mirror of
https://github.com/zeldaret/tp
synced 2026-05-23 06:54:28 -04:00
Revolution SDK work (#3091)
* Implement revolution/ax Copied mostly unchanged from Petari * Implement revolution/axfx Copied mostly unchanged from Petari * Implement revolution/arc Copied mostly unchanged from Petari * Implement revolution/mem Copied mostly unchanged from Petari * Implement revolution/tpl Copied verbatim from Petari * revolution/ipc matching (except small linking issue on ShieldD) * revolution/pad/Pad matching Largely copied from Petari with significant modifications * Fix up ut_TextWriterBase symbols * Fix homebuttonLib file names in Shield splits
This commit is contained in:
@@ -0,0 +1,297 @@
|
||||
#include <revolution/arc.h>
|
||||
#include <revolution.h>
|
||||
#include <locale>
|
||||
|
||||
/* this is here because it won't be inlined otherwise */
|
||||
inline int tolower(int c) {
|
||||
return ((c < 0) || (c >= 0x100)) ? c : (int) (_current_locale.ctype_cmpt_ptr->lower_map_ptr[c]);
|
||||
}
|
||||
|
||||
typedef struct FSTEntry FSTEntry;
|
||||
|
||||
struct FSTEntry {
|
||||
unsigned int isDirAndStringOff;
|
||||
unsigned int parentOrPosition;
|
||||
unsigned int nextEntryOrLength;
|
||||
};
|
||||
|
||||
#define entryIsDir(fstStart, i) \
|
||||
( ( ( fstStart[i].isDirAndStringOff & 0xFF000000 ) == 0 )? FALSE : TRUE )
|
||||
#define stringOff(fstStart, i) \
|
||||
( fstStart[i].isDirAndStringOff & 0x00FFFFFF )
|
||||
#define parentDir(fstStart, i) \
|
||||
( fstStart[i].parentOrPosition )
|
||||
#define nextDir(fstStart, i) \
|
||||
( fstStart[i].nextEntryOrLength )
|
||||
#define filePosition(fstStart, i) \
|
||||
( fstStart[i].parentOrPosition )
|
||||
#define fileLength(fstStart, i) \
|
||||
( fstStart[i].nextEntryOrLength )
|
||||
|
||||
BOOL ARCInitHandle(void* arcStart, ARCHandle* handle) {
|
||||
FSTEntry* FSTEntries;
|
||||
ARCHeader* arcHeader = (ARCHeader*)arcStart;
|
||||
|
||||
if (arcHeader->magic != 0x55AA382D) {
|
||||
#if SDK_AUG2010
|
||||
OSPanic(__FILE__, 0x4A, "ARCInitHandle: bad archive format");
|
||||
#else
|
||||
OSPanic(__FILE__, 0x47, "ARCInitHandle: bad archive format");
|
||||
#endif
|
||||
}
|
||||
|
||||
handle->archiveStartAddr = arcStart;
|
||||
handle->FSTStart = FSTEntries = (void*)((u32)arcStart + arcHeader->fstStart);
|
||||
handle->fileStart = (void*)((u32)arcStart + arcHeader->fileStart);
|
||||
handle->entryNum = nextDir(FSTEntries, 0);
|
||||
handle->FSTStringStart = (char*)&(FSTEntries[handle->entryNum]);
|
||||
handle->FSTLength = (u32)arcHeader->fstSize;
|
||||
handle->currDir = 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL ARCFastOpen(ARCHandle* handle, s32 entrynum, ARCFileInfo* af) {
|
||||
FSTEntry* FSTEntries = (FSTEntry*)handle->FSTStart;
|
||||
|
||||
if ((entrynum < 0) || (entrynum >= handle->entryNum) || entryIsDir(FSTEntries, entrynum)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
af->handle = handle;
|
||||
af->startOffset = filePosition(FSTEntries, entrynum);
|
||||
af->length = fileLength(FSTEntries, entrynum);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL isSame(const char* path, const char* string) {
|
||||
while(*string != '\0') {
|
||||
if (tolower(*path++) != tolower(*string++)) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if ((*path == '/') || (*path == '\0')) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
s32 ARCConvertPathToEntrynum(ARCHandle* handle, const char* pathPtr)
|
||||
{
|
||||
const char* ptr;
|
||||
char* stringPtr;
|
||||
BOOL isDir;
|
||||
s32 length;
|
||||
u32 dirLookAt;
|
||||
u32 i;
|
||||
const char* origPathPtr = pathPtr;
|
||||
FSTEntry* FSTEntries;
|
||||
|
||||
dirLookAt = handle->currDir;
|
||||
FSTEntries = (FSTEntry*)handle->FSTStart;
|
||||
|
||||
while (1) {
|
||||
if (*pathPtr == '\0') {
|
||||
return (s32)dirLookAt;
|
||||
}
|
||||
else if (*pathPtr == '/') {
|
||||
dirLookAt = 0;
|
||||
pathPtr++;
|
||||
continue;
|
||||
}
|
||||
else if (*pathPtr == '.') {
|
||||
if (*(pathPtr + 1) == '.') {
|
||||
if (*(pathPtr + 2) == '/') {
|
||||
dirLookAt = parentDir(FSTEntries, dirLookAt);
|
||||
pathPtr += 3;
|
||||
continue;
|
||||
}
|
||||
else if (*(pathPtr + 2) == '\0') {
|
||||
return (s32)parentDir(FSTEntries, dirLookAt);
|
||||
}
|
||||
}
|
||||
else if (*(pathPtr + 1) == '/') {
|
||||
pathPtr += 2;
|
||||
continue;
|
||||
}
|
||||
else if (*(pathPtr + 1) == '\0') {
|
||||
return (s32)dirLookAt;
|
||||
}
|
||||
}
|
||||
|
||||
for(ptr = pathPtr; (*ptr != '\0') && (*ptr != '/'); ptr++);
|
||||
isDir = (*ptr == '\0')? FALSE : TRUE;
|
||||
length = (s32)(ptr - pathPtr);
|
||||
ptr = pathPtr;
|
||||
|
||||
for(i = dirLookAt + 1; i < nextDir(FSTEntries, dirLookAt);
|
||||
i = entryIsDir(FSTEntries, i)? nextDir(FSTEntries, i): (i+1) )
|
||||
{
|
||||
dot:
|
||||
if ((entryIsDir(FSTEntries, i) == FALSE) && (isDir == TRUE)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
stringPtr = handle->FSTStringStart + stringOff(FSTEntries, i);
|
||||
|
||||
if (*stringPtr == '.' && *(stringPtr + 1) == '\0') {
|
||||
i++;
|
||||
goto dot;
|
||||
}
|
||||
|
||||
if (isSame(ptr, stringPtr) == TRUE) {
|
||||
goto next_hier;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
|
||||
next_hier:
|
||||
if (!isDir) {
|
||||
return (s32)i;
|
||||
}
|
||||
|
||||
dirLookAt = i;
|
||||
pathPtr += length + 1;
|
||||
}
|
||||
|
||||
// the world ends if this is reached
|
||||
}
|
||||
|
||||
static u32 myStrncpy(char* dest, char* src, u32 maxlen) {
|
||||
u32 i = maxlen;
|
||||
|
||||
while ((i > 0) && (*src != 0)) {
|
||||
*dest++ = *src++;
|
||||
i--;
|
||||
}
|
||||
|
||||
return (maxlen - i);
|
||||
}
|
||||
|
||||
static u32 entryToPath(ARCHandle* handle, u32 entry, char* path, u32 maxlen) {
|
||||
char* name;
|
||||
u32 loc;
|
||||
FSTEntry* FSTEntries = (FSTEntry*)handle->FSTStart;
|
||||
|
||||
if (entry == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
name = handle->FSTStringStart + stringOff(FSTEntries, entry);
|
||||
loc = entryToPath(handle, parentDir(FSTEntries, entry), path, maxlen);
|
||||
|
||||
if (loc == maxlen) {
|
||||
return loc;
|
||||
}
|
||||
|
||||
*(path + loc++) = '/';
|
||||
loc += myStrncpy(path + loc, name, maxlen - loc);
|
||||
return loc;
|
||||
}
|
||||
|
||||
static BOOL ARCConvertEntrynumToPath(ARCHandle* handle, s32 entrynum, char* path, u32 maxlen) {
|
||||
u32 loc;
|
||||
FSTEntry* FSTEntries = (FSTEntry*)handle->FSTStart;
|
||||
|
||||
loc = entryToPath(handle, (u32)entrynum, path, maxlen);
|
||||
|
||||
if (loc == maxlen) {
|
||||
path[maxlen - 1] = '\0';
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (entryIsDir(FSTEntries, entrynum)) {
|
||||
if (loc == maxlen - 1) {
|
||||
path[loc] = '\0';
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
path[loc++] = '/';
|
||||
}
|
||||
|
||||
path[loc] = '\0';
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL ARCGetCurrentDir(ARCHandle* handle, char* path, u32 maxlen) {
|
||||
return ARCConvertEntrynumToPath(handle, (s32)handle->currDir, path, maxlen);
|
||||
}
|
||||
|
||||
void* ARCGetStartAddrInMem(ARCFileInfo* af) {
|
||||
ARCHandle* handle = af->handle;
|
||||
return (void*)((u32)handle->archiveStartAddr + af->startOffset);
|
||||
}
|
||||
|
||||
u32 ARCGetLength(ARCFileInfo* af) {
|
||||
return af->length;
|
||||
}
|
||||
|
||||
BOOL ARCClose(ARCFileInfo* af) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL ARCChangeDir(ARCHandle* handle, const char* dirName) {
|
||||
s32 entry;
|
||||
FSTEntry* FSTEntries;
|
||||
|
||||
entry = ARCConvertPathToEntrynum(handle, dirName);
|
||||
FSTEntries = (FSTEntry*)handle->FSTStart;
|
||||
|
||||
if ((entry < 0) || (entryIsDir(FSTEntries, entry) == FALSE)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
handle->currDir = (u32)entry;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL ARCOpenDir(ARCHandle* handle, const char* dirName, ARCDir* dir) {
|
||||
s32 entry;
|
||||
FSTEntry* FSTEntries;
|
||||
|
||||
entry = ARCConvertPathToEntrynum(handle, dirName);
|
||||
FSTEntries = (FSTEntry*)handle->FSTStart;
|
||||
|
||||
if ((entry < 0) || (entryIsDir(FSTEntries, entry) == FALSE)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
dir->handle = handle;
|
||||
dir->entryNum = (u32)entry;
|
||||
dir->location = (u32)entry + 1;
|
||||
dir->next = nextDir(FSTEntries, entry);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL ARCReadDir(ARCDir* dir, ARCDirEntry* dirent) {
|
||||
u32 loc;
|
||||
FSTEntry* FSTEntries;
|
||||
ARCHandle* handle;
|
||||
|
||||
handle = dir->handle;
|
||||
FSTEntries = (FSTEntry*)handle->FSTStart;
|
||||
loc = dir->location;
|
||||
retry:
|
||||
if ((loc <= dir->entryNum) || (dir->next <= loc)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
dirent->handle = handle;
|
||||
dirent->entryNum = loc;
|
||||
dirent->isDir = entryIsDir(FSTEntries, loc);
|
||||
dirent->name = handle->FSTStringStart + stringOff(FSTEntries, loc);
|
||||
|
||||
if (dirent->name[0] == '.' && dirent->name[1] == '\0') {
|
||||
loc++;
|
||||
goto retry;
|
||||
}
|
||||
|
||||
dir->location = entryIsDir(FSTEntries, loc)? nextDir(FSTEntries, loc) : (loc+1);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL ARCCloseDir(ARCDir* dir) {
|
||||
return TRUE;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#include <revolution/ax.h>
|
||||
#include <revolution/os.h>
|
||||
#include <cstring>
|
||||
|
||||
static u8 __clearAuxA[3];
|
||||
|
||||
static AXAuxCallback __AXCallbackAuxA;
|
||||
static void* __AXContextAuxA;
|
||||
|
||||
void AXRegisterAuxACallback(AXAuxCallback callback, void* context) {
|
||||
#if SDK_AUG2010
|
||||
BOOL enabled = OSDisableInterrupts();
|
||||
#endif
|
||||
|
||||
__AXCallbackAuxA = callback;
|
||||
__AXContextAuxA = context;
|
||||
|
||||
#if SDK_AUG2010
|
||||
if (callback == NULL) {
|
||||
memset(&__clearAuxA, TRUE, 3);
|
||||
}
|
||||
|
||||
OSRestoreInterrupts(enabled);
|
||||
#endif
|
||||
}
|
||||
|
||||
void AXGetAuxACallback(AXAuxCallback* callback, void** context) {
|
||||
*callback = __AXCallbackAuxA;
|
||||
*context = __AXContextAuxA;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#include <revolution/ax.h>
|
||||
#include <revolution/types.h>
|
||||
|
||||
static u16 __AXAuxAVolume;
|
||||
static u16 __AXAuxBVolume;
|
||||
static u16 __AXAuxCVolume;
|
||||
|
||||
u16 AXGetAuxAReturnVolume(void) {
|
||||
return __AXAuxAVolume;
|
||||
}
|
||||
|
||||
u16 AXGetAuxBReturnVolume(void) {
|
||||
return __AXAuxBVolume;
|
||||
}
|
||||
|
||||
u16 AXGetAuxCReturnVolume(void) {
|
||||
return __AXAuxCVolume;
|
||||
}
|
||||
|
||||
void AXSetAuxAReturnVolume(u16 volume) {
|
||||
__AXAuxAVolume = volume;
|
||||
}
|
||||
|
||||
void AXSetAuxBReturnVolume(u16 volume) {
|
||||
__AXAuxBVolume = volume;
|
||||
}
|
||||
|
||||
void AXSetAuxCReturnVolume(u16 volume) {
|
||||
__AXAuxCVolume = volume;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#include <revolution/axfx.h>
|
||||
#include <revolution/os.h>
|
||||
#include <revolution/os/OSAlloc.h>
|
||||
#include <cstdio>
|
||||
|
||||
static void* __AXFXAllocFunction(size_t size);
|
||||
static void __AXFXFreeFunction(void* block);
|
||||
|
||||
AXFXAllocHook __AXFXAlloc = __AXFXAllocFunction;
|
||||
AXFXFreeHook __AXFXFree = __AXFXFreeFunction;
|
||||
|
||||
static void* __AXFXAllocFunction(size_t size) {
|
||||
return OSAllocFromHeap(__OSCurrHeap, size);
|
||||
}
|
||||
|
||||
static void __AXFXFreeFunction(void* block) {
|
||||
OSFreeToHeap(__OSCurrHeap, block);
|
||||
}
|
||||
|
||||
void AXFXSetHooks(AXFXAllocHook alloc, AXFXFreeHook free) {
|
||||
__AXFXAlloc = alloc;
|
||||
__AXFXFree = free;
|
||||
}
|
||||
|
||||
void AXFXGetHooks(AXFXAllocHook* alloc, AXFXFreeHook* free) {
|
||||
*alloc = __AXFXAlloc;
|
||||
*free = __AXFXFree;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
#include <revolution/axfx.h>
|
||||
#include <revolution.h>
|
||||
|
||||
static void __ParamConvert(AXFX_REVERBHI* fx) {
|
||||
fx->exp.earlyMode = 5;
|
||||
fx->exp.preDelayTimeMax = fx->preDelay;
|
||||
fx->exp.preDelayTime = fx->preDelay;
|
||||
fx->exp.fusedMode = 0;
|
||||
fx->exp.fusedTime = fx->time;
|
||||
fx->exp.coloration = fx->coloration;
|
||||
fx->exp.damping = fx->damping;
|
||||
fx->exp.crosstalk = fx->crosstalk;
|
||||
fx->exp.earlyGain = 0.0f;
|
||||
fx->exp.fusedGain = 1.0f;
|
||||
fx->exp.busIn = NULL;
|
||||
fx->exp.busOut = NULL;
|
||||
fx->exp.outGain = fx->mix;
|
||||
fx->exp.sendGain = 0.0f;
|
||||
}
|
||||
|
||||
BOOL AXFXReverbHiInit(AXFX_REVERBHI* fx) {
|
||||
__ParamConvert(fx);
|
||||
return AXFXReverbHiExpInit(&fx->exp);
|
||||
}
|
||||
|
||||
BOOL AXFXReverbHiShutdown(AXFX_REVERBHI* fx) {
|
||||
AXFXReverbHiExpShutdown(&fx->exp);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void AXFXReverbHiCallback(void* chans, void* context) {
|
||||
AXFXReverbHiExpCallback((AXFX_BUFFERUPDATE*)chans, &((AXFX_REVERBHI*)context)->exp);
|
||||
}
|
||||
@@ -0,0 +1,418 @@
|
||||
#include <revolution/axfx.h>
|
||||
#include <revolution/mem.h>
|
||||
#include <cmath>
|
||||
|
||||
static u32 __EarlySizeTable[8][3] = {
|
||||
{157, 479, 829}, {317, 809, 1117}, {479, 941, 1487}, {641, 1259, 1949},
|
||||
{797, 1667, 2579}, {967, 1901, 2903}, {1123, 2179, 3413}, {1279, 2477, 3889}
|
||||
};
|
||||
|
||||
static f32 __EarlyCoefTable[8][3] = {
|
||||
{0.4f, -1.0f, 0.3f}, {0.5f, -0.95f, 0.3f}, {0.6f, -0.9f, 0.3f}, {0.75f, -0.85f, 0.3f},
|
||||
{-0.9f, 0.8f, 0.3f}, {-1.0f, 0.7f, 0.3f}, {-1.0f, 0.7f, 0.3f}, {-1.0f, 0.7f, 0.3f}
|
||||
};
|
||||
|
||||
static u32 __FilterSizeTable[7][8] = {
|
||||
{1789, 1999, 2333, 433, 149, 47, 73, 67}, {149, 293, 449, 251, 103, 47, 73, 67},
|
||||
{947, 1361, 1531, 433, 137, 47, 73, 67}, {1279, 1531, 1973, 509, 149, 47, 73, 67},
|
||||
{1531, 1847, 2297, 563, 179, 47, 73, 67}, {1823, 2357, 2693, 571, 137, 47, 73, 67},
|
||||
{1823, 2357, 2693, 571, 179, 47, 73, 67}
|
||||
};
|
||||
|
||||
static BOOL __AllocDelayLine(AXFX_REVERBHI_EXP* reverb);
|
||||
static void __FreeDelayLine(AXFX_REVERBHI_EXP* reverb);
|
||||
static void __BzeroDelayLines(AXFX_REVERBHI_EXP* reverb);
|
||||
static BOOL __InitParams(AXFX_REVERBHI_EXP* reverb);
|
||||
|
||||
f32 dummy_0() {
|
||||
return 32000.0f;
|
||||
}
|
||||
|
||||
BOOL AXFXReverbHiExpInit(AXFX_REVERBHI_EXP* reverb) {
|
||||
u32 ch, i;
|
||||
BOOL result = TRUE;
|
||||
BOOL mask = OSDisableInterrupts();
|
||||
|
||||
reverb->active = 1;
|
||||
|
||||
if (reverb->preDelayTimeMax < 0.0f) {
|
||||
AXFXReverbHiExpShutdown(reverb);
|
||||
OSRestoreInterrupts(mask);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
reverb->earlyMaxLength = __EarlySizeTable[8 - 1][2];
|
||||
reverb->preDelayMaxLength = (u32)(reverb->preDelayTimeMax * 32000);
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
reverb->combMaxLength[i] = __FilterSizeTable[6][i];
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
reverb->allpassMaxLength[i] = __FilterSizeTable[6][3 + i];
|
||||
}
|
||||
|
||||
for (ch = 0; ch < 3; ch++) {
|
||||
reverb->lastAllpassMaxLength[ch] = __FilterSizeTable[6][5 + ch];
|
||||
}
|
||||
|
||||
result = __AllocDelayLine(reverb);
|
||||
if (result == FALSE) {
|
||||
AXFXReverbHiExpShutdown(reverb);
|
||||
OSRestoreInterrupts(mask);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
__BzeroDelayLines(reverb);
|
||||
result = __InitParams(reverb);
|
||||
if (result == FALSE) {
|
||||
AXFXReverbHiExpShutdown(reverb);
|
||||
OSRestoreInterrupts(mask);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
reverb->active &= ~1;
|
||||
OSRestoreInterrupts(mask);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void AXFXReverbHiExpShutdown(AXFX_REVERBHI_EXP* reverb) {
|
||||
BOOL mask = OSDisableInterrupts();
|
||||
reverb->active |= 1;
|
||||
__FreeDelayLine(reverb);
|
||||
OSRestoreInterrupts(mask);
|
||||
}
|
||||
|
||||
void AXFXReverbHiExpCallback(AXFX_BUFFERUPDATE* bufferUpdate, AXFX_REVERBHI_EXP* reverb) {
|
||||
u32 ch, i;
|
||||
u32 samp;
|
||||
s32* input[3];
|
||||
f32 data;
|
||||
f32 output[3];
|
||||
f32* earlyLine;
|
||||
f32 earlyOut;
|
||||
f32* preDelayLine;
|
||||
f32 preDelayOut;
|
||||
f32 filterOut;
|
||||
f32* combLine;
|
||||
f32 combOutOne;
|
||||
f32* allpass;
|
||||
f32 outTmp;
|
||||
f32 allpassIn;
|
||||
f32 allpassCoef;
|
||||
f32 lpfOut;
|
||||
f32 lpfCoef1;
|
||||
f32 lpfCoef2;
|
||||
f32 fusedOut[3];
|
||||
f32 fusedGain;
|
||||
f32 crosstalkGain;
|
||||
f32 crosstalkL;
|
||||
f32 crosstalkR;
|
||||
f32 crosstalkS;
|
||||
s32* inBusData[3];
|
||||
s32* outBusData[3];
|
||||
|
||||
if (reverb->active != 0) {
|
||||
reverb->active &= ~2;
|
||||
return;
|
||||
}
|
||||
|
||||
input[0] = bufferUpdate->left;
|
||||
input[1] = bufferUpdate->right;
|
||||
input[2] = bufferUpdate->surround;
|
||||
|
||||
if (reverb->busIn != NULL) {
|
||||
inBusData[0] = reverb->busIn->left;
|
||||
inBusData[1] = reverb->busIn->right;
|
||||
inBusData[2] = reverb->busIn->surround;
|
||||
}
|
||||
|
||||
if (reverb->busOut != NULL) {
|
||||
outBusData[0] = reverb->busOut->left;
|
||||
outBusData[1] = reverb->busOut->right;
|
||||
outBusData[2] = reverb->busOut->surround;
|
||||
}
|
||||
|
||||
lpfCoef1 = 1.0f - reverb->lpfCoef;
|
||||
lpfCoef2 = reverb->lpfCoef;
|
||||
allpassCoef = reverb->allpassCoef;
|
||||
fusedGain = reverb->fusedGain * 0.6f;
|
||||
crosstalkGain = reverb->crosstalk * 0.5f;
|
||||
|
||||
for (samp = 0; samp < 96; samp++) {
|
||||
for (ch = 0; ch < 3; ch++) {
|
||||
if (reverb->busIn != NULL) {
|
||||
data = (f32)(*(input[ch]) + *(inBusData[ch]++));
|
||||
} else {
|
||||
data = (f32)(*input[ch]);
|
||||
}
|
||||
|
||||
earlyLine = reverb->earlyLine[ch];
|
||||
earlyOut = earlyLine[reverb->earlyPos[0]] * reverb->earlyCoef[0] +
|
||||
earlyLine[reverb->earlyPos[1]] * reverb->earlyCoef[1] +
|
||||
earlyLine[reverb->earlyPos[2]] * reverb->earlyCoef[2];
|
||||
|
||||
#if SDK_AUG2010
|
||||
earlyLine[reverb->earlyPos[2]] = data;
|
||||
#endif
|
||||
|
||||
if (reverb->preDelayLength != 0) {
|
||||
preDelayLine = reverb->preDelayLine[ch];
|
||||
preDelayOut = preDelayLine[reverb->preDelayPos];
|
||||
preDelayLine[reverb->preDelayPos] = data;
|
||||
} else {
|
||||
preDelayOut = data;
|
||||
}
|
||||
|
||||
filterOut = 0.0f;
|
||||
for (i = 0; i < 3; i++) {
|
||||
combLine = reverb->combLine[ch][i];
|
||||
combOutOne = combLine[reverb->combPos[i]];
|
||||
combLine[reverb->combPos[i]] = preDelayOut + (combOutOne * reverb->combCoef[i]);
|
||||
filterOut += combOutOne;
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
allpass = reverb->allpassLine[ch][i];
|
||||
outTmp = allpass[reverb->allpassPos[i]];
|
||||
allpassIn = filterOut + outTmp * allpassCoef;
|
||||
allpass[reverb->allpassPos[i]] = allpassIn;
|
||||
filterOut = outTmp - allpassIn * allpassCoef;
|
||||
}
|
||||
|
||||
lpfOut = lpfCoef1 * filterOut + lpfCoef2 * reverb->lastLpfOut[ch];
|
||||
reverb->lastLpfOut[ch] = lpfOut;
|
||||
allpass = reverb->lastAllpassLine[ch];
|
||||
outTmp = allpass[reverb->lastAllpassPos[ch]];
|
||||
allpassIn = lpfOut + outTmp * allpassCoef;
|
||||
allpass[reverb->lastAllpassPos[ch]] = allpassIn;
|
||||
fusedOut[ch] = outTmp - allpassIn * allpassCoef;
|
||||
if (++reverb->lastAllpassPos[ch] >= reverb->lastAllpassLength[ch]) {
|
||||
reverb->lastAllpassPos[ch] = 0;
|
||||
}
|
||||
|
||||
fusedOut[ch] *= fusedGain;
|
||||
fusedOut[ch] += earlyOut;
|
||||
}
|
||||
|
||||
crosstalkL = fusedOut[1] + fusedOut[2];
|
||||
crosstalkR = fusedOut[0] + fusedOut[2];
|
||||
crosstalkS = fusedOut[0] + fusedOut[1];
|
||||
|
||||
output[0] = fusedOut[0] + crosstalkL * crosstalkGain;
|
||||
output[1] = fusedOut[1] + crosstalkR * crosstalkGain;
|
||||
output[2] = fusedOut[2] + crosstalkS * crosstalkGain;
|
||||
|
||||
*(input[0]++) = (s32)(output[0] * reverb->outGain);
|
||||
*(input[1]++) = (s32)(output[1] * reverb->outGain);
|
||||
*(input[2]++) = (s32)(output[2] * reverb->outGain);
|
||||
|
||||
if (reverb->busOut != NULL) {
|
||||
*(outBusData[0]++) = (s32)(output[0] * reverb->sendGain);
|
||||
*(outBusData[1]++) = (s32)(output[1] * reverb->sendGain);
|
||||
*(outBusData[2]++) = (s32)(output[2] * reverb->sendGain);
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (++reverb->earlyPos[i] >= reverb->earlyLength) {
|
||||
reverb->earlyPos[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (reverb->preDelayLength != 0) {
|
||||
if (++reverb->preDelayPos >= reverb->preDelayLength) {
|
||||
reverb->preDelayPos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (++reverb->combPos[i] >= reverb->combLength[i]) {
|
||||
reverb->combPos[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (++reverb->allpassPos[i] >= reverb->allpassLength[i]) {
|
||||
reverb->allpassPos[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static BOOL __AllocDelayLine(AXFX_REVERBHI_EXP* reverb) {
|
||||
u32 ch, i;
|
||||
|
||||
for (ch = 0; ch < 3; ch++) {
|
||||
reverb->earlyLine[ch] = (f32*)__AXFXAlloc(sizeof(f32) * reverb->earlyMaxLength);
|
||||
if (reverb->earlyLine[ch] == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (reverb->preDelayMaxLength != 0) {
|
||||
reverb->preDelayLine[ch] = (f32*)__AXFXAlloc(sizeof(f32) * reverb->preDelayMaxLength);
|
||||
if (reverb->preDelayLine[ch] == NULL)
|
||||
return FALSE;
|
||||
} else {
|
||||
reverb->preDelayLine[ch] = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
reverb->combLine[ch][i] = (f32*)__AXFXAlloc(sizeof(f32) * reverb->combMaxLength[i]);
|
||||
if (reverb->combLine[ch][i] == NULL)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
reverb->allpassLine[ch][i] = (f32*)__AXFXAlloc(sizeof(f32) * reverb->allpassMaxLength[i]);
|
||||
if (reverb->allpassLine[ch][i] == NULL)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
reverb->lastAllpassLine[ch] = (f32*)__AXFXAlloc(sizeof(f32) * reverb->lastAllpassMaxLength[ch]);
|
||||
if (reverb->lastAllpassLine[ch] == NULL)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void __BzeroDelayLines(AXFX_REVERBHI_EXP* reverb) {
|
||||
u32 ch, i;
|
||||
|
||||
for (ch = 0; ch < 3; ch++) {
|
||||
if (reverb->earlyLine[ch] != NULL) {
|
||||
memset(reverb->earlyLine[ch], 0, sizeof(f32) * reverb->earlyMaxLength);
|
||||
}
|
||||
|
||||
if (reverb->preDelayLine[ch] != NULL) {
|
||||
memset(reverb->preDelayLine[ch], 0, sizeof(f32) * reverb->preDelayMaxLength);
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (reverb->combLine[ch][i] != NULL) {
|
||||
memset(reverb->combLine[ch][i], 0, sizeof(f32) * reverb->combMaxLength[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (reverb->allpassLine[ch][i] != NULL) {
|
||||
memset(reverb->allpassLine[ch][i], 0, sizeof(f32) * reverb->allpassMaxLength[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (reverb->lastAllpassLine[ch] != NULL) {
|
||||
memset(reverb->lastAllpassLine[ch], 0, sizeof(f32) * reverb->lastAllpassMaxLength[ch]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void __FreeDelayLine(AXFX_REVERBHI_EXP* reverb) {
|
||||
u32 ch, i;
|
||||
|
||||
for (ch = 0; ch < 3; ch++) {
|
||||
if (reverb->earlyLine[ch] != NULL) {
|
||||
__AXFXFree(reverb->earlyLine[ch]);
|
||||
reverb->earlyLine[ch] = NULL;
|
||||
}
|
||||
|
||||
if (reverb->preDelayLine[ch] != NULL) {
|
||||
__AXFXFree(reverb->preDelayLine[ch]);
|
||||
reverb->preDelayLine[ch] = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (reverb->combLine[ch][i] != NULL) {
|
||||
__AXFXFree(reverb->combLine[ch][i]);
|
||||
reverb->combLine[ch][i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (reverb->allpassLine[ch][i] != NULL) {
|
||||
__AXFXFree(reverb->allpassLine[ch][i]);
|
||||
reverb->allpassLine[ch][i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (reverb->lastAllpassLine[ch] != NULL) {
|
||||
__AXFXFree(reverb->lastAllpassLine[ch]);
|
||||
reverb->lastAllpassLine[ch] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
f32 dummy_1() {
|
||||
return -3.0f;
|
||||
}
|
||||
|
||||
static BOOL __InitParams(AXFX_REVERBHI_EXP* reverb) {
|
||||
u32 ch, i;
|
||||
|
||||
if (reverb->earlyMode >= 8)
|
||||
return FALSE;
|
||||
|
||||
if (reverb->preDelayTime < 0.0f || reverb->preDelayTime > reverb->preDelayTimeMax)
|
||||
return FALSE;
|
||||
|
||||
if (reverb->fusedMode >= 6)
|
||||
return FALSE;
|
||||
|
||||
if (reverb->fusedTime < 0.0f)
|
||||
return FALSE;
|
||||
|
||||
if (reverb->coloration < 0.0f || reverb->coloration > 1.0f)
|
||||
return FALSE;
|
||||
|
||||
if (reverb->damping < 0.0f || reverb->damping > 1.0f)
|
||||
return FALSE;
|
||||
|
||||
if (reverb->crosstalk < 0.0f || reverb->crosstalk > 1.0f)
|
||||
return FALSE;
|
||||
|
||||
if (reverb->earlyGain < 0.0f || reverb->earlyGain > 1.0f)
|
||||
return FALSE;
|
||||
|
||||
if (reverb->fusedGain < 0.0f || reverb->fusedGain > 1.0f)
|
||||
return FALSE;
|
||||
|
||||
if (reverb->outGain < 0.0f || reverb->outGain > 1.0f)
|
||||
return FALSE;
|
||||
|
||||
if (reverb->sendGain < 0.0f || reverb->sendGain > 1.0f)
|
||||
return FALSE;
|
||||
|
||||
reverb->earlyLength = __EarlySizeTable[reverb->earlyMode][2];
|
||||
for (i = 0; i < 3; i++) {
|
||||
reverb->earlyPos[i] = reverb->earlyLength - __EarlySizeTable[reverb->earlyMode][i];
|
||||
reverb->earlyCoef[i] = __EarlyCoefTable[reverb->earlyMode][i] * reverb->earlyGain * 0.6f;
|
||||
}
|
||||
|
||||
reverb->preDelayPos = 0;
|
||||
reverb->preDelayLength = (u32)(reverb->preDelayTime * (f32)32000);
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
reverb->combPos[i] = 0;
|
||||
reverb->combLength[i] = __FilterSizeTable[reverb->fusedMode][i];
|
||||
reverb->combCoef[i] = pow(10.0f, (-3.0f * (f32)(reverb->combLength[i]) / (f32)(reverb->fusedTime * 32000)));
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
reverb->allpassPos[i] = 0;
|
||||
reverb->allpassLength[i] = __FilterSizeTable[reverb->fusedMode][3 + i];
|
||||
}
|
||||
|
||||
for (ch = 0; ch < 3; ch++) {
|
||||
reverb->lastAllpassPos[ch] = 0;
|
||||
reverb->lastAllpassLength[ch] = __FilterSizeTable[reverb->fusedMode][5 + ch];
|
||||
}
|
||||
|
||||
reverb->allpassCoef = reverb->coloration;
|
||||
reverb->lpfCoef = 1.0f - reverb->damping;
|
||||
if (reverb->lpfCoef > 0.95f)
|
||||
reverb->lpfCoef = 0.95f;
|
||||
|
||||
for (ch = 0; ch < 3; ch++) {
|
||||
reverb->lastLpfOut[ch] = 0.0f;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -260,8 +260,8 @@ namespace homebutton {
|
||||
/* 0x5D0 */ nw4hbm::snd::SoundHeap* mpSoundHeap;
|
||||
/* 0x5D4 */ nw4hbm::snd::SoundHandle* mpSoundHandle;
|
||||
/* 0x5D8 */ u16 mAppVolume[3];
|
||||
/* 0x5E0 */ AXFXAllocFunc mAxFxAlloc;
|
||||
/* 0x5E4 */ AXFXFreeFunc mAxFxFree;
|
||||
/* 0x5E0 */ AXFXAllocHook mAxFxAlloc;
|
||||
/* 0x5E4 */ AXFXFreeHook mAxFxFree;
|
||||
/* 0x5E8 */ AXFX_REVERBHI mAxFxReverb;
|
||||
/* 0x748 */ AXAuxCallback mAuxCallback;
|
||||
/* 0x74C */ void* mpAuxContext;
|
||||
|
||||
@@ -23,10 +23,12 @@ void IPCInit(void) {
|
||||
Initialized = TRUE;
|
||||
}
|
||||
|
||||
#if SDK_AUG2010
|
||||
void IPCReInit(void) {
|
||||
Initialized = FALSE;
|
||||
IPCInit();
|
||||
}
|
||||
#endif
|
||||
|
||||
u32 IPCReadReg(u32 regIdx) {
|
||||
u32 reg = __IPCRegs[regIdx];
|
||||
|
||||
+124
-14
@@ -1,17 +1,40 @@
|
||||
#include <revolution.h>
|
||||
#include <cstring>
|
||||
|
||||
static u32 IpcReqPtrArray[96] = {0};
|
||||
static u32 IpcReqArray[0x300] = {0};
|
||||
static OSTime IpcStartTimeArray[96];
|
||||
static u8 IpcHandlePathBuf[0x1800];
|
||||
static u8 IpcOpenPathBuf[0x1200];
|
||||
#if SDK_AUG2010
|
||||
#define IPC_REQ_MAX 0x60
|
||||
#define IPC_PATH_MAX 0x30
|
||||
#else
|
||||
#define IPC_REQ_MAX 0x20
|
||||
#endif
|
||||
|
||||
#if SDK_AUG2010
|
||||
// either release or debug config does something weird to swap the order of these in .bss
|
||||
#if VERSION == VERSION_SHIELD_DEBUG
|
||||
static IOSResourceRequest* IpcReqPtrArray[IPC_REQ_MAX] = {0};
|
||||
static IOSResourceRequest IpcReqArray[IPC_REQ_MAX] = {0};
|
||||
#else
|
||||
static IOSResourceRequest IpcReqArray[IPC_REQ_MAX] = {0};
|
||||
static IOSResourceRequest* IpcReqPtrArray[IPC_REQ_MAX] = {0};
|
||||
#endif
|
||||
static OSTime IpcStartTimeArray[IPC_REQ_MAX];
|
||||
static char IpcHandlePathBuf[0x80][0x30];
|
||||
static char IpcOpenPathBuf[IPC_REQ_MAX][0x30];
|
||||
#else
|
||||
static s32 IpcFdArray[IPC_REQ_MAX] = {0};
|
||||
static u32 IpcReqPtrArray[IPC_REQ_MAX] = {0};
|
||||
#endif
|
||||
|
||||
static u32 IpcNumPendingReqs = 0;
|
||||
static u32 IpcNumUnIssuedReqs = 0;
|
||||
|
||||
static void AddReqInfo(void* req);
|
||||
static void DelReqInfo(void* req);
|
||||
#if SDK_AUG2010
|
||||
static void AddReqInfo(IOSResourceRequest* req);
|
||||
static void DelReqInfo(IOSResourceRequest* req);
|
||||
#else
|
||||
static void AddReqInfo(IOSResourceRequest* req, s32 fd);
|
||||
static void DelReqInfo(IOSResourceRequest* req, s32 fd);
|
||||
#endif
|
||||
|
||||
void IPCiProfInit(void) {
|
||||
u32 i;
|
||||
@@ -19,20 +42,31 @@ void IPCiProfInit(void) {
|
||||
IpcNumPendingReqs = 0;
|
||||
IpcNumUnIssuedReqs = 0;
|
||||
|
||||
for (i = 0; i < 96; ++i) {
|
||||
for (i = 0; i < IPC_REQ_MAX; ++i) {
|
||||
#if SDK_AUG2010
|
||||
IpcReqPtrArray[i] = 0;
|
||||
IpcStartTimeArray[i] = 0;
|
||||
#else
|
||||
IpcReqPtrArray[i] = 0;
|
||||
IpcFdArray[i] = -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if SDK_AUG2010
|
||||
memset(IpcHandlePathBuf, 0, sizeof(IpcHandlePathBuf));
|
||||
memset(IpcOpenPathBuf, 0, sizeof(IpcOpenPathBuf));
|
||||
memset(IpcReqArray, 0, sizeof(IpcReqArray));
|
||||
#endif
|
||||
}
|
||||
|
||||
void IPCiProfQueueReq(void* req, s32 handle) {
|
||||
++IpcNumPendingReqs;
|
||||
++IpcNumUnIssuedReqs;
|
||||
AddReqInfo(req);
|
||||
#if SDK_AUG2010
|
||||
AddReqInfo((IOSResourceRequest*)req);
|
||||
#else
|
||||
AddReqInfo((IOSResourceRequest*)req, handle);
|
||||
#endif
|
||||
}
|
||||
|
||||
void IPCiProfAck(void) {
|
||||
@@ -41,13 +75,89 @@ void IPCiProfAck(void) {
|
||||
|
||||
void IPCiProfReply(void* req, s32 handle) {
|
||||
--IpcNumPendingReqs;
|
||||
DelReqInfo(req);
|
||||
#if SDK_AUG2010
|
||||
DelReqInfo((IOSResourceRequest*)req);
|
||||
#else
|
||||
DelReqInfo((IOSResourceRequest*)req, handle);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void AddReqInfo(void* ptr) {
|
||||
// NONMATCHING
|
||||
#if SDK_AUG2010
|
||||
static void AddReqInfo(IOSResourceRequest* req) {
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < IPC_REQ_MAX; i++) {
|
||||
if (!IpcReqPtrArray[i]) {
|
||||
BOOL irqEnabled = OSDisableInterrupts();
|
||||
|
||||
IpcReqPtrArray[i] = req;
|
||||
IpcReqArray[i] = *req;
|
||||
IpcStartTimeArray[i] = OSGetTime();
|
||||
if (IpcReqArray[i].cmd == 1) {
|
||||
const char* path_p_virt = (const char*)OSPhysicalToCached((u32)IpcReqArray[i].args.open.path);
|
||||
strncpy(IpcOpenPathBuf[i], path_p_virt,
|
||||
IPC_PATH_MAX - 1);
|
||||
IpcOpenPathBuf[i][IPC_PATH_MAX - 1] = '\0';
|
||||
IpcReqArray[i].args.open.path = (u8*)IpcOpenPathBuf[i];
|
||||
}
|
||||
|
||||
OSRestoreInterrupts(irqEnabled);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void DelReqInfo(void* ptr) {
|
||||
// NONMATCHING
|
||||
static void DelReqInfo(IOSResourceRequest* req) {
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < IPC_REQ_MAX; i++) {
|
||||
if (req == IpcReqPtrArray[i] && req->handle == IpcReqArray[i].cmd) {
|
||||
BOOL irqEnabled = OSDisableInterrupts();
|
||||
|
||||
if (IpcReqArray[i].cmd == 1) {
|
||||
if (req->status >= 0) {
|
||||
strncpy(IpcHandlePathBuf[req->status],
|
||||
(const char*)IpcReqArray[i].args.open.path, IPC_PATH_MAX - 1);
|
||||
IpcHandlePathBuf[req->status][IPC_PATH_MAX - 1] = '\0';
|
||||
memset(&IpcOpenPathBuf[i], 0, IPC_PATH_MAX);
|
||||
}
|
||||
}
|
||||
|
||||
if (IpcReqArray[i].cmd == 2) {
|
||||
memset(&IpcHandlePathBuf[IpcReqArray[i].handle], 0, IPC_PATH_MAX);
|
||||
}
|
||||
|
||||
IpcReqPtrArray[i] = NULL;
|
||||
memset(&IpcReqArray[i], 0, sizeof(IOSResourceRequest));
|
||||
IpcStartTimeArray[i] = 0;
|
||||
|
||||
OSRestoreInterrupts(irqEnabled);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
static void AddReqInfo(IOSResourceRequest* ptr, s32 fd) {
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < 32; ++i) {
|
||||
if (IpcReqPtrArray[i] == 0 && IpcFdArray[i] == -1) {
|
||||
IpcReqPtrArray[i] = (u32)ptr;
|
||||
IpcFdArray[i] = fd;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void DelReqInfo(IOSResourceRequest* ptr, s32 fd) {
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < 32; ++i) {
|
||||
if (IpcReqPtrArray[i] == (u32)ptr && IpcFdArray[i] == fd) {
|
||||
IpcReqPtrArray[i] = 0;
|
||||
IpcFdArray[i] = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -4,6 +4,14 @@
|
||||
#include <revolution/ipc.h>
|
||||
#include <cstring>
|
||||
|
||||
#if SDK_AUG2010
|
||||
#define RESPONSE_REQ_BUF_LEN 0x30
|
||||
#define IPC_BUF_CNT 0x40
|
||||
#else
|
||||
#define RESPONSE_REQ_BUF_LEN 0x10
|
||||
#define IPC_BUF_CNT 0x10
|
||||
#endif
|
||||
|
||||
/* macro for matching __ipcQueueRequest */
|
||||
#define diff(a, b) \
|
||||
((a) < (b)) ? ((u32)0xffffffff - (b) + (a) + 1) : ((a) - (b))
|
||||
@@ -23,9 +31,11 @@ typedef struct IOSRpcRequest {
|
||||
} IOSRpcRequest;
|
||||
|
||||
static IOSRpcRequest* __relnchRpc = 0;
|
||||
#if SDK_AUG2010
|
||||
static IOSRpcRequest* __relnchRpcSave = 0;
|
||||
#endif
|
||||
|
||||
#define ROUNDUP(sz) (((u32)(sz) + 31) & ~(u32)(31))
|
||||
#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);
|
||||
|
||||
@@ -34,7 +44,7 @@ static struct {
|
||||
u32 wcount;
|
||||
u32 rptr;
|
||||
u32 wptr;
|
||||
IOSResourceRequest* buf[48];
|
||||
IOSResourceRequest* buf[RESPONSE_REQ_BUF_LEN];
|
||||
} __responses;
|
||||
|
||||
static OSAlarm __timeout_alarm;
|
||||
@@ -93,6 +103,10 @@ static void __ipcSendRequest(void) {
|
||||
}
|
||||
|
||||
if (rpc->relaunch_flag) {
|
||||
#if !SDK_AUG2010
|
||||
__relnchFl = 1;
|
||||
__relnchRpc = rpc;
|
||||
#endif
|
||||
__mailboxAck--;
|
||||
}
|
||||
|
||||
@@ -149,7 +163,12 @@ void IpcReplyHandler(__OSInterrupt interrupt, OSContext* context) {
|
||||
DCInvalidateRange(v->vector[i].base, v->vector[i].length);
|
||||
}
|
||||
|
||||
if (__relnchFl && __relnchRpcSave == rep) {
|
||||
#if SDK_AUG2010
|
||||
if (__relnchFl && __relnchRpcSave == rep)
|
||||
#else
|
||||
if (__relnchFl && __relnchRpc == rep)
|
||||
#endif
|
||||
{
|
||||
__relnchFl = 0;
|
||||
|
||||
if (__mailboxAck < 1) {
|
||||
@@ -229,7 +248,7 @@ IOSError IPCCltInit(void) {
|
||||
|
||||
IPCInit();
|
||||
|
||||
i = ROUNDUP(64 * (ROUNDUP(sizeof(IOSRpcRequest)) + 64));
|
||||
i = ROUNDUP(IPC_BUF_CNT * (ROUNDUP(sizeof(IOSRpcRequest)) + 64));
|
||||
bufferLo = IPCGetBufferLo();
|
||||
|
||||
if ((void*)((u8*)bufferLo + i) > IPCGetBufferHi()) {
|
||||
@@ -245,18 +264,21 @@ IOSError IPCCltInit(void) {
|
||||
|
||||
IPCWriteReg(1, (1 << 5 | 1<< 4 | 1 << 3));
|
||||
IPCiProfInit();
|
||||
#if SDK_AUG2010
|
||||
OSCreateAlarm(&__timeout_alarm);
|
||||
#endif
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if SDK_AUG2010
|
||||
IOSError IPCCltReInit(void) {
|
||||
u32 i;
|
||||
IOSError ret = 0;
|
||||
void* bufferLo;
|
||||
|
||||
i = ROUNDUP(64 * ROUNDUP(sizeof(IOSRpcRequest)));
|
||||
i = ROUNDUP(IPC_BUF_CNT * ROUNDUP(sizeof(IOSRpcRequest)));
|
||||
bufferLo = IPCGetBufferLo();
|
||||
|
||||
if ((void*)((u8*)bufferLo + i) > IPCGetBufferHi()) {
|
||||
@@ -270,6 +292,7 @@ IOSError IPCCltReInit(void) {
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static IOSError __ios_Ipc1(IOSFd fd, u32 cmd, IOSIpcCb cb, void* cbArg, IOSRpcRequest** rpc) {
|
||||
IOSError ret = 0;
|
||||
@@ -773,6 +796,7 @@ IOSError IOS_IoctlvReboot(IOSFd fd, s32 cmd, u32 readCount, u32 writeCount, IOSI
|
||||
u32 inten;
|
||||
IOSResourceRequest* req;
|
||||
|
||||
#if SDK_AUG2010
|
||||
inten = OSDisableInterrupts();
|
||||
|
||||
if (__relnchFl) {
|
||||
@@ -783,6 +807,7 @@ IOSError IOS_IoctlvReboot(IOSFd fd, s32 cmd, u32 readCount, u32 writeCount, IOSI
|
||||
|
||||
__relnchFl = 1;
|
||||
OSRestoreInterrupts(inten);
|
||||
#endif
|
||||
|
||||
ret = __ios_Ipc1(fd, 7, 0, 0, &rpc);
|
||||
|
||||
@@ -790,15 +815,18 @@ IOSError IOS_IoctlvReboot(IOSFd fd, s32 cmd, u32 readCount, u32 writeCount, IOSI
|
||||
goto err;
|
||||
}
|
||||
|
||||
#if SDK_AUG2010
|
||||
__relnchRpcSave = rpc;
|
||||
#endif
|
||||
rpc->relaunch_flag = 1;
|
||||
|
||||
ret = __ios_Ioctlv(rpc, cmd, readCount, writeCount, vect);
|
||||
|
||||
|
||||
if (ret != 0) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
#if SDK_AUG2010
|
||||
memcpy(&__rpcBuf, rpc, sizeof(IOSRpcRequest));
|
||||
__relnchRpc = (IOSRpcRequest*)&__rpcBuf;
|
||||
req = &rpc->request;
|
||||
@@ -821,14 +849,19 @@ IOSError IOS_IoctlvReboot(IOSFd fd, s32 cmd, u32 readCount, u32 writeCount, IOSI
|
||||
OSSleepThread(&__relnchRpc->thread_queue);
|
||||
OSRestoreInterrupts(inten);
|
||||
ret = (&__relnchRpc->request)->status;
|
||||
#else
|
||||
ret = __ios_Ipc2(rpc, NULL);
|
||||
#endif
|
||||
|
||||
err:
|
||||
#if SDK_AUG2010
|
||||
__relnchFl = 0;
|
||||
__relnchRpcSave = NULL;
|
||||
|
||||
if (rpc && (ret != 0)) {
|
||||
ipcFree(rpc);
|
||||
}
|
||||
#endif
|
||||
|
||||
finish:
|
||||
return ret;
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
#include <revolution/mem/allocator.h>
|
||||
#include <revolution/mem/expHeap.h>
|
||||
|
||||
static void* AllocatorAllocForExpHeap_(MEMAllocator *pAllocator, u32 size) {
|
||||
return MEMAllocFromExpHeapEx(pAllocator->pHeap, size, pAllocator->heapParam1);
|
||||
}
|
||||
|
||||
static void AllocatorFreeForExpHeap_(MEMAllocator *pAllocator, void *pBlock) {
|
||||
MEMFreeToExpHeap(pAllocator->pHeap, pBlock);
|
||||
}
|
||||
|
||||
void* MEMAllocFromAllocator(MEMAllocator *pAllocator, u32 size) {
|
||||
return (*pAllocator->pFunc->pfAlloc)(pAllocator, size);
|
||||
}
|
||||
|
||||
void MEMFreeToAllocator(MEMAllocator *pAllocator, void *pBlock) {
|
||||
(*pAllocator->pFunc->pfFree)(pAllocator, pBlock);
|
||||
}
|
||||
|
||||
void MEMInitAllocatorForExpHeap(MEMAllocator *pAllocator, MEMHeapHandle handle, int align) {
|
||||
static const MEMAllocatorFunc sAllocatorFunc =
|
||||
{
|
||||
AllocatorAllocForExpHeap_,
|
||||
AllocatorFreeForExpHeap_,
|
||||
};
|
||||
|
||||
pAllocator->pFunc = &sAllocatorFunc;
|
||||
pAllocator->pHeap = handle;
|
||||
pAllocator->heapParam1 = align;
|
||||
pAllocator->heapParam2 = 0;
|
||||
}
|
||||
@@ -0,0 +1,380 @@
|
||||
#include <revolution/mem/expHeap.h>
|
||||
#include <revolution/mem/heapCommon.h>
|
||||
|
||||
#define FillFreeMemory(pHeapHd, address, size) ((void)0)
|
||||
#define FillNoUseMemory(pHeapHd, address, size) ((void)0)
|
||||
|
||||
#define RoundUp(value, alignment) (((value) + ((alignment) - 1)) & ~((alignment) - 1))
|
||||
#define RoundUpPtr(ptr, alignment) ((void*)RoundUp(GetUIntPtr(ptr), (alignment)))
|
||||
#define RoundDown(value, alignment) ((value) & ~((alignment) - 1))
|
||||
#define RoundDownPtr(ptr, alignment) ((void*)RoundDown(GetUIntPtr(ptr), (alignment)))
|
||||
|
||||
typedef struct MemRegion MemRegion;
|
||||
|
||||
struct MemRegion {
|
||||
void* start;
|
||||
void* end;
|
||||
};
|
||||
|
||||
static inline void* GetMemPtrForMBlock_(MEMiExpHeapMBlockHead* pMBlkHd) {
|
||||
return AddU32ToPtr(pMBlkHd, sizeof(MEMiExpHeapMBlockHead));
|
||||
}
|
||||
|
||||
static inline void* GetMBlockEndAddr_(MEMiExpHeapMBlockHead* pMBHead) {
|
||||
return AddU32ToPtr(GetMemPtrForMBlock_(pMBHead), pMBHead->blockSize);
|
||||
}
|
||||
|
||||
static inline u16 GetAllocMode_(MEMiExpHeapHead* pEHHead) {
|
||||
return pEHHead->feature.fields.allocMode;
|
||||
}
|
||||
|
||||
static MEMiExpHeapMBlockHead* InitMBlock_(MemRegion* pRegion, u16 signature) {
|
||||
MEMiExpHeapMBlockHead* block = (MEMiExpHeapMBlockHead*)pRegion->start;
|
||||
|
||||
block->signature = signature;
|
||||
block->attribute.val = 0;
|
||||
block->blockSize = GetOffsetFromPtr(GetMemPtrForMBlock_(block), pRegion->end);
|
||||
|
||||
block->prev = NULL;
|
||||
block->next = NULL;
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
static inline void SetAllocDirForMBlock_(MEMiExpHeapMBlockHead* pMBHead, u16 mode) {
|
||||
pMBHead->attribute.fields.allocDir = mode;
|
||||
}
|
||||
|
||||
static inline u16 GetAlignmentForMBlock_(const MEMiExpHeapMBlockHead* pMBlkHd) {
|
||||
return pMBlkHd->attribute.fields.alignment;
|
||||
}
|
||||
|
||||
static inline void SetAlignmentForMBlock_(MEMiExpHeapMBlockHead* pMBlkHd, u16 alignment) {
|
||||
pMBlkHd->attribute.fields.alignment = alignment;
|
||||
}
|
||||
|
||||
static inline void SetGroupIDForMBlock_(MEMiExpHeapMBlockHead* pMBHead, u16 id) {
|
||||
pMBHead->attribute.fields.groupID = (u8)id;
|
||||
}
|
||||
|
||||
static void GetRegionOfMBlock_(MemRegion* region, MEMiExpHeapMBlockHead* block) {
|
||||
region->start = SubU32ToPtr(block, GetAlignmentForMBlock_(block));
|
||||
region->end = GetMBlockEndAddr_(block);
|
||||
}
|
||||
|
||||
static inline MEMiHeapHead* GetHeapHeadPtrFromExpHeapHead_(MEMiExpHeapHead* pEHHead) {
|
||||
return (MEMiHeapHead*)SubU32ToPtr(pEHHead, sizeof(MEMiHeapHead));
|
||||
}
|
||||
|
||||
static MEMiExpHeapMBlockHead* InsertMBlock_(MEMiExpMBlockList* list, MEMiExpHeapMBlockHead* target, MEMiExpHeapMBlockHead* prev) {
|
||||
MEMiExpHeapMBlockHead* next;
|
||||
|
||||
target->prev = prev;
|
||||
if (prev) {
|
||||
next = prev->next;
|
||||
prev->next = target;
|
||||
} else {
|
||||
next = list->head;
|
||||
list->head = target;
|
||||
}
|
||||
|
||||
target->next = next;
|
||||
if (next) {
|
||||
next->prev = target;
|
||||
} else {
|
||||
list->tail = target;
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
static inline void AppendMBlock_(MEMiExpMBlockList* list, MEMiExpHeapMBlockHead* block) {
|
||||
(void)InsertMBlock_(list, block, list->tail);
|
||||
}
|
||||
|
||||
static inline MEMiExpHeapHead* GetExpHeapHeadPtrFromHeapHead_(MEMiHeapHead* pHHead) {
|
||||
return (MEMiExpHeapHead*)AddU32ToPtr(pHHead, sizeof(MEMiHeapHead));
|
||||
}
|
||||
|
||||
static MEMiExpHeapMBlockHead* RemoveMBlock_(MEMiExpMBlockList* list, MEMiExpHeapMBlockHead* block) {
|
||||
MEMiExpHeapMBlockHead* const prev = block->prev;
|
||||
MEMiExpHeapMBlockHead* const next = block->next;
|
||||
|
||||
if (prev) {
|
||||
prev->next = next;
|
||||
} else {
|
||||
list->head = next;
|
||||
}
|
||||
|
||||
if (next) {
|
||||
next->prev = prev;
|
||||
} else {
|
||||
list->tail = prev;
|
||||
}
|
||||
|
||||
return prev;
|
||||
}
|
||||
|
||||
static inline MEMiExpHeapMBlockHead* InitFreeMBlock_(MemRegion* pRegion) {
|
||||
return InitMBlock_(pRegion, 'FR');
|
||||
}
|
||||
|
||||
static inline void SetAllocMode_(MEMiExpHeapHead* pEHHead, u16 mode) {
|
||||
pEHHead->feature.fields.allocMode = mode;
|
||||
}
|
||||
|
||||
static MEMiHeapHead* InitExpHeap_(void* startAddress, void* endAddress, u16 optFlag) {
|
||||
MEMiHeapHead* pHeapHd = (MEMiHeapHead*)startAddress;
|
||||
MEMiExpHeapHead* pExpHeapHd = GetExpHeapHeadPtrFromHeapHead_(pHeapHd);
|
||||
|
||||
MEMiInitHeapHead(pHeapHd, 'EXPH', AddU32ToPtr(pExpHeapHd, sizeof(MEMiExpHeapHead)), endAddress, optFlag);
|
||||
|
||||
pExpHeapHd->groupID = 0;
|
||||
pExpHeapHd->feature.val = 0;
|
||||
SetAllocMode_(pExpHeapHd, 0);
|
||||
|
||||
{
|
||||
MEMiExpHeapMBlockHead* pMBHead;
|
||||
MemRegion region;
|
||||
|
||||
region.start = pHeapHd->heapStart;
|
||||
region.end = pHeapHd->heapEnd;
|
||||
pMBHead = InitFreeMBlock_(®ion);
|
||||
pExpHeapHd->mbFreeList.head = pMBHead;
|
||||
pExpHeapHd->mbFreeList.tail = pMBHead;
|
||||
pExpHeapHd->mbUsedList.head = NULL;
|
||||
pExpHeapHd->mbUsedList.tail = NULL;
|
||||
|
||||
return pHeapHd;
|
||||
}
|
||||
}
|
||||
|
||||
static void* AllocUsedBlockFromFreeBlock_(MEMiExpHeapHead* pEHHead, MEMiExpHeapMBlockHead* pMBHeadFree, void* mblock, u32 size, u16 direction) {
|
||||
MemRegion freeRgnT;
|
||||
MemRegion freeRgnB;
|
||||
MEMiExpHeapMBlockHead* pMBHeadFreePrev;
|
||||
|
||||
GetRegionOfMBlock_(&freeRgnT, pMBHeadFree);
|
||||
freeRgnB.end = freeRgnT.end;
|
||||
freeRgnB.start = AddU32ToPtr(mblock, size);
|
||||
freeRgnT.end = SubU32ToPtr(mblock, sizeof(MEMiExpHeapMBlockHead));
|
||||
|
||||
pMBHeadFreePrev = RemoveMBlock_(&pEHHead->mbFreeList, pMBHeadFree);
|
||||
|
||||
if ((GetOffsetFromPtr(freeRgnT.start, freeRgnT.end) < sizeof(MEMiExpHeapMBlockHead) + 4)
|
||||
#if SDK_AUG2010
|
||||
|| (direction == 0 && !pEHHead->feature.fields.useMarginOfAlign)
|
||||
#endif
|
||||
) {
|
||||
freeRgnT.end = freeRgnT.start;
|
||||
} else {
|
||||
pMBHeadFreePrev = InsertMBlock_(&pEHHead->mbFreeList, InitFreeMBlock_(&freeRgnT), pMBHeadFreePrev);
|
||||
}
|
||||
|
||||
if ((GetOffsetFromPtr(freeRgnB.start, freeRgnB.end) < sizeof(MEMiExpHeapMBlockHead) + 4)
|
||||
#if SDK_AUG2010
|
||||
|| (direction == 1 && !pEHHead->feature.fields.useMarginOfAlign)
|
||||
#endif
|
||||
) {
|
||||
freeRgnB.start = freeRgnB.end;
|
||||
} else {
|
||||
(void)InsertMBlock_(&pEHHead->mbFreeList, InitFreeMBlock_(&freeRgnB), pMBHeadFreePrev);
|
||||
}
|
||||
|
||||
FillAllocMemory(GetHeapHeadPtrFromExpHeapHead_(pEHHead), freeRgnT.end, GetOffsetFromPtr(freeRgnT.end, freeRgnB.start));
|
||||
|
||||
{
|
||||
MEMiExpHeapMBlockHead* pMBHeadNewUsed;
|
||||
MemRegion region;
|
||||
|
||||
region.start = SubU32ToPtr(mblock, sizeof(MEMiExpHeapMBlockHead));
|
||||
region.end = freeRgnB.start;
|
||||
|
||||
pMBHeadNewUsed = InitMBlock_(®ion, 'UD');
|
||||
SetAllocDirForMBlock_(pMBHeadNewUsed, direction);
|
||||
SetAlignmentForMBlock_(pMBHeadNewUsed, (u16)GetOffsetFromPtr(freeRgnT.end, pMBHeadNewUsed));
|
||||
SetGroupIDForMBlock_(pMBHeadNewUsed, pEHHead->groupID);
|
||||
AppendMBlock_(&pEHHead->mbUsedList, pMBHeadNewUsed);
|
||||
}
|
||||
|
||||
return mblock;
|
||||
}
|
||||
|
||||
static void* AllocFromHead_(MEMiHeapHead* pHeapHd, u32 size, int alignment) {
|
||||
MEMiExpHeapHead* pExpHeapHd = GetExpHeapHeadPtrFromHeapHead_(pHeapHd);
|
||||
|
||||
const BOOL bAllocFirst = GetAllocMode_(pExpHeapHd) == 0;
|
||||
|
||||
MEMiExpHeapMBlockHead* pMBlkHd = NULL;
|
||||
MEMiExpHeapMBlockHead* pMBlkHdFound = NULL;
|
||||
u32 foundSize = 0xffffffff;
|
||||
void* foundMBlock = NULL;
|
||||
|
||||
for (pMBlkHd = pExpHeapHd->mbFreeList.head; pMBlkHd; pMBlkHd = pMBlkHd->next) {
|
||||
void* const mblock = GetMemPtrForMBlock_(pMBlkHd);
|
||||
void* const reqMBlock = RoundUpPtr(mblock, alignment);
|
||||
const u32 offset = GetOffsetFromPtr(mblock, reqMBlock);
|
||||
|
||||
if (pMBlkHd->blockSize >= size + offset && foundSize > pMBlkHd->blockSize) {
|
||||
pMBlkHdFound = pMBlkHd;
|
||||
foundSize = pMBlkHd->blockSize;
|
||||
foundMBlock = reqMBlock;
|
||||
|
||||
if (bAllocFirst || foundSize == size) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!pMBlkHdFound) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return AllocUsedBlockFromFreeBlock_(pExpHeapHd, pMBlkHdFound, foundMBlock, size, 0);
|
||||
}
|
||||
|
||||
static void* AllocFromTail_(MEMiHeapHead* pHeapHd, u32 size, int alignment) {
|
||||
MEMiExpHeapHead* pExpHeapHd = GetExpHeapHeadPtrFromHeapHead_(pHeapHd);
|
||||
const BOOL bAllocFirst = GetAllocMode_(pExpHeapHd) == 0;
|
||||
MEMiExpHeapMBlockHead* pMBlkHd = NULL;
|
||||
MEMiExpHeapMBlockHead* pMBlkHdFound = NULL;
|
||||
u32 foundSize = 0xffffffff;
|
||||
void* foundMBlock = NULL;
|
||||
|
||||
for (pMBlkHd = pExpHeapHd->mbFreeList.tail; pMBlkHd; pMBlkHd = pMBlkHd->prev) {
|
||||
void* const mblock = GetMemPtrForMBlock_(pMBlkHd);
|
||||
void* const mblockEnd = AddU32ToPtr(mblock, pMBlkHd->blockSize);
|
||||
void* const reqMBlock = RoundDownPtr(SubU32ToPtr(mblockEnd, size), alignment);
|
||||
|
||||
if (ComparePtr(reqMBlock, mblock) >= 0 && foundSize > pMBlkHd->blockSize) {
|
||||
pMBlkHdFound = pMBlkHd;
|
||||
foundSize = pMBlkHd->blockSize;
|
||||
foundMBlock = reqMBlock;
|
||||
|
||||
if (bAllocFirst || foundSize == size) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!pMBlkHdFound) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return AllocUsedBlockFromFreeBlock_(pExpHeapHd, pMBlkHdFound, foundMBlock, size, 1);
|
||||
}
|
||||
|
||||
static BOOL RecycleRegion_(MEMiExpHeapHead* pEHHead, const MemRegion* pRegion) {
|
||||
MEMiExpHeapMBlockHead* pBlkPrFree = NULL;
|
||||
MemRegion freeRgn = *pRegion;
|
||||
|
||||
{
|
||||
MEMiExpHeapMBlockHead* pBlk;
|
||||
|
||||
for (pBlk = pEHHead->mbFreeList.head; pBlk; pBlk = pBlk->next) {
|
||||
if (pBlk < pRegion->start) {
|
||||
pBlkPrFree = pBlk;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pBlk == pRegion->end) {
|
||||
freeRgn.end = GetMBlockEndAddr_(pBlk);
|
||||
(void)RemoveMBlock_(&pEHHead->mbFreeList, pBlk);
|
||||
FillNoUseMemory(GetHeapHeadPtrFromExpHeapHead_(pEHHead), pBlk, sizeof(MEMiExpHeapMBlockHead));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pBlkPrFree && GetMBlockEndAddr_(pBlkPrFree) == pRegion->start) {
|
||||
freeRgn.start = pBlkPrFree;
|
||||
pBlkPrFree = RemoveMBlock_(&pEHHead->mbFreeList, pBlkPrFree);
|
||||
}
|
||||
|
||||
if (GetOffsetFromPtr(freeRgn.start, freeRgn.end) < sizeof(MEMiExpHeapMBlockHead)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
FillFreeMemory(GetHeapHeadPtrFromExpHeapHead_(pEHHead), pRegion->start, GetOffsetFromPtr(pRegion->start, pRegion->end));
|
||||
|
||||
(void)InsertMBlock_(&pEHHead->mbFreeList, InitFreeMBlock_(&freeRgn), pBlkPrFree);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
MEMHeapHandle MEMCreateExpHeapEx(void* startAddress, u32 size, u16 optFlag) {
|
||||
void* endAddress;
|
||||
|
||||
endAddress = RoundDownPtr(AddU32ToPtr(startAddress, size), 4);
|
||||
startAddress = RoundUpPtr(startAddress, 4);
|
||||
|
||||
if (GetUIntPtr(startAddress) > GetUIntPtr(endAddress) ||
|
||||
GetOffsetFromPtr(startAddress, endAddress) < sizeof(MEMiHeapHead) + sizeof(MEMiExpHeapHead) + sizeof(MEMiExpHeapMBlockHead) + 4) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
{
|
||||
MEMiHeapHead* pHeapHd = InitExpHeap_(startAddress, endAddress, optFlag);
|
||||
return pHeapHd;
|
||||
}
|
||||
}
|
||||
|
||||
void* MEMAllocFromExpHeapEx(MEMHeapHandle heap, u32 size, int alignment) {
|
||||
void* memory = NULL;
|
||||
|
||||
if (size == 0) {
|
||||
size = 1;
|
||||
}
|
||||
|
||||
size = RoundUp(size, 4);
|
||||
|
||||
LockHeap(heap);
|
||||
|
||||
if (alignment >= 0) {
|
||||
memory = AllocFromHead_(heap, size, alignment);
|
||||
} else {
|
||||
memory = AllocFromTail_(heap, size, -alignment);
|
||||
}
|
||||
|
||||
UnlockHeap(heap);
|
||||
|
||||
return memory;
|
||||
}
|
||||
|
||||
static inline MEMiExpHeapMBlockHead* GetMBlockHeadPtr_(void* memBlock) {
|
||||
return (MEMiExpHeapMBlockHead*)SubU32ToPtr(memBlock, sizeof(MEMiExpHeapMBlockHead));
|
||||
}
|
||||
|
||||
static inline MEMiExpHeapHead* GetExpHeapHeadPtrFromHandle_(MEMHeapHandle heap) {
|
||||
return (MEMiExpHeapHead*)GetExpHeapHeadPtrFromHeapHead_(heap);
|
||||
}
|
||||
|
||||
void MEMFreeToExpHeap(MEMHeapHandle heap, void* memBlock) {
|
||||
MEMiHeapHead* pHeapHd;
|
||||
MEMiExpHeapHead* pExpHeapHd;
|
||||
MEMiExpHeapMBlockHead* pMBHead;
|
||||
MemRegion region;
|
||||
|
||||
if (memBlock == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if SDK_AUG2010
|
||||
LockHeap(heap);
|
||||
#endif
|
||||
|
||||
pHeapHd = heap;
|
||||
pExpHeapHd = GetExpHeapHeadPtrFromHandle_(pHeapHd);
|
||||
pMBHead = GetMBlockHeadPtr_(memBlock);
|
||||
|
||||
|
||||
#if !SDK_AUG2010
|
||||
LockHeap(heap);
|
||||
#endif
|
||||
|
||||
GetRegionOfMBlock_(®ion, pMBHead);
|
||||
(void)RemoveMBlock_(&pExpHeapHd->mbUsedList, pMBHead);
|
||||
(void)RecycleRegion_(pExpHeapHd, ®ion);
|
||||
|
||||
UnlockHeap(heap);
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
#include <revolution/mem/heapCommon.h>
|
||||
#include <revolution/mem/list.h>
|
||||
|
||||
static MEMList sRootList;
|
||||
static BOOL sRootListInitialized = FALSE;
|
||||
static OSMutex sRootMutex;
|
||||
|
||||
static MEMiHeapHead* FindContainHeap_(MEMList* pList, const void* memBlock) {
|
||||
MEMiHeapHead* pHeapHd = NULL;
|
||||
while (NULL != (pHeapHd = (MEMiHeapHead*)MEMGetNextListObject(pList, pHeapHd))) {
|
||||
if (GetUIntPtr(pHeapHd->heapStart) <= GetUIntPtr(memBlock) && GetUIntPtr(memBlock) < GetUIntPtr(pHeapHd->heapEnd)) {
|
||||
MEMiHeapHead* pChildHeapHd = FindContainHeap_(&pHeapHd->childList, memBlock);
|
||||
if (pChildHeapHd) {
|
||||
return pChildHeapHd;
|
||||
}
|
||||
return pHeapHd;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static MEMList* FindListContainHeap_(const MEMiHeapHead* pHeapHd) {
|
||||
MEMList* pList = &sRootList;
|
||||
|
||||
MEMiHeapHead* pContainHeap = FindContainHeap_(&sRootList, pHeapHd);
|
||||
|
||||
if (pContainHeap) {
|
||||
pList = &pContainHeap->childList;
|
||||
}
|
||||
|
||||
return pList;
|
||||
}
|
||||
|
||||
#define FillNoUseMemory(pHeapHd, address, size) ((void)0)
|
||||
|
||||
void MEMiInitHeapHead(MEMiHeapHead* pHeapHd, u32 signature, void* heapStart, void* heapEnd, u16 optFlag) {
|
||||
pHeapHd->signature = signature;
|
||||
pHeapHd->heapStart = heapStart;
|
||||
pHeapHd->heapEnd = heapEnd;
|
||||
pHeapHd->attribute.val = 0;
|
||||
|
||||
SetOptForHeap(pHeapHd, optFlag);
|
||||
|
||||
FillNoUseMemory(pHeapHd, heapStart, GetOffsetFromPtr(heapStart, heapEnd));
|
||||
MEM_INIT_LIST(&pHeapHd->childList, MEMiHeapHead, link);
|
||||
|
||||
if (!sRootListInitialized) {
|
||||
MEM_INIT_LIST(&sRootList, MEMiHeapHead, link);
|
||||
OSInitMutex(&sRootMutex);
|
||||
sRootListInitialized = TRUE;
|
||||
}
|
||||
|
||||
OSInitMutex(&pHeapHd->mutex);
|
||||
OSLockMutex(&sRootMutex);
|
||||
MEMAppendListObject(FindListContainHeap_(pHeapHd), pHeapHd);
|
||||
OSUnlockMutex(&sRootMutex);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
#include <revolution/mem/list.h>
|
||||
|
||||
// I've tried inlines but only a macro seems to work
|
||||
#define GetLink(parent_list, obj) ((MEMLink*)(((u32)(obj))+(parent_list)->offs))
|
||||
|
||||
void MEMInitList(MEMList *pList, u16 offs) {
|
||||
pList->head = NULL;
|
||||
pList->tail = NULL;
|
||||
pList->num = 0;
|
||||
pList->offs = offs;
|
||||
}
|
||||
|
||||
void MEMAppendListObject(MEMList *pList, void *pObj) {
|
||||
MEMLink* link;
|
||||
|
||||
if (pList->head == NULL) {
|
||||
link = GetLink(pList, pObj);
|
||||
link->next = NULL;
|
||||
link->prev = NULL;
|
||||
pList->head = pObj;
|
||||
pList->tail = pObj;
|
||||
pList->num++;
|
||||
}
|
||||
else {
|
||||
link = GetLink(pList, pObj);
|
||||
link->prev = pList->tail;
|
||||
link->next = NULL;
|
||||
|
||||
GetLink(pList, pList->tail)->next = pObj;
|
||||
pList->tail = pObj;
|
||||
pList->num++;
|
||||
}
|
||||
}
|
||||
|
||||
void* MEMGetNextListObject(MEMList *pList, void *pObj) {
|
||||
if (pObj == NULL) {
|
||||
return pList->head;
|
||||
}
|
||||
|
||||
return GetLink(pList, pObj)->next;
|
||||
}
|
||||
@@ -515,8 +515,10 @@ void __OSLaunchNextFirmware(void) {
|
||||
}
|
||||
|
||||
__OSInitIPCBuffer();
|
||||
#if SDK_AUG2010
|
||||
IPCReInit();
|
||||
IPCCltReInit();
|
||||
#endif
|
||||
|
||||
DVDLowInit();
|
||||
DVDLowIntType = 0;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include "__os.h"
|
||||
|
||||
OSAlarm __OSExpireAlarm;
|
||||
OSAlarm __OSExpireAlarm ATTRIBUTE_ALIGN(32);
|
||||
OSTime __OSExpireTime;
|
||||
OSPlayTimeCallbackFunc __OSExpireCallback;
|
||||
BOOL __OSExpireSetExpiredFlag;
|
||||
|
||||
+45
-13
@@ -5,6 +5,7 @@
|
||||
#include <cstring>
|
||||
|
||||
#include "__si.h"
|
||||
#include "revolution/vi/__vi.h"
|
||||
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
@@ -14,11 +15,11 @@
|
||||
#if DEBUG
|
||||
#define BUILD_TIME "17:27:55"
|
||||
#else
|
||||
#define BUILD_TIME "17:33:06"
|
||||
#define BUILD_TIME "17:33:17"
|
||||
#endif
|
||||
#elif SDK_SEP2006
|
||||
#define BUILD_DATE "Sep 21 2006"
|
||||
#define BUILD_TIME "14:32:13"
|
||||
#define BUILD_DATE "Sep 7 2006"
|
||||
#define BUILD_TIME "07:20:50"
|
||||
#endif
|
||||
|
||||
#ifdef SDK_AUG2010
|
||||
@@ -143,7 +144,7 @@ static void DoReset() {
|
||||
ASSERTLINE(589, 0 <= ResettingChan && ResettingChan < SI_MAX_CHAN);
|
||||
chanBit = (PAD_CHAN0_BIT >> ResettingChan);
|
||||
ResettingBits &= ~chanBit;
|
||||
|
||||
|
||||
memset(&Origin[ResettingChan], 0, sizeof(PADStatus));
|
||||
SIGetTypeAsync(ResettingChan, PADTypeAndStatusCallback);
|
||||
}
|
||||
@@ -221,7 +222,7 @@ static void PADProbeCallback(s32 chan, u32 error, OSContext* context) {
|
||||
ASSERTLINE(740, 0 <= ResettingChan && ResettingChan < SI_MAX_CHAN);
|
||||
ASSERTLINE(741, chan == ResettingChan);
|
||||
ASSERTLINE(743, (Type[chan] & SI_WIRELESS_CONT_MASK) == SI_WIRELESS_CONT && !(Type[chan] & SI_WIRELESS_LITE));
|
||||
|
||||
|
||||
if (!(error & (SI_ERROR_UNDER_RUN | SI_ERROR_OVER_RUN | SI_ERROR_NO_RESPONSE | SI_ERROR_COLLISION)))
|
||||
{
|
||||
PADEnable(ResettingChan);
|
||||
@@ -381,7 +382,7 @@ BOOL PADInit() {
|
||||
if (Initialized) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
OSRegisterVersion(__PADVersion);
|
||||
|
||||
if (__PADSpec)
|
||||
@@ -394,7 +395,7 @@ BOOL PADInit() {
|
||||
__OSWirelessPadFixMode
|
||||
= (u16)((((time)&0xffff) + ((time >> 16) & 0xffff) + ((time >> 32) & 0xffff) + ((time >> 48) & 0xffff))
|
||||
& 0x3fffu);
|
||||
|
||||
|
||||
RecalibrateBits = PAD_CHAN0_BIT | PAD_CHAN1_BIT | PAD_CHAN2_BIT | PAD_CHAN3_BIT;
|
||||
}
|
||||
|
||||
@@ -416,7 +417,9 @@ u32 PADRead(PADStatus* status) {
|
||||
u32 sr;
|
||||
int chanShift;
|
||||
u32 motor;
|
||||
#if SDK_AUG2010
|
||||
static PADStatus pre_status[4];
|
||||
#endif
|
||||
int threshold;
|
||||
|
||||
threshold = 3;
|
||||
@@ -462,7 +465,7 @@ u32 PADRead(PADStatus* status) {
|
||||
if (!(SIGetType(chan) & SI_GC_NOMOTOR)) {
|
||||
motor |= chanBit;
|
||||
}
|
||||
|
||||
|
||||
if (!SIGetResponse(chan, &data)) {
|
||||
status->err = PAD_ERR_TRANSFER;
|
||||
memset(status, 0, offsetof(PADStatus, err));
|
||||
@@ -470,7 +473,7 @@ u32 PADRead(PADStatus* status) {
|
||||
status->err = PAD_ERR_TRANSFER;
|
||||
memset(status, 0, offsetof(PADStatus, err));
|
||||
} else {
|
||||
|
||||
|
||||
|
||||
MakeStatus(chan, status, data);
|
||||
|
||||
@@ -480,6 +483,7 @@ u32 PADRead(PADStatus* status) {
|
||||
threshold = 3;
|
||||
}
|
||||
|
||||
#if SDK_AUG2010
|
||||
#ifdef __MWERKS__
|
||||
#define abs(x) __abs(x)
|
||||
#else
|
||||
@@ -500,19 +504,20 @@ u32 PADRead(PADStatus* status) {
|
||||
#undef abs
|
||||
|
||||
memcpy(&pre_status[chan], status, sizeof(PADStatus));
|
||||
|
||||
#endif
|
||||
|
||||
// Check and clear PAD_ORIGIN bit
|
||||
if (status->button & 0x2000) {
|
||||
status->err = PAD_ERR_TRANSFER;
|
||||
memset(status, 0, offsetof(PADStatus, err));
|
||||
|
||||
|
||||
// Get origin. It is okay if the following transfer fails
|
||||
// since the PAD_ORIGIN bit remains until the read origin
|
||||
// command complete.
|
||||
SITransfer(chan, &CmdReadOrigin, 1, &Origin[chan], 10, PADOriginUpdateCallback, 0);
|
||||
} else {
|
||||
status->err = PAD_ERR_NONE;
|
||||
|
||||
|
||||
// Clear PAD_INTERFERE bit
|
||||
status->button &= ~0x0080;
|
||||
}
|
||||
@@ -690,6 +695,10 @@ static u8 ClampU8(u8 var, u8 org) {
|
||||
}
|
||||
|
||||
static void SPEC2_MakeStatus(s32 chan, PADStatus* status, u32 data[2]) {
|
||||
#if !SDK_AUG2010 || VERSION == VERSION_SHIELD
|
||||
static PADStatus pre_status[4];
|
||||
#endif
|
||||
s32 threshold;
|
||||
PADStatus* origin;
|
||||
|
||||
status->button = (u16)((data[0] >> 16) & PAD_ALL);
|
||||
@@ -765,6 +774,29 @@ static void SPEC2_MakeStatus(s32 chan, PADStatus* status, u32 data[2]) {
|
||||
status->substickY = ClampS8(status->substickY, origin->substickY);
|
||||
status->triggerLeft = ClampU8(status->triggerLeft, origin->triggerLeft);
|
||||
status->triggerRight = ClampU8(status->triggerRight, origin->triggerRight);
|
||||
|
||||
#if !SDK_AUG2010
|
||||
#ifdef __MWERKS__
|
||||
#define abs(x) __abs(x)
|
||||
#else
|
||||
#define abs(x) __builtin_abs(x)
|
||||
#endif
|
||||
|
||||
threshold = 9;
|
||||
if (abs(status->stickX * status->stickX - pre_status[chan].stickX * pre_status[chan].stickX) >= threshold ||
|
||||
abs(status->stickY * status->stickY - pre_status[chan].stickY * pre_status[chan].stickY) >= threshold ||
|
||||
abs(status->substickX * status->substickX - pre_status[chan].substickX * pre_status[chan].substickX) >= threshold ||
|
||||
abs(status->substickY * status->substickY - pre_status[chan].substickY * pre_status[chan].substickY) >= threshold ||
|
||||
abs(status->triggerLeft * status->triggerLeft - pre_status[chan].triggerLeft * pre_status[chan].triggerLeft) >= threshold ||
|
||||
abs(status->triggerRight * status->triggerRight - pre_status[chan].triggerRight * pre_status[chan].triggerRight) >= threshold ||
|
||||
pre_status[chan].button != status->button) {
|
||||
__VIResetSIIdle();
|
||||
}
|
||||
|
||||
memcpy(&pre_status[chan], status, sizeof(PADStatus));
|
||||
#endif
|
||||
|
||||
#undef abs
|
||||
}
|
||||
|
||||
int PADGetType(s32 chan, u32* type) {
|
||||
@@ -889,6 +921,6 @@ BOOL PADIsBarrel(s32 chan) {
|
||||
if (BarrelBits & (PAD_CHAN0_BIT >> chan)) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
#include <revolution/tpl.h>
|
||||
#include <revolution/os.h>
|
||||
|
||||
void TPLBind(TPLPalettePtr ptr) {
|
||||
u16 i;
|
||||
|
||||
if (ptr->versionNumber != 2142000) {
|
||||
OSPanic(__FILE__, 0x19, "invalid version number for texture palette");
|
||||
}
|
||||
|
||||
ptr->descriptorArray = (TPLDescriptorPtr)(((u32)(ptr->descriptorArray)) + ((u32)ptr));
|
||||
|
||||
for (i = 0; i < ptr->numDescriptors; i++) {
|
||||
if (ptr->descriptorArray[i].textureHeader) {
|
||||
ptr->descriptorArray[i].textureHeader = (TPLHeaderPtr)(((u32)(ptr->descriptorArray[i].textureHeader)) + ((u32)ptr));
|
||||
|
||||
if (!ptr->descriptorArray[i].textureHeader->unpacked) {
|
||||
ptr->descriptorArray[i].textureHeader->data = (char*)((u32)(ptr->descriptorArray[i].textureHeader->data) + (u32)ptr);
|
||||
ptr->descriptorArray[i].textureHeader->unpacked = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ptr->descriptorArray[i].CLUTHeader) {
|
||||
ptr->descriptorArray[i].CLUTHeader = (TPLClutHeaderPtr)((u32)(ptr->descriptorArray[i].CLUTHeader) + (u32)ptr);
|
||||
|
||||
if (!ptr->descriptorArray[i].CLUTHeader->unpacked) {
|
||||
ptr->descriptorArray[i].CLUTHeader->data = (char*)((u32)(ptr->descriptorArray[i].CLUTHeader->data) + (u32)ptr);
|
||||
ptr->descriptorArray[i].CLUTHeader->unpacked = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TPLDescriptorPtr TPLGet(TPLPalettePtr ptr, u32 id) {
|
||||
id %= ptr->numDescriptors;
|
||||
return &ptr->descriptorArray[id];
|
||||
}
|
||||
Reference in New Issue
Block a user