#include #include #include #include #include #include #include #include //for sleep() #include #include "main.h" #include "gecko.h" void boot_elf(void *payload, size_t size); static void* xfb = NULL; void* initialise(); static GXRModeObj* rmode = NULL; const int min_row = 0; int max_row; int cursorrow; enum direction { UP,DOWN }; void move_cursor(enum direction d) { if (d == UP) { if(cursorrow > min_row) { //move cursor back one space printf("\033[1D"); //print space overwriting '>' printf(" "); --cursorrow; //move up a line printf("\033[1A"); //back 1 printf("\033[1D"); //overwrite space printf(">"); } } else if (d == DOWN) { if(cursorrow < max_row) { printf("\033[1D");//move cursor back 1 space printf(" ");//overwrite '>' ++cursorrow; printf("\033[1B");//move down a line printf("\033[1D");//back 1 printf(">");//overwrite space } } } int main(int argc, char** argv) { checkForGecko(); gprintf("Welcome to Yet Another Mod Fetcher"); xfb = initialise(); reset: cursorrow = 0;//reset cursor position to 0 every loop printf("\n\n\nYet Another Mod Fetcher\n"); printf("Use Dpad to select a mod\n"); printf("Press A to install\n"); printf("Installed mods are coloured green\n"); printf("Press + or x to boot mod (will hang if elf is too large)\n"); printf("Press home or start to quit\n"); if(!fatInitDefault()){printf("Initializing filesystem failed!\n"); exit(1);}//attempt to initalize filesystem download_file("files/wii/root.txt","root.txt",0);//download the root file and save it as "sd:/root.txt" max_row = parse_root_txt("sd:/root.txt");//max row = number of mods //move cursor back to first row and print '>' //up max_row+1 lines to be at the first line printf("\033[%dA", max_row+1); printf(">"); while(1) { VIDEO_WaitVSync(); WPAD_ScanPads(); PAD_ScanPads(); //get the button value for wii and gamecube remotes int buttonsDown = WPAD_ButtonsDown(0); int gcbuttonsDown = PAD_ButtonsDown(0); if((buttonsDown & WPAD_BUTTON_HOME) || (gcbuttonsDown & PAD_BUTTON_START)) { remove("sd:/root.txt"); printf("\033[2J"); printf("\n\nBye bye\n"); gprintf("Exiting"); exit(0); } else if((buttonsDown & WPAD_BUTTON_A)||(gcbuttonsDown & PAD_BUTTON_A)) { break;//install selected mod } else if((buttonsDown & WPAD_BUTTON_UP)||(gcbuttonsDown & PAD_BUTTON_UP)) { move_cursor(UP); } else if((buttonsDown & WPAD_BUTTON_DOWN)||(gcbuttonsDown & PAD_BUTTON_DOWN)) { move_cursor(DOWN); } else if((buttonsDown & WPAD_BUTTON_PLUS)||(gcbuttonsDown & PAD_BUTTON_X)) { FILE *fp = fopen("sd:/root.txt", "r"); fseek(fp, 0L, SEEK_END);//seek to the end of the file int size = ftell(fp);//store lenght of file rewind(fp);//seek back to start of file char buff[size]; buff[size] = '\0';//add null char to end of buff char *colon = buff;//discarded char *secondColon = buff;//location of second colon char *newLine = buff; //location of newline int count = 0; //current line while(1) { if (fgets(buff, size, fp) == NULL) { printf("Somethings wrong with root.txt\n"); gprintf("Somethings wrong with root.txt"); exit(1); }//get a single line from fp to buff if (cursorrow == count)//only parse root.txt if the correct line is reached { fclose(fp); colon = strstr(buff,":");//find colon in buff if (!colon) { printf("root.txt malformed!\n"); gprintf("root.txt malformed!"); exit(1); } secondColon = strstr(colon+1,":");//find second colon in buff if (!secondColon) { printf("root.txt malformed!\n"); gprintf("root.txt malformed!"); exit(1); } newLine = strstr(secondColon+1,"\n");//find newline in buff if (!newLine) { printf("root.txt malformed!\n"); gprintf("root.txt malformed!"); exit(1); } *newLine = '\0'; //replace newline with null char printf("\033[2J");//clear screen if (!strstr(secondColon+1,".elf")) { printf("\n\n\nNot an elf.\n"); printf("Falling back to sd:/boot.elf.\n"); gprintf("Not an elf."); gprintf("Falling back to sd:/boot.elf.\n"); memcpy(secondColon+1,"sd:/boot.elf",13);//replace original file with sd:/boot.elf sleep(1); } FILE *elf = fopen(secondColon+1, "r"); if (!elf) { printf("\n\n\nCould not open %s.\n", secondColon+1); printf("Falling back to sd:/boot.elf.\n"); gprintf("Could not open %s.", secondColon+1); gprintf("Falling back to sd:/boot.elf.\n"); sleep(1); elf = fopen("sd:/boot.elf", "r"); if (!elf){printf("sd:/boot.elf does not exist"); printf("\033[2J"); goto reset;} } fseek(elf, 0L, SEEK_END);//seek to the end of the file int size = ftell(elf);//store lenght of file rewind(elf);//seek back to start of file char *payload_elf = malloc(size*sizeof(char)); if (!payload_elf) { printf("Malloc failed!\n"); gprintf("Malloc failed!"); exit(1); } (void)fread(payload_elf, 1, size, elf);//if this fread fails here, we were going to crash anyway fclose(elf); boot_elf(payload_elf, size); printf("You should not be here\n"); } ++count; } /* printf("\033[2J");//clear screen FILE *elf = fopen("sd:/boot.elf", "r"); if (!elf){printf("Could not open root.txt\n"); gprintf("Could not open root.txt"); exit(1);} fseek(elf, 0L, SEEK_END);//seek to the end of the file int size = ftell(elf);//store lenght of file rewind(elf);//seek back to start of file //malloc is used since it seems to move the elf away from where is overwritten char *payload_elf = malloc(size*sizeof(char)); (void)fread(payload_elf, 1, size, elf);//if this fread fails here, we were going to crash anyway boot_elf(payload_elf, size); printf("You should not be here\n"); */ } } //clear screen printf("\033[2J"); //install selected mod install_mod("sd:/root.txt", cursorrow); int removed = remove("sd:/root.zip"); if (removed == -1){printf("Could not cleanup root.zip\n"); gprintf("Could not cleanup root.zip");} gprintf("Install Done"); printf("Install Done\n"); sleep(1); printf("\033[2J");//clear screen goto reset;//reset so you can install another mod or something... return 0; } //needs to be below main if you don't want a DSI void* initialise() { void *framebuffer; VIDEO_Init(); WPAD_Init(); PAD_Init(); rmode = VIDEO_GetPreferredMode(NULL); framebuffer = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode)); console_init(framebuffer,20,20,rmode->fbWidth,rmode->xfbHeight,rmode->fbWidth*VI_DISPLAY_PIX_SZ); VIDEO_Configure(rmode); VIDEO_SetNextFramebuffer(framebuffer); VIDEO_SetBlack(FALSE); VIDEO_Flush(); VIDEO_WaitVSync(); if(rmode->viTVMode&VI_NON_INTERLACE){VIDEO_WaitVSync(); return framebuffer;} return NULL; }