gameapp.cpp
来自「一个symbian 冒险游戏代码」· C++ 代码 · 共 1,186 行 · 第 1/3 页
CPP
1,186 行
#include "GameApp.h"
#include "Surface.h"
#include "dprintf.h"
#include "MapConverter.h"
#include "SoundContext.h"
#include <math.h>
#include <io/FileInputStream.h>
#include <io/FileOutputStream.h>
#include <lang/String.h>
#include <lang/Profile.h>
#include <lang/algorithm/quicksort.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
//#define TEST_HEAP_SIZE
#ifdef WIN32_CONVERT
#include <io.h>
#endif
#ifdef WIN32_EXTRA_CHECKS
#include <crtdbg.h>
#endif
#include <config.h>
#define VER "Beta Build v3"
#ifdef WIN32_CONVERT
using namespace lua;
#endif
using namespace io;
using namespace lang;
App* init()
{
dprintf( "App* init()\n" );
return new GameApp;
}
void sorttest( int* a, int size )
{
quicksort( a, a+size );
for ( int i = 0 ; i < size-1 ; ++i )
{
assert( a[i] <= a[i+1] );
}
}
void sorttest()
{
int a1[] = {3,2,1,2,3,1};
int a2[] = {1,2,3,4};
int a3[] = {1,2,3,4,5};
int a4[] = {6,1,2,3,4};
int a5[] = {6,1,2,3,4,5};
int a6[] = {1,2,3,4,0};
int a7[] = {1,2,3,4,5,0};
sorttest( a1, sizeof(a1)/sizeof(int) );
sorttest( a2, sizeof(a2)/sizeof(int) );
sorttest( a3, sizeof(a3)/sizeof(int) );
sorttest( a4, sizeof(a4)/sizeof(int) );
sorttest( a5, sizeof(a5)/sizeof(int) );
sorttest( a6, sizeof(a6)/sizeof(int) );
sorttest( a7, sizeof(a7)/sizeof(int) );
}
void memtest()
{
int allocated = 0;
char* a[256];
for ( int i = 0 ; i < 10000 ; ++i )
{
int size = 100*1024;
char* x = new char[size];
a[i&0xFF] = x;
if ( x == 0 )
{
dprintf( "char* x = new char[%d]; // returned 0\n", size );
break;
}
allocated += size;
dprintf( "allocated %dkB\n", allocated>>10 );
}
dprintf( "TOTAL allocated %dkB\n", allocated>>10 );
}
GameApp::GameApp() :
m_soundContext( 0 ),
m_map( 0 ),
m_mapCachePtr( 0 ),
m_triggerText( 0 ),
m_triggerTextTime( Fix(0) ),
m_triggerTextPos( Fix(0), Fix(0) ),
m_screen( 0 ),
m_screenTrigger( 0 ),
m_healthBarScalingFactor( Fix(0) ),
m_loadingProgress( Fix(0) ),
m_quitPhase( QUIT_NONE ),
m_initPhase( INIT_NONE ),
m_restartPhase( RESTART_NONE ),
m_resetTime( true ),
m_initDone( false ),
m_restarting( false ),
m_halfResolution( true ),
m_gameFinished( false )
{
dprintf( "GameApp::GameApp\n" );
//sorttest();
//memtest();
const char* startMap = "forest";
strcpy( m_name, "Into The Darkness " );
strcat( m_name, VER );
#ifdef DEBUG_INFO
strcat( m_name, " (debug info)" );
#endif
#ifdef WIN32_CONVERT
strcat( m_name, " (map converter active)" );
#endif
m_debugPrint[0] = 0;
strcpy( m_loadingText, "Loading" );
String::cpy( m_startMap, sizeof(m_startMap), startMap );
}
GameApp::~GameApp()
{
dprintf( "GameApp::~GameApp\n" );
m_imageResamplingEngine.deinit();
// dump memory usage
#ifdef WIN32_EXTRA_CHECKS
_CrtMemState s;
_CrtMemCheckpoint( &s );
_CrtMemDumpStatistics( &s );
#endif
for ( int i = 0 ; i < MAX_SPRITES ; ++i )
sprites[i].destroy();
for ( int i = 0 ; i < MAX_SCREENS ; ++i )
screens[i].destroy();
Player::deinitStatic();
Enemy::deinitStatic();
}
void GameApp::playSound( const char* basename, int channel )
{
assert( basename != 0 );
m_soundContext->playSound( basename, channel );
}
void GameApp::init( Context*, SoundContext* soundcontext )
{
dprintf( "GameApp::init\n" );
String::cpy( m_debugPrint, sizeof(m_debugPrint), "Init Launched" );
m_initPhase = INIT_START;
m_initDone = false;
m_soundContext = soundcontext;
}
bool GameApp::init( Context* context )
{
#ifdef TEST_HEAP_SIZE
char* x[100];
int bytes = 0;
int n = 0;
for ( ;; ++n )
{
int xbytes = 1024*10;
char* p = new char[xbytes];
assert( p != 0 );
x[n%100] = p;
bytes += xbytes;
dprintf( "%d kB allocated ok\n", bytes>>10 );
}
#endif
if ( m_initDone || ( m_initPhase == INIT_NONE ) ) return true;
m_initDone = false;
int nextPhase = -1;
switch ( m_initPhase )
{
// start
case INIT_START:
TRACE();
dprintf( "GameApp::init, start\n" );
String::cpy( m_debugPrint, sizeof(m_debugPrint), "Init/Start Ok" );
m_imageResamplingEngine.init( RESAMPLE_BUFFER_SIZE );
m_halfResolution = ( ( context->width() * context->height() ) < HALF_RESOLUTION_THRESHOLD );
nextPhase = INIT_START_REFRESH;
TRACE();
break;
// refresh
case INIT_START_REFRESH:
nextPhase = INIT_FONT;
break;
// font
case INIT_FONT:
TRACE();
dprintf( "GameApp::init, font\n" );
String::cpy( m_debugPrint, sizeof(m_debugPrint), "Init/Font Ok" );
if ( !m_halfResolution )
{
// full resolution font
mainFont.load( expandPath("data/fonts/mainfont_11x14.nan"), 11, 14 );
}
else
{
// half resolution font
mainFont.load( expandPath("data/fonts/mainfont_11x14.nan"), 11, 14 );
}
nextPhase = INIT_PLAYER;
TRACE();
break;
// player
case INIT_PLAYER:
TRACE();
dprintf( "GameApp::init, player\n" );
String::cpy( m_debugPrint, sizeof(m_debugPrint), "Init/Player Ok" );
Player::initStatic();
nextPhase = INIT_ENEMIES;
TRACE();
break;
// enemies
case INIT_ENEMIES:
TRACE();
dprintf( "GameApp::init, enemies\n" );
String::cpy( m_debugPrint, sizeof(m_debugPrint), "Init/Enemies Ok" );
Enemy::initStatic();
nextPhase = INIT_SOUNDS;
TRACE();
break;
// sounds
case INIT_SOUNDS:
TRACE();
dprintf( "GameApp::init, sounds\n" );
String::cpy( m_debugPrint, sizeof(m_debugPrint), "Init/Sounds Ok" );
m_soundContext->addSample( expandPath("data/sounds/start_sound.wav") );
m_soundContext->addSample( expandPath("data/sounds/sound_in_well.wav") );
m_soundContext->addSample( expandPath("data/sounds/door_open.wav") );
m_soundContext->addSample( expandPath("data/sounds/enemy_laugh.wav") );
m_soundContext->addSample( expandPath("data/sounds/hero_attack.wav") );
m_soundContext->addSample( expandPath("data/sounds/hero_shotgun.wav") );
m_soundContext->addSample( expandPath("data/sounds/hero_get_hit.wav") );
m_soundContext->addSample( expandPath("data/sounds/hero_die.wav") );
m_soundContext->addSample( expandPath("data/sounds/enemy_combat.wav") );
m_soundContext->addSample( expandPath("data/sounds/enemy_die.wav") );
m_soundContext->addSample( expandPath("data/sounds/enemy_flee.wav") );
nextPhase = INIT_SPRITES;
TRACE();
break;
// sprites
case INIT_SPRITES:
{
TRACE();
dprintf( "GameApp::init, sprites\n" );
String::cpy( m_debugPrint, sizeof(m_debugPrint), "Init/Sprites Ok" );
int ix = 0;
spriteNames[ix] = "lever_on";
sprites[ix].loadCustom( expandPath("data/sprites/trigger/trigger_on.nan"), &m_imageResamplingEngine, m_halfResolution );
setSpriteReferencePoint( ix++, 25, 40 );
spriteNames[ix] = "lever_off";
sprites[ix].loadCustom( expandPath("data/sprites/trigger/trigger_off.nan"), &m_imageResamplingEngine, m_halfResolution );
setSpriteReferencePoint( ix++, 25, 40 );
spriteNames[ix] = "potionofhealth";
sprites[ix].loadCustom( expandPath("data/sprites/potion_of_health/potion_of_health.nan"), &m_imageResamplingEngine, m_halfResolution );
setSpriteReferencePoint( ix++, 10, 29 );
spriteNames[ix] = "key";
sprites[ix].loadCustom( expandPath("data/sprites/key/key.nan"), &m_imageResamplingEngine, m_halfResolution );
setSpriteReferencePoint( ix++, 9, 9 );
spriteNames[ix] = "shotgun";
sprites[ix].loadCustom( expandPath("data/sprites/shotgun/shotgun.nan"), &m_imageResamplingEngine, m_halfResolution );
setSpriteReferencePoint( ix++, 18, 22 );
spriteNames[ix] = "sage";
sprites[ix].loadCustom( expandPath("data/sprites/sage/sage.nan"), &m_imageResamplingEngine, m_halfResolution );
setSpriteReferencePoint( ix++, 16, 67 );
spriteNames[ix] = "adventurer";
sprites[ix].loadCustom( expandPath("data/sprites/adventurer/adventurer.nan"), &m_imageResamplingEngine, m_halfResolution );
setSpriteReferencePoint( ix++, 17, 53 );
spriteCount = ix;
nextPhase = INIT_SCREENS;
TRACE();
break;
}
// screens
case INIT_SCREENS:
{
TRACE();
dprintf( "GameApp::init, screens\n" );
String::cpy( m_debugPrint, sizeof(m_debugPrint), "Init/Screens Ok" );
int ix = 0;
screenNames[ix] = "start"; screens[ix++].loadCustom( expandPath("data/screens/start.nan"), &m_imageResamplingEngine, m_halfResolution );
screenNames[ix] = "restart"; screens[ix++].loadCustom( expandPath("data/screens/restart.nan"), &m_imageResamplingEngine, m_halfResolution );
screenNames[ix] = "quit"; screens[ix++].loadCustom( expandPath("data/screens/quit.nan"), &m_imageResamplingEngine, m_halfResolution );
screenNames[ix] = "finish"; screens[ix++].loadCustom( expandPath("data/screens/finish.nan"), &m_imageResamplingEngine, m_halfResolution );
screenNames[ix] = "gameover"; screens[ix++].loadCustom( expandPath("data/screens/gameover.nan"), &m_imageResamplingEngine, m_halfResolution );
screenNames[ix] = "something_watching"; screens[ix++].loadCustom( expandPath("data/screens/something_watching.nan"), &m_imageResamplingEngine, m_halfResolution );
screenNames[ix] = "sage_helpme"; screens[ix++].loadCustom( expandPath("data/screens/sage_helpme.nan"), &m_imageResamplingEngine, m_halfResolution );
screenNames[ix] = "sage_thanks"; screens[ix++].loadCustom( expandPath("data/screens/sage_thanks.nan"), &m_imageResamplingEngine, m_halfResolution );
screenNames[ix] = "sage_hello"; screens[ix++].loadCustom( expandPath("data/screens/sage_hello.nan"), &m_imageResamplingEngine, m_halfResolution );
screenNames[ix] = "adventurer_speaks"; screens[ix++].loadCustom( expandPath("data/screens/adventurer_speaks.nan"), &m_imageResamplingEngine, m_halfResolution );
screenNames[ix] = "demon_lair"; screens[ix++].loadCustom( expandPath("data/screens/demon_lair.nan"), &m_imageResamplingEngine, m_halfResolution );
screenCount = ix;
nextPhase = INIT_MAP;
TRACE();
break;
}
// map
case INIT_MAP:
{
TRACE();
dprintf( "GameApp::init, map\n" );
String::cpy( m_debugPrint, sizeof(m_debugPrint), "Init/Map Ok" );
#ifdef WIN32_CONVERT
dprintf( "convert()\n" );
convert();
#endif
loadMap( m_startMap );
nextPhase = INIT_FINISH;
TRACE();
break;
}
// finish
case INIT_FINISH:
{
TRACE();
dprintf( "GameApp::init, finish\n" );
FileInputStream in( expandPath("data/player.bin") );
m_player.read( &in );
m_map->setPlayerStartPosition( m_map->startBlock );
// no next phase (init done)
TRACE();
break;
}
default:
break;
}
if ( nextPhase >= INIT_START )
{
m_initPhase = nextPhase;
}
else
{
m_initPhase = INIT_NONE;
m_debugPrint[0] = 0;
m_initDone = true;
}
TRACE();
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?