altra64/src/main.c

4658 lines
126 KiB
C
Raw Normal View History

2017-10-06 09:48:52 -04:00
//
// Copyright (c) 2017 The Altra64 project contributors
// Portions (c) 2013 saturnu (Alt64) based on libdragon, Neo64Menu, ED64IO, libn64-hkz, libmikmod
// See LICENSE file in the project root for full license information.
//
2014-06-29 01:10:11 -04:00
#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"
//filesystem
2017-10-14 06:57:45 -04:00
#include "sd.h"
#include "ff.h"
2014-06-29 01:10:11 -04:00
//utils
#include "utils.h"
//config file on sd
#include "ini.h"
#include "strlib.h"
//main header
#include "main.h"
2014-06-29 01:10:11 -04:00
//sound
#include "sound.h"
2014-06-30 03:16:08 -04:00
#include "mp3.h"
2014-06-29 01:10:11 -04:00
// YAML parser
#include <yaml.h>
2014-06-29 01:10:11 -04:00
2021-10-24 17:03:39 -04:00
#include "constants.h"
#include "debug.h"
#include "mem.h"
2017-10-11 12:44:46 -04:00
#include "chksum64.h"
#include "image.h"
#include "rom.h"
#include "memorypak.h"
#include "menu.h"
#include "cic.h"
2014-06-29 01:10:11 -04:00
#ifdef USE_TRUETYPE
#define STB_TRUETYPE_IMPLEMENTATION
#include "stb_truetype.h"
2017-10-11 12:44:46 -04:00
#define MAX_LIST 20
2016-09-16 19:08:00 -04:00
struct glyph
{
2014-06-30 01:37:40 -04:00
int xoff;
int yoff;
int adv;
int lsb;
float scale;
unsigned int color;
unsigned char *alpha;
sprite_t sprite;
2014-06-29 01:10:11 -04:00
};
typedef struct glyph glyph_t;
glyph_t sans[96];
glyph_t serif[96];
#endif
typedef struct
{
uint32_t type;
uint32_t color;
2016-09-16 19:08:00 -04:00
char filename[MAX_FILENAME_LEN + 1];
2014-06-29 01:10:11 -04:00
} direntry_t;
//ini file
typedef struct
{
int version;
2016-09-16 19:08:00 -04:00
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;
2014-06-30 01:37:40 -04:00
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;
2014-06-29 01:10:11 -04:00
2014-06-30 01:37:40 -04:00
} configuration;
2014-06-29 01:10:11 -04:00
2016-09-16 19:08:00 -04:00
volatile u32 *romaddr_ptr = (u32 *)ROM_ADDR;
unsigned int gBootCic = CIC_6102;
2014-06-29 01:10:11 -04:00
static void *bg_buffer;
void *__safe_bg_buffer;
2016-09-16 19:08:00 -04:00
#define __get_buffer(x) __safe_buffer[(x)-1]
2014-06-29 01:10:11 -04:00
extern uint32_t __bitdepth;
extern uint32_t __width;
extern uint32_t __height;
extern void *__safe_buffer[];
2016-09-16 19:08:00 -04:00
int firm_found = 0;
2014-06-29 01:10:11 -04:00
char rom_config[10];
display_context_t lockVideo(int wait);
int select_mode = 0;
2016-09-16 19:08:00 -04:00
int toplist_reload = 1;
int toplist_cursor = 0;
2014-06-29 01:10:11 -04:00
char toplist15[15][256];
2016-09-16 19:08:00 -04:00
int fat_initialized = 0;
2014-06-29 01:10:11 -04:00
int exit_ok = 0;
2016-09-16 19:08:00 -04:00
int boot_cic = 0;
int boot_save = 0;
2017-01-02 16:44:32 -05:00
2016-09-16 19:08:00 -04:00
int cursor_line = 0;
int cursor_lastline = 0;
2014-06-29 01:10:11 -04:00
u16 cursor_history[32];
2016-09-16 19:08:00 -04:00
u16 cursor_history_pos = 0;
2017-01-02 16:44:32 -05:00
2016-09-16 19:08:00 -04:00
u8 empty = 0;
int mp3playing = 0;
2014-06-29 01:10:11 -04:00
FATFS *fs;
2014-06-30 01:37:40 -04:00
//start with filebrowser menu key settings
2016-12-15 17:48:53 -05:00
enum InputMap
{
none,
file_manager,
mempak_menu,
char_input,
rom_loaded,
mpk_format,
mpk_restore,
rom_config_box,
toplist,
mpk_choice,
mpk_quick_backup,
mp3,
abort_screen,
};
enum InputMap input_mapping = file_manager;
2014-06-29 01:10:11 -04:00
//holds the string of the character input screen result
//int text_input_on = 0;
2014-06-29 01:10:11 -04:00
//char input vars
2016-09-16 19:08:00 -04:00
int x, y, position, set;
2014-06-29 01:10:11 -04:00
unsigned char input_text[32];
2016-09-16 19:08:00 -04:00
uint32_t chr_forecolor;
uint32_t chr_backcolor;
2014-06-29 01:10:11 -04:00
//save type still set - save to do after reboot
int save_after_reboot = 0;
2014-06-29 01:10:11 -04:00
//cart id from the rom header
2014-06-29 01:10:11 -04:00
unsigned char cartID[4];
char curr_dirname[64];
char pwd[64];
TCHAR rom_filename[MAX_SUPPORTED_PATH_LEN];
2014-06-29 01:10:11 -04:00
u32 rom_buff[128]; //rom buffer
2016-09-16 19:08:00 -04:00
u8 *rom_buff8; //rom buffer
2014-06-29 01:10:11 -04:00
u8 *firmware;
2016-09-16 19:08:00 -04:00
u8 gbload = 0;
2014-06-29 01:10:11 -04:00
2016-09-16 19:08:00 -04:00
int cheats_on = 0;
int checksum_fix_on = 0;
short int gCheats = 0; /* 0 = off, 1 = select, 2 = all */
2014-06-29 01:10:11 -04:00
short int force_tv = 0;
2016-09-16 19:08:00 -04:00
short int boot_country = 0;
2014-06-29 01:10:11 -04:00
static resolution_t res = RESOLUTION_320x240;
//background sprites
sprite_t *loadPng(u8 *png_filename);
sprite_t *background; //background
sprite_t *splashscreen; //splash screen
2014-06-29 01:10:11 -04:00
//config file theme settings
2016-09-16 19:08:00 -04:00
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 *save_path;
u8 sound_on = 0;
u8 page_display = 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;
2014-06-29 01:10:11 -04:00
2016-12-29 19:31:51 -05:00
//mp3
int buf_size;
char *buf_ptr;
2014-06-29 01:10:11 -04:00
//toplist helper
int list_pos_backup[3];
char list_pwd_backup[256];
char dirz[512] = "rom://";
int count = 0;
int page = 0;
int cursor = 0;
direntry_t *list;
2016-09-16 19:08:00 -04:00
int filesize(FILE *pFile)
2014-06-29 01:10:11 -04:00
{
2016-09-16 19:08:00 -04:00
fseek(pFile, 0, SEEK_END);
int lSize = ftell(pFile);
rewind(pFile);
2014-06-29 01:10:11 -04:00
return lSize;
}
2016-09-16 19:08:00 -04:00
sprite_t *read_sprite(const char *const spritename)
{
FILE *fp = fopen(spritename, "r");
2014-06-29 01:10:11 -04:00
2016-09-16 19:08:00 -04:00
if (fp)
{
sprite_t *sp = malloc(filesize(fp));
fread(sp, 1, filesize(fp), fp);
fclose(fp);
2014-06-29 01:10:11 -04:00
return sp;
}
2016-09-16 19:08:00 -04:00
else
{
2014-06-29 01:10:11 -04:00
return 0;
}
}
2016-09-16 19:08:00 -04:00
void drawSelection(display_context_t disp, int p)
{
int s_x = 23 + (text_offset * 8);
2014-06-29 01:10:11 -04:00
2016-09-16 19:08:00 -04:00
if (scroll_behaviour)
{
if (select_mode)
{
if (cursor_lastline > cursor && cursor_line > 0)
{
2014-06-30 01:37:40 -04:00
cursor_line--;
}
2014-06-29 01:10:11 -04:00
2016-09-16 19:08:00 -04:00
if (cursor_lastline < cursor && cursor_line < 19)
{
2014-06-30 01:37:40 -04:00
cursor_line++;
}
2014-06-29 01:10:11 -04:00
2016-09-16 19:08:00 -04:00
p = cursor_line;
graphics_draw_box_trans(disp, s_x, (((p + 3) * 8) + 24), 272, 8, selection_color); //(p+3) diff
cursor_lastline = cursor;
2014-06-30 01:37:40 -04:00
}
}
2016-09-16 19:08:00 -04:00
else
{ //new page-system
2014-06-30 01:37:40 -04:00
//accept p
2016-09-16 19:08:00 -04:00
graphics_draw_box_trans(disp, s_x, (((p + 3) * 8) + 24), 272, 8, selection_color);
2014-06-30 01:37:40 -04:00
}
}
2014-06-29 01:10:11 -04:00
2016-09-16 19:08:00 -04:00
void drawConfigSelection(display_context_t disp, int l)
{
int s_x = 62 + (text_offset * 8);
2014-06-29 01:10:11 -04:00
2016-09-16 19:08:00 -04:00
l = l + 5;
graphics_draw_box_trans(disp, s_x, (((l + 3) * 8) + 24), 193, 8, 0x00000080); //(p+3) diff
2014-06-29 01:10:11 -04:00
}
2016-09-16 19:08:00 -04:00
void drawToplistSelection(display_context_t disp, int l)
{
int s_x = 30 + (text_offset * 8);
2014-06-29 01:10:11 -04:00
2016-09-16 19:08:00 -04:00
l = l + 2;
graphics_draw_box_trans(disp, s_x, (((l + 3) * 8) + 24), 256, 8, 0xFFFFFF70); //(p+3) diff
2014-06-29 01:10:11 -04:00
}
2016-09-16 19:08:00 -04:00
void chdir(const char *const dirent)
{
2014-06-29 01:10:11 -04:00
/* Ghetto implementation */
2016-09-16 19:08:00 -04:00
if (strcmp(dirent, "..") == 0)
{
2014-06-29 01:10:11 -04:00
/* Go up one */
2016-09-16 19:08:00 -04:00
int len = strlen(dirz) - 1;
2014-06-29 01:10:11 -04:00
/* Stop going past the min */
2016-09-16 19:08:00 -04:00
if (dirz[len] == '/' && dirz[len - 1] == '/' && dirz[len - 2] == ':')
{
2014-06-30 01:37:40 -04:00
//return if ://
2014-06-29 01:10:11 -04:00
return;
}
2016-09-16 19:08:00 -04:00
if (dirz[len] == '/')
{
2014-06-29 01:10:11 -04:00
dirz[len] = 0;
len--;
}
2016-09-16 19:08:00 -04:00
while (dirz[len] != '/')
{
2014-06-29 01:10:11 -04:00
dirz[len] = 0;
len--;
}
}
2016-09-16 19:08:00 -04:00
else
{
2014-06-29 01:10:11 -04:00
/* Add to end */
2016-09-16 19:08:00 -04:00
strcat(dirz, dirent);
strcat(dirz, "/");
2014-06-29 01:10:11 -04:00
}
}
2016-09-16 19:08:00 -04:00
int compare(const void *a, const void *b)
{
2014-06-29 01:10:11 -04:00
direntry_t *first = (direntry_t *)a;
direntry_t *second = (direntry_t *)b;
2016-09-16 19:08:00 -04:00
if (first->type == DT_DIR && second->type != DT_DIR)
{
2014-06-29 01:10:11 -04:00
/* First should be first */
return -1;
}
2016-09-16 19:08:00 -04:00
if (first->type != DT_DIR && second->type == DT_DIR)
{
2014-06-29 01:10:11 -04:00
/* First should be second */
return 1;
}
return strcmp(first->filename, second->filename);
}
2016-09-16 19:08:00 -04:00
int compare_int(const void *a, const void *b)
{
2014-06-30 01:37:40 -04:00
const int *ia = (const int *)a; // casting pointer types
2014-06-29 01:10:11 -04:00
const int *ib = (const int *)b;
2016-09-16 19:08:00 -04:00
return *ia - *ib;
2014-06-29 01:10:11 -04:00
}
2016-09-16 19:08:00 -04:00
int compare_int_reverse(const void *a, const void *b)
{
2014-06-30 01:37:40 -04:00
const int *ia = (const int *)a; // casting pointer types
2014-06-29 01:10:11 -04:00
const int *ib = (const int *)b;
2016-09-16 19:08:00 -04:00
return *ib - *ia;
2014-06-29 01:10:11 -04:00
}
2016-09-16 19:08:00 -04:00
void new_scroll_pos(int *cursor, int *page, int max, int count)
{
2014-06-29 01:10:11 -04:00
/* Make sure windows too small can be calculated right */
2016-09-16 19:08:00 -04:00
if (max > count)
{
2014-06-30 01:37:40 -04:00
max = count;
}
2014-06-29 01:10:11 -04:00
/* Bounds checking */
2016-09-16 19:08:00 -04:00
if (*cursor >= count)
{
*cursor = count - 1;
2014-06-29 01:10:11 -04:00
}
2016-09-16 19:08:00 -04:00
if (*cursor < 0)
{
2014-06-29 01:10:11 -04:00
*cursor = 0;
}
/* Scrolled up? */
2016-09-16 19:08:00 -04:00
if (*cursor < *page)
{
2014-06-29 01:10:11 -04:00
*page = *cursor;
return;
}
/* Scrolled down/ */
2016-09-16 19:08:00 -04:00
if (*cursor >= (*page + max))
{
2014-06-29 01:10:11 -04:00
*page = (*cursor - max) + 1;
return;
}
/* Nothing here, should be good! */
}
2016-09-16 19:08:00 -04:00
void display_dir(direntry_t *list, int cursor, int page, int max, int count, display_context_t disp)
{
2014-06-30 01:37:40 -04:00
//system color
2016-09-16 19:08:00 -04:00
uint32_t forecolor = 0;
uint32_t forecolor_menu = 0;
uint32_t backcolor;
backcolor = graphics_make_color(0x00, 0x00, 0x00, 0x00); //bg
2014-06-30 01:37:40 -04:00
forecolor_menu = graphics_make_color(0xFF, 0xFF, 0xFF, 0xFF); //fg
2016-09-16 19:08:00 -04:00
graphics_set_color(list_font_color, backcolor);
2014-06-30 01:37:40 -04:00
2016-09-16 19:08:00 -04:00
u8 c_pos[MAX_LIST + 1];
int c_pos_counter = 0;
2014-06-30 01:37:40 -04:00
2016-09-16 19:08:00 -04:00
c_pos[c_pos_counter++] = 0;
2014-06-30 01:37:40 -04:00
u8 c_dirname[64];
2016-09-16 19:08:00 -04:00
if (page_display)
{
2014-06-30 01:37:40 -04:00
2016-09-16 19:08:00 -04:00
u8 pi = page / 20;
u8 ci = 0;
2014-06-30 01:37:40 -04:00
2016-09-16 19:08:00 -04:00
if (count % 20 == 0)
ci = (count - 1) / 20;
2014-06-30 01:37:40 -04:00
else
2016-09-16 19:08:00 -04:00
ci = count / 20;
sprintf(c_dirname, "%i/%i SD:/%s", pi + 1, ci + 1, pwd);
2014-06-30 01:37:40 -04:00
}
2016-09-16 19:08:00 -04:00
else
{
2014-06-30 01:37:40 -04:00
sprintf(c_dirname, "SD:/%s", pwd);
}
char sel_str[128];
printText(c_dirname, 3, 4, disp);
2016-09-16 19:08:00 -04:00
int firstrun = 1;
2014-06-29 01:10:11 -04:00
/* Page bounds checking */
2016-09-16 19:08:00 -04:00
if (max > count)
{ //count = directories starting at 1
2014-06-29 01:10:11 -04:00
max = count;
}
/* Cursor bounds checking */
2016-09-16 19:08:00 -04:00
if (cursor >= (page + max))
{
2014-06-29 01:10:11 -04:00
cursor = (page + max) - 1;
}
2016-09-16 19:08:00 -04:00
if (cursor < page)
{
2014-06-29 01:10:11 -04:00
cursor = page;
}
2016-09-16 19:08:00 -04:00
if (max == 0)
{
2014-06-29 01:10:11 -04:00
printText("dir empty...", 3, 6, disp);
sprintf(sel_str, "dir empty...");
2016-09-16 19:08:00 -04:00
empty = 1;
2014-06-30 01:37:40 -04:00
}
2016-09-16 19:08:00 -04:00
else
{
empty = 0;
2014-06-30 01:37:40 -04:00
}
2014-06-29 01:10:11 -04:00
2014-06-30 01:37:40 -04:00
//last page anti ghosting entries
2016-09-16 19:08:00 -04:00
if (page == (count / 20) * 20)
max = count % 20;
2014-06-30 01:37:40 -04:00
2016-09-16 19:08:00 -04:00
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);
2014-06-29 01:10:11 -04:00
2016-09-16 19:08:00 -04:00
tmpdir[CONSOLE_WIDTH - 5] = 0;
2014-06-29 01:10:11 -04:00
2014-06-30 01:37:40 -04:00
char *dir_str;
2016-09-16 19:08:00 -04:00
dir_str = malloc(slen(tmpdir) + 3);
2014-06-29 01:10:11 -04:00
2016-09-16 19:08:00 -04:00
if (i == cursor)
{
2014-06-30 01:37:40 -04:00
sprintf(dir_str, " [%s]", tmpdir);
sprintf(sel_str, " [%s]", tmpdir);
2016-09-16 19:08:00 -04:00
if (scroll_behaviour)
drawSelection(disp, i);
2014-06-30 01:37:40 -04:00
2016-09-16 19:08:00 -04:00
c_pos[c_pos_counter++] = 1;
2014-06-30 01:37:40 -04:00
}
2016-09-16 19:08:00 -04:00
else
{
2014-06-30 01:37:40 -04:00
sprintf(dir_str, "[%s]", tmpdir);
2016-09-16 19:08:00 -04:00
c_pos[c_pos_counter++] = 0;
2014-06-30 01:37:40 -04:00
}
2016-09-16 19:08:00 -04:00
graphics_set_color(list_dir_font_color, backcolor);
if (firstrun)
{
2014-06-30 01:37:40 -04:00
printText(dir_str, 3, 6, disp);
2016-09-16 19:08:00 -04:00
firstrun = 0;
2014-06-30 01:37:40 -04:00
}
2016-09-16 19:08:00 -04:00
else
{
2014-06-30 01:37:40 -04:00
printText(dir_str, 3, -1, disp);
}
free(dir_str);
2014-06-29 01:10:11 -04:00
}
2016-09-16 19:08:00 -04:00
else
{ //if(list[i].type == DT_REG)
int fcolor = list[i].color;
2014-06-30 01:37:40 -04:00
2016-09-16 19:08:00 -04:00
if (fcolor != 0)
{
switch (fcolor)
{
case 1:
forecolor = graphics_make_color(0xFF, 0xFF, 0xFF, 0xFF); //common (white)
2014-06-30 01:37:40 -04:00
break;
2016-09-16 19:08:00 -04:00
case 2:
forecolor = graphics_make_color(0x00, 0xFF, 0x00, 0xCF); //uncommon (green)
2014-06-30 01:37:40 -04:00
break;
2016-09-16 19:08:00 -04:00
case 3:
forecolor = graphics_make_color(0x1E, 0x90, 0xFF, 0xFF); //rare (blue)
2014-06-30 01:37:40 -04:00
break;
2016-09-16 19:08:00 -04:00
case 4:
forecolor = graphics_make_color(0x9B, 0x30, 0xFF, 0xFF); //epic (purple)
2014-06-30 01:37:40 -04:00
break;
2016-09-16 19:08:00 -04:00
case 5:
forecolor = graphics_make_color(0xFF, 0xA5, 0x00, 0xFF); //legendary (orange)
2014-06-30 01:37:40 -04:00
break;
default:
break;
}
}
else
forecolor = list_font_color;
2016-09-16 19:08:00 -04:00
char tmpdir[(CONSOLE_WIDTH - 3) + 1];
strncpy(tmpdir, list[i].filename, CONSOLE_WIDTH - 3);
tmpdir[CONSOLE_WIDTH - 3] = 0;
2014-06-29 01:10:11 -04:00
char *dir_str;
2016-09-16 19:08:00 -04:00
dir_str = malloc(slen(tmpdir) + 1);
2014-06-29 01:10:11 -04:00
2016-09-16 19:08:00 -04:00
if (i == cursor)
{
2014-06-30 01:37:40 -04:00
sprintf(dir_str, " %s", tmpdir);
sprintf(sel_str, " %s", tmpdir);
2016-09-16 19:08:00 -04:00
if (scroll_behaviour)
drawSelection(disp, i);
2014-06-30 01:37:40 -04:00
2016-09-16 19:08:00 -04:00
c_pos[c_pos_counter++] = 1;
2014-06-30 01:37:40 -04:00
}
2016-09-16 19:08:00 -04:00
else
{
2014-06-30 01:37:40 -04:00
sprintf(dir_str, "%s", tmpdir);
2016-09-16 19:08:00 -04:00
c_pos[c_pos_counter++] = 0;
2014-06-30 01:37:40 -04:00
}
graphics_set_color(list_font_color, backcolor);
2016-09-16 19:08:00 -04:00
if (firstrun)
{
if (enable_colored_list)
2014-06-30 01:37:40 -04:00
graphics_set_color(forecolor, backcolor);
printText(dir_str, 3, 6, disp); //3,6
2016-09-16 19:08:00 -04:00
firstrun = 0;
2014-06-30 01:37:40 -04:00
}
2016-09-16 19:08:00 -04:00
else
{
if (enable_colored_list)
2014-06-30 01:37:40 -04:00
graphics_set_color(forecolor, backcolor);
printText(dir_str, 3, -1, disp); //3,1
}
free(dir_str);
2014-06-29 01:10:11 -04:00
}
}
//for page-wise scrolling
2016-09-16 19:08:00 -04:00
if (scroll_behaviour == 0)
{
int c = 0;
for (c = 0; c < max + 1; c++)
{
if (c_pos[c] == 1)
{
drawSelection(disp, c - 1);
2014-06-30 01:37:40 -04:00
//todo: set selection color
graphics_set_color(selection_font_color, backcolor);
2016-09-16 19:08:00 -04:00
printText(sel_str, 3, 6 + c - 1, disp);
2014-06-30 01:37:40 -04:00
graphics_set_color(forecolor, backcolor);
}
}
}
graphics_set_color(forecolor_menu, backcolor);
2014-06-29 01:10:11 -04:00
}
//background sprite
2016-09-16 19:08:00 -04:00
void drawBg(display_context_t disp)
{
graphics_draw_sprite(disp, 0, 0, background);
2014-06-29 01:10:11 -04:00
}
2016-09-16 19:08:00 -04:00
void drawBox(short x, short y, short width, short height, display_context_t disp)
{
x = x + (text_offset * 8);
2014-06-30 01:37:40 -04:00
/*
* |Y
* | x0/y0
* |
* |
* | x1/y1
* |_______________X
*
*/
2016-09-16 19:08:00 -04:00
// 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
2014-06-29 01:10:11 -04:00
}
2016-09-16 19:08:00 -04:00
void drawBoxNumber(display_context_t disp, int box)
{
2014-06-30 01:37:40 -04:00
int old_color = box_color;
//backup color
2016-09-16 19:08:00 -04:00
switch (box)
{
case 1:
drawBox(20, 24, 277, 193, disp);
break; //filebrowser
case 2:
drawBox(60, 56, 200, 128, disp);
break; //info screen
2014-06-30 01:37:40 -04:00
case 3:
2016-09-16 19:08:00 -04:00
box_color = graphics_make_color(0x00, 0x00, 0x60, 0xC9);
2014-06-30 01:37:40 -04:00
drawBox(79, 29, 161, 180, disp);
break; //cover
case 4:
2016-09-16 19:08:00 -04:00
box_color = graphics_make_color(0x30, 0x00, 0x00, 0xA3);
2014-06-30 01:37:40 -04:00
drawBox(79, 29, 161, 180, disp);
break; //mempak content
case 5:
2016-09-16 19:08:00 -04:00
box_color = graphics_make_color(0x60, 0x00, 0x00, 0xD3);
drawBox(60, 64, 197, 114, disp); //red confirm screen
break; //mempak content
2014-06-30 01:37:40 -04:00
case 6:
2016-09-16 19:08:00 -04:00
box_color = graphics_make_color(0x60, 0x60, 0x00, 0xC3);
drawBox(60, 64, 197, 125, disp); //yellow screen
break; //rom config box
2014-06-30 01:37:40 -04:00
case 7:
2016-09-16 19:08:00 -04:00
box_color = graphics_make_color(0x00, 0x00, 0x60, 0xC3);
drawBox(60, 105, 197, 20, disp); //blue info screen
break; //info screen
2014-06-30 01:37:40 -04:00
case 8:
2016-09-16 19:08:00 -04:00
box_color = graphics_make_color(0x60, 0x00, 0x00, 0xD3);
drawBox(60, 105, 197, 20, disp); //red error screen
break; //info screen
2014-06-30 01:37:40 -04:00
case 9:
2016-09-16 19:08:00 -04:00
box_color = graphics_make_color(0x00, 0x00, 0x00, 0xB6);
2014-06-30 01:37:40 -04:00
drawBox(28, 49, 260, 150, disp);
break; //yellow toplist
case 10:
2016-09-16 19:08:00 -04:00
box_color = graphics_make_color(0x00, 0x60, 0x00, 0xC3);
drawBox(60, 105, 197, 20, disp); //green info screen
break; //info screen
2014-06-30 01:37:40 -04:00
case 11:
2016-09-16 19:08:00 -04:00
box_color = graphics_make_color(0x00, 0x60, 0x00, 0xC3);
2014-06-30 01:37:40 -04:00
drawBox(28, 105, 260, 30, disp);
break; //green full filename
default:
break;
}
//restore color
2016-09-16 19:08:00 -04:00
box_color = old_color;
2014-06-29 01:10:11 -04:00
}
//is setting the config file vars into the pconfig-structure
2016-09-16 19:08:00 -04:00
static int configHandler(void *user, const char *section, const char *name, const char *value)
{
configuration *pconfig = (configuration *)user;
2014-06-29 01:10:11 -04:00
2016-09-16 19:08:00 -04:00
#define MATCH(s, n) strcmp(section, s) == 0 && strcmp(name, n) == 0
2014-06-30 01:37:40 -04:00
2016-09-16 19:08:00 -04:00
if (MATCH("ed64", "border_color_1"))
{
2014-06-29 01:10:11 -04:00
pconfig->border_color_1 = strdup(value);
}
2016-09-16 19:08:00 -04:00
else if (MATCH("ed64", "border_color_2"))
{
2014-06-29 01:10:11 -04:00
pconfig->border_color_2 = strdup(value);
}
2016-09-16 19:08:00 -04:00
else if (MATCH("ed64", "box_color"))
{
2014-06-29 01:10:11 -04:00
pconfig->box_color = strdup(value);
}
2016-09-16 19:08:00 -04:00
else if (MATCH("ed64", "selection_color"))
{
2014-06-29 01:10:11 -04:00
pconfig->selection_color = strdup(value);
}
2016-09-16 19:08:00 -04:00
else if (MATCH("ed64", "list_font_color"))
{
2014-06-29 01:10:11 -04:00
pconfig->list_font_color = strdup(value);
}
2016-09-16 19:08:00 -04:00
else if (MATCH("ed64", "list_dir_font_color"))
{
2014-06-29 01:10:11 -04:00
pconfig->list_dir_font_color = strdup(value);
}
2016-09-16 19:08:00 -04:00
else if (MATCH("ed64", "selection_font_color"))
{
2014-06-29 01:10:11 -04:00
pconfig->selection_font_color = strdup(value);
}
2016-09-16 19:08:00 -04:00
else if (MATCH("ed64", "mempak_path"))
{
2014-06-29 01:10:11 -04:00
pconfig->mempak_path = strdup(value);
}
2016-09-16 19:08:00 -04:00
else if (MATCH("ed64", "save_path"))
{
2014-06-29 01:10:11 -04:00
pconfig->save_path = strdup(value);
}
2016-09-16 19:08:00 -04:00
else if (MATCH("ed64", "sound_on"))
{
2014-06-29 01:10:11 -04:00
pconfig->sound_on = atoi(value);
}
2016-09-16 19:08:00 -04:00
else if (MATCH("ed64", "page_display"))
{
2014-06-29 01:10:11 -04:00
pconfig->page_display = atoi(value);
}
2016-09-16 19:08:00 -04:00
else if (MATCH("ed64", "tv_mode"))
{
2014-06-29 01:10:11 -04:00
pconfig->tv_mode = atoi(value);
}
2016-09-16 19:08:00 -04:00
else if (MATCH("ed64", "quick_boot"))
{
2014-06-29 01:10:11 -04:00
pconfig->quick_boot = atoi(value);
}
2016-09-16 19:08:00 -04:00
else if (MATCH("ed64", "enable_colored_list"))
{
2014-06-29 01:10:11 -04:00
pconfig->enable_colored_list = atoi(value);
}
2016-09-16 19:08:00 -04:00
else if (MATCH("ed64", "ext_type"))
{
2014-06-29 01:10:11 -04:00
pconfig->ext_type = atoi(value);
}
2016-09-16 19:08:00 -04:00
else if (MATCH("ed64", "cd_behaviour"))
{
2014-06-29 01:10:11 -04:00
pconfig->cd_behaviour = atoi(value);
}
2016-09-16 19:08:00 -04:00
else if (MATCH("ed64", "scroll_behaviour"))
{
2014-06-29 01:10:11 -04:00
pconfig->scroll_behaviour = atoi(value);
2014-06-30 01:37:40 -04:00
}
2016-09-16 19:08:00 -04:00
else if (MATCH("ed64", "text_offset"))
{
2014-06-29 01:10:11 -04:00
pconfig->text_offset = atoi(value);
}
2016-09-16 19:08:00 -04:00
else if (MATCH("ed64", "sd_speed"))
{
2014-06-29 01:10:11 -04:00
pconfig->sd_speed = atoi(value);
}
2016-09-16 19:08:00 -04:00
else if (MATCH("ed64", "hide_sysfolder"))
{
2014-06-29 01:10:11 -04:00
pconfig->hide_sysfolder = atoi(value);
}
2016-09-16 19:08:00 -04:00
else if (MATCH("ed64", "background_image"))
{
2014-06-29 01:10:11 -04:00
pconfig->background_image = strdup(value);
2014-06-30 01:37:40 -04:00
}
2016-09-16 19:08:00 -04:00
else if (MATCH("user", "name"))
{
2014-06-29 01:10:11 -04:00
pconfig->name = strdup(value);
2014-06-30 01:37:40 -04:00
}
2016-09-16 19:08:00 -04:00
else
{
return 0; /* unknown section/name, error */
2014-06-29 01:10:11 -04:00
}
2014-06-30 01:37:40 -04:00
2014-06-29 01:10:11 -04:00
return 1;
}
void updateFirmware(char *filename)
{ //check that firmware exists on the disk? mainly because it has to be ripped from the official image and may not have been.
FRESULT fr;
FILINFO fno;
fr = f_stat(filename, &fno); //TODO: given this is on the ROM (not SD) does it even work??????
if (fr == FR_OK)
{
int fpf = dfs_open(filename);
firmware = malloc(dfs_size(fpf));
dfs_read(firmware, 1, dfs_size(fpf), fpf);
dfs_close(fpf);
bi_load_firmware(firmware);
}
}
2014-06-29 01:10:11 -04:00
//everdrive init functions
2016-09-16 19:08:00 -04:00
void configure()
{
2014-06-29 01:10:11 -04:00
u16 msg = 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); //TODO: this should be displayed somewhere...
2014-06-29 01:10:11 -04:00
evd_setCfgBit(ED_CFG_SDRAM_ON, 1);
firm = evd_getFirmVersion();
2014-06-29 01:10:11 -04:00
2016-09-16 19:08:00 -04:00
if (firm >= 0x0200)
{
2014-06-29 01:10:11 -04:00
sleep(1);
evd_setCfgBit(ED_CFG_SDRAM_ON, 0);
sleep(1);
msg = evd_readReg(REG_MAX_MSG);
2016-09-16 19:08:00 -04:00
if (!(msg & (1 << 14)))
{
2014-06-29 01:10:11 -04:00
msg |= 1 << 14;
evd_writeReg(REG_MAX_MSG, msg);
switch(firm) //need to take into account different default firmware versions for each ED64 version
{
case 0x0214:
updateFirmware("/firmware/firmware_v2.bin");
break;
case 0x0250:
updateFirmware("/firmware/firmware_v2_5.bin");
break;
case 0x0300:
updateFirmware("/firmware/firmware_v3.bin");
break;
default:
break;
2016-08-31 19:09:17 -04:00
}
2014-06-29 01:10:11 -04:00
sleep(1);
evd_init();
}
sleep(1);
evd_setCfgBit(ED_CFG_SDRAM_ON, 1);
}
if (streql("ED64 SD boot", buff, 12) && firm >= 0x0116) //TODO: can this be moved before the firmware is loaded?
2016-09-16 19:08:00 -04:00
{
2017-10-14 06:57:45 -04:00
sdSetInterface(DISK_IFACE_SD);
2016-09-16 19:08:00 -04:00
}
else
{
2017-10-14 06:57:45 -04:00
sdSetInterface(DISK_IFACE_SPI);
2014-06-29 01:10:11 -04:00
}
memSpiSetDma(0);
}
//rewrites the background and the box to clear the screen
2016-09-16 19:08:00 -04:00
void clearScreen(display_context_t disp)
{
drawBg(disp); //background
drawBoxNumber(disp, 1); //filebrowser box
2014-06-29 01:10:11 -04:00
}
2016-09-16 19:08:00 -04:00
void romInfoScreen(display_context_t disp, u8 *buff, int silent)
{
TCHAR filename[MAX_SUPPORTED_PATH_LEN];
2016-09-16 19:08:00 -04:00
sprintf(filename, "%s", buff);
2016-09-16 19:08:00 -04:00
int swapped = 0;
2014-06-29 01:10:11 -04:00
FRESULT result;
int fsize = 512; //rom-headersize 4096 but the bootcode is not needed
unsigned char headerdata[fsize]; //1*512
2014-06-29 01:10:11 -04:00
FIL file;
UINT bytesread;
result = f_open(&file, filename, FA_READ);
2014-06-29 01:10:11 -04:00
if (result == FR_OK)
{
int fsizeMB = f_size(&file) / 1048576; //Bytes in a MB
2014-06-29 01:10:11 -04:00
result =
f_read (
&file, /* [IN] File object */
2017-10-23 12:46:05 -04:00
headerdata, /* [OUT] Buffer to store read data */
fsize, /* [IN] Number of bytes to read */
&bytesread /* [OUT] Number of bytes read */
);
2014-06-29 01:10:11 -04:00
2017-10-23 12:46:05 -04:00
f_close(&file);
2014-06-29 01:10:11 -04:00
int sw_type = is_valid_rom(headerdata);
2014-06-29 01:10:11 -04:00
if (sw_type != 0)
{
swapped = 1;
swap_header(headerdata, 512);
}
2014-06-29 01:10:11 -04:00
if (silent != 1)
{
//char 32-51 name
unsigned char rom_name[32];
2014-06-29 01:10:11 -04:00
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]);
}
2014-06-29 01:10:11 -04:00
//rom name
sprintf(rom_name, "%s", trim(rom_name));
printText(rom_name, 11, 19, disp);
2014-06-29 01:10:11 -04:00
//rom size
sprintf(rom_name, "Size: %iMB", fsizeMB);
printText(rom_name, 11, -1, disp);
2014-06-29 01:10:11 -04:00
//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]);
printText(cartID_str, 11, -1, disp);
}
2014-06-29 01:10:11 -04:00
int cic, save;
2014-06-29 01:10:11 -04:00
cic = get_cic(&headerdata[0x40]);
2014-06-29 01:10:11 -04:00
unsigned char cartID_short[4];
sprintf(cartID_short, "%c%c\0", headerdata[0x3C], headerdata[0x3D]);
2014-06-29 01:10:11 -04:00
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));
printText(save_type_str, 11, -1, disp);
2014-06-29 01:10:11 -04:00
unsigned char cic_type_str[12];
2014-06-29 01:10:11 -04:00
switch (cic)
{
case 4:
sprintf(cic_type_str, "CIC: CIC-5101", cic);
break;
case 7:
sprintf(cic_type_str, "CIC: CIC-5167", cic);
break;
default:
sprintf(cic_type_str, "CIC: CIC-610%i", cic);
break;
}
2014-06-30 01:37:40 -04:00
printText(cic_type_str, 11, -1, disp);
}
//thanks for the db :>
//cart was found, use CIC and SaveRAM type
}
2016-09-16 19:08:00 -04:00
if (silent != 1)
{
char box_path[32];
2014-06-30 01:37:40 -04:00
sprite_t *n64cover;
2014-06-29 01:10:11 -04:00
sprintf(box_path, "/"ED64_FIRMWARE_PATH"/boxart/lowres/%c%c.png", headerdata[0x3C], headerdata[0x3D]);
2014-06-29 01:10:11 -04:00
FILINFO fnoba;
result = f_stat (box_path, &fnoba);
2014-06-29 01:10:11 -04:00
if (result != FR_OK)
{
//not found
sprintf(box_path, "/"ED64_FIRMWARE_PATH"/boxart/lowres/00.png");
}
2014-06-29 01:10:11 -04:00
n64cover = loadPng(box_path);
graphics_draw_sprite(disp, 81, 32, n64cover);
display_show(disp);
}
else
2016-09-16 19:08:00 -04:00
{
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
2014-06-30 01:37:40 -04:00
}
}
}
2014-06-29 01:10:11 -04:00
2016-09-16 19:08:00 -04:00
sprite_t *loadPng(u8 *png_filename)
{
TCHAR *filename = (TCHAR *)malloc(slen(png_filename));
sprintf(filename, "%s", png_filename);
2014-06-29 01:10:11 -04:00
FRESULT result;
FIL file;
UINT bytesread;
result = f_open(&file, filename, FA_READ);
2014-06-29 01:10:11 -04:00
if (result == FR_OK)
{
int fsize = f_size(&file);
u8 png_rawdata[fsize];
2014-06-29 01:10:11 -04:00
result =
f_read (
&file, /* [IN] File object */
2017-10-23 12:46:05 -04:00
png_rawdata, /* [OUT] Buffer to store read data */
fsize, /* [IN] Number of bytes to read */
&bytesread /* [OUT] Number of bytes read */
);
2014-06-29 01:10:11 -04:00
2017-10-23 12:46:05 -04:00
f_close(&file);
2014-06-29 01:10:11 -04:00
free(filename);
return loadImage32(png_rawdata, fsize);
}
2014-06-29 01:10:11 -04:00
return 0;
2014-06-29 01:10:11 -04:00
}
2021-05-05 00:57:27 -04:00
void loadgbrom(display_context_t disp, TCHAR *rom_path)
2016-09-16 19:08:00 -04:00
{
2021-05-05 06:08:03 -04:00
drawShortInfoBox(disp, " loading please wait", 0);
2021-05-05 00:57:27 -04:00
FRESULT result;
FIL emufile;
UINT emubytesread;
result = f_open(&emufile, "/"ED64_FIRMWARE_PATH"/gb.v64", FA_READ);
2014-06-29 01:10:11 -04:00
2021-05-05 00:57:27 -04:00
if (result == FR_OK)
2016-09-16 19:08:00 -04:00
{
2021-05-05 00:57:27 -04:00
int emufsize = f_size(&emufile);
//load gb emulator
result =
f_read (
&emufile, /* [IN] File object */
(void *)0xb0000000, /* [OUT] Buffer to store read data */
emufsize, /* [IN] Number of bytes to read */
&emubytesread /* [OUT] Number of bytes read */
);
2014-06-29 01:10:11 -04:00
2021-05-05 00:57:27 -04:00
f_close(&emufile);
2014-06-29 01:10:11 -04:00
2021-05-05 00:57:27 -04:00
//load gb rom
FIL romfile;
UINT rombytesread;
result = f_open(&romfile, rom_path, FA_READ);
2017-10-18 07:03:09 -04:00
if (result == FR_OK)
{
2021-05-05 00:57:27 -04:00
int romfsize = f_size(&romfile);
2017-10-18 07:03:09 -04:00
result =
2021-05-05 00:57:27 -04:00
f_read (
&romfile, /* [IN] File object */
(void *)0xb0200000, /* [OUT] Buffer to store read data */
romfsize, /* [IN] Number of bytes to read */
&rombytesread /* [OUT] Number of bytes read */
);
2017-10-18 07:03:09 -04:00
2021-05-05 00:57:27 -04:00
f_close(&romfile);
2014-06-29 01:10:11 -04:00
2021-05-05 00:57:27 -04:00
boot_cic = CIC_6102;
boot_save = 5; //flash
force_tv = 0; //no force
cheats_on = 0; //cheats off
checksum_fix_on = 0;
2017-10-18 07:03:09 -04:00
2021-05-05 00:57:27 -04:00
bootRom(disp, 1);
2017-10-18 07:03:09 -04:00
}
2014-06-30 01:37:40 -04:00
}
}
void loadmsx2rom(display_context_t disp, TCHAR *rom_path)
2016-09-16 19:08:00 -04:00
{
2014-06-29 01:10:11 -04:00
2017-10-14 19:21:31 -04:00
FRESULT romresult;
FIL romfile;
UINT rombytesread;
romresult = f_open(&romfile, rom_path, FA_READ);
2014-06-29 01:10:11 -04:00
2017-10-14 19:21:31 -04:00
if (romresult == FR_OK)
2016-09-16 19:08:00 -04:00
{
2017-10-14 19:21:31 -04:00
int romfsize = f_size(&romfile);
2014-06-29 01:10:11 -04:00
2017-10-14 19:21:31 -04:00
//max 128KB rom
if (romfsize > 128 * 1024)
{
//error
2014-06-29 01:10:11 -04:00
2017-10-14 19:21:31 -04:00
drawShortInfoBox(disp, " error: rom > 128KB", 1);
input_mapping = abort_screen;
2014-06-29 01:10:11 -04:00
2017-10-14 19:21:31 -04:00
return;
}
else
{
drawShortInfoBox(disp, " loading please wait", 0);
2014-06-29 01:10:11 -04:00
2017-10-14 19:21:31 -04:00
FRESULT result;
FIL file;
UINT bytesread;
result = f_open(&file, "/"ED64_FIRMWARE_PATH"/ultraMSX2.z64", FA_READ);
2017-10-14 19:21:31 -04:00
if (result == FR_OK)
{
int fsize = f_size(&file);
result =
f_read (
&file, /* [IN] File object */
2017-10-23 12:46:05 -04:00
(void *)0xb0000000, /* [OUT] Buffer to store read data */
2017-10-14 19:21:31 -04:00
fsize, /* [IN] Number of bytes to read */
&bytesread /* [OUT] Number of bytes read */
);
2017-10-23 12:46:05 -04:00
f_close(&file);
2017-10-14 19:21:31 -04:00
romresult =
f_read (
&romfile, /* [IN] File object */
2017-10-23 12:46:05 -04:00
(void *)0xb0000000 + 0x2df48, /* [OUT] Buffer to store read data */ //TODO: why is the offset this particular number
2017-10-14 19:21:31 -04:00
romfsize, /* [IN] Number of bytes to read */
&rombytesread /* [OUT] Number of bytes read */
);
2017-10-23 12:46:05 -04:00
f_close(&romfile);
2017-10-14 19:21:31 -04:00
boot_cic = 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);
}
}
2014-06-30 01:37:40 -04:00
}
}
2014-06-29 01:10:11 -04:00
void loadggrom(display_context_t disp, TCHAR *rom_path) //TODO: this could be merged with MSX
2016-09-16 19:08:00 -04:00
{
2014-06-29 01:10:11 -04:00
2017-10-14 19:21:31 -04:00
FRESULT romresult;
FIL romfile;
UINT rombytesread;
romresult = f_open(&romfile, rom_path, FA_READ);
2014-06-29 01:10:11 -04:00
2017-10-14 19:21:31 -04:00
if (romresult == FR_OK)
2016-09-16 19:08:00 -04:00
{
2017-10-14 19:21:31 -04:00
int romfsize = f_size(&romfile);
2014-06-29 01:10:11 -04:00
2017-10-14 19:21:31 -04:00
//max 512KB rom
if (romfsize > 512 * 1024)
{
//error
2014-06-29 01:10:11 -04:00
2017-10-14 19:21:31 -04:00
drawShortInfoBox(disp, " error: rom > 512KB", 1);
input_mapping = abort_screen;
2014-06-29 01:10:11 -04:00
2017-10-14 19:21:31 -04:00
return;
}
else
{
drawShortInfoBox(disp, " loading please wait", 0);
2014-06-29 01:10:11 -04:00
2017-10-14 19:21:31 -04:00
FRESULT result;
FIL file;
UINT bytesread;
result = f_open(&file, "/"ED64_FIRMWARE_PATH"/UltraSMS.z64", FA_READ);
2017-10-14 19:21:31 -04:00
if (result == FR_OK)
{
int fsize = f_size(&file);
result =
f_read (
&file, /* [IN] File object */
2017-10-23 12:46:05 -04:00
(void *)0xb0000000, /* [OUT] Buffer to store read data */
2017-10-14 19:21:31 -04:00
fsize, /* [IN] Number of bytes to read */
&bytesread /* [OUT] Number of bytes read */
);
2017-10-23 12:46:05 -04:00
f_close(&file);
2017-10-14 19:21:31 -04:00
romresult =
f_read (
&romfile, /* [IN] File object */
2017-10-23 12:46:05 -04:00
(void *)0xb0000000 + 0x1b410, /* [OUT] Buffer to store read data */ //TODO: why is the offset this particular number
2017-10-14 19:21:31 -04:00
romfsize, /* [IN] Number of bytes to read */
&rombytesread /* [OUT] Number of bytes read */
);
2017-10-23 12:46:05 -04:00
f_close(&romfile);
2017-10-14 19:21:31 -04:00
boot_cic = 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);
}
}
}
2014-06-29 01:10:11 -04:00
}
void loadnesrom(display_context_t disp, TCHAR *rom_path)
2016-09-16 19:08:00 -04:00
{
FRESULT result;
FIL emufile;
UINT emubytesread;
result = f_open(&emufile, "/"ED64_FIRMWARE_PATH"/neon64bu.rom", FA_READ);
2014-06-29 01:10:11 -04:00
if (result == FR_OK)
2016-09-16 19:08:00 -04:00
{
int emufsize = f_size(&emufile);
2014-06-30 01:37:40 -04:00
//load nes emulator
result =
f_read (
&emufile, /* [IN] File object */
(void *)0xb0000000, /* [OUT] Buffer to store read data */
emufsize, /* [IN] Number of bytes to read */
&emubytesread /* [OUT] Number of bytes read */
);
2014-06-29 01:10:11 -04:00
2017-10-23 12:46:05 -04:00
f_close(&emufile);
2014-06-29 01:10:11 -04:00
//load nes rom
FIL romfile;
UINT rombytesread;
result = f_open(&romfile, rom_path, FA_READ);
if (result == FR_OK)
{
int romfsize = f_size(&romfile);
result =
f_read (
&romfile, /* [IN] File object */
(void *)0xb0200000, /* [OUT] Buffer to store read data */
romfsize, /* [IN] Number of bytes to read */
&rombytesread /* [OUT] Number of bytes read */
);
2017-10-23 12:46:05 -04:00
f_close(&romfile);
2014-06-29 01:10:11 -04:00
boot_cic = CIC_6102;
boot_save = 2; //SRAM
force_tv = 0; //no force
cheats_on = 0; //cheats off
checksum_fix_on = 0;
bootRom(disp, 1);
}
2014-06-30 01:37:40 -04:00
}
}
2014-06-29 01:10:11 -04:00
2014-06-30 01:37:40 -04:00
//load a z64/v64/n64 rom to the sdram
2016-09-16 19:08:00 -04:00
void loadrom(display_context_t disp, u8 *buff, int fast)
{
2014-06-30 01:37:40 -04:00
clearScreen(disp);
display_show(disp);
2014-06-29 01:10:11 -04:00
printText("Loading ROM, Please wait:", 3, 4, disp);
2014-06-29 01:10:11 -04:00
TCHAR filename[MAX_SUPPORTED_PATH_LEN];
2016-09-16 19:08:00 -04:00
sprintf(filename, "%s", buff);
FRESULT result;
FIL file;
UINT bytesread = 0;
result = f_open(&file, filename, FA_READ);
2014-06-29 01:10:11 -04:00
if (result == FR_OK)
2016-09-16 19:08:00 -04:00
{
int swapped = 0;
int headerfsize = 512; //rom-headersize 4096 but the bootcode is not needed
unsigned char headerdata[headerfsize]; //1*512
int fsize = f_size(&file);
int fsizeMB = fsize /1048576; //Bytes in a MB
2014-06-29 01:10:11 -04:00
result =
f_read (
&file, /* [IN] File object */
2017-10-23 12:46:05 -04:00
headerdata, /* [OUT] Buffer to store read data */
headerfsize, /* [IN] Number of bytes to read */
&bytesread /* [OUT] Number of bytes read */
);
2014-06-29 01:10:11 -04:00
2017-10-23 12:46:05 -04:00
f_close(&file);
2014-06-29 01:10:11 -04:00
int sw_type = is_valid_rom(headerdata);
2014-06-29 01:10:11 -04:00
if (sw_type != 0)
{
swapped = 1;
swap_header(headerdata, 512);
}
2014-06-29 01:10:11 -04:00
if (fast != 1)
{
//char 32-51 name
unsigned char rom_name[32];
2014-06-29 01:10:11 -04:00
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]);
}
2014-06-29 01:10:11 -04:00
//rom name
sprintf(rom_name, "%s", trim(rom_name));
printText(rom_name, 3, -1, disp);
2014-06-29 01:10:11 -04:00
//rom size
sprintf(rom_name, "Size: %iMB", fsizeMB);
printText(rom_name, 3, -1, disp);
2014-06-29 01:10:11 -04:00
//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]);
printText(cartID_str, 3, -1, disp);
}
2014-06-29 01:10:11 -04:00
int cic, save;
2016-09-16 19:08:00 -04:00
cic = get_cic(&headerdata[0x40]);
2016-09-16 19:08:00 -04:00
unsigned char cartID_short[4];
sprintf(cartID_short, "%c%c\0", headerdata[0x3C], headerdata[0x3D]);
2014-06-29 01:10:11 -04:00
if (get_cic_save(cartID_short, &cic, &save))
{
if (fast != 1)
{
printText("found in db", 3, -1, disp);
unsigned char save_type_str[12];
sprintf(save_type_str, "Save: %s", saveTypeToExtension(save, ext_type));
printText(save_type_str, 3, -1, disp);
2014-06-29 01:10:11 -04:00
unsigned char cic_type_str[12];
2014-06-29 01:10:11 -04:00
switch (cic)
{
case 4:
sprintf(cic_type_str, "CIC: CIC-5101", cic);
break;
case 7:
sprintf(cic_type_str, "CIC: CIC-5167", cic);
break;
default:
sprintf(cic_type_str, "CIC: CIC-610%i", cic);
break;
}
2014-06-29 01:10:11 -04:00
printText(cic_type_str, 3, -1, disp);
}
//thanks for the db :>
//cart was found, use CIC and SaveRAM type
}
2014-06-29 01:10:11 -04:00
//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
2014-06-29 01:10:11 -04:00
if (gbload == 1)
boot_save = 1;
2014-06-29 01:10:11 -04:00
if (swapped == 1)
{
while (evd_isDmaBusy())
;
evd_mmcSetDmaSwap(1);
2014-06-29 01:10:11 -04:00
TRACE(disp, "swapping on");
}
2014-06-29 01:10:11 -04:00
bytesread = 0;
result = f_open(&file, filename, FA_READ);
if (fsizeMB <= 32)
{
result =
f_read (
&file, /* [IN] File object */
(void *)0xb0000000, /* [OUT] Buffer to store read data */
fsize, /* [IN] Number of bytes to read */
&bytesread /* [OUT] Number of bytes read */
);
}
else
{
result =
f_read (
&file, /* [IN] File object */
(void *)0xb0000000, /* [OUT] Buffer to store read data */
32 * 1048576, /* [IN] Number of bytes to read */
&bytesread /* [OUT] Number of bytes read */
);
if(result == FR_OK)
{
result =
f_read (
&file, /* [IN] File object */
(void *)0xb2000000, /* [OUT] Buffer to store read data */
fsize - bytesread, /* [IN] Number of bytes to read */
&bytesread /* [OUT] Number of bytes read */
);
}
}
2014-06-29 01:10:11 -04:00
if(result == FR_OK)
{
printText("Rom loaded", 3, -1, disp);
2014-06-29 01:10:11 -04:00
if (!fast)
{
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);
}
}
else
{
printText("file open error", 3, -1, disp);
}
}
2014-06-30 01:37:40 -04:00
}
2014-06-29 01:10:11 -04:00
2016-09-16 19:08:00 -04:00
int backupSaveData(display_context_t disp)
{
//backup cart-save on sd after reboot
TCHAR config_file_path[MAX_SUPPORTED_PATH_LEN];
sprintf(config_file_path, "/"ED64_FIRMWARE_PATH"/%s/LASTROM.CFG", save_path);
2014-06-29 01:10:11 -04:00
u8 save_format;
u8 cfg_data[2]; //TODO: this should be a strut?
2014-06-29 01:10:11 -04:00
FRESULT result;
FIL file;
UINT bytesread;
result = f_open(&file, config_file_path, FA_READ);
if (result == FR_OK)
{
2017-10-14 17:16:13 -04:00
printText("updating last played game record...", 3, 4, disp);
int fsize = f_size(&file);
result =
f_read (
&file, /* [IN] File object */
&cfg_data, /* [OUT] Buffer to store read data */
2, /* [IN] Number of bytes to read */
&bytesread /* [OUT] Number of bytes read */
);
2014-06-29 01:10:11 -04:00
2017-10-23 12:46:05 -04:00
//split in save type and cart-id
save_format = cfg_data[0];
2014-06-29 01:10:11 -04:00
f_gets(rom_filename, 256, &file);
f_close(&file);
2017-10-23 12:46:05 -04:00
//set savetype to 0 disable for next boot
if (save_format != 0)
{
result = f_open(&file, config_file_path, FA_WRITE | FA_OPEN_EXISTING);
2017-10-23 12:46:05 -04:00
//set savetype to off
cfg_data[0] = 0;
2014-06-29 01:10:11 -04:00
2017-10-23 12:46:05 -04:00
UINT bw;
result = f_write (
&file, /* [IN] Pointer to the file object structure */
&cfg_data, /* [IN] Pointer to the data to be written */
1, /* [IN] Number of bytes to write */
2017-10-23 12:46:05 -04:00
&bw /* [OUT] Pointer to the variable to return number of bytes written */
);
f_close(&file);
2014-06-30 01:37:40 -04:00
2017-10-23 12:46:05 -04:00
TRACE(disp, "Disabling save for subsequent system reboots");
2014-06-30 01:37:40 -04:00
2017-10-23 12:46:05 -04:00
volatile u8 save_config_state = 0;
int cfgreg = evd_readReg(REG_CFG);
2017-10-23 12:46:05 -04:00
save_config_state = evd_readReg(REG_SAV_CFG);
2014-06-29 01:10:11 -04:00
2017-10-23 12:46:05 -04:00
if (save_config_state != 0 || evd_getFirmVersion() >= 0x0300)
{ //save register set or the firmware is V3
if (save_config_state == 0)
{ //we are V3 and have had a hard reboot
evd_writeReg(REG_SAV_CFG, 1); //so we need to tell the save register it still has data.
2016-09-02 18:00:22 -04:00
}
2017-10-23 12:46:05 -04:00
save_after_reboot = 1;
2014-06-30 01:37:40 -04:00
}
2017-10-23 12:46:05 -04:00
else
{
TRACE(disp, "Save not required.");
printText("...ready", 3, -1, disp);
display_show(disp);
2017-10-23 12:46:05 -04:00
return 1;
}
2014-06-30 01:37:40 -04:00
}
2016-09-16 19:08:00 -04:00
}
2017-10-23 12:46:05 -04:00
else
{
TRACE(disp, "No previous ROM loaded!");
printText("...ready", 3, -1, disp);
display_show(disp);
2017-10-23 12:46:05 -04:00
return 0;
}
2014-06-30 01:37:40 -04:00
2016-09-16 19:08:00 -04:00
//reset with save request
if (save_after_reboot)
2016-09-16 19:08:00 -04:00
{
2017-10-14 17:16:13 -04:00
printText("Copying save RAM to SD card...", 3, -1, disp);
2016-09-16 19:08:00 -04:00
if (saveTypeToSd(disp, rom_filename, save_format))
{
printText("Operation completed sucessfully...", 3, -1, disp);
}
else
{
TRACE(disp, "ERROR: the RAM was not successfully saved!");
2014-06-30 01:37:40 -04:00
}
2016-09-16 19:08:00 -04:00
}
else
{
TRACE(disp, "no reset - save request");
2017-10-14 17:16:13 -04:00
printText("...done", 3, -1, disp);
2016-09-16 19:08:00 -04:00
}
display_show(disp);
2014-06-30 01:37:40 -04:00
return 1;
2014-06-29 01:10:11 -04:00
}
2014-06-30 01:37:40 -04:00
//before boot_simulation
2017-10-14 17:16:13 -04:00
//write a cart-save from a file to the fpga/cart
2016-09-16 19:08:00 -04:00
int saveTypeFromSd(display_context_t disp, char *rom_name, int stype)
{
TRACE(disp, rom_filename);
2017-10-14 17:16:13 -04:00
const char* save_type_extension = saveTypeToExtension(stype, ext_type);
TCHAR fname[MAX_SUPPORTED_PATH_LEN] = {0};
int save_count = 0; //TODO: once this crosses 9999 bad infinite-loop type things happen, look into that one day
FRESULT result;
FILINFO fnoba;
printText("Finding latest save slot...", 3, -1, disp);
display_show(disp);
while (true) {
2021-10-23 00:32:33 -04:00
sprintf(fname, "/"ED64_FIRMWARE_PATH"/%s/%s.%04d.%s", save_path, rom_name, save_count, save_type_extension);
result = f_stat (fname, &fnoba);
if (result != FR_OK) {
// we found our first missing save slot, break
break;
}
++save_count;
}
if (save_count > 0) {
// we've went 1 past the end, so back up
2021-10-23 00:32:33 -04:00
sprintf(fname, "Found latest save slot: %04d", --save_count);
printText(fname, 3, -1, disp);
2021-10-23 00:32:33 -04:00
sprintf(fname, "/"ED64_FIRMWARE_PATH"/%s/%s.%04d.%s", save_path, rom_name, save_count, save_type_extension);
} else {
// not even a 0000 was found, so look at the original name before numbering was implemented
printText("No save slot found!", 3, -1, disp);
printText("Looking for non-numbered file...", 3, -1, disp);
sprintf(fname, "/"ED64_FIRMWARE_PATH"/%s/%s.%s", save_path, rom_name, save_type_extension);
}
display_show(disp);
2017-10-14 17:16:13 -04:00
int size = saveTypeToSize(stype); // int byte
2014-06-30 01:37:40 -04:00
uint8_t cartsave_data[size];
2014-06-29 01:10:11 -04:00
2017-10-14 17:16:13 -04:00
FIL file;
UINT bytesread;
result = f_open(&file, fname, FA_READ);
2017-10-14 17:16:13 -04:00
if (result == FR_OK)
2016-09-16 19:08:00 -04:00
{
2017-10-14 17:16:13 -04:00
int fsize = f_size(&file);
2014-06-29 01:10:11 -04:00
2017-10-14 17:16:13 -04:00
result =
f_read (
&file, /* [IN] File object */
2017-10-23 12:46:05 -04:00
cartsave_data, /* [OUT] Buffer to store read data */
2017-10-14 17:16:13 -04:00
size, /* [IN] Number of bytes to read */
&bytesread /* [OUT] Number of bytes read */
);
2014-06-29 01:10:11 -04:00
2017-10-23 12:46:05 -04:00
f_close(&file);
2014-06-30 01:37:40 -04:00
}
2016-09-16 19:08:00 -04:00
else
{
switch(result)
{
case FR_NOT_READY:
printText("not ready error", 11, -1, disp);
break;
case FR_NO_FILE:
printText("no file error", 11, -1, disp);
break;
case FR_NO_PATH:
printText("no path error", 11, -1, disp);
break;
case FR_INVALID_NAME:
printText("invalid name error", 11, -1, disp);
break;
case FR_DENIED:
printText("denied error", 11, -1, disp);
break;
case FR_EXIST:
printText("exist error", 11, -1, disp);
break;
case FR_TIMEOUT:
printText("timeout error", 11, -1, disp);
break;
case FR_LOCKED:
printText("locked error", 11, -1, disp);
break;
default:
break;
}
2017-10-14 17:16:13 -04:00
printText("no save found", 3, -1, disp);
//todo: clear memory area
2014-06-29 01:10:11 -04:00
2014-06-30 01:37:40 -04:00
return 0;
}
2014-06-29 01:10:11 -04:00
if (pushSaveToCart(stype, cartsave_data))
{
printText("transferred save data...", 3, -1, disp);
}
else
{
printText("error transfering save data", 3, -1, disp);
}
2014-06-29 01:10:11 -04:00
2014-06-30 01:37:40 -04:00
return 1;
2014-06-29 01:10:11 -04:00
}
2016-09-16 19:08:00 -04:00
int saveTypeToSd(display_context_t disp, char *rom_name, int stype)
{
2014-06-30 01:37:40 -04:00
//after reset create new savefile
const char* save_type_extension = saveTypeToExtension(stype, ext_type);
TCHAR fname[MAX_SUPPORTED_PATH_LEN];
int save_count = 0; //TODO: once this crosses 9999 bad infinite-loop type things happen, look into that one day
FRESULT result;
FILINFO fnoba;
printText("Finding unused save slot...", 3, -1, disp);
display_show(disp);
while (true) {
2021-10-23 00:32:33 -04:00
sprintf(fname, "/"ED64_FIRMWARE_PATH"/%s/%s.%04d.%s", save_path, rom_name, save_count, save_type_extension);
result = f_stat (fname, &fnoba);
if (result != FR_OK) {
// we found our first missing save slot, break
break;
}
++save_count;
}
2021-10-23 00:32:33 -04:00
sprintf(fname, "Found unused save slot: %04d", save_count);
printText(fname, 3, -1, disp);
display_show(disp);
2021-10-23 00:32:33 -04:00
sprintf(fname, "/"ED64_FIRMWARE_PATH"/%s/%s.%04d.%s", save_path, rom_name, save_count, save_type_extension);
2014-06-29 01:10:11 -04:00
int size = saveTypeToSize(stype); // int byte
TRACEF(disp, "size for save=%i", size);
2014-06-29 01:10:11 -04:00
FIL file;
UINT bytesread;
2017-10-20 12:28:40 -04:00
result = f_open(&file, fname, FA_WRITE | FA_OPEN_ALWAYS); //Could use FA_CREATE_ALWAYS but this could lead to the posibility of the file being emptied
2014-06-29 01:10:11 -04:00
if (result == FR_OK)
2016-09-16 19:08:00 -04:00
{
//for savegame
2017-10-18 08:55:40 -04:00
uint8_t cartsave_data[size]; //TODO: bring back old initialisation if this doesn't work
TRACEF(disp, "cartsave_data=%p", &cartsave_data);
printText("Transfering save data...", 3, -1, disp);
if (getSaveFromCart(stype, cartsave_data))
{
UINT bw;
result = f_write (
&file, /* [IN] Pointer to the file object structure */
cartsave_data, /* [IN] Pointer to the data to be written */
size, /* [IN] Number of bytes to write */
&bw /* [OUT] Pointer to the variable to return number of bytes written */
);
f_close(&file);
printText("RAM area copied to SD card.", 3, -1, disp);
return 1;
}
else
{
2017-10-23 12:46:05 -04:00
f_close(&file);
printText("Error saving game to SD", 3, -1, disp);
return 0;
}
2014-06-30 01:37:40 -04:00
}
else
{
TRACE(disp, "COULDNT CREATE FILE :-(");
printText("Error saving game to SD, couldn't create file!", 3, -1, disp);
}
2014-06-29 01:10:11 -04:00
}
2014-06-30 01:37:40 -04:00
//check out the userfriendly ini file for config-information
2016-09-16 19:08:00 -04:00
int readConfigFile(void)
{
TCHAR filename[MAX_SUPPORTED_PATH_LEN];
sprintf(filename, "/"ED64_FIRMWARE_PATH"/ALT64.INI");
2017-10-14 17:16:13 -04:00
FRESULT result;
FIL file;
UINT bytesread;
result = f_open(&file, filename, FA_READ);
2014-06-29 01:10:11 -04:00
2017-10-14 17:16:13 -04:00
if (result == FR_OK)
{
int fsize = f_size(&file);
2014-06-30 01:37:40 -04:00
2017-10-14 17:16:13 -04:00
char config_rawdata[fsize];
result =
f_read (
&file, /* [IN] File object */
2017-10-23 12:46:05 -04:00
config_rawdata, /* [OUT] Buffer to store read data */
2017-10-14 17:16:13 -04:00
fsize, /* [IN] Number of bytes to read */
&bytesread /* [OUT] Number of bytes read */
);
2014-06-30 01:37:40 -04:00
2017-10-23 12:46:05 -04:00
f_close(&file);
2017-10-14 17:16:13 -04:00
configuration config;
2014-06-30 01:37:40 -04:00
2017-10-14 17:16:13 -04:00
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;
2014-06-30 01:37:40 -04:00
2017-10-14 17:16:13 -04:00
return 1;
}
2014-06-30 01:37:40 -04:00
}
2014-06-29 01:10:11 -04:00
}
2016-09-16 19:08:00 -04:00
int str2int(char data)
{
2014-06-30 01:37:40 -04:00
data -= '0';
2016-09-16 19:08:00 -04:00
if (data > 9)
data -= 7;
2014-06-30 01:37:40 -04:00
return data;
2014-06-29 01:10:11 -04:00
}
2016-09-16 19:08:00 -04:00
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]);
2014-06-29 01:10:11 -04:00
2016-09-16 19:08:00 -04:00
return graphics_make_color(r, g, b, a);
2014-06-29 01:10:11 -04:00
}
2014-06-30 01:37:40 -04:00
//init fat filesystem after everdrive init and before sdcard access
2016-09-16 19:08:00 -04:00
void initFilesystem(void)
{
2014-06-30 01:37:40 -04:00
evd_ulockRegs();
sleep(10);
2014-06-29 01:10:11 -04:00
fs = malloc(sizeof (FATFS)); /* Get work area for the volume */
FRESULT result = f_mount(fs,"",1);
if(result != FR_OK)
2017-10-18 07:03:09 -04:00
{
2017-10-20 12:28:40 -04:00
//printText("mount error", 11, -1, disp);
2017-10-18 07:03:09 -04:00
}
else
{
2017-10-20 12:28:40 -04:00
fat_initialized = 1;
}
2014-06-29 01:10:11 -04:00
}
2014-06-30 01:37:40 -04:00
//prints the sdcard-filesystem content
2016-09-16 19:08:00 -04:00
void readSDcard(display_context_t disp, char *directory)
2017-10-27 10:35:27 -04:00
{ //TODO: readd coloured list? use a hash table...
// FatRecord *frec;
// u8 cresp = 0;
2014-06-29 01:10:11 -04:00
// //load the directory-entry
// cresp = fatLoadDirByName("/"ED64_FIRMWARE_PATH"/CFG");
2014-06-29 01:10:11 -04:00
// int dsize = dir->size;
// char colorlist[dsize][256];
2014-06-29 01:10:11 -04:00
// if (enable_colored_list)
// {
2014-06-29 01:10:11 -04:00
// for (int i = 0; i < dir->size; i++)
// {
// frec = dir->rec[i];
// u8 rom_cfg_file[MAX_SUPPORTED_PATH_LEN];
2014-06-29 01:10:11 -04:00
// //set rom_cfg
// sprintf(rom_cfg_file, "/"ED64_FIRMWARE_PATH"/CFG/%s", frec->name);
2014-06-29 01:10:11 -04:00
// static uint8_t cfg_file_data[512] = {0};
2014-06-30 01:37:40 -04:00
// FRESULT result;
// FIL file;
// UINT bytesread;
// result = f_open(&file, rom_cfg_file, FA_READ);
// if (result == FR_OK)
// {
// int fsize = f_size(&file);
// result =
// f_read (
// &file, /* [IN] File object */
// &cfg_file_data, /* [OUT] Buffer to store read data */
// fsize, /* [IN] Number of bytes to read */
// &bytesread /* [OUT] Number of bytes read */
// );
// f_close(&file);
2014-06-29 01:10:11 -04:00
// colorlist[i][0] = (char)cfg_file_data[5]; //row i column 0 = colour
// strcpy(colorlist[i] + 1, cfg_file_data + 32); //row i column 1+ = fullpath
// }
// }
// }
2014-06-30 01:37:40 -04:00
// u8 buff[32];
2014-06-30 01:37:40 -04:00
// //some trash buffer
// FatRecord *rec;
// u8 resp = 0;
2014-06-30 01:37:40 -04:00
count = 1;
//dir_t buf;
2014-06-30 01:37:40 -04:00
//clear screen and print the directory name
clearScreen(disp);
FRESULT res;
DIR dir;
UINT i;
static FILINFO fno;
2014-06-30 01:37:40 -04:00
res = f_opendir(&dir, directory); /* Open the directory */
if (res == FR_OK) {
for (;;) {
res = f_readdir(&dir, &fno); /* Read a directory item */
if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */
if (!strcmp(fno.fname, "System Volume Information") == 0 || (!strcmp(fno.fname, "ED64") == 0 && hide_sysfolder == 0))
2016-09-16 19:08:00 -04:00
{
if (fno.fattrib & AM_DIR) { /* It is a directory */
list[count - 1].type = DT_DIR;
} else { /* It is a file. */
//printf("%s/%s\n", path, fno.fname);
list[count - 1].type = DT_REG;
}
strcpy(list[count - 1].filename, fno.fname);
list[count - 1].color = 0;
// if (enable_colored_list)
// {
// for (int c = 0; c < dsize; c++)
// {
2014-06-30 01:37:40 -04:00
// u8 short_name[256];
2014-06-30 01:37:40 -04:00
// sprintf(short_name, "%s", colorlist[c] + 1);
2014-06-30 01:37:40 -04:00
// u8 *pch_s; // point-offset
// pch_s = strrchr(short_name, '/');
2014-06-30 01:37:40 -04:00
// if (strcmp(list[count - 1].filename, pch_s + 1) == 0)
// {
2014-06-30 01:37:40 -04:00
// list[count - 1].color = colorlist[c][0];
// }
// }
// //new color test end
// }
2014-06-30 01:37:40 -04:00
count++;
list = realloc(list, sizeof(direntry_t) * count);
}
2014-06-30 01:37:40 -04:00
}
f_closedir(&dir);
count--;
}
else
{
char error_msg[32];
sprintf(error_msg, "CHDIR ERROR: %i", res);
printText(error_msg, 3, -1, disp);
sleep(3000);
2014-06-30 01:37:40 -04:00
}
page = 0;
cursor = 0;
2016-09-16 19:08:00 -04:00
select_mode = 1;
2014-06-30 01:37:40 -04:00
2016-09-16 19:08:00 -04:00
if (count > 0)
{
2014-06-30 01:37:40 -04:00
/* 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(TCHAR *filename, u32 *cheat_lists[2])
2016-09-16 19:08:00 -04:00
{
// YAML parser
yaml_parser_t parser;
yaml_event_t event;
2014-06-30 01:37:40 -04:00
// State for YAML parser
int is_code = 0;
int code_on = 1;
int done = 0;
u32 *list1;
u32 *list2;
char *next;
2014-06-30 01:37:40 -04:00
int repeater = 0;
u32 address;
u32 value;
2014-06-30 01:37:40 -04:00
yaml_parser_initialize(&parser);
2014-06-30 01:37:40 -04:00
2017-10-18 08:55:40 -04:00
FRESULT result;
FIL file;
UINT bytesread;
result = f_open(&file, filename, FA_READ);
2014-06-30 01:37:40 -04:00
2017-10-18 08:55:40 -04:00
if (result == FR_OK)
2016-09-16 19:08:00 -04:00
{
2017-10-18 08:55:40 -04:00
int fsize = f_size(&file);
2014-06-30 01:37:40 -04:00
2017-10-18 08:55:40 -04:00
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 * sizeof(u32)); // Plus 2 words to be safe
if (!list1)
2016-09-16 19:08:00 -04:00
{
// Free
free(cheatfile);
2017-10-18 08:55:40 -04:00
return -2; // Out of memory
}
2017-10-18 08:55:40 -04:00
list2 = &list1[fsize / sizeof(u32) / 2];
cheat_lists[0] = list1;
cheat_lists[1] = list2;
2017-10-18 08:55:40 -04:00
result =
f_read (
&file, /* [IN] File object */
2017-10-23 12:46:05 -04:00
cheatfile, /* [OUT] Buffer to store read data */
2017-10-18 08:55:40 -04:00
fsize, /* [IN] Number of bytes to read */
&bytesread /* [OUT] Number of bytes read */
);
2014-06-30 01:37:40 -04:00
2017-10-23 12:46:05 -04:00
f_close(&file);
2014-06-30 01:37:40 -04:00
2017-10-18 08:55:40 -04:00
yaml_parser_set_input_string(&parser, cheatfile, strlen(cheatfile));
do
2016-09-16 19:08:00 -04:00
{
2017-10-18 08:55:40 -04:00
if (!yaml_parser_parse(&parser, &event))
2016-09-16 19:08:00 -04:00
{
2017-10-18 08:55:40 -04:00
// 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
2014-06-30 01:37:40 -04:00
}
2017-10-18 08:55:40 -04:00
// Process YAML
switch (event.type)
2016-09-16 19:08:00 -04:00
{
2017-10-18 08:55:40 -04:00
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;
default:
2014-06-30 01:37:40 -04:00
break;
}
2017-10-18 08:55:40 -04:00
yaml_event_delete(&event);
} while (!done);
// Free
yaml_parser_delete(&parser);
free(cheatfile);
return repeater; // Ok or repeater error
2014-06-30 01:37:40 -04:00
2017-10-18 08:55:40 -04:00
}
else
{
return -1; //err file not found
}
2014-06-30 01:37:40 -04:00
}
2016-09-16 19:08:00 -04:00
void bootRom(display_context_t disp, int silent)
{
if (boot_cic != 0)
{
// first load cheats if enabled, and error out if we can't
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_FIRMWARE_PATH"/CHEATS/%s.yml", rom_filename);
int ok = readCheatFile(cheat_filename, cheat_lists);
if (ok == 0)
{
printText("cheats found...", 3, -1, disp);
}
else
{
printText("cheats not found", 3, -1, disp);
printText("or parsing failed", 3, -1, disp);
printText("reset console...", 3, -1, disp);
gCheats = 0;
while(true) {
sleep(20000);
}
}
}
else
{
gCheats = 0;
}
2016-09-16 19:08:00 -04:00
if (boot_save != 0)
{
TCHAR cfg_file[MAX_SUPPORTED_PATH_LEN];
2014-06-30 01:37:40 -04:00
//set cfg file with last loaded cart info and save-type
sprintf(cfg_file, "/"ED64_FIRMWARE_PATH"/%s/LASTROM.CFG", save_path);
2014-06-30 01:37:40 -04:00
2017-10-18 07:03:09 -04:00
FRESULT result;
FIL file;
2017-10-23 12:46:05 -04:00
result = f_open(&file, cfg_file, FA_WRITE | FA_CREATE_ALWAYS);
2017-10-18 07:03:09 -04:00
if (result == FR_OK)
{
uint8_t cfg_data[2] = {boot_save, boot_cic};
UINT bw;
result = f_write (
2017-10-18 07:03:09 -04:00
&file, /* [IN] Pointer to the file object structure */
&cfg_data, /* [IN] Pointer to the data to be written */
2, /* [IN] Number of bytes to write */
&bw /* [OUT] Pointer to the variable to return number of bytes written */
2017-10-18 07:03:09 -04:00
);
2017-10-23 12:46:05 -04:00
f_puts(rom_filename, &file);
2017-10-18 07:03:09 -04:00
2017-10-23 12:46:05 -04:00
f_close(&file);
2014-06-30 01:37:40 -04:00
2017-10-18 07:03:09 -04:00
//set the fpga cart-save type
evd_setSaveType(boot_save);
2017-10-18 07:03:09 -04:00
saveTypeFromSd(disp, rom_filename, boot_save);
}
2014-06-30 01:37:40 -04:00
}
TRACE(disp, "Cartridge-Savetype set");
TRACE(disp, "information stored for reboot-save...");
2014-06-30 01:37:40 -04:00
u32 cart, country;
u32 info = *(vu32 *)0xB000003C;
cart = info >> 16;
country = (info >> 8) & 0xFF;
disable_interrupts();
int bios_cic = getCicType(1);
2014-06-30 01:37:40 -04:00
2016-09-16 19:08:00 -04:00
if (checksum_fix_on)
{
2014-06-30 01:37:40 -04:00
checksum_sdram();
}
2014-06-30 01:37:40 -04:00
evd_lockRegs();
2017-10-27 10:48:28 -04:00
sleep(10);
2014-06-30 01:37:40 -04:00
2016-09-16 19:08:00 -04:00
while (!(disp = display_lock()))
;
2014-06-30 01:37:40 -04:00
//blank screen to avoid glitches
graphics_fill_screen(disp, 0x000000FF);
display_show(disp);
f_mount(0, "", 0); /* Unmount the default drive */
free(fs); /* Here the work area can be discarded */
simulate_boot(boot_cic, bios_cic, cheat_lists); // boot_cic
2014-06-30 01:37:40 -04:00
}
}
2016-09-16 19:08:00 -04:00
void playSound(int snd)
{
2014-06-30 01:37:40 -04:00
//no thread support in libdragon yet, sounds pause the menu for a time :/
2016-09-16 19:08:00 -04:00
if (snd == 1)
2017-10-06 08:57:47 -04:00
sndPlaySFX("rom://sounds/ed64_mono.wav");
2014-06-30 01:37:40 -04:00
2016-09-16 19:08:00 -04:00
if (snd == 2)
2017-10-06 08:57:47 -04:00
sndPlaySFX("rom://sounds/bamboo.wav");
2014-06-30 01:37:40 -04:00
2016-09-16 19:08:00 -04:00
if (snd == 3)
2017-10-06 08:57:47 -04:00
sndPlaySFX("rom://sounds/warning.wav");
2014-06-30 01:37:40 -04:00
2016-09-16 19:08:00 -04:00
if (snd == 4)
2017-10-06 08:57:47 -04:00
sndPlaySFX("rom://sounds/done.wav");
2014-06-30 01:37:40 -04:00
}
//draws the next char at the text input screen
2016-09-16 19:08:00 -04:00
void drawInputAdd(display_context_t disp, char *msg)
{
2014-06-30 01:37:40 -04:00
graphics_draw_box_trans(disp, 23, 5, 272, 18, 0x00000090);
position++;
2016-09-16 19:08:00 -04:00
sprintf(input_text, "%s%s", input_text, msg);
drawTextInput(disp, input_text);
2014-06-30 01:37:40 -04:00
}
//del the last char at the text input screen
2016-09-16 19:08:00 -04:00
void drawInputDel(display_context_t disp)
{
2014-06-30 01:37:40 -04:00
graphics_draw_box_trans(disp, 23, 5, 272, 18, 0x00000090);
2016-09-16 19:08:00 -04:00
if (position)
{
input_text[position - 1] = '\0';
drawTextInput(disp, input_text);
2014-06-30 01:37:40 -04:00
position--;
}
}
2016-09-16 19:08:00 -04:00
void drawTextInput(display_context_t disp, char *msg)
{
graphics_draw_text(disp, 40, 15, msg);
2014-06-30 01:37:40 -04:00
}
2016-09-16 19:08:00 -04:00
void drawConfirmBox(display_context_t disp)
{ 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);
2016-09-16 19:08:00 -04:00
drawBoxNumber(disp, 5);
2014-06-30 01:37:40 -04:00
display_show(disp);
if (sound_on)
playSound(3);
2014-06-30 01:37:40 -04:00
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);
2017-10-27 10:48:28 -04:00
sleep(300);
2014-06-30 01:37:40 -04:00
}
2016-09-16 19:08:00 -04:00
void drawShortInfoBox(display_context_t disp, char *text, u8 mode)
{ 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);
2016-09-16 19:08:00 -04:00
if (mode == 0)
2016-09-16 19:08:00 -04:00
drawBoxNumber(disp, 7);
else if (mode == 1)
drawBoxNumber(disp, 8);
else if (mode == 2)
drawBoxNumber(disp, 10);
2014-06-30 01:37:40 -04:00
printText(text, 9, 14, disp);
display_show(disp);
2016-09-16 19:08:00 -04:00
if (sound_on)
{
if (mode == 0)
2014-06-30 01:37:40 -04:00
playSound(4);
2016-09-16 19:08:00 -04:00
else if (mode == 1)
2014-06-30 01:37:40 -04:00
playSound(3);
2016-09-16 19:08:00 -04:00
else if (mode == 2)
2014-06-30 01:37:40 -04:00
playSound(4);
}
sleep(300);
}
2016-09-16 19:08:00 -04:00
void readRomConfig(display_context_t disp, char *short_filename, char *full_filename)
{
TCHAR cfg_filename[MAX_SUPPORTED_PATH_LEN];
2016-09-16 19:08:00 -04:00
sprintf(rom_filename, "%s", short_filename);
rom_filename[strlen(rom_filename) - 4] = '\0'; // cut extension
sprintf(cfg_filename, "/"ED64_FIRMWARE_PATH"/CFG/%s.CFG", rom_filename);
2014-06-30 01:37:40 -04:00
uint8_t rom_cfg_data[512];
2017-10-18 07:03:09 -04:00
FRESULT result;
FIL file;
UINT bytesread;
result = f_open(&file, cfg_filename, FA_READ);
2014-06-30 01:37:40 -04:00
2017-10-18 07:03:09 -04:00
if (result == FR_OK)
2016-09-16 19:08:00 -04:00
{
2014-06-30 01:37:40 -04:00
2017-10-18 07:03:09 -04:00
result =
f_read (
&file, /* [IN] File object */
2017-10-23 12:46:05 -04:00
rom_cfg_data, /* [OUT] Buffer to store read data */
2017-10-18 07:03:09 -04:00
512, /* [IN] Number of bytes to read */
&bytesread /* [OUT] Number of bytes read */
);
2017-10-23 12:46:05 -04:00
f_close(&file);
2017-10-18 07:03:09 -04:00
rom_config[0] = 1; //preload cursor position 1 cic
2016-09-16 19:08:00 -04:00
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];
2017-10-18 07:03:09 -04:00
2014-06-30 01:37:40 -04:00
}
2016-09-16 19:08:00 -04:00
else
{
2014-06-30 01:37:40 -04:00
//preload with header data
romInfoScreen(disp, full_filename, 1); //silent info screen with readout
}
}
2016-09-16 19:08:00 -04:00
void alterRomConfig(int type, int mode)
{
2014-06-30 01:37:40 -04:00
//mode 1 = increae mode 2 = decrease
//cic
2016-09-16 19:08:00 -04:00
u8 min_cic = 0;
u8 max_cic = 6;
2014-06-30 01:37:40 -04:00
//save
2016-09-16 19:08:00 -04:00
u8 min_save = 0;
u8 max_save = 5;
2014-06-30 01:37:40 -04:00
//tv-type
2016-09-16 19:08:00 -04:00
u8 min_tv = 0;
u8 max_tv = 3;
2014-06-30 01:37:40 -04:00
//cheat
2016-09-16 19:08:00 -04:00
u8 min_cheat = 0;
u8 max_cheat = 1;
2014-06-30 01:37:40 -04:00
//chk fix
2016-09-16 19:08:00 -04:00
u8 min_chk_sum = 0;
u8 max_chk_sum = 1;
2014-06-30 01:37:40 -04:00
//quality
2016-09-16 19:08:00 -04:00
u8 min_quality = 0;
u8 max_quality = 5;
2014-06-30 01:37:40 -04:00
//country
2016-09-16 19:08:00 -04:00
u8 min_country = 0;
u8 max_country = 2;
2014-06-30 01:37:40 -04:00
2016-09-16 19:08:00 -04:00
switch (type)
{
case 1:
//start cic
if (mode == 1)
{
2014-06-30 01:37:40 -04:00
//down
2016-09-16 19:08:00 -04:00
if (rom_config[1] < max_cic)
2014-06-30 01:37:40 -04:00
rom_config[1]++;
}
2016-09-16 19:08:00 -04:00
else if (mode == 2)
{
2014-06-30 01:37:40 -04:00
//up
2016-09-16 19:08:00 -04:00
if (rom_config[1] > min_cic)
2014-06-30 01:37:40 -04:00
rom_config[1]--;
}
2016-09-16 19:08:00 -04:00
//end cic
break;
2016-09-16 16:20:19 -04:00
case 2:
2016-09-16 19:08:00 -04:00
//start save
if (mode == 1)
{
2014-06-30 01:37:40 -04:00
//down
2016-09-16 19:08:00 -04:00
if (rom_config[2] < max_save)
2014-06-30 01:37:40 -04:00
rom_config[2]++;
}
2016-09-16 19:08:00 -04:00
else if (mode == 2)
{
2014-06-30 01:37:40 -04:00
//up
2016-09-16 19:08:00 -04:00
if (rom_config[2] > min_save)
2014-06-30 01:37:40 -04:00
rom_config[2]--;
}
2016-09-16 19:08:00 -04:00
//end save
break;
2016-09-16 16:20:19 -04:00
case 3:
2016-09-16 19:08:00 -04:00
//start tv
if (mode == 1)
{
2014-06-30 01:37:40 -04:00
//down
2016-09-16 19:08:00 -04:00
if (rom_config[3] < max_tv)
2014-06-30 01:37:40 -04:00
rom_config[3]++;
}
2016-09-16 19:08:00 -04:00
else if (mode == 2)
{
2014-06-30 01:37:40 -04:00
//up
2016-09-16 19:08:00 -04:00
if (rom_config[3] > min_tv)
2014-06-30 01:37:40 -04:00
rom_config[3]--;
}
2016-09-16 19:08:00 -04:00
//end tv
break;
2016-09-16 16:20:19 -04:00
case 4:
2016-09-16 19:08:00 -04:00
//start cheat
if (mode == 1)
{
2014-06-30 01:37:40 -04:00
//down
2016-09-16 19:08:00 -04:00
if (rom_config[4] < max_cheat)
rom_config[4]++;
2014-06-30 01:37:40 -04:00
}
2016-09-16 19:08:00 -04:00
else if (mode == 2)
{
2014-06-30 01:37:40 -04:00
//up
2016-09-16 19:08:00 -04:00
if (rom_config[4] > min_cheat)
2014-06-30 01:37:40 -04:00
rom_config[4]--;
}
2016-09-16 19:08:00 -04:00
//end cheat
break;
2016-09-16 16:20:19 -04:00
case 5:
2016-09-16 19:08:00 -04:00
//start chk sum
if (mode == 1)
{
2014-06-30 01:37:40 -04:00
//down
2016-09-16 19:08:00 -04:00
if (rom_config[5] < max_chk_sum)
2014-06-30 01:37:40 -04:00
rom_config[5]++;
}
2016-09-16 19:08:00 -04:00
else if (mode == 2)
{
2014-06-30 01:37:40 -04:00
//up
2016-09-16 19:08:00 -04:00
if (rom_config[5] > min_chk_sum)
2014-06-30 01:37:40 -04:00
rom_config[5]--;
}
2016-09-16 19:08:00 -04:00
//end chk sum
break;
2016-09-16 16:20:19 -04:00
case 6:
2016-09-16 19:08:00 -04:00
//start quality
if (mode == 1)
{
2014-06-30 01:37:40 -04:00
//down
2016-09-16 19:08:00 -04:00
if (rom_config[6] < max_quality)
2014-06-30 01:37:40 -04:00
rom_config[6]++;
}
2016-09-16 19:08:00 -04:00
else if (mode == 2)
{
2014-06-30 01:37:40 -04:00
//up
2016-09-16 19:08:00 -04:00
if (rom_config[6] > min_quality)
2014-06-30 01:37:40 -04:00
rom_config[6]--;
}
2016-09-16 19:08:00 -04:00
break;
case 7:
//start country
if (mode == 1)
{
2014-06-30 01:37:40 -04:00
//down
2016-09-16 19:08:00 -04:00
if (rom_config[7] < max_country)
2014-06-30 01:37:40 -04:00
rom_config[7]++;
}
2016-09-16 19:08:00 -04:00
else if (mode == 2)
{
2014-06-30 01:37:40 -04:00
//up
2016-09-16 19:08:00 -04:00
if (rom_config[7] > min_country)
2014-06-30 01:37:40 -04:00
rom_config[7]--;
}
2016-09-16 16:20:19 -04:00
break;
default:
break;
2014-06-30 01:37:40 -04:00
}
}
2016-09-16 19:08:00 -04:00
void drawToplistBox(display_context_t disp, int line)
{
list_pos_backup[0] = cursor;
list_pos_backup[1] = page;
int dsize = 0;
2016-09-16 19:08:00 -04:00
u8 list_size = 0;
2014-06-30 01:37:40 -04:00
2016-09-16 19:08:00 -04:00
if (line == 0)
{
char* path = "/"ED64_FIRMWARE_PATH"/CFG";
FRESULT res;
DIR dir;
UINT i;
static FILINFO fno;
//TODO: is there a better way we can count the entries perhaps a hashtable?
res = f_opendir(&dir, path); /* Open the directory */
if (res == FR_OK) {
for (;;) {
res = f_readdir(&dir, &fno); /* Read a directory item */
if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */
if (!fno.fattrib & !AM_DIR) {
dsize++;
}
}
f_closedir(&dir);
}
2014-06-30 01:37:40 -04:00
res = f_opendir(&dir, path); /* Open the directory */
if (res == FR_OK) {
char toplist[dsize][256];
for (;;) {
res = f_readdir(&dir, &fno); /* Read a directory item */
if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */
if (fno.fattrib & AM_DIR) { /* It is a directory */
//i = strlen(path);
// sprintf(&path[i], "/%s", fno.fname);
// res = scan_files(path); /* Enter the directory */
// if (res != FR_OK) break;
// path[i] = 0;
} else { /* It is a file. */
TCHAR rom_cfg_file[MAX_SUPPORTED_PATH_LEN];
//set rom_cfg
sprintf(rom_cfg_file, path, fno.fname);
FRESULT result;
FIL file;
UINT bytesread;
result = f_open(&file, rom_cfg_file, FA_READ);
if (result == FR_OK)
{
static uint8_t cfg_file_data[512] = {0};
2014-06-30 01:37:40 -04:00
int fsize = f_size(&file) + 1;
result =
f_read (
&file, /* [IN] File object */
2017-10-23 12:46:05 -04:00
cfg_file_data, /* [OUT] Buffer to store read data */
fsize, /* [IN] Number of bytes to read */
&bytesread /* [OUT] Number of bytes read */
);
2017-10-23 12:46:05 -04:00
f_close(&file);
toplist[i][0] = (char)cfg_file_data[5]; //quality
strcpy(toplist[i] + 1, cfg_file_data + 32); //fullpath
i++;
}
}
}
f_closedir(&dir);
2014-06-30 01:37:40 -04:00
qsort(toplist, dsize, 256, compare_int_reverse);
2014-06-30 01:37:40 -04:00
if (dsize > 15)
list_size = 15;
else
list_size = dsize;
2014-06-30 01:37:40 -04:00
for (int c = 0; c < list_size; c++)
strcpy(toplist15[c], toplist[c]);
2014-06-30 01:37:40 -04:00
list_pos_backup[2] = list_size;
2014-06-30 01:37:40 -04:00
}
}
2016-09-16 19:08:00 -04:00
list_size = list_pos_backup[2];
2014-06-30 01:37:40 -04:00
2016-09-16 19:08:00 -04:00
u8 min = 1;
u8 max = 15;
u8 real_max = 0;
2014-06-30 01:37:40 -04:00
2016-09-16 19:08:00 -04:00
for (int c = 0; c < list_size; c++)
if (toplist15[c][0] != 0)
real_max++;
2014-06-30 01:37:40 -04:00
2016-09-16 19:08:00 -04:00
max = real_max;
2014-06-30 01:37:40 -04:00
//cursor line
2016-09-16 19:08:00 -04:00
if (line != 0)
{
if (line == 1)
{
2014-06-30 01:37:40 -04:00
//down
2016-09-16 19:08:00 -04:00
if (toplist_cursor < max)
2014-06-30 01:37:40 -04:00
toplist_cursor++;
}
2016-09-16 19:08:00 -04:00
else if (line == 2)
{
2014-06-30 01:37:40 -04:00
//up
2016-09-16 19:08:00 -04:00
if (toplist_cursor > min)
2014-06-30 01:37:40 -04:00
toplist_cursor--;
}
}
2016-09-16 19:08:00 -04:00
drawBoxNumber(disp, 9); //toplist
2014-06-30 01:37:40 -04:00
printText(" -Toplist 15-", 4, 7, disp);
printText(" ", 4, -1, disp);
2016-09-16 19:08:00 -04:00
uint32_t forecolor;
uint32_t backcolor;
backcolor = graphics_make_color(0x00, 0x00, 0x00, 0x00); //bg
2014-06-30 01:37:40 -04:00
forecolor = graphics_make_color(0xFF, 0xFF, 0xFF, 0xFF); //fg
2016-09-16 19:08:00 -04:00
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)
2014-06-30 01:37:40 -04:00
break;
2016-09-16 19:08:00 -04:00
case 3:
forecolor = graphics_make_color(0x1E, 0x90, 0xFF, 0xFF); //rare (blue)
2014-06-30 01:37:40 -04:00
break;
2016-09-16 19:08:00 -04:00
case 4:
forecolor = graphics_make_color(0x9B, 0x30, 0xFF, 0xFF); //epic (purple)
2014-06-30 01:37:40 -04:00
break;
2016-09-16 19:08:00 -04:00
case 5:
forecolor = graphics_make_color(0xFF, 0xA5, 0x00, 0xFF); //legendary (orange)
2014-06-30 01:37:40 -04:00
break;
2016-09-16 19:08:00 -04:00
default:
2014-06-30 01:37:40 -04:00
break;
}
2016-09-16 19:08:00 -04:00
graphics_set_color(forecolor, backcolor);
2014-06-30 01:37:40 -04:00
//max 32 chr
u8 short_name[256];
2016-09-16 19:08:00 -04:00
sprintf(short_name, "%s", toplist15[t] + 1);
2014-06-30 01:37:40 -04:00
u8 *pch_s; // point-offset
2016-09-16 19:08:00 -04:00
pch_s = strrchr(short_name, '/');
2014-06-30 01:37:40 -04:00
u8 *pch; // point-offset
2016-09-16 19:08:00 -04:00
pch = strrchr(pch_s, '.');
pch_s[30] = '\0'; //was 31
pch_s[pch - pch_s] = '\0';
2014-06-30 01:37:40 -04:00
2016-09-16 19:08:00 -04:00
if (t + 1 == toplist_cursor)
printText(pch_s + 1, 5, -1, disp);
2014-06-30 01:37:40 -04:00
else
2016-09-16 19:08:00 -04:00
printText(pch_s + 1, 4, -1, disp);
2014-06-30 01:37:40 -04:00
//restore color
graphics_set_color(graphics_make_color(0xFF, 0xFF, 0xFF, 0xFF), graphics_make_color(0x00, 0x00, 0x00, 0x00));
}
}
}
2016-09-16 19:08:00 -04:00
void drawRomConfigBox(display_context_t disp, int line)
{
u8 min = 1;
u8 max = 7;
2014-06-30 01:37:40 -04:00
//cursor line
2016-09-16 19:08:00 -04:00
if (line != 0)
{
if (line == 1)
{
2014-06-30 01:37:40 -04:00
//down
2016-09-16 19:08:00 -04:00
if (rom_config[0] < max)
2014-06-30 01:37:40 -04:00
rom_config[0]++;
}
2016-09-16 19:08:00 -04:00
else if (line == 2)
{
2014-06-30 01:37:40 -04:00
//up
2016-09-16 19:08:00 -04:00
if (rom_config[0] > min)
2014-06-30 01:37:40 -04:00
rom_config[0]--;
}
}
2016-09-16 19:08:00 -04:00
drawBoxNumber(disp, 6);
2014-06-30 01:37:40 -04:00
drawConfigSelection(disp, rom_config[0]);
printText(" ", 9, 9, disp);
printText("Rom configuration:", 9, -1, disp);
printText(" ", 9, -1, disp);
2016-09-16 19:08:00 -04:00
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: 5101", 9, -1, disp);
break;
2016-09-16 19:08:00 -04:00
case 4:
printText(" CIC: 6105", 9, -1, disp);
break;
case 5:
printText(" CIC: 6106", 9, -1, disp);
break;
case 6:
printText(" CIC: 5167", 9, -1, disp);
break;
2016-09-16 19:08:00 -04:00
default:
break;
2014-06-30 01:37:40 -04:00
}
2016-09-16 19:08:00 -04:00
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;
2014-06-30 01:37:40 -04:00
}
2016-09-16 19:08:00 -04:00
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;
2014-06-30 01:37:40 -04:00
}
2016-09-16 19:08:00 -04:00
switch (rom_config[4])
{
case 0:
printText(" Cheat: off", 9, -1, disp);
break;
case 1:
printText(" Cheat: on", 9, -1, disp);
break;
default:
break;
2014-06-30 01:37:40 -04:00
}
2016-09-16 19:08:00 -04:00
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;
2014-06-30 01:37:40 -04:00
}
2016-09-16 19:08:00 -04:00
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;
2014-06-30 01:37:40 -04:00
2016-09-16 19:08:00 -04:00
default:
break;
2014-06-30 01:37:40 -04:00
}
2016-09-16 19:08:00 -04:00
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;
2014-06-30 01:37:40 -04:00
}
printText(" ", 9, -1, disp);
printText("B Cancel", 9, -1, disp);
printText("A Save config", 9, -1, disp);
}
//draws the charset for the textinputscreen
2016-09-16 19:08:00 -04:00
void drawSet1(display_context_t disp)
{
set = 1;
uint32_t forecolor;
uint32_t backcolor;
2014-06-30 01:37:40 -04:00
backcolor = graphics_make_color(0x00, 0x00, 0x00, 0xFF);
forecolor = graphics_make_color(0xFF, 0xFF, 0x00, 0xFF); //yellow
2016-09-16 19:08:00 -04:00
graphics_draw_text(disp, 80, 40, "<"); //L
2014-06-30 01:37:40 -04:00
graphics_set_color(forecolor, backcolor);
2016-09-16 19:08:00 -04:00
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
2014-06-30 01:37:40 -04:00
}
2016-09-16 19:08:00 -04:00
void drawSet2(display_context_t disp)
{
set = 2;
uint32_t forecolor;
uint32_t backcolor;
2014-06-30 01:37:40 -04:00
backcolor = graphics_make_color(0x00, 0x00, 0x00, 0xFF);
forecolor = graphics_make_color(0xFF, 0xFF, 0x00, 0xFF);
2016-09-16 19:08:00 -04:00
graphics_draw_text(disp, 80, 40, "<");
2014-06-30 01:37:40 -04:00
graphics_set_color(forecolor, backcolor);
2016-09-16 19:08:00 -04:00
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");
2014-06-30 01:37:40 -04:00
}
2016-09-16 19:08:00 -04:00
void drawSet3(display_context_t disp)
{
set = 3;
uint32_t forecolor;
uint32_t backcolor;
2014-06-30 01:37:40 -04:00
backcolor = graphics_make_color(0x00, 0x00, 0x00, 0xFF);
forecolor = graphics_make_color(0xFF, 0xFF, 0x00, 0xFF);
2016-09-16 19:08:00 -04:00
graphics_draw_text(disp, 80, 40, "<");
2014-06-30 01:37:40 -04:00
graphics_set_color(forecolor, backcolor);
2016-09-16 19:08:00 -04:00
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");
2014-06-30 01:37:40 -04:00
}
2016-09-16 19:08:00 -04:00
display_context_t lockVideo(int wait)
{
2014-06-30 01:37:40 -04:00
display_context_t dc;
if (wait)
2016-09-16 19:08:00 -04:00
while (!(dc = display_lock()))
;
2014-06-30 01:37:40 -04:00
else
dc = display_lock();
return dc;
}
2016-09-16 19:08:00 -04:00
void drawSet4(display_context_t disp)
{
set = 4;
uint32_t forecolor;
uint32_t backcolor;
2014-06-30 01:37:40 -04:00
backcolor = graphics_make_color(0x00, 0x00, 0x00, 0xFF);
forecolor = graphics_make_color(0xFF, 0xFF, 0x00, 0xFF);
2016-09-16 19:08:00 -04:00
graphics_draw_text(disp, 80, 40, "<");
2014-06-30 01:37:40 -04:00
graphics_set_color(forecolor, backcolor);
2016-09-16 19:08:00 -04:00
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, "_");
2014-06-30 01:37:40 -04:00
}
2016-12-29 19:31:51 -05:00
void showAboutScreen(display_context_t disp)
{
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);
2016-12-29 19:31:51 -05:00
drawBoxNumber(disp, 2);
display_show(disp);
if (sound_on)
playSound(2);
menu_about(disp);
2016-12-29 19:31:51 -05:00
}
void loadFile(display_context_t disp)
{
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);
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, "Z64") || !strcmp(extension, "V64") || !strcmp(extension, "N64")) //TODO: an enum would be better
ft = 1;
else if (!strcmp(extension, "MPK"))
ft = 2;
2016-12-29 19:31:51 -05:00
if (!strcmp(extension, "GB"))
ft = 5;
else if (!strcmp(extension, "GBC"))
2016-12-29 19:31:51 -05:00
ft = 6;
else if (!strcmp(extension, "NES"))
2016-12-29 19:31:51 -05:00
ft = 7;
else if (!strcmp(extension, "GG"))
2016-12-29 19:31:51 -05:00
ft = 8;
else if (!strcmp(extension, "MSX"))
2016-12-29 19:31:51 -05:00
ft = 9;
else if (!strcmp(extension, "MP3"))
2016-12-29 19:31:51 -05:00
ft = 10;
if (ft != 10 || ft != 2)
{
while (!(disp = display_lock()))
;
clearScreen(disp);
u16 msg = 0;
evd_ulockRegs();
2017-10-26 07:57:02 -04:00
sleep(10);
2016-12-29 19:31:51 -05:00
sprintf(rom_filename, "%s", list[cursor].filename);
display_show(disp);
select_mode = 9;
}
switch (ft)
{
case 1:
if (quick_boot) //write to the file
{
2017-10-18 07:03:09 -04:00
FRESULT result;
FIL file;
result = f_open(&file, "/"ED64_FIRMWARE_PATH"/LASTROM.CFG", FA_WRITE | FA_CREATE_ALWAYS);
2017-10-18 07:03:09 -04:00
if (result == FR_OK)
{
2017-10-23 12:46:05 -04:00
f_puts (
name_file, /* [IN] String */
&file /* [IN] File object */
2017-10-18 07:03:09 -04:00
);
2017-10-23 12:46:05 -04:00
f_close(&file);
2016-12-29 19:31:51 -05:00
2017-10-18 07:03:09 -04:00
if (result == FR_OK)
{
//read rom_config data
readRomConfig(disp, rom_filename, name_file);
2017-10-23 12:46:05 -04:00
2017-10-18 07:03:09 -04:00
loadrom(disp, name_file, 1);
display_show(disp);
//rom loaded mapping
input_mapping = rom_loaded;
}
2017-10-23 12:46:05 -04:00
else
{
TRACE(disp, "Issue writing file...");
}
2016-12-29 19:31:51 -05:00
2017-10-18 07:03:09 -04:00
}
2017-10-23 12:46:05 -04:00
else
{
TRACE(disp, "Couldnt Open file");
}
2016-12-29 19:31:51 -05:00
2017-10-18 07:03:09 -04:00
}
2016-12-29 19:31:51 -05:00
break;
case 2:
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 = mpk_choice;
sprintf(rom_filename, "%s", name_file);
break;
case 5:
case 6:
loadgbrom(disp, name_file);
display_show(disp);
break;
case 7:
loadnesrom(disp, name_file);
display_show(disp);
break;
case 8:
loadggrom(disp, name_file);
display_show(disp);
break;
case 9:
loadmsx2rom(disp, name_file);
display_show(disp);
break;
case 10:
{
2016-12-29 19:31:51 -05:00
while (!(disp = display_lock()))
;
2016-12-29 19:31:51 -05:00
clearScreen(disp);
drawShortInfoBox(disp, " Loading...", 0);
display_show(disp);
2016-12-29 19:31:51 -05:00
long long start = 0, end = 0, curr, pause = 0, samples;
int rate = 44100, last_rate = 44100, channels = 2;
audio_init(44100, 4);
buf_size = audio_get_buffer_length() * 4;
buf_ptr = malloc(buf_size);
2016-12-29 19:31:51 -05:00
2016-12-29 19:38:05 -05:00
mp3_Start(name_file, &samples, &rate, &channels);
mp3playing = 1;
2016-12-29 19:31:51 -05:00
select_mode = 9;
while (!(disp = display_lock()))
;
clearScreen(disp);
drawShortInfoBox(disp, " MP3 Playback", 0);
2016-12-29 19:31:51 -05:00
display_show(disp);
input_mapping = mp3; //mp3 stop
2016-12-29 19:31:51 -05:00
break;
}
2016-12-29 19:31:51 -05:00
default:
break;
}
}
void handleInput(display_context_t disp, sprite_t *contr)
2016-09-16 19:08:00 -04:00
{
//request controller
controller_scan();
struct controller_data keys = get_keys_down();
struct controller_data keys_held = get_keys_held();
2014-06-30 01:37:40 -04:00
if (keys.c[0].up || keys_held.c[0].up || keys_held.c[0].y > +25)
2016-09-16 19:08:00 -04:00
{
switch (input_mapping)
{
case file_manager:
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--;
}
}
2014-06-30 01:37:40 -04:00
//end
while (!(disp = display_lock()))
;
2014-06-30 01:37:40 -04:00
new_scroll_pos(&cursor, &page, MAX_LIST, count);
2014-06-30 01:37:40 -04:00
clearScreen(disp); //part clear?
display_dir(list, cursor, page, MAX_LIST, count, disp);
2014-06-30 01:37:40 -04:00
display_show(disp);
}
}
break;
case mempak_menu:
break;
case char_input:
//chr input screen
set = 1;
break;
case rom_config_box:
while (!(disp = display_lock()))
;
2014-06-30 01:37:40 -04:00
new_scroll_pos(&cursor, &page, MAX_LIST, count);
clearScreen(disp); //part clear?
display_dir(list, cursor, page, MAX_LIST, count, disp);
2014-06-30 01:37:40 -04:00
drawRomConfigBox(disp, 2);
display_show(disp);
input_mapping = rom_config_box;
break;
case toplist:
while (!(disp = display_lock()))
;
2014-06-30 01:37:40 -04:00
drawBg(disp); //background
drawToplistBox(disp, 2);
2014-06-30 01:37:40 -04:00
display_show(disp);
input_mapping = toplist;
break;
default:
break;
2014-06-30 01:37:40 -04:00
}
}
if (keys.c[0].down || keys_held.c[0].down || keys_held.c[0].y < -25)
{
switch (input_mapping)
2016-09-16 19:08:00 -04:00
{
case file_manager:
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++;
}
}
2014-06-30 01:37:40 -04:00
while (!(disp = display_lock()))
;
2014-06-30 01:37:40 -04:00
new_scroll_pos(&cursor, &page, MAX_LIST, count);
clearScreen(disp); //part clear?
display_dir(list, cursor, page, MAX_LIST, count, disp);
2014-06-30 01:37:40 -04:00
display_show(disp);
}
}
break;
case mempak_menu:
break;
case char_input:
//chr input screen
set = 3;
break;
case rom_config_box:
while (!(disp = display_lock()))
;
2014-06-30 01:37:40 -04:00
new_scroll_pos(&cursor, &page, MAX_LIST, count);
clearScreen(disp); //part clear?
2014-06-30 01:37:40 -04:00
display_dir(list, cursor, page, MAX_LIST, count, disp);
drawRomConfigBox(disp, 1);
2014-06-30 01:37:40 -04:00
display_show(disp);
input_mapping = rom_config_box;
break;
case toplist:
while (!(disp = display_lock()))
;
2014-06-30 01:37:40 -04:00
drawBg(disp);
drawToplistBox(disp, 1);
2014-06-30 01:37:40 -04:00
display_show(disp);
input_mapping = toplist;
break;
default:
break;
}
}
else if (keys.c[0].left || keys_held.c[0].left || keys_held.c[0].x < -25)
{
switch (input_mapping)
{
case file_manager:
if (select_mode)
{
if (count != 0 && scroll_behaviour == 0 && cursor - 20 >= 0)
{
page -= 20;
cursor = page;
}
2014-06-30 01:37:40 -04:00
while (!(disp = display_lock()))
;
2014-06-30 01:37:40 -04:00
new_scroll_pos(&cursor, &page, MAX_LIST, count);
clearScreen(disp); //part clear?
display_dir(list, cursor, page, MAX_LIST, count, disp);
2014-06-30 01:37:40 -04:00
display_show(disp);
}
break;
case mempak_menu:
break;
case char_input:
//chr input screen
set = 4;
break;
case rom_config_box:
while (!(disp = display_lock()))
;
2014-06-30 01:37:40 -04:00
new_scroll_pos(&cursor, &page, MAX_LIST, count);
clearScreen(disp); //part clear?
display_dir(list, cursor, page, MAX_LIST, count, disp);
2014-06-30 01:37:40 -04:00
alterRomConfig(rom_config[0], 2);
2014-06-30 01:37:40 -04:00
drawRomConfigBox(disp, 0);
display_show(disp);
input_mapping = rom_config_box;
break;
default:
break;
}
}
else if (keys.c[0].right || keys_held.c[0].right || keys_held.c[0].x > +25)
{
switch (input_mapping)
{
case file_manager:
if (select_mode)
{
if ((count != 0) &&
(scroll_behaviour == 0) &&
(page + 20 != count) &&
(cursor + 20 <= ((count / 20) * 20 + 19)))
{
page += 20;
cursor = page;
}
2014-06-30 01:37:40 -04:00
while (!(disp = display_lock()))
;
2014-06-30 01:37:40 -04:00
new_scroll_pos(&cursor, &page, MAX_LIST, count);
clearScreen(disp); //part clear?
display_dir(list, cursor, page, MAX_LIST, count, disp);
2014-06-30 01:37:40 -04:00
display_show(disp);
}
break;
case mempak_menu:
break;
case char_input:
//chr input screen
set = 2;
break;
case rom_config_box:
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);
2014-06-30 01:37:40 -04:00
alterRomConfig(rom_config[0], 1);
2014-06-30 01:37:40 -04:00
drawRomConfigBox(disp, 0);
display_show(disp);
input_mapping = rom_config_box;
break;
default:
break;
}
}
else if (keys.c[0].start)
{
switch (input_mapping)
{
case file_manager:
//quick boot
if (quick_boot)
2016-09-16 19:08:00 -04:00
{
2017-10-14 17:16:13 -04:00
FRESULT result;
FIL file;
UINT bytesread;
result = f_open(&file, "/"ED64_FIRMWARE_PATH"/LASTROM.CFG", FA_READ);
2017-10-14 17:16:13 -04:00
if (result == FR_OK)
2016-09-16 19:08:00 -04:00
{
int fsize = f_size(&file) + 1; //extra char needed for null terminator '/0'
uint8_t lastrom_cfg_data[fsize];
2017-10-14 17:16:13 -04:00
2017-10-23 12:46:05 -04:00
// result =
// f_read (
// &file, /* [IN] File object */
// lastrom_cfg_data, /* [OUT] Buffer to store read data */
// fsize, /* [IN] Number of bytes to read */
// &bytesread /* [OUT] Number of bytes read */
// );
f_gets(lastrom_cfg_data, fsize, &file);
2017-10-14 17:16:13 -04:00
2017-10-23 12:46:05 -04:00
f_close(&file);
2017-10-14 17:16:13 -04:00
u8 *file_name = strrchr(lastrom_cfg_data, '/');
2014-06-30 01:37:40 -04:00
2016-09-16 19:08:00 -04:00
while (!(disp = display_lock()))
;
clearScreen(disp);
2014-06-30 01:37:40 -04:00
evd_ulockRegs();
2017-10-26 07:57:02 -04:00
sleep(10);
2014-06-30 01:37:40 -04:00
select_mode = 9;
//short fullpath
readRomConfig(disp, file_name + 1, lastrom_cfg_data);
2014-06-30 01:37:40 -04:00
loadrom(disp, lastrom_cfg_data, 1);
2014-06-30 01:37:40 -04:00
display_show(disp);
}
else
{
drawShortInfoBox(disp, " rom not found", 0);
}
}
else if (list[cursor].type != DT_DIR && empty == 0)
2016-09-16 19:08:00 -04:00
{
loadFile(disp);
}
break;
case mempak_menu:
break;
case char_input:
//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);
2014-06-30 01:37:40 -04:00
if (input_text[0] != '\0')
{ //input_text is set - do backup
drawBoxNumber(disp, 2);
2014-06-30 01:37:40 -04:00
display_show(disp);
2014-06-30 01:37:40 -04:00
printText("Mempak-Backup:", 9, 9, disp);
printText(" ", 9, -1, disp);
printText("search...", 9, -1, disp);
mpk_to_file(disp, input_text, 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);
drawShortInfoBox(disp, " done", 0);
2017-10-27 10:48:28 -04:00
sleep(1000);
2014-06-30 01:37:40 -04:00
//reread filesystem
cursor_line = 0;
readSDcard(disp, "/");
}
2014-06-30 01:37:40 -04:00
input_mapping = file_manager;
break;
case rom_loaded:
//rom start screen
2014-06-30 01:37:40 -04:00
//normal boot
//boot the loaded rom
bootRom(disp, 0);
//never return
break;
default:
break;
}
}
else if (keys.c[0].L)
{
switch (input_mapping)
{
case file_manager:
input_mapping = mempak_menu;
2014-06-30 01:37:40 -04:00
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);
drawBoxNumber(disp, 2);
2014-06-30 01:37:40 -04:00
display_show(disp);
2014-06-30 01:37:40 -04:00
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);
2017-10-27 10:48:28 -04:00
sleep(1000);
break;
case mempak_menu:
break;
case char_input:
//chr input screen
drawInputDel(disp);
break;
case mpk_choice:
//c-up or A
drawConfirmBox(disp);
//confirm restore mpk
input_mapping = mpk_restore;
break;
default:
break;
}
}
else if (keys.c[0].R)
{
switch (input_mapping)
{
case file_manager:
break;
case mempak_menu:
//c-up or A
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);
drawConfirmBox(disp);
//confirm format mpk
input_mapping = mpk_format;
break;
case char_input:
//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");
break;
case mpk_choice:
//c-up or A
drawConfirmBox(disp);
//confirm quick-backup
input_mapping = mpk_quick_backup;
break;
default:
break;
}
}
else if (keys.c[0].C_up)
{
switch (input_mapping)
{
case file_manager:
if (list[cursor].type != DT_DIR && empty == 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);
drawBoxNumber(disp, 11);
display_show(disp);
char *part;
2014-06-30 01:37:40 -04:00
part = malloc(slen(list[cursor].filename));
sprintf(part, "%s", list[cursor].filename);
part[31] = '\0';
printText(part, 4, 14, disp);
2014-06-30 01:37:40 -04:00
if (slen(list[cursor].filename) > 31)
{
sprintf(part, "%s", list[cursor].filename + 31);
part[31] = '\0';
printText(part, 4, -1, disp);
2014-06-30 01:37:40 -04:00
}
free(part);
input_mapping = abort_screen;
2014-06-30 01:37:40 -04:00
}
break;
case mempak_menu:
break;
case char_input:
//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");
break;
case rom_loaded:
//rom start screen
if (cheats_on == 0)
2016-09-16 19:08:00 -04:00
{
printText("cheat system activated...", 3, -1, disp);
cheats_on = 1;
}
break;
case mpk_format:
// format mpk
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);
drawBoxNumber(disp, 2);
display_show(disp);
2014-06-30 01:37:40 -04:00
printText("Mempak-Format:", 9, 9, disp);
printText(" ", 9, -1, disp);
2014-06-30 01:37:40 -04:00
printText("formating...", 9, -1, disp);
2014-06-30 01:37:40 -04:00
/* 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))
2016-09-16 19:08:00 -04:00
{
printText("Error formatting!", 9, -1, disp);
2014-06-30 01:37:40 -04:00
}
else
2016-09-16 19:08:00 -04:00
{
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);
drawShortInfoBox(disp, " done", 0);
input_mapping = abort_screen;
2014-06-30 01:37:40 -04:00
}
break;
2014-06-30 01:37:40 -04:00
case ACCESSORY_RUMBLEPAK:
printText("Really, format a RumblePak?!", 9, -1, disp);
break;
}
2014-06-30 01:37:40 -04:00
2017-10-27 10:48:28 -04:00
sleep(1000);
2014-06-30 01:37:40 -04:00
input_mapping = abort_screen;
break;
case mpk_restore:
//restore mpk
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);
drawBoxNumber(disp, 2);
display_show(disp);
2014-06-30 01:37:40 -04:00
printText("Mempak-Restore:", 9, 9, disp);
printText(" ", 9, -1, disp);
file_to_mpk(disp, rom_filename);
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);
drawShortInfoBox(disp, " done", 0);
2017-10-27 10:48:28 -04:00
sleep(1000);
input_mapping = abort_screen;
2014-06-30 01:37:40 -04:00
display_show(disp);
break;
case mpk_quick_backup:
//quick-backup
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);
drawBoxNumber(disp, 2);
display_show(disp);
2014-06-30 01:37:40 -04:00
printText("Quick-Backup:", 9, 9, disp);
printText(" ", 9, -1, disp);
printText("search...", 9, -1, disp);
2014-06-30 01:37:40 -04:00
mpk_to_file(disp, list[cursor].filename, 1); //quick
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);
drawShortInfoBox(disp, " done", 0);
2017-10-27 10:48:28 -04:00
sleep(1000);
input_mapping = abort_screen;
break;
default:
break;
}
}
else if (keys.c[0].C_right)
{
switch (input_mapping)
{
case file_manager:
2014-06-30 01:37:40 -04:00
if (list[cursor].type != DT_DIR)
{
//show rom cfg screen
2014-06-30 01:37:40 -04:00
char name_file[64];
2014-06-30 01:37:40 -04:00
if (strcmp(pwd, "/") == 0)
sprintf(name_file, "/%s", list[cursor].filename);
else
sprintf(name_file, "%s/%s", pwd, list[cursor].filename);
/*filetype
* 1 rom
*/
2014-06-30 01:37:40 -04:00
//TODO: this code is very similar to that used in loadFile, we should move it to a seperate function!
char _upper_name_file[64];
2014-06-30 01:37:40 -04:00
strcpy(_upper_name_file, name_file);
2014-06-30 01:37:40 -04:00
strhicase(_upper_name_file, strlen(_upper_name_file));
sprintf(_upper_name_file, "%s", _upper_name_file);
2014-06-30 01:37:40 -04:00
u8 extension[4];
u8 *pch;
pch = strrchr(_upper_name_file, '.'); //asd.n64
2014-06-30 01:37:40 -04:00
sprintf(extension, "%s", (pch + 1)); //0123456
2014-06-30 01:37:40 -04:00
if (!strcmp(extension, "Z64") || !strcmp(extension, "V64") || !strcmp(extension, "N64"))
{ //rom
//cfg rom
sprintf(rom_filename, "%s", list[cursor].filename);
2014-06-30 01:37:40 -04:00
//preload config or file header
readRomConfig(disp, rom_filename, name_file);
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);
2014-06-30 01:37:40 -04:00
drawRomConfigBox(disp, 0);
display_show(disp);
input_mapping = rom_config_box;
}
2014-06-30 01:37:40 -04:00
}
break;
case mempak_menu:
break;
case char_input:
//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");
break;
case rom_loaded:
//rom start screen
if (force_tv != 0)
2016-09-16 19:08:00 -04:00
{
printText("force tv mode...", 3, -1, disp);
2014-06-30 01:37:40 -04:00
}
break;
default:
break;
}
}
else if (keys.c[0].C_down)
{
switch (input_mapping)
{
case file_manager:
scopy(pwd, list_pwd_backup);
while (!(disp = display_lock()))
;
2014-06-30 01:37:40 -04:00
drawBg(disp); //background
2014-06-30 01:37:40 -04:00
toplist_cursor = 1;
drawToplistBox(disp, 0); //0 = load entries
display_show(disp);
2014-06-30 01:37:40 -04:00
input_mapping = toplist;
break;
case mempak_menu:
break;
case char_input:
//chr input screen
if (set == 1)
drawInputAdd(disp, "F"); //P X )
2017-10-11 15:30:48 -04:00
else if (set == 2)
drawInputAdd(disp, "M");
2017-10-11 15:30:48 -04:00
else if (set == 3)
drawInputAdd(disp, "T");
2017-10-11 15:30:48 -04:00
else if (set == 4)
drawInputAdd(disp, "-"); //GR Set4
break;
default:
break;
}
}
else if (keys.c[0].C_left)
{
switch (input_mapping)
{
case file_manager:
if (list[cursor].type != DT_DIR)
{
//TODO: this code is similar (if not the same) as loadFile and can be optimised!
//open
char name_file[64];
2014-06-30 01:37:40 -04:00
if (strcmp(pwd, "/") == 0)
sprintf(name_file, "/%s", list[cursor].filename);
else
sprintf(name_file, "%s/%s", pwd, list[cursor].filename);
2014-06-30 01:37:40 -04:00
char _upper_name_file[64];
2014-06-30 01:37:40 -04:00
strcpy(_upper_name_file, name_file);
strhicase(_upper_name_file, strlen(_upper_name_file));
sprintf(_upper_name_file, "%s", _upper_name_file);
2014-06-30 01:37:40 -04:00
u8 extension[4];
u8 *pch;
pch = strrchr(_upper_name_file, '.');
sprintf(extension, "%s", (pch + 1));
2014-06-30 01:37:40 -04:00
if (!strcmp(extension, "Z64") || !strcmp(extension, "V64") || !strcmp(extension, "N64"))
{ //rom
//load rom
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);
drawBoxNumber(disp, 3); //rominfo
display_show(disp);
2014-06-30 01:37:40 -04:00
u16 msg = 0;
evd_ulockRegs();
sleep(10);
sprintf(rom_filename, "%s", list[cursor].filename);
romInfoScreen(disp, name_file, 0);
2014-06-30 01:37:40 -04:00
if (sound_on)
playSound(2);
2014-06-30 01:37:40 -04:00
input_mapping = abort_screen;
2014-06-30 01:37:40 -04:00
}
2017-10-11 15:30:48 -04:00
else if (!strcmp(extension, "MPK"))
{ //mpk file
drawBoxNumber(disp, 4);
2014-06-30 01:37:40 -04:00
display_show(disp);
if (strcmp(pwd, "/") == 0)
sprintf(rom_filename, "/%s", list[cursor].filename);
else
sprintf(rom_filename, "%s/%s", pwd, list[cursor].filename);
2014-06-30 01:37:40 -04:00
view_mpk_file(disp, rom_filename);
if (sound_on)
playSound(2);
2014-06-30 01:37:40 -04:00
2016-12-15 17:48:53 -05:00
input_mapping = abort_screen;
2014-06-30 01:37:40 -04:00
}
} //mapping and not dir
break;
case mempak_menu:
break;
case char_input:
//chr input screen
if (set == 1)
drawInputAdd(disp, "C"); //P X )
2017-10-11 15:30:48 -04:00
else if (set == 2)
drawInputAdd(disp, "J");
2017-10-11 15:30:48 -04:00
else if (set == 3)
drawInputAdd(disp, "Q");
2017-10-11 15:30:48 -04:00
else if (set == 4)
drawInputAdd(disp, "X");
break;
}
}
else if (keys.c[0].Z)
{
switch (input_mapping)
{
case file_manager:
showAboutScreen(disp);
2017-10-12 18:02:08 -04:00
input_mapping = none;
break;
case mempak_menu:
2017-01-02 16:44:32 -05:00
if (sound_on)
playSound(2);
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);
drawBoxNumber(disp, 4);
display_show(disp);
view_mpk(disp);
input_mapping = abort_screen;
break;
default:
break;
}
}
else if (keys.c[0].A)
{
switch (input_mapping)
{
// open
case file_manager:
{
while (!(disp = display_lock()))
;
2014-06-30 01:37:40 -04:00
if (list[cursor].type == DT_DIR && empty == 0)
{
char name_dir[256];
2014-06-30 01:37:40 -04:00
/* init pwd=/
* /
*
* cursor=ED64
* /ED64
*
* cursor=SAVE
* /"ED64_FIRMWARE_PATH"/SAVE
*/
2014-06-30 01:37:40 -04:00
if (strcmp(pwd, "/") == 0)
sprintf(name_dir, "/%s", list[cursor].filename);
else
sprintf(name_dir, "%s/%s", pwd, list[cursor].filename);
2014-06-30 01:37:40 -04:00
sprintf(curr_dirname, "%s", list[cursor].filename);
sprintf(pwd, "%s", name_dir);
2014-06-30 01:37:40 -04:00
//load dir
cursor_lastline = 0;
cursor_line = 0;
2014-06-30 01:37:40 -04:00
//backup tree cursor postions
if (cd_behaviour == 1)
2016-09-16 19:08:00 -04:00
{
cursor_history[cursor_history_pos] = cursor;
cursor_history_pos++;
2014-06-30 01:37:40 -04:00
}
readSDcard(disp, name_dir);
display_show(disp);
} //mapping 1 and dir
else if (list[cursor].type != DT_DIR && empty == 0)
{ //open
loadFile(disp);
2014-06-30 01:37:40 -04:00
}
break; //mapping 1 end
}
case mempak_menu:
{
//open up charinput screen
while (!(disp = display_lock()))
;
new_scroll_pos(&cursor, &page, MAX_LIST, count);
clearScreen(disp); //part clear?
input_mapping = char_input;
input_text[0] = '\0';
graphics_draw_sprite(disp, 0, 0, contr);
display_show(disp);
break;
}
case char_input:
{
//chr input screen
if (set == 1)
drawInputAdd(disp, "G"); //P X )
2017-10-11 15:30:48 -04:00
else if (set == 2)
drawInputAdd(disp, "N");
2017-10-11 15:30:48 -04:00
else if (set == 3)
drawInputAdd(disp, "U");
2017-10-11 15:30:48 -04:00
else if (set == 4)
drawInputAdd(disp, "_");
break;
}
case rom_config_box:
{
char name_file[256];
2014-06-30 01:37:40 -04:00
if (strcmp(pwd, "/") == 0)
sprintf(name_file, "/%s", list[cursor].filename);
else
sprintf(name_file, "%s/%s", pwd, list[cursor].filename);
2014-06-30 01:37:40 -04:00
TCHAR rom_cfg_file[MAX_SUPPORTED_PATH_LEN];
2014-06-30 01:37:40 -04:00
u8 resp = 0;
2014-06-30 01:37:40 -04:00
//set rom_cfg
sprintf(rom_cfg_file, "/"ED64_FIRMWARE_PATH"/CFG/%s.CFG", rom_filename);
2014-06-30 01:37:40 -04:00
2017-10-18 07:03:09 -04:00
FRESULT result;
FIL file;
2017-10-20 12:28:40 -04:00
result = f_open(&file, rom_cfg_file, FA_WRITE | FA_OPEN_ALWAYS);
2017-10-18 07:03:09 -04:00
if (result == FR_OK)
{
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
2017-10-23 12:46:05 -04:00
UINT bw;
2017-10-18 07:03:09 -04:00
result =
f_write (
&file, /* [IN] Pointer to the file object structure */
2017-10-23 12:46:05 -04:00
cfg_file_data, /* [IN] Pointer to the data to be written */
2017-10-18 07:03:09 -04:00
512, /* [IN] Number of bytes to write */
2017-10-23 12:46:05 -04:00
&bw /* [OUT] Pointer to the variable to return number of bytes written */
2017-10-18 07:03:09 -04:00
);
2017-10-23 12:46:05 -04:00
f_close(&file);
while (!(disp = display_lock()))
;
drawRomConfigBox(disp, 0);
display_show(disp);
2017-10-18 07:03:09 -04:00
drawShortInfoBox(disp, " done", 0);
toplist_reload = 1;
}
2014-06-30 01:37:40 -04:00
input_mapping = abort_screen;
break;
}
case toplist:
{
//run from toplist
u8 *pch_s;
pch_s = strrchr(toplist15[toplist_cursor - 1] + 1, '/');
2014-06-30 01:37:40 -04:00
readRomConfig(disp, pch_s + 1, toplist15[toplist_cursor - 1] + 1);
2014-06-30 01:37:40 -04:00
loadrom(disp, toplist15[toplist_cursor - 1] + 1, 1);
2014-06-30 01:37:40 -04:00
//rom loaded mapping
input_mapping = rom_loaded;
break;
}
case abort_screen:
{
//rom info screen
2014-06-30 01:37:40 -04:00
while (!(disp = display_lock()))
;
2014-06-30 01:37:40 -04:00
clearScreen(disp); //part clear?
display_dir(list, cursor, page, MAX_LIST, count, disp);
2014-06-30 01:37:40 -04:00
display_show(disp);
2014-06-30 01:37:40 -04:00
input_mapping = file_manager;
break;
}
default:
break;
}
} //key a
else if (keys.c[0].B)
{ //go back
switch (input_mapping)
{
case file_manager:
if (!(strcmp(pwd, "/") == 0))
{
while (!(disp = display_lock()))
;
2014-06-30 01:37:40 -04:00
//replace by strstr()? :>
int slash_pos = 0;
int i = 0;
while (pwd[i] != '\0')
2016-09-16 19:08:00 -04:00
{
if (pwd[i] == '/')
slash_pos = i;
i++;
2014-06-30 01:37:40 -04:00
}
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)
2016-09-16 19:08:00 -04:00
{
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;
2014-06-30 01:37:40 -04:00
}
while (!(disp = display_lock()))
;
2014-06-30 01:37:40 -04:00
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
break;
case mempak_menu:
while (!(disp = display_lock()))
;
graphics_set_color(graphics_make_color(0xFF, 0xFF, 0xFF, 0xFF), graphics_make_color(0x00, 0x00, 0x00, 0x00));
new_scroll_pos(&cursor, &page, MAX_LIST, count);
clearScreen(disp);
display_show(disp);
display_dir(list, cursor, page, MAX_LIST, count, disp);
input_mapping = file_manager;
display_show(disp);
break;
case char_input:
//chr input screen
/* Lazy switching */
if (set == 1)
drawInputAdd(disp, "E"); //P X )
2017-10-11 15:30:48 -04:00
else if (set == 2)
drawInputAdd(disp, "L");
2017-10-11 15:30:48 -04:00
else if (set == 3)
drawInputAdd(disp, "S");
2017-10-11 15:30:48 -04:00
else if (set == 4)
drawInputAdd(disp, "Z");
break;
case toplist:
//leave toplist
while (!(disp = display_lock()))
;
2014-06-30 01:37:40 -04:00
readSDcard(disp, list_pwd_backup);
2014-06-30 01:37:40 -04:00
if (scroll_behaviour == 0)
{
cursor = list_pos_backup[0];
page = list_pos_backup[1];
}
else
{
cursor_line = 0;
}
2014-06-30 01:37:40 -04:00
clearScreen(disp); //part clear?
display_dir(list, cursor, page, MAX_LIST, count, disp);
2014-06-30 01:37:40 -04:00
display_show(disp);
2014-06-30 01:37:40 -04:00
input_mapping = file_manager;
break;
case mp3:
mp3_Stop();
mp3playing = 0;
audio_close();
free(buf_ptr);
buf_ptr = 0;
2014-06-30 01:37:40 -04:00
clearScreen(disp); //part clear?
display_dir(list, cursor, page, MAX_LIST, count, disp);
2014-06-30 01:37:40 -04:00
display_show(disp);
2014-06-30 01:37:40 -04:00
input_mapping = file_manager;
break;
default:
while (!(disp = display_lock()))
;
clearScreen(disp); //part clear?
display_dir(list, cursor, page, MAX_LIST, count, disp);
display_show(disp);
//rom info screen
input_mapping = file_manager;
break;
}
} //key b
}
//entry point
int main(void)
{
int fast_boot = 0;
//reserve memory
list = malloc(sizeof(direntry_t));
2014-06-30 01:37:40 -04:00
//dfs init for the rom-attached virtual filesystem
if (dfs_init(DFS_DEFAULT_LOCATION) == DFS_ESUCCESS)
{
// everdrive initial function
configure();
2014-06-30 01:37:40 -04:00
//fast boot for backup-save data
int sj = evd_readReg(REG_CFG); // not sure if this is needed!
int save_job = evd_readReg(REG_SAV_CFG); //TODO: or the firmware is V3
2014-06-30 01:37:40 -04:00
if (save_job != 0)
fast_boot = 1;
2014-06-30 01:37:40 -04:00
//not gamepads more or less the n64 hardware-controllers
controller_init();
2014-06-30 01:37:40 -04:00
//filesystem on
initFilesystem();
2014-06-30 01:37:40 -04:00
readConfigFile();
//n64 initialization
2014-06-30 01:37:40 -04:00
//sd card speed settings from config
if (sd_speed == 2)
{
bi_speed50();
}
else
{
bi_speed25();
}
2014-06-30 01:37:40 -04:00
if (tv_mode != 0)
{
*(u32 *)0x80000300 = tv_mode;
}
2014-06-30 01:37:40 -04:00
init_interrupts();
2014-06-30 01:37:40 -04:00
if (sound_on)
{
//load soundsystem
audio_init(44100, 2);
sndInit();
}
2014-06-30 01:37:40 -04:00
//timer_init(); no use of timers yet...
//background
display_init(res, DEPTH_32_BPP, 3, GAMMA_NONE, ANTIALIAS_RESAMPLE);
2014-06-30 01:37:40 -04:00
//bg buffer
static display_context_t disp;
2014-06-30 01:37:40 -04:00
//Grab a render buffer
while (!(disp = display_lock()))
;
//backgrounds from ramfs/libdragonfs
2014-06-30 01:37:40 -04:00
if (!fast_boot)
{
splashscreen = read_sprite("rom://sprites/splash.sprite");
graphics_draw_sprite(disp, 0, 0, splashscreen); //start-picture
display_show(disp);
if (sound_on)
{
playSound(1);
for (int s = 0; s < 200; s++) //todo: this blocks for 2 seconds (splashscreen)! is there a better way before the main loop starts!
{
sndUpdate();
sleep(10);
}
}
}
2014-06-30 01:37:40 -04:00
char background_path[64];
sprintf(background_path, "/"ED64_FIRMWARE_PATH"/wallpaper/%s", background_image);
FRESULT fr;
FILINFO fno;
fr = f_stat(background_path, &fno);
if (fr == FR_OK)
{
background = loadPng(background_path);
}
else
{
background = read_sprite("rom://sprites/background.sprite");
}
2014-06-30 01:37:40 -04:00
//todo: if bgm is enabled, we should start it...
2017-10-06 08:57:47 -04:00
//sndPlayBGM("rom://sounds/bgm21.it");
2014-06-30 01:37:40 -04:00
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);
2014-06-30 01:37:40 -04:00
while (!(disp = display_lock()))
;
2014-06-30 01:37:40 -04:00
drawBg(disp); //new
drawBoxNumber(disp, 1); //new
2014-06-30 01:37:40 -04:00
uint32_t *buffer = (uint32_t *)__get_buffer(disp); //fg disp = 2
2016-09-16 19:08:00 -04:00
display_show(disp); //new
2014-06-30 01:37:40 -04:00
backupSaveData(disp);
2014-06-30 01:37:40 -04:00
while (!(disp = display_lock()))
;
2014-06-30 01:37:40 -04:00
sprintf(pwd, "%s", "/");
readSDcard(disp, "/");
2014-06-30 01:37:40 -04:00
display_show(disp);
//chr input coord
x = 30;
y = 30;
2014-06-30 01:37:40 -04:00
position = 0;
set = 1;
sprintf(input_text, "");
2014-06-30 01:37:40 -04:00
//sprite for chr input
int fp = dfs_open("/sprites/n64controller.sprite");
sprite_t *contr = malloc(dfs_size(fp));
dfs_read(contr, 1, dfs_size(fp), fp);
dfs_close(fp);
2014-06-30 01:37:40 -04:00
//system main-loop with controller inputs-scan
for ( ;; )
{
if (sound_on)
sndUpdate();
2014-06-30 01:37:40 -04:00
handleInput(disp, contr);
2014-06-30 01:37:40 -04:00
if (mp3playing && audio_can_write())
{
mp3playing = mp3_Update(buf_ptr, buf_size);
if (mp3playing)
{
audio_write((short *)buf_ptr);
}
}
2014-06-30 01:37:40 -04:00
if (input_mapping == file_manager)
sleep(60);
2014-06-30 01:37:40 -04:00
if (input_mapping == char_input)
{
while (!(disp = display_lock()))
;
2014-06-30 01:37:40 -04:00
graphics_draw_sprite(disp, 0, 0, contr);
/* Set the text output color */
graphics_set_color(0x0, 0xFFFFFFFF);
2014-06-30 01:37:40 -04:00
chr_forecolor = graphics_make_color(0xFF, 0x14, 0x94, 0xFF); //pink
graphics_set_color(chr_forecolor, chr_backcolor);
2014-06-30 01:37:40 -04:00
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
2014-06-30 01:37:40 -04:00
graphics_draw_text(disp, 208, 206, "press START");
2014-06-30 01:37:40 -04:00
if (set == 1)
drawSet1(disp);
if (set == 2)
drawSet2(disp);
if (set == 3)
drawSet3(disp);
if (set == 4)
drawSet4(disp);
2014-06-30 01:37:40 -04:00
drawTextInput(disp, input_text);
2014-06-30 01:37:40 -04:00
/* Force backbuffer flip */
display_show(disp);
} //mapping 2 chr input drawings
2014-06-30 01:37:40 -04:00
//sleep(10);
2014-06-30 01:37:40 -04:00
}
}
else
{
printf("Filesystem failed to start!\n");
f_mount(0, "", 0); /* Unmount the default drive */
free(fs); /* Here the work area can be discarded */
for ( ;; )
; //never leave!
}
2014-06-30 01:37:40 -04:00
}