From c25e9696760afa898f24acab9ff43378e4156499 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Tue, 14 Jan 2020 23:29:56 -0600 Subject: [PATCH] wip viewroll stuff --- src/d_main.c | 6 ++ src/d_player.h | 2 + src/lua_playerlib.c | 4 ++ src/p_user.c | 2 + src/r_main.c | 141 +++++++++++++++++++++++++++++++++++++++++++- src/r_main.h | 3 + 6 files changed, 157 insertions(+), 1 deletion(-) diff --git a/src/d_main.c b/src/d_main.c index 8a7c446bb..763814a5a 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -266,6 +266,9 @@ static void D_Display(void) #endif } + if (rendermode == render_soft && !splitscreen) + R_CheckViewMorph(); + // change the view size if needed if (setsizeneeded || setrenderstillneeded) { @@ -446,6 +449,9 @@ static void D_Display(void) // Image postprocessing effect if (rendermode == render_soft) { + if (!splitscreen) + R_ApplyViewMorph(); + if (postimgtype) V_DoPostProcessor(0, postimgtype, postimgparam); if (postimgtype2) diff --git a/src/d_player.h b/src/d_player.h index 62f38193f..6a1750113 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -324,6 +324,8 @@ typedef struct player_s // bounded/scaled total momentum. fixed_t bob; + angle_t viewrollangle; + // Mouse aiming, where the guy is looking at! // It is updated with cmd->aiming. angle_t aiming; diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index c501fbbb2..8b9397663 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -120,6 +120,8 @@ static int player_get(lua_State *L) lua_pushfixed(L, plr->deltaviewheight); else if (fastcmp(field,"bob")) lua_pushfixed(L, plr->bob); + else if (fastcmp(field,"viewrollangle")) + lua_pushangle(L, plr->viewrollangle); else if (fastcmp(field,"aiming")) lua_pushangle(L, plr->aiming); else if (fastcmp(field,"drawangle")) @@ -415,6 +417,8 @@ static int player_set(lua_State *L) plr->deltaviewheight = luaL_checkfixed(L, 3); else if (fastcmp(field,"bob")) plr->bob = luaL_checkfixed(L, 3); + else if (fastcmp(field,"viewrollangle")) + plr->viewrollangle = luaL_checkangle(L, 3); else if (fastcmp(field,"aiming")) { plr->aiming = luaL_checkangle(L, 3); if (plr == &players[consoleplayer]) diff --git a/src/p_user.c b/src/p_user.c index 0c4d25554..5d7383c4b 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -7432,6 +7432,8 @@ static void P_NiGHTSMovement(player_t *player) else // AngleFixed(R_PointToAngle2()) results in slight inaccuracy! Don't use it unless movement is on both axises. newangle = (INT16)FixedInt(AngleFixed(R_PointToAngle2(0,0, cmd->sidemove*FRACUNIT, cmd->forwardmove*FRACUNIT))); + newangle -= player->viewrollangle / ANG1; + if (newangle < 0 && moved) newangle = (INT16)(360+newangle); } diff --git a/src/r_main.c b/src/r_main.c index 3c6aaf6a6..fbb3c7047 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -551,6 +551,145 @@ static inline void R_InitLightTables(void) } } +static struct { + angle_t rollangle; // pre-shifted by fineshift + fixed_t fisheye; + + fixed_t zoomneeded; + INT32 *scrmap; + size_t scrmapsize; + boolean use; +} viewmorph = {0, 0, FRACUNIT, NULL, 0, false}; + +void R_CheckViewMorph(void) +{ + float zoomfactor, rollcos, rollsin; + float x1, y1, x2, y2; + fixed_t temp; + size_t end, vx, vy, pos, usedpos; + INT32 usedx, usedy, halfwidth = vid.width/2, halfheight = vid.height/2; + + angle_t rollangle = players[displayplayer].viewrollangle; + //fixed_t fisheye = players[displayplayer].viewfisheye; + + // temp values + //angle_t rollangle = leveltime << (ANGLETOFINESHIFT); + fixed_t fisheye = 0; + + rollangle >>= ANGLETOFINESHIFT; + rollangle = (((rollangle+1)/2)*2) & FINEMASK; // Limit the distinct number of angles to reduce recalcs from angles changing a lot. + + fisheye &= ~0xFF; // Same limiter logic for fisheye + + if (rollangle == viewmorph.rollangle && fisheye == viewmorph.fisheye) + return; // No change + + viewmorph.rollangle = rollangle; + viewmorph.fisheye = fisheye; + + if (viewmorph.rollangle == 0 && viewmorph.fisheye == 0) + { + viewmorph.use = false; + if (viewmorph.zoomneeded != FRACUNIT) + R_SetViewSize(); + viewmorph.zoomneeded = FRACUNIT; + + return; + } + + if (viewmorph.scrmapsize != vid.width*vid.height) + { + if (viewmorph.scrmap) + free(viewmorph.scrmap); + viewmorph.scrmap = malloc(vid.width*vid.height * sizeof(INT32)); + viewmorph.scrmapsize = vid.width*vid.height; + } + + temp = FINECOSINE(rollangle); + rollcos = FIXED_TO_FLOAT(temp); + temp = FINESINE(rollangle); + rollsin = FIXED_TO_FLOAT(temp); + + // Calculate maximum zoom needed + x1 = (vid.width*fabsf(rollcos) + vid.height*fabsf(rollsin)) / vid.width; + y1 = (vid.height*fabsf(rollcos) + vid.width*fabsf(rollsin)) / vid.height; + + temp = max(x1, y1)*FRACUNIT; + if (temp < FRACUNIT) + temp = FRACUNIT; + else + temp |= 0xFFF; // Limit how many times the viewport needs to be recalculated + + //CONS_Printf("Setting zoom to %f\n", FIXED_TO_FLOAT(temp)); + + if (temp != viewmorph.zoomneeded) + { + viewmorph.zoomneeded = temp; + R_SetViewSize(); + } + + zoomfactor = FIXED_TO_FLOAT(viewmorph.zoomneeded); + + end = vid.width * vid.height - 1; + + pos = 0; + + // Pre-multiply rollcos and rollsin to use for positional stuff + rollcos /= zoomfactor; + rollsin /= zoomfactor; + + x1 = -(halfwidth * rollcos - halfheight * rollsin); + y1 = -(halfheight * rollcos + halfwidth * rollsin); + + //CONS_Printf("Top left corner is %f %f\n", x1, y1); + + for (vy = 0; vy < halfheight; vy++) + { + x2 = x1; + y2 = y1; + x1 -= rollsin; + y1 += rollcos; + + for (vx = 0; vx < vid.width; vx++) + { + usedx = halfwidth+x2; + usedy = halfheight+y2; + + if (usedx < 0) usedx = 0; + else if (usedx >= vid.width) usedx = vid.width-1; + if (usedy < 0) usedy = 0; + else if (usedy >= vid.height) usedy = vid.height-1; + + usedpos = usedx + usedy*vid.width; + + viewmorph.scrmap[pos] = usedpos; + viewmorph.scrmap[end-pos] = end-usedpos; + + x2 += rollcos; + y2 += rollsin; + pos++; + } + } + + viewmorph.use = true; +} + +void R_ApplyViewMorph(void) +{ + UINT8 *tmpscr = screens[4]; + UINT8 *srcscr = screens[0]; + INT32 p, end = vid.width * vid.height; + + if (!viewmorph.use) + return; + + for (p = 0; p < end; p++) + tmpscr[p] = srcscr[viewmorph.scrmap[p]]; + + VID_BlitLinearScreen(tmpscr, screens[0], + vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.width); +} + // // R_SetViewSize @@ -599,7 +738,7 @@ void R_ExecuteSetViewSize(void) centeryfrac = centery<> ANGLETOFINESHIFT); + fovtan = FixedMul(FINETANGENT(fov >> ANGLETOFINESHIFT), viewmorph.zoomneeded); if (splitscreen == 1) // Splitscreen FOV should be adjusted to maintain expected vertical view fovtan = 17*fovtan/10; diff --git a/src/r_main.h b/src/r_main.h index 998bb50ef..92876ce25 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -95,6 +95,9 @@ void R_InitHardwareMode(void); #endif void R_ReloadHUDGraphics(void); +void R_CheckViewMorph(void); +void R_ApplyViewMorph(void); + // just sets setsizeneeded true extern boolean setsizeneeded; void R_SetViewSize(void);