1
0
mirror of https://github.com/blawar/ooot.git synced 2024-06-25 22:09:34 +00:00

added key rebind options gui

This commit is contained in:
Blake Warner 2022-03-24 12:32:29 -04:00
parent cdace23a0a
commit 7d713577a1
50 changed files with 13528 additions and 10717 deletions

@ -1 +1 @@
Subproject commit 0b4909721c90ac1b5eb5870b1fe1f5389818822e
Subproject commit 746be9cfa1d0175f17b7aff1d21f5575d37ea74f

View File

@ -6,7 +6,7 @@ void GfxPrint_Destroy(GfxPrint* pthis);
void GfxPrint_Init(GfxPrint* pthis);
void GfxPrint_Open(GfxPrint* pthis, Gfx* dList);
s32 GfxPrint_Printf(GfxPrint* pthis, const char* fmt, ...);
void GfxPrint_SetBasePosPx(GfxPrint* pthis, s32 x, s32 y);
void GfxPrint_SetBasePosPx(GfxPrint* pthis, s32 x, s32 y, u8 multiplier = 4);
void GfxPrint_SetColor(GfxPrint* pthis, u8 r, u8 g, u8 b, u8 a);
void GfxPrint_SetPos(GfxPrint* pthis, s32 x, s32 y);
void GfxPrint_SetPosPx(GfxPrint* pthis, s32 x, s32 y);

View File

