mirror of
https://github.com/sanni/cartreader.git
synced 2024-11-26 14:34:15 +01:00
port NES fast forward selection to other systems
This commit is contained in:
parent
38f3ebdc8d
commit
06d5f28d0c
@ -792,12 +792,18 @@ setmapper:
|
||||
//******************************************
|
||||
// CART SELECT CODE
|
||||
//******************************************
|
||||
void readDataLine_2600(FsFile& database, byte* gameMapper) {
|
||||
// Read mapper with three ascii character and subtract 48 to convert to decimal
|
||||
(*gameMapper) = ((database.read() - 48) * 100) + ((database.read() - 48) * 10) + (database.read() - 48);
|
||||
|
||||
// Skip rest of line
|
||||
database.seekCur(2);
|
||||
}
|
||||
|
||||
void setCart_2600() {
|
||||
//go to root
|
||||
sd.chdir();
|
||||
|
||||
char gamename[100];
|
||||
byte gameMapper;
|
||||
byte gameSize;
|
||||
|
||||
@ -808,64 +814,13 @@ void setCart_2600() {
|
||||
if (myFile.open("2600.txt", O_READ)) {
|
||||
seek_first_letter_in_database(myFile, myLetter);
|
||||
|
||||
// Display database
|
||||
while (myFile.available()) {
|
||||
display_Clear();
|
||||
|
||||
get_line(gamename, &myFile, sizeof(gamename));
|
||||
|
||||
// Read mapper with three ascii character and subtract 48 to convert to decimal
|
||||
gameMapper = ((myFile.read() - 48) * 100) + ((myFile.read() - 48) * 10) + (myFile.read() - 48);
|
||||
|
||||
// Skip rest of line
|
||||
myFile.seekCur(2);
|
||||
|
||||
skip_line(&myFile);
|
||||
|
||||
println_Msg(F("Select your cartridge"));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
println_Msg(gamename);
|
||||
|
||||
#if defined(ENABLE_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(ENABLE_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#elif defined(SERIAL_MONITOR)
|
||||
println_Msg(F("U/D to Change"));
|
||||
println_Msg(F("Space to Select"));
|
||||
#endif
|
||||
display_Update();
|
||||
|
||||
uint8_t b = 0;
|
||||
while (1) {
|
||||
// Check button input
|
||||
b = checkButton();
|
||||
|
||||
// Next
|
||||
if (b == 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Previous
|
||||
else if (b == 2) {
|
||||
rewind_line(myFile, 6);
|
||||
break;
|
||||
}
|
||||
|
||||
// Selection
|
||||
else if (b == 3) {
|
||||
EEPROM_writeAnything(7, gameMapper);
|
||||
for (int i = 0; i < a2600mapcount; i++) {
|
||||
a2600index = i * 2;
|
||||
if (gameMapper == pgm_read_byte(a2600mapsize + a2600index)) {
|
||||
a2600size = pgm_read_byte(a2600mapsize + a2600index + 1);
|
||||
EEPROM_writeAnything(8, a2600size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
myFile.close();
|
||||
if(checkCartSelection(myFile, &readDataLine_2600, &gameMapper)) {
|
||||
EEPROM_writeAnything(7, gameMapper);
|
||||
for (int i = 0; i < a2600mapcount; i++) {
|
||||
a2600index = i * 2;
|
||||
if (gameMapper == pgm_read_byte(a2600mapsize + a2600index)) {
|
||||
a2600size = pgm_read_byte(a2600mapsize + a2600index + 1);
|
||||
EEPROM_writeAnything(8, a2600size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -781,14 +781,30 @@ setmapper:
|
||||
//******************************************
|
||||
// CART SELECT CODE
|
||||
//******************************************
|
||||
struct database_entry_7800 {
|
||||
byte gameMapper;
|
||||
byte gameSize;
|
||||
};
|
||||
|
||||
void readDataLine_7800(FsFile& database, struct database_entry_7800* entry) {
|
||||
// Read mapper
|
||||
entry->gameMapper = database.read() - 48;
|
||||
|
||||
// Skip over semicolon
|
||||
database.seekCur(1);
|
||||
|
||||
// Read rom size
|
||||
entry->gameSize = database.read() - 48;
|
||||
|
||||
// Skip rest of line
|
||||
database.seekCur(2);
|
||||
}
|
||||
|
||||
void setCart_7800() {
|
||||
//go to root
|
||||
sd.chdir();
|
||||
|
||||
char gamename[100];
|
||||
byte gameMapper;
|
||||
byte gameSize;
|
||||
struct database_entry_7800 entry;
|
||||
|
||||
// Select starting letter
|
||||
byte myLetter = starting_letter();
|
||||
@ -797,66 +813,9 @@ void setCart_7800() {
|
||||
if (myFile.open("7800.txt", O_READ)) {
|
||||
seek_first_letter_in_database(myFile, myLetter);
|
||||
|
||||
// Display database
|
||||
while (myFile.available()) {
|
||||
display_Clear();
|
||||
|
||||
get_line(gamename, &myFile, sizeof(gamename));
|
||||
|
||||
// Read mapper
|
||||
gameMapper = myFile.read() - 48;
|
||||
|
||||
// Skip over semicolon
|
||||
myFile.seekCur(1);
|
||||
|
||||
// Read rom size
|
||||
gameSize = myFile.read() - 48;
|
||||
|
||||
// Skip rest of line
|
||||
myFile.seekCur(2);
|
||||
|
||||
skip_line(&myFile);
|
||||
|
||||
println_Msg(F("Select your cartridge"));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
println_Msg(gamename);
|
||||
|
||||
#if defined(ENABLE_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(ENABLE_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#elif defined(SERIAL_MONITOR)
|
||||
println_Msg(F("U/D to Change"));
|
||||
println_Msg(F("Space to Select"));
|
||||
#endif
|
||||
display_Update();
|
||||
|
||||
uint8_t b = 0;
|
||||
while (1) {
|
||||
// Check button input
|
||||
b = checkButton();
|
||||
|
||||
// Next
|
||||
if (b == 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Previous
|
||||
else if (b == 2) {
|
||||
rewind_line(myFile, 6);
|
||||
break;
|
||||
}
|
||||
|
||||
// Selection
|
||||
else if (b == 3) {
|
||||
EEPROM_writeAnything(7, gameMapper);
|
||||
EEPROM_writeAnything(8, gameSize);
|
||||
myFile.close();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(checkCartSelection(myFile, &readDataLine_7800, &entry)) {
|
||||
EEPROM_writeAnything(7, entry.gameMapper);
|
||||
EEPROM_writeAnything(8, entry.gameSize);
|
||||
}
|
||||
} else {
|
||||
print_FatalError(F("Database file not found"));
|
||||
|
@ -1029,13 +1029,30 @@ void printMapper_C64(byte c64maplabel) {
|
||||
//******************************************
|
||||
// CART SELECT CODE
|
||||
//******************************************
|
||||
struct database_entry_C64 {
|
||||
byte gameMapper;
|
||||
byte gameSize;
|
||||
};
|
||||
|
||||
void readDataLine_C64(FsFile& database, struct database_entry_C64* entry) {
|
||||
// Read mapper with two ascii character and subtract 48 to convert to decimal
|
||||
entry->gameMapper = ((database.read() - 48) * 10) + (database.read() - 48);
|
||||
|
||||
// Skip over semicolon
|
||||
database.seekCur(1);
|
||||
|
||||
// Read size and subtract 48 to convert to decimal
|
||||
entry->gameSize = database.read() - 48;
|
||||
|
||||
// Skip rest of line
|
||||
database.seekCur(2);
|
||||
}
|
||||
|
||||
void setCart_C64() {
|
||||
//go to root
|
||||
sd.chdir();
|
||||
|
||||
char gamename[100];
|
||||
byte gameMapper;
|
||||
byte gameSize;
|
||||
struct database_entry_C64 entry;
|
||||
|
||||
// Select starting letter
|
||||
byte myLetter = starting_letter();
|
||||
@ -1044,65 +1061,9 @@ void setCart_C64() {
|
||||
if (myFile.open("c64cart.txt", O_READ)) {
|
||||
seek_first_letter_in_database(myFile, myLetter);
|
||||
|
||||
// Display database
|
||||
while (myFile.available()) {
|
||||
display_Clear();
|
||||
|
||||
get_line(gamename, &myFile, sizeof(gamename));
|
||||
|
||||
// Read mapper with two ascii character and subtract 48 to convert to decimal
|
||||
gameMapper = ((myFile.read() - 48) * 10) + (myFile.read() - 48);
|
||||
|
||||
// Skip over semicolon
|
||||
myFile.seekCur(1);
|
||||
|
||||
// Read size and subtract 48 to convert to decimal
|
||||
gameSize = myFile.read() - 48;
|
||||
|
||||
// Skip rest of line
|
||||
myFile.seekCur(2);
|
||||
|
||||
skip_line(&myFile);
|
||||
|
||||
println_Msg(F("Select your cartridge"));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
println_Msg(gamename);
|
||||
|
||||
#if defined(ENABLE_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(ENABLE_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#elif defined(SERIAL_MONITOR)
|
||||
println_Msg(F("U/D to Change"));
|
||||
println_Msg(F("Space to Select"));
|
||||
#endif
|
||||
display_Update();
|
||||
|
||||
uint8_t b = 0;
|
||||
while (1) {
|
||||
// Check button input
|
||||
b = checkButton();
|
||||
|
||||
// Next
|
||||
if (b == 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Previous
|
||||
else if (b == 2) {
|
||||
rewind_line(myFile, 6);
|
||||
break;
|
||||
}
|
||||
// Selection
|
||||
else if (b == 3) {
|
||||
EEPROM_writeAnything(7, gameMapper);
|
||||
EEPROM_writeAnything(8, gameSize);
|
||||
myFile.close();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(checkCartSelection(myFile, &readDataLine_C64, &entry)) {
|
||||
EEPROM_writeAnything(7, entry.gameMapper);
|
||||
EEPROM_writeAnything(8, entry.gameSize);
|
||||
}
|
||||
} else {
|
||||
print_FatalError(F("Database file not found"));
|
||||
|
@ -364,14 +364,54 @@ void checkStatus_COL() {
|
||||
//******************************************
|
||||
// CART SELECT CODE
|
||||
//******************************************
|
||||
void setCart_COL() {
|
||||
char gamename[100];
|
||||
char tempStr2[2];
|
||||
struct database_entry_COL {
|
||||
char crc_search[9];
|
||||
byte gameSize;
|
||||
};
|
||||
|
||||
void readDataLine_COL(FsFile& database, struct database_entry_COL* entry) {
|
||||
char tempStr2[2];
|
||||
|
||||
// Read CRC32 checksum
|
||||
sprintf(checksumStr, "%c", database.read());
|
||||
for (byte i = 0; i < 7; i++) {
|
||||
sprintf(tempStr2, "%c", database.read());
|
||||
strcat(checksumStr, tempStr2);
|
||||
}
|
||||
|
||||
// Skip over semicolon
|
||||
database.seekCur(1);
|
||||
|
||||
// Read CRC32 of first 512 bytes
|
||||
sprintf(entry->crc_search, "%c", database.read());
|
||||
for (byte i = 0; i < 7; i++) {
|
||||
sprintf(tempStr2, "%c", database.read());
|
||||
strcat(entry->crc_search, tempStr2);
|
||||
}
|
||||
|
||||
// Skip over semicolon
|
||||
database.seekCur(1);
|
||||
|
||||
// Read rom size
|
||||
// Read the next ascii character and subtract 48 to convert to decimal
|
||||
entry->gameSize = ((database.read() - 48) * 10) + (database.read() - 48);
|
||||
|
||||
// Skip rest of line
|
||||
database.seekCur(2);
|
||||
}
|
||||
|
||||
void printDataLine_COL(struct database_entry_COL* entry) {
|
||||
print_Msg(F("Size: "));
|
||||
print_Msg(entry->gameSize);
|
||||
println_Msg(F("KB"));
|
||||
}
|
||||
|
||||
void setCart_COL() {
|
||||
//go to root
|
||||
sd.chdir();
|
||||
|
||||
struct database_entry_COL entry;
|
||||
|
||||
// Select starting letter
|
||||
byte myLetter = starting_letter();
|
||||
|
||||
@ -379,122 +419,38 @@ void setCart_COL() {
|
||||
if (myFile.open("colv.txt", O_READ)) {
|
||||
seek_first_letter_in_database(myFile, myLetter);
|
||||
|
||||
// Display database
|
||||
while (myFile.available()) {
|
||||
display_Clear();
|
||||
if(checkCartSelection(myFile, &readDataLine_COL, &entry, &printDataLine_COL)) {
|
||||
//byte COL[] = {8, 12, 16, 20, 24, 32};
|
||||
switch (entry.gameSize) {
|
||||
case 8:
|
||||
colsize = 0;
|
||||
break;
|
||||
|
||||
// Read game name
|
||||
get_line(gamename, &myFile, 96);
|
||||
case 12:
|
||||
colsize = 1;
|
||||
break;
|
||||
|
||||
// Read CRC32 checksum
|
||||
sprintf(checksumStr, "%c", myFile.read());
|
||||
for (byte i = 0; i < 7; i++) {
|
||||
sprintf(tempStr2, "%c", myFile.read());
|
||||
strcat(checksumStr, tempStr2);
|
||||
}
|
||||
case 16:
|
||||
colsize = 2;
|
||||
break;
|
||||
|
||||
// Skip over semicolon
|
||||
myFile.seekCur(1);
|
||||
case 20:
|
||||
colsize = 3;
|
||||
break;
|
||||
|
||||
// Read CRC32 of first 512 bytes
|
||||
sprintf(crc_search, "%c", myFile.read());
|
||||
for (byte i = 0; i < 7; i++) {
|
||||
sprintf(tempStr2, "%c", myFile.read());
|
||||
strcat(crc_search, tempStr2);
|
||||
}
|
||||
case 24:
|
||||
colsize = 4;
|
||||
break;
|
||||
|
||||
// Skip over semicolon
|
||||
myFile.seekCur(1);
|
||||
case 32:
|
||||
colsize = 5;
|
||||
break;
|
||||
|
||||
// Read rom size
|
||||
// Read the next ascii character and subtract 48 to convert to decimal
|
||||
cartSize = myFile.read() - 48;
|
||||
|
||||
// Remove leading 0 for single digit cart sizes
|
||||
if (cartSize != 0) {
|
||||
cartSize = cartSize * 10 + myFile.read() - 48;
|
||||
} else {
|
||||
cartSize = myFile.read() - 48;
|
||||
}
|
||||
|
||||
// Skip rest of line
|
||||
myFile.seekCur(2);
|
||||
|
||||
// Skip every 3rd line
|
||||
skip_line(&myFile);
|
||||
|
||||
println_Msg(F("Select your cartridge"));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
println_Msg(gamename);
|
||||
print_Msg(F("Size: "));
|
||||
print_Msg(cartSize);
|
||||
println_Msg(F("KB"));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
#if defined(ENABLE_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(ENABLE_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#elif defined(SERIAL_MONITOR)
|
||||
println_Msg(F("U/D to Change"));
|
||||
println_Msg(F("Space to Select"));
|
||||
#endif
|
||||
display_Update();
|
||||
|
||||
uint8_t b = 0;
|
||||
while (1) {
|
||||
// Check button input
|
||||
b = checkButton();
|
||||
|
||||
// Next
|
||||
if (b == 1) {
|
||||
default:
|
||||
colsize = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
// Previous
|
||||
else if (b == 2) {
|
||||
rewind_line(myFile, 6);
|
||||
break;
|
||||
}
|
||||
|
||||
// Selection
|
||||
else if (b == 3) {
|
||||
//byte COL[] = {8, 12, 16, 20, 24, 32};
|
||||
switch (cartSize) {
|
||||
case 8:
|
||||
colsize = 0;
|
||||
break;
|
||||
|
||||
case 12:
|
||||
colsize = 1;
|
||||
break;
|
||||
|
||||
case 16:
|
||||
colsize = 2;
|
||||
break;
|
||||
|
||||
case 20:
|
||||
colsize = 3;
|
||||
break;
|
||||
|
||||
case 24:
|
||||
colsize = 4;
|
||||
break;
|
||||
|
||||
case 32:
|
||||
colsize = 5;
|
||||
break;
|
||||
|
||||
default:
|
||||
colsize = 0;
|
||||
break;
|
||||
}
|
||||
EEPROM_writeAnything(8, colsize);
|
||||
myFile.close();
|
||||
break;
|
||||
}
|
||||
}
|
||||
EEPROM_writeAnything(8, colsize);
|
||||
}
|
||||
} else {
|
||||
print_FatalError(F("Database file not found"));
|
||||
|
@ -707,6 +707,108 @@ void seek_first_letter_in_database(FsFile& database, byte myLetter) {
|
||||
#endif
|
||||
}
|
||||
|
||||
// navigate through the database file using OSSC input buttons. Requires function pointer readData for reading device specific data line from database
|
||||
// printDataLine - optional callback for printing device specific data informations about the currently browsed game
|
||||
// setRomName - callback function to set rom name if game is selected
|
||||
// returns true if a game was selected, false otherwise
|
||||
boolean checkCartSelection(FsFile& database, void (*readData)(FsFile&, void*), void* data, void (*printDataLine)(void*) = NULL, void (setRomName)(const char* input) = NULL) {
|
||||
char gamename[128];
|
||||
uint8_t fastScrolling = 1;
|
||||
|
||||
// Display database
|
||||
while (database.available()) {
|
||||
#ifdef ENABLE_GLOBAL_LOG
|
||||
// Disable log to prevent unnecessary logging
|
||||
dont_log = true;
|
||||
#endif
|
||||
display_Clear();
|
||||
|
||||
get_line(gamename, &database, sizeof(gamename));
|
||||
|
||||
readData(database, data);
|
||||
|
||||
skip_line(&database);
|
||||
|
||||
println_Msg(F("Select your cartridge"));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
println_Msg(gamename);
|
||||
|
||||
if(printDataLine) {
|
||||
printDataLine(data);
|
||||
}
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
#if defined(ENABLE_OLED)
|
||||
print_STR(press_to_change_STR, 0);
|
||||
if (fastScrolling > 1)
|
||||
println_Msg(F(" (fast)"));
|
||||
else
|
||||
println_Msg("");
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(ENABLE_LCD)
|
||||
print_STR(rotate_to_change_STR, 0);
|
||||
if (fastScrolling > 1)
|
||||
println_Msg(F(" (fast)"));
|
||||
else
|
||||
println_Msg("");
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#elif defined(SERIAL_MONITOR)
|
||||
println_Msg(F("U/D to Change"));
|
||||
println_Msg(F("Space to Select"));
|
||||
#endif
|
||||
display_Update();
|
||||
|
||||
#ifdef ENABLE_GLOBAL_LOG
|
||||
// Enable log again
|
||||
dont_log = false;
|
||||
#endif
|
||||
uint8_t b = 0;
|
||||
while (1) {
|
||||
// Check button input
|
||||
b = checkButton();
|
||||
|
||||
// Next
|
||||
if (b == 1) {
|
||||
// 1: Next record
|
||||
if (fastScrolling > 1) {
|
||||
for (uint8_t skipped = 0; skipped < fastScrolling * 3; skipped++) {
|
||||
skip_line(&database);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Previous
|
||||
else if (b == 2) {
|
||||
// 2: Previous record
|
||||
if (fastScrolling > 1)
|
||||
rewind_line(database, fastScrolling * 3 + 3);
|
||||
else
|
||||
rewind_line(database, 6);
|
||||
break;
|
||||
}
|
||||
|
||||
// Selection
|
||||
else if (b == 3) {
|
||||
if(setRomName) {
|
||||
setRomName(gamename);
|
||||
}
|
||||
database.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
else if (b == 4) {
|
||||
// 4: Toggle Fast Scrolling
|
||||
if (fastScrolling == 1)
|
||||
fastScrolling = 30;
|
||||
else
|
||||
fastScrolling = 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void starting_letter__subDraw(byte selection, byte line) {
|
||||
display.setDrawColor(0);
|
||||
for (uint8_t i = 0; i < 4; i++) display.drawLine(0, 10 + i * 16, 128, 10 + i * 16);
|
||||
|
@ -757,14 +757,69 @@ void checkStatus_INTV() {
|
||||
//******************************************
|
||||
// CART SELECT CODE
|
||||
//******************************************
|
||||
void setCart_INTV() {
|
||||
char gamename[100];
|
||||
char tempStr2[2];
|
||||
struct database_entry_INTV {
|
||||
char crc_search[9];
|
||||
byte gameMapper;
|
||||
byte gameSize;
|
||||
};
|
||||
|
||||
void readDataLine_INTV(FsFile& database, struct database_entry_INTV* entry) {
|
||||
char tempStr2[2];
|
||||
|
||||
// Read CRC32 checksum
|
||||
sprintf(checksumStr, "%c", database.read());
|
||||
for (byte i = 0; i < 7; i++) {
|
||||
sprintf(tempStr2, "%c", database.read());
|
||||
strcat(checksumStr, tempStr2);
|
||||
}
|
||||
|
||||
// Skip over semicolon
|
||||
database.seekCur(1);
|
||||
|
||||
// Read CRC32 of first 512 bytes
|
||||
sprintf(entry->crc_search, "%c", database.read());
|
||||
for (byte i = 0; i < 7; i++) {
|
||||
sprintf(tempStr2, "%c", database.read());
|
||||
strcat(entry->crc_search, tempStr2);
|
||||
}
|
||||
|
||||
// Skip over semicolon
|
||||
database.seekCur(1);
|
||||
|
||||
// Read mapper
|
||||
entry->gameMapper = database.read() - 48;
|
||||
|
||||
// Skip over semicolon
|
||||
database.seekCur(1);
|
||||
|
||||
// Read rom size
|
||||
// Read the next ascii character and subtract 48 to convert to decimal
|
||||
entry->gameSize = ((database.read() - 48) * 10) + (database.read() - 48);
|
||||
|
||||
// Skip over semicolon
|
||||
database.seekCur(1);
|
||||
|
||||
// Read SRAM size
|
||||
byte sramSize __attribute__((unused)) = database.read() - 48;
|
||||
|
||||
// Skip rest of line
|
||||
database.seekCur(2);
|
||||
}
|
||||
|
||||
void printDataLine_INTV(struct database_entry_INTV* entry) {
|
||||
print_Msg(F("Size: "));
|
||||
print_Msg(entry->gameSize);
|
||||
println_Msg(F("KB"));
|
||||
print_Msg(F("Mapper: "));
|
||||
println_Msg(entry->gameMapper);
|
||||
}
|
||||
|
||||
void setCart_INTV() {
|
||||
//go to root
|
||||
sd.chdir();
|
||||
|
||||
struct database_entry_INTV entry;
|
||||
|
||||
// Select starting letter
|
||||
byte myLetter = starting_letter();
|
||||
|
||||
@ -772,136 +827,39 @@ void setCart_INTV() {
|
||||
if (myFile.open("intv.txt", O_READ)) {
|
||||
seek_first_letter_in_database(myFile, myLetter);
|
||||
|
||||
// Display database
|
||||
while (myFile.available()) {
|
||||
display_Clear();
|
||||
|
||||
// Read game name
|
||||
get_line(gamename, &myFile, 96);
|
||||
|
||||
// Read CRC32 checksum
|
||||
sprintf(checksumStr, "%c", myFile.read());
|
||||
for (byte i = 0; i < 7; i++) {
|
||||
sprintf(tempStr2, "%c", myFile.read());
|
||||
strcat(checksumStr, tempStr2);
|
||||
}
|
||||
|
||||
// Skip over semicolon
|
||||
myFile.seekCur(1);
|
||||
|
||||
// Read CRC32 of first 512 bytes
|
||||
sprintf(crc_search, "%c", myFile.read());
|
||||
for (byte i = 0; i < 7; i++) {
|
||||
sprintf(tempStr2, "%c", myFile.read());
|
||||
strcat(crc_search, tempStr2);
|
||||
}
|
||||
|
||||
// Skip over semicolon
|
||||
myFile.seekCur(1);
|
||||
|
||||
// Read mapper
|
||||
intvmapper = myFile.read() - 48;
|
||||
|
||||
// Skip over semicolon
|
||||
myFile.seekCur(1);
|
||||
|
||||
// Read rom size
|
||||
// Read the next ascii character and subtract 48 to convert to decimal
|
||||
cartSize = myFile.read() - 48;
|
||||
|
||||
// Remove leading 0 for single digit cart sizes
|
||||
if (cartSize != 0) {
|
||||
cartSize = cartSize * 10 + myFile.read() - 48;
|
||||
} else {
|
||||
cartSize = myFile.read() - 48;
|
||||
}
|
||||
|
||||
// Skip over semicolon
|
||||
myFile.seekCur(1);
|
||||
|
||||
// Read SRAM size
|
||||
byte sramSize __attribute__((unused)) = myFile.read() - 48;
|
||||
|
||||
// Skip rest of line
|
||||
myFile.seekCur(2);
|
||||
|
||||
// Skip every 3rd line
|
||||
skip_line(&myFile);
|
||||
|
||||
println_Msg(F("Select your cartridge"));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
println_Msg(gamename);
|
||||
print_Msg(F("Size: "));
|
||||
print_Msg(cartSize);
|
||||
println_Msg(F("KB"));
|
||||
print_Msg(F("Mapper: "));
|
||||
println_Msg(intvmapper);
|
||||
#if defined(ENABLE_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(ENABLE_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#elif defined(SERIAL_MONITOR)
|
||||
println_Msg(F("U/D to Change"));
|
||||
println_Msg(F("Space to Select"));
|
||||
#endif
|
||||
display_Update();
|
||||
|
||||
uint8_t b = 0;
|
||||
while (1) {
|
||||
// Check button input
|
||||
b = checkButton();
|
||||
|
||||
// Next
|
||||
if (b == 1) {
|
||||
if(checkCartSelection(myFile, &readDataLine_INTV, &entry, &printDataLine_INTV)) {
|
||||
//byte INTV[] = {8, 12, 16, 24, 32, 48};
|
||||
switch (entry.gameSize) {
|
||||
case 8:
|
||||
intvsize = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
// Previous
|
||||
else if (b == 2) {
|
||||
rewind_line(myFile, 6);
|
||||
case 12:
|
||||
intvsize = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
// Selection
|
||||
else if (b == 3) {
|
||||
//byte INTV[] = {8, 12, 16, 24, 32, 48};
|
||||
switch (cartSize) {
|
||||
case 8:
|
||||
intvsize = 0;
|
||||
break;
|
||||
|
||||
case 12:
|
||||
intvsize = 1;
|
||||
break;
|
||||
|
||||
case 16:
|
||||
intvsize = 2;
|
||||
break;
|
||||
|
||||
case 24:
|
||||
intvsize = 3;
|
||||
break;
|
||||
|
||||
case 32:
|
||||
intvsize = 4;
|
||||
break;
|
||||
|
||||
case 48:
|
||||
intvsize = 5;
|
||||
break;
|
||||
|
||||
default:
|
||||
intvsize = 0;
|
||||
break;
|
||||
}
|
||||
EEPROM_writeAnything(7, intvmapper);
|
||||
EEPROM_writeAnything(8, intvsize);
|
||||
myFile.close();
|
||||
case 16:
|
||||
intvsize = 2;
|
||||
break;
|
||||
|
||||
case 24:
|
||||
intvsize = 3;
|
||||
break;
|
||||
|
||||
case 32:
|
||||
intvsize = 4;
|
||||
break;
|
||||
|
||||
case 48:
|
||||
intvsize = 5;
|
||||
break;
|
||||
|
||||
default:
|
||||
intvsize = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
EEPROM_writeAnything(7, entry.gameMapper);
|
||||
EEPROM_writeAnything(8, intvsize);
|
||||
}
|
||||
} else {
|
||||
print_FatalError(F("Database file not found"));
|
||||
|
@ -514,6 +514,69 @@ void setRomnameFromString(const char* input) {
|
||||
}
|
||||
}
|
||||
|
||||
void printDataLine_NES(struct database_entry* entry) {
|
||||
uint8_t iNES[16];
|
||||
uint8_t* output;
|
||||
char* input;
|
||||
|
||||
input = entry->iNES_str;
|
||||
output = iNES;
|
||||
for (uint8_t i = 0; i < sizeof(iNES); i++) {
|
||||
unsigned int buf;
|
||||
|
||||
sscanf(input, "%2X", &buf);
|
||||
*(output++) = buf;
|
||||
input += 2;
|
||||
}
|
||||
|
||||
mapper = (iNES[6] >> 4) | (iNES[7] & 0xF0) | (iNES[8] & 0x0F);
|
||||
|
||||
if ((iNES[9] & 0x0F) != 0x0F) {
|
||||
// simple notation
|
||||
prgsize = (iNES[4] | ((iNES[9] & 0x0F) << 8)); //*16
|
||||
} else {
|
||||
// exponent-multiplier notation
|
||||
prgsize = (((1 << (iNES[4] >> 2)) * ((iNES[4] & 0b11) * 2 + 1)) >> 14); //*16
|
||||
}
|
||||
if (prgsize != 0)
|
||||
prgsize = (int(log(prgsize) / log(2)));
|
||||
|
||||
if ((iNES[9] & 0xF0) != 0xF0) {
|
||||
// simple notation
|
||||
chrsize = (uppow2(iNES[5] | ((iNES[9] & 0xF0) << 4))) * 2; //*4
|
||||
} else {
|
||||
// exponent-multiplier notation
|
||||
chrsize = (((1 << (iNES[5] >> 2)) * ((iNES[5] & 0b11) * 2 + 1)) >> 13) * 2; //*4
|
||||
}
|
||||
if (chrsize != 0)
|
||||
chrsize = (int(log(chrsize) / log(2)));
|
||||
|
||||
ramsize = ((iNES[10] & 0xF0) ? (64 << ((iNES[10] & 0xF0) >> 4)) : 0) / 4096; //*4
|
||||
if (ramsize != 0)
|
||||
ramsize = (int(log(ramsize) / log(2)));
|
||||
|
||||
prg = (int_pow(2, prgsize)) * 16;
|
||||
if (chrsize == 0)
|
||||
chr = 0; // 0K
|
||||
else
|
||||
chr = (int_pow(2, chrsize)) * 4;
|
||||
if (ramsize == 0)
|
||||
ram = 0; // 0K
|
||||
else if (mapper == 82)
|
||||
ram = 5; // 5K
|
||||
else
|
||||
ram = (int_pow(2, ramsize)) * 4;
|
||||
|
||||
// Mapper Variants
|
||||
// Identify variant for use across multiple functions
|
||||
if (mapper == 4) { // Check for MMC6/MMC3
|
||||
checkMMC6();
|
||||
if (mmc6)
|
||||
ram = 1; // 1K
|
||||
}
|
||||
printNESSettings();
|
||||
}
|
||||
|
||||
void getMapping() {
|
||||
FsFile database;
|
||||
uint32_t oldcrc32 = 0xFFFFFFFF;
|
||||
@ -590,143 +653,15 @@ void getMapping() {
|
||||
}
|
||||
}
|
||||
if (browseDatabase) {
|
||||
uint8_t fastScrolling = 1;
|
||||
struct database_entry entry;
|
||||
|
||||
// Display database
|
||||
while (database.available()) {
|
||||
#ifdef ENABLE_GLOBAL_LOG
|
||||
// Disable log to prevent unnecessary logging
|
||||
dont_log = true;
|
||||
#endif
|
||||
|
||||
uint8_t iNES[16];
|
||||
uint8_t* output;
|
||||
char* input;
|
||||
|
||||
struct database_entry entry;
|
||||
display_Clear();
|
||||
readDatabaseEntry(database, &entry);
|
||||
|
||||
input = entry.iNES_str;
|
||||
output = iNES;
|
||||
for (uint8_t i = 0; i < sizeof(iNES); i++) {
|
||||
unsigned int buf;
|
||||
|
||||
sscanf(input, "%2X", &buf);
|
||||
*(output++) = buf;
|
||||
input += 2;
|
||||
}
|
||||
|
||||
mapper = (iNES[6] >> 4) | (iNES[7] & 0xF0) | (iNES[8] & 0x0F);
|
||||
|
||||
if ((iNES[9] & 0x0F) != 0x0F) {
|
||||
// simple notation
|
||||
prgsize = (iNES[4] | ((iNES[9] & 0x0F) << 8)); //*16
|
||||
} else {
|
||||
// exponent-multiplier notation
|
||||
prgsize = (((1 << (iNES[4] >> 2)) * ((iNES[4] & 0b11) * 2 + 1)) >> 14); //*16
|
||||
}
|
||||
if (prgsize != 0)
|
||||
prgsize = (int(log(prgsize) / log(2)));
|
||||
|
||||
if ((iNES[9] & 0xF0) != 0xF0) {
|
||||
// simple notation
|
||||
chrsize = (uppow2(iNES[5] | ((iNES[9] & 0xF0) << 4))) * 2; //*4
|
||||
} else {
|
||||
// exponent-multiplier notation
|
||||
chrsize = (((1 << (iNES[5] >> 2)) * ((iNES[5] & 0b11) * 2 + 1)) >> 13) * 2; //*4
|
||||
}
|
||||
if (chrsize != 0)
|
||||
chrsize = (int(log(chrsize) / log(2)));
|
||||
|
||||
ramsize = ((iNES[10] & 0xF0) ? (64 << ((iNES[10] & 0xF0) >> 4)) : 0) / 4096; //*4
|
||||
if (ramsize != 0)
|
||||
ramsize = (int(log(ramsize) / log(2)));
|
||||
|
||||
prg = (int_pow(2, prgsize)) * 16;
|
||||
if (chrsize == 0)
|
||||
chr = 0; // 0K
|
||||
else
|
||||
chr = (int_pow(2, chrsize)) * 4;
|
||||
if (ramsize == 0)
|
||||
ram = 0; // 0K
|
||||
else if (mapper == 82)
|
||||
ram = 5; // 5K
|
||||
else
|
||||
ram = (int_pow(2, ramsize)) * 4;
|
||||
|
||||
// Mapper Variants
|
||||
// Identify variant for use across multiple functions
|
||||
if (mapper == 4) { // Check for MMC6/MMC3
|
||||
checkMMC6();
|
||||
if (mmc6)
|
||||
ram = 1; // 1K
|
||||
}
|
||||
|
||||
println_Msg(entry.filename);
|
||||
printNESSettings();
|
||||
#if defined(ENABLE_OLED)
|
||||
print_STR(press_to_change_STR, 0);
|
||||
if (fastScrolling > 1)
|
||||
println_Msg(F(" (fast)"));
|
||||
else
|
||||
println_Msg("");
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(ENABLE_LCD)
|
||||
print_STR(rotate_to_change_STR, 0);
|
||||
if (fastScrolling > 1)
|
||||
println_Msg(F(" (fast)"));
|
||||
else
|
||||
println_Msg("");
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#elif defined(SERIAL_MONITOR)
|
||||
println_Msg(F("U/D to Change"));
|
||||
println_Msg(F("Space to Select"));
|
||||
#endif
|
||||
display_Update();
|
||||
|
||||
#ifdef ENABLE_GLOBAL_LOG
|
||||
// Enable log again
|
||||
dont_log = false;
|
||||
#endif
|
||||
uint8_t b = 0;
|
||||
do {
|
||||
b = checkButton();
|
||||
} while (b == 0);
|
||||
|
||||
if (b == 1) {
|
||||
// 1: Next record
|
||||
if (fastScrolling > 1) {
|
||||
for (uint8_t skipped = 0; skipped < fastScrolling * 3; skipped++) {
|
||||
skip_line(&database);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (b == 2) {
|
||||
// 2: Previous record
|
||||
if (fastScrolling > 1)
|
||||
rewind_line(database, fastScrolling * 3 + 3);
|
||||
else
|
||||
rewind_line(database, 6);
|
||||
continue;
|
||||
}
|
||||
if (b == 4) {
|
||||
// 4: Toggle Fast Scrolling
|
||||
if (fastScrolling == 1)
|
||||
fastScrolling = 30;
|
||||
else
|
||||
fastScrolling = 1;
|
||||
continue;
|
||||
}
|
||||
if(checkCartSelection(database, &readDataLine_NES, &entry, &printDataLine_NES, &setRomnameFromString)) {
|
||||
// anything else: select current record
|
||||
setRomnameFromString(entry.filename);
|
||||
// Save Mapper
|
||||
EEPROM_writeAnything(7, mapper);
|
||||
EEPROM_writeAnything(8, prgsize);
|
||||
EEPROM_writeAnything(9, chrsize);
|
||||
EEPROM_writeAnything(10, ramsize);
|
||||
break;
|
||||
}
|
||||
}
|
||||
database.close();
|
||||
@ -734,8 +669,12 @@ void getMapping() {
|
||||
|
||||
static void readDatabaseEntry(FsFile& database, struct database_entry* entry) {
|
||||
get_line(entry->filename, &database, sizeof(entry->filename));
|
||||
get_line(entry->crc_str, &database, sizeof(entry->crc_str));
|
||||
readDataLine_NES(database, entry);
|
||||
skip_line(&database);
|
||||
}
|
||||
|
||||
void readDataLine_NES(FsFile& database, struct database_entry* entry) {
|
||||
get_line(entry->crc_str, &database, sizeof(entry->crc_str));
|
||||
|
||||
entry->crc_str[8] = 0;
|
||||
entry->crc512_str = &entry->crc_str[8 + 1];
|
||||
|
@ -378,14 +378,57 @@ void checkStatus_WSV() {
|
||||
//******************************************
|
||||
// CART SELECT CODE
|
||||
//******************************************
|
||||
void setCart_WSV() {
|
||||
char gamename[100];
|
||||
char tempStr2[2];
|
||||
struct database_entry_WSV {
|
||||
char crc_search[9];
|
||||
byte gameSize;
|
||||
};
|
||||
|
||||
void readDataLine_WSV(FsFile& database, struct database_entry_WSV* entry) {
|
||||
char tempStr2[2];
|
||||
|
||||
// Read CRC32 checksum
|
||||
sprintf(checksumStr, "%c", database.read());
|
||||
for (byte i = 0; i < 7; i++) {
|
||||
sprintf(tempStr2, "%c", database.read());
|
||||
strcat(checksumStr, tempStr2);
|
||||
}
|
||||
|
||||
// Skip over semicolon
|
||||
database.seekCur(1);
|
||||
|
||||
// Read CRC32 of first 512 bytes
|
||||
sprintf(entry->crc_search, "%c", database.read());
|
||||
for (byte i = 0; i < 7; i++) {
|
||||
sprintf(tempStr2, "%c", database.read());
|
||||
strcat(entry->crc_search, tempStr2);
|
||||
}
|
||||
|
||||
// Skip over semicolon
|
||||
database.seekCur(1);
|
||||
|
||||
// Read rom size
|
||||
// Read the next ascii character and subtract 48 to convert to decimal
|
||||
entry->gameSize = ((database.read() - 48) * 10) + (database.read() - 48);
|
||||
|
||||
// Skip rest of line
|
||||
database.seekCur(2);
|
||||
}
|
||||
|
||||
void printDataLine_WSV(struct database_entry_WSV* entry) {
|
||||
print_Msg(F("Size: "));
|
||||
if (entry->gameSize == 51)
|
||||
print_Msg(F("512"));
|
||||
else
|
||||
print_Msg(entry->gameSize);
|
||||
println_Msg(F("KB"));
|
||||
}
|
||||
|
||||
void setCart_WSV() {
|
||||
//go to root
|
||||
sd.chdir();
|
||||
|
||||
struct database_entry_WSV entry;
|
||||
|
||||
// Select starting letter
|
||||
byte myLetter = starting_letter();
|
||||
|
||||
@ -393,109 +436,22 @@ void setCart_WSV() {
|
||||
if (myFile.open("wsv.txt", O_READ)) {
|
||||
seek_first_letter_in_database(myFile, myLetter);
|
||||
|
||||
// Display database
|
||||
while (myFile.available()) {
|
||||
display_Clear();
|
||||
if(checkCartSelection(myFile, &readDataLine_WSV, &entry, &printDataLine_WSV)) {
|
||||
//word WSV[] = {32,64,512};
|
||||
switch (entry.gameSize) {
|
||||
case 32:
|
||||
wsvsize = 0;
|
||||
break;
|
||||
|
||||
// Read game name
|
||||
get_line(gamename, &myFile, 96);
|
||||
case 64:
|
||||
wsvsize = 1;
|
||||
break;
|
||||
|
||||
// Read CRC32 checksum
|
||||
sprintf(checksumStr, "%c", myFile.read());
|
||||
for (byte i = 0; i < 7; i++) {
|
||||
sprintf(tempStr2, "%c", myFile.read());
|
||||
strcat(checksumStr, tempStr2);
|
||||
}
|
||||
|
||||
// Skip over semicolon
|
||||
myFile.seekCur(1);
|
||||
|
||||
// Read CRC32 of first 512 bytes
|
||||
sprintf(crc_search, "%c", myFile.read());
|
||||
for (byte i = 0; i < 7; i++) {
|
||||
sprintf(tempStr2, "%c", myFile.read());
|
||||
strcat(crc_search, tempStr2);
|
||||
}
|
||||
|
||||
// Skip over semicolon
|
||||
myFile.seekCur(1);
|
||||
|
||||
// Read rom size
|
||||
// Read the next ascii character and subtract 48 to convert to decimal
|
||||
cartSize = myFile.read() - 48;
|
||||
|
||||
// Remove leading 0 for single digit cart sizes
|
||||
if (cartSize != 0) {
|
||||
cartSize = cartSize * 10 + myFile.read() - 48;
|
||||
} else {
|
||||
cartSize = myFile.read() - 48;
|
||||
}
|
||||
|
||||
// Skip rest of line
|
||||
myFile.seekCur(2);
|
||||
|
||||
// Skip every 3rd line
|
||||
skip_line(&myFile);
|
||||
|
||||
println_Msg(F("Select your cartridge"));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
println_Msg(gamename);
|
||||
print_Msg(F("Size: "));
|
||||
if (cartSize == 51)
|
||||
print_Msg(F("512"));
|
||||
else
|
||||
print_Msg(cartSize);
|
||||
println_Msg(F("KB"));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
#if defined(ENABLE_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(ENABLE_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#elif defined(SERIAL_MONITOR)
|
||||
println_Msg(F("U/D to Change"));
|
||||
println_Msg(F("Space to Select"));
|
||||
#endif
|
||||
display_Update();
|
||||
|
||||
uint8_t b = 0;
|
||||
while (1) {
|
||||
// Check button input
|
||||
b = checkButton();
|
||||
|
||||
// Next
|
||||
if (b == 1) {
|
||||
case 51:
|
||||
wsvsize = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
// Previous
|
||||
else if (b == 2) {
|
||||
rewind_line(myFile, 6);
|
||||
break;
|
||||
}
|
||||
|
||||
// Selection
|
||||
else if (b == 3) {
|
||||
//word WSV[] = {32,64,512};
|
||||
switch (cartSize) {
|
||||
case 32:
|
||||
wsvsize = 0;
|
||||
break;
|
||||
|
||||
case 64:
|
||||
wsvsize = 1;
|
||||
break;
|
||||
|
||||
case 51:
|
||||
wsvsize = 2;
|
||||
break;
|
||||
}
|
||||
EEPROM_writeAnything(8, wsvsize);
|
||||
myFile.close();
|
||||
break;
|
||||
}
|
||||
}
|
||||
EEPROM_writeAnything(8, wsvsize);
|
||||
}
|
||||
} else {
|
||||
print_FatalError(F("Database file not found"));
|
||||
|
Loading…
Reference in New Issue
Block a user