mirror of
https://github.com/wavemotion-dave/GimliDS.git
synced 2025-06-18 13:55:32 -04:00
913 lines
29 KiB
C++
913 lines
29 KiB
C++
// =====================================================================================
|
|
// GimliDS Copyright (c) 2025 Dave Bernazzani (wavemotion-dave)
|
|
//
|
|
// As GimliDS is a port of the Frodo emulator for the DS/DSi/XL/LL handhelds,
|
|
// any copying or distribution of this emulator, its source code and associated
|
|
// readme files, with or without modification, are permitted per the original
|
|
// Frodo emulator license shown below. Hugest thanks to Christian Bauer for his
|
|
// efforts to provide a clean open-source emulation base for the C64.
|
|
//
|
|
// Numerous hacks and 'unsafe' optimizations have been performed on the original
|
|
// Frodo emulator codebase to get it running on the small handheld system. You
|
|
// are strongly encouraged to seek out the official Frodo sources if you're at
|
|
// all interested in this emulator code.
|
|
//
|
|
// The GimliDS emulator is offered as-is, without any warranty. Please see readme.md
|
|
// =====================================================================================
|
|
|
|
// Diskette Menu Loading Code
|
|
|
|
#include <nds.h>
|
|
#include <fat.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
|
|
#include <sys/stat.h>
|
|
#include <sys/dir.h>
|
|
#include "diskmenu.h"
|
|
#include "Display.h"
|
|
#include "mainmenu.h"
|
|
#include "keyboard.h"
|
|
#include "mainmenu_bg.h"
|
|
#include "diskmenu_bg.h"
|
|
#include "cartmenu_bg.h"
|
|
#include "Prefs.h"
|
|
#include "C64.h"
|
|
#include "printf.h"
|
|
|
|
char Drive8File[MAX_FILENAME_LEN];
|
|
char Drive9File[MAX_FILENAME_LEN];
|
|
char CartFilename[MAX_FILENAME_LEN];
|
|
|
|
extern int bg0b, bg1b;
|
|
int diskCount=0;
|
|
int diskGameAct=0;
|
|
int diskGameChoice = -1;
|
|
FIC64 gpFic[MAX_FILES];
|
|
char szName[256];
|
|
char szFile[256];
|
|
u32 file_size = 0;
|
|
char strBuf[40];
|
|
u8 bLastFileTypeLoaded = 0;
|
|
|
|
#define WAITVBL swiWaitForVBlank();swiWaitForVBlank();swiWaitForVBlank();
|
|
|
|
extern u8 bDebugDisplay;
|
|
|
|
/*********************************************************************************
|
|
* Show The 14 games on the list to allow the user to choose a new game.
|
|
********************************************************************************/
|
|
static char szName2[40];
|
|
void dsDisplayFiles(u16 NoDebGame, u8 ucSel)
|
|
{
|
|
u16 ucBcl,ucGame;
|
|
u8 maxLen;
|
|
|
|
DSPrint(31,5,0,(NoDebGame>0 ? (char*)"<" : (char*)" "));
|
|
DSPrint(31,22,0,(NoDebGame+14<diskCount ? (char*)">" : (char*)" "));
|
|
|
|
for (ucBcl=0;ucBcl<18; ucBcl++)
|
|
{
|
|
ucGame= ucBcl+NoDebGame;
|
|
if (ucGame < diskCount)
|
|
{
|
|
maxLen=(int)strlen(gpFic[ucGame].szName);
|
|
strcpy(szName,gpFic[ucGame].szName);
|
|
if (maxLen>30) szName[30]='\0';
|
|
if (gpFic[ucGame].uType == DIRECTORY)
|
|
{
|
|
szName[28] = 0; // Needs to be 2 chars shorter with brackets
|
|
sprintf(szName2, "[%s]",szName);
|
|
sprintf(szName,"%-30s",szName2);
|
|
DSPrint(1,5+ucBcl,(ucSel == ucBcl ? 2 : 0),szName);
|
|
}
|
|
else
|
|
{
|
|
sprintf(szName,"%-30s",strupr(szName));
|
|
DSPrint(1,5+ucBcl,(ucSel == ucBcl ? 2 : 0 ),szName);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DSPrint(1,5+ucBcl,(ucSel == ucBcl ? 2 : 0 ),(char *)" ");
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// -------------------------------------------------------------------------
|
|
// Standard qsort routine for the games - we sort all directory
|
|
// listings first and then a case-insenstive sort of all games.
|
|
// -------------------------------------------------------------------------
|
|
int Filescmp (const void *c1, const void *c2)
|
|
{
|
|
FIC64 *p1 = (FIC64 *) c1;
|
|
FIC64 *p2 = (FIC64 *) c2;
|
|
|
|
if (p1->szName[0] == '.' && p2->szName[0] != '.')
|
|
return -1;
|
|
if (p2->szName[0] == '.' && p1->szName[0] != '.')
|
|
return 1;
|
|
if ((p1->uType == DIRECTORY) && !(p2->uType == DIRECTORY))
|
|
return -1;
|
|
if ((p2->uType == DIRECTORY) && !(p1->uType == DIRECTORY))
|
|
return 1;
|
|
return strcasecmp (p1->szName, p2->szName);
|
|
}
|
|
|
|
/*********************************************************************************
|
|
* Find files (TAP/TZX/Z80/SNA) available - sort them for display.
|
|
********************************************************************************/
|
|
void gimliDSFindFiles(u8 bCartOnly)
|
|
{
|
|
u32 uNbFile;
|
|
DIR *dir;
|
|
struct dirent *pent;
|
|
|
|
uNbFile=0;
|
|
diskCount=0;
|
|
|
|
dir = opendir(".");
|
|
while (((pent=readdir(dir))!=NULL) && (uNbFile<MAX_FILES))
|
|
{
|
|
strcpy(szFile,pent->d_name);
|
|
|
|
if(pent->d_type == DT_DIR)
|
|
{
|
|
if (!((szFile[0] == '.') && ((int)strlen(szFile) == 1)))
|
|
{
|
|
// Do not include the [sav] and [pok] directories
|
|
if ((strcasecmp(szFile, "sav") != 0))
|
|
{
|
|
strcpy(gpFic[uNbFile].szName,szFile);
|
|
gpFic[uNbFile].uType = DIRECTORY;
|
|
uNbFile++;
|
|
diskCount++;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
if ((strlen(szFile)>4) && (strlen(szFile)<(MAX_FILENAME_LEN-4)) && (szFile[0] != '.') && (szFile[0] != '_')) // For MAC don't allow files starting with an underscore
|
|
{
|
|
if (bCartOnly)
|
|
{
|
|
if ( (strcasecmp(strrchr(szFile, '.'), ".CRT") == 0) )
|
|
{
|
|
strcpy(gpFic[uNbFile].szName,szFile);
|
|
gpFic[uNbFile].uType = NORMALFILE;
|
|
uNbFile++;
|
|
diskCount++;
|
|
}
|
|
|
|
if ( (strcasecmp(strrchr(szFile, '.'), ".PRG") == 0) )
|
|
{
|
|
strcpy(gpFic[uNbFile].szName,szFile);
|
|
gpFic[uNbFile].uType = NORMALFILE;
|
|
uNbFile++;
|
|
diskCount++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( (strcasecmp(strrchr(szFile, '.'), ".D64") == 0) )
|
|
{
|
|
strcpy(gpFic[uNbFile].szName,szFile);
|
|
gpFic[uNbFile].uType = NORMALFILE;
|
|
uNbFile++;
|
|
diskCount++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
closedir(dir);
|
|
|
|
// ----------------------------------------------
|
|
// If we found any files, go sort the list...
|
|
// ----------------------------------------------
|
|
if (diskCount)
|
|
{
|
|
qsort (gpFic, diskCount, sizeof(FIC64), Filescmp);
|
|
}
|
|
}
|
|
|
|
// ----------------------------------------------------------------
|
|
// Let the user select a new game (rom) file and load it up!
|
|
// ----------------------------------------------------------------
|
|
u8 gimliDSLoadFile(u8 bCartOnly)
|
|
{
|
|
bool bDone=false;
|
|
u16 ucHaut=0x00, ucBas=0x00,ucSHaut=0x00, ucSBas=0x00, romSelected= 0, firstRomDisplay=0,nbRomPerPage, uNbRSPage;
|
|
s16 uLenFic=0, ucFlip=0, ucFlop=0;
|
|
u8 retVal = 0;
|
|
|
|
if (bLastFileTypeLoaded != bCartOnly)
|
|
{
|
|
diskCount=0;
|
|
diskGameAct=0;
|
|
}
|
|
|
|
// Show the menu...
|
|
while ((keysCurrent() & (KEY_TOUCH | KEY_START | KEY_SELECT | KEY_A | KEY_B))!=0)
|
|
{
|
|
currentBrightness = 0;
|
|
}
|
|
|
|
gimliDSFindFiles(bCartOnly);
|
|
|
|
diskGameChoice = -1;
|
|
|
|
nbRomPerPage = (diskCount>=18 ? 18 : diskCount);
|
|
uNbRSPage = (diskCount>=5 ? 5 : diskCount);
|
|
|
|
if (diskGameAct>diskCount-nbRomPerPage)
|
|
{
|
|
firstRomDisplay=diskCount-nbRomPerPage;
|
|
romSelected=diskGameAct-diskCount+nbRomPerPage;
|
|
}
|
|
else
|
|
{
|
|
firstRomDisplay=diskGameAct;
|
|
romSelected=0;
|
|
}
|
|
|
|
if (romSelected >= diskCount) romSelected = 0; // Just start at the top
|
|
|
|
dsDisplayFiles(firstRomDisplay,romSelected);
|
|
|
|
// -----------------------------------------------------
|
|
// Until the user selects a file or exits the menu...
|
|
// -----------------------------------------------------
|
|
while (!bDone)
|
|
{
|
|
currentBrightness = 0;
|
|
if (keysCurrent() & KEY_UP)
|
|
{
|
|
if (!ucHaut)
|
|
{
|
|
diskGameAct = (diskGameAct>0 ? diskGameAct-1 : diskCount-1);
|
|
if (romSelected>uNbRSPage) { romSelected -= 1; }
|
|
else {
|
|
if (firstRomDisplay>0) { firstRomDisplay -= 1; }
|
|
else {
|
|
if (romSelected>0) { romSelected -= 1; }
|
|
else {
|
|
firstRomDisplay=diskCount-nbRomPerPage;
|
|
romSelected=nbRomPerPage-1;
|
|
}
|
|
}
|
|
}
|
|
ucHaut=0x01;
|
|
dsDisplayFiles(firstRomDisplay,romSelected);
|
|
}
|
|
else {
|
|
|
|
ucHaut++;
|
|
if (ucHaut>10) ucHaut=0;
|
|
}
|
|
uLenFic=0; ucFlip=-50; ucFlop=0;
|
|
}
|
|
else
|
|
{
|
|
ucHaut = 0;
|
|
}
|
|
if (keysCurrent() & KEY_DOWN)
|
|
{
|
|
if (!ucBas) {
|
|
diskGameAct = (diskGameAct< diskCount-1 ? diskGameAct+1 : 0);
|
|
if (romSelected<uNbRSPage-1) { romSelected += 1; }
|
|
else {
|
|
if (firstRomDisplay<diskCount-nbRomPerPage) { firstRomDisplay += 1; }
|
|
else {
|
|
if (romSelected<nbRomPerPage-1) { romSelected += 1; }
|
|
else {
|
|
firstRomDisplay=0;
|
|
romSelected=0;
|
|
}
|
|
}
|
|
}
|
|
ucBas=0x01;
|
|
dsDisplayFiles(firstRomDisplay,romSelected);
|
|
}
|
|
else
|
|
{
|
|
ucBas++;
|
|
if (ucBas>10) ucBas=0;
|
|
}
|
|
uLenFic=0; ucFlip=-50; ucFlop=0;
|
|
}
|
|
else {
|
|
ucBas = 0;
|
|
}
|
|
|
|
// -------------------------------------------------------------
|
|
// Left and Right on the D-Pad will scroll 1 page at a time...
|
|
// -------------------------------------------------------------
|
|
if (keysCurrent() & KEY_RIGHT)
|
|
{
|
|
if (!ucSBas)
|
|
{
|
|
diskGameAct = (diskGameAct< diskCount-nbRomPerPage ? diskGameAct+nbRomPerPage : diskCount-nbRomPerPage);
|
|
if (firstRomDisplay<diskCount-nbRomPerPage) { firstRomDisplay += nbRomPerPage; }
|
|
else { firstRomDisplay = diskCount-nbRomPerPage; }
|
|
if (diskGameAct == diskCount-nbRomPerPage) romSelected = 0;
|
|
ucSBas=0x01;
|
|
dsDisplayFiles(firstRomDisplay,romSelected);
|
|
}
|
|
else
|
|
{
|
|
ucSBas++;
|
|
if (ucSBas>10) ucSBas=0;
|
|
}
|
|
uLenFic=0; ucFlip=-50; ucFlop=0;
|
|
}
|
|
else {
|
|
ucSBas = 0;
|
|
}
|
|
|
|
// -------------------------------------------------------------
|
|
// Left and Right on the D-Pad will scroll 1 page at a time...
|
|
// -------------------------------------------------------------
|
|
if (keysCurrent() & KEY_LEFT)
|
|
{
|
|
if (!ucSHaut)
|
|
{
|
|
diskGameAct = (diskGameAct> nbRomPerPage ? diskGameAct-nbRomPerPage : 0);
|
|
if (firstRomDisplay>nbRomPerPage) { firstRomDisplay -= nbRomPerPage; }
|
|
else { firstRomDisplay = 0; }
|
|
if (diskGameAct == 0) romSelected = 0;
|
|
if (romSelected > diskGameAct) romSelected = diskGameAct;
|
|
ucSHaut=0x01;
|
|
dsDisplayFiles(firstRomDisplay,romSelected);
|
|
}
|
|
else
|
|
{
|
|
ucSHaut++;
|
|
if (ucSHaut>10) ucSHaut=0;
|
|
}
|
|
uLenFic=0; ucFlip=-50; ucFlop=0;
|
|
}
|
|
else {
|
|
ucSHaut = 0;
|
|
}
|
|
|
|
// -------------------------------------------------------------------------
|
|
// They B key will exit out of the ROM selection without picking a new game
|
|
// -------------------------------------------------------------------------
|
|
if ( keysCurrent() & KEY_B )
|
|
{
|
|
bDone=true;
|
|
retVal = 0;
|
|
while (keysCurrent() & KEY_B);
|
|
}
|
|
|
|
// -------------------------------------------------------------------
|
|
// Any of these keys will pick the current ROM and try to load it...
|
|
// -------------------------------------------------------------------
|
|
if (keysCurrent() & KEY_A || keysCurrent() & KEY_Y || keysCurrent() & KEY_X)
|
|
{
|
|
if (gpFic[diskGameAct].uType != DIRECTORY)
|
|
{
|
|
bDone=true;
|
|
if (keysCurrent() & KEY_X) retVal = 2; else retVal = 1;
|
|
if (keysCurrent() & KEY_Y) bDebugDisplay = 1; else bDebugDisplay = 0;
|
|
diskGameChoice = diskGameAct;
|
|
WAITVBL;
|
|
}
|
|
else
|
|
{
|
|
chdir(gpFic[diskGameAct].szName);
|
|
gimliDSFindFiles(bCartOnly);
|
|
diskGameAct = 0;
|
|
nbRomPerPage = (diskCount>=14 ? 14 : diskCount);
|
|
uNbRSPage = (diskCount>=5 ? 5 : diskCount);
|
|
if (diskGameAct>diskCount-nbRomPerPage) {
|
|
firstRomDisplay=diskCount-nbRomPerPage;
|
|
romSelected=diskGameAct-diskCount+nbRomPerPage;
|
|
}
|
|
else {
|
|
firstRomDisplay=diskGameAct;
|
|
romSelected=0;
|
|
}
|
|
dsDisplayFiles(firstRomDisplay,romSelected);
|
|
while (keysCurrent() & KEY_A);
|
|
}
|
|
}
|
|
|
|
// --------------------------------------------
|
|
// If the filename is too long... scroll it.
|
|
// --------------------------------------------
|
|
if ((int)strlen(gpFic[diskGameAct].szName) > 30)
|
|
{
|
|
ucFlip++;
|
|
if (ucFlip >= 25)
|
|
{
|
|
ucFlip = 0;
|
|
uLenFic++;
|
|
if ((uLenFic+30)>(int)strlen(gpFic[diskGameAct].szName))
|
|
{
|
|
ucFlop++;
|
|
if (ucFlop >= 15)
|
|
{
|
|
uLenFic=0;
|
|
ucFlop = 0;
|
|
}
|
|
else
|
|
uLenFic--;
|
|
}
|
|
strncpy(szName,gpFic[diskGameAct].szName+uLenFic,30);
|
|
szName[30] = '\0';
|
|
DSPrint(1,5+romSelected,2,szName);
|
|
}
|
|
}
|
|
swiWaitForVBlank();
|
|
}
|
|
|
|
// Wait for some key to be pressed before returning
|
|
while ((keysCurrent() & (KEY_TOUCH | KEY_START | KEY_SELECT | KEY_A | KEY_B | KEY_R | KEY_L | KEY_UP | KEY_DOWN))!=0);
|
|
|
|
return retVal;
|
|
}
|
|
|
|
u16 nds_key;
|
|
|
|
void LoadGameConfig(void)
|
|
{
|
|
// Cart overrides disk...
|
|
if (strlen(CartFilename) > 1)
|
|
{
|
|
file_crc = getCRC32((u8*)CartFilename, strlen(CartFilename));
|
|
FindConfig();
|
|
}
|
|
else if (strlen(Drive8File) > 1)
|
|
{
|
|
file_crc = getCRC32((u8*)Drive8File, strlen(Drive8File));
|
|
FindConfig();
|
|
}
|
|
}
|
|
|
|
void BottomScreenDiskette(void)
|
|
{
|
|
decompress(diskmenu_bgTiles, bgGetGfxPtr(bg0b), LZ77Vram);
|
|
decompress(diskmenu_bgMap, (void*) bgGetMapPtr(bg0b), LZ77Vram);
|
|
dmaCopy((void*) bgGetMapPtr(bg0b)+32*30*2,(void*) bgGetMapPtr(bg1b),32*24*2);
|
|
dmaCopy((void*) diskmenu_bgPal,(void*) BG_PALETTE_SUB,256*2);
|
|
unsigned short dmaVal = *(bgGetMapPtr(bg1b)+24*32);
|
|
dmaFillWords(dmaVal | (dmaVal<<16),(void*) bgGetMapPtr(bg1b),32*24*2);
|
|
}
|
|
|
|
void BottomScreenCartridge(void)
|
|
{
|
|
decompress(cartmenu_bgTiles, bgGetGfxPtr(bg0b), LZ77Vram);
|
|
decompress(cartmenu_bgMap, (void*) bgGetMapPtr(bg0b), LZ77Vram);
|
|
dmaCopy((void*) bgGetMapPtr(bg0b)+32*30*2,(void*) bgGetMapPtr(bg1b),32*24*2);
|
|
dmaCopy((void*) cartmenu_bgPal,(void*) BG_PALETTE_SUB,256*2);
|
|
unsigned short dmaVal = *(bgGetMapPtr(bg1b)+24*32);
|
|
dmaFillWords(dmaVal | (dmaVal<<16),(void*) bgGetMapPtr(bg1b),32*24*2);
|
|
}
|
|
|
|
void BottomScreenMainMenu(void)
|
|
{
|
|
decompress(mainmenu_bgTiles, bgGetGfxPtr(bg0b), LZ77Vram);
|
|
decompress(mainmenu_bgMap, (void*) bgGetMapPtr(bg0b), LZ77Vram);
|
|
dmaCopy((void*) bgGetMapPtr(bg0b)+32*30*2,(void*) bgGetMapPtr(bg1b),32*24*2);
|
|
dmaCopy((void*) mainmenu_bgPal,(void*) BG_PALETTE_SUB,256*2);
|
|
unsigned short dmaVal = *(bgGetMapPtr(bg1b)+24*32);
|
|
dmaFillWords(dmaVal | (dmaVal<<16),(void*) bgGetMapPtr(bg1b),32*24*2);
|
|
}
|
|
|
|
void DisplayFileNameDiskette(void)
|
|
{
|
|
char tmp[34];
|
|
|
|
DSPrint(5,6,6, (char*)" ");
|
|
DSPrint(5,10,6, (char*)" ");
|
|
if (strlen(Drive8File) > 1)
|
|
{
|
|
DSPrint(5,5,6, (char *)"DRIVE 8 IS MOUNTED WITH:");
|
|
strncpy(tmp, Drive8File, 27); tmp[26]=0;
|
|
DSPrint(5,6,6, tmp);
|
|
}
|
|
else
|
|
{
|
|
DSPrint(5,5,6, (char *)"DRIVE 8 IS NOT MOUNTED ");
|
|
}
|
|
|
|
if (strlen(Drive9File) > 1)
|
|
{
|
|
DSPrint(5,9,6, (char *)"DRIVE 9 IS MOUNTED WITH:");
|
|
strncpy(tmp, Drive9File, 27); tmp[26]=0;
|
|
DSPrint(5,10,6, tmp);
|
|
}
|
|
else
|
|
{
|
|
DSPrint(5,9,6, (char *)"DRIVE 9 IS NOT MOUNTED ");
|
|
}
|
|
|
|
if (myConfig.trueDrive)
|
|
{
|
|
DSPrint(0,22,6, (char *)" TRUE DRIVE IS ENABLED (SLOW) ");
|
|
}
|
|
else
|
|
{
|
|
DSPrint(0,22,6, (char *)" TRUE DRIVE IS DISABLED (FAST) ");
|
|
}
|
|
}
|
|
|
|
void DisplayFileNameCartridge(void)
|
|
{
|
|
char tmp[34];
|
|
|
|
DSPrint(7,5,6, (char*)" ");
|
|
DSPrint(7,7,6, (char*)" ");
|
|
if (strlen(CartFilename) > 1)
|
|
{
|
|
DSPrint(7,5,6, (char *)"CARTRIDGE IS MOUNTED AS:");
|
|
strncpy(tmp, CartFilename, 25); tmp[24]=0;
|
|
DSPrint(7,7,6, tmp);
|
|
}
|
|
else
|
|
{
|
|
DSPrint(7,5,6, (char *)"CARTRIDGE IS NOT MOUNTED");
|
|
}
|
|
}
|
|
|
|
// ----------------------------------------------------------------------
|
|
// The Disk Menu can be called up directly from the keyboard graphic
|
|
// and allows the user to rewind the tape, swap in a new tape, etc.
|
|
// ----------------------------------------------------------------------
|
|
#define MENU_ACTION_END 255 // Always the last sentinal value
|
|
#define MENU_ACTION_EXIT 0 // Exit the menu
|
|
#define MENU_ACTION_DRIVE8 1 // Mount Drive 8 File
|
|
#define MENU_ACTION_DRIVE9 2 // Mount Drive 9 File
|
|
#define MENU_ACTION_EJECT 3 // Eject all drives
|
|
#define MENU_ACTION_REBOOT_C64 4 // Force C64 Reboot
|
|
#define MENU_ACTION_TRUE_DRIVE 5 // Toggle True Drive
|
|
#define MENU_ACTION_CONFIG 6 // Configure Game
|
|
|
|
#define MENU_ACTION_INSERT_CART 10
|
|
#define MENU_ACTION_REMOVE_CART 11
|
|
|
|
#define MENU_ACTION_SKIP 99 // Skip this MENU choice
|
|
|
|
typedef struct
|
|
{
|
|
char *menu_string;
|
|
u8 menu_action;
|
|
} MenuItem_t;
|
|
|
|
typedef struct
|
|
{
|
|
char *title;
|
|
u8 start_row;
|
|
MenuItem_t menulist[15];
|
|
} DiskMenu_t;
|
|
|
|
DiskMenu_t disk_menu =
|
|
{
|
|
(char *)" ", 10,
|
|
{
|
|
{(char *)" MOUNT DISK 8 ", MENU_ACTION_DRIVE8},
|
|
{(char *)" MOUNT DISK 9 ", MENU_ACTION_DRIVE9},
|
|
{(char *)" EJECT DISKS ", MENU_ACTION_EJECT},
|
|
{(char *)" TOGGLE TRUEDRIVE ", MENU_ACTION_TRUE_DRIVE},
|
|
{(char *)" CONFIG GAME ", MENU_ACTION_CONFIG},
|
|
{(char *)" RESET C64 ", MENU_ACTION_REBOOT_C64},
|
|
{(char *)" EXIT MENU ", MENU_ACTION_EXIT},
|
|
{(char *)" NULL ", MENU_ACTION_END},
|
|
},
|
|
};
|
|
|
|
DiskMenu_t cart_menu =
|
|
{
|
|
(char *)" ", 11,
|
|
{
|
|
{(char *)" INSERT CARTRIDGE ", MENU_ACTION_INSERT_CART},
|
|
{(char *)" REMOVE CARTRIDGE ", MENU_ACTION_REMOVE_CART},
|
|
{(char *)" EXIT MENU ", MENU_ACTION_EXIT},
|
|
{(char *)" NULL ", MENU_ACTION_END},
|
|
},
|
|
};
|
|
|
|
|
|
static DiskMenu_t *menu = &disk_menu;
|
|
|
|
// -------------------------------------------------------
|
|
// Show the Disk Menu text - highlight the selected row.
|
|
// -------------------------------------------------------
|
|
u8 diskette_menu_items = 0;
|
|
void DiskMenuShow(bool bClearScreen, u8 sel)
|
|
{
|
|
diskette_menu_items = 0;
|
|
|
|
if (bClearScreen)
|
|
{
|
|
// -------------------------------------
|
|
// Put up the Diskette menu background
|
|
// -------------------------------------
|
|
BottomScreenDiskette();
|
|
}
|
|
|
|
// ---------------------------------------------------
|
|
// Pick the right context menu based on the machine
|
|
// ---------------------------------------------------
|
|
menu = &disk_menu;
|
|
|
|
// Display the menu title
|
|
DSPrint(15-(strlen(menu->title)/2), menu->start_row, 6, menu->title);
|
|
|
|
// And display all of the menu items
|
|
while (menu->menulist[diskette_menu_items].menu_action != MENU_ACTION_END)
|
|
{
|
|
DSPrint(16-(strlen(menu->menulist[diskette_menu_items].menu_string)/2), menu->start_row+2+diskette_menu_items, (diskette_menu_items == sel) ? 7:6, menu->menulist[diskette_menu_items].menu_string);
|
|
diskette_menu_items++;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------------
|
|
// And near the bottom, display the file/rom/disk that is currently loaded into memory.
|
|
// ----------------------------------------------------------------------------------------------
|
|
DisplayFileNameDiskette();
|
|
}
|
|
|
|
// ------------------------------------------------------------------------
|
|
// Handle Disk mini-menu interface... Allows rewind, swap tape, etc.
|
|
// ------------------------------------------------------------------------
|
|
u8 DisketteMenu(C64 *the_c64)
|
|
{
|
|
u8 menuSelection = 0;
|
|
u8 retVal = 0;
|
|
|
|
while ((keysCurrent() & (KEY_TOUCH | KEY_LEFT | KEY_RIGHT | KEY_A ))!=0);
|
|
|
|
// ------------------------------------------------------------------
|
|
//Show the cassette menu background - we'll draw text on top of this
|
|
// ------------------------------------------------------------------
|
|
DiskMenuShow(true, menuSelection);
|
|
|
|
u8 bExitMenu = false;
|
|
while (true)
|
|
{
|
|
currentBrightness = 0;
|
|
nds_key = keysCurrent();
|
|
if (nds_key)
|
|
{
|
|
if (nds_key & KEY_UP)
|
|
{
|
|
menuSelection = (menuSelection > 0) ? (menuSelection-1):(diskette_menu_items-1);
|
|
while (menu->menulist[menuSelection].menu_action == MENU_ACTION_SKIP)
|
|
{
|
|
menuSelection = (menuSelection > 0) ? (menuSelection-1):(diskette_menu_items-1);
|
|
}
|
|
DiskMenuShow(false, menuSelection);
|
|
}
|
|
if (nds_key & KEY_DOWN)
|
|
{
|
|
menuSelection = (menuSelection+1) % diskette_menu_items;
|
|
while (menu->menulist[menuSelection].menu_action == MENU_ACTION_SKIP)
|
|
{
|
|
menuSelection = (menuSelection+1) % diskette_menu_items;
|
|
}
|
|
DiskMenuShow(false, menuSelection);
|
|
}
|
|
|
|
if (nds_key & KEY_B) // Treat this as selecting 'exit'
|
|
{
|
|
bExitMenu = true;
|
|
}
|
|
else
|
|
if (nds_key & KEY_A) // User has picked a menu item... let's see what it is!
|
|
{
|
|
switch(menu->menulist[menuSelection].menu_action)
|
|
{
|
|
case MENU_ACTION_EXIT:
|
|
bExitMenu = true;
|
|
break;
|
|
|
|
case MENU_ACTION_DRIVE8:
|
|
BottomScreenMainMenu();
|
|
retVal = gimliDSLoadFile(0);
|
|
if (diskGameChoice >= 0)
|
|
{
|
|
retVal = 1;
|
|
strcpy(Drive8File, gpFic[diskGameChoice].szName);
|
|
LoadGameConfig();
|
|
}
|
|
DiskMenuShow(true, menuSelection);
|
|
break;
|
|
|
|
case MENU_ACTION_DRIVE9:
|
|
BottomScreenMainMenu();
|
|
retVal = gimliDSLoadFile(0);
|
|
if (diskGameChoice >= 0)
|
|
{
|
|
retVal = 1;
|
|
strcpy(Drive9File, gpFic[diskGameChoice].szName);
|
|
}
|
|
DiskMenuShow(true, menuSelection);
|
|
break;
|
|
|
|
case MENU_ACTION_EJECT:
|
|
strcpy(Drive8File, "");
|
|
strcpy(Drive9File, "");
|
|
retVal = 1;
|
|
DiskMenuShow(true, menuSelection);
|
|
break;
|
|
|
|
case MENU_ACTION_TRUE_DRIVE:
|
|
myConfig.trueDrive ^= 1;
|
|
DiskMenuShow(true, menuSelection);
|
|
break;
|
|
|
|
case MENU_ACTION_CONFIG:
|
|
if (file_crc != 0x00000000)
|
|
{
|
|
u8 last_trueDrive = myConfig.trueDrive;
|
|
BottomScreenMainMenu();
|
|
GimliDSGameOptions();
|
|
if (last_trueDrive != myConfig.trueDrive) // Need to reload...
|
|
{
|
|
Prefs *prefs = new Prefs(ThePrefs);
|
|
prefs->TrueDrive = myConfig.trueDrive;
|
|
the_c64->NewPrefs(prefs);
|
|
ThePrefs = *prefs;
|
|
delete prefs;
|
|
}
|
|
DiskMenuShow(true, menuSelection);
|
|
}
|
|
else
|
|
{
|
|
DSPrint(0, 20, 6, (char*)" NO GAME IS LOADED ");
|
|
WAITVBL;WAITVBL;WAITVBL;WAITVBL;WAITVBL;WAITVBL;
|
|
WAITVBL;WAITVBL;WAITVBL;WAITVBL;WAITVBL;WAITVBL;
|
|
WAITVBL;WAITVBL;WAITVBL;WAITVBL;WAITVBL;WAITVBL;
|
|
DSPrint(0, 20, 6, (char*)" ");
|
|
}
|
|
break;
|
|
|
|
case MENU_ACTION_REBOOT_C64:
|
|
retVal = 2;
|
|
bExitMenu = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (bExitMenu) break;
|
|
while ((keysCurrent() & (KEY_UP | KEY_DOWN | KEY_A ))!=0);
|
|
WAITVBL;WAITVBL;WAITVBL;
|
|
}
|
|
}
|
|
|
|
while ((keysCurrent() & (KEY_UP | KEY_DOWN | KEY_A ))!=0);
|
|
WAITVBL;WAITVBL;WAITVBL;
|
|
|
|
return retVal;
|
|
}
|
|
|
|
u8 mount_disk(C64 *the_c64)
|
|
{
|
|
strcpy(Drive8File, ThePrefs.DrivePath[0]);
|
|
strcpy(Drive9File, ThePrefs.DrivePath[1]);
|
|
|
|
u8 retVal = DisketteMenu(the_c64);
|
|
|
|
if (retVal) bLastFileTypeLoaded = 0;
|
|
|
|
return retVal;
|
|
}
|
|
|
|
// -------------------------------------------------------
|
|
// Show the Disk Menu text - highlight the selected row.
|
|
// -------------------------------------------------------
|
|
void CartMenuShow(bool bClearScreen, u8 sel)
|
|
{
|
|
diskette_menu_items = 0;
|
|
|
|
if (bClearScreen)
|
|
{
|
|
// -------------------------------------
|
|
// Put up the Cartridge menu background
|
|
// -------------------------------------
|
|
BottomScreenCartridge();
|
|
}
|
|
|
|
// ---------------------------------------------------
|
|
// Pick the right context menu based on the machine
|
|
// ---------------------------------------------------
|
|
menu = &cart_menu;
|
|
|
|
// Display the menu title
|
|
DSPrint(15-(strlen(menu->title)/2), menu->start_row, 6, menu->title);
|
|
|
|
// And display all of the menu items
|
|
while (menu->menulist[diskette_menu_items].menu_action != MENU_ACTION_END)
|
|
{
|
|
DSPrint(16-(strlen(menu->menulist[diskette_menu_items].menu_string)/2), menu->start_row+2+diskette_menu_items, (diskette_menu_items == sel) ? 7:6, menu->menulist[diskette_menu_items].menu_string);
|
|
diskette_menu_items++;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------------
|
|
// And near the bottom, display the file/rom/disk that is currently loaded into memory.
|
|
// ----------------------------------------------------------------------------------------------
|
|
DisplayFileNameCartridge();
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------------
|
|
// Handle Disk mini-menu interface... Allows rewind, swap tape, etc.
|
|
// ------------------------------------------------------------------------
|
|
u8 CartMenu(C64 *the_c64)
|
|
{
|
|
u8 menuSelection = 0;
|
|
u8 retVal = 0;
|
|
|
|
while ((keysCurrent() & (KEY_TOUCH | KEY_LEFT | KEY_RIGHT | KEY_A ))!=0);
|
|
|
|
// ------------------------------------------------------------------
|
|
//Show the cassette menu background - we'll draw text on top of this
|
|
// ------------------------------------------------------------------
|
|
CartMenuShow(true, menuSelection);
|
|
|
|
u8 bExitMenu = false;
|
|
while (true)
|
|
{
|
|
currentBrightness = 0;
|
|
nds_key = keysCurrent();
|
|
if (nds_key)
|
|
{
|
|
if (nds_key & KEY_UP)
|
|
{
|
|
menuSelection = (menuSelection > 0) ? (menuSelection-1):(diskette_menu_items-1);
|
|
while (menu->menulist[menuSelection].menu_action == MENU_ACTION_SKIP)
|
|
{
|
|
menuSelection = (menuSelection > 0) ? (menuSelection-1):(diskette_menu_items-1);
|
|
}
|
|
CartMenuShow(false, menuSelection);
|
|
}
|
|
if (nds_key & KEY_DOWN)
|
|
{
|
|
menuSelection = (menuSelection+1) % diskette_menu_items;
|
|
while (menu->menulist[menuSelection].menu_action == MENU_ACTION_SKIP)
|
|
{
|
|
menuSelection = (menuSelection+1) % diskette_menu_items;
|
|
}
|
|
CartMenuShow(false, menuSelection);
|
|
}
|
|
|
|
if (nds_key & KEY_B) // Treat this as selecting 'exit'
|
|
{
|
|
bExitMenu = true;
|
|
}
|
|
else
|
|
if (nds_key & KEY_A) // User has picked a menu item... let's see what it is!
|
|
{
|
|
switch(menu->menulist[menuSelection].menu_action)
|
|
{
|
|
case MENU_ACTION_EXIT:
|
|
bExitMenu = true;
|
|
break;
|
|
|
|
case MENU_ACTION_INSERT_CART:
|
|
BottomScreenMainMenu();
|
|
retVal = gimliDSLoadFile(1);
|
|
if (diskGameChoice >= 0)
|
|
{
|
|
retVal = 1;
|
|
strcpy(CartFilename, gpFic[diskGameChoice].szName);
|
|
if ( (strcasecmp(strrchr(CartFilename, '.'), ".PRG") == 0) ) retVal = 2;
|
|
LoadGameConfig();
|
|
}
|
|
bExitMenu = true;
|
|
break;
|
|
|
|
case MENU_ACTION_REMOVE_CART:
|
|
BottomScreenMainMenu();
|
|
retVal = 3;
|
|
strcpy(CartFilename, "");
|
|
bExitMenu = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (bExitMenu) break;
|
|
while ((keysCurrent() & (KEY_UP | KEY_DOWN | KEY_A ))!=0);
|
|
WAITVBL;WAITVBL;WAITVBL;
|
|
}
|
|
}
|
|
|
|
while ((keysCurrent() & (KEY_UP | KEY_DOWN | KEY_A ))!=0);
|
|
WAITVBL;WAITVBL;WAITVBL;
|
|
|
|
return retVal;
|
|
}
|
|
|
|
u8 mount_cart(C64 *the_c64)
|
|
{
|
|
u8 retVal = CartMenu(the_c64);
|
|
|
|
if (retVal) bLastFileTypeLoaded = 1;
|
|
|
|
return retVal;
|
|
}
|