diff --git a/src/b_bot.c b/src/b_bot.c index 51dc4d2f2..f83aaa34c 100644 --- a/src/b_bot.c +++ b/src/b_bot.c @@ -127,13 +127,17 @@ static void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) } // Orientation - if ((bot->pflags & (PF_SPINNING|PF_STARTDASH)) || flymode == 2) + if (bot->pflags & (PF_SPINNING|PF_STARTDASH)) { - cmd->angleturn = (sonic->angle - tails->angle) >> FRACBITS; + cmd->angleturn = (sonic->angle - tails->angle) >> 16; // NOT FRACBITS DAMNIT + } + else if (flymode == 2) + { + cmd->angleturn = sonic->player->cmd.angleturn - (tails->angle >> 16); } else { - cmd->angleturn = (ang - tails->angle) >> FRACBITS; + cmd->angleturn = (ang - tails->angle) >> 16; // NOT FRACBITS DAMNIT } // ******** @@ -222,7 +226,7 @@ static void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) { if (dist < followthres && dist > touchdist) // Do positioning { - cmd->angleturn = (ang - tails->angle) >> FRACBITS; + cmd->angleturn = (ang - tails->angle) >> 16; // NOT FRACBITS DAMNIT cmd->forwardmove = 50; spinmode = true; } @@ -230,7 +234,7 @@ static void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) { if (!bmom && (!(bot->pflags & PF_SPINNING) || (bot->dashspeed && bot->pflags & PF_SPINNING))) { - cmd->angleturn = (sonic->angle - tails->angle) >> FRACBITS; + cmd->angleturn = (sonic->angle - tails->angle) >> 16; // NOT FRACBITS DAMNIT spin = true; } spinmode = true; @@ -244,7 +248,7 @@ static void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) if (bot->pflags & PF_SPINNING || !spin_last) { spin = true; - cmd->angleturn = (sonic->angle - tails->angle) >> FRACBITS; + cmd->angleturn = (sonic->angle - tails->angle) >> 16; // NOT FRACBITS DAMNIT cmd->forwardmove = MAXPLMOVE; spinmode = true; } @@ -290,7 +294,7 @@ static void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) else if (dist < followmin) { // Copy inputs - cmd->angleturn = (sonic->angle - tails->angle) >> FRACBITS; + cmd->angleturn = (sonic->angle - tails->angle) >> 16; // NOT FRACBITS DAMNIT bot->drawangle = ang; cmd->forwardmove = 8 * pcmd->forwardmove / 10; cmd->sidemove = 8 * pcmd->sidemove / 10; @@ -358,7 +362,7 @@ void B_BuildTiccmd(player_t *player, ticcmd_t *cmd) } // Bot AI isn't programmed in analog. - CV_SetValue(&cv_analog2, false); + CV_SetValue(&cv_analog[1], false); #ifdef HAVE_BLUA // Let Lua scripts build ticcmds diff --git a/src/command.c b/src/command.c index 2893106dd..0afc07118 100644 --- a/src/command.c +++ b/src/command.c @@ -2114,7 +2114,12 @@ void CV_SaveVariables(FILE *f) // Silly hack for Min/Max vars if (!strcmp(cvar->string, "MAX") || !strcmp(cvar->string, "MIN")) - sprintf(stringtowrite, "%d", cvar->value); + { + if (cvar->flags & CV_FLOAT) + sprintf(stringtowrite, "%f", FIXED_TO_FLOAT(cvar->value)); + else + sprintf(stringtowrite, "%d", cvar->value); + } else strcpy(stringtowrite, cvar->string); diff --git a/src/command.h b/src/command.h index 42bd6eb84..e7371b2fa 100644 --- a/src/command.h +++ b/src/command.h @@ -20,6 +20,15 @@ // Command buffer & command execution //=================================== +/* Lua command registration flags. */ +enum +{ + COM_ADMIN = 1, + COM_SPLITSCREEN = 2, + COM_LOCAL = 4, +}; + +/* Command buffer flags. */ enum { COM_SAFE = 1, diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 98ff3a6f8..46f404f9a 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -4651,9 +4651,9 @@ static void Local_Maketic(INT32 realtics) // and G_MapEventsToControls if (!dedicated) rendergametic = gametic; // translate inputs (keyboard/mouse/joystick) into game controls - G_BuildTiccmd(&localcmds, realtics); + G_BuildTiccmd(&localcmds, realtics, 1); if (splitscreen || botingame) - G_BuildTiccmd2(&localcmds2, realtics); + G_BuildTiccmd(&localcmds2, realtics, 2); localcmds.angleturn |= TICCMD_RECEIVED; } diff --git a/src/d_main.c b/src/d_main.c index 432dfd34f..92492e747 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -832,7 +832,7 @@ void D_StartTitle(void) CV_SetValue(&cv_usemouse, tutorialusemouse); CV_SetValue(&cv_alwaysfreelook, tutorialfreelook); CV_SetValue(&cv_mousemove, tutorialmousemove); - CV_SetValue(&cv_analog, tutorialanalog); + CV_SetValue(&cv_analog[0], tutorialanalog); M_StartMessage("Do you want to \x82save the recommended \x82movement controls?\x80\n\nPress 'Y' or 'Enter' to confirm\nPress 'N' or any key to keep \nyour current controls", M_TutorialSaveControlResponse, MM_YESNO); } diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 19e1f1dad..29e68143c 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -781,6 +781,10 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_fireaxis2); CV_RegisterVar(&cv_firenaxis); CV_RegisterVar(&cv_firenaxis2); + CV_RegisterVar(&cv_deadzone); + CV_RegisterVar(&cv_deadzone2); + CV_RegisterVar(&cv_digitaldeadzone); + CV_RegisterVar(&cv_digitaldeadzone2); // filesrch.c CV_RegisterVar(&cv_addons_option); @@ -819,20 +823,34 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_joyscale2); // Analog Control - CV_RegisterVar(&cv_analog); - CV_RegisterVar(&cv_analog2); - CV_RegisterVar(&cv_useranalog); - CV_RegisterVar(&cv_useranalog2); + CV_RegisterVar(&cv_analog[0]); + CV_RegisterVar(&cv_analog[1]); + CV_RegisterVar(&cv_useranalog[0]); + CV_RegisterVar(&cv_useranalog[1]); // deez New User eXperiences - CV_RegisterVar(&cv_directionchar); - CV_RegisterVar(&cv_directionchar2); + CV_RegisterVar(&cv_directionchar[0]); + CV_RegisterVar(&cv_directionchar[1]); CV_RegisterVar(&cv_autobrake); CV_RegisterVar(&cv_autobrake2); - // Ported from kart - CV_RegisterVar(&cv_deadzone); - CV_RegisterVar(&cv_deadzone2); + // hi here's some new controls + CV_RegisterVar(&cv_cam_shiftfacing[0]); + CV_RegisterVar(&cv_cam_shiftfacing[1]); + CV_RegisterVar(&cv_cam_turnfacing[0]); + CV_RegisterVar(&cv_cam_turnfacing[1]); + CV_RegisterVar(&cv_cam_turnfacingability[0]); + CV_RegisterVar(&cv_cam_turnfacingability[1]); + CV_RegisterVar(&cv_cam_turnfacingspindash[0]); + CV_RegisterVar(&cv_cam_turnfacingspindash[1]); + CV_RegisterVar(&cv_cam_turnfacinginput[0]); + CV_RegisterVar(&cv_cam_turnfacinginput[1]); + CV_RegisterVar(&cv_cam_centertoggle[0]); + CV_RegisterVar(&cv_cam_centertoggle[1]); + CV_RegisterVar(&cv_cam_lockedinput[0]); + CV_RegisterVar(&cv_cam_lockedinput[1]); + CV_RegisterVar(&cv_cam_lockonboss[0]); + CV_RegisterVar(&cv_cam_lockonboss[1]); // s_sound.c CV_RegisterVar(&cv_soundvolume); @@ -1501,9 +1519,9 @@ void SendWeaponPref(void) buf[0] = 0; if (cv_flipcam.value) buf[0] |= 1; - if (cv_analog.value) + if (cv_analog[0].value && cv_directionchar[0].value != 2) buf[0] |= 2; - if (cv_directionchar.value) + if (cv_directionchar[0].value == 1) buf[0] |= 4; if (cv_autobrake.value) buf[0] |= 8; @@ -1517,9 +1535,9 @@ void SendWeaponPref2(void) buf[0] = 0; if (cv_flipcam2.value) buf[0] |= 1; - if (cv_analog2.value) + if (cv_analog[1].value && cv_directionchar[1].value != 2) buf[0] |= 2; - if (cv_directionchar2.value) + if (cv_directionchar[1].value == 1) buf[0] |= 4; if (cv_autobrake2.value) buf[0] |= 8; @@ -1984,7 +2002,7 @@ static void Command_Map_f(void) CV_SetValue(&cv_usemouse, tutorialusemouse); CV_SetValue(&cv_alwaysfreelook, tutorialfreelook); CV_SetValue(&cv_mousemove, tutorialmousemove); - CV_SetValue(&cv_analog, tutorialanalog); + CV_SetValue(&cv_analog[0], tutorialanalog); } tutorialmode = false; // warping takes us out of tutorial mode diff --git a/src/dehacked.c b/src/dehacked.c index 6f39f7545..c8e3a7901 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -9462,6 +9462,10 @@ struct { {"SF_MULTIABILITY",SF_MULTIABILITY}, {"SF_NONIGHTSROTATION",SF_NONIGHTSROTATION}, + // Dashmode constants + {"DASHMODE_THRESHOLD",DASHMODE_THRESHOLD}, + {"DASHMODE_MAX",DASHMODE_MAX}, + // Character abilities! // Primary {"CA_NONE",CA_NONE}, // now slot 0! @@ -9738,6 +9742,11 @@ struct { {"BT_CUSTOM2",BT_CUSTOM2}, // Lua customizable {"BT_CUSTOM3",BT_CUSTOM3}, // Lua customizable + // Lua command registration flags + {"COM_ADMIN",COM_ADMIN}, + {"COM_SPLITSCREEN",COM_SPLITSCREEN}, + {"COM_LOCAL",COM_LOCAL}, + // cvflags_t {"CV_SAVE",CV_SAVE}, {"CV_CALL",CV_CALL}, diff --git a/src/doomstat.h b/src/doomstat.h index 6d1d6eb36..7e961677f 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -140,7 +140,7 @@ extern INT32 tutorialgcs; // which control scheme is loaded? extern INT32 tutorialusemouse; // store cv_usemouse user value extern INT32 tutorialfreelook; // store cv_alwaysfreelook user value extern INT32 tutorialmousemove; // store cv_mousemove user value -extern INT32 tutorialanalog; // store cv_analog user value +extern INT32 tutorialanalog; // store cv_analog[0] user value extern boolean looptitle; diff --git a/src/f_finale.c b/src/f_finale.c index 317a57f3d..bbee48bdc 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -3790,7 +3790,7 @@ void F_ContinueDrawer(void) sprdef = &contskins[n]->sprites[cont_spr2[n][0]];\ sprframe = &sprdef->spriteframes[cont_spr2[n][1]];\ patch = W_CachePatchNum(sprframe->lumppat[cont_spr2[n][2]], PU_PATCH);\ - V_DrawFixedPatch((dx), (dy), FRACUNIT, (sprframe->flip & (1<highresscale, (sprframe->flip & (1< (+JOYAXISRANGE)) retaxis = +JOYAXISRANGE; + + if (!Joystick.bGamepadStyle && axissel > AXISDIGITAL) + { + const INT32 jdeadzone = ((JOYAXISRANGE-1) * cv_digitaldeadzone.value) >> FRACBITS; + if (-jdeadzone < retaxis && retaxis < jdeadzone) + return 0; + } + if (flp) retaxis = -retaxis; //flip it around return retaxis; } @@ -959,10 +1023,21 @@ static INT32 Joy2Axis(axis_input_e axissel) retaxis = -JOYAXISRANGE; if (retaxis > (+JOYAXISRANGE)) retaxis = +JOYAXISRANGE; + + if (!Joystick2.bGamepadStyle && axissel > AXISDIGITAL) + { + const INT32 jdeadzone = ((JOYAXISRANGE-1) * cv_digitaldeadzone2.value) >> FRACBITS; + if (-jdeadzone < retaxis && retaxis < jdeadzone) + return 0; + } + if (flp) retaxis = -retaxis; //flip it around return retaxis; } + +#define PlayerJoyAxis(p, ax) ((p) == 1 ? JoyAxis(ax) : Joy2Axis(ax)) + // Take a magnitude of two axes, and adjust it to take out the deadzone // Will return a value between 0 and JOYAXISRANGE static INT32 G_BasicDeadZoneCalculation(INT32 magnitude, fixed_t deadZone) @@ -1029,6 +1104,7 @@ static void G_HandleAxisDeadZone(UINT8 splitnum, joystickvector2_t *joystickvect } + // // G_BuildTiccmd // Builds a ticcmd from all of the available inputs @@ -1044,61 +1120,118 @@ static fixed_t forwardmove[2] = {25<>16, 50<>16}; static fixed_t sidemove[2] = {25<>16, 50<>16}; // faster! static fixed_t angleturn[3] = {640, 1280, 320}; // + slow turn -void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) +boolean ticcmd_centerviewdown[2]; // For simple controls, lock the camera behind the player +mobj_t *ticcmd_ztargetfocus[2]; // Locking onto an object? +void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) { boolean forcestrafe = false; boolean forcefullinput = false; INT32 tspeed, forward, side, axis, strafeaxis, moveaxis, turnaxis, lookaxis, i; + + joystickvector2_t movejoystickvector, lookjoystickvector; + const INT32 speed = 1; // these ones used for multiple conditions boolean turnleft, turnright, strafelkey, straferkey, movefkey, movebkey, mouseaiming, analogjoystickmove, gamepadjoystickmove, thisjoyaiming; - player_t *player = &players[consoleplayer]; - camera_t *thiscam = &camera; - joystickvector2_t movejoystickvector, lookjoystickvector; + boolean strafeisturn; // Simple controls only + player_t *player = &players[ssplayer == 2 ? secondarydisplayplayer : consoleplayer]; + camera_t *thiscam = ((ssplayer == 1 || player->bot == 2) ? &camera : &camera2); + angle_t *myangle = (ssplayer == 1 ? &localangle : &localangle2); + INT32 *myaiming = (ssplayer == 1 ? &localaiming : &localaiming2); - static INT32 turnheld; // for accelerative turning - static boolean keyboard_look; // true if lookup/down using keyboard - static boolean resetdown; // don't cam reset every frame - static boolean joyaiming; // check the last frame's value if we need to reset the camera + angle_t drawangleoffset = (player->powers[pw_carry] == CR_ROLLOUT) ? ANGLE_180 : 0; + INT32 chasecam, chasefreelook, alwaysfreelook, usejoystick, invertmouse, mousemove; + controlstyle_e controlstyle = G_ControlStyle(ssplayer); + INT32 *mx; INT32 *my; INT32 *mly; - G_CopyTiccmd(cmd, I_BaseTiccmd(), 1); // empty, or external driver + static INT32 turnheld[2]; // for accelerative turning + static boolean keyboard_look[2]; // true if lookup/down using keyboard + static boolean resetdown[2]; // don't cam reset every frame + static boolean joyaiming[2]; // check the last frame's value if we need to reset the camera + + // simple mode vars + static boolean zchange[2]; // only switch z targets once per press + static fixed_t tta_factor[2] = {FRACUNIT, FRACUNIT}; // disables turn-to-angle when manually turning camera until movement happens + boolean centerviewdown = false; + + UINT8 forplayer = ssplayer-1; + + if (ssplayer == 1) + { + chasecam = cv_chasecam.value; + chasefreelook = cv_chasefreelook.value; + alwaysfreelook = cv_alwaysfreelook.value; + usejoystick = cv_usejoystick.value; + invertmouse = cv_invertmouse.value; + mousemove = cv_mousemove.value; + mx = &mousex; + my = &mousey; + mly = &mlooky; + G_CopyTiccmd(cmd, I_BaseTiccmd(), 1); // empty, or external driver + } + else + { + chasecam = cv_chasecam2.value; + chasefreelook = cv_chasefreelook2.value; + alwaysfreelook = cv_alwaysfreelook2.value; + usejoystick = cv_usejoystick2.value; + invertmouse = cv_invertmouse2.value; + mousemove = cv_mousemove2.value; + mx = &mouse2x; + my = &mouse2y; + mly = &mlook2y; + G_CopyTiccmd(cmd, I_BaseTiccmd2(), 1); // empty, or external driver + } + + strafeisturn = controlstyle == CS_SIMPLE && ticcmd_centerviewdown[forplayer] && + ((cv_cam_lockedinput[forplayer].value && !ticcmd_ztargetfocus[forplayer]) || (player->pflags & PF_STARTDASH)) && + !player->climbing && player->powers[pw_carry] != CR_MINECART; // why build a ticcmd if we're paused? // Or, for that matter, if we're being reborn. // ...OR if we're blindfolded. No looking into the floor. if (paused || P_AutoPause() || (gamestate == GS_LEVEL && (player->playerstate == PST_REBORN || ((gametyperules & GTR_TAG) && (leveltime < hidetime * TICRATE) && (player->pflags & PF_TAGIT))))) - { - cmd->angleturn = (INT16)(localangle >> 16); - cmd->aiming = G_ClipAimingPitch(&localaiming); + {//@TODO splitscreen player + cmd->angleturn = (INT16)(*myangle >> 16); + cmd->aiming = G_ClipAimingPitch(myaiming); return; } - turnright = PLAYER1INPUTDOWN(gc_turnright); - turnleft = PLAYER1INPUTDOWN(gc_turnleft); + turnright = PLAYERINPUTDOWN(ssplayer, gc_turnright); + turnleft = PLAYERINPUTDOWN(ssplayer, gc_turnleft); - straferkey = PLAYER1INPUTDOWN(gc_straferight); - strafelkey = PLAYER1INPUTDOWN(gc_strafeleft); - movefkey = PLAYER1INPUTDOWN(gc_forward); - movebkey = PLAYER1INPUTDOWN(gc_backward); + straferkey = PLAYERINPUTDOWN(ssplayer, gc_straferight); + strafelkey = PLAYERINPUTDOWN(ssplayer, gc_strafeleft); + movefkey = PLAYERINPUTDOWN(ssplayer, gc_forward); + movebkey = PLAYERINPUTDOWN(ssplayer, gc_backward); - mouseaiming = (PLAYER1INPUTDOWN(gc_mouseaiming)) ^ - ((cv_chasecam.value && !player->spectator) ? cv_chasefreelook.value : cv_alwaysfreelook.value); - analogjoystickmove = cv_usejoystick.value && !Joystick.bGamepadStyle; - gamepadjoystickmove = cv_usejoystick.value && Joystick.bGamepadStyle; + if (strafeisturn) + { + turnright |= straferkey; + turnleft |= strafelkey; + straferkey = strafelkey = false; + } - thisjoyaiming = (cv_chasecam.value && !player->spectator) ? cv_chasefreelook.value : cv_alwaysfreelook.value; + mouseaiming = (PLAYERINPUTDOWN(ssplayer, gc_mouseaiming)) ^ + ((chasecam && !player->spectator) ? chasefreelook : alwaysfreelook); + analogjoystickmove = usejoystick && !Joystick.bGamepadStyle; + gamepadjoystickmove = usejoystick && Joystick.bGamepadStyle; + + thisjoyaiming = (chasecam && !player->spectator) ? chasefreelook : alwaysfreelook; // Reset the vertical look if we're no longer joyaiming - if (!thisjoyaiming && joyaiming) - localaiming = 0; - joyaiming = thisjoyaiming; + if (!thisjoyaiming && joyaiming[forplayer]) + *myaiming = 0; + joyaiming[forplayer] = thisjoyaiming; - turnaxis = JoyAxis(AXISTURN); - lookaxis = JoyAxis(AXISLOOK); + turnaxis = PlayerJoyAxis(ssplayer, AXISTURN); + if (strafeisturn) + turnaxis += PlayerJoyAxis(ssplayer, AXISSTRAFE); + lookaxis = PlayerJoyAxis(ssplayer, AXISLOOK); lookjoystickvector.xaxis = turnaxis; lookjoystickvector.yaxis = lookaxis; - G_HandleAxisDeadZone(0, &lookjoystickvector); + G_HandleAxisDeadZone(forplayer, &lookjoystickvector); if (gamepadjoystickmove && lookjoystickvector.xaxis != 0) { @@ -1110,17 +1243,17 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) // use two stage accelerative turning // on the keyboard and joystick if (turnleft || turnright) - turnheld += realtics; + turnheld[forplayer] += realtics; else - turnheld = 0; + turnheld[forplayer] = 0; - if (turnheld < SLOWTURNTICS) + if (turnheld[forplayer] < SLOWTURNTICS) tspeed = 2; // slow turn else tspeed = speed; // let movement keys cancel each other out - if (cv_analog.value) // Analog + if (controlstyle == CS_LMAOGALOG) // Analog { if (turnright) cmd->angleturn = (INT16)(cmd->angleturn - angleturn[tspeed]); @@ -1149,7 +1282,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) side += ((lookjoystickvector.xaxis * sidemove[1]) >> 10); } } - else if (cv_analog.value) // Analog + else if (controlstyle == CS_LMAOGALOG) // Analog { if (turnright) cmd->buttons |= BT_CAMRIGHT; @@ -1158,7 +1291,8 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) } else { - if (turnright) + if (turnright && turnleft); + else if (turnright) cmd->angleturn = (INT16)(cmd->angleturn - ((angleturn[tspeed] * cv_cam_turnmultiplier.value)>>FRACBITS)); else if (turnleft) cmd->angleturn = (INT16)(cmd->angleturn + ((angleturn[tspeed] * cv_cam_turnmultiplier.value)>>FRACBITS)); @@ -1168,13 +1302,16 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) // JOYAXISRANGE should be 1023 (divide by 1024) cmd->angleturn = (INT16)(cmd->angleturn - ((((lookjoystickvector.xaxis * angleturn[1]) >> 10) * cv_cam_turnmultiplier.value)>>FRACBITS)); // ANALOG! } + + if (turnright || turnleft || abs(cmd->angleturn) > angleturn[2]) + tta_factor[forplayer] = 0; // suspend turn to angle } - strafeaxis = JoyAxis(AXISSTRAFE); - moveaxis = JoyAxis(AXISMOVE); + strafeaxis = strafeisturn ? 0 : PlayerJoyAxis(ssplayer, AXISSTRAFE); + moveaxis = PlayerJoyAxis(ssplayer, AXISMOVE); movejoystickvector.xaxis = strafeaxis; movejoystickvector.yaxis = moveaxis; - G_HandleAxisDeadZone(0, &movejoystickvector); + G_HandleAxisDeadZone(forplayer, &movejoystickvector); if (gamepadjoystickmove && movejoystickvector.xaxis != 0) { @@ -1192,11 +1329,11 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) // forward with key or button if (movefkey || (gamepadjoystickmove && movejoystickvector.yaxis < 0) || ((player->powers[pw_carry] == CR_NIGHTSMODE) - && (PLAYER1INPUTDOWN(gc_lookup) || (gamepadjoystickmove && lookjoystickvector.yaxis > 0)))) + && (PLAYERINPUTDOWN(ssplayer, gc_lookup) || (gamepadjoystickmove && lookjoystickvector.yaxis > 0)))) forward = forwardmove[speed]; if (movebkey || (gamepadjoystickmove && movejoystickvector.yaxis > 0) || ((player->powers[pw_carry] == CR_NIGHTSMODE) - && (PLAYER1INPUTDOWN(gc_lookdown) || (gamepadjoystickmove && lookjoystickvector.yaxis < 0)))) + && (PLAYERINPUTDOWN(ssplayer, gc_lookdown) || (gamepadjoystickmove && lookjoystickvector.yaxis < 0)))) forward -= forwardmove[speed]; if (analogjoystickmove && movejoystickvector.yaxis != 0) @@ -1209,9 +1346,9 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) if (strafelkey) side -= sidemove[speed]; - if (PLAYER1INPUTDOWN(gc_weaponnext)) + if (PLAYERINPUTDOWN(ssplayer, gc_weaponnext)) cmd->buttons |= BT_WEAPONNEXT; // Next Weapon - if (PLAYER1INPUTDOWN(gc_weaponprev)) + if (PLAYERINPUTDOWN(ssplayer, gc_weaponprev)) cmd->buttons |= BT_WEAPONPREV; // Previous Weapon #if NUM_WEAPONS > 10 @@ -1220,118 +1357,223 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) //use the four avaliable bits to determine the weapon. cmd->buttons &= ~BT_WEAPONMASK; for (i = 0; i < NUM_WEAPONS; ++i) - if (PLAYER1INPUTDOWN(gc_wepslot1 + i)) + if (PLAYERINPUTDOWN(ssplayer, gc_wepslot1 + i)) { cmd->buttons |= (UINT16)(i + 1); break; } // fire with any button/key - axis = JoyAxis(AXISFIRE); - if (PLAYER1INPUTDOWN(gc_fire) || (cv_usejoystick.value && axis > 0)) + axis = PlayerJoyAxis(ssplayer, AXISFIRE); + if (PLAYERINPUTDOWN(ssplayer, gc_fire) || (usejoystick && axis > 0)) cmd->buttons |= BT_ATTACK; // fire normal with any button/key - axis = JoyAxis(AXISFIRENORMAL); - if (PLAYER1INPUTDOWN(gc_firenormal) || (cv_usejoystick.value && axis > 0)) + axis = PlayerJoyAxis(ssplayer, AXISFIRENORMAL); + if (PLAYERINPUTDOWN(ssplayer, gc_firenormal) || (usejoystick && axis > 0)) cmd->buttons |= BT_FIRENORMAL; - if (PLAYER1INPUTDOWN(gc_tossflag)) + if (PLAYERINPUTDOWN(ssplayer, gc_tossflag)) cmd->buttons |= BT_TOSSFLAG; // Lua scriptable buttons - if (PLAYER1INPUTDOWN(gc_custom1)) + if (PLAYERINPUTDOWN(ssplayer, gc_custom1)) cmd->buttons |= BT_CUSTOM1; - if (PLAYER1INPUTDOWN(gc_custom2)) + if (PLAYERINPUTDOWN(ssplayer, gc_custom2)) cmd->buttons |= BT_CUSTOM2; - if (PLAYER1INPUTDOWN(gc_custom3)) + if (PLAYERINPUTDOWN(ssplayer, gc_custom3)) cmd->buttons |= BT_CUSTOM3; // use with any button/key - axis = JoyAxis(AXISSPIN); - if (PLAYER1INPUTDOWN(gc_use) || (cv_usejoystick.value && axis > 0)) + axis = PlayerJoyAxis(ssplayer, AXISSPIN); + if (PLAYERINPUTDOWN(ssplayer, gc_use) || (usejoystick && axis > 0)) cmd->buttons |= BT_USE; - if (PLAYER1INPUTDOWN(gc_camreset)) + // Centerview can be a toggle in simple mode! { - if (camera.chase && !resetdown) - P_ResetCamera(&players[displayplayer], &camera); - resetdown = true; + static boolean last_centerviewdown[2], centerviewhold[2]; // detect taps for toggle behavior + boolean down = PLAYERINPUTDOWN(ssplayer, gc_centerview); + + if (!(controlstyle == CS_SIMPLE && cv_cam_centertoggle[forplayer].value)) + centerviewdown = down; + else + { + if (down && !last_centerviewdown[forplayer]) + centerviewhold[forplayer] = !centerviewhold[forplayer]; + last_centerviewdown[forplayer] = down; + + if (cv_cam_centertoggle[forplayer].value == 2 && !down && !ticcmd_ztargetfocus[forplayer]) + centerviewhold[forplayer] = false; + + centerviewdown = centerviewhold[forplayer]; + } + } + + if (centerviewdown) + { + if (controlstyle == CS_SIMPLE && !ticcmd_centerviewdown[forplayer] && !G_RingSlingerGametype()) + { + CV_SetValue(&cv_directionchar[forplayer], 2); + *myangle = player->mo->angle; + *myaiming = 0; + + if (cv_cam_lockonboss[forplayer].value) + P_SetTarget(&ticcmd_ztargetfocus[forplayer], P_LookForFocusTarget(player, NULL, 0, cv_cam_lockonboss[forplayer].value)); + } + + ticcmd_centerviewdown[forplayer] = true; + } + else if (ticcmd_centerviewdown[forplayer]) + { + if (controlstyle == CS_SIMPLE) + { + P_SetTarget(&ticcmd_ztargetfocus[forplayer], NULL); + CV_SetValue(&cv_directionchar[forplayer], 1); + } + + ticcmd_centerviewdown[forplayer] = false; + } + + if (ticcmd_ztargetfocus[forplayer]) + { + if ( + P_MobjWasRemoved(ticcmd_ztargetfocus[forplayer]) || + !ticcmd_ztargetfocus[forplayer]->health || + (ticcmd_ztargetfocus[forplayer]->flags2 & MF2_FRET) || + (ticcmd_ztargetfocus[forplayer]->type == MT_EGGMOBILE3 && !ticcmd_ztargetfocus[forplayer]->movecount) // Sea Egg is moving around underground and shouldn't be tracked + ) + P_SetTarget(&ticcmd_ztargetfocus[forplayer], NULL); + else + { + mobj_t *newtarget = NULL; + if (zchange[forplayer]) + { + if (!turnleft && !turnright && abs(cmd->angleturn) < angleturn[0]) + zchange[forplayer] = false; + } + else if (turnleft || cmd->angleturn > angleturn[0]) + { + zchange[forplayer] = true; + newtarget = P_LookForFocusTarget(player, ticcmd_ztargetfocus[forplayer], 1, cv_cam_lockonboss[forplayer].value); + } + else if (turnright || cmd->angleturn < -angleturn[0]) + { + zchange[forplayer] = true; + newtarget = P_LookForFocusTarget(player, ticcmd_ztargetfocus[forplayer], -1, cv_cam_lockonboss[forplayer].value); + } + + if (newtarget) + P_SetTarget(&ticcmd_ztargetfocus[forplayer], newtarget); + + // I assume this is netgame-safe because gunslinger spawns this for only the local player...... *sweats intensely* + newtarget = P_SpawnMobj(ticcmd_ztargetfocus[forplayer]->x, ticcmd_ztargetfocus[forplayer]->y, ticcmd_ztargetfocus[forplayer]->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker + P_SetTarget(&newtarget->target, ticcmd_ztargetfocus[forplayer]); + + if (P_AproxDistance( + player->mo->x - ticcmd_ztargetfocus[forplayer]->x, + player->mo->y - ticcmd_ztargetfocus[forplayer]->y + ) > 50*player->mo->scale) + { + INT32 anglediff = R_PointToAngle2(player->mo->x, player->mo->y, ticcmd_ztargetfocus[forplayer]->x, ticcmd_ztargetfocus[forplayer]->y) - *myangle; + const INT32 maxturn = ANG10/2; + anglediff /= 4; + + if (anglediff > maxturn) + anglediff = maxturn; + else if (anglediff < -maxturn) + anglediff = -maxturn; + + *myangle += anglediff; + } + } + } + + if (ticcmd_centerviewdown[forplayer] && controlstyle == CS_SIMPLE) + controlstyle = CS_LEGACY; + + if (PLAYERINPUTDOWN(ssplayer, gc_camreset)) + { + if (thiscam->chase && !resetdown[forplayer]) + P_ResetCamera(&players[ssplayer == 1 ? displayplayer : secondarydisplayplayer], thiscam); + + resetdown[forplayer] = true; } else - resetdown = false; + resetdown[forplayer] = false; + // jump button - axis = JoyAxis(AXISJUMP); - if (PLAYER1INPUTDOWN(gc_jump) || (cv_usejoystick.value && axis > 0)) + axis = PlayerJoyAxis(ssplayer, AXISJUMP); + if (PLAYERINPUTDOWN(ssplayer, gc_jump) || (usejoystick && axis > 0)) cmd->buttons |= BT_JUMP; // player aiming shit, ahhhh... { - INT32 player_invert = cv_invertmouse.value ? -1 : 1; + INT32 player_invert = invertmouse ? -1 : 1; INT32 screen_invert = (player->mo && (player->mo->eflags & MFE_VERTICALFLIP) - && (!camera.chase || player->pflags & PF_FLIPCAM)) //because chasecam's not inverted + && (!thiscam->chase || player->pflags & PF_FLIPCAM)) //because chasecam's not inverted ? -1 : 1; // set to -1 or 1 to multiply + INT32 configlookaxis = ssplayer == 1 ? cv_lookaxis.value : cv_lookaxis2.value; // mouse look stuff (mouse look is not the same as mouse aim) if (mouseaiming) { - keyboard_look = false; + keyboard_look[forplayer] = false; // looking up/down - localaiming += (mlooky<<19)*player_invert*screen_invert; + *myaiming += (*mly<<19)*player_invert*screen_invert; } - if (analogjoystickmove && joyaiming && lookjoystickvector.yaxis != 0 && cv_lookaxis.value != 0) - localaiming += (lookjoystickvector.yaxis<<16) * screen_invert; + if (analogjoystickmove && joyaiming[forplayer] && lookjoystickvector.yaxis != 0 && configlookaxis != 0) + *myaiming += (lookjoystickvector.yaxis<<16) * screen_invert; // spring back if not using keyboard neither mouselookin' - if (!keyboard_look && cv_lookaxis.value == 0 && !joyaiming && !mouseaiming) - localaiming = 0; + if (!keyboard_look[forplayer] && configlookaxis == 0 && !joyaiming[forplayer] && !mouseaiming) + *myaiming = 0; if (!(player->powers[pw_carry] == CR_NIGHTSMODE)) { - if (PLAYER1INPUTDOWN(gc_lookup) || (gamepadjoystickmove && lookjoystickvector.yaxis > 0)) + if (PLAYERINPUTDOWN(ssplayer, gc_lookup) || (gamepadjoystickmove && lookjoystickvector.yaxis < 0)) { - localaiming += KB_LOOKSPEED * screen_invert; - keyboard_look = true; + *myaiming += KB_LOOKSPEED * screen_invert; + keyboard_look[forplayer] = true; } - else if (PLAYER1INPUTDOWN(gc_lookdown) || (gamepadjoystickmove && lookjoystickvector.yaxis < 0)) + else if (PLAYERINPUTDOWN(ssplayer, gc_lookdown) || (gamepadjoystickmove && lookjoystickvector.yaxis > 0)) { - localaiming -= KB_LOOKSPEED * screen_invert; - keyboard_look = true; + *myaiming -= KB_LOOKSPEED * screen_invert; + keyboard_look[forplayer] = true; } - else if (PLAYER1INPUTDOWN(gc_centerview)) - localaiming = 0; + else if (ticcmd_centerviewdown[forplayer]) + *myaiming = 0; } // accept no mlook for network games if (!cv_allowmlook.value) - localaiming = 0; + *myaiming = 0; - cmd->aiming = G_ClipAimingPitch(&localaiming); + cmd->aiming = G_ClipAimingPitch(myaiming); } - if (!mouseaiming && cv_mousemove.value) - forward += mousey; + if (!mouseaiming && mousemove) + forward += *my; if ((!demoplayback && (player->pflags & PF_SLIDING))) // Analog for mouse - side += mousex*2; - else if (cv_analog.value) + side += *mx*2; + else if (controlstyle == CS_LMAOGALOG) { - if (mousex) + if (*mx) { - if (mousex > 0) + if (*mx > 0) cmd->buttons |= BT_CAMRIGHT; else cmd->buttons |= BT_CAMLEFT; } } else - cmd->angleturn = (INT16)(cmd->angleturn - (mousex*8)); + cmd->angleturn = (INT16)(cmd->angleturn - (*mx*8)); - mousex = mousey = mlooky = 0; + *mx = *my = *mly = 0; if (forward > MAXPLMOVE) forward = MAXPLMOVE; @@ -1354,7 +1596,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) } //Silly hack to make 2d mode *somewhat* playable with no chasecam. - if ((twodlevel || (player->mo && player->mo->flags2 & MF2_TWOD)) && !camera.chase) + if ((twodlevel || (player->mo && player->mo->flags2 & MF2_TWOD)) && !thiscam->chase) { INT32 temp = forward; forward = side; @@ -1364,7 +1606,23 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) cmd->forwardmove = (SINT8)(cmd->forwardmove + forward); cmd->sidemove = (SINT8)(cmd->sidemove + side); - if (cv_analog.value) { + if (player->bot == 1) { // Tailsbot for P2 + if (!player->powers[pw_tailsfly] && (cmd->forwardmove || cmd->sidemove || cmd->buttons)) + { + player->bot = 2; // A player-controlled bot. Returns to AI when it respawns. + CV_SetValue(&cv_analog[1], true); + } + else + { + G_CopyTiccmd(cmd, I_BaseTiccmd2(), 1); // empty, or external driver + B_BuildTiccmd(player, cmd); + } + B_HandleFlightIndicator(player); + } + else if (player->bot == 2) + *myangle = localangle; // Fix offset angle for P2-controlled Tailsbot when P2's controls are set to non-Legacy + + if (controlstyle == CS_LMAOGALOG) { if (player->awayviewtics) cmd->angleturn = (INT16)(player->awayviewmobj->angle >> 16); else @@ -1372,12 +1630,87 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) } else { - localangle += (cmd->angleturn<<16); - cmd->angleturn = (INT16)(localangle >> 16); + *myangle += (cmd->angleturn<<16); + cmd->angleturn = (INT16)(*myangle >> 16); + + // Adjust camera angle by player input + if (controlstyle == CS_SIMPLE && !forcestrafe && thiscam->chase && !turnheld[forplayer] && !ticcmd_centerviewdown[forplayer] && !player->climbing && player->powers[pw_carry] != CR_MINECART) + { + fixed_t camadjustfactor = cv_cam_turnfacinginput[forplayer].value; + + if (camadjustfactor) + { + fixed_t sine = FINESINE((R_PointToAngle2(0, 0, player->rmomx, player->rmomy) - localangle)>>ANGLETOFINESHIFT); + fixed_t factor; + + if ((sine > 0) == (cmd->sidemove > 0)) + sine = 0; // Prevent jerking right when braking from going left, or vice versa + + factor = min(40, FixedMul(player->speed, abs(sine))*2 / FRACUNIT); + + *myangle -= cmd->sidemove * factor * camadjustfactor; + } + + if (ticcmd_centerviewdown[forplayer] && (cv_cam_lockedinput[forplayer].value || (player->pflags & PF_STARTDASH))) + cmd->sidemove = 0; + } + + // Adjust camera angle to face player direction, depending on circumstances + // Nothing happens if cam left/right are held, so you can hold both to lock the camera in one direction + if (controlstyle == CS_SIMPLE && !forcestrafe && thiscam->chase && !turnheld[forplayer] && !ticcmd_centerviewdown[forplayer] && player->powers[pw_carry] != CR_MINECART) + { + fixed_t camadjustfactor; + boolean alt = false; // Reduce intensity on diagonals and prevent backwards movement from turning the camera + + if (player->pflags & PF_GLIDING) + camadjustfactor = cv_cam_turnfacingability[forplayer].value/4; + else if (player->pflags & PF_STARTDASH) + camadjustfactor = cv_cam_turnfacingspindash[forplayer].value/4; + else + { + alt = true; + camadjustfactor = cv_cam_turnfacing[forplayer].value/8; + } + + camadjustfactor = FixedMul(camadjustfactor, max(FRACUNIT - player->speed, min(player->speed/18, FRACUNIT))); + + camadjustfactor = FixedMul(camadjustfactor, tta_factor[forplayer]); + + if (tta_factor[forplayer] < FRACUNIT && (cmd->forwardmove || cmd->sidemove || tta_factor[forplayer] >= FRACUNIT/3)) + tta_factor[forplayer] += FRACUNIT>>5; + else if (tta_factor[forplayer] && tta_factor[forplayer] < FRACUNIT/3) + tta_factor[forplayer] -= FRACUNIT>>5; + + if (camadjustfactor) + { + angle_t controlangle; + INT32 anglediff; + + if ((cmd->forwardmove || cmd->sidemove) && !(player->pflags & PF_SPINNING)) + controlangle = (cmd->angleturn<<16) + R_PointToAngle2(0, 0, cmd->forwardmove << FRACBITS, -cmd->sidemove << FRACBITS); + else + controlangle = player->drawangle + drawangleoffset; + + anglediff = controlangle - *myangle; + + if (alt) + { + fixed_t sine = FINESINE((angle_t) (anglediff)>>ANGLETOFINESHIFT); + sine = abs(sine); + + if (abs(anglediff) > ANGLE_90) + sine = max(0, sine*3 - 2*FRACUNIT); // At about 135 degrees, this will stop turning + + anglediff = FixedMul(anglediff, sine); + } + + *myangle += FixedMul(anglediff, camadjustfactor); + } + } } //Reset away view if a command is given. - if ((cmd->forwardmove || cmd->sidemove || cmd->buttons) + if (ssplayer == 1 && (cmd->forwardmove || cmd->sidemove || cmd->buttons) && displayplayer != consoleplayer) { #ifdef HAVE_BLUA @@ -1389,370 +1722,25 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) } } -// like the g_buildticcmd 1 but using mouse2, gamcontrolbis, ... -void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics) -{ - boolean forcestrafe = false; - boolean forcefullinput = false; - INT32 tspeed, forward, side, axis, strafeaxis, moveaxis, turnaxis, lookaxis, i; - const INT32 speed = 1; - // these ones used for multiple conditions - boolean turnleft, turnright, strafelkey, straferkey, movefkey, movebkey, mouseaiming, analogjoystickmove, gamepadjoystickmove, thisjoyaiming; - player_t *player = &players[secondarydisplayplayer]; - camera_t *thiscam = (player->bot == 2 ? &camera : &camera2); - joystickvector2_t movejoystickvector, lookjoystickvector; - - static INT32 turnheld; // for accelerative turning - static boolean keyboard_look; // true if lookup/down using keyboard - static boolean resetdown; // don't cam reset every frame - static boolean joyaiming; // check the last frame's value if we need to reset the camera - - G_CopyTiccmd(cmd, I_BaseTiccmd2(), 1); // empty, or external driver - - //why build a ticcmd if we're paused? - // Or, for that matter, if we're being reborn. - if (paused || P_AutoPause() || player->playerstate == PST_REBORN) - { - cmd->angleturn = (INT16)(localangle2 >> 16); - cmd->aiming = G_ClipAimingPitch(&localaiming2); - return; - } - - turnright = PLAYER2INPUTDOWN(gc_turnright); - turnleft = PLAYER2INPUTDOWN(gc_turnleft); - - straferkey = PLAYER2INPUTDOWN(gc_straferight); - strafelkey = PLAYER2INPUTDOWN(gc_strafeleft); - movefkey = PLAYER2INPUTDOWN(gc_forward); - movebkey = PLAYER2INPUTDOWN(gc_backward); - - mouseaiming = (PLAYER2INPUTDOWN(gc_mouseaiming)) ^ - ((cv_chasecam2.value && !player->spectator) ? cv_chasefreelook2.value : cv_alwaysfreelook2.value); - analogjoystickmove = cv_usejoystick2.value && !Joystick2.bGamepadStyle; - gamepadjoystickmove = cv_usejoystick2.value && Joystick2.bGamepadStyle; - - thisjoyaiming = (cv_chasecam2.value && !player->spectator) ? cv_chasefreelook2.value : cv_alwaysfreelook2.value; - - // Reset the vertical look if we're no longer joyaiming - if (!thisjoyaiming && joyaiming) - localaiming2 = 0; - joyaiming = thisjoyaiming; - - turnaxis = Joy2Axis(AXISTURN); - lookaxis = Joy2Axis(AXISLOOK); - lookjoystickvector.xaxis = turnaxis; - lookjoystickvector.yaxis = lookaxis; - G_HandleAxisDeadZone(1, &lookjoystickvector); - - if (gamepadjoystickmove && lookjoystickvector.xaxis != 0) - { - turnright = turnright || (lookjoystickvector.xaxis > 0); - turnleft = turnleft || (lookjoystickvector.xaxis < 0); - } - forward = side = 0; - - // use two stage accelerative turning - // on the keyboard and joystick - if (turnleft || turnright) - turnheld += realtics; - else - turnheld = 0; - - if (turnheld < SLOWTURNTICS) - tspeed = 2; // slow turn - else - tspeed = speed; - - // let movement keys cancel each other out - if (cv_analog2.value) // Analog - { - if (turnright) - cmd->angleturn = (INT16)(cmd->angleturn - angleturn[tspeed]); - if (turnleft) - cmd->angleturn = (INT16)(cmd->angleturn + angleturn[tspeed]); - } - if (twodlevel - || (player->mo && (player->mo->flags2 & MF2_TWOD)) - || (!demoplayback && (player->pflags & PF_SLIDING))) - forcefullinput = true; - if (twodlevel - || (player->mo && (player->mo->flags2 & MF2_TWOD)) - || player->climbing - || (player->powers[pw_carry] == CR_NIGHTSMODE) - || (player->pflags & (PF_SLIDING|PF_FORCESTRAFE))) // Analog - forcestrafe = true; - if (forcestrafe) // Analog - { - if (turnright) - side += sidemove[speed]; - if (turnleft) - side -= sidemove[speed]; - - if (analogjoystickmove && lookjoystickvector.xaxis != 0) - { - // JOYAXISRANGE is supposed to be 1023 (divide by 1024) - side += ((lookjoystickvector.xaxis * sidemove[1]) >> 10); - } - } - else if (cv_analog2.value) // Analog - { - if (turnright) - cmd->buttons |= BT_CAMRIGHT; - if (turnleft) - cmd->buttons |= BT_CAMLEFT; - } - else - { - if (turnright) - cmd->angleturn = (INT16)(cmd->angleturn - (((angleturn[tspeed]<>FRACBITS)); - else if (turnleft) - cmd->angleturn = (INT16)(cmd->angleturn + (((angleturn[tspeed]<>FRACBITS)); - - if (analogjoystickmove && lookjoystickvector.xaxis != 0) - { - // JOYAXISRANGE should be 1023 (divide by 1024) - cmd->angleturn = (INT16)(cmd->angleturn - ((((lookjoystickvector.xaxis * angleturn[1]) >> 10) * cv_cam2_turnmultiplier.value)>>FRACBITS)); // ANALOG! - } - } - - strafeaxis = Joy2Axis(AXISSTRAFE); - moveaxis = Joy2Axis(AXISMOVE); - movejoystickvector.xaxis = strafeaxis; - movejoystickvector.yaxis = moveaxis; - G_HandleAxisDeadZone(1, &movejoystickvector); - - if (gamepadjoystickmove && movejoystickvector.xaxis != 0) - { - if (movejoystickvector.xaxis > 0) - side += sidemove[speed]; - else if (movejoystickvector.xaxis < 0) - side -= sidemove[speed]; - } - else if (analogjoystickmove && movejoystickvector.xaxis != 0) - { - // JOYAXISRANGE is supposed to be 1023 (divide by 1024) - side += ((movejoystickvector.xaxis * sidemove[1]) >> 10); - } - - // forward with key or button - if (movefkey || (gamepadjoystickmove && movejoystickvector.yaxis < 0) - || ((player->powers[pw_carry] == CR_NIGHTSMODE) - && (PLAYER2INPUTDOWN(gc_lookup) || (gamepadjoystickmove && lookjoystickvector.yaxis > 0)))) - forward = forwardmove[speed]; - if (movebkey || (gamepadjoystickmove && movejoystickvector.yaxis > 0) - || ((player->powers[pw_carry] == CR_NIGHTSMODE) - && (PLAYER2INPUTDOWN(gc_lookdown) || (gamepadjoystickmove && lookjoystickvector.yaxis < 0)))) - forward -= forwardmove[speed]; - - if (analogjoystickmove && movejoystickvector.yaxis != 0) - forward -= ((movejoystickvector.yaxis * forwardmove[1]) >> 10); // ANALOG! - - // some people strafe left & right with mouse buttons - // those people are (still) weird - if (straferkey) - side += sidemove[speed]; - if (strafelkey) - side -= sidemove[speed]; - - if (PLAYER2INPUTDOWN(gc_weaponnext)) - cmd->buttons |= BT_WEAPONNEXT; // Next Weapon - if (PLAYER2INPUTDOWN(gc_weaponprev)) - cmd->buttons |= BT_WEAPONPREV; // Previous Weapon - - //use the four avaliable bits to determine the weapon. - cmd->buttons &= ~BT_WEAPONMASK; - for (i = 0; i < NUM_WEAPONS; ++i) - if (PLAYER2INPUTDOWN(gc_wepslot1 + i)) - { - cmd->buttons |= (UINT16)(i + 1); - break; - } - - // fire with any button/key - axis = Joy2Axis(AXISFIRE); - if (PLAYER2INPUTDOWN(gc_fire) || (cv_usejoystick2.value && axis > 0)) - cmd->buttons |= BT_ATTACK; - - // fire normal with any button/key - axis = Joy2Axis(AXISFIRENORMAL); - if (PLAYER2INPUTDOWN(gc_firenormal) || (cv_usejoystick2.value && axis > 0)) - cmd->buttons |= BT_FIRENORMAL; - - if (PLAYER2INPUTDOWN(gc_tossflag)) - cmd->buttons |= BT_TOSSFLAG; - - // Lua scriptable buttons - if (PLAYER2INPUTDOWN(gc_custom1)) - cmd->buttons |= BT_CUSTOM1; - if (PLAYER2INPUTDOWN(gc_custom2)) - cmd->buttons |= BT_CUSTOM2; - if (PLAYER2INPUTDOWN(gc_custom3)) - cmd->buttons |= BT_CUSTOM3; - - // use with any button/key - axis = Joy2Axis(AXISSPIN); - if (PLAYER2INPUTDOWN(gc_use) || (cv_usejoystick2.value && axis > 0)) - cmd->buttons |= BT_USE; - - if (PLAYER2INPUTDOWN(gc_camreset)) - { - if (camera2.chase && !resetdown) - P_ResetCamera(&players[secondarydisplayplayer], &camera2); - resetdown = true; - } - else - resetdown = false; - - // jump button - axis = Joy2Axis(AXISJUMP); - if (PLAYER2INPUTDOWN(gc_jump) || (cv_usejoystick2.value && axis > 0)) - cmd->buttons |= BT_JUMP; - - // player aiming shit, ahhhh... - { - INT32 player_invert = cv_invertmouse2.value ? -1 : 1; - INT32 screen_invert = - (player->mo && (player->mo->eflags & MFE_VERTICALFLIP) - && (!camera2.chase || player->pflags & PF_FLIPCAM)) //because chasecam's not inverted - ? -1 : 1; // set to -1 or 1 to multiply - - // mouse look stuff (mouse look is not the same as mouse aim) - if (mouseaiming) - { - keyboard_look = false; - - // looking up/down - localaiming2 += (mlook2y<<19)*player_invert*screen_invert; - } - - if (analogjoystickmove && joyaiming && lookjoystickvector.yaxis != 0 && cv_lookaxis2.value != 0) - localaiming2 += (lookjoystickvector.yaxis<<16) * screen_invert; - - // spring back if not using keyboard neither mouselookin' - if (!keyboard_look && cv_lookaxis2.value == 0 && !joyaiming && !mouseaiming) - localaiming2 = 0; - - if (!(player->powers[pw_carry] == CR_NIGHTSMODE)) - { - if (PLAYER2INPUTDOWN(gc_lookup) || (gamepadjoystickmove && lookjoystickvector.yaxis > 0)) - { - localaiming2 += KB_LOOKSPEED * screen_invert; - keyboard_look = true; - } - else if (PLAYER2INPUTDOWN(gc_lookdown) || (gamepadjoystickmove && lookjoystickvector.yaxis < 0)) - { - localaiming2 -= KB_LOOKSPEED * screen_invert; - keyboard_look = true; - } - else if (PLAYER2INPUTDOWN(gc_centerview)) - localaiming2 = 0; - } - - // accept no mlook for network games - if (!cv_allowmlook.value) - localaiming2 = 0; - - cmd->aiming = G_ClipAimingPitch(&localaiming2); - } - - if (!mouseaiming && cv_mousemove2.value) - forward += mouse2y; - - if (player->climbing - || (player->pflags & PF_SLIDING)) // Analog for mouse - side += mouse2x*2; - else if (cv_analog2.value) - { - if (mouse2x) - { - if (mouse2x > 0) - cmd->buttons |= BT_CAMRIGHT; - else - cmd->buttons |= BT_CAMLEFT; - } - } - else - cmd->angleturn = (INT16)(cmd->angleturn - (mouse2x*8)); - - mouse2x = mouse2y = mlook2y = 0; - - if (forward > MAXPLMOVE) - forward = MAXPLMOVE; - else if (forward < -MAXPLMOVE) - forward = -MAXPLMOVE; - if (side > MAXPLMOVE) - side = MAXPLMOVE; - else if (side < -MAXPLMOVE) - side = -MAXPLMOVE; - - // No additional acceleration when moving forward/backward and strafing simultaneously. - // do this AFTER we cap to MAXPLMOVE so people can't find ways to cheese around this. - if (!forcefullinput && forward && side) - { - angle_t angle = R_PointToAngle2(0, 0, side << FRACBITS, forward << FRACBITS); - INT32 maxforward = abs(P_ReturnThrustY(NULL, angle, MAXPLMOVE)); - INT32 maxside = abs(P_ReturnThrustX(NULL, angle, MAXPLMOVE)); - forward = max(min(forward, maxforward), -maxforward); - side = max(min(side, maxside), -maxside); - } - - //Silly hack to make 2d mode *somewhat* playable with no chasecam. - if ((twodlevel || (player->mo && player->mo->flags2 & MF2_TWOD)) && !camera2.chase) - { - INT32 temp = forward; - forward = side; - side = temp; - } - - cmd->forwardmove = (SINT8)(cmd->forwardmove + forward); - cmd->sidemove = (SINT8)(cmd->sidemove + side); - - if (player->bot == 1) { - if (!player->powers[pw_tailsfly] && (cmd->forwardmove || cmd->sidemove || cmd->buttons)) - { - player->bot = 2; // A player-controlled bot. Returns to AI when it respawns. - CV_SetValue(&cv_analog2, true); - } - else - { - G_CopyTiccmd(cmd, I_BaseTiccmd2(), 1); // empty, or external driver - B_BuildTiccmd(player, cmd); - } - B_HandleFlightIndicator(player); - } - - if (cv_analog2.value) { - if (player->awayviewtics) - cmd->angleturn = (INT16)(player->awayviewmobj->angle >> 16); - else - cmd->angleturn = (INT16)(thiscam->angle >> 16); - } - else - { - localangle2 += (cmd->angleturn<<16); - cmd->angleturn = (INT16)(localangle2 >> 16); - } -} - // User has designated that they want // analog ON, so tell the game to stop // fudging with it. static void UserAnalog_OnChange(void) { - if (cv_useranalog.value) - CV_SetValue(&cv_analog, 1); + if (cv_useranalog[0].value) + CV_SetValue(&cv_analog[0], 1); else - CV_SetValue(&cv_analog, 0); + CV_SetValue(&cv_analog[0], 0); } static void UserAnalog2_OnChange(void) { if (botingame) return; - if (cv_useranalog2.value) - CV_SetValue(&cv_analog2, 1); + if (cv_useranalog[1].value) + CV_SetValue(&cv_analog[1], 1); else - CV_SetValue(&cv_analog2, 0); + CV_SetValue(&cv_analog[1], 0); } static void Analog_OnChange(void) @@ -1762,8 +1750,8 @@ static void Analog_OnChange(void) // cameras are not initialized at this point - if (!cv_chasecam.value && cv_analog.value) { - CV_SetValue(&cv_analog, 0); + if (!cv_chasecam.value && cv_analog[0].value) { + CV_SetValue(&cv_analog[0], 0); return; } @@ -1777,8 +1765,8 @@ static void Analog2_OnChange(void) // cameras are not initialized at this point - if (!cv_chasecam2.value && cv_analog2.value) { - CV_SetValue(&cv_analog2, 0); + if (!cv_chasecam2.value && cv_analog[1].value) { + CV_SetValue(&cv_analog[1], 0); return; } @@ -6310,12 +6298,12 @@ void G_BeginRecording(void) buf |= 0x01; pflags |= PF_FLIPCAM; } - if (cv_analog.value) + if (cv_analog[0].value) { buf |= 0x02; pflags |= PF_ANALOGMODE; } - if (cv_directionchar.value) + if (cv_directionchar[0].value) { buf |= 0x04; pflags |= PF_DIRECTIONCHAR; diff --git a/src/g_game.h b/src/g_game.h index cb51faaca..a589a8917 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -68,15 +68,37 @@ extern consvar_t cv_chatwidth, cv_chatnotifications, cv_chatheight, cv_chattime, extern consvar_t cv_crosshair, cv_crosshair2; extern consvar_t cv_invertmouse, cv_alwaysfreelook, cv_chasefreelook, cv_mousemove; 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_directionchar, cv_directionchar2; + +extern consvar_t cv_useranalog[2], cv_analog[2]; +extern consvar_t cv_directionchar[2]; + +typedef enum { + CS_LEGACY, + CS_LMAOGALOG, + CS_STANDARD, + CS_SIMPLE = CS_LMAOGALOG|CS_STANDARD, +} controlstyle_e; +#define G_ControlStyle(ssplayer) (cv_directionchar[(ssplayer)-1].value == 3 ? CS_LMAOGALOG : ((cv_analog[(ssplayer)-1].value ? CS_LMAOGALOG : 0) | (cv_directionchar[(ssplayer)-1].value ? CS_STANDARD : 0))) +#define P_ControlStyle(player) ((((player)->pflags & PF_ANALOGMODE) ? CS_LMAOGALOG : 0) | (((player)->pflags & PF_DIRECTIONCHAR) ? CS_STANDARD : 0)) + extern consvar_t cv_autobrake, cv_autobrake2; -extern consvar_t cv_deadzone, cv_deadzone2; -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_sideaxis,cv_turnaxis,cv_moveaxis,cv_lookaxis,cv_jumpaxis,cv_spinaxis,cv_fireaxis,cv_firenaxis,cv_deadzone,cv_digitaldeadzone; +extern consvar_t cv_sideaxis2,cv_turnaxis2,cv_moveaxis2,cv_lookaxis2,cv_jumpaxis2,cv_spinaxis2,cv_fireaxis2,cv_firenaxis2,cv_deadzone2,cv_digitaldeadzone2; extern consvar_t cv_ghost_bestscore, cv_ghost_besttime, cv_ghost_bestrings, cv_ghost_last, cv_ghost_guest; +// hi here's some new controls +extern consvar_t cv_cam_shiftfacing[2], cv_cam_turnfacing[2], + cv_cam_turnfacingability[2], cv_cam_turnfacingspindash[2], cv_cam_turnfacinginput[2], + cv_cam_centertoggle[2], cv_cam_lockedinput[2], cv_cam_lockonboss[2]; + +typedef enum +{ + LOCK_BOSS = 1<<0, + LOCK_ENEMY = 1<<1, + LOCK_INTERESTS = 1<<2, +} lockassist_e; + + // mouseaiming (looking up/down with the mouse or keyboard) #define KB_LOOKSPEED (1<<25) #define MAXPLMOVE (50) @@ -84,8 +106,10 @@ extern consvar_t cv_ghost_bestscore, cv_ghost_besttime, cv_ghost_bestrings, cv_g // build an internal map name MAPxx from map number const char *G_BuildMapName(INT32 map); -void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics); -void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics); + +extern boolean ticcmd_centerviewdown[2]; // For simple controls, lock the camera behind the player +extern mobj_t *ticcmd_ztargetfocus[2]; // Locking onto an object? +void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer); // copy ticcmd_t to and fro the normal way ticcmd_t *G_CopyTiccmd(ticcmd_t* dest, const ticcmd_t* src, const size_t n); diff --git a/src/g_input.h b/src/g_input.h index d089332c5..f7f952d72 100644 --- a/src/g_input.h +++ b/src/g_input.h @@ -132,6 +132,7 @@ extern INT32 gamecontroldefault[num_gamecontrolschemes][num_gamecontrols][2]; // extern INT32 gamecontrolbisdefault[num_gamecontrolschemes][num_gamecontrols][2]; #define PLAYER1INPUTDOWN(gc) (gamekeydown[gamecontrol[gc][0]] || gamekeydown[gamecontrol[gc][1]]) #define PLAYER2INPUTDOWN(gc) (gamekeydown[gamecontrolbis[gc][0]] || gamekeydown[gamecontrolbis[gc][1]]) +#define PLAYERINPUTDOWN(p, gc) ((p) == 2 ? PLAYER2INPUTDOWN(gc) : PLAYER1INPUTDOWN(gc)) #define num_gcl_tutorial_check 6 #define num_gcl_tutorial_used 8 diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 59504be73..b998b3360 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -127,11 +127,11 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm if (mipmap->colormap) texel = mipmap->colormap[texel]; - // transparent pixel - if (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX) + // If the mipmap is chromakeyed, check if the texel's color + // is equivalent to the chroma key's color index. + alpha = 0xff; + if ((mipmap->flags & TF_CHROMAKEYED) && (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX)) alpha = 0x00; - else - alpha = 0xff; // hope compiler will get this switch out of the loops (dreams...) // gcc do it ! but vcc not ! (why don't use cygwin gcc for win32 ?) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index b9fd60fe4..12dc28cb7 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5503,7 +5503,7 @@ static void HWR_ProjectSprite(mobj_t *thing) spriteinfo_t *sprinfo; size_t lumpoff; unsigned rot; - UINT8 flip; + UINT16 flip; boolean vflip = (!(thing->eflags & MFE_VERTICALFLIP) != !(thing->frame & FF_VERTICALFLIP)); angle_t ang; @@ -5589,12 +5589,7 @@ static void HWR_ProjectSprite(mobj_t *thing) flip = sprframe->flip; // Will only be 0x00 or 0xFF if (papersprite && ang < ANGLE_180) - { - if (flip) - flip = 0; - else - flip = 255; - } + flip ^= 0xFFFF; } else { @@ -5603,6 +5598,11 @@ static void HWR_ProjectSprite(mobj_t *thing) rot = 6; // F7 slot else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left rot = 2; // F3 slot + else if (sprframe->rotate & SRF_3DGE) // 16-angle mode + { + rot = (ang+ANGLE_180+ANGLE_11hh)>>28; + rot = ((rot & 1)<<3)|(rot>>1); + } else // Normal behaviour rot = (ang+ANGLE_202h)>>29; @@ -5611,12 +5611,7 @@ static void HWR_ProjectSprite(mobj_t *thing) flip = sprframe->flip & (1<skin && ((skin_t *)thing->skin)->flags & SF_HIRES) @@ -5631,7 +5626,7 @@ static void HWR_ProjectSprite(mobj_t *thing) if (thing->rollangle) { rollangle = R_GetRollAngle(thing->rollangle); - if (!sprframe->rotsprite.cached[rot]) + if (!(sprframe->rotsprite.cached & (1<sprite, (thing->frame & FF_FRAMEMASK), sprinfo, sprframe, rot, flip); rotsprite = sprframe->rotsprite.patch[rot][rollangle]; if (rotsprite != NULL) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 3800b6ad9..3f0575dd9 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1108,7 +1108,7 @@ boolean HWR_DrawModel(gr_vissprite_t *spr) { sector_t *sector = spr->mobj->subsector->sector; UINT8 lightlevel = 255; - extracolormap_t *colormap = sector->extra_colormap; + extracolormap_t *colormap = NULL; if (sector->numlights) { @@ -1145,6 +1145,7 @@ boolean HWR_DrawModel(gr_vissprite_t *spr) INT32 durs = spr->mobj->state->tics; INT32 tics = spr->mobj->tics; //mdlframe_t *next = NULL; + const boolean papersprite = (spr->mobj->frame & FF_PAPERSPRITE); const UINT8 flip = (UINT8)(!(spr->mobj->eflags & MFE_VERTICALFLIP) != !(spr->mobj->frame & FF_VERTICALFLIP)); spritedef_t *sprdef; spriteframe_t *sprframe; @@ -1361,14 +1362,12 @@ boolean HWR_DrawModel(gr_vissprite_t *spr) sprframe = &sprdef->spriteframes[spr->mobj->frame & FF_FRAMEMASK]; - if (sprframe->rotate) + if (sprframe->rotate || papersprite) { fixed_t anglef = AngleFixed(spr->mobj->angle); if (spr->mobj->player) anglef = AngleFixed(spr->mobj->player->drawangle); - else - anglef = AngleFixed(spr->mobj->angle); p.angley = FIXED_TO_FLOAT(anglef); } diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 97b3b98be..327dbd3df 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -2273,14 +2273,30 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform) EXPORT INT32 HWRAPI(GetTextureUsed) (void) { - FTextureInfo* tmp = gr_cachehead; - INT32 res = 0; + FTextureInfo *tmp = gr_cachehead; + INT32 res = 0; while (tmp) { - res += tmp->height*tmp->width*(screen_depth/8); + // Figure out the correct bytes-per-pixel for this texture + // I don't know which one the game actually _uses_ but this + // follows format2bpp in hw_cache.c + int bpp = 1; + int format = tmp->grInfo.format; + if (format == GR_RGBA) + bpp = 4; + else if (format == GR_TEXFMT_RGB_565 + || format == GR_TEXFMT_ARGB_1555 + || format == GR_TEXFMT_ARGB_4444 + || format == GR_TEXFMT_ALPHA_INTENSITY_88 + || format == GR_TEXFMT_AP_88) + bpp = 2; + + // Add it up! + res += tmp->height*tmp->width*bpp; tmp = tmp->nextmipmap; } + return res; } diff --git a/src/hu_stuff.c b/src/hu_stuff.c index f558b8c0c..c6a92487c 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -2201,10 +2201,14 @@ void HU_Drawer(void) return; // draw the crosshair, not when viewing demos nor with chasecam - if (!automapactive && cv_crosshair.value && !demoplayback && !camera.chase && !players[displayplayer].spectator) + if (!automapactive && cv_crosshair.value && !demoplayback && + (!camera.chase || ticcmd_ztargetfocus[0]) + && !players[displayplayer].spectator) HU_DrawCrosshair(); - if (!automapactive && cv_crosshair2.value && !demoplayback && !camera2.chase && !players[secondarydisplayplayer].spectator) + if (!automapactive && cv_crosshair2.value && !demoplayback && + (!camera2.chase || ticcmd_ztargetfocus[1]) + && !players[secondarydisplayplayer].spectator) HU_DrawCrosshair2(); // draw desynch text diff --git a/src/info.c b/src/info.c index 30f3e96d0..5f1cb8fbe 100644 --- a/src/info.c +++ b/src/info.c @@ -3565,7 +3565,7 @@ state_t states[NUMSTATES] = {SPR_PUMA, FF_FULLBRIGHT|FF_TRANS60|8, 3, {NULL}, 0, 0, S_NULL}, // S_PUMATRAIL4 // Hammer - {SPR_HAMM, FF_ANIMATE, -1, {NULL}, 4, 3, S_NULL}, // S_HAMMER + {SPR_HAMM, FF_ANIMATE, -1, {NULL}, 3, 3, S_NULL}, // S_HAMMER // Koopa {SPR_KOOP, 0, -1, {NULL}, 0, 0, S_NULL}, // S_KOOPA1 diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index 558540829..9c426fad3 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -118,12 +118,12 @@ void COM_Lua_f(void) lua_rawgeti(gL, -1, 2); // push flags from command info table if (lua_isboolean(gL, -1)) - flags = (lua_toboolean(gL, -1) ? 1 : 0); + flags = (lua_toboolean(gL, -1) ? COM_ADMIN : 0); else flags = (UINT8)lua_tointeger(gL, -1); lua_pop(gL, 1); // pop flags - if (flags & 2) // flag 2: splitscreen player command. + if (flags & COM_SPLITSCREEN) // flag 2: splitscreen player command. { if (!splitscreen) { @@ -133,12 +133,12 @@ void COM_Lua_f(void) playernum = secondarydisplayplayer; } - if (netgame) + if (netgame && !( flags & COM_LOCAL ))/* don't send local commands */ { // Send the command through the network UINT8 argc; lua_pop(gL, 1); // pop command info table - if (flags & 1 && !server && !IsPlayerAdmin(playernum)) // flag 1: only server/admin can use this command. + if (flags & COM_ADMIN && !server && !IsPlayerAdmin(playernum)) // flag 1: only server/admin can use this command. { CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n")); return; @@ -158,7 +158,7 @@ void COM_Lua_f(void) WRITEUINT8(p, argc); for (i = 0; i < argc; i++) WRITESTRINGN(p, COM_Argv(i), 255); - if (flags & 2) + if (flags & COM_SPLITSCREEN) SendNetXCmd2(XD_LUACMD, buf, p-buf); else SendNetXCmd(XD_LUACMD, buf, p-buf); @@ -192,7 +192,15 @@ static int lib_comAddCommand(lua_State *L) if (lua_gettop(L) >= 3) { // For the third argument, only take a boolean or a number. lua_settop(L, 3); - if (lua_type(L, 3) != LUA_TBOOLEAN) + if (lua_type(L, 3) == LUA_TBOOLEAN) + { + CONS_Alert(CONS_WARNING, + "Using a boolean for admin commands is " + "deprecated and will be removed.\n" + "Use \"COM_ADMIN\" instead.\n" + ); + } + else luaL_checktype(L, 3, LUA_TNUMBER); } else diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 58af64359..f451944e3 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -468,11 +468,11 @@ static int libd_getSpritePatch(lua_State *L) // convert WAD editor angle numbers (1-8) to internal angle numbers (0-7) // keep 0 the same since we'll make it default to angle 1 (which is internally 0) - // in case somebody didn't know that angle 0 really just maps all 8 angles to the same patch + // in case somebody didn't know that angle 0 really just maps all 8/16 angles to the same patch if (angle != 0) angle--; - if (angle >= 8) // out of range? + if (angle >= ((sprframe->rotate & SRF_3DGE) ? 16 : 8)) // out of range? return 0; // push both the patch and it's "flip" value @@ -563,11 +563,11 @@ static int libd_getSprite2Patch(lua_State *L) // convert WAD editor angle numbers (1-8) to internal angle numbers (0-7) // keep 0 the same since we'll make it default to angle 1 (which is internally 0) - // in case somebody didn't know that angle 0 really just maps all 8 angles to the same patch + // in case somebody didn't know that angle 0 really just maps all 8/16 angles to the same patch if (angle != 0) angle--; - if (angle >= 8) // out of range? + if (angle >= ((sprframe->rotate & SRF_3DGE) ? 16 : 8)) // out of range? return 0; // push both the patch and it's "flip" value diff --git a/src/m_anigif.c b/src/m_anigif.c index f761db143..32fc2746d 100644 --- a/src/m_anigif.c +++ b/src/m_anigif.c @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2013-2016 by Matthew "Inuyasha" Walsh. +// Copyright (C) 2013-2016 by Matthew "Kaito Sinclaire" Walsh. // Copyright (C) 2013 by "Ninji". // Copyright (C) 2013-2019 by Sonic Team Junior. // diff --git a/src/m_anigif.h b/src/m_anigif.h index 592d2cf19..9bdf2cc7f 100644 --- a/src/m_anigif.h +++ b/src/m_anigif.h @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2013-2016 by Matthew "Inuyasha" Walsh. +// Copyright (C) 2013-2016 by Matthew "Kaito Sinclaire" Walsh. // Copyright (C) 2013-2019 by Sonic Team Junior. // // This program is free software distributed under the diff --git a/src/m_cheat.c b/src/m_cheat.c index 58bb2962c..c284acf3e 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -1304,7 +1304,7 @@ void OP_ObjectplaceMovement(player_t *player) { ticcmd_t *cmd = &player->cmd; - if (!player->climbing && (netgame || !cv_analog.value || (player->pflags & PF_SPINNING))) + if (!player->climbing && (netgame || !cv_analog[0].value || (player->pflags & PF_SPINNING))) player->drawangle = player->mo->angle = (cmd->angleturn<<16 /* not FRACBITS */); ticruned++; diff --git a/src/m_cond.c b/src/m_cond.c index 1e761fdb4..08f3fe038 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2012-2016 by Matthew "Inuyasha" Walsh. +// Copyright (C) 2012-2016 by Matthew "Kaito Sinclaire" Walsh. // Copyright (C) 2012-2019 by Sonic Team Junior. // // This program is free software distributed under the diff --git a/src/m_cond.h b/src/m_cond.h index 3ea77145d..f4f017787 100644 --- a/src/m_cond.h +++ b/src/m_cond.h @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2012-2016 by Matthew "Inuyasha" Walsh. +// Copyright (C) 2012-2016 by Matthew "Kaito Sinclaire" Walsh. // Copyright (C) 2012-2019 by Sonic Team Junior. // // This program is free software distributed under the diff --git a/src/m_menu.c b/src/m_menu.c index 63ab21438..1dcd4ef0f 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 2011-2016 by Matthew "Inuyasha" Walsh. +// Copyright (C) 2011-2016 by Matthew "Kaito Sinclaire" Walsh. // Copyright (C) 1999-2019 by Sonic Team Junior. // // This program is free software distributed under the @@ -298,11 +298,14 @@ menu_t OP_MPControlsDef, OP_MiscControlsDef; menu_t OP_P1ControlsDef, OP_P2ControlsDef, OP_MouseOptionsDef; menu_t OP_Mouse2OptionsDef, OP_Joystick1Def, OP_Joystick2Def; menu_t OP_CameraOptionsDef, OP_Camera2OptionsDef; +menu_t OP_PlaystyleDef; static void M_VideoModeMenu(INT32 choice); static void M_Setup1PControlsMenu(INT32 choice); static void M_Setup2PControlsMenu(INT32 choice); static void M_Setup1PJoystickMenu(INT32 choice); static void M_Setup2PJoystickMenu(INT32 choice); +static void M_Setup1PPlaystyleMenu(INT32 choice); +static void M_Setup2PPlaystyleMenu(INT32 choice); static void M_AssignJoystick(INT32 choice); static void M_ChangeControl(INT32 choice); @@ -348,6 +351,9 @@ static void M_DrawLevelStats(void); static void M_DrawTimeAttackMenu(void); static void M_DrawNightsAttackMenu(void); static void M_DrawSetupChoosePlayerMenu(void); +static void M_DrawControlsDefMenu(void); +static void M_DrawCameraOptionsMenu(void); +static void M_DrawPlaystyleMenu(void); static void M_DrawControl(void); static void M_DrawMainVideoMenu(void); static void M_DrawVideoMode(void); @@ -375,6 +381,7 @@ static void M_HandleSoundTest(INT32 choice); static void M_HandleImageDef(INT32 choice); static void M_HandleLoadSave(INT32 choice); static void M_HandleLevelStats(INT32 choice); +static void M_HandlePlaystyleMenu(INT32 choice); #ifndef NONET static boolean M_CancelConnect(void); static void M_HandleConnectIP(INT32 choice); @@ -1040,9 +1047,8 @@ static menuitem_t OP_P1ControlsMenu[] = {IT_SUBMENU | IT_STRING, NULL, "Camera Options...", &OP_CameraOptionsDef, 50}, - //{IT_STRING | IT_CVAR, NULL, "Analog Control", &cv_useranalog, 100}, - {IT_STRING | IT_CVAR, NULL, "Character angle", &cv_directionchar, 70}, - {IT_STRING | IT_CVAR, NULL, "Automatic braking", &cv_autobrake, 80}, + {IT_STRING | IT_CVAR, NULL, "Automatic braking", &cv_autobrake, 70}, + {IT_CALL | IT_STRING, NULL, "Play Style...", M_Setup1PPlaystyleMenu, 80}, }; static menuitem_t OP_P2ControlsMenu[] = @@ -1053,9 +1059,8 @@ static menuitem_t OP_P2ControlsMenu[] = {IT_SUBMENU | IT_STRING, NULL, "Camera Options...", &OP_Camera2OptionsDef, 50}, - //{IT_STRING | IT_CVAR, NULL, "Analog Control", &cv_useranalog2, 100}, - {IT_STRING | IT_CVAR, NULL, "Character angle", &cv_directionchar2, 70}, - {IT_STRING | IT_CVAR, NULL, "Automatic braking", &cv_autobrake2, 80}, + {IT_STRING | IT_CVAR, NULL, "Automatic braking", &cv_autobrake2, 70}, + {IT_CALL | IT_STRING, NULL, "Play Style...", M_Setup2PPlaystyleMenu, 80}, }; static menuitem_t OP_ChangeControlsMenu[] = @@ -1127,8 +1132,8 @@ static menuitem_t OP_Joystick1Menu[] = {IT_STRING | IT_CVAR, NULL, "First-Person Vert-Look", &cv_alwaysfreelook, 120}, {IT_STRING | IT_CVAR, NULL, "Third-Person Vert-Look", &cv_chasefreelook, 130}, - {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, - NULL, "Deadzone", &cv_deadzone, 140 }, + {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Analog Deadzone", &cv_deadzone, 140}, + {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Digital Deadzone", &cv_digitaldeadzone, 150}, }; static menuitem_t OP_Joystick2Menu[] = @@ -1145,8 +1150,8 @@ static menuitem_t OP_Joystick2Menu[] = {IT_STRING | IT_CVAR, NULL, "First-Person Vert-Look", &cv_alwaysfreelook2,120}, {IT_STRING | IT_CVAR, NULL, "Third-Person Vert-Look", &cv_chasefreelook2, 130}, - {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, - NULL, "Deadzone", &cv_deadzone2, 140 }, + {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Analog Deadzone", &cv_deadzone2,140}, + {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Digital Deadzone", &cv_digitaldeadzone2,150}, }; static menuitem_t OP_JoystickSetMenu[1+MAX_JOYSTICKS]; @@ -1183,32 +1188,98 @@ static menuitem_t OP_Mouse2OptionsMenu[] = static menuitem_t OP_CameraOptionsMenu[] = { - {IT_STRING | IT_CVAR, NULL, "Third-person Camera" , &cv_chasecam , 10}, - {IT_STRING | IT_CVAR, NULL, "Flip Camera with Gravity" , &cv_flipcam , 20}, - {IT_STRING | IT_CVAR, NULL, "Orbital Looking" , &cv_cam_orbit , 30}, - {IT_STRING | IT_CVAR, NULL, "Downhill Slope Adjustment", &cv_cam_adjust, 40}, + {IT_HEADER, NULL, "General Toggles", NULL, 0}, + {IT_STRING | IT_CVAR, NULL, "Third-person Camera" , &cv_chasecam , 6}, + {IT_STRING | IT_CVAR, NULL, "Flip Camera with Gravity" , &cv_flipcam , 11}, + {IT_STRING | IT_CVAR, NULL, "Orbital Looking" , &cv_cam_orbit , 16}, + {IT_STRING | IT_CVAR, NULL, "Downhill Slope Adjustment", &cv_cam_adjust, 21}, - {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Distance", &cv_cam_dist, 60}, - {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam_height, 70}, - {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Spacial Speed", &cv_cam_speed, 80}, - {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Turning Speed", &cv_cam_turnmultiplier, 90}, + {IT_HEADER, NULL, "Camera Positioning", NULL, 30}, + {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Distance", &cv_cam_savedist[0][0], 36}, + {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam_saveheight[0][0], 41}, + {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Spacial Speed", &cv_cam_speed, 46}, + {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Rotation Speed", &cv_cam_turnmultiplier, 51}, - {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair, 100}, + {IT_HEADER, NULL, "Display Options", NULL, 60}, + {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair, 66}, }; static menuitem_t OP_Camera2OptionsMenu[] = { - {IT_STRING | IT_CVAR, NULL, "Third-person Camera" , &cv_chasecam2 , 10}, - {IT_STRING | IT_CVAR, NULL, "Flip Camera with Gravity" , &cv_flipcam2 , 20}, - {IT_STRING | IT_CVAR, NULL, "Orbital Looking" , &cv_cam2_orbit , 30}, - {IT_STRING | IT_CVAR, NULL, "Downhill Slope Adjustment", &cv_cam2_adjust, 40}, + {IT_HEADER, NULL, "General Toggles", NULL, 0}, + {IT_STRING | IT_CVAR, NULL, "Third-person Camera" , &cv_chasecam2 , 6}, + {IT_STRING | IT_CVAR, NULL, "Flip Camera with Gravity" , &cv_flipcam2 , 11}, + {IT_STRING | IT_CVAR, NULL, "Orbital Looking" , &cv_cam2_orbit , 16}, + {IT_STRING | IT_CVAR, NULL, "Downhill Slope Adjustment", &cv_cam2_adjust, 21}, - {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Distance", &cv_cam2_dist, 60}, - {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam2_height, 70}, - {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Spacial Speed", &cv_cam2_speed, 80}, - {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Turning Speed", &cv_cam2_turnmultiplier, 90}, + {IT_HEADER, NULL, "Camera Positioning", NULL, 30}, + {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Distance", &cv_cam_savedist[0][1], 36}, + {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam_saveheight[0][1], 41}, + {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Spacial Speed", &cv_cam2_speed, 46}, + {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Rotation Speed", &cv_cam2_turnmultiplier, 51}, - {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair2, 100}, + {IT_HEADER, NULL, "Display Options", NULL, 60}, + {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair2, 66}, +}; + +static menuitem_t OP_CameraExtendedOptionsMenu[] = +{ + {IT_HEADER, NULL, "General Toggles", NULL, 0}, + {IT_STRING | IT_CVAR, NULL, "Third-person Camera" , &cv_chasecam , 6}, + {IT_STRING | IT_CVAR, NULL, "Flip Camera with Gravity" , &cv_flipcam , 11}, + {IT_STRING | IT_CVAR, NULL, "Orbital Looking" , &cv_cam_orbit , 16}, + {IT_STRING | IT_CVAR, NULL, "Downhill Slope Adjustment", &cv_cam_adjust, 21}, + + {IT_HEADER, NULL, "Camera Positioning", NULL, 30}, + {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Distance", &cv_cam_savedist[1][0], 36}, + {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam_saveheight[1][0], 41}, + {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Spacial Speed", &cv_cam_speed, 46}, + {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Rotation Speed", &cv_cam_turnmultiplier, 51}, + + {IT_HEADER, NULL, "Automatic Camera Options", NULL, 60}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Shift to player angle", &cv_cam_shiftfacing[0], 66}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to player angle", &cv_cam_turnfacing[0], 71}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to ability", &cv_cam_turnfacingability[0], 76}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to spindash", &cv_cam_turnfacingspindash[0], 81}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to input", &cv_cam_turnfacinginput[0], 86}, + + {IT_HEADER, NULL, "Locked Camera Options", NULL, 95}, + {IT_STRING | IT_CVAR, NULL, "Lock button behavior", &cv_cam_centertoggle[0], 101}, + {IT_STRING | IT_CVAR, NULL, "Sideways movement", &cv_cam_lockedinput[0], 106}, + {IT_STRING | IT_CVAR, NULL, "Targeting assist", &cv_cam_lockonboss[0], 111}, + + {IT_HEADER, NULL, "Display Options", NULL, 120}, + {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair, 126}, +}; + +static menuitem_t OP_Camera2ExtendedOptionsMenu[] = +{ + {IT_HEADER, NULL, "General Toggles", NULL, 0}, + {IT_STRING | IT_CVAR, NULL, "Third-person Camera" , &cv_chasecam2 , 6}, + {IT_STRING | IT_CVAR, NULL, "Flip Camera with Gravity" , &cv_flipcam2 , 11}, + {IT_STRING | IT_CVAR, NULL, "Orbital Looking" , &cv_cam2_orbit , 16}, + {IT_STRING | IT_CVAR, NULL, "Downhill Slope Adjustment", &cv_cam2_adjust, 21}, + + {IT_HEADER, NULL, "Camera Positioning", NULL, 30}, + {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Distance", &cv_cam_savedist[1][1], 36}, + {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam_saveheight[1][1], 41}, + {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Spacial Speed", &cv_cam2_speed, 46}, + {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Rotation Speed", &cv_cam2_turnmultiplier, 51}, + + {IT_HEADER, NULL, "Automatic Camera Options", NULL, 60}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Shift to player angle", &cv_cam_shiftfacing[1], 66}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to player angle", &cv_cam_turnfacing[1], 71}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to ability", &cv_cam_turnfacingability[1], 76}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to spindash", &cv_cam_turnfacingspindash[1], 81}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to input", &cv_cam_turnfacinginput[1], 86}, + + {IT_HEADER, NULL, "Locked Camera Options", NULL, 95}, + {IT_STRING | IT_CVAR, NULL, "Lock button behavior", &cv_cam_centertoggle[1], 101}, + {IT_STRING | IT_CVAR, NULL, "Sideways movement", &cv_cam_lockedinput[1], 106}, + {IT_STRING | IT_CVAR, NULL, "Targeting assist", &cv_cam_lockonboss[1], 111}, + + {IT_HEADER, NULL, "Display Options", NULL, 120}, + {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair2, 126}, }; static menuitem_t OP_VideoOptionsMenu[] = @@ -1927,12 +1998,24 @@ menu_t OP_MainDef = DEFAULTMENUSTYLE( menu_t OP_ChangeControlsDef = CONTROLMENUSTYLE( MN_OP_MAIN + (MN_OP_CHANGECONTROLS << 12), // second level (<<6) set on runtime OP_ChangeControlsMenu, &OP_MainDef); -menu_t OP_P1ControlsDef = DEFAULTMENUSTYLE( + +menu_t OP_P1ControlsDef = { MN_OP_MAIN + (MN_OP_P1CONTROLS << 6), - "M_CONTRO", OP_P1ControlsMenu, &OP_MainDef, 50, 30); -menu_t OP_P2ControlsDef = DEFAULTMENUSTYLE( + "M_CONTRO", + sizeof(OP_P1ControlsMenu)/sizeof(menuitem_t), + &OP_MainDef, + OP_P1ControlsMenu, + M_DrawControlsDefMenu, + 50, 30, 0, NULL}; +menu_t OP_P2ControlsDef = { MN_OP_MAIN + (MN_OP_P2CONTROLS << 6), - "M_CONTRO", OP_P2ControlsMenu, &OP_MainDef, 50, 30); + "M_CONTRO", + sizeof(OP_P2ControlsMenu)/sizeof(menuitem_t), + &OP_MainDef, + OP_P2ControlsMenu, + M_DrawControlsDefMenu, + 50, 30, 0, NULL}; + menu_t OP_MouseOptionsDef = DEFAULTMENUSTYLE( MN_OP_MAIN + (MN_OP_P1CONTROLS << 6) + (MN_OP_P1MOUSE << 12), "M_CONTRO", OP_MouseOptionsMenu, &OP_P1ControlsDef, 35, 30); @@ -1957,12 +2040,41 @@ menu_t OP_JoystickSetDef = 0, NULL }; -menu_t OP_CameraOptionsDef = DEFAULTMENUSTYLE( + +menu_t OP_CameraOptionsDef = { MN_OP_MAIN + (MN_OP_P1CONTROLS << 6) + (MN_OP_P1CAMERA << 12), - "M_CONTRO", OP_CameraOptionsMenu, &OP_P1ControlsDef, 35, 30); -menu_t OP_Camera2OptionsDef = DEFAULTMENUSTYLE( + "M_CONTRO", + sizeof (OP_CameraOptionsMenu)/sizeof (menuitem_t), + &OP_P1ControlsDef, + OP_CameraOptionsMenu, + M_DrawCameraOptionsMenu, + 35, 30, + 0, + NULL +}; +menu_t OP_Camera2OptionsDef = { MN_OP_MAIN + (MN_OP_P2CONTROLS << 6) + (MN_OP_P2CAMERA << 12), - "M_CONTRO", OP_Camera2OptionsMenu, &OP_P2ControlsDef, 35, 30); + "M_CONTRO", + sizeof (OP_Camera2OptionsMenu)/sizeof (menuitem_t), + &OP_P2ControlsDef, + OP_Camera2OptionsMenu, + M_DrawCameraOptionsMenu, + 35, 30, + 0, + NULL +}; + +static menuitem_t OP_PlaystyleMenu[] = {{IT_KEYHANDLER | IT_NOTHING, NULL, "", M_HandlePlaystyleMenu, 0}}; + +menu_t OP_PlaystyleDef = { + MN_OP_MAIN + (MN_OP_P1CONTROLS << 6) + (MN_OP_PLAYSTYLE << 12), + NULL, + 1, + &OP_P1ControlsDef, + OP_PlaystyleMenu, + M_DrawPlaystyleMenu, + 0, 0, 0, NULL +}; menu_t OP_VideoOptionsDef = @@ -3079,7 +3191,7 @@ boolean M_Responder(event_t *ev) } else if (ev->type == ev_joystick && ev->data1 == 0 && joywait < I_GetTime()) { - const INT32 jdeadzone = (JOYAXISRANGE * cv_deadzone.value) / FRACUNIT; + const INT32 jdeadzone = (JOYAXISRANGE * cv_digitaldeadzone.value) / FRACUNIT; if (ev->data3 != INT32_MAX) { if (Joystick.bGamepadStyle || abs(ev->data3) > jdeadzone) @@ -4197,6 +4309,102 @@ static void M_DrawGenericMenu(void) } } +const char *PlaystyleNames[4] = {"Legacy", "Standard", "Simple", "Old Analog??"}; +const char *PlaystyleDesc[4] = { + // Legacy + "The play style used for\n" + "old-school SRB2.\n" + "\n" + "This play style is identical\n" + "to Standard, except that the\n" + "player always looks in the\n" + "direction of the camera." + , + + // Standard + "The default play style,\n" + "designed for full control\n" + "with a keyboard and mouse.\n" + "\n" + "The camera rotates only when\n" + "you tell it to. The player\n" + "looks in the direction they're\n" + "moving, but acts in the direction\n" + "the camera is facing.\n" + "\n" + "Mastery of this play style will\n" + "open up the highest level of play!" + , + + // Simple + "A play style designed for\n" + "gamepads and hassle-free play.\n" + "\n" + "The camera rotates automatically\n" + "as you move, and the player faces\n" + "and acts in the direction\n" + "they're moving.\n" + "\n" + "Hold \x82" "Center View\x80 to lock the\n" + "camera behind the player!\n" + , + + // Old Analog + "I see.\n" + "\n" + "You really liked the old analog mode,\n" + "so when 2.2 came out, you opened up\n" + "your config file and brought it back.\n" + "\n" + "That's absolutely valid, but I implore\n" + "you to try the new Simple play style\n" + "instead!" +}; + +static UINT8 playstyle_activeplayer = 0, playstyle_currentchoice = 0; + +static void M_DrawControlsDefMenu(void) +{ + UINT8 opt = 0; + + M_DrawGenericMenu(); + + if (currentMenu == &OP_P1ControlsDef) + { + opt = cv_directionchar[0].value ? 1 : 0; + opt = playstyle_currentchoice = cv_useranalog[0].value ? 3 - opt : opt; + + if (opt == 2) + { + OP_CameraOptionsDef.menuitems = OP_CameraExtendedOptionsMenu; + OP_CameraOptionsDef.numitems = sizeof (OP_CameraExtendedOptionsMenu) / sizeof (menuitem_t); + } + else + { + OP_CameraOptionsDef.menuitems = OP_CameraOptionsMenu; + OP_CameraOptionsDef.numitems = sizeof (OP_CameraOptionsMenu) / sizeof (menuitem_t); + } + } + else + { + opt = cv_directionchar[1].value ? 1 : 0; + opt = playstyle_currentchoice = cv_useranalog[1].value ? 3 - opt : opt; + + if (opt == 2) + { + OP_Camera2OptionsDef.menuitems = OP_Camera2ExtendedOptionsMenu; + OP_Camera2OptionsDef.numitems = sizeof (OP_Camera2ExtendedOptionsMenu) / sizeof (menuitem_t); + } + else + { + OP_Camera2OptionsDef.menuitems = OP_Camera2OptionsMenu; + OP_Camera2OptionsDef.numitems = sizeof (OP_Camera2OptionsMenu) / sizeof (menuitem_t); + } + } + + V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + 80, V_YELLOWMAP, PlaystyleNames[opt]); +} + #define scrollareaheight 72 // note that alphakey is multiplied by 2 for scrolling menus to allow greater usage in UINT8 range. @@ -4208,7 +4416,9 @@ static void M_DrawGenericScrollMenu(void) x = currentMenu->x; y = currentMenu->y; - if ((currentMenu->menuitems[itemOn].alphaKey*2 - currentMenu->menuitems[0].alphaKey*2) <= scrollareaheight) + if (currentMenu->menuitems[currentMenu->numitems-1].alphaKey < scrollareaheight) + tempcentery = currentMenu->y; // Not tall enough to scroll, but this thinker is used in case it becomes so + else if ((currentMenu->menuitems[itemOn].alphaKey*2 - currentMenu->menuitems[0].alphaKey*2) <= scrollareaheight) tempcentery = currentMenu->y - currentMenu->menuitems[0].alphaKey*2; else if ((currentMenu->menuitems[currentMenu->numitems-1].alphaKey*2 - currentMenu->menuitems[itemOn].alphaKey*2) <= scrollareaheight) tempcentery = currentMenu->y - currentMenu->menuitems[currentMenu->numitems-1].alphaKey*2 + 2*scrollareaheight; @@ -7644,7 +7854,7 @@ void M_TutorialSaveControlResponse(INT32 ch) CV_Set(&cv_usemouse, cv_usemouse.defaultvalue); CV_Set(&cv_alwaysfreelook, cv_alwaysfreelook.defaultvalue); CV_Set(&cv_mousemove, cv_mousemove.defaultvalue); - CV_Set(&cv_analog, cv_analog.defaultvalue); + CV_Set(&cv_analog[0], cv_analog[0].defaultvalue); S_StartSound(NULL, sfx_itemup); } else @@ -7662,13 +7872,13 @@ static void M_TutorialControlResponse(INT32 ch) tutorialusemouse = cv_usemouse.value; tutorialfreelook = cv_alwaysfreelook.value; tutorialmousemove = cv_mousemove.value; - tutorialanalog = cv_analog.value; + tutorialanalog = cv_analog[0].value; G_CopyControls(gamecontrol, gamecontroldefault[tutorialgcs], gcl_tutorial_full, num_gcl_tutorial_full); CV_Set(&cv_usemouse, cv_usemouse.defaultvalue); CV_Set(&cv_alwaysfreelook, cv_alwaysfreelook.defaultvalue); CV_Set(&cv_mousemove, cv_mousemove.defaultvalue); - CV_Set(&cv_analog, cv_analog.defaultvalue); + CV_Set(&cv_analog[0], cv_analog[0].defaultvalue); //S_StartSound(NULL, sfx_itemup); } @@ -11575,6 +11785,88 @@ static void M_ChangeControl(INT32 choice) M_StartMessage(tmp, M_ChangecontrolResponse, MM_EVENTHANDLER); } +static void M_Setup1PPlaystyleMenu(INT32 choice) +{ + (void)choice; + + playstyle_activeplayer = 0; + OP_PlaystyleDef.prevMenu = &OP_P1ControlsDef; + M_SetupNextMenu(&OP_PlaystyleDef); +} + +static void M_Setup2PPlaystyleMenu(INT32 choice) +{ + (void)choice; + + playstyle_activeplayer = 1; + OP_PlaystyleDef.prevMenu = &OP_P2ControlsDef; + M_SetupNextMenu(&OP_PlaystyleDef); +} + +static void M_DrawPlaystyleMenu(void) +{ + size_t i; + + for (i = 0; i < 4; i++) + { + if (i != 3) + V_DrawCenteredString((i+1)*BASEVIDWIDTH/4, 20, (i == playstyle_currentchoice) ? V_YELLOWMAP : 0, PlaystyleNames[i]); + + if (i == playstyle_currentchoice) + { + V_DrawScaledPatch((i+1)*BASEVIDWIDTH/4 - 8, 10, 0, W_CachePatchName("M_CURSOR", PU_CACHE)); + V_DrawString(30, 50, V_ALLOWLOWERCASE, PlaystyleDesc[i]); + } + } +} + +static void M_HandlePlaystyleMenu(INT32 choice) +{ + switch (choice) + { + case KEY_ESCAPE: + case KEY_BACKSPACE: + M_SetupNextMenu(currentMenu->prevMenu); + break; + + case KEY_ENTER: + S_StartSound(NULL, sfx_menu1); + CV_SetValue((playstyle_activeplayer ? &cv_directionchar[1] : &cv_directionchar[0]), playstyle_currentchoice ? 1 : 0); + CV_SetValue((playstyle_activeplayer ? &cv_useranalog[1] : &cv_useranalog[0]), playstyle_currentchoice/2); + + if (playstyle_activeplayer) + CV_UpdateCam2Dist(); + else + CV_UpdateCamDist(); + + M_SetupNextMenu(currentMenu->prevMenu); + break; + + case KEY_LEFTARROW: + S_StartSound(NULL, sfx_menu1); + playstyle_currentchoice = (playstyle_currentchoice+2)%3; + break; + + case KEY_RIGHTARROW: + S_StartSound(NULL, sfx_menu1); + playstyle_currentchoice = (playstyle_currentchoice+1)%3; + break; + } +} + +static void M_DrawCameraOptionsMenu(void) +{ + M_DrawGenericScrollMenu(); + + if (gamestate == GS_LEVEL && (paused || P_AutoPause())) + { + if (currentMenu == &OP_Camera2OptionsDef && splitscreen && camera2.chase) + P_MoveChaseCamera(&players[secondarydisplayplayer], &camera2, false); + if (currentMenu == &OP_CameraOptionsDef && camera.chase) + P_MoveChaseCamera(&players[displayplayer], &camera, false); + } +} + // =============== // VIDEO MODE MENU // =============== diff --git a/src/m_menu.h b/src/m_menu.h index 48a4ba6f0..a563a18dc 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 2011-2016 by Matthew "Inuyasha" Walsh. +// Copyright (C) 2011-2016 by Matthew "Kaito Sinclaire" Walsh. // Copyright (C) 1999-2019 by Sonic Team Junior. // // This program is free software distributed under the @@ -81,6 +81,8 @@ typedef enum MN_OP_P2JOYSTICK, MN_OP_P2CAMERA, + MN_OP_PLAYSTYLE, + MN_OP_VIDEO, MN_OP_VIDEOMODE, MN_OP_COLOR, diff --git a/src/m_misc.c b/src/m_misc.c index edb24ab1e..a5091c257 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -600,12 +600,12 @@ void M_SaveConfig(const char *filename) CV_SetValue(&cv_usemouse, tutorialusemouse); CV_SetValue(&cv_alwaysfreelook, tutorialfreelook); CV_SetValue(&cv_mousemove, tutorialmousemove); - CV_SetValue(&cv_analog, tutorialanalog); + CV_SetValue(&cv_analog[0], tutorialanalog); CV_SaveVariables(f); CV_Set(&cv_usemouse, cv_usemouse.defaultvalue); CV_Set(&cv_alwaysfreelook, cv_alwaysfreelook.defaultvalue); CV_Set(&cv_mousemove, cv_mousemove.defaultvalue); - CV_Set(&cv_analog, cv_analog.defaultvalue); + CV_Set(&cv_analog[0], cv_analog[0].defaultvalue); } else CV_SaveVariables(f); diff --git a/src/m_random.c b/src/m_random.c index 8a7b62b19..8fd0e1e4e 100644 --- a/src/m_random.c +++ b/src/m_random.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 2012-2016 by Matthew "Inuyasha" Walsh. +// Copyright (C) 2012-2016 by Matthew "Kaito Sinclaire" Walsh. // Copyright (C) 1999-2019 by Sonic Team Junior. // // This program is free software distributed under the diff --git a/src/m_random.h b/src/m_random.h index fb14249bc..5efd3e02c 100644 --- a/src/m_random.h +++ b/src/m_random.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 2012-2016 by Matthew "Inuyasha" Walsh. +// Copyright (C) 2012-2016 by Matthew "Kaito Sinclaire" Walsh. // Copyright (C) 1999-2019 by Sonic Team Junior. // // This program is free software distributed under the diff --git a/src/p_enemy.c b/src/p_enemy.c index ce201844f..bd7b81d40 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -14603,12 +14603,9 @@ void A_RolloutRock(mobj_t *actor) if (!actor->tracer || P_MobjWasRemoved(actor->tracer) || !actor->tracer->health) actor->flags |= MF_PUSHABLE; - if (!(actor->flags & MF_PUSHABLE)) // if being ridden, don't disappear - actor->fuse = 0; - else if (!actor->fuse && actor->movecount == 1) // otherwise if rock has moved, set its fuse + if (!(actor->flags & MF_PUSHABLE) || (actor->movecount != 1)) // if being ridden or haven't moved, don't disappear actor->fuse = actor->info->painchance; - - if (actor->fuse && actor->fuse < 2*TICRATE) + else if (actor->fuse < 2*TICRATE) actor->flags2 ^= MF2_DONTDRAW; } diff --git a/src/p_local.h b/src/p_local.h index 88deb0942..a5f3d313c 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -120,6 +120,10 @@ extern consvar_t cv_cam_speed, cv_cam_rotate, cv_cam_rotspeed, cv_cam_turnmultip extern consvar_t cv_cam2_dist, cv_cam2_still, cv_cam2_height; extern consvar_t cv_cam2_speed, cv_cam2_rotate, cv_cam2_rotspeed, cv_cam2_turnmultiplier, cv_cam2_orbit, cv_cam2_adjust; +extern consvar_t cv_cam_savedist[2][2], cv_cam_saveheight[2][2]; +void CV_UpdateCamDist(void); +void CV_UpdateCam2Dist(void); + extern fixed_t t_cam_dist, t_cam_height, t_cam_rotate; extern fixed_t t_cam2_dist, t_cam2_height, t_cam2_rotate; @@ -181,16 +185,14 @@ fixed_t P_ReturnThrustX(mobj_t *mo, angle_t angle, fixed_t move); fixed_t P_ReturnThrustY(mobj_t *mo, angle_t angle, fixed_t move); void P_InstaThrustEvenIn2D(mobj_t *mo, angle_t angle, fixed_t move); +mobj_t *P_LookForFocusTarget(player_t *player, mobj_t *exclude, SINT8 direction, UINT8 lockonflags); + mobj_t *P_LookForEnemies(player_t *player, boolean nonenemies, boolean bullet); void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius); boolean P_HomingAttack(mobj_t *source, mobj_t *enemy); /// \todo doesn't belong in p_user boolean P_SuperReady(player_t *player); void P_DoJump(player_t *player, boolean soundandstate); -#if 0 -boolean P_AnalogMove(player_t *player); -#else -#define P_AnalogMove(player) (player->pflags & PF_ANALOGMODE) -#endif +#define P_AnalogMove(player) (P_ControlStyle(player) == CS_LMAOGALOG) boolean P_TransferToNextMare(player_t *player); UINT8 P_FindLowestMare(void); void P_FindEmerald(void); diff --git a/src/p_map.c b/src/p_map.c index a522418f7..40fee7b46 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -377,7 +377,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) { object->angle = object->player->drawangle = spring->angle; - if (!demoplayback || P_AnalogMove(object->player)) + if (!demoplayback || P_ControlStyle(object->player) == CS_LMAOGALOG) { if (object->player == &players[consoleplayer]) localangle = spring->angle; @@ -426,7 +426,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) object->player->pflags |= pflags; object->player->secondjump = secondjump; } - else if (object->player->dashmode >= 3*TICRATE) + else if (object->player->dashmode >= DASHMODE_THRESHOLD) P_SetPlayerMobjState(object, S_PLAY_DASH); else if (P_IsObjectOnGround(object) && horizspeed >= FixedMul(object->player->runspeed, object->scale)) P_SetPlayerMobjState(object, S_PLAY_RUN); @@ -632,7 +632,7 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails) && P_MobjFlip(tails->mo)*sonic->mo->momz <= 0) { if (sonic-players == consoleplayer && botingame) - CV_SetValue(&cv_analog2, false); + CV_SetValue(&cv_analog[1], false); P_ResetPlayer(sonic); P_SetTarget(&sonic->mo->tracer, tails->mo); sonic->powers[pw_carry] = CR_PLAYER; @@ -644,7 +644,7 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails) } else { if (sonic-players == consoleplayer && botingame) - CV_SetValue(&cv_analog2, true); + CV_SetValue(&cv_analog[1], true); P_SetTarget(&sonic->mo->tracer, NULL); sonic->powers[pw_carry] = CR_NONE; } @@ -806,7 +806,7 @@ static boolean PIT_CheckThing(mobj_t *thing) // SF_DASHMODE users destroy spikes and monitors, CA_TWINSPIN users and CA2_MELEE users destroy spikes. if ((tmthing->player) - && (((tmthing->player->charflags & SF_DASHMODE) && (tmthing->player->dashmode >= 3*TICRATE) + && ((((tmthing->player->charflags & (SF_DASHMODE|SF_MACHINE)) == (SF_DASHMODE|SF_MACHINE)) && (tmthing->player->dashmode >= DASHMODE_THRESHOLD) && (thing->flags & (MF_MONITOR) || (thing->type == MT_SPIKE || thing->type == MT_WALLSPIKE))) @@ -1327,7 +1327,7 @@ static boolean PIT_CheckThing(mobj_t *thing) thing->angle = tmthing->angle; - if (!demoplayback || P_AnalogMove(thing->player)) + if (!demoplayback || P_ControlStyle(thing->player) == CS_LMAOGALOG) { if (thing->player == &players[consoleplayer]) localangle = thing->angle; @@ -1626,7 +1626,7 @@ static boolean PIT_CheckThing(mobj_t *thing) } else if (thing->player) { if (thing->player-players == consoleplayer && botingame) - CV_SetValue(&cv_analog2, true); + CV_SetValue(&cv_analog[1], true); if (thing->player->powers[pw_carry] == CR_PLAYER) { P_SetTarget(&thing->tracer, NULL); @@ -2005,7 +2005,7 @@ static boolean PIT_CheckLine(line_t *ld) if (lowfloor < tmdropoffz) tmdropoffz = lowfloor; - + return true; } @@ -3509,7 +3509,7 @@ isblocking: && canclimb) { slidemo->angle = climbangle; - /*if (!demoplayback || P_AnalogMove(slidemo->player)) + /*if (!demoplayback || P_ControlStyle(slidemo->player) == CS_LMAOGALOG) { if (slidemo->player == &players[consoleplayer]) localangle = slidemo->angle; diff --git a/src/p_mobj.c b/src/p_mobj.c index 3d8d81d9b..7d83fffb0 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1892,7 +1892,7 @@ void P_XYMovement(mobj_t *mo) #endif // Pushables can break some blocks - if (CheckForBustableBlocks && mo->flags & MF_PUSHABLE) + if (CheckForBustableBlocks && ((mo->flags & MF_PUSHABLE) || ((mo->info->flags & MF_PUSHABLE) && mo->fuse))) P_PushableCheckBustables(mo); if (!P_TryMove(mo, mo->x + xmove, mo->y + ymove, true) @@ -3298,7 +3298,7 @@ boolean P_CanRunOnWater(player_t *player, ffloor_t *rover) *rover->topheight; if (!player->powers[pw_carry] && !player->homing - && ((player->powers[pw_super] || player->charflags & SF_RUNONWATER || player->dashmode >= 3*TICRATE) && player->mo->ceilingz-topheight >= player->mo->height) + && ((player->powers[pw_super] || player->charflags & SF_RUNONWATER || player->dashmode >= DASHMODE_THRESHOLD) && player->mo->ceilingz-topheight >= player->mo->height) && (rover->flags & FF_SWIMMABLE) && !(player->pflags & PF_SPINNING) && player->speed > FixedMul(player->runspeed, player->mo->scale) && !(player->pflags & PF_SLIDING) && abs(player->mo->z - topheight) < FixedMul(30*FRACUNIT, player->mo->scale)) @@ -7286,7 +7286,7 @@ static void P_FlameJetSceneryThink(mobj_t *mobj) if (!(mobj->flags2 & MF2_FIRING)) return; - if ((leveltime & 3) == 0) + if ((leveltime & 3) != 0) return; // Wave the flames back and forth. Reactiontime determines which direction it's going. @@ -7325,7 +7325,7 @@ static void P_VerticalFlameJetSceneryThink(mobj_t *mobj) if (!(mobj->flags2 & MF2_FIRING)) return; - if ((leveltime & 3) == 0) + if ((leveltime & 3) != 0) return; // Wave the flames back and forth. Reactiontime determines which direction it's going. @@ -7977,7 +7977,7 @@ static void P_MobjSceneryThink(mobj_t *mobj) mobj->x = mobj->extravalue1 + P_ReturnThrustX(mobj, mobj->movedir, mobj->cvmem*mobj->scale); mobj->y = mobj->extravalue2 + P_ReturnThrustY(mobj, mobj->movedir, mobj->cvmem*mobj->scale); P_SetThingPosition(mobj); - + if (!mobj->fuse) { #ifdef HAVE_BLUA diff --git a/src/p_polyobj.c b/src/p_polyobj.c index 36a9ba613..cd0a44bb4 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -1351,9 +1351,9 @@ static void Polyobj_rotateThings(polyobj_t *po, vertex_t origin, angle_t delta, if (turnthings == 2 || (turnthings == 1 && !mo->player)) { mo->angle += delta; if (mo->player == &players[consoleplayer]) - localangle = mo->angle; + localangle += delta; else if (mo->player == &players[secondarydisplayplayer]) - localangle2 = mo->angle; + localangle2 += delta; } } } diff --git a/src/p_setup.c b/src/p_setup.c index 322e2d3b8..189771d9e 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1127,7 +1127,6 @@ static void P_LoadSidedefs(UINT8 *data) // Special info stored in texture fields! switch (sd->special) { - case 63: // Fake floor/ceiling planes case 606: //SoM: 4/4/2000: Just colormap transfer case 447: // Change colormap of tagged sectors! -- Monster Iestyn 14/06/18 case 455: // Fade colormaps! mazmazz 9/12/2018 (:flag_us:) @@ -2857,7 +2856,7 @@ static void P_InitLevelSettings(void) } if (botingame) - CV_SetValue(&cv_analog2, true); + CV_SetValue(&cv_analog[1], true); } // Respawns all the mapthings and mobjs in the map from the already loaded map data. @@ -3168,26 +3167,26 @@ static void P_InitCamera(void) if (!cv_cam2_rotate.changed) CV_Set(&cv_cam2_rotate, cv_cam2_rotate.defaultvalue); - if (!cv_analog.changed) - CV_SetValue(&cv_analog, 0); - if (!cv_analog2.changed) - CV_SetValue(&cv_analog2, 0); + if (!cv_analog[0].changed) + CV_SetValue(&cv_analog[0], 0); + if (!cv_analog[1].changed) + CV_SetValue(&cv_analog[1], 0); displayplayer = consoleplayer; // Start with your OWN view, please! } if (twodlevel) { - CV_SetValue(&cv_analog, false); - CV_SetValue(&cv_analog2, false); + CV_SetValue(&cv_analog[0], false); + CV_SetValue(&cv_analog[1], false); } else { - if (cv_useranalog.value) - CV_SetValue(&cv_analog, true); + if (cv_useranalog[0].value) + CV_SetValue(&cv_analog[0], true); - if ((splitscreen && cv_useranalog2.value) || botingame) - CV_SetValue(&cv_analog2, true); + if ((splitscreen && cv_useranalog[1].value) || botingame) + CV_SetValue(&cv_analog[1], true); } } @@ -3434,6 +3433,9 @@ boolean P_LoadLevel(boolean fromnetsave) /*if (!cv_cam_speed.changed) CV_Set(&cv_cam_speed, cv_cam_speed.defaultvalue);*/ + CV_UpdateCamDist(); + CV_UpdateCam2Dist(); + if (!cv_chasecam.changed) CV_SetValue(&cv_chasecam, chase); diff --git a/src/p_spec.c b/src/p_spec.c index ba0a7216e..1fae65608 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1888,7 +1888,7 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller while (node) { mo = node->m_thing; - if (mo->flags & MF_PUSHABLE) + if ((mo->flags & MF_PUSHABLE) || ((mo->info->flags & MF_PUSHABLE) && mo->fuse)) numpush++; node = node->m_thinglist_next; } @@ -4615,7 +4615,7 @@ DoneSection2: player->mo->angle = player->drawangle = lineangle; - if (!demoplayback || P_AnalogMove(player)) + if (!demoplayback || P_ControlStyle(player) == CS_LMAOGALOG) { if (player == &players[consoleplayer]) localangle = player->mo->angle; @@ -8975,7 +8975,8 @@ void T_Pusher(pusher_t *p) || thing->type == MT_EXTRALARGEBUBBLE)) continue; - if (!(thing->flags & MF_PUSHABLE) && !(thing->type == MT_PLAYER + if (!((thing->flags & MF_PUSHABLE) || ((thing->info->flags & MF_PUSHABLE) && thing->fuse)) + && !(thing->type == MT_PLAYER || thing->type == MT_SMALLBUBBLE || thing->type == MT_MEDIUMBUBBLE || thing->type == MT_EXTRALARGEBUBBLE @@ -9128,7 +9129,7 @@ void T_Pusher(pusher_t *p) thing->player->pflags |= PF_SLIDING; thing->angle = R_PointToAngle2 (0, 0, xspeed<<(FRACBITS-PUSH_FACTOR), yspeed<<(FRACBITS-PUSH_FACTOR)); - if (!demoplayback || P_AnalogMove(thing->player)) + if (!demoplayback || P_ControlStyle(thing->player) == CS_LMAOGALOG) { if (thing->player == &players[consoleplayer]) { diff --git a/src/p_user.c b/src/p_user.c index d0b49000f..b40e647b6 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -42,6 +42,8 @@ #include "b_bot.h" // Objectplace #include "m_cheat.h" +// Thok camera snap (ctrl-f "chalupa") +#include "g_input.h" #ifdef HW3SOUND #include "hardware/hw3sound.h" @@ -347,11 +349,11 @@ void P_GiveEmerald(boolean spawnObj) continue; P_SetTarget(&emmo->target, players[i].mo); P_SetMobjState(emmo, mobjinfo[MT_GOTEMERALD].meleestate + em); - + // Make sure we're not being carried before our tracer is changed if (players[i].powers[pw_carry] != CR_NIGHTSMODE) players[i].powers[pw_carry] = CR_NONE; - + P_SetTarget(&players[i].mo->tracer, emmo); if (pnum == 255) @@ -1063,7 +1065,7 @@ void P_ResetPlayer(player_t *player) player->onconveyor = 0; player->skidtime = 0; if (player-players == consoleplayer && botingame) - CV_SetValue(&cv_analog2, true); + CV_SetValue(&cv_analog[1], true); } // P_PlayerCanDamage @@ -3578,7 +3580,7 @@ static void P_DoClimbing(player_t *player) } #define CLIMBCONEMAX FixedAngle(90*FRACUNIT) - if (!demoplayback || P_AnalogMove(player)) + if (!demoplayback || P_ControlStyle(player) == CS_LMAOGALOG) { if (player == &players[consoleplayer]) { @@ -4393,7 +4395,7 @@ void P_DoJump(player_t *player, boolean soundandstate) player->drawangle = player->mo->angle = player->mo->angle - ANGLE_180; // Turn around from the wall you were climbing. - if (!demoplayback || P_AnalogMove(player)) + if (!demoplayback || P_ControlStyle(player) == CS_LMAOGALOG) { if (player == &players[consoleplayer]) localangle = player->mo->angle; // Adjust the local control angle. @@ -4437,7 +4439,7 @@ void P_DoJump(player_t *player, boolean soundandstate) player->powers[pw_carry] = CR_NONE; P_SetTarget(&player->mo->tracer, NULL); if (player-players == consoleplayer && botingame) - CV_SetValue(&cv_analog2, true); + CV_SetValue(&cv_analog[1], true); } else if (player->powers[pw_carry] == CR_GENERIC) { @@ -4641,7 +4643,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) if (player->dashspeed > player->maxdash) player->dashspeed = player->maxdash; - + if (player->dashspeed < player->maxdash && player->mindash != player->maxdash) { #define chargecalculation (6*(player->dashspeed - player->mindash))/(player->maxdash - player->mindash) @@ -4724,7 +4726,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) { player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y, lockon->x, lockon->y); bullet = P_SpawnPointMissile(player->mo, lockon->x, lockon->y, zpos(lockon), player->revitem, player->mo->x, player->mo->y, zpos(player->mo)); - if (!demoplayback || P_AnalogMove(player)) + if (!demoplayback || P_ControlStyle(player) == CS_LMAOGALOG) { if (player == &players[consoleplayer]) localangle = player->mo->angle; @@ -5353,6 +5355,16 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) player->pflags &= ~(PF_SPINNING|PF_STARTDASH); player->pflags |= PF_THOKKED; + + // Change localangle to match for simple controls? (P.S. chalupa) + // disabled because it seemed to disorient people and Z-targeting exists now + /*if (!demoplayback) + { + if (player == &players[consoleplayer] && cv_cam_turnfacingability[0].value > 0 && !(PLAYER1INPUTDOWN(gc_turnleft) || PLAYER1INPUTDOWN(gc_turnright))) + localangle = player->mo->angle; + else if (player == &players[secondarydisplayplayer] && cv_cam_turnfacingability[1].value > 0 && !(PLAYER2INPUTDOWN(gc_turnleft) || PLAYER2INPUTDOWN(gc_turnright))) + localangle2 = player->mo->angle; + }*/ } break; @@ -5607,13 +5619,6 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) } } -#if 0 -boolean P_AnalogMove(player_t *player) -{ - return player->pflags & PF_ANALOGMODE; -} -#endif - // // P_GetPlayerControlDirection // @@ -5652,7 +5657,7 @@ INT32 P_GetPlayerControlDirection(player_t *player) origtempangle = tempangle = 0; // relative to the axis rather than the player! controlplayerdirection = R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy); } - else if (P_AnalogMove(player) && thiscam->chase) + else if ((P_ControlStyle(player) & CS_LMAOGALOG) && thiscam->chase) { if (player->awayviewtics) origtempangle = tempangle = player->awayviewmobj->angle; @@ -5878,7 +5883,7 @@ static void P_3dMovement(player_t *player) INT32 mforward = 0, mbackward = 0; angle_t dangle; // replaces old quadrants bits fixed_t normalspd = FixedMul(player->normalspeed, player->mo->scale); - boolean analogmove = false; + controlstyle_e controlstyle; boolean spin = ((onground = P_IsObjectOnGround(player->mo)) && (player->pflags & (PF_SPINNING|PF_THOKKED)) == PF_SPINNING && (player->rmomx || player->rmomy) && !(player->pflags & PF_STARTDASH)); fixed_t oldMagnitude, newMagnitude; #ifdef ESLOPE @@ -5891,7 +5896,7 @@ static void P_3dMovement(player_t *player) // Get the old momentum; this will be needed at the end of the function! -SH oldMagnitude = R_PointToDist2(player->mo->momx - player->cmomx, player->mo->momy - player->cmomy, 0, 0); - analogmove = P_AnalogMove(player); + controlstyle = P_ControlStyle(player); cmd = &player->cmd; @@ -5918,7 +5923,7 @@ static void P_3dMovement(player_t *player) } } - if (analogmove) + if (controlstyle & CS_LMAOGALOG) { movepushangle = (cmd->angleturn<<16 /* not FRACBITS */); } @@ -6064,7 +6069,7 @@ static void P_3dMovement(player_t *player) P_SetObjectMomZ(player->mo, FixedDiv(cmd->forwardmove*FRACUNIT, 15*FRACUNIT>>1), false); } } - else if (!analogmove + else if (!(controlstyle == CS_LMAOGALOG) && cmd->forwardmove != 0 && !(player->pflags & PF_GLIDING || player->exiting || (P_PlayerInPain(player) && !onground))) { @@ -6103,7 +6108,7 @@ static void P_3dMovement(player_t *player) P_InstaThrust(player->mo, player->mo->angle-ANGLE_90, FixedDiv(cmd->sidemove*player->mo->scale, 15*FRACUNIT>>1)); } // Analog movement control - else if (analogmove) + else if (controlstyle == CS_LMAOGALOG) { if (!(player->pflags & PF_GLIDING || player->exiting || P_PlayerInPain(player))) { @@ -8114,8 +8119,33 @@ static void P_MovePlayer(player_t *player) P_2dMovement(player); else { - if (!player->climbing && (!P_AnalogMove(player))) - player->mo->angle = (cmd->angleturn<<16 /* not FRACBITS */); + if (!player->climbing) + { + switch (P_ControlStyle(player)) + { + case CS_LEGACY: + case CS_STANDARD: + player->mo->angle = (cmd->angleturn<<16 /* not FRACBITS */); + break; + + case CS_LMAOGALOG: + break; // handled elsewhere + + case CS_SIMPLE: + if (cmd->forwardmove || cmd->sidemove) + { + angle_t controlangle = R_PointToAngle2(0, 0, cmd->forwardmove << FRACBITS, -cmd->sidemove << FRACBITS); + player->mo->angle = (cmd->angleturn<<16 /* not FRACBITS */) + controlangle; + } + else + { + angle_t drawangleoffset = (player->powers[pw_carry] == CR_ROLLOUT) ? ANGLE_180 : 0; + player->mo->angle = player->drawangle + drawangleoffset; + } + + break; + } + } ticruned++; if ((cmd->angleturn & TICCMD_RECEIVED) == 0) @@ -8241,7 +8271,7 @@ static void P_MovePlayer(player_t *player) if (player->pflags & PF_GLIDING) { mobj_t *mo = player->mo; // seriously why isn't this at the top of the function hngngngng - fixed_t leeway = !P_AnalogMove(player) ? FixedAngle(cmd->sidemove*(FRACUNIT)) : 0; + fixed_t leeway = (P_ControlStyle(player) != CS_LMAOGALOG) ? FixedAngle(cmd->sidemove*(FRACUNIT)) : 0; fixed_t glidespeed = player->actionspd; fixed_t momx = mo->momx - player->cmomx, momy = mo->momy - player->cmomy; angle_t angle, moveangle = R_PointToAngle2(0, 0, momx, momy); @@ -8513,7 +8543,7 @@ static void P_MovePlayer(player_t *player) ////////////////// // This really looks like it should be moved to P_3dMovement. -Red - if (P_AnalogMove(player) + if (P_ControlStyle(player) == CS_LMAOGALOG && (cmd->forwardmove != 0 || cmd->sidemove != 0) && !player->climbing && !twodlevel && !(player->mo->flags2 & MF2_TWOD)) { // If travelling slow enough, face the way the controls @@ -9117,6 +9147,132 @@ void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius) } } +// +// P_LookForFocusTarget +// Looks for a target for a player to focus on, for Z-targeting etc. +// exclude would be the current focus target, to ignore. +// direction, if set, requires the target to be to the left (1) or right (-1) of the angle +// mobjflags can be used to limit the flags of objects that can be focused +// +mobj_t *P_LookForFocusTarget(player_t *player, mobj_t *exclude, SINT8 direction, UINT8 lockonflags) +{ + mobj_t *mo; + thinker_t *think; + mobj_t *closestmo = NULL; + const fixed_t maxdist = 2560*player->mo->scale; + const angle_t span = ANGLE_45; + fixed_t dist, closestdist = 0; + angle_t dangle, closestdangle = 0; + + for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next) + { + if (think->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + + mo = (mobj_t *)think; + + if (mo->flags & MF_NOCLIPTHING) + continue; + + if (mo == player->mo || mo == exclude) + continue; + + if (mo->health <= 0) // dead + continue; + + switch (mo->type) + { + case MT_TNTBARREL: + if (lockonflags & LOCK_INTERESTS) + break; + /*fallthru*/ + case MT_PLAYER: // Don't chase other players! + case MT_DETON: + continue; // Don't be STUPID, Sonic! + + case MT_FAKEMOBILE: + if (!(lockonflags & LOCK_BOSS)) + continue; + break; + + case MT_EGGSHIELD: + if (!(lockonflags & LOCK_ENEMY)) + continue; + break; + + case MT_EGGSTATUE: + if (tutorialmode) + break; // Always focus egg statue in the tutorial + /*fallthru*/ + default: + + if ((lockonflags & LOCK_BOSS) && ((mo->flags & (MF_BOSS|MF_SHOOTABLE)) == (MF_BOSS|MF_SHOOTABLE))) // allows if it has the flags desired XOR it has the invert aimable flag + { + if (mo->flags2 & MF2_FRET) + continue; + break; + } + + if ((lockonflags & LOCK_ENEMY) && (!((mo->flags & (MF_ENEMY|MF_SHOOTABLE)) == (MF_ENEMY|MF_SHOOTABLE)) != !(mo->flags2 & MF2_INVERTAIMABLE))) // allows if it has the flags desired XOR it has the invert aimable flag + break; + + if ((lockonflags & LOCK_INTERESTS) && (mo->flags & (MF_PUSHABLE|MF_MONITOR))) // allows if it has the flags desired XOR it has the invert aimable flag + break; + + continue; // not a valid object + } + + { + fixed_t zdist = (player->mo->z + player->mo->height/2) - (mo->z + mo->height/2); + dist = P_AproxDistance(player->mo->x-mo->x, player->mo->y-mo->y); + + if (abs(zdist) > dist) + continue; // Don't home outside of desired angle! + + dist = P_AproxDistance(dist, zdist); + if (dist > maxdist) + continue; // out of range + } + + if ((twodlevel || player->mo->flags2 & MF2_TWOD) + && abs(player->mo->y-mo->y) > player->mo->radius) + continue; // not in your 2d plane + + dangle = R_PointToAngle2(player->mo->x, player->mo->y, mo->x, mo->y) - ( + !exclude ? player->mo->angle : R_PointToAngle2(player->mo->x, player->mo->y, exclude->x, exclude->y) + ); + + if (direction) + { + if (direction == 1 && dangle > ANGLE_180) + continue; // To the right of the player + if (direction == -1 && dangle < ANGLE_180) + continue; // To the left of the player + } + + if (dangle > ANGLE_180) + dangle = InvAngle(dangle); + + if (dangle > span) + continue; // behind back + + // Inflate dist by angle difference to bias toward objects at a closer angle + dist = FixedDiv(dist, FINECOSINE(dangle>>ANGLETOFINESHIFT)*3); + + if (closestmo && (exclude ? (dangle > closestdangle) : (dist > closestdist))) + continue; + + if (!P_CheckSight(player->mo, mo)) + continue; // out of sight + + closestmo = mo; + closestdist = dist; + closestdangle = dangle; + } + + return closestmo; +} + // // P_LookForEnemies // Looks for something you can hit - Used for homing attack @@ -9232,7 +9388,7 @@ boolean P_HomingAttack(mobj_t *source, mobj_t *enemy) // Home in on your target if (source->player) { source->player->drawangle = source->angle; - if (!demoplayback || P_AnalogMove(source->player)) + if (!demoplayback || P_ControlStyle(source->player) == CS_LMAOGALOG) { if (source->player == &players[consoleplayer]) localangle = source->angle; @@ -9584,12 +9740,12 @@ static void CV_CamRotate2_OnChange(void) } static CV_PossibleValue_t CV_CamSpeed[] = {{0, "MIN"}, {1*FRACUNIT, "MAX"}, {0, NULL}}; -static CV_PossibleValue_t rotation_cons_t[] = {{1, "MIN"}, {45, "MAX"}, {0, NULL}}; +static CV_PossibleValue_t rotation_cons_t[] = {{1, "MIN"}, {25, "MAX"}, {0, NULL}}; static CV_PossibleValue_t CV_CamRotate[] = {{-720, "MIN"}, {720, "MAX"}, {0, NULL}}; static CV_PossibleValue_t multiplier_cons_t[] = {{0, "MIN"}, {3*FRACUNIT, "MAX"}, {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_dist = {"cam_curdist", "160", CV_FLOAT, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_cam_height = {"cam_curheight", "25", CV_FLOAT, 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.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}; @@ -9597,8 +9753,8 @@ consvar_t cv_cam_rotspeed = {"cam_rotspeed", "10", CV_SAVE, rotation_cons_t, NUL consvar_t cv_cam_turnmultiplier = {"cam_turnmultiplier", "1.0", CV_FLOAT|CV_SAVE, multiplier_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_cam_orbit = {"cam_orbit", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_cam_adjust = {"cam_adjust", "On", CV_SAVE, CV_OnOff, 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_dist = {"cam2_curdist", "160", CV_FLOAT, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_cam2_height = {"cam2_curheight", "25", CV_FLOAT, 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.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}; @@ -9607,6 +9763,42 @@ consvar_t cv_cam2_turnmultiplier = {"cam2_turnmultiplier", "1.0", CV_FLOAT|CV_SA consvar_t cv_cam2_orbit = {"cam2_orbit", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_cam2_adjust = {"cam2_adjust", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +// [standard vs simple][p1 or p2] +consvar_t cv_cam_savedist[2][2] = { + { // standard + {"cam_dist", "160", CV_FLOAT|CV_SAVE|CV_CALL, NULL, CV_UpdateCamDist, 0, NULL, NULL, 0, 0, NULL}, + {"cam2_dist", "160", CV_FLOAT|CV_SAVE|CV_CALL, NULL, CV_UpdateCam2Dist, 0, NULL, NULL, 0, 0, NULL} + }, + { // simple + {"cam_simpledist", "224", CV_FLOAT|CV_SAVE|CV_CALL, NULL, CV_UpdateCamDist, 0, NULL, NULL, 0, 0, NULL}, + {"cam2_simpledist", "224", CV_FLOAT|CV_SAVE|CV_CALL, NULL, CV_UpdateCam2Dist, 0, NULL, NULL, 0, 0, NULL} + + } +}; +consvar_t cv_cam_saveheight[2][2] = { + { // standard + {"cam_height", "25", CV_FLOAT|CV_SAVE|CV_CALL, NULL, CV_UpdateCamDist, 0, NULL, NULL, 0, 0, NULL}, + {"cam2_height", "25", CV_FLOAT|CV_SAVE|CV_CALL, NULL, CV_UpdateCam2Dist, 0, NULL, NULL, 0, 0, NULL} + }, + { // simple + {"cam_simpleheight", "48", CV_FLOAT|CV_SAVE|CV_CALL, NULL, CV_UpdateCamDist, 0, NULL, NULL, 0, 0, NULL}, + {"cam2_simpleheight", "48", CV_FLOAT|CV_SAVE|CV_CALL, NULL, CV_UpdateCam2Dist, 0, NULL, NULL, 0, 0, NULL} + + } +}; + +void CV_UpdateCamDist(void) +{ + CV_Set(&cv_cam_dist, va("%f", FIXED_TO_FLOAT(cv_cam_savedist[cv_useranalog[0].value][0].value))); + CV_Set(&cv_cam_height, va("%f", FIXED_TO_FLOAT(cv_cam_saveheight[cv_useranalog[0].value][0].value))); +} + +void CV_UpdateCam2Dist(void) +{ + CV_Set(&cv_cam2_dist, va("%f", FIXED_TO_FLOAT(cv_cam_savedist[cv_useranalog[1].value][1].value))); + CV_Set(&cv_cam2_height, va("%f", FIXED_TO_FLOAT(cv_cam_saveheight[cv_useranalog[1].value][1].value))); +} + fixed_t t_cam_dist = -42; fixed_t t_cam_height = -42; fixed_t t_cam_rotate = -42; @@ -9640,8 +9832,14 @@ void P_ResetCamera(player_t *player, camera_t *thiscam) thiscam->y = y; thiscam->z = z; - if (!(thiscam == &camera && (cv_cam_still.value || cv_analog.value)) - && !(thiscam == &camera2 && (cv_cam2_still.value || cv_analog2.value))) + if ((thiscam == &camera && G_ControlStyle(1) == CS_SIMPLE) + || (thiscam == &camera2 && G_ControlStyle(2) == CS_SIMPLE)) + { + thiscam->angle = (thiscam == &camera) ? localangle : localangle2; + thiscam->aiming = (thiscam == &camera) ? localaiming : localaiming2; + } + else if (!(thiscam == &camera && (cv_cam_still.value || cv_analog[0].value)) + && !(thiscam == &camera2 && (cv_cam2_still.value || cv_analog[1].value))) { thiscam->angle = player->mo->angle; thiscam->aiming = 0; @@ -9666,6 +9864,9 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall subsector_t *newsubsec; fixed_t f1, f2; + static fixed_t camsideshift[2] = {0, 0}; + fixed_t shiftx = 0, shifty = 0; + // We probably shouldn't move the camera if there is no player or player mobj somehow if (!player || !player->mo) return true; @@ -9756,7 +9957,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall } else { - focusangle = mo->angle; + focusangle = player->cmd.angleturn << 16; focusaiming = player->aiming; } @@ -9796,7 +9997,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall camheight = FixedMul(camheight, player->camerascale); #ifdef REDSANALOG - if (P_AnalogMove(player) && (player->cmd.buttons & (BT_CAMLEFT|BT_CAMRIGHT)) == (BT_CAMLEFT|BT_CAMRIGHT)) { + if (P_ControlStyle(player) == CS_LMAOGALOG && (player->cmd.buttons & (BT_CAMLEFT|BT_CAMRIGHT)) == (BT_CAMLEFT|BT_CAMRIGHT)) { camstill = true; if (camspeed < 4*FRACUNIT/5) @@ -9826,7 +10027,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall angle = R_PointToAngle2(mo->x, mo->y, mo->target->x, mo->target->y); } } - else if (P_AnalogMove(player) && !sign) // Analog + else if (P_ControlStyle(player) == CS_LMAOGALOG && !sign) // Analog angle = R_PointToAngle2(thiscam->x, thiscam->y, mo->x, mo->y); else if (demoplayback) { @@ -9843,14 +10044,14 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall else angle = focusangle + FixedAngle(camrotate*FRACUNIT); - if (!resetcalled && (cv_analog.value || demoplayback) && ((thiscam == &camera && t_cam_rotate != -42) || (thiscam == &camera2 + if (!resetcalled && (cv_analog[0].value || demoplayback) && ((thiscam == &camera && t_cam_rotate != -42) || (thiscam == &camera2 && t_cam2_rotate != -42))) { angle = FixedAngle(camrotate*FRACUNIT); thiscam->angle = angle; } - if ((((thiscam == &camera) && cv_analog.value) || ((thiscam != &camera) && cv_analog2.value) || demoplayback) && !sign && !objectplacing && !(twodlevel || (mo->flags2 & MF2_TWOD)) && (player->powers[pw_carry] != CR_NIGHTSMODE) && displayplayer == consoleplayer) + if ((((thiscam == &camera) && cv_analog[0].value) || ((thiscam != &camera) && cv_analog[1].value) || demoplayback) && !sign && !objectplacing && !(twodlevel || (mo->flags2 & MF2_TWOD)) && (player->powers[pw_carry] != CR_NIGHTSMODE) && displayplayer == consoleplayer) { #ifdef REDSANALOG if ((player->cmd.buttons & (BT_CAMLEFT|BT_CAMRIGHT)) == (BT_CAMLEFT|BT_CAMRIGHT)); else @@ -9871,6 +10072,29 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall } } + if (G_ControlStyle((thiscam == &camera) ? 1 : 2) == CS_SIMPLE && !sign) + { + // Shift the camera slightly to the sides depending on the player facing direction + UINT8 forplayer = (thiscam == &camera) ? 0 : 1; + fixed_t shift = FixedMul(FINESINE((player->mo->angle - angle) >> ANGLETOFINESHIFT), cv_cam_shiftfacing[forplayer].value); + + if (player->powers[pw_carry] == CR_NIGHTSMODE) + { + fixed_t cos = FINECOSINE((angle_t) (player->flyangle * ANG1)>>ANGLETOFINESHIFT); + shift = FixedMul(shift, min(FRACUNIT, player->speed*abs(cos)/6000)); + shift += FixedMul(camsideshift[forplayer] - shift, FRACUNIT-(camspeed>>2)); + } + else if (ticcmd_centerviewdown[(thiscam == &camera) ? 0 : 1]) + shift = FixedMul(camsideshift[forplayer], FRACUNIT-camspeed); + else + shift += FixedMul(camsideshift[forplayer] - shift, FRACUNIT-(camspeed>>3)); + camsideshift[forplayer] = shift; + + shift = FixedMul(shift, camdist); + shiftx = -FixedMul(FINESINE(angle>>ANGLETOFINESHIFT), shift); + shifty = FixedMul(FINECOSINE(angle>>ANGLETOFINESHIFT), shift); + } + // sets ideal cam pos if (twodlevel || (mo->flags2 & MF2_TWOD)) dist = 480<scale << 7; camspeed = FRACUNIT/12; } - else if (P_AnalogMove(player)) // x1.2 dist for analog + else if (P_ControlStyle(player) == CS_LMAOGALOG) // x1.2 dist for analog { dist = FixedMul(dist, 6*FRACUNIT/5); camheight = FixedMul(camheight, 6*FRACUNIT/5); @@ -10217,8 +10441,8 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall } else { - viewpointx = mo->x + FixedMul(FINECOSINE((angle>>ANGLETOFINESHIFT) & FINEMASK), dist); - viewpointy = mo->y + FixedMul(FINESINE((angle>>ANGLETOFINESHIFT) & FINEMASK), dist); + viewpointx = mo->x + shiftx + FixedMul(FINECOSINE((angle>>ANGLETOFINESHIFT) & FINEMASK), dist); + viewpointy = mo->y + shifty + FixedMul(FINESINE((angle>>ANGLETOFINESHIFT) & FINEMASK), dist); } if (!camstill && !resetcalled && !paused) @@ -10259,6 +10483,9 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall } else thiscam->momz = FixedMul(z - thiscam->z, camspeed); + + thiscam->momx += FixedMul(shiftx, camspeed); + thiscam->momy += FixedMul(shifty, camspeed); } // compute aming to look the viewed point @@ -10806,7 +11033,7 @@ static void P_MinecartThink(player_t *player) else if (angdiff > ANGLE_180 && angdiff < InvAngle(MINECARTCONEMAX)) player->mo->angle = minecart->angle - MINECARTCONEMAX; - if (angdiff + minecart->angle != player->mo->angle && (!demoplayback || P_AnalogMove(player))) + if (angdiff + minecart->angle != player->mo->angle && (!demoplayback || P_ControlStyle(player) == CS_LMAOGALOG)) { if (player == &players[consoleplayer]) localangle = player->mo->angle; @@ -10885,7 +11112,7 @@ static void P_MinecartThink(player_t *player) else minecart->angle = targetangle + ANGLE_180; angdiff = (minecart->angle - prevangle); - if (angdiff && (!demoplayback || P_AnalogMove(player))) // maintain relative angle on turns + if (angdiff && (!demoplayback || P_ControlStyle(player) == CS_LMAOGALOG)) // maintain relative angle on turns { player->mo->angle += angdiff; if (player == &players[consoleplayer]) @@ -11660,7 +11887,7 @@ void P_PlayerThink(player_t *player) player->mo->reactiontime--; else if (player->powers[pw_carry] == CR_MINECART) { - if (!P_AnalogMove(player)) + if (P_ControlStyle(player) != CS_LMAOGALOG) player->mo->angle = (cmd->angleturn << 16 /* not FRACBITS */); ticruned++; @@ -11673,7 +11900,7 @@ void P_PlayerThink(player_t *player) { if (player->powers[pw_carry] == CR_ROPEHANG) { - if (!P_AnalogMove(player)) + if (P_ControlStyle(player) != CS_LMAOGALOG) player->mo->angle = (cmd->angleturn<<16 /* not FRACBITS */); ticruned++; @@ -11721,7 +11948,7 @@ void P_PlayerThink(player_t *player) ; else if (!(player->pflags & PF_DIRECTIONCHAR) || (player->climbing) // stuff where the direction is forced at all times - || (P_AnalogMove(player) || twodlevel || player->mo->flags2 & MF2_TWOD) // keep things synchronised up there, since the camera IS seperate from player motion when that happens + || (twodlevel || player->mo->flags2 & MF2_TWOD) // keep things synchronised up there, since the camera IS seperate from player motion when that happens || G_RingSlingerGametype()) // no firing rings in directions your player isn't aiming player->drawangle = player->mo->angle; else if (P_PlayerInPain(player)) @@ -11752,7 +11979,7 @@ void P_PlayerThink(player_t *player) case CR_ROLLOUT: if (cmd->forwardmove || cmd->sidemove) // only when you're pressing movement keys { // inverse direction! - diff = ((player->mo->angle + R_PointToAngle2(0, 0, -cmd->forwardmove<sidemove<drawangle); + diff = (((player->cmd.angleturn<<16) + R_PointToAngle2(0, 0, -cmd->forwardmove<sidemove<drawangle); factor = 4; } break; @@ -11809,7 +12036,7 @@ void P_PlayerThink(player_t *player) } else if (cmd->forwardmove || cmd->sidemove) // only when you're pressing movement keys { - diff = ((player->mo->angle + R_PointToAngle2(0, 0, cmd->forwardmove<sidemove<drawangle); + diff = ((player->mo->angle + ((player->pflags & PF_ANALOGMODE) ? 0 : R_PointToAngle2(0, 0, cmd->forwardmove<sidemove<drawangle); factor = 4; } else if (player->rmomx || player->rmomy) @@ -12422,7 +12649,7 @@ void P_PlayerAfterThink(player_t *player) { player->mo->angle = tails->angle; - if (!demoplayback || P_AnalogMove(player)) + if (!demoplayback || P_ControlStyle(player) == CS_LMAOGALOG) { if (player == &players[consoleplayer]) localangle = player->mo->angle; @@ -12445,7 +12672,7 @@ void P_PlayerAfterThink(player_t *player) P_SetTarget(&player->mo->tracer, NULL); if (player-players == consoleplayer && botingame) - CV_SetValue(&cv_analog2, (player->powers[pw_carry] != CR_PLAYER)); + CV_SetValue(&cv_analog[1], (player->powers[pw_carry] != CR_PLAYER)); break; } case CR_GENERIC: // being carried by some generic item @@ -12511,7 +12738,7 @@ void P_PlayerAfterThink(player_t *player) macecenter->angle += cmd->sidemove<mo->angle += cmd->sidemove< ANGLE_MAX - if (!demoplayback || P_AnalogMove(player)) + if (!demoplayback || P_ControlStyle(player) == CS_LMAOGALOG) { if (player == &players[consoleplayer]) localangle = player->mo->angle; // Adjust the local control angle. diff --git a/src/r_data.c b/src/r_data.c index db791ab16..6ba40206c 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -1254,14 +1254,29 @@ void R_PrecacheLevel(void) for (j = 0; j < sprites[i].numframes; j++) { sf = &sprites[i].spriteframes[j]; - for (k = 0; k < 8; k++) +#define cacheang(a) {\ + lump = sf->lumppat[a];\ + if (devparm)\ + spritememory += W_LumpLength(lump);\ + W_CachePatchNum(lump, PU_PATCH);\ + } + // see R_InitSprites for more about lumppat,lumpid + switch (sf->rotate) { - // see R_InitSprites for more about lumppat,lumpid - lump = sf->lumppat[k]; - if (devparm) - spritememory += W_LumpLength(lump); - W_CachePatchNum(lump, PU_PATCH); + case SRF_SINGLE: + cacheang(0); + break; + case SRF_2D: + cacheang(2); + cacheang(6); + break; + default: + k = (sf->rotate & SRF_3DGE ? 16 : 8); + while (k--) + cacheang(k); + break; } +#undef cacheang } } free(spritepresent); diff --git a/src/r_defs.h b/src/r_defs.h index 176f33c4f..52b9bea95 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -727,8 +727,8 @@ typedef struct #ifdef ROTSPRITE typedef struct { - patch_t *patch[8][ROTANGLES]; - boolean cached[8]; + patch_t *patch[16][ROTANGLES]; + UINT16 cached; } rotsprite_t; #endif/*ROTSPRITE*/ @@ -736,9 +736,11 @@ typedef enum { SRF_SINGLE = 0, // 0-angle for all rotations SRF_3D = 1, // Angles 1-8 - SRF_LEFT = 2, // Left side uses single patch - SRF_RIGHT = 4, // Right side uses single patch - SRF_2D = SRF_LEFT|SRF_RIGHT, // 6 + SRF_3DGE = 2, // 3DGE, ZDoom and Doom Legacy all have 16-angle support. Why not us? + SRF_3DMASK = SRF_3D|SRF_3DGE, // 3 + SRF_LEFT = 4, // Left side uses single patch + SRF_RIGHT = 8, // Right side uses single patch + SRF_2D = SRF_LEFT|SRF_RIGHT, // 12 SRF_NONE = 0xff // Initial value } spriterotateflags_t; // SRF's up! @@ -764,7 +766,7 @@ typedef struct patchinfo_s patchinfo_t; // Sprites are patches with a special naming convention so they can be // recognized by R_InitSprites. // The base name is NNNNFx or NNNNFxFx, with x indicating the rotation, -// x = 0, 1-8, L/R +// x = 0, 1-8, 9+A-G, L/R // The sprite and frame specified by a thing_t is range checked at run time. // A sprite is a patch_t that is assumed to represent a three dimensional // object and may have multiple rotations predrawn. @@ -781,12 +783,12 @@ typedef struct // name eight times. UINT8 rotate; // see spriterotateflags_t above - // Lump to use for view angles 0-7. - lumpnum_t lumppat[8]; // lump number 16 : 16 wad : lump - size_t lumpid[8]; // id in the spriteoffset, spritewidth, etc. tables + // Lump to use for view angles 0-7/15. + lumpnum_t lumppat[16]; // lump number 16 : 16 wad : lump + size_t lumpid[16]; // id in the spriteoffset, spritewidth, etc. tables - // Flip bits (1 = flip) to use for view angles 0-7. - UINT8 flip; + // Flip bits (1 = flip) to use for view angles 0-7/15. + UINT16 flip; #ifdef ROTSPRITE rotsprite_t rotsprite; diff --git a/src/r_main.c b/src/r_main.c index 22061b407..a2674b543 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -187,20 +187,20 @@ void SplitScreen_OnChange(void) static void ChaseCam_OnChange(void) { - if (!cv_chasecam.value || !cv_useranalog.value) - CV_SetValue(&cv_analog, 0); + if (!cv_chasecam.value || !cv_useranalog[0].value) + CV_SetValue(&cv_analog[0], 0); else - CV_SetValue(&cv_analog, 1); + CV_SetValue(&cv_analog[0], 1); } static void ChaseCam2_OnChange(void) { if (botingame) return; - if (!cv_chasecam2.value || !cv_useranalog2.value) - CV_SetValue(&cv_analog2, 0); + if (!cv_chasecam2.value || !cv_useranalog[1].value) + CV_SetValue(&cv_analog[1], 0); else - CV_SetValue(&cv_analog2, 1); + CV_SetValue(&cv_analog[1], 1); } static void FlipCam_OnChange(void) @@ -1234,6 +1234,16 @@ void R_RegisterEngineStuff(void) CV_RegisterVar(&cv_cam2_orbit); CV_RegisterVar(&cv_cam2_adjust); + CV_RegisterVar(&cv_cam_savedist[0][0]); + CV_RegisterVar(&cv_cam_savedist[0][1]); + CV_RegisterVar(&cv_cam_savedist[1][0]); + CV_RegisterVar(&cv_cam_savedist[1][1]); + + CV_RegisterVar(&cv_cam_saveheight[0][0]); + CV_RegisterVar(&cv_cam_saveheight[0][1]); + CV_RegisterVar(&cv_cam_saveheight[1][0]); + CV_RegisterVar(&cv_cam_saveheight[1][1]); + CV_RegisterVar(&cv_showhud); CV_RegisterVar(&cv_translucenthud); diff --git a/src/r_patch.h b/src/r_patch.h new file mode 100644 index 000000000..e743a7d09 --- /dev/null +++ b/src/r_patch.h @@ -0,0 +1,74 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 1993-1996 by id Software, Inc. +// Copyright (C) 2018-2019 by Jaime "Lactozilla" Passos. +// Copyright (C) 2019 by Sonic Team Junior. +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file r_patch.h +/// \brief Patch generation. + +#ifndef __R_PATCH__ +#define __R_PATCH__ + +#include "r_defs.h" +#include "doomdef.h" + +// Structs +typedef enum +{ + ROTAXIS_X, // Roll (the default) + ROTAXIS_Y, // Pitch + ROTAXIS_Z // Yaw +} rotaxis_t; + +typedef struct +{ + INT32 x, y; + rotaxis_t rotaxis; +} spriteframepivot_t; + +typedef struct +{ + spriteframepivot_t pivot[64]; + boolean available; +} spriteinfo_t; + +// Conversions between patches / flats / textures... +boolean R_CheckIfPatch(lumpnum_t lump); +void R_TextureToFlat(size_t tex, UINT8 *flat); +void R_PatchToFlat(patch_t *patch, UINT8 *flat); +void R_PatchToMaskedFlat(patch_t *patch, UINT16 *raw, boolean flip); +patch_t *R_FlatToPatch(UINT8 *raw, UINT16 width, UINT16 height, UINT16 leftoffset, UINT16 topoffset, size_t *destsize, boolean transparency); +patch_t *R_MaskedFlatToPatch(UINT16 *raw, UINT16 width, UINT16 height, UINT16 leftoffset, UINT16 topoffset, size_t *destsize); + +// Portable Network Graphics +boolean R_IsLumpPNG(const UINT8 *d, size_t s); +#define W_ThrowPNGError(lumpname, wadfilename) I_Error("W_Wad: Lump \"%s\" in file \"%s\" is a .png - please convert to either Doom or Flat (raw) image format.", lumpname, wadfilename); // Fears Of LJ Sonic + +#ifndef NO_PNG_LUMPS +UINT8 *R_PNGToFlat(UINT16 *width, UINT16 *height, UINT8 *png, size_t size); +patch_t *R_PNGToPatch(const UINT8 *png, size_t size, size_t *destsize); +boolean R_PNGDimensions(UINT8 *png, INT16 *width, INT16 *height, size_t size); +#endif + +// SpriteInfo +extern spriteinfo_t spriteinfo[NUMSPRITES]; +void R_LoadSpriteInfoLumps(UINT16 wadnum, UINT16 numlumps); +void R_ParseSPRTINFOLump(UINT16 wadNum, UINT16 lumpNum); + +// Sprite rotation +#ifdef ROTSPRITE +INT32 R_GetRollAngle(angle_t rollangle); +void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, spriteframe_t *sprframe, INT32 rot, UINT8 flip); +void R_FreeSingleRotSprite(spritedef_t *spritedef); +void R_FreeSkinRotSprite(size_t skinnum); +extern fixed_t rollcosang[ROTANGLES]; +extern fixed_t rollsinang[ROTANGLES]; +void R_FreeAllRotSprite(void); +#endif + +#endif // __R_PATCH__ diff --git a/src/r_picformats.c b/src/r_picformats.c index c7e54cf4e..2d3977054 100644 --- a/src/r_picformats.c +++ b/src/r_picformats.c @@ -1469,7 +1469,7 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp #define ROTSPRITE_XCENTER (newwidth / 2) #define ROTSPRITE_YCENTER (newheight / 2) - if (!sprframe->rotsprite.cached[rot]) + if (!(sprframe->rotsprite.cached & (1<rotsprite.cached[rot] = true; + sprframe->rotsprite.cached |= (1<numframes; frame++) { spriteframe_t *sprframe = &spritedef->spriteframes[frame]; - for (rot = 0; rot < 8; rot++) + for (rot = 0; rot < 16; rot++) { - if (sprframe->rotsprite.cached[rot]) + if (sprframe->rotsprite.cached & (1<rotsprite.cached[rot] = false; + sprframe->rotsprite.cached &= ~(1<= 64 || !(R_ValidSpriteAngle(rotation))) - I_Error("R_InstallSpriteLump: Bad frame characters in lump %s", W_CheckNameForNum(lumppat)); - if (maxframe ==(size_t)-1 || frame > maxframe) maxframe = frame; // rotsprite #ifdef ROTSPRITE - for (r = 0; r < 8; r++) + sprtemp[frame].rotsprite.cached = 0; + for (r = 0; r < 16; r++) { - sprtemp[frame].rotsprite.cached[r] = false; for (ang = 0; ang < ROTANGLES; ang++) sprtemp[frame].rotsprite.patch[r][ang] = NULL; } @@ -133,16 +130,16 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch // the lump should be used for all rotations if (sprtemp[frame].rotate == SRF_SINGLE) CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has multiple rot = 0 lump\n", spritename, cn); - else if (sprtemp[frame].rotate != SRF_NONE) // Let's bundle 1-8 and L/R rotations into one debug message. + else if (sprtemp[frame].rotate != SRF_NONE) // Let's bundle 1-8/16 and L/R rotations into one debug message. CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has rotations and a rot = 0 lump\n", spritename, cn); sprtemp[frame].rotate = SRF_SINGLE; - for (r = 0; r < 8; r++) + for (r = 0; r < 16; r++) { sprtemp[frame].lumppat[r] = lumppat; sprtemp[frame].lumpid[r] = lumpid; } - sprtemp[frame].flip = flipped ? 0xFF : 0; // 11111111 in binary + sprtemp[frame].flip = flipped ? 0xFFFF : 0; // 1111111111111111 in binary return; } @@ -151,54 +148,67 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch UINT8 rightfactor = ((rotation == ROT_R) ? 4 : 0); // the lump should be used for half of all rotations - if (sprtemp[frame].rotate == SRF_SINGLE) + if (sprtemp[frame].rotate == SRF_NONE) + sprtemp[frame].rotate = SRF_SINGLE; + else if (sprtemp[frame].rotate == SRF_SINGLE) CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has L/R rotations and a rot = 0 lump\n", spritename, cn); else if (sprtemp[frame].rotate == SRF_3D) CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has both L/R and 1-8 rotations\n", spritename, cn); + else if (sprtemp[frame].rotate == SRF_3DGE) + CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has both L/R and 1-G rotations\n", spritename, cn); else if ((sprtemp[frame].rotate & SRF_LEFT) && (rotation == ROT_L)) CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has multiple L rotations\n", spritename, cn); else if ((sprtemp[frame].rotate & SRF_RIGHT) && (rotation == ROT_R)) CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has multiple R rotations\n", spritename, cn); - if (sprtemp[frame].rotate == SRF_NONE) - sprtemp[frame].rotate = SRF_SINGLE; - sprtemp[frame].rotate |= ((rotation == ROT_R) ? SRF_RIGHT : SRF_LEFT); - if (sprtemp[frame].rotate == (SRF_3D|SRF_2D)) - sprtemp[frame].rotate = SRF_2D; // SRF_3D|SRF_2D being enabled at the same time doesn't HURT in the current sprite angle implementation, but it DOES mean more to check in some of the helper functions. Let's not allow this scenario to happen. + if ((sprtemp[frame].rotate & SRF_2D) == SRF_2D) + sprtemp[frame].rotate &= ~SRF_3DMASK; // SRF_3D|SRF_2D being enabled at the same time doesn't HURT in the current sprite angle implementation, but it DOES mean more to check in some of the helper functions. Let's not allow this scenario to happen. - for (r = 0; r < 4; r++) // Thanks to R_PrecacheLevel, we can't leave sprtemp[*].lumppat[*] == LUMPERROR... so we load into the front/back angle too. + // load into every relevant angle, including the front one + for (r = 0; r < 4; r++) { sprtemp[frame].lumppat[r + rightfactor] = lumppat; sprtemp[frame].lumpid[r + rightfactor] = lumpid; + sprtemp[frame].lumppat[r + rightfactor + 8] = lumppat; + sprtemp[frame].lumpid[r + rightfactor + 8] = lumpid; + } if (flipped) - sprtemp[frame].flip |= (0x0F< 3) // Right side - sprtemp[frame].rotate = (SRF_3D | (sprtemp[frame].rotate & SRF_LEFT)); // Continue allowing L frame changeover - else // if (rotation <= 3) // Left side - sprtemp[frame].rotate = (SRF_3D | (sprtemp[frame].rotate & SRF_RIGHT)); // Continue allowing R frame changeover + { + // SRF_3D|SRF_3DGE being enabled at the same time doesn't HURT in the current sprite angle implementation, but it DOES mean more to check in some of the helper functions. Let's not allow this scenario to happen. + UINT8 threedrot = (rotation > 7) ? SRF_3DGE : (sprtemp[frame].rotate & SRF_3DMASK); + if (!threedrot) + threedrot = SRF_3D; + + if (rotation == 0 || rotation == 4) // Front or back... + sprtemp[frame].rotate = threedrot; // Prevent L and R changeover + else if ((rotation & 7) > 3) // Right side + sprtemp[frame].rotate = (threedrot | (sprtemp[frame].rotate & SRF_LEFT)); // Continue allowing L frame changeover + else // if ((rotation & 7) <= 3) // Left side + sprtemp[frame].rotate = (threedrot | (sprtemp[frame].rotate & SRF_RIGHT)); // Continue allowing R frame changeover + } if (sprtemp[frame].lumppat[rotation] != LUMPERROR) - CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s: %c%c has two lumps mapped to it\n", spritename, cn, '1'+rotation); + CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s: %c%c has two lumps mapped to it\n", spritename, cn, cr); // lumppat & lumpid are the same for original Doom, but different // when using sprites in pwad : the lumppat points the new graphics @@ -259,9 +269,9 @@ static boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, if (memcmp(lumpinfo[l].name,sprname,4)==0) { frame = R_Char2Frame(lumpinfo[l].name[4]); - rotation = (UINT8)(lumpinfo[l].name[5] - '0'); + rotation = R_Char2Rotation(lumpinfo[l].name[5]); - if (frame >= 64 || !(R_ValidSpriteAngle(rotation))) // Give an actual NAME error -_-... + if (frame >= 64 || rotation == 255) // Give an actual NAME error -_-... { CONS_Alert(CONS_WARNING, M_GetText("Bad sprite name: %s\n"), W_CheckNameForNumPwad(wadnum,l)); continue; @@ -312,7 +322,13 @@ static boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, if (lumpinfo[l].name[6]) { frame = R_Char2Frame(lumpinfo[l].name[6]); - rotation = (UINT8)(lumpinfo[l].name[7] - '0'); + rotation = R_Char2Rotation(lumpinfo[l].name[7]); + + if (frame >= 64 || rotation == 255) // Give an actual NAME error -_-... + { + CONS_Alert(CONS_WARNING, M_GetText("Bad sprite name: %s\n"), W_CheckNameForNumPwad(wadnum,l)); + continue; + } R_InstallSpriteLump(wadnum, l, numspritelumps, frame, rotation, 1); } @@ -373,18 +389,19 @@ static boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, case SRF_2D: // both Left and Right rotations // we test to see whether the left and right slots are present if ((sprtemp[frame].lumppat[2] == LUMPERROR) || (sprtemp[frame].lumppat[6] == LUMPERROR)) - I_Error("R_AddSingleSpriteDef: Sprite %.4s frame %c is missing rotations", + I_Error("R_AddSingleSpriteDef: Sprite %.4s frame %c is missing rotations (L-R mode)", sprname, R_Frame2Char(frame)); break; default: - // must have all 8 frames - for (rotation = 0; rotation < 8; rotation++) + // must have all 8/16 frames + rotation = ((sprtemp[frame].rotate & SRF_3DGE) ? 16 : 8); + while (rotation--) // we test the patch lump, or the id lump whatever // if it was not loaded the two are LUMPERROR if (sprtemp[frame].lumppat[rotation] == LUMPERROR) - I_Error("R_AddSingleSpriteDef: Sprite %.4s frame %c is missing rotations", - sprname, R_Frame2Char(frame)); + I_Error("R_AddSingleSpriteDef: Sprite %.4s frame %c is missing rotations (1-%c mode)", + sprname, R_Frame2Char(frame), ((sprtemp[frame].rotate & SRF_3DGE) ? 'G' : '8')); break; } } @@ -1098,7 +1115,7 @@ static void R_ProjectSprite(mobj_t *thing) size_t lump; size_t rot; - UINT8 flip; + UINT16 flip; boolean vflip = (!(thing->eflags & MFE_VERTICALFLIP) != !(thing->frame & FF_VERTICALFLIP)); INT32 lindex; @@ -1228,7 +1245,7 @@ static void R_ProjectSprite(mobj_t *thing) // use single rotation for all views rot = 0; //Fab: for vis->patch below lump = sprframe->lumpid[0]; //Fab: see note above - flip = sprframe->flip; // Will only be 0x00 or 0xFF + flip = sprframe->flip; // Will only be 0 or 0xFFFF } else { @@ -1239,6 +1256,11 @@ static void R_ProjectSprite(mobj_t *thing) rot = 6; // F7 slot else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left rot = 2; // F3 slot + else if (sprframe->rotate & SRF_3DGE) // 16-angle mode + { + rot = (ang+ANGLE_180+ANGLE_11hh)>>28; + rot = ((rot & 1)<<3)|(rot>>1); + } else // Normal behaviour rot = (ang+ANGLE_202h)>>29; @@ -1261,7 +1283,7 @@ static void R_ProjectSprite(mobj_t *thing) if (thing->rollangle) { rollangle = R_GetRollAngle(thing->rollangle); - if (!sprframe->rotsprite.cached[rot]) + if (!(sprframe->rotsprite.cached & (1<sprite, (thing->frame & FF_FRAMEMASK), sprinfo, sprframe, rot, flip); rotsprite = sprframe->rotsprite.patch[rot][rollangle]; if (rotsprite != NULL) diff --git a/src/r_things.h b/src/r_things.h index 706d98c4e..c60df7c28 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -20,10 +20,6 @@ #include "r_portal.h" #include "r_defs.h" -// "Left" and "Right" character symbols for additional rotation functionality -#define ROT_L ('L' - '0') -#define ROT_R ('R' - '0') - // number of sprite lumps for spritewidth,offset,topoffset lookup tables // Fab: this is a hack : should allocate the lookup tables per sprite #define MAXVISSPRITES 2048 // added 2-2-98 was 128 @@ -270,7 +266,7 @@ FUNCMATH FUNCINLINE static ATTRINLINE UINT8 R_Char2Frame(char cn) if (cn == '+') return '\\' - 'A'; // PK3 can't use backslash, so use + instead return cn - 'A'; #else - if (cn >= 'A' && cn <= 'Z') return cn - 'A'; + if (cn >= 'A' && cn <= 'Z') return (cn - 'A'); if (cn >= '0' && cn <= '9') return (cn - '0') + 26; if (cn >= 'a' && cn <= 'z') return (cn - 'a') + 36; if (cn == '!') return 62; @@ -279,9 +275,26 @@ FUNCMATH FUNCINLINE static ATTRINLINE UINT8 R_Char2Frame(char cn) #endif } -FUNCMATH FUNCINLINE static ATTRINLINE boolean R_ValidSpriteAngle(UINT8 rotation) +// "Left" and "Right" character symbols for additional rotation functionality +#define ROT_L 17 +#define ROT_R 18 + +FUNCMATH FUNCINLINE static ATTRINLINE char R_Rotation2Char(UINT8 rot) { - return ((rotation <= 8) || (rotation == ROT_L) || (rotation == ROT_R)); + if (rot <= 9) return '0' + rot; + if (rot <= 16) return 'A' + (rot - 10); + if (rot == ROT_L) return 'L'; + if (rot == ROT_R) return 'R'; + return '\xFF'; +} + +FUNCMATH FUNCINLINE static ATTRINLINE UINT8 R_Char2Rotation(char cn) +{ + if (cn >= '0' && cn <= '9') return (cn - '0'); + if (cn >= 'A' && cn <= 'G') return (cn - 'A') + 10; + if (cn == 'L') return ROT_L; + if (cn == 'R') return ROT_R; + return 255; } #endif //__R_THINGS__ diff --git a/src/st_stuff.c b/src/st_stuff.c index 9a1505ce3..68803b665 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1179,10 +1179,20 @@ static void ST_drawInput(void) "AUTOBRAKE"); y -= 8; } - if (stplyr->pflags & PF_ANALOGMODE) + switch (P_ControlStyle(stplyr)) { + case CS_LMAOGALOG: V_DrawThinString(x, y, hudinfo[HUD_LIVES].f, "ANALOG"); y -= 8; + break; + + case CS_SIMPLE: + V_DrawThinString(x, y, hudinfo[HUD_LIVES].f, "SIMPLE"); + y -= 8; + break; + + default: + break; } } if (!demosynced) // should always be last, so it doesn't push anything else around diff --git a/src/w_wad.c b/src/w_wad.c index 8de4876d9..44a4854f8 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -1465,6 +1465,21 @@ boolean W_IsPatchCached(lumpnum_t lumpnum, void *ptr) return W_IsPatchCachedPWAD(WADFILENUM(lumpnum),LUMPNUM(lumpnum), ptr); } +void W_FlushCachedPatches(void) +{ + if (needpatchflush) + { + Z_FreeTag(PU_CACHE); + Z_FreeTag(PU_PATCH); + Z_FreeTag(PU_HUDGFX); + Z_FreeTag(PU_HWRPATCHINFO); + Z_FreeTag(PU_HWRMODELTEXTURE); + Z_FreeTag(PU_HWRCACHE); + Z_FreeTags(PU_HWRCACHE_UNLOCKED, PU_HWRPATCHINFO_UNLOCKED); + } + needpatchflush = false; +} + // ========================================================================== // W_CacheLumpName // ========================================================================== @@ -1488,22 +1503,6 @@ void *W_CacheLumpName(const char *name, INT32 tag) // Cache a patch into heap memory, convert the patch format as necessary // -void W_FlushCachedPatches(void) -{ - if (needpatchflush) - { - Z_FreeTag(PU_CACHE); - Z_FreeTag(PU_PATCH); - Z_FreeTag(PU_HUDGFX); - Z_FreeTag(PU_HWRPATCHINFO); - Z_FreeTag(PU_HWRMODELTEXTURE); - Z_FreeTag(PU_HWRCACHE); - Z_FreeTags(PU_HWRCACHE_UNLOCKED, PU_HWRPATCHINFO_UNLOCKED); - } - needpatchflush = false; -} - -// Software-only compile cache the data without conversion void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag) { #ifdef HWRENDER