more controller support and fix some crashes

This commit is contained in:
Ondřej Novák 2025-03-04 12:07:40 +01:00
parent 3f946405b9
commit 0e251dcd05
19 changed files with 608 additions and 195 deletions

View file

@ -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);

View file

@ -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();
@ -776,7 +752,7 @@ static void key_check(EVENT_MSG *msg,void **unused)
}
else if (c==27) {
dlg_konec(0,0,0,0,0);
}*/
}
}
@ -788,13 +764,13 @@ void wire_dialog_drw()
wire_dialog();
draw_all();
ukaz_mysku();
effect_show(NULL);
effect_show(NULL);
}
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);
}

View file

@ -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;
}
}
}

View file

@ -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

View file

@ -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));

View file

@ -1546,13 +1546,13 @@ 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;
}
}
}
}
}
}
if (!found_price) {
strcopy_n(c,glob_items[i-1].jmeno,sizeof(c));
}
@ -1754,13 +1754,13 @@ 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;
}
}
}
}
}
}
if (!found_price) {
strcopy_n(c,glob_items[i-1].jmeno,sizeof(c));
}
@ -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;
}
}
@ -3047,7 +3050,7 @@ void unwire_shop(void)
send_message(E_DONE,E_KEYBOARD, shop_keyboard_proc);
norefresh=0;
wire_proc=wire_shop;
inv_view_mode=old_inv_view_mode;
inv_view_mode=old_inv_view_mode;
}
void wire_shop(void)

View file

@ -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());
}

View file

@ -77,17 +77,21 @@ 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;
}

View file

@ -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);
@ -1382,7 +1383,7 @@ static void game_big_circle(char enforced)
leave_current_map();
strcopy_n(s,loadlevel.name,sizeof(s));
if (s[0]!=0) {
err=load_map(s);
err=load_map(s);
}
memset(GlobEventList,0,sizeof(GlobEventList));

View file

@ -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);
}
@ -1627,12 +1627,12 @@ void vyber_cil(int typ)
char power_info(int id,int xa,int ya,int xr,int yr) {
rune_info = NULL;
int x = ms_last_event.x;
int x = ms_last_event.x;
int y = ms_last_event.y;
for (int i = 0; i < CLK_POWER; ++i) {
const T_CLK_MAP *m = clk_power+i;
if (m->proc == &power && m->xlu <= x && m->xrb >= x && m->ylu <= y && m->yrb >= y) {
rune_info = powers_info[m->id];
rune_info = powers_info[m->id];
}
}
return 1;
@ -1700,7 +1700,7 @@ char runes_mask(int id,int xa,int ya,int xr,int yr)
}
else
{
rune_name=get_rune_name(x);
rune_name=get_rune_name(x);
}
}
}
@ -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;
@ -1852,18 +1853,18 @@ void program_draw()
c=rune_name;
} else {
c=texty[40+pgm_help];
}
}
set_aligned_position(580,376,1,2,c);
outtext(c);
if (rune_name && rune_info) {
set_aligned_position(580,362,1,2,rune_info);
outtext(rune_info);
}
}
ukaz_mysku();
}
@ -1908,11 +1909,31 @@ 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)
{
if (d==AC_STAND || d==AC_RUN) postavy[select_player].actions=0;
@ -2079,6 +2100,48 @@ static void zahajit_kolo(char prekvapeni)
send_message(E_KOUZLO_KOLO);
}
static char add_pc_action(int d) {
souboje_stisknout(d);
switch(d)
{
case AC_RUN:
if (lodka) {
group_flee = 1;break;
} else {
postavy[select_player].utek=5+postavy[select_player].actions;
}
CASE_FALLTHROUGH;
case AC_ATTACK:
case AC_STAND:
case AC_ARMOR:
case AC_MOVE:
case AC_MAGIC:if (postavy[select_player].actions && (d != AC_MOVE || !lodka))
{
HUM_ACTION *c;
postavy[select_player].direction=viewdir;
c=postavy[select_player].zvolene_akce;while (c->action) c++;
if (d==AC_MAGIC)
{
wire_select_rune();
return 1;
}
c->action=d;
if (d==AC_ATTACK) c->data1=select_weapon(&postavy[select_player],1);
c++;
c->action=0;
souboje_vybrano(d);
}
break;
case AC_CANCEL:zrusit_akce();group_flee = 0;break;
case AC_START:zahajit_kolo(0);
souboje_stisknout(d);
return 0;
break;
}
return 0;
}
char mask_click(int id,int xa,int ya,int xr,int yr)
{
char *c;
@ -2090,47 +2153,9 @@ char mask_click(int id,int xa,int ya,int xr,int yr)
c=(char *)mask+6+512;
c+=yr*mask[0]+xr;
d=*c;
if (d)
{
souboje_stisknout(d);
switch(d)
{
case AC_RUN:
if (lodka) {
group_flee = 1;break;
} else {
postavy[select_player].utek=5+postavy[select_player].actions;
}
CASE_FALLTHROUGH;
case AC_ATTACK:
case AC_STAND:
case AC_ARMOR:
case AC_MOVE:
case AC_MAGIC:if (postavy[select_player].actions && (d != AC_MOVE || !lodka))
{
HUM_ACTION *c;
postavy[select_player].direction=viewdir;
c=postavy[select_player].zvolene_akce;while (c->action) c++;
if (d==AC_MAGIC)
{
wire_select_rune();
return 1;
}
c->action=d;
if (d==AC_ATTACK) c->data1=select_weapon(&postavy[select_player],1);
c++;
c->action=0;
souboje_vybrano(d);
}
break;
case AC_CANCEL:zrusit_akce();group_flee = 0;break;
case AC_START:zahajit_kolo(0);
souboje_stisknout(d);
return 0;
break;
}
return 0;
}
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);