mirror of
https://github.com/mwpenny/portal64-still-alive.git
synced 2024-10-20 10:37:37 -04:00
Work on controls settings
This commit is contained in:
parent
2a0969abd0
commit
0602f6c30e
2
Makefile
2
Makefile
|
@ -257,7 +257,7 @@ build/src/menu/landing_menu.o: build/assets/materials/ui.h build/src/audio/clips
|
|||
|
||||
build/src/menu/options_menu.o: build/assets/materials/ui.h
|
||||
|
||||
build/src/menu/joystick_options.o: build/assets/materials/ui.h
|
||||
build/src/menu/joystick_options.o: build/assets/materials/ui.h build/src/audio/clips.h
|
||||
|
||||
build/src/menu/controls.o: build/assets/materials/ui.h build/src/audio/clips.h
|
||||
|
||||
|
|
|
@ -2,20 +2,71 @@
|
|||
|
||||
#include "../controls/controller.h"
|
||||
#include "../font/dejavusans.h"
|
||||
#include "../audio/soundplayer.h"
|
||||
#include "../savefile/savefile.h"
|
||||
|
||||
#include "../build/assets/materials/ui.h"
|
||||
#include "../build/src/audio/clips.h"
|
||||
|
||||
#define JOYSTICK_Y 54
|
||||
#define JOYSTICK_WIDTH 252
|
||||
#define JOYSTICK_HEIGHT 124
|
||||
|
||||
#define SCROLL_TICKS 9
|
||||
#define SCROLL_INTERVALS (SCROLL_TICKS - 1)
|
||||
|
||||
#define JOYSTICK_X ((SCREEN_WD - JOYSTICK_WIDTH) / 2)
|
||||
|
||||
void joystickOptionsInit(struct JoystickOptions* joystickOptions) {
|
||||
joystickOptions->selectedItem = 0;
|
||||
joystickOptions->selectedItem = JoystickOptionInvert;
|
||||
|
||||
joystickOptions->invertControls = menuBuildCheckbox(&gDejaVuSansFont, "Invert Camera", JOYSTICK_X + 8, JOYSTICK_Y + 8);
|
||||
joystickOptions->lookSensitivity = menuBuildSlider(JOYSTICK_X + 8, JOYSTICK_Y + 20, 80, 8, 13);
|
||||
|
||||
joystickOptions->lookSensitivityText = menuBuildText(&gDejaVuSansFont, "Look Sensitivity", JOYSTICK_X + 8, JOYSTICK_Y + 28);
|
||||
joystickOptions->lookSensitivity = menuBuildSlider(JOYSTICK_X + 120, JOYSTICK_Y + 28, 120, SCROLL_TICKS);
|
||||
|
||||
joystickOptions->lookAccelerationText = menuBuildText(&gDejaVuSansFont, "Look Acceleration", JOYSTICK_X + 8, JOYSTICK_Y + 48);
|
||||
joystickOptions->lookAcceleration = menuBuildSlider(JOYSTICK_X + 120, JOYSTICK_Y + 48, 120, SCROLL_TICKS);
|
||||
|
||||
joystickOptions->invertControls.checked = (gSaveData.controls.flags & ControlSaveFlagsInvert) != 0;
|
||||
joystickOptions->lookSensitivity.value = (float)gSaveData.controls.sensitivity / 0xFFFF;
|
||||
joystickOptions->lookAcceleration.value = (float)gSaveData.controls.acceleration / 0xFFFF;
|
||||
}
|
||||
|
||||
#define FULL_SCROLL_TIME 2.0f
|
||||
#define SCROLL_MULTIPLIER (int)(0xFFFF * FIXED_DELTA_TIME / (80 * FULL_SCROLL_TIME))
|
||||
|
||||
#define SCROLL_CHUNK_SIZE (0x10000 / SCROLL_INTERVALS)
|
||||
|
||||
void joystickOptionsHandleSlider(unsigned short* settingValue, float* sliderValue) {
|
||||
OSContPad* pad = controllersGetControllerData(0);
|
||||
|
||||
int newValue = (int)*settingValue + pad->stick_x * SCROLL_MULTIPLIER;
|
||||
|
||||
if (controllerGetButtonDown(0, A_BUTTON | R_JPAD)) {
|
||||
if (newValue >= 0xFFFF && controllerGetButtonDown(0, A_BUTTON)) {
|
||||
newValue = 0;
|
||||
} else {
|
||||
newValue = newValue + SCROLL_CHUNK_SIZE;
|
||||
newValue = newValue - (newValue % SCROLL_CHUNK_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
if (controllerGetButtonDown(0, L_JPAD)) {
|
||||
newValue = newValue - 1;
|
||||
newValue = newValue - (newValue % SCROLL_CHUNK_SIZE);
|
||||
}
|
||||
|
||||
if (newValue < 0) {
|
||||
newValue = 0;
|
||||
}
|
||||
|
||||
if (newValue > 0xFFFF) {
|
||||
newValue = 0xFFFF;
|
||||
}
|
||||
|
||||
*settingValue = newValue;
|
||||
*sliderValue = (float)newValue / 0xFFFF;
|
||||
}
|
||||
|
||||
enum MenuDirection joystickOptionsUpdate(struct JoystickOptions* joystickOptions) {
|
||||
|
@ -25,6 +76,44 @@ enum MenuDirection joystickOptionsUpdate(struct JoystickOptions* joystickOptions
|
|||
return MenuDirectionUp;
|
||||
}
|
||||
|
||||
if (controllerDir & ControllerDirectionDown) {
|
||||
++joystickOptions->selectedItem;
|
||||
|
||||
if (joystickOptions->selectedItem == JoystickOptionCount) {
|
||||
joystickOptions->selectedItem = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (controllerDir & ControllerDirectionUp) {
|
||||
if (joystickOptions->selectedItem == 0) {
|
||||
joystickOptions->selectedItem = JoystickOptionCount - 1;
|
||||
} else {
|
||||
--joystickOptions->selectedItem;
|
||||
}
|
||||
}
|
||||
|
||||
switch (joystickOptions->selectedItem) {
|
||||
case JoystickOptionInvert:
|
||||
if (controllerGetButtonDown(0, A_BUTTON)) {
|
||||
joystickOptions->invertControls.checked = !joystickOptions->invertControls.checked;
|
||||
soundPlayerPlay(SOUNDS_BUTTONCLICKRELEASE, 1.0f, 0.5f, NULL, NULL);
|
||||
|
||||
if (joystickOptions->invertControls.checked) {
|
||||
gSaveData.controls.flags |= ControlSaveFlagsInvert;
|
||||
} else {
|
||||
gSaveData.controls.flags &= ~ControlSaveFlagsInvert;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case JoystickOptionSensitivity:
|
||||
joystickOptionsHandleSlider(&gSaveData.controls.sensitivity, &joystickOptions->lookSensitivity.value);
|
||||
return MenuDirectionStay;
|
||||
case JoystickOptionAcceleration:
|
||||
joystickOptionsHandleSlider(&gSaveData.controls.acceleration, &joystickOptions->lookAcceleration.value);
|
||||
return MenuDirectionStay;
|
||||
}
|
||||
|
||||
if (controllerDir & ControllerDirectionLeft) {
|
||||
return MenuDirectionLeft;
|
||||
}
|
||||
|
@ -40,13 +129,28 @@ void joystickOptionsRender(struct JoystickOptions* joystickOptions, struct Rende
|
|||
gSPDisplayList(renderState->dl++, ui_material_list[SOLID_ENV_INDEX]);
|
||||
|
||||
gSPDisplayList(renderState->dl++, joystickOptions->invertControls.outline);
|
||||
renderState->dl = menuCheckboxRender(&joystickOptions->invertControls, renderState->dl);
|
||||
gSPDisplayList(renderState->dl++, joystickOptions->lookSensitivity.back);
|
||||
renderState->dl = menuSliderRender(&joystickOptions->lookSensitivity, renderState->dl);
|
||||
|
||||
gSPDisplayList(renderState->dl++, joystickOptions->lookAcceleration.back);
|
||||
renderState->dl = menuSliderRender(&joystickOptions->lookAcceleration, renderState->dl);
|
||||
|
||||
gSPDisplayList(renderState->dl++, ui_material_revert_list[SOLID_ENV_INDEX]);
|
||||
|
||||
gSPDisplayList(renderState->dl++, ui_material_list[DEJAVU_SANS_INDEX]);
|
||||
|
||||
gDPPipeSync(renderState->dl++);
|
||||
menuSetRenderColor(renderState, joystickOptions->selectedItem == JoystickOptionInvert, &gSelectionGray, &gColorWhite);
|
||||
gSPDisplayList(renderState->dl++, joystickOptions->invertControls.text);
|
||||
|
||||
gDPPipeSync(renderState->dl++);
|
||||
menuSetRenderColor(renderState, joystickOptions->selectedItem == JoystickOptionSensitivity, &gSelectionGray, &gColorWhite);
|
||||
gSPDisplayList(renderState->dl++, joystickOptions->lookSensitivityText);
|
||||
|
||||
gDPPipeSync(renderState->dl++);
|
||||
menuSetRenderColor(renderState, joystickOptions->selectedItem == JoystickOptionAcceleration, &gSelectionGray, &gColorWhite);
|
||||
gSPDisplayList(renderState->dl++, joystickOptions->lookAccelerationText);
|
||||
|
||||
gSPDisplayList(renderState->dl++, ui_material_revert_list[DEJAVU_SANS_INDEX]);
|
||||
}
|
|
@ -4,9 +4,20 @@
|
|||
#include "./menu.h"
|
||||
#include "../graphics/graphics.h"
|
||||
|
||||
enum JoystickOption {
|
||||
JoystickOptionInvert,
|
||||
JoystickOptionSensitivity,
|
||||
JoystickOptionAcceleration,
|
||||
|
||||
JoystickOptionCount,
|
||||
};
|
||||
|
||||
struct JoystickOptions {
|
||||
struct MenuCheckbox invertControls;
|
||||
struct MenuSlider lookSensitivity;
|
||||
struct MenuSlider lookAcceleration;
|
||||
Gfx* lookSensitivityText;
|
||||
Gfx* lookAccelerationText;
|
||||
short selectedItem;
|
||||
};
|
||||
|
||||
|
|
|
@ -197,36 +197,90 @@ struct MenuCheckbox menuBuildCheckbox(struct Font* font, char* message, int x, i
|
|||
return result;
|
||||
}
|
||||
|
||||
#define SLIDER_CENTER_HEIGHT 4
|
||||
Gfx* menuCheckboxRender(struct MenuCheckbox* checkbox, Gfx* dl) {
|
||||
if (!checkbox->checked) {
|
||||
return dl;
|
||||
}
|
||||
|
||||
struct MenuSlider menuBuildSlider(int x, int y, int w, int h, int tickCount) {
|
||||
gDPPipeSync(dl++);
|
||||
gDPSetEnvColor(dl++, 255, 255, 255, 255);
|
||||
gDPFillRectangle(
|
||||
dl++,
|
||||
checkbox->x + 3,
|
||||
checkbox->y + 3,
|
||||
checkbox->x + 8,
|
||||
checkbox->y + 8
|
||||
);
|
||||
return dl;
|
||||
}
|
||||
|
||||
|
||||
#define SLIDER_TRACK_HEIGHT 4
|
||||
#define SLIDER_HEIGHT 12
|
||||
#define SLIDER_WIDTH 6
|
||||
#define TICK_Y 11
|
||||
#define TICK_HEIGHT 3
|
||||
|
||||
struct MenuSlider menuBuildSlider(int x, int y, int w, int tickCount) {
|
||||
struct MenuSlider result;
|
||||
|
||||
result.x = x;
|
||||
result.y = y;
|
||||
result.w = w;
|
||||
result.h = h;
|
||||
|
||||
result.back = malloc(sizeof(Gfx) * 12 + tickCount + 2);
|
||||
result.back = malloc(sizeof(Gfx) * (12 + tickCount));
|
||||
|
||||
Gfx* dl = result.back;
|
||||
|
||||
int sliderX = x;
|
||||
int sliderY = y + (h >> 1) - (SLIDER_CENTER_HEIGHT >> 1);
|
||||
int sliderY = y + (SLIDER_HEIGHT / 2) - (SLIDER_TRACK_HEIGHT / 2);
|
||||
|
||||
gDPPipeSync(dl++);
|
||||
gDPSetEnvColor(dl++, 93, 96, 97, 255);
|
||||
gDPSetEnvColor(dl++, 25, 25, 25, 255);
|
||||
gDPFillRectangle(
|
||||
dl++,
|
||||
sliderX,
|
||||
sliderY,
|
||||
sliderX + w,
|
||||
sliderY + SLIDER_CENTER_HEIGHT
|
||||
sliderY + SLIDER_TRACK_HEIGHT
|
||||
);
|
||||
dl = menuRenderOutline(sliderX, sliderY, w, SLIDER_CENTER_HEIGHT, 1, dl);
|
||||
|
||||
int tickMin = x + (SLIDER_WIDTH / 2);
|
||||
int tickWidth = w - SLIDER_WIDTH;
|
||||
for (int i = 0; i < tickCount; ++i) {
|
||||
int tickX = (i * tickWidth) / (tickCount - 1) + tickMin;
|
||||
gDPFillRectangle(
|
||||
dl++,
|
||||
tickX,
|
||||
y + TICK_Y,
|
||||
tickX + 1,
|
||||
y + TICK_Y + TICK_HEIGHT
|
||||
);
|
||||
}
|
||||
|
||||
dl = menuRenderOutline(sliderX, sliderY, w, SLIDER_TRACK_HEIGHT, 1, dl);
|
||||
|
||||
gSPEndDisplayList(dl++);
|
||||
|
||||
result.value = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Gfx* menuSliderRender(struct MenuSlider* slider, Gfx* dl) {
|
||||
gDPPipeSync(dl++);
|
||||
gDPSetEnvColor(dl++, 93, 96, 97, 255);
|
||||
|
||||
int sliderPos = (slider->w - SLIDER_WIDTH) * slider->value + slider->x + (SLIDER_WIDTH / 2);
|
||||
|
||||
gDPFillRectangle(
|
||||
dl++,
|
||||
sliderPos - (SLIDER_WIDTH / 2),
|
||||
slider->y,
|
||||
sliderPos + (SLIDER_WIDTH / 2),
|
||||
slider->y + SLIDER_HEIGHT
|
||||
);
|
||||
dl = menuRenderOutline(sliderPos - (SLIDER_WIDTH / 2), slider->y, SLIDER_WIDTH, SLIDER_HEIGHT, 0, dl);
|
||||
|
||||
return dl;
|
||||
}
|
|
@ -25,7 +25,7 @@ struct MenuSlider {
|
|||
Gfx* back;
|
||||
float value;
|
||||
short x, y;
|
||||
short w, h;
|
||||
short w;
|
||||
};
|
||||
|
||||
enum MenuDirection {
|
||||
|
@ -55,6 +55,9 @@ struct MenuButton menuBuildButton(struct Font* font, char* message, int x, int y
|
|||
void menuSetRenderColor(struct RenderState* renderState, int isSelected, struct Coloru8* selected, struct Coloru8* defaultColor);
|
||||
|
||||
struct MenuCheckbox menuBuildCheckbox(struct Font* font, char* message, int x, int y);
|
||||
struct MenuSlider menuBuildSlider(int x, int y, int w, int h, int tickCount);
|
||||
Gfx* menuCheckboxRender(struct MenuCheckbox* checkbox, Gfx* dl);
|
||||
|
||||
struct MenuSlider menuBuildSlider(int x, int y, int w, int tickCount);
|
||||
Gfx* menuSliderRender(struct MenuSlider* slider, Gfx* dl);
|
||||
|
||||
#endif
|
|
@ -186,9 +186,11 @@ void playerInit(struct Player* player, struct Location* startLocation, struct Ve
|
|||
#define PLAYER_STOP_ACCEL (5.875f)
|
||||
#define PLAYER_SLIDE_ACCEL (40.0f)
|
||||
|
||||
#define ROTATE_RATE (M_PI * 2.0f)
|
||||
#define ROTATE_RATE_DELTA (M_PI * 0.125f)
|
||||
#define ROTATE_RATE_STOP_DELTA (M_PI * 0.25f)
|
||||
#define MIN_ROTATE_RATE (M_PI * 0.5f)
|
||||
#define MAX_ROTATE_RATE (M_PI * 3.5f)
|
||||
|
||||
#define MIN_ROTATE_RATE_DELTA (M_PI * 0.06125f)
|
||||
#define MAX_ROTATE_RATE_DELTA MAX_ROTATE_RATE
|
||||
|
||||
#define JUMP_IMPULSE 2.7f
|
||||
|
||||
|
@ -718,18 +720,26 @@ void playerUpdate(struct Player* player, struct Transform* cameraTransform) {
|
|||
}
|
||||
|
||||
struct Vector2 lookInput = controllerDirectionGet(ControllerActionRotate);
|
||||
float targetYaw = -lookInput.x * ROTATE_RATE;
|
||||
float targetPitch = lookInput.y * ROTATE_RATE;
|
||||
float rotateRate = mathfLerp(MIN_ROTATE_RATE, MAX_ROTATE_RATE, (float)gSaveData.controls.sensitivity / 0xFFFF);
|
||||
float targetYaw = -lookInput.x * rotateRate;
|
||||
float targetPitch = lookInput.y * rotateRate;
|
||||
|
||||
if (gSaveData.controls.flags & ControlSaveFlagsInvert) {
|
||||
targetYaw = -targetYaw;
|
||||
targetPitch = -targetPitch;
|
||||
}
|
||||
|
||||
float rotateRateDelta = mathfLerp(MIN_ROTATE_RATE_DELTA, MAX_ROTATE_RATE_DELTA, (float)gSaveData.controls.acceleration / 0xFFFF);
|
||||
|
||||
player->yawVelocity = mathfMoveTowards(
|
||||
player->yawVelocity,
|
||||
targetYaw,
|
||||
player->yawVelocity * targetYaw > 0.0f ? ROTATE_RATE_DELTA : ROTATE_RATE_STOP_DELTA
|
||||
rotateRateDelta
|
||||
);
|
||||
player->pitchVelocity = mathfMoveTowards(
|
||||
player->pitchVelocity,
|
||||
targetPitch,
|
||||
player->pitchVelocity * targetPitch > 0.0f ? ROTATE_RATE_DELTA : ROTATE_RATE_STOP_DELTA
|
||||
rotateRateDelta
|
||||
);
|
||||
|
||||
struct Vector3 lookingForward;
|
||||
|
|
|
@ -90,6 +90,9 @@ void savefileNew() {
|
|||
}
|
||||
|
||||
controllerSetDefaultSource();
|
||||
gSaveData.controls.flags = 0;
|
||||
gSaveData.controls.sensitivity = 0x7FFF;
|
||||
gSaveData.controls.acceleration = 0x7FFF;
|
||||
|
||||
gSaveData.audio.soundVolume = 0xFF;
|
||||
gSaveData.audio.musicVolume = 0xFF;
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#define SCREEN_SHOT_SRAM(slotIndex) (((slotIndex) + 1) * SAVE_SLOT_SIZE + MAX_CHECKPOINT_SIZE + SRAM_START_ADDR)
|
||||
|
||||
#define SAVEFILE_HEADER 0xDEAD
|
||||
#define SAVEFILE_HEADER 0xDEA0
|
||||
|
||||
// first save slot is always reserved for auto save
|
||||
#define MAX_SAVE_SLOTS ((int)(SRAM_SIZE / SAVE_SLOT_SIZE) - 1)
|
||||
|
@ -33,8 +33,15 @@ struct SaveHeader {
|
|||
unsigned char nextTestSubject;
|
||||
};
|
||||
|
||||
enum ControlSaveFlags {
|
||||
ControlSaveFlagsInvert,
|
||||
};
|
||||
|
||||
struct ControlSaveState {
|
||||
unsigned char controllerSettings[2][ControllerActionSourceCount];
|
||||
unsigned short flags;
|
||||
unsigned short sensitivity;
|
||||
unsigned short acceleration;
|
||||
};
|
||||
|
||||
struct AudioSettingsSaveState {
|
||||
|
|
Loading…
Reference in a new issue