Pitch and roll, and slope equivalents #84

Merged
Chearii merged 9 commits from Saturn-pitch-roll into Saturn-Next 2024-01-02 00:08:59 +01:00
21 changed files with 492 additions and 130 deletions

No files matched your search

+20
View File
@@ -0,0 +1,20 @@
[Desktop Entry]
Version=1.0
Type=Application
Name=Sonic Robo Blast 2 Kart Saturn
Comment=A kart racing mod based on the 3D Sonic the Hedgehog fangame Sonic Robo Blast 2
TryExec=srb2kart.sh
Exec=srb2kart.sh
Icon=org.srb2.SRB2Kart-Saturn
Terminal=false
Categories=Game;SportsGame;
Keywords=kart;sonic;racer;multiplayer;doom;
Actions=OpenGL;Software;
[Desktop Action OpenGL]
Name=OpenGL renderer
Exec=srb2kart.sh -opengl
[Desktop Action Software]
Name=Software renderer
Exec=srb2kart.sh -software
+80
View File
@@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!-- Copyright 2023 Flathub maintainers -->
<component type="desktop-application">
<id>org.srb2.SRB2Kart-Saturn</id>
<metadata_license>FSFAP</metadata_license>
<project_license>GPL-2.0+</project_license>
<name>Sonic Robo Blast 2 Kart Saturn</name>
<summary>Modded SRB2Kart adding many custom features</summary>
<description>
<p>
A modded net-compatible version of SRB2Kart v1.6 that offers multiple code optimizations, palette rendering, player sprite rotation, base Kart HUD customization, and many more.
</p>
</description>
<launchable type="desktop-id">org.srb2.SRB2Kart-Saturn.desktop</launchable>
<screenshots>
<screenshot type="default">
<image>https://wiki.srb2.org/w/images/a/ac/Srb2kart_title.png</image>
<caption>Title screen</caption>
</screenshot>
<screenshot>
<image>https://user-images.githubusercontent.com/15758649/227740700-26e0962b-5572-486c-b633-7d4990d86f89.png</image>
<caption>Game modes</caption>
</screenshot>
<screenshot>
<image>https://user-images.githubusercontent.com/1964655/82821921-3d180c00-9ea5-11ea-937b-e1f53fe6c686.png</image>
<caption>Game play as Sonic</caption>
</screenshot>
<screenshot>
<image>https://user-images.githubusercontent.com/1964655/82821933-41442980-9ea5-11ea-9146-38998161edae.png</image>
<caption>Game play as Tails</caption>
</screenshot>
<screenshot>
<image>https://user-images.githubusercontent.com/1964655/82821966-502adc00-9ea5-11ea-9cbd-274d7adb479e.png</image>
<caption>Game play as Eggman</caption>
</screenshot>
<screenshot>
<image>https://user-images.githubusercontent.com/1964655/82821980-5620bd00-9ea5-11ea-9eec-2835ebb2a262.png</image>
<caption>Game play as Metal Sonic</caption>
</screenshot>
</screenshots>
<url type="homepage">https://github.com/Indev450/SRB2Kart-Saturn</url>
<url type="bugtracker">https://github.com/Indev450/SRB2Kart-Saturn/issues</url>
<developer_name>Indev450</developer_name>
<provides>
<binary>srb2kart</binary>
</provides>
<releases>
<release version="5.1" date="2023-12-20">
<description>
<p>The complete changelog can be found on the build's GitHub repository.</p>
</description>
<url>https://github.com/Indev450/SRB2Kart-Saturn/releases/tag/v5.1</url>
</release>
<release version="5.0" date="2023-12-17">
<description>
<p>The complete changelog can be found on the build's GitHub repository.</p>
</description>
<url>https://github.com/Indev450/SRB2Kart-Saturn/releases/tag/v5</url>
</release>
</releases>
<categories>
<category>Game</category>
<category>SportsGame</category>
</categories>
<recommends>
<control>keyboard</control>
<control>gamepad</control>
</recommends>
<content_rating type="oars-1.1">
<content_attribute id="violence-cartoon">moderate</content_attribute>
<content_attribute id="language-humor">mild</content_attribute>
<content_attribute id="social-chat">intense</content_attribute>
<content_attribute id="social-info">mild</content_attribute>
</content_rating>
<keywords>
<keyword>doom</keyword>
<keyword>multiplayer</keyword>
<keyword>racing</keyword>
</keywords>
</component>
+2
View File
@@ -517,6 +517,8 @@ static CV_PossibleValue_t sloperolldist_cons_t[] = {
{8192, "8192"}, {0, "Infinite"}, {0, NULL}};
consvar_t cv_sloperolldist = {"sloperolldist", "Infinite", CV_SAVE, sloperolldist_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_sparkroll = {"sparkroll", "Off", CV_SAVE|CV_CALL, CV_OnOff, PDistort_menu_Onchange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_cechotoggle = {"show_cecho", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
#if MAXPLAYERS > 16
+1
View File
@@ -159,6 +159,7 @@ extern consvar_t cv_sloperoll;
extern consvar_t cv_sliptideroll;
extern consvar_t cv_slamsound;
extern consvar_t cv_sloperolldist;
extern consvar_t cv_sparkroll;
extern consvar_t cv_cechotoggle;
+2
View File
@@ -129,8 +129,10 @@ typedef struct
FLOAT x,y,z; // position
#ifdef USE_FTRANSFORM_ANGLEZ
FLOAT anglex,angley,anglez; // aimingangle / viewangle
FLOAT anglex2,anglez2; // secondaries
#else
FLOAT anglex,angley; // aimingangle / viewangle
FLOAT anglex2; // secondaries
#endif
FLOAT scalex,scaley,scalez;
FLOAT spritexscale,spriteyscale;
+13 -4
View File
@@ -5515,7 +5515,7 @@ void HWR_ProjectSprite(mobj_t *thing)
boolean mirrored = thing->mirrored;
boolean hflip = (!(thing->frame & FF_HORIZONTALFLIP) != !mirrored);
angle_t ang;
angle_t ang, camang;
const boolean papersprite = (thing->frame & FF_PAPERSPRITE);
INT32 heightsec, phs;
vector3_t pos;
@@ -5616,6 +5616,8 @@ void HWR_ProjectSprite(mobj_t *thing)
#endif
ang = R_PointToAngle (interp.x, interp.y) - interp.angle;
camang = R_PointToAngle (interp.x, interp.y);
if (mirrored)
ang = InvAngle(ang);
@@ -5666,15 +5668,22 @@ void HWR_ProjectSprite(mobj_t *thing)
spr_topoffset = spritecachedinfo[lumpoff].topoffset;
#ifdef ROTSPRITE
if ((thing->rollangle)||(thing->sloperoll)||(thing->player && thing->player->sliproll))
rollangle = FixedMul(FINECOSINE((ang) >> ANGLETOFINESHIFT), interp.roll)
+ FixedMul(FINESINE((ang) >> ANGLETOFINESHIFT), interp.pitch)
+ FixedMul(FINECOSINE((camang) >> ANGLETOFINESHIFT), interp.sloperoll)
+ FixedMul(FINESINE((camang) >> ANGLETOFINESHIFT), interp.slopepitch)
+ thing->rollangle;
if ((rollangle)||(thing->player && thing->player->sliproll))
{
if (thing->player)
{
sliptiderollangle = cv_sliptideroll.value ? thing->player->sliproll*(thing->player->sliptidemem) : 0;
rollsum = (thing->rollangle)+(thing->sloperoll)+FixedMul(FINECOSINE((ang) >> ANGLETOFINESHIFT), sliptiderollangle);
rollsum = rollangle+FixedMul(FINECOSINE((ang) >> ANGLETOFINESHIFT), sliptiderollangle);
}
else
rollsum = (thing->rollangle)+(thing->sloperoll);
rollsum = rollangle;
rollangle = R_GetRollAngle(rollsum);
rotsprite = Patch_GetRotatedSprite(sprframe, (thing->frame & FF_FRAMEMASK), rot, flip, false, sprinfo, rollangle);
+39 -2
View File
@@ -1401,18 +1401,55 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
p.anglex = 0.0f;
p.anglex2 = 0.0f;
#ifdef USE_FTRANSFORM_ANGLEZ
// Slope rotation from Kart
p.anglez = 0.0f;
p.anglez2 = 0.0f;
// use secondary angles for the slope rotation
if (spr->mobj->standingslope)
{
fixed_t tempz = spr->mobj->standingslope->normal.z;
fixed_t tempy = spr->mobj->standingslope->normal.y;
fixed_t tempx = spr->mobj->standingslope->normal.x;
fixed_t tempangle = AngleFixed(R_PointToAngle2(0, 0, FixedSqrt(FixedMul(tempy, tempy) + FixedMul(tempz, tempz)), tempx));
p.anglez = FIXED_TO_FLOAT(tempangle);
p.anglez2 = FIXED_TO_FLOAT(tempangle);
tempangle = -AngleFixed(R_PointToAngle2(0, 0, tempz, tempy));
p.anglex = FIXED_TO_FLOAT(tempangle);
p.anglex2 = FIXED_TO_FLOAT(tempangle);
}
else if ((spr->mobj->sloperoll || spr->mobj->slopepitch) && (!P_IsObjectOnGround(spr->mobj)) && (!paused))
{
SINT8 flipfactor = flip ? -1 : 1;
angle_t camang = R_PointToAngle(interp.x, interp.y);
angle_t mobjang;
if (spr->mobj->flags & (MF_NOTHINK|MF_SCENERY))
mobjang = spr->mobj->angle;
else
mobjang = interp.angle;
angle_t fmoang;
fmoang = camang - mobjang;
// slopepitch
p.anglex += flipfactor*FIXED_TO_FLOAT( AngleFixed(FixedMul(FINESINE((camang-fmoang) >> ANGLETOFINESHIFT), interp.slopepitch)) );
p.anglez -= flipfactor*FIXED_TO_FLOAT( AngleFixed(FixedMul(FINECOSINE((camang-fmoang) >> ANGLETOFINESHIFT), interp.slopepitch)) );
// sloperoll
p.anglex += flipfactor*FIXED_TO_FLOAT( AngleFixed(FixedMul(FINECOSINE((camang-fmoang) >> ANGLETOFINESHIFT), interp.sloperoll)) );
p.anglez += flipfactor*FIXED_TO_FLOAT( AngleFixed(FixedMul(FINESINE((camang-fmoang) >> ANGLETOFINESHIFT), interp.sloperoll)) );
p.roll = true;
}
// pitch and roll
if (interp.roll || interp.pitch)
{
SINT8 flipfactor = flip ? -1 : 1;
p.anglex += flipfactor*FIXED_TO_FLOAT(AngleFixed(interp.roll));
p.anglez -= flipfactor*FIXED_TO_FLOAT(AngleFixed(interp.pitch));
p.roll = true;
}
#endif
+10 -2
View File
@@ -3742,21 +3742,29 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, float duration, float
if (hflipped)
scalez = -scalez;
#ifdef USE_FTRANSFORM_ANGLEZ
pglRotatef(pos->anglez, 0.0f, 0.0f, -1.0f); // rotate by slope from Kart
pglRotatef(pos->anglez2, 0.0f, 0.0f, -1.0f); // rotate by slope from Kart
#endif
pglRotatef(pos->anglex, -1.0f, 0.0f, 0.0f);
pglRotatef(pos->anglex2, -1.0f, 0.0f, 0.0f);
pglRotatef(pos->angley, 0.0f, -1.0f, 0.0f);
if (pos->roll)
{
float roll = (1.0f * pos->rollflip);
pglTranslatef(pos->centerx, pos->centery, 0);
// rotate model for pitch and roll
pglRotatef(pos->anglex, 1.0f, 0.0f, 0.0f);
#ifdef USE_FTRANSFORM_ANGLEZ
pglRotatef(pos->anglez, 0.0f, 0.0f, -1.0f);
#endif
if (pos->rotaxis == 2) // Z
pglRotatef(pos->rollangle, 0.0f, 0.0f, roll);
else if (pos->rotaxis == 1) // Y
pglRotatef(pos->rollangle, 0.0f, roll, 0.0f);
else // X
pglRotatef(pos->rollangle, roll, 0.0f, 0.0f);
pglTranslatef(-pos->centerx, -pos->centery, 0);
}
+68 -79
View File
@@ -3005,6 +3005,13 @@ static void K_SpawnDriftSparks(player_t *player)
spark->momy = player->mo->momy/2;
//spark->momz = player->mo->momz/2;
// rotate the sparks based on pitch and roll; it just looks neat
if (cv_sparkroll.value == 1)
{
spark->slopepitch = player->mo->slopepitch;
spark->sloperoll = player->mo->sloperoll;
}
if (player->kartstuff[k_driftcharge] >= K_GetKartDriftSparkValue(player)*4)
{
spark->color = (UINT8)(1 + (leveltime % (MAXSKINCOLORS-1)));
@@ -3214,7 +3221,7 @@ static void K_QuiteSaltyHop(player_t *p)
}
}
static INT32 K_FindPlayerNum(player_t *plyr)
/*static INT32 K_FindPlayerNum(player_t *plyr)
{
INT32 i;
@@ -3224,95 +3231,61 @@ static INT32 K_FindPlayerNum(player_t *plyr)
return i;
}
return 0; // technically defaulting to player 1 but fuck it
alufolie91 commented 2024-01-01 22:18:52 +01:00 (Migrated from github.com)
Review

one thing i did notice however, the camspin divisior change from 3 to 1 was just a workaround since sprites used to rotate based on the lookangle before and thus looked very weird when looking back
since this is not the case anymore this could probably be removed now unless its used for something else now

one thing i did notice however, the camspin divisior change from 3 to 1 was just a workaround since sprites used to rotate based on the lookangle before and thus looked very weird when looking back since this is not the case anymore this could probably be removed now unless its used for something else now
Chearii commented 2024-01-01 22:58:16 +01:00 (Migrated from github.com)
Review

Ah, I thought this was for the camera tilting, hence the name on the boolean. I can probably just push a commit to change that.

Ah, I thought this was for the camera tilting, hence the name on the boolean. I can probably just push a commit to change that.
alufolie91 commented 2024-01-02 00:08:50 +01:00 (Migrated from github.com)
Review

was just a little hack X)
anyways, played a little with it today and everything seems to work very well
ty much for this c:

was just a little hack X) anyways, played a little with it today and everything seems to work very well ty much for this c:
Chearii commented 2024-01-02 00:23:48 +01:00 (Migrated from github.com)
Review

np!

np!
}
}*/
static angle_t K_GetSlopeRollAngle(player_t *p, boolean dontflip, boolean useReserves)
#define SLOPEROLL_DIV 3
void K_RollMobjBySlopes(mobj_t* mo, boolean usedistance)
{
angle_t lookAngle = 0;
angle_t zangle = 0;
angle_t xydirection = 0;
angle_t an;
angle_t final_slope;
INT32 pNum = K_FindPlayerNum(p);
I_Assert(mo->subsector != NULL);
I_Assert(mo->subsector->sector != NULL);
I_Assert(p != NULL);
I_Assert(p->mo != NULL);
I_Assert(!P_MobjWasRemoved(p->mo));
angle_t an;
fixed_t m_dist = R_PointToDist(mo->x, mo->y);
fixed_t rolldist = cv_sloperolldist.value * mapobjectscale;
if (useReserves)
{
I_Assert(p->mo->reservezangle != NULL);
I_Assert(p->mo->reservexydir != NULL);
}
// lifted from hw_md2
if (mo->standingslope)
{
fixed_t tempz = mo->standingslope->normal.z;
fixed_t tempy = mo->standingslope->normal.y;
fixed_t tempx = mo->standingslope->normal.x;
fixed_t tempangle = -(R_PointToAngle2(
0, 0, FixedSqrt(FixedMul(tempy, tempy) + FixedMul(tempz, tempz)), tempx));
lookAngle = R_PointToAngle2(camera[pNum].x, camera[pNum].y, p->mo->x, p->mo->y);
// admittedly this is a very hacky way to do the pitch and roll easing
if (!R_PointToDist(p->mo->x, p->mo->y))
lookAngle = p->mo->angle;
// pitch
if ((!usedistance) || (m_dist <= (rolldist)))
{
an = (INT32)((angle_t)tempangle - mo->pitch_sprite) / SLOPEROLL_DIV;
if (!useReserves)
{
zangle = p->mo->standingslope->zangle;
xydirection = p->mo->standingslope->xydirection;
mo->pitch_sprite = an ? mo->pitch_sprite + an : (angle_t)tempangle;
}
else
mo->pitch_sprite = FixedAngle(0);
p->mo->reservezangle = zangle;
p->mo->reservexydir = xydirection;
}
else if (p->mo->reservezangle)
{
zangle = p->mo->reservezangle;
xydirection = p->mo->reservexydir;
}
mo->slopepitch = mo->pitch_sprite;
if ((p->mo->eflags & MFE_VERTICALFLIP) && (!dontflip))
zangle = InvAngle(zangle);
// roll
tempangle = (R_PointToAngle2(0, 0, tempz, tempy));
an = (lookAngle - xydirection);
final_slope = -(FixedMul(FINESINE(an>>ANGLETOFINESHIFT), zangle));
an = (INT32)(final_slope - p->tilt_sprite) / (camspin[pNum] ? 1 : 3);
p->tilt_sprite = an ? p->tilt_sprite + an : final_slope;
return -p->tilt_sprite;
}
if ((!usedistance) || (m_dist <= (rolldist)))
{
an = (INT32)((angle_t)tempangle - mo->roll_sprite) / SLOPEROLL_DIV;
static void K_RollPlayerBySlopes(player_t *p, boolean usedistance)
{
I_Assert(p->mo->subsector != NULL);
I_Assert(p->mo->subsector->sector != NULL);
mo->roll_sprite = an ? mo->roll_sprite + an : (angle_t)tempangle;
}
else
mo->roll_sprite = FixedAngle(0);
INT32 pNum = K_FindPlayerNum(p);
fixed_t p_dist = R_PointToDist2(p->mo->x, p->mo->y, camera[pNum].x, camera[pNum].y);
fixed_t mos = mapobjectscale;
fixed_t rolldist = cv_sloperolldist.value*mos;
if (!P_IsObjectOnGround(p->mo))
{
if (!usedistance)
p->mo->sloperoll = K_GetSlopeRollAngle(p, false, true);
else if (p_dist <= (rolldist))
p->mo->sloperoll = K_GetSlopeRollAngle(p, false, true);
else
p->mo->sloperoll = FixedAngle(0);
return;
}
if (!p->mo->standingslope)
{
p->mo->sloperoll = FixedAngle(0);
p->mo->reservezangle = FixedAngle(0);
p->mo->reservexydir = FixedAngle(0);
return;
}
if (!usedistance)
p->mo->sloperoll = K_GetSlopeRollAngle(p, false, false);
else if (p_dist <= (rolldist))
p->mo->sloperoll = K_GetSlopeRollAngle(p, false, false);
else
p->mo->sloperoll = FixedAngle(0);
mo->sloperoll = mo->roll_sprite;
}
else if (P_IsObjectOnGround(mo))
{
mo->sloperoll = FixedAngle(0);
mo->slopepitch = FixedAngle(0);
}
}
void K_SpawnBoostTrail(player_t *player)
@@ -3364,6 +3337,14 @@ void K_SpawnBoostTrail(player_t *player)
K_FlipFromObject(flame, player->mo);
flame->momx = 8;
// since you have to be on the ground for sneaker trails, this should be fine(?)
if (cv_sparkroll.value == 1)
{
flame->slopepitch = player->mo->slopepitch;
flame->sloperoll = player->mo->sloperoll;
}
P_XYMovement(flame);
if (P_MobjWasRemoved(flame))
continue;
@@ -6459,13 +6440,21 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
player->mo->spritexscale = player->mo->realxscale;
player->mo->spriteyscale = player->mo->realyscale;
}
boolean usedist = false;
if (cv_sloperolldist.value > 0)
usedist = true;
if (cv_sloperoll.value == 1)
K_RollPlayerBySlopes(player, usedist);
{
if ((!player->mo->salty_jump)) // seeing a character rotate mid-hop looks really janky
K_RollMobjBySlopes(player->mo, usedist);
}
else
{
player->mo->sloperoll = FixedAngle(0);
player->mo->slopepitch = FixedAngle(0);
}
// Quick Turning
+1
View File
@@ -49,6 +49,7 @@ void K_ExplodePlayer(player_t *player, mobj_t *source, mobj_t *inflictor);
void K_StealBumper(player_t *player, player_t *victim, boolean force);
void K_SpawnKartExplosion(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 number, mobjtype_t type, angle_t rotangle, boolean spawncenter, boolean ghostit, mobj_t *source);
void K_SpawnMineExplosion(mobj_t *source, UINT8 color);
void K_RollMobjBySlopes(mobj_t *mo, boolean usedistance);
void K_SpawnBoostTrail(player_t *player);
void K_SpawnSparkleTrail(mobj_t *mo);
void K_SpawnWipeoutTrail(mobj_t *mo, boolean translucent);
+13
View File
@@ -538,6 +538,18 @@ static int lib_pFlashPal(lua_State *L)
return 0;
}
// not sure if this is netsafe...
static int lib_pRollPitchMobj(lua_State *L)
{
mobj_t *source = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
NOHUD
if (!source)
return LUA_ErrInvalid(L, "mobj_t");
P_RollPitchMobj(source);
return 0;
}
static int lib_pGetClosestAxis(lua_State *L)
{
mobj_t *source = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
@@ -3033,6 +3045,7 @@ static luaL_Reg lib[] = {
{"P_GetMobjGravity",lib_pGetMobjGravity},
{"P_WeaponOrPanel",lib_pWeaponOrPanel},
{"P_FlashPal",lib_pFlashPal},
{"P_RollPitchMobj",lib_pRollPitchMobj},
{"P_GetClosestAxis",lib_pGetClosestAxis},
{"P_SpawnParaloop",lib_pSpawnParaloop},
{"P_BossTargetPlayer",lib_pBossTargetPlayer},
+6 -1
View File
@@ -83,8 +83,11 @@ static const udata_field_t mobj_fields[] = {
FIELD(mobj_t, snext, udatalib_getter_mobj, mobj_snext_noset),
FIELD(mobj_t, sprev, mobj_sprev_unimplemented, mobj_sprev_unimplemented),
FIELD(mobj_t, angle, udatalib_getter_angle, mobj_angle_setter),
FIELD(mobj_t, pitch, udatalib_getter_angle, udatalib_setter_angle),
FIELD(mobj_t, roll, udatalib_getter_angle, udatalib_setter_angle),
FIELD(mobj_t, rollangle, udatalib_getter_angle, udatalib_setter_angle),
FIELD(mobj_t, sloperoll, udatalib_getter_angle, mobj_sloperoll_noop),
FIELD(mobj_t, slopepitch, udatalib_getter_angle, mobj_sloperoll_noop),
// Macro fails here
{ "rollsum", 0, mobj_rollsum_getter, mobj_rollsum_noset },
FIELD(mobj_t, sprite, udatalib_getter_spritenum, udatalib_setter_spritenum),
@@ -624,7 +627,9 @@ int mobj_rollsum_getter(lua_State *L)
{
mobj_t *mo = GETMO();
angle_t rollsum = mo->rollangle + cv_sloperoll.value ? mo->sloperoll : 0;
angle_t pitchnroll = P_MobjPitchAndRoll(mo);
angle_t rollsum = mo->rollangle + pitchnroll;
if (mo->player)
{
+14 -10
View File
@@ -2005,7 +2005,7 @@ static menuitem_t OP_SaturnMenu[] =
{IT_STRING | IT_CVAR, NULL, "Midnight Channel Flicker Effect", &cv_lessflicker, 95},
{IT_SUBMENU|IT_STRING, NULL, "Player distortion...", &OP_PlayerDistortDef, 105},
{IT_SUBMENU|IT_STRING, NULL, "Sprite Distortion...", &OP_PlayerDistortDef, 105},
{IT_SUBMENU|IT_STRING, NULL, "Hud Offsets...", &OP_HudOffsetDef, 110},
{IT_SUBMENU|IT_STRING, NULL, "Saturn Credits", &OP_SaturnCreditsDef, 120}, // uwu
@@ -2029,7 +2029,7 @@ static const char* OP_SaturnTooltips[] =
"Show the big Cecho Messages.",
"Show Localskin Menus.",
"Disables the flicker effect on Midnight Channel.",
"Options for player distortion effects.",
"Options for sprite distortion effects.",
"Move position of HUD elements.",
"See the people who helped make this project possible!",
};
@@ -2057,13 +2057,14 @@ enum
static menuitem_t OP_PlayerDistortMenu[] =
{
{IT_HEADER, NULL, "Player Distortion", NULL, 0},
{IT_HEADER, NULL, "Sprite Distortion", NULL, 0},
{IT_STRING | IT_CVAR, NULL, "Rotate players on slopes", &cv_sloperoll, 20},
{IT_STRING | IT_CVAR, NULL, "Slope rotation distance", &cv_sloperolldist, 35},
{IT_STRING | IT_CVAR, NULL, "Rotate players when sliptiding", &cv_sliptideroll, 50},
{IT_STRING | IT_CVAR, NULL, "Player stretch factor", &cv_gravstretch, 65},
{IT_STRING | IT_CVAR, NULL, "Squish Sound Effect", &cv_slamsound, 80},
{IT_STRING | IT_CVAR, NULL, "Rotate Objects on Slopes", &cv_sloperoll, 20},
{IT_STRING | IT_CVAR, NULL, "Slope Rotation Distance", &cv_sloperolldist, 35},
{IT_STRING | IT_CVAR, NULL, "Rotate Players when Sliptiding", &cv_sliptideroll, 50},
{IT_STRING | IT_CVAR, NULL, "Rotate Sparks and Boost Trails", &cv_sparkroll, 65},
{IT_STRING | IT_CVAR, NULL, "Player Stretch Factor", &cv_gravstretch, 80},
{IT_STRING | IT_CVAR, NULL, "Squish Sound Effect", &cv_slamsound, 95},
{IT_STRING | IT_CVAR, NULL, "Saltyhop", &cv_saltyhop, 110},
{IT_STRING | IT_CVAR, NULL, "Saltyhop Sound Effect", &cv_saltyhopsfx, 125},
{IT_STRING | IT_CVAR, NULL, "Saltyhop Squish", &cv_saltysquish, 140},
@@ -2072,9 +2073,10 @@ static menuitem_t OP_PlayerDistortMenu[] =
static const char* OP_PlayerDistortTooltips[] =
{
NULL,
"Player rotation on slopes.",
"Distance player rotation should be visable.",
"Object rotation on slopes.",
"Distance object rotation should be visable.",
"Player rotation when sliptiding.",
"Rotation of a player's boost trails and drift sparks.",
"Player squash and stretch.",
"Player landing sound effect.",
"Kart hopping while drifting. This is purely visual.",
@@ -3136,7 +3138,9 @@ void PDistort_menu_Onchange(void)
status = IT_GRAYEDOUT;
}
// enable/disable rolldist and sparkroll options
OP_PlayerDistortMenu[2].status = status;
OP_PlayerDistortMenu[4].status = status;
}
void Bird_menu_Onchange(void)
+100
View File
@@ -6251,6 +6251,84 @@ static void P_KoopaThinker(mobj_t *koopa)
}
}
//
// P_RollPitchMobj
// Assigns slopepitch and sloperoll to objects, and resets said values when slope-rolling
// is turned off completely.
//
void P_RollPitchMobj(mobj_t* mobj)
{
boolean usedist = false;
if (cv_sloperolldist.value > 0)
usedist = true;
if (cv_sloperoll.value == 1)
{
K_RollMobjBySlopes(mobj, usedist);
}
else
{
mobj->sloperoll = FixedAngle(0);
mobj->slopepitch = FixedAngle(0);
}
}
angle_t P_MobjPitchAndRoll(mobj_t *mobj)
{
spritedef_t *sprdef;
spriteframe_t *sprframe;
angle_t ang = 0;
angle_t camang = 0;
angle_t return_angle = 0;
if (P_MobjWasRemoved(mobj))
return 0;
size_t rot = mobj->frame & FF_FRAMEMASK;
boolean papersprite = (mobj->frame & FF_PAPERSPRITE);
if (mobj->skin && mobj->sprite == SPR_PLAY)
{
sprdef = &((skin_t *)mobj->skin)->spritedef;
if (rot >= sprdef->numframes)
sprdef = &sprites[mobj->sprite];
}
else
{
sprdef = &sprites[mobj->sprite];
}
if (rot >= sprdef->numframes)
{
sprdef = &sprites[states[S_UNKNOWN].sprite];
rot = states[S_UNKNOWN].frame&FF_FRAMEMASK;
}
sprframe = &sprdef->spriteframes[rot];
// No sprite frame? I guess it is possible
if (!sprframe) return 0;
if (sprframe->rotate != SRF_SINGLE || papersprite)
{
ang = R_PointToAngle(mobj->x, mobj->y) - mobj->angle;
camang = R_PointToAngle(mobj->x, mobj->y);
}
return_angle = FixedMul(FINECOSINE((ang) >> ANGLETOFINESHIFT), mobj->roll)
+ FixedMul(FINESINE((ang) >> ANGLETOFINESHIFT), mobj->pitch);
if (cv_sloperoll.value)
{
return_angle += FixedMul(FINECOSINE((camang) >> ANGLETOFINESHIFT), mobj->sloperoll)
+ FixedMul(FINESINE((camang) >> ANGLETOFINESHIFT), mobj->slopepitch);
}
return return_angle;
}
//
// P_MobjThinker
//
@@ -6393,6 +6471,12 @@ void P_MobjThinker(mobj_t *mobj)
return;
}
if (mobj->state == &states[S_PLAY_SIGN]) // hack to make the player sign icon roll with the sign itself
{
mobj->slopepitch = mobj->target->slopepitch;
mobj->sloperoll = mobj->target->sloperoll;
}
P_AddOverlay(mobj);
break;
case MT_SHADOW:
@@ -6428,6 +6512,7 @@ void P_MobjThinker(mobj_t *mobj)
P_RemoveMobj(mobj);
return;
}
P_RollPitchMobj(mobj);
break;
case MT_SMOLDERING:
if (leveltime % 2 == 0)
@@ -7856,6 +7941,7 @@ void P_MobjThinker(mobj_t *mobj)
fixed_t distbarrier = 512*mapobjectscale;
fixed_t distaway;
P_RollPitchMobj(mobj);
P_SpawnGhostMobj(mobj);
if (mobj->threshold > 0)
@@ -7923,6 +8009,7 @@ void P_MobjThinker(mobj_t *mobj)
}
else
{
P_RollPitchMobj(mobj);
P_SpawnGhostMobj(mobj);
mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy);
P_InstaThrust(mobj, mobj->angle, mobj->movefactor);
@@ -7956,6 +8043,9 @@ void P_MobjThinker(mobj_t *mobj)
mobj->momx = mobj->momy = 0;
mobj->health = 1;
}
P_RollPitchMobj(mobj);
if (mobj->threshold > 0)
mobj->threshold--;
break;
@@ -8003,6 +8093,8 @@ void P_MobjThinker(mobj_t *mobj)
|| (mobj->state >= &states[S_SSMINE_DEPLOY8] && mobj->state <= &states[S_SSMINE_DEPLOY13]))
A_GrenadeRing(mobj);
P_RollPitchMobj(mobj);
if (mobj->threshold > 0)
mobj->threshold--;
break;
@@ -8355,6 +8447,10 @@ void P_MobjThinker(mobj_t *mobj)
}
}
}
// fancy sign rotation
P_RollPitchMobj(mobj);
break;
case MT_CDUFO:
if (!mobj->spawnpoint || mobj->fuse)
@@ -9535,6 +9631,10 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
mobj->height = info->height;
mobj->flags = info->flags;
mobj->sloperoll = 0;
mobj->slopepitch = 0;
mobj->pitch_sprite = 0;
mobj->roll_sprite = 0;
mobj->health = info->spawnhealth;
+18 -8
View File
@@ -283,9 +283,9 @@ typedef struct mobj_s
struct mobj_s **sprev; // killough 8/11/98: change to ptr-to-ptr
// More drawing info: to determine current sprite.
angle_t angle; // orientation
angle_t old_angle; // orientation interpolation
angle_t old_angle2;
angle_t angle, pitch, roll; // orientation
angle_t old_angle, old_pitch, old_roll; // orientation interpolation
angle_t old_angle2, old_pitch2, old_roll2;
angle_t rollangle;
spritenum_t sprite; // used to find patch_t and flip value
UINT32 frame; // frame number, plus bits see p_pspr.h
@@ -302,7 +302,10 @@ typedef struct mobj_s
fixed_t stretchslam; // "squish" effect when you land
//sloperollangle
angle_t sloperoll, reservezangle, reservexydir;
angle_t sloperoll, slopepitch;
angle_t old_sloperoll, old_slopepitch;
angle_t old_sloperoll2, old_slopepitch2;
angle_t pitch_sprite, roll_sprite;
struct msecnode_s *touching_sectorlist; // a linked list of sectors where this object appears
@@ -433,9 +436,9 @@ typedef struct precipmobj_s
struct precipmobj_s **sprev; // killough 8/11/98: change to ptr-to-ptr
// More drawing info: to determine current sprite.
angle_t angle; // orientation
angle_t old_angle; // orientation interpolation
angle_t old_angle2;
angle_t angle, pitch, roll; // orientation
angle_t old_angle, old_pitch, old_roll; // orientation interpolation
angle_t old_angle2, old_pitch2, old_roll2;
angle_t rollangle;
spritenum_t sprite; // used to find patch_t and flip value
UINT32 frame; // frame number, plus bits see p_pspr.h
@@ -452,7 +455,10 @@ typedef struct precipmobj_s
fixed_t stretchslam; // "squish" effect when you land
//sloperollangle
angle_t sloperoll, reservezangle, reservexydir;
angle_t sloperoll, slopepitch;
angle_t old_sloperoll, old_slopepitch;
angle_t old_sloperoll2, old_slopepitch2;
angle_t pitch_sprite, roll_sprite;
struct mprecipsecnode_s *touching_sectorlist; // a linked list of sectors where this object appears
@@ -494,6 +500,10 @@ void P_AddCachedAction(mobj_t *mobj, INT32 statenum);
// check mobj against water content, before movement code
void P_MobjCheckWater(mobj_t *mobj);
// fancy sprite rotation
void P_RollPitchMobj(mobj_t *mobj);
angle_t P_MobjPitchAndRoll(mobj_t *mobj);
// Player spawn points
void P_SpawnPlayer(INT32 playernum);
void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing);
+8 -2
View File
@@ -1976,9 +1976,15 @@ static void LoadMobjThinker(actionf_p1 thinker)
mobj->thinker.function.acp1 = thinker;
mobj->rollangle = 0;
mobj->pitch = 0;
mobj->roll = 0;
mobj->sloperoll = 0;
mobj->reservexydir = 0;
mobj->reservezangle = 0;
mobj->slopepitch = 0;
mobj->pitch_sprite = 0;
mobj->roll_sprite = 0;
mobj->spritexoffset = mobj->old_spritexoffset = 0;
mobj->spriteyoffset = mobj->old_spriteyoffset = 0;
+8
View File
@@ -1697,11 +1697,15 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj)
else
ghost->angle = mobj->angle;
ghost->pitch = mobj->pitch;
ghost->roll = mobj->roll;
ghost->sprite = mobj->sprite;
ghost->frame = mobj->frame;
ghost->tics = -1;
ghost->frame &= ~FF_TRANSMASK;
ghost->frame |= tr_trans50<<FF_TRANSSHIFT;
ghost->slopepitch = mobj->slopepitch;
ghost->sloperoll = mobj->sloperoll;
ghost->fuse = ghost->info->damage;
@@ -1724,6 +1728,10 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj)
ghost->old_y = mobj->old_y2;
ghost->old_z = mobj->old_z2;
ghost->old_angle = (mobj->player ? mobj->player->old_frameangle2 : mobj->old_angle2);
ghost->old_pitch = mobj->old_pitch2;
ghost->old_roll = mobj->old_roll2;
ghost->old_sloperoll = mobj->old_sloperoll2;
ghost->old_slopepitch = mobj->old_slopepitch2;
return ghost;
}
+29
View File
@@ -282,6 +282,10 @@ void R_InterpolateMobjState(mobj_t *mobj, fixed_t frac, interpmobjstate_t *out)
out->scale = mobj->scale;
out->subsector = mobj->subsector;
out->angle = mobj->player ? mobj->player->frameangle : mobj->angle;
out->pitch = mobj->pitch;
out->roll = mobj->roll;
out->slopepitch = mobj->slopepitch;
out->sloperoll = mobj->sloperoll;
out->spritexscale = mobj->spritexscale;
out->spriteyscale = mobj->spriteyscale;
out->spritexoffset = mobj->spritexoffset;
@@ -313,6 +317,14 @@ void R_InterpolateMobjState(mobj_t *mobj, fixed_t frac, interpmobjstate_t *out)
{
out->angle = mobj->resetinterp ? mobj->angle : R_LerpAngle(mobj->old_angle, mobj->angle, frac);
}
// pitch roll stuff
out->pitch = mobj->resetinterp ? mobj->pitch : R_LerpAngle(mobj->old_pitch, mobj->pitch, frac);
out->roll = mobj->resetinterp ? mobj->roll : R_LerpAngle(mobj->old_roll, mobj->roll, frac);
// and the slope stuff
out->slopepitch = mobj->resetinterp ? mobj->slopepitch : R_LerpAngle(mobj->old_slopepitch, mobj->slopepitch, frac);
out->sloperoll = mobj->resetinterp ? mobj->sloperoll : R_LerpAngle(mobj->old_sloperoll, mobj->sloperoll, frac);
}
void R_InterpolatePrecipMobjState(precipmobj_t *mobj, fixed_t frac, interpmobjstate_t *out)
@@ -755,10 +767,27 @@ void R_ResetMobjInterpolationState(mobj_t *mobj)
mobj->old_z2 = mobj->old_z;
mobj->old_angle2 = mobj->old_angle;
mobj->old_scale2 = mobj->old_scale;
// rotation humor
mobj->old_pitch2 = mobj->old_pitch;
mobj->old_roll2 = mobj->old_roll;
mobj->old_slopepitch2 = mobj->old_slopepitch;
mobj->old_sloperoll2 = mobj->old_sloperoll;
mobj->old_x = mobj->x;
mobj->old_y = mobj->y;
mobj->old_z = mobj->z;
mobj->old_angle = mobj->angle;
// rotation humor, again
// pitch and roll first
mobj->old_pitch = mobj->pitch;
mobj->old_roll = mobj->roll;
mobj->old_slopepitch = mobj->slopepitch;
mobj->old_sloperoll = mobj->sloperoll;
mobj->old_scale = mobj->scale;
mobj->old_spritexscale = mobj->spritexscale;
mobj->old_spriteyscale = mobj->spriteyscale;
+2
View File
@@ -65,6 +65,8 @@ typedef struct {
fixed_t spriteyscale;
fixed_t spritexoffset;
fixed_t spriteyoffset;
angle_t pitch, roll;
angle_t sloperoll, slopepitch;
} interpmobjstate_t;
// Level interpolators
+1
View File
@@ -1957,6 +1957,7 @@ void R_RegisterEngineStuff(void)
CV_RegisterVar(&cv_sloperoll);
CV_RegisterVar(&cv_sliptideroll);
CV_RegisterVar(&cv_sloperolldist);
CV_RegisterVar(&cv_sparkroll);
CV_RegisterVar(&cv_showhud);
CV_RegisterVar(&cv_translucenthud);
+57 -22
View File
@@ -1327,6 +1327,7 @@ static void R_ProjectSprite(mobj_t *thing)
spritecut_e cut = SC_NONE;
angle_t ang = 0; // gcc 4.6 and lower fix
angle_t camang = 0;
fixed_t iscale;
fixed_t scalestep; // toast '16
fixed_t offset, offset2;
@@ -1346,6 +1347,7 @@ static void R_ProjectSprite(mobj_t *thing)
patch_t *rotsprite = NULL;
INT32 rollangle = 0;
angle_t rollsum = 0;
angle_t pitchnroll = 0;
angle_t sliptiderollangle = 0;
#endif
@@ -1446,6 +1448,8 @@ static void R_ProjectSprite(mobj_t *thing)
if (sprframe->rotate != SRF_SINGLE || papersprite)
{
ang = R_PointToAngle (interp.x, interp.y) - interp.angle;
camang = R_PointToAngle (interp.x, interp.y);
if (mirrored)
ang = InvAngle(ang);
if (papersprite)
@@ -1489,31 +1493,62 @@ static void R_ProjectSprite(mobj_t *thing)
spr_topoffset = spritecachedinfo[lump].topoffset;
#ifdef ROTSPRITE
if ((thing->rollangle)||(thing->sloperoll)||(thing->player && thing->player->sliproll))
{
if (thing->player)
{
sliptiderollangle = cv_sliptideroll.value ? thing->player->sliproll*(thing->player->sliptidemem) : 0;
rollsum = (thing->rollangle)+(thing->sloperoll)+FixedMul(FINECOSINE((ang) >> ANGLETOFINESHIFT), sliptiderollangle);
}
else
rollsum = (thing->rollangle)+(thing->sloperoll);
pitchnroll = 0; // set this to 0, non-paper sprites will affect this value
rollangle = R_GetRollAngle(rollsum);
rotsprite = Patch_GetRotatedSprite(sprframe, (thing->frame & FF_FRAMEMASK), rot, flip, false, sprinfo, rollangle);
if (papersprite)
{
if (ang >= ANGLE_180)
{
// Makes Software act much more sane like OpenGL
rollangle = InvAngle(thing->rollangle);
}
else
{
rollangle = thing->rollangle;
}
}
else
{
// this is very messy, but it on-the-fly calculates rotations for all the
// pitch and roll variables
pitchnroll = FixedMul(FINECOSINE((ang) >> ANGLETOFINESHIFT), interp.roll) +
FixedMul(FINESINE((ang) >> ANGLETOFINESHIFT), interp.pitch) +
FixedMul(FINECOSINE((camang) >> ANGLETOFINESHIFT), interp.sloperoll) +
FixedMul(FINESINE((camang) >> ANGLETOFINESHIFT), interp.slopepitch);
if (rotsprite != NULL)
{
spr_width = rotsprite->width << FRACBITS;
spr_height = rotsprite->height << FRACBITS;
spr_offset = rotsprite->leftoffset << FRACBITS;
spr_topoffset = rotsprite->topoffset << FRACBITS;
spr_topoffset += FEETADJUST;
rollangle = thing->rollangle;
}
// flip -> rotate, not rotate -> flip
flip = 0;
}
}
if ((rollangle) || (pitchnroll) || (thing->player && thing->player->sliproll))
{
rollsum = pitchnroll;
if (thing->player)
{
sliptiderollangle =
cv_sliptideroll.value ? thing->player->sliproll * (thing->player->sliptidemem) : 0;
rollsum += thing->rollangle +
FixedMul(FINECOSINE((ang) >> ANGLETOFINESHIFT), sliptiderollangle);
}
else
rollsum += thing->rollangle;
rollangle = R_GetRollAngle(rollsum);
rotsprite = Patch_GetRotatedSprite(
sprframe, (thing->frame & FF_FRAMEMASK), rot, flip, false, sprinfo, rollangle);
if (rotsprite != NULL)
{
spr_width = rotsprite->width << FRACBITS;
spr_height = rotsprite->height << FRACBITS;
spr_offset = rotsprite->leftoffset << FRACBITS;
spr_topoffset = rotsprite->topoffset << FRACBITS;
spr_topoffset += FEETADJUST;
// flip -> rotate, not rotate -> flip
flip = 0;
}
}
#endif
// calculate edges of the shape