diff --git a/src/d_clisrv.h b/src/d_clisrv.h index a906758f..dd1aaf4e 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -429,9 +429,9 @@ extern doomdata_t *netbuffer; extern consvar_t cv_playbackspeed; -#define BASEPACKETSIZE ((size_t)&(((doomdata_t *)0)->u)) -#define FILETXHEADER ((size_t)((filetx_pak *)0)->data) -#define BASESERVERTICSSIZE ((size_t)&(((doomdata_t *)0)->u.serverpak.cmds[0])) +#define BASEPACKETSIZE offsetof(doomdata_t, u) +#define FILETXHEADER offsetof(filetx_pak, data) +#define BASESERVERTICSSIZE offsetof(doomdata_t, u.serverpak.cmds[0]) #define KICK_MSG_GO_AWAY 1 #define KICK_MSG_CON_FAIL 2 diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 2e2a2d2a..9adba8e7 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -697,6 +697,10 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_moveaxis2); CV_RegisterVar(&cv_lookaxis); CV_RegisterVar(&cv_lookaxis2); + CV_RegisterVar(&cv_jumpaxis); + CV_RegisterVar(&cv_jumpaxis2); + CV_RegisterVar(&cv_spinaxis); + CV_RegisterVar(&cv_spinaxis2); CV_RegisterVar(&cv_fireaxis); CV_RegisterVar(&cv_fireaxis2); CV_RegisterVar(&cv_firenaxis); diff --git a/src/dehacked.c b/src/dehacked.c index 333c6ceb..3972cd17 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1248,6 +1248,18 @@ static void readlevelheader(MYFILE *f, INT32 num) deh_warning("Level header %d: invalid bonus type number %d", num, i); } + else if (fastcmp(word, "SAVEOVERRIDE")) + { + if (fastcmp(word2, "DEFAULT")) i = SAVE_DEFAULT; + else if (fastcmp(word2, "ALWAYS")) i = SAVE_ALWAYS; + else if (fastcmp(word2, "NEVER")) i = SAVE_NEVER; + + if (i >= SAVE_NEVER && i <= SAVE_ALWAYS) + mapheaderinfo[num-1]->saveoverride = (SINT8)i; + else + deh_warning("Level header %d: invalid save override number %d", num, i); + } + else if (fastcmp(word, "LEVELFLAGS")) mapheaderinfo[num-1]->levelflags = (UINT8)i; else if (fastcmp(word, "MENUFLAGS")) @@ -7074,6 +7086,11 @@ struct { {"LF2_NIGHTSATTACK",LF2_NIGHTSATTACK}, {"LF2_NOVISITNEEDED",LF2_NOVISITNEEDED}, + // Save override + {"SAVE_NEVER",SAVE_NEVER}, + {"SAVE_DEFAULT",SAVE_DEFAULT}, + {"SAVE_ALWAYS",SAVE_ALWAYS}, + // NiGHTS grades {"GRADE_F",GRADE_F}, {"GRADE_E",GRADE_E}, diff --git a/src/doomstat.h b/src/doomstat.h index 7b4aa264..d37ae440 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -234,6 +234,7 @@ typedef struct SINT8 unlockrequired; ///< Is an unlockable required to play this level? -1 if no. UINT8 levelselect; ///< Is this map available in the level select? If so, which map list is it available in? SINT8 bonustype; ///< What type of bonus does this level have? (-1 for null.) + SINT8 saveoverride; ///< Set how the game is allowed to save (1 for always, -1 for never, 0 is 2.1 default) UINT8 levelflags; ///< LF_flags: merged eight booleans into one UINT8 for space, see below UINT8 menuflags; ///< LF2_flags: options that affect record attack / nights mode menus @@ -261,6 +262,11 @@ typedef struct #define LF2_NIGHTSATTACK 8 ///< Show this map in NiGHTS mode menu #define LF2_NOVISITNEEDED 16 ///< Available in time attack/nights mode without visiting the level +// Save override +#define SAVE_NEVER -1 +#define SAVE_DEFAULT 0 +#define SAVE_ALWAYS 1 + extern mapheader_t* mapheaderinfo[NUMMAPS]; enum TypeOfLevel diff --git a/src/f_finale.c b/src/f_finale.c index 484a0afe..fa6d6dba 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1082,11 +1082,14 @@ static const char *credits[] = { "Bill \"Tets\" Reed", "", "\1Special Thanks", - "Doom Legacy Project", "iD Software", - "Alex \"MistaED\" Fuller", + "Doom Legacy Project", "FreeDoom Project", // Used some of the mancubus and rocket launcher sprites for Brak + "Alex \"MistaED\" Fuller", + "Pascal \"CodeImp\" vd Heiden", // Doom Builder developer "Randi Heit ()", // For their MSPaint sprite that we nicked + "Simon \"sirjuddington\" Judd", // SLADE developer + "", "\1Produced By", "Sonic Team Junior", diff --git a/src/g_game.c b/src/g_game.c index 2f2ac043..93e7c15a 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -406,6 +406,8 @@ typedef enum AXISLOOK, AXISSTRAFE, AXISDEAD, //Axises that don't want deadzones + AXISJUMP, + AXISSPIN, AXISFIRE, AXISFIRENORMAL, } axis_input_e; @@ -415,6 +417,8 @@ consvar_t cv_turnaxis = {"joyaxis_turn", "LStick.X", CV_SAVE, joyaxis_cons_t, NU consvar_t cv_moveaxis = {"joyaxis_move", "LStick.Y", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_sideaxis = {"joyaxis_side", "RStick.X", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_lookaxis = {"joyaxis_look", "RStick.Y", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_jumpaxis = {"joyaxis_jump", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_spinaxis = {"joyaxis_spin", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_fireaxis = {"joyaxis_fire", "LAnalog", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_firenaxis = {"joyaxis_firenormal", "RAnalog", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; #else @@ -441,6 +445,8 @@ consvar_t cv_lookaxis = {"joyaxis_look", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL consvar_t cv_lookaxis = {"joyaxis_look", "Y-Rudder-", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; #endif #endif +consvar_t cv_jumpaxis = {"joyaxis_jump", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_spinaxis = {"joyaxis_spin", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_fireaxis = {"joyaxis_fire", "Z-Axis-", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_firenaxis = {"joyaxis_firenormal", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; #endif @@ -450,6 +456,8 @@ consvar_t cv_turnaxis2 = {"joyaxis2_turn", "LStick.X", CV_SAVE, joyaxis_cons_t, consvar_t cv_moveaxis2 = {"joyaxis2_move", "LStick.Y", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_sideaxis2 = {"joyaxis2_side", "RStick.X", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_lookaxis2 = {"joyaxis2_look", "RStick.Y", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_jumpaxis2 = {"joyaxis2_jump", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_spinaxis2 = {"joyaxis2_spin", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_fireaxis2 = {"joyaxis2_fire", "LAnalog", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_firenaxis2 = {"joyaxis2_firenormal", "RAnalog", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; #else @@ -468,6 +476,8 @@ consvar_t cv_sideaxis2 = {"joyaxis2_side", "X-Axis", CV_SAVE, joyaxis_cons_t, NU #ifndef _XBOX consvar_t cv_lookaxis2 = {"joyaxis2_look", "Y-Rudder-", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; #endif +consvar_t cv_jumpaxis2 = {"joyaxis2_jump", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_spinaxis2 = {"joyaxis2_spin", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_fireaxis2 = {"joyaxis2_fire", "Z-Axis-", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_firenaxis2 = {"joyaxis2_firenormal", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; #endif @@ -835,6 +845,12 @@ static INT32 JoyAxis(axis_input_e axissel) case AXISSTRAFE: axisval = cv_sideaxis.value; break; + case AXISJUMP: + axisval = cv_jumpaxis.value; + break; + case AXISSPIN: + axisval = cv_spinaxis.value; + break; case AXISFIRE: axisval = cv_fireaxis.value; break; @@ -912,6 +928,12 @@ static INT32 Joy2Axis(axis_input_e axissel) case AXISSTRAFE: axisval = cv_sideaxis2.value; break; + case AXISJUMP: + axisval = cv_jumpaxis2.value; + break; + case AXISSPIN: + axisval = cv_spinaxis2.value; + break; case AXISFIRE: axisval = cv_fireaxis2.value; break; @@ -1157,7 +1179,8 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) cmd->buttons |= BT_CUSTOM3; // use with any button/key - if (PLAYER1INPUTDOWN(gc_use)) + axis = JoyAxis(AXISSPIN); + if (PLAYER1INPUTDOWN(gc_use) || (cv_usejoystick.value && axis > 0)) cmd->buttons |= BT_USE; // Camera Controls @@ -1179,7 +1202,8 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) resetdown = false; // jump button - if (PLAYER1INPUTDOWN(gc_jump)) + axis = JoyAxis(AXISJUMP); + if (PLAYER1INPUTDOWN(gc_jump) || (cv_usejoystick.value && axis > 0)) cmd->buttons |= BT_JUMP; // player aiming shit, ahhhh... @@ -1454,7 +1478,8 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics) cmd->buttons |= BT_CUSTOM3; // use with any button/key - if (PLAYER2INPUTDOWN(gc_use)) + axis = Joy2Axis(AXISSPIN); + if (PLAYER2INPUTDOWN(gc_use) || (cv_usejoystick2.value && axis > 0)) cmd->buttons |= BT_USE; // Camera Controls @@ -1476,7 +1501,8 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics) resetdown = false; // jump button - if (PLAYER2INPUTDOWN(gc_jump)) + axis = Joy2Axis(AXISJUMP); + if (PLAYER2INPUTDOWN(gc_jump) || (cv_usejoystick2.value && axis > 0)) cmd->buttons |= BT_JUMP; // player aiming shit, ahhhh... @@ -1616,11 +1642,6 @@ static void Analog_OnChange(void) // cameras are not initialized at this point - if (leveltime > 1) - CV_SetValue(&cv_cam_dist, 128); - if (cv_analog.value || demoplayback) - CV_SetValue(&cv_cam_dist, 192); - if (!cv_chasecam.value && cv_analog.value) { CV_SetValue(&cv_analog, 0); return; @@ -1636,11 +1657,6 @@ static void Analog2_OnChange(void) // cameras are not initialized at this point - if (leveltime > 1) - CV_SetValue(&cv_cam2_dist, 128); - if (cv_analog2.value) - CV_SetValue(&cv_cam2_dist, 192); - if (!cv_chasecam2.value && cv_analog2.value) { CV_SetValue(&cv_analog2, 0); return; diff --git a/src/g_game.h b/src/g_game.h index 46a5bbb3..5259eacb 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -60,8 +60,8 @@ extern consvar_t cv_invertmouse, cv_alwaysfreelook, cv_chasefreelook, cv_mousemo extern consvar_t cv_invertmouse2, cv_alwaysfreelook2, cv_chasefreelook2, cv_mousemove2; extern consvar_t cv_useranalog, cv_useranalog2; extern consvar_t cv_analog, cv_analog2; -extern consvar_t cv_sideaxis,cv_turnaxis,cv_moveaxis,cv_lookaxis,cv_fireaxis,cv_firenaxis; -extern consvar_t cv_sideaxis2,cv_turnaxis2,cv_moveaxis2,cv_lookaxis2,cv_fireaxis2,cv_firenaxis2; +extern consvar_t cv_sideaxis,cv_turnaxis,cv_moveaxis,cv_lookaxis,cv_jumpaxis,cv_spinaxis,cv_fireaxis,cv_firenaxis; +extern consvar_t cv_sideaxis2,cv_turnaxis2,cv_moveaxis2,cv_lookaxis2,cv_jumpaxis2,cv_spinaxis2,cv_fireaxis2,cv_firenaxis2; extern consvar_t cv_ghost_bestscore, cv_ghost_besttime, cv_ghost_bestrings, cv_ghost_last, cv_ghost_guest; // mouseaiming (looking up/down with the mouse or keyboard) diff --git a/src/g_input.c b/src/g_input.c index 44d9f2b2..95664e2d 100644 --- a/src/g_input.c +++ b/src/g_input.c @@ -1165,7 +1165,9 @@ void G_Controldefault(void) gamecontrol[gc_turnleft ][0] = KEY_LEFTARROW; gamecontrol[gc_turnright ][0] = KEY_RIGHTARROW; gamecontrol[gc_weaponnext ][0] = 'e'; + gamecontrol[gc_weaponnext ][1] = KEY_JOY1+1; // B gamecontrol[gc_weaponprev ][0] = 'q'; + gamecontrol[gc_weaponprev ][1] = KEY_JOY1+2; // X gamecontrol[gc_wepslot1 ][0] = '1'; gamecontrol[gc_wepslot2 ][0] = '2'; gamecontrol[gc_wepslot3 ][0] = '3'; @@ -1180,24 +1182,45 @@ void G_Controldefault(void) gamecontrol[gc_fire ][1] = KEY_MOUSE1+0; gamecontrol[gc_firenormal ][0] = 'c'; gamecontrol[gc_tossflag ][0] = '\''; + gamecontrol[gc_tossflag ][1] = KEY_JOY1+0; // A gamecontrol[gc_use ][0] = KEY_LSHIFT; + gamecontrol[gc_use ][1] = KEY_JOY1+4; // LB gamecontrol[gc_camtoggle ][0] = 'v'; + gamecontrol[gc_camtoggle ][1] = KEY_HAT1+0; // D-Pad Up gamecontrol[gc_camleft ][0] = '['; gamecontrol[gc_camright ][0] = ']'; gamecontrol[gc_camreset ][0] = 'r'; + gamecontrol[gc_camreset ][1] = KEY_JOY1+3; // Y gamecontrol[gc_lookup ][0] = KEY_UPARROW; gamecontrol[gc_lookdown ][0] = KEY_DOWNARROW; gamecontrol[gc_centerview ][0] = KEY_END; gamecontrol[gc_talkkey ][0] = 't'; + gamecontrol[gc_talkkey ][1] = KEY_HAT1+2; // D-Pad Left gamecontrol[gc_teamkey ][0] = 'y'; gamecontrol[gc_scores ][0] = KEY_TAB; + gamecontrol[gc_scores ][1] = KEY_HAT1+3; // D-Pad Right gamecontrol[gc_jump ][0] = KEY_SPACE; + gamecontrol[gc_jump ][1] = KEY_JOY1+5; // RB gamecontrol[gc_console ][0] = KEY_CONSOLE; gamecontrol[gc_pause ][0] = 'p'; + gamecontrol[gc_pause ][1] = KEY_JOY1+6; // Back gamecontrol[gc_screenshot ][0] = KEY_F8; + gamecontrol[gc_screenshot ][1] = KEY_HAT1+1; // D-Pad Down gamecontrol[gc_recordgif ][0] = KEY_F9; gamecontrol[gc_viewpoint ][0] = KEY_F12; gamecontrol[gc_systemmenu ][0] = KEY_JOY1+7; // Start + gamecontrolbis[gc_weaponnext][0] = KEY_2JOY1+1; // B + gamecontrolbis[gc_weaponprev][0] = KEY_2JOY1+2; // X + gamecontrolbis[gc_tossflag ][0] = KEY_2JOY1+0; // A + gamecontrolbis[gc_use ][0] = KEY_2JOY1+4; // LB + gamecontrolbis[gc_camreset ][0] = KEY_2JOY1+3; // Y + gamecontrolbis[gc_jump ][0] = KEY_2JOY1+5; // RB + //gamecontrolbis[gc_pause ][0] = KEY_2JOY1+6; // Back + //gamecontrolbis[gc_systemmenu][0] = KEY_2JOY1+7; // Start + gamecontrolbis[gc_camtoggle ][0] = KEY_2HAT1+0; // D-Pad Up + gamecontrolbis[gc_screenshot][0] = KEY_2HAT1+1; // D-Pad Down + //gamecontrolbis[gc_talkkey ][0] = KEY_2HAT1+2; // D-Pad Left + //gamecontrolbis[gc_scores ][0] = KEY_2HAT1+3; // D-Pad Right #ifdef WMINPUT gamecontrol[gc_forward ][0] = KEY_JOY1+02; //UP gamecontrol[gc_backward ][0] = KEY_JOY1+03; //DOWN diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 6ae4ad8c..fd83cf95 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -1727,6 +1727,25 @@ static int lib_rSetPlayerSkin(lua_State *L) return 0; } +// R_DATA +//////////// + +static int lib_rCheckTextureNumForName(lua_State *L) +{ + const char *name = luaL_checkstring(L, 1); + //HUDSAFE + lua_pushinteger(L, R_CheckTextureNumForName(name)); + return 1; +} + +static int lib_rTextureNumForName(lua_State *L) +{ + const char *name = luaL_checkstring(L, 1); + //HUDSAFE + lua_pushinteger(L, R_TextureNumForName(name)); + return 1; +} + // S_SOUND //////////// @@ -1947,28 +1966,45 @@ static int lib_gDoReborn(lua_State *L) return 0; } -static int lib_gExitLevel(lua_State *L) +// Another Lua function that doesn't actually exist! +// Sets nextmapoverride & skipstats without instantly ending the level, for instances where other sources should be exiting the level, like normal signposts. +static int lib_gSetCustomExitVars(lua_State *L) { int n = lua_gettop(L); // Num arguments NOHUD // LUA EXTENSION: Custom exit like support // Supported: - // G_ExitLevel(); [no modifications] - // G_ExitLevel(int) [nextmap override only] - // G_ExitLevel(bool) [skipstats only] - // G_ExitLevel(int, bool) [both of the above] + // G_SetCustomExitVars(); [reset to defaults] + // G_SetCustomExitVars(int) [nextmap override only] + // G_SetCustomExitVars(bool) [skipstats only] + // G_SetCustomExitVars(int, bool) [both of the above] if (n >= 1) { if (lua_isnumber(L, 1) || n >= 2) { nextmapoverride = (INT16)luaL_checknumber(L, 1); - lua_pop(L, 1); // pop nextmapoverride; skipstats now 1 if available + lua_remove(L, 1); // remove nextmapoverride; skipstats now 1 if available } skipstats = lua_optboolean(L, 1); } + else + { + nextmapoverride = 0; + skipstats = false; + } // --- + return 0; +} + +static int lib_gExitLevel(lua_State *L) +{ + int n = lua_gettop(L); // Num arguments + NOHUD + // Moved this bit to G_SetCustomExitVars + if (n >= 1) // Don't run the reset to defaults option + lib_gSetCustomExitVars(L); G_ExitLevel(); return 0; } @@ -2217,6 +2253,10 @@ static luaL_Reg lib[] = { {"R_Frame2Char",lib_rFrame2Char}, {"R_SetPlayerSkin",lib_rSetPlayerSkin}, + // r_data + {"R_CheckTextureNumForName",lib_rCheckTextureNumForName}, + {"R_TextureNumForName",lib_rTextureNumForName}, + // s_sound {"S_StartSound",lib_sStartSound}, {"S_StartSoundAtVolume",lib_sStartSoundAtVolume}, @@ -2231,6 +2271,7 @@ static luaL_Reg lib[] = { // g_game {"G_BuildMapName",lib_gBuildMapName}, {"G_DoReborn",lib_gDoReborn}, + {"G_SetCustomExitVars",lib_gSetCustomExitVars}, {"G_ExitLevel",lib_gExitLevel}, {"G_IsSpecialStage",lib_gIsSpecialStage}, {"G_GametypeUsesLives",lib_gGametypeUsesLives}, diff --git a/src/lua_maplib.c b/src/lua_maplib.c index efe9e6f4..1f2414ba 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -795,16 +795,16 @@ static int side_set(lua_State *L) side->rowoffset = luaL_checkfixed(L, 3); break; case side_toptexture: - side->toptexture = luaL_checkinteger(L, 3); + side->toptexture = luaL_checkinteger(L, 3); break; case side_bottomtexture: - side->bottomtexture = luaL_checkinteger(L, 3); + side->bottomtexture = luaL_checkinteger(L, 3); break; case side_midtexture: - side->midtexture = luaL_checkinteger(L, 3); + side->midtexture = luaL_checkinteger(L, 3); break; case side_repeatcnt: - side->repeatcnt = luaL_checkinteger(L, 3); + side->repeatcnt = luaL_checkinteger(L, 3); break; } return 0; @@ -1090,6 +1090,7 @@ static int ffloor_get(lua_State *L) { ffloor_t *ffloor = *((ffloor_t **)luaL_checkudata(L, 1, META_FFLOOR)); enum ffloor_e field = luaL_checkoption(L, 2, ffloor_opt[0], ffloor_opt); + INT16 i; if (!ffloor) { @@ -1109,11 +1110,11 @@ static int ffloor_get(lua_State *L) lua_pushfixed(L, *ffloor->topheight); return 1; case ffloor_toppic: { // toppic - levelflat_t *levelflat; - INT16 i; - for (i = 0, levelflat = levelflats; i != *ffloor->toppic; i++, levelflat++) - ; - lua_pushlstring(L, levelflat->name, 8); + levelflat_t *levelflat = &levelflats[*ffloor->toppic]; + for (i = 0; i < 8; i++) + if (!levelflat->name[i]) + break; + lua_pushlstring(L, levelflat->name, i); return 1; } case ffloor_toplightlevel: @@ -1123,11 +1124,11 @@ static int ffloor_get(lua_State *L) lua_pushfixed(L, *ffloor->bottomheight); return 1; case ffloor_bottompic: { // bottompic - levelflat_t *levelflat; - INT16 i; - for (i = 0, levelflat = levelflats; i != *ffloor->bottompic; i++, levelflat++) - ; - lua_pushlstring(L, levelflat->name, 8); + levelflat_t *levelflat = &levelflats[*ffloor->bottompic]; + for (i = 0; i < 8; i++) + if (!levelflat->name[i]) + break; + lua_pushlstring(L, levelflat->name, i); return 1; } #ifdef ESLOPE @@ -1504,6 +1505,8 @@ static int mapheaderinfo_get(lua_State *L) lua_pushinteger(L, header->levelselect); else if (fastcmp(field,"bonustype")) lua_pushinteger(L, header->bonustype); + else if (fastcmp(field,"saveoverride")) + lua_pushinteger(L, header->saveoverride); else if (fastcmp(field,"levelflags")) lua_pushinteger(L, header->levelflags); else if (fastcmp(field,"menuflags")) diff --git a/src/m_menu.c b/src/m_menu.c index acc52f51..8daeba2c 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1089,25 +1089,29 @@ static menuitem_t OP_Joystick1Menu[] = {IT_STRING | IT_CVAR, NULL, "Axis For Moving" , &cv_moveaxis , 40}, {IT_STRING | IT_CVAR, NULL, "Axis For Strafe" , &cv_sideaxis , 50}, {IT_STRING | IT_CVAR, NULL, "Axis For Looking" , &cv_lookaxis , 60}, - {IT_STRING | IT_CVAR, NULL, "Axis For Firing" , &cv_fireaxis , 70}, - {IT_STRING | IT_CVAR, NULL, "Axis For NFiring" , &cv_firenaxis , 80}, + {IT_STRING | IT_CVAR, NULL, "Axis For Jumping" , &cv_jumpaxis , 70}, + {IT_STRING | IT_CVAR, NULL, "Axis For Spinning" , &cv_spinaxis , 80}, + {IT_STRING | IT_CVAR, NULL, "Axis For Firing" , &cv_fireaxis , 90}, + {IT_STRING | IT_CVAR, NULL, "Axis For NFiring" , &cv_firenaxis , 100}, - {IT_STRING | IT_CVAR, NULL, "First-Person Vert-Look", &cv_alwaysfreelook, 100}, - {IT_STRING | IT_CVAR, NULL, "Third-Person Vert-Look", &cv_chasefreelook, 110}, + {IT_STRING | IT_CVAR, NULL, "First-Person Vert-Look", &cv_alwaysfreelook, 120}, + {IT_STRING | IT_CVAR, NULL, "Third-Person Vert-Look", &cv_chasefreelook, 130}, }; static menuitem_t OP_Joystick2Menu[] = { - {IT_STRING | IT_CALL, NULL, "Select Joystick...", M_Setup2PJoystickMenu, 10}, - {IT_STRING | IT_CVAR, NULL, "Axis For Turning" , &cv_turnaxis2 , 30}, - {IT_STRING | IT_CVAR, NULL, "Axis For Moving" , &cv_moveaxis2 , 40}, - {IT_STRING | IT_CVAR, NULL, "Axis For Strafe" , &cv_sideaxis2 , 50}, - {IT_STRING | IT_CVAR, NULL, "Axis For Looking" , &cv_lookaxis2 , 60}, - {IT_STRING | IT_CVAR, NULL, "Axis For Firing" , &cv_fireaxis2 , 70}, - {IT_STRING | IT_CVAR, NULL, "Axis For NFiring" , &cv_firenaxis2 , 80}, + {IT_STRING | IT_CALL, NULL, "Select Joystick...", M_Setup2PJoystickMenu, 10}, + {IT_STRING | IT_CVAR, NULL, "Axis For Turning" , &cv_turnaxis2 , 30}, + {IT_STRING | IT_CVAR, NULL, "Axis For Moving" , &cv_moveaxis2 , 40}, + {IT_STRING | IT_CVAR, NULL, "Axis For Strafe" , &cv_sideaxis2 , 50}, + {IT_STRING | IT_CVAR, NULL, "Axis For Looking" , &cv_lookaxis2 , 60}, + {IT_STRING | IT_CVAR, NULL, "Axis For Jumping" , &cv_jumpaxis2 , 70}, + {IT_STRING | IT_CVAR, NULL, "Axis For Spinning" , &cv_spinaxis2 , 80}, + {IT_STRING | IT_CVAR, NULL, "Axis For Firing" , &cv_fireaxis2 , 90}, + {IT_STRING | IT_CVAR, NULL, "Axis For NFiring" , &cv_firenaxis2 , 100}, - {IT_STRING | IT_CVAR, NULL, "First-Person Vert-Look", &cv_alwaysfreelook2, 100}, - {IT_STRING | IT_CVAR, NULL, "Third-Person Vert-Look", &cv_chasefreelook2, 110}, + {IT_STRING | IT_CVAR, NULL, "First-Person Vert-Look", &cv_alwaysfreelook2,120}, + {IT_STRING | IT_CVAR, NULL, "Third-Person Vert-Look", &cv_chasefreelook2, 130}, }; static menuitem_t OP_JoystickSetMenu[] = diff --git a/src/p_setup.c b/src/p_setup.c index 2e568800..4e66bebb 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -219,6 +219,8 @@ static void P_ClearSingleMapHeaderInfo(INT16 i) mapheaderinfo[num]->levelselect = 0; DEH_WriteUndoline("BONUSTYPE", va("%d", mapheaderinfo[num]->bonustype), UNDO_NONE); mapheaderinfo[num]->bonustype = 0; + DEH_WriteUndoline("SAVEOVERRIDE", va("%d", mapheaderinfo[num]->saveoverride), UNDO_NONE); + mapheaderinfo[num]->saveoverride = SAVE_DEFAULT; DEH_WriteUndoline("LEVELFLAGS", va("%d", mapheaderinfo[num]->levelflags), UNDO_NONE); mapheaderinfo[num]->levelflags = 0; DEH_WriteUndoline("MENUFLAGS", va("%d", mapheaderinfo[num]->menuflags), UNDO_NONE); @@ -380,30 +382,26 @@ static inline void P_LoadVertexes(lumpnum_t lumpnum) Z_Free(data); } - -// -// Computes the line length in fracunits, the OpenGL render needs this -// - /** Computes the length of a seg in fracunits. - * This is needed for splats. * * \param seg Seg to compute length for. * \return Length in fracunits. */ fixed_t P_SegLength(seg_t *seg) { - fixed_t dx, dy; - - // make a vector (start at origin) - dx = seg->v2->x - seg->v1->x; - dy = seg->v2->y - seg->v1->y; - - return FixedHypot(dx, dy); + INT64 dx = (seg->v2->x - seg->v1->x)>>1; + INT64 dy = (seg->v2->y - seg->v1->y)>>1; + return FixedHypot(dx, dy)<<1; } #ifdef HWRENDER -static inline float P_SegLengthf(seg_t *seg) +/** Computes the length of a seg as a float. + * This is needed for OpenGL. + * + * \param seg Seg to compute length for. + * \return Length as a float. + */ +static inline float P_SegLengthFloat(seg_t *seg) { float dx, dy; @@ -439,11 +437,11 @@ static void P_LoadRawSegs(UINT8 *data, size_t i) li->v1 = &vertexes[SHORT(ml->v1)]; li->v2 = &vertexes[SHORT(ml->v2)]; -#ifdef HWRENDER // not win32 only 19990829 by Kin - // used for the hardware render - if (rendermode != render_soft && rendermode != render_none) + li->length = P_SegLength(li); +#ifdef HWRENDER + if (rendermode == render_opengl) { - li->flength = P_SegLengthf(li); + li->flength = P_SegLengthFloat(li); //Hurdler: 04/12/2000: for now, only used in hardware mode li->lightmaps = NULL; // list of static lightmap for this seg } @@ -2626,6 +2624,28 @@ static void P_SetupCamera(void) } } +static boolean P_CanSave(void) +{ + // Saving is completely ignored under these conditions: + if ((cursaveslot < 0) // Playing without saving + || (!modifiedgame || savemoddata) // Game is modified + || (netgame || multiplayer) // Not in single-player + || (demoplayback || demorecording || metalrecording) // Currently in demo + || (players[consoleplayer].lives <= 0) // Completely dead + || (modeattacking || ultimatemode || G_IsSpecialStage(gamemap))) // Specialized instances + return false; + + if (mapheaderinfo[gamemap-1]->saveoverride == SAVE_ALWAYS) + return true; // Saving should ALWAYS happen! + else if (mapheaderinfo[gamemap-1]->saveoverride == SAVE_NEVER) + return false; // Saving should NEVER happen! + + // Default condition: In a non-hidden map, at the beginning of a zone or on a completed save-file, and not on save reload. + return (!(mapheaderinfo[gamemap-1]->menuflags & LF2_HIDEINMENU) + && (mapheaderinfo[gamemap-1]->actnum < 2 || gamecomplete) + && (gamemap != lastmapsaved)); +} + /** Loads a level from a lump or external wad. * * \param skipprecip If true, don't spawn precipitation. @@ -2689,8 +2709,9 @@ boolean P_SetupLevel(boolean skipprecip) if (!dedicated) { - if (!cv_cam_speed.changed) - CV_Set(&cv_cam_speed, cv_cam_speed.defaultvalue); + // Salt: CV_ClearChangedFlags() messes with your settings :( + /*if (!cv_cam_speed.changed) + CV_Set(&cv_cam_speed, cv_cam_speed.defaultvalue);*/ if (!cv_chasecam.changed) CV_SetValue(&cv_chasecam, chase); @@ -3025,20 +3046,22 @@ boolean P_SetupLevel(boolean skipprecip) { P_SetupCamera(); - if (!cv_cam_height.changed) + // Salt: CV_ClearChangedFlags() messes with your settings :( + /*if (!cv_cam_height.changed) CV_Set(&cv_cam_height, cv_cam_height.defaultvalue); if (!cv_cam_dist.changed) CV_Set(&cv_cam_dist, cv_cam_dist.defaultvalue); - if (!cv_cam_rotate.changed) - CV_Set(&cv_cam_rotate, cv_cam_rotate.defaultvalue); - if (!cv_cam2_height.changed) CV_Set(&cv_cam2_height, cv_cam2_height.defaultvalue); if (!cv_cam2_dist.changed) - CV_Set(&cv_cam2_dist, cv_cam2_dist.defaultvalue); + CV_Set(&cv_cam2_dist, cv_cam2_dist.defaultvalue);*/ + + // Though, I don't think anyone would care about cam_rotate being reset back to the only value that makes sense :P + if (!cv_cam_rotate.changed) + CV_Set(&cv_cam_rotate, cv_cam_rotate.defaultvalue); if (!cv_cam2_rotate.changed) CV_Set(&cv_cam2_rotate, cv_cam2_rotate.defaultvalue); @@ -3103,10 +3126,7 @@ boolean P_SetupLevel(boolean skipprecip) P_RunCachedActions(); - if (!(netgame || multiplayer || demoplayback || demorecording || metalrecording || modeattacking || players[consoleplayer].lives <= 0) - && (!modifiedgame || savemoddata) && cursaveslot >= 0 && !ultimatemode - && !(mapheaderinfo[gamemap-1]->menuflags & LF2_HIDEINMENU) - && (!G_IsSpecialStage(gamemap)) && gamemap != lastmapsaved && (mapheaderinfo[gamemap-1]->actnum < 2 || gamecomplete)) + if (P_CanSave()) G_SaveGame((UINT32)cursaveslot); if (savedata.lives > 0) diff --git a/src/p_user.c b/src/p_user.c index 90616754..a27e571e 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -7781,18 +7781,18 @@ static CV_PossibleValue_t CV_CamSpeed[] = {{0, "MIN"}, {1*FRACUNIT, "MAX"}, {0, static CV_PossibleValue_t rotation_cons_t[] = {{1, "MIN"}, {45, "MAX"}, {0, NULL}}; static CV_PossibleValue_t CV_CamRotate[] = {{-720, "MIN"}, {720, "MAX"}, {0, NULL}}; -consvar_t cv_cam_dist = {"cam_dist", "128", CV_FLOAT, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_cam_height = {"cam_height", "20", CV_FLOAT, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_cam_dist = {"cam_dist", "160", CV_FLOAT|CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_cam_height = {"cam_height", "25", CV_FLOAT|CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_cam_still = {"cam_still", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_cam_speed = {"cam_speed", "0.25", CV_FLOAT, CV_CamSpeed, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_cam_speed = {"cam_speed", "0.3", CV_FLOAT|CV_SAVE, CV_CamSpeed, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_cam_rotate = {"cam_rotate", "0", CV_CALL|CV_NOINIT, CV_CamRotate, CV_CamRotate_OnChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_cam_rotspeed = {"cam_rotspeed", "10", 0, rotation_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_cam2_dist = {"cam2_dist", "128", CV_FLOAT, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_cam2_height = {"cam2_height", "20", CV_FLOAT, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_cam_rotspeed = {"cam_rotspeed", "10", CV_SAVE, rotation_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_cam2_dist = {"cam2_dist", "160", CV_FLOAT|CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_cam2_height = {"cam2_height", "25", CV_FLOAT|CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_cam2_still = {"cam2_still", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_cam2_speed = {"cam2_speed", "0.25", CV_FLOAT, CV_CamSpeed, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_cam2_speed = {"cam2_speed", "0.3", CV_FLOAT|CV_SAVE, CV_CamSpeed, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_cam2_rotate = {"cam2_rotate", "0", CV_CALL|CV_NOINIT, CV_CamRotate, CV_CamRotate2_OnChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_cam2_rotspeed = {"cam2_rotspeed", "10", 0, rotation_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_cam2_rotspeed = {"cam2_rotspeed", "10", CV_SAVE, rotation_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; fixed_t t_cam_dist = -42; fixed_t t_cam_height = -42; @@ -8048,6 +8048,20 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall { dist = camdist; + // x1.5 dist for splitscreen + if (splitscreen) + { + dist = FixedMul(dist, 3*FRACUNIT/2); + camheight = FixedMul(camheight, 3*FRACUNIT/2); + } + + // x1.2 dist for analog + if (P_AnalogMove(player)) + { + dist = FixedMul(dist, 6*FRACUNIT/5); + camheight = FixedMul(camheight, 6*FRACUNIT/5); + } + if (player->climbing || player->exiting || player->playerstate == PST_DEAD || (player->pflags & (PF_MACESPIN|PF_ITEMHANG|PF_ROPEHANG))) dist <<= 1; } @@ -8719,9 +8733,14 @@ void P_PlayerThink(player_t *player) if (player->flashcount) player->flashcount--; - // By the time P_MoveChaseCamera is called, this might be zero. Do not do it here. - //if (player->awayviewtics) - // player->awayviewtics--; + // Re-fixed by Jimita (11-12-2018) + if (player->awayviewtics) + { + player->awayviewtics--; + if (!player->awayviewtics) + player->awayviewtics = -1; + // The timer might've reached zero, but we'll run the remote view camera anyway by setting it to -1. + } /// \note do this in the cheat code if (player->pflags & PF_NOCLIP) @@ -9499,8 +9518,8 @@ void P_PlayerAfterThink(player_t *player) } } - if (player->awayviewtics) - player->awayviewtics--; + if (player->awayviewtics < 0) + player->awayviewtics = 0; // spectator invisibility and nogravity. if ((netgame || multiplayer) && player->spectator) diff --git a/src/r_bsp.c b/src/r_bsp.c index a41c6403..cae66844 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -403,17 +403,17 @@ static void R_AddLine(seg_t *line) { INT32 x1, x2; angle_t angle1, angle2, span, tspan; - static sector_t tempsec; // ceiling/water hack + static sector_t tempsec; + + portalline = false; if (line->polyseg && !(line->polyseg->flags & POF_RENDERSIDES)) return; + // big room fix + angle1 = R_PointToAngleEx(viewx, viewy, line->v1->x, line->v1->y); + angle2 = R_PointToAngleEx(viewx, viewy, line->v2->x, line->v2->y); curline = line; - portalline = false; - - // OPTIMIZE: quickly reject orthogonal back sides. - angle1 = R_PointToAngle(line->v1->x, line->v1->y); - angle2 = R_PointToAngle(line->v2->x, line->v2->y); // Clip to view edges. span = angle1 - angle2; @@ -592,69 +592,35 @@ INT32 checkcoord[12][4] = {2, 1, 3, 0} }; -static boolean R_CheckBBox(fixed_t *bspcoord) +static boolean R_CheckBBox(const fixed_t *bspcoord) { - INT32 boxpos, sx1, sx2; - fixed_t px1, py1, px2, py2; - angle_t angle1, angle2, span, tspan; + angle_t angle1, angle2; + INT32 sx1, sx2, boxpos; + const INT32* check; cliprange_t *start; // Find the corners of the box that define the edges from current viewpoint. - if (viewx <= bspcoord[BOXLEFT]) - boxpos = 0; - else if (viewx < bspcoord[BOXRIGHT]) - boxpos = 1; - else - boxpos = 2; - - if (viewy >= bspcoord[BOXTOP]) - boxpos |= 0; - else if (viewy > bspcoord[BOXBOTTOM]) - boxpos |= 1<<2; - else - boxpos |= 2<<2; - - if (boxpos == 5) + if ((boxpos = (viewx <= bspcoord[BOXLEFT] ? 0 : viewx < bspcoord[BOXRIGHT] ? 1 : 2) + (viewy >= bspcoord[BOXTOP] ? 0 : viewy > bspcoord[BOXBOTTOM] ? 4 : 8)) == 5) return true; - px1 = bspcoord[checkcoord[boxpos][0]]; - py1 = bspcoord[checkcoord[boxpos][1]]; - px2 = bspcoord[checkcoord[boxpos][2]]; - py2 = bspcoord[checkcoord[boxpos][3]]; + check = checkcoord[boxpos]; - // check clip list for an open space - angle1 = R_PointToAngle2(viewx>>1, viewy>>1, px1>>1, py1>>1) - viewangle; - angle2 = R_PointToAngle2(viewx>>1, viewy>>1, px2>>1, py2>>1) - viewangle; + // big room fix + angle1 = R_PointToAngleEx(viewx, viewy, bspcoord[check[0]], bspcoord[check[1]]) - viewangle; + angle2 = R_PointToAngleEx(viewx, viewy, bspcoord[check[2]], bspcoord[check[3]]) - viewangle; - span = angle1 - angle2; - - // Sitting on a line? - if (span >= ANGLE_180) - return true; - - tspan = angle1 + clipangle; - - if (tspan > doubleclipangle) + if ((signed)angle1 < (signed)angle2) { - tspan -= doubleclipangle; - - // Totally off the left edge? - if (tspan >= span) - return false; - - angle1 = clipangle; + if ((angle1 >= ANGLE_180) && (angle1 < ANGLE_270)) + angle1 = ANGLE_180-1; + else + angle2 = -ANGLE_180; } - tspan = clipangle - angle2; - if (tspan > doubleclipangle) - { - tspan -= doubleclipangle; - // Totally off the left edge? - if (tspan >= span) - return false; - - angle2 = -(signed)clipangle; - } + if ((signed)angle2 >= (signed)clipangle) return false; + if ((signed)angle1 <= -(signed)clipangle) return false; + if ((signed)angle1 >= (signed)clipangle) angle1 = clipangle; + if ((signed)angle2 <= -(signed)clipangle) angle2 = 0-clipangle; // Find the first clippost that touches the source post (adjacent pixels are touching). angle1 = (angle1+ANGLE_90)>>ANGLETOFINESHIFT; @@ -663,9 +629,7 @@ static boolean R_CheckBBox(fixed_t *bspcoord) sx2 = viewangletox[angle2]; // Does not cross a pixel. - if (sx1 == sx2) - return false; - sx2--; + if (sx1 >= sx2) return false; start = solidsegs; while (start->last < sx2) diff --git a/src/r_defs.h b/src/r_defs.h index b936c7e7..1cb4e081 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -573,6 +573,7 @@ typedef struct seg_s sector_t *frontsector; sector_t *backsector; + fixed_t length; // precalculated seg length #ifdef HWRENDER // new pointers so that AdjustSegs doesn't mess with v1/v2 void *pv1; // polyvertex_t diff --git a/src/r_main.c b/src/r_main.c index 2b0fbc39..94945af5 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -355,6 +355,29 @@ fixed_t R_PointToDist(fixed_t x, fixed_t y) return R_PointToDist2(viewx, viewy, x, y); } +angle_t R_PointToAngleEx(INT32 x2, INT32 y2, INT32 x1, INT32 y1) +{ + INT64 dx = x1-x2; + INT64 dy = y1-y2; + if (dx < INT32_MIN || dx > INT32_MAX || dy < INT32_MIN || dy > INT32_MAX) + { + x1 = (int)(dx / 2 + x2); + y1 = (int)(dy / 2 + y2); + } + return (y1 -= y2, (x1 -= x2) || y1) ? + x1 >= 0 ? + y1 >= 0 ? + (x1 > y1) ? tantoangle[SlopeDivEx(y1,x1)] : // octant 0 + ANGLE_90-tantoangle[SlopeDivEx(x1,y1)] : // octant 1 + x1 > (y1 = -y1) ? 0-tantoangle[SlopeDivEx(y1,x1)] : // octant 8 + ANGLE_270+tantoangle[SlopeDivEx(x1,y1)] : // octant 7 + y1 >= 0 ? (x1 = -x1) > y1 ? ANGLE_180-tantoangle[SlopeDivEx(y1,x1)] : // octant 3 + ANGLE_90 + tantoangle[SlopeDivEx(x1,y1)] : // octant 2 + (x1 = -x1) > (y1 = -y1) ? ANGLE_180+tantoangle[SlopeDivEx(y1,x1)] : // octant 4 + ANGLE_270-tantoangle[SlopeDivEx(x1,y1)] : // octant 5 + 0; +} + // // R_ScaleFromGlobalAngle // Returns the texture mapping scale for the current line (horizontal span) diff --git a/src/r_main.h b/src/r_main.h index 81fa13de..6ae5aa22 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -58,6 +58,7 @@ INT32 R_PointOnSide(fixed_t x, fixed_t y, node_t *node); INT32 R_PointOnSegSide(fixed_t x, fixed_t y, seg_t *line); angle_t R_PointToAngle(fixed_t x, fixed_t y); angle_t R_PointToAngle2(fixed_t px2, fixed_t py2, fixed_t px1, fixed_t py1); +angle_t R_PointToAngleEx(INT32 x2, INT32 y2, INT32 x1, INT32 y1); fixed_t R_PointToDist(fixed_t x, fixed_t y); fixed_t R_PointToDist2(fixed_t px2, fixed_t py2, fixed_t px1, fixed_t py1); diff --git a/src/r_segs.c b/src/r_segs.c index 1637ce90..6d6ba1ef 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -1647,6 +1647,23 @@ static void R_RenderSegLoop (void) } } +// Uses precalculated seg->length +static INT64 R_CalcSegDist(seg_t* seg, INT64 x2, INT64 y2) +{ + if (!seg->linedef->dy) + return llabs(y2 - seg->v1->y); + else if (!seg->linedef->dx) + return llabs(x2 - seg->v1->x); + else + { + INT64 dx = (seg->v2->x)-(seg->v1->x); + INT64 dy = (seg->v2->y)-(seg->v1->y); + INT64 vdx = x2-(seg->v1->x); + INT64 vdy = y2-(seg->v1->y); + return ((dy*vdx)-(dx*vdy))/(seg->length); + } +} + // // R_StoreWallRange // A wall segment will be drawn @@ -1657,6 +1674,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) fixed_t hyp; fixed_t sineval; angle_t distangle, offsetangle; + boolean longboi; #ifndef ESLOPE fixed_t vtop; #endif @@ -1702,10 +1720,15 @@ void R_StoreWallRange(INT32 start, INT32 stop) offsetangle = ANGLE_90; distangle = ANGLE_90 - offsetangle; - hyp = R_PointToDist (curline->v1->x, curline->v1->y); sineval = FINESINE(distangle>>ANGLETOFINESHIFT); - rw_distance = FixedMul (hyp, sineval); + hyp = R_PointToDist(curline->v1->x, curline->v1->y); + rw_distance = FixedMul(hyp, sineval); + longboi = (hyp >= INT32_MAX); + + // big room fix + if (longboi) + rw_distance = (fixed_t)R_CalcSegDist(curline,viewx,viewy); ds_p->x1 = rw_x = start; ds_p->x2 = stop; @@ -2562,8 +2585,18 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (offsetangle > ANGLE_90) offsetangle = ANGLE_90; - sineval = FINESINE(offsetangle >>ANGLETOFINESHIFT); - rw_offset = FixedMul (hyp, sineval); + sineval = FINESINE(offsetangle>>ANGLETOFINESHIFT); + rw_offset = FixedMul(hyp, sineval); + + // big room fix + if (longboi) + { + INT64 dx = (curline->v2->x)-(curline->v1->x); + INT64 dy = (curline->v2->y)-(curline->v1->y); + INT64 vdx = viewx-(curline->v1->x); + INT64 vdy = viewy-(curline->v1->y); + rw_offset = ((dx*vdx-dy*vdy))/(curline->length); + } if (rw_normalangle-rw_angle1 < ANGLE_180) rw_offset = -rw_offset; diff --git a/src/r_things.h b/src/r_things.h index e4a5f426..6614e0aa 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -219,6 +219,7 @@ FUNCMATH FUNCINLINE static ATTRINLINE char R_Frame2Char(UINT8 frame) FUNCMATH FUNCINLINE static ATTRINLINE UINT8 R_Char2Frame(char cn) { #if 1 // 2.1 compat + if (cn == '+') return '\\' - 'A'; // PK3 can't use backslash, so use + instead return cn - 'A'; #else if (cn >= 'A' && cn <= 'Z') return cn - 'A'; diff --git a/src/sdl/Srb2SDL-vc10.vcxproj b/src/sdl/Srb2SDL-vc10.vcxproj index 3e4a9ebb..00ed0db3 100644 --- a/src/sdl/Srb2SDL-vc10.vcxproj +++ b/src/sdl/Srb2SDL-vc10.vcxproj @@ -297,7 +297,7 @@ - + diff --git a/src/tables.c b/src/tables.c index d4e0e5df..7d513707 100644 --- a/src/tables.c +++ b/src/tables.c @@ -37,6 +37,15 @@ unsigned SlopeDiv(unsigned num, unsigned den) return ans <= SLOPERANGE ? ans : SLOPERANGE; } +UINT64 SlopeDivEx(unsigned int num, unsigned int den) +{ + UINT64 ans; + if (den < 512) + return SLOPERANGE; + ans = ((UINT64)num<<3)/(den>>8); + return ans <= SLOPERANGE ? ans : SLOPERANGE; +} + fixed_t AngleFixed(angle_t af) { angle_t wa = ANGLE_180; diff --git a/src/tables.h b/src/tables.h index 1ea49a62..e82b147d 100644 --- a/src/tables.h +++ b/src/tables.h @@ -83,6 +83,8 @@ extern angle_t tantoangle[SLOPERANGE+1]; // Utility function, called by R_PointToAngle. FUNCMATH unsigned SlopeDiv(unsigned num, unsigned den); +// Only called by R_PointToAngleEx +UINT64 SlopeDivEx(unsigned int num, unsigned int den); // 360 - angle_t(ANGLE_45) = ANGLE_315 FUNCMATH FUNCINLINE static ATTRINLINE angle_t InvAngle(angle_t a) diff --git a/src/win32/Srb2win-vc10.vcxproj b/src/win32/Srb2win-vc10.vcxproj index 5bfa29b8..ed6b46b8 100644 --- a/src/win32/Srb2win-vc10.vcxproj +++ b/src/win32/Srb2win-vc10.vcxproj @@ -132,7 +132,7 @@ - +