boat in exploration is drawn by compositor

This commit is contained in:
Ondřej Novák 2025-02-17 21:08:03 +01:00
parent 232dae6708
commit 05c1f952c4
12 changed files with 323 additions and 72 deletions

View file

@ -81,6 +81,7 @@ char obl_max_anim=1;
char anim_mirror=0; char anim_mirror=0;
static char showrune=0; static char showrune=0;
static int showruneitem=0; static int showruneitem=0;
static char lodka_loaded=0;
@ -1102,12 +1103,13 @@ static void zobraz_lodku(const word *lodka, word *screen, int size)
{ {
int32_t scr_linelen2 = GetScreenPitch(); int32_t scr_linelen2 = GetScreenPitch();
lodka+=3;
int x; int x;
while (size) while (size)
{ {
for (x=0;x<640 && size;x++) for (x=0;x<640 && size;x++)
{ {
if (*lodka!=0) screen[x]=*lodka; if (*lodka!=0x8000) screen[x]=*lodka;
lodka++; lodka++;
size--; size--;
} }
@ -1263,7 +1265,17 @@ void render_scene(int sector, int smer)
if (cancel_render) return; if (cancel_render) return;
} }
calc_spectxtrs(); calc_spectxtrs();
if (lodka) zobraz_lodku(ablock(H_LODKA),LODKA_POS,LODKA_SIZ); if (lodka) {
if (cur_mode == MD_GAME) {
if (!lodka_loaded) {
game_display_load_sprite(H_LODKA, (const unsigned short *)ablock(H_LODKA));
lodka_loaded = 1;
}
game_display_place_sprite(H_LODKA, 0, SCREEN_OFFLINE+301);
} else {
zobraz_lodku(ablock(H_LODKA),LODKA_POS,LODKA_SIZ);
}
}
} }
@ -1379,3 +1391,7 @@ void display_ver(int x,int y,int ax,int ay)
set_font(H_FTINY,RGB555(31,31,31));set_aligned_position(x,y,ax,ay,ver); set_font(H_FTINY,RGB555(31,31,31));set_aligned_position(x,y,ax,ay,ver);
outtext(ver);showview(0,0,0,0); outtext(ver);showview(0,0,0,0);
} }
void hide_boat() {
game_display_hide_sprite(H_LODKA);
}

View file

@ -1814,6 +1814,7 @@ char *change_extension_support(char *buffer, const char *filename,char *new_exte
#define set_file_extension(filename, extension) change_extension_support((char *)alloca(strlen(filename)+strlen(extension)), (filename), (extension)) #define set_file_extension(filename, extension) change_extension_support((char *)alloca(strlen(filename)+strlen(extension)), (filename), (extension))
void load_enemy_to_map(int i, int sector, int dir, const TMOB *t); void load_enemy_to_map(int i, int sector, int dir, const TMOB *t);
void hide_boat();
//extras //extras
#include "extras.h" #include "extras.h"

View file

@ -1182,6 +1182,7 @@ void check_players_place(char mode) {
if (map_sectors[sect].sector_type != S_LODKA && lodka) { if (map_sectors[sect].sector_type != S_LODKA && lodka) {
set_backgrnd_mode(0); set_backgrnd_mode(0);
lodka = 0; lodka = 0;
hide_boat();
} }
} }
} }

View file

