mirror of
https://github.com/ondra-novak/gates_of_skeldal.git
synced 2025-07-20 13:15:16 -04:00
Merge branch 'main' into sse
This commit is contained in:
commit
5931c6eab4
37 changed files with 739 additions and 147 deletions
|
@ -40,6 +40,30 @@ else()
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
set(VERSION_IN "${CMAKE_SOURCE_DIR}/version.in.h")
|
||||||
|
set(VERSION_OUT "${CMAKE_BINARY_DIR}/version.h")
|
||||||
|
|
||||||
|
find_package(Git QUIET)
|
||||||
|
|
||||||
|
if(GIT_FOUND)
|
||||||
|
execute_process(
|
||||||
|
COMMAND ${GIT_EXECUTABLE} describe --tags --always
|
||||||
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
|
OUTPUT_VARIABLE GIT_VERSION
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
RESULT_VARIABLE GIT_RESULT
|
||||||
|
)
|
||||||
|
if(NOT GIT_RESULT EQUAL 0)
|
||||||
|
set(GIT_VERSION "unknown")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
set(GIT_VERSION "unknown")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(APP_VERSION "${GIT_VERSION}")
|
||||||
|
configure_file(${VERSION_IN} ${VERSION_OUT} @ONLY)
|
||||||
|
|
||||||
|
include_directories(${CMAKE_BINARY_DIR})
|
||||||
|
|
||||||
include_directories(.)
|
include_directories(.)
|
||||||
|
|
||||||
|
|
|
@ -1109,3 +1109,9 @@ void free_map_description() {
|
||||||
if (texty_v_mape!=NULL)release_list(texty_v_mape);
|
if (texty_v_mape!=NULL)release_list(texty_v_mape);
|
||||||
texty_v_mape = NULL;
|
texty_v_mape = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TSTR_LIST swap_map_description(TSTR_LIST new_list) {
|
||||||
|
TSTR_LIST old = texty_v_mape;
|
||||||
|
texty_v_mape = new_list;
|
||||||
|
return old;
|
||||||
|
}
|
|
@ -327,14 +327,14 @@ static const void *bott_draw_normal(const void *pp, int32_t *s)
|
||||||
{
|
{
|
||||||
char c[]=" ";int z,lv,llv;
|
char c[]=" ";int z,lv,llv;
|
||||||
put_picture(x,0,ablock(H_OKNO));lv=p->lives;llv=p->vlastnosti[VLS_MAXHIT];
|
put_picture(x,0,ablock(H_OKNO));lv=p->lives;llv=p->vlastnosti[VLS_MAXHIT];
|
||||||
if (lv || p->used & 0x80 || p->kondice > 0)
|
if (lv || p->used & 0x80)
|
||||||
{
|
{
|
||||||
z=3-((lv-1)*4/llv);if (lv==llv) z=0;
|
z=3-((lv-1)*4/llv);if (lv==llv) z=0;
|
||||||
z*=75;
|
z*=75;
|
||||||
if (p->xicht>=0)put_8bit_clipped(ablock(H_XICHTY+i),bott_scr+PIC_X+x+PIC_Y*scr_linelen2,z,54,75);
|
if (p->xicht>=0)put_8bit_clipped(ablock(H_XICHTY+i),bott_scr+PIC_X+x+PIC_Y*scr_linelen2,z,54,75);
|
||||||
if (!lv && !(p->used & 0x80) && p->kondice>0) {
|
/* if (!lv && !(p->used & 0x80) && p->kondice>0) {
|
||||||
greyscale_rectangle(PIC_X+x,PIC_Y, 54, 75);
|
greyscale_rectangle(PIC_X+x,PIC_Y, 54, 75);
|
||||||
}
|
}*/
|
||||||
if (p->bonus) draw_small_icone(0,PIC_X+x+1,PIC_Y+1);
|
if (p->bonus) draw_small_icone(0,PIC_X+x+1,PIC_Y+1);
|
||||||
if (p->spell) draw_small_icone(1,PIC_X+x+1,PIC_Y+1);
|
if (p->spell) draw_small_icone(1,PIC_X+x+1,PIC_Y+1);
|
||||||
if (!p->voda) draw_small_icone(2,PIC_X+x+1,PIC_Y+1);
|
if (!p->voda) draw_small_icone(2,PIC_X+x+1,PIC_Y+1);
|
||||||
|
|
|
@ -745,7 +745,7 @@ static void wait_timer(EVENT_MSG *msg, void **udata) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void effect_show(va_list args)
|
void effect_show(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char s = exit_wait;
|
char s = exit_wait;
|
||||||
|
@ -861,7 +861,7 @@ char enter_generator()
|
||||||
memset(&cur_stats,0,sizeof(cur_stats));
|
memset(&cur_stats,0,sizeof(cur_stats));
|
||||||
vypocet_vlastnosti(cur_angle,&cur_vls);
|
vypocet_vlastnosti(cur_angle,&cur_vls);
|
||||||
b_disables=0x7;
|
b_disables=0x7;
|
||||||
redraw_generator(rep);if (!rep)effect_show(NULL);rep=1;
|
redraw_generator(rep);if (!rep)effect_show();rep=1;
|
||||||
edit_name();
|
edit_name();
|
||||||
change_click_map(clk_page1,CLK_PAGE1);
|
change_click_map(clk_page1,CLK_PAGE1);
|
||||||
was_enter=0;
|
was_enter=0;
|
||||||
|
|
|
@ -766,7 +766,7 @@ void wire_dialog_drw(void)
|
||||||
wire_dialog();
|
wire_dialog();
|
||||||
draw_all();
|
draw_all();
|
||||||
ukaz_mysku();
|
ukaz_mysku();
|
||||||
effect_show(NULL);
|
effect_show();
|
||||||
}
|
}
|
||||||
void unwire_dialog(void)
|
void unwire_dialog(void)
|
||||||
{
|
{
|
||||||
|
|
28
game/enemy.c
28
game/enemy.c
|
@ -1317,18 +1317,24 @@ void vymaz_zasahy(THE_TIMER *q)
|
||||||
bott_draw(0);
|
bott_draw(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int select_drop_inventory_place(TMOB *p) {
|
||||||
|
int x,y,pl;
|
||||||
|
if (p->locx>128) x=1;else if (p->locx<128) x=-1;else x=rnd(2)*2-1;
|
||||||
|
if (p->locy>128) y=1;else if (p->locy<128) y=-1;else y=rnd(2)*2-1;
|
||||||
|
pl=0;if (x>0) pl++;
|
||||||
|
if (y>0) pl=3-pl;
|
||||||
|
return pl;
|
||||||
|
}
|
||||||
|
|
||||||
static int drop_inventory(TMOB *p)
|
static int drop_inventory(TMOB *p)
|
||||||
{
|
{
|
||||||
int i,x,y,pl;
|
int i,pl;
|
||||||
short c[]={0,0};
|
short c[]={0,0};
|
||||||
|
|
||||||
for(i=-1;i<MOBS_INV;i++)
|
for(i=-1;i<MOBS_INV;i++) {
|
||||||
if (p->inv[i] || (i<0 && p->money))
|
if (p->inv[i] || (i<0 && p->money))
|
||||||
{
|
{
|
||||||
if (p->locx>128) x=1;else if (p->locx<128) x=-1;else x=rnd(2)*2-1;
|
pl = select_drop_inventory_place(p);
|
||||||
if (p->locy>128) y=1;else if (p->locy<128) y=-1;else y=rnd(2)*2-1;
|
|
||||||
pl=0;if (x>0) pl++;
|
|
||||||
if (y>0) pl=3-pl;
|
|
||||||
if (i<0)
|
if (i<0)
|
||||||
{
|
{
|
||||||
int z=(int)p->money+(int)(rnd(40)-20)*(int)p->money/(int)100;
|
int z=(int)p->money+(int)(rnd(40)-20)*(int)p->money/(int)100;
|
||||||
|
@ -1341,6 +1347,16 @@ static int drop_inventory(TMOB *p)
|
||||||
}
|
}
|
||||||
push_item(p->sector,pl,c);
|
push_item(p->sector,pl,c);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (destroyed_items) {
|
||||||
|
int cnt = count_items_total(destroyed_items);
|
||||||
|
if (cnt) {
|
||||||
|
int idx = cnt -1;
|
||||||
|
pl = select_drop_inventory_place(p);
|
||||||
|
push_item(p->sector,pl, destroyed_items+idx);
|
||||||
|
destroyed_items[idx] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,9 @@
|
||||||
#define SLOTS_MAX 10
|
#define SLOTS_MAX 10
|
||||||
|
|
||||||
#define GM_MAPENABLE 0x1
|
#define GM_MAPENABLE 0x1
|
||||||
|
#define GM_FASTBATTLES 0x2
|
||||||
|
#define GM_GAMESPEED_SHIFT 2
|
||||||
|
#define GM_GAMESPEED_MASK 0x1F
|
||||||
|
|
||||||
#define SAVE_SLOT_S 34
|
#define SAVE_SLOT_S 34
|
||||||
#define LOAD_SLOT_S (372+34)
|
#define LOAD_SLOT_S (372+34)
|
||||||
|
@ -583,6 +586,14 @@ int unpack_all_status(FILE *f)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void save_destroyed_items(TMPFILE_WR *f) {
|
||||||
|
short c = (short)count_items_total(destroyed_items);
|
||||||
|
temp_storage_write(&c,sizeof(c), f);
|
||||||
|
if (c) {
|
||||||
|
temp_storage_write(destroyed_items,sizeof(short)*c, f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int save_basic_info()
|
int save_basic_info()
|
||||||
{
|
{
|
||||||
TMPFILE_WR *f;
|
TMPFILE_WR *f;
|
||||||
|
@ -618,7 +629,14 @@ int save_basic_info()
|
||||||
s.swapchans=MIN(get_snd_effect(SND_SWAP),255);
|
s.swapchans=MIN(get_snd_effect(SND_SWAP),255);
|
||||||
s.out_filter=MIN(get_snd_effect(SND_OUTFILTER),255);
|
s.out_filter=MIN(get_snd_effect(SND_OUTFILTER),255);
|
||||||
s.autosave=autosave_enabled;
|
s.autosave=autosave_enabled;
|
||||||
s.game_flags=(enable_glmap!=0);
|
s.game_flags=0;
|
||||||
|
|
||||||
|
if (enable_glmap!=0) s.game_flags |= GM_MAPENABLE;
|
||||||
|
if (gamespeedbattle<gamespeed) s.game_flags |= GM_FASTBATTLES;
|
||||||
|
if (timerspeed_val <= GM_GAMESPEED_MASK) {
|
||||||
|
s.game_flags |= (timerspeed_val & GM_GAMESPEED_MASK) << GM_GAMESPEED_SHIFT;
|
||||||
|
}
|
||||||
|
|
||||||
strcopy_n(s.level_name,level_fname,sizeof(s.level_name));
|
strcopy_n(s.level_name,level_fname,sizeof(s.level_name));
|
||||||
for(i=0;i<5;i++) s.runes[i]=runes[i];
|
for(i=0;i<5;i++) s.runes[i]=runes[i];
|
||||||
if (picked_item!=NULL)
|
if (picked_item!=NULL)
|
||||||
|
@ -635,11 +653,26 @@ int save_basic_info()
|
||||||
for(i=0,h=postavy;i<POCET_POSTAV;h++,i++) if (h->demon_save!=NULL)
|
for(i=0,h=postavy;i<POCET_POSTAV;h++,i++) if (h->demon_save!=NULL)
|
||||||
temp_storage_write(h->demon_save,sizeof(THUMAN)*1,f); //ulozeni polozek s demony
|
temp_storage_write(h->demon_save,sizeof(THUMAN)*1,f); //ulozeni polozek s demony
|
||||||
res|=save_dialog_info(f);
|
res|=save_dialog_info(f);
|
||||||
|
save_destroyed_items(f);
|
||||||
temp_storage_close_wr(f);
|
temp_storage_close_wr(f);
|
||||||
SEND_LOG("(SAVELOAD) Done... Result: %d",res);
|
SEND_LOG("(SAVELOAD) Done... Result: %d",res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int load_destroyed_items(TMPFILE_RD *f) {
|
||||||
|
int res = 0;
|
||||||
|
short destroyed_items_count = 0;
|
||||||
|
temp_storage_read(&destroyed_items_count,sizeof(destroyed_items_count), f);
|
||||||
|
free(destroyed_items);
|
||||||
|
destroyed_items = NULL;
|
||||||
|
if (destroyed_items_count) {
|
||||||
|
destroyed_items = NewArr(short, destroyed_items_count+1);
|
||||||
|
res|=temp_storage_read(destroyed_items,destroyed_items_count*sizeof(short), f) != destroyed_items_count*sizeof(short);
|
||||||
|
destroyed_items[destroyed_items_count] = 0;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
int load_basic_info()
|
int load_basic_info()
|
||||||
{
|
{
|
||||||
TMPFILE_RD *f;
|
TMPFILE_RD *f;
|
||||||
|
@ -654,6 +687,9 @@ int load_basic_info()
|
||||||
if (f==NULL) return 1;
|
if (f==NULL) return 1;
|
||||||
res|=(temp_storage_read(&s,1*sizeof(s),f)!=sizeof(s));
|
res|=(temp_storage_read(&s,1*sizeof(s),f)!=sizeof(s));
|
||||||
if (s.game_flags & GM_MAPENABLE) enable_glmap=1;else enable_glmap=0;
|
if (s.game_flags & GM_MAPENABLE) enable_glmap=1;else enable_glmap=0;
|
||||||
|
gamespeedbattle =s.game_flags & GM_FASTBATTLES? GAMESPEED_FASTBATTLE:gamespeed;
|
||||||
|
int tmsp = (s.game_flags >> GM_GAMESPEED_SHIFT) & GM_GAMESPEED_MASK;
|
||||||
|
if (tmsp) timerspeed_val = tmsp;
|
||||||
i=s.picks;
|
i=s.picks;
|
||||||
if (picked_item!=NULL) free(picked_item);
|
if (picked_item!=NULL) free(picked_item);
|
||||||
if (i)
|
if (i)
|
||||||
|
@ -685,6 +721,7 @@ int load_basic_info()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res|=load_dialog_info(f);
|
res|=load_dialog_info(f);
|
||||||
|
res|=load_destroyed_items(f);
|
||||||
temp_storage_close_rd(f);
|
temp_storage_close_rd(f);
|
||||||
viewsector=s.viewsector;
|
viewsector=s.viewsector;
|
||||||
viewdir=s.viewdir;
|
viewdir=s.viewdir;
|
||||||
|
@ -776,11 +813,12 @@ int save_game(long game_time,char *gamename, char is_autosave)
|
||||||
temp_storage_store("playtime",&new_play_time, sizeof(new_play_time));
|
temp_storage_store("playtime",&new_play_time, sizeof(new_play_time));
|
||||||
|
|
||||||
svf=fopen_icase(sn,"wb");
|
svf=fopen_icase(sn,"wb");
|
||||||
if (svf==NULL)
|
if (svf==NULL){
|
||||||
{
|
if (!is_autosave) {
|
||||||
char buff[256];
|
char buff[256];
|
||||||
sprintf(buff,"Nelze ulozit pozici na cestu: %s", sn);
|
sprintf(buff,"Failed to create savegame at path %s", sn);
|
||||||
display_error(buff);
|
message(1,0,0,"",buff,texty[80]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1769,12 +1807,12 @@ void wire_save_load(char save) {
|
||||||
change_click_map(clk_save,CLK_SAVELOAD);
|
change_click_map(clk_save,CLK_SAVELOAD);
|
||||||
redraw_save();
|
redraw_save();
|
||||||
send_message(E_ADD, E_KEYBOARD, saveload_keyboard);
|
send_message(E_ADD, E_KEYBOARD, saveload_keyboard);
|
||||||
effect_show(NULL);
|
effect_show();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
curcolor = 0;
|
curcolor = 0;
|
||||||
redraw_load();
|
redraw_load();
|
||||||
effect_show(NULL);
|
effect_show();
|
||||||
if (save == 2)
|
if (save == 2)
|
||||||
change_click_map(clk_load_error, CLK_LOAD_ERROR);
|
change_click_map(clk_load_error, CLK_LOAD_ERROR);
|
||||||
else if (save == 4) {
|
else if (save == 4) {
|
||||||
|
|
|
@ -12,6 +12,10 @@
|
||||||
#define POCET_POSTAV 6
|
#define POCET_POSTAV 6
|
||||||
#define HODINA 360
|
#define HODINA 360
|
||||||
|
|
||||||
|
#define GAMESPEED 5
|
||||||
|
#define GAMESPEED_FASTBATTLE 2
|
||||||
|
|
||||||
|
|
||||||
#define MAX_FILESYSTEM_PATH 256
|
#define MAX_FILESYSTEM_PATH 256
|
||||||
|
|
||||||
#define A_SIDEMAP 0x8001
|
#define A_SIDEMAP 0x8001
|
||||||
|
@ -573,6 +577,7 @@ extern int mapsize; //pocet sektoru v mape
|
||||||
extern int hl_ptr; //ukazatel na konec staticke tabulky registraci
|
extern int hl_ptr; //ukazatel na konec staticke tabulky registraci
|
||||||
extern int end_ptr; //ukazatel na uplny konec tabulky registraci
|
extern int end_ptr; //ukazatel na uplny konec tabulky registraci
|
||||||
extern short **map_items; //ukazatel na mapu predmetu
|
extern short **map_items; //ukazatel na mapu predmetu
|
||||||
|
extern short *destroyed_items; //list of destroyed items to be returned to the game
|
||||||
extern int default_ms_cursor; //cislo zakladniho mysiho kurzoru
|
extern int default_ms_cursor; //cislo zakladniho mysiho kurzoru
|
||||||
extern void (*unwire_proc)(void); //procedura zajistujici odpojeni prave ukoncovane interakce
|
extern void (*unwire_proc)(void); //procedura zajistujici odpojeni prave ukoncovane interakce
|
||||||
extern void (*wire_proc)(void); //procedura zajistujici pripojeni drive ukoncene interakce
|
extern void (*wire_proc)(void); //procedura zajistujici pripojeni drive ukoncene interakce
|
||||||
|
@ -581,8 +586,8 @@ extern word minimap[VIEW3D_Z+1][VIEW3D_X*2+1]; //minimalizovana mapa s informace
|
||||||
extern char norefresh; //vypina refresh obrazovky
|
extern char norefresh; //vypina refresh obrazovky
|
||||||
extern char cancel_pass; //okamzite zrusi plynuly prechod
|
extern char cancel_pass; //okamzite zrusi plynuly prechod
|
||||||
extern char reverse_draw ; //kresba odpredu dozadu
|
extern char reverse_draw ; //kresba odpredu dozadu
|
||||||
extern char gamespeed; //rychlost hry
|
extern uint8_t gamespeed; //rychlost hry
|
||||||
extern char gamespeedbattle; //akcelerace rychlosti pro bitvy
|
extern uint8_t gamespeedbattle; //akcelerace rychlosti pro bitvy
|
||||||
extern int num_ofsets[]; //tabulka offsetu pro steny
|
extern int num_ofsets[]; //tabulka offsetu pro steny
|
||||||
extern int back_color; //cislo barvy pozadi
|
extern int back_color; //cislo barvy pozadi
|
||||||
extern uint8_t cur_group; //cislo aktualni skupiny
|
extern uint8_t cur_group; //cislo aktualni skupiny
|
||||||
|
@ -986,10 +991,10 @@ char pick_item_(int id,int xa,int ya,int xr,int yr);
|
||||||
void wire_inv_mode(THUMAN *select);
|
void wire_inv_mode(THUMAN *select);
|
||||||
void init_inventory(void);
|
void init_inventory(void);
|
||||||
void init_items(void);
|
void init_items(void);
|
||||||
void push_item(int sect,int pos,short *picked_item);
|
void push_item(int sect,int pos,const short *picked_item);
|
||||||
void pop_item(int sect,int pos,int mask,short **picked_item);
|
void pop_item(int sect,int pos,int mask,short **picked_item);
|
||||||
int count_items_inside(short *place);
|
int count_items_inside(const short *place);
|
||||||
int count_items_total(short *place);
|
int count_items_total(const short *place);
|
||||||
char put_item_to_inv(THUMAN *p,short *picked_items); //funkce vklada predmet(y) do batohu postavy
|
char put_item_to_inv(THUMAN *p,short *picked_items); //funkce vklada predmet(y) do batohu postavy
|
||||||
void pick_set_cursor(void); //nastavuje kurzor podle vlozeneho predmetu;
|
void pick_set_cursor(void); //nastavuje kurzor podle vlozeneho predmetu;
|
||||||
void calc_fly(THE_TIMER *t);
|
void calc_fly(THE_TIMER *t);
|
||||||
|
@ -1402,7 +1407,7 @@ void destroy_all_fly();
|
||||||
void stop_fly(LETICI_VEC *p,char zvuk);
|
void stop_fly(LETICI_VEC *p,char zvuk);
|
||||||
void herni_cas(char *s);
|
void herni_cas(char *s);
|
||||||
|
|
||||||
|
typedef char **TSTR_LIST;
|
||||||
|
|
||||||
//gamesaver
|
//gamesaver
|
||||||
void leave_current_map(void);
|
void leave_current_map(void);
|
||||||
|
@ -1415,6 +1420,7 @@ int save_game(long game_time,char *gamename, char is_autosave);
|
||||||
void save_map_description(TMPFILE_WR *f);
|
void save_map_description(TMPFILE_WR *f);
|
||||||
void load_map_description(TMPFILE_RD *f);
|
void load_map_description(TMPFILE_RD *f);
|
||||||
void free_map_description();
|
void free_map_description();
|
||||||
|
TSTR_LIST swap_map_description(TSTR_LIST new_list);
|
||||||
void wire_save_load(char save);
|
void wire_save_load(char save);
|
||||||
void do_save_dialog();
|
void do_save_dialog();
|
||||||
char ask_save_dialog(char *name_buffer, size_t name_size, char allow_remove);
|
char ask_save_dialog(char *name_buffer, size_t name_size, char allow_remove);
|
||||||
|
@ -1762,8 +1768,8 @@ char clk_enter(int id,int xa,int ya,int xr,int yr);
|
||||||
//menu
|
//menu
|
||||||
int enter_menu(char open); //task!
|
int enter_menu(char open); //task!
|
||||||
void titles(va_list args); //task!
|
void titles(va_list args); //task!
|
||||||
void run_titles(va_list args); //task!
|
void run_titles(void );
|
||||||
void effect_show(va_list args); //effektni zobrazeni // task!
|
void effect_show(void); //effektni zobrazeni
|
||||||
void konec_hry(void);
|
void konec_hry(void);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -630,13 +630,14 @@ struct _tag_map_save_state{
|
||||||
TSTENA *_map_sides;
|
TSTENA *_map_sides;
|
||||||
TSECTOR *_map_sectors;
|
TSECTOR *_map_sectors;
|
||||||
TMAP_EDIT_INFO *_map_coord;
|
TMAP_EDIT_INFO *_map_coord;
|
||||||
|
TSTR_LIST _map_desc;
|
||||||
int _map_size;
|
int _map_size;
|
||||||
int _viewsector;
|
int _viewsector;
|
||||||
int _viewdir;
|
int _viewdir;
|
||||||
uint32_t _hash;
|
uint32_t _hash;
|
||||||
} MAP_SAVE_STATE;
|
} MAP_SAVE_STATE;
|
||||||
|
|
||||||
static struct _tag_map_save_state save_state = {NULL,NULL,NULL,0,0,0,0};
|
static struct _tag_map_save_state save_state = {NULL,NULL,NULL,NULL,0,0,0,0};
|
||||||
|
|
||||||
static void save_current_map() {
|
static void save_current_map() {
|
||||||
if (save_state._map_coord) {
|
if (save_state._map_coord) {
|
||||||
|
@ -647,6 +648,7 @@ static void save_current_map() {
|
||||||
save_state._map_coord = map_coord;
|
save_state._map_coord = map_coord;
|
||||||
save_state._map_sectors = map_sectors;
|
save_state._map_sectors = map_sectors;
|
||||||
save_state._map_size = mapsize;
|
save_state._map_size = mapsize;
|
||||||
|
save_state._map_desc = swap_map_description(NULL);
|
||||||
save_state._viewsector = viewsector;
|
save_state._viewsector = viewsector;
|
||||||
save_state._viewdir = viewdir;
|
save_state._viewdir = viewdir;
|
||||||
save_state._hash = current_map_hash;
|
save_state._hash = current_map_hash;
|
||||||
|
@ -661,6 +663,7 @@ static void restore_saved_map() {
|
||||||
free(map_sides);
|
free(map_sides);
|
||||||
free(map_sectors);
|
free(map_sectors);
|
||||||
free(map_coord);
|
free(map_coord);
|
||||||
|
free_map_description();
|
||||||
mapsize =save_state._map_size;
|
mapsize =save_state._map_size;
|
||||||
map_sides = save_state._map_sides;
|
map_sides = save_state._map_sides;
|
||||||
map_sectors = save_state._map_sectors;
|
map_sectors = save_state._map_sectors;
|
||||||
|
@ -668,9 +671,11 @@ static void restore_saved_map() {
|
||||||
viewsector = save_state._viewsector;
|
viewsector = save_state._viewsector;
|
||||||
viewdir = save_state._viewdir;
|
viewdir = save_state._viewdir;
|
||||||
current_map_hash = save_state._hash;
|
current_map_hash = save_state._hash;
|
||||||
|
swap_map_description(save_state._map_desc);
|
||||||
save_state._map_sides = NULL;
|
save_state._map_sides = NULL;
|
||||||
save_state._map_coord = NULL;
|
save_state._map_coord = NULL;
|
||||||
save_state._map_sectors = NULL;
|
save_state._map_sectors = NULL;
|
||||||
|
save_state._map_desc = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1486,8 +1486,9 @@ int smlouvat_prodej(int cena,int ponuka,int posledni,int puvod,int pocet)
|
||||||
|
|
||||||
if (ponuka==0) return 0;
|
if (ponuka==0) return 0;
|
||||||
if (ponuka<=cena) return 0;
|
if (ponuka<=cena) return 0;
|
||||||
if (posledni!=0) if (ponuka>=posledni || ponuka>min) return 1;
|
if (ponuka <= min && (posledni==0 || ponuka<posledni)) {
|
||||||
if (p_ok>r_ok) return 0;
|
if (p_ok>r_ok) return 0;
|
||||||
|
}
|
||||||
if (p_ok>75) return 2;
|
if (p_ok>75) return 2;
|
||||||
if (p_ok>50) return 3;
|
if (p_ok>50) return 3;
|
||||||
if (p_ok>25) return 4;
|
if (p_ok>25) return 4;
|
||||||
|
@ -1544,7 +1545,7 @@ THAGGLERESULT smlouvat_dlg(int cena,int puvod,int pocet,int posledni, int money,
|
||||||
define(-1,150,15,100,13,0,label,int2ascii(cena,buffer,10));
|
define(-1,150,15,100,13,0,label,int2ascii(cena,buffer,10));
|
||||||
set_font(H_FBOLD,MSG_COLOR1);
|
set_font(H_FBOLD,MSG_COLOR1);
|
||||||
define(-1,10,30,1,1,0,label,texty[238]);
|
define(-1,10,30,1,1,0,label,texty[238]);
|
||||||
define(10,150,30,100,13,0,input_line,8,0,0,"");property(def_border(5,BAR_COLOR),NULL,NULL,0);set_default("");
|
define(10,150,30,100,13,0,input_line,7,0,0,"");property(def_border(5,BAR_COLOR),NULL,NULL,0);set_default("");
|
||||||
on_control_event(smlouvat_enter);
|
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(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);
|
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);
|
||||||
|
|
60
game/inv.c
60
game/inv.c
|
@ -432,7 +432,7 @@ void draw_placed_items_normal(int celx,int cely,int sect,int side)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int count_items_total(short *place)
|
int count_items_total(const short *place)
|
||||||
{
|
{
|
||||||
int c=0;
|
int c=0;
|
||||||
|
|
||||||
|
@ -441,7 +441,7 @@ int count_items_total(short *place)
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
int count_items_visible(short *place)
|
int count_items_visible(const short *place)
|
||||||
{
|
{
|
||||||
int c=0;
|
int c=0;
|
||||||
|
|
||||||
|
@ -455,7 +455,7 @@ int count_items_visible(short *place)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int count_items_inside(short *place)
|
int count_items_inside(const short *place)
|
||||||
{
|
{
|
||||||
int c=1;
|
int c=1;
|
||||||
|
|
||||||
|
@ -479,43 +479,37 @@ int find_item(short *place,int mask)
|
||||||
return lastitem;
|
return lastitem;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lastsector;
|
void push_to_destroyed_items(const short *picked_items) {
|
||||||
|
int new_count = count_items_total(picked_items);
|
||||||
static char ValidateSector(word sector, void *_)
|
if (new_count == 0) return;
|
||||||
{
|
int cur_destroyed = count_items_total(destroyed_items);
|
||||||
int pp=map_sectors[sector].sector_type;
|
short *nw = NewArr(short, new_count+cur_destroyed+1);
|
||||||
if (pp==S_NORMAL || pp==S_SMER || pp==S_LEAVE || pp==S_FLT_SMER)
|
for (int i = 0; i < new_count; ++i) {
|
||||||
{
|
nw[i] = abs(picked_items[i]);
|
||||||
lastsector=sector;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
for (int i = 0; i < cur_destroyed; ++i) {
|
||||||
|
nw[new_count+i] = destroyed_items[i];
|
||||||
|
}
|
||||||
|
nw[new_count+cur_destroyed] = 0;
|
||||||
|
free(destroyed_items);
|
||||||
|
destroyed_items = nw;
|
||||||
|
}
|
||||||
|
|
||||||
void push_item(int sect,int pos,short *picked_item)
|
void push_item(int sect,int pos,const short *picked_item)
|
||||||
{
|
{
|
||||||
int bc;
|
int bc;
|
||||||
int pc;
|
int pc;
|
||||||
int tc;
|
int tc;
|
||||||
short *p;
|
short *p;
|
||||||
|
char s = map_sectors[sect].sector_type;
|
||||||
|
|
||||||
if (map_sectors[sect].sector_type==S_DIRA || ISTELEPORTSECT(sect))
|
|
||||||
|
if (s==S_DIRA || ISTELEPORTSECT(sect) || s == S_SCHODY)
|
||||||
sect=map_sectors[sect].sector_tag;
|
sect=map_sectors[sect].sector_tag;
|
||||||
if (sect==0 || map_sectors[sect].sector_type==S_VODA)
|
if (sect==0 || s==S_VODA || s == S_LAVA || s == S_SSMRT || s == S_LODKA) {
|
||||||
{
|
push_to_destroyed_items(picked_item);
|
||||||
if (game_extras & EX_RECOVER_DESTROYED_ITEMS)
|
return;
|
||||||
{
|
}
|
||||||
labyrinth_find_path(viewsector,65535,SD_PLAY_IMPS,ValidateSector,NULL, NULL);
|
|
||||||
push_item(lastsector,viewdir,picked_item);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
free(picked_item);
|
|
||||||
picked_item=NULL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sect=(sect<<2)+pos;
|
sect=(sect<<2)+pos;
|
||||||
bc=count_items_total(map_items[sect]);
|
bc=count_items_total(map_items[sect]);
|
||||||
pc=count_items_total(picked_item);
|
pc=count_items_total(picked_item);
|
||||||
|
@ -682,7 +676,7 @@ char pick_item_(int id,int xa,int ya,int xr,int yr)
|
||||||
idd=(id+viewdir)&0x3;
|
idd=(id+viewdir)&0x3;
|
||||||
if (picked_item!=NULL)
|
if (picked_item!=NULL)
|
||||||
{
|
{
|
||||||
if (map_sectors[sect].sector_type==S_DIRA)
|
if (map_sectors[sect].sector_type==S_DIRA)
|
||||||
{
|
{
|
||||||
throw_fly(xa,ya,0);
|
throw_fly(xa,ya,0);
|
||||||
letici_veci->speed=0;
|
letici_veci->speed=0;
|
||||||
|
@ -2494,7 +2488,6 @@ static int shop_sector;
|
||||||
T_CLK_MAP clk_shop[]=
|
T_CLK_MAP clk_shop[]=
|
||||||
{
|
{
|
||||||
{-1,54,378,497,479,shop_change_player,2+8,-1},
|
{-1,54,378,497,479,shop_change_player,2+8,-1},
|
||||||
{-1,0,0,639,479,_exit_shop,8,-1},
|
|
||||||
{-1,INV_X,INV_Y,INV_X+INV_XS*6,INV_Y+INV_YS*5,shop_bag_click,MS_EVENT_MOUSE_LPRESS,-1},
|
{-1,INV_X,INV_Y,INV_X+INV_XS*6,INV_Y+INV_YS*5,shop_bag_click,MS_EVENT_MOUSE_LPRESS,-1},
|
||||||
{1,2+BUYBOX_X,39+BUYBOX_Y,22+BUYBOX_X,76+BUYBOX_Y,shop_block_click,2,H_MS_DEFAULT},
|
{1,2+BUYBOX_X,39+BUYBOX_Y,22+BUYBOX_X,76+BUYBOX_Y,shop_block_click,2,H_MS_DEFAULT},
|
||||||
{2,246+BUYBOX_X,39+BUYBOX_Y,266+BUYBOX_X,76+BUYBOX_Y,shop_block_click,2,H_MS_DEFAULT},
|
{2,246+BUYBOX_X,39+BUYBOX_Y,266+BUYBOX_X,76+BUYBOX_Y,shop_block_click,2,H_MS_DEFAULT},
|
||||||
|
@ -2503,6 +2496,7 @@ T_CLK_MAP clk_shop[]=
|
||||||
{-1,337,0,357,14,go_map,2,H_MS_DEFAULT},
|
{-1,337,0,357,14,go_map,2,H_MS_DEFAULT},
|
||||||
{-1,87,0,142,14,game_setup,2,H_MS_DEFAULT},
|
{-1,87,0,142,14,game_setup,2,H_MS_DEFAULT},
|
||||||
{-1,30,0,85,14,konec,2,H_MS_DEFAULT},
|
{-1,30,0,85,14,konec,2,H_MS_DEFAULT},
|
||||||
|
{-1,0,0,639,479,_exit_shop,8,-1},
|
||||||
};
|
};
|
||||||
|
|
||||||
static void shop_mouse_event(EVENT_MSG *msg,void **unused)
|
static void shop_mouse_event(EVENT_MSG *msg,void **unused)
|
||||||
|
|
24
game/menu.c
24
game/menu.c
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#include "ach_events.h"
|
#include "ach_events.h"
|
||||||
#include "lang.h"
|
#include "lang.h"
|
||||||
|
#include <version.h>
|
||||||
|
|
||||||
#define MUSIC "TRACK06.MUS"
|
#define MUSIC "TRACK06.MUS"
|
||||||
|
|
||||||
|
@ -334,6 +335,12 @@ static void klavesnice(EVENT_MSG *msg,void **unused)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void show_version() {
|
||||||
|
const char *verstr = "Version: " SKELDAL_VERSION;
|
||||||
|
set_font(H_FLITT5, RGB888(255,255,255));
|
||||||
|
set_aligned_position(639, 479, 2, 2, verstr);
|
||||||
|
outtext(verstr);
|
||||||
|
}
|
||||||
|
|
||||||
int enter_menu(char open)
|
int enter_menu(char open)
|
||||||
{
|
{
|
||||||
|
@ -350,8 +357,9 @@ int enter_menu(char open)
|
||||||
put_picture(0,0,ablock(H_MENU_BAR));
|
put_picture(0,0,ablock(H_MENU_BAR));
|
||||||
put_picture(0,56,ablock(H_ANIM));
|
put_picture(0,56,ablock(H_ANIM));
|
||||||
ukaz_mysku();
|
ukaz_mysku();
|
||||||
effect_show(NULL);
|
show_version();
|
||||||
//if (open) effect_show(NULL);else showview(0,0,0,0);
|
effect_show();
|
||||||
|
|
||||||
change_click_map(clk_main_menu,CLK_MAIN_MENU);
|
change_click_map(clk_main_menu,CLK_MAIN_MENU);
|
||||||
send_message(E_ADD,E_TIMER,prehraj_animaci_v_menu);
|
send_message(E_ADD,E_TIMER,prehraj_animaci_v_menu);
|
||||||
send_message(E_ADD,E_KEYBOARD,klavesnice);
|
send_message(E_ADD,E_KEYBOARD,klavesnice);
|
||||||
|
@ -552,7 +560,7 @@ void titles(va_list args)
|
||||||
alock(H_PICTURE);
|
alock(H_PICTURE);
|
||||||
picture=ablock(H_PICTURE);
|
picture=ablock(H_PICTURE);
|
||||||
put_picture(0,0,picture);
|
put_picture(0,0,picture);
|
||||||
effect_show(NULL);
|
effect_show();
|
||||||
titlefont=H_FBIG;
|
titlefont=H_FBIG;
|
||||||
set_font(titlefont,RGB(158,210,25));charcolors[1]=0;
|
set_font(titlefont,RGB(158,210,25));charcolors[1]=0;
|
||||||
counter=get_timer_value();newc=counter;
|
counter=get_timer_value();newc=counter;
|
||||||
|
@ -604,7 +612,7 @@ void titles(va_list args)
|
||||||
if (send_back)send_message(E_KEYBOARD,27);
|
if (send_back)send_message(E_KEYBOARD,27);
|
||||||
}
|
}
|
||||||
|
|
||||||
void run_titles(va_list args)
|
void run_titles(void)
|
||||||
{
|
{
|
||||||
int task_id;
|
int task_id;
|
||||||
task_id=add_task(8196,titles,1,"titulky.TXT");
|
task_id=add_task(8196,titles,1,"titulky.TXT");
|
||||||
|
@ -612,16 +620,16 @@ void run_titles(va_list args)
|
||||||
term_task(task_id);
|
term_task(task_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void konec_hry()
|
void konec_hry(void)
|
||||||
{
|
{
|
||||||
int task_id;
|
int task_id;
|
||||||
int timer;
|
int timer;
|
||||||
|
|
||||||
|
|
||||||
schovej_mysku();
|
schovej_mysku();
|
||||||
curcolor=0;
|
curcolor=0;
|
||||||
bar32(0,0,639,479);
|
bar32(0,0,639,479);
|
||||||
effect_show(NULL);
|
effect_show();
|
||||||
create_playlist(texty[205]);
|
create_playlist(texty[205]);
|
||||||
change_music(get_next_music_from_playlist());
|
change_music(get_next_music_from_playlist());
|
||||||
timer=get_timer_value();
|
timer=get_timer_value();
|
||||||
|
@ -641,7 +649,7 @@ void konec_hry()
|
||||||
curcolor=0;
|
curcolor=0;
|
||||||
bar32(0,0,639,479);
|
bar32(0,0,639,479);
|
||||||
ukaz_mysku();
|
ukaz_mysku();
|
||||||
effect_show(NULL);
|
effect_show();
|
||||||
timer=get_timer_value();
|
timer=get_timer_value();
|
||||||
while (get_timer_value()-timer<150) task_sleep();
|
while (get_timer_value()-timer<150) task_sleep();
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,8 @@ TSTENA *map_sides;
|
||||||
TSECTOR *map_sectors;
|
TSECTOR *map_sectors;
|
||||||
TVYKLENEK *map_vyk; //mapa vyklenku
|
TVYKLENEK *map_vyk; //mapa vyklenku
|
||||||
word vyk_max; //pocet vyklenku v mape
|
word vyk_max; //pocet vyklenku v mape
|
||||||
short **map_items;
|
short **map_items = 0;
|
||||||
|
short *destroyed_items = 0;;
|
||||||
char *flag_map;
|
char *flag_map;
|
||||||
TMAP_EDIT_INFO *map_coord;
|
TMAP_EDIT_INFO *map_coord;
|
||||||
TSTR_LIST level_texts;
|
TSTR_LIST level_texts;
|
||||||
|
|
12
game/setup.c
12
game/setup.c
|
@ -44,7 +44,7 @@ static void checkbox_animator(THE_TIMER *t)
|
||||||
animate_checkbox(10,130,10);
|
animate_checkbox(10,130,10);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int effects[]={SND_GVOLUME,SND_MUSIC,SND_GFX,SND_TREBL,SND_BASS,SND_XBASS};
|
static int effects[]={SND_GVOLUME,SND_MUSIC,SND_GFX,SND_TREBL,SND_BASS};
|
||||||
|
|
||||||
static void do_setup_change(void)
|
static void do_setup_change(void)
|
||||||
{
|
{
|
||||||
|
@ -55,6 +55,7 @@ static void do_setup_change(void)
|
||||||
{
|
{
|
||||||
case 10:set_snd_effect(SND_SWAP,c & 1);break;
|
case 10:set_snd_effect(SND_SWAP,c & 1);break;
|
||||||
case 20:set_snd_effect(SND_OUTFILTER,c & 1);break;
|
case 20:set_snd_effect(SND_OUTFILTER,c & 1);break;
|
||||||
|
case 250:timerspeed_val = TIMERSPEED- c;break;
|
||||||
default:set_snd_effect(effects[o_aktual->id/10-20],c);break;
|
default:set_snd_effect(effects[o_aktual->id/10-20],c);break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,7 +112,7 @@ static void unwire_setup(void)
|
||||||
enable_sort=f_get_value(0,100) & 1;
|
enable_sort=f_get_value(0,100) & 1;
|
||||||
autoattack=f_get_value(0,110) & 1;
|
autoattack=f_get_value(0,110) & 1;
|
||||||
autosave_enabled=f_get_value(0,120) & 1;
|
autosave_enabled=f_get_value(0,120) & 1;
|
||||||
level_preload=f_get_value(0,130) & 1;
|
gamespeedbattle=(f_get_value(0,130) & 1)?GAMESPEED_FASTBATTLE:gamespeed;
|
||||||
delete_from_timer(TM_CHECKBOX);
|
delete_from_timer(TM_CHECKBOX);
|
||||||
mix_back_sound(32768);
|
mix_back_sound(32768);
|
||||||
close_current();
|
close_current();
|
||||||
|
@ -187,8 +188,8 @@ void new_setup()
|
||||||
case 0:c_default(show_names);break;
|
case 0:c_default(show_names);break;
|
||||||
case 1:c_default(enable_sort);break;
|
case 1:c_default(enable_sort);break;
|
||||||
case 2:c_default(autoattack);break;
|
case 2:c_default(autoattack);break;
|
||||||
case 3:c_default(1);break;
|
case 3:c_default(autosave_enabled);break;
|
||||||
case 4:c_default(level_preload);break;
|
case 4:c_default(gamespeedbattle < gamespeed);break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,6 +202,9 @@ void new_setup()
|
||||||
define(200+i*10,50+i*60,30,30,200,0,skeldal_soupak,effects[i]==SND_MUSIC?127:255);c_default(get_snd_effect(effects[i]));
|
define(200+i*10,50+i*60,30,30,200,0,skeldal_soupak,effects[i]==SND_MUSIC?127:255);c_default(get_snd_effect(effects[i]));
|
||||||
on_control_change(do_setup_change);
|
on_control_change(do_setup_change);
|
||||||
}
|
}
|
||||||
|
define(200+5*10,50+5*60,30,30,200,0,skeldal_soupak,TIMERSPEED-1);c_default(timerspeed_val >TIMERSPEED?0:TIMERSPEED - timerspeed_val);
|
||||||
|
on_control_change(do_setup_change);
|
||||||
|
|
||||||
define(300,559,336,81,21,0,setup_ok_button,texty[174]);on_control_change(exit_setup_action);
|
define(300,559,336,81,21,0,setup_ok_button,texty[174]);on_control_change(exit_setup_action);
|
||||||
property(NULL,ablock(H_FTINY),&color_topbar,0);
|
property(NULL,ablock(H_FTINY),&color_topbar,0);
|
||||||
redraw_window();
|
redraw_window();
|
||||||
|
|
|
@ -75,12 +75,13 @@ typedef struct inis
|
||||||
THE_TIMER timer_tree;
|
THE_TIMER timer_tree;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int hl_ptr=H_FIRST_FREE;
|
int hl_ptr=H_FIRST_FREE;
|
||||||
int debug_enabled=0;
|
int debug_enabled=0;
|
||||||
char sound_detection=1;
|
char sound_detection=1;
|
||||||
int snd_devnum,snd_parm1,snd_parm2,snd_parm3,snd_mixing=22000;
|
int snd_devnum,snd_parm1,snd_parm2,snd_parm3,snd_mixing=22000;
|
||||||
char gamespeed=5;
|
uint8_t gamespeed=GAMESPEED;
|
||||||
char gamespeedbattle=0;
|
uint8_t gamespeedbattle=GAMESPEED;
|
||||||
char level_preload=1;
|
char level_preload=1;
|
||||||
char *level_fname=NULL;
|
char *level_fname=NULL;
|
||||||
int game_extras=0;
|
int game_extras=0;
|
||||||
|
@ -827,6 +828,8 @@ void cti_texty(void)
|
||||||
//patch stringtable
|
//patch stringtable
|
||||||
if (!texty[98]) str_replace(&texty,98,"Ulo\x91it hru jako");
|
if (!texty[98]) str_replace(&texty,98,"Ulo\x91it hru jako");
|
||||||
if (!texty[99]) str_replace(&texty,99,"CRT Filter (>720p)");
|
if (!texty[99]) str_replace(&texty,99,"CRT Filter (>720p)");
|
||||||
|
str_replace(&texty, 144, "Zrychlit souboje");
|
||||||
|
str_replace(&texty, 51, "Celkov\x88 Hudba Efekty V\x98\xA8ky Basy Rychlost");
|
||||||
str_replace(&texty,0,"Byl nalezen p\xA9ipojen\x98 ovlada\x87\nPro aktivaci ovlada\x87""e stiskn\x88te kter\x82koliv tla\x87\xA1tko na ovlada\x87i");
|
str_replace(&texty,0,"Byl nalezen p\xA9ipojen\x98 ovlada\x87\nPro aktivaci ovlada\x87""e stiskn\x88te kter\x82koliv tla\x87\xA1tko na ovlada\x87i");
|
||||||
lang_patch_stringtable(&texty, "ui.csv", "");
|
lang_patch_stringtable(&texty, "ui.csv", "");
|
||||||
}
|
}
|
||||||
|
@ -1622,7 +1625,7 @@ static void start(va_list args)
|
||||||
openning =0;
|
openning =0;
|
||||||
break;
|
break;
|
||||||
case V_OBNOVA_HRY:load_saved_game();break;
|
case V_OBNOVA_HRY:load_saved_game();break;
|
||||||
case V_AUTORI:run_titles(NULL);break;
|
case V_AUTORI:run_titles();break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (!exit_wait);
|
while (!exit_wait);
|
||||||
|
|
|
@ -678,6 +678,7 @@ void zacatek_kola()
|
||||||
viewsector=postavy[select_player].sektor;
|
viewsector=postavy[select_player].sektor;
|
||||||
viewdir=postavy[select_player].direction;
|
viewdir=postavy[select_player].direction;
|
||||||
redraw_scene();
|
redraw_scene();
|
||||||
|
recalc_volumes(viewsector,viewdir);
|
||||||
}
|
}
|
||||||
|
|
||||||
char check_end_game()
|
char check_end_game()
|
||||||
|
@ -878,7 +879,7 @@ char JePozdrzeno()
|
||||||
|
|
||||||
void pozdrz_akci()
|
void pozdrz_akci()
|
||||||
{
|
{
|
||||||
int battlespeed=gamespeed-gamespeed*gamespeedbattle/5;
|
int battlespeed=gamespeedbattle;
|
||||||
SPozdrzeno=get_game_tick_count()+battlespeed*2000/6;
|
SPozdrzeno=get_game_tick_count()+battlespeed*2000/6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -905,6 +906,7 @@ void prejdi_na_pohled(THUMAN *p)
|
||||||
{
|
{
|
||||||
viewsector=p->sektor;
|
viewsector=p->sektor;
|
||||||
viewdir=p->direction;
|
viewdir=p->direction;
|
||||||
|
recalc_volumes(viewsector,viewdir);
|
||||||
pozdrz_akci();
|
pozdrz_akci();
|
||||||
hold_timer(TM_SCENE,1);
|
hold_timer(TM_SCENE,1);
|
||||||
redraw_scene();
|
redraw_scene();
|
||||||
|
@ -1144,7 +1146,7 @@ static void pouzij_svitek(THUMAN *p,int ruka)
|
||||||
static void play_weapon_anim(int anim_num,int hitpos)
|
static void play_weapon_anim(int anim_num,int hitpos)
|
||||||
{
|
{
|
||||||
char count_save=global_anim_counter;
|
char count_save=global_anim_counter;
|
||||||
int battlespeed=gamespeed-gamespeed*gamespeedbattle/5;
|
int battlespeed=gamespeedbattle;
|
||||||
|
|
||||||
if (anim_num==0) return;
|
if (anim_num==0) return;
|
||||||
hold_timer(TM_SCENE,1);
|
hold_timer(TM_SCENE,1);
|
||||||
|
@ -1440,6 +1442,7 @@ void jadro_souboje(EVENT_MSG *msg,void **unused) //!!!! Jadro souboje
|
||||||
viewsector=postavy[i].sektor;
|
viewsector=postavy[i].sektor;
|
||||||
viewdir=postavy[i].direction;
|
viewdir=postavy[i].direction;
|
||||||
build_player_map();
|
build_player_map();
|
||||||
|
recalc_volumes(viewsector,viewdir);
|
||||||
GlobEvent(MAGLOB_AFTERBATTLE,viewsector,viewdir);
|
GlobEvent(MAGLOB_AFTERBATTLE,viewsector,viewdir);
|
||||||
autosave();
|
autosave();
|
||||||
}
|
}
|
||||||
|
@ -1450,7 +1453,7 @@ void jadro_souboje(EVENT_MSG *msg,void **unused) //!!!! Jadro souboje
|
||||||
|
|
||||||
void wire_jadro_souboje(void)
|
void wire_jadro_souboje(void)
|
||||||
{
|
{
|
||||||
int battlespeed=gamespeed-gamespeed*gamespeedbattle/5;
|
int battlespeed=gamespeedbattle;
|
||||||
recalc_volumes(viewsector,viewdir);
|
recalc_volumes(viewsector,viewdir);
|
||||||
if (battlespeed<1) battlespeed=1;
|
if (battlespeed<1) battlespeed=1;
|
||||||
add_to_timer(TM_SCENE,battlespeed,-1,hrat_souboj);
|
add_to_timer(TM_SCENE,battlespeed,-1,hrat_souboj);
|
||||||
|
@ -1924,6 +1927,7 @@ static void souboje_dalsi()
|
||||||
while ((!postavy[select_player].used || postavy[select_player].inmaphash != current_map_hash || !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;
|
viewsector=postavy[select_player].sektor;
|
||||||
viewdir=postavy[select_player].direction;
|
viewdir=postavy[select_player].direction;
|
||||||
|
recalc_volumes(viewsector,viewdir);
|
||||||
cur_group=postavy[select_player].groupnum;
|
cur_group=postavy[select_player].groupnum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1944,6 +1948,7 @@ static void souboje_dalsi_user() {
|
||||||
viewsector=postavy[select_player].sektor;
|
viewsector=postavy[select_player].sektor;
|
||||||
viewdir=postavy[select_player].direction;
|
viewdir=postavy[select_player].direction;
|
||||||
cur_group=postavy[select_player].groupnum;
|
cur_group=postavy[select_player].groupnum;
|
||||||
|
recalc_volumes(viewsector,viewdir);
|
||||||
}
|
}
|
||||||
|
|
||||||
void souboje_vybrano(int d)
|
void souboje_vybrano(int d)
|
||||||
|
|
|
@ -45,7 +45,7 @@ To activate the controller, press any button on the controller"
|
||||||
48,Start
|
48,Start
|
||||||
49,Throw
|
49,Throw
|
||||||
50,Combat in Progress
|
50,Combat in Progress
|
||||||
51,Overall Music Sounds Treble Bass
|
51,Overall Music Sounds Treble Bass Speed
|
||||||
52,Stereo Settings (Ultrasound)
|
52,Stereo Settings (Ultrasound)
|
||||||
53,Swap Sides
|
53,Swap Sides
|
||||||
54,Output Filter (SBPro)
|
54,Output Filter (SBPro)
|
||||||
|
@ -117,7 +117,7 @@ To activate the controller, press any button on the controller"
|
||||||
141,Rearrange Portraits
|
141,Rearrange Portraits
|
||||||
142,Auto Attack
|
142,Auto Attack
|
||||||
143,Auto Save
|
143,Auto Save
|
||||||
144,Load All Into Memory
|
144,Speed up battles
|
||||||
145,Adventure Length:
|
145,Adventure Length:
|
||||||
146,%d day and
|
146,%d day and
|
||||||
147,%d days and
|
147,%d days and
|
||||||
|
|
|
|
@ -12,7 +12,7 @@ SET(files basicobj.c
|
||||||
mgifplaya.c
|
mgifplaya.c
|
||||||
pcx.c
|
pcx.c
|
||||||
wav_mem.c
|
wav_mem.c
|
||||||
strlists.c
|
strlite.c
|
||||||
cztable.c
|
cztable.c
|
||||||
music.cpp
|
music.cpp
|
||||||
string_table.cpp )
|
string_table.cpp )
|
||||||
|
|
|
@ -95,9 +95,10 @@ elseif(APPLE)
|
||||||
target_sources(skeldal PRIVATE
|
target_sources(skeldal PRIVATE
|
||||||
linux/app_start.cpp
|
linux/app_start.cpp
|
||||||
)
|
)
|
||||||
target_compile_definitions(mylib PRIVATE PLATFORM_MACOS)
|
if(STEAM_ENABLED)
|
||||||
set(STEAMLIB ${STEAMWORKS_SDK_DIR}/redistributable_bin/osx/libsteam_api.dylib)
|
set(STEAMLIB ${STEAMWORKS_SDK_DIR}/redistributable_bin/osx/libsteam_api.dylib)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-declarations")
|
endif()
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-declarations")
|
||||||
message(STATUS "Building for macOS")
|
message(STATUS "Building for macOS")
|
||||||
target_link_libraries(skeldal ${all_libs} ${STEAMLIB})
|
target_link_libraries(skeldal ${all_libs} ${STEAMLIB})
|
||||||
else()
|
else()
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <cstdarg>
|
#include <cstdarg>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
|
|
||||||
|
@ -38,3 +39,18 @@ void send_log_impl(const char *format, ...) {
|
||||||
void throw_exception(const char *text) {
|
void throw_exception(const char *text) {
|
||||||
throw std::runtime_error(std::string("Invoked crash:") + text);
|
throw std::runtime_error(std::string("Invoked crash:") + text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string exception_to_string(const std::exception& e) {
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << e.what();
|
||||||
|
|
||||||
|
try {
|
||||||
|
std::rethrow_if_nested(e);
|
||||||
|
} catch (const std::exception& nested) {
|
||||||
|
oss << "\n\n Reason: " << exception_to_string(nested);
|
||||||
|
} catch (...) {
|
||||||
|
oss << "\n\n Reason: unknown exception of crash";
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::move(oss).str();
|
||||||
|
}
|
||||||
|
|
|
@ -2,6 +2,11 @@
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <exception>
|
||||||
|
std::string exception_to_string(const std::exception& e);
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -10,7 +15,8 @@ void send_log_impl(const char *format, ...);
|
||||||
void display_error(const char *format, ...);
|
void display_error(const char *format, ...);
|
||||||
void throw_exception(const char *text);
|
void throw_exception(const char *text);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -7,23 +7,37 @@
|
||||||
#include "../libs/logfile.h"
|
#include "../libs/logfile.h"
|
||||||
|
|
||||||
|
|
||||||
std::filesystem::path break_and_compose_path(const std::string_view &pathname, char sep) {
|
|
||||||
|
std::filesystem::path break_and_compose_path(std::string_view pathname, char sep) {
|
||||||
|
auto utf8_to_path = [](std::string_view sv) -> std::filesystem::path {
|
||||||
|
return std::filesystem::path(std::u8string(reinterpret_cast<const char8_t*>(sv.data()), sv.size()));
|
||||||
|
};
|
||||||
|
|
||||||
auto p = pathname.rfind(sep);
|
auto p = pathname.rfind(sep);
|
||||||
|
|
||||||
if (p == pathname.npos) {
|
if (p == pathname.npos) {
|
||||||
if (pathname == "." || pathname == "..") {
|
if (pathname == "." || pathname == "..") {
|
||||||
return std::filesystem::canonical(".");
|
return std::filesystem::canonical(".");
|
||||||
} else if (pathname.empty()) {
|
|
||||||
return std::filesystem::current_path().root_path();
|
|
||||||
} else if (pathname == std::filesystem::current_path().root_name()) {
|
|
||||||
return std::filesystem::current_path().root_path();
|
|
||||||
} else {
|
|
||||||
return std::filesystem::current_path()/pathname;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
// Detekce Windows drive letter jako "C:"
|
||||||
return break_and_compose_path(pathname.substr(0,p), sep) / pathname.substr(p+1);
|
if (pathname.size() == 2 && std::isalpha(static_cast<unsigned char>(pathname[0])) && pathname[1] == ':') {
|
||||||
}
|
return utf8_to_path(std::string(pathname) + "\\"); // vždy konstruujeme s \ pro root disku
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kontrola na root (např. "/") – musíme převést pro porovnání
|
||||||
|
if (utf8_to_path(pathname) == std::filesystem::current_path().root_path()) {
|
||||||
|
return std::filesystem::current_path().root_path();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vše ostatní relativně vůči current_path
|
||||||
|
return std::filesystem::current_path() / utf8_to_path(pathname);
|
||||||
|
} else if (p == 0) {
|
||||||
|
return std::filesystem::current_path().root_path() / utf8_to_path(pathname);
|
||||||
|
}
|
||||||
|
|
||||||
|
return break_and_compose_path(pathname.substr(0, p), sep) / utf8_to_path(pathname.substr(p + 1));
|
||||||
|
}
|
||||||
|
|
||||||
std::filesystem::path convert_pathname_to_path(const std::string_view &pathname) {
|
std::filesystem::path convert_pathname_to_path(const std::string_view &pathname) {
|
||||||
auto p = pathname.find('\\');
|
auto p = pathname.find('\\');
|
||||||
|
@ -81,7 +95,12 @@ const char *file_icase_find(const char *pathname) {
|
||||||
|
|
||||||
FILE *fopen_icase(const char *pathname, const char *mode) {
|
FILE *fopen_icase(const char *pathname, const char *mode) {
|
||||||
std::filesystem::path path = try_to_find_file(convert_pathname_to_path(pathname));
|
std::filesystem::path path = try_to_find_file(convert_pathname_to_path(pathname));
|
||||||
|
#ifdef _WIN32
|
||||||
|
std::wstring wmode(mode, mode + std::strlen(mode)); // bezpečnější převod
|
||||||
|
return _wfopen(path.wstring().c_str(), wmode.c_str());
|
||||||
|
#else
|
||||||
return fopen(path.string().c_str(), mode);
|
return fopen(path.string().c_str(), mode);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static thread_local std::string build_pathname_buffer;
|
static thread_local std::string build_pathname_buffer;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "../../game/skeldal.h"
|
#include "../../game/skeldal.h"
|
||||||
#include "../getopt.h"
|
#include "../getopt.h"
|
||||||
#include "../platform.h"
|
#include "../platform.h"
|
||||||
|
#include "../error.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
@ -67,7 +68,7 @@ int main(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
std::cerr << "ERROR: " << e.what() << std::endl;
|
std::cerr << "ERROR: " << exception_to_string(e) << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
#include "map_file.h"
|
#include "map_file.h"
|
||||||
#include "../error.h"
|
#include "../error.h"
|
||||||
}
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
|
@ -1,4 +1,13 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
void *map_file_to_memory(const char *name, size_t *sz);
|
void *map_file_to_memory(const char *name, size_t *sz);
|
||||||
void unmap_file(void *ptr, size_t sz);
|
void unmap_file(void *ptr, size_t sz);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
temp_file=$(mktemp /tmp/skeldal.XXXXXX.log)
|
temp_file=$(mktemp /tmp/skeldal.XXXXXX.log)
|
||||||
CURDIR=`dirname "$0"`
|
CURDIR=`dirname "$0"`
|
||||||
|
|
||||||
|
chmod +x "$CURDIR/skeldal_bin"
|
||||||
LD_LIBRARY_PATH=$CURDIR:$LD_LIBRARY_PATH "$CURDIR/skeldal_bin" $* > "$temp_file" 2>&1
|
LD_LIBRARY_PATH=$CURDIR:$LD_LIBRARY_PATH "$CURDIR/skeldal_bin" $* > "$temp_file" 2>&1
|
||||||
|
|
||||||
exit_code=$?
|
exit_code=$?
|
||||||
|
@ -25,4 +26,3 @@ fi
|
||||||
rm $temp_file
|
rm $temp_file
|
||||||
exit $exit_code
|
exit $exit_code
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,2 +1,6 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <malloc.h>
|
#if defined(__linux__)
|
||||||
|
#include <malloc.h>
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
#include <stdlib.h>
|
||||||
|
#endif
|
||||||
|
|
184
platform/sdl/format_mapping.h
Normal file
184
platform/sdl/format_mapping.h
Normal file
|
@ -0,0 +1,184 @@
|
||||||
|
#pragma once
|
||||||
|
#include <SDL_surface.h>
|
||||||
|
|
||||||
|
|
||||||
|
template<Uint32 format>
|
||||||
|
struct FormatMapping {
|
||||||
|
static_assert(false, "Unsupported pixel format");
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct FormatMapping<SDL_PIXELFORMAT_ARGB2101010> {
|
||||||
|
static constexpr int RShift = 20;
|
||||||
|
static constexpr int GShift = 10;
|
||||||
|
static constexpr int BShift = 0;
|
||||||
|
static constexpr int AShift = 30;
|
||||||
|
|
||||||
|
static constexpr int RBits = 10;
|
||||||
|
static constexpr int GBits = 10;
|
||||||
|
static constexpr int BBits = 10;
|
||||||
|
static constexpr int ABits = 2;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct FormatMapping<SDL_PIXELFORMAT_ABGR8888> {
|
||||||
|
static constexpr int RShift = 0;
|
||||||
|
static constexpr int GShift = 8;
|
||||||
|
static constexpr int BShift = 16;
|
||||||
|
static constexpr int AShift = 24;
|
||||||
|
|
||||||
|
static constexpr int RBits = 8;
|
||||||
|
static constexpr int GBits = 8;
|
||||||
|
static constexpr int BBits = 8;
|
||||||
|
static constexpr int ABits = 8;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct FormatMapping<SDL_PIXELFORMAT_ARGB8888> {
|
||||||
|
static constexpr int RShift = 16;
|
||||||
|
static constexpr int GShift = 8;
|
||||||
|
static constexpr int BShift = 0;
|
||||||
|
static constexpr int AShift = 24;
|
||||||
|
|
||||||
|
static constexpr int RBits = 8;
|
||||||
|
static constexpr int GBits = 8;
|
||||||
|
static constexpr int BBits = 8;
|
||||||
|
static constexpr int ABits = 8;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct FormatMapping<SDL_PIXELFORMAT_RGBA8888> {
|
||||||
|
static constexpr int RShift = 24;
|
||||||
|
static constexpr int GShift = 16;
|
||||||
|
static constexpr int BShift = 8;
|
||||||
|
static constexpr int AShift = 0;
|
||||||
|
|
||||||
|
static constexpr int RBits = 8;
|
||||||
|
static constexpr int GBits = 8;
|
||||||
|
static constexpr int BBits = 8;
|
||||||
|
static constexpr int ABits = 8;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct FormatMapping<SDL_PIXELFORMAT_BGRA8888> {
|
||||||
|
static constexpr int RShift = 8;
|
||||||
|
static constexpr int GShift = 16;
|
||||||
|
static constexpr int BShift = 24;
|
||||||
|
static constexpr int AShift = 0;
|
||||||
|
|
||||||
|
static constexpr int RBits = 8;
|
||||||
|
static constexpr int GBits = 8;
|
||||||
|
static constexpr int BBits = 8;
|
||||||
|
static constexpr int ABits = 8;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct FormatMapping<SDL_PIXELFORMAT_ABGR4444> {
|
||||||
|
static constexpr int RShift = 0;
|
||||||
|
static constexpr int GShift = 4;
|
||||||
|
static constexpr int BShift = 8;
|
||||||
|
static constexpr int AShift = 12;
|
||||||
|
|
||||||
|
static constexpr int RBits = 4;
|
||||||
|
static constexpr int GBits = 4;
|
||||||
|
static constexpr int BBits = 4;
|
||||||
|
static constexpr int ABits = 4;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct FormatMapping<SDL_PIXELFORMAT_ARGB4444> {
|
||||||
|
static constexpr int RShift = 8;
|
||||||
|
static constexpr int GShift = 4;
|
||||||
|
static constexpr int BShift = 0;
|
||||||
|
static constexpr int AShift = 12;
|
||||||
|
|
||||||
|
static constexpr int RBits = 4;
|
||||||
|
static constexpr int GBits = 4;
|
||||||
|
static constexpr int BBits = 4;
|
||||||
|
static constexpr int ABits = 4;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct FormatMapping<SDL_PIXELFORMAT_RGBA4444> {
|
||||||
|
static constexpr int RShift = 12;
|
||||||
|
static constexpr int GShift = 8;
|
||||||
|
static constexpr int BShift = 4;
|
||||||
|
static constexpr int AShift = 0;
|
||||||
|
|
||||||
|
static constexpr int RBits = 4;
|
||||||
|
static constexpr int GBits = 4;
|
||||||
|
static constexpr int BBits = 4;
|
||||||
|
static constexpr int ABits = 4;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct FormatMapping<SDL_PIXELFORMAT_BGRA4444> {
|
||||||
|
static constexpr int RShift = 4;
|
||||||
|
static constexpr int GShift = 8;
|
||||||
|
static constexpr int BShift = 12;
|
||||||
|
static constexpr int AShift = 0;
|
||||||
|
|
||||||
|
static constexpr int RBits = 4;
|
||||||
|
static constexpr int GBits = 4;
|
||||||
|
static constexpr int BBits = 4;
|
||||||
|
static constexpr int ABits = 4;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct FormatMapping<SDL_PIXELFORMAT_ABGR1555> {
|
||||||
|
static constexpr int RShift = 0;
|
||||||
|
static constexpr int GShift = 5;
|
||||||
|
static constexpr int BShift = 10;
|
||||||
|
static constexpr int AShift = 15;
|
||||||
|
|
||||||
|
static constexpr int RBits = 5;
|
||||||
|
static constexpr int GBits = 5;
|
||||||
|
static constexpr int BBits = 5;
|
||||||
|
static constexpr int ABits = 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct FormatMapping<SDL_PIXELFORMAT_ARGB1555> {
|
||||||
|
static constexpr int RShift = 10;
|
||||||
|
static constexpr int GShift = 5;
|
||||||
|
static constexpr int BShift = 0;
|
||||||
|
static constexpr int AShift = 15;
|
||||||
|
|
||||||
|
static constexpr int RBits = 5;
|
||||||
|
static constexpr int GBits = 5;
|
||||||
|
static constexpr int BBits = 5;
|
||||||
|
static constexpr int ABits = 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct FormatMapping<SDL_PIXELFORMAT_RGBA5551> {
|
||||||
|
static constexpr int RShift = 11;
|
||||||
|
static constexpr int GShift = 6;
|
||||||
|
static constexpr int BShift = 1;
|
||||||
|
static constexpr int AShift = 0;
|
||||||
|
|
||||||
|
static constexpr int RBits = 5;
|
||||||
|
static constexpr int GBits = 5;
|
||||||
|
static constexpr int BBits = 5;
|
||||||
|
static constexpr int ABits = 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct FormatMapping<SDL_PIXELFORMAT_BGRA5551> {
|
||||||
|
static constexpr int RShift = 1;
|
||||||
|
static constexpr int GShift = 6;
|
||||||
|
static constexpr int BShift = 11;
|
||||||
|
static constexpr int AShift = 0;
|
||||||
|
|
||||||
|
static constexpr int RBits = 5;
|
||||||
|
static constexpr int GBits = 5;
|
||||||
|
static constexpr int BBits = 5;
|
||||||
|
static constexpr int ABits = 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
#include "sdl_context.h"
|
#include "sdl_context.h"
|
||||||
#include "keyboard_map.h"
|
#include "keyboard_map.h"
|
||||||
|
#include "format_mapping.h"
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include "../platform.h"
|
#include "../platform.h"
|
||||||
|
#include "../error.h"
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
@ -34,6 +36,9 @@ void SDLContext::SDL_Deleter::operator ()(SDL_Surface* surface) {
|
||||||
void SDLContext::SDL_Deleter::operator ()(SDL_Texture* texture) {
|
void SDLContext::SDL_Deleter::operator ()(SDL_Texture* texture) {
|
||||||
SDL_DestroyTexture(texture);
|
SDL_DestroyTexture(texture);
|
||||||
}
|
}
|
||||||
|
void SDLContext::SDL_Deleter::operator ()(SDL_PixelFormat* f) {
|
||||||
|
SDL_FreeFormat(f);
|
||||||
|
}
|
||||||
|
|
||||||
void SDLContext::SDL_Audio_Deleter::operator()(SDL_AudioDeviceID x) {
|
void SDLContext::SDL_Audio_Deleter::operator()(SDL_AudioDeviceID x) {
|
||||||
SDL_CloseAudioDevice(x);
|
SDL_CloseAudioDevice(x);
|
||||||
|
@ -74,10 +79,24 @@ SDLContext::SDLContext() {
|
||||||
void handle_sdl_error(const char *msg) {
|
void handle_sdl_error(const char *msg) {
|
||||||
char buff[512];
|
char buff[512];
|
||||||
|
|
||||||
snprintf(buff, sizeof(buff), "SDL critical error (check video driver): %s %s",msg, SDL_GetError());
|
snprintf(buff, sizeof(buff), "SDL critical error: %s %s",msg, SDL_GetError());
|
||||||
throw std::runtime_error(buff);
|
throw std::runtime_error(buff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isFormatSupported(SDL_Renderer *renderer, Uint32 pixel_format) {
|
||||||
|
SDL_RendererInfo info;
|
||||||
|
if (SDL_GetRendererInfo(renderer, &info) != 0) {
|
||||||
|
handle_sdl_error("Failed to get renderer info");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Uint32 i = 0; i < info.num_texture_formats; ++i) {
|
||||||
|
if (info.texture_formats[i] == pixel_format) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void SDLContext::generateCRTTexture(SDL_Renderer* renderer, SDL_Texture** texture, int width, int height, CrtFilterType type) {
|
void SDLContext::generateCRTTexture(SDL_Renderer* renderer, SDL_Texture** texture, int width, int height, CrtFilterType type) {
|
||||||
|
|
||||||
|
@ -95,6 +114,8 @@ void SDLContext::generateCRTTexture(SDL_Renderer* renderer, SDL_Texture** textur
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (type == CrtFilterType::scanlines || type == CrtFilterType::scanlines_2) {
|
if (type == CrtFilterType::scanlines || type == CrtFilterType::scanlines_2) {
|
||||||
width = 32;
|
width = 32;
|
||||||
} else {
|
} else {
|
||||||
|
@ -105,8 +126,11 @@ void SDLContext::generateCRTTexture(SDL_Renderer* renderer, SDL_Texture** textur
|
||||||
unsigned int mult_of_base = std::max<unsigned int>((height+240)/480,interfer);
|
unsigned int mult_of_base = std::max<unsigned int>((height+240)/480,interfer);
|
||||||
height = height * interfer / mult_of_base;
|
height = height * interfer / mult_of_base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Vytvoř novou texturu ve správné velikosti
|
// Vytvoř novou texturu ve správné velikosti
|
||||||
*texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, width, height);
|
*texture = SDL_CreateTexture(renderer, _texture_render_format, SDL_TEXTUREACCESS_STREAMING, width, height);
|
||||||
if (!*texture) {
|
if (!*texture) {
|
||||||
type = CrtFilterType::none;
|
type = CrtFilterType::none;
|
||||||
return; //crt filter failed to create, do not use filter
|
return; //crt filter failed to create, do not use filter
|
||||||
|
@ -126,10 +150,12 @@ void SDLContext::generateCRTTexture(SDL_Renderer* renderer, SDL_Texture** textur
|
||||||
|
|
||||||
Uint32* pixelArray = (Uint32*)pixels;
|
Uint32* pixelArray = (Uint32*)pixels;
|
||||||
|
|
||||||
|
|
||||||
if (type == CrtFilterType::scanlines) {
|
if (type == CrtFilterType::scanlines) {
|
||||||
|
|
||||||
Uint32 darkPixel = 0xA0A0A0FF;
|
|
||||||
Uint32 transparentPixel = 0xFFFFFFC0;
|
Uint32 darkPixel = SDL_MapRGBA(_main_pixel_format.get(), 0xA0, 0xA0, 0xA0, 0xFF);
|
||||||
|
Uint32 transparentPixel = SDL_MapRGBA(_main_pixel_format.get(), 0xFF, 0xFF, 0xFF, 0xC0);
|
||||||
|
|
||||||
for (int y = 0; y < height; y++) {
|
for (int y = 0; y < height; y++) {
|
||||||
Uint32 color = ((y & 1)== 0) ? darkPixel : transparentPixel;
|
Uint32 color = ((y & 1)== 0) ? darkPixel : transparentPixel;
|
||||||
|
@ -141,8 +167,8 @@ void SDLContext::generateCRTTexture(SDL_Renderer* renderer, SDL_Texture** textur
|
||||||
else if (type == CrtFilterType::scanlines_2) {
|
else if (type == CrtFilterType::scanlines_2) {
|
||||||
|
|
||||||
|
|
||||||
Uint32 darkPixel = 0x808080FF;
|
Uint32 darkPixel = SDL_MapRGBA(_main_pixel_format.get(), 0x80, 0x80, 0x80, 0xFF);
|
||||||
Uint32 transparentPixel = 0xFFFFFFE0;
|
Uint32 transparentPixel = SDL_MapRGBA(_main_pixel_format.get(), 0xFF, 0xFF, 0xFF, 0xE0);
|
||||||
|
|
||||||
for (int y = 0; y < height; y++) {
|
for (int y = 0; y < height; y++) {
|
||||||
Uint32 color = (y % 3== 2) ? darkPixel : transparentPixel;
|
Uint32 color = (y % 3== 2) ? darkPixel : transparentPixel;
|
||||||
|
@ -152,10 +178,10 @@ void SDLContext::generateCRTTexture(SDL_Renderer* renderer, SDL_Texture** textur
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
static Uint32 red_pixel = 0xFF8080A0;
|
static Uint32 red_pixel = SDL_MapRGBA(_main_pixel_format.get(), 0xFF, 0x80, 0x80, 0xA0);
|
||||||
static Uint32 green_pixel = 0x80FF80A0;
|
static Uint32 green_pixel = SDL_MapRGBA(_main_pixel_format.get(), 0x80, 0xFF, 0x80, 0xA0);
|
||||||
static Uint32 blue_pixel = 0x8080FFA0;
|
static Uint32 blue_pixel = SDL_MapRGBA(_main_pixel_format.get(), 0x80, 0x80, 0xFF, 0xA0);
|
||||||
static Uint32 dark_pixel = 0x000000C0;
|
static Uint32 dark_pixel = SDL_MapRGBA(_main_pixel_format.get(), 0x0, 0x0, 0x00, 0xA0);
|
||||||
for (int y = 2; y < height; y++) {
|
for (int y = 2; y < height; y++) {
|
||||||
if (type == CrtFilterType::rgb_matrix_2) {
|
if (type == CrtFilterType::rgb_matrix_2) {
|
||||||
for (int x = 2; x < width; x+=3) {
|
for (int x = 2; x < width; x+=3) {
|
||||||
|
@ -199,6 +225,48 @@ static void crash_sdl_exception() {
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Seznam akceptovatelných formátů odpovídajících RGBA8888 (v různém pořadí)
|
||||||
|
constexpr Uint32 acceptable_formats[] = {
|
||||||
|
SDL_PIXELFORMAT_RGBA8888,
|
||||||
|
SDL_PIXELFORMAT_ARGB8888,
|
||||||
|
SDL_PIXELFORMAT_BGRA8888,
|
||||||
|
SDL_PIXELFORMAT_ABGR8888,
|
||||||
|
|
||||||
|
SDL_PIXELFORMAT_RGBA4444,
|
||||||
|
SDL_PIXELFORMAT_ARGB4444,
|
||||||
|
SDL_PIXELFORMAT_BGRA4444,
|
||||||
|
SDL_PIXELFORMAT_ABGR4444,
|
||||||
|
|
||||||
|
SDL_PIXELFORMAT_ARGB2101010,
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr bool is_acceptable_format(Uint32 format) {
|
||||||
|
for (size_t i = 0; i < sizeof(acceptable_formats)/sizeof(acceptable_formats[0]); ++i) {
|
||||||
|
if (format == acceptable_formats[i]) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Uint32 find_best_rgba_like_format(SDL_Renderer* renderer) {
|
||||||
|
SDL_RendererInfo info;
|
||||||
|
if (SDL_GetRendererInfo(renderer, &info) != 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((info.max_texture_width != 0 && info.max_texture_width < 640) ||
|
||||||
|
(info.max_texture_height!= 0 && info.max_texture_height < 480)) return 0;
|
||||||
|
|
||||||
|
for (Uint32 i = 0; i < info.num_texture_formats; ++i) {
|
||||||
|
Uint32 fmt = info.texture_formats[i];
|
||||||
|
if (is_acceptable_format(fmt)) {
|
||||||
|
return fmt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void SDLContext::init_video(const VideoConfig &config, const char *title) {
|
void SDLContext::init_video(const VideoConfig &config, const char *title) {
|
||||||
static Uint32 update_request_event = SDL_RegisterEvents(1);
|
static Uint32 update_request_event = SDL_RegisterEvents(1);
|
||||||
|
@ -219,15 +287,17 @@ void SDLContext::init_video(const VideoConfig &config, const char *title) {
|
||||||
_enable_crt = false;
|
_enable_crt = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
_fullscreen_mode = config.fullscreen;
|
_fullscreen_mode = config.fullscreen;
|
||||||
_mouse_size = config.cursor_size;
|
_mouse_size = config.cursor_size;
|
||||||
|
|
||||||
std::atomic<bool> done = false;
|
std::atomic<bool> done = false;
|
||||||
std::exception_ptr e;
|
std::exception_ptr e;
|
||||||
|
std::string_view stage;
|
||||||
|
std::string rname;
|
||||||
_render_thread = std::jthread([&](std::stop_token stp){
|
_render_thread = std::jthread([&](std::stop_token stp){
|
||||||
bool err = false;
|
bool err = false;
|
||||||
try {
|
try {
|
||||||
|
stage = "window";
|
||||||
SDL_Window *window = SDL_CreateWindow(title,
|
SDL_Window *window = SDL_CreateWindow(title,
|
||||||
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
|
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
|
||||||
width, height, SDL_WINDOW_RESIZABLE|(_fullscreen_mode?SDL_WINDOW_FULLSCREEN_DESKTOP:0));
|
width, height, SDL_WINDOW_RESIZABLE|(_fullscreen_mode?SDL_WINDOW_FULLSCREEN_DESKTOP:0));
|
||||||
|
@ -237,13 +307,49 @@ void SDLContext::init_video(const VideoConfig &config, const char *title) {
|
||||||
}
|
}
|
||||||
|
|
||||||
_window.reset(window);
|
_window.reset(window);
|
||||||
SDL_Renderer *renderer = SDL_CreateRenderer(_window.get(), -1, config.composer);
|
|
||||||
if (!renderer) {
|
auto composer = config.composer;
|
||||||
handle_sdl_error("Failed to create composer");
|
|
||||||
|
stage = "renderer";
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
|
||||||
|
SDL_Renderer *renderer = SDL_CreateRenderer(_window.get(), -1, composer);
|
||||||
|
if (!renderer) {
|
||||||
|
if (config.composer & SDL_RENDERER_SOFTWARE) {
|
||||||
|
handle_sdl_error("Failed to create composer");
|
||||||
|
} else {
|
||||||
|
composer |= SDL_RENDERER_SOFTWARE;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_texture_render_format = find_best_rgba_like_format(renderer);
|
||||||
|
if (_texture_render_format == 0) {
|
||||||
|
if (composer & SDL_RENDERER_SOFTWARE) {
|
||||||
|
throw std::runtime_error("Failed to create composer, failed software fallback");
|
||||||
|
} else {
|
||||||
|
SDL_DestroyRenderer(renderer);
|
||||||
|
composer |= SDL_RENDERER_SOFTWARE;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_renderer.reset(renderer);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SDL_RendererInfo rinfo;
|
SDL_RendererInfo rinfo;
|
||||||
SDL_GetRendererInfo(renderer, &rinfo);
|
SDL_GetRendererInfo(_renderer.get(), &rinfo);
|
||||||
|
|
||||||
|
rname = rinfo.name;
|
||||||
|
|
||||||
|
stage = "pixel format";
|
||||||
|
|
||||||
|
_main_pixel_format.reset(SDL_AllocFormat(_texture_render_format));
|
||||||
|
if (!_main_pixel_format) {
|
||||||
|
handle_sdl_error("Failed to create texture format");
|
||||||
|
}
|
||||||
|
|
||||||
if (istrcmp(config.scale_quality, "auto") == 0) {
|
if (istrcmp(config.scale_quality, "auto") == 0) {
|
||||||
if (rinfo.flags & SDL_RENDERER_ACCELERATED) {
|
if (rinfo.flags & SDL_RENDERER_ACCELERATED) {
|
||||||
|
@ -253,20 +359,30 @@ void SDLContext::init_video(const VideoConfig &config, const char *title) {
|
||||||
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, config.scale_quality);
|
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, config.scale_quality);
|
||||||
}
|
}
|
||||||
|
|
||||||
_renderer.reset(renderer);
|
|
||||||
SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB1555, SDL_TEXTUREACCESS_STREAMING, 640, 480);
|
|
||||||
|
stage = "main render target";
|
||||||
|
|
||||||
|
|
||||||
|
SDL_Texture *texture = SDL_CreateTexture(_renderer.get(), _texture_render_format, SDL_TEXTUREACCESS_STREAMING, 640, 480);
|
||||||
if (!texture) {
|
if (!texture) {
|
||||||
handle_sdl_error("Failed to create render target");
|
handle_sdl_error("Failed to create render target");
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
|
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
|
||||||
_texture.reset(texture);
|
_texture.reset(texture);
|
||||||
texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB1555, SDL_TEXTUREACCESS_STREAMING, 640, 480);
|
|
||||||
|
stage = "secondary render target";
|
||||||
|
|
||||||
|
texture = SDL_CreateTexture(_renderer.get(), _texture_render_format, SDL_TEXTUREACCESS_STREAMING, 640, 480);
|
||||||
if (!texture) {
|
if (!texture) {
|
||||||
handle_sdl_error("Failed to create second render target");
|
handle_sdl_error("Failed to create second render target");
|
||||||
}
|
}
|
||||||
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
|
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
|
||||||
_texture2.reset(texture);
|
_texture2.reset(texture);
|
||||||
|
|
||||||
|
stage = "all done";
|
||||||
|
|
||||||
_visible_texture = _texture.get();
|
_visible_texture = _texture.get();
|
||||||
_hidden_texture = _texture2.get();
|
_hidden_texture = _texture2.get();
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
@ -294,7 +410,17 @@ void SDLContext::init_video(const VideoConfig &config, const char *title) {
|
||||||
done.wait(false);
|
done.wait(false);
|
||||||
if (e) {
|
if (e) {
|
||||||
_render_thread.join();
|
_render_thread.join();
|
||||||
std::rethrow_exception(e);
|
try {
|
||||||
|
std::rethrow_exception(e);
|
||||||
|
} catch (...) {
|
||||||
|
std::throw_with_nested(
|
||||||
|
std::runtime_error(std::string("Oops! The application couldn't start properly (problem during SDL initialization). Stage: [")
|
||||||
|
.append(stage).append("]\n\n"
|
||||||
|
"Renderer: ").append(rname).append("\n\n"
|
||||||
|
"This may be caused by outdated or missing graphics or audio drivers."
|
||||||
|
"To fix this, please try the following:\n- Restart your computer and try again\n- "
|
||||||
|
"Make sure your graphics and sound drivers are up to date.")));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -335,6 +461,102 @@ int SDLContext::adjust_deadzone(int v, short deadzone) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<int shift>
|
||||||
|
constexpr Uint32 shift_bits_5(Uint32 val) {
|
||||||
|
if constexpr(shift > 0) {
|
||||||
|
return val << shift | shift_bits_5<shift-5>(val);
|
||||||
|
} else if constexpr(shift < 0) {
|
||||||
|
return val >> (-shift);
|
||||||
|
} else {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<Uint32 pixel_format>
|
||||||
|
void SDLContext::convert_bitmap(const void *pixels, SDL_Rect rect, int pitch) {
|
||||||
|
|
||||||
|
constexpr auto RShift = FormatMapping<pixel_format>::RShift;
|
||||||
|
constexpr auto GShift = FormatMapping<pixel_format>::GShift;
|
||||||
|
constexpr auto BShift = FormatMapping<pixel_format>::BShift;
|
||||||
|
constexpr auto AShift = FormatMapping<pixel_format>::AShift;
|
||||||
|
constexpr auto RBits = FormatMapping<pixel_format>::RBits;
|
||||||
|
constexpr auto GBits = FormatMapping<pixel_format>::GBits;
|
||||||
|
constexpr auto BBits = FormatMapping<pixel_format>::BBits;
|
||||||
|
constexpr auto ABits = FormatMapping<pixel_format>::ABits;
|
||||||
|
|
||||||
|
const Uint16 *src = static_cast<const Uint16*>(pixels);
|
||||||
|
auto trg = converted_pixels.data();
|
||||||
|
for (int y = 0; y < rect.h; ++y) {
|
||||||
|
for (int x = 0; x < rect.w; ++x) {
|
||||||
|
Uint16 pixel = src[x];
|
||||||
|
Uint32 a = (pixel & 0x8000) ? 0 : 0x1F;
|
||||||
|
Uint32 r = ((pixel >> 10) & 0x1F);
|
||||||
|
Uint32 g = ((pixel >> 5) & 0x1F);
|
||||||
|
Uint32 b = (pixel & 0x1F);
|
||||||
|
|
||||||
|
r = shift_bits_5<RBits-5>(r);
|
||||||
|
g = shift_bits_5<GBits-5>(g);
|
||||||
|
b = shift_bits_5<BBits-5>(b);
|
||||||
|
a = shift_bits_5<ABits-5>(a);
|
||||||
|
|
||||||
|
trg[x] = (r << RShift) | (g << GShift) | (b << BShift) | (a << AShift);
|
||||||
|
}
|
||||||
|
trg += rect.w;
|
||||||
|
src = src + pitch / 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SDLContext::update_texture_with_conversion(SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch)
|
||||||
|
{
|
||||||
|
SDL_Rect r;
|
||||||
|
if (rect) {
|
||||||
|
r = *rect;
|
||||||
|
} else {
|
||||||
|
SDL_QueryTexture(texture, nullptr, nullptr, &r.w, &r.h);
|
||||||
|
r.x = 0;
|
||||||
|
r.y = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
converted_pixels.clear();
|
||||||
|
converted_pixels.resize(r.w * r.h);
|
||||||
|
|
||||||
|
switch (_texture_render_format) {
|
||||||
|
case SDL_PIXELFORMAT_ABGR8888:
|
||||||
|
convert_bitmap<SDL_PIXELFORMAT_ABGR8888>(pixels, r, pitch);break;
|
||||||
|
case SDL_PIXELFORMAT_ARGB8888:
|
||||||
|
convert_bitmap<SDL_PIXELFORMAT_ARGB8888>(pixels, r, pitch);break;
|
||||||
|
case SDL_PIXELFORMAT_ARGB2101010:
|
||||||
|
convert_bitmap<SDL_PIXELFORMAT_ARGB2101010>(pixels, r, pitch);break;
|
||||||
|
case SDL_PIXELFORMAT_RGBA8888:
|
||||||
|
convert_bitmap<SDL_PIXELFORMAT_RGBA8888>(pixels, r, pitch);break;
|
||||||
|
case SDL_PIXELFORMAT_BGRA8888:
|
||||||
|
convert_bitmap<SDL_PIXELFORMAT_BGRA8888>(pixels, r, pitch);break;
|
||||||
|
case SDL_PIXELFORMAT_ABGR4444:
|
||||||
|
convert_bitmap<SDL_PIXELFORMAT_ABGR4444>(pixels, r, pitch);break;
|
||||||
|
case SDL_PIXELFORMAT_ARGB4444:
|
||||||
|
convert_bitmap<SDL_PIXELFORMAT_ARGB4444>(pixels, r, pitch);break;
|
||||||
|
case SDL_PIXELFORMAT_BGRA4444:
|
||||||
|
convert_bitmap<SDL_PIXELFORMAT_BGRA4444>(pixels, r, pitch);break;
|
||||||
|
case SDL_PIXELFORMAT_RGBA4444:
|
||||||
|
convert_bitmap<SDL_PIXELFORMAT_RGBA4444>(pixels, r, pitch);break;
|
||||||
|
case SDL_PIXELFORMAT_ABGR1555:
|
||||||
|
convert_bitmap<SDL_PIXELFORMAT_ABGR1555>(pixels, r, pitch);break;
|
||||||
|
case SDL_PIXELFORMAT_ARGB1555:
|
||||||
|
convert_bitmap<SDL_PIXELFORMAT_ARGB1555>(pixels, r, pitch);break;
|
||||||
|
case SDL_PIXELFORMAT_RGBA5551:
|
||||||
|
convert_bitmap<SDL_PIXELFORMAT_RGBA5551>(pixels, r, pitch);break;
|
||||||
|
case SDL_PIXELFORMAT_BGRA5551:
|
||||||
|
convert_bitmap<SDL_PIXELFORMAT_BGRA5551>(pixels, r, pitch);break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SDL_UpdateTexture(texture, &r, converted_pixels.data(), r.w * 4) < 0) {
|
||||||
|
handle_sdl_error("Failed to update texture");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int axis_dynamic(int c) {
|
static int axis_dynamic(int c) {
|
||||||
double f = std::floor(std::pow(std::abs(c)*0.001,2)*0.025);
|
double f = std::floor(std::pow(std::abs(c)*0.001,2)*0.025);
|
||||||
|
|
||||||
|
@ -698,19 +920,19 @@ void SDLContext::update_screen(bool force_refresh) {
|
||||||
SDL_Rect r;
|
SDL_Rect r;
|
||||||
pop_item(iter, r);
|
pop_item(iter, r);
|
||||||
std::string_view data = pop_data(iter, r.w*r.h*2);
|
std::string_view data = pop_data(iter, r.w*r.h*2);
|
||||||
if (SDL_UpdateTexture(_texture.get(), &r, data.data(), r.w*2)<0) handle_sdl_error("Update of render target failed");
|
update_texture_with_conversion(_texture.get(), &r, data.data(), r.w*2);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DisplayRequest::show_mouse_cursor: {
|
case DisplayRequest::show_mouse_cursor: {
|
||||||
SDL_Rect r;
|
SDL_Rect r;
|
||||||
pop_item(iter, r);
|
pop_item(iter, r);
|
||||||
std::string_view data = pop_data(iter, r.w*r.h*2);
|
std::string_view data = pop_data(iter, r.w*r.h*2);
|
||||||
_mouse.reset(SDL_CreateTexture(_renderer.get(), SDL_PIXELFORMAT_ARGB1555,SDL_TEXTUREACCESS_STATIC, r.w, r.h));
|
_mouse.reset(SDL_CreateTexture(_renderer.get(), _texture_render_format,SDL_TEXTUREACCESS_STATIC, r.w, r.h));
|
||||||
if (!_mouse) handle_sdl_error("Failed to create surface for mouse cursor");
|
if (!_mouse) handle_sdl_error("Failed to create surface for mouse cursor");
|
||||||
SDL_SetTextureBlendMode(_mouse.get(), SDL_BLENDMODE_BLEND);
|
SDL_SetTextureBlendMode(_mouse.get(), SDL_BLENDMODE_BLEND);
|
||||||
_mouse_rect.w = r.w;
|
_mouse_rect.w = r.w;
|
||||||
_mouse_rect.h = r.h;
|
_mouse_rect.h = r.h;
|
||||||
if (SDL_UpdateTexture(_mouse.get(), NULL, data.data(), r.w*2)<0) handle_sdl_error("Update of mouse cursor failed");
|
update_texture_with_conversion(_mouse.get(), NULL, data.data(), r.w*2);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DisplayRequest::hide_mouse_cursor: {
|
case DisplayRequest::hide_mouse_cursor: {
|
||||||
|
@ -747,10 +969,10 @@ void SDLContext::update_screen(bool force_refresh) {
|
||||||
if (iter == _sprites.end()) {
|
if (iter == _sprites.end()) {
|
||||||
iter = _sprites.insert(iter,{id});
|
iter = _sprites.insert(iter,{id});
|
||||||
}
|
}
|
||||||
iter->_txtr.reset(SDL_CreateTexture(_renderer.get(), SDL_PIXELFORMAT_ARGB1555, SDL_TEXTUREACCESS_STATIC,r.w, r.h));
|
iter->_txtr.reset(SDL_CreateTexture(_renderer.get(), _texture_render_format, SDL_TEXTUREACCESS_STATIC,r.w, r.h));
|
||||||
if (!iter->_txtr) handle_sdl_error("Failed to create compositor sprite");
|
if (!iter->_txtr) handle_sdl_error("Failed to create compositor sprite");
|
||||||
SDL_SetTextureBlendMode(iter->_txtr.get(), SDL_BLENDMODE_BLEND);
|
SDL_SetTextureBlendMode(iter->_txtr.get(), SDL_BLENDMODE_BLEND);
|
||||||
if (SDL_UpdateTexture(iter->_txtr.get(), NULL, data.data(), r.w*2)<0) handle_sdl_error("Update of sprite failed");
|
update_texture_with_conversion(iter->_txtr.get(), NULL, data.data(), r.w*2);
|
||||||
iter->_rect = r;
|
iter->_rect = r;
|
||||||
update_zindex();
|
update_zindex();
|
||||||
} break;
|
} break;
|
||||||
|
@ -851,10 +1073,8 @@ void SDLContext::push_update_msg(const SDL_Rect &rc, const uint16_t *data, int p
|
||||||
_display_update_queue.resize(sz+rc.w*rc.h*2);
|
_display_update_queue.resize(sz+rc.w*rc.h*2);
|
||||||
short *trg = reinterpret_cast<short *>(_display_update_queue.data()+sz);
|
short *trg = reinterpret_cast<short *>(_display_update_queue.data()+sz);
|
||||||
for (int yp = 0; yp < rc.h; ++yp) {
|
for (int yp = 0; yp < rc.h; ++yp) {
|
||||||
for (int xp = 0; xp < rc.w; ++xp) {
|
std::copy(data, data+rc.w, trg);
|
||||||
*trg = data[xp] ^ 0x8000;
|
trg += rc.w;
|
||||||
++trg;
|
|
||||||
}
|
|
||||||
data += pitch;
|
data += pitch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1009,7 +1229,7 @@ void put_picture_ex(unsigned short x,unsigned short y,const void *p, unsigned sh
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDLContext::push_hi_image(const unsigned short *image) {
|
void SDLContext::push_hi_image(const unsigned short *image) {
|
||||||
SDL_Rect rc;
|
SDL_Rect rc = {};
|
||||||
rc.w= image[0];
|
rc.w= image[0];
|
||||||
rc.h =image[1];
|
rc.h =image[1];
|
||||||
push_item(rc);
|
push_item(rc);
|
||||||
|
@ -1019,7 +1239,6 @@ void SDLContext::push_hi_image(const unsigned short *image) {
|
||||||
unsigned short *trg = reinterpret_cast<unsigned short *>(_display_update_queue.data()+sz);
|
unsigned short *trg = reinterpret_cast<unsigned short *>(_display_update_queue.data()+sz);
|
||||||
std::fill(trg, trg+imgsz, 0x8000);
|
std::fill(trg, trg+imgsz, 0x8000);
|
||||||
put_picture_ex(0, 0, image, trg, rc.w);
|
put_picture_ex(0, 0, image, trg, rc.w);
|
||||||
std::transform(trg, trg+imgsz, trg, [](unsigned short &x)->unsigned short {return x ^ 0x8000;});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDLContext::show_mouse_cursor(const unsigned short *ms_hi_format, SDL_Point finger) {
|
void SDLContext::show_mouse_cursor(const unsigned short *ms_hi_format, SDL_Point finger) {
|
||||||
|
|
|
@ -170,6 +170,7 @@ protected:
|
||||||
void operator()(SDL_Renderer *);
|
void operator()(SDL_Renderer *);
|
||||||
void operator()(SDL_Surface *);
|
void operator()(SDL_Surface *);
|
||||||
void operator()(SDL_Texture *);
|
void operator()(SDL_Texture *);
|
||||||
|
void operator()(SDL_PixelFormat* f);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BlendTransitionReq {
|
struct BlendTransitionReq {
|
||||||
|
@ -237,13 +238,16 @@ protected:
|
||||||
std::unique_ptr<SDL_Texture, SDL_Deleter> _texture2;
|
std::unique_ptr<SDL_Texture, SDL_Deleter> _texture2;
|
||||||
std::unique_ptr<SDL_Texture, SDL_Deleter> _crt_effect;
|
std::unique_ptr<SDL_Texture, SDL_Deleter> _crt_effect;
|
||||||
std::unique_ptr<SDL_Texture, SDL_Deleter> _mouse;
|
std::unique_ptr<SDL_Texture, SDL_Deleter> _mouse;
|
||||||
|
std::unique_ptr<SDL_PixelFormat, SDL_Deleter> _main_pixel_format;
|
||||||
unique_value<SDL_AudioDeviceID, SDL_Audio_Deleter> _audio;
|
unique_value<SDL_AudioDeviceID, SDL_Audio_Deleter> _audio;
|
||||||
SDL_Texture *_visible_texture;
|
SDL_Texture *_visible_texture = nullptr;
|
||||||
SDL_Texture *_hidden_texture;
|
SDL_Texture *_hidden_texture = nullptr;
|
||||||
|
uint32_t _texture_render_format = SDL_PIXELFORMAT_ARGB1555;
|
||||||
|
|
||||||
|
|
||||||
bool _fullscreen_mode = false;
|
bool _fullscreen_mode = false;
|
||||||
bool _present = false;
|
bool _present = false;
|
||||||
|
bool _convert_format = false;
|
||||||
std::atomic<bool> _key_control = false;
|
std::atomic<bool> _key_control = false;
|
||||||
std::atomic<bool> _key_shift = false;
|
std::atomic<bool> _key_shift = false;
|
||||||
std::atomic<bool> _key_capslock = false;
|
std::atomic<bool> _key_capslock = false;
|
||||||
|
@ -252,11 +256,12 @@ protected:
|
||||||
|
|
||||||
|
|
||||||
std::vector<char> _display_update_queue;
|
std::vector<char> _display_update_queue;
|
||||||
|
std::vector<uint32_t> converted_pixels;
|
||||||
using QueueIter = const char *;
|
using QueueIter = const char *;
|
||||||
std::queue<uint16_t> _keyboard_queue;
|
std::queue<uint16_t> _keyboard_queue;
|
||||||
SDL_Rect _mouse_rect;
|
SDL_Rect _mouse_rect;
|
||||||
SDL_Point _mouse_finger;
|
SDL_Point _mouse_finger;
|
||||||
float _mouse_size;
|
float _mouse_size = 1;
|
||||||
SpriteList _sprites;
|
SpriteList _sprites;
|
||||||
|
|
||||||
|
|
||||||
|
@ -307,4 +312,11 @@ protected:
|
||||||
void generate_j_event(int button, char up);
|
void generate_j_event(int button, char up);
|
||||||
static int adjust_deadzone(int v, short deadzone);
|
static int adjust_deadzone(int v, short deadzone);
|
||||||
|
|
||||||
|
void update_texture_with_conversion(SDL_Texture * texture,
|
||||||
|
const SDL_Rect * rect,
|
||||||
|
const void *pixels, int pitch);
|
||||||
|
|
||||||
|
template<Uint32 pixel_format>
|
||||||
|
void convert_bitmap(const void *pixels, SDL_Rect r, int pitch);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -299,7 +299,8 @@ static void update_music_volume(){
|
||||||
float v = music_volume * master_volume;
|
float v = music_volume * master_volume;
|
||||||
for (int i = 0; i <2; i++)
|
for (int i = 0; i <2; i++)
|
||||||
sound_mixer.visit_track(music_track_id_base+i,[&](WaveMixer<2> &m){
|
sound_mixer.visit_track(music_track_id_base+i,[&](WaveMixer<2> &m){
|
||||||
m.set_channel_volume(v, v);
|
m.set_channel_volume(0, v);
|
||||||
|
m.set_channel_volume(1, v);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -91,8 +91,8 @@ public:
|
||||||
} else {
|
} else {
|
||||||
(*iter) += value.left * vol[0];
|
(*iter) += value.left * vol[0];
|
||||||
++iter;
|
++iter;
|
||||||
(*iter) += value.right * vol[0];
|
(*iter) += value.right * vol[1];
|
||||||
++iter;
|
std::advance(iter, channels-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "../../game/skeldal.h"
|
#include "../../game/skeldal.h"
|
||||||
#include "../getopt.h"
|
#include "../getopt.h"
|
||||||
#include "../platform.h"
|
#include "../platform.h"
|
||||||
|
#include "../error.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
@ -86,7 +87,7 @@ int main(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
cfg.show_error(e.what());
|
cfg.show_error(exception_to_string(e).c_str());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
catch (...) {
|
catch (...) {
|
||||||
|
|
|
@ -15,13 +15,17 @@ std::string getSavedGamesDirectory() {
|
||||||
PWSTR path = nullptr;
|
PWSTR path = nullptr;
|
||||||
if (SUCCEEDED(SHGetKnownFolderPath(FOLDERID_SavedGames, 0, NULL, &path))) {
|
if (SUCCEEDED(SHGetKnownFolderPath(FOLDERID_SavedGames, 0, NULL, &path))) {
|
||||||
fs::path savedGamesPath(path);
|
fs::path savedGamesPath(path);
|
||||||
CoTaskMemFree(path);
|
CoTaskMemFree(path);
|
||||||
return (savedGamesPath / SAVEGAME_FOLDERNAME).string();
|
|
||||||
|
// Převod na UTF-8 std::string
|
||||||
|
std::u8string utf8 = (savedGamesPath / SAVEGAME_FOLDERNAME).u8string();
|
||||||
|
return std::string(reinterpret_cast<const char*>(utf8.data()), utf8.size());
|
||||||
} else {
|
} else {
|
||||||
display_error("Failed to retrieve FOLDEROD_SavedGames");
|
display_error("Failed to retrieve FOLDERID_SavedGames");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *get_default_savegame_directory() {
|
const char *get_default_savegame_directory() {
|
||||||
|
|
||||||
static std::string dir = getSavedGamesDirectory();
|
static std::string dir = getSavedGamesDirectory();
|
||||||
|
|
|
@ -47,6 +47,7 @@
|
||||||
#crt_filter=auto
|
#crt_filter=auto
|
||||||
#scale_quality=auto
|
#scale_quality=auto
|
||||||
#composer=auto
|
#composer=auto
|
||||||
|
#sdl_renderer_driver=software
|
||||||
#aspect_ratio=4:3
|
#aspect_ratio=4:3
|
||||||
#cursor_size=100
|
#cursor_size=100
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ DDLArchive::Extracted DDLArchive::extract_file(std::ifstream &s,
|
||||||
std::vector<char> data;
|
std::vector<char> data;
|
||||||
data.resize(sz);
|
data.resize(sz);
|
||||||
s.read(data.data(), sz);
|
s.read(data.data(), sz);
|
||||||
if (s.gcount() != sz) return {fname, false, {}};
|
if (static_cast<uint32_t>(s.gcount()) != sz) return {fname, false, {}};
|
||||||
return {fname, true, std::move(data)};
|
return {fname, true, std::move(data)};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
5
version.in.h
Normal file
5
version.in.h
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define SKELDAL_VERSION "@APP_VERSION@"
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue