From 9327cba2a1e9946fbb2d7c54d74a628c847a5ff6 Mon Sep 17 00:00:00 2001 From: pelya Date: Tue, 6 Jul 2010 11:56:05 +0300 Subject: [PATCH] Correct resize algorithm without rounding errors --- alienblaster/AppSettings.cfg | 2 +- alienblaster/ChangeAppSettings.sh | 6 ++- .../project/jni/sdl/src/video/SDL_video.c | 46 +++++++++++++++---- 3 files changed, 42 insertions(+), 12 deletions(-) diff --git a/alienblaster/AppSettings.cfg b/alienblaster/AppSettings.cfg index 82d60f457..47b58dcc2 100644 --- a/alienblaster/AppSettings.cfg +++ b/alienblaster/AppSettings.cfg @@ -3,5 +3,5 @@ AppFullName=de.schwardtnet.alienblaster ScreenOrientation=h AppDataDownloadUrl="http://sites.google.com/site/xpelyax/Home/alienblaster110_data.zip?attredirects=0&d=1" DownloadToSdcard=n -SdlVideoResize=y +SdlVideoResize=a NeedDepthBuffer=n diff --git a/alienblaster/ChangeAppSettings.sh b/alienblaster/ChangeAppSettings.sh index ed93f86a2..af19627c7 100755 --- a/alienblaster/ChangeAppSettings.sh +++ b/alienblaster/ChangeAppSettings.sh @@ -33,13 +33,13 @@ if [ -n "$var" ] ; then DownloadToSdcard="$var" fi -echo -n "\nApplication window should be resized to fit into 480x320 screen ($SdlVideoResize): " +echo -n "\nApplication window should be resized to fit into 480x320 screen,\n(y) or (n) or (a)lways resize, even if screen is bigger ($SdlVideoResize): " read var if [ -n "$var" ] ; then SdlVideoResize="$var" fi -echo -n "\nEnable OpenGL depth buffer (needed only for 3-d applications) ($NeedDepthBuffer): " +echo -n "\nEnable OpenGL depth buffer (needed only for 3-d applications, small speed decrease) (y) or (n) ($NeedDepthBuffer): " read var if [ -n "$var" ] ; then NeedDepthBuffer="$var" @@ -72,6 +72,8 @@ fi AppDataDownloadUrl1="`echo $AppDataDownloadUrl | sed 's/[&]/%26/g'`" if [ "$SdlVideoResize" = "y" ] ; then SdlVideoResize=1 +elif [ "$SdlVideoResize" = "a" ] ; then + SdlVideoResize=2 else SdlVideoResize=0 fi diff --git a/alienblaster/project/jni/sdl/src/video/SDL_video.c b/alienblaster/project/jni/sdl/src/video/SDL_video.c index 94f6a0a68..2328b67d4 100644 --- a/alienblaster/project/jni/sdl/src/video/SDL_video.c +++ b/alienblaster/project/jni/sdl/src/video/SDL_video.c @@ -2376,6 +2376,13 @@ SDL_RenderClear() } #if SDL_VIDEO_RENDER_RESIZE + +#if ( SDL_VIDEO_RENDER_RESIZE == 2 ) +#define SDL_VIDEO_RENDER_RESIZE_ALWAYS 1 +#else +#define SDL_VIDEO_RENDER_RESIZE_ALWAYS +#endif + static inline void SDL_RESIZE_resizePoints(int realW, int fakeW, int realH, int fakeH, const SDL_Point * src, SDL_Point * dest, int count ) @@ -2393,10 +2400,12 @@ SDL_RESIZE_resizeRects(int realW, int fakeW, int realH, int fakeH, { int i; for( i = 0; i < count; i++ ) { + // Calculate bottom-right corner instead of width/height, and substract upper-left corner, + // otherwise we'll have rounding errors and holes between textures dest[i].x = src[i]->x * realW / fakeW; - dest[i].w = src[i]->w * realW / fakeW; dest[i].y = src[i]->y * realH / fakeH; - dest[i].h = src[i]->h * realH / fakeH; + dest[i].w = (src[i]->w + src[i]->x) * realW / fakeW - dest[i].x; + dest[i].h = (src[i]->h + src[i]->y) * realH / fakeH - dest[i].y; } } #endif @@ -2442,7 +2451,10 @@ SDL_RenderDrawPoints(const SDL_Point * points, int count) realH = renderer->window->display->current_mode.h; fakeW = renderer->window->w; fakeH = renderer->window->h; - if( fakeW > realW || fakeH > realH ) { +#if !(SDL_VIDEO_RENDER_RESIZE_ALWAYS) + if( fakeW > realW || fakeH > realH ) +#endif + { SDL_Point * resized = SDL_stack_alloc( SDL_Point, count ); if( ! resized ) { SDL_OutOfMemory(); @@ -2500,7 +2512,10 @@ SDL_RenderDrawLines(const SDL_Point * points, int count) realH = renderer->window->display->current_mode.h; fakeW = renderer->window->w; fakeH = renderer->window->h; - if( fakeW > realW || fakeH > realH ) { +#if !(SDL_VIDEO_RENDER_RESIZE_ALWAYS) + if( fakeW > realW || fakeH > realH ) +#endif + { SDL_Point * resized = SDL_stack_alloc( SDL_Point, count ); if( ! resized ) { SDL_OutOfMemory(); @@ -2568,7 +2583,10 @@ SDL_RenderDrawRects(const SDL_Rect ** rects, int count) realH = renderer->window->display->current_mode.h; fakeW = renderer->window->w; fakeH = renderer->window->h; - if( fakeW > realW || fakeH > realH ) { +#if !(SDL_VIDEO_RENDER_RESIZE_ALWAYS) + if( fakeW > realW || fakeH > realH ) +#endif + { SDL_Rect * resized = SDL_stack_alloc( SDL_Rect, count ); if( ! resized ) { SDL_OutOfMemory(); @@ -2647,7 +2665,10 @@ SDL_RenderFillRects(const SDL_Rect ** rects, int count) realH = renderer->window->display->current_mode.h; fakeW = renderer->window->w; fakeH = renderer->window->h; - if( fakeW > realW || fakeH > realH ) { +#if !(SDL_VIDEO_RENDER_RESIZE_ALWAYS) + if( fakeW > realW || fakeH > realH ) +#endif + { SDL_Rect * resized = SDL_stack_alloc( SDL_Rect, count ); if( ! resized ) { SDL_OutOfMemory(); @@ -2743,11 +2764,18 @@ SDL_RenderCopy(SDL_Texture * texture, const SDL_Rect * srcrect, realH = window->display->current_mode.h; fakeW = window->w; fakeH = window->h; - if( fakeW > realW || fakeH > realH ) { +#if !(SDL_VIDEO_RENDER_RESIZE_ALWAYS) + if( fakeW > realW || fakeH > realH ) +#endif + { + // Calculate bottom-right corner instead of width/height, and substract upper-left corner, + // otherwise we'll have rounding errors and holes between textures + real_dstrect.w = (real_dstrect.w + real_dstrect.x) * realW / fakeW; + real_dstrect.h = (real_dstrect.h + real_dstrect.y) * realH / fakeH; real_dstrect.x = real_dstrect.x * realW / fakeW; real_dstrect.y = real_dstrect.y * realH / fakeH; - real_dstrect.w = real_dstrect.w * realW / fakeW; - real_dstrect.h = real_dstrect.h * realH / fakeH; + real_dstrect.w -= real_dstrect.x; + real_dstrect.h -= real_dstrect.y; } #endif