mirror of
https://github.com/ondra-novak/gates_of_skeldal.git
synced 2025-07-05 06:00:33 -04:00
walking and turning effect
This commit is contained in:
parent
3b903e2b52
commit
4f9f985918
12 changed files with 286 additions and 98 deletions
|
@ -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];
|
||||
|
|
|
@ -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 (curtime<maxtime);
|
||||
|
|
|
@ -2393,6 +2393,7 @@ static void shop_mouse_event(EVENT_MSG *msg,void **unused)
|
|||
int x,y;
|
||||
char cc=1;
|
||||
static int last_pos=-1;
|
||||
EVENT_MSG msgc = clone_message(msg);
|
||||
|
||||
ms=get_mouse(msg);
|
||||
x=ms->x-(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) {
|
||||
|
|
|
@ -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
|
||||
{
|
||||
sort_groups();
|
||||
bott_draw(0);
|
||||
other_draw();
|
||||
shift_zoom(smer);
|
||||
OutBuffer2nd();
|
||||
if (nopass) shift_zoom(smer+2);
|
||||
}
|
||||
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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include <cassert>
|
||||
#include <cstdarg>
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
void task_sleep(void) {
|
||||
|
|
|
@ -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<int>(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<int>(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) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <cassert>
|
||||
#include "../platform.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
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<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) {
|
||||
|
@ -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<int>(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};
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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<short> 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<typename T>
|
||||
requires(std::is_trivially_copy_constructible_v<T>)
|
||||
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();
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue