diff --git a/src/android/i_video.c b/src/android/i_video.c index b8bb4fefb..1909cd71a 100644 --- a/src/android/i_video.c +++ b/src/android/i_video.c @@ -19,10 +19,10 @@ boolean allow_fullscreen = false; consvar_t cv_vidwait = {"vid_wait", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; void I_StartupGraphics(void){} -void I_StartupHardwareGraphics(void){} - void I_ShutdownGraphics(void){} +void VID_StartupOpenGL(void){} + void I_SetPalette(RGBA_t *palette) { (void)palette; @@ -52,10 +52,8 @@ INT32 VID_SetMode(INT32 modenum) return 0; } -void VID_CheckRenderer(void) -{ - // .............. -} +void VID_CheckRenderer(void) {} +void VID_CheckGLLoaded(rendermode_t oldrender) {} const char *VID_GetModeName(INT32 modenum) { diff --git a/src/b_bot.c b/src/b_bot.c index 4fefbdcb6..9a4c20c17 100644 --- a/src/b_bot.c +++ b/src/b_bot.c @@ -459,6 +459,21 @@ boolean B_CheckRespawn(player_t *player) if (!sonic || sonic->health <= 0) return false; +#ifdef HAVE_BLUA + // B_RespawnBot doesn't do anything if the condition above this isn't met + { + UINT8 shouldForce = LUAh_BotRespawn(sonic, tails); + + if (P_MobjWasRemoved(sonic) || P_MobjWasRemoved(tails)) + return (shouldForce == 1); // mobj was removed + + if (shouldForce == 1) + return true; + else if (shouldForce == 2) + return false; + } +#endif + // Check if Sonic is busy first. // If he's doing any of these things, he probably doesn't want to see us. if (sonic->player->pflags & (PF_GLIDING|PF_SLIDING|PF_BOUNCING) diff --git a/src/console.c b/src/console.c index f8fa1314a..0f1ccbd33 100644 --- a/src/console.c +++ b/src/console.c @@ -97,6 +97,7 @@ static void CON_InputInit(void); static void CON_RecalcSize(void); static void CON_ChangeHeight(void); +static void CON_DrawBackpic(void); static void CONS_hudlines_Change(void); static void CONS_backcolor_Change(void); @@ -1530,6 +1531,51 @@ static void CON_DrawHudlines(void) con_clearlines = y; // this is handled by HU_Erase(); } +// Lactozilla: Draws the console's background picture. +static void CON_DrawBackpic(void) +{ + patch_t *con_backpic; + lumpnum_t piclump; + int x, w, h; + + // Get the lumpnum for CONSBACK, or fallback into MISSING. + piclump = W_CheckNumForName("CONSBACK"); + if (piclump == LUMPERROR) + piclump = W_GetNumForName("MISSING"); + + // Cache the Software patch. + con_backpic = W_CacheSoftwarePatchNum(piclump, PU_PATCH); + + // Center the backpic, and draw a vertically cropped patch. + w = (con_backpic->width * vid.dupx); + x = (vid.width / 2) - (w / 2); + h = con_curlines/vid.dupy; + + // If the patch doesn't fill the entire screen, + // then fill the sides with a solid color. + if (x > 0) + { + column_t *column = (column_t *)((UINT8 *)(con_backpic) + LONG(con_backpic->columnofs[0])); + if (!column->topdelta) + { + UINT8 *source = (UINT8 *)(column) + 3; + INT32 color = (source[0] | V_NOSCALESTART); + // left side + V_DrawFill(0, 0, x, con_curlines, color); + // right side + V_DrawFill((x + w), 0, (vid.width - w), con_curlines, color); + } + } + + // Cache the patch normally. + con_backpic = W_CachePatchNum(piclump, PU_PATCH); + V_DrawCroppedPatch(x << FRACBITS, 0, FRACUNIT, V_NOSCALESTART, con_backpic, + 0, ( BASEVIDHEIGHT - h ), BASEVIDWIDTH, h); + + // Unlock the cached patch. + W_UnlockCachedPatch(con_backpic); +} + // draw the console background, text, and prompt if enough place // static void CON_DrawConsole(void) @@ -1551,19 +1597,7 @@ static void CON_DrawConsole(void) // draw console background if (cons_backpic.value || con_forcepic) - { - patch_t *con_backpic = W_CachePatchName("CONSBACK", PU_PATCH); - int h; - - h = con_curlines/vid.dupy; - - // Jimita: CON_DrawBackpic just called V_DrawScaledPatch - //V_DrawScaledPatch(0, 0, 0, con_backpic); - V_DrawCroppedPatch(0, 0, FRACUNIT, 0, con_backpic, - 0, ( BASEVIDHEIGHT - h ), BASEVIDWIDTH, h); - - W_UnlockCachedPatch(con_backpic); - } + CON_DrawBackpic(); else { // inu: no more width (was always 0 and vid.width) diff --git a/src/d_main.c b/src/d_main.c index 40e7af22a..78ebbcd41 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1284,11 +1284,10 @@ void D_SRB2Main(void) // Set cv_renderer to the new render mode VID_CheckRenderer(); - SCR_ChangeRendererCVars(setrenderneeded); + SCR_ChangeRendererCVars(rendermode); - // check the renderer's state, and then clear setrenderneeded + // check the renderer's state D_CheckRendererState(); - setrenderneeded = 0; } wipegamestate = gamestate; diff --git a/src/d_netcmd.c b/src/d_netcmd.c index ddf6c341f..333dc015c 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1252,7 +1252,7 @@ static void SendNameAndColor(void) players[consoleplayer].skincolor = cv_playercolor.value; - if (players[consoleplayer].mo) + if (players[consoleplayer].mo && !players[consoleplayer].powers[pw_dye]) players[consoleplayer].mo->color = players[consoleplayer].skincolor; if (metalrecording) @@ -1364,8 +1364,9 @@ static void SendNameAndColor2(void) if (botingame) { players[secondplaya].skincolor = botcolor; - if (players[secondplaya].mo) + if (players[secondplaya].mo && !players[secondplaya].powers[pw_dye]) players[secondplaya].mo->color = players[secondplaya].skincolor; + SetPlayerSkinByNum(secondplaya, botskin-1); return; } @@ -1378,7 +1379,7 @@ static void SendNameAndColor2(void) // don't use secondarydisplayplayer: the second player must be 1 players[secondplaya].skincolor = cv_playercolor2.value; - if (players[secondplaya].mo) + if (players[secondplaya].mo && !players[secondplaya].powers[pw_dye]) players[secondplaya].mo->color = players[secondplaya].skincolor; if (cv_forceskin.value >= 0 && (netgame || multiplayer)) // Server wants everyone to use the same player diff --git a/src/d_player.h b/src/d_player.h index 209ff766d..8697e9836 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -48,6 +48,7 @@ typedef enum SF_FASTEDGE = 1<<12, // Faster edge teeter? SF_MULTIABILITY = 1<<13, // Revenge of Final Demo. SF_NONIGHTSROTATION = 1<<14, // Disable sprite rotation for NiGHTS + SF_NONIGHTSSUPER = 1<<15, // Disable super colors for NiGHTS (if you have SF_SUPER) // free up to and including 1<<31 } skinflags_t; @@ -278,6 +279,9 @@ typedef enum pw_nights_linkfreeze, pw_nocontrol, //for linedef exec 427 + + pw_dye, // for dyes + pw_justlaunched, // Launched off a slope this tic (0=none, 1=standard launch, 2=half-pipe launch) NUMPOWERS diff --git a/src/dehacked.c b/src/dehacked.c index 20d23d680..08ff13cf2 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -2909,6 +2909,7 @@ static actionpointer_t actionpointers[] = {{A_SetRandomTics}, "A_SETRANDOMTICS"}, {{A_ChangeColorRelative}, "A_CHANGECOLORRELATIVE"}, {{A_ChangeColorAbsolute}, "A_CHANGECOLORABSOLUTE"}, + {{A_Dye}, "A_DYE"}, {{A_MoveRelative}, "A_MOVERELATIVE"}, {{A_MoveAbsolute}, "A_MOVEABSOLUTE"}, {{A_Thrust}, "A_THRUST"}, @@ -9132,7 +9133,11 @@ static const char *const POWERS_LIST[] = { //for linedef exec 427 "NOCONTROL", - "JUSTLAUNCHED", + + //for dyes + "DYE", + + "JUSTLAUNCHED" }; static const char *const HUDITEMS_LIST[] = { @@ -9467,6 +9472,7 @@ struct { {"SF_FASTEDGE",SF_FASTEDGE}, {"SF_MULTIABILITY",SF_MULTIABILITY}, {"SF_NONIGHTSROTATION",SF_NONIGHTSROTATION}, + {"SF_NONIGHTSSUPER",SF_NONIGHTSSUPER}, // Dashmode constants {"DASHMODE_THRESHOLD",DASHMODE_THRESHOLD}, diff --git a/src/djgppdos/i_video.c b/src/djgppdos/i_video.c index 02c7a842b..f525b96ca 100644 --- a/src/djgppdos/i_video.c +++ b/src/djgppdos/i_video.c @@ -339,7 +339,4 @@ void I_StartupGraphics(void) } -void I_StartupHardwareGraphics(void) -{ - // oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo y -} +void VID_StartupOpenGL(void) {} diff --git a/src/djgppdos/vid_vesa.c b/src/djgppdos/vid_vesa.c index c8ce7dae5..61ed18e4b 100644 --- a/src/djgppdos/vid_vesa.c +++ b/src/djgppdos/vid_vesa.c @@ -378,10 +378,8 @@ INT32 VID_SetMode (INT32 modenum) //, UINT8 *palette) return 1; } -void VID_CheckRenderer(void) -{ - // .............. -} +void VID_CheckRenderer(void) {} +void VID_CheckGLLoaded(rendermode_t oldrender) {} diff --git a/src/dummy/i_video.c b/src/dummy/i_video.c index fafeee000..56ead3672 100644 --- a/src/dummy/i_video.c +++ b/src/dummy/i_video.c @@ -11,10 +11,10 @@ boolean allow_fullscreen = false; consvar_t cv_vidwait = {"vid_wait", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; void I_StartupGraphics(void){} -void I_StartupHardwareGraphics(void){} - void I_ShutdownGraphics(void){} +void VID_StartupOpenGL(void){} + void I_SetPalette(RGBA_t *palette) { (void)palette; @@ -40,10 +40,8 @@ INT32 VID_SetMode(INT32 modenum) return 0; } -void VID_CheckRenderer(void) -{ - // .............. -} +void VID_CheckRenderer(void) {} +void VID_CheckGLLoaded(rendermode_t oldrender) {} const char *VID_GetModeName(INT32 modenum) { diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index 598a635aa..d01331765 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -291,7 +291,7 @@ void HWR_DrawStretchyFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t if (cx >= -0.1f && cx <= 0.1f && SHORT(gpatch->width) == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && SHORT(gpatch->height) == BASEVIDHEIGHT) { // Need to temporarily cache the real patch to get the colour of the top left pixel - patch_t *realpatch = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC); + patch_t *realpatch = W_CacheSoftwarePatchNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC); const column_t *column = (const column_t *)((const UINT8 *)(realpatch) + LONG((realpatch)->columnofs[0])); if (!column->topdelta) { @@ -450,7 +450,7 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal if (cx >= -0.1f && cx <= 0.1f && SHORT(gpatch->width) == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && SHORT(gpatch->height) == BASEVIDHEIGHT) { // Need to temporarily cache the real patch to get the colour of the top left pixel - patch_t *realpatch = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC); + patch_t *realpatch = W_CacheSoftwarePatchNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC); const column_t *column = (const column_t *)((const UINT8 *)(realpatch) + LONG((realpatch)->columnofs[0])); if (!column->topdelta) { diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 51c6471ac..7ee96ed62 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -3983,7 +3983,10 @@ static void HWR_DrawDropShadow(mobj_t *thing, gr_vissprite_t *spr, fixed_t scale { light = R_GetPlaneLight(thing->subsector->sector, floorz, false); // Always use the light at the top instead of whatever I was doing before - lightlevel = *thing->subsector->sector->lightlist[light].lightlevel; + if (*thing->subsector->sector->lightlist[light].lightlevel > 255) + lightlevel = 255; + else + lightlevel = *thing->subsector->sector->lightlist[light].lightlevel; if (*thing->subsector->sector->lightlist[light].extra_colormap) colormap = *thing->subsector->sector->lightlist[light].extra_colormap; @@ -4184,7 +4187,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) if (h <= temp) { if (!(spr->mobj->frame & FF_FULLBRIGHT)) - lightlevel = *list[i-1].lightlevel; + lightlevel = *list[i-1].lightlevel > 255 ? 255 : *list[i-1].lightlevel; colormap = *list[i-1].extra_colormap; break; } @@ -4199,7 +4202,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) if (!(list[i].flags & FF_NOSHADE) && (list[i].flags & FF_CUTSPRITES)) { if (!(spr->mobj->frame & FF_FULLBRIGHT)) - lightlevel = *list[i].lightlevel; + lightlevel = *list[i].lightlevel > 255 ? 255 : *list[i].lightlevel; colormap = *list[i].extra_colormap; } @@ -4420,7 +4423,7 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) extracolormap_t *colormap = sector->extra_colormap; if (!(spr->mobj->frame & FF_FULLBRIGHT)) - lightlevel = sector->lightlevel; + lightlevel = sector->lightlevel > 255 ? 255 : sector->lightlevel; if (colormap) Surf.FlatColor.rgba = HWR_Lighting(lightlevel, colormap->rgba, colormap->fadergba, false, false); @@ -4517,7 +4520,7 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr) light = R_GetPlaneLight(sector, spr->mobj->z + spr->mobj->height, false); // Always use the light at the top instead of whatever I was doing before if (!(spr->mobj->frame & FF_FULLBRIGHT)) - lightlevel = *sector->lightlist[light].lightlevel; + lightlevel = *sector->lightlist[light].lightlevel > 255 ? 255 : *sector->lightlist[light].lightlevel; if (*sector->lightlist[light].extra_colormap) colormap = *sector->lightlist[light].extra_colormap; @@ -4525,7 +4528,7 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr) else { if (!(spr->mobj->frame & FF_FULLBRIGHT)) - lightlevel = sector->lightlevel; + lightlevel = sector->lightlevel > 255 ? 255 : sector->lightlevel; if (sector->extra_colormap) colormap = sector->extra_colormap; @@ -6346,7 +6349,6 @@ void HWR_Shutdown(void) CONS_Printf("HWR_Shutdown()\n"); HWR_FreeExtraSubsectors(); HWR_FreePolyPool(); - HWR_FreeMipmapCache(); HWR_FreeTextureCache(); HWD.pfnFlushScreenTextures(); } diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 5c3cd40a6..2e3af4a4c 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1221,7 +1221,7 @@ boolean HWR_DrawModel(gr_vissprite_t *spr) light = R_GetPlaneLight(sector, spr->mobj->z + spr->mobj->height, false); // Always use the light at the top instead of whatever I was doing before if (!(spr->mobj->frame & FF_FULLBRIGHT)) - lightlevel = *sector->lightlist[light].lightlevel; + lightlevel = *sector->lightlist[light].lightlevel > 255 ? 255 : *sector->lightlist[light].lightlevel; if (*sector->lightlist[light].extra_colormap) colormap = *sector->lightlist[light].extra_colormap; @@ -1229,7 +1229,7 @@ boolean HWR_DrawModel(gr_vissprite_t *spr) else { if (!(spr->mobj->frame & FF_FULLBRIGHT)) - lightlevel = sector->lightlevel; + lightlevel = sector->lightlevel > 255 ? 255 : sector->lightlevel; if (sector->extra_colormap) colormap = sector->extra_colormap; diff --git a/src/i_video.h b/src/i_video.h index bdc10c9c5..98ed7f38a 100644 --- a/src/i_video.h +++ b/src/i_video.h @@ -36,10 +36,10 @@ typedef enum */ extern rendermode_t rendermode; -/** \brief hardware renderer loaded +/** \brief OpenGL state 0 = never loaded, 1 = loaded successfully, -1 = failed loading */ -extern INT32 hwrenderloaded; +extern INT32 vid_opengl_state; /** \brief use highcolor modes if true */ @@ -49,11 +49,7 @@ extern boolean highcolor; */ void I_StartupGraphics(void); -/** \brief setup hardware mode -*/ -void I_StartupHardwareGraphics(void); - -/** \brief restore old video mode +/** \brief shutdown video mode */ void I_ShutdownGraphics(void); @@ -97,6 +93,14 @@ INT32 VID_SetMode(INT32 modenum); */ void VID_CheckRenderer(void); +/** \brief Load OpenGL mode +*/ +void VID_StartupOpenGL(void); + +/** \brief Checks if OpenGL loaded +*/ +void VID_CheckGLLoaded(rendermode_t oldrender); + /** \brief The VID_GetModeName function \param modenum video mode number diff --git a/src/info.h b/src/info.h index f8a713674..586209ff9 100644 --- a/src/info.h +++ b/src/info.h @@ -165,6 +165,7 @@ void A_SetTics(); void A_SetRandomTics(); void A_ChangeColorRelative(); void A_ChangeColorAbsolute(); +void A_Dye(); void A_MoveRelative(); void A_MoveAbsolute(); void A_Thrust(); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 3379ad3aa..74938739c 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -218,10 +218,16 @@ static const char *GetUserdataUType(lua_State *L) // or players[0].powers -> "player_t.powers" static int lib_userdataType(lua_State *L) { + int type; lua_settop(L, 1); // pop everything except arg 1 (in case somebody decided to add more) - luaL_checktype(L, 1, LUA_TUSERDATA); - lua_pushstring(L, GetUserdataUType(L)); - return 1; + type = lua_type(L, 1); + if (type == LUA_TLIGHTUSERDATA || type == LUA_TUSERDATA) + { + lua_pushstring(L, GetUserdataUType(L)); + return 1; + } + else + return luaL_typerror(L, 1, "userdata"); } static int lib_isPlayerAdmin(lua_State *L) diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index a9fbad65f..4fe234dee 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -430,22 +430,8 @@ static int lib_cvRegisterVar(lua_State *L) static int lib_cvFindVar(lua_State *L) { - consvar_t *cv; - if (( cv = CV_FindVar(luaL_checkstring(L,1)) )) - { - lua_settop(L,1);/* We only want one argument in the stack. */ - lua_pushlightuserdata(L, cv);/* Now the second value on stack. */ - luaL_getmetatable(L, META_CVAR); - /* - The metatable is the last value on the stack, so this - applies it to the second value, which is the cvar. - */ - lua_setmetatable(L,2); - lua_pushvalue(L,2); - return 1; - } - else - return 0; + LUA_PushLightUserdata(L, CV_FindVar(luaL_checkstring(L,1)), META_CVAR); + return 1; } // CONS_Printf for a single player diff --git a/src/lua_hook.h b/src/lua_hook.h index 7aaac6581..48f6cab32 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -40,6 +40,7 @@ enum hook { hook_JumpSpinSpecial, hook_BotTiccmd, hook_BotAI, + hook_BotRespawn, hook_LinedefExecute, hook_PlayerMsg, hook_HurtMsg, @@ -92,6 +93,7 @@ boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 #define LUAh_JumpSpinSpecial(player) LUAh_PlayerHook(player, hook_JumpSpinSpecial) // Hook for P_DoJumpStuff (Spin button effect (mid-air)) boolean LUAh_BotTiccmd(player_t *bot, ticcmd_t *cmd); // Hook for B_BuildTiccmd boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd); // Hook for B_BuildTailsTiccmd by skin name +boolean LUAh_BotRespawn(mobj_t *sonic, mobj_t *tails); // Hook for B_CheckRespawn boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector); // Hook for linedef executors boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg); // Hook for chat messages boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 damagetype); // Hook for hurt messages diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 88f1b291d..99a2eb4cb 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -52,6 +52,7 @@ const char *const hookNames[hook_MAX+1] = { "JumpSpinSpecial", "BotTiccmd", "BotAI", + "BotRespawn", "LinedefExecute", "PlayerMsg", "HurtMsg", @@ -81,9 +82,7 @@ struct hook_s UINT16 id; union { mobjtype_t mt; - char *skinname; - char *musname; - char *funcname; + char *str; } s; boolean error; }; @@ -152,28 +151,16 @@ static int lib_addHook(lua_State *L) break; case hook_BotAI: case hook_ShouldJingleContinue: - hook.s.skinname = NULL; + hook.s.str = NULL; if (lua_isstring(L, 2)) { // lowercase copy - const char *s = lua_tostring(L, 2); - char *p = hook.s.skinname = ZZ_Alloc(strlen(s)+1); - do { - *p = tolower(*s); - ++p; - } while(*(++s)); - *p = 0; + hook.s.str = Z_StrDup(lua_tostring(L, 2)); + strlwr(hook.s.str); } break; case hook_LinedefExecute: // Linedef executor functions - { // uppercase copy - const char *s = luaL_checkstring(L, 2); - char *p = hook.s.funcname = ZZ_Alloc(strlen(s)+1); - do { - *p = toupper(*s); - ++p; - } while(*(++s)); - *p = 0; - } + hook.s.str = Z_StrDup(luaL_checkstring(L, 2)); + strupr(hook.s.str); break; default: break; @@ -1076,7 +1063,7 @@ boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) for (hookp = roothook; hookp; hookp = hookp->next) { if (hookp->type != hook_BotAI - || (hookp->s.skinname && strcmp(hookp->s.skinname, ((skin_t*)tails->skin)->name))) + || (hookp->s.str && strcmp(hookp->s.str, ((skin_t*)tails->skin)->name))) continue; if (lua_gettop(gL) == 0) @@ -1126,6 +1113,51 @@ boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) return hooked; } +// Hook for B_CheckRespawn +boolean LUAh_BotRespawn(mobj_t *sonic, mobj_t *tails) +{ + hook_p hookp; + UINT8 shouldRespawn = 0; // 0 = default, 1 = force yes, 2 = force no. + if (!gL || !(hooksAvailable[hook_BotRespawn/8] & (1<<(hook_BotRespawn%8)))) + return false; + + lua_settop(gL, 0); + + for (hookp = roothook; hookp; hookp = hookp->next) + { + if (hookp->type != hook_BotRespawn) + continue; + + if (lua_gettop(gL) == 0) + { + LUA_PushUserdata(gL, sonic, META_MOBJ); + LUA_PushUserdata(gL, tails, META_MOBJ); + } + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + lua_pushvalue(gL, -3); + lua_pushvalue(gL, -3); + if (lua_pcall(gL, 2, 1, 0)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + continue; + } + if (!lua_isnil(gL, -1)) + { + if (lua_toboolean(gL, -1)) + shouldRespawn = 1; // Force yes + else + shouldRespawn = 2; // Force no + } + lua_pop(gL, 1); + } + + lua_settop(gL, 0); + return shouldRespawn; +} + // Hook for linedef executors boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector) { @@ -1138,7 +1170,7 @@ boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector) for (hookp = linedefexecutorhooks; hookp; hookp = hookp->next) { - if (strcmp(hookp->s.funcname, line->text)) + if (strcmp(hookp->s.str, line->text)) continue; if (lua_gettop(gL) == 0) @@ -1676,7 +1708,7 @@ boolean LUAh_ShouldJingleContinue(player_t *player, const char *musname) for (hookp = roothook; hookp; hookp = hookp->next) { if (hookp->type != hook_ShouldJingleContinue - || (hookp->s.musname && strcmp(hookp->s.musname, musname))) + || (hookp->s.str && strcmp(hookp->s.str, musname))) continue; if (lua_gettop(gL) == 0) diff --git a/src/lua_script.c b/src/lua_script.c index 8c0cd5351..1bc89180e 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -568,6 +568,27 @@ fixed_t LUA_EvalMath(const char *word) return res; } +/* +LUA_PushUserdata but no userdata is created. +You can't invalidate it therefore. +*/ + +void LUA_PushLightUserdata (lua_State *L, void *data, const char *meta) +{ + if (data) + { + lua_pushlightuserdata(L, data); + luaL_getmetatable(L, meta); + /* + The metatable is the last value on the stack, so this + applies it to the second value, which is the userdata. + */ + lua_setmetatable(L, -2); + } + else + lua_pushnil(L); +} + // Takes a pointer, any pointer, and a metatable name // Creates a userdata for that pointer with the given metatable // Pushes it to the stack and stores it in the registry. diff --git a/src/lua_script.h b/src/lua_script.h index 7bdf7685b..3166fdfc7 100644 --- a/src/lua_script.h +++ b/src/lua_script.h @@ -44,6 +44,7 @@ void LUA_LoadLump(UINT16 wad, UINT16 lump); void LUA_DumpFile(const char *filename); #endif fixed_t LUA_EvalMath(const char *word); +void LUA_PushLightUserdata(lua_State *L, void *data, const char *meta); void LUA_PushUserdata(lua_State *L, void *data, const char *meta); void LUA_InvalidateUserdata(void *data); void LUA_InvalidateLevel(void); diff --git a/src/m_fixed.h b/src/m_fixed.h index 7fdb9ad0a..cc54c1aea 100644 --- a/src/m_fixed.h +++ b/src/m_fixed.h @@ -38,8 +38,20 @@ typedef INT32 fixed_t; /*! \brief convert fixed_t into floating number */ -#define FIXED_TO_FLOAT(x) (((float)(x)) / ((float)FRACUNIT)) -#define FLOAT_TO_FIXED(f) (fixed_t)((f) * ((float)FRACUNIT)) + +FUNCMATH FUNCINLINE static ATTRINLINE float FixedToFloat(fixed_t x) +{ + return x / (float)FRACUNIT; +} + +FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FloatToFixed(float f) +{ + return (fixed_t)(f * FRACUNIT); +} + +// for backwards compat +#define FIXED_TO_FLOAT(x) FixedToFloat(x) // (((float)(x)) / ((float)FRACUNIT)) +#define FLOAT_TO_FIXED(f) FloatToFixed(f) // (fixed_t)((f) * ((float)FRACUNIT)) #if defined (__WATCOMC__) && FRACBITS == 16 diff --git a/src/m_menu.c b/src/m_menu.c index 0303b0de0..6ff13a19c 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -523,6 +523,8 @@ static menuitem_t MISC_AddonsMenu[] = // --------------------------------- static menuitem_t MAPauseMenu[] = { + {IT_CALL | IT_STRING, NULL, "Emblem Hints...", M_EmblemHints, 32}, + {IT_CALL | IT_STRING, NULL, "Continue", M_SelectableClearMenus,48}, {IT_CALL | IT_STRING, NULL, "Retry", M_ModeAttackRetry, 56}, {IT_CALL | IT_STRING, NULL, "Abort", M_ModeAttackEndGame, 64}, @@ -530,6 +532,7 @@ static menuitem_t MAPauseMenu[] = typedef enum { + mapause_hints, mapause_continue, mapause_retry, mapause_abort @@ -731,9 +734,9 @@ static menuitem_t SR_SoundTestMenu[] = static menuitem_t SR_EmblemHintMenu[] = { - {IT_STRING | IT_ARROWS, NULL, "Page", M_HandleEmblemHints, 10}, - {IT_STRING|IT_CVAR, NULL, "Emblem Radar", &cv_itemfinder, 20}, - {IT_WHITESTRING|IT_SUBMENU, NULL, "Back", &SPauseDef, 30} + {IT_STRING | IT_ARROWS, NULL, "Page", M_HandleEmblemHints, 10}, + {IT_STRING|IT_CVAR, NULL, "Emblem Radar", &cv_itemfinder, 20}, + {IT_WHITESTRING|IT_CALL, NULL, "Back", M_GoBack, 30} }; // -------------------------------- @@ -2099,7 +2102,7 @@ static void M_VideoOptions(INT32 choice) { (void)choice; #ifdef HWRENDER - if (hwrenderloaded == -1) + if (vid_opengl_state == -1) { OP_VideoOptionsMenu[op_video_renderer].status = (IT_TRANSTEXT | IT_PAIR); OP_VideoOptionsMenu[op_video_renderer].patch = "Renderer"; @@ -3635,6 +3638,7 @@ void M_StartControlPanel(void) else if (modeattacking) { currentMenu = &MAPauseDef; + MAPauseMenu[mapause_hints].status = (M_SecretUnlocked(SECRET_EMBLEMHINTS)) ? (IT_STRING | IT_CALL) : (IT_DISABLED); itemOn = mapause_continue; } else if (!(netgame || multiplayer)) // Single Player @@ -7307,6 +7311,7 @@ static void M_EmblemHints(INT32 choice) SR_EmblemHintMenu[0].status = (local > NUMHINTS*2) ? (IT_STRING | IT_ARROWS) : (IT_DISABLED); SR_EmblemHintMenu[1].status = (M_SecretUnlocked(SECRET_ITEMFINDER)) ? (IT_CVAR|IT_STRING) : (IT_SECRET); hintpage = 1; + SR_EmblemHintDef.prevMenu = currentMenu; M_SetupNextMenu(&SR_EmblemHintDef); itemOn = 2; // always start on back. } @@ -7987,12 +7992,20 @@ static void M_CustomLevelSelect(INT32 choice) static void M_SinglePlayerMenu(INT32 choice) { (void)choice; - SP_MainMenu[sptutorial].status = - tutorialmap ? IT_CALL|IT_STRING : IT_NOTHING|IT_DISABLED; - SP_MainMenu[sprecordattack].status = - (M_SecretUnlocked(SECRET_RECORDATTACK)) ? IT_CALL|IT_STRING : IT_SECRET; - SP_MainMenu[spnightsmode].status = - (M_SecretUnlocked(SECRET_NIGHTSMODE)) ? IT_CALL|IT_STRING : IT_SECRET; + + levellistmode = LLM_RECORDATTACK; + if (M_GametypeHasLevels(-1)) + SP_MainMenu[sprecordattack].status = (M_SecretUnlocked(SECRET_RECORDATTACK)) ? IT_CALL|IT_STRING : IT_SECRET; + else + SP_MainMenu[sprecordattack].status = IT_NOTHING|IT_DISABLED; + + levellistmode = LLM_NIGHTSATTACK; + if (M_GametypeHasLevels(-1)) + SP_MainMenu[spnightsmode].status = (M_SecretUnlocked(SECRET_NIGHTSMODE)) ? IT_CALL|IT_STRING : IT_SECRET; + else + SP_MainMenu[spnightsmode].status = IT_NOTHING|IT_DISABLED; + + SP_MainMenu[sptutorial].status = tutorialmap ? IT_CALL|IT_STRING : IT_NOTHING|IT_DISABLED; M_SetupNextMenu(&SP_MainDef); } diff --git a/src/p_enemy.c b/src/p_enemy.c index 09d33c537..2341be6d3 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -189,6 +189,7 @@ void A_SetTics(mobj_t *actor); void A_SetRandomTics(mobj_t *actor); void A_ChangeColorRelative(mobj_t *actor); void A_ChangeColorAbsolute(mobj_t *actor); +void A_Dye(mobj_t *actor); void A_MoveRelative(mobj_t *actor); void A_MoveAbsolute(mobj_t *actor); void A_Thrust(mobj_t *actor); @@ -8773,6 +8774,42 @@ void A_ChangeColorAbsolute(mobj_t *actor) actor->color = (UINT8)locvar2; } +// Function: A_Dye +// +// Description: Colorizes an object. +// +// var1 = if (var1 != 0), dye your target instead of yourself +// var2 = color value to dye +// +void A_Dye(mobj_t *actor) +{ + INT32 locvar1 = var1; + INT32 locvar2 = var2; + + mobj_t *target = ((locvar1 && actor->target) ? actor->target : actor); + UINT8 color = (UINT8)locvar2; +#ifdef HAVE_BLUA + if (LUA_CallAction("A_Dye", actor)) + return; +#endif + if (color >= MAXTRANSLATIONS) + return; + + if (!color) + target->colorized = false; + else + target->colorized = true; + + // What if it's a player? + if (target->player) + { + target->player->powers[pw_dye] = color; + return; + } + + target->color = color; +} + // Function: A_MoveRelative // // Description: Moves an object (wrapper for P_Thrust) diff --git a/src/p_inter.c b/src/p_inter.c index 67d197375..30e3c31b1 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3150,7 +3150,7 @@ static boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj_t *sou return false; // In COOP/RACE, you can't hurt other players unless cv_friendlyfire is on - if (!(cv_friendlyfire.value || (gametyperules & GTR_FRIENDLYFIRE)) && (G_PlatformGametype())) + if (!(cv_friendlyfire.value || (gametyperules & GTR_FRIENDLYFIRE)) && (gametyperules & GTR_FRIENDLY)) { if (gametype == GT_COOP && inflictor->type == MT_LHRT && !(player->powers[pw_shield] & SH_NOSTACK)) // co-op only { diff --git a/src/p_setup.c b/src/p_setup.c index cdf867d61..6c6ecbc5d 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1181,10 +1181,14 @@ static void P_LoadSidedefs(UINT8 *data) case 9: // Mace parameters case 14: // Bustable block parameters case 15: // Fan particle spawner parameters + case 334: // Trigger linedef executor: Object dye - Continuous + case 335: // Trigger linedef executor: Object dye - Each time + case 336: // Trigger linedef executor: Object dye - Once case 425: // Calls P_SetMobjState on calling mobj case 434: // Custom Power case 442: // Calls P_SetMobjState on mobjs of a given type in the tagged sectors case 461: // Spawns an object on the map based on texture offsets + case 463: // Colorizes an object { char process[8*3+1]; memset(process,0,8*3+1); diff --git a/src/p_spec.c b/src/p_spec.c index dee816e47..50b767535 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2034,6 +2034,17 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller if (!(actor && actor->player && ((stricmp(triggerline->text, skins[actor->player->skin].name) == 0) ^ ((triggerline->flags & ML_NOCLIMB) == ML_NOCLIMB)))) return false; break; + case 334: // object dye - continuous + case 335: // object dye - each time + case 336: // object dye - once + { + INT32 triggercolor = (INT32)sides[triggerline->sidenum[0]].toptexture; + UINT8 color = (actor->player ? actor->player->powers[pw_dye] : actor->color); + boolean invert = (triggerline->flags & ML_NOCLIMB ? true : false); + + if (invert ^ (triggercolor != color)) + return false; + } default: break; } @@ -2167,6 +2178,7 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller || specialtype == 328 // Nights lap - Once || specialtype == 330 // Nights Bonus Time - Once || specialtype == 333 // Skin - Once + || specialtype == 336 // Dye - Once || specialtype == 399) // Level Load triggerline->special = 0; // Clear it out @@ -2208,7 +2220,8 @@ void P_LinedefExecute(INT16 tag, mobj_t *actor, sector_t *caller) || lines[masterline].special == 310 // CTF Red team - Each time || lines[masterline].special == 312 // CTF Blue team - Each time || lines[masterline].special == 322 // Trigger on X calls - Each Time - || lines[masterline].special == 332)// Skin - Each time + || lines[masterline].special == 332 // Skin - Each time + || lines[masterline].special == 335)// Dye - Each time continue; if (lines[masterline].special < 300 @@ -4037,7 +4050,23 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) } } break; - + + case 463: // Dye object + { + INT32 color = sides[line->sidenum[0]].toptexture; + + if (mo) + { + if (color < 0 || color >= MAXTRANSLATIONS) + return; + + var1 = 0; + var2 = color; + A_Dye(mo); + } + } + break; + #ifdef POLYOBJECTS case 480: // Polyobj_DoorSlide case 481: // Polyobj_DoorSwing @@ -7205,6 +7234,7 @@ void P_SpawnSpecials(boolean fromnetsave) case 310: case 312: case 332: + case 335: sec = sides[*lines[i].sidenum].sector - sectors; P_AddEachTimeThinker(§ors[sec], &lines[i]); break; @@ -7257,6 +7287,11 @@ void P_SpawnSpecials(boolean fromnetsave) case 331: case 333: break; + + // Object dye executors + case 334: + case 336: + break; case 399: // Linedef execute on map load // This is handled in P_RunLevelLoadExecutors. diff --git a/src/p_user.c b/src/p_user.c index 612e31cbc..994eb7007 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1548,6 +1548,10 @@ boolean P_EvaluateMusicStatus(UINT16 status, const char *musname) int i; boolean result = false; +#ifndef HAVE_BLUA + (void)musname; +#endif + for (i = 0; i < MAXPLAYERS; i++) { if (!P_IsLocalPlayer(&players[i])) @@ -7978,7 +7982,7 @@ static void P_MovePlayer(player_t *player) && player->mo->state < &states[S_PLAY_NIGHTS_TRANS6]))) // Note the < instead of <= { skin_t *skin = ((skin_t *)(player->mo->skin)); - if (skin->flags & SF_SUPER) + if (( skin->flags & (SF_SUPER|SF_NONIGHTSSUPER) ) == SF_SUPER) { player->mo->color = skin->supercolor + ((player->nightstime == player->startedtime) @@ -12209,7 +12213,7 @@ void P_PlayerThink(player_t *player) player->powers[pw_nocontrol]--; else player->powers[pw_nocontrol] = 0; - + //pw_super acts as a timer now if (player->powers[pw_super] && (player->mo->state < &states[S_PLAY_SUPER_TRANS1] @@ -12854,6 +12858,12 @@ void P_PlayerAfterThink(player_t *player) player->mo->flags |= MF_NOGRAVITY; } + if (player->powers[pw_dye]) + { + player->mo->colorized = true; + player->mo->color = player->powers[pw_dye]; + } + if (player->followmobj && (player->spectator || player->mo->health <= 0 || player->followmobj->type != player->followitem)) { P_RemoveMobj(player->followmobj); diff --git a/src/r_data.c b/src/r_data.c index 3d80bbda3..831e75bef 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -721,14 +721,12 @@ Rloadflats (INT32 i, INT32 w) } else { - texstart = W_CheckNumForNamePwad("F_START", (UINT16)w, 0); + texstart = W_CheckNumForMarkerStartPwad("F_START", (UINT16)w, 0); texend = W_CheckNumForNamePwad("F_END", (UINT16)w, texstart); } if (!( texstart == INT16_MAX || texend == INT16_MAX )) { - texstart++; // Do not count the first marker - // Work through each lump between the markers in the WAD. for (j = 0; j < (texend - texstart); j++) { @@ -841,7 +839,7 @@ Rloadtextures (INT32 i, INT32 w) } else { - texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0); + texstart = W_CheckNumForMarkerStartPwad(TX_START, (UINT16)w, 0); texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0); texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0); if (texturesLumpPos != INT16_MAX) @@ -850,8 +848,6 @@ Rloadtextures (INT32 i, INT32 w) if (!( texstart == INT16_MAX || texend == INT16_MAX )) { - texstart++; // Do not count the first marker - // Work through each lump between the markers in the WAD. for (j = 0; j < (texend - texstart); j++) { @@ -958,14 +954,12 @@ void R_LoadTextures(void) } else { - texstart = W_CheckNumForNamePwad("F_START", (UINT16)w, 0); + texstart = W_CheckNumForMarkerStartPwad("F_START", (UINT16)w, 0); texend = W_CheckNumForNamePwad("F_END", (UINT16)w, texstart); } if (!( texstart == INT16_MAX || texend == INT16_MAX )) { - texstart++; // Do not count the first marker - // PK3s have subfolders, so we can't just make a simple sum if (wadfiles[w]->type == RET_PK3) { @@ -998,15 +992,13 @@ void R_LoadTextures(void) } else { - texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0); + texstart = W_CheckNumForMarkerStartPwad(TX_START, (UINT16)w, 0); texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0); } if (texstart == INT16_MAX || texend == INT16_MAX) continue; - texstart++; // Do not count the first marker - // PK3s have subfolders, so we can't just make a simple sum if (wadfiles[w]->type == RET_PK3) { @@ -1592,9 +1584,9 @@ lumpnum_t R_GetFlatNumForName(const char *name) switch (wadfiles[i]->type) { case RET_WAD: - if ((start = W_CheckNumForNamePwad("F_START", (UINT16)i, 0)) == INT16_MAX) + if ((start = W_CheckNumForMarkerStartPwad("F_START", (UINT16)i, 0)) == INT16_MAX) { - if ((start = W_CheckNumForNamePwad("FF_START", (UINT16)i, 0)) == INT16_MAX) + if ((start = W_CheckNumForMarkerStartPwad("FF_START", (UINT16)i, 0)) == INT16_MAX) continue; else if ((end = W_CheckNumForNamePwad("FF_END", (UINT16)i, start)) == INT16_MAX) continue; diff --git a/src/r_draw.c b/src/r_draw.c index b983db0aa..0155ec113 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -233,11 +233,11 @@ const UINT8 Color_Index[MAXTRANSLATIONS-1][16] = { {0x00, 0xd0, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x44, 0x45, 0x46}, // SKINCOLOR_SUPERORANGE4 {0xd0, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x44, 0x45, 0x46, 0x47}, // SKINCOLOR_SUPERORANGE5 - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50, 0x51, 0x52, 0x53, 0x48}, // SKINCOLOR_SUPERGOLD1 - {0x00, 0x50, 0x51, 0x52, 0x53, 0x53, 0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41}, // SKINCOLOR_SUPERGOLD2 - {0x51, 0x52, 0x53, 0x53, 0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x42, 0x43}, // SKINCOLOR_SUPERGOLD3 - {0x53, 0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46}, // SKINCOLOR_SUPERGOLD4 - {0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47}, // SKINCOLOR_SUPERGOLD5 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50, 0x51, 0x52, 0x53, 0x48, 0x48, 0x48}, // SKINCOLOR_SUPERGOLD1 + {0x00, 0x50, 0x51, 0x52, 0x53, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x41, 0x41}, // SKINCOLOR_SUPERGOLD2 + {0x51, 0x52, 0x53, 0x53, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x42, 0x43, 0x43, 0x43}, // SKINCOLOR_SUPERGOLD3 + {0x53, 0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x46, 0x46}, // SKINCOLOR_SUPERGOLD4 + {0x48, 0x48, 0x49, 0x49, 0x49, 0x40, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x47, 0x47}, // SKINCOLOR_SUPERGOLD5 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x58, 0x58, 0xbc, 0xbc, 0xbc}, // SKINCOLOR_SUPERPERIDOT1 {0x00, 0x58, 0x58, 0x58, 0xbc, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe}, // SKINCOLOR_SUPERPERIDOT2 diff --git a/src/r_skins.c b/src/r_skins.c index 2e9548bd7..caf1fb172 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -504,6 +504,7 @@ static boolean R_ProcessPatchableFields(skin_t *skin, char *stoken, char *value) GETFLAG(FASTEDGE) GETFLAG(MULTIABILITY) GETFLAG(NONIGHTSROTATION) + GETFLAG(NONIGHTSSUPER) #undef GETFLAG else // let's check if it's a sound, otherwise error out diff --git a/src/r_things.c b/src/r_things.c index fc0469f4c..aec4ed950 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -428,9 +428,9 @@ void R_AddSpriteDefs(UINT16 wadnum) switch (wadfiles[wadnum]->type) { case RET_WAD: - start = W_CheckNumForNamePwad("S_START", wadnum, 0); + start = W_CheckNumForMarkerStartPwad("S_START", wadnum, 0); if (start == INT16_MAX) - start = W_CheckNumForNamePwad("SS_START", wadnum, 0); //deutex compatib. + start = W_CheckNumForMarkerStartPwad("SS_START", wadnum, 0); //deutex compatib. end = W_CheckNumForNamePwad("S_END",wadnum,start); if (end == INT16_MAX) @@ -452,8 +452,6 @@ void R_AddSpriteDefs(UINT16 wadnum) start = 0; //let say S_START is lump 0 } - else - start++; // just after S_START if (end == INT16_MAX || start >= end) { diff --git a/src/s_sound.c b/src/s_sound.c index 0cc40a9ce..6952b17f2 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -1456,6 +1456,7 @@ musicdef_t soundtestsfx = { 0, // with no conditions 0, 0, + 0, false, NULL }; @@ -1651,6 +1652,8 @@ ReadMusicDefFields (UINT16 wadnum, int line, boolean fields, char *stoken, fixed_t bpmf = FLOAT_TO_FIXED(bpm); if (bpmf > 0) def->bpm = FixedDiv((60*TICRATE)<loop_ms = atoi(textline); } else { CONS_Alert(CONS_WARNING, "MUSICDEF: Invalid field '%s'. (file %s, line %d)\n", @@ -2262,6 +2265,8 @@ static void S_UnloadMusic(void) static boolean S_PlayMusic(boolean looping, UINT32 fadeinms) { + musicdef_t *def; + if (S_MusicDisabled()) return false; @@ -2273,6 +2278,17 @@ static boolean S_PlayMusic(boolean looping, UINT32 fadeinms) return false; } + /* set loop point from MUSICDEF */ + for (def = musicdefstart; def; def = def->next) + { + if (strcasecmp(def->name, music_name) == 0) + { + if (def->loop_ms) + S_SetMusicLoopPoint(def->loop_ms); + break; + } + } + S_InitMusicVolume(); // switch between digi and sequence volume if (S_MusicNotInFocus()) diff --git a/src/s_sound.h b/src/s_sound.h index d7e0c46ab..119722af4 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -208,6 +208,7 @@ typedef struct musicdef_s INT16 soundtestcond; // +ve for map, -ve for conditionset, 0 for already here tic_t stoppingtics; fixed_t bpm; + UINT32 loop_ms;/* override LOOPPOINT/LOOPMS */ boolean allowed; // question marks or listenable on sound test? struct musicdef_s *next; } musicdef_t; diff --git a/src/screen.c b/src/screen.c index 6bdf91ed8..6e5fd54cd 100644 --- a/src/screen.c +++ b/src/screen.c @@ -449,7 +449,7 @@ void SCR_ActuallyChangeRenderer(void) #ifdef HWRENDER // Well, it didn't even load anyway. - if ((hwrenderloaded == -1) && (setrenderneeded == render_opengl)) + if ((vid_opengl_state == -1) && (setrenderneeded == render_opengl)) { if (M_CheckParm("-nogl")) CONS_Alert(CONS_ERROR, "OpenGL rendering was disabled!\n"); @@ -474,7 +474,7 @@ void SCR_ChangeRenderer(void) { target_renderer = cv_renderer.value; #ifdef HWRENDER - if (M_CheckParm("-opengl") && (hwrenderloaded == 1)) + if (M_CheckParm("-opengl") && (vid_opengl_state == 1)) target_renderer = rendermode = render_opengl; else #endif diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index a7923f9cc..7e334a31d 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -105,7 +105,7 @@ static consvar_t cv_stretch = {"stretch", "Off", CV_SAVE|CV_NOSHOWHELP, CV_OnOff static consvar_t cv_alwaysgrabmouse = {"alwaysgrabmouse", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; UINT8 graphics_started = 0; // Is used in console.c and screen.c -INT32 hwrenderloaded = 0; +INT32 vid_opengl_state = 0; // To disable fullscreen at startup; is set in VID_PrepareModeList boolean allow_fullscreen = false; @@ -1443,7 +1443,7 @@ static SDL_bool Impl_CreateContext(void) { // Renderer-specific stuff #ifdef HWRENDER - if ((rendermode == render_opengl) && (hwrenderloaded != -1)) + if ((rendermode == render_opengl) && (vid_opengl_state != -1)) { if (!sdlglcontext) sdlglcontext = SDL_GL_CreateContext(window); @@ -1476,10 +1476,10 @@ static SDL_bool Impl_CreateContext(void) return SDL_TRUE; } -#ifdef HWRENDER -static void VID_CheckGLLoaded(rendermode_t oldrender) +void VID_CheckGLLoaded(rendermode_t oldrender) { - if (hwrenderloaded == -1) // Well, it didn't work the first time anyway. +#ifdef HWRENDER + if (vid_opengl_state == -1) // Well, it didn't work the first time anyway. { rendermode = oldrender; if (chosenrendermode == render_opengl) // fallback to software @@ -1491,40 +1491,66 @@ static void VID_CheckGLLoaded(rendermode_t oldrender) setrenderneeded = 0; } } -} #endif +} void VID_CheckRenderer(void) { - SDL_bool rendererchanged = SDL_FALSE; + boolean rendererchanged = false; + boolean contextcreated = false; rendermode_t oldrenderer = rendermode; if (dedicated) return; -#ifdef HWRENDER - if (!graphics_started) - VID_CheckGLLoaded(oldrenderer); -#endif - if (setrenderneeded) { rendermode = setrenderneeded; - rendererchanged = SDL_TRUE; + rendererchanged = true; #ifdef HWRENDER if (rendermode == render_opengl) { VID_CheckGLLoaded(oldrenderer); + // Initialise OpenGL before calling SDLSetMode!!! - if (hwrenderloaded != 1) - I_StartupHardwareGraphics(); - else if (hwrenderloaded == -1) - rendererchanged = SDL_FALSE; + // This is because SDLSetMode calls OglSdlSurface. + if (vid_opengl_state == 0) + { + VID_StartupOpenGL(); + // Loaded successfully! + if (vid_opengl_state == 1) + { + // Destroy the current window, if it exists. + if (window) + { + SDL_DestroyWindow(window); + window = NULL; + } + + // Destroy the current window rendering context, if that also exists. + if (renderer) + { + SDL_DestroyRenderer(renderer); + renderer = NULL; + } + + // Create a new window. + Impl_CreateWindow(USE_FULLSCREEN); + + // From there, the OpenGL context was already created. + contextcreated = true; + } + } + else if (vid_opengl_state == -1) + rendererchanged = false; } #endif - Impl_CreateContext(); + if (!contextcreated) + Impl_CreateContext(); + + setrenderneeded = 0; } SDLSetMode(vid.width, vid.height, USE_FULLSCREEN, (rendererchanged ? SDL_FALSE : SDL_TRUE)); @@ -1537,15 +1563,25 @@ void VID_CheckRenderer(void) SDL_FreeSurface(bufSurface); bufSurface = NULL; } + + if (rendererchanged) + { #ifdef HWRENDER - if (hwrenderloaded == 1) // Only if OpenGL ever loaded! - HWR_FreeTextureCache(); + if (vid_opengl_state == 1) // Only if OpenGL ever loaded! + HWR_FreeTextureCache(); #endif - SCR_SetDrawFuncs(); + SCR_SetDrawFuncs(); + } } #ifdef HWRENDER else if (rendermode == render_opengl) - R_InitHardwareMode(); + { + if (rendererchanged) + { + R_InitHardwareMode(); + V_SetPalette(0); + } + } #else (void)oldrenderer; #endif @@ -1589,7 +1625,7 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen) flags |= SDL_WINDOW_BORDERLESS; #ifdef HWRENDER - if (hwrenderloaded != -1) + if (vid_opengl_state == 1) flags |= SDL_WINDOW_OPENGL; #endif @@ -1723,11 +1759,12 @@ void I_StartupGraphics(void) //SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY>>1,SDL_DEFAULT_REPEAT_INTERVAL<<2); VID_Command_ModeList_f(); + #ifdef HWRENDER if (M_CheckParm("-nogl")) - hwrenderloaded = -1; // Don't call SDL_GL_LoadLibrary - else - I_StartupHardwareGraphics(); + vid_opengl_state = -1; // Don't startup OpenGL + else if (chosenrendermode == render_opengl) + VID_StartupOpenGL(); #endif // Fury: we do window initialization after GL setup to allow @@ -1782,12 +1819,13 @@ void I_StartupGraphics(void) graphics_started = true; } -void I_StartupHardwareGraphics(void) +void VID_StartupOpenGL(void) { #ifdef HWRENDER static boolean glstartup = false; if (!glstartup) { + CONS_Printf("VID_StartupOpenGL()...\n"); HWD.pfnInit = hwSym("Init",NULL); HWD.pfnFinishUpdate = NULL; HWD.pfnDraw2DLine = hwSym("Draw2DLine",NULL); @@ -1819,13 +1857,13 @@ void I_StartupHardwareGraphics(void) // check gl renderer lib if (HWD.pfnGetRenderVersion() != VERSION) { - CONS_Alert(CONS_ERROR, M_GetText("The version of the renderer doesn't match the version of the executable\nBe sure you have installed SRB2 properly.\n")); - hwrenderloaded = -1; + CONS_Alert(CONS_ERROR, M_GetText("The version of the renderer doesn't match the version of the executable!\nBe sure you have installed SRB2 properly.\n")); + vid_opengl_state = -1; } else - hwrenderloaded = HWD.pfnInit(I_Error) ? 1 : -1; // let load the OpenGL library + vid_opengl_state = HWD.pfnInit(I_Error) ? 1 : -1; // let load the OpenGL library - if (hwrenderloaded == -1) + if (vid_opengl_state == -1) { rendermode = render_soft; setrenderneeded = 0; diff --git a/src/st_stuff.c b/src/st_stuff.c index ee7fc3f21..6e365dc68 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1331,6 +1331,16 @@ void ST_drawTitleCard(void) INT32 ttlscroll = FixedInt(lt_scroll); INT32 zzticker; patch_t *actpat, *zigzag, *zztext; + UINT8 colornum; + const UINT8 *colormap; + stplyr = &players[consoleplayer]; + + if (stplyr->skincolor) + colornum = stplyr->skincolor; + else + colornum = cv_playercolor.value; + + colormap = R_GetTranslationColormap(TC_DEFAULT, colornum, GTC_CACHE); if (!G_IsTitleCardAvailable()) return; @@ -1364,16 +1374,16 @@ void ST_drawTitleCard(void) if (!splitscreen || (splitscreen && stplyr == &players[displayplayer])) { zzticker = lt_ticker; - V_DrawScaledPatch(FixedInt(lt_zigzag), (-zzticker) % zigzag->height, V_SNAPTOTOP|V_SNAPTOLEFT, zigzag); - V_DrawScaledPatch(FixedInt(lt_zigzag), (zigzag->height-zzticker) % zigzag->height, V_SNAPTOTOP|V_SNAPTOLEFT, zigzag); - V_DrawScaledPatch(FixedInt(lt_zigzag), (-zigzag->height+zzticker) % zztext->height, V_SNAPTOTOP|V_SNAPTOLEFT, zztext); - V_DrawScaledPatch(FixedInt(lt_zigzag), (zzticker) % zztext->height, V_SNAPTOTOP|V_SNAPTOLEFT, zztext); + V_DrawMappedPatch(FixedInt(lt_zigzag), (-zzticker) % zigzag->height, V_SNAPTOTOP|V_SNAPTOLEFT, zigzag, colormap); + V_DrawMappedPatch(FixedInt(lt_zigzag), (zigzag->height-zzticker) % zigzag->height, V_SNAPTOTOP|V_SNAPTOLEFT, zigzag, colormap); + V_DrawMappedPatch(FixedInt(lt_zigzag), (-zigzag->height+zzticker) % zztext->height, V_SNAPTOTOP|V_SNAPTOLEFT, zztext, colormap); + V_DrawMappedPatch(FixedInt(lt_zigzag), (zzticker) % zztext->height, V_SNAPTOTOP|V_SNAPTOLEFT, zztext, colormap); } if (actnum) { if (!splitscreen) - V_DrawScaledPatch(ttlnumxpos + ttlscroll, 104 - ttlscroll, 0, actpat); + V_DrawMappedPatch(ttlnumxpos + ttlscroll, 104 - ttlscroll, 0, actpat, colormap); V_DrawLevelActNum(ttlnumxpos + ttlscroll, 104, V_PERPLAYER, actnum); } diff --git a/src/w_wad.c b/src/w_wad.c index f7ccc175b..ba29637ad 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -194,7 +194,6 @@ static inline void W_LoadDehackedLumpsPK3(UINT16 wadnum, boolean mainfile) if (posStart != INT16_MAX) { posEnd = W_CheckNumForFolderEndPK3("Lua/", wadnum, posStart); - posStart++; // first "lump" will be "Lua/" folder itself, so ignore it for (; posStart < posEnd; posStart++) LUA_LoadLump(wadnum, posStart); } @@ -204,7 +203,6 @@ static inline void W_LoadDehackedLumpsPK3(UINT16 wadnum, boolean mainfile) { posEnd = W_CheckNumForFolderEndPK3("SOC/", wadnum, posStart); - posStart++; // first "lump" will be "SOC/" folder itself, so ignore it for(; posStart < posEnd; posStart++) { lumpinfo_t *lump_p = &wadfiles[wadnum]->lumpinfo[posStart]; @@ -914,15 +912,32 @@ UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump) return INT16_MAX; } +UINT16 +W_CheckNumForMarkerStartPwad (const char *name, UINT16 wad, UINT16 startlump) +{ + UINT16 marker; + marker = W_CheckNumForNamePwad(name, wad, startlump); + if (marker != INT16_MAX) + marker++; // Do not count the first marker + return marker; +} + // Look for the first lump from a folder. UINT16 W_CheckNumForFolderStartPK3(const char *name, UINT16 wad, UINT16 startlump) { + size_t name_length; INT32 i; lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump; + name_length = strlen(name); for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++) { - if (strnicmp(name, lump_p->name2, strlen(name)) == 0) + if (strnicmp(name, lump_p->name2, name_length) == 0) + { + /* SLADE is special and puts a single directory entry. Skip that. */ + if (strlen(lump_p->name2) == name_length) + i++; break; + } } return i; } @@ -1025,7 +1040,7 @@ lumpnum_t W_CheckNumForMap(const char *name) else continue; // Now look for the specified map. - for (++lumpNum; lumpNum < end; lumpNum++) + for (; lumpNum < end; lumpNum++) if (!strnicmp(name, (wadfiles[i]->lumpinfo + lumpNum)->name, 8)) return (i<<16) + lumpNum; } @@ -1505,6 +1520,57 @@ void *W_CacheLumpName(const char *name, INT32 tag) // Cache a patch into heap memory, convert the patch format as necessary // +void *W_CacheSoftwarePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag) +{ + lumpcache_t *lumpcache = NULL; + + if (needpatchflush) + W_FlushCachedPatches(); + + if (!TestValidLump(wad, lump)) + return NULL; + + lumpcache = wadfiles[wad]->patchcache; + + if (!lumpcache[lump]) + { + size_t len = W_LumpLengthPwad(wad, lump); + void *ptr, *lumpdata; +#ifndef NO_PNG_LUMPS + void *srcdata = NULL; +#endif + + ptr = Z_Malloc(len, tag, &lumpcache[lump]); + lumpdata = Z_Malloc(len, tag, NULL); + + // read the lump in full + W_ReadLumpHeaderPwad(wad, lump, lumpdata, 0, 0); + +#ifndef NO_PNG_LUMPS + // lump is a png so convert it + if (R_IsLumpPNG((UINT8 *)lumpdata, len)) + { + size_t newlen; + srcdata = R_PNGToPatch((UINT8 *)lumpdata, len, &newlen); + ptr = Z_Realloc(ptr, newlen, tag, &lumpcache[lump]); + M_Memcpy(ptr, srcdata, newlen); + Z_Free(srcdata); + } + else // just copy it into the patch cache +#endif + M_Memcpy(ptr, lumpdata, len); + } + else + Z_ChangeTag(lumpcache[lump], tag); + + return lumpcache[lump]; +} + +void *W_CacheSoftwarePatchNum(lumpnum_t lumpnum, INT32 tag) +{ + return W_CacheSoftwarePatchNumPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum),tag); +} + void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag) { #ifdef HWRENDER @@ -1522,39 +1588,7 @@ void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag) if (rendermode == render_soft || rendermode == render_none) #endif { - lumpcache_t *lumpcache = wadfiles[wad]->patchcache; - if (!lumpcache[lump]) - { - size_t len = W_LumpLengthPwad(wad, lump); - void *ptr, *lumpdata; -#ifndef NO_PNG_LUMPS - void *srcdata = NULL; -#endif - - ptr = Z_Malloc(len, tag, &lumpcache[lump]); - lumpdata = Z_Malloc(len, tag, NULL); - - // read the lump in full - W_ReadLumpHeaderPwad(wad, lump, lumpdata, 0, 0); - -#ifndef NO_PNG_LUMPS - // lump is a png so convert it - if (R_IsLumpPNG((UINT8 *)lumpdata, len)) - { - size_t newlen; - srcdata = R_PNGToPatch((UINT8 *)lumpdata, len, &newlen); - ptr = Z_Realloc(ptr, newlen, tag, &lumpcache[lump]); - M_Memcpy(ptr, srcdata, newlen); - Z_Free(srcdata); - } - else // just copy it into the patch cache -#endif - M_Memcpy(ptr, lumpdata, len); - } - else - Z_ChangeTag(lumpcache[lump], tag); - - return lumpcache[lump]; + return W_CacheSoftwarePatchNumPwad(wad, lump, tag); } #ifdef HWRENDER diff --git a/src/w_wad.h b/src/w_wad.h index d598d9b39..d4455ba14 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -156,6 +156,9 @@ const char *W_CheckNameForNum(lumpnum_t lumpnum); UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump); // checks only in one pwad +/* Find the first lump after F_START for instance. */ +UINT16 W_CheckNumForMarkerStartPwad(const char *name, UINT16 wad, UINT16 startlump); + UINT16 W_CheckNumForFullNamePK3(const char *name, UINT16 wad, UINT16 startlump); UINT16 W_CheckNumForFolderStartPK3(const char *name, UINT16 wad, UINT16 startlump); UINT16 W_CheckNumForFolderEndPK3(const char *name, UINT16 wad, UINT16 startlump); @@ -191,8 +194,15 @@ boolean W_IsPatchCached(lumpnum_t lump, void *ptr); void *W_CacheLumpName(const char *name, INT32 tag); void *W_CachePatchName(const char *name, INT32 tag); -void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag); // return a patch_t -void *W_CachePatchNum(lumpnum_t lumpnum, INT32 tag); // return a patch_t +// Returns either a Software patch, or an OpenGL patch. +// Performs any necessary conversions from PNG images. +void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag); +void *W_CachePatchNum(lumpnum_t lumpnum, INT32 tag); + +// Returns a Software patch. +// Performs any necessary conversions from PNG images. +void *W_CacheSoftwarePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag); +void *W_CacheSoftwarePatchNum(lumpnum_t lumpnum, INT32 tag); void W_UnlockCachedPatch(void *patch); void W_FlushCachedPatches(void); diff --git a/src/win32/win_vid.c b/src/win32/win_vid.c index d0aab92b3..4e7bab569 100644 --- a/src/win32/win_vid.c +++ b/src/win32/win_vid.c @@ -239,10 +239,7 @@ void I_StartupGraphics(void) if (!dedicated) graphics_started = true; } -void I_StartupHardwareGraphics(void) -{ - // oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo y -} +void VID_StartupOpenGL(void){} // ------------------ // I_ShutdownGraphics @@ -951,10 +948,8 @@ INT32 VID_SetMode(INT32 modenum) return 1; } -void VID_CheckRenderer(void) -{ - // .............. -} +void VID_CheckRenderer(void) {} +void VID_CheckGLLoaded(rendermode_t oldrender) {} // ======================================================================== // Free the video buffer of the last video mode,