Alien Blaster compiles and works with new SDL 1.3, but the alpha channel fails for SDL_Texture (is that an SDL bug?)

This commit is contained in:
pelya
2012-01-03 17:26:17 +02:00
parent bfcffa7f77
commit 32c68280bf
8 changed files with 86 additions and 32 deletions

View File

@@ -24,7 +24,7 @@ if uname -s | grep -i "windows" > /dev/null ; then
MYARCH=windows-x86
fi
rm -f project/bin/*.apk project/bin/*.apk.d project/bin/*.ap_ project/bin/*.ap_.d # New Android SDK introduced some lame-ass optimizations to the build system which we should take care about
rm -r -f project/bin/* # New Android SDK introduced some lame-ass optimizations to the build system which we should take care about
cd project && env PATH=$NDKBUILDPATH nice -n19 ndk-build V=1 -j4 && \
{ grep "CustomBuildScript=y" ../AndroidAppSettings.cfg > /dev/null && \

View File

@@ -22,6 +22,8 @@ struct SdlCompat_AcceleratedSurface
SDL_PixelFormat * format;
};
extern SDL_Renderer * SDL_global_renderer;
static inline SdlCompat_AcceleratedSurface * SdlCompat_CreateAcceleratedSurface(SDL_Surface * surface)
{
SdlCompat_AcceleratedSurface * ret = new SdlCompat_AcceleratedSurface();
@@ -34,10 +36,36 @@ static inline SdlCompat_AcceleratedSurface * SdlCompat_CreateAcceleratedSurface(
*(ret->format) = *(surface->format);
format = SDL_PIXELFORMAT_RGB565;
SDL_Surface * surface2 = surface;
if( surface->flags & SDL_SRCCOLORKEY )
{
format = SDL_PIXELFORMAT_RGBA4444;
//surface2 = SDL_ConvertSurfaceFormat(surface, format, 0); // Does not copy alpha
int bpp;
Uint32 r,g,b,a;
SDL_PixelFormatEnumToMasks(format, &bpp, &r, &g, &b, &a);
surface2 = SDL_CreateRGBSurface(0, surface->w, surface->h, bpp, r, g, b, a);
SDL_FillRect(surface2, NULL, 0);
SDL_BlitSurface(surface, NULL, surface2, NULL);
// Fix the alpha channel, using ugly pixel access
SDL_LockSurface(surface2);
SDL_LockSurface(surface);
for(int y = 0; y < surface->h; y++)
for(int x = 0; x < surface->w; x++)
{
// Assume 24-bit or 32-bit surface
Uint8 * pixel = ((Uint8 *) surface->pixels) + y*surface->pitch + x*surface->format->BytesPerPixel;
if( pixel[0] == 255 && pixel[1] == 0 && pixel[2] == 255 )
*(Uint16 *)(((Uint8 *) surface2->pixels) + y*surface2->pitch + x*surface2->format->BytesPerPixel) = 0;
}
SDL_UnlockSurface(surface);
SDL_UnlockSurface(surface2);
}
ret->t = SDL_CreateTextureFromSurface(format, surface);
ret->t = SDL_CreateTextureFromSurface(SDL_global_renderer, surface2);
if(surface != surface2)
SDL_FreeSurface(surface2);
if( ! ret->t )
{
@@ -45,21 +73,23 @@ static inline SdlCompat_AcceleratedSurface * SdlCompat_CreateAcceleratedSurface(
return ret;
}
SDL_SetTextureBlendMode( ret->t, SDL_BLENDMODE_BLEND );
//SDL_SetTextureAlphaMod( ret->t, SDL_ALPHA_OPAQUE );
SDL_SetTextureAlphaMod( ret->t, 128 );
if( surface->flags & SDL_SRCALPHA )
{
SDL_SetTextureBlendMode( ret->t, SDL_BLENDMODE_BLEND );
Uint8 alpha = 128;
if( SDL_GetSurfaceAlphaMod( surface, &alpha ) < 0 )
alpha = 128;
SDL_SetTextureAlphaMod( ret->t, alpha );
}
return ret;
};
static inline int SDL_BlitSurface( SdlCompat_AcceleratedSurface * src, SDL_Rect * srcR, SdlCompat_AcceleratedSurface * unused, SDL_Rect * destR )
{
return SDL_RenderCopy(src->t, srcR, destR);
return SDL_RenderCopy(SDL_global_renderer, src->t, srcR, destR);
};
static inline void SDL_FreeSurface(SdlCompat_AcceleratedSurface * surface)
@@ -71,15 +101,14 @@ static inline void SDL_FreeSurface(SdlCompat_AcceleratedSurface * surface)
static inline void SDL_FillRect( SdlCompat_AcceleratedSurface * unused, const SDL_Rect* rect, Uint32 color )
{
Uint8 r, g, b, a;
SDL_GetRGBA( color, SDL_GetVideoSurface()->format, &r, &g, &b, &a );
SDL_SetRenderDrawColor(r, g, b, SDL_ALPHA_OPAQUE /* a */);
SDL_RenderFillRect(rect);
Uint8 r = color & 0xff, g = (color >> 8) & 0xff, b = (color >> 16) & 0xff;
SDL_SetRenderDrawColor(SDL_global_renderer, r, g, b, SDL_ALPHA_OPAQUE /* a */);
SDL_RenderFillRect(SDL_global_renderer, rect);
};
static inline int SDL_Flip(SdlCompat_AcceleratedSurface * unused)
{
SDL_RenderPresent();
SDL_RenderPresent(SDL_global_renderer);
return 0;
};

