From dfd02ad9e3b85794087d1fdf701563f675824fb1 Mon Sep 17 00:00:00 2001 From: Spoike Date: Sun, 5 Sep 2010 10:42:23 +0000 Subject: [PATCH] Fix hexen2 cd tracks. Fix zalon's crash. git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3605 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/client/cd_win.c | 16 +++++----- engine/client/client.h | 1 + engine/client/image.c | 3 ++ engine/client/m_mp3.c | 4 ++- engine/common/fs_zip.c | 5 ++- engine/gl/gl_shadow.c | 5 +++ engine/gl/gl_vidnt.c | 68 ++++++++++++++++++++--------------------- engine/qclib/initlib.c | 1 + engine/qclib/pr_edict.c | 2 ++ engine/qclib/progslib.h | 1 + engine/server/pr_cmds.c | 22 +++++++++++-- engine/server/server.h | 5 +-- engine/server/sv_user.c | 16 ++++++++-- 13 files changed, 98 insertions(+), 51 deletions(-) diff --git a/engine/client/cd_win.c b/engine/client/cd_win.c index 50e5a53b..ea401fda 100644 --- a/engine/client/cd_win.c +++ b/engine/client/cd_win.c @@ -104,21 +104,23 @@ static int CDAudio_GetAudioDiskInfo(void) return 0; } -#ifndef NOMEDIA -void Media_FakeTrack(int i, qboolean loop); -#endif - void CDAudio_Play(int track, qboolean looping) { DWORD dwReturn; MCI_PLAY_PARMS mciPlayParms; MCI_STATUS_PARMS mciStatusParms; +#ifndef NOMEDIA + if (Media_FakeTrack(track, looping)) + { + if (playing) + CDAudio_Stop(); + return; + } +#endif + if (!enabled) { -#ifndef NOMEDIA - Media_FakeTrack(track, looping); -#endif return; } diff --git a/engine/client/client.h b/engine/client/client.h index f493bf58..6cc317f8 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -1220,6 +1220,7 @@ typedef struct cin_s cin_t; struct cin_s *Media_StartCin(char *name); texid_t Media_UpdateForShader(cin_t *cin); void Media_ShutdownCin(cin_t *cin); +qboolean Media_FakeTrack(int i, qboolean loop); //these accept NULL for cin to mean the current fullscreen video void Media_Send_Command(cin_t *cin, char *command); diff --git a/engine/client/image.c b/engine/client/image.c index 9ba62f06..8d629e7e 100644 --- a/engine/client/image.c +++ b/engine/client/image.c @@ -2002,6 +2002,9 @@ texid_t R_LoadHiResTexture(char *name, char *subpath, unsigned int flags) int i, e; + if (!*name) + return r_nulltex; + image_width = 0; image_height = 0; diff --git a/engine/client/m_mp3.c b/engine/client/m_mp3.c index 943873b8..b376399e 100644 --- a/engine/client/m_mp3.c +++ b/engine/client/m_mp3.c @@ -216,7 +216,7 @@ void Media_Clear (void) } qboolean fakecdactive; -void Media_FakeTrack(int i, qboolean loop) +qboolean Media_FakeTrack(int i, qboolean loop) { char trackname[512]; @@ -234,9 +234,11 @@ void Media_FakeTrack(int i, qboolean loop) fakecdactive = true; media_playing = true; + return true; } else fakecdactive = false; + return false; } //actually, this func just flushes and states that it should be playing. the ambientsound func actually changes the track. diff --git a/engine/common/fs_zip.c b/engine/common/fs_zip.c index d383f4b0..8b0d7fd2 100644 --- a/engine/common/fs_zip.c +++ b/engine/common/fs_zip.c @@ -196,7 +196,10 @@ static void *FSZIP_LoadZipFile (vfsfile_t *packhandle, const char *desc) if (unzGetCurrentFileInfo (zip->handle, &file_info, newfiles[i].name, sizeof(newfiles[i].name), NULL, 0, NULL, 0) != UNZ_OK) Con_Printf("Zip Error\n"); Q_strlwr(newfiles[i].name); - newfiles[i].filelen = file_info.uncompressed_size; + if (!*newfiles[i].name || newfiles[i].name[strlen(newfiles[i].name)-1] == '/') + newfiles[i].filelen = -1; + else + newfiles[i].filelen = file_info.uncompressed_size; newfiles[i].filepos = file_info.c_offset; nextfileziphandle = unzGoToNextFile (zip->handle); diff --git a/engine/gl/gl_shadow.c b/engine/gl/gl_shadow.c index 4d9e9791..9b768fb4 100644 --- a/engine/gl/gl_shadow.c +++ b/engine/gl/gl_shadow.c @@ -2096,7 +2096,12 @@ void Sh_DrawLights(qbyte *vis) return; if (!gl_config.arb_shader_objects) + { + Con_Printf("Missing GL extensions: switching off realtime lighting.\n"); + r_shadow_realtime_world.ival = 0; + r_shadow_realtime_dlight.ival = 0; return; + } ignoreflags = (r_shadow_realtime_world.value?LFLAG_REALTIMEMODE:LFLAG_NORMALMODE); diff --git a/engine/gl/gl_vidnt.c b/engine/gl/gl_vidnt.c index fe5bc8ab..fb29e799 100644 --- a/engine/gl/gl_vidnt.c +++ b/engine/gl/gl_vidnt.c @@ -935,7 +935,7 @@ qboolean VID_AttachGL (rendererstate_t *info) if (qwglCreateContextAttribsARB) { HGLRC opengl3; - int attribs[7]; + int attribs[9]; char *mv; int i = 0; @@ -959,9 +959,9 @@ qboolean VID_AttachGL (rendererstate_t *info) //flags attribs[i+1] = 0; - if (vid_gl_context_debug.value) + if (vid_gl_context_debug.ival) attribs[i+1] |= WGL_CONTEXT_DEBUG_BIT_ARB; - if (vid_gl_context_forwardcompatible.value) + if (vid_gl_context_forwardcompatible.ival) attribs[i+1] |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; if (attribs[i+1]) @@ -970,39 +970,39 @@ qboolean VID_AttachGL (rendererstate_t *info) i += 2; } - attribs[i+1] = 0; - if (vid_gl_context_compatibility.value) - attribs[i+1] |= WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; - else - attribs[i+1] |= WGL_CONTEXT_CORE_PROFILE_BIT_ARB; - attribs[i] = WGL_CONTEXT_PROFILE_MASK_ARB; - i+=2; - - attribs[i] = 0; - - if (!i) + /*only switch contexts if there's actually a point*/ + if (i || !vid_gl_context_compatibility.ival) { - //just use the default (ie: max = opengl 2.1 or so) - } - else if ((opengl3 = qwglCreateContextAttribsARB(maindc, NULL, attribs))) - { - qwglMakeCurrent(NULL, NULL); - qwglDeleteContext(baseRC); - - baseRC = opengl3; - if (!qwglMakeCurrent( maindc, baseRC )) - { - Con_SafePrintf(CON_ERROR "wglMakeCurrent failed\n"); //green to make it show. - return false; - } - } - else - { - DWORD error = GetLastError(); - if (error == ERROR_INVALID_VERSION_ARB) - Con_Printf("Unsupported OpenGL context version (%s).\n", vid_gl_context_version.string); + attribs[i+1] = 0; + if (vid_gl_context_compatibility.ival) + attribs[i+1] |= WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; else - Con_Printf("Unknown error creating an OpenGL (%s) Context.\n", vid_gl_context_version.string); + attribs[i+1] |= WGL_CONTEXT_CORE_PROFILE_BIT_ARB; + attribs[i] = WGL_CONTEXT_PROFILE_MASK_ARB; + i+=2; + + attribs[i] = 0; + + if ((opengl3 = qwglCreateContextAttribsARB(maindc, NULL, attribs))) + { + qwglMakeCurrent(NULL, NULL); + qwglDeleteContext(baseRC); + + baseRC = opengl3; + if (!qwglMakeCurrent( maindc, baseRC )) + { + Con_SafePrintf(CON_ERROR "wglMakeCurrent failed\n"); //green to make it show. + return false; + } + } + else + { + DWORD error = GetLastError(); + if (error == ERROR_INVALID_VERSION_ARB) + Con_Printf("Unsupported OpenGL context version (%s).\n", vid_gl_context_version.string); + else + Con_Printf("Unknown error creating an OpenGL (%s) Context.\n", vid_gl_context_version.string); + } } } #endif diff --git a/engine/qclib/initlib.c b/engine/qclib/initlib.c index 77c4f13d..bc66c3e2 100644 --- a/engine/qclib/initlib.c +++ b/engine/qclib/initlib.c @@ -677,6 +677,7 @@ progexterns_t defexterns = { //used when loading a game NULL, //builtin_t *(*builtinsfor) (int num); //must return a pointer to the builtins that were used before the state was saved. NULL, //void (*loadcompleate) (int edictsize); //notification to reset any pointers. + NULL, (void*)malloc, //void *(*memalloc) (int size); //small string allocation malloced and freed randomly by the executor. (use memalloc if you want) free, //void (*memfree) (void * mem); diff --git a/engine/qclib/pr_edict.c b/engine/qclib/pr_edict.c index d6c4d57d..8fef90a4 100644 --- a/engine/qclib/pr_edict.c +++ b/engine/qclib/pr_edict.c @@ -1224,6 +1224,8 @@ char *ED_ParseEdict (progfuncs_t *progfuncs, char *data, edictrun_t *ent) if (!strcmp(keyname, "light")) //Quake lighthack - allows a field name and a classname to go by the same thing in the level editor if ((key = ED_FindField (progfuncs, "light_lev"))) goto cont; + if (externs->badfield && externs->badfield(progfuncs, (struct edict_s*)ent, keyname, qcc_token)) + continue; printf ("'%s' is not a field\n", keyname); continue; } diff --git a/engine/qclib/progslib.h b/engine/qclib/progslib.h index 635d29d4..5c474afb 100644 --- a/engine/qclib/progslib.h +++ b/engine/qclib/progslib.h @@ -150,6 +150,7 @@ typedef struct progexterns_s { //used when loading a game builtin_t *(*builtinsfor) (int num, int headercrc); //must return a pointer to the builtins that were used before the state was saved. void (*loadcompleate) (int edictsize); //notification to reset any pointers. + pbool (*badfield)(progfuncs_t *prinst, struct edict_s *ent, const char *keyname, const char *value); //called for any fields that are not registered void *(VARGS *memalloc) (int size); //small string allocation malloced and freed randomly by the executor. (use malloc if you want) void (VARGS *memfree) (void * mem); diff --git a/engine/server/pr_cmds.c b/engine/server/pr_cmds.c index 9b235a2a..0672297c 100644 --- a/engine/server/pr_cmds.c +++ b/engine/server/pr_cmds.c @@ -331,12 +331,27 @@ void CWStateOp (progfuncs_t *prinst, float startFrame, float endFrame, func_t cu void ThinkTimeOp (progfuncs_t *prinst, edict_t *ed, float var) { stdentvars_t *vars = ed->v; -#ifdef PARANOID - NUM_FOR_EDICT(ed); // Make sure it's in range -#endif vars->nextthink = pr_global_struct->time+var; } +pbool SV_BadField(progfuncs_t *inst, edict_t *foo, const char *keyname, const char *value) +{ + /*Worldspawn only fields...*/ + if (NUM_FOR_EDICT(inst, foo) == 0) + { + /*hexen2 midi - just mute it, we don't support it*/ + if (!stricmp(keyname, "MIDI")) + return true; + /*hexen2 does cd tracks slightly differently too*/ + if (!stricmp(keyname, "CD")) + { + sv.h2cdtrack = atoi(value); + return true; + } + } + return false; +} + //int QCEditor (char *filename, int line, int nump, char **parms); void QC_Clear(void); builtin_t pr_builtin[]; @@ -448,6 +463,7 @@ void Q_SetProgsParms(qboolean forcompiler) //used when loading a game svprogparms.builtinsfor = NULL;//builtin_t *(*builtinsfor) (int num); //must return a pointer to the builtins that were used before the state was saved. svprogparms.loadcompleate = NULL;//void (*loadcompleate) (int edictsize); //notification to reset any pointers. + svprogparms.badfield = SV_BadField; svprogparms.memalloc = PR_CB_Malloc;//void *(*memalloc) (int size); //small string allocation malloced and freed randomly svprogparms.memfree = PR_CB_Free;//void (*memfree) (void * mem); diff --git a/engine/server/server.h b/engine/server/server.h index 48b91ef7..49b882ca 100644 --- a/engine/server/server.h +++ b/engine/server/server.h @@ -141,6 +141,7 @@ typedef struct char lightstylecolours[MAX_LIGHTSTYLES]; }; } strings; + qbyte h2cdtrack; int allocated_client_slots; //number of slots available. (used mostly to stop single player saved games cacking up) @@ -260,11 +261,11 @@ typedef struct char *demolightstyles[MAX_LIGHTSTYLES]; #endif //==================================================== - - int num_static_entities; // movevars_t demomovevars; //FIXME:! //end this lot... (demo playback) + int num_static_entities; + svcustomtents_t customtents[255]; int csqcentversion[MAX_EDICTS];//prevents ent versions from going backwards diff --git a/engine/server/sv_user.c b/engine/server/sv_user.c index 0c1f5bfb..185fb2b1 100644 --- a/engine/server/sv_user.c +++ b/engine/server/sv_user.c @@ -378,7 +378,9 @@ void SV_New_f (void) ClientReliableCheckBlock(host_client, 2); ClientReliableWrite_Byte (host_client, svc_cdtrack); - if (svprogfuncs) + if (progstype == PROG_H2) + ClientReliableWrite_Byte (host_client, sv.h2cdtrack); + else if (svprogfuncs) ClientReliableWrite_Byte (host_client, ((edict_t*)sv.world.edicts)->v->sounds); else ClientReliableWrite_Byte (host_client, 0); @@ -470,8 +472,16 @@ void SVNQ_New_f (void) // send music MSG_WriteByte (&host_client->netchan.message, svc_cdtrack); - MSG_WriteByte (&host_client->netchan.message, ((edict_t*)sv.world.edicts)->v->sounds); - MSG_WriteByte (&host_client->netchan.message, ((edict_t*)sv.world.edicts)->v->sounds); + if (progstype == PROG_H2) + { + MSG_WriteByte (&host_client->netchan.message, sv.h2cdtrack); + MSG_WriteByte (&host_client->netchan.message, sv.h2cdtrack); + } + else + { + MSG_WriteByte (&host_client->netchan.message, ((edict_t*)sv.world.edicts)->v->sounds); + MSG_WriteByte (&host_client->netchan.message, ((edict_t*)sv.world.edicts)->v->sounds); + } // set view MSG_WriteByte (&host_client->netchan.message, svc_setview);