diff --git a/src/f_finale.c b/src/f_finale.c index 0c648bc36..925b57b89 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1381,8 +1381,8 @@ void F_TitleScreenDrawer(void) // Draw that sky! if (curbgcolor >= 0) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, curbgcolor); - else if (!curbghide || !titlemapinaction || gamestate == GS_WAITINGPLAYERS) - F_SkyScroll(curbgxspeed, curbgyspeed, curbgname); + //else if (!curbghide || !titlemapinaction || gamestate == GS_WAITINGPLAYERS) + //F_SkyScroll(curbgxspeed, curbgyspeed, curbgname); // Don't draw outside of the title screen, or if the patch isn't there. if (gamestate != GS_TITLESCREEN && gamestate != GS_WAITINGPLAYERS) diff --git a/src/filesrch.c b/src/filesrch.c index eff1fef20..d622cd096 100644 --- a/src/filesrch.c +++ b/src/filesrch.c @@ -428,9 +428,32 @@ filestatus_t filesearch(char *filename, const char *startpath, UINT64 wantedhash // okay, now we actually want searchpath to incorporate d_name strcpy(&searchpath[searchpathindex[depthleft]],dent->d_name); - if (stat(searchpath,&fsstat) < 0) // do we want to follow symlinks? if not: change it to lstat +#if defined(__linux__) || defined(__FreeBSD__) + if (dent->d_type == DT_UNKNOWN && lstat(searchpath, &fsstat) == 0) + { + if (S_ISDIR(fsstat.st_mode)) + dent->d_type = DT_DIR; + else if (S_ISLNK(fsstat.st_mode)) + dent->d_type = DT_LNK; + } + + // Symlinks aren't always directory symlinks. Dunno if this would resolve recursive + // symlinks, but i think stat already does that + if (dent->d_type == DT_LNK && stat(searchpath, &fsstat) == 0 && !S_ISDIR(fsstat.st_mode)) + { + dent->d_type = DT_UNKNOWN; + } + + // Linux and FreeBSD has a special field for file type on dirent, so use that to speed up lookups. + // FIXME: should we also follow symlinks? + if ((dent->d_type == DT_DIR && depthleft) || (dent->d_type == DT_LNK && depthleft)) +#else + // if we wanna follow symlinks we can check with FILE_ATTRIBUTE_REPARSE_POINT + DWORD fileattr = GetFileAttributes(searchpath); + if (fileattr == INVALID_FILE_ATTRIBUTES) ; // was the file (re)moved? can't stat it - else if (S_ISDIR(fsstat.st_mode) && depthleft) + else if ((fileattr & FILE_ATTRIBUTE_DIRECTORY) && depthleft) +#endif { searchpathindex[--depthleft] = strlen(searchpath) + 1; dirhandle[depthleft] = opendir(searchpath); diff --git a/src/g_game.c b/src/g_game.c index d65a5e6fd..9f845cf56 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -938,7 +938,7 @@ INT32 G_PlayerInputAnalog(UINT8 p, INT32 gc, boolean digital) deadzone = (JOYAXISRANGE * cv_deadzone[p].value) / FRACUNIT; - deviceID = cv_usejoystick[p].value; + deviceID = I_GetJoystickDeviceIndexForPlayer(p) + 1; retrygetcontrol: for (i = 0; i < MAXINPUTMAPPING; i++) @@ -1056,7 +1056,7 @@ static void G_DoCameraTurn(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer, player if (player->mo) cmd->angle = K_GetKartTurnValue(player, cmd->angle); - + cmd->angle *= realtics; if (P_CanPlayerTurn(player, cmd)) @@ -1315,7 +1315,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) cmd->sidemove = MAXPLMOVE; else if (cmd->sidemove < -MAXPLMOVE) cmd->sidemove = -MAXPLMOVE; - + if (cmd->turning > KART_FULLTURN) cmd->turning = KART_FULLTURN; else if (cmd->turning < -KART_FULLTURN) @@ -2375,9 +2375,9 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) boolean followerready; INT32 followerskin; UINT16 followercolor; - + mobj_t *follower; // old follower, will probably be removed by the time we're dead but you never know. - + INT32 charflags; UINT32 followitem; @@ -2394,7 +2394,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) tic_t starposttime; // The time of the last cheatcheck you hit INT32 prevcheck; // Distance from Previous Legacy Checkpoint INT32 nextcheck; // Distace to Next Legacy Checkpoint - + INT32 exiting; INT32 khudcardanimation; INT16 totalring; @@ -2542,7 +2542,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) wanted = players[player].wanted; rings = players[player].rings; kickstartaccel = players[player].kickstartaccel; - + nocontrol = players[player].nocontrol; laps = players[player].laps; @@ -2552,7 +2552,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) exiting = players[player].exiting; khudcardanimation = (exiting > 0) ? players[player].karthud[khud_cardanimation] : 0; - + starpostx = players[player].starpostx; starposty = players[player].starposty; starpostz = players[player].starpostz; @@ -2579,7 +2579,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) { follower = NULL; } - + spectatorreentry = players[player].spectatorreentry; grieftime = players[player].grieftime; @@ -2622,7 +2622,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) p->starposttime = starposttime; p->prevcheck = prevcheck; p->nextcheck = nextcheck; - + p->exiting = exiting; p->karthud[khud_cardanimation] = khudcardanimation; @@ -2654,7 +2654,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) p->ringvolume = 255; p->ringtransparency = 255; - + p->spectatorreentry = spectatorreentry; p->grieftime = grieftime; p->griefstrikes = griefstrikes; @@ -2732,7 +2732,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) if (songcredit) S_ShowMusicCredit(); - + if (leveltime > (starttime + (TICRATE/2)) && !p->spectator) p->respawn = 48; // Respawn effect } @@ -2795,7 +2795,7 @@ void G_SpawnPlayer(INT32 playernum, boolean starpost) } void G_MovePlayerToSpawnOrStarpost(INT32 playernum, boolean starpost) -{ +{ if ((leveltime > starttime) && starpost) P_MovePlayerToStarpost(playernum); else @@ -3121,10 +3121,10 @@ void G_DoReborn(INT32 playernum) { // respawn at the start mobj_t *oldmo = NULL; - + if (player->spectator) ; - else if ((player->starpostnum || ((player->nextwaypoint != NULL) && player->starposttime)) + else if ((player->starpostnum || ((player->nextwaypoint != NULL) && player->starposttime)) || ((mapheaderinfo[gamemap - 1]->levelflags & LF_SECTIONRACE) && player->laps)) // SRB2kart starpost = true; @@ -4563,7 +4563,7 @@ void G_LoadGameData(void) if (vspowerlevel[i] < PWRLVRECORD_MIN || vspowerlevel[i] > PWRLVRECORD_MAX) goto datacorrupt; } - + modded = READUINT8(save.p); // Aha! Someone's been screwing with the save file! diff --git a/src/g_input.c b/src/g_input.c index 9914d6bef..20ef4d199 100644 --- a/src/g_input.c +++ b/src/g_input.c @@ -14,6 +14,7 @@ #include "doomdef.h" #include "doomstat.h" #include "g_input.h" +#include "i_system.h" #include "keys.h" #include "hu_stuff.h" // need HUFONT start & end #include "d_net.h" @@ -38,7 +39,7 @@ consvar_t cv_turnsmooth = CVAR_INIT ("turnsmoothing", "Off", CV_SAVE, turnsmooth // current state of the keys // JOYAXISRANGE for fully pressed, 0 for not pressed INT32 gamekeydown[MAXDEVICES][NUMINPUTS]; -boolean deviceResponding[MAXDEVICES]; +boolean deviceResponding[MAXDEVICES]; // several key codes (or virtual key) per game control INT32 gamecontrol[MAXSPLITSCREENPLAYERS][num_gamecontrols][MAXINPUTMAPPING]; @@ -100,7 +101,7 @@ INT32 G_GetDevicePlayer(INT32 deviceID) for (i = 0; i < MAXSPLITSCREENPLAYERS; i++) { - if (deviceID == cv_usejoystick[i].value) + if (deviceID == I_GetJoystickDeviceIndexForPlayer(i) + 1) { return i; } diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 96b500d1d..2028f2479 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -460,24 +460,22 @@ static void HWR_GenerateTexture(GLMapTexture_t *grtex, INT32 texnum, boolean noe UINT8 *colormap = colormaps; - INT32 i; + INT32 i, idx; boolean skyspecial = false; //poor hack for Legacy large skies.. texture = textures[texnum]; + grtex->mipmap.flags = TF_CHROMAKEYED | TF_WRAPXY; + grtex->mipmap.format = textureformat; + // hack the Legacy skies.. - if (texture->name[0] == 'S' && - texture->name[1] == 'K' && - texture->name[2] == 'Y' && - (texture->name[4] == 0 || - texture->name[5] == 0) - ) + if (memcmp(texture->name, "SKY", 3) == 0 && + (texture->name[4] == 0 || texture->name[5] == 0)) { skyspecial = true; - grtex->mipmap.flags = TF_WRAPXY; // don't use the chromakey for sky + grtex->mipmap.flags &= ~TF_CHROMAKEYED; // don't use the chromakey for sky + grtex->mipmap.format = GL_TEXFMT_RGBA; // that skyspecial code below assumes this format ... } - else - grtex->mipmap.flags = TF_CHROMAKEYED | TF_WRAPXY; grtex->mipmap.width = (UINT16)texture->width; grtex->mipmap.height = (UINT16)texture->height; @@ -501,14 +499,14 @@ static void HWR_GenerateTexture(GLMapTexture_t *grtex, INT32 texnum, boolean noe RGBA_t col; col = V_GetColor(HWR_PATCHES_CHROMAKEY_COLORINDEX); - for (j = 0; j < blockheight; j++) + for (idx = 0, j = 0; j < blockheight; j++) { - for (i = 0; i < blockwidth; i++) + for (i = 0; i < blockwidth; i++, idx++) { - block[4*(j*blockwidth+i)+0] = col.s.red; - block[4*(j*blockwidth+i)+1] = col.s.green; - block[4*(j*blockwidth+i)+2] = col.s.blue; - block[4*(j*blockwidth+i)+3] = 0xff; + block[4*idx+0] = col.s.red; + block[4*idx+1] = col.s.green; + block[4*idx+2] = col.s.blue; + block[4*idx+3] = 0xff; } } } diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index f901d8a2f..a0b3661fe 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -6184,7 +6184,7 @@ consvar_t cv_glspritebillboarding = CVAR_INIT ("gr_spritebillboarding", "On", CV consvar_t cv_glskydome = CVAR_INIT ("gr_skydome", "On", CV_SAVE, CV_OnOff, NULL); consvar_t cv_glfiltermode = CVAR_INIT ("gr_filtermode", "Nearest", CV_SAVE|CV_CALL, glfiltermode_cons_t, CV_glfiltermode_OnChange); -consvar_t cv_glanisotropicmode = CVAR_INIT ("gr_anisotropicmode", "1", CV_CALL, glanisotropicmode_cons_t, CV_glanisotropic_OnChange); +consvar_t cv_glanisotropicmode = CVAR_INIT ("gr_anisotropicmode", "1", CV_SAVE|CV_CALL, glanisotropicmode_cons_t, CV_glanisotropic_OnChange); consvar_t cv_glsolvetjoin = CVAR_INIT ("gr_solvetjoin", "On", 0, CV_OnOff, NULL); diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 989a6e10b..6357f9a8f 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1880,11 +1880,14 @@ EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *pTexInfo) INT32 w = pTexInfo->width, h = pTexInfo->height; INT32 i, j; + INT32 idx; const GLubyte *pImgData = (const GLubyte *)pTexInfo->data; const GLvoid *ptex = NULL; RGBA_t *tex = NULL; + GLint texformat = 0; + // Generate a new texture name. if (!num) { @@ -1895,85 +1898,84 @@ EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *pTexInfo) //GL_DBG_Printf("UpdateTexture %d %x\n", (INT32)num, pImgData); - if ((pTexInfo->format == GL_TEXFMT_P_8) || (pTexInfo->format == GL_TEXFMT_AP_88)) + texformat = textureformatGL; + const GLTextureFormat_t texinfoformat = pTexInfo->format; + + switch (texinfoformat) { - AllocTextureBuffer(pTexInfo); - ptex = tex = textureBuffer; + case GL_TEXFMT_P_8: + case GL_TEXFMT_AP_88: + AllocTextureBuffer(pTexInfo); + ptex = tex = textureBuffer; - for (j = 0; j < h; j++) - { - for (i = 0; i < w; i++) + const int chromakeyed = (pTexInfo->flags & TF_CHROMAKEYED); + + for (idx = 0, j = 0; j < h; j++) { - if ((*pImgData == HWR_PATCHES_CHROMAKEY_COLORINDEX) && - (pTexInfo->flags & TF_CHROMAKEYED)) + for (i = 0; i < w; i++, idx++) { - tex[w*j+i].s.red = 0; - tex[w*j+i].s.green = 0; - tex[w*j+i].s.blue = 0; - tex[w*j+i].s.alpha = 0; - pTexInfo->flags |= TF_TRANSPARENT; // there is a hole in it - } - else - { - tex[w*j+i].s.red = myPaletteData[*pImgData].s.red; - tex[w*j+i].s.green = myPaletteData[*pImgData].s.green; - tex[w*j+i].s.blue = myPaletteData[*pImgData].s.blue; - tex[w*j+i].s.alpha = myPaletteData[*pImgData].s.alpha; - } + if (chromakeyed && (*pImgData == HWR_PATCHES_CHROMAKEY_COLORINDEX)) + { + tex[idx].s = (byteColor_t){0, 0, 0, 0}; + pTexInfo->flags |= TF_TRANSPARENT; // there is a hole in it + } + else + { + tex[idx].s = myPaletteData[*pImgData].s; + } - pImgData++; + pImgData++; - if (pTexInfo->format == GL_TEXFMT_AP_88) - { - if (!(pTexInfo->flags & TF_CHROMAKEYED)) - tex[w*j+i].s.alpha = *pImgData; + if (texinfoformat != GL_TEXFMT_AP_88 || chromakeyed) + continue; + + tex[idx].s.alpha = *pImgData; pImgData++; } } - } - } - else if (pTexInfo->format == GL_TEXFMT_RGBA) - { - // Directly upload the texture data without any kind of conversion. - ptex = pImgData; - } - else if (pTexInfo->format == GL_TEXFMT_ALPHA_INTENSITY_88) - { - AllocTextureBuffer(pTexInfo); - ptex = tex = textureBuffer; + break; + case GL_TEXFMT_RGBA: + // Directly upload the texture data without any kind of conversion. + ptex = pImgData; + break; + case GL_TEXFMT_ALPHA_INTENSITY_88: + AllocTextureBuffer(pTexInfo); + ptex = tex = textureBuffer; + texformat = GL_RGBA; - for (j = 0; j < h; j++) - { - for (i = 0; i < w; i++) + for (idx = 0, j = 0; j < h; j++) { - tex[w*j+i].s.red = *pImgData; - tex[w*j+i].s.green = *pImgData; - tex[w*j+i].s.blue = *pImgData; - pImgData++; - tex[w*j+i].s.alpha = *pImgData; - pImgData++; + for (i = 0; i < w; i++, idx++) + { + tex[idx].s.red = *pImgData; + tex[idx].s.green = *pImgData; + tex[idx].s.blue = *pImgData; + pImgData++; + tex[idx].s.alpha = *pImgData; + pImgData++; + } } - } - } - else if (pTexInfo->format == GL_TEXFMT_ALPHA_8) // Used for fade masks - { - AllocTextureBuffer(pTexInfo); - ptex = tex = textureBuffer; + break; + case GL_TEXFMT_ALPHA_8: // Used for fade masks + AllocTextureBuffer(pTexInfo); + ptex = tex = textureBuffer; + texformat = GL_RGBA; - for (j = 0; j < h; j++) - { - for (i = 0; i < w; i++) + // 255 because the fade mask is modulated with the screen texture, so alpha affects it while the colours don't + memset(&tex->s, 255, sizeof(byteColor_t)*w*h); + + for (idx = 0, j = 0; j < h; j++) { - tex[w*j+i].s.red = 255; // 255 because the fade mask is modulated with the screen texture, so alpha affects it while the colours don't - tex[w*j+i].s.green = 255; - tex[w*j+i].s.blue = 255; - tex[w*j+i].s.alpha = *pImgData; - pImgData++; + for (i = 0; i < w; i++, idx++) + { + tex[idx].s.alpha = *pImgData++; + } } - } + break; + default: + GL_MSG_Warning("UpdateTexture: bad format %d\n", texinfoformat); + break; } - else - GL_MSG_Warning("UpdateTexture: bad format %d\n", pTexInfo->format); if (!(pTexInfo->flags & TF_BRIGHTMAP)) { @@ -1985,8 +1987,10 @@ EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *pTexInfo) pglBindTexture(GL_TEXTURE_2D, num); tex_downloaded = num; + const int transparent = (pTexInfo->flags & TF_TRANSPARENT); + // disable texture filtering on any texture that has holes so there's no dumb borders or blending issues - if (pTexInfo->flags & TF_TRANSPARENT) + if (transparent) { pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); @@ -1997,70 +2001,25 @@ EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *pTexInfo) pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter); } - if (pTexInfo->format == GL_TEXFMT_ALPHA_INTENSITY_88) + if (MipMap && !transparent) // No mipmaps on transparent stuff { - //pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); - if (MipMap) - { - pglTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); - pglTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0); - if (pTexInfo->flags & TF_TRANSPARENT) - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0); // No mippmaps on transparent stuff - else - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 4); - //pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_LINEAR_MIPMAP_LINEAR); - } + pglTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); + + if (update) + pglTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex); else - { - if (update) - pglTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex); - else - pglTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); - } - } - else if (pTexInfo->format == GL_TEXFMT_ALPHA_8) - { - //pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); - if (MipMap) - { - pglTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); - pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0); - if (pTexInfo->flags & TF_TRANSPARENT) - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0); // No mippmaps on transparent stuff - else - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 4); - //pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_LINEAR_MIPMAP_LINEAR); - } - else - { - if (update) - pglTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex); - else - pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); - } + pglTexImage2D(GL_TEXTURE_2D, 0, texformat, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); + + // Control the mipmap level of detail + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 5); } else { - if (MipMap) - { - pglTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); - pglTexImage2D(GL_TEXTURE_2D, 0, textureformatGL, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); - // Control the mipmap level of detail - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0); // the lower the number, the higer the detail - if (pTexInfo->flags & TF_TRANSPARENT) - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0); // No mippmaps on transparent stuff - else - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 5); - } + if (update) + pglTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex); else - { - if (update) - pglTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex); - else - pglTexImage2D(GL_TEXTURE_2D, 0, textureformatGL, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); - } + pglTexImage2D(GL_TEXTURE_2D, 0, texformat, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); } if (pTexInfo->flags & TF_WRAPX) diff --git a/src/i_system.h b/src/i_system.h index c778b3d0b..aaf37fb9a 100644 --- a/src/i_system.h +++ b/src/i_system.h @@ -310,6 +310,8 @@ const char *I_LocateWad(void); */ void I_GetJoystickEvents(UINT8 index); +INT32 I_GetJoystickDeviceIndexForPlayer(UINT8 pnum); + /** \brief Checks if the mouse needs to be grabbed */ void I_UpdateMouseGrab(void); diff --git a/src/p_floor.c b/src/p_floor.c index 1677c72db..1856a051b 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -2054,92 +2054,210 @@ void EV_DoCrushFloorOnce(mtag_t tag, fixed_t speed) // jff 2/22/98 new type to move floor and ceiling in parallel // void EV_DoElevator(mtag_t tag, line_t *line, elevator_e elevtype) +{ + // This function is deprecated. + // Use any of the following functions directly, instead. + + switch (elevtype) + { + case elevateDown: + EV_DoElevateDown(tag); + break; + case elevateUp: + EV_DoElevateUp(tag); + break; + case elevateHighest: + EV_DoElevateHighest(tag); + break; + case elevateContinuous: + EV_DoContinuousElevator( + tag, + line->args[1] << (FRACBITS - 2), + line->args[2], + line->args[3], + (line->args[4] == 0) + ); + break; + case bridgeFall: + EV_DoBridgeFall(tag); + break; + default: + break; + } +} + +static elevator_t *CreateElevatorThinker(sector_t *sec) +{ + elevator_t *elevator = NULL; + + if (sec->floordata || sec->ceilingdata) + { + return NULL; + } + + elevator = Z_Calloc(sizeof (*elevator), PU_LEVSPEC, NULL); + P_AddThinker(THINK_MAIN, &elevator->thinker); + + // make sure other thinkers won't get started over this one + sec->floordata = elevator; + sec->ceilingdata = elevator; + + // set up some generic aspects of the floormove_t + elevator->thinker.function.acp1 = (actionf_p1)T_MoveElevator; + elevator->distance = 1; // Always crush unless otherwise + elevator->sector = sec; + + // interpolation + R_CreateInterpolator_SectorPlane(&elevator->thinker, sec, false); + R_CreateInterpolator_SectorPlane(&elevator->thinker, sec, true); + + return elevator; +} + +void EV_DoElevateDown(mtag_t tag) { INT32 secnum = -1; sector_t *sec; - elevator_t *elevator; - // act on all sectors with the given tag TAG_ITER_SECTORS(tag, secnum) { + elevator_t *elevator = NULL; sec = §ors[secnum]; - // If either floor or ceiling is already activated, skip it - if (sec->floordata || sec->ceilingdata) - continue; - - // create and initialize new elevator thinker - elevator = Z_Calloc(sizeof (*elevator), PU_LEVSPEC, NULL); - P_AddThinker(THINK_MAIN, &elevator->thinker); - sec->floordata = elevator; - sec->ceilingdata = elevator; - elevator->thinker.function.acp1 = (actionf_p1)T_MoveElevator; - elevator->type = elevtype; - elevator->sourceline = line; - elevator->distance = 1; // Always crush unless otherwise - elevator->sector = sec; - - // set up the fields according to the type of elevator action - switch (elevtype) + elevator = CreateElevatorThinker(sec); + if (elevator == NULL) { - // elevator down to next floor - case elevateDown: - elevator->direction = -1; - elevator->speed = ELEVATORSPEED/2; // half speed - elevator->floordestheight = P_FindNextLowestFloor(sec, sec->floorheight); - break; - - // elevator up to next floor - case elevateUp: - elevator->direction = 1; - elevator->speed = ELEVATORSPEED/4; // quarter speed - elevator->floordestheight = P_FindNextHighestFloor(sec, sec->floorheight); - break; - - // elevator up to highest floor - case elevateHighest: - elevator->direction = 1; - elevator->speed = ELEVATORSPEED/4; // quarter speed - elevator->floordestheight = P_FindHighestFloorSurrounding(sec); - break; - - case elevateContinuous: - elevator->origspeed = line->args[1] << (FRACBITS - 2); - elevator->speed = elevator->origspeed; - - elevator->low = !line->args[4]; // go down first unless args[4] is set - if (elevator->low) - { - elevator->direction = 1; - elevator->floordestheight = P_FindNextHighestFloor(sec, sec->floorheight); - } - else - { - elevator->direction = -1; - elevator->floordestheight = P_FindNextLowestFloor(sec,sec->floorheight); - } - elevator->floorwasheight = elevator->sector->floorheight; - elevator->ceilingwasheight = elevator->sector->ceilingheight; - - elevator->delay = line->args[3]; - elevator->delaytimer = line->args[2]; // Initial delay - break; - - case bridgeFall: - elevator->direction = -1; - elevator->speed = ELEVATORSPEED*4; // quadruple speed - elevator->floordestheight = P_FindNextLowestFloor(sec, sec->floorheight); - break; - - default: - break; + continue; } - elevator->ceilingdestheight = elevator->floordestheight + sec->ceilingheight - sec->floorheight; + elevator->type = elevateDown; - // interpolation - R_CreateInterpolator_SectorPlane(&elevator->thinker, sec, false); - R_CreateInterpolator_SectorPlane(&elevator->thinker, sec, true); + elevator->direction = -1; + elevator->speed = ELEVATORSPEED/2; // half speed + elevator->floordestheight = P_FindNextLowestFloor(sec, sec->floorheight); + + elevator->ceilingdestheight = elevator->floordestheight + (sec->ceilingheight - sec->floorheight); + } +} + +void EV_DoElevateUp(mtag_t tag) +{ + INT32 secnum = -1; + sector_t *sec; + + TAG_ITER_SECTORS(tag, secnum) + { + elevator_t *elevator = NULL; + sec = §ors[secnum]; + + elevator = CreateElevatorThinker(sec); + if (elevator == NULL) + { + continue; + } + + elevator->type = elevateDown; + + elevator->direction = 1; + elevator->speed = ELEVATORSPEED/4; // quarter speed + elevator->floordestheight = P_FindNextHighestFloor(sec, sec->floorheight); + + elevator->ceilingdestheight = elevator->floordestheight + (sec->ceilingheight - sec->floorheight); + } +} + +void EV_DoElevateHighest(mtag_t tag) +{ + INT32 secnum = -1; + sector_t *sec; + + TAG_ITER_SECTORS(tag, secnum) + { + elevator_t *elevator = NULL; + sec = §ors[secnum]; + + elevator = CreateElevatorThinker(sec); + if (elevator == NULL) + { + continue; + } + + elevator->type = elevateHighest; + + elevator->direction = 1; + elevator->speed = ELEVATORSPEED/4; // quarter speed + elevator->floordestheight = P_FindHighestFloorSurrounding(sec); + + elevator->ceilingdestheight = elevator->floordestheight + (sec->ceilingheight - sec->floorheight); + } +} + +void EV_DoContinuousElevator(mtag_t tag, fixed_t speed, INT32 delayInit, INT32 delay, boolean lowFirst) +{ + INT32 secnum = -1; + sector_t *sec; + + TAG_ITER_SECTORS(tag, secnum) + { + elevator_t *elevator = NULL; + sec = §ors[secnum]; + + elevator = CreateElevatorThinker(sec); + if (elevator == NULL) + { + continue; + } + + elevator->type = elevateContinuous; + + elevator->origspeed = speed; + elevator->speed = elevator->origspeed; + + elevator->low = lowFirst; // go down first unless args[4] is set + if (elevator->low) + { + elevator->direction = 1; + elevator->floordestheight = P_FindNextHighestFloor(sec, sec->floorheight); + } + else + { + elevator->direction = -1; + elevator->floordestheight = P_FindNextLowestFloor(sec,sec->floorheight); + } + + elevator->floorwasheight = elevator->sector->floorheight; + elevator->ceilingwasheight = elevator->sector->ceilingheight; + + elevator->delay = delay; + elevator->delaytimer = delayInit; // Initial delay + + elevator->ceilingdestheight = elevator->floordestheight + (sec->ceilingheight - sec->floorheight); + } +} + +void EV_DoBridgeFall(mtag_t tag) +{ + INT32 secnum = -1; + sector_t *sec; + + TAG_ITER_SECTORS(tag, secnum) + { + elevator_t *elevator = NULL; + sec = §ors[secnum]; + + elevator = CreateElevatorThinker(sec); + if (elevator == NULL) + { + continue; + } + + elevator->type = bridgeFall; + + elevator->direction = -1; + elevator->speed = ELEVATORSPEED*4; // quadruple speed + elevator->floordestheight = P_FindNextLowestFloor(sec, sec->floorheight); + + elevator->ceilingdestheight = elevator->floordestheight + (sec->ceilingheight - sec->floorheight); } } diff --git a/src/p_saveg.c b/src/p_saveg.c index 9af8dd45b..80de3ea72 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -2864,7 +2864,6 @@ static void SaveElevatorThinker(savebuffer_t *save, const thinker_t *th, const U WRITEFIXED(save->p, ht->delaytimer); WRITEFIXED(save->p, ht->floorwasheight); WRITEFIXED(save->p, ht->ceilingwasheight); - WRITEUINT32(save->p, SaveLine(ht->sourceline)); } static void SaveCrumbleThinker(savebuffer_t *save, const thinker_t *th, const UINT8 type) @@ -4201,7 +4200,6 @@ static thinker_t* LoadElevatorThinker(savebuffer_t *save, actionf_p1 thinker, bo ht->delaytimer = READFIXED(save->p); ht->floorwasheight = READFIXED(save->p); ht->ceilingwasheight = READFIXED(save->p); - ht->sourceline = LoadLine(READUINT32(save->p)); if (ht->sector && setplanedata) { diff --git a/src/p_spec.c b/src/p_spec.c index 43216beda..e37a912df 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3150,7 +3150,13 @@ boolean P_ProcessSpecial(activator_t *activator, INT16 special, INT32 *args, cha break; case 428: // Start floating platform movement - EV_DoElevator(args[0], line, elevateContinuous); + EV_DoContinuousElevator( + args[0], + args[1] << (FRACBITS - 2), + args[2], + args[3], + (args[4] == 0) + ); break; case 429: // Crush planes once diff --git a/src/p_spec.h b/src/p_spec.h index c34a4e80d..a1d389598 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -890,7 +890,6 @@ struct elevator_t fixed_t delaytimer; fixed_t floorwasheight; // Height the floor WAS at fixed_t ceilingwasheight; // Height the ceiling WAS at - line_t *sourceline; }; typedef enum @@ -1039,6 +1038,12 @@ void EV_DoBounceFloor(mtag_t tag, boolean crush, fixed_t crushHeight, fixed_t cr void EV_DoCrushFloorOnce(mtag_t tag, fixed_t speed); void EV_DoElevator(mtag_t tag, line_t *line, elevator_e elevtype); +void EV_DoElevateDown(mtag_t tag); +void EV_DoElevateUp(mtag_t tag); +void EV_DoElevateHighest(mtag_t tag); +void EV_DoContinuousElevator(mtag_t tag, fixed_t speed, INT32 delayInit, INT32 delay, boolean lowFirst); +void EV_DoBridgeFall(mtag_t tag); + void EV_CrumbleChain(sector_t *sec, ffloor_t *rover); void EV_BounceSector(sector_t *sector, fixed_t momz, line_t *sourceline); diff --git a/src/r_draw_column.cpp b/src/r_draw_column.cpp index abd970e3c..4234427c5 100644 --- a/src/r_draw_column.cpp +++ b/src/r_draw_column.cpp @@ -99,6 +99,7 @@ static void R_DrawColumnTemplate(drawcolumndata_t *dc) { INT32 count; UINT8 *dest; + const INT32 vidwidth = vid.width; count = dc->yh - dc->yl; @@ -107,7 +108,7 @@ static void R_DrawColumnTemplate(drawcolumndata_t *dc) return; } - if ((unsigned)dc->x >= (unsigned)vid.width || dc->yl < 0 || dc->yh >= vid.height) + if ((unsigned)dc->x >= (unsigned)vidwidth || dc->yl < 0 || dc->yh >= vid.height) { return; } @@ -210,7 +211,7 @@ static void R_DrawColumnTemplate(drawcolumndata_t *dc) // Use columnofs LUT for subwindows? //dest = ylookup[dc_yl] + columnofs[dc_x]; - dest = &topleft[dc->yl * vid.width + dc->x]; + dest = &topleft[dc->yl * vidwidth + dc->x]; count++; @@ -235,7 +236,7 @@ static void R_DrawColumnTemplate(drawcolumndata_t *dc) while (--count > 0) { *dest = R_DrawColumnPixel(dc, dest, frac>>FRACBITS); - dest += vid.width; + dest += vidwidth; frac += fracstep; } } @@ -280,7 +281,7 @@ static void R_DrawColumnTemplate(drawcolumndata_t *dc) *dest = R_DrawColumnPixel(dc, dest, n); } - dest += vid.width; + dest += vidwidth; // Avoid overflow. if (fracstep > 0x7FFFFFFF - frac) @@ -305,12 +306,12 @@ static void R_DrawColumnTemplate(drawcolumndata_t *dc) { *dest = R_DrawColumnPixel(dc, dest, (frac>>FRACBITS) & heightmask); - dest += vid.width; + dest += vidwidth; frac += fracstep; *dest = R_DrawColumnPixel(dc, dest, (frac>>FRACBITS) & heightmask); - dest += vid.width; + dest += vidwidth; frac += fracstep; } @@ -348,6 +349,7 @@ void R_DrawFogColumn(drawcolumndata_t *dc) INT32 count; UINT8 *dest; + const INT32 vidwidth = vid.width; count = dc->yh - dc->yl; @@ -355,21 +357,21 @@ void R_DrawFogColumn(drawcolumndata_t *dc) if (count < 0) return; - if ((unsigned)dc->x >= (unsigned)vid.width || dc->yl < 0 || dc->yh >= vid.height) + if ((unsigned)dc->x >= (unsigned)vidwidth || dc->yl < 0 || dc->yh >= vid.height) return; // Framebuffer destination address. // Use ylookup LUT to avoid multiply with ScreenWidth. // Use columnofs LUT for subwindows? //dest = ylookup[dc_yl] + columnofs[dc_x]; - dest = &topleft[dc->yl*vid.width + dc->x]; + dest = &topleft[dc->yl*vidwidth + dc->x]; // Determine scaling, which is the only mapping to be done. do { // Simple. Apply the colormap to what's already on the screen. *dest = dc->colormap[*dest]; - dest += vid.width; + dest += vidwidth; } while (count--); } @@ -386,21 +388,22 @@ void R_DrawDropShadowColumn(drawcolumndata_t *dc) INT32 count; UINT8 *dest; + const INT32 vidwidth = vid.width; count = dc->yh - dc->yl + 1; if (count <= 0) // Zero length, column does not exceed a pixel. return; - dest = &topleft[dc->yl*vid.width + dc->x]; + dest = &topleft[dc->yl*vidwidth + dc->x]; const UINT8 *transmap_offset = dc->transmap + (dc->shadowcolor << 8); while ((count -= 2) >= 0) { *dest = *(transmap_offset + (*dest)); - dest += vid.width; + dest += vidwidth; *dest = *(transmap_offset + (*dest)); - dest += vid.width; + dest += vidwidth; } if (count & 1) @@ -414,13 +417,14 @@ void R_DrawColumn_Flat(drawcolumndata_t *dc) INT32 count; UINT8 color = dc->lightmap[dc->r8_flatcolor]; UINT8 *dest; + const INT32 vidwidth = vid.width; count = dc->yh - dc->yl; if (count < 0) // Zero length, column does not exceed a pixel. return; - if ((unsigned)dc->x >= (unsigned)vid.width || dc->yl < 0 || dc->yh >= vid.height) + if ((unsigned)dc->x >= (unsigned)vidwidth || dc->yl < 0 || dc->yh >= vid.height) return; // Framebuffer destination address. @@ -428,14 +432,14 @@ void R_DrawColumn_Flat(drawcolumndata_t *dc) // Use columnofs LUT for subwindows? //dest = ylookup[dc_yl] + columnofs[dc_x]; - dest = &topleft[dc->yl*vid.width + dc->x]; + dest = &topleft[dc->yl*vidwidth + dc->x]; count++; do { *dest = color; - dest += vid.width; + dest += vidwidth; } while (--count); } diff --git a/src/r_draw_span.cpp b/src/r_draw_span.cpp index 70e62c487..77d707be3 100644 --- a/src/r_draw_span.cpp +++ b/src/r_draw_span.cpp @@ -25,7 +25,7 @@ using namespace libdivide; // 4194303 = (2048x2048)-1 (2048x2048 is maximum flat size) #define MAXFLATBYTES 4194303 -#define PLANELIGHTFLOAT (BASEVIDWIDTH * BASEVIDWIDTH / vid.width / ds->zeroheight / 21.0f * FIXED_TO_FLOAT(fovtan[viewssnum])) +#define PLANELIGHTFLOAT (BASEVIDWIDTH * BASEVIDWIDTH / vidwidth / ds->zeroheight / 21.0f * FIXED_TO_FLOAT(fovtan[viewssnum])) enum DrawSpanType { @@ -147,6 +147,7 @@ static void R_DrawSpanTemplate(drawspandata_t* ds) UINT8 *dest; UINT8 *dsrc; + const INT32 vidwidth = vid.width; const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; @@ -174,7 +175,7 @@ static void R_DrawSpanTemplate(drawspandata_t* ds) dest = ylookup[ds->y] + columnofs[ds->x1]; if constexpr (Type & DS_RIPPLE) { - dsrc = screens[1] + (ds->y + ds->bgofs) * vid.width + ds->x1; + dsrc = screens[1] + (ds->y + ds->bgofs) * vidwidth + ds->x1; } else { @@ -262,6 +263,7 @@ static void R_DrawTiltedSpanTemplate(drawspandata_t* ds) UINT8 *colormap; UINT8 *dest; UINT8 *dsrc; + const INT32 vidwidth = vid.width; float startz, startu, startv; float izstep, uzstep, vzstep; @@ -298,7 +300,7 @@ static void R_DrawTiltedSpanTemplate(drawspandata_t* ds) dest = ylookup[ds->y] + columnofs[ds->x1]; if constexpr (Type & DS_RIPPLE) { - dsrc = screens[1] + (ds->y + ds->bgofs) * vid.width + ds->x1; + dsrc = screens[1] + (ds->y + ds->bgofs) * vidwidth + ds->x1; } else { @@ -437,6 +439,7 @@ static void R_DrawNPO2SpanTemplate(drawspandata_t* ds) UINT8 *dest; UINT8 *dsrc; + const INT32 vidwidth = vid.width; const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; size_t count = (ds->x2 - ds->x1 + 1); @@ -453,7 +456,7 @@ static void R_DrawNPO2SpanTemplate(drawspandata_t* ds) if constexpr (Type & DS_RIPPLE) { - dsrc = screens[1] + (ds->y + ds->bgofs) * vid.width + ds->x1; + dsrc = screens[1] + (ds->y + ds->bgofs) * vidwidth + ds->x1; } else { @@ -521,6 +524,7 @@ static void R_DrawTiltedNPO2SpanTemplate(drawspandata_t* ds) UINT8 *colormap; UINT8 *dest; UINT8 *dsrc; + const INT32 vidwidth = vid.width; float startz, startu, startv; float izstep, uzstep, vzstep; @@ -555,7 +559,7 @@ static void R_DrawTiltedNPO2SpanTemplate(drawspandata_t* ds) if constexpr (Type & DS_RIPPLE) { - dsrc = screens[1] + (ds->y + ds->bgofs) * vid.width + ds->x1; + dsrc = screens[1] + (ds->y + ds->bgofs) * vidwidth + ds->x1; } else { @@ -769,13 +773,14 @@ void R_DrawFogSpan(drawspandata_t* ds) UINT8 *colormap; UINT8 *dest; + const INT32 vidwidth = vid.width; size_t count; colormap = ds->colormap; //dest = ylookup[ds_y] + columnofs[ds_x1]; - dest = &topleft[ds->y *vid.width + ds->x1]; + dest = &topleft[ds->y *vidwidth + ds->x1]; count = ds->x2 - ds->x1 + 1; @@ -807,6 +812,7 @@ void R_DrawFogSpan_Tilted(drawspandata_t* ds) INT32 tiltlighting[MAXVIDWIDTH]; UINT8 *dest = ylookup[ds->y] + columnofs[ds->x1]; + const INT32 vidwidth = vid.width; // Lighting is simple. It's just linear interpolation from start to end { @@ -845,6 +851,7 @@ void R_DrawTiltedSpan_Flat(drawspandata_t* ds) int width = ds->x2 - ds->x1; double iz = ds->szp.z + ds->szp.y*(centery-ds->y) + ds->szp.x*(ds->x1-centerx); INT32 tiltlighting[MAXVIDWIDTH]; + const INT32 vidwidth = vid.width; UINT8 *dest = ylookup[ds->y]; diff --git a/src/screen.c b/src/screen.c index ec1f215ca..a32e01737 100644 --- a/src/screen.c +++ b/src/screen.c @@ -76,11 +76,7 @@ CV_PossibleValue_t cv_renderer_t[] = { {0, NULL} }; -#ifdef HWRENDER -consvar_t cv_renderer = CVAR_INIT ("renderer", "OpenGL", CV_SAVE|CV_NOLUA|CV_CALL, cv_renderer_t, SCR_ChangeRenderer); -#else consvar_t cv_renderer = CVAR_INIT ("renderer", "Software", CV_SAVE|CV_NOLUA|CV_CALL, cv_renderer_t, SCR_ChangeRenderer); -#endif static void SCR_ChangeFullscreen(void); diff --git a/src/sdl/i_system.cpp b/src/sdl/i_system.cpp index ac26f6e20..e34681af6 100644 --- a/src/sdl/i_system.cpp +++ b/src/sdl/i_system.cpp @@ -144,16 +144,32 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); #define UNIXBACKTRACE #endif -// Locations for searching for main.pk3 +const char *wadDefaultPaths[] = { #if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) -#define DEFAULTWADLOCATION1 "/usr/local/share/games/SRB2Kart-V2" -#define DEFAULTWADLOCATION2 "/usr/local/games/SRB2Kart-V2" -#define DEFAULTWADLOCATION3 "/usr/share/games/SRB2Kart-V2" -#define DEFAULTWADLOCATION4 "/usr/games/SRB2Kart-V2" -#define DEFAULTSEARCHPATH1 "/usr/local/games" -#define DEFAULTSEARCHPATH2 "/usr/games" -#define DEFAULTSEARCHPATH3 "/usr/local" + "/usr/local/share/games/SRB2Kart-V2", + "/usr/local/games/SRB2Kart-V2", + "/usr/share/games/SRB2Kart-V2", + "/usr/games/SRB2Kart-V2", +#elif defined (_WIN32) + "c:\\games\\SRB2Kart-V2", + "\\games\\SRB2Kart-V2", #endif + NULL +}; + +// Folders to recurse through looking for main.pk3 +const char *wadSearchPaths[] = { +#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) + "/usr/local/games", + "/usr/games", + "/usr/local", +#elif defined (_WIN32) + "c:\\games", + "\\games", +#endif + NULL +}; + /** \brief WAD file to look for */ @@ -1098,6 +1114,20 @@ INT32 I_GetJoystickDeviceIndex(SDL_GameController *dev) return -1; } +INT32 I_GetJoystickDeviceIndexForPlayer(UINT8 pnum) +{ + SDL_Joystick *joystick = NULL; + + joystick = SDL_GameControllerGetJoystick(JoyInfo[pnum].dev); + + if (joystick) + { + return SDL_JoystickInstanceID(joystick); + } + + return -1; +} + void I_UpdateJoystickDeviceIndex(UINT8 player) { /////////////////////////////////////////////// @@ -2401,15 +2431,29 @@ static const char *searchWad(const char *searchDir) return NULL; } +#define CHECKWADPATH(ret) \ +do { \ + I_OutputMsg(",%s", ret); \ + if (isWadPathOk(ret)) \ + return ret; \ +} while (0) + +#define SEARCHWAD(str) \ +do { \ + WadPath = searchWad(str); \ + if (WadPath) \ + return WadPath; \ +} while (0) + /** \brief go through all possible paths and look for main.pk3 - - \return path to main.pk3 if any - -*/ + * + * \return path to main.pk3 if any + */ static const char *locateWad(void) { const char *envstr; const char *WadPath; + int i; I_OutputMsg("SRB2WADDIR"); // does SRB2WADDIR exist? @@ -2417,108 +2461,46 @@ static const char *locateWad(void) return envstr; #ifndef NOCWD - I_OutputMsg(",."); // examine current dir strcpy(returnWadPath, "."); + I_OutputMsg(",%s", returnWadPath); if (isWadPathOk(returnWadPath)) return NULL; #endif - -#ifdef DEFAULTDIR - I_OutputMsg(",HOME/" DEFAULTDIR); - // examine user jart directory - if ((envstr = I_GetEnv("HOME")) != NULL) - { - sprintf(returnWadPath, "%s" PATHSEP DEFAULTDIR, envstr); - if (isWadPathOk(returnWadPath)) - return returnWadPath; - } -#endif - #ifdef __APPLE__ OSX_GetResourcesPath(returnWadPath); - I_OutputMsg(",%s", returnWadPath); - if (isWadPathOk(returnWadPath)) - { - return returnWadPath; - } + CHECKWADPATH(returnWadPath); #endif // examine default dirs -#ifdef DEFAULTWADLOCATION1 - I_OutputMsg("," DEFAULTWADLOCATION1); - strcpy(returnWadPath, DEFAULTWADLOCATION1); - if (isWadPathOk(returnWadPath)) - return returnWadPath; -#endif -#ifdef DEFAULTWADLOCATION2 - I_OutputMsg("," DEFAULTWADLOCATION2); - strcpy(returnWadPath, DEFAULTWADLOCATION2); - if (isWadPathOk(returnWadPath)) - return returnWadPath; -#endif -#ifdef DEFAULTWADLOCATION3 - I_OutputMsg("," DEFAULTWADLOCATION3); - strcpy(returnWadPath, DEFAULTWADLOCATION3); - if (isWadPathOk(returnWadPath)) - return returnWadPath; -#endif -#ifdef DEFAULTWADLOCATION4 - I_OutputMsg("," DEFAULTWADLOCATION4); - strcpy(returnWadPath, DEFAULTWADLOCATION4); - if (isWadPathOk(returnWadPath)) - return returnWadPath; -#endif -#ifdef DEFAULTWADLOCATION5 - I_OutputMsg("," DEFAULTWADLOCATION5); - strcpy(returnWadPath, DEFAULTWADLOCATION5); - if (isWadPathOk(returnWadPath)) - return returnWadPath; -#endif -#ifdef DEFAULTWADLOCATION6 - I_OutputMsg("," DEFAULTWADLOCATION6); - strcpy(returnWadPath, DEFAULTWADLOCATION6); - if (isWadPathOk(returnWadPath)) - return returnWadPath; -#endif -#ifdef DEFAULTWADLOCATION7 - I_OutputMsg("," DEFAULTWADLOCATION7); - strcpy(returnWadPath, DEFAULTWADLOCATION7); - if (isWadPathOk(returnWadPath)) - return returnWadPath; -#endif + for (i = 0; wadDefaultPaths[i]; i++) + { + strcpy(returnWadPath, wadDefaultPaths[i]); + CHECKWADPATH(returnWadPath); + } + #ifndef NOHOME // find in $HOME - I_OutputMsg(",HOME"); + I_OutputMsg(",HOME/" DEFAULTDIR); if ((envstr = I_GetEnv("HOME")) != NULL) { - WadPath = searchWad(envstr); - if (WadPath) - return WadPath; + char *tmp = static_cast(malloc(strlen(envstr) + sizeof(PATHSEP) + sizeof(DEFAULTDIR))); + strcpy(tmp, envstr); + strcat(tmp, PATHSEP); + strcat(tmp, DEFAULTDIR); + CHECKWADPATH(tmp); + free(tmp); } -#endif -#ifdef DEFAULTSEARCHPATH1 - // find in /usr/local - I_OutputMsg(", in:" DEFAULTSEARCHPATH1); - WadPath = searchWad(DEFAULTSEARCHPATH1); - if (WadPath) - return WadPath; -#endif -#ifdef DEFAULTSEARCHPATH2 - // find in /usr/games - I_OutputMsg(", in:" DEFAULTSEARCHPATH2); - WadPath = searchWad(DEFAULTSEARCHPATH2); - if (WadPath) - return WadPath; -#endif -#ifdef DEFAULTSEARCHPATH3 - // find in ??? - I_OutputMsg(", in:" DEFAULTSEARCHPATH3); - WadPath = searchWad(DEFAULTSEARCHPATH3); - if (WadPath) - return WadPath; -#endif + #endif + + // search paths + for (i = 0; wadSearchPaths[i]; i++) + { + I_OutputMsg(", in:%s", wadSearchPaths[i]); + SEARCHWAD(wadSearchPaths[i]); + } + // if nothing was found return NULL; } @@ -2535,8 +2517,10 @@ const char *I_LocateWad(void) { // change to the directory where we found main.pk3 #if defined (_WIN32) + waddir = _fullpath(NULL, waddir, MAX_PATH); SetCurrentDirectoryA(waddir); #else + waddir = realpath(waddir, NULL); if (chdir(waddir) == -1) I_OutputMsg("Couldn't change working directory\n"); #endif diff --git a/src/sdl/i_video.cpp b/src/sdl/i_video.cpp index 82289c8e8..4f80e2be5 100644 --- a/src/sdl/i_video.cpp +++ b/src/sdl/i_video.cpp @@ -682,7 +682,7 @@ static INT32 SDLJoyAxis(const Sint16 axis, UINT8 pid) } else { - raxis = (JoyInfo[pid].scale != 1) ? ((raxis / JoyInfo[pid].scale) * JoyInfo[pid].scale) : raxis; + raxis = (abs(JoyInfo[pid].scale) > 1) ? ((raxis / JoyInfo[pid].scale) * JoyInfo[pid].scale) : raxis; #ifdef SDL_JDEADZONE if (-SDL_JDEADZONE <= raxis && raxis <= SDL_JDEADZONE) diff --git a/src/v_video.c b/src/v_video.c index 4d99d39c0..02b77d730 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -714,27 +714,15 @@ static UINT8 hudminusalpha[11] = { 10, 9, 9, 8, 8, 7, 7, 6, 6, 5, 5}; static const UINT8 *v_colormap = NULL; static const UINT8 *v_translevel = NULL; -static inline UINT8 standardpdraw(const UINT8 *dest, const UINT8 *source, fixed_t ofs) -{ - (void)dest; return source[ofs>>FRACBITS]; -} -static inline UINT8 mappedpdraw(const UINT8 *dest, const UINT8 *source, fixed_t ofs) -{ - (void)dest; return *(v_colormap + source[ofs>>FRACBITS]); -} -static inline UINT8 translucentpdraw(const UINT8 *dest, const UINT8 *source, fixed_t ofs) -{ - return *(v_translevel + ((source[ofs>>FRACBITS]<<8)&0xff00) + (*dest&0xff)); -} -static inline UINT8 transmappedpdraw(const UINT8 *dest, const UINT8 *source, fixed_t ofs) -{ - return *(v_translevel + (((*(v_colormap + source[ofs>>FRACBITS]))<<8)&0xff00) + (*dest&0xff)); -} +#define STANDARDDRAW 1 +#define MAPPEDDRAW 2 +#define TRANSLUCENTDRAW 3 +#define TRANSMAPPEDDRAW 4 // Draws a patch scaled to arbitrary size. void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 scrn, patch_t *patch, const UINT8 *colormap) { - UINT8 (*patchdrawfunc)(const UINT8*, const UINT8*, fixed_t); + UINT8 patchdrawtype; UINT32 alphalevel, blendmode; fixed_t col, ofs, colfrac, rowfrac, fdup, vdup; @@ -744,6 +732,7 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca const UINT8 *source, *deststop; fixed_t pwidth; // patch width fixed_t offx = 0; // x offset + const INT32 vidwidth = vid.width; const cliprect_t *clip = V_GetClipRect(); @@ -759,7 +748,7 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca } #endif - patchdrawfunc = standardpdraw; + patchdrawtype = STANDARDDRAW; if ((blendmode = ((scrn & V_BLENDMASK) >> V_BLENDSHIFT))) blendmode++; // realign to constants @@ -776,13 +765,13 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca return; } if ((v_translevel = R_GetBlendTable(blendmode, alphalevel))) - patchdrawfunc = translucentpdraw; + patchdrawtype = TRANSLUCENTDRAW; v_colormap = NULL; if (colormap) { v_colormap = colormap; - patchdrawfunc = (v_translevel) ? transmappedpdraw : mappedpdraw; + patchdrawtype = (v_translevel) ? TRANSMAPPEDDRAW : MAPPEDDRAW; } dupx = vid.dupx; @@ -858,7 +847,7 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca V_AdjustXYWithSnap(&x, &y, scrn, dupx, dupy); } - desttop += (y*vid.width) + x; + desttop += (y*vidwidth) + x; } if (pscale != FRACUNIT) // scale width properly @@ -882,91 +871,324 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca { if (x+pwidth-offx < (clip ? clip->left : 0)) // don't draw off the left of the screen (WRAP PREVENTION) break; - if (x+pwidth-offx >= (clip ? clip->right : vid.width)) // don't draw off the right of the screen (WRAP PREVENTION) + if (x+pwidth-offx >= (clip ? clip->right : vidwidth)) // don't draw off the right of the screen (WRAP PREVENTION) continue; } else { if (x+offx < (clip ? clip->left : 0)) // don't draw off the left of the screen (WRAP PREVENTION) continue; - if (x+offx >= (clip ? clip->right : vid.width)) // don't draw off the right of the screen (WRAP PREVENTION) + if (x+offx >= (clip ? clip->right : vidwidth)) // don't draw off the right of the screen (WRAP PREVENTION) break; } column = (const column_t *)((const UINT8 *)(patch->columns) + (patch->columnofs[col>>FRACBITS])); - while (column->topdelta != 0xff) + switch (patchdrawtype) { - fixed_t offy = 0; - - topdelta = column->topdelta; - if (topdelta <= prevdelta) - topdelta += prevdelta; - prevdelta = topdelta; - source = (const UINT8 *)(column) + 3; - - dest = desttop; - if (scrn & V_FLIP) - dest = deststart + (destend - dest); - topdelta = FixedInt(FixedMul(topdelta << FRACBITS, vdup)); - dest += topdelta * vid.width; - - if (scrn & V_VFLIP) - { - for (ofs = (column->length << FRACBITS)-1; dest < deststop && ofs >= 0; ofs -= rowfrac, ++offy) + case STANDARDDRAW: + while (column->topdelta != 0xff) { - if (clip != NULL) + fixed_t offy = 0; + + topdelta = column->topdelta; + if (topdelta <= prevdelta) + topdelta += prevdelta; + prevdelta = topdelta; + source = (const UINT8 *)(column) + 3; + + dest = desttop; + if (scrn & V_FLIP) + dest = deststart + (destend - dest); + topdelta = FixedInt(FixedMul(topdelta << FRACBITS, vdup)); + dest += topdelta * vidwidth; + + if (scrn & V_VFLIP) { - const INT32 cy = y + topdelta - offy; - - if (cy < clip->top) // don't draw off the top of the clip rect + for (ofs = (column->length << FRACBITS)-1; dest < deststop && ofs >= 0; ofs -= rowfrac, ++offy) { - dest += vid.width; - continue; + if (clip != NULL) + { + const INT32 cy = y + topdelta - offy; + + if (cy < clip->top) // don't draw off the top of the clip rect + { + dest += vidwidth; + continue; + } + + if (cy >= clip->bottom) // don't draw off the bottom of the clip rect + { + dest += vidwidth; + continue; + } + } + + if (dest >= screens[scrn&V_SCREENMASK]) // don't draw off the top of the screen (CRASH PREVENTION) + *dest = source[ofs>>FRACBITS]; + + dest += vidwidth; } - - if (cy >= clip->bottom) // don't draw off the bottom of the clip rect + } + else + { + for (ofs = 0; dest < deststop && ofs < (column->length << FRACBITS); ofs += rowfrac, ++offy) { - dest += vid.width; - continue; + if (clip != NULL) + { + const INT32 cy = y + topdelta + offy; + + if (cy < clip->top) // don't draw off the top of the clip rect + { + dest += vidwidth; + continue; + } + + if (cy >= clip->bottom) // don't draw off the bottom of the clip rect + { + dest += vidwidth; + continue; + } + } + + if (dest >= screens[scrn&V_SCREENMASK]) // don't draw off the top of the screen (CRASH PREVENTION) + *dest = source[ofs>>FRACBITS]; + + dest += vidwidth; } } - if (dest >= screens[scrn&V_SCREENMASK]) // don't draw off the top of the screen (CRASH PREVENTION) - *dest = patchdrawfunc(dest, source, ofs); - - dest += vid.width; + column = (const column_t *)((const UINT8 *)column + column->length + 4); } - } - else - { - for (ofs = 0; dest < deststop && ofs < (column->length << FRACBITS); ofs += rowfrac, ++offy) + break; + + case MAPPEDDRAW: + while (column->topdelta != 0xff) { - if (clip != NULL) + fixed_t offy = 0; + + topdelta = column->topdelta; + if (topdelta <= prevdelta) + topdelta += prevdelta; + prevdelta = topdelta; + source = (const UINT8 *)(column) + 3; + + dest = desttop; + if (scrn & V_FLIP) + dest = deststart + (destend - dest); + topdelta = FixedInt(FixedMul(topdelta << FRACBITS, vdup)); + dest += topdelta * vidwidth; + + if (scrn & V_VFLIP) { - const INT32 cy = y + topdelta + offy; - - if (cy < clip->top) // don't draw off the top of the clip rect + for (ofs = (column->length << FRACBITS)-1; dest < deststop && ofs >= 0; ofs -= rowfrac, ++offy) { - dest += vid.width; - continue; + if (clip != NULL) + { + const INT32 cy = y + topdelta - offy; + + if (cy < clip->top) // don't draw off the top of the clip rect + { + dest += vidwidth; + continue; + } + + if (cy >= clip->bottom) // don't draw off the bottom of the clip rect + { + dest += vidwidth; + continue; + } + } + + if (dest >= screens[scrn&V_SCREENMASK]) // don't draw off the top of the screen (CRASH PREVENTION) + *dest = *(v_colormap + source[ofs>>FRACBITS]); + + dest += vidwidth; } - - if (cy >= clip->bottom) // don't draw off the bottom of the clip rect + } + else + { + for (ofs = 0; dest < deststop && ofs < (column->length << FRACBITS); ofs += rowfrac, ++offy) { - dest += vid.width; - continue; + if (clip != NULL) + { + const INT32 cy = y + topdelta + offy; + + if (cy < clip->top) // don't draw off the top of the clip rect + { + dest += vidwidth; + continue; + } + + if (cy >= clip->bottom) // don't draw off the bottom of the clip rect + { + dest += vidwidth; + continue; + } + } + + if (dest >= screens[scrn&V_SCREENMASK]) // don't draw off the top of the screen (CRASH PREVENTION) + *dest = *(v_colormap + source[ofs>>FRACBITS]); + + dest += vidwidth; } } - if (dest >= screens[scrn&V_SCREENMASK]) // don't draw off the top of the screen (CRASH PREVENTION) - *dest = patchdrawfunc(dest, source, ofs); - - dest += vid.width; + column = (const column_t *)((const UINT8 *)column + column->length + 4); } - } + break; - column = (const column_t *)((const UINT8 *)column + column->length + 4); + case TRANSMAPPEDDRAW: + while (column->topdelta != 0xff) + { + fixed_t offy = 0; + + topdelta = column->topdelta; + if (topdelta <= prevdelta) + topdelta += prevdelta; + prevdelta = topdelta; + source = (const UINT8 *)(column) + 3; + + dest = desttop; + if (scrn & V_FLIP) + dest = deststart + (destend - dest); + topdelta = FixedInt(FixedMul(topdelta << FRACBITS, vdup)); + dest += topdelta * vidwidth; + + if (scrn & V_VFLIP) + { + for (ofs = (column->length << FRACBITS)-1; dest < deststop && ofs >= 0; ofs -= rowfrac, ++offy) + { + if (clip != NULL) + { + const INT32 cy = y + topdelta - offy; + + if (cy < clip->top) // don't draw off the top of the clip rect + { + dest += vidwidth; + continue; + } + + if (cy >= clip->bottom) // don't draw off the bottom of the clip rect + { + dest += vidwidth; + continue; + } + } + + if (dest >= screens[scrn&V_SCREENMASK]) // don't draw off the top of the screen (CRASH PREVENTION) + *dest = *(v_translevel + (((*(v_colormap + source[ofs>>FRACBITS]))<<8)&0xff00) + (*dest&0xff)); + + dest += vidwidth; + } + } + else + { + for (ofs = 0; dest < deststop && ofs < (column->length << FRACBITS); ofs += rowfrac, ++offy) + { + if (clip != NULL) + { + const INT32 cy = y + topdelta + offy; + + if (cy < clip->top) // don't draw off the top of the clip rect + { + dest += vidwidth; + continue; + } + + if (cy >= clip->bottom) // don't draw off the bottom of the clip rect + { + dest += vidwidth; + continue; + } + } + + if (dest >= screens[scrn&V_SCREENMASK]) // don't draw off the top of the screen (CRASH PREVENTION) + *dest = *(v_translevel + (((*(v_colormap + source[ofs>>FRACBITS]))<<8)&0xff00) + (*dest&0xff)); + + dest += vidwidth; + } + } + + column = (const column_t *)((const UINT8 *)column + column->length + 4); + } + break; + + case TRANSLUCENTDRAW: + while (column->topdelta != 0xff) + { + fixed_t offy = 0; + + topdelta = column->topdelta; + if (topdelta <= prevdelta) + topdelta += prevdelta; + prevdelta = topdelta; + source = (const UINT8 *)(column) + 3; + + dest = desttop; + if (scrn & V_FLIP) + dest = deststart + (destend - dest); + topdelta = FixedInt(FixedMul(topdelta << FRACBITS, vdup)); + dest += topdelta * vidwidth; + + if (scrn & V_VFLIP) + { + for (ofs = (column->length << FRACBITS)-1; dest < deststop && ofs >= 0; ofs -= rowfrac, ++offy) + { + if (clip != NULL) + { + const INT32 cy = y + topdelta - offy; + + if (cy < clip->top) // don't draw off the top of the clip rect + { + dest += vidwidth; + continue; + } + + if (cy >= clip->bottom) // don't draw off the bottom of the clip rect + { + dest += vidwidth; + continue; + } + } + + if (dest >= screens[scrn&V_SCREENMASK]) // don't draw off the top of the screen (CRASH PREVENTION) + *dest = *(v_translevel + ((source[ofs>>FRACBITS]<<8)&0xff00) + (*dest&0xff)); + + dest += vidwidth; + } + } + else + { + for (ofs = 0; dest < deststop && ofs < (column->length << FRACBITS); ofs += rowfrac, ++offy) + { + if (clip != NULL) + { + const INT32 cy = y + topdelta + offy; + + if (cy < clip->top) // don't draw off the top of the clip rect + { + dest += vidwidth; + continue; + } + + if (cy >= clip->bottom) // don't draw off the bottom of the clip rect + { + dest += vidwidth; + continue; + } + } + + if (dest >= screens[scrn&V_SCREENMASK]) // don't draw off the top of the screen (CRASH PREVENTION) + *dest = *(v_translevel + ((source[ofs>>FRACBITS]<<8)&0xff00) + (*dest&0xff)); + + dest += vidwidth; + } + } + + column = (const column_t *)((const UINT8 *)column + column->length + 4); + } + break; } } }