mirror of
https://github.com/ondra-novak/gates_of_skeldal.git
synced 2025-07-09 16:10:27 -04:00
boat in exploration is drawn by compositor
This commit is contained in:
parent
232dae6708
commit
05c1f952c4
12 changed files with 323 additions and 72 deletions
|
@ -245,3 +245,33 @@ void game_display_set_icon(const void *icon_data, size_t icon_size) {
|
|||
auto &sdl = get_sdl_global_context();
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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_show_mouse(const unsigned short *mouse_image, int finger_x, int finger_y);
|
||||
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 DxZoomWalk(void *handle, int ypos, int *points,float phase, void *lodka);
|
||||
|
|
|
@ -403,6 +403,10 @@ void SDLContext::refresh_screen() {
|
|||
_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) {
|
||||
SDL_Rect recalc_rect = to_window_rect(winrc, _mouse_rect);
|
||||
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;
|
||||
pop_item(iter, r);
|
||||
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);
|
||||
_mouse_rect.w = r.w;
|
||||
_mouse_rect.h = r.h;
|
||||
|
@ -465,6 +469,81 @@ void SDLContext::update_screen() {
|
|||
slide_transition.emplace();
|
||||
pop_item(iter, *slide_transition);
|
||||
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();
|
||||
|
@ -473,6 +552,13 @@ void SDLContext::update_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>
|
||||
requires(std::is_trivially_copy_constructible_v<T>)
|
||||
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" {
|
||||
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);
|
||||
signal_push();
|
||||
push_item(DisplayRequest::show_mouse_cursor);
|
||||
|
||||
void SDLContext::push_hi_image(const unsigned short *image) {
|
||||
SDL_Rect rc;
|
||||
rc.w= ms_hi_format[0];
|
||||
rc.h =ms_hi_format[1];
|
||||
_mouse_finger = finger;
|
||||
rc.w= image[0];
|
||||
rc.h =image[1];
|
||||
push_item(rc);
|
||||
auto sz = _display_update_queue.size();
|
||||
auto imgsz = rc.w*rc.h;
|
||||
_display_update_queue.resize(sz+imgsz*2);
|
||||
unsigned short *trg = reinterpret_cast<unsigned short *>(_display_update_queue.data()+sz);
|
||||
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;});
|
||||
}
|
||||
|
||||
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() {
|
||||
std::lock_guard _(_mx);
|
||||
signal_push();
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -96,6 +96,13 @@ public:
|
|||
void show_mouse_cursor(const unsigned short *ms_hi_format, SDL_Point finger);
|
||||
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:
|
||||
|
||||
struct SDL_Deleter {
|
||||
|
@ -128,13 +135,28 @@ protected:
|
|||
slide_transition,
|
||||
show_mouse_cursor, //< loads mouse cursor and shows it
|
||||
hide_mouse_cursor, //< clears mouse cursor
|
||||
|
||||
sprite_load,
|
||||
sprite_unload,
|
||||
sprite_place,
|
||||
sprite_scale,
|
||||
sprite_zindex,
|
||||
sprite_hide
|
||||
};
|
||||
|
||||
struct SDL_Audio_Deleter {
|
||||
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;
|
||||
|
@ -170,6 +192,7 @@ protected:
|
|||
std::queue<uint16_t> _keyboard_queue;
|
||||
SDL_Rect _mouse_rect;
|
||||
SDL_Point _mouse_finger;
|
||||
SpriteList _sprites;
|
||||
|
||||
Uint32 _update_request_event;
|
||||
|
||||
|
@ -204,5 +227,7 @@ protected:
|
|||
std::optional<BlendTransitionReq> blend_transition;
|
||||
std::optional<SlideTransitionReq> slide_transition;
|
||||
|
||||
void push_hi_image(const unsigned short *image);
|
||||
void update_zindex();
|
||||
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue