2016-12-10 11:40:41 +01:00
|
|
|
#include <iostream>
|
|
|
|
#include <guisan.hpp>
|
|
|
|
#include <SDL_ttf.h>
|
|
|
|
#include <guisan/sdl.hpp>
|
2017-09-19 14:24:41 +02:00
|
|
|
#include <guisan/sdl/sdltruetypefont.hpp>
|
2015-05-13 18:47:23 +00:00
|
|
|
#include "SelectorEntry.hpp"
|
|
|
|
|
|
|
|
#include "sysconfig.h"
|
|
|
|
#include "sysdeps.h"
|
|
|
|
#include "config.h"
|
|
|
|
#include "options.h"
|
|
|
|
#include "uae.h"
|
|
|
|
#include "gui.h"
|
|
|
|
#include "gui_handling.h"
|
2017-02-27 14:29:54 +01:00
|
|
|
#include "amiberry_gfx.h"
|
2017-09-18 17:36:45 +02:00
|
|
|
#include "autoconf.h"
|
2015-05-13 18:47:23 +00:00
|
|
|
|
|
|
|
bool gui_running = false;
|
2017-09-18 17:36:45 +02:00
|
|
|
static int last_active_panel = 2;
|
2015-05-13 18:47:23 +00:00
|
|
|
|
2017-09-18 17:36:45 +02:00
|
|
|
#define MAX_STARTUP_TITLE 64
|
|
|
|
#define MAX_STARTUP_MESSAGE 256
|
|
|
|
static TCHAR startup_title[MAX_STARTUP_TITLE] = _T("");
|
|
|
|
static TCHAR startup_message[MAX_STARTUP_MESSAGE] = _T("");
|
2016-10-15 20:49:53 +02:00
|
|
|
|
2017-09-18 17:36:45 +02:00
|
|
|
|
|
|
|
void target_startup_msg(TCHAR* title, TCHAR* msg)
|
2016-09-01 13:53:43 +02:00
|
|
|
{
|
2017-09-18 17:36:45 +02:00
|
|
|
_tcsncpy(startup_title, title, MAX_STARTUP_TITLE);
|
|
|
|
_tcsncpy(startup_message, msg, MAX_STARTUP_MESSAGE);
|
|
|
|
}
|
|
|
|
|
|
|
|
ConfigCategory categories[] = {
|
|
|
|
{ "Paths", "data/paths.ico", nullptr, nullptr, InitPanelPaths, ExitPanelPaths, RefreshPanelPaths, HelpPanelPaths },
|
|
|
|
{ "Quickstart", "data/quickstart.ico", nullptr, nullptr, InitPanelQuickstart, ExitPanelQuickstart, RefreshPanelQuickstart, HelpPanelQuickstart },
|
|
|
|
{ "Configurations", "data/file.ico", nullptr, nullptr, InitPanelConfig, ExitPanelConfig, RefreshPanelConfig, HelpPanelConfig },
|
|
|
|
{ "CPU and FPU", "data/cpu.ico", nullptr, nullptr, InitPanelCPU, ExitPanelCPU, RefreshPanelCPU, HelpPanelCPU },
|
|
|
|
{ "Chipset", "data/cpu.ico", nullptr, nullptr, InitPanelChipset, ExitPanelChipset, RefreshPanelChipset, HelpPanelChipset },
|
|
|
|
{ "ROM", "data/chip.ico", nullptr, nullptr, InitPanelROM, ExitPanelROM, RefreshPanelROM, HelpPanelROM },
|
|
|
|
{ "RAM", "data/chip.ico", nullptr, nullptr, InitPanelRAM, ExitPanelRAM, RefreshPanelRAM, HelpPanelRAM },
|
|
|
|
{ "Floppy drives", "data/35floppy.ico", nullptr, nullptr, InitPanelFloppy, ExitPanelFloppy, RefreshPanelFloppy, HelpPanelFloppy },
|
|
|
|
{ "Hard drives/CD", "data/drive.ico", nullptr, nullptr, InitPanelHD, ExitPanelHD, RefreshPanelHD, HelpPanelHD },
|
|
|
|
{ "Display", "data/screen.ico", nullptr, nullptr, InitPanelDisplay, ExitPanelDisplay, RefreshPanelDisplay, HelpPanelDisplay },
|
|
|
|
{ "Sound", "data/sound.ico", nullptr, nullptr, InitPanelSound, ExitPanelSound, RefreshPanelSound, HelpPanelSound },
|
|
|
|
{ "Input", "data/joystick.ico", nullptr, nullptr, InitPanelInput, ExitPanelInput, RefreshPanelInput, HelpPanelInput },
|
|
|
|
{ "Miscellaneous", "data/misc.ico", nullptr, nullptr, InitPanelMisc, ExitPanelMisc, RefreshPanelMisc, HelpPanelMisc },
|
|
|
|
{ "Savestates", "data/savestate.png", nullptr, nullptr, InitPanelSavestate, ExitPanelSavestate, RefreshPanelSavestate, HelpPanelSavestate },
|
|
|
|
{ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }
|
2017-01-29 12:03:00 +01:00
|
|
|
};
|
|
|
|
|
2017-09-18 17:36:45 +02:00
|
|
|
enum {
|
|
|
|
PANEL_PATHS, PANEL_QUICKSTART, PANEL_CONFIGURATIONS, PANEL_CPU, PANEL_CHIPSET, PANEL_ROM, PANEL_RAM,
|
|
|
|
PANEL_FLOPPY, PANEL_HD, PANEL_DISPLAY, PANEL_SOUND, PANEL_INPUT, PANEL_MISC, PANEL_SAVESTATES,
|
2017-01-29 12:03:00 +01:00
|
|
|
NUM_PANELS
|
2015-05-13 18:47:23 +00:00
|
|
|
};
|
|
|
|
|
2016-09-23 00:01:16 +02:00
|
|
|
|
2016-12-10 11:40:41 +01:00
|
|
|
/*
|
2017-09-18 17:36:45 +02:00
|
|
|
* SDL Stuff we need
|
|
|
|
*/
|
2016-12-10 11:40:41 +01:00
|
|
|
SDL_Surface* gui_screen;
|
2017-01-23 22:08:44 +01:00
|
|
|
SDL_Texture* gui_texture;
|
2017-03-07 00:20:02 +01:00
|
|
|
SDL_Event gui_event;
|
2017-04-05 23:38:59 +02:00
|
|
|
SDL_Cursor* cursor;
|
2017-09-18 17:36:45 +02:00
|
|
|
SDL_Surface* cursorSurface;
|
2016-12-10 11:40:41 +01:00
|
|
|
|
|
|
|
/*
|
2017-09-18 17:36:45 +02:00
|
|
|
* Guisan SDL stuff we need
|
|
|
|
*/
|
2016-12-10 11:40:41 +01:00
|
|
|
gcn::SDLInput* gui_input;
|
|
|
|
gcn::SDLGraphics* gui_graphics;
|
|
|
|
gcn::SDLImageLoader* gui_imageLoader;
|
|
|
|
gcn::SDLTrueTypeFont* gui_font;
|
|
|
|
|
|
|
|
/*
|
2017-09-18 17:36:45 +02:00
|
|
|
* Guisan stuff we need
|
|
|
|
*/
|
2015-05-13 18:47:23 +00:00
|
|
|
gcn::Gui* uae_gui;
|
2016-12-10 11:40:41 +01:00
|
|
|
gcn::Container* gui_top;
|
|
|
|
gcn::Container* selectors;
|
2015-05-13 18:47:23 +00:00
|
|
|
gcn::Color gui_baseCol;
|
2017-04-16 00:50:58 +02:00
|
|
|
gcn::Color colTextboxBackground;
|
2015-05-13 18:47:23 +00:00
|
|
|
gcn::Color colSelectorInactive;
|
|
|
|
gcn::Color colSelectorActive;
|
|
|
|
|
2016-09-01 13:53:43 +02:00
|
|
|
namespace widgets
|
2015-10-11 14:23:51 +02:00
|
|
|
{
|
2017-01-28 01:03:18 +01:00
|
|
|
// Main buttons
|
2016-09-17 10:15:23 +02:00
|
|
|
gcn::Button* cmdQuit;
|
|
|
|
gcn::Button* cmdReset;
|
|
|
|
gcn::Button* cmdRestart;
|
|
|
|
gcn::Button* cmdStart;
|
2017-01-28 01:03:18 +01:00
|
|
|
gcn::Button* cmdShutdown;
|
2017-09-18 17:36:45 +02:00
|
|
|
gcn::Button* cmdHelp;
|
2015-10-11 14:23:51 +02:00
|
|
|
}
|
|
|
|
|
2016-10-15 20:49:53 +02:00
|
|
|
|
|
|
|
/* Flag for changes in rtarea:
|
2017-09-18 17:36:45 +02:00
|
|
|
Bit 0: any HD in config?
|
2017-09-27 00:15:50 +02:00
|
|
|
Bit 1: force because add/remove HD was clicked or new config loaded
|
2017-09-18 17:36:45 +02:00
|
|
|
Bit 2: socket_emu on
|
|
|
|
Bit 3: mousehack on
|
|
|
|
Bit 4: rtgmem on
|
|
|
|
Bit 5: chipmem larger than 2MB
|
|
|
|
|
|
|
|
gui_rtarea_flags_onenter is set before GUI is shown, bit 1 may change during GUI display.
|
2016-10-15 20:49:53 +02:00
|
|
|
*/
|
2016-04-24 09:45:29 +00:00
|
|
|
static int gui_rtarea_flags_onenter;
|
|
|
|
|
2017-01-29 12:03:00 +01:00
|
|
|
static int gui_create_rtarea_flag(struct uae_prefs* p)
|
2015-10-11 14:23:51 +02:00
|
|
|
{
|
2017-01-29 12:03:00 +01:00
|
|
|
int flag = 0;
|
2016-09-01 13:53:43 +02:00
|
|
|
|
2017-01-29 12:03:00 +01:00
|
|
|
if (count_HDs(p) > 0)
|
|
|
|
flag |= 1;
|
2016-04-24 09:45:29 +00:00
|
|
|
|
2017-01-29 12:03:00 +01:00
|
|
|
if (p->socket_emu)
|
|
|
|
flag |= 4;
|
2016-04-24 09:45:29 +00:00
|
|
|
|
2017-01-29 12:03:00 +01:00
|
|
|
if (p->input_tablet > 0)
|
|
|
|
flag |= 8;
|
2016-04-24 09:45:29 +00:00
|
|
|
|
2017-09-18 17:36:45 +02:00
|
|
|
if (p->rtgboards[0].rtgmem_size)
|
2017-01-29 12:03:00 +01:00
|
|
|
flag |= 16;
|
2015-10-11 14:23:51 +02:00
|
|
|
|
2017-01-29 12:03:00 +01:00
|
|
|
if (p->chipmem_size > 2 * 1024 * 1024)
|
|
|
|
flag |= 32;
|
2016-09-01 13:53:43 +02:00
|
|
|
|
2017-01-29 12:03:00 +01:00
|
|
|
return flag;
|
2016-04-24 09:45:29 +00:00
|
|
|
}
|
|
|
|
|
2017-01-29 10:36:18 +01:00
|
|
|
void gui_force_rtarea_hdchange()
|
2016-04-24 09:45:29 +00:00
|
|
|
{
|
2017-01-29 12:03:00 +01:00
|
|
|
gui_rtarea_flags_onenter |= 2;
|
2015-10-11 14:23:51 +02:00
|
|
|
}
|
|
|
|
|
2017-09-18 17:36:45 +02:00
|
|
|
void gui_restart()
|
|
|
|
{
|
|
|
|
gui_running = false;
|
|
|
|
}
|
|
|
|
|
2017-01-29 10:36:18 +01:00
|
|
|
static void (*refreshFuncAfterDraw)() = nullptr;
|
2016-04-25 18:51:31 +00:00
|
|
|
|
2017-01-29 10:36:18 +01:00
|
|
|
void RegisterRefreshFunc(void (*func)())
|
2016-04-25 18:51:31 +00:00
|
|
|
{
|
2017-01-29 12:03:00 +01:00
|
|
|
refreshFuncAfterDraw = func;
|
2016-04-25 18:51:31 +00:00
|
|
|
}
|
|
|
|
|
2017-09-18 17:36:45 +02:00
|
|
|
void FocusBugWorkaround(gcn::Window *wnd)
|
|
|
|
{
|
|
|
|
// When modal dialog opens via mouse, the dialog will not
|
|
|
|
// have the focus unless there is a mouse click. We simulate the click...
|
|
|
|
SDL_Event event;
|
|
|
|
event.type = SDL_MOUSEBUTTONDOWN;
|
|
|
|
event.button.button = SDL_BUTTON_LEFT;
|
|
|
|
event.button.state = SDL_PRESSED;
|
|
|
|
event.button.x = wnd->getX() + 2;
|
|
|
|
event.button.y = wnd->getY() + 2;
|
|
|
|
gui_input->pushInput(event);
|
|
|
|
event.type = SDL_MOUSEBUTTONUP;
|
|
|
|
gui_input->pushInput(event);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ShowHelpRequested()
|
|
|
|
{
|
|
|
|
std::vector<std::string> helptext;
|
|
|
|
if (categories[last_active_panel].HelpFunc != nullptr && categories[last_active_panel].HelpFunc(helptext))
|
|
|
|
{
|
|
|
|
//------------------------------------------------
|
|
|
|
// Show help for current panel
|
|
|
|
//------------------------------------------------
|
|
|
|
char title[128];
|
|
|
|
snprintf(title, 128, "Help for %s", categories[last_active_panel].category);
|
|
|
|
ShowHelp(title, helptext);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-02-23 00:34:24 +01:00
|
|
|
void UpdateGuiScreen()
|
2017-02-22 14:30:04 +01:00
|
|
|
{
|
|
|
|
// Update the texture from the surface
|
|
|
|
SDL_UpdateTexture(gui_texture, nullptr, gui_screen->pixels, gui_screen->pitch);
|
|
|
|
// Copy the texture on the renderer
|
|
|
|
SDL_RenderCopy(renderer, gui_texture, nullptr, nullptr);
|
|
|
|
// Update the window surface (show the renderer)
|
|
|
|
SDL_RenderPresent(renderer);
|
|
|
|
}
|
|
|
|
|
2015-05-13 18:47:23 +00:00
|
|
|
namespace sdl
|
|
|
|
{
|
2016-09-17 10:15:23 +02:00
|
|
|
void gui_init()
|
|
|
|
{
|
|
|
|
//-------------------------------------------------
|
|
|
|
// Create new screen for GUI
|
|
|
|
//-------------------------------------------------
|
2017-04-06 00:03:07 +02:00
|
|
|
if (sdlMode.w > 1280)
|
|
|
|
{
|
|
|
|
// High resolution detected, we'll use a double-size cursor
|
|
|
|
cursorSurface = SDL_LoadBMP("data/cursor-x2.bmp");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
cursorSurface = SDL_LoadBMP("data/cursor.bmp");
|
|
|
|
}
|
2017-04-05 23:38:59 +02:00
|
|
|
if (cursorSurface)
|
|
|
|
{
|
|
|
|
cursor = SDL_CreateColorCursor(cursorSurface, 0, 0);
|
|
|
|
SDL_SetCursor(cursor);
|
|
|
|
}
|
|
|
|
|
2017-02-22 14:30:04 +01:00
|
|
|
// make the scaled rendering look smoother (linear scaling).
|
2017-02-24 01:34:54 +01:00
|
|
|
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
|
2017-02-02 22:27:51 +01:00
|
|
|
|
2017-01-25 12:47:51 +01:00
|
|
|
gui_screen = SDL_CreateRGBSurface(0, GUI_WIDTH, GUI_HEIGHT, 32, 0, 0, 0, 0);
|
2016-12-10 11:40:41 +01:00
|
|
|
check_error_sdl(gui_screen == nullptr, "Unable to create a surface");
|
2017-01-29 12:03:00 +01:00
|
|
|
|
2017-01-23 22:08:44 +01:00
|
|
|
SDL_RenderSetLogicalSize(renderer, GUI_WIDTH, GUI_HEIGHT);
|
2017-02-24 01:34:54 +01:00
|
|
|
|
2017-02-22 14:30:04 +01:00
|
|
|
gui_texture = SDL_CreateTextureFromSurface(renderer, gui_screen);
|
2017-01-23 22:08:44 +01:00
|
|
|
check_error_sdl(gui_texture == nullptr, "Unable to create texture");
|
2017-01-29 12:03:00 +01:00
|
|
|
|
2016-09-17 10:15:23 +02:00
|
|
|
SDL_ShowCursor(SDL_ENABLE);
|
|
|
|
|
|
|
|
//-------------------------------------------------
|
2017-09-19 14:24:41 +02:00
|
|
|
// Create helpers for guisan
|
2016-09-17 10:15:23 +02:00
|
|
|
//-------------------------------------------------
|
|
|
|
gui_imageLoader = new gcn::SDLImageLoader();
|
2016-12-10 11:40:41 +01:00
|
|
|
// The ImageLoader in use is static and must be set to be
|
|
|
|
// able to load images
|
2016-09-17 10:15:23 +02:00
|
|
|
gcn::Image::setImageLoader(gui_imageLoader);
|
|
|
|
gui_graphics = new gcn::SDLGraphics();
|
2016-12-10 11:40:41 +01:00
|
|
|
// Set the target for the graphics object to be the screen.
|
|
|
|
// In other words, we will draw to the screen.
|
|
|
|
// Note, any surface will do, it doesn't have to be the screen.
|
2016-09-17 10:15:23 +02:00
|
|
|
gui_graphics->setTarget(gui_screen);
|
|
|
|
gui_input = new gcn::SDLInput();
|
|
|
|
uae_gui = new gcn::Gui();
|
|
|
|
uae_gui->setGraphics(gui_graphics);
|
|
|
|
uae_gui->setInput(gui_input);
|
|
|
|
}
|
2017-01-29 12:03:00 +01:00
|
|
|
|
2016-09-17 10:15:23 +02:00
|
|
|
void gui_halt()
|
|
|
|
{
|
|
|
|
delete uae_gui;
|
|
|
|
delete gui_imageLoader;
|
|
|
|
delete gui_input;
|
|
|
|
delete gui_graphics;
|
2017-09-18 17:36:45 +02:00
|
|
|
|
2016-09-17 10:15:23 +02:00
|
|
|
SDL_FreeSurface(gui_screen);
|
2017-01-23 22:08:44 +01:00
|
|
|
SDL_DestroyTexture(gui_texture);
|
2017-09-18 17:36:45 +02:00
|
|
|
if (cursor)
|
|
|
|
{
|
2017-04-05 23:38:59 +02:00
|
|
|
SDL_FreeCursor(cursor);
|
|
|
|
}
|
2017-01-29 10:36:18 +01:00
|
|
|
gui_screen = nullptr;
|
2016-09-17 10:15:23 +02:00
|
|
|
}
|
|
|
|
|
2016-12-10 11:40:41 +01:00
|
|
|
void checkInput()
|
2016-09-17 10:15:23 +02:00
|
|
|
{
|
2017-03-07 00:20:02 +01:00
|
|
|
while (SDL_PollEvent(&gui_event))
|
2016-09-17 10:15:23 +02:00
|
|
|
{
|
2017-03-07 00:20:02 +01:00
|
|
|
if (gui_event.type == SDL_KEYDOWN)
|
2016-09-17 10:15:23 +02:00
|
|
|
{
|
2016-12-10 11:40:41 +01:00
|
|
|
gcn::FocusHandler* focusHdl;
|
|
|
|
gcn::Widget* activeWidget;
|
2017-01-29 12:03:00 +01:00
|
|
|
|
2017-04-23 18:11:40 +02:00
|
|
|
if (gui_event.key.keysym.sym == SDL_GetKeyFromName(currprefs.open_gui))
|
2016-09-17 10:15:23 +02:00
|
|
|
{
|
2016-12-10 11:40:41 +01:00
|
|
|
if (emulating && widgets::cmdStart->isEnabled())
|
2016-09-23 00:01:16 +02:00
|
|
|
{
|
2016-12-10 11:40:41 +01:00
|
|
|
//------------------------------------------------
|
|
|
|
// Continue emulation
|
|
|
|
//------------------------------------------------
|
|
|
|
gui_running = false;
|
2016-09-23 00:01:16 +02:00
|
|
|
}
|
2016-10-15 20:49:53 +02:00
|
|
|
else
|
2016-12-10 11:40:41 +01:00
|
|
|
{
|
|
|
|
//------------------------------------------------
|
|
|
|
// First start of emulator -> reset Amiga
|
|
|
|
//------------------------------------------------
|
|
|
|
uae_reset(0, 1);
|
|
|
|
gui_running = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2017-03-07 00:20:02 +01:00
|
|
|
switch (gui_event.key.keysym.scancode)
|
2016-12-10 11:40:41 +01:00
|
|
|
{
|
2017-02-28 13:21:37 +01:00
|
|
|
case SDL_SCANCODE_Q:
|
2016-12-10 11:40:41 +01:00
|
|
|
//-------------------------------------------------
|
|
|
|
// Quit entire program via Q on keyboard
|
|
|
|
//-------------------------------------------------
|
|
|
|
focusHdl = gui_top->_getFocusHandler();
|
|
|
|
activeWidget = focusHdl->getFocused();
|
2017-01-29 10:36:18 +01:00
|
|
|
if (dynamic_cast<gcn::TextField*>(activeWidget) == nullptr)
|
2016-10-15 20:49:53 +02:00
|
|
|
{
|
2016-12-10 11:40:41 +01:00
|
|
|
// ...but only if we are not in a Textfield...
|
|
|
|
uae_quit();
|
2016-10-15 20:49:53 +02:00
|
|
|
gui_running = false;
|
|
|
|
}
|
2016-12-10 11:40:41 +01:00
|
|
|
break;
|
|
|
|
|
2017-01-28 01:03:18 +01:00
|
|
|
case VK_ESCAPE:
|
2016-12-10 11:40:41 +01:00
|
|
|
gui_running = false;
|
|
|
|
break;
|
|
|
|
|
2017-02-28 13:21:37 +01:00
|
|
|
case VK_Red:
|
|
|
|
case VK_Green:
|
2017-01-28 01:03:18 +01:00
|
|
|
//------------------------------------------------
|
|
|
|
// Simulate press of enter when 'X' pressed
|
|
|
|
//------------------------------------------------
|
2017-03-07 00:20:02 +01:00
|
|
|
gui_event.key.keysym.scancode = SDL_SCANCODE_RETURN;
|
|
|
|
gui_input->pushInput(gui_event); // Fire key down
|
|
|
|
gui_event.type = SDL_KEYUP; // and the key up
|
2017-01-28 01:03:18 +01:00
|
|
|
break;
|
2017-01-29 12:03:00 +01:00
|
|
|
|
2017-01-28 01:03:18 +01:00
|
|
|
case VK_UP:
|
2016-12-10 11:40:41 +01:00
|
|
|
if (HandleNavigation(DIRECTION_UP))
|
|
|
|
continue; // Don't change value when enter ComboBox -> don't send event to control
|
|
|
|
break;
|
|
|
|
|
2017-01-28 01:03:18 +01:00
|
|
|
case VK_DOWN:
|
2016-12-10 11:40:41 +01:00
|
|
|
if (HandleNavigation(DIRECTION_DOWN))
|
|
|
|
continue; // Don't change value when enter ComboBox -> don't send event to control
|
|
|
|
break;
|
|
|
|
|
2017-01-28 01:03:18 +01:00
|
|
|
case VK_LEFT:
|
2016-12-10 11:40:41 +01:00
|
|
|
if (HandleNavigation(DIRECTION_LEFT))
|
|
|
|
continue; // Don't change value when enter Slider -> don't send event to control
|
|
|
|
break;
|
|
|
|
|
2017-01-28 01:03:18 +01:00
|
|
|
case VK_RIGHT:
|
2016-12-10 11:40:41 +01:00
|
|
|
if (HandleNavigation(DIRECTION_RIGHT))
|
|
|
|
continue; // Don't change value when enter Slider -> don't send event to control
|
|
|
|
break;
|
2017-09-18 17:36:45 +02:00
|
|
|
default:
|
2017-02-28 13:21:37 +01:00
|
|
|
break;
|
2016-12-10 11:40:41 +01:00
|
|
|
}
|
|
|
|
}
|
2017-03-07 00:20:02 +01:00
|
|
|
else if (gui_event.type == SDL_QUIT)
|
2016-12-10 11:40:41 +01:00
|
|
|
{
|
2016-09-17 10:15:23 +02:00
|
|
|
//-------------------------------------------------
|
2016-12-10 11:40:41 +01:00
|
|
|
// Quit entire program via SQL-Quit
|
2016-09-17 10:15:23 +02:00
|
|
|
//-------------------------------------------------
|
2016-12-10 11:40:41 +01:00
|
|
|
uae_quit();
|
|
|
|
gui_running = false;
|
2016-09-17 10:15:23 +02:00
|
|
|
}
|
2016-12-10 11:40:41 +01:00
|
|
|
//-------------------------------------------------
|
|
|
|
// Send event to guichan-controls
|
|
|
|
//-------------------------------------------------
|
2017-03-07 00:20:02 +01:00
|
|
|
gui_input->pushInput(gui_event);
|
2016-12-10 11:40:41 +01:00
|
|
|
}
|
|
|
|
}
|
2017-01-29 12:03:00 +01:00
|
|
|
|
2016-12-10 11:40:41 +01:00
|
|
|
void gui_run()
|
|
|
|
{
|
|
|
|
//-------------------------------------------------
|
|
|
|
// The main loop
|
|
|
|
//-------------------------------------------------
|
2017-01-29 12:03:00 +01:00
|
|
|
while (gui_running)
|
2016-12-10 11:40:41 +01:00
|
|
|
{
|
|
|
|
// Poll input
|
|
|
|
checkInput();
|
2017-01-29 12:03:00 +01:00
|
|
|
|
|
|
|
if (gui_rtarea_flags_onenter != gui_create_rtarea_flag(&changed_prefs))
|
2016-09-17 10:15:23 +02:00
|
|
|
DisableResume();
|
|
|
|
|
|
|
|
// Now we let the Gui object perform its logic.
|
|
|
|
uae_gui->logic();
|
|
|
|
// Now we let the Gui object draw itself.
|
|
|
|
uae_gui->draw();
|
2016-10-15 20:49:53 +02:00
|
|
|
// Finally we update the screen.
|
2017-01-29 12:03:00 +01:00
|
|
|
|
2017-02-23 00:34:24 +01:00
|
|
|
UpdateGuiScreen();
|
2016-10-15 20:49:53 +02:00
|
|
|
|
2017-01-29 12:03:00 +01:00
|
|
|
if (refreshFuncAfterDraw != nullptr)
|
2016-10-15 20:49:53 +02:00
|
|
|
{
|
2017-01-29 12:03:00 +01:00
|
|
|
void (*currFunc)() = refreshFuncAfterDraw;
|
2017-01-29 10:36:18 +01:00
|
|
|
refreshFuncAfterDraw = nullptr;
|
2016-10-15 20:49:53 +02:00
|
|
|
currFunc();
|
|
|
|
}
|
2016-09-17 10:15:23 +02:00
|
|
|
}
|
|
|
|
}
|
2015-05-13 18:47:23 +00:00
|
|
|
}
|
|
|
|
|
2015-10-11 14:23:51 +02:00
|
|
|
|
2016-09-01 13:53:43 +02:00
|
|
|
namespace widgets
|
|
|
|
{
|
2016-09-17 10:15:23 +02:00
|
|
|
class MainButtonActionListener : public gcn::ActionListener
|
|
|
|
{
|
|
|
|
public:
|
2017-03-07 00:20:02 +01:00
|
|
|
void action(const gcn::ActionEvent& actionEvent) override
|
2016-09-17 10:15:23 +02:00
|
|
|
{
|
2017-01-28 01:03:18 +01:00
|
|
|
if (actionEvent.getSource() == cmdShutdown)
|
|
|
|
{
|
|
|
|
// ------------------------------------------------
|
|
|
|
// Shutdown the host (power off)
|
|
|
|
// ------------------------------------------------
|
|
|
|
uae_quit();
|
|
|
|
gui_running = false;
|
|
|
|
host_shutdown();
|
|
|
|
}
|
2017-01-29 12:03:00 +01:00
|
|
|
|
2016-09-17 10:15:23 +02:00
|
|
|
if (actionEvent.getSource() == cmdQuit)
|
|
|
|
{
|
|
|
|
//-------------------------------------------------
|
|
|
|
// Quit entire program via click on Quit-button
|
|
|
|
//-------------------------------------------------
|
|
|
|
uae_quit();
|
|
|
|
gui_running = false;
|
|
|
|
}
|
2017-01-29 12:03:00 +01:00
|
|
|
else if (actionEvent.getSource() == cmdReset)
|
2016-09-17 10:15:23 +02:00
|
|
|
{
|
|
|
|
//-------------------------------------------------
|
|
|
|
// Reset Amiga via click on Reset-button
|
|
|
|
//-------------------------------------------------
|
|
|
|
uae_reset(1, 1);
|
|
|
|
gui_running = false;
|
|
|
|
}
|
2017-01-29 12:03:00 +01:00
|
|
|
else if (actionEvent.getSource() == cmdRestart)
|
2016-09-17 10:15:23 +02:00
|
|
|
{
|
|
|
|
//-------------------------------------------------
|
|
|
|
// Restart emulator
|
|
|
|
//-------------------------------------------------
|
2017-04-21 22:27:47 +02:00
|
|
|
char tmp[MAX_DPATH];
|
|
|
|
fetch_configurationpath(tmp, sizeof tmp);
|
2017-01-29 12:03:00 +01:00
|
|
|
if (strlen(last_loaded_config) > 0)
|
|
|
|
strcat(tmp, last_loaded_config);
|
2016-09-17 10:15:23 +02:00
|
|
|
else
|
|
|
|
{
|
2017-01-29 12:03:00 +01:00
|
|
|
strcat(tmp, OPTIONSFILENAME);
|
|
|
|
strcat(tmp, ".uae");
|
2016-09-17 10:15:23 +02:00
|
|
|
}
|
|
|
|
uae_restart(0, tmp);
|
|
|
|
gui_running = false;
|
|
|
|
}
|
2017-01-29 12:03:00 +01:00
|
|
|
else if (actionEvent.getSource() == cmdStart)
|
2016-09-17 10:15:23 +02:00
|
|
|
{
|
2017-01-29 12:03:00 +01:00
|
|
|
if (emulating && cmdStart->isEnabled())
|
2016-09-17 10:15:23 +02:00
|
|
|
{
|
|
|
|
//------------------------------------------------
|
|
|
|
// Continue emulation
|
|
|
|
//------------------------------------------------
|
|
|
|
gui_running = false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
//------------------------------------------------
|
|
|
|
// First start of emulator -> reset Amiga
|
|
|
|
//------------------------------------------------
|
|
|
|
uae_reset(0, 1);
|
|
|
|
gui_running = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2017-01-29 12:03:00 +01:00
|
|
|
|
2016-09-17 10:15:23 +02:00
|
|
|
MainButtonActionListener* mainButtonActionListener;
|
|
|
|
|
|
|
|
|
|
|
|
class PanelFocusListener : public gcn::FocusListener
|
|
|
|
{
|
|
|
|
public:
|
2017-03-07 00:20:02 +01:00
|
|
|
void focusGained(const gcn::Event& event) override
|
2016-09-17 10:15:23 +02:00
|
|
|
{
|
2017-04-23 22:23:19 +02:00
|
|
|
for (int i = 0; categories[i].category != nullptr; ++i)
|
2016-09-17 10:15:23 +02:00
|
|
|
{
|
2017-01-29 12:03:00 +01:00
|
|
|
if (event.getSource() == categories[i].selector)
|
2016-09-17 10:15:23 +02:00
|
|
|
{
|
|
|
|
categories[i].selector->setActive(true);
|
|
|
|
categories[i].panel->setVisible(true);
|
|
|
|
last_active_panel = i;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
categories[i].selector->setActive(false);
|
|
|
|
categories[i].panel->setVisible(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2017-01-29 12:03:00 +01:00
|
|
|
|
2016-09-17 10:15:23 +02:00
|
|
|
PanelFocusListener* panelFocusListener;
|
2015-05-13 18:47:23 +00:00
|
|
|
|
|
|
|
|
2017-01-29 12:03:00 +01:00
|
|
|
void gui_init()
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
int yPos;
|
2015-05-13 18:47:23 +00:00
|
|
|
|
2017-01-29 12:03:00 +01:00
|
|
|
//-------------------------------------------------
|
|
|
|
// Define base colors
|
|
|
|
//-------------------------------------------------
|
2017-04-16 00:50:58 +02:00
|
|
|
gui_baseCol = gcn::Color(170, 170, 170);
|
|
|
|
colSelectorInactive = gcn::Color(170, 170, 170);
|
|
|
|
colSelectorActive = gcn::Color(103, 136, 187);
|
|
|
|
colTextboxBackground = gcn::Color(220, 220, 220);
|
2015-05-13 18:47:23 +00:00
|
|
|
|
2017-01-29 12:03:00 +01:00
|
|
|
//-------------------------------------------------
|
|
|
|
// Create container for main page
|
|
|
|
//-------------------------------------------------
|
|
|
|
gui_top = new gcn::Container();
|
|
|
|
gui_top->setDimension(gcn::Rectangle(0, 0, GUI_WIDTH, GUI_HEIGHT));
|
|
|
|
gui_top->setBaseColor(gui_baseCol);
|
|
|
|
uae_gui->setTop(gui_top);
|
2015-05-13 18:47:23 +00:00
|
|
|
|
2017-01-29 12:03:00 +01:00
|
|
|
//-------------------------------------------------
|
|
|
|
// Initialize fonts
|
|
|
|
//-------------------------------------------------
|
|
|
|
TTF_Init();
|
2017-04-05 23:38:59 +02:00
|
|
|
gui_font = new gcn::SDLTrueTypeFont("data/Topaznew.ttf", 14);
|
2017-01-29 12:03:00 +01:00
|
|
|
gcn::Widget::setGlobalFont(gui_font);
|
|
|
|
|
|
|
|
//--------------------------------------------------
|
|
|
|
// Create main buttons
|
|
|
|
//--------------------------------------------------
|
|
|
|
mainButtonActionListener = new MainButtonActionListener();
|
|
|
|
|
|
|
|
cmdQuit = new gcn::Button("Quit");
|
|
|
|
cmdQuit->setSize(BUTTON_WIDTH, BUTTON_HEIGHT);
|
|
|
|
cmdQuit->setBaseColor(gui_baseCol);
|
|
|
|
cmdQuit->setId("Quit");
|
|
|
|
cmdQuit->addActionListener(mainButtonActionListener);
|
|
|
|
|
|
|
|
cmdShutdown = new gcn::Button("Shutdown");
|
|
|
|
cmdShutdown->setSize(BUTTON_WIDTH, BUTTON_HEIGHT);
|
|
|
|
cmdShutdown->setBaseColor(gui_baseCol);
|
|
|
|
cmdShutdown->setId("Shutdown");
|
|
|
|
cmdShutdown->addActionListener(mainButtonActionListener);
|
|
|
|
|
|
|
|
cmdReset = new gcn::Button("Reset");
|
|
|
|
cmdReset->setSize(BUTTON_WIDTH, BUTTON_HEIGHT);
|
|
|
|
cmdReset->setBaseColor(gui_baseCol);
|
|
|
|
cmdReset->setId("Reset");
|
|
|
|
cmdReset->addActionListener(mainButtonActionListener);
|
|
|
|
|
|
|
|
cmdRestart = new gcn::Button("Restart");
|
|
|
|
cmdRestart->setSize(BUTTON_WIDTH, BUTTON_HEIGHT);
|
|
|
|
cmdRestart->setBaseColor(gui_baseCol);
|
|
|
|
cmdRestart->setId("Restart");
|
|
|
|
cmdRestart->addActionListener(mainButtonActionListener);
|
|
|
|
|
|
|
|
cmdStart = new gcn::Button("Start");
|
|
|
|
if (emulating)
|
|
|
|
cmdStart->setCaption("Resume");
|
|
|
|
cmdStart->setSize(BUTTON_WIDTH, BUTTON_HEIGHT);
|
|
|
|
cmdStart->setBaseColor(gui_baseCol);
|
|
|
|
cmdStart->setId("Start");
|
|
|
|
cmdStart->addActionListener(mainButtonActionListener);
|
|
|
|
|
2017-09-18 17:36:45 +02:00
|
|
|
cmdHelp = new gcn::Button("Help");
|
|
|
|
cmdHelp->setSize(BUTTON_WIDTH, BUTTON_HEIGHT);
|
|
|
|
cmdHelp->setBaseColor(gui_baseCol);
|
|
|
|
cmdHelp->setId("Help");
|
|
|
|
cmdHelp->addActionListener(mainButtonActionListener);
|
|
|
|
|
2017-01-29 12:03:00 +01:00
|
|
|
//--------------------------------------------------
|
|
|
|
// Create selector entries
|
|
|
|
//--------------------------------------------------
|
|
|
|
int workAreaHeight = GUI_HEIGHT - 2 * DISTANCE_BORDER - BUTTON_HEIGHT - DISTANCE_NEXT_Y;
|
|
|
|
selectors = new gcn::Container();
|
|
|
|
selectors->setSize(150, workAreaHeight - 2);
|
|
|
|
selectors->setBaseColor(colSelectorInactive);
|
|
|
|
selectors->setBorderSize(1);
|
|
|
|
int panelStartX = DISTANCE_BORDER + selectors->getWidth() + 2 + 11;
|
|
|
|
|
|
|
|
panelFocusListener = new PanelFocusListener();
|
|
|
|
for (i = 0; categories[i].category != nullptr; ++i)
|
|
|
|
{
|
|
|
|
categories[i].selector = new gcn::SelectorEntry(categories[i].category, categories[i].imagepath);
|
|
|
|
categories[i].selector->setActiveColor(colSelectorActive);
|
|
|
|
categories[i].selector->setInactiveColor(colSelectorInactive);
|
|
|
|
categories[i].selector->setSize(150, 24);
|
|
|
|
categories[i].selector->addFocusListener(panelFocusListener);
|
|
|
|
|
|
|
|
categories[i].panel = new gcn::Container();
|
|
|
|
categories[i].panel->setId(categories[i].category);
|
|
|
|
categories[i].panel->setSize(GUI_WIDTH - panelStartX - DISTANCE_BORDER - 1, workAreaHeight - 2);
|
|
|
|
categories[i].panel->setBaseColor(gui_baseCol);
|
|
|
|
categories[i].panel->setBorderSize(1);
|
|
|
|
categories[i].panel->setVisible(false);
|
|
|
|
}
|
2015-05-13 18:47:23 +00:00
|
|
|
|
2017-01-29 12:03:00 +01:00
|
|
|
//--------------------------------------------------
|
|
|
|
// Initialize panels
|
|
|
|
//--------------------------------------------------
|
|
|
|
for (i = 0; categories[i].category != nullptr; ++i)
|
|
|
|
{
|
|
|
|
if (categories[i].InitFunc != nullptr)
|
|
|
|
(*categories[i].InitFunc)(categories[i]);
|
|
|
|
}
|
2015-05-13 18:47:23 +00:00
|
|
|
|
2017-01-29 12:03:00 +01:00
|
|
|
//--------------------------------------------------
|
|
|
|
// Place everything on main form
|
|
|
|
//--------------------------------------------------
|
|
|
|
gui_top->add(cmdReset, DISTANCE_BORDER, GUI_HEIGHT - DISTANCE_BORDER - BUTTON_HEIGHT);
|
|
|
|
gui_top->add(cmdQuit, DISTANCE_BORDER + BUTTON_WIDTH + DISTANCE_NEXT_X, GUI_HEIGHT - DISTANCE_BORDER - BUTTON_HEIGHT);
|
|
|
|
gui_top->add(cmdShutdown, DISTANCE_BORDER + 2 * BUTTON_WIDTH + 2 * DISTANCE_NEXT_X, GUI_HEIGHT - DISTANCE_BORDER - BUTTON_HEIGHT);
|
2017-09-18 17:36:45 +02:00
|
|
|
gui_top->add(cmdHelp, DISTANCE_BORDER + 3 * BUTTON_WIDTH + 3 * DISTANCE_NEXT_X, GUI_HEIGHT - DISTANCE_BORDER - BUTTON_HEIGHT);
|
2017-01-29 12:03:00 +01:00
|
|
|
gui_top->add(cmdStart, GUI_WIDTH - DISTANCE_BORDER - BUTTON_WIDTH, GUI_HEIGHT - DISTANCE_BORDER - BUTTON_HEIGHT);
|
2016-09-01 13:53:43 +02:00
|
|
|
|
2017-01-29 12:03:00 +01:00
|
|
|
gui_top->add(selectors, DISTANCE_BORDER + 1, DISTANCE_BORDER + 1);
|
|
|
|
for (i = 0 , yPos = 0; categories[i].category != nullptr; ++i , yPos += 24)
|
|
|
|
{
|
|
|
|
selectors->add(categories[i].selector, 0, yPos);
|
|
|
|
gui_top->add(categories[i].panel, panelStartX, DISTANCE_BORDER + 1);
|
|
|
|
}
|
2016-09-01 13:53:43 +02:00
|
|
|
|
2017-01-29 12:03:00 +01:00
|
|
|
//--------------------------------------------------
|
|
|
|
// Activate last active panel
|
|
|
|
//--------------------------------------------------
|
2017-09-18 17:36:45 +02:00
|
|
|
if (!emulating && quickstart_start)
|
|
|
|
last_active_panel = 1;
|
2017-01-29 12:03:00 +01:00
|
|
|
categories[last_active_panel].selector->requestFocus();
|
2017-09-18 17:36:45 +02:00
|
|
|
cmdHelp->setVisible(categories[last_active_panel].HelpFunc != nullptr);
|
2017-01-29 12:03:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void gui_halt()
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; categories[i].category != nullptr; ++i)
|
|
|
|
{
|
|
|
|
if (categories[i].ExitFunc != nullptr)
|
|
|
|
(*categories[i].ExitFunc)();
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; categories[i].category != nullptr; ++i)
|
|
|
|
delete categories[i].selector;
|
|
|
|
delete panelFocusListener;
|
|
|
|
delete selectors;
|
|
|
|
|
|
|
|
delete cmdQuit;
|
|
|
|
delete cmdShutdown;
|
|
|
|
delete cmdReset;
|
|
|
|
delete cmdRestart;
|
|
|
|
delete cmdStart;
|
2017-09-18 17:36:45 +02:00
|
|
|
delete cmdHelp;
|
2017-01-29 12:03:00 +01:00
|
|
|
|
|
|
|
delete mainButtonActionListener;
|
|
|
|
|
|
|
|
delete gui_font;
|
|
|
|
delete gui_top;
|
|
|
|
}
|
2015-05-13 18:47:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-01-29 10:36:18 +01:00
|
|
|
void RefreshAllPanels()
|
2015-05-13 18:47:23 +00:00
|
|
|
{
|
2017-04-23 22:23:19 +02:00
|
|
|
for (int i = 0; categories[i].category != nullptr; ++i)
|
2017-01-29 12:03:00 +01:00
|
|
|
{
|
|
|
|
if (categories[i].RefreshFunc != nullptr)
|
|
|
|
(*categories[i].RefreshFunc)();
|
|
|
|
}
|
2015-05-13 18:47:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-01-29 10:36:18 +01:00
|
|
|
void DisableResume()
|
2015-10-11 14:23:51 +02:00
|
|
|
{
|
2017-01-29 12:03:00 +01:00
|
|
|
if (emulating)
|
|
|
|
{
|
|
|
|
widgets::cmdStart->setEnabled(false);
|
|
|
|
gcn::Color backCol;
|
|
|
|
backCol.r = 128;
|
|
|
|
backCol.g = 128;
|
|
|
|
backCol.b = 128;
|
|
|
|
widgets::cmdStart->setForegroundColor(backCol);
|
|
|
|
}
|
2015-10-11 14:23:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-01-29 10:36:18 +01:00
|
|
|
void run_gui()
|
2015-05-13 18:47:23 +00:00
|
|
|
{
|
2017-01-29 12:03:00 +01:00
|
|
|
gui_running = true;
|
|
|
|
gui_rtarea_flags_onenter = gui_create_rtarea_flag(&currprefs);
|
|
|
|
|
2017-09-18 17:36:45 +02:00
|
|
|
expansion_generate_autoconfig_info(&changed_prefs);
|
|
|
|
|
2017-01-29 12:03:00 +01:00
|
|
|
try
|
|
|
|
{
|
|
|
|
sdl::gui_init();
|
|
|
|
widgets::gui_init();
|
2017-09-18 17:36:45 +02:00
|
|
|
if (_tcslen(startup_message) > 0) {
|
|
|
|
ShowMessage(startup_title, startup_message, _T(""), _T("Ok"), _T(""));
|
|
|
|
_tcscpy(startup_title, _T(""));
|
|
|
|
_tcscpy(startup_message, _T(""));
|
|
|
|
widgets::cmdStart->requestFocus();
|
|
|
|
}
|
2017-01-29 12:03:00 +01:00
|
|
|
sdl::gui_run();
|
|
|
|
widgets::gui_halt();
|
|
|
|
sdl::gui_halt();
|
|
|
|
}
|
2017-09-18 17:36:45 +02:00
|
|
|
|
2017-01-29 12:03:00 +01:00
|
|
|
// Catch all guisan exceptions.
|
|
|
|
catch (gcn::Exception e)
|
|
|
|
{
|
|
|
|
cout << e.getMessage() << endl;
|
|
|
|
uae_quit();
|
|
|
|
}
|
2017-09-18 17:36:45 +02:00
|
|
|
|
2017-01-29 12:03:00 +01:00
|
|
|
// Catch all Std exceptions.
|
|
|
|
catch (exception e)
|
|
|
|
{
|
|
|
|
cout << "Std exception: " << e.what() << endl;
|
|
|
|
uae_quit();
|
|
|
|
}
|
2017-09-18 17:36:45 +02:00
|
|
|
|
2017-01-29 12:03:00 +01:00
|
|
|
// Catch all unknown exceptions.
|
|
|
|
catch (...)
|
|
|
|
{
|
|
|
|
cout << "Unknown exception" << endl;
|
|
|
|
uae_quit();
|
|
|
|
}
|
2017-09-18 17:36:45 +02:00
|
|
|
|
|
|
|
expansion_generate_autoconfig_info(&changed_prefs);
|
|
|
|
cfgfile_compatibility_romtype(&changed_prefs);
|
|
|
|
|
2017-01-29 12:03:00 +01:00
|
|
|
if (quit_program > UAE_QUIT || quit_program < -UAE_QUIT)
|
|
|
|
{
|
|
|
|
//--------------------------------------------------
|
|
|
|
// Prepare everything for Reset of Amiga
|
|
|
|
//--------------------------------------------------
|
|
|
|
currprefs.nr_floppies = changed_prefs.nr_floppies;
|
2017-09-18 17:36:45 +02:00
|
|
|
screen_is_picasso = 0;
|
2017-01-29 12:03:00 +01:00
|
|
|
|
|
|
|
if (gui_rtarea_flags_onenter != gui_create_rtarea_flag(&changed_prefs))
|
|
|
|
quit_program = -UAE_RESET_HARD; // Hardreset required...
|
|
|
|
}
|
2017-09-18 17:36:45 +02:00
|
|
|
|
|
|
|
// Reset counter for access violations
|
|
|
|
init_max_signals();
|
2015-05-13 18:47:23 +00:00
|
|
|
}
|