From 99698187cf252d3845867b2ea9246bc54a149ac2 Mon Sep 17 00:00:00 2001 From: pelya Date: Tue, 6 Jul 2010 13:57:58 +0300 Subject: [PATCH] True HW acceleration for Alien Blaster - it now runs 45 FPS on ADP1, and 30 FPS on HTC Evo (it could run faster but they limited max FPS in GL renderer). See file SdlForwardCompat.h to have an idea how to make your SDL 1.2 app HW accelerated with SDL 1.3 - it's a compilation of hacks but whatever. --- .../jni/application/src/SdlForwardCompat.h | 122 ++++++++++++++++++ .../jni/application/src/background.cpp | 8 +- .../project/jni/application/src/background.h | 9 +- .../project/jni/application/src/banner.cpp | 2 +- .../project/jni/application/src/banner.h | 6 +- .../project/jni/application/src/banners.cpp | 2 +- .../project/jni/application/src/banners.h | 2 +- .../project/jni/application/src/enemy.cpp | 8 +- .../project/jni/application/src/enemy.h | 12 +- .../project/jni/application/src/enemys.cpp | 18 +-- .../project/jni/application/src/enemys.h | 10 +- .../project/jni/application/src/explosion.cpp | 4 +- .../project/jni/application/src/explosion.h | 6 +- .../jni/application/src/explosions.cpp | 4 +- .../project/jni/application/src/explosions.h | 5 +- .../project/jni/application/src/font.cpp | 37 +++--- .../project/jni/application/src/font.h | 8 +- .../project/jni/application/src/game.cpp | 31 +++-- .../project/jni/application/src/game.h | 16 ++- .../project/jni/application/src/global.cpp | 4 +- .../project/jni/application/src/global.h | 21 +-- .../jni/application/src/infoscreen.cpp | 4 +- .../project/jni/application/src/infoscreen.h | 16 +-- .../project/jni/application/src/intro.cpp | 32 +++-- .../project/jni/application/src/intro.h | 11 +- .../project/jni/application/src/item.cpp | 2 +- .../project/jni/application/src/item.h | 4 +- .../project/jni/application/src/items.cpp | 2 +- .../project/jni/application/src/items.h | 2 +- .../jni/application/src/menuArcadeMode.cpp | 2 +- .../jni/application/src/menuArcadeMode.h | 12 +- .../project/jni/application/src/racer.cpp | 6 +- .../project/jni/application/src/racer.h | 20 +-- .../project/jni/application/src/racers.cpp | 6 +- .../project/jni/application/src/racers.h | 6 +- .../jni/application/src/setDifficulty.cpp | 4 +- .../jni/application/src/setDifficulty.h | 16 +-- .../project/jni/application/src/settings.cpp | 10 +- .../project/jni/application/src/settings.h | 22 ++-- .../jni/application/src/shieldGlow.cpp | 2 +- .../project/jni/application/src/shieldGlow.h | 4 +- .../project/jni/application/src/shot.cpp | 8 +- .../project/jni/application/src/shot.h | 12 +- .../project/jni/application/src/shots.cpp | 8 +- .../project/jni/application/src/shots.h | 9 +- .../project/jni/application/src/smokePuff.cpp | 2 +- .../project/jni/application/src/smokePuff.h | 4 +- .../jni/application/src/smokePuffs.cpp | 2 +- .../project/jni/application/src/smokePuffs.h | 2 +- .../project/jni/application/src/sonic.cpp | 4 +- .../project/jni/application/src/sonic.h | 8 +- .../project/jni/application/src/surfaceDB.cpp | 11 +- .../project/jni/application/src/surfaceDB.h | 7 +- .../project/jni/application/src/video.cpp | 15 ++- .../project/jni/application/src/video.h | 6 +- .../project/jni/application/src/wreck.cpp | 2 +- .../project/jni/application/src/wreck.h | 4 +- .../project/jni/application/src/wrecks.cpp | 2 +- .../project/jni/application/src/wrecks.h | 3 +- .../project/jni/sdl/src/video/SDL_video.c | 4 + alienblaster110_data.zip | Bin 2189731 -> 2196602 bytes 61 files changed, 401 insertions(+), 230 deletions(-) create mode 100644 alienblaster/project/jni/application/src/SdlForwardCompat.h diff --git a/alienblaster/project/jni/application/src/SdlForwardCompat.h b/alienblaster/project/jni/application/src/SdlForwardCompat.h new file mode 100644 index 000000000..f3f5f2986 --- /dev/null +++ b/alienblaster/project/jni/application/src/SdlForwardCompat.h @@ -0,0 +1,122 @@ +/* + Compatibility wrapper to compile the same code on both SDL 1.2 and 1.3 without many #ifdefs +*/ + +#ifndef __SDL_FORWARD_COMPAT_H__ +#define __SDL_FORWARD_COMPAT_H__ + +#include +#include +#include + +#ifndef __cplusplus +#error "This header is for C++ only, you're unlucky, sorry" +#endif + +#if SDL_VERSION_ATLEAST(1,3,0) + +struct SdlCompat_AcceleratedSurface +{ + SDL_Texture * t; + int w, h; + SDL_PixelFormat * format; +}; + +static inline SdlCompat_AcceleratedSurface * SdlCompat_CreateAcceleratedSurface(SDL_Surface * surface) +{ + SdlCompat_AcceleratedSurface * ret = new SdlCompat_AcceleratedSurface(); + + // Allocate accelerated surface even if that means loss of color quality + Uint32 format; + + if( surface->flags & SDL_SRCALPHA ) + { + format = SDL_PIXELFORMAT_RGBA4444; + ret->t = SDL_CreateTextureFromSurface(format, surface); + } + else if( surface->flags & SDL_SRCCOLORKEY ) + { + // Use 1-bit alpha as colorkey + Uint32 key; + SDL_GetColorKey(surface, &key); + format = SDL_PIXELFORMAT_RGBA5551; + int bpp; + Uint32 Rmask, Gmask, Bmask, Amask; + SDL_PixelFormatEnumToMasks(format, &bpp, &Rmask, &Gmask, &Bmask, &Amask); + + SDL_Surface * temp = SDL_CreateRGBSurface( SDL_SRCALPHA, surface->w, surface->h, bpp, Rmask, Gmask, Bmask, Amask ); + + SDL_FillRect( temp, NULL, SDL_MapRGBA(temp->format, 0, 0, 0, SDL_ALPHA_TRANSPARENT) ); + + SDL_BlitSurface( surface, NULL, temp, NULL ); // Copies only opaque pixels, and sets their alpha to opaque + + ret->t = SDL_CreateTextureFromSurface(format, temp); + + SDL_FreeSurface(temp); + } + else + { + format = SDL_PIXELFORMAT_RGB565; + ret->t = SDL_CreateTextureFromSurface(format, surface); + } + + ret->w = surface->w; + ret->h = surface->h; + + if( ! ret->t ) + { + SDL_SetError("SdlCompat_CreateAcceleratedSurface: Cannot allocate HW texture, W %d H %d format %x surface->flags %x", ret->w, ret->h, format, surface->flags ); + } + + ret->format = new SDL_PixelFormat(); + *(ret->format) = *(surface->format); + + 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); +}; + +static inline void SDL_FreeSurface(SdlCompat_AcceleratedSurface * surface) +{ + delete surface->format; + delete 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, a); + SDL_RenderDrawRect(rect); +}; + +static inline int SDL_Flip(SdlCompat_AcceleratedSurface * unused) +{ + SDL_RenderPresent(); + return 0; +}; + +static inline int SDL_SetAlpha(SdlCompat_AcceleratedSurface * surface, Uint32 flag, Uint8 alpha) +{ + if( ! (flag & SDL_SRCALPHA) ) + alpha = SDL_ALPHA_OPAQUE; + return SDL_SetTextureAlphaMod(surface->t, alpha); +}; + +#else + +// TODO: did not check if SDL 1.2 part compiles +typedef SDL_Surface SdlCompat_AcceleratedSurface; + +static inline SdlCompat_AcceleratedSurface * SdlCompat_CreateAcceleratedSurface(SDL_Surface * surface) +{ + return SDL_ConvertSurface(surface, surface->format, 0); // Just copy it +}; + +#endif + +#endif + diff --git a/alienblaster/project/jni/application/src/background.cpp b/alienblaster/project/jni/application/src/background.cpp index 884719ee9..cefa91457 100644 --- a/alienblaster/project/jni/application/src/background.cpp +++ b/alienblaster/project/jni/application/src/background.cpp @@ -52,10 +52,10 @@ void Background::generateBackground( int length ) { minTileHeight = 9999999; // load all tiles - vector< SDL_Surface* > tmpTiles; + vector< SdlCompat_AcceleratedSurface* > tmpTiles; for(int i=tileNames.size()-1; i>=0; i--) { - SDL_Surface *tile = surfaceDB.loadSurface( tileNames[i] ); + SdlCompat_AcceleratedSurface *tile = surfaceDB.loadSurface( tileNames[i] ); if (tile != NULL) { tmpTiles.push_back( tile ); @@ -92,13 +92,13 @@ void Background::generateBackground( int length ) { } -void Background::draw( SDL_Surface* screen ) { +void Background::draw( SdlCompat_AcceleratedSurface* screen ) { step = (step+1) % (tilesPerColumn*minTileHeight); draw( screen, step ); } -void Background::draw( SDL_Surface* screen, int step ) { +void Background::draw( SdlCompat_AcceleratedSurface* screen, int step ) { if (step < 0) { step *= -1; } diff --git a/alienblaster/project/jni/application/src/background.h b/alienblaster/project/jni/application/src/background.h index f2967a367..74686da2e 100644 --- a/alienblaster/project/jni/application/src/background.h +++ b/alienblaster/project/jni/application/src/background.h @@ -22,8 +22,7 @@ #include #include - -class SDL_Surface; +#include "SdlForwardCompat.h" class Background { public: @@ -32,8 +31,8 @@ class Background { void clearTileList(); void addTile( std::string tilename ); void generateBackground( int length ); - void draw( SDL_Surface* screen ); - void draw( SDL_Surface* screen, int step ); + void draw( SdlCompat_AcceleratedSurface* screen ); + void draw( SdlCompat_AcceleratedSurface* screen, int step ); private: @@ -44,7 +43,7 @@ class Background { int step; std::vector< std::string > tileNames; - std::vector< SDL_Surface* > tileSurfaces; + std::vector< SdlCompat_AcceleratedSurface* > tileSurfaces; }; diff --git a/alienblaster/project/jni/application/src/banner.cpp b/alienblaster/project/jni/application/src/banner.cpp index 547d7ee00..502a63174 100644 --- a/alienblaster/project/jni/application/src/banner.cpp +++ b/alienblaster/project/jni/application/src/banner.cpp @@ -104,7 +104,7 @@ bool Banner::movingAway() { return ( 3000 <= timeLived ); } -void Banner::draw(SDL_Surface *screen) { +void Banner::draw(SdlCompat_AcceleratedSurface *screen) { SDL_Rect r; r.x = lroundf(pos.getX()); r.y = lroundf(pos.getY()); diff --git a/alienblaster/project/jni/application/src/banner.h b/alienblaster/project/jni/application/src/banner.h index 35667e11b..5c3230a6f 100644 --- a/alienblaster/project/jni/application/src/banner.h +++ b/alienblaster/project/jni/application/src/banner.h @@ -26,8 +26,8 @@ #include "global.h" class Banner { - SDL_Surface *sprite; - SDL_Surface *spriteBonus; + SdlCompat_AcceleratedSurface *sprite; + SdlCompat_AcceleratedSurface *spriteBonus; int sound; @@ -42,7 +42,7 @@ class Banner { ~Banner(); void update( int dT ); - void draw( SDL_Surface *screen ); + void draw( SdlCompat_AcceleratedSurface *screen ); bool isExpired(); bool movingAway(); }; diff --git a/alienblaster/project/jni/application/src/banners.cpp b/alienblaster/project/jni/application/src/banners.cpp index 21d872f95..a14844acb 100644 --- a/alienblaster/project/jni/application/src/banners.cpp +++ b/alienblaster/project/jni/application/src/banners.cpp @@ -73,7 +73,7 @@ void Banners::update( int dT ) { } } -void Banners::draw(SDL_Surface *screen) { +void Banners::draw(SdlCompat_AcceleratedSurface *screen) { switch ( banners.size() ) { case 0: break; case 1: banners[0]->draw( screen ); break; diff --git a/alienblaster/project/jni/application/src/banners.h b/alienblaster/project/jni/application/src/banners.h index ea08a1275..2ebdf2314 100644 --- a/alienblaster/project/jni/application/src/banners.h +++ b/alienblaster/project/jni/application/src/banners.h @@ -39,7 +39,7 @@ class Banners { void expireBanners(); void deleteAllBanners(); void update( int dT ); - void draw(SDL_Surface *screen); + void draw(SdlCompat_AcceleratedSurface *screen); }; diff --git a/alienblaster/project/jni/application/src/enemy.cpp b/alienblaster/project/jni/application/src/enemy.cpp index fea64969e..1e28c620c 100644 --- a/alienblaster/project/jni/application/src/enemy.cpp +++ b/alienblaster/project/jni/application/src/enemy.cpp @@ -474,7 +474,7 @@ void Enemy::doDamage( ShotTypes shotType, int fromWhichPlayer ) { } -void Enemy::drawGroundEnemy( SDL_Surface *screen ) { +void Enemy::drawGroundEnemy( SdlCompat_AcceleratedSurface *screen ) { if ( ENEMY_FLYING[ enemyType ] ) return; SDL_Rect destR; @@ -487,7 +487,7 @@ void Enemy::drawGroundEnemy( SDL_Surface *screen ) { SDL_BlitSurface( spriteEnemy, 0, screen, &destR ); } -void Enemy::drawAirEnemy( SDL_Surface *screen ) { +void Enemy::drawAirEnemy( SdlCompat_AcceleratedSurface *screen ) { if ( !ENEMY_FLYING[ enemyType ] ) return; SDL_Rect destR; @@ -500,7 +500,7 @@ void Enemy::drawAirEnemy( SDL_Surface *screen ) { SDL_BlitSurface( spriteEnemy, 0, screen, &destR ); } -void Enemy::drawShadow( SDL_Surface *screen ) { +void Enemy::drawShadow( SdlCompat_AcceleratedSurface *screen ) { if ( !ENEMY_FLYING[ enemyType ] ) return; SDL_Rect destR; @@ -514,7 +514,7 @@ void Enemy::drawShadow( SDL_Surface *screen ) { } -void Enemy::drawStats( SDL_Surface *screen ) { +void Enemy::drawStats( SdlCompat_AcceleratedSurface *screen ) { // draw status of the bosses float pixPerHP = spriteEnemy->w / (float)(ENEMY_HITPOINTS[ enemyType ]); SDL_Rect destR; diff --git a/alienblaster/project/jni/application/src/enemy.h b/alienblaster/project/jni/application/src/enemy.h index 3cd0faa7d..bfc659e00 100644 --- a/alienblaster/project/jni/application/src/enemy.h +++ b/alienblaster/project/jni/application/src/enemy.h @@ -32,8 +32,8 @@ class BoundingBox; class Enemy { private: - SDL_Surface *spriteEnemy; - SDL_Surface *spriteShadow; + SdlCompat_AcceleratedSurface *spriteEnemy; + SdlCompat_AcceleratedSurface *spriteShadow; // for collision with racers or shots. // A rectangle with racersize * 0.9 is used. BoundingBox *boundingBox; @@ -97,10 +97,10 @@ class Enemy { void updateBoundingBox(); public: - void drawGroundEnemy( SDL_Surface *screen ); - void drawAirEnemy( SDL_Surface *screen ); - void drawShadow( SDL_Surface *screen ); - void drawStats( SDL_Surface *screen ); + void drawGroundEnemy( SdlCompat_AcceleratedSurface *screen ); + void drawAirEnemy( SdlCompat_AcceleratedSurface *screen ); + void drawShadow( SdlCompat_AcceleratedSurface *screen ); + void drawStats( SdlCompat_AcceleratedSurface *screen ); // collision system // return if the line between the two points collides with the boundingBox diff --git a/alienblaster/project/jni/application/src/enemys.cpp b/alienblaster/project/jni/application/src/enemys.cpp index e85483537..77423d15e 100644 --- a/alienblaster/project/jni/application/src/enemys.cpp +++ b/alienblaster/project/jni/application/src/enemys.cpp @@ -208,13 +208,13 @@ void Enemys::generateEnemys( int dT ) { } case TANK: { -// SDL_Surface *spriteTank = surfaceDB.loadSurface( FN_ENEMY_TANK ); -// SDL_Surface *spriteTankWreck = surfaceDB.loadSurface( FN_WRECK_TANK ); +// SdlCompat_AcceleratedSurface *spriteTank = surfaceDB.loadSurface( FN_ENEMY_TANK ); +// SdlCompat_AcceleratedSurface *spriteTankWreck = surfaceDB.loadSurface( FN_WRECK_TANK ); string fn1, fn2; levelConf->getStr( LVL_ENEMY_TANK, fn1 ); levelConf->getStr( LVL_WRECK_TANK, fn2 ); - SDL_Surface *spriteTank = surfaceDB.loadSurface( fn1 ); - SDL_Surface *spriteTankWreck = surfaceDB.loadSurface( fn2 ); + SdlCompat_AcceleratedSurface *spriteTank = surfaceDB.loadSurface( fn1 ); + SdlCompat_AcceleratedSurface *spriteTankWreck = surfaceDB.loadSurface( fn2 ); int halfWidthTank = spriteTank->w / 2; int halfHeightTank = spriteTank->h / 2; int halfWidthTankWreck = spriteTankWreck->w / 2; @@ -338,28 +338,28 @@ void Enemys::deleteExpiredEnemys() { } } -void Enemys::drawGroundEnemys(SDL_Surface *screen) { +void Enemys::drawGroundEnemys(SdlCompat_AcceleratedSurface *screen) { vector::iterator i; for (i = enemys.begin(); i != enemys.end(); ++i) { (*i)->drawGroundEnemy(screen); } } -void Enemys::drawAirEnemys(SDL_Surface *screen) { +void Enemys::drawAirEnemys(SdlCompat_AcceleratedSurface *screen) { vector::iterator i; for (i = enemys.begin(); i != enemys.end(); ++i) { (*i)->drawAirEnemy(screen); } } -void Enemys::drawShadows(SDL_Surface *screen) { +void Enemys::drawShadows(SdlCompat_AcceleratedSurface *screen) { vector::iterator i; for (i = enemys.begin(); i != enemys.end(); ++i) { (*i)->drawShadow(screen); } } -void Enemys::drawBossStats( SDL_Surface *screen ) { +void Enemys::drawBossStats( SdlCompat_AcceleratedSurface *screen ) { for ( unsigned int i = 0; i < enemys.size(); i++ ) { if ( enemys[ i ]->getType() >= NR_ENEMY_TYPES_NORMAL ) { enemys[ i ]->drawStats( screen ); @@ -367,7 +367,7 @@ void Enemys::drawBossStats( SDL_Surface *screen ) { } } -void Enemys::drawAllStats( SDL_Surface *screen ) { +void Enemys::drawAllStats( SdlCompat_AcceleratedSurface *screen ) { for ( unsigned int i = 0; i < enemys.size(); i++ ) { enemys[ i ]->drawStats( screen ); } diff --git a/alienblaster/project/jni/application/src/enemys.h b/alienblaster/project/jni/application/src/enemys.h index 4652d82af..8abaca35e 100644 --- a/alienblaster/project/jni/application/src/enemys.h +++ b/alienblaster/project/jni/application/src/enemys.h @@ -67,11 +67,11 @@ class Enemys { void doNukeDamage(); // draws the enemys. - void drawGroundEnemys( SDL_Surface *screen ); - void drawAirEnemys( SDL_Surface *screen ); - void drawShadows( SDL_Surface *screen ); - void drawBossStats( SDL_Surface *screen ); - void drawAllStats( SDL_Surface *screen ); + void drawGroundEnemys( SdlCompat_AcceleratedSurface *screen ); + void drawAirEnemys( SdlCompat_AcceleratedSurface *screen ); + void drawShadows( SdlCompat_AcceleratedSurface *screen ); + void drawBossStats( SdlCompat_AcceleratedSurface *screen ); + void drawAllStats( SdlCompat_AcceleratedSurface *screen ); }; #endif diff --git a/alienblaster/project/jni/application/src/explosion.cpp b/alienblaster/project/jni/application/src/explosion.cpp index 14b6750d0..8c840be1c 100644 --- a/alienblaster/project/jni/application/src/explosion.cpp +++ b/alienblaster/project/jni/application/src/explosion.cpp @@ -70,7 +70,7 @@ void Explosion::update( int dT ) { } } -void Explosion::drawAirExplosion(SDL_Surface *screen) { +void Explosion::drawAirExplosion(SdlCompat_AcceleratedSurface *screen) { if (expired) return; if ( ! ( explosionType == EXPLOSION_NORMAL_AIR ) ) return; @@ -89,7 +89,7 @@ void Explosion::drawAirExplosion(SDL_Surface *screen) { SDL_BlitSurface( sprite, &src, screen, &dest ); } -void Explosion::drawGroundExplosion(SDL_Surface *screen) { +void Explosion::drawGroundExplosion(SdlCompat_AcceleratedSurface *screen) { if (expired) return; if ( ! ( explosionType == EXPLOSION_NORMAL_GROUND ) ) return; diff --git a/alienblaster/project/jni/application/src/explosion.h b/alienblaster/project/jni/application/src/explosion.h index d25f5c473..384f794ca 100644 --- a/alienblaster/project/jni/application/src/explosion.h +++ b/alienblaster/project/jni/application/src/explosion.h @@ -29,7 +29,7 @@ class Explosion { // a sprite, that contains horizontally all animationframes of the explosion. // it is assumed, that every frame is quadratic. - SDL_Surface *sprite; + SdlCompat_AcceleratedSurface *sprite; // how many frames does this explosion have? int nrAnimStages; @@ -57,8 +57,8 @@ class Explosion { ~Explosion(); // updates the position and the counters void update( int dT ); - void drawAirExplosion(SDL_Surface *screen); - void drawGroundExplosion(SDL_Surface *screen); + void drawAirExplosion(SdlCompat_AcceleratedSurface *screen); + void drawGroundExplosion(SdlCompat_AcceleratedSurface *screen); bool isExpired() { return expired; } }; diff --git a/alienblaster/project/jni/application/src/explosions.cpp b/alienblaster/project/jni/application/src/explosions.cpp index b9f313314..c4886e32b 100644 --- a/alienblaster/project/jni/application/src/explosions.cpp +++ b/alienblaster/project/jni/application/src/explosions.cpp @@ -38,14 +38,14 @@ void Explosions::addExplosion(Explosion *explosion) { } } -void Explosions::drawAirExplosions(SDL_Surface *screen) { +void Explosions::drawAirExplosions(SdlCompat_AcceleratedSurface *screen) { vector::iterator i; for (i = explosions.begin(); i != explosions.end(); ++i) { (*i)->drawAirExplosion(screen); } } -void Explosions::drawGroundExplosions(SDL_Surface *screen) { +void Explosions::drawGroundExplosions(SdlCompat_AcceleratedSurface *screen) { vector::iterator i; for (i = explosions.begin(); i != explosions.end(); ++i) { (*i)->drawGroundExplosion(screen); diff --git a/alienblaster/project/jni/application/src/explosions.h b/alienblaster/project/jni/application/src/explosions.h index 38c1e2b25..df0a40403 100644 --- a/alienblaster/project/jni/application/src/explosions.h +++ b/alienblaster/project/jni/application/src/explosions.h @@ -22,6 +22,7 @@ #include #include "SDL.h" +#include "SdlForwardCompat.h" class Explosion; @@ -41,8 +42,8 @@ class Explosions { // deletes the explosions, that have timed out void expireExplosions(); // draws all explosions - void drawAirExplosions( SDL_Surface *screen ); - void drawGroundExplosions( SDL_Surface *screen ); + void drawAirExplosions( SdlCompat_AcceleratedSurface *screen ); + void drawGroundExplosions( SdlCompat_AcceleratedSurface *screen ); }; #endif diff --git a/alienblaster/project/jni/application/src/font.cpp b/alienblaster/project/jni/application/src/font.cpp index a4e060261..7d2ab854e 100644 --- a/alienblaster/project/jni/application/src/font.cpp +++ b/alienblaster/project/jni/application/src/font.cpp @@ -25,11 +25,13 @@ using namespace std; #include Font::Font(string fn) { - sprite = surfaceDB.loadSurface( fn ); + sprites[0] = surfaceDB.loadSurface( fn + "-1.bmp" ); + sprites[1] = surfaceDB.loadSurface( fn + "-2.bmp" ); + sprites[2] = surfaceDB.loadSurface( fn + "-3.bmp" ); charset = " ABCDEFGHIJKLMNOPQRSTUVWXYZÜÄÖabcdefghijklmnopqrstuvwxyzüäöß0123456789!\"§$%&/()=?*+'#,.-;:_@°\\"; // 94 Zeichen - charWidth = sprite->w / 94; - charHeight = sprite->h; + charWidth = sprites[0]->w / MAX_CHARS_PER_TEXTURE; + charHeight = sprites[0]->h; } Font::~Font() { @@ -45,10 +47,10 @@ int Font::getCharWidth() { } int Font::getCharHeight() { - return sprite->h; + return sprites[0]->h; } -void Font::drawInt(SDL_Surface *screen, int posx, int posy, int val, int alignDigitCnt, int flags) { +void Font::drawInt(SdlCompat_AcceleratedSurface *screen, int posx, int posy, int val, int alignDigitCnt, int flags) { int indent = 0; int digitCnt = 1; int i=1; @@ -85,17 +87,16 @@ void Font::drawInt(SDL_Surface *screen, int posx, int posy, int val, int alignDi destR.h = charHeight; unsigned int charsetpos = charset.find( (char)((val % 10) + '0') ); - if (charsetpos != string::npos ) { - srcR.x = charsetpos * charWidth; - } else { - srcR.x = charWidth; - } + if (charsetpos == string::npos ) + charsetpos = 0; // Space + srcR.x = (charsetpos % MAX_CHARS_PER_TEXTURE) * charWidth; + // srcR.x = (1 + 2*26 + (val % 10)) * charWidth; srcR.y = 0; srcR.w = charWidth; srcR.h = charHeight; - SDL_BlitSurface( sprite, &srcR, screen, &destR ); + SDL_BlitSurface( sprites[charsetpos / MAX_CHARS_PER_TEXTURE], &srcR, screen, &destR ); } val /= 10; digitCnt--; @@ -105,7 +106,7 @@ void Font::drawInt(SDL_Surface *screen, int posx, int posy, int val, int alignDi -void Font::drawStr(SDL_Surface *screen, int posx, int posy, const string &text, int flags) { +void Font::drawStr(SdlCompat_AcceleratedSurface *screen, int posx, int posy, const string &text, int flags) { int indent = 0; if ( flags & (FONT_ALIGN_CENTERED | FONT_ALIGN_RIGHT) ) { @@ -131,21 +132,21 @@ void Font::drawStr(SDL_Surface *screen, int posx, int posy, const string &text, for(unsigned int i=0; i < text.size(); ++i) { x = 0; charsetpos = charset.find(text[i]); - if (charsetpos != string::npos ) { - x = charsetpos * charWidth; - } + if (charsetpos == string::npos ) + charsetpos = 0; // Space + x = (charsetpos % MAX_CHARS_PER_TEXTURE) * charWidth; destR.x = posx + indent; destR.y = posy; destR.w = charWidth; - destR.h = sprite->h; + destR.h = sprites[0]->h; srcR.x = x; srcR.y = 0; srcR.w = charWidth; - srcR.h = sprite->h; + srcR.h = sprites[0]->h; - SDL_BlitSurface( sprite, &srcR, screen, &destR ); + SDL_BlitSurface( sprites[charsetpos / MAX_CHARS_PER_TEXTURE], &srcR, screen, &destR ); if (!(flags & FONT_MONOSPACE) && text[i] == ' ') { posx += ((charWidth * 2) / 3); diff --git a/alienblaster/project/jni/application/src/font.h b/alienblaster/project/jni/application/src/font.h index 823ce54ab..8e7dee768 100644 --- a/alienblaster/project/jni/application/src/font.h +++ b/alienblaster/project/jni/application/src/font.h @@ -22,6 +22,7 @@ #include "SDL.h" #include +#include "SdlForwardCompat.h" // *** Code *** // @@ -58,7 +59,8 @@ const int FONT_MONOSPACE = (1<<3); class Font { private: - SDL_Surface *sprite; + enum { MAX_CHARS_PER_TEXTURE = 32 }; // OpenGL ES does not allow textures wider than 1024 bytes, so we have to split it + SdlCompat_AcceleratedSurface *sprites[3]; // Our font has only 94 letters int charWidth; int charHeight; std::string charset; @@ -70,8 +72,8 @@ class Font { void setCharWidth(int width); int getCharWidth(); int getCharHeight(); - void drawInt(SDL_Surface *screen, int posx, int posy, int val, int alignDigitCnt, int flags = 0); - void drawStr(SDL_Surface *screen, int posx, int posy, const std::string &text, int flags = 0); + void drawInt(SdlCompat_AcceleratedSurface *screen, int posx, int posy, int val, int alignDigitCnt, int flags = 0); + void drawStr(SdlCompat_AcceleratedSurface *screen, int posx, int posy, const std::string &text, int flags = 0); }; #endif diff --git a/alienblaster/project/jni/application/src/game.cpp b/alienblaster/project/jni/application/src/game.cpp index c733d57e9..e17ce2cfa 100644 --- a/alienblaster/project/jni/application/src/game.cpp +++ b/alienblaster/project/jni/application/src/game.cpp @@ -22,6 +22,7 @@ using namespace std; #include #include #include +#include #include #include "SDL.h" @@ -140,7 +141,7 @@ Game::Game() { __android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Game() 9"); - SDL_Surface *loadingSprite = surfaceDB.loadSurface( FN_LOADING ); + SdlCompat_AcceleratedSurface *loadingSprite = surfaceDB.loadSurface( FN_LOADING ); __android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Game() 10"); SDL_Rect dest; dest.x = (SCREEN_WIDTH - loadingSprite->w ) / 2; @@ -337,8 +338,13 @@ void Game::playOn() { int A = SDL_GetTicks(); frameCnt = 0; tickCnt = 0; - cout << "frameCnt: " << frameCnt << " tickCnt: " << tickCnt - << " SDL_GetTicks()=" << A << endl; + { + std::ostringstream logout; + logout << "frameCnt: " << frameCnt << " tickCnt: " << tickCnt + << " SDL_GetTicks()=" << A; + __android_log_print(ANDROID_LOG_INFO, "Alien Blaster", logout.str().c_str()); + } + while ( gameState == GS_PLAYON ) { handleEventsPlayOn(); @@ -365,12 +371,17 @@ void Game::playOn() { if ( racers->bothPlayersLost() ) gameState = GS_ROUNDFINISHED; } - int B = SDL_GetTicks(); - cout << "frameCnt: " << frameCnt << " tickCnt: " << tickCnt - << " SDL_GetTicks()=" << B << endl; - cout << "Miliseconds: " << B-A << endl; - cout << "Frames/sec : " << (float)frameCnt / ((float)(B-A) / 1000.0) << endl; - cout << "ms/Frame : " << (float)tickCnt / (float)frameCnt << endl; + { + std::ostringstream logout; + + int B = SDL_GetTicks(); + logout << "frameCnt: " << frameCnt << " tickCnt: " << tickCnt + << " SDL_GetTicks()=" << B << endl; + logout << "Milliseconds: " << B-A << endl; + logout << "Frames/sec : " << (float)frameCnt / ((float)(B-A) / 1000.0) << endl; + logout << "ms/Frame : " << (float)tickCnt / (float)frameCnt << endl; + __android_log_print(ANDROID_LOG_INFO, "Alien Blaster", logout.str().c_str()); + } } @@ -636,9 +647,11 @@ void Game::drawNukeEffect() { // effect-process: transparent -> nearly opaque -> transparent int timeFromMaximum = (NUKE_EFFECT_DURATION / 2) - (timeNukeEnd - SDL_GetTicks()); timeFromMaximum = abs(timeFromMaximum); + SDL_SetAlpha( nukeEffectSurface, SDL_SRCALPHA | SDL_RLEACCEL, lroundf(((NUKE_EFFECT_DURATION / 2) - timeFromMaximum) * 128.0 / (NUKE_EFFECT_DURATION / 2)) ); + SDL_BlitSurface( nukeEffectSurface, 0, screen, 0 ); int randRange = (int) diff --git a/alienblaster/project/jni/application/src/game.h b/alienblaster/project/jni/application/src/game.h index 1b92d4dd2..55a006a07 100644 --- a/alienblaster/project/jni/application/src/game.h +++ b/alienblaster/project/jni/application/src/game.h @@ -21,8 +21,10 @@ #define GAME_HH #include "SDL.h" +#include "SdlForwardCompat.h" #include + class Video; class SurfaceDB; class Racers; @@ -46,14 +48,14 @@ enum GameStates { GS_QUIT, GS_SCREENSHOTS, GS_INTRO, GS_SET_DIFFICULTY, game objects and their dependencies. */ class Game { // Video system - SDL_Surface *screen; + SdlCompat_AcceleratedSurface *screen; - SDL_Surface *pauseSprite; - SDL_Surface *youLoseSprite; - SDL_Surface *youWinSprite; - SDL_Surface *gameOverSprite; - SDL_Surface *nukeEffectSurface; - SDL_Surface *hud; + SdlCompat_AcceleratedSurface *pauseSprite; + SdlCompat_AcceleratedSurface *youLoseSprite; + SdlCompat_AcceleratedSurface *youWinSprite; + SdlCompat_AcceleratedSurface *gameOverSprite; + SdlCompat_AcceleratedSurface *nukeEffectSurface; + SdlCompat_AcceleratedSurface *hud; // Time system Font *fontTime; diff --git a/alienblaster/project/jni/application/src/global.cpp b/alienblaster/project/jni/application/src/global.cpp index e5dda4a1d..bd3b01055 100644 --- a/alienblaster/project/jni/application/src/global.cpp +++ b/alienblaster/project/jni/application/src/global.cpp @@ -366,8 +366,8 @@ void initAllSurfaces() { surfaceDB.loadSurface("./images/lightFighterShieldDamaged.bmp"); surfaceDB.loadSurface("./images/heavyFighterShieldDamaged.bmp"); surfaceDB.loadSurface("./images/heavyFighterDeflector.bmp", true); - surfaceDB.loadSurface("./images/font-20red.bmp"); - surfaceDB.loadSurface("./images/font-20blue.bmp"); + //surfaceDB.loadSurface("./images/font-20red"); + //surfaceDB.loadSurface("./images/font-20blue"); surfaceDB.loadSurface("./images/explosion.bmp"); surfaceDB.loadSurface("./images/explosionEnemy.bmp"); surfaceDB.loadSurface("./images/bannerExcellent.bmp", true); diff --git a/alienblaster/project/jni/application/src/global.h b/alienblaster/project/jni/application/src/global.h index ce4d62078..e4b752d18 100644 --- a/alienblaster/project/jni/application/src/global.h +++ b/alienblaster/project/jni/application/src/global.h @@ -21,6 +21,7 @@ #define GLOBAL_H #include +#include "SdlForwardCompat.h" class Racers; class Enemys; @@ -617,16 +618,16 @@ const std::string FN_INTRO_SHOW_CHOICE = "./images/menuIcon.bmp"; const std::string FN_FONT_PATH = "./images/"; const std::string FN_FONT_SUFFIX_SURFACE = ".bmp"; -const std::string FN_FONT_INTRO = "./images/font-20white.bmp"; -const std::string FN_FONT_INTRO_HIGHLIGHTED = "./images/font-20lightblue.bmp"; -const std::string FN_FONT_NUMBERS_TIME = "./images/font-20red.bmp"; -const std::string FN_FONT_NUMBERS_LEFT = "./images/font-20red.bmp"; -const std::string FN_FONT_NUMBERS_RIGHT = "./images/font-20blue.bmp"; -const std::string FN_FONT_SETTINGS = "./images/font-20white.bmp"; -const std::string FN_FONT_SETTINGS_HIGHLIGHTED = "./images/font-20lightblue.bmp"; -const std::string FN_FONT_SETTINGS_SMALL = "./images/font-14white.bmp"; -const std::string FN_FONT_SETTINGS_SMALL_BLUE = "./images/font-14lightblue.bmp"; -const std::string FN_FONT_SETTINGS_SMALL_HIGHLIGHTED = "./images/font-14red.bmp"; +const std::string FN_FONT_INTRO = "./images/font-20white"; +const std::string FN_FONT_INTRO_HIGHLIGHTED = "./images/font-20lightblue"; +const std::string FN_FONT_NUMBERS_TIME = "./images/font-20red"; +const std::string FN_FONT_NUMBERS_LEFT = "./images/font-20red"; +const std::string FN_FONT_NUMBERS_RIGHT = "./images/font-20blue"; +const std::string FN_FONT_SETTINGS = "./images/font-20white"; +const std::string FN_FONT_SETTINGS_HIGHLIGHTED = "./images/font-20lightblue"; +const std::string FN_FONT_SETTINGS_SMALL = "./images/font-14white"; +const std::string FN_FONT_SETTINGS_SMALL_BLUE = "./images/font-14lightblue"; +const std::string FN_FONT_SETTINGS_SMALL_HIGHLIGHTED = "./images/font-14red"; const std::string FN_SETTINGS_BLUE = "./images/bluePlain.bmp"; const std::string FN_SETTINGS_WHITE = "./images/whitePlain.bmp"; diff --git a/alienblaster/project/jni/application/src/infoscreen.cpp b/alienblaster/project/jni/application/src/infoscreen.cpp index 9ef3c081b..dece84f50 100644 --- a/alienblaster/project/jni/application/src/infoscreen.cpp +++ b/alienblaster/project/jni/application/src/infoscreen.cpp @@ -30,7 +30,7 @@ using namespace std; Items *infoscreenItems; -Infoscreen::Infoscreen( SDL_Surface *scr ) { +Infoscreen::Infoscreen( SdlCompat_AcceleratedSurface *scr ) { screen = scr; font = new Font( FN_FONT_INTRO ); fontHighlighted = new Font( FN_FONT_INTRO_HIGHLIGHTED ); @@ -61,7 +61,7 @@ void Infoscreen::run() { } } -void Infoscreen::putBitmapAtPosition( int x, int y, SDL_Surface* bitmap ) { +void Infoscreen::putBitmapAtPosition( int x, int y, SdlCompat_AcceleratedSurface* bitmap ) { SDL_Rect d; d.x = x - bitmap->w / 2; d.y = y - bitmap->h / 2; diff --git a/alienblaster/project/jni/application/src/infoscreen.h b/alienblaster/project/jni/application/src/infoscreen.h index 91c7825da..74ab336e0 100644 --- a/alienblaster/project/jni/application/src/infoscreen.h +++ b/alienblaster/project/jni/application/src/infoscreen.h @@ -66,12 +66,12 @@ const int NR_INFOSCREEN_CHOICES = 15; class Infoscreen { private: - SDL_Surface *screen; - SDL_Surface *activeChoiceSprite; - SDL_Surface *lightFighterIcon1; - SDL_Surface *lightFighterIcon2; - SDL_Surface *heavyFighterIcon1; - SDL_Surface *heavyFighterIcon2; + SdlCompat_AcceleratedSurface *screen; + SdlCompat_AcceleratedSurface *activeChoiceSprite; + SdlCompat_AcceleratedSurface *lightFighterIcon1; + SdlCompat_AcceleratedSurface *lightFighterIcon2; + SdlCompat_AcceleratedSurface *heavyFighterIcon1; + SdlCompat_AcceleratedSurface *heavyFighterIcon2; Font *font; Font *fontHighlighted; Item *newItem; @@ -83,14 +83,14 @@ class Infoscreen { int choose, confirm; public: - Infoscreen( SDL_Surface *scr ); + Infoscreen( SdlCompat_AcceleratedSurface *scr ); ~Infoscreen(); void run(); private: void handleEvents(); void draw(); - void putBitmapAtPosition( int x, int y, SDL_Surface* bitmap ); + void putBitmapAtPosition( int x, int y, SdlCompat_AcceleratedSurface* bitmap ); }; #endif diff --git a/alienblaster/project/jni/application/src/intro.cpp b/alienblaster/project/jni/application/src/intro.cpp index 8fbedc985..0db3584a6 100644 --- a/alienblaster/project/jni/application/src/intro.cpp +++ b/alienblaster/project/jni/application/src/intro.cpp @@ -30,7 +30,7 @@ using namespace std; #include "settings.h" #include "infoscreen.h" -Intro::Intro( SDL_Surface *scr ) { +Intro::Intro( SdlCompat_AcceleratedSurface *scr ) { __android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Intro() 1"); screen = scr; __android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Intro() 2"); @@ -184,17 +184,19 @@ void Intro::showScreenshots() { Mixer::mixer().playMusic( MUSIC_INTRO, -1, 1000 ); } - SDL_Surface *surfS = SDL_LoadBMP( FN_ALIENBLASTER_INTRO.c_str() ); - SDL_Surface *surf0 = SDL_LoadBMP( FN_SCREENSHOT0.c_str() ); - SDL_Surface *surf1 = SDL_LoadBMP( FN_SCREENSHOT1.c_str() ); - SDL_Surface *surf2 = SDL_LoadBMP( FN_SCREENSHOT2.c_str() ); - SDL_Surface *surf3 = SDL_LoadBMP( FN_SCREENSHOT3.c_str() ); - SDL_Surface *surf4 = SDL_LoadBMP( FN_SCREENSHOT4.c_str() ); - SDL_Surface *surf5 = SDL_LoadBMP( FN_SCREENSHOT5.c_str() ); - SDL_Surface *surf6 = SDL_LoadBMP( FN_SCREENSHOT6.c_str() ); - SDL_Surface *surf7 = SDL_LoadBMP( FN_SCREENSHOT7.c_str() ); - SDL_Surface *surf8 = SDL_LoadBMP( FN_SCREENSHOT8.c_str() ); - SDL_Surface *surf9 = SDL_LoadBMP( FN_SCREENSHOT9.c_str() ); + // TODO: Too lazy to fix that + /* + SdlCompat_AcceleratedSurface *surfS = SDL_LoadBMP( FN_ALIENBLASTER_INTRO.c_str() ); + SdlCompat_AcceleratedSurface *surf0 = SDL_LoadBMP( FN_SCREENSHOT0.c_str() ); + SdlCompat_AcceleratedSurface *surf1 = SDL_LoadBMP( FN_SCREENSHOT1.c_str() ); + SdlCompat_AcceleratedSurface *surf2 = SDL_LoadBMP( FN_SCREENSHOT2.c_str() ); + SdlCompat_AcceleratedSurface *surf3 = SDL_LoadBMP( FN_SCREENSHOT3.c_str() ); + SdlCompat_AcceleratedSurface *surf4 = SDL_LoadBMP( FN_SCREENSHOT4.c_str() ); + SdlCompat_AcceleratedSurface *surf5 = SDL_LoadBMP( FN_SCREENSHOT5.c_str() ); + SdlCompat_AcceleratedSurface *surf6 = SDL_LoadBMP( FN_SCREENSHOT6.c_str() ); + SdlCompat_AcceleratedSurface *surf7 = SDL_LoadBMP( FN_SCREENSHOT7.c_str() ); + SdlCompat_AcceleratedSurface *surf8 = SDL_LoadBMP( FN_SCREENSHOT8.c_str() ); + SdlCompat_AcceleratedSurface *surf9 = SDL_LoadBMP( FN_SCREENSHOT9.c_str() ); SDL_BlitSurface( surfS, 0, screen, 0 ); SDL_Flip(screen); @@ -210,9 +212,12 @@ void Intro::showScreenshots() { if (blendImages( screen, surf6, 0, surf7, 0, sps )) if (blendImages( screen, surf7, 0, surf8, 0, sps )) blendImages( screen, surf8, 0, surf9, 0, sps ); + */ } -bool Intro::blendImages( SDL_Surface *screen, SDL_Surface *surf0, SDL_Rect *r1, SDL_Surface *surf1, SDL_Rect *r2, int sps ) { +// TODO: Too lazy to fix that +/* +bool Intro::blendImages( SdlCompat_AcceleratedSurface *screen, SdlCompat_AcceleratedSurface *surf0, SDL_Rect *r1, SdlCompat_AcceleratedSurface *surf1, SDL_Rect *r2, int sps ) { SDL_Event event; int i = 0; @@ -242,3 +247,4 @@ bool Intro::blendImages( SDL_Surface *screen, SDL_Surface *surf0, SDL_Rect *r1, } return true; } +*/ diff --git a/alienblaster/project/jni/application/src/intro.h b/alienblaster/project/jni/application/src/intro.h index 27d5e1c63..52fcec7f8 100644 --- a/alienblaster/project/jni/application/src/intro.h +++ b/alienblaster/project/jni/application/src/intro.h @@ -22,6 +22,7 @@ #include #include "SDL.h" +#include "SdlForwardCompat.h" #include "game.h" class Font; @@ -36,9 +37,9 @@ const int NR_INTRO_CHOICES = 6; class Intro { private: - SDL_Surface *screen; - SDL_Surface *introSprite; - SDL_Surface *activeChoiceSprite; + SdlCompat_AcceleratedSurface *screen; + SdlCompat_AcceleratedSurface *introSprite; + SdlCompat_AcceleratedSurface *activeChoiceSprite; Font *font; Font *fontHighlighted; Infoscreen *infoscreen; @@ -50,11 +51,11 @@ class Intro { int confirm; public: - Intro( SDL_Surface *scr ); + Intro( SdlCompat_AcceleratedSurface *scr ); ~Intro(); void run( GameStates &gameState ); void showScreenshots(); - bool blendImages( SDL_Surface *screen, SDL_Surface *surf0, SDL_Rect *r1, SDL_Surface *surf1, SDL_Rect *r2, int sps ); + // bool blendImages( SdlCompat_AcceleratedSurface *screen, SdlCompat_AcceleratedSurface *surf0, SDL_Rect *r1, SdlCompat_AcceleratedSurface *surf1, SDL_Rect *r2, int sps ); private: void handleEvents( GameStates &gameState ); diff --git a/alienblaster/project/jni/application/src/item.cpp b/alienblaster/project/jni/application/src/item.cpp index 65e6c8a95..d965f238d 100644 --- a/alienblaster/project/jni/application/src/item.cpp +++ b/alienblaster/project/jni/application/src/item.cpp @@ -121,7 +121,7 @@ void Item::updateBoundingBox() { boundingBox->moveLeftBound( lroundf(pos.getX() - sprite->w * 0.5) ); } -void Item::draw(SDL_Surface *screen) { +void Item::draw(SdlCompat_AcceleratedSurface *screen) { SDL_Rect r; r.x = lroundf(pos.getX()) - sprite->w / 2; r.y = lroundf(pos.getY()) - sprite->h / 2; diff --git a/alienblaster/project/jni/application/src/item.h b/alienblaster/project/jni/application/src/item.h index 917363ffe..6b9ad78b5 100644 --- a/alienblaster/project/jni/application/src/item.h +++ b/alienblaster/project/jni/application/src/item.h @@ -28,7 +28,7 @@ class BoundingBox; class Item { - SDL_Surface *sprite; + SdlCompat_AcceleratedSurface *sprite; BoundingBox *boundingBox; Vector2D pos; @@ -47,7 +47,7 @@ class Item { void deleteItem(); - void draw(SDL_Surface *screen); + void draw(SdlCompat_AcceleratedSurface *screen); inline bool isExpired() { return (timeLived >= ITEM_LIFETIME); } inline Vector2D getPos() { return pos; } diff --git a/alienblaster/project/jni/application/src/items.cpp b/alienblaster/project/jni/application/src/items.cpp index 1948460a6..4c30ae6a3 100644 --- a/alienblaster/project/jni/application/src/items.cpp +++ b/alienblaster/project/jni/application/src/items.cpp @@ -62,7 +62,7 @@ void Items::update( int dT ) { } } -void Items::draw(SDL_Surface *screen) { +void Items::draw(SdlCompat_AcceleratedSurface *screen) { vector::iterator i; for (i = items.begin(); i != items.end(); ++i) { (*i)->draw(screen); diff --git a/alienblaster/project/jni/application/src/items.h b/alienblaster/project/jni/application/src/items.h index dc673ebe6..23ad76891 100644 --- a/alienblaster/project/jni/application/src/items.h +++ b/alienblaster/project/jni/application/src/items.h @@ -40,7 +40,7 @@ class Items { void generate( int dT ); void expireItems(); void update( int dT ); - void draw(SDL_Surface *screen); + void draw(SdlCompat_AcceleratedSurface *screen); void deleteAllItems(); inline unsigned int getNrItems() { return items.size(); } diff --git a/alienblaster/project/jni/application/src/menuArcadeMode.cpp b/alienblaster/project/jni/application/src/menuArcadeMode.cpp index cdbd7d894..ede53751b 100644 --- a/alienblaster/project/jni/application/src/menuArcadeMode.cpp +++ b/alienblaster/project/jni/application/src/menuArcadeMode.cpp @@ -32,7 +32,7 @@ using namespace std; #include #include -MenuArcadeMode::MenuArcadeMode( SDL_Surface *scr ) { +MenuArcadeMode::MenuArcadeMode( SdlCompat_AcceleratedSurface *scr ) { screen = scr; arcadeSprite = surfaceDB.loadSurface( FN_ARCADE_LOGO ); activeChoiceSprite = surfaceDB.loadSurface( FN_INTRO_SHOW_CHOICE ); diff --git a/alienblaster/project/jni/application/src/menuArcadeMode.h b/alienblaster/project/jni/application/src/menuArcadeMode.h index 41b7e8a43..1cb9589cb 100644 --- a/alienblaster/project/jni/application/src/menuArcadeMode.h +++ b/alienblaster/project/jni/application/src/menuArcadeMode.h @@ -36,11 +36,11 @@ const int NR_MENU_ARCADE_CHOICES = 2; class MenuArcadeMode { private: - SDL_Surface *screen; - SDL_Surface *arcadeSprite; - SDL_Surface *activeChoiceSprite; - SDL_Surface *lightFighterIcon1; - SDL_Surface *heavyFighterIcon1; + SdlCompat_AcceleratedSurface *screen; + SdlCompat_AcceleratedSurface *arcadeSprite; + SdlCompat_AcceleratedSurface *activeChoiceSprite; + SdlCompat_AcceleratedSurface *lightFighterIcon1; + SdlCompat_AcceleratedSurface *heavyFighterIcon1; Font *font; Font *fontHighlighted; @@ -54,7 +54,7 @@ class MenuArcadeMode { bool playerOneLightFighter; public: - MenuArcadeMode( SDL_Surface *scr ); + MenuArcadeMode( SdlCompat_AcceleratedSurface *scr ); ~MenuArcadeMode(); void run( GameStates &gameState, int points=-1 ); bool getPlayerOneLightFighter(); diff --git a/alienblaster/project/jni/application/src/racer.cpp b/alienblaster/project/jni/application/src/racer.cpp index 76cf19dc7..18ef749af 100644 --- a/alienblaster/project/jni/application/src/racer.cpp +++ b/alienblaster/project/jni/application/src/racer.cpp @@ -231,7 +231,7 @@ void Racer::clipWorld() { } -void Racer::drawStats( SDL_Surface *screen ) { +void Racer::drawStats( SdlCompat_AcceleratedSurface *screen ) { SDL_Rect srcR, destR; int indent = 5; @@ -320,7 +320,7 @@ void Racer::drawStats( SDL_Surface *screen ) { } -void Racer::drawShadow( SDL_Surface *screen ) { +void Racer::drawShadow( SdlCompat_AcceleratedSurface *screen ) { SDL_Rect destR; destR.x = lroundf(pos.getX()) - (spriteShadow->w / 2) - 10; destR.y = lroundf(pos.getY()) - (spriteShadow->h / 2) + 10; @@ -330,7 +330,7 @@ void Racer::drawShadow( SDL_Surface *screen ) { } -void Racer::drawRacer( SDL_Surface *screen ) { +void Racer::drawRacer( SdlCompat_AcceleratedSurface *screen ) { SDL_Rect srcR; SDL_Rect destR; diff --git a/alienblaster/project/jni/application/src/racer.h b/alienblaster/project/jni/application/src/racer.h index 5f24c0afd..0e86c2850 100644 --- a/alienblaster/project/jni/application/src/racer.h +++ b/alienblaster/project/jni/application/src/racer.h @@ -40,13 +40,13 @@ class ShieldGlow; /* The Racer is the vehicle, that the player can steer. */ class Racer { - SDL_Surface *spriteRacerBase; + SdlCompat_AcceleratedSurface *spriteRacerBase; SDL_Rect drawRectBase; - SDL_Surface *spriteShadow; - SDL_Surface *spriteDeflector; + SdlCompat_AcceleratedSurface *spriteShadow; + SdlCompat_AcceleratedSurface *spriteDeflector; SDL_Rect drawRectDeflector; - SDL_Surface *spriteHPStat; - SDL_Surface *spriteFighterIcon; + SdlCompat_AcceleratedSurface *spriteHPStat; + SdlCompat_AcceleratedSurface *spriteFighterIcon; // for collision with other racers or shots. // A rectangle with racersize * 0.9 is used. @@ -57,8 +57,8 @@ class Racer { Font *font; // font used for displaying ammo and lapcnt int fontSize; - SDL_Surface *spriteSecondaryWeapons; - SDL_Surface *spriteSpecials; + SdlCompat_AcceleratedSurface *spriteSecondaryWeapons; + SdlCompat_AcceleratedSurface *spriteSpecials; int sndShotPrimary; int sndShotSecondary; @@ -155,9 +155,9 @@ class Racer { // switch special, if the activespecial is out of ammo void specialKeyUp(); - void drawRacer( SDL_Surface *screen ); - void drawShadow( SDL_Surface *screen ); - void drawStats( SDL_Surface *screen ); + void drawRacer( SdlCompat_AcceleratedSurface *screen ); + void drawShadow( SdlCompat_AcceleratedSurface *screen ); + void drawStats( SdlCompat_AcceleratedSurface *screen ); // collision system // return if the line between the two points collides with the boundingBox diff --git a/alienblaster/project/jni/application/src/racers.cpp b/alienblaster/project/jni/application/src/racers.cpp index 2b225aae4..912de49eb 100644 --- a/alienblaster/project/jni/application/src/racers.cpp +++ b/alienblaster/project/jni/application/src/racers.cpp @@ -114,21 +114,21 @@ void Racers::rechargeShield( int dT ) { } } -void Racers::drawRacers( SDL_Surface *screen ) { +void Racers::drawRacers( SdlCompat_AcceleratedSurface *screen ) { vector::iterator i; for (i = racers.begin(); i != racers.end(); ++i) { (*i)->drawRacer(screen); } } -void Racers::drawShadows( SDL_Surface *screen ) { +void Racers::drawShadows( SdlCompat_AcceleratedSurface *screen ) { vector::iterator i; for (i = racers.begin(); i != racers.end(); ++i) { (*i)->drawShadow(screen); } } -void Racers::drawStats( SDL_Surface *screen ) { +void Racers::drawStats( SdlCompat_AcceleratedSurface *screen ) { vector::iterator i; for (i = racers.begin(); i != racers.end(); ++i) { (*i)->drawStats(screen); diff --git a/alienblaster/project/jni/application/src/racers.h b/alienblaster/project/jni/application/src/racers.h index 72564c658..f728096ef 100644 --- a/alienblaster/project/jni/application/src/racers.h +++ b/alienblaster/project/jni/application/src/racers.h @@ -69,9 +69,9 @@ class Racers { // recharge the shields void rechargeShield( int dT ); // draws the racers. - void drawRacers( SDL_Surface *screen ); - void drawShadows( SDL_Surface *screen ); - void drawStats( SDL_Surface *screen ); + void drawRacers( SdlCompat_AcceleratedSurface *screen ); + void drawShadows( SdlCompat_AcceleratedSurface *screen ); + void drawStats( SdlCompat_AcceleratedSurface *screen ); // returns, which racer has shot more enemys //int getWinner(); diff --git a/alienblaster/project/jni/application/src/setDifficulty.cpp b/alienblaster/project/jni/application/src/setDifficulty.cpp index a538ae0ac..e78cd516c 100644 --- a/alienblaster/project/jni/application/src/setDifficulty.cpp +++ b/alienblaster/project/jni/application/src/setDifficulty.cpp @@ -29,7 +29,7 @@ using namespace std; #include "racer.h" #include "racers.h" -SetDifficulty::SetDifficulty( SDL_Surface *scr ) { +SetDifficulty::SetDifficulty( SdlCompat_AcceleratedSurface *scr ) { screen = scr; introSprite = surfaceDB.loadSurface( FN_ALIENBLASTER_INTRO ); activeChoiceSprite = surfaceDB.loadSurface( FN_INTRO_SHOW_CHOICE ); @@ -163,7 +163,7 @@ void SetDifficulty::handleEvents( GameStates &gameState ) { break; } case SDLK_F5: { - SDL_WM_ToggleFullScreen( screen ); + //SDL_WM_ToggleFullScreen( screen ); break; } case SDLK_F7: { diff --git a/alienblaster/project/jni/application/src/setDifficulty.h b/alienblaster/project/jni/application/src/setDifficulty.h index ffb862e8c..714ca9d61 100644 --- a/alienblaster/project/jni/application/src/setDifficulty.h +++ b/alienblaster/project/jni/application/src/setDifficulty.h @@ -36,13 +36,13 @@ const int NR_DIFFICULTY_CHOICES = 5; class SetDifficulty { private: - SDL_Surface *screen; - SDL_Surface *introSprite; - SDL_Surface *activeChoiceSprite; - SDL_Surface *lightFighterIcon1; - SDL_Surface *lightFighterIcon2; - SDL_Surface *heavyFighterIcon1; - SDL_Surface *heavyFighterIcon2; + SdlCompat_AcceleratedSurface *screen; + SdlCompat_AcceleratedSurface *introSprite; + SdlCompat_AcceleratedSurface *activeChoiceSprite; + SdlCompat_AcceleratedSurface *lightFighterIcon1; + SdlCompat_AcceleratedSurface *lightFighterIcon2; + SdlCompat_AcceleratedSurface *heavyFighterIcon1; + SdlCompat_AcceleratedSurface *heavyFighterIcon2; Font *font; Font *fontHighlighted; @@ -56,7 +56,7 @@ class SetDifficulty { int choose; public: - SetDifficulty( SDL_Surface *scr ); + SetDifficulty( SdlCompat_AcceleratedSurface *scr ); ~SetDifficulty(); void run( GameStates &gameState, bool onePlayerGame ); bool getPlayerOneLightFighter(); diff --git a/alienblaster/project/jni/application/src/settings.cpp b/alienblaster/project/jni/application/src/settings.cpp index fd9883082..38d1ab2a7 100644 --- a/alienblaster/project/jni/application/src/settings.cpp +++ b/alienblaster/project/jni/application/src/settings.cpp @@ -134,7 +134,7 @@ void Settings::saveSettings() { } -void Settings::draw( SDL_Surface *screen, bool getNewKey ) { +void Settings::draw( SdlCompat_AcceleratedSurface *screen, bool getNewKey ) { videoserver->clearScreen(); SDL_Rect r; r.x = screen->w / 2 - introSprite->w / 2; @@ -149,7 +149,7 @@ void Settings::draw( SDL_Surface *screen, bool getNewKey ) { } -void Settings::showSpecialKeys( SDL_Surface *screen ) { +void Settings::showSpecialKeys( SdlCompat_AcceleratedSurface *screen ) { fontNormal->drawStr(screen, screen->w/2, screen->h - 2*fontNormal->getCharHeight() - 10, "F1: Configure Keys F5: Fullscreen", FONT_ALIGN_CENTERED ); fontNormal->drawStr(screen, screen->w/2, screen->h - fontNormal->getCharHeight() - 5, @@ -158,7 +158,7 @@ void Settings::showSpecialKeys( SDL_Surface *screen ) { } -void Settings::showSettings( SDL_Surface *screen, bool getNewKey ) { +void Settings::showSettings( SdlCompat_AcceleratedSurface *screen, bool getNewKey ) { int playerOfActiveItem = -1; if ( actChoice <= SC_FIRE_SPEC_1 ) playerOfActiveItem = 0; else if ( actChoice <= SC_FIRE_SPEC_2 ) playerOfActiveItem = 1; @@ -242,7 +242,7 @@ void Settings::showSettings( SDL_Surface *screen, bool getNewKey ) { } } -void Settings::showMenu( SDL_Surface *screen ) { +void Settings::showMenu( SdlCompat_AcceleratedSurface *screen ) { SDL_Rect r; r.x = 230 - activeChoiceSprite->w - 8; r.w = activeChoiceSprite->w; @@ -267,7 +267,7 @@ void Settings::showMenu( SDL_Surface *screen ) { } else fontMenu->drawStr( screen, 230, 400, "Finish" ); } -void Settings::settingsDialog( SDL_Surface *screen ) { +void Settings::settingsDialog( SdlCompat_AcceleratedSurface *screen ) { bool run = true; actChoice = SC_FINISH; wasLeftColumn = true; diff --git a/alienblaster/project/jni/application/src/settings.h b/alienblaster/project/jni/application/src/settings.h index efa8c19f4..2c0d9e35c 100644 --- a/alienblaster/project/jni/application/src/settings.h +++ b/alienblaster/project/jni/application/src/settings.h @@ -24,6 +24,8 @@ #include #include #include "SDL.h" +#include "SdlForwardCompat.h" + class Font; class Options; @@ -60,15 +62,15 @@ class Settings { Settings(); ~Settings(); - void settingsDialog(SDL_Surface *screen); + void settingsDialog(SdlCompat_AcceleratedSurface *screen); const PlayerKeys getPlayerKeys(unsigned int player) const; private: - SDL_Surface *introSprite; - SDL_Surface *activeChoiceSprite; - SDL_Surface *bluePlain; - SDL_Surface *whitePlain; + SdlCompat_AcceleratedSurface *introSprite; + SdlCompat_AcceleratedSurface *activeChoiceSprite; + SdlCompat_AcceleratedSurface *bluePlain; + SdlCompat_AcceleratedSurface *whitePlain; SettingsChoices actChoice; bool wasLeftColumn; Options *opfile; @@ -85,11 +87,11 @@ class Settings { void loadDefaultSettings(); void loadSettings(); void saveSettings(); - void draw( SDL_Surface *screen, bool getNewKey=false ); - void showSpecialKeys( SDL_Surface *screen ); - void showSettings( SDL_Surface *screen, bool getNewKey ); - void showMenu( SDL_Surface *screen ); - void changeCurrentSettings(SDL_Surface *screen, int player); + void draw( SdlCompat_AcceleratedSurface *screen, bool getNewKey=false ); + void showSpecialKeys( SdlCompat_AcceleratedSurface *screen ); + void showSettings( SdlCompat_AcceleratedSurface *screen, bool getNewKey ); + void showMenu( SdlCompat_AcceleratedSurface *screen ); + void changeCurrentSettings(SdlCompat_AcceleratedSurface *screen, int player); void setKeyNames(); }; diff --git a/alienblaster/project/jni/application/src/shieldGlow.cpp b/alienblaster/project/jni/application/src/shieldGlow.cpp index fda735c09..7b55280d6 100644 --- a/alienblaster/project/jni/application/src/shieldGlow.cpp +++ b/alienblaster/project/jni/application/src/shieldGlow.cpp @@ -42,7 +42,7 @@ ShieldGlow::ShieldGlow( ShipTypes shipType ) { ShieldGlow::~ShieldGlow() {} -void ShieldGlow::draw( SDL_Surface *screen, Vector2D pos, int time ) { +void ShieldGlow::draw( SdlCompat_AcceleratedSurface *screen, Vector2D pos, int time ) { if ( time < 0 || RACER_SHIELD_DAMAGE_LIFETIME < time ) return; int actFrame = time / timePerFrame; diff --git a/alienblaster/project/jni/application/src/shieldGlow.h b/alienblaster/project/jni/application/src/shieldGlow.h index 9664c2884..cbe8ae57a 100644 --- a/alienblaster/project/jni/application/src/shieldGlow.h +++ b/alienblaster/project/jni/application/src/shieldGlow.h @@ -25,7 +25,7 @@ #include "global.h" class ShieldGlow { - SDL_Surface *spriteShieldGlow; + SdlCompat_AcceleratedSurface *spriteShieldGlow; int nrFrames; int frameWidth; int halfFrameWidth; @@ -36,7 +36,7 @@ class ShieldGlow { ShieldGlow( ShipTypes shipType ); ~ShieldGlow(); - void draw( SDL_Surface *screen, Vector2D drawPos, int time ); + void draw( SdlCompat_AcceleratedSurface *screen, Vector2D drawPos, int time ); }; diff --git a/alienblaster/project/jni/application/src/shot.cpp b/alienblaster/project/jni/application/src/shot.cpp index db0e3fc52..488d85084 100644 --- a/alienblaster/project/jni/application/src/shot.cpp +++ b/alienblaster/project/jni/application/src/shot.cpp @@ -642,7 +642,7 @@ void Shot::addExplosion() { //////////////////// -void Shot::drawShadow(SDL_Surface *screen) { +void Shot::drawShadow(SdlCompat_AcceleratedSurface *screen) { switch (shotType) { case SHOT_KICK_ASS_ROCKET: case SHOT_HF_KICK_ASS_ROCKET: @@ -680,7 +680,7 @@ void Shot::drawShadow(SDL_Surface *screen) { } } -void Shot::drawGroundShot(SDL_Surface *screen) { +void Shot::drawGroundShot(SdlCompat_AcceleratedSurface *screen) { switch (shotType) { case SHOT_KICK_ASS_ROCKET: case SHOT_HF_KICK_ASS_ROCKET: @@ -704,7 +704,7 @@ void Shot::drawGroundShot(SDL_Surface *screen) { } } -void Shot::drawGroundAirShot(SDL_Surface *screen) { +void Shot::drawGroundAirShot(SdlCompat_AcceleratedSurface *screen) { switch (shotType) { case SHOT_DUMBFIRE: case SHOT_DUMBFIRE_DOUBLE: @@ -798,7 +798,7 @@ void Shot::drawGroundAirShot(SDL_Surface *screen) { } } -void Shot::drawAirShot(SDL_Surface *screen) { +void Shot::drawAirShot(SdlCompat_AcceleratedSurface *screen) { switch (shotType) { case SHOT_NORMAL: case SHOT_NORMAL_HEAVY: diff --git a/alienblaster/project/jni/application/src/shot.h b/alienblaster/project/jni/application/src/shot.h index 8175caa4d..26ae0a108 100644 --- a/alienblaster/project/jni/application/src/shot.h +++ b/alienblaster/project/jni/application/src/shot.h @@ -36,8 +36,8 @@ class Shot { int fromWhichPlayer; ShotTypes shotType; - SDL_Surface *sprite; - SDL_Surface *spriteShadow; + SdlCompat_AcceleratedSurface *sprite; + SdlCompat_AcceleratedSurface *spriteShadow; bool collidedWithGround; // defaultValue = false @@ -55,10 +55,10 @@ class Shot { // and makes a neat explosion void moveAndCollide( int dT ); // draws the shot - void drawShadow(SDL_Surface *screen); - void drawGroundShot(SDL_Surface *screen); - void drawAirShot(SDL_Surface *screen); - void drawGroundAirShot(SDL_Surface *screen); + void drawShadow(SdlCompat_AcceleratedSurface *screen); + void drawGroundShot(SdlCompat_AcceleratedSurface *screen); + void drawAirShot(SdlCompat_AcceleratedSurface *screen); + void drawGroundAirShot(SdlCompat_AcceleratedSurface *screen); bool isExpired() { return (timeToLive <= 0); } Vector2D getPos() { return pos; } diff --git a/alienblaster/project/jni/application/src/shots.cpp b/alienblaster/project/jni/application/src/shots.cpp index 18e145cb2..f59c1bf04 100644 --- a/alienblaster/project/jni/application/src/shots.cpp +++ b/alienblaster/project/jni/application/src/shots.cpp @@ -67,28 +67,28 @@ void Shots::expireShots() { } } -void Shots::drawShadows(SDL_Surface *screen) { +void Shots::drawShadows(SdlCompat_AcceleratedSurface *screen) { vector::iterator i; for (i = shots.begin(); i != shots.end(); ++i) { (*i)->drawShadow(screen); } } -void Shots::drawGroundShots(SDL_Surface *screen) { +void Shots::drawGroundShots(SdlCompat_AcceleratedSurface *screen) { vector::iterator i; for (i = shots.begin(); i != shots.end(); ++i) { (*i)->drawGroundShot(screen); } } -void Shots::drawAirShots(SDL_Surface *screen) { +void Shots::drawAirShots(SdlCompat_AcceleratedSurface *screen) { vector::iterator i; for (i = shots.begin(); i != shots.end(); ++i) { (*i)->drawAirShot(screen); } } -void Shots::drawGroundAirShots(SDL_Surface *screen) { +void Shots::drawGroundAirShots(SdlCompat_AcceleratedSurface *screen) { vector::iterator i; for (i = shots.begin(); i != shots.end(); ++i) { (*i)->drawGroundAirShot(screen); diff --git a/alienblaster/project/jni/application/src/shots.h b/alienblaster/project/jni/application/src/shots.h index d8005da95..53b21b9cf 100644 --- a/alienblaster/project/jni/application/src/shots.h +++ b/alienblaster/project/jni/application/src/shots.h @@ -23,6 +23,7 @@ #include #include "SDL.h" #include "geometry.h" +#include "SdlForwardCompat.h" class Shot; @@ -45,10 +46,10 @@ class Shots { void moveAndCollide( int dT ); // draw the shots - void drawShadows(SDL_Surface *screen); - void drawAirShots(SDL_Surface *screen); - void drawGroundShots(SDL_Surface *screen); - void drawGroundAirShots(SDL_Surface *screen); + void drawShadows(SdlCompat_AcceleratedSurface *screen); + void drawAirShots(SdlCompat_AcceleratedSurface *screen); + void drawGroundShots(SdlCompat_AcceleratedSurface *screen); + void drawGroundAirShots(SdlCompat_AcceleratedSurface *screen); Shot* getNearestRocket(Vector2D position); bool existsRocket(); diff --git a/alienblaster/project/jni/application/src/smokePuff.cpp b/alienblaster/project/jni/application/src/smokePuff.cpp index 56fea60e5..978274d0a 100644 --- a/alienblaster/project/jni/application/src/smokePuff.cpp +++ b/alienblaster/project/jni/application/src/smokePuff.cpp @@ -52,7 +52,7 @@ void SmokePuff::update( int dT ) { } } -void SmokePuff::drawSmokePuff( SDL_Surface *screen ) { +void SmokePuff::drawSmokePuff( SdlCompat_AcceleratedSurface *screen ) { if (expired) return; SDL_Rect dest; diff --git a/alienblaster/project/jni/application/src/smokePuff.h b/alienblaster/project/jni/application/src/smokePuff.h index d5395cebb..381f9527b 100644 --- a/alienblaster/project/jni/application/src/smokePuff.h +++ b/alienblaster/project/jni/application/src/smokePuff.h @@ -29,7 +29,7 @@ class SmokePuff { // a sprite, that contains horizontally all animationframes of the smokePuff. // it is assumed, that every frame is quadratic. - SDL_Surface *sprite; + SdlCompat_AcceleratedSurface *sprite; // how many frames does this explosion have? int nrAnimStages; @@ -54,7 +54,7 @@ class SmokePuff { ~SmokePuff(); // updates the position and the counters void update( int dT ); - void drawSmokePuff(SDL_Surface *screen); + void drawSmokePuff(SdlCompat_AcceleratedSurface *screen); bool isExpired() { return expired; } }; diff --git a/alienblaster/project/jni/application/src/smokePuffs.cpp b/alienblaster/project/jni/application/src/smokePuffs.cpp index 2f40fedaf..2f8717ecb 100644 --- a/alienblaster/project/jni/application/src/smokePuffs.cpp +++ b/alienblaster/project/jni/application/src/smokePuffs.cpp @@ -61,7 +61,7 @@ void SmokePuffs::update( int dT ) { } } -void SmokePuffs::draw(SDL_Surface *screen) { +void SmokePuffs::draw(SdlCompat_AcceleratedSurface *screen) { vector::iterator i; for (i = smokePuffs.begin(); i != smokePuffs.end(); ++i) { (*i)->drawSmokePuff( screen ); diff --git a/alienblaster/project/jni/application/src/smokePuffs.h b/alienblaster/project/jni/application/src/smokePuffs.h index c9a4cdf46..2939739f0 100644 --- a/alienblaster/project/jni/application/src/smokePuffs.h +++ b/alienblaster/project/jni/application/src/smokePuffs.h @@ -37,7 +37,7 @@ class SmokePuffs { void addSmokePuff( Vector2D pos, Vector2D vel, SmokePuffTypes whichType ); void expireSmokePuffs(); void update( int dT ); - void draw(SDL_Surface *screen); + void draw(SdlCompat_AcceleratedSurface *screen); unsigned int getNrSmokePuffs() { return smokePuffs.size(); } }; diff --git a/alienblaster/project/jni/application/src/sonic.cpp b/alienblaster/project/jni/application/src/sonic.cpp index 7a88db4b9..1ca67fd6b 100644 --- a/alienblaster/project/jni/application/src/sonic.cpp +++ b/alienblaster/project/jni/application/src/sonic.cpp @@ -40,12 +40,12 @@ void Sonic::setPos( Vector2D pos1, Vector2D pos2 ) { active = true; } -void Sonic::drawAtPos( SDL_Surface *screen, Vector2D pos1, Vector2D pos2 ) { +void Sonic::drawAtPos( SdlCompat_AcceleratedSurface *screen, Vector2D pos1, Vector2D pos2 ) { setPos( pos1, pos2 ); draw( screen ); } -void Sonic::draw( SDL_Surface *screen ) { +void Sonic::draw( SdlCompat_AcceleratedSurface *screen ) { if ( !active ) return; timeStage += 2; timeStage = (timeStage % (int)(waveLength + 0.5f)) + 1; diff --git a/alienblaster/project/jni/application/src/sonic.h b/alienblaster/project/jni/application/src/sonic.h index 97b2531dd..b038c3e53 100644 --- a/alienblaster/project/jni/application/src/sonic.h +++ b/alienblaster/project/jni/application/src/sonic.h @@ -22,6 +22,8 @@ #include #include "geometry.h" +#include "SdlForwardCompat.h" + class Sonic { public: @@ -30,13 +32,13 @@ class Sonic { void setActive( bool newActivation ) { active = newActivation; }; void setWaveLength( float wvLength ) { waveLength = wvLength; }; void setPos( Vector2D pos1, Vector2D pos2 ); - void drawAtPos( SDL_Surface *screen, Vector2D pos1, Vector2D pos2 ); - void draw( SDL_Surface *screen ); + void drawAtPos( SdlCompat_AcceleratedSurface *screen, Vector2D pos1, Vector2D pos2 ); + void draw( SdlCompat_AcceleratedSurface *screen ); private: - SDL_Surface *sonicBall; + SdlCompat_AcceleratedSurface *sonicBall; bool active; Vector2D pos1; Vector2D pos2; diff --git a/alienblaster/project/jni/application/src/surfaceDB.cpp b/alienblaster/project/jni/application/src/surfaceDB.cpp index 8f8650a48..f96840b43 100644 --- a/alienblaster/project/jni/application/src/surfaceDB.cpp +++ b/alienblaster/project/jni/application/src/surfaceDB.cpp @@ -45,9 +45,9 @@ SurfaceDB::~SurfaceDB() { } } -SDL_Surface *SurfaceDB::loadSurface( string fn, bool alpha ) { +SdlCompat_AcceleratedSurface *SurfaceDB::loadSurface( string fn, bool alpha ) { - SDL_Surface *searchResult = getSurface( fn ); + SdlCompat_AcceleratedSurface *searchResult = getSurface( fn ); if ( searchResult ) { return searchResult; } @@ -103,11 +103,12 @@ SDL_Surface *SurfaceDB::loadSurface( string fn, bool alpha ) { SDL_MapRGB(newSurface->format, transR, transG, transB) ); } - surfaceDB[ fn ] = newSurface; - return newSurface; + surfaceDB[ fn ] = SdlCompat_CreateAcceleratedSurface( newSurface ); + SDL_FreeSurface(newSurface); + return surfaceDB[ fn ]; } -SDL_Surface *SurfaceDB::getSurface( string fn ) { +SdlCompat_AcceleratedSurface *SurfaceDB::getSurface( string fn ) { if ( surfaceDB.empty() ) { return 0; } else { diff --git a/alienblaster/project/jni/application/src/surfaceDB.h b/alienblaster/project/jni/application/src/surfaceDB.h index 59362b6e4..435f782e7 100644 --- a/alienblaster/project/jni/application/src/surfaceDB.h +++ b/alienblaster/project/jni/application/src/surfaceDB.h @@ -22,12 +22,13 @@ #include "SDL.h" +#include "SdlForwardCompat.h" #include #include #include -typedef std::map > StringSurfaceMap; +typedef std::map > StringSurfaceMap; class SurfaceDB; @@ -48,13 +49,13 @@ class SurfaceDB { Uint8 transparentB=255 ); ~SurfaceDB(); - SDL_Surface *loadSurface( std::string fn, bool alpha=false ); + SdlCompat_AcceleratedSurface *loadSurface( std::string fn, bool alpha=false ); private: StringSurfaceMap surfaceDB; Uint8 transR, transG, transB; - SDL_Surface *getSurface( std::string fn ); + SdlCompat_AcceleratedSurface *getSurface( std::string fn ); }; diff --git a/alienblaster/project/jni/application/src/video.cpp b/alienblaster/project/jni/application/src/video.cpp index d4b143551..5c57e82ef 100644 --- a/alienblaster/project/jni/application/src/video.cpp +++ b/alienblaster/project/jni/application/src/video.cpp @@ -35,7 +35,7 @@ Video::~Video(){ // kill something } -SDL_Surface *Video::init(){ +SdlCompat_AcceleratedSurface *Video::init(){ // -------------------------------------------------- // SDL initialisation // ----------------------------------------------------- @@ -47,12 +47,18 @@ SDL_Surface *Video::init(){ __android_log_print(ANDROID_LOG_ERROR, "Alien Blaster", "Couldn't initialize SDL video subsystem: %s\n", SDL_GetError()); exit(1); } - screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, BIT_DEPTH, SDL_DOUBLEBUF /* | SDL_FULLSCREEN */ ); - if (!screen) { + SDL_Surface * screen2 = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, BIT_DEPTH, SDL_DOUBLEBUF /* | SDL_FULLSCREEN */ ); + 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); } + // 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); + SDL_FreeSurface(screen3); SDL_WM_SetCaption("AlienBlaster", "AlienBlaster"); SDL_WM_SetIcon(SDL_LoadBMP( FN_ALIENBLASTER_ICON.c_str() ), NULL); @@ -74,10 +80,13 @@ void Video::clearScreen() { } void Video::toggleFullscreen() { + // TODO: fix that? + /* if ( fullscreen ) { screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, BIT_DEPTH, SDL_DOUBLEBUF ); } else { screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, BIT_DEPTH, SDL_DOUBLEBUF | SDL_FULLSCREEN ); } + */ fullscreen = !fullscreen; } diff --git a/alienblaster/project/jni/application/src/video.h b/alienblaster/project/jni/application/src/video.h index 126913829..f7577aee1 100644 --- a/alienblaster/project/jni/application/src/video.h +++ b/alienblaster/project/jni/application/src/video.h @@ -21,6 +21,8 @@ #define VIDEO_H #include "SDL.h" +#include "SdlForwardCompat.h" + class Video; @@ -29,12 +31,12 @@ extern Video *videoserver; class Video { private: - SDL_Surface *screen; + SdlCompat_AcceleratedSurface *screen; public: Video(); ~Video(); - SDL_Surface *init(); + SdlCompat_AcceleratedSurface *init(); bool fullscreen; diff --git a/alienblaster/project/jni/application/src/wreck.cpp b/alienblaster/project/jni/application/src/wreck.cpp index 8d9ba462e..475daeecd 100644 --- a/alienblaster/project/jni/application/src/wreck.cpp +++ b/alienblaster/project/jni/application/src/wreck.cpp @@ -94,7 +94,7 @@ void Wreck::update( int dT ) { } -void Wreck::draw(SDL_Surface *screen) { +void Wreck::draw(SdlCompat_AcceleratedSurface *screen) { SDL_Rect r; r.x = lroundf(pos.getX()) - sprite->w / 2; r.y = lroundf(pos.getY()) - sprite->h / 2; diff --git a/alienblaster/project/jni/application/src/wreck.h b/alienblaster/project/jni/application/src/wreck.h index 8f4d4752e..08947154b 100644 --- a/alienblaster/project/jni/application/src/wreck.h +++ b/alienblaster/project/jni/application/src/wreck.h @@ -26,7 +26,7 @@ #include "global.h" class Wreck { - SDL_Surface *sprite; + SdlCompat_AcceleratedSurface *sprite; Vector2D pos; Vector2D vel; @@ -36,7 +36,7 @@ class Wreck { Wreck( Vector2D position, WreckTypes wreckType ); ~Wreck(); void update( int dT ); - void draw(SDL_Surface *screen); + void draw(SdlCompat_AcceleratedSurface *screen); bool isExpired(); void deleteWreck(); diff --git a/alienblaster/project/jni/application/src/wrecks.cpp b/alienblaster/project/jni/application/src/wrecks.cpp index e67c3bc6f..776743648 100644 --- a/alienblaster/project/jni/application/src/wrecks.cpp +++ b/alienblaster/project/jni/application/src/wrecks.cpp @@ -55,7 +55,7 @@ void Wrecks::updateWrecks( int dT ) { } } -void Wrecks::draw(SDL_Surface *screen) { +void Wrecks::draw(SdlCompat_AcceleratedSurface *screen) { vector::iterator i; for (i = wrecks.begin(); i != wrecks.end(); ++i) { (*i)->draw(screen); diff --git a/alienblaster/project/jni/application/src/wrecks.h b/alienblaster/project/jni/application/src/wrecks.h index 30f1a1197..b5aa20065 100644 --- a/alienblaster/project/jni/application/src/wrecks.h +++ b/alienblaster/project/jni/application/src/wrecks.h @@ -22,6 +22,7 @@ #include "SDL.h" #include +#include "SdlForwardCompat.h" class Wreck; @@ -35,7 +36,7 @@ class Wrecks { void addWreck(Wreck *wreck); void expireWrecks(); void updateWrecks( int dT ); - void draw(SDL_Surface *screen); + void draw(SdlCompat_AcceleratedSurface *screen); void deleteAllWrecks(); unsigned int getNrWrecks() { return wrecks.size(); } diff --git a/alienblaster/project/jni/sdl/src/video/SDL_video.c b/alienblaster/project/jni/sdl/src/video/SDL_video.c index 2328b67d4..39ccd7b29 100644 --- a/alienblaster/project/jni/sdl/src/video/SDL_video.c +++ b/alienblaster/project/jni/sdl/src/video/SDL_video.c @@ -1732,10 +1732,12 @@ SDL_CreateTextureFromSurface(Uint32 format, SDL_Surface * surface) SDL_PIXELFORMAT_BGR565, SDL_PIXELFORMAT_ARGB1555, SDL_PIXELFORMAT_ABGR1555, + SDL_PIXELFORMAT_RGBA5551, SDL_PIXELFORMAT_RGB555, SDL_PIXELFORMAT_BGR555, SDL_PIXELFORMAT_ARGB4444, SDL_PIXELFORMAT_ABGR4444, + SDL_PIXELFORMAT_RGBA4444, SDL_PIXELFORMAT_RGB444, SDL_PIXELFORMAT_ARGB2101010, SDL_PIXELFORMAT_INDEX8, @@ -1820,8 +1822,10 @@ SDL_CreateTextureFromSurface(Uint32 format, SDL_Surface * surface) SDL_PIXELFORMAT_BGRA8888, SDL_PIXELFORMAT_ARGB1555, SDL_PIXELFORMAT_ABGR1555, + SDL_PIXELFORMAT_RGBA5551, SDL_PIXELFORMAT_ARGB4444, SDL_PIXELFORMAT_ABGR4444, + SDL_PIXELFORMAT_RGBA4444, SDL_PIXELFORMAT_ARGB2101010, SDL_PIXELFORMAT_UNKNOWN }; diff --git a/alienblaster110_data.zip b/alienblaster110_data.zip index 81c75eabe0f4e76094201c43e5ff5d986e5a1448..3d46e9171cfc75db60c5a2f68bdb37c871212f99 100644 GIT binary patch delta 22536 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 HFfafB`ub}` delta 16388 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

R5#zKc-&tWc`z zB?YYBE~BZIKYhVY^)s<8_t+Mltp57DKCHO%-+Wh>wDL|)iJ$wOKIhl*HWw!Q%^rEE}Z<~^}+)gm;IW2BYvn{ z*njd&JmbE&rgv*CV^37+eY3c9pI1bueMM1I{3`434wq%OAN(?V^@=%WZ4cXY>)FpF zcT7%uFYqdH%ksnL#q&e5#J5ghe=;e&>@=IUK1%g^P?8oTG)+&_5mcf(2ECmi=KZ=U>V+UlpOOYAHxb{K!Cz3lo! zKK9A)i-pYdA5Wb=QGmN<`zC48XEO3jD%)yn*%%l=7=6yf(4=Vc|9lgEBI=PHuzDo7 z@2&#RmoQuA@AmWcFaFE;I)(RJg#n*_<>?hssfs_ilY2V1#n(US&&jD#o7K^g@xA7i z?5kThZrs?xd8^M)+WE&V%lpTUnRo>qW|>%45%%cp1dAI^-`;IXeDt*C)t2t3mh-F| z0~c=JUY{ZIBD9|4Me2%Ht@8^kw@tN->kUh6Z#6$uTw$WTKXaGRTGdAG1+uHu?oHSi zzE3=J&qmwDac`dWCvCah$1QL^@LX)5J9ud1BIJGkS!?ARYj>}EC91Hpu zwi$S(Xxy6Saf4gIz+L3WA?J^GeEGuH@4dGnV%^2fKUb^QD>}#gdBXf&WX4?cB|n`# zz8dybUklL5YM*~9P+9+LIoC*z@bcRBj=I;zi89Gw1NXS@VY}p>2h{l*9Dt z3o=|}^n3Pw_gJW|SKw(77HV~j(YWeu=gCh#7j>GrDm9-ka5z5UU*P%)P3Ei%pW4e= zU26U8Q4n>zf*Z7au^zsD5&QB*KhW|;Mz!aY4^y^$@gY z<+^P)^76%tJrnRPUpzx_`JzQBX!+vYH6QCA-Ig~#;JQTI=W5kinM2`6W~O(Bu_!N0 zvHh8{=+@PCeJl6=vU@86oAyc?9{1$t*pge}$*K|~pk=!(@l%xa$=l!OpFgWyol>H> z|M_R7DFxgMTx>mcmwbAo zy?$fZjd?Y%p+VhMxsD?PU_*8Pm+8aAmYM#8fy7_GP-9s!Kv-xhb|IU3_>z6zC z{mzZ=><`U3@3UQeMX&k4i;CeL(-T^PPhOlcJD~W*zGq4XjX5HppO+RX?D)F-MA-M^ zzqGzeEsfg|V%=N6r~KK2Bgq?+uXEK4{n&PIM)!@y^7p>(bGavR<(95{*UHw$4lcSim2Rx~6AaPrMENb7oq*)}=PyZ3(fnuHL(U zxbK{xT7~SoxVDE&W=!*sPX6cnnQ4V%{GsskuXeE8?Rv6rGUNQeo%8kTLG=T>?H^&Q z%Dq=Iv-Lfz_r}FUO}l>k``Ot`;(6CSy5kz4>-f^9hU-VZ(dYRL`=t&Rbhb_SzSH8- zmydpHIO^)}x6J$r|+ z>Ey=~J~%in^HyS);EmtWt&)-D-j^llSf}`W1*5@r@fm7mhc3RJIEQEPm30g&K3A?5 zDo>1SWqH1~WZ8!Q@_px?iNWQR7z>C1x^9hfKYW1JqJp(r~2f3Tt_(~gtVy+Ra2neLsMzA!{Fk@@#o z#_8`4Gs=L}DnX2rILe4>waIyqTG8p&M;V2u&n;Gz0lRSe%=?Ud)Axre@-S_EIsI&? zVl4C9SB%piJYbZV&Yp+jxa=@RDW(-~rniSFMl#2KXPh4JmQiZ@-!Mf7=6RV+(FdK4-I$(~PyZgSn8CETW_n_TVk}ch-Sh(yiqT9h_0we| z6(g9hO<Fc8ueVC-zO#d6D z7|pD=mT9`;VkXJycZ(F2rcaAjlw%6rFnwFJVkFOg7H-&jiIVC5QHt8r-C`8wn40;g zr^P77F&`J;p1zBXTMFb-aL98_XOC5sV%C)Ao-QNEtqF<|wdutmp?Qkj(E`rTv5JvQ|8GrqjZ+L`(tI?1Zk(d!bWk!eWP)#$U|k~++H}i!MJeVDQ+TI8Xy%oeo)@p^z_e%T^bPTf ziA?R&r!P!Y6rO&vjaL}tOtAAI3C9qzDi_@WJLaM~z{mjN0LDB;o$2ujic(BFmQSxv zP>f(YwE|*3Pam%&$b7Zw>WPX{%-7cPPX6dDIz2K`(T%D9G)PSj)2|ED`I8i*nGRi= zo|B{)&-CNU^s`Bdp-ia{r>i6@#xUnT0cjGMK0R5{omq~FZ~8-!=oVhS=?*E1@yzr1 z`KF)y!YeU-SBjzo(@MYTe^M0VnAiiR$D}GoGZm*z-4j;E z@yzFr@J;`>l238^?kGjI=~C&6Qq26v_@>*h<`bXpm#*l*wB-2o3F(UYOt;QXXUtHH zX8PhkJuX8rf$8V_=?5|t6PWY93r?SRM^IwAb*7>N^Cfnn$se6Xrl*uDs)M2t5|q;q zXDUiDtx=kOKT|Q1>Ac!>t1QJ}<`v2!pd>9a{SAi*&-4vhiVjRi)uw;SQVeH$sx{p^ zTQQV*r=iI7mtrCc=-K9FHmGDUp3a)17|yI_BQpJz)8FSPIxva)PB+X|jAaV)n?4~|(G=lAebnVa$f@mahzLq*gDe&TNA>w!MJZw|=@@ zzG5U(bi?$@e8m_htETDK^A&TL?sZIeEl><+`r9>qUV&mL)1^t%zZNKlF`Ld7na-ah zA_fXIwdq}jic-v<=7>x`lPe-IeSe{%0~6!C>5N5+k<2%DLTo$UCBi?wp-9nz+3~u_ zbmfvM-lbopY%5N6g}5OrO}iowjvETYpN6f1@@i}H(3e}7*@ae8Elq670b zQPJshN)&^ccZ-Qm|5TzF%`7S*3W?v8Qblj(dU?_5ksm~)r=KlVbYQMf6rC@4oS)qjBb1%{95B?}ffHJ!hIJl=XmMcmzKMWKF zB?6`C4&|V96f?c4TrrO6N9y!P<%&+aOHev8$gz7oPZT9~4NZ!s8zv~KK#ZPYA&Oey zPcEJAP@$O4bf9Yb$_m9;rb#u^IVu&snVP3h53N-6Vmds1`oc=ZXr@`OrvIx{jAp*6 zAU6H&V^N9el2wXI(?3)zvP_>m0}1}THth^YQ=D-($?vz)r!GP75k^} ss#XkPI=W@LK#gK3lf~KT={1VlBCKqn%C4KCn}NfafuYq*k%55$02Q`4e*gdg