1
0
mirror of https://github.com/mist-devel/mist-firmware.git synced 2026-01-11 23:43:04 +00:00

CFG updates

- convert corename.cfg to INI format
- mistcfg.ini as global config, writable by the firmware
- interactive setup of joystick_remap via the OSD
This commit is contained in:
Gyorgy Szombathelyi 2022-01-12 15:59:30 +01:00
parent a73183f987
commit e514a1bdc4
18 changed files with 340 additions and 111 deletions

View File

@ -11,7 +11,7 @@ TODAY = `date +"%m/%d/%y"`
PRJ = firmware
SRC = hw/AT91SAM/Cstartup_SAM7.c hw/AT91SAM/hardware.c hw/AT91SAM/spi.c hw/AT91SAM/mmc.c hw/AT91SAM/at91sam_usb.c hw/AT91SAM/usbdev.c
SRC += fdd.c firmware.c fpga.c hdd.c main.c menu.c minimig-menu.c osd.c state.c syscalls.c user_io.c data_io.c boot.c idxfile.c config.c tos.c ikbd.c xmodem.c ini_parser.c cue_parser.c mist_cfg.c archie.c pcecd.c arc_file.c font.c utils.c
SRC += fdd.c firmware.c fpga.c hdd.c main.c menu.c minimig-menu.c osd.c state.c syscalls.c user_io.c settings.c data_io.c boot.c idxfile.c config.c tos.c ikbd.c xmodem.c ini_parser.c cue_parser.c mist_cfg.c archie.c pcecd.c arc_file.c font.c utils.c
SRC += usb/max3421e.c usb/usb.c usb/usbdebug.c usb/hub.c usb/hid.c usb/hidparser.c usb/xboxusb.c usb/timer.c usb/asix.c usb/pl2303.c usb/usbrtc.c usb/joymapping.c usb/joystick.c
SRC += fat_compat.c
SRC += FatFs/diskio.c FatFs/ff.c FatFs/ffunicode.c

View File

