mirror of
https://github.com/ondra-novak/gates_of_skeldal.git
synced 2025-07-04 21:50:38 -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
31
README.md
31
README.md
|
@ -46,18 +46,18 @@ This fix will only work with the new code. (It will not work in earlier releases
|
||||||
|
|
||||||
## Goals
|
## Goals
|
||||||
|
|
||||||
1) to rewrite all Intel 386 depend code to independed variant.
|
1. to rewrite all Intel 386 depend code to independed variant.
|
||||||
2) tp rewrite all ASM code to C
|
2. tp rewrite all ASM code to C
|
||||||
3) tp improve C code by using up C20 features (original is C89)
|
3. tp improve C code by using up C20 features (original is C89)
|
||||||
4) a new code should be written in C++20
|
4. a new code should be written in C++20
|
||||||
5) to fix all bugs, to run under valgrind and to use other tools to find bugs
|
5. to fix all bugs, to run under valgrind and to use other tools to find bugs
|
||||||
6) to render using SDL - Fullscreen and Windowed
|
6. to render using SDL - Fullscreen and Windowed z
|
||||||
7) to implement sounds and music using SDL sound library
|
7. to implement sounds and music using SDL sound library
|
||||||
8) to define and polish platform API - to allow future ports.
|
8. to define and polish platform API - to allow future ports.
|
||||||
9) Install/Setup GUI application - by using some platform independed library
|
9. Install/Setup GUI application - by using some platform independed library
|
||||||
10) Target platforms: Windows, Ubuntu/Debian/Linux, MacOS.
|
10. Target platforms: Windows, Ubuntu/Debian/Linux, MacOS.
|
||||||
11) ADV (custom adventure) support for existing adventures
|
11. ADV (custom adventure) support for existing adventures
|
||||||
12) - later MapEdit and other tools
|
12. - later MapEdit and other tools
|
||||||
|
|
||||||
## Considered changes in the game
|
## Considered changes in the game
|
||||||
1) Campaigns - the player will have saved games sorted by campaign and the number of saved positions in a campaign will not be limited. The only limitation will be the number of campaigns to 10, as the graphics only allow for 10 positions.
|
1) Campaigns - the player will have saved games sorted by campaign and the number of saved positions in a campaign will not be limited. The only limitation will be the number of campaigns to 10, as the graphics only allow for 10 positions.
|
||||||
|
@ -72,10 +72,9 @@ This fix will only work with the new code. (It will not work in earlier releases
|
||||||
2. Leaving a dead member on the map does not make them completely lost. It is possible to return to the map later and revive them.
|
2. Leaving a dead member on the map does not make them completely lost. It is possible to return to the map later and revive them.
|
||||||
3. The "Reincarnation" spell can be used to revive characters lost due to falling into the abyss, drowning, burning, or any other means where the character's corpse is out of reach. In this case, the revived character is automatically transported to the caster's location.
|
3. The "Reincarnation" spell can be used to revive characters lost due to falling into the abyss, drowning, burning, or any other means where the character's corpse is out of reach. In this case, the revived character is automatically transported to the caster's location.
|
||||||
4. The "Merge 3" spell also applies to all character corpses
|
4. The "Merge 3" spell also applies to all character corpses
|
||||||
5. The "Mobility" attribute has a more subtle effect on the action points gained during combat. A character may gain one additional action point during combat after a certain number of rounds if their "Mobility" attribute number approaches the threshold. On the other hand, if their mobility is below 15, they may not gain any action points in that round.
|
5. The "Dexterity" attribute is on the opposite side of "Mobility" because it is primarily intended for use in shooting, where shooting takes longer (having to draw an arrow, aim, and fire) than a melee attack. To support this attribute, the rules for two-weapon combat have been changed. In order for a character to hold and fight with two weapons, the sum of the required attributes of both weapons must be met. For example, weapons with strength requirements of 20 and 30 mean having a strength of 50 to wield both. However, if a character has "Dexterity", they can use this attribute instead of the required attribute of the other weapon, with the higher number of the pair being considered, while still having to meet the requirements for both weapons individually. So to hold both weapons in the example above, they would need "Strength" = 30 and "Dexterity = 30"
|
||||||
6. The "Dexterity" attribute is on the opposite side of "Mobility" because it is primarily intended for use in shooting, where shooting takes longer (having to draw an arrow, aim, and fire) than a melee attack. To support this attribute, the rules for two-weapon combat have been changed. In order for a character to hold and fight with two weapons, the sum of the required attributes of both weapons must be met. For example, weapons with strength requirements of 20 and 30 mean having a strength of 50 to wield both. However, if a character has "Dexterity", they can use this attribute instead of the required attribute of the other weapon, with the higher number of the pair being considered, while still having to meet the requirements for both weapons individually. So to hold both weapons in the example above, they would need "Strength" = 30 and "Dexterity = 30"
|
6. Attacking with two melee weapons causes two attacks in one action.
|
||||||
7. Attacking with two melee weapons causes two attacks in one action.
|
7. When making a melee attack, the higher number from "Strength" and "Dexterity" is used as the attack attribute. However, this does not mean that a character with higher Dexterity can wield a weapon with a higher "Strength" attribute requirement. (Finesse rule)
|
||||||
8. When making a melee attack, the higher number from "Strength" and "Dexterity" is used as the attack attribute. However, this does not mean that a character with higher Dexterity can wield a weapon with a higher "Strength" attribute requirement. (Finesse rule)
|
|
||||||
|
|
||||||
|
|
||||||
## Console commands
|
## Console commands
|
||||||
|
|
|
@ -51,6 +51,8 @@ void char2_32(word *posit,const word *font,char znak);
|
||||||
word charsize(const word *font,char znak);
|
word charsize(const word *font,char znak);
|
||||||
//#pragma aux charsize parm [esi] [eax]
|
//#pragma aux charsize parm [esi] [eax]
|
||||||
void put_picture(word x,word y,const void *p);
|
void put_picture(word x,word y,const void *p);
|
||||||
|
|
||||||
|
void put_picture_ex(word x,word y,const void *p, word *target_addr, size_t pitch);
|
||||||
//#pragma aux put_picture parm [esi] [eax] [edi] modify [ebx ecx edx]
|
//#pragma aux put_picture parm [esi] [eax] [edi] modify [ebx ecx edx]
|
||||||
void get_picture(word x,word y,word xs,word ys,void *p);
|
void get_picture(word x,word y,word xs,word ys,void *p);
|
||||||
//#pragma aux get_picture parm [esi] [eax] [ebx] [ecx] [edi] modify [edx]
|
//#pragma aux get_picture parm [esi] [eax] [ebx] [ecx] [edi] modify [edx]
|
||||||
|
@ -113,6 +115,7 @@ void line32(word x1,word y1, word x2, word y2);
|
||||||
void position(word x,word y);
|
void position(word x,word y);
|
||||||
void show_ms_cursor(integer x,integer y);
|
void show_ms_cursor(integer x,integer y);
|
||||||
void *register_ms_cursor(const void *cursor);
|
void *register_ms_cursor(const void *cursor);
|
||||||
|
const void *get_registered_ms_cursor();
|
||||||
void move_ms_cursor(integer newx,integer newy,char nodraw);
|
void move_ms_cursor(integer newx,integer newy,char nodraw);
|
||||||
void hide_ms_cursor(void);
|
void hide_ms_cursor(void);
|
||||||
void redraw_ms_cursor_on_screen(void);
|
void redraw_ms_cursor_on_screen(void);
|
||||||
|
|
|
@ -508,6 +508,10 @@ void showview_lo(word x,word y,word xs,word ys)
|
||||||
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
const void *get_registered_ms_cursor() {
|
||||||
|
return mscursor;
|
||||||
|
}
|
||||||
void show_ms_cursor(integer x,integer y)
|
void show_ms_cursor(integer x,integer y)
|
||||||
{
|
{
|
||||||
integer xs,ys;
|
integer xs,ys;
|
||||||
|
|
|
@ -315,11 +315,12 @@ chsend: and eax,0ffffh
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void put_picture(word x,word y,const void *p)
|
|
||||||
|
void put_picture_ex(word x,word y,const void *p, word *target_addr, size_t pitch)
|
||||||
//#pragma aux put_picture parm [esi] [eax] [edi] modify [ebx ecx edx]
|
//#pragma aux put_picture parm [esi] [eax] [edi] modify [ebx ecx edx]
|
||||||
{
|
{
|
||||||
int32_t scr_linelen2 = GetScreenPitch();
|
int32_t scr_linelen2 = pitch;
|
||||||
word *adr=GetScreenAdr()+scr_linelen2*y+x;
|
word *adr=target_addr+scr_linelen2*y+x;
|
||||||
const word *data=p;
|
const word *data=p;
|
||||||
word xs=data[0];
|
word xs=data[0];
|
||||||
word ys=data[1];
|
word ys=data[1];
|
||||||
|
@ -391,6 +392,10 @@ void put_picture(word x,word y,const void *p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void put_picture(word x,word y,const void *p) {
|
||||||
|
put_picture_ex(x, y, p, GetScreenAdr(), GetScreenPitch());
|
||||||
|
|
||||||
|
}
|
||||||
void get_picture(word x,word y,word xs,word ys,void *p)
|
void get_picture(word x,word y,word xs,word ys,void *p)
|
||||||
{
|
{
|
||||||
int32_t scr_linelen2 = GetScreenPitch();
|
int32_t scr_linelen2 = GetScreenPitch();
|
||||||
|
|
|
@ -20,14 +20,20 @@ void ukaz_mysku()
|
||||||
visible--;
|
visible--;
|
||||||
if (!visible)
|
if (!visible)
|
||||||
{
|
{
|
||||||
|
#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
|
||||||
|
game_display_show_mouse((const word *)get_registered_ms_cursor(),h_x, h_y);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void schovej_mysku()
|
void schovej_mysku()
|
||||||
{
|
{
|
||||||
|
#ifdef FORCE_SOFTWARE_CURSOR
|
||||||
if (!visible)
|
if (!visible)
|
||||||
hide_ms_cursor();
|
hide_ms_cursor();
|
||||||
|
#endif
|
||||||
visible++;
|
visible++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,6 +63,7 @@ void ms_idle_event(EVENT_MSG *info,void *user_data)
|
||||||
|
|
||||||
void ms_draw_event(EVENT_MSG *info,void *user_data)
|
void ms_draw_event(EVENT_MSG *info,void *user_data)
|
||||||
{
|
{
|
||||||
|
#ifdef FORCE_SOFTWARE_CURSOR
|
||||||
MS_EVENT *ms_ev;
|
MS_EVENT *ms_ev;
|
||||||
|
|
||||||
user_data;
|
user_data;
|
||||||
|
@ -66,11 +73,13 @@ void ms_draw_event(EVENT_MSG *info,void *user_data)
|
||||||
if (ms_ev->event_type & 1)
|
if (ms_ev->event_type & 1)
|
||||||
if (!visible) move_ms_cursor(ms_ev->x-h_x,ms_ev->y-h_y,0);
|
if (!visible) move_ms_cursor(ms_ev->x-h_x,ms_ev->y-h_y,0);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void update_mysky(void)
|
void update_mysky(void)
|
||||||
{
|
{
|
||||||
|
#ifdef FORCE_SOFTWARE_CURSOR
|
||||||
MS_EVENT x;
|
MS_EVENT x;
|
||||||
|
|
||||||
get_ms_event(&x);
|
get_ms_event(&x);
|
||||||
|
@ -80,6 +89,7 @@ void update_mysky(void)
|
||||||
x.event = 0;
|
x.event = 0;
|
||||||
}
|
}
|
||||||
if(!visible) move_ms_cursor(x.x-h_x,x.y-h_y,0);
|
if(!visible) move_ms_cursor(x.x-h_x,x.y-h_y,0);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
char je_myska_zobrazena()
|
char je_myska_zobrazena()
|
||||||
|
@ -94,12 +104,6 @@ void set_ms_finger(int x,int y)
|
||||||
h_y=y;
|
h_y=y;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *mouse()
|
|
||||||
{
|
|
||||||
send_message(E_ADD,E_WATCH,ms_idle_event);
|
|
||||||
send_message(E_ADD,E_MOUSE,ms_draw_event);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
short init_mysky()
|
short init_mysky()
|
||||||
{
|
{
|
||||||
|
@ -107,7 +111,10 @@ short init_mysky()
|
||||||
// i=install_mouse_handler();
|
// i=install_mouse_handler();
|
||||||
// hranice_mysky(0,0,639,479);
|
// hranice_mysky(0,0,639,479);
|
||||||
visible=1;
|
visible=1;
|
||||||
send_message(E_INIT,mouse);
|
send_message(E_ADD,E_WATCH,ms_idle_event);
|
||||||
|
#ifdef FORCE_SOFTWARE_CURSOR
|
||||||
|
send_message(E_ADD,E_MOUSE,ms_draw_event);
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,7 +123,9 @@ short done_mysky()
|
||||||
|
|
||||||
// i=deinstall_mouse_handler();
|
// i=deinstall_mouse_handler();
|
||||||
send_message(E_DONE,E_WATCH,ms_idle_event);
|
send_message(E_DONE,E_WATCH,ms_idle_event);
|
||||||
|
#ifdef FORCE_SOFTWARE_CURSOR
|
||||||
send_message(E_DONE,E_MOUSE,ms_draw_event);
|
send_message(E_DONE,E_MOUSE,ms_draw_event);
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -89,8 +89,23 @@ int DxGetResY() {
|
||||||
return 480;
|
return 480;
|
||||||
}
|
}
|
||||||
void setvesa_displaystart(int x,int y){
|
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) {
|
void StripBlt(const void *data, unsigned int startline, uint32_t width) {
|
||||||
|
|
||||||
unsigned short *start=startline*GetScreenPitch()+GetScreenAdr();
|
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();
|
char game_display_is_quit_requested();
|
||||||
void game_display_cancel_quit_request();
|
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_hide_mouse();
|
||||||
|
|
||||||
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);
|
||||||
|
|
|
@ -30,6 +30,7 @@ void SetWheelMapping(char up, char down) { //todo
|
||||||
|
|
||||||
void get_ms_event(MS_EVENT *event) {
|
void get_ms_event(MS_EVENT *event) {
|
||||||
*event = get_sdl_global_context().getMsEvent();
|
*event = get_sdl_global_context().getMsEvent();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShareCPU() {
|
void ShareCPU() {
|
||||||
|
|
|
@ -282,9 +282,14 @@ void SDLContext::event_loop(std::stop_token stp) {
|
||||||
SDL_Rect winrc = get_window_aspect_rect();
|
SDL_Rect winrc = get_window_aspect_rect();
|
||||||
SDL_Point srcpt = to_source_point(winrc, mspt);
|
SDL_Point srcpt = to_source_point(winrc, mspt);
|
||||||
ms_event.event = 1;
|
ms_event.event = 1;
|
||||||
ms_event.event_type = 1;
|
ms_event.event_type |= 1;
|
||||||
ms_event.x = srcpt.x;
|
ms_event.x = srcpt.x;
|
||||||
ms_event.y = srcpt.y;
|
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) {
|
} else if (e.type == SDL_MOUSEBUTTONDOWN || e.type == SDL_MOUSEBUTTONUP) {
|
||||||
int button = e.button.button;
|
int button = e.button.button;
|
||||||
int up = e.type == SDL_MOUSEBUTTONUP?1:0;
|
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 2: ms_event.tl3 = !up; shift = 5; break;
|
||||||
case 3: ms_event.tl2 = !up; shift = 3; 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() {
|
void SDLContext::refresh_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();
|
|
||||||
|
|
||||||
}
|
|
||||||
SDL_Rect winrc = get_window_aspect_rect();
|
SDL_Rect winrc = get_window_aspect_rect();
|
||||||
SDL_RenderClear(_renderer.get());
|
SDL_RenderClear(_renderer.get());
|
||||||
if (slide_transition) {
|
if (slide_transition) {
|
||||||
|
@ -438,8 +402,74 @@ void SDLContext::update_screen() {
|
||||||
_crt_effect.reset(txt);
|
_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_RenderCopy(_renderer.get(), _crt_effect.get(), NULL, &winrc);
|
||||||
SDL_RenderPresent(_renderer.get());
|
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>
|
template<typename T>
|
||||||
|
@ -625,5 +655,32 @@ void SDLContext::set_window_icon(const void *icon_data, size_t icon_size) {
|
||||||
} else {
|
} else {
|
||||||
SDL_SetWindowIcon(_window.get(), surface);
|
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);
|
std::lock_guard _(_mx);
|
||||||
MS_EVENT out = ms_event;
|
MS_EVENT out = ms_event;
|
||||||
ms_event.event = 0;
|
ms_event.event = 0;
|
||||||
|
ms_event.event_type = 0;
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,6 +93,9 @@ public:
|
||||||
_quit_requested = false;
|
_quit_requested = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void show_mouse_cursor(const unsigned short *ms_hi_format, SDL_Point finger);
|
||||||
|
void hide_mouse_cursor();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
struct SDL_Deleter {
|
struct SDL_Deleter {
|
||||||
|
@ -121,7 +125,9 @@ protected:
|
||||||
swap_render_buffers,
|
swap_render_buffers,
|
||||||
swap_visible_buffers,
|
swap_visible_buffers,
|
||||||
blend_transition,
|
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 {
|
struct SDL_Audio_Deleter {
|
||||||
|
@ -143,6 +149,7 @@ protected:
|
||||||
std::unique_ptr<SDL_Texture, SDL_Deleter> _texture;
|
std::unique_ptr<SDL_Texture, SDL_Deleter> _texture;
|
||||||
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;
|
||||||
unique_value<SDL_AudioDeviceID, SDL_Audio_Deleter> _audio;
|
unique_value<SDL_AudioDeviceID, SDL_Audio_Deleter> _audio;
|
||||||
SDL_Texture *_visible_texture;
|
SDL_Texture *_visible_texture;
|
||||||
SDL_Texture *_hidden_texture;
|
SDL_Texture *_hidden_texture;
|
||||||
|
@ -161,6 +168,8 @@ protected:
|
||||||
std::vector<char> _display_update_queue;
|
std::vector<char> _display_update_queue;
|
||||||
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_Point _mouse_finger;
|
||||||
|
|
||||||
Uint32 _update_request_event;
|
Uint32 _update_request_event;
|
||||||
|
|
||||||
|
@ -191,5 +200,9 @@ protected:
|
||||||
void signal_push();
|
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