\r
#define DEFAULT_DYNTEXTURE r_texture_grey128\r
\r
-static dyntexture_t * _CL_FindDynTexture( const char *name ) {\r
+static dyntexture_t * cl_finddyntexture( const char *name ) {\r
unsigned i;\r
dyntexture_t *dyntexture = NULL;\r
- // some sanity checks - and make sure its actually a dynamic texture path\r
- if( !name || strncmp( name, DYNAMIC_TEXTURE_PATH_PREFIX, sizeof( DYNAMIC_TEXTURE_PATH_PREFIX ) - 1 ) != 0 ) {\r
+\r
+ // sanity checks - make sure its actually a dynamic texture path\r
+ if( !name || !*name || strncmp( name, CLDYNTEXTUREPREFIX, sizeof( CLDYNTEXTUREPREFIX ) - 1 ) != 0 ) {\r
+ // TODO: print a warning or something\r
+ if( developer.integer > 0 ) {\r
+ Con_Printf( "cl_finddyntexture: Bad dynamic texture name '%s'\n", name );\r
+ }\r
return NULL;\r
}\r
\r
}\r
\r
rtexture_t * CL_GetDynTexture( const char *name ) {\r
- dyntexture_t *dyntexture = _CL_FindDynTexture( name );\r
+ dyntexture_t *dyntexture = cl_finddyntexture( name );\r
if( dyntexture ) {\r
return dyntexture->texture;\r
} else {\r
cachepic_t *cachepic;\r
skinframe_t *skinframe;\r
\r
- dyntexture = _CL_FindDynTexture( name );\r
+ dyntexture = cl_finddyntexture( name );\r
// TODO: assert dyntexture != NULL!\r
if( dyntexture->texture != texture ) {\r
+ dyntexture->texture = texture;\r
+\r
cachepic = Draw_CachePic( name, false );\r
- skinframe = R_SkinFrame_Find( name, 0, 0, 0, 0, false );\r
- // this is kind of hacky\r
// TODO: assert cachepic and skinframe should be valid pointers...\r
-\r
// TODO: assert cachepic->tex = dyntexture->texture\r
cachepic->tex = texture;\r
// update cachepic's size, too\r
cachepic->width = R_TextureWidth( texture );\r
cachepic->height = R_TextureHeight( texture );\r
- // TODO: assert skinframe->base = dyntexture->texture\r
- skinframe->base = texture;\r
- // simply reset the compare* attributes of skinframe\r
- skinframe->comparecrc = 0;\r
- skinframe->comparewidth = skinframe->compareheight = 0;\r
\r
- dyntexture->texture = texture;\r
+ // update skinframes\r
+ skinframe = NULL;\r
+ while( (skinframe = R_SkinFrame_FindNextByName( skinframe, name )) != NULL ) {\r
+ skinframe->base = texture;\r
+ // simply reset the compare* attributes of skinframe\r
+ skinframe->comparecrc = 0;\r
+ skinframe->comparewidth = skinframe->compareheight = 0;\r
+ // this is kind of hacky\r
+ }\r
}\r
}\r
\r
#ifndef CL_DYNTEXTURE_H\r
#define CL_DYNTEXTURE_H\r
\r
-#define DYNAMIC_TEXTURE_PATH_PREFIX "_dynamic/"\r
+#define CLDYNTEXTUREPREFIX "_dynamic/"\r
#define MAX_DYNAMIC_TEXTURE_COUNT 64\r
\r
+// always path fully specified names to the dynamic texture functions! (ie. with the _dynamic/ prefix, etc.!)\r
+\r
// return a valid texture handle for a dynamic texture (might be filler texture if it hasnt been initialized yet)\r
-// textureflags will be ignored though for now [11/22/2007 Black]\r
+// or NULL if its not a valid dynamic texture name\r
rtexture_t * CL_GetDynTexture( const char *name );\r
\r
// link a texture handle as dynamic texture and update texture handles in the renderer and draw_* accordingly\r
--- /dev/null
+#ifdef SUPPORT_GECKO\r
+\r
+// includes everything!\r
+#include <OffscreenGecko/browser.h>\r
+\r
+#ifdef _MSC_VER\r
+# pragma comment( lib, "OffscreenGecko" )\r
+#endif\r
+\r
+#include "quakedef.h"\r
+#include "cl_dyntexture.h"\r
+#include "cl_gecko.h"\r
+\r
+static rtexturepool_t *cl_geckotexturepool;\r
+static OSGK_Embedding *cl_geckoembedding;\r
+\r
+struct clgecko_s {\r
+ qboolean active;\r
+ char name[ MAX_QPATH + 32 ];\r
+\r
+ OSGK_Browser *browser;\r
+ \r
+ rtexture_t *texture;\r
+};\r
+\r
+static clgecko_t cl_geckoinstances[ MAX_GECKO_INSTANCES ];\r
+\r
+static clgecko_t * cl_gecko_findunusedinstance( void ) {\r
+ int i;\r
+ for( i = 0 ; i < MAX_GECKO_INSTANCES ; i++ ) {\r
+ clgecko_t *instance = &cl_geckoinstances[ i ];\r
+ if( !instance->active ) {\r
+ return instance;\r
+ }\r
+ }\r
+ return NULL;\r
+}\r
+\r
+clgecko_t * CL_Gecko_FindBrowser( const char *name ) {\r
+ int i;\r
+\r
+ if( !name || !*name || strncmp( name, CLGECKOPREFIX, sizeof( CLGECKOPREFIX ) - 1 ) != 0 ) {\r
+ if( developer.integer > 0 ) {\r
+ Con_Printf( "CL_Gecko_FindBrowser: Bad gecko texture name '%s'!\n", name );\r
+ }\r
+ return NULL;\r
+ }\r
+\r
+ for( i = 0 ; i < MAX_GECKO_INSTANCES ; i++ ) {\r
+ clgecko_t *instance = &cl_geckoinstances[ i ];\r
+ if( instance->active && strcmp( instance->name, name ) == 0 ) {\r
+ return instance;\r
+ }\r
+ }\r
+\r
+ return NULL;\r
+}\r
+\r
+static void cl_gecko_updatecallback( rtexture_t *texture, clgecko_t *instance ) {\r
+ const unsigned char *data;\r
+ if( instance->browser ) {\r
+ // TODO: OSGK only supports BGRA right now\r
+ data = osgk_browser_lock_data( instance->browser, NULL );\r
+ R_UpdateTexture( texture, data, 0, 0, DEFAULT_GECKO_WIDTH, DEFAULT_GECKO_HEIGHT );\r
+ osgk_browser_unlock_data( instance->browser, data );\r
+ }\r
+}\r
+\r
+static void cl_gecko_linktexture( clgecko_t *instance ) {\r
+ // TODO: assert that instance->texture == NULL\r
+ instance->texture = R_LoadTexture2D( cl_geckotexturepool, instance->name, DEFAULT_GECKO_WIDTH, DEFAULT_GECKO_HEIGHT, NULL, TEXTYPE_RGBA, TEXF_ALPHA, NULL );\r
+ R_MakeTextureDynamic( instance->texture, cl_gecko_updatecallback, instance );\r
+ CL_LinkDynTexture( instance->name, instance->texture );\r
+}\r
+\r
+static void cl_gecko_unlinktexture( clgecko_t *instance ) {\r
+ if( instance->texture ) {\r
+ CL_UnlinkDynTexture( instance->name );\r
+ R_FreeTexture( instance->texture );\r
+ instance->texture = NULL;\r
+ }\r
+}\r
+\r
+clgecko_t * CL_Gecko_CreateBrowser( const char *name ) {\r
+ // TODO: verify that we dont use a name twice\r
+ clgecko_t *instance = cl_gecko_findunusedinstance();\r
+ // TODO: assert != NULL\r
+ \r
+ instance->active = true;\r
+ strlcpy( instance->name, name, sizeof( instance->name ) );\r
+ instance->browser = osgk_browser_create( cl_geckoembedding, DEFAULT_GECKO_WIDTH, DEFAULT_GECKO_HEIGHT );\r
+ // TODO: assert != NULL\r
+\r
+ cl_gecko_linktexture( instance );\r
+\r
+ return instance;\r
+}\r
+\r
+void CL_Gecko_DestroyBrowser( clgecko_t *instance ) {\r
+ if( !instance || !instance->active ) {\r
+ return;\r
+ }\r
+\r
+ instance->active = false;\r
+ cl_gecko_unlinktexture( instance );\r
+\r
+ osgk_release( instance->browser );\r
+ instance->browser = NULL;\r
+}\r
+\r
+void CL_Gecko_Frame( void ) {\r
+ int i;\r
+ for( i = 0 ; i < MAX_GECKO_INSTANCES ; i++ ) {\r
+ clgecko_t *instance = &cl_geckoinstances[ i ];\r
+ if( instance->active ) {\r
+ if( instance->browser && osgk_browser_query_dirty( instance->browser ) == 1 ) {\r
+ R_MarkDirtyTexture( instance->texture );\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+static void cl_gecko_start( void )\r
+{\r
+ int i;\r
+ cl_geckotexturepool = R_AllocTexturePool();\r
+\r
+ // recreate textures on module start\r
+ for( i = 0 ; i < MAX_GECKO_INSTANCES ; i++ ) {\r
+ clgecko_t *instance = &cl_geckoinstances[ i ];\r
+ if( instance->active ) {\r
+ cl_gecko_linktexture( instance );\r
+ }\r
+ }\r
+}\r
+\r
+static void cl_gecko_shutdown( void )\r
+{\r
+ int i;\r
+ for( i = 0 ; i < MAX_GECKO_INSTANCES ; i++ ) {\r
+ clgecko_t *instance = &cl_geckoinstances[ i ];\r
+ if( instance->active ) {\r
+ cl_gecko_unlinktexture( instance );\r
+ }\r
+ }\r
+ R_FreeTexturePool( &cl_geckotexturepool );\r
+}\r
+\r
+static void cl_gecko_newmap( void )\r
+{\r
+ // DO NOTHING\r
+}\r
+\r
+void CL_Gecko_Shutdown( void ) {\r
+ int i;\r
+ for( i = 0 ; i < MAX_GECKO_INSTANCES ; i++ ) {\r
+ clgecko_t *instance = &cl_geckoinstances[ i ];\r
+ if( instance->active ) {\r
+ cl_gecko_unlinktexture( instance );\r
+ } \r
+ }\r
+ osgk_release( cl_geckoembedding );\r
+}\r
+\r
+static void cl_gecko_create_f( void ) {\r
+ char name[MAX_QPATH];\r
+\r
+ if (Cmd_Argc() != 2)\r
+ {\r
+ Con_Print("usage: gecko_create <name>\npcreates a browser (full texture path " CLGECKOPREFIX "<name>)\n");\r
+ return;\r
+ }\r
+\r
+ // TODO: use snprintf instead\r
+ sprintf(name, CLGECKOPREFIX "%s", Cmd_Argv(1));\r
+ CL_Gecko_CreateBrowser( name );\r
+}\r
+\r
+static void cl_gecko_destroy_f( void ) {\r
+ char name[MAX_QPATH];\r
+\r
+ if (Cmd_Argc() != 2)\r
+ {\r
+ Con_Print("usage: gecko_destroy <name>\ndestroys a browser (full texture path " CLGECKOPREFIX "<name>)\n");\r
+ return;\r
+ }\r
+\r
+ // TODO: use snprintf instead\r
+ sprintf(name, CLGECKOPREFIX "%s", Cmd_Argv(1));\r
+ CL_Gecko_DestroyBrowser( CL_Gecko_FindBrowser( name ) );\r
+}\r
+\r
+static void cl_gecko_navigate_f( void ) {\r
+ char name[MAX_QPATH];\r
+ const char *URI;\r
+\r
+ if (Cmd_Argc() != 3)\r
+ {\r
+ Con_Print("usage: gecko_destroy <name> <URI>\nnavigates to a certain URI (full texture path " CLGECKOPREFIX "<name>)\n");\r
+ return;\r
+ }\r
+\r
+ // TODO: use snprintf instead\r
+ sprintf(name, CLGECKOPREFIX "%s", Cmd_Argv(1));\r
+ URI = Cmd_Argv( 2 );\r
+ CL_Gecko_NavigateToURI( CL_Gecko_FindBrowser( name ), URI );\r
+}\r
+\r
+void CL_Gecko_Init( void )\r
+{\r
+ OSGK_EmbeddingOptions *options = osgk_embedding_options_create();\r
+ osgk_embedding_options_add_search_path( options, "./xulrunner/" );\r
+ cl_geckoembedding = osgk_embedding_create_with_options( options, NULL );\r
+ osgk_release( options );\r
+ \r
+ if( cl_geckoembedding == NULL ) {\r
+ Con_Printf( "CL_Gecko_Init: Couldn't retrieve gecko embedding object!\n" );\r
+ }\r
+ \r
+ Cmd_AddCommand( "gecko_create", cl_gecko_create_f, "Create a gecko browser instance" );\r
+ Cmd_AddCommand( "gecko_destroy", cl_gecko_destroy_f, "Destroy a gecko browser instance" );\r
+ Cmd_AddCommand( "gecko_navigate", cl_gecko_navigate_f, "Navigate a gecko browser to an URI" );\r
+\r
+ R_RegisterModule( "CL_Gecko", cl_gecko_start, cl_gecko_shutdown, cl_gecko_newmap );\r
+}\r
+\r
+void CL_Gecko_NavigateToURI( clgecko_t *instance, const char *URI ) {\r
+ if( instance && instance->active ) {\r
+ osgk_browser_navigate( instance->browser, URI );\r
+ }\r
+}\r
+\r
+// TODO: write this function\r
+void CL_Gecko_Event_CursorMove( clgecko_t *instance, float x, float y );\r
+qboolean CL_Gecko_Event_Key( clgecko_t *instance, int key, clgecko_buttoneventtype_t eventtype );\r
+\r
+#endif
\ No newline at end of file
--- /dev/null
+// Andreas Kirsch 07\r
+\r
+#ifdef SUPPORT_GECKO\r
+\r
+#ifndef CL_GECKO_H\r
+#define CL_GECKO_H\r
+\r
+#define DEFAULT_GECKO_WIDTH 512\r
+#define DEFAULT_GECKO_HEIGHT DEFAULT_GECKO_WIDTH\r
+\r
+#define CLGECKOPREFIX CLDYNTEXTUREPREFIX "gecko/"\r
+#define MAX_GECKO_INSTANCES 16\r
+\r
+typedef enum clgecko_buttoneventtype_e {\r
+ CLG_BET_DOWN,\r
+ CLG_BET_UP,\r
+ CLG_BET_DOUBLECLICK,\r
+ // use for up + down (but dont use both)\r
+ CLG_BET_PRESS\r
+} clgecko_buttoneventtype_t;\r
+\r
+typedef struct clgecko_s clgecko_t;\r
+\r
+void CL_Gecko_Frame( void );\r
+void CL_Gecko_Init( void );\r
+void CL_Gecko_Shutdown( void );\r
+\r
+clgecko_t * CL_Gecko_CreateBrowser( const char *name );\r
+clgecko_t * CL_Gecko_FindBrowser( const char *name );\r
+void CL_Gecko_DestroyBrowser( clgecko_t *instance );\r
+\r
+void CL_Gecko_NavigateToURI( clgecko_t *instance, const char *URI );\r
+void CL_Gecko_Event_CursorMove( clgecko_t *instance, float x, float y );\r
+\r
+// returns whether the key/button event was handled or not\r
+qboolean CL_Gecko_Event_Key( clgecko_t *instance, int key, clgecko_buttoneventtype_t eventtype );\r
+\r
+#endif\r
+\r
+#endif
\ No newline at end of file
#include "quakedef.h"
#include "cl_collision.h"
+#include "cl_gecko.h"
#include "cl_video.h"
#include "image.h"
#include "csprogs.h"
CL_Screen_Init();
CL_Video_Init();
+#ifdef SUPPORT_GECKO
+ CL_Gecko_Init();
+#endif
}
#include "quakedef.h"
+#include "cl_dyntexture.h"
#include "cl_video.h"
#include "dpvsimpledecode.h"
return true;
}
+static void VideoUpdateCallback(rtexture_t *rt, clvideo_t *video) {
+ R_UpdateTexture( video->cpif.tex, (unsigned char *)video->imagedata, 0, 0, video->cpif.width, video->cpif.height );
+}
+
+static void LinkVideoTexture( clvideo_t *video ) {
+ video->cpif.tex = R_LoadTexture2D( cl_videotexturepool, video->cpif.name,
+ video->cpif.width, video->cpif.height, NULL, TEXTYPE_RGBA, TEXF_ALWAYSPRECACHE, NULL );
+ R_MakeTextureDynamic( video->cpif.tex, VideoUpdateCallback, video );
+ CL_LinkDynTexture( video->cpif.name, video->cpif.tex );
+}
+
+static void UnlinkVideoTexture( clvideo_t *video ) {
+ CL_UnlinkDynTexture( video->cpif.name );
+ // free the texture
+ R_FreeTexture( video->cpif.tex );
+ // free the image data
+ Mem_Free( video->imagedata );
+}
+
static void SuspendVideo( clvideo_t * video )
{
if( video->suspended )
return;
video->suspended = true;
- // free the texture
- R_FreeTexture( video->cpif.tex );
- // free the image data
- Mem_Free( video->imagedata );
+ UnlinkVideoTexture( video );
// if we are in firstframe mode, also close the stream
if( video->state == CLVIDEO_FIRSTFRAME )
dpvsimpledecode_close( video->stream );
}
video->imagedata = Mem_Alloc( cls.permanentmempool, video->cpif.width * video->cpif.height * cl_videobytesperpixel );
- video->cpif.tex = R_LoadTexture2D( cl_videotexturepool, video->cpif.name,
- video->cpif.width, video->cpif.height, NULL, TEXTYPE_RGBA, TEXF_ALWAYSPRECACHE, NULL );
+ LinkVideoTexture( video );
// update starttime
video->starttime += realtime - video->lasttime;
video->cpif.width = dpvsimpledecode_getwidth( video->stream );
video->cpif.height = dpvsimpledecode_getheight( video->stream );
- video->cpif.tex = R_LoadTexture2D( cl_videotexturepool, video->cpif.name,
- video->cpif.width, video->cpif.height, NULL, TEXTYPE_RGBA, TEXF_ALWAYSPRECACHE, NULL );
-
- video->imagedata = Mem_Alloc( cls.permanentmempool, video->cpif.width * video->cpif.height * cl_videobytesperpixel );
+ video->imagedata = Mem_Alloc( cls.permanentmempool, video->cpif.width * video->cpif.height * cl_videobytesperpixel );
+ LinkVideoTexture( video );
return video;
}
clvideo_t* CL_OpenVideo( const char *filename, const char *name, int owner )
{
clvideo_t *video;
+ // sanity check
+ if( !name || !*name || strncmp( name, CLVIDEOPREFIX, sizeof( CLVIDEOPREFIX ) - 1 ) != 0 ) {
+ if( developer.integer > 0 ) {
+ Con_Printf( "CL_OpenVideo: Bad video texture name '%s'!\n", name );
+ }
+ return NULL;
+ }
video = FindUnusedVid();
if( !video ) {
- Con_Printf( "unable to open video \"%s\" - video limit reached\n", filename );
+ Con_Printf( "CL_OpenVideo: unable to open video \"%s\" - video limit reached\n", filename );
return NULL;
}
video = OpenVideo( video, filename, name, owner );
// expand the active range to include the new entry
- if (video)
+ if (video) {
cl_num_videos = max(cl_num_videos, (int)(video - cl_videos) + 1);
+ }
return video;
}
if( !video->suspended || video->state != CLVIDEO_FIRSTFRAME )
dpvsimpledecode_close( video->stream );
if( !video->suspended ) {
- Mem_Free( video->imagedata );
- R_FreeTexture( video->cpif.tex );
+ UnlinkVideoTexture( video );
}
video->state = CLVIDEO_UNUSED;
return;
}
} while( video->framenum < destframe );
- R_UpdateTexture( video->cpif.tex, (unsigned char *)video->imagedata, 0, 0, video->cpif.width, video->cpif.height );
+ R_MarkDirtyTexture( video->cpif.tex );
}
}
-void CL_VideoFrame( void ) // update all videos
+void CL_Video_Frame( void ) // update all videos
{
int i;
clvideo_t *video;
if( cl_videos->state != CLVIDEO_UNUSED )
CL_CloseVideo( cl_videos );
- if( !OpenVideo( cl_videos, filename, va( CLVIDEOPREFIX "%s", filename ), 0 ) )
+ // already contains video/
+ if( !OpenVideo( cl_videos, filename, va( CLDYNTEXTUREPREFIX "%s", filename ), 0 ) )
return;
// expand the active range to include the new entry
cl_num_videos = max(cl_num_videos, 1);
for( video = cl_videos, i = 0 ; i < cl_num_videos ; i++, video++ )
if( video->state != CLVIDEO_UNUSED && !video->suspended )
- video->cpif.tex = R_LoadTexture2D( cl_videotexturepool, video->cpif.name,
- video->cpif.width, video->cpif.height, NULL, TEXTYPE_RGBA, TEXF_ALWAYSPRECACHE, NULL );
+ LinkVideoTexture( video );
}
static void cl_video_shutdown( void )
{
+ // TODO: unlink video textures?
R_FreeTexturePool( &cl_videotexturepool );
}
#define CL_VIDEO_H
#define MAXCLVIDEOS 64 + 1 // 1 video is reserved for the cinematic mode
-#define CLVIDEOPREFIX "_video/"
+// yields DYNAMIC_TEXTURE_PATH_PREFIX CLVIDEOPREFIX video name for a path
+#define CLVIDEOPREFIX CLDYNTEXTUREPREFIX "video/"
#define CLTHRESHOLD 2.0
#define MENUOWNER 1
void CL_CloseVideo( clvideo_t * video );
void CL_PurgeOwner( int owner );
-void CL_VideoFrame( void ); // update all videos
+void CL_Video_Frame( void ); // update all videos
void CL_Video_Init( void );
void CL_Video_Shutdown( void );
#include "wad.h"
#include "cl_video.h"
+#include "cl_dyntexture.h"
cvar_t r_textshadow = {CVAR_SAVE, "r_textshadow", "0", "draws a shadow on all text to improve readability (note: value controls offset, 1 = 1 pixel, 1.5 = 1.5 pixels, etc)"};
cvar_t r_textbrightness = {CVAR_SAVE, "r_textbrightness", "0", "additional brightness for text color codes (0 keeps colors as is, 1 makes them all white)"};
unsigned char *lmpdata;
char lmpname[MAX_QPATH];
- if (!strncmp(CLVIDEOPREFIX, path, sizeof(CLVIDEOPREFIX) - 1))
- {
- clvideo_t *video;
-
- video = CL_GetVideoByName(path);
- if( video )
- return &video->cpif;
- }
-
+ // check whether the picture has already been cached
crc = CRC_Block((unsigned char *)path, strlen(path));
hashkey = ((crc >> 8) ^ crc) % CACHEPICHASHSIZE;
for (pic = cachepichash[hashkey];pic;pic = pic->chain)
pic->chain = cachepichash[hashkey];
cachepichash[hashkey] = pic;
+ // check whether it is an dynamic texture (if so, we can directly use its texture handler)
+ pic->tex = CL_GetDynTexture( path );
+ // if so, set the width/height, too
+ if( pic->tex ) {
+ pic->width = R_TextureWidth(pic->tex);
+ pic->height = R_TextureHeight(pic->tex);
+ // we're done now (early-out)
+ return pic;
+ }
+
flags = TEXF_ALPHA;
if (persistent)
flags |= TEXF_PRECACHE;
// r_main.c
#include "quakedef.h"
+#include "cl_dyntexture.h"
#include "r_shadow.h"
#include "polygon.h"
#include "image.h"
}
}
+skinframe_t *R_SkinFrame_FindNextByName( skinframe_t *last, const char *name ) {
+ skinframe_t *item;
+ char basename[MAX_QPATH];
+
+ Image_StripImageExtension(name, basename, sizeof(basename));
+
+ if( last == NULL ) {
+ int hashindex;
+ hashindex = CRC_Block((unsigned char *)basename, strlen(basename)) & (SKINFRAME_HASH - 1);
+ item = r_skinframe.hash[hashindex];
+ } else {
+ item = last->next;
+ }
+
+ // linearly search through the hash bucket
+ for( ; item ; item = item->next ) {
+ if( !strcmp( item->basename, basename ) ) {
+ return item;
+ }
+ }
+ return NULL;
+}
+
skinframe_t *R_SkinFrame_Find(const char *name, int textureflags, int comparewidth, int compareheight, int comparecrc, qboolean add)
{
skinframe_t *item;
break;
if (!item)
{
- if (!add)
+ rtexture_t *dyntexture;
+ // check whether its a dynamic texture
+ dyntexture = CL_GetDynTexture( basename );
+ if (!add && !dyntexture)
return NULL;
item = (skinframe_t *)Mem_ExpandableArray_AllocRecord(&r_skinframe.array);
memset(item, 0, sizeof(*item));
strlcpy(item->basename, basename, sizeof(item->basename));
item->textureflags = textureflags;
+ item->base = dyntexture;
item->comparewidth = comparewidth;
item->compareheight = compareheight;
item->comparecrc = comparecrc;
- item->next = r_skinframe.hash[hashindex];
+ item->next = r_skinframe.hash[hashindex];
r_skinframe.hash[hashindex] = item;
}
R_SkinFrame_MarkUsed(item);
newt = r;
for(i=0,t=m->data_textures;i<m->num_textures;i++,t++)
{
- if(t->width && !strcasecmp(t->name, r))
+ if(/*t->width && !strcasecmp(t->name, r)*/ matchpattern( t->name, r, true ) )
{
- if ((skinframe = R_SkinFrame_LoadExternal((char*)newt, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE | TEXF_PICMIP, true)))
+ if ((skinframe = R_SkinFrame_LoadExternal(newt, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE | TEXF_PICMIP, true)))
{
- t->skinframes[0] = skinframe;
+// t->skinframes[0] = skinframe;
+ t->currentskinframe = skinframe;
Con_Printf("%s replaced with %s\n", r, newt);
- return;
}
else
{
// dynamic texture code [11/22/2007 Black]
void R_MarkDirtyTexture(rtexture_t *rt) {
gltexture_t *glt = (gltexture_t*) rt;
+ if( !glt ) {
+ return;
+ }
+
// dont do anything if the texture is already dirty (and make sure this *is* a dynamic texture after all!)
if( !glt->dirtytexnum && glt->flags & GLTEXF_DYNAMIC ) {
glt->dirtytexnum = glt->texnum;
void R_MakeTextureDynamic(rtexture_t *rt, updatecallback_t updatecallback, void *data) {
gltexture_t *glt = (gltexture_t*) rt;
+ if( !glt ) {
+ return;
+ }
+
glt->flags |= GLTEXF_DYNAMIC;
glt->updatecallback = updatecallback;
glt->updatacallback_data = data;
{
gltexture_t *glt;
glt = (gltexture_t *)rt;
- if (glt->flags & GLTEXF_UPLOAD)
- R_UploadTexture(glt);
if (glt->flags & GLTEXF_DYNAMIC)
R_UpdateDynamicTexture(glt);
+ if (glt->flags & GLTEXF_UPLOAD)
+ R_UploadTexture(glt);
return glt->texnum;
}
CHECKGLERROR
}
-static void R_Upload(gltexture_t *glt, unsigned char *data, int fragx, int fragy, int fragz, int fragwidth, int fragheight, int fragdepth)
+static void R_Upload(gltexture_t *glt, const unsigned char *data, int fragx, int fragy, int fragz, int fragwidth, int fragheight, int fragdepth)
{
int i, mip, width, height, depth;
GLint oldbindtexnum;
- unsigned char *prevbuffer;
+ const unsigned char *prevbuffer;
prevbuffer = data;
CHECKGLERROR
return rt ? ((gltexture_t *)rt)->inputheight : 0;
}
-void R_UpdateTexture(rtexture_t *rt, unsigned char *data, int x, int y, int width, int height)
+void R_UpdateTexture(rtexture_t *rt, const unsigned char *data, int x, int y, int width, int height)
{
gltexture_t *glt;
if (rt == NULL)
#include <time.h>
#include "libcurl.h"
#include "cdaudio.h"
+#include "cl_gecko.h"
#include "cl_video.h"
#include "progsvm.h"
#include "csprogs.h"
//ui_update();
- CL_VideoFrame();
+ CL_Video_Frame();
+#ifdef SUPPORT_GECKO
+ CL_Gecko_Frame();
+#endif
CL_UpdateScreen();
// AK shutdown PRVM
// AK hmm, no PRVM_Shutdown(); yet
+#ifdef SUPPORT_GECKO
+ CL_Gecko_Shutdown();
+#endif
CL_Video_Shutdown();
Host_SaveConfig_f();
// update a portion of the image data of a texture, used by lightmap updates
// and procedural textures such as video playback.
-void R_UpdateTexture(rtexture_t *rt, unsigned char *data, int x, int y, int width, int height);
+void R_UpdateTexture(rtexture_t *rt, const unsigned char *data, int x, int y, int width, int height);
// returns the renderer dependent texture slot number (call this before each
// use, as a texture might not have been precached)
void R_SkinFrame_PrepareForPurge(void);
void R_SkinFrame_MarkUsed(skinframe_t *skinframe);
void R_SkinFrame_Purge(void);
+// set last to NULL to start from the beginning
+skinframe_t *R_SkinFrame_FindNextByName( skinframe_t *last, const char *name );
skinframe_t *R_SkinFrame_Find(const char *name, int textureflags, int comparewidth, int compareheight, int comparecrc, qboolean add);
skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboolean complain);
skinframe_t *R_SkinFrame_LoadInternal(const char *name, int textureflags, int loadpantsandshirt, int loadglowtexture, const unsigned char *skindata, int width, int height, int bitsperpixel, const unsigned int *palette, const unsigned int *alphapalette);