From 1b87935b70dec8f7d9468ffdea8dfb6f0ff7334c Mon Sep 17 00:00:00 2001 From: pelya Date: Fri, 4 Jun 2010 18:56:00 +0300 Subject: [PATCH] Resizing proxy renderer implementation, did not test it yet --- .../project/jni/application/src/global.h | 2 +- .../jni/sdl/include/SDL_config_android.h | 1 + .../jni/sdl/src/video/SDL_renderer_resize.c | 307 ++++++++++++++++++ .../jni/sdl/src/video/SDL_renderer_resize.h | 29 ++ .../project/jni/sdl/src/video/SDL_video.c | 9 + 5 files changed, 347 insertions(+), 1 deletion(-) create mode 100644 alienblaster/project/jni/sdl/src/video/SDL_renderer_resize.c create mode 100644 alienblaster/project/jni/sdl/src/video/SDL_renderer_resize.h diff --git a/alienblaster/project/jni/application/src/global.h b/alienblaster/project/jni/application/src/global.h index 9d0a8f0ea..ce4d62078 100644 --- a/alienblaster/project/jni/application/src/global.h +++ b/alienblaster/project/jni/application/src/global.h @@ -56,7 +56,7 @@ int getRandValue( const int *choicesWeights, int nrChoices, int sumWeights=0 ); void initAllSurfaces(); // screen options -const int SCREEN_WIDTH = 320; +const int SCREEN_WIDTH = 640; const int SCREEN_HEIGHT = 480; const int BIT_DEPTH = 16; diff --git a/alienblaster/project/jni/sdl/include/SDL_config_android.h b/alienblaster/project/jni/sdl/include/SDL_config_android.h index b00791c5c..eb74bf2b8 100644 --- a/alienblaster/project/jni/sdl/include/SDL_config_android.h +++ b/alienblaster/project/jni/sdl/include/SDL_config_android.h @@ -34,6 +34,7 @@ #define SDL_VIDEO_DRIVER_ANDROID 1 #define SDL_VIDEO_OPENGL_ES 1 #define SDL_VIDEO_RENDER_OGL_ES 1 +#define SDL_VIDEO_RENDER_RESIZE 1 #define SDL_AUDIO_DRIVER_ANDROID 1 diff --git a/alienblaster/project/jni/sdl/src/video/SDL_renderer_resize.c b/alienblaster/project/jni/sdl/src/video/SDL_renderer_resize.c new file mode 100644 index 000000000..85e0d01a0 --- /dev/null +++ b/alienblaster/project/jni/sdl/src/video/SDL_renderer_resize.c @@ -0,0 +1,307 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +#if SDL_VIDEO_RENDER_RESIZE + +#include "SDL_video.h" +#include "SDL_sysvideo.h" +#include "SDL_pixels_c.h" +#include "SDL_rect_c.h" + +static int RESIZE_RenderDrawPoints(SDL_Renderer * renderer, + const SDL_Point * points, int count); +static int RESIZE_RenderDrawLines(SDL_Renderer * renderer, + const SDL_Point * points, int count); +static int RESIZE_RenderDrawRects(SDL_Renderer * renderer, + const SDL_Rect ** rects, int count); +static int RESIZE_RenderFillRects(SDL_Renderer * renderer, + const SDL_Rect ** rects, int count); +static int RESIZE_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * srcrect, + const SDL_Rect * dstrect); +static void RESIZE_DestroyRenderer(SDL_Renderer * renderer); + + +typedef struct +{ + /* It should work fast on FPU-less processors, so I did not use floats but ints. + Hopefully compiler will somehow optimize (realW / fakeW) because it's adjacent bytes */ + uint8_t realW, fakeW, realH, fakeH; + SDL_Renderer * renderer; + +} RESIZE_RenderData; + + +static int +RESIZE_LoadFunctions(RESIZE_RenderData * data) +{ + return 0; +} + +int +RESIZE_CreateRenderer(SDL_Window * window) +{ + + SDL_Renderer * renderer; + RESIZE_RenderData * data; + int realW, realH; + int fakeW, fakeH; + + realW = window->display->current_mode.w; + realH = window->display->current_mode.h; + fakeW = window->w; + fakeH = window->h; + + /* Here we're assuming that both real and fake dimensins can be shrinked to byte-size ints + by dividong both in half, for example real 480x320 : fake 640x480 becomes 3x2 : 4x3 */ + while( (realW / 2) * 2 == realW && (fakeW / 2) * 2 == fakeW ) { + realW /= 2; + fakeW /= 2; + } + + while( (realH / 2) * 2 == realH && (fakeH / 2) * 2 == fakeH ) { + realH /= 2; + fakeH /= 2; + } + + if( realW > 255 || realH > 255 || fakeW > 255 || fakeH > 255 || + realW == 0 || realH == 0 || fakeW == 0 || fakeH == 0 ) + return -1; + + renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer)); + if (!renderer) { + SDL_OutOfMemory(); + return -1; + } + + data = (RESIZE_RenderData *) SDL_calloc(1, sizeof(*data)); + if (!data) { + SDL_free(renderer); + SDL_OutOfMemory(); + return -1; + } + + data->realW = realW; + data->fakeW = fakeW; + data->realH = realH; + data->fakeH = fakeH; + data->renderer = window->renderer; + + memcpy(renderer, window->renderer, sizeof(SDL_Renderer)); + + renderer->RenderDrawPoints = RESIZE_RenderDrawPoints; + renderer->RenderDrawLines = RESIZE_RenderDrawLines; + renderer->RenderDrawRects = RESIZE_RenderDrawRects; + renderer->RenderFillRects = RESIZE_RenderFillRects; + renderer->RenderCopy = RESIZE_RenderCopy; + renderer->DestroyRenderer = RESIZE_DestroyRenderer; + renderer->driverdata = data; + + window->renderer = renderer; + + return 0; +} + +static inline void +RESIZE_resizePoints(uint8_t realW, uint8_t fakeW, uint8_t realH, uint8_t fakeH, + const SDL_Point * src, SDL_Point * dest, int count ) +{ + int i; + for( i = 0; i < count; i++ ) { + dest[i].x = src[i].x * realW / fakeW; + dest[i].y = src[i].y * realH / fakeH; + } +} + +static int +RESIZE_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, + int count) +{ + RESIZE_RenderData *data = (RESIZE_RenderData *) renderer->driverdata; + int ret; + + if( !data->renderer->RenderDrawPoints ) + return -1; + + SDL_Point * resized = SDL_stack_alloc( SDL_Point, count ); + if( ! resized ) { + SDL_OutOfMemory(); + return -1; + } + + RESIZE_resizePoints( data->realW, data->fakeW, data->realH, data->fakeH, points, resized, count ); + + ret = data->renderer->RenderDrawPoints(data->renderer, resized, count); + + SDL_stack_free(resized); + + return ret; +} + +static int +RESIZE_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, + int count) +{ + RESIZE_RenderData *data = (RESIZE_RenderData *) renderer->driverdata; + int ret; + + if( !data->renderer->RenderDrawLines ) + return -1; + + SDL_Point * resized = SDL_stack_alloc( SDL_Point, count * 2 ); + if( ! resized ) { + SDL_OutOfMemory(); + return -1; + } + + RESIZE_resizePoints( data->realW, data->fakeW, data->realH, data->fakeH, points, resized, count * 2 ); + + ret = data->renderer->RenderDrawLines(data->renderer, resized, count); + + SDL_stack_free(resized); + + return ret; +} + +static inline void +RESIZE_resizeRects(uint8_t realW, uint8_t fakeW, uint8_t realH, uint8_t fakeH, + const SDL_Rect ** src, SDL_Rect * dest, int count ) +{ + int i; + for( i = 0; i < count; i++ ) { + 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; + } +} + +static int +RESIZE_RenderDrawRects(SDL_Renderer * renderer, const SDL_Rect ** rects, + int count) +{ + RESIZE_RenderData *data = (RESIZE_RenderData *) renderer->driverdata; + int i, ret; + + if( !data->renderer->RenderDrawRects ) + return -1; + + SDL_Rect * resized = SDL_stack_alloc( SDL_Rect, count ); + if( ! resized ) { + SDL_OutOfMemory(); + return -1; + } + + const SDL_Rect ** resizedPtrs = SDL_stack_alloc( const SDL_Rect *, count ); + if( ! resizedPtrs ) { + SDL_OutOfMemory(); + return -1; + } + + for( i = 0; i < count; i++ ) { + resizedPtrs[i] = &(resized[i]); + } + + RESIZE_resizeRects( data->realW, data->fakeW, data->realH, data->fakeH, rects, resized, count ); + + ret = data->renderer->RenderDrawRects(data->renderer, resizedPtrs, count); + + SDL_stack_free(resizedPtrs); + SDL_stack_free(resized); + + return ret; +} + +static int +RESIZE_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects, + int count) +{ + RESIZE_RenderData *data = (RESIZE_RenderData *) renderer->driverdata; + int i, ret; + + if( !data->renderer->RenderFillRects ) + return -1; + + SDL_Rect * resized = SDL_stack_alloc( SDL_Rect, count ); + if( ! resized ) { + SDL_OutOfMemory(); + return -1; + } + + const SDL_Rect ** resizedPtrs = SDL_stack_alloc( const SDL_Rect *, count ); + if( ! resizedPtrs ) { + SDL_OutOfMemory(); + return -1; + } + + for( i = 0; i < count; i++ ) { + resizedPtrs[i] = &(resized[i]); + } + + RESIZE_resizeRects( data->realW, data->fakeW, data->realH, data->fakeH, rects, resized, count * 4 ); + + ret = data->renderer->RenderFillRects(data->renderer, resizedPtrs, count); + + SDL_stack_free(resizedPtrs); + SDL_stack_free(resized); + + return ret; +} + +static int +RESIZE_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * srcrect, const SDL_Rect * dstrect) +{ + RESIZE_RenderData *data = (RESIZE_RenderData *) renderer->driverdata; + SDL_Rect dest; + uint8_t realW = data->realW, fakeW = data->fakeW, realH = data->realH, fakeH = data->fakeH; + + dest.x = dstrect->x * realW / fakeW; + dest.w = dstrect->w * realW / fakeW; + dest.y = dstrect->y * realH / fakeH; + dest.h = dstrect->h * realH / fakeH; + + return data->renderer->RenderCopy(data->renderer, texture, srcrect, &dest); +} + + +static void +RESIZE_DestroyRenderer(SDL_Renderer * renderer) +{ + + RESIZE_RenderData *data = (RESIZE_RenderData *) renderer->driverdata; + + if (data && data->renderer && data->renderer->DestroyRenderer) { + data->renderer->DestroyRenderer(data->renderer); + } + + if (data) { + SDL_free(data); + } + + SDL_free(renderer); +} + +#endif /* SDL_VIDEO_RENDER_RESIZE */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/alienblaster/project/jni/sdl/src/video/SDL_renderer_resize.h b/alienblaster/project/jni/sdl/src/video/SDL_renderer_resize.h new file mode 100644 index 000000000..aea944c9e --- /dev/null +++ b/alienblaster/project/jni/sdl/src/video/SDL_renderer_resize.h @@ -0,0 +1,29 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +/* Resizing proxy renderer implementation */ + +int +RESIZE_CreateRenderer(SDL_Window * window); + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/alienblaster/project/jni/sdl/src/video/SDL_video.c b/alienblaster/project/jni/sdl/src/video/SDL_video.c index 9e9b053d8..c0feee351 100644 --- a/alienblaster/project/jni/sdl/src/video/SDL_video.c +++ b/alienblaster/project/jni/sdl/src/video/SDL_video.c @@ -31,6 +31,7 @@ #include "SDL_renderer_gl.h" #include "SDL_renderer_gles.h" #include "SDL_renderer_sw.h" +#include "SDL_renderer_resize.h" #include "../events/SDL_sysevents.h" #include "../events/SDL_events_c.h" @@ -1603,6 +1604,14 @@ SDL_CreateRenderer(SDL_Window * window, int index, Uint32 flags) SDL_SelectRenderer(window); +#ifdef SDL_VIDEO_RENDER_RESIZE + + if( window->w > window->display->current_mode.w || window->h > window->display->current_mode.h ) { + RESIZE_CreateRenderer(window); + } + +#endif + return 0; }