@ -21,7 +21,7 @@ typedef struct {
static arc_t arc;
static int conf_ptr;
void arc_set_conf(char *);
char arc_set_conf(char *, char, int);
// arc ini sections
const ini_section_t arc_ini_sections[] = {
@ -39,13 +39,15 @@ const ini_var_t arc_ini_vars[] = {
{"CONF", (void*)arc_set_conf, CUSTOM_HANDLER, 0, 0, 1},
};
void arc_set_conf(char *c)
char arc_set_conf(char *c, char action, int tag)
{
if (action == INI_SAVE) return 0;
if ((conf_ptr+strlen(c))<MAX_CONF_SIZE-1) {
strcpy(&arc.conf[conf_ptr], c);
strcat(arc.conf, ";");
conf_ptr += strlen(c) + 1;
}
return 0;
}
char arc_open(const char *fname)
@ -60,7 +62,7 @@ char arc_open(const char *fname)
arc_reset();
arc.mod = -1; // indicate error by default, valid ARC file will overrdide with the correct MOD value
ini_parse(&arc_ini_cfg, 0);
ini_parse(&arc_ini_cfg, 0, 0);
iprintf("ARC CONF STR: %s\n",arc.conf);
return arc.mod;
}

View File

@ -589,5 +589,5 @@ static char archie_getmenuitem(uint8_t idx, char action, menu_item_t *item) {
void archie_setup_menu()
{
SetupMenu(archie_getmenupage, archie_getmenuitem);
SetupMenu(archie_getmenupage, archie_getmenuitem, NULL);
}

View File

@ -351,7 +351,7 @@ unsigned char LoadConfiguration(char *filename, int printconfig)
config_ini_cfg.nsections = (int)(sizeof(config_ini_sections) / sizeof(ini_section_t));
config_ini_cfg.nvars = (int)(sizeof(config_ini_vars) / sizeof(ini_var_t));
ini_parse(&config_ini_cfg, 0);
ini_parse(&config_ini_cfg, 0, 0);
if(tmpconf.floppy.drives<=4 && tmpconf.kickstart[0]) {
// If either the old config and new config have a different kickstart file,
@ -622,7 +622,7 @@ unsigned char SaveConfiguration(char *filename)
config_ini_cfg.nvars = (int)(sizeof(config_ini_vars) / sizeof(ini_var_t));
memcpy((void*)&tmpconf, (void*)&config, sizeof(config));
ini_save(&config_ini_cfg);
ini_save(&config_ini_cfg, 0);
return(0);
}

11
fpga.c
View File

@ -22,8 +22,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// 2009-12-10 - changed command header id
// 2010-04-14 - changed command header id
#include "stdio.h"
#include "string.h"
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include "errors.h"
#include "hardware.h"
#include "fdd.h"
@ -34,6 +35,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "fpga.h"
#include "tos.h"
#include "mist_cfg.h"
#include "settings.h"
#include "usb/joymapping.h"
uint8_t rstval = 0;
@ -931,9 +934,11 @@ void fpga_init(const char *name) {
iprintf("ident = %x\n", ct);
}
virtual_joystick_remap_init(false);
settings_load(true);
user_io_detect_core_type();
mist_ini_parse();
user_io_send_buttons(1);
user_io_send_buttons(true);
InitDB9();
if((user_io_core_type() == CORE_TYPE_MINIMIG)||

View File

@ -189,7 +189,7 @@ static int ini_get_section(const ini_cfg_t* cfg, char* buf, const char* alter_se
//// ini_get_var() ////
static void* ini_get_var(const ini_cfg_t* cfg, int cur_section, char* buf)
static void* ini_get_var(const ini_cfg_t* cfg, int cur_section, char* buf, int tag)
{
int i=0, j=0;
int var_id = -1;
@ -270,7 +270,7 @@ static void* ini_get_var(const ini_cfg_t* cfg, int cur_section, char* buf)
strncpy((char*)(cfg->vars[var_id].var), &(buf[i]), cfg->vars[var_id].max);
break;
case CUSTOM_HANDLER:
((custom_handler_t*)(cfg->vars[var_id].var))(&(buf[i]));
((custom_handler_t*)(cfg->vars[var_id].var))(&(buf[i]), INI_LOAD, tag);
break;
}
return (void*)(&(cfg->vars[var_id].var));
@ -281,7 +281,7 @@ static void* ini_get_var(const ini_cfg_t* cfg, int cur_section, char* buf)
//// ini_parse() ////
void ini_parse(const ini_cfg_t* cfg, const char *alter_section)
void ini_parse(const ini_cfg_t* cfg, const char *alter_section, int tag)
{
char line[INI_LINE_SIZE] = {0};
int section = INI_SECTION_INVALID_ID;
@ -326,7 +326,7 @@ void ini_parse(const ini_cfg_t* cfg, const char *alter_section)
section = ini_get_section(cfg, line, alter_section);
} else {
// otherwise this is a variable, get it
ini_get_var(cfg, section, line);
ini_get_var(cfg, section, line, tag);
}
}
// if end of file, stop
@ -343,10 +343,11 @@ void ini_parse(const ini_cfg_t* cfg, const char *alter_section)
//// ini_save() ////
void ini_save(const ini_cfg_t* cfg)
void ini_save(const ini_cfg_t* cfg, int tag)
{
int section, var;
char line[INI_LINE_SIZE] = {0};
char val[INI_LINE_SIZE] = {0};
ini_pt = 0;
// open ini file
@ -379,6 +380,9 @@ void ini_save(const ini_cfg_t* cfg)
case UINT32:
siprintf(line, "%s=%u\n", cfg->vars[var].name, *(uint32_t*)(cfg->vars[var].var));
break;
case UINT64:
siprintf(line, "%s=%llu\n", cfg->vars[var].name, *(uint64_t*)(cfg->vars[var].var));
break;
case INT8:
siprintf(line, "%s=%d\n", cfg->vars[var].name, *(int8_t*)(cfg->vars[var].var));
break;
@ -396,8 +400,14 @@ void ini_save(const ini_cfg_t* cfg)
case STRING:
siprintf(line, "%s=\"%s\"\n", cfg->vars[var].name, (char*)(cfg->vars[var].var));
break;
case CUSTOM_HANDLER:
while (((custom_handler_t*)(cfg->vars[var].var))(val, INI_SAVE, tag)) {
siprintf(line, "%s=\"%s\"\n", cfg->vars[var].name, val);
ini_putline(line);
};
}
ini_putline(line);
if (cfg->vars[var].type != CUSTOM_HANDLER)
ini_putline(line);
}
}

View File

@ -23,7 +23,10 @@ typedef enum {UINT8=0, INT8, UINT16, INT16, UINT32, INT32, UINT64, INT64,
#endif
STRING, CUSTOM_HANDLER} ini_vartypes_t;
typedef void custom_handler_t(char*);
#define INI_LOAD 0
#define INI_SAVE 1
typedef char custom_handler_t(char*, char, int);
typedef struct {
char* name;
@ -44,8 +47,8 @@ typedef struct {
//// functions ////
void ini_parse(const ini_cfg_t* cfg, const char *alter_section);
void ini_save(const ini_cfg_t* cfg);
void ini_parse(const ini_cfg_t* cfg, const char *alter_section, int tag);
void ini_save(const ini_cfg_t* cfg, int tag);
#endif // __INI_PARSER_H__

184
menu.c
View File

@ -47,6 +47,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "usb/joymapping.h"
#include "mist_cfg.h"
#include "minimig-menu.h"
#include "settings.h"
// test features (not used right now)
// #define ALLOW_TEST_MENU 0 //remove to disable in prod version
@ -77,6 +78,7 @@ static unsigned int menumask = 0; // Used to determine which rows are selectable
static unsigned long menu_timer = 0;
static menu_get_items_t menu_item_callback;
static menu_get_page_t menu_page_callback;
static menu_key_event_t menu_key_callback;
static menu_select_file_t menu_select_callback;
extern const char version[];
@ -95,7 +97,7 @@ const char *config_cpu_msg[] = {"68000 ", "68010", "-----","68020"};
const char *config_autofire_msg[] = {"\n\n AUTOFIRE OFF", "\n\n AUTOFIRE FAST", "\n\n AUTOFIRE MEDIUM", "\n\n AUTOFIRE SLOW"};
const char *days[] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
enum HelpText_Message {HELPTEXT_NONE,HELPTEXT_MAIN,HELPTEXT_HARDFILE,HELPTEXT_CHIPSET,HELPTEXT_MEMORY,HELPTEXT_VIDEO,HELPTEXT_FEATURES};
enum HelpText_Message {HELPTEXT_NONE,HELPTEXT_MAIN,HELPTEXT_HARDFILE,HELPTEXT_CHIPSET,HELPTEXT_MEMORY,HELPTEXT_VIDEO,HELPTEXT_FEATURES,HELPTEXT_INPUT};
const char *helptexts[]={
0,
" Welcome to MiST! Use the cursor keys to navigate the menus. Use space bar or enter to select an item. Press Esc or F12 to exit the menus. Joystick emulation on the numeric keypad can be toggled with the numlock key, while pressing Ctrl-Alt-0 (numeric keypad) toggles autofire mode.",
@ -104,6 +106,7 @@ const char *helptexts[]={
" Minimig can make use of up to 2 megabytes of Chip RAM, up to 1.5 megabytes of Slow RAM (A500 Trapdoor RAM), and up to 8 megabytes (68000/68010) / 24 megabytes (68020) of true Fast RAM. To use the HRTmon feature you will need a file on the SD card named hrtmon.rom.",
" Minimig's video features include a blur filter, to simulate the poorer picture quality on older monitors, and also scanline generation to simulate the appearance of a screen with low vertical resolution.",
" Minimig can set the audio filter to switchable with power LED (A500r5+), always off or always on (A1000, A500r3). The power LED off-state can be configured to dim (A500r6+) or off (A1000, A500r3/5).",
" Press F1 to setup the button mapping of the current joystick. Press F2 to save the current mapping globally. Press F3 to save the current mapping to the actual core only.",
0
};
@ -481,12 +484,34 @@ static void Setup8bitMenu() {
if(!p[0]) OsdCoreNameSet("8BIT");
else OsdCoreNameSet(p);
SetupMenu(GetMenuPage_8bit, GetMenuItem_8bit);
SetupMenu(GetMenuPage_8bit, GetMenuItem_8bit, NULL);
}
///////////////////////////
/////// System menu ///////
///////////////////////////
static uint8_t setup_phase = 0;
static joymapping_t mapping;
static char *buttons [16] = {
"RIGHT",
"LEFT",
"DOWN",
"UP",
"A",
"B",
"SELECT(C)",
"START",
"X",
"Y",
"L",
"R",
"L2",
"R2",
"L3",
"R3"
};
// prints input as a string of binary (on/off) values
// assumes big endian, returns using special characters (checked box/unchecked box)
static void siprintbinary(char* buffer, uint8_t byte)
@ -666,18 +691,13 @@ static char ResetDialog(uint8_t idx) {
CloseMenu();
OsdReset(RESET_NORMAL);
} else {
FIL file;
UINT br;
if (!user_io_create_config_name(s, "CFG", CONFIG_ROOT)) {
iprintf("Saving config to %s\n", s);
if(f_open(&file, s, FA_READ | FA_WRITE | FA_OPEN_ALWAYS) == FR_OK) {
// finally write data
((unsigned long long*)sector_buffer)[0] = user_io_8bit_set_status(arc_get_default(),~0);
f_write(&file, sector_buffer, 8, &br);
iprintf("Settings for %s written\n", s);
f_close(&file);
}
}
user_io_8bit_set_status(arc_get_default(),~0);
if (settings_save(false)) {
iprintf("Settings for %s reset\n", user_io_get_core_name());
Setup8bitMenu();
menusub = 0;
} else
ErrorMessage("\n Error writing settings!\n", 0);
}
}
return 0;
@ -721,12 +741,49 @@ static char CoreFileSelected(uint8_t idx, const char *SelectedName) {
return 0;
}
static char KeyEvent_System(uint8_t key) {
if (page_idx >= 4 && page_idx <= 7) {
uint8_t joy_num = page_idx-4;
uint16_t vid = StateUsbVidGet(joy_num);
uint16_t pid = StateUsbPidGet(joy_num);
if (key == KEY_F1) {
if (!setup_phase) {
if (vid && pid) setup_phase = 1; // start setup
memset(&mapping, 0, sizeof(joymapping_t));
} else if (setup_phase >= 1 && setup_phase <= 16)
setup_phase++; // skip button
return true;
}
if (key == KEY_F2 && !setup_phase) {
virtual_joystick_tag_update(vid, pid, 1); // new tag -> global tag
if (settings_save(true)) {
DialogBox("\n Saved global\n joystick mappings.", MENU_DIALOG_OK, NULL);
} else {
ErrorMessage("\n Error writing settings!\n", 0);
}
return true;
}
if (key == KEY_F3 && !setup_phase) {
virtual_joystick_tag_update(vid, pid, 2); // new tag -> core tag
if (settings_save(false)) {
DialogBox("\n Saved core\n joystick mappings.", MENU_DIALOG_OK, NULL);
} else {
ErrorMessage("\n Error writing settings!\n", 0);
}
return true;
}
}
return false;
}
static char GetMenuPage_System(uint8_t idx, char action, menu_page_t *page) {
if (action == MENU_PAGE_EXIT) return 0;
page->timer = 0;
page->stdexit = MENU_STD_EXIT;
page->flags = 0;
helptext=helptexts[HELPTEXT_NONE];
switch (idx) {
case 0:
page->title = "System";
@ -746,10 +803,13 @@ static char GetMenuPage_System(uint8_t idx, char action, menu_page_t *page) {
case 5:
case 6:
case 7:
helptext=helptexts[HELPTEXT_INPUT];
siprintf(s, "Joy%d", idx-3);
page->title = s;
page->timer = 10;
page->stdexit = MENU_STD_SPACE_EXIT;
memset(&mapping, 0, sizeof(joymapping_t));
setup_phase = 0;
break;
case 8:
page->title = "Keyboard";
@ -898,7 +958,7 @@ static char GetMenuItem_System(uint8_t idx, char action, menu_item_t *item) {
case 21:
case 22:
case 23:
siprintf(s, " Joystick %d Test", idx-19);
siprintf(s, " Joystick %d Setup/Test", idx-19);
item->item = s;
item->newpage = 4+idx-20; // page 4-7
break;
@ -913,8 +973,12 @@ static char GetMenuItem_System(uint8_t idx, char action, menu_item_t *item) {
// page 4-7 - joy test
case 26:
get_joystick_state(joy_string, joy_string2, page_idx-4); //grab state of joy
siprintf(s, " Test Joystick %d", page_idx-4+1);
if (!setup_phase) {
get_joystick_state(joy_string, joy_string2, page_idx-4); //grab state of joy
siprintf(s, " Test Joystick %d", page_idx-4+1);
} else {
siprintf(s, " Setup Joystick %d", page_idx-4+1);
}
item->item = s;
break;
case 27:
@ -922,10 +986,46 @@ static char GetMenuItem_System(uint8_t idx, char action, menu_item_t *item) {
item->item = s;
break;
case 29:
item->item = joy_string;
if (!setup_phase) {
item->item = joy_string;
} else {
uint8_t joy_num = page_idx-4;
uint32_t joy;
static uint32_t joy_prev;
if (setup_phase>15) {
setup_phase = 0;
mapping.vid = StateUsbVidGet(joy_num);
mapping.pid = StateUsbPidGet(joy_num);
mapping.tag = 3; // highest prio
iprintf("mapping: %04x,%04x", mapping.vid, mapping.pid);
for (int i = 0; i<16; i++) {
iprintf(",%x", mapping.mapping[i]);
}
iprintf("\n");
virtual_joystick_remap_update(&mapping);
break;
}
siprintf(s, " Press button %s", buttons[setup_phase - 1]);
joy = StateUsbJoyGet(joy_num);
joy |= StateUsbJoyGetExtra(joy_num) << 8;
if (!joy_prev && joy) {
for (int i = 0; i<16; i++) {
if (joy & (1<<i)) mapping.mapping[i] = 1<<(setup_phase - 1);
}
setup_phase++;
}
joy_prev = joy;
item->item = s;
}
break;
case 30:
item->item = joy_string2;
if (!setup_phase) {
item->item = joy_string2;
} else {
item->item = " F1 - skip this button";
}
break;
case 32:
get_joystick_state_usb(s, page_idx-4);
@ -999,28 +1099,15 @@ static char GetMenuItem_System(uint8_t idx, char action, menu_item_t *item) {
DialogBox(m ? "\n Reset MiST?" : "\n Reset settings?", MENU_DIALOG_YESNO, ResetDialog);
break;
}
case 4: {
case 4:
// Save settings
FIL file;
UINT bw = 0;
if (!user_io_create_config_name(s, "CFG", CONFIG_ROOT)) {
iprintf("Saving config to %s\n", s);
FRESULT res;
if((res = f_open(&file, s, FA_READ | FA_WRITE | FA_OPEN_ALWAYS)) == FR_OK) {
// finally write data
((unsigned long long*)sector_buffer)[0] = user_io_8bit_set_status(0,0);
res = f_write(&file, sector_buffer, 8, &bw);
f_close(&file);
}
if (res == FR_OK && bw == 8) {
iprintf("Settings for %s written\n", s);
Setup8bitMenu();
menusub = 0;
} else
ErrorMessage("\n Error writing settings!\n", 0);
}
if (settings_save(false)) {
iprintf("Settings for %s written\n", user_io_get_core_name());
Setup8bitMenu();
menusub = 0;
} else
ErrorMessage("\n Error writing settings!\n", 0);
break;
}
case 5:
parentstate = MENU_8BIT_ABOUT1;
menusub = 0;
@ -1113,7 +1200,7 @@ static char GetMenuItem_System(uint8_t idx, char action, menu_item_t *item) {
void SetupSystemMenu() {
helptext = helptexts[HELPTEXT_NONE];
SetupMenu(GetMenuPage_System, GetMenuItem_System);
SetupMenu(GetMenuPage_System, GetMenuItem_System, KeyEvent_System);
menusub = 0;
}
@ -1182,11 +1269,12 @@ void SelectFileNG(char *pFileExt, unsigned char Options, menu_select_file_t call
menu_select_callback = callback;
}
void SetupMenu(menu_get_page_t menu_page_cb, menu_get_items_t menu_item_cb)
void SetupMenu(menu_get_page_t menu_page_cb, menu_get_items_t menu_item_cb, menu_key_event_t menu_key_cb)
{
menuidx[0] = menu_last = page_idx = page_level = scroll_down = scroll_up = 0;
menu_item_callback = menu_item_cb;
menu_page_callback = menu_page_cb;
menu_key_callback = menu_key_cb;
menustate = parentstate = MENU_NG;
}
@ -1287,8 +1375,6 @@ void HandleUI(void)
if(menu || select || up || down || left || right )
{
if(helpstate)
OsdWrite(7,STD_EXIT,(menumask-((1<<(menusub+1))-1))<=0,0); // Redraw the Exit line...
helpstate=0;
helptext_timer=GetTimer(HELPTEXT_DELAY);
}
@ -1300,7 +1386,8 @@ void HandleUI(void)
if(CheckTimer(helptext_timer))
{
helptext_timer=GetTimer(FRAME_DELAY);
OsdWriteOffset(7,STD_EXIT,0,0,helpstate);
if (menu_page.stdexit)
OsdWriteOffset(OSDNLINE-1,menu_page.stdexit == 1 ? STD_EXIT : menu_page.stdexit == 2 ? STD_SPACE_EXIT : STD_COMBO_EXIT,0,0,helpstate);
++helpstate;
}
}
@ -1310,7 +1397,7 @@ void HandleUI(void)
++helpstate;
}
else
ScrollText(7,helptext,0,0,0,0);
ScrollText(OSDNLINE-1,helptext,0,0,0,0);
}
// Standardised menu up/down.
@ -1449,7 +1536,8 @@ void HandleUI(void)
menu_item.stipple = 0;
}
if (!(menumask & 1<<idx) && menusub == idx) menusub++;
OsdWrite(idx, item, menusub == idx, menu_item.stipple);
if (!(helpstate && idx == OSDNLINE-1))
OsdWrite(idx, item, menusub == idx, menu_item.stipple);
}
if (menu_page.timer) page_timer = GetTimer(menu_page.timer);
menustate = MENU_NG2;
@ -1517,6 +1605,10 @@ void HandleUI(void)
menustate = parentstate;
break;
}
if (c && menu_key_callback) {
if (menu_key_callback(c)) break;
}
action = MENU_ACT_NONE;
if (select) action = MENU_ACT_SEL;
else if (backsp) action = MENU_ACT_BKSP;

3
menu.h
View File

@ -63,6 +63,7 @@ typedef struct {
typedef char (*menu_get_items_t)(uint8_t, char, menu_item_t*);
typedef char (*menu_get_page_t)(uint8_t, char, menu_page_t*);
typedef char (*menu_key_event_t)(uint8_t);
typedef char (*menu_select_file_t)(uint8_t, const char*);
typedef char (*menu_dialog_t)(uint8_t);
@ -70,7 +71,7 @@ void DialogBox(const char *message, char options, menu_dialog_t);
void SelectFile(char* pFileExt, unsigned char Options, unsigned char MenuSelect, char chdir);
void SelectFileNG(char *pFileExt, unsigned char Options, menu_select_file_t callback, char chdir);
void SetupSystemMenu();
void SetupMenu(menu_get_page_t, menu_get_items_t);
void SetupMenu(menu_get_page_t, menu_get_items_t, menu_key_event_t);
void CloseMenu();
void ResetMenu();
void ClosePage();

View File

@ -877,5 +877,5 @@ static char GetMenuItem_Minimig(uint8_t idx, char action, menu_item_t *item) {
}
void SetupMinimigMenu() {
SetupMenu(GetMenuPage_Minimig, GetMenuItem_Minimig);
SetupMenu(GetMenuPage_Minimig, GetMenuItem_Minimig, NULL);
}

View File

@ -17,12 +17,14 @@ extern FIL ini_file;
// call data_io_rom_upload but reload sector_buffer afterwards since the io
// operations in data_io_rom_upload may have overwritten the buffer
// mode = 0: prepare for rom upload, mode = 1: rom upload, mode = 2, end rom upload
void ini_rom_upload(char *s) {
char ini_rom_upload(char *s, char action, int tag) {
if(action == INI_SAVE) return 0;
#ifndef INI_PARSER_TEST
data_io_rom_upload(s, 1);
f_lseek(&ini_file, (((f_tell(&ini_file)+511)>>9)-1)<<9);
FileReadBlock(&ini_file, sector_buffer);
#endif
return 0;
}
//// mist_ini_parse() ////
@ -30,14 +32,13 @@ void mist_ini_parse()
{
#ifndef INI_PARSER_TEST
hid_joystick_button_remap_init();
virtual_joystick_remap_init();
joy_key_map_init();
data_io_rom_upload(NULL, 0); // prepare upload
memset(&mist_cfg, 0, sizeof(mist_cfg));
mist_cfg.mouse_speed = 100;
mist_cfg.joystick_analog_mult = 128;
minimig_cfg.kick1x_memory_detection_patch = 1;
ini_parse(&mist_ini_cfg, user_io_get_core_name());
ini_parse(&mist_ini_cfg, user_io_get_core_name(), 0);
data_io_rom_upload(NULL, 2); // upload done
#endif
}

2
tos.c
View File

@ -1835,5 +1835,5 @@ static char tos_getmenuitem(uint8_t idx, char action, menu_item_t *item) {
}
void tos_setup_menu() {
SetupMenu(tos_getmenupage, tos_getmenuitem);
SetupMenu(tos_getmenupage, tos_getmenuitem, NULL);
}

View File

@ -42,14 +42,16 @@ void hid_joystick_button_remap_init(void) {
memset(joystick_button_remap, 0, sizeof(joystick_button_remap));
}
void hid_joystick_button_remap(char *s) {
char hid_joystick_button_remap(char *s, char action, int tag) {
uint8_t i;
hid_debugf("%s(%s)", __FUNCTION__, s);
if (action == INI_SAVE) return 0;
if(strlen(s) < 13) {
hid_debugf("malformed entry");
return;
return 0;
}
// parse remap request
@ -67,9 +69,10 @@ void hid_joystick_button_remap(char *s) {
joystick_button_remap[i].vid, joystick_button_remap[i].pid,
joystick_button_remap[i].offset, joystick_button_remap[i].button);
return;
return 0;
}
}
return 0;
}
/*****************************************************************************/

View File

@ -103,7 +103,7 @@ int8_t hid_keyboard_present(void);
// HID low-level remapping - do not confuse with virtual joystick in joymapping.h
void hid_joystick_button_remap_init(void);
void hid_joystick_button_remap(char *);
char hid_joystick_button_remap(char *, char, int);
void joy_key_map_init(void); // older function, prefer to use joymapping.h function
#endif // HID_H

View File

@ -42,11 +42,7 @@ This file defines how to handle mapping in the MiST controllers in various ways:
The mapping translates directions plus generic HID buttons (1-12) into a sandard MiST "virtual joystick"
\****************************************************************************/
static struct {
uint16_t vid;
uint16_t pid;
uint16_t mapping[16];
} joystick_mappers[MAX_VIRTUAL_JOYSTICK_REMAP];
static joymapping_t joystick_mappers[MAX_VIRTUAL_JOYSTICK_REMAP];
static uint16_t default_joystick_mapping [16] = {
JOY_RIGHT,
@ -67,16 +63,30 @@ static uint16_t default_joystick_mapping [16] = {
JOY_R3
};
void virtual_joystick_remap_init(void) {
memset(joystick_mappers, 0, sizeof(joystick_mappers));
static char dump_mapping() {
for(int i=0;i<MAX_VIRTUAL_JOYSTICK_REMAP;i++) {
if(joystick_mappers[i].vid && joystick_mappers[i].pid) {
iprintf("map[%d]: VID: %04x PID: %04x tag: %d\n", i, joystick_mappers[i].vid, joystick_mappers[i].pid, joystick_mappers[i].tag);
}
}
}
static char idx = 0;
void virtual_joystick_remap_init(char save) {
if(save)
idx = 0;
else
memset(joystick_mappers, 0, sizeof(joystick_mappers));
}
/* Parses an input comma-separated string into a mapping strucutre
The string is expected to have the following format: [VID],[PID],[comma separated list of buttons]
and requires at least 13 characters in length
*/
void virtual_joystick_remap(char *s) {
char virtual_joystick_remap(char *s, char action, int tag) {
uint8_t i;
uint8_t count;
uint8_t off = 0;
@ -84,24 +94,47 @@ void virtual_joystick_remap(char *s) {
uint16_t value = 0;
char *token;
char *sub_token;
// save entry to string
if(action == INI_SAVE) {
hid_debugf("%s(tag: %d)", __FUNCTION__, tag);
while(1) {
if (idx == MAX_VIRTUAL_JOYSTICK_REMAP || joystick_mappers[idx].vid == 0)
return 0;
if(joystick_mappers[idx].tag == tag) {
siprintf(s, "%04X,%04X", joystick_mappers[idx].vid, joystick_mappers[idx].pid);
for (count=0; count<16; count++) {
char hex[16];
siprintf(hex, ",%X", joystick_mappers[idx].mapping[count]);
strcat(s, hex);
}
idx++;
return 1;
}
idx++;
}
}
hid_debugf("%s(%s)", __FUNCTION__, s);
// load entry from string
if(len < 13) {
hid_debugf("malformed entry");
return;
return 0;
}
// parse remap request
for(i=0;i<MAX_VIRTUAL_JOYSTICK_REMAP;i++) {
// fill sequentially the available mapping slots, stopping at first empty one
if(!joystick_mappers[i].vid) {
// init mapping data
// init mapping data
for (count=0; count<16; count++)
joystick_mappers[i].mapping[count]=0;
// parse this first to stop if error - it will occupy a slot and proceed
value = strtol(s, NULL, 16);
if (value==0) continue; // ignore zero entries
value = strtol(s, NULL, 16);
if (value==0) continue; // ignore zero entries
joystick_mappers[i].vid = value;
// default assignment for directions
joystick_mappers[i].mapping[0] = JOY_RIGHT;
@ -115,6 +148,7 @@ void virtual_joystick_remap(char *s) {
value = strtol(token, NULL, 16);
if (count==1) {
joystick_mappers[i].pid = value;
joystick_mappers[i].tag = tag;
} else if (count >= 2) {
//parse sub-tokens sequentially and assign 16-bit value to them
joystick_mappers[i].mapping[off+count-2] = value;
@ -125,9 +159,63 @@ void virtual_joystick_remap(char *s) {
token = strtok (NULL, ",");
count+=1;
}
return; // finished processing input string so exit
return 0; // finished processing input string so exit
}
}
return 0;
}
void virtual_joystick_remap_update(joymapping_t *map) {
for(int i=0;i<MAX_VIRTUAL_JOYSTICK_REMAP;i++) {
if((joystick_mappers[i].vid == map->vid &&
joystick_mappers[i].pid == map->pid &&
joystick_mappers[i].tag == map->tag) ||
!joystick_mappers[i].vid) {
memcpy(&joystick_mappers[i], map, sizeof(joymapping_t));
return;
}
}
}
void virtual_joystick_tag_update(uint16_t vid, uint16_t pid, int newtag)
{
// first search for the entry to update with the largest tag
int old = -1, new = -1, i, oldtag = 0;
for(i=0;i<MAX_VIRTUAL_JOYSTICK_REMAP;i++) {
if(joystick_mappers[i].vid == vid &&
joystick_mappers[i].pid == pid &&
joystick_mappers[i].tag >= oldtag) {
old = i;
}
}
if (old == -1) return; // old entry not found
// now search if the entry with the same newtag already there
for(i=0;i<MAX_VIRTUAL_JOYSTICK_REMAP;i++) {
if(joystick_mappers[i].vid == vid &&
joystick_mappers[i].pid == pid &&
joystick_mappers[i].tag == newtag) {
new = i;
break;
}
}
if (new == -1) {
// no entry with the same tag, simply update
joystick_mappers[old].tag = newtag;
} else if (new != old) {
memcpy(&joystick_mappers[new].mapping, &joystick_mappers[old].mapping, 16*sizeof(uint16_t));
// delete the old entry
for(i = old; i<MAX_VIRTUAL_JOYSTICK_REMAP; i++) {
if (i==(MAX_VIRTUAL_JOYSTICK_REMAP-1)) {
memset(&joystick_mappers[i], 0, sizeof(joymapping_t));
} else {
memcpy(&joystick_mappers[i], &joystick_mappers[i+1].mapping, sizeof(joymapping_t));
}
}
}
}
/*****************************************************************************/
@ -331,16 +419,22 @@ uint16_t virtual_joystick_mapping (uint16_t vid, uint16_t pid, uint16_t joy_inpu
use_default=0;
}
// apply remap information from mist.ini if present
// Apply remap information from various config sources if present
// Priority (low to high):
// 0 - mist.ini
// 1 - mistcfg.ini
// 2 - [corename].cfg
uint8_t j;
int tag = 0;
for(j=0;j<MAX_VIRTUAL_JOYSTICK_REMAP;j++) {
if(joystick_mappers[j].vid==vid && joystick_mappers[j].pid==pid) {
for(i=0; i<16; i++)
mapping[i]=joystick_mappers[j].mapping[i];
use_default=0;
}
if(joystick_mappers[j].vid==vid && joystick_mappers[j].pid==pid && joystick_mappers[j].tag >= tag) {
for(i=0; i<16; i++)
mapping[i]=joystick_mappers[j].mapping[i];
use_default=0;
tag = joystick_mappers[j].tag + 1;
}
}
// apply default mapping to rest of buttons if requested
if (use_default) {
for(i=4; i<16; i++)
@ -376,19 +470,21 @@ void joy_key_map_init(void) {
}
void joystick_key_map(char *s) {
char joystick_key_map(char *s, char action, int tag) {
uint8_t i,j;
uint8_t count;
uint8_t assign=0;
uint8_t len = strlen(s);
uint8_t scancode=0;
char *token;
hid_debugf("%s(%s)", __FUNCTION__, s);
if(action == INI_SAVE) return 0;
if(len < 3) {
hid_debugf("malformed entry");
return;
return 0;
}
// parse remap request
@ -421,7 +517,7 @@ void joystick_key_map(char *s) {
s = strtok (NULL, ",");
count+=1;
}
return; // finished processing input string so exit
return 0; // finished processing input string so exit
}
}
}

View File

@ -49,11 +49,22 @@
#define VID_DAPTOR 0x04D8
#define VID_RETROLINK 0x0079
typedef struct {
uint16_t vid;
uint16_t pid;
uint16_t mapping[16];
int tag;
} joymapping_t;
/*****************************************************************************/
// INI parsing
void virtual_joystick_remap_init(void);
void virtual_joystick_remap(char *);
void virtual_joystick_remap_init(char);
char virtual_joystick_remap(char *, char, int);
// add new mapping
void virtual_joystick_remap_update(joymapping_t*);
void virtual_joystick_tag_update(uint16_t vid, uint16_t pid, int newtag);
// runtime mapping
uint16_t virtual_joystick_mapping (uint16_t vid, uint16_t pid, uint16_t joy_input);
@ -65,7 +76,7 @@ char* get_joystick_alias( uint16_t vid, uint16_t pid );
// INI parsing
void joystick_key_map_init(void);
void joystick_key_map(char *);
char joystick_key_map(char *, char, int);
// runtime mapping
bool virtual_joystick_keyboard ( uint16_t vjoy );

View File

@ -24,6 +24,7 @@
#include "arc_file.h"
#include "cue_parser.h"
#include "utils.h"
#include "settings.h"
#include "usb/joymapping.h"
#include "usb/joystick.h"
@ -337,6 +338,8 @@ void user_io_detect_core_type() {
((unsigned long long*)sector_buffer)[0] = 0;
f_read(&file, sector_buffer, f_size(&file), &br);
user_io_8bit_set_status(((unsigned long long*)sector_buffer)[0], ~1);
} else {
settings_load(false);
}
f_close(&file);
} else {
@ -2378,11 +2381,12 @@ void add_modifiers(uint8_t mod, uint16_t* keys_ps2)
}
}
void user_io_key_remap(char *s) {
char user_io_key_remap(char *s, char action, int tag) {
if (action == INI_SAVE) return 0;
// s is a string containing two comma separated hex numbers
if((strlen(s) != 5) && (s[2]!=',')) {
ini_parser_debugf("malformed entry %s", s);
return;
return 0;
}
char i;
@ -2393,9 +2397,10 @@ void user_io_key_remap(char *s) {
ini_parser_debugf("key remap entry %d = %02x,%02x",
i, key_remap_table[i][0], key_remap_table[i][1]);
return;
return 0;
}
}
return 0;
}
unsigned char user_io_ext_idx(const char *name, const char* ext) {

View File

@ -213,7 +213,7 @@ void user_io_analog_joystick(unsigned char, char, char, char, char);
char user_io_osd_is_visible();
void user_io_send_buttons(char);
void user_io_key_remap(char *);
char user_io_key_remap(char *, char, int);
void add_modifiers(uint8_t mod, uint16_t* keys_ps2);
unsigned char user_io_ext_idx(const char*, const char*);