View File

@@ -100,13 +100,18 @@ SDL_Surface *SurfaceDB::loadSurfaceInternal( string fn, bool alpha ) {
SDL_SetColorKey( newSurface, SDL_SRCCOLORKEY,
SDL_MapRGB(newSurface->format, transR, transG, transB) );
#if SDL_VERSION_ATLEAST(1,3,0)
// Do not even think of calling SDL_DisplayFormat(), it will return NULL and crash your code! (and kill your cat also)
#else
SDL_Surface * hwSurface = SDL_DisplayFormat(newSurface);
if( hwSurface ) {
SDL_FreeSurface(newSurface);
newSurface = hwSurface;
}
#endif
return newSurface;
}

View File

@@ -23,6 +23,7 @@
#include "global.h"
#include "surfaceDB.h"
#include <android/log.h>
#include <SDL_image.h>
using namespace std;
@@ -36,6 +37,8 @@ Video::~Video(){
// kill something
}
SDL_Renderer * SDL_global_renderer = NULL;
SdlCompat_AcceleratedSurface *Video::init(){
// --------------------------------------------------
// SDL initialisation
@@ -48,28 +51,41 @@ SdlCompat_AcceleratedSurface *Video::init(){
__android_log_print(ANDROID_LOG_ERROR, "Alien Blaster", "Couldn't initialize SDL video subsystem: %s\n", SDL_GetError());
exit(1);
}
#if SDL_VERSION_ATLEAST(1,3,0)
// SDL_VideoInit(NULL);
SDL_Window * window = SDL_CreateWindow("Alien Blaster", 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_BORDERLESS | SDL_WINDOW_SHOWN | SDL_WINDOW_INPUT_GRABBED);
if (!window) {
__android_log_print(ANDROID_LOG_ERROR, "Alien Blaster", "SDL_CreateWindow() failed: %s", SDL_GetError());
exit(1);
}
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "SDL_CreateWindow() ret %p", window);
SDL_global_renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (!SDL_global_renderer) {
__android_log_print(ANDROID_LOG_ERROR, "Alien Blaster", "SDL_CreateRenderer() ret %p", SDL_global_renderer);
exit(1);
}
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "SDL_CreateRenderer() ret %p", SDL_global_renderer);
// Dummy texture
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Creating dummy video surface");
SDL_Surface *screen2 = IMG_Load( "images/bomber.png" );
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Creating dummy video surface 2");
screen = SdlCompat_CreateAcceleratedSurface(screen2);
screen->w = SCREEN_WIDTH;
screen->h = SCREEN_HEIGHT;
SDL_FreeSurface(screen2);
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "video init done");
#else
SDL_Surface * screen2 = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, BIT_DEPTH, SDL_DOUBLEBUF | SDL_HWSURFACE );
if (!screen2) {
printf("Couldn't set %dx%d, %dbit video mode: %s\n", SCREEN_WIDTH, SCREEN_HEIGHT, BIT_DEPTH, SDL_GetError());
__android_log_print(ANDROID_LOG_ERROR, "Alien Blaster", "Couldn't set %dx%d, %dbit video mode: %s\n", SCREEN_WIDTH, SCREEN_HEIGHT, BIT_DEPTH, SDL_GetError());
exit(2);
}
#if SDL_VERSION_ATLEAST(1,3,0)
// Dummy texture
screen2 = SDL_CreateRGBSurface( 0, 16, 16, 16, 0xff, 0x00ff, 0x0000ff, 0 );
SDL_Surface * screen3 = SDL_DisplayFormat( screen2 );
SDL_FreeSurface(screen2);
screen = SdlCompat_CreateAcceleratedSurface(screen3);
screen->w = SCREEN_WIDTH;
screen->h = SCREEN_HEIGHT;
SDL_FreeSurface(screen3);
#else
screen = screen2;
#endif
SDL_WM_SetCaption("AlienBlaster", "AlienBlaster");
SDL_WM_SetIcon(SDL_LoadBMP( FN_ALIENBLASTER_ICON.c_str() ), NULL);
SDL_ShowCursor(SDL_DISABLE);
#endif
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Initializing video done");
return screen;

