mirror of
https://github.com/ondra-novak/gates_of_skeldal.git
synced 2025-07-15 02:36:40 -04:00
mouse cursor managed by compositor, earthquake spell supported
This commit is contained in:
parent
8fb866f2f5
commit
04ab5898ef
10 changed files with 179 additions and 71 deletions
|
@ -89,8 +89,23 @@ int DxGetResY() {
|
|||
return 480;
|
||||
}
|
||||
void setvesa_displaystart(int x,int y){
|
||||
auto &sdl = get_sdl_global_context();
|
||||
SDL_Rect hidden_from = {};
|
||||
SDL_Rect hidden_where = {};
|
||||
SDL_Rect visible_from = {0,0,640,480};
|
||||
SDL_Rect visible_where = {x,y,640,480};
|
||||
sdl.show_slide_transition(visible_from, visible_where, hidden_from, hidden_where);
|
||||
|
||||
}
|
||||
|
||||
void game_display_show_mouse(const unsigned short *mouse_image, int finger_x, int finger_y) {
|
||||
get_sdl_global_context().show_mouse_cursor(mouse_image,{finger_x, finger_y});
|
||||
}
|
||||
void game_display_hide_mouse() {
|
||||
get_sdl_global_context().hide_mouse_cursor();
|
||||
|
||||
}
|
||||
|
||||
void StripBlt(const void *data, unsigned int startline, uint32_t width) {
|
||||
|
||||
unsigned short *start=startline*GetScreenPitch()+GetScreenAdr();
|
||||
|
|
|
@ -25,6 +25,8 @@ void game_display_update_rect(unsigned short x,unsigned short y,unsigned short x
|
|||
char game_display_is_quit_requested();
|
||||
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();
|
||||
|
||||
void *DxPrepareWalk(int ypos);
|
||||
void DxZoomWalk(void *handle, int ypos, int *points,float phase, void *lodka);
|
||||
|
|
|
@ -30,6 +30,7 @@ void SetWheelMapping(char up, char down) { //todo
|
|||
|
||||
void get_ms_event(MS_EVENT *event) {
|
||||
*event = get_sdl_global_context().getMsEvent();
|
||||
|
||||
}
|
||||
|
||||
void ShareCPU() {
|
||||
|
|
|
@ -282,9 +282,14 @@ void SDLContext::event_loop(std::stop_token stp) {
|
|||
SDL_Rect winrc = get_window_aspect_rect();
|
||||
SDL_Point srcpt = to_source_point(winrc, mspt);
|
||||
ms_event.event = 1;
|
||||
ms_event.event_type = 1;
|
||||
ms_event.event_type |= 1;
|
||||
ms_event.x = srcpt.x;
|
||||
ms_event.y = srcpt.y;
|
||||
if (_mouse) {
|
||||
_mouse_rect.x = e.motion.x;
|
||||
_mouse_rect.y = e.motion.y;
|
||||
refresh_screen();
|
||||
}
|
||||
} else if (e.type == SDL_MOUSEBUTTONDOWN || e.type == SDL_MOUSEBUTTONUP) {
|
||||
int button = e.button.button;
|
||||
int up = e.type == SDL_MOUSEBUTTONUP?1:0;
|
||||
|
@ -296,7 +301,7 @@ void SDLContext::event_loop(std::stop_token stp) {
|
|||
case 2: ms_event.tl3 = !up; shift = 5; break;
|
||||
case 3: ms_event.tl2 = !up; shift = 3; break;
|
||||
}
|
||||
ms_event.event_type = (1<<(shift+up));
|
||||
ms_event.event_type |= (1<<(shift+up));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -349,48 +354,7 @@ void SDLContext::signal_push() {
|
|||
|
||||
}
|
||||
|
||||
void SDLContext::update_screen() {
|
||||
std::optional<BlendTransitionReq> blend_transition;
|
||||
std::optional<SlideTransitionReq> slide_transition;
|
||||
{
|
||||
std::lock_guard _(_mx);
|
||||
if (_display_update_queue.empty()) return;
|
||||
QueueIter iter = _display_update_queue.data();
|
||||
QueueIter end = iter + _display_update_queue.size();
|
||||
while (iter != end) {
|
||||
DisplayRequest req;
|
||||
pop_item(iter, req);
|
||||
switch (req) {
|
||||
case DisplayRequest::update: {
|
||||
SDL_Rect r;
|
||||
pop_item(iter, r);
|
||||
std::string_view data = pop_data(iter, r.w*r.h*2);
|
||||
SDL_UpdateTexture(_texture.get(), &r, data.data(), r.w*2);
|
||||
}
|
||||
break;
|
||||
case DisplayRequest::swap_render_buffers: {
|
||||
std::swap(_texture,_texture2);
|
||||
}
|
||||
break;
|
||||
case DisplayRequest::swap_visible_buffers: {
|
||||
std::swap(_visible_texture,_hidden_texture);
|
||||
blend_transition.reset();
|
||||
slide_transition.reset();
|
||||
}
|
||||
break;
|
||||
case DisplayRequest::blend_transition:
|
||||
blend_transition.emplace();
|
||||
pop_item(iter, *blend_transition);
|
||||
break;
|
||||
case DisplayRequest::slide_transition:
|
||||
slide_transition.emplace();
|
||||
pop_item(iter, *slide_transition);
|
||||
break;
|
||||
}
|
||||
}
|
||||
_display_update_queue.clear();
|
||||
|
||||
}
|
||||
void SDLContext::refresh_screen() {
|
||||
SDL_Rect winrc = get_window_aspect_rect();
|
||||
SDL_RenderClear(_renderer.get());
|
||||
if (slide_transition) {
|
||||
|
@ -438,8 +402,74 @@ void SDLContext::update_screen() {
|
|||
_crt_effect.reset(txt);
|
||||
}
|
||||
}
|
||||
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);
|
||||
recalc_rect.x = _mouse_rect.x - f.x;
|
||||
recalc_rect.y = _mouse_rect.y - f.y;
|
||||
SDL_RenderCopy(_renderer.get(), _mouse.get(), NULL, &recalc_rect);
|
||||
}
|
||||
SDL_RenderCopy(_renderer.get(), _crt_effect.get(), NULL, &winrc);
|
||||
SDL_RenderPresent(_renderer.get());
|
||||
|
||||
}
|
||||
|
||||
void SDLContext::update_screen() {
|
||||
{
|
||||
std::lock_guard _(_mx);
|
||||
if (_display_update_queue.empty()) return;
|
||||
QueueIter iter = _display_update_queue.data();
|
||||
QueueIter end = iter + _display_update_queue.size();
|
||||
while (iter != end) {
|
||||
DisplayRequest req;
|
||||
pop_item(iter, req);
|
||||
switch (req) {
|
||||
case DisplayRequest::update: {
|
||||
SDL_Rect r;
|
||||
pop_item(iter, r);
|
||||
std::string_view data = pop_data(iter, r.w*r.h*2);
|
||||
SDL_UpdateTexture(_texture.get(), &r, data.data(), r.w*2);
|
||||
}
|
||||
break;
|
||||
case DisplayRequest::show_mouse_cursor: {
|
||||
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));
|
||||
SDL_SetTextureBlendMode(_mouse.get(), SDL_BLENDMODE_BLEND);
|
||||
_mouse_rect.w = r.w;
|
||||
_mouse_rect.h = r.h;
|
||||
SDL_UpdateTexture(_mouse.get(), NULL, data.data(), r.w*2);
|
||||
}
|
||||
break;
|
||||
case DisplayRequest::hide_mouse_cursor: {
|
||||
_mouse.reset();
|
||||
}
|
||||
break;
|
||||
case DisplayRequest::swap_render_buffers: {
|
||||
std::swap(_texture,_texture2);
|
||||
}
|
||||
break;
|
||||
case DisplayRequest::swap_visible_buffers: {
|
||||
std::swap(_visible_texture,_hidden_texture);
|
||||
blend_transition.reset();
|
||||
slide_transition.reset();
|
||||
}
|
||||
break;
|
||||
case DisplayRequest::blend_transition:
|
||||
blend_transition.emplace();
|
||||
pop_item(iter, *blend_transition);
|
||||
break;
|
||||
case DisplayRequest::slide_transition:
|
||||
slide_transition.emplace();
|
||||
pop_item(iter, *slide_transition);
|
||||
break;
|
||||
}
|
||||
}
|
||||
_display_update_queue.clear();
|
||||
|
||||
}
|
||||
refresh_screen();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
@ -625,5 +655,32 @@ void SDLContext::set_window_icon(const void *icon_data, size_t icon_size) {
|
|||
} else {
|
||||
SDL_SetWindowIcon(_window.get(), surface);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
SDL_Rect rc;
|
||||
rc.w= ms_hi_format[0];
|
||||
rc.h =ms_hi_format[1];
|
||||
_mouse_finger = finger;
|
||||
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);
|
||||
std::transform(trg, trg+imgsz, trg, [](unsigned short &x)->unsigned short {return x ^ 0x8000;});
|
||||
}
|
||||
|
||||
void SDLContext::hide_mouse_cursor() {
|
||||
std::lock_guard _(_mx);
|
||||
signal_push();
|
||||
push_item(DisplayRequest::hide_mouse_cursor);
|
||||
|
||||
}
|
||||
|
|
|
@ -69,6 +69,7 @@ public:
|
|||
std::lock_guard _(_mx);
|
||||
MS_EVENT out = ms_event;
|
||||
ms_event.event = 0;
|
||||
ms_event.event_type = 0;
|
||||
return out;
|
||||
}
|
||||
|
||||
|
@ -92,6 +93,9 @@ public:
|
|||
_quit_requested = false;
|
||||
}
|
||||
|
||||
void show_mouse_cursor(const unsigned short *ms_hi_format, SDL_Point finger);
|
||||
void hide_mouse_cursor();
|
||||
|
||||
protected:
|
||||
|
||||
struct SDL_Deleter {
|
||||
|
@ -121,7 +125,9 @@ protected:
|
|||
swap_render_buffers,
|
||||
swap_visible_buffers,
|
||||
blend_transition,
|
||||
slide_transition
|
||||
slide_transition,
|
||||
show_mouse_cursor, //< loads mouse cursor and shows it
|
||||
hide_mouse_cursor, //< clears mouse cursor
|
||||
};
|
||||
|
||||
struct SDL_Audio_Deleter {
|
||||
|
@ -143,6 +149,7 @@ protected:
|
|||
std::unique_ptr<SDL_Texture, SDL_Deleter> _texture;
|
||||
std::unique_ptr<SDL_Texture, SDL_Deleter> _texture2;
|
||||
std::unique_ptr<SDL_Texture, SDL_Deleter> _crt_effect;
|
||||
std::unique_ptr<SDL_Texture, SDL_Deleter> _mouse;
|
||||
unique_value<SDL_AudioDeviceID, SDL_Audio_Deleter> _audio;
|
||||
SDL_Texture *_visible_texture;
|
||||
SDL_Texture *_hidden_texture;
|
||||
|
@ -161,6 +168,8 @@ protected:
|
|||
std::vector<char> _display_update_queue;
|
||||
using QueueIter = const char *;
|
||||
std::queue<uint16_t> _keyboard_queue;
|
||||
SDL_Rect _mouse_rect;
|
||||
SDL_Point _mouse_finger;
|
||||
|
||||
Uint32 _update_request_event;
|
||||
|
||||
|
@ -191,5 +200,9 @@ protected:
|
|||
void signal_push();
|
||||
|
||||
|
||||
void refresh_screen();
|
||||
std::optional<BlendTransitionReq> blend_transition;
|
||||
std::optional<SlideTransitionReq> slide_transition;
|
||||
|
||||
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue