alt64/menu.c

4454 lines
128 KiB
C

/*
* ALT64 Menu v0.1.8.6 - 2013
* a menu for the Everdrive64
* based on libdragon, Neo64Menu, ED64IO, libn64-hkz, libmikmod
* by saturnu
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include <math.h>
//libdragon n64 lib
#include <libdragon.h>
//everdrive system libs
#include "types.h"
#include "sys.h"
#include "everdrive.h"
#include "everdrive.h"
//filesystem
#include "disk.h"
#include "fat.h"
//utils
#include "utils.h"
//config file on sd
#include "ini.h"
#include "strlib.h"
//menu header
#include "menu.h"
//sound
#include <mikmod.h>
#include "mp3.h"
// YAML parser
#include <yaml.h>
#ifdef USE_TRUETYPE
#define STB_TRUETYPE_IMPLEMENTATION
#include "stb_truetype.h"
struct glyph {
int xoff;
int yoff;
int adv;
int lsb;
float scale;
unsigned int color;
unsigned char *alpha;
sprite_t sprite;
};
typedef struct glyph glyph_t;
glyph_t sans[96];
glyph_t serif[96];
#endif
typedef struct
{
uint32_t type;
uint32_t color;
char filename[MAX_FILENAME_LEN+1];
} direntry_t;
//ini file
typedef struct
{
int version;
const char* name;
char* background_image;
char* border_color_1;
char* border_color_2;
char* box_color;
char* selection_color;
char* list_font_color;
char* list_dir_font_color;
char* selection_font_color;
char* mempak_path;
char* save_path;
int sound_on;
int page_display;
int tv_mode;
int quick_boot;
int enable_colored_list;
int ext_type;
int cd_behaviour;
int scroll_behaviour;
int text_offset;
int hide_sysfolder;
int sd_speed;
} configuration;
volatile u32 *romaddr_ptr = (u32 *) ROM_ADDR;
unsigned int gBootCic=CIC_6102;
u8 debug=DBG_MODE;
static uint8_t mempak_data[128 * 256];
static void *bg_buffer;
void *__safe_bg_buffer;
#define __get_buffer( x ) __safe_buffer[(x)-1]
extern uint32_t __bitdepth;
extern uint32_t __width;
extern uint32_t __height;
extern void *__safe_buffer[];
char firmware_str[64];
int firm_found=0;
char rom_config[10];
display_context_t lockVideo(int wait);
int select_mode = 0;
int toplist_reload=1;
int toplist_cursor=0;
char toplist15[15][256];
int fat_initialized=0;
int exit_ok = 0;
int boot_cic=0;
int boot_save=0;
int cursor_line=0;
int cursor_lastline=0;
u16 cursor_history[32];
u16 cursor_history_pos=0;
u8 empty=0;
u8 playing=0;
u8 gb_load_y=0;
//start with filebrowser menu key settings
int input_mapping=1;
/* 1=filemanager
* 2=mempak-menu
* 3=charinput
* 4=rom loaded
* 5=format mpk
* 6=restore mpk
* 7=rom config box
* 8=toplist
* 9=mpk choice
* 10=mpk quick-backup
* 11=mp3
* 98= A/B abort screen
*/
//holds the string of the character input screen result
int text_input_on=0;
//char input vars
int x,y,position,set;
unsigned char input_text[32];
uint32_t chr_forecolor;
uint32_t chr_backcolor;
//save type still set - save todo after reboot
int save_reboot=0;
//cart id from rom header
unsigned char cartID[4];
char curr_dirname[64];
char pwd[64];
char rom_filename[128];
u32 rom_buff[128]; //rom buffer
u8 *rom_buff8; //rom buffer
u8 *firmware;
u8 gbload=0;
int cheats_on=0;
int checksum_fix_on=0;
short int gCheats = 0; /* 0 = off, 1 = select, 2 = all */
short int force_tv = 0;
short int boot_country=0;
static resolution_t res = RESOLUTION_320x240;
//background sprites
sprite_t *loadPng(u8 *png_filename);
sprite_t *background; //background
sprite_t *background0; //splash screen
//config file theme settings
u32 border_color_1=0xFFFFFFFF; //hex 0xRRGGBBAA AA=transparenxy
u32 border_color_2=0x3F3F3FFF;
u32 box_color=0x00000080;
u32 selection_color=0x6495ED60;
u32 selection_font_color=0xFFFFFFFF;
u32 list_font_color=0xFFFFFFFF;
u32 list_dir_font_color=0xFFFFFFFF;
char* border_color_1_s;
char* border_color_2_s;
char* box_color_s;
char* selection_color_s;
char* selection_font_color_s;
char* list_font_color_s;
char* list_dir_font_color_s;
char* mempak_path;
char* save_path;
u8 sound_on=0;
u8 page_display=0;
int text_offset=0;
u8 tv_mode=0; // 1=ntsc 2=pal 3=mpal 0=default automatic
u8 quick_boot=0;
u8 enable_colored_list=0;
u8 cd_behaviour=0; //0=first entry 1=last entry
u8 scroll_behaviour=0; //1=classic 0=new page-system
u8 ext_type=0; //0=classic 1=org os
u8 sd_speed=1; // 1=25Mhz 2=50Mhz
u8 hide_sysfolder=0;
char* background_image;
//toplist helper
int list_pos_backup[3];
char list_pwd_backup[256];
char dirz[512] = "rom://";
short int gCursorX;
short int gCursorY;
int count = 0;
int page = 0;
int cursor = 0;
direntry_t *list;
int filesize( FILE *pFile )
{
fseek( pFile, 0, SEEK_END );
int lSize = ftell( pFile );
rewind( pFile );
return lSize;
}
sprite_t *read_sprite( const char * const spritename ) {
FILE *fp = fopen( spritename, "r" );
if( fp ) {
sprite_t *sp = malloc( filesize( fp ) );
fread( sp, 1, filesize( fp ), fp );
fclose( fp );
return sp;
}
else {
return 0;
}
}
void drawSelection(display_context_t disp,int p){
int s_x=23+(text_offset*8);
if(scroll_behaviour){
if(select_mode){
if(cursor_lastline>cursor && cursor_line > 0) {
cursor_line--;
}
if(cursor_lastline<cursor && cursor_line < 19) {
cursor_line++;
}
p=cursor_line;
graphics_draw_box_trans(disp, s_x, (((p+3)*8)+24), 272, 8, selection_color); //(p+3) diff
cursor_lastline=cursor;
}
}
else { //new page-system
//accept p
graphics_draw_box_trans(disp, s_x, (((p+3)*8)+24), 272, 8, selection_color);
}
}
void drawConfigSelection(display_context_t disp,int l){
int s_x=62+(text_offset*8);
l=l+5;
graphics_draw_box_trans(disp, s_x, (((l+3)*8)+24), 193, 8, 0x00000080); //(p+3) diff
}
void drawToplistSelection(display_context_t disp,int l){
int s_x=30+(text_offset*8);
l=l+2;
graphics_draw_box_trans(disp, s_x, (((l+3)*8)+24), 256, 8, 0xFFFFFF70); //(p+3) diff
}
void chdir( const char * const dirent ) {
/* Ghetto implementation */
if( strcmp( dirent, ".." ) == 0 ) {
/* Go up one */
int len = strlen( dirz ) - 1;
/* Stop going past the min */
if( dirz[len] == '/' && dirz[len-1] == '/' && dirz[len-2] == ':' ) {
//return if ://
return;
}
if( dirz[len] == '/' ) {
dirz[len] = 0;
len--;
}
while( dirz[len] != '/') {
dirz[len] = 0;
len--;
}
}
else {
/* Add to end */
strcat( dirz, dirent );
strcat( dirz, "/" );
}
}
int compare(const void * a, const void * b) {
direntry_t *first = (direntry_t *)a;
direntry_t *second = (direntry_t *)b;
if(first->type == DT_DIR && second->type != DT_DIR) {
/* First should be first */
return -1;
}
if(first->type != DT_DIR && second->type == DT_DIR) {
/* First should be second */
return 1;
}
return strcmp(first->filename, second->filename);
}
int compare_int (const void *a, const void *b) {
const int *ia = (const int *)a; // casting pointer types
const int *ib = (const int *)b;
return *ia - *ib;
}
int compare_int_reverse (const void *a, const void *b) {
const int *ia = (const int *)a; // casting pointer types
const int *ib = (const int *)b;
return *ib - *ia;
}
void free_dir(direntry_t *dirz) {
if(dirz) { free(dirz); }
}
void new_scroll_pos(int *cursor, int *page, int max, int count) {
/* Make sure windows too small can be calculated right */
if(max > count) {
max = count;
}
/* Bounds checking */
if(*cursor >= count) {
*cursor = count-1;
}
if(*cursor < 0) {
*cursor = 0;
}
/* Scrolled up? */
if(*cursor < *page) {
*page = *cursor;
return;
}
/* Scrolled down/ */
if(*cursor >= (*page + max)) {
*page = (*cursor - max) + 1;
return;
}
/* Nothing here, should be good! */
}
void display_dir(direntry_t *list, int cursor, int page, int max, int count, display_context_t disp) {
//system color
uint32_t forecolor=0;
uint32_t forecolor_menu=0;
uint32_t backcolor;
backcolor = graphics_make_color(0x00, 0x00, 0x00, 0xFF); //bg
forecolor_menu = graphics_make_color(0xFF, 0xFF, 0xFF, 0xFF); //fg
graphics_set_color (list_font_color, backcolor);
u8 c_pos[MAX_LIST+1];
int c_pos_counter=0;
c_pos[c_pos_counter++]=0;
u8 c_dirname[64];
if(page_display){
u8 pi = page/20;
u8 ci=0;
if(count%20==0)
ci = (count-1)/20;
else
ci = count/20;
sprintf(c_dirname, "%i/%i SD:/%s", pi+1, ci+1, pwd);
}
else{
sprintf(c_dirname, "SD:/%s", pwd);
}
char sel_str[128];
printText(c_dirname, 3, 4, disp);
int firstrun=1;
/* Page bounds checking */
if(max > count) { //count = directories starting at 1
max = count;
}
/* Cursor bounds checking */
if(cursor >= (page + max)) {
cursor = (page + max) - 1;
}
if(cursor < page) {
cursor = page;
}
if( max == 0 ) {
printText("dir empty...", 3, 6, disp);
sprintf(sel_str, "dir empty...");
empty=1;
}
else {
empty=0;
}
//last page anti ghosting entries
if(page == (count/20)*20)
max=count%20;
for(int i = page; i < (page + max); i++) {//from page to page + max
if(list[i].type == DT_DIR) {
char tmpdir[(CONSOLE_WIDTH-5)+1];
strncpy(tmpdir, list[i].filename, CONSOLE_WIDTH-5);
tmpdir[CONSOLE_WIDTH-5] = 0;
char *dir_str;
dir_str = malloc(slen(tmpdir)+3);
if(i == cursor){
sprintf(dir_str, " [%s]", tmpdir);
sprintf(sel_str, " [%s]", tmpdir);
if(scroll_behaviour)
drawSelection(disp,i);
c_pos[c_pos_counter++]=1;
}
else{
sprintf(dir_str, "[%s]", tmpdir);
c_pos[c_pos_counter++]=0;
}
graphics_set_color (list_dir_font_color, backcolor);
if(firstrun){
printText(dir_str, 3, 6, disp);
firstrun=0;
}
else{
printText(dir_str, 3, -1, disp);
}
free(dir_str);
}
else { //if(list[i].type == DT_REG)
int fcolor=list[i].color;
if(fcolor!=0){
switch(fcolor){
case 1: forecolor = graphics_make_color(0xFF, 0xFF, 0xFF, 0xFF); //common (white)
break;
case 2: forecolor = graphics_make_color(0x00, 0xFF, 0x00, 0xCF); //uncommon (green)
break;
case 3: forecolor = graphics_make_color(0x1E, 0x90, 0xFF, 0xFF); //rare (blue)
break;
case 4: forecolor = graphics_make_color(0x9B, 0x30, 0xFF, 0xFF); //epic (purple)
break;
case 5: forecolor = graphics_make_color(0xFF, 0xA5, 0x00, 0xFF); //legendary (orange)
break;
default:
break;
}
}
else
forecolor = list_font_color;
char tmpdir[(CONSOLE_WIDTH-3)+1];
strncpy(tmpdir, list[i].filename, CONSOLE_WIDTH-3);
tmpdir[CONSOLE_WIDTH-3] = 0;
char *dir_str;
dir_str = malloc(slen(tmpdir)+1);
if(i == cursor){
sprintf(dir_str, " %s", tmpdir);
sprintf(sel_str, " %s", tmpdir);
if(scroll_behaviour)
drawSelection(disp,i);
c_pos[c_pos_counter++]=1;
}
else{
sprintf(dir_str, "%s", tmpdir);
c_pos[c_pos_counter++]=0;
}
graphics_set_color(list_font_color, backcolor);
if(firstrun){
if(enable_colored_list)
graphics_set_color(forecolor, backcolor);
printText(dir_str, 3, 6, disp); //3,6
firstrun=0;
}
else{
if(enable_colored_list)
graphics_set_color(forecolor, backcolor);
printText(dir_str, 3, -1, disp); //3,1
}
free(dir_str);
}
}
//for page-wise scrolling
if(scroll_behaviour==0){
int c=0;
for(c=0;c<max+1;c++){
if(c_pos[c]==1){
drawSelection(disp,c-1);
//todo: set selection color
graphics_set_color(selection_font_color, backcolor);
printText(sel_str, 3, 6+c-1, disp);
graphics_set_color(forecolor, backcolor);
}
}
}
graphics_set_color(forecolor_menu, backcolor);
}
void printText(char *msg, int x, int y, display_context_t dcon) {
x=x+text_offset;
if (x != -1)
gCursorX = x;
if (y != -1)
gCursorY = y;
if (dcon)
graphics_draw_text(dcon, gCursorX*8, gCursorY*8, msg);
gCursorY++;
if (gCursorY > 29) {
gCursorY = 0;
gCursorX ++;
}
}
void lprintText(char *msg, int x, int y, display_context_t dcon) {
x=x+text_offset;
if (x != -1)
gCursorX = x;
if (y != -1)
gCursorY = y;
if (dcon)
graphics_draw_text(dcon, gCursorX*8, gCursorY*8, msg);
if (gCursorY > 29) {
gCursorY = 0;
gCursorX ++;
}
}
//background sprite
void drawBg(display_context_t disp){
graphics_draw_sprite( disp, 0, 0, background );
}
void drawBox(short x, short y, short width, short height, display_context_t disp){
x=x+(text_offset*8);
/*
* |Y
* | x0/y0
* |
* |
* | x1/y1
* |_______________X
*
*/
// X0 Y0 X1 Y1
graphics_draw_line(disp, x, y, width+x, y, border_color_1); //A top left tp bottom right ok
graphics_draw_line(disp, width+x, y, width+x, height+y, border_color_1); //B top right to bottom right
graphics_draw_line(disp, x, y, x, height+y, border_color_2); //C //152-20
graphics_draw_line(disp, x, height+y, width+x, height+y, border_color_2); //D
graphics_draw_box_trans(disp, x+1, y+1, width-1, height-1, box_color); //red light transparent
}
void drawBoxNumber(display_context_t disp, int box){
int old_color = box_color;
//backup color
switch(box){
case 1: drawBox(20, 24, 277, 193, disp); break; //filebrowser
case 2: drawBox(60, 56, 200, 128, disp); break; //info screen
case 3:
box_color= graphics_make_color(0x00, 0x00, 0x60, 0xC9);
drawBox(79, 29, 161, 180, disp);
break; //cover
case 4:
box_color= graphics_make_color(0x30, 0x00, 0x00, 0xA3);
drawBox(79, 29, 161, 180, disp);
break; //mempak content
case 5:
box_color= graphics_make_color(0x60, 0x00, 0x00, 0xD3);
drawBox(60, 64, 197, 114, disp); //red confirm screen
break; //mempak content
case 6:
box_color= graphics_make_color(0x60, 0x60, 0x00, 0xC3);
drawBox(60, 64, 197, 125, disp); //yellow screen
break; //rom config box
case 7:
box_color= graphics_make_color(0x00, 0x00, 0x60, 0xC3);
drawBox(60, 105, 197, 20, disp); //blue info screen
break; //info screen
case 8:
box_color= graphics_make_color(0x60, 0x00, 0x00, 0xD3);
drawBox(60, 105, 197, 20, disp); //red error screen
break; //info screen
case 9:
box_color= graphics_make_color(0x00, 0x00, 0x00, 0xB6);
drawBox(28, 49, 260, 150, disp);
break; //yellow toplist
case 10:
box_color= graphics_make_color(0x00, 0x60, 0x00, 0xC3);
drawBox(60, 105, 197, 20, disp); //green info screen
break; //info screen
case 11:
box_color= graphics_make_color(0x00, 0x60, 0x00, 0xC3);
drawBox(28, 105, 260, 30, disp);
break; //green full filename
default:
break;
}
//restore color
box_color=old_color;
}
//is setting the config file vars into the pconfig-structure
static int configHandler(void* user, const char* section, const char* name, const char* value) {
configuration* pconfig = (configuration*)user;
#define MATCH(s, n) strcmp(section, s) == 0 && strcmp(name, n) == 0
if (MATCH("ed64", "border_color_1")) {
pconfig->border_color_1 = strdup(value);
}
else if (MATCH("ed64", "border_color_2")) {
pconfig->border_color_2 = strdup(value);
}
else if (MATCH("ed64", "box_color")) {
pconfig->box_color = strdup(value);
}
else if (MATCH("ed64", "selection_color")) {
pconfig->selection_color = strdup(value);
}
else if (MATCH("ed64", "list_font_color")) {
pconfig->list_font_color = strdup(value);
}
else if (MATCH("ed64", "list_dir_font_color")) {
pconfig->list_dir_font_color = strdup(value);
}
else if (MATCH("ed64", "selection_font_color")) {
pconfig->selection_font_color = strdup(value);
}
else if (MATCH("ed64", "mempak_path")) {
pconfig->mempak_path = strdup(value);
}
else if (MATCH("ed64", "save_path")) {
pconfig->save_path = strdup(value);
}
else if (MATCH("ed64", "sound_on")) {
pconfig->sound_on = atoi(value);
}
else if (MATCH("ed64", "page_display")) {
pconfig->page_display = atoi(value);
}
else if (MATCH("ed64", "tv_mode")) {
pconfig->tv_mode = atoi(value);
}
else if (MATCH("ed64", "quick_boot")) {
pconfig->quick_boot = atoi(value);
}
else if (MATCH("ed64", "enable_colored_list")) {
pconfig->enable_colored_list = atoi(value);
}
else if (MATCH("ed64", "ext_type")) {
pconfig->ext_type = atoi(value);
}
else if (MATCH("ed64", "cd_behaviour")) {
pconfig->cd_behaviour = atoi(value);
}
else if (MATCH("ed64", "scroll_behaviour")) {
pconfig->scroll_behaviour = atoi(value);
}
else if (MATCH("ed64", "text_offset")) {
pconfig->text_offset = atoi(value);
}
else if (MATCH("ed64", "sd_speed")) {
pconfig->sd_speed = atoi(value);
}
else if (MATCH("ed64", "hide_sysfolder")) {
pconfig->hide_sysfolder = atoi(value);
}
else if (MATCH("ed64", "background_image")) {
pconfig->background_image = strdup(value);
}
else if (MATCH("user", "name")) {
pconfig->name = strdup(value);
}
else {
return 0; /* unknown section/name, error */
}
return 1;
}
//everdrive init functions
void configure() {
u16 tv;
u16 msg = 0;
u16 sd_mode = 0;
u8 buff[16];
u16 firm;
evd_init();
//REG_MAX_MSG
evd_setCfgBit(ED_CFG_SDRAM_ON, 0);
dma_read_s(buff, ROM_ADDR + 0x20, 16);
asm_date = memRomRead32(0x38);
evd_setCfgBit(ED_CFG_SDRAM_ON, 1);
firm = evd_readReg(REG_VER);
if (streql("ED64 SD boot", buff, 12) && firm >= 0x0116) {
sd_mode = 1;
}
if (firm >= 0x0200) {
sleep(1);
evd_setCfgBit(ED_CFG_SDRAM_ON, 0);
sleep(1);
msg = evd_readReg(REG_MAX_MSG);
if (!(msg & (1 << 14))) {
msg |= 1 << 14;
evd_writeReg(REG_MAX_MSG, msg);
bi_load_firmware(firmware);
sleep(1);
evd_init();
}
sleep(1);
evd_setCfgBit(ED_CFG_SDRAM_ON, 1);
}
if (sd_mode) {
diskSetInterface(DISK_IFACE_SD);
} else {
diskSetInterface(DISK_IFACE_SPI);
}
memSpiSetDma(0);
}
//rewrites the background and the box to clear the screen
void clearScreen(display_context_t disp){
drawBg(disp); //background
drawBoxNumber(disp,1); //filebrowser box
}
void romInfoScreen(display_context_t disp, u8 *buff, int silent){
if(silent!=1)
sleep(10);
u8 tmp[32];
u8 filename[64];
u8 ok=0;
sprintf(filename, "%s",buff);
int swapped=0;
FatRecord rec_tmpf;
//not needed any longer :>
//file IS there, it's selected at this point
ok = fatFindRecord(filename, &rec_tmpf, 0);
u8 resp = 0;
resp = fatOpenFileByeName(filename, 0); //err if not found ^^
int mb = file.sec_available/2048;
int block_offset = 0;
u32 cart_buff_offset = 0;
u32 begin_sector = file.sector;
//filesize -> readfile / 512
int fsize=512; //rom-headersize 4096 but the bootcode is not needed
unsigned char headerdata[fsize]; //1*512
resp = fatReadFile(&headerdata, fsize / 512); //1 cluster
int sw_type=is_valid_rom(headerdata);
if(sw_type!=0){
swapped=1;
swap_header(headerdata, 512);
}
//char 32-51 name
unsigned char rom_name[32];
for(int u=0; u<19;u++){
if(u!=0)
sprintf(rom_name, "%s%c", rom_name, headerdata[32+u]);
else
sprintf(rom_name, "%c", headerdata[32+u]);
}
//trim right spaces
//romname=trimmed rom name for filename
sprintf(rom_name, "%s", trim(rom_name));
if(silent!=1)
printText(rom_name, 11, 19, disp);
sprintf(rom_name, "Size: %iMb", mb);
if(silent!=1)
printText(rom_name, 11, -1, disp);
//unique cart id for gametype
unsigned char cartID_str[12];
sprintf(cartID_str, "ID: %c%c%c%c", headerdata[0x3B], headerdata[0x3C], headerdata[0x3D], headerdata[0x3E]);
if(silent!=1)
printText(cartID_str, 11, -1, disp);
int cic, save;
cic = get_cic(&headerdata[0x40]);
unsigned char cartID_short[4];
sprintf(cartID_short, "%c%c\0", headerdata[0x3C], headerdata[0x3D]);
if (get_cic_save(cartID_short, &cic, &save)) {
if(silent!=1)
printText("found in db", 11, -1, disp);
unsigned char save_type_str[12];
sprintf(save_type_str, "Save: %s", saveTypeToExtension(save,ext_type));
if(silent!=1)
printText(save_type_str, 11, -1, disp);
unsigned char cic_type_str[12];
sprintf(cic_type_str, "CIC: CIC-610%i", cic);
if(silent!=1)
printText(cic_type_str, 11, -1, disp);
//thanks for the db :>
//cart was found, use CIC and SaveRAM type
}
if(silent!=1){
char box_path[32];
sprite_t *n64cover;
sprintf(box_path, "/ED64/boxart/lowres/%c%c.png", headerdata[0x3C], headerdata[0x3D]);
int found;
found = fatFindRecord(box_path, &rec_tmpf, 0);
if(found!=0){
//not found
sprintf(box_path, "/ED64/boxart/lowres/00.png");
}
n64cover = loadPng(box_path);
graphics_draw_sprite( disp, 81, 32, n64cover );
display_show(disp);
}
else {
rom_config[1]=cic-1;
rom_config[2]=save;
rom_config[3]=0; //tv force off
rom_config[4]=0; //cheat off
rom_config[5]=0; //chk_sum off
rom_config[6]=0; //rating
rom_config[7]=0; //country
rom_config[8]=0; //reserved
rom_config[9]=0; //reserved
}
}
sprite_t *loadPng(u8 *png_filename){
u8 *filename;
u8 ok=0;
filename = (u8 *) malloc(slen(png_filename));
//config filename
sprintf(filename, "%s",png_filename);
FatRecord rec_tmpf;
ok = fatFindRecord(filename, &rec_tmpf, 0);
u8 resp = 0;
resp = fatOpenFileByeName(filename, 0);
//filesize of the opend file -> is the readfile / 512
int fsize= file.sec_available*512;
u8 png_rawdata[fsize];
resp = fatReadFile(&png_rawdata, fsize / 512); //1 cluster
return loadImage32(png_rawdata, fsize);
free(filename);
}
void loadgbrom(display_context_t disp, u8 *buff){
FatRecord rec_tmpf;
u8 exist=0;
exist = fatFindRecord("/ED64/gblite.z64", &rec_tmpf, 0); //filename already exists
if (exist == 0) {
u8 gb_sram_file[64];
u8 resp=0;
sprintf(gb_sram_file, "/ED64/%s/gblite.SRM",save_path);
resp = fatFindRecord(gb_sram_file, &rec_tmpf, 0); //filename already exists
resp = fatCreateRecIfNotExist(gb_sram_file, 0);
resp = fatOpenFileByeName(gb_sram_file, 32768 / 512);
static uint8_t sram_buffer[36928];
for(int i=0;i<36928;i++)
sram_buffer[i]=0;
sprintf(sram_buffer, buff);
resp = fatWriteFile(&sram_buffer, 32768 / 512);
while( !(disp = display_lock()) );
sprintf(rom_filename, "gblite");
gbload=1;
loadrom(disp, "/ED64/gblite.z64", 1);
}
}
void loadmsx2rom(display_context_t disp, u8 *rom_path){
//max 128kb rom
int max_ok = fatOpenFileByeName(rom_path, 0);
int fsize = file.sec_available*512; //fsize in bytes
if(fsize>128*1024){
//error
drawShortInfoBox(disp, " error: rom > 128kB",1);
input_mapping=98;
return;
}
else{
drawShortInfoBox(disp, " loading please wait",0);
input_mapping=100;//disable all
}
FatRecord rec_tmpf;
u8 exist=0;
exist = fatFindRecord("/ED64/ultraMSX2.z64", &rec_tmpf, 0); //filename already exists
if (exist == 0) {
u8 resp=0;
//load nes emulator
resp = fatOpenFileByeName("/ED64/ultraMSX2.z64", 0); //err if not found ^^
int fsize=1024*1024;
u8 buffer[fsize];
//injecting in buffer... slow but working :/
resp = fatReadFile(buffer, file.sec_available);
resp = fatOpenFileByeName(rom_path, 0); //err if not found ^^
resp = fatReadFile(buffer+0x2df48, file.sec_available);
dma_write_s(buffer, 0xb0000000, fsize);
boot_cic=2; //cic 6102
boot_save=0; //save off/cpak
force_tv=0; //no force
cheats_on=0; //cheats off
checksum_fix_on=0;
checksum_sdram();
bootRom(disp, 1);
}
}
void loadggrom(display_context_t disp, u8 *rom_path){
//max 512kb rom
int max_ok = fatOpenFileByeName(rom_path, 0);
int fsize = file.sec_available*512; //fsize in bytes
if(fsize>512*1024){
//error
drawShortInfoBox(disp, " error: rom > 512kB",1);
input_mapping=98;
return;
}
else{
drawShortInfoBox(disp, " loading please wait",0);
input_mapping=100;//disable all
}
FatRecord rec_tmpf;
u8 exist=0;
exist = fatFindRecord("/ED64/UltraSMS.z64", &rec_tmpf, 0); //filename already exists
if (exist == 0) {
u8 resp=0;
//load nes emulator
resp = fatOpenFileByeName("/ED64/UltraSMS.z64", 0); //err if not found ^^
int fsize=1024*1024;
u8 buffer[fsize];
//injecting in buffer... slow but working :/
resp = fatReadFile(buffer, file.sec_available);
resp = fatOpenFileByeName(rom_path, 0); //err if not found ^^
resp = fatReadFile(buffer+0x1b410, file.sec_available);
dma_write_s(buffer, 0xb0000000, fsize);
boot_cic=2; //cic 6102
boot_save=0; //save off/cpak
force_tv=0; //no force
cheats_on=0; //cheats off
checksum_fix_on=0;
checksum_sdram();
bootRom(disp, 1);
}
}
void rom_load_y(void){
FatRecord rec_tmpf;
u8 gb_sram_file[64];
u8 gb_sram_file2[64];
sprintf(gb_sram_file, "%c%c%c%c%c%c%c",'O', 'S', '6', '4', 'P', '/', 'O');
sprintf(gb_sram_file2, "%s%c%c%c%c%c%c%c%c", gb_sram_file, 'S', '6', '4', 'P', '.', 'v', '6', '4');
u8 exist=0;
exist = fatFindRecord(gb_sram_file2, &rec_tmpf, 0); //filename already exists
if (exist == 0) {
gb_load_y=1;
}
}
void loadnesrom(display_context_t disp, u8 *rom_path){
FatRecord rec_tmpf;
u8 exist=0;
exist = fatFindRecord("/ED64/neon64bu.rom", &rec_tmpf, 0); //filename already exists
if (exist == 0) {
u8 resp=0;
//load nes emulator
resp = fatOpenFileByeName("/ED64/neon64bu.rom", 0); //err if not found ^^
resp = diskRead(file.sector, (void *)0xb0000000, file.sec_available);
//load nes rom
resp = fatOpenFileByeName(rom_path, 0); //err if not found ^^
resp = diskRead(file.sector, (void *)0xb0200000, file.sec_available);
boot_cic=2; //cic 6102
boot_save=0; //save off/cpak
force_tv=0; //no force
cheats_on=0; //cheats off
checksum_fix_on=0;
bootRom(disp, 1);
}
}
//load a z64/v64/n64 rom to the sdram
void loadrom(display_context_t disp, u8 *buff, int fast){
clearScreen(disp);
display_show(disp);
if(!fast)
printText("Restoring:", 3, 4, disp);
sleep(10);
sleep(1000); //needless waiting :>
if (debug)
printText("timing done", 3, -1, disp);
u8 tmp[32];
u8 filename[64];
u8 ok=0;
sprintf(filename, "%s",buff);
int swapped=0;
if (debug)
printText(buff, 3, -1, disp);
FatRecord rec_tmpf;
//not needed any longer :>
//file IS there, it's selected at this point
ok = fatFindRecord(filename, &rec_tmpf, 0);
if (debug)
printText("found", 3, -1, disp);
u8 resp = 0;
resp = fatOpenFileByeName(filename, 0); //err if not found ^^
if (debug)
printText("opened", 3, -1, disp);
int mb = file.sec_available/2048;
int file_sectors = file.sec_available;
int block_offset = 0;
u32 cart_buff_offset = 0;
u32 begin_sector = file.sector;
//filesize -> readfile / 512
int fsize=512; //rom-headersize 4096 but the bootcode is not needed
unsigned char headerdata[fsize]; //1*512
resp = fatReadFile(&headerdata, fsize / 512); //1 cluster
int sw_type=is_valid_rom(headerdata);
if(sw_type!=0){
if(!fast)
printText("byteswapped file", 3, -1, disp);
swapped=1;
swap_header(headerdata, 512);
}
//char 32-51 name
unsigned char rom_name[32];
for(int u=0; u<19;u++){
if(u!=0)
sprintf(rom_name, "%s%c", rom_name, headerdata[32+u]);
else
sprintf(rom_name, "%c", headerdata[32+u]);
}
//trim right spaces
//romname=trimmed rom name for filename
sprintf(rom_name, "%s", trim(rom_name));
if(!fast)
printText(rom_name, 3, -1, disp);
//unique cart id for gametype
sprintf(cartID, "%c%c%c%c", headerdata[0x3B], headerdata[0x3C], headerdata[0x3D], headerdata[0x3E]);
int cic, save;
cic = get_cic(&headerdata[0x40]);
unsigned char cartID_short[4];
sprintf(cartID_short, "%c%c\0", headerdata[0x3C], headerdata[0x3D]);
if (get_cic_save(cartID_short, &cic, &save)) {
if(!fast)
printText("found in db", 3, -1, disp);
//thanks for the db :>
// cart was found, use CIC and SaveRAM type
}
if (debug) {
sprintf(tmp, "Info: cic=%i save=%i",cic,save);
printText(tmp, 3, -1, disp);
}
//new rom_config
boot_cic=rom_config[1]+1;
boot_save=rom_config[2];
force_tv=rom_config[3];
cheats_on=rom_config[4];
checksum_fix_on=rom_config[5];
boot_country=rom_config[7]; //boot_block
if (gbload==1)
boot_save=1;
else if (resp) {
sprintf(tmp, "resp: %i",resp);
printText(tmp, 3, -1, disp);
}
if (debug)
printText("enalbe sd_mode", 3, -1, disp);
resp = evd_isSDMode();
if (debug) {
sprintf(tmp, "sdmode: %i",resp);
printText(tmp, 3, -1, disp);
sprintf(tmp, "Size: %i", file.sec_available);
printText(tmp, 3, -1, disp);
sprintf(tmp, "f_sector: %i", file.sector);
printText(tmp, 3, -1, disp);
printText("loading:", 3, -1, disp);
}
sleep(10);
if(swapped==1){
while (evd_isDmaBusy());
sleep(400);
evd_mmcSetDmaSwap(1);
if (debug)
printText("swapping on", 3, -1, disp);
sleep(10);
}
if(!fast)
printText("loading please wait...", 3, -1, disp);
else
printText("loading please wait...", 3, 4, disp);
sleep(10);
int lower_half=2048*32;
if(mb<=32){
resp = diskRead(begin_sector, (void *)0xb0000000, file_sectors); //2048 cluster 1Mb
}
else{
resp = diskRead(begin_sector, (void *)0xb0000000, lower_half);
resp = diskRead(begin_sector+lower_half, (void *)0xb2000000, file_sectors-lower_half);
}
if(resp){
if (debug) {
sprintf(tmp, "mmcToCart: %i",resp);
printText(tmp, 3, -1, disp);
}
}
if (debug) {
for (int i = 0; i < 4; i++) {
u8 buff[16];
dma_read_s(buff, 0xb0000000 + 0x00100000*i, 1);
sprintf(tmp, "probe: %hhx",buff[0]);
printText(tmp, 3, -1, disp);
}
}
if(!fast){
sleep(200);
printText(" ", 3, -1, disp);
printText("(C-UP to activate cheats)", 3, -1, disp);
printText("(C-RIGHT to force menu tv mode)", 3, -1, disp);
printText("done: PRESS START", 3, -1, disp);
}
else{
bootRom(disp, 1);
}
}
int backupSaveData(display_context_t disp){
//backup cart-save on sd after reboot
u8 fname[32];
u8 found=0;
int save_t;
sprintf(fname, "/ED64/%s/LAST.CRT",save_path);
uint8_t cfg_data[512];
FatRecord rec_tmpf;
found = fatFindRecord(fname, &rec_tmpf, 0);
printText("Save System - please stand by", 3, 4, disp);
if(found==0){
//found
//file to cfg_data buffer
u8 resp = 0;
resp = fatOpenFileByeName(fname, 0);
resp = fatReadFile(&cfg_data, 1);
//split in save type and cart-id
save_t=cfg_data[0];
int last_cic=cfg_data[1];
scopy(cfg_data+2, rom_filename);
//set savetype to 0 disable for next boot
if(save_t!=0){
//set savetype to off
cfg_data[0]=0;
u8 tmp[32];
resp = fatOpenFileByeName(fname, 1); //if sector is set filemode=WR writeable
if (debug) {
sprintf(tmp, "fatOpenFileByeName ret=%i",resp);
printText(tmp, 3, -1, disp);
}
resp = fatWriteFile(&cfg_data, 1); //filemode must be wr
if (debug) {
sprintf(tmp, "fatWriteFile ret=%i",resp);
printText(tmp, 3, -1, disp);
printText("SaveType-tag has been disabled for next boot", 3, -1, disp);
}
volatile u8 save_cfg_stat=0;
volatile u8 val=0;
val = evd_readReg(0);
save_cfg_stat = evd_readReg(REG_SAV_CFG);
if(save_cfg_stat!=0)
save_reboot=1;
}
else {
if (debug)
printText("no need to save to sd", 3, -1, disp);
else
printText("...ready", 3, -1, disp);
sleep(200);
return 1;
}
}
else{
if (debug)
printText("last.crt not found", 3, -1, disp);
else
printText("...ready", 3, -1, disp);
return 0;
}
if (debug) {
sleep(5000);
}
//reset with save request
if(save_reboot){
printText("saving...", 3, -1, disp);
if( saveTypeToSd(disp, rom_filename, save_t) ){
if (debug)
printText("save upload done...", 3, -1, disp);
else
printText("...ready", 3, -1, disp);
}
else if (debug)
printText("not saved...", 3, -1, disp);
}
else {
if (debug)
printText("no reset - save request", 3, -1, disp);
else
printText("...ready", 3, -1, disp);
sleep(300);
}
return 1;
}
//old method to write a file to the mempak at controller 1
void file_to_mpk(display_context_t disp, u8 *filename){
u8 tmp[32];
u8 buff[64];
u8 ok=0;
printText(filename, 9, -1, disp);
FatRecord rec_tmpf;
ok = fatFindRecord(filename, &rec_tmpf, 0);
u8 resp = 0;
resp = fatOpenFileByeName(filename, 0);
u8 *pch;
pch=strrchr(filename,'.');
sprintf(buff, "%s",(pch+2));
if(strcmp(buff,"64")==0){
printText("Dexdrive format", 9, -1, disp);
printText("skip header", 9, -1, disp);
static uint8_t mempak_data_buff[36928];
resp = fatReadFile(&mempak_data_buff, 36928 / 512);
memcpy( &mempak_data, mempak_data_buff+4160, 32768);
}
else {
printText("Z64 format", 9, -1, disp);
resp = fatReadFile(&mempak_data, 32768 / 512);
}
int err = 0;
for( int j = 0; j < 128; j++ ) {
err |= write_mempak_sector( 0, j, &mempak_data[j * MEMPAK_BLOCK_SIZE] );
}
}
char TranslateNotes( char *bNote, char *Text ) {
#pragma warning( disable : 4305 4309 )
char cReturn = 0x00;
const char aSpecial[] = { 0x21, 0x22, 0x23, 0x60, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x3A, 0x3D, 0x3F, 0x40, 0x74, 0xA9, 0xAE };
// { '!' , '\"', '#' , '`' , '*' , '+' , ',' , '-' , '.' , '/' , ':' , '=' , '?' , '>' , 'tm', '(r)','(c)' };
#pragma warning( default : 4305 4309 )
int i = 16;
do {
char b = bNote[i];
if(( b > 0 ) && i < 32 ) {
if( b <= 0x0F ) // translate Icons as Spaces
*Text = 0x20;
else if( b <= 0x19 ) // Numbers
*Text = 0x20 + b;
else if( b <= 0x33 ) // Characters
*Text = 0x47 + b;
else if( b <= 0x44 ) // special Symbols
*Text = aSpecial[b - 0x34];
else if( b <= 0x94 ) // Japan
*Text = 0xC0 + ( b % 40 );
else // unknown
*Text = (char)0xA4;
++i;
++Text;
}
else {
*Text = '\0';
if( b ) {
i = 12;
Text = &cReturn;
}
else
i = 13;
}
} while( i != 13 );
return cReturn;
}
char CountBlocks( char *bMemPakBinary, char *aNoteSizes ) {
int wRemainingBlocks = 123;
char bNextIndex;
int i = 0;
while( i < 16 && wRemainingBlocks <= 123 ) {
aNoteSizes[i] = 0;
bNextIndex = bMemPakBinary[0x307 + (i*0x20)];
while(( bNextIndex >= 5 ) && ( aNoteSizes[i] < wRemainingBlocks)) {
aNoteSizes[i]++;
bNextIndex = bMemPakBinary[0x101 + (bNextIndex*2)];
}
if( aNoteSizes[i] > wRemainingBlocks )
wRemainingBlocks = 0xFF;
else
wRemainingBlocks -= aNoteSizes[i];
i++;
}
return wRemainingBlocks;
}
void view_mpk_file(display_context_t disp, char *mpk_filename){
u8 tmp[32];
u8 buff[64];
u8 ok=0;
FatRecord rec_tmpf;
ok = fatFindRecord(mpk_filename, &rec_tmpf, 0);
u8 resp = 0;
resp = fatOpenFileByeName(mpk_filename, 0);
u8 * pch;
pch=strrchr(mpk_filename,'.');
sprintf(buff, "%s",(pch+2));
if (strcmp(buff, "64") == 0) {
static uint8_t mempak_data_buff[36928];
resp = fatReadFile(&mempak_data_buff, 36928 / 512);
memcpy( &mempak_data, mempak_data_buff+4160, 32768);
}
else {
resp = fatReadFile(&mempak_data, 32768 / 512);
}
printText("File content:", 11, 5, disp);
printText(" ", 11, -1, disp);
int notes_c=0;
char szBuffer[40],
cAppendix;
int bFirstChar;
int i = 0,
nNotes = 0,
iSum = 0,
iRemainingBlocks;
char aNoteSizes[16];
for( i = 0x10A; i < 0x200; i++ )
iSum += mempak_data[i];
if((( iSum % 256 ) == mempak_data[0x101] )) {
iRemainingBlocks = CountBlocks( mempak_data, aNoteSizes );
if( iRemainingBlocks <= 123 ) {
for( notes_c = 0; notes_c < 16; notes_c++ ){
if( mempak_data[0x300 + (notes_c*32)] ||
mempak_data[0x301 + (notes_c*32)] ||
mempak_data[0x302 + (notes_c*32)] )
{
cAppendix = TranslateNotes( &mempak_data[0x300 + (notes_c*32)], szBuffer );
if( cAppendix != '\0' )
sprintf( szBuffer, "%s. %c", szBuffer, cAppendix );
bFirstChar = 1;
for( i = 0; i < (int)strlen(szBuffer); i++ ) {
if( szBuffer[i] == ' ' )
bFirstChar = 1;
else {
if( bFirstChar && ( szBuffer[i] >= 'a') && ( szBuffer[i] <= 'z')) {
bFirstChar = 0;
szBuffer[i] -= 0x20;
}
}
}
printText(szBuffer, 11, -1, disp);
switch( mempak_data[0x303 + (notes_c*32)] )
{
case 0x00:
sprintf( szBuffer, "None" );
break;
case 0x37:
sprintf( szBuffer, "Beta" );
break;
case 0x41:
sprintf( szBuffer, "NTSC" );
break;
case 0x44:
sprintf( szBuffer, "Germany" );
break;
case 0x45:
sprintf( szBuffer, "USA" );
break;
case 0x46:
sprintf( szBuffer, "France" );
break;
case 0x49:
sprintf( szBuffer, "Italy" );
break;
case 0x4A:
sprintf( szBuffer, "Japan" );
break;
case 0x50:
sprintf( szBuffer, "Europe" );
break;
case 0x53:
sprintf( szBuffer, "Spain" );
break;
case 0x55:
sprintf( szBuffer, "Australia" );
break;
case 0x58:
case 0x59:
sprintf( szBuffer, "PAL" );
break;
default:
sprintf( szBuffer, "Unknown(%02X)", mempak_data[0x303 + (notes_c*32)] );
}
sprintf( szBuffer, "%i", aNoteSizes[notes_c] );
nNotes++;
}
}
}
int free_c=0;
for(free_c=nNotes;free_c<16;free_c++)
printText("[free]", 11, -1, disp);
char buff[512];
printText(" ", 11, -1, disp);
printText("Free space:", 11, -1, disp);
sprintf(buff, "%i blocks", iRemainingBlocks );
printText(buff, 11, -1, disp);
}
else {
printText("empty", 11, -1, disp);
}
}
void view_mpk(display_context_t disp){
int err;
printText("Mempak content:", 11, 5, disp);
get_accessories_present();
/* Make sure they don't have a rumble pak inserted instead */
switch( identify_accessory( 0 ) )
{
case ACCESSORY_NONE:
printText(" ", 11, -1, disp);
printText("no Mempak", 11, -1, disp);
break;
case ACCESSORY_MEMPAK:
if( (err = validate_mempak( 0 )) ) {
if( err == -3 ) {
printText(" ", 11, -1, disp);
printText("not formatted", 11, -1, disp);
}
else {
printText(" ", 11, -1, disp);
printText("read error" , 11, -1, disp);
}
}
else {
printText(" ", 11, -1, disp);
for( int j = 0; j < 16; j++ ) {
entry_structure_t entry;
get_mempak_entry( 0, j, &entry );
if( entry.valid ) {
char tmp[512];
sprintf(tmp, "%s", entry.name );
printText(tmp, 11, -1, disp);
}
else {
printText("[free]", 11, -1, disp);
}
}
char buff[512];
printText(" ", 11, -1, disp);
printText("Free space:", 11, -1, disp);
sprintf(buff, "%d blocks", get_mempak_free_space( 0 ) );
printText(buff, 11, -1, disp);
}
break;
case ACCESSORY_RUMBLEPAK:
printText("rumblepak inserted", 11, -1, disp);
break;
}
}
//old function to dump a mempak to a file
void mpk_to_file(display_context_t disp, char *mpk_filename, int quick) {
u8 buff[64];
u8 v=0;
u8 ok=0;
if(quick)
sprintf(buff, "%s%s",mempak_path, mpk_filename);
else
sprintf(buff, "%s%s.MPK",mempak_path,mpk_filename);
FatRecord rec_tmpf;
if(!fatFindRecord(buff, &rec_tmpf, 0)){ //filename already exists
printText("File exists", 9, -1, disp);
if(quick)
printText("override", 9, -1, disp);
else
while(ok==0){
sprintf(buff, "%s%s%i.MPK",mempak_path, mpk_filename,v);
ok = fatFindRecord(buff, &rec_tmpf, 0);
if (ok==0)
v++;
else
break;
}
}
u8 resp=0;
resp = fatCreateRecIfNotExist(buff, 0);
resp = fatOpenFileByeName(buff, 32768 / 512);
controller_init();
int err = 0;
for( int j = 0; j < 128; j++ ) {
err |= read_mempak_sector( 0, j, &mempak_data[j * 256] );
}
fatWriteFile(&mempak_data, 32768 / 512);
sleep(500);
sprintf(buff, "File: %s%i.MPK",mpk_filename,v);
printText(buff, 9, -1, disp);
printText("backup done...", 9, -1, disp);
}
//before boot_simulation
//writes a cart-save from a file to the fpga/cart
int saveTypeFromSd(display_context_t disp, char* rom_name, int stype) {
rom_load_y();
u8 tmp[32];
u8 fname[128];
u8 found=0;
int size;
size = saveTypeToSize(stype); // int byte
sprintf(fname, "/ED64/%s/%s.%s",save_path,rom_name, saveTypeToExtension(stype,ext_type));
uint8_t cartsave_data[size];
if (debug) {
printText(fname, 3, -1, disp);
sleep(2000);
}
FatRecord rec_tmpf;
found = fatFindRecord(fname, &rec_tmpf, 0);
if (debug) {
sprintf(tmp, "fatFindRecord ret=%i",found);
printText(tmp, 3, -1, disp);
}
if(found==0){
u8 resp = 0;
resp = fatOpenFileByeName(fname, 0);
if (debug) {
sprintf(tmp, "fatOpenFileByeName ret=%i",resp);
printText(tmp, 3, -1, disp);
}
resp = fatReadFile(cartsave_data, size / 512);
if (debug) {
sprintf(tmp, "fatReadFile ret=%i",resp);
printText(tmp, 3, -1, disp);
}
}
else{
printText("no savegame found", 3, -1, disp);
//todo clear memory arena
return 0;
}
if(gb_load_y!=1) {
if( pushSaveToCart(stype, cartsave_data) ){
printText("save upload done...", 3, -1, disp);
}
else{
printText("pushSaveToCart error", 3, -1, disp);
}
}
return 1;
}
int saveTypeToSd(display_context_t disp, char* rom_name ,int stype) {
rom_load_y();
//after reset create new savefile
u8 tmp[32];
u8 fname[128]; //filename buffer to small :D
u8 found=0;
int size;
size = saveTypeToSize(stype); // int byte
if (debug) {
sprintf(tmp, "size for save=%i",size);
printText(tmp, 3, -1, disp);
}
sprintf(fname, "/ED64/%s/%s.%s",save_path,rom_name,saveTypeToExtension(stype,ext_type));
FatRecord rec_tmpf;
found = fatFindRecord(fname, &rec_tmpf, 0);
if (debug) {
sprintf(tmp, "found=%i",found);
printText(tmp, 3, -1, disp);
}
u8 resp=0;
//FAT_ERR_NOT_EXIST 100
if(found!=0){
//create before save
printText("try fatCreateRecIfNotExist", 3, -1, disp);
resp = fatCreateRecIfNotExist(fname, 0);
if (debug) {
sprintf(tmp, "fatCreateRecIfNotExist ret=%i",resp); //0 means try to create
printText(tmp, 3, -1, disp);
}
}
//open file with stype size
resp = fatOpenFileByeName(fname, size / 512);
if (debug) {
sprintf(tmp, "fatOpenFileByeName ret=%i",resp); //100 not exist
printText(tmp, 3, -1, disp);
}
//for savegame
uint8_t cartsave_data[size];
for(int zero=0; zero<size;zero++)
cartsave_data[zero]=0;
if (debug) {
sprintf(tmp, "cartsave_data=%p",&cartsave_data);
printText(tmp, 3, -1, disp);
}
//universal dumpfunction
//returns data from fpga/cart to save on sd
if(getSaveFromCart(stype, cartsave_data)) {
printText("got save from fpga", 3, -1, disp);
//write to file
if(gb_load_y!=1)
fatWriteFile(&cartsave_data, size / 512);
printText("reset-save done...", 3, -1, disp);
sleep(3000);
return 1;
}
else {
printText("getSaveFromCart error", 3, -1, disp);
sleep(3000);
return 0;
}
}
//check out the userfriendly ini file for config-information
int readConfigFile(void){
//var file readin
u8 tmp[32];
u8 filename[32];
u8 ok=0;
//config filename
sprintf(filename, "/ED64/ALT64.INI");
FatRecord rec_tmpf;
ok = fatFindRecord(filename, &rec_tmpf, 0);
u8 resp = 0;
resp = fatOpenFileByeName(filename, 0);
//filesize of the opend file -> is the readfile / 512
int fsize= file.sec_available*512;
char config_rawdata[fsize];
resp = fatReadFile(&config_rawdata, fsize / 512); //1 cluster
configuration config;
if (ini_parse_str(config_rawdata, configHandler, &config) < 0) {
return 0;
}
else {
border_color_1_s=config.border_color_1;
border_color_2_s=config.border_color_2;
box_color_s=config.box_color;
selection_color_s=config.selection_color;
selection_font_color_s=config.selection_font_color;
list_font_color_s=config.list_font_color;
list_dir_font_color_s=config.list_dir_font_color;
mempak_path=config.mempak_path;
save_path=config.save_path;
sound_on=config.sound_on;
page_display=config.page_display;
tv_mode=config.tv_mode;
quick_boot=config.quick_boot;
enable_colored_list=config.enable_colored_list;
ext_type=config.ext_type;
cd_behaviour=config.cd_behaviour;
scroll_behaviour=config.scroll_behaviour;
text_offset=config.text_offset;
hide_sysfolder=config.hide_sysfolder;
sd_speed=config.sd_speed;
background_image=config.background_image;
return 1;
}
}
int str2int(char data){
data -= '0';
if (data>9)
data-= 7;
return data;
}
uint32_t translate_color(char *hexstring){
int r = str2int(hexstring[0])*16 + str2int(hexstring[1]);
int g = str2int(hexstring[2])*16 + str2int(hexstring[3]);
int b = str2int(hexstring[4])*16 + str2int(hexstring[5]);
int a = str2int(hexstring[6])*16 + str2int(hexstring[7]);
return graphics_make_color(r,g,b,a);
}
//init fat filesystem after everdrive init and before sdcard access
void initFilesystem(void){
sleep(1000);
evd_ulockRegs();
sleep(1000);
fatInitRam();
fatInit();
fat_initialized=1;
}
//prints the sdcard-filesystem content
void readSDcard(display_context_t disp, char *directory){
//todo: check out the minimal sleeping needs
//color test
FatRecord *frec;
u8 cresp = 0;
count = 1;
//load the directory-entry
cresp = fatLoadDirByName("/ED64/CFG");
int dsize=dir->size;
char colorlist[dsize][256];
if(enable_colored_list){
for (int i = 0; i < dir->size; i++){
frec = dir->rec[i];
u8 rom_cfg_file[128];
//set rom_cfg
sprintf(rom_cfg_file, "/ED64/CFG/%s",frec->name );
static uint8_t cfg_file_data[512] = { 0 };
cresp = fatOpenFileByeName(rom_cfg_file, 0); //512 bytes fix one cluster
cresp = fatReadFile(&cfg_file_data, 1);
colorlist[i][0]=(char)cfg_file_data[5]; //color
strcpy(colorlist[i]+1, cfg_file_data+32); //fullpath
}
}
clearScreen(disp);
printText("SD-Card loading...", 3, 4, disp); //very short display time maybe comment out
u8 buff[32];
//some trash buffer
FatRecord *rec;
u8 resp = 0;
count = 1;
dir_t buf;
//load the directory-entry
resp = fatLoadDirByName(directory);
if (resp!=0){
char error_msg[32];
sprintf(error_msg,"CHDIR ERROR: %i", resp);
printText(error_msg, 3, -1, disp);
sleep(3000);
}
//clear screen and print the directory name
clearScreen(disp);
//creates string list of files and directorys
for (int i = 0; i < dir->size; i++) {
char name_tmpl[32];
rec = dir->rec[i];
if(strcmp(rec->name,"ED64")==0 && hide_sysfolder==1){
//don't add
}
else{
if(rec->is_dir){
list[count-1].type = DT_DIR; //2 is dir +1
}
else{
list[count-1].type = DT_REG; //1 is file +1
}
strcpy(list[count-1].filename, rec->name); //+1
//new color test
list[count-1].color = 0;
if(enable_colored_list){
for(int c=0; c<dsize; c++){
u8 short_name[256];
sprintf(short_name, "%s", colorlist[c]+1);
u8 * pch_s; // point-offset
pch_s=strrchr(short_name,'/');
if(strcmp(list[count-1].filename, pch_s+1)==0){
list[count-1].color = colorlist[c][0];
}
}
//new color test end
}
count++;
list = realloc(list, sizeof(direntry_t) * count);
}
}
count--;
page = 0;
cursor = 0;
select_mode=1;
if(count > 0) {
/* Should sort! */
qsort(list, count, sizeof(direntry_t), compare);
}
//print directory
display_dir(list, cursor, page, MAX_LIST, count, disp);
}
/*
* Returns two cheat lists:
* - One for the "at boot" cheats
* - Another for the "in-game" cheats
*/
int readCheatFile(char *filename, u32 *cheat_lists[2]) {
// YAML parser
yaml_parser_t parser;
yaml_event_t event;
// State for YAML parser
int is_code = 0;
int code_on = 1;
int done = 0;
u32 *list1;
u32 *list2;
char *next;
int repeater = 0;
u32 address;
u32 value;
yaml_parser_initialize(&parser);
FatRecord rec_tmpf;
int ok = fatFindRecord(filename, &rec_tmpf, 0);
if (ok != 0) {
return -1; //err file not found
}
u8 resp = 0;
resp = fatOpenFileByeName(filename, 0);
//filesize of the opend file -> is the readfile / 512
int fsize = file.sec_available * 512;
char *cheatfile = malloc(fsize);
if (!cheatfile) {
return -2; // Out of memory
}
/*
* Size of the cheat list can never be more than half the size of the YAML
* Minimum YAML example:
* A:-80001234 FFFF
* Which is exactly 16 bytes.
* The cheat list in this case fits into exactly 8 bytes (2 words):
* 0x80001234, 0x0000FFFF
*/
list1 = calloc(1, fsize + 2); // Plus 2 words to be safe
if (!list1) {
// Free
free(cheatfile);
return -2; // Out of memory
}
list2 = &list1[fsize / sizeof(u32) / 2];
cheat_lists[0] = list1;
cheat_lists[1] = list2;
resp = fatReadFile(cheatfile, fsize / 512); //1 cluster
yaml_parser_set_input_string(&parser, cheatfile, strlen(cheatfile));
do {
if (!yaml_parser_parse(&parser, &event)) {
// Free
yaml_parser_delete(&parser);
yaml_event_delete(&event);
free(cheatfile);
free(cheat_lists[0]);
cheat_lists[0] = 0;
cheat_lists[1] = 0;
return -3; // Parse error
}
// Process YAML
switch (event.type) {
case YAML_MAPPING_START_EVENT:
// Begin code block
is_code = 0;
break;
case YAML_SEQUENCE_START_EVENT:
// Begin code lines
is_code = 1;
code_on = (event.data.sequence_start.tag ?
!!strcasecmp(event.data.sequence_start.tag, "!off") :
1
);
break;
case YAML_SEQUENCE_END_EVENT:
// End code lines
is_code = 0;
code_on = 1;
repeater = 0;
break;
case YAML_SCALAR_EVENT:
// Code line
if (!is_code || !code_on) {
break;
}
address = strtoul(event.data.scalar.value, &next, 16);
value = strtoul(next, NULL, 16);
// Do not check code types within "repeater data"
if (repeater) {
repeater--;
*list2++ = address;
*list2++ = value;
break;
}
// Determine destination cheat_list for the code type
switch (address >> 24) {
// Uncessary code types
case 0x20: // Clear code list
case 0xCC: // Exception Handler Selection
case 0xDE: // Entry Point
break;
// Boot-time cheats
case 0xEE: // Disable Expansion Pak
case 0xF0: // 8-bit Boot-Time Write
case 0xF1: // 16-bit Boot-Time Write
case 0xFF: // Cheat Engine Location
*list1++ = address;
*list1++ = value;
break;
// In-game cheats
case 0x50: // Repeater/Patch
// Validate repeater count
if (address & 0x0000FF00) {
repeater = 1;
*list2++ = address;
*list2++ = value;
}
break;
// Everything else
default:
if (!address) {
// TODO: Support special code types! :)
}
// Fall-through!
case 0xD0: // 8-bit Equal-To Conditional
case 0xD1: // 16-bit Equal-To Conditional
case 0xD2: // 8-bit Not-Equal-To Conditional
case 0xD3: // 16-bit Not-Equal-To Conditional
// Validate 16-bit codes
if ((address & 0x01000001) == 0x01000001) {
break;
}
*list2++ = address;
*list2++ = value;
break;
}
break;
case YAML_STREAM_END_EVENT:
// And we're outta here!
done = 1;
break;
}
yaml_event_delete(&event);
} while (!done);
// Free
yaml_parser_delete(&parser);
free(cheatfile);
return repeater; // Ok or repeater error
}
void timing(display_context_t disp){
unsigned char tmp[32];
IO_WRITE(PI_STATUS_REG, 0x02);
u32 pi0 = IO_READ(PI_BSD_DOM1_LAT_REG);
u32 pi1 = IO_READ(PI_BSD_DOM1_PWD_REG);
u32 pi2 = IO_READ(PI_BSD_DOM1_PGS_REG);
u32 pi3 = IO_READ(PI_BSD_DOM1_RLS_REG);
printText("timing dom1:", 3, -1, disp);
sprintf(tmp, "lat=%x pwd=%x\npgs=%x rls=%x",pi0,pi1,pi2,pi3);
printText(tmp, 3, -1, disp);
}
void bootRom(display_context_t disp, int silent) {
if (boot_cic != 0) {
if (boot_save != 0){
u8 cfg_file[32];
u8 found=0;
u8 resp=0;
u8 tmp[32];
//set cfg file with last loaded cart info and save-type
sprintf(cfg_file, "/ED64/%s/LAST.CRT", save_path);
resp = fatCreateRecIfNotExist(cfg_file, 0);
resp = fatOpenFileByeName(cfg_file, 1); //512 bytes fix one cluster
static uint8_t cfg_file_data[512] = { 0 };
cfg_file_data[0] = boot_save;
cfg_file_data[1] = boot_cic;
scopy(rom_filename, cfg_file_data + 2);
fatWriteFile(&cfg_file_data, 1);
sleep(500);
//set the fpga cart-save type
evd_setSaveType(boot_save);
if (debug) {
printText("try to restore save from sd", 3, -1, disp);
}
resp = saveTypeFromSd(disp, rom_filename, boot_save);
if (debug) {
sprintf(tmp, "saveTypeFromSd ret=%i",resp);
printText(tmp, 3, -1, disp);
}
}
if (debug) {
printText("Cartridge-Savetype set", 3, -1, disp);
printText("information stored for reboot-save...", 3, -1, disp);
}
sleep(50);
u32 cart, country;
u32 info = *(vu32 *)0xB000003C;
cart = info >> 16;
country = (info >> 8) & 0xFF;
u32 *cheat_lists[2] = { NULL, NULL };
if (cheats_on) {
gCheats = 1;
printText("try to load cheat-file...", 3, -1, disp);
char cheat_filename[64];
sprintf(cheat_filename, "/ED64/CHEATS/%s.yml", rom_filename);
int ok = readCheatFile(cheat_filename, cheat_lists);
if (ok == 0) {
printText("cheats found...", 3, -1, disp);
sleep(600);
}
else {
printText("cheats not found...", 3, -1, disp);
sleep(2000);
gCheats = 0;
}
}
else {
gCheats = 0;
}
disable_interrupts();
int bios_cic = getCicType(1);
if (checksum_fix_on) {
checksum_sdram();
}
evd_lockRegs();
sleep(1000);
while( !(disp = display_lock()) );
//blank screen to avoid glitches
graphics_fill_screen(disp, 0x000000FF);
display_show(disp);
simulate_boot(boot_cic, bios_cic, cheat_lists); // boot_cic
}
}
void playSound(int snd){
//no thread support in libdragon yet, sounds pause the menu for a time :/
//maybe global
int v1;
static SAMPLE *add_sfx = NULL;
if(snd==1)
add_sfx = Sample_Load("rom://ed64_mono.wav");
if(snd==2)
add_sfx = Sample_Load("rom://bamboo.wav");
if(snd==3)
add_sfx = Sample_Load("rom://warning.wav");
if(snd==4)
add_sfx = Sample_Load("rom://done.wav");
MikMod_SetNumVoices(-1, 2);
if (!add_sfx) {
MikMod_Exit();
}
else{
MikMod_EnableOutput();
audio_write_silence();
audio_write_silence();
v1 = Sample_Play(add_sfx, 0, 0);
Voice_SetVolume(v1, 100);
//maybe put update function into a int/vblank callback
for(int s=0;s<50;s++){
MikMod_Update();
sleep(10);
}
MikMod_DisableOutput();
Sample_Free(add_sfx);
}
}
//draws the next char at the text input screen
void drawInputAdd(display_context_t disp, char *msg){
graphics_draw_box_trans(disp, 23, 5, 272, 18, 0x00000090);
position++;
sprintf(input_text, "%s%s",input_text, msg);
drawTextInput(disp,input_text);
}
//del the last char at the text input screen
void drawInputDel(display_context_t disp){
graphics_draw_box_trans(disp, 23, 5, 272, 18, 0x00000090);
if(position){
input_text[position-1]='\0';
drawTextInput(disp,input_text);
position--;
}
}
void drawTextInput(display_context_t disp,char *msg){
graphics_draw_text( disp, 40, 15, msg );
}
void drawConfirmBox(display_context_t disp){
drawBoxNumber(disp,5);
display_show(disp);
printText(" ", 9, 9, disp);
printText("Confirmation required:", 9, -1, disp);
printText(" ", 9, -1, disp);
printText(" ", 9, -1, disp);
printText(" Are you sure?", 9, -1, disp);
printText(" ", 9, -1, disp);
printText(" C-UP Continue ", 9, -1, disp); //set mapping 3
printText(" ", 9, -1, disp);
printText(" B Cancel", 9, -1, disp);
if(sound_on)
playSound(3);
sleep(500);
}
void drawShortInfoBox(display_context_t disp, char* text, u8 mode){
if(mode==0)
drawBoxNumber(disp,7);
else if(mode==1)
drawBoxNumber(disp,8);
else if(mode==2)
drawBoxNumber(disp,10);
printText(text, 9, 14, disp);
display_show(disp);
if(sound_on){
if(mode==0)
playSound(4);
else if(mode==1)
playSound(3);
else if(mode==2)
playSound(4);
}
sleep(300);
}
void readRomConfig(display_context_t disp, char* short_filename, char* full_filename){
u8 found=0;
char cfg_filename[128];
sprintf(rom_filename,"%s", short_filename);
rom_filename[strlen(rom_filename)-4]='\0'; // cut extension
sprintf(cfg_filename,"/ED64/CFG/%s.CFG",rom_filename);
uint8_t rom_cfg_data[512];
FatRecord rec_tmpf;
found = fatFindRecord(cfg_filename, &rec_tmpf, 0);
if(found==0){
//read rom-config
u8 resp = 0;
resp = fatOpenFileByeName(cfg_filename, 0);
resp = fatReadFile(&rom_cfg_data, 1);
rom_config[1]=rom_cfg_data[0];
rom_config[2]=rom_cfg_data[1];
rom_config[3]=rom_cfg_data[2];
rom_config[4]=rom_cfg_data[3];
rom_config[5]=rom_cfg_data[4];
rom_config[6]=rom_cfg_data[5];
rom_config[7]=rom_cfg_data[6];
rom_config[8]=rom_cfg_data[7];
rom_config[9]=rom_cfg_data[8];
}
else{
//preload with header data
romInfoScreen(disp, full_filename, 1); //silent info screen with readout
}
//preload cursor position 1 cic
rom_config[0]=1;
}
void alterRomConfig(int type, int mode){
//mode 1 = increae mode 2 = decrease
//cic
u8 min_cic=0;
u8 max_cic=5;
//save
u8 min_save=0;
u8 max_save=5;
//tv-type
u8 min_tv=0;
u8 max_tv=3;
//cheat
u8 min_cheat=0;
u8 max_cheat=1;
//chk fix
u8 min_chk_sum=0;
u8 max_chk_sum=1;
//quality
u8 min_quality=0;
u8 max_quality=5;
//country
u8 min_country=0;
u8 max_country=2;
if(type==1){//start cic
if(mode==1){
//down
if(rom_config[1]<max_cic)
rom_config[1]++;
if(rom_config[1]==3)
rom_config[1]++;
}
else if(mode==2){
//up
if(rom_config[1]>min_cic)
rom_config[1]--;
if(rom_config[1]==3)
rom_config[1]--;
}
}//end cic
else if(type==2){//start save
if(mode==1){
//down
if(rom_config[2]<max_save)
rom_config[2]++;
}
else if(mode==2){
//up
if(rom_config[2]>min_save)
rom_config[2]--;
}
}//end save
else if(type==3){//start tv
if(mode==1){
//down
if(rom_config[3]<max_tv)
rom_config[3]++;
}
else if(mode==2){
//up
if(rom_config[3]>min_tv)
rom_config[3]--;
}
}//end tv
else if(type==4){//start cheat
if(mode==1){
//down
if(rom_config[4]<max_cheat)
rom_config[4]++;
}
else if(mode==2){
//up
if(rom_config[4]>min_cheat)
rom_config[4]--;
}
}//end cheat
else if(type==5){//start chk sum
if(mode==1){
//down
if(rom_config[5]<max_chk_sum)
rom_config[5]++;
}
else if(mode==2){
//up
if(rom_config[5]>min_chk_sum)
rom_config[5]--;
}
}//end chk sum
else if(type==6){ //start quality
if(mode==1){
//down
if(rom_config[6]<max_quality)
rom_config[6]++;
}
else if(mode==2){
//up
if(rom_config[6]>min_quality)
rom_config[6]--;
}
}
else if(type==7){ //start country
if(mode==1){
//down
if(rom_config[7]<max_country)
rom_config[7]++;
}
else if(mode==2){
//up
if(rom_config[7]>min_country)
rom_config[7]--;
}
}
}
void drawToplistBox(display_context_t disp,int line){
list_pos_backup[0]=cursor;
list_pos_backup[1]=page;
u8 list_size=0;
if(line==0){
FatRecord *rec;
u8 resp = 0;
count = 1;
dir_t buf;
//load the directory-entry
resp = fatLoadDirByName("/ED64/CFG");
int dsize=dir->size;
char toplist[dsize][256];
for (int i = 0; i < dir->size; i++){
rec = dir->rec[i];
u8 rom_cfg_file[128];
//set rom_cfg
sprintf(rom_cfg_file, "/ED64/CFG/%s",rec->name );
static uint8_t cfg_file_data[512] = { 0 };
resp = fatOpenFileByeName(rom_cfg_file, 0); //512 bytes fix one cluster
resp = fatReadFile(&cfg_file_data, 1);
toplist[i][0]=(char)cfg_file_data[5]; //quality
strcpy(toplist[i]+1, cfg_file_data+32); //fullpath
}
qsort(toplist, dsize, 256, compare_int_reverse);
if(dsize>15)
list_size=15;
else
list_size=dsize;
for(int c = 0; c < list_size; c++)
strcpy(toplist15[c], toplist[c]);
list_pos_backup[2]=list_size;
}
list_size=list_pos_backup[2];
u8 min=1;
u8 max=15;
u8 real_max=0;
for(int c = 0; c < list_size; c++)
if(toplist15[c][0]!=0)
real_max++;
max=real_max;
//cursor line
if(line!=0){
if(line==1){
//down
if(toplist_cursor<max)
toplist_cursor++;
}
else if(line==2){
//up
if(toplist_cursor>min)
toplist_cursor--;
}
}
drawBoxNumber(disp,9); //toplist
printText(" -Toplist 15-", 4, 7, disp);
printText(" ", 4, -1, disp);
uint32_t forecolor;
uint32_t backcolor;
backcolor = graphics_make_color(0x00, 0x00, 0x00, 0xFF); //bg
forecolor = graphics_make_color(0xFF, 0xFF, 0xFF, 0xFF); //fg
for(int t = 0; t < 15; t++){
int quality_level=toplist15[t][0]; //quality
if(quality_level!=0){
switch(quality_level){
case 1: forecolor = graphics_make_color(0xFF, 0xFF, 0xFF, 0xFF); //common (white)
break;
case 2: forecolor = graphics_make_color(0x00, 0xFF, 0x00, 0xCF); //uncommon (green)
break;
case 3: forecolor = graphics_make_color(0x1E, 0x90, 0xFF, 0xFF); //rare (blue)
break;
case 4: forecolor = graphics_make_color(0x9B, 0x30, 0xFF, 0xFF); //epic (purple)
break;
case 5: forecolor = graphics_make_color(0xFF, 0xA5, 0x00, 0xFF); //legendary (orange)
break;
default: break;
}
graphics_set_color (forecolor, backcolor);
//max 32 chr
u8 short_name[256];
sprintf(short_name, "%s", toplist15[t]+1);
u8 *pch_s; // point-offset
pch_s=strrchr(short_name,'/');
u8 *pch; // point-offset
pch=strrchr(pch_s,'.');
pch_s[30]='\0'; //was 31
pch_s[pch-pch_s]='\0';
if(t+1==toplist_cursor)
printText(pch_s+1, 5, -1, disp);
else
printText(pch_s+1, 4, -1, disp);
//restore color
graphics_set_color(graphics_make_color(0xFF, 0xFF, 0xFF, 0xFF), graphics_make_color(0x00, 0x00, 0x00, 0x00));
}
}
}
void drawRomConfigBox(display_context_t disp,int line){
u8 min=1;
u8 max=7;
//cursor line
if(line!=0){
if(line==1){
//down
if(rom_config[0]<max)
rom_config[0]++;
}
else if(line==2){
//up
if(rom_config[0]>min)
rom_config[0]--;
}
}
drawBoxNumber(disp,6);
drawConfigSelection(disp, rom_config[0]);
printText(" ", 9, 9, disp);
printText("Rom configuration:", 9, -1, disp);
printText(" ", 9, -1, disp);
switch(rom_config[1]){
case 0: printText(" CIC: 6101", 9, -1, disp); break;
case 1: printText(" CIC: 6102", 9, -1, disp); break;
case 2: printText(" CIC: 6103", 9, -1, disp); break;
case 3: printText(" CIC: 6104", 9, -1, disp); break; //do i really need 6104 in that list? :D
case 4: printText(" CIC: 6105", 9, -1, disp); break;
case 5: printText(" CIC: 6106", 9, -1, disp); break;
default: break;
}
switch(rom_config[2]){
case 0: printText(" Save: Off/Mempak", 9, -1, disp); break;
case 1: printText(" Save: Sram 32", 9, -1, disp); break;
case 2: printText(" Save: Sram 128", 9, -1, disp); break;
case 3: printText(" Save: Eeprom 4k", 9, -1, disp); break;
case 4: printText(" Save: Eeprom 16k", 9, -1, disp); break;
case 5: printText(" Save: Flashram", 9, -1, disp); break;
default: break;
}
switch(rom_config[3]){
case 0: printText(" Tv: Force off", 9, -1, disp); break;
case 1: printText(" Tv: NTSC", 9, -1, disp); break;
case 2: printText(" Tv: PAL", 9, -1, disp); break;
case 3: printText(" Tv: M-PAL", 9, -1, disp); break;
default: break;
}
switch(rom_config[4]){
case 0: printText(" Cheat: off", 9, -1, disp); break;
case 1: printText(" Cheat: on", 9, -1, disp); break;
default: break;
}
switch(rom_config[5]){
case 0: printText("Checksum: disable fix", 9, -1, disp); break;
case 1: printText("Checksum: enable fix", 9, -1, disp); break;
default: break;
}
switch(rom_config[6]){
case 0: printText(" Rating: off", 9, -1, disp); break;
case 1: printText(" Rating: common", 9, -1, disp); break;
case 2: printText(" Rating: uncommon", 9, -1, disp); break;
case 3: printText(" Rating: rare", 9, -1, disp); break;
case 4: printText(" Rating: epic", 9, -1, disp); break;
case 5: printText(" Rating: legendary", 9, -1, disp); break;
default: break;
}
switch(rom_config[7]){
case 0: printText(" Country: default", 9, -1, disp); break;
case 1: printText(" Country: NTSC", 9, -1, disp); break;
case 2: printText(" Country: PAL", 9, -1, disp); break;
default: break;
}
printText(" ", 9, -1, disp);
printText("B Cancel", 9, -1, disp);
printText("A Save config", 9, -1, disp);
}
//draws the charset for the textinputscreen
void drawSet1(display_context_t disp){
set=1;
uint32_t forecolor;
uint32_t backcolor;
backcolor = graphics_make_color(0x00, 0x00, 0x00, 0xFF);
forecolor = graphics_make_color(0xFF, 0xFF, 0x00, 0xFF); //yellow
graphics_draw_text( disp, 80, 40, "<" ); //L
graphics_set_color(forecolor, backcolor);
graphics_draw_text( disp, 233, 40, "A" ); //R
graphics_draw_text( disp, 223, 62, "B" ); //G up
graphics_draw_text( disp, 210, 74, "C" ); //G left
graphics_draw_text( disp, 235, 74, "D" ); //G right
graphics_draw_text( disp, 193, 86, "E" ); //B
graphics_draw_text( disp, 223, 86, "F" ); //G down
graphics_draw_text( disp, 209, 100, "G" ); //A
}
void drawSet2(display_context_t disp){
set=2;
uint32_t forecolor;
uint32_t backcolor;
backcolor = graphics_make_color(0x00, 0x00, 0x00, 0xFF);
forecolor = graphics_make_color(0xFF, 0xFF, 0x00, 0xFF);
graphics_draw_text( disp, 80, 40, "<" );
graphics_set_color(forecolor, backcolor);
graphics_draw_text( disp, 233, 40, "H" );
graphics_draw_text( disp, 223, 62, "I" );
graphics_draw_text( disp, 210, 74, "J" );
graphics_draw_text( disp, 235, 74, "K" );
graphics_draw_text( disp, 193, 86, "L" );
graphics_draw_text( disp, 223, 86, "M" );
graphics_draw_text( disp, 209, 100, "N" );
}
void drawSet3(display_context_t disp){
set=3;
uint32_t forecolor;
uint32_t backcolor;
backcolor = graphics_make_color(0x00, 0x00, 0x00, 0xFF);
forecolor = graphics_make_color(0xFF, 0xFF, 0x00, 0xFF);
graphics_draw_text( disp, 80, 40, "<" );
graphics_set_color(forecolor, backcolor);
graphics_draw_text( disp, 233, 40, "O" );
graphics_draw_text( disp, 223, 62, "P" );
graphics_draw_text( disp, 210, 74, "Q" );
graphics_draw_text( disp, 235, 74, "R" );
graphics_draw_text( disp, 193, 86, "S" );
graphics_draw_text( disp, 223, 86, "T" );
graphics_draw_text( disp, 209, 100, "U" );
}
display_context_t lockVideo(int wait) {
display_context_t dc;
if (wait)
while (!(dc = display_lock()));
else
dc = display_lock();
return dc;
}
void drawSet4(display_context_t disp){
set=4;
uint32_t forecolor;
uint32_t backcolor;
backcolor = graphics_make_color(0x00, 0x00, 0x00, 0xFF);
forecolor = graphics_make_color(0xFF, 0xFF, 0x00, 0xFF);
graphics_draw_text( disp, 80, 40, "<" );
graphics_set_color(forecolor, backcolor);
graphics_draw_text( disp, 233, 40, "V" );
graphics_draw_text( disp, 223, 62, "W" );
graphics_draw_text( disp, 210, 74, "X" );
graphics_draw_text( disp, 235, 74, "Y" );
graphics_draw_text( disp, 193, 86, "Z" );
graphics_draw_text( disp, 223, 86, "-" );
graphics_draw_text( disp, 209, 100, "_" );
}
//entry point
int main(void) {
int fast_boot=0;
//reserve memory
list = malloc(sizeof(direntry_t));
//dfs init for the rom-attached virtual filesystem
if(dfs_init( DFS_DEFAULT_LOCATION ) != DFS_ESUCCESS) {
printf("Filesystem failed to start!\n");
}
else {
int fpf = dfs_open("/firmware.bin");
firmware = malloc( dfs_size( fpf ) );
dfs_read( firmware, 1, dfs_size( fpf ), fpf );
dfs_close( fpf );
// everdrive initial function
configure();
//fast boot for backup-save data
int sj = evd_readReg(0);
int save_job = evd_readReg(REG_SAV_CFG);
if(save_job!=0)
fast_boot=1;
//not gamepads more or less the n64 hardware-controllers
controller_init();
//filesystem on
initFilesystem();
sleep(200);
readConfigFile();
//n64 initialization
if(tv_mode!=0){
*(u32 *) 0x80000300 = tv_mode;
}
init_interrupts();
//background
display_init( res, DEPTH_32_BPP, 3, GAMMA_NONE, ANTIALIAS_RESAMPLE );
//bg buffer
static display_context_t disp;
//Grab a render buffer
while( !(disp = display_lock()) );
//backgrounds from ramfs/libdragonfs
if(!fast_boot){
background0 = read_sprite( "rom://sprites/splash.sprite" );
graphics_draw_sprite( disp, 0, 0, background0 ); //start-picture
display_show(disp);
}
char background_path[64];
sprintf(background_path, "/ED64/wallpaper/%s", background_image);
int found;
FatRecord rec_tmpf;
found = fatFindRecord(background_path, &rec_tmpf, 0);
if(found==0){
background = loadPng(background_path);
}
else{
background = read_sprite( "rom://sprites/background.sprite" );
}
sleep(200);
//mp3
int buf_size;
char *buf_ptr;
if(sound_on){
audio_init(44100,2);
//load soundsystem
timer_init();
MikMod_RegisterAllDrivers();
MikMod_RegisterAllLoaders();
md_mode = 0;
md_mode |= DMODE_16BITS;
md_mode |= DMODE_SOFT_MUSIC;
md_mode |= DMODE_SOFT_SNDFX;
md_mixfreq = audio_get_frequency();
MikMod_Init("");
}
if(!fast_boot){
if(sound_on)
playSound(1);
sleep(2000); //splash screen duration
}
border_color_1 = translate_color(border_color_1_s);
border_color_2= translate_color(border_color_2_s);
box_color= translate_color(box_color_s);
selection_color= translate_color(selection_color_s);
selection_font_color= translate_color(selection_font_color_s);
list_font_color= translate_color(list_font_color_s);
list_dir_font_color= translate_color(list_dir_font_color_s);
while( !(disp = display_lock()) );
drawBg(disp); //new
drawBoxNumber(disp,1); //new
uint32_t *buffer = (uint32_t *)__get_buffer( disp ); //fg disp = 2
display_show(disp); //new
backupSaveData(disp);
while( !(disp = display_lock()) );
sprintf(pwd,"%s", "/");
readSDcard(disp,"/");
display_show(disp);
//chr input coord
x=30;
y=30;
position=0;
set=1;
sprintf(input_text, "");
//sprite for chr input
int fp = dfs_open("/n64controller.sprite");
sprite_t *contr = malloc( dfs_size( fp ) );
dfs_read( contr, 1, dfs_size( fp ), fp );
dfs_close( fp );
//sd card speed settings from config
if(sd_speed==2){
bi_speed50();
}
else{
bi_speed25();
}
//system main-loop with controller inputs-scan
while(1) {
if (playing==1)
playing = update_mp3(buf_ptr, buf_size);
if(input_mapping==1)
sleep(60);
if(input_mapping==3){
while( !(disp = display_lock()) );
graphics_draw_sprite( disp, 0, 0, contr );
/* Set the text output color */
graphics_set_color( 0x0, 0xFFFFFFFF );
chr_forecolor = graphics_make_color(0xFF, 0x14, 0x94, 0xFF); //pink
graphics_set_color(chr_forecolor, chr_backcolor);
graphics_draw_text( disp, 85, 55, "SETS" );
graphics_draw_text( disp, 94, 70, "1" ); //u
graphics_draw_text( disp, 104, 82, "2" ); //r
graphics_draw_text( disp, 94, 93, "3" ); //d
graphics_draw_text( disp, 82, 82, "4" ); //l
graphics_draw_text( disp, 208, 206, "press START" );
if(set==1)
drawSet1(disp);
if(set==2)
drawSet2(disp);
if(set==3)
drawSet3(disp);
if(set==4)
drawSet4(disp);
drawTextInput(disp, input_text);
/* Force backbuffer flip */
display_show(disp);
} //mapping 2 chr input drawings
//request controller
controller_scan();
struct controller_data keys = get_keys_down();
struct controller_data keys_held = get_keys_held();
if(keys.c[0].up || keys_held.c[0].up || keys_held.c[0].y > +25) {
if(input_mapping==1){
if(select_mode){
if(count!=0){
if(scroll_behaviour==1)
cursor--;
else if(cursor!=0) {
if((cursor+0)%20==0){
cursor--;
page-=20;
}
else{
cursor--;
}
}
//end
while( !(disp = display_lock()) );
new_scroll_pos(&cursor, &page, MAX_LIST, count);
clearScreen(disp); //part clear?
display_dir(list, cursor, page, MAX_LIST, count, disp);
display_show(disp);
}
}
}
else if(input_mapping==2){
}
else if(input_mapping==3){
//chr input screen
set=1;
}
else if(input_mapping==7){
while( !(disp = display_lock()) );
new_scroll_pos(&cursor, &page, MAX_LIST, count);
clearScreen(disp); //part clear?
display_dir(list, cursor, page, MAX_LIST, count, disp);
drawRomConfigBox(disp,2);
display_show(disp);
input_mapping=7;
sleep(80);
}
else if(input_mapping==8){
while( !(disp = display_lock()) );
drawBg(disp); //background
drawToplistBox(disp,2);
display_show(disp);
input_mapping=8;
sleep(80);
}
}
if(keys.c[0].down || keys_held.c[0].down || keys_held.c[0].y < -25) {
if(input_mapping==1){
if(select_mode){
if(count!=0){
if(scroll_behaviour==1)
cursor++;
else if(cursor+1!=count) {
if((cursor+1)%20==0){
cursor++;
page+=20;
}
else{
cursor++;
}
}
while( !(disp = display_lock()) );
new_scroll_pos(&cursor, &page, MAX_LIST, count);
clearScreen(disp); //part clear?
display_dir(list, cursor, page, MAX_LIST, count, disp);
display_show(disp);
}
}
}
else if(input_mapping==2){
}
else if(input_mapping==3){
//chr input screen
set=3;
}
else if(input_mapping==7){
while( !(disp = display_lock()) );
new_scroll_pos(&cursor, &page, MAX_LIST, count);
clearScreen(disp); //part clear?
display_dir(list, cursor, page, MAX_LIST, count, disp);
drawRomConfigBox(disp,1);
display_show(disp);
input_mapping=7;
sleep(80);
}
else if(input_mapping==8){
while( !(disp = display_lock()) );
drawBg(disp);
drawToplistBox(disp,1);
display_show(disp);
input_mapping=8;
sleep(80);
}
}
else if(keys.c[0].left || keys_held.c[0].left || keys_held.c[0].x < -25) {
if(input_mapping==1){
if(select_mode){
if(count!=0 && scroll_behaviour==0 && cursor-20>=0){
page-=20;
cursor=page;
}
while( !(disp = display_lock()) );
new_scroll_pos(&cursor, &page, MAX_LIST, count);
clearScreen(disp); //part clear?
display_dir(list, cursor, page, MAX_LIST, count, disp);
display_show(disp);
}
}
else if(input_mapping==2){
}
else if(input_mapping==3){
//chr input screen
set=4;
}
else if(input_mapping==7){
while( !(disp = display_lock()) );
new_scroll_pos(&cursor, &page, MAX_LIST, count);
clearScreen(disp); //part clear?
display_dir(list, cursor, page, MAX_LIST, count, disp);
alterRomConfig(rom_config[0], 2);
drawRomConfigBox(disp,0);
display_show(disp);
input_mapping=7;
sleep(80);
}
}
else if(keys.c[0].right || keys_held.c[0].right || keys_held.c[0].x > +25) {
if(input_mapping==1){
if(select_mode){
if ((count != 0) &&
(scroll_behaviour == 0) &&
(page + 20 != count) &&
(cursor+20 <= ((count / 20) * 20 + 19)))
{
page+=20;
cursor=page;
}
while( !(disp = display_lock()) );
new_scroll_pos(&cursor, &page, MAX_LIST, count);
clearScreen(disp); //part clear?
display_dir(list, cursor, page, MAX_LIST, count, disp);
display_show(disp);
}
}
else if(input_mapping==2){
}
else if(input_mapping==3){
//chr input screen
set=2;
}
else if(input_mapping==7){
while( !(disp = display_lock()) );
new_scroll_pos(&cursor, &page, MAX_LIST, count);
clearScreen(disp); //part clear?
display_dir(list, cursor, page, MAX_LIST, count, disp);
alterRomConfig(rom_config[0], 1);
drawRomConfigBox(disp,0);
display_show(disp);
input_mapping=7;
sleep(80);
}
}
else if( keys.c[0].start ){
if(input_mapping==1){
//quick boot
if(quick_boot){
FatRecord rec_last;
uint8_t lastrom_cfg_data[512];
if(fatFindRecord("/ED64/LASTROM.CFG", &rec_last, 0)==0){
u8 resp = 0;
resp = fatOpenFileByeName("/ED64/LASTROM.CFG", 0);
resp = fatReadFile(&lastrom_cfg_data, 1);
u8 * short_s;
short_s=strrchr(lastrom_cfg_data,'/');
while( !(disp = display_lock()) );
clearScreen(disp);
sleep(100);
evd_ulockRegs();
sleep(100);
select_mode=9;
//short fullpath
readRomConfig(disp, short_s+1, lastrom_cfg_data);
loadrom(disp, lastrom_cfg_data, 1);
display_show(disp);
}
//nothing else :>
drawShortInfoBox(disp, " rom not found",0);
}
else if(list[cursor].type != DT_DIR && empty==0){
char name_file[64];
if(strcmp(pwd,"/")==0 )
sprintf(name_file,"/%s", list[cursor].filename);
else
sprintf(name_file,"%s/%s", pwd, list[cursor].filename);
/*filetype
* 1 rom
* 2 mempak
* 3 background
* 4 mp3
*/
int ft=0;
char _upper_name_file[64];
strcpy(_upper_name_file, name_file);
strhicase(_upper_name_file, strlen (_upper_name_file));
sprintf(_upper_name_file, "%s", _upper_name_file );
u8 extension[4];
u8 *pch;
pch=strrchr(_upper_name_file,'.'); //asd.n64
sprintf(extension, "%s",(pch+1)); //0123456
if(!strcmp(extension,"GB" ))
ft=5;
if(!strcmp(extension,"GBC" ))
ft=6;
if(!strcmp(extension,"NES" ))
ft=7;
if(!strcmp(extension,"GG" ))
ft=8;
if(!strcmp(extension,"MSX" ))
ft=9;
if(!strcmp(extension,"MPK" ))
ft=2;
if(!strcmp(extension,"Z64") || !strcmp(extension,"V64") || !strcmp(extension,"N64"))
ft=1;
if(ft==1){ //rom
//load rom
while( !(disp = display_lock()) );
clearScreen(disp);
u16 msg = 0;
sleep(300);
evd_ulockRegs();
sleep(300);
sprintf(rom_filename,"%s", list[cursor].filename);
select_mode=9;
//read rom_config data
readRomConfig(disp, rom_filename, name_file);
loadrom(disp,name_file, 1);
display_show(disp);
//rom loaded mapping
input_mapping=4;
}
else if(ft==5 || ft==6){ //gb/gbc rom
//load rom
while( !(disp = display_lock()) );
clearScreen(disp);
u16 msg = 0;
sleep(300);
evd_ulockRegs();
sleep(300);
sprintf(rom_filename,"%s", list[cursor].filename);
display_show(disp);
select_mode=9;
loadgbrom(disp,name_file);
display_show(disp);
}
else if(ft==2){ //mempak
}
else if(ft==7){ //nes
//load rom
while( !(disp = display_lock()) );
clearScreen(disp);
u16 msg = 0;
sleep(300);
evd_ulockRegs();
sleep(300);
sprintf(rom_filename,"%s", list[cursor].filename);
display_show(disp);
select_mode=9;
loadnesrom(disp,name_file);
display_show(disp);
}
else if(ft==8){ //gg
//load gg rom
while( !(disp = display_lock()) );
clearScreen(disp);
u16 msg = 0;
sleep(300);
evd_ulockRegs();
sleep(300);
sprintf(rom_filename,"%s", list[cursor].filename);
display_show(disp);
select_mode=9;
loadggrom(disp,name_file);
display_show(disp);
}
else if(ft==9){ //msx2
//load msx2 rom
while( !(disp = display_lock()) );
clearScreen(disp);
u16 msg = 0;
sleep(300);
evd_ulockRegs();
sleep(300);
sprintf(rom_filename,"%s", list[cursor].filename);
display_show(disp);
select_mode=9;
loadmsx2rom(disp,name_file);
display_show(disp);
}
}
}
else if(input_mapping==2){
}
else if(input_mapping==3){
//better config color-set
graphics_set_color(
graphics_make_color(0xFF, 0xFF, 0xFF, 0xFF),
graphics_make_color(0x00, 0x00, 0x00, 0x00)
);
clearScreen(disp);
display_dir(list, cursor, page, MAX_LIST, count, disp);
if(input_text[0]!='\0'){ //input_text is set - do backup
drawBoxNumber(disp,2);
display_show(disp);
printText("Mempak-Backup:", 9, 9, disp);
printText(" ", 9, -1, disp);
printText("search...", 9, -1, disp);
mpk_to_file(disp, input_text, 0);
sleep(300);
drawShortInfoBox(disp, " done",0);
sleep(2000);
//reread filesystem
cursor_line=0;
readSDcard(disp,"/");
}
input_mapping=1;
}
else if(input_mapping==4){
//rom start screen
//normal boot
//boot the loaded rom
bootRom(disp, 0);
//never return
}
}
else if( keys.c[0].L ) {
if(input_mapping==1){
input_mapping=2;
drawBoxNumber(disp,2);
display_show(disp);
printText("Mempak-Subsystem:", 9, 9, disp);
printText(" ", 9, -1, disp);
printText(" ", 9, -1, disp);
printText(" Z: View content", 9, -1, disp);
printText(" ", 9, -1, disp);
printText(" A: Backup - new", 9, -1, disp); //set mapping 3
printText(" ", 9, -1, disp);
printText(" R: Format", 9, -1, disp);
printText(" ", 9, -1, disp);
printText(" B: Abort", 9, -1, disp);
if(sound_on) playSound(2);
sleep(500);
}
else if(input_mapping==2){
}
else if(input_mapping==3){
//chr input screen
drawInputDel(disp);
}
else if(input_mapping==9){
//c-up or A
drawConfirmBox(disp);
//confirm restore mpk
input_mapping=6;
}
}
else if( keys.c[0].R ) {
if(input_mapping==1){
}
else if(input_mapping==2){
//c-up or A
drawConfirmBox(disp);
//confirm format mpk
input_mapping=5;
}
else if(input_mapping==3){
//chr input screen
if(set==1)
drawInputAdd(disp, "A"); //P X )
if(set==2)
drawInputAdd(disp, "H");
if(set==3)
drawInputAdd(disp, "O");
if(set==4)
drawInputAdd(disp, "V");
}
else if(input_mapping==9){
//c-up or A
drawConfirmBox(disp);
//confirm quick-backup
input_mapping=10;
}
}
else if( keys.c[0].C_up ) {
if(input_mapping==1){
if(list[cursor].type != DT_DIR && empty==0){
drawBoxNumber(disp,11);
char *part;
part = malloc(slen(list[cursor].filename));
sprintf(part,"%s", list[cursor].filename);
part[31]='\0';
printText(part, 4, 14, disp);
if(slen(list[cursor].filename)>31){
sprintf(part,"%s", list[cursor].filename+31);
part[31]='\0';
printText(part, 4, -1, disp);
}
free(part);
input_mapping=98;
}
}
else if(input_mapping==2){
}
else if(input_mapping==3){
//chr input screen
if(set==1)
drawInputAdd(disp, "B"); //P X )
if(set==2)
drawInputAdd(disp, "I");
if(set==3)
drawInputAdd(disp, "P");
if(set==4)
drawInputAdd(disp, "W");
}
else if(input_mapping==4){
//rom start screen
if(cheats_on==0){
printText("cheat system activated...", 3, -1, disp);
cheats_on=1;
}
}
else if(input_mapping==5){ // format mpk
drawBoxNumber(disp,2);
display_show(disp);
printText("Mempak-Format:", 9, 9, disp);
printText(" ", 9, -1, disp);
printText("formating...", 9, -1, disp);
/* Make sure they don't have a rumble pak inserted instead */
switch( identify_accessory( 0 ) ){
case ACCESSORY_NONE:
printText("No Mempak", 9, -1, disp);
break;
case ACCESSORY_MEMPAK:
printText("Please wait...", 9, -1, disp);
if( format_mempak( 0 ) ) {
printText("Error formatting!", 9, -1, disp);
}
else {
drawShortInfoBox(disp, " done",0);
input_mapping=98;
}
break;
case ACCESSORY_RUMBLEPAK:
printText("Cannot format rumblepak!", 9, -1, disp);
break;
}
sleep(500);
input_mapping=98;
}
else if(input_mapping==6){ //restore mpk
drawBoxNumber(disp,2);
display_show(disp);
printText("Mempak-Restore:", 9, 9, disp);
printText(" ", 9, -1, disp);
file_to_mpk(disp, rom_filename);
sleep(300);
drawShortInfoBox(disp, " done",0);
input_mapping=98;
display_show(disp);
}
else if(input_mapping==10){ //quick-backup
drawBoxNumber(disp,2);
display_show(disp);
printText("Quick-Backup:", 9, 9, disp);
printText(" ", 9, -1, disp);
printText("search...", 9, -1, disp);
mpk_to_file(disp, list[cursor].filename, 1); //quick
sleep(300);
drawShortInfoBox(disp, " done",0);
sleep(500);
input_mapping=98;
}
}
else if( keys.c[0].C_right ) {
if(input_mapping==1 && list[cursor].type != DT_DIR){
//show rom cfg screen
char name_file[64];
if(strcmp(pwd,"/")==0 )
sprintf(name_file,"/%s", list[cursor].filename);
else
sprintf(name_file,"%s/%s", pwd, list[cursor].filename);
/*filetype
* 1 rom
*/
int ft=0;
char _upper_name_file[64];
strcpy(_upper_name_file, name_file);
strhicase(_upper_name_file, strlen (_upper_name_file));
sprintf(_upper_name_file, "%s", _upper_name_file );
u8 extension[4];
u8 *pch;
pch=strrchr(_upper_name_file,'.'); //asd.n64
sprintf(extension, "%s",(pch+1)); //0123456
if(!strcmp(extension,"Z64") || !strcmp(extension,"V64") || !strcmp(extension,"N64"))
ft=1;
if(ft==1){ //rom
//cfg rom
sprintf(rom_filename,"%s", list[cursor].filename);
//preload config or file header
readRomConfig(disp, rom_filename, name_file);
drawRomConfigBox(disp,0);
display_show(disp);
input_mapping=7;
}
}
else if(input_mapping==2){
}
else if(input_mapping==3){
//chr input screen
if(set==1)
drawInputAdd(disp, "D"); //P X )
if(set==2)
drawInputAdd(disp, "K");
if(set==3)
drawInputAdd(disp, "R");
if(set==4)
drawInputAdd(disp, "Y");
}
else if(input_mapping==4){
//rom start screen
if(force_tv!=0){
printText("force tv mode...", 3, -1, disp);
}
}
}
else if( keys.c[0].C_down ) {
if(input_mapping==1){
input_mapping=99;
scopy(pwd, list_pwd_backup);
while( !(disp = display_lock()) );
drawBg(disp); //background
toplist_cursor=1;
drawToplistBox(disp,0); //0 = load entries
display_show(disp);
input_mapping=8;
}
else if(input_mapping==2){
}
else if(input_mapping==3){
//chr input screen
if(set==1)
drawInputAdd(disp, "F"); //P X )
if(set==2)
drawInputAdd(disp, "M");
if(set==3)
drawInputAdd(disp, "T");
if(set==4)
drawInputAdd(disp, "-"); //GR Set4
}
}
else if( keys.c[0].C_left ) {
if(input_mapping==1){
if(input_mapping==1 && list[cursor].type != DT_DIR ){//open
char name_file[64];
if(strcmp(pwd,"/")==0 )
sprintf(name_file,"/%s", list[cursor].filename);
else
sprintf(name_file,"%s/%s", pwd, list[cursor].filename);
/*filetype
* 1 rom
* 2 mempak
* 3 background
* 4 mp3
*/
int ft=0;
char _upper_name_file[64];
strcpy(_upper_name_file, name_file);
strhicase(_upper_name_file, strlen (_upper_name_file));
sprintf(_upper_name_file, "%s", _upper_name_file );
u8 extension[4];
u8 *pch;
pch=strrchr(_upper_name_file,'.');
sprintf(extension, "%s",(pch+1));
if(!strcmp(extension,"MPK" ))
ft=2;
if(!strcmp(extension,"Z64") || !strcmp(extension,"V64") || !strcmp(extension,"N64"))
ft=1;
if(ft==1){ //rom
//load rom
input_mapping=99;
drawBoxNumber(disp,3); //rominfo
u16 msg = 0;
sleep(300);
evd_ulockRegs();
sleep(300);
sprintf(rom_filename,"%s", list[cursor].filename);
romInfoScreen(disp, name_file, 0);
if(sound_on)
playSound(2);
sleep(500);
input_mapping=98;
}
if(ft==2){ //mpk file
drawBoxNumber(disp,4);
display_show(disp);
if(strcmp(pwd,"/")==0 )
sprintf(rom_filename,"/%s", list[cursor].filename);
else
sprintf(rom_filename,"%s/%s", pwd, list[cursor].filename);
view_mpk_file(disp, rom_filename);
if(sound_on)
playSound(2);
sleep(500);
input_mapping=98;
}
} //mapping and not dir
}
else if(input_mapping==2){
}
else if(input_mapping==3){
//chr input screen
if(set==1)
drawInputAdd(disp, "C"); //P X )
if(set==2)
drawInputAdd(disp, "J");
if(set==3)
drawInputAdd(disp, "Q");
if(set==4)
drawInputAdd(disp, "X");
}
}
else if(keys.c[0].Z){
if(input_mapping==1){
input_mapping=99;
drawBoxNumber(disp,2);
display_show(disp);
printText("About: ", 9, 8, disp);
printText(" ", 9, -1, disp);
printText("ALT64: v0.1.8.6-cheat", 9, -1, disp);
printText("by saturnu", 9, -1, disp);
printText(" ", 9, -1, disp);
printText("Code engine by:", 9, -1, disp);
printText("Jay Oster", 9, -1, disp);
printText(" ", 9, -1, disp);
printText("thanks to:", 9, -1, disp);
printText("Krikzz", 9, -1, disp);
printText("Richard Weick", 9, -1, disp);
printText("ChillyWilly", 9, -1, disp);
printText("ShaunTaylor", 9, -1, disp);
printText("Conle", 9, -1, disp);
if(sound_on)
playSound(2);
sleep(500);
input_mapping=98;
}
else if(input_mapping==2){
drawBoxNumber(disp,4);
display_show(disp);
view_mpk(disp);
if(sound_on)
playSound(2);
sleep(500);
input_mapping=98;
}
}
else if(keys.c[0].A) { // open
if(input_mapping==1){
while( !(disp = display_lock()) );
if(input_mapping==1 && list[cursor].type == DT_DIR && empty==0){
char name_dir[256];
/* init pwd=/
* /
*
* cursor=ED64
* /ED64
*
* cursor=SAVE
* /ED64/SAVE
*/
if(strcmp(pwd,"/")==0 )
sprintf(name_dir,"/%s", list[cursor].filename);
else
sprintf(name_dir,"%s/%s", pwd, list[cursor].filename);
sprintf(curr_dirname,"%s", list[cursor].filename);
sprintf(pwd,"%s", name_dir);
//load dir
cursor_lastline=0;
cursor_line=0;
//backup tree cursor postions
if(cd_behaviour==1){
cursor_history[cursor_history_pos]=cursor;
cursor_history_pos++;
}
readSDcard(disp,name_dir);
display_show(disp);
}//mapping 1 and dir
else if(input_mapping==1 && list[cursor].type != DT_DIR && empty==0){//open
char name_file[256];
if(strcmp(pwd,"/")==0 )
sprintf(name_file,"/%s", list[cursor].filename);
else
sprintf(name_file,"%s/%s", pwd, list[cursor].filename);
/*filetype
* 1 rom
* 2 mempak
* 3 background
* 4 mp3
*/
int ft=0;
char _upper_name_file[256];
strcpy(_upper_name_file, name_file);
strhicase(_upper_name_file, strlen (_upper_name_file));
sprintf(_upper_name_file, "%s", _upper_name_file );
u8 extension[4];
u8 *pch;
pch=strrchr(_upper_name_file,'.'); //asd.n64
sprintf(extension, "%s",(pch+1)); //0123456
if(!strcmp(extension,"GB" ))
ft=5;
if(!strcmp(extension,"GBC" ))
ft=6;
if(!strcmp(extension,"NES" ))
ft=7;
if(!strcmp(extension,"GG" ))
ft=8;
if(!strcmp(extension,"MSX" ))
ft=9;
if(!strcmp(extension,"MP3" ))
ft=10;
if(!strcmp(extension,"MPK" ))
ft=2;
if(!strcmp(extension,"Z64") || !strcmp(extension,"V64") || !strcmp(extension,"N64"))
ft=1;
if(ft==1){ //rom
//load rom
while( !(disp = display_lock()) );
clearScreen(disp);
u16 msg = 0;
sleep(300);
evd_ulockRegs();
sleep(300);
sprintf(rom_filename,"%s", list[cursor].filename);
if(quick_boot){
u8 resp=0;
resp = fatCreateRecIfNotExist("/ED64/LASTROM.CFG", 0);
resp = fatOpenFileByeName("/ED64/LASTROM.CFG", 1); //512 bytes fix one cluster
static uint8_t lastrom_file_data[512] = { 0 };
scopy(name_file, lastrom_file_data);
fatWriteFile(&lastrom_file_data, 1);
}
select_mode=9;
//read rom_config data
readRomConfig(disp, rom_filename, name_file);
loadrom(disp,name_file, 1);
display_show(disp);
//rom loaded mapping
input_mapping=4;
}
else if(ft==5 || ft==6){ //gb/gbc rom
//load rom
while( !(disp = display_lock()) );
clearScreen(disp);
u16 msg = 0;
sleep(300);
evd_ulockRegs();
sleep(300);
sprintf(rom_filename,"%s", list[cursor].filename);
display_show(disp);
select_mode=9;
loadgbrom(disp,name_file);
display_show(disp);
}
else if(ft==2){ //mempak
while( !(disp = display_lock()) );
clearScreen(disp); //part clear?
display_dir(list, cursor, page, MAX_LIST, count, disp);
display_show(disp);
drawShortInfoBox(disp, " L=Restore R=Backup", 2);
input_mapping=9;
sprintf(rom_filename,"%s", name_file);
}
else if(ft==7){ //nes
//load rom
while( !(disp = display_lock()) );
clearScreen(disp);
u16 msg = 0;
sleep(300);
evd_ulockRegs();
sleep(300);
sprintf(rom_filename,"%s", list[cursor].filename);
display_show(disp);
select_mode=9;
loadnesrom(disp,name_file);
display_show(disp);
}
else if(ft==8){ //gg
//load gg rom
while( !(disp = display_lock()) );
clearScreen(disp);
u16 msg = 0;
sleep(300);
evd_ulockRegs();
sleep(300);
sprintf(rom_filename,"%s", list[cursor].filename);
display_show(disp);
select_mode=9;
loadggrom(disp,name_file);
display_show(disp);
}
else if(ft==9){ //msx2
//load msx2 rom
while( !(disp = display_lock()) );
clearScreen(disp);
u16 msg = 0;
sleep(300);
evd_ulockRegs();
sleep(300);
sprintf(rom_filename,"%s", list[cursor].filename);
display_show(disp);
select_mode=9;
loadmsx2rom(disp,name_file);
display_show(disp);
}
else if(ft==10){ //mp3
//load mp3
buf_size = audio_get_buffer_length() * 4;
buf_ptr = malloc(buf_size);
while( !(disp = display_lock()) );
clearScreen(disp);
drawShortInfoBox(disp, " playback",0);
long long start = 0, end = 0, curr, pause = 0, samples;
int rate = 44100, last_rate = 44100, channels = 2;
audio_init(44100,2);
start_mp3(name_file, &samples, &rate, &channels);
playing=1;
select_mode=9;
input_mapping=11;//mp3 stop
display_show(disp);
}
} //mapping and not dir
}//mapping 1 end
else if(input_mapping==2){
//open up charinput screen
input_mapping=3;
input_text[0]='\0';
graphics_draw_sprite( disp, 0, 0, contr );
}
else if(input_mapping==3){
//chr input screen
if(set==1)
drawInputAdd(disp, "G"); //P X )
if(set==2)
drawInputAdd(disp, "N");
if(set==3)
drawInputAdd(disp, "U");
if(set==4)
drawInputAdd(disp, "_");
}
else if(input_mapping==7){
//save rom_cfg[] to
// /ED64/CFG/Romname.cfg if not exist create
// if exist open/write
//print confirm msg
char name_file[256];
if(strcmp(pwd,"/")==0 )
sprintf(name_file,"/%s", list[cursor].filename);
else
sprintf(name_file,"%s/%s", pwd, list[cursor].filename);
u8 rom_cfg_file[128];
u8 resp=0;
//set rom_cfg
sprintf(rom_cfg_file, "/ED64/CFG/%s.CFG",rom_filename );
resp = fatCreateRecIfNotExist(rom_cfg_file, 0);
resp = fatOpenFileByeName(rom_cfg_file, 1); //512 bytes fix one cluster
static uint8_t cfg_file_data[512] = { 0 };
cfg_file_data[0]=rom_config[1]; //cic
cfg_file_data[1]=rom_config[2]; //save
cfg_file_data[2]=rom_config[3]; //tv
cfg_file_data[3]=rom_config[4]; //cheat
cfg_file_data[4]=rom_config[5]; //chksum
cfg_file_data[5]=rom_config[6]; //rating
cfg_file_data[6]=rom_config[7]; //country
cfg_file_data[7]=rom_config[8];
cfg_file_data[8]=rom_config[9];
//copy full rom path to offset at 32 byte - 32 bytes reversed
scopy(name_file, cfg_file_data+32); //filename to rom_cfg file
fatWriteFile(&cfg_file_data, 1);
sleep(200);
drawShortInfoBox(disp, " done",0);
toplist_reload=1;
input_mapping=98;
}
else if(input_mapping==8){
//run from toplist
u8 * pch_s;
pch_s=strrchr(toplist15[toplist_cursor-1]+1,'/');
readRomConfig(disp, pch_s+1, toplist15[toplist_cursor-1]+1);
loadrom(disp,toplist15[toplist_cursor-1]+1, 1);
//rom loaded mapping
input_mapping=4;
}
else if(input_mapping==98){
//rom info screen
while( !(disp = display_lock()) );
clearScreen(disp); //part clear?
display_dir(list, cursor, page, MAX_LIST, count, disp);
display_show(disp);
input_mapping=1;
}
}//key a
else if(keys.c[0].B ) { //go back
if(input_mapping==1){
if(!(strcmp(pwd,"/")==0)){
while( !(disp = display_lock()) );
//replace by strstr()? :>
int slash_pos=0;
int i = 0;
while(pwd[i] != '\0'){
if(pwd[i] == '/')
slash_pos=i;
i++;
}
char new_pwd[64];
int j;
for(j = 0; j < slash_pos; j++)
new_pwd[j] = pwd[j];
if(j==0)
j++;
new_pwd[j] = '\0';
sprintf(pwd,"%s", new_pwd);
cursor_lastline=0;
cursor_line=0;
readSDcard(disp,pwd);
if(cd_behaviour==1){
cursor_history_pos--;
cursor=cursor_history[cursor_history_pos];
if(cursor_history[cursor_history_pos]>0){
cursor_line=cursor_history[cursor_history_pos]-1;
if(scroll_behaviour==0){
int p = cursor_line/20;
page=p*20;
}
else{
if(cursor_line>19)
cursor_line=19;
}
}
else
cursor_line=0;
}
while( !(disp = display_lock()) );
new_scroll_pos(&cursor, &page, MAX_LIST, count);
clearScreen(disp); //part clear?
display_dir(list, cursor, page, MAX_LIST, count, disp);
display_show(disp);
}//not root
}
else if(input_mapping==2){
while( !(disp = display_lock()) );
graphics_set_color(graphics_make_color(0xFF, 0xFF, 0xFF, 0xFF), graphics_make_color(0x00, 0x00, 0x00, 0x00));
clearScreen(disp);
display_show(disp);
display_dir(list, cursor, page, MAX_LIST, count, disp);
input_mapping=1;
display_show(disp);
}
else if(input_mapping==3){
//chr input screen
/* Lazy switching */
if(set==1)
drawInputAdd(disp, "E"); //P X )
if(set==2)
drawInputAdd(disp, "L");
if(set==3)
drawInputAdd(disp, "S");
if(set==4)
drawInputAdd(disp, "Z");
}
else if(input_mapping==98 || input_mapping==5 || input_mapping==6 || input_mapping==7 || input_mapping==10){
//rom info screen
while( !(disp = display_lock()) );
clearScreen(disp); //part clear?
display_dir(list, cursor, page, MAX_LIST, count, disp);
display_show(disp);
input_mapping=1;
}
else if(input_mapping==8){
//leave toplist
while( !(disp = display_lock()) );
readSDcard(disp,list_pwd_backup);
if(scroll_behaviour==0){
cursor=list_pos_backup[0];
page=list_pos_backup[1];
}
else{
cursor_line=0;
}
clearScreen(disp); //part clear?
display_dir(list, cursor, page, MAX_LIST, count, disp);
display_show(disp);
input_mapping=1;
}
else if(input_mapping==11){
//stop mp3
stop_mp3();
playing=0;
clearScreen(disp); //part clear?
display_dir(list, cursor, page, MAX_LIST, count, disp);
display_show(disp);
input_mapping=1;
}
}//key b
sleep(10);
}
}
//never return
while(1);
return 0;
}