mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-08-07 17:52:07 -04:00
Merge branch 'main' of https://www.github.com/TwilitRealm/dusklight into rando-mod
This commit is contained in:
+19
-8
@@ -209,8 +209,8 @@ if (svc_resource->load(mod_ctx, "config.txt", &buf) == MOD_OK) {
|
||||
}
|
||||
```
|
||||
|
||||
Missing files return `MOD_UNAVAILABLE`. Always `free` what you `load`. Note that the bundle is read-only; for writable
|
||||
storage, use the directory from `svc_host->mod_dir(mod_ctx)`.
|
||||
Missing files return `MOD_UNAVAILABLE`. Always `free` what you `load`. The bundle is read-only; use
|
||||
`HostService::data_dir` for persistent storage.
|
||||
|
||||
### HostService (`mods/svc/host.h`)
|
||||
|
||||
@@ -219,9 +219,17 @@ Mod metadata and runtime interaction with the loader:
|
||||
```cpp
|
||||
IMPORT_SERVICE(HostService, svc_host);
|
||||
|
||||
const char* id = svc_host->mod_id(mod_ctx);
|
||||
const char* dir = svc_host->mod_dir(mod_ctx); // writable per-mod directory
|
||||
svc_host->fail(mod_ctx, MOD_ERROR, "something unrecoverable happened"); // disables the mod
|
||||
// Temporary mod data directory, wiped on startup
|
||||
const char* cacheDir = svc_host->mod_dir(mod_ctx);
|
||||
|
||||
// Persistent mod data directory
|
||||
const char* dataDir = nullptr;
|
||||
if (svc_host->data_dir(mod_ctx, &dataDir) == MOD_OK) {
|
||||
// ...
|
||||
}
|
||||
|
||||
// Report an error and disable the mod
|
||||
svc_host->fail(mod_ctx, MOD_ERROR, "something unrecoverable happened");
|
||||
```
|
||||
|
||||
`get_service`/`publish_service` provide dynamic service lookup; see [Exporting Services](#exporting-services).
|
||||
@@ -625,6 +633,9 @@ if (svc_camera->get_camera(mod_ctx, game_view, &camera) == MOD_OK) {
|
||||
first in-game frame. Projection matrices match the renderer's WebGPU clip convention and renderer depth convention
|
||||
(reversed-Z by default).
|
||||
|
||||
Camera operators allow overriding the main camera. When an operator callback returns true, its values replace the camera
|
||||
state for the current frame. Register and unregister using `register_camera_operator` / `unregister_camera_operator`.
|
||||
|
||||
---
|
||||
|
||||
## Hooking Game Functions
|
||||
@@ -927,6 +938,6 @@ const char* nativeDir = svc_host->native_dir(mod_ctx); // read-only
|
||||
```
|
||||
|
||||
Libraries loaded explicitly by the mod remain its responsibility: stop their threads and unload them during
|
||||
`mod_shutdown`. Do not write into `native_dir`; use `mod_dir` for writable state. Native library namespaces are
|
||||
process-wide on some platforms, so two mods cannot safely assume that incompatible libraries with the same filename
|
||||
will remain isolated.
|
||||
`mod_shutdown`. Do not write into `native_dir`; use `data_dir` for persistent storage or `mod_dir` for temporary
|
||||
(session) storage. Native library namespaces are process-wide on some platforms, so two mods cannot safely assume that
|
||||
incompatible libraries with the same filename will remain isolated.
|
||||
|
||||
Vendored
+1
-1
Submodule extern/aurora updated: 5027ed63a7...8005d336ab
Vendored
+1
-1
Submodule extern/borealis updated: eec74b6dec...6fd955e7e6
@@ -130,8 +130,8 @@ private:
|
||||
}; // Size = 0x28
|
||||
|
||||
struct mDoDvdThdStack {
|
||||
u8 stack[4096];
|
||||
} ATTRIBUTE_ALIGN(16);
|
||||
ATTRIBUTE_ALIGN(16) u8 stack[4096];
|
||||
};
|
||||
|
||||
struct mDoDvdThd {
|
||||
static s32 main(void*);
|
||||
|
||||
@@ -23,9 +23,9 @@ DUSK_GAME_DATA Vec J3DSys::mParentS;
|
||||
DUSK_GAME_DATA J3DTexCoordScaleInfo J3DSys::sTexCoordScaleTable[8];
|
||||
|
||||
#if TARGET_PC // Original game bug, array is too small.
|
||||
static u8 NullTexData[0x20] ATTRIBUTE_ALIGN(32) = {0};
|
||||
ATTRIBUTE_ALIGN(32) static u8 NullTexData[0x20] = {0};
|
||||
#else
|
||||
static u8 NullTexData[0x10] ATTRIBUTE_ALIGN(32) = {0};
|
||||
ATTRIBUTE_ALIGN(32) static u8 NullTexData[0x10] = {0};
|
||||
#endif
|
||||
|
||||
static Mtx j3dIdentityMtx = {
|
||||
|
||||
@@ -99,14 +99,14 @@ void JASDsp::invalChannelAll() {
|
||||
DCInvalidateRange(CH_BUF, sizeof(TChannel) * DSP_CHANNELS);
|
||||
}
|
||||
|
||||
DUSK_GAME_DATA u8 const ATTRIBUTE_ALIGN(32) JASDsp::DSPADPCM_FILTER[64] = {
|
||||
ATTRIBUTE_ALIGN(32) DUSK_GAME_DATA u8 const JASDsp::DSPADPCM_FILTER[64] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x04, 0x00,
|
||||
0x10, 0x00, 0xF8, 0x00, 0x0E, 0x00, 0xFA, 0x00, 0x0C, 0x00, 0xFC, 0x00, 0x12, 0x00, 0xF6, 0x00,
|
||||
0x10, 0x68, 0xF7, 0x38, 0x12, 0xC0, 0xF7, 0x04, 0x14, 0x00, 0xF4, 0x00, 0x08, 0x00, 0xF8, 0x00,
|
||||
0x04, 0x00, 0xFC, 0x00, 0xFC, 0x00, 0x04, 0x00, 0xFC, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
DUSK_GAME_DATA u32 const ATTRIBUTE_ALIGN(32) JASDsp::DSPRES_FILTER[320] = {
|
||||
ATTRIBUTE_ALIGN(32) DUSK_GAME_DATA u32 const JASDsp::DSPRES_FILTER[320] = {
|
||||
0x0C3966AD,
|
||||
0x0D46FFDF,
|
||||
0x0B396696,
|
||||
|
||||
@@ -25,7 +25,7 @@ void DspHandShake(void*) {
|
||||
Dsp_Running_Start();
|
||||
}
|
||||
|
||||
static u8 jdsp[7936] ATTRIBUTE_ALIGN(32) = {
|
||||
ATTRIBUTE_ALIGN(32) static u8 jdsp[7936] = {
|
||||
0x02, 0x9F, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0x00, 0x00, 0x02, 0xFF, 0x00, 0x00,
|
||||
0x02, 0xFF, 0x00, 0x00, 0x02, 0xFF, 0x00, 0x00, 0x02, 0xFF, 0x00, 0x00, 0x02, 0x9F, 0x06, 0xA5,
|
||||
0x02, 0x9F, 0x00, 0x4E, 0x12, 0x05, 0x02, 0xBF, 0x00, 0x57, 0x81, 0x00, 0x00, 0x9F, 0x10, 0x00,
|
||||
@@ -524,9 +524,9 @@ static u8 jdsp[7936] ATTRIBUTE_ALIGN(32) = {
|
||||
0x80, 0x01, 0x02, 0xBF, 0x00, 0xF4, 0x02, 0xDF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
static DSPTaskInfo audio_task ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) static DSPTaskInfo audio_task;
|
||||
|
||||
static u8 AUDIO_YIELD_BUFFER[8192] ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) static u8 AUDIO_YIELD_BUFFER[8192];
|
||||
|
||||
void DspBoot(void (*requestCallback)(void*)) {
|
||||
DspInitWork();
|
||||
|
||||
@@ -452,13 +452,13 @@ static void dummy() {
|
||||
JUTXfb::getManager()->setDisplayingXfbIndex(0);
|
||||
}
|
||||
|
||||
static Mtx e_mtx ATTRIBUTE_ALIGN(32) = {
|
||||
ATTRIBUTE_ALIGN(32) static Mtx e_mtx = {
|
||||
{1.0f, 0.0f, 0.0f, 0.0f},
|
||||
{0.0f, 1.0f, 0.0f, 0.0f},
|
||||
{0.0f, 0.0f, 1.0f, 0.0f},
|
||||
};
|
||||
|
||||
static u8 clear_z_TX[64] ATTRIBUTE_ALIGN(32) = {
|
||||
ATTRIBUTE_ALIGN(32) static u8 clear_z_TX[64] = {
|
||||
0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF,
|
||||
0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
|
||||
@@ -16,10 +16,10 @@ inline f64 getConst2() {
|
||||
return 9.765625E-4;
|
||||
}
|
||||
|
||||
DUSK_GAME_DATA TSinCosTable<13, f32> sincosTable_ ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) DUSK_GAME_DATA TSinCosTable<13, f32> sincosTable_;
|
||||
|
||||
DUSK_GAME_DATA TAtanTable<1024, f32> atanTable_ ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) DUSK_GAME_DATA TAtanTable<1024, f32> atanTable_;
|
||||
|
||||
DUSK_GAME_DATA TAsinAcosTable<1024, f32> asinAcosTable_ ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) DUSK_GAME_DATA TAsinAcosTable<1024, f32> asinAcosTable_;
|
||||
|
||||
} // namespace JMath
|
||||
|
||||
@@ -46,7 +46,7 @@ JPAResource::JPAResource() {
|
||||
mUsrIdx = fldNum = keyNum = texNum = mpCalcEmitterFuncListNum = mpDrawEmitterFuncListNum = mpDrawEmitterChildFuncListNum = mpCalcParticleFuncListNum = mpDrawParticleFuncListNum = mpCalcParticleChildFuncListNum = mpDrawParticleChildFuncListNum = 0;
|
||||
}
|
||||
|
||||
static u8 jpa_pos[324] ATTRIBUTE_ALIGN(32) = {
|
||||
ATTRIBUTE_ALIGN(32) static u8 jpa_pos[324] = {
|
||||
0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x32, 0xCE, 0x00, 0x00, 0xCE, 0x00, 0xE7, 0x00, 0x00, 0x19,
|
||||
0x00, 0x00, 0x19, 0xCE, 0x00, 0xE7, 0xCE, 0x00, 0xCE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCE,
|
||||
0x00, 0xCE, 0xCE, 0x00, 0x00, 0x19, 0x00, 0x32, 0x19, 0x00, 0x32, 0xE7, 0x00, 0x00, 0xE7, 0x00,
|
||||
@@ -70,7 +70,7 @@ static u8 jpa_pos[324] ATTRIBUTE_ALIGN(32) = {
|
||||
0x00, 0x00, 0x00, 0xCE,
|
||||
};
|
||||
|
||||
static u8 jpa_crd[32] ATTRIBUTE_ALIGN(32) = {
|
||||
ATTRIBUTE_ALIGN(32) static u8 jpa_crd[32] = {
|
||||
0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x02, 0x01, 0x00, 0x01,
|
||||
0x00, 0x00, 0x01, 0x00, 0x01, 0x02, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x02, 0x02, 0x00, 0x02,
|
||||
};
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#endif
|
||||
#include "global.h"
|
||||
|
||||
DUSK_GAME_DATA u8 const JUTResFONT_Ascfont_fix12[] ATTRIBUTE_ALIGN(32) = {
|
||||
ATTRIBUTE_ALIGN(32) DUSK_GAME_DATA u8 const JUTResFONT_Ascfont_fix12[] = {
|
||||
0x46, 0x4F, 0x4E, 0x54, 0x62, 0x66, 0x6E, 0x31, 0x00, 0x00, 0x41, 0x60, 0x00, 0x00, 0x00, 0x04,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x49, 0x4E, 0x46, 0x31, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C,
|
||||
|
||||
@@ -136,7 +136,7 @@ void TRK__read_aram(__REGISTER int c, __REGISTER u32 p2, void* p3) {
|
||||
}
|
||||
|
||||
void TRK__write_aram(__REGISTER int c, __REGISTER u32 p2, void* p3) {
|
||||
u8 buff[32] ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) u8 buff[32];
|
||||
u32 err;
|
||||
__REGISTER int count = c;
|
||||
__REGISTER u32 bf;
|
||||
|
||||
@@ -85,7 +85,7 @@ DSError TRKDoSupportMask(TRKBuffer*) {
|
||||
}
|
||||
|
||||
DSError TRKDoReadMemory(TRKBuffer* buffer) {
|
||||
u8 buf[0x820] ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) u8 buf[0x820];
|
||||
size_t tempLength;
|
||||
int result;
|
||||
int replyErr;
|
||||
@@ -158,7 +158,7 @@ DSError TRKDoReadMemory(TRKBuffer* buffer) {
|
||||
}
|
||||
|
||||
DSError TRKDoWriteMemory(TRKBuffer* b) {
|
||||
u8 buf[0x820] ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) u8 buf[0x820];
|
||||
size_t tempLength;
|
||||
int options;
|
||||
int result;
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
|
||||
#include "__ax.h"
|
||||
|
||||
static s32 __AXBufferAuxA[3][480] ATTRIBUTE_ALIGN(32);
|
||||
static s32 __AXBufferAuxB[3][480] ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) static s32 __AXBufferAuxA[3][480];
|
||||
ATTRIBUTE_ALIGN(32) static s32 __AXBufferAuxB[3][480];
|
||||
|
||||
static void (* __AXCallbackAuxA)(void*, void*);
|
||||
static void (* __AXCallbackAuxB)(void*, void*);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "__ax.h"
|
||||
|
||||
static AXSPB __AXStudio ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) static AXSPB __AXStudio;
|
||||
|
||||
static s32 __AXSpbAL;
|
||||
static s32 __AXSpbAR;
|
||||
|
||||
@@ -35,9 +35,9 @@ static u32 __AXAuxMixCycles[32] = {
|
||||
0x000009E2, 0x00000E97
|
||||
};
|
||||
|
||||
static AXPB __AXPB[AX_MAX_VOICES] ATTRIBUTE_ALIGN(32);
|
||||
static AXPBITDBUFFER __AXITD[AX_MAX_VOICES] ATTRIBUTE_ALIGN(32);
|
||||
static AXPBU __AXUpdates[AX_MAX_VOICES] ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) static AXPB __AXPB[AX_MAX_VOICES];
|
||||
ATTRIBUTE_ALIGN(32) static AXPBITDBUFFER __AXITD[AX_MAX_VOICES];
|
||||
ATTRIBUTE_ALIGN(32) static AXPBU __AXUpdates[AX_MAX_VOICES];
|
||||
static AXVPB __AXVPB[AX_MAX_VOICES];
|
||||
|
||||
static u32 __AXMaxDspCycles;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
u16 axDspSlaveLength = (AX_DSP_SLAVE_LENGTH * 2);
|
||||
|
||||
u16 axDspSlave[AX_DSP_SLAVE_LENGTH] ATTRIBUTE_ALIGN(32) = {
|
||||
ATTRIBUTE_ALIGN(32) u16 axDspSlave[AX_DSP_SLAVE_LENGTH] = {
|
||||
0x0000, 0x0000, 0x029F, 0x0E88, 0x029F, 0x0E97,
|
||||
0x029F, 0x0EB3, 0x029F, 0x0ED3, 0x029F, 0x0ED9,
|
||||
0x029F, 0x0F0B, 0x029F, 0x0F11, 0x1302, 0x1303,
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#include "__card.h"
|
||||
|
||||
static u8 CardData[352] ATTRIBUTE_ALIGN(DOLPHIN_ALIGNMENT) = {
|
||||
ATTRIBUTE_ALIGN(DOLPHIN_ALIGNMENT) static u8 CardData[352] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x02, 0xFF, 0x00, 0x21, 0x13, 0x06, 0x12, 0x03, 0x12, 0x04,
|
||||
0x13, 0x05, 0x00, 0x92, 0x00, 0xFF, 0x00, 0x88, 0xFF, 0xFF, 0x00, 0x89, 0xFF, 0xFF, 0x00, 0x8A, 0xFF, 0xFF, 0x00,
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include <dolphin/demo.h>
|
||||
#include "sdk_math.h"
|
||||
|
||||
static s16 __AVX_internal_buffer[3200] ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) static s16 __AVX_internal_buffer[3200];
|
||||
|
||||
static void (*__AVX_save_isr)(void);
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <dolphin/dolphin.h>
|
||||
#include <dolphin/demo.h>
|
||||
|
||||
u32 DEMOFontBitmap[768] ATTRIBUTE_ALIGN(32) = {
|
||||
ATTRIBUTE_ALIGN(32) u32 DEMOFontBitmap[768] = {
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
|
||||
@@ -43,7 +43,7 @@ void* __piReg;
|
||||
GXBool __GXinBegin;
|
||||
#endif
|
||||
|
||||
static u16 DefaultTexData[] ATTRIBUTE_ALIGN(32) = {
|
||||
ATTRIBUTE_ALIGN(32) static u16 DefaultTexData[] = {
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
};
|
||||
|
||||
@@ -7,11 +7,11 @@ const char* __MCCVersion = "<< Dolphin SDK - MCC\tdebug build: Apr 5 2004 03:57
|
||||
const char* __MCCVersion = "<< Dolphin SDK - MCC\trelease build: Apr 5 2004 04:15:49 (0x2301) >>";
|
||||
#endif
|
||||
|
||||
static MCC_ChannelInfo gChannelInfo[16] ATTRIBUTE_ALIGN(32);
|
||||
static char gStreamWork[32] ATTRIBUTE_ALIGN(32);
|
||||
static char m_szAdapterMode[32] ATTRIBUTE_ALIGN(32);
|
||||
static char m_szInitCode[32] ATTRIBUTE_ALIGN(32);
|
||||
static MCC_Info channelInfo[16] ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) static MCC_ChannelInfo gChannelInfo[16];
|
||||
ATTRIBUTE_ALIGN(32) static char gStreamWork[32];
|
||||
ATTRIBUTE_ALIGN(32) static char m_szAdapterMode[32];
|
||||
ATTRIBUTE_ALIGN(32) static char m_szInitCode[32];
|
||||
ATTRIBUTE_ALIGN(32) static MCC_Info channelInfo[16];
|
||||
|
||||
volatile static BOOL gIsChannelinfoDirty = TRUE;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "__os.h"
|
||||
|
||||
static SramControl Scb ATTRIBUTE_ALIGN(DOLPHIN_ALIGNMENT);
|
||||
ATTRIBUTE_ALIGN(DOLPHIN_ALIGNMENT) static SramControl Scb;
|
||||
|
||||
// prototypes
|
||||
static int GetRTC(u32* rtc);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "__card.h"
|
||||
|
||||
static u8 CardData[352] ATTRIBUTE_ALIGN(DOLPHIN_ALIGNMENT) = {
|
||||
ATTRIBUTE_ALIGN(DOLPHIN_ALIGNMENT) static u8 CardData[352] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x02, 0xFF, 0x00, 0x21, 0x13, 0x06, 0x12, 0x03, 0x12, 0x04,
|
||||
0x13, 0x05, 0x00, 0x92, 0x00, 0xFF, 0x00, 0x88, 0xFF, 0xFF, 0x00, 0x89, 0xFF, 0xFF, 0x00, 0x8A, 0xFF, 0xFF, 0x00,
|
||||
|
||||
@@ -44,7 +44,7 @@ static u32 LastError;
|
||||
static BOOL ResetRequired;
|
||||
static u32 MotorState;
|
||||
static volatile OSTime LastResetEnd;
|
||||
static u32 __DVDNumTmdBytes ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) static u32 __DVDNumTmdBytes;
|
||||
static DVDGameTOC* GameToc;
|
||||
static DVDPartitionInfo* PartInfo;
|
||||
static DVDPartitionInfo* BootGameInfo;
|
||||
@@ -80,10 +80,10 @@ static DVDCommandBlock DummyCommandBlock;
|
||||
static OSAlarm ResetAlarm;
|
||||
static OSAlarm CoverAlarm;
|
||||
|
||||
static u8 __DVDGameTocBuffer[OSRoundUp32B(sizeof(DVDGameTOC) * 4)] ATTRIBUTE_ALIGN(32);
|
||||
static u8 __DVDPartInfoBuffer[OSRoundUp32B(sizeof(DVDPartitionInfo) * 4)] ATTRIBUTE_ALIGN(32);
|
||||
static u8 __DVDTmdBuffer[OSRoundUp32B(sizeof(ESTitleMeta))] ATTRIBUTE_ALIGN(32);
|
||||
static u8 __DVDTicketViewBuffer[OSRoundUp32B(sizeof(ESTicketView))] ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) static u8 __DVDGameTocBuffer[OSRoundUp32B(sizeof(DVDGameTOC) * 4)];
|
||||
ATTRIBUTE_ALIGN(32) static u8 __DVDPartInfoBuffer[OSRoundUp32B(sizeof(DVDPartitionInfo) * 4)];
|
||||
ATTRIBUTE_ALIGN(32) static u8 __DVDTmdBuffer[OSRoundUp32B(sizeof(ESTitleMeta))];
|
||||
ATTRIBUTE_ALIGN(32) static u8 __DVDTicketViewBuffer[OSRoundUp32B(sizeof(ESTicketView))];
|
||||
|
||||
static OSAlarm FatalAlarm;
|
||||
DVDCommandBlock __DVDStopMotorCommandBlock;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "__os.h"
|
||||
#include "__dvd.h"
|
||||
|
||||
static u8 CheckBuffer[32] ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) static u8 CheckBuffer[32];
|
||||
|
||||
static volatile BOOL lowDone = TRUE;
|
||||
static volatile u32 lowIntType = 0;
|
||||
|
||||
@@ -8,15 +8,15 @@ static volatile u8 requestInProgress = FALSE;
|
||||
static u8 breakRequested;
|
||||
static u8 callbackInProgress;
|
||||
|
||||
static u32 registerBuf[8] ATTRIBUTE_ALIGN(32);
|
||||
static u32 statusRegister[8] ATTRIBUTE_ALIGN(32);
|
||||
static u32 controlRegister[8] ATTRIBUTE_ALIGN(32);
|
||||
static s32 lastTicketError[8] ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) static u32 registerBuf[8];
|
||||
ATTRIBUTE_ALIGN(32) static u32 statusRegister[8];
|
||||
ATTRIBUTE_ALIGN(32) static u32 controlRegister[8];
|
||||
ATTRIBUTE_ALIGN(32) static s32 lastTicketError[8];
|
||||
|
||||
static u32 readLength;
|
||||
static u32 spinUpValue;
|
||||
|
||||
static diRegVals_t diRegValCache ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) static diRegVals_t diRegValCache;
|
||||
|
||||
static u8 DVDLowInitCalled = FALSE;
|
||||
|
||||
@@ -42,8 +42,8 @@ typedef struct dvdContext {
|
||||
|
||||
static int freeDvdContext = 0;
|
||||
static u8 dvdContextsInited = FALSE;
|
||||
static dvdContext_t dvdContexts[4] ATTRIBUTE_ALIGN(32);
|
||||
static IOSIoVector ioVec[10] ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) static dvdContext_t dvdContexts[4];
|
||||
ATTRIBUTE_ALIGN(32) static IOSIoVector ioVec[10];
|
||||
|
||||
static void* ddrAllocAligned32(const int size) {
|
||||
void* low, *high;
|
||||
|
||||
@@ -11,8 +11,8 @@ static NANDCommandBlock NandCb;
|
||||
static NANDFileInfo NandInfo;
|
||||
static DVDCBCallback Callback;
|
||||
static u32 NextOffset;
|
||||
DVDErrorInfo __ErrorInfo ATTRIBUTE_ALIGN(32);
|
||||
DVDErrorInfo __FirstErrorInfo ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) DVDErrorInfo __ErrorInfo;
|
||||
ATTRIBUTE_ALIGN(32) DVDErrorInfo __FirstErrorInfo;
|
||||
|
||||
void cbForNandClose(s32 result, NANDCommandBlock* block) {
|
||||
if (Callback) {
|
||||
|
||||
@@ -33,7 +33,7 @@ s32 ESP_CloseLib(void) {
|
||||
|
||||
s32 ESP_LaunchTitle(u64 titleID, ESTicketView* pTicketView) {
|
||||
s32 ret = 0;
|
||||
u8 buf[256] ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) u8 buf[256];
|
||||
IOSIoVector* vec = (IOSIoVector*)(buf + 208);
|
||||
u64* id = (u64*)buf;
|
||||
|
||||
@@ -63,7 +63,7 @@ out:
|
||||
|
||||
s32 ESP_GetTicketViews(ESTitleId titleId, ESTicketView* ticketViewList, u32* ticketViewCnt) {
|
||||
s32 rv = 0;
|
||||
u8 __esBuf[256] ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) u8 __esBuf[256];
|
||||
IOSIoVector* v = (IOSIoVector*)(__esBuf + 256 - 6 * sizeof(IOSIoVector));
|
||||
ESTitleId* p1 = (ESTitleId*)__esBuf;
|
||||
u32* p2 = (u32*)(__esBuf + 32);
|
||||
@@ -111,7 +111,7 @@ out:
|
||||
|
||||
s32 ESP_DiGetTicketView(const void* ticket, ESTicketView* ticketView) {
|
||||
s32 rv = 0;
|
||||
u8 __esBuf[256] ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) u8 __esBuf[256];
|
||||
IOSIoVector* v = (IOSIoVector*)(__esBuf + 256 - 6 * sizeof(IOSIoVector));
|
||||
|
||||
if (__esFd < 0 || ticketView == NULL) {
|
||||
@@ -142,7 +142,7 @@ out:
|
||||
|
||||
s32 ESP_DiGetTmd(ESTitleMeta* tmd, u32* tmdSize) {
|
||||
s32 rv = 0;
|
||||
u8 __esBuf[256] ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) u8 __esBuf[256];
|
||||
IOSIoVector* v = (IOSIoVector*)(__esBuf + 256 - 6 * sizeof(IOSIoVector));
|
||||
u32* p1 = (u32*)__esBuf;
|
||||
|
||||
@@ -184,7 +184,7 @@ out:
|
||||
|
||||
s32 ESP_GetTmdView(ESTitleId titleId, ESTmdView* tmdView, u32* size) {
|
||||
s32 rv = 0;
|
||||
u8 __esBuf[256] ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) u8 __esBuf[256];
|
||||
IOSIoVector* v = (IOSIoVector*)(__esBuf + 256 - 6 * sizeof(IOSIoVector));
|
||||
ESTitleId* p1 = (ESTitleId*)__esBuf;
|
||||
u32* p2 = (u32*)(__esBuf + 32);
|
||||
@@ -233,7 +233,7 @@ out:
|
||||
|
||||
s32 ESP_GetDataDir(ESTitleId titleId, char* dataDir) {
|
||||
s32 rv = 0;
|
||||
u8 __esBuf[256] ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) u8 __esBuf[256];
|
||||
IOSIoVector* v = (IOSIoVector*)(__esBuf + 256 - 6 * sizeof(IOSIoVector));
|
||||
ESTitleId* p1 = (ESTitleId*)__esBuf;
|
||||
|
||||
@@ -260,7 +260,7 @@ out:
|
||||
|
||||
s32 ESP_GetTitleId(ESTitleId* titleId) {
|
||||
s32 rv = 0;
|
||||
u8 __esBuf[256] ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) u8 __esBuf[256];
|
||||
IOSIoVector* v = (IOSIoVector*)(__esBuf + 256 - 6 * sizeof(IOSIoVector));
|
||||
|
||||
if (__esFd < 0 || titleId == NULL) {
|
||||
@@ -283,7 +283,7 @@ out:
|
||||
|
||||
s32 ESP_GetConsumption(ESTicketId ticketId, ESLpEntry* entries, u32* nEntries) {
|
||||
s32 rv = 0;
|
||||
u8 __esBuf[256] ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) u8 __esBuf[256];
|
||||
IOSIoVector* v = (IOSIoVector*)(__esBuf + 256 - 6 * sizeof(IOSIoVector));
|
||||
ESTicketId* p1 = (ESTicketId*)__esBuf;
|
||||
u32* p2 = (u32*)(__esBuf + 32);
|
||||
|
||||
@@ -25,7 +25,7 @@ typedef struct isfs_GetUsage {
|
||||
} isfs_GetUsage;
|
||||
|
||||
typedef struct __isfsCtxt {
|
||||
u8 ioBuf[ROUNDUP(256)] ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) u8 ioBuf[ROUNDUP(256)];
|
||||
ISFSCallback cb;
|
||||
void* ctxt;
|
||||
u32 func;
|
||||
|
||||
@@ -49,7 +49,7 @@ volatile void* __piReg;
|
||||
GXBool __GXinBegin;
|
||||
#endif
|
||||
|
||||
static u16 DefaultTexData[] ATTRIBUTE_ALIGN(32) = {
|
||||
ATTRIBUTE_ALIGN(32) static u16 DefaultTexData[] = {
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
};
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace nw4hbm {
|
||||
|
||||
private:
|
||||
/* 0x00 (base) */
|
||||
/* 0xD4 */ ut::Color mVtxColors[VERTEXCOLOR_MAX] ATTRIBUTE_ALIGN(4);
|
||||
/* 0xD4 */ ATTRIBUTE_ALIGN(4) ut::Color mVtxColors[VERTEXCOLOR_MAX];
|
||||
/* 0xE4 */ detail::TexCoordAry mTexCoordAry;
|
||||
};
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace nw4hbm {
|
||||
public:
|
||||
/* 0x14 */ ut::LinkListNode mLinkNode;
|
||||
|
||||
static u8 mMramBuf[LOAD_BUFFER_SIZE] ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) static u8 mMramBuf[LOAD_BUFFER_SIZE];
|
||||
};
|
||||
typedef ut::LinkList<LoadCommand, offsetof(LoadCommand, mLinkNode)> LoadCommandList;
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ static u32 __relnchFl = 0;
|
||||
|
||||
typedef struct IOSRpcRequest {
|
||||
IOSResourceRequest request;
|
||||
IOSIpcCb cb ATTRIBUTE_ALIGN(32); // I am assuming this is aligned due to where cbArg is stored, and I see nothing between cb and callback_arg?
|
||||
ATTRIBUTE_ALIGN(32) IOSIpcCb cb; // I am assuming this is aligned due to where cbArg is stored, and I see nothing between cb and callback_arg?
|
||||
void* callback_arg;
|
||||
u32 relaunch_flag;
|
||||
OSThreadQueue thread_queue;
|
||||
@@ -37,7 +37,7 @@ static IOSRpcRequest* __relnchRpcSave = 0;
|
||||
|
||||
#define ROUNDUP(sz) (((u32)(sz) + (IPC_BUF_CNT / 2 - 1)) & ~(u32)(IPC_BUF_CNT / 2 - 1))
|
||||
|
||||
static u8 __rpcBuf[ROUNDUP(sizeof(IOSRpcRequest))] ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) static u8 __rpcBuf[ROUNDUP(sizeof(IOSRpcRequest))];
|
||||
|
||||
static struct {
|
||||
u32 rcount;
|
||||
|
||||
@@ -33,8 +33,8 @@ enum LibState {
|
||||
};
|
||||
|
||||
static enum LibState s_libState = STATE_NOT_INITIALIZED;
|
||||
static char s_currentDir[64] ATTRIBUTE_ALIGN(32) = "/";
|
||||
static char s_homeDir[64] ATTRIBUTE_ALIGN(32) = "";
|
||||
ATTRIBUTE_ALIGN(32) static char s_currentDir[64] = "/";
|
||||
ATTRIBUTE_ALIGN(32) static char s_homeDir[64] = "";
|
||||
|
||||
static BOOL nandOnShutdown(BOOL final, u32 event);
|
||||
void nandConvertPath(char* abspath, const char* wd, const char* relpath);
|
||||
@@ -262,7 +262,7 @@ s32 nandConvertErrorCode(const ISFSError err) {
|
||||
for (; i < sizeof(ERRMAP) / 4; i = i + 2) {
|
||||
if (ERRMAP[i] == err) {
|
||||
if (err == ISFS_ERROR_ECC_CRIT || err == ISFS_ERROR_HMAC || err == ISFS_ERROR_UNKNOWN || err == IOS_ERROR_UNKNOWN || err == IOS_ERROR_ECC_CRIT) {
|
||||
char buf[128] ATTRIBUTE_ALIGN(64);
|
||||
ATTRIBUTE_ALIGN(64) char buf[128];
|
||||
sprintf(buf, "ISFS error code: %d", err);
|
||||
NANDLoggingAddMessageAsync(nandLoggingCallback, err, buf);
|
||||
}
|
||||
@@ -279,7 +279,7 @@ s32 nandConvertErrorCode(const ISFSError err) {
|
||||
|
||||
OSReport("CAUTION! Unexpected error code [%d] was found.\n", err);
|
||||
{
|
||||
char buf[128] ATTRIBUTE_ALIGN(64);
|
||||
ATTRIBUTE_ALIGN(64) char buf[128];
|
||||
sprintf(buf, "ISFS unexpected error code: %d", err);
|
||||
NANDLoggingAddMessageAsync(nandLoggingCallback, err, buf);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
static IOSFd s_fd = -255;
|
||||
static IOSError s_err = ISFS_ERROR_UNKNOWN;
|
||||
static int s_stage;
|
||||
static char s_message[256] ATTRIBUTE_ALIGN(64);
|
||||
ATTRIBUTE_ALIGN(64) static char s_message[256];
|
||||
static NANDLoggingCallback s_callback = 0;
|
||||
|
||||
static void asyncRoutine(ISFSError, void*);
|
||||
@@ -70,8 +70,8 @@ static void callbackRoutine(BOOL result) {
|
||||
|
||||
static void asyncRoutine(ISFSError result, void *ctxt) {
|
||||
ISFSError ret = ISFS_ERROR_UNKNOWN;
|
||||
static char s_rBuf[256] ATTRIBUTE_ALIGN(64);
|
||||
static char s_wBuf[256] ATTRIBUTE_ALIGN(64);
|
||||
ATTRIBUTE_ALIGN(64) static char s_rBuf[256];
|
||||
ATTRIBUTE_ALIGN(64) static char s_wBuf[256];
|
||||
++s_stage;
|
||||
|
||||
if (s_stage == 2) {
|
||||
|
||||
@@ -293,7 +293,7 @@ s32 NANDMove(const char* path, const char* destDir) {
|
||||
}
|
||||
|
||||
static ISFSError nandGetFileStatus(IOSFd fd, u32* length, u32* pos) {
|
||||
ISFSFileStats fstat ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) ISFSFileStats fstat;
|
||||
ISFSError result = ISFS_GetFileStats(fd, &fstat);
|
||||
if (result == ISFS_ERROR_OK) {
|
||||
if (length) {
|
||||
|
||||
@@ -8,7 +8,7 @@ void __OSRelaunchTitle(u32 resetCode) {
|
||||
s32 rc = 0;
|
||||
u32 ticketCnt = 1;
|
||||
ESTicketView* tik = NULL;
|
||||
ESTitleId titleId ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) ESTitleId titleId;
|
||||
__OSPlayTimeType type = OSPLAYTIME_PERMANENT;
|
||||
u32 remain = 0;
|
||||
u8* bi2 = NULL;
|
||||
|
||||
@@ -85,7 +85,7 @@ NWC24Err NWC24iSynchronizeRtcCounter(BOOL param_0) {
|
||||
}
|
||||
|
||||
NWC24Err NWC24SuspendScheduler(void) {
|
||||
static u8 susResult[0x20] ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) static u8 susResult[0x20];
|
||||
NWC24Err rt = NWC24_OK;
|
||||
NWC24Err closeRt = NWC24_OK;
|
||||
IOSFd fd;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include <revolution/nand.h>
|
||||
|
||||
static BOOL PlayRecordGet = FALSE;
|
||||
static OSPlayRecord PlayRecord ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) static OSPlayRecord PlayRecord;
|
||||
static NANDFileInfo FileInfo;
|
||||
static NANDCommandBlock Block;
|
||||
static s32 PlayRecordState = 9;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include "__os.h"
|
||||
|
||||
OSAlarm __OSExpireAlarm ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) OSAlarm __OSExpireAlarm;
|
||||
OSTime __OSExpireTime;
|
||||
OSPlayTimeCallbackFunc __OSExpireCallback;
|
||||
BOOL __OSExpireSetExpiredFlag;
|
||||
@@ -103,7 +103,7 @@ BOOL __OSWriteExpiredFlag(void) {
|
||||
s32 rv = 0;
|
||||
NANDFileInfo nInfo;
|
||||
BOOL openNInfo = FALSE;
|
||||
u8 titleId[32] ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) u8 titleId[32];
|
||||
|
||||
rv = NANDPrivateCreate("/shared2/expired", 63, 0);
|
||||
|
||||
@@ -162,7 +162,7 @@ BOOL __OSWriteExpiredFlagIfSet(void) {
|
||||
void* __OSPlayTimeRebootThread(void* args) {
|
||||
BOOL enabled;
|
||||
u32 frames, fadeShift = 1;
|
||||
__OSExpireAIFadeStruct aiFade ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) __OSExpireAIFadeStruct aiFade;
|
||||
|
||||
__OSExpireAIFade = &aiFade;
|
||||
memset(__OSExpireAIFade, 0, sizeof(__OSExpireAIFadeStruct));
|
||||
@@ -227,9 +227,9 @@ out:
|
||||
s32 __OSGetPlayTime(ESTicketView* ticket, __OSPlayTimeType* type, u32* playTime) {
|
||||
s32 rv;
|
||||
u32 i;
|
||||
ESLpEntry lpEntry[8] ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) ESLpEntry lpEntry[8];
|
||||
u32 numCc = 0, seenOther = 0;
|
||||
ESTicketView ticketAligned ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) ESTicketView ticketAligned;
|
||||
|
||||
ASSERTLINE(601, ticket && type && playTime);
|
||||
|
||||
@@ -288,7 +288,7 @@ out:
|
||||
|
||||
s32 __OSGetPlayTimeCurrent(__OSPlayTimeType* type, u32* playTime) {
|
||||
s32 rv;
|
||||
ESTicketView ticket ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) ESTicketView ticket;
|
||||
|
||||
ASSERTLINE(676, type && playTime);
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "__os.h"
|
||||
|
||||
static SramControl Scb ATTRIBUTE_ALIGN(DOLPHIN_ALIGNMENT);
|
||||
ATTRIBUTE_ALIGN(DOLPHIN_ALIGNMENT) static SramControl Scb;
|
||||
|
||||
// prototypes
|
||||
static int GetRTC(u32* rtc);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include <revolution/nand.h>
|
||||
#include <cstring>
|
||||
|
||||
static OSStateFlags StateFlags ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) static OSStateFlags StateFlags;
|
||||
|
||||
static u32 CheckSum(OSStateFlags* flags) {
|
||||
u32* ptr, i, sum;
|
||||
|
||||
@@ -5,14 +5,14 @@
|
||||
|
||||
#include <revolution/private/iosrestypes.h>
|
||||
|
||||
static u32 StmImInBuf[8] ATTRIBUTE_ALIGN(32);
|
||||
static u32 StmImOutBuf[8] ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) static u32 StmImInBuf[8];
|
||||
ATTRIBUTE_ALIGN(32) static u32 StmImOutBuf[8];
|
||||
|
||||
static u32 StmVdInBuf[8] ATTRIBUTE_ALIGN(32);
|
||||
static u32 StmVdOutBuf[8] ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) static u32 StmVdInBuf[8];
|
||||
ATTRIBUTE_ALIGN(32) static u32 StmVdOutBuf[8];
|
||||
|
||||
static u32 StmEhInBuf[8] ATTRIBUTE_ALIGN(32);
|
||||
static u32 StmEhOutBuf[8] ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) static u32 StmEhInBuf[8];
|
||||
ATTRIBUTE_ALIGN(32) static u32 StmEhOutBuf[8];
|
||||
|
||||
static OSResetCallback ResetCallback;
|
||||
static OSPowerCallback PowerCallback;
|
||||
|
||||
@@ -873,4 +873,4 @@ void* OSGetThreadSpecific(s32 index) {
|
||||
|
||||
#include "global.h"
|
||||
extern u8 Debug_BBA_804516D0;
|
||||
u8 Debug_BBA_804516D0 ATTRIBUTE_ALIGN(8);
|
||||
ATTRIBUTE_ALIGN(8) u8 Debug_BBA_804516D0;
|
||||
|
||||
@@ -75,8 +75,8 @@ static const char ConfDirName[] = "/shared2/sys";
|
||||
static const char ConfFileName[] = "/shared2/sys/SYSCONF";
|
||||
static const char ProductInfoFileName[] = "/title/00000001/00000002/data/setting.txt";
|
||||
|
||||
static u8 ConfBuf[0x4000] ATTRIBUTE_ALIGN(32);
|
||||
static u8 ConfBufForFlush[0x4000] ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) static u8 ConfBuf[0x4000];
|
||||
ATTRIBUTE_ALIGN(32) static u8 ConfBufForFlush[0x4000];
|
||||
|
||||
static u8 Initialized;
|
||||
static u8 DirtyFlag;
|
||||
|
||||
@@ -262,7 +262,7 @@ void WPADiManageHandler(OSAlarm*, OSContext*) {
|
||||
BTA_HhGetAclQueueInfo();
|
||||
}
|
||||
|
||||
u8 __WPADiManageHandlerStack[4096] ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) u8 __WPADiManageHandlerStack[4096];
|
||||
|
||||
void WPADiManageHandler0(OSAlarm* alarm, OSContext* context) {
|
||||
OSSwitchFiberEx((u32)alarm, (u32)context, 0, 0, (u32)WPADiManageHandler, (u32)(__WPADiManageHandlerStack + sizeof(__WPADiManageHandlerStack)));
|
||||
|
||||
@@ -41,7 +41,7 @@ WUDControlBlock _wcb;
|
||||
WUDDevInfo _work;
|
||||
static WUDDiscResp _discResp;
|
||||
SCBtDeviceInfoArray _scArray;
|
||||
u8 __WUDHandlerStack[0x1000] ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) u8 __WUDHandlerStack[0x1000];
|
||||
|
||||
extern u8 _scFlush;
|
||||
|
||||
|
||||
@@ -53,4 +53,14 @@ ModResult hook_replace(HookReplaceFn callback, const HookOptions* options = null
|
||||
return hook::replace<Entry>(callback, options);
|
||||
}
|
||||
|
||||
template <class Entry>
|
||||
ModResult hook_uninstall(const HookService* hooks) {
|
||||
return hook::uninstall<Entry>(hooks);
|
||||
}
|
||||
|
||||
template <class Entry>
|
||||
ModResult hook_uninstall() {
|
||||
return hook::uninstall<Entry>();
|
||||
}
|
||||
|
||||
} // namespace mods
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
#define CAMERA_SERVICE_ID "dev.twilitrealm.dusklight.camera"
|
||||
#define CAMERA_SERVICE_MAJOR 1u
|
||||
#define CAMERA_SERVICE_MINOR 0u
|
||||
#define CAMERA_SERVICE_MINOR 1u
|
||||
|
||||
/*
|
||||
* Snapshot of a game camera for the frame currently being recorded.
|
||||
@@ -46,6 +46,37 @@ typedef struct CameraInfo {
|
||||
|
||||
#define CAMERA_INFO_INIT {sizeof(CameraInfo)}
|
||||
|
||||
/* 0 is never a valid handle. */
|
||||
typedef uint64_t CameraOperatorHandle;
|
||||
|
||||
typedef struct CameraOperatorState {
|
||||
uint32_t struct_size;
|
||||
|
||||
/* Host inputs. */
|
||||
uint64_t frame_counter;
|
||||
uint64_t ticks;
|
||||
float aspect;
|
||||
|
||||
/* Initial camera state and callback output. */
|
||||
float eye[3];
|
||||
float center[3];
|
||||
float fovy;
|
||||
float bank_degrees;
|
||||
} CameraOperatorState;
|
||||
|
||||
/* Return true to use state for the current frame. Game thread only. */
|
||||
typedef bool (*CameraOperateFn)(ModContext* ctx, CameraOperatorState* state, void* user_data);
|
||||
|
||||
typedef struct CameraOperatorDesc {
|
||||
uint32_t struct_size;
|
||||
const char* debug_name;
|
||||
int32_t priority;
|
||||
CameraOperateFn operate;
|
||||
void* user_data;
|
||||
} CameraOperatorDesc;
|
||||
|
||||
#define CAMERA_OPERATOR_DESC_INIT {sizeof(CameraOperatorDesc), NULL, 0, NULL, NULL}
|
||||
|
||||
typedef struct CameraService {
|
||||
ServiceHeader header;
|
||||
|
||||
@@ -55,6 +86,17 @@ typedef struct CameraService {
|
||||
* perspective camera.
|
||||
*/
|
||||
ModResult (*get_camera)(ModContext* ctx, const void* game_view, CameraInfo* out_info);
|
||||
|
||||
/* Minor version 1 */
|
||||
|
||||
/*
|
||||
* Register an operator for the main camera. Operators run by descending priority, then
|
||||
* registration order, until one returns true. debug_name and operate must be set; debug_name
|
||||
* is copied. out_handle must not be NULL.
|
||||
*/
|
||||
ModResult (*register_camera_operator)(
|
||||
ModContext* ctx, const CameraOperatorDesc* desc, CameraOperatorHandle* out_handle);
|
||||
ModResult (*unregister_camera_operator)(ModContext* ctx, CameraOperatorHandle handle);
|
||||
} CameraService;
|
||||
|
||||
MOD_DECLARE_SERVICE(
|
||||
|
||||
+33
-14
@@ -7,20 +7,22 @@
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Intercept game functions by address. Prefer the typed helpers in mods/svc/hook.hpp
|
||||
* (mods::hook::add_pre/add_post/replace over a &Class::method): they generate the
|
||||
* trampoline and hide install/dispatch, which are the low-level primitives those helpers
|
||||
* build. resolve() maps a symbol name to an address for targets you can't name at compile time
|
||||
* (file-local statics included).
|
||||
* Hooks allow intercepting calls to game functions, allowing you to:
|
||||
* - Modify arguments
|
||||
* - Perform your own work before (pre), after (post) or instead of (replace) the original call
|
||||
* - From a pre hook, conditionally skip the original call and return your own value
|
||||
*
|
||||
* Every call is game-thread-only. Install and removal must run with no hooked function on the
|
||||
* stack; the loader guarantees this by applying mod lifecycle changes between frames, which is
|
||||
* why hooking a function that never returns (the outermost loop) makes a mod un-unloadable.
|
||||
* In most cases, you'll want to instead use the C++ helpers in mods/svc/hook.hpp
|
||||
* (mods::hook::add_pre/add_post/replace). They generate the trampoline passed to
|
||||
* install and provide compile-time type checking.
|
||||
*
|
||||
* resolve() resolves an address by symbol name for targets you can't name at compile time
|
||||
* (file-local statics included).
|
||||
*/
|
||||
|
||||
#define HOOK_SERVICE_ID "dev.twilitrealm.dusklight.hook"
|
||||
#define HOOK_SERVICE_MAJOR 1u
|
||||
#define HOOK_SERVICE_MINOR 0u
|
||||
#define HOOK_SERVICE_MINOR 1u
|
||||
|
||||
/* Symbol flags reported by resolve() */
|
||||
typedef enum HookSymbolFlags {
|
||||
@@ -72,11 +74,18 @@ typedef struct HookService {
|
||||
ServiceHeader header;
|
||||
|
||||
/*
|
||||
* Install a trampoline detour on fn_addr and return the address to call the original through in
|
||||
* *out_original_fn. The typed helpers generate the trampoline and call this; mods normally
|
||||
* don't. The first mod to install a given target owns the live detour; later mods register as
|
||||
* candidates so a hook survives the owner unloading (the detour is handed off and every
|
||||
* original pointer is rewritten). Idempotent per (mod, out slot).
|
||||
* Install a hook on fn_addr.
|
||||
*
|
||||
* trampoline_fn must point to a function that matches the original function's signature and
|
||||
* dispatches pre- and post- hooks. This dispatch trampoline is normally generated at compile
|
||||
* time using C++ template instantiation (see mods/svc/hook.hpp).
|
||||
*
|
||||
* The first hook install on a target will implicitly install a detour (patched instructions
|
||||
* on the target that jump to the dispatch trampoline). When all hooks are uninstalled from a
|
||||
* target, the detour is completely uninstalled.
|
||||
*
|
||||
* The address that the dispatch trampoline should call the original function through is written
|
||||
* to out_original_fn.
|
||||
*/
|
||||
ModResult (*install)(
|
||||
ModContext* ctx, void* fn_addr, void* trampoline_fn, void** out_original_fn);
|
||||
@@ -116,6 +125,16 @@ typedef struct HookService {
|
||||
*/
|
||||
ModResult (*resolve)(
|
||||
ModContext* ctx, const char* symbol, void** out_addr, HookSymbolFlags* out_flags);
|
||||
|
||||
/* Minor version 1 */
|
||||
|
||||
/*
|
||||
* Uninstall the current mod's hook on fn_addr and unregister all callbacks.
|
||||
* If no other mods have a hook installed on the target, the detour is uninstalled entirely.
|
||||
*
|
||||
* original_fn_slot must match the out_original_fn passed to install.
|
||||
*/
|
||||
ModResult (*uninstall)(ModContext* ctx, void* fn_addr, void** original_fn_slot);
|
||||
} HookService;
|
||||
|
||||
MOD_DECLARE_SERVICE(HookService, svc_hook, HOOK_SERVICE_ID, HOOK_SERVICE_MAJOR, HOOK_SERVICE_MINOR);
|
||||
|
||||
@@ -238,5 +238,27 @@ ModResult replace(HookReplaceFn callback, const HookOptions* options = nullptr)
|
||||
return replace<Entry>(svc_hook, callback, options);
|
||||
}
|
||||
|
||||
template <class Entry>
|
||||
ModResult uninstall(const HookService* hooks) {
|
||||
if (hooks == nullptr || !SERVICE_HAS(hooks, HookService, uninstall) ||
|
||||
hooks->uninstall == nullptr || Entry::target == nullptr)
|
||||
{
|
||||
return MOD_UNAVAILABLE;
|
||||
}
|
||||
|
||||
const ModResult result =
|
||||
hooks->uninstall(mod_ctx, Entry::target, reinterpret_cast<void**>(&Entry::g_orig));
|
||||
if (result == MOD_OK) {
|
||||
Entry::hooks = nullptr;
|
||||
Entry::g_orig = nullptr;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class Entry>
|
||||
ModResult uninstall() {
|
||||
return uninstall<Entry>(svc_hook);
|
||||
}
|
||||
|
||||
} // namespace hook
|
||||
} // namespace mods
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
#define HOST_SERVICE_ID "dev.twilitrealm.dusklight.host"
|
||||
#define HOST_SERVICE_MAJOR 2u
|
||||
#define HOST_SERVICE_MINOR 1u
|
||||
#define HOST_SERVICE_MINOR 2u
|
||||
|
||||
/*
|
||||
* Ignore unknown values: later service minors may add events.
|
||||
@@ -96,15 +96,24 @@ typedef struct HostService {
|
||||
ModContext* ctx, ModLifecycleFn fn, void* user_data, uint64_t* out_handle);
|
||||
ModResult (*unwatch_mod_lifecycle)(ModContext* ctx, uint64_t handle);
|
||||
|
||||
/* Minor version 1 */
|
||||
|
||||
/*
|
||||
* Read-only directory containing this platform's packaged native runtime: the mod module
|
||||
* and any RUNTIME_LIBRARIES. The path is absolute and remains valid until mod_shutdown
|
||||
* returns. Libraries loaded dynamically from here are owned by the mod and must be unloaded
|
||||
* during mod_shutdown.
|
||||
*
|
||||
* Added in minor version 1.
|
||||
*/
|
||||
const char* (*native_dir)(ModContext* ctx);
|
||||
|
||||
/* Minor version 2 */
|
||||
|
||||
/*
|
||||
* A persistent writable directory reserved for the calling mod, created on first use.
|
||||
*
|
||||
* The returned path remains valid until mod_shutdown returns. *out_path is null on failure.
|
||||
*/
|
||||
ModResult (*data_dir)(ModContext* ctx, const char** out_path);
|
||||
} HostService;
|
||||
|
||||
MOD_DECLARE_SERVICE(HostService, svc_host, HOST_SERVICE_ID, HOST_SERVICE_MAJOR, HOST_SERVICE_MINOR);
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
|
||||
/*
|
||||
* Read-only access to the res/ tree of the calling mod's own bundle. Reload serves the new
|
||||
* bundle's contents. For writable storage, use HostService::mod_dir.
|
||||
* bundle's contents. Use HostService::data_dir for persistent storage or HostService::mod_dir
|
||||
* for temporary storage.
|
||||
*/
|
||||
|
||||
#define RESOURCE_SERVICE_ID "dev.twilitrealm.dusklight.resource"
|
||||
|
||||
@@ -218,21 +218,21 @@ static void __THPAudioInitialize(THPAudioDecodeInfo* info, u8* ptr) {
|
||||
}
|
||||
|
||||
#if !TARGET_PC
|
||||
static u8 THPStatistics[1120] ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) static u8 THPStatistics[1120];
|
||||
|
||||
static THPHuffmanTab* Ydchuff ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) static THPHuffmanTab* Ydchuff;
|
||||
|
||||
static THPHuffmanTab* Udchuff ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) static THPHuffmanTab* Udchuff;
|
||||
|
||||
static THPHuffmanTab* Vdchuff ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) static THPHuffmanTab* Vdchuff;
|
||||
|
||||
static THPHuffmanTab* Yachuff ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) static THPHuffmanTab* Yachuff;
|
||||
|
||||
static THPHuffmanTab* Uachuff ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) static THPHuffmanTab* Uachuff;
|
||||
|
||||
static THPHuffmanTab* Vachuff ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) static THPHuffmanTab* Vachuff;
|
||||
|
||||
static f32 __THPIDCTWorkspace[64] ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) static f32 __THPIDCTWorkspace[64];
|
||||
|
||||
static u8* __THPHuffmanBits;
|
||||
|
||||
@@ -240,11 +240,11 @@ static u8* __THPHuffmanSizeTab;
|
||||
|
||||
static u16* __THPHuffmanCodeTab;
|
||||
|
||||
static THPSample* Gbase ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) static THPSample* Gbase;
|
||||
|
||||
static u32 Gwid ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) static u32 Gwid;
|
||||
|
||||
static f32* Gq ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) static f32* Gq;
|
||||
|
||||
static u8* __THPLCWork512[3];
|
||||
|
||||
@@ -3582,7 +3582,7 @@ static void daMP_MixAudio(s16* destination, s16*, u32 sample) {
|
||||
|
||||
static BOOL daMP_Initialized;
|
||||
|
||||
static u32 daMP_WorkBuffer[16] ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) static u32 daMP_WorkBuffer[16];
|
||||
|
||||
static OSMessageQueue daMP_PrepareReadyQueue;
|
||||
|
||||
@@ -3604,7 +3604,7 @@ static void* daMP_CurAudioBuffer;
|
||||
|
||||
static s32 daMP_AudioSystem;
|
||||
|
||||
static u8 daMP_SoundBuffer[2][0x8C0] ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) static u8 daMP_SoundBuffer[2][0x8C0];
|
||||
|
||||
static s16* daMP_audioCallbackWithMSound(s32 sample) {
|
||||
if (daMP_ActivePlayer.open == 0 || daMP_ActivePlayer.internalState != 2 || daMP_ActivePlayer.audioExist == 0) {
|
||||
|
||||
@@ -101,7 +101,7 @@ static f32 l_texCoord[42] = {
|
||||
0.8f, 0.9f, 1.0, 0.0, 1.0, 0.2f, 1.0, 0.4f, 1.0, 0.6f, 1.0, 0.8f, 1.0, 1.0,
|
||||
};
|
||||
|
||||
static u8 l_pennant_flagDL[152] ATTRIBUTE_ALIGN(32) = {
|
||||
ATTRIBUTE_ALIGN(32) static u8 l_pennant_flagDL[152] = {
|
||||
0x98, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x04, 0x04, 0x04, 0x05,
|
||||
0x05, 0x05, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x0D, 0x0D, 0x0D, 0x0E, 0x0E, 0x0E, 0x13, 0x13,
|
||||
0x13, 0x14, 0x14, 0x14, 0x98, 0x00, 0x09, 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04,
|
||||
|
||||
+2
-1
@@ -29,6 +29,7 @@
|
||||
#endif
|
||||
|
||||
#if TARGET_PC
|
||||
#include "dusk/camera_operators.hpp"
|
||||
#include "dusk/frame_interpolation.h"
|
||||
#include "dusk/logging.h"
|
||||
#include "dusk/action_bindings.h"
|
||||
@@ -1053,7 +1054,7 @@ void dCamera_c::debugDrawInit() {
|
||||
bool dCamera_c::Run() {
|
||||
#if TARGET_PC
|
||||
ResetView();
|
||||
if (executeDebugFlyCam()) {
|
||||
if (executeDebugFlyCam() || dusk::mods::camera_run_operators(this)) {
|
||||
mFrameCounter++;
|
||||
mTicks++;
|
||||
return true;
|
||||
|
||||
@@ -2469,7 +2469,7 @@ struct field_data {
|
||||
};
|
||||
|
||||
void dComIfGp_calcNowRegion() {
|
||||
u8 buffer[0x800] ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) u8 buffer[0x800];
|
||||
|
||||
dComIfGp_getFieldMapArchive2()->readResource(buffer, 0x800, "dat/field.dat");
|
||||
u8* entry_num_p = &buffer[((field_data_header*)buffer)->field_0x4];
|
||||
@@ -2525,7 +2525,7 @@ void dComIfGp_calcNowRegion() {
|
||||
}
|
||||
|
||||
u8 dComIfG_getNowCalcRegion() {
|
||||
u8 buffer[0x800] ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) u8 buffer[0x800];
|
||||
|
||||
dComIfGp_getFieldMapArchive2()->readResource(buffer, 0x800, "dat/field.dat");
|
||||
u8* entry_num_p = &buffer[((field_data_header*)buffer)->field_0x4];
|
||||
|
||||
+13
-13
@@ -529,14 +529,14 @@ void dDlst_2DT2_c::draw() {
|
||||
dComIfGp_getCurrentGrafPort()->setup2D();
|
||||
}
|
||||
|
||||
static u8 l_frontZMat[] ATTRIBUTE_ALIGN(32) = {
|
||||
ATTRIBUTE_ALIGN(32) static u8 l_frontZMat[] = {
|
||||
0x61, 0x40, 0x00, 0x00, 0x07, 0x10, 0x00, 0x00, 0x10, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x10,
|
||||
0x00, 0x00, 0x10, 0x09, 0x00, 0x00, 0x00, 0x01, 0x61, 0x00, 0x00, 0x40, 0x10, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
static u8 l_frontNoZSubMat[] ATTRIBUTE_ALIGN(32) = {
|
||||
ATTRIBUTE_ALIGN(32) static u8 l_frontNoZSubMat[] = {
|
||||
0x61, 0x40, 0x00, 0x00, 0x06, 0x61, 0x41, 0x00, 0x09, 0x35, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
@@ -547,14 +547,14 @@ static Vec l_shadowVolPos[] = {
|
||||
{1.0f, -1.0f, 0.0f}, {1.0f, -1.0f, -300.0f}, {1.0f, 1.0f, 0.0f}, {1.0f, 1.0f, -300.0f},
|
||||
};
|
||||
|
||||
static u8 l_shadowVolDL[] ATTRIBUTE_ALIGN(32) = {
|
||||
ATTRIBUTE_ALIGN(32) static u8 l_shadowVolDL[] = {
|
||||
0x80, 0x00, 0x18, 0x06, 0x02, 0x03, 0x07, 0x00, 0x04, 0x05, 0x01, 0x06, 0x04, 0x00, 0x02,
|
||||
0x07, 0x05, 0x04, 0x06, 0x03, 0x01, 0x05, 0x07, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
static u8 l_shadowProjMat[] ATTRIBUTE_ALIGN(32) = {
|
||||
ATTRIBUTE_ALIGN(32) static u8 l_shadowProjMat[] = {
|
||||
0x61, 0x28, 0x38, 0x03, 0xC0, 0x61, 0xC0, 0x08, 0xFF, 0xFF, 0x61, 0xC1, 0x08, 0xE6, 0x70,
|
||||
0x61, 0x43, 0x00, 0x00, 0x01, 0x61, 0x40, 0x00, 0x00, 0x07, 0x61, 0x41, 0x00, 0x04, 0xAD,
|
||||
0x61, 0xF3, 0x64, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x3F, 0x00, 0x00, 0x00, 0x01, 0x10,
|
||||
@@ -563,7 +563,7 @@ static u8 l_shadowProjMat[] ATTRIBUTE_ALIGN(32) = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
static u8 l_shadowVolMat[] ATTRIBUTE_ALIGN(32) = {
|
||||
ATTRIBUTE_ALIGN(32) static u8 l_shadowVolMat[] = {
|
||||
0x61, 0x28, 0x38, 0x00, 0x00, 0x61, 0xC0, 0x08, 0xFF, 0xFC, 0x61, 0xC1, 0x08, 0xFF, 0x90,
|
||||
0x61, 0x43, 0x00, 0x00, 0x41, 0x61, 0x40, 0x00, 0x00, 0x0D, 0x61, 0x41, 0x00, 0x01, 0x35,
|
||||
0x61, 0xF3, 0x7F, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x10,
|
||||
@@ -572,7 +572,7 @@ static u8 l_shadowVolMat[] ATTRIBUTE_ALIGN(32) = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
static u8 l_clearMat[] ATTRIBUTE_ALIGN(32) = {
|
||||
ATTRIBUTE_ALIGN(32) static u8 l_clearMat[] = {
|
||||
0x61, 0x28, 0x38, 0x00, 0x00, 0x61, 0xC0, 0x08, 0xFF, 0xFF, 0x61, 0xC1, 0x08, 0xFF, 0xA0,
|
||||
0x61, 0x40, 0x00, 0x00, 0x06, 0x61, 0x41, 0x00, 0x00, 0x14, 0x61, 0xF3, 0x7F, 0x00, 0x00,
|
||||
0x10, 0x00, 0x00, 0x10, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x09, 0x00,
|
||||
@@ -581,7 +581,7 @@ static u8 l_clearMat[] ATTRIBUTE_ALIGN(32) = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
static u8 l_frontMat[] ATTRIBUTE_ALIGN(32) = {
|
||||
ATTRIBUTE_ALIGN(32) static u8 l_frontMat[] = {
|
||||
0x61, 0x28, 0x38, 0x00, 0x00, 0x61, 0xC0, 0x08, 0xFF, 0xFF, 0x61, 0xC1, 0x08, 0xFF, 0x90,
|
||||
0x61, 0x43, 0x00, 0x00, 0x41, 0x61, 0x40, 0x00, 0x00, 0x07, 0x61, 0x41, 0x00, 0x01, 0x15,
|
||||
0x10, 0x00, 0x00, 0x10, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x09, 0x00,
|
||||
@@ -590,7 +590,7 @@ static u8 l_frontMat[] ATTRIBUTE_ALIGN(32) = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
static u8 l_backSubMat[] ATTRIBUTE_ALIGN(32) = {
|
||||
ATTRIBUTE_ALIGN(32) static u8 l_backSubMat[] = {
|
||||
0x61, 0x41, 0x00, 0x09, 0x35, 0x10, 0x00, 0x00, 0x10, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x10,
|
||||
0x00, 0x00, 0x10, 0x09, 0x00, 0x00, 0x00, 0x01, 0x61, 0x00, 0x00, 0x80, 0x10, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
@@ -604,7 +604,7 @@ static Vec l_simpleShadowPos[] = {
|
||||
{1.0f, 1.0f, 1.0f}, {-1.0f, 1.0f, 1.0f},
|
||||
};
|
||||
|
||||
static u8 l_shadowVolumeDL[] ATTRIBUTE_ALIGN(32) = {
|
||||
ATTRIBUTE_ALIGN(32) static u8 l_shadowVolumeDL[] = {
|
||||
0x98, 0x00, 0x05, 0x03, 0x09, 0x01, 0x07, 0x05, 0x98, 0x00, 0x05, 0x04, 0x06, 0x00, 0x08,
|
||||
0x02, 0x98, 0x00, 0x04, 0x04, 0x05, 0x06, 0x07, 0x98, 0x00, 0x04, 0x02, 0x03, 0x04, 0x05,
|
||||
0x98, 0x00, 0x04, 0x08, 0x09, 0x02, 0x03, 0x98, 0x00, 0x04, 0x06, 0x07, 0x08, 0x09, 0x98,
|
||||
@@ -613,7 +613,7 @@ static u8 l_shadowVolumeDL[] ATTRIBUTE_ALIGN(32) = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
static u8 l_shadowSealTexDL[] ATTRIBUTE_ALIGN(32) = {
|
||||
ATTRIBUTE_ALIGN(32) static u8 l_shadowSealTexDL[] = {
|
||||
0x61, 0x28, 0x38, 0x03, 0xC0, 0x61, 0x40, 0x00, 0x00, 0x06, 0x61, 0x41, 0x00, 0x06, 0x15,
|
||||
0x10, 0x00, 0x00, 0x10, 0x3F, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x10, 0x09, 0x00,
|
||||
0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x40, 0x01, 0x80, 0x00, 0x04, 0x0A, 0x00, 0x00, 0x0B,
|
||||
@@ -622,7 +622,7 @@ static u8 l_shadowSealTexDL[] ATTRIBUTE_ALIGN(32) = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
static u8 l_shadowSealTex2DL[] ATTRIBUTE_ALIGN(32) = {
|
||||
ATTRIBUTE_ALIGN(32) static u8 l_shadowSealTex2DL[] = {
|
||||
0x61, 0x28, 0x38, 0x03, 0xC0, 0x61, 0x40, 0x00, 0x00, 0x06, 0x61, 0x41, 0x00, 0x06, 0x15,
|
||||
0x10, 0x00, 0x00, 0x10, 0x3F, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x10, 0x09, 0x00,
|
||||
0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x40, 0x01, 0x80, 0x00, 0x04, 0x0A, 0x00, 0x00, 0x0B,
|
||||
@@ -631,7 +631,7 @@ static u8 l_shadowSealTex2DL[] ATTRIBUTE_ALIGN(32) = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
static u8 l_shadowSealDL[] ATTRIBUTE_ALIGN(32) = {
|
||||
ATTRIBUTE_ALIGN(32) static u8 l_shadowSealDL[] = {
|
||||
0x10, 0x00, 0x00, 0x10, 0x0E, 0x00, 0x00, 0x05, 0x00, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00,
|
||||
0x00, 0x05, 0x00, 0x61, 0x28, 0x38, 0x00, 0x00, 0x61, 0xC0, 0x08, 0xFF, 0xFF, 0x61, 0xC1,
|
||||
0x08, 0xFF, 0xB0, 0x61, 0x40, 0x00, 0x00, 0x06, 0x61, 0x41, 0x00, 0x06, 0xED, 0x10, 0x00,
|
||||
@@ -1534,7 +1534,7 @@ void dDlst_shadowControl_c::reset() {
|
||||
}
|
||||
|
||||
void dDlst_shadowControl_c::imageDraw(Mtx param_0) {
|
||||
static u8 l_matDL[] ATTRIBUTE_ALIGN(32) = {
|
||||
ATTRIBUTE_ALIGN(32) static u8 l_matDL[] = {
|
||||
0x10, 0x00, 0x00, 0x10, 0x0E, 0x00, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x10, 0x10,
|
||||
0x00, 0x00, 0x04, 0x00, 0x61, 0x28, 0x38, 0x00, 0x00, 0x61, 0xC0, 0x08, 0xFF, 0xF2,
|
||||
0x61, 0xC1, 0x08, 0xFF, 0x90, 0x61, 0x43, 0x00, 0x00, 0x41, 0x61, 0xF3, 0x7F, 0x00,
|
||||
|
||||
+1
-1
@@ -300,7 +300,7 @@ BOOL dLib_checkActorInRectangle(fopAc_ac_c* param_0, fopAc_ac_c* param_1, cXyz c
|
||||
}
|
||||
|
||||
u32 dLib_getExpandSizeFromAramArchive(JKRAramArchive* i_aramArchive, char const* param_2) {
|
||||
u8 header[32] ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) u8 header[32];
|
||||
JUT_ASSERT(1252, i_aramArchive != NULL);
|
||||
u32 address = i_aramArchive->getAramAddress(param_2);
|
||||
if (address == 0) {
|
||||
|
||||
@@ -172,7 +172,7 @@ int renderingDmap_c::getLineWidth(int param_0) {
|
||||
return var_r31;
|
||||
}
|
||||
|
||||
static u32 const l_paletteDmap_m[60] ATTRIBUTE_ALIGN(32) = {
|
||||
ATTRIBUTE_ALIGN(32) static u32 const l_paletteDmap_m[60] = {
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x80008000,
|
||||
@@ -680,7 +680,7 @@ f32 dMenu_DmapMapCtrl_c::getZoomCmPerPixel() {
|
||||
return var_f29;
|
||||
}
|
||||
|
||||
static u32 l_data[61] ATTRIBUTE_ALIGN(32) = {
|
||||
ATTRIBUTE_ALIGN(32) static u32 l_data[61] = {
|
||||
0x80008000,
|
||||
0x80008000,
|
||||
0x00000000,
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
class dCamera_c;
|
||||
|
||||
namespace dusk::mods {
|
||||
|
||||
bool camera_run_operators(dCamera_c* camera);
|
||||
|
||||
} // namespace dusk::mods
|
||||
@@ -166,6 +166,8 @@ struct LoadedMod {
|
||||
std::filesystem::path dir;
|
||||
// Stable UTF-8 storage for HostService::mod_dir.
|
||||
std::string dirUtf8;
|
||||
// Stable UTF-8 storage for HostService::data_dir.
|
||||
std::string dataDirUtf8;
|
||||
|
||||
uint32_t searchDirIndex = 0;
|
||||
// Native lib is dlopen'd in place and stays resident for the session. Reload is unsupported.
|
||||
|
||||
@@ -1,13 +1,24 @@
|
||||
#include "registry.hpp"
|
||||
#include "slot_map.hpp"
|
||||
|
||||
#include "dusk/camera_operators.hpp"
|
||||
#include "dusk/mods/loader/loader.hpp"
|
||||
#include "mods/svc/camera.h"
|
||||
|
||||
#include "SSystem/SComponent/c_angle.h"
|
||||
#include "d/d_camera.h"
|
||||
#include "d/d_com_inf_game.h"
|
||||
#include "f_op/f_op_camera_mng.h"
|
||||
#include "f_op/f_op_view.h"
|
||||
#include "m_Do/m_Do_mtx.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <aurora/gfx.hpp>
|
||||
#include <cstring>
|
||||
#include <exception>
|
||||
#include <fmt/format.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace dusk::mods::svc {
|
||||
namespace {
|
||||
@@ -117,9 +128,125 @@ ModResult camera_get_camera_from_view(
|
||||
return snapshot_view(static_cast<const view_class*>(gameView), outInfo);
|
||||
}
|
||||
|
||||
struct CameraOperator {
|
||||
std::string debugName;
|
||||
int32_t priority = 0;
|
||||
uint64_t sequence = 0;
|
||||
CameraOperateFn operate = nullptr;
|
||||
void* userData = nullptr;
|
||||
};
|
||||
|
||||
SlotMap<CameraOperator> sOperators;
|
||||
uint64_t sNextOperatorSequence = 0;
|
||||
|
||||
ModResult camera_register_operator(
|
||||
ModContext* context, const CameraOperatorDesc* desc, CameraOperatorHandle* outHandle) {
|
||||
if (outHandle != nullptr) {
|
||||
*outHandle = 0;
|
||||
}
|
||||
|
||||
auto* mod = mod_from_context(context);
|
||||
if (mod == nullptr || desc == nullptr || desc->struct_size < sizeof(CameraOperatorDesc) ||
|
||||
desc->debug_name == nullptr || desc->debug_name[0] == '\0' || desc->operate == nullptr ||
|
||||
outHandle == nullptr)
|
||||
{
|
||||
return MOD_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
*outHandle = sOperators.emplace(*mod, CameraOperator{
|
||||
.debugName = desc->debug_name,
|
||||
.priority = desc->priority,
|
||||
.sequence = sNextOperatorSequence++,
|
||||
.operate = desc->operate,
|
||||
.userData = desc->user_data,
|
||||
});
|
||||
return MOD_OK;
|
||||
}
|
||||
|
||||
ModResult camera_unregister_operator(ModContext* context, CameraOperatorHandle handle) {
|
||||
auto* mod = mod_from_context(context);
|
||||
if (mod == nullptr || handle == 0) {
|
||||
return MOD_INVALID_ARGUMENT;
|
||||
}
|
||||
return sOperators.erase_owned(handle, *mod) ? MOD_OK : MOD_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
CameraOperatorState make_operator_state(const dCamera_c& camera) {
|
||||
return CameraOperatorState{
|
||||
.struct_size = sizeof(CameraOperatorState),
|
||||
.frame_counter = camera.mFrameCounter,
|
||||
.ticks = camera.mTicks,
|
||||
.aspect = mDoGph_gInf_c::getAspect(),
|
||||
.eye = {camera.mEye.x, camera.mEye.y, camera.mEye.z},
|
||||
.center = {camera.mCenter.x, camera.mCenter.y, camera.mCenter.z},
|
||||
.fovy = camera.mFovy,
|
||||
.bank_degrees = camera.mBank.Degree(),
|
||||
};
|
||||
}
|
||||
|
||||
bool run_operators(dCamera_c* camera) {
|
||||
auto* mainCamera = dComIfGp_getCamera(0);
|
||||
if (camera == nullptr || mainCamera == nullptr || &mainCamera->mCamera != camera) {
|
||||
return false;
|
||||
}
|
||||
|
||||
struct PendingOperator {
|
||||
CameraOperatorHandle handle;
|
||||
CameraOperator value;
|
||||
LoadedMod* owner;
|
||||
};
|
||||
std::vector<PendingOperator> operators;
|
||||
sOperators.for_each([&](CameraOperatorHandle handle, const auto& entry) {
|
||||
operators.push_back({.handle = handle, .value = entry.value, .owner = entry.owner});
|
||||
});
|
||||
std::ranges::sort(operators, [](const PendingOperator& lhs, const PendingOperator& rhs) {
|
||||
if (lhs.value.priority != rhs.value.priority) {
|
||||
return lhs.value.priority > rhs.value.priority;
|
||||
}
|
||||
return lhs.value.sequence < rhs.value.sequence;
|
||||
});
|
||||
|
||||
const auto initialState = make_operator_state(*camera);
|
||||
for (const auto& entry : operators) {
|
||||
if (!entry.owner->active || sOperators.find(entry.handle) == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto state = initialState;
|
||||
bool useState = false;
|
||||
try {
|
||||
useState =
|
||||
entry.value.operate(entry.owner->context.get(), &state, entry.value.userData);
|
||||
} catch (const std::exception& e) {
|
||||
fail_mod(*entry.owner, MOD_ERROR,
|
||||
fmt::format(
|
||||
"exception in camera operator '{}': {}", entry.value.debugName, e.what()));
|
||||
} catch (...) {
|
||||
fail_mod(*entry.owner, MOD_ERROR,
|
||||
fmt::format("unknown exception in camera operator '{}'", entry.value.debugName));
|
||||
}
|
||||
|
||||
if (!useState) {
|
||||
continue;
|
||||
}
|
||||
|
||||
camera->Reset(cXyz{state.center[0], state.center[1], state.center[2]},
|
||||
cXyz{state.eye[0], state.eye[1], state.eye[2]}, state.fovy,
|
||||
cAngle::Degree_to_SAngle(state.bank_degrees));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void camera_mod_detached(LoadedMod& mod) {
|
||||
sOperators.erase_all(mod);
|
||||
}
|
||||
|
||||
constexpr CameraService s_cameraService{
|
||||
.header = SERVICE_HEADER(CameraService, CAMERA_SERVICE_MAJOR, CAMERA_SERVICE_MINOR),
|
||||
.get_camera = camera_get_camera_from_view,
|
||||
.register_camera_operator = camera_register_operator,
|
||||
.unregister_camera_operator = camera_unregister_operator,
|
||||
};
|
||||
|
||||
} // namespace
|
||||
@@ -129,6 +256,11 @@ constinit const ServiceModule g_cameraModule{
|
||||
.majorVersion = CAMERA_SERVICE_MAJOR,
|
||||
.minorVersion = CAMERA_SERVICE_MINOR,
|
||||
.service = &s_cameraService,
|
||||
.modDetached = camera_mod_detached,
|
||||
};
|
||||
|
||||
} // namespace dusk::mods::svc
|
||||
|
||||
bool dusk::mods::camera_run_operators(dCamera_c* camera) {
|
||||
return svc::run_operators(camera);
|
||||
}
|
||||
|
||||
+110
-42
@@ -86,6 +86,7 @@ struct InstalledHook {
|
||||
InstalledBackend backend{};
|
||||
void* original = nullptr;
|
||||
ModContext* active = nullptr;
|
||||
void** activeStore = nullptr;
|
||||
std::vector<HookCandidate> candidates;
|
||||
};
|
||||
|
||||
@@ -143,6 +144,15 @@ void sort_hooks(std::vector<T>& hooks) {
|
||||
});
|
||||
}
|
||||
|
||||
bool erase_callbacks(HookSlot& slot, ModContext* context) {
|
||||
std::erase_if(slot.pre, [&](const PreHookFn& hook) { return hook.context == context; });
|
||||
std::erase_if(slot.post, [&](const VoidHookFn& hook) { return hook.context == context; });
|
||||
if (slot.replace.context == context) {
|
||||
slot.replace = {};
|
||||
}
|
||||
return slot.pre.empty() && slot.post.empty() && slot.replace.replaceCallback == nullptr;
|
||||
}
|
||||
|
||||
// Once a hook is installed, funchook has patched the target's entry: its bytes lead to the
|
||||
// detour, not the function, so canonicalization must stop there.
|
||||
[[maybe_unused]] bool installed_target(void* addr) {
|
||||
@@ -336,6 +346,46 @@ bool handoff_backend(
|
||||
#endif
|
||||
}
|
||||
|
||||
bool handoff_hook(void* target, InstalledHook& entry) {
|
||||
#if DUSK_HAS_PREPATCH
|
||||
const bool prepatched = entry.backend.kind == BackendKind::Prepatch;
|
||||
#else
|
||||
constexpr bool prepatched = false;
|
||||
#endif
|
||||
if (!prepatched) {
|
||||
deactivate_backend(target, entry.backend);
|
||||
}
|
||||
|
||||
entry.active = nullptr;
|
||||
entry.activeStore = nullptr;
|
||||
for (auto& candidate : entry.candidates) {
|
||||
void* original = nullptr;
|
||||
if (!handoff_backend(target, entry, candidate, &original)) {
|
||||
continue;
|
||||
}
|
||||
entry.original = original;
|
||||
entry.active = candidate.context;
|
||||
entry.activeStore = candidate.origStore;
|
||||
break;
|
||||
}
|
||||
|
||||
if (entry.active == nullptr) {
|
||||
DuskLog.warn("HookSystem: no reinstallable trampoline for {:p}; hooks there are "
|
||||
"disabled until a mod reinstalls one",
|
||||
target);
|
||||
for (auto& candidate : entry.candidates) {
|
||||
*candidate.origStore = target;
|
||||
}
|
||||
deactivate_backend(target, entry.backend);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto& candidate : entry.candidates) {
|
||||
*candidate.origStore = entry.original;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
ModResult hook_install(ModContext* context, void* fnAddr, void* trampolineFn, void** outOriginal) {
|
||||
if (fnAddr == nullptr || trampolineFn == nullptr || outOriginal == nullptr) {
|
||||
return MOD_INVALID_ARGUMENT;
|
||||
@@ -390,6 +440,7 @@ ModResult hook_install(ModContext* context, void* fnAddr, void* trampolineFn, vo
|
||||
entry.backend = backend;
|
||||
entry.original = *outOriginal;
|
||||
entry.active = context;
|
||||
entry.activeStore = outOriginal;
|
||||
entry.candidates.push_back({context, trampolineFn, outOriginal, s_nextOrder++});
|
||||
return MOD_OK;
|
||||
}
|
||||
@@ -459,6 +510,57 @@ ModResult hook_replace(
|
||||
return MOD_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
ModResult hook_uninstall(ModContext* context, void* fnAddr, void** originalFnSlot) {
|
||||
if (context == nullptr || fnAddr == nullptr || originalFnSlot == nullptr) {
|
||||
return MOD_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
fnAddr = resolve_target(fnAddr);
|
||||
if (!declared_target(context, fnAddr)) {
|
||||
return reject_undeclared(context, fnAddr);
|
||||
}
|
||||
|
||||
const auto key = reinterpret_cast<uintptr_t>(fnAddr);
|
||||
const auto installedIt = s_installed.find(key);
|
||||
if (installedIt == s_installed.end()) {
|
||||
return MOD_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
auto& entry = installedIt->second;
|
||||
const auto candidateIt =
|
||||
std::ranges::find_if(entry.candidates, [&](const HookCandidate& candidate) {
|
||||
return candidate.context == context && candidate.origStore == originalFnSlot;
|
||||
});
|
||||
if (candidateIt == entry.candidates.end()) {
|
||||
return MOD_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (const auto registryIt = s_registry.find(key);
|
||||
registryIt != s_registry.end() && erase_callbacks(registryIt->second, context))
|
||||
{
|
||||
s_registry.erase(registryIt);
|
||||
}
|
||||
|
||||
const bool removedActive = entry.activeStore == originalFnSlot;
|
||||
entry.candidates.erase(candidateIt);
|
||||
*originalFnSlot = nullptr;
|
||||
if (!removedActive) {
|
||||
return MOD_OK;
|
||||
}
|
||||
|
||||
auto* target = reinterpret_cast<void*>(key);
|
||||
if (entry.candidates.empty()) {
|
||||
deactivate_backend(target, entry.backend);
|
||||
s_installed.erase(installedIt);
|
||||
return MOD_OK;
|
||||
}
|
||||
if (!handoff_hook(target, entry)) {
|
||||
s_installed.erase(installedIt);
|
||||
return MOD_ERROR;
|
||||
}
|
||||
return MOD_OK;
|
||||
}
|
||||
|
||||
ModResult hook_dispatch_pre(
|
||||
ModContext*, void* fnAddr, void* args, void* retval, int* outSkipOriginal) {
|
||||
if (outSkipOriginal != nullptr) {
|
||||
@@ -775,13 +877,7 @@ void hook_remove_mod(LoadedMod& mod) {
|
||||
s_declaredTargets.erase(context);
|
||||
|
||||
for (auto it = s_registry.begin(); it != s_registry.end();) {
|
||||
auto& slot = it->second;
|
||||
std::erase_if(slot.pre, [&](const PreHookFn& hook) { return hook.context == context; });
|
||||
std::erase_if(slot.post, [&](const VoidHookFn& hook) { return hook.context == context; });
|
||||
if (slot.replace.context == context) {
|
||||
slot.replace = {};
|
||||
}
|
||||
if (slot.pre.empty() && slot.post.empty() && slot.replace.replaceCallback == nullptr) {
|
||||
if (erase_callbacks(it->second, context)) {
|
||||
it = s_registry.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
@@ -806,44 +902,12 @@ void hook_remove_mod(LoadedMod& mod) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// A prepatch may be atomically updated directly.
|
||||
// Funchook must first restore the original instructions before reinstalling.
|
||||
#if DUSK_HAS_PREPATCH
|
||||
const bool prepatched = entry.backend.kind == BackendKind::Prepatch;
|
||||
#else
|
||||
constexpr bool prepatched = false;
|
||||
#endif
|
||||
if (!prepatched) {
|
||||
deactivate_backend(target, entry.backend);
|
||||
}
|
||||
entry.active = nullptr;
|
||||
for (auto& cand : entry.candidates) {
|
||||
void* original = nullptr;
|
||||
if (!handoff_backend(target, entry, cand, &original)) {
|
||||
continue;
|
||||
}
|
||||
entry.original = original;
|
||||
entry.active = cand.context;
|
||||
DuskLog.info("HookSystem: replaced trampoline for {:p}: {} -> {} (tramp={:p})", target,
|
||||
mod_id_from_context(context), mod_id_from_context(cand.context), cand.trampoline);
|
||||
break;
|
||||
}
|
||||
|
||||
if (entry.active == nullptr) {
|
||||
DuskLog.warn("HookSystem: no reinstallable trampoline for {:p}; hooks there are "
|
||||
"disabled until a mod reinstalls one",
|
||||
target);
|
||||
for (auto& cand : entry.candidates) {
|
||||
*cand.origStore = target;
|
||||
}
|
||||
deactivate_backend(target, entry.backend);
|
||||
if (!handoff_hook(target, entry)) {
|
||||
it = s_installed.erase(it);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (auto& cand : entry.candidates) {
|
||||
*cand.origStore = entry.original;
|
||||
}
|
||||
DuskLog.info("HookSystem: replaced trampoline for {:p}: {} -> {}", target,
|
||||
mod_id_from_context(context), mod_id_from_context(entry.active));
|
||||
++it;
|
||||
}
|
||||
}
|
||||
@@ -862,6 +926,9 @@ ModResult hook_add_post(ModContext*, void*, HookPostFn, const HookOptions*) {
|
||||
ModResult hook_replace(ModContext*, void*, HookReplaceFn, const HookOptions*) {
|
||||
return MOD_UNSUPPORTED;
|
||||
}
|
||||
ModResult hook_uninstall(ModContext*, void*, void**) {
|
||||
return MOD_UNSUPPORTED;
|
||||
}
|
||||
ModResult hook_dispatch_pre(ModContext*, void*, void*, void*, int* outSkipOriginal) {
|
||||
if (outSkipOriginal != nullptr) {
|
||||
*outSkipOriginal = 0;
|
||||
@@ -902,6 +969,7 @@ constexpr HookService s_hookService{
|
||||
.dispatch_pre = hook_dispatch_pre,
|
||||
.dispatch_post = hook_dispatch_post,
|
||||
.resolve = hook_resolve,
|
||||
.uninstall = hook_uninstall,
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
#include "registry.hpp"
|
||||
#include "slot_map.hpp"
|
||||
|
||||
#include "dusk/main.h"
|
||||
#include "dusk/mods/loader/loader.hpp"
|
||||
#include "dusk/mods/log_buffer.hpp"
|
||||
#include "dusk/mods/manifest.hpp"
|
||||
#include "fmt/format.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <borealis/io.hpp>
|
||||
#include <borealis/version.h>
|
||||
#include <filesystem>
|
||||
#include <vector>
|
||||
|
||||
namespace dusk::mods::svc {
|
||||
namespace {
|
||||
@@ -68,6 +72,41 @@ const char* host_native_dir(ModContext* context) {
|
||||
return mod != nullptr ? mod->nativeDirUtf8.c_str() : "";
|
||||
}
|
||||
|
||||
ModResult host_data_dir(ModContext* context, const char** outPath) {
|
||||
if (outPath == nullptr) {
|
||||
return MOD_INVALID_ARGUMENT;
|
||||
}
|
||||
*outPath = nullptr;
|
||||
|
||||
auto* mod = mod_from_context(context);
|
||||
if (mod == nullptr) {
|
||||
return MOD_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (mod->dataDirUtf8.empty()) {
|
||||
namespace fs = std::filesystem;
|
||||
std::error_code ec;
|
||||
const fs::path path = fs::absolute(dusk::ConfigPath / "mod_data" / mod->metadata.id, ec);
|
||||
if (ec) {
|
||||
log::write(mod->metadata.id, LOG_LEVEL_ERROR,
|
||||
"failed to resolve persistent mod data directory: {}", ec.message());
|
||||
return MOD_ERROR;
|
||||
}
|
||||
|
||||
fs::create_directories(path, ec);
|
||||
if (ec) {
|
||||
log::write(mod->metadata.id, LOG_LEVEL_ERROR,
|
||||
"failed to create persistent mod data directory {}: {}",
|
||||
borealis::io::fs_path_to_string(path), ec.message());
|
||||
return MOD_ERROR;
|
||||
}
|
||||
mod->dataDirUtf8 = borealis::io::fs_path_to_string(path);
|
||||
}
|
||||
|
||||
*outPath = mod->dataDirUtf8.c_str();
|
||||
return MOD_OK;
|
||||
}
|
||||
|
||||
struct LifecycleWatcher {
|
||||
ModLifecycleFn fn = nullptr;
|
||||
void* userData = nullptr;
|
||||
@@ -148,6 +187,7 @@ constinit HostService s_hostService{
|
||||
.watch_mod_lifecycle = host_watch_mod_lifecycle,
|
||||
.unwatch_mod_lifecycle = host_unwatch_mod_lifecycle,
|
||||
.native_dir = host_native_dir,
|
||||
.data_dir = host_data_dir,
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -22,7 +22,7 @@ static OSThread DvdErr_thread;
|
||||
|
||||
#pragma push
|
||||
#pragma force_active on
|
||||
static u8 DvdErr_stack[stack_size] ATTRIBUTE_ALIGN(16);
|
||||
ATTRIBUTE_ALIGN(16) static u8 DvdErr_stack[stack_size];
|
||||
#pragma pop
|
||||
|
||||
static OSAlarm Alarm;
|
||||
|
||||
@@ -484,7 +484,7 @@ void mDoMemCd_Ctrl_c::detach() {
|
||||
mCardState = CARD_STATE_NO_CARD_e;
|
||||
}
|
||||
|
||||
static u8 MemCardWorkArea0[CARD_WORKAREA_SIZE] ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) static u8 MemCardWorkArea0[CARD_WORKAREA_SIZE];
|
||||
|
||||
s32 mDoMemCd_Ctrl_c::mount() {
|
||||
s32 result = CARDMount(mChannel, MemCardWorkArea0, NULL);
|
||||
|
||||
@@ -2239,7 +2239,7 @@ void mDoExt_invJntPacket::draw() {
|
||||
} while (shapePkt != NULL);
|
||||
}
|
||||
} else {
|
||||
static u8 l_invisibleMat[] ATTRIBUTE_ALIGN(32) = {
|
||||
ATTRIBUTE_ALIGN(32) static u8 l_invisibleMat[] = {
|
||||
0x10, 0x00, 0x00, 0x10, 0x0E, 0x00, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00,
|
||||
0x00, 0x04, 0x00, 0x61, 0x28, 0x38, 0x00, 0x00, 0x61, 0xC0, 0x08, 0xFF, 0xFC, 0x61, 0xC1,
|
||||
0x08, 0xFF, 0xF0, 0x61, 0xF3, 0x7F, 0x00, 0x00, 0x61, 0x43, 0x00, 0x00, 0x41, 0x61, 0x40,
|
||||
@@ -2357,7 +2357,7 @@ int mDoExt_3DlineMat0_c::init(u16 param_0, u16 param_1, int param_2) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static u8 l_matDL[132] ATTRIBUTE_ALIGN(32) = {
|
||||
ATTRIBUTE_ALIGN(32) static u8 l_matDL[132] = {
|
||||
0x08, 0x30, 0x3C, 0xF3, 0xCF, 0x00, 0x10, 0x00, 0x00, 0x10, 0x18, 0x3C, 0xF3, 0xCF, 0x00,
|
||||
0x10, 0x00, 0x00, 0x10, 0x0E, 0x00, 0x00, 0x7F, 0x32, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00,
|
||||
0x00, 0x05, 0x00, 0x10, 0x00, 0x00, 0x10, 0x0C, 0xFF, 0xFF, 0xFF, 0xFF, 0x61, 0x28, 0x38,
|
||||
@@ -2682,7 +2682,7 @@ int mDoExt_3DlineMat1_c::init(u16 param_0, u16 param_1, ResTIMG* param_2, int pa
|
||||
return 1;
|
||||
}
|
||||
|
||||
static u8 l_mat1DL[141] ATTRIBUTE_ALIGN(32) = {
|
||||
ATTRIBUTE_ALIGN(32) static u8 l_mat1DL[141] = {
|
||||
0x10, 0x00, 0x00, 0x10, 0x40, 0xFF, 0xFF, 0x42, 0x80, 0x08, 0x30, 0x3C, 0xF3, 0xCF, 0x00, 0x10,
|
||||
0x00, 0x00, 0x10, 0x18, 0x3C, 0xF3, 0xCF, 0x00, 0x10, 0x00, 0x00, 0x10, 0x0E, 0x00, 0x00, 0x7F,
|
||||
0x32, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x05, 0x00, 0x10, 0x00, 0x00, 0x10, 0x0C, 0xFF,
|
||||
|
||||
@@ -126,7 +126,7 @@ void OSReportInit() {
|
||||
}
|
||||
}
|
||||
|
||||
static u8 mDoPrintf_FiberStack[2048] ATTRIBUTE_ALIGN(32);
|
||||
ATTRIBUTE_ALIGN(32) static u8 mDoPrintf_FiberStack[2048];
|
||||
|
||||
void mDoPrintf_vprintf_Interrupt(char const* fmt, va_list args) {
|
||||
BOOL interruptStatus = OSDisableInterrupts();
|
||||
|
||||
Reference in New Issue
Block a user