Permalink
Cannot retrieve contributors at this time
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
2467 lines (2144 sloc)
82.5 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| ** Oricutron | |
| ** Copyright (C) 2009-2014 Peter Gordon | |
| ** | |
| ** 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, version 2 | |
| ** of the License. | |
| ** | |
| ** 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, write to the Free Software | |
| ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |
| ** | |
| ** GUI | |
| */ | |
| /* | |
| ** The GUI in Oricutron is built on the basic element of the "textzone". This | |
| ** is a simple structure containing the position, size and contents of an area | |
| ** of text, which you can render onto an SDL surface whenever you like. | |
| */ | |
| #include <stdlib.h> | |
| #include <string.h> | |
| #include <stdarg.h> | |
| #include <stdio.h> | |
| #include <sys/stat.h> | |
| #ifdef __amigaos4__ | |
| #include <proto/dos.h> | |
| #endif | |
| #if defined(__MORPHOS__) || defined(__AROS__) | |
| #include <proto/exec.h> | |
| #include <proto/openurl.h> | |
| #endif | |
| #include "system.h" | |
| #include "6502.h" | |
| #include "via.h" | |
| #include "8912.h" | |
| #include "gui.h" | |
| #include "disk.h" | |
| #include "monitor.h" | |
| #include "6551.h" | |
| #include "machine.h" | |
| #include "filereq.h" | |
| #include "render_sw.h" | |
| #include "render_sw8.h" | |
| #include "render_gl.h" | |
| #include "render_null.h" | |
| #include "ula.h" | |
| #include "tape.h" | |
| #include "joystick.h" | |
| #include "snapshot.h" | |
| #include "msgbox.h" | |
| #include "keyboard.h" | |
| #include "plugins/ch376/ch376.h" | |
| #include "plugins/ch376/oric_ch376_plugin.h" | |
| #include "plugins/twilighte_board/oric_twilighte_board_plugin.h" | |
| extern SDL_bool fullscreen; | |
| char tapepath[4096], tapefile[512]; | |
| char diskpath[4096], diskfile[512]; | |
| char telediskpath[4096], telediskfile[512]; | |
| char pravdiskpath[4096], pravdiskfile[512]; | |
| extern char atmosromfile[]; | |
| extern char oric1romfile[]; | |
| extern char mdiscromfile[]; | |
| extern char bd500romfile[]; | |
| extern char jasmnromfile[]; | |
| extern char pravetzromfile[2][1024]; | |
| extern char telebankfiles[8][1024]; | |
| char snappath[4096], snapfile[512]; | |
| char mappingpath[4096], mappingfile[512]; | |
| char filetmp[4096+512+4]; | |
| SDL_bool refreshstatus = SDL_TRUE, refreshdisks = SDL_TRUE, refreshavi = SDL_TRUE, refreshtape = SDL_TRUE, | |
| refreshkeyboard = SDL_TRUE; | |
| extern struct avi_handle *vidcap; | |
| extern SDL_bool need_sdl_quit; | |
| extern SDL_AudioSpec obtained; | |
| extern Uint32 cyclespersample; | |
| #define GIMG_W_DISK 18 | |
| #define GIMG_W_TAPE 20 | |
| #define GIMG_W_AVIR 16 | |
| // Images used in the GUI | |
| struct guiimg gimgs[NUM_GIMG] = { { IMAGEPREFIX"statusbar.bmp", 640, 16, NULL }, | |
| { IMAGEPREFIX"disk_ejected.bmp", GIMG_W_DISK, 16, NULL }, | |
| { IMAGEPREFIX"disk_idle.bmp", GIMG_W_DISK, 16, NULL }, | |
| { IMAGEPREFIX"disk_active.bmp", GIMG_W_DISK, 16, NULL }, | |
| { IMAGEPREFIX"disk_modified.bmp", GIMG_W_DISK, 16, NULL }, | |
| { IMAGEPREFIX"disk_modactive.bmp", GIMG_W_DISK, 16, NULL }, | |
| { IMAGEPREFIX"tape_ejected.bmp", GIMG_W_TAPE, 16, NULL }, | |
| { IMAGEPREFIX"tape_pause.bmp", GIMG_W_TAPE, 16, NULL }, | |
| { IMAGEPREFIX"tape_play.bmp", GIMG_W_TAPE, 16, NULL }, | |
| { IMAGEPREFIX"tape_stop.bmp", GIMG_W_TAPE, 16, NULL }, | |
| { IMAGEPREFIX"tape_record.bmp", GIMG_W_TAPE, 16, NULL }, | |
| { IMAGEPREFIX"avirec.bmp", GIMG_W_AVIR, 16, NULL }, | |
| { IMAGEPREFIX"gfx_oric1kbd.bmp", 640, 240, NULL }, | |
| { IMAGEPREFIX"gfx_atmoskbd.bmp", 640, 240, NULL }, | |
| { IMAGEPREFIX"gfx_pravetzkbd.bmp", 640, 240, NULL }}; | |
| SDL_bool soundavailable, soundon; | |
| #if defined(__linux__) | |
| Sint16 soundsilence = 0; | |
| #else | |
| Sint16 soundsilence = -32768; | |
| #endif | |
| extern SDL_bool microdiscrom_valid, jasminrom_valid, pravetzrom_valid; | |
| // GUI image locations | |
| #define GIMG_POS_SBARY (480-16) | |
| #define GIMG_POS_TAPEX (640-4-GIMG_W_TAPE) | |
| #define GIMG_POS_DISKX (GIMG_POS_TAPEX-(6+(GIMG_W_DISK*4))) | |
| #define GIMG_POS_AVIRECX (GIMG_POS_DISKX-(6+GIMG_W_AVIR)) | |
| // Text zone (and other gui area) colours R, G, B | |
| unsigned char sgpal[] = { 0x00, 0x00, 0x00, // 0 = black | |
| 0xff, 0xff, 0xff, // 1 = white | |
| 0xcc, 0xcc, 0xff, // 2 = light blue | |
| 0x00, 0x00, 0xff, // 3 = dark blue | |
| 0x00, 0x00, 0x40, // 4 = very dark blue | |
| 0x70, 0x70, 0xff, // 5 = mid blue | |
| 0x80, 0x80, 0x80, // 6 = grey | |
| 0xa0, 0xa0, 0x00, // 7 = yellow | |
| 0x80, 0x00, 0x00, // 8 = dark red | |
| 0xff, 0x00, 0x00, // 9 = red | |
| 0xcc, 0xcc, 0xcc, // 10 = Oric-1 bc | |
| 0x33, 0x66, 0x99, // 11 = Oric-1 sel | |
| 0xff, 0x66, 0x00, // 12 = Atmos sel | |
| 0xff, 0x33, 0x33, // 13 = Telestrat sel | |
| 0x99, 0x99, 0x66, // 14 = Pravetz bc | |
| 0xcc, 0xcc, 0x99 // 15 = Pravetz sel | |
| }; | |
| // Colors for the menu, see sgpal for color index | |
| // MACH_ORIC1 = 0, MACH_ORIC1_16K, MACH_ATMOS, MACH_TELESTRAT, MACH_PRAVETZ | |
| // Name = { OR TE PR Or | |
| // OR IC AT LE AV ig | |
| // IC -1 MO ST ET in a$ | |
| // -1, 16, S , RA, Z , al, c }; | |
| static char g_foregroundc[] = { 0, 0, 1, 1, 0, 2, 1 }; | |
| static char g_backgroundc[] = { 10, 10, 0, 0, 14, 3, 0 }; | |
| static char g_foregroundcsel[] = { 1, 1, 0, 0, 0, 1, 0 }; | |
| static char g_backgroundcsel[] = { 11, 11, 12, 13, 15, 5, 9 }; | |
| int g_menu_scheme = 5; // Default is original color scheme, set to the current machine type in machine.c swapmach | |
| // All the textzones. Spaces in this array | |
| // are reserved in gui.h | |
| struct textzone *tz[NUM_TZ]; | |
| // Temporary string buffer | |
| char vsptmp[VSPTMPSIZE]; | |
| // FPS calculation vars | |
| extern Uint32 frametimeave; | |
| SDL_bool warpspeed=SDL_FALSE; | |
| // Current menu, and highlighted item number | |
| struct osdmenu *cmenu = NULL; | |
| int cmenuitem = 0; | |
| static char* aciabackends[ACIA_TYPE_LAST] = { | |
| " Serial none ", | |
| "\x0e""Serial loopback $xxxx", | |
| "\x0e""Serial modem $xxxx", | |
| "\x0e""Serial com $xxxx", | |
| }; | |
| static char aciabackendlabel[32]; | |
| char menufc(SDL_bool bSelected) { return (bSelected ? g_foregroundcsel[g_menu_scheme] : g_foregroundc[g_menu_scheme]); } | |
| char menubc(SDL_bool bSelected) { return (bSelected ? g_backgroundcsel[g_menu_scheme] : g_backgroundc[g_menu_scheme]); } | |
| // Menufunctions | |
| void toggletapenoise( struct machine *oric, struct osdmenuitem *mitem, int dummy ); | |
| void togglesound( struct machine *oric, struct osdmenuitem *mitem, int dummy ); | |
| void inserttape( struct machine *oric, struct osdmenuitem *mitem, int dummy ); | |
| void insertdisk( struct machine *oric, struct osdmenuitem *mitem, int drive ); | |
| void resetoric( struct machine *oric, struct osdmenuitem *mitem, int dummy ); | |
| void toggletapeturbo( struct machine *oric, struct osdmenuitem *mitem, int dummy ); | |
| void togglech376(struct machine *oric, struct osdmenuitem *mitem, int dummy); | |
| void toggletwilighte(struct machine *oric, struct osdmenuitem *mitem, int dummy); | |
| void toggleautowind( struct machine *oric, struct osdmenuitem *mitem, int dummy ); | |
| void toggleautoinsrt( struct machine *oric, struct osdmenuitem *mitem, int dummy ); | |
| void togglesymbolsauto( struct machine *oric, struct osdmenuitem *mitem, int dummy ); | |
| void togglecasesyms( struct machine *oric, struct osdmenuitem *mitem, int dummy ); | |
| void togglevsynchack( struct machine *oric, struct osdmenuitem *mitem, int dummy ); | |
| void swap_render_mode( struct machine *oric, struct osdmenuitem *mitem, int newrendermode ); | |
| void togglearatio( struct machine *oric, struct osdmenuitem *mitem, int dummy ); | |
| void togglehstretch( struct machine *oric, struct osdmenuitem *mitem, int dummy ); | |
| void togglepalghost( struct machine *oric, struct osdmenuitem *mitem, int dummy ); | |
| void togglescanlines( struct machine *oric, struct osdmenuitem *mitem, int dummy ); | |
| void togglelightpen( struct machine *oric, struct osdmenuitem *mitem, int dummy ); | |
| void toggleaciabackend( struct machine *oric, struct osdmenuitem *mitem, int dummy ); | |
| void setoverclock( struct machine *oric, struct osdmenuitem *mitem, int dummy ); | |
| void savesnap( struct machine *oric, struct osdmenuitem *mitem, int dummy ); | |
| void loadsnap( struct machine *oric, struct osdmenuitem *mitem, int dummy ); | |
| void togglekeyboard( struct machine *oric, struct osdmenuitem *mitem, int dummy ); | |
| void definemapping( struct machine *oric, struct osdmenuitem *mitem, int dummy ); | |
| void togglestickykeys( struct machine *oric, struct osdmenuitem *mitem, int dummy ); | |
| void savemapping( struct machine *oric, struct osdmenuitem *mitem, int dummy ); | |
| void loadmapping( struct machine *oric, struct osdmenuitem *mitem, int dummy ); | |
| void resetmapping( struct machine *oric, struct osdmenuitem *mitem, int dummy ); | |
| #ifdef __CBCOPY__ | |
| void clipbd_copy_gui( struct machine *oric, struct osdmenuitem *mitem, int dummy ); | |
| #endif | |
| #ifdef __CBPASTE__ | |
| void clipbd_paste_gui( struct machine *oric, struct osdmenuitem *mitem, int dummy ); | |
| #endif | |
| // Menu definitions. Name, key name, SDL key code, function, parameter | |
| // Keys that are also available while emulating should be marked with | |
| // square brackets | |
| struct osdmenuitem mainitems[] = { { "Insert tape...", "T", 't', inserttape, 0, 0 }, | |
| { "Save tape output...", "[F9]", SDLK_F9, toggletapecap, 0, 0 }, | |
| { "Insert disk 0...", "0", SDLK_0, insertdisk, 0, 0 }, | |
| { "Insert disk 1...", "1", SDLK_1, insertdisk, 1, 0 }, | |
| { "Insert disk 2...", "2", SDLK_2, insertdisk, 2, 0 }, | |
| { "Insert disk 3...", "3", SDLK_3, insertdisk, 3, 0 }, | |
| { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, | |
| { "Save snapshot...", NULL, 0, savesnap, 0, 0 }, | |
| { "Load snapshot...", NULL, 0, loadsnap, 0, 0 }, | |
| #if defined(__CBCOPY__) || defined(__CBPASTE__) | |
| { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, | |
| #endif | |
| #if defined(__CBCOPY__) | |
| { "Copy to clipboard", "[F11]",SDLK_F11, clipbd_copy_gui, 0, 0 }, | |
| #endif | |
| #if defined(__CBPASTE__) | |
| { "Paste from clipboard", "[F12]",SDLK_F12, clipbd_paste_gui,0, 0 }, | |
| #endif | |
| { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, | |
| { "Hardware options...", "H", 'h', gotomenu, 1, 0 }, | |
| { "Audio options...", "A", 'a', gotomenu, 2, 0 }, | |
| { "Video options...", "V", 'v', gotomenu, 4, 0 }, | |
| { "Keyboard options...", "K", 'k', gotomenu, 7, 0 }, | |
| { "Debug options...", "D", 'd', gotomenu, 3, 0 }, | |
| { "Overclock options...", "C", 'c', gotomenu, 6, 0 }, | |
| { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, | |
| { "Monitor", "[F2]", SDLK_F2, setemumode, EM_DEBUG, 0 }, | |
| { "Reset Button NMI", "[F3]", SDLK_F3, softresetoric, 0, 0 }, | |
| { "Hard Reset", "[F4]", SDLK_F4, resetoric, 0, 0 }, | |
| { "Back", "\x17", SDLK_BACKSPACE,setemumode, EM_RUNNING, 0 }, | |
| { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, | |
| { "About", NULL, 0, gotomenu, 5, 0 }, | |
| { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, | |
| { "Quit", NULL, 0, setemumode, EM_PLEASEQUIT, 0 }, | |
| { NULL, } }; | |
| struct osdmenuitem hwopitems[] = { { " Oric-1", "1", SDLK_1, swapmach, (0xffff<<16)|MACH_ORIC1, 0 }, | |
| { " Oric-1 16K", "2", SDLK_2, swapmach, (0xffff<<16)|MACH_ORIC1_16K, 0 }, | |
| { " Atmos", "3", SDLK_3, swapmach, (0xffff<<16)|MACH_ATMOS, 0 }, | |
| { " Telestrat", "4", SDLK_4, swapmach, (DRV_NONE<<16)|MACH_TELESTRAT, 0 }, | |
| { " Pravetz 8D", "5", SDLK_5, swapmach, (0xffff<<16)|MACH_PRAVETZ, 0 }, | |
| { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, | |
| { " No disk", "X", 'x', setdrivetype, DRV_NONE, 0 }, | |
| { " Microdisc", "M", 'm', setdrivetype, DRV_MICRODISC, 0 }, | |
| { " Jasmin", "J", 'j', setdrivetype, DRV_JASMIN, 0 }, | |
| { " BD500", "B", 'b', setdrivetype, DRV_BD500, 0 }, | |
| // { " Cumana", "C", 'c', NULL, 0, 0 }, | |
| { " Pravetz 8D disk", "P", 'p', setdrivetype, DRV_PRAVETZ, 0 }, | |
| { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, | |
| { " Turbo tape", NULL, 0, toggletapeturbo, 0, 0 }, | |
| { " Autoinsert tape", NULL, 0, toggleautoinsrt, 0, 0 }, | |
| { " Autorewind tape", NULL, 0, toggleautowind, 0, 0 }, | |
| { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, | |
| { " VSync hack", NULL, 0, togglevsynchack, 0, 0 }, | |
| { " Lightpen", NULL, 0, togglelightpen, 0, 0 }, | |
| { " Serial none ", NULL, 0, toggleaciabackend, 0, 0 }, | |
| { " CH376 (Telestrat) ", NULL, 0, togglech376, 0, 0 }, | |
| { " Twilighte board ", NULL, 0, toggletwilighte, 0, 0 }, | |
| // { " Mouse", NULL, 0, NULL, 0, 0 }, | |
| { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, | |
| { "Back", "\x17", SDLK_BACKSPACE,gotomenu, 0, 0 }, | |
| { NULL, } }; | |
| struct osdmenuitem auopitems[] = { { " Sound enabled", NULL, 0, togglesound, 0, 0 }, | |
| { " Tape noise", NULL, 0, toggletapenoise, 0, 0 }, | |
| { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, | |
| { "Back", "\x17", SDLK_BACKSPACE,gotomenu, 0, 0 }, | |
| { NULL, } }; | |
| struct osdmenuitem keopitems[] = { { " Show keyboard", NULL, 0, togglekeyboard, 0, 0 }, | |
| { " Sticky mod keys", NULL, 0, togglestickykeys,0, 0 }, | |
| { " Define mapping", NULL, 0, definemapping, 0, 0 }, | |
| { "Save mapping...", NULL, 0, savemapping, 0, 0 }, | |
| { "Load mapping...", NULL, 0, loadmapping, 0, 0 }, | |
| { "Reset mapping", NULL, 0, resetmapping, 0, 0 }, | |
| { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, | |
| { "Back", "\x17", SDLK_BACKSPACE,gotomenu, 0, 0 }, | |
| { NULL, } }; | |
| struct osdmenuitem dbopitems[] = { { " Autoload symbols file", NULL, 0, togglesymbolsauto, 0, 0 }, | |
| { " Case-sensitive symbols",NULL, 0, togglecasesyms, 0, 0 }, | |
| { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, | |
| { "Back", "\x17", SDLK_BACKSPACE,gotomenu, 0, 0 }, | |
| { NULL, } }; | |
| #ifdef __OPENGL_AVAILABLE__ | |
| struct osdmenuitem vdopitems[] = { { " OpenGL rendering", "O", 'o', swap_render_mode, RENDERMODE_GL, 0 }, | |
| { " Software rendering", "S", 's', swap_render_mode, RENDERMODE_SW, 0 }, | |
| { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, | |
| { " Fullscreen", "[F8]", SDLK_F8, togglefullscreen, 0, 0 }, | |
| { " Scanlines", "C", 'c', togglescanlines, 0, 0 }, | |
| { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, | |
| { "Back", "\x17", SDLK_BACKSPACE,gotomenu, 0, 0 }, | |
| { NULL, } }; | |
| #else | |
| struct osdmenuitem vdopitems[] = { { " Fullscreen", "F", 'f', togglefullscreen, 0, 0 }, | |
| { " Scanlines", "C", 'c', togglescanlines, 0, 0 }, | |
| { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, | |
| { "Back", "\x17", SDLK_BACKSPACE,gotomenu, 0, 0 }, | |
| { NULL, } }; | |
| #endif | |
| struct osdmenuitem glopitems[] = { { " OpenGL rendering", "O", 'o', swap_render_mode, RENDERMODE_GL, 0 }, | |
| { " Software rendering", "S", 's', swap_render_mode, RENDERMODE_SW, 0 }, | |
| { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, | |
| { " Fullscreen", "F", 'f', togglefullscreen, 0, 0 }, | |
| { " 50Hz/60Hz aspect ratio", "R", 'r', togglearatio, 0, 0 }, | |
| { " Horizontal stretch", "H", 'h', togglehstretch, 0, 0 }, | |
| { " Scanlines", "C", 'c', togglescanlines, 0, 0 }, | |
| { " PAL ghosting", "P", 'p', togglepalghost, 0, 0 }, | |
| { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, | |
| { "Back", "\x17", SDLK_BACKSPACE,gotomenu, 0, 0 }, | |
| { NULL, } }; | |
| struct osdmenuitem aboutitems[] = { { "", NULL, 0, NULL, 0, 0 }, | |
| { APP_NAME_FULL, NULL, 0, NULL, 0, OMIF_BRIGHT|OMIF_CENTRED }, | |
| { "https://github.com/pete-gordon/oricutron",NULL, 0, gotosite, 0, OMIF_CENTRED }, | |
| { "", NULL, 0, NULL, 0, 0 }, | |
| { "(C)" APP_YEAR " Peter Gordon", NULL, 0, NULL, 0, OMIF_BRIGHT|OMIF_CENTRED }, | |
| { "http://www.petergordon.org.uk", NULL, 0, gotosite, 0, OMIF_CENTRED }, | |
| { "", NULL, 0, NULL, 0, 0 }, | |
| { "Additional programming", NULL, 0, NULL, 0, OMIF_BRIGHT|OMIF_CENTRED }, | |
| { "Francois Revol", NULL, 0, NULL, 0, OMIF_CENTRED }, | |
| { "Stefan Haubenthal", NULL, 0, NULL, 0, OMIF_CENTRED }, | |
| { "Alexandre Devert", NULL, 0, NULL, 0, OMIF_CENTRED }, | |
| { "Ibisum", NULL, 0, NULL, 0, OMIF_CENTRED }, | |
| { "Kamel Biskri", NULL, 0, NULL, 0, OMIF_CENTRED }, | |
| { "Iss", NULL, 0, NULL, 0, OMIF_CENTRED }, | |
| { "Patrice Torguet", NULL, 0, NULL, 0, OMIF_CENTRED }, | |
| { "", NULL, 0, NULL, 0, 0 }, | |
| { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, | |
| { "Back", "\x17", SDLK_BACKSPACE, gotomenu, 0, 0 }, | |
| { NULL, } }; | |
| struct osdmenuitem ovopitems[] = { { " 1mhz (None)", "1", '1', setoverclock, 0, 0 }, | |
| { " 2mhz", "2", '2', setoverclock, 1, 0 }, | |
| { " 4mhz", "3", '3', setoverclock, 2, 0 }, | |
| { " 8mhz", "4", '4', setoverclock, 3, 0 }, | |
| { " 16mhz", "5", '5', setoverclock, 4, 0 }, | |
| { " 32mhz", "6", '6', setoverclock, 5, 0 }, | |
| { " 64mhz", "7", '7', setoverclock, 6, 0 }, | |
| { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, | |
| { "Back", "\x17", SDLK_BACKSPACE,gotomenu,0, 0 }, | |
| { NULL, } }; | |
| #define LAST_ITEM(x) ((sizeof(x)/sizeof(struct osdmenuitem))-2) | |
| struct osdmenu menus[] = { { "Main Menu", LAST_ITEM(mainitems)-4, mainitems }, | |
| { "Hardware options", LAST_ITEM(hwopitems), hwopitems }, | |
| { "Audio options", LAST_ITEM(auopitems), auopitems }, | |
| { "Debug options", LAST_ITEM(dbopitems), dbopitems }, | |
| { "Video options", LAST_ITEM(vdopitems), vdopitems }, | |
| { "About Oricutron", LAST_ITEM(aboutitems), aboutitems }, | |
| { "Overclock", LAST_ITEM(ovopitems), ovopitems }, | |
| { "Keyboard options", LAST_ITEM(keopitems), keopitems }}; | |
| // Load a 24bit BMP for the GUI | |
| SDL_bool gimg_load( struct guiimg *gi ) | |
| { | |
| SDL_RWops *f; | |
| Uint8 hdrbuf[640*3]; | |
| Sint32 x, y; | |
| SDL_bool fileok; | |
| // Get the file | |
| f = SDL_RWFromFile( gi->filename, "rb" ); | |
| if( !f ) | |
| { | |
| error_printf( "Unable to open '%s'\n", gi->filename ); | |
| return SDL_FALSE; | |
| } | |
| // Read the header | |
| if( SDL_RWread( f, hdrbuf, 54, 1 ) != 1 ) | |
| { | |
| error_printf( "Error reading '%s'\n", gi->filename ); | |
| SDL_RWclose( f ); | |
| return SDL_FALSE; | |
| } | |
| fileok = SDL_TRUE; | |
| if( strncmp( (char *)hdrbuf, "BM", 2 ) != 0 ) fileok = SDL_FALSE; // Must start with "BM" | |
| if( ((hdrbuf[21]<<24)|(hdrbuf[20]<<16)|(hdrbuf[19]<<8)|hdrbuf[18]) != gi->w ) fileok = SDL_FALSE; // Must be the correct width | |
| if( ((hdrbuf[25]<<24)|(hdrbuf[24]<<16)|(hdrbuf[23]<<8)|hdrbuf[22]) != gi->h ) fileok = SDL_FALSE; // Must be the correct height | |
| if( ((hdrbuf[27]<<8)|hdrbuf[26]) != 1 ) fileok = SDL_FALSE; // Must contain one plane | |
| if( ((hdrbuf[29]<<8)|hdrbuf[28]) != 24 ) fileok = SDL_FALSE; // Must be 24 bit | |
| if( ((hdrbuf[33]<<24)|(hdrbuf[32]<<16)|(hdrbuf[31]<<8)|hdrbuf[30]) != 0 ) fileok = SDL_FALSE; // Must not be compressed | |
| if( !fileok ) | |
| { | |
| error_printf( "'%s' needs to be a %dx%d, uncompressed, 24-bit BMP image\n", gi->filename, gi->w, gi->h ); | |
| SDL_RWclose( f ); | |
| return SDL_FALSE; | |
| } | |
| // Get some RAM! | |
| if( !gi->buf ) | |
| gi->buf = malloc( gi->w * gi->h * 3 ); | |
| if( !gi->buf ) | |
| { | |
| error_printf( "Out of memory\n" ); | |
| SDL_RWclose( f ); | |
| return SDL_FALSE; | |
| } | |
| // BMPs are upside down! | |
| for( y=gi->h-1; y>=0; y-- ) | |
| { | |
| SDL_RWread( f, hdrbuf, ((gi->w*3)+3)&0xfffffffc, 1 ); | |
| for( x=0; x<gi->w; x++ ) | |
| { | |
| gi->buf[(y*gi->w+x)*3+0] = hdrbuf[x*3+2]; | |
| gi->buf[(y*gi->w+x)*3+1] = hdrbuf[x*3+1]; | |
| gi->buf[(y*gi->w+x)*3+2] = hdrbuf[x*3]; | |
| } | |
| } | |
| SDL_RWclose( f ); | |
| return SDL_TRUE; | |
| } | |
| // Draw the statusbar at the bottom | |
| void draw_statusbar( struct machine *oric ) | |
| { | |
| if (oric->statusbar_mode == STATUSBARMODE_NONE) | |
| oric->render_clear_area( 0, GIMG_POS_SBARY, 640, 480-GIMG_POS_SBARY ); | |
| else | |
| oric->render_gimg( GIMG_STATUSBAR, 0, GIMG_POS_SBARY ); | |
| } | |
| void draw_keyboard( struct machine *oric ) { | |
| if (oric->show_keyboard) { | |
| switch( oric->type ) | |
| { | |
| case MACH_PRAVETZ: | |
| oric->render_gimg( GIMG_PRAVETZ_KEYBOARD, 0, 480); | |
| break; | |
| case MACH_ORIC1: | |
| case MACH_ORIC1_16K: | |
| oric->render_gimg( GIMG_ORIC1_KEYBOARD, 0, 480); | |
| break; | |
| default: | |
| oric->render_gimg( GIMG_ATMOS_KEYBOARD, 0, 480); | |
| break; | |
| } | |
| } | |
| } | |
| // Overlay the disk icons onto the status bar | |
| void draw_disks( struct machine *oric ) | |
| { | |
| Sint32 i, j; | |
| if( oric->statusbar_mode == STATUSBARMODE_NONE ) | |
| return; | |
| if( oric->drivetype == DRV_NONE ) | |
| { | |
| oric->render_gimgpart( GIMG_STATUSBAR, GIMG_POS_DISKX, GIMG_POS_SBARY, GIMG_POS_DISKX, 0, 18*4, 16 ); | |
| return; | |
| } | |
| for( i=0; i<4; i++ ) | |
| { | |
| j = GIMG_DISK_EJECTED; | |
| if( oric->wddisk.disk[i] ) | |
| { | |
| j = ((oric->wddisk.c_drive==i)&&(oric->wddisk.currentop!=COP_NUFFINK)) ? GIMG_DISK_ACTIVE : GIMG_DISK_IDLE; | |
| if( oric->wddisk.disk[i]->modified ) j+=2; | |
| } | |
| oric->render_gimg( j, GIMG_POS_DISKX+i*GIMG_W_DISK, GIMG_POS_SBARY ); | |
| } | |
| } | |
| // Overlay the AVI record icon onto the status bar | |
| void draw_avirec( struct machine *oric, SDL_bool recording ) | |
| { | |
| if( oric->statusbar_mode == STATUSBARMODE_NONE) | |
| return; | |
| if( recording ) | |
| { | |
| oric->render_gimg( GIMG_AVI_RECORD, GIMG_POS_AVIRECX, GIMG_POS_SBARY ); | |
| return; | |
| } | |
| oric->render_gimgpart( GIMG_STATUSBAR, GIMG_POS_AVIRECX, GIMG_POS_SBARY, GIMG_POS_AVIRECX, 0, 16, 16 ); | |
| } | |
| // Overlay the tape icon onto the status bar | |
| void draw_tape( struct machine *oric ) | |
| { | |
| if( oric->statusbar_mode == STATUSBARMODE_NONE ) | |
| return; | |
| if( oric->tapecap ) | |
| { | |
| oric->render_gimg( GIMG_TAPE_RECORD, GIMG_POS_TAPEX, GIMG_POS_SBARY ); | |
| return; | |
| } | |
| if( !oric->tapebuf ) | |
| { | |
| oric->render_gimg( GIMG_TAPE_EJECTED, GIMG_POS_TAPEX, GIMG_POS_SBARY ); | |
| return; | |
| } | |
| if( oric->tapemotor ) | |
| { | |
| oric->render_gimg( GIMG_TAPE_PLAY, GIMG_POS_TAPEX, GIMG_POS_SBARY ); | |
| return; | |
| } | |
| if( oric->tapeoffs >= oric->tapelen ) | |
| { | |
| oric->render_gimg( GIMG_TAPE_STOP, GIMG_POS_TAPEX, GIMG_POS_SBARY ); | |
| return; | |
| } | |
| oric->render_gimg( GIMG_TAPE_PAUSE, GIMG_POS_TAPEX, GIMG_POS_SBARY ); | |
| } | |
| // Pop up some info! | |
| void do_popup( struct machine *oric, char *str ) | |
| { | |
| strncpy( oric->popupstr, str, 40 ); oric->popupstr[39] = 0; | |
| oric->newpopupstr = SDL_TRUE; | |
| oric->popuptime = 100; | |
| } | |
| void render_status( struct machine *oric ) | |
| { | |
| if( refreshstatus ) | |
| draw_statusbar( oric ); | |
| if( refreshdisks || refreshstatus ) | |
| { | |
| draw_disks( oric ); | |
| refreshdisks = SDL_FALSE; | |
| } | |
| if( refreshavi || refreshstatus ) | |
| { | |
| draw_avirec( oric, vidcap != NULL ); | |
| refreshavi = SDL_FALSE; | |
| } | |
| if( refreshtape || refreshstatus ) | |
| { | |
| draw_tape( oric ); | |
| refreshtape = SDL_FALSE; | |
| } | |
| if(refreshkeyboard || refreshstatus) { | |
| draw_keyboard( oric ); | |
| refreshkeyboard = SDL_FALSE; | |
| } | |
| refreshstatus = SDL_FALSE; | |
| } | |
| // Top-level rendering routine | |
| void render( struct machine *oric ) | |
| { | |
| int perc, fps; //, i; | |
| if( oric->emu_mode == EM_DEBUG ) | |
| mon_update( oric ); | |
| oric->render_begin( oric ); | |
| switch( oric->emu_mode ) | |
| { | |
| case EM_MENU: | |
| oric->render_video( oric, SDL_TRUE ); | |
| render_status( oric ); | |
| if( tz[TZ_MENU] ) oric->render_textzone( oric, TZ_MENU ); | |
| break; | |
| case EM_RUNNING: | |
| oric->render_video( oric, SDL_TRUE ); | |
| render_status( oric ); | |
| if( oric->statusbar_mode == STATUSBARMODE_FULL ) | |
| { | |
| fps = 100000/(frametimeave?frametimeave:1); | |
| if( oric->vid_freq ) | |
| perc = 200000/(frametimeave?frametimeave:1); | |
| else | |
| perc = 166667/(frametimeave?frametimeave:1); | |
| #ifdef DEBUG_VSYNC | |
| sprintf( oric->statusstr, "%4d.%02d%% - %4dFPS VSYNC:%3d", perc/100, perc%100, fps/100, oric->vid_offset ); | |
| #else | |
| sprintf( oric->statusstr, "%4d.%02d%% - %4dFPS", perc/100, perc%100, fps/100 ); | |
| #endif | |
| oric->newstatusstr = SDL_TRUE; | |
| } | |
| if( oric->popuptime > 0 ) | |
| { | |
| oric->popuptime--; | |
| if( oric->popuptime == 0 ) | |
| { | |
| oric->popupstr[0] = 0; | |
| oric->newpopupstr = SDL_TRUE; | |
| } | |
| } | |
| break; | |
| case EM_DEBUG: | |
| mon_render( oric ); | |
| break; | |
| } | |
| oric->render_end( oric ); | |
| } | |
| // Draws a box in a textzone (uses the box chars in the font) | |
| // ptz = target textzone | |
| // x,y,w,h = location and dimensions | |
| // fg,bg = colours | |
| void makebox( struct textzone *ptz, int x, int y, int w, int h, int fg, int bg ) | |
| { | |
| int cx, cy, o, bo; | |
| o = y*ptz->w+x; | |
| for( cy=0; cy<h; cy++ ) | |
| { | |
| for( cx=0; cx<w; cx++ ) | |
| { | |
| ptz->tx[o ] = ' '; | |
| ptz->fc[o ] = fg; | |
| ptz->bc[o++] = bg; | |
| } | |
| ptz->tx[o-w] = 5; | |
| ptz->tx[o-1] = 5; | |
| o += ptz->w-w; | |
| } | |
| o = y*ptz->w+x; | |
| bo = o + (h-1)*ptz->w; | |
| for( cx=0; cx<(w-1); cx++ ) | |
| { | |
| ptz->tx[o++] = cx==0?1:2; | |
| ptz->tx[bo++] = cx==0?9:2; | |
| } | |
| ptz->tx[o] = 4; | |
| ptz->tx[bo] = 11; | |
| ptz->modified = SDL_TRUE; | |
| } | |
| // Write a string to a textzone | |
| void tzstr( struct textzone *ptz, char *text ) | |
| { | |
| int i, o; | |
| o = ptz->py*ptz->w+ptz->px; | |
| for( i=0; text && text[i]; i++ ) | |
| { | |
| switch( text[i] ) | |
| { | |
| case 10: | |
| ptz->px = 1; | |
| ptz->py++; | |
| o = ptz->py*ptz->w+1; | |
| break; | |
| case 13: | |
| break; | |
| default: | |
| ptz->tx[o ] = text[i]; | |
| ptz->fc[o ] = ptz->cfc; | |
| ptz->bc[o++] = ptz->cbc; | |
| ptz->px++; | |
| if( ptz->px >= ptz->w ) | |
| { | |
| ptz->px = 1; | |
| ptz->py++; | |
| o = ptz->py*ptz->w+1; | |
| } | |
| break; | |
| } | |
| } | |
| ptz->modified = SDL_TRUE; | |
| } | |
| void tzputc( struct textzone *ptz, char c ) | |
| { | |
| char tmp[2]; | |
| tmp[0] = c; | |
| tmp[1] = 0; | |
| tzstr( ptz, tmp ); | |
| } | |
| // Print a formatted string into a textzone | |
| void tzprintf( struct textzone *ptz, char *fmt, ... ) | |
| { | |
| va_list ap; | |
| va_start( ap, fmt ); | |
| if( vsnprintf( vsptmp, VSPTMPSIZE, fmt, ap ) != -1 ) | |
| { | |
| vsptmp[VSPTMPSIZE-1] = 0; | |
| tzstr( ptz, vsptmp ); | |
| } | |
| va_end( ap ); | |
| } | |
| // Write a string to a textzone at a specific location | |
| void tzstrpos( struct textzone *ptz, int x, int y, char *text ) | |
| { | |
| ptz->px = x; | |
| ptz->py = y; | |
| tzstr( ptz, text ); | |
| } | |
| // Print a formatted string into a textzone at a specific location | |
| void tzprintfpos( struct textzone *ptz, int x, int y, char *fmt, ... ) | |
| { | |
| va_list ap; | |
| va_start( ap, fmt ); | |
| if( vsnprintf( vsptmp, VSPTMPSIZE, fmt, ap ) != -1 ) | |
| { | |
| vsptmp[VSPTMPSIZE-1] = 0; | |
| tzstrpos( ptz, x, y, vsptmp ); | |
| } | |
| va_end( ap ); | |
| } | |
| // Set the foreground and background colours for printing text into a textzone | |
| void tzsetcol( struct textzone *ptz, int fc, int bc ) | |
| { | |
| ptz->cfc = fc; | |
| ptz->cbc = bc; | |
| } | |
| // Set the title of a textzone | |
| void tzsettitle( struct textzone *ptz, char *title ) | |
| { | |
| int ox, oy; | |
| makebox( ptz, 0, 0, ptz->w, ptz->h, menufc(SDL_FALSE), menubc(SDL_FALSE)); | |
| if( !title ) return; | |
| tzsetcol( ptz, menufc(SDL_FALSE), menubc(SDL_FALSE)); | |
| ox = ptz->px; | |
| oy = ptz->py; | |
| ptz->px = 3; | |
| ptz->py = 0; | |
| tzstr( ptz, "[ " ); | |
| tzstr( ptz, title ); | |
| tzstr( ptz, " ]" ); | |
| ptz->px = ox; | |
| ptz->py = oy; | |
| } | |
| SDL_bool in_textzone( struct textzone *tz_, int x, int y ) | |
| { | |
| if( ( x >= tz_->x ) && ( x < (tz_->x+tz_->w*8) ) && | |
| ( y >= tz_->y ) && ( y < (tz_->y+tz_->h*12) ) ) | |
| { | |
| return SDL_TRUE; | |
| } | |
| return SDL_FALSE; | |
| } | |
| // Allocate a textzone structure | |
| SDL_bool alloc_textzone( struct machine *oric, int i, int x, int y, int w, int h, char *title ) | |
| { | |
| struct textzone *ntz; | |
| ntz = malloc( sizeof( struct textzone ) + w*h*3 ); | |
| if( !ntz ) return SDL_FALSE; | |
| ntz->x = x; | |
| ntz->y = y; | |
| ntz->w = w; | |
| ntz->h = h; | |
| ntz->tx = (unsigned char *)(&ntz[1]); | |
| ntz->fc = &ntz->tx[w*h]; | |
| ntz->bc = &ntz->fc[w*h]; | |
| tzsettitle( ntz, title ); | |
| ntz->px = 1; | |
| ntz->py = 1; | |
| ntz->modified = SDL_TRUE; | |
| tz[i] = ntz; | |
| oric->render_textzone_alloc( oric, i ); | |
| return SDL_TRUE; | |
| } | |
| void clear_textzone( struct machine *oric, int i ) | |
| { | |
| int x, y; | |
| struct textzone *ptz = tz[i]; | |
| if (!ptz) return; | |
| for( y=1; y<(ptz->h-1); y++ ) | |
| { | |
| for( x=1; x<(ptz->w-1); x++ ) | |
| { | |
| ptz->tx[y*ptz->w+x] = ' '; | |
| ptz->fc[y*ptz->w+x] = 2; | |
| ptz->bc[y*ptz->w+x] = 3; | |
| } | |
| } | |
| ptz->modified = SDL_TRUE; | |
| } | |
| // Free a textzone structure | |
| void free_textzone( struct machine *oric, int i ) | |
| { | |
| oric->render_textzone_free( oric, i ); | |
| if( !tz[i] ) return; | |
| free( tz[i] ); | |
| tz[i] = NULL; | |
| } | |
| // Draw the current menu items into the menu textzone | |
| void drawitems( void ) | |
| { | |
| int i, j, o; | |
| // No menu, or no textzone? | |
| if( ( !cmenu ) || ( !tz[TZ_MENU] ) ) | |
| return; | |
| // For each item... | |
| for( i=0; cmenu->items[i].name; i++ ) | |
| { | |
| // Check if its a menu bar | |
| if( cmenu->items[i].name == OSDMENUBAR ) | |
| { | |
| // Fill it with the menu bar char | |
| o = tz[TZ_MENU]->w * (i+1) + 1; | |
| for( j=1; j<tz[TZ_MENU]->w-1; j++, o++ ) | |
| { | |
| tz[TZ_MENU]->tx[o] = 12; | |
| tz[TZ_MENU]->fc[o] = menufc(SDL_FALSE); | |
| tz[TZ_MENU]->bc[o] = menubc(SDL_FALSE); | |
| } | |
| continue; | |
| } | |
| // Check if this is the highlighted item, and set the colours accordingly | |
| if( i==cmenu->citem ) | |
| tzsetcol( tz[TZ_MENU], menufc(SDL_TRUE), menubc(SDL_TRUE)); | |
| else | |
| tzsetcol( tz[TZ_MENU], (cmenu->items[i].flags&OMIF_BRIGHT) ? 1 : menufc(SDL_FALSE), menubc(SDL_FALSE)); | |
| // Calculate the position in the textzone | |
| o = tz[TZ_MENU]->w * (i+1) + 1; | |
| // Fill the background colour all the way along | |
| for( j=1; j<tz[TZ_MENU]->w-1; j++, o++ ) | |
| tz[TZ_MENU]->bc[o] = tz[TZ_MENU]->cbc; | |
| // Write the text for the item | |
| if( cmenu->items[i].flags & OMIF_CENTRED ) | |
| tzstrpos( tz[TZ_MENU], (tz[TZ_MENU]->w-(int)strlen(cmenu->items[i].name))/2, i+1, cmenu->items[i].name ); | |
| else | |
| tzstrpos( tz[TZ_MENU], 1, i+1, cmenu->items[i].name ); | |
| // And the key (if there is one) | |
| if( cmenu->items[i].key ) | |
| tzstrpos( tz[TZ_MENU], tz[TZ_MENU]->w-(1+(int)strlen(cmenu->items[i].key)), i+1, cmenu->items[i].key ); | |
| } | |
| } | |
| /***************** These functions can be used directly from the menu system ***************/ | |
| void joinpath( char *path, char *file ) | |
| { | |
| #if defined(__amigaos4__) | |
| strcpy( filetmp, path ); | |
| IDOS->AddPart( filetmp, file, 4096 ); | |
| #elif defined(WIN32) | |
| int i; | |
| strncpy( filetmp, path, 4096 ); filetmp[4095] = 0; | |
| i = strlen( filetmp ); | |
| if( ( i > 0 ) && ( filetmp[i-1] != PATHSEP ) && ( filetmp[i-1] != ':' ) ) | |
| { | |
| filetmp[i++] = PATHSEP; | |
| filetmp[i++] = 0; | |
| } | |
| strncat( filetmp, file, 4096+512 ); | |
| filetmp[4096+511] = 0; | |
| #else | |
| int i; | |
| strncpy( filetmp, path, 4096 ); filetmp[4095] = 0; | |
| i = (int)strlen( filetmp ); | |
| if( ( i > 0 ) && ( filetmp[i-1] != PATHSEP ) ) | |
| { | |
| filetmp[i++] = PATHSEP; | |
| filetmp[i++] = 0; | |
| } | |
| strncat( filetmp, file, 4096+512 ); | |
| filetmp[4096+511] = 0; | |
| #endif | |
| } | |
| // "insert" a tape into the virtual tape drive, via filerequester | |
| void inserttape( struct machine *oric, struct osdmenuitem *mitem, int dummy ) | |
| { | |
| if( !filerequester( oric, "Insert tape", tapepath, tapefile, FR_TAPELOAD ) ) return; | |
| oric->lasttapefile[0] = 0; | |
| joinpath( tapepath, tapefile ); | |
| switch (detect_image_type(filetmp)) | |
| { | |
| case IMG_SNAPSHOT: | |
| if (msgbox(oric, MSGBOX_YES_NO, | |
| "The file you selected appears to be a snapshot file.\n" | |
| "Would you like to load it? (All RAM and machine state will be lost)")) | |
| { | |
| load_snapshot(oric, filetmp); | |
| return; | |
| } | |
| break; | |
| case IMG_ATMOS_MICRODISC: | |
| if ((oric->type != MACH_ATMOS) && | |
| (oric->type != MACH_ORIC1) && | |
| (oric->type != MACH_PRAVETZ)) | |
| { | |
| if (msgbox(oric, MSGBOX_YES_NO, | |
| "The file you selected appears to be a disk for an Oric Atmos with Microdisc.\n" | |
| "Would you like to switch to that configuration and insert it as a disk?")) | |
| { | |
| swapmach( oric, NULL, (DRV_MICRODISC<<16)|MACH_ATMOS ); | |
| joinpath( tapepath, tapefile ); | |
| diskimage_load( oric, filetmp, 0 ); | |
| } | |
| setemumode( oric, NULL, EM_RUNNING ); | |
| return; | |
| } | |
| if (oric->drivetype != DRV_MICRODISC) | |
| { | |
| if (msgbox(oric, MSGBOX_YES_NO, | |
| "The file you selected appears to be a disk for a use with the Microdisc controller.\n" | |
| "Would you like to switch to that configuration and insert it as a disk?")) | |
| { | |
| swapmach( oric, NULL, (DRV_MICRODISC<<16)|oric->type ); | |
| joinpath( tapepath, tapefile ); | |
| diskimage_load( oric, filetmp, 0 ); | |
| } | |
| setemumode( oric, NULL, EM_RUNNING ); | |
| return; | |
| } | |
| if (msgbox(oric, MSGBOX_YES_NO, | |
| "The file you selected appears to be a disk.\n" | |
| "Would you like to insert it in drive 0?")) | |
| { | |
| joinpath( tapepath, tapefile ); | |
| diskimage_load( oric, filetmp, 0 ); | |
| } | |
| setemumode( oric, NULL, EM_RUNNING ); | |
| return; | |
| case IMG_ATMOS_JASMIN: | |
| if ((oric->type != MACH_ATMOS) && | |
| (oric->type != MACH_ORIC1) && | |
| (oric->type != MACH_PRAVETZ)) | |
| { | |
| if (msgbox(oric, MSGBOX_YES_NO, | |
| "The file you selected appears to be a disk for an Oric Atmos with Jasmin.\n" | |
| "Would you like to switch to that configuration and insert it as a disk?")) | |
| { | |
| swapmach( oric, NULL, (DRV_JASMIN<<16)|MACH_ATMOS ); | |
| joinpath( tapepath, tapefile ); | |
| diskimage_load( oric, filetmp, 0 ); | |
| oric->auto_jasmin_reset = SDL_TRUE; | |
| } | |
| setemumode( oric, NULL, EM_RUNNING ); | |
| return; | |
| } | |
| if (oric->drivetype != DRV_JASMIN) | |
| { | |
| if (msgbox(oric, MSGBOX_YES_NO, | |
| "The file you selected appears to be a disk for a use with the Jasmin controller.\n" | |
| "Would you like to switch to that configuration and insert it as a disk?")) | |
| { | |
| swapmach( oric, NULL, (DRV_JASMIN<<16)|oric->type ); | |
| joinpath( tapepath, tapefile ); | |
| diskimage_load( oric, filetmp, 0 ); | |
| oric->auto_jasmin_reset = SDL_TRUE; | |
| } | |
| setemumode( oric, NULL, EM_RUNNING ); | |
| return; | |
| } | |
| if (msgbox(oric, MSGBOX_YES_NO, | |
| "The file you selected appears to be a disk.\n" | |
| "Would you like to insert it in drive 0?")) | |
| { | |
| joinpath( tapepath, tapefile ); | |
| diskimage_load( oric, filetmp, 0 ); | |
| } | |
| setemumode( oric, NULL, EM_RUNNING ); | |
| return; | |
| case IMG_TELESTRAT_DISK: | |
| if (oric->type != MACH_TELESTRAT) | |
| { | |
| if (msgbox(oric, MSGBOX_YES_NO, | |
| "The file you selected appears to be a disk for the Telestrat.\n" | |
| "Would you like to switch to that configuration and insert it as a disk?")) | |
| { | |
| swapmach( oric, NULL, MACH_TELESTRAT ); | |
| joinpath( tapepath, tapefile ); | |
| diskimage_load( oric, filetmp, 0 ); | |
| } | |
| setemumode( oric, NULL, EM_RUNNING ); | |
| return; | |
| } | |
| if (msgbox(oric, MSGBOX_YES_NO, | |
| "The file you selected appears to be a disk.\n" | |
| "Would you like to insert it in drive 0?")) | |
| { | |
| joinpath( tapepath, tapefile ); | |
| diskimage_load( oric, filetmp, 0 ); | |
| } | |
| setemumode( oric, NULL, EM_RUNNING ); | |
| return; | |
| case IMG_PRAVETZ_DISK: | |
| if (oric->type != MACH_PRAVETZ) | |
| { | |
| if (msgbox(oric, MSGBOX_YES_NO, | |
| "The file you selected appears to be a disk for the Pravetz 8D disk controller.\n" | |
| "Would you like to switch to that configuration and insert it as a disk?")) | |
| { | |
| swapmach( oric, NULL, (DRV_PRAVETZ<<16)|MACH_PRAVETZ ); | |
| joinpath( tapepath, tapefile ); | |
| diskimage_load( oric, filetmp, 0 ); | |
| pravdiskboot( oric ); | |
| } | |
| setemumode( oric, NULL, EM_RUNNING ); | |
| return; | |
| } | |
| if (oric->drivetype != DRV_PRAVETZ) | |
| { | |
| if (msgbox(oric, MSGBOX_YES_NO, | |
| "The file you selected appears to be a disk for the Pravetz disk controller.\n" | |
| "Would you like to switch to that configuration and insert it as a disk?")) | |
| { | |
| swapmach( oric, NULL, (DRV_PRAVETZ<<16)|MACH_PRAVETZ ); | |
| joinpath( tapepath, tapefile ); | |
| diskimage_load( oric, filetmp, 0 ); | |
| pravdiskboot( oric ); | |
| } | |
| setemumode( oric, NULL, EM_RUNNING ); | |
| return; | |
| } | |
| if (msgbox(oric, MSGBOX_YES_NO, | |
| "The file you selected appears to be a disk.\n" | |
| "Would you like to insert it in drive 0?")) | |
| { | |
| joinpath( tapepath, tapefile ); | |
| diskimage_load( oric, filetmp, 0 ); | |
| } | |
| setemumode( oric, NULL, EM_RUNNING ); | |
| return; | |
| case IMG_GUESS_MICRODISC: | |
| if ((oric->drivetype == DRV_PRAVETZ) || | |
| (oric->drivetype == DRV_NONE)) | |
| { | |
| if (msgbox(oric, MSGBOX_YES_NO, | |
| "The file you selected appears to be a disk for a Microdisc or Jasmin system.\n" | |
| "Would you like to switch to Microdisc and insert it as a disk?")) | |
| { | |
| swapmach( oric, NULL, (DRV_MICRODISC<<16)|oric->type ); | |
| joinpath( tapepath, tapefile ); | |
| diskimage_load( oric, filetmp, 0 ); | |
| } | |
| setemumode( oric, NULL, EM_RUNNING ); | |
| return; | |
| } | |
| if (msgbox(oric, MSGBOX_YES_NO, | |
| "The file you selected appears to be a disk.\n" | |
| "Would you like to insert it in drive 0?")) | |
| { | |
| joinpath( tapepath, tapefile ); | |
| diskimage_load( oric, filetmp, 0 ); | |
| } | |
| setemumode( oric, NULL, EM_RUNNING ); | |
| return; | |
| } | |
| tape_load_tap( oric, filetmp ); | |
| if( oric->symbolsautoload ) mon_new_symbols( &oric->usersyms, oric, "symbols", SYM_BESTGUESS, SDL_TRUE, SDL_TRUE ); | |
| setemumode( oric, NULL, EM_RUNNING ); | |
| } | |
| // "insert" a disk into the virtual disk drive, via filerequester | |
| void insertdisk( struct machine *oric, struct osdmenuitem *mitem, int drive ) | |
| { | |
| char *dpath, *dfile; | |
| if( oric->type != MACH_TELESTRAT ) | |
| { | |
| switch (oric->drivetype) | |
| { | |
| case DRV_PRAVETZ: | |
| dpath = pravdiskpath; | |
| dfile = pravdiskfile; | |
| break; | |
| default: | |
| dpath = diskpath; | |
| dfile = diskfile; | |
| break; | |
| } | |
| } else { | |
| dpath = telediskpath; | |
| dfile = telediskfile; | |
| } | |
| if( !filerequester( oric, "Insert disk", dpath, dfile, FR_DISKLOAD ) ) return; | |
| joinpath( dpath, dfile ); | |
| switch (detect_image_type(filetmp)) | |
| { | |
| case IMG_SNAPSHOT: | |
| if (msgbox(oric, MSGBOX_YES_NO, | |
| "The file you selected appears to be a snapshot file.\n" | |
| "Would you like to load it? (All RAM and machine state will be lost)")) | |
| { | |
| load_snapshot(oric, filetmp); | |
| return; | |
| } | |
| break; | |
| case IMG_ATMOS_MICRODISC: | |
| if ((oric->type != MACH_ATMOS) && | |
| (oric->type != MACH_ORIC1) && | |
| (oric->type != MACH_PRAVETZ)) | |
| { | |
| if (msgbox(oric, MSGBOX_YES_NO, | |
| "The file you selected appears to be for an Oric Atmos with Microdisc.\n" | |
| "Would you like to switch to that configuration?")) | |
| { | |
| swapmach( oric, NULL, (DRV_MICRODISC<<16)|MACH_ATMOS ); | |
| } | |
| break; | |
| } | |
| if ((oric->drivetype != DRV_MICRODISC) && | |
| (oric->drivetype != DRV_NONE)) | |
| { | |
| if (msgbox(oric, MSGBOX_YES_NO, | |
| "The file you selected appears to be for a use with the Microdisc controller.\n" | |
| "Would you like to switch to that configuration?")) | |
| { | |
| swapmach( oric, NULL, (DRV_MICRODISC<<16)|oric->type ); | |
| } | |
| break; | |
| } | |
| break; | |
| case IMG_ATMOS_JASMIN: | |
| if ((oric->type != MACH_ATMOS) && | |
| (oric->type != MACH_ORIC1) && | |
| (oric->type != MACH_PRAVETZ)) | |
| { | |
| if (msgbox(oric, MSGBOX_YES_NO, | |
| "The file you selected appears to be for an Oric Atmos with Jasmin.\n" | |
| "Would you like to switch to that configuration?")) | |
| { | |
| swapmach( oric, NULL, (DRV_JASMIN<<16)|MACH_ATMOS ); | |
| oric->auto_jasmin_reset = SDL_TRUE; | |
| } | |
| break; | |
| } | |
| if (oric->drivetype == DRV_NONE) | |
| { | |
| swapmach( oric, NULL, (DRV_JASMIN<<16)|oric->type); | |
| oric->auto_jasmin_reset = SDL_TRUE; | |
| break; | |
| } | |
| if (oric->drivetype != DRV_JASMIN) | |
| { | |
| if (msgbox(oric, MSGBOX_YES_NO, | |
| "The file you selected appears to be for a use with the Jasmin controller.\n" | |
| "Would you like to switch to that configuration?")) | |
| { | |
| swapmach( oric, NULL, (DRV_JASMIN<<16)|oric->type ); | |
| oric->auto_jasmin_reset = SDL_TRUE; | |
| } | |
| break; | |
| } | |
| break; | |
| case IMG_TELESTRAT_DISK: | |
| if (oric->type != MACH_TELESTRAT) | |
| { | |
| if (msgbox(oric, MSGBOX_YES_NO, | |
| "The file you selected appears to be for a Telestrat.\n" | |
| "Would you like to switch to that configuration?")) | |
| { | |
| swapmach( oric, NULL, MACH_TELESTRAT ); | |
| } | |
| break; | |
| } | |
| break; | |
| case IMG_PRAVETZ_DISK: | |
| if (oric->type != MACH_PRAVETZ) | |
| { | |
| if (msgbox(oric, MSGBOX_YES_NO, | |
| "The file you selected appears to be for a Pravetz 8D disk controller.\n" | |
| "Would you like to switch to that configuration?")) | |
| { | |
| swapmach( oric, NULL, (DRV_PRAVETZ<<16)|MACH_PRAVETZ ); | |
| pravdiskboot( oric ); | |
| } | |
| break; | |
| } | |
| if (oric->drivetype == DRV_NONE) | |
| { | |
| swapmach( oric, NULL, (DRV_PRAVETZ<<16)|MACH_PRAVETZ ); | |
| pravdiskboot( oric ); | |
| break; | |
| } | |
| if (oric->drivetype != DRV_PRAVETZ) | |
| { | |
| if (msgbox(oric, MSGBOX_YES_NO, | |
| "The file you selected appears to be for a use with the Pravetz disk controller.\n" | |
| "Would you like to switch to that configuration?")) | |
| { | |
| swapmach( oric, NULL, (DRV_PRAVETZ<<16)|MACH_PRAVETZ ); | |
| pravdiskboot( oric ); | |
| } | |
| break; | |
| } | |
| break; | |
| case IMG_GUESS_MICRODISC: | |
| if (oric->drivetype == DRV_PRAVETZ) | |
| { | |
| if (msgbox(oric, MSGBOX_YES_NO, | |
| "The file you selected appears to be for a Microdisc or Jasmin system.\n" | |
| "Would you like to switch to Microdisc?")) | |
| { | |
| swapmach( oric, NULL, (DRV_MICRODISC<<16)|oric->type ); | |
| } | |
| break; | |
| } | |
| break; | |
| case IMG_TAPE: | |
| if (msgbox(oric, MSGBOX_YES_NO, | |
| "This appears to be a tape image...\n" | |
| "Would you like to insert it as a tape?")) | |
| { | |
| oric->lasttapefile[0] = 0; | |
| tape_load_tap( oric, filetmp ); | |
| if( oric->symbolsautoload ) mon_new_symbols( &oric->usersyms, oric, "symbols", SYM_BESTGUESS, SDL_TRUE, SDL_TRUE ); | |
| } | |
| setemumode( oric, NULL, EM_RUNNING ); | |
| return; | |
| } | |
| joinpath( dpath, dfile ); | |
| diskimage_load( oric, filetmp, drive ); | |
| if( oric->drivetype == DRV_NONE ) | |
| { | |
| swapmach( oric, NULL, (DRV_MICRODISC<<16)|oric->type ); | |
| // setemumode( oric, NULL, EM_DEBUG ); | |
| return; | |
| } | |
| setemumode( oric, NULL, EM_RUNNING ); | |
| } | |
| void savesnap( struct machine *oric, struct osdmenuitem *mitem, int dummy ) | |
| { | |
| if( !filerequester( oric, "Save Snapshot", snappath, snapfile, FR_SNAPSHOTSAVE ) ) return; | |
| joinpath( snappath, snapfile ); | |
| save_snapshot( oric, filetmp ); | |
| } | |
| void loadsnap( struct machine *oric, struct osdmenuitem *mitem, int dummy ) | |
| { | |
| if( !filerequester( oric, "Load Snapshot", snappath, snapfile, FR_SNAPSHOTLOAD ) ) return; | |
| joinpath( snappath, snapfile ); | |
| load_snapshot( oric, filetmp ); | |
| } | |
| void softresetoric(struct machine *oric, struct osdmenuitem *mitem, int dummy) | |
| { | |
| oric->cpu.nmi = SDL_TRUE; | |
| oric->cpu.nmicount = 2; | |
| setemumode(oric, NULL, EM_RUNNING); | |
| } | |
| // Reset the oric | |
| void resetoric( struct machine *oric, struct osdmenuitem *mitem, int dummy ) | |
| { | |
| switch( oric->drivetype ) | |
| { | |
| case DRV_MICRODISC: | |
| oric->romdis = SDL_TRUE; | |
| microdisc_init( &oric->md, &oric->wddisk, oric ); | |
| break; | |
| case DRV_JASMIN: | |
| oric->romdis = SDL_TRUE; | |
| break; | |
| default: | |
| oric->romdis = SDL_FALSE; | |
| break; | |
| } | |
| setromon( oric ); | |
| m6502_reset( &oric->cpu ); | |
| via_init( &oric->via, oric, VIA_MAIN ); | |
| via_init( &oric->tele_via, oric, VIA_TELESTRAT ); | |
| ay_init( &oric->ay, oric ); | |
| oric->cpu.rastercycles = oric->cyclesperraster; | |
| oric->frames = 0; | |
| if( oric->autorewind ) tape_rewind( oric ); | |
| setemumode( oric, NULL, EM_RUNNING ); | |
| } | |
| struct osdmenuitem *find_item_by_function(struct osdmenuitem *menu, void *function) | |
| { | |
| int i; | |
| static struct osdmenuitem dummyitem; /* So we can always return non-NULL */ | |
| for (i=0; menu[i].name; i++) | |
| if (menu[i].func == function) | |
| return &menu[i]; | |
| return &dummyitem; | |
| } | |
| struct osdmenuitem *find_item_by_function_and_arg(struct osdmenuitem *menu, void *function, int arg) | |
| { | |
| int i; | |
| static struct osdmenuitem dummyitem; /* So we can always return non-NULL */ | |
| for (i=0; menu[i].name; i++) | |
| if ((menu[i].func == function) && (menu[i].arg == arg)) | |
| return &menu[i]; | |
| return &dummyitem; | |
| } | |
| struct osdmenuitem *find_item_by_key(struct osdmenuitem *menu, int sdlkey) | |
| { | |
| int i; | |
| static struct osdmenuitem dummyitem; /* So we can always return non-NULL */ | |
| for (i=0; menu[i].name; i++) | |
| if (menu[i].sdlkey == sdlkey) | |
| return &menu[i]; | |
| return &dummyitem; | |
| } | |
| // Turn tape noise on/off | |
| void toggletapenoise( struct machine *oric, struct osdmenuitem *mitem, int dummy ) | |
| { | |
| if( oric->tapenoise ) | |
| { | |
| oric->ay.tapeout = 0; | |
| oric->tapenoise = SDL_FALSE; | |
| mitem->name = " Tape noise"; | |
| return; | |
| } | |
| oric->tapenoise = SDL_TRUE; | |
| mitem->name = "\x0e""Tape noise"; | |
| } | |
| // Toggle sound on/off | |
| void togglesound( struct machine *oric, struct osdmenuitem *mitem, int dummy ) | |
| { | |
| if( ( soundon ) || (!soundavailable) ) | |
| { | |
| soundon = SDL_FALSE; | |
| oric->ay.soundon = SDL_FALSE; | |
| mitem->name = " Sound enabled"; | |
| if( soundavailable ) SDL_PauseAudio( 1 ); | |
| return; | |
| } | |
| soundon = SDL_TRUE; | |
| oric->ay.soundon = !warpspeed; | |
| mitem->name = "\x0e""Sound enabled"; | |
| if( oric->emu_mode == EM_RUNNING ) SDL_PauseAudio( !warpspeed ); | |
| } | |
| // Toggle turbotape on/off | |
| void toggletapeturbo( struct machine *oric, struct osdmenuitem *mitem, int dummy ) | |
| { | |
| oric->tapeturbo_forceoff = SDL_FALSE; | |
| if( oric->tapeturbo ) | |
| { | |
| oric->tapeturbo = SDL_FALSE; | |
| mitem->name = " Turbo tape"; | |
| return; | |
| } | |
| oric->tapeturbo = SDL_TRUE; | |
| mitem->name = "\x0e""Turbo tape"; | |
| } | |
| // Toggle VSync Hack | |
| void togglevsynchack( struct machine *oric, struct osdmenuitem *mitem, int dummy ) | |
| { | |
| if( oric->vsynchack ) | |
| { | |
| oric->vsynchack = SDL_FALSE; | |
| mitem->name = " VSync hack"; | |
| return; | |
| } | |
| oric->vsynchack = SDL_TRUE; | |
| mitem->name = "\x0e""VSync hack"; | |
| } | |
| // Toggle lightpen | |
| void togglelightpen( struct machine *oric, struct osdmenuitem *mitem, int dummy ) | |
| { | |
| if( oric->lightpen ) | |
| { | |
| oric->lightpen = SDL_FALSE; | |
| oric->cpu.read = oric->read_not_lightpen; | |
| mitem->name = " Lightpen"; | |
| return; | |
| } | |
| oric->lightpen = SDL_TRUE; | |
| oric->cpu.read = lightpen_read; | |
| mitem->name = "\x0e""Lightpen"; | |
| } | |
| // Toggle tele acia (Serial card) | |
| void toggleaciabackend( struct machine *oric, struct osdmenuitem *mitem, int dummy ) | |
| { | |
| if( oric->aciabackend ) | |
| { | |
| oric->aciabackend = ACIA_TYPE_NONE; | |
| mitem->name = aciabackends[oric->aciabackend]; | |
| } | |
| else | |
| { | |
| oric->aciabackend = oric->aciabackendcfg; | |
| mitem->name = aciabackendlabel; | |
| } | |
| acia_init( &oric->tele_acia, oric ); | |
| } | |
| // Toggle ch376 on/off | |
| void togglech376(struct machine *oric, struct osdmenuitem *mitem, int dummy) | |
| { | |
| if (oric->ch376_activated) | |
| { | |
| oric->ch376_activated = SDL_FALSE; | |
| mitem->name = " CH376 (Telestrat)"; | |
| return; | |
| } | |
| oric->ch376_activated = SDL_TRUE; | |
| mitem->name = "\x0e""CH376 (Telestrat)"; | |
| oric->ch376 = ch376_oric_init(); | |
| if (oric->ch376 != NULL) | |
| ch376_oric_config(oric->ch376); | |
| } | |
| // Toggle twilighte on/off | |
| void toggletwilighte(struct machine *oric, struct osdmenuitem *mitem, int dummy) | |
| { | |
| if (oric->twilighteboard_activated) | |
| { | |
| oric->twilighteboard_activated = SDL_FALSE; | |
| mitem->name = " Twilighte board"; | |
| return; | |
| } | |
| oric->twilighteboard_activated = SDL_TRUE; | |
| mitem->name = "\x0e""Twilighte board"; | |
| oric->twilighte = twilighte_oric_init(); | |
| if (oric->twilighte == NULL) | |
| { | |
| oric->twilighteboard_activated = SDL_FALSE; // Impossible to create struct, we did not activate twilighteboard | |
| } | |
| else | |
| { | |
| oric->ch376_activated = SDL_TRUE; | |
| } | |
| } | |
| // Toggle symbols autoload | |
| void togglesymbolsauto( struct machine *oric, struct osdmenuitem *mitem, int dummy ) | |
| { | |
| if( oric->symbolsautoload ) | |
| { | |
| oric->symbolsautoload = SDL_FALSE; | |
| mitem->name = " Autoload symbols file"; | |
| return; | |
| } | |
| oric->symbolsautoload = SDL_TRUE; | |
| mitem->name = "\x0e""Autoload symbols file"; | |
| } | |
| // Toggle case sensitive symbols | |
| void togglecasesyms( struct machine *oric, struct osdmenuitem *mitem, int dummy ) | |
| { | |
| if( oric->symbolscase ) | |
| { | |
| oric->symbolscase = SDL_FALSE; | |
| mitem->name = " Case-sensitive symbols"; | |
| return; | |
| } | |
| oric->symbolscase = SDL_TRUE; | |
| mitem->name = "\x0e""Case-sensitive symbols"; | |
| } | |
| // Toggle autorewind on/off | |
| void toggleautowind( struct machine *oric, struct osdmenuitem *mitem, int dummy ) | |
| { | |
| if( oric->autorewind ) | |
| { | |
| oric->autorewind = SDL_FALSE; | |
| mitem->name = " Autorewind tape"; | |
| return; | |
| } | |
| oric->autorewind = SDL_TRUE; | |
| mitem->name = "\x0e""Autorewind tape"; | |
| } | |
| // Toggle autoinsert on/off | |
| void toggleautoinsrt( struct machine *oric, struct osdmenuitem *mitem, int dummy ) | |
| { | |
| if( oric->autoinsert ) | |
| { | |
| oric->autoinsert = SDL_FALSE; | |
| mitem->name = " Autoinsert tape"; | |
| return; | |
| } | |
| oric->autoinsert = SDL_TRUE; | |
| mitem->name = "\x0e""Autoinsert tape"; | |
| } | |
| // Toggle fullscreen on/off | |
| void togglefullscreen( struct machine *oric, struct osdmenuitem *mitem, int dummy ) | |
| { | |
| if( !oric->render_togglefullscreen( oric ) ) return; // Failed :-( | |
| if( fullscreen ) | |
| { | |
| find_item_by_function(vdopitems, togglefullscreen)->name = "\x0e""Fullscreen"; | |
| find_item_by_function(glopitems, togglefullscreen)->name = "\x0e""Fullscreen"; | |
| return; | |
| } | |
| find_item_by_function(vdopitems, togglefullscreen)->name = " Fullscreen"; | |
| find_item_by_function(glopitems, togglefullscreen)->name = " Fullscreen"; | |
| } | |
| // Toggle 50Hz/60Hz aspect ratio | |
| void togglearatio( struct machine *oric, struct osdmenuitem *mitem, int dummy ) | |
| { | |
| if( oric->aratio ) | |
| { | |
| oric->aratio = SDL_FALSE; | |
| mitem->name = " 50Hz/60Hz aspect ratio"; | |
| return; | |
| } | |
| oric->aratio = SDL_TRUE; | |
| mitem->name = "\x0e""50Hz/60Hz aspect ratio"; | |
| } | |
| // Toggle hstretch on/off | |
| void togglehstretch( struct machine *oric, struct osdmenuitem *mitem, int dummy ) | |
| { | |
| if( oric->hstretch ) | |
| { | |
| oric->hstretch = SDL_FALSE; | |
| mitem->name = " Horizontal stretch"; | |
| return; | |
| } | |
| oric->hstretch = SDL_TRUE; | |
| mitem->name = "\x0e""Horizontal stretch"; | |
| } | |
| // Toggle PAL ghosting on/off | |
| void togglepalghost( struct machine *oric, struct osdmenuitem *mitem, int dummy ) | |
| { | |
| if( oric->palghost ) | |
| { | |
| oric->palghost = SDL_FALSE; | |
| mitem->name = " PAL ghosting"; | |
| return; | |
| } | |
| oric->palghost = SDL_TRUE; | |
| mitem->name = "\x0e""PAL ghosting"; | |
| } | |
| // Toggle scanlines on/off | |
| void togglescanlines( struct machine *oric, struct osdmenuitem *mitem, int dummy ) | |
| { | |
| if( oric->scanlines ) | |
| { | |
| oric->scanlines = SDL_FALSE; | |
| find_item_by_function(vdopitems, togglescanlines)->name = " Scanlines"; | |
| find_item_by_function(glopitems, togglescanlines)->name = " Scanlines"; | |
| return; | |
| } | |
| oric->scanlines = SDL_TRUE; | |
| find_item_by_function(vdopitems, togglescanlines)->name = "\x0e""Scanlines"; | |
| find_item_by_function(glopitems, togglescanlines)->name = "\x0e""Scanlines"; | |
| } | |
| void setoverclock( struct machine *oric, struct osdmenuitem *mitem, int value ) | |
| { | |
| int i; | |
| /* Don't want to just modify name[0], since */ | |
| /* string constants are supposed to be constant.. */ | |
| char *setnames[] = { "\x0e"" 1MHz (None)", "\x0e"" 2MHz", "\x0e"" 4MHz", "\x0e"" 8MHz", | |
| "\x0e""16MHz", "\x0e""32MHz", "\x0e""64MHz" }; | |
| char *unsetnames[] = { " 1MHz (None)", " 2MHz", " 4MHz", " 8MHz", | |
| " 16MHz", " 32MHz", " 64MHz" }; | |
| oric->overclockmult = 1<<value; | |
| oric->overclockshift = value; | |
| for( i=0; i<7; i++ ) | |
| { | |
| if(i == value) | |
| ovopitems[i].name = setnames[i]; | |
| else | |
| ovopitems[i].name = unsetnames[i]; | |
| } | |
| } | |
| // Go to internet site | |
| void gotosite( struct machine *oric, struct osdmenuitem *mitem, int dummy ) | |
| { | |
| /* TODO: mode those to their own gui_*.c */ | |
| #if defined(__MORPHOS__) || defined(__AROS__) | |
| struct Library *OpenURLBase = OpenLibrary( "openurl.library", 0 ); | |
| static const struct TagItem URLTags[] = {{TAG_DONE, (ULONG) NULL}}; | |
| if( OpenURLBase ) | |
| { | |
| URL_OpenA(mitem->name, (struct TagItem*) URLTags); | |
| CloseLibrary( OpenURLBase ); | |
| } | |
| #elif defined(__amigaos4__) | |
| char tmp[256]; | |
| BPTR h; | |
| sprintf( tmp, "URL:%s", mitem->name ); | |
| if( ( h = IDOS->Open( tmp, MODE_OLDFILE ) ) ) IDOS->Close( h ); | |
| #elif defined(WIN32) || defined(__APPLE__) || defined(__BEOS__) || defined(__HAIKU__) | |
| gui_open_url( mitem->name ); | |
| #else | |
| /* default: assume XDG-compliant desktop */ | |
| char tmp[256]; | |
| sprintf( tmp, "xdg-open '%s'", mitem->name ); | |
| system( tmp ); | |
| #endif | |
| } | |
| // Go to a different menu | |
| void gotomenu( struct machine *oric, struct osdmenuitem *mitem, int menunum ) | |
| { | |
| int i, w, keyw; | |
| if( tz[TZ_MENU] ) free_textzone( oric, TZ_MENU ); | |
| cmenu = &menus[menunum]; | |
| w = (int)strlen( cmenu->title )+8; | |
| keyw = 0; | |
| for( i=0; cmenu->items[i].name; i++ ) | |
| { | |
| if( cmenu->items[i].name == OSDMENUBAR ) | |
| continue; | |
| if( strlen( cmenu->items[i].name ) > w ) | |
| w = (int)strlen( cmenu->items[i].name ); | |
| if( cmenu->items[i].key ) | |
| { | |
| if( (strlen( cmenu->items[i].key )+1) > keyw ) | |
| keyw = (int)strlen( cmenu->items[i].key )+1; | |
| } | |
| } | |
| w+=keyw+2; i+=2; | |
| if( !alloc_textzone( oric, TZ_MENU, 320-w*4, 240-i*6, w, i, cmenu->title ) ) | |
| { | |
| cmenu = NULL; | |
| oric->emu_mode = EM_RUNNING; | |
| return; | |
| } | |
| drawitems(); | |
| } | |
| void togglekeyboard( struct machine *oric, struct osdmenuitem *mitem, int dummy ) | |
| { | |
| if( oric->show_keyboard ) | |
| { | |
| oric->show_keyboard = SDL_FALSE; | |
| mitem->name = " Show keyboard"; | |
| oric->shut_render(oric); | |
| oric->init_render(oric); | |
| return; | |
| } | |
| oric->show_keyboard = SDL_TRUE; | |
| mitem->name = "\x0e""Show keyboard"; | |
| oric->shut_render(oric); | |
| oric->init_render(oric); | |
| setemumode( oric, NULL, EM_RUNNING ); | |
| } | |
| void definemapping( struct machine *oric, struct osdmenuitem *mitem, int dummy ) | |
| { | |
| if( oric->define_mapping ) | |
| { | |
| oric->define_mapping = SDL_FALSE; | |
| mitem->name = " Define mapping"; | |
| return; | |
| } | |
| oric->define_mapping = SDL_TRUE; | |
| mitem->name = "\x0e""Define mapping"; | |
| if(!oric->show_keyboard) { | |
| find_item_by_function(keopitems, togglekeyboard)->name = "\x0e""Show keyboard"; | |
| oric->show_keyboard = SDL_TRUE; | |
| oric->shut_render(oric); | |
| oric->init_render(oric); | |
| } | |
| cmenu = NULL; | |
| oric->emu_mode = EM_RUNNING; | |
| do_popup( oric, "Click on an Oric key." ); | |
| setemumode( oric, NULL, EM_RUNNING ); | |
| } | |
| void togglestickykeys( struct machine *oric, struct osdmenuitem *mitem, int dummy ) | |
| { | |
| if( oric->sticky_mod_keys ) | |
| { | |
| oric->sticky_mod_keys = SDL_FALSE; | |
| mitem->name = " Sticky mod keys"; | |
| release_sticky_keys(); | |
| return; | |
| } | |
| oric->sticky_mod_keys = SDL_TRUE; | |
| mitem->name = "\x0e""Sticky mod keys"; | |
| setemumode( oric, NULL, EM_RUNNING ); | |
| } | |
| void savemapping( struct machine *oric, struct osdmenuitem *mitem, int dummy ) | |
| { | |
| if( !filerequester( oric, "Save Keyboard Mapping", mappingpath, mappingfile, FR_KEYMAPPINGSAVE ) ) return; | |
| joinpath( mappingpath, mappingfile ); | |
| save_keyboard_mapping(oric, filetmp); | |
| setemumode( oric, NULL, EM_RUNNING ); | |
| } | |
| void loadmapping( struct machine *oric, struct osdmenuitem *mitem, int dummy ) | |
| { | |
| if( !filerequester( oric, "Load Keyboard Mapping", mappingpath, mappingfile, FR_KEYMAPPINGLOAD ) ) return; | |
| joinpath( mappingpath, mappingfile ); | |
| load_keyboard_mapping(oric, filetmp); | |
| setemumode( oric, NULL, EM_RUNNING ); | |
| } | |
| void resetmapping( struct machine *oric, struct osdmenuitem *mitem, int dummy ) | |
| { | |
| reset_keyboard_mapping(&(oric->keyboard_mapping)); | |
| setemumode( oric, NULL, EM_RUNNING ); | |
| } | |
| #ifdef __CBCOPY__ | |
| void clipbd_copy_gui( struct machine *oric, struct osdmenuitem *mitem, int dummy ) | |
| { | |
| clipboard_copy(oric); | |
| setemumode( oric, NULL, EM_RUNNING ); | |
| } | |
| #endif | |
| #ifdef __CBPASTE__ | |
| void clipbd_paste_gui( struct machine *oric, struct osdmenuitem *mitem, int dummy ) | |
| { | |
| clipboard_paste(oric); | |
| setemumode( oric, NULL, EM_RUNNING ); | |
| } | |
| #endif | |
| /************************* End of menu callable funcs *******************************/ | |
| // This is the event handler for when you are in the menus | |
| SDL_bool menu_event( SDL_Event *ev, struct machine *oric, SDL_bool *needrender ) | |
| { | |
| SDL_bool done = SDL_FALSE; | |
| int i, x, y; | |
| // Wot, no menu?! | |
| if( ( !cmenu ) || ( !tz[TZ_MENU] ) ) | |
| return done; | |
| x = -1; | |
| y = -1; | |
| switch( ev->type ) | |
| { | |
| case SDL_MOUSEMOTION: | |
| x = (ev->motion.x - tz[TZ_MENU]->x)/8; | |
| y = (ev->motion.y - tz[TZ_MENU]->y)/12-1; | |
| break; | |
| case SDL_MOUSEBUTTONDOWN: | |
| if( ev->button.button == SDL_BUTTON_LEFT ) | |
| { | |
| x = (ev->button.x - tz[TZ_MENU]->x)/8; | |
| y = (ev->button.y - tz[TZ_MENU]->y)/12-1; | |
| } | |
| break; | |
| } | |
| switch( ev->type ) | |
| { | |
| case SDL_COMPAT_ACTIVEEVENT: | |
| if(SDL_COMPAT_IsAppFocused(ev)) { | |
| *needrender = SDL_TRUE; | |
| } | |
| break; | |
| case SDL_MOUSEMOTION: | |
| case SDL_MOUSEBUTTONDOWN: | |
| x = (ev->motion.x - tz[TZ_MENU]->x)/8; | |
| y = (ev->motion.y - tz[TZ_MENU]->y)/12-1; | |
| if( ( x < 0 ) || ( y < 0 ) || | |
| ( x >= tz[TZ_MENU]->w ) ) | |
| break; | |
| for( i=0; i<y; i++ ) | |
| if( cmenu->items[i].name == NULL ) | |
| break; | |
| if( ( i != y ) || ( cmenu->items[y].name == OSDMENUBAR ) || ( cmenu->items[y].func == NULL ) ) | |
| break; | |
| cmenu->citem = y; | |
| if( ( ev->type == SDL_MOUSEBUTTONDOWN ) && | |
| ( (ev->button.button==SDL_BUTTON_LEFT) || | |
| (ev->button.button==SDL_BUTTON_RIGHT) ) ) | |
| cmenu->items[cmenu->citem].func( oric, &cmenu->items[cmenu->citem], cmenu->items[cmenu->citem].arg ); | |
| drawitems(); | |
| *needrender = SDL_TRUE; | |
| break; | |
| case SDL_KEYDOWN: | |
| switch( ev->key.keysym.sym ) | |
| { | |
| case SDLK_UP: | |
| // Find the next selectable item above this one | |
| i = cmenu->citem-1; | |
| while( ( cmenu->items[i].name == OSDMENUBAR ) || | |
| ( cmenu->items[i].func == NULL ) ) | |
| { | |
| if( i < 0 ) break; | |
| i--; | |
| } | |
| // Hit the top? | |
| if( ( i < 0 ) || ( cmenu->items[i].name == OSDMENUBAR ) ) | |
| { | |
| // Start the search again from the last item | |
| for( i=0; cmenu->items[i].name; i++ ) ; | |
| i--; | |
| // Find the first selectable item from here | |
| while( ( cmenu->items[i].name == OSDMENUBAR ) || | |
| ( cmenu->items[i].func == NULL ) ) | |
| { | |
| if( i < 0 ) break; | |
| i--; | |
| } | |
| if( ( i < 0 ) || ( cmenu->items[i].name == OSDMENUBAR ) ) break; | |
| } | |
| cmenu->citem = i; | |
| drawitems(); | |
| *needrender = SDL_TRUE; | |
| break; | |
| case SDLK_DOWN: | |
| i = cmenu->citem+1; | |
| while( ( cmenu->items[i].name == OSDMENUBAR ) || | |
| ( cmenu->items[i].func == NULL ) ) | |
| { | |
| if( cmenu->items[i].name == NULL ) break; | |
| i++; | |
| } | |
| if( ( cmenu->items[i].name == NULL ) || ( cmenu->items[i].name == OSDMENUBAR ) ) | |
| { | |
| i=0; | |
| while( ( cmenu->items[i].name == OSDMENUBAR ) || | |
| ( cmenu->items[i].func == NULL ) ) | |
| { | |
| if( cmenu->items[i].name == NULL ) break; | |
| i++; | |
| } | |
| if( ( cmenu->items[i].name == NULL ) || ( cmenu->items[i].name == OSDMENUBAR ) ) | |
| break; | |
| } | |
| cmenu->citem = i; | |
| drawitems(); | |
| *needrender = SDL_TRUE; | |
| break; | |
| default: | |
| break; | |
| } | |
| break; | |
| case SDL_KEYUP: | |
| switch( ev->key.keysym.sym ) | |
| { | |
| case SDLK_RETURN: | |
| case SDLK_KP_ENTER: | |
| if( !cmenu->items[cmenu->citem].func ) break; | |
| cmenu->items[cmenu->citem].func( oric, &cmenu->items[cmenu->citem], cmenu->items[cmenu->citem].arg ); | |
| drawitems(); | |
| *needrender = SDL_TRUE; | |
| break; | |
| case SDLK_ESCAPE: | |
| setemumode( oric, NULL, EM_RUNNING ); | |
| *needrender = SDL_TRUE; | |
| break; | |
| default: | |
| for( i=0; cmenu->items[i].name; i++ ) | |
| { | |
| if( ( cmenu->items[i].sdlkey ) && | |
| ( cmenu->items[i].sdlkey == ev->key.keysym.sym ) && | |
| ( cmenu->items[i].func ) ) | |
| break; | |
| } | |
| if( !cmenu->items[i].name ) break; | |
| cmenu->items[i].func( oric, &cmenu->items[i], cmenu->items[i].arg ); | |
| drawitems(); | |
| *needrender = SDL_TRUE; | |
| break; | |
| } | |
| break; | |
| } | |
| if (*needrender) ula_set_dirty(oric); | |
| return done; | |
| } | |
| void set_render_mode( struct machine *oric, int whichrendermode ) | |
| { | |
| oric->rendermode = whichrendermode; | |
| switch( whichrendermode ) | |
| { | |
| case RENDERMODE_SW: | |
| if (oric->sw_depth == 8) | |
| { | |
| oric->render_begin = render_begin_sw8; | |
| oric->render_end = render_end_sw8; | |
| oric->render_textzone_alloc = render_textzone_alloc_sw8; | |
| oric->render_textzone_free = render_textzone_free_sw8; | |
| oric->render_textzone = render_textzone_sw8; | |
| oric->render_clear_area = render_clear_area_sw8; | |
| oric->render_gimg = render_gimg_sw8; | |
| oric->render_gimgpart = render_gimgpart_sw8; | |
| oric->render_video = render_video_sw8; | |
| oric->render_togglefullscreen = render_togglefullscreen_sw8; | |
| oric->init_render = init_render_sw8; | |
| oric->shut_render = shut_render_sw8; | |
| find_item_by_function_and_arg(vdopitems, swap_render_mode, RENDERMODE_GL)->name = " OpenGL rendering"; | |
| find_item_by_function_and_arg(glopitems, swap_render_mode, RENDERMODE_GL)->name = " OpenGL rendering"; | |
| find_item_by_function_and_arg(vdopitems, swap_render_mode, RENDERMODE_SW)->name = "\x0e""Software rendering"; | |
| find_item_by_function_and_arg(glopitems, swap_render_mode, RENDERMODE_SW)->name = "\x0e""Software rendering"; | |
| menus[4].items = vdopitems; | |
| break; | |
| } | |
| oric->render_begin = render_begin_sw; | |
| oric->render_end = render_end_sw; | |
| oric->render_textzone_alloc = render_textzone_alloc_sw; | |
| oric->render_textzone_free = render_textzone_free_sw; | |
| oric->render_textzone = render_textzone_sw; | |
| oric->render_clear_area = render_clear_area_sw; | |
| oric->render_gimg = render_gimg_sw; | |
| oric->render_gimgpart = render_gimgpart_sw; | |
| switch(oric->sw_depth) | |
| { | |
| case 16: | |
| oric->render_video = render_video_sw_16bpp; | |
| break; | |
| case 32: | |
| oric->render_video = render_video_sw_32bpp; | |
| break; | |
| default: | |
| // If we get there, it would be safe to give up | |
| oric->render_video = render_video_sw_16bpp; | |
| break; | |
| } | |
| oric->render_togglefullscreen = render_togglefullscreen_sw; | |
| oric->init_render = init_render_sw; | |
| oric->shut_render = shut_render_sw; | |
| find_item_by_function_and_arg(vdopitems, swap_render_mode, RENDERMODE_GL)->name = " OpenGL rendering"; | |
| find_item_by_function_and_arg(glopitems, swap_render_mode, RENDERMODE_GL)->name = " OpenGL rendering"; | |
| find_item_by_function_and_arg(vdopitems, swap_render_mode, RENDERMODE_SW)->name = "\x0e""Software rendering"; | |
| find_item_by_function_and_arg(glopitems, swap_render_mode, RENDERMODE_SW)->name = "\x0e""Software rendering"; | |
| menus[4].items = vdopitems; | |
| break; | |
| #ifdef __OPENGL_AVAILABLE__ | |
| case RENDERMODE_GL: | |
| oric->render_begin = render_begin_gl; | |
| oric->render_end = render_end_gl; | |
| oric->render_textzone_alloc = render_textzone_alloc_gl; | |
| oric->render_textzone_free = render_textzone_free_gl; | |
| oric->render_textzone = render_textzone_gl; | |
| oric->render_clear_area = render_clear_area_gl; | |
| oric->render_gimg = render_gimg_gl; | |
| oric->render_gimgpart = render_gimgpart_gl; | |
| oric->render_video = render_video_gl; | |
| oric->render_togglefullscreen = render_togglefullscreen_gl; | |
| oric->init_render = init_render_gl; | |
| oric->shut_render = shut_render_gl; | |
| find_item_by_function_and_arg(vdopitems, swap_render_mode, RENDERMODE_GL)->name = "\x0e""OpenGL rendering"; | |
| find_item_by_function_and_arg(glopitems, swap_render_mode, RENDERMODE_GL)->name = "\x0e""OpenGL rendering"; | |
| find_item_by_function_and_arg(vdopitems, swap_render_mode, RENDERMODE_SW)->name = " Software rendering"; | |
| find_item_by_function_and_arg(glopitems, swap_render_mode, RENDERMODE_SW)->name = " Software rendering"; | |
| menus[4].items = glopitems; | |
| break; | |
| #endif | |
| default: | |
| oric->render_begin = render_begin_null; | |
| oric->render_end = render_end_null; | |
| oric->render_textzone_alloc = render_textzone_alloc_null; | |
| oric->render_textzone_free = render_textzone_free_null; | |
| oric->render_textzone = render_textzone_null; | |
| oric->render_clear_area = render_clear_area_null; | |
| oric->render_gimg = render_gimg_null; | |
| oric->render_gimgpart = render_gimgpart_null; | |
| oric->render_video = render_video_null; | |
| oric->render_togglefullscreen = render_togglefullscreen_null; | |
| oric->init_render = init_render_null; | |
| oric->shut_render = shut_render_null; | |
| find_item_by_function_and_arg(vdopitems, swap_render_mode, RENDERMODE_GL)->name = " OpenGL rendering"; | |
| find_item_by_function_and_arg(glopitems, swap_render_mode, RENDERMODE_GL)->name = " OpenGL rendering"; | |
| find_item_by_function_and_arg(vdopitems, swap_render_mode, RENDERMODE_SW)->name = " Software rendering"; | |
| find_item_by_function_and_arg(glopitems, swap_render_mode, RENDERMODE_SW)->name = " Software rendering"; | |
| menus[4].items = vdopitems; | |
| break; | |
| } | |
| } | |
| void swap_render_mode( struct machine *oric, struct osdmenuitem *mitem, int newrendermode ) | |
| { | |
| if( oric->rendermode == newrendermode ) return; | |
| shut_gui( oric ); | |
| shut_joy( oric ); | |
| SDL_COMPAT_Quit( SDL_FALSE ); | |
| need_sdl_quit = SDL_FALSE; | |
| // Go SDL! | |
| if( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_AUDIO ) < 0 ) | |
| { | |
| error_printf( "SDL init failed\n" ); | |
| oric->emu_mode = EM_PLEASEQUIT; | |
| return; | |
| } | |
| need_sdl_quit = SDL_TRUE; | |
| if( !init_gui( oric, newrendermode ) ) | |
| { | |
| oric->emu_mode = EM_PLEASEQUIT; | |
| return; | |
| } | |
| if( !ay_init( &oric->ay, oric ) ) | |
| { | |
| oric->emu_mode = EM_PLEASEQUIT; | |
| return; | |
| } | |
| if( !init_joy( oric ) ) | |
| { | |
| oric->emu_mode = EM_PLEASEQUIT; | |
| return; | |
| } | |
| if( !init_filerequester( oric ) ) | |
| { | |
| oric->emu_mode = EM_PLEASEQUIT; | |
| return; | |
| } | |
| if( !init_msgbox( oric ) ) | |
| { | |
| oric->emu_mode = EM_PLEASEQUIT; | |
| return; | |
| } | |
| joy_setup( oric ); | |
| mon_warminit( oric ); | |
| setemumode( oric, NULL, EM_RUNNING ); | |
| } | |
| // Set things to default that can't fail | |
| void preinit_gui( struct machine *oric ) | |
| { | |
| int i; | |
| for( i=0; i<NUM_TZ; i++ ) tz[i] = NULL; | |
| for( i=0; i<NUM_GIMG; i++ ) gimgs[i].buf = NULL; | |
| strcpy( tapepath, FILEPREFIX"tapes" ); | |
| strcpy( tapefile, "" ); | |
| strcpy( diskpath, FILEPREFIX"disks" ); | |
| strcpy( diskfile, "" ); | |
| strcpy( telediskpath, FILEPREFIX"teledisks" ); | |
| strcpy( telediskfile, "" ); | |
| strcpy( pravdiskpath, FILEPREFIX"pravdisks" ); | |
| strcpy( pravdiskfile, "" ); | |
| strcpy( atmosromfile, ROMPREFIX"basic11b" ); | |
| strcpy( oric1romfile, ROMPREFIX"basic10" ); | |
| strcpy( mdiscromfile, ROMPREFIX"microdis" ); | |
| strcpy( bd500romfile, ROMPREFIX"bd500" ); | |
| strcpy( jasmnromfile, ROMPREFIX"jasmin" ); | |
| strcpy( pravetzromfile[0], ROMPREFIX"pravetzt" ); | |
| strcpy( pravetzromfile[1], ROMPREFIX"8dos2" ); | |
| telebankfiles[0][0] = 0; | |
| telebankfiles[1][0] = 0; | |
| telebankfiles[2][0] = 0; | |
| telebankfiles[3][0] = 0; | |
| telebankfiles[4][0] = 0; | |
| strcpy( telebankfiles[5], ROMPREFIX"teleass" ); | |
| strcpy( telebankfiles[6], ROMPREFIX"hyperbas" ); | |
| strcpy( telebankfiles[7], ROMPREFIX"telmon24" ); | |
| set_render_mode( oric, RENDERMODE_NULL ); | |
| strcpy( snappath, FILEPREFIX"snapshots" ); | |
| strcpy( snapfile, "" ); | |
| strcpy( mappingpath, FILEPREFIX"keymap" ); | |
| strcpy( mappingfile, "" ); | |
| #ifndef __APPLE__ | |
| SDL_COMPAT_WM_SetIcon( SDL_LoadBMP( IMAGEPREFIX"winicon.bmp" ), NULL ); | |
| #endif | |
| } | |
| // Ensure the sanity of toggle menuitems | |
| void setmenutoggles( struct machine *oric ) | |
| { | |
| switch (oric->drivetype) | |
| { | |
| case DRV_JASMIN: | |
| case DRV_MICRODISC: | |
| case DRV_BD500: | |
| find_item_by_key(mainitems, SDLK_0)->func = insertdisk; | |
| find_item_by_key(mainitems, SDLK_1)->func = insertdisk; | |
| find_item_by_key(mainitems, SDLK_2)->func = insertdisk; | |
| find_item_by_key(mainitems, SDLK_3)->func = insertdisk; | |
| break; | |
| case DRV_PRAVETZ: | |
| default: | |
| find_item_by_key(mainitems, SDLK_0)->func = insertdisk; | |
| find_item_by_key(mainitems, SDLK_1)->func = insertdisk; | |
| find_item_by_key(mainitems, SDLK_2)->func = NULL; | |
| find_item_by_key(mainitems, SDLK_3)->func = NULL; | |
| break; | |
| } | |
| if( soundavailable && soundon ) | |
| find_item_by_function(auopitems, togglesound)->name = "\x0e""Sound enabled"; | |
| else | |
| find_item_by_function(auopitems, togglesound)->name = " Sound enabled"; | |
| if( oric->tapenoise ) | |
| find_item_by_function(auopitems, toggletapenoise)->name = "\x0e""Tape noise"; | |
| else | |
| find_item_by_function(auopitems, toggletapenoise)->name = " Tape noise"; | |
| if( oric->tapeturbo ) | |
| find_item_by_function(hwopitems, toggletapeturbo)->name = "\x0e""Turbo tape"; | |
| else | |
| find_item_by_function(hwopitems, toggletapeturbo)->name = " Turbo tape"; | |
| if( oric->autoinsert ) | |
| find_item_by_function(hwopitems, toggleautoinsrt)->name = "\x0e""Autoinsert tape"; | |
| else | |
| find_item_by_function(hwopitems, toggleautoinsrt)->name = " Autoinsert tape"; | |
| if( oric->autorewind ) | |
| find_item_by_function(hwopitems, toggleautowind)->name = "\x0e""Autorewind tape"; | |
| else | |
| find_item_by_function(hwopitems, toggleautowind)->name = " Autorewind tape"; | |
| if( oric->vsynchack ) | |
| find_item_by_function(hwopitems, togglevsynchack)->name = "\x0e""VSync hack"; | |
| else | |
| find_item_by_function(hwopitems, togglevsynchack)->name = " VSync hack"; | |
| if( oric->lightpen ) | |
| find_item_by_function(hwopitems, togglelightpen)->name = "\x0e""Lightpen"; | |
| else | |
| find_item_by_function(hwopitems, togglelightpen)->name = " Lightpen"; | |
| if( oric->aciabackend ) | |
| { | |
| strcpy(aciabackendlabel, aciabackends[oric->aciabackend]); | |
| sprintf(aciabackendlabel+18, "%.4X", oric->aciaoffset); | |
| find_item_by_function(hwopitems, toggleaciabackend)->name = aciabackendlabel; | |
| } | |
| else | |
| find_item_by_function(hwopitems, toggleaciabackend)->name = aciabackends[oric->aciabackend]; | |
| if( oric->symbolsautoload ) | |
| find_item_by_function(dbopitems, togglesymbolsauto)->name = "\x0e""Autoload symbols file"; | |
| else | |
| find_item_by_function(dbopitems, togglesymbolsauto)->name = " Autoload symbols file"; | |
| if( oric->symbolscase ) | |
| find_item_by_function(dbopitems, togglecasesyms)->name = "\x0e""Case-sensitive symbols"; | |
| else | |
| find_item_by_function(dbopitems, togglecasesyms)->name = " Case-sensitive symbols"; | |
| if( fullscreen ) | |
| { | |
| find_item_by_function(vdopitems, togglefullscreen)->name = "\x0e""Fullscreen"; | |
| find_item_by_function(glopitems, togglefullscreen)->name = "\x0e""Fullscreen"; | |
| } else { | |
| find_item_by_function(vdopitems, togglefullscreen)->name = " Fullscreen"; | |
| find_item_by_function(glopitems, togglefullscreen)->name = " Fullscreen"; | |
| } | |
| if( oric->aratio ) | |
| find_item_by_function(glopitems, togglearatio)->name = "\x0e""50Hz/60Hz aspect ratio"; | |
| else | |
| find_item_by_function(glopitems, togglearatio)->name = " 50Hz/60Hz aspect ratio"; | |
| if( oric->hstretch ) | |
| find_item_by_function(glopitems, togglehstretch)->name = "\x0e""Horizontal stretch"; | |
| else | |
| find_item_by_function(glopitems, togglehstretch)->name = " Horizontal stretch"; | |
| if( oric->scanlines ) | |
| { | |
| find_item_by_function(vdopitems, togglescanlines)->name = "\x0e""Scanlines"; | |
| find_item_by_function(glopitems, togglescanlines)->name = "\x0e""Scanlines"; | |
| } else { | |
| find_item_by_function(vdopitems, togglescanlines)->name = " Scanlines"; | |
| find_item_by_function(glopitems, togglescanlines)->name = " Scanlines"; | |
| } | |
| if( oric->palghost ) | |
| find_item_by_function(glopitems, togglepalghost)->name = "\x0e""PAL ghosting"; | |
| else | |
| find_item_by_function(glopitems, togglepalghost)->name = " PAL ghosting"; | |
| find_item_by_function_and_arg(hwopitems, swapmach, (0xffff<<16)|MACH_ORIC1 )->name = oric->type==MACH_ORIC1 ? "\x0e""Oric-1" : " Oric-1"; | |
| find_item_by_function_and_arg(hwopitems, swapmach, (0xffff<<16)|MACH_ORIC1_16K )->name = oric->type==MACH_ORIC1_16K ? "\x0e""Oric-1 16K" : " Oric-1 16K"; | |
| find_item_by_function_and_arg(hwopitems, swapmach, (0xffff<<16)|MACH_ATMOS )->name = oric->type==MACH_ATMOS ? "\x0e""Atmos" : " Atmos"; | |
| find_item_by_function_and_arg(hwopitems, swapmach, (DRV_NONE<<16)|MACH_TELESTRAT)->name = oric->type==MACH_TELESTRAT ? "\x0e""Telestrat" : " Telestrat"; | |
| find_item_by_function_and_arg(hwopitems, swapmach, (0xffff<<16)|MACH_PRAVETZ )->name = oric->type==MACH_PRAVETZ ? "\x0e""Pravetz 8D" : " Pravetz 8D"; | |
| find_item_by_key(hwopitems, 'm')->func = microdiscrom_valid ? setdrivetype : NULL; | |
| find_item_by_key(hwopitems, 'j')->func = jasminrom_valid ? setdrivetype : NULL; | |
| find_item_by_key(hwopitems, 'p')->func = pravetzrom_valid ? setdrivetype : NULL; | |
| find_item_by_key(hwopitems, 'x')->name = oric->drivetype==DRV_NONE ? "\x0e""No disk" : " No disk"; | |
| find_item_by_key(hwopitems, 'm')->name = oric->drivetype==DRV_MICRODISC ? "\x0e""Microdisc" : " Microdisc"; | |
| find_item_by_key(hwopitems, 'b')->name = oric->drivetype==DRV_BD500 ? "\x0e""BD500" : " BD500"; | |
| find_item_by_key(hwopitems, 'j')->name = oric->drivetype==DRV_JASMIN ? "\x0e""Jasmin" : " Jasmin"; | |
| find_item_by_key(hwopitems, 'p')->name = oric->drivetype==DRV_PRAVETZ ? "\x0e""Pravetz 8D disk" : " Pravetz 8D disk"; | |
| if(oric->show_keyboard) | |
| find_item_by_function(keopitems, togglekeyboard)->name = "\x0e""Show keyboard"; | |
| else | |
| find_item_by_function(keopitems, togglekeyboard)->name = " Show keyboard"; | |
| if(oric->show_keyboard) | |
| find_item_by_function(keopitems, togglestickykeys)->name = "\x0e""Sticky mod keys"; | |
| else | |
| find_item_by_function(keopitems, togglestickykeys)->name = " Sticky mod keys"; | |
| g_menu_scheme = oric->disable_menuscheme? 5 : oric->type; | |
| find_item_by_function(hwopitems, togglech376)->name = oric->ch376_activated ? "\x0e""CH376 (Telestrat)" : " CH376 (Telestrat) "; | |
| find_item_by_function(hwopitems, toggletwilighte)->name = oric->twilighteboard_activated ? "\x0e""Twilighte board" : " Twilighte board"; | |
| } | |
| // Initialise the GUI | |
| SDL_bool init_gui( struct machine *oric, Sint32 rendermode ) | |
| { | |
| int i; | |
| SDL_AudioSpec wanted; | |
| for( i=0; i<NUM_GIMG; i++ ) | |
| { | |
| if( !gimg_load( &gimgs[i] ) ) return SDL_FALSE; | |
| } | |
| set_render_mode( oric, rendermode ); | |
| if( !oric->init_render( oric ) ) return SDL_FALSE; | |
| // Allocate all text zones | |
| if( !alloc_textzone( oric, TZ_MONITOR, 0, 228, 50, 21, "Monitor" ) ) return SDL_FALSE; | |
| if( !alloc_textzone( oric, TZ_DEBUG, 0, 228, 50, 21, "Debug console" ) ) return SDL_FALSE; | |
| if( !alloc_textzone( oric, TZ_MEMWATCH, 0, 228, 50, 21, "Memory watch" ) ) return SDL_FALSE; | |
| if( !alloc_textzone( oric, TZ_REGS, 240, 0, 50, 19, "6502 Status" ) ) return SDL_FALSE; | |
| if( !alloc_textzone( oric, TZ_VIA, 400, 228, 30, 21, "VIA Status" ) ) return SDL_FALSE; | |
| if( !alloc_textzone( oric, TZ_VIA2, 400, 228, 30, 21, "Telestrat VIA Status" ) ) return SDL_FALSE; | |
| if( !alloc_textzone( oric, TZ_AY, 400, 228, 30, 21, "AY Status" ) ) return SDL_FALSE; | |
| if( !alloc_textzone( oric, TZ_DISK, 400, 228, 30, 21, "Disk Status" ) ) return SDL_FALSE; | |
| // Set up SDL audio | |
| wanted.freq = AUDIO_FREQ; | |
| wanted.format = AUDIO_S16SYS; | |
| wanted.channels = 2; /* 1 = mono, 2 = stereo */ | |
| wanted.samples = AUDIO_BUFLEN; | |
| wanted.callback = (void*)ay_callback; | |
| wanted.userdata = &oric->ay; | |
| soundavailable = SDL_FALSE; | |
| soundon = SDL_FALSE; | |
| if( SDL_OpenAudio( &wanted, &obtained ) >= 0 ) | |
| { | |
| soundon = SDL_TRUE; | |
| soundavailable = SDL_TRUE; | |
| soundsilence = obtained.silence * 8192; | |
| cyclespersample = ((CYCLESPERSECOND<<FPBITS)/obtained.freq); | |
| } | |
| setmenutoggles( oric ); | |
| #if defined(__APPLE__) || defined(__BEOS__) || defined(__HAIKU__) | |
| init_gui_native( oric ); | |
| #elif defined(__WIN32__) || defined(__CYGWIN__) | |
| init_gui_native( oric ); | |
| #elif defined(__linux__) | |
| init_gui_native( oric ); | |
| #endif | |
| return SDL_TRUE; | |
| } | |
| // Bye bye. | |
| void shut_gui( struct machine *oric ) | |
| { | |
| int i; | |
| for (i = 0; i<NUM_GIMG; i++) | |
| { | |
| free(gimgs[i].buf); | |
| gimgs[i].buf = 0; | |
| } | |
| oric->shut_render( oric ); | |
| for( i=0; i<NUM_TZ; i++ ) | |
| free_textzone( oric, i ); | |
| #if defined(__APPLE__) || defined(__BEOS__) || defined(__HAIKU__) | |
| shut_gui_native( oric ); | |
| #elif defined(__WIN32__) || defined(__CYGWIN__) | |
| shut_gui_native( oric ); | |
| #elif defined(__linux__) | |
| shut_gui_native( oric ); | |
| #endif | |
| } | |
| void pravdiskboot( struct machine *oric ) | |
| { | |
| if( oric->pravdiskautoboot ) | |
| { | |
| queuekeys( "CALL800\x0d" ); | |
| } | |
| } |