diff options
Diffstat (limited to 'source/main.c')
-rw-r--r-- | source/main.c | 358 |
1 files changed, 358 insertions, 0 deletions
diff --git a/source/main.c b/source/main.c new file mode 100644 index 0000000..b41efe6 --- /dev/null +++ b/source/main.c @@ -0,0 +1,358 @@ +/* + 3ds81 - Nintendo 3DS ZX81 emulator. + + Copyright (C) 2021 Ian Cowburn <ianc@noddybox.co.uk> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 3 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see <http://www.gnu.org/licenses/> + + $Id: main.c 77 2010-11-23 08:10:25Z ianc $ +*/ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <3ds.h> + +#include "framebuffer.h" +#include "gui.h" +#include "keyboard.h" +#include "z80.h" +#include "zx81.h" +#include "tapes.h" +#include "config.h" +#include "snapshot.h" + +#ifndef DS81_VERSION +#define DS81_VERSION "DEV " __TIME__ "/" __DATE__ +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#define DEBUG(x) \ + do \ + { \ + printf(x); \ + gfxFlushBuffers(); \ + gfxSwapBuffers(); \ + } while(0); \ + do \ + { \ + hidScanInput(); \ + } while(!(hidKeysDown() & KEY_TOUCH)) \ + +/* ---------------------------------------- STATIC DATA +*/ +static const char *main_menu[]= + { + "Reset ZX81", + "Select Tape", + "Configure", + "Map Joypad to Keys", + "Save Memory Snapshot", + "Load Memory Snapshot", + "Save Joypad/Key State", + "Load Joypad/Key State", + "Exit 3DS81", + "Cancel", + NULL + }; + +typedef enum +{ + MenuReset, + MenuSelectTape, + MenuConfigure, + MenuMapJoypad, + MenuSaveSnapshot, + MenuLoadSnapshot, + MenuSaveMappings, + MenuLoadMappings, + MenuExit +} MenuOpt; + + +/* ---------------------------------------- DISPLAY FUNCS +*/ +static void Splash(void) +{ + static char scroller[]= + { + " " + "Welcome to 3DS81, a ZX81 emulator for the Ninetendo 3DS. " + "You can safely ignore this message. I was just bored for half an " + "hour. And no retro game is complete without a side-scroller... " + "Thanks to Slay Radio, Ladytron, the Genki Rockets, the High " + "Voltage SID Collection, The Prodigy, Paradise Lost and " + "Retro Gamer for coding fuel." + }; + + static const char *text[]= + { + "3DS81 \177 2021 Ian Cowburn", + " ", + "ZX81 ROM \177 1981", + "Nine Tiles Networks LTD", + " ", + "PRESS A TO CONTINUE", + " ", + "https://noddybox.co.uk/", + " ", + "If you place .P tape files in", + "the top directory or ZX81SNAP", + "then you should be able to load", + "GAME.P with the command", + "LOAD \"GAME\"", + NULL + }; + + int f; + int y; + int scr_x = 0; + int scr_y = 240; + Framebuffer upper; + Framebuffer lower; + + ZX81EnableFileSystem(TRUE); + SNAP_Enable(TRUE); + + while(!(hidKeysDown() & KEY_A)) + { + FB_StartFrame(&upper, &lower); + + FB_Clear(&upper, COL_BLACK); + FB_Clear(&lower, COL_BLACK); + + FB_Blit(&upper, IMG_SPLASH, 0, scr_y); + + FB_Print(&upper, "10 REM VERSION \001" DS81_VERSION "\001\n" + "20 PRINT \"\001THE ZX81 IS ACE\001\"\n" + "30 GOTO 20", + 0, 230, COL_WHITE, COL_TRANSPARENT); + + FB_printf(&lower, scr_x, 8, COL_WHITE, COL_TRANSPARENT, + "%-42.42s",scroller); + + y = lower.height - 20; + + for(f=0;text[f];f++) + { + FB_Centre(&lower, text[f], y, COL_WHITE, COL_TRANSPARENT); + y -= 8; + } + + FB_EndFrame(); + + if (scr_y > 0) + { + scr_y--; + } + + if (--scr_x == -8) + { + size_t l = sizeof scroller; + char c; + + scr_x = 0; + + c = scroller[0]; + memmove(scroller, scroller+1, l-2); + scroller[l-2] = c; + } + } +} + + +/* ---------------------------------------- JOYPAD MAPPING +*/ +static void MapJoypad(void) +{ + SoftKeyEvent ev; + SoftKey pad = NUM_SOFT_KEYS; + int done = FALSE; + Framebuffer upper; + Framebuffer lower; + + while(!done) + { + FB_StartFrame(&upper, &lower); + + SK_DisplayKeyboard(); + + FB_Clear(&upper, COL_WHITE); + + FB_Print(&upper, "Press the joypad button you want\n" + "to define and then the ZX81 key\n" + "you want to use.\n\n" + "Press CONFIG to finish.", + 0, upper.height - 40, COL_BLACK,COL_TRANSPARENT); + + if (pad != NUM_SOFT_KEYS) + { + FB_printf(&upper, 0, 80, COL_BLACK, COL_TRANSPARENT, + "defining\n \001%s\001",SK_KeyName(pad)); + } + + FB_EndFrame(); + + while(SK_GetBareEvent(&ev)) + { + if (ev.pressed) + { + if (ev.key==SK_ABOUT || ev.key==SK_CONFIG) + { + done = true; + } + } + else + { + if (ev.key>=SK_PAD_UP && ev.key<=SK_PAD_SELECT) + { + pad = ev.key; + } + + if (ev.key<=SK_SPACE && pad!=NUM_SOFT_KEYS) + { + SK_DefinePad(pad,ev.key); + pad = NUM_SOFT_KEYS; + } + } + } + } +} + + +/* ---------------------------------------- MAIN +*/ +int main(int argc, char *argv[]) +{ + Z80 *z80; + int quit = FALSE; + + gfxInit(GSP_RGB565_OES, GSP_RGB565_OES, false); + consoleInit(GFX_TOP, NULL); + + FB_Init(); + + z80 = Z80Init(ZX81ReadMem, + ZX81WriteMem, + ZX81ReadPort, + ZX81WritePort, + ZX81ReadDisassem); + + if (!z80) + { + GUI_Alert(TRUE,"Failed to initialise\nthe Z80 CPU emulation!"); + } + + ZX81Init(z80); + + Splash(); + + LoadConfig(); + ZX81Reconfigure(); + + SK_DisplayKeyboard(); + + SK_SetSticky(SK_SHIFT,DS81_Config[DS81_STICKY_SHIFT]); + + if (DS81_Config[DS81_LOAD_DEFAULT_SNAPSHOT]) + { + SNAP_Load(z80, "AUTO", SNAP_TYPE_FULL); + } + + while(!quit && aptMainLoop()) + { + SoftKeyEvent ev; + Framebuffer upper; + Framebuffer lower; + + FB_StartFrame(&upper, &lower); + + SK_DisplayKeyboard(); + + Z80Exec(z80); + + ZX81RenderDisplay(&upper); + + FB_EndFrame(); + + while(SK_GetEvent(&ev)) + { + switch(ev.key) + { + case SK_ABOUT: + case SK_CONFIG: + if (ev.pressed) + { + switch(GUI_Menu(main_menu)) + { + case MenuReset: + ZX81Reset(z80); + break; + + case MenuSelectTape: + SelectTape(); + break; + + case MenuConfigure: + GUI_Config(); + SK_SetSticky(SK_SHIFT, + DS81_Config[DS81_STICKY_SHIFT]); + ZX81Reconfigure(); + break; + + case MenuMapJoypad: + MapJoypad(); + break; + + case MenuSaveSnapshot: + SNAP_Save(z80, SNAP_TYPE_FULL); + break; + + case MenuLoadSnapshot: + SNAP_Load(z80, NULL, SNAP_TYPE_FULL); + break; + + case MenuSaveMappings: + SNAP_Save(z80, SNAP_TYPE_KEYBOARD); + break; + + case MenuLoadMappings: + SNAP_Load(z80, NULL, SNAP_TYPE_KEYBOARD); + break; + + case MenuExit: + quit = TRUE; + break; + } + } + break; + + default: + ZX81HandleKey(ev.key,ev.pressed); + break; + } + } + } + + gfxExit(); + + return 0; +} |