diff --git a/CMakeLists.txt b/CMakeLists.txt index 8bbf46945..855393de1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.0) # DO NOT CHANGE THIS SRB2 STRING! Some variable names depend on this string. # Version change is fine. project(SRB2 - VERSION 2.2.0 + VERSION 2.2.1 LANGUAGES C) if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR}) diff --git a/appveyor.yml b/appveyor.yml index d33d3d3a3..20b18d7d5 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 2.2.0.{branch}-{build} +version: 2.2.1.{branch}-{build} os: MinGW environment: diff --git a/src/am_map.c b/src/am_map.c index 7dfbf4ba4..b2c7de442 100644 --- a/src/am_map.c +++ b/src/am_map.c @@ -160,6 +160,7 @@ static boolean am_stopped = true; static INT32 f_x, f_y; // location of window on screen (always zero for both) static INT32 f_w, f_h; // size of window on screen (always the screen width and height respectively) +static boolean m_keydown[4]; // which window panning keys are being pressed down? static mpoint_t m_paninc; // how far the window pans each tic (map coords) static fixed_t mtof_zoommul; // how far the window zooms in each tic (map coords) static fixed_t ftom_zoommul; // how far the window zooms in each tic (fb coords) @@ -205,6 +206,7 @@ static boolean followplayer = true; // specifies whether to follow the player ar typedef void (*AMDRAWFLINEFUNC) (const fline_t *fl, INT32 color); static AMDRAWFLINEFUNC AM_drawFline; +static void AM_drawPixel(INT32 xx, INT32 yy, INT32 cc); static void AM_drawFline_soft(const fline_t *fl, INT32 color); static void AM_activateNewScale(void) @@ -344,22 +346,22 @@ static void AM_initVariables(void) old_m_h = m_h; } +// +// Called when the screen size changes. +// +static void AM_FrameBufferInit(void) +{ + f_x = f_y = 0; + f_w = vid.width; + f_h = vid.height; +} + // // should be called at the start of every level // right now, i figure it out myself // static void AM_LevelInit(void) { - f_x = f_y = 0; - f_w = vid.width; - f_h = vid.height; - - AM_drawFline = AM_drawFline_soft; -#ifdef HWRENDER - if (rendermode == render_opengl) - AM_drawFline = HWR_drawAMline; -#endif - AM_findMinMaxBoundaries(); scale_mtof = FixedDiv(min_scale_mtof*10, 7*FRACUNIT); if (scale_mtof > max_scale_mtof) @@ -381,7 +383,7 @@ void AM_Stop(void) * * \sa AM_Stop */ -static inline void AM_Start(void) +void AM_Start(void) { static INT32 lastlevel = -1; @@ -390,8 +392,12 @@ static inline void AM_Start(void) am_stopped = false; if (lastlevel != gamemap || am_recalc) // screen size changed { - AM_LevelInit(); - lastlevel = gamemap; + AM_FrameBufferInit(); + if (lastlevel != gamemap) + { + AM_LevelInit(); + lastlevel = gamemap; + } am_recalc = false; } AM_initVariables(); @@ -417,6 +423,28 @@ static void AM_maxOutWindowScale(void) AM_activateNewScale(); } +// +// set window panning +// +static void AM_setWindowPanning(void) +{ + // up and down + if (m_keydown[2]) // pan up + m_paninc.y = FTOM(F_PANINC); + else if (m_keydown[3]) // pan down + m_paninc.y = -FTOM(F_PANINC); + else + m_paninc.y = 0; + + // left and right + if (m_keydown[0]) // pan right + m_paninc.x = FTOM(F_PANINC); + else if (m_keydown[1]) // pan left + m_paninc.x = -FTOM(F_PANINC); + else + m_paninc.x = 0; +} + /** Responds to user inputs in automap mode. * * \param ev Event to possibly respond to. @@ -449,35 +477,49 @@ boolean AM_Responder(event_t *ev) { case AM_PANRIGHTKEY: // pan right if (!followplayer) - m_paninc.x = FTOM(F_PANINC); + { + m_keydown[0] = true; + AM_setWindowPanning(); + } else rc = false; break; case AM_PANLEFTKEY: // pan left if (!followplayer) - m_paninc.x = -FTOM(F_PANINC); + { + m_keydown[1] = true; + AM_setWindowPanning(); + } else rc = false; break; case AM_PANUPKEY: // pan up if (!followplayer) - m_paninc.y = FTOM(F_PANINC); + { + m_keydown[2] = true; + AM_setWindowPanning(); + } else rc = false; break; case AM_PANDOWNKEY: // pan down if (!followplayer) - m_paninc.y = -FTOM(F_PANINC); + { + m_keydown[3] = true; + AM_setWindowPanning(); + } else rc = false; break; case AM_ZOOMOUTKEY: // zoom out mtof_zoommul = M_ZOOMOUT; ftom_zoommul = M_ZOOMIN; + AM_setWindowPanning(); break; case AM_ZOOMINKEY: // zoom in mtof_zoommul = M_ZOOMIN; ftom_zoommul = M_ZOOMOUT; + AM_setWindowPanning(); break; case AM_TOGGLEKEY: AM_Stop(); @@ -491,6 +533,7 @@ boolean AM_Responder(event_t *ev) } else AM_restoreScaleAndLoc(); + AM_setWindowPanning(); break; case AM_FOLLOWKEY: followplayer = !followplayer; @@ -510,14 +553,32 @@ boolean AM_Responder(event_t *ev) switch (ev->data1) { case AM_PANRIGHTKEY: + if (!followplayer) + { + m_keydown[0] = false; + AM_setWindowPanning(); + } + break; case AM_PANLEFTKEY: if (!followplayer) - m_paninc.x = 0; + { + m_keydown[1] = false; + AM_setWindowPanning(); + } break; case AM_PANUPKEY: + if (!followplayer) + { + m_keydown[2] = false; + AM_setWindowPanning(); + } + break; case AM_PANDOWNKEY: if (!followplayer) - m_paninc.y = 0; + { + m_keydown[3] = false; + AM_setWindowPanning(); + } break; case AM_ZOOMOUTKEY: case AM_ZOOMINKEY: @@ -718,6 +779,17 @@ static boolean AM_clipMline(const mline_t *ml, fline_t *fl) } #undef DOOUTCODE +// +// Draws a pixel. +// +static void AM_drawPixel(INT32 xx, INT32 yy, INT32 cc) +{ + UINT8 *dest = screens[0]; + if (xx < 0 || yy < 0 || xx >= vid.width || yy >= vid.height) + return; // off the screen + dest[(yy*vid.width) + xx] = cc; +} + // // Classic Bresenham w/ whatever optimizations needed for speed // @@ -739,8 +811,6 @@ static void AM_drawFline_soft(const fline_t *fl, INT32 color) } #endif - #define PUTDOT(xx,yy,cc) V_DrawFill(xx,yy,1,1,cc|V_NOSCALESTART); - dx = fl->b.x - fl->a.x; ax = 2 * (dx < 0 ? -dx : dx); sx = dx < 0 ? -1 : 1; @@ -757,7 +827,7 @@ static void AM_drawFline_soft(const fline_t *fl, INT32 color) d = ay - ax/2; for (;;) { - PUTDOT(x, y, color) + AM_drawPixel(x, y, color); if (x == fl->b.x) return; if (d >= 0) @@ -774,7 +844,7 @@ static void AM_drawFline_soft(const fline_t *fl, INT32 color) d = ax - ay/2; for (;;) { - PUTDOT(x, y, color) + AM_drawPixel(x, y, color); if (y == fl->b.y) return; if (d >= 0) @@ -786,8 +856,6 @@ static void AM_drawFline_soft(const fline_t *fl, INT32 color) d += ax; } } - - #undef PUTDOT } // @@ -1100,6 +1168,12 @@ void AM_Drawer(void) if (!automapactive) return; + AM_drawFline = AM_drawFline_soft; +#ifdef HWRENDER + if (rendermode == render_opengl) + AM_drawFline = HWR_drawAMline; +#endif + AM_clearFB(BACKGROUND); if (draw_grid) AM_drawGrid(GRIDCOLORS); AM_drawWalls(); diff --git a/src/am_map.h b/src/am_map.h index 462bb3d6d..0560207bb 100644 --- a/src/am_map.h +++ b/src/am_map.h @@ -38,6 +38,9 @@ void AM_Ticker(void); // Called by main loop, instead of view drawer if automap is active. void AM_Drawer(void); +// Enables the automap. +void AM_Start(void); + // Called to force the automap to quit if the level is completed while it is up. void AM_Stop(void); diff --git a/src/config.h.in b/src/config.h.in index 233cbdc53..498f3086d 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -26,12 +26,12 @@ #else /* Manually defined asset hashes for non-CMake builds - * Last updated 2019 / 12 / 06 - v2.2.0 - main assets + * Last updated 2020 / 02 / 15 - v2.2.1 - main assets * Last updated 20?? / ?? / ?? - v2.2.? - patch.pk3 */ -#define ASSET_HASH_SRB2_PK3 "51419a33b4982d840c6772c159ba7c0a" -#define ASSET_HASH_ZONES_PK3 "df74843919fd51af26a0baa8e21e4c19" -#define ASSET_HASH_PLAYER_DTA "56a247e074dd0dc794b6617efef1e918" +#define ASSET_HASH_SRB2_PK3 "0277c9416756627004e83cbb5b2e3e28" +#define ASSET_HASH_ZONES_PK3 "f7e88afb6af7996a834c7d663144bead" +#define ASSET_HASH_PLAYER_DTA "ad49e07b17cc662f1ad70c454910b4ae" #ifdef USE_PATCH_DTA #define ASSET_HASH_PATCH_PK3 "there is no patch.pk3, only zuul" #endif diff --git a/src/console.c b/src/console.c index ba5ba71df..59d2b3e6c 100644 --- a/src/console.c +++ b/src/console.c @@ -613,6 +613,15 @@ void CON_Ticker(void) con_tick++; con_tick &= 7; + // if the menu is open then close the console. + if (menuactive && con_destlines) + { + consoletoggle = false; + con_destlines = 0; + CON_ClearHUD(); + I_UpdateMouseGrab(); + } + // console key was pushed if (consoletoggle) { @@ -769,7 +778,7 @@ boolean CON_Responder(event_t *ev) // check for console toggle key if (ev->type != ev_console) { - if (modeattacking || metalrecording || menuactive) + if (modeattacking || metalrecording) return false; if (key == gamecontrol[gc_console][0] || key == gamecontrol[gc_console][1]) @@ -784,7 +793,7 @@ boolean CON_Responder(event_t *ev) // check other keys only if console prompt is active if (!consoleready && key < NUMINPUTS) // metzgermeister: boundary check!! { - if (! menuactive && bindtable[key]) + if (bindtable[key]) { COM_BufAddText(bindtable[key]); COM_BufAddText("\n"); diff --git a/src/d_clisrv.c b/src/d_clisrv.c index ee4e62b91..77118110e 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -404,8 +404,8 @@ static void ExtraDataTicker(void) } // If you are a client, you can safely forget the net commands for this tic - // If you are the server, you need to remember them until every client has been aknowledged, - // because if you need to resend a PT_SERVERTICS packet, you need to put the commands in it + // If you are the server, you need to remember them until every client has been acknowledged, + // because if you need to resend a PT_SERVERTICS packet, you will need to put the commands in it if (client) D_FreeTextcmd(gametic); } @@ -1278,8 +1278,14 @@ static boolean CL_SendJoin(void) netbuffer->u.clientcfg.subversion = SUBVERSION; strncpy(netbuffer->u.clientcfg.application, SRB2APPLICATION, sizeof netbuffer->u.clientcfg.application); + + CleanupPlayerName(consoleplayer, cv_playername.zstring); + if (splitscreen) + CleanupPlayerName(1, cv_playername2.zstring);/* 1 is a HACK? oh no */ + strncpy(netbuffer->u.clientcfg.names[0], cv_playername.zstring, MAXPLAYERNAME); strncpy(netbuffer->u.clientcfg.names[1], cv_playername2.zstring, MAXPLAYERNAME); + return HSendPacket(servernode, true, 0, sizeof (clientconfig_pak)); } @@ -4504,7 +4510,7 @@ static void CL_SendClientCmd(void) packetsize = sizeof (clientcmd_pak) - sizeof (ticcmd_t) - sizeof (INT16); HSendPacket(servernode, false, 0, packetsize); } - else if (gamestate != GS_NULL && addedtogame) + else if (gamestate != GS_NULL && (addedtogame || dedicated)) { G_MoveTiccmd(&netbuffer->u.clientpak.cmd, &localcmds, 1); netbuffer->u.clientpak.consistancy = SHORT(consistancy[gametic%BACKUPTICS]); @@ -4678,6 +4684,7 @@ static void Local_Maketic(INT32 realtics) G_BuildTiccmd(&localcmds2, realtics, 2); localcmds.angleturn |= TICCMD_RECEIVED; + localcmds2.angleturn |= TICCMD_RECEIVED; } // This function is utter bullshit and is responsible for diff --git a/src/d_main.c b/src/d_main.c index 34cf56125..99a0c2947 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -188,14 +188,14 @@ void D_ProcessEvents(void) continue; } - // console input - if (CON_Responder(ev)) - continue; // ate the event - // Menu input if (M_Responder(ev)) continue; // menu ate the event + // console input + if (CON_Responder(ev)) + continue; // ate the event + G_Responder(ev); } } @@ -508,12 +508,13 @@ static void D_Display(void) // vid size change is now finished if it was on... vid.recalc = 0; - M_Drawer(); // menu is drawn even on top of everything - // focus lost moved to M_Drawer - + // FIXME: draw either console or menu, not the two if (gamestate != GS_TIMEATTACK) CON_Drawer(); + M_Drawer(); // menu is drawn even on top of everything + // focus lost moved to M_Drawer + // // wipe update // @@ -1219,7 +1220,7 @@ void D_SRB2Main(void) #endif D_CleanFile(); -#ifndef DEVELOP // md5s last updated 06/12/19 (ddmmyy) +#ifndef DEVELOP // md5s last updated 16/02/20 (ddmmyy) // Check MD5s of autoloaded files W_VerifyFileMD5(0, ASSET_HASH_SRB2_PK3); // srb2.pk3 diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 6b3662710..3204d3227 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -632,7 +632,7 @@ void D_RegisterClientCommands(void) // Set default player names // Monster Iestyn (12/08/19): not sure where else I could have actually put this, but oh well for (i = 0; i < MAXPLAYERS; i++) - sprintf(player_names[i], "Player %d", i); + sprintf(player_names[i], "Player %d", 1 + i); if (dedicated) return; @@ -1008,7 +1008,7 @@ boolean EnsurePlayerNameIsGood(char *name, INT32 playernum) * SetPlayerName * \author Graue */ -static void CleanupPlayerName(INT32 playernum, const char *newname) +void CleanupPlayerName(INT32 playernum, const char *newname) { char *buf; char *p; @@ -1036,6 +1036,17 @@ static void CleanupPlayerName(INT32 playernum, const char *newname) tmpname = p; + do + { + /* from EnsurePlayerNameIsGood */ + if (!isprint(*p) || *p == ';' || (UINT8)*p >= 0x80) + break; + } + while (*++p) ; + + if (*p)/* bad char found */ + break; + // Remove trailing spaces. p = &tmpname[strlen(tmpname)-1]; // last character while (*p == ' ' && p >= tmpname) diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 8f857c6db..f258cde62 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -194,6 +194,7 @@ typedef union { // add game commands, needs cleanup void D_RegisterServerCommands(void); void D_RegisterClientCommands(void); +void CleanupPlayerName(INT32 playernum, const char *newname); boolean EnsurePlayerNameIsGood(char *name, INT32 playernum); void D_SendPlayerConfig(void); void Command_ExitGame_f(void); diff --git a/src/dehacked.c b/src/dehacked.c index 4c36639a2..6093d6fd6 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1293,10 +1293,7 @@ static void readgametype(MYFILE *f, char *gtname) UINT32 wordgt = 0; for (j = 0; GAMETYPERULE_LIST[j]; j++) if (fastcmp(word, GAMETYPERULE_LIST[j])) { - if (!j) // GTR_CAMPAIGN - wordgt |= 1; - else - wordgt |= (1< 0) + F_UnloadAlacroixGraphics(oldttscale); + } + testttscale = newttscale; // If ttscale is unavailable: look for lower scales, then higher scales. @@ -2714,10 +2727,6 @@ static void F_FigureActiveTtScale(void) activettscale = (newttscale >= 1 && newttscale <= 6) ? newttscale : 0; - // We have a new ttscale, so load gfx - if(oldttscale > 0) - F_UnloadAlacroixGraphics(oldttscale); - if(activettscale > 0) F_LoadAlacroixGraphics(activettscale); } @@ -2759,12 +2768,6 @@ void F_TitleScreenDrawer(void) return; #endif - if (needpatchrecache && (curttmode == TTMODE_ALACROIX)) - { - ttloaded[0] = ttloaded[1] = ttloaded[2] = ttloaded[3] = ttloaded[4] = ttloaded[5] = 0; - F_LoadAlacroixGraphics(activettscale); - } - switch(curttmode) { case TTMODE_OLD: @@ -3630,7 +3633,6 @@ void F_StartContinue(void) } wipestyleflags = WSF_FADEOUT; - F_TryColormapFade(31); G_SetGamestate(GS_CONTINUING); gameaction = ga_nothing; diff --git a/src/g_game.c b/src/g_game.c index f5d7cd2fb..aaab89163 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1941,6 +1941,10 @@ boolean G_IsTitleCardAvailable(void) if (gametyperules & GTR_NOTITLECARD) return false; + // The current level has no name. + if (!mapheaderinfo[gamemap-1]->lvlttl[0]) + return false; + // The title card is available. return true; } @@ -3252,8 +3256,8 @@ void G_AddGametypeConstant(INT16 gtype, const char *newgtconst) { size_t r = 0; // read size_t w = 0; // write - char *gtconst = Z_Calloc(strlen(newgtconst) + 3, PU_STATIC, NULL); - char *tmpconst = Z_Calloc(strlen(newgtconst), PU_STATIC, NULL); + char *gtconst = Z_Calloc(strlen(newgtconst) + 4, PU_STATIC, NULL); + char *tmpconst = Z_Calloc(strlen(newgtconst) + 1, PU_STATIC, NULL); // Copy the gametype name. strcpy(tmpconst, newgtconst); @@ -3735,7 +3739,10 @@ static void G_DoCompleted(void) } if (i == 7) + { gottoken = false; + token = 0; + } } if (spec && !gottoken) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 95d3794b7..a702b1866 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5325,7 +5325,7 @@ static void HWR_AddSprites(sector_t *sec) #ifdef HWPRECIP precipmobj_t *precipthing; #endif - fixed_t approx_dist, limit_dist, hoop_limit_dist; + fixed_t limit_dist, hoop_limit_dist; // BSP is traversed by subsector. // A sector might have been split into several @@ -5344,35 +5344,10 @@ static void HWR_AddSprites(sector_t *sec) // If a limit exists, handle things a tiny bit different. limit_dist = (fixed_t)(cv_drawdist.value) << FRACBITS; hoop_limit_dist = (fixed_t)(cv_drawdist_nights.value) << FRACBITS; - if (limit_dist || hoop_limit_dist) + for (thing = sec->thinglist; thing; thing = thing->snext) { - for (thing = sec->thinglist; thing; thing = thing->snext) - { - if (thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW) - continue; - - approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y); - - if (thing->sprite == SPR_HOOP) - { - if (hoop_limit_dist && approx_dist > hoop_limit_dist) - continue; - } - else - { - if (limit_dist && approx_dist > limit_dist) - continue; - } - + if (R_ThingVisibleWithinDist(thing, limit_dist, hoop_limit_dist)) HWR_ProjectSprite(thing); - } - } - else - { - // Draw everything in sector, no checks - for (thing = sec->thinglist; thing; thing = thing->snext) - if (!(thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW)) - HWR_ProjectSprite(thing); } #ifdef HWPRECIP @@ -5381,15 +5356,8 @@ static void HWR_AddSprites(sector_t *sec) { for (precipthing = sec->preciplist; precipthing; precipthing = precipthing->snext) { - if (precipthing->precipflags & PCF_INVISIBLE) - continue; - - approx_dist = P_AproxDistance(viewx-precipthing->x, viewy-precipthing->y); - - if (approx_dist > limit_dist) - continue; - - HWR_ProjectPrecipitationSprite(precipthing); + if (R_PrecipThingVisible(precipthing, limit_dist)) + HWR_ProjectPrecipitationSprite(precipthing); } } #endif @@ -5643,7 +5611,7 @@ static void HWR_ProjectSprite(mobj_t *thing) if ((thing->flags2 & MF2_LINKDRAW) && thing->tracer) { // bodge support - not nearly as comprehensive as r_things.c, but better than nothing - if (thing->tracer->sprite == SPR_NULL || thing->tracer->flags2 & MF2_DONTDRAW) + if (! R_ThingVisible(thing->tracer)) return; } diff --git a/src/hu_stuff.c b/src/hu_stuff.c index c51499282..bf2432f5d 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1437,7 +1437,7 @@ static void HU_drawMiniChat(void) for (; i>0; i--) { - const char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i-1]); + char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i-1]); size_t j = 0; INT32 linescount = 0; @@ -1479,6 +1479,9 @@ static void HU_drawMiniChat(void) dy = 0; dx = 0; msglines += linescount+1; + + if (msg) + Z_Free(msg); } y = chaty - charheight*(msglines+1); @@ -1501,7 +1504,7 @@ static void HU_drawMiniChat(void) INT32 timer = ((cv_chattime.value*TICRATE)-chat_timers[i]) - cv_chattime.value*TICRATE+9; // see below... INT32 transflag = (timer >= 0 && timer <= 9) ? (timer*V_10TRANS) : 0; // you can make bad jokes out of this one. size_t j = 0; - const char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i]); // get the current message, and word wrap it. + char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i]); // get the current message, and word wrap it. UINT8 *colormap = NULL; while(msg[j]) // iterate through msg @@ -1547,6 +1550,9 @@ static void HU_drawMiniChat(void) } dy += charheight; dx = 0; + + if (msg) + Z_Free(msg); } // decrement addy and make that shit smooth: @@ -1598,7 +1604,7 @@ static void HU_drawChatLog(INT32 offset) { INT32 clrflag = 0; INT32 j = 0; - const char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_log[i]); // get the current message, and word wrap it. + char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_log[i]); // get the current message, and word wrap it. UINT8 *colormap = NULL; while(msg[j]) // iterate through msg { @@ -1638,6 +1644,9 @@ static void HU_drawChatLog(INT32 offset) } dy += charheight; dx = 0; + + if (msg) + Z_Free(msg); } diff --git a/src/info.c b/src/info.c index de6ff475c..20bd73498 100644 --- a/src/info.c +++ b/src/info.c @@ -762,7 +762,7 @@ state_t states[NUMSTATES] = {SPR_PLAY, SPR2_LIFE, 20, {NULL}, 0, 4, S_NULL}, // S_PLAY_ICON3 // Level end sign (uses player sprite) - {SPR_PLAY, SPR2_SIGN|FF_PAPERSPRITE, -1, {NULL}, 0, 29, S_PLAY_SIGN}, // S_PLAY_SIGN + {SPR_PLAY, SPR2_SIGN|FF_PAPERSPRITE, 2, {NULL}, 0, 29, S_PLAY_SIGN}, // S_PLAY_SIGN // NiGHTS Player, transforming {SPR_PLAY, SPR2_TRNS|FF_ANIMATE, 7, {NULL}, 0, 4, S_PLAY_NIGHTS_TRANS2}, // S_PLAY_NIGHTS_TRANS1 @@ -2343,12 +2343,13 @@ state_t states[NUMSTATES] = // TNT barrel {SPR_BARR, 0, -1, {NULL}, 0, 0, S_NULL}, // S_TNTBARREL_STND1 - {SPR_BARX, 0|FF_FULLBRIGHT, 3, {A_SetObjectFlags}, MF_NOCLIP|MF_NOGRAVITY|MF_NOBLOCKMAP, 0, S_TNTBARREL_EXPL2}, // S_TNTBARREL_EXPL1 - {SPR_BARX, 1|FF_FULLBRIGHT, 2, {A_TNTExplode}, MT_TNTDUST, 0, S_TNTBARREL_EXPL3}, // S_TNTBARREL_EXPL2 - {SPR_BARX, 1|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_TNTBARREL_EXPL4}, // S_TNTBARREL_EXPL3 - {SPR_BARX, 2|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_TNTBARREL_EXPL5}, // S_TNTBARREL_EXPL4 - {SPR_BARX, 3|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_TNTBARREL_EXPL6}, // S_TNTBARREL_EXPL5 - {SPR_NULL, 0, 35, {NULL}, 0, 0, S_NULL}, // S_TNTBARREL_EXPL6 + {SPR_BARX, 0, 0, {A_RollAngle}, 0, 1, S_TNTBARREL_EXPL2}, // S_TNTBARREL_EXPL1 + {SPR_BARX, 0|FF_FULLBRIGHT, 3, {A_SetObjectFlags}, MF_NOCLIP|MF_NOGRAVITY|MF_NOBLOCKMAP, 0, S_TNTBARREL_EXPL3}, // S_TNTBARREL_EXPL2 + {SPR_BARX, 1|FF_FULLBRIGHT, 2, {A_TNTExplode}, MT_TNTDUST, 0, S_TNTBARREL_EXPL4}, // S_TNTBARREL_EXPL3 + {SPR_BARX, 1|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_TNTBARREL_EXPL5}, // S_TNTBARREL_EXPL4 + {SPR_BARX, 2|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_TNTBARREL_EXPL6}, // S_TNTBARREL_EXPL5 + {SPR_BARX, 3|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_TNTBARREL_EXPL7}, // S_TNTBARREL_EXPL6 + {SPR_NULL, 0, 35, {NULL}, 0, 0, S_NULL}, // S_TNTBARREL_EXPL7 #ifndef ROTSPRITE {SPR_BARR, 1|FF_ANIMATE, -1, {NULL}, 7, 2, S_NULL}, // S_TNTBARREL_FLYING #else @@ -2394,7 +2395,7 @@ state_t states[NUMSTATES] = // Minecart {SPR_NULL, 0, 1, {NULL}, 0, 0, S_MINECART_IDLE}, // S_MINECART_IDLE - {SPR_NULL, 0, 0, {A_KillSegments}, 0, 0, S_TNTBARREL_EXPL3}, // S_MINECART_DTH1 + {SPR_NULL, 0, 0, {A_KillSegments}, 0, 0, S_TNTBARREL_EXPL4}, // S_MINECART_DTH1 {SPR_MCRT, 8|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_MINECARTEND {SPR_MCRT, 0|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_MINECARTSEG_FRONT {SPR_MCRT, 1|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_MINECARTSEG_BACK @@ -6487,10 +6488,10 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 24*FRACUNIT, // radius 24*FRACUNIT, // height 0, // display offset - 0, // mass + DMG_FIRE, // mass 1, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY, // flags + MF_NOBLOCKMAP|MF_MISSILE|MF_PAIN|MF_NOGRAVITY, // flags S_NULL // raisestate }, diff --git a/src/info.h b/src/info.h index 628335635..59b8eb68d 100644 --- a/src/info.h +++ b/src/info.h @@ -2503,6 +2503,7 @@ typedef enum state S_TNTBARREL_EXPL4, S_TNTBARREL_EXPL5, S_TNTBARREL_EXPL6, + S_TNTBARREL_EXPL7, S_TNTBARREL_FLYING, // TNT proximity shell diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index f451944e3..dbab801df 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -268,10 +268,14 @@ static int patch_get(lua_State *L) #endif enum patch field = luaL_checkoption(L, 2, NULL, patch_opt); - // patches are CURRENTLY always valid, expected to be cached with PU_STATIC - // this may change in the future, so patch.valid still exists - if (!patch) + // patches are invalidated when switching renderers + if (!patch) { + if (field == patch_valid) { + lua_pushboolean(L, 0); + return 1; + } return LUA_ErrInvalid(L, "patch_t"); + } switch (field) { @@ -1214,7 +1218,7 @@ void LUAh_GameHUD(player_t *stplayr) lua_getfield(gL, LUA_REGISTRYINDEX, "HUD"); I_Assert(lua_istable(gL, -1)); - lua_rawgeti(gL, -1, 2); // HUD[2] = rendering funcs + lua_rawgeti(gL, -1, 2+hudhook_game); // HUD[2] = rendering funcs I_Assert(lua_istable(gL, -1)); lua_rawgeti(gL, -2, 1); // HUD[1] = lib_draw @@ -1248,7 +1252,7 @@ void LUAh_ScoresHUD(void) lua_getfield(gL, LUA_REGISTRYINDEX, "HUD"); I_Assert(lua_istable(gL, -1)); - lua_rawgeti(gL, -1, 3); // HUD[3] = rendering funcs + lua_rawgeti(gL, -1, 2+hudhook_scores); // HUD[3] = rendering funcs I_Assert(lua_istable(gL, -1)); lua_rawgeti(gL, -2, 1); // HUD[1] = lib_draw @@ -1273,7 +1277,7 @@ void LUAh_TitleHUD(void) lua_getfield(gL, LUA_REGISTRYINDEX, "HUD"); I_Assert(lua_istable(gL, -1)); - lua_rawgeti(gL, -1, 4); // HUD[4] = rendering funcs + lua_rawgeti(gL, -1, 2+hudhook_title); // HUD[5] = rendering funcs I_Assert(lua_istable(gL, -1)); lua_rawgeti(gL, -2, 1); // HUD[1] = lib_draw @@ -1298,7 +1302,7 @@ void LUAh_TitleCardHUD(player_t *stplayr) lua_getfield(gL, LUA_REGISTRYINDEX, "HUD"); I_Assert(lua_istable(gL, -1)); - lua_rawgeti(gL, -1, 5); // HUD[5] = rendering funcs + lua_rawgeti(gL, -1, 2+hudhook_titlecard); // HUD[6] = rendering funcs I_Assert(lua_istable(gL, -1)); lua_rawgeti(gL, -2, 1); // HUD[1] = lib_draw @@ -1332,7 +1336,7 @@ void LUAh_IntermissionHUD(void) lua_getfield(gL, LUA_REGISTRYINDEX, "HUD"); I_Assert(lua_istable(gL, -1)); - lua_rawgeti(gL, -1, 4); // HUD[4] = rendering funcs + lua_rawgeti(gL, -1, 2+hudhook_intermission); // HUD[4] = rendering funcs I_Assert(lua_istable(gL, -1)); lua_rawgeti(gL, -2, 1); // HUD[1] = lib_draw diff --git a/src/m_anigif.c b/src/m_anigif.c index 32fc2746d..f062bc826 100644 --- a/src/m_anigif.c +++ b/src/m_anigif.c @@ -624,14 +624,6 @@ static void GIF_framewrite(void) // INT32 GIF_open(const char *filename) { -#if 0 - if (rendermode != render_soft) - { - CONS_Alert(CONS_WARNING, M_GetText("GIFs cannot be taken in non-software modes!\n")); - return 0; - } -#endif - gif_out = fopen(filename, "wb"); if (!gif_out) return 0; @@ -640,13 +632,13 @@ INT32 GIF_open(const char *filename) gif_downscale = (!!cv_gif_downscale.value); // GIF color table - // In hardware mode, uses the master palette - gif_palette = ((cv_screenshot_colorprofile.value + // In hardware mode, forces the local palette #ifdef HWRENDER - && (rendermode == render_soft) + if (rendermode == render_opengl) + gif_palette = pLocalPalette; + else #endif - ) ? pLocalPalette - : pMasterPalette); + gif_palette = ((cv_screenshot_colorprofile.value) ? pLocalPalette : pMasterPalette); GIF_headwrite(); gif_frames = 0; diff --git a/src/m_menu.c b/src/m_menu.c index 21b490b67..97c04ebd5 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -5602,7 +5602,8 @@ static void M_DrawNightsAttackMountains(void) static INT32 bgscrollx; INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy); patch_t *background = W_CachePatchName(curbgname, PU_PATCH); - INT32 x = FixedInt(bgscrollx) % SHORT(background->width); + INT16 w = SHORT(background->width); + INT32 x = FixedInt(-bgscrollx) % w; INT32 y = BASEVIDHEIGHT - SHORT(background->height)*2; if (vid.height != BASEVIDHEIGHT * dupz) @@ -5610,11 +5611,13 @@ static void M_DrawNightsAttackMountains(void) V_DrawFill(0, y+50, vid.width, BASEVIDHEIGHT, V_SNAPTOLEFT|31); V_DrawScaledPatch(x, y, V_SNAPTOLEFT, background); - x += SHORT(background->width); + x += w; if (x < BASEVIDWIDTH) V_DrawScaledPatch(x, y, V_SNAPTOLEFT, background); - bgscrollx -= (FRACUNIT/2); + bgscrollx += (FRACUNIT/2); + if (bgscrollx > w<= 28-1) diff --git a/src/p_enemy.c b/src/p_enemy.c index db297e684..2ddbd8d29 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -5198,8 +5198,8 @@ void A_SignPlayer(mobj_t *actor) player_t *player = actor->target ? actor->target->player : NULL; UINT8 skinnum; UINT8 skincount = 0; - for (skincount = 0; skincount < numskins; skincount++) - if (!skincheck(skincount)) + for (skinnum = 0; skinnum < numskins; skinnum++) + if (!skincheck(skinnum)) skincount++; skinnum = P_RandomKey(skincount); for (skincount = 0; skincount < numskins; skincount++) @@ -5232,20 +5232,23 @@ void A_SignPlayer(mobj_t *actor) { ov->color = facecolor; ov->skin = skin; - P_SetMobjState(ov, actor->info->seestate); // S_PLAY_SIGN + if ((statenum_t)(ov->state-states) != actor->info->seestate) + P_SetMobjState(ov, actor->info->seestate); // S_PLAY_SIGN } else // CLEAR! sign { ov->color = SKINCOLOR_NONE; ov->skin = NULL; // needs to be NULL in the case of SF_HIRES characters - P_SetMobjState(ov, actor->info->missilestate); // S_CLEARSIGN + if ((statenum_t)(ov->state-states) != actor->info->missilestate) + P_SetMobjState(ov, actor->info->missilestate); // S_CLEARSIGN } } else // Eggman face { ov->color = SKINCOLOR_NONE; ov->skin = NULL; - P_SetMobjState(ov, actor->info->meleestate); // S_EGGMANSIGN + if ((statenum_t)(ov->state-states) != actor->info->meleestate) + P_SetMobjState(ov, actor->info->meleestate); // S_EGGMANSIGN if (!signcolor) signcolor = SKINCOLOR_CARBON; } diff --git a/src/p_inter.c b/src/p_inter.c index 8090b7406..667245f03 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1428,98 +1428,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) // Misc touchables // // *************** // case MT_STARPOST: - if (player->bot) - return; - // In circuit, player must have touched all previous starposts - if (circuitmap - && special->health - player->starpostnum > 1) - { - // blatant reuse of a variable that's normally unused in circuit - if (!player->tossdelay) - S_StartSound(toucher, sfx_lose); - player->tossdelay = 3; - return; - } - - // We could technically have 91.1 Star Posts. 90 is cleaner. - if (special->health > 90) - { - CONS_Debug(DBG_GAMELOGIC, "Bad Starpost Number!\n"); - return; - } - - if (player->starpostnum >= special->health) - return; // Already hit this post - - if (cv_coopstarposts.value && G_GametypeUsesCoopStarposts() && (netgame || multiplayer)) - { - for (i = 0; i < MAXPLAYERS; i++) - { - if (playeringame[i]) - { - if (players[i].bot) // ignore dumb, stupid tails - continue; - - players[i].starposttime = leveltime; - players[i].starpostx = player->mo->x>>FRACBITS; - players[i].starposty = player->mo->y>>FRACBITS; - players[i].starpostz = special->z>>FRACBITS; - players[i].starpostangle = special->angle; - players[i].starpostscale = player->mo->destscale; - if (special->flags2 & MF2_OBJECTFLIP) - { - players[i].starpostscale *= -1; - players[i].starpostz += special->height>>FRACBITS; - } - players[i].starpostnum = special->health; - - if (cv_coopstarposts.value == 2 && (players[i].playerstate == PST_DEAD || players[i].spectator) && P_GetLives(&players[i])) - P_SpectatorJoinGame(&players[i]); //players[i].playerstate = PST_REBORN; - } - } - S_StartSound(NULL, special->info->painsound); - } - else - { - // Save the player's time and position. - player->starposttime = leveltime; - player->starpostx = toucher->x>>FRACBITS; - player->starposty = toucher->y>>FRACBITS; - player->starpostz = special->z>>FRACBITS; - player->starpostangle = special->angle; - player->starpostscale = player->mo->destscale; - if (special->flags2 & MF2_OBJECTFLIP) - { - player->starpostscale *= -1; - player->starpostz += special->height>>FRACBITS; - } - player->starpostnum = special->health; - S_StartSound(toucher, special->info->painsound); - } - - P_ClearStarPost(special->health); - - // Find all starposts in the level with this value - INCLUDING this one! - if (!(netgame && circuitmap && player != &players[consoleplayer])) - { - thinker_t *th; - mobj_t *mo2; - - for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) - { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - - mo2 = (mobj_t *)th; - - if (mo2->type != MT_STARPOST) - continue; - if (mo2->health != special->health) - continue; - - P_SetMobjState(mo2, mo2->info->painstate); - } - } + P_TouchStarPost(special, player, special->spawnpoint && (special->spawnpoint->options & MTF_OBJECTSPECIAL)); return; case MT_FAKEMOBILE: @@ -1872,6 +1781,112 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) special->shadowscale = 0; } +/** Saves a player's level progress at a star post + * + * \param post The star post to trigger + * \param player The player that should receive the checkpoint + * \param snaptopost If true, the respawn point will use the star post's position, otherwise player x/y and star post z + */ +void P_TouchStarPost(mobj_t *post, player_t *player, boolean snaptopost) +{ + size_t i; + mobj_t *toucher = player->mo; + mobj_t *checkbase = snaptopost ? post : toucher; + + if (player->bot) + return; + // In circuit, player must have touched all previous starposts + if (circuitmap + && post->health - player->starpostnum > 1) + { + // blatant reuse of a variable that's normally unused in circuit + if (!player->tossdelay) + S_StartSound(toucher, sfx_lose); + player->tossdelay = 3; + return; + } + + // With the parameter + angle setup, we can go up to 1365 star posts. Who needs that many? + if (post->health > 1365) + { + CONS_Debug(DBG_GAMELOGIC, "Bad Starpost Number!\n"); + return; + } + + if (player->starpostnum >= post->health) + return; // Already hit this post + + if (cv_coopstarposts.value && G_GametypeUsesCoopStarposts() && (netgame || multiplayer)) + { + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i]) + { + if (players[i].bot) // ignore dumb, stupid tails + continue; + + players[i].starposttime = leveltime; + players[i].starpostx = checkbase->x>>FRACBITS; + players[i].starposty = checkbase->y>>FRACBITS; + players[i].starpostz = post->z>>FRACBITS; + players[i].starpostangle = post->angle; + players[i].starpostscale = player->mo->destscale; + if (post->flags2 & MF2_OBJECTFLIP) + { + players[i].starpostscale *= -1; + players[i].starpostz += post->height>>FRACBITS; + } + players[i].starpostnum = post->health; + + if (cv_coopstarposts.value == 2 && (players[i].playerstate == PST_DEAD || players[i].spectator) && P_GetLives(&players[i])) + P_SpectatorJoinGame(&players[i]); //players[i].playerstate = PST_REBORN; + } + } + S_StartSound(NULL, post->info->painsound); + } + else + { + // Save the player's time and position. + player->starposttime = leveltime; + player->starpostx = checkbase->x>>FRACBITS; + player->starposty = checkbase->y>>FRACBITS; + player->starpostz = post->z>>FRACBITS; + player->starpostangle = post->angle; + player->starpostscale = player->mo->destscale; + if (post->flags2 & MF2_OBJECTFLIP) + { + player->starpostscale *= -1; + player->starpostz += post->height>>FRACBITS; + } + player->starpostnum = post->health; + S_StartSound(toucher, post->info->painsound); + } + + P_ClearStarPost(post->health); + + // Find all starposts in the level with this value - INCLUDING this one! + if (!(netgame && circuitmap && player != &players[consoleplayer])) + { + thinker_t *th; + mobj_t *mo2; + + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) + { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + + mo2 = (mobj_t *)th; + + if (mo2->type != MT_STARPOST) + continue; + if (mo2->health != post->health) + continue; + + P_SetMobjState(mo2, mo2->info->painstate); + } + } +} + /** Prints death messages relating to a dying or hit player. * * \param player Affected player. diff --git a/src/p_local.h b/src/p_local.h index a5f3d313c..8056d137c 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -486,6 +486,7 @@ void P_PlayerWeaponPanelOrAmmoBurst(player_t *player); void P_PlayerEmeraldBurst(player_t *player, boolean toss); void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck); +void P_TouchStarPost(mobj_t *starpost, player_t *player, boolean snaptopost); void P_PlayerFlagBurst(player_t *player, boolean toss); void P_CheckTimeLimit(void); void P_CheckPointLimit(void); diff --git a/src/p_mobj.c b/src/p_mobj.c index e6d84086c..10898f70e 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2350,6 +2350,7 @@ static void P_RingZMovement(mobj_t *mo) if (mo->eflags & MFE_APPLYPMOMZ && !P_IsObjectOnGround(mo)) { mo->momz += mo->pmomz; + mo->pmomz = 0; mo->eflags &= ~MFE_APPLYPMOMZ; } mo->z += mo->momz; @@ -2419,6 +2420,7 @@ static boolean P_ZMovement(mobj_t *mo) if (mo->eflags & MFE_APPLYPMOMZ && !P_IsObjectOnGround(mo)) { mo->momz += mo->pmomz; + mo->pmomz = 0; mo->eflags &= ~MFE_APPLYPMOMZ; } mo->z += mo->momz; @@ -2907,6 +2909,7 @@ static void P_PlayerZMovement(mobj_t *mo) if (mo->eflags & MFE_APPLYPMOMZ && !P_IsObjectOnGround(mo)) { mo->momz += mo->pmomz; + mo->pmomz = 0; mo->eflags &= ~MFE_APPLYPMOMZ; } @@ -3157,6 +3160,7 @@ static boolean P_SceneryZMovement(mobj_t *mo) if (mo->eflags & MFE_APPLYPMOMZ && !P_IsObjectOnGround(mo)) { mo->momz += mo->pmomz; + mo->pmomz = 0; mo->eflags &= ~MFE_APPLYPMOMZ; } mo->z += mo->momz; @@ -10457,6 +10461,61 @@ void P_SceneryThinker(mobj_t *mobj) // GAME SPAWN FUNCTIONS // +static fixed_t P_DefaultMobjShadowScale (mobj_t *thing) +{ + switch (thing->type) + { + case MT_PLAYER: + case MT_ROLLOUTROCK: + + case MT_EGGMOBILE4_MACE: + case MT_SMALLMACE: + case MT_BIGMACE: + + case MT_SMALLGRABCHAIN: + case MT_BIGGRABCHAIN: + + case MT_YELLOWSPRINGBALL: + case MT_REDSPRINGBALL: + + return FRACUNIT; + + case MT_RING: + case MT_FLINGRING: + + case MT_BLUESPHERE: + case MT_FLINGBLUESPHERE: + case MT_BOMBSPHERE: + + case MT_REDTEAMRING: + case MT_BLUETEAMRING: + case MT_REDFLAG: + case MT_BLUEFLAG: + + case MT_EMBLEM: + + case MT_TOKEN: + case MT_EMERALD1: + case MT_EMERALD2: + case MT_EMERALD3: + case MT_EMERALD4: + case MT_EMERALD5: + case MT_EMERALD6: + case MT_EMERALD7: + case MT_EMERHUNT: + case MT_FLINGEMERALD: + + return 2*FRACUNIT/3; + + default: + + if (thing->flags & (MF_ENEMY|MF_BOSS)) + return FRACUNIT; + else + return 0; + } +} + // // P_SpawnMobj // @@ -10558,20 +10617,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) mobj->z = z; // Set shadowscale here, before spawn hook so that Lua can change it - if ( - type == MT_PLAYER || - type == MT_ROLLOUTROCK || - type == MT_EGGMOBILE4_MACE || - (type >= MT_SMALLMACE && type <= MT_REDSPRINGBALL) || - (mobj->flags & (MF_ENEMY|MF_BOSS)) - ) - mobj->shadowscale = FRACUNIT; - else if ( - type >= MT_RING && type <= MT_FLINGEMERALD && type != MT_EMERALDSPAWN - ) - mobj->shadowscale = 2*FRACUNIT/3; - else - mobj->shadowscale = 0; + mobj->shadowscale = P_DefaultMobjShadowScale(mobj); #ifdef HAVE_BLUA // DANGER! This can cause P_SpawnMobj to return NULL! @@ -12931,7 +12977,16 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean thinker_t* th; mobj_t* mo2; boolean foundanother = false; - mobj->health = (mthing->angle/360) + 1; + + if (mthing->extrainfo) + // Allow thing Parameter to define star post num too! + // For starposts above param 15 (the 16th), add 360 to the angle like before and start parameter from 1 (NOT 0)! + // So the 16th starpost is angle=0 param=15, the 17th would be angle=360 param=1. + // This seems more intuitive for mappers to use until UDMF is ready, since most SP maps won't have over 16 consecutive star posts. + mobj->health = mthing->extrainfo + (mthing->angle/360)*15 + 1; + else + // Old behavior if Parameter is 0; add 360 to the angle for each consecutive star post. + mobj->health = (mthing->angle/360) + 1; // See if other starposts exist in this level that have the same value. for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) diff --git a/src/p_polyobj.c b/src/p_polyobj.c index cd0a44bb4..a206d0171 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -1001,15 +1001,35 @@ static void Polyobj_pushThing(polyobj_t *po, line_t *line, mobj_t *mo) // static void Polyobj_slideThing(mobj_t *mo, fixed_t dx, fixed_t dy) { - if (mo->player) { // Do something similar to conveyor movement. -Red - mo->player->cmomx += dx; - mo->player->cmomy += dy; + if (mo->player) { // Finally this doesn't suck eggs -fickle + fixed_t cdx, cdy; - dx = FixedMul(dx, CARRYFACTOR); - dy = FixedMul(dy, CARRYFACTOR); + cdx = FixedMul(dx, FRACUNIT-CARRYFACTOR); + cdy = FixedMul(dy, FRACUNIT-CARRYFACTOR); - mo->player->cmomx -= dx; - mo->player->cmomy -= dy; + if (mo->player->onconveyor == 1) + { + mo->momx += cdx; + mo->momy += cdy; + + // Multiple slides in the same tic, somehow + mo->player->cmomx += cdx; + mo->player->cmomy += cdy; + } + else + { + if (mo->player->onconveyor == 3) + { + mo->momx += cdx - mo->player->cmomx; + mo->momy += cdy - mo->player->cmomy; + } + + mo->player->cmomx = cdx; + mo->player->cmomy = cdy; + } + + dx = FixedMul(dx, FRACUNIT - mo->friction); + dy = FixedMul(dy, FRACUNIT - mo->friction); if (mo->player->pflags & PF_SPINNING && (mo->player->rmomx || mo->player->rmomy) && !(mo->player->pflags & PF_STARTDASH)) { #define SPINMULT 5184 // Consider this a substitute for properly calculating FRACUNIT-friction. I'm tired. -Red @@ -1282,7 +1302,8 @@ static void Polyobj_rotateThings(polyobj_t *po, vertex_t origin, angle_t delta, { static INT32 pomovecount = 10000; INT32 x, y; - angle_t deltafine = delta >> ANGLETOFINESHIFT; + angle_t deltafine = (((po->angle + delta) >> ANGLETOFINESHIFT) - (po->angle >> ANGLETOFINESHIFT)) & FINEMASK; + // This fineshift trickery replaces the old delta>>ANGLETOFINESHIFT; doing it this way avoids loss of precision causing objects to slide off -fickle pomovecount++; @@ -1334,19 +1355,10 @@ static void Polyobj_rotateThings(polyobj_t *po, vertex_t origin, angle_t delta, oldxoff = mo->x-origin.x; oldyoff = mo->y-origin.y; - if (mo->player) // Hack to fix players sliding off of spinning polys -Red - { - fixed_t temp; + newxoff = FixedMul(oldxoff, c)-FixedMul(oldyoff, s) - oldxoff; + newyoff = FixedMul(oldyoff, c)+FixedMul(oldxoff, s) - oldyoff; - temp = FixedMul(oldxoff, c)-FixedMul(oldyoff, s); - oldyoff = FixedMul(oldyoff, c)+FixedMul(oldxoff, s); - oldxoff = temp; - } - - newxoff = FixedMul(oldxoff, c)-FixedMul(oldyoff, s); - newyoff = FixedMul(oldyoff, c)+FixedMul(oldxoff, s); - - Polyobj_slideThing(mo, newxoff-oldxoff, newyoff-oldyoff); + Polyobj_slideThing(mo, newxoff, newyoff); if (turnthings == 2 || (turnthings == 1 && !mo->player)) { mo->angle += delta; diff --git a/src/p_saveg.c b/src/p_saveg.c index c5568af1b..973f5ef64 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1257,6 +1257,7 @@ typedef enum #endif MD2_COLORIZED = 1<<12, MD2_ROLLANGLE = 1<<13, + MD2_SHADOWSCALE = 1<<14, } mobj_diff2_t; typedef enum @@ -1478,6 +1479,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) diff2 |= MD2_COLORIZED; if (mobj->rollangle) diff2 |= MD2_ROLLANGLE; + if (mobj->shadowscale) + diff2 |= MD2_SHADOWSCALE; if (diff2 != 0) diff |= MD_MORE; @@ -1644,6 +1647,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) WRITEUINT8(save_p, mobj->colorized); if (diff2 & MD2_ROLLANGLE) WRITEANGLE(save_p, mobj->rollangle); + if (diff2 & MD2_SHADOWSCALE) + WRITEFIXED(save_p, mobj->shadowscale); WRITEUINT32(save_p, mobj->mobjnum); } @@ -2723,6 +2728,8 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) mobj->colorized = READUINT8(save_p); if (diff2 & MD2_ROLLANGLE) mobj->rollangle = READANGLE(save_p); + if (diff2 & MD2_SHADOWSCALE) + mobj->shadowscale = READFIXED(save_p); if (diff & MD_REDFLAG) { diff --git a/src/p_setup.c b/src/p_setup.c index 2b0a5efa3..c291dc7c3 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3684,8 +3684,7 @@ boolean P_LoadLevel(boolean fromnetsave) return true; // If so... - if ((!(mapheaderinfo[gamemap-1]->levelflags & LF_NOTITLECARD)) && (*mapheaderinfo[gamemap-1]->lvlttl != '\0')) - G_PreLevelTitleCard(); + G_PreLevelTitleCard(); return true; } diff --git a/src/p_spec.c b/src/p_spec.c index 84ccc29a5..76a80d754 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4692,7 +4692,7 @@ DoneSection2: if (!post) break; - P_TouchSpecialThing(post, player->mo, false); + P_TouchStarPost(post, player, false); break; } diff --git a/src/p_tick.c b/src/p_tick.c index 0b30ff42d..74472b71f 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -600,7 +600,7 @@ void P_Ticker(boolean run) { players[i].quittime++; - if (players[i].quittime == 30 * TICRATE) + if (players[i].quittime == 30 * TICRATE && G_TagGametype()) P_CheckSurvivors(); if (server && players[i].quittime >= (tic_t)FixedMul(cv_rejointimeout.value, 60 * TICRATE) diff --git a/src/p_user.c b/src/p_user.c index 66d690847..b46659bcb 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2380,6 +2380,8 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) } } } + else if (player->charability == CA_GLIDEANDCLIMB && (player->mo->state-states == S_PLAY_GLIDE_LANDING)) + ; else if (player->charability2 == CA2_GUNSLINGER && player->panim == PA_ABILITY2) ; else if (player->panim != PA_IDLE && player->panim != PA_WALK && player->panim != PA_RUN && player->panim != PA_DASH) @@ -4537,16 +4539,14 @@ void P_DoJump(player_t *player, boolean soundandstate) player->mo->z--; if (player->mo->pmomz < 0) player->mo->momz += player->mo->pmomz; // Add the platform's momentum to your jump. - else - player->mo->pmomz = 0; + player->mo->pmomz = 0; } else { player->mo->z++; if (player->mo->pmomz > 0) player->mo->momz += player->mo->pmomz; // Add the platform's momentum to your jump. - else - player->mo->pmomz = 0; + player->mo->pmomz = 0; } player->mo->eflags &= ~MFE_APPLYPMOMZ; @@ -5503,10 +5503,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) ; // Can't do anything if you're a fish out of water! else if (player->powers[pw_tailsfly]) // If currently flying, give an ascend boost. { - if (!player->fly1) - player->fly1 = 20; - else - player->fly1 = 2; + player->fly1 = 20; if (player->charability == CA_SWIM) player->fly1 /= 2; @@ -8489,7 +8486,11 @@ static void P_MovePlayer(player_t *player) // Descend if (cmd->buttons & BT_USE && !(player->pflags & PF_STASIS) && !player->exiting && !(player->mo->eflags & MFE_GOOWATER)) if (P_MobjFlip(player->mo)*player->mo->momz > -FixedMul(5*actionspd, player->mo->scale)) + { + if (player->fly1 > 2) + player->fly1 = 2; P_SetObjectMomZ(player->mo, -actionspd/2, true); + } } else @@ -11045,10 +11046,21 @@ static void P_MinecartThink(player_t *player) if (angdiff + minecart->angle != player->mo->angle && (!demoplayback || P_ControlStyle(player) == CS_LMAOGALOG)) { + angle_t *ang = NULL; + if (player == &players[consoleplayer]) - localangle = player->mo->angle; + ang = &localangle; else if (player == &players[secondarydisplayplayer]) - localangle2 = player->mo->angle; + ang = &localangle2; + + if (ang) + { + angdiff = *ang - minecart->angle; + if (angdiff < ANGLE_180 && angdiff > MINECARTCONEMAX) + *ang = minecart->angle + MINECARTCONEMAX; + else if (angdiff > ANGLE_180 && angdiff < InvAngle(MINECARTCONEMAX)) + *ang = minecart->angle - MINECARTCONEMAX; + } } } @@ -12164,7 +12176,9 @@ void P_PlayerThink(player_t *player) #ifdef POLYOBJECTS if (player->onconveyor == 1) - player->cmomy = player->cmomx = 0; + player->onconveyor = 3; + else if (player->onconveyor == 3) + player->cmomy = player->cmomx = 0; #endif P_DoSuperStuff(player); diff --git a/src/r_data.c b/src/r_data.c index 871816672..5608fdbde 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -2465,16 +2465,20 @@ extracolormap_t *R_AddColormaps(extracolormap_t *exc_augend, extracolormap_t *ex // Thanks to quake2 source! // utils3/qdata/images.c -UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b) +UINT8 NearestPaletteColor(UINT8 r, UINT8 g, UINT8 b, RGBA_t *palette) { int dr, dg, db; int distortion, bestdistortion = 256 * 256 * 4, bestcolor = 0, i; + // Use master palette if none specified + if (palette == NULL) + palette = pMasterPalette; + for (i = 0; i < 256; i++) { - dr = r - pMasterPalette[i].s.red; - dg = g - pMasterPalette[i].s.green; - db = b - pMasterPalette[i].s.blue; + dr = r - palette[i].s.red; + dg = g - palette[i].s.green; + db = b - palette[i].s.blue; distortion = dr*dr + dg*dg + db*db; if (distortion < bestdistortion) { diff --git a/src/r_data.h b/src/r_data.h index f028f2f5d..145f0182b 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -171,7 +171,8 @@ const char *R_NameForColormap(extracolormap_t *extra_colormap); #define R_PutRgbaRGB(r, g, b) (R_PutRgbaR(r) + R_PutRgbaG(g) + R_PutRgbaB(b)) #define R_PutRgbaRGBA(r, g, b, a) (R_PutRgbaRGB(r, g, b) + R_PutRgbaA(a)) -UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b); +UINT8 NearestPaletteColor(UINT8 r, UINT8 g, UINT8 b, RGBA_t *palette); +#define NearestColor(r, g, b) NearestPaletteColor(r, g, b, NULL) extern INT32 numtextures; diff --git a/src/r_main.c b/src/r_main.c index 414521321..643d8ea49 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -71,6 +71,7 @@ angle_t viewangle, aimingangle; fixed_t viewcos, viewsin; sector_t *viewsector; player_t *viewplayer; +mobj_t *r_viewmobj; // // precalculated math tables @@ -1039,8 +1040,6 @@ subsector_t *R_PointInSubsectorOrNull(fixed_t x, fixed_t y) // R_SetupFrame // -static mobj_t *viewmobj; - // WARNING: a should be unsigned but to add with 2048, it isn't! #define AIMINGTODY(a) ((FINETANGENT((2048+(((INT32)a)>>ANGLETOFINESHIFT)) & FINEMASK)*160)/fovtan) @@ -1097,16 +1096,16 @@ void R_SetupFrame(player_t *player) if (player->awayviewtics) { // cut-away view stuff - viewmobj = player->awayviewmobj; // should be a MT_ALTVIEWMAN - I_Assert(viewmobj != NULL); - viewz = viewmobj->z + 20*FRACUNIT; + r_viewmobj = player->awayviewmobj; // should be a MT_ALTVIEWMAN + I_Assert(r_viewmobj != NULL); + viewz = r_viewmobj->z + 20*FRACUNIT; aimingangle = player->awayviewaiming; - viewangle = viewmobj->angle; + viewangle = r_viewmobj->angle; } else if (!player->spectator && chasecam) // use outside cam view { - viewmobj = NULL; + r_viewmobj = NULL; viewz = thiscam->z + (thiscam->height>>1); aimingangle = thiscam->aiming; viewangle = thiscam->angle; @@ -1116,11 +1115,11 @@ void R_SetupFrame(player_t *player) { viewz = player->viewz; - viewmobj = player->mo; - I_Assert(viewmobj != NULL); + r_viewmobj = player->mo; + I_Assert(r_viewmobj != NULL); aimingangle = player->aiming; - viewangle = viewmobj->angle; + viewangle = r_viewmobj->angle; if (!demoplayback && player->playerstate != PST_DEAD) { @@ -1154,13 +1153,13 @@ void R_SetupFrame(player_t *player) } else { - viewx = viewmobj->x; - viewy = viewmobj->y; + viewx = r_viewmobj->x; + viewy = r_viewmobj->y; viewx += quake.x; viewy += quake.y; - if (viewmobj->subsector) - viewsector = viewmobj->subsector->sector; + if (r_viewmobj->subsector) + viewsector = r_viewmobj->subsector->sector; else viewsector = R_PointInSubsector(viewx, viewy)->sector; } @@ -1182,12 +1181,12 @@ void R_SkyboxFrame(player_t *player) thiscam = &camera; // cut-away view stuff - viewmobj = skyboxmo[0]; + r_viewmobj = skyboxmo[0]; #ifdef PARANOIA - if (!viewmobj) + if (!r_viewmobj) { const size_t playeri = (size_t)(player - players); - I_Error("R_SkyboxFrame: viewmobj null (player %s)", sizeu1(playeri)); + I_Error("R_SkyboxFrame: r_viewmobj null (player %s)", sizeu1(playeri)); } #endif if (player->awayviewtics) @@ -1218,13 +1217,13 @@ void R_SkyboxFrame(player_t *player) } } } - viewangle += viewmobj->angle; + viewangle += r_viewmobj->angle; viewplayer = player; - viewx = viewmobj->x; - viewy = viewmobj->y; - viewz = viewmobj->z; // 26/04/17: use actual Z position instead of spawnpoint angle! + viewx = r_viewmobj->x; + viewy = r_viewmobj->y; + viewz = r_viewmobj->z; // 26/04/17: use actual Z position instead of spawnpoint angle! if (mapheaderinfo[gamemap-1]) { @@ -1264,29 +1263,29 @@ void R_SkyboxFrame(player_t *player) else if (mh->skybox_scaley < 0) y = (campos.y - skyboxmo[1]->y) * -mh->skybox_scaley; - if (viewmobj->angle == 0) + if (r_viewmobj->angle == 0) { viewx += x; viewy += y; } - else if (viewmobj->angle == ANGLE_90) + else if (r_viewmobj->angle == ANGLE_90) { viewx -= y; viewy += x; } - else if (viewmobj->angle == ANGLE_180) + else if (r_viewmobj->angle == ANGLE_180) { viewx -= x; viewy -= y; } - else if (viewmobj->angle == ANGLE_270) + else if (r_viewmobj->angle == ANGLE_270) { viewx += y; viewy -= x; } else { - angle_t ang = viewmobj->angle>>ANGLETOFINESHIFT; + angle_t ang = r_viewmobj->angle>>ANGLETOFINESHIFT; viewx += FixedMul(x,FINECOSINE(ang)) - FixedMul(y, FINESINE(ang)); viewy += FixedMul(x, FINESINE(ang)) + FixedMul(y,FINECOSINE(ang)); } @@ -1297,8 +1296,8 @@ void R_SkyboxFrame(player_t *player) viewz += campos.z * -mh->skybox_scalez; } - if (viewmobj->subsector) - viewsector = viewmobj->subsector->sector; + if (r_viewmobj->subsector) + viewsector = r_viewmobj->subsector->sector; else viewsector = R_PointInSubsector(viewx, viewy)->sector; diff --git a/src/r_patch.c b/src/r_patch.c index b4127f825..80c0f846f 100644 --- a/src/r_patch.c +++ b/src/r_patch.c @@ -1196,7 +1196,7 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp INT32 angle; patch_t *patch; patch_t *newpatch; - UINT16 *rawsrc, *rawdst; + UINT16 *rawdst; size_t size; INT32 bflip = (flip != 0x00); @@ -1242,16 +1242,6 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp leftoffset = width - leftoffset; } - // Draw the sprite to a temporary buffer. - size = (width*height); - rawsrc = Z_Malloc(size * sizeof(UINT16), PU_STATIC, NULL); - - // can't memset here - for (i = 0; i < size; i++) - rawsrc[i] = 0xFF00; - - R_PatchToMaskedFlat(patch, rawsrc, bflip); - // Don't cache angle = 0 for (angle = 1; angle < ROTANGLES; angle++) { diff --git a/src/r_state.h b/src/r_state.h index 4e1eb388e..1451fca7a 100644 --- a/src/r_state.h +++ b/src/r_state.h @@ -86,6 +86,7 @@ extern fixed_t viewx, viewy, viewz; extern angle_t viewangle, aimingangle; extern sector_t *viewsector; extern player_t *viewplayer; +extern mobj_t *r_viewmobj; extern consvar_t cv_allowmlook; extern consvar_t cv_maxportals; diff --git a/src/r_things.c b/src/r_things.c index cb9d78464..dd0722975 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1686,7 +1686,7 @@ static void R_ProjectSprite(mobj_t *thing) thing = thing->tracer; - if (thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW) + if (! R_ThingVisible(thing)) return; tr_x = thing->x - viewx; @@ -2071,7 +2071,7 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel) mobj_t *thing; precipmobj_t *precipthing; // Tails 08-25-2002 INT32 lightnum; - fixed_t approx_dist, limit_dist, hoop_limit_dist; + fixed_t limit_dist, hoop_limit_dist; if (rendermode != render_soft) return; @@ -2104,35 +2104,10 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel) // If a limit exists, handle things a tiny bit different. limit_dist = (fixed_t)(cv_drawdist.value) << FRACBITS; hoop_limit_dist = (fixed_t)(cv_drawdist_nights.value) << FRACBITS; - if (limit_dist || hoop_limit_dist) + for (thing = sec->thinglist; thing; thing = thing->snext) { - for (thing = sec->thinglist; thing; thing = thing->snext) - { - if (thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW) - continue; - - approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y); - - if (thing->sprite == SPR_HOOP) - { - if (hoop_limit_dist && approx_dist > hoop_limit_dist) - continue; - } - else - { - if (limit_dist && approx_dist > limit_dist) - continue; - } - + if (R_ThingVisibleWithinDist(thing, limit_dist, hoop_limit_dist)) R_ProjectSprite(thing); - } - } - else - { - // Draw everything in sector, no checks - for (thing = sec->thinglist; thing; thing = thing->snext) - if (!(thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW)) - R_ProjectSprite(thing); } // no, no infinite draw distance for precipitation. this option at zero is supposed to turn it off @@ -2140,15 +2115,8 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel) { for (precipthing = sec->preciplist; precipthing; precipthing = precipthing->snext) { - if (precipthing->precipflags & PCF_INVISIBLE) - continue; - - approx_dist = P_AproxDistance(viewx-precipthing->x, viewy-precipthing->y); - - if (approx_dist > limit_dist) - continue; - - R_ProjectPrecipitationSprite(precipthing); + if (R_PrecipThingVisible(precipthing, limit_dist)) + R_ProjectPrecipitationSprite(precipthing); } } } @@ -2850,6 +2818,55 @@ void R_ClipSprites(drawseg_t* dsstart, portal_t* portal) } } +/* Check if thing may be drawn from our current view. */ +boolean R_ThingVisible (mobj_t *thing) +{ + return (!( + thing->sprite == SPR_NULL || + ( thing->flags2 & (MF2_DONTDRAW) ) || + thing == r_viewmobj + )); +} + +boolean R_ThingVisibleWithinDist (mobj_t *thing, + fixed_t limit_dist, + fixed_t hoop_limit_dist) +{ + fixed_t approx_dist; + + if (! R_ThingVisible(thing)) + return false; + + approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y); + + if (thing->sprite == SPR_HOOP) + { + if (hoop_limit_dist && approx_dist > hoop_limit_dist) + return false; + } + else + { + if (limit_dist && approx_dist > limit_dist) + return false; + } + + return true; +} + +/* Check if precipitation may be drawn from our current view. */ +boolean R_PrecipThingVisible (precipmobj_t *precipthing, + fixed_t limit_dist) +{ + fixed_t approx_dist; + + if (( precipthing->precipflags & PCF_INVISIBLE )) + return false; + + approx_dist = P_AproxDistance(viewx-precipthing->x, viewy-precipthing->y); + + return ( approx_dist <= limit_dist ); +} + // // R_DrawMasked // @@ -3419,6 +3436,7 @@ static boolean R_ProcessPatchableFields(skin_t *skin, char *stoken, char *value) GETFLAG(DASHMODE) GETFLAG(FASTEDGE) GETFLAG(MULTIABILITY) + GETFLAG(NONIGHTSROTATION) #undef GETFLAG else // let's check if it's a sound, otherwise error out diff --git a/src/r_things.h b/src/r_things.h index c1933e662..217179148 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -59,6 +59,15 @@ void R_InitSprites(void); void R_ClearSprites(void); void R_ClipSprites(drawseg_t* dsstart, portal_t* portal); +boolean R_ThingVisible (mobj_t *thing); + +boolean R_ThingVisibleWithinDist (mobj_t *thing, + fixed_t draw_dist, + fixed_t nights_draw_dist); + +boolean R_PrecipThingVisible (precipmobj_t *precipthing, + fixed_t precip_draw_dist); + /** Used to count the amount of masked elements * per portal to later group them in separate * drawnode lists. diff --git a/src/screen.c b/src/screen.c index 5bb304c08..fcf6c6b0b 100644 --- a/src/screen.c +++ b/src/screen.c @@ -360,10 +360,13 @@ void SCR_Recalc(void) vid.fsmalldupy = vid.smalldupy*FRACUNIT; #endif - // toggle off automap because some screensize-dependent values will + // toggle off (then back on) the automap because some screensize-dependent values will // be calculated next time the automap is activated. if (automapactive) - AM_Stop(); + { + am_recalc = true; + AM_Start(); + } // set the screen[x] ptrs on the new vidbuffers V_Init(); diff --git a/src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj b/src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj index ab3157c44..2b03cb8d4 100644 --- a/src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj +++ b/src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj @@ -1219,7 +1219,7 @@ C01FCF4B08A954540054247B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - CURRENT_PROJECT_VERSION = 2.2.0; + CURRENT_PROJECT_VERSION = 2.2.1; GCC_PREPROCESSOR_DEFINITIONS = ( "$(inherited)", NORMALSRB2, @@ -1231,7 +1231,7 @@ C01FCF4C08A954540054247B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - CURRENT_PROJECT_VERSION = 2.2.0; + CURRENT_PROJECT_VERSION = 2.2.1; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_PREPROCESSOR_DEFINITIONS = ( diff --git a/src/st_stuff.c b/src/st_stuff.c index 4676506fc..d99d564c8 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1278,13 +1278,15 @@ void ST_preDrawTitleCard(void) // void ST_runTitleCard(void) { + boolean run = !(paused || P_AutoPause()); + if (!G_IsTitleCardAvailable()) return; if (lt_ticker >= (lt_endtime + TICRATE)) return; - if (!(paused || P_AutoPause())) + if (run || (lt_ticker < PRELEVELTIME)) { // tick lt_ticker++; diff --git a/src/v_video.c b/src/v_video.c index 4785a1541..81625ff9e 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -3244,7 +3244,6 @@ Unoptimized version #endif } -// Taken from my videos-in-SRB2 project // Generates a color look-up table // which has up to 64 colors at each channel // (see the defines in v_video.h) @@ -3261,7 +3260,7 @@ void InitColorLUT(RGBA_t *palette) for (r = 0; r < CLUTSIZE; r++) for (g = 0; g < CLUTSIZE; g++) for (b = 0; b < CLUTSIZE; b++) - colorlookup[r][g][b] = NearestColor(r << SHIFTCOLORBITS, g << SHIFTCOLORBITS, b << SHIFTCOLORBITS); + colorlookup[r][g][b] = NearestPaletteColor(r << SHIFTCOLORBITS, g << SHIFTCOLORBITS, b << SHIFTCOLORBITS, palette); clutinit = true; lastpalette = palette; } diff --git a/src/v_video.h b/src/v_video.h index eb75a414f..bc19f6e99 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -37,10 +37,7 @@ cv_allcaps; // Allocates buffer screens, call before R_Init. void V_Init(void); -// Taken from my videos-in-SRB2 project -// Generates a color look-up table -// which has up to 64 colors at each channel - +// Color look-up table #define COLORBITS 6 #define SHIFTCOLORBITS (8-COLORBITS) #define CLUTSIZE (1<real); - block->prev->next = block->next; - block->next->prev = block->prev; - free(block); #ifdef VALGRIND_DESTROY_MEMPOOL VALGRIND_DESTROY_MEMPOOL(block); #endif + block->prev->next = block->next; + block->next->prev = block->prev; + free(block); } /** malloc() that doesn't accept failure. @@ -317,13 +317,9 @@ void *Z_MallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits) // The mem header lives 'sizeof (memhdr_t)' bytes before given. hdr = (memhdr_t *)((UINT8 *)given - sizeof *hdr); -#ifdef VALGRIND_CREATE_MEMPOOL - VALGRIND_CREATE_MEMPOOL(block, padsize, Z_calloc); +#ifdef HAVE_VALGRIND Z_calloc = false; #endif -#ifdef VALGRIND_MEMPOOL_ALLOC - VALGRIND_MEMPOOL_ALLOC(block, hdr, size + sizeof *hdr); -#endif block->next = head.next; block->prev = &head; @@ -341,6 +337,13 @@ void *Z_MallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits) block->size = blocksize; block->realsize = size; +#ifdef VALGRIND_CREATE_MEMPOOL + VALGRIND_CREATE_MEMPOOL(block, padsize, Z_calloc); +#endif +//#ifdef VALGRIND_MEMPOOL_ALLOC +// VALGRIND_MEMPOOL_ALLOC(block, hdr, size + sizeof *hdr); +//#endif + hdr->id = ZONEID; hdr->block = block;