WiiFlow_Lite/resources/wiiflow_game_booter/source/disc.c
Fledge68 9f7da43da4 - beta 12 (external booter changes).
- fixed launching of real nand channels.
- fixed launching of forwarder channels, but some apps (ie. wiimcc and savegame manager gx) don't connect with USB devices. if they are on real nand use the 'custom' option in game settings for these forwarders.
- fixed launching HBC on real nand. don't know if its even possible on a emu nand.
- 480p pixel patch for nand wiiware/vc games no longer requires apploader setting ON.
- Exclude Prince of Persia: The Forgotten Sands and a few games that use MetaFortress from using 480p pixel patch
- added giantpunes returnto patch for channels just in case not using d2x cios. some reason it was missing.
2021-11-29 11:36:30 -06:00

252 lines
5.4 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ogcsys.h>
#include <unistd.h>
#include <malloc.h>
#include <ogc/lwp_watchdog.h>
#include "frag.h"
#include "memory.h"
#include "cios.h"
#include "types.h"
#include "wdvd.h"
#include "video_tinyload.h"
/* Constants */
#define PART_INFO_OFFSET 0x10000
s32 Disc_Open(u8 type)
{
if(type > 0)// if not a wii disc (wbfs ext or wbfs drive)
{ /* Reset drive */
s32 ret = WDVD_Reset();
if(ret < 0)
return ret;
}
/* Read disc ID */
return WDVD_ReadDiskId((u8*)Disc_ID);
}
void Disc_SetLowMem(void)
{
/* 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)
*(vu32 *) 0xCD00643C = 0x00000000; // 32Mhz on Bus
/* Copy Disc ID */
memcpy((void*)Online_Check, (void*)Disc_ID, 4);
}
/* Thanks Tinyload */
static struct {
u32 offset;
u32 type;
} partition_table[32] ATTRIBUTE_ALIGN(32);
static struct {
u32 count;
u32 offset;
u32 pad[6];
} part_table_info ATTRIBUTE_ALIGN(32);
s32 Disc_FindPartition(u32 *outbuf)
{
u32 offset = 0;
u32 cnt = 0;
/* Read partition info */
s32 ret = WDVD_UnencryptedRead(&part_table_info, sizeof(part_table_info), PART_INFO_OFFSET);
if(ret < 0)
return ret;
/* Read partition table */
ret = WDVD_UnencryptedRead(&partition_table, sizeof(partition_table), part_table_info.offset);
if(ret < 0)
return ret;
/* Find game partition */
for(cnt = 0; cnt < part_table_info.count; cnt++)
{
/* Game partition */
if(partition_table[cnt].type == 0)
{
offset = partition_table[cnt].offset;
break;
}
}
/* No game partition found */
if(offset == 0)
return -1;
WDVD_Seek(offset);
/* Set output buffer */
*outbuf = offset;
return 0;
}
GXRModeObj *Disc_SelectVMode(u8 videoselected, u32 *rmode_reg)
{
GXRModeObj *rmode = VIDEO_GetPreferredMode(0);
/* Get video mode configuration */
bool progressive = (CONF_GetProgressiveScan() > 0) && VIDEO_HaveComponentCable();
/* Select video mode register */
switch (CONF_GetVideo())
{
case CONF_VIDEO_PAL:
if (CONF_GetEuRGB60() > 0)
{
*rmode_reg = VI_EURGB60;
rmode = progressive ? &TVNtsc480Prog : &TVEurgb60Hz480IntDf;
}
else
*rmode_reg = VI_PAL;
break;
case CONF_VIDEO_MPAL:
*rmode_reg = VI_MPAL;
break;
case CONF_VIDEO_NTSC:
*rmode_reg = VI_NTSC;
break;
}
const char DiscRegion = ((u8*)Disc_ID)[3];
switch(videoselected)
{
case 0: // DEFAULT (DISC/GAME)
/* Select video mode */
switch(DiscRegion)
{
case 'W':
break; // Don't overwrite wiiware video modes.
// PAL
case 'D':
case 'F':
case 'P':
case 'X':
case 'Y':
if(CONF_GetVideo() != CONF_VIDEO_PAL)
{
*rmode_reg = VI_PAL;
rmode = progressive ? &TVNtsc480Prog : &TVNtsc480IntDf;
}
break;
// NTSC
case 'E':
case 'J':
default:
if(CONF_GetVideo() != CONF_VIDEO_NTSC)
{
*rmode_reg = VI_NTSC;
rmode = progressive ? &TVNtsc480Prog : &TVEurgb60Hz480IntDf;
}
break;
}
break;
case 1: // SYSTEM
break;
case 2: // PAL50
rmode = &TVPal528IntDf;
*rmode_reg = rmode->viTVMode >> 2;
break;
case 3: // PAL60
rmode = progressive ? &TVNtsc480Prog : &TVEurgb60Hz480IntDf;
*rmode_reg = progressive ? TVEurgb60Hz480Prog.viTVMode >> 2 : rmode->viTVMode >> 2;
break;
case 4: // NTSC
rmode = progressive ? &TVNtsc480Prog : &TVNtsc480IntDf;
*rmode_reg = rmode->viTVMode >> 2;
break;
case 5: // PROGRESSIVE 480P
rmode = &TVNtsc480Prog;
*rmode_reg = DiscRegion == 'P' ? TVEurgb60Hz480Prog.viTVMode >> 2 : rmode->viTVMode >> 2;
break;
default:
break;
}
return rmode;
}
void Disc_SetVMode(GXRModeObj *rmode, u32 rmode_reg)
{
/* Remove Load Bar */
video_clear();
/* Set video mode register */
*Video_Mode = rmode_reg;
DCFlushRange((void*)Video_Mode, 4);
/* Set video mode */
if(rmode != 0)
VIDEO_Configure(rmode);
/* Setup video */
VIDEO_SetBlack(FALSE);
VIDEO_Flush();
VIDEO_WaitVSync();
if(rmode->viTVMode & VI_NON_INTERLACE)
VIDEO_WaitVSync();
else while(VIDEO_GetNextField())
VIDEO_WaitVSync();
/* Set black and flush */
VIDEO_SetBlack(TRUE);
VIDEO_Flush();
VIDEO_WaitVSync();
if(rmode->viTVMode & VI_NON_INTERLACE)
VIDEO_WaitVSync();
else while(VIDEO_GetNextField())
VIDEO_WaitVSync();
}
s32 wbfsDev = 0;
u32 wbfs_part_idx = 0;
FragList *frag_list = NULL;
void copy_frag_list(FragList *src)
{
if(src == NULL)
return;
frag_list = malloc(sizeof(FragList)); //internal copy
memcpy(frag_list, src, sizeof(FragList));
}
static int set_frag_list()
{
// (+1 for header which is same size as fragment)
int size = sizeof(Fragment) * (frag_list->num + 1);
DCFlushRange(frag_list, size);
return WDVD_SetFragList(wbfsDev, frag_list, size);
}
s32 Disc_SetUSB(const u8 *id, bool frag)
{
/* ENABLE USB in cIOS */
if(id)
{
if(frag)
return set_frag_list();
s32 part = -1;
if(CurrentIOS.Type == IOS_TYPE_HERMES)
part = wbfs_part_idx ? wbfs_part_idx - 1 : 0;
return WDVD_SetUSBMode(wbfsDev, (u8*)id, part);
}
/* DISABLE USB in cIOS */
return WDVD_SetUSBMode(0, NULL, -1);
}