1229 lines
34 KiB
C++
1229 lines
34 KiB
C++
#include <cstdio>
|
|
#include <cstring>
|
|
#include <cstdlib>
|
|
#include <iostream>
|
|
|
|
#include <guisan.hpp>
|
|
#include <SDL_ttf.h>
|
|
#include <guisan/sdl.hpp>
|
|
#include <guisan/sdl/sdltruetypefont.hpp>
|
|
#include "SelectorEntry.hpp"
|
|
|
|
#include "sysdeps.h"
|
|
#include "config.h"
|
|
#include "options.h"
|
|
#include "memory.h"
|
|
#include "uae.h"
|
|
#include "gui_handling.h"
|
|
#include "amiberry_gfx.h"
|
|
#include "amiberry_filesys.hpp"
|
|
#include "autoconf.h"
|
|
|
|
#include "inputdevice.h"
|
|
|
|
#if defined(ANDROID)
|
|
#include "androidsdl_event.h"
|
|
//#include <SDL_screenkeyboard.h>
|
|
//#include <SDL_android.h>
|
|
#include <android/log.h>
|
|
#endif
|
|
|
|
std::vector<int> joypad_axis_state; // Keep track of horizontal and vertical axis states
|
|
|
|
bool gui_running = false;
|
|
static int last_active_panel = 3;
|
|
|
|
#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("");
|
|
|
|
void target_startup_msg(const TCHAR* title, const TCHAR* msg)
|
|
{
|
|
_tcsncpy(startup_title, title, MAX_STARTUP_TITLE);
|
|
_tcsncpy(startup_message, msg, MAX_STARTUP_MESSAGE);
|
|
}
|
|
|
|
ConfigCategory categories[] = {
|
|
{
|
|
"About", "data/amigainfo.ico", nullptr, nullptr, InitPanelAbout, ExitPanelAbout, RefreshPanelAbout,
|
|
HelpPanelAbout
|
|
},
|
|
{"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},
|
|
{
|
|
"Custom controls", "data/controller.png", nullptr, nullptr, InitPanelCustom, ExitPanelCustom,
|
|
RefreshPanelCustom, HelpPanelCustom
|
|
},
|
|
{"Miscellaneous", "data/misc.ico", nullptr, nullptr, InitPanelMisc, ExitPanelMisc, RefreshPanelMisc, HelpPanelMisc},
|
|
{
|
|
"Savestates", "data/savestate.png", nullptr, nullptr, InitPanelSavestate, ExitPanelSavestate,
|
|
RefreshPanelSavestate, HelpPanelSavestate
|
|
},
|
|
#ifdef ANDROID
|
|
{ "OnScreen", "data/screen.ico", NULL, NULL, InitPanelOnScreen, ExitPanelOnScreen, RefreshPanelOnScreen, HelpPanelOnScreen },
|
|
#endif
|
|
{nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}
|
|
};
|
|
|
|
enum
|
|
{
|
|
PANEL_ABOUT,
|
|
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_CUSTOM,
|
|
PANEL_MISC,
|
|
PANEL_SAVESTATES,
|
|
#ifdef ANDROID
|
|
PANEL_ONSCREEN,
|
|
#endif
|
|
NUM_PANELS
|
|
};
|
|
|
|
/*
|
|
* SDL Stuff we need
|
|
*/
|
|
SDL_Joystick* gui_joystick;
|
|
SDL_Surface* gui_screen;
|
|
SDL_Event gui_event;
|
|
SDL_Event touch_event;
|
|
SDL_Window* sdl_window;
|
|
#ifdef USE_DISPMANX
|
|
DISPMANX_RESOURCE_HANDLE_T gui_resource;
|
|
DISPMANX_RESOURCE_HANDLE_T black_gui_resource;
|
|
DISPMANX_ELEMENT_HANDLE_T gui_element;
|
|
int element_present = 0;
|
|
#else
|
|
SDL_Texture* gui_texture;
|
|
SDL_Cursor* cursor;
|
|
SDL_Surface* cursor_surface;
|
|
#endif
|
|
|
|
/*
|
|
* Gui SDL stuff we need
|
|
*/
|
|
gcn::SDLInput* gui_input;
|
|
gcn::SDLGraphics* gui_graphics;
|
|
gcn::SDLImageLoader* gui_imageLoader;
|
|
gcn::SDLTrueTypeFont* gui_font;
|
|
|
|
/*
|
|
* Gui stuff we need
|
|
*/
|
|
gcn::Gui* uae_gui;
|
|
gcn::Container* gui_top;
|
|
gcn::Container* selectors;
|
|
gcn::Color gui_baseCol;
|
|
gcn::Color colTextboxBackground;
|
|
gcn::Color colSelectorInactive;
|
|
gcn::Color colSelectorActive;
|
|
gcn::FocusHandler* focusHdl;
|
|
gcn::Widget* activeWidget;
|
|
|
|
// Main buttons
|
|
gcn::Button* cmdQuit;
|
|
gcn::Button* cmdReset;
|
|
gcn::Button* cmdRestart;
|
|
gcn::Button* cmdStart;
|
|
gcn::Button* cmdHelp;
|
|
gcn::Button* cmdShutdown;
|
|
|
|
|
|
/* Flag for changes in rtarea:
|
|
Bit 0: any HD in config?
|
|
Bit 1: force because add/remove HD was clicked or new config loaded
|
|
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.
|
|
*/
|
|
static int gui_rtarea_flags_onenter;
|
|
|
|
static int gui_create_rtarea_flag(struct uae_prefs* p)
|
|
{
|
|
auto flag = 0;
|
|
|
|
if (count_HDs(p) > 0)
|
|
flag |= 1;
|
|
|
|
if (p->input_tablet > 0)
|
|
flag |= 8;
|
|
|
|
return flag;
|
|
}
|
|
|
|
void gui_force_rtarea_hdchange()
|
|
{
|
|
gui_rtarea_flags_onenter |= 2;
|
|
}
|
|
|
|
void gui_restart()
|
|
{
|
|
gui_running = false;
|
|
}
|
|
|
|
static void (*refresh_func_after_draw)(void) = nullptr;
|
|
|
|
void register_refresh_func(void (*func)(void))
|
|
{
|
|
refresh_func_after_draw = func;
|
|
}
|
|
|
|
static void show_help_requested()
|
|
{
|
|
vector<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);
|
|
}
|
|
}
|
|
|
|
void cap_fps(Uint64 start, int fps)
|
|
{
|
|
const auto end = SDL_GetPerformanceCounter();
|
|
const auto elapsed_ms = static_cast<float>(end - start) / static_cast<float>(SDL_GetPerformanceFrequency()) * 1000.0f;
|
|
if (fps == 60)
|
|
SDL_Delay(floor(16.666f - elapsed_ms));
|
|
else if (fps == 50)
|
|
SDL_Delay(floor(20.000f - elapsed_ms));
|
|
}
|
|
|
|
void update_gui_screen()
|
|
{
|
|
#ifdef USE_DISPMANX
|
|
vc_dispmanx_resource_write_data(gui_resource, rgb_mode, gui_screen->pitch, gui_screen->pixels, &blit_rect);
|
|
updateHandle = vc_dispmanx_update_start(0);
|
|
vc_dispmanx_element_change_source(updateHandle, gui_element, gui_resource);
|
|
vc_dispmanx_update_submit_sync(updateHandle);
|
|
#else
|
|
SDL_RenderClear(renderer);
|
|
SDL_UpdateTexture(gui_texture, nullptr, gui_screen->pixels, gui_screen->pitch);
|
|
if (amiberry_options.rotation_angle == 0 || amiberry_options.rotation_angle == 180)
|
|
renderQuad = { 0, 0, gui_screen->w, gui_screen->h };
|
|
else
|
|
renderQuad = { -(GUI_WIDTH - GUI_HEIGHT) / 2, (GUI_WIDTH - GUI_HEIGHT) / 2, gui_screen->w, gui_screen->h };
|
|
|
|
SDL_RenderCopyEx(renderer, gui_texture, nullptr, &renderQuad, amiberry_options.rotation_angle, nullptr, SDL_FLIP_NONE);
|
|
SDL_RenderPresent(renderer);
|
|
#endif
|
|
}
|
|
|
|
#ifdef USE_DISPMANX
|
|
#else
|
|
void setup_cursor()
|
|
{
|
|
// Detect resolution and load appropriate cursor image
|
|
if (strcmp(sdl_video_driver, "x11") != 0 && sdlMode.w > 1280)
|
|
{
|
|
cursor_surface = SDL_LoadBMP(prefix_with_application_directory_path("data/cursor-x2.bmp").c_str());
|
|
}
|
|
else
|
|
{
|
|
cursor_surface = SDL_LoadBMP(prefix_with_application_directory_path("data/cursor.bmp").c_str());
|
|
}
|
|
|
|
if (!cursor_surface)
|
|
{
|
|
// Load failed. Log error.
|
|
write_log("Could not load cursor bitmap: %s\n", SDL_GetError());
|
|
return;
|
|
}
|
|
|
|
auto* formatted_surface = SDL_ConvertSurfaceFormat(cursor_surface, SDL_PIXELFORMAT_RGBA8888, 0);
|
|
if (formatted_surface != nullptr)
|
|
{
|
|
SDL_FreeSurface(cursor_surface);
|
|
|
|
// Create new cursor with surface
|
|
cursor = SDL_CreateColorCursor(formatted_surface, 0, 0);
|
|
SDL_FreeSurface(formatted_surface);
|
|
}
|
|
|
|
if (!cursor)
|
|
{
|
|
// Cursor creation failed. Log error and free surface
|
|
write_log("Could not create color cursor: %s\n", SDL_GetError());
|
|
cursor_surface = nullptr;
|
|
formatted_surface = nullptr;
|
|
SDL_SetCursor(SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW));
|
|
return;
|
|
}
|
|
|
|
SDL_SetCursor(cursor);
|
|
}
|
|
#endif
|
|
|
|
void amiberry_gui_init()
|
|
{
|
|
//-------------------------------------------------
|
|
// Create new screen for GUI
|
|
//-------------------------------------------------
|
|
if (!gui_screen)
|
|
{
|
|
gui_screen = SDL_CreateRGBSurface(0, GUI_WIDTH, GUI_HEIGHT, 16, 0, 0, 0, 0);
|
|
}
|
|
check_error_sdl(gui_screen == nullptr, "Unable to create GUI surface:");
|
|
|
|
#ifdef USE_DISPMANX
|
|
displayHandle = vc_dispmanx_display_open(0);
|
|
rgb_mode = VC_IMAGE_RGB565;
|
|
uint32_t vc_gui_image_ptr;
|
|
if (!gui_resource)
|
|
gui_resource = vc_dispmanx_resource_create(rgb_mode, GUI_WIDTH, GUI_HEIGHT, &vc_gui_image_ptr);
|
|
if (!black_gui_resource)
|
|
black_gui_resource = vc_dispmanx_resource_create(rgb_mode, GUI_WIDTH, GUI_HEIGHT, &vc_gui_image_ptr);
|
|
|
|
vc_dispmanx_rect_set(&blit_rect, 0, 0, GUI_WIDTH, GUI_HEIGHT);
|
|
vc_dispmanx_resource_write_data(gui_resource, rgb_mode, gui_screen->pitch, gui_screen->pixels, &blit_rect);
|
|
vc_dispmanx_resource_write_data(black_gui_resource, rgb_mode, gui_screen->pitch, gui_screen->pixels, &blit_rect);
|
|
vc_dispmanx_rect_set(&src_rect, 0, 0, GUI_WIDTH << 16, GUI_HEIGHT << 16);
|
|
vc_dispmanx_rect_set(&black_rect, 0, 0, modeInfo.width, modeInfo.height);
|
|
// Full screen destination rectangle
|
|
//vc_dispmanx_rect_set(&dst_rect, 0, 0, modeInfo.width, modeInfo.height);
|
|
|
|
// Scaled display with correct Aspect Ratio
|
|
const auto want_aspect = static_cast<float>(GUI_WIDTH) / static_cast<float>(GUI_HEIGHT);
|
|
const auto real_aspect = static_cast<float>(modeInfo.width) / static_cast<float>(modeInfo.height);
|
|
|
|
SDL_Rect viewport;
|
|
if (want_aspect > real_aspect)
|
|
{
|
|
const auto scale = static_cast<float>(modeInfo.width) / static_cast<float>(GUI_WIDTH);
|
|
viewport.x = 0;
|
|
viewport.w = modeInfo.width;
|
|
viewport.h = static_cast<int>(std::ceil(GUI_HEIGHT * scale));
|
|
viewport.y = (modeInfo.height - viewport.h) / 2;
|
|
}
|
|
else
|
|
{
|
|
const auto scale = static_cast<float>(modeInfo.height) / static_cast<float>(GUI_HEIGHT);
|
|
viewport.y = 0;
|
|
viewport.h = modeInfo.height;
|
|
viewport.w = static_cast<int>(std::ceil(GUI_WIDTH * scale));
|
|
viewport.x = (modeInfo.width - viewport.w) / 2;
|
|
}
|
|
vc_dispmanx_rect_set(&dst_rect, viewport.x, viewport.y, viewport.w, viewport.h);
|
|
|
|
if (!element_present)
|
|
{
|
|
element_present = 1;
|
|
updateHandle = vc_dispmanx_update_start(0);
|
|
|
|
VC_DISPMANX_ALPHA_T alpha;
|
|
alpha.flags = DISPMANX_FLAGS_ALPHA_FROM_SOURCE;
|
|
alpha.opacity = 255;
|
|
alpha.mask = 0;
|
|
|
|
if (!blackscreen_element)
|
|
blackscreen_element = vc_dispmanx_element_add(updateHandle, displayHandle, 0,
|
|
&black_rect, black_gui_resource, &src_rect, DISPMANX_PROTECTION_NONE, &alpha,
|
|
nullptr, DISPMANX_NO_ROTATE);
|
|
|
|
if (!gui_element)
|
|
gui_element = vc_dispmanx_element_add(updateHandle, displayHandle, 1,
|
|
&dst_rect, gui_resource, &src_rect, DISPMANX_PROTECTION_NONE, &alpha,
|
|
nullptr, DISPMANX_NO_ROTATE);
|
|
|
|
vc_dispmanx_update_submit_sync(updateHandle);
|
|
}
|
|
#else
|
|
setup_cursor();
|
|
|
|
if (sdl_window)
|
|
{
|
|
if (amiberry_options.rotation_angle != 0 && amiberry_options.rotation_angle != 180)
|
|
SDL_SetWindowSize(sdl_window, GUI_HEIGHT, GUI_WIDTH);
|
|
else
|
|
SDL_SetWindowSize(sdl_window, GUI_WIDTH, GUI_HEIGHT);
|
|
}
|
|
|
|
// make the scaled rendering look smoother (linear scaling).
|
|
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
|
|
|
|
gui_texture = SDL_CreateTexture(renderer, gui_screen->format->format, SDL_TEXTUREACCESS_STREAMING, gui_screen->w,
|
|
gui_screen->h);
|
|
check_error_sdl(gui_texture == nullptr, "Unable to create GUI texture:");
|
|
#endif
|
|
|
|
if (amiberry_options.rotation_angle == 0 || amiberry_options.rotation_angle == 180)
|
|
SDL_RenderSetLogicalSize(renderer, GUI_WIDTH, GUI_HEIGHT);
|
|
else
|
|
SDL_RenderSetLogicalSize(renderer, GUI_HEIGHT, GUI_WIDTH);
|
|
|
|
SDL_ShowCursor(SDL_ENABLE);
|
|
SDL_SetRelativeMouseMode(SDL_FALSE);
|
|
|
|
//-------------------------------------------------
|
|
// Create helpers for GUI framework
|
|
//-------------------------------------------------
|
|
gui_imageLoader = new gcn::SDLImageLoader();
|
|
// The ImageLoader in use is static and must be set to be
|
|
// able to load images
|
|
gui_imageLoader->setRenderer(renderer);
|
|
gcn::Image::setImageLoader(gui_imageLoader);
|
|
gui_graphics = new gcn::SDLGraphics();
|
|
// 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.
|
|
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);
|
|
}
|
|
|
|
void amiberry_gui_halt()
|
|
{
|
|
delete uae_gui;
|
|
delete gui_imageLoader;
|
|
delete gui_input;
|
|
delete gui_graphics;
|
|
|
|
if (gui_screen != nullptr)
|
|
{
|
|
SDL_FreeSurface(gui_screen);
|
|
gui_screen = nullptr;
|
|
}
|
|
#ifdef USE_DISPMANX
|
|
if (element_present == 1)
|
|
{
|
|
element_present = 0;
|
|
updateHandle = vc_dispmanx_update_start(0);
|
|
vc_dispmanx_element_remove(updateHandle, gui_element);
|
|
gui_element = 0;
|
|
vc_dispmanx_element_remove(updateHandle, blackscreen_element);
|
|
blackscreen_element = 0;
|
|
vc_dispmanx_update_submit_sync(updateHandle);
|
|
}
|
|
|
|
if (gui_resource)
|
|
{
|
|
vc_dispmanx_resource_delete(gui_resource);
|
|
gui_resource = 0;
|
|
}
|
|
|
|
if (black_gui_resource)
|
|
{
|
|
vc_dispmanx_resource_delete(black_gui_resource);
|
|
black_gui_resource = 0;
|
|
}
|
|
if (displayHandle)
|
|
vc_dispmanx_display_close(displayHandle);
|
|
#else
|
|
if (gui_texture != nullptr)
|
|
{
|
|
SDL_DestroyTexture(gui_texture);
|
|
gui_texture = nullptr;
|
|
}
|
|
|
|
if (cursor != nullptr)
|
|
{
|
|
SDL_FreeCursor(cursor);
|
|
cursor = nullptr;
|
|
}
|
|
|
|
// Clear the screen
|
|
SDL_RenderClear(renderer);
|
|
SDL_RenderPresent(renderer);
|
|
#endif
|
|
}
|
|
|
|
// Return the state of a joypad axis
|
|
// -1 (left or up), 0 (centered) or 1 (right or down)
|
|
int get_joypad_axis_state(int axis)
|
|
{
|
|
if (!gui_joystick)
|
|
return 0;
|
|
|
|
const auto state = SDL_JoystickGetAxis(gui_joystick, axis);
|
|
|
|
int result;
|
|
if (std::abs(state) < 10000)
|
|
result = 0;
|
|
else
|
|
result = state > 0 ? 1 : -1;
|
|
|
|
return result;
|
|
}
|
|
|
|
void check_input()
|
|
{
|
|
const auto key_for_gui = SDL_GetKeyFromName(currprefs.open_gui);
|
|
int gotEvent = 0;
|
|
|
|
while (SDL_PollEvent(&gui_event))
|
|
{
|
|
switch (gui_event.type)
|
|
{
|
|
case SDL_QUIT:
|
|
gotEvent = 1;
|
|
//-------------------------------------------------
|
|
// Quit entire program via SQL-Quit
|
|
//-------------------------------------------------
|
|
uae_quit();
|
|
gui_running = false;
|
|
break;
|
|
|
|
case SDL_JOYHATMOTION:
|
|
case SDL_JOYBUTTONDOWN:
|
|
if (gui_joystick)
|
|
{
|
|
gotEvent = 1;
|
|
const int hat = SDL_JoystickGetHat(gui_joystick, 0);
|
|
|
|
if (SDL_JoystickGetButton(gui_joystick, host_input_buttons[0].dpad_up) || hat & SDL_HAT_UP) // dpad
|
|
{
|
|
if (HandleNavigation(DIRECTION_UP))
|
|
continue; // Don't change value when enter Slider -> don't send event to control
|
|
PushFakeKey(SDLK_UP);
|
|
break;
|
|
}
|
|
if (SDL_JoystickGetButton(gui_joystick, host_input_buttons[0].dpad_down) || hat & SDL_HAT_DOWN) // dpad
|
|
{
|
|
if (HandleNavigation(DIRECTION_DOWN))
|
|
continue; // Don't change value when enter Slider -> don't send event to control
|
|
PushFakeKey(SDLK_DOWN);
|
|
break;
|
|
}
|
|
|
|
if (SDL_JoystickGetButton(gui_joystick, host_input_buttons[0].left_shoulder)) // dpad
|
|
{
|
|
for (auto z = 0; z < 10; ++z)
|
|
{
|
|
PushFakeKey(SDLK_UP);
|
|
}
|
|
}
|
|
if (SDL_JoystickGetButton(gui_joystick, host_input_buttons[0].right_shoulder)) // dpad
|
|
{
|
|
for (auto z = 0; z < 10; ++z)
|
|
{
|
|
PushFakeKey(SDLK_DOWN);
|
|
}
|
|
}
|
|
|
|
if (SDL_JoystickGetButton(gui_joystick, host_input_buttons[0].dpad_right) || hat & SDL_HAT_RIGHT)
|
|
// dpad
|
|
{
|
|
if (HandleNavigation(DIRECTION_RIGHT))
|
|
continue; // Don't change value when enter Slider -> don't send event to control
|
|
PushFakeKey(SDLK_RIGHT);
|
|
break;
|
|
}
|
|
if (SDL_JoystickGetButton(gui_joystick, host_input_buttons[0].dpad_left) || hat & SDL_HAT_LEFT) // dpad
|
|
{
|
|
if (HandleNavigation(DIRECTION_LEFT))
|
|
continue; // Don't change value when enter Slider -> don't send event to control
|
|
PushFakeKey(SDLK_LEFT);
|
|
break;
|
|
}
|
|
if (SDL_JoystickGetButton(gui_joystick, host_input_buttons[0].south_button)) // need this to be X button
|
|
{
|
|
PushFakeKey(SDLK_RETURN);
|
|
continue;
|
|
}
|
|
|
|
if (SDL_JoystickGetButton(gui_joystick, host_input_buttons[0].quit_button) &&
|
|
SDL_JoystickGetButton(gui_joystick, host_input_buttons[0].hotkey_button)) // use the HOTKEY button
|
|
{
|
|
uae_quit();
|
|
gui_running = false;
|
|
break;
|
|
}
|
|
if (SDL_JoystickGetButton(gui_joystick, host_input_buttons[0].left_trigger))
|
|
{
|
|
show_help_requested();
|
|
cmdHelp->requestFocus();
|
|
break;
|
|
}
|
|
if (SDL_JoystickGetButton(gui_joystick, host_input_buttons[0].menu_button)) // use the HOTKEY button
|
|
{
|
|
gui_running = false;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case SDL_JOYAXISMOTION:
|
|
if (gui_joystick)
|
|
{
|
|
gotEvent = 1;
|
|
// Deadzone
|
|
if (std::abs(gui_event.jaxis.value) >= 10000 || std::abs(gui_event.jaxis.value) <= 5000)
|
|
{
|
|
int axis_state;
|
|
int axis = gui_event.jaxis.axis;
|
|
int value = gui_event.jaxis.value;
|
|
if (std::abs(value) < 10000)
|
|
axis_state = 0;
|
|
else
|
|
axis_state = value > 0 ? 1 : -1;
|
|
|
|
if (joypad_axis_state[axis] == axis_state)
|
|
{
|
|
// ignore repeated axis movement state
|
|
break;
|
|
}
|
|
joypad_axis_state[axis] = axis_state;
|
|
|
|
if (get_joypad_axis_state(host_input_buttons[0].lstick_axis_y) == -1)
|
|
{
|
|
if (HandleNavigation(DIRECTION_UP))
|
|
continue; // Don't change value when enter Slider -> don't send event to control
|
|
PushFakeKey(SDLK_UP);
|
|
break;
|
|
}
|
|
if (get_joypad_axis_state(host_input_buttons[0].lstick_axis_y) == 1)
|
|
{
|
|
if (HandleNavigation(DIRECTION_DOWN))
|
|
continue; // Don't change value when enter Slider -> don't send event to control
|
|
PushFakeKey(SDLK_DOWN);
|
|
break;
|
|
}
|
|
if (get_joypad_axis_state(host_input_buttons[0].lstick_axis_x) == 1)
|
|
{
|
|
if (HandleNavigation(DIRECTION_RIGHT))
|
|
continue; // Don't change value when enter Slider -> don't send event to control
|
|
PushFakeKey(SDLK_RIGHT);
|
|
break;
|
|
}
|
|
if (get_joypad_axis_state(host_input_buttons[0].lstick_axis_x) == -1)
|
|
{
|
|
if (HandleNavigation(DIRECTION_LEFT))
|
|
continue; // Don't change value when enter Slider -> don't send event to control
|
|
PushFakeKey(SDLK_LEFT);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case SDL_KEYDOWN:
|
|
gotEvent = 1;
|
|
if (gui_event.key.keysym.sym == key_for_gui)
|
|
{
|
|
if (emulating && cmdStart->isEnabled())
|
|
{
|
|
//------------------------------------------------
|
|
// Continue emulation
|
|
//------------------------------------------------
|
|
gui_running = false;
|
|
}
|
|
else
|
|
{
|
|
//------------------------------------------------
|
|
// First start of emulator -> reset Amiga
|
|
//------------------------------------------------
|
|
uae_reset(0, 1);
|
|
gui_running = false;
|
|
}
|
|
}
|
|
else
|
|
switch (gui_event.key.keysym.sym)
|
|
{
|
|
case SDLK_q:
|
|
//-------------------------------------------------
|
|
// Quit entire program via Q on keyboard
|
|
//-------------------------------------------------
|
|
focusHdl = gui_top->_getFocusHandler();
|
|
activeWidget = focusHdl->getFocused();
|
|
if (dynamic_cast<gcn::TextField*>(activeWidget) == nullptr)
|
|
{
|
|
// ...but only if we are not in a Textfield...
|
|
uae_quit();
|
|
gui_running = false;
|
|
}
|
|
break;
|
|
|
|
case VK_ESCAPE:
|
|
case VK_Red:
|
|
gui_running = false;
|
|
break;
|
|
|
|
|
|
case VK_Green:
|
|
case VK_Blue:
|
|
//------------------------------------------------
|
|
// Simulate press of enter when 'X' pressed
|
|
//------------------------------------------------
|
|
gui_event.key.keysym.sym = SDLK_RETURN;
|
|
|
|
gui_input->pushInput(gui_event); // Fire key down
|
|
gui_event.type = SDL_KEYUP; // and the key up
|
|
break;
|
|
|
|
case VK_UP:
|
|
if (HandleNavigation(DIRECTION_UP))
|
|
continue; // Don't change value when enter ComboBox -> don't send event to control
|
|
break;
|
|
|
|
case VK_DOWN:
|
|
if (HandleNavigation(DIRECTION_DOWN))
|
|
continue; // Don't change value when enter ComboBox -> don't send event to control
|
|
break;
|
|
|
|
case VK_LEFT:
|
|
if (HandleNavigation(DIRECTION_LEFT))
|
|
continue; // Don't change value when enter Slider -> don't send event to control
|
|
break;
|
|
|
|
case VK_RIGHT:
|
|
if (HandleNavigation(DIRECTION_RIGHT))
|
|
continue; // Don't change value when enter Slider -> don't send event to control
|
|
break;
|
|
|
|
case SDLK_F1:
|
|
show_help_requested();
|
|
cmdHelp->requestFocus();
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case SDL_FINGERDOWN:
|
|
gotEvent = 1;
|
|
memcpy(&touch_event, &gui_event, sizeof gui_event);
|
|
touch_event.type = SDL_MOUSEBUTTONDOWN;
|
|
touch_event.button.which = 0;
|
|
touch_event.button.button = SDL_BUTTON_LEFT;
|
|
touch_event.button.state = SDL_PRESSED;
|
|
touch_event.button.x = gui_graphics->getTarget()->w * gui_event.tfinger.x;
|
|
touch_event.button.y = gui_graphics->getTarget()->h * gui_event.tfinger.y;
|
|
gui_input->pushInput(touch_event);
|
|
break;
|
|
|
|
case SDL_FINGERUP:
|
|
gotEvent = 1;
|
|
memcpy(&touch_event, &gui_event, sizeof gui_event);
|
|
touch_event.type = SDL_MOUSEBUTTONUP;
|
|
touch_event.button.which = 0;
|
|
touch_event.button.button = SDL_BUTTON_LEFT;
|
|
touch_event.button.state = SDL_RELEASED;
|
|
touch_event.button.x = gui_graphics->getTarget()->w * gui_event.tfinger.x;
|
|
touch_event.button.y = gui_graphics->getTarget()->h * gui_event.tfinger.y;
|
|
gui_input->pushInput(touch_event);
|
|
break;
|
|
|
|
case SDL_FINGERMOTION:
|
|
gotEvent = 1;
|
|
memcpy(&touch_event, &gui_event, sizeof gui_event);
|
|
touch_event.type = SDL_MOUSEMOTION;
|
|
touch_event.motion.which = 0;
|
|
touch_event.motion.state = 0;
|
|
touch_event.motion.x = gui_graphics->getTarget()->w * gui_event.tfinger.x;
|
|
touch_event.motion.y = gui_graphics->getTarget()->h * gui_event.tfinger.y;
|
|
gui_input->pushInput(touch_event);
|
|
break;
|
|
|
|
case SDL_KEYUP:
|
|
case SDL_JOYBUTTONUP:
|
|
case SDL_MOUSEBUTTONDOWN:
|
|
case SDL_MOUSEBUTTONUP:
|
|
case SDL_MOUSEMOTION:
|
|
case SDL_MOUSEWHEEL:
|
|
gotEvent = 1;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
//-------------------------------------------------
|
|
// Send event to gui-controls
|
|
//-------------------------------------------------
|
|
#ifdef ANDROID
|
|
androidsdl_event(gui_event, gui_input);
|
|
#else
|
|
gui_input->pushInput(gui_event);
|
|
#endif
|
|
}
|
|
|
|
if (gotEvent)
|
|
{
|
|
// Now we let the Gui object perform its logic.
|
|
uae_gui->logic();
|
|
// Now we let the Gui object draw itself.
|
|
uae_gui->draw();
|
|
|
|
update_gui_screen();
|
|
}
|
|
}
|
|
|
|
void amiberry_gui_run()
|
|
{
|
|
if (amiberry_options.gui_joystick_control)
|
|
{
|
|
const auto available_joysticks = SDL_NumJoysticks();
|
|
if (available_joysticks > 0)
|
|
{
|
|
for (auto j = 0; j <= available_joysticks; j++)
|
|
{
|
|
gui_joystick = SDL_JoystickOpen(j);
|
|
// Some joysticks have no axes or buttons (e.g. Wii Remote IR), skip those
|
|
if (SDL_JoystickNumAxes(gui_joystick) > 0 && SDL_JoystickNumButtons(gui_joystick) > 0)
|
|
{
|
|
joypad_axis_state.assign(SDL_JoystickNumAxes(gui_joystick), 0);
|
|
break;
|
|
}
|
|
|
|
SDL_JoystickClose(gui_joystick);
|
|
gui_joystick = nullptr;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Prepare the screen once
|
|
uae_gui->logic();
|
|
uae_gui->draw();
|
|
update_gui_screen();
|
|
|
|
//-------------------------------------------------
|
|
// The main loop
|
|
//-------------------------------------------------
|
|
while (gui_running)
|
|
{
|
|
const auto start = SDL_GetPerformanceCounter();
|
|
check_input();
|
|
|
|
if (gui_rtarea_flags_onenter != gui_create_rtarea_flag(&changed_prefs))
|
|
disable_resume();
|
|
|
|
if (refresh_func_after_draw != nullptr)
|
|
{
|
|
void (*currFunc)() = refresh_func_after_draw;
|
|
refresh_func_after_draw = nullptr;
|
|
currFunc();
|
|
}
|
|
|
|
cap_fps(start, 60);
|
|
}
|
|
|
|
if (gui_joystick)
|
|
{
|
|
SDL_JoystickClose(gui_joystick);
|
|
gui_joystick = nullptr;
|
|
joypad_axis_state.clear();
|
|
}
|
|
}
|
|
|
|
class MainButtonActionListener : public gcn::ActionListener
|
|
{
|
|
public:
|
|
void action(const gcn::ActionEvent& actionEvent) override
|
|
{
|
|
if (actionEvent.getSource() == cmdShutdown)
|
|
{
|
|
// ------------------------------------------------
|
|
// Shutdown the host (power off)
|
|
// ------------------------------------------------
|
|
uae_quit();
|
|
gui_running = false;
|
|
host_poweroff = true;
|
|
}
|
|
|
|
if (actionEvent.getSource() == cmdQuit)
|
|
{
|
|
//-------------------------------------------------
|
|
// Quit entire program via click on Quit-button
|
|
//-------------------------------------------------
|
|
uae_quit();
|
|
gui_running = false;
|
|
}
|
|
else if (actionEvent.getSource() == cmdReset)
|
|
{
|
|
//-------------------------------------------------
|
|
// Reset Amiga via click on Reset-button
|
|
//-------------------------------------------------
|
|
uae_reset(1, 1);
|
|
gui_running = false;
|
|
}
|
|
else if (actionEvent.getSource() == cmdRestart)
|
|
{
|
|
//-------------------------------------------------
|
|
// Restart emulator
|
|
//-------------------------------------------------
|
|
char tmp[MAX_DPATH];
|
|
get_configuration_path(tmp, sizeof tmp);
|
|
if (strlen(last_loaded_config) > 0)
|
|
strncat(tmp, last_loaded_config, MAX_DPATH - 1);
|
|
else
|
|
{
|
|
strncat(tmp, OPTIONSFILENAME, MAX_DPATH - 1);
|
|
strncat(tmp, ".uae", MAX_DPATH - 10);
|
|
}
|
|
uae_restart(-1, tmp);
|
|
gui_running = false;
|
|
}
|
|
else if (actionEvent.getSource() == cmdStart)
|
|
{
|
|
if (emulating && cmdStart->isEnabled())
|
|
{
|
|
//------------------------------------------------
|
|
// Continue emulation
|
|
//------------------------------------------------
|
|
gui_running = false;
|
|
}
|
|
else
|
|
{
|
|
//------------------------------------------------
|
|
// First start of emulator -> reset Amiga
|
|
//------------------------------------------------
|
|
uae_reset(0, 1);
|
|
gui_running = false;
|
|
}
|
|
}
|
|
else if (actionEvent.getSource() == cmdHelp)
|
|
{
|
|
show_help_requested();
|
|
cmdHelp->requestFocus();
|
|
}
|
|
}
|
|
};
|
|
|
|
MainButtonActionListener* mainButtonActionListener;
|
|
|
|
class PanelFocusListener : public gcn::FocusListener
|
|
{
|
|
public:
|
|
void focusGained(const gcn::Event& event) override
|
|
{
|
|
for (auto i = 0; categories[i].category != nullptr; ++i)
|
|
{
|
|
if (event.getSource() == categories[i].selector)
|
|
{
|
|
categories[i].selector->setActive(true);
|
|
categories[i].panel->setVisible(true);
|
|
last_active_panel = i;
|
|
cmdHelp->setVisible(categories[last_active_panel].HelpFunc != nullptr);
|
|
}
|
|
else
|
|
{
|
|
categories[i].selector->setActive(false);
|
|
categories[i].panel->setVisible(false);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
PanelFocusListener* panelFocusListener;
|
|
|
|
void gui_widgets_init()
|
|
{
|
|
int i;
|
|
int yPos;
|
|
|
|
//-------------------------------------------------
|
|
// Define base colors
|
|
//-------------------------------------------------
|
|
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);
|
|
|
|
//-------------------------------------------------
|
|
// 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);
|
|
|
|
//-------------------------------------------------
|
|
// Initialize fonts
|
|
//-------------------------------------------------
|
|
TTF_Init();
|
|
|
|
try
|
|
{
|
|
gui_font = new gcn::SDLTrueTypeFont(prefix_with_application_directory_path("data/AmigaTopaz.ttf"), 15);
|
|
}
|
|
catch (const std::exception& ex)
|
|
{
|
|
write_log("Could not open data/AmigaTopaz.ttf!\n");
|
|
abort();
|
|
}
|
|
catch (...)
|
|
{
|
|
write_log("An error occurred while trying to open data/AmigaTopaz.ttf!\n");
|
|
abort();
|
|
}
|
|
|
|
gcn::Widget::setGlobalFont(gui_font);
|
|
gui_font->setAntiAlias(false);
|
|
|
|
//--------------------------------------------------
|
|
// 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);
|
|
|
|
cmdHelp = new gcn::Button("Help");
|
|
cmdHelp->setSize(BUTTON_WIDTH, BUTTON_HEIGHT);
|
|
cmdHelp->setBaseColor(gui_baseCol);
|
|
cmdHelp->setId("Help");
|
|
cmdHelp->addActionListener(mainButtonActionListener);
|
|
|
|
//--------------------------------------------------
|
|
// Create selector entries
|
|
//--------------------------------------------------
|
|
const auto 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);
|
|
const auto 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, prefix_with_application_directory_path(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);
|
|
}
|
|
|
|
//--------------------------------------------------
|
|
// Initialize panels
|
|
//--------------------------------------------------
|
|
for (i = 0; categories[i].category != nullptr; ++i)
|
|
{
|
|
if (categories[i].InitFunc != nullptr)
|
|
(*categories[i].InitFunc)(categories[i]);
|
|
}
|
|
|
|
//--------------------------------------------------
|
|
// Place everything on main form
|
|
//--------------------------------------------------
|
|
#ifndef ANDROID
|
|
gui_top->add(cmdShutdown, DISTANCE_BORDER, GUI_HEIGHT - DISTANCE_BORDER - BUTTON_HEIGHT);
|
|
#endif
|
|
gui_top->add(cmdQuit, DISTANCE_BORDER + BUTTON_WIDTH + DISTANCE_NEXT_X,
|
|
GUI_HEIGHT - DISTANCE_BORDER - BUTTON_HEIGHT);
|
|
gui_top->add(cmdRestart, DISTANCE_BORDER + 2 * BUTTON_WIDTH + 2 * DISTANCE_NEXT_X,
|
|
GUI_HEIGHT - DISTANCE_BORDER - BUTTON_HEIGHT);
|
|
gui_top->add(cmdHelp, DISTANCE_BORDER + 3 * BUTTON_WIDTH + 3 * DISTANCE_NEXT_X,
|
|
GUI_HEIGHT - DISTANCE_BORDER - BUTTON_HEIGHT);
|
|
gui_top->add(cmdReset, DISTANCE_BORDER + 5 * BUTTON_WIDTH + 5 * DISTANCE_NEXT_X,
|
|
GUI_HEIGHT - DISTANCE_BORDER - BUTTON_HEIGHT);
|
|
gui_top->add(cmdStart, GUI_WIDTH - DISTANCE_BORDER - BUTTON_WIDTH, GUI_HEIGHT - DISTANCE_BORDER - BUTTON_HEIGHT);
|
|
|
|
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);
|
|
}
|
|
|
|
//--------------------------------------------------
|
|
// Activate last active panel
|
|
//--------------------------------------------------
|
|
if (!emulating && amiberry_options.quickstart_start)
|
|
last_active_panel = 2;
|
|
categories[last_active_panel].selector->requestFocus();
|
|
cmdHelp->setVisible(categories[last_active_panel].HelpFunc != nullptr);
|
|
}
|
|
|
|
void gui_widgets_halt()
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; categories[i].category != nullptr; ++i)
|
|
{
|
|
if (categories[i].ExitFunc != nullptr)
|
|
(*categories[i].ExitFunc)();
|
|
|
|
delete categories[i].selector;
|
|
delete categories[i].panel;
|
|
}
|
|
|
|
delete panelFocusListener;
|
|
delete selectors;
|
|
|
|
delete cmdQuit;
|
|
delete cmdShutdown;
|
|
delete cmdReset;
|
|
delete cmdRestart;
|
|
delete cmdStart;
|
|
delete cmdHelp;
|
|
|
|
delete mainButtonActionListener;
|
|
|
|
delete gui_font;
|
|
delete gui_top;
|
|
}
|
|
|
|
void refresh_all_panels()
|
|
{
|
|
for (auto i = 0; categories[i].category != nullptr; ++i)
|
|
{
|
|
if (categories[i].RefreshFunc != nullptr)
|
|
(*categories[i].RefreshFunc)();
|
|
}
|
|
}
|
|
|
|
void disable_resume()
|
|
{
|
|
if (emulating)
|
|
{
|
|
cmdStart->setEnabled(false);
|
|
}
|
|
}
|
|
|
|
void run_gui()
|
|
{
|
|
#if 0
|
|
#ifdef ANDROID
|
|
SDL_ANDROID_SetScreenKeyboardShown(0);
|
|
SDL_ANDROID_SetSystemMousePointerVisible(1);
|
|
#endif
|
|
#endif
|
|
gui_running = true;
|
|
gui_rtarea_flags_onenter = gui_create_rtarea_flag(&currprefs);
|
|
|
|
expansion_generate_autoconfig_info(&changed_prefs);
|
|
|
|
try
|
|
{
|
|
amiberry_gui_init();
|
|
gui_widgets_init();
|
|
if (_tcslen(startup_message) > 0)
|
|
{
|
|
ShowMessage(startup_title, startup_message, _T(""), _T("Ok"), _T(""));
|
|
_tcscpy(startup_title, _T(""));
|
|
_tcscpy(startup_message, _T(""));
|
|
cmdStart->requestFocus();
|
|
}
|
|
amiberry_gui_run();
|
|
gui_widgets_halt();
|
|
amiberry_gui_halt();
|
|
#if 0
|
|
#ifdef ANDROID
|
|
if (currprefs.onScreen != 0)
|
|
{
|
|
SDL_ANDROID_SetScreenKeyboardShown(1);
|
|
SDL_ANDROID_SetSystemMousePointerVisible(0);
|
|
}
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
// Catch all GUI framework exceptions.
|
|
catch (gcn::Exception& e)
|
|
{
|
|
std::cout << e.getMessage() << std::endl;
|
|
uae_quit();
|
|
}
|
|
|
|
// Catch all Std exceptions.
|
|
catch (exception& e)
|
|
{
|
|
std::cout << "Std exception: " << e.what() << std::endl;
|
|
uae_quit();
|
|
}
|
|
|
|
// Catch all unknown exceptions.
|
|
catch (...)
|
|
{
|
|
std::cout << "Unknown exception" << std::endl;
|
|
uae_quit();
|
|
}
|
|
|
|
expansion_generate_autoconfig_info(&changed_prefs);
|
|
cfgfile_compatibility_romtype(&changed_prefs);
|
|
|
|
if (quit_program > UAE_QUIT || quit_program < -UAE_QUIT)
|
|
{
|
|
//--------------------------------------------------
|
|
// Prepare everything for Reset of Amiga
|
|
//--------------------------------------------------
|
|
currprefs.nr_floppies = changed_prefs.nr_floppies;
|
|
screen_is_picasso = 0;
|
|
|
|
if (gui_rtarea_flags_onenter != gui_create_rtarea_flag(&changed_prefs))
|
|
quit_program = -UAE_RESET_HARD; // Hardreset required...
|
|
}
|
|
|
|
// Reset counter for access violations
|
|
init_max_signals();
|
|
}
|