@ -92,6 +92,7 @@ static char titles_on=0;
const void *pcx_fade_decomp(const void *p, int32_t *s); const void *pcx_fade_decomp(const void *p, int32_t *s);
const void *pcx_15bit_decomp(const void *p, int32_t *s); const void *pcx_15bit_decomp(const void *p, int32_t *s);
const void *pcx_15bit_decomp_transp0(const void *p, int32_t *s);
const void *pcx_15bit_autofade(const void *p, int32_t *s); const void *pcx_15bit_autofade(const void *p, int32_t *s);
const void *pcx_15bit_backgrnd(const void *p, int32_t *s); const void *pcx_15bit_backgrnd(const void *p, int32_t *s);
const void *pcx_8bit_decomp(const void *p, int32_t *s); const void *pcx_8bit_decomp(const void *p, int32_t *s);
@ -130,7 +131,7 @@ TDREGISTERS registred[]=
{H_FKNIHA,"kniha.fon",NULL,SR_FONT}, {H_FKNIHA,"kniha.fon",NULL,SR_FONT},
{H_FBIG,"timese.fon",NULL,SR_FONT}, {H_FBIG,"timese.fon",NULL,SR_FONT},
{H_IOBLOUK,"ioblouk.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, {H_IOBLOUK,"ioblouk.pcx",pcx_8bit_decomp,SR_BGRAFIKA},
{H_LODKA,"lodka.pcx",pcx_15bit_decomp,SR_BGRAFIKA}, {H_LODKA,"lodka.pcx",pcx_15bit_decomp_transp0,SR_BGRAFIKA},
{H_IDESKA,"ideska.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, {H_IDESKA,"ideska.pcx",pcx_8bit_decomp,SR_BGRAFIKA},
{H_IMRIZ1,"imriz1.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, {H_IMRIZ1,"imriz1.pcx",pcx_8bit_decomp,SR_BGRAFIKA},
{H_RAMECEK,"ramecek.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, {H_RAMECEK,"ramecek.pcx",pcx_8bit_decomp,SR_BGRAFIKA},
@ -296,6 +297,14 @@ const void *pcx_15bit_decomp(const void *p, int32_t *s)
*s=r; *s=r;
return buff; return buff;
} }
const void *pcx_15bit_decomp_transp0(const void *p, int32_t *s)
{
char *buff;
int r = load_pcx(p,*s,A_16BIT_ZERO_TRANSP,&buff);
assert(r > 0);
*s=r;
return buff;
}
const void *pcx_15bit_autofade(const void *p, int32_t *s) const void *pcx_15bit_autofade(const void *p, int32_t *s)
{ {
@ -1022,6 +1031,7 @@ void unwire_main_functs(void)
disable_click_map(); disable_click_map();
cancel_render=1; cancel_render=1;
wire_proc=wire_main_functs; wire_proc=wire_main_functs;
hide_boat();
} }

View file

@ -29,6 +29,7 @@ short cislo_kola;
HUM_ACTION spell_string; HUM_ACTION spell_string;
short caster; short caster;
short vybrana_zbran=-1; short vybrana_zbran=-1;
static char group_flee = 0;
char plr_switcher[POCET_POSTAV]; char plr_switcher[POCET_POSTAV];
static int pohyblivost_counter[POCET_POSTAV]; static int pohyblivost_counter[POCET_POSTAV];
static int autostart_round=0; static int autostart_round=0;
@ -552,7 +553,7 @@ void auto_group()
{ {
p->groupnum=t++; p->groupnum=t++;
for(j=i+1;q=&postavy[j],j<POCET_POSTAV;j++) for(j=i+1;q=&postavy[j],j<POCET_POSTAV;j++)
if (p->sektor==q->sektor && p->direction==q->direction && p->inmaphash == current_map_hash && q->used && q->lives) if (p->sektor==q->sektor && p->inmaphash == current_map_hash && q->used && q->lives)
q->groupnum=p->groupnum; q->groupnum=p->groupnum;
} }
@ -911,29 +912,15 @@ void prejdi_na_pohled(THUMAN *p)
} }
int hromadny_utek; int hromadny_utek;
static int UtekHromadne(int sector)
{
int minact=999;
int i;
int p=0;
for (i=0;i<POCET_POSTAV;i++) if (postavy[i].used && postavy[i].sektor==sector && postavy[i].kondice>2 && postavy[i].inmaphash == current_map_hash)
{
int wf=weigth_defect(postavy+i)+2;
if (postavy[i].provadena_akce==NULL || postavy[i].provadena_akce->action!=AC_RUN) return 0;
if (postavy[i].utek<minact) minact=postavy[i].utek;
if (postavy[i].kondice/wf<minact) minact=postavy[i].kondice/wf;
p++;
}
return p>1?minact:0;
}
void utek_postavy(THUMAN *p) void utek_postavy(THUMAN *p, char group)
{ {
int minact=0; int minact=0;
p->actions=p->utek; p->actions=p->utek;
if (game_extras & EX_GROUP_FLEE && (minact=UtekHromadne(p->sektor))!=0) if (group)
{ {
int i; int i;
minact = 5;
p->actions=minact; p->actions=minact;
hromadny_utek=p->sektor; hromadny_utek=p->sektor;
for (i=0;i<POCET_POSTAV;i++) if (postavy[i].used && postavy[i].sektor==p->sektor && postavy[i].inmaphash == current_map_hash) for (i=0;i<POCET_POSTAV;i++) if (postavy[i].used && postavy[i].sektor==p->sektor && postavy[i].inmaphash == current_map_hash)
@ -1353,7 +1340,10 @@ void jadro_souboje(EVENT_MSG *msg,void **unused) //!!!! Jadro souboje
else else
{ {
SEND_LOG("(BATTLE) Player Action '%s', number: %d",p->jmeno,p->provadena_akce->action); SEND_LOG("(BATTLE) Player Action '%s', number: %d",p->jmeno,p->provadena_akce->action);
switch(p->provadena_akce->action) if (group_flee) {
group_flee = 0;
utek_postavy(p, 1);
} else switch(p->provadena_akce->action)
{ {
case AC_MOVE: case AC_MOVE:
{ {
@ -1401,7 +1391,7 @@ void jadro_souboje(EVENT_MSG *msg,void **unused) //!!!! Jadro souboje
} }
break; break;
case AC_STAND:pomala_regenerace_postavy(p);break; case AC_STAND:pomala_regenerace_postavy(p);break;
case AC_RUN:utek_postavy(p);break; case AC_RUN:utek_postavy(p,0);break;
case AC_MAGIC: case AC_MAGIC:
prejdi_na_pohled(p); prejdi_na_pohled(p);
bott_draw(1); bott_draw(1);
@ -1769,6 +1759,16 @@ void program_draw()
maxy; maxy;
schovej_mysku(); schovej_mysku();
if (group_flee) {
trans_bar(0,377-15,640,15,0);
for (j = 0; j < POCET_POSTAV; ++j) if (postavy[j].groupnum == cur_group) {
set_font(H_FLITT5,PRG_COLOR);
int y=386-10;
set_aligned_position(x,y,1,2,texty[AC_RUN+40]);
outtext(texty[40+AC_RUN]);
x+=74;
}
} else {
for(j=0;j<POCET_POSTAV;j++) for(j=0;j<POCET_POSTAV;j++)
if (postavy[i=group_sort[j]].used) if (postavy[i=group_sort[j]].used)
{ {
@ -1801,6 +1801,7 @@ void program_draw()
} }
x+=74; x+=74;
} }
}
if(pgm_help || rune_name!=NULL) if(pgm_help || rune_name!=NULL)
{ {
char *c; char *c;
@ -2000,7 +2001,10 @@ static void zahajit_kolo(char prekvapeni)
if (w==0) w=select_weapon(p,0); if (w==0) w=select_weapon(p,0);
else if (w==3) w=select_weapon(p,0),monster|=monster_far; else if (w==3) w=select_weapon(p,0),monster|=monster_far;
else w--,monster|=monster_far; else w--,monster|=monster_far;
if (p->used && !p->programovano && p->lives && p->inmaphash == current_map_hash) { if (p->used && group_flee) {
p->programovano = 1;
p->zvolene_akce->action=AC_RUN;
} else if (p->used && !p->programovano && p->lives && p->inmaphash == current_map_hash) {
if (prekvapeni || !p->actions || !autoattack || !monster) if (prekvapeni || !p->actions || !autoattack || !monster)
{ {
p->programovano++;p->zvolene_akce->action=AC_STAND; p->programovano++;p->zvolene_akce->action=AC_STAND;
@ -2038,13 +2042,18 @@ char mask_click(int id,int xa,int ya,int xr,int yr)
souboje_stisknout(d); souboje_stisknout(d);
switch(d) switch(d)
{ {
case AC_RUN: postavy[select_player].utek=5+postavy[select_player].actions; case AC_RUN:
if (lodka) {
group_flee = 1;break;
} else {
postavy[select_player].utek=5+postavy[select_player].actions;
}
CASE_FALLTHROUGH; CASE_FALLTHROUGH;
case AC_ATTACK: case AC_ATTACK:
case AC_STAND: case AC_STAND:
case AC_ARMOR: case AC_ARMOR:
case AC_MOVE: case AC_MOVE:
case AC_MAGIC:if (postavy[select_player].actions) case AC_MAGIC:if (postavy[select_player].actions && (d != AC_MOVE || !lodka))
{ {
HUM_ACTION *c; HUM_ACTION *c;
postavy[select_player].direction=viewdir; postavy[select_player].direction=viewdir;
@ -2061,7 +2070,7 @@ char mask_click(int id,int xa,int ya,int xr,int yr)
souboje_vybrano(d); souboje_vybrano(d);
} }
break; break;
case AC_CANCEL:zrusit_akce();break; case AC_CANCEL:zrusit_akce();group_flee = 0;break;
case AC_START:zahajit_kolo(0); case AC_START:zahajit_kolo(0);
souboje_stisknout(d); souboje_stisknout(d);
return 0; return 0;

View file

@ -13,6 +13,7 @@ char visible=0;
MS_EVENT ms_last_event; MS_EVENT ms_last_event;
integer h_x,h_y=0; integer h_x,h_y=0;
static const void *cur_hw_mouse = NULL;
void ukaz_mysku() void ukaz_mysku()
{ {
@ -23,7 +24,11 @@ void ukaz_mysku()
#ifdef FORCE_SOFTWARE_CURSOR #ifdef FORCE_SOFTWARE_CURSOR
show_ms_cursor(ms_last_event.x-h_x,ms_last_event.y-h_y); show_ms_cursor(ms_last_event.x-h_x,ms_last_event.y-h_y);
#else #else
game_display_show_mouse((const word *)get_registered_ms_cursor(),h_x, h_y); const void *reg = (const word *)get_registered_ms_cursor();
if (reg != cur_hw_mouse) {
cur_hw_mouse = reg;
game_display_show_mouse(reg,h_x, h_y);
}
#endif #endif
} }
} }

View file

@ -126,6 +126,7 @@ int load_pcx(const char *pcx,int32_t fsize,int conv_type,char **buffer, ... )
switch (conv_type) switch (conv_type)
{ {
case A_8BIT: *buffer=(char *)getmem(sz = xsize*ysize+512+16);break; case A_8BIT: *buffer=(char *)getmem(sz = xsize*ysize+512+16);break;
case A_16BIT_ZERO_TRANSP:conv_type = A_16BIT; paleta2[0] = 0x8000;CASE_FALLTHROUGH;
case A_16BIT: *buffer=(char *)getmem(sz = xsize*ysize*2+16);break; case A_16BIT: *buffer=(char *)getmem(sz = xsize*ysize*2+16);break;
case A_FADE_PAL: *buffer=(char *)getmem(sz = xsize*ysize+SHADE_PAL+16);break; case A_FADE_PAL: *buffer=(char *)getmem(sz = xsize*ysize+SHADE_PAL+16);break;
case A_8BIT_NOPAL: *buffer=(char *)getmem(sz = xsize*ysize+16);break; case A_8BIT_NOPAL: *buffer=(char *)getmem(sz = xsize*ysize+16);break;

View file

@ -7,6 +7,7 @@ extern "C" {
#define A_8BIT 8 #define A_8BIT 8
#define A_16BIT 16 #define A_16BIT 16
#define A_16BIT_ZERO_TRANSP (1024+16)
#define A_FADE_PAL (256+8) #define A_FADE_PAL (256+8)
#define A_8BIT_NOPAL (512+8) #define A_8BIT_NOPAL (512+8)
#define A_NORMAL_PAL (768+8) #define A_NORMAL_PAL (768+8)

View file

@ -245,3 +245,33 @@ void game_display_set_icon(const void *icon_data, size_t icon_size) {
auto &sdl = get_sdl_global_context(); auto &sdl = get_sdl_global_context();
sdl.set_window_icon(icon_data, icon_size); sdl.set_window_icon(icon_data, icon_size);
} }
///Load sprite HI format, returns ID of sprite
void game_display_load_sprite(int sprite_id, const unsigned short *hi_image) {
auto &sdl = get_sdl_global_context();
return sdl.load_sprite(sprite_id, hi_image);
}
///show and place sprite at given coordinates
void game_display_place_sprite(int sprite_id, int x, int y) {
auto &sdl = get_sdl_global_context();
sdl.place_sprite(sprite_id,x, y);
}
///show and place (and scale) sprite at given coordinates
void game_display_scale_sprite(int sprite_id, int x, int y, int w, int h) {
auto &sdl = get_sdl_global_context();
sdl.scale_sprite(sprite_id, x, y, w,h);
}
///hide sprite
void game_display_hide_sprite(int sprite_id) {
auto &sdl = get_sdl_global_context();
sdl.hide_sprite(sprite_id);
}
///unload sprite and free index
void game_display_unload_sprite(int sprite_id) {
auto &sdl = get_sdl_global_context();
sdl.unload_sprite(sprite_id);
}
void game_display_sprite_set_zindex(int sprite_id, int zindex) {
auto &sdl = get_sdl_global_context();
sdl.sprite_set_zindex(sprite_id, zindex);
}

View file

@ -27,6 +27,17 @@ void game_display_cancel_quit_request();
void game_display_set_icon(const void *icon_data, size_t icon_size); void game_display_set_icon(const void *icon_data, size_t icon_size);
void game_display_show_mouse(const unsigned short *mouse_image, int finger_x, int finger_y); void game_display_show_mouse(const unsigned short *mouse_image, int finger_x, int finger_y);
void game_display_hide_mouse(); void game_display_hide_mouse();
///Load sprite HI format, sprite_id can be any integer value- if sprite exists it is replaced
void game_display_load_sprite(int sprite_id, const unsigned short *hi_image);
///show and place sprite at given coordinates
void game_display_place_sprite(int sprite_id, int x, int y);
///show and place (and scale) sprite at given coordinates
void game_display_scale_sprite(int sprite_id, int x, int y, int w, int h);
void game_display_sprite_set_zindex(int sprite_id, int zindex);
///hide sprite
void game_display_hide_sprite(int sprite_id);
///unload sprite and free index
void game_display_unload_sprite(int sprite);
void *DxPrepareWalk(int ypos); void *DxPrepareWalk(int ypos);
void DxZoomWalk(void *handle, int ypos, int *points,float phase, void *lodka); void DxZoomWalk(void *handle, int ypos, int *points,float phase, void *lodka);

View file

@ -403,6 +403,10 @@ void SDLContext::refresh_screen() {
_crt_effect.reset(txt); _crt_effect.reset(txt);
} }
} }
for (const auto &sprite: _sprites) if (sprite.shown) {
SDL_Rect rc = to_window_rect(winrc,sprite._rect);
SDL_RenderCopy(_renderer.get(), sprite._txtr.get(), NULL, &rc);
}
if (_mouse) { if (_mouse) {
SDL_Rect recalc_rect = to_window_rect(winrc, _mouse_rect); SDL_Rect recalc_rect = to_window_rect(winrc, _mouse_rect);
SDL_Point f= to_window_point({0,0,winrc.w, winrc.h}, _mouse_finger); SDL_Point f= to_window_point({0,0,winrc.w, winrc.h}, _mouse_finger);
@ -436,7 +440,7 @@ void SDLContext::update_screen() {
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_STREAMING, r.w, r.h)); _mouse.reset(SDL_CreateTexture(_renderer.get(), SDL_PIXELFORMAT_ARGB1555,SDL_TEXTUREACCESS_STATIC, r.w, r.h));
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;
@ -465,6 +469,81 @@ void SDLContext::update_screen() {
slide_transition.emplace(); slide_transition.emplace();
pop_item(iter, *slide_transition); pop_item(iter, *slide_transition);
break; break;
case DisplayRequest::sprite_load: {
int id;
SDL_Rect r;
pop_item(iter, id);
pop_item(iter, r);
std::string_view data = pop_data(iter, r.w*r.h*2);
auto iter = std::find_if(_sprites.begin(), _sprites.end(),[&](const Sprite &x){
return x.id == id;
});
if (iter == _sprites.end()) {
iter = _sprites.insert(iter,{id});
}
iter->_txtr.reset(SDL_CreateTexture(_renderer.get(), SDL_PIXELFORMAT_ARGB1555, SDL_TEXTUREACCESS_STATIC,r.w, r.h));
SDL_SetTextureBlendMode(iter->_txtr.get(), SDL_BLENDMODE_BLEND);
SDL_UpdateTexture(iter->_txtr.get(), NULL, data.data(), r.w*2);
iter->_rect = r;
update_zindex();
} break;
case DisplayRequest::sprite_unload: {
int id;
pop_item(iter, id);
auto iter = std::remove_if(_sprites.begin(), _sprites.end(),[&](const Sprite &x){
return x.id == id;
});
_sprites.erase(iter,_sprites.end());
} break;
case DisplayRequest::sprite_hide: {
int id;
pop_item(iter, id);
auto iter = std::find_if(_sprites.begin(), _sprites.end(),[&](const Sprite &x){
return x.id == id;
});
if (iter != _sprites.end()) iter->shown = false;
} break;
case DisplayRequest::sprite_place: {
int id;
SDL_Point pt;
pop_item(iter, id);
pop_item(iter, pt);
auto iter = std::find_if(_sprites.begin(), _sprites.end(),[&](const Sprite &x){
return x.id == id;
});
if (iter != _sprites.end()) {
iter->shown = true;
iter->_rect.x = pt.x;
iter->_rect.y = pt.y;
}
} break;
case DisplayRequest::sprite_scale: {
int id;
SDL_Rect rc;
pop_item(iter, id);
pop_item(iter, rc);
auto iter = std::find_if(_sprites.begin(), _sprites.end(),[&](const Sprite &x){
return x.id == id;
});
if (iter != _sprites.end()) {
iter->shown = true;
iter->_rect = rc;
}
} break;
case DisplayRequest::sprite_zindex: {
int id;
int zindex;
pop_item(iter, id);
pop_item(iter, zindex);
auto iter = std::find_if(_sprites.begin(), _sprites.end(),[&](const Sprite &x){
return x.id == id;
});
if (iter != _sprites.end()) {
iter->zindex = zindex;
update_zindex();
}
} break;
} }
} }
_display_update_queue.clear(); _display_update_queue.clear();
@ -473,6 +552,13 @@ void SDLContext::update_screen() {
refresh_screen(); refresh_screen();
} }
void SDLContext::update_zindex() {
std::stable_sort(_sprites.begin(), _sprites.end(), [&](const Sprite &a, const Sprite &b){
return a.zindex < b.zindex;
});
}
template<typename T> template<typename T>
requires(std::is_trivially_copy_constructible_v<T>) requires(std::is_trivially_copy_constructible_v<T>)
void SDLContext::push_item(const T &item) { void SDLContext::push_item(const T &item) {
@ -661,27 +747,82 @@ void SDLContext::set_window_icon(const void *icon_data, size_t icon_size) {
extern "C" { extern "C" {
void put_picture_ex(unsigned short x,unsigned short y,const void *p, unsigned short *target_addr, size_t pitch); void put_picture_ex(unsigned short x,unsigned short y,const void *p, unsigned short *target_addr, size_t pitch);
} }
void SDLContext::show_mouse_cursor(const unsigned short *ms_hi_format, SDL_Point finger) {
std::lock_guard _(_mx); void SDLContext::push_hi_image(const unsigned short *image) {
signal_push();
push_item(DisplayRequest::show_mouse_cursor);
SDL_Rect rc; SDL_Rect rc;
rc.w= ms_hi_format[0]; rc.w= image[0];
rc.h =ms_hi_format[1]; rc.h =image[1];
_mouse_finger = finger;
push_item(rc); push_item(rc);
auto sz = _display_update_queue.size(); auto sz = _display_update_queue.size();
auto imgsz = rc.w*rc.h; auto imgsz = rc.w*rc.h;
_display_update_queue.resize(sz+imgsz*2); _display_update_queue.resize(sz+imgsz*2);
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, ms_hi_format, 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;}); 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) {
std::lock_guard _(_mx);
signal_push();
push_item(DisplayRequest::show_mouse_cursor);
push_hi_image(ms_hi_format);
_mouse_finger = finger;
}
void SDLContext::hide_mouse_cursor() { void SDLContext::hide_mouse_cursor() {
std::lock_guard _(_mx); std::lock_guard _(_mx);
signal_push(); signal_push();
push_item(DisplayRequest::hide_mouse_cursor); push_item(DisplayRequest::hide_mouse_cursor);
} }
void SDLContext::load_sprite(int sprite_id, const unsigned short *hi_image) {
std::lock_guard _(_mx);
signal_push();
push_item(DisplayRequest::sprite_load);
push_item(sprite_id);
push_hi_image(hi_image);
}
void SDLContext::place_sprite(int sprite_id, int x, int y) {
std::lock_guard _(_mx);
signal_push();
push_item(DisplayRequest::sprite_place);
push_item(sprite_id);
SDL_Point pt{x,y};
push_item(pt);
}
void SDLContext::scale_sprite(int sprite_id, int x, int y, int w, int h) {
std::lock_guard _(_mx);
signal_push();
push_item(DisplayRequest::sprite_scale);
push_item(sprite_id);
SDL_Rect pt{x,y,w,h};
push_item(pt);
}
void SDLContext::hide_sprite(int sprite_id) {
std::lock_guard _(_mx);
signal_push();
push_item(DisplayRequest::sprite_hide);
push_item(sprite_id);
}
void SDLContext::sprite_set_zindex(int sprite_id, int zindex) {
std::lock_guard _(_mx);
signal_push();
push_item(DisplayRequest::sprite_hide);
push_item(sprite_id);
push_item(zindex);
}
void SDLContext::unload_sprite(int sprite) {
std::lock_guard _(_mx);
signal_push();
push_item(DisplayRequest::sprite_unload);
push_item(sprite);
}

View file

@ -96,6 +96,13 @@ public:
void show_mouse_cursor(const unsigned short *ms_hi_format, SDL_Point finger); void show_mouse_cursor(const unsigned short *ms_hi_format, SDL_Point finger);
void hide_mouse_cursor(); void hide_mouse_cursor();
void load_sprite(int sprite_id, const unsigned short *hi_image);
void place_sprite(int sprite_id, int x, int y);
void scale_sprite(int sprite_id, int x, int y, int w, int h);
void hide_sprite(int sprite_id);
void sprite_set_zindex(int sprite_id, int zindex);
void unload_sprite(int sprite);
protected: protected:
struct SDL_Deleter { struct SDL_Deleter {
@ -128,13 +135,28 @@ protected:
slide_transition, slide_transition,
show_mouse_cursor, //< loads mouse cursor and shows it show_mouse_cursor, //< loads mouse cursor and shows it
hide_mouse_cursor, //< clears mouse cursor hide_mouse_cursor, //< clears mouse cursor
sprite_load,
sprite_unload,
sprite_place,
sprite_scale,
sprite_zindex,
sprite_hide
}; };
struct SDL_Audio_Deleter { struct SDL_Audio_Deleter {
void operator()(SDL_AudioDeviceID x); void operator()(SDL_AudioDeviceID x);
}; };
struct Sprite {
int id = {};
int zindex = {};
std::unique_ptr<SDL_Texture, SDL_Deleter> _txtr = {};
SDL_Rect _rect = {};
bool shown = false;
};
using SpriteList = std::vector<Sprite>;
MS_EVENT ms_event; MS_EVENT ms_event;
@ -170,6 +192,7 @@ protected:
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;
SpriteList _sprites;
Uint32 _update_request_event; Uint32 _update_request_event;
@ -204,5 +227,7 @@ protected:
std::optional<BlendTransitionReq> blend_transition; std::optional<BlendTransitionReq> blend_transition;
std::optional<SlideTransitionReq> slide_transition; std::optional<SlideTransitionReq> slide_transition;
void push_hi_image(const unsigned short *image);
void update_zindex();
}; };