Work on configurable controls

This commit is contained in:
James Lambert 2023-04-25 08:51:55 -06:00
parent b7d1404868
commit e104577c41
18 changed files with 480 additions and 83 deletions

View file

@ -0,0 +1,161 @@
#include "controller_actions.h"
#include "../util/memory.h"
#include "./controller.h"
#include "../math/mathf.h"
enum ControllerAction gDefaultControllerSettings[ControllerActionSourceCount] = {
[ControllerActionSourceAButton] = ControllerActionJump,
[ControllerActionSourceBButton] = ControllerActionUseItem,
[ControllerActionSourceCUpButton] = ControllerActionMove,
[ControllerActionSourceCRightButton] = ControllerActionMove,
[ControllerActionSourceCDownButton] = ControllerActionMove,
[ControllerActionSourceCLeftButton] = ControllerActionMove,
[ControllerActionSourceDUpButton] = ControllerActionMove,
[ControllerActionSourceDRightButton] = ControllerActionMove,
[ControllerActionSourceDDownButton] = ControllerActionMove,
[ControllerActionSourceDLeftButton] = ControllerActionMove,
[ControllerActionSourceStartButton] = ControllerActionPause,
[ControllerActionSourceLTrig] = ControllerActionOpenPortal1,
[ControllerActionSourceRTrig] = ControllerActionOpenPortal1,
[ControllerActionSourceZTrig] = ControllerActionOpenPortal0,
[ControllerActionSourceJoystick] = ControllerActionRotate,
};
unsigned short gActionSourceButtonMask[ControllerActionSourceCount] = {
[ControllerActionSourceAButton] = A_BUTTON,
[ControllerActionSourceBButton] = B_BUTTON,
[ControllerActionSourceCUpButton] = U_CBUTTONS,
[ControllerActionSourceCRightButton] = R_CBUTTONS,
[ControllerActionSourceCDownButton] = D_CBUTTONS,
[ControllerActionSourceCLeftButton] = L_CBUTTONS,
[ControllerActionSourceDUpButton] = U_JPAD,
[ControllerActionSourceDRightButton] = R_JPAD,
[ControllerActionSourceDDownButton] = D_JPAD,
[ControllerActionSourceDLeftButton] = L_JPAD,
[ControllerActionSourceStartButton] = START_BUTTON,
[ControllerActionSourceLTrig] = L_TRIG,
[ControllerActionSourceRTrig] = R_TRIG,
[ControllerActionSourceZTrig] = Z_TRIG,
[ControllerActionSourceJoystick] = 0,
};
#define IS_DIRECTION_ACTION(action) ((action) >= ControllerActionMove && (action) <= ControllerActionRotate)
enum ControllerAction gControllerSettings[2][ControllerActionSourceCount];
int gActionState = 0;
struct Vector2 gDirections[2];
void controllerActionInit() {
memCopy(gControllerSettings[0], gDefaultControllerSettings, sizeof(gDefaultControllerSettings));
zeroMemory(gControllerSettings[1], sizeof(gDefaultControllerSettings));
}
void controllerActionApply(enum ControllerAction action) {
gActionState |= (1 << action);
}
#define DEADZONE_SIZE 5
#define MAX_JOYSTICK_RANGE 80
float controllerCleanupStickInput(s8 input) {
if (input > -DEADZONE_SIZE && input < DEADZONE_SIZE) {
return 0.0f;
}
if (input >= MAX_JOYSTICK_RANGE) {
return 1.0f;
}
if (input <= -MAX_JOYSTICK_RANGE) {
return -1.0f;
}
return ((float)input + (input > 0 ? -DEADZONE_SIZE : DEADZONE_SIZE)) * (1.0f / (MAX_JOYSTICK_RANGE - DEADZONE_SIZE));
}
void controllerActionReadDirection(enum ControllerActionSource source, int controllerIndex, int directionIndex) {
struct Vector2 result = gDirections[directionIndex];
switch (source) {
case ControllerActionSourceCUpButton:
if (controllerGetButton(controllerIndex, U_CBUTTONS)) {
result.y += 1.0f;
}
if (controllerGetButton(controllerIndex, D_CBUTTONS)) {
result.y -= 1.0f;
}
if (controllerGetButton(controllerIndex, R_CBUTTONS)) {
result.x += 1.0f;
}
if (controllerGetButton(controllerIndex, L_CBUTTONS)) {
result.x -= 1.0f;
}
break;
case ControllerActionSourceDUpButton:
if (controllerGetButton(controllerIndex, U_JPAD)) {
result.y += 1.0f;
}
if (controllerGetButton(controllerIndex, D_JPAD)) {
result.y -= 1.0f;
}
if (controllerGetButton(controllerIndex, R_JPAD)) {
result.x += 1.0f;
}
if (controllerGetButton(controllerIndex, L_JPAD)) {
result.x -= 1.0f;
}
break;
case ControllerActionSourceJoystick:
{
OSContPad* pad = controllersGetControllerData(controllerIndex);
result.x = controllerCleanupStickInput(pad->stick_x);
result.y = controllerCleanupStickInput(pad->stick_y);
break;
}
default:
break;
}
gDirections[directionIndex] = result;
}
void controllerActionRead() {
gActionState = 0;
gDirections[0] = gZeroVec2;
gDirections[1] = gZeroVec2;
for (int controllerIndex = 0; controllerIndex < 2; ++controllerIndex) {
for (int sourceIndex = 0; sourceIndex < ControllerActionSourceCount; ++sourceIndex) {
enum ControllerAction action = gControllerSettings[controllerIndex][sourceIndex];
if (IS_DIRECTION_ACTION(action)) {
controllerActionReadDirection(sourceIndex, controllerIndex, action - ControllerActionMove);
if (sourceIndex == ControllerActionSourceCUpButton || sourceIndex == ControllerActionSourceDUpButton) {
sourceIndex += 3;
}
} else if (controllerGetButtonDown(controllerIndex, gActionSourceButtonMask[sourceIndex])) {
controllerActionApply(action);
}
}
}
for (int i = 0; i < 2; ++i) {
gDirections[i].x = clampf(gDirections[i].x, -1.0f, 1.0f);
gDirections[i].y = clampf(gDirections[i].y, -1.0f, 1.0f);
}
}
struct Vector2 controllerDirectionGet(enum ControllerAction direction) {
if (!IS_DIRECTION_ACTION(direction)) {
return gZeroVec2;
}
return gDirections[direction - ControllerActionMove];
}
int controllerActionGet(enum ControllerAction action) {
return (gActionState & (1 << action)) != 0;
}

