mirror of
https://github.com/kichikuou/xsystem35-sdl2.git
synced 2026-10-07 22:28:01 +03:00
Refactor clipping functions
This commit is contained in:
+12
-120
@@ -9,20 +9,13 @@
|
||||
#include "surface.h"
|
||||
#include "graph.h"
|
||||
#include "ngraph.h"
|
||||
#include "nact.h"
|
||||
#include "ags.h"
|
||||
|
||||
/*
|
||||
gr_xxxx はクリッピングあり
|
||||
gre_xxxx はクリッピングなし
|
||||
*/
|
||||
|
||||
#undef WARNING
|
||||
#define WARNING(...)
|
||||
|
||||
#undef NOTICE
|
||||
#define NOTICE(...)
|
||||
|
||||
|
||||
/**
|
||||
* surface から surface にコピーなどをする際に、転送元と転送先のsurface
|
||||
* の大きさや、転送元・転送先座標、転送する領域の大きさなどから、実際に
|
||||
@@ -42,74 +35,10 @@
|
||||
* それぞれの引数は適宜変更されている
|
||||
*/
|
||||
bool gr_clip(surface_t *ss, int *sx, int *sy, int *sw, int *sh, surface_t *ds, int *dx, int *dy) {
|
||||
int w, h;
|
||||
|
||||
if (ss == NULL) {
|
||||
WARNING("ss surface is null");
|
||||
return false;
|
||||
}
|
||||
if (ss == NULL) {
|
||||
WARNING("ss surface is null");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (*sx > ss->width) {
|
||||
WARNING("sx is too large (sx=%d,width=%d)", *sx, ss->width);
|
||||
return false;
|
||||
}
|
||||
if (*sy > ss->height) {
|
||||
WARNING("sy is too large (sy=%d,height=%d)", *sy, ss->height);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (*sx < 0) {
|
||||
WARNING("sx is too small (sx=%d)", *sx);
|
||||
return false;
|
||||
}
|
||||
if (*sy < 0) {
|
||||
WARNING("sy is too small (sy=%d)", *sy);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (*dx > ds->width) {
|
||||
WARNING("dx is too large (dx=%d,width=%d)", *dx, ds->width);
|
||||
return false;
|
||||
}
|
||||
if (*dy > ds->height) {
|
||||
WARNING("dy is too large (dy=%d,height=%d)", *dy, ds->height);
|
||||
return false;
|
||||
}
|
||||
|
||||
w = *sw;
|
||||
h = *sh;
|
||||
|
||||
if (*dx < 0) {
|
||||
*sx -= *dx; *sw += *dx; *dx = 0;
|
||||
}
|
||||
if (*dy < 0) {
|
||||
*sy -= *dy; *sh += *dy; *dy = 0;
|
||||
}
|
||||
|
||||
*sw = min(ss->width - *sx, min(ds->width - *dx, *sw));
|
||||
*sh = min(ss->height - *sy, min(ds->height - *dy, *sh));
|
||||
|
||||
if (*sw <= 0) {
|
||||
WARNING("sw become <=0");
|
||||
return false;
|
||||
}
|
||||
if (*sh <= 0) {
|
||||
WARNING("sh become <=0");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (*sw != w) {
|
||||
NOTICE("width change %d -> %d", w, *sw);
|
||||
}
|
||||
if (*sh != h) {
|
||||
NOTICE("height change %d -> %d", h, *sh);
|
||||
}
|
||||
|
||||
return true;
|
||||
if (!ss || !ds) return false;
|
||||
MyRectangle src_window = { 0, 0, ss->width, ss->height };
|
||||
MyRectangle dst_window = { 0, 0, ds->width, ds->height };
|
||||
return ags_clipCopyRect(&src_window, &dst_window, sx, sy, dx, dy, sw, sh);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -126,51 +55,14 @@ bool gr_clip(surface_t *ss, int *sx, int *sy, int *sw, int *sh, surface_t *ds, i
|
||||
* それぞれの引数は適宜変更されている
|
||||
*/
|
||||
bool gr_clip_xywh(surface_t *ss, int *sx, int *sy, int *sw, int *sh) {
|
||||
int w, h;
|
||||
|
||||
if (ss == NULL) {
|
||||
WARNING("ss surface is null");
|
||||
if (!ss) return false;
|
||||
SDL_Rect rect = {*sx, *sy, *sw, *sh};
|
||||
if (!SDL_IntersectRect(&rect, &(SDL_Rect){ 0, 0, ss->width, ss->height }, &rect))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (*sx > ss->width) {
|
||||
WARNING("sx is too large (sx=%d,width=%d)", *sx, ss->width);
|
||||
return false;
|
||||
}
|
||||
if (*sy > ss->height) {
|
||||
WARNING("sy is too large (sy=%d,height=%d)", *sy, ss->height);
|
||||
return false;
|
||||
}
|
||||
|
||||
w = *sw;
|
||||
h = *sh;
|
||||
|
||||
if (*sx < 0) {
|
||||
*sw += *sx; *sx = 0;
|
||||
}
|
||||
if (*sy < 0) {
|
||||
*sh += *sy; *sy = 0;
|
||||
}
|
||||
|
||||
*sw = min(ss->width - *sx, *sw);
|
||||
*sh = min(ss->height - *sy, *sh);
|
||||
|
||||
if (*sw <= 0) {
|
||||
WARNING("sw become <=0");
|
||||
return false;
|
||||
}
|
||||
if (*sh <= 0) {
|
||||
WARNING("sh become <=0");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (*sw != w) {
|
||||
NOTICE("width change %d -> %d", w, *sw);
|
||||
}
|
||||
if (*sh != h) {
|
||||
NOTICE("height change %d -> %d", h, *sh);
|
||||
}
|
||||
|
||||
*sx = rect.x;
|
||||
*sy = rect.y;
|
||||
*sw = rect.w;
|
||||
*sh = rect.h;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -785,3 +785,31 @@ agsurface_t *ags_getDIB() {
|
||||
void ags_autorepeat(bool enable) {
|
||||
sdl_setAutoRepeat(enable);
|
||||
}
|
||||
|
||||
bool ags_clipCopyRect(const MyRectangle *sw, const MyRectangle *dw, int *sx, int *sy, int *dx, int *dy, int *w, int *h) {
|
||||
// Clip source rectangle to source window
|
||||
SDL_Rect sr = {*sx, *sy, *w, *h};
|
||||
if (!SDL_IntersectRect(&sr, sw, &sr))
|
||||
return false;
|
||||
|
||||
// Shift destination rectangle if source origin has changed
|
||||
int dx_ = *dx + (sr.x - *sx);
|
||||
int dy_ = *dy + (sr.y - *sy);
|
||||
|
||||
// Clip destination rectangle to destination window
|
||||
SDL_Rect dr = {dx_, dy_, sr.w, sr.h};
|
||||
if (!SDL_IntersectRect(&dr, dw, &dr))
|
||||
return false;
|
||||
|
||||
// Shift source rectangle if destination origin has changed
|
||||
sr.x += dr.x - dx_;
|
||||
sr.y += dr.y - dy_;
|
||||
|
||||
*sx = sr.x;
|
||||
*sy = sr.y;
|
||||
*w = dr.w;
|
||||
*h = dr.h;
|
||||
*dx = dr.x;
|
||||
*dy = dr.y;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -230,6 +230,7 @@ extern int ags_getCursorMoveTime();
|
||||
extern void ags_setAntialiasedStringMode(bool mode);
|
||||
extern bool ags_getAntialiasedStringMode();
|
||||
extern void ags_autorepeat(bool enable);
|
||||
extern bool ags_clipCopyRect(const MyRectangle *sr, const MyRectangle *dr, int *sx, int *sy, int *dx, int *dy, int *w, int *h);
|
||||
|
||||
typedef void (*ags_EffectStepFunc)(void *, float);
|
||||
void ags_runEffect(int duration_ms, bool cancelable, ags_EffectStepFunc step, void *arg);
|
||||
|
||||
+9
-13
@@ -104,22 +104,18 @@ void sdl_wait_vsync() {
|
||||
|
||||
/* off-screen の指定領域を Main Window へ転送 */
|
||||
void sdl_updateArea(MyRectangle *rect, MyPoint *dst) {
|
||||
SDL_Rect rs = {0, 0, sdl_dib->w, sdl_dib->h};
|
||||
if (!SDL_IntersectRect(rect, &rs, &rs))
|
||||
SDL_Rect sw = {0, 0, sdl_dib->w, sdl_dib->h};
|
||||
SDL_Rect dw = {0, 0, view_w, view_h};
|
||||
SDL_Rect sr = {rect->x, rect->y, rect->w, rect->h};
|
||||
SDL_Rect dr = {dst->x, dst->y, rect->w, rect->h};
|
||||
if (!ags_clipCopyRect(&sw, &dw, &sr.x, &sr.y, &dr.x, &dr.y, &sr.w, &sr.h))
|
||||
return;
|
||||
int dx = dst->x + (rs.x - rect->x);
|
||||
int dy = dst->y + (rs.y - rect->y);
|
||||
SDL_Rect rd = {dx, dy, rs.w, rs.h};
|
||||
if (!SDL_IntersectRect(&rd, &(SDL_Rect){0, 0, view_w, view_h}, &rd))
|
||||
return;
|
||||
rs.x += rd.x - dx;
|
||||
rs.y += rd.y - dy;
|
||||
rs.w = rd.w;
|
||||
rs.h = rd.h;
|
||||
dr.w = sr.w;
|
||||
dr.h = sr.h;
|
||||
|
||||
SDL_Surface *sf;
|
||||
SDL_LockTextureToSurface(sdl_texture, &rd, &sf);
|
||||
SDL_BlitSurface(sdl_dib, &rs, sf, NULL);
|
||||
SDL_LockTextureToSurface(sdl_texture, &dr, &sf);
|
||||
SDL_BlitSurface(sdl_dib, &sr, sf, NULL);
|
||||
SDL_UnlockTexture(sdl_texture);
|
||||
|
||||
sdl_dirty = true;
|
||||
|
||||
Reference in New Issue
Block a user