Support up to 3 alternative INI files (Back+DPAD in OSD). Some refactoring in cfg/ini parsing.
This commit is contained in:
@@ -58,7 +58,6 @@
|
||||
<ClCompile Include="file_io.cpp" />
|
||||
<ClCompile Include="fpga_io.cpp" />
|
||||
<ClCompile Include="hardware.cpp" />
|
||||
<ClCompile Include="ini_parser.cpp" />
|
||||
<ClCompile Include="input.cpp" />
|
||||
<ClCompile Include="joymapping.cpp" />
|
||||
<ClCompile Include="lib\libco\arm.c" />
|
||||
@@ -113,7 +112,6 @@
|
||||
<ClInclude Include="fpga_reset_manager.h" />
|
||||
<ClInclude Include="fpga_system_manager.h" />
|
||||
<ClInclude Include="hardware.h" />
|
||||
<ClInclude Include="ini_parser.h" />
|
||||
<ClInclude Include="input.h" />
|
||||
<ClInclude Include="joymapping.h" />
|
||||
<ClInclude Include="lib\imlib2\Imlib2.h" />
|
||||
|
||||
@@ -70,9 +70,6 @@
|
||||
<ClCompile Include="hardware.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ini_parser.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="input.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
@@ -234,9 +231,6 @@
|
||||
<ClInclude Include="hardware.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ini_parser.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="input.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
|
||||
287
cfg.cpp
287
cfg.cpp
@@ -2,30 +2,34 @@
|
||||
// 2015, rok.krajnc@gmail.com
|
||||
// 2017+, Sorgelig
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "ini_parser.h"
|
||||
#include <inttypes.h>
|
||||
#include <ctype.h>
|
||||
#include "cfg.h"
|
||||
#include "debug.h"
|
||||
#include "file_io.h"
|
||||
#include "user_io.h"
|
||||
|
||||
cfg_t cfg;
|
||||
|
||||
void MiSTer_ini_parse()
|
||||
typedef enum
|
||||
{
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
cfg.bootscreen = 1;
|
||||
cfg.fb_terminal = 1;
|
||||
cfg.controller_info = 6;
|
||||
ini_parse(&ini_cfg, altcfg());
|
||||
}
|
||||
UINT8 = 0, INT8, UINT16, INT16, UINT32, INT32, FLOAT, STRING
|
||||
} ini_vartypes_t;
|
||||
|
||||
// mist ini sections
|
||||
const ini_section_t ini_sections[] =
|
||||
typedef struct
|
||||
{
|
||||
{ 1, "MiSTer" }
|
||||
};
|
||||
const char* name;
|
||||
void* var;
|
||||
ini_vartypes_t type;
|
||||
int min;
|
||||
int max;
|
||||
} ini_var_t;
|
||||
|
||||
// mist ini vars
|
||||
const ini_var_t ini_vars[] = {
|
||||
static const ini_var_t ini_vars[] =
|
||||
{
|
||||
{ "YPBPR", (void*)(&(cfg.ypbpr)), UINT8, 0, 1 },
|
||||
{ "COMPOSITE_SYNC", (void*)(&(cfg.csync)), UINT8, 0, 1 },
|
||||
{ "FORCED_SCANDOUBLER", (void*)(&(cfg.forced_scandoubler)), UINT8, 0, 1 },
|
||||
@@ -34,7 +38,7 @@ const ini_var_t ini_vars[] = {
|
||||
{ "KEYRAH_MODE", (void*)(&(cfg.keyrah_mode)), UINT32, 0, (int)0xFFFFFFFF },
|
||||
{ "RESET_COMBO", (void*)(&(cfg.reset_combo)), UINT8, 0, 3 },
|
||||
{ "KEY_MENU_AS_RGUI", (void*)(&(cfg.key_menu_as_rgui)), UINT8, 0, 1 },
|
||||
{ "VIDEO_MODE", (void*)(cfg.video_conf), STRING, 0, sizeof(cfg.video_conf)-1 },
|
||||
{ "VIDEO_MODE", (void*)(cfg.video_conf), STRING, 0, sizeof(cfg.video_conf) - 1 },
|
||||
{ "VIDEO_MODE_PAL", (void*)(cfg.video_conf_pal), STRING, 0, sizeof(cfg.video_conf_pal) - 1 },
|
||||
{ "VIDEO_MODE_NTSC", (void*)(cfg.video_conf_ntsc), STRING, 0, sizeof(cfg.video_conf_ntsc) - 1 },
|
||||
{ "VIDEO_INFO", (void*)(&(cfg.video_info)), UINT8, 0, 10 },
|
||||
@@ -65,12 +69,247 @@ const ini_var_t ini_vars[] = {
|
||||
{ "REFRESH_MAX", (void*)(&(cfg.refresh_max)), UINT8, 0, 150 },
|
||||
};
|
||||
|
||||
// mist ini config
|
||||
const ini_cfg_t ini_cfg = {
|
||||
"MiSTer.ini",
|
||||
"MiSTer_alt.ini",
|
||||
ini_sections,
|
||||
ini_vars,
|
||||
(int)(sizeof(ini_sections) / sizeof(ini_section_t)),
|
||||
(int)(sizeof(ini_vars) / sizeof(ini_var_t))
|
||||
};
|
||||
static const int nvars = (int)(sizeof(ini_vars) / sizeof(ini_var_t));
|
||||
|
||||
#define INI_EOT 4 // End-Of-Transmission
|
||||
|
||||
#define INI_LINE_SIZE 256
|
||||
|
||||
#define INI_SECTION_START '['
|
||||
#define INI_SECTION_END ']'
|
||||
#define INI_SECTION_INVALID_ID 0
|
||||
|
||||
#define CHAR_IS_NUM(c) (((c) >= '0') && ((c) <= '9'))
|
||||
#define CHAR_IS_ALPHA_LOWER(c) (((c) >= 'a') && ((c) <= 'z'))
|
||||
#define CHAR_IS_ALPHA_UPPER(c) (((c) >= 'A') && ((c) <= 'Z'))
|
||||
#define CHAR_IS_ALPHANUM(c) (CHAR_IS_ALPHA_LOWER(c) || CHAR_IS_ALPHA_UPPER(c) || CHAR_IS_NUM(c))
|
||||
#define CHAR_IS_SPECIAL(c) (((c) == '[') || ((c) == ']') || ((c) == '(') || ((c) == ')') || \
|
||||
((c) == '-') || ((c) == '+') || ((c) == '/') || ((c) == '=') || \
|
||||
((c) == '#') || ((c) == '$') || ((c) == '@') || ((c) == '_') || \
|
||||
((c) == ',') || ((c) == '.') || ((c) == '!') || ((c) == '*'))
|
||||
|
||||
#define CHAR_IS_VALID(c) (CHAR_IS_ALPHANUM(c) || CHAR_IS_SPECIAL(c))
|
||||
#define CHAR_IS_SPACE(c) (((c) == ' ') || ((c) == '\t'))
|
||||
#define CHAR_IS_LINEEND(c) (((c) == '\n'))
|
||||
#define CHAR_IS_COMMENT(c) (((c) == ';'))
|
||||
#define CHAR_IS_QUOTE(c) (((c) == '"'))
|
||||
|
||||
|
||||
fileTYPE ini_file;
|
||||
|
||||
int ini_pt = 0;
|
||||
static char ini_getch()
|
||||
{
|
||||
static uint8_t buf[512];
|
||||
if (!(ini_pt & 0x1ff)) FileReadSec(&ini_file, buf);
|
||||
if (ini_pt >= ini_file.size) return 0;
|
||||
return buf[(ini_pt++) & 0x1ff];
|
||||
}
|
||||
|
||||
static int ini_getline(char* line)
|
||||
{
|
||||
char c, ignore = 0, skip = 1;
|
||||
int i = 0;
|
||||
|
||||
while ((c = ini_getch()))
|
||||
{
|
||||
if (!CHAR_IS_SPACE(c)) skip = 0;
|
||||
if (i >= (INI_LINE_SIZE - 1) || CHAR_IS_COMMENT(c)) ignore = 1;
|
||||
|
||||
if (CHAR_IS_LINEEND(c)) break;
|
||||
if (CHAR_IS_VALID(c) && !ignore && !skip) line[i++] = c;
|
||||
}
|
||||
line[i] = '\0';
|
||||
return c == 0 ? INI_EOT : 0;
|
||||
}
|
||||
|
||||
static int ini_get_section(char* buf)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
// get section start marker
|
||||
if (buf[0] != INI_SECTION_START)
|
||||
{
|
||||
return INI_SECTION_INVALID_ID;
|
||||
}
|
||||
else buf++;
|
||||
|
||||
int wc_pos = -1;
|
||||
|
||||
// get section stop marker
|
||||
while (1)
|
||||
{
|
||||
if (buf[i] == INI_SECTION_END)
|
||||
{
|
||||
buf[i] = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
if (buf[i] == '*') wc_pos = i;
|
||||
|
||||
i++;
|
||||
if (i >= INI_LINE_SIZE) return INI_SECTION_INVALID_ID;
|
||||
}
|
||||
|
||||
// convert to uppercase
|
||||
for (i = 0; i < INI_LINE_SIZE; i++)
|
||||
{
|
||||
if (!buf[i]) break;
|
||||
else buf[i] = toupper(buf[i]);
|
||||
}
|
||||
|
||||
if (!strcasecmp(buf, "MiSTer") || ((wc_pos >= 0) ? !strncasecmp(buf, user_io_get_core_name_ex(), wc_pos) : !strcasecmp(buf, user_io_get_core_name_ex())))
|
||||
{
|
||||
ini_parser_debugf("Got SECTION '%s'", buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return INI_SECTION_INVALID_ID;
|
||||
}
|
||||
|
||||
static void ini_parse_var(char* buf)
|
||||
{
|
||||
int i = 0, j = 0;
|
||||
int var_id = -1;
|
||||
|
||||
// find var
|
||||
while (1)
|
||||
{
|
||||
if (buf[i] == '=')
|
||||
{
|
||||
buf[i] = '\0';
|
||||
break;
|
||||
}
|
||||
else if (buf[i] == '\0') return;
|
||||
i++;
|
||||
}
|
||||
|
||||
// convert to uppercase
|
||||
for (j = 0; j <= i; j++)
|
||||
{
|
||||
if (!buf[j]) break;
|
||||
else buf[j] = toupper(buf[j]);
|
||||
}
|
||||
|
||||
// parse var
|
||||
for (j = 0; j < (int)(sizeof(ini_vars) / sizeof(ini_var_t)); j++)
|
||||
{
|
||||
if (!strcasecmp(buf, ini_vars[j].name)) var_id = j;
|
||||
}
|
||||
|
||||
// get data
|
||||
if (var_id != -1)
|
||||
{
|
||||
ini_parser_debugf("Got VAR '%s' with VALUE %s", buf, &(buf[i + 1]));
|
||||
i++;
|
||||
switch (ini_vars[var_id].type)
|
||||
{
|
||||
case UINT8:
|
||||
*(uint8_t*)(ini_vars[var_id].var) = strtoul(&(buf[i]), NULL, 0);
|
||||
if (*(uint8_t*)(ini_vars[var_id].var) > ini_vars[var_id].max) *(uint8_t*)(ini_vars[var_id].var) = ini_vars[var_id].max;
|
||||
if (*(uint8_t*)(ini_vars[var_id].var) < ini_vars[var_id].min) *(uint8_t*)(ini_vars[var_id].var) = ini_vars[var_id].min;
|
||||
break;
|
||||
case INT8:
|
||||
*(int8_t*)(ini_vars[var_id].var) = strtol(&(buf[i]), NULL, 0);
|
||||
if (*(int8_t*)(ini_vars[var_id].var) > ini_vars[var_id].max) *(int8_t*)(ini_vars[var_id].var) = ini_vars[var_id].max;
|
||||
if (*(int8_t*)(ini_vars[var_id].var) < ini_vars[var_id].min) *(int8_t*)(ini_vars[var_id].var) = ini_vars[var_id].min;
|
||||
break;
|
||||
case UINT16:
|
||||
*(uint16_t*)(ini_vars[var_id].var) = strtoul(&(buf[i]), NULL, 0);
|
||||
if (*(uint16_t*)(ini_vars[var_id].var) > ini_vars[var_id].max) *(uint16_t*)(ini_vars[var_id].var) = ini_vars[var_id].max;
|
||||
if (*(uint16_t*)(ini_vars[var_id].var) < ini_vars[var_id].min) *(uint16_t*)(ini_vars[var_id].var) = ini_vars[var_id].min;
|
||||
break;
|
||||
case INT16:
|
||||
*(int16_t*)(ini_vars[var_id].var) = strtol(&(buf[i]), NULL, 0);
|
||||
if (*(int16_t*)(ini_vars[var_id].var) > ini_vars[var_id].max) *(int16_t*)(ini_vars[var_id].var) = ini_vars[var_id].max;
|
||||
if (*(int16_t*)(ini_vars[var_id].var) < ini_vars[var_id].min) *(int16_t*)(ini_vars[var_id].var) = ini_vars[var_id].min;
|
||||
break;
|
||||
case UINT32:
|
||||
*(uint32_t*)(ini_vars[var_id].var) = strtoul(&(buf[i]), NULL, 0);
|
||||
if (*(uint32_t*)(ini_vars[var_id].var) > (uint32_t)ini_vars[var_id].max) *(uint32_t*)(ini_vars[var_id].var) = ini_vars[var_id].max;
|
||||
if (*(uint32_t*)(ini_vars[var_id].var) < (uint32_t)ini_vars[var_id].min) *(uint32_t*)(ini_vars[var_id].var) = ini_vars[var_id].min;
|
||||
break;
|
||||
case INT32:
|
||||
*(int32_t*)(ini_vars[var_id].var) = strtol(&(buf[i]), NULL, 0);
|
||||
if (*(int32_t*)(ini_vars[var_id].var) > ini_vars[var_id].max) *(int32_t*)(ini_vars[var_id].var) = ini_vars[var_id].max;
|
||||
if (*(int32_t*)(ini_vars[var_id].var) < ini_vars[var_id].min) *(int32_t*)(ini_vars[var_id].var) = ini_vars[var_id].min;
|
||||
break;
|
||||
case FLOAT:
|
||||
*(float*)(ini_vars[var_id].var) = strtof(&(buf[i]), NULL);
|
||||
if (*(float*)(ini_vars[var_id].var) > ini_vars[var_id].max) *(float*)(ini_vars[var_id].var) = ini_vars[var_id].max;
|
||||
if (*(float*)(ini_vars[var_id].var) < ini_vars[var_id].min) *(float*)(ini_vars[var_id].var) = ini_vars[var_id].min;
|
||||
break;
|
||||
case STRING:
|
||||
memset(ini_vars[var_id].var, 0, ini_vars[var_id].max);
|
||||
strncpy((char*)(ini_vars[var_id].var), &(buf[i]), ini_vars[var_id].max);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ini_parse(int alt)
|
||||
{
|
||||
char line[INI_LINE_SIZE] = { 0 };
|
||||
int section = INI_SECTION_INVALID_ID;
|
||||
int line_status;
|
||||
|
||||
ini_parser_debugf("Start INI parser for core \"%s\".", user_io_get_core_name_ex());
|
||||
|
||||
memset(&ini_file, 0, sizeof(ini_file));
|
||||
|
||||
const char *name = cfg_get_name(alt);
|
||||
if (!FileOpen(&ini_file, name)) return;
|
||||
|
||||
ini_parser_debugf("Opened file %s with size %llu bytes.", name, ini_file.size);
|
||||
|
||||
ini_pt = 0;
|
||||
|
||||
// parse ini
|
||||
while (1)
|
||||
{
|
||||
// get line
|
||||
line_status = ini_getline(line);
|
||||
ini_parser_debugf("line(%d): \"%s\".", line_status, line);
|
||||
|
||||
if (line[0] == INI_SECTION_START)
|
||||
{
|
||||
// if first char in line is INI_SECTION_START, get section
|
||||
section = ini_get_section(line);
|
||||
}
|
||||
else if(section)
|
||||
{
|
||||
// otherwise this is a variable, get it
|
||||
ini_parse_var(line);
|
||||
}
|
||||
|
||||
// if end of file, stop
|
||||
if (line_status == INI_EOT) break;
|
||||
}
|
||||
|
||||
FileClose(&ini_file);
|
||||
}
|
||||
|
||||
const char* cfg_get_name(uint8_t alt)
|
||||
{
|
||||
static char name[64];
|
||||
strcpy(name, "MiSTer.ini");
|
||||
|
||||
if (alt == 1)
|
||||
{
|
||||
strcpy(name, "MiSTer_alt_1.ini");
|
||||
if (FileExists(name)) return name;
|
||||
return "MiSTer_alt.ini";
|
||||
}
|
||||
|
||||
if (alt && alt < 4) sprintf(name, "MiSTer_alt_%d.ini", alt);
|
||||
return name;
|
||||
}
|
||||
|
||||
void cfg_parse()
|
||||
{
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
cfg.bootscreen = 1;
|
||||
cfg.fb_terminal = 1;
|
||||
cfg.controller_info = 6;
|
||||
ini_parse(altcfg());
|
||||
}
|
||||
|
||||
12
cfg.h
12
cfg.h
@@ -5,11 +5,7 @@
|
||||
#ifndef __CFG_H__
|
||||
#define __CFG_H__
|
||||
|
||||
|
||||
//// includes ////
|
||||
#include <inttypes.h>
|
||||
#include "ini_parser.h"
|
||||
|
||||
|
||||
//// type definitions ////
|
||||
typedef struct {
|
||||
@@ -52,12 +48,10 @@ typedef struct {
|
||||
char font[1024];
|
||||
} cfg_t;
|
||||
|
||||
//// functions ////
|
||||
void MiSTer_ini_parse();
|
||||
|
||||
//// global variables ////
|
||||
extern const ini_cfg_t ini_cfg;
|
||||
extern cfg_t cfg;
|
||||
|
||||
//// functions ////
|
||||
void cfg_parse();
|
||||
const char* cfg_get_name(uint8_t alt);
|
||||
|
||||
#endif // __CFG_H__
|
||||
|
||||
@@ -1002,7 +1002,7 @@ void FindStorage(void)
|
||||
{
|
||||
int saveddev = device;
|
||||
device = 0;
|
||||
MiSTer_ini_parse();
|
||||
cfg_parse();
|
||||
device = saveddev;
|
||||
video_mode_load();
|
||||
user_io_send_buttons(1);
|
||||
|
||||
235
ini_parser.cpp
235
ini_parser.cpp
@@ -1,235 +0,0 @@
|
||||
// ini_parser.c
|
||||
// 2015, rok.krajnc@gmail.com
|
||||
|
||||
|
||||
//// includes ////
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include <ctype.h>
|
||||
#include "ini_parser.h"
|
||||
#include "debug.h"
|
||||
#include "file_io.h"
|
||||
#include "user_io.h"
|
||||
|
||||
//// defines ////
|
||||
#define INI_EOT 4 // End-Of-Transmission
|
||||
|
||||
#define INI_LINE_SIZE 256
|
||||
|
||||
#define INI_SECTION_START '['
|
||||
#define INI_SECTION_END ']'
|
||||
#define INI_SECTION_INVALID_ID 0
|
||||
|
||||
|
||||
//// macros ////
|
||||
#define CHAR_IS_NUM(c) (((c) >= '0') && ((c) <= '9'))
|
||||
#define CHAR_IS_ALPHA_LOWER(c) (((c) >= 'a') && ((c) <= 'z'))
|
||||
#define CHAR_IS_ALPHA_UPPER(c) (((c) >= 'A') && ((c) <= 'Z'))
|
||||
#define CHAR_IS_ALPHANUM(c) (CHAR_IS_ALPHA_LOWER(c) || CHAR_IS_ALPHA_UPPER(c) || CHAR_IS_NUM(c))
|
||||
#define CHAR_IS_SPECIAL(c) (((c) == '[') || ((c) == ']') || ((c) == '(') || ((c) == ')') || \
|
||||
((c) == '-') || ((c) == '+') || ((c) == '/') || ((c) == '=') || \
|
||||
((c) == '#') || ((c) == '$') || ((c) == '@') || ((c) == '_') || \
|
||||
((c) == ',') || ((c) == '.') || ((c) == '!') || ((c) == '*'))
|
||||
|
||||
#define CHAR_IS_VALID(c) (CHAR_IS_ALPHANUM(c) || CHAR_IS_SPECIAL(c))
|
||||
#define CHAR_IS_SPACE(c) (((c) == ' ') || ((c) == '\t'))
|
||||
#define CHAR_IS_LINEEND(c) (((c) == '\n'))
|
||||
#define CHAR_IS_COMMENT(c) (((c) == ';'))
|
||||
#define CHAR_IS_QUOTE(c) (((c) == '"'))
|
||||
|
||||
fileTYPE ini_file;
|
||||
|
||||
int ini_pt = 0;
|
||||
char ini_getch()
|
||||
{
|
||||
static uint8_t buf[512];
|
||||
if (!(ini_pt & 0x1ff)) FileReadSec(&ini_file, buf);
|
||||
if (ini_pt >= ini_file.size) return 0;
|
||||
return buf[(ini_pt++) & 0x1ff];
|
||||
}
|
||||
|
||||
int ini_getline(char* line)
|
||||
{
|
||||
char c, ignore = 0, skip = 1;
|
||||
int i = 0;
|
||||
|
||||
while((c = ini_getch()))
|
||||
{
|
||||
if (!CHAR_IS_SPACE(c)) skip = 0;
|
||||
if (i >= (INI_LINE_SIZE - 1) || CHAR_IS_COMMENT(c)) ignore = 1;
|
||||
|
||||
if (CHAR_IS_LINEEND(c)) break;
|
||||
if (CHAR_IS_VALID(c) && !ignore && !skip) line[i++] = c;
|
||||
}
|
||||
line[i] = '\0';
|
||||
return c == 0 ? INI_EOT : 0;
|
||||
}
|
||||
|
||||
int ini_get_section(const ini_cfg_t* cfg, char* buf)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
// get section start marker
|
||||
if (buf[0] != INI_SECTION_START) {
|
||||
return INI_SECTION_INVALID_ID;
|
||||
}
|
||||
else buf++;
|
||||
|
||||
int wc_pos = -1;
|
||||
// get section stop marker
|
||||
while (1) {
|
||||
if (buf[i] == INI_SECTION_END) {
|
||||
buf[i] = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
if (buf[i] == '*') wc_pos = i;
|
||||
|
||||
i++;
|
||||
if (i >= INI_LINE_SIZE) {
|
||||
return INI_SECTION_INVALID_ID;
|
||||
}
|
||||
}
|
||||
|
||||
// convert to uppercase
|
||||
for (i = 0; i<INI_LINE_SIZE; i++) {
|
||||
if (!buf[i]) break;
|
||||
else buf[i] = toupper(buf[i]);
|
||||
}
|
||||
|
||||
// parse section
|
||||
for (i = 0; i<cfg->nsections; i++) {
|
||||
if (!strcasecmp(buf, cfg->sections[i].name)) {
|
||||
ini_parser_debugf("Got SECTION '%s' with ID %d", buf, cfg->sections[i].id);
|
||||
return cfg->sections[i].id;
|
||||
}
|
||||
}
|
||||
|
||||
if ((wc_pos>=0) ? !strncasecmp(buf, user_io_get_core_name_ex(), wc_pos) : !strcasecmp(buf, user_io_get_core_name_ex())) return cfg->sections[0].id;
|
||||
|
||||
return INI_SECTION_INVALID_ID;
|
||||
}
|
||||
|
||||
void* ini_get_var(const ini_cfg_t* cfg, int cur_section, char* buf)
|
||||
{
|
||||
int i = 0, j = 0;
|
||||
int var_id = -1;
|
||||
|
||||
// find var
|
||||
while (1) {
|
||||
if (buf[i] == '=') {
|
||||
buf[i] = '\0';
|
||||
break;
|
||||
}
|
||||
else if (buf[i] == '\0') return (void*)0;
|
||||
i++;
|
||||
}
|
||||
|
||||
// convert to uppercase
|
||||
for (j = 0; j <= i; j++) {
|
||||
if (!buf[j]) break;
|
||||
else buf[j] = toupper(buf[j]);
|
||||
}
|
||||
|
||||
// parse var
|
||||
for (j = 0; j<cfg->nvars; j++) {
|
||||
if (!strcasecmp(buf, cfg->vars[j].name) && cur_section) var_id = j;
|
||||
}
|
||||
|
||||
// get data
|
||||
if (var_id != -1) {
|
||||
ini_parser_debugf("Got VAR '%s' with VALUE %s", buf, &(buf[i + 1]));
|
||||
i++;
|
||||
switch (cfg->vars[var_id].type) {
|
||||
case UINT8:
|
||||
*(uint8_t*)(cfg->vars[var_id].var) = strtoul(&(buf[i]), NULL, 0);
|
||||
if (*(uint8_t*)(cfg->vars[var_id].var) > cfg->vars[var_id].max) *(uint8_t*)(cfg->vars[var_id].var) = cfg->vars[var_id].max;
|
||||
if (*(uint8_t*)(cfg->vars[var_id].var) < cfg->vars[var_id].min) *(uint8_t*)(cfg->vars[var_id].var) = cfg->vars[var_id].min;
|
||||
break;
|
||||
case INT8:
|
||||
*(int8_t*)(cfg->vars[var_id].var) = strtol(&(buf[i]), NULL, 0);
|
||||
if (*(int8_t*)(cfg->vars[var_id].var) > cfg->vars[var_id].max) *(int8_t*)(cfg->vars[var_id].var) = cfg->vars[var_id].max;
|
||||
if (*(int8_t*)(cfg->vars[var_id].var) < cfg->vars[var_id].min) *(int8_t*)(cfg->vars[var_id].var) = cfg->vars[var_id].min;
|
||||
break;
|
||||
case UINT16:
|
||||
*(uint16_t*)(cfg->vars[var_id].var) = strtoul(&(buf[i]), NULL, 0);
|
||||
if (*(uint16_t*)(cfg->vars[var_id].var) > cfg->vars[var_id].max) *(uint16_t*)(cfg->vars[var_id].var) = cfg->vars[var_id].max;
|
||||
if (*(uint16_t*)(cfg->vars[var_id].var) < cfg->vars[var_id].min) *(uint16_t*)(cfg->vars[var_id].var) = cfg->vars[var_id].min;
|
||||
break;
|
||||
case INT16:
|
||||
*(int16_t*)(cfg->vars[var_id].var) = strtol(&(buf[i]), NULL, 0);
|
||||
if (*(int16_t*)(cfg->vars[var_id].var) > cfg->vars[var_id].max) *(int16_t*)(cfg->vars[var_id].var) = cfg->vars[var_id].max;
|
||||
if (*(int16_t*)(cfg->vars[var_id].var) < cfg->vars[var_id].min) *(int16_t*)(cfg->vars[var_id].var) = cfg->vars[var_id].min;
|
||||
break;
|
||||
case UINT32:
|
||||
*(uint32_t*)(cfg->vars[var_id].var) = strtoul(&(buf[i]), NULL, 0);
|
||||
if (*(uint32_t*)(cfg->vars[var_id].var) > (uint32_t)cfg->vars[var_id].max) *(uint32_t*)(cfg->vars[var_id].var) = cfg->vars[var_id].max;
|
||||
if (*(uint32_t*)(cfg->vars[var_id].var) < (uint32_t)cfg->vars[var_id].min) *(uint32_t*)(cfg->vars[var_id].var) = cfg->vars[var_id].min;
|
||||
break;
|
||||
case INT32:
|
||||
*(int32_t*)(cfg->vars[var_id].var) = strtol(&(buf[i]), NULL, 0);
|
||||
if (*(int32_t*)(cfg->vars[var_id].var) > cfg->vars[var_id].max) *(int32_t*)(cfg->vars[var_id].var) = cfg->vars[var_id].max;
|
||||
if (*(int32_t*)(cfg->vars[var_id].var) < cfg->vars[var_id].min) *(int32_t*)(cfg->vars[var_id].var) = cfg->vars[var_id].min;
|
||||
break;
|
||||
case FLOAT:
|
||||
*(float*)(cfg->vars[var_id].var) = strtof(&(buf[i]), NULL);
|
||||
if (*(float*)(cfg->vars[var_id].var) > cfg->vars[var_id].max) *(float*)(cfg->vars[var_id].var) = cfg->vars[var_id].max;
|
||||
if (*(float*)(cfg->vars[var_id].var) < cfg->vars[var_id].min) *(float*)(cfg->vars[var_id].var) = cfg->vars[var_id].min;
|
||||
break;
|
||||
case STRING:
|
||||
memset(cfg->vars[var_id].var, 0, cfg->vars[var_id].max);
|
||||
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]));
|
||||
break;
|
||||
}
|
||||
return (void*)(&(cfg->vars[var_id].var));
|
||||
}
|
||||
|
||||
return (void*)0;
|
||||
}
|
||||
|
||||
void ini_parse(const ini_cfg_t* cfg, int alt)
|
||||
{
|
||||
char line[INI_LINE_SIZE] = { 0 };
|
||||
int section = INI_SECTION_INVALID_ID;
|
||||
int line_status;
|
||||
|
||||
ini_parser_debugf("Start INI parser for core \"%s\".", user_io_get_core_name_ex());
|
||||
|
||||
memset(&ini_file, 0, sizeof(ini_file));
|
||||
if (!FileOpen(&ini_file, alt ? cfg->filename_alt : cfg->filename))
|
||||
{
|
||||
return;
|
||||
}
|
||||
else ini_parser_debugf("Opened file %s with size %llu bytes.", cfg->filename, ini_file.size);
|
||||
|
||||
ini_pt = 0;
|
||||
|
||||
// parse ini
|
||||
while (1)
|
||||
{
|
||||
// get line
|
||||
line_status = ini_getline(line);
|
||||
ini_parser_debugf("line(%d): \"%s\".", line_status, line);
|
||||
|
||||
if (line[0] == INI_SECTION_START)
|
||||
{
|
||||
// if first char in line is INI_SECTION_START, get section
|
||||
section = ini_get_section(cfg, line);
|
||||
}
|
||||
else
|
||||
{
|
||||
// otherwise this is a variable, get it
|
||||
ini_get_var(cfg, section, line);
|
||||
}
|
||||
|
||||
// if end of file, stop
|
||||
if (line_status == INI_EOT) break;
|
||||
}
|
||||
|
||||
FileClose(&ini_file);
|
||||
}
|
||||
46
ini_parser.h
46
ini_parser.h
@@ -1,46 +0,0 @@
|
||||
// ini_parser.h
|
||||
// 2015, rok.krajnc@gmail.com
|
||||
|
||||
#ifndef __INI_PARSER_H__
|
||||
#define __INI_PARSER_H__
|
||||
|
||||
//// includes ////
|
||||
#include <inttypes.h>
|
||||
|
||||
|
||||
//// type definitions ////
|
||||
typedef struct {
|
||||
int id;
|
||||
const char* name;
|
||||
} ini_section_t;
|
||||
|
||||
typedef enum {
|
||||
UINT8 = 0, INT8, UINT16, INT16, UINT32, INT32, FLOAT,
|
||||
STRING, CUSTOM_HANDLER
|
||||
} ini_vartypes_t;
|
||||
|
||||
typedef void custom_handler_t(char*);
|
||||
|
||||
typedef struct {
|
||||
const char* name;
|
||||
void* var;
|
||||
ini_vartypes_t type;
|
||||
int min;
|
||||
int max;
|
||||
} ini_var_t;
|
||||
|
||||
typedef struct {
|
||||
const char* filename;
|
||||
const char* filename_alt;
|
||||
const ini_section_t* sections;
|
||||
const ini_var_t* vars;
|
||||
int nsections;
|
||||
int nvars;
|
||||
} ini_cfg_t;
|
||||
|
||||
|
||||
//// functions ////
|
||||
void ini_parse(const ini_cfg_t* cfg, int alt);
|
||||
|
||||
#endif // __INI_PARSER_H__
|
||||
|
||||
26
input.cpp
26
input.cpp
@@ -1664,6 +1664,8 @@ static void joy_digital(int jnum, uint32_t mask, uint32_t code, char press, int
|
||||
mask = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if((mask & JOY_BTN2) && !(old_osdbtn & JOY_BTN2)) mask = 0;
|
||||
}
|
||||
|
||||
memset(joy, 0, sizeof(joy));
|
||||
@@ -1673,18 +1675,42 @@ static void joy_digital(int jnum, uint32_t mask, uint32_t code, char press, int
|
||||
switch (mask)
|
||||
{
|
||||
case JOY_RIGHT:
|
||||
if (press && (osdbtn & JOY_BTN2))
|
||||
{
|
||||
user_io_set_ini(0);
|
||||
osdbtn = 0;
|
||||
return;
|
||||
}
|
||||
ev.code = KEY_RIGHT;
|
||||
break;
|
||||
|
||||
case JOY_LEFT:
|
||||
if (press && (osdbtn & JOY_BTN2))
|
||||
{
|
||||
user_io_set_ini(1);
|
||||
osdbtn = 0;
|
||||
return;
|
||||
}
|
||||
ev.code = KEY_LEFT;
|
||||
break;
|
||||
|
||||
case JOY_UP:
|
||||
if (press && (osdbtn & JOY_BTN2))
|
||||
{
|
||||
user_io_set_ini(2);
|
||||
osdbtn = 0;
|
||||
return;
|
||||
}
|
||||
ev.code = KEY_UP;
|
||||
break;
|
||||
|
||||
case JOY_DOWN:
|
||||
if (press && (osdbtn & JOY_BTN2))
|
||||
{
|
||||
user_io_set_ini(3);
|
||||
osdbtn = 0;
|
||||
return;
|
||||
}
|
||||
ev.code = KEY_DOWN;
|
||||
break;
|
||||
|
||||
|
||||
67
user_io.cpp
67
user_io.cpp
@@ -35,7 +35,8 @@
|
||||
|
||||
#include "support.h"
|
||||
|
||||
static char core_path[1024];
|
||||
static char core_path[1024] = {};
|
||||
static char rbf_path[1024] = {};
|
||||
|
||||
static uint8_t vol_att = 0;
|
||||
unsigned long vol_set_timeout = 0;
|
||||
@@ -526,10 +527,10 @@ const char* get_rbf_path()
|
||||
|
||||
void MakeFile(const char * filename, const char * data)
|
||||
{
|
||||
FILE * file;
|
||||
file = fopen(filename, "w");
|
||||
fwrite(data, strlen(data), 1, file);
|
||||
fclose(file);
|
||||
FILE * file;
|
||||
file = fopen(filename, "w");
|
||||
fwrite(data, strlen(data), 1, file);
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
int GetUARTMode()
|
||||
@@ -553,18 +554,18 @@ int GetMidiLinkMode()
|
||||
|
||||
void SetMidiLinkMode(int mode)
|
||||
{
|
||||
MakeFile("/tmp/CORENAME", user_io_get_core_name_ex());
|
||||
remove("/tmp/ML_FSYNTH");
|
||||
remove("/tmp/ML_MUNT");
|
||||
remove("/tmp/ML_UDP");
|
||||
remove("/tmp/ML_TCP");
|
||||
switch (mode)
|
||||
{
|
||||
case 0: MakeFile("/tmp/ML_FSYNTH", ""); break;
|
||||
case 1: MakeFile("/tmp/ML_MUNT", ""); break;
|
||||
case 2: MakeFile("/tmp/ML_TCP", ""); break;
|
||||
case 3: MakeFile("/tmp/ML_UDP", ""); break;
|
||||
}
|
||||
MakeFile("/tmp/CORENAME", user_io_get_core_name_ex());
|
||||
remove("/tmp/ML_FSYNTH");
|
||||
remove("/tmp/ML_MUNT");
|
||||
remove("/tmp/ML_UDP");
|
||||
remove("/tmp/ML_TCP");
|
||||
switch (mode)
|
||||
{
|
||||
case 0: MakeFile("/tmp/ML_FSYNTH", ""); break;
|
||||
case 1: MakeFile("/tmp/ML_MUNT", ""); break;
|
||||
case 2: MakeFile("/tmp/ML_TCP", ""); break;
|
||||
case 3: MakeFile("/tmp/ML_UDP", ""); break;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t sdram_sz(int sz)
|
||||
@@ -674,6 +675,8 @@ void user_io_init(const char *path, const char *xml)
|
||||
// not the RBF. The RBF will be in arcade, which the user shouldn't
|
||||
// browse
|
||||
strcpy(core_path, xml ? xml : path);
|
||||
strcpy(rbf_path, path);
|
||||
|
||||
if (xml) arcade_override_name(xml);
|
||||
|
||||
memset(sd_image, 0, sizeof(sd_image));
|
||||
@@ -715,7 +718,7 @@ void user_io_init(const char *path, const char *xml)
|
||||
user_io_8bit_set_status(UIO_STATUS_RESET, UIO_STATUS_RESET);
|
||||
}
|
||||
|
||||
MiSTer_ini_parse();
|
||||
cfg_parse();
|
||||
if (cfg.bootcore[0] != '\0')
|
||||
{
|
||||
bootcore_init(xml ? xml : path);
|
||||
@@ -2037,15 +2040,6 @@ void user_io_send_buttons(char force)
|
||||
|
||||
if ((map != key_map) || force)
|
||||
{
|
||||
if ((key_map & (BUTTON1 | BUTTON2)) == BUTTON2 && (map & (BUTTON1 | BUTTON2)) == (BUTTON1 | BUTTON2) && is_menu_core())
|
||||
{
|
||||
if (FileExists(ini_cfg.filename_alt))
|
||||
{
|
||||
altcfg(altcfg() ? 0 : 1);
|
||||
fpga_load_rbf("menu.rbf");
|
||||
}
|
||||
}
|
||||
|
||||
const char *name = get_rbf_path();
|
||||
if (name[0] && (get_key_mod() & (LGUI | LSHIFT)) == (LGUI | LSHIFT) && (key_map & BUTTON2) && !(map & BUTTON2))
|
||||
{
|
||||
@@ -2072,6 +2066,25 @@ void user_io_send_buttons(char force)
|
||||
}
|
||||
}
|
||||
|
||||
void user_io_set_ini(int ini_num)
|
||||
{
|
||||
const char *name = rbf_path;
|
||||
const char *xml = strcasecmp(rbf_path, core_path) ? core_path : NULL;
|
||||
|
||||
if (!name[0])
|
||||
{
|
||||
name = "menu.rbf";
|
||||
xml = NULL;
|
||||
}
|
||||
|
||||
if (FileExists(cfg_get_name(ini_num)))
|
||||
{
|
||||
altcfg(ini_num);
|
||||
fpga_load_rbf(name, NULL, xml);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint32_t diskled_timer = 0;
|
||||
static uint32_t diskled_is_on = 0;
|
||||
void diskled_on()
|
||||
|
||||
Reference in New Issue
Block a user