@ -21,6 +21,10 @@ f32 Math_SmoothStepToF(f32* pValue, f32 target, f32 fraction, f32 step, f32 minS
s16 Math_SmoothStepToS(s16* pValue, s16 target, s16 scale, s16 step, s16 minStep);
s32 Math_StepToAngleS(s16* pValue, s16 target, s16 step);
s32 Math_StepToF(f32* pValue, f32 target, f32 step);
s32 Math_StepRotationToF(f32* pValue, f32 target, f32 step);
f32 Math_AngleDiffF(f32 a, f32 b);
f32 Math_NormalizeAngleF(f32 angle);
f32 Math_AngleF(Vec2f v);
s32 Math_StepToS(s16* pValue, s16 target, s16 step);
s32 Math_StepUntilAngleS(s16* pValue, s16 limit, s16 step);
s32 Math_StepUntilF(f32* pValue, f32 limit, f32 step);

View File

@ -75,30 +75,12 @@ struct GfxPrint {
/* 0x08 */ u16 posX;
/* 0x0A */ u16 posY;
/* 0x0C */ u16 baseX;
/* 0x0E */ u8 baseY;
/* 0x0F */ u8 flags;
/* 0x0E */ u16 baseY;
/* 0x0F */ u16 flags;
/* 0x10 */ Color_RGBA8 color;
/* 0x14 */ char unk_14[0x1C]; // unused
}; // size = 0x30
/*
void Graph_InitTHGA(struct GraphicsContext* gfxCtx);
struct GameStateOverlay* Graph_GetNextGameState(struct GameState* gameState);
void Graph_Init(struct GraphicsContext* gfxCtx);
void Graph_Destroy(struct GraphicsContext* gfxCtx);
void Graph_TaskSet00(struct GraphicsContext* gfxCtx);
void Graph_Update(struct GraphicsContext* gfxCtx, struct GameState* gameState);
void Graph_ThreadEntry(void*);
void* Graph_Alloc(struct GraphicsContext* gfxCtx, size_t size);
void* Graph_Alloc2(struct GraphicsContext* gfxCtx, size_t size);
void Graph_OpenDisps(Gfx** dispRefs, struct GraphicsContext* gfxCtx, const char* file, s32 line);
void Graph_CloseDisps(Gfx** dispRefs, struct GraphicsContext* gfxCtx, const char* file, s32 line);
Gfx* Graph_GfxPlusOne(Gfx* gfx);
Gfx* Graph_BranchDlist(Gfx* gfx, Gfx* dst);
void* Graph_DlistAlloc(Gfx** gfx, u32 size);
*/
extern GraphicsContext* __gfxCtx;
extern u16 gZBuffer[SCREEN_HEIGHT][SCREEN_WIDTH];
extern GfxPool gGfxPools[2];
extern u8 gGfxSPTaskStack[0x400];

View File

@ -17,3 +17,4 @@
#define GFXP_FLAG_UPDATE (1 << 3)
#define GFXP_FLAG_ENLARGE (1 << 6)
#define GFXP_FLAG_OPEN (1 << 7)
#define GFXP_FLAG_CENTER (1 << 8)

View File

@ -3,20 +3,22 @@
#include "ultra64/types.h"
#include "view.h"
struct KaleidoMgrOverlay {
/* 0x00 */ void* loadedRamAddr;
/* 0x04 */ uintptr_t vromStart;
/* 0x08 */ uintptr_t vromEnd;
/* 0x0C */ void* vramStart;
/* 0x10 */ void* vramEnd;
/* 0x14 */ u32 offset; // loadedRamAddr - vramStart
/* 0x18 */ const char* name;
struct KaleidoMgrOverlay
{
/* 0x00 */ void* loadedRamAddr;
/* 0x04 */ uintptr_t vromStart;
/* 0x08 */ uintptr_t vromEnd;
/* 0x0C */ void* vramStart;
/* 0x10 */ void* vramEnd;
/* 0x14 */ u32 offset; // loadedRamAddr - vramStart
/* 0x18 */ const char* name;
}; // size = 0x1C
enum KaleidoOverlayType {
/* 0x00 */ KALEIDO_OVL_KALEIDO_SCOPE,
/* 0x01 */ KALEIDO_OVL_PLAYER_ACTOR,
/* 0x02 */ KALEIDO_OVL_MAX
enum KaleidoOverlayType
{
/* 0x00 */ KALEIDO_OVL_KALEIDO_SCOPE,
/* 0x01 */ KALEIDO_OVL_PLAYER_ACTOR,
/* 0x02 */ KALEIDO_OVL_MAX
};
#define PAUSE_ITEM_NONE 999
@ -24,120 +26,110 @@ enum KaleidoOverlayType {
#define PAUSE_CURSOR_PAGE_LEFT 10
#define PAUSE_CURSOR_PAGE_RIGHT 11
enum PauseMenuPage {
/* 0x00 */ PAUSE_ITEM,
/* 0x01 */ PAUSE_MAP,
/* 0x02 */ PAUSE_QUEST,
/* 0x03 */ PAUSE_EQUIP,
/* 0x04 */ PAUSE_WORLD_MAP
enum PauseMenuPage
{
PAUSE_ITEM,
PAUSE_MAP,
PAUSE_QUEST,
PAUSE_EQUIP,
PAUSE_CONTROLLER,
};
#define PAUSE_WORLD_MAP PAUSE_MAP
namespace oot::pause
{
struct Segments
struct Segments
{
u8 preRenderFb[0x3800]; // offset 0
u8* keep; // offset 0x3800
Vec3s linkJointTable[22]; // size = ~0x90 PLAYER_LIMB_MAX
u8* linkObjectSegment;
u8 preRenderCvg[SCREEN_WIDTH * SCREEN_HEIGHT];
u8 preRenderFb[0x3800]; // offset 0
u8* keep; // offset 0x3800
Vec3s linkJointTable[22]; // size = ~0x90 PLAYER_LIMB_MAX
u8* linkObjectSegment;
u8 preRenderCvg[SCREEN_WIDTH * SCREEN_HEIGHT];
};
}
} // namespace oot::pause
struct PauseContext {
/* 0x0000 */ View view;
/* 0x0128 */ u8* iconItemSegment;
/* 0x012C */ u8* iconItem24Segment;
/* 0x0130 */ u8* iconItemAltSegment;
/* 0x0134 */ u8* iconItemLangSegment;
/* 0x0138 */ u8* nameSegment;
u8* nameSegment2;
u8* uknSegment2;
u8* uknSegment3;
/* 0x013C */ oot::pause::Segments* playerSegment;
/* 0x0140 */ char unk_140[0x04];
/* 0x0144 */ Vtx* itemPageVtx;
/* 0x0148 */ Vtx* equipPageVtx;
/* 0x014C */ Vtx* mapPageVtx;
/* 0x0150 */ Vtx* questPageVtx;
/* 0x0154 */ Vtx* infoPanelVtx;
/* 0x0158 */ Vtx* itemVtx;
/* 0x015C */ Vtx* equipVtx;
/* 0x0160 */ char unk_160[0x04];
/* 0x0164 */ Vtx* questVtx;
/* 0x0168 */ Vtx cursorVtx[20];
/* 0x016C */ Vtx* saveVtx;
/* 0x0170 */ char unk_170[0x24];
/* 0x0194 */ struct OcarinaStaff* ocarinaStaff;
/* 0x0198 */ char unk_198[0x20];
/* 0x01B8 */ OSMesgQueue loadQueue;
/* 0x01D0 */ OSMesg loadMsg;
/* 0x01D4 */ u16 state;
/* 0x01D6 */ u16 debugState;
/* 0x01D8 */ Vec3f eye;
/* 0x01E4 */ u16 unk_1E4;
/* 0x01E6 */ u16 mode;
/* 0x01E8 */ u16 pageIndex; // "kscp_pos"
/* 0x01EA */ u16 unk_1EA;
/* 0x01EC */ u16 unk_1EC;
/* 0x01F0 */ f32 unk_1F0;
/* 0x01F4 */ f32 unk_1F4;
/* 0x01F8 */ f32 unk_1F8;
/* 0x01FC */ f32 unk_1FC;
/* 0x0200 */ f32 unk_200;
/* 0x0204 */ f32 unk_204; // "angle_s"
/* 0x0208 */ u16 alpha;
/* 0x020A */ s16 offsetY;
/* 0x020C */ char unk_20C[0x08];
/* 0x0214 */ s16 stickRelX;
/* 0x0216 */ s16 stickRelY;
/* 0x0218 */ s16 cursorPoint[5]; // "cursor_point"
/* 0x0222 */ s16 cursorX[5]; // "cur_xpt"
/* 0x022C */ s16 cursorY[5]; // "cur_ypt"
/* 0x0236 */ s16 dungeonMapSlot;
/* 0x0238 */ s16 cursorSpecialPos; // "key_angle"
/* 0x023A */ s16 pageSwitchTimer;
/* 0x023C */ u16 namedItem; // "zoom_name"
/* 0x023E */ u16 cursorItem[4]; // "select_name"
/* 0x0246 */ u16 cursorSlot[4];
/* 0x024E */ u16 equipTargetItem; // "sl_item_no"
/* 0x0250 */ u16 equipTargetSlot; // "sl_number"
/* 0x0252 */ u16 equipTargetCBtn;
/* 0x0254 */ float equipAnimX;
/* 0x0256 */ float equipAnimY;
float equipAnimStartX;
float equipAnimStartY;
/* 0x0258 */ s16 equipAnimAlpha;
/* 0x025A */ s16 infoPanelOffsetY;
/* 0x025C */ u16 nameDisplayTimer;
/* 0x025E */ u16 nameColorSet; // 0 = white; 1 = grey
/* 0x0260 */ s16 cursorColorSet; // 0 = white; 4 = yellow; 8 = green
/* 0x0262 */ s16 promptChoice; // save/continue choice: 0 = yes; 4 = no
/* 0x0264 */ s16 ocarinaSongIdx;
/* 0x0266 */ u8 worldMapPoints[20]; // 0 = hidden; 1 = displayed; 2 = highlighted
/* 0x027A */ u8 tradeQuestLocation;
/* 0x027C */ SkelAnime playerSkelAnime;
struct PauseContext
{
/* 0x0000 */ View view;
/* 0x0128 */ u8* iconItemSegment;
/* 0x012C */ u8* iconItem24Segment;
/* 0x0130 */ u8* iconItemAltSegment;
/* 0x0134 */ u8* iconItemLangSegment;
/* 0x0138 */ u8* nameSegment;
u8* nameSegment2;
u8* uknSegment2;
u8* uknSegment3;
/* 0x013C */ oot::pause::Segments* playerSegment;
/* 0x0140 */ char unk_140[0x04];
/* 0x0154 */ Vtx* infoPanelVtx;
///* 0x0158 */ Vtx* itemVtx;
///* 0x015C */ Vtx* equipVtx;
Vtx* controllerPageVtx;
/* 0x0160 */ char unk_160[0x04];
///* 0x0164 */ Vtx* questVtx;
/* 0x0168 */ Vtx cursorVtx[20];
/* 0x016C */ Vtx* saveVtx;
/* 0x0170 */ char unk_170[0x24];
/* 0x0194 */ struct OcarinaStaff* ocarinaStaff;
/* 0x0198 */ char unk_198[0x20];
/* 0x01B8 */ OSMesgQueue loadQueue;
/* 0x01D0 */ OSMesg loadMsg;
/* 0x01D4 */ u16 state;
/* 0x01D6 */ u16 debugState;
/* 0x01D8 */ Vec3f eye;
/* 0x01E4 */ u16 unk_1E4;
/* 0x01E8 */ u16 pageIndex; // "kscp_pos"
/* 0x01EA */ float rotAccum;
/* 0x01EC */ u16 unk_1EC;
/* 0x01F0 */ f32 radius;
/* 0x0204 */ f32 unk_204; // "angle_s"
/* 0x0208 */ u16 alpha;
/* 0x020A */ s16 offsetY;
/* 0x020C */ char unk_20C[0x08];
/* 0x0214 */ s16 stickRelX;
/* 0x0216 */ s16 stickRelY;
/* 0x0236 */ s16 dungeonMapSlot;
/* 0x0238 */ s16 cursorSpecialPos; // "key_angle"
/* 0x023A */ s16 pageSwitchTimer;
/* 0x023C */ u16 namedItem; // "zoom_name"
/* 0x024E */ u16 equipTargetItem; // "sl_item_no"
/* 0x0250 */ u16 equipTargetSlot; // "sl_number"
/* 0x0252 */ u16 equipTargetCBtn;
/* 0x0254 */ float equipAnimX;
/* 0x0256 */ float equipAnimY;
float equipAnimStartX;
float equipAnimStartY;
/* 0x0258 */ s16 equipAnimAlpha;
/* 0x025A */ s16 infoPanelOffsetY;
/* 0x025C */ u16 nameDisplayTimer;
/* 0x025E */ u16 nameColorSet; // 0 = white; 1 = grey
/* 0x0260 */ s16 cursorColorSet; // 0 = white; 4 = yellow; 8 = green
/* 0x0262 */ s16 promptChoice; // save/continue choice: 0 = yes; 4 = no
/* 0x0264 */ s16 ocarinaSongIdx;
/* 0x0266 */ u8 worldMapPoints[20]; // 0 = hidden; 1 = displayed; 2 = highlighted
/* 0x027A */ u8 tradeQuestLocation;
/* 0x027C */ SkelAnime playerSkelAnime;
}; // size = 0x2C0
#define PAUSE_MAP_MARK_NONE -1
#define PAUSE_MAP_MARK_CHEST 0
#define PAUSE_MAP_MARK_BOSS 1
struct PauseMapMarkPoint {
/* 0x00 */ s16
chestFlag; // chest icon is only displayed if this flag is not set for the current room, -1 for no flag
/* 0x04 */ f32 x, y; // coordinates to place the icon (top-left corner)
}; // size = 0x0C
struct PauseMapMarkPoint
{
/* 0x00 */ s16 chestFlag; // chest icon is only displayed if this flag is not set for the current room, -1 for no flag
/* 0x04 */ f32 x, y; // coordinates to place the icon (top-left corner)
}; // size = 0x0C
struct PauseMapMarkData {
/* 0x00 */ s16 markType; // 0 for the chest icon, 1 for the boss skull icon, -1 for none
/* 0x04 */ s32 unk_04;
/* 0x08 */ const Vtx* vtx;
/* 0x0C */ s32 vtxCount;
/* 0x10 */ s32 count; // number of icons to display
/* 0x14 */ PauseMapMarkPoint points[12];
struct PauseMapMarkData
{
/* 0x00 */ s16 markType; // 0 for the chest icon, 1 for the boss skull icon, -1 for none
/* 0x04 */ s32 unk_04;
/* 0x08 */ const Vtx* vtx;
/* 0x0C */ s32 vtxCount;
/* 0x10 */ s32 count; // number of icons to display
/* 0x14 */ PauseMapMarkPoint points[12];
}; // size = 0xA4
typedef PauseMapMarkData PauseMapMarksData[3];

161
include/kaleido_macros.h Normal file
View File

@ -0,0 +1,161 @@
#pragma once
#define PAGE_COUNT 6
#if PAGE_COUNT == 6
#define PAGE_RADIUS_MULT 1.72
#elif PAGE_COUNT == 5
#define PAGE_RADIUS_MULT 1.37
#else
#define PAGE_RADIUS_MULT 1.0
#endif
// (f32)WREG(2) / 100.0f
#define PAGE_ACTIVE_Y ((f32)WREG(2) / 100.0f)
//(f32)WREG(3) / 100.0f
//#define PAGE_ACTIVE_X (93.55 * m_inradiusScaler)
#define PAUSE_LEFT_CARET WREG(16)
#define PAUSE_RIGHT_CARET WREG(17)
#define PAUSE_ANIMATION_STEPS WREG(6)
#define PAUSE_LEFT_CARET_MOVE WREG(25)
#define PAUSE_RIGHT_CARET_MOVE WREG(26)
#define PAUSE_LEFT_CARET_ORIGINAL_X (-175 + PAUSE_LEFT_CARET_MOVE)
#define PAUSE_RIGHT_CARET_ORIGINAL_X (155 + PAUSE_RIGHT_CARET_MOVE)
#define INRADIUS(width, sides) ((width / 2.0) * (1.0f / tanf(M_PI / sides)))
namespace oot::pause
{
class Page
{
public:
Page();
virtual ~Page();
virtual void initVerticies(GlobalContext* globalCtx) = 0;
virtual void setDefaultCursor(u16& slot, u16& item, u16& namedItem);
virtual void preDraw(GlobalContext* globalCtx, GraphicsContext* __gfxCtx, float inRadius, bool active);
virtual void dialogDraw(GlobalContext* globalCtx, GraphicsContext* __gfxCtx, float inRadius, bool active);
virtual void draw(GlobalContext* globalCtx, GraphicsContext* __gfxCtx, float inRadius, bool active);
virtual void postDraw(GlobalContext* globalCtx, GraphicsContext* gfxCtx, float inRadius, bool active);
virtual void drawInfo(GlobalContext* globalCtx, GraphicsContext* gfxCtx);
virtual void drawInfoText(GlobalContext* globalCtx, GraphicsContext* __gfxCtx, const std::string& str);
virtual void setCursorMetrics(s32& offset_x, s32& offset_y, s32& width, s32& height);
void update(u16 index, float angle);
virtual u8* infoPanelTexture(u8 langId);
virtual void setFlipAngle(float angle);
float flipAngle() const;
Vtx* auxVtx();
Vtx* pageVtx();
void setActive(bool active);
bool active() const;
bool is(PauseMenuPage id) const;
u16 index() const
{
return m_index;
}
const s16& cursorPoint() const
{
return m_cursorPoint;
}
s16& cursorPoint()
{
return m_cursorPoint;
}
const s16& cursorX() const
{
return m_cursorX;
}
s16& cursorX()
{
return m_cursorX;
}
const s16& cursorY() const
{
return m_cursorY;
}
s16& cursorY()
{
return m_cursorY;
}
const u16& cursorItem() const
{
return m_cursorItem;
}
u16& cursorItem()
{
return m_cursorItem;
}
const u16& cursorSlot() const
{
return m_cursorSlot;
}
u16& cursorSlot()
{
return m_cursorSlot;
}
virtual PauseMenuPage id() const = 0;
protected:
u16 m_index;
float m_angle;
float m_flipAngle;
std::unique_ptr<Vtx[]> m_pageVtx;
std::unique_ptr<Vtx[]> m_auxVtx;
s16 m_cursorPoint;
s16 m_cursorX;
s16 m_cursorY;
u16 m_cursorItem;
u16 m_cursorSlot;
bool m_active;
};
namespace page
{
class Controller : public Page
{
public:
Controller();
PauseMenuPage id() const override
{
return PAUSE_CONTROLLER;
}
u8* infoPanelTexture(u8 langId) override;
void drawInfo(GlobalContext* globalCtx, GraphicsContext* __gfxCtx) override;
void initVerticies(GlobalContext* globalCtx) override;
void preDraw(GlobalContext* globalCtx, GraphicsContext* __gfxCtx, float inRadius, bool active) override;
void postDraw(GlobalContext* globalCtx, GraphicsContext* __gfxCtx, float inRadius, bool active) override;
void setCursorMetrics(s32& offset_x, s32& offset_y, s32& width, s32& height) override;
};
} // namespace page
} // namespace oot::pause
void KaleidoScope_SetPage(GlobalContext* globalCtx, u16 pageIndex);
Gfx* KaleidoScope_DrawPageSections(Gfx* gfx, Vtx* vertices, void** textures);
s16 KaleidoScope_SetPageVertices(GlobalContext* globalCtx, Vtx* vtx, s16 pageId, s16 arg3);
oot::pause::Page* KaleidoScope_FindPage(PauseMenuPage id);
oot::pause::Page* KaleidoScope_CurrentPage();

View File

@ -82,10 +82,10 @@
Gfx* dispRefs[4]; \
__gfxCtx = gfxCtx; \
(void)__gfxCtx; \
Graph_OpenDisps(dispRefs, gfxCtx, file, line)
Graph_OpenDisps(dispRefs, gfxCtx, __FILE__, __LINE__)
#define CLOSE_DISPS(gfxCtx, file, line) \
Graph_CloseDisps(dispRefs, gfxCtx, file, line); \
Graph_CloseDisps(dispRefs, gfxCtx, __FILE__, __LINE__); \
} \
(void)0
@ -100,7 +100,7 @@
* `cbnz` blue component of color vertex, or z component of normal vertex
* `a` alpha
*/
#define VTX(x,y,z,s,t,crnx,cgny,cbnz,a) { { { x, y, z }, 0, { s, t }, { crnx, cgny, cbnz, a } } }
#define VTX(x,y,z,s,t,crnx,cgny,cbnz,a) { { { (short)(x), (short)(y), (short)(z) }, 0, { (short)(s), (short)(t) }, { crnx, cgny, cbnz, a } } }
#define VTX_T(x,y,z,s,t,cr,cg,cb,a) { { x, y, z }, 0, { s, t }, { cr, cg, cb, a } }
@ -153,4 +153,6 @@ MES(n30), MES(n31), MES(n32), MES(n33)}
#define FLT_MAX 340282346638528859811704183484516925440.0f
#define SHT_MAX 32767.0f
#define SHT_MINV (1.0f / SHT_MAX)
#define DEGTORAD(x) (x * M_PI / 180.0f)
#define DEGTORAD(x) (x * M_PI / 180.0)
#define RADTODEG(x) (x * 180.0 / M_PI)

View File

@ -3262,7 +3262,7 @@ _DW({ \
#ifdef _HW_VERSION_1
#define G_TX_LDBLK_MAX_TXL 4095
#else
#define G_TX_LDBLK_MAX_TXL 2047
#define G_TX_LDBLK_MAX_TXL 4095
#endif /* _HW_VERSION_1 */
#define TXL2WORDS(txls, b_txl) MAX(1, ((txls)*(b_txl)/8))
@ -3275,20 +3275,24 @@ _DW({ \
(((1 << G_TX_DXT_FRAC) + TXL2WORDS_4b(width) - 1) / \
TXL2WORDS_4b(width))
#define LRS_UPPER_SHIFT(lrs) _SHIFTL(((lrs) >> 12), 27, 5)
#define TILE_SHIFT(tile) _SHIFTL(tile, 24, 3)
#define LRS_SHIFT(lrs) _SHIFTL(lrs, 12, 12)
#define LRT_SHIFT(lrt) _SHIFTL(lrt, 0, 12)
#define gDPLoadTileGeneric(pkt, c, tile, uls, ult, lrs, lrt) \
_DW({ \
Gfx *_g = (Gfx *)(pkt); \
\
_g->words.w0 = _SHIFTL(c, 24, 8) | _SHIFTL(uls, 12, 12) | \
_SHIFTL(ult, 0, 12); \
_g->words.w1 = _SHIFTL(tile, 24, 3) | _SHIFTL(lrs, 12, 12) | \
_SHIFTL(lrt, 0, 12); \
_g->words.w1 = TILE_SHIFT(tile) | LRS_SHIFT(lrs) | LRT_SHIFT(lrt) | LRS_UPPER_SHIFT(lrs); \
})
#define gsDPLoadTileGeneric(c, tile, uls, ult, lrs, lrt) \
{ \
_SHIFTL(c, 24, 8) | _SHIFTL(uls, 12, 12) | _SHIFTL(ult, 0, 12), \
_SHIFTL(tile, 24, 3) | _SHIFTL(lrs, 12, 12) | _SHIFTL(lrt, 0, 12)\
TILE_SHIFT(tile) | LRS_SHIFT(lrs) | LRT_SHIFT(lrt) | LRS_UPPER_SHIFT(lrs)\
}
#define gDPSetTileSize(pkt, t, uls, ult, lrs, lrt) \
@ -3341,18 +3345,20 @@ _DW({ \
\
_g->words.w0 = (_SHIFTL(G_LOADBLOCK, 24, 8) | \
_SHIFTL(uls, 12, 12) | _SHIFTL(ult, 0, 12)); \
_g->words.w1 = (_SHIFTL(tile, 24, 3) | \
_SHIFTL((MIN(lrs,G_TX_LDBLK_MAX_TXL)), 12, 12) |\
_SHIFTL(dxt, 0, 12)); \
_g->words.w1 = (TILE_SHIFT(tile) | \
LRS_SHIFT((MIN(lrs,G_TX_LDBLK_MAX_TXL))) |\
LRS_UPPER_SHIFT((lrs)) |\
LRT_SHIFT(dxt)); \
})
#define gsDPLoadBlock(tile, uls, ult, lrs, dxt) \
{ \
(_SHIFTL(G_LOADBLOCK, 24, 8) | _SHIFTL(uls, 12, 12) | \
_SHIFTL(ult, 0, 12)), \
(_SHIFTL(tile, 24, 3) | \
_SHIFTL((MIN(lrs,G_TX_LDBLK_MAX_TXL)), 12, 12) | \
_SHIFTL(dxt, 0, 12)) \
(TILE_SHIFT(tile) | \
LRS_SHIFT((MIN(lrs,G_TX_LDBLK_MAX_TXL))) | \
LRS_UPPER_SHIFT((lrs)) | \
LRT_SHIFT(dxt)) \
}
#define gDPLoadTLUTCmd(pkt, tile, count) \

View File

@ -72,6 +72,7 @@ def main():
parser.add_argument("--pause-exit-input-clear-frames", choices=['0', '2', '3', '4', '5'], help="Number of frames to clear input state after pause menu exits (For speed-running, 0 disables)", default='2')
parser.add_argument("--left-deadzone", help="Left analog stick deadzone", type=int, default=20)
parser.add_argument("--right-deadzone", help="Right analog stick deadzone", type=int, default=20)
parser.add_argument("--disable-option-remap", help="Removes Remap option page from pause menu", type=int, default=20)
args = parser.parse_args()
@ -97,6 +98,9 @@ def main():
if args.disable_distance_culling:
defines.append('NO_CULLING')
if args.disable_option_remap:
defines.append('DISABLE_OPTIONS_REMAP')
if args.enable_gyro:
defines.append('ENABLE_GYRO')

View File

@ -8,7 +8,7 @@ static FramerateProfile g_profile = PROFILE_BOOT;
#if FRAME_RATE == 20
static Framerate g_profileRates[] = {
FRAMERATE_30FPS, // PROFILE_BOOT
FRAMERATE_30FPS, // PROFILE_PAUSE
FRAMERATE_60FPS, // PROFILE_PAUSE
FRAMERATE_20FPS, // PROFILE_GAMEPLAY
FRAMERATE_60FPS, // PROFILE_UNKNOWN1
FRAMERATE_60FPS, // PROFILE_UNKNOWN2

View File

@ -193,9 +193,9 @@ void GfxPrint_SetPos(GfxPrint* pthis, s32 x, s32 y) {
GfxPrint_SetPosPx(pthis, x * 8, y * 8);
}
void GfxPrint_SetBasePosPx(GfxPrint* pthis, s32 x, s32 y) {
pthis->baseX = x * 4;
pthis->baseY = y * 4;
void GfxPrint_SetBasePosPx(GfxPrint* pthis, s32 x, s32 y, u8 multiplier) {
pthis->baseX = x * multiplier;
pthis->baseY = y * multiplier;
}
void GfxPrint_PrintCharImpl(GfxPrint* pthis, u8 c) {
@ -299,6 +299,11 @@ void GfxPrint_PrintStringWithSize(GfxPrint* pthis, const void* buffer, u32 charS
const char* str = (const char*)buffer;
u32 count = charSize * charCount;
if(pthis->flags & GFXP_FLAG_CENTER)
{
pthis->posX -= ((count / 2.0f) * 32.0f);
}
while (count != 0) {
GfxPrint_PrintChar(pthis, *(str++));
count--;
@ -320,7 +325,7 @@ void* GfxPrint_Callback(void* arg, const char* str, u32 size) {
}
void GfxPrint_Init(GfxPrint* pthis) {
pthis->flags &= ~GFXP_FLAG_OPEN;
pthis->flags &= ~(GFXP_FLAG_OPEN | GFXP_FLAG_CENTER);
pthis->callback = GfxPrint_Callback;
pthis->dList = NULL;

View File

@ -394,8 +394,8 @@ void Graph_ThreadEntry(void* arg0) {
while (GameState_IsRunning(gameState) && isRunning()) {
//Has the TAS playback completed?
if (oot::hid::tas::isTasPlaying() && oot::hid::tas::hasTasEnded())
break;
/*if (oot::hid::tas::isTasPlaying() && oot::hid::tas::hasTasEnded())
break; TODO FIX*/
if (oot::config().game().isGraphicsDisabled())
{

View File

@ -48,7 +48,7 @@ void PadMgr_HandlePreNMI(PadMgr* padMgr) {
}
void PadMgr_RequestPadData(PadMgr* padMgr, Input* inputs, s32 mode) {
oot::hid::Players::Update();
oot::players().update();
s32 i;
Input* ogInput;
Input* newInput;

View File

@ -621,7 +621,7 @@ Mtx* Matrix_ToMtx(Mtx* dest, const char* file, s32 line) {
}
Mtx* Matrix_NewMtx(GraphicsContext* gfxCtx, const char* file, s32 line) {
return Matrix_ToMtx((Mtx*)Graph_Alloc(gfxCtx, sizeof(Mtx)), file, line);
return Matrix_ToMtx((Mtx*)Graph_Alloc(gfxCtx, sizeof(Mtx)), __FILE__, __LINE__);
}
Mtx* Matrix_MtxFToNewMtx(MtxF* src, GraphicsContext* gfxCtx) {

View File

@ -11,7 +11,7 @@
#include "quake.h"
#include "vt.h"
#include "overlays/actors/ovl_En_Horse/z_en_horse.h"
#include "port/controller/controller.h"
#include "port/player/players.h"
#include "def/code_800BB0A0.h"
#include "def/audio.h"
#include "def/math_float.h"
@ -1352,8 +1352,9 @@ s16 Camera_CalcDefaultYaw(Camera* camera, s16 cur, s16 target, f32 arg3, f32 acc
s16 Camera_CalcControllerPitch(Camera* camera, s16 cur, s16 target, s16 arg3) {
f32 pitchUpdRate;
const oot::hid::Controller* sControlInput = oot::hid::Players::GetController();
s16 rStickY = (s16)sControlInput->state().r_stick_y * (s16)-100;
const oot::hid::Controller& controller = oot::player(0).controller();
s16 rStickY = (s16)controller.state().r_stick_y * (s16)-100;
if (rStickY != 0) {
camera->startControlTimer = 250;//10s
}
@ -1364,8 +1365,8 @@ s16 Camera_CalcControllerPitch(Camera* camera, s16 cur, s16 target, s16 arg3) {
s16 Camera_CalcControllerYaw(Camera* camera, s16 cur, s16 target, f32 arg3, f32 accel) {
f32 yawUpdRate;
const oot::hid::Controller* sControlInput = oot::hid::Players::GetController();
s16 rStickX = (s16)sControlInput->state().r_stick_x * (s16)-250;
const oot::hid::Controller& controller = oot::player(0).controller();
s16 rStickX = (s16)controller.state().r_stick_x * (s16)-250;
if (rStickX != 0) {
camera->startControlTimer = 250;//10s
}
@ -1375,8 +1376,8 @@ s16 Camera_CalcControllerYaw(Camera* camera, s16 cur, s16 target, f32 arg3, f32
void StepControlTimer(Camera* camera)
{
const oot::hid::Controller* sControlInput = oot::hid::Players::GetController();
if(camera->xzSpeed > 0.001f && (sControlInput->state().r_stick_x != 0 || sControlInput->state().r_stick_y != 0)) {
const oot::hid::Controller& controller = oot::player(0).controller();
if(camera->xzSpeed > 0.001f && (controller.state().r_stick_x != 0 || controller.state().r_stick_y != 0)) {
camera->startControlTimer = 250;//10s
}
if(camera->startControlTimer > 0) {
@ -1658,9 +1659,9 @@ s32 Camera_Normal1(Camera* camera) {
Camera_CalcDefaultPitch(camera, atEyeNextGeo.pitch, norm1->pitchTarget, anim->slopePitchAdj);
}
#else
const oot::hid::Controller* sControlInput = oot::hid::Players::GetController();
const oot::hid::Controller& controller = oot::player(0).controller();
StepControlTimer(camera);
if (camera->startControlTimer > 0 || sControlInput->state().r_stick_x != 0 || sControlInput->state().r_stick_y != 0) {
if (camera->startControlTimer > 0 || controller.state().r_stick_x != 0 || controller.state().r_stick_y != 0) {
eyeAdjustment.yaw = Camera_CalcControllerYaw(camera, atEyeNextGeo.yaw, camera->playerPosRot.rot.y, norm1->unk_14, sp94);
eyeAdjustment.pitch = Camera_CalcControllerPitch(camera, atEyeNextGeo.pitch, norm1->pitchTarget, anim->slopePitchAdj);
} else if (anim->swing.unk_18 != 0) {
@ -2038,9 +2039,9 @@ s32 Camera_Normal3(Camera* camera) {
anim->yawTimer--;
}
#else
const oot::hid::Controller* sControlInput = oot::hid::Players::GetController();
const oot::hid::Controller& controller = oot::player(0).controller();
StepControlTimer(camera);
if(camera->startControlTimer > 0 || sControlInput->state().r_stick_x != 0 || sControlInput->state().r_stick_y != 0)
if(camera->startControlTimer > 0 || controller.state().r_stick_x != 0 || controller.state().r_stick_y != 0)
{
sp84.yaw = Camera_CalcControllerYaw(camera, sp74.yaw, playerPosRot->rot.y, norm3->yOffset, 0.0f);
sp84.pitch = Camera_CalcControllerPitch(camera, sp74.pitch, norm3->pitchTarget, 0);
@ -2389,9 +2390,9 @@ s32 Camera_Jump1(Camera* camera) {
Camera_CalcDefaultYaw(camera, eyeNextAtOffset.yaw, camera->playerPosRot.rot.y, jump1->maxYawUpdate, 0.0f);
}
#else
const oot::hid::Controller* sControlInput = oot::hid::Players::GetController();
const oot::hid::Controller& controller = oot::player(0).controller();
StepControlTimer(camera);
if(camera->startControlTimer > 0 || sControlInput->state().r_stick_x != 0 || sControlInput->state().r_stick_y != 0)
if(camera->startControlTimer > 0 || controller.state().r_stick_x != 0 || controller.state().r_stick_y != 0)
{
eyeDiffSph.yaw = Camera_CalcControllerYaw(camera, eyeNextAtOffset.yaw, playerPosRot->rot.y, 0, 0.0f);
eyeDiffSph.pitch = Camera_CalcControllerPitch(camera, eyeNextAtOffset.pitch, 0, 0);
@ -2598,9 +2599,9 @@ s32 Camera_Jump2(Camera* camera) {
adjAtToEyeDir.yaw = Camera_LERPCeilS(adjAtToEyeDir.yaw, atToEyeNextDir.yaw, 0.25f, 0xA);
}
#else
const oot::hid::Controller* sControlInput = oot::hid::Players::GetController();
const oot::hid::Controller& controller = oot::player(0).controller();
StepControlTimer(camera);
if(camera->startControlTimer > 0 || sControlInput->state().r_stick_x != 0 || sControlInput->state().r_stick_y != 0)
if(camera->startControlTimer > 0 || controller.state().r_stick_x != 0 || controller.state().r_stick_y != 0)
{
adjAtToEyeDir.yaw = Camera_CalcControllerYaw(camera, atToEyeNextDir.yaw, playerPosRot->rot.y, 0, 0.0f);
adjAtToEyeDir.pitch = Camera_CalcControllerPitch(camera, atToEyeNextDir.pitch, 0, 0);
@ -2802,9 +2803,9 @@ s32 Camera_Jump3(Camera* camera) {
eyeDiffSph.pitch = Camera_CalcDefaultPitch(camera, eyeNextAtOffset.pitch, jump3->pitchTarget, 0);
}
#else
const oot::hid::Controller* sControlInput = oot::hid::Players::GetController();
const oot::hid::Controller& controller = oot::player(0).controller();
StepControlTimer(camera);
if(camera->startControlTimer > 0 || sControlInput->state().r_stick_x != 0 || sControlInput->state().r_stick_y != 0) {
if(camera->startControlTimer > 0 || controller.state().r_stick_x != 0 || controller.state().r_stick_y != 0) {
eyeDiffSph.yaw = Camera_CalcControllerYaw(camera, eyeNextAtOffset.yaw, playerPosRot->rot.y, jump3->unk_14, 0.0f);
eyeDiffSph.pitch = Camera_CalcControllerPitch(camera, eyeNextAtOffset.pitch, jump3->pitchTarget, 0);
} else if(anim->swing.unk_18 != 0) {

View File

@ -5,6 +5,7 @@
#include "z64save.h"
#include "z64interface.h"
#include "segment_symbols.h"
#include "kaleido_macros.h"
#include "textures/do_action_static/do_action_static.h"
#include "textures/icon_item_static/icon_item_static.h"
#include "textures/parameter_static/parameter_static.h"
@ -417,7 +418,7 @@ void func_80111070(void) {
WREG(3) = 9355;
WREG(4) = 8;
WREG(5) = 3;
WREG(6) = 8;
PAUSE_ANIMATION_STEPS = 8;
WREG(7) = 0;
WREG(8) = 100;
WREG(9) = 109;
@ -427,8 +428,8 @@ void func_80111070(void) {
WREG(13) = 22;
WREG(14) = -380;
WREG(15) = -350;
WREG(16) = -175;
WREG(17) = 155;
PAUSE_LEFT_CARET = -175;
PAUSE_RIGHT_CARET = 155;
WREG(18) = 10;
WREG(19) = 10;
WREG(20) = -50;
@ -436,8 +437,8 @@ void func_80111070(void) {
WREG(22) = -32;
WREG(23) = -38;
WREG(24) = -36;
WREG(25) = 40;
WREG(26) = -40;
PAUSE_LEFT_CARET_MOVE = 40;
PAUSE_RIGHT_CARET_MOVE = -40;
WREG(27) = 0;
WREG(28) = 0;
R_OW_MINIMAP_X = 238;

View File

@ -3,6 +3,7 @@
#include "z64save.h"
#include "padmgr.h"
#include "kaleido.h"
#include "kaleido_macros.h"
#include "z64global.h"
#include "z64item.h"
#include "framerate.h"
@ -14,122 +15,87 @@
#include "def/z_play.h"
#include "def/z_view.h"
s16 sKaleidoSetupKscpPos0[] = { PAUSE_QUEST, PAUSE_EQUIP, PAUSE_ITEM, PAUSE_MAP };
f32 sKaleidoSetupEyeX0[] = { 0.0f, 64.0f, 0.0f, -64.0f };
f32 sKaleidoSetupEyeZ0[] = { -64.0f, 0.0f, 64.0f, 0.0f };
s16 sKaleidoSetupKscpPos0[] = {PAUSE_QUEST, PAUSE_EQUIP, PAUSE_ITEM, PAUSE_MAP};
s16 sKaleidoSetupKscpPos1[] = {PAUSE_MAP, PAUSE_QUEST, PAUSE_EQUIP, PAUSE_ITEM};
s16 sKaleidoSetupKscpPos1[] = { PAUSE_MAP, PAUSE_QUEST, PAUSE_EQUIP, PAUSE_ITEM };
f32 sKaleidoSetupEyeX1[] = { -64.0f, 0.0f, 64.0f, 0.0f };
f32 sKaleidoSetupEyeZ1[] = { 0.0f, -64.0f, 0.0f, 64.0f };
void KaleidoSetup_Update(GlobalContext* globalCtx)
{
PauseContext* pauseCtx = &globalCtx->pauseCtx;
Input* input = &globalCtx->state.input[0];
void KaleidoSetup_Update(GlobalContext* globalCtx) {
PauseContext* pauseCtx = &globalCtx->pauseCtx;
Input* input = &globalCtx->state.input[0];
if(pauseCtx->state == 0 && pauseCtx->debugState == 0 && globalCtx->gameOverCtx.state == GAMEOVER_INACTIVE && globalCtx->sceneLoadFlag == 0 && globalCtx->transitionMode == 0 && gSaveContext.cutsceneIndex < 0xFFF0 &&
gSaveContext.nextCutsceneIndex < 0xFFF0 && !Gameplay_InCsMode(globalCtx) && globalCtx->shootingGalleryStatus <= 1 && gSaveContext.unk_13F0 != 8 && gSaveContext.unk_13F0 != 9 &&
(globalCtx->sceneNum != SCENE_BOWLING || !Flags_GetSwitch(globalCtx, 0x38)))
{
if(CHECK_BTN_ALL(input->cur.button, BTN_L) && CHECK_BTN_ALL(input->press.button, BTN_CUP))
{
if(BREG(0))
{
pauseCtx->debugState = 3;
}
}
else if(CHECK_BTN_ALL(input->press.button, BTN_START))
{
gSaveContext.unk_13EE = gSaveContext.unk_13EA;
if (pauseCtx->state == 0 && pauseCtx->debugState == 0 && globalCtx->gameOverCtx.state == GAMEOVER_INACTIVE &&
globalCtx->sceneLoadFlag == 0 && globalCtx->transitionMode == 0 && gSaveContext.cutsceneIndex < 0xFFF0 &&
gSaveContext.nextCutsceneIndex < 0xFFF0 && !Gameplay_InCsMode(globalCtx) &&
globalCtx->shootingGalleryStatus <= 1 && gSaveContext.unk_13F0 != 8 && gSaveContext.unk_13F0 != 9 &&
(globalCtx->sceneNum != SCENE_BOWLING || !Flags_GetSwitch(globalCtx, 0x38))) {
PAUSE_LEFT_CARET = -175;
PAUSE_RIGHT_CARET = 155;
if (CHECK_BTN_ALL(input->cur.button, BTN_L) && CHECK_BTN_ALL(input->press.button, BTN_CUP)) {
if (BREG(0)) {
pauseCtx->debugState = 3;
}
} else if (CHECK_BTN_ALL(input->press.button, BTN_START)) {
gSaveContext.unk_13EE = gSaveContext.unk_13EA;
pauseCtx->rotAccum = 0;
pauseCtx->unk_1E4 = 1;
WREG(16) = -175;
WREG(17) = 155;
if(ZREG(48) == 0)
{
KaleidoScope_SetPage(globalCtx, sKaleidoSetupKscpPos0[pauseCtx->pageIndex]);
}
else
{
KaleidoScope_SetPage(globalCtx, sKaleidoSetupKscpPos1[pauseCtx->pageIndex]);
}
pauseCtx->unk_1EA = 0;
pauseCtx->unk_1E4 = 1;
pauseCtx->state = 1;
}
if (ZREG(48) == 0) {
pauseCtx->eye.x = sKaleidoSetupEyeX0[pauseCtx->pageIndex];
pauseCtx->eye.z = sKaleidoSetupEyeZ0[pauseCtx->pageIndex];
pauseCtx->pageIndex = sKaleidoSetupKscpPos0[pauseCtx->pageIndex];
} else {
pauseCtx->eye.x = sKaleidoSetupEyeX1[pauseCtx->pageIndex];
pauseCtx->eye.z = sKaleidoSetupEyeZ1[pauseCtx->pageIndex];
pauseCtx->pageIndex = sKaleidoSetupKscpPos1[pauseCtx->pageIndex];
}
if(pauseCtx->state == 1)
{
WREG(2) = -6240;
framerate_set_profile(PROFILE_PAUSE);
pauseCtx->mode = (u16)(pauseCtx->pageIndex * 2) + 1;
pauseCtx->state = 1;
if(ShrinkWindow_GetVal())
{
ShrinkWindow_SetVal(0);
}
osSyncPrintf("=%d eye.x=%f, eye.z=%f kscp_pos=%d\n", pauseCtx->mode, pauseCtx->eye.x,
pauseCtx->eye.z, pauseCtx->pageIndex);
}
if (pauseCtx->state == 1) {
WREG(2) = -6240;
framerate_set_profile(PROFILE_PAUSE);
if (ShrinkWindow_GetVal()) {
ShrinkWindow_SetVal(0);
}
Audio_PlayKaleido(1);
}
}
Audio_PlayKaleido(1);
}
}
}
void KaleidoSetup_Init(GlobalContext* globalCtx) {
PauseContext* pauseCtx = &globalCtx->pauseCtx;
u64 temp = 0; // Necessary to match
void KaleidoSetup_Init(GlobalContext* globalCtx)
{
PauseContext* pauseCtx = &globalCtx->pauseCtx;
pauseCtx->state = 0;
pauseCtx->debugState = 0;
pauseCtx->alpha = 0;
pauseCtx->unk_1EA = 0;
pauseCtx->unk_1E4 = 0;
pauseCtx->mode = 0;
pauseCtx->pageIndex = PAUSE_ITEM;
pauseCtx->state = 0;
pauseCtx->debugState = 0;
pauseCtx->alpha = 0;
pauseCtx->rotAccum = 0;
pauseCtx->unk_1E4 = 0;
KaleidoScope_SetPage(globalCtx, PAUSE_ITEM);
pauseCtx->unk_1F4 = 160.0f;
pauseCtx->unk_1F8 = 160.0f;
pauseCtx->unk_1FC = 160.0f;
pauseCtx->unk_200 = 160.0f;
pauseCtx->eye.z = 64.0f;
pauseCtx->unk_1F0 = 936.0f;
pauseCtx->eye.x = pauseCtx->eye.y = 0.0f;
pauseCtx->unk_204 = -314.0f;
pauseCtx->radius = 93.6f;
pauseCtx->eye.x = pauseCtx->eye.y = 0.0f;
pauseCtx->unk_204 = -314.0f;
pauseCtx->cursorPoint[PAUSE_ITEM] = 0;
pauseCtx->cursorPoint[PAUSE_MAP] = VREG(30) + 3;
pauseCtx->cursorPoint[PAUSE_QUEST] = 0;
pauseCtx->cursorPoint[PAUSE_EQUIP] = 1;
pauseCtx->cursorPoint[PAUSE_WORLD_MAP] = 10;
pauseCtx->infoPanelOffsetY = -40;
pauseCtx->nameDisplayTimer = 0;
pauseCtx->nameColorSet = 0;
pauseCtx->cursorColorSet = 4;
pauseCtx->ocarinaSongIdx = -1;
pauseCtx->cursorSpecialPos = 0;
pauseCtx->cursorX[PAUSE_ITEM] = 0;
pauseCtx->cursorY[PAUSE_ITEM] = 0;
pauseCtx->cursorX[PAUSE_MAP] = 0;
pauseCtx->cursorY[PAUSE_MAP] = 0;
pauseCtx->cursorX[PAUSE_QUEST] = temp;
pauseCtx->cursorY[PAUSE_QUEST] = temp;
pauseCtx->cursorX[PAUSE_EQUIP] = 1;
pauseCtx->cursorY[PAUSE_EQUIP] = 0;
pauseCtx->cursorItem[PAUSE_ITEM] = PAUSE_ITEM_NONE;
pauseCtx->cursorItem[PAUSE_MAP] = VREG(30) + 3;
pauseCtx->cursorItem[PAUSE_QUEST] = PAUSE_ITEM_NONE;
pauseCtx->cursorItem[PAUSE_EQUIP] = ITEM_SWORD_KOKIRI;
pauseCtx->cursorSlot[PAUSE_ITEM] = 0;
pauseCtx->cursorSlot[PAUSE_MAP] = VREG(30) + 3;
pauseCtx->cursorSlot[PAUSE_QUEST] = 0;
pauseCtx->cursorSlot[PAUSE_EQUIP] = pauseCtx->cursorPoint[PAUSE_EQUIP];
pauseCtx->infoPanelOffsetY = -40;
pauseCtx->nameDisplayTimer = 0;
pauseCtx->nameColorSet = 0;
pauseCtx->cursorColorSet = 4;
pauseCtx->ocarinaSongIdx = -1;
pauseCtx->cursorSpecialPos = 0;
View_Init(&pauseCtx->view, globalCtx->state.gfxCtx);
View_Init(&pauseCtx->view, globalCtx->state.gfxCtx);
}
void KaleidoSetup_Destroy(GlobalContext* globalCtx) {
void KaleidoSetup_Destroy(GlobalContext* globalCtx)
{
}

View File

@ -1,4 +1,4 @@
#define INTERNAL_SRC_CODE_Z_LIB_C
#define INTERNAL_SRC_CODE_Z_LIB_C
#include "global.h"
#include "ichain.h"
#include "regs.h"
@ -101,6 +101,104 @@ s32 Math_StepToF(f32* pValue, f32 target, f32 step) {
return false;
}
f32 Math_NormalizeAngleF(f32 angle)
{
while(angle < 0.0f)
{
angle += 360.0f;
}
while(angle >= 360.0f)
{
angle -= 360.0f;
}
return angle;
}
f32 Math_AngleF(Vec2f v)
{
if(v.x == 0)
{
return (v.y > 0) ? 90 : (v.y == 0) ? 0 : 270;
}
else if(v.y == 0)
{
return (v.x >= 0) ? 0 : 180;
}
int ret = RADTODEG(atan2f(v.y, v.x));
if(v.x < 0 && v.y < 0)
{
ret = 180 + ret;
}
else if(v.x < 0)
{
ret = 180 + ret;
}
else if(v.y < 0)
{
ret = 270 + (90 + ret);
}
return ret;
}
f32 Math_AngleDiffF(f32 a, f32 b)
{
const float angleDelta = Math_NormalizeAngleF(a - b);
if(angleDelta > 180.0f)
{
return 360.0f - angleDelta;
}
return angleDelta;
}
s32 Math_StepRotationToF(f32* pValue, f32 target, f32 step)
{
if(step != 0.0f)
{
const float angleDelta = target - *pValue;
if(angleDelta > 180.0f) // value > target
{
step = -step;
if(target < *pValue)
{
step = -step;
}
}
else if(angleDelta < -180.0f) // target > value
{
step = step;
}
else
{
if(target < *pValue)
{
step = -step;
}
}
*pValue = Math_NormalizeAngleF(*pValue + step);
if(fabsf(*pValue - target) < fabs(step))
{
*pValue = target;
return true;
}
}
else if(target == *pValue)
{
return true;
}
return false;
}
/**
* Changes pValue by step. If pvalue reaches limit angle or its opposite, sets it equal to limit angle.
* Returns true when limit angle or its opposite is reached, false otherwise.

File diff suppressed because it is too large Load Diff

View File

@ -412,7 +412,7 @@ void EnBox_WaitOpen(EnBox* pthis, GlobalContext* globalCtx) {
pthis->alpha = 255;
pthis->movementFlags |= ENBOX_MOVE_IMMOBILE;
if (pthis->unk_1F4 != 0) { // unk_1F4 is modified by player code
if (pthis->unk_1F4 != 0) { // itemPageAngle is modified by player code
linkAge = gSaveContext.linkAge;
anim = sAnimations[(pthis->unk_1F4 < 0 ? 2 : 0) + linkAge];
frameCount = Animation_GetLastFrame(anim);

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 589 B

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,701 @@
#define INTERNAL_SRC_OVERLAYS_MISC_OVL_KALEIDO_SCOPE_Z_KALEIDO_CONTROLLER_C
#include "actor_common.h"
#include <functional>
#include "port/player/players.h"
#include "z_kaleido_scope.h"
#include "def/z_lib.h"
#include "textures/icon_item_static/icon_item_static.h"
#include "textures/parameter_static/parameter_static.h"
#include "textures/icon_item_nes_static/icon_item_nes_static.h"
#include "def/inventory.h"
#include "def/audio_bank.h"
#include "def/z_common_data.h"
#include "def/z_parameter.h"
#include "def/z_player_lib.h"
#include "def/z_rcp.h"
extern void* sGameOverTexs[];
#define DIRECTION_MULT 2
#define HOTSPOT_MAX_ANGLE 60
#define MAX_RING_BUFFER_SIZE 32
#define POINT_X_MAX 4
#define POINT_Y_MAX 4
#define qu08(n) ((u8)((n)*0x100))
#define qu016(n) ((u16)((n)*0x10000))
#define qs48(n) ((s16)((n)*0x0100))
#define qs510(n) ((s16)((n)*0x0400))
#define qu510(n) ((u16)((n)*0x0400))
#define qs102(n) ((s16)((n)*0x0004))
#define qu102(n) ((u16)((n)*0x0004))
#define qs105(n) ((s16)((n)*0x0020))
#define qu105(n) ((u16)((n)*0x0020))
#define qs132(n) ((s16)((n)*0x0004))
#define qs142(n) ((s16)((n)*0x0004))
#define qs1516(n) ((s32)((n)*0x00010000))
#define qs1616(n) ((s32)((n)*0x00010000))
#define qs205(n) ((s32)((n)*0x00000020))
#define TEX_WIDTH 128
#define TEX_HEIGHT 128
#define TEX_X 0
#define TEX_Y -7
u8 gN64ControllerTex[] = {
#include "n64_controller_128x128.rgba32.inc.c"
};
u8 gResetTex[] = {
#include "reset_32x32.rgba32.inc.c"
};
static Vtx controllerVtx[] = {
VTX(TEX_WIDTH / -2 + TEX_X, TEX_HEIGHT / -2 + TEX_Y, 0, qs105(0), qs105(0 + TEX_HEIGHT), 255, 255, 255, 255),
VTX(TEX_WIDTH / +2 + TEX_X, TEX_HEIGHT / -2 + TEX_Y, 0, qs105(0 + TEX_WIDTH), qs105(0 + TEX_HEIGHT), 255, 255, 255, 255),
VTX(TEX_WIDTH / +2 + TEX_X, TEX_HEIGHT / +2 + TEX_Y, 0, qs105(0 + TEX_WIDTH), qs105(0), 255, 255, 255, 255),
VTX(TEX_WIDTH / -2 + TEX_X, TEX_HEIGHT / +2 + TEX_Y, 0, qs105(0), qs105(0), 255, 255, 255, 255),
};
static u16 gRingBufferIndex = 0;
static Vtx gRingBufferVtx[MAX_RING_BUFFER_SIZE][4];
void drawTextureRGBA32(GraphicsContext* __gfxCtx, s16 x, s16 y, u16 width, u16 height, const u8* texture, bool centered = false, float scale = 1.0f)
{
if(centered)
{
gRingBufferVtx[gRingBufferIndex][0] = VTX(width * scale / -2 + x, height * scale / -2 + y, 0, qs105(0), qs105(0 + height), 255, 255, 255, 255);
gRingBufferVtx[gRingBufferIndex][1] = VTX(width * scale / +2 + x, height * scale / -2 + y, 0, qs105(0 + width), qs105(0 + height), 255, 255, 255, 255);
gRingBufferVtx[gRingBufferIndex][2] = VTX(width * scale / +2 + x, height * scale / +2 + y, 0, qs105(0 + width), qs105(0), 255, 255, 255, 255);
gRingBufferVtx[gRingBufferIndex][3] = VTX(width * scale / -2 + x, height * scale / +2 + y, 0, qs105(0), qs105(0), 255, 255, 255, 255);
}
else
{
gRingBufferVtx[gRingBufferIndex][0] = VTX(x, y, 0, qs105(0), qs105(0 + height), 255, 255, 255, 255);
gRingBufferVtx[gRingBufferIndex][1] = VTX(x + width, y, 0, qs105(0 + width), qs105(0 + height), 255, 255, 255, 255);
gRingBufferVtx[gRingBufferIndex][2] = VTX(x + width, y + height, 0, qs105(0 + width), qs105(0), 255, 255, 255, 255);
gRingBufferVtx[gRingBufferIndex][3] = VTX(x, y + height, 0, qs105(0), qs105(0), 255, 255, 255, 255);
}
gDPLoadTextureBlock(POLY_OPA_DISP++, texture, G_IM_FMT_RGBA, G_IM_SIZ_32b, width, height, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
gSPVertex(POLY_OPA_DISP++, gRingBufferVtx[gRingBufferIndex], 4, 0);
gSP2Triangles(POLY_OPA_DISP++, 0, 2, 3, 0, 0, 1, 2, 0);
gDPPipeSync(POLY_OPA_DISP++);
gRingBufferIndex = (gRingBufferIndex + 1) % MAX_RING_BUFFER_SIZE;
}
class Image
{
public:
Image(int width, int height, const u8* texture, float scale = 1.0f) : width(width), height(height), texture(texture), scale(scale)
{
}
int width;
int height;
const u8* texture;
float scale;
};
class Hotspot
{
public:
Hotspot() : m_name(nullptr), m_x(0), m_y(0), m_index(0), m_up(nullptr), m_right(nullptr), m_down(nullptr), m_left(nullptr), m_onClick(nullptr), m_image(nullptr), m_size(1), m_pageRight(false), m_pageLeft(false)
{
}
Hotspot(const char* name, int x, int y, const std::function<void()> onClick = nullptr, Image* image = nullptr, u8 size = 1) :
m_name(name), m_x(x), m_y(y), m_index(0), m_up(nullptr), m_right(nullptr), m_down(nullptr), m_left(nullptr), m_onClick(onClick), m_image(image), m_size(size), m_pageRight(false), m_pageLeft(false)
{
}
void draw(GraphicsContext* __gfxCtx)
{
if(m_image && m_image->texture)
{
drawTextureRGBA32(__gfxCtx, x() /*+ (m_image->width / 4)*/, y() /*- (m_image->height / 4)*/, m_image->width, m_image->height, m_image->texture, true, m_image->scale);
}
}
void markPageRight()
{
m_pageRight = true;
}
void markPageLeft()
{
m_pageLeft = true;
}
bool pageRight() const
{
return m_pageRight;
}
bool pageLeft() const
{
return m_pageLeft;
}
int x() const
{
return m_x;
}
int y() const
{
return m_y;
}
const int& index() const
{
return m_index;
}
int& index()
{
return m_index;
}
const char* name()
{
return m_name;
}
double costX(Hotspot* current)
{
int delta_x = current->x() - x();
int delta_y = current->y() - y();
float angle = Math_AngleF({(float)delta_x, (float)delta_y});
float dist = sqrt(delta_x * delta_x + delta_y * delta_y);
angle = Math_AngleDiffF(angle, 0);
if(angle == 180.0f)
{
angle = 0.0f;
}
if(angle > HOTSPOT_MAX_ANGLE)
{
return 0;
}
const float scaler = 1.0f + (angle * DIRECTION_MULT / 100.0f);
return (double)(dist * scaler * (delta_x < 0 ? -1.0f : 1.0f));
}
double costY(Hotspot* current)
{
int delta_x = current->x() - x();
int delta_y = current->y() - y();
float angle = Math_AngleF({(float)delta_y, (float)delta_x});
float dist = sqrt(delta_x * delta_x + delta_y * delta_y);
angle = Math_AngleDiffF(angle, 0);
if(angle == 180.0f)
{
angle = 0.0f;
}
if(angle > HOTSPOT_MAX_ANGLE)
{
return 0;
}
const float scaler = 1.0f + (angle * DIRECTION_MULT / 100.0f);
return (double)(dist * scaler * (delta_y < 0 ? -1.0f : 1.0f));
}
Hotspot*& up()
{
return m_up;
}
Hotspot*& right()
{
return m_right;
}
Hotspot*& down()
{
return m_down;
}
Hotspot*& left()
{
return m_left;
}
const std::function<void()>& onClick() const
{
return m_onClick;
}
u8 size() const
{
return m_size;
}
const char* m_name;
std::vector<double> m_costsX;
std::vector<double> m_costsY;
protected:
int m_x;
int m_y;
int m_index;
Hotspot* m_up;
Hotspot* m_right;
Hotspot* m_down;
Hotspot* m_left;
std::function<void()> m_onClick;
Image* m_image;
u8 m_size;
bool m_pageRight;
bool m_pageLeft;
};
class Hotspots
{
public:
Hotspots() : m_hotspots(), m_index(0)
{
}
Hotspot* add(std::unique_ptr<Hotspot>&& hotspot)
{
m_hotspots.push_back(std::move(hotspot));
return m_hotspots.back().get();
}
Hotspot* add(Hotspot* hotspot)
{
m_hotspots.push_back(std::unique_ptr<Hotspot>(hotspot));
return hotspot;
}
Hotspot* findLowestCost(const std::vector<double>& costs, bool invert)
{
double lowest = -1.0f;
int index = 0;
for(int i = 0; i < costs.size(); i++)
{
const auto cost = invert ? costs[i] * -1 : costs[i];
if(cost > 0 && (cost < lowest || lowest < 0))
{
lowest = cost;
index = i;
}
}
if(lowest < 0)
{
return nullptr;
}
return m_hotspots[index].get();
}
void update()
{
for(int i = 0; i < m_hotspots.size(); i++)
{
m_hotspots[i]->index() = i;
}
for(auto& hotspot1 : m_hotspots)
{
for(auto& hotspot2 : m_hotspots)
{
hotspot1->m_costsX.push_back(hotspot1->costX(hotspot2.get()));
hotspot1->m_costsY.push_back(hotspot1->costY(hotspot2.get()));
}
hotspot1->left() = findLowestCost(hotspot1->m_costsX, true);
hotspot1->right() = findLowestCost(hotspot1->m_costsX, false);
hotspot1->up() = findLowestCost(hotspot1->m_costsY, false);
hotspot1->down() = findLowestCost(hotspot1->m_costsY, true);
}
}
void draw(GraphicsContext* __gfxCtx)
{
for(auto& hotspot : m_hotspots)
{
hotspot->draw(__gfxCtx);
}
}
void click()
{
auto cur = current();
if(cur->onClick() != nullptr)
{
cur->onClick()();
}
}
bool empty() const
{
return m_hotspots.size() == 0;
}
Hotspot* current()
{
return m_hotspots[m_index].get();
}
bool moveX(s8 dir)
{
if(empty())
{
return false;
}
Hotspot* next = nullptr;
if(dir > 0)
{
next = current()->right();
}
else
{
next = current()->left();
}
if(next)
{
m_index = next->index();
return true;
}
return false;
}
bool moveY(s8 dir)
{
if(empty())
{
return false;
}
Hotspot* next = nullptr;
if(dir > 0)
{
next = current()->up();
}
else
{
next = current()->down();
}
if(next)
{
m_index = next->index();
return true;
}
return false;
}
bool set(s8 dir)
{
if(empty())
{
return false;
}
Hotspot* closest = nullptr;
for(int i = 0; i < m_hotspots.size(); i++)
{
if(i == m_index)
{
continue;
}
if(dir > 0)
{
if(closest == nullptr || m_hotspots[i]->x() > closest->x())
{
closest = m_hotspots[i].get();
m_index = i;
}
}
else
{
if(closest == nullptr || m_hotspots[i]->x() < closest->x())
{
closest = m_hotspots[i].get();
m_index = i;
}
}
}
return closest != nullptr;
}
bool setLeft()
{
return set(-1);
}
bool setRight()
{
return set(1);
}
protected:
std::vector<std::unique_ptr<Hotspot>> m_hotspots;
u32 m_index;
};
static int a_x = 0;
static int a_y = 0;
#define ADJUST_X(n) ((n - 64) + 1)
#define ADJUST_Y(n) ((64 - n) - 7)
class ControllerHotspots : public Hotspots
{
public:
ControllerHotspots() : Hotspots()
{
auto start = add(new Hotspot("Remap Start", ADJUST_X(64), ADJUST_Y(45), []() { oot::player(0).rebind(oot::hid::Button::START_BUTTON); }));
auto a_button = add(new Hotspot("Remap A", ADJUST_X(98), ADJUST_Y(53), []() { oot::player(0).rebind(oot::hid::Button::A_BUTTON); }));
auto b_button = add(new Hotspot("Remap B", ADJUST_X(89), ADJUST_Y(44), []() { oot::player(0).rebind(oot::hid::Button::B_BUTTON); }));
// auto joystick = add(new Hotspot("Joystick", ADJUST_X(65), ADJUST_Y(70)));
auto z_button = add(new Hotspot("Remap Z", ADJUST_X(65), ADJUST_Y(80), []() { oot::player(0).rebind(oot::hid::Button::Z_TRIG); }));
auto c_right = add(new Hotspot("Remap C-Right", ADJUST_X(115), ADJUST_Y(36), []() { oot::player(0).rebind(oot::hid::Button::R_CBUTTONS); }));
auto c_left = add(new Hotspot("Remap C-Left", ADJUST_X(100), ADJUST_Y(36), []() { oot::player(0).rebind(oot::hid::Button::L_CBUTTONS); }));
auto c_up = add(new Hotspot("Remap C-Up", ADJUST_X(108), ADJUST_Y(29), []() { oot::player(0).rebind(oot::hid::Button::U_CBUTTONS); }));
auto c_down = add(new Hotspot("Remap C-Down", ADJUST_X(108), ADJUST_Y(43), []() { oot::player(0).rebind(oot::hid::Button::D_CBUTTONS); }));
auto up = add(new Hotspot("Remap Up", ADJUST_X(25), ADJUST_Y(33), []() { oot::player(0).rebind(oot::hid::Button::U_JPAD); }));
auto down = add(new Hotspot("Remap Down", ADJUST_X(25), ADJUST_Y(48), []() { oot::player(0).rebind(oot::hid::Button::D_JPAD); }));
auto left = add(new Hotspot("Remap Left", ADJUST_X(18), ADJUST_Y(41), []() { oot::player(0).rebind(oot::hid::Button::L_JPAD); }));
auto right = add(new Hotspot("Remap Right", ADJUST_X(33), ADJUST_Y(41), []() { oot::player(0).rebind(oot::hid::Button::R_JPAD); }));
auto l_button = add(new Hotspot("Remap L", ADJUST_X(25), ADJUST_Y(15), []() { oot::player(0).rebind(oot::hid::Button::L_TRIG); }));
auto r_button = add(new Hotspot("Remap R", ADJUST_X(104), ADJUST_Y(15), []() { oot::player(0).rebind(oot::hid::Button::R_TRIG); }));
auto shield = add(new Hotspot("Remap Shield", 95 - (2 * 16), -60, []() { oot::player(0).rebind(oot::hid::Button::SHIELD_TOGGLE); }, new Image(32, 32, gDekuShieldIconTex, 0.5f), 8));
auto tunic = add(new Hotspot("Remap Tunic", 95 - (1 * 16), -60, []() { oot::player(0).rebind(oot::hid::Button::TUNIC_TOGGLE); }, new Image(32, 32, gKokiriTunicIconTex, 0.5f), 8));
auto boots = add(new Hotspot("Remap Boots", 95 - (0 * 16), -60, []() { oot::player(0).rebind(oot::hid::Button::BOOTS_TOGGLE); }, new Image(32, 32, gKokiriBootsIconTex, 0.5f), 8));
auto reset = add(new Hotspot("Reset Bindings", 95, 49, []() { oot::player(0).resetBindings(); }, new Image(32, 32, gResetTex, 0.5f), 8));
c_right->markPageRight();
left->markPageLeft();
boots->markPageRight();
reset->markPageRight();
l_button->markPageLeft();
update();
return;
}
};
static ControllerHotspots hotspots;
void KaleidoScope_DrawController(GlobalContext* globalCtx, oot::pause::Page* page)
{
PauseContext* pauseCtx = &globalCtx->pauseCtx;
Input* input = &globalCtx->state.input[0];
OPEN_DISPS(globalCtx->state.gfxCtx, __FILE__, __LINE__);
gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATERGBA, G_CC_MODULATERGBA);
Gfx* x = POLY_OPA_DISP;
gDPLoadTextureBlock(POLY_OPA_DISP++, gN64ControllerTex, G_IM_FMT_RGBA, G_IM_SIZ_32b, TEX_WIDTH, TEX_HEIGHT, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
gSPVertex(POLY_OPA_DISP++, controllerVtx, 4, 0);
gSP2Triangles(POLY_OPA_DISP++, 0, 2, 3, 0, 0, 1, 2, 0);
gDPPipeSync(POLY_OPA_DISP++);
hotspots.draw(__gfxCtx);
if((pauseCtx->state == 6) && (pauseCtx->unk_1E4 == 0) && (page == KaleidoScope_CurrentPage()))
{
bool playSound = false;
if(pauseCtx->stickRelX > 30)
{
if(pauseCtx->cursorSpecialPos == PAUSE_CURSOR_PAGE_LEFT)
{
hotspots.setLeft();
pauseCtx->cursorSpecialPos = 0;
}
else
{
if(!hotspots.moveX(1))
{
if(hotspots.current()->pageRight())
{
pauseCtx->cursorSpecialPos = PAUSE_CURSOR_PAGE_RIGHT;
}
}
else
{
playSound = true;
}
}
}
else if(pauseCtx->stickRelX < -30)
{
if(pauseCtx->cursorSpecialPos == PAUSE_CURSOR_PAGE_RIGHT)
{
hotspots.setRight();
pauseCtx->cursorSpecialPos = 0;
}
else
{
if(!hotspots.moveX(-1))
{
if(hotspots.current()->pageLeft()) // left
{
pauseCtx->cursorSpecialPos = PAUSE_CURSOR_PAGE_LEFT;
}
}
else
{
playSound = true;
}
}
}
if(pauseCtx->cursorSpecialPos == 0)
{
if(pauseCtx->stickRelY > 30)
{
if(hotspots.moveY(1))
{
playSound = true;
}
}
else if(pauseCtx->stickRelY < -30)
{
if(hotspots.moveY(-1))
{
playSound = true;
}
}
if(CHECK_BTN_ALL(input->press.button, BTN_A))
{
hotspots.click();
}
}
if(playSound)
{
pauseCtx->nameSegment = nullptr;
// page->cursorItem() = hotspots.current()->index();
pauseCtx->nameDisplayTimer = 0;
Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gAudioDefaultPos, 4, &D_801333E0, &D_801333E0, &gReverbAdd2);
}
if(pauseCtx->cursorSpecialPos == 0)
{
auto cur = hotspots.current();
if(cur)
{
pauseCtx->cursorVtx[0].v.ob[0] = cur->x() + a_x;
pauseCtx->cursorVtx[0].v.ob[1] = cur->y() + a_y;
}
}
}
CLOSE_DISPS(globalCtx->state.gfxCtx, __FILE__, __LINE__);
return;
}
namespace oot::pause::page
{
Controller::Controller()
{
cursorPoint() = 0;
cursorX() = 0;
cursorY() = 0;
cursorItem() = 0;
cursorSlot() = 0;
}
u8* Controller::infoPanelTexture(u8 langId)
{
return nullptr;
}
void Controller::drawInfo(GlobalContext* globalCtx, GraphicsContext* __gfxCtx)
{
if(oot::player(0).isRebindMode())
{
drawInfoText(globalCtx, __gfxCtx, "Press any input");
}
else
{
drawInfoText(globalCtx, __gfxCtx, hotspots.current()->name());
}
}
void Controller::initVerticies(GlobalContext* globalCtx)
{
s16 phi_t1;
s16 phi_t2;
s16 phi_t2_2;
s16 phi_t3;
s16 phi_t4;
s16 phi_t5;
PauseContext* pauseCtx = &globalCtx->pauseCtx;
// m_pageVtx = std::make_unique<Vtx[]>(60);
// KaleidoScope_SetPageVertices(globalCtx, m_pageVtx.get(), 1, 0);
m_pageVtx = std::make_unique<Vtx[]>(80);
KaleidoScope_SetPageVertices(globalCtx, m_pageVtx.get(), 5, 5);
}
void Controller::preDraw(GlobalContext* globalCtx, GraphicsContext* __gfxCtx, float inRadius, bool active)
{
if(!active)
{
gDPPipeSync(POLY_OPA_DISP++);
gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA, G_CC_MODULATEIA);
}
}
void Controller::postDraw(GlobalContext* globalCtx, GraphicsContext* __gfxCtx, float inRadius, bool active)
{
PauseContext* pauseCtx = &globalCtx->pauseCtx;
POLY_OPA_DISP = KaleidoScope_DrawPageSections(POLY_OPA_DISP, m_pageVtx.get(), (void**)sGameOverTexs);
KaleidoScope_DrawController(globalCtx, this);
if(active && pauseCtx->cursorSpecialPos == 0)
{
KaleidoScope_DrawCursor(globalCtx, this);
}
}
void Controller::setCursorMetrics(s32& offset_x, s32& offset_y, s32& width, s32& height)
{
int sz = hotspots.current()->size();
offset_x = -16 + (16 - sz) / 2;
offset_y = 16 - (16 - sz) / 2;
width = sz;
height = sz;
}
} // namespace oot::pause

View File

@ -24,7 +24,7 @@ static u8 sEquipmentItemOffsets[] = {
static s16 sEquipTimer = 0;
void KaleidoScope_DrawEquipmentImage(GlobalContext* globalCtx, void* source, u32 width, u32 height) {
void KaleidoScope_DrawEquipmentImage(GlobalContext* globalCtx, void* source, u32 width, u32 height, Vtx* equipVtx) {
PauseContext* pauseCtx = &globalCtx->pauseCtx;
u8* curTexture;
s32 vtxIndex;
@ -59,7 +59,7 @@ void KaleidoScope_DrawEquipmentImage(GlobalContext* globalCtx, void* source, u32
remainingSize -= textureSize;
for (i = 0; i < textureCount; i++) {
gSPVertex(POLY_OPA_DISP++, &pauseCtx->equipVtx[vtxIndex], 4, 0);
gSPVertex(POLY_OPA_DISP++, &equipVtx[vtxIndex], 4, 0);
gDPSetTextureImage(POLY_OPA_DISP++, G_IM_FMT_RGBA, G_IM_SIZ_16b, width, curTexture);
@ -119,7 +119,8 @@ void KaleidoScope_DrawPlayerWork(GlobalContext* globalCtx) {
CUR_EQUIP_VALUE(EQUIP_BOOTS) - 1);
}
void KaleidoScope_DrawEquipment(GlobalContext* globalCtx) {
void KaleidoScope_DrawEquipment(GlobalContext* globalCtx, oot::pause::Page* page) {
Vtx* equipVtx = page->auxVtx();
PauseContext* pauseCtx = &globalCtx->pauseCtx;
Input* input = &globalCtx->state.input[0];
u16 i;
@ -138,7 +139,7 @@ void KaleidoScope_DrawEquipment(GlobalContext* globalCtx) {
s16 cursorY;
volatile s16 oldCursorPoint;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_kaleido_equipment.c", 219);
OPEN_DISPS(globalCtx->state.gfxCtx, __FILE__, __LINE__);
gDPPipeSync(POLY_OPA_DISP++);
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, ZREG(39), ZREG(40), ZREG(41), pauseCtx->alpha);
@ -147,104 +148,104 @@ void KaleidoScope_DrawEquipment(GlobalContext* globalCtx) {
for (i = 0, j = 64; i < 4; i++, j += 4) {
if (CUR_EQUIP_VALUE(i) != 0) {
gDPPipeSync(POLY_OPA_DISP++);
gSPVertex(POLY_OPA_DISP++, &pauseCtx->equipVtx[j], 4, 0);
gSPVertex(POLY_OPA_DISP++, &equipVtx[j], 4, 0);
POLY_OPA_DISP = KaleidoScope_QuadTextureIA8(POLY_OPA_DISP, gEquippedItemOutlineTex, 32, 32, 0);
}
}
if ((pauseCtx->state == 6) && (pauseCtx->unk_1E4 == 0) && (pauseCtx->pageIndex == PAUSE_EQUIP)) {
oldCursorPoint = pauseCtx->cursorPoint[PAUSE_EQUIP];
if ((pauseCtx->state == 6) && (pauseCtx->unk_1E4 == 0) && (page == KaleidoScope_CurrentPage())) {
oldCursorPoint = page->cursorPoint();
pauseCtx->cursorColorSet = 0;
if (pauseCtx->cursorSpecialPos == 0) {
pauseCtx->nameColorSet = 0;
cursorItem = pauseCtx->cursorItem[PAUSE_EQUIP];
cursorItem = page->cursorItem();
if ((cursorItem >= ITEM_SWORD_KOKIRI) && (cursorItem <= ITEM_BOOTS_HOVER)) {
pauseCtx->cursorColorSet = 8;
}
cursorPoint = pauseCtx->cursorPoint[PAUSE_EQUIP];
cursorX = pauseCtx->cursorX[PAUSE_EQUIP];
cursorY = pauseCtx->cursorY[PAUSE_EQUIP];
cursorPoint = page->cursorPoint();
cursorX = page->cursorX();
cursorY = page->cursorY();
cursorMoveResult = 0;
while (cursorMoveResult == 0) {
if (pauseCtx->stickRelX < -30) {
if (pauseCtx->cursorX[PAUSE_EQUIP] != 0) {
pauseCtx->cursorX[PAUSE_EQUIP] -= 1;
pauseCtx->cursorPoint[PAUSE_EQUIP] -= 1;
if (page->cursorX() != 0) {
page->cursorX() -= 1;
page->cursorPoint() -= 1;
if (pauseCtx->cursorX[PAUSE_EQUIP] == 0) {
if (pauseCtx->cursorY[PAUSE_EQUIP] == 0) {
if (page->cursorX() == 0) {
if (page->cursorY() == 0) {
if (CUR_UPG_VALUE(UPG_BULLET_BAG) != 0) {
cursorMoveResult = 1;
}
} else {
if (CUR_UPG_VALUE(pauseCtx->cursorY[PAUSE_EQUIP]) != 0) {
if (CUR_UPG_VALUE(page->cursorY()) != 0) {
cursorMoveResult = 1;
}
}
} else {
if (gBitFlags[pauseCtx->cursorPoint[PAUSE_EQUIP] - 1] & gSaveContext.inventory.equipment) {
if (gBitFlags[page->cursorPoint() - 1] & gSaveContext.inventory.equipment) {
cursorMoveResult = 2;
}
}
} else {
pauseCtx->cursorX[PAUSE_EQUIP] = cursorX;
pauseCtx->cursorY[PAUSE_EQUIP] += 1;
page->cursorX() = cursorX;
page->cursorY() += 1;
if (pauseCtx->cursorY[PAUSE_EQUIP] >= 4) {
pauseCtx->cursorY[PAUSE_EQUIP] = 0;
if (page->cursorY() >= 4) {
page->cursorY() = 0;
}
pauseCtx->cursorPoint[PAUSE_EQUIP] =
pauseCtx->cursorX[PAUSE_EQUIP] + (pauseCtx->cursorY[PAUSE_EQUIP] * 4);
page->cursorPoint() =
page->cursorX() + (page->cursorY() * 4);
if (pauseCtx->cursorPoint[PAUSE_EQUIP] >= 16) {
pauseCtx->cursorPoint[PAUSE_EQUIP] = pauseCtx->cursorX[PAUSE_EQUIP];
if (page->cursorPoint() >= 16) {
page->cursorPoint() = page->cursorX();
}
if (cursorY == pauseCtx->cursorY[PAUSE_EQUIP]) {
pauseCtx->cursorX[PAUSE_EQUIP] = cursorX;
pauseCtx->cursorPoint[PAUSE_EQUIP] = cursorPoint;
if (cursorY == page->cursorY()) {
page->cursorX() = cursorX;
page->cursorPoint() = cursorPoint;
KaleidoScope_MoveCursorToSpecialPos(globalCtx, PAUSE_CURSOR_PAGE_LEFT);
cursorMoveResult = 3;
}
}
} else if (pauseCtx->stickRelX > 30) {
if (pauseCtx->cursorX[PAUSE_EQUIP] < 3) {
pauseCtx->cursorX[PAUSE_EQUIP] += 1;
pauseCtx->cursorPoint[PAUSE_EQUIP] += 1;
if (page->cursorX() < 3) {
page->cursorX() += 1;
page->cursorPoint() += 1;
if (pauseCtx->cursorX[PAUSE_EQUIP] == 0) {
if (CUR_UPG_VALUE(pauseCtx->cursorY[PAUSE_EQUIP]) != 0) {
if (page->cursorX() == 0) {
if (CUR_UPG_VALUE(page->cursorY()) != 0) {
cursorMoveResult = 1;
}
} else {
if (gBitFlags[pauseCtx->cursorPoint[PAUSE_EQUIP] - 1] & gSaveContext.inventory.equipment) {
if (gBitFlags[page->cursorPoint() - 1] & gSaveContext.inventory.equipment) {
cursorMoveResult = 2;
}
}
} else {
pauseCtx->cursorX[PAUSE_EQUIP] = cursorX;
pauseCtx->cursorY[PAUSE_EQUIP] += 1;
page->cursorX() = cursorX;
page->cursorY() += 1;
if (pauseCtx->cursorY[PAUSE_EQUIP] >= 4) {
pauseCtx->cursorY[PAUSE_EQUIP] = 0;
if (page->cursorY() >= 4) {
page->cursorY() = 0;
}
pauseCtx->cursorPoint[PAUSE_EQUIP] =
pauseCtx->cursorX[PAUSE_EQUIP] + (pauseCtx->cursorY[PAUSE_EQUIP] * 4);
page->cursorPoint() =
page->cursorX() + (page->cursorY() * 4);
if (pauseCtx->cursorPoint[PAUSE_EQUIP] >= 16) {
pauseCtx->cursorPoint[PAUSE_EQUIP] = pauseCtx->cursorX[PAUSE_EQUIP];
if (page->cursorPoint() >= 16) {
page->cursorPoint() = page->cursorX();
}
if (cursorY == pauseCtx->cursorY[PAUSE_EQUIP]) {
pauseCtx->cursorX[PAUSE_EQUIP] = cursorX;
pauseCtx->cursorPoint[PAUSE_EQUIP] = cursorPoint;
if (cursorY == page->cursorY()) {
page->cursorX() = cursorX;
page->cursorPoint() = cursorPoint;
KaleidoScope_MoveCursorToSpecialPos(globalCtx, PAUSE_CURSOR_PAGE_RIGHT);
cursorMoveResult = 3;
}
@ -254,51 +255,51 @@ void KaleidoScope_DrawEquipment(GlobalContext* globalCtx) {
}
}
cursorPoint = pauseCtx->cursorPoint[PAUSE_EQUIP];
cursorY = pauseCtx->cursorY[PAUSE_EQUIP];
cursorPoint = page->cursorPoint();
cursorY = page->cursorY();
if (cursorMoveResult) {}
cursorMoveResult = 0;
while (cursorMoveResult == 0) {
if (pauseCtx->stickRelY > 30) {
if (pauseCtx->cursorY[PAUSE_EQUIP] != 0) {
pauseCtx->cursorY[PAUSE_EQUIP] -= 1;
pauseCtx->cursorPoint[PAUSE_EQUIP] -= 4;
if (page->cursorY() != 0) {
page->cursorY() -= 1;
page->cursorPoint() -= 4;
if (pauseCtx->cursorX[PAUSE_EQUIP] == 0) {
if (pauseCtx->cursorY[PAUSE_EQUIP] == 0) {
if (page->cursorX() == 0) {
if (page->cursorY() == 0) {
if (CUR_UPG_VALUE(UPG_BULLET_BAG) != 0) {
cursorMoveResult = 1;
}
} else if (CUR_UPG_VALUE(pauseCtx->cursorY[PAUSE_EQUIP]) != 0) {
} else if (CUR_UPG_VALUE(page->cursorY()) != 0) {
cursorMoveResult = 1;
}
} else if (gBitFlags[pauseCtx->cursorPoint[PAUSE_EQUIP] - 1] &
} else if (gBitFlags[page->cursorPoint() - 1] &
gSaveContext.inventory.equipment) {
cursorMoveResult = 2;
}
} else {
pauseCtx->cursorY[PAUSE_EQUIP] = cursorY;
pauseCtx->cursorPoint[PAUSE_EQUIP] = cursorPoint;
page->cursorY() = cursorY;
page->cursorPoint() = cursorPoint;
cursorMoveResult = 3;
}
} else if (pauseCtx->stickRelY < -30) {
if (pauseCtx->cursorY[PAUSE_EQUIP] < 3) {
pauseCtx->cursorY[PAUSE_EQUIP] += 1;
pauseCtx->cursorPoint[PAUSE_EQUIP] += 4;
if (page->cursorY() < 3) {
page->cursorY() += 1;
page->cursorPoint() += 4;
if (pauseCtx->cursorX[PAUSE_EQUIP] == 0) {
if (CUR_UPG_VALUE(pauseCtx->cursorY[PAUSE_EQUIP]) != 0) {
if (page->cursorX() == 0) {
if (CUR_UPG_VALUE(page->cursorY()) != 0) {
cursorMoveResult = 1;
}
} else if (gBitFlags[pauseCtx->cursorPoint[PAUSE_EQUIP] - 1] &
} else if (gBitFlags[page->cursorPoint() - 1] &
gSaveContext.inventory.equipment) {
cursorMoveResult = 2;
}
} else {
pauseCtx->cursorY[PAUSE_EQUIP] = cursorY;
pauseCtx->cursorPoint[PAUSE_EQUIP] = cursorPoint;
page->cursorY() = cursorY;
page->cursorPoint() = cursorPoint;
cursorMoveResult = 3;
}
} else {
@ -317,21 +318,21 @@ void KaleidoScope_DrawEquipment(GlobalContext* globalCtx) {
if (cursorX == 0) {
if (cursorY == 0) {
if (CUR_UPG_VALUE(UPG_BULLET_BAG) != 0) {
pauseCtx->cursorPoint[PAUSE_EQUIP] = cursorPoint;
pauseCtx->cursorX[PAUSE_EQUIP] = cursorX;
pauseCtx->cursorY[PAUSE_EQUIP] = cursorY;
page->cursorPoint() = cursorPoint;
page->cursorX() = cursorX;
page->cursorY() = cursorY;
break;
}
} else if (CUR_UPG_VALUE(cursorY) != 0) {
pauseCtx->cursorPoint[PAUSE_EQUIP] = cursorPoint;
pauseCtx->cursorX[PAUSE_EQUIP] = cursorX;
pauseCtx->cursorY[PAUSE_EQUIP] = cursorY;
page->cursorPoint() = cursorPoint;
page->cursorX() = cursorX;
page->cursorY() = cursorY;
break;
}
} else if (gBitFlags[cursorPoint - 1] & gSaveContext.inventory.equipment) {
pauseCtx->cursorPoint[PAUSE_EQUIP] = cursorPoint;
pauseCtx->cursorX[PAUSE_EQUIP] = cursorX;
pauseCtx->cursorY[PAUSE_EQUIP] = cursorY;
page->cursorPoint() = cursorPoint;
page->cursorX() = cursorX;
page->cursorY() = cursorY;
break;
}
@ -363,15 +364,15 @@ void KaleidoScope_DrawEquipment(GlobalContext* globalCtx) {
while (true) {
if (cursorX == 0) {
if (CUR_UPG_VALUE(cursorY) != 0) {
pauseCtx->cursorPoint[PAUSE_EQUIP] = cursorPoint;
pauseCtx->cursorX[PAUSE_EQUIP] = cursorX;
pauseCtx->cursorY[PAUSE_EQUIP] = cursorY;
page->cursorPoint() = cursorPoint;
page->cursorX() = cursorX;
page->cursorY() = cursorY;
break;
}
} else if (gBitFlags[cursorPoint - 1] & gSaveContext.inventory.equipment) {
pauseCtx->cursorPoint[PAUSE_EQUIP] = cursorPoint;
pauseCtx->cursorX[PAUSE_EQUIP] = cursorX;
pauseCtx->cursorY[PAUSE_EQUIP] = cursorY;
page->cursorPoint() = cursorPoint;
page->cursorX() = cursorX;
page->cursorY() = cursorY;
break;
}
@ -394,28 +395,28 @@ void KaleidoScope_DrawEquipment(GlobalContext* globalCtx) {
}
}
if (pauseCtx->cursorX[PAUSE_EQUIP] == 0) {
if (page->cursorX() == 0) {
pauseCtx->cursorColorSet = 0;
if (LINK_AGE_IN_YEARS == YEARS_CHILD) {
if ((pauseCtx->cursorY[PAUSE_EQUIP] == 0) && (CUR_UPG_VALUE(UPG_BULLET_BAG) != 0)) {
if ((page->cursorY() == 0) && (CUR_UPG_VALUE(UPG_BULLET_BAG) != 0)) {
cursorItem = ITEM_BULLET_BAG_30 + CUR_UPG_VALUE(UPG_BULLET_BAG) - 1;
} else {
cursorItem = ITEM_QUIVER_30 + sUpgradeItemOffsets[pauseCtx->cursorY[PAUSE_EQUIP]] +
CUR_UPG_VALUE(pauseCtx->cursorY[PAUSE_EQUIP]) - 1;
cursorItem = ITEM_QUIVER_30 + sUpgradeItemOffsets[page->cursorY()] +
CUR_UPG_VALUE(page->cursorY()) - 1;
osSyncPrintf("H_arrowcase_1 + non_equip_item_table = %d\n", cursorItem);
}
} else {
if ((pauseCtx->cursorY[PAUSE_EQUIP] == 0) && (CUR_UPG_VALUE(UPG_QUIVER) == 0)) {
if ((page->cursorY() == 0) && (CUR_UPG_VALUE(UPG_QUIVER) == 0)) {
cursorItem = ITEM_BULLET_BAG_30 + CUR_UPG_VALUE(UPG_BULLET_BAG) - 1;
} else {
cursorItem = ITEM_QUIVER_30 + sUpgradeItemOffsets[pauseCtx->cursorY[PAUSE_EQUIP]] +
CUR_UPG_VALUE(pauseCtx->cursorY[PAUSE_EQUIP]) - 1;
cursorItem = ITEM_QUIVER_30 + sUpgradeItemOffsets[page->cursorY()] +
CUR_UPG_VALUE(page->cursorY()) - 1;
osSyncPrintf("大人 H_arrowcase_1 + non_equip_item_table = %d\n", cursorItem);
}
}
} else {
cursorItem = ITEM_SWORD_KOKIRI + sEquipmentItemOffsets[pauseCtx->cursorPoint[PAUSE_EQUIP]];
cursorItem = ITEM_SWORD_KOKIRI + sEquipmentItemOffsets[page->cursorPoint()];
osSyncPrintf("ccc=%d\n", cursorItem);
if (pauseCtx->cursorSpecialPos == 0) {
@ -423,7 +424,7 @@ void KaleidoScope_DrawEquipment(GlobalContext* globalCtx) {
}
}
if ((pauseCtx->cursorY[PAUSE_EQUIP] == 0) && (pauseCtx->cursorX[PAUSE_EQUIP] == 3)) {
if ((page->cursorY() == 0) && (page->cursorX() == 3)) {
if (gSaveContext.bgsFlag != 0) {
cursorItem = ITEM_HEART_PIECE_2;
} else if (gBitFlags[3] & gSaveContext.inventory.equipment) {
@ -431,20 +432,20 @@ void KaleidoScope_DrawEquipment(GlobalContext* globalCtx) {
}
}
cursorSlot = pauseCtx->cursorPoint[PAUSE_EQUIP];
cursorSlot = page->cursorPoint();
pauseCtx->cursorItem[PAUSE_EQUIP] = cursorItem;
pauseCtx->cursorSlot[PAUSE_EQUIP] = cursorSlot;
page->cursorItem() = cursorItem;
page->cursorSlot() = cursorSlot;
osSyncPrintf("kscope->select_name[Display_Equipment] = %d\n", pauseCtx->cursorItem[PAUSE_EQUIP]);
osSyncPrintf("kscope->select_name[Display_Equipment] = %d\n", page->cursorItem());
if (!((gEquipAgeReqs[pauseCtx->cursorY[PAUSE_EQUIP]][pauseCtx->cursorX[PAUSE_EQUIP]] == 9) ||
(gEquipAgeReqs[pauseCtx->cursorY[PAUSE_EQUIP]][pauseCtx->cursorX[PAUSE_EQUIP]] ==
if (!((gEquipAgeReqs[page->cursorY()][page->cursorX()] == 9) ||
(gEquipAgeReqs[page->cursorY()][page->cursorX()] ==
((void)0, gSaveContext.linkAge)))) {
pauseCtx->nameColorSet = 1;
}
if (pauseCtx->cursorItem[PAUSE_EQUIP] == ITEM_BRACELET) {
if (page->cursorItem() == ITEM_BRACELET) {
if (LINK_AGE_IN_YEARS == YEARS_CHILD) {
pauseCtx->nameColorSet = 0;
} else {
@ -452,7 +453,7 @@ void KaleidoScope_DrawEquipment(GlobalContext* globalCtx) {
}
}
if ((pauseCtx->cursorX[PAUSE_EQUIP] == 0) && (pauseCtx->cursorY[PAUSE_EQUIP] == 0)) {
if ((page->cursorX() == 0) && (page->cursorY() == 0)) {
if (LINK_AGE_IN_YEARS != YEARS_CHILD) {
if ((cursorItem >= ITEM_BULLET_BAG_30) && (cursorItem <= ITEM_BULLET_BAG_50)) {
pauseCtx->nameColorSet = 1;
@ -464,24 +465,24 @@ void KaleidoScope_DrawEquipment(GlobalContext* globalCtx) {
}
}
KaleidoScope_SetCursorVtx(pauseCtx, cursorSlot * 4, pauseCtx->equipVtx);
KaleidoScope_SetCursorVtx(pauseCtx, cursorSlot * 4, equipVtx);
if ((pauseCtx->cursorSpecialPos == 0) && (cursorItem != PAUSE_ITEM_NONE) && (pauseCtx->state == 6) &&
(pauseCtx->unk_1E4 == 0) &&
(pauseCtx->cursorX[PAUSE_EQUIP] != 0)) {
(page->cursorX() != 0)) {
if(CHECK_BTN_ALL(input->press.button, BTN_A))
{
if((gEquipAgeReqs[pauseCtx->cursorY[PAUSE_EQUIP]][pauseCtx->cursorX[PAUSE_EQUIP]] == 9) || (gEquipAgeReqs[pauseCtx->cursorY[PAUSE_EQUIP]][pauseCtx->cursorX[PAUSE_EQUIP]] == ((void)0, gSaveContext.linkAge)))
if((gEquipAgeReqs[page->cursorY()][page->cursorX()] == 9) || (gEquipAgeReqs[page->cursorY()][page->cursorX()] == ((void)0, gSaveContext.linkAge)))
{
Inventory_ChangeEquipment(pauseCtx->cursorY[PAUSE_EQUIP], pauseCtx->cursorX[PAUSE_EQUIP]);
Inventory_ChangeEquipment(page->cursorY(), page->cursorX());
if(pauseCtx->cursorY[PAUSE_EQUIP] == EQUIP_SWORD)
if(page->cursorY() == EQUIP_SWORD)
{
gSaveContext.infTable[29] = 0;
gSaveContext.equips.buttonItems[0] = cursorItem;
if((pauseCtx->cursorX[PAUSE_EQUIP] == 3) && (gSaveContext.bgsFlag != 0))
if((page->cursorX() == 3) && (gSaveContext.bgsFlag != 0))
{
gSaveContext.equips.buttonItems[0] = ITEM_SWORD_BGS;
gSaveContext.swordHealth = 8;
@ -525,7 +526,7 @@ void KaleidoScope_DrawEquipment(GlobalContext* globalCtx) {
pauseCtx->equipTargetCBtn = 2;
}
EquipmentPosition equip(PAUSE_EQUIP, pauseCtx->cursorX[PAUSE_EQUIP] - 1, pauseCtx->cursorY[PAUSE_EQUIP]);
EquipmentPosition equip(PAUSE_EQUIP, page->cursorX() - 1, page->cursorY());
if(Equip_MeetsAgeRequirement(equip) && Inventory_IsEquipmentOwned(equip))
{
@ -546,11 +547,11 @@ void KaleidoScope_DrawEquipment(GlobalContext* globalCtx) {
}
}
if (oldCursorPoint != pauseCtx->cursorPoint[PAUSE_EQUIP]) {
if (oldCursorPoint != page->cursorPoint()) {
Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gAudioDefaultPos, 4, &D_801333E0, &D_801333E0, &gReverbAdd2);
}
} else if ((pauseCtx->unk_1E4 == 7) && (pauseCtx->pageIndex == PAUSE_EQUIP)) {
KaleidoScope_SetCursorVtx(pauseCtx, pauseCtx->cursorSlot[PAUSE_EQUIP] * 4, pauseCtx->equipVtx);
} else if ((pauseCtx->unk_1E4 == 7) && page == KaleidoScope_CurrentPage()) {
KaleidoScope_SetCursorVtx(pauseCtx, page->cursorSlot() * 4, equipVtx);
pauseCtx->cursorColorSet = 8;
sEquipTimer--;
@ -566,14 +567,14 @@ void KaleidoScope_DrawEquipment(GlobalContext* globalCtx) {
if ((gBitFlags[bit] & gSaveContext.inventory.equipment) && (pauseCtx->cursorSpecialPos == 0)) {
if ((gEquipAgeReqs[i][k + 1] == 9) || (gEquipAgeReqs[i][k + 1] == ((void)0, gSaveContext.linkAge))) {
if (temp == cursorSlot) {
pauseCtx->equipVtx[j].v.ob[0] = pauseCtx->equipVtx[j + 2].v.ob[0] =
pauseCtx->equipVtx[j].v.ob[0] - 2;
pauseCtx->equipVtx[j + 1].v.ob[0] = pauseCtx->equipVtx[j + 3].v.ob[0] =
pauseCtx->equipVtx[j + 1].v.ob[0] + 4;
pauseCtx->equipVtx[j].v.ob[1] = pauseCtx->equipVtx[j + 1].v.ob[1] =
pauseCtx->equipVtx[j].v.ob[1] + 2;
pauseCtx->equipVtx[j + 2].v.ob[1] = pauseCtx->equipVtx[j + 3].v.ob[1] =
pauseCtx->equipVtx[j + 2].v.ob[1] - 4;
equipVtx[j].v.ob[0] = equipVtx[j + 2].v.ob[0] =
equipVtx[j].v.ob[0] - 2;
equipVtx[j + 1].v.ob[0] = equipVtx[j + 3].v.ob[0] =
equipVtx[j + 1].v.ob[0] + 4;
equipVtx[j].v.ob[1] = equipVtx[j + 1].v.ob[1] =
equipVtx[j].v.ob[1] + 2;
equipVtx[j + 2].v.ob[1] = equipVtx[j + 3].v.ob[1] =
equipVtx[j + 2].v.ob[1] - 4;
}
}
}
@ -586,7 +587,7 @@ void KaleidoScope_DrawEquipment(GlobalContext* globalCtx) {
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, pauseCtx->alpha);
for (rowStart = 0, j = 0, temp = 0, i = 0; i < 4; i++, rowStart += 4, j += 16) {
gSPVertex(POLY_OPA_DISP++, &pauseCtx->equipVtx[j], 16, 0);
gSPVertex(POLY_OPA_DISP++, &equipVtx[j], 16, 0);
if (LINK_AGE_IN_YEARS == YEARS_CHILD) {
point = CUR_UPG_VALUE(sChildUpgrades[i]);
@ -637,7 +638,7 @@ void KaleidoScope_DrawEquipment(GlobalContext* globalCtx) {
gSPSegment(POLY_OPA_DISP++, 0x0C, pauseCtx->iconItemAltSegment);
func_800949A8(globalCtx->state.gfxCtx);
KaleidoScope_DrawEquipmentImage(globalCtx, pauseCtx->playerSegment, 64, 112);
KaleidoScope_DrawEquipmentImage(globalCtx, pauseCtx->playerSegment, 64, 112, equipVtx);
if (gUpgradeMasks[0]) {}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -3,6 +3,7 @@
#include "ultra64.h"
#include "global.h"
#include "kaleido_macros.h"
extern u8 gAmmoItems[];
extern s16 D_8082AAEC[];
@ -11,24 +12,27 @@ extern u8 gSlotAgeReqs[];
extern u8 gEquipAgeReqs[][4];
extern u8 gAreaGsFlags[];
void KaleidoScope_DrawQuestStatus(GlobalContext* globalCtx, GraphicsContext* gfxCtx);
s32 KaleidoScope_UpdateQuestStatusPoint(PauseContext* pauseCtx, s32 point);
void KaleidoScope_DrawQuestStatus(GlobalContext* globalCtx, GraphicsContext* gfxCtx, oot::pause::Page* page);
s32 KaleidoScope_UpdateQuestStatusPoint(oot::pause::Page* page, s32 point);
void KaleidoScope_DrawDebugEditor(GlobalContext* globalCtx);
void KaleidoScope_DrawPlayerWork(GlobalContext* globalCtx);
void KaleidoScope_DrawEquipment(GlobalContext* globalCtx);
void KaleidoScope_DrawEquipment(GlobalContext* globalCtx, oot::pause::Page* page);
void KaleidoScope_DrawController(GlobalContext* globalCtx, oot::pause::Page* page);
void KaleidoScope_SetCursorVtx(PauseContext* pauseCtx, u16 index, Vtx* vtx);
void KaleidoScope_DrawItemSelect(GlobalContext* globalCtx);
void KaleidoScope_UpdateItemEquip(GlobalContext* globalCtx);
void KaleidoScope_DrawDungeonMap(GlobalContext* globalCtx, GraphicsContext* gfxCtx);
void KaleidoScope_DrawWorldMap(GlobalContext* globalCtx, GraphicsContext* gfxCtx);
void KaleidoScope_DrawItemSelect(GlobalContext* globalCtx, oot::pause::Page* page);
void KaleidoScope_UpdateItemEquip(GlobalContext* globalCtx, Vtx* itemVtx);
void KaleidoScope_DrawDungeonMap(GlobalContext* globalCtx, GraphicsContext* gfxCtx, oot::pause::Page* page);
void KaleidoScope_DrawWorldMap(GlobalContext* globalCtx, GraphicsContext* gfxCtx, oot::pause::Page* page);
void KaleidoScope_UpdatePrompt(GlobalContext* globalCtx);
Gfx* KaleidoScope_QuadTextureIA4(Gfx* gfx, void* texture, s16 width, s16 height, u16 point);
Gfx* KaleidoScope_QuadTextureIA8(Gfx* gfx, void* texture, s16 width, s16 height, u16 point);
Gfx* KaleidoScope_QuadTextureRGBA16(Gfx* gfx, void* texture, s16 width, s16 height, u16 point);
Gfx* KaleidoScope_QuadTextureRGBA32(Gfx* gfx, void* texture, s16 width, s16 height, u16 point);
void KaleidoScope_MoveCursorToSpecialPos(GlobalContext* globalCtx, u16 specialPos);
void KaleidoScope_DrawQuadTextureRGBA32(GraphicsContext* gfxCtx, void* texture, u16 width, u16 height, u16 point);
void KaleidoScope_ProcessPlayerPreRender();
void KaleidoScope_SetupPlayerPreRender(GlobalContext* globalCtx);
void KaleidoScope_DrawCursor(GlobalContext* globalCtx, u16 pageIndex);
void KaleidoScope_DrawCursor(GlobalContext* globalCtx, oot::pause::Page* page);
void KaleidoScope_UpdateDungeonMap(GlobalContext* globalCtx);
void PauseMapMark_Draw(GlobalContext* globalCtx);

File diff suppressed because it is too large Load Diff

View File

@ -3,12 +3,10 @@
#include <ctime>
#include <fstream>
#include <filesystem>
#include "tas.h"
#include "../options.h"
#include "controllers.h"
#ifdef __SWITCH__
#define TAS_DIR "sdmc:/switch/sm64/tas"
#define TAS_DIR "sdmc:/switch/oot/tas"
#else
#define TAS_DIR "tas"
#endif
@ -32,21 +30,23 @@ namespace oot::hid
return g_gyroEnabled;
}
Controller::State::State()
{
mouse_x = 0;
mouse_y = 0;
has_mouse = false;
static u16 gClearButtonPressFrames = 0;
#ifdef ENABLE_GYRO
memset(&gyro, 0, sizeof(gyro));
memset(&accel, 0, sizeof(accel));
#endif
void clearPressedButtons(u16 frames)
{
gClearButtonPressFrames = frames;
}
State::State()
{
mouse_x = 0;
mouse_y = 0;
has_mouse = false;
reset();
}
void Controller::State::reset()
void State::reset()
{
button = 0;
stick_x = 0;
@ -62,11 +62,24 @@ namespace oot::hid
{
}
Controller::~Controller()
void Controller::SendMotorEvent(short time, short level)
{
}
void Controller::SendMotorDecay(short level)
{
}
void Controller::ResetMotorPack()
{
}
void Controller::SendMotorVib(int level)
{
}
void Controller::update()
{
if(m_tasFile) // Tas file is open
fclose(m_tasFile);
m_tasFile = nullptr;
}
void Controller::merge(const Controller& controller)
@ -74,16 +87,24 @@ namespace oot::hid
m_state.button |= controller.m_state.button;
if(abs(m_state.stick_x) < abs(controller.m_state.stick_x))
{
m_state.stick_x = controller.m_state.stick_x;
}
if(abs(m_state.stick_y) < abs(controller.m_state.stick_y))
{
m_state.stick_y = controller.m_state.stick_y;
}
if(abs(m_state.r_stick_x) < abs(controller.m_state.r_stick_x))
{
m_state.r_stick_x = controller.m_state.r_stick_x;
}
if(abs(m_state.r_stick_y) < abs(controller.m_state.r_stick_y))
{
m_state.r_stick_y = controller.m_state.r_stick_y;
}
if(controller.hasMouse())
{
@ -94,118 +115,65 @@ namespace oot::hid
m_state.has_mouse |= controller.m_state.has_mouse;
}
static std::ofstream g_tas;
bool Controller::hasMouse() const
{
return m_state.has_mouse;
}
static std::string getTasFileName()
{
std::error_code error;
std::filesystem::create_directory(TAS_DIR, error);
time_t now = time(0);
tm* ltm = localtime(&now);
if (!ltm)
{
return TAS_DIR"/record.tas";
}
char buf[64] = { 0 };
sprintf(buf, TAS_DIR"/%04d.%02d.%02d-%04d.tas", ltm->tm_year, ltm->tm_mon + 1, ltm->tm_mday, ltm->tm_hour * 60 + ltm->tm_min);
return buf;
}
#ifdef ENABLE_TAS
static std::ofstream* g_tas = nullptr;
static std::ofstream& stream()
{
/*if (!g_tas)
if (!g_tas)
{
auto name = getTasFileName();
g_tas = std::ofstream(name, std::ofstream::binary);
if (g_tas)
g_tas.write((const char*)&oot::config(), sizeof(oot::config()));
}*/
g_tas = new std::ofstream(name, std::ifstream::binary);
g_tas->write((const char*)&config(), sizeof(config()));
}
return g_tas;
}
static u16 gClearButtonPressFrames = 0;
void Controller::clearPressedButtons(u16 frames)
{
gClearButtonPressFrames = frames;
return *g_tas;
}
#endif
void Controller::resolveInputs()
{
#define SRAM_SIZE 0x8000 // But this in ultra_reimplementation.h?
// Recording TAS?
if(!tas::isTasPlaying() && oot::config().game().recordTas())
#ifdef ENABLE_TAS
if (!hid::isTasPlaying() && config().game().recordTas())
{
// stream().write((const char*)&m_state, sizeof(m_state));
stream().write((const char*)&m_state, sizeof(m_state));
// Write TAS data
if(!m_tasFile) // Not open yet?
if (m_state.button)
{
fopen_s(&m_tasFile, tas::getTasFileName().c_str(), "wb");
if(!m_tasFile)
return;
// Write our current config
// fwrite(&oot::config(), sizeof(oot::config()), 1, m_tasOutput);
// Write save data
uint8_t* sram = new uint8_t[SRAM_SIZE];
FILE* save = nullptr;
fopen_s(&save, "oot.sav", "rb");
if(save)
{
fread(sram, sizeof(uint8_t), SRAM_SIZE, save);
fclose(save);
}
fwrite(sram, sizeof(uint8_t), SRAM_SIZE, m_tasFile);
delete[] sram;
int y = 0;
}
if(m_tasFile) // Tas file is open
{
// fwrite(&m_state, sizeof(m_state), 1, m_tasFile);
StateCompressed compressed(m_state); // Compress the state
compressed.write(m_tasFile); // Write to TAS file
#ifdef _DEBUG
fflush(m_tasFile); // Flush every frame to keep all the data when the game crashes
}
#endif
}
}
// Playing back a TAS?
else if(tas::isTasPlaying())
{
if(!m_tasFile)
{
m_tasFile = fopen(tas::getTasFileName().c_str(), "rb");
if(!m_tasFile)
return;
// fread(&oot::config(), 1, sizeof(oot::config()), fp);
uint8_t* sram = new uint8_t[SRAM_SIZE];
fread(sram, sizeof(uint8_t), SRAM_SIZE, m_tasFile);
FILE* save = nullptr;
fopen_s(&save, "oot.sav", "wb");
if(save)
{
fwrite(sram, sizeof(uint8_t), SRAM_SIZE, save);
fclose(save);
}
delete[] sram;
}
if(m_tasFile)
{
// fread(&m_state, sizeof(m_state), 1, m_tasFile);//Uncompressed read
StateCompressed compressed;
bool end_of_file = compressed.read(m_tasFile); // Read the compressed state
if(end_of_file) // End of file reached, playback is complete
tas::TasEnded();
else
m_state = compressed; // Uncompress
}
}
rawStickX = m_state.stick_x;
rawStickY = m_state.stick_y;
r_rawStickX = m_state.r_stick_x;
r_rawStickY = m_state.r_stick_y;
if(gClearButtonPressFrames)
{
gClearButtonPressFrames--;
@ -231,16 +199,24 @@ namespace oot::hid
// modulate the rawStickX and rawStickY to be the new f32 values by adding/subtracting 6.
if(this->rawStickX <= -8)
{
this->stickX = this->rawStickX + 6;
}
if(this->rawStickX >= 8)
{
this->stickX = this->rawStickX - 6;
}
if(this->rawStickY <= -8)
{
this->stickY = this->rawStickY + 6;
}
if(this->rawStickY >= 8)
{
this->stickY = this->rawStickY - 6;
}
// calculate f32 magnitude from the center by vector length.
this->stickMag = sqrtf(this->stickX * this->stickX + this->stickY * this->stickY);
@ -258,16 +234,24 @@ namespace oot::hid
this->r_stickY = 0;
if(this->r_rawStickX <= -8)
{
this->r_stickX = this->r_rawStickX + 6;
}
if(this->r_rawStickX >= 8)
{
this->r_stickX = this->r_rawStickX - 6;
}
if(this->r_rawStickY <= -8)
{
this->r_stickY = this->r_rawStickY + 6;
}
if(this->r_rawStickY >= 8)
{
this->r_stickY = this->r_rawStickY - 6;
}
// calculate f32 magnitude from the center by vector length.
this->r_stickMag = sqrtf(this->r_stickX * this->r_stickX + this->r_stickY * this->r_stickY);
@ -305,8 +289,13 @@ namespace oot::hid
return m_state.mouse_y * (oot::config().camera().mouseyInvert() ? -1 : 1) * oot::config().camera().mouseyScaler();
}
/*bool Controller::updateRebind(int input)
bool Controller::updateRebind(int input)
{
return false;
}*/
} // namespace oot::hid
}
void Controller::resetBindings()
{
}
} // namespace oot::hid

View File

@ -1,148 +1,131 @@
#pragma once
#include "ultra64/types.h"
#include <stdio.h>
namespace oot
namespace oot::hid
{
namespace hid
enum Button
{
void gyroEnable();
void gyroDisable();
bool isGyroEnabled();
CONT_A = 0x8000,
CONT_B = 0x4000,
CONT_G = 0x2000,
CONT_START = 0x1000,
CONT_UP = 0x0800,
CONT_DOWN = 0x0400,
CONT_LEFT = 0x0200,
CONT_RIGHT = 0x0100,
CONT_L = 0x0020,
CONT_R = 0x0010,
CONT_E = 0x0008,
CONT_D = 0x0004,
CONT_C = 0x0002,
CONT_F = 0x0001,
class Controller
{
A_BUTTON = CONT_A,
B_BUTTON = CONT_B,
L_TRIG = CONT_L,
R_TRIG = CONT_R,
Z_TRIG = CONT_G,
START_BUTTON = CONT_START,
U_JPAD = CONT_UP,
L_JPAD = CONT_LEFT,
R_JPAD = CONT_RIGHT,
D_JPAD = CONT_DOWN,
U_CBUTTONS = CONT_E,
L_CBUTTONS = CONT_C,
R_CBUTTONS = CONT_F,
D_CBUTTONS = CONT_D,
STICK_X_LEFT = 1 << 16,
STICK_X_RIGHT = 1 << 17,
STICK_X_DOWN = 1 << 19,
STICK_X_UP = 1 << 18,
WALK_BUTTON = 1 << 20,
OCARINA = 1 << 21,
HOOKSHOT = 1 << 22,
BOW_ARROW = 1 << 23,
LENS_OF_TRUTH = 1 << 24,
BOOTS_TOGGLE = 1 << 25,
SWORD_TOGGLE = 1 << 26,
SHIELD_TOGGLE = 1 << 27,
TUNIC_TOGGLE = 1 << 28
};
class State
{
public:
class State
{
public:
State();
void reset();
State();
void reset();
u16 button;
s8 stick_x; /* -80 <= stick_x <= 80 */
s8 stick_y; /* -80 <= stick_y <= 80 */
u8 errnum;
s8 r_stick_x; /* -80 <= stick_x <= 80 */
s8 r_stick_y; /* -80 <= stick_y <= 80 */
u16 button;
s8 stick_x; /* -80 <= stick_x <= 80 */
s8 stick_y; /* -80 <= stick_y <= 80 */
u8 errnum;
s8 r_stick_x; /* -80 <= stick_x <= 80 */
s8 r_stick_y; /* -80 <= stick_y <= 80 */
#ifdef ENABLE_GYRO
float gyro[3];
float accel[3];
#endif
s64 mouse_x;
s64 mouse_y;
bool has_mouse;
};
s64 mouse_x;
s64 mouse_y;
bool has_mouse;
};
class StateCompressed
{
public:
StateCompressed() = default;
StateCompressed(State state)
{
m_data.button = state.button;
m_data.stick_x = state.stick_x;
m_data.stick_y = state.stick_y;
//Is there any real data?
m_isUsed = m_data.button || m_data.stick_x || m_data.stick_y;
}
operator State ()
{
State ret;
ret.button = m_data.button;
ret.stick_x = m_data.stick_x;
ret.stick_y = m_data.stick_y;
return ret;
}
bool read(FILE* in) {
if (fread(&m_isUsed, sizeof(u8), 1, in) != 1)//Read the flag
return true;//End of file reached
if (m_isUsed)//Is there even any input?
fread(&m_data, sizeof(InputFrame), 1, in);//Write the full state
return false;
}
void write(FILE* out) {
fwrite(&m_isUsed, sizeof(u8), 1, out);//Write if there is data
if (m_isUsed)//Is there even any input?
fwrite(&m_data, sizeof(InputFrame), 1, out);//Write the full state
}
private:
u8 m_isUsed = 0;//0 when all input is zero
struct InputFrame {
u16 button = 0x0000;
s8 stick_x = 0; /* -80 <= stick_x <= 80 */
s8 stick_y = 0; /* -80 <= stick_y <= 80 */
} m_data;
};
class Controller
{
public:
s16 rawStickX;
s16 rawStickY;
float stickX; // [-64, 64] positive is right
float stickY; // [-64, 64] positive is up
float stickMag; // distance from center [0, 64]
u16 buttonDown;
u16 buttonPressed;
s16 r_rawStickX; //
s16 r_rawStickY; //
float r_stickX; // [-64, 64] positive is right
float r_stickY; // [-64, 64] positive is up
float r_stickMag; // distance from center [0, 64]
s16 rawStickX;
s16 rawStickY;
float stickX; // [-64, 64] positive is right
float stickY; // [-64, 64] positive is up
float stickMag; // distance from center [0, 64]
u16 buttonDown;
u16 buttonPressed;
s16 r_rawStickX; //
s16 r_rawStickY; //
float r_stickX; // [-64, 64] positive is right
float r_stickY; // [-64, 64] positive is up
float r_stickMag; // distance from center [0, 64]
s64 mouse_x() const;
s64 mouse_y() const;
#ifdef ENABLE_GYRO
bool m_hasGyro = false;
bool m_hasAccel = false;
#endif
Controller(bool isLocal = true);
virtual void update();
virtual void resolveInputs();
virtual bool isLocal() const
{
return m_isLocal;
}
const State& state() const
{
return m_state;
}
s64 mouse_x() const;
s64 mouse_y() const;
State& state()
{
return m_state;
}
Controller(bool isLocal = true);
~Controller();
virtual void resetBindings();
static void clearPressedButtons(u16 frames = 1);
virtual void merge(const Controller& controller);
virtual bool hasMouse() const;
virtual void update() {}
virtual void resolveInputs();
virtual bool isLocal() const {
return m_isLocal;
}
State& state() {
return m_state;
}
const State state() const {
return m_state;
}
virtual void SendMotorEvent(short time, short level);
virtual void SendMotorDecay(short level);
virtual void ResetMotorPack();
virtual void SendMotorVib(int level);
virtual void merge(const Controller& controller);
virtual bool hasMouse() const { return m_state.has_mouse; }
virtual void SendMotorEvent(short time, short level) {}
virtual void SendMotorDecay(short level) {}
virtual void ResetMotorPack() {}
virtual void SendMotorVib(int level) {}
//virtual bool updateRebind(Button input);
virtual bool updateRebind(int input);
protected:
State m_state;
bool m_isLocal;
bool m_motorEnabled;
State m_state;
bool m_isLocal;
bool m_motorEnabled;
};
private:
FILE* m_tasFile = nullptr;
};
}
}
bool isTasPlaying();
void gyroEnable();
void gyroDisable();
bool isGyroEnabled();
void clearPressedButtons(u16 frames = 1);
} // namespace oot::hid

View File

@ -5,107 +5,146 @@
#include <stdexcept>
#include "../options.h"
using namespace oot::hid;
static InputDeviceManager* g_deviceManager = nullptr;
InputDeviceManager& InputDeviceManager::get()
namespace oot::hid
{
if (!g_deviceManager)
g_deviceManager = new InputDeviceManager();
return *g_deviceManager;
}
static Controllers* g_controllers;
Controller& Device::controller(const u64 index)
{
if (index >= m_controllers.size())
throw std::runtime_error("invalid controller index");
return *m_controllers[index];
}
bool Device::updateRebind(Button input)
{
bool result = 0;
for (auto& controller : m_controllers)
Controllers& controllers()
{
controller->state().reset();
//result |= controller->updateRebind(input);
controller->resolveInputs();
if(!g_controllers)
{
g_controllers = new Controllers();
}
return *g_controllers;
}
return result;
}
void Device::update()
{
for(auto& controller : m_controllers)
Driver::Driver()
{
controller->state().reset();
controller->update();
controller->resolveInputs();
}
}
Driver::~Driver()
{
}
const u64 Driver::size() const
{
return m_controllers.size();
}
InputDeviceManager::InputDeviceManager() : m_rebindInput(Button::NONE)
{
m_drivers.push_back(new Joypad());
Controller& Driver::controller(const u64 index)
{
if(index >= m_controllers.size())
{
throw std::runtime_error("invalid controller index");
}
return *m_controllers[index];
}
#ifdef ENABLE_MOUSE
m_drivers.push_back(new Keyboard());
#endif
//if (Tas::isTasPlaying())
//m_drivers.push_back(new Tas());
}
const u64 InputDeviceManager::size() const
{
u64 count = 0;
for (auto& driver : m_drivers)
count += driver->size();
return count;
}
void InputDeviceManager::update()
{
if (isRebindMode())
bool Driver::updateRebind(int input)
{
bool result = 0;
for (auto& driver : m_drivers)
result |= driver->updateRebind(m_rebindInput);
if (result)
m_rebindInput = Button::NONE;
for (auto& controller : m_controllers)
{
controller->state().reset();
result |= controller->updateRebind(input);
controller->resolveInputs();
}
return result;
}
else
void Driver::update()
{
for (auto& driver : m_drivers)
driver->update();
for(auto& controller : m_controllers)
{
controller->state().reset();
controller->update();
controller->resolveInputs();
}
}
}
void InputDeviceManager::scan()
{
for (auto& driver : m_drivers)
void Driver::scan(class Controllers* controllers)
{
//if(!driver->defaultOnly() || !found)
driver->scan();
}
}
Controllers::Controllers() : m_rebindInput(0)
{
m_drivers.push_back(new SDL());
#ifdef ENABLE_MOUSE
m_drivers.push_back(new Keyboard());
#endif
//m_drivers.push_back(new Tas());
}
Controllers::~Controllers()
{
}
const u64 Controllers::size() const
{
u64 count = 0;
for(auto& driver : m_drivers)
{
count += driver->size();
}
return count;
}
void Controllers::update()
{
if (isRebindMode())
{
bool result = 0;
for (auto& driver : m_drivers)
{
result |= driver->updateRebind(m_rebindInput);
}
if (result)
{
m_rebindInput = 0;
}
}
else
{
for (auto& driver : m_drivers)
{
driver->update();
}
}
}
void Controllers::scan()
{
u64 found = 0;
for(auto& driver : m_drivers)
{
//if(!driver->defaultOnly() || !found)
{
driver->scan(this);
found += driver->size();
}
}
}
void Controllers::resetBindings()
{
for(auto& driver : m_drivers)
{
driver->resetBindings();
}
}
void Controllers::rebind(int input)
{
m_rebindInput = input;
}
bool Controllers::isRebindMode() const
{
return m_rebindInput > 0;
}
} // namespace oot::hid

View File

@ -1,105 +1,57 @@
#pragma once
#include "ultra64/types.h"
#include "controller.h"
#include <vector>
#include <memory>
namespace oot
namespace oot::hid
{
namespace hid
class Driver
{
enum class Button : uint32_t
public:
Driver();
virtual ~Driver();
virtual const u64 size() const;
virtual Controller& controller(const u64 index);
virtual void update();
virtual bool updateRebind(int input);
virtual void scan(class Controllers* controllers);
virtual void resetBindings() = 0;
virtual bool defaultOnly()
{
NONE = 0x0000,
CONT_A = 0x8000,
CONT_B = 0x4000,
CONT_G = 0x2000,
CONT_START = 0x1000,
CONT_UP = 0x0800,
CONT_DOWN = 0x0400,
CONT_LEFT = 0x0200,
CONT_RIGHT = 0x0100,
CONT_L = 0x0020,
CONT_R = 0x0010,
CONT_E = 0x0008,
CONT_D = 0x0004,
CONT_C = 0x0002,
CONT_F = 0x0001,
return false;
}
A_BUTTON = CONT_A,
B_BUTTON = CONT_B,
L_TRIG = CONT_L,
R_TRIG = CONT_R,
Z_TRIG = CONT_G,
START_BUTTON = CONT_START,
U_JPAD = CONT_UP,
L_JPAD = CONT_LEFT,
R_JPAD = CONT_RIGHT,
D_JPAD = CONT_DOWN,
U_CBUTTONS = CONT_E,
L_CBUTTONS = CONT_C,
R_CBUTTONS = CONT_F,
D_CBUTTONS = CONT_D,
STICK_X_LEFT = 1 << 16,
STICK_X_RIGHT = 1 << 17,
STICK_X_DOWN = 1 << 19,
STICK_X_UP = 1 << 18,
WALK_BUTTON = 1 << 20,
OCARINA = 1 << 21,
HOOKSHOT = 1 << 22,
BOW_ARROW = 1 << 23,
LENS_OF_TRUTH = 1 << 24,
BOOTS_TOGGLE = 1 << 25,
SWORD_TOGGLE = 1 << 26,
SHIELD_TOGGLE = 1 << 27,
TUNIC_TOGGLE = 1 << 28
};
class Device;
class InputDeviceManager
std::vector<std::shared_ptr<Controller>>& controllers()
{
public:
static InputDeviceManager& get();
return m_controllers;
}
InputDeviceManager();
virtual ~InputDeviceManager() {}
const u64 size() const;
void update();
void scan();
bool isRebindMode() const { return m_rebindInput != Button::NONE; }
void rebind(Button input) { m_rebindInput = input; }
std::vector<Device*>& drivers() { return m_drivers; }
protected:
std::vector<std::shared_ptr<Controller>> m_controllers;
};
protected:
std::vector<Device*> m_drivers;
Button m_rebindInput;
};
class Device
class Controllers
{
public:
Controllers();
virtual ~Controllers();
const u64 size() const;
void update();
void scan();
bool isRebindMode() const;
void rebind(int input);
void resetBindings();
std::vector<class Driver*>& drivers()
{
public:
Device() = default;
virtual ~Device() {}
return m_drivers;
}
virtual void scan() = 0;
protected:
std::vector<class Driver*> m_drivers;
int m_rebindInput;
};
virtual const u64 size() const { return m_controllers.size(); }
virtual Controller& controller(const u64 index);
virtual void update();
virtual bool updateRebind(Button input);
virtual bool defaultOnly() { return false; }
std::vector<std::shared_ptr<Controller>>& controllers() { return m_controllers; }
protected:
std::vector<std::shared_ptr<Controller>> m_controllers;
};
}
}
Controllers& controllers();
} // namespace oot::hid

View File

@ -1,468 +1,557 @@
#include "ultra64/types.h"
#include "keyboard.h"
#include "def/z_player_lib.h"
#include "rapidjson/document.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/prettywriter.h"
#include <rapidjson/istreamwrapper.h>
#include <fstream>
#include <unordered_map>
#include <algorithm>
#include "def/z_player_lib.h"
#if !defined(DISABLE_SDL_CONTROLLER)
#include <SDL2/SDL.h>
#endif
#include "../player/players.h"
#include "../options.h"
#include "tas.h"
extern "C"
{
void set_fullscreen(bool value);
}
u8 Get_Language();
void Set_Language(u8 language_id);
bool saveJson(rapidjson::Document& doc, const std::string& jsonFilePath)
{
rapidjson::StringBuffer buffer;
rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buffer);
if(!doc.Accept(writer))
{
return false;
}
std::ofstream out(jsonFilePath.c_str(), std::ofstream::trunc);
out << buffer.GetString();
return true;
}
namespace oot::hid
{
bool saveJson(rapidjson::Document& doc, const std::string& jsonFilePath)
namespace controller
{
rapidjson::StringBuffer buffer;
rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buffer);
if(!doc.Accept(writer))
const char* getInputName(Button input)
{
return false;
switch(input)
{
case Button::STICK_X_UP:
return "STICK_X_UP";
case Button::STICK_X_LEFT:
return "STICK_X_LEFT";
case Button::STICK_X_DOWN:
return "STICK_X_DOWN";
case Button::STICK_X_RIGHT:
return "STICK_X_RIGHT";
case Button::A_BUTTON:
return "A_BUTTON";
case Button::B_BUTTON:
return "B_BUTTON";
case Button::Z_TRIG:
return "Z_TRIG";
case Button::U_CBUTTONS:
return "U_CBUTTONS";
case Button::L_CBUTTONS:
return "L_CBUTTONS";
case Button::D_CBUTTONS:
return "D_CBUTTONS";
case Button::R_CBUTTONS:
return "R_CBUTTONS";
case Button::R_TRIG:
return "R_TRIG";
case Button::L_TRIG:
return "L_TRIG";
case Button::START_BUTTON:
return "START_BUTTON";
case Button::WALK_BUTTON:
return "WALK_BUTTON";
case Button::OCARINA:
return "OCARINA";
case Button::HOOKSHOT:
return "HOOKSHOT";
case Button::BOW_ARROW:
return "BOW_ARROW";
case Button::LENS_OF_TRUTH:
return "LENS_OF_TRUTH";
case Button::BOOTS_TOGGLE:
return "BOOTS_TOGGLE";
case Button::SWORD_TOGGLE:
return "SWORD_TOGGLE";
case Button::SHIELD_TOGGLE:
return "SHIELD_TOGGLE";
case Button::TUNIC_TOGGLE:
return "TUNIC_TOGGLE";
}
return "";
}
std::ofstream out(jsonFilePath.c_str(), std::ofstream::trunc);
out << buffer.GetString();
return true;
}
const char* getInputName(Button input)
{
switch(input)
Button getInputValue(const std::string& input)
{
case Button::STICK_X_UP:
return "STICK_X_UP";
case Button::STICK_X_LEFT:
return "STICK_X_LEFT";
case Button::STICK_X_DOWN:
return "STICK_X_DOWN";
case Button::STICK_X_RIGHT:
return "STICK_X_RIGHT";
case Button::A_BUTTON:
return "A_BUTTON";
case Button::B_BUTTON:
return "B_BUTTON";
case Button::Z_TRIG:
return "Z_TRIG";
case Button::U_CBUTTONS:
return "U_CBUTTONS";
case Button::L_CBUTTONS:
return "L_CBUTTONS";
case Button::D_CBUTTONS:
return "D_CBUTTONS";
case Button::R_CBUTTONS:
return "R_CBUTTONS";
case Button::R_TRIG:
return "R_TRIG";
case Button::L_TRIG:
return "L_TRIG";
case Button::START_BUTTON:
return "START_BUTTON";
case Button::WALK_BUTTON:
return "WALK_BUTTON";
if(input == "STICK_X_UP")
return Button::STICK_X_UP;
if(input == "STICK_X_LEFT")
return Button::STICK_X_LEFT;
if(input == "STICK_X_DOWN")
return Button::STICK_X_DOWN;
if(input == "STICK_X_RIGHT")
return Button::STICK_X_RIGHT;
if(input == "A_BUTTON")
return Button::A_BUTTON;
if(input == "B_BUTTON")
return Button::B_BUTTON;
if(input == "Z_TRIG")
return Button::Z_TRIG;
if(input == "U_CBUTTONS")
return Button::U_CBUTTONS;
if(input == "L_CBUTTONS")
return Button::L_CBUTTONS;
if(input == "D_CBUTTONS")
return Button::D_CBUTTONS;
if(input == "R_CBUTTONS")
return Button::R_CBUTTONS;
if(input == "R_TRIG")
return Button::R_TRIG;
if(input == "L_TRIG")
return Button::L_TRIG;
if(input == "START_BUTTON")
return Button::START_BUTTON;
if(input == "WALK_BUTTON")
return Button::WALK_BUTTON;
case Button::OCARINA:
return "OCARINA";
case Button::HOOKSHOT:
return "HOOKSHOT";
case Button::BOW_ARROW:
return "BOW_ARROW";
case Button::LENS_OF_TRUTH:
return "LENS_OF_TRUTH";
case Button::BOOTS_TOGGLE:
return "BOOTS_TOGGLE";
case Button::SWORD_TOGGLE:
return "SWORD_TOGGLE";
case Button::SHIELD_TOGGLE:
return "SHIELD_TOGGLE";
case Button::TUNIC_TOGGLE:
return "TUNIC_TOGGLE";
if(input == "OCARINA")
return Button::OCARINA;
if(input == "HOOKSHOT")
return Button::HOOKSHOT;
if(input == "BOW_ARROW")
return Button::BOW_ARROW;
if(input == "LENS_OF_TRUTH")
return Button::LENS_OF_TRUTH;
if(input == "BOOTS_TOGGLE")
return Button::BOOTS_TOGGLE;
if(input == "SWORD_TOGGLE")
return Button::SWORD_TOGGLE;
if(input == "SHIELD_TOGGLE")
return Button::SHIELD_TOGGLE;
if(input == "TUNIC_TOGGLE")
return Button::TUNIC_TOGGLE;
return (Button)0;
}
return "";
}
Button getInputValue(const std::string& input)
{
if(input == "STICK_X_UP")
return Button::STICK_X_UP;
if(input == "STICK_X_LEFT")
return Button::STICK_X_LEFT;
if(input == "STICK_X_DOWN")
return Button::STICK_X_DOWN;
if(input == "STICK_X_RIGHT")
return Button::STICK_X_RIGHT;
if(input == "A_BUTTON")
return Button::A_BUTTON;
if(input == "B_BUTTON")
return Button::B_BUTTON;
if(input == "Z_TRIG")
return Button::Z_TRIG;
if(input == "U_CBUTTONS")
return Button::U_CBUTTONS;
if(input == "L_CBUTTONS")
return Button::L_CBUTTONS;
if(input == "D_CBUTTONS")
return Button::D_CBUTTONS;
if(input == "R_CBUTTONS")
return Button::R_CBUTTONS;
if(input == "R_TRIG")
return Button::R_TRIG;
if(input == "L_TRIG")
return Button::L_TRIG;
if(input == "START_BUTTON")
return Button::START_BUTTON;
if(input == "WALK_BUTTON")
return Button::WALK_BUTTON;
class Keyboard : public Controller
{
public:
Keyboard() : Controller()
{
memset(m_lastKeyState, 0, sizeof(m_lastKeyState));
m_keyBindings[SDL_SCANCODE_W] = Button::STICK_X_UP;
m_keyBindings[SDL_SCANCODE_A] = Button::STICK_X_LEFT;
m_keyBindings[SDL_SCANCODE_S] = Button::STICK_X_DOWN;
m_keyBindings[SDL_SCANCODE_D] = Button::STICK_X_RIGHT;
m_keyBindings[SDL_SCANCODE_SPACE] = Button::A_BUTTON;
m_keyBindings[SDL_SCANCODE_F] = Button::B_BUTTON;
m_keyBindings[SDL_SCANCODE_O] = Button::A_BUTTON;
m_keyBindings[SDL_SCANCODE_P] = Button::B_BUTTON;
m_keyBindings[SDL_SCANCODE_LSHIFT] = Button::Z_TRIG;
m_keyBindings[SDL_SCANCODE_C] = Button::Z_TRIG;
m_keyBindings[SDL_SCANCODE_I] = Button::U_JPAD;
m_keyBindings[SDL_SCANCODE_J] = Button::L_JPAD;
m_keyBindings[SDL_SCANCODE_K] = Button::D_JPAD;
m_keyBindings[SDL_SCANCODE_L] = Button::R_JPAD;
m_keyBindings[SDL_SCANCODE_UP] = Button::U_CBUTTONS;
m_keyBindings[SDL_SCANCODE_LEFT] = Button::L_CBUTTONS;
m_keyBindings[SDL_SCANCODE_DOWN] = Button::D_CBUTTONS;
m_keyBindings[SDL_SCANCODE_RIGHT] = Button::R_CBUTTONS;
m_keyBindings[SDL_SCANCODE_X] = Button::L_TRIG;
m_keyBindings[SDL_SCANCODE_V] = Button::R_TRIG;
m_keyBindings[SDL_SCANCODE_RSHIFT] = Button::R_TRIG;
m_keyBindings[SDL_SCANCODE_RETURN] = Button::START_BUTTON;
if(input == "OCARINA")
return Button::OCARINA;
if(input == "HOOKSHOT")
return Button::HOOKSHOT;
if(input == "BOW_ARROW")
return Button::BOW_ARROW;
if(input == "LENS_OF_TRUTH")
return Button::LENS_OF_TRUTH;
if(input == "BOOTS_TOGGLE")
return Button::BOOTS_TOGGLE;
if(input == "SWORD_TOGGLE")
return Button::SWORD_TOGGLE;
if(input == "SHIELD_TOGGLE")
return Button::SHIELD_TOGGLE;
if(input == "TUNIC_TOGGLE")
return Button::TUNIC_TOGGLE;
return (Button)0;
}
Keyboard::Keyboard() : Controller()
{
memset(m_lastKeyState, 0, sizeof(m_lastKeyState));
m_keyBindings[SDL_SCANCODE_W] = Button::STICK_X_UP;
m_keyBindings[SDL_SCANCODE_A] = Button::STICK_X_LEFT;
m_keyBindings[SDL_SCANCODE_S] = Button::STICK_X_DOWN;
m_keyBindings[SDL_SCANCODE_D] = Button::STICK_X_RIGHT;
m_keyBindings[SDL_SCANCODE_SPACE] = Button::A_BUTTON;
m_keyBindings[SDL_SCANCODE_F] = Button::B_BUTTON;
m_keyBindings[SDL_SCANCODE_O] = Button::A_BUTTON;
m_keyBindings[SDL_SCANCODE_P] = Button::B_BUTTON;
m_keyBindings[SDL_SCANCODE_LSHIFT] = Button::Z_TRIG;
m_keyBindings[SDL_SCANCODE_C] = Button::Z_TRIG;
m_keyBindings[SDL_SCANCODE_I] = Button::U_JPAD;
m_keyBindings[SDL_SCANCODE_J] = Button::L_JPAD;
m_keyBindings[SDL_SCANCODE_K] = Button::D_JPAD;
m_keyBindings[SDL_SCANCODE_L] = Button::R_JPAD;
m_keyBindings[SDL_SCANCODE_UP] = Button::U_CBUTTONS;
m_keyBindings[SDL_SCANCODE_LEFT] = Button::L_CBUTTONS;
m_keyBindings[SDL_SCANCODE_DOWN] = Button::D_CBUTTONS;
m_keyBindings[SDL_SCANCODE_RIGHT] = Button::R_CBUTTONS;
m_keyBindings[SDL_SCANCODE_X] = Button::L_TRIG;
m_keyBindings[SDL_SCANCODE_V] = Button::R_TRIG;
m_keyBindings[SDL_SCANCODE_RSHIFT] = Button::R_TRIG;
m_keyBindings[SDL_SCANCODE_RETURN] = Button::START_BUTTON;
m_keyBindings[SDL_SCANCODE_F1] = Button::BOOTS_TOGGLE;
m_keyBindings[SDL_SCANCODE_F2] = Button::SWORD_TOGGLE;
m_keyBindings[SDL_SCANCODE_F3] = Button::SHIELD_TOGGLE;
m_keyBindings[SDL_SCANCODE_F4] = Button::TUNIC_TOGGLE;
m_keyBindings[SDL_SCANCODE_F1] = Button::BOOTS_TOGGLE;
m_keyBindings[SDL_SCANCODE_F2] = Button::SWORD_TOGGLE;
m_keyBindings[SDL_SCANCODE_F3] = Button::SHIELD_TOGGLE;
m_keyBindings[SDL_SCANCODE_F4] = Button::TUNIC_TOGGLE;
#ifndef __SWITCH__
loadKeyBindings();
loadKeyBindings();
#endif
}
}
void Keyboard::loadKeyBindings()
{
try
{
std::ifstream ifs("keyboard1.bindings.json", std::ifstream::in);
if(ifs.is_open())
void resetBindings() override
{
rapidjson::IStreamWrapper isw(ifs);
rapidjson::Document d;
d.ParseStream(isw);
m_keyBindings.clear();
m_keyBindings[SDL_SCANCODE_W] = Button::STICK_X_UP;
m_keyBindings[SDL_SCANCODE_A] = Button::STICK_X_LEFT;
m_keyBindings[SDL_SCANCODE_S] = Button::STICK_X_DOWN;
m_keyBindings[SDL_SCANCODE_D] = Button::STICK_X_RIGHT;
m_keyBindings[SDL_SCANCODE_SPACE] = Button::A_BUTTON;
m_keyBindings[SDL_SCANCODE_F] = Button::B_BUTTON;
m_keyBindings[SDL_SCANCODE_O] = Button::A_BUTTON;
m_keyBindings[SDL_SCANCODE_P] = Button::B_BUTTON;
m_keyBindings[SDL_SCANCODE_LSHIFT] = Button::Z_TRIG;
m_keyBindings[SDL_SCANCODE_C] = Button::Z_TRIG;
m_keyBindings[SDL_SCANCODE_I] = Button::U_JPAD;
m_keyBindings[SDL_SCANCODE_J] = Button::L_JPAD;
m_keyBindings[SDL_SCANCODE_K] = Button::D_JPAD;
m_keyBindings[SDL_SCANCODE_L] = Button::R_JPAD;
m_keyBindings[SDL_SCANCODE_UP] = Button::U_CBUTTONS;
m_keyBindings[SDL_SCANCODE_LEFT] = Button::L_CBUTTONS;
m_keyBindings[SDL_SCANCODE_DOWN] = Button::D_CBUTTONS;
m_keyBindings[SDL_SCANCODE_RIGHT] = Button::R_CBUTTONS;
m_keyBindings[SDL_SCANCODE_X] = Button::L_TRIG;
m_keyBindings[SDL_SCANCODE_V] = Button::R_TRIG;
m_keyBindings[SDL_SCANCODE_RSHIFT] = Button::R_TRIG;
m_keyBindings[SDL_SCANCODE_RETURN] = Button::START_BUTTON;
if(d.IsObject())
m_keyBindings[SDL_SCANCODE_F1] = Button::BOOTS_TOGGLE;
m_keyBindings[SDL_SCANCODE_F2] = Button::SWORD_TOGGLE;
m_keyBindings[SDL_SCANCODE_F3] = Button::SHIELD_TOGGLE;
m_keyBindings[SDL_SCANCODE_F4] = Button::TUNIC_TOGGLE;
}
void loadKeyBindings()
{
try
{
for(auto itr = d.MemberBegin(); itr != d.MemberEnd(); ++itr)
{
if(itr->name.IsString() && itr->value.IsString())
{
auto key = SDL_GetScancodeFromName(itr->name.GetString());
auto value = getInputValue(itr->value.GetString());
std::ifstream ifs("keyboard1.bindings.json", std::ifstream::in);
if(key != SDL_SCANCODE_UNKNOWN && value != Button::NONE)
if(ifs.is_open())
{
rapidjson::IStreamWrapper isw(ifs);
rapidjson::Document d;
d.ParseStream(isw);
if(d.IsObject())
{
for(auto itr = d.MemberBegin(); itr != d.MemberEnd(); ++itr)
{
m_keyBindings[key] = value;
if(itr->name.IsString() && itr->value.IsString())
{
auto key = SDL_GetScancodeFromName(itr->name.GetString());
auto value = getInputValue(itr->value.GetString());
if(key != SDL_SCANCODE_UNKNOWN && value)
{
m_keyBindings[key] = value;
}
else
{
// TODO FIX oot::log("could not bind key: \"%s\" -> \"%s\"\n", itr->value.GetString(), itr->name.GetString());
}
}
}
}
}
}
catch(...)
{
}
}
void saveKeyBindings()
{
#ifdef ENABLE_JSON
try
{
rapidjson::Document d;
d.SetObject();
rapidjson::Document::AllocatorType& allocator = d.GetAllocator();
for(const auto i : m_keyBindings)
{
rapidjson::Value value(getInputName(i.second), allocator);
rapidjson::Value key(SDL_GetScancodeName(i.first), allocator);
d.AddMember(key, value, allocator);
}
saveJson(d, "keyboard1.bindings.json");
}
catch(...)
{
}
#endif
}
void clearRebindMode()
{
}
void resetRebinds()
{
}
bool hasMouse() const
{
return true;
return m_state.has_mouse;
}
int keyboard_buttons_down;
int keyboard_map_scancode(SDL_Scancode scancode)
{
if(m_keyBindings.count(scancode))
{
return m_keyBindings[scancode];
}
return 0;
}
bool on_key_down(SDL_Scancode scancode)
{
int mapped = keyboard_map_scancode(scancode);
keyboard_buttons_down |= mapped;
return mapped != 0;
}
bool on_key_up(SDL_Scancode scancode)
{
int mapped = keyboard_map_scancode(scancode);
keyboard_buttons_down &= ~mapped;
return mapped != 0;
}
void on_all_keys_up()
{
keyboard_buttons_down = 0;
}
void enableMouse()
{
this->state().has_mouse = true;
}
bool canRebind(SDL_Scancode scancode, int input)
{
if(m_keyBindings.count(scancode) == 0)
{
return true;
}
auto replacingInput = m_keyBindings[scancode];
u64 count = 0;
for(auto i : m_keyBindings)
{
if(i.second == replacingInput)
{
count++;
}
}
return count != 1;
}
bool updateRebind(int input) override
{
int count = 0;
auto state = SDL_GetKeyboardState(&count);
u64 changed = 0;
for(int i = 0; i < std::min(MAX_KEY_STATE, count); i++)
{
m_lastKeyState[i] = (state[i] ^ m_lastKeyState[i]) & state[i];
}
for(int i = 0; i < std::min(MAX_KEY_STATE, count); i++)
{
if(m_lastKeyState[i] && canRebind((SDL_Scancode)i, input))
{
m_keyBindings[(SDL_Scancode)i] = input;
changed++;
saveKeyBindings();
}
}
memcpy(m_lastKeyState, state, std::min(MAX_KEY_STATE, count));
return changed != 0;
}
void update()
{
bool walk = false;
int count = 0;
auto state = SDL_GetKeyboardState(&count);
if(state[SDL_SCANCODE_F10] && (m_lastKeyState[SDL_SCANCODE_F10] ^ state[SDL_SCANCODE_F10]))
{
oot::config().game().fullscreen() = !oot::config().game().fullscreen();
set_fullscreen(oot::config().game().fullscreen());
}
if(state[SDL_SCANCODE_ESCAPE] && (m_lastKeyState[SDL_SCANCODE_ESCAPE] ^ state[SDL_SCANCODE_ESCAPE]))
{
if(oot::config().game().fullscreen())
{
oot::config().game().fullscreen() = false;
set_fullscreen(oot::config().game().fullscreen());
}
}
if(hid::isTasPlaying())
{
return;
}
for(const auto& [scancode, input] : m_keyBindings)
{
if(scancode < count)
{
if(state[scancode])
{
if(input > 0xFFFF)
{
switch(input)
{
case STICK_X_DOWN:
m_state.stick_y = -128;
break;
case STICK_X_UP:
m_state.stick_y = 127;
break;
case STICK_X_LEFT:
m_state.stick_x = -128;
break;
case STICK_X_RIGHT:
m_state.stick_x = 127;
break;
case WALK_BUTTON:
walk = true;
break;
}
if((u32)input >= (u32)Button::OCARINA && (u32)input <= (u32)Button::TUNIC_TOGGLE)
{
if(!m_lastKeyState[scancode])
{
switch(input)
{
case Button::OCARINA:
Player_EquipOcarina();
break;
case Button::BOW_ARROW:
Player_EquipBow();
break;
case Button::LENS_OF_TRUTH:
Player_EquipLensOfTruth();
break;
case Button::BOOTS_TOGGLE:
Player_ToggleBoots();
break;
case Button::SWORD_TOGGLE:
Player_ToggleSword();
break;
case Button::SHIELD_TOGGLE:
Player_ToggleShield();
break;
case Button::TUNIC_TOGGLE:
Player_ToggleTunic();
break;
}
}
}
}
else
{
// TODO FIX sm64::log("could not bind key: \"%s\" -> \"%s\"\n", itr->value.GetString(), itr->name.GetString());
this->state().button |= input;
}
}
}
}
}
else
{
#ifndef __SWITCH__
saveKeyBindings(); // create default bindings file
#endif
}
}
catch(...)
{
}
}
void Keyboard::saveKeyBindings()
{
try
{
rapidjson::Document d;
d.SetObject();
rapidjson::Document::AllocatorType& allocator = d.GetAllocator();
for(const auto i : m_keyBindings)
{
rapidjson::Value value(getInputName(i.second), allocator);
rapidjson::Value key(SDL_GetScancodeName(i.first), allocator);
d.AddMember(key, value, allocator);
}
saveJson(d, "keyboard1.bindings.json");
}
catch(...)
{
}
}
bool Keyboard::hasMouse() const
{
return true;
return m_state.has_mouse;
}
Button Keyboard::keyboard_map_scancode(SDL_Scancode scancode)
{
if(m_keyBindings.count(scancode))
return m_keyBindings[scancode];
return Button::NONE;
}
bool Keyboard::on_key_down(SDL_Scancode scancode)
{
Button mapped = keyboard_map_scancode(scancode);
keyboard_buttons_down |= (int)mapped;
return (int)mapped != 0;
}
bool Keyboard::on_key_up(SDL_Scancode scancode)
{
Button mapped = keyboard_map_scancode(scancode);
keyboard_buttons_down &= ~(int)mapped;
return (int)mapped != 0;
}
bool Keyboard::canRebind(SDL_Scancode scancode, Button input)
{
if(m_keyBindings.count(scancode) == 0)
return true;
auto replacingInput = m_keyBindings[scancode];
u64 count = 0;
for(auto i : m_keyBindings)
{
if(i.second == replacingInput)
count++;
}
return count != 1;
}
bool Keyboard::updateRebind(Button input)
{
int count = 0;
auto state = SDL_GetKeyboardState(&count);
u64 changed = 0;
for(int i = 0; i < std::min(MAX_KEY_STATE, count); i++)
m_lastKeyState[i] = (state[i] ^ m_lastKeyState[i]) & state[i];
for(int i = 0; i < std::min(MAX_KEY_STATE, count); i++)
{
if(m_lastKeyState[i] && canRebind((SDL_Scancode)i, input))
{
m_keyBindings[(SDL_Scancode)i] = input;
changed++;
saveKeyBindings();
}
}
memcpy(m_lastKeyState, state, std::min(MAX_KEY_STATE, count));
return changed != 0;
}
void Keyboard::update()
{
bool walk = false;
int count = 0;
auto state = SDL_GetKeyboardState(&count);
if(state[SDL_SCANCODE_F10] && (m_lastKeyState[SDL_SCANCODE_F10] ^ state[SDL_SCANCODE_F10]))
{
oot::config().game().fullscreen() = !oot::config().game().fullscreen();
set_fullscreen(oot::config().game().fullscreen());
}
if(state[SDL_SCANCODE_F9] && (m_lastKeyState[SDL_SCANCODE_F9] ^ state[SDL_SCANCODE_F9]))
Set_Language(Get_Language() + 1);
if(state[SDL_SCANCODE_ESCAPE] && (m_lastKeyState[SDL_SCANCODE_ESCAPE] ^ state[SDL_SCANCODE_ESCAPE]))
{
if(oot::config().game().fullscreen())
{
oot::config().game().fullscreen() = false;
set_fullscreen(oot::config().game().fullscreen());
}
}
// When F5 is pressed. Mark all dpad button as pressed. Used to open map select
if(state[SDL_SCANCODE_F5] && (m_lastKeyState[SDL_SCANCODE_F5] ^ state[SDL_SCANCODE_F5]))
m_state.button |= (uint16_t)Button::U_JPAD | (uint16_t)Button::D_JPAD | (uint16_t)Button::L_JPAD | (uint16_t)Button::R_JPAD;
if(tas::isTasPlaying())
return;
for(const auto& [scancode, input] : m_keyBindings)
{
if(scancode < count && state[scancode])
{
if((uint32_t)input <= 0xFFFF)
{
m_state.button |= (uint32_t)input;
}
else if((u32)input >= (u32)Button::OCARINA && (u32)input <= (u32)Button::TUNIC_TOGGLE)
{
if(!m_lastKeyState[scancode])
{
switch(input)
{
case Button::OCARINA:
Player_EquipOcarina();
break;
case Button::BOW_ARROW:
Player_EquipBow();
break;
case Button::LENS_OF_TRUTH:
Player_EquipLensOfTruth();
break;
case Button::BOOTS_TOGGLE:
Player_ToggleBoots();
break;
case Button::SWORD_TOGGLE:
Player_ToggleSword();
break;
case Button::SHIELD_TOGGLE:
Player_ToggleShield();
break;
case Button::TUNIC_TOGGLE:
Player_ToggleTunic();
break;
}
}
}
else
{
switch(input)
{
case Button::STICK_X_DOWN:
m_state.stick_y = -128;
break;
case Button::STICK_X_UP:
m_state.stick_y = 127;
break;
case Button::STICK_X_LEFT:
m_state.stick_x = -128;
break;
case Button::STICK_X_RIGHT:
m_state.stick_x = 127;
break;
case Button::WALK_BUTTON:
walk = true;
break;
}
}
}
}
#ifdef ENABLE_MOUSE
int mouse_delta_x = 0;
int mouse_delta_y = 0;
int mouse_delta_x = 0;
int mouse_delta_y = 0;
auto buttons = SDL_GetRelativeMouseState(&mouse_delta_x, &mouse_delta_y);
enableMouse();
auto buttons = SDL_GetRelativeMouseState(&mouse_delta_x, &mouse_delta_y);
this->enableMouse();
if(buttons & SDL_BUTTON(SDL_BUTTON_LEFT))
m_state.button |= (uint16_t)Button::B_BUTTON;
if(buttons & SDL_BUTTON(SDL_BUTTON_LEFT))
{
m_state.button |= B_BUTTON;
}
if(buttons & SDL_BUTTON(SDL_BUTTON_RIGHT))
m_state.button |= (uint16_t)Button::A_BUTTON;
if(buttons & SDL_BUTTON(SDL_BUTTON_RIGHT))
{
m_state.button |= A_BUTTON;
}
if(buttons & SDL_BUTTON(SDL_BUTTON_MIDDLE))
walk = true;
if(buttons & SDL_BUTTON(SDL_BUTTON_MIDDLE))
{
walk = true;
}
m_state.mouse_x += mouse_delta_x * 4;
m_state.mouse_y += mouse_delta_y * 4;
m_state.mouse_x += mouse_delta_x * 4;
m_state.mouse_y += mouse_delta_y * 4;
if(mouse_delta_x > 10)
{
int yy = 0;
}
#endif
if(walk)
{
m_state.stick_x *= 0.25f;
m_state.stick_y *= 0.25f;
}
if(walk)
{
m_state.stick_x *= 0.25f;
m_state.stick_y *= 0.25f;
}
memcpy(m_lastKeyState, state, std::min(MAX_KEY_STATE, count));
}
memcpy(m_lastKeyState, state, std::min(MAX_KEY_STATE, count));
protected:
std::unordered_map<SDL_Scancode, int> m_keyBindings;
u8 m_lastKeyState[MAX_KEY_STATE];
};
} // namespace controller
Keyboard::Keyboard() : Driver()
{
}
void Keyboard::scan()
Keyboard::~Keyboard()
{
}
void Keyboard::scan(class Controllers* controllers)
{
if(!size())
{
#ifdef ENABLE_MOUSE
// SDL_SetRelativeMouseMode(SDL_TRUE);
#endif
auto controller = std::make_shared<Keyboard>();
auto controller = std::make_shared<controller::Keyboard>();
#ifdef ENABLE_MOUSE
controller->enableMouse();
#endif
m_controllers.push_back(controller);
Players::get().attach(controller, 0);
players().attach(controller, 0);
}
}
/*void Keyboard::update()
void Keyboard::update()
{
for (auto& keyboard : m_controllers)
((Keyboard*)keyboard.get())->update();
}*/
} // namespace oot::hid
for(auto& keyboard : m_controllers)
{
((controller::Keyboard*)keyboard.get())->update();
}
}
void Keyboard::resetBindings()
{
for(auto& keyboard : m_controllers)
{
keyboard->resetBindings();
}
}
} // namespace oot::hid

View File

@ -1,51 +1,23 @@
#pragma once
#include <SDL2/SDL.h>
#include <unordered_map>
#include <string>
#include "controllers.h"
#define MAX_KEY_STATE (16*1024)
#define MAX_KEY_STATE (16 * 1024)
namespace oot
namespace oot::hid
{
namespace hid
class Keyboard : public Driver
{
class Keyboard : public Controller, public Device
{
public:
Keyboard();
virtual ~Keyboard() {}
void scan();
void update() override;
bool defaultOnly() override { return true; }
bool updateRebind(Button input) override;
Keyboard();
virtual ~Keyboard();
void scan(class Controllers* controllers) override;
void update() override;
void resetBindings() override;
bool defaultOnly() override
{
return true;
}
void clearRebindMode() {}
void resetRebinds() {}
bool hasMouse() const;
void enableMouse() { state().has_mouse = true; }
bool canRebind(SDL_Scancode scancode, Button input);
Button keyboard_map_scancode(SDL_Scancode scancode);
bool on_key_down(SDL_Scancode scancode);
bool on_key_up(SDL_Scancode scancode);
void on_all_keys_up() { keyboard_buttons_down = 0; }
void loadKeyBindings();
void saveKeyBindings();
int keyboard_buttons_down;
private:
std::unordered_map<SDL_Scancode, Button> m_keyBindings;
u8 m_lastKeyState[MAX_KEY_STATE];
};
const char* getInputName(Button input);
Button getInputValue(const std::string& input);
}
}
protected:
};
} // namespace oot::hid

File diff suppressed because it is too large Load Diff

View File

@ -1,69 +1,17 @@
#pragma once
#include <string>
#include <unordered_map>
#include <SDL2/SDL.h>
#include "controllers.h"
#include "xcontroller.h"
namespace oot
namespace oot::hid
{
namespace hid
class SDL : public Driver
{
class Joypad : public Controller, public Device
{
public:
Joypad();
virtual ~Joypad();
SDL();
virtual ~SDL();
void scan(class Controllers* controllers) override;
void resetBindings() override;
virtual void scan() override;
void loadKeyBindings();
void saveKeyBindings();
void ResetMotorPack() override;
void SendMotorVib(int level) override;
static inline int8_t convertToByte(int value, int max);
static inline int8_t invert(const int8_t value);
inline int8_t stickLeftX();
inline int8_t stickLeftY();
inline int8_t stickRightX();
inline int8_t stickRightY();
bool canRebind(SDL_GameControllerButton button, Button input);
bool updateRebind(Button input) override;
void update() override;
private:
//Old haptics
bool initHaptics();
void closeHaptics();
void SendMotorEvent(short time, short level) override;
void SendMotorDecay(short level) override {};
//New haptics
void onVibrate(uint8_t strength, uint8_t time, uint8_t decay);//Called from the game
void updateVibration();//Called every frame in update()
SDL_GameController* m_context = nullptr;
SDL_Haptic* m_haptic = nullptr;
std::unordered_map<SDL_GameControllerButton, Button> m_keyBindings;
u8 m_buttonState[SDL_CONTROLLER_BUTTON_MAX];
u8 m_lastButtonState[SDL_CONTROLLER_BUTTON_MAX];
//Haptics
XController xinput;
uint32_t m_VibrationEnds = 0;//Timestamp when the current vibration should end
int32_t m_VibrationStrength = 0;//Strength of the last vibration
int32_t m_VibrationDecay = 0;
};
}
}
protected:
};
} // namespace oot::hid

View File

@ -2,116 +2,74 @@
#include <stdio.h>
#include "../player/players.h"
#include "../options.h"
#include "tas.h"
static u64 g_counter = 0;
static bool g_tasPlaying = false;
using namespace oot::hid::tas;
bool g_tasPlaying = false;
bool g_tasEnded = false;
std::string g_tasFilename;
bool oot::hid::tas::isTasPlaying()
namespace oot::hid
{
return g_tasPlaying;
}
bool isTasPlaying()
{
return g_tasPlaying;
}
void oot::hid::tas::playTas(bool enable)
{
g_tasPlaying = enable;
}
namespace controller
{
class Tas : public Controller
{
public:
Tas() : Controller()
{
fp = fopen("cont.tas", "rb");
void oot::hid::tas::setTasFileName(const std::string& newFilename)
{
g_tasFilename = newFilename;
}
if(fp != NULL)
{
fread(&oot::config(), 1, sizeof(oot::config()), fp);
g_tasPlaying = true;
}
}
std::string oot::hid::tas::getTasFileName()
{
if (g_tasFilename.empty())
g_tasFilename = "last-run.tas";
return g_tasFilename;
/*std::error_code error;
std::filesystem::create_directory(TAS_DIR, error);
virtual ~Tas()
{
if(fp)
{
fclose(fp);
}
}
time_t now = time(0);
tm* ltm = localtime(&now);
void update()
{
if(fp != NULL)
{
auto r = fread(&m_state, 1, sizeof(m_state), fp);
if (m_state.button)
{
int x = 0;
}
}
}
if (!ltm)
return TAS_DIR"/record.tas";
protected:
FILE* fp;
};
} // namespace controller
char buf[64] = { 0 };
sprintf(buf, TAS_DIR"/%04d.%02d.%02d-%04d.tas", ltm->tm_year, ltm->tm_mon + 1, ltm->tm_mday, ltm->tm_hour * 60 + ltm->tm_min);
return buf;*/
}
Tas::Tas() : Driver()
{
}
void oot::hid::tas::TasEnded()
{
g_tasEnded = true;
}
Tas::~Tas()
{
}
bool oot::hid::tas::hasTasEnded()
{
return g_tasEnded;
}
void Tas::scan(class Controllers* controllers)
{
if(!size())
{
auto controller = std::make_shared<controller::Tas>();
m_controllers.push_back(controller);
players().attach(controller, 0);
}
}
/*namespace controller
{
class Tas : public Controller
{
public:
Tas() : Controller()
{
fp = fopen("cont.tas", "rb");
if(fp != NULL)
{
fread(&oot::config(), 1, sizeof(oot::config()), fp);
g_tasPlaying = true;
}
}
virtual ~Tas()
{
if(fp)
{
fclose(fp);
}
}
void update()
{
if(fp != NULL)
{
auto r = fread(&m_state, 1, sizeof(m_state), fp);
if (m_state.button)
{
int x = 0;
}
}
}
protected:
FILE* fp;
};
} // namespace controller
Tas::Tas() : Driver()
{
}
Tas::~Tas()
{
}
void Tas::scan(class Controllers* controllers)
{
if (!size())
{
auto controller = std::make_shared<controller::Tas>();
m_controllers.push_back(controller);
players().attach(controller, 0);
}
}*/
} // namespace oot::hid

View File

@ -1,19 +1,15 @@
#pragma once
#include <string>
#include "controllers.h"
namespace oot::hid
{
namespace tas
{
bool isTasPlaying();
void playTas(bool enable);
class Tas : public Driver
{
public:
Tas();
virtual ~Tas();
void scan(class Controllers* controllers) override;
std::string getTasFileName();
void setTasFileName(const std::string& newFilename);
void TasEnded();//Called when the TAS has ended (end of file of .tas file reached)
bool hasTasEnded();//Returns true when playback was complete
}
}
protected:
};
} // namespace oot::hid

View File

@ -141,14 +141,14 @@ void ParseCommandLineArguments(const std::vector<std::string>& commands)
auto& cmd = commands[i];
size_left--;
if (cmd == "-tas" && size_left > 0)
/*if (cmd == "-tas" && size_left > 0) TODO FIX
{
auto tas_filename = std::move(commands[++i]);
oot::hid::tas::setTasFileName(tas_filename);
oot::hid::tas::playTas(true);
}
else if (cmd == "-no-graphics")
else*/ if (cmd == "-no-graphics")
oot::config().game().disableGraphics();
else if (cmd == "-fast-forward")

View File

@ -164,8 +164,8 @@ void main_func(void)
#ifdef _DEBUG//Record TAS to capture bugs and crashes
//oot::hid::tas::playTas(true);//Uncomment to play back TAS/crash report from end-users
if (!oot::hid::tas::isTasPlaying())
oot::config().game().recordTas(true);
/*if (!oot::hid::tas::isTasPlaying()) TODO FIX
oot::config().game().recordTas(true);*/
#endif
if (!oot::config().game().isGraphicsDisabled())
@ -180,7 +180,7 @@ void main_func(void)
if (!oot::config().game().isGraphicsDisabled())
gWindow->resize(-1, -1);
oot::hid::InputDeviceManager::get().scan();
oot::hid::controllers().scan();
inited = 1;

View File

@ -1,46 +1,80 @@
#include "player.h"
#include "../options.h"
using namespace oot::hid;
void Player::attach(const std::shared_ptr<Controller>& controller)
namespace oot
{
m_controllers.push_back(controller);
}
void Player::update()
{
m_controller.state().reset();
if (isRebindMode())
Player::Player() : m_rebindInput(0)
{
bool result = false;
//for (auto& controller : m_controllers)
//result |= controller->updateRebind(m_rebindInput);
if (result)
m_rebindInput = -10;
}
else if (m_rebindInput < 0)
m_rebindInput++;
else
Player::~Player()
{
for (auto& controller : m_controllers)
}
void Player::attach(const std::shared_ptr<hid::Controller>& controller)
{
m_controllers.push_back(controller);
}
void Player::detachControllers()
{
m_controllers.resize(0);
}
void Player::resetBindings()
{
for(auto& controller : m_controllers)
{
controller->state().reset();
controller->update();
m_controller.merge(*controller);
controller->resetBindings();
}
if (m_controllers.size() > 2 && !oot::config().game().forceMouse())
m_controller.state().has_mouse = false;
}
m_controller.resolveInputs();
}
void Player::update()
{
m_controller.state().reset();
if (isRebindMode())
{
bool result = 0;
for (auto& controller : m_controllers)
{
result |= controller->updateRebind(m_rebindInput);
}
if (result)
{
m_rebindInput = -10;
}
}
else if (m_rebindInput < 0)
{
m_rebindInput++;
}
else
{
for (auto& controller : m_controllers)
{
controller->state().reset();
controller->update();
m_controller.merge(*controller);
}
if (m_controllers.size() > 2 && !config().game().forceMouse())
{
m_controller.state().has_mouse = false;
}
}
m_controller.resolveInputs();
}
void Player::rebind(int input)
{
m_rebindInput = input;
}
bool Player::isRebindMode() const
{
return m_rebindInput > 0;
}
} // namespace oot

View File

@ -4,35 +4,34 @@
#include <vector>
#include <memory>
namespace oot
{
namespace hid
class Player
{
class Player
{
public:
Player() : m_rebindInput(0) {}
virtual ~Player() {}
Player();
virtual ~Player();
std::vector<std::shared_ptr<Controller> >& controllers() {
return m_controllers;
}
void attach(const std::shared_ptr<Controller>& controller);
void detachControllers() { m_controllers.resize(0); }
void update();
Controller& controller() {
return m_controller;
}
std::vector<std::shared_ptr<hid::Controller> >& controllers()
{
return m_controllers;
}
void resetBindings();
void attach(const std::shared_ptr<hid::Controller>& controller);
void detachControllers();
void update();
hid::Controller& controller()
{
return m_controller;
}
void rebind(int input) { m_rebindInput = input; }
bool isRebindMode() const { return m_rebindInput > 0; }
void rebind(int input);
bool isRebindMode() const;
protected:
std::vector<std::shared_ptr<Controller> > m_controllers;
Controller m_controller;
int m_rebindInput;
};
}
}
std::vector<std::shared_ptr<hid::Controller> > m_controllers;
hid::Controller m_controller;
int m_rebindInput;
};
} // namespace oot

View File

@ -1,68 +1,61 @@
#include <algorithm>
#include "players.h"
#include "../controller/controllers.h"
#include "../options.h"
#include "z64.h";
#include "padmgr.h"
extern PadMgr gPadMgr;
using namespace oot::hid;
Players g_players;
Players& Players::get()
namespace oot
{
return g_players;
}
Players g_players;
void Players::Update()
{
g_players.update();
}
const Controller* Players::GetController()
{
if (g_players[0].controllers().size() == 0)
return nullptr;
return g_players[0].controllers()[0].get();
}
void Players::update()
{
memset(&gPadMgr.ctrlrIsConnected[0], 0, sizeof(gPadMgr.ctrlrIsConnected));
int i = 0;
for (auto& player : m_players)
Players& players()
{
player.update();
gPadMgr.inputs[i].cur.button = player.controller().state().button;
gPadMgr.inputs[i].cur.stick_x = player.controller().state().stick_x;
gPadMgr.inputs[i].cur.stick_y = player.controller().state().stick_y;
gPadMgr.ctrlrIsConnected[i] = true;
i++;
return g_players;
}
gPadMgr.nControllers = i;
}
void Players::attach(const std::shared_ptr<Controller>& controller, const u8 playerId)
{
if (playerId == MAX_PLAYERS)
m_players[m_size++].attach(controller);
else
Player& player(const u64 i)
{
m_players[playerId].attach(controller);
m_size = std::max((u64)playerId + 1, m_size);
return g_players[i];
}
}
Players::Players() : m_players(), m_size(0)
{
}
const u64 Players::size() const
{
return m_size;
}
void Players::update()
{
int i = 0;
memset(&gPadMgr.ctrlrIsConnected[0], 0, sizeof(gPadMgr.ctrlrIsConnected));
for(auto& player : m_players)
{
player.update();
gPadMgr.inputs[i].cur.button = player.controller().state().button;
gPadMgr.inputs[i].cur.stick_x = player.controller().state().stick_x;
gPadMgr.inputs[i].cur.stick_y = player.controller().state().stick_y;
gPadMgr.ctrlrIsConnected[i] = true;
i++;
}
gPadMgr.nControllers = i;
}
void Players::attach(const std::shared_ptr<hid::Controller>& controller, const u8 playerId)
{
if(playerId == MAX_PLAYERS)
{
m_players[m_size++].attach(controller);
}
else
{
m_players[playerId].attach(controller);
m_size = std::max((u64)playerId + 1, m_size);
}
}
} // namespace oot

View File

@ -1,36 +1,30 @@
#pragma once
#include "ultra64/types.h"
#include <vector>
#include "player.h"
#include "../controller/sdl.h"
static const u8 MAX_PLAYERS = 0xFF;
#include <vector>
namespace oot
{
namespace hid
static const u8 MAX_PLAYERS = 0xFF;
class Players
{
class Players
{
public:
static const u32 MAX_PLAYERS = 1;
static const u32 MAX_PLAYERS = 1;
static Players& get();
static void Update();
static const Controller* GetController();
Players();
const u64 size() const;
void update();
Player& operator[](u32 i)
{
return m_players[i];
}
void attach(const std::shared_ptr<hid::Controller>& controller, const u8 playerId = MAX_PLAYERS);
Players() = default;
const u64 size() const { return m_size; }
void update();
void attach(const std::shared_ptr<Controller>& controller, const u8 playerId = MAX_PLAYERS);
protected:
Player m_players[MAX_PLAYERS];
u64 m_size;
};
Player& operator[](u32 i) { return m_players[i]; }
private:
Player m_players[MAX_PLAYERS];
u64 m_size = 0;
};
}
}
Players& players();
Player& player(const u64 i);
} // namespace oot

View File

@ -743,6 +743,7 @@
<ClCompile Include="..\src\overlays\gamestates\ovl_select\z_select.cpp" />
<ClCompile Include="..\src\overlays\gamestates\ovl_title\z_title.cpp" />
<ClCompile Include="..\src\overlays\misc\ovl_kaleido_scope\z_kaleido_collect.cpp" />
<ClCompile Include="..\src\overlays\misc\ovl_kaleido_scope\z_kaleido_controller.cpp" />
<ClCompile Include="..\src\overlays\misc\ovl_kaleido_scope\z_kaleido_debug.cpp" />
<ClCompile Include="..\src\overlays\misc\ovl_kaleido_scope\z_kaleido_equipment.cpp" />
<ClCompile Include="..\src\overlays\misc\ovl_kaleido_scope\z_kaleido_item.cpp" />

View File

@ -2190,6 +2190,9 @@
<ClCompile Include="..\src\port\controller\xcontroller.cpp">
<Filter>Source Files\port\controller</Filter>
</ClCompile>
<ClCompile Include="..\src\overlays\misc\ovl_kaleido_scope\z_kaleido_controller.cpp">
<Filter>Source Files\overlays\misc</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\include\segment_symbols.h">