Any-Region-Changer-ModMii-E.../source/wiibasics.c

570 lines
12 KiB
C
Raw Normal View History

2022-04-21 02:12:38 +02:00
/*-------------------------------------------------------------
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
wiibasics.c -- basic Wii initialization and functions
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
Copyright (C) 2008 tona
Unless other credit specified
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
1.The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
2.Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
3.This notice may not be removed or altered from any source
distribution.
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
-------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <gccore.h>
#include <wiiuse/wpad.h>
#include <string.h>
#include "wiibasics.h"
#include "id.h"
#include "gecko.h"
#define MAX_WIIMOTES 4
static void *xfb = NULL;
static GXRModeObj *rmode = NULL;
int ConsoleRows;
int ConsoleCols;
u16 be16(const u8 *p)
{
return (p[0] << 8) | p[1];
}
u32 be32(const u8 *p)
{
return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
}
u64 be64(const u8 *p)
{
return ((u64)be32(p) << 32) | be32(p + 4);
}
2022-04-21 03:38:39 +02:00
u32 getTitleIDUID(u64 titleID)
{
2022-04-21 02:12:38 +02:00
s32 ret, i;
static u8 uid_buffer[0x1000] ATTRIBUTE_ALIGN(32);
u32 size;
ret = ISFS_ReadFileToArray("/sys/uid.sys", uid_buffer, 0x1000, &size);
if (ret < 0)
return 0;
2022-04-21 03:38:39 +02:00
for (i = 0; i < size; i += 12)
2022-04-21 02:12:38 +02:00
if (be64(&uid_buffer[i]) == titleID)
2022-04-21 03:38:39 +02:00
return be32(&uid_buffer[i + 8]);
2022-04-21 02:12:38 +02:00
return 0;
}
2022-04-21 03:38:39 +02:00
u64 getUIDTitleID(u32 uid)
{
2022-04-21 02:12:38 +02:00
s32 ret, i;
static u8 uid_buffer[0x1000] ATTRIBUTE_ALIGN(32);
u32 size;
ret = ISFS_ReadFileToArray("/sys/uid.sys", uid_buffer, 0x1000, &size);
if (ret < 0)
return 0;
2022-04-21 03:38:39 +02:00
for (i = 8; i < size; i += 12)
2022-04-21 02:12:38 +02:00
if (be32(&uid_buffer[i]) == uid)
2022-04-21 03:38:39 +02:00
return be64(&uid_buffer[i - 8]);
return 0;
2022-04-21 02:12:38 +02:00
}
/* Basic init taken pretty directly from the libOGC examples */
void basicInit(void)
{
// Initialise the video system
VIDEO_Init();
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
// Obtain the preferred video mode from the system
// This will correspond to the settings in the Wii menu
rmode = VIDEO_GetPreferredMode(NULL);
2022-04-21 03:38:39 +02:00
// rmode->viWidth = 678;
// rmode->viXOrigin = (VI_MAX_WIDTH_PAL - 678)/2;
2022-04-21 02:12:38 +02:00
GX_AdjustForOverscan(rmode, rmode, 32, 24);
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
// Allocate memory for the display in the uncached region
xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
// Initialise the console, required for printf
2022-04-21 03:38:39 +02:00
console_init(xfb, 0, 0, rmode->fbWidth, rmode->xfbHeight, rmode->fbWidth * VI_DISPLAY_PIX_SZ);
2022-04-21 02:12:38 +02:00
// Set up the video registers with the chosen mode
VIDEO_Configure(rmode);
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
// Tell the video hardware where our display memory is
VIDEO_SetNextFramebuffer(xfb);
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
// Make the display visible
VIDEO_SetBlack(FALSE);
// Flush the video register changes to the hardware
VIDEO_Flush();
// Wait for Video setup to complete
VIDEO_WaitVSync();
2022-04-21 03:38:39 +02:00
if (rmode->viTVMode & VI_NON_INTERLACE)
VIDEO_WaitVSync();
2022-04-21 02:12:38 +02:00
// The console understands VT terminal escape codes
// This positions the cursor on row 2, column 0
// we can use variables for this with format codes too
// e.g. printf ("\x1b[%d;%dH", row, column );
2022-04-21 03:38:39 +02:00
// printf("\x1b[2;0H");
2022-04-21 02:12:38 +02:00
CON_GetMetrics(&ConsoleCols, &ConsoleRows);
}
2022-04-21 03:38:39 +02:00
void ClearScreen()
{
/* Clear console */
printf("\x1b[2J");
fflush(stdout);
2022-04-21 02:12:38 +02:00
}
2022-04-21 03:38:39 +02:00
void ClearLine()
{
printf("\r\x1b[2K\r");
fflush(stdout);
2022-04-21 02:12:38 +02:00
}
2022-04-21 03:38:39 +02:00
void PrintCenter(char *text, int width)
{
int textLen = strlen(text);
int leftPad = (width - textLen) / 2;
int rightPad = (width - textLen) - leftPad;
printf("%*s%s%*s", leftPad, " ", text, rightPad, " ");
2022-04-21 02:12:38 +02:00
}
2022-04-21 03:38:39 +02:00
void Console_SetFgColor(u8 color, u8 bold)
{
printf("\x1b[%u;%dm", color + 30, bold);
2022-04-21 02:12:38 +02:00
}
2022-04-21 03:38:39 +02:00
void Console_SetBgColor(u8 color, u8 bold)
{
printf("\x1b[%u;%dm", color + 40, bold);
2022-04-21 02:12:38 +02:00
}
2022-04-21 03:38:39 +02:00
void Console_SetColors(u8 bgColor, u8 bgBold, u8 fgColor, u8 fgBold)
{
Console_SetBgColor(bgColor, bgBold);
Console_SetFgColor(fgColor, fgBold);
2022-04-21 02:12:38 +02:00
}
2022-04-21 03:38:39 +02:00
void Console_SetPosition(u8 row, u8 column)
{
// The console understands VT terminal escape codes
// This positions the cursor on row 2, column 0
// we can use variables for this with format codes too
// e.g. printf ("\x1b[%d;%dH", row, column );
printf("\x1b[%u;%uH", row, column);
2022-04-21 02:12:38 +02:00
}
2022-04-21 03:38:39 +02:00
void PrintBanner()
{
ClearScreen();
Console_SetColors(GREEN, 0, WHITE, 2);
char text[ConsoleCols];
snprintf(text, sizeof(text), "Any Region Changer ModMii Edition %.1lf.%i IOS: %i", ARCME_VERSION, ARCME_REV, IOS_GetVersion());
PrintCenter(text, ConsoleCols);
Console_SetColors(BLACK, 0, WHITE, 2);
2022-04-21 02:12:38 +02:00
}
void miscInit(void)
{
int ret;
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
// This function initialises the attached controllers
WPAD_Init();
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
Identify_SU();
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
gprintf("Initializing Filesystem driver...");
fflush(stdout);
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
ret = ISFS_Initialize();
2022-04-21 03:38:39 +02:00
if (ret < 0)
{
2022-04-21 02:12:38 +02:00
gprintf("\nError! ISFS_Initialize (ret = %d)\n", ret);
wait_anyKey();
exit(0);
2022-04-21 03:38:39 +02:00
}
else
{
2022-04-21 02:12:38 +02:00
gprintf("OK!\n");
}
2022-04-21 03:38:39 +02:00
// IdentSysMenu();
2022-04-21 02:12:38 +02:00
}
2022-04-21 03:38:39 +02:00
void IdentSysMenu(void)
{
2022-04-21 02:12:38 +02:00
int ret;
Identify_SysMenu();
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
ret = ES_SetUID(TITLE_ID(1, 2));
2022-04-21 03:38:39 +02:00
if (ret < 0)
{
2022-04-21 02:12:38 +02:00
printf("SetUID fail %d", ret);
wait_anyKey();
exit(1);
}
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
printf("Initializing Filesystem driver...");
fflush(stdout);
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
ISFS_Deinitialize();
ret = ISFS_Initialize();
2022-04-21 03:38:39 +02:00
if (ret < 0)
{
2022-04-21 02:12:38 +02:00
printf("\nError! ISFS_Initialize (ret = %d)\n", ret);
wait_anyKey();
exit(1);
2022-04-21 03:38:39 +02:00
}
else
{
2022-04-21 02:12:38 +02:00
printf("OK!\n");
}
}
void miscDeInit(void)
{
fflush(stdout);
ISFS_Deinitialize();
}
u32 getButtons(void)
{
WPAD_ScanPads();
return WPAD_ButtonsDown(0);
}
2022-04-21 03:38:39 +02:00
u32 wait_anyKey(void)
{
2022-04-21 02:12:38 +02:00
u32 pressed;
2022-04-21 03:38:39 +02:00
while (!(pressed = getButtons()))
{
2022-04-21 02:12:38 +02:00
VIDEO_WaitVSync();
}
2022-04-21 03:38:39 +02:00
if (pressed & WPAD_BUTTON_HOME)
{
Console_SetPosition(26, 0);
2022-04-21 02:12:38 +02:00
ClearLine();
2022-04-21 03:38:39 +02:00
Console_SetPosition(26, 30);
2022-04-21 02:12:38 +02:00
Console_SetColors(BLACK, 0, GREEN, 0);
printf("Exiting");
exit(0);
}
return pressed;
}
2022-04-21 03:38:39 +02:00
u32 wait_key(u32 button)
{
2022-04-21 02:12:38 +02:00
u32 pressed;
2022-04-21 03:38:39 +02:00
do
{
2022-04-21 02:12:38 +02:00
VIDEO_WaitVSync();
pressed = getButtons();
2022-04-21 03:38:39 +02:00
if (pressed & WPAD_BUTTON_HOME)
{
Console_SetPosition(26, 0);
2022-04-21 02:12:38 +02:00
ClearLine();
2022-04-21 03:38:39 +02:00
Console_SetPosition(26, 30);
2022-04-21 02:12:38 +02:00
Console_SetColors(BLACK, 0, GREEN, 0);
printf("Exiting");
exit(0);
}
2022-04-21 03:38:39 +02:00
} while (!(pressed & button));
2022-04-21 02:12:38 +02:00
return pressed;
}
2022-04-21 03:38:39 +02:00
char charASCII(u8 c)
{
2022-04-21 02:12:38 +02:00
if (c < 0x20 || c > 0x7E)
return '.';
else
return (char)c;
}
2022-04-21 03:38:39 +02:00
void hex_print_array16(const u8 *array, u32 size)
{
2022-04-21 02:12:38 +02:00
u32 offset = 0;
u32 page_size = 0x100;
char line[17];
line[16] = 0;
if (size > page_size)
2022-04-21 03:38:39 +02:00
printf("Page 1 of %lu", (size / page_size) + 1);
while (offset < size)
{
if (!(offset % 16))
printf("\n0x%08lX: ", offset);
2022-04-21 02:12:38 +02:00
printf("%02X", array[offset]);
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
line[offset % 16] = charASCII(array[offset]);
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
if (!(++offset % 2))
printf(" ");
2022-04-21 03:38:39 +02:00
if (!(offset % 16))
2022-04-21 02:12:38 +02:00
printf(line);
2022-04-21 03:38:39 +02:00
if (!(offset % page_size) && offset < size)
{
2022-04-21 02:12:38 +02:00
u32 pressed;
printf("\n\tPress a key for next page or B for finish\n");
pressed = wait_anyKey();
if (pressed & WPAD_BUTTON_HOME)
exit(1);
else if (pressed & WPAD_BUTTON_B)
return;
}
}
}
2022-04-21 03:38:39 +02:00
bool yes_or_no(void)
{
2022-04-21 02:12:38 +02:00
bool yes = 0;
u32 buttons = 0;
2022-04-21 03:38:39 +02:00
do
{
2022-04-21 02:12:38 +02:00
yes = buttons & WPAD_BUTTON_LEFT;
2022-04-21 03:38:39 +02:00
if (yes)
2022-04-21 02:12:38 +02:00
printf("\r\x1b[K <\x1b[30m\x1b[47;1m Yes \x1b[37;1m\x1b[40m> No ");
2022-04-21 03:38:39 +02:00
else
printf("\r\x1b[K Yes <\x1b[30m\x1b[47;1m No \x1b[37;1m\x1b[40m> ");
} while ((buttons = wait_key(WPAD_BUTTON_A | WPAD_BUTTON_LEFT | WPAD_BUTTON_RIGHT)) && (!(buttons & WPAD_BUTTON_A)));
2022-04-21 02:12:38 +02:00
printf("\n");
2022-04-21 03:38:39 +02:00
return yes;
2022-04-21 02:12:38 +02:00
}
/* Reads a file from ISFS to an array in memory */
2022-04-21 03:38:39 +02:00
s32 ISFS_ReadFileToArray(const char *filepath, u8 *filearray, u32 max_size, u32 *file_size)
{
2022-04-21 02:12:38 +02:00
s32 ret, fd;
static fstats filestats ATTRIBUTE_ALIGN(32);
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
*file_size = 0;
ret = ISFS_Open(filepath, ISFS_OPEN_READ);
if (ret <= 0)
{
printf("Error! ISFS_Open (ret = %ld)\n", ret);
return -1;
}
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
fd = ret;
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
ret = ISFS_GetFileStats(fd, &filestats);
if (ret < 0)
{
printf("Error! ISFS_GetFileStats (ret = %ld)\n", ret);
return -1;
}
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
*file_size = filestats.file_length;
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
if (*file_size > max_size)
{
printf("File is too large! Size: %lu Max: %lu", *file_size, max_size);
return -1;
}
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
ret = ISFS_Read(fd, filearray, *file_size);
*file_size = ret;
if (ret < 0)
{
printf("Error! ISFS_Read (ret = %ld)\n", ret);
return -1;
2022-04-21 03:38:39 +02:00
}
2022-04-21 02:12:38 +02:00
else if (ret != filestats.file_length)
{
printf("Error! ISFS_Read Only read: %ld\n", ret);
return -1;
}
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
ret = ISFS_Close(fd);
if (ret < 0)
{
printf("Error! ISFS_Close (ret = %ld)\n", ret);
return -1;
}
return 0;
}
/* Writes from an array in memory to a file with ISFS */
2022-04-21 03:38:39 +02:00
s32 ISFS_WriteFileFromArray(const char *filepath, const u8 *filearray, u32 array_size, u32 ownerID, u16 groupID, u8 attr, u8 own_perm, u8 group_perm, u8 other_perm)
{
2022-04-21 02:12:38 +02:00
s32 ret, fd = 0, out;
u64 currentTid;
u32 realownid;
u16 realgroupid;
u8 realattr, realownperm, realgroupperm, realotherperm;
static fstats filestats ATTRIBUTE_ALIGN(32);
out = 0;
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
ret = ISFS_Open(filepath, ISFS_OPEN_WRITE);
2022-04-21 03:38:39 +02:00
if (ret == -102)
{
2022-04-21 02:12:38 +02:00
printf("\tMaking file writable...\n");
ret = ISFS_SetAttr(filepath, ownerID, groupID, attr, 3, 3, 3);
if (ret < 0)
{
printf("Error! ISFS_SetAttr (ret = %ld)\n", ret);
out = -1;
goto cleanup;
}
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
return ISFS_WriteFileFromArray(filepath, filearray, array_size, ownerID, groupID, attr, own_perm, group_perm, other_perm);
2022-04-21 03:38:39 +02:00
}
else if (ret == -106)
{
2022-04-21 02:12:38 +02:00
printf("\tCreating file...\n");
ret = ISFS_CreateFile(filepath, attr, 3, 3, 3);
2022-04-21 03:38:39 +02:00
if (ret < 0)
{
2022-04-21 02:12:38 +02:00
printf("Error! ISFS_CreateFile (ret = %ld)\n", ret);
out = -1;
goto cleanup;
2022-04-21 03:38:39 +02:00
}
2022-04-21 02:12:38 +02:00
return ISFS_WriteFileFromArray(filepath, filearray, array_size, ownerID, groupID, attr, own_perm, group_perm, other_perm);
2022-04-21 03:38:39 +02:00
}
else if (ret <= 0)
{
2022-04-21 02:12:38 +02:00
printf("Error! ISFS_Open WRITE (ret = %ld)\n", ret);
out = -1;
goto cleanup;
}
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
fd = ret;
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
ret = ISFS_Seek(fd, 0, 0);
2022-04-21 03:38:39 +02:00
if (ret < 0)
{
2022-04-21 02:12:38 +02:00
printf("Error! ISFS_Seek (ret = %ld)\n", ret);
out = -1;
goto cleanup;
}
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
ret = ISFS_Write(fd, filearray, array_size);
if (ret < 0)
{
printf("Error! ISFS_Write (ret = %ld)\n", ret);
out = -1;
goto cleanup;
}
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
if (ret != array_size)
{
printf("Filesize is wrong! Wrote:%lu Expect:%lu", filestats.file_length, array_size);
out = -1;
}
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
ret = ISFS_Close(fd);
if (ret < 0)
{
printf("Error! ISFS_Close (ret = %ld)\n", ret);
return -1;
}
fd = 0;
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
/*
ret = ISFS_Open(filepath, ISFS_OPEN_READ);
if (ret <= 0) {
printf("Error! ISFS_Open READ (ret = %d)\n", ret);
out = -1;
goto cleanup;
}
fd = ret;
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
ret = ISFS_GetFileStats(fd, &filestats);
if (ret < 0)
{
printf("Error! ISFS_GetFileStats (ret = %d)\n", ret);
out = -1;
goto cleanup;
}
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
ret = ISFS_Close(fd);
if (ret < 0)
{
printf("Error! ISFS_Close (ret = %d)\n", ret);
return -1;
}
fd = 0;
*/
ret = ISFS_GetAttr(filepath, &realownid, &realgroupid, &realattr, &realownperm, &realgroupperm, &realotherperm);
if (ret < 0)
{
printf("Error! ISFS_GetAttr (ret = %ld)\n", ret);
out = -1;
}
2022-04-21 03:38:39 +02:00
if (realownid != ownerID)
{
2022-04-21 02:12:38 +02:00
ret = ES_GetTitleID(&currentTid);
2022-04-21 03:38:39 +02:00
if (ret)
{
2022-04-21 02:12:38 +02:00
printf("Fail GetTitleID %ld", ret);
2022-04-21 03:38:39 +02:00
if (wait_key(WPAD_BUTTON_A | WPAD_BUTTON_B) & WPAD_BUTTON_B)
goto cleanup;
2022-04-21 02:12:38 +02:00
}
ret = ES_SetUID(getUIDTitleID(ownerID));
2022-04-21 03:38:39 +02:00
if (ret)
{
2022-04-21 02:12:38 +02:00
printf("Couldn't set OwnerID, using current owner ID\n");
2022-04-21 03:38:39 +02:00
if (wait_key(WPAD_BUTTON_A | WPAD_BUTTON_B) & WPAD_BUTTON_B)
goto cleanup;
2022-04-21 02:12:38 +02:00
ownerID = realownid;
}
}
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
ret = ISFS_SetAttr(filepath, ownerID, groupID, attr, own_perm, group_perm, other_perm);
if (ret < 0)
{
printf("Error! ISFS_SetAttr (ret = %ld)\n", ret);
out = -1;
goto cleanup;
}
2022-04-21 03:38:39 +02:00
if (realownid != ownerID)
{
2022-04-21 02:12:38 +02:00
ret = ES_SetUID(currentTid);
2022-04-21 03:38:39 +02:00
if (ret)
{
2022-04-21 02:12:38 +02:00
printf("Fail SetUID %ld", ret);
2022-04-21 03:38:39 +02:00
if (wait_key(WPAD_BUTTON_A | WPAD_BUTTON_B) & WPAD_BUTTON_B)
goto cleanup;
2022-04-21 02:12:38 +02:00
}
}
2022-04-21 03:38:39 +02:00
cleanup:
if (fd)
{
2022-04-21 02:12:38 +02:00
ret = ISFS_Close(fd);
if (ret < 0)
{
printf("Error! ISFS_Close (ret = %ld)\n", ret);
return -1;
}
}
return out;
2022-04-21 03:38:39 +02:00
}