static void dma_callback(void) { gx_audio_t *wa = (gx_audio_t*)gx_audio_data; /* Erase last chunk to avoid repeating audio. */ memset(wa->data[wa->dma_busy], 0, CHUNK_SIZE); wa->dma_busy = wa->dma_next; wa->dma_next = (wa->dma_next + 1) & (BLOCKS - 1); DCFlushRange(wa->data[wa->dma_next], CHUNK_SIZE); AIInitDMA((uint32_t)wa->data[wa->dma_next], CHUNK_SIZE); OSSignalCond(wa->cond); }
void __Disc_SetLowMem(void) { /* Setup low memory */ *(vu32 *)0x80000030 = 0x00000000; *(vu32 *)0x80000060 = 0x38A00040; *(vu32 *)0x800000E4 = 0x80431A80; *(vu32 *)0x800000EC = 0x81800000; *(vu32 *)0x800000F4 = 0x817E5480; *(vu32 *)0x800000F8 = 0x0E7BE2C0; *(vu32 *)0x800000FC = 0x2B73A840; /* Copy disc ID */ memcpy((void *)0x80003180, (void *)0x80000000, 4); /* Flush cache */ DCFlushRange((void *)0x80000000, 0x3F00); }
u32 load_dol_start(void *dolstart) { if (dolstart) { dolfile = (dolheader *)dolstart; return dolfile->entry_point; } else { return 0; } memset((void *)dolfile->bss_start, 0, dolfile->bss_size); DCFlushRange((void *)dolfile->bss_start, dolfile->bss_size); phase = 0; i = 0; }
void HIDUpdateRegisters() { if(*(vu32*)HID_CHANGE == 0) return; u32 DeviceVID = *(vu32*)HID_CHANGE; u32 DevicePID = *(vu32*)HID_CFG_SIZE; /* I hope this covers all possible ini files */ gprintf("Trying to get VID%04x PID%04x\n", DeviceVID, DevicePID); char filename[50]; sprintf(filename, "sd:/controllers/%04X_%04X.ini", DeviceVID, DevicePID); FILE *f = fopen(filename, "rb"); if(f == NULL) { sprintf(filename, "usb:/controllers/%04X_%04X.ini", DeviceVID, DevicePID); f = fopen(filename, "rb"); if(f == NULL) { f = fopen("sd:/controller.ini", "rb"); if(f == NULL) { fopen("sd:/controller.ini.ini", "rb"); if(f == NULL) { f = fopen("usb:/controller.ini", "rb"); if(f == NULL) f = fopen("usb:/controller.ini.ini", "rb"); } } } } if(f != NULL) { fseek(f, 0, SEEK_END); size_t fsize = ftell(f); rewind(f); fread((void*)HID_CFG_FILE, 1, fsize, f); DCFlushRange((void*)HID_CFG_FILE, fsize); fclose(f); *(vu32*)HID_CFG_SIZE = fsize; } else *(vu32*)HID_CFG_SIZE = 0; *(vu32*)HID_CHANGE = 0; }
/** * Shameless wrapper around the handy FreeTypeGRRLIB */ GX_Texture* GX_Text(const wchar_t *string, uint fontSize, uint color) { unsigned int error = FT_Set_Pixel_Sizes(ftFace, 0, fontSize); if (error) { /* Failed to set the font size to the requested size. * You probably should set a default size or something. * I'll leave that up to the reader. */ } const unsigned int height = fontSize*2; const unsigned int tempWidth = 640; /* Set the font colour, alpha is determined when we blit the glyphs */ color = color << 8; /* Create a tempory buffer, 640 pixels wide, for freetype draw the glyphs */ void *tempTextureBuffer = (void*) malloc(tempWidth * height * 4); if (tempTextureBuffer == NULL) { /* Oops! Something went wrong! */ exit(0); } /* Set the RGB pixels in tempTextureBuffer to the requested colour */ unsigned int *p = (unsigned int*)tempTextureBuffer; unsigned int loop = 0; for (loop = 0; loop < (tempWidth * height); ++loop) { *(p++) = color; } /* Render the glyphs on to the temp buffer */ unsigned int width = DrawText(string, fontSize, tempTextureBuffer); width = ((width + 3) / 4) * 4; // round up to the nearest mod 4 number GX_InvalidateTexAll(); /* Create a new buffer, this time to hold the final texture * in a format suitable for the Wii */ void *texture = memalign(32, width * height * 4); /* Convert the RGBA temp buffer to a format usuable by GX */ BitmapTo4x4RGBA((const unsigned char *)tempTextureBuffer,texture, tempWidth, height, width, height); DCFlushRange(texture, 640 * (fontSize*2) * 4); /* The temp buffer is no longer required */ free(tempTextureBuffer); return new GX_Texture(width, height, GX_TF_RGBA8, (u8*)texture); }
static void put_text (void *tileidx, int row, int startcol, unsigned char *text, unsigned int textlen, int offset, int len) { unsigned char *c = tileidx; int i; for (i = 0; i < len; i++) { int offset2 = offset + i * 4; int idx = tex_index (startcol + i, row, TILES_W, 8); c[idx] = (offset2 >= 0 && offset2 < textlen) ? ascii_to_char[text[offset2]] : 0; } DCFlushRange (c, GX_GetTexBufferSize (TILES_W, TILES_H, TILES_FMT, GX_FALSE, 0)); }
static void reset(void) { AUDIO_RegisterDMACallback(NULL); while(AUDIO_GetDMABytesLeft() > 0) usleep(100); playing = false; buffer_fill = 0; buffer_play = 0; buffered = 0; for (int counter = 0; counter < BUFFER_COUNT; counter++) { memset(buffers[counter], 0, BUFFER_SIZE); DCFlushRange(buffers[counter], BUFFER_SIZE); } AUDIO_RegisterDMACallback(switch_buffers); }
void wipparsebuffer(u8 *buffer, u32 length) // The buffer needs a 0 at the end to properly terminate the string functions { int i; u32 pos = 0; u32 offset; char buf[10]; while (pos < length) { if ( *(char *)(buffer + pos) != '#' && *(char *)(buffer + pos) != ';' && *(char *)(buffer + pos) != 10 && *(char *)(buffer + pos) != 13 && *(char *)(buffer + pos) != 32 && *(char *)(buffer + pos) != 0 ) { memcpy(buf, (char *)(buffer + pos), 8); buf[8] = 0; offset = strtol(buf,NULL,16); pos += (u32)strchr((char *)(buffer + pos), 32)-(u32)(buffer + pos) + 1; pos += (u32)strchr((char *)(buffer + pos), 32)-(u32)(buffer + pos) + 1; while (*(char *)(buffer + pos) != 10 && *(char *)(buffer + pos) != 13 && *(char *)(buffer + pos) != 0) { memcpy(buf, (char *)(buffer + pos), 2); buf[2] = 0; patchu8(offset, strtol(buf,NULL,16)); offset++; pos +=2; } // s_printf("\n"); } if (strchr((char *)(buffer + pos), 10) == NULL) { break; } else { pos += (u32)strchr((char *)(buffer + pos), 10)-(u32)(buffer + pos) + 1; } } for(i=0;i<doltableentries;i++) DCFlushRange((void *) doltableoffset[i], doltablelength[i]); }
static void __ARClearArea(u32 aramaddr,u32 len) { u32 currlen,curraddr,endaddr; static u8 zero_buffer[2048] ATTRIBUTE_ALIGN(32); while(!(_dspReg[11]&0x0001)); memset(zero_buffer,0,2048); DCFlushRange(zero_buffer,2048); curraddr = aramaddr; endaddr = aramaddr+len; currlen = 2048; while(curraddr<endaddr) { if((endaddr-curraddr)<currlen) currlen = ((endaddr-curraddr)+31)&~31; __ARWriteDMA((u32)zero_buffer,curraddr,currlen); curraddr += currlen; } }
bool SFont::fromFile(const char *path, u32 size, u32 lspacing, u32 w, u32 idx, const char *fontname) { fSize = min(max(6u, size), 1000u); weight = min(w, 32u); index = idx = 0; lineSpacing = min(max(6u, lspacing), 1000u); if(data != NULL) free(data); data = fsop_ReadFile(path, &dataSize); if(data == NULL) return false; DCFlushRange(data, dataSize); memcpy(name, fontname, 127); font = new FreeTypeGX(); font->loadFont(data, dataSize, fSize, weight, index, false); return true; }
int SNDWiiInit() { AUDIO_Init(NULL); AUDIO_SetDSPSampleRate(AI_SAMPLERATE_48KHZ); soundpos = 0; soundlen = 44100 / 60; // 60 for NTSC or 50 for PAL. Initially assume it's going to be NTSC. soundtruelen = 48000 / 60; truesoundoffset = stereodata16[0]; memset(stereodata16, 0, SOUNDBUFSIZE); issoundmuted = 0; AUDIO_RegisterDMACallback(StartDMA); AUDIO_InitDMA((u32)stereodata16[soundpos], soundlen * 4); DCFlushRange((void *)stereodata16[soundpos], soundlen * 4); AUDIO_StartDMA(); return 0; }
void OSystem_Wii::initSfx() { _mixer = new Audio::MixerImpl(this, 48000); sfx_thread_running = false; sfx_thread_quit = false; sfx_stack = (u8 *) memalign(32, SFX_THREAD_STACKSIZE); if (sfx_stack) { memset(sfx_stack, 0, SFX_THREAD_STACKSIZE); LWP_InitQueue(&sfx_queue); s32 res = LWP_CreateThread(&sfx_thread, sfx_thread_func, _mixer, sfx_stack, SFX_THREAD_STACKSIZE, SFX_THREAD_PRIO); if (res) { printf("ERROR creating sfx thread: %d\n", res); LWP_CloseQueue(sfx_queue); return; } sfx_thread_running = true; } for (u32 i = 0; i < SFX_BUFFERS; ++i) { sound_buffer[i] = (u8 *) memalign(32, SFX_THREAD_FRAG_SIZE); memset(sound_buffer[i], 0, SFX_THREAD_FRAG_SIZE); DCFlushRange(sound_buffer[i], SFX_THREAD_FRAG_SIZE); } _mixer->setReady(true); sb_hw = 0; AUDIO_SetDSPSampleRate(AI_SAMPLERATE_48KHZ); AUDIO_RegisterDMACallback(audio_switch_buffers); AUDIO_InitDMA((u32) sound_buffer[sb_hw], SFX_THREAD_FRAG_SIZE); AUDIO_StartDMA(); }
static void *gx_audio_init(const char *device, unsigned rate, unsigned latency) { if (g_audio) return g_audio; AUDIO_Init(NULL); AUDIO_RegisterDMACallback(dma_callback); if (rate < 33000) { AUDIO_SetDSPSampleRate(AI_SAMPLERATE_32KHZ); g_settings.audio.out_rate = 32000; } else { AUDIO_SetDSPSampleRate(AI_SAMPLERATE_48KHZ); g_settings.audio.out_rate = 48000; } if (!g_audio) { g_audio = memalign(32, sizeof(*g_audio)); memset(g_audio, 0, sizeof(*g_audio)); LWP_InitQueue(&g_audio->cond); } else { memset(g_audio->data, 0, sizeof(g_audio->data)); g_audio->dma_busy = g_audio->dma_next = 0; g_audio->write_ptr = 0; g_audio->nonblock = false; } g_audio->dma_write = BLOCKS - 1; DCFlushRange(g_audio->data, sizeof(g_audio->data)); AUDIO_InitDMA((u32)g_audio->data[g_audio->dma_next], CHUNK_SIZE); AUDIO_StartDMA(); return g_audio; }
void GuiImageData::LoadTPL(const u8 *img, int imgSize) { TplImage TplFile(img, imgSize); width = TplFile.GetWidth(0); height = TplFile.GetHeight(0); format = (u8) TplFile.GetFormat(0); const u8 * ImgPtr = TplFile.GetTextureBuffer(0); if(ImgPtr) { int len = ALIGN32(TplFile.GetTextureSize(0)); data = (u8 *) memalign(32, len); if(!data) return; memcpy(data, ImgPtr, len); DCFlushRange(data, len); } }
s32 StartMIOS (void) { s32 ret; SetGCVideoMode (); tikview view ATTRIBUTE_ALIGN(32); ret = ES_GetTicketViews(BC, &view, 1); if (ret != 0) return -1; // Tell DML to boot the game from sd card *(u32 *)0x80001800 = 0xB002D105; DCFlushRange((void *)(0x80001800), 4); ICInvalidateRange((void *)(0x80001800), 4); *(volatile unsigned int *)0xCC003024 |= 7; ret = ES_LaunchTitle(BC, &view); return -102; }
void SetDolArgv(void* bin, int binsize, int argc, char **argv) { int i, len, curpos = 0; int found = 0; char *args = (char*)((int)bin + binsize); u32 *dolptr = (u32*)bin; struct __argv *dolargv; argc-=1; for(i=strlen(argv[1]); i>0 && argv[1][i]!='/'; i--); len = strlen(&argv[1][i]); memset(&args[curpos], 0, len+1); strcpy(&args[curpos], &argv[1][i]); curpos+= len+1; for(i=2; i<=argc; i++) { len = strlen(argv[i]); memset(&args[curpos], 0, len+1); strcpy(&args[curpos], argv[i]); curpos+= len+1; } DCFlushRange(args, curpos); for(i=0; i<binsize/4; i++) { if(dolptr[i]==ARGV_MAGIC) { found = 1; break; } } if(!found)return; dolargv = (struct __argv*)&dolptr[i+1]; dolargv->argvMagic = ARGV_MAGIC; dolargv->commandLine = args; dolargv->length = curpos; }
int File::ReadOffsetAlloc(FILE *file, u32 offset, u32 length, u8 **outbuf) { u8 *buffer = NULL; int ret; /* Allocate memory */ buffer = (u8*)Tools::AllocateMemory(length); if (!buffer) return -1; /* Read file */ ret = ReadOffset(file, offset, length, &buffer); if (ret < 0) { delete buffer; buffer = NULL; return ret; } DCFlushRange(buffer, length); /* Set pointer */ *outbuf = buffer; return 0; }
s32 USBStorageOGC_Close(usbstorage_handle *dev) { if(dev != NULL) { important_storage_data *d = (important_storage_data*)0x932C1000; d->sector_size = __sector_size; d->sector_count = __sector_count; d->lun = __lun; d->vid = __vid; d->pid = __pid; d->tag = dev->tag; d->interface = dev->interface; d->usb_fd = dev->usb_fd; d->ep_in = dev->ep_in; d->ep_out = dev->ep_out; DCFlushRange((void*)0x932C1000, sizeof(important_storage_data)); } __mounted = false; __lun = 0; __vid = 0; __pid = 0; if (dev->usb_fd != -1) USB_OGC_CloseDevice(&dev->usb_fd); LWP_MutexDestroy(dev->lock); SYS_RemoveAlarm(dev->alarm); if(dev->sector_size) free(dev->sector_size); if (dev->buffer) __lwp_heap_free(&__heap, dev->buffer); memset(dev, 0, sizeof(*dev)); dev->usb_fd = -1; return 0; }
static void * sfx_thread_func(void *arg) { Audio::MixerImpl *mixer = (Audio::MixerImpl *) arg; u8 sb_sw; while (true) { LWP_ThreadSleep(sfx_queue); if (sfx_thread_quit) break; // the hardware uses two buffers: a front and a back buffer // we use 3 buffers here: two are beeing pushed to the DSP, // and the free one is where our mixer writes to // thus the latency of our stream is: // 8192 [frag size] / 48000 / 2 [16bit] / 2 [stereo] * 2 [hw buffers] // -> 85.3ms sb_sw = (sb_hw + 1) % SFX_BUFFERS; mixer->mixCallback(sound_buffer[sb_sw], SFX_THREAD_FRAG_SIZE); DCFlushRange(sound_buffer[sb_sw], SFX_THREAD_FRAG_SIZE); } return NULL; }
bool SFont::fromBuffer(const u8 *buffer, const u32 bufferSize, u32 size, u32 lspacing, u32 w, u32 idx, const char *fontname) { if(buffer == NULL) return false; fSize = min(max(6u, size), 1000u); lineSpacing = min(max(6u, lspacing), 1000u); weight = min(w, 32u); index = idx; if(data != NULL) free(data); data = (u8*)MEM2_alloc(bufferSize); if(data == NULL) return false; dataSize = bufferSize; memcpy(data, buffer, bufferSize); DCFlushRange(data, dataSize); memcpy(name, fontname, 127); font = new FreeTypeGX(); font->loadFont(data, dataSize, fSize, weight, index, false); return true; }
u8 *ISFS_GetFile(u8 *path, u32 *size, s32 length) { *size = 0; s32 fd = ISFS_Open((const char *) path, ISFS_OPEN_READ); u8 *buf = NULL; static fstats stats ATTRIBUTE_ALIGN(32); if(fd >= 0) { if(ISFS_GetFileStats(fd, &stats) >= 0) { if(length <= 0) length = stats.file_length; if(length > 0) buf = (u8 *)MEM2_memalign(32, length); if(buf) { *size = stats.file_length; if(ISFS_Read(fd, (char*)buf, length) != length) { *size = 0; MEM2_free(buf); } } } ISFS_Close(fd); } if(*size > 0) { DCFlushRange(buf, *size); ICInvalidateRange(buf, *size); } return buf; }
static void *gx_audio_init(const char *device, unsigned rate, unsigned latency, unsigned block_frames, unsigned *new_rate) { gx_audio_t *wa = (gx_audio_t*)memalign(32, sizeof(*wa)); if (!wa) return NULL; gx_audio_data = (gx_audio_t*)wa; memset(wa, 0, sizeof(*wa)); AIInit(NULL); AIRegisterDMACallback(dma_callback); if (rate < 33000) { AISetDSPSampleRate(AI_SAMPLERATE_32KHZ); *new_rate = 32000; } else { AISetDSPSampleRate(AI_SAMPLERATE_48KHZ); *new_rate = 48000; } OSInitThreadQueue(&wa->cond); wa->dma_write = BLOCKS - 1; DCFlushRange(wa->data, sizeof(wa->data)); stop_audio = false; AIInitDMA((uint32_t)wa->data[wa->dma_next], CHUNK_SIZE); AIStartDMA(); return wa; }
static void inline play_buffer(void){ #ifndef THREADED_AUDIO // We should wait for the other buffer to finish its DMA transfer first while( AUDIO_GetDMABytesLeft() ); AUDIO_StopDMA(); #else // THREADED_AUDIO // Wait for a sample to actually be played to work around a deadlock LWP_SemWait(first_audio); // This thread will keep giving buffers to the audio as they come while(thread_running){ // Wait for a buffer to be processed LWP_SemWait(buffer_full); #endif // Make sure the buffer is in RAM, not the cache DCFlushRange(buffer[thread_buffer], buffer_size); // Actually send the buffer out to be played next AUDIO_InitDMA((unsigned int)&buffer[thread_buffer], buffer_size); #ifdef THREADED_AUDIO // Wait for the audio interface to be free before playing LWP_SemWait(audio_free); #endif // Start playing the buffer AUDIO_StartDMA(); #ifdef THREADED_AUDIO // Move the index to the next buffer NEXT(thread_buffer); } #endif }
//--------------------------------------------------------------------------------- int main(int argc, char **argv) { //--------------------------------------------------------------------------------- // Initialise the video system VIDEO_Init(); Video_SetMode(); WPAD_Init(); PAD_Init(); if(AHBPROT_DISABLED) IosPatch_RUNTIME(true, false, false, true); else IOS_ReloadIOS(236); menu(); signed_blob *p_tmd = NULL; u32 len; s32 ret; ret = GetTMD(0x0001000154484246LL, &p_tmd, &len); if(ret < 0) { *(vu32*)0x8132FFFB = 0x50756E65; DCFlushRange((void*)0x8132FFFB, 4); SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0); } else { WII_LaunchTitle(0x0001000154484246); } return 0; }
// Installs the GeckoOS (kenobiGC) cheats engine and sets up variables/copies cheats void kenobi_install_engine() { int isDebug = swissSettings.wiirdDebug; // If high memory is in use, we'll use low, otherwise high. u8 *ptr = isDebug ? kenobigc_dbg_bin : kenobigc_bin; u32 size = isDebug ? kenobigc_dbg_bin_size : kenobigc_bin_size; print_gecko("Copying kenobi%s to %08X\r\n", (isDebug?"_dbg":""),(u32)CHEATS_ENGINE); memcpy(CHEATS_ENGINE, ptr, size); memcpy(CHEATS_GAMEID, (void*)0x80000000, CHEATS_GAMEID_LEN); if(!isDebug) { CHEATS_ENABLE_CHEATS = CHEATS_TRUE; } CHEATS_START_PAUSED = isDebug ? CHEATS_TRUE : CHEATS_FALSE; memset(CHEATS_LOCATION(size), 0, kenobi_get_maxsize()); print_gecko("Copying %i bytes of cheats to %08X\r\n", getEnabledCheatsSize(),(u32)CHEATS_LOCATION(size)); u32 *cheatsLocation = (u32*)CHEATS_LOCATION(size); cheatsLocation[0] = 0x00D0C0DE; cheatsLocation[1] = 0x00D0C0DE; cheatsLocation+=2; int i = 0, j = 0; for(i = 0; i < _cheats.num_cheats; i++) { CheatEntry *cheat = &_cheats.cheat[i]; if(cheat->enabled) { for(j = 0; j < cheat->num_codes; j++) { // Copy & fix cheats that want to jump to the old cheat engine location 0x800018A8 -> CHEATS_ENGINE+0xA8 cheatsLocation[0] = cheat->codes[j][0]; cheatsLocation[1] = cheat->codes[j][1] == 0x800018A8 ? (u32)(CHEATS_ENGINE+0xA8) : cheat->codes[j][1]; cheatsLocation+=2; } } } cheatsLocation[0] = 0xFF000000; DCFlushRange((void*)CHEATS_ENGINE, WIIRD_ENGINE_SPACE); ICInvalidateRange((void*)CHEATS_ENGINE, WIIRD_ENGINE_SPACE); }
void Disc_SetLowMem(u32 IOS) { /* Setup low memory */ *Sys_Magic = 0x0D15EA5E; // Standard Boot Code *Sys_Version = 0x00000001; // Version *Arena_L = 0x00000000; // Arena Low *Bus_Speed = 0x0E7BE2C0; // Console Bus Speed *CPU_Speed = 0x2B73A840; // Console CPU Speed *Assembler = 0x38A00040; // Assembler *OS_Thread = 0x80431A80; // Thread Init *Dev_Debugger = 0x81800000; // Dev Debugger Monitor Address *Simulated_Mem = 0x01800000; // Simulated Memory Size *GameID_Address = 0x80000000; // Fix for Sam & Max (WiiPower) /* Copy Disc ID */ memcpy((void*)Online_Check, (void*)Disc_ID, 4); /* Error 002 Fix (thanks WiiPower and uLoader) */ *Current_IOS = (IOS << 16) | 0xffff; *Apploader_IOS = (IOS << 16) | 0xffff; /* Flush everything */ DCFlushRange((void*)0x80000000, 0x3f00); }
static u8* DGifDecodeTo4x4RGB8(GifFileType *gifFile, GifRowType *rowType, short transparentColor, u8 *dstPtr) { unsigned int vert, hor, col, row; ColorMapObject *colorMap = (gifFile->Image.ColorMap ? gifFile->Image.ColorMap : gifFile->SColorMap); if (colorMap == NULL) return NULL; int newWidth = gifFile->Image.Width; if (newWidth % 4) newWidth += (4 - newWidth % 4); int newHeight = gifFile->Image.Height; if (newHeight % 4) newHeight += (4 - newHeight % 4); int len = (newWidth * newHeight) << 2; if (len % 32) len += (32 - len % 32); u8 * dst; if(dstPtr) dst = dstPtr; // use existing allocation else dst = gif_memalign (32, len); if (!dst) return NULL; unsigned char *p = (unsigned char*) dst; for (vert = 0; vert < newHeight; vert += 4) { for (hor = 0; hor < newWidth; hor += 4) { for (row = 0; row < 4; row++) { GifRowType gifRow = rowType[vert + row]; unsigned char *gb = (unsigned char *) (p + 32); for (col = 0; col < 4; col++) { if (vert + row >= gifFile->Image.Height || // Transparent cell hor + col >= gifFile->Image.Width) { *p++ = 0; *p++ = 255; *gb++ = 255; *gb++ = 255; } else { int color = *(char*) (gifRow + hor + col); GifColorType *colorMapEntry = &colorMap->Colors[color]; *p++ = color == transparentColor ? 0 : 255; *p++ = colorMapEntry->Red; *gb++ = colorMapEntry->Green; *gb++ = colorMapEntry->Blue; } } } p += 32; } } DCFlushRange(dst, len); return dst; }
bool dogamehooks(void *addr, u32 len, bool channel) { /* 0 No Hook 1 VBI 2 KPAD read 3 Joypad Hook 4 GXDraw Hook 5 GXFlush Hook 6 OSSleepThread Hook 7 AXNextFrame Hook */ void *addr_start = addr; void *addr_end = addr+len; while(addr_start < addr_end) { switch(hooktype) { case 0x00: hookpatched = true; break; case 0x01: if(memcmp(addr_start, viwiihooks, sizeof(viwiihooks))==0) { patchhook((u32)addr_start, len); wifi_printf("patchcode_dogamehooks: viwiihooks at = %08X\n", addr_start); hookpatched = true; } break; case 0x02: if(memcmp(addr_start, kpadhooks, sizeof(kpadhooks))==0) { patchhook((u32)addr_start, len); wifi_printf("patchcode_dogamehooks: kpadhooks at = %08X\n", addr_start); hookpatched = true; } if(memcmp(addr_start, kpadoldhooks, sizeof(kpadoldhooks))==0) { patchhook((u32)addr_start, len); wifi_printf("patchcode_dogamehooks: kpadoldhooks at = %08X\n", addr_start); hookpatched = true; } break; case 0x03: if(memcmp(addr_start, joypadhooks, sizeof(joypadhooks))==0) { patchhook((u32)addr_start, len); wifi_printf("patchcode_dogamehooks: joypadhooks at = %08X\n", addr_start); hookpatched = true; } break; case 0x04: if(memcmp(addr_start, gxdrawhooks, sizeof(gxdrawhooks))==0) { patchhook((u32)addr_start, len); wifi_printf("patchcode_dogamehooks: gxdrawhooks at = %08X\n", addr_start); hookpatched = true; } break; case 0x05: if(memcmp(addr_start, gxflushhooks, sizeof(gxflushhooks))==0) { patchhook((u32)addr_start, len); wifi_printf("patchcode_dogamehooks: gxflushhooks at = %08X\n", addr_start); hookpatched = true; } break; case 0x06: if(memcmp(addr_start, ossleepthreadhooks, sizeof(ossleepthreadhooks))==0) { patchhook((u32)addr_start, len); wifi_printf("patchcode_dogamehooks: ossleepthreadhooks at = %08X\n", addr_start); hookpatched = true; } break; case 0x07: if(memcmp(addr_start, axnextframehooks, sizeof(axnextframehooks))==0) { patchhook((u32)addr_start, len); wifi_printf("patchcode_dogamehooks: axnextframehooks at = %08X\n", addr_start); hookpatched = true; } break; } if (hooktype != 0) { if(channel && memcmp(addr_start, multidolchanhooks, sizeof(multidolchanhooks))==0) { *(((u32*)addr_start)+1) = 0x7FE802A6; DCFlushRange(((u32*)addr_start)+1, 4); multidolhook((u32)addr_start+sizeof(multidolchanhooks)-4); wifi_printf("patchcode_dogamehooks: multidolchanhooks at = %08X\n", addr_start); } else if(!channel && memcmp(addr_start, multidolhooks, sizeof(multidolhooks))==0) { multidolhook((u32)addr_start+sizeof(multidolhooks)-4); wifi_printf("patchcode_dogamehooks: multidoldolhooks at = %08X\n", addr_start); } } addr_start += 4; } return hookpatched; }
/** * ARAMPut * * Move data from MAIN memory to ARAM */ void ARAMPut (char *src, char *dst, int len) { DCFlushRange (src, len); AR_StartDMA( ARAM_WRITE, (u32)src, (u32)dst, len); while (AR_GetDMAStatus()); }
static void dol_copy_argv_path(const char *dolpath, const char *argpath) { char tmp[PATH_MAX_LENGTH]; size_t t_len; struct __argv *argv = (struct __argv *)ARGS_ADDR; char *cmdline = NULL; size_t len = 0; memset(ARGS_ADDR, 0, sizeof(struct __argv)); cmdline = (char *)ARGS_ADDR + sizeof(struct __argv); argv->argvMagic = ARGV_MAGIC; argv->commandLine = cmdline; /* a device-less fullpath */ if (dolpath[0] == '/') { char *dev = strchr(__system_argv->argv[0], ':'); t_len = dev - __system_argv->argv[0] + 1; memcpy(cmdline, __system_argv->argv[0], t_len); len += t_len; } /* a relative path */ else if (strstr(dolpath, "sd:/") != dolpath && strstr(dolpath, "usb:/") != dolpath && strstr(dolpath, "carda:/") != dolpath && strstr(dolpath, "cardb:/") != dolpath) { fill_pathname_parent_dir(tmp, __system_argv->argv[0], sizeof(tmp)); t_len = strlen(tmp); memcpy(cmdline, tmp, t_len); len += t_len; } t_len = strlen(dolpath); memcpy(cmdline + len, dolpath, t_len); len += t_len; cmdline[len++] = 0; /* File must be split into two parts, * the path and the actual filename * done to be compatible with loaders. */ if (argpath && strrchr(argpath, '/') != NULL) { char *name = NULL; /* basedir. */ fill_pathname_parent_dir(tmp, argpath, sizeof(tmp)); t_len = strlen(tmp); memcpy(cmdline + len, tmp, t_len); len += t_len; cmdline[len++] = 0; /* filename */ name = strrchr(argpath, '/') + 1; t_len = strlen(name); memcpy(cmdline + len, name, t_len); len += t_len; cmdline[len++] = 0; } cmdline[len++] = 0; argv->length = len; DCFlushRange(ARGS_ADDR, sizeof(struct __argv) + argv->length); }