diff --git a/game/enemy.c b/game/enemy.c index 5e4593a..b9db33f 100644 --- a/game/enemy.c +++ b/game/enemy.c @@ -373,7 +373,7 @@ void load_enemies(short *data,int size,int *grptr,TMOB *template,int32_t tsize) { mobs[i]=b[j]; if (~mobs[i].vlajky & MOB_MOBILE) mob_map[data[0]]=i+MOB_START; - if (mobs[i].palette>=0)mobs[i].palette=rnd(mobs[i].palette);else mobs[i].palette=abs(mobs[i].palette); + if (mobs[i].palette>0)mobs[i].palette=rnd(mobs[i].palette);else mobs[i].palette=abs(mobs[i].palette); mobs[i].sector=data[0]; mobs[i].dir=(data[1]>>14)&0x3; mobs[i].home_pos=data[0]; diff --git a/game/engine1.c b/game/engine1.c index 739dfbb..65b1c91 100644 --- a/game/engine1.c +++ b/game/engine1.c @@ -456,7 +456,7 @@ static void zooming_forward_backward(word *background,char back) { int32_t tmp=get_timer_value(); void *buffer=DxPrepareWalk(SCREEN_OFFLINE); - int tpoints[4]={90,31,90+460,31+259}; + int tpoints[4]={90,31,90+460,31+270}; int maxtime=5*zoom_speed(-1); int curtime; @@ -467,7 +467,7 @@ static void zooming_forward_backward(word *background,char back) curtime=get_timer_value()-tmp; phase=(curtime)*(1.0f/(float)maxtime); //phase=(float)sin(3.14159265*0.5f*phase); - if (back) phase=1.0-phase; + if (back) phase=-phase; DxZoomWalk(buffer, SCREEN_OFFLINE, tpoints,phase, NULL); do_events(); } @@ -532,7 +532,7 @@ static void turn_left_right(char right) curtime=get_timer_value()-tmp; phase=(curtime)*(1.0f/(float)maxtime); //phase=(float)sin(3.14159265*0.5f*phase); - DxTurn(buffer,right,SCREEN_OFFLINE,90,phase,NULL); + DxTurn(buffer,SCREEN_OFFLINE,90,right?-phase:phase,NULL); do_events(); } while (curtimex-(BUYBOX_X+SHP_ICPLCX); @@ -2422,10 +2423,12 @@ static void shop_mouse_event(EVENT_MSG *msg,void **unused) } if (cc) { - inv_item_info_box(msg,unused); + inv_item_info_box(&msgc,unused); last_pos=-1; } + destroy_message(&msgc); } + } static __inline void copy_data(char **src, void *target, int size) { diff --git a/game/realgame.c b/game/realgame.c index 3ed2325..d1cdc8a 100644 --- a/game/realgame.c +++ b/game/realgame.c @@ -1600,6 +1600,7 @@ void step_zoom(char smer) anim_sipky(0,255); hide_ms_at(385); ukaz_mysku(); + redraw_ms_cursor_on_screen(); if (set_halucination) do_halucinace(); if (loadlevel.name[0]) { @@ -1624,17 +1625,12 @@ void step_zoom(char smer) if (!cancel_pass) { render_scene(viewsector,viewdir); - if (smer==2) - { - OutBuffer2nd(); - if (!nopass) shift_zoom(smer); - } - else - { - shift_zoom(smer); - OutBuffer2nd(); - if (nopass) shift_zoom(smer+2); - } + OutBuffer2nd(); + sort_groups(); + bott_draw(0); + other_draw(); + shift_zoom(smer); + if (smer==0 && nopass) shift_zoom(smer+2); if (battle || (game_extras & EX_ALWAYS_MINIMAP)) draw_medium_map(); sort_groups(); bott_draw(0); @@ -1672,6 +1668,9 @@ void turn_zoom(int smer) viewdir=(viewdir+smer)&3; render_scene(viewsector,viewdir); hide_ms_at(387); + OutBuffer2nd(); + other_draw(); + bott_draw(0); if (smer==1) { anim_sipky(H_SIPKY_SV,1); @@ -1685,9 +1684,7 @@ void turn_zoom(int smer) turn_right(); } chod_s_postavama(0); - OutBuffer2nd(); if (battle || (game_extras & EX_ALWAYS_MINIMAP)) draw_medium_map(); - other_draw(); update_mysky(); ukaz_mysku(); showview(0,0,0,0); diff --git a/libs/bgraph.h b/libs/bgraph.h index 5a1851d..d958aa8 100644 --- a/libs/bgraph.h +++ b/libs/bgraph.h @@ -116,6 +116,7 @@ void show_ms_cursor(integer x,integer y); void *register_ms_cursor(void *cursor); void move_ms_cursor(integer newx,integer newy,char nodraw); void hide_ms_cursor(void); +void redraw_ms_cursor_on_screen(void); int text_height(char *text); int text_width(char *text); void set_aligned_position(int x,int y,char alignx, char aligny,char *text); diff --git a/libs/bgraph2.c b/libs/bgraph2.c index 72f4977..8261077 100644 --- a/libs/bgraph2.c +++ b/libs/bgraph2.c @@ -509,8 +509,18 @@ void show_ms_cursor(integer x,integer y) void hide_ms_cursor() { put_picture(mscuroldx,mscuroldy,mssavebuffer); + } +void redraw_ms_cursor_on_screen(void) { + if (mssavebuffer) { + integer xs=*(integer *)mssavebuffer; + integer ys=*((integer *)mssavebuffer+1); + showview(mscuroldx,mscuroldy,xs,ys); + } +} + + void *register_ms_cursor(void *cursor) { integer xs,ys; diff --git a/platform/error.cpp b/platform/error.cpp index b14aafb..5b8e622 100644 --- a/platform/error.cpp +++ b/platform/error.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -8,7 +9,9 @@ extern "C" { void display_error(const char *text) { + char failed_because_error = 0; std::cerr << "ERROR:" << text << std::endl; + assert(failed_because_error); } diff --git a/platform/legacy_coroutines.cpp b/platform/legacy_coroutines.cpp index e7ee1a1..3af63f8 100644 --- a/platform/legacy_coroutines.cpp +++ b/platform/legacy_coroutines.cpp @@ -147,12 +147,9 @@ char is_running(int id_num) { return id_num < 0 || task_list.find(id_num) != task_list.end(); } void unsuspend_task(EVENT_MSG *msg) { + if (current_task_inst) return; msg_queue.push({msg, current_task_inst}); - if (current_task_inst) { - switch_to_task(NULL); - } else { - flush_message_queue(); - } + flush_message_queue(); } void task_sleep(void) { diff --git a/platform/sdl/BGraph2.cpp b/platform/sdl/BGraph2.cpp index 372e8d6..ea2b125 100644 --- a/platform/sdl/BGraph2.cpp +++ b/platform/sdl/BGraph2.cpp @@ -90,22 +90,96 @@ void DXCopyRects64(unsigned short x,unsigned short y,unsigned short xs,unsigned } void *DxPrepareWalk(int ypos) { - return 0; + auto &sdl = get_sdl_global_context(); + sdl.swap_render_buffers(); + sdl.present_rect(screen_buffer.get(), screen_pitch, 0,0,640,480);//new is in hidden buffer + return NULL; } void DxZoomWalk(void *handle, int ypos, int *points,float phase, void *lodka) { - + auto &sdl = get_sdl_global_context(); + if (phase>1.0) phase=1.0f; + if (phase<-1.0) phase=-1.0f; + SDL_Rect rc1; + rc1.x=0; + rc1.y=0+ypos; + rc1.w=640; + rc1.h=360; + SDL_Rect rc2; + rc2.x=points[0]; + rc2.y=points[1]+ypos; + rc2.w=points[2]-rc2.x; + rc2.h=points[3]-rc2.y; + sdl.show_blend_transition({0,ypos,640,360},rc1, rc2, phase); } void DxDoneWalk(void *handle) { - + auto &sdl = get_sdl_global_context(); + sdl.swap_display_buffers(); //present hidden buffer } void *DxPrepareTurn(int ypos) { - return 0; + auto &sdl = get_sdl_global_context(); + sdl.swap_render_buffers(); + sdl.present_rect(screen_buffer.get(), screen_pitch, 0,0,640,480);//new is in hidden buffer + return NULL; } -void DxTurn(void *handle, char right, int ypos,int border, float phase, void *lodka) { +void DxTurn(void *handle, int ypos,int border, float phase, void *lodka) { + auto &sdl = get_sdl_global_context(); + if (phase>1.0) phase=1.0f; + if (phase<-1.0) phase=-1.0f; + int width = 640-2*border; + SDL_Rect visible_from{0,ypos,640,360}; + SDL_Rect visible_where; + SDL_Rect hidden_from{0,ypos,640,360}; + SDL_Rect hidden_where; + if (phase > 0) { + hidden_from.x = border; + } else if (phase < 0) { + visible_from.x = border; + } else { + return ; + } + visible_from.w-= border; + hidden_from.w -= border; + visible_where = visible_from; + hidden_where = hidden_from; + + int xsep = border + static_cast(std::round(width * std::abs(phase))); + if (phase > 0) { + xsep = 640-xsep; + hidden_where.x = xsep; + visible_where.x = xsep - visible_where.w; + } else { + hidden_where.x = xsep - visible_where.w; + visible_where.x = xsep; + } + + auto crop_rects = [](SDL_Rect &primary, SDL_Rect &secondary) { + if (primary.x < 0) { + secondary.x -= primary.x*2/3; + secondary.w += primary.x*2/3; + primary.w += primary.x; + primary.x = 0; + } + int extra = 640 - (primary.x + primary.w);; + if (extra < 0) { + primary.w += extra; + secondary.w += extra*2/3; + } + + }; + crop_rects(visible_where, visible_from); + crop_rects(hidden_where, hidden_from); + int adjw = static_cast(hidden_from.w / (1.0+2.0*std::abs(phase))); + if (phase < 0) { + hidden_from.x += adjw; + } + hidden_from.w -= adjw; + sdl.show_slide_transition(visible_from, visible_where, hidden_from, hidden_where); } void DxDoneTurn(void *handle) { + auto &sdl = get_sdl_global_context(); + sdl.swap_display_buffers(); //present hidden buffer } void DxTurnLeftRight(char right, float phase, int border, int ypos, int *last) { diff --git a/platform/sdl/BGraph2.h b/platform/sdl/BGraph2.h index 3597151..d4116d7 100644 --- a/platform/sdl/BGraph2.h +++ b/platform/sdl/BGraph2.h @@ -33,7 +33,8 @@ void DxZoomWalk(void *handle, int ypos, int *points,float phase, void *lodka); void DxDoneWalk(void *handle); void *DxPrepareTurn(int ypos); -void DxTurn(void *handle, char right, int ypos,int border, float phase, void *lodka); +//phase > 0 right, phase < 0 left +void DxTurn(void *handle, int ypos,int border, float phase, void *lodka); void DxDoneTurn(void *handle); void DxTurnLeftRight(char right, float phase, int border, int ypos, int *last); diff --git a/platform/sdl/sdl_context.cpp b/platform/sdl/sdl_context.cpp index d7c4021..8177b07 100644 --- a/platform/sdl/sdl_context.cpp +++ b/platform/sdl/sdl_context.cpp @@ -5,6 +5,7 @@ #include #include "../platform.h" +#include #include #include void SDLContext::SDL_Deleter::operator ()(SDL_Window* window) { @@ -79,7 +80,7 @@ void SDLContext::init_screen(DisplayMode mode, const char *title) { } _window.reset(window); - SDL_Renderer *renderer = SDL_CreateRenderer(_window.get(), -1, 0); + SDL_Renderer *renderer = SDL_CreateRenderer(_window.get(), -1, SDL_RENDERER_SOFTWARE); if (!renderer) { snprintf(buff,sizeof(buff), "Chyba při vytváření rendereru: %s\n", SDL_GetError()); throw std::runtime_error(buff); @@ -90,15 +91,17 @@ void SDLContext::init_screen(DisplayMode mode, const char *title) { snprintf(buff, sizeof(buff), "Chyba při vytváření textury: %s\n", SDL_GetError()); throw std::runtime_error(buff); } + SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); _texture.reset(texture); texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, 640, 480); if (!texture) { snprintf(buff, sizeof(buff), "Chyba při vytváření textury: %s\n", SDL_GetError()); throw std::runtime_error(buff); } + SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); _texture2.reset(texture); _visible_texture = _texture.get(); - _hidden_texture = _texture.get(); + _hidden_texture = _texture2.get(); } catch (...) { e = std::current_exception(); err = true; @@ -164,17 +167,13 @@ void SDLContext::event_loop(std::stop_token stp) { } } } else if (e.type == SDL_MOUSEMOTION) { - int mouseX = e.motion.x; - int mouseY = e.motion.y; - int windowWidth; - int windowHeight; - SDL_GetWindowSize(_window.get(), &windowWidth, &windowHeight); - float normalizedX = (float)mouseX / windowWidth; - float normalizedY = (float)mouseY / windowHeight; + SDL_Point mspt(e.motion.x, e.motion.y); + 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.x = (int16_t)(640*normalizedX); - ms_event.y = (int16_t)(480*normalizedY); + ms_event.x = srcpt.x; + ms_event.y = srcpt.y; } else if (e.type == SDL_MOUSEBUTTONDOWN || e.type == SDL_MOUSEBUTTONUP) { int button = e.button.button; int up = e.type == SDL_MOUSEBUTTONUP?1:0; @@ -183,8 +182,8 @@ void SDLContext::event_loop(std::stop_token stp) { switch (button) { default: break; case 1: ms_event.tl1 = !up; break; - case 2: ms_event.tl2 = !up; break; - case 3: ms_event.tl3 = !up; break; + case 2: ms_event.tl3 = !up; break; + case 3: ms_event.tl2 = !up; break; } } @@ -192,57 +191,6 @@ void SDLContext::event_loop(std::stop_token stp) { } -/* -void SDLContext::pool_events() { - SDL_RenderClear(_renderer.get()); - SDL_RenderCopy(_renderer.get(), _texture.get(), NULL, NULL); - SDL_RenderPresent(_renderer.get()); - ms_event.event = 0; - SDL_Event e; - while (true) { - if (SDL_WaitEvent(&e)) { - if (e.type == SDL_QUIT) { - _quit_requested = true; - return; - if (e.type == SDL_KEYDOWN) { - if (e.key.keysym.sym == SDLK_RETURN && (e.key.keysym.mod & KMOD_ALT)) { - _fullscreen_mode = !_fullscreen_mode; - SDL_SetWindowFullscreen(_window.get(), _fullscreen_mode ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); - } - } else if (e.type == SDL_MOUSEMOTION) { - std::lock_guard _(_mx); - int mouseX = e.motion.x; - int mouseY = e.motion.y; - int windowWidth; - int windowHeight; - SDL_GetWindowSize(_window.get(), &windowWidth, &windowHeight); - float normalizedX = (float)mouseX / windowWidth; - float normalizedY = (float)mouseY / windowHeight; - ms_event.event = 1; - ms_event.event_type = 1; - ms_event.x = (int16_t)(640*normalizedX); - ms_event.y = (int16_t)(480*normalizedY); - } else if (e.type == SDL_MOUSEBUTTONDOWN || e.type == SDL_MOUSEBUTTONUP) { - std::lock_guard _(_mx); - int button = e.button.button; - int up = e.type == SDL_MOUSEBUTTONUP?1:0; - ms_event.event = 1; - ms_event.event_type = (1<<(2*button-1+up)); - switch (button) { - default: break; - case 1: ms_event.tl1 = !up; break; - case 2: ms_event.tl2 = !up; break; - case 3: ms_event.tl3 = !up; break; - } - } - - } else { - throw std::runtime_error("SDL_WaitEvent error"); - } - } - charge_timer(); -}*/ - void SDLContext::present_rect(uint16_t *pixels, unsigned int pitch, unsigned int x, unsigned int y, unsigned int xs, unsigned ys) { @@ -271,6 +219,15 @@ bool SDLContext::is_keyboard_ready() const { return !_keyboard_queue.empty(); } +void SDLContext::show_slide_transition(const SDL_Rect &visible_from, + const SDL_Rect &visible_where, const SDL_Rect &hidden_from, + const SDL_Rect &hidden_where) { + std::lock_guard _(_mx); + signal_push(); + push_item(DisplayRequest::slide_transition); + push_item(SlideTransitionReq{visible_from, visible_where,hidden_from, hidden_where}); +} + void SDLContext::signal_push() { if (_display_update_queue.empty()) { SDL_Event event; @@ -281,8 +238,11 @@ void SDLContext::signal_push() { } void SDLContext::update_screen() { + std::optional blend_transition; + std::optional 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) { @@ -302,14 +262,63 @@ void SDLContext::update_screen() { 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_RenderClear(_renderer.get()); - SDL_RenderCopy(_renderer.get(), _visible_texture, NULL, NULL); + if (slide_transition) { + SDL_SetTextureAlphaMod(_hidden_texture, 255); + SDL_SetTextureAlphaMod(_visible_texture, 255); + SDL_RenderCopy(_renderer.get(), _hidden_texture, NULL, &winrc); + SDL_Rect visible_where_win = to_window_rect(winrc, slide_transition->visible_where); + SDL_Rect hidden_where_win = to_window_rect(winrc, slide_transition->hidden_where); + SDL_RenderCopy(_renderer.get(), _visible_texture, &slide_transition->visible_from, &visible_where_win); + SDL_RenderCopy(_renderer.get(), _hidden_texture, &slide_transition->hidden_from, &hidden_where_win); + } + else if (blend_transition) { + SDL_SetTextureAlphaMod(_hidden_texture, 255); + SDL_RenderCopy(_renderer.get(), _hidden_texture, NULL, &winrc); + if (blend_transition->phase >= 0) { + float f = blend_transition->phase; + SDL_SetTextureAlphaMod(_visible_texture, 255); + SDL_Rect wrkarea = to_window_rect(winrc, blend_transition->wrkarea); + SDL_Rect src1 = transition_rect(blend_transition->prev, blend_transition->next, f); + SDL_RenderCopy(_renderer.get(), _visible_texture, &src1, &wrkarea); + if (SDL_SetTextureAlphaMod(_hidden_texture, (uint8_t)(255.0f*(f)))!= -1) { + SDL_Rect trgnxt = to_window_rect(winrc, blend_transition->next); + SDL_Rect trgwin = transition_rect(trgnxt, wrkarea, f); + SDL_RenderCopy(_renderer.get(), _hidden_texture, &blend_transition->wrkarea, &trgwin); + } + } else { + float f = blend_transition->phase; + SDL_Rect wrkarea = to_window_rect(winrc, blend_transition->wrkarea); + SDL_Rect src1 = transition_rect(blend_transition->prev, blend_transition->next, 1+f); + SDL_RenderCopy(_renderer.get(), _hidden_texture, &src1, &wrkarea); + if (SDL_SetTextureAlphaMod(_visible_texture, (uint8_t)(255.0f*(1+f))) != -1) { + SDL_Rect trgnxt = to_window_rect(winrc, blend_transition->next); + SDL_Rect trgwin = transition_rect(trgnxt, wrkarea, 1+f); + SDL_RenderCopy(_renderer.get(), _visible_texture, &blend_transition->wrkarea, &trgwin); + } + } + } else { + SDL_SetTextureAlphaMod(_visible_texture, 255); + SDL_RenderCopy(_renderer.get(), _visible_texture, NULL, &winrc); + } SDL_RenderPresent(_renderer.get()); } @@ -359,6 +368,76 @@ void SDLContext::swap_render_buffers() { void SDLContext::swap_display_buffers() { std::lock_guard _(_mx); signal_push(); - push_item(DisplayRequest::swap_render_buffers); + push_item(DisplayRequest::swap_visible_buffers); } +void SDLContext::show_blend_transition(const SDL_Rect &wrkarea, const SDL_Rect &prev, + const SDL_Rect &next, float phase) { + std::lock_guard _(_mx); + signal_push(); + push_item(DisplayRequest::blend_transition); + push_item(BlendTransitionReq{wrkarea, prev, next, phase}); +} + +SDL_Rect SDLContext::get_window_aspect_rect() const { + SDL_Rect w; + int ww; + int wh; + SDL_GetWindowSizeInPixels(_window.get(), &ww, &wh); + int apw = wh * 4 / 3; + int aph = ww * 3 / 4; + int fw; + int fh; + if (apw > ww) { + fw = ww; + fh = aph; + } else { + fw = apw; + fh = wh; + } + w.h = fh; + w.w = fw; + w.x = (ww - fw)/2; + w.y = (wh - fh)/2; + return w; +} + +SDL_Point SDLContext::to_window_point(const SDL_Rect &winrc, const SDL_Point &pt) { + return { + pt.x * winrc.w / 640 + winrc.x, + pt.y * winrc.h / 480 + winrc.y, + }; +} + +SDL_Point SDLContext::to_source_point(const SDL_Rect &winrc, const SDL_Point &win_pt) { + return { + (win_pt.x - winrc.x) * 640 / winrc.w, + (win_pt.y - winrc.y) * 480 / winrc.h, + }; +} + +int SDLContext::transition_int(int beg, int end, float phase) { + int w = end - beg; + return beg + static_cast(std::round(w * phase)); +} + +SDL_Rect SDLContext::transition_rect(const SDL_Rect &beg, const SDL_Rect &end, float phase) { + SDL_Rect out; + out.x = transition_int(beg.x, end.x, phase); + out.y = transition_int(beg.y, end.y, phase); + out.w = transition_int(beg.w, end.w, phase); + out.h = transition_int(beg.h, end.h, phase); + return out; +} + + +SDL_Rect SDLContext::to_window_rect(const SDL_Rect &winrc, const SDL_Rect &source_rect) { + SDL_Point pt1(source_rect.x, source_rect.y); + SDL_Point pt2(source_rect.x+source_rect.w, source_rect.y+source_rect.h); + SDL_Point wpt1(to_window_point(winrc, pt1)); + SDL_Point wpt2(to_window_point(winrc, pt2)); + return {wpt1.x, wpt1.y, wpt2.x - wpt1.x, wpt2.y - wpt1.y}; + + + +} diff --git a/platform/sdl/sdl_context.h b/platform/sdl/sdl_context.h index 5262470..34e91ff 100644 --- a/platform/sdl/sdl_context.h +++ b/platform/sdl/sdl_context.h @@ -29,6 +29,9 @@ public: void present_rect(uint16_t *pixels, unsigned int pitch, unsigned int x, unsigned int y, unsigned int xs,unsigned ys); void swap_render_buffers(); void swap_display_buffers(); + void show_blend_transition(const SDL_Rect &wrkarea, const SDL_Rect &prev, const SDL_Rect &next, float phase); + void show_slide_transition(const SDL_Rect &visible_from, const SDL_Rect &visible_where, + const SDL_Rect &hidden_from, const SDL_Rect &hidden_where); MS_EVENT getMsEvent() { std::lock_guard _(_mx); @@ -60,15 +63,27 @@ protected: void operator()(SDL_Texture *); }; - struct UpdateMsg { - SDL_Rect rc; - std::vector data; + struct BlendTransitionReq { + SDL_Rect wrkarea; + SDL_Rect prev; + SDL_Rect next; + float phase; + }; + + struct SlideTransitionReq { + SDL_Rect visible_from; + SDL_Rect visible_where; + SDL_Rect hidden_from; + SDL_Rect hidden_where; + }; enum class DisplayRequest { update, swap_render_buffers, swap_visible_buffers, + blend_transition, + slide_transition }; @@ -102,6 +117,7 @@ protected: void event_loop(std::stop_token stp); void update_screen(); + template requires(std::is_trivially_copy_constructible_v) void push_item(const T &item); @@ -114,6 +130,13 @@ protected: void pop_item(QueueIter &iter, T &item); std::string_view pop_data(QueueIter &iter, std::size_t size); + SDL_Rect get_window_aspect_rect() const; + static SDL_Rect to_window_rect(const SDL_Rect &winrc, const SDL_Rect &source_rect) ; + static SDL_Point to_window_point(const SDL_Rect &win_rec, const SDL_Point &pt) ; + static SDL_Point to_source_point(const SDL_Rect &win_rec, const SDL_Point &win_pt) ; + static SDL_Rect transition_rect(const SDL_Rect &beg, const SDL_Rect &end, float phase); + static int transition_int(int beg, int end, float phase); + void signal_push();