usbloadergx/source/usbloader/alternatedol.c
giantpune 4d6e0fe412 Free up ~24KB for every 150 games installed.
Add button to mount DVD drive.  Not completely tested, but somewhat.
*Tested and working*
retail Wii DVD
Wii backup
Wii backup w/ alt dol (redsteel)
Wii backup w/ alt dol & ocarina (redsteel)
Wii backup w/ alt dol & WiiRD 
Retail & Backup forcing video modes
Saving individual settings for games on DVD (only Wii as BC is loaded before any settings would be used)
Display disc images for DVD games
Loading GC games retail & backup (w/ working MIOS patch installed)  
I did change some stuff after testing GC so it might be broken.

Theme stuff for the button is not tested and I'm not quite up to speed with ardi's changes to the theme stuff so it might not work.

Changed images are not compressed or optimized.
2009-09-29 08:09:09 +00:00

239 lines
5.8 KiB
C

#include <ogcsys.h>
#include <stdio.h>
#include <gccore.h>
#include <string.h>
#include <malloc.h>
#include "fatmounter.h"
#include "apploader.h"
#include "wdvd.h"
#include "fstfile.h"
#include "../patches/dvd_broadway.h"
extern u8 dvdMounted;
/** Alternate dolloader made by WiiPower modified by dimok **/
bool Load_Dol(void **buffer, int* dollen, char * filepath) {
int ret;
FILE* file;
void* dol_buffer;
char fullpath[200];
char gameidbuffer6[7];
memset(gameidbuffer6, 0, 7);
memcpy(gameidbuffer6, (char*)0x80000000, 6);
snprintf(fullpath, 200, "%s%s.dol", filepath, gameidbuffer6);
SDCard_Init();
USBDevice_Init();
file = fopen(fullpath, "rb");
if (file == NULL) {
fclose(file);
SDCard_deInit();
USBDevice_deInit();
return false;
}
int filesize;
fseek(file, 0, SEEK_END);
filesize = ftell(file);
fseek(file, 0, SEEK_SET);
dol_buffer = malloc(filesize);
if (dol_buffer == NULL) {
fclose(file);
SDCard_deInit();
USBDevice_deInit();
return false;
}
ret = fread( dol_buffer, 1, filesize, file);
if (ret != filesize) {
free(dol_buffer);
fclose(file);
SDCard_deInit();
USBDevice_deInit();
return false;
}
fclose(file);
SDCard_deInit();
USBDevice_deInit();
*buffer = dol_buffer;
*dollen = filesize;
return true;
}
bool Remove_001_Protection(void *Address, int Size) {
u8 SearchPattern[16] = { 0x40, 0x82, 0x00, 0x0C, 0x38, 0x60, 0x00, 0x01, 0x48, 0x00, 0x02, 0x44, 0x38, 0x61, 0x00, 0x18 };
u8 PatchData[16] = { 0x40, 0x82, 0x00, 0x04, 0x38, 0x60, 0x00, 0x01, 0x48, 0x00, 0x02, 0x44, 0x38, 0x61, 0x00, 0x18 };
void *Addr = Address;
void *Addr_end = Address+Size;
while (Addr <= Addr_end-sizeof(SearchPattern)) {
if (memcmp(Addr, SearchPattern, sizeof(SearchPattern))==0) {
memcpy(Addr,PatchData,sizeof(PatchData));
return true;
}
Addr += 4;
}
return false;
}
typedef struct _dolheader {
u32 text_pos[7];
u32 data_pos[11];
u32 text_start[7];
u32 data_start[11];
u32 text_size[7];
u32 data_size[11];
u32 bss_start;
u32 bss_size;
u32 entry_point;
} dolheader;
static dolheader *dolfile;
u32 load_dol_image(void *dolstart) {
u32 i;
if (dolstart) {
dolfile = (dolheader *) dolstart;
for (i = 0; i < 7; i++) {
if ((!dolfile->text_size[i]) || (dolfile->text_start[i] < 0x100)) continue;
VIDEO_WaitVSync();
ICInvalidateRange ((void *) dolfile->text_start[i],dolfile->text_size[i]);
memmove ((void *) dolfile->text_start[i],dolstart+dolfile->text_pos[i],dolfile->text_size[i]);
}
for (i = 0; i < 11; i++) {
if ((!dolfile->data_size[i]) || (dolfile->data_start[i] < 0x100)) continue;
VIDEO_WaitVSync();
memmove ((void *) dolfile->data_start[i],dolstart+dolfile->data_pos[i],dolfile->data_size[i]);
DCFlushRangeNoSync ((void *) dolfile->data_start[i],dolfile->data_size[i]);
}
/*
memset ((void *) dolfile->bss_start, 0, dolfile->bss_size);
DCFlushRange((void *) dolfile->bss_start, dolfile->bss_size);
*/
return dolfile->entry_point;
}
return 0;
}
static int i;
static int phase;
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;
}
bool load_dol_image_modified(void **offset, u32 *pos, u32 *len) {
if (phase == 0) {
if (i == 7) {
phase = 1;
i = 0;
} else {
if ((!dolfile->text_size[i]) || (dolfile->text_start[i] < 0x100)) {
*offset = 0;
*pos = 0;
*len = 0;
} else {
*offset = (void *)dolfile->text_start[i];
*pos = dolfile->text_pos[i];
*len = dolfile->text_size[i];
}
i++;
return true;
}
}
if (phase == 1) {
if (i == 11) {
phase = 2;
return false;
}
if ((!dolfile->data_size[i]) || (dolfile->data_start[i] < 0x100)) {
*offset = 0;
*pos = 0;
*len = 0;
} else {
*offset = (void *)dolfile->data_start[i];
*pos = dolfile->data_pos[i];
*len = dolfile->data_size[i];
}
i++;
return true;
}
return false;
}
static vu32 dvddone = 0;
void __dvd_readidcb(s32 result)
{
dvddone = result;
}
u32 Load_Dol_from_disc(u32 doloffset, u8 videoSelected, u8 patchcountrystring, u8 vipatch) {
int ret;
void *dol_header;
u32 entrypoint;
dol_header = memalign(32, sizeof(dolheader));
if (dol_header == NULL) {
return -1;
}
if (!dvdMounted)ret = WDVD_Read(dol_header, sizeof(dolheader), (doloffset<<2));
else{
dvddone = 0;
ret = bwDVD_LowRead(dol_header, sizeof(dolheader), doloffset, __dvd_readidcb);
while(ret>=0 && dvddone==0);
}
entrypoint = load_dol_start(dol_header);
if (entrypoint == 0) {
free(dol_header);
return -1;
}
void *offset;
u32 pos;
u32 len;
while (load_dol_image_modified(&offset, &pos, &len)) {
if (len != 0) {
ret = WDVD_Read(offset, len, (doloffset<<2) + pos);
DCFlushRange(offset, len);
gamepatches(offset, len, videoSelected, patchcountrystring, vipatch);
DCFlushRange(offset, len);
Remove_001_Protection(offset, len);
}
}
free(dol_header);
return entrypoint;
}