View File

@@ -1 +1 @@
ballfield
alienblaster

View File

@@ -231,7 +231,7 @@ SDL_PixelFormatEnumToMasks(Uint32 format, int *bpp, Uint32 * Rmask,
masks[3] = 0x00000003;
break;
default:
SDL_SetError("Unknown pixel format");
SDL_SetError("SDL_PixelFormatEnumToMasks: Unknown pixel format - unknown pixel layout");
return SDL_FALSE;
}
@@ -281,7 +281,7 @@ SDL_PixelFormatEnumToMasks(Uint32 format, int *bpp, Uint32 * Rmask,
*Rmask = masks[3];
break;
default:
SDL_SetError("Unknown pixel format");
SDL_SetError("SDL_PixelFormatEnumToMasks: Unknown pixel format - unknown pixel order");
return SDL_FALSE;
}
return SDL_TRUE;

View File

@@ -46,7 +46,7 @@ SDL_CreateRGBSurface(Uint32 flags,
/* Get the pixel format */
format = SDL_MasksToPixelFormatEnum(depth, Rmask, Gmask, Bmask, Amask);
if (format == SDL_PIXELFORMAT_UNKNOWN) {
SDL_SetError("Unknown pixel format");
SDL_SetError("SDL_CreateRGBSurface: Unknown pixel format: depth %d masks 0x%x 0x%x 0x%x 0x%x", depth, Rmask, Gmask, Bmask, Amask);
return NULL;
}

View File

@@ -340,7 +340,7 @@ SDL_Surface *IMG_LoadPNG_RW(SDL_RWops *src)
png_structp png_ptr;
png_infop info_ptr;
png_uint_32 width, height;
int bit_depth, color_type, interlace_type;
int bit_depth, color_type, interlace_type, num_channels;
Uint32 Rmask;
Uint32 Gmask;
Uint32 Bmask;
@@ -452,15 +452,19 @@ SDL_Surface *IMG_LoadPNG_RW(SDL_RWops *src)
&color_type, &interlace_type, NULL, NULL);
/* Allocate the SDL surface to hold the image */
Rmask = Gmask = Bmask = Amask = 0 ;
Rmask = Gmask = Bmask = Amask = 0 ;
num_channels = lib.png_get_channels(png_ptr, info_ptr);
/* Some .png files are monochrome, with as much as 1 channel and 1 bit per pixel */
if( num_channels != 3 && num_channels != 4 )
num_channels = 3;
if ( color_type != PNG_COLOR_TYPE_PALETTE ) {
if ( SDL_BYTEORDER == SDL_LIL_ENDIAN ) {
Rmask = 0x000000FF;
Gmask = 0x0000FF00;
Bmask = 0x00FF0000;
Amask = (lib.png_get_channels(png_ptr, info_ptr) == 4) ? 0xFF000000 : 0;
Amask = (num_channels == 4) ? 0xFF000000 : 0;
} else {
int s = (lib.png_get_channels(png_ptr, info_ptr) == 4) ? 0 : 8;
int s = (num_channels == 4) ? 0 : 8;
Rmask = 0xFF000000 >> s;
Gmask = 0x00FF0000 >> s;
Bmask = 0x0000FF00 >> s;
@@ -468,7 +472,7 @@ SDL_Surface *IMG_LoadPNG_RW(SDL_RWops *src)
}
}
surface = SDL_AllocSurface(SDL_SWSURFACE, width, height,
bit_depth*lib.png_get_channels(png_ptr, info_ptr), Rmask,Gmask,Bmask,Amask);
bit_depth*num_channels, Rmask,Gmask,Bmask,Amask);
if ( surface == NULL ) {
error = "Out of memory";
goto done;