mirror of
https://github.com/ondra-novak/gates_of_skeldal.git
synced 2025-07-05 06:00:33 -04:00
more controller support and fix some crashes
This commit is contained in:
parent
3f946405b9
commit
0e251dcd05
19 changed files with 608 additions and 195 deletions
26
README.md
26
README.md
|
@ -44,6 +44,32 @@ A script error in the White Tower map in the puzzle located on the top floor of
|
|||
|
||||
This fix will only work with the new code. (It will not work in earlier releases of the game, i.e. in the DOS, Windows, Android and iOS versions). The reason is that a new scripting action has been introduced to enable this fix, which will ensure the correct evaluation of the puzzle
|
||||
|
||||
## Controller support
|
||||
|
||||
Controller support is experimental. Tested on PS4 controller connected on bluetooth.
|
||||
Controller can be configured in INI file. If it is connected when program starts,
|
||||
it is detected and can be used.
|
||||
|
||||
Following mapping is defined by default (you can change it in INI)
|
||||
Left stick - walking turning, strafing with meta, list selection
|
||||
Right stick - cursor movement
|
||||
Key X - cursor action (left mouse click)
|
||||
Key [] - ENTER/RETURN, accept selection, start battle, finish move
|
||||
Key O - cancel action, walk by cursor, (right mouse click)
|
||||
Key /\ - SPACE, wall action, fast trade, next PC in battle, accept selection
|
||||
Key Ps - settings
|
||||
Key Share - SAVE
|
||||
Key Options - LOAD
|
||||
Key on right stick - Split group
|
||||
Key R1 - mod/meta key
|
||||
Key L1 - with meta - sleep, without - backspace
|
||||
Key DPAD UP - map, with meta cast spell
|
||||
Key DPAD DOWN - merge group
|
||||
Key DPAD left - move left
|
||||
KEY DPAD right - move right
|
||||
Key X,[],O,/\ with meta - actions during battle
|
||||
|
||||
|
||||
## Goals
|
||||
|
||||
1. to rewrite all Intel 386 depend code to independed variant.
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <libs/pcx.h>
|
||||
#include "globals.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#define AUTOMAP_BACK RGB555(8,4,0)
|
||||
#define AUTOMAP_VODA RGB555(0,15,31)
|
||||
|
@ -141,11 +142,15 @@ void save_text_to_map(int x,int y,int depth,char *text)
|
|||
{
|
||||
char c[512],*d;
|
||||
if (text[0]==0) return;
|
||||
d = text;
|
||||
while (*d && isspace(*d)) ++d;
|
||||
if (!*d) return;
|
||||
memset(c,1,sizeof(c));
|
||||
strncpy(c+12,text,sizeof(c)-13);
|
||||
c[511] = 0;
|
||||
if (texty_v_mape==NULL) texty_v_mape=create_list(8);
|
||||
d=texty_v_mape[str_add(&texty_v_mape,c)];
|
||||
int id = str_add(&texty_v_mape,c);
|
||||
d=texty_v_mape[id];
|
||||
x=(x-320)+map_xr;
|
||||
y=(y-197)+map_yr;
|
||||
memcpy(d,&x,4);memcpy(d+4,&y,4);memcpy(d+8,&depth,4);
|
||||
|
|
|
@ -110,41 +110,14 @@ void wire_dialog_drw(void);
|
|||
|
||||
static void (*old_wire_proc)(void) = NULL;
|
||||
|
||||
void wire_dialog_drw_restore(void) {
|
||||
wire_proc = old_wire_proc ;
|
||||
wire_dialog_drw();
|
||||
}
|
||||
|
||||
static char dlg_konec(int id,int xa,int ya,int xr,int yr) {
|
||||
old_wire_proc = wire_proc;
|
||||
wire_proc = wire_dialog_drw_restore;
|
||||
konec(id,xa,ya,xr,yr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char dlg_game_setup(int id,int xa,int ya,int xr,int yr) {
|
||||
old_wire_proc = wire_proc;
|
||||
wire_proc = wire_dialog_drw_restore;
|
||||
game_setup(id,xa,ya,xr,yr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static char dlg_clk_saveload(int id,int xa,int ya,int xr,int yr) {
|
||||
old_wire_proc = wire_proc;
|
||||
wire_proc = wire_dialog_drw_restore;
|
||||
clk_saveload(id,xa,ya,xr,yr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define CLK_DIALOG 5
|
||||
static T_CLK_MAP clk_dialog[CLK_DIALOG]=
|
||||
{
|
||||
{0,TEXT_X,TEXT_Y,TEXT_X+TEXT_XS,TEXT_Y+TEXT_YS,case_click,3,H_MS_DEFAULT},
|
||||
{-1,30,0,85,14,dlg_konec,2,H_MS_DEFAULT},
|
||||
{-1,87,0,142,14,dlg_game_setup,2,H_MS_DEFAULT},
|
||||
{0,207,0,265,14,dlg_clk_saveload,2,H_MS_DEFAULT},
|
||||
{-1,30,0,85,14,konec,2,H_MS_DEFAULT},
|
||||
{-1,87,0,142,14,game_setup,2,H_MS_DEFAULT},
|
||||
{0,207,0,265,14,clk_saveload,2,H_MS_DEFAULT},
|
||||
{0,0,0,639,479,empty_clk,0xff,H_MS_DEFAULT},
|
||||
};
|
||||
|
||||
|
@ -719,6 +692,7 @@ static void dialog_cont()
|
|||
save_jump=vol_n[(uint8_t)vyb_volba];
|
||||
remove_all_cases();
|
||||
echo(" ");
|
||||
wire_proc = old_wire_proc;
|
||||
his_line=get_last_his_line();
|
||||
if (halt_flag) goto_paragraph(save_jump);
|
||||
schovej_mysku();
|
||||
|
@ -736,7 +710,7 @@ static void key_check(EVENT_MSG *msg,void **unused)
|
|||
int c = va_arg(msg->data, int) >> 8;
|
||||
char redraw = 0;
|
||||
switch (c) {
|
||||
case 1:dlg_konec(0,0,0,0,0);break;
|
||||
case 1:konec(0,0,0,0,0);break;
|
||||
case 17:
|
||||
case 'H':if (vyb_volba==0) his_line-=(his_line>0);
|
||||
else vyb_volba--;
|
||||
|
@ -749,6 +723,8 @@ static void key_check(EVENT_MSG *msg,void **unused)
|
|||
break;
|
||||
case 28:
|
||||
case 57:dialog_cont();break;
|
||||
case 61:clk_saveload(0, 0, 0, 0, 0);break;
|
||||
case 59:game_setup(0,0,0,0,0);break;
|
||||
}
|
||||
if (redraw) {
|
||||
schovej_mysku();
|
||||
|
@ -794,7 +770,7 @@ void unwire_dialog(void)
|
|||
{
|
||||
send_message(E_DONE,E_KEYBOARD,key_check);
|
||||
disable_click_map();
|
||||
// wire_proc=wire_dialog_drw;
|
||||
|
||||
}
|
||||
|
||||
void wire_dialog()
|
||||
|
@ -934,7 +910,9 @@ void dialog_select(char halt)
|
|||
unwire_proc();
|
||||
draw_all();
|
||||
ukaz_mysku();
|
||||
old_wire_proc = wire_proc;
|
||||
wire_dialog();
|
||||
wire_proc = wire_dialog_drw;
|
||||
halt_flag=halt && (pocet_voleb>0);
|
||||
}
|
||||
|
||||
|
|
|
@ -1651,7 +1651,22 @@ static void saveload_keyboard(EVENT_MSG *msg,void **_)
|
|||
} else {
|
||||
load_save_pos_ingame(last_select);break;
|
||||
}
|
||||
}break;
|
||||
case 60:if (force_save) {
|
||||
unwire_proc();wire_proc();
|
||||
} else {
|
||||
clk_saveload(1, 0, 0, 0, 0);
|
||||
}
|
||||
break;
|
||||
case 61:if (!force_save) {
|
||||
unwire_proc();wire_proc();
|
||||
} else {
|
||||
clk_saveload(0, 0, 0, 0, 0);
|
||||
}
|
||||
break;
|
||||
case 59:game_setup(0,0,0,0,0);break;
|
||||
case 64:go_book(0, 0, 0, 0, 0);break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -809,6 +809,7 @@ char clk_touch(int id,int xa,int ya,int xr,int yr);
|
|||
char go_book(int id,int xa,int ya,int xr,int yr);
|
||||
char clk_saveload(int id,int xa,int ya,int xr,int yr);
|
||||
char clk_sleep(int id,int xa,int ya,int xr,int yr);
|
||||
char spell_casting(int id,int xa,int ya,int xr,int yr);
|
||||
|
||||
|
||||
//inventory viewer - items
|
||||
|
|
|
@ -246,6 +246,18 @@ void open_message_win(int pocet_textu,char **texts)
|
|||
|
||||
static char default_action,cancel_action;
|
||||
|
||||
static void message_mouse(EVENT_MSG *msg,void **user_ptr) {
|
||||
if (msg->msg == E_MOUSE) {
|
||||
const MS_EVENT * msev = va_arg(msg->data, MS_EVENT *);
|
||||
if (msev->event_type & MS_EVENT_MOUSE_RPRESS) {
|
||||
goto_control(cancel_action);
|
||||
terminate_gui();
|
||||
msg->msg = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void message_keyboard(EVENT_MSG *msg,void **user_ptr)
|
||||
{
|
||||
char *c;
|
||||
|
@ -304,9 +316,11 @@ int message(int butts,char def,char canc,char *keys,...)
|
|||
}
|
||||
open_message_win(butts+1,texts);
|
||||
send_message(E_ADD,E_KEYBOARD,message_keyboard,keys);
|
||||
send_message(E_ADD,E_MOUSE,message_mouse);
|
||||
escape();
|
||||
id=o_aktual->id;
|
||||
id=o_aktual?o_aktual->id:0;
|
||||
send_message(E_DONE,E_KEYBOARD,message_keyboard,keys);
|
||||
send_message(E_DONE,E_MOUSE,message_mouse);
|
||||
close_current();
|
||||
restore_click_map(clksav,clksav2);
|
||||
return id;
|
||||
|
@ -1495,14 +1509,38 @@ static void smlouvat_enter(EVENT_MSG *msg,OBJREC *o)
|
|||
}
|
||||
}
|
||||
|
||||
static int add_number_cb(EVENT_MSG *msg, void *x) {
|
||||
o_aktual->call_event(msg, o_aktual);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void add_number() {
|
||||
if (o_aktual) {
|
||||
int n = o_aktual->id - 40;
|
||||
goto_control(10);
|
||||
send_message_to(add_number_cb,NULL, E_KEYBOARD, 'O'<<8);
|
||||
send_message_to(add_number_cb,NULL, E_KEYBOARD, n+48);
|
||||
|
||||
}
|
||||
}
|
||||
static void remove_number() {
|
||||
if (o_aktual) {
|
||||
goto_control(10);
|
||||
send_message_to(add_number_cb,NULL, E_KEYBOARD, 'O'<<8);
|
||||
send_message_to(add_number_cb,NULL, E_KEYBOARD, 8);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
THAGGLERESULT smlouvat_dlg(int cena,int puvod,int pocet,int posledni, int money,char mode)
|
||||
{
|
||||
char buffer[20];
|
||||
int ponuka;
|
||||
THAGGLERESULT res;
|
||||
char j = is_joystick_used();
|
||||
|
||||
set_font(H_FBOLD,RGB555(31,31,31));
|
||||
add_window(170,130,300,100,H_WINTXTR,3,20,20);
|
||||
add_window(170,130,300,100+j*20,H_WINTXTR,3,20,20);
|
||||
define(-1,10,15,1,1,0,label,texty[241]);
|
||||
define(-1,150,15,100,13,0,label,int2ascii(cena,buffer,10));
|
||||
set_font(H_FBOLD,MSG_COLOR1);
|
||||
|
@ -1511,6 +1549,14 @@ THAGGLERESULT smlouvat_dlg(int cena,int puvod,int pocet,int posledni, int money,
|
|||
on_control_event(smlouvat_enter);
|
||||
define(20,20,20,80,20,2,button,texty[239]);property(def_border(5,BAR_COLOR),NULL,NULL,BAR_COLOR);on_control_change(terminate_gui);
|
||||
define(30,110,20,80,20,2,button,texty[230]);property(def_border(5,BAR_COLOR),NULL,NULL,BAR_COLOR);on_control_change(terminate_gui);
|
||||
if (j) {
|
||||
char nstr[2] = "0";
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
nstr[0] = i+48;
|
||||
define(40+i, 10+i*24,50,22,20,0,button,nstr);property(def_border(0,BAR_COLOR),NULL,NULL,BAR_COLOR);on_control_change(add_number);
|
||||
}
|
||||
define(50, 20,50,20,20,1,button,"<-");property(def_border(0,BAR_COLOR),NULL,NULL,BAR_COLOR);on_control_change(remove_number);
|
||||
}
|
||||
{
|
||||
redraw_window();
|
||||
schovej_mysku();set_font(H_FBOLD,RGB555(31,31,31));
|
||||
|
|
11
game/inv.c
11
game/inv.c
|
@ -1546,7 +1546,7 @@ void inv_informuj()
|
|||
if (cur_shop->list[j].item == i-1) {
|
||||
int cena = cur_shop->list[j].cena;
|
||||
if (cena) {
|
||||
sprintf(c,"%s (%d)",glob_items[i-1].jmeno,cena+cur_shop->koef*cena/100);
|
||||
sprintf(c,"%s (%d)",glob_items[i-1].jmeno,cena-cur_shop->koef*cena/100);
|
||||
found_price = 1;
|
||||
break;
|
||||
}
|
||||
|
@ -1754,7 +1754,7 @@ void inv_item_info_box(EVENT_MSG *msg,void **data)
|
|||
if (cur_shop->list[j].item == i-1) {
|
||||
int cena = cur_shop->list[j].cena;
|
||||
if (cena) {
|
||||
sprintf(c,"%s (%d)",glob_items[i-1].jmeno,cena+cur_shop->koef*cena/100);
|
||||
sprintf(c,"%s (%d)",glob_items[i-1].jmeno,cena-cur_shop->koef*cena/100);
|
||||
found_price = 1;
|
||||
break;
|
||||
}
|
||||
|
@ -1778,8 +1778,7 @@ void inv_item_info_box(EVENT_MSG *msg,void **data)
|
|||
|
||||
void unwire_inv_mode(void)
|
||||
{
|
||||
send_message(E_DONE,E_KEYBOARD,inv_keyboard);
|
||||
send_message(E_DONE,E_MOUSE,inv_item_info_box);
|
||||
send_message(E_DONE,E_KEYBOARD,inv_keyboard); send_message(E_DONE,E_MOUSE,inv_item_info_box);
|
||||
build_all_players();
|
||||
}
|
||||
|
||||
|
@ -3033,6 +3032,10 @@ static void shop_keyboard_proc(EVENT_MSG *msg, void **_) {
|
|||
switch(c>>8) {
|
||||
case 1: _exit_shop(0,0,0,0,0);break;
|
||||
case 57: fast_trade_click();break;
|
||||
case 32:
|
||||
case 'M':shop_block_click(2,0,0,0,0);break;
|
||||
case 30:
|
||||
case 'K':shop_block_click(1,0,0,0,0);break;
|
||||
default:break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1955,13 +1955,15 @@ void game_keyboard(EVENT_MSG *msg,void **usr)
|
|||
case 1:konec(0,0,0,0,0);break;
|
||||
// case 25:GamePause();break;
|
||||
case 28:enforce_start_battle();break;
|
||||
case 60:clk_saveload(1, 0, 0, 0, 0);break;
|
||||
case 61:clk_saveload(0, 0, 0, 0, 0);break;
|
||||
case 59:game_setup(0,0,0,0,0);break;
|
||||
case 63:do_autosave();break;
|
||||
case 62:clk_sleep(0,0,0,0,0);break;
|
||||
case 64:go_book(0, 0, 0, 0, 0);break;
|
||||
case 65:spell_casting(0, 0, 0, 0, 0);break;
|
||||
case 45:
|
||||
case 82:group_all();break;
|
||||
case '<':if (!battle && GlobEvent(MAGLOB_CLICKSAVE,viewsector,viewdir))
|
||||
{unwire_proc();cancel_render=1;do_save_dialog();wire_proc();}break;
|
||||
case '=':unwire_proc();cancel_render=1;wire_save_load(0);break;
|
||||
case '>':game_setup(0,0,0,0,0);break;
|
||||
case 0x2E: if (get_control_key_state() && get_shift_key_state()) {
|
||||
console_show(!console_is_visible());
|
||||
}
|
||||
|
|
14
game/setup.c
14
game/setup.c
|
@ -77,16 +77,20 @@ static void change_turn(void)
|
|||
turn_speed((id-60)/10);
|
||||
}
|
||||
|
||||
char exit_setup(int id,int xa,int ya,int xr,int yr);
|
||||
static void unwire_setup(void);
|
||||
|
||||
static void setup_keyboard(EVENT_MSG *msg,void **_)
|
||||
{
|
||||
if (msg->msg == E_KEYBOARD)
|
||||
{
|
||||
char c= quit_request_as_escape(va_arg(msg->data, int));
|
||||
if (c==27)
|
||||
{
|
||||
unwire_proc();
|
||||
int c= quit_request_as_escape(va_arg(msg->data, int));
|
||||
switch(c>>8) {
|
||||
case 1:
|
||||
case 59: exit_setup(0, 0, 0,0,0); break;
|
||||
case 60:clk_saveload(1, 0, 0, 0, 0);break;
|
||||
case 61:clk_saveload(0, 0, 0, 0, 0);break;
|
||||
case 64:go_book(0, 0, 0, 0, 0);break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -112,7 +116,6 @@ static void unwire_setup(void)
|
|||
mix_back_sound(32768);
|
||||
close_current();
|
||||
send_message(E_DONE,E_KEYBOARD,setup_keyboard);
|
||||
wire_proc();
|
||||
cancel_render=1;
|
||||
SEND_LOG("(GAME) Setup closed");
|
||||
}
|
||||
|
@ -121,6 +124,7 @@ char exit_setup(int id,int xa,int ya,int xr,int yr)
|
|||
{
|
||||
id,xa,ya,xr,yr;
|
||||
unwire_setup();
|
||||
wire_proc();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -957,6 +957,7 @@ void init_skeldal(const INI_CONFIG *cfg)
|
|||
}
|
||||
showview = game_display_update_rect;
|
||||
game_display_set_icon(getWindowIcon(), getWindowIconSize());
|
||||
init_joystick(ini_section_open(cfg, "controller"));
|
||||
|
||||
general_engine_init();
|
||||
atexit(done_skeldal);
|
||||
|
|
|
@ -1494,7 +1494,7 @@ static void *runebar;
|
|||
static char *rune_name=NULL;
|
||||
static char *rune_info=NULL;
|
||||
|
||||
void display_power_bar(THE_TIMER *_);
|
||||
void display_power_bar(char);
|
||||
void display_rune_bar(THE_TIMER *_)
|
||||
{
|
||||
short coords[][2]={{3,26},{32,26},{61,26},{90,26},{18,64},{47,64},{76,64}};
|
||||
|
@ -1540,7 +1540,7 @@ void rune_bar_redrawing(THE_TIMER *_)
|
|||
{
|
||||
schovej_mysku();
|
||||
program_draw();
|
||||
display_power_bar(NULL);
|
||||
display_power_bar(0);
|
||||
ukaz_mysku();
|
||||
showview(0,0,0,0);
|
||||
}
|
||||
|
@ -1808,7 +1808,7 @@ void program_draw()
|
|||
x+=74;
|
||||
}
|
||||
} else {
|
||||
for(j=0;j<POCET_POSTAV;j++)
|
||||
for(j=0;j<POCET_POSTAV;j++) {
|
||||
if (postavy[i=group_sort[j]].used)
|
||||
{
|
||||
int y;
|
||||
|
@ -1816,6 +1816,7 @@ void program_draw()
|
|||
y=postavy[i].programovano*10;
|
||||
if (y>maxy) maxy=y;
|
||||
}
|
||||
}
|
||||
int m = 0;
|
||||
if (pgm_help || rune_name!=NULL) m=10*(rune_info?2:1);
|
||||
if (m > maxy) maxy = m;
|
||||
|
@ -1908,9 +1909,29 @@ static void souboje_dalsi()
|
|||
select_player=group_sort[i];
|
||||
j--;
|
||||
}
|
||||
while ((!postavy[select_player].used || !postavy[select_player].actions || (postavy[select_player].groupnum!=cd && j>6)) && j);
|
||||
while ((!postavy[select_player].used || postavy[select_player].inmaphash != current_map_hash || !postavy[select_player].actions || (postavy[select_player].groupnum!=cd && j>6)) && j);
|
||||
viewsector=postavy[select_player].sektor;
|
||||
viewdir=postavy[select_player].direction;
|
||||
cur_group=postavy[select_player].groupnum;
|
||||
}
|
||||
|
||||
static void souboje_dalsi_user() {
|
||||
int i,j=6,k;
|
||||
for(i=0;group_sort[i]!=select_player;i++);
|
||||
do
|
||||
{
|
||||
i++;
|
||||
if (i>=POCET_POSTAV) i=0;
|
||||
k=group_sort[i];
|
||||
j--;
|
||||
}
|
||||
while ((!postavy[k].used
|
||||
|| !postavy[k].lives
|
||||
|| postavy[k].inmaphash != current_map_hash) && j);
|
||||
select_player = k;
|
||||
viewsector=postavy[select_player].sektor;
|
||||
viewdir=postavy[select_player].direction;
|
||||
cur_group=postavy[select_player].groupnum;
|
||||
}
|
||||
|
||||
void souboje_vybrano(int d)
|
||||
|
@ -2079,19 +2100,7 @@ static void zahajit_kolo(char prekvapeni)
|
|||
send_message(E_KOUZLO_KOLO);
|
||||
}
|
||||
|
||||
char mask_click(int id,int xa,int ya,int xr,int yr)
|
||||
{
|
||||
char *c;
|
||||
int d;
|
||||
word *mask;
|
||||
|
||||
id;xa;ya;
|
||||
mask=(word *)ablock(H_BATTLE_MASK);
|
||||
c=(char *)mask+6+512;
|
||||
c+=yr*mask[0]+xr;
|
||||
d=*c;
|
||||
if (d)
|
||||
{
|
||||
static char add_pc_action(int d) {
|
||||
souboje_stisknout(d);
|
||||
switch(d)
|
||||
{
|
||||
|
@ -2130,6 +2139,22 @@ char mask_click(int id,int xa,int ya,int xr,int yr)
|
|||
break;
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
char mask_click(int id,int xa,int ya,int xr,int yr)
|
||||
{
|
||||
char *c;
|
||||
int d;
|
||||
word *mask;
|
||||
|
||||
id;xa;ya;
|
||||
mask=(word *)ablock(H_BATTLE_MASK);
|
||||
c=(char *)mask+6+512;
|
||||
c+=yr*mask[0]+xr;
|
||||
d=*c;
|
||||
if (d) {
|
||||
return add_pc_action(d);
|
||||
}
|
||||
bott_draw(1);
|
||||
return 1;
|
||||
|
@ -2190,13 +2215,22 @@ void programming_keyboard(EVENT_MSG *msg,void **unused)
|
|||
case 'M':souboje_turn(1);break;
|
||||
case 16:
|
||||
case 'K':souboje_turn(-1);break;
|
||||
case '=':unwire_proc();cancel_render=1;wire_save_load(0);break;
|
||||
case '>':game_setup(0,0,0,0,0);break;
|
||||
case 57:souboje_dalsi();bott_draw(1);break;
|
||||
case 15:
|
||||
case 61:clk_saveload(0, 0, 0, 0, 0);break;
|
||||
case 60:clk_saveload(1, 0, 0, 0, 0);break;
|
||||
case 64:go_book(1, 0, 0, 0, 0);break;
|
||||
case 65:add_pc_action(AC_MAGIC);break;
|
||||
case 66:add_pc_action(AC_ATTACK);break;
|
||||
case 67:add_pc_action(AC_MOVE);break;
|
||||
case 68:add_pc_action(AC_ARMOR);break;
|
||||
case 133:add_pc_action(AC_RUN);break;
|
||||
case 134:add_pc_action(AC_STAND);break;
|
||||
case 14:add_pc_action(AC_CANCEL);break;
|
||||
case 59:game_setup(0,0,0,0,0);break;
|
||||
case 57:souboje_dalsi_user();bott_draw(1);break;
|
||||
case 28:zahajit_kolo(0);
|
||||
souboje_stisknout(AC_START);
|
||||
break;
|
||||
case 15:
|
||||
case 50:
|
||||
if (GlobEvent(MAGLOB_BEFOREMAPOPEN,viewsector,viewdir))
|
||||
show_automap(1);
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "types.h"
|
||||
#include "event.h"
|
||||
#include "mouse.h"
|
||||
|
||||
typedef struct tms_basic_info
|
||||
{
|
||||
int mouse_event;
|
||||
|
@ -20,4 +21,5 @@ extern TMS_BASIC_INFO ms_basic_info;
|
|||
int lock_region (void *address, unsigned length);
|
||||
void keyboard(EVENT_MSG *msg,void *user_data);
|
||||
char ms_get_keycount(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -812,7 +812,7 @@ static void set_object_value(char redraw,OBJREC *o,const char *value)
|
|||
|
||||
static void set_object_value_bin(char redraw,OBJREC *o,const void *value, size_t sz)
|
||||
{
|
||||
size_t cpsz = MIN(o->datasize, sz);
|
||||
size_t cpsz = MIN((size_t)o->datasize, sz);
|
||||
if (memcmp(o->data,value,cpsz))
|
||||
{
|
||||
memcpy(o->data,value,cpsz);
|
||||
|
@ -875,7 +875,10 @@ void goto_control(int obj_id)
|
|||
{
|
||||
EVENT_MSG msg;
|
||||
if (send_lost()) return;
|
||||
o_aktual=find_object(waktual,obj_id);
|
||||
|
||||
OBJREC *x = find_object(waktual,obj_id);
|
||||
if (x == NULL) return;
|
||||
o_aktual=x;
|
||||
msg.msg=E_GET_FOCUS;
|
||||
o_aktual->on_event(&msg,o_aktual);
|
||||
o_aktual->call_event(&msg,o_aktual);
|
||||
|
@ -963,6 +966,7 @@ void background_runner(EVENT_MSG *msg,void **prog)
|
|||
*prog_ptr=NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
(*prog_ptr)();
|
||||
|
||||
msg->msg=-2;
|
||||
|
|
|
@ -130,6 +130,9 @@ int list_files(const char *directory, int type, LIST_FILES_CALLBACK cb, void *ct
|
|||
|
||||
#include "sdl/BGraph2.h"
|
||||
|
||||
void init_joystick(const INI_CONFIG_SECTION *section);
|
||||
char is_joystick_used();
|
||||
|
||||
#define WM_RELOADMAP (WM_APP+215)
|
||||
#define E_RELOADMAP 40
|
||||
|
||||
|
|
|
@ -39,3 +39,68 @@ void ShareCPU() {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void init_joystick(const INI_CONFIG_SECTION *section) {
|
||||
SDLContext::JoystickConfig cfg = {};
|
||||
cfg.buttons[0] = SDLContext::JoystickButton::lclick;
|
||||
cfg.buttons[1] = SDLContext::JoystickButton::rclick;
|
||||
cfg.buttons[2] = SDLContext::JoystickButton::enter;
|
||||
cfg.buttons[3] = SDLContext::JoystickButton::space;
|
||||
cfg.buttons[5] = SDLContext::JoystickButton::F1;
|
||||
cfg.buttons[4] = SDLContext::JoystickButton::F2;
|
||||
cfg.buttons_mod[4] = SDLContext::JoystickButton::F5;
|
||||
cfg.buttons[6] = SDLContext::JoystickButton::F3;
|
||||
cfg.buttons[8] = SDLContext::JoystickButton::ctrl_lclick;
|
||||
cfg.buttons[10] = SDLContext::JoystickButton::mod_key;
|
||||
cfg.buttons_mod[10] = SDLContext::JoystickButton::mod_key;
|
||||
cfg.buttons[11] = SDLContext::JoystickButton::map;
|
||||
cfg.buttons_mod[11] = SDLContext::JoystickButton::F6;
|
||||
cfg.buttons[12] = SDLContext::JoystickButton::merge;
|
||||
cfg.buttons[14] = SDLContext::JoystickButton::left;
|
||||
cfg.buttons[13] = SDLContext::JoystickButton::right;
|
||||
cfg.buttons[9] = SDLContext::JoystickButton::backspace;
|
||||
cfg.buttons_mod[5] = SDLContext::JoystickButton::escape;
|
||||
cfg.buttons_mod[9] = SDLContext::JoystickButton::F4;
|
||||
cfg.buttons_mod[12] = SDLContext::JoystickButton::F7;
|
||||
cfg.buttons_mod[0] = SDLContext::JoystickButton::F8;
|
||||
cfg.buttons_mod[1] = SDLContext::JoystickButton::F9;
|
||||
cfg.buttons_mod[2] = SDLContext::JoystickButton::F10;
|
||||
cfg.buttons_mod[3] = SDLContext::JoystickButton::F11;
|
||||
cfg.buttons_mod[14] = SDLContext::JoystickButton::F12;
|
||||
cfg.buttons_mod[13] = SDLContext::JoystickButton::backspace;
|
||||
cfg.enabled = true;
|
||||
cfg.walk_deadzone = 0x4000;
|
||||
cfg.cursor_deadzone = 1;
|
||||
|
||||
cfg.enabled = ini_get_boolean(section, "enabled", 1) != 0;
|
||||
cfg.swap_axis = ini_get_boolean(section, "swap_sticks", 0) != 0;
|
||||
cfg.walk_deadzone = ini_get_int(section,"walk_deadzone", 0x4000);
|
||||
cfg.cursor_deadzone = ini_get_int(section,"cursor_deadzone", 0x800);
|
||||
auto bcount = std::distance(std::begin(cfg.buttons),std::end(cfg.buttons));
|
||||
for (std::ptrdiff_t i = 0; i < bcount; ++i) {
|
||||
char buff[100];
|
||||
{
|
||||
snprintf(buff,sizeof(buff),"button%d", static_cast<int>(i));
|
||||
const char *v = ini_get_string(section, buff, NULL);
|
||||
if (v) {
|
||||
auto n = cfg.buttons[i] = SDLContext::button_from_string(v);
|
||||
if (n == SDLContext::JoystickButton::mod_key) {
|
||||
cfg.buttons_mod[i] = n;
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
snprintf(buff,sizeof(buff),"mod+button%d", static_cast<int>(i));
|
||||
const char *v = ini_get_string(section, buff, NULL);
|
||||
if (v) {
|
||||
cfg.buttons_mod[i] = SDLContext::button_from_string(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
get_sdl_global_context().configure_controller(cfg);
|
||||
}
|
||||
|
||||
char is_joystick_used() {
|
||||
return get_sdl_global_context().is_joystick_used()?1:0;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#include <libs/devices.h>
|
||||
#include "../config.h"
|
||||
|
||||
|
||||
char get_control_key_state(void);
|
||||
|
@ -26,6 +27,9 @@ void SetWheelMapping(char up, char down);
|
|||
void get_ms_event(MS_EVENT *event);
|
||||
void ShareCPU();
|
||||
|
||||
void init_joystick(const INI_CONFIG_SECTION *section);
|
||||
char is_joystick_used();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -255,29 +255,37 @@ void SDLContext::close_video() {
|
|||
}
|
||||
|
||||
int SDLContext::check_axis_dir(int &cooldown, int value) {
|
||||
if (cooldown>0) {
|
||||
cooldown -= 0x400;
|
||||
int range = 0x8000-_jcontrol_map.walk_deadzone;
|
||||
int step = range >> 4;
|
||||
int max_speed = range+(step<<2);
|
||||
if (value == 0) {
|
||||
cooldown = -1;
|
||||
} else if (cooldown>0) {
|
||||
cooldown -= step;
|
||||
if (cooldown < 0) cooldown = 0;
|
||||
} else {
|
||||
if (value > 0) {
|
||||
cooldown = 0x5000-value;
|
||||
if (cooldown < 0) value = step;
|
||||
cooldown = max_speed-value;
|
||||
return 1;
|
||||
}
|
||||
if (value < 0) {
|
||||
cooldown = 0x5000+value;
|
||||
else if (value < 0) {
|
||||
if (cooldown < 0) value = -step;
|
||||
cooldown = max_speed+value;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int adjust_deadzone(int v) {
|
||||
if (v > 0x4000) return v - 0x4000;
|
||||
if (v < -0x4000) return v + 0x4000;
|
||||
int SDLContext::adjust_deadzone(int v, short deadzone) {
|
||||
if (v > deadzone) return v - deadzone;
|
||||
if (v < -deadzone) return v + deadzone;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int axis_dynamic(int c) {
|
||||
double f = std::floor(std::pow(std::abs(c)*0.001,2)*0.02)+0.5;
|
||||
double f = std::floor(std::pow(std::abs(c)*0.001,2)*0.025);
|
||||
|
||||
if (c < 0) return static_cast<int>(-f);
|
||||
else return static_cast<int>(f);
|
||||
|
@ -286,18 +294,18 @@ static int axis_dynamic(int c) {
|
|||
|
||||
void SDLContext::joystick_handle() {
|
||||
|
||||
int a1 = SDL_JoystickGetAxis(init_context.controller, 0);
|
||||
int a2 = SDL_JoystickGetAxis(init_context.controller, 1);
|
||||
if (std::abs(a1) - std::abs(a2) > 0x1000) a2 = 0;
|
||||
else if (std::abs(a2) - std::abs(a1) >0x1000) a1 = 0;
|
||||
int a1 = SDL_JoystickGetAxis(init_context.controller, _jcontrol_map.swap_axis?2:0);
|
||||
int a2 = SDL_JoystickGetAxis(init_context.controller, _jcontrol_map.swap_axis?3:1);
|
||||
if (std::abs(a1) - std::abs(a2) > 0x2000) a2 = 0;
|
||||
else if (std::abs(a2) - std::abs(a1) >0x2000) a1 = 0;
|
||||
else {
|
||||
a1 = 0;
|
||||
a2 = 0;
|
||||
}
|
||||
int axis1 = check_axis_dir(axis1_cooldown,adjust_deadzone(a1));
|
||||
int axis2 = check_axis_dir(axis2_cooldown,adjust_deadzone(a2));
|
||||
int axis3 = axis_dynamic(SDL_JoystickGetAxis(init_context.controller,2));
|
||||
int axis4 = axis_dynamic(SDL_JoystickGetAxis(init_context.controller,3));
|
||||
int axis1 = check_axis_dir(axis1_cooldown,adjust_deadzone(a1, _jcontrol_map.walk_deadzone));
|
||||
int axis2 = check_axis_dir(axis2_cooldown,adjust_deadzone(a2, _jcontrol_map.walk_deadzone));
|
||||
int axis3 = axis_dynamic(adjust_deadzone(SDL_JoystickGetAxis(init_context.controller,_jcontrol_map.swap_axis?0:2), _jcontrol_map.cursor_deadzone));
|
||||
int axis4 = axis_dynamic(adjust_deadzone(SDL_JoystickGetAxis(init_context.controller,_jcontrol_map.swap_axis?1:3), _jcontrol_map.cursor_deadzone));
|
||||
|
||||
int newx = this->ms_event.x + axis3;
|
||||
int newy = this->ms_event.y + axis4;
|
||||
|
@ -329,8 +337,8 @@ void SDLContext::joystick_handle() {
|
|||
default:break;
|
||||
}
|
||||
switch(axis1) {
|
||||
case -1: scn = SDL_SCANCODE_LEFT;break;
|
||||
case 1: scn = SDL_SCANCODE_RIGHT;break;
|
||||
case -1: if (_jcontrol_mod_key) scn = SDL_SCANCODE_END; else scn = SDL_SCANCODE_LEFT;break;
|
||||
case 1: if (_jcontrol_mod_key) scn = SDL_SCANCODE_PAGEDOWN; else scn = SDL_SCANCODE_RIGHT;break;
|
||||
default:break;
|
||||
}
|
||||
if (scn != SDL_Scancode{}) {
|
||||
|
@ -339,6 +347,84 @@ void SDLContext::joystick_handle() {
|
|||
}
|
||||
}
|
||||
|
||||
void SDLContext::configure_controller(const JoystickConfig &cfg) {
|
||||
_jcontrol_map = cfg;
|
||||
if (_jcontrol_map.enabled) {
|
||||
if (init_context.controller) {
|
||||
SDL_AddTimer(25,[](Uint32 tm, void *ptr){
|
||||
SDLContext *me = reinterpret_cast<SDLContext *>(ptr);
|
||||
me->joystick_handle();
|
||||
return tm;
|
||||
}, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
bool SDLContext::is_joystick_used() const {
|
||||
return _jcontrol_used;
|
||||
}
|
||||
|
||||
|
||||
void SDLContext::generate_j_event(int button, char up) {
|
||||
if (_jcontrol_map.enabled && button >= 0 && button < static_cast<int>(sizeof(_jcontrol_map.buttons)/sizeof(JoystickButton))) {
|
||||
_jcontrol_used = true;
|
||||
JoystickButton b = _jcontrol_mod_key?_jcontrol_map.buttons_mod[button]:_jcontrol_map.buttons[button];
|
||||
SDL_Scancode cd = {};
|
||||
switch (b) {
|
||||
default: break;
|
||||
case JoystickButton::enter: if (!up) cd = SDL_SCANCODE_RETURN;break;
|
||||
case JoystickButton::space: if (!up) cd = SDL_SCANCODE_SPACE; break;
|
||||
case JoystickButton::ctrl: _key_control = !up; break;
|
||||
case JoystickButton::lclick: ms_event.tl1 = !up;
|
||||
ms_event.event = 1;
|
||||
ms_event.event_type|= up?MS_EVENT_MOUSE_LRELEASE:MS_EVENT_MOUSE_LPRESS;
|
||||
break;
|
||||
case JoystickButton::rclick: ms_event.tl2 = !up;
|
||||
ms_event.event = 1;
|
||||
ms_event.event_type|= up?MS_EVENT_MOUSE_RRELEASE:MS_EVENT_MOUSE_RPRESS;
|
||||
break;
|
||||
case JoystickButton::ctrl_lclick:_key_control = !up;
|
||||
ms_event.tl1 = !up;
|
||||
ms_event.event = 1;
|
||||
ms_event.event_type|= up?MS_EVENT_MOUSE_LRELEASE:MS_EVENT_MOUSE_LPRESS;
|
||||
break;
|
||||
case JoystickButton::escape: if (!up) cd = SDL_SCANCODE_ESCAPE;break;
|
||||
case JoystickButton::up: if (!up) cd = SDL_SCANCODE_UP;break;
|
||||
case JoystickButton::down: if (!up) cd = SDL_SCANCODE_DOWN;break;
|
||||
case JoystickButton::left: if (!up) cd = SDL_SCANCODE_PAGEDOWN;break;
|
||||
case JoystickButton::right: if (!up) cd = SDL_SCANCODE_END;break;
|
||||
case JoystickButton::turn_left: if (!up) cd = SDL_SCANCODE_LEFT;break;
|
||||
case JoystickButton::turn_right: if (!up) cd = SDL_SCANCODE_RIGHT;break;
|
||||
case JoystickButton::merge: if (!up) cd = SDL_SCANCODE_INSERT;break;
|
||||
case JoystickButton::map: if (!up) cd = SDL_SCANCODE_TAB;break;
|
||||
case JoystickButton::split1: if (!up) cd = SDL_SCANCODE_1;break;
|
||||
case JoystickButton::split2: if (!up) cd = SDL_SCANCODE_2;break;
|
||||
case JoystickButton::split3: if (!up) cd = SDL_SCANCODE_3;break;
|
||||
case JoystickButton::split4: if (!up) cd = SDL_SCANCODE_4;break;
|
||||
case JoystickButton::split5: if (!up) cd = SDL_SCANCODE_5;break;
|
||||
case JoystickButton::split6: if (!up) cd = SDL_SCANCODE_6;break;
|
||||
case JoystickButton::F1: if (!up) cd = SDL_SCANCODE_F1;break;
|
||||
case JoystickButton::F2: if (!up) cd = SDL_SCANCODE_F2;break;
|
||||
case JoystickButton::F3: if (!up) cd = SDL_SCANCODE_F3;break;
|
||||
case JoystickButton::F4: if (!up) cd = SDL_SCANCODE_F4;break;
|
||||
case JoystickButton::F5: if (!up) cd = SDL_SCANCODE_F5;break;
|
||||
case JoystickButton::F6: if (!up) cd = SDL_SCANCODE_F6;break;
|
||||
case JoystickButton::F7: if (!up) cd = SDL_SCANCODE_F7;break;
|
||||
case JoystickButton::F8: if (!up) cd = SDL_SCANCODE_F8;break;
|
||||
case JoystickButton::F9: if (!up) cd = SDL_SCANCODE_F9;break;
|
||||
case JoystickButton::F10: if (!up) cd = SDL_SCANCODE_F10;break;
|
||||
case JoystickButton::F11: if (!up) cd = SDL_SCANCODE_F11;break;
|
||||
case JoystickButton::F12: if (!up) cd = SDL_SCANCODE_F12;break;
|
||||
case JoystickButton::backspace: if (!up) cd = SDL_SCANCODE_BACKSPACE;break;
|
||||
case JoystickButton::mod_key: _jcontrol_mod_key = !up;
|
||||
}
|
||||
if (cd != SDL_Scancode{}) {
|
||||
std::lock_guard _(_mx);
|
||||
_keyboard_queue.push(sdl_keycode_map.get_bios_code(cd, 0, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SDLContext::event_loop(std::stop_token stp) {
|
||||
|
||||
static Uint32 exit_loop_event = SDL_RegisterEvents(1);
|
||||
|
@ -348,13 +434,6 @@ void SDLContext::event_loop(std::stop_token stp) {
|
|||
SDL_PushEvent(&event);
|
||||
});
|
||||
|
||||
if (init_context.controller) {
|
||||
SDL_AddTimer(25,[](Uint32 tm, void *ptr){
|
||||
SDLContext *me = reinterpret_cast<SDLContext *>(ptr);
|
||||
me->joystick_handle();
|
||||
return tm;
|
||||
}, this);
|
||||
}
|
||||
|
||||
SDL_Event e;
|
||||
while (SDL_WaitEvent(&e)) {
|
||||
|
@ -427,44 +506,9 @@ void SDLContext::event_loop(std::stop_token stp) {
|
|||
if (e.wheel.y > 0) kbdevent =SDL_SCANCODE_UP;
|
||||
else if (e.wheel.y < 0) kbdevent =SDL_SCANCODE_DOWN;
|
||||
} else if (e.type == SDL_JOYBUTTONDOWN) {
|
||||
switch (e.jbutton.button) {
|
||||
case 3: kbdevent = SDL_SCANCODE_SPACE; break;
|
||||
case 2: kbdevent = SDL_SCANCODE_RETURN; break;
|
||||
case 9: kbdevent = SDL_SCANCODE_END;break;
|
||||
case 7: kbdevent = SDL_SCANCODE_ESCAPE;break;
|
||||
case 10:kbdevent = SDL_SCANCODE_PAGEDOWN;break;
|
||||
case 11:kbdevent = SDL_SCANCODE_UP;break;
|
||||
case 12:kbdevent = SDL_SCANCODE_DOWN;break;
|
||||
case 13:kbdevent = SDL_SCANCODE_LEFT;break;
|
||||
case 14:kbdevent = SDL_SCANCODE_RIGHT;break;
|
||||
case 0: ms_event.event = 1;
|
||||
ms_event.event_type |= MS_EVENT_MOUSE_LPRESS;
|
||||
ms_event.tl1 = 1;
|
||||
break;
|
||||
case 8: ms_event.event = 1;
|
||||
ms_event.event_type |= MS_EVENT_MOUSE_LPRESS|MS_EVENT_MOUSE_LDBLCLK;
|
||||
ms_event.tl1 = 1;
|
||||
break;
|
||||
case 1: ms_event.event = 1;
|
||||
ms_event.event_type |= MS_EVENT_MOUSE_RPRESS;
|
||||
ms_event.tl1 = 1;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
generate_j_event(e.jbutton.button, 0);
|
||||
} else if (e.type == SDL_JOYBUTTONUP) {
|
||||
switch (e.jbutton.button) {
|
||||
case 0: ms_event.event = 1;
|
||||
ms_event.event_type |= MS_EVENT_MOUSE_LRELEASE;
|
||||
ms_event.tl1 = 0;
|
||||
break;
|
||||
case 8:
|
||||
case 1: ms_event.event = 1;
|
||||
ms_event.event_type |= MS_EVENT_MOUSE_RRELEASE;
|
||||
ms_event.tl1 = 1;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
generate_j_event(e.jbutton.button, 1);
|
||||
}
|
||||
|
||||
if (kbdevent != SDL_Scancode{}) {
|
||||
|
@ -1000,3 +1044,43 @@ bool SDLContext::is_crt_enabled() const
|
|||
std::lock_guard _(_mx);
|
||||
return _enable_crt;
|
||||
}
|
||||
|
||||
SDLContext::JoystickButton SDLContext::button_from_string(std::string_view s) {
|
||||
if (s=="enter") return JoystickButton::enter;
|
||||
if (s=="space") return JoystickButton::space;
|
||||
if (s=="ctrl") return JoystickButton::ctrl;
|
||||
if (s=="lclick") return JoystickButton::lclick;
|
||||
if (s=="rclick") return JoystickButton::rclick;
|
||||
if (s=="ctrl+lclick") return JoystickButton::ctrl_lclick;
|
||||
if (s=="escape") return JoystickButton::escape;
|
||||
if (s=="up") return JoystickButton::up;
|
||||
if (s=="down") return JoystickButton::down;
|
||||
if (s=="left") return JoystickButton::left;
|
||||
if (s=="right") return JoystickButton::right;
|
||||
if (s=="turn_left") return JoystickButton::turn_left;
|
||||
if (s=="turn_right") return JoystickButton::turn_right;
|
||||
if (s=="merge_group") return JoystickButton::merge;
|
||||
if (s=="split1") return JoystickButton::split1;
|
||||
if (s=="split2") return JoystickButton::split2;
|
||||
if (s=="split3") return JoystickButton::split3;
|
||||
if (s=="split4") return JoystickButton::split4;
|
||||
if (s=="split5") return JoystickButton::split5;
|
||||
if (s=="split6") return JoystickButton::split6;
|
||||
if (s=="map") return JoystickButton::map;
|
||||
if (s=="F1") return JoystickButton::F1;
|
||||
if (s=="F2") return JoystickButton::F2;
|
||||
if (s=="F3") return JoystickButton::F3;
|
||||
if (s=="F4") return JoystickButton::F4;
|
||||
if (s=="F5") return JoystickButton::F5;
|
||||
if (s=="F6") return JoystickButton::F6;
|
||||
if (s=="F7") return JoystickButton::F7;
|
||||
if (s=="F8") return JoystickButton::F8;
|
||||
if (s=="F9") return JoystickButton::F9;
|
||||
if (s=="F10") return JoystickButton::F10;
|
||||
if (s=="F11") return JoystickButton::F11;
|
||||
if (s=="F12") return JoystickButton::F12;
|
||||
if (s=="backspace") return JoystickButton::backspace;
|
||||
if (s=="mod_key") return JoystickButton::mod_key;
|
||||
return JoystickButton::disabled;
|
||||
|
||||
}
|
||||
|
|
|
@ -42,6 +42,57 @@ public:
|
|||
const char *audioDevice;
|
||||
};
|
||||
|
||||
enum class JoystickButton : char{
|
||||
disabled,
|
||||
enter,
|
||||
space,
|
||||
ctrl,
|
||||
lclick,
|
||||
rclick,
|
||||
ctrl_lclick,
|
||||
escape,
|
||||
up,
|
||||
down,
|
||||
left,
|
||||
right,
|
||||
turn_left,
|
||||
turn_right,
|
||||
merge,
|
||||
split1,
|
||||
split2,
|
||||
split3,
|
||||
split4,
|
||||
split5,
|
||||
split6,
|
||||
map,
|
||||
F1,
|
||||
F2,
|
||||
F3,
|
||||
F4,
|
||||
F5,
|
||||
F6,
|
||||
F7,
|
||||
F8,
|
||||
F9,
|
||||
F10,
|
||||
F11,
|
||||
F12,
|
||||
backspace,
|
||||
mod_key
|
||||
};
|
||||
|
||||
static JoystickButton button_from_string(std::string_view s);
|
||||
|
||||
struct JoystickConfig {
|
||||
bool enabled;
|
||||
bool swap_axis;
|
||||
short walk_deadzone;
|
||||
short cursor_deadzone;
|
||||
JoystickButton buttons[32];
|
||||
JoystickButton buttons_mod[32];
|
||||
|
||||
};
|
||||
|
||||
struct AudioInfo {
|
||||
int freq;
|
||||
};
|
||||
|
@ -50,6 +101,8 @@ public:
|
|||
|
||||
void set_window_icon(const void *icon_data, size_t icon_size);
|
||||
|
||||
void configure_controller(const JoystickConfig &cfg);
|
||||
|
||||
void close_video();
|
||||
|
||||
AudioInfo init_audio(const AudioConfig &config, SDL_AudioCallback cb, void *cb_ctx);
|
||||
|
@ -105,6 +158,8 @@ public:
|
|||
void enable_crt_filter(bool enable);
|
||||
bool is_crt_enabled() const;
|
||||
|
||||
|
||||
bool is_joystick_used() const;
|
||||
protected:
|
||||
|
||||
struct SDL_Deleter {
|
||||
|
@ -168,6 +223,9 @@ protected:
|
|||
CrtFilterType _crt_filter= CrtFilterType::autoselect;
|
||||
bool _enable_crt = true;
|
||||
std::function<void()> _quit_callback;
|
||||
JoystickConfig _jcontrol_map;
|
||||
bool _jcontrol_mod_key = false;
|
||||
bool _jcontrol_used = false;
|
||||
|
||||
std::unique_ptr<SDL_Window, SDL_Deleter> _window;
|
||||
std::unique_ptr<SDL_Renderer, SDL_Deleter> _renderer;
|
||||
|
@ -198,10 +256,8 @@ protected:
|
|||
SpriteList _sprites;
|
||||
|
||||
|
||||
int axis1_cooldown = 0;
|
||||
int axis2_cooldown = 0;
|
||||
int axis3_cooldown = 0;
|
||||
int axis4_cooldown = 0;
|
||||
int axis1_cooldown = -1;
|
||||
int axis2_cooldown = -1;
|
||||
int check_axis_dir(int &cooldown, int value);
|
||||
|
||||
Uint32 _update_request_event;
|
||||
|
@ -242,5 +298,7 @@ protected:
|
|||
void update_zindex();
|
||||
|
||||
void joystick_handle();
|
||||
void generate_j_event(int button, char up);
|
||||
static int adjust_deadzone(int v, short deadzone);
|
||||
|
||||
};
|
||||
|
|
78
skeldal.ini
78
skeldal.ini
|
@ -56,6 +56,84 @@
|
|||
[audio]
|
||||
#device=
|
||||
|
||||
|
||||
### controller
|
||||
#
|
||||
# enable = enable or disable controller (must be connected)
|
||||
# swap_sticks = swap levers
|
||||
# buttonX = map button to action
|
||||
# mod+buttonX = map button pressed with mod button together to action
|
||||
|
||||
# disabled - button is disabled
|
||||
# enter - ENTER key (start battle, etc),
|
||||
# space - SPACE key (wall action, open door, next in battle, fast action)
|
||||
# ctrl - control mod key,
|
||||
# lclick - left mouse click,
|
||||
# rclick - right mouse click (exit),
|
||||
# ctrl_lclick - ctrl+lclick (split group, fast action)
|
||||
# escape - escape key,
|
||||
# up - go forward, up in lists,
|
||||
# down - go backward, down in lists
|
||||
# left - go left
|
||||
# right - go right
|
||||
# turn_left - turn left
|
||||
# turn_right - turn right
|
||||
# merge - merge group
|
||||
# split1 - split first character
|
||||
# split2 - split second character
|
||||
# split3,
|
||||
# split4,
|
||||
# split5,
|
||||
# split6,
|
||||
# map, - open map (TAB)
|
||||
# F1 - Settings
|
||||
# F2 - Save
|
||||
# F3 - Load
|
||||
# F4 - Rest
|
||||
# F5 - Autosave
|
||||
# F6 - Book
|
||||
# F7 - Spell casting
|
||||
# F8 - Attack (in battle)
|
||||
# F9 - Move (in battle)
|
||||
# F10 - Armor and inventory (in battle)
|
||||
# F11 - Run/Flee (in battle)
|
||||
# F12 - No action (in battle)
|
||||
# backspace - cancel action (in battle)
|
||||
# mod_key
|
||||
#
|
||||
# walk_deadzone = specifies deadzone for walk (0-32768)
|
||||
# cursor_deadzone = specifies deadzone for cursor movement (0-32768)
|
||||
[controller]
|
||||
#enabled=on
|
||||
#swap_sticks=off
|
||||
#button0=lclick
|
||||
#button1=rclick
|
||||
#button2=enter
|
||||
#button3=space
|
||||
#button5=F1
|
||||
#button4=F2
|
||||
#mod+button4=F5
|
||||
#button6=F3
|
||||
#button8=ctrl_lclick
|
||||
#button10=mod_key
|
||||
#mod+button10=mod_key
|
||||
#button11=map
|
||||
#mod+button11=F6
|
||||
#button12=merge
|
||||
#button14=left
|
||||
#button13=right
|
||||
#button9=backspace
|
||||
#mod+button5=escape
|
||||
#mod+button9=F4
|
||||
#mod+button12=F7
|
||||
#mod+button0=F8
|
||||
#mod+button1=F9
|
||||
#mod+button2=F10
|
||||
#mod+button3=F11
|
||||
#mod+button14=F12
|
||||
#mod+button13=backspace
|
||||
|
||||
|
||||
### localization settings
|
||||
#
|
||||
# keyboard_layout = cz_querty, cz_quertz, us
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue