WHDLoad Booter Direct within Amiberry (#283)

* WHDBooter Itegration

* Further WHDBoot development

* Clean-ups and beginning of kick-rom checking

* Loads matching .whd (database) config file from game-data folder, and .uae from /confs/ - start of host options

* Fixes problem with saving of equally-named config. Some Host options being set from hard-code variables. (WIP)

* Solution for host controller settings implemented

* Example Template files (not final versions)

* Game information (future database info) is imported from .whd file, .controls (customs) also loaded

* Tidies up auto-loading of existing .uae config

* Separates WHDLoad Booter into it's own module. `amiberry_whdbooter.cpp`

* Many options now implemented from .whd (cpu speed and memory to-do)

* Y offset, Memory , Clock Speed options added - all needed options now being implemented

* Compatibility settings now correctly read from XML file (or fall-back to individual game file) and are applied

* Custom controls now imported from XML.

* Hostconfig options and general near-completion of WHDBooter

* Final change and example XML file provided
This commit is contained in:
Horace And The Spider 2018-03-11 20:09:57 +00:00 committed by Dimitris Panokostas
parent 4344d6d55d
commit af82ad7833
69 changed files with 1115 additions and 1 deletions

View file

@ -326,6 +326,7 @@ OBJS = \
src/osdep/amiberry_gui.o \
src/osdep/amiberry_rp9.o \
src/osdep/amiberry_mem.o \
src/osdep/amiberry_whdbooter.o \
src/osdep/sigsegv_handler.o \
src/sounddep/sound.o \
src/osdep/gui/UaeRadioButton.o \

View file

@ -562,6 +562,10 @@ extern void fixup_cpu (struct uae_prefs *prefs);
extern void cfgfile_compatibility_romtype(struct uae_prefs *p);
extern void cfgfile_compatibility_rtg(struct uae_prefs *p);
extern void whdload_auto_prefs (struct uae_prefs *p, char* filename);
extern void check_prefs_changed_custom (void);
extern void check_prefs_changed_cpu (void);
extern void check_prefs_changed_audio (void);
@ -582,6 +586,7 @@ struct amiberry_customised_layout {
};
extern const int RemapEventList[];
extern const int RemapEventListSize;

View file

@ -463,6 +463,7 @@ void print_usage()
printf("\nUsage:\n");
printf(" -f <file> Load a configuration file.\n");
printf(" -config=<file> Load a configuration file.\n");
printf(" -autowhdload=<file> Load a WHDLoad game pack.\n");
printf(" -statefile=<file> Load a save state file.\n");
printf(" -s <config param>=<value> Set the configuration parameter with value.\n");
printf(" Edit a configuration file in order to know valid parameters and settings.\n");
@ -517,6 +518,13 @@ static void parse_cmdline(int argc, TCHAR **argv)
xfree(txt);
loaded = true;
}
else if (_tcsncmp(argv[i], _T("-autowhdload="), 13) == 0) {
TCHAR *txt = parsetextpath(argv[i] + 13);
whdload_auto_prefs (&currprefs, txt);
xfree(txt);
firstconfig = false;
loaded = true;
}
else if (_tcscmp(argv[i], _T("-f")) == 0) {
/* Check for new-style "-f xxx" argument, where xxx is config-file */
if (i + 1 == argc) {

View file

@ -0,0 +1,857 @@
/*
* UAE - The Un*x Amiga Emulator
*
* Amiberry interface
*
*/
#include <algorithm>
#include <iostream>
#include <vector>
#include <cstdlib>
#include <cstdarg>
#include <asm/sigcontext.h>
#include <csignal>
#include <dlfcn.h>
#ifndef ANDROID
#include <execinfo.h>
#endif
#include "sysconfig.h"
#include "sysdeps.h"
#include "config.h"
#include "uae.h"
#include "options.h"
#include "custom.h"
#include "inputdevice.h"
#include "disk.h"
#include "savestate.h"
#include "rommgr.h"
#include "zfile.h"
#include <SDL.h>
#include "amiberry_rp9.h"
#include "machdep/rpt.h"
#include "threaddep/thread.h"
#include "include/memory.h"
#include "keyboard.h"
#include "rtgmodes.h"
#include "gfxboard.h"
#include "amiberry_gfx.h"
#ifdef USE_SDL2
#include <map>
#endif
#ifdef WITH_LOGGING
extern FILE *debugfile;
#endif
#include "crc32.h"
#include "fsdb.h"
#include <libxml/tree.h>
#include <libxml/parser.h>
#include <libxml/xmlmemory.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
extern void SetLastActiveConfig(const char* filename);
//char start_path_data[MAX_DPATH];
//char currentDir[MAX_DPATH];
//static char config_path[MAX_DPATH];
//char last_loaded_config[MAX_DPATH] = {'\0'};
extern char start_path_data[MAX_DPATH];
extern char currentDir[MAX_DPATH];
extern char last_loaded_config[MAX_DPATH];
#include "zfile.h" /// Horace added
#include <fstream> /// Horace added
#include <string> /// Horace added (to remove)
struct game_options {
TCHAR port0[256] = "nul\0";
TCHAR port1[256] = "nul\0";
TCHAR control[256] = "nul\0";
TCHAR control2[256] = "nul\0";
TCHAR fastcopper[256] = "nul\0";
TCHAR cpu[256] = "nul\0";
TCHAR blitter[256] = "nul\0";
TCHAR clock[256] = "nul\0";
TCHAR chipset[256] = "nul\0";
TCHAR jit[256] = "nul\0";
TCHAR cpu_comp[256] = "nul\0";
TCHAR sprites[256] = "nul\0";
TCHAR scr_height[256] = "nul\0";
TCHAR y_offset[256] = "nul\0";
TCHAR ntsc[256] = "nul\0";
TCHAR chip[256] = "nul\0";
TCHAR fast[256] = "nul\0";
TCHAR z3[256] = "nul\0";
};
struct host_options {
TCHAR controller1[256] = "nul\0";
TCHAR controller2[256] = "nul\0";
TCHAR controller3[256] = "nul\0";
TCHAR controller4[256] = "nul\0";
TCHAR mouse1[256] = "nul\0";
TCHAR mouse2[256] = "nul\0";
TCHAR ra_quit[256] = "nul\0";
TCHAR ra_menu[256] = "nul\0";
TCHAR ra_reset[256] = "nul\0";
TCHAR key_quit[256] = "nul\0";
TCHAR key_gui[256] = "nul\0";
TCHAR deadzone[256] = "nul\0";
TCHAR stereo_split[256] = "nul\0";
TCHAR sound_on[256] = "nul\0";
TCHAR sound_mode[256] = "nul\0";
TCHAR frameskip[256] = "nul\0";
TCHAR aspect_ratio[256] = "nul\0";
};
static xmlNode* get_node(xmlNode* node, const char* name)
{
for (auto curr_node = node; curr_node; curr_node = curr_node->next)
{
if (curr_node->type == XML_ELEMENT_NODE && strcmp(reinterpret_cast<const char *>(curr_node->name), name) == 0)
return curr_node->children;
}
return nullptr;
}
static bool get_value(xmlNode* node, const char* key, char* value, int max_size)
{
auto result = false;
for (auto curr_node = node; curr_node; curr_node = curr_node->next)
{
if (curr_node->type == XML_ELEMENT_NODE && strcmp(reinterpret_cast<const char *>(curr_node->name), key) == 0)
{
const auto content = xmlNodeGetContent(curr_node);
if (content != nullptr)
{
strncpy(value, reinterpret_cast<char *>(content), max_size);
xmlFree(content);
result = true;
}
break;
}
}
return result;
}
static TCHAR *parsetext(const TCHAR *s)
{
if (*s == '"' || *s == '\'') {
TCHAR *d;
TCHAR c = *s++;
int i;
d = my_strdup(s);
for (i = 0; i < _tcslen(d); i++) {
if (d[i] == c) {
d[i] = 0;
break;
}
}
return d;
}
else {
return my_strdup(s);
}
}
static TCHAR *parsetextpath(const TCHAR *s)
{
TCHAR *s2 = parsetext(s);
TCHAR *s3 = target_expand_environment(s2, NULL, 0);
xfree(s2);
return s3;
}
long GetFileSize(std::string filename)
{
struct stat stat_buf;
int rc = stat(filename.c_str(), &stat_buf);
return rc == 0 ? stat_buf.st_size : -1;
}
void RemoveChar(char* array, int len, int index)
{
for(int i = index; i < len-1; ++i)
array[i] = array[i+1];
array[len-1] = 0;
}
void parse_custom_settings(struct uae_prefs* p, char* InSettings)
{
char temp_options[4096];
strcpy(temp_options, InSettings);
char *full_line;
full_line = strtok (temp_options,"\n");
while (full_line != NULL)
{
std::string line = full_line;
std::string check = "amiberry_custom";
if(strstr(line.c_str(),check.c_str()) != NULL)
{
cfgfile_parse_line(p, full_line, 0);
}
full_line = strtok (NULL, "\n");
}
}
struct membuf : std::streambuf
{
membuf(char* begin, char* end) {
this->setg(begin, begin, end);
}
};
const TCHAR* find_whdload_game_option(const TCHAR* find_setting, char* whd_options)
{
char temp_options[4096];
char temp_setting[4096];
strcpy(temp_options, whd_options);
auto output = "nul";
char *full_line;
full_line = strtok (temp_options,"\n");
char *this_option;
while (full_line != NULL)
{
strcpy(temp_setting, find_setting);
strcat(temp_setting, "=");
if (strlen(full_line) >= strlen(temp_setting))
{
// check that the beginging of the full line
if (strncmp(temp_setting, full_line ,strlen(find_setting))==0)
{
std::string t = full_line;
t.erase (t.begin(),t.begin() + strlen(temp_setting));
output = &t[0u];
return output;
}
}
full_line = strtok (NULL, "\n");
}
return output;
}
struct game_options get_game_settings(char* HW)
{
struct game_options output_detail;
strcpy(output_detail.port0, find_whdload_game_option("PORT0",HW));
strcpy(output_detail.port1, find_whdload_game_option("PORT1",HW));
strcpy(output_detail.control, find_whdload_game_option("PRIMARY_CONTROL",HW));
strcpy(output_detail.control2, find_whdload_game_option("SECONDARY_CONTROL",HW));
strcpy(output_detail.fastcopper, find_whdload_game_option("FAST_COPPER",HW));
strcpy(output_detail.cpu, find_whdload_game_option("CPU",HW));
strcpy(output_detail.blitter, find_whdload_game_option("BLITTER",HW));
strcpy(output_detail.clock, find_whdload_game_option("CLOCK",HW));
strcpy(output_detail.chipset, find_whdload_game_option("CHIPSET",HW));
strcpy(output_detail.jit, find_whdload_game_option("JIT",HW));
strcpy(output_detail.cpu_comp, find_whdload_game_option("CPU_COMPATIBLE",HW));
strcpy(output_detail.sprites, find_whdload_game_option("SPRITES",HW));
strcpy(output_detail.scr_height, find_whdload_game_option("SCREEN_HEIGHT",HW));
strcpy(output_detail.y_offset, find_whdload_game_option("SCREEN_Y_OFFSET",HW));
strcpy(output_detail.ntsc, find_whdload_game_option("NTSC",HW));
strcpy(output_detail.fast, find_whdload_game_option("FAST_RAM",HW));
strcpy(output_detail.z3, find_whdload_game_option("Z3_RAM",HW));
return output_detail;
}
struct host_options get_host_settings(char* HW)
{
struct host_options output_detail;
strcpy(output_detail.controller1, find_whdload_game_option("CONTROLLER_1",HW));
strcpy(output_detail.controller2, find_whdload_game_option("CONTROLLER_2",HW));
strcpy(output_detail.controller3, find_whdload_game_option("CONTROLLER_3",HW));
strcpy(output_detail.controller4, find_whdload_game_option("CONTROLLER_4",HW));
strcpy(output_detail.mouse1, find_whdload_game_option("CONTROLLER_MOUSE_1",HW));
strcpy(output_detail.mouse2, find_whdload_game_option("CONTROLLER_MOUSE_2",HW));
strcpy(output_detail.ra_quit, find_whdload_game_option("RETROARCH_QUIT",HW));
strcpy(output_detail.ra_menu, find_whdload_game_option("RETROARCH_MENU",HW));
strcpy(output_detail.ra_reset, find_whdload_game_option("RETROARCH_RESET",HW));
strcpy(output_detail.key_quit, find_whdload_game_option("KEY_FOR_QUIT",HW));
strcpy(output_detail.key_gui, find_whdload_game_option("KEY_FOR_MENU",HW));
strcpy(output_detail.deadzone, find_whdload_game_option("DEADZONE",HW));
strcpy(output_detail.stereo_split, find_whdload_game_option("STEREO_SPLIT",HW));
strcpy(output_detail.sound_on, find_whdload_game_option("SOUND_ON",HW));
strcpy(output_detail.sound_mode, find_whdload_game_option("SOUND_MODE",HW));
strcpy(output_detail.aspect_ratio, find_whdload_game_option("ASPECT_RATIO_FIX",HW));
strcpy(output_detail.frameskip, find_whdload_game_option("FRAMESKIP",HW));
return output_detail;
}
void symlink_roms(struct uae_prefs* p)
{
// *** KICKSTARTS ***
//
char KickPath[MAX_DPATH];
int rom_test;
int roms[2];
// here we can do some checks for Kickstarts we might need to make symlinks for
strncpy(currentDir, start_path_data, MAX_DPATH);
snprintf(KickPath, MAX_DPATH, "%s/whdboot/boot-data/Devs/Kickstarts/kick33180.A500", start_path_data);
if (!zfile_exists(KickPath))
{ roms[0] = 5; // kickstart 1.2 A500
rom_test = configure_rom(p, roms, 0); // returns 0 or 1 if found or not found
if (rom_test == 1)
symlink(p->romfile, KickPath);
}
snprintf(KickPath, MAX_DPATH, "%s/whdboot/boot-data/Devs/Kickstarts/kick34005.A500", start_path_data);
if (!zfile_exists(KickPath))
{ roms[0] = 6; // kickstart 1.3 A500
rom_test = configure_rom(p, roms, 0); // returns 0 or 1 if found or not found
printf(p->romfile);
printf("result: %d\n",rom_test);
if (rom_test == 1)
symlink(p->romfile, KickPath);
}
snprintf(KickPath, MAX_DPATH, "%s/whdboot/boot-data/Devs/Kickstarts/kick40068.A1200", start_path_data);
if (!zfile_exists(KickPath))
{ roms[0] = 15; // kickstart 3.1 A1200
rom_test = configure_rom(p, roms, 0); // returns 0 or 1 if found or not found
if (rom_test == 1)
symlink(p->romfile, KickPath);
}
}
void whdload_auto_prefs (struct uae_prefs* p, char* filepath)
{
// setup variables etc
TCHAR game_name[MAX_DPATH];;
TCHAR *txt2;
TCHAR tmp[MAX_DPATH];
TCHAR tmp2[MAX_DPATH];
char BootPath[MAX_DPATH];
char ConfigPath[MAX_DPATH];
// char GameTypePath[MAX_DPATH];
char WHDConfig[255];
int rom_test;
int *type;
auto config_type = CONFIG_TYPE_ALL;
char HardwareSettings[4096];
char CustomSettings[4096];
fetch_configurationpath(ConfigPath,MAX_DPATH);
//
// *** KICKSTARTS ***
symlink_roms(p);
// this allows A600HD to be used to slow games down
int roms[2];
roms[0] = 15; // kickstart 2.05 A600HD .. 10
rom_test = configure_rom(p, roms , 0); // returns 0 or 1 if found or not found
const int a600_available = rom_test;
//
// *** GAME DETECTION ***
// REMOVE THE FILE PATH AND EXTENSION
const TCHAR* filename = my_getfilepart(filepath);
// SOMEWHERE HERE WE NEED TO SET THE GAME 'NAME' FOR SAVESTATE ETC PURPOSES
extractFileName(filepath, last_loaded_config);
extractFileName(filepath, game_name);
removeFileExtension(game_name);
// find the SHA1 - this currently does not return the correct result!!
long filesize;
filesize = GetFileSize(filepath);
// const TCHAR* filesha = get_sha1_txt (input, filesize); <<< ??! FIX ME
// LOAD GAME SPECIFICS FOR EXISTING .UAE - USE SHA1 IF AVAILABLE
// CONFIG LOAD IF .UAE IS IN CONFIG PATH
strcpy(WHDConfig, ConfigPath);
strcat(WHDConfig, game_name);
strcat(WHDConfig,".uae");
if (zfile_exists(WHDConfig))
{ target_cfgfile_load(&currprefs, WHDConfig, CONFIG_TYPE_ALL, 0);
return;}
// LOAD HOST OPTIONS
char WHDPath[MAX_DPATH];
struct host_options host_detail;
snprintf(WHDPath, MAX_DPATH, "%s/whdboot/", start_path_data);
strcpy(WHDConfig, WHDPath);
strcat(WHDConfig,"hostprefs.conf");
if (zfile_exists(WHDConfig)) // use direct .whd file
{
ifstream readFile(WHDConfig);
std::ifstream in(WHDConfig);
std::string contents((std::istreambuf_iterator<char>(in)),
std::istreambuf_iterator<char>());
_stprintf(HardwareSettings, "%s",contents.c_str());
host_detail = get_host_settings(HardwareSettings);
}
// LOAD GAME SPECIFICS - USE SHA1 IF AVAILABLE
snprintf(WHDPath, MAX_DPATH, "%s/whdboot/game-data/", start_path_data);
struct game_options game_detail;
// EDIT THE FILE NAME TO USE HERE
strcpy(WHDConfig, WHDPath);
strcat(WHDConfig,game_name);
strcat(WHDConfig,".whd");
if (zfile_exists(WHDConfig)) // use direct .whd file
{
ifstream readFile(WHDConfig);
std::ifstream in(WHDConfig);
std::string contents((std::istreambuf_iterator<char>(in)),
std::istreambuf_iterator<char>());
_stprintf(HardwareSettings, "%s",contents.c_str());
game_detail = get_game_settings(HardwareSettings);
}
else
{
strcpy(WHDConfig, WHDPath);
strcat(WHDConfig, "whdload_db.xml");
if (zfile_exists(WHDConfig)) // use XML database
{
char buffer[4096];
xmlDocPtr doc;
xmlNodePtr game_node;
xmlNodePtr temp_node;
doc = xmlParseFile(WHDConfig);
const auto root_element = xmlDocGetRootElement(doc);
game_node = get_node(root_element, "whdbooter");
while (game_node != NULL)
{
auto attr = xmlGetProp(game_node, reinterpret_cast<const xmlChar *>("filename"));
if (attr != NULL)
{
if (strcmpi(reinterpret_cast<const char*>(attr),game_name) == 0)
{
// now get the <hardware> and <custom_controls> items
temp_node = game_node->xmlChildrenNode;
temp_node = get_node(temp_node, "hardware");
if (xmlNodeGetContent(temp_node) != NULL)
{
_stprintf(HardwareSettings, "%s",xmlNodeGetContent(temp_node));
game_detail = get_game_settings(HardwareSettings);
}
temp_node = game_node->xmlChildrenNode;
temp_node = get_node(temp_node, "custom_controls");
if (xmlNodeGetContent(temp_node) != NULL)
{
_stprintf(CustomSettings, "%s",xmlNodeGetContent(temp_node));
// process these later
}
break;
}
}
xmlFree(attr);
game_node = game_node->next;
}
xmlCleanupParser();
}
}
// debugging code!
// printf("port 0: %s \n",game_detail.port0);
// printf("port 1: %s \n",game_detail.port1);
// printf("contrl: %s \n",game_detail.control);
// printf("fstcpr: %s \n",game_detail.fastcopper);
// printf("cpu : %s \n",game_detail.cpu);
// printf("blitta: %s \n",game_detail.blitter);
// printf("clock : %s \n",game_detail.clock);
// printf("chipst: %s \n",game_detail.chipset);
// printf("jit : %s \n",game_detail.jit);
// printf("cpcomp: %s \n",game_detail.cpu_comp);
// printf("scrhei: %s \n",game_detail.scr_height);
// printf("scr y : %s \n",game_detail.y_offset);
// printf("ntsc : %s \n",game_detail.ntsc);
// printf("fast : %s \n",game_detail.fast);
// printf("z3 : %s \n",game_detail.z3);
// debugging code!
printf("cont 1: %s \n",host_detail.controller1);
printf("cont 2: %s \n",host_detail.controller2);
printf("cont 3: %s \n",host_detail.controller3);
printf("cont 4: %s \n",host_detail.controller4);
printf("mous 1: %s \n",host_detail.mouse1);
printf("mous 2: %s \n",host_detail.mouse2);
printf("ra_qui: %s \n",host_detail.ra_quit);
printf("ra_men: %s \n",host_detail.ra_menu);
printf("ra_rst: %s \n",host_detail.ra_reset);
printf("ky_qut: %s \n",host_detail.key_quit);
printf("ky_gui: %s \n",host_detail.key_gui);
printf("deadzn: %s \n",host_detail.stereo_split);
printf("stereo: %s \n",host_detail.stereo_split);
printf("snd_on: %s \n",host_detail.sound_on);
printf("snd_md: %s \n",host_detail.sound_mode);
printf("aspect: %s \n",host_detail.aspect_ratio);
printf("frames: %s \n",host_detail.frameskip);
//
// *** EMULATED HARDWARE ***
//
// SET UNIVERSAL DEFAULTS
p->start_gui = false;
if ((strcmpi(game_detail.cpu,"68000") == 0 || strcmpi(game_detail.cpu,"68010") == 0) && a600_available != 0)
// SET THE BASE AMIGA (Expanded A600)
{ built_in_prefs(&currprefs, 2, 2, 0, 0);
_stprintf(txt2,"chipmem_size=4");
cfgfile_parse_line(p, txt2, 0);
}
else
// SET THE BASE AMIGA (Expanded A1200)
{ built_in_prefs(&currprefs, 3, 1, 0, 0);
if ((strcmpi(game_detail.fast,"nul") != 0) && (strcmpi(game_detail.cpu,"nul") == 0))
strcpy(game_detail.cpu,_T("68020"));
}
// DO CHECKS FOR AGA / CD32
const int is_aga = (strstr(filename,"_AGA") != NULL || strcmpi(game_detail.chipset,"AGA") == 0);
const int is_cd32 = (strstr(filename,"_CD32") != NULL || strcmpi(game_detail.chipset,"CD32") == 0);
// A1200 no AGA
if (is_aga == false && is_cd32 == false)
{
_tcscpy(p->description, _T("WHDLoad AutoBoot Configuration"));
p->cs_compatible = CP_A600;
built_in_chipset_prefs(p);
p->chipset_mask = CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE;
p->m68k_speed = 0;
}
// A1200
else
_tcscpy(p->description, _T("WHDLoad AutoBoot Configuration [AGA]"));
//SET THE WHD BOOTER AND GAME DATA
snprintf(BootPath, MAX_DPATH, "%s/whdboot/boot-data/", start_path_data);
// set the first (whdboot) Drive
_stprintf(tmp,_T("filesystem2=rw,DH0:DH0:%s,10"),BootPath);
txt2 = parsetextpath(_T(tmp));
cfgfile_parse_line(p, txt2, 0);
_stprintf(tmp,_T("uaehf0=dir,rw,DH0:DH0::%s,10") , BootPath);
txt2 = parsetextpath(_T(tmp));
cfgfile_parse_line(p, txt2, 0);
//set the Second (game data) drive
_stprintf(tmp,"filesystem2=rw,DH1:games:%s,0" , filepath);
txt2 = parsetextpath(_T(tmp));
cfgfile_parse_line(p, txt2, 0);
_stprintf(tmp,"uaehf1=dir,rw,DH1:games:%s,0" , filepath);
txt2 = parsetextpath(_T(tmp));
cfgfile_parse_line(p, txt2, 0);
//APPLY THE SETTINGS FOR MOUSE/JOYSTICK ETC
// CD32
if ((is_cd32 == true && strcmpi(game_detail.port0,"nul") == 0)
|| strcmpi(game_detail.port0,"cd32") == 0)
p->jports[0].mode = 7;
if ((is_cd32 == true && strcmpi(game_detail.port1,"nul") == 0)
|| strcmpi(game_detail.port1,"cd32") == 0)
p->jports[1].mode = 7;
// JOY
if (strcmpi(game_detail.port0,"joy") == 0)
p->jports[0].mode = 3;
if (strcmpi(game_detail.port1,"joy") == 0)
p->jports[1].mode = 3;
// MOUSE
if (strcmpi(game_detail.port0,"mouse") == 0)
p->jports[0].mode = 2;
if (strcmpi(game_detail.port1,"mouse") == 0)
p->jports[1].mode = 2;
// APPLY SPECIAL CONFIG E.G. MOUSE OR ALT. JOYSTICK SETTINGS
for (auto i = 0; i < MAX_JPORTS; i++)
{
p->jports[i].id = JPORT_NONE;
p->jports[i].idc.configname[0] = 0;
p->jports[i].idc.name[0] = 0;
p->jports[i].idc.shortid[0] = 0;
}
// WHAT IS THE MAIN CONTROL?
// MOUSE GAMES
if (strcmpi(game_detail.control,"mouse") == 0 && strcmpi(host_detail.mouse1,"nul") != 0)
{ _stprintf(txt2,"%s=%s",_T("joyport0"),_T(host_detail.mouse1));
cfgfile_parse_line(p, txt2, 0); }
if (strcmpi(game_detail.control,"mouse") == 0 && strcmpi(host_detail.mouse2,"nul") != 0)
{ _stprintf(txt2,"%s=%s",_T("joyport1"),_T(host_detail.mouse2));
cfgfile_parse_line(p, txt2, 0);
}
// JOYSTICK GAMES
if (!strcmpi(game_detail.control,"mouse") == 0 && strcmpi(host_detail.controller1,"nul") != 0)
{ _stprintf(txt2,"%s=%s",_T("joyport1"),_T(host_detail.controller1));
cfgfile_parse_line(p, txt2, 0); }
if (!strcmpi(game_detail.control,"mouse") == 0 && strcmpi(host_detail.controller2,"nul") != 0)
{ _stprintf(txt2,"%s=%s",_T("joyport0"),_T(host_detail.controller2));
cfgfile_parse_line(p, txt2, 0);
}
// PARALLEL PORT GAMES
if (strcmpi(host_detail.controller3,"nul") != 0)
{ _stprintf(txt2,"%s=%s",_T("joyport2"),_T(host_detail.controller3));
cfgfile_parse_line(p, txt2, 0);
}
if (strcmpi(host_detail.controller4,"nul") != 0)
{ _stprintf(txt2,"%s=%s",_T("joyport3"),_T(host_detail.controller4));
cfgfile_parse_line(p, txt2, 0);
}
// CUSTOM CONTROLS
if (strlen(CustomSettings) > 0 )
parse_custom_settings(p, CustomSettings);
if (!strcmpi(host_detail.deadzone,"nul") == 0)
{ _stprintf(txt2,"input.joymouse_deadzone=%s",_T(host_detail.deadzone));
cfgfile_parse_line(p, txt2, 0);
_stprintf(txt2,"input.joystick_deadzone=%s",_T(host_detail.deadzone));
cfgfile_parse_line(p, txt2, 0);
}
// RETROARCH CONTROLS
if (!strcmpi(host_detail.ra_quit,"nul") == 0)
{ _stprintf(txt2,"amiberry.use_retroarch_quit=%s",_T(host_detail.ra_quit));
cfgfile_parse_line(p, txt2, 0);
}
if (!strcmpi(host_detail.ra_menu,"nul") == 0)
{ _stprintf(txt2,"amiberry.use_retroarch_menu=%s",_T(host_detail.ra_menu));
cfgfile_parse_line(p, txt2, 0);
}
if (!strcmpi(host_detail.ra_reset,"nul") == 0)
{ _stprintf(txt2,"amiberry.use_retroarch_reset=%s",_T(host_detail.ra_reset));
cfgfile_parse_line(p, txt2, 0);
}
// KEYBOARD CONTROLS
if (!strcmpi(host_detail.key_quit,"nul") == 0)
{ _stprintf(txt2,"amiberry.quit_amiberry=%s",_T(host_detail.key_quit));
cfgfile_parse_line(p, txt2, 0);
}
if (!strcmpi(host_detail.key_gui,"nul") == 0)
{ _stprintf(txt2,"amiberry.open_gui=%s",_T(host_detail.key_gui));
cfgfile_parse_line(p, txt2, 0);
}
// GRAPHICS OPTIONS
if (!strcmpi(host_detail.aspect_ratio,"nul") == 0)
{ _stprintf(txt2,"amiberry.gfx_correct_aspect=%s",_T(host_detail.aspect_ratio));
cfgfile_parse_line(p, txt2, 0);
}
if (!strcmpi(host_detail.frameskip,"nul") == 0)
{ _stprintf(txt2,"gfx_framerate=%s",_T(host_detail.frameskip));
cfgfile_parse_line(p, txt2, 0);
}
// SOUND OPTIONS
if (!strcmpi(host_detail.sound_on,"false") == 0 || !strcmpi(host_detail.sound_on,"off") == 0 || !strcmpi(host_detail.sound_on,"none") == 0)
{ _stprintf(txt2,"sound_output=none");
cfgfile_parse_line(p, txt2, 0);
}
if (!strcmpi(host_detail.stereo_split,"nul") == 0)
{ _stprintf(txt2,"sound_stereo_separation=%s",_T(host_detail.stereo_split));
cfgfile_parse_line(p, txt2, 0);
}
// *** GAME-SPECIFICS ***
// SET THE GAME COMPATIBILITY SETTINGS
//
// SCREEN HEIGHT, BLITTER, SPRITES, MEMORY, JIT, BIG CPU ETC
// CPU 68020/040
if (strcmpi(game_detail.cpu,"68020") == 0 || strcmpi(game_detail.cpu,"68040") == 0)
{ _stprintf(txt2,"cpu_type=%s",game_detail.cpu);
cfgfile_parse_line(p, txt2, 0); }
// CPU 68000/010 [requires a600 rom)]
if ((strcmpi(game_detail.cpu,"68000") == 0 || strcmpi(game_detail.cpu,"68010") == 0) && a600_available != 0)
{ _stprintf(txt2,"cpu_type=%s",game_detail.cpu);
cfgfile_parse_line(p, txt2, 0); }
// CPU SPEED
if (strcmpi(game_detail.clock,"7") == 0)
{ _stprintf(txt2,"cpu_speed=real");
cfgfile_parse_line(p, txt2, 0); }
else if (strcmpi(game_detail.clock,"14") == 0)
{ _stprintf(txt2,"finegrain_cpu_speed=1024");
cfgfile_parse_line(p, txt2, 0); }
else if (strcmpi(game_detail.clock,"28") == 0)
{ _stprintf(txt2,"finegrain_cpu_speed=128");
cfgfile_parse_line(p, txt2, 0); }
else if (strcmpi(game_detail.clock,"max") == 0)
{ _stprintf(txt2,"cpu_speed=max");
cfgfile_parse_line(p, txt2, 0); }
else if (strcmpi(game_detail.clock,"turbo") == 0)
{ _stprintf(txt2,"cpu_speed=turbo");
cfgfile_parse_line(p, txt2, 0); }
//FAST / Z3 MEMORY REQUIREMENTS
int temp_ram;
if (strcmpi(game_detail.fast,"nul") != 0)
{
temp_ram = atol(game_detail.fast) ;
_stprintf(txt2,"fastmem_size=%d",temp_ram);
cfgfile_parse_line(p, txt2, 0);
}
if (strcmpi(game_detail.fast,"nul") != 0)
{
temp_ram = atol(game_detail.z3) ;
_stprintf(txt2,"z3mem_size=%d",temp_ram);
cfgfile_parse_line(p, txt2, 0);
}
// FAST COPPER
if (strcmpi(game_detail.fastcopper,"true") == 0)
{ _stprintf(txt2,"fast_copper=true");
cfgfile_parse_line(p, txt2, 0); }
// BLITTER=IMMEDIATE/WAIT/NORMAL
if (strcmpi(game_detail.blitter,"immediate") == 0)
{ _stprintf(txt2,"immediate_blits=true");
cfgfile_parse_line(p, txt2, 0);
}
else if (strcmpi(game_detail.blitter,"normal") == 0)
{ _stprintf(txt2,"waiting_blits=disabled");
cfgfile_parse_line(p, txt2, 0); }
// CHIPSET OVERWRITE
if (strcmpi(game_detail.chipset,"ocs") == 0)
{ p->cs_compatible = CP_A600;
built_in_chipset_prefs(p);
p->chipset_mask = 0; }
else if (strcmpi(game_detail.chipset,"ecs") == 0)
{ p->cs_compatible = CP_A600;
built_in_chipset_prefs(p);
p->chipset_mask = CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE; }
else if (strcmpi(game_detail.chipset,"aga") == 0)
{ p->cs_compatible = CP_A1200;
built_in_chipset_prefs(p);
p->chipset_mask = CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE | CSMASK_AGA; }
// JIT
if (strcmpi(game_detail.jit,"true") == 0)
{ _stprintf(txt2,"cachesize=8192");
cfgfile_parse_line(p, txt2, 0); }
// COMPATIBLE CPU
if (strcmpi(game_detail.cpu_comp,"true") == 0)
{ _stprintf(txt2,"cpu_compatible=true");
cfgfile_parse_line(p, txt2, 0); }
// NTSC
if (strcmpi(game_detail.ntsc,"true") == 0)
{ _stprintf(txt2,"ntsc=true");
cfgfile_parse_line(p, txt2, 0); }
// NTSC
if (strcmpi(game_detail.ntsc,"true") == 0)
{ _stprintf(txt2,"ntsc=true");
cfgfile_parse_line(p, txt2, 0); }
// SCREEN HEIGHT
if (strcmpi(game_detail.scr_height,"nul") != 0 )
{ _stprintf(txt2,"gfx_height=%s",game_detail.scr_height);
cfgfile_parse_line(p, txt2, 0);
_stprintf(txt2,"gfx_height_windowed=%s",game_detail.scr_height);
cfgfile_parse_line(p, txt2, 0);
_stprintf(txt2,"gfx_height_fullscreen=%s",game_detail.scr_height);
cfgfile_parse_line(p, txt2, 0); }
// Y OFFSET
if (strcmpi(game_detail.y_offset,"nul") != 0 )
{ _stprintf(txt2,"amiberry.vertical_offset=%s",game_detail.y_offset);
cfgfile_parse_line(p, txt2, 0);
}
// SPRITE COLLISION
if (strcmpi(game_detail.scr_height,"nul") != 0 )
{ _stprintf(txt2,"collision_level=%s",game_detail.sprites);
cfgfile_parse_line(p, txt2, 0); }
// CLEAN UP SETTINGS
// fixup_prefs(&currprefs, true);
// cfgfile_configuration_change(1);
}

View file

@ -293,7 +293,15 @@ void InitPanelConfig(const struct _ConfigCategory& category)
category.panel->add(txtDesc, DISTANCE_BORDER + lblDesc->getWidth() + 8, txtName->getY() + txtName->getHeight() + DISTANCE_NEXT_Y);
if (strlen(last_active_config) == 0)
{
if (strlen(last_loaded_config) == 0)
strncpy(last_active_config, OPTIONSFILENAME, MAX_DPATH);
else
{
strcpy(last_active_config, last_loaded_config);
removeFileExtension(last_active_config);
}
}
txtName->setText(last_active_config);
txtDesc->setText(changed_prefs.description);
ensureVisible = -1;

BIN
whdboot/boot-data/C/Assign Executable file

Binary file not shown.

BIN
whdboot/boot-data/C/Copy Executable file

Binary file not shown.

BIN
whdboot/boot-data/C/Dir Executable file

Binary file not shown.

BIN
whdboot/boot-data/C/DiskInDrive Executable file

Binary file not shown.

BIN
whdboot/boot-data/C/Ed Executable file

Binary file not shown.

BIN
whdboot/boot-data/C/Execute Executable file

Binary file not shown.

BIN
whdboot/boot-data/C/GetMouseInput Executable file

Binary file not shown.

BIN
whdboot/boot-data/C/Info Executable file

Binary file not shown.

BIN
whdboot/boot-data/C/List Executable file

Binary file not shown.

BIN
whdboot/boot-data/C/Makedir Executable file

Binary file not shown.

BIN
whdboot/boot-data/C/Rename Executable file

Binary file not shown.

BIN
whdboot/boot-data/C/Search Executable file

Binary file not shown.

BIN
whdboot/boot-data/C/SetPatch Executable file

Binary file not shown.

BIN
whdboot/boot-data/C/Type Executable file

Binary file not shown.

BIN
whdboot/boot-data/C/Version Executable file

Binary file not shown.

BIN
whdboot/boot-data/C/WHDLoad Executable file

Binary file not shown.

BIN
whdboot/boot-data/C/Wait Executable file

Binary file not shown.

BIN
whdboot/boot-data/C/delete Executable file

Binary file not shown.

BIN
whdboot/boot-data/C/joytest Executable file

Binary file not shown.

BIN
whdboot/boot-data/C/jst Executable file

Binary file not shown.

BIN
whdboot/boot-data/C/kgiconload Executable file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,95 @@
C:Assign ENV: RAM: >nil:
C:Assign T: RAM: >nil:
C:Assign PROGDIR: C: >nil:
Resident C:WHDLoad PURE
Echo ""
; ======================
IF EXISTS C:SetPatch
C:SetPatch > NIL:
ENDIF
; ====================== Set path
info >t:tempfile DH1:
search >nil: t:tempfile "[Mounted]"
if not warn
Assign WHDLoadGame: DH1:
echo "WHDLoadGame: will be mapped to DH1:"
Echo ""
else
Assign WHDLoadGame: DH0:
echo "WHDLoadGame: will be mapped to DH0:"
Echo ""
endif
; ======================
C:GetMouseInput Local
IF $MouseInput EQ 1
Echo "Left Mouse Button held. Force creation of new Auto-Startup file"
Echo ""
ELSE
SET Reply `C:joytest 1 0`
IF $Reply EQ "(Fire-1)"
Echo "Joystick Fire held. Force creation of new Auto-Startup file"
Echo ""
ELSE
Echo "Scan for auto-startup and debugging messages..."
cd :WHDbooter/
Find_AutoStartup.exe
Echo "Scan done"
Echo ""
ENDIF
ENDIF
; ======= did we create a file earlier?
IF EXISTS T:auto-startup
Echo ""
ELSE
cd :WHDbooter/
GameBootLoader.exe scanpath=WHDLoadGame: only usefolderpath
ENDIF
; ======================
;IF EXISTS :WHDbooter/SplashScreen.exe
; cd :WHDbooter
; :WHDbooter/SplashScreen.exe >NIL:
;ELSE
; c:TUDE hardreset >nil:
;ENDIF
; +++ RUN IT
IF EXISTS T:auto-startup
Echo "Execute the Auto-Startup boot script."
Echo ""
c:execute T:auto-startup
ELSE
echo "Error: There is still no Auto-Startup boot script."
ENDIF
; c:TUDE hardreset >nil:

View file

@ -0,0 +1,32 @@
;
; global configuration file for WHDLoad
; searched as "S:whdload.prefs"
;
; CLI-Arguments and ToolTypes will overwrite these !
;
NoWriteCache ;disable the disk write cache
QuitKey=$5a ;rawkey code to quit
SplashDelay=0 ;time to display splash window (1/50 seconds)
SavePath=dh0:WHDBooter/Savegames/
;ButtonWait ;wait for button pressed (slave must support this)
;ChipNoCache ;disable cachebility of Chip-Memory
;CoreDumpPath=T: ;path for coredump files
;DebugKey=$5b ;rawkey code to quit with coredump (debug)
;ExecuteStartup=rx offline.rexx ;command to execute on WHDLoad startup
;ExecuteCleanup=rx online.rexx ;command to execute on WHDLoad exit
;Expert ;selects expert mode
;FreezeKey=$5d ;rawkey code to enter HrtMon/TK
;MMU ;use MMU (for 68030)
;NoAutoVec ;ignore unwanted autovector interrupts
;NoFilter ;disable audio filter
;NoFlushMem ;do not flush memory
;NoMemReverse ;do not allocate memory reverse
;ReadDelay=150 ;wait after reading from disk (1/50 seconds)
;RestartKey=$5c ;rawkey code to restart
;ShowRegs=SYS:Utilities/MuchMore W WL=80 WT=80 WW=582 WH=700 ;command for Show Regs
;WriteDelay=150 ;wait after saving something to disk (1/50 seconds)

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1 @@
C1:B:Infinite Lives;

View file

@ -0,0 +1,2 @@
C1:B:Infinite Lives;
C2:B:Infinite Missiles;

View file

@ -0,0 +1 @@
C1:B:Infinite Energy & Lives;

View file

@ -0,0 +1,4 @@
C1:B:Enable Trainers:0;
C2:L:Mouse Control Mode:None,LMB forward / RMB fire,LMB fire / RMB forward;
C3:B:Load Aminet Version (abd8ch):0;
C4:B:Enable main music at the end (HackAB3D):0;

View file

@ -0,0 +1,2 @@
C1:C:Enable Trainers;
C2:X:Load Rolling Demo;

View file

@ -0,0 +1,3 @@
C1:X:Enable in-game Trainers;
C2:X:Enable CD32 Controls;

View file

@ -0,0 +1,6 @@
C1:X:Infinite Lives:0;
C1:X:Infinite Weapons:1;
C1:X:Infinite Level Timer:2;
C1:X:Infinite Screen Timer:3;
C1:X:Enable Level Skip:4;
C2:B:Infinite Enable CD32 Controls;

View file

@ -0,0 +1,6 @@
C1:X:Infinite Lives:0;
C1:X:Infinite Weapons:1;
C1:X:Infinite Level Timer:2;
C1:X:Infinite Screen Timer:3;
C1:X:Enable Level Skip:4;
C2:B:Infinite Enable CD32 Controls;

View file

@ -0,0 +1,2 @@
C1:X:Player 1 Unlimited Lives;
C2:X:Player 2 Unlimited Lives ?;

View file

@ -0,0 +1 @@
C1:B:Faster Boot Option;

View file

@ -0,0 +1,2 @@
C1:X:Skip Intro;
C2:L:Select Speed:Fast,Normal,Slow;

View file

@ -0,0 +1 @@
C1:B:Faster Boot Option;

View file

@ -0,0 +1,3 @@
C1:X:Activate Original Cheat;
C2:L:Select Track:None,Track 1,Track 2,Track 3,Track 4,Track 5,Track 6,Track 7;
C3:X:Raise Panel (NTSC);

View file

@ -0,0 +1,58 @@
<whdbooter>
<game filename="IK+_v1.8_2063" sha1="066a43d17271b9f523350a8c3639c554c0a2bb0a">
<name>IK+</name>
<slave_count>1</slave_count>
<slave_default>IK+.slave</slave_default>
<hardware>
PRIMARY_CONTROL=JOYSTICK
PORT0=JOY
PORT1=JOY
SCREEN_HEIGHT=200
SCREEN_Y_OFFSET=8
FAST_RAM=1
</hardware>
<custom_controls></custom_controls>
</game>
<game filename="IndyHeat_v1.1" sha1="36ad3f8831240d77fa77b35da5e1af10df5b06ce">
<name>Indy Heat</name>
<slave_count>1</slave_count>
<slave_default>IndyHeat.slave</slave_default>
<hardware>
PRIMARY_CONTROL=JOYSTICK
PORT0=JOY
PORT1=JOY
SCREEN_HEIGHT=240
SCREEN_Y_OFFSET=3
FAST_RAM=1 </hardware>
<custom_controls>
joyport2_amiberry_custom_none_dpad_up=Cursor Up
joyport2_amiberry_custom_none_dpad_down=Cursor Down
joyport2_amiberry_custom_none_dpad_left=Cursor Left
joyport2_amiberry_custom_none_dpad_right=Cursor Right
joyport2_amiberry_custom_none_south=Right Shift
</custom_controls>
</game>
<game filename="OhNoMoreLemmings_v1.2_0697" sha1="">
<name>Oh No! More Lemmings</name>
<hardware>
PRIMARY_CONTROL=MOUSE
SECONDARY_CONTROL=MOUSE
PORT0=MOUSE
PORT1=MOUSE
SCREEN_HEIGHT=240
SCREEN_Y_OFFSET=3
FAST_RAM=1 </hardware>
<custom_controls>
joyport0_amiberry_custom_none_left_shoulder=Cursor Left
joyport0_amiberry_custom_none_east=P
joyport0_amiberry_custom_none_start=ESC
joyport0_amiberry_custom_none_right_shoulder=Cursor Right
joyport1_amiberry_custom_none_left_shoulder=Z
joyport1_amiberry_custom_none_east=P
joyport1_amiberry_custom_none_start=ESC
joyport1_amiberry_custom_none_right_shoulder=X
</custom_controls>
</game>
</whdbooter>

16
whdboot/hostprefs.conf Executable file
View file

@ -0,0 +1,16 @@
CONTROLLER_1=joy1
CONTROLLER_2=joy2
CONTROLLER_3=joy0
;CONTROLLER_4=
CONTROLLER_MOUSE_1=joy2
CONTROLLER_MOUSE_2=joy1
;RETROARCH_QUIT=TRUE
;RETROARCH_MENU=TRUE
;RETROARCH_RESET=TRUE
;KEY_FOR_QUIT=F12
;KEY_FOR_MENU=F11
;DEADZONE=
STEREO_SPLIT=1
;SOUND_ON=FALSE
;ASPECT_RATIO_FIX=TRUE
;FRAMESKIP=TRUE