summaryrefslogtreecommitdiffstats
path: root/source/template.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/template.c')
-rw-r--r--source/template.c303
1 files changed, 303 insertions, 0 deletions
diff --git a/source/template.c b/source/template.c
new file mode 100644
index 0000000..8665774
--- /dev/null
+++ b/source/template.c
@@ -0,0 +1,303 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <gccore.h>
+#include <wiiuse/wpad.h>
+#include <inttypes.h>
+#include <string.h>
+
+#include "term.h"
+#include "state.h"
+
+static void *xfb = NULL;
+static GXRModeObj *rmode = NULL;
+
+#define TARGET_IOS 58
+
+static void initialize(int again) {
+ VIDEO_Init();
+
+ rmode = VIDEO_GetPreferredMode(NULL);
+ xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
+
+ console_init(xfb, 20, 20, rmode->fbWidth - 20, rmode->xfbHeight - 20, rmode->fbWidth * VI_DISPLAY_PIX_SZ);
+
+ VIDEO_Configure(rmode);
+ VIDEO_SetNextFramebuffer(xfb);
+ VIDEO_ClearFrameBuffer(rmode, xfb, COLOR_BLACK);
+ VIDEO_SetBlack(FALSE);
+ VIDEO_Flush();
+ VIDEO_WaitVSync();
+ if (rmode->viTVMode & VI_NON_INTERLACE) {
+ VIDEO_WaitVSync();
+ }
+
+ fputs(TERM_CLEAR TERM_CUR_POS(2, 5), stdout);
+ printf("USB Gecko (newnewexi) test tool by figboot\n\n");
+
+ s32 iosver = IOS_GetVersion();
+ s32 iosrev = IOS_GetRevision();
+ printf("You're running IOS%" PRId32 " rev %" PRId32 ".\n", iosver, iosrev);
+
+ if (iosver != TARGET_IOS) {
+ if (again) {
+ printf(TERM_CSI("93m") "Failed to set up IOS" STR(TARGET_IOS) "! Bailing out.\n");
+ exit(1);
+ }
+
+ printf("Trying to load IOS" STR(TARGET_IOS) "...\n");
+
+ s32 res;
+ if ((res = IOS_ReloadIOS(TARGET_IOS)) < 0) {
+ printf(TERM_CSI("93m") "Failed to set up IOS" STR(TARGET_IOS) "! IOS_ReloadIOS returned %" PRId32 "\n", res);
+ exit(1);
+ }
+
+ free(MEM_K1_TO_K0(xfb));
+ initialize(1);
+ }
+}
+
+static void __attribute__((noreturn)) fatal_error(void) {
+ printf("The program will now abort due to the fatal error.\n");
+ exit(1);
+}
+
+int main(int argc, char **argv)
+{
+ void *state_data = NULL;
+ size_t state_data_size = 0;
+ struct et_next_state next;
+ const struct et_state *cur_state = NULL;
+ int stateres = 0;
+
+ u32 wpad_pressed;
+ u32 pad_pressed;
+
+ initialize(0);
+
+ WPAD_Init();
+ PAD_Init();
+
+ printf("Done initializing.\n");
+
+ /* Set up initial state */
+ cur_state = et_state_setup;
+
+ if (cur_state->private_size > 0) {
+ state_data = malloc(cur_state->private_size);
+ state_data_size = cur_state->private_size;
+ if (!state_data) {
+ printf("Failed to allocate private space for setup state %p!", cur_state);
+ fatal_error();
+ }
+ }
+
+ if ((stateres = et_state_init(cur_state, state_data, et_init_data_null)) < 0) {
+ printf("Failed to init setup state %p: %d\n", cur_state, stateres);
+ fatal_error();
+ }
+
+ while (SYS_MainLoop()) {
+ WPAD_ScanPads();
+ PAD_ScanPads();
+
+ wpad_pressed = WPAD_ButtonsDown(0);
+ pad_pressed = PAD_ButtonsDown(0);
+
+ if (wpad_pressed & WPAD_BUTTON_HOME || pad_pressed & PAD_BUTTON_START) {
+ printf("Exit button pressed. Goodbye!\n");
+ exit(0);
+ }
+
+ stateres = et_state_tick(cur_state, state_data, &next);
+ if (stateres < 0) {
+ printf("Failed to tick state %p: %d\n", cur_state, stateres);
+ fatal_error();
+ }
+
+ if (stateres > 0) {
+ /* tear down the old state first... */
+ et_state_cleanup(cur_state, state_data);
+
+ cur_state = next.state;
+
+ if (state_data_size < cur_state->private_size) {
+ void *new_data = realloc(state_data, cur_state->private_size);
+ if (!new_data) {
+ printf("Failed to allocate %zu bytes for new state %p\n", cur_state->private_size, cur_state);
+ fatal_error();
+ }
+
+ state_data = new_data;
+ state_data_size = cur_state->private_size;
+ }
+
+ if ((stateres = et_state_init(cur_state, state_data, next.init_data)) < 0) {
+ printf("Failed to init new state %p: %d\n", cur_state, stateres);
+ fatal_error();
+ }
+ }
+
+ VIDEO_WaitVSync();
+ }
+
+ return 0;
+}
+
+#if 0
+
+//---------------------------------------------------------------------------------
+int main(int argc, char **argv) {
+//---------------------------------------------------------------------------------
+
+ // Initialise the video system
+ VIDEO_Init();
+
+ // This function initialises the attached controllers
+ WPAD_Init();
+
+ // Obtain the preferred video mode from the system
+ // This will correspond to the settings in the Wii menu
+ rmode = VIDEO_GetPreferredMode(NULL);
+
+ // Allocate memory for the display in the uncached region
+ xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
+
+ // Initialise the console, required for printf
+ console_init(xfb,20,20,rmode->fbWidth,rmode->xfbHeight,rmode->fbWidth*VI_DISPLAY_PIX_SZ);
+
+ // Set up the video registers with the chosen mode
+ VIDEO_Configure(rmode);
+
+ // Tell the video hardware where our display memory is
+ VIDEO_SetNextFramebuffer(xfb);
+
+ // 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();
+ if(rmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync();
+
+
+ // 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[2;0H");
+
+
+ printf("Hello World!\n");
+
+#define UGCHAN EXI_CHANNEL_1 /* slot B */
+#define UGDEV EXI_DEVICE_0 /* memory card */
+
+ if (EXI_Lock(UGCHAN, UGDEV, NULL) == 1) {
+ EXI_Select(UGCHAN, UGDEV, EXI_SPEED32MHZ);
+ uint32_t cmd = 0x90000000;
+ int res = 0;
+ if (EXI_Imm(UGCHAN, &cmd, sizeof(cmd), EXI_READWRITE, NULL) == 0) res |= 0x01;
+ if (EXI_Sync(UGCHAN) == 0) res |= 0x02;
+
+ if (res == 0) {
+ printf("Got: 0x%08x\n", cmd);
+ if (cmd != 0x04700000) {
+ printf("This is probably not a USB gecko...\n");
+ }
+ } else {
+ printf("EXI read/write error :( %#04x\n", res);
+ }
+
+ EXI_Deselect(UGCHAN);
+ EXI_Unlock(UGCHAN);
+ } else {
+ printf("Failed to lock EXI channel %d %d\n", UGCHAN, UGDEV);
+ goto waitexit;
+ }
+
+ for (int i = 0; i < 10; ++i) {
+ if (EXI_Lock(UGCHAN, UGDEV, NULL) == 0) {
+ printf("Failed to lock EXI for LED\n");
+ break;
+ }
+
+ int res = 0;
+
+ if (EXI_Select(UGCHAN, UGDEV, EXI_SPEED32MHZ) == 0) res |= 0x01;
+ uint32_t cmd = (i & 1) ? 0x80000000 : 0x70000000;
+ if (EXI_Imm(UGCHAN, &cmd, sizeof(cmd), EXI_WRITE, NULL) == 0) res |= 0x02;
+ if (EXI_Sync(UGCHAN) == 0) res |= 0x04;
+ if (EXI_Deselect(UGCHAN) == 0) res |= 0x08;
+
+ if (EXI_Unlock(UGCHAN) == 0) res |= 0x10;
+
+ printf("Error for LED: 0x%02x\n", res);
+
+ for (int j = 0; j < 60; ++j) {
+ VIDEO_WaitVSync();
+ }
+ }
+
+
+ for (int j = 0; j < 10; ++j) {
+ if (EXI_Lock(UGCHAN, UGDEV, NULL) == 1) {
+ printf("Sending a zillion bytes to your so-called \"usb gecko\"...\n");
+
+ for (int i = 0; i < 4096; ++i) {
+ EXI_Select(UGCHAN, UGDEV, EXI_SPEED32MHZ);
+
+ uint16_t cmd = 0xB000 | (uint16_t)(((i & 63) + 32) << 4);
+ if (EXI_Imm(UGCHAN, &cmd, sizeof(cmd), EXI_READWRITE, NULL) == 0) {
+ printf("Failed when writing %d\n", i);
+ goto error;
+ }
+
+ if (EXI_Sync(UGCHAN) == 0) {
+ printf("Failed sync when writing %d\n", i);
+ goto error;
+ }
+
+ if ((cmd & 0x0400) == 0) {
+ printf("Out of FIFO space at %d\n", i);
+ goto error;
+ }
+
+ EXI_Deselect(UGCHAN);
+ continue;
+error:
+ EXI_Deselect(UGCHAN);
+ break;
+ }
+
+ EXI_Unlock(UGCHAN);
+ } else {
+ printf("Failed to lock EXI channel %d %d\n", UGCHAN, UGDEV);
+ goto waitexit;
+ }
+ }
+
+waitexit:
+ printf("That's all! Press HOME to exit.\n");
+
+ while(SYS_MainLoop()) {
+
+ // Call WPAD_ScanPads each loop, this reads the latest controller states
+ WPAD_ScanPads();
+
+ // WPAD_ButtonsDown tells us which buttons were pressed in this loop
+ // this is a "one shot" state which will not fire again until the button has been released
+ u32 pressed = WPAD_ButtonsDown(0);
+
+ // We return to the launcher application via exit
+ if ( pressed & WPAD_BUTTON_HOME ) exit(0);
+
+ // Wait for the next frame
+ VIDEO_WaitVSync();
+ }
+
+ return 0;
+}
+#endif