View file

@ -0,0 +1,53 @@
#ifndef __CONTROLS_CONTROLLER_ACTIONS_H__
#define __CONTROLS_CONTROLLER_ACTIONS_H__
#include "../math/vector2.h"
enum ControllerActionSource {
// face buttons
ControllerActionSourceAButton,
ControllerActionSourceBButton,
ControllerActionSourceStartButton,
// c buttons
ControllerActionSourceCUpButton,
ControllerActionSourceCRightButton,
ControllerActionSourceCDownButton,
ControllerActionSourceCLeftButton,
// d pad
ControllerActionSourceDUpButton,
ControllerActionSourceDRightButton,
ControllerActionSourceDDownButton,
ControllerActionSourceDLeftButton,
// triggers
ControllerActionSourceLTrig,
ControllerActionSourceRTrig,
ControllerActionSourceZTrig,
// joystick
ControllerActionSourceJoystick,
ControllerActionSourceCount,
};
enum ControllerAction {
ControllerActionOpenNone,
ControllerActionOpenPortal0,
ControllerActionOpenPortal1,
ControllerActionJump,
ControllerActionUseItem,
ControllerActionDuck,
ControllerActionLookForward,
ControllerActionLookBackward,
ControllerActionPause,
// direction actions
ControllerActionMove,
ControllerActionRotate,
};
void controllerActionInit();
void controllerActionRead();
struct Vector2 controllerDirectionGet(enum ControllerAction direction);
int controllerActionGet(enum ControllerAction action);
#endif

View file

@ -81,3 +81,39 @@ int fontCountGfx(struct Font* font, char* message) {
return result;
}
struct Vector2s16 fontMeasure(struct Font* font, char* message) {
int startX = 0;
char prev = 0;
int x = 0;
int y = 0;
struct Vector2s16 result;
result.x = 0;
for (; *message; prev = *message, ++message) {
char curr = *message;
if (curr == '\n') {
y += font->charHeight;
x = startX;
continue;
}
if ((unsigned char)curr >= font->symbolCount) {
continue;
}
struct FontSymbol* symbol = &font->symbols[(int)curr];
x += fontDetermineKerning(font, prev, curr);
x += symbol->xadvance;
result.x = MAX(result.x, x);
}
result.y = y + font->charHeight;
return result;
}

View file

@ -2,6 +2,7 @@
#define __FONT_FONT_H__
#include <ultra64.h>
#include "../math/vector2s16.h"
struct FontKerning {
char amount;
@ -31,5 +32,6 @@ struct Font {
int fontDetermineKerning(struct Font* font, char first, char second);
Gfx* fontRender(struct Font* font, char* message, int x, int y, Gfx* dl);
int fontCountGfx(struct Font* font, char* message);
struct Vector2s16 fontMeasure(struct Font* font, char* message);
#endif

View file

@ -2,8 +2,6 @@
#include "initgfx.h"
#include "util/memory.h"
#include "../controls/controller.h"
struct GraphicsTask gGraphicsTasks[2];
extern OSMesgQueue gfxFrameMsgQ;
@ -75,11 +73,6 @@ void graphicsCreateTask(struct GraphicsTask* targetTask, GraphicsCallback callba
gDPPipeSync(renderState->dl++);
gDPSetColorImage(renderState->dl++, G_IM_FMT_RGBA, G_IM_SIZ_16b, SCREEN_WD, osVirtualToPhysical(targetTask->framebuffer));
if (controllerGetButton(1, A_BUTTON)) {
gDPSetFillColor(renderState->dl++, 0);
gDPFillRectangle(renderState->dl++, 0, 0, SCREEN_WD-1, SCREEN_HT-1);
}
gDPPipeSync(renderState->dl++);
gDPSetCycleType(renderState->dl++, G_CYC_1CYCLE);

View file

@ -11,6 +11,7 @@
#include "util/memory.h"
#include "string.h"
#include "controls/controller.h"
#include "controls/controller_actions.h"
#include "scene/dynamic_scene.h"
#include "audio/soundplayer.h"
#include "audio/audio.h"
@ -199,9 +200,10 @@ static void gameProc(void* arg) {
contactSolverInit(&gContactSolver);
portalSurfaceCleanupQueueInit();
savefileNew();
levelLoadWithCallbacks(MAIN_MENU);
levelLoadWithCallbacks(0);
cutsceneRunnerReset();
controllersInit();
controllerActionInit();
initAudio(fps);
soundPlayerInit();
skSetSegmentLocation(CHARACTER_ANIMATION_SEGMENT, (unsigned)_animation_segmentSegmentRomStart);
@ -245,6 +247,7 @@ static void gameProc(void* arg) {
controllersTriggerRead();
controllerHandlePlayback();
controllerActionRead();
skAnimatorSync();
if (inputIgnore) {

1
src/menu/controls.c Normal file
View file

@ -0,0 +1 @@
#include "controls.h"

8
src/menu/controls.h Normal file
View file

@ -0,0 +1,8 @@
#ifndef __MENU_CONTROLS_H__
#define __MENU_CONTROLS_H__
struct ControlsMenu {
};
#endif

View file

@ -24,7 +24,7 @@ void mainMenuInit(struct MainMenu* mainMenu) {
newGameInit(&mainMenu->newGameMenu);
optionsMenuInit(&mainMenu->optionsMenu);
mainMenu->state = MainMenuStateLanding;
mainMenu->state = MainMenuStateOptions;
mainMenuReadCamera(mainMenu);

View file

@ -2,6 +2,11 @@
#include "../util/memory.h"
struct Coloru8 gSelectionOrange = {255, 156, 0, 255};
struct Coloru8 gSelectionGray = {201, 201, 201, 255};
struct Coloru8 gBorderHighlight = {193, 193, 193, 255};
struct Coloru8 gBorderDark = {86, 86, 86, 255};
Gfx* menuBuildText(struct Font* font, char* message, int x, int y) {
Gfx* result = malloc(sizeof(Gfx) * (fontCountGfx(font, message) + 1));
Gfx* dl = result;
@ -121,11 +126,11 @@ struct MenuButton menuBuildButton(struct Font* font, char* message, int x, int y
Gfx* dl = result.outline;
gDPPipeSync(dl++);
gDPSetEnvColor(dl++, 188, 188, 188, 255);
gDPSetEnvColor(dl++, gBorderHighlight.r, gBorderHighlight.g, gBorderHighlight.b, gBorderHighlight.a);
gDPFillRectangle(dl++, x, y, x + width - 1, y + 1);
gDPFillRectangle(dl++, x, y, x + 1, y + height);
gDPPipeSync(dl++);
gDPSetEnvColor(dl++, 76, 76, 76, 255);
gDPSetEnvColor(dl++, gBorderDark.r, gBorderDark.g, gBorderDark.b, gBorderDark.a);
gDPFillRectangle(dl++, x, y + height - 1, x + width, y + height);
gDPFillRectangle(dl++, x + width - 1, y, x + width, y + height - 1);
gSPEndDisplayList(dl++);
@ -133,9 +138,6 @@ struct MenuButton menuBuildButton(struct Font* font, char* message, int x, int y
return result;
}
struct Coloru8 gSelectionOrange = {255, 156, 0, 255};
struct Coloru8 gSelectionGray = {201, 201, 201, 255};
void menuSetRenderColor(struct RenderState* renderState, int isSelected, struct Coloru8* selected, struct Coloru8* defaultColor) {
if (isSelected) {
gDPSetEnvColor(renderState->dl++, selected->r, selected->g, selected->b, selected->a);

View file

@ -15,6 +15,9 @@ struct MenuButton {
extern struct Coloru8 gSelectionOrange;
extern struct Coloru8 gSelectionGray;
extern struct Coloru8 gBorderHighlight;
extern struct Coloru8 gBorderDark;
Gfx* menuBuildText(struct Font* font, char* message, int x, int y);
Gfx* menuBuildBorder(int x, int y, int width, int height);
Gfx* menuBuildHorizontalLine(int x, int y, int width);

View file

@ -7,13 +7,37 @@
#include "../controls/controller.h"
#define OPTIONS_LEFT 40
#define OPTIONS_TOP 45
struct Tab gOptionTabs[] = {
{
.message = "Controls",
},
{
.message = "Audio",
},
};
#define MENU_WIDTH 280
#define MENU_HEIGHT 200
#define MENU_LEFT ((SCREEN_WD - MENU_WIDTH) / 2)
#define MENU_TOP ((SCREEN_HT - MENU_HEIGHT) / 2)
#define OPTIONS_PADDING 8
void optionsMenuInit(struct OptionsMenu* options) {
options->menuOutline = menuBuildBorder(OPTIONS_LEFT, OPTIONS_TOP, SCREEN_WD - OPTIONS_LEFT * 2, SCREEN_HT - OPTIONS_TOP * 2);
options->menuOutline = menuBuildBorder(MENU_LEFT, MENU_TOP, MENU_WIDTH, MENU_HEIGHT);
options->optionsText = menuBuildText(&gDejaVuSansFont, "OPTIONS", 48, 48);
tabsInit(
&options->tabs,
gOptionTabs,
sizeof(gOptionTabs) / sizeof(*gOptionTabs),
&gDejaVuSansFont,
MENU_LEFT + OPTIONS_PADDING, MENU_TOP + OPTIONS_PADDING,
MENU_WIDTH - OPTIONS_PADDING * 2, MENU_HEIGHT - OPTIONS_PADDING * 2
);
}
enum MainMenuState optionsMenuUpdate(struct OptionsMenu* options) {
@ -34,4 +58,12 @@ void optionsMenuRender(struct OptionsMenu* options, struct RenderState* renderSt
gSPDisplayList(renderState->dl++, ui_material_list[ROUNDED_CORNERS_INDEX]);
gSPDisplayList(renderState->dl++, options->menuOutline);
gSPDisplayList(renderState->dl++, ui_material_revert_list[ROUNDED_CORNERS_INDEX]);
gSPDisplayList(renderState->dl++, ui_material_list[SOLID_ENV_INDEX]);
gSPDisplayList(renderState->dl++, options->tabs.tabOutline);
gSPDisplayList(renderState->dl++, ui_material_revert_list[SOLID_ENV_INDEX]);
gSPDisplayList(renderState->dl++, ui_material_list[DEJAVU_SANS_INDEX]);
renderState->dl = tabsRenderText(&options->tabs, renderState->dl);
gSPDisplayList(renderState->dl++, ui_material_revert_list[DEJAVU_SANS_INDEX]);
}

View file

@ -4,10 +4,13 @@
#include "../graphics/graphics.h"
#include "./menu.h"
#include "./menu_state.h"
#include "./tabs.h"
struct OptionsMenu {
Gfx* menuOutline;
Gfx* optionsText;
struct Tabs tabs;
};
void optionsMenuInit(struct OptionsMenu* options);

105
src/menu/tabs.c Normal file
View file

@ -0,0 +1,105 @@
#include "tabs.h"
#include "../util/memory.h"
#include "./menu.h"
#define LEFT_TEXT_PADDING 4
#define RIGHT_TEXT_PADDING 16
#define TOP_TEXT_PADDING 3
#define TAB_HEIGHT 18
void tabsSetSelectedTab(struct Tabs* tabs, int index) {
if (index < 0 || index >= tabs->tabCount) {
return;
}
tabs->selectedTab = 0;
Gfx* dl = tabs->tabOutline;
gDPPipeSync(dl++);
gDPSetEnvColor(dl++, gBorderDark.r, gBorderDark.g, gBorderDark.b, gBorderDark.a);
gDPFillRectangle(dl++, tabs->x, tabs->y + tabs->height - 1, tabs->x + tabs->width, tabs->y + tabs->height);
gDPFillRectangle(dl++, tabs->x + tabs->width - 1, tabs->y + TAB_HEIGHT, tabs->x + tabs->width, tabs->y + tabs->height);
for (int i = 0; i < tabs->tabCount; ++i) {
struct TabRenderData* tab = &tabs->tabRenderData[i];
int tabTop = (i == tabs->selectedTab) ? tabs->y : (tabs->y + 1);
gDPFillRectangle(dl++, tab->x + tab->width - 2, tabTop, tab->x + tab->width - 1, tabs->y + TAB_HEIGHT);
fontRender(tabs->font, tabs->tabs[i].message, tab->x + LEFT_TEXT_PADDING, tabTop + TOP_TEXT_PADDING, tab->text);
}
gDPPipeSync(dl++);
gDPSetEnvColor(dl++, gBorderHighlight.r, gBorderHighlight.g, gBorderHighlight.b, gBorderHighlight.a);
gDPFillRectangle(dl++, tabs->x, tabs->y + TAB_HEIGHT, tabs->x + 1, tabs->y + tabs->height);
for (int i = 0; i < tabs->tabCount; ++i) {
struct TabRenderData* tab = &tabs->tabRenderData[i];
int tabTop = (i == tabs->selectedTab) ? tabs->y : (tabs->y + 1);
gDPFillRectangle(dl++, tab->x, tabTop, tab->x + 1, tabs->y + TAB_HEIGHT);
gDPFillRectangle(dl++, tab->x, tabTop, tab->x + tab->width - 2, tabTop + 1);
}
struct TabRenderData* selectedTab = tabs->selectedTab < tabs->tabCount ? &tabs->tabRenderData[tabs->selectedTab] : NULL;
if (selectedTab) {
gDPFillRectangle(dl++, tabs->x, tabs->y + TAB_HEIGHT, selectedTab->x, tabs->y + TAB_HEIGHT + 1);
gDPFillRectangle(dl++, tabs->x + selectedTab->width, tabs->y + TAB_HEIGHT, tabs->x + tabs->width, tabs->y + TAB_HEIGHT + 1);
}
gSPEndDisplayList(dl++);
}
void tabsInit(struct Tabs* tabs, struct Tab* tabList, int tabCount, struct Font* font, int x, int y, int width, int height) {
tabs->tabs = tabList;
tabs->tabCount = tabCount;
tabs->font = font;
tabs->width = width;
tabs->height = height;
tabs->x = x;
tabs->y = y;
tabs->tabOutline = malloc(sizeof(Gfx) * (10 + 3 * tabCount));
tabs->tabRenderData = malloc(sizeof(struct TabRenderData) * tabCount);
int currentX = x;
for (int i = 0; i < tabCount; ++i) {
struct Vector2s16 textSize = fontMeasure(font, tabList[i].message);
tabs->tabRenderData[i].text = menuBuildText(font, tabList[i].message, currentX + LEFT_TEXT_PADDING, y + TOP_TEXT_PADDING);
tabs->tabRenderData[i].width = textSize.x + LEFT_TEXT_PADDING + RIGHT_TEXT_PADDING;
tabs->tabRenderData[i].x = currentX;
currentX += tabs->tabRenderData[i].width;
}
tabs->selectedTab = -1;
tabsSetSelectedTab(tabs, 0);
}
Gfx* tabsRenderText(struct Tabs* tabs, Gfx* dl) {
gDPPipeSync(dl++);
gDPSetEnvColor(dl++, gSelectionGray.r, gSelectionGray.g, gSelectionGray.b, gSelectionGray.a);
for (int i = 0; i < tabs->tabCount; ++i) {
if (i == tabs->selectedTab) {
gDPSetEnvColor(dl++, gColorWhite.r, gColorWhite.g, gColorWhite.b, gColorWhite.a);
}
gSPDisplayList(dl++, tabs->tabRenderData[i].text);
if (i == tabs->selectedTab) {
gDPPipeSync(dl++);
gDPSetEnvColor(dl++, gSelectionGray.r, gSelectionGray.g, gSelectionGray.b, gSelectionGray.a);
}
}
gDPPipeSync(dl++);
gDPSetEnvColor(dl++, gColorWhite.r, gColorWhite.g, gColorWhite.b, gColorWhite.a);
return dl;
}

34
src/menu/tabs.h Normal file
View file

@ -0,0 +1,34 @@
#ifndef __MENU_TABS_H__
#define __MENU_TABS_H__
#include <ultra64.h>
#include "../font/font.h"
struct Tab {
char* message;
};
struct TabRenderData {
Gfx* text;
short width;
short x;
};
struct Tabs {
struct Tab* tabs;
struct Font* font;
short tabCount;
short width;
short height;
short selectedTab;
short x;
short y;
Gfx* tabOutline;
struct TabRenderData* tabRenderData;
};
void tabsInit(struct Tabs* tabs, struct Tab* tabList, int tabCount, struct Font* font, int x, int y, int width, int height);
void tabsSetSelectedTab(struct Tabs* tabs, int index);
Gfx* tabsRenderText(struct Tabs* tabs, Gfx* dl);
#endif

View file

@ -3,7 +3,7 @@
#include "player.h"
#include "../audio/clips.h"
#include "../audio/soundplayer.h"
#include "../controls/controller.h"
#include "../controls/controller_actions.h"
#include "../defs.h"
#include "../levels/levels.h"
#include "../math/mathf.h"
@ -317,14 +317,8 @@ void playerUpdateGrabbedObject(struct Player* player) {
return;
}
if (controllerGetButtonDown(0, B_BUTTON) || controllerGetButtonDown(1, U_JPAD)) {
if (controllerActionGet(ControllerActionUseItem)) {
if (player->grabConstraint.object) {
if (controllerGetButtonDown(1, U_JPAD)) {
struct Vector3 forward;
quatMultVector(&player->lookTransform.rotation, &gForward, &forward);
vector3AddScaled(&player->grabConstraint.object->body->velocity, &forward, -50.0f, &player->grabConstraint.object->body->velocity);
}
playerSetGrabbing(player, NULL);
} else {
struct RaycastHit hit;
@ -440,25 +434,6 @@ void playerUpdateGunObject(struct Player* player) {
}
#define DEADZONE_SIZE 5
#define MAX_JOYSTICK_RANGE 80
float playerCleanupStickInput(s8 input) {
if (input > -DEADZONE_SIZE && input < DEADZONE_SIZE) {
return 0.0f;
}
if (input >= MAX_JOYSTICK_RANGE) {
return 1.0f;
}
if (input <= -MAX_JOYSTICK_RANGE) {
return -1.0f;
}
return ((float)input + (input > 0 ? -DEADZONE_SIZE : DEADZONE_SIZE)) * (1.0f / (MAX_JOYSTICK_RANGE - DEADZONE_SIZE));
}
void playerGetMoveBasis(struct Transform* transform, struct Vector3* forward, struct Vector3* right) {
quatMultVector(&transform->rotation, &gForward, forward);
quatMultVector(&transform->rotation, &gRight, right);
@ -559,7 +534,7 @@ void playerUpdate(struct Player* player, struct Transform* cameraTransform) {
int isDead = playerIsDead(player);
if (!isDead && (player->flags & PlayerFlagsGrounded) && controllerGetButtonDown(0, A_BUTTON)) {
if (!isDead && (player->flags & PlayerFlagsGrounded) && controllerActionGet(ControllerActionJump)) {
player->body.velocity.y = JUMP_IMPULSE;
player->flags |= PlayerJustJumped;
}
@ -575,20 +550,13 @@ void playerUpdate(struct Player* player, struct Transform* cameraTransform) {
}
if (!isDead) {
if (controllerGetButton(0, L_JPAD)) {
vector3AddScaled(&targetVelocity, &right, -PLAYER_SPEED, &targetVelocity);
} else if (controllerGetButton(0, R_JPAD)) {
vector3AddScaled(&targetVelocity, &right, PLAYER_SPEED, &targetVelocity);
}
struct Vector2 moveInput = controllerDirectionGet(ControllerActionMove);
if (controllerGetButton(0, U_JPAD)) {
vector3AddScaled(&targetVelocity, &forward, -PLAYER_SPEED, &targetVelocity);
} else if (controllerGetButton(0, D_JPAD)) {
vector3AddScaled(&targetVelocity, &forward, PLAYER_SPEED, &targetVelocity);
}
vector3AddScaled(&targetVelocity, &right, PLAYER_SPEED * moveInput.x, &targetVelocity);
vector3AddScaled(&targetVelocity, &forward, -PLAYER_SPEED * moveInput.y, &targetVelocity);
// if player isnt crouched, crouch
if (!(player->flags & PlayerCrouched) && (controllerGetButtonDown(0, R_CBUTTONS))){
if (!(player->flags & PlayerCrouched) && (controllerActionGet(ControllerActionDuck))){
player->flags |= PlayerCrouched;
camera_y_modifier = -0.25;
collisionSceneRemoveDynamicObject(&player->collisionObject);
@ -597,7 +565,7 @@ void playerUpdate(struct Player* player, struct Transform* cameraTransform) {
collisionObjectUpdateBB(&player->collisionObject);
}
//if player crouched, uncrouch
else if ((player->flags & PlayerCrouched) && (controllerGetButtonDown(0, R_CBUTTONS))){
else if ((player->flags & PlayerCrouched) && (controllerActionGet(ControllerActionDuck))){
player->flags &= ~PlayerCrouched;
camera_y_modifier = 0.0;
collisionSceneRemoveDynamicObject(&player->collisionObject);
@ -607,7 +575,7 @@ void playerUpdate(struct Player* player, struct Transform* cameraTransform) {
}
//look straight forward
if (controllerGetButtonDown(0, U_CBUTTONS)){
if (controllerActionGet(ControllerActionLookForward)){
struct Vector3 lookingForward;
vector3Negate(&gForward, &lookingForward);
quatMultVector(&player->lookTransform.rotation, &lookingForward, &lookingForward);
@ -617,7 +585,7 @@ void playerUpdate(struct Player* player, struct Transform* cameraTransform) {
}
}
//look behind
if (controllerGetButtonDown(0, D_CBUTTONS)){
if (controllerActionGet(ControllerActionLookBackward)){
struct Vector3 lookingForward;
vector3Negate(&gForward, &lookingForward);
quatMultVector(&player->lookTransform.rotation, &lookingForward, &lookingForward);
@ -751,9 +719,9 @@ void playerUpdate(struct Player* player, struct Transform* cameraTransform) {
soundPlayerPlay(soundsPortalExit[2 - didPassThroughPortal], 0.75f, 1.0f, NULL, NULL);
}
OSContPad* controllerInput = controllersGetControllerData(0);
float targetYaw = -playerCleanupStickInput(controllerInput->stick_x) * ROTATE_RATE;
float targetPitch = playerCleanupStickInput(controllerInput->stick_y) * ROTATE_RATE;
struct Vector2 lookInput = controllerDirectionGet(ControllerActionRotate);
float targetYaw = -lookInput.x * ROTATE_RATE;
float targetPitch = lookInput.y * ROTATE_RATE;
player->yawVelocity = mathfMoveTowards(
player->yawVelocity,

View file

@ -11,7 +11,6 @@
#include "../util/time.h"
#include "../levels/levels.h"
#include "./portal_surface_generator.h"
#include "../controls/controller.h"
#include "../build/assets/models/portal/portal_blue.h"
#include "../build/assets/models/portal/portal_blue_filled.h"
@ -62,10 +61,6 @@ void portalUpdate(struct Portal* portal, int isOpen) {
portal->opacity = 1.0f;
}
if (controllerGetButton(1, B_BUTTON)) {
portal->opacity = 0.5f;
}
if (portal->scale < 1.0f) {
portal->scale += FIXED_DELTA_TIME * (1.0f / PORTAL_GROW_TIME);

View file

@ -10,11 +10,11 @@
#include "materials/point_light_rendered.h"
#include "util/time.h"
#include "sk64/skelatool_defs.h"
#include "controls/controller.h"
#include "shadow_map.h"
#include "../physics/point_constraint.h"
#include "../physics/debug_renderer.h"
#include "../controls/controller.h"
#include "../controls/controller_actions.h"
#include "../physics/collision_scene.h"
#include "../levels/static_render.h"
#include "../levels/levels.h"
@ -255,32 +255,30 @@ void sceneCheckPortals(struct Scene* scene) {
quatMultVector(&scene->player.lookTransform.rotation, &raycastRay.dir, &raycastRay.dir);
quatMultVector(&scene->player.lookTransform.rotation, &gUp, &playerUp);
int bluePortalFlags;
if (scene->player.flags & PlayerHasSecondPortalGun){
bluePortalFlags = (L_TRIG);
}else{
bluePortalFlags = (L_TRIG | Z_TRIG | R_TRIG);
}
int fireBlue = controllerActionGet(ControllerActionOpenPortal0);
int fireOrange = controllerActionGet(ControllerActionOpenPortal1);
if (controllerGetButtonDown(0, Z_TRIG | R_TRIG) && (scene->player.flags & PlayerHasSecondPortalGun) && !playerIsGrabbing(&scene->player)) {
int hasBlue = (scene->player.flags & PlayerHasFirstPortalGun) != 0;
int hasOrange = (scene->player.flags & PlayerHasSecondPortalGun) != 0;
if (fireOrange && hasOrange && !playerIsGrabbing(&scene->player)) {
sceneFirePortal(scene, &raycastRay, &playerUp, 0, scene->player.body.currentRoom, 1, 0);
scene->player.flags |= PlayerJustShotPortalGun;
scene->last_portal_indx_shot=0;
soundPlayerPlay(soundsPortalgunShoot[0], 1.0f, 1.0f, NULL, NULL);
}
if (controllerGetButtonDown(0, bluePortalFlags) && (scene->player.flags & PlayerHasFirstPortalGun) && !playerIsGrabbing(&scene->player)) {
if ((fireBlue || (!hasOrange && fireOrange)) && hasBlue && !playerIsGrabbing(&scene->player)) {
sceneFirePortal(scene, &raycastRay, &playerUp, 1, scene->player.body.currentRoom, 1, 0);
scene->player.flags |= PlayerJustShotPortalGun;
scene->last_portal_indx_shot=1;
soundPlayerPlay(soundsPortalgunShoot[1], 1.0f, 1.0f, NULL, NULL);
}
if (controllerGetButtonDown(0, R_TRIG | L_TRIG | Z_TRIG) && playerIsGrabbing(&scene->player)){
if ((fireOrange || fireBlue) && playerIsGrabbing(&scene->player)){
playerSetGrabbing(&scene->player, NULL);
}
scene->looked_wall_portalable_0 = 0;
scene->looked_wall_portalable_1 = 0;
@ -444,7 +442,7 @@ void sceneUpdate(struct Scene* scene) {
sceneUpdateListeners(scene);
sceneCheckPortals(scene);
if ((playerIsDead(&scene->player) && controllerGetButtonDown(0, START_BUTTON | A_BUTTON)) ||
if ((playerIsDead(&scene->player) && (controllerActionGet(ControllerActionPause) || controllerActionGet(ControllerActionJump))) ||
scene->player.lookTransform.position.y < KILL_PLANE_Y) {
levelLoadLastCheckpoint();
}
@ -553,7 +551,7 @@ void sceneUpdate(struct Scene* scene) {
scene->cpuTime = osGetTime() - frameStart;
scene->lastFrameStart = frameStart;
OSContPad* freecam = controllersGetControllerData(1);
OSContPad* freecam = controllersGetControllerData(2);
struct Vector3 lookDir;
@ -562,7 +560,7 @@ void sceneUpdate(struct Scene* scene) {
playerGetMoveBasis(&scene->camera.transform, &lookDir, &rightDir);
if (freecam->stick_y) {
if (controllerGetButton(1, Z_TRIG)) {
if (controllerGetButton(2, Z_TRIG)) {
vector3AddScaled(
&scene->freeCameraOffset,
&lookDir,
@ -583,13 +581,13 @@ void sceneUpdate(struct Scene* scene) {
);
}
if (controllerGetButtonDown(1, START_BUTTON)) {
if (controllerGetButtonDown(2, START_BUTTON)) {
scene->freeCameraOffset = gZeroVec;
}
vector3Add(&scene->camera.transform.position, &scene->freeCameraOffset, &scene->camera.transform.position);
if (controllerGetButtonDown(1, L_TRIG)) {
if (controllerGetButtonDown(2, L_TRIG)) {
struct Transform identityTransform;
transformInitIdentity(&identityTransform);
identityTransform.position.y = 1.0f;