diff --git a/include/PR/os_cont.h b/include/PR/os_cont.h index 15ee60f3..b266aa71 100644 --- a/include/PR/os_cont.h +++ b/include/PR/os_cont.h @@ -60,6 +60,8 @@ typedef struct { u16 button; s8 stick_x; /* -80 <= stick_x <= 80 */ s8 stick_y; /* -80 <= stick_y <= 80 */ + s8 ext_stick_x; + s8 ext_stick_y; u8 errnum; } OSContPad; diff --git a/include/text_options_strings.h.in b/include/text_options_strings.h.in index 141d3548..6d7aff9e 100644 --- a/include/text_options_strings.h.in +++ b/include/text_options_strings.h.in @@ -40,6 +40,7 @@ #define TEXT_OPT_CAMC _("CAMERA CENTRE AGGRESSION") #define TEXT_OPT_CAMP _("CAMERA PAN LEVEL") #define TEXT_OPT_CAMD _("CAMERA DECELERATION") +#define TEXT_OPT_CAMON _("FREE CAMERA") #define TEXT_OPT_ANALOGUE _("ANALOGUE CAMERA") #define TEXT_OPT_MOUSE _("MOUSE LOOK") #define TEXT_OPT_TEXFILTER _("TEXTURE FILTERING") @@ -103,6 +104,7 @@ #define TEXT_OPT_CAMC _("Camera Centre Aggression") #define TEXT_OPT_CAMP _("Camera Pan Level") #define TEXT_OPT_CAMD _("Camera Deceleration") +#define TEXT_OPT_CAMON _("Free Camera") #define TEXT_OPT_ANALOGUE _("Analogue Camera") #define TEXT_OPT_MOUSE _("Mouse Look") #define TEXT_OPT_TEXFILTER _("Texture Filtering") diff --git a/include/types.h b/include/types.h index d11e2380..19256d74 100644 --- a/include/types.h +++ b/include/types.h @@ -31,6 +31,8 @@ struct Controller /*0x14*/ OSContStatus *statusData; /*0x18*/ OSContPad *controllerData; /*0x1C*/ int port; + /*ext */ s16 extStickX; // additional (right) stick values + /*ext */ s16 extStickY; }; typedef f32 Vec2f[2]; diff --git a/src/game/bettercamera.h b/src/game/bettercamera.h index ea814dd7..2f7cd376 100644 --- a/src/game/bettercamera.h +++ b/src/game/bettercamera.h @@ -27,17 +27,17 @@ enum newcam_flagvalues }; extern void newcam_init_settings(void); +extern void newcam_disable(void); extern void newcam_diagnostics(void); - -extern u8 newcam_sensitivityX; //How quick the camera works. -extern u8 newcam_sensitivityY; -extern u8 newcam_invertX; -extern u8 newcam_invertY; -extern u8 newcam_panlevel; //How much the camera sticks out a bit in the direction you're looking. -extern u8 newcam_aggression; //How much the camera tries to centre itself to Mario's facing and movement. +extern s16 newcam_sensitivityX; //How quick the camera works. +extern s16 newcam_sensitivityY; +extern s16 newcam_invertX; +extern s16 newcam_invertY; +extern s16 newcam_panlevel; //How much the camera sticks out a bit in the direction you're looking. +extern s16 newcam_aggression; //How much the camera tries to centre itself to Mario's facing and movement. extern u8 newcam_active; // basically the thing that governs if newcam is on. -extern u8 newcam_analogue; +extern s16 newcam_analogue; extern u16 newcam_intendedmode; extern u16 newcam_mode; diff --git a/src/game/bettercamera.inc.h b/src/game/bettercamera.inc.h index c2003347..c871f84d 100644 --- a/src/game/bettercamera.inc.h +++ b/src/game/bettercamera.inc.h @@ -9,6 +9,7 @@ #include "include/text_strings.h" #include "engine/surface_collision.h" #include "pc/configfile.h" +#include "pc/controller/controller_mouse.h" #if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) //quick and dirty fix for some older MinGW.org mingwrt #else @@ -34,8 +35,7 @@ NC_MODE_NOTURN: Disables horizontal and vertical control of the camera. //!Hardcoded camera angle stuff. They're essentially area boxes that when Mario is inside, will trigger some view changes. ///Don't touch this btw, unless you know what you're doing, this has to be above for religious reasons. -struct newcam_hardpos -{ +struct newcam_hardpos { u8 newcam_hard_levelID; u8 newcam_hard_areaID; u8 newcam_hard_permaswap; @@ -57,13 +57,14 @@ struct newcam_hardpos ///This is the bit that defines where the angles happen. They're basically environment boxes that dictate camera behaviour. //Permaswap is a boolean that simply determines wether or not when the camera changes at this point it stays changed. 0 means it resets when you leave, and 1 means it stays changed. //The camera position fields accept "32767" as an ignore flag. -struct newcam_hardpos newcam_fixedcam[] = -{ -{/*Level ID*/ 16,/*Area ID*/ 1,/*Permaswap*/ 0,/*Mode*/ NC_MODE_FIXED_NOMOVE, //Standard params. -/*X begin*/ -540,/*Y begin*/ 800,/*Z begin*/ -3500, //Where the activation box begins -/*X end*/ 540,/*Y end*/ 2000,/*Z end*/ -1500, //Where the activation box ends. -/*Cam X*/ 0,/*Cam Y*/ 1500,/*Cam Z*/ -1000, //The position the camera gets placed for NC_MODE_FIXED and NC_MODE_FIXED_NOMOVE -/*Look X*/ 0,/*Look Y*/ 800,/*Look Z*/ -2500}, //The position the camera looks at for NC_MODE_FIXED_NOMOVE +struct newcam_hardpos newcam_fixedcam[] = { + { + /*Level ID*/ 16,/*Area ID*/ 1,/*Permaswap*/ 0,/*Mode*/ NC_MODE_FIXED_NOMOVE, //Standard params. + /*X begin*/ -540,/*Y begin*/ 800,/*Z begin*/ -3500, //Where the activation box begins + /*X end*/ 540,/*Y end*/ 2000,/*Z end*/ -1500, //Where the activation box ends. + /*Cam X*/ 0,/*Cam Y*/ 1500,/*Cam Z*/ -1000, //The position the camera gets placed for NC_MODE_FIXED and NC_MODE_FIXED_NOMOVE + /*Look X*/ 0,/*Look Y*/ 800,/*Look Z*/ -2500 //The position the camera looks at for NC_MODE_FIXED_NOMOVE + }, }; @@ -74,9 +75,9 @@ struct newcam_hardpos newcam_fixedcam[] = #endif // noaccel s16 newcam_yaw; //Z axis rotation -s16 newcam_yaw_acc; +f32 newcam_yaw_acc; s16 newcam_tilt = 1500; //Y axis rotation -s16 newcam_tilt_acc; +f32 newcam_tilt_acc; u16 newcam_distance = 750; //The distance the camera stays from the player u16 newcam_distance_target = 750; //The distance the player camera tries to reach. f32 newcam_pos_target[3]; //The position the camera is basing calculations off. *usually* Mario. @@ -89,38 +90,39 @@ s16 newcam_yaw_target; // The yaw value the camera tries to set itself to when t f32 newcam_turnwait; // The amount of time to wait after landing before allowing the camera to turn again f32 newcam_pan_x; f32 newcam_pan_z; -f32 newcam_degrade = 0.1f; //What percent of the remaining camera movement is degraded. Default is 10% u8 newcam_cstick_down = 0; //Just a value that triggers true when the player 2 stick is moved in 8 direction move to prevent holding it down. u8 newcam_target; +s32 newcam_sintimer = 0; +s16 newcam_coldist; +u8 newcam_xlu = 255; +s8 newcam_stick2[2]; -u8 newcam_sensitivityX; //How quick the camera works. -u8 newcam_sensitivityY; -u8 newcam_invertX; //Reverses movement of the camera axis. -u8 newcam_invertY; -u8 newcam_panlevel; //How much the camera sticks out a bit in the direction you're looking. -u8 newcam_aggression; //How much the camera tries to centre itself to Mario's facing and movement. -u8 newcam_analogue; //Wether to accept inputs from a player 2 joystick, and then disables C button input. -u8 newcam_mouse; // Whether to accept mouse input +s16 newcam_sensitivityX; //How quick the camera works. +s16 newcam_sensitivityY; +s16 newcam_invertX; //Reverses movement of the camera axis. +s16 newcam_invertY; +s16 newcam_panlevel; //How much the camera sticks out a bit in the direction you're looking. +s16 newcam_aggression ; //How much the camera tries to centre itself to Mario's facing and movement. +s16 newcam_degrade = 1; +s16 newcam_analogue = 0; //Wether to accept inputs from a player 2 joystick, and then disables C button input. s16 newcam_distance_values[] = {750,1250,2000}; -u8 newcam_active = 1; // basically the thing that governs if newcam is on. +u8 newcam_active = 0; // basically the thing that governs if newcam is on. +u8 newcam_mouse = 0; u16 newcam_mode; u16 newcam_intendedmode = 0; // which camera mode the camera's going to try to be in when not forced into another. u16 newcam_modeflags; - -extern int mouse_x; -extern int mouse_y; +s16 newcam_saved_mode = -1; +s16 newcam_saved_defmode = -1; ///This is called at every level initialisation. -void newcam_init(struct Camera *c, u8 dv) -{ +void newcam_init(struct Camera *c, u8 dv) { newcam_tilt = 1500; newcam_distance_target = newcam_distance_values[dv]; newcam_yaw = -c->yaw+0x4000; //Mario and the camera's yaw have this offset between them. newcam_mode = NC_MODE_NORMAL; ///This here will dictate what modes the camera will start in at the beginning of a level. Below are some examples. - switch (gCurrLevelNum) - { + switch (gCurrLevelNum) { case LEVEL_BITDW: newcam_yaw = 0x4000; newcam_mode = NC_MODE_8D; newcam_tilt = 4000; newcam_distance_target = newcam_distance_values[2]; break; case LEVEL_BITFS: newcam_yaw = 0x4000; newcam_mode = NC_MODE_8D; newcam_tilt = 4000; newcam_distance_target = newcam_distance_values[2]; break; case LEVEL_BITS: newcam_yaw = 0x4000; newcam_mode = NC_MODE_8D; newcam_tilt = 4000; newcam_distance_target = newcam_distance_values[2]; break; @@ -132,47 +134,67 @@ void newcam_init(struct Camera *c, u8 dv) case LEVEL_TTM: if (gCurrAreaIndex == 2) newcam_mode = NC_MODE_SLIDE; break; } + // clear these out when entering a new level to prevent "camera mode buffering" + newcam_saved_defmode = -1; + newcam_saved_mode = -1; + newcam_distance = newcam_distance_target; newcam_intendedmode = newcam_mode; newcam_modeflags = newcam_mode; } -static u8 newcam_clamp(u8 value, u8 min, u8 max) -{ - if (value > max) - value = max; - if (value < min) - value = min; - return value; +static s16 newcam_clamp(s16 value, s16 min, s16 max) { + if (value >= max) + return max; + else if (value <= min) + return min; + else + return value; +} + +void newcam_toggle(const bool enabled) { + if (enabled && !newcam_active) { + newcam_active = 1; + newcam_saved_mode = gLakituState.mode; + newcam_saved_defmode = gLakituState.defMode; + gLakituState.mode = CAMERA_MODE_NEWCAM; + gLakituState.defMode = CAMERA_MODE_NEWCAM; + } else if (!enabled && newcam_active) { + if (newcam_saved_mode != -1) { + gLakituState.defMode = newcam_saved_defmode; + gLakituState.mode = newcam_saved_mode; + newcam_saved_defmode = -1; + newcam_saved_mode = -1; + } + newcam_active = 0; + } } ///These are the default settings for Puppycam. You may change them to change how they'll be set for first timers. -void newcam_init_settings(void) -{ - newcam_sensitivityX = newcam_clamp(configCameraXSens, 10, 250); - newcam_sensitivityY = newcam_clamp(configCameraYSens, 10, 250); +void newcam_init_settings(void) { + newcam_sensitivityX = newcam_clamp(configCameraXSens, 1, 100) * 5; + newcam_sensitivityY = newcam_clamp(configCameraYSens, 1, 100) * 5; newcam_aggression = newcam_clamp(configCameraAggr, 0, 100); newcam_panlevel = newcam_clamp(configCameraPan, 0, 100); - newcam_invertX = (u8)configCameraInvertX; - newcam_invertY = (u8)configCameraInvertY; + newcam_invertX = (s16)configCameraInvertX; + newcam_invertY = (s16)configCameraInvertY; newcam_mouse = (u8)configCameraMouse; - newcam_analogue = (u8)configEnableCamera; - newcam_degrade = (f32)configCameraDegrade / 100.0f; + newcam_analogue = (s16)configCameraAnalog; + newcam_degrade = (f32)configCameraDegrade; + + newcam_toggle(configEnableCamera); } /** Mathematic calculations. This stuffs so basic even *I* understand it lol Basically, it just returns a position based on angle */ -static s16 lengthdir_x(f32 length, s16 dir) -{ +static s16 lengthdir_x(f32 length, s16 dir) { return (s16) (length * coss(dir)); } -static s16 lengthdir_y(f32 length, s16 dir) -{ +static s16 lengthdir_y(f32 length, s16 dir) { return (s16) (length * sins(dir)); } -void newcam_diagnostics(void) -{ +void newcam_diagnostics(void) { print_text_fmt_int(32,192,"Lv %d",gCurrLevelNum); print_text_fmt_int(32,176,"Area %d",gCurrAreaIndex); print_text_fmt_int(32,160,"X %d",gMarioState->pos[0]); @@ -187,50 +209,41 @@ void newcam_diagnostics(void) print_text_fmt_int(32,32,"DISTANCE %d",newcam_distance); } -static s16 newcam_adjust_value(s16 var, s16 val, s16 max) -{ - if (val > 0) - { +static s16 newcam_adjust_value(f32 var, f32 val, f32 max) { + if (val > 0.0f) { var += val; if (var > max) var = max; - } - else if (val < 0) - { + } else if (val < 0.0f) { var += val; if (var < max) var = max; } + return var; } -static f32 newcam_approach_float(f32 var, f32 val, f32 inc) -{ +static f32 newcam_approach_float(f32 var, f32 val, f32 inc) { if (var < val) return min(var + inc, val); - else + else return max(var - inc, val); } -static s16 newcam_approach_s16(s16 var, s16 val, s16 inc) -{ +static s16 newcam_approach_s16(s16 var, s16 val, s16 inc) { if (var < val) return max(var + inc, val); - else + else return min(var - inc, val); } -static int ivrt(u8 axis) -{ - if (axis == 0) - { +static int ivrt(u8 axis) { + if (axis == 0) { if (newcam_invertX == 0) return -1; else return 1; - } - else - { + } else { if (newcam_invertY == 0) return 1; else @@ -238,75 +251,63 @@ static int ivrt(u8 axis) } } -static void newcam_rotate_button(void) -{ +static void newcam_rotate_button(void) { f32 intendedXMag; f32 intendedYMag; - if ((newcam_modeflags & NC_FLAG_8D || newcam_modeflags & NC_FLAG_4D) && newcam_modeflags & NC_FLAG_XTURN) //8 directional camera rotation input for buttons. - { - if ((gPlayer1Controller->buttonPressed & L_CBUTTONS) && newcam_analogue == 0) - { + + if ((newcam_modeflags & NC_FLAG_8D || newcam_modeflags & NC_FLAG_4D) && newcam_modeflags & NC_FLAG_XTURN) { + //8 directional camera rotation input for buttons. + if ((gPlayer1Controller->buttonPressed & L_CBUTTONS) && newcam_analogue == 0) { #ifndef nosound play_sound(SOUND_MENU_CAMERA_ZOOM_IN, gDefaultSoundArgs); #endif if (newcam_modeflags & NC_FLAG_8D) - newcam_yaw_target = newcam_yaw_target+0x2000; + newcam_yaw_target = newcam_yaw_target+(ivrt(newcam_invertX)*0x2000); else - newcam_yaw_target = newcam_yaw_target+0x4000; + newcam_yaw_target = newcam_yaw_target+(ivrt(newcam_invertX)*0x4000); newcam_centering = 1; - } - else - if ((gPlayer1Controller->buttonPressed & R_CBUTTONS) && newcam_analogue == 0) - { + } else if ((gPlayer1Controller->buttonPressed & R_CBUTTONS) && newcam_analogue == 0) { #ifndef nosound play_sound(SOUND_MENU_CAMERA_ZOOM_IN, gDefaultSoundArgs); #endif if (newcam_modeflags & NC_FLAG_8D) - newcam_yaw_target = newcam_yaw_target-0x2000; + newcam_yaw_target = newcam_yaw_target-(ivrt(newcam_invertX)*0x2000); else - newcam_yaw_target = newcam_yaw_target-0x4000; + newcam_yaw_target = newcam_yaw_target-(ivrt(newcam_invertX)*0x4000); newcam_centering = 1; } - } - else //Standard camera movement - if (newcam_modeflags & NC_FLAG_XTURN) - { - if ((gPlayer1Controller->buttonDown & L_CBUTTONS) && newcam_analogue == 0) - newcam_yaw_acc = newcam_adjust_value(newcam_yaw_acc,accel, 100); - else if ((gPlayer1Controller->buttonDown & R_CBUTTONS) && newcam_analogue == 0) - newcam_yaw_acc = newcam_adjust_value(newcam_yaw_acc,-accel, -100); - else - if (!newcam_analogue) - { + } else if (newcam_modeflags & NC_FLAG_XTURN) { + //Standard camera movement + if ((gPlayer1Controller->buttonDown & L_CBUTTONS) && newcam_analogue == 0) { + newcam_yaw_acc = newcam_adjust_value(newcam_yaw_acc, -accel, -100); + } else if ((gPlayer1Controller->buttonDown & R_CBUTTONS) && newcam_analogue == 0) { + newcam_yaw_acc = newcam_adjust_value(newcam_yaw_acc, accel, 100); + } else if (!newcam_analogue) { #ifdef noaccel newcam_yaw_acc = 0; #else - newcam_yaw_acc -= (newcam_yaw_acc*newcam_degrade); + newcam_yaw_acc -= (newcam_yaw_acc*((f32)newcam_degrade/100)); #endif } } - if (gPlayer1Controller->buttonDown & U_CBUTTONS && newcam_modeflags & NC_FLAG_YTURN && newcam_analogue == 0) - newcam_tilt_acc = newcam_adjust_value(newcam_tilt_acc,accel, 100); - else if (gPlayer1Controller->buttonDown & D_CBUTTONS && newcam_modeflags & NC_FLAG_YTURN && newcam_analogue == 0) - newcam_tilt_acc = newcam_adjust_value(newcam_tilt_acc,-accel, -100); - else - if (!newcam_analogue) - { + if (gPlayer1Controller->buttonDown & U_CBUTTONS && newcam_modeflags & NC_FLAG_YTURN && newcam_analogue == 0) { + newcam_tilt_acc = newcam_adjust_value(newcam_tilt_acc, accel, 100); + } else if (gPlayer1Controller->buttonDown & D_CBUTTONS && newcam_modeflags & NC_FLAG_YTURN && newcam_analogue == 0) { + newcam_tilt_acc = newcam_adjust_value(newcam_tilt_acc, -accel, -100); + } else if (!newcam_analogue) { #ifdef noaccel newcam_tilt_acc = 0; #else - newcam_tilt_acc -= (newcam_tilt_acc*newcam_degrade); + newcam_tilt_acc -= (newcam_tilt_acc*((f32)newcam_degrade/100)); #endif } - newcam_framessincec[0] += 1; - newcam_framessincec[1] += 1; - if ((gPlayer1Controller->buttonPressed & L_CBUTTONS) && newcam_modeflags & NC_FLAG_XTURN && !(newcam_modeflags & NC_FLAG_8D) && newcam_analogue == 0) - { - if (newcam_framessincec[0] < 6) - { - newcam_yaw_target = newcam_yaw+0x3000; + newcam_framessincec[0] ++; + newcam_framessincec[1] ++; + if ((gPlayer1Controller->buttonPressed & L_CBUTTONS) && newcam_modeflags & NC_FLAG_XTURN && !(newcam_modeflags & NC_FLAG_8D) && newcam_analogue == 0) { + if (newcam_framessincec[0] < 6) { + newcam_yaw_target = newcam_yaw+(ivrt(newcam_invertX)*0x3000); newcam_centering = 1; #ifndef nosound play_sound(SOUND_MENU_CAMERA_ZOOM_IN, gDefaultSoundArgs); @@ -314,11 +315,9 @@ static void newcam_rotate_button(void) } newcam_framessincec[0] = 0; } - if ((gPlayer1Controller->buttonPressed & R_CBUTTONS) && newcam_modeflags & NC_FLAG_XTURN && !(newcam_modeflags & NC_FLAG_8D) && newcam_analogue == 0) - { - if (newcam_framessincec[1] < 6) - { - newcam_yaw_target = newcam_yaw-0x3000; + if ((gPlayer1Controller->buttonPressed & R_CBUTTONS) && newcam_modeflags & NC_FLAG_XTURN && !(newcam_modeflags & NC_FLAG_8D) && newcam_analogue == 0) { + if (newcam_framessincec[1] < 6) { + newcam_yaw_target = newcam_yaw-(ivrt(newcam_invertX)*0x3000); newcam_centering = 1; #ifndef nosound play_sound(SOUND_MENU_CAMERA_ZOOM_IN, gDefaultSoundArgs); @@ -328,176 +327,146 @@ static void newcam_rotate_button(void) } - if (newcam_analogue == 1) //There's not much point in keeping this behind a check, but it wouldn't hurt, just incase any 2player shenanigans ever happen, it makes it easy to disable. - { //The joystick values cap at 80, so divide by 8 to get the same net result at maximum turn as the button - intendedXMag = gPlayer2Controller->stickX*1.25; - intendedYMag = gPlayer2Controller->stickY*1.25; - if (ABS(gPlayer2Controller->stickX) > 20 && newcam_modeflags & NC_FLAG_XTURN) - { - if (newcam_modeflags & NC_FLAG_8D) - { - if (newcam_cstick_down == 0) - { + //There's not much point in keeping this behind a check, but it wouldn't hurt, just incase any 2player shenanigans ever happen, it makes it easy to disable. + if (newcam_analogue == 1) { + //The joystick values cap at 80, so divide by 8 to get the same net result at maximum turn as the button + intendedXMag = newcam_stick2[0]*1.25; + intendedYMag = newcam_stick2[1]*1.25; + + if (ABS(newcam_stick2[0]) > 20 && newcam_modeflags & NC_FLAG_XTURN) { + if (newcam_modeflags & NC_FLAG_8D) { + if (newcam_cstick_down == 0) { newcam_cstick_down = 1; newcam_centering = 1; #ifndef nosound play_sound(SOUND_MENU_CAMERA_ZOOM_IN, gDefaultSoundArgs); #endif - if (gPlayer2Controller->stickX > 20) - { + if (newcam_stick2[0] > 20) { if (newcam_modeflags & NC_FLAG_8D) - newcam_yaw_target = newcam_yaw_target+0x2000; + newcam_yaw_target = newcam_yaw_target+(ivrt(newcam_invertX)*0x2000); else - newcam_yaw_target = newcam_yaw_target+0x4000; - } - else - { + newcam_yaw_target = newcam_yaw_target+(ivrt(newcam_invertX)*0x4000); + } else { if (newcam_modeflags & NC_FLAG_8D) - newcam_yaw_target = newcam_yaw_target-0x2000; + newcam_yaw_target = newcam_yaw_target-(ivrt(newcam_invertX)*0x2000); else - newcam_yaw_target = newcam_yaw_target-0x4000; + newcam_yaw_target = newcam_yaw_target-(ivrt(newcam_invertX)*0x4000); } } + } else { + newcam_yaw_acc = newcam_adjust_value(newcam_yaw_acc,newcam_stick2[0]*0.125, intendedXMag); } - else - { - newcam_yaw_acc = newcam_adjust_value(newcam_yaw_acc,-gPlayer2Controller->stickX/8, intendedXMag); - } - } - else - if (newcam_analogue) - { + } else if (newcam_analogue) { newcam_cstick_down = 0; - newcam_yaw_acc -= (newcam_yaw_acc*newcam_degrade); + newcam_yaw_acc -= (newcam_yaw_acc*((f32)newcam_degrade/100)); } - if (ABS(gPlayer2Controller->stickY) > 20 && newcam_modeflags & NC_FLAG_YTURN) - newcam_tilt_acc = newcam_adjust_value(newcam_tilt_acc,-gPlayer2Controller->stickY/8, intendedYMag); - else - if (newcam_analogue) - { - newcam_tilt_acc -= (newcam_tilt_acc*newcam_degrade); - } + if (ABS(newcam_stick2[1]) > 20 && newcam_modeflags & NC_FLAG_YTURN) + newcam_tilt_acc = newcam_adjust_value(newcam_tilt_acc, newcam_stick2[1]*0.125, intendedYMag); + else if (newcam_analogue) + newcam_tilt_acc -= (newcam_tilt_acc*((f32)newcam_degrade/100)); } - if (newcam_mouse == 1) - { + if (newcam_mouse == 1) { newcam_yaw += ivrt(0) * mouse_x * 16; newcam_tilt += ivrt(1) * mouse_y * 16; } } -static void newcam_zoom_button(void) -{ +static void newcam_zoom_button(void) { //Smoothly move the camera to the new spot. - if (newcam_distance > newcam_distance_target) - { + if (newcam_distance > newcam_distance_target) { newcam_distance -= 250; if (newcam_distance < newcam_distance_target) newcam_distance = newcam_distance_target; } - if (newcam_distance < newcam_distance_target) - { + if (newcam_distance < newcam_distance_target) { newcam_distance += 250; if (newcam_distance > newcam_distance_target) newcam_distance = newcam_distance_target; } - //When you press L, set the flag for centering the camera. Afterwards, start setting the yaw to the Player's yaw at the time. - if (gPlayer1Controller->buttonDown & L_TRIG && newcam_modeflags & NC_FLAG_ZOOM) - { + //When you press L and R together, set the flag for centering the camera. Afterwards, start setting the yaw to the Player's yaw at the time. + if (gPlayer1Controller->buttonDown & L_TRIG && gPlayer1Controller->buttonDown & R_TRIG && newcam_modeflags & NC_FLAG_ZOOM) { newcam_yaw_target = -gMarioState->faceAngle[1]-0x4000; newcam_centering = 1; - } - else //Each time the player presses R, but NOT L the camera zooms out more, until it hits the limit and resets back to close view. - if (gPlayer1Controller->buttonPressed & R_TRIG && newcam_modeflags & NC_FLAG_XTURN) - { + } else if (gPlayer1Controller->buttonPressed & R_TRIG && newcam_modeflags & NC_FLAG_XTURN) { + //Each time the player presses R, but NOT L the camera zooms out more, until it hits the limit and resets back to close view. #ifndef nosound play_sound(SOUND_MENU_CLICK_CHANGE_VIEW, gDefaultSoundArgs); #endif if (newcam_distance_target == newcam_distance_values[0]) newcam_distance_target = newcam_distance_values[1]; - else - if (newcam_distance_target == newcam_distance_values[1]) + else if (newcam_distance_target == newcam_distance_values[1]) newcam_distance_target = newcam_distance_values[2]; else newcam_distance_target = newcam_distance_values[0]; - } - if (newcam_centering && newcam_modeflags & NC_FLAG_XTURN) - { + + if (newcam_centering && newcam_modeflags & NC_FLAG_XTURN) { newcam_yaw = approach_s16_symmetric(newcam_yaw,newcam_yaw_target,0x800); if (newcam_yaw == newcam_yaw_target) newcam_centering = 0; - } - else + } else { newcam_yaw_target = newcam_yaw; + } } -static void newcam_update_values(void) -{//For tilt, this just limits it so it doesn't go further than 90 degrees either way. 90 degrees is actually 16384, but can sometimes lead to issues, so I just leave it shy of 90. +static void newcam_update_values(void) { + //For tilt, this just limits it so it doesn't go further than 90 degrees either way. 90 degrees is actually 16384, but can sometimes lead to issues, so I just leave it shy of 90. u8 waterflag = 0; - if (newcam_modeflags & NC_FLAG_XTURN) - newcam_yaw += ((ivrt(0)*(newcam_yaw_acc*(newcam_sensitivityX/10)))); - if (((newcam_tilt < 12000 && newcam_tilt_acc*ivrt(1) > 0) || (newcam_tilt > -12000 && newcam_tilt_acc*ivrt(1) < 0)) && newcam_modeflags & NC_FLAG_YTURN) - newcam_tilt += ((ivrt(1)*(newcam_tilt_acc*(newcam_sensitivityY/10)))); - else - { - if (newcam_tilt > 12000) - newcam_tilt = 12000; - if (newcam_tilt < -12000) - newcam_tilt = -12000; - } - if (newcam_turnwait > 0 && gMarioState->vel[1] == 0) - { - newcam_turnwait -= 1; - if (newcam_turnwait < 0) - newcam_turnwait = 0; - } - else - { - if (gMarioState->intendedMag > 0 && gMarioState->vel[1] == 0 && newcam_modeflags & NC_FLAG_XTURN) - newcam_yaw = (approach_s16_symmetric(newcam_yaw,-gMarioState->faceAngle[1]-0x4000,((newcam_aggression*(ABS(gPlayer1Controller->stickX/10)))*(gMarioState->forwardVel/32)))); + if (newcam_modeflags & NC_FLAG_XTURN) + newcam_yaw -= ((newcam_yaw_acc*(newcam_sensitivityX/10))*ivrt(newcam_invertX)); + if (((newcam_tilt <= 12000) && (newcam_tilt >= -12000)) && newcam_modeflags & NC_FLAG_YTURN) + newcam_tilt += ((newcam_tilt_acc*ivrt(newcam_invertY))*(newcam_sensitivityY/10)); + + if (newcam_tilt > 12000) + newcam_tilt = 12000; + if (newcam_tilt < -12000) + newcam_tilt = -12000; + + if (newcam_turnwait > 0 && gMarioState->vel[1] == 0) { + newcam_turnwait -= 1; + if (newcam_turnwait < 0) + newcam_turnwait = 0; + } else { + if (gMarioState->intendedMag > 0 && gMarioState->vel[1] == 0 && newcam_modeflags & NC_FLAG_XTURN && !(newcam_modeflags & NC_FLAG_8D) && !(newcam_modeflags & NC_FLAG_4D)) + newcam_yaw = (approach_s16_symmetric(newcam_yaw,-gMarioState->faceAngle[1]-0x4000,((newcam_aggression*(ABS(gPlayer1Controller->rawStickX/10)))*(gMarioState->forwardVel/32)))); else newcam_turnwait = 10; - } + } - if (newcam_modeflags & NC_FLAG_SLIDECORRECT) - { - switch (gMarioState->action) - { - case ACT_BUTT_SLIDE: if (gMarioState->forwardVel > 8) waterflag = 1; break; - case ACT_STOMACH_SLIDE: if (gMarioState->forwardVel > 8) waterflag = 1; break; - case ACT_HOLD_BUTT_SLIDE: if (gMarioState->forwardVel > 8) waterflag = 1; break; - case ACT_HOLD_STOMACH_SLIDE: if (gMarioState->forwardVel > 8) waterflag = 1; break; - } - } - switch (gMarioState->action) - { - case ACT_SHOT_FROM_CANNON: waterflag = 1; break; - case ACT_FLYING: waterflag = 1; break; + if (newcam_modeflags & NC_FLAG_SLIDECORRECT) { + switch (gMarioState->action) { + case ACT_BUTT_SLIDE: if (gMarioState->forwardVel > 8) waterflag = 1; break; + case ACT_STOMACH_SLIDE: if (gMarioState->forwardVel > 8) waterflag = 1; break; + case ACT_HOLD_BUTT_SLIDE: if (gMarioState->forwardVel > 8) waterflag = 1; break; + case ACT_HOLD_STOMACH_SLIDE: if (gMarioState->forwardVel > 8) waterflag = 1; break; } + } - if (gMarioState->action & ACT_FLAG_SWIMMING) - { - if (gMarioState->forwardVel > 2) - waterflag = 1; - } + switch (gMarioState->action) { + case ACT_SHOT_FROM_CANNON: waterflag = 1; break; + case ACT_FLYING: waterflag = 1; break; + } - if (waterflag && newcam_modeflags & NC_FLAG_XTURN) - { - newcam_yaw = (approach_s16_symmetric(newcam_yaw,-gMarioState->faceAngle[1]-0x4000,(gMarioState->forwardVel*128))); - if ((signed)gMarioState->forwardVel > 1) - newcam_tilt = (approach_s16_symmetric(newcam_tilt,(-gMarioState->faceAngle[0]*0.8)+3000,(gMarioState->forwardVel*32))); - else - newcam_tilt = (approach_s16_symmetric(newcam_tilt,3000,32)); - } + if (gMarioState->action & ACT_FLAG_SWIMMING) { + if (gMarioState->forwardVel > 2) + waterflag = 1; + } + + if (waterflag && newcam_modeflags & NC_FLAG_XTURN) { + newcam_yaw = (approach_s16_symmetric(newcam_yaw,-gMarioState->faceAngle[1]-0x4000,(gMarioState->forwardVel*128))); + if ((signed)gMarioState->forwardVel > 1) + newcam_tilt = (approach_s16_symmetric(newcam_tilt,(-gMarioState->faceAngle[0]*0.8)+3000,(gMarioState->forwardVel*32))); + else + newcam_tilt = (approach_s16_symmetric(newcam_tilt,3000,32)); + } } -static void newcam_collision(void) -{ +static void newcam_collision(void) { struct Surface *surf; Vec3f camdir; Vec3f hitpos; @@ -506,12 +475,10 @@ static void newcam_collision(void) camdir[1] = newcam_pos[1]-newcam_lookat[1]; camdir[2] = newcam_pos[2]-newcam_lookat[2]; - - find_surface_on_ray(newcam_pos_target, camdir, &surf, hitpos); + newcam_coldist = sqrtf((newcam_pos_target[0] - hitpos[0]) * (newcam_pos_target[0] - hitpos[0]) + (newcam_pos_target[1] - hitpos[1]) * (newcam_pos_target[1] - hitpos[1]) + (newcam_pos_target[2] - hitpos[2]) * (newcam_pos_target[2] - hitpos[2])); - if (surf) - { + if (surf) { newcam_pos[0] = hitpos[0]; newcam_pos[1] = approach_f32(hitpos[1],newcam_pos[1],25,-25); newcam_pos[2] = hitpos[2]; @@ -520,16 +487,12 @@ static void newcam_collision(void) } } -static void newcam_set_pan(void) -{ +static void newcam_set_pan(void) { //Apply panning values based on Mario's direction. - if (gMarioState->action != ACT_HOLDING_BOWSER && gMarioState->action != ACT_SLEEPING && gMarioState->action != ACT_START_SLEEPING) - { + if (gMarioState->action != ACT_HOLDING_BOWSER && gMarioState->action != ACT_SLEEPING && gMarioState->action != ACT_START_SLEEPING) { approach_f32_asymptotic_bool(&newcam_pan_x, lengthdir_x((160*newcam_panlevel)/100, -gMarioState->faceAngle[1]-0x4000), 0.05); approach_f32_asymptotic_bool(&newcam_pan_z, lengthdir_y((160*newcam_panlevel)/100, -gMarioState->faceAngle[1]-0x4000), 0.05); - } - else - { + } else { approach_f32_asymptotic_bool(&newcam_pan_x, 0, 0.05); approach_f32_asymptotic_bool(&newcam_pan_z, 0, 0.05); } @@ -538,14 +501,13 @@ static void newcam_set_pan(void) newcam_pan_z = newcam_pan_z*(min(newcam_distance/newcam_distance_target,1)); } -static void newcam_position_cam(void) -{ +static void newcam_position_cam(void) { f32 floorY = 0; f32 floorY2 = 0; s16 shakeX; s16 shakeY; - if (!(gMarioState->action & ACT_FLAG_SWIMMING)) + if (!(gMarioState->action & ACT_FLAG_SWIMMING) && newcam_modeflags & NC_FLAG_FOCUSY && newcam_modeflags & NC_FLAG_POSY) calc_y_to_curr_floor(&floorY, 1.f, 200.f, &floorY2, 0.9f, 200.f); newcam_update_values(); @@ -558,9 +520,9 @@ static void newcam_position_cam(void) //These will set the position of the camera to where Mario is supposed to be, minus adjustments for where the camera should be, on top of. if (newcam_modeflags & NC_FLAG_POSX) newcam_pos[0] = newcam_pos_target[0]+lengthdir_x(lengthdir_x(newcam_distance,newcam_tilt+shakeX),newcam_yaw+shakeY); - if (newcam_modeflags & NC_FLAG_POSY) - newcam_pos[2] = newcam_pos_target[2]+lengthdir_y(lengthdir_x(newcam_distance,newcam_tilt+shakeX),newcam_yaw+shakeY); if (newcam_modeflags & NC_FLAG_POSZ) + newcam_pos[2] = newcam_pos_target[2]+lengthdir_y(lengthdir_x(newcam_distance,newcam_tilt+shakeX),newcam_yaw+shakeY); + if (newcam_modeflags & NC_FLAG_POSY) newcam_pos[1] = newcam_pos_target[1]+lengthdir_y(newcam_distance,newcam_tilt+gLakituState.shakeMagnitude[0])+floorY; if ((newcam_modeflags & NC_FLAG_FOCUSX) && (newcam_modeflags & NC_FLAG_FOCUSY) && (newcam_modeflags & NC_FLAG_FOCUSZ)) newcam_set_pan(); @@ -578,22 +540,18 @@ static void newcam_position_cam(void) } //Nested if's baybeeeee -static void newcam_find_fixed(void) -{ +static void newcam_find_fixed(void) { u8 i = 0; newcam_mode = newcam_intendedmode; newcam_modeflags = newcam_mode; - for (i = 0; i < sizeof(newcam_fixedcam); i++) - { - if (newcam_fixedcam[i].newcam_hard_levelID == gCurrLevelNum && newcam_fixedcam[i].newcam_hard_areaID == gCurrAreaIndex) - {//I didn't wanna just obliterate the horizontal plane of the IDE with a beefy if statement, besides, I think this runs slightly better anyway? - if (newcam_pos_target[0] > newcam_fixedcam[i].newcam_hard_X1) - if (newcam_pos_target[0] < newcam_fixedcam[i].newcam_hard_X2) - if (newcam_pos_target[1] > newcam_fixedcam[i].newcam_hard_Y1) - if (newcam_pos_target[1] < newcam_fixedcam[i].newcam_hard_Y2) - if (newcam_pos_target[2] > newcam_fixedcam[i].newcam_hard_Z1) - if (newcam_pos_target[2] < newcam_fixedcam[i].newcam_hard_Z2) - { + for (i = 0; i < sizeof(newcam_fixedcam) / sizeof(struct newcam_hardpos); i++) { + if (newcam_fixedcam[i].newcam_hard_levelID == gCurrLevelNum && newcam_fixedcam[i].newcam_hard_areaID == gCurrAreaIndex) { + if ((newcam_pos_target[0] > newcam_fixedcam[i].newcam_hard_X1) + && (newcam_pos_target[0] < newcam_fixedcam[i].newcam_hard_X2) + && (newcam_pos_target[1] > newcam_fixedcam[i].newcam_hard_Y1) + && (newcam_pos_target[1] < newcam_fixedcam[i].newcam_hard_Y2) + && (newcam_pos_target[2] > newcam_fixedcam[i].newcam_hard_Z1) + && (newcam_pos_target[2] < newcam_fixedcam[i].newcam_hard_Z2)) { if (newcam_fixedcam[i].newcam_hard_permaswap) newcam_intendedmode = newcam_fixedcam[i].newcam_hard_modeset; newcam_mode = newcam_fixedcam[i].newcam_hard_modeset; @@ -619,9 +577,7 @@ static void newcam_find_fixed(void) } } -static void newcam_apply_values(struct Camera *c) -{ - +static void newcam_apply_values(struct Camera *c) { c->pos[0] = newcam_pos[0]; c->pos[1] = newcam_pos[1]; c->pos[2] = newcam_pos[2]; @@ -642,37 +598,52 @@ static void newcam_apply_values(struct Camera *c) gLakituState.yaw = -newcam_yaw+0x4000; //Adds support for wing mario tower - if (gMarioState->floor && gMarioState->floor->type == SURFACE_LOOK_UP_WARP) { - if (save_file_get_total_star_count(gCurrSaveFileNum - 1, 0, 0x18) >= 10) { - if (newcam_tilt < -8000 && gMarioState->forwardVel == 0) { - level_trigger_warp(gMarioState, 1); + if (gMarioState->floor != NULL) { + if (gMarioState->floor->type == SURFACE_LOOK_UP_WARP) { + if (save_file_get_total_star_count(gCurrSaveFileNum - 1, 0, 0x18) >= 10) { + if (newcam_tilt < -8000 && gMarioState->forwardVel == 0) { + level_trigger_warp(gMarioState, 1); + } } } } - } -//The ingame cutscene system is such a spaghetti mess I actually have to resort to something as stupid as this to cover every base. -void newcam_apply_outside_values(struct Camera *c, u8 bit) -{ - if (newcam_modeflags == NC_FLAG_XTURN) - { - if (bit) - newcam_yaw = -gMarioState->faceAngle[1]-0x4000; +//If puppycam gets too close to its target, start fading it out so you don't see the inside of it. +void newcam_fade_target_closeup(void) { + if (newcam_coldist <= 250 && (newcam_coldist-150)*2.55f < 255) { + if ((newcam_coldist-150)*2.55f > 0) + newcam_xlu = (newcam_coldist-150)*2.55f; else - newcam_yaw = -c->yaw+0x4000; + newcam_xlu = 0; + } else { + newcam_xlu = 255; } } +//The ingame cutscene system is such a spaghetti mess I actually have to resort to something as stupid as this to cover every base. +void newcam_apply_outside_values(struct Camera *c, u8 bit) { + if (bit) + newcam_yaw = -gMarioState->faceAngle[1]-0x4000; + else + newcam_yaw = -c->yaw+0x4000; +} + +static void newcam_stick_input(void) { + newcam_stick2[0] = gPlayer1Controller->extStickX; + newcam_stick2[1] = gPlayer1Controller->extStickY; +} + //Main loop. -void newcam_loop(struct Camera *c) -{ +void newcam_loop(struct Camera *c) { + newcam_stick_input(); newcam_rotate_button(); newcam_zoom_button(); newcam_position_cam(); newcam_find_fixed(); if (gMarioObject) newcam_apply_values(c); + newcam_fade_target_closeup(); //Just some visual information on the values of the camera. utilises ifdef because it's better at runtime. #ifdef NEWCAM_DEBUG diff --git a/src/game/camera.c b/src/game/camera.c index c1f75d2f..bde06626 100644 --- a/src/game/camera.c +++ b/src/game/camera.c @@ -28,6 +28,7 @@ #include "paintings.h" #include "engine/graph_node.h" #include "level_table.h" +#include "pc/configfile.h" #define CBUTTON_MASK (U_CBUTTONS | D_CBUTTONS | L_CBUTTONS | R_CBUTTONS) @@ -3471,12 +3472,8 @@ void init_camera(struct Camera *c) { c->nextYaw = gLakituState.yaw; #ifdef BETTERCAMERA - if (newcam_active == 1) - { - gLakituState.mode = CAMERA_MODE_NEWCAM; - gLakituState.defMode = CAMERA_MODE_NEWCAM; - newcam_init(c, 0); - } + newcam_init(c, 0); + newcam_init_settings(); #endif } diff --git a/src/game/game_init.c b/src/game/game_init.c index 87012408..0c27c7c3 100644 --- a/src/game/game_init.c +++ b/src/game/game_init.c @@ -63,8 +63,6 @@ struct DemoInput *gCurrDemoInput = NULL; // demo input sequence u16 gDemoInputListID = 0; struct DemoInput gRecordedDemoInput = { 0 }; // possibly removed in EU. TODO: Check -extern int c_rightx; -extern int c_righty; /** * Initializes the Reality Display Processor (RDP). * This function initializes settings such as texture filtering mode, @@ -460,69 +458,34 @@ void read_controller_inputs(void) { } run_demo_inputs(); - #ifdef BETTERCAMERA - for (i = 0; i < 2; i++) - { + for (i = 0; i < 2; i++) { struct Controller *controller = &gControllers[i]; - if (i==1) // This is related to the analog camera control, using a P2 controller hack. P2 will no longer be correctly available for multiplayer. - { - controller->rawStickX = c_rightx; - controller->rawStickY = c_righty; - controller->stickX = c_rightx; - controller->stickY = c_righty; - } - else - { - // if we're receiving inputs, update the controller struct - // with the new button info. - if (controller->controllerData != NULL) { - controller->rawStickX = controller->controllerData->stick_x; - controller->rawStickY = controller->controllerData->stick_y; - controller->buttonPressed = controller->controllerData->button + // if we're receiving inputs, update the controller struct + // with the new button info. + if (controller->controllerData != NULL) { + controller->rawStickX = controller->controllerData->stick_x; + controller->rawStickY = controller->controllerData->stick_y; + controller->extStickX = controller->controllerData->ext_stick_x; + controller->extStickY = controller->controllerData->ext_stick_y; + controller->buttonPressed = controller->controllerData->button & (controller->controllerData->button ^ controller->buttonDown); - // 0.5x A presses are a good meme - controller->buttonDown = controller->controllerData->button; - adjust_analog_stick(controller); - } else // otherwise, if the controllerData is NULL, 0 out all of the inputs. - { - controller->rawStickX = 0; - controller->rawStickY = 0; - controller->buttonPressed = 0; - controller->buttonDown = 0; - controller->stickX = 0; - controller->stickY = 0; - controller->stickMag = 0; - } + // 0.5x A presses are a good meme + controller->buttonDown = controller->controllerData->button; + adjust_analog_stick(controller); + } else { + // otherwise, if the controllerData is NULL, 0 out all of the inputs. + controller->rawStickX = 0; + controller->rawStickY = 0; + controller->extStickX = 0; + controller->extStickY = 0; + controller->buttonPressed = 0; + controller->buttonDown = 0; + controller->stickX = 0; + controller->stickY = 0; + controller->stickMag = 0; } - } - #else - for (i = 0; i < 2; i++) { - struct Controller *controller = &gControllers[i]; - - // if we're receiving inputs, update the controller struct - // with the new button info. - if (controller->controllerData != NULL) { - controller->rawStickX = controller->controllerData->stick_x; - controller->rawStickY = controller->controllerData->stick_y; - controller->buttonPressed = controller->controllerData->button - & (controller->controllerData->button ^ controller->buttonDown); - // 0.5x A presses are a good meme - controller->buttonDown = controller->controllerData->button; - adjust_analog_stick(controller); - } else // otherwise, if the controllerData is NULL, 0 out all of the inputs. - { - controller->rawStickX = 0; - controller->rawStickY = 0; - controller->buttonPressed = 0; - controller->buttonDown = 0; - controller->stickX = 0; - controller->stickY = 0; - controller->stickMag = 0; - } - } - #endif // For some reason, player 1's inputs are copied to player 3's port. This // potentially may have been a way the developers "recorded" the inputs diff --git a/src/game/options_menu.c b/src/game/options_menu.c index e004749c..d2b356ae 100644 --- a/src/game/options_menu.c +++ b/src/game/options_menu.c @@ -69,6 +69,7 @@ static const u8 optsCameraStr[][32] = { { TEXT_OPT_ANALOGUE }, { TEXT_OPT_MOUSE }, { TEXT_OPT_CAMD }, + { TEXT_OPT_CAMON }, }; static const u8 optsVideoStr[][32] = { @@ -218,12 +219,13 @@ static void optvideo_apply(UNUSED struct Option *self, s32 arg) { #ifdef BETTERCAMERA static struct Option optsCamera[] = { - DEF_OPT_TOGGLE( optsCameraStr[6], &configEnableCamera ), + DEF_OPT_TOGGLE( optsCameraStr[9], &configEnableCamera ), + DEF_OPT_TOGGLE( optsCameraStr[6], &configCameraAnalog ), DEF_OPT_TOGGLE( optsCameraStr[7], &configCameraMouse ), DEF_OPT_TOGGLE( optsCameraStr[2], &configCameraInvertX ), DEF_OPT_TOGGLE( optsCameraStr[3], &configCameraInvertY ), - DEF_OPT_SCROLL( optsCameraStr[0], &configCameraXSens, 10, 250, 1 ), - DEF_OPT_SCROLL( optsCameraStr[1], &configCameraYSens, 10, 250, 1 ), + DEF_OPT_SCROLL( optsCameraStr[0], &configCameraXSens, 1, 100, 1 ), + DEF_OPT_SCROLL( optsCameraStr[1], &configCameraYSens, 1, 100, 1 ), DEF_OPT_SCROLL( optsCameraStr[4], &configCameraAggr, 0, 100, 1 ), DEF_OPT_SCROLL( optsCameraStr[5], &configCameraPan, 0, 100, 1 ), DEF_OPT_SCROLL( optsCameraStr[8], &configCameraDegrade, 0, 100, 1 ), diff --git a/src/pc/configfile.c b/src/pc/configfile.c index d5151216..855ee659 100644 --- a/src/pc/configfile.c +++ b/src/pc/configfile.c @@ -85,6 +85,7 @@ unsigned int configCameraDegrade = 10; // 0 - 100% bool configCameraInvertX = true; bool configCameraInvertY = false; bool configEnableCamera = false; +bool configCameraAnalog = true; bool configCameraMouse = false; #endif bool configSkipIntro = 0; @@ -126,6 +127,7 @@ static const struct ConfigOption options[] = { #endif #ifdef BETTERCAMERA {.name = "bettercam_enable", .type = CONFIG_TYPE_BOOL, .boolValue = &configEnableCamera}, + {.name = "bettercam_analog", .type = CONFIG_TYPE_BOOL, .boolValue = &configCameraAnalog}, {.name = "bettercam_mouse_look", .type = CONFIG_TYPE_BOOL, .boolValue = &configCameraMouse}, {.name = "bettercam_invertx", .type = CONFIG_TYPE_BOOL, .boolValue = &configCameraInvertX}, {.name = "bettercam_inverty", .type = CONFIG_TYPE_BOOL, .boolValue = &configCameraInvertY}, diff --git a/src/pc/configfile.h b/src/pc/configfile.h index 51064306..848a3494 100644 --- a/src/pc/configfile.h +++ b/src/pc/configfile.h @@ -52,6 +52,7 @@ extern bool configCameraInvertX; extern bool configCameraInvertY; extern bool configEnableCamera; extern bool configCameraMouse; +extern bool configCameraAnalog; #endif extern bool configHUD; extern bool configSkipIntro; diff --git a/src/pc/controller/controller_entry_point.c b/src/pc/controller/controller_entry_point.c index d5403f93..c2e5207a 100644 --- a/src/pc/controller/controller_entry_point.c +++ b/src/pc/controller/controller_entry_point.c @@ -11,11 +11,6 @@ // Analog camera movement by Pathétique (github.com/vrmiguel), y0shin and Mors // Contribute or communicate bugs at github.com/vrmiguel/sm64-analog-camera -int16_t rightx; -int16_t righty; -int c_rightx; -int c_righty; - static struct ControllerAPI *controller_implementations[] = { &controller_recorded_tas, &controller_sdl, @@ -54,23 +49,10 @@ void osContGetReadData(OSContPad *pad) { pad->button = 0; pad->stick_x = 0; pad->stick_y = 0; + pad->ext_stick_x = 0; + pad->ext_stick_y = 0; pad->errnum = 0; -#ifdef BETTERCAMERA - uint32_t magnitude_sq = (uint32_t)(rightx * rightx) + (uint32_t)(righty * righty); - uint32_t stickDeadzoneActual = configStickDeadzone * DEADZONE_STEP; - if (magnitude_sq > (uint32_t)(stickDeadzoneActual * stickDeadzoneActual)) { - c_rightx = rightx / 0x100; - int stick_y = -righty / 0x100; - c_righty = stick_y == 128 ? 127 : stick_y; - } else - { - c_rightx = 0; - c_righty = 0; - } -#endif - - for (size_t i = 0; i < sizeof(controller_implementations) / sizeof(struct ControllerAPI *); i++) { controller_implementations[i]->read(pad); } diff --git a/src/pc/controller/controller_mouse.h b/src/pc/controller/controller_mouse.h new file mode 100644 index 00000000..8ef01196 --- /dev/null +++ b/src/pc/controller/controller_mouse.h @@ -0,0 +1,13 @@ +#ifndef CONTROLLER_MOUSE_H +#define CONTROLLER_MOUSE_H + +#include "controller_api.h" + +extern int mouse_x; +extern int mouse_y; + +#define VK_BASE_MOUSE 0x2000 + +extern struct ControllerAPI controller_mouse; + +#endif diff --git a/src/pc/controller/controller_sdl.c b/src/pc/controller/controller_sdl.c index 84f5e024..4b9869b9 100644 --- a/src/pc/controller/controller_sdl.c +++ b/src/pc/controller/controller_sdl.c @@ -26,13 +26,10 @@ #define MAX_JOYBINDS 32 #define MAX_MOUSEBUTTONS 8 // arbitrary -extern int16_t rightx; -extern int16_t righty; - -#ifdef BETTERCAMERA int mouse_x; int mouse_y; +#ifdef BETTERCAMERA extern u8 newcam_mouse; #endif @@ -214,8 +211,8 @@ static void controller_sdl_read(OSContPad *pad) { int16_t leftx = SDL_GameControllerGetAxis(sdl_cntrl, SDL_CONTROLLER_AXIS_LEFTX); int16_t lefty = SDL_GameControllerGetAxis(sdl_cntrl, SDL_CONTROLLER_AXIS_LEFTY); - rightx = SDL_GameControllerGetAxis(sdl_cntrl, SDL_CONTROLLER_AXIS_RIGHTX); - righty = SDL_GameControllerGetAxis(sdl_cntrl, SDL_CONTROLLER_AXIS_RIGHTY); + int16_t rightx = SDL_GameControllerGetAxis(sdl_cntrl, SDL_CONTROLLER_AXIS_RIGHTX); + int16_t righty = SDL_GameControllerGetAxis(sdl_cntrl, SDL_CONTROLLER_AXIS_RIGHTY); int16_t ltrig = SDL_GameControllerGetAxis(sdl_cntrl, SDL_CONTROLLER_AXIS_TRIGGERLEFT); int16_t rtrig = SDL_GameControllerGetAxis(sdl_cntrl, SDL_CONTROLLER_AXIS_TRIGGERRIGHT); @@ -249,6 +246,14 @@ static void controller_sdl_read(OSContPad *pad) { int stick_y = -lefty / 0x100; pad->stick_y = stick_y == 128 ? 127 : stick_y; } + + magnitude_sq = (uint32_t)(rightx * rightx) + (uint32_t)(righty * righty); + stickDeadzoneActual = configStickDeadzone * DEADZONE_STEP; + if (magnitude_sq > (uint32_t)(stickDeadzoneActual * stickDeadzoneActual)) { + pad->ext_stick_x = rightx / 0x100; + int stick_y = -righty / 0x100; + pad->ext_stick_y = stick_y == 128 ? 127 : stick_y; + } } static void controller_sdl_rumble_play(f32 strength, f32 length) {