From 4d528922fd8a4385654b354196db7b7e7f71175a Mon Sep 17 00:00:00 2001 From: Spoike Date: Wed, 13 Oct 2004 07:24:59 +0000 Subject: [PATCH] plugins capture_codec tga/png/jpg Changed intensity of hud images so that high-gamma settings work... (maybe too much) Small progs changes that fixes hexenc git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@323 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/client/cl_main.c | 26 ++-- engine/client/cl_screen.c | 156 ++++++++++---------- engine/client/image.c | 6 +- engine/client/m_mp3.c | 289 ++++++++++++++++++++++--------------- engine/client/r_part.c | 2 +- engine/client/sbar.c | 3 + engine/common/gl_q2bsp.c | 4 +- engine/common/mathlib.h | 3 + engine/common/plugin.c | 247 ++++++++++++++++++++++++++++++- engine/common/vm.h | 8 +- engine/gl/gl_alias.c | 14 +- engine/gl/gl_draw.c | 33 +++-- engine/gl/gl_model.c | 10 +- engine/gl/gl_screen.c | 10 +- engine/gl/gl_vidcommon.c | 1 - engine/gl/gl_warp.c | 4 +- engine/gl/glmod_doom.c | 2 +- engine/gl/glquake.h | 4 +- engine/qclib/execloop.h | 4 +- engine/qclib/pr_exec.c | 10 +- engine/qclib/qcc.h | 1 + engine/qclib/qcc_pr_comp.c | 97 +++++++++---- engine/qclib/qcc_pr_lex.c | 3 + engine/qclib/qccmain.c | 29 +++- engine/sw/sw_draw.c | 2 + engine/sw/sw_screen.c | 6 +- 26 files changed, 676 insertions(+), 298 deletions(-) diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index b2f1b758a..2032acd35 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -63,7 +63,7 @@ cvar_t cl_hudswap = {"cl_hudswap", "0", NULL, CVAR_ARCHIVE}; cvar_t cl_maxfps = {"cl_maxfps", "-1", NULL, CVAR_ARCHIVE}; cvar_t cl_nopext = {"cl_nopext", "0", NULL, CVAR_ARCHIVE}; -cvar_t cfg_save_name = {"cfg_save_name", "fteconfig", NULL, CVAR_ARCHIVE}; +cvar_t cfg_save_name = {"cfg_save_name", "fte", NULL, CVAR_ARCHIVE}; cvar_t cl_splitscreen = {"cl_splitscreen", "0"}; @@ -1018,47 +1018,47 @@ void CL_CheckServerInfo(void) #endif cls.allow_fbskins = 0; // cls.allow_overbrightlight; - if (atoi(Info_ValueForKey(cl.serverinfo, "rearview"))) + if (cls.demoplayback || atoi(Info_ValueForKey(cl.serverinfo, "rearview"))) cls.allow_rearview=true; - if (atoi(Info_ValueForKey(cl.serverinfo, "watervis"))) + if (cls.demoplayback || atoi(Info_ValueForKey(cl.serverinfo, "watervis"))) cls.allow_watervis=true; - if (atoi(Info_ValueForKey(cl.serverinfo, "allow_skybox")) || atoi(Info_ValueForKey(cl.serverinfo, "allow_skyboxes"))) + if (cls.demoplayback || atoi(Info_ValueForKey(cl.serverinfo, "allow_skybox")) || atoi(Info_ValueForKey(cl.serverinfo, "allow_skyboxes"))) cls.allow_skyboxes=true; - if (atoi(Info_ValueForKey(cl.serverinfo, "mirrors"))) + if (cls.demoplayback || atoi(Info_ValueForKey(cl.serverinfo, "mirrors"))) cls.allow_mirrors=true; - if (atoi(Info_ValueForKey(cl.serverinfo, "allow_shaders"))) + if (cls.demoplayback || atoi(Info_ValueForKey(cl.serverinfo, "allow_shaders"))) cls.allow_shaders=true; - if (!atoi(Info_ValueForKey(cl.serverinfo, "allow_luma"))) + if (cls.demoplayback || !atoi(Info_ValueForKey(cl.serverinfo, "allow_luma"))) cls.allow_luma=false; - if (atoi(Info_ValueForKey(cl.serverinfo, "allow_lmgamma"))) + if (cls.demoplayback || atoi(Info_ValueForKey(cl.serverinfo, "allow_lmgamma"))) cls.allow_lightmapgamma=true; s = Info_ValueForKey(cl.serverinfo, "allow_bump"); - if (atoi(s) || !*s) //admin doesn't care. + if (cls.demoplayback || atoi(s) || !*s) //admin doesn't care. cls.allow_bump=true; #ifdef FISH - if (atoi(Info_ValueForKey(cl.serverinfo, "allow_fish"))) + if (cls.demoplayback || atoi(Info_ValueForKey(cl.serverinfo, "allow_fish"))) cls.allow_fish=true; #endif s = Info_ValueForKey(cl.serverinfo, "fbskins"); - if (*s) + if (cls.demoplayback || *s) cls.allow_fbskins = atof(s); else cls.allow_fbskins = 0.3; s = Info_ValueForKey(cl.serverinfo, "*cheats"); - if (!stricmp(s, "on")) + if (cls.demoplayback || !stricmp(s, "on")) cls.allow_cheats = true; s = Info_ValueForKey(cl.serverinfo, "strict"); - if (*s && strcmp(s, "0")) + if (!cls.demoplayback && *s && strcmp(s, "0")) { cls.allow_semicheats = false; cls.allow_cheats = false; diff --git a/engine/client/cl_screen.c b/engine/client/cl_screen.c index 3f452e382..5374b6707 100644 --- a/engine/client/cl_screen.c +++ b/engine/client/cl_screen.c @@ -715,7 +715,7 @@ void SCR_CrosshairPosition(int pnum, int *x, int *y) { VectorCopy(cl.simorg[pnum], start); start[2] -= cl.viewheight[pnum]/4; - ML_Project(tr.endpos, end, cl.viewangles[pnum], start, (float)rect.width/rect.height); + ML_Project(tr.endpos, end, cl.viewangles[pnum], start, (float)rect.width/rect.height, r_refdef.fov_y); *x = rect.x+rect.width*end[0]; *y = rect.y+rect.height*end[1]; return; @@ -1209,6 +1209,82 @@ int MipColor(int r, int g, int b) return best; } +void SCR_ScreenShot (char *filename) +{ + int truewidth, trueheight; + qbyte *buffer; + int i, c, temp; + +#define MAX_PREPAD 128 + char *ext; + + ext = COM_FileExtension(filename); + + buffer = VID_GetRGBInfo(MAX_PREPAD, &truewidth, &trueheight); + +#ifdef AVAIL_PNGLIB + if (!strcmp(ext, "png")) + { + Image_WritePNG(filename, 100, buffer+MAX_PREPAD, truewidth, trueheight); + } + else +#endif +#ifdef AVAIL_JPEGLIB + if (!strcmp(ext, "jpeg") || !strcmp(ext, "jpg")) + { + screenshotJPEG(filename, buffer+MAX_PREPAD, truewidth, trueheight); + } + else +#endif + /* if (!strcmp(ext, "bmp")) + { + WriteBMPFile(pcxname, buffer+MAX_PREPAD, truewidth, trueheight); + } + else*/ + if (!strcmp(ext, "pcx")) + { + int y, x; + qbyte *src, *dest; + qbyte *newbuf = buffer + MAX_PREPAD; + // convert to eight bit + for (y = 0; y < trueheight; y++) { + src = newbuf + (truewidth * 3 * y); + dest = newbuf + (truewidth * y); + + for (x = 0; x < truewidth; x++) { + *dest++ = MipColor(src[0], src[1], src[2]); + src += 3; + } + } + + WritePCXfile (filename, newbuf, truewidth, trueheight, truewidth, host_basepal, false); + } + else //tga + { + buffer+=MAX_PREPAD-18; + memset (buffer, 0, 18); + buffer[2] = 2; // uncompressed type + buffer[12] = truewidth&255; + buffer[13] = truewidth>>8; + buffer[14] = trueheight&255; + buffer[15] = trueheight>>8; + buffer[16] = 24; // pixel size + + // swap rgb to bgr + c = 18+truewidth*trueheight*3; + for (i=18 ; i>8; - buffer[14] = trueheight&255; - buffer[15] = trueheight>>8; - buffer[16] = 24; // pixel size - - // swap rgb to bgr - c = 18+truewidth*trueheight*3; - for (i=18 ; i vid.height-8) - y = vid.height-8; - Draw_String(0, y, capturemessage.string); -} + if (*capturemessage.string) + { + int y = vid.height -32-16; + if (y < scr_con_current) y = scr_con_current; + if (y > vid.height-8) + y = vid.height-8; + Draw_String(0, y, capturemessage.string); + } //time for annother frame? /*if (recordavi_uncompressed_audio_stream) //sync video to the same frame as audio. @@ -1306,20 +1314,35 @@ void Media_RecordFrame (void) recordavi_videotime += recordavi_frametime; } - //ask gl for it - glReadPixels (glx, gly, glwidth, glheight, GL_RGB, GL_UNSIGNED_BYTE, framebuffer ); - - // swap rgb to bgr - c = glwidth*glheight*3; - for (i=0 ; isn.speed; - recordavi_wave_format.wBitsPerSample = 16; // always 16bit in Quake sound engine - recordavi_wave_format.nBlockAlign = recordavi_wave_format.wBitsPerSample/8 * recordavi_wave_format.nChannels; - recordavi_wave_format.nAvgBytesPerSec = recordavi_wave_format.nSamplesPerSec * recordavi_wave_format.nBlockAlign; - recordavi_wave_format.cbSize = 0; + if (recordavi_codec_fourcc) + { + AVICOMPRESSOPTIONS opts; + AVICOMPRESSOPTIONS* aopts[1] = { &opts }; + memset(&opts, 0, sizeof(opts)); + opts.fccType = stream_header.fccType; + opts.fccHandler = recordavi_codec_fourcc; + // Make the stream according to compression + hr = AVIMakeCompressedStream(&recordavi_compressed_video_stream, recordavi_uncompressed_video_stream, &opts, NULL); + if (FAILED(hr)) + { + Con_Printf("Failed to init compressor\n"); + Media_StopRecordFilm_f(); + return; + } + } - memset(&stream_header, 0, sizeof(stream_header)); - stream_header.fccType = streamtypeAUDIO; - stream_header.dwScale = recordavi_wave_format.nBlockAlign; - stream_header.dwRate = stream_header.dwScale * (unsigned long)recordavi_wave_format.nSamplesPerSec; - stream_header.dwSampleSize = recordavi_wave_format.nBlockAlign; - hr = AVIFileCreateStream(recordavi_file, &recordavi_uncompressed_audio_stream, &stream_header); - if (FAILED(hr)) return; + hr = AVIStreamSetFormat(recordavi_video_stream, 0, &bitmap_info_header, sizeof(BITMAPINFOHEADER)); + if (FAILED(hr)) + { + Con_Printf("Failed to set format\n"); + Media_StopRecordFilm_f(); + return; + } - hr = AVIStreamSetFormat(recordavi_uncompressed_audio_stream, 0, &recordavi_wave_format, sizeof(WAVEFORMATEX)); - if (FAILED(hr)) return; + if (capturesound.value) + { + memset(&recordavi_wave_format, 0, sizeof(WAVEFORMATEX)); + recordavi_wave_format.wFormatTag = WAVE_FORMAT_PCM; + recordavi_wave_format.nChannels = 2; // always stereo in Quake sound engine + recordavi_wave_format.nSamplesPerSec = sndcardinfo->sn.speed; + recordavi_wave_format.wBitsPerSample = 16; // always 16bit in Quake sound engine + recordavi_wave_format.nBlockAlign = recordavi_wave_format.wBitsPerSample/8 * recordavi_wave_format.nChannels; + recordavi_wave_format.nAvgBytesPerSec = recordavi_wave_format.nSamplesPerSec * recordavi_wave_format.nBlockAlign; + recordavi_wave_format.cbSize = 0; + + + memset(&stream_header, 0, sizeof(stream_header)); + stream_header.fccType = streamtypeAUDIO; + stream_header.dwScale = recordavi_wave_format.nBlockAlign; + stream_header.dwRate = stream_header.dwScale * (unsigned long)recordavi_wave_format.nSamplesPerSec; + stream_header.dwSampleSize = recordavi_wave_format.nBlockAlign; + + hr = AVIFileCreateStream(recordavi_file, &recordavi_uncompressed_audio_stream, &stream_header); + if (FAILED(hr)) return; + + hr = AVIStreamSetFormat(recordavi_uncompressed_audio_stream, 0, &recordavi_wave_format, sizeof(WAVEFORMATEX)); + if (FAILED(hr)) return; + } + + + recordavi_videotime = realtime; + recordavi_audiotime = realtime; + + captureaudiomem = BZ_Malloc(recordavi_wave_format.nSamplesPerSec*2); + + capturevideomem = BZ_Malloc(glwidth*glheight*3); } - - - recordavi_videotime = realtime; - recordavi_audiotime = realtime; - - capturevideomem = BZ_Malloc(glwidth*glheight*3); - captureaudiomem = BZ_Malloc(recordavi_wave_format.nSamplesPerSec*2); } void Media_CaptureDemoEnd(void) { diff --git a/engine/client/r_part.c b/engine/client/r_part.c index a97e8bcaf..24fb2dc99 100644 --- a/engine/client/r_part.c +++ b/engine/client/r_part.c @@ -512,7 +512,7 @@ void R_ParticleEffect_f(void) ptype->spawnmode = SM_LAVASPLASH; else ptype->spawnmode = SM_BOX; - + } else if (!strcmp(var, "isbeam")) ptype->isbeam = true; diff --git a/engine/client/sbar.c b/engine/client/sbar.c index 6f06c163e..8335aeedb 100644 --- a/engine/client/sbar.c +++ b/engine/client/sbar.c @@ -1323,6 +1323,9 @@ void Sbar_DrawFace (int pnum) f = 4; else f = cl.stats[pnum][STAT_HEALTH] / 20; + + if (f < 0) + f=0; if (cl.time <= cl.faceanimtime[pnum]) { diff --git a/engine/common/gl_q2bsp.c b/engine/common/gl_q2bsp.c index 1b11420d5..86e9ad7c1 100644 --- a/engine/common/gl_q2bsp.c +++ b/engine/common/gl_q2bsp.c @@ -970,7 +970,7 @@ void *Mod_LoadWall(char *name) tex->height = height; texture_mode = GL_LINEAR_MIPMAP_NEAREST; //_LINEAR; - if (!(tex->gl_texturenum = Mod_LoadReplacementTexture(name, true, false))) + if (!(tex->gl_texturenum = Mod_LoadReplacementTexture(name, true, false, true))) tex->gl_texturenum = GL_LoadTexture32 (name, width, height, (unsigned int *)in, true, false); texture_mode = GL_LINEAR; } @@ -1052,7 +1052,7 @@ void *Mod_LoadWall(char *name) tex->height = wal->height; texture_mode = GL_LINEAR_MIPMAP_NEAREST; //_LINEAR; - if (!(tex->gl_texturenum = Mod_LoadReplacementTexture(wal->name, true, false))) + if (!(tex->gl_texturenum = Mod_LoadReplacementTexture(wal->name, true, false, true))) tex->gl_texturenum = GL_LoadTexture8Pal24 (wal->name, tex->width, tex->height, (qbyte *)wal+wal->offsets[0], d_q28to24table, true, false); in = Hunk_TempAllocMore(wal->width*wal->height); diff --git a/engine/common/mathlib.h b/engine/common/mathlib.h index efcf81912..ece9e354e 100644 --- a/engine/common/mathlib.h +++ b/engine/common/mathlib.h @@ -97,3 +97,6 @@ void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point, ) \ : \ BoxOnPlaneSide( (emins), (emaxs), (p))) + +//used for crosshair stuff. +void ML_Project (vec3_t in, vec3_t out, vec3_t viewangles, vec3_t vieworg, float wdivh, float fovy); diff --git a/engine/common/plugin.c b/engine/common/plugin.c index ad3c25344..035d1e654 100644 --- a/engine/common/plugin.c +++ b/engine/common/plugin.c @@ -218,6 +218,12 @@ int Plug_ExportToEngine(void *offset, unsigned int mask, const long *arg) currentplug->menufunction = arg[1]; else if (!strcmp(name, "UpdateVideo")) currentplug->reschange = arg[1]; + else if (!strcmp(name, "SbarBase")) //basic SBAR. + currentplug->sbarlevel[0] = arg[1]; + else if (!strcmp(name, "SbarSupplement")) //supplementry stuff - teamplay + currentplug->sbarlevel[1] = arg[1]; + else if (!strcmp(name, "SbarOverlay")) //overlay - scoreboard type stuff. + currentplug->sbarlevel[2] = arg[1]; else return 0; return 1; @@ -347,6 +353,128 @@ int Plug_Menu_Control(void *offset, unsigned int mask, const long *arg) } } +typedef struct { + //Make SURE that the engine has resolved all cvar pointers into globals before this happens. + plugin_t *plugin; + char name[64]; + qboolean picfromwad; + qpic_t *pic; +} pluginimagearray_t; +int pluginimagearraylen; +pluginimagearray_t *pluginimagearray; + +int Plug_Draw_LoadImage(void *offset, unsigned int mask, const long *arg) +{ + char *name = VM_POINTER(arg[0]); + qboolean fromwad = arg[1]; + int i; + + qpic_t *pic; + + for (i = 0; i < pluginimagearraylen; i++) + { + if (!pluginimagearray[i].plugin) + break; + if (pluginimagearray[i].plugin == currentplug) + { + if (!strcmp(name, pluginimagearray[i].name)) + break; + } + } + if (i == pluginimagearraylen) + { + pluginimagearraylen++; + pluginimagearray = BZ_Realloc(pluginimagearray, pluginimagearraylen*sizeof(pluginimagearray_t)); + } + + if (qrenderer) + { + if (fromwad) + pic = Draw_SafePicFromWad(name); + else + { +#ifdef RGLQUAKE //GL saves images persistantly (so don't bother with cachepic stuff) + if (qrenderer == QR_OPENGL) + pic = Draw_SafeCachePic(name); + else +#endif + pic = NULL; + } + } + else + pic = NULL; + + Q_strncpyz(pluginimagearray[i].name, name, sizeof(pluginimagearray[i].name)); + pluginimagearray[i].picfromwad = fromwad; + pluginimagearray[i].pic = pic; + pluginimagearray[i].plugin = currentplug; + return i; +} + +void Plug_DrawReloadImages(void) +{ + int i; + for (i = 0; i < pluginimagearraylen; i++) + { + if (!pluginimagearray[i].plugin) + continue; + + if (pluginimagearray[i].picfromwad) + pluginimagearray[i].pic = Draw_SafePicFromWad(pluginimagearray[i].name); +#ifdef RGLQUAKE + else if (qrenderer == QR_OPENGL) + pluginimagearray[i].pic = Draw_SafeCachePic(pluginimagearray[i].name); +#endif + else + pluginimagearray[i].pic = NULL; + } +} + +void GLDraw_Image(float x, float y, float w, float h, float s1, float t1, float s2, float t2, qpic_t *pic); +void SWDraw_Image (float xp, float yp, float wp, float hp, float s1, float t1, float s2, float t2, qpic_t *pic); +//int Draw_Image (float x, float y, float w, float h, float s1, float t1, float s2, float t2, qhandle_t image) +int Plug_Draw_Image(void *offset, unsigned int mask, const long *arg) +{ + qpic_t *pic; + int i; + if (!qrenderer) + return 0; + + i = VM_LONG(arg[8]); + if (i < 0 || i >= pluginimagearraylen) + return -1; // you fool + if (pluginimagearray[i].plugin != currentplug) + return -1; + + if (pluginimagearray[i].pic) + pic = pluginimagearray[i].pic; + else if (pluginimagearray[i].picfromwad) + return 0; //wasn't loaded. + else + pic = Draw_CachePic(pluginimagearray[i].name); + + switch (qrenderer) + { +#ifdef RGLQUAKE + case QR_OPENGL: + glEnable(GL_BLEND); + glDisable(GL_DEPTH_TEST); + glDisable(GL_ALPHA_TEST); + GLDraw_Image(VM_FLOAT(arg[0]), VM_FLOAT(arg[1]), VM_FLOAT(arg[2]), VM_FLOAT(arg[3]), VM_FLOAT(arg[4]), VM_FLOAT(arg[5]), VM_FLOAT(arg[6]), VM_FLOAT(arg[7]), pic); + break; +#endif +#ifdef SWQUAKE + case QR_SOFTWARE: + SWDraw_Image(VM_FLOAT(arg[0]), VM_FLOAT(arg[1]), VM_FLOAT(arg[2]), VM_FLOAT(arg[3]), VM_FLOAT(arg[4]), VM_FLOAT(arg[5]), VM_FLOAT(arg[6]), VM_FLOAT(arg[7]), pic); + break; +#endif + default: + break; + } + + return 1; +} + int Plug_Draw_Character(void *offset, unsigned int mask, const long *arg) { Draw_Character(arg[0], arg[1], (unsigned int)arg[2]); @@ -355,6 +483,26 @@ int Plug_Draw_Character(void *offset, unsigned int mask, const long *arg) int Plug_Draw_Fill(void *offset, unsigned int mask, const long *arg) { + float x, y, width, height; + x = VM_FLOAT(arg[0]); + y = VM_FLOAT(arg[1]); + width = VM_FLOAT(arg[2]); + height = VM_FLOAT(arg[3]); + switch(qrenderer) + { +#ifdef RGLQUAKE + case QR_OPENGL: + glDisable(GL_TEXTURE_2D); + glBegin(GL_QUADS); + glVertex2f(x, y); + glVertex2f(x+width, y); + glVertex2f(x+width, y+height); + glVertex2f(x, y+height); + glEnd(); + glEnable(GL_TEXTURE_2D); + return 1; +#endif + } return 0; } @@ -369,12 +517,16 @@ int Plug_Draw_ColourP(void *offset, unsigned int mask, const long *arg) switch(qrenderer) { +#ifdef RGLQUAKE case QR_OPENGL: glColor3f(pal[0]/255.0f, pal[1]/255.0f, pal[2]/255.0f); break; +#endif +#ifdef SWQUAKE case QR_SOFTWARE: SWDraw_ImageColours(pal[0]/255.0f, pal[1]/255.0f, pal[2]/255.0f, 1); break; +#endif default: return 0; } @@ -385,12 +537,16 @@ int Plug_Draw_Colour3f(void *offset, unsigned int mask, const long *arg) { switch(qrenderer) { +#ifdef RGLQUAKE case QR_OPENGL: glColor3f(VM_FLOAT(arg[0]), VM_FLOAT(arg[1]), VM_FLOAT(arg[2])); break; +#endif +#ifdef SWQUAKE case QR_SOFTWARE: SWDraw_ImageColours(VM_FLOAT(arg[0]), VM_FLOAT(arg[1]), VM_FLOAT(arg[2]), 1); break; +#endif default: return 0; } @@ -400,12 +556,16 @@ int Plug_Draw_Colour4f(void *offset, unsigned int mask, const long *arg) { switch(qrenderer) { +#ifdef RGLQUAKE case QR_OPENGL: glColor4f(VM_FLOAT(arg[0]), VM_FLOAT(arg[1]), VM_FLOAT(arg[2]), VM_FLOAT(arg[3])); break; +#endif +#ifdef SWQUAKE case QR_SOFTWARE: SWDraw_ImageColours(VM_FLOAT(arg[0]), VM_FLOAT(arg[1]), VM_FLOAT(arg[2]), VM_FLOAT(arg[3])); break; +#endif default: return 0; } @@ -500,6 +660,29 @@ int Plug_Cmd_AddText(void *offset, unsigned int mask, const long *arg) return 1; } +int Plug_CL_GetStats(void *offset, unsigned int mask, const long *arg) +{ + int i; + int pnum = VM_LONG(arg[0]); + unsigned int *stats = VM_POINTER(arg[1]); + int pluginstats = VM_LONG(arg[2]); + int max; + + if (VM_OOB(arg[1], arg[2]*4)) + return 0; + + max = pluginstats; + if (max > MAX_CL_STATS) + max = MAX_CL_STATS; + for (i = 0; i < max; i++) + { //fill stats with the right player's stats + stats[i] = cl.stats[pnum][i]; + } + for (; i < pluginstats; i++) //plugin has too many stats (wow) + stats[i] = 0; //fill the rest. + return max; +} + void Plug_Init(void) { Plug_RegisterBuiltin("Plug_GetEngineFunction", Plug_FindBuiltin, 0);//plugin wishes to find a builtin number. @@ -513,7 +696,9 @@ void Plug_Init(void) Plug_RegisterBuiltin("Cmd_Argv", Plug_Cmd_Argv, 0); Plug_RegisterBuiltin("Cmd_AddText", Plug_Cmd_AddText, 0); + Plug_RegisterBuiltin("CL_GetStats", Plug_CL_GetStats, 0); Plug_RegisterBuiltin("Menu_Control", Plug_Menu_Control, 0); + Plug_RegisterBuiltin("Key_GetKeyCode", Plug_Key_GetKeyCode, 0); Plug_RegisterBuiltin("Cvar_Register", Plug_Cvar_Register, 0); Plug_RegisterBuiltin("Cvar_SetString", Plug_Cvar_SetString, 0); @@ -521,14 +706,15 @@ void Plug_Init(void) Plug_RegisterBuiltin("Cvar_GetString", Plug_Cvar_GetString, 0); Plug_RegisterBuiltin("Cvar_GetFloat", Plug_Cvar_GetFloat, 0); + Plug_RegisterBuiltin("Draw_LoadImage", Plug_Draw_LoadImage, 0); + Plug_RegisterBuiltin("Draw_Image", Plug_Draw_Image, 0); + Plug_RegisterBuiltin("Draw_Character", Plug_Draw_Character, 0); Plug_RegisterBuiltin("Draw_Fill", Plug_Draw_Fill, 0); Plug_RegisterBuiltin("Draw_Colourp", Plug_Draw_ColourP, 0); Plug_RegisterBuiltin("Draw_Colour3f", Plug_Draw_Colour3f, 0); Plug_RegisterBuiltin("Draw_Colour4f", Plug_Draw_Colour4f, 0); - Plug_RegisterBuiltin("Key_GetKeyCode", Plug_Key_GetKeyCode, 0); - #ifdef _WIN32 COM_EnumerateFiles("plugins/*x86.dll", Plug_Emumerated, "x86.dll"); #elif defined(__linux__) @@ -581,10 +767,65 @@ qboolean Plugin_ExecuteString(void) qboolean Plug_Menu_Event(int eventtype, int param) //eventtype = draw/keydown/keyup, param = time/key { + extern int mousecursor_x, mousecursor_y; + if (!menuplug) return false; - return VM_Call(menuplug->vm, menuplug->menufunction, eventtype, param); + return VM_Call(menuplug->vm, menuplug->menufunction, eventtype, param, mousecursor_x, mousecursor_y); +} + +void Plug_SBar(void) +{ + plugin_t *oc=currentplug; + int cp; + vrect_t rect; + + for (currentplug = plugs; currentplug; currentplug = currentplug->next) + { + if (currentplug->sbarlevel[0]) + { + for (cp = 0; cp < cl.splitclients; cp++) + { //if you don't use splitscreen, use a full videosize rect. + SCR_VRectForPlayer(&rect, cp); + VM_Call(currentplug->vm, currentplug->sbarlevel[0], cp, rect.x, rect.y, rect.width, rect.height); + } + break; + } + } + if (!currentplug) + { + Sbar_Draw(); + return; //our current sbar draws a scoreboard too. We don't want that bug to be quite so apparent. + //please don't implement this identical hack in your engines... + } + + for (currentplug = plugs; currentplug; currentplug = currentplug->next) + { + if (currentplug->sbarlevel[1]) + { + for (cp = 0; cp < cl.splitclients; cp++) + { //if you don't use splitscreen, use a full videosize rect. + SCR_VRectForPlayer(&rect, cp); + VM_Call(currentplug->vm, currentplug->sbarlevel[1], cp, rect.x, rect.y, rect.width, rect.height); + } + } + } + + for (currentplug = plugs; currentplug; currentplug = currentplug->next) + { + if (currentplug->sbarlevel[2]) + { + for (cp = 0; cp < cl.splitclients; cp++) + { //if you don't use splitscreen, use a full videosize rect. + SCR_VRectForPlayer(&rect, cp); + VM_Call(currentplug->vm, currentplug->sbarlevel[2], cp, rect.x, rect.y, rect.width, rect.height); + } + } + } + + + currentplug = oc; } void Plug_Close(plugin_t *plug) diff --git a/engine/common/vm.h b/engine/common/vm.h index 9bf1bda60..46e6e7610 100644 --- a/engine/common/vm.h +++ b/engine/common/vm.h @@ -30,9 +30,13 @@ int VARGS VM_Call(vm_t *vm, int instruction, ...); +//plugin functions +qboolean Plug_Menu_Event(int eventtype, int param); +void Plug_ResChanged(void); +void Plug_Tick(void); +void Plug_Init(void); - - +void Plug_SBar(void); diff --git a/engine/gl/gl_alias.c b/engine/gl/gl_alias.c index 44e6d537d..1640bb32f 100644 --- a/engine/gl/gl_alias.c +++ b/engine/gl/gl_alias.c @@ -1639,15 +1639,15 @@ static void *Q1_LoadSkins (daliasskintype_t *pskintype, qboolean alpha) outskin->skinheight = pq1inmodel->skinheight; sprintf(skinname, "%s_%i", loadname, i); - texture = Mod_LoadReplacementTexture(skinname, true, false); + texture = Mod_LoadReplacementTexture(skinname, true, false, true); if (!texture) { sprintf(skinname, "textures/models/%s_%i", loadname, i); - texture = Mod_LoadReplacementTexture(skinname, true, false); + texture = Mod_LoadReplacementTexture(skinname, true, false, true); if (texture && r_fb_models.value) { sprintf(skinname, "textures/models/%s_%i_luma", loadname, i); - fbtexture = Mod_LoadReplacementTexture(skinname, true, true); + fbtexture = Mod_LoadReplacementTexture(skinname, true, true, true); } else fbtexture = 0; @@ -1655,7 +1655,7 @@ static void *Q1_LoadSkins (daliasskintype_t *pskintype, qboolean alpha) else if (texture && r_fb_models.value) { sprintf(skinname, "%s_%i_luma", loadname, i); - fbtexture = Mod_LoadReplacementTexture(skinname, true, true); + fbtexture = Mod_LoadReplacementTexture(skinname, true, true, true); } else fbtexture = 0; @@ -1703,14 +1703,14 @@ static void *Q1_LoadSkins (daliasskintype_t *pskintype, qboolean alpha) for (t = 0; t < outskin->texnums; t++,data+=s, texnums++) { sprintf(skinname, "%s_%i%c", loadname, i, t+'a'); - texture = Mod_LoadReplacementTexture(skinname, true, false); + texture = Mod_LoadReplacementTexture(skinname, true, false, true); if (texture) { texnums->base = texture; if (r_fb_models.value) { sprintf(skinname, "%s_%i%c_luma", loadname, i, t+'a'); - texnums->fullbright = Mod_LoadReplacementTexture(skinname, true, true); + texnums->fullbright = Mod_LoadReplacementTexture(skinname, true, true, true); } } else @@ -1992,7 +1992,7 @@ static void Q2_LoadSkins(char *skins) outskin->ofstexnums = (char *)texnums - (char *)outskin; outskin->texnums=1; - texnums->base = Mod_LoadReplacementTexture(skins, true, false); + texnums->base = Mod_LoadReplacementTexture(skins, true, false, true); outskin->skinwidth = 0; outskin->skinheight = 0; outskin->skinspeed = 0; diff --git a/engine/gl/gl_draw.c b/engine/gl/gl_draw.c index 5f39497d5..8a354a794 100644 --- a/engine/gl/gl_draw.c +++ b/engine/gl/gl_draw.c @@ -242,11 +242,11 @@ qboolean Draw_RealPicFromWad (qpic_t *out, char *name) } //standard names substitution - texnum = Mod_LoadReplacementTexture(name, false, true); + texnum = Mod_LoadReplacementTexture(name, false, true, false); if (!in && !texnum) //try a q2 texture { sprintf(name2, "pics/%s", name); - texnum = Mod_LoadHiResTexture(name2, false, true, true); + texnum = Mod_LoadHiResTexture(name2, false, true, false); } if (texnum) @@ -361,8 +361,8 @@ qpic_t *GLDraw_SafeCachePic (char *path) if ((mem = ReadPCXFile((qbyte *)dat, com_filesize, &pic->pic.width, &pic->pic.height))) { gl = (glpic_t *)pic->pic.data; - if (!(gl->texnum = Mod_LoadReplacementTexture(alternatename, false, true))) - gl->texnum = GL_LoadTexture32(path, pic->pic.width, pic->pic.height, (unsigned *)dat, false, true); + if (!(gl->texnum = Mod_LoadReplacementTexture(alternatename, false, true, false))) + gl->texnum = GL_LoadTexture32(path, pic->pic.width, pic->pic.height, (unsigned *)dat, false, false); gl->sl = 0; gl->sh = 1; gl->tl = 0; @@ -401,7 +401,7 @@ qpic_t *GLDraw_SafeCachePic (char *path) if (mem) { gl = (glpic_t *)pic->pic.data; - if (!(gl->texnum = Mod_LoadReplacementTexture(alternatename, false, true))) + if (!(gl->texnum = Mod_LoadReplacementTexture(alternatename, false, true, false))) gl->texnum = GL_LoadTexture32(path, pic->pic.width, pic->pic.height, (unsigned *)dat, false, true); gl->sl = 0; gl->sh = 1; @@ -429,8 +429,8 @@ qpic_t *GLDraw_SafeCachePic (char *path) if ((mem = ReadJPEGFile((qbyte *)dat, com_filesize, &pic->pic.width, &pic->pic.height))) { gl = (glpic_t *)pic->pic.data; - if (!(gl->texnum = Mod_LoadReplacementTexture(alternatename, false, true))) - gl->texnum = GL_LoadTexture32(path, pic->pic.width, pic->pic.height, (unsigned *)mem, false, true); + if (!(gl->texnum = Mod_LoadReplacementTexture(alternatename, false, true, false))) + gl->texnum = GL_LoadTexture32(path, pic->pic.width, pic->pic.height, (unsigned *)mem, false, false); gl->sl = 0; gl->sh = 1; gl->tl = 0; @@ -510,7 +510,7 @@ qpic_t *GLDraw_SafeCachePic (char *path) pic->pic.height = dat->height; gl = (glpic_t *)pic->pic.data; - if (!(gl->texnum = Mod_LoadReplacementTexture(path, false, true))) + if (!(gl->texnum = Mod_LoadReplacementTexture(path, false, true, false))) gl->texnum = GL_LoadPicTexture (dat); gl->sl = 0; gl->sh = 1; @@ -701,11 +701,11 @@ TRACE(("dbg: GLDraw_ReInit: Allocating upload buffers\n")); // now turn them into textures TRACE(("dbg: GLDraw_ReInit: looking for conchars\n")); - if (!(char_texture=Mod_LoadReplacementTexture("gfx/conchars.lmp", false, true))) //no high res + if (!(char_texture=Mod_LoadReplacementTexture("gfx/conchars.lmp", false, true, false))) //no high res { if (!draw_chars) //or low res. { - if (!(char_texture=Mod_LoadHiResTexture("pics/conchars.pcx", false, true, true))) //try low res q2 path + if (!(char_texture=Mod_LoadHiResTexture("pics/conchars.pcx", false, true, false))) //try low res q2 path { char *tempchars = COM_LoadMallocFile("gfx/menu/conchars.lmp"); char *in, *out; @@ -837,7 +837,7 @@ TRACE(("dbg: GLDraw_ReInit: Allocating upload buffers\n")); TRACE(("dbg: GLDraw_ReInit: gfx/conchars2.lmp\n")); - if (!(char_tex2=Mod_LoadReplacementTexture("gfx/conchars2.lmp", false, true))) + if (!(char_tex2=Mod_LoadReplacementTexture("gfx/conchars2.lmp", false, true, false))) { if (!draw_chars) char_tex2 = char_texture; @@ -919,12 +919,12 @@ TRACE(("dbg: GLDraw_ReInit: Allocating upload buffers\n")); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); gl = (glpic_t *)conback->data; - if (!(gl->texnum=Mod_LoadReplacementTexture("gfx/conback.lmp", false, true))) + if (!(gl->texnum=Mod_LoadReplacementTexture("gfx/conback.lmp", false, true, false))) { if (!ncdata) //no fallback { - if (!(gl->texnum=Mod_LoadHiResTexture("pics/conback.pcx", false, true, true))) - if (!(gl->texnum=Mod_LoadReplacementTexture("gfx/menu/conback.lmp", false, true))) + if (!(gl->texnum=Mod_LoadHiResTexture("pics/conback.pcx", false, true, false))) + if (!(gl->texnum=Mod_LoadReplacementTexture("gfx/menu/conback.lmp", false, true, false))) Sys_Error ("Couldn't load gfx/conback.lmp"); //that's messed it up, hasn't it?... } else @@ -973,13 +973,16 @@ TRACE(("dbg: GLDraw_ReInit: Allocating upload buffers\n")); if (!draw_backtile) draw_backtile = Draw_SafeCachePic ("gfx/menu/backtile.lmp"); - detailtexture = Mod_LoadReplacementTexture("textures/detail", true, false); + detailtexture = Mod_LoadReplacementTexture("textures/detail", true, false, false); inited15to8 = false; + glClearColor (1,0,0,0); TRACE(("dbg: GLDraw_ReInit: PPL_LoadSpecularFragmentProgram\n")); PPL_LoadSpecularFragmentProgram(); + + Plug_DrawReloadImages(); } void GLDraw_Init (void) diff --git a/engine/gl/gl_model.c b/engine/gl/gl_model.c index 31b8c468b..39ddc0497 100644 --- a/engine/gl/gl_model.c +++ b/engine/gl/gl_model.c @@ -962,7 +962,7 @@ TRACE(("dbg: GLMod_LoadTextures: inittexturedescs\n")); base = W_ConvertWAD3Texture(mt, &mt->width, &mt->height, &alphaed); //convert texture to 32 bit. tx->alphaed = alphaed; texture_mode = GL_LINEAR_MIPMAP_NEAREST; //_LINEAR; - if (!(tx->gl_texturenum = Mod_LoadReplacementTexture(mt->name, true, alphaed))) + if (!(tx->gl_texturenum = Mod_LoadReplacementTexture(mt->name, true, alphaed, true))) tx->gl_texturenum = GL_LoadTexture32 (mt->name, tx->width, tx->height, (unsigned int *)base, true, alphaed); *tx->name = *mt->name; @@ -971,7 +971,7 @@ TRACE(("dbg: GLMod_LoadTextures: inittexturedescs\n")); else { texture_mode = GL_LINEAR_MIPMAP_NEAREST; //_LINEAR; - if (!(tx->gl_texturenum = Mod_LoadReplacementTexture(mt->name, true, false))) + if (!(tx->gl_texturenum = Mod_LoadReplacementTexture(mt->name, true, false, true))) tx->gl_texturenum = GL_LoadTexture (mt->name, tx->width, tx->height, base, true, false); texture_mode = GL_LINEAR; @@ -980,7 +980,7 @@ TRACE(("dbg: GLMod_LoadTextures: inittexturedescs\n")); _snprintf(altname, sizeof(altname)-1, "%s_luma", mt->name); if (gl_load24bit.value && r_fb_bmodels.value) { - tx->gl_texturenumfb = Mod_LoadReplacementTexture(altname, true, false); + tx->gl_texturenumfb = Mod_LoadReplacementTexture(altname, true, false, true); } if (!tx->gl_texturenumfb) //generate one (if possible). tx->gl_texturenumfb = GL_LoadTextureFB(altname, tx->width, tx->height, base, true, true); @@ -1152,7 +1152,7 @@ void GLMod_NowLoadExternal(void) } if (!(tx->gl_texturenum = Mod_LoadHiResTexture(tx->name, true, false, true))) - tx->gl_texturenum = Mod_LoadReplacementTexture("light1_4", true, false); + tx->gl_texturenum = Mod_LoadReplacementTexture("light1_4", true, false, true); texture_mode = GL_LINEAR; } } @@ -2762,7 +2762,7 @@ void * GLMod_LoadSpriteFrame (void * pin, mspriteframe_t **ppframe, int framenum COM_StripExtension(loadmodel->name, name); strcat(name, va("_%i", framenum)); - pspriteframe->gl_texturenum = Mod_LoadReplacementTexture(name, true, true); + pspriteframe->gl_texturenum = Mod_LoadReplacementTexture(name, true, true, true); if (version == SPRITE32_VERSION) { size *= 4; diff --git a/engine/gl/gl_screen.c b/engine/gl/gl_screen.c index 0d6621ac6..4b3f5de85 100644 --- a/engine/gl/gl_screen.c +++ b/engine/gl/gl_screen.c @@ -181,6 +181,8 @@ void GLSCR_UpdateScreen (void) GL_Set2D (); + GLR_BrightenScreen(); + // // draw any areas not covered by the refresh // @@ -191,7 +193,7 @@ void GLSCR_UpdateScreen (void) if (scr_drawdialog) { - Sbar_Draw (); + Plug_SBar (); SCR_ShowPics_Draw(); Draw_FadeScreen (); SCR_DrawNotifyString (); @@ -200,7 +202,7 @@ void GLSCR_UpdateScreen (void) else if (scr_drawloading) { SCR_DrawLoading (); - Sbar_Draw (); + Plug_SBar (); SCR_ShowPics_Draw(); } else if (cl.intermission == 1 && key_dest == key_game) @@ -222,7 +224,7 @@ void GLSCR_UpdateScreen (void) SCR_DrawFPS (); SCR_DrawTurtle (); SCR_DrawPause (); - Sbar_Draw (); + Plug_SBar (); SCR_ShowPics_Draw(); SCR_CheckDrawCenterString (); glTexEnvi ( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); @@ -234,8 +236,6 @@ void GLSCR_UpdateScreen (void) SCR_DrawConsole (false); } - GLR_BrightenScreen(); - GLV_UpdatePalette (); #if defined(_WIN32) && defined(RGLQUAKE) Media_RecordFrame(); diff --git a/engine/gl/gl_vidcommon.c b/engine/gl/gl_vidcommon.c index 2c0b2a54c..8c0f08ccf 100644 --- a/engine/gl/gl_vidcommon.c +++ b/engine/gl/gl_vidcommon.c @@ -384,7 +384,6 @@ void GL_Init(void *(*getglfunction) (char *name)) glClearColor (0,0,0,0); //clear to black so that it looks a little nicer on start. glClear(GL_COLOR_BUFFER_BIT); - glClearColor (1,0,0,0); glCullFace(GL_FRONT); glEnable(GL_TEXTURE_2D); diff --git a/engine/gl/gl_warp.c b/engine/gl/gl_warp.c index 78d5bcc46..8b0f12d1f 100644 --- a/engine/gl/gl_warp.c +++ b/engine/gl/gl_warp.c @@ -949,7 +949,7 @@ void GLR_InitSky (texture_t *mt) sprintf(name, "%s_solid", mt->name); strlwr(name); - solidskytexture = Mod_LoadReplacementTexture(name, true, false); + solidskytexture = Mod_LoadReplacementTexture(name, true, false, true); if (!solidskytexture) solidskytexture = GL_LoadTexture32(name, 128, 128, trans, true, false); /* @@ -974,7 +974,7 @@ void GLR_InitSky (texture_t *mt) sprintf(name, "%s_trans", mt->name); strlwr(name); - alphaskytexture = Mod_LoadReplacementTexture(name, true, true); + alphaskytexture = Mod_LoadReplacementTexture(name, true, true, true); if (!alphaskytexture) alphaskytexture = GL_LoadTexture32(name, 128, 128, trans, true, true); /* diff --git a/engine/gl/glmod_doom.c b/engine/gl/glmod_doom.c index 235f6a3b2..55a191ff7 100644 --- a/engine/gl/glmod_doom.c +++ b/engine/gl/glmod_doom.c @@ -265,7 +265,7 @@ int Doom_LoadFlat(char *name) sprintf(texname, "flat-%-.8s", name); strlwr(texname); - tex = Mod_LoadReplacementTexture(texname, true, false); + tex = Mod_LoadReplacementTexture(texname, true, false, true); if (tex) return tex; diff --git a/engine/gl/glquake.h b/engine/gl/glquake.h index 53efd2e87..86436568b 100644 --- a/engine/gl/glquake.h +++ b/engine/gl/glquake.h @@ -290,8 +290,8 @@ void R_DrawWorld (void); void GL_BuildLightmaps (void); void GL_LoadShaders(void); -int Mod_LoadReplacementTexture(char *name, qboolean mipmap, qboolean alpha); -int Mod_LoadHiResTexture(char *name, qboolean mipmap, qboolean alpha, qboolean colouradjust); +int Mod_LoadReplacementTexture(char *name, qboolean mipmap, qboolean alpha, qboolean gammaadjust); +int Mod_LoadHiResTexture(char *name, qboolean mipmap, qboolean alpha, qboolean gammaadjust); int Mod_LoadBumpmapTexture(char *name); #define LMBLOCK_WIDTH 128 diff --git a/engine/qclib/execloop.h b/engine/qclib/execloop.h index 6f03243ab..b3ff1a9d0 100644 --- a/engine/qclib/execloop.h +++ b/engine/qclib/execloop.h @@ -424,7 +424,7 @@ reeval: case OP_IFNOTS: RUNAWAYCHECK(); - if (!OPA->string || !*OPA->string) + if (!OPA->string || !OPA->string[progfuncs->stringtable]) st += (sofs)st->b - 1; // offset the s++ break; @@ -436,7 +436,7 @@ reeval: case OP_IFS: RUNAWAYCHECK(); - if (OPA->string && *OPA->string) + if (OPA->string && OPA->string[progfuncs->stringtable]) st += (sofs)st->b - 1; // offset the s++ break; diff --git a/engine/qclib/pr_exec.c b/engine/qclib/pr_exec.c index a56c83b13..f8936bc1d 100644 --- a/engine/qclib/pr_exec.c +++ b/engine/qclib/pr_exec.c @@ -233,11 +233,11 @@ int PR_EnterFunction (progfuncs_t *progfuncs, dfunction_t *f, int progsnum) pr_stack[pr_depth].f = pr_xfunction; pr_stack[pr_depth].progsnum = progsnum; pr_depth++; - if (pr_depth >= MAX_STACK_DEPTH) + if (pr_depth == MAX_STACK_DEPTH) { - printf ("stack overflow"); - PR_StackTrace (progfuncs); + printf ("stack overflow on call to %s", f->s_name); pr_depth--; + PR_StackTrace (progfuncs); return pr_xstatement; } @@ -761,7 +761,7 @@ void PR_ExecuteCode (progfuncs_t *progfuncs, int s) float *glob; - int fnum; + int fnum = pr_xfunction - pr_functions; runaway = 100000; @@ -850,7 +850,7 @@ void PR_ExecuteProgram (progfuncs_t *progfuncs, func_t fnum) // Host_Error ("PR_ExecuteProgram: NULL function from exe"); // PR_MoveParms(0, pr_typecurrent); - PR_SwitchProgs(progfuncs, 0); + PR_SwitchProgs(progfuncs, initial_progs); return; } diff --git a/engine/qclib/qcc.h b/engine/qclib/qcc.h index 3219e1bad..42d8f79a0 100644 --- a/engine/qclib/qcc.h +++ b/engine/qclib/qcc.h @@ -34,6 +34,7 @@ extern progfuncs_t *qccprogfuncs; #endif void *qccHunkAlloc(size_t mem); +void qccClearHunk(void); extern short (*BigShort) (short l); extern short (*LittleShort) (short l); diff --git a/engine/qclib/qcc_pr_comp.c b/engine/qclib/qcc_pr_comp.c index d2db188d4..7d6723293 100644 --- a/engine/qclib/qcc_pr_comp.c +++ b/engine/qclib/qcc_pr_comp.c @@ -1157,7 +1157,7 @@ static const char *QCC_VarAtOffset(unsigned int ofs, unsigned int size) QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var_b, QCC_dstatement_t **outstatement) { QCC_dstatement_t *statement; - QCC_def_t *var_c=NULL, *temp; + QCC_def_t *var_c=NULL, *temp=NULL; if (var_a) { @@ -2586,10 +2586,16 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func) //warning, the func could } } else + { oself = NULL; + d = NULL; + } } else + { oself = NULL; + d = NULL; + } if (arg>MAX_PARMS) QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[callconvention-1+MAX_PARMS], func, 0, (QCC_dstatement_t **)&st)); @@ -2693,7 +2699,14 @@ QCC_def_t *QCC_MakeFloatDef(float value) { QCC_def_t *cn; - cn = Hash_GetKey(&floatconstdefstable, *(int*)&value); + union { + float f; + int i; + } fi; + + fi.f = value; + + cn = Hash_GetKey(&floatconstdefstable, fi.i); if (cn) return cn; @@ -2713,7 +2726,7 @@ QCC_def_t *QCC_MakeFloatDef(float value) // copy the immediate to the global area cn->ofs = QCC_GetFreeOffsetSpace (type_size[type_integer->type]); - Hash_AddKey(&floatconstdefstable, *(int *)&value, cn); + Hash_AddKey(&floatconstdefstable, fi.i, cn); G_FLOAT(cn->ofs) = value; @@ -3080,7 +3093,10 @@ reloop: else if (ao->type->type == ev_float) nd = QCC_PR_Statement(&pr_opcodes[OP_MUL_F], nd, QCC_MakeFloatDef((float)d->type->size), NULL); //get add part else + { QCC_PR_ParseError(ERR_BADARRAYINDEXTYPE, "Array offset is not of integer or float type"); + nd = NULL; + } } if (nd->type->type == ao->type->type) @@ -3090,7 +3106,10 @@ reloop: else if (ao->type->type == ev_float) ao = QCC_PR_Statement(&pr_opcodes[OP_ADD_F], ao, nd, NULL); //get add part else + { QCC_PR_ParseError(ERR_BADARRAYINDEXTYPE, "Array offset is not of integer or float type"); + nd = NULL; + } } else { @@ -3113,7 +3132,10 @@ reloop: else if (ao->type->type == ev_float) ao = QCC_PR_Statement(&pr_opcodes[OP_MUL_F], ao, QCC_MakeFloatDef((float)d->type->size), NULL); //get add part else + { + nd = NULL; QCC_PR_ParseError(ERR_BADARRAYINDEXTYPE, "Array offset is not of integer or float type"); + } } newtype = d->type; @@ -3132,7 +3154,9 @@ reloop: newtype = nd->type;//don't be fooled } else + { nd = QCC_PR_Statement(&pr_opcodes[OP_LOADA_S], d, ao, NULL); //get pointer to precise def. + } break; case ev_vector: nd = QCC_PR_Statement(&pr_opcodes[OP_LOADA_V], d, ao, NULL); //get pointer to precise def. @@ -3157,6 +3181,7 @@ reloop: break; default: QCC_PR_ParseError(ERR_NOVALIDOPCODES, "No op available. Try assembler"); + nd = NULL; break; } d=nd; @@ -3215,6 +3240,7 @@ reloop: break; default: QCC_PR_ParseError(ERR_NOVALIDOPCODES, "No op available. Try assembler"); + nd = NULL; break; } @@ -3296,6 +3322,7 @@ reloop: break; default: QCC_PR_ParseError(ERR_NOVALIDOPCODES, "No op available. Try assembler"); + nd = NULL; break; } } @@ -3367,6 +3394,7 @@ reloop: // break; default: QCC_PR_ParseError(ERR_NOVALIDOPCODES, "No op available. Try assembler"); + nd = NULL; break; } @@ -3440,6 +3468,7 @@ reloop: // break; default: QCC_PR_ParseError(ERR_NOVALIDOPCODES, "No op available. Try assembler"); + nd = NULL; break; } @@ -4396,6 +4425,7 @@ void QCC_PR_ParseStatement (void) } if (keyword_switch && QCC_PR_Check("switch")) { + int op; int hcstyle; int defaultcase = -1; temp_t *et; @@ -4413,8 +4443,6 @@ void QCC_PR_ParseStatement (void) et = e->temp; e->temp = NULL; //so noone frees it until we finish this loop - hcstyle = QCC_OPCodeValid(&pr_opcodes[OP_SWITCH_F]); - //expands //switch (CONDITION) @@ -4444,31 +4472,37 @@ void QCC_PR_ParseStatement (void) //x is emitted in an opcode, stored as a register that we cannot access later. //it should be possible to nest these. - if (hcstyle) + switch(e->type->type) { - switch(e->type->type) - { - case ev_float: - QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_SWITCH_F], e, 0, &patch1)); - break; - case ev_entity: //whu??? - QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_SWITCH_E], e, 0, &patch1)); - break; - case ev_vector: - QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_SWITCH_V], e, 0, &patch1)); - break; - case ev_string: - QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_SWITCH_S], e, 0, &patch1)); - break; - case ev_function: - QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_SWITCH_FNC], e, 0, &patch1)); - break; - default: - hcstyle = false; - break; - } + case ev_float: + op = OP_SWITCH_F; + break; + case ev_entity: //whu??? + op = OP_SWITCH_E; + break; + case ev_vector: + op = OP_SWITCH_V; + break; + case ev_string: + op = OP_SWITCH_S; + break; + case ev_function: + op = OP_SWITCH_FNC; + break; + default: //err hmm. + op = 0; + break; } - if (!hcstyle) + + if (op) + hcstyle = QCC_OPCodeValid(&pr_opcodes[op]); + else + hcstyle = false; + + + if (hcstyle) + QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[op], e, 0, &patch1)); + else QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_GOTO], e, 0, &patch1)); QCC_PR_Expect (")"); //close bracket is after we save the statement to mem (so debugger does not show the if statement as being on the line after @@ -4543,6 +4577,7 @@ void QCC_PR_ParseStatement (void) break; default: QCC_PR_ParseError(ERR_BADSWITCHTYPE, "Bad switch type"); + e2 = NULL; break; } QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IF], e2, 0, &patch3)); @@ -6430,6 +6465,7 @@ void QCC_PR_ParseDefs (char *classname) // return; // } QCC_PR_ParseError (ERR_TYPEWITHNONAME, "type with no name"); + name = NULL; } else name = QCC_PR_ParseName (); @@ -6449,7 +6485,10 @@ void QCC_PR_ParseDefs (char *classname) else if (pr_immediate_type->type == ev_float && (float)(int)pr_immediate._float == pr_immediate._float) arraysize = (int)pr_immediate._float; else + { QCC_PR_ParseError (ERR_BADARRAYSIZE, "Definition of array (%s) size is not of a numerical value", name); + arraysize=0; //grrr... + } QCC_PR_Lex(); QCC_PR_Expect("]"); } @@ -7093,7 +7132,7 @@ pbool QCC_Include(char *filename) strcpy(fname, qccmsourcedir); strcat(fname, filename); } - QCC_LoadFile(fname, (void **)&newfile); + QCC_LoadFile(fname, (void*)&newfile); currentchunk = NULL; pr_file_p = newfile; QCC_PR_CompileFile(newfile, fname); diff --git a/engine/qclib/qcc_pr_lex.c b/engine/qclib/qcc_pr_lex.c index 4fa84f7d4..5353e6927 100644 --- a/engine/qclib/qcc_pr_lex.c +++ b/engine/qclib/qcc_pr_lex.c @@ -2584,6 +2584,8 @@ QCC_type_t *QCC_PR_ParseType (int newtype) type = NULL; if (QCC_PR_Check(",")) QCC_PR_ParseError(ERR_NOTANAME, "element missing name"); + + newparm = NULL; while (!QCC_PR_Check("}")) { if (QCC_PR_Check(",")) @@ -2630,6 +2632,7 @@ QCC_type_t *QCC_PR_ParseType (int newtype) type = NULL; if (QCC_PR_Check(",")) QCC_PR_ParseError(ERR_NOTANAME, "element missing name"); + newparm = NULL; while (!QCC_PR_Check("}")) { if (QCC_PR_Check(",")) diff --git a/engine/qclib/qccmain.c b/engine/qclib/qccmain.c index 25f12b7aa..d2c071233 100644 --- a/engine/qclib/qccmain.c +++ b/engine/qclib/qccmain.c @@ -1114,6 +1114,29 @@ strofs = (strofs+3)&~3; SafeSeek (h, 0, SEEK_SET); SafeWrite (h, &progs, sizeof(progs)); SafeClose (h); + + if (outputversion != 7 || !debugdefined) + { + if (opt_filenames) + { + printf("Not writing linenumbers file due to conflicting optimisation\n"); + } + else + { + unsigned int lnotype = *(unsigned int*)"LNOF"; + COM_StripExtension(destfile); + COM_DefaultExtension(destfile, ".lno"); + printf("Writing %s\n", destfile); + h = SafeOpenWrite (destfile, 2*1024*1024); + SafeWrite (h, &lnotype, sizeof(int)); + SafeWrite (h, &numglobaldefs, sizeof(int)); + SafeWrite (h, &numpr_globals, sizeof(int)); + SafeWrite (h, &numfielddefs, sizeof(int)); + SafeWrite (h, &numstatements, sizeof(int)); + SafeWrite (h, statement_linenums, numstatements*sizeof(int)); + SafeClose (h); + } + } } @@ -2447,8 +2470,8 @@ void QCC_main (int argc, char **argv) //as part of the quake engine int p; - extern char qcc_gamedir[]; #ifndef QCCONLY + extern char qcc_gamedir[]; char destfile2[1024], *s2; #endif char *s; @@ -2670,7 +2693,7 @@ memset(pr_immediate_string, 0, sizeof(pr_immediate_string)); else sprintf (qccmsourcedir, "%s/src/", qcc_gamedir); #else - sprintf (qccmsourcedir, ""); + *qccmsourcedir = '\0'; #endif QCC_InitData (); @@ -3132,7 +3155,7 @@ float (*LittleFloat) (float l); LoadFile ============== */ -char *QCC_ReadFile (char *fname, void *buffer, int len) +unsigned char *QCC_ReadFile (char *fname, void *buffer, int len) { long length; FILE *f; diff --git a/engine/sw/sw_draw.c b/engine/sw/sw_draw.c index 7b5f0c320..94aabad23 100644 --- a/engine/sw/sw_draw.c +++ b/engine/sw/sw_draw.c @@ -418,6 +418,8 @@ void SWDraw_Init (void) r_rectdesc.ptexbytes = draw_backtile->data; r_rectdesc.rowbytes = draw_backtile->width; } + + Plug_DrawReloadImages(); } void SWDraw_Shutdown(void) diff --git a/engine/sw/sw_screen.c b/engine/sw/sw_screen.c index 3dc49fd14..bb74949f3 100644 --- a/engine/sw/sw_screen.c +++ b/engine/sw/sw_screen.c @@ -160,12 +160,12 @@ void SWSCR_UpdateScreen (void) if (scr_drawloading) { SCR_DrawLoading (); - Sbar_Draw (); + Plug_SBar (); SCR_ShowPics_Draw(); } else if (scr_drawdialog) { - Sbar_Draw (); + Plug_SBar (); SCR_ShowPics_Draw(); Draw_FadeScreen (); SCR_DrawNotifyString (); @@ -189,7 +189,7 @@ void SWSCR_UpdateScreen (void) SCR_DrawTurtle (); SCR_DrawPause (); SCR_DrawFPS (); - Sbar_Draw (); + Plug_SBar (); SCR_ShowPics_Draw(); SCR_CheckDrawCenterString (); #ifdef TEXTEDITOR