mirror of
https://github.com/LIV2/amiberry.git
synced 2025-12-05 22:22:44 +00:00
feat: merged WHDLoad panel and other improvements from preview
This commit is contained in:
parent
5913bfc5ad
commit
d0dfc4561a
@ -290,6 +290,7 @@ add_executable(${PROJECT_NAME}
|
||||
src/threaddep/threading.cpp
|
||||
src/osdep/gui/ControllerMap.cpp
|
||||
src/osdep/gui/SelectorEntry.cpp
|
||||
src/osdep/gui/ShowCustomFields.cpp
|
||||
src/osdep/gui/ShowHelp.cpp
|
||||
src/osdep/gui/ShowMessage.cpp
|
||||
src/osdep/gui/ShowDiskInfo.cpp
|
||||
@ -322,6 +323,7 @@ add_executable(${PROJECT_NAME}
|
||||
src/osdep/gui/PanelPrio.cpp
|
||||
src/osdep/gui/PanelSavestate.cpp
|
||||
src/osdep/gui/PanelVirtualKeyboard.cpp
|
||||
src/osdep/gui/PanelWHDLoad.cpp
|
||||
src/osdep/gui/main_window.cpp
|
||||
src/osdep/gui/Navigation.cpp
|
||||
src/osdep/vkbd/vkbd.cpp
|
||||
@ -387,7 +389,8 @@ target_link_options(${PROJECT_NAME} PRIVATE "LINKER:-as-needed,-no-pie")
|
||||
if (USE_OPENGL)
|
||||
add_definitions(-DUSE_OPENGL)
|
||||
find_package(OpenGL REQUIRED)
|
||||
TARGET_LINK_LIBRARIES(${PROJECT_NAME} PRIVATE ${TARGET_LINK_LIBRARIES} OpenGL::GL)
|
||||
find_package(GLEW REQUIRED)
|
||||
TARGET_LINK_LIBRARIES(${PROJECT_NAME} PRIVATE ${TARGET_LINK_LIBRARIES} GLEW OpenGL::GL)
|
||||
endif ()
|
||||
|
||||
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
|
||||
|
||||
6
Makefile
6
Makefile
@ -51,7 +51,7 @@ LDFLAGS += -Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed -lpthread -lz -lpng -lrt
|
||||
|
||||
ifdef USE_OPENGL
|
||||
CFLAGS += -DUSE_OPENGL
|
||||
LDFLAGS += -lGL
|
||||
LDFLAGS += -lGLEW -lGL
|
||||
endif
|
||||
|
||||
ifdef USE_LTO
|
||||
@ -636,6 +636,7 @@ OBJS = \
|
||||
src/threaddep/threading.o \
|
||||
src/osdep/gui/ControllerMap.o \
|
||||
src/osdep/gui/SelectorEntry.o \
|
||||
src/osdep/gui/ShowCustomFields.o \
|
||||
src/osdep/gui/ShowHelp.o \
|
||||
src/osdep/gui/ShowMessage.o \
|
||||
src/osdep/gui/ShowDiskInfo.o \
|
||||
@ -668,6 +669,7 @@ OBJS = \
|
||||
src/osdep/gui/PanelPrio.o \
|
||||
src/osdep/gui/PanelSavestate.o \
|
||||
src/osdep/gui/PanelVirtualKeyboard.o \
|
||||
src/osdep/gui/PanelWHDLoad.o \
|
||||
src/osdep/gui/main_window.o \
|
||||
src/osdep/gui/Navigation.o \
|
||||
src/osdep/vkbd/vkbd.o \
|
||||
@ -737,7 +739,7 @@ clean:
|
||||
cleanprofile:
|
||||
$(RM) $(OBJS:%.o=%.gcda)
|
||||
$(MAKE) -C external/libguisan cleanprofile
|
||||
|
||||
|
||||
guisan:
|
||||
$(MAKE) -C external/libguisan
|
||||
|
||||
|
||||
3
cmake/gcc-flags-x86_64.cmake
Normal file
3
cmake/gcc-flags-x86_64.cmake
Normal file
@ -0,0 +1,3 @@
|
||||
set(CMAKE_C_FLAGS_INIT "-march=x86-64 -msse2 -mfpmath=sse -mstackrealign")
|
||||
set(CMAKE_CXX_FLAGS_INIT "${CMAKE_C_FLAGS_INIT}")
|
||||
|
||||
12
external/libguisan/include/guisan.hpp
vendored
12
external/libguisan/include/guisan.hpp
vendored
@ -117,13 +117,13 @@ class Widget;
|
||||
|
||||
extern "C"
|
||||
{
|
||||
/**
|
||||
* Gets the the version of Guisan. As it is a C function
|
||||
/**
|
||||
* Gets the the version of Guisan. As it is a C function
|
||||
* it can be used to check for Guisan with autotools.
|
||||
*
|
||||
* @return the version of Guisan.
|
||||
*/
|
||||
GCN_CORE_DECLSPEC extern const char* gcnGuisanVersion();
|
||||
*
|
||||
* @return the version of Guisan.
|
||||
*/
|
||||
GCN_CORE_DECLSPEC extern const char* gcnGuisanVersion();
|
||||
}
|
||||
|
||||
#endif // end GCN_GUISAN_HPP
|
||||
|
||||
@ -44,7 +44,7 @@
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
<releases>
|
||||
<release version="5.6.9" date="2024-03-09"/>
|
||||
<release version="5.6.9" date="2024-03-17"/>
|
||||
<release version="5.6.8" date="2024-02-29"/>
|
||||
<release version="5.6.7" date="2024-02-14"/>
|
||||
<release version="5.6.6" date="2024-01-14"/>
|
||||
|
||||
@ -2968,18 +2968,18 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
|
||||
#ifdef AMIBERRY
|
||||
cfg_write(_T("; *** WHDLoad Booter. Options"), f);
|
||||
|
||||
cfgfile_write_str(f, _T("whdload_slave"), p->whdbootprefs.slave);
|
||||
cfgfile_write_bool(f, _T("whdload_showsplash"), p->whdbootprefs.showsplash);
|
||||
cfgfile_write_bool(f, _T("whdload_buttonwait"), p->whdbootprefs.buttonwait);
|
||||
cfgfile_dwrite(f, _T("whdload_configdelay"), _T("%d"), p->whdbootprefs.configdelay);
|
||||
cfgfile_write(f, _T("whdload_custom1"), _T("%d"), p->whdbootprefs.custom1);
|
||||
cfgfile_write(f, _T("whdload_custom2"), _T("%d"), p->whdbootprefs.custom2);
|
||||
cfgfile_write(f, _T("whdload_custom3"), _T("%d"), p->whdbootprefs.custom3);
|
||||
cfgfile_write(f, _T("whdload_custom4"), _T("%d"), p->whdbootprefs.custom4);
|
||||
cfgfile_write(f, _T("whdload_custom5"), _T("%d"), p->whdbootprefs.custom5);
|
||||
cfgfile_write_str(f, _T("whdload_custom"), p->whdbootprefs.custom);
|
||||
cfgfile_write_bool(f, _T("whdload_writecache"), p->whdbootprefs.writecache);
|
||||
cfgfile_write_bool(f, _T("whdload_quit_on_exit"), p->whdbootprefs.quit_on_exit);
|
||||
cfgfile_write_str(f, _T("whdload_slave"), whdload_prefs.selected_slave.filename.c_str());
|
||||
cfgfile_write_bool(f, _T("whdload_showsplash"), whdload_prefs.show_splash);
|
||||
cfgfile_write_bool(f, _T("whdload_buttonwait"), whdload_prefs.button_wait);
|
||||
cfgfile_dwrite(f, _T("whdload_configdelay"), _T("%d"), whdload_prefs.config_delay);
|
||||
cfgfile_write(f, _T("whdload_custom1"), _T("%d"), whdload_prefs.selected_slave.custom1.value);
|
||||
cfgfile_write(f, _T("whdload_custom2"), _T("%d"), whdload_prefs.selected_slave.custom2.value);
|
||||
cfgfile_write(f, _T("whdload_custom3"), _T("%d"), whdload_prefs.selected_slave.custom3.value);
|
||||
cfgfile_write(f, _T("whdload_custom4"), _T("%d"), whdload_prefs.selected_slave.custom4.value);
|
||||
cfgfile_write(f, _T("whdload_custom5"), _T("%d"), whdload_prefs.selected_slave.custom5.value);
|
||||
cfgfile_write_str(f, _T("whdload_custom"), whdload_prefs.custom.c_str());
|
||||
cfgfile_write_bool(f, _T("whdload_writecache"), whdload_prefs.write_cache);
|
||||
cfgfile_write_bool(f, _T("whdload_quit_on_exit"), whdload_prefs.quit_on_exit);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -3518,18 +3518,18 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value)
|
||||
}
|
||||
|
||||
/* Read in WHDLoad Options */
|
||||
if (cfgfile_string(option, value, _T("whdload_slave"), p->whdbootprefs.slave, sizeof p->whdbootprefs.slave / sizeof(TCHAR))
|
||||
|| cfgfile_string(option, value, _T("whdload_custom"), p->whdbootprefs.custom, sizeof p->whdbootprefs.custom / sizeof(TCHAR))
|
||||
|| cfgfile_intval(option, value, _T("whdload_custom1"), &p->whdbootprefs.custom1, 1)
|
||||
|| cfgfile_intval(option, value, _T("whdload_custom2"), &p->whdbootprefs.custom2, 1)
|
||||
|| cfgfile_intval(option, value, _T("whdload_custom3"), &p->whdbootprefs.custom3, 1)
|
||||
|| cfgfile_intval(option, value, _T("whdload_custom4"), &p->whdbootprefs.custom4, 1)
|
||||
|| cfgfile_intval(option, value, _T("whdload_custom5"), &p->whdbootprefs.custom5, 1)
|
||||
|| cfgfile_yesno(option, value, _T("whdload_buttonwait"), &p->whdbootprefs.buttonwait)
|
||||
|| cfgfile_yesno(option, value, _T("whdload_showsplash"), &p->whdbootprefs.showsplash)
|
||||
|| cfgfile_intval(option, value, _T("whdload_configdelay"), &p->whdbootprefs.configdelay, 1)
|
||||
|| cfgfile_yesno(option, value, _T("whdload_writecache"), &p->whdbootprefs.writecache)
|
||||
|| cfgfile_yesno(option, value, _T("whdload_quit_on_exit"), &p->whdbootprefs.quit_on_exit)
|
||||
if (cfgfile_string(option, value, _T("whdload_slave"), whdload_prefs.selected_slave.filename)
|
||||
|| cfgfile_intval(option, value, _T("whdload_custom1"), &whdload_prefs.selected_slave.custom1.value, 1)
|
||||
|| cfgfile_intval(option, value, _T("whdload_custom2"), &whdload_prefs.selected_slave.custom2.value, 1)
|
||||
|| cfgfile_intval(option, value, _T("whdload_custom3"), &whdload_prefs.selected_slave.custom3.value, 1)
|
||||
|| cfgfile_intval(option, value, _T("whdload_custom4"), &whdload_prefs.selected_slave.custom4.value, 1)
|
||||
|| cfgfile_intval(option, value, _T("whdload_custom5"), &whdload_prefs.selected_slave.custom5.value, 1)
|
||||
|| cfgfile_string(option, value, _T("whdload_custom"), whdload_prefs.custom)
|
||||
|| cfgfile_yesno(option, value, _T("whdload_buttonwait"), &whdload_prefs.button_wait)
|
||||
|| cfgfile_yesno(option, value, _T("whdload_showsplash"), &whdload_prefs.show_splash)
|
||||
|| cfgfile_intval(option, value, _T("whdload_configdelay"), &whdload_prefs.config_delay, 1)
|
||||
|| cfgfile_yesno(option, value, _T("whdload_writecache"), &whdload_prefs.write_cache)
|
||||
|| cfgfile_yesno(option, value, _T("whdload_quit_on_exit"), &whdload_prefs.quit_on_exit)
|
||||
)
|
||||
{
|
||||
return 1;
|
||||
@ -8380,7 +8380,7 @@ void default_prefs (struct uae_prefs *p, bool reset, int type)
|
||||
p->sampler_freq = 0;
|
||||
#ifdef AMIBERRY
|
||||
p->sound_volume_cd = 20;
|
||||
p->whdbootprefs.writecache = false;
|
||||
whdload_prefs.write_cache = false;
|
||||
#endif
|
||||
p->comptrustbyte = 0;
|
||||
p->comptrustword = 0;
|
||||
|
||||
@ -161,10 +161,10 @@ extern unsigned int my_read (struct my_openfile_s*, void*, unsigned int);
|
||||
extern unsigned int my_write (struct my_openfile_s*, void*, unsigned int);
|
||||
extern int my_truncate (const TCHAR *name, uae_u64 len);
|
||||
extern int dos_errno (void);
|
||||
extern int my_existslink(const char* name);
|
||||
extern int my_existsfile (const TCHAR *name);
|
||||
extern int my_existsfile2(const TCHAR* name);
|
||||
extern int my_existsdir (const TCHAR *name);
|
||||
extern bool my_existslink(const char* name);
|
||||
extern bool my_existsfile (const TCHAR *name);
|
||||
extern bool my_existsfile2(const TCHAR* name);
|
||||
extern bool my_existsdir (const TCHAR *name);
|
||||
extern FILE *my_opentext (const TCHAR*);
|
||||
|
||||
extern bool my_stat (const TCHAR *name, struct mystat *ms);
|
||||
@ -187,7 +187,7 @@ extern bool my_createshortcut(const TCHAR *source, const TCHAR *target, const TC
|
||||
#define MYVOLUMEINFO_CDFS 16
|
||||
|
||||
extern int my_getvolumeinfo (const TCHAR *root);
|
||||
extern const std::string my_get_sha1_of_file(const char* filepath);
|
||||
extern std::string my_get_sha1_of_file(const char* filepath);
|
||||
|
||||
#ifdef AMIBERRY
|
||||
char* fsdb_native_path(const char* root_dir, const char* amiga_path);
|
||||
|
||||
@ -11,6 +11,8 @@
|
||||
#define UAE_OPTIONS_H
|
||||
|
||||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
#include "uae/types.h"
|
||||
|
||||
#include "traps.h"
|
||||
@ -18,7 +20,7 @@
|
||||
|
||||
#define UAEMAJOR 5
|
||||
#define UAEMINOR 6
|
||||
#define UAESUBREV 8
|
||||
#define UAESUBREV 9
|
||||
|
||||
#define MAX_AMIGADISPLAYS 1
|
||||
|
||||
@ -533,20 +535,83 @@ struct monconfig
|
||||
};
|
||||
|
||||
#ifdef AMIBERRY
|
||||
struct whdbooter
|
||||
enum custom_type
|
||||
{
|
||||
int custom1 = 0;
|
||||
int custom2 = 0;
|
||||
int custom3 = 0;
|
||||
int custom4 = 0;
|
||||
int custom5 = 0;
|
||||
TCHAR custom[256]{};
|
||||
bool buttonwait{};
|
||||
TCHAR slave[4096]{};
|
||||
bool showsplash{};
|
||||
int configdelay = 0;
|
||||
bool writecache{};
|
||||
bool quit_on_exit{};
|
||||
none,
|
||||
bool_type,
|
||||
bit_type,
|
||||
list_type
|
||||
};
|
||||
struct whdload_custom
|
||||
{
|
||||
/**
|
||||
* \brief The value of this custom field. This will be sent to WHDLoad
|
||||
*/
|
||||
int value;
|
||||
/**
|
||||
* \brief The type of the custom field: None, Boolean, Bit or List
|
||||
*/
|
||||
custom_type type;
|
||||
/**
|
||||
* \brief Caption for this custom field function. Used in the label which describes what this option does
|
||||
*/
|
||||
std::string caption;
|
||||
/**
|
||||
* \brief The list of labels to show in the dropdown. Used in List type custom fields
|
||||
*/
|
||||
std::vector<std::string> labels;
|
||||
/**
|
||||
* \brief When the type is a Bit, it can contain multiple entries for the same custom field.
|
||||
* Each entry has it's own label and a different value that goes with it.
|
||||
*/
|
||||
std::vector<std::pair<std::string, int>> label_bit_pairs;
|
||||
};
|
||||
struct whdload_slave
|
||||
{
|
||||
std::string filename;
|
||||
std::string data_path;
|
||||
whdload_custom custom1;
|
||||
whdload_custom custom2;
|
||||
whdload_custom custom3;
|
||||
whdload_custom custom4;
|
||||
whdload_custom custom5;
|
||||
|
||||
whdload_custom& get_custom(const int index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 1:
|
||||
return custom1;
|
||||
case 2:
|
||||
return custom2;
|
||||
case 3:
|
||||
return custom3;
|
||||
case 4:
|
||||
return custom4;
|
||||
case 5:
|
||||
return custom5;
|
||||
default:
|
||||
return custom1;
|
||||
}
|
||||
}
|
||||
};
|
||||
struct whdload_options
|
||||
{
|
||||
std::string filename;
|
||||
std::string game_name;
|
||||
std::string sub_path;
|
||||
std::string variant_uuid;
|
||||
int slave_count;
|
||||
std::string slave_default;
|
||||
bool slave_libraries;
|
||||
std::vector<whdload_slave> slaves;
|
||||
whdload_slave selected_slave;
|
||||
std::string custom;
|
||||
bool button_wait;
|
||||
bool show_splash;
|
||||
int config_delay;
|
||||
bool write_cache;
|
||||
bool quit_on_exit;
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -1032,11 +1097,12 @@ struct uae_prefs
|
||||
bool use_retroarch_statebuttons;
|
||||
bool use_retroarch_vkbd;
|
||||
|
||||
struct whdbooter whdbootprefs;
|
||||
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
extern whdload_options whdload_prefs;
|
||||
|
||||
extern int config_changed, config_changed_flags;
|
||||
extern void config_check_vsync(void);
|
||||
extern void set_config_changed(int flags = 0);
|
||||
@ -1143,7 +1209,7 @@ extern bool cfgfile_createconfigstore(struct uae_prefs* p);
|
||||
extern void cfgfile_get_shader_config(struct uae_prefs* p, int rtg);
|
||||
|
||||
#ifdef AMIBERRY
|
||||
extern void whdload_auto_prefs(struct uae_prefs* prefs, char* filepath);
|
||||
extern void whdload_auto_prefs(struct uae_prefs* prefs, const char* filepath);
|
||||
extern void cd_auto_prefs(struct uae_prefs* prefs, char* filepath);
|
||||
extern void symlink_roms(struct uae_prefs* prefs);
|
||||
extern void drawbridge_update_profiles(struct uae_prefs* prefs);
|
||||
|
||||
@ -74,7 +74,7 @@
|
||||
#include "fsdb_host.h"
|
||||
#include "keyboard.h"
|
||||
|
||||
static const char __ver[40] = "$VER: Amiberry 5.6.9 (2024-3-09)";
|
||||
static const char __ver[40] = "$VER: Amiberry 5.6.9 (2024-03-17)";
|
||||
long int version = 256 * 65536L * UAEMAJOR + 65536L * UAEMINOR + UAESUBREV;
|
||||
|
||||
struct uae_prefs currprefs, changed_prefs;
|
||||
|
||||
@ -110,6 +110,7 @@ bool host_poweroff = false;
|
||||
int relativepaths = 0;
|
||||
int saveimageoriginalpath = 0;
|
||||
|
||||
struct whdload_options whdload_prefs = {};
|
||||
struct amiberry_options amiberry_options = {};
|
||||
struct amiberry_gui_theme gui_theme = {};
|
||||
amiberry_hotkey enter_gui_key;
|
||||
@ -1502,6 +1503,9 @@ void process_event(SDL_Event event)
|
||||
|
||||
case SDL_MOUSEMOTION:
|
||||
{
|
||||
if (event.window.windowID != SDL_GetWindowID(mon->sdl_window))
|
||||
return;
|
||||
|
||||
// This will be useful when/if SDL2 supports more than 1 mouse.
|
||||
// Currently, it always returns 0.
|
||||
auto wm = event.motion.which;
|
||||
@ -2211,11 +2215,11 @@ void target_default_options(struct uae_prefs* p, int type)
|
||||
p->use_retroarch_reset = amiberry_options.default_retroarch_reset;
|
||||
p->use_retroarch_vkbd = amiberry_options.default_retroarch_vkbd;
|
||||
|
||||
p->whdbootprefs.buttonwait = amiberry_options.default_whd_buttonwait;
|
||||
p->whdbootprefs.showsplash = amiberry_options.default_whd_showsplash;
|
||||
p->whdbootprefs.configdelay = amiberry_options.default_whd_configdelay;
|
||||
p->whdbootprefs.writecache = amiberry_options.default_whd_writecache;
|
||||
p->whdbootprefs.quit_on_exit = amiberry_options.default_whd_quit_on_exit;
|
||||
whdload_prefs.button_wait = amiberry_options.default_whd_buttonwait;
|
||||
whdload_prefs.show_splash = amiberry_options.default_whd_showsplash;
|
||||
whdload_prefs.config_delay = amiberry_options.default_whd_configdelay;
|
||||
whdload_prefs.write_cache = amiberry_options.default_whd_writecache;
|
||||
whdload_prefs.quit_on_exit = amiberry_options.default_whd_quit_on_exit;
|
||||
|
||||
if (amiberry_options.default_soundcard > 0) p->soundcard = amiberry_options.default_soundcard;
|
||||
|
||||
@ -2975,7 +2979,7 @@ int target_cfgfile_load(struct uae_prefs* p, const char* filename, int type, int
|
||||
p->floppyslots[i].df[0] = 0;
|
||||
disk_insert(i, p->floppyslots[i].df);
|
||||
if (strlen(p->floppyslots[i].df) > 0)
|
||||
AddFileToDiskList(p->floppyslots[i].df, 1);
|
||||
add_file_to_mru_list(lstMRUDiskList, std::string(p->floppyslots[i].df));
|
||||
}
|
||||
|
||||
if (!isdefault)
|
||||
@ -3023,6 +3027,12 @@ void extract_filename(const char* str, char* buffer)
|
||||
strncpy(buffer, p, MAX_DPATH - 1);
|
||||
}
|
||||
|
||||
std::string extract_filename(const std::string& path)
|
||||
{
|
||||
const std::filesystem::path file_path(path);
|
||||
return file_path.filename().string();
|
||||
}
|
||||
|
||||
void extract_path(char* str, char* buffer)
|
||||
{
|
||||
strncpy(buffer, str, MAX_DPATH - 1);
|
||||
@ -3051,7 +3061,7 @@ void remove_file_extension(char* filename)
|
||||
|
||||
std::string remove_file_extension(const std::string& filename)
|
||||
{
|
||||
const size_t last_dot = filename.find_last_of(".");
|
||||
const size_t last_dot = filename.find_last_of('.');
|
||||
if (last_dot == std::string::npos) {
|
||||
// No extension found, return the original filename
|
||||
return filename;
|
||||
@ -3059,50 +3069,43 @@ std::string remove_file_extension(const std::string& filename)
|
||||
return filename.substr(0, last_dot);
|
||||
}
|
||||
|
||||
void read_directory(const std::string path, std::vector<std::string>* dirs, std::vector<std::string>* files)
|
||||
void read_directory(const std::string& path, std::vector<std::string>* dirs, std::vector<std::string>* files)
|
||||
{
|
||||
struct dirent* dent;
|
||||
|
||||
if (dirs != nullptr)
|
||||
dirs->clear();
|
||||
if (files != nullptr)
|
||||
files->clear();
|
||||
|
||||
auto* const dir = opendir(path.c_str());
|
||||
if (dir != nullptr)
|
||||
// check if the path exists first
|
||||
if (!std::filesystem::exists(path))
|
||||
return;
|
||||
for (const auto& entry : std::filesystem::directory_iterator(path))
|
||||
{
|
||||
while ((dent = readdir(dir)) != nullptr)
|
||||
if (entry.is_directory())
|
||||
{
|
||||
if (dent->d_type == DT_DIR)
|
||||
{
|
||||
if (dirs != nullptr
|
||||
&& (dent->d_name[0] != '.' || (dent->d_name[0] == '.' && dent->d_name[1] == '.')))
|
||||
dirs->emplace_back(dent->d_name);
|
||||
}
|
||||
else if (dent->d_type == DT_LNK)
|
||||
{
|
||||
struct stat stbuf{};
|
||||
stat(dent->d_name, &stbuf);
|
||||
if (S_ISDIR(stbuf.st_mode))
|
||||
{
|
||||
if (dirs != nullptr
|
||||
&& (dent->d_name[0] != '.' || (dent->d_name[0] == '.' && dent->d_name[1] == '.')))
|
||||
dirs->emplace_back(dent->d_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (files != nullptr && dent->d_name[0] != '.')
|
||||
files->emplace_back(dent->d_name);
|
||||
}
|
||||
}
|
||||
else if (files != nullptr && dent->d_name[0] != '.')
|
||||
files->emplace_back(dent->d_name);
|
||||
if (dirs != nullptr && (entry.path().filename().string()[0] != '.' || (entry.path().filename().string()[0] == '.' && entry.path().filename().string()[1] == '.')))
|
||||
dirs->emplace_back(entry.path().filename().string());
|
||||
}
|
||||
if (dirs != nullptr && !dirs->empty() && (*dirs)[0] == ".")
|
||||
dirs->erase(dirs->begin());
|
||||
closedir(dir);
|
||||
else if (entry.is_symlink())
|
||||
{
|
||||
if (std::filesystem::is_directory(entry))
|
||||
{
|
||||
if (dirs != nullptr && (entry.path().filename().string()[0] != '.' || (entry.path().filename().string()[0] == '.' && entry.path().filename().string()[1] == '.')))
|
||||
dirs->emplace_back(entry.path().filename().string());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (files != nullptr && entry.path().filename().string()[0] != '.')
|
||||
files->emplace_back(entry.path().filename().string());
|
||||
}
|
||||
}
|
||||
else if (files != nullptr && entry.path().filename().string()[0] != '.')
|
||||
files->emplace_back(entry.path().filename().string());
|
||||
}
|
||||
|
||||
if (dirs != nullptr && !dirs->empty() && (*dirs)[0] == ".")
|
||||
dirs->erase(dirs->begin());
|
||||
|
||||
if (dirs != nullptr)
|
||||
sort(dirs->begin(), dirs->end());
|
||||
if (files != nullptr)
|
||||
@ -3117,300 +3120,222 @@ void save_amiberry_settings(void)
|
||||
|
||||
char buffer[MAX_DPATH];
|
||||
|
||||
auto write_bool_option = [&](const char* name, bool value) {
|
||||
snprintf(buffer, MAX_DPATH, "%s=%s\n", name, value ? "yes" : "no");
|
||||
fputs(buffer, f);
|
||||
};
|
||||
|
||||
auto write_int_option = [&](const char* name, int value) {
|
||||
snprintf(buffer, MAX_DPATH, "%s=%d\n", name, value);
|
||||
fputs(buffer, f);
|
||||
};
|
||||
|
||||
auto write_string_option = [&](const char* name, const std::string& value) {
|
||||
snprintf(buffer, MAX_DPATH, "%s=%s\n", name, value.c_str());
|
||||
fputs(buffer, f);
|
||||
};
|
||||
|
||||
// Should the Quickstart Panel be the default when opening the GUI?
|
||||
snprintf(buffer, MAX_DPATH, "Quickstart=%d\n", amiberry_options.quickstart_start);
|
||||
fputs(buffer, f);
|
||||
write_int_option("Quickstart", amiberry_options.quickstart_start);
|
||||
|
||||
// Open each config file and read the Description field?
|
||||
// This will slow down scanning the config list if it's very large
|
||||
snprintf(buffer, MAX_DPATH, "read_config_descriptions=%s\n", amiberry_options.read_config_descriptions ? "yes" : "no");
|
||||
fputs(buffer, f);
|
||||
write_bool_option("read_config_descriptions", amiberry_options.read_config_descriptions);
|
||||
|
||||
// Write to logfile?
|
||||
// If enabled, a file named "amiberry_log.txt" will be generated in the startup folder
|
||||
snprintf(buffer, MAX_DPATH, "write_logfile=%s\n", amiberry_options.write_logfile ? "yes" : "no");
|
||||
fputs(buffer, f);
|
||||
write_bool_option("write_logfile", amiberry_options.write_logfile);
|
||||
|
||||
// Scanlines ON by default?
|
||||
// This will only be enabled if the vertical height is enough, as we need Line Doubling set to ON also
|
||||
// Beware this comes with a performance hit, as double the amount of lines need to be drawn on-screen
|
||||
snprintf(buffer, MAX_DPATH, "default_line_mode=%d\n", amiberry_options.default_line_mode);
|
||||
fputs(buffer, f);
|
||||
write_int_option("default_line_mode", amiberry_options.default_line_mode);
|
||||
|
||||
// Map RCtrl key to RAmiga key?
|
||||
// This helps with keyboards that may not have 2 Win keys and no Menu key either
|
||||
snprintf(buffer, MAX_DPATH, "rctrl_as_ramiga=%s\n", amiberry_options.rctrl_as_ramiga ? "yes" : "no");
|
||||
fputs(buffer, f);
|
||||
write_bool_option("rctrl_as_ramiga", amiberry_options.rctrl_as_ramiga);
|
||||
|
||||
// Disable controller in the GUI?
|
||||
// If you want to disable the default behavior for some reason
|
||||
snprintf(buffer, MAX_DPATH, "gui_joystick_control=%s\n", amiberry_options.gui_joystick_control ? "yes" : "no");
|
||||
fputs(buffer, f);
|
||||
write_bool_option("gui_joystick_control", amiberry_options.gui_joystick_control);
|
||||
|
||||
// Use a separate thread for drawing native chipset output
|
||||
// This helps with performance, but may cause glitches in some cases
|
||||
snprintf(buffer, MAX_DPATH, "default_multithreaded_drawing=%s\n", amiberry_options.default_multithreaded_drawing ? "yes" : "no");
|
||||
fputs(buffer, f);
|
||||
write_bool_option("default_multithreaded_drawing", amiberry_options.default_multithreaded_drawing);
|
||||
|
||||
// Default mouse input speed
|
||||
snprintf(buffer, MAX_DPATH, "input_default_mouse_speed=%d\n", amiberry_options.input_default_mouse_speed);
|
||||
fputs(buffer, f);
|
||||
write_int_option("input_default_mouse_speed", amiberry_options.input_default_mouse_speed);
|
||||
|
||||
// When using Keyboard as Joystick, stop any double keypresses
|
||||
snprintf(buffer, MAX_DPATH, "input_keyboard_as_joystick_stop_keypresses=%s\n", amiberry_options.input_keyboard_as_joystick_stop_keypresses ? "yes" : "no");
|
||||
fputs(buffer, f);
|
||||
write_bool_option("input_keyboard_as_joystick_stop_keypresses", amiberry_options.input_keyboard_as_joystick_stop_keypresses);
|
||||
|
||||
// Default key for opening the GUI (e.g. "F12")
|
||||
snprintf(buffer, MAX_DPATH, "default_open_gui_key=%s\n", amiberry_options.default_open_gui_key);
|
||||
fputs(buffer, f);
|
||||
write_string_option("default_open_gui_key", amiberry_options.default_open_gui_key);
|
||||
|
||||
// Default key for Quitting the emulator
|
||||
snprintf(buffer, MAX_DPATH, "default_quit_key=%s\n", amiberry_options.default_quit_key);
|
||||
fputs(buffer, f);
|
||||
write_string_option("default_quit_key", amiberry_options.default_quit_key);
|
||||
|
||||
// Default key for opening Action Replay
|
||||
snprintf(buffer, MAX_DPATH, "default_ar_key=%s\n", amiberry_options.default_ar_key);
|
||||
fputs(buffer, f);
|
||||
write_string_option("default_ar_key", amiberry_options.default_ar_key);
|
||||
|
||||
// Default key for Fullscreen Toggle
|
||||
snprintf(buffer, MAX_DPATH, "default_fullscreen_toggle_key=%s\n", amiberry_options.default_fullscreen_toggle_key);
|
||||
fputs(buffer, f);
|
||||
write_string_option("default_fullscreen_toggle_key", amiberry_options.default_fullscreen_toggle_key);
|
||||
|
||||
// Rotation angle of the output display (useful for screens with portrait orientation, like the Go Advance)
|
||||
snprintf(buffer, MAX_DPATH, "rotation_angle=%d\n", amiberry_options.rotation_angle);
|
||||
fputs(buffer, f);
|
||||
|
||||
write_int_option("rotation_angle", amiberry_options.rotation_angle);
|
||||
|
||||
// Enable Horizontal Centering by default?
|
||||
snprintf(buffer, MAX_DPATH, "default_horizontal_centering=%s\n", amiberry_options.default_horizontal_centering ? "yes" : "no");
|
||||
fputs(buffer, f);
|
||||
write_bool_option("default_horizontal_centering", amiberry_options.default_horizontal_centering);
|
||||
|
||||
// Enable Vertical Centering by default?
|
||||
snprintf(buffer, MAX_DPATH, "default_vertical_centering=%s\n", amiberry_options.default_vertical_centering ? "yes" : "no");
|
||||
fputs(buffer, f);
|
||||
write_bool_option("default_vertical_centering", amiberry_options.default_vertical_centering);
|
||||
|
||||
// Scaling method to use by default?
|
||||
// Valid options are: -1 Auto, 0 Nearest Neighbor, 1 Linear
|
||||
snprintf(buffer, MAX_DPATH, "default_scaling_method=%d\n", amiberry_options.default_scaling_method);
|
||||
fputs(buffer, f);
|
||||
write_int_option("default_scaling_method", amiberry_options.default_scaling_method);
|
||||
|
||||
// Enable frameskip by default?
|
||||
snprintf(buffer, MAX_DPATH, "default_frameskip=%s\n", amiberry_options.default_frameskip ? "yes" : "no");
|
||||
fputs(buffer, f);
|
||||
write_bool_option("default_frameskip", amiberry_options.default_frameskip);
|
||||
|
||||
// Correct Aspect Ratio by default?
|
||||
snprintf(buffer, MAX_DPATH, "default_correct_aspect_ratio=%s\n", amiberry_options.default_correct_aspect_ratio ? "yes" : "no");
|
||||
fputs(buffer, f);
|
||||
write_bool_option("default_correct_aspect_ratio", amiberry_options.default_correct_aspect_ratio);
|
||||
|
||||
// Enable Auto-Height by default?
|
||||
snprintf(buffer, MAX_DPATH, "default_auto_crop=%s\n", amiberry_options.default_auto_crop ? "yes" : "no");
|
||||
fputs(buffer, f);
|
||||
// Enable Auto-Crop by default?
|
||||
write_bool_option("default_auto_crop", amiberry_options.default_auto_crop);
|
||||
|
||||
// Default Screen Width
|
||||
snprintf(buffer, MAX_DPATH, "default_width=%d\n", amiberry_options.default_width);
|
||||
fputs(buffer, f);
|
||||
write_int_option("default_width", amiberry_options.default_width);
|
||||
|
||||
// Default Screen Height
|
||||
snprintf(buffer, MAX_DPATH, "default_height=%d\n", amiberry_options.default_height);
|
||||
fputs(buffer, f);
|
||||
write_int_option("default_height", amiberry_options.default_height);
|
||||
|
||||
// Full screen mode (0, 1, 2)
|
||||
snprintf(buffer, MAX_DPATH, "default_fullscreen_mode=%d\n", amiberry_options.default_fullscreen_mode);
|
||||
fputs(buffer, f);
|
||||
write_int_option("default_fullscreen_mode", amiberry_options.default_fullscreen_mode);
|
||||
|
||||
// Default Stereo Separation
|
||||
snprintf(buffer, MAX_DPATH, "default_stereo_separation=%d\n", amiberry_options.default_stereo_separation);
|
||||
fputs(buffer, f);
|
||||
write_int_option("default_stereo_separation", amiberry_options.default_stereo_separation);
|
||||
|
||||
// Default Sound buffer size
|
||||
snprintf(buffer, MAX_DPATH, "default_sound_buffer=%d\n", amiberry_options.default_sound_buffer);
|
||||
fputs(buffer, f);
|
||||
write_int_option("default_sound_buffer", amiberry_options.default_sound_buffer);
|
||||
|
||||
// Default Sound Mode (Pull/Push)
|
||||
snprintf(buffer, MAX_DPATH, "default_sound_pull=%s\n", amiberry_options.default_sound_pull ? "yes" : "no");
|
||||
fputs(buffer, f);
|
||||
write_bool_option("default_sound_pull", amiberry_options.default_sound_pull);
|
||||
|
||||
// Default Joystick Deadzone
|
||||
snprintf(buffer, MAX_DPATH, "default_joystick_deadzone=%d\n", amiberry_options.default_joystick_deadzone);
|
||||
fputs(buffer, f);
|
||||
write_int_option("default_joystick_deadzone", amiberry_options.default_joystick_deadzone);
|
||||
|
||||
// Enable RetroArch Quit by default?
|
||||
snprintf(buffer, MAX_DPATH, "default_retroarch_quit=%s\n", amiberry_options.default_retroarch_quit ? "yes" : "no");
|
||||
fputs(buffer, f);
|
||||
write_bool_option("default_retroarch_quit", amiberry_options.default_retroarch_quit);
|
||||
|
||||
// Enable RetroArch Menu by default?
|
||||
snprintf(buffer, MAX_DPATH, "default_retroarch_menu=%s\n", amiberry_options.default_retroarch_menu ? "yes" : "no");
|
||||
fputs(buffer, f);
|
||||
write_bool_option("default_retroarch_menu", amiberry_options.default_retroarch_menu);
|
||||
|
||||
// Enable RetroArch Reset by default?
|
||||
snprintf(buffer, MAX_DPATH, "default_retroarch_reset=%s\n", amiberry_options.default_retroarch_reset ? "yes" : "no");
|
||||
fputs(buffer, f);
|
||||
write_bool_option("default_retroarch_reset", amiberry_options.default_retroarch_reset);
|
||||
|
||||
// Enable RetroArch Reset by default?
|
||||
snprintf(buffer, MAX_DPATH, "default_retroarch_vkbd=%s\n", amiberry_options.default_retroarch_vkbd ? "yes" : "no");
|
||||
fputs(buffer, f);
|
||||
// Enable RetroArch VKBD by default?
|
||||
write_bool_option("default_retroarch_vkbd", amiberry_options.default_retroarch_vkbd);
|
||||
|
||||
// Controller1
|
||||
snprintf(buffer, MAX_DPATH, "default_controller1=%s\n", amiberry_options.default_controller1);
|
||||
fputs(buffer, f);
|
||||
write_string_option("default_controller1", amiberry_options.default_controller1);
|
||||
|
||||
// Controller2
|
||||
snprintf(buffer, MAX_DPATH, "default_controller2=%s\n", amiberry_options.default_controller2);
|
||||
fputs(buffer, f);
|
||||
write_string_option("default_controller2", amiberry_options.default_controller2);
|
||||
|
||||
// Controller3
|
||||
snprintf(buffer, MAX_DPATH, "default_controller3=%s\n", amiberry_options.default_controller3);
|
||||
fputs(buffer, f);
|
||||
write_string_option("default_controller3", amiberry_options.default_controller3);
|
||||
|
||||
// Controller4
|
||||
snprintf(buffer, MAX_DPATH, "default_controller4=%s\n", amiberry_options.default_controller4);
|
||||
fputs(buffer, f);
|
||||
write_string_option("default_controller4", amiberry_options.default_controller4);
|
||||
|
||||
// Mouse1
|
||||
snprintf(buffer, MAX_DPATH, "default_mouse1=%s\n", amiberry_options.default_mouse1);
|
||||
fputs(buffer, f);
|
||||
write_string_option("default_mouse1", amiberry_options.default_mouse1);
|
||||
|
||||
// Mouse2
|
||||
snprintf(buffer, MAX_DPATH, "default_mouse2=%s\n", amiberry_options.default_mouse2);
|
||||
fputs(buffer, f);
|
||||
write_string_option("default_mouse2", amiberry_options.default_mouse2);
|
||||
|
||||
// WHDLoad ButtonWait
|
||||
snprintf(buffer, MAX_DPATH, "default_whd_buttonwait=%s\n", amiberry_options.default_whd_buttonwait ? "yes" : "no");
|
||||
fputs(buffer, f);
|
||||
write_bool_option("default_whd_buttonwait", amiberry_options.default_whd_buttonwait);
|
||||
|
||||
// WHDLoad Show Splash screen
|
||||
snprintf(buffer, MAX_DPATH, "default_whd_showsplash=%s\n", amiberry_options.default_whd_showsplash ? "yes" : "no");
|
||||
fputs(buffer, f);
|
||||
write_bool_option("default_whd_showsplash", amiberry_options.default_whd_showsplash);
|
||||
|
||||
// WHDLoad Config Delay
|
||||
snprintf(buffer, MAX_DPATH, "default_whd_configdelay=%d\n", amiberry_options.default_whd_configdelay);
|
||||
fputs(buffer, f);
|
||||
write_int_option("default_whd_configdelay", amiberry_options.default_whd_configdelay);
|
||||
|
||||
// WHDLoad WriteCache
|
||||
snprintf(buffer, MAX_DPATH, "default_whd_writecache=%s\n", amiberry_options.default_whd_writecache ? "yes" : "no");
|
||||
fputs(buffer, f);
|
||||
write_bool_option("default_whd_writecache", amiberry_options.default_whd_writecache);
|
||||
|
||||
// WHDLoad Quit emulator after game exits
|
||||
snprintf(buffer, MAX_DPATH, "default_whd_quit_on_exit=%s\n", amiberry_options.default_whd_quit_on_exit ? "yes" : "no");
|
||||
fputs(buffer, f);
|
||||
write_bool_option("default_whd_quit_on_exit", amiberry_options.default_whd_quit_on_exit);
|
||||
|
||||
// Disable Shutdown button in GUI
|
||||
snprintf(buffer, MAX_DPATH, "disable_shutdown_button=%s\n", amiberry_options.disable_shutdown_button ? "yes" : "no");
|
||||
fputs(buffer, f);
|
||||
write_bool_option("disable_shutdown_button", amiberry_options.disable_shutdown_button);
|
||||
|
||||
// Allow Display settings to be used from the WHDLoad XML (override amiberry.conf defaults)
|
||||
snprintf(buffer, MAX_DPATH, "allow_display_settings_from_xml=%s\n", amiberry_options.allow_display_settings_from_xml ? "yes" : "no");
|
||||
fputs(buffer, f);
|
||||
write_bool_option("allow_display_settings_from_xml", amiberry_options.allow_display_settings_from_xml);
|
||||
|
||||
// Default Sound Card (0=default, first one available in the system)
|
||||
snprintf(buffer, MAX_DPATH, "default_soundcard=%d\n", amiberry_options.default_soundcard);
|
||||
fputs(buffer, f);
|
||||
|
||||
write_int_option("default_soundcard", amiberry_options.default_soundcard);
|
||||
|
||||
// Enable Virtual Keyboard by default
|
||||
snprintf(buffer, MAX_DPATH, "default_vkbd_enabled=%s\n", amiberry_options.default_vkbd_enabled ? "yes" : "no");
|
||||
fputs(buffer, f);
|
||||
write_bool_option("default_vkbd_enabled", amiberry_options.default_vkbd_enabled);
|
||||
|
||||
// Show the High-res version of the Virtual Keyboard by default
|
||||
snprintf(buffer, MAX_DPATH, "default_vkbd_hires=%s\n", amiberry_options.default_vkbd_hires ? "yes" : "no");
|
||||
fputs(buffer, f);
|
||||
write_bool_option("default_vkbd_hires", amiberry_options.default_vkbd_hires);
|
||||
|
||||
// Enable Quit functionality through Virtual Keyboard by default
|
||||
snprintf(buffer, MAX_DPATH, "default_vkbd_exit=%s\n", amiberry_options.default_vkbd_exit ? "yes" : "no");
|
||||
fputs(buffer, f);
|
||||
write_bool_option("default_vkbd_exit", amiberry_options.default_vkbd_exit);
|
||||
|
||||
// Default Language for the Virtual Keyboard
|
||||
snprintf(buffer, MAX_DPATH, "default_vkbd_language=%s\n", amiberry_options.default_vkbd_language);
|
||||
fputs(buffer, f);
|
||||
write_string_option("default_vkbd_language", amiberry_options.default_vkbd_language);
|
||||
|
||||
// Default Style for the Virtual Keyboard
|
||||
snprintf(buffer, MAX_DPATH, "default_vkbd_style=%s\n", amiberry_options.default_vkbd_style);
|
||||
fputs(buffer, f);
|
||||
write_string_option("default_vkbd_style", amiberry_options.default_vkbd_style);
|
||||
|
||||
// Default transparency for the Virtual Keyboard
|
||||
snprintf(buffer, MAX_DPATH, "default_vkbd_transparency=%d\n", amiberry_options.default_vkbd_transparency);
|
||||
fputs(buffer, f);
|
||||
write_int_option("default_vkbd_transparency", amiberry_options.default_vkbd_transparency);
|
||||
|
||||
// Default controller button for toggling the Virtual Keyboard
|
||||
snprintf(buffer, MAX_DPATH, "default_vkbd_toggle=%s\n", amiberry_options.default_vkbd_toggle);
|
||||
fputs(buffer, f);
|
||||
write_string_option("default_vkbd_toggle", amiberry_options.default_vkbd_toggle);
|
||||
|
||||
// GUI Theme: Font name
|
||||
snprintf(buffer, MAX_DPATH, "gui_theme_font_name=%s\n", amiberry_options.gui_theme_font_name);
|
||||
fputs(buffer, f);
|
||||
write_string_option("gui_theme_font_name", amiberry_options.gui_theme_font_name);
|
||||
|
||||
// GUI Theme: Font size
|
||||
snprintf(buffer, MAX_DPATH, "gui_theme_font_size=%d\n", amiberry_options.gui_theme_font_size);
|
||||
fputs(buffer, f);
|
||||
write_int_option("gui_theme_font_size", amiberry_options.gui_theme_font_size);
|
||||
|
||||
// GUI Theme: Base color
|
||||
snprintf(buffer, MAX_DPATH, "gui_theme_base_color=%s\n", amiberry_options.gui_theme_base_color);
|
||||
fputs(buffer, f);
|
||||
write_string_option("gui_theme_base_color", amiberry_options.gui_theme_base_color);
|
||||
|
||||
// GUI Theme: Selector Inactive color
|
||||
snprintf(buffer, MAX_DPATH, "gui_theme_selector_inactive=%s\n", amiberry_options.gui_theme_selector_inactive);
|
||||
fputs(buffer, f);
|
||||
write_string_option("gui_theme_selector_inactive", amiberry_options.gui_theme_selector_inactive);
|
||||
|
||||
// GUI Theme: Selector Active color
|
||||
snprintf(buffer, MAX_DPATH, "gui_theme_selector_active=%s\n", amiberry_options.gui_theme_selector_active);
|
||||
fputs(buffer, f);
|
||||
write_string_option("gui_theme_selector_active", amiberry_options.gui_theme_selector_active);
|
||||
|
||||
// GUI Theme: Textbox Background color
|
||||
snprintf(buffer, MAX_DPATH, "gui_theme_textbox_background=%s\n", amiberry_options.gui_theme_textbox_background);
|
||||
fputs(buffer, f);
|
||||
write_string_option("gui_theme_textbox_background", amiberry_options.gui_theme_textbox_background);
|
||||
|
||||
// Paths
|
||||
snprintf(buffer, MAX_DPATH, "path=%s\n", current_dir.c_str());
|
||||
fputs(buffer, f);
|
||||
|
||||
snprintf(buffer, MAX_DPATH, "config_path=%s\n", config_path.c_str());
|
||||
fputs(buffer, f);
|
||||
|
||||
snprintf(buffer, MAX_DPATH, "controllers_path=%s\n", controllers_path.c_str());
|
||||
fputs(buffer, f);
|
||||
|
||||
snprintf(buffer, MAX_DPATH, "retroarch_config=%s\n", retroarch_file.c_str());
|
||||
fputs(buffer, f);
|
||||
|
||||
snprintf(buffer, MAX_DPATH, "whdboot_path=%s\n", whdboot_path.c_str());
|
||||
fputs(buffer, f);
|
||||
|
||||
snprintf(buffer, MAX_DPATH, "whdload_arch_path=%s\n", whdload_arch_path.c_str());
|
||||
fputs(buffer, f);
|
||||
|
||||
snprintf(buffer, MAX_DPATH, "logfile_path=%s\n", logfile_path.c_str());
|
||||
fputs(buffer, f);
|
||||
|
||||
snprintf(buffer, MAX_DPATH, "rom_path=%s\n", rom_path.c_str());
|
||||
fputs(buffer, f);
|
||||
|
||||
snprintf(buffer, MAX_DPATH, "rp9_path=%s\n", rp9_path.c_str());
|
||||
fputs(buffer, f);
|
||||
|
||||
snprintf(buffer, MAX_DPATH, "floppy_sounds_dir=%s\n", floppy_sounds_dir.c_str());
|
||||
fputs(buffer, f);
|
||||
|
||||
snprintf(buffer, MAX_DPATH, "data_dir=%s\n", data_dir.c_str());
|
||||
fputs(buffer, f);
|
||||
|
||||
snprintf(buffer, MAX_DPATH, "saveimage_dir=%s\n", saveimage_dir.c_str());
|
||||
fputs(buffer, f);
|
||||
|
||||
snprintf(buffer, MAX_DPATH, "savestate_dir=%s\n", savestate_dir.c_str());
|
||||
fputs(buffer, f);
|
||||
|
||||
snprintf(buffer, MAX_DPATH, "ripper_dir=%s\n", ripper_path.c_str());
|
||||
fputs(buffer, f);
|
||||
|
||||
snprintf(buffer, MAX_DPATH, "inputrecordings_dir=%s\n", input_dir.c_str());
|
||||
fputs(buffer, f);
|
||||
|
||||
snprintf(buffer, MAX_DPATH, "screenshot_dir=%s\n", screenshot_dir.c_str());
|
||||
fputs(buffer, f);
|
||||
|
||||
snprintf(buffer, MAX_DPATH, "nvram_dir=%s\n", nvram_dir.c_str());
|
||||
fputs(buffer, f);
|
||||
|
||||
snprintf(buffer, MAX_DPATH, "video_dir=%s\n", video_dir.c_str());
|
||||
fputs(buffer, f);
|
||||
write_string_option("path", current_dir);
|
||||
write_string_option("config_path", config_path);
|
||||
write_string_option("controllers_path", controllers_path);
|
||||
write_string_option("retroarch_config", retroarch_file);
|
||||
write_string_option("whdboot_path", whdboot_path);
|
||||
write_string_option("whdload_arch_path", whdload_arch_path);
|
||||
write_string_option("logfile_path", logfile_path);
|
||||
write_string_option("rom_path", rom_path);
|
||||
write_string_option("rp9_path", rp9_path);
|
||||
write_string_option("floppy_sounds_dir", floppy_sounds_dir);
|
||||
write_string_option("data_dir", data_dir);
|
||||
write_string_option("saveimage_dir", saveimage_dir);
|
||||
write_string_option("savestate_dir", savestate_dir);
|
||||
write_string_option("screenshot_dir", screenshot_dir);
|
||||
write_string_option("ripper_path", ripper_path);
|
||||
write_string_option("inputrecordings_dir", input_dir);
|
||||
write_string_option("nvram_dir", nvram_dir);
|
||||
write_string_option("video_dir", video_dir);
|
||||
|
||||
// The number of ROMs in the last scan
|
||||
snprintf(buffer, MAX_DPATH, "ROMs=%zu\n", lstAvailableROMs.size());
|
||||
@ -3419,12 +3344,9 @@ void save_amiberry_settings(void)
|
||||
// The ROMs found in the last scan
|
||||
for (auto& lstAvailableROM : lstAvailableROMs)
|
||||
{
|
||||
snprintf(buffer, MAX_DPATH, "ROMName=%s\n", lstAvailableROM->Name);
|
||||
fputs(buffer, f);
|
||||
snprintf(buffer, MAX_DPATH, "ROMPath=%s\n", lstAvailableROM->Path);
|
||||
fputs(buffer, f);
|
||||
snprintf(buffer, MAX_DPATH, "ROMType=%d\n", lstAvailableROM->ROMType);
|
||||
fputs(buffer, f);
|
||||
write_string_option("ROMName", lstAvailableROM->Name);
|
||||
write_string_option("ROMPath", lstAvailableROM->Path);
|
||||
write_int_option("ROMType", lstAvailableROM->ROMType);
|
||||
}
|
||||
|
||||
// Recent disk entries (these are used in the dropdown controls)
|
||||
@ -3432,8 +3354,7 @@ void save_amiberry_settings(void)
|
||||
fputs(buffer, f);
|
||||
for (auto& i : lstMRUDiskList)
|
||||
{
|
||||
snprintf(buffer, MAX_DPATH, "Diskfile=%s\n", i.c_str());
|
||||
fputs(buffer, f);
|
||||
write_string_option("Diskfile", i);
|
||||
}
|
||||
|
||||
// Recent CD entries (these are used in the dropdown controls)
|
||||
@ -3441,8 +3362,7 @@ void save_amiberry_settings(void)
|
||||
fputs(buffer, f);
|
||||
for (auto& i : lstMRUCDList)
|
||||
{
|
||||
snprintf(buffer, MAX_DPATH, "CDfile=%s\n", i.c_str());
|
||||
fputs(buffer, f);
|
||||
write_string_option("CDfile", i);
|
||||
}
|
||||
|
||||
// Recent WHDLoad entries (these are used in the dropdown controls)
|
||||
@ -3451,8 +3371,7 @@ void save_amiberry_settings(void)
|
||||
fputs(buffer, f);
|
||||
for (auto& i : lstMRUWhdloadList)
|
||||
{
|
||||
snprintf(buffer, MAX_DPATH, "WHDLoadfile=%s\n", i.c_str());
|
||||
fputs(buffer, f);
|
||||
write_string_option("WHDLoadfile", i);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
@ -3681,7 +3600,7 @@ static int get_env_dir( char * path, const char *path_template, const char *envn
|
||||
return ret;
|
||||
}
|
||||
|
||||
void init_macos_amiberry_folders(std::string macos_amiberry_directory)
|
||||
void init_macos_amiberry_folders(const std::string& macos_amiberry_directory)
|
||||
{
|
||||
if (!my_existsdir(macos_amiberry_directory.c_str()))
|
||||
my_mkdir(macos_amiberry_directory.c_str());
|
||||
@ -4088,12 +4007,12 @@ int main(int argc, char* argv[])
|
||||
sortdisplays();
|
||||
enumerate_sound_devices();
|
||||
for (int i = 0; i < MAX_SOUND_DEVICES && sound_devices[i]; i++) {
|
||||
int type = sound_devices[i]->type;
|
||||
const int type = sound_devices[i]->type;
|
||||
write_log(_T("%d:%s: %s\n"), i, type == SOUND_DEVICE_SDL2 ? _T("SDL2") : (type == SOUND_DEVICE_DS ? _T("DS") : (type == SOUND_DEVICE_AL ? _T("AL") : (type == SOUND_DEVICE_WASAPI ? _T("WA") : (type == SOUND_DEVICE_WASAPI_EXCLUSIVE ? _T("WX") : _T("PA"))))), sound_devices[i]->name);
|
||||
}
|
||||
write_log(_T("Enumerating recording devices:\n"));
|
||||
for (int i = 0; i < MAX_SOUND_DEVICES && record_devices[i]; i++) {
|
||||
int type = record_devices[i]->type;
|
||||
const int type = record_devices[i]->type;
|
||||
write_log(_T("%d:%s: %s\n"), i, type == SOUND_DEVICE_SDL2 ? _T("SDL2") : (type == SOUND_DEVICE_DS ? _T("DS") : (type == SOUND_DEVICE_AL ? _T("AL") : (type == SOUND_DEVICE_WASAPI ? _T("WA") : (type == SOUND_DEVICE_WASAPI_EXCLUSIVE ? _T("WX") : _T("PA"))))), record_devices[i]->name);
|
||||
}
|
||||
write_log(_T("done\n"));
|
||||
@ -4220,7 +4139,7 @@ bool get_plugin_path(TCHAR* out, int len, const TCHAR* path)
|
||||
void drawbridge_update_profiles(uae_prefs* p)
|
||||
{
|
||||
#ifdef FLOPPYBRIDGE
|
||||
unsigned int flags = (p->drawbridge_autocache ? 1 : 0) | (p->drawbridge_connected_drive_b & 1) << 1 | (p->drawbridge_serial_auto ? 4 : 0) | (p->drawbridge_smartspeed ? 8 : 0);
|
||||
const unsigned int flags = (p->drawbridge_autocache ? 1 : 0) | (p->drawbridge_connected_drive_b & 1) << 1 | (p->drawbridge_serial_auto ? 4 : 0) | (p->drawbridge_smartspeed ? 8 : 0);
|
||||
|
||||
const std::string profile_name_fast = "Fast";
|
||||
const std::string profile_name_comp = "Compatible";
|
||||
@ -4269,3 +4188,17 @@ struct netdriverdata **target_ethernet_enumerate(void)
|
||||
net_enumerated = 1;
|
||||
return ndd;
|
||||
}
|
||||
|
||||
void clear_whdload_prefs()
|
||||
{
|
||||
whdload_prefs.filename.clear();
|
||||
whdload_prefs.game_name.clear();
|
||||
whdload_prefs.sub_path.clear();
|
||||
whdload_prefs.variant_uuid.clear();
|
||||
whdload_prefs.slave_count = 0;
|
||||
whdload_prefs.slave_default.clear();
|
||||
whdload_prefs.slave_libraries = false;
|
||||
whdload_prefs.slaves = {};
|
||||
whdload_prefs.selected_slave = {};
|
||||
whdload_prefs.custom.clear();
|
||||
}
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
#include <filesystem>
|
||||
#endif
|
||||
|
||||
#include <set>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include "crc32.h"
|
||||
@ -41,45 +42,44 @@ struct my_openfile_s {
|
||||
void utf8_to_latin1_string(std::string& input, std::string& output)
|
||||
{
|
||||
std::vector<char> in_buf(input.begin(), input.end());
|
||||
char* src_ptr = &in_buf[0];
|
||||
char* src_ptr = in_buf.data();
|
||||
size_t src_size = input.size();
|
||||
std::vector<char> buf(1024);
|
||||
std::string dst;
|
||||
|
||||
|
||||
auto* iconv_ = iconv_open("ISO-8859-1//TRANSLIT", "UTF-8");
|
||||
|
||||
while (0 < src_size) {
|
||||
char* dst_ptr = &buf[0];
|
||||
|
||||
while (src_size > 0) {
|
||||
char* dst_ptr = buf.data();
|
||||
size_t dst_size = buf.size();
|
||||
size_t res = ::iconv(iconv_, &src_ptr, &src_size, &dst_ptr, &dst_size);
|
||||
if (res == (size_t)-1) {
|
||||
if (errno == E2BIG) {
|
||||
// ignore this error
|
||||
}
|
||||
else {
|
||||
if (errno != E2BIG) {
|
||||
// skip character
|
||||
++src_ptr;
|
||||
--src_size;
|
||||
}
|
||||
}
|
||||
dst.append(&buf[0], buf.size() - dst_size);
|
||||
dst.append(buf.data(), buf.size() - dst_size);
|
||||
}
|
||||
dst.swap(output);
|
||||
output = std::move(dst);
|
||||
iconv_close(iconv_);
|
||||
}
|
||||
|
||||
std::string iso_8859_1_to_utf8(std::string& str)
|
||||
std::string iso_8859_1_to_utf8(const std::string& str)
|
||||
{
|
||||
string str_out;
|
||||
for (auto it = str.begin(); it != str.end(); ++it)
|
||||
std::string str_out;
|
||||
str_out.reserve(str.size() * 2); // Reserve space to avoid reallocations
|
||||
|
||||
for (const auto& ch : str)
|
||||
{
|
||||
uint8_t ch = *it;
|
||||
if (ch < 0x80) {
|
||||
str_out.push_back(ch);
|
||||
uint8_t byte = static_cast<uint8_t>(ch);
|
||||
if (byte < 0x80) {
|
||||
str_out.push_back(byte);
|
||||
}
|
||||
else {
|
||||
str_out.push_back(0xc0 | ch >> 6);
|
||||
str_out.push_back(0x80 | (ch & 0x3f));
|
||||
str_out.push_back(0xc0 | byte >> 6);
|
||||
str_out.push_back(0x80 | (byte & 0x3f));
|
||||
}
|
||||
}
|
||||
return str_out;
|
||||
@ -209,54 +209,50 @@ bool my_chmod(const TCHAR* name, uae_u32 mode)
|
||||
{
|
||||
// Note: only used to set or clear write protect on disk file
|
||||
|
||||
// get current state
|
||||
struct stat st{};
|
||||
auto input = string(name);
|
||||
auto output = iso_8859_1_to_utf8(input);
|
||||
// Convert input to UTF-8
|
||||
auto output = iso_8859_1_to_utf8(string(name));
|
||||
|
||||
// Get current state
|
||||
struct stat st {};
|
||||
if (stat(output.c_str(), &st) == -1) {
|
||||
write_log("my_chmod: stat on file %s failed\n", output.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Prepare new mode
|
||||
auto newmode = st.st_mode;
|
||||
if (mode & FILEFLAG_WRITE)
|
||||
// set write permission
|
||||
st.st_mode |= S_IWUSR;
|
||||
newmode |= S_IWUSR; // set write permission
|
||||
else
|
||||
// clear write permission
|
||||
st.st_mode &= ~(S_IWUSR);
|
||||
chmod(output.c_str(), st.st_mode);
|
||||
newmode &= ~S_IWUSR; // clear write permission
|
||||
|
||||
stat(output.c_str(), &st);
|
||||
auto newmode = 0;
|
||||
if (st.st_mode & S_IRUSR) {
|
||||
newmode |= FILEFLAG_READ;
|
||||
}
|
||||
if (st.st_mode & S_IWUSR) {
|
||||
newmode |= FILEFLAG_WRITE;
|
||||
// Change mode
|
||||
if (chmod(output.c_str(), newmode) == -1) {
|
||||
write_log("my_chmod: chmod on file %s failed\n", output.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
return (mode == newmode);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool my_stat(const TCHAR* name, struct mystat* statbuf)
|
||||
{
|
||||
struct stat st{};
|
||||
if (!name || !statbuf) {
|
||||
write_log("my_stat: null arguments provided\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
struct stat st {};
|
||||
auto output = iso_8859_1_to_utf8(string(name));
|
||||
|
||||
auto input = string(name);
|
||||
auto output = iso_8859_1_to_utf8(input);
|
||||
if (stat(output.c_str(), &st) == -1) {
|
||||
write_log("my_stat: stat on file %s failed\n", output.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
statbuf->size = st.st_size;
|
||||
statbuf->mode = 0;
|
||||
if (st.st_mode & S_IRUSR) {
|
||||
statbuf->mode |= FILEFLAG_READ;
|
||||
}
|
||||
if (st.st_mode & S_IWUSR) {
|
||||
statbuf->mode |= FILEFLAG_WRITE;
|
||||
}
|
||||
statbuf->mode = ((st.st_mode & S_IRUSR) ? FILEFLAG_READ : 0) |
|
||||
((st.st_mode & S_IWUSR) ? FILEFLAG_WRITE : 0);
|
||||
statbuf->mtime.tv_sec = st.st_mtime;
|
||||
statbuf->mtime.tv_usec = 0;
|
||||
|
||||
@ -265,29 +261,42 @@ bool my_stat(const TCHAR* name, struct mystat* statbuf)
|
||||
|
||||
bool compare_nocase(const std::string& first, const std::string& second)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
while ((i < first.length()) && (i < second.length()))
|
||||
const auto len = std::min(first.length(), second.length());
|
||||
|
||||
for (unsigned int i = 0; i < len; ++i)
|
||||
{
|
||||
if (tolower(first[i]) < tolower(second[i])) return true;
|
||||
else if (tolower(first[i]) > tolower(second[i])) return false;
|
||||
++i;
|
||||
const auto first_ch = std::tolower(first[i]);
|
||||
const auto second_ch = std::tolower(second[i]);
|
||||
|
||||
if (first_ch != second_ch)
|
||||
return first_ch < second_ch;
|
||||
}
|
||||
return (first.length() < second.length());
|
||||
|
||||
return first.length() < second.length();
|
||||
}
|
||||
|
||||
struct my_opendir_s* my_opendir(const TCHAR* name, const TCHAR* mask)
|
||||
{
|
||||
auto* mod = xmalloc(struct my_opendir_s, 1);
|
||||
if (!mod)
|
||||
return NULL;
|
||||
auto input = string(name);
|
||||
auto output = iso_8859_1_to_utf8(input);
|
||||
mod->dir = opendir(output.c_str());
|
||||
if (!mod->dir) {
|
||||
write_log("my_opendir %s failed\n", name);
|
||||
xfree(mod);
|
||||
if (!name) {
|
||||
write_log("my_opendir: null directory name provided\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
auto* mod = new my_opendir_s;
|
||||
if (!mod) {
|
||||
write_log("my_opendir: memory allocation failed\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
auto output = iso_8859_1_to_utf8(string(name));
|
||||
mod->dir = opendir(output.c_str());
|
||||
|
||||
if (!mod->dir) {
|
||||
write_log("my_opendir: opendir on directory %s failed\n", name);
|
||||
delete mod;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return mod;
|
||||
}
|
||||
|
||||
@ -305,99 +314,77 @@ void my_closedir(struct my_opendir_s* mod)
|
||||
|
||||
int my_readdir(struct my_opendir_s* mod, TCHAR* name)
|
||||
{
|
||||
if (!mod)
|
||||
if (!mod || !name)
|
||||
return 0;
|
||||
|
||||
|
||||
const set<std::string> ignoreList = { "_UAEFSDB.___", "Thumbs.db", ".DS_Store", "UAEFS.ini" };
|
||||
|
||||
while (true)
|
||||
{
|
||||
auto* entry = readdir(mod->dir);
|
||||
if (entry == NULL)
|
||||
return 0;
|
||||
|
||||
|
||||
auto* result = entry->d_name;
|
||||
const int len = strlen(result);
|
||||
|
||||
if (strcasecmp(result, "_UAEFSDB.___") == 0) {
|
||||
continue;
|
||||
}
|
||||
if (strcasecmp(result, "Thumbs.db") == 0) {
|
||||
continue;
|
||||
}
|
||||
if (strcasecmp(result, ".DS_Store") == 0) {
|
||||
continue;
|
||||
}
|
||||
if (strcasecmp(result, "UAEFS.ini") == 0) {
|
||||
continue;
|
||||
}
|
||||
if (len > 5 && strncmp(result + len - 5, ".uaem", 5) == 0) {
|
||||
// ignore metadata / attribute files, obviously
|
||||
if (ignoreList.find(result) != ignoreList.end() ||
|
||||
(len > 5 && strncmp(result + len - 5, ".uaem", 5) == 0)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto string_input = string(result);
|
||||
string string_output;
|
||||
utf8_to_latin1_string(string_input, string_output);
|
||||
//write_log("Original: %s - Converted: %s\n", string_input.c_str(), string_output.c_str());
|
||||
_tcscpy(name, string_output.c_str());
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int my_existslink(const char* name)
|
||||
bool my_existslink(const char* name)
|
||||
{
|
||||
struct stat st {};
|
||||
if (lstat(name, &st) == -1)
|
||||
{
|
||||
return 0;
|
||||
if (!name) {
|
||||
write_log("my_existslink: null file name provided\n");
|
||||
return false;
|
||||
}
|
||||
if (S_ISLNK(st.st_mode))
|
||||
return 1;
|
||||
return 0;
|
||||
|
||||
struct stat st {};
|
||||
if (lstat(name, &st) == -1) {
|
||||
write_log("my_existslink: lstat on file %s failed\n", name);
|
||||
return false;
|
||||
}
|
||||
|
||||
return S_ISLNK(st.st_mode);
|
||||
}
|
||||
|
||||
int my_existsfile2(const char* name)
|
||||
bool my_existsfile2(const char* name)
|
||||
{
|
||||
struct stat st {};
|
||||
if (lstat(name, &st) == -1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (!S_ISDIR(st.st_mode))
|
||||
return 1;
|
||||
return 0;
|
||||
return lstat(name, &st) != -1 && !S_ISDIR(st.st_mode);
|
||||
}
|
||||
|
||||
int my_existsfile(const char* name)
|
||||
bool my_existsfile(const char* name)
|
||||
{
|
||||
struct stat st {};
|
||||
auto input = string(name);
|
||||
auto output = iso_8859_1_to_utf8(input);
|
||||
if (lstat(output.c_str(), &st) == -1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (!S_ISDIR(st.st_mode))
|
||||
return 1;
|
||||
return 0;
|
||||
auto output = iso_8859_1_to_utf8(string(name));
|
||||
return lstat(output.c_str(), &st) != -1 && !S_ISDIR(st.st_mode);
|
||||
}
|
||||
|
||||
int my_existsdir(const char* name)
|
||||
bool my_existsdir(const char* name)
|
||||
{
|
||||
struct stat st {};
|
||||
auto input = string(name);
|
||||
auto output = iso_8859_1_to_utf8(input);
|
||||
if (lstat(output.c_str(), &st) == -1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (S_ISDIR(st.st_mode))
|
||||
return 1;
|
||||
return 0;
|
||||
auto output = iso_8859_1_to_utf8(string(name));
|
||||
return lstat(output.c_str(), &st) != -1 && S_ISDIR(st.st_mode);
|
||||
}
|
||||
|
||||
uae_s64 my_fsize(struct my_openfile_s* mos)
|
||||
{
|
||||
if (mos == nullptr) {
|
||||
write_log("my_fsize: null pointer provided\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct stat st {};
|
||||
if (fstat(mos->fd, &st) == -1) {
|
||||
write_log("my_fsize: fstat on file %s failed\n", mos->path);
|
||||
@ -408,48 +395,67 @@ uae_s64 my_fsize(struct my_openfile_s* mos)
|
||||
|
||||
int my_getvolumeinfo(const char* root)
|
||||
{
|
||||
if (root == nullptr) {
|
||||
write_log("my_getvolumeinfo: null pointer provided\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct stat st {};
|
||||
auto ret = 0;
|
||||
|
||||
if (lstat(root, &st) == -1)
|
||||
if (lstat(root, &st) == -1) {
|
||||
write_log("my_getvolumeinfo: lstat on file %s failed\n", root);
|
||||
return -1;
|
||||
if (!S_ISDIR(st.st_mode))
|
||||
}
|
||||
if (!S_ISDIR(st.st_mode)) {
|
||||
write_log("my_getvolumeinfo: %s is not a directory\n", root);
|
||||
return -2;
|
||||
}
|
||||
|
||||
ret |= MYVOLUMEINFO_STREAMS;
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool fs_path_exists(const std::string& s)
|
||||
{
|
||||
struct stat buffer{};
|
||||
auto input = string(s);
|
||||
auto output = iso_8859_1_to_utf8(input);
|
||||
if (s.empty()) {
|
||||
write_log("fs_path_exists: empty string provided\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
struct stat buffer {};
|
||||
auto output = iso_8859_1_to_utf8(s);
|
||||
return stat(output.c_str(), &buffer) == 0;
|
||||
}
|
||||
|
||||
struct my_openfile_s* my_open(const TCHAR* name, int flags)
|
||||
{
|
||||
struct my_openfile_s* mos;
|
||||
|
||||
mos = xmalloc(struct my_openfile_s, 1);
|
||||
if (!mos)
|
||||
if (name == nullptr) {
|
||||
write_log("my_open: null pointer provided\n");
|
||||
return NULL;
|
||||
auto input = string(name);
|
||||
auto output = iso_8859_1_to_utf8(input);
|
||||
if (flags & O_CREAT)
|
||||
{
|
||||
}
|
||||
|
||||
auto* mos = xmalloc(struct my_openfile_s, 1);
|
||||
if (!mos) {
|
||||
write_log("my_open: memory allocation failed\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
auto output = iso_8859_1_to_utf8(string(name));
|
||||
if (flags & O_CREAT) {
|
||||
mos->fd = open(output.c_str(), flags, 0660);
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
mos->fd = open(output.c_str(), flags);
|
||||
}
|
||||
if (!mos->fd) {
|
||||
|
||||
if (mos->fd == -1) {
|
||||
write_log("my_open: open on file %s failed\n", name);
|
||||
xfree(mos);
|
||||
mos = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return mos;
|
||||
}
|
||||
|
||||
@ -462,35 +468,63 @@ void my_close(struct my_openfile_s* mos)
|
||||
|
||||
unsigned int my_read(struct my_openfile_s* mos, void* b, unsigned int size)
|
||||
{
|
||||
const auto bytes_read = read(mos->fd, b, size);
|
||||
if (bytes_read == -1)
|
||||
{
|
||||
write_log("WARNING: my_read failed (-1)\n");
|
||||
if (mos == nullptr) {
|
||||
write_log("my_read: null file pointer provided\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (b == nullptr) {
|
||||
write_log("my_read: null buffer pointer provided\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
const auto bytes_read = read(mos->fd, b, size);
|
||||
if (bytes_read == -1) {
|
||||
write_log("my_read: read on file %s failed with error %s\n", mos->path, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
else if (bytes_read < size) {
|
||||
write_log("my_read: read on file %s returned less bytes than requested\n", mos->path);
|
||||
}
|
||||
|
||||
return static_cast<unsigned int>(bytes_read);
|
||||
}
|
||||
|
||||
unsigned int my_write(struct my_openfile_s* mos, void* b, unsigned int size)
|
||||
{
|
||||
const auto bytes_written = write(mos->fd, b, size);
|
||||
if (bytes_written == -1)
|
||||
{
|
||||
write_log("WARNING: my_write failed (-1) fd=%d buffer=%p size=%d\n",
|
||||
mos->fd, b, size);
|
||||
write_log("errno %d\n", errno);
|
||||
write_log(" mos %p -> h=%d\n", mos, mos->fd);
|
||||
if (mos == nullptr) {
|
||||
write_log("my_write: null file pointer provided\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (b == nullptr) {
|
||||
write_log("my_write: null buffer pointer provided\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
const auto bytes_written = write(mos->fd, b, size);
|
||||
if (bytes_written == -1) {
|
||||
write_log("my_write: write on file %s failed with error %s\n", mos->path, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
else if (bytes_written < size) {
|
||||
write_log("my_write: write on file %s wrote less bytes than requested\n", mos->path);
|
||||
}
|
||||
|
||||
return static_cast<unsigned int>(bytes_written);
|
||||
}
|
||||
|
||||
int my_mkdir(const TCHAR* path)
|
||||
{
|
||||
auto input = string(path);
|
||||
auto output = iso_8859_1_to_utf8(input);
|
||||
if (path == nullptr) {
|
||||
write_log("my_mkdir: null pointer provided\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
auto output = iso_8859_1_to_utf8(string(path));
|
||||
int error = mkdir(output.c_str(), 0755);
|
||||
if (error) {
|
||||
write_log("my_mkdir: mkdir on path %s failed with error %s\n", path, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
@ -498,87 +532,192 @@ int my_mkdir(const TCHAR* path)
|
||||
|
||||
int my_truncate(const TCHAR* name, uae_u64 len)
|
||||
{
|
||||
int int_len = (int)len;
|
||||
struct my_openfile_s* mos = my_open(name, O_WRONLY);
|
||||
if (mos == NULL) {
|
||||
write_log("WARNING: opening file for truncation failed\n");
|
||||
if (name == nullptr) {
|
||||
write_log("my_truncate: null pointer provided\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct my_openfile_s* mos = my_open(name, O_WRONLY);
|
||||
if (mos == NULL) {
|
||||
write_log("my_truncate: opening file %s for truncation failed\n", name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int result;
|
||||
#ifdef WINDOWS
|
||||
int result = _chsize(mos->fd, int_len);
|
||||
if (len > INT_MAX) {
|
||||
write_log("my_truncate: length %llu is too large for _chsize\n", len);
|
||||
result = -1;
|
||||
}
|
||||
else {
|
||||
result = _chsize(mos->fd, static_cast<int>(len));
|
||||
}
|
||||
#else
|
||||
int result = ftruncate(mos->fd, int_len);
|
||||
result = ftruncate(mos->fd, len);
|
||||
#endif
|
||||
|
||||
if (result == -1) {
|
||||
write_log("my_truncate: truncating file %s failed with error %s\n", name, strerror(errno));
|
||||
}
|
||||
|
||||
my_close(mos);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void remove_extra_file(const char* path, const char* name)
|
||||
{
|
||||
auto* p = (TCHAR*)malloc(MAX_DPATH);
|
||||
_tcscpy(p, path);
|
||||
fix_trailing(p);
|
||||
strcat(p, name);
|
||||
|
||||
unlink(p);
|
||||
xfree(p);
|
||||
std::string p(path);
|
||||
p = fix_trailing(p);
|
||||
p += name;
|
||||
unlink(p.c_str());
|
||||
}
|
||||
|
||||
bool my_isfilehidden (const TCHAR *path)
|
||||
bool my_isfilehidden(const char* path)
|
||||
{
|
||||
return false;
|
||||
if (path == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string filename(path);
|
||||
return filename[0] == '.';
|
||||
}
|
||||
|
||||
void my_setfilehidden (const TCHAR *path, bool hidden)
|
||||
void my_setfilehidden(const TCHAR* path, bool hidden)
|
||||
{
|
||||
if (path == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::string filename(path);
|
||||
|
||||
#ifdef _WIN32
|
||||
DWORD attrs = GetFileAttributes(path);
|
||||
|
||||
if (hidden)
|
||||
{
|
||||
attrs |= FILE_ATTRIBUTE_HIDDEN;
|
||||
}
|
||||
else
|
||||
{
|
||||
attrs &= ~FILE_ATTRIBUTE_HIDDEN;
|
||||
}
|
||||
|
||||
SetFileAttributes(path, attrs);
|
||||
#else
|
||||
std::string newname;
|
||||
|
||||
if (hidden)
|
||||
{
|
||||
if (filename[0] != '.')
|
||||
{
|
||||
newname = "." + filename;
|
||||
rename(filename.c_str(), newname.c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (filename[0] == '.')
|
||||
{
|
||||
newname = filename.substr(1);
|
||||
rename(filename.c_str(), newname.c_str());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int my_rmdir(const TCHAR* path)
|
||||
{
|
||||
if (path == nullptr) {
|
||||
write_log("my_rmdir: null directory path provided\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
remove_extra_file(path, "Thumbs.db");
|
||||
remove_extra_file(path, ".DS_Store");
|
||||
|
||||
errno = 0;
|
||||
auto input = string(path);
|
||||
auto output = iso_8859_1_to_utf8(input);
|
||||
auto output = iso_8859_1_to_utf8(string(path));
|
||||
int result = rmdir(output.c_str());
|
||||
|
||||
if (result != 0) {
|
||||
write_log("my_rmdir: rmdir on directory %s failed with error %d\n", path, errno);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int my_unlink(const TCHAR* path)
|
||||
{
|
||||
if (path == nullptr) {
|
||||
write_log("my_unlink: null file path provided\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
auto input = string(path);
|
||||
auto output = iso_8859_1_to_utf8(input);
|
||||
auto output = iso_8859_1_to_utf8(string(path));
|
||||
int result = unlink(output.c_str());
|
||||
|
||||
if (result != 0) {
|
||||
write_log("my_unlink: unlink on file %s failed with error %d\n", path, errno);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int my_rename(const TCHAR* oldname, const TCHAR* newname)
|
||||
{
|
||||
errno = 0;
|
||||
auto old_input = string(oldname);
|
||||
auto old_output = iso_8859_1_to_utf8(old_input);
|
||||
auto new_input = string(newname);
|
||||
auto new_output = iso_8859_1_to_utf8(new_input);
|
||||
if (oldname == nullptr || newname == nullptr) {
|
||||
write_log("my_rename: null file name provided\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return rename(old_output.c_str(), new_output.c_str());
|
||||
errno = 0;
|
||||
auto old_output = iso_8859_1_to_utf8(string(oldname));
|
||||
auto new_output = iso_8859_1_to_utf8(string(newname));
|
||||
|
||||
int result = rename(old_output.c_str(), new_output.c_str());
|
||||
|
||||
if (result != 0) {
|
||||
write_log("my_rename: rename from %s to %s failed with error %d\n", oldname, newname, errno);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
uae_s64 my_lseek(struct my_openfile_s* mos, uae_s64 offset, int whence)
|
||||
{
|
||||
if (mos == nullptr) {
|
||||
write_log("my_lseek: null file descriptor provided\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
return lseek(mos->fd, offset, whence);
|
||||
auto result = lseek(mos->fd, offset, whence);
|
||||
|
||||
if (result == -1) {
|
||||
write_log("my_lseek: lseek on file %s failed with error %d\n", mos->path, errno);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
FILE* my_opentext(const TCHAR* name)
|
||||
{
|
||||
auto input = string(name);
|
||||
auto output = iso_8859_1_to_utf8(input);
|
||||
return fopen(output.c_str(), "rb");
|
||||
if (name == nullptr) {
|
||||
write_log("my_opentext: null file name provided\n");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto output = iso_8859_1_to_utf8(string(name));
|
||||
FILE* file = fopen(output.c_str(), "rb");
|
||||
|
||||
if (file == nullptr) {
|
||||
write_log("my_opentext: fopen on file %s failed\n", name);
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
bool my_createshortcut(const char* source, const char* target, const char* description)
|
||||
@ -648,37 +787,55 @@ int host_errno_to_dos_errno(int err)
|
||||
|
||||
void my_canonicalize_path(const TCHAR* path, TCHAR* out, int size)
|
||||
{
|
||||
_tcsncpy(out, path, size);
|
||||
out[size - 1] = 0;
|
||||
return;
|
||||
if (path == nullptr || out == nullptr) {
|
||||
write_log("my_canonicalize_path: null arguments provided\n");
|
||||
return;
|
||||
}
|
||||
|
||||
_tcsncpy(out, path, size - 1);
|
||||
out[size - 1] = '\0';
|
||||
}
|
||||
|
||||
bool my_issamepath(const TCHAR* path1, const TCHAR* path2)
|
||||
{
|
||||
if (path1 == nullptr || path2 == nullptr) {
|
||||
write_log("my_issamepath: null path provided\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return _tcsicmp(path1, path2) == 0;
|
||||
}
|
||||
|
||||
int my_issamevolume(const TCHAR* path1, const TCHAR* path2, TCHAR* path)
|
||||
{
|
||||
if (path1 == nullptr || path2 == nullptr || path == nullptr) {
|
||||
write_log("my_issamevolume: null arguments provided\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
TCHAR p1[MAX_DPATH];
|
||||
TCHAR p2[MAX_DPATH];
|
||||
unsigned int len, cnt;
|
||||
|
||||
my_canonicalize_path(path1, p1, sizeof p1 / sizeof(TCHAR));
|
||||
my_canonicalize_path(path2, p2, sizeof p2 / sizeof(TCHAR));
|
||||
len = _tcslen(p1);
|
||||
|
||||
unsigned int len = _tcslen(p1);
|
||||
if (len > _tcslen(p2))
|
||||
len = _tcslen(p2);
|
||||
|
||||
if (_tcsnicmp(p1, p2, len))
|
||||
return 0;
|
||||
|
||||
_tcscpy(path, p2 + len);
|
||||
cnt = 0;
|
||||
|
||||
unsigned int cnt = 0;
|
||||
for (unsigned int i = 0; i < _tcslen(path); i++) {
|
||||
if (path[i] == '\\' || path[i] == '/') {
|
||||
path[i] = '/';
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
write_log(_T("'%s' (%s) matched with '%s' (%s), extra = '%s'\n"), path1, p1, path2, p2, path);
|
||||
return cnt;
|
||||
}
|
||||
@ -709,7 +866,7 @@ int dos_errno(void)
|
||||
#endif
|
||||
|
||||
default:
|
||||
write_log(("Unimplemented error %s\n", strerror(e)));
|
||||
write_log(_T("Unimplemented error %s\n"), strerror(e));
|
||||
return ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
}
|
||||
@ -729,13 +886,13 @@ int target_get_volume_name(struct uaedev_mount_info* mtinf, struct uaedev_config
|
||||
// If replace is false, copyfile will fail if file already exists
|
||||
bool copyfile(const char* target, const char* source, const bool replace)
|
||||
{
|
||||
#ifdef USE_OLDGCC
|
||||
#ifdef USE_OLDGCC
|
||||
std::experimental::filesystem::copy_options options = {};
|
||||
options = replace ? experimental::filesystem::copy_options::overwrite_existing : experimental::filesystem::copy_options::none;
|
||||
#else
|
||||
#else
|
||||
std::filesystem::copy_options options = {};
|
||||
options = replace ? filesystem::copy_options::overwrite_existing : filesystem::copy_options::none;
|
||||
#endif
|
||||
#endif
|
||||
return copy_file(source, target, options);
|
||||
}
|
||||
|
||||
@ -744,32 +901,37 @@ void filesys_addexternals(void)
|
||||
// this would mount system drives on Windows
|
||||
}
|
||||
|
||||
const std::string my_get_sha1_of_file(const char* filepath)
|
||||
std::string my_get_sha1_of_file(const char* filepath)
|
||||
{
|
||||
void* mem;
|
||||
struct stat sb;
|
||||
int fd = -1;
|
||||
int ret = 0;
|
||||
int len;
|
||||
|
||||
if ((fd = open((char*)filepath, O_RDONLY)) < 0) ret = (-3);
|
||||
if (ret == 0 && fstat(fd, &sb) < 0) ret = (-2);
|
||||
|
||||
if (ret == 0) {
|
||||
if ((mem = mmap((caddr_t)0, (int)sb.st_size,
|
||||
PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0)) != MAP_FAILED) {
|
||||
len = (int)sb.st_size;
|
||||
}
|
||||
else ret = (-1);
|
||||
if (filepath == nullptr) {
|
||||
write_log("my_get_sha1_of_file: null file path provided\n");
|
||||
return "";
|
||||
}
|
||||
|
||||
if (ret > (-3)) close(fd);
|
||||
int fd = open(filepath, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
write_log("my_get_sha1_of_file: open on file %s failed\n", filepath);
|
||||
return "";
|
||||
}
|
||||
|
||||
if (ret < 0) return NULL;
|
||||
struct stat sb;
|
||||
if (fstat(fd, &sb) < 0) {
|
||||
write_log("my_get_sha1_of_file: fstat on file %s failed\n", filepath);
|
||||
close(fd);
|
||||
return "";
|
||||
}
|
||||
|
||||
const TCHAR* sha1 = get_sha1_txt(mem, len);
|
||||
void* mem = mmap(nullptr, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
if (mem == MAP_FAILED) {
|
||||
write_log("my_get_sha1_of_file: mmap on file %s failed\n", filepath);
|
||||
close(fd);
|
||||
return "";
|
||||
}
|
||||
|
||||
munmap((caddr_t)mem, (size_t)len);
|
||||
const TCHAR* sha1 = get_sha1_txt(mem, sb.st_size);
|
||||
|
||||
munmap(mem, sb.st_size);
|
||||
close(fd);
|
||||
|
||||
return string(sha1);
|
||||
}
|
||||
|
||||
@ -4,6 +4,9 @@
|
||||
#include <cstdlib>
|
||||
#include <cstdarg>
|
||||
#include <fstream>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include <guisan.hpp>
|
||||
#include <guisan/sdl.hpp>
|
||||
@ -94,83 +97,25 @@ std::string get_full_path_from_disk_list(std::string element)
|
||||
return full_path;
|
||||
}
|
||||
|
||||
void AddFileToDiskList(const char *file, int moveToTop)
|
||||
void add_file_to_mru_list(std::vector<std::string>& vec, const std::string& file)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < lstMRUDiskList.size(); ++i)
|
||||
{
|
||||
if (!stricmp(lstMRUDiskList[i].c_str(), file))
|
||||
{
|
||||
if (moveToTop)
|
||||
{
|
||||
lstMRUDiskList.erase(lstMRUDiskList.begin() + i);
|
||||
lstMRUDiskList.insert(lstMRUDiskList.begin(), file);
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Check if the string already exists in the vector
|
||||
if (std::find(vec.begin(), vec.end(), file) == vec.end()) {
|
||||
// The string does not exist in the vector, so add it at the first position
|
||||
vec.insert(vec.begin(), file);
|
||||
}
|
||||
if (i >= lstMRUDiskList.size())
|
||||
lstMRUDiskList.insert(lstMRUDiskList.begin(), file);
|
||||
|
||||
while (lstMRUDiskList.size() > MAX_MRU_DISKLIST)
|
||||
lstMRUDiskList.pop_back();
|
||||
}
|
||||
|
||||
void AddFileToCDList(const char *file, int moveToTop)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < lstMRUCDList.size(); ++i)
|
||||
{
|
||||
if (!stricmp(lstMRUCDList[i].c_str(), file))
|
||||
{
|
||||
if (moveToTop)
|
||||
{
|
||||
lstMRUCDList.erase(lstMRUCDList.begin() + i);
|
||||
lstMRUCDList.insert(lstMRUCDList.begin(), file);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i >= lstMRUCDList.size())
|
||||
lstMRUCDList.insert(lstMRUCDList.begin(), file);
|
||||
|
||||
while (lstMRUCDList.size() > MAX_MRU_CDLIST)
|
||||
lstMRUCDList.pop_back();
|
||||
}
|
||||
|
||||
void AddFileToWHDLoadList(const char* file, int moveToTop)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < lstMRUWhdloadList.size(); ++i)
|
||||
{
|
||||
if (!stricmp(lstMRUWhdloadList[i].c_str(), file))
|
||||
{
|
||||
if (moveToTop)
|
||||
{
|
||||
lstMRUWhdloadList.erase(lstMRUWhdloadList.begin() + i);
|
||||
lstMRUWhdloadList.insert(lstMRUWhdloadList.begin(), file);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i >= lstMRUWhdloadList.size())
|
||||
lstMRUWhdloadList.insert(lstMRUWhdloadList.begin(), file);
|
||||
|
||||
while (lstMRUWhdloadList.size() > MAX_MRU_WHDLOADLIST)
|
||||
lstMRUWhdloadList.pop_back();
|
||||
while (vec.size() > MAX_MRU_LIST)
|
||||
vec.pop_back();
|
||||
}
|
||||
|
||||
void ClearAvailableROMList()
|
||||
{
|
||||
while (!lstAvailableROMs.empty())
|
||||
for (const auto* rom : lstAvailableROMs)
|
||||
{
|
||||
auto* const tmp = lstAvailableROMs[0];
|
||||
lstAvailableROMs.erase(lstAvailableROMs.begin());
|
||||
delete tmp;
|
||||
delete rom;
|
||||
}
|
||||
lstAvailableROMs.clear();
|
||||
}
|
||||
|
||||
static void addrom(struct romdata* rd, const char* path)
|
||||
@ -321,7 +266,7 @@ void RescanROMs()
|
||||
if (dir != "..")
|
||||
{
|
||||
std::string full_path = std::string(path).append(dir);
|
||||
read_directory(full_path.c_str(), nullptr, &files);
|
||||
read_directory(full_path, nullptr, &files);
|
||||
for (auto & file : files)
|
||||
{
|
||||
std::string tmp_path = full_path;
|
||||
@ -346,12 +291,11 @@ void RescanROMs()
|
||||
|
||||
static void ClearConfigFileList()
|
||||
{
|
||||
while (!ConfigFilesList.empty())
|
||||
for (const auto* config : ConfigFilesList)
|
||||
{
|
||||
auto* const tmp = ConfigFilesList[0];
|
||||
ConfigFilesList.erase(ConfigFilesList.begin());
|
||||
delete tmp;
|
||||
delete config;
|
||||
}
|
||||
ConfigFilesList.clear();
|
||||
}
|
||||
|
||||
void ReadConfigFileList(void)
|
||||
@ -404,7 +348,7 @@ void ReadConfigFileList(void)
|
||||
|
||||
ConfigFileInfo* SearchConfigInList(const char* name)
|
||||
{
|
||||
for (auto & i : ConfigFilesList)
|
||||
for (const auto & i : ConfigFilesList)
|
||||
{
|
||||
if (!SDL_strncasecmp(i->Name, name, MAX_DPATH))
|
||||
return i;
|
||||
@ -426,7 +370,7 @@ void disk_selection(const int drive, uae_prefs* prefs)
|
||||
{
|
||||
strncpy(prefs->floppyslots[drive].df, tmp.c_str(), MAX_DPATH);
|
||||
disk_insert(drive, tmp.c_str());
|
||||
AddFileToDiskList(tmp.c_str(), 1);
|
||||
add_file_to_mru_list(lstMRUDiskList, tmp);
|
||||
current_dir = extract_path(tmp);
|
||||
}
|
||||
}
|
||||
@ -543,68 +487,11 @@ int gui_update()
|
||||
remove_file_extension(savestate_fname);
|
||||
remove_file_extension(screenshot_filename);
|
||||
|
||||
switch(currentStateNum)
|
||||
{
|
||||
case 1:
|
||||
strncat(savestate_fname,"-1.uss", MAX_DPATH - 1);
|
||||
screenshot_filename.append("-1.png");
|
||||
break;
|
||||
case 2:
|
||||
strncat(savestate_fname,"-2.uss", MAX_DPATH - 1);
|
||||
screenshot_filename.append("-2.png");
|
||||
break;
|
||||
case 3:
|
||||
strncat(savestate_fname,"-3.uss", MAX_DPATH - 1);
|
||||
screenshot_filename.append("-3.png");
|
||||
break;
|
||||
case 4:
|
||||
strncat(savestate_fname, "-4.uss", MAX_DPATH - 1);
|
||||
screenshot_filename.append("-4.png");
|
||||
break;
|
||||
case 5:
|
||||
strncat(savestate_fname, "-5.uss", MAX_DPATH - 1);
|
||||
screenshot_filename.append("-5.png");
|
||||
break;
|
||||
case 6:
|
||||
strncat(savestate_fname, "-6.uss", MAX_DPATH - 1);
|
||||
screenshot_filename.append("-6.png");
|
||||
break;
|
||||
case 7:
|
||||
strncat(savestate_fname, "-7.uss", MAX_DPATH - 1);
|
||||
screenshot_filename.append("-7.png");
|
||||
break;
|
||||
case 8:
|
||||
strncat(savestate_fname, "-8.uss", MAX_DPATH - 1);
|
||||
screenshot_filename.append("-8.png");
|
||||
break;
|
||||
case 9:
|
||||
strncat(savestate_fname, "-9.uss", MAX_DPATH - 1);
|
||||
screenshot_filename.append("-9.png");
|
||||
break;
|
||||
case 10:
|
||||
strncat(savestate_fname, "-10.uss", MAX_DPATH - 1);
|
||||
screenshot_filename.append("-10.png");
|
||||
break;
|
||||
case 11:
|
||||
strncat(savestate_fname, "-11.uss", MAX_DPATH - 1);
|
||||
screenshot_filename.append("-11.png");
|
||||
break;
|
||||
case 12:
|
||||
strncat(savestate_fname, "-12.uss", MAX_DPATH - 1);
|
||||
screenshot_filename.append("-12.png");
|
||||
break;
|
||||
case 13:
|
||||
strncat(savestate_fname, "-13.uss", MAX_DPATH - 1);
|
||||
screenshot_filename.append("-13.png");
|
||||
break;
|
||||
case 14:
|
||||
strncat(savestate_fname, "-14.uss", MAX_DPATH - 1);
|
||||
screenshot_filename.append("-14.png");
|
||||
break;
|
||||
default:
|
||||
strncat(savestate_fname,".uss", MAX_DPATH - 1);
|
||||
screenshot_filename.append(".png");
|
||||
}
|
||||
std::string suffix = (currentStateNum >= 1 && currentStateNum <= 14) ?
|
||||
"-" + std::to_string(currentStateNum) : "";
|
||||
strncat(savestate_fname, (suffix + ".uss").c_str(), MAX_DPATH - 1);
|
||||
screenshot_filename.append(suffix + ".png");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -648,7 +535,7 @@ void gui_display(int shortcut)
|
||||
inputdevice_copyconfig(&changed_prefs, &currprefs);
|
||||
inputdevice_config_change_test();
|
||||
clearallkeys ();
|
||||
update_display(&changed_prefs);
|
||||
|
||||
if (resumepaused(7)) {
|
||||
inputdevice_acquire(TRUE);
|
||||
setmouseactive(0, 1);
|
||||
@ -1125,30 +1012,30 @@ void DisplayDiskInfo(int num)
|
||||
snprintf(title, MAX_DPATH - 1, "Info for %s", nameonly);
|
||||
|
||||
snprintf(linebuffer, sizeof(linebuffer) - 1, "Disk readable: %s", di.unreadable ? _T("No") : _T("Yes"));
|
||||
infotext.push_back(linebuffer);
|
||||
infotext.emplace_back(linebuffer);
|
||||
snprintf(linebuffer, sizeof(linebuffer) - 1, "Disk CRC32: %08X", di.imagecrc32);
|
||||
infotext.push_back(linebuffer);
|
||||
infotext.emplace_back(linebuffer);
|
||||
snprintf(linebuffer, sizeof(linebuffer) - 1, "Boot block CRC32: %08X", di.bootblockcrc32);
|
||||
infotext.push_back(linebuffer);
|
||||
infotext.emplace_back(linebuffer);
|
||||
snprintf(linebuffer, sizeof(linebuffer) - 1, "Boot block checksum valid: %s", di.bb_crc_valid ? _T("Yes") : _T("No"));
|
||||
infotext.push_back(linebuffer);
|
||||
infotext.emplace_back(linebuffer);
|
||||
snprintf(linebuffer, sizeof(linebuffer) - 1, "Boot block type: %s", di.bootblocktype == 0 ? _T("Custom") : (di.bootblocktype == 1 ? _T("Standard 1.x") : _T("Standard 2.x+")));
|
||||
infotext.push_back(linebuffer);
|
||||
infotext.emplace_back(linebuffer);
|
||||
if (di.diskname[0]) {
|
||||
snprintf(linebuffer, sizeof(linebuffer) - 1, "Label: '%s'", di.diskname);
|
||||
infotext.push_back(linebuffer);
|
||||
infotext.emplace_back(linebuffer);
|
||||
}
|
||||
infotext.push_back("");
|
||||
infotext.emplace_back("");
|
||||
|
||||
if (di.bootblockinfo[0]) {
|
||||
infotext.push_back("Amiga Bootblock Reader database detected:");
|
||||
infotext.emplace_back("Amiga Bootblock Reader database detected:");
|
||||
snprintf(linebuffer, sizeof(linebuffer) - 1, "Name: '%s'", di.bootblockinfo);
|
||||
infotext.push_back(linebuffer);
|
||||
infotext.emplace_back(linebuffer);
|
||||
if (di.bootblockclass[0]) {
|
||||
snprintf(linebuffer, sizeof(linebuffer) - 1, "Class: '%s'", di.bootblockclass);
|
||||
infotext.push_back(linebuffer);
|
||||
infotext.emplace_back(linebuffer);
|
||||
}
|
||||
infotext.push_back("");
|
||||
infotext.emplace_back("");
|
||||
}
|
||||
|
||||
int w = 16;
|
||||
@ -1163,13 +1050,13 @@ void DisplayDiskInfo(int num)
|
||||
}
|
||||
linebuffer[w * 3] = ' ';
|
||||
linebuffer[w * 3 + 1 + w] = 0;
|
||||
infotext.push_back(linebuffer);
|
||||
infotext.emplace_back(linebuffer);
|
||||
}
|
||||
|
||||
ShowDiskInfo(title, infotext);
|
||||
}
|
||||
|
||||
void save_mapping_to_file(std::string mapping)
|
||||
void save_mapping_to_file(const std::string& mapping)
|
||||
{
|
||||
std::string filename = get_controllers_path();
|
||||
filename.append("gamecontrollerdb_user.txt");
|
||||
@ -1178,7 +1065,7 @@ void save_mapping_to_file(std::string mapping)
|
||||
file_output.open(filename, ios::app);
|
||||
if (file_output.is_open())
|
||||
{
|
||||
file_output << std::endl << mapping << std::endl;
|
||||
file_output << '\n' << mapping << '\n';
|
||||
file_output.close();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1081,7 +1081,7 @@ static const TCHAR* get_joystick_friendlyname(const int joy)
|
||||
static const TCHAR* get_joystick_uniquename(const int joy)
|
||||
{
|
||||
TCHAR tmp[MAX_DPATH];
|
||||
_stprintf(tmp, _T("JOY%d"), joy);
|
||||
_sntprintf(tmp, MAX_DPATH, _T("JOY%d"), joy);
|
||||
return my_strdup(tmp);
|
||||
}
|
||||
|
||||
|
||||
@ -31,7 +31,7 @@ enum
|
||||
A1200_CONFIG = 2 // 8MB fast ram
|
||||
};
|
||||
|
||||
struct game_options
|
||||
struct game_hardware_options
|
||||
{
|
||||
std::string port0 = "nul";
|
||||
std::string port1 = "nul";
|
||||
@ -71,12 +71,6 @@ TCHAR uae_config[255];
|
||||
TCHAR whd_config[255];
|
||||
TCHAR whd_startup[255];
|
||||
|
||||
TCHAR game_name[MAX_DPATH];
|
||||
TCHAR selected_slave[MAX_DPATH];
|
||||
TCHAR sub_path[MAX_DPATH];
|
||||
TCHAR data_path[MAX_DPATH];
|
||||
TCHAR use_slave_libs = false;
|
||||
|
||||
static TCHAR* parse_text(const TCHAR* s)
|
||||
{
|
||||
if (*s == '"' || *s == '\'')
|
||||
@ -147,11 +141,11 @@ void parse_cfg_line(uae_prefs* prefs, const std::string& line_string)
|
||||
xfree(line);
|
||||
}
|
||||
|
||||
void parse_custom_settings(uae_prefs* p, const char* settings)
|
||||
void parse_custom_settings(uae_prefs* p, const std::string& settings)
|
||||
{
|
||||
const std::string lf = "\n";
|
||||
const std::string check = "amiberry_custom";
|
||||
auto full_line = trim_full_line(string(settings));
|
||||
auto full_line = trim_full_line(settings);
|
||||
|
||||
auto lf_found = full_line.find(lf);
|
||||
while (lf_found != std::string::npos)
|
||||
@ -173,38 +167,38 @@ void parse_custom_settings(uae_prefs* p, const char* settings)
|
||||
}
|
||||
}
|
||||
|
||||
std::string find_whdload_game_option(const TCHAR* find_setting, const char* whd_options)
|
||||
std::string find_whdload_game_option(const std::string& find_setting, const std::string& whd_options)
|
||||
{
|
||||
return find_substring(string(find_setting), string(whd_options));
|
||||
return find_substring(find_setting, whd_options);
|
||||
}
|
||||
|
||||
game_options get_game_settings(const char* HW)
|
||||
game_hardware_options get_game_hardware_settings(const std::string& hardware)
|
||||
{
|
||||
game_options output_detail;
|
||||
output_detail.port0 = find_whdload_game_option("PORT0", HW);
|
||||
output_detail.port1 = find_whdload_game_option("PORT1", HW);
|
||||
output_detail.control = find_whdload_game_option("PRIMARY_CONTROL", HW);
|
||||
output_detail.control2 = find_whdload_game_option("SECONDARY_CONTROL", HW);
|
||||
output_detail.cpu = find_whdload_game_option("CPU", HW);
|
||||
output_detail.blitter = find_whdload_game_option("BLITTER", HW);
|
||||
output_detail.clock = find_whdload_game_option("CLOCK", HW);
|
||||
output_detail.chipset = find_whdload_game_option("CHIPSET", HW);
|
||||
output_detail.jit = find_whdload_game_option("JIT", HW);
|
||||
output_detail.cpu_24bit = find_whdload_game_option("CPU_24BITADDRESSING", HW);
|
||||
output_detail.cpu_comp = find_whdload_game_option("CPU_COMPATIBLE", HW);
|
||||
output_detail.sprites = find_whdload_game_option("SPRITES", HW);
|
||||
output_detail.scr_height = find_whdload_game_option("SCREEN_HEIGHT", HW);
|
||||
output_detail.scr_width = find_whdload_game_option("SCREEN_WIDTH", HW);
|
||||
output_detail.scr_autoheight = find_whdload_game_option("SCREEN_AUTOHEIGHT", HW);
|
||||
output_detail.scr_centerh = find_whdload_game_option("SCREEN_CENTERH", HW);
|
||||
output_detail.scr_centerv = find_whdload_game_option("SCREEN_CENTERV", HW);
|
||||
output_detail.scr_offseth = find_whdload_game_option("SCREEN_OFFSETH", HW);
|
||||
output_detail.scr_offsetv = find_whdload_game_option("SCREEN_OFFSETV", HW);
|
||||
output_detail.ntsc = find_whdload_game_option("NTSC", HW);
|
||||
output_detail.fast = find_whdload_game_option("FAST_RAM", HW);
|
||||
output_detail.z3 = find_whdload_game_option("Z3_RAM", HW);
|
||||
output_detail.cpu_exact = find_whdload_game_option("CPU_EXACT", HW);
|
||||
output_detail.fastcopper = find_whdload_game_option("FAST_COPPER", HW);
|
||||
game_hardware_options output_detail;
|
||||
output_detail.port0 = find_whdload_game_option("PORT0", hardware);
|
||||
output_detail.port1 = find_whdload_game_option("PORT1", hardware);
|
||||
output_detail.control = find_whdload_game_option("PRIMARY_CONTROL", hardware);
|
||||
output_detail.control2 = find_whdload_game_option("SECONDARY_CONTROL", hardware);
|
||||
output_detail.cpu = find_whdload_game_option("CPU", hardware);
|
||||
output_detail.blitter = find_whdload_game_option("BLITTER", hardware);
|
||||
output_detail.clock = find_whdload_game_option("CLOCK", hardware);
|
||||
output_detail.chipset = find_whdload_game_option("CHIPSET", hardware);
|
||||
output_detail.jit = find_whdload_game_option("JIT", hardware);
|
||||
output_detail.cpu_24bit = find_whdload_game_option("CPU_24BITADDRESSING", hardware);
|
||||
output_detail.cpu_comp = find_whdload_game_option("CPU_COMPATIBLE", hardware);
|
||||
output_detail.sprites = find_whdload_game_option("SPRITES", hardware);
|
||||
output_detail.scr_height = find_whdload_game_option("SCREEN_HEIGHT", hardware);
|
||||
output_detail.scr_width = find_whdload_game_option("SCREEN_WIDTH", hardware);
|
||||
output_detail.scr_autoheight = find_whdload_game_option("SCREEN_AUTOHEIGHT", hardware);
|
||||
output_detail.scr_centerh = find_whdload_game_option("SCREEN_CENTERH", hardware);
|
||||
output_detail.scr_centerv = find_whdload_game_option("SCREEN_CENTERV", hardware);
|
||||
output_detail.scr_offseth = find_whdload_game_option("SCREEN_OFFSETH", hardware);
|
||||
output_detail.scr_offsetv = find_whdload_game_option("SCREEN_OFFSETV", hardware);
|
||||
output_detail.ntsc = find_whdload_game_option("NTSC", hardware);
|
||||
output_detail.fast = find_whdload_game_option("FAST_RAM", hardware);
|
||||
output_detail.z3 = find_whdload_game_option("Z3_RAM", hardware);
|
||||
output_detail.cpu_exact = find_whdload_game_option("CPU_EXACT", hardware);
|
||||
output_detail.fastcopper = find_whdload_game_option("FAST_COPPER", hardware);
|
||||
|
||||
return output_detail;
|
||||
}
|
||||
@ -289,11 +283,11 @@ void symlink_roms(struct uae_prefs* prefs)
|
||||
}
|
||||
}
|
||||
|
||||
void get_game_name(char* filepath)
|
||||
std::string get_game_filename(const char* filepath)
|
||||
{
|
||||
extract_filename(filepath, last_loaded_config);
|
||||
extract_filename(filepath, game_name);
|
||||
remove_file_extension(game_name);
|
||||
const std::string game_name = extract_filename(filepath);
|
||||
return remove_file_extension(game_name);
|
||||
}
|
||||
|
||||
void set_jport_modes(uae_prefs* prefs, const bool is_cd32)
|
||||
@ -322,10 +316,10 @@ void clear_jports(uae_prefs* prefs)
|
||||
}
|
||||
}
|
||||
|
||||
void build_uae_config_filename()
|
||||
void build_uae_config_filename(const std::string& game_name)
|
||||
{
|
||||
_tcscpy(uae_config, conf_path);
|
||||
_tcscat(uae_config, game_name);
|
||||
_tcscat(uae_config, game_name.c_str());
|
||||
_tcscat(uae_config, ".uae");
|
||||
}
|
||||
|
||||
@ -336,11 +330,11 @@ void cd_auto_prefs(uae_prefs* prefs, char* filepath)
|
||||
write_log("\nCD Autoload: %s \n\n", filepath);
|
||||
|
||||
get_configuration_path(conf_path, MAX_DPATH);
|
||||
get_game_name(filepath);
|
||||
whdload_prefs.filename = get_game_filename(filepath);
|
||||
|
||||
// LOAD GAME SPECIFICS FOR EXISTING .UAE - USE SHA1 IF AVAILABLE
|
||||
// CONFIG LOAD IF .UAE IS IN CONFIG PATH
|
||||
build_uae_config_filename();
|
||||
build_uae_config_filename(whdload_prefs.filename);
|
||||
|
||||
if (my_existsfile2(uae_config))
|
||||
{
|
||||
@ -374,11 +368,11 @@ void cd_auto_prefs(uae_prefs* prefs, char* filepath)
|
||||
}
|
||||
|
||||
// enable CD
|
||||
_stprintf(tmp, "cd32cd=1");
|
||||
_sntprintf(tmp, MAX_DPATH, "cd32cd=1");
|
||||
cfgfile_parse_line(prefs, parse_text(tmp), 0);
|
||||
|
||||
// mount the image
|
||||
_stprintf(tmp, "cdimage0=%s,image", filepath);
|
||||
_sntprintf(tmp, MAX_DPATH, "cdimage0=%s,image", filepath);
|
||||
cfgfile_parse_line(prefs, parse_text(tmp), 0);
|
||||
|
||||
//APPLY THE SETTINGS FOR MOUSE/JOYSTICK ETC
|
||||
@ -422,7 +416,7 @@ void cd_auto_prefs(uae_prefs* prefs, char* filepath)
|
||||
}
|
||||
}
|
||||
|
||||
void set_input_settings(uae_prefs* prefs, const game_options& game_detail, const bool is_cd32)
|
||||
void set_input_settings(uae_prefs* prefs, const game_hardware_options& game_detail, const bool is_cd32)
|
||||
{
|
||||
// APPLY SPECIAL CONFIG E.G. MOUSE OR ALT. JOYSTICK SETTINGS
|
||||
clear_jports(prefs);
|
||||
@ -503,7 +497,7 @@ void set_input_settings(uae_prefs* prefs, const game_options& game_detail, const
|
||||
}
|
||||
}
|
||||
|
||||
void parse_gfx_settings(uae_prefs* prefs, const game_options& game_detail)
|
||||
void set_gfx_settings(uae_prefs* prefs, const game_hardware_options& game_detail)
|
||||
{
|
||||
std::string line_string;
|
||||
// SCREEN AUTO-HEIGHT
|
||||
@ -680,7 +674,7 @@ void parse_gfx_settings(uae_prefs* prefs, const game_options& game_detail)
|
||||
}
|
||||
}
|
||||
|
||||
void set_compatibility_settings(uae_prefs* prefs, const game_options& game_detail, const bool a600_available, const bool use_aga)
|
||||
void set_compatibility_settings(uae_prefs* prefs, const game_hardware_options& game_detail, const bool a600_available, const bool use_aga)
|
||||
{
|
||||
std::string line_string;
|
||||
// CPU 68020/040 or no A600 ROM available
|
||||
@ -835,17 +829,170 @@ void set_compatibility_settings(uae_prefs* prefs, const game_options& game_detai
|
||||
// Screen settings, only if allowed to override the defaults from amiberry.conf
|
||||
if (amiberry_options.allow_display_settings_from_xml)
|
||||
{
|
||||
parse_gfx_settings(prefs, game_detail);
|
||||
set_gfx_settings(prefs, game_detail);
|
||||
}
|
||||
}
|
||||
|
||||
game_options parse_settings_from_xml(uae_prefs* prefs, const char* filepath)
|
||||
void parse_slave_custom_fields(whdload_slave& slave, const std::string& custom)
|
||||
{
|
||||
game_options game_detail{};
|
||||
std::istringstream stream(custom);
|
||||
std::string line;
|
||||
|
||||
while (std::getline(stream, line)) {
|
||||
if (line.find("C1") != std::string::npos || line.find("C2") != std::string::npos ||
|
||||
line.find("C3") != std::string::npos || line.find("C4") != std::string::npos ||
|
||||
line.find("C5") != std::string::npos) {
|
||||
|
||||
std::istringstream lineStream(line);
|
||||
std::string segment;
|
||||
std::vector<std::string> seglist;
|
||||
|
||||
while (std::getline(lineStream, segment, ':')) {
|
||||
segment.erase(std::remove(segment.begin(), segment.end(), '\t'), segment.end());
|
||||
seglist.push_back(segment);
|
||||
}
|
||||
|
||||
// Process seglist as needed
|
||||
if (seglist[0] == "C1")
|
||||
{
|
||||
if (seglist[1] == "B")
|
||||
{
|
||||
slave.custom1.type = bool_type;
|
||||
slave.custom1.caption = seglist[2];
|
||||
slave.custom1.value = 0;
|
||||
}
|
||||
else if (seglist[1] == "X")
|
||||
{
|
||||
slave.custom1.type = bit_type;
|
||||
slave.custom1.value = 0;
|
||||
slave.custom1.label_bit_pairs.insert(slave.custom1.label_bit_pairs.end(), { seglist[2], stoi(seglist[3]) });
|
||||
}
|
||||
else if (seglist[1] == "L")
|
||||
{
|
||||
slave.custom1.type = list_type;
|
||||
slave.custom1.caption = seglist[2];
|
||||
slave.custom1.value = 0;
|
||||
std::string token;
|
||||
std::istringstream token_stream(seglist[3]);
|
||||
while (std::getline(token_stream, token, ',')) {
|
||||
slave.custom1.labels.push_back(token);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (seglist[0] == "C2")
|
||||
{
|
||||
if (seglist[1] == "B")
|
||||
{
|
||||
slave.custom2.type = bool_type;
|
||||
slave.custom2.caption = seglist[2];
|
||||
slave.custom2.value = 0;
|
||||
}
|
||||
else if (seglist[1] == "X")
|
||||
{
|
||||
slave.custom2.type = bit_type;
|
||||
slave.custom2.value = 0;
|
||||
slave.custom2.label_bit_pairs.insert(slave.custom2.label_bit_pairs.end(), { seglist[2], stoi(seglist[3]) });
|
||||
}
|
||||
else if (seglist[1] == "L")
|
||||
{
|
||||
slave.custom2.type = list_type;
|
||||
slave.custom2.caption = seglist[2];
|
||||
slave.custom2.value = 0;
|
||||
std::string token;
|
||||
std::istringstream token_stream(seglist[3]);
|
||||
while (std::getline(token_stream, token, ',')) {
|
||||
slave.custom2.labels.push_back(token);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (seglist[0] == "C3")
|
||||
{
|
||||
if (seglist[1] == "B")
|
||||
{
|
||||
slave.custom3.type = bool_type;
|
||||
slave.custom3.caption = seglist[2];
|
||||
slave.custom3.value = 0;
|
||||
}
|
||||
else if (seglist[1] == "X")
|
||||
{
|
||||
slave.custom3.type = bit_type;
|
||||
slave.custom3.value = 0;
|
||||
slave.custom3.label_bit_pairs.insert(slave.custom3.label_bit_pairs.end(), { seglist[2], stoi(seglist[3]) });
|
||||
}
|
||||
else if (seglist[1] == "L")
|
||||
{
|
||||
slave.custom3.type = list_type;
|
||||
slave.custom3.caption = seglist[2];
|
||||
slave.custom3.value = 0;
|
||||
std::string token;
|
||||
std::istringstream token_stream(seglist[3]);
|
||||
while (std::getline(token_stream, token, ',')) {
|
||||
slave.custom3.labels.push_back(token);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (seglist[0] == "C4")
|
||||
{
|
||||
if (seglist[1] == "B")
|
||||
{
|
||||
slave.custom4.type = bool_type;
|
||||
slave.custom4.caption = seglist[2];
|
||||
slave.custom4.value = 0;
|
||||
}
|
||||
else if (seglist[1] == "X")
|
||||
{
|
||||
slave.custom4.type = bit_type;
|
||||
slave.custom4.value = 0;
|
||||
slave.custom4.label_bit_pairs.insert(slave.custom4.label_bit_pairs.end(), { seglist[2], stoi(seglist[3]) });
|
||||
}
|
||||
else if (seglist[1] == "L")
|
||||
{
|
||||
slave.custom4.type = list_type;
|
||||
slave.custom4.caption = seglist[2];
|
||||
slave.custom4.value = 0;
|
||||
std::string token;
|
||||
std::istringstream token_stream(seglist[3]);
|
||||
while (std::getline(token_stream, token, ',')) {
|
||||
slave.custom4.labels.push_back(token);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (seglist[0] == "C5")
|
||||
{
|
||||
if (seglist[1] == "B")
|
||||
{
|
||||
slave.custom5.type = bool_type;
|
||||
slave.custom5.caption = seglist[2];
|
||||
slave.custom5.value = 0;
|
||||
}
|
||||
else if (seglist[1] == "X")
|
||||
{
|
||||
slave.custom5.type = bit_type;
|
||||
slave.custom5.value = 0;
|
||||
slave.custom5.label_bit_pairs.insert(slave.custom5.label_bit_pairs.end(), { seglist[2], stoi(seglist[3]) });
|
||||
}
|
||||
else if (seglist[1] == "L")
|
||||
{
|
||||
slave.custom5.type = list_type;
|
||||
slave.custom5.caption = seglist[2];
|
||||
slave.custom5.value = 0;
|
||||
std::string token;
|
||||
std::istringstream token_stream(seglist[3]);
|
||||
while (std::getline(token_stream, token, ',')) {
|
||||
slave.custom5.labels.push_back(token);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
game_hardware_options parse_settings_from_xml(uae_prefs* prefs, const char* filepath)
|
||||
{
|
||||
game_hardware_options game_detail{};
|
||||
tinyxml2::XMLDocument doc;
|
||||
auto error = false;
|
||||
write_log("WHDBooter - Loading whdload_db.xml\n");
|
||||
write_log("WHDBooter - Searching whdload_db.xml for %s\n", game_name);
|
||||
write_log(_T("WHDBooter - Searching whdload_db.xml for %s\n"), whdload_prefs.filename.c_str());
|
||||
|
||||
auto* f = fopen(whd_config, _T("rb"));
|
||||
if (f)
|
||||
@ -875,85 +1022,117 @@ game_options parse_settings_from_xml(uae_prefs* prefs, const char* filepath)
|
||||
// then fall back to sha1 if a user has renamed the file!
|
||||
//
|
||||
int found = 0;
|
||||
if (game_node->Attribute("filename", game_name))
|
||||
{
|
||||
found = 1;
|
||||
}
|
||||
if (game_node->Attribute("sha1", sha1.c_str()))
|
||||
if (game_node->Attribute("filename", whdload_prefs.filename.c_str()) ||
|
||||
game_node->Attribute("sha1", sha1.c_str()))
|
||||
{
|
||||
found = 1;
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
// now get the <hardware> and <custom_controls> items
|
||||
// Name
|
||||
auto xml_element = game_node->FirstChildElement("name");
|
||||
if (xml_element)
|
||||
{
|
||||
whdload_prefs.game_name.assign(xml_element->GetText());
|
||||
}
|
||||
|
||||
// Sub Path
|
||||
xml_element = game_node->FirstChildElement("subpath");
|
||||
if (xml_element)
|
||||
{
|
||||
whdload_prefs.sub_path.assign(xml_element->GetText());
|
||||
}
|
||||
|
||||
// Variant UUID
|
||||
xml_element = game_node->FirstChildElement("variant_uuid");
|
||||
if (xml_element)
|
||||
{
|
||||
whdload_prefs.variant_uuid.assign(xml_element->GetText());
|
||||
}
|
||||
|
||||
// Slave count
|
||||
xml_element = game_node->FirstChildElement("slave_count");
|
||||
if (xml_element)
|
||||
{
|
||||
whdload_prefs.slave_count = xml_element->IntText(0);
|
||||
}
|
||||
|
||||
// Default slave
|
||||
xml_element = game_node->FirstChildElement("slave_default");
|
||||
if (xml_element)
|
||||
{
|
||||
whdload_prefs.slave_default.assign(xml_element->GetText());
|
||||
write_log("WHDBooter - Selected Slave: %s \n", whdload_prefs.slave_default.c_str());
|
||||
}
|
||||
|
||||
// Slave_libraries
|
||||
xml_element = game_node->FirstChildElement("slave_libraries");
|
||||
if (xml_element->GetText() != nullptr)
|
||||
{
|
||||
if (strcmpi(xml_element->GetText(), "true") == 0)
|
||||
whdload_prefs.slave_libraries = true;
|
||||
}
|
||||
|
||||
// Get slaves and settings
|
||||
xml_element = game_node->FirstChildElement("slave");
|
||||
whdload_prefs.slaves.clear();
|
||||
|
||||
for (int i = 0; i < whdload_prefs.slave_count && xml_element; ++i)
|
||||
{
|
||||
whdload_slave slave;
|
||||
const char* slave_text = nullptr;
|
||||
|
||||
slave_text = xml_element->FirstChildElement("filename")->GetText();
|
||||
if (slave_text)
|
||||
slave.filename.assign(slave_text);
|
||||
|
||||
slave_text = xml_element->FirstChildElement("datapath")->GetText();
|
||||
if (slave_text)
|
||||
slave.data_path.assign(slave_text);
|
||||
|
||||
auto customElement = xml_element->FirstChildElement("custom");
|
||||
if (customElement && ((slave_text = customElement->GetText())))
|
||||
{
|
||||
auto custom = std::string(slave_text);
|
||||
parse_slave_custom_fields(slave, custom);
|
||||
}
|
||||
|
||||
whdload_prefs.slaves.emplace_back(slave);
|
||||
|
||||
// Set the default slave as the selected one
|
||||
if (slave.filename == whdload_prefs.slave_default)
|
||||
whdload_prefs.selected_slave = slave;
|
||||
|
||||
xml_element = xml_element->NextSiblingElement("slave");
|
||||
}
|
||||
|
||||
// get hardware
|
||||
const auto* temp_node = game_node->FirstChildElement("hardware");
|
||||
if (temp_node)
|
||||
xml_element = game_node->FirstChildElement("hardware");
|
||||
if (xml_element)
|
||||
{
|
||||
const auto* hardware = temp_node->GetText();
|
||||
if (hardware)
|
||||
std::string hardware;
|
||||
hardware.assign(xml_element->GetText());
|
||||
if (!hardware.empty())
|
||||
{
|
||||
game_detail = get_game_settings(hardware);
|
||||
write_log("WHDBooter - Game H/W Settings: \n%s\n", hardware);
|
||||
game_detail = get_game_hardware_settings(hardware);
|
||||
write_log("WHDBooter - Game H/W Settings: \n%s\n", hardware.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// get custom controls
|
||||
temp_node = game_node->FirstChildElement("custom_controls");
|
||||
if (temp_node)
|
||||
xml_element = game_node->FirstChildElement("custom_controls");
|
||||
if (xml_element)
|
||||
{
|
||||
const auto* custom_settings = temp_node->GetText();
|
||||
if (custom_settings)
|
||||
std::string custom_settings;
|
||||
custom_settings.assign(xml_element->GetText());
|
||||
if (!custom_settings.empty())
|
||||
{
|
||||
write_log("WHDBooter - Game Custom Settings: \n%s\n", custom_settings);
|
||||
parse_custom_settings(prefs, custom_settings);
|
||||
write_log("WHDBooter - Game Custom Settings: \n%s\n", custom_settings.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if (strlen(selected_slave) == 0)
|
||||
{
|
||||
temp_node = game_node->FirstChildElement("slave_default");
|
||||
|
||||
// use a selected slave if we have one
|
||||
if (strlen(prefs->whdbootprefs.slave) != 0)
|
||||
{
|
||||
_tcscpy(selected_slave, prefs->whdbootprefs.slave);
|
||||
write_log("WHDBooter - Config Selected Slave: %s \n", selected_slave);
|
||||
}
|
||||
// otherwise use the XML default
|
||||
else if (temp_node->GetText() != nullptr)
|
||||
{
|
||||
_stprintf(selected_slave, "%s", temp_node->GetText());
|
||||
write_log("WHDBooter - Default Slave: %s\n", selected_slave);
|
||||
}
|
||||
|
||||
temp_node = game_node->FirstChildElement("subpath");
|
||||
|
||||
if (temp_node->GetText() != nullptr)
|
||||
{
|
||||
_stprintf(sub_path, "%s", temp_node->GetText());
|
||||
write_log("WHDBooter - SubPath: %s\n", sub_path);
|
||||
}
|
||||
}
|
||||
|
||||
// get slave_libraries
|
||||
temp_node = game_node->FirstChildElement("slave_libraries");
|
||||
if (temp_node->GetText() != nullptr)
|
||||
{
|
||||
if (strcmpi(temp_node->GetText(), "true") == 0)
|
||||
use_slave_libs = true;
|
||||
|
||||
write_log("WHDBooter - Libraries: %s\n", sub_path);
|
||||
}
|
||||
|
||||
// get data path
|
||||
temp_node = game_node->FirstChildElement("slave")->FirstChildElement("datapath");
|
||||
if (temp_node && temp_node->GetText() != nullptr)
|
||||
{
|
||||
_stprintf(data_path, "%s", temp_node->GetText());
|
||||
write_log("WHDBooter - Data Path: %s\n", data_path);
|
||||
}
|
||||
break;
|
||||
}
|
||||
game_node = game_node->NextSiblingElement();
|
||||
@ -962,12 +1141,12 @@ game_options parse_settings_from_xml(uae_prefs* prefs, const char* filepath)
|
||||
return game_detail;
|
||||
}
|
||||
|
||||
void create_startup_sequence(uae_prefs* prefs)
|
||||
void create_startup_sequence()
|
||||
{
|
||||
std::ostringstream whd_bootscript;
|
||||
whd_bootscript << "FAILAT 999\n";
|
||||
|
||||
if (use_slave_libs)
|
||||
if (whdload_prefs.slave_libraries)
|
||||
{
|
||||
whd_bootscript << "DH3:C/Assign LIBS: DH3:LIBS/ ADD\n";
|
||||
}
|
||||
@ -976,74 +1155,57 @@ void create_startup_sequence(uae_prefs* prefs)
|
||||
whd_bootscript << "DH3:C/Assign C: DH3:C/ ADD\n";
|
||||
whd_bootscript << "ENDIF\n";
|
||||
|
||||
whd_bootscript << "CD \"Games:" << sub_path << "\"\n";
|
||||
whd_bootscript << "WHDLoad SLAVE=\"Games:" << sub_path << "/" << selected_slave << "\"";
|
||||
whd_bootscript << "CD \"Games:" << whdload_prefs.sub_path << "\"\n";
|
||||
whd_bootscript << "WHDLoad SLAVE=\"Games:" << whdload_prefs.sub_path << "/" << whdload_prefs.selected_slave.filename << "\"";
|
||||
|
||||
// Write Cache
|
||||
if (prefs->whdbootprefs.writecache)
|
||||
whd_bootscript << " PRELOAD NOREQ";
|
||||
if (!whdload_prefs.write_cache)
|
||||
{
|
||||
whd_bootscript << " PRELOAD NOREQ";
|
||||
}
|
||||
else
|
||||
{
|
||||
whd_bootscript << " PRELOAD NOREQ NOWRITECACHE";
|
||||
whd_bootscript << " NOWRITECACHE";
|
||||
}
|
||||
|
||||
// CUSTOM options
|
||||
if (prefs->whdbootprefs.custom1 > 0)
|
||||
{
|
||||
whd_bootscript << " CUSTOM1=" << prefs->whdbootprefs.custom1;
|
||||
for (int i = 1; i <= 5; ++i) {
|
||||
auto& custom = whdload_prefs.selected_slave.get_custom(i);
|
||||
if (custom.type != none && custom.value != 0) {
|
||||
whd_bootscript << " CUSTOM" << i << "=" << custom.value;
|
||||
}
|
||||
}
|
||||
if (prefs->whdbootprefs.custom2 > 0)
|
||||
if (!whdload_prefs.custom.empty())
|
||||
{
|
||||
whd_bootscript << " CUSTOM2=" << prefs->whdbootprefs.custom2;
|
||||
}
|
||||
if (prefs->whdbootprefs.custom3 > 0)
|
||||
{
|
||||
whd_bootscript << " CUSTOM3=" << prefs->whdbootprefs.custom3;
|
||||
}
|
||||
if (prefs->whdbootprefs.custom4 > 0)
|
||||
{
|
||||
whd_bootscript << " CUSTOM4=" << prefs->whdbootprefs.custom4;
|
||||
}
|
||||
if (prefs->whdbootprefs.custom5 > 0)
|
||||
{
|
||||
whd_bootscript << " CUSTOM5=" << prefs->whdbootprefs.custom5;
|
||||
}
|
||||
if (strlen(prefs->whdbootprefs.custom) != 0)
|
||||
{
|
||||
whd_bootscript << " CUSTOM=\"" << prefs->whdbootprefs.custom << "\"";
|
||||
whd_bootscript << " CUSTOM=\"" << whdload_prefs.custom << "\"";
|
||||
}
|
||||
|
||||
// BUTTONWAIT
|
||||
if (prefs->whdbootprefs.buttonwait)
|
||||
if (whdload_prefs.button_wait)
|
||||
{
|
||||
whd_bootscript << " BUTTONWAIT";
|
||||
}
|
||||
|
||||
// SPLASH
|
||||
if (!prefs->whdbootprefs.showsplash)
|
||||
if (!whdload_prefs.show_splash)
|
||||
{
|
||||
whd_bootscript << " SPLASHDELAY=0";
|
||||
}
|
||||
|
||||
// CONFIGDELAY
|
||||
if (prefs->whdbootprefs.configdelay != 0)
|
||||
if (whdload_prefs.config_delay != 0)
|
||||
{
|
||||
whd_bootscript << " CONFIGDELAY=" << prefs->whdbootprefs.configdelay;
|
||||
whd_bootscript << " CONFIGDELAY=" << whdload_prefs.config_delay;
|
||||
}
|
||||
|
||||
// SPECIAL SAVE PATH
|
||||
whd_bootscript << " SAVEPATH=Saves:Savegames/ SAVEDIR=\"" << sub_path << "\"";
|
||||
whd_bootscript << " SAVEPATH=Saves:Savegames/ SAVEDIR=\"" << whdload_prefs.sub_path << "\"";
|
||||
|
||||
// DATA PATH
|
||||
if (data_path[0])
|
||||
whd_bootscript << "DATA=\"" << data_path << "\"";
|
||||
if (!whdload_prefs.selected_slave.data_path.empty())
|
||||
whd_bootscript << " DATA=\"" << whdload_prefs.selected_slave.data_path << "\"";
|
||||
|
||||
whd_bootscript << '\n';
|
||||
|
||||
// Launches utility program to quit the emulator (via a UAE trap in RTAREA)
|
||||
if (prefs->whdbootprefs.quit_on_exit)
|
||||
if (whdload_prefs.quit_on_exit)
|
||||
{
|
||||
whd_bootscript << "DH0:C/AmiQuit\n";
|
||||
}
|
||||
@ -1066,28 +1228,28 @@ bool is_a600_available(uae_prefs* prefs)
|
||||
return rom_test == 1;
|
||||
}
|
||||
|
||||
void set_booter_drives(uae_prefs* prefs, char* filepath)
|
||||
void set_booter_drives(uae_prefs* prefs, const char* filepath)
|
||||
{
|
||||
TCHAR tmp[MAX_DPATH];
|
||||
|
||||
if (strlen(selected_slave) != 0) // new booter solution
|
||||
if (!whdload_prefs.selected_slave.filename.empty()) // new booter solution
|
||||
{
|
||||
_sntprintf(boot_path, MAX_DPATH, "/tmp/amiberry/");
|
||||
|
||||
_stprintf(tmp, _T("filesystem2=rw,DH0:DH0:%s,10"), boot_path);
|
||||
_sntprintf(tmp, MAX_DPATH, _T("filesystem2=rw,DH0:DH0:%s,10"), boot_path);
|
||||
cfgfile_parse_line(prefs, parse_text(tmp), 0);
|
||||
|
||||
_stprintf(tmp, _T("uaehf0=dir,rw,DH0:DH0::%s,10"), boot_path);
|
||||
_sntprintf(tmp, MAX_DPATH, _T("uaehf0=dir,rw,DH0:DH0::%s,10"), boot_path);
|
||||
cfgfile_parse_line(prefs, parse_text(tmp), 0);
|
||||
|
||||
_sntprintf(boot_path, MAX_DPATH, "%sboot-data.zip", whdbooter_path.c_str());
|
||||
if (!my_existsfile2(boot_path))
|
||||
_sntprintf(boot_path, MAX_DPATH, "%sboot-data/", whdbooter_path.c_str());
|
||||
|
||||
_stprintf(tmp, _T("filesystem2=rw,DH3:DH3:%s,-10"), boot_path);
|
||||
_sntprintf(tmp, MAX_DPATH, _T("filesystem2=rw,DH3:DH3:%s,-10"), boot_path);
|
||||
cfgfile_parse_line(prefs, parse_text(tmp), 0);
|
||||
|
||||
_stprintf(tmp, _T("uaehf0=dir,rw,DH3:DH3::%s,-10"), boot_path);
|
||||
_sntprintf(tmp, MAX_DPATH, _T("uaehf0=dir,rw,DH3:DH3::%s,-10"), boot_path);
|
||||
cfgfile_parse_line(prefs, parse_text(tmp), 0);
|
||||
}
|
||||
else // revert to original booter is no slave was set
|
||||
@ -1096,18 +1258,18 @@ void set_booter_drives(uae_prefs* prefs, char* filepath)
|
||||
if (!my_existsfile2(boot_path))
|
||||
_sntprintf(boot_path, MAX_DPATH, "%sboot-data/", whdbooter_path.c_str());
|
||||
|
||||
_stprintf(tmp, _T("filesystem2=rw,DH0:DH0:%s,10"), boot_path);
|
||||
_sntprintf(tmp, MAX_DPATH, _T("filesystem2=rw,DH0:DH0:%s,10"), boot_path);
|
||||
cfgfile_parse_line(prefs, parse_text(tmp), 0);
|
||||
|
||||
_stprintf(tmp, _T("uaehf0=dir,rw,DH0:DH0::%s,10"), boot_path);
|
||||
_sntprintf(tmp, MAX_DPATH, _T("uaehf0=dir,rw,DH0:DH0::%s,10"), boot_path);
|
||||
cfgfile_parse_line(prefs, parse_text(tmp), 0);
|
||||
}
|
||||
|
||||
//set the Second (game data) drive
|
||||
_stprintf(tmp, "filesystem2=rw,DH1:Games:\"%s\",0", filepath);
|
||||
_sntprintf(tmp, MAX_DPATH, "filesystem2=rw,DH1:Games:\"%s\",0", filepath);
|
||||
cfgfile_parse_line(prefs, parse_text(tmp), 0);
|
||||
|
||||
_stprintf(tmp, "uaehf1=dir,rw,DH1:Games:\"%s\",0", filepath);
|
||||
_sntprintf(tmp, MAX_DPATH, "uaehf1=dir,rw,DH1:Games:\"%s\",0", filepath);
|
||||
cfgfile_parse_line(prefs, parse_text(tmp), 0);
|
||||
|
||||
//set the third (save data) drive
|
||||
@ -1115,18 +1277,17 @@ void set_booter_drives(uae_prefs* prefs, char* filepath)
|
||||
|
||||
if (my_existsdir(save_path))
|
||||
{
|
||||
_stprintf(tmp, "filesystem2=rw,DH2:Saves:%s,0", save_path);
|
||||
_sntprintf(tmp, MAX_DPATH, "filesystem2=rw,DH2:Saves:%s,0", save_path);
|
||||
cfgfile_parse_line(prefs, parse_text(tmp), 0);
|
||||
|
||||
_stprintf(tmp, "uaehf2=dir,rw,DH2:Saves:%s,0", save_path);
|
||||
_sntprintf(tmp, MAX_DPATH, "uaehf2=dir,rw,DH2:Saves:%s,0", save_path);
|
||||
cfgfile_parse_line(prefs, parse_text(tmp), 0);
|
||||
}
|
||||
}
|
||||
|
||||
void whdload_auto_prefs(uae_prefs* prefs, char* filepath)
|
||||
void whdload_auto_prefs(uae_prefs* prefs, const char* filepath)
|
||||
{
|
||||
write_log("WHDBooter Launched\n");
|
||||
_tcscpy(selected_slave, "");
|
||||
|
||||
get_configuration_path(conf_path, MAX_DPATH);
|
||||
whdbooter_path = get_whdbootpath();
|
||||
@ -1147,11 +1308,12 @@ void whdload_auto_prefs(uae_prefs* prefs, char* filepath)
|
||||
|
||||
// REMOVE THE FILE PATH AND EXTENSION
|
||||
const auto* filename = my_getfilepart(filepath);
|
||||
get_game_name(filepath);
|
||||
const std::string filename_no_extension = get_game_filename(filepath);
|
||||
whdload_prefs.filename = filename_no_extension;
|
||||
|
||||
// LOAD GAME SPECIFICS FOR EXISTING .UAE - USE SHA1 IF AVAILABLE
|
||||
// CONFIG LOAD IF .UAE IS IN CONFIG PATH
|
||||
build_uae_config_filename();
|
||||
build_uae_config_filename(whdload_prefs.filename);
|
||||
|
||||
// If we have a config file, we will use it.
|
||||
// We will need it for the WHDLoad options too.
|
||||
@ -1177,7 +1339,7 @@ void whdload_auto_prefs(uae_prefs* prefs, char* filepath)
|
||||
|
||||
// LOAD GAME SPECIFICS
|
||||
_sntprintf(whd_path, MAX_DPATH, "%sgame-data/", whdbooter_path.c_str());
|
||||
game_options game_detail;
|
||||
game_hardware_options game_detail;
|
||||
|
||||
_tcscpy(whd_config, whd_path);
|
||||
_tcscat(whd_config, "whdload_db.xml");
|
||||
@ -1192,9 +1354,9 @@ void whdload_auto_prefs(uae_prefs* prefs, char* filepath)
|
||||
}
|
||||
|
||||
// If we have a slave, create a startup-sequence
|
||||
if (strlen(selected_slave) != 0)
|
||||
if (!whdload_prefs.selected_slave.filename.empty())
|
||||
{
|
||||
create_startup_sequence(prefs);
|
||||
create_startup_sequence();
|
||||
}
|
||||
|
||||
// now we should have a startup-sequence file (if we don't, we are going to use the original booter)
|
||||
|
||||
@ -29,8 +29,8 @@ struct fs_stat {
|
||||
};
|
||||
|
||||
extern bool fs_path_exists(const std::string& s);
|
||||
extern std::string iso_8859_1_to_utf8(std::string& str);
|
||||
extern std::string iso_8859_1_to_utf8(const std::string& str);
|
||||
extern void utf8_to_latin1_string(std::string& input, std::string& output);
|
||||
extern std::string prefix_with_application_directory_path(std::string currentpath);
|
||||
extern std::string prefix_with_data_path(std::string filename);
|
||||
extern std::string prefix_with_whdboot_path(std::string filename);
|
||||
extern std::string prefix_with_whdboot_path(std::string filename);
|
||||
|
||||
@ -40,13 +40,14 @@ static NavigationMap navMap[] =
|
||||
{"Miscellaneous", "chkMouseUntrap", "chkMouseUntrap", "Disk swapper", "Priority"},
|
||||
{"Priority", "cboInactiveRunAtPrio", "cboActiveRunAtPrio", "Miscellaneous", "Savestates" },
|
||||
{"Savestates", "State0", "State0", "Priority", "Virtual Keyboard"},
|
||||
{"Virtual Keyboard", "chkVkEnabled", "chkVkEnabled", "Savestates", "Quit"},
|
||||
{"Shutdown", "Start", "Quit", "Virtual Keyboard", "About"},
|
||||
{"Quit", "Shutdown", "Restart", "Virtual Keyboard", "About"},
|
||||
{"Restart", "Quit", "Help", "Virtual Keyboard", "About"},
|
||||
{"Help", "Restart", "Reset", "Virtual Keyboard", "About"},
|
||||
{"Reset", "Help", "Start", "Virtual Keyboard", "About"},
|
||||
{"Start", "Reset", "Shutdown", "Virtual Keyboard", "About"},
|
||||
{"Virtual Keyboard", "chkVkEnabled", "chkVkEnabled", "Savestates", "WHDLoad"},
|
||||
{"WHDLoad", "", "", "Virtual Keyboard", "Quit"},
|
||||
{"Shutdown", "Start", "Quit", "WHDLoad", "About"},
|
||||
{"Quit", "Shutdown", "Restart", "WHDLoad", "About"},
|
||||
{"Restart", "Quit", "Help", "WHDLoad", "About"},
|
||||
{"Help", "Restart", "Reset", "WHDLoad", "About"},
|
||||
{"Reset", "Help", "Start", "WHDLoad", "About"},
|
||||
{"Start", "Reset", "Shutdown", "WHDLoad", "About"},
|
||||
|
||||
// PanelPaths
|
||||
{"cmdSystemROMs", "Paths", "Paths", "cmdRescanROMs", "cmdConfigPath"},
|
||||
|
||||
@ -334,7 +334,7 @@ void InitPanelCustom(const config_category& category)
|
||||
posY = txtPortInput->getY() + txtPortInput->getHeight() + DISTANCE_NEXT_Y;
|
||||
|
||||
// Column 1
|
||||
const auto column1 = 5;
|
||||
constexpr auto column1 = 5;
|
||||
for (i = 0; i < SDL_CONTROLLER_BUTTON_MAX / 2; i++)
|
||||
{
|
||||
category.panel->add(lblCustomButtonAction[i], column1, posY);
|
||||
|
||||
@ -150,7 +150,7 @@ public:
|
||||
if (strncmp(changed_prefs.dfxlist[i], tmp.c_str(), MAX_DPATH) != 0)
|
||||
{
|
||||
strncpy(changed_prefs.dfxlist[i], tmp.c_str(), MAX_DPATH);
|
||||
AddFileToDiskList(tmp.c_str(), 1);
|
||||
add_file_to_mru_list(lstMRUDiskList, tmp);
|
||||
}
|
||||
}
|
||||
cmdDiskSwapperListAdd[i]->requestFocus();
|
||||
@ -212,7 +212,7 @@ public:
|
||||
{
|
||||
disk_swap(row, 1);
|
||||
|
||||
AddFileToDiskList(changed_prefs.dfxlist[row], 1);
|
||||
add_file_to_mru_list(lstMRUDiskList, std::string(changed_prefs.dfxlist[row]));
|
||||
RefreshPanelDiskSwapper();
|
||||
RefreshPanelFloppy();
|
||||
RefreshPanelQuickstart();
|
||||
|
||||
@ -388,8 +388,8 @@ void InitPanelDisplay(const config_category& category)
|
||||
|
||||
lblHOffset = new gcn::Label("H. Offset:");
|
||||
lblHOffset->setAlignment(gcn::Graphics::LEFT);
|
||||
sldHOffset = new gcn::Slider(-60, 60);
|
||||
sldHOffset->setSize(135, SLIDER_HEIGHT);
|
||||
sldHOffset = new gcn::Slider(-80, 80);
|
||||
sldHOffset->setSize(200, SLIDER_HEIGHT);
|
||||
sldHOffset->setBaseColor(gui_baseCol);
|
||||
sldHOffset->setMarkerLength(20);
|
||||
sldHOffset->setStepLength(1);
|
||||
@ -400,8 +400,8 @@ void InitPanelDisplay(const config_category& category)
|
||||
|
||||
lblVOffset = new gcn::Label("V. Offset:");
|
||||
lblVOffset->setAlignment(gcn::Graphics::LEFT);
|
||||
sldVOffset = new gcn::Slider(-60, 60);
|
||||
sldVOffset->setSize(135, SLIDER_HEIGHT);
|
||||
sldVOffset = new gcn::Slider(-80, 80);
|
||||
sldVOffset->setSize(200, SLIDER_HEIGHT);
|
||||
sldVOffset->setBaseColor(gui_baseCol);
|
||||
sldVOffset->setMarkerLength(20);
|
||||
sldVOffset->setStepLength(1);
|
||||
@ -700,9 +700,8 @@ void RefreshPanelDisplay()
|
||||
sldBrightness->setValue(changed_prefs.gfx_luminance);
|
||||
lblBrightnessValue->setCaption(std::to_string(changed_prefs.gfx_luminance));
|
||||
lblBrightnessValue->adjustSize();
|
||||
|
||||
int i;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < AMIGAWIDTH_COUNT; ++i)
|
||||
{
|
||||
if (changed_prefs.gfx_monitor[0].gfx_size_win.width == amigawidth_values[i])
|
||||
|
||||
@ -211,7 +211,7 @@ public:
|
||||
{
|
||||
strncpy(changed_prefs.floppyslots[i].df, tmp.c_str(), MAX_DPATH);
|
||||
disk_insert(i, tmp.c_str());
|
||||
AddFileToDiskList(tmp.c_str(), 1);
|
||||
add_file_to_mru_list(lstMRUDiskList, tmp);
|
||||
RefreshDiskListModel();
|
||||
current_dir = extract_path(tmp);
|
||||
|
||||
@ -334,7 +334,7 @@ public:
|
||||
diskname[31] = '\0';
|
||||
disk_creatediskfile(&changed_prefs, tmp.c_str(), 0, DRV_35_DD, -1, diskname, false, false, nullptr);
|
||||
DISK_history_add (tmp.c_str(), -1, HISTORY_FLOPPY, 0);
|
||||
AddFileToDiskList(tmp.c_str(), 1);
|
||||
add_file_to_mru_list(lstMRUDiskList, tmp);
|
||||
RefreshDiskListModel();
|
||||
current_dir = extract_path(tmp);
|
||||
}
|
||||
@ -351,7 +351,7 @@ public:
|
||||
diskname[31] = '\0';
|
||||
disk_creatediskfile(&changed_prefs, tmp.c_str(), 0, DRV_35_HD, -1, diskname, false, false, nullptr);
|
||||
DISK_history_add (tmp.c_str(), -1, HISTORY_FLOPPY, 0);
|
||||
AddFileToDiskList(tmp.c_str(), 1);
|
||||
add_file_to_mru_list(lstMRUDiskList, tmp);
|
||||
RefreshDiskListModel();
|
||||
current_dir = extract_path(tmp);
|
||||
}
|
||||
|
||||
@ -252,7 +252,7 @@ public:
|
||||
strncpy(changed_prefs.cdslots[0].name, tmp.c_str(), sizeof changed_prefs.cdslots[0].name);
|
||||
changed_prefs.cdslots[0].inuse = true;
|
||||
changed_prefs.cdslots[0].type = SCSI_UNIT_DEFAULT;
|
||||
AddFileToCDList(tmp.c_str(), 1);
|
||||
add_file_to_mru_list(lstMRUCDList, tmp);
|
||||
current_dir = extract_path(tmp);
|
||||
|
||||
RefreshCDListModel();
|
||||
|
||||
@ -136,7 +136,6 @@ static amigamodels amodels[] = {
|
||||
static const int numModels = 10;
|
||||
static int numModelConfigs = 0;
|
||||
static bool bIgnoreListChange = true;
|
||||
static char whdload_file[MAX_DPATH];
|
||||
|
||||
static gcn::StringListModel amigaModelList;
|
||||
static gcn::StringListModel amigaConfigList;
|
||||
@ -144,6 +143,8 @@ static gcn::StringListModel diskfileList;
|
||||
static gcn::StringListModel cdfileList;
|
||||
static gcn::StringListModel whdloadFileList;
|
||||
|
||||
std::string whdload_filename;
|
||||
|
||||
static void AdjustDropDownControls();
|
||||
|
||||
static void CountModelConfigs()
|
||||
@ -317,7 +318,7 @@ public:
|
||||
strncpy(changed_prefs.cdslots[0].name, tmp.c_str(), MAX_DPATH);
|
||||
changed_prefs.cdslots[0].inuse = true;
|
||||
changed_prefs.cdslots[0].type = SCSI_UNIT_DEFAULT;
|
||||
AddFileToCDList(tmp.c_str(), 1);
|
||||
add_file_to_mru_list(lstMRUCDList, tmp);
|
||||
current_dir = extract_path(tmp);
|
||||
|
||||
RefreshCDListModel();
|
||||
@ -394,21 +395,21 @@ public:
|
||||
|
||||
if (idx < 0)
|
||||
{
|
||||
strncpy(whdload_file, "", MAX_DPATH);
|
||||
whdload_filename = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto element = get_full_path_from_disk_list(whdloadFileList.getElementAt(idx));
|
||||
if (element != whdload_file)
|
||||
if (element != whdload_filename)
|
||||
{
|
||||
strncpy(whdload_file, element.c_str(), MAX_DPATH);
|
||||
whdload_filename.assign(element);
|
||||
lstMRUWhdloadList.erase(lstMRUWhdloadList.begin() + idx);
|
||||
lstMRUWhdloadList.insert(lstMRUWhdloadList.begin(), whdload_file);
|
||||
lstMRUWhdloadList.insert(lstMRUWhdloadList.begin(), whdload_filename);
|
||||
bIgnoreListChange = true;
|
||||
cboWhdload->setSelected(0);
|
||||
bIgnoreListChange = false;
|
||||
}
|
||||
whdload_auto_prefs(&changed_prefs, whdload_file);
|
||||
whdload_auto_prefs(&changed_prefs, whdload_filename.c_str());
|
||||
}
|
||||
refresh_all_panels();
|
||||
}
|
||||
@ -428,23 +429,22 @@ public:
|
||||
//---------------------------------------
|
||||
// Eject WHDLoad file
|
||||
//---------------------------------------
|
||||
strncpy(whdload_file, "", MAX_DPATH);
|
||||
AdjustPrefs();
|
||||
whdload_filename = "";
|
||||
}
|
||||
else if (actionEvent.getSource() == cmdWhdloadSelect)
|
||||
{
|
||||
std::string tmp;
|
||||
if (strlen(whdload_file) > 0)
|
||||
tmp = std::string(whdload_file);
|
||||
if (!whdload_filename.empty())
|
||||
tmp = whdload_filename;
|
||||
else
|
||||
tmp = get_whdload_arch_path();
|
||||
|
||||
tmp = SelectFile("Select WHDLoad LHA file", tmp, whdload_filter);
|
||||
{
|
||||
strncpy(whdload_file, tmp.c_str(), MAX_DPATH);
|
||||
AddFileToWHDLoadList(whdload_file, 1);
|
||||
whdload_filename = tmp;
|
||||
add_file_to_mru_list(lstMRUWhdloadList, whdload_filename);
|
||||
RefreshWhdListModel();
|
||||
whdload_auto_prefs(&changed_prefs, whdload_file);
|
||||
whdload_auto_prefs(&changed_prefs, whdload_filename.c_str());
|
||||
|
||||
AdjustDropDownControls();
|
||||
}
|
||||
@ -642,7 +642,7 @@ public:
|
||||
{
|
||||
strncpy(changed_prefs.floppyslots[i].df, tmp.c_str(), MAX_DPATH);
|
||||
disk_insert(i, tmp.c_str());
|
||||
AddFileToDiskList(tmp.c_str(), 1);
|
||||
add_file_to_mru_list(lstMRUDiskList, tmp);
|
||||
current_dir = extract_path(tmp);
|
||||
RefreshDiskListModel();
|
||||
current_dir = extract_path(tmp);
|
||||
@ -1027,11 +1027,11 @@ static void AdjustDropDownControls()
|
||||
}
|
||||
|
||||
cboWhdload->clearSelected();
|
||||
if (strlen(whdload_file) > 0)
|
||||
if (!whdload_filename.empty())
|
||||
{
|
||||
for (auto i = 0; i < static_cast<int>(lstMRUWhdloadList.size()); ++i)
|
||||
{
|
||||
if (lstMRUWhdloadList[i].c_str() != whdload_file)
|
||||
if (lstMRUWhdloadList[i] == whdload_filename)
|
||||
{
|
||||
cboWhdload->setSelected(i);
|
||||
break;
|
||||
@ -1048,6 +1048,7 @@ void RefreshPanelQuickstart()
|
||||
|
||||
chkNTSC->setSelected(changed_prefs.ntscmode);
|
||||
|
||||
RefreshWhdListModel();
|
||||
AdjustDropDownControls();
|
||||
|
||||
changed_prefs.nr_floppies = 0;
|
||||
|
||||
455
src/osdep/gui/PanelWHDLoad.cpp
Normal file
455
src/osdep/gui/PanelWHDLoad.cpp
Normal file
@ -0,0 +1,455 @@
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
#include <vector>
|
||||
|
||||
#include <guisan.hpp>
|
||||
#include <guisan/sdl.hpp>
|
||||
|
||||
#include "SelectorEntry.hpp"
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include "options.h"
|
||||
#include "gui_handling.h"
|
||||
#include "StringListModel.h"
|
||||
|
||||
static gcn::Label* lblWhdload;
|
||||
static gcn::DropDown* cboWhdload;
|
||||
static gcn::Button* cmdWhdloadEject;
|
||||
static gcn::Button* cmdWhdloadSelect;
|
||||
|
||||
// WHDLoad game options
|
||||
static gcn::Label* lblGameName;
|
||||
static gcn::TextField* txtGameName;
|
||||
|
||||
static gcn::Label* lblVariantUuid;
|
||||
static gcn::TextField* txtVariantUuid;
|
||||
|
||||
static gcn::Label* lblSlaveDefault;
|
||||
static gcn::TextField* txtSlaveDefault;
|
||||
|
||||
static gcn::CheckBox* chkSlaveLibraries;
|
||||
|
||||
static gcn::Label* lblSlaves;
|
||||
static gcn::DropDown* cboSlaves;
|
||||
|
||||
// WHDLoad global options
|
||||
static gcn::Window* grpWHDLoadGlobal;
|
||||
static gcn::Label* lblCustomText;
|
||||
static gcn::TextField* txtCustomText;
|
||||
|
||||
static gcn::CheckBox* chkButtonWait;
|
||||
static gcn::CheckBox* chkShowSplash;
|
||||
|
||||
static gcn::Label* lblConfigDelay;
|
||||
static gcn::TextField* txtConfigDelay;
|
||||
|
||||
static gcn::CheckBox* chkWriteCache;
|
||||
static gcn::CheckBox* chkQuitOnExit;
|
||||
|
||||
// Selected Slave options
|
||||
static gcn::Label* lblSlaveDataPath;
|
||||
static gcn::TextField* txtSlaveDataPath;
|
||||
|
||||
// Selected Slave Custom options
|
||||
static gcn::Button* cmdCustomFields;
|
||||
|
||||
static gcn::StringListModel whdloadFileList;
|
||||
static gcn::StringListModel slaves_list;
|
||||
|
||||
static bool bIgnoreListChange = true;
|
||||
|
||||
static void RefreshWhdListModel()
|
||||
{
|
||||
whdloadFileList.clear();
|
||||
for (const auto& i : lstMRUWhdloadList)
|
||||
{
|
||||
const std::string full_path = i;
|
||||
const std::string filename = full_path.substr(full_path.find_last_of("/\\") + 1);
|
||||
whdloadFileList.add(std::string(filename).append(" { ").append(full_path).append(" }"));
|
||||
}
|
||||
}
|
||||
|
||||
static void AdjustDropDownControls()
|
||||
{
|
||||
bIgnoreListChange = true;
|
||||
|
||||
cboWhdload->clearSelected();
|
||||
if (!whdload_filename.empty())
|
||||
{
|
||||
for (auto i = 0; i < static_cast<int>(lstMRUWhdloadList.size()); ++i)
|
||||
{
|
||||
if (lstMRUWhdloadList[i] == whdload_filename)
|
||||
{
|
||||
cboWhdload->setSelected(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bIgnoreListChange = false;
|
||||
}
|
||||
|
||||
class WHDLoadActionListener : public gcn::ActionListener
|
||||
{
|
||||
public:
|
||||
void action(const gcn::ActionEvent& actionEvent) override
|
||||
{
|
||||
const auto source = actionEvent.getSource();
|
||||
if (source == cboWhdload)
|
||||
{
|
||||
//---------------------------------------
|
||||
// WHDLoad file from list selected
|
||||
//---------------------------------------
|
||||
if (!bIgnoreListChange)
|
||||
{
|
||||
const auto idx = cboWhdload->getSelected();
|
||||
|
||||
if (idx < 0)
|
||||
{
|
||||
whdload_filename = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto element = get_full_path_from_disk_list(whdloadFileList.getElementAt(idx));
|
||||
if (element != whdload_filename)
|
||||
{
|
||||
whdload_filename.assign(element);
|
||||
lstMRUWhdloadList.erase(lstMRUWhdloadList.begin() + idx);
|
||||
lstMRUWhdloadList.insert(lstMRUWhdloadList.begin(), whdload_filename);
|
||||
bIgnoreListChange = true;
|
||||
cboWhdload->setSelected(0);
|
||||
bIgnoreListChange = false;
|
||||
}
|
||||
whdload_auto_prefs(&changed_prefs, whdload_filename.c_str());
|
||||
}
|
||||
refresh_all_panels();
|
||||
}
|
||||
}
|
||||
else if (source == cmdWhdloadEject)
|
||||
{
|
||||
//---------------------------------------
|
||||
// Eject WHDLoad file
|
||||
//---------------------------------------
|
||||
whdload_filename = "";
|
||||
refresh_all_panels();
|
||||
}
|
||||
else if (source == cmdWhdloadSelect)
|
||||
{
|
||||
std::string tmp;
|
||||
if (!whdload_filename.empty())
|
||||
tmp = whdload_filename;
|
||||
else
|
||||
tmp = get_whdload_arch_path();
|
||||
|
||||
tmp = SelectFile("Select WHDLoad LHA file", tmp, whdload_filter);
|
||||
{
|
||||
whdload_filename.assign(tmp);
|
||||
add_file_to_mru_list(lstMRUWhdloadList, whdload_filename);
|
||||
RefreshWhdListModel();
|
||||
whdload_auto_prefs(&changed_prefs, whdload_filename.c_str());
|
||||
|
||||
AdjustDropDownControls();
|
||||
}
|
||||
cmdWhdloadSelect->requestFocus();
|
||||
refresh_all_panels();
|
||||
}
|
||||
else if (source == cboSlaves)
|
||||
{
|
||||
if (cboSlaves->getSelected() >= 0)
|
||||
{
|
||||
whdload_prefs.selected_slave = whdload_prefs.slaves[cboSlaves->getSelected()];
|
||||
txtSlaveDataPath->setText(whdload_prefs.selected_slave.data_path.empty() ? "" : whdload_prefs.selected_slave.data_path);
|
||||
create_startup_sequence();
|
||||
}
|
||||
}
|
||||
else if (source == cmdCustomFields)
|
||||
{
|
||||
ShowCustomFields();
|
||||
}
|
||||
else if (source == chkButtonWait)
|
||||
{
|
||||
whdload_prefs.button_wait = chkButtonWait->isSelected();
|
||||
create_startup_sequence();
|
||||
}
|
||||
else if (source == chkShowSplash)
|
||||
{
|
||||
whdload_prefs.show_splash = chkShowSplash->isSelected();
|
||||
create_startup_sequence();
|
||||
}
|
||||
else if (source == chkWriteCache)
|
||||
{
|
||||
whdload_prefs.write_cache = chkWriteCache->isSelected();
|
||||
create_startup_sequence();
|
||||
}
|
||||
else if (source == chkQuitOnExit)
|
||||
{
|
||||
whdload_prefs.quit_on_exit = chkQuitOnExit->isSelected();
|
||||
create_startup_sequence();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static WHDLoadActionListener* whdloadActionListener;
|
||||
|
||||
void InitPanelWHDLoad(const struct config_category& category)
|
||||
{
|
||||
slaves_list.clear();
|
||||
|
||||
constexpr int textfield_width = 350;
|
||||
|
||||
whdloadActionListener = new WHDLoadActionListener();
|
||||
|
||||
lblWhdload = new gcn::Label("WHDLoad auto-config:");
|
||||
cboWhdload = new gcn::DropDown(&whdloadFileList);
|
||||
cboWhdload->setSize(category.panel->getWidth() - 2 * DISTANCE_BORDER, cboWhdload->getHeight());
|
||||
cboWhdload->setBaseColor(gui_baseCol);
|
||||
cboWhdload->setBackgroundColor(colTextboxBackground);
|
||||
cboWhdload->setId("cboWhdload");
|
||||
cboWhdload->addActionListener(whdloadActionListener);
|
||||
|
||||
cmdWhdloadEject = new gcn::Button("Eject");
|
||||
cmdWhdloadEject->setSize(SMALL_BUTTON_WIDTH * 2, SMALL_BUTTON_HEIGHT);
|
||||
cmdWhdloadEject->setBaseColor(gui_baseCol);
|
||||
cmdWhdloadEject->setId("cmdWhdloadEject");
|
||||
cmdWhdloadEject->addActionListener(whdloadActionListener);
|
||||
|
||||
cmdWhdloadSelect = new gcn::Button("Select file");
|
||||
cmdWhdloadSelect->setSize(BUTTON_WIDTH + 10, SMALL_BUTTON_HEIGHT);
|
||||
cmdWhdloadSelect->setBaseColor(gui_baseCol);
|
||||
cmdWhdloadSelect->setId("cmdWhdloadSelect");
|
||||
cmdWhdloadSelect->addActionListener(whdloadActionListener);
|
||||
|
||||
// WHDLoad options
|
||||
lblGameName = new gcn::Label("Game Name:");
|
||||
txtGameName = new gcn::TextField();
|
||||
txtGameName->setSize(textfield_width, TEXTFIELD_HEIGHT);
|
||||
txtGameName->setBackgroundColor(colTextboxBackground);
|
||||
|
||||
lblVariantUuid = new gcn::Label("UUID:");
|
||||
txtVariantUuid = new gcn::TextField();
|
||||
txtVariantUuid->setSize(textfield_width, TEXTFIELD_HEIGHT);
|
||||
txtVariantUuid->setBackgroundColor(colTextboxBackground);
|
||||
|
||||
lblSlaveDefault = new gcn::Label("Slave Default:");
|
||||
txtSlaveDefault = new gcn::TextField();
|
||||
txtSlaveDefault->setSize(textfield_width, TEXTFIELD_HEIGHT);
|
||||
txtSlaveDefault->setBackgroundColor(colTextboxBackground);
|
||||
|
||||
chkSlaveLibraries = new gcn::CheckBox("Slave Libraries");
|
||||
|
||||
lblSlaves = new gcn::Label("Slaves:");
|
||||
cboSlaves = new gcn::DropDown(&slaves_list);
|
||||
cboSlaves->setSize(textfield_width, cboSlaves->getHeight());
|
||||
cboSlaves->setBaseColor(gui_baseCol);
|
||||
cboSlaves->setBackgroundColor(colTextboxBackground);
|
||||
cboSlaves->addActionListener(whdloadActionListener);
|
||||
|
||||
lblSlaveDataPath = new gcn::Label("Slave Data path:");
|
||||
txtSlaveDataPath = new gcn::TextField();
|
||||
txtSlaveDataPath->setSize(textfield_width, TEXTFIELD_HEIGHT);
|
||||
txtSlaveDataPath->setBackgroundColor(colTextboxBackground);
|
||||
|
||||
cmdCustomFields = new gcn::Button("Custom Fields");
|
||||
cmdCustomFields->setSize(BUTTON_WIDTH * 2, BUTTON_HEIGHT);
|
||||
cmdCustomFields->setBaseColor(gui_baseCol);
|
||||
cmdCustomFields->setId("cmdCustomFields");
|
||||
cmdCustomFields->addActionListener(whdloadActionListener);
|
||||
|
||||
lblCustomText = new gcn::Label("Custom:");
|
||||
txtCustomText = new gcn::TextField();
|
||||
txtCustomText->setSize(textfield_width, TEXTFIELD_HEIGHT);
|
||||
txtCustomText->setBackgroundColor(colTextboxBackground);
|
||||
|
||||
chkButtonWait = new gcn::CheckBox("Button Wait");
|
||||
chkButtonWait->addActionListener(whdloadActionListener);
|
||||
chkShowSplash = new gcn::CheckBox("Show Splash");
|
||||
chkShowSplash->addActionListener(whdloadActionListener);
|
||||
|
||||
lblConfigDelay = new gcn::Label("Config Delay:");
|
||||
txtConfigDelay = new gcn::TextField();
|
||||
txtConfigDelay->setSize(textfield_width, TEXTFIELD_HEIGHT);
|
||||
txtConfigDelay->setBackgroundColor(colTextboxBackground);
|
||||
|
||||
chkWriteCache = new gcn::CheckBox("Write Cache");
|
||||
chkWriteCache->addActionListener(whdloadActionListener);
|
||||
chkQuitOnExit = new gcn::CheckBox("Quit on Exit");
|
||||
chkQuitOnExit->addActionListener(whdloadActionListener);
|
||||
|
||||
constexpr int pos_x1 = DISTANCE_BORDER;
|
||||
const int pos_x2 = chkSlaveLibraries->getWidth() + 8;
|
||||
int pos_y = DISTANCE_BORDER;
|
||||
|
||||
category.panel->add(lblWhdload, DISTANCE_BORDER, pos_y);
|
||||
category.panel->add(cmdWhdloadEject, lblWhdload->getX() + lblWhdload->getWidth() + DISTANCE_NEXT_X * 16, pos_y);
|
||||
category.panel->add(cmdWhdloadSelect, cmdWhdloadEject->getX() + cmdWhdloadEject->getWidth() + DISTANCE_NEXT_X, pos_y);
|
||||
pos_y += cmdWhdloadSelect->getHeight() + 8;
|
||||
|
||||
category.panel->add(cboWhdload, DISTANCE_BORDER, pos_y);
|
||||
pos_y += cboWhdload->getHeight() + DISTANCE_NEXT_Y;
|
||||
|
||||
category.panel->add(lblGameName, pos_x1, pos_y);
|
||||
category.panel->add(txtGameName, pos_x2, pos_y);
|
||||
pos_y += lblGameName->getHeight() + 8;
|
||||
|
||||
category.panel->add(lblVariantUuid, pos_x1, pos_y);
|
||||
category.panel->add(txtVariantUuid, pos_x2, pos_y);
|
||||
pos_y += lblVariantUuid->getHeight() + 8;
|
||||
|
||||
category.panel->add(lblSlaveDefault, pos_x1, pos_y);
|
||||
category.panel->add(txtSlaveDefault, pos_x2, pos_y);
|
||||
pos_y += lblSlaveDefault->getHeight() + 8;
|
||||
|
||||
category.panel->add(chkSlaveLibraries, pos_x1, pos_y);
|
||||
pos_y += chkSlaveLibraries->getHeight() + 8;
|
||||
|
||||
category.panel->add(lblSlaves, pos_x1, pos_y);
|
||||
category.panel->add(cboSlaves, pos_x2, pos_y);
|
||||
pos_y += lblSlaves->getHeight() + 8;
|
||||
|
||||
category.panel->add(lblSlaveDataPath, pos_x1, pos_y);
|
||||
category.panel->add(txtSlaveDataPath, pos_x2, pos_y);
|
||||
pos_y += lblSlaveDataPath->getHeight() + 8;
|
||||
|
||||
category.panel->add(lblCustomText, pos_x1, pos_y);
|
||||
category.panel->add(txtCustomText, pos_x2, pos_y);
|
||||
pos_y += lblCustomText->getHeight() + DISTANCE_NEXT_Y;
|
||||
|
||||
category.panel->add(cmdCustomFields, pos_x2, pos_y);
|
||||
|
||||
grpWHDLoadGlobal = new gcn::Window("Global options");
|
||||
grpWHDLoadGlobal->setMovable(false);
|
||||
grpWHDLoadGlobal->setTitleBarHeight(TITLEBAR_HEIGHT);
|
||||
grpWHDLoadGlobal->setBaseColor(gui_baseCol);
|
||||
|
||||
pos_y = 10;
|
||||
grpWHDLoadGlobal->add(chkButtonWait, pos_x1, pos_y);
|
||||
pos_y += chkButtonWait->getHeight() + 8;
|
||||
|
||||
grpWHDLoadGlobal->add(chkShowSplash, pos_x1, pos_y);
|
||||
pos_y += chkShowSplash->getHeight() + 8;
|
||||
|
||||
grpWHDLoadGlobal->add(lblConfigDelay, pos_x1, pos_y);
|
||||
grpWHDLoadGlobal->add(txtConfigDelay, pos_x2, pos_y);
|
||||
pos_y += txtConfigDelay->getHeight() + 8;
|
||||
|
||||
grpWHDLoadGlobal->add(chkWriteCache, pos_x1, pos_y);
|
||||
pos_y += chkWriteCache->getHeight() + 8;
|
||||
|
||||
grpWHDLoadGlobal->add(chkQuitOnExit, pos_x1, pos_y);
|
||||
grpWHDLoadGlobal->setSize(category.panel->getWidth() - DISTANCE_BORDER * 2,
|
||||
chkQuitOnExit->getY() + chkQuitOnExit->getHeight() + DISTANCE_NEXT_Y + TITLEBAR_HEIGHT);
|
||||
grpWHDLoadGlobal->setPosition(pos_x1, category.panel->getHeight() - grpWHDLoadGlobal->getHeight() - DISTANCE_NEXT_Y);
|
||||
category.panel->add(grpWHDLoadGlobal);
|
||||
|
||||
bIgnoreListChange = false;
|
||||
|
||||
RefreshPanelWHDLoad();
|
||||
}
|
||||
|
||||
void ExitPanelWHDLoad()
|
||||
{
|
||||
delete lblWhdload;
|
||||
delete cboWhdload;
|
||||
delete cmdWhdloadEject;
|
||||
delete cmdWhdloadSelect;
|
||||
|
||||
// WHDLoad options
|
||||
delete lblGameName;
|
||||
delete txtGameName;
|
||||
|
||||
delete lblVariantUuid;
|
||||
delete txtVariantUuid;
|
||||
|
||||
delete lblSlaveDefault;
|
||||
delete txtSlaveDefault;
|
||||
|
||||
delete chkSlaveLibraries;
|
||||
|
||||
delete lblSlaves;
|
||||
delete cboSlaves;
|
||||
|
||||
delete lblCustomText;
|
||||
delete txtCustomText;
|
||||
|
||||
delete chkButtonWait;
|
||||
delete chkShowSplash;
|
||||
|
||||
delete lblConfigDelay;
|
||||
delete txtConfigDelay;
|
||||
|
||||
delete chkWriteCache;
|
||||
delete chkQuitOnExit;
|
||||
|
||||
// Selected Slave options
|
||||
delete lblSlaveDataPath;
|
||||
delete txtSlaveDataPath;
|
||||
|
||||
// Selected Slave Custom options
|
||||
delete cmdCustomFields;
|
||||
delete grpWHDLoadGlobal;
|
||||
|
||||
delete whdloadActionListener;
|
||||
}
|
||||
|
||||
void update_slaves_list(const std::vector<whdload_slave>& slaves)
|
||||
{
|
||||
slaves_list.clear();
|
||||
for (auto& slave : slaves)
|
||||
{
|
||||
slaves_list.add(slave.filename);
|
||||
}
|
||||
}
|
||||
|
||||
void update_selected_slave(const whdload_slave& selected_slave)
|
||||
{
|
||||
int selected = 0;
|
||||
for (int i = 0; i < slaves_list.getNumberOfElements(); i++)
|
||||
{
|
||||
if (slaves_list.getElementAt(i) == selected_slave.filename)
|
||||
{
|
||||
selected = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
cboSlaves->setSelected(selected);
|
||||
}
|
||||
|
||||
void RefreshPanelWHDLoad()
|
||||
{
|
||||
RefreshWhdListModel();
|
||||
AdjustDropDownControls();
|
||||
|
||||
cmdCustomFields->setEnabled(!whdload_filename.empty());
|
||||
|
||||
if (whdload_filename.empty())
|
||||
{
|
||||
clear_whdload_prefs();
|
||||
slaves_list.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
update_slaves_list(whdload_prefs.slaves);
|
||||
update_selected_slave(whdload_prefs.selected_slave);
|
||||
txtSlaveDataPath->setText(whdload_prefs.selected_slave.data_path.empty() ? "" : whdload_prefs.selected_slave.data_path);
|
||||
}
|
||||
|
||||
txtGameName->setText(whdload_prefs.game_name.empty() ? "" : whdload_prefs.game_name);
|
||||
txtVariantUuid->setText(whdload_prefs.variant_uuid.empty() ? "" : whdload_prefs.variant_uuid);
|
||||
txtSlaveDefault->setText(whdload_prefs.slave_default.empty() ? "" : whdload_prefs.slave_default);
|
||||
chkSlaveLibraries->setSelected(whdload_prefs.slave_libraries);
|
||||
txtCustomText->setText(whdload_prefs.custom.empty() ? "" : whdload_prefs.custom);
|
||||
|
||||
// These are global
|
||||
chkButtonWait->setSelected(whdload_prefs.button_wait);
|
||||
chkShowSplash->setSelected(whdload_prefs.show_splash);
|
||||
txtConfigDelay->setText(std::to_string(whdload_prefs.config_delay));
|
||||
chkWriteCache->setSelected(whdload_prefs.write_cache);
|
||||
chkQuitOnExit->setSelected(whdload_prefs.quit_on_exit);
|
||||
}
|
||||
|
||||
bool HelpPanelWHDLoad(std::vector<std::string>& helptext)
|
||||
{
|
||||
helptext.clear();
|
||||
//TODO
|
||||
return true;
|
||||
}
|
||||
@ -44,40 +44,41 @@ static gcn::TextField* txtFilename;
|
||||
|
||||
class SelectFileListModel : public gcn::ListModel
|
||||
{
|
||||
std::vector<std::string> dirs{};
|
||||
std::vector<std::string> files{};
|
||||
std::vector<std::string> dirs;
|
||||
std::vector<std::string> files;
|
||||
|
||||
public:
|
||||
explicit SelectFileListModel(const char* path)
|
||||
explicit SelectFileListModel(const std::string& path)
|
||||
{
|
||||
changeDir(path);
|
||||
}
|
||||
|
||||
int getNumberOfElements() override
|
||||
{
|
||||
return static_cast<int>(dirs.size() + files.size());
|
||||
return dirs.size() + files.size();
|
||||
}
|
||||
|
||||
void add(const std::string& elem) override
|
||||
{
|
||||
dirs.emplace_back(elem);
|
||||
dirs.push_back(elem);
|
||||
}
|
||||
|
||||
void clear() override
|
||||
{
|
||||
dirs.clear();
|
||||
files.clear();
|
||||
}
|
||||
|
||||
std::string getElementAt(const int i) override
|
||||
std::string getElementAt(int i) override
|
||||
{
|
||||
if (i >= static_cast<int>(dirs.size() + files.size()) || i < 0)
|
||||
if (i < 0 || i >= getNumberOfElements())
|
||||
return "---";
|
||||
if (i < static_cast<int>(dirs.size()))
|
||||
if (i < dirs.size())
|
||||
return dirs[i];
|
||||
return files[i - dirs.size()];
|
||||
}
|
||||
|
||||
void changeDir(const char* path)
|
||||
void changeDir(const std::string& path)
|
||||
{
|
||||
read_directory(path, &dirs, &files);
|
||||
if (dirs.empty())
|
||||
@ -85,7 +86,7 @@ public:
|
||||
FilterFiles(&files, filefilter);
|
||||
}
|
||||
|
||||
[[nodiscard]] bool isDir(const unsigned int i) const
|
||||
bool isDir(unsigned int i) const
|
||||
{
|
||||
return (i < dirs.size());
|
||||
}
|
||||
|
||||
@ -49,13 +49,11 @@ public:
|
||||
dialogFinished = true;
|
||||
}
|
||||
};
|
||||
|
||||
static FolderRequesterButtonActionListener* folderButtonActionListener;
|
||||
|
||||
|
||||
class SelectDirListModel : public gcn::ListModel
|
||||
{
|
||||
std::vector<std::string> dirs{};
|
||||
std::vector<std::string> dirs;
|
||||
|
||||
public:
|
||||
SelectDirListModel(const std::string& path)
|
||||
@ -70,7 +68,7 @@ public:
|
||||
|
||||
void add(const std::string& elem) override
|
||||
{
|
||||
dirs.emplace_back(elem);
|
||||
dirs.push_back(elem);
|
||||
}
|
||||
|
||||
void clear() override
|
||||
@ -78,9 +76,9 @@ public:
|
||||
dirs.clear();
|
||||
}
|
||||
|
||||
std::string getElementAt(const int i) override
|
||||
std::string getElementAt(int i) override
|
||||
{
|
||||
if (i >= static_cast<int>(dirs.size()) || i < 0)
|
||||
if (i < 0 || i >= getNumberOfElements())
|
||||
return "---";
|
||||
return dirs[i];
|
||||
}
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
#ifndef GCN_SELECTORENTRY_HPP
|
||||
#define GCN_SELECTORENTRY_HPP
|
||||
#pragma once
|
||||
|
||||
#include <guisan/basiccontainer.hpp>
|
||||
#include <guisan/platform.hpp>
|
||||
@ -31,7 +30,7 @@ namespace gcn
|
||||
void setInactiveColor(const Color& color);
|
||||
void setActiveColor(const Color& color);
|
||||
void setActive(bool active);
|
||||
[[nodiscard]] bool getActive() const;
|
||||
bool getActive() const;
|
||||
|
||||
void widgetResized(const Event& event) override;
|
||||
|
||||
@ -48,4 +47,3 @@ namespace gcn
|
||||
};
|
||||
}
|
||||
|
||||
#endif // end GCN_SELECTORENTRY_HPP
|
||||
|
||||
434
src/osdep/gui/ShowCustomFields.cpp
Normal file
434
src/osdep/gui/ShowCustomFields.cpp
Normal file
@ -0,0 +1,434 @@
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
#include <guisan.hpp>
|
||||
#include <guisan/sdl.hpp>
|
||||
|
||||
#include "SelectorEntry.hpp"
|
||||
#include "StringListModel.h"
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include "config.h"
|
||||
#include "gui_handling.h"
|
||||
|
||||
#include "options.h"
|
||||
#include "amiberry_input.h"
|
||||
|
||||
enum
|
||||
{
|
||||
DIALOG_WIDTH = 600,
|
||||
DIALOG_HEIGHT = 600
|
||||
};
|
||||
|
||||
static bool dialog_finished = false;
|
||||
static int custom_number[5];
|
||||
static gcn::StringListModel custom_list[5];
|
||||
|
||||
static gcn::Window* wndShowCustomFields;
|
||||
static gcn::Button* cmdOK;
|
||||
|
||||
struct custom_widget {
|
||||
std::vector<gcn::Label*> lbl;
|
||||
std::vector<gcn::CheckBox*> boolean;
|
||||
std::vector<gcn::CheckBox*> bit;
|
||||
std::vector<gcn::DropDown*> list;
|
||||
};
|
||||
|
||||
custom_widget customWidget1;
|
||||
custom_widget customWidget2;
|
||||
custom_widget customWidget3;
|
||||
custom_widget customWidget4;
|
||||
custom_widget customWidget5;
|
||||
|
||||
constexpr std::array<custom_widget*, 5> customWidgets = { &customWidget1, &customWidget2, &customWidget3, &customWidget4, &customWidget5 };
|
||||
constexpr std::array<whdload_custom*, 5> customFields = { &whdload_prefs.selected_slave.custom1, &whdload_prefs.selected_slave.custom2, &whdload_prefs.selected_slave.custom3, &whdload_prefs.selected_slave.custom4, &whdload_prefs.selected_slave.custom5 };
|
||||
|
||||
static int set_bit(const int value, const int bit_position) {
|
||||
return value | (1 << bit_position);
|
||||
}
|
||||
|
||||
static int clear_bit(const int value, const int bit_position) {
|
||||
return value & ~(1 << bit_position);
|
||||
}
|
||||
|
||||
static bool is_bit_set(const int num, const int bit) {
|
||||
return (num & (1 << bit)) != 0;
|
||||
}
|
||||
|
||||
class ShowCustomFieldsActionListener : public gcn::ActionListener
|
||||
{
|
||||
public:
|
||||
void action(const gcn::ActionEvent& actionEvent) override
|
||||
{
|
||||
const auto source = actionEvent.getSource();
|
||||
|
||||
if (source == cmdOK)
|
||||
dialog_finished = true;
|
||||
else
|
||||
{
|
||||
for (int j = 0; j < 5; ++j)
|
||||
{
|
||||
for (int i = 0; i < custom_number[j]; i++)
|
||||
{
|
||||
if (!customWidgets[j]->list.empty() && customFields[j]->type == list_type)
|
||||
{
|
||||
if (source == customWidgets[j]->list[i])
|
||||
{
|
||||
customFields[j]->value = customWidgets[j]->list[i]->getSelected();
|
||||
write_log("Custom field %d value updated to: %d\n", i, customFields[j]->value);
|
||||
}
|
||||
}
|
||||
else if (!customWidgets[j]->boolean.empty() && customFields[j]->type == bool_type)
|
||||
{
|
||||
if (source == customWidgets[j]->boolean[i])
|
||||
{
|
||||
customFields[j]->value = customWidgets[j]->boolean[i]->isSelected();
|
||||
write_log("Custom field %d value updated to: %d\n", i, customFields[j]->value);
|
||||
}
|
||||
}
|
||||
else if (!customWidgets[j]->bit.empty() && customFields[j]->type == bit_type)
|
||||
{
|
||||
if (source == customWidgets[j]->bit[i])
|
||||
{
|
||||
customFields[j]->value = customWidgets[j]->bit[i]->isSelected()
|
||||
? set_bit(customFields[j]->value, customFields[j]->label_bit_pairs[i].second)
|
||||
: clear_bit(customFields[j]->value, customFields[j]->label_bit_pairs[i].second);
|
||||
write_log("Custom field %d value updated to: %d\n", i, customFields[j]->value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static ShowCustomFieldsActionListener* showCustomFieldsActionListener;
|
||||
|
||||
void create_custom_field(custom_widget& widget, const int number, const std::string& caption, const whdload_custom& custom_field, int& pos_y, const int custom_list_index)
|
||||
{
|
||||
constexpr int textfield_width = 350;
|
||||
constexpr int pos_x1 = DISTANCE_BORDER;
|
||||
constexpr int pos_x2 = 150;
|
||||
|
||||
for (int i = 0; i < number; i++) {
|
||||
std::string id;
|
||||
|
||||
auto label = new gcn::Label(caption + ":");
|
||||
label->setPosition(pos_x1, pos_y);
|
||||
widget.lbl.emplace_back(label);
|
||||
wndShowCustomFields->add(label);
|
||||
|
||||
switch (custom_field.type) {
|
||||
case bit_type: {
|
||||
auto checkbox = new gcn::CheckBox(custom_field.label_bit_pairs[i].first);
|
||||
checkbox->setSelected(is_bit_set(custom_field.value, custom_field.label_bit_pairs[i].second));
|
||||
checkbox->addActionListener(showCustomFieldsActionListener);
|
||||
checkbox->setId("chkCustomFieldBit_" + std::to_string(i));
|
||||
checkbox->setPosition(pos_x2, pos_y);
|
||||
widget.bit.emplace_back(checkbox);
|
||||
wndShowCustomFields->add(checkbox);
|
||||
pos_y += checkbox->getHeight() + 8;
|
||||
break;
|
||||
}
|
||||
case bool_type: {
|
||||
auto checkbox = new gcn::CheckBox(custom_field.caption);
|
||||
checkbox->setSelected(custom_field.value);
|
||||
checkbox->addActionListener(showCustomFieldsActionListener);
|
||||
checkbox->setId("chkCustomFieldBool_" + std::to_string(i));
|
||||
checkbox->setPosition(pos_x2, pos_y);
|
||||
widget.boolean.emplace_back(checkbox);
|
||||
wndShowCustomFields->add(checkbox);
|
||||
pos_y += checkbox->getHeight() + 8;
|
||||
break;
|
||||
}
|
||||
case list_type: {
|
||||
label->setCaption(custom_field.caption);
|
||||
label->adjustSize();
|
||||
for (const auto& item : custom_field.labels)
|
||||
{
|
||||
custom_list[custom_list_index].add(item);
|
||||
}
|
||||
auto dropdown = new gcn::DropDown(&custom_list[custom_list_index]);
|
||||
dropdown->setId("cboCustomFieldList_" + std::to_string(i));
|
||||
dropdown->setSize(textfield_width, dropdown->getHeight());
|
||||
dropdown->setBaseColor(gui_baseCol);
|
||||
dropdown->setBackgroundColor(colTextboxBackground);
|
||||
dropdown->addActionListener(showCustomFieldsActionListener);
|
||||
dropdown->setPosition(pos_x2, pos_y);
|
||||
widget.list.emplace_back(dropdown);
|
||||
wndShowCustomFields->add(dropdown);
|
||||
pos_y += dropdown->getHeight() + 8;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
pos_y += label->getHeight() + 8;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void delete_custom_field(custom_widget& customField) {
|
||||
for (const auto& lbl : customField.lbl) {
|
||||
delete lbl;
|
||||
}
|
||||
customField.lbl.clear();
|
||||
|
||||
for (const auto& chk : customField.boolean) {
|
||||
delete chk;
|
||||
}
|
||||
customField.boolean.clear();
|
||||
|
||||
for (const auto& chk : customField.bit) {
|
||||
delete chk;
|
||||
}
|
||||
customField.bit.clear();
|
||||
|
||||
for (const auto& cbo : customField.list) {
|
||||
delete cbo;
|
||||
}
|
||||
customField.list.clear();
|
||||
}
|
||||
|
||||
static void InitShowCustomFields()
|
||||
{
|
||||
wndShowCustomFields = new gcn::Window("Custom Fields");
|
||||
wndShowCustomFields->setSize(DIALOG_WIDTH, DIALOG_HEIGHT);
|
||||
wndShowCustomFields->setPosition((GUI_WIDTH - DIALOG_WIDTH) / 2, (GUI_HEIGHT - DIALOG_HEIGHT) / 2);
|
||||
wndShowCustomFields->setBaseColor(gui_baseCol);
|
||||
wndShowCustomFields->setTitleBarHeight(TITLEBAR_HEIGHT);
|
||||
|
||||
showCustomFieldsActionListener = new ShowCustomFieldsActionListener();
|
||||
int pos_y = DISTANCE_BORDER;
|
||||
|
||||
for (auto& i : custom_list)
|
||||
{
|
||||
i.clear();
|
||||
}
|
||||
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
create_custom_field(*customWidgets[i], custom_number[i], "Custom" + std::to_string(i + 1), *customFields[i], pos_y, i);
|
||||
}
|
||||
cmdOK = new gcn::Button("Ok");
|
||||
cmdOK->setSize(BUTTON_WIDTH, BUTTON_HEIGHT);
|
||||
cmdOK->setPosition(DIALOG_WIDTH - DISTANCE_BORDER - BUTTON_WIDTH,
|
||||
DIALOG_HEIGHT - 2 * DISTANCE_BORDER - BUTTON_HEIGHT - 10);
|
||||
cmdOK->setBaseColor(gui_baseCol);
|
||||
cmdOK->addActionListener(showCustomFieldsActionListener);
|
||||
|
||||
wndShowCustomFields->add(cmdOK);
|
||||
|
||||
gui_top->add(wndShowCustomFields);
|
||||
|
||||
wndShowCustomFields->requestModalFocus();
|
||||
focus_bug_workaround(wndShowCustomFields);
|
||||
cmdOK->requestFocus();
|
||||
}
|
||||
|
||||
static void ExitShowCustomFields()
|
||||
{
|
||||
wndShowCustomFields->releaseModalFocus();
|
||||
gui_top->remove(wndShowCustomFields);
|
||||
|
||||
delete cmdOK;
|
||||
|
||||
delete_custom_field(customWidget1);
|
||||
delete_custom_field(customWidget2);
|
||||
delete_custom_field(customWidget3);
|
||||
delete_custom_field(customWidget4);
|
||||
delete_custom_field(customWidget5);
|
||||
|
||||
delete showCustomFieldsActionListener;
|
||||
delete wndShowCustomFields;
|
||||
}
|
||||
|
||||
static void ShowCustomFieldsLoop()
|
||||
{
|
||||
const AmigaMonitor* mon = &AMonitors[0];
|
||||
|
||||
auto got_event = 0;
|
||||
SDL_Event event;
|
||||
SDL_Event touch_event;
|
||||
didata* did = &di_joystick[0];
|
||||
while (SDL_PollEvent(&event))
|
||||
{
|
||||
switch (event.type)
|
||||
{
|
||||
case SDL_KEYDOWN:
|
||||
got_event = 1;
|
||||
switch (event.key.keysym.sym)
|
||||
{
|
||||
case VK_ESCAPE:
|
||||
dialog_finished = true;
|
||||
break;
|
||||
|
||||
case VK_Blue:
|
||||
case VK_Green:
|
||||
case SDLK_RETURN:
|
||||
event.key.keysym.sym = SDLK_RETURN;
|
||||
gui_input->pushInput(event); // Fire key down
|
||||
event.type = SDL_KEYUP; // and the key up
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_JOYBUTTONDOWN:
|
||||
if (gui_joystick)
|
||||
{
|
||||
got_event = 1;
|
||||
if (SDL_JoystickGetButton(gui_joystick, did->mapping.button[SDL_CONTROLLER_BUTTON_A]) ||
|
||||
SDL_JoystickGetButton(gui_joystick, did->mapping.button[SDL_CONTROLLER_BUTTON_B]))
|
||||
{
|
||||
PushFakeKey(SDLK_RETURN);
|
||||
break;
|
||||
}
|
||||
if (SDL_JoystickGetButton(gui_joystick, did->mapping.button[SDL_CONTROLLER_BUTTON_X]) ||
|
||||
SDL_JoystickGetButton(gui_joystick, did->mapping.button[SDL_CONTROLLER_BUTTON_Y]) ||
|
||||
SDL_JoystickGetButton(gui_joystick, did->mapping.button[SDL_CONTROLLER_BUTTON_START]))
|
||||
{
|
||||
dialog_finished = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_FINGERDOWN:
|
||||
got_event = 1;
|
||||
memcpy(&touch_event, &event, sizeof 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 * static_cast<int>(event.tfinger.x);
|
||||
touch_event.button.y = gui_graphics->getTarget()->h * static_cast<int>(event.tfinger.y);
|
||||
|
||||
gui_input->pushInput(touch_event);
|
||||
break;
|
||||
|
||||
case SDL_FINGERUP:
|
||||
got_event = 1;
|
||||
memcpy(&touch_event, &event, sizeof 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 * static_cast<int>(event.tfinger.x);
|
||||
touch_event.button.y = gui_graphics->getTarget()->h * static_cast<int>(event.tfinger.y);
|
||||
|
||||
gui_input->pushInput(touch_event);
|
||||
break;
|
||||
|
||||
case SDL_FINGERMOTION:
|
||||
got_event = 1;
|
||||
memcpy(&touch_event, &event, sizeof event);
|
||||
touch_event.type = SDL_MOUSEMOTION;
|
||||
touch_event.motion.which = 0;
|
||||
touch_event.motion.state = 0;
|
||||
|
||||
touch_event.motion.x = gui_graphics->getTarget()->w * static_cast<int>(event.tfinger.x);
|
||||
touch_event.motion.y = gui_graphics->getTarget()->h * static_cast<int>(event.tfinger.y);
|
||||
|
||||
gui_input->pushInput(touch_event);
|
||||
break;
|
||||
|
||||
case SDL_MOUSEWHEEL:
|
||||
got_event = 1;
|
||||
if (event.wheel.y > 0)
|
||||
{
|
||||
for (auto z = 0; z < event.wheel.y; ++z)
|
||||
{
|
||||
PushFakeKey(SDLK_UP);
|
||||
}
|
||||
}
|
||||
else if (event.wheel.y < 0)
|
||||
{
|
||||
for (auto z = 0; z > event.wheel.y; --z)
|
||||
{
|
||||
PushFakeKey(SDLK_DOWN);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_KEYUP:
|
||||
case SDL_JOYBUTTONUP:
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
case SDL_MOUSEMOTION:
|
||||
case SDL_RENDER_TARGETS_RESET:
|
||||
case SDL_RENDER_DEVICE_RESET:
|
||||
case SDL_WINDOWEVENT:
|
||||
case SDL_DISPLAYEVENT:
|
||||
case SDL_SYSWMEVENT:
|
||||
got_event = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
//-------------------------------------------------
|
||||
// Send event to guisan-controls
|
||||
//-------------------------------------------------
|
||||
gui_input->pushInput(event);
|
||||
}
|
||||
|
||||
if (got_event)
|
||||
{
|
||||
// Now we let the Gui object perform its logic.
|
||||
uae_gui->logic();
|
||||
|
||||
SDL_RenderClear(mon->sdl_renderer);
|
||||
|
||||
// Now we let the Gui object draw itself.
|
||||
uae_gui->draw();
|
||||
// Finally we update the screen.
|
||||
update_gui_screen();
|
||||
}
|
||||
}
|
||||
|
||||
void ShowCustomFields()
|
||||
{
|
||||
const AmigaMonitor* mon = &AMonitors[0];
|
||||
|
||||
dialog_finished = false;
|
||||
|
||||
// Initialize custom_number to 1
|
||||
std::fill(std::begin(custom_number), std::end(custom_number), 1);
|
||||
|
||||
// If the custom field is a bit field, set the custom_number to the number of pairs
|
||||
if (whdload_prefs.selected_slave.custom1.type == bit_type)
|
||||
custom_number[0] = static_cast<int>(whdload_prefs.selected_slave.custom1.label_bit_pairs.size());
|
||||
if (whdload_prefs.selected_slave.custom2.type == bit_type)
|
||||
custom_number[1] = static_cast<int>(whdload_prefs.selected_slave.custom2.label_bit_pairs.size());
|
||||
if (whdload_prefs.selected_slave.custom3.type == bit_type)
|
||||
custom_number[2] = static_cast<int>(whdload_prefs.selected_slave.custom3.label_bit_pairs.size());
|
||||
if (whdload_prefs.selected_slave.custom4.type == bit_type)
|
||||
custom_number[3] = static_cast<int>(whdload_prefs.selected_slave.custom4.label_bit_pairs.size());
|
||||
if (whdload_prefs.selected_slave.custom5.type == bit_type)
|
||||
custom_number[4] = static_cast<int>(whdload_prefs.selected_slave.custom5.label_bit_pairs.size());
|
||||
|
||||
InitShowCustomFields();
|
||||
|
||||
wndShowCustomFields->setCaption("Custom Fields");
|
||||
cmdOK->setCaption("Ok");
|
||||
|
||||
// Prepare the screen once
|
||||
uae_gui->logic();
|
||||
|
||||
SDL_RenderClear(mon->sdl_renderer);
|
||||
|
||||
uae_gui->draw();
|
||||
update_gui_screen();
|
||||
|
||||
while (!dialog_finished)
|
||||
{
|
||||
const auto start = SDL_GetPerformanceCounter();
|
||||
ShowCustomFieldsLoop();
|
||||
cap_fps(start);
|
||||
}
|
||||
|
||||
create_startup_sequence();
|
||||
ExitShowCustomFields();
|
||||
}
|
||||
@ -322,6 +322,11 @@ void ExitPanelVirtualKeyboard();
|
||||
void RefreshPanelVirtualKeyboard();
|
||||
bool HelpPanelVirtualKeyboard(std::vector<std::string>& helptext);
|
||||
|
||||
void InitPanelWHDLoad(const struct config_category& category);
|
||||
void ExitPanelWHDLoad();
|
||||
void RefreshPanelWHDLoad();
|
||||
bool HelpPanelWHDLoad(std::vector<std::string>& helptext);
|
||||
|
||||
void refresh_all_panels();
|
||||
void register_refresh_func(void (*func)());
|
||||
void focus_bug_workaround(gcn::Window* wnd);
|
||||
@ -340,9 +345,10 @@ bool EditFilesysHardDrive(int unit_no);
|
||||
bool CreateFilesysHardfile();
|
||||
void ShowHelp(const char* title, const std::vector<std::string>& text);
|
||||
void ShowDiskInfo(const char* title, const std::vector<std::string>& text);
|
||||
void ShowCustomFields();
|
||||
|
||||
std::string show_controller_map(int device, bool map_touchpad);
|
||||
extern void read_directory(std::string path, vector<string>* dirs, vector<string>* files);
|
||||
extern void read_directory(const std::string& path, vector<string>* dirs, vector<string>* files);
|
||||
extern void FilterFiles(vector<string>* files, const char* filter[]);
|
||||
|
||||
enum
|
||||
@ -371,6 +377,7 @@ STATIC_INLINE bool is_hdf_rdb()
|
||||
return current_hfdlg.ci.sectors == 0 && current_hfdlg.ci.surfaces == 0 && current_hfdlg.ci.reserved == 0;
|
||||
}
|
||||
|
||||
extern std::string whdload_filename;
|
||||
extern std::string screenshot_filename;
|
||||
extern int currentStateNum;
|
||||
extern int delay_savestate_frame;
|
||||
@ -390,6 +397,8 @@ extern int todfxtype(int num, int dfx, int* subtype);
|
||||
extern void DisplayDiskInfo(int num);
|
||||
extern std::string get_full_path_from_disk_list(std::string element);
|
||||
extern amiberry_hotkey get_hotkey_from_config(std::string config_option);
|
||||
extern void save_mapping_to_file(std::string mapping);
|
||||
extern void save_mapping_to_file(const std::string& mapping);
|
||||
extern void clear_whdload_prefs();
|
||||
extern void create_startup_sequence();
|
||||
|
||||
#endif // GUI_HANDLING_H
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
#include <guisan.hpp>
|
||||
#include <SDL_image.h>
|
||||
@ -91,6 +92,7 @@ ConfigCategory categories[] = {
|
||||
{"Virtual Keyboard", "keyboard.png", nullptr, nullptr, InitPanelVirtualKeyboard,
|
||||
ExitPanelVirtualKeyboard, RefreshPanelVirtualKeyboard, HelpPanelVirtualKeyboard
|
||||
},
|
||||
{"WHDLoad", "drive.ico", nullptr, nullptr, InitPanelWHDLoad, ExitPanelWHDLoad, RefreshPanelWHDLoad, HelpPanelWHDLoad},
|
||||
|
||||
{nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}
|
||||
};
|
||||
@ -248,28 +250,23 @@ static void show_help_requested()
|
||||
|
||||
void cap_fps(Uint64 start)
|
||||
{
|
||||
int refresh_rate;
|
||||
const auto end = SDL_GetPerformanceCounter();
|
||||
const auto elapsed_ms = static_cast<float>(end - start) / static_cast<float>(SDL_GetPerformanceFrequency()) * 1000.0f;
|
||||
#ifdef USE_DISPMANX
|
||||
refresh_rate = 60;
|
||||
#else
|
||||
refresh_rate = sdl_mode.refresh_rate;
|
||||
if (refresh_rate < 50) refresh_rate = 50;
|
||||
if (refresh_rate > 60) refresh_rate = 60;
|
||||
const int refresh_rate = std::clamp(sdl_mode.refresh_rate, 50, 60);
|
||||
#endif
|
||||
float d = 0.0f;
|
||||
if (refresh_rate == 60)
|
||||
d = floor(16.666f - elapsed_ms);
|
||||
else
|
||||
d = floor(20.000f - elapsed_ms);
|
||||
const float frame_time = 1000.0f / refresh_rate;
|
||||
const float delay_time = frame_time - elapsed_ms;
|
||||
|
||||
if( d > 0.0f ) SDL_Delay( Uint32(d) );
|
||||
if (delay_time > 0.0f)
|
||||
SDL_Delay(static_cast<Uint32>(delay_time));
|
||||
}
|
||||
|
||||
void update_gui_screen()
|
||||
{
|
||||
AmigaMonitor* mon = &AMonitors[0];
|
||||
const AmigaMonitor* mon = &AMonitors[0];
|
||||
#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);
|
||||
@ -557,7 +554,7 @@ void amiberry_gui_halt()
|
||||
|
||||
void check_input()
|
||||
{
|
||||
AmigaMonitor* mon = &AMonitors[0];
|
||||
const AmigaMonitor* mon = &AMonitors[0];
|
||||
|
||||
auto got_event = 0;
|
||||
didata* did = &di_joystick[0];
|
||||
@ -928,11 +925,7 @@ void check_input()
|
||||
//-------------------------------------------------
|
||||
// Send event to gui-controls
|
||||
//-------------------------------------------------
|
||||
#ifdef ANDROID
|
||||
androidsdl_event(gui_event, gui_input);
|
||||
#else
|
||||
gui_input->pushInput(gui_event);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (got_event)
|
||||
@ -950,7 +943,7 @@ void check_input()
|
||||
|
||||
void amiberry_gui_run()
|
||||
{
|
||||
AmigaMonitor* mon = &AMonitors[0];
|
||||
const AmigaMonitor* mon = &AMonitors[0];
|
||||
|
||||
if (amiberry_options.gui_joystick_control)
|
||||
{
|
||||
@ -1010,72 +1003,84 @@ class MainButtonActionListener : public gcn::ActionListener
|
||||
public:
|
||||
void action(const gcn::ActionEvent& actionEvent) override
|
||||
{
|
||||
if (actionEvent.getSource() == cmdShutdown)
|
||||
const auto source = actionEvent.getSource();
|
||||
if (source == cmdShutdown)
|
||||
{
|
||||
// ------------------------------------------------
|
||||
// Shutdown the host (power off)
|
||||
// ------------------------------------------------
|
||||
uae_quit();
|
||||
gui_running = false;
|
||||
host_poweroff = true;
|
||||
shutdown_host();
|
||||
}
|
||||
else if (source == cmdQuit)
|
||||
{
|
||||
quit_program();
|
||||
}
|
||||
else if (source == cmdReset)
|
||||
{
|
||||
reset_amiga();
|
||||
}
|
||||
else if (source == cmdRestart)
|
||||
{
|
||||
restart_emulator();
|
||||
}
|
||||
else if (source == cmdStart)
|
||||
{
|
||||
start_emulation();
|
||||
}
|
||||
else if (source == cmdHelp)
|
||||
{
|
||||
show_help();
|
||||
}
|
||||
}
|
||||
private:
|
||||
static void shutdown_host()
|
||||
{
|
||||
uae_quit();
|
||||
gui_running = false;
|
||||
host_poweroff = true;
|
||||
}
|
||||
|
||||
if (actionEvent.getSource() == cmdQuit)
|
||||
static void quit_program()
|
||||
{
|
||||
uae_quit();
|
||||
gui_running = false;
|
||||
}
|
||||
|
||||
static void reset_amiga()
|
||||
{
|
||||
uae_reset(1, 1);
|
||||
gui_running = false;
|
||||
}
|
||||
|
||||
static void 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(&changed_prefs, -1, tmp);
|
||||
gui_running = false;
|
||||
}
|
||||
|
||||
static void start_emulation()
|
||||
{
|
||||
if (emulating && cmdStart->isEnabled())
|
||||
{
|
||||
//-------------------------------------------------
|
||||
// Quit entire program via click on Quit-button
|
||||
//-------------------------------------------------
|
||||
uae_quit();
|
||||
gui_running = false;
|
||||
}
|
||||
else if (actionEvent.getSource() == cmdReset)
|
||||
else
|
||||
{
|
||||
//-------------------------------------------------
|
||||
// Reset Amiga via click on Reset-button
|
||||
//-------------------------------------------------
|
||||
uae_reset(1, 1);
|
||||
uae_reset(0, 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(&changed_prefs, -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();
|
||||
}
|
||||
}
|
||||
|
||||
static void show_help()
|
||||
{
|
||||
show_help_requested();
|
||||
cmdHelp->requestFocus();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -20,8 +20,8 @@
|
||||
#define GETBDM(x) (((x) - (((x) / 10000) * 10000)) / 100)
|
||||
#define GETBDD(x) ((x) % 100)
|
||||
|
||||
#define AMIBERRYVERSION _T("Amiberry v5.6.9 (2024-09-09)")
|
||||
#define AMIBERRYDATE MAKEBD(2024, 3, 9)
|
||||
#define AMIBERRYVERSION _T("Amiberry v5.6.9 (2024-03-17)")
|
||||
#define AMIBERRYDATE MAKEBD(2024, 3, 17)
|
||||
#define COPYRIGHT _T("Copyright (C) 2016-2024 Dimitris Panokostas")
|
||||
|
||||
#define IHF_WINDOWHIDDEN 6
|
||||
@ -129,6 +129,7 @@ extern void get_rp9_path(char* out, int size);
|
||||
extern std::string get_screenshot_path();
|
||||
|
||||
extern void extract_filename(const char* str, char* buffer);
|
||||
extern std::string extract_filename(const std::string& path);
|
||||
extern void extract_path(char* str, char* buffer);
|
||||
extern std::string extract_path(const std::string& filename);
|
||||
extern void remove_file_extension(char* filename);
|
||||
@ -158,17 +159,13 @@ typedef struct
|
||||
|
||||
extern std::vector<AvailableROM*> lstAvailableROMs;
|
||||
|
||||
#define MAX_MRU_DISKLIST 40
|
||||
#define MAX_MRU_LIST 40
|
||||
|
||||
extern std::vector<std::string> lstMRUDiskList;
|
||||
extern void AddFileToDiskList(const char* file, int moveToTop);
|
||||
|
||||
#define MAX_MRU_CDLIST 10
|
||||
extern std::vector<std::string> lstMRUCDList;
|
||||
extern void AddFileToCDList(const char* file, int moveToTop);
|
||||
|
||||
#define MAX_MRU_WHDLOADLIST 10
|
||||
extern std::vector<std::string> lstMRUWhdloadList;
|
||||
extern void AddFileToWHDLoadList(const char* file, int moveToTop);
|
||||
|
||||
extern void add_file_to_mru_list(std::vector<std::string>& vec, const std::string& file);
|
||||
|
||||
int count_HDs(struct uae_prefs* p);
|
||||
extern void gui_force_rtarea_hdchange(void);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user