merging upstream
Merge remote-tracking branch 'refs/remotes/origin/master'
This commit is contained in:
@@ -53,6 +53,7 @@
|
||||
<ClCompile Include="brightness.cpp" />
|
||||
<ClCompile Include="cfg.cpp" />
|
||||
<ClCompile Include="charrom.cpp" />
|
||||
<ClCompile Include="cheats.cpp" />
|
||||
<ClCompile Include="DiskImage.cpp" />
|
||||
<ClCompile Include="file_io.cpp" />
|
||||
<ClCompile Include="fpga_io.cpp" />
|
||||
@@ -90,6 +91,7 @@
|
||||
<ClInclude Include="brightness.h" />
|
||||
<ClInclude Include="cfg.h" />
|
||||
<ClInclude Include="charrom.h" />
|
||||
<ClInclude Include="cheats.h" />
|
||||
<ClInclude Include="debug.h" />
|
||||
<ClInclude Include="DiskImage.h" />
|
||||
<ClInclude Include="file_io.h" />
|
||||
|
||||
@@ -133,6 +133,9 @@
|
||||
<ClCompile Include="charrom.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="cheats.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="battery.h">
|
||||
@@ -267,5 +270,8 @@
|
||||
<ClInclude Include="bootcore.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="cheats.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
330
cheats.cpp
Normal file
330
cheats.cpp
Normal file
@@ -0,0 +1,330 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include <limits.h>
|
||||
#include <ctype.h>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include "hardware.h"
|
||||
#include "file_io.h"
|
||||
#include "user_io.h"
|
||||
#include "fpga_io.h"
|
||||
#include "miniz_zip.h"
|
||||
#include "osd.h"
|
||||
#include "cheats.h"
|
||||
|
||||
struct cheat_rec_t
|
||||
{
|
||||
char enabled;
|
||||
char name[256];
|
||||
};
|
||||
|
||||
typedef std::vector<cheat_rec_t> CheatVector;
|
||||
static CheatVector cheats;
|
||||
|
||||
static int iSelectedEntry = 0;
|
||||
static int iFirstEntry = 0;
|
||||
static int loaded = 0;
|
||||
|
||||
struct CheatComp
|
||||
{
|
||||
bool operator()(const cheat_rec_t& ce1, const cheat_rec_t& ce2)
|
||||
{
|
||||
int len1 = strlen(ce1.name);
|
||||
int len2 = strlen(ce2.name);
|
||||
|
||||
int len = (len1 < len2) ? len1 : len2;
|
||||
int ret = strncasecmp(ce1.name, ce2.name, len);
|
||||
if (!ret)
|
||||
{
|
||||
return len1 < len2;
|
||||
}
|
||||
|
||||
return ret < 0;
|
||||
}
|
||||
};
|
||||
|
||||
static char cheat_zip[1024] = {};
|
||||
|
||||
void cheats_init(char *rom_path)
|
||||
{
|
||||
cheats.clear();
|
||||
loaded = 0;
|
||||
cheat_zip[0] = 0;
|
||||
|
||||
if (!strcasestr(rom_path, ".zip"))
|
||||
{
|
||||
sprintf(cheat_zip, "%s/%s", getRootDir(), rom_path);
|
||||
char *p = strrchr(cheat_zip, '.');
|
||||
if (p) *p = 0;
|
||||
strcat(cheat_zip, ".zip");
|
||||
}
|
||||
|
||||
mz_zip_archive _z = {};
|
||||
if (!mz_zip_reader_init_file(&_z, cheat_zip, 0))
|
||||
{
|
||||
memset(&_z, 0, sizeof(_z));
|
||||
|
||||
char *rom_name = strrchr(rom_path, '/');
|
||||
if (!rom_name) return;
|
||||
|
||||
sprintf(cheat_zip, "%s/cheats/%s%s", getRootDir(), HomeDir, rom_name);
|
||||
char *p = strrchr(cheat_zip, '.');
|
||||
if (p) *p = 0;
|
||||
strcat(cheat_zip, ".zip");
|
||||
|
||||
if (!mz_zip_reader_init_file(&_z, cheat_zip, 0))
|
||||
{
|
||||
printf("no cheat file %s\n", cheat_zip);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
mz_zip_archive *z = new mz_zip_archive(_z);
|
||||
for (size_t i = 0; i < mz_zip_reader_get_num_files(z); i++)
|
||||
{
|
||||
cheat_rec_t ch = {};
|
||||
mz_zip_reader_get_filename(z, i, ch.name, sizeof(ch.name));
|
||||
|
||||
if (mz_zip_reader_is_file_a_directory(z, i))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
cheats.push_back(ch);
|
||||
}
|
||||
|
||||
mz_zip_reader_end(z);
|
||||
delete z;
|
||||
|
||||
std::sort(cheats.begin(), cheats.end(), CheatComp());
|
||||
|
||||
printf("cheats: %d\n", cheats_available());
|
||||
cheats_scan(SCANF_INIT);
|
||||
}
|
||||
|
||||
int cheats_available()
|
||||
{
|
||||
return cheats.size();
|
||||
}
|
||||
|
||||
void cheats_scan(int mode)
|
||||
{
|
||||
if (mode == SCANF_INIT)
|
||||
{
|
||||
iFirstEntry = 0;
|
||||
iSelectedEntry = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!cheats_available()) return;
|
||||
|
||||
if (mode == SCANF_END)
|
||||
{
|
||||
iSelectedEntry = cheats_available() - 1;
|
||||
iFirstEntry = iSelectedEntry - OsdGetSize() + 1;
|
||||
if (iFirstEntry < 0) iFirstEntry = 0;
|
||||
}
|
||||
else if (mode == SCANF_NEXT)
|
||||
{
|
||||
if (iSelectedEntry + 1 < cheats_available()) // scroll within visible items
|
||||
{
|
||||
iSelectedEntry++;
|
||||
if (iSelectedEntry > iFirstEntry + OsdGetSize() - 1) iFirstEntry = iSelectedEntry - OsdGetSize() + 1;
|
||||
}
|
||||
}
|
||||
else if (mode == SCANF_PREV)
|
||||
{
|
||||
if (iSelectedEntry > 0) // scroll within visible items
|
||||
{
|
||||
iSelectedEntry--;
|
||||
if (iSelectedEntry < iFirstEntry) iFirstEntry = iSelectedEntry;
|
||||
}
|
||||
}
|
||||
else if (mode == SCANF_NEXT_PAGE)
|
||||
{
|
||||
if (iSelectedEntry < iFirstEntry + OsdGetSize() - 1)
|
||||
{
|
||||
iSelectedEntry = iFirstEntry + OsdGetSize() - 1;
|
||||
if (iSelectedEntry >= cheats_available()) iSelectedEntry = cheats_available() - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
iSelectedEntry += OsdGetSize();
|
||||
iFirstEntry += OsdGetSize();
|
||||
if (iSelectedEntry >= cheats_available())
|
||||
{
|
||||
iSelectedEntry = cheats_available() - 1;
|
||||
iFirstEntry = iSelectedEntry - OsdGetSize() + 1;
|
||||
if (iFirstEntry < 0) iFirstEntry = 0;
|
||||
}
|
||||
else if (iFirstEntry + OsdGetSize() > cheats_available())
|
||||
{
|
||||
iFirstEntry = cheats_available() - OsdGetSize();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (mode == SCANF_PREV_PAGE)
|
||||
{
|
||||
if (iSelectedEntry != iFirstEntry)
|
||||
{
|
||||
iSelectedEntry = iFirstEntry;
|
||||
}
|
||||
else
|
||||
{
|
||||
iFirstEntry -= OsdGetSize();
|
||||
if (iFirstEntry < 0) iFirstEntry = 0;
|
||||
iSelectedEntry = iFirstEntry;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cheats_scroll_name()
|
||||
{
|
||||
// this function is called periodically when file selection window is displayed
|
||||
// it checks if predefined period of time has elapsed and scrolls the name if necessary
|
||||
int len;
|
||||
int max_len;
|
||||
static char name[256 + 4];
|
||||
|
||||
name[0] = 32;
|
||||
name[1] = cheats[iSelectedEntry].enabled ? 0x1a : 0x1b;
|
||||
name[2] = 32;
|
||||
strcpy(name + 3, cheats[iSelectedEntry].name);
|
||||
|
||||
len = strlen(name); // get name length
|
||||
if (len > 3 && !strncasecmp(name + len - 3, ".gg", 3)) len -= 3;
|
||||
|
||||
max_len = 30;
|
||||
ScrollText(iSelectedEntry - iFirstEntry, name, 3, len, max_len, 1);
|
||||
}
|
||||
|
||||
void cheats_print()
|
||||
{
|
||||
int k;
|
||||
int len;
|
||||
|
||||
static char s[256+4];
|
||||
|
||||
ScrollReset();
|
||||
|
||||
for (int i = 0; i < OsdGetSize(); i++)
|
||||
{
|
||||
char leftchar = 0;
|
||||
if (i < cheats_available())
|
||||
{
|
||||
k = iFirstEntry + i;
|
||||
|
||||
s[0] = 32;
|
||||
s[1] = cheats[k].enabled ? 0x1a : 0x1b;
|
||||
s[2] = 32;
|
||||
strcpy(s + 3, cheats[k].name);
|
||||
|
||||
len = strlen(s); // get name length
|
||||
if (len > 3 && !strncasecmp(s + len - 3, ".gg", 3)) len -= 3;
|
||||
s[len] = 0;
|
||||
|
||||
if (len > 28)
|
||||
{
|
||||
len = 27; // trim display length if longer than 30 characters
|
||||
s[28] = 22;
|
||||
}
|
||||
|
||||
s[29] = 0;
|
||||
|
||||
if (!i && k) leftchar = 17;
|
||||
if ((i == OsdGetSize() - 1) && (k < cheats_available() - 1)) leftchar = 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(s, ' ', 32);
|
||||
}
|
||||
|
||||
OsdWriteOffset(i, s, i == (iSelectedEntry - iFirstEntry), 0, 0, leftchar);
|
||||
}
|
||||
}
|
||||
|
||||
#define CHEAT_SIZE (128*16) // 128 codes max
|
||||
|
||||
static void cheats_send()
|
||||
{
|
||||
static char filename[1024];
|
||||
static uint8_t buff[CHEAT_SIZE];
|
||||
int pos = 0;
|
||||
for (int i = 0; i < cheats_available(); i++)
|
||||
{
|
||||
fileTYPE f = {};
|
||||
if (cheats[i].enabled)
|
||||
{
|
||||
sprintf(filename, "%s/%s", cheat_zip, cheats[i].name);
|
||||
if (FileOpen(&f, filename))
|
||||
{
|
||||
int len = f.size;
|
||||
if (!len || (len & 15))
|
||||
{
|
||||
printf("Cheat file %s has incorrect length %d -> skipping.", filename, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (len + pos > CHEAT_SIZE)
|
||||
{
|
||||
len = CHEAT_SIZE - pos;
|
||||
}
|
||||
|
||||
if (FileReadAdv(&f, buff + pos, len) == len)
|
||||
{
|
||||
pos += len;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Cannot read cheat file %s.", filename);
|
||||
}
|
||||
}
|
||||
FileClose(&f);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Cannot open cheat file %s.", filename);
|
||||
}
|
||||
}
|
||||
|
||||
if (pos >= CHEAT_SIZE) break;
|
||||
}
|
||||
|
||||
loaded = pos / 16;
|
||||
printf("Cheat codes: %d\n", loaded);
|
||||
|
||||
user_io_set_index(255);
|
||||
|
||||
// prepare transmission
|
||||
EnableFpga();
|
||||
spi8(UIO_FILE_TX);
|
||||
spi8(0xff);
|
||||
DisableFpga();
|
||||
|
||||
EnableFpga();
|
||||
spi8(UIO_FILE_TX_DAT);
|
||||
spi_write(buff, pos ? pos : 2, fpga_get_fio_size());
|
||||
DisableFpga();
|
||||
|
||||
// signal end of transmission
|
||||
EnableFpga();
|
||||
spi8(UIO_FILE_TX);
|
||||
spi8(0x00);
|
||||
DisableFpga();
|
||||
}
|
||||
|
||||
void cheats_toggle()
|
||||
{
|
||||
cheats[iSelectedEntry].enabled = !cheats[iSelectedEntry].enabled;
|
||||
cheats_send();
|
||||
}
|
||||
|
||||
int cheats_loaded()
|
||||
{
|
||||
return loaded;
|
||||
}
|
||||
12
cheats.h
Normal file
12
cheats.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef CHEATS_H
|
||||
#define CHEATS_H
|
||||
|
||||
void cheats_init(char *rom_path);
|
||||
int cheats_available();
|
||||
void cheats_scan(int mode);
|
||||
void cheats_scroll_name();
|
||||
void cheats_print();
|
||||
void cheats_toggle();
|
||||
int cheats_loaded();
|
||||
|
||||
#endif
|
||||
@@ -33,8 +33,8 @@ typedef std::vector<dirent> DirentVector;
|
||||
static const size_t YieldIterations = 128;
|
||||
|
||||
DirentVector DirItem;
|
||||
int iSelectedEntry = 0; // selected entry index
|
||||
int iFirstEntry = 0;
|
||||
static int iSelectedEntry = 0; // selected entry index
|
||||
static int iFirstEntry = 0;
|
||||
|
||||
static char full_path[2100];
|
||||
|
||||
|
||||
462
input.cpp
462
input.cpp
@@ -18,7 +18,7 @@
|
||||
#include "osd.h"
|
||||
#include "errno.h"
|
||||
|
||||
#define NUMDEV 10
|
||||
#define NUMDEV 20
|
||||
#define NUMPLAYERS 6
|
||||
|
||||
static int ev2amiga[] =
|
||||
@@ -970,11 +970,22 @@ uint32_t get_key_mod()
|
||||
return modifier & MODMASK;
|
||||
}
|
||||
|
||||
enum QUIRK
|
||||
{
|
||||
QUIRK_NONE = 0,
|
||||
QUIRK_CWIID,
|
||||
QUIRK_WIIMOTE,
|
||||
QUIRK_DS3,
|
||||
QUIRK_DS4,
|
||||
QUIRK_DS4TOUCH,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t vid, pid;
|
||||
uint8_t led;
|
||||
uint8_t axis_state[256];
|
||||
uint8_t axis_edge[256];
|
||||
int8_t axis_pos[256];
|
||||
|
||||
uint8_t num;
|
||||
uint8_t has_map;
|
||||
@@ -988,6 +999,15 @@ typedef struct
|
||||
uint8_t kbdmap[256];
|
||||
|
||||
int accx, accy;
|
||||
int quirk;
|
||||
|
||||
int lightgun_req;
|
||||
int lightgun;
|
||||
|
||||
int bind;
|
||||
char devname[32];
|
||||
char uniq[32];
|
||||
char name[128];
|
||||
} devInput;
|
||||
|
||||
static devInput input[NUMDEV] = {};
|
||||
@@ -1139,26 +1159,34 @@ int toggle_kbdled(int mask)
|
||||
|
||||
static int mapping = 0;
|
||||
static int mapping_button;
|
||||
static int mapping_dev;
|
||||
static int mapping_dev = -1;
|
||||
static int mapping_type;
|
||||
static int mapping_count;
|
||||
static int mapping_clear;
|
||||
static int mapping_set;
|
||||
|
||||
static uint32_t tmp_axis[4];
|
||||
static int tmp_axis_n = 0;
|
||||
|
||||
void start_map_setting(int cnt)
|
||||
void start_map_setting(int cnt, int set)
|
||||
{
|
||||
mapping_button = 0;
|
||||
mapping = 1;
|
||||
mapping_dev = -1;
|
||||
mapping_type = (cnt<0) ? 3 : cnt ? 1 : 2;
|
||||
mapping_set = set;
|
||||
if (!mapping_set)
|
||||
{
|
||||
mapping_dev = -1;
|
||||
mapping_type = (cnt < 0) ? 3 : cnt ? 1 : 2;
|
||||
}
|
||||
mapping_count = cnt;
|
||||
mapping_clear = 0;
|
||||
tmp_axis_n = 0;
|
||||
|
||||
if (mapping_type <= 1 && is_menu_core()) mapping_button = -6;
|
||||
memset(tmp_axis, 0, sizeof(tmp_axis));
|
||||
|
||||
//un-stick the enter key
|
||||
user_io_kbd(KEY_ENTER, 0);
|
||||
}
|
||||
|
||||
int get_map_button()
|
||||
@@ -1209,9 +1237,6 @@ void finish_map_setting(int dismiss)
|
||||
{
|
||||
for (int i = 0; i < NUMDEV; i++) input[i].has_map = 0;
|
||||
|
||||
if (mapping_button < 0) mapping_button = 0;
|
||||
if (!is_menu_core()) for (uint i = mapping_button; i < BTN_NUM; i++) input[mapping_dev].map[i] = 0;
|
||||
|
||||
if (!dismiss) FileSaveConfig(get_map_name(mapping_dev, 0), &input[mapping_dev].map, sizeof(input[mapping_dev].map));
|
||||
if (is_menu_core()) input[mapping_dev].has_mmap = 0;
|
||||
}
|
||||
@@ -1513,11 +1538,15 @@ static void joy_analog(int num, int axis, int offset)
|
||||
}
|
||||
}
|
||||
|
||||
static int ds_ver = 0;
|
||||
static int ds_mouse_emu = 0;
|
||||
|
||||
static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int dev)
|
||||
{
|
||||
int sub_dev = dev;
|
||||
|
||||
//check if device is a part of multifunctional device
|
||||
if (input[dev].bind >= 0) dev = input[dev].bind;
|
||||
|
||||
//mouse
|
||||
if (ev->type == EV_KEY && ev->code >= BTN_MOUSE && ev->code < BTN_JOYSTICK)
|
||||
{
|
||||
@@ -1545,12 +1574,9 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
|
||||
}
|
||||
else
|
||||
{
|
||||
//copy alternative directional buttons, remove system buttons
|
||||
for (uint i = 0; i < sizeof(input[0].map) / sizeof(input[0].map[0]); i++)
|
||||
for (uint i = 8; i < sizeof(input[0].map) / sizeof(input[0].map[0]); i++)
|
||||
{
|
||||
if(i < 4) input[dev].map[i] = (input[dev].map[i] << 16) | (input[dev].map[i + 8] & 0xFFFF);
|
||||
else if(i < 8) input[dev].map[i] = input[dev].map[i] << 16;
|
||||
else input[dev].map[i] = 0;
|
||||
input[dev].map[i] = 0;
|
||||
}
|
||||
}
|
||||
input[dev].has_map++;
|
||||
@@ -1618,16 +1644,17 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
|
||||
else
|
||||
{
|
||||
int clear = ev->code == KEY_F12 || ev->code == KEY_MENU || ev->code == KEY_HOMEPAGE;
|
||||
if (mapping_dev < 0 && !clear)
|
||||
if (ev->value == 1 && mapping_dev < 0 && !clear)
|
||||
{
|
||||
mapping_dev = dev;
|
||||
mapping_type = (ev->code >= 256) ? 1 : 0;
|
||||
key_mapped = 0;
|
||||
}
|
||||
|
||||
mapping_clear = 0;
|
||||
if (mapping_dev >= 0 && (mapping_dev == dev || clear) && mapping_button < (is_menu_core() ? 17 : mapping_count))
|
||||
{
|
||||
if (ev->value == 1)
|
||||
if (ev->value == 1 && !key_mapped)
|
||||
{
|
||||
if (is_menu_core())
|
||||
{
|
||||
@@ -1642,6 +1669,18 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
|
||||
{
|
||||
input[dev].map[(mapping_button == 16) ? 16 + mapping_type : mapping_button] = ev->code;
|
||||
key_mapped = ev->code;
|
||||
|
||||
//check if analog stick has been used for mouse
|
||||
if (mapping_button == 9 || mapping_button == 11)
|
||||
{
|
||||
if (input[dev].map[mapping_button] >= KEY_EMU &&
|
||||
input[dev].map[mapping_button - 1] >= KEY_EMU &&
|
||||
(input[dev].map[mapping_button - 1] - input[dev].map[mapping_button] == 1) && // same axis
|
||||
absinfo)
|
||||
{
|
||||
input[dev].map[AXIS_MX + (mapping_button - 9)/2] = ((input[dev].map[mapping_button] - KEY_EMU)/2) | 0x20000;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1659,19 +1698,21 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
|
||||
{
|
||||
for (uint i = 0; i < sizeof(input[0].map) / sizeof(input[0].map[0]); i++)
|
||||
{
|
||||
input[dev].map[i] = mapping_type ? input[dev].map[i] << 16 : 0;
|
||||
input[dev].map[i] &= mapping_set ? 0x0000FFFF : 0xFFFF0000;
|
||||
}
|
||||
}
|
||||
|
||||
int found = 0;
|
||||
for (int i = 0; i < mapping_button; i++)
|
||||
{
|
||||
if ((input[dev].map[i] & 0xFFFF) == ev->code) found = 1;
|
||||
if (mapping_set && (input[dev].map[i] >> 16) == ev->code) found = 1;
|
||||
if (!mapping_set && (input[dev].map[i] & 0xFFFF) == ev->code) found = 1;
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
input[dev].map[mapping_button] = input[dev].map[mapping_button] | (ev->code & 0xFFFF);
|
||||
if (mapping_set) input[dev].map[mapping_button] = (input[dev].map[mapping_button] & 0xFFFF) | (ev->code << 16);
|
||||
else input[dev].map[mapping_button] = (input[dev].map[mapping_button] & 0xFFFF0000) | ev->code;
|
||||
key_mapped = ev->code;
|
||||
}
|
||||
}
|
||||
@@ -1798,7 +1839,15 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
|
||||
{
|
||||
if (ev->value == 1)
|
||||
{
|
||||
if (idx && mapping_dev >= 0) input[mapping_dev].map[idx] = is_menu_core() ? 0 : (input[mapping_dev].map[idx] & 0xFFFF0000);
|
||||
if (mapping_dev >= 0)
|
||||
{
|
||||
if (idx) input[mapping_dev].map[idx] = 0;
|
||||
else if (mapping_button > 0)
|
||||
{
|
||||
if (is_menu_core()) input[mapping_dev].map[mapping_button] = 0;
|
||||
else input[mapping_dev].map[mapping_button] &= mapping_set ? 0x0000FFFF : 0xFFFF0000;
|
||||
}
|
||||
}
|
||||
mapping_button++;
|
||||
if (mapping_button < 0 && (mapping_button&1)) mapping_button++;
|
||||
}
|
||||
@@ -1842,7 +1891,13 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
|
||||
|
||||
if (ev->code == input[dev].mmap[17])
|
||||
{
|
||||
if (ev->value <= 1) joy_digital(input[dev].num, 0, 0, ev->value, BTN_OSD);
|
||||
if (ev->value == 1 && input[dev].lightgun_req && !user_io_osd_is_visible())
|
||||
{
|
||||
input[dev].lightgun = !input[dev].lightgun;
|
||||
Info(input[dev].lightgun ? "Light Gun mode is ON" : "Light Gun mode is OFF");
|
||||
}
|
||||
else if (ev->value <= 1) joy_digital(input[dev].num, 0, 0, ev->value, BTN_OSD);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1866,6 +1921,20 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
|
||||
joy_digital(0, 0, 0, ev->value, BTN_OSD);
|
||||
return;
|
||||
}
|
||||
|
||||
if (input[dev].mmap[AXIS_X])
|
||||
{
|
||||
uint16_t key = KEY_EMU + ((uint16_t)input[dev].mmap[AXIS_X]*2);
|
||||
if (ev->code == (key + 1)) joy_digital(0, 1 << 0, 0, ev->value, 0);
|
||||
if (ev->code == key) joy_digital(0, 1 << 1, 0, ev->value, 1);
|
||||
}
|
||||
|
||||
if (input[dev].mmap[AXIS_Y])
|
||||
{
|
||||
uint16_t key = KEY_EMU + ((uint16_t)input[dev].mmap[AXIS_Y]*2);
|
||||
if (ev->code == (key + 1)) joy_digital(0, 1 << 2, 0, ev->value, 2);
|
||||
if (ev->code == key) joy_digital(0, 1 << 3, 0, ev->value, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1923,7 +1992,7 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
|
||||
if (ev->code == input[dev].mmap[15] && (ev->value <= 1) && ((!(mouse_emu & 1)) ^ (!ev->value)))
|
||||
{
|
||||
mouse_emu = ev->value ? mouse_emu | 1 : mouse_emu & ~1;
|
||||
if (ds_ver == 4) ds_mouse_emu = mouse_emu & 1;
|
||||
if (input[sub_dev].quirk == QUIRK_DS4) ds_mouse_emu = mouse_emu & 1;
|
||||
printf("mouse_emu = %d\n", mouse_emu);
|
||||
if (mouse_emu & 2)
|
||||
{
|
||||
@@ -2064,15 +2133,45 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
|
||||
case EV_ABS:
|
||||
if (!user_io_osd_is_visible())
|
||||
{
|
||||
// TODO: implement inversion
|
||||
int hrange = (absinfo->maximum - absinfo->minimum) / 2;
|
||||
int dead = hrange/63;
|
||||
|
||||
//convert to 0..255 range
|
||||
int value = ((ev->value - absinfo->minimum) * 256) / (absinfo->maximum - absinfo->minimum + 1);
|
||||
value = (value < 127 || value>129) ? value - 128 : 0;
|
||||
if (input[sub_dev].quirk == QUIRK_CWIID)
|
||||
{
|
||||
if(ev->code == 3 || ev->code == 4) dead = 10;
|
||||
}
|
||||
|
||||
if (input[sub_dev].quirk == QUIRK_DS3 || input[sub_dev].quirk == QUIRK_DS4)
|
||||
{
|
||||
dead = 10;
|
||||
}
|
||||
|
||||
int value = ev->value;
|
||||
if (ev->value < absinfo->minimum) value = absinfo->minimum;
|
||||
else if (ev->value > absinfo->maximum) value = absinfo->maximum;
|
||||
|
||||
// normalize to -range/2...+range/2
|
||||
value = value - (absinfo->minimum + absinfo->maximum) / 2;
|
||||
|
||||
if (ev->code > 1 || !input[dev].lightgun) //lightgun has no dead zone
|
||||
{
|
||||
// check the dead-zone and remove it from the range
|
||||
hrange -= dead;
|
||||
if (value < -dead) value += dead;
|
||||
else if (value > dead) value -= dead;
|
||||
else value = 0;
|
||||
}
|
||||
|
||||
value = (value * 127) / hrange;
|
||||
|
||||
//final check to eliminate additive error
|
||||
if (value < -127) value = -127;
|
||||
//printf("ABS: axis %d = %d -> %d\n", ev->code, ev->value, value);
|
||||
else if (value > 127) value = 127;
|
||||
|
||||
else if (ev->code == (input[dev].mmap[AXIS_MX] & 0xFFFF) && mouse_emu)
|
||||
if (input[sub_dev].axis_pos[ev->code & 0xFF] == (int8_t)value) break;
|
||||
input[sub_dev].axis_pos[ev->code & 0xFF] = (int8_t)value;
|
||||
|
||||
if (ev->code == (input[dev].mmap[AXIS_MX] & 0xFFFF) && mouse_emu)
|
||||
{
|
||||
mouse_emu_x = 0;
|
||||
if (value < -1 || value>1) mouse_emu_x = value;
|
||||
@@ -2086,9 +2185,9 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
|
||||
mouse_emu_y /= 12;
|
||||
return;
|
||||
}
|
||||
else if (ev->code == (input[dev].mmap[AXIS_X] & 0xFFFF))
|
||||
else if (ev->code == (input[dev].mmap[AXIS_X] & 0xFFFF) || (ev->code == 0 && input[dev].lightgun))
|
||||
{
|
||||
// skip if first joystick is not defined.
|
||||
// skip if joystick is undefined.
|
||||
if (!input[dev].num) break;
|
||||
|
||||
int offset = 0;
|
||||
@@ -2097,9 +2196,9 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
|
||||
joy_analog(input[dev].num, 0, offset);
|
||||
return;
|
||||
}
|
||||
else if (ev->code == (input[dev].mmap[AXIS_Y] & 0xFFFF))
|
||||
else if (ev->code == (input[dev].mmap[AXIS_Y] & 0xFFFF) || (ev->code == 1 && input[dev].lightgun))
|
||||
{
|
||||
// skip if first joystick is not defined.
|
||||
// skip if joystick is undefined.
|
||||
if (!input[dev].num) break;
|
||||
|
||||
int offset = 0;
|
||||
@@ -2114,41 +2213,13 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
|
||||
}
|
||||
}
|
||||
|
||||
static uint16_t read_hex(char *filename)
|
||||
{
|
||||
FILE *in;
|
||||
unsigned int value;
|
||||
|
||||
in = fopen(filename, "rb");
|
||||
if (!in) return 0;
|
||||
|
||||
if (fscanf(in, "%x", &value) == 1)
|
||||
{
|
||||
fclose(in);
|
||||
return (uint16_t)value;
|
||||
}
|
||||
fclose(in);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void getVidPid(char *evt, uint16_t *vid, uint16_t *pid)
|
||||
{
|
||||
char name[256];
|
||||
sprintf(name, "/sys/class/input/%s/device/id/vendor", evt);
|
||||
*vid = read_hex(name);
|
||||
sprintf(name, "/sys/class/input/%s/device/id/product", evt);
|
||||
*pid = read_hex(name);
|
||||
}
|
||||
|
||||
static struct pollfd pool[NUMDEV + 2];
|
||||
|
||||
int input_test(int getchar)
|
||||
{
|
||||
static char cur_leds = 0;
|
||||
static int state = 0;
|
||||
static char cur_leds = 0;
|
||||
static int state = 0;
|
||||
struct input_absinfo absinfo;
|
||||
|
||||
char devname[32];
|
||||
struct input_event ev;
|
||||
|
||||
if (state == 0)
|
||||
@@ -2181,34 +2252,122 @@ int input_test(int getchar)
|
||||
if (state == 1)
|
||||
{
|
||||
printf("Open up to %d input devices.\n", NUMDEV);
|
||||
for (int i = 0; i < NUMDEV; i++)
|
||||
{
|
||||
pool[i].fd = -1;
|
||||
pool[i].events = 0;
|
||||
}
|
||||
|
||||
int n = 0;
|
||||
DIR *d = opendir("/dev/input");
|
||||
if (d)
|
||||
{
|
||||
struct input_id id;
|
||||
struct dirent *de;
|
||||
while ((de = readdir(d)))
|
||||
{
|
||||
if (!strncmp(de->d_name, "event", 5))
|
||||
{
|
||||
sprintf(devname, "/dev/input/%s", de->d_name);
|
||||
int fd = open(devname, O_RDWR);
|
||||
memset(&input[n], 0, sizeof(input[n]));
|
||||
sprintf(input[n].devname, "/dev/input/%s", de->d_name);
|
||||
int fd = open(input[n].devname, O_RDWR);
|
||||
printf("open(%s): %d\n", input[n].devname, fd);
|
||||
|
||||
if (fd > 0)
|
||||
{
|
||||
pool[n].fd = fd;
|
||||
pool[n].events = POLLIN;
|
||||
memset(&input[n], 0, sizeof(input[n]));
|
||||
input[n].led = has_led(pool[n].fd);
|
||||
getVidPid(de->d_name, &input[n].vid, &input[n].pid);
|
||||
printf("opened %d: %s (%04x:%04x)\n", n, devname, input[n].vid, input[n].pid);
|
||||
|
||||
memset(&id, 0, sizeof(id));
|
||||
ioctl(pool[n].fd, EVIOCGID, &id);
|
||||
input[n].vid = id.vendor;
|
||||
input[n].pid = id.product;
|
||||
|
||||
ioctl(pool[n].fd, EVIOCGUNIQ(sizeof(input[n].uniq)), input[n].uniq);
|
||||
ioctl(pool[n].fd, EVIOCGNAME(sizeof(input[n].name)), input[n].name);
|
||||
input[n].bind = -1;
|
||||
if (strcasestr(input[n].name, "Wiimote") && input[n].vid == 1 && input[n].pid == 1)
|
||||
{
|
||||
input[n].quirk = QUIRK_CWIID;
|
||||
input[n].lightgun = 1;
|
||||
}
|
||||
|
||||
if (input[n].vid == 0x054c)
|
||||
{
|
||||
if (input[n].pid == 0x0268) input[n].quirk = QUIRK_DS3;
|
||||
else if (input[n].pid == 0x05c4 || input[n].pid == 0x09cc)
|
||||
{
|
||||
input[n].quirk = QUIRK_DS4;
|
||||
if (strcasestr(input[n].name, "Touchpad"))
|
||||
{
|
||||
input[n].quirk = QUIRK_DS4TOUCH;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (input[n].vid == 0x0079 && input[n].pid == 0x1802)
|
||||
{
|
||||
strcpy(input[n].uniq, "Mayflash 1802");
|
||||
input[n].lightgun = 1;
|
||||
input[n].num = 2; // force mayflash mode 1/2 as second joystick.
|
||||
}
|
||||
|
||||
if (input[n].vid == 0x057e && (input[n].pid == 0x0306 || input[n].pid == 0x0330))
|
||||
{
|
||||
if (strcasestr(input[n].name, "Accelerometer"))
|
||||
{
|
||||
// don't use Accelerometer
|
||||
close(pool[n].fd);
|
||||
continue;
|
||||
}
|
||||
else if (strcasestr(input[n].name, "Motion Plus"))
|
||||
{
|
||||
// don't use Accelerometer
|
||||
close(pool[n].fd);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
input[n].quirk = QUIRK_WIIMOTE;
|
||||
}
|
||||
}
|
||||
|
||||
// Raphnet devices: clear uniq to prevent merging the ports
|
||||
if (input[n].vid == 0x289b)
|
||||
{
|
||||
memset(input[n].uniq, 0, sizeof(input[n].uniq));
|
||||
}
|
||||
|
||||
n++;
|
||||
if (n >= NUMDEV) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(d);
|
||||
}
|
||||
|
||||
// merge multifunctional devices using uniq field
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
input[i].bind = i;
|
||||
if (input[i].uniq[0])
|
||||
{
|
||||
for (int j = 0; j < i; j++)
|
||||
{
|
||||
if (!memcmp(input[i].uniq, input[j].uniq, sizeof(input[0].uniq)))
|
||||
{
|
||||
input[i].bind = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
printf("opened %d(%2d): %s (%04x:%04x) %d \"%s\" \"%s\"\n", i, input[i].bind, input[i].devname, input[i].vid, input[i].pid, input[i].quirk, input[i].uniq, input[i].name);
|
||||
}
|
||||
}
|
||||
cur_leds |= 0x80;
|
||||
state++;
|
||||
}
|
||||
@@ -2225,10 +2384,7 @@ int input_test(int getchar)
|
||||
if ((pool[NUMDEV].revents & POLLIN) && check_devs())
|
||||
{
|
||||
printf("Close all devices.\n");
|
||||
for (int i = 0; i<NUMDEV; i++)
|
||||
{
|
||||
if (pool[i].fd >= 0) close(pool[i].fd);
|
||||
}
|
||||
for (int i = 0; i<NUMDEV; i++) if (pool[i].fd >= 0) close(pool[i].fd);
|
||||
state = 1;
|
||||
return 0;
|
||||
}
|
||||
@@ -2249,33 +2405,101 @@ int input_test(int getchar)
|
||||
}
|
||||
else if(ev.type)
|
||||
{
|
||||
ds_ver = 0;
|
||||
if (input[i].vid == 0x054c)
|
||||
{
|
||||
if (input[i].pid == 0x0268) ds_ver = 3;
|
||||
if (input[i].pid == 0x05c4 || input[i].pid == 0x09cc) ds_ver = 4;
|
||||
}
|
||||
int dev = i;
|
||||
if (input[dev].bind >= 0) dev = input[dev].bind;
|
||||
|
||||
if (ds_ver == 4 && ev.type == EV_KEY)
|
||||
int noabs = 0;
|
||||
|
||||
if (input[i].quirk == QUIRK_DS4TOUCH && ev.type == EV_KEY)
|
||||
{
|
||||
if (ev.code == BTN_TOOL_FINGER || ev.code == BTN_TOUCH || ev.code == BTN_TOOL_DOUBLETAP) continue;
|
||||
}
|
||||
|
||||
if (ev.type == EV_ABS)
|
||||
{
|
||||
if (input[i].quirk == QUIRK_WIIMOTE)
|
||||
{
|
||||
//nunchuck accel events
|
||||
if(ev.code >= 3 && ev.code <= 5) continue;
|
||||
}
|
||||
|
||||
//Dualshock: drop accelerator and raw touchpad events
|
||||
if (ds_ver && ev.code > 40) continue;
|
||||
if (input[i].quirk == QUIRK_DS4TOUCH && ev.code == 57)
|
||||
{
|
||||
input[dev].lightgun_req = (ev.value >= 0);
|
||||
}
|
||||
|
||||
if ((input[i].quirk == QUIRK_DS4TOUCH || input[i].quirk == QUIRK_DS4 || input[i].quirk == QUIRK_DS3) && ev.code > 40)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ioctl(pool[i].fd, EVIOCGABS(ev.code), &absinfo) < 0) memset(&absinfo, 0, sizeof(absinfo));
|
||||
else
|
||||
{
|
||||
//DS4: drop mapped touchpad events.
|
||||
if (ds_ver == 4 && ev.code <= 1 && absinfo.maximum > 255) continue;
|
||||
//DS4 specific: touchpad as lightgun
|
||||
if (input[i].quirk == QUIRK_DS4TOUCH && ev.code <= 1)
|
||||
{
|
||||
if (!input[dev].lightgun || user_io_osd_is_visible()) continue;
|
||||
|
||||
if (ev.code == 1)
|
||||
{
|
||||
absinfo.minimum = 300;
|
||||
absinfo.maximum = 850;
|
||||
}
|
||||
else if (ev.code == 0)
|
||||
{
|
||||
absinfo.minimum = 200;
|
||||
absinfo.maximum = 1720;
|
||||
}
|
||||
else continue;
|
||||
}
|
||||
|
||||
if (input[i].quirk == QUIRK_DS4 && ev.code <= 1)
|
||||
{
|
||||
if (input[dev].lightgun) noabs = 1;
|
||||
}
|
||||
|
||||
if (input[i].quirk == QUIRK_WIIMOTE)
|
||||
{
|
||||
input[dev].lightgun = 0;
|
||||
if (absinfo.maximum == 1023 || absinfo.maximum == 767)
|
||||
{
|
||||
if (user_io_osd_is_visible()) continue;
|
||||
if (ev.code == 16)
|
||||
{
|
||||
ev.value = absinfo.maximum - ev.value;
|
||||
ev.code = 0;
|
||||
input[dev].lightgun = 1;
|
||||
}
|
||||
else if (ev.code == 17)
|
||||
{
|
||||
ev.code = 1;
|
||||
input[dev].lightgun = 1;
|
||||
}
|
||||
// other 3 IR tracking aren't used
|
||||
else continue;
|
||||
}
|
||||
else if (absinfo.maximum == 62)
|
||||
{
|
||||
//LT/RT analog
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (input[i].quirk == QUIRK_CWIID)
|
||||
{
|
||||
if (ev.code == 3 || ev.code == 4)
|
||||
{
|
||||
absinfo.minimum = 30;
|
||||
absinfo.maximum = 225;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Menu combo on 8BitDo receiver in PSC mode
|
||||
if (input[i].vid == 0x054c && input[i].pid == 0x0cda && ev.type == EV_KEY)
|
||||
if (input[dev].vid == 0x054c && input[dev].pid == 0x0cda && ev.type == EV_KEY)
|
||||
{
|
||||
//in PSC mode these keys coming from separate virtual keyboard device
|
||||
//so it's impossible to use joystick codes as keyboards aren't personalized
|
||||
@@ -2284,7 +2508,7 @@ int input_test(int getchar)
|
||||
}
|
||||
|
||||
//Menu button quirk of 8BitDo gamepad in X-Input mode
|
||||
if (input[i].vid == 0x045e && input[i].pid == 0x02e0 && ev.type == EV_KEY)
|
||||
if (input[dev].vid == 0x045e && input[dev].pid == 0x02e0 && ev.type == EV_KEY)
|
||||
{
|
||||
if (ev.code == KEY_MENU) ev.code = BTN_MODE;
|
||||
}
|
||||
@@ -2322,11 +2546,11 @@ int input_test(int getchar)
|
||||
{
|
||||
//keyboard, buttons
|
||||
case EV_KEY:
|
||||
printf("Input event: type=EV_KEY, code=%d(0x%x), value=%d, jnum=%d, ID:%04x:%04x\n", ev.code, ev.code, ev.value, input[i].num, input[i].vid, input[i].pid);
|
||||
printf("Input event: type=EV_KEY, code=%d(0x%x), value=%d, jnum=%d, ID:%04x:%04x:%02d\n", ev.code, ev.code, ev.value, input[dev].num, input[dev].vid, input[dev].pid, i);
|
||||
break;
|
||||
|
||||
case EV_REL:
|
||||
printf("Input event: type=EV_REL, Axis=%d, Offset=%d, jnum=%d, ID:%04x:%04x\n", ev.code, ev.value, input[i].num, input[i].vid, input[i].pid);
|
||||
printf("Input event: type=EV_REL, Axis=%d, Offset=%d, jnum=%d, ID:%04x:%04x:%02d\n", ev.code, ev.value, input[dev].num, input[dev].vid, input[dev].pid, i);
|
||||
break;
|
||||
|
||||
case EV_SYN:
|
||||
@@ -2336,55 +2560,69 @@ int input_test(int getchar)
|
||||
//analog joystick
|
||||
case EV_ABS:
|
||||
//reduce flood from DUALSHOCK 3/4
|
||||
if (ds_ver && ev.code <= 5 && ev.value > 118 && ev.value < 138) break;
|
||||
if ((input[i].quirk == QUIRK_DS4 || input[i].quirk == QUIRK_DS3) && ev.code <= 5 && ev.value > 118 && ev.value < 138)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
//aliexpress USB encoder floods messages
|
||||
if (input[i].vid == 0x0079 && input[i].pid == 0x0006)
|
||||
if (input[dev].vid == 0x0079 && input[dev].pid == 0x0006)
|
||||
{
|
||||
if (ev.code == 2) break;
|
||||
}
|
||||
|
||||
printf("Input event: type=EV_ABS, Axis=%d, Offset=%d, jnum=%d, ID:%04x:%04x.", ev.code, ev.value, input[i].num, input[i].vid, input[i].pid);
|
||||
printf(" ABS_INFO: min = %d max = %d", absinfo.minimum, absinfo.maximum);
|
||||
if (absinfo.fuzz) printf(" fuzz = %d", absinfo.fuzz);
|
||||
if (absinfo.resolution) printf(" res = %d", absinfo.resolution);
|
||||
printf("Input event: type=EV_ABS, Axis=%d, Offset=%d, jnum=%d, ID:%04x:%04x:%02d,", ev.code, ev.value, input[dev].num, input[dev].vid, input[dev].pid, i);
|
||||
printf(" abs_min = %d, abs_max = %d", absinfo.minimum, absinfo.maximum);
|
||||
if (absinfo.fuzz) printf(", fuzz = %d", absinfo.fuzz);
|
||||
if (absinfo.resolution) printf(", res = %d", absinfo.resolution);
|
||||
printf("\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("Input event: type=%d, code=%d(0x%x), value=%d(0x%x), jnum=%d, ID:%04x:%04x\n", ev.type, ev.code, ev.code, ev.value, ev.value, input[i].num, input[i].vid, input[i].pid);
|
||||
printf("Input event: type=%d, code=%d(0x%x), value=%d(0x%x), jnum=%d, ID:%04x:%04x:%02d\n", ev.type, ev.code, ev.code, ev.value, ev.value, input[dev].num, input[dev].vid, input[dev].pid, i);
|
||||
}
|
||||
}
|
||||
|
||||
input_cb(&ev, &absinfo, i);
|
||||
if (input[i].quirk == QUIRK_CWIID && ev.type == EV_ABS)
|
||||
{
|
||||
if (ev.code <= 1 && user_io_osd_is_visible())
|
||||
{
|
||||
// don't pass IR tracking to OSD
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if(!noabs) input_cb(&ev, &absinfo, i);
|
||||
|
||||
//sumulate digital directions from analog
|
||||
if (ev.type == EV_ABS && !(mapping && mapping_type<=1 && mapping_button<-4))
|
||||
if (ev.type == EV_ABS && !(mapping && mapping_type<=1 && mapping_button<-4) && !(ev.code<=1 && input[dev].lightgun))
|
||||
{
|
||||
uint8_t axis_state = 0;
|
||||
input_absinfo *pai = 0;
|
||||
uint8_t axis_edge = 0;
|
||||
if ((absinfo.maximum == 1 && absinfo.minimum == -1) || (absinfo.maximum == 2 && absinfo.minimum == 0))
|
||||
{
|
||||
if (ev.value == absinfo.minimum) axis_state = 1;
|
||||
if (ev.value == absinfo.maximum) axis_state = 2;
|
||||
if (ev.value == absinfo.minimum) axis_edge = 1;
|
||||
if (ev.value == absinfo.maximum) axis_edge = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
pai = &absinfo;
|
||||
int range = absinfo.maximum - absinfo.minimum + 1;
|
||||
int center = absinfo.minimum + (range / 2);
|
||||
int treshold = range / 4;
|
||||
|
||||
int only_max = 1;
|
||||
for (int n = 0; n < 4; n++) if (input[i].mmap[AXIS1_X + n] && ((input[i].mmap[AXIS1_X + n] & 0xFFFF) == ev.code)) only_max = 0;
|
||||
for (int n = 0; n < 4; n++) if (input[dev].mmap[AXIS1_X + n] && ((input[dev].mmap[AXIS1_X + n] & 0xFFFF) == ev.code)) only_max = 0;
|
||||
|
||||
if (ev.value < center - treshold && !only_max) axis_state = 1;
|
||||
if (ev.value > center + treshold) axis_state = 2;
|
||||
if (ev.value < center - treshold && !only_max) axis_edge = 1;
|
||||
if (ev.value > center + treshold) axis_edge = 2;
|
||||
}
|
||||
|
||||
uint8_t last_state = input[i].axis_state[ev.code & 255];
|
||||
input[i].axis_state[ev.code & 255] = axis_state;
|
||||
uint8_t last_state = input[dev].axis_edge[ev.code & 255];
|
||||
input[dev].axis_edge[ev.code & 255] = axis_edge;
|
||||
|
||||
//printf("last_state=%d, axis_state=%d\n", last_state, axis_state);
|
||||
if (last_state != axis_state)
|
||||
//printf("last_state=%d, axis_edge=%d\n", last_state, axis_edge);
|
||||
if (last_state != axis_edge)
|
||||
{
|
||||
uint16_t ecode = KEY_EMU + (ev.code << 1) - 1;
|
||||
ev.type = EV_KEY;
|
||||
@@ -2392,23 +2630,23 @@ int input_test(int getchar)
|
||||
{
|
||||
ev.value = 0;
|
||||
ev.code = ecode + last_state;
|
||||
input_cb(&ev, 0, i);
|
||||
input_cb(&ev, pai, i);
|
||||
}
|
||||
|
||||
if (axis_state)
|
||||
if (axis_edge)
|
||||
{
|
||||
ev.value = 1;
|
||||
ev.code = ecode + axis_state;
|
||||
input_cb(&ev, 0, i);
|
||||
ev.code = ecode + axis_edge;
|
||||
input_cb(&ev, pai, i);
|
||||
}
|
||||
}
|
||||
|
||||
// Menu button on 8BitDo Receiver in D-Input mode
|
||||
if (ev.code == 9 && input[i].vid == 0x2dc8 && (input[i].pid == 0x3100 || input[i].pid == 0x3104))
|
||||
if (ev.code == 9 && input[dev].vid == 0x2dc8 && (input[dev].pid == 0x3100 || input[dev].pid == 0x3104))
|
||||
{
|
||||
ev.type = EV_KEY;
|
||||
ev.code = KEY_EMU + (ev.code << 1);
|
||||
input_cb(&ev, &absinfo, i);
|
||||
input_cb(&ev, pai, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
2
input.h
2
input.h
@@ -37,7 +37,7 @@ void input_notify_mode();
|
||||
int input_poll(int getchar);
|
||||
int is_key_pressed(int key);
|
||||
|
||||
void start_map_setting(int cnt);
|
||||
void start_map_setting(int cnt, int set = 0);
|
||||
int get_map_button();
|
||||
int get_map_type();
|
||||
int get_map_clear();
|
||||
|
||||
353
menu.cpp
353
menu.cpp
@@ -48,6 +48,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include "input.h"
|
||||
#include "battery.h"
|
||||
#include "bootcore.h"
|
||||
#include "cheats.h"
|
||||
|
||||
#include "support.h"
|
||||
|
||||
@@ -97,13 +98,21 @@ enum MENU
|
||||
MENU_JOYDIGMAP,
|
||||
MENU_JOYDIGMAP1,
|
||||
MENU_JOYDIGMAP2,
|
||||
MENU_JOYDIGMAP3,
|
||||
MENU_JOYDIGMAP4,
|
||||
MENU_JOYKBDMAP,
|
||||
MENU_JOYKBDMAP1,
|
||||
MENU_KBDMAP,
|
||||
MENU_KBDMAP1,
|
||||
MENU_SCRIPTS_PRE,
|
||||
MENU_SCRIPTS_PRE1,
|
||||
MENU_SCRIPTS,
|
||||
MENU_SCRIPTS1,
|
||||
MENU_BTPAIR,
|
||||
MENU_WMPAIR,
|
||||
MENU_WMPAIR1,
|
||||
MENU_CHEATS1,
|
||||
MENU_CHEATS2,
|
||||
|
||||
// Mist/atari specific pages
|
||||
MENU_MIST_MAIN1,
|
||||
@@ -507,6 +516,35 @@ static int has_bt()
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int toggle_wminput()
|
||||
{
|
||||
if (access("/bin/wminput", F_OK) < 0 || access("/media/fat/linux/wiimote.cfg", F_OK) < 0) return -1;
|
||||
|
||||
FILE *fp;
|
||||
static char out[1035];
|
||||
|
||||
fp = popen("pidof wminput", "r");
|
||||
if (!fp) return -1;
|
||||
|
||||
int ret = -1;
|
||||
if (fgets(out, sizeof(out) - 1, fp) != NULL)
|
||||
{
|
||||
if (strlen(out))
|
||||
{
|
||||
system("killall wminput");
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
system("taskset 1 wminput --daemon --config /media/fat/linux/wiimote.cfg &");
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
pclose(fp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static char* getNet(int spec)
|
||||
{
|
||||
int netType = 0;
|
||||
@@ -694,6 +732,8 @@ const char* get_rbf_name_bootcore(char *str)
|
||||
return p + 1;
|
||||
}
|
||||
|
||||
static int joymap_first = 0;
|
||||
|
||||
void HandleUI(void)
|
||||
{
|
||||
switch (user_io_core_type())
|
||||
@@ -724,6 +764,7 @@ void HandleUI(void)
|
||||
static char drive_num = 0;
|
||||
static char flag;
|
||||
static int cr = 0;
|
||||
static uint32_t cheatsub = 0;
|
||||
|
||||
static char cp_MenuCancel;
|
||||
|
||||
@@ -768,6 +809,13 @@ void HandleUI(void)
|
||||
}
|
||||
break;
|
||||
|
||||
case KEY_F10:
|
||||
if (user_io_osd_is_visible())
|
||||
{
|
||||
//menustate = MENU_WMPAIR;
|
||||
}
|
||||
break;
|
||||
|
||||
// Within the menu the esc key acts as the menu key. problem:
|
||||
// if the menu is left with a press of ESC, then the follwing
|
||||
// break code for the ESC key when the key is released will
|
||||
@@ -932,42 +980,53 @@ void HandleUI(void)
|
||||
case MENU_ARCHIE_MAIN1:
|
||||
OsdSetTitle(user_io_get_core_name(), OSD_ARROW_RIGHT | OSD_ARROW_LEFT);
|
||||
|
||||
menumask = 0xff;
|
||||
OsdWrite(0, "", 0, 0);
|
||||
m = 0;
|
||||
menumask = 0x3ff;
|
||||
OsdWrite(m++);
|
||||
|
||||
strcpy(s, " Floppy 0: ");
|
||||
strncat(s, get_image_name(0) ? get_image_name(0) : "* no disk *",27);
|
||||
OsdWrite(1, s, menusub == 0, 0);
|
||||
OsdWrite(m++, s, menusub == 0);
|
||||
|
||||
strcpy(s, " Floppy 1: ");
|
||||
strncat(s, get_image_name(1) ? get_image_name(1) : "* no disk *", 27);
|
||||
OsdWrite(2, s, menusub == 1, 0);
|
||||
OsdWrite(m++, s, menusub == 1);
|
||||
|
||||
OsdWrite(3, "", 0, 0);
|
||||
OsdWrite(m++);
|
||||
|
||||
strcpy(s, " OS ROM: ");
|
||||
strcat(s, archie_get_rom_name());
|
||||
OsdWrite(4, s, menusub == 2, 0);
|
||||
OsdWrite(m++, s, menusub == 2);
|
||||
|
||||
OsdWrite(5, "", 0, 0);
|
||||
OsdWrite(m++);
|
||||
|
||||
strcpy(s, " Aspect ratio: ");
|
||||
strcat(s, archie_get_ar() ? "16:9" : "4:3");
|
||||
OsdWrite(6, s, menusub == 3, 0);
|
||||
OsdWrite(m++, s, menusub == 3);
|
||||
|
||||
strcpy(s, " Refresh rate: ");
|
||||
strcat(s, archie_get_60() ? "Variable" : "60Hz");
|
||||
OsdWrite(m++, s, menusub == 4);
|
||||
|
||||
OsdWrite(m++);
|
||||
|
||||
OsdWrite(7, "", 0, 0);
|
||||
sprintf(s, " Stereo mix: %s", config_stereo_msg[archie_get_amix()]);
|
||||
OsdWrite(8, s, menusub == 4, 0);
|
||||
OsdWrite(m++, s, menusub == 5);
|
||||
|
||||
strcpy(s, " 25MHz audio fix: ");
|
||||
strcat(s, archie_get_afix() ? "Enable" : "Disable");
|
||||
OsdWrite(m++, s, menusub == 6);
|
||||
|
||||
OsdWrite(m++);
|
||||
|
||||
OsdWrite(9, "", 0, 0);
|
||||
sprintf(s, " Swap joysticks: %s", user_io_get_joyswap() ? "Yes" : "No");
|
||||
OsdWrite(10, s, menusub == 5, 0);
|
||||
OsdWrite(m++, s, menusub == 7);
|
||||
sprintf(s, " Swap mouse btn 2/3: %s", archie_get_mswap() ? "Yes" : "No");
|
||||
OsdWrite(11, s, menusub == 6, 0);
|
||||
OsdWrite(m++, s, menusub == 8);
|
||||
|
||||
for (int i = 12; i<15; i++) OsdWrite(i, "", 0, 0);
|
||||
while(m<15) OsdWrite(m++);
|
||||
|
||||
OsdWrite(15, STD_EXIT, menusub == 7, 0);
|
||||
OsdWrite(15, STD_EXIT, menusub == 9, 0);
|
||||
menustate = MENU_ARCHIE_MAIN2;
|
||||
parentstate = MENU_ARCHIE_MAIN1;
|
||||
|
||||
@@ -999,21 +1058,31 @@ void HandleUI(void)
|
||||
break;
|
||||
|
||||
case 4:
|
||||
archie_set_amix(archie_get_amix()+1);
|
||||
archie_set_60(!archie_get_60());
|
||||
menustate = MENU_ARCHIE_MAIN1;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
user_io_set_joyswap(!user_io_get_joyswap());
|
||||
archie_set_amix(archie_get_amix()+1);
|
||||
menustate = MENU_ARCHIE_MAIN1;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
archie_set_afix(!archie_get_afix());
|
||||
menustate = MENU_ARCHIE_MAIN1;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
user_io_set_joyswap(!user_io_get_joyswap());
|
||||
menustate = MENU_ARCHIE_MAIN1;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
archie_set_mswap(!archie_get_mswap());
|
||||
menustate = MENU_ARCHIE_MAIN1;
|
||||
break;
|
||||
|
||||
case 7: // Exit
|
||||
case 9: // Exit
|
||||
menustate = MENU_NONE1;
|
||||
break;
|
||||
}
|
||||
@@ -1095,6 +1164,27 @@ void HandleUI(void)
|
||||
selentry++;
|
||||
}
|
||||
|
||||
// check for 'C'heats
|
||||
if (p && (p[0] == 'C'))
|
||||
{
|
||||
substrcpy(s, p, 1);
|
||||
if (strlen(s))
|
||||
{
|
||||
strcpy(s, " ");
|
||||
substrcpy(s + 1, p, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(s, " Cheats");
|
||||
}
|
||||
MenuWrite(entry, s, menusub == selentry, !cheats_available());
|
||||
|
||||
// add bit in menu mask
|
||||
menumask = (menumask << 1) | 1;
|
||||
entry++;
|
||||
selentry++;
|
||||
}
|
||||
|
||||
// check for 'T'oggle and 'R'eset (toggle and then close menu) strings
|
||||
if (p && ((p[0] == 'T') || (p[0] == 'R')))
|
||||
{
|
||||
@@ -1241,7 +1331,13 @@ void HandleUI(void)
|
||||
entry++;
|
||||
}
|
||||
|
||||
if (p[0] == 'F')
|
||||
if (p[0] == 'C' && cheats_available())
|
||||
{
|
||||
menustate = MENU_CHEATS1;
|
||||
cheatsub = menusub;
|
||||
menusub = 0;
|
||||
}
|
||||
else if (p[0] == 'F')
|
||||
{
|
||||
opensave = (p[1] == 'S');
|
||||
substrcpy(ext, p, 1);
|
||||
@@ -1298,7 +1394,6 @@ void HandleUI(void)
|
||||
menustate = MENU_8BIT_MAIN1;
|
||||
if (p[0] == 'R') menustate = MENU_NONE1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1317,6 +1412,7 @@ void HandleUI(void)
|
||||
case MENU_8BIT_MAIN_FILE_SELECTED:
|
||||
printf("File selected: %s\n", SelectedPath);
|
||||
user_io_file_tx(SelectedPath, user_io_ext_idx(SelectedPath, fs_pFileExt) << 6 | (menusub + 1), opensave);
|
||||
cheats_init(SelectedPath);
|
||||
menustate = MENU_NONE1;
|
||||
break;
|
||||
|
||||
@@ -1445,6 +1541,7 @@ void HandleUI(void)
|
||||
start_map_setting(joy_bcount ? joy_bcount+4 : 8);
|
||||
menustate = MENU_JOYDIGMAP;
|
||||
menusub = 0;
|
||||
joymap_first = 1;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
@@ -1750,7 +1847,7 @@ void HandleUI(void)
|
||||
|
||||
case MENU_JOYDIGMAP:
|
||||
helptext = 0;
|
||||
menumask = 0;
|
||||
menumask = 1;
|
||||
OsdSetTitle("Define buttons", 0);
|
||||
menustate = MENU_JOYDIGMAP1;
|
||||
parentstate = MENU_JOYDIGMAP;
|
||||
@@ -1758,11 +1855,6 @@ void HandleUI(void)
|
||||
OsdWrite(7, " Esc \x16 Cancel");
|
||||
OsdWrite(8, " Enter \x16 Finish");
|
||||
OsdWrite(9, " Space \x16 Skip");
|
||||
if (!is_menu_core())
|
||||
{
|
||||
OsdWrite(13, " You may define 2 sets of");
|
||||
OsdWrite(14, " buttons on the same gamepad");
|
||||
}
|
||||
break;
|
||||
|
||||
case MENU_JOYDIGMAP1:
|
||||
@@ -1772,6 +1864,7 @@ void HandleUI(void)
|
||||
OsdWrite(3);
|
||||
OsdWrite(4, " Clearing");
|
||||
OsdWrite(5);
|
||||
joymap_first = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1789,7 +1882,7 @@ void HandleUI(void)
|
||||
p = joy_bnames[get_map_button() - 4];
|
||||
if (is_menu_core())
|
||||
{
|
||||
if (get_map_type()) joy_bcount = 17;
|
||||
if (get_map_type()) joy_bcount = 15;
|
||||
if (get_map_button() == 16) p = joy_button_map[8 + get_map_type()];
|
||||
}
|
||||
}
|
||||
@@ -1844,7 +1937,13 @@ void HandleUI(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (select || menu || get_map_button() >= (joy_bcount ? joy_bcount + 4 : 8))
|
||||
if (!is_menu_core() && (get_map_button() >= (joy_bcount ? joy_bcount + 4 : 8) || (select & get_map_vid() & get_map_pid())) && joymap_first && get_map_type())
|
||||
{
|
||||
finish_map_setting(0);
|
||||
menustate = MENU_JOYDIGMAP3;
|
||||
menusub = 0;
|
||||
}
|
||||
else if (select || menu || get_map_button() >= (joy_bcount ? joy_bcount + 4 : 8))
|
||||
{
|
||||
finish_map_setting(menu);
|
||||
if (is_menu_core())
|
||||
@@ -1869,6 +1968,44 @@ void HandleUI(void)
|
||||
}
|
||||
break;
|
||||
|
||||
case MENU_JOYDIGMAP3:
|
||||
for (int i = 0; i < OsdGetSize(); i++) OsdWrite(i);
|
||||
m = 6;
|
||||
menumask = 3;
|
||||
OsdWrite(m++, " Do you want to setup");
|
||||
OsdWrite(m++, " alternative buttons?");
|
||||
OsdWrite(m++, " No", menusub == 0);
|
||||
OsdWrite(m++, " Yes", menusub == 1);
|
||||
parentstate = menustate;
|
||||
menustate = MENU_JOYDIGMAP4;
|
||||
break;
|
||||
|
||||
case MENU_JOYDIGMAP4:
|
||||
if (menu)
|
||||
{
|
||||
menustate = MENU_8BIT_SYSTEM1;
|
||||
menusub = 1;
|
||||
break;
|
||||
}
|
||||
else if (select)
|
||||
{
|
||||
switch (menusub)
|
||||
{
|
||||
case 0:
|
||||
menustate = MENU_8BIT_SYSTEM1;
|
||||
menusub = 1;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
start_map_setting(joy_bcount ? joy_bcount + 4 : 8, 1);
|
||||
menustate = MENU_JOYDIGMAP;
|
||||
menusub = 0;
|
||||
joymap_first = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MENU_JOYKBDMAP:
|
||||
helptext = 0;
|
||||
menumask = 1;
|
||||
@@ -1947,7 +2084,7 @@ void HandleUI(void)
|
||||
OsdDrawLogo(3);
|
||||
OsdDrawLogo(4);
|
||||
|
||||
sprintf(s, " HPS s/w v%s", version + 5);
|
||||
sprintf(s, " MiSTer v%s", version + 5);
|
||||
OsdWrite(10, s, 0, 0, 1);
|
||||
|
||||
s[0] = 0;
|
||||
@@ -2794,6 +2931,73 @@ void HandleUI(void)
|
||||
|
||||
break;
|
||||
|
||||
/******************************************************************/
|
||||
/* cheats menu */
|
||||
/******************************************************************/
|
||||
case MENU_CHEATS1:
|
||||
helptext = helptexts[HELPTEXT_NONE];
|
||||
sprintf(s, "Cheats (%d)", cheats_loaded());
|
||||
OsdSetTitle(s);
|
||||
cheats_print();
|
||||
menustate = MENU_CHEATS2;
|
||||
parentstate = menustate;
|
||||
break;
|
||||
|
||||
case MENU_CHEATS2:
|
||||
menumask = 0;
|
||||
|
||||
if (menu)
|
||||
{
|
||||
menustate = MENU_8BIT_MAIN1;
|
||||
menusub = cheatsub;
|
||||
break;
|
||||
}
|
||||
|
||||
cheats_scroll_name();
|
||||
|
||||
if (c == KEY_HOME)
|
||||
{
|
||||
cheats_scan(SCANF_INIT);
|
||||
menustate = MENU_CHEATS1;
|
||||
}
|
||||
|
||||
if (c == KEY_END)
|
||||
{
|
||||
cheats_scan(SCANF_END);
|
||||
menustate = MENU_CHEATS1;
|
||||
}
|
||||
|
||||
if ((c == KEY_PAGEUP) || (c == KEY_LEFT))
|
||||
{
|
||||
cheats_scan(SCANF_PREV_PAGE);
|
||||
menustate = MENU_CHEATS1;
|
||||
}
|
||||
|
||||
if ((c == KEY_PAGEDOWN) || (c == KEY_RIGHT))
|
||||
{
|
||||
cheats_scan(SCANF_NEXT_PAGE);
|
||||
menustate = MENU_CHEATS1;
|
||||
}
|
||||
|
||||
if (down) // scroll down one entry
|
||||
{
|
||||
cheats_scan(SCANF_NEXT);
|
||||
menustate = MENU_CHEATS1;
|
||||
}
|
||||
|
||||
if (up) // scroll up one entry
|
||||
{
|
||||
cheats_scan(SCANF_PREV);
|
||||
menustate = MENU_CHEATS1;
|
||||
}
|
||||
|
||||
if (select)
|
||||
{
|
||||
cheats_toggle();
|
||||
menustate = MENU_CHEATS1;
|
||||
}
|
||||
break;
|
||||
|
||||
/******************************************************************/
|
||||
/* reset menu */
|
||||
/******************************************************************/
|
||||
@@ -3421,7 +3625,17 @@ void HandleUI(void)
|
||||
|
||||
OsdSetTitle("System Settings", 0);
|
||||
OsdWrite(0, "", 0, 0);
|
||||
sprintf(s, " HPS s/w v%s", version + 5);
|
||||
sprintf(s, " MiSTer v%s", version + 5);
|
||||
{
|
||||
char str[8] = {};
|
||||
FILE *f = fopen("/MiSTer.version", "r");
|
||||
if (f)
|
||||
{
|
||||
if (fread(str, 6, 1, f)) sprintf(s, " MiSTer v%s, OS v%s", version + 5, str);
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
|
||||
OsdWrite(1, s, 0, 0);
|
||||
|
||||
{
|
||||
@@ -3497,26 +3711,90 @@ void HandleUI(void)
|
||||
strcpy(joy_bnames[1], "Btn 2 (ESC/Back)");
|
||||
strcpy(joy_bnames[2], "Btn 3 (Backspace)");
|
||||
strcpy(joy_bnames[3], "Btn 4");
|
||||
strcpy(joy_bnames[4], "RIGHT (Alt/Mouse)");
|
||||
strcpy(joy_bnames[5], "LEFT (Alt/Mouse)");
|
||||
strcpy(joy_bnames[6], "DOWN (Alt/Mouse)");
|
||||
strcpy(joy_bnames[7], "UP (Alt/Mouse)");
|
||||
strcpy(joy_bnames[4], "Mouse Move RIGHT");
|
||||
strcpy(joy_bnames[5], "Mouse Move LEFT");
|
||||
strcpy(joy_bnames[6], "Mouse Move DOWN");
|
||||
strcpy(joy_bnames[7], "Mouse Move UP");
|
||||
strcpy(joy_bnames[8], "Mouse Left Btn");
|
||||
strcpy(joy_bnames[9], "Mouse Right Btn");
|
||||
strcpy(joy_bnames[10], "Mouse Middle Btn");
|
||||
strcpy(joy_bnames[11], "Mouse Emu/Sniper");
|
||||
start_map_setting(21);
|
||||
start_map_setting(19);
|
||||
menustate = MENU_JOYDIGMAP;
|
||||
menusub = 0;
|
||||
break;
|
||||
case 3:
|
||||
SelectFile("SH", SCANO_DIR, MENU_SCRIPTS, MENU_FIRMWARE1);
|
||||
menustate = MENU_SCRIPTS_PRE;
|
||||
menusub = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
printSysInfo();
|
||||
break;
|
||||
|
||||
case MENU_WMPAIR:
|
||||
{
|
||||
OsdSetTitle("Wiimote", 0);
|
||||
int res = toggle_wminput();
|
||||
menu_timer = GetTimer(2000);
|
||||
for (int i = 0; i < OsdGetSize(); i++) OsdWrite(i);
|
||||
if (res < 0) OsdWrite(7, " Cannot enable Wiimote");
|
||||
else if (res == 0) OsdWrite(7, " Wiimote disabled");
|
||||
else
|
||||
{
|
||||
OsdWrite(7, " Wiimote enabled");
|
||||
OsdWrite(9, " Press 1+2 to connect");
|
||||
menu_timer = GetTimer(3000);
|
||||
}
|
||||
menustate = MENU_WMPAIR1;
|
||||
}
|
||||
//fall through
|
||||
|
||||
case MENU_WMPAIR1:
|
||||
if (CheckTimer(menu_timer)) menustate = MENU_NONE1;
|
||||
break;
|
||||
|
||||
case MENU_SCRIPTS_PRE:
|
||||
OsdSetTitle("Warning!!!", 0);
|
||||
helptext = 0;
|
||||
menumask = 3;
|
||||
m = 0;
|
||||
OsdWrite(m++);
|
||||
OsdWrite(m++, " Attention:");
|
||||
OsdWrite(m++, " This is dangerous operation!");
|
||||
OsdWrite(m++);
|
||||
OsdWrite(m++, " Script has control over the");
|
||||
OsdWrite(m++, " whole system and may damage");
|
||||
OsdWrite(m++, " the files or settings, then");
|
||||
OsdWrite(m++, " MiSTer won't boot, so you");
|
||||
OsdWrite(m++, " will have to re-format the");
|
||||
OsdWrite(m++, " SD card and fill with files");
|
||||
OsdWrite(m++, " in order to use it again.");
|
||||
OsdWrite(m++);
|
||||
OsdWrite(m++);
|
||||
OsdWrite(m++, " Do you want to continue?");
|
||||
OsdWrite(m++, " No", menusub == 0);
|
||||
OsdWrite(m++, " Yes", menusub == 1);
|
||||
menustate = MENU_SCRIPTS_PRE1;
|
||||
parentstate = MENU_SCRIPTS_PRE;
|
||||
break;
|
||||
|
||||
case MENU_SCRIPTS_PRE1:
|
||||
if (menu) menustate = MENU_FIRMWARE1;
|
||||
else if (select)
|
||||
{
|
||||
switch (menusub)
|
||||
{
|
||||
case 0:
|
||||
menustate = MENU_FIRMWARE1;
|
||||
break;
|
||||
case 1:
|
||||
SelectFile("SH", SCANO_DIR, MENU_SCRIPTS, MENU_FIRMWARE1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MENU_BTPAIR:
|
||||
OsdSetSize(16);
|
||||
OsdEnable(DISABLE_KEYBOARD);
|
||||
@@ -3750,6 +4028,7 @@ void open_joystick_setup()
|
||||
OsdEnable(DISABLE_KEYBOARD);
|
||||
start_map_setting(joy_bcount ? joy_bcount + 4 : 8);
|
||||
menustate = MENU_JOYDIGMAP;
|
||||
joymap_first = 1;
|
||||
}
|
||||
|
||||
void ScrollLongName(void)
|
||||
@@ -3786,7 +4065,7 @@ void ScrollLongName(void)
|
||||
if (flist_SelectedItem()->d_type == DT_DIR)
|
||||
max_len = 25; // number of directory name characters to display
|
||||
|
||||
ScrollText(flist_iSelectedEntry()-flist_iFirstEntry(), flist_SelectedItem()->d_name, 2, len, max_len, 1);
|
||||
ScrollText(flist_iSelectedEntry()-flist_iFirstEntry(), flist_SelectedItem()->d_name, 0, len, max_len, 1);
|
||||
}
|
||||
|
||||
void PrintFileName(char *name, int row, int maxinv)
|
||||
|
||||
51
osd.cpp
51
osd.cpp
@@ -397,7 +397,7 @@ void OsdDrawLogo(int row)
|
||||
}
|
||||
|
||||
// write a null-terminated string <s> to the OSD buffer starting at line <n>
|
||||
void OSD_PrintText(unsigned char line, const char *text, unsigned long start, unsigned long width, unsigned long offset, unsigned char invert)
|
||||
void OSD_PrintText(unsigned char line, const char *hdr, const char *text, unsigned long start, unsigned long width, unsigned long offset, unsigned char invert)
|
||||
{
|
||||
// line : OSD line number (0-7)
|
||||
// text : pointer to null-terminated string
|
||||
@@ -419,45 +419,53 @@ void OSD_PrintText(unsigned char line, const char *text, unsigned long start, un
|
||||
invert = 0xff;
|
||||
|
||||
p = &titlebuffer[(osd_size - 1 - line) * 8];
|
||||
if (start>2) {
|
||||
if (start>2)
|
||||
{
|
||||
spi16(0xffff);
|
||||
start -= 2;
|
||||
}
|
||||
|
||||
i = start>16 ? 16 : start;
|
||||
for (j = 0; j<(i / 2); ++j)
|
||||
spi_n(255 ^ *p++, 2);
|
||||
for (j = 0; j<(i / 2); ++j) spi_n(255 ^ *p++, 2);
|
||||
|
||||
if (i & 1)
|
||||
spi8(255 ^ *p);
|
||||
if (i & 1) spi8(255 ^ *p);
|
||||
start -= i;
|
||||
|
||||
if (start>2) {
|
||||
if (start>2)
|
||||
{
|
||||
spi16(0xffff);
|
||||
start -= 2;
|
||||
}
|
||||
|
||||
while (start--)
|
||||
spi8(0x00);
|
||||
while (start--) spi8(0x00);
|
||||
|
||||
if (offset) {
|
||||
while(*hdr)
|
||||
{
|
||||
width -= 8;
|
||||
p = charfont[(uint)(*hdr++)];
|
||||
for (int i=0; i < 8; i++) spi8(*p++^invert);
|
||||
}
|
||||
|
||||
if (offset)
|
||||
{
|
||||
width -= 8 - offset;
|
||||
p = &charfont[(uint)(*text++)][offset];
|
||||
for (; offset < 8; offset++)
|
||||
spi8(*p++^invert);
|
||||
}
|
||||
|
||||
while (width > 8) {
|
||||
while (width > 8)
|
||||
{
|
||||
unsigned char b;
|
||||
p = &charfont[(uint)(*text++)][0];
|
||||
for (b = 0; b<8; b++) spi8(*p++^invert);
|
||||
width -= 8;
|
||||
}
|
||||
|
||||
if (width) {
|
||||
if (width)
|
||||
{
|
||||
p = &charfont[(uint)(*text++)][0];
|
||||
while (width--)
|
||||
spi8(*p++^invert);
|
||||
while (width--) spi8(*p++^invert);
|
||||
}
|
||||
|
||||
DisableOsd();
|
||||
@@ -640,12 +648,21 @@ void ScrollText(char n, const char *str, int off, int len, int max_len, unsigned
|
||||
|
||||
#define BLANKSPACE 10 // number of spaces between the end and start of repeated name
|
||||
|
||||
char s[40];
|
||||
char s[40], hdr[40];
|
||||
long offset;
|
||||
if (!max_len) max_len = 30;
|
||||
|
||||
if (str && str[0] && CheckTimer(scroll_timer)) // scroll if long name and timer delay elapsed
|
||||
{
|
||||
hdr[0] = 0;
|
||||
if (off)
|
||||
{
|
||||
strncpy(hdr, str, off);
|
||||
hdr[off] = 0;
|
||||
str += off;
|
||||
if (len > off) len -= off;
|
||||
}
|
||||
|
||||
scroll_timer = GetTimer(SCROLL_DELAY2); // reset scroll timer to repeat delay
|
||||
|
||||
scroll_offset++; // increase scroll position (1 pixel unit)
|
||||
@@ -653,7 +670,7 @@ void ScrollText(char n, const char *str, int off, int len, int max_len, unsigned
|
||||
|
||||
if (!len) len = strlen(str); // get name length
|
||||
|
||||
if (off+len > max_len) // scroll name if longer than display size
|
||||
if (off+2+len > max_len) // scroll name if longer than display size
|
||||
{
|
||||
// reset scroll position if it exceeds predefined maximum
|
||||
if (scroll_offset >= (uint)(len + BLANKSPACE) << 3) scroll_offset = 0;
|
||||
@@ -668,7 +685,7 @@ void ScrollText(char n, const char *str, int off, int len, int max_len, unsigned
|
||||
strncpy(s + len + BLANKSPACE, str, max_len - len - BLANKSPACE); // repeat the name after its end and predefined number of blank space
|
||||
}
|
||||
|
||||
OSD_PrintText(n, s, 22, (max_len - 1) << 3, (scroll_offset & 0x7), invert); // OSD print function with pixel precision
|
||||
OSD_PrintText(n, hdr, s, 22, (max_len - 1) << 3, (scroll_offset & 0x7), invert); // OSD print function with pixel precision
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BIN
releases/MiSTer_20190427
Normal file
BIN
releases/MiSTer_20190427
Normal file
Binary file not shown.
BIN
releases/MiSTer_20190501
Normal file
BIN
releases/MiSTer_20190501
Normal file
Binary file not shown.
@@ -84,17 +84,41 @@ int archie_get_ar()
|
||||
return config.system_ctrl & 1;
|
||||
}
|
||||
|
||||
static int mswap = 0;
|
||||
void archie_set_mswap(char i)
|
||||
{
|
||||
mswap = i;
|
||||
}
|
||||
|
||||
int archie_get_mswap()
|
||||
{
|
||||
return mswap;
|
||||
}
|
||||
|
||||
void archie_set_60(char i)
|
||||
{
|
||||
if (i) config.system_ctrl |= 0b1000;
|
||||
else config.system_ctrl &= ~0b1000;
|
||||
user_io_8bit_set_status((i ? -1 : 0), 0b10000);
|
||||
}
|
||||
|
||||
int archie_get_60()
|
||||
{
|
||||
return config.system_ctrl & 0b1000;
|
||||
}
|
||||
|
||||
void archie_set_afix(char i)
|
||||
{
|
||||
if (i) config.system_ctrl |= 0b10000;
|
||||
else config.system_ctrl &= ~0b10000;
|
||||
user_io_8bit_set_status((i ? -1 : 0), 0b100000);
|
||||
}
|
||||
|
||||
int archie_get_afix()
|
||||
{
|
||||
return config.system_ctrl & 0b10000;
|
||||
}
|
||||
|
||||
static int mswap = 0;
|
||||
void archie_set_mswap(char i)
|
||||
{
|
||||
mswap = i;
|
||||
}
|
||||
|
||||
int archie_get_mswap()
|
||||
{
|
||||
return mswap;
|
||||
}
|
||||
|
||||
void archie_set_amix(char i)
|
||||
{
|
||||
config.system_ctrl = (config.system_ctrl & ~0b110) | ((i & 3)<<1);
|
||||
@@ -190,6 +214,9 @@ void archie_init(void)
|
||||
|
||||
archie_set_ar(archie_get_ar());
|
||||
archie_set_amix(archie_get_amix());
|
||||
archie_set_60(archie_get_60());
|
||||
archie_set_afix(archie_get_afix());
|
||||
|
||||
|
||||
// upload rom file
|
||||
archie_set_rom(config.rom_img);
|
||||
@@ -381,27 +408,27 @@ void archie_poll(void)
|
||||
|
||||
// arm acks first byte
|
||||
case BACK:
|
||||
if (kbd_state != STATE_WAIT4ACK1) {
|
||||
archie_debugf("KBD unexpected BACK, resetting KBD");
|
||||
kbd_state = STATE_HRST;
|
||||
}
|
||||
else {
|
||||
#ifdef HOLD_OFF_TIME
|
||||
// wait some time before sending next byte
|
||||
archie_debugf("KBD starting hold off");
|
||||
kbd_state = STATE_HOLD_OFF;
|
||||
hold_off_timer = GetTimer(10);
|
||||
// wait some time before sending next byte
|
||||
archie_debugf("KBD starting hold off");
|
||||
kbd_state = STATE_HOLD_OFF;
|
||||
hold_off_timer = GetTimer(10);
|
||||
#else
|
||||
kbd_state = STATE_IDLE;
|
||||
archie_check_queue();
|
||||
kbd_state = STATE_IDLE;
|
||||
archie_check_queue();
|
||||
#endif
|
||||
}
|
||||
if (kbd_state != STATE_WAIT4ACK1) {
|
||||
archie_debugf("KBD unexpected BACK, resetting KBD");
|
||||
kbd_state = STATE_HRST;
|
||||
}
|
||||
else {
|
||||
#ifdef HOLD_OFF_TIME
|
||||
// wait some time before sending next byte
|
||||
archie_debugf("KBD starting hold off");
|
||||
kbd_state = STATE_HOLD_OFF;
|
||||
hold_off_timer = GetTimer(10);
|
||||
// wait some time before sending next byte
|
||||
archie_debugf("KBD starting hold off");
|
||||
kbd_state = STATE_HOLD_OFF;
|
||||
hold_off_timer = GetTimer(10);
|
||||
#else
|
||||
kbd_state = STATE_IDLE;
|
||||
archie_check_queue();
|
||||
kbd_state = STATE_IDLE;
|
||||
archie_check_queue();
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
// arm acks second byte
|
||||
|
||||
@@ -15,7 +15,11 @@ void archie_set_ar(char i);
|
||||
int archie_get_ar();
|
||||
void archie_set_amix(char i);
|
||||
int archie_get_amix();
|
||||
void archie_set_mswap(char i);
|
||||
int archie_get_mswap();
|
||||
void archie_set_mswap(char i);
|
||||
int archie_get_mswap();
|
||||
void archie_set_60(char i);
|
||||
int archie_get_60();
|
||||
void archie_set_afix(char i);
|
||||
int archie_get_afix();
|
||||
|
||||
#endif // ARCHIE_H
|
||||
|
||||
@@ -241,7 +241,7 @@ void user_io_set_scaler_coeff(char *name);
|
||||
void user_io_minimig_set_adjust(char n);
|
||||
char user_io_minimig_get_adjust();
|
||||
|
||||
#define HomeDir (is_minimig() ? "Amiga" : is_archie() ? "Archie" : user_io_get_core_name())
|
||||
#define HomeDir (is_minimig() ? "Amiga" : is_archie() ? "Archie" : is_menu_core() ? "Scripts" : user_io_get_core_name())
|
||||
|
||||
int GetUARTMode();
|
||||
int GetMidiLinkMode();
|
||||
|
||||
Reference in New Issue
Block a user