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 + -
显示快捷键?