示例#1
0
void RegionLoad::RemoveActors()
{
	Actor *actor;
	GlobalMapActorIterator it(createdActors);
	for( it.Begin(); !it.Done(); it.Next() )
	{
		actor = *it.Key();

#ifdef DEBUG
	GLOUTPUT( "--- RegionLoad::RemoveActors: (%X) ",  actor);
#endif

		if(IS_VALID_ACTOR(actor))
		{
#ifdef DEBUG
			GLOUTPUT("ok");
#endif
			actor->RemoveRegionLoad(this);
		}

#ifdef DEBUG
	GLOUTPUT("\n");
#endif
	}

	createdActors.Clear();
}
示例#2
0
void MemLeakCheck()
{
	GLOUTPUT((	"MEMORY REPORT: watermark=%dk new count=%d. delete count=%d. %d allocations leaked.\n",
				memWatermark/1024, memNewCount, memDeleteCount, memNewCount-memDeleteCount ));

	for( MemCheckHead* node = root; node; node=node->next )
	{
		GLOUTPUT(( "  size=%d %s id=%d name=%s line=%d\n",
					node->size, (node->arrayType) ? "array" : "single", node->id,
					(node->name) ? node->name :  "(null)", node->line ));
	}		    

	/*
		If these fire, then a memory leak has been detected. The library doesn't track
		the source. The best way to find the source is to break in the allocator,
		search for: #BREAKHERE. Each allocation has a unique ID. Once you know the ID 
		of the thing you are leaking, you can track the source of the leak.

		It's not elegant, but it does work.
	*/
	GLASSERT( memNewCount-memDeleteCount == 0 && !root );

	// If this fires, the code isn't working or you never allocated memory:
	GLASSERT( memNewCount );
}
示例#3
0
void KrDom::ReadFrameAttributes( const TiXmlNode* node,
								 KrDom::Frame* frame )
{
	TiXmlElement* element = node->ToElement();
	
	memset( frame, 0, sizeof( Frame ) );

	if ( !element )
	{
		#ifdef DEBUG
			GLOUTPUT( "WARNING not an element in ReadFrameAttributes\n" );
			GLASSERT( 0 );
		#endif
		return;
	}

	if ( element->Value() != "Frame" )
	{
		#ifdef DEBUG
			GLOUTPUT( "WARNING not an element of type 'Frame' in ReadFrameAttributes\n" );
			GLASSERT( 0 );
		#endif
		return;
	}

	element->Attribute( "x", &frame->x );
	element->Attribute( "y", &frame->y );
	element->Attribute( "width",  &frame->width );
	element->Attribute( "height", &frame->height );

	frame->hasDelta = false;
	frame->hasHotspot = false;
	if ( element->Attribute( "hotspotx" ) && element->Attribute( "hotspoty" ) )
	{
		element->Attribute( "hotspotx", &frame->hotspotX );
		element->Attribute( "hotspoty", &frame->hotspotY );
		frame->hasHotspot = true;
	}
	if ( element->Attribute( "hotspotx" ) && element->Attribute( "hotspoty" ) )
	{
		element->Attribute( "deltax", &frame->deltaX );
		element->Attribute( "deltay", &frame->deltaY );
		frame->hasDelta = true;
	}
	if ( element->Attribute( "isotile" ) )
	{
		element->Attribute( "isotile", &frame->isotile );
	}
}
示例#4
0
KrSpriteResource::KrSpriteResource( U32 size, 
									SDL_RWops* data ) 
{
	
	gedString name;
	ReadString( data, &name );
	U32 id = SDL_ReadLE32( data );
	SetNameAndId( name, id );

	

	#ifdef DEBUG
		GLOUTPUT( "Sprite or Font resource '%s' id=%d\n", name.c_str(), id );
	#endif

	U32 nAction = SDL_ReadLE32( data );
	actionArr.SetCount( nAction );

	

	actionMap   = new GlMap< gedString, KrAction*, GlStringHash >( nAction );
	actionIdMap = new GlMap< U32, KrAction*, GlNumberHash< U32 > >( nAction );

	

	for ( U32 i=0; i<nAction; i++ )
	{
		actionArr[ i ] = new KrAction( data );

		actionMap->Add(   actionArr[i]->Name(), actionArr[i] );
		actionIdMap->Add( actionArr[i]->Id(), actionArr[i] );
	}

	
}
示例#5
0
void RegionLoad::DestroyActors()
{
	//Destroys actors that don't belong more any region
	//and not intercept view

	if(!bRegionInView) return; //Actors are not created
	bRegionInView = false;

#ifdef DEBUG
	GLOUTPUT( "Leave region: %X\n", this );
#endif


	Actor *actor;
	GlobalMapActorIterator it(createdActors);
	for( it.Begin(); !it.Done(); it.Next() )
	{
		actor = *it.Key();
		if(IS_VALID_ACTOR(actor))
		{
			actor->RemoveRegionLoad(this);
			if(actor->getRegionCount() <= 0 && actor->getRunning() && !actor->IsActorInView(true))
			{
				//Don't delete now 
				//Solve Activation Region bug in Houp/JItering/JItering9.15_2.ged 
				//(don't destroy desk1.4 after change Activation Region)

				actor->PostMessage(actor, DELETE_ME, DELETE_ME);
			}
		}
	}

	createdActors.Clear();
}
示例#6
0
void RegionLoad::CreateActors()
{
	//Create regions actor, and necessary parent actors
	if(bRegionInView) return; //Actors are already created
	bRegionInView = true;

	bCreatingActors = true;

	createdActors.Clear();

#ifdef DEBUG
	GLOUTPUT( "Enter region: %X\n", this );
#endif

	
	MapRegionActorsIterator it(regionActors);
	for( it.Begin(); !it.Done(); it.Next() )
	{
		GameControl::Get()->GetActor(*it.Key());
	}
	
	CallOnCreate();

	bCreatingActors = false;
}
示例#7
0
bool KrEncoder::EndDat()
{
	StartTag( KYRATAG_END );
	EndTag();

	SDL_RWseek( stream, numRlePos, SEEK_SET );
	GLASSERT( numRGBA >= numSegment );
	//GLASSERT( numSegment >= numLine ); //maks: Is be possible (GE_N.bmp)
	SDL_WriteLE32( stream, numRGBA );
	SDL_WriteLE32( stream, numLine );
	SDL_WriteLE32( stream, numSegment );

	#ifdef DEBUG
		GLOUTPUT( "Tally count: rgba=%d line=%d segment=%d\n", numRGBA, numLine, numSegment );
	#endif

	cachedWrite.Flush();
	return true;
}
示例#8
0
bool SharedStateData::LoadSurface( int nTrans, const KrRGBA* trans )
{
	const char* filename = SurfaceFileName().c_str();
	if ( filename && *filename )
	{
		// We are borrowing functionality from the encoder - 
		// it does all the surface loading processing 
		// that we would like to do.
		canvasResource = KrEncoder::Load32Canvas(	filename,
													trans,
													nTrans,
													0 );
		return canvasResource != 0;
	}

	#ifdef DEBUG
		GLOUTPUT( "Error in SharedStateData::LoadSurface\n" );
	#endif
	return false;
}
示例#9
0
bool Compression::Decompression(SDL_RWops* src, unsigned int lenghtComp, void *out, unsigned int lenght)
{
	if(lenghtComp < lenght)
	{
		U8 *in = new U8[lenghtComp];
		
		SDL_RWread(src, in, lenghtComp, 1);
		bool res = Decompression(in, lenghtComp, out, lenght, false);
		
#ifdef _DEBUG
		if(!res)
		{
			GLOUTPUT("*** Decompression error (%ld, %ld)\n", lenghtComp, lenght);
		}
#endif
		
		delete [] in;
		
		return res;
	}
	
	return false;
}
示例#10
0
int main( int argc, char **argv )
{    
	MemStartCheck();
	{ char* test = new char[16]; delete [] test; }

	SDL_Surface *surface = 0;

	// SDL initialization steps.
    if ( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE | SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK ) < 0 )
	{
	    fprintf( stderr, "SDL initialization failed: %s\n", SDL_GetError( ) );
		exit( 1 );
	}
	SDL_EnableKeyRepeat( 0, 0 );
	SDL_EnableUNICODE( 1 );

	const SDL_version* sversion = SDL_Linked_Version();
	GLOUTPUT(( "SDL: major %d minor %d patch %d\n", sversion->major, sversion->minor, sversion->patch ));

	SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
	SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 8);
	SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 8);
	SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 8);
	SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 8);

	if ( multisample ) {
		SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, 1 );
		SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, multisample );
	}

	int	videoFlags  = SDL_OPENGL;          /* Enable OpenGL in SDL */
		videoFlags |= SDL_GL_DOUBLEBUFFER; /* Enable double buffering */

	if ( fullscreen )
		videoFlags |= SDL_FULLSCREEN;
	else
		videoFlags |= SDL_RESIZABLE;

#ifdef TEST_ROTATION
	screenWidth  = SCREEN_WIDTH;
	screenHeight = SCREEN_HEIGHT;
#else
	screenWidth  = SCREEN_HEIGHT;
	screenHeight = SCREEN_WIDTH;
#endif

	if ( argc == 3 ) {
		screenWidth = atoi( argv[1] );
		screenHeight = atoi( argv[2] );
		if ( screenWidth <= 0 ) screenWidth = IPOD_SCREEN_WIDTH;
		if ( screenHeight <= 0 ) screenHeight = IPOD_SCREEN_HEIGHT;
	}

	// Note that our output surface is rotated from the iPod.
	//surface = SDL_SetVideoMode( IPOD_SCREEN_HEIGHT, IPOD_SCREEN_WIDTH, 32, videoFlags );
	surface = SDL_SetVideoMode( screenWidth, screenHeight, 32, videoFlags );
	GLASSERT( surface );

	int stencil = 0;
	int depth = 0;
	SDL_GL_GetAttribute( SDL_GL_STENCIL_SIZE, &stencil );
	glGetIntegerv( GL_DEPTH_BITS, &depth );
	GLOUTPUT(( "SDL surface created. w=%d h=%d bpp=%d stencil=%d depthBits=%d\n", 
				surface->w, surface->h, surface->format->BitsPerPixel, stencil, depth ));

    /* Verify there is a surface */
    if ( !surface ) {
	    fprintf( stderr,  "Video mode set failed: %s\n", SDL_GetError( ) );
	    exit( 1 );
	}

    SDL_JoystickEventState(SDL_ENABLE);
    SDL_Joystick* joystick = SDL_JoystickOpen(0);
	if ( joystick ) {
		GLOUTPUT(( "Joystick '%s' open.\n", SDL_JoystickName(0) ));
	}

	int r = glewInit();
	GLASSERT( r == GL_NO_ERROR );

	// Calling this seems to confuse my ATI driver and cause lag / event back up?
//#ifdef TEST_FULLSPEED	
//	wglSwapIntervalEXT( 0 );	// vsync
//#else
//	wglSwapIntervalEXT( 1 );	// vsync
//#endif

	const unsigned char* vendor   = glGetString( GL_VENDOR );
	const unsigned char* renderer = glGetString( GL_RENDERER );
	const unsigned char* version  = glGetString( GL_VERSION );

	GLOUTPUT(( "OpenGL vendor: '%s'  Renderer: '%s'  Version: '%s'\n", vendor, renderer, version ));

	Audio_Init();

	bool done = false;
	bool zooming = false;
    SDL_Event event;

	float yRotation = 45.0f;
	grinliz::Vector2I mouseDown = { 0, 0 };
	grinliz::Vector2I prevMouseDown = { 0, 0 };
	U32 prevMouseDownTime = 0;

	int zoomX = 0;
	int zoomY = 0;

	void* game = 0;
	bool mapMakerMode = false;

	WIN32_FIND_DATA findFileData;
	HANDLE h;
	h = FindFirstFile( ".\\mods\\*.xwdb", &findFileData );
	if ( h != INVALID_HANDLE_VALUE ) {
		BOOL findResult = TRUE;
		while( findResult && nModDB < GAME_MAX_MOD_DATABASES ) {
			grinliz::GLString* str = new grinliz::GLString( ".\\mods\\" );
			str->append( findFileData.cFileName );
			databases[nModDB++] = str;
			GameAddDatabase( str->c_str() );
			findResult = FindNextFile( h, &findFileData );
		}
		FindClose( h );
	}

	if ( argc > 3 ) {
		// -- MapMaker -- //
		Engine::mapMakerMode = true;

		TileSetDesc desc;
		desc.set = "FARM";
		desc.size = 16;
		desc.type = "TILE";
		desc.variation = 0;

		if ( argc > 2 ) {
			desc.set = argv[2];
			GLASSERT( strlen( desc.set ) == 4 );
		}

		if ( argc > 3 ) {
			desc.size = atol( argv[3] );
			GLASSERT( desc.size == 16 || desc.size == 32 || desc.size == 48 || desc.size == 64 );
		}

		if ( argc > 4 ) {
			desc.type = argv[4];
			GLASSERT( strlen( desc.type ) == 4 );
		}

		if ( argc > 5 ) {
			desc.variation = atol( argv[5] );
			GLASSERT( desc.variation >= 0 && desc.variation < 100 );
		}

		game = new Game( screenWidth, screenHeight, rotation, ".\\resin\\", desc );
		mapMakerMode = true;
	}
	else {
		game = NewGame( screenWidth, screenHeight, rotation, ".\\", tvMode );
	}


#if SEND_CRASH_LOGS
	// Can't call this until after the game is created!
	if ( !SettingsManager::Instance()->GetSuppressCrashLog() ) {
		// Check for a "didn't crash" file.
		FILE* fp = fopen( "UFO_Running.txt", "r" );
		if ( fp ) {
			fseek( fp, 0, SEEK_END );
			long len = ftell( fp );
			if ( len > 1 ) {
				// Wasn't deleted.
				PostCurrentGame();
			}
			fclose( fp );
		}
	}
	{
		FILE* fp = fopen( "UFO_Running.txt", "w" );
		if ( fp ) {
			fprintf( fp, "Game running." );
			fclose( fp );
		}
	}
#endif


#ifndef TEST_FULLSPEED
	SDL_TimerID timerID = SDL_AddTimer( TIME_BETWEEN_FRAMES, TimerCallback, 0 );
#endif

	bool L2Down = false;
	bool R2Down = false;
	grinliz::Vector2F joystickAxis[2] = { 0, 0 };

	// ---- Main Loop --- //
#ifdef TEST_FULLSPEED	
	while ( !done ) {
		if ( SDL_PollEvent( &event ) )
#else
	while ( !done && SDL_WaitEvent( &event ) )
#endif
	{
		// The user event shouldn't be duplicated...if there are 2, pull out the dupe.
		if ( event.type == SDL_USEREVENT ) {
			SDL_Event e;
			while( true ) {
				int n = SDL_PeepEvents( &e, 1, SDL_PEEKEVENT, SDL_ALLEVENTS );		
				if ( n == 1 && e.type == SDL_USEREVENT ) {
					SDL_PeepEvents( &e, 1, SDL_GETEVENT, SDL_ALLEVENTS );
				}
				else {
					break;
				}
			}
		}

		switch( event.type )
		{
			case SDL_VIDEORESIZE:
				screenWidth = event.resize.w;
				screenHeight = event.resize.h;
				surface = SDL_SetVideoMode( screenWidth, screenHeight, 32, videoFlags );
				GameDeviceLoss( game );
				GameResize( game, event.resize.w, event.resize.h, rotation );
				break;

			/*
				A: 0		Triggers: axis=2
				X: 2
				Y: 3
				B: 1
				L1: 4
				R1: 5
			*/

			case SDL_JOYBUTTONDOWN:
			case SDL_JOYBUTTONUP:
				//GLOUTPUT(( "Button %d.\n", event.jbutton.button ));
				switch( event.jbutton.button ) {
				case 0:	GameJoyButton( game, GAME_JOY_BUTTON_DOWN,	event.type == SDL_JOYBUTTONDOWN );	break;
				case 1:	GameJoyButton( game, GAME_JOY_BUTTON_RIGHT,	event.type == SDL_JOYBUTTONDOWN );	break;
				case 2:	GameJoyButton( game, GAME_JOY_BUTTON_LEFT,	event.type == SDL_JOYBUTTONDOWN );	break;
				case 3:	GameJoyButton( game, GAME_JOY_BUTTON_UP,	event.type == SDL_JOYBUTTONDOWN );	break;
				case 4: GameJoyButton( game, GAME_JOY_L1,			event.type == SDL_JOYBUTTONDOWN );	break;
				case 5: GameJoyButton( game, GAME_JOY_R1,			event.type == SDL_JOYBUTTONDOWN );	break;
				}
				break;

			case SDL_JOYAXISMOTION:
				//GLOUTPUT(( "Axis %d to %d.\n", event.jaxis.axis, event.jaxis.value ));

				// axis2, posL, negR
				if ( event.jaxis.axis == 2 ) {
					int value = event.jaxis.value;
					static const int T = 10*1000;
					if ( value > 10 ) {
						if ( !L2Down && value > T ) {
							L2Down = true;
							GameJoyButton( game, GAME_JOY_L2, true );
						}
						else if ( L2Down && value < T ) {
							L2Down = false;
							GameJoyButton( game, GAME_JOY_L2, false );
						}
					}
					else if ( value < -10 ) {
						if ( !R2Down && value < -T ) {
							R2Down = true;
							GameJoyButton( game, GAME_JOY_R2, true );
						}
						else if ( R2Down && value > -T ) {
							R2Down = false;
							GameJoyButton( game, GAME_JOY_R2, false );
						}
					}
				}
				else {
					int value = event.jaxis.value;
					double normal = (double)value/32768.0f;
					int axis = -1;
					int stick = -1;

					switch( event.jaxis.axis ) {
						case 0:	axis=0;	stick=0;					break;
						case 1: axis=1; stick=0; normal *= -1.0;	break;
						case 3: axis=1;	stick=1; normal *= -1.0f;	break;
						case 4: axis=0; stick=1;					break;
						default: break;
					}

					if ( axis >= 0 && stick >= 0 ) {
						joystickAxis[stick].X(axis) = (float)normal;
					}
				}


				break;

			case SDL_JOYHATMOTION:
				GameJoyDPad( game, event.jhat.value );
				break;

			case SDL_KEYDOWN:
			{
				SDLMod sdlMod = SDL_GetModState();

				if ( mapMakerMode && event.key.keysym.sym >= SDLK_0 && event.key.keysym.sym <= SDLK_9 ) {
					int index = 0;
					switch ( event.key.keysym.sym ) {
					case SDLK_1:	index = 0;	break;
					case SDLK_2:	index = 1;	break;
					case SDLK_3:	index = 2;	break;
					case SDLK_4:	index = 3;	break;
					case SDLK_5:	index = 4;	break;
					case SDLK_6:	index = 5;	break;
					case SDLK_7:	index = 6;	break;
					case SDLK_8:	index = 7;	break;
					case SDLK_9:	index = 8;	break;
					case SDLK_0:	index = 9;	break;
					};

					const U8* light = ((Game*)game)->engine->GetMap()->DayTime() ? dayLight : nightLight;
					static const float INV = 1.0f/255.0f;

					U8 r = light[index*3+0];
					U8 g = light[index*3+1];
					U8 b = light[index*3+2];

					if ( sdlMod & sdlMod & ( KMOD_LSHIFT | KMOD_RSHIFT ) ) {
						if ( index < 6 ) {
							// Average with shade.
							r = (light[index*3+0] + light[SHADE*3+0]) / 2;
							g = (light[index*3+1] + light[SHADE*3+1]) / 2;
							b = (light[index*3+2] + light[SHADE*3+2]) / 2;
						}
						else if ( index > 6 ) {
							// make darker (index 6 is the darkest. SHIFT does nothing.)
							int m = index-1;
							r = (light[index*3+0] + light[m*3+0]) / 2;
							g = (light[index*3+1] + light[m*3+1]) / 2;
							b = (light[index*3+2] + light[m*3+2]) / 2;
						}
					}
					((Game*)game)->SetLightMap( (float)r * INV, (float)g * INV, (float)b * INV );
				}

				switch ( event.key.keysym.sym )
				{
					case SDLK_ESCAPE:
						{
							//int handled = GameHotKey( game, GAME_HK_BACK );
#ifdef DEBUG
							// only escape out in debug mode
							// if ( !handled ) 
							done = true;
#endif
						}
						break;

					case SDLK_F4:
						if ( sdlMod & ( KMOD_RALT | KMOD_LALT ) )
							done = true;
						break;

#ifdef SIM_GAMEPAD
					case SDLK_RIGHT:	GameJoyDPad( game, GAME_JOY_DPAD_RIGHT );	break;
					case SDLK_LEFT:		GameJoyDPad( game, GAME_JOY_DPAD_LEFT );	break;
					case SDLK_UP:		GameJoyDPad( game, GAME_JOY_DPAD_UP );		break;
					case SDLK_DOWN:		GameJoyDPad( game, GAME_JOY_DPAD_DOWN );	break;
					case SDLK_1:		GameJoyButton( game, 1, true );				break;
					case SDLK_2:		GameJoyButton( game, 2, true );				break;
					case SDLK_3:		GameJoyButton( game, 3, true );				break;
					case SDLK_4:		GameJoyButton( game, 4, true );				break;

#else
					case SDLK_RIGHT:
						if ( !mapMakerMode ) {
							if ( sdlMod & (KMOD_RCTRL|KMOD_LCTRL) )
								GameHotKey( game, GAME_HK_ROTATE_CW );
							else
								GameHotKey( game, GAME_HK_NEXT_UNIT );
						}
						break;

					case SDLK_LEFT:
						if ( !mapMakerMode ) {
							if ( sdlMod & (KMOD_RCTRL|KMOD_LCTRL) )
								GameHotKey( game, GAME_HK_ROTATE_CCW );
							else
								GameHotKey( game, GAME_HK_PREV_UNIT );
						}
						break;
#endif
					case SDLK_u:
						if ( mapMakerMode ) {
							((Game*)game)->engine->camera.SetTilt( -90.0f );
							((Game*)game)->engine->camera.SetPosWC( 8.f, 90.f, 8.f );
							((Game*)game)->engine->camera.SetYRotation( 0.0f );
						}
						else {
							GameHotKey( game, GAME_HK_TOGGLE_ROTATION_UI | GAME_HK_TOGGLE_NEXT_UI );
						}
						break;

					case SDLK_o:
						if ( mapMakerMode ) {
							cameraIso = !cameraIso;
							((Game*)game)->engine->CameraIso( cameraIso, true, (float)((Game*)game)->engine->GetMap()->Width(), (float)((Game*)game)->engine->GetMap()->Height() );
						}
						break;

					case SDLK_s:
						if ( mapMakerMode ) {
							((Game*)game)->SuppressText( true );
						}
						GameDoTick( game, SDL_GetTicks() );
						SDL_GL_SwapBuffers();
						if ( mapMakerMode ) {
							((Game*)game)->SuppressText( false );
						}
						ScreenCapture( "cap" );
						break;

					case SDLK_l:
						if ( mapMakerMode ) {
							const Surface* lightmap = ((Game*)game)->engine->GetMap()->GetLightMap();
							SaveLightMap( lightmap );
						}
						break;

					case SDLK_d:
						GameHotKey( game, GAME_HK_TOGGLE_DEBUG_TEXT );
						break;

					case SDLK_DELETE:
						if ( mapMakerMode )
							((Game*)game)->DeleteAtSelection(); 
						break;

					case SDLK_KP9:			
						if ( mapMakerMode )
							((Game*)game)->RotateSelection( -1 );			
						break;

					case SDLK_r:
					case SDLK_KP7:			
						if ( mapMakerMode )
							((Game*)game)->RotateSelection( 1 );			
						break;

					case SDLK_KP8:			
						if ( mapMakerMode )
							((Game*)game)->DeltaCurrentMapItem(16);			
						break;

					case SDLK_KP5:			
						if ( mapMakerMode )
							((Game*)game)->DeltaCurrentMapItem(-16);		
						break;

					case SDLK_KP6:			
						if ( mapMakerMode )
							((Game*)game)->DeltaCurrentMapItem(1); 			
						break;

					case SDLK_KP4:			
						if ( mapMakerMode )
							((Game*)game)->DeltaCurrentMapItem(-1);			
						break;

					case SDLK_p:
						//if ( mapMakerMode )
						{
							int pathing = (((Game*)game)->ShowingPathing() + 1) % 3;
							((Game*)game)->ShowPathing( pathing );
						}
						break;

					case SDLK_t:
						if ( mapMakerMode )
							((Game*)game)->engine->GetMap()->SetDayTime( !((Game*)game)->engine->GetMap()->DayTime() );
						break;

					case SDLK_v:
						((Game*)game)->ToggleTV();
						break;

					case SDLK_m:
						if ( mapMakerMode )
							((Game*)game)->engine->EnableMetadata( !((Game*)game)->engine->IsMetadataEnabled() );
						break;

					default:
						break;
				}
/*					GLOUTPUT(( "fov=%.1f rot=%.1f h=%.1f\n", 
							game->engine.fov, 
							game->engine.camera.Tilt(), 
							game->engine.camera.PosWC().y ));
*/
			}
			break;

#ifdef SIM_GAMEPAD
			case SDL_KEYUP:
			{
				switch ( event.key.keysym.sym )
				{
					case SDLK_1:		GameJoyButton( game, 1, false );				break;
					case SDLK_2:		GameJoyButton( game, 2, false );				break;
					case SDLK_3:		GameJoyButton( game, 3, false );				break;
					case SDLK_4:		GameJoyButton( game, 4, false );				break;
				}
			}
			break;
#endif

			case SDL_MOUSEBUTTONDOWN:
			{
				int x, y;
				TransformXY( event.button.x, event.button.y, &x, &y );

				mouseDown.Set( event.button.x, event.button.y );

				if ( event.button.button == 1 ) {
					GameTap( game, GAME_TAP_DOWN, x, y );
				}
				else if ( event.button.button == 3 ) {
					GameTap( game, GAME_TAP_CANCEL, x, y );
					zooming = true;
					//GameCameraRotate( game, GAME_ROTATE_START, 0.0f );
					SDL_GetRelativeMouseState( &zoomX, &zoomY );
				}
			}
			break;

			case SDL_MOUSEBUTTONUP:
			{
				int x, y;
				TransformXY( event.button.x, event.button.y, &x, &y );

				if ( event.button.button == 3 ) {
					zooming = false;
				}
				if ( event.button.button == 1 ) {
					GameTap( game, GAME_TAP_UP, x, y );
				}
			}
			break;

			case SDL_MOUSEMOTION:
			{
				SDL_GetRelativeMouseState( &zoomX, &zoomY );
				int state = SDL_GetMouseState(NULL, NULL);
				int x, y;
				TransformXY( event.button.x, event.button.y, &x, &y );

				if ( state & SDL_BUTTON(1) ) {
					GameTap( game, GAME_TAP_MOVE, x, y );
				}
				else if ( zooming && (state & SDL_BUTTON(3)) ) {
					float deltaZoom = 0.01f * (float)zoomY;
					GameZoom( game, GAME_ZOOM_DISTANCE, deltaZoom );
					GameCameraRotate( game, (float)(zoomX)*0.5f );
				}
				else if ( ( ( state & SDL_BUTTON(1) ) == 0 ) ) {
					((Game*)game)->MouseMove( x, y );
				}
			}
			break;

			case SDL_QUIT:
			{
				done = true;
			}
			break;

			case SDL_USEREVENT:
			{
				glEnable( GL_DEPTH_TEST );
				glDepthFunc( GL_LEQUAL );

				for( int stick=0; stick<2; ++stick ) {
					if ( joystickAxis[stick].x || joystickAxis[stick].y ) {
						GameJoyStick( game, stick, joystickAxis[stick].x, joystickAxis[stick].y );
					}
				}
				GameDoTick( game, SDL_GetTicks() );
				SDL_GL_SwapBuffers();

				int databaseID=0, size=0, offset=0;
				// FIXME: account for databaseID when looking up sound.
				while ( GamePopSound( game, &databaseID, &offset, &size ) ) {
					Audio_PlayWav( "./res/uforesource.db", offset, size );
				}
			};

			default:
				break;
		}
#ifdef TEST_FULLSPEED	
		}

		glEnable( GL_DEPTH_TEST );
		glDepthFunc( GL_LEQUAL );

		GameDoTick( game, SDL_GetTicks() );
		SDL_GL_SwapBuffers();
	}
#else
	}
示例#11
0
ScalingTest::ScalingTest( SDL_Surface* screen )
{
	int i, j;
	//KrMatrix2 xForm;
	state = BOTH;

	//
	// Create the engine, load the dat files, get the resource.
	//
	engine = new KrEngine( screen );
	GLASSERT( engine );

	if ( !engine->Vault()->LoadDatFile( "space.dat" ) )
	{
		GLOUTPUT(( "Error loading 'space.dat'\n" ));
		exit(100);
	}

	fontVault = new KrResourceVault();
	if ( !fontVault->LoadDatFile( "font.dat" ) )
	{
		GLOUTPUT(( "Error loading 'font.dat'\n" ));
		exit(100);
	}

	KrSpriteResource* shipRes = engine->Vault()->GetSpriteResource( "MED" );
	GLASSERT( shipRes );
	KrSpriteResource* smallShipRes = engine->Vault()->GetSpriteResource( "SMALL" );
	GLASSERT( smallShipRes );
	KrFontResource*	fontConsole = fontVault->GetFontResource( "CONSOLE" );
	GLASSERT( fontConsole );

	KrRGBA white, red;
	white.Set( 255, 255, 255 );
	red.Set( 255, 0, 0 );

	AddBackground();

	// A group of travelling ships.
	travellingShip = new KrSprite( shipRes );
	travellingShip->SetAction( "BODY" );
	travellingShip->SetPos( 500, 390 );
	engine->Tree()->AddNode( 0, travellingShip );

	for ( i=0; i<4; ++i )
	{
		KrSprite* escort = new KrSprite( smallShipRes );
		escort->SetPos( 10 + i*30, -55 + i*30 );
		engine->Tree()->AddNode( travellingShip, escort );
	}

	travelText = new KrTextBox( fontConsole, 300, 300, 1 );
	engine->Tree()->AddNode( travellingShip, travelText );
	travelText->SetPos( -60, 30 );
	travelText->SetTextChar( "sin wave motion", 0 );



	//
	// Zoom 3 canvases to compare. The canvas are set up by drawing
	// a sprite to a canvas.
	//
	int hotx, hoty;
	KrCanvasResource* canvasRes = shipRes->CreateCanvasResource( "BODY", 0, &hotx, &hoty );
	GLASSERT( canvasRes );
	GLASSERT( canvasRes->Alpha() );
	engine->Vault()->AddResource( canvasRes );

	for( i=0; i<canvasRes->Width(); ++i )
	{
		for( j=0; j<canvasRes->Height(); ++j )
		{
			KrRGBA* pixel = canvasRes->Pixels() + j*canvasRes->Width() + i;
			if ( pixel->c.alpha )
				pixel->c.alpha = i * 256 / canvasRes->Width();
		}
	}

	for( i=0; i<3; ++i )
	{
		canvas[i] = new KrCanvas( canvasRes );
		canvas[i]->SetPos( 50 + i * 200, 170 );
		engine->Tree()->AddNode( 0, canvas[i] );
	}
	canvas[0]->SetQuality( KrQualityFast );
	canvas[1]->SetQuality( KrQualityLinear );
	canvas[2]->SetQuality( KrQualityAdaptive );


	// A sprite that scales in the upper left.
	// A resource to mark the center of the sprite.
	KrBoxResource* centerRes = new KrBoxResource( "Center",
												  5, 5,
												  &red, 1,
												  KrBoxResource::CROSSHAIR );
	engine->Vault()->AddResource( centerRes );

	// The ship that scales in the upper left
	ship = new KrSprite( shipRes );
	ship->SetAction( "BODY" );
	ship->SetPos( SHIPX, SHIPY );
	engine->Tree()->AddNode( 0, ship );


	// Center marker of the sprite
	center = new KrBox( centerRes );
	engine->Tree()->AddNode( 0, center );
	center->SetPos( SHIPX, SHIPY );

	// Some text info.
	textBox = new KrTextBox( fontConsole, 1024, 1024, 0 );
	textBox->SetPos( 10, 10 );
	engine->Tree()->AddNode( 0, textBox );

	scaleX.v = GlFixed_1 - GlFixed_1 / 8;
	scaleY.v = GlFixed_1 - GlFixed_1 / 8;
	AddText( engine );
}
示例#12
0
int main( int argc, char *argv[] )
{
	SDL_Surface* screen;
	int  depth = 0;
	bool speedtest = false;	
	U32  flags = SDL_SWSURFACE;
	int i;
	bool timerOn = true;
	bool useOpenGL = false;
// 	bool saveBMP = false;

	const SDL_version* sdlVersion = SDL_Linked_Version();
	if ( sdlVersion->minor < 2 )
	{
		GLOUTPUT(( "SDL version must be at least 1.2.0" ));
		GLASSERT( 0 );
		exit( 254 );
	}

	/* Initialize the SDL library */
	if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_NOPARACHUTE) < 0 ) {
		GLOUTPUT(( "Couldn't initialize SDL: %s\n",SDL_GetError()));
		exit(255);
	}

	SDL_WM_SetCaption( "Kyra Demo", 0 );

	for ( i=1; i<argc; i++ )
	{
		if ( *argv[i] == '-' && *(argv[i]+1) )
		{
			const char* param = argv[i]+2;
			switch( *(argv[i]+1) )
			{
				case 'd':
				{
					depth = atoi( param );
				}
				break;

				case 's':
				{
					speedtest = true;
				}
				break;

				case 'f':
				{
					flags |= SDL_FULLSCREEN;
				}
				break;

				case '1':
				{
					timerOn = false;
				}
				break;

				case 't':
				{
					singleTest = atoi( param );
				}
				break;

				case 'o':
				{
					useOpenGL = true;
				}
			}
		}
	}

	if ( useOpenGL )
	{
		if ( flags & SDL_FULLSCREEN )
			flags = SDL_OPENGL | SDL_FULLSCREEN;
		else
			flags = SDL_OPENGL;
	}

	/* Create a display for the image. If we are forcing the mode,
	   skip this step and potentially use a shadow surface.
	*/
	if ( depth == 0 )
	{
		depth = SDL_VideoModeOK( SCREENX, SCREENY, 32, flags );
		if ( depth < 16 )
			depth = 16;
	}

	if ( useOpenGL )
	{
		// We want *at least* 5 bits per channel.
		//SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );
    	//SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 );
    	//SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );

		SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, depth );
		SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
	}
	screen = SDL_SetVideoMode( SCREENX, SCREENY, depth, flags );

	if ( screen == NULL ) {
		fprintf( stdout, "Can't open display (%dx%d %dbps %s)\n",
				 SCREENX, SCREENY, depth,
				 useOpenGL ? "OpenGL" : "" );		
		fprintf( stdout, "SDL_Error: %s\n", SDL_GetError() );
		exit(3);
	}

	char buf[512];
 	factory.GetHeader( screen, buf );
	printf( buf );
	GLOUTPUT(( "%s\n", buf ));

	SDL_Event event;

	if ( speedtest )
	{
		memset( &event, 0, sizeof( event ) );
		event.type = SDL_TIMER_EVENT;
		SDL_PeepEvents( &event, 1, SDL_ADDEVENT, 0 );
		GLOUTPUT(( "Speedtest mode!\n" ));
	}
	else if ( timerOn )
	{
		SDL_SetTimer( timerInterval, TimerCallback );
		GLOUTPUT(( "Demo play mode!\n" ));
	}
	U32 start = SDL_GetTicks();

	if ( singleTest < 0 )
		currentGame = factory.CreateGame( 0, screen );
	else
		currentGame = factory.CreateGame( singleTest, screen );		
	timerInterval = currentGame->FrameInterval();

	while( currentGame && SDL_WaitEvent(&event) )
	{
		if ( event.type == SDL_QUIT )
			break;

		// Cull extra timer messages:
		if ( !speedtest && timerOn )
		{
			SDL_Event nextEvent;
			if (    SDL_PeepEvents( &nextEvent, 1, SDL_PEEKEVENT, SDL_ALLEVENTS )
			     && nextEvent.type == SDL_TIMER_EVENT )
			{
				// the event is duplicated
				//GLOUTPUT( "Timer event tossed.\n" );
				continue;
			}
		}

		switch(event.type)
		{
			case SDL_KEYDOWN:
			{
				if ( event.key.keysym.sym == SDLK_F10 )
				{
					// save a bitmap.
					static int count = 0;
					char buf[ 256 ];
					sprintf( buf, "krdemo%d.bmp", count++ );

					if ( !(screen->flags & SDL_OPENGL ) )
						SDL_SaveBMP( screen, buf );
				} 
				else if ( !timerOn && event.key.keysym.sym == SDLK_SPACE )
				{
					// Simulate a timer:
					SDL_Event e;
					memset( &e, 0, sizeof( e ) );
					e.type = SDL_TIMER_EVENT;
					SDL_PeepEvents( &e, 1, SDL_ADDEVENT, 0 );
				}
				else if ( event.key.keysym.sym == SDLK_s )
				{
					timerInterval = 500;
				}
				else if ( event.key.keysym.sym == SDLK_a )
				{
					timerInterval = 10000;
				}
				else
				{
					NextTest( screen );
				}
			}
			break;

			case SDL_KEYUP:
			{
				if (    event.key.keysym.sym == SDLK_s
					 || event.key.keysym.sym == SDLK_a )
				{
					if ( currentGame )
						timerInterval = currentGame->FrameInterval();

					SDL_SetTimer( 0, TimerCallback );
					SDL_SetTimer( timerInterval, TimerCallback );
				}
			}
			break;

			case SDL_VIDEOEXPOSE:
			{
				currentGame->VideoExpose();
//				currentGame->UpperDrawFrame();
			}
			break;

			case SDL_TIMER_EVENT:
			{
				if ( currentGame )
				{
					currentGame->UpperDrawFrame();

// 					if (    speedtest 
// 					     && currentGame->Frame() == currentGame->TestFrames() )
					if ( currentGame->Frame() == currentGame->TestFrames() )
					{
						U32 end = SDL_GetTicks();
						factory.SetTime( end - start );
						NextTest( screen );
						start = SDL_GetTicks();
					}
					if ( speedtest )
					{
						SDL_Event e;
						memset( &e, 0, sizeof( e ) );
						e.type = SDL_TIMER_EVENT;
						SDL_PeepEvents( &e, 1, SDL_ADDEVENT, 0 );
					}
				}
			}
			break;
		}

	}

	if ( speedtest )
	{
		factory.PrintTimes( screen );
	}
	else
	{
		printf( "Tested at %dbbp\n", screen->format->BitsPerPixel );
	}

	if ( speedtest )
	{
		FILE* fp = fopen( "perf.txt", "w" );
		if ( fp )
		{
			fprintf( fp, "Performance: \n" );
			
			grinliz::Performance::Dump( fp, "kyra" );
			fclose( fp );
		}
	}
	SDL_Quit();	
	return 0;
}
示例#13
0
void KrEventManager::HandleEvent( const SDL_Event& event, KrEngine* engine )
{
    if ( event.type == SDL_KEYDOWN && keyFocus >= 0) //maks
    {
        //	- the tab key changes key focus.
        //	- accelerators are checked
        //	- keys passed through to the handler.

#ifdef DEBUG
        GLOUTPUT( "KeyDown mod=%d sym=%d, unicode=%d, name=%s\n", event.key.keysym.mod, event.key.keysym.sym, event.key.keysym.unicode, SDL_GetKeyName(event.key.keysym.sym)); //maks
#endif

        if (    event.key.keysym.sym == SDLK_TAB
                && keyListeners.Count() > 1 )
        {
            if ( event.key.keysym.mod & KMOD_SHIFT )
                ChangeKeyFocus( keyFocus + keyListeners.Count() - 1 );
            else
                ChangeKeyFocus( keyFocus + 1 );
            return;
        }

        for( int i=0; i<accelListeners.Count(); ++i )
        {
            int sym = accelListeners[i].keysym;
            int mod = accelListeners[i].keymod;

            if (    event.key.keysym.sym == sym &&
                    event.key.keysym.mod & mod &&
                    keyListeners.Count() &&
                    accelListeners[i].target == keyListeners[ keyFocus ]) //maks: send accelerators for key focus owners
            {
                accelListeners[i].target->Accelerate( true, mod, sym ); //maks
                return;
            }
        }

        if ( keyListeners.Count() > 0 )
        {
            keyFocus = GlClamp( keyFocus, 0, int( keyListeners.Count()-1 ) );
            KrWidget* widget = keyListeners[ keyFocus ];

            // Go up the chain until handled.
            while( widget && !widget->KeyEvent( event ) )
            {
                widget = widget->ParentWidget();
            }
        }
    }
    else if ( event.type == SDL_KEYUP )
    {
        // - only accelerates key up
        for( int i=0; i<accelListeners.Count(); ++i )
        {
            if (    event.key.keysym.sym == accelListeners[i].keysym &&
                    event.key.keysym.mod & accelListeners[i].keymod &&
                    keyFocus >= 0 &&
                    keyListeners.Count() &&
                    accelListeners[i].target == keyListeners[ keyFocus ]) //maks
            {
                accelListeners[i].target->Accelerate( false, event.key.keysym.mod, event.key.keysym.sym ); //maks
                return;
            }
        }

        //Send shift key up
        if ( keyListeners.Count() > 0 && (event.key.keysym.sym == SDLK_LSHIFT || event.key.keysym.sym == SDLK_RSHIFT))
        {
            keyFocus = GlClamp( keyFocus, 0, int( keyListeners.Count()-1 ) );
            KrWidget* widget = keyListeners[ keyFocus ];

            // Go up the chain until handled.
            while( widget && !widget->KeyEvent( event ) )
            {
                widget = widget->ParentWidget();
            }
        }
    }
    else if ( event.type == SDL_MOUSEMOTION )
    {
        GlDynArray<KrImage*> hitArray;
        KrWidget* hit = 0;
        //int window = engine->GetWindowFromPoint( event.motion.x, event.motion.y );

        KrVector2T< GlFixed > object;

#ifndef _WIN32_WCE
        if(mouseDown && mouseFocus) //maks
        {
            //Don't change the focus if mouse button is down
            //Don't works on Pocket PC. In input.ged don't close the SIP keyboard (only send keyFocus = true)

            hit = mouseFocus;
            hit->ScreenToObject( event.motion.x, event.motion.y, &object/*, window*/ );
        }
        else
#endif
        {
            engine->Tree()->HitTest( event.motion.x, event.motion.y,
                                     KrImageTree::ALWAYS_INSIDE_BOX, //| GET_ALL_HITS,
                                     &hitArray/*,
				&window*/ );


            for( int i=0; i<hitArray.Count(); ++i )
            {
                KrImNode* parent = hitArray[i]->Parent();
                while( parent )
                {
                    if ( parent->ToWidget() )
                    {
                        hit = parent->ToWidget();
                        hit->ScreenToObject( event.motion.x, event.motion.y, &object/*, window*/ );
                        break;
                    }
                    parent = parent->Parent();
                }
            }
        }

        // 1) Something has the focus. Nothing had it before.
        // 2) Something has the focus, something else had it before.
        // 3) Something loses the focus.
        // 5) The thing with focus gets a move.
        if ( hit && !mouseFocus )
        {
            mouseFocus = hit;
            mouseFocus->MouseIn( mouseDown, true );
            mouseFocus->MouseMove( mouseDown, object.x.ToIntRound(), object.y.ToIntRound() );
        }
        else if ( hit && mouseFocus && mouseFocus != hit )
        {
            mouseFocus->MouseIn( mouseDown, false );
            mouseFocus = hit;
            mouseFocus->MouseIn( mouseDown, true );
            mouseFocus->MouseMove( mouseDown, object.x.ToIntRound(), object.y.ToIntRound() );
        }
        else if ( !hit && mouseFocus )
        {
            mouseFocus->MouseIn( mouseDown, false );
            mouseFocus = hit;
        }
        else if ( hit && hit == mouseFocus )
        {
            GLASSERT( hit == mouseFocus );
            mouseFocus->MouseMove( mouseDown, object.x.ToIntRound(), object.y.ToIntRound() );
        }
        else if ( !hit && !mouseFocus )
        {
            // nothing to do
        }
        else
        {
            GLASSERT( 0 );
        }

    }
    else if ( event.type == SDL_MOUSEBUTTONDOWN || event.type == SDL_MOUSEBUTTONUP )
    {
        if ( event.button.button == SDL_BUTTON_LEFT )
        {
            bool down = event.button.state != 0;	// & SDL_BUTTON_LMASK;
            if ( down != mouseDown )
            {
                mouseDown = down;
                if ( mouseFocus )
                {
                    int window = engine->GetWindowFromPoint( event.motion.x, event.motion.y );
                    KrVector2T< GlFixed > object;
                    mouseFocus->ScreenToObject( event.motion.x, event.motion.y, &object/*, window*/ );

                    mouseFocus->MouseClick( mouseDown ? KrWidget::LEFT_DOWN : KrWidget::LEFT_UP,
                                            object.x.ToIntRound(),
                                            object.y.ToIntRound() );
                }
                else //maks
                {
                    if(
                        keyFocus >= 0 && keyFocus < keyListeners.Count() &&
                        !newListnerFocus //maks: Only remove the focus if the widget don't has changed the focus in this cycle (solve focus bug in Math for Kids.ged)
                    )
                    {
                        keyListeners[ keyFocus ]->KeyFocus( false );
                        keyFocus = -1;
                        FocusState(false);
                    }
                }
            }
        }
        else if ( event.button.button == SDL_BUTTON_RIGHT ) //maks
        {
            bool down = event.button.state != 0;
            if ( down != mouseDown )
            {
                mouseDown = down;
                if ( mouseFocus )
                {
                    int window = engine->GetWindowFromPoint( event.motion.x, event.motion.y );
                    KrVector2T< GlFixed > object;
                    mouseFocus->ScreenToObject( event.motion.x, event.motion.y, &object/*, window*/ );

                    mouseFocus->MouseClick( mouseDown ? KrWidget::RIGHT_DOWN : KrWidget::RIGHT_UP,
                                            object.x.ToIntRound(),
                                            object.y.ToIntRound() );
                }
            }
        }
    }

    newListnerFocus = false; //maks
}
示例#14
0
BemGame::BemGame( SDL_Surface* screen, bool useWindows )
{
	random.SetSeed( 0 );

	KrRGBA green;
	green.Set( 0, 200, 0 );
	
	if ( useWindows )
	{
		KrRect rects[5];
		
		const int lW = 280;
		const int lH = 180;
		const int r = 200;
		const int pad = 10;
		
		rects[0].Set( 0,   0, screen->w - 1 - pad - r, r + pad - 1 );
		rects[1].Set( 0, r + pad, screen->w-1, screen->h - 1 - pad - lH );
		rects[2].Set( lW + pad, screen->h - pad - lH, screen->w-1, screen->h - 1 );

		rects[3].Set( 0, screen->h - lH, lW-1, screen->h - 1 );
		rects[4].Set( screen->w - r, 0, screen->w-1, r-1 );

		engine = new KrEngine( screen, 5, rects, &green );
	}
	else
	{
		engine = new KrEngine( screen );
	}
	GLASSERT( engine );

	// The vault contains all the resources used by this
	// demo.
	if (!engine->Vault()->LoadDatFile( "bem.dat" ) )
	{
		GLOUTPUT(( "Error loading dat file: 'bem.dat'!\n" ));
		exit( 100 );
	}

	KrRGBA black;
	black.Set( 0, 0, 0 );
	if ( useWindows )
	{
		engine->FillBackgroundWindow( 0, 0 );			// main
		engine->FillBackgroundWindow( 1, 0 );			// main
		engine->FillBackgroundWindow( 2, 0 );			// main
		engine->FillBackgroundWindow( 3, &black );		// zoomed out
		engine->FillBackgroundWindow( 4, &black );		// moving zoom
	}
	else
	{
		// We have a space image so the engine should not draw
		// the background. Performance enhancement.
		engine->FillBackground( 0 );
	}

	// Set up some depth categories:
	backgroundTree = new KrImNode;
	underTree	   = new KrImNode;
	floorTree      = new KrImNode;
	standingTree   = new KrImNode;
	overTree       = new KrImNode;

	// Depth sort by order of addition. All the z-depths are
	// left at 0. In other words, when added at the same Z-depth (0
	// in this case) the object added most recently is on top.
	engine->Tree()->AddNode( 0, backgroundTree );
	engine->Tree()->AddNode( 0, underTree );
	engine->Tree()->AddNode( 0, floorTree );
	engine->Tree()->AddNode( 0, standingTree );
	engine->Tree()->AddNode( 0, overTree );

	// Store the floor size. Due to the way the sprites are defined,
	// the size in terms of positioning the tiles is slightly different
	// than the size in terms of the tile bitmap.
	KrSpriteResource* resource = engine->Vault()->GetSpriteResource( BEM_ROOM | BEM_FLOOR );
	GLASSERT( resource );
	tileWidth  = resource->GetActionByIndex( 0 )->Frame( 0 ).Width() +2;
	tileHeight = resource->GetActionByIndex( 0 )->Frame( 0 ).Height();

	isoMath = new GlIsoMath( tileWidth, tileHeight );
	isoMath->SetScreenCenterToTile( screen->w,
									screen->h,
									MAPX / 2, MAPY / 2, 0 );

	AddSpaceTiles();
	AddFloor();
	AddRoomObjects();
	AddActors( useWindows );

	// Add the mini-map
	KrCanvasResource* canvasResource =
					new KrCanvasResource(	"minimap",
											140, 140,
											true  );
	GLASSERT( canvasResource );


	// An example of a user-defined resource getting added to a vault.
	engine->Vault()->AddResource( canvasResource );

	canvas = new KrCanvas( canvasResource );
	canvas->SetPos( screen->w - canvasResource->Width(),
					screen->h - canvasResource->Height() );
	engine->Tree()->AddNode( overTree, canvas );

	subtick = 0;
	tick = 0;
	teleFrame = 0;
	teleSprite = 0;
	DrawMiniMap();

	if ( useWindows )
	{
		// Set the 3 "band" windows to be positioned
		// to the first.
 		engine->Tree()->Root()->SetPos( 0, 0, 0 );
		engine->Tree()->Root()->SetPos( -engine->ScreenBounds(1).min.x, -engine->ScreenBounds(1).min.y, 1 );
 		engine->Tree()->Root()->SetPos( -engine->ScreenBounds(2).min.x, -engine->ScreenBounds(2).min.y, 2 );

		SetupLeftWindow();
		SetupRightWindow();
	}
}
示例#15
0
int main( int argc, char *argv[] )
{
	const SDL_version* sdlVersion = SDL_Linked_Version();
	if ( sdlVersion->minor < 2 )
	{
		printf( "SDL version must be at least 1.2.0\n" );
		GLASSERT( 0 );
		exit( 254 );
	}

	if ( argc < 2 )
	{
		printf( "Usage: krmapmaker map.xml\n" );
		exit( 253 );
	}

	TiXmlDocument doc( argv[1] );
	doc.LoadFile();

	XmlUtil xmlUtil( &doc );
	if ( !xmlUtil.IsValidMap() )
	{
		printf( "Not a valid map file.\n" );
		exit( 252 );
	}

	/* Initialize the SDL library */
	if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_NOPARACHUTE) < 0 ) {
		#ifdef DEBUG
			GLOUTPUT( "Couldn't initialize SDL: %s\n",SDL_GetError());
		#endif
		exit(255);
	}

	SDL_WM_SetCaption( "Kyra MapMaker", 0 );

	int screenX = 800;
	int screenY = 600;

	SDL_Surface* screen = SDL_SetVideoMode( screenX, screenY, 32, SDL_SWSURFACE );

	if ( screen )
	{
		KrResourceVault fontVault;
		//fontVault.LoadDatFileFromMemory( fontDat, sizeof( fontDat ) );
		KrFontResource* consoleFontRes =  KrEncoder::CreateFixedFontResource( "CONSOLE", CONSOLEFONT_DAT, CONSOLEFONT_SIZE );

		Layout layout( screen, consoleFontRes );
		if ( layout.Engine()->Vault()->LoadDatFile( xmlUtil.DatFileName().c_str() ) != true )
		{
			printf( "Couldn't load dat file.\n" );
			exit( 250 );
		}

		KrSquareWorldMap* worldMap = new KrSquareWorldMap( 100, 100, 100 );	// fixme hardcoded!
		layout.Engine()->Tree()->AddNode( layout.Map(), worldMap );
		worldMap->SetPos( 0, screenY-1, Layout::MAIN_VIEW );

		xmlUtil.Init( layout.Engine()->Vault(), layout.Engine(), layout.Map(), worldMap );
//		xmlUtil.InsertLayers( layout.LayerBox() );

		UILogic logic( &layout, &xmlUtil );
		layout.SetLayer( xmlUtil.GetLayer( "null" ), 0 );		

		KrRGBA white;
		white.Set( 200, 200, 200 );
		KrBox* whereBox = new KrBox( layout.Engine()->ScreenBounds( Layout::MAIN_VIEW ).Width(),
									 layout.Engine()->ScreenBounds( Layout::MAIN_VIEW ).Height(),
									 white, 
									 KrBoxResource::OUTLINE );
		layout.Engine()->Tree()->AddNode( 0, whereBox );
		whereBox->SetVisible( false );
		whereBox->SetVisible( true, Layout::MINIMAP_VIEW );

		layout.Engine()->Draw();

		SDL_Event event;

		while ( SDL_WaitEvent( &event ) )
		{
			if ( event.type == SDL_QUIT )
				break;

			KrEventManager::Instance()->HandleEvent( event, layout.Engine() );

			bool mapChanged = false;

			if (	( event.type == SDL_MOUSEMOTION || event.type == SDL_MOUSEBUTTONDOWN )
				 && layout.Engine()->GetWindowFromPoint( event.motion.x, event.motion.y ) == Layout::MAIN_VIEW )
			{
				KrVector2T< GlFixed > map;
				worldMap->ScreenToMap( event.motion.x, event.motion.y, &map, Layout::MAIN_VIEW );
				layout.DisplayMapCoords( map.x.ToFloat(), map.y.ToFloat() );

				if(			event.type == SDL_MOUSEBUTTONDOWN 
					   ||  ( event.type == SDL_MOUSEMOTION && event.motion.state == 1 ) )
				{
					if ( logic.CurrentImage() )
					{
						worldMap->SetLoc( map.x.ToInt(), map.y.ToInt(), 
										  logic.CurrentImage()->Clone()->ToImage() );
						mapChanged = true;
					}
				}
			}
			else if ( event.type == SDL_KEYDOWN )
			{
				if ( event.key.keysym.sym == SDLK_UP )
				{
					worldMap->SetPos( worldMap->X(), worldMap->Y() + worldMap->TileHeight(), Layout::MAIN_VIEW );
					mapChanged = true;
				}
				else if ( event.key.keysym.sym == SDLK_DOWN )
				{
					worldMap->SetPos( worldMap->X(), worldMap->Y() - worldMap->TileHeight(), Layout::MAIN_VIEW );
					mapChanged = true;
				}				
				else if ( event.key.keysym.sym == SDLK_RIGHT )
				{
					worldMap->SetPos( worldMap->X() - worldMap->TileWidth(), worldMap->Y(), Layout::MAIN_VIEW );
					mapChanged = true;
				}
				else if ( event.key.keysym.sym == SDLK_LEFT )
				{
					worldMap->SetPos( worldMap->X() + worldMap->TileWidth(), 
									  worldMap->Y(), 
									  Layout::MAIN_VIEW );
					mapChanged = true;
				}
				else if ( event.key.keysym.sym >= SDLK_0 && event.key.keysym.sym <= SDLK_7 )
				{
					layout.SetRotation( event.key.keysym.sym - SDLK_0 );
					logic.SetRotation( event.key.keysym.sym - SDLK_0 );
				}
			}

			if ( mapChanged )
			{
				layout.Engine()->Tree()->Walk();
				KrRect bounds = worldMap->CompositeBounds( Layout::MAIN_VIEW );

//				layout.Map()->SetPos(	-bounds.xmin, // - layout.Engine()->ScreenBounds( Layout::MAIN_VIEW ).xmin,
//										-bounds.ymin, // - layout.Engine()->ScreenBounds( Layout::MAIN_VIEW ).ymin,
//										Layout::MINIMAP_VIEW );

				GlFixed scale = GlMin(  GlFixed( layout.Engine()->ScreenBounds( Layout::MINIMAP_VIEW ).Width() ) / GlFixed( bounds.Width() ),
										GlFixed( layout.Engine()->ScreenBounds( Layout::MINIMAP_VIEW ).Height() ) / GlFixed( bounds.Height() ) );
				
				layout.Map()->SetPos(	0,
										( GlFixed( Layout::UI_WIDTH ) / scale ).ToInt(),
										Layout::MINIMAP_VIEW );

				layout.Engine()->Tree()->Root()->SetScale( scale, scale, Layout::MINIMAP_VIEW );
				GLOUTPUT( "Minimap scale set to %f\n", scale.ToFloat() );

				whereBox->SetPos( -worldMap->X(), bounds.Height() - 1 - worldMap->Y() );		
			}

			layout.Engine()->Draw();
		}	
	}
	SDL_Quit();

	return 0;
}
示例#16
0
int main(int argc, char **argv)
{
	MemStartCheck();
	{ char* test = new char[16]; delete[] test; }
	grinliz::TestContainers();

	{
		grinliz::GLString releasePath;
		GetSystemPath(GAME_SAVE_DIR, "release_log.txt", &releasePath);
		SetReleaseLog(fopen(releasePath.c_str(), "w"));
	}
	GLOUTPUT_REL(("Altera startup. version'%s'\n", VERSION));

	SDL_version compiled;
	SDL_version linked;

	SDL_VERSION(&compiled);
	SDL_GetVersion(&linked);

	GLOUTPUT_REL(("SDL version compiled: %d.%d.%d\n", compiled.major, compiled.minor, compiled.patch));
	GLOUTPUT_REL(("SDL version linked:   %d.%d.%d\n", linked.major, linked.minor, linked.patch));
	GLASSERT((linked.major == compiled.major && linked.minor == compiled.minor));

	// SDL initialization steps.
	if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE | SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_EVENTS) < 0)
	{
		fprintf(stderr, "SDL initialization failed: %s\n", SDL_GetError());
		exit(1);
	}

	//  OpenGL 4.3 provides full compatibility with OpenGL ES 3.0.
	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
	SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);

#ifdef DEBUG
#if 0	// I was hoping to get to Angle on intel - may still be able to. But
	// as is this gets HW mode, which crashes in a function that should
	// be supported. The Intel drivers are so terrible. As of this writing,
	// you can't specify the DX version of ES:
	//		http://forums.libsdl.org/viewtopic.php?t=9770&highlight=angle+opengl
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);	// driver supports 2 and 3. Both crash.
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
#endif
#if 0
	// 3.0 context.
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
#endif
#if 0
	// The trickier 3.2 context.
	// No GL_QUADs anymore.
	// All the attributes need to be floats.
	// No ALPHA textures.
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
#endif
#if 0
	// In theory the minimum supported version:
	// has instancing, and modern shader syntax
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
#endif
#if 0
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
#endif
#endif

	if (multisample) {
		SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
		SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, multisample);
	}

	SDL_DisplayMode displayMode;
	SDL_GetCurrentDisplayMode(0, &displayMode);

	int screenX = displayMode.w / 8;
	int screenY = displayMode.h / 8;
	int screenWidth = displayMode.w * 3 / 4;
	int screenHeight = displayMode.h * 3 / 4;

	if (argc == 3) {
		screenWidth = atoi(argv[1]);
		screenHeight = atoi(argv[2]);
		if (screenWidth <= 0) screenWidth = SCREEN_WIDTH;
		if (screenHeight <= 0) screenHeight = SCREEN_HEIGHT;
	}

	restoreWidth = screenWidth;
	restoreHeight = screenHeight;

	SDL_Window *screen = SDL_CreateWindow("Altera",
		screenX, screenY, screenWidth, screenHeight,
		/*SDL_WINDOW_FULLSCREEN | */ SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
	GLASSERT(screen);
	SDL_GL_CreateContext(screen);

	int stencil = 0;
	int depth = 0;
	CHECK_GL_ERROR;
	SDL_GL_GetAttribute(SDL_GL_STENCIL_SIZE, &stencil);
	SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &depth);
	glGetError();	// the above stencil/depth query sometimes does throw an error.
	glGetError();	// 2 queries, 2 errors.
	CHECK_GL_ERROR;
	GLOUTPUT_REL(("SDL screen created. stencil=%d depthBits=%d\n", stencil, depth));

	/* Verify there is a surface */
	if (!screen) {
		fprintf(stderr, "Video mode set failed: %s\n", SDL_GetError());
		exit(1);
	}

	CHECK_GL_ERROR;
	glewExperimental = GL_TRUE;
	int r = glewInit();
	GLASSERT(r == GL_NO_ERROR);
	(void)r;

	while (glGetError() != GL_NO_ERROR) {
		// around again
	}
	CHECK_GL_ERROR;

	const unsigned char* vendor = glGetString(GL_VENDOR);
	const unsigned char* renderer = glGetString(GL_RENDERER);
	const unsigned char* version = glGetString(GL_VERSION);

	GLOUTPUT_REL(("OpenGL vendor: '%s'  Renderer: '%s'  Version: '%s'\n", vendor, renderer, version));
	CHECK_GL_ERROR;

	bool done = false;
	bool zooming = false;
	SDL_Event event;

	grinliz::Vector2I mouseDown = { 0, 0 };
	grinliz::Vector2I rightMouseDown = { 0, 0 };

	int zoomX = 0;
	int zoomY = 0;
	// Used to compute fingers close, but problems:
	// - really to the OS to do that, because of all the tuning
	// - the coordinates are in windows normalized, so can't get the physical distance reliably.
	//bool fingersClose = true;
	int nFingers = 0;

	void* game = NewGame(screenWidth, screenHeight, 0);

	int modKeys = SDL_GetModState();
	U32 tickTimer = 0, lastTick = 0, thisTick = 0;

#ifdef OUTPUT_MOUSE_AND_TOUCH
	int value = GetSystemMetrics(SM_DIGITIZER);
	if (value & NID_INTEGRATED_TOUCH) GLOUTPUT(("NID_INTEGRATED_TOUCH\n"));
	if (value & NID_MULTI_INPUT) GLOUTPUT(("NID_MULTI_INPUT\n"));
	if (value & NID_READY) GLOUTPUT(("NID_READY\n"));
#endif

	grinliz::Vector2F multiTouchStart = { 0, 0 };

	// ---- Main Loop --- //
	while (!done) {
		while (SDL_PollEvent(&event)) {

			switch (event.type)
			{
				case SDL_WINDOWEVENT:
				if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
					screenWidth = event.window.data1;
					screenHeight = event.window.data2;
					GameDeviceLoss(game);
					GameResize(game, screenWidth, screenHeight, 0);
				}
				break;

				case SDL_KEYUP:
				switch (event.key.keysym.scancode)
				{
					case SDL_SCANCODE_LCTRL:	modKeys = modKeys & (~KMOD_LCTRL);		break;
					case SDL_SCANCODE_RCTRL:	modKeys = modKeys & (~KMOD_RCTRL);		break;
					case SDL_SCANCODE_LSHIFT:	modKeys = modKeys & (~KMOD_LSHIFT);		break;
					case SDL_SCANCODE_RSHIFT:	modKeys = modKeys & (~KMOD_RSHIFT);		break;
					default:
					break;
				}
				break;

				case SDL_KEYDOWN:
				{
					// sym or scancode? I used a dvorak keyboard, so appreciate
					// every day the difference. However, AWSD support is the 
					// primary thing so scancode is hopefully the better choice.
					switch (event.key.keysym.scancode)
					{
						case SDL_SCANCODE_LCTRL:	modKeys = modKeys | KMOD_LCTRL;		break;
						case SDL_SCANCODE_RCTRL:	modKeys = modKeys | KMOD_RCTRL;		break;
						case SDL_SCANCODE_LSHIFT:	modKeys = modKeys | KMOD_LSHIFT;	break;
						case SDL_SCANCODE_RSHIFT:	modKeys = modKeys | KMOD_RSHIFT;	break;

						case SDL_SCANCODE_F4:
						{
							int sdlMod = SDL_GetModState();
							if (sdlMod & (KMOD_RALT | KMOD_LALT))
								done = true;
						}
						break;

						case SDL_SCANCODE_ESCAPE:	GameHotKey(game, GAME_HK_ESCAPE);			break;
						case SDL_SCANCODE_SPACE:	GameHotKey(game, GAME_HK_TOGGLE_PAUSE);		break;
						case SDL_SCANCODE_RETURN:	GameHotKey(game, GAME_HK_DEBUG_ACTION);		break;
						case SDL_SCANCODE_F1:	GameHotKey(game, GAME_HK_TOGGLE_DEBUG_TEXT);	break;
						case SDL_SCANCODE_F2:	GameHotKey(game, GAME_HK_TOGGLE_DEBUG_UI);		break;
							// F3: screenshot
						case SDL_SCANCODE_TAB:	GameHotKey(game, GAME_HK_CAMERA_TOGGLE);		break;
						case SDL_SCANCODE_HOME:	GameHotKey(game, GAME_HK_CAMERA_CORE);			break;
						case SDL_SCANCODE_END:	GameHotKey(game, GAME_HK_CAMERA_AVATAR);		break;
						case SDL_SCANCODE_PAGEUP:	GameHotKey(game, GAME_HK_TELEPORT_AVATAR);	break;

							//case SDLK_a: reserved
						case SDL_SCANCODE_B:	GameHotKey(game, GAME_HK_CHEAT_GOLD);			break;
						case SDL_SCANCODE_C:	GameHotKey(game, GAME_HK_ATTACH_CORE);			break;
							//case SDLK_d: reserved
						case SDL_SCANCODE_E:	GameHotKey(game, GAME_HK_CHEAT_ELIXIR);			break;
						case SDL_SCANCODE_H:	GameHotKey(game, GAME_HK_TOGGLE_PATHING);		break;
						case SDL_SCANCODE_I:	GameHotKey(game, GAME_HK_TOGGLE_AI_DEBUG);		break;
						case SDL_SCANCODE_K:	GameHotKey(game, GAME_HK_CHEAT_CRYSTAL);		break;
						case SDL_SCANCODE_M:	GameHotKey(game, GAME_HK_MAP);					break;
						case SDL_SCANCODE_P:	GameHotKey(game, GAME_HK_TOGGLE_PERF);			break;
						case SDL_SCANCODE_Q:	GameHotKey(game, GAME_HK_CHEAT_HERD);			break;
							//case SDLK_s: reserved
						case SDL_SCANCODE_T:	GameHotKey(game, GAME_HK_CHEAT_TECH);			break;
						case SDL_SCANCODE_U:	GameHotKey(game, GAME_HK_TOGGLE_UI);			break;
							//case SDLK_w: reserved

						case SDL_SCANCODE_1:	GameHotKey(game, GAME_HK_TOGGLE_GLOW);			break;
						case SDL_SCANCODE_2:	GameHotKey(game, GAME_HK_TOGGLE_PARTICLE);		break;
						case SDL_SCANCODE_3:	GameHotKey(game, GAME_HK_TOGGLE_VOXEL);			break;
						case SDL_SCANCODE_4:	GameHotKey(game, GAME_HK_TOGGLE_SHADOW);		break;
						case SDL_SCANCODE_5:	GameHotKey(game, GAME_HK_TOGGLE_BOLT);			break;

						case SDL_SCANCODE_F3:
						GameDoTick(game, SDL_GetTicks());
						SDL_GL_SwapWindow(screen);
						ScreenCapture();
						break;

						case SDL_SCANCODE_F11:
						{
							if (fullscreen) {
								// SDL_RestoreWindow doesn't seem to work as I expect.
								SDL_SetWindowFullscreen(screen, 0);
								SDL_SetWindowSize(screen, restoreWidth, restoreHeight);
								fullscreen = false;
							}
							else {
								restoreWidth = screenWidth;
								restoreHeight = screenHeight;
								SDL_SetWindowFullscreen(screen, SDL_WINDOW_FULLSCREEN_DESKTOP);
								fullscreen = true;
							}
						}
						break;

						default:
						break;
					}
				}
				break;

				case SDL_MOUSEBUTTONDOWN:
				{
					int x = event.button.x;
					int y = event.button.y;

					int mod = 0;
					if (modKeys & (KMOD_LSHIFT | KMOD_RSHIFT))    mod = GAME_TAP_MOD_SHIFT;
					else if (modKeys & (KMOD_LCTRL | KMOD_RCTRL)) mod = GAME_TAP_MOD_CTRL;

					if (nFingers > 1) {
						// do nothing
					}
					else if (event.button.button == SDL_BUTTON_LEFT) {
						#ifdef OUTPUT_MOUSE_AND_TOUCH
						GLOUTPUT(("Left mouse down %d %d\n", x, y));
						#endif
						mouseDown.Set(event.button.x, event.button.y);
						GameTap(game, GAME_TAP_DOWN, x, y, mod);
					}
					else if (event.button.button == SDL_BUTTON_RIGHT) {
						#ifdef OUTPUT_MOUSE_AND_TOUCH
						GLOUTPUT(("Right mouse down %d %d\n", x, y));
						#endif
						GameTap(game, GAME_TAP_CANCEL, x, y, mod);
						rightMouseDown.Zero();
						if (mod == 0) {
							rightMouseDown.Set(event.button.x, event.button.y);
							GameCameraPan(game, GAME_PAN_START, float(x), float(y));
						}
						else if (mod == GAME_TAP_MOD_CTRL) {
							zooming = true;
							//GameCameraRotate( game, GAME_ROTATE_START, 0.0f );
							SDL_GetRelativeMouseState(&zoomX, &zoomY);
						}
					}
				}
				break;

				case SDL_MOUSEBUTTONUP:
				{
					int x = event.button.x;
					int y = event.button.y;

					if (event.button.button == SDL_BUTTON_RIGHT) {
						#ifdef OUTPUT_MOUSE_AND_TOUCH
						GLOUTPUT(("Right mouse up %d %d\n", x, y));
						#endif
						zooming = false;
						if (!rightMouseDown.IsZero()) {
							GameCameraPan(game, GAME_PAN_END, float(x), float(y));
							rightMouseDown.Zero();
						}
					}
					if (event.button.button == SDL_BUTTON_LEFT) {
						if (!mouseDown.IsZero()) {	// filter out mouse events that become finger events.
							#ifdef OUTPUT_MOUSE_AND_TOUCH
							GLOUTPUT(("Left mouse up %d %d\n", x, y));
							#endif
							int mod = 0;
							if (modKeys & (KMOD_LSHIFT | KMOD_RSHIFT))    mod = GAME_TAP_MOD_SHIFT;
							else if (modKeys & (KMOD_LCTRL | KMOD_RCTRL)) mod = GAME_TAP_MOD_CTRL;
							GameTap(game, GAME_TAP_UP, x, y, mod);
						}
					}
				}
				break;

				case SDL_MOUSEMOTION:
				{
					SDL_GetRelativeMouseState(&zoomX, &zoomY);
					int state = event.motion.state;
					int x = event.motion.x;
					int y = event.motion.y;

					int mod = 0;
					if (modKeys & (KMOD_LSHIFT | KMOD_RSHIFT))    mod = GAME_TAP_MOD_SHIFT;
					else if (modKeys & (KMOD_LCTRL | KMOD_RCTRL)) mod = GAME_TAP_MOD_CTRL;

					if (nFingers > 1) {
						// Do nothing.
						// Multi touch in progress.
					}
					else if (state & SDL_BUTTON(SDL_BUTTON_LEFT)) {
						if (!mouseDown.IsZero()) {
							#ifdef OUTPUT_MOUSE_AND_TOUCH
							GLOUTPUT(("Left Mouse move %d %d\n", x, y));
							#endif
							GameTap(game, GAME_TAP_MOVE, x, y, mod);
//							mouseMoveCount = 0;
						}
					}
					else if (!rightMouseDown.IsZero()) {
						GLASSERT(state & SDL_BUTTON(SDL_BUTTON_RIGHT));
						GameCameraPan(game, GAME_PAN_END, float(x), float(y));
					}
					else if (zooming && (state & SDL_BUTTON(SDL_BUTTON_RIGHT))) {
						float deltaZoom = 0.01f * (float)zoomY;
						GameZoom(game, GAME_ZOOM_DISTANCE, deltaZoom);
						GameCameraRotate(game, (float)(zoomX)*0.5f);
					}
					else if (state ==0) {
						GameTap(game, GAME_MOVE_WHILE_UP, x, y, mod);
					}
				}
				break;

				case SDL_MOUSEWHEEL:
				{
					if (event.wheel.y) {
						float deltaZoom = -0.1f * float(event.wheel.y);
						GameZoom(game, GAME_ZOOM_DISTANCE, deltaZoom);
					}
				}
				break;

				case SDL_FINGERUP:
				{
					const SDL_TouchFingerEvent* tfe = &event.tfinger;
					nFingers = SDL_GetNumTouchFingers(tfe->touchId);
					if (nFingers < 2 && !multiTouchStart.IsZero()) {
						#ifdef OUTPUT_MOUSE_AND_TOUCH
						GLOUTPUT(("2 finger END.\n"));
						#endif
						multiTouchStart.Zero();
					}
				}
				break;

				case SDL_FINGERDOWN:
				{
					const SDL_TouchFingerEvent* tfe = &event.tfinger;
					nFingers = SDL_GetNumTouchFingers(tfe->touchId);
					if (nFingers > 1) {
						if (!mouseDown.IsZero()) {
							// Wrap up the existing action.
							#ifdef OUTPUT_MOUSE_AND_TOUCH
							GLOUTPUT(("Switch to gesture.\n"));
							#endif
							mouseDown.Zero();
						}
					}
				}
				break;

				case SDL_MULTIGESTURE:
				{
					const SDL_MultiGestureEvent* mge = &event.mgesture;
					nFingers = SDL_GetNumTouchFingers(mge->touchId);
					if (nFingers > 1 && multiTouchStart.IsZero()) {
						#ifdef OUTPUT_MOUSE_AND_TOUCH
						GLOUTPUT(("2 finger START.\n"));
						#endif
						multiTouchStart.Set(mge->x, mge->y);
					}
					else if (!multiTouchStart.IsZero()) {
						// The Pan interacts badly with zoom and rotated. So instead of a continuous,
						// multi-event action do a bunch of "mini pans".
						GameCameraPan(game, GAME_PAN_START,
									  multiTouchStart.x * float(screenWidth), multiTouchStart.y*float(screenHeight));
						multiTouchStart.Set(mge->x, mge->y);
						GameCameraPan(game, GAME_PAN_MOVE,
									  multiTouchStart.x * float(screenWidth), multiTouchStart.y*float(screenHeight));
						GameCameraPan(game, GAME_PAN_END,
									  multiTouchStart.x * float(screenWidth), multiTouchStart.y*float(screenHeight));
					}

					if (nFingers == 2) {
						GameZoom(game, GAME_ZOOM_DISTANCE, -mge->dDist * 10.f);
						GameCameraRotate(game, -mge->dTheta * 100.0f);
						//GLOUTPUT(("MultiGestureEvent dTheta=%.4f dDist=%.4f x=%.4f y=%.4f nFing=%d\n", mge->dTheta, mge->dDist, mge->x, mge->y, mge->numFingers));
					}
				}
				break;

				case SDL_DOLLARGESTURE:
				{
					GLOUTPUT(("DollarGestureEvent\n"));
				}
				break;


				case SDL_QUIT:
				{
					done = true;
				}
				break;

				default:
				break;
			}
		}
		U32 delta = SDL_GetTicks() - tickTimer;
		if (delta < TIME_BETWEEN_FRAMES) {
			SDL_Delay(1);
			continue;
		}
		tickTimer = SDL_GetTicks();
		glEnable(GL_DEPTH_TEST);
		glDepthFunc(GL_LEQUAL);

		const U8* keys = SDL_GetKeyboardState(0);
		U32 tickDelta = thisTick - lastTick;
		if (tickDelta > 100) tickDelta = 100;

		float keyMoveSpeed = KEY_MOVE_SPEED * float(tickDelta) / float(TIME_BETWEEN_FRAMES);
		float keyZoomSpeed = KEY_ZOOM_SPEED * float(tickDelta) / float(TIME_BETWEEN_FRAMES);
		float keyRotatepeed = KEY_ROTATE_SPEED * float(tickDelta) / float(TIME_BETWEEN_FRAMES);

		if (keys[SDL_SCANCODE_DOWN] || keys[SDL_SCANCODE_S]) {
			if (modKeys & KMOD_CTRL)
				GameZoom(game, GAME_ZOOM_DISTANCE, keyZoomSpeed);
			else
				GameCameraMove(game, 0, -keyMoveSpeed);
		}
		if (keys[SDL_SCANCODE_UP] || keys[SDL_SCANCODE_W]) {
			if (modKeys & KMOD_CTRL)
				GameZoom(game, GAME_ZOOM_DISTANCE, -keyZoomSpeed);
			else
				GameCameraMove(game, 0, keyMoveSpeed);
		}
		if (keys[SDL_SCANCODE_LEFT] || keys[SDL_SCANCODE_A]) {
			if (modKeys & KMOD_CTRL)
				GameCameraRotate(game, keyRotatepeed);
			else
				GameCameraMove(game, -keyMoveSpeed, 0);
		}
		if (keys[SDL_SCANCODE_RIGHT] || keys[SDL_SCANCODE_D]) {
			if (modKeys & KMOD_CTRL)
				GameCameraRotate(game, -keyRotatepeed);
			else
				GameCameraMove(game, keyMoveSpeed, 0);
		}

		if (game) {
			lastTick = thisTick;
			thisTick = SDL_GetTicks();
			PROFILE_BLOCK(GameDoTick);
			GameDoTick(game, thisTick);
		}
		{
			PROFILE_BLOCK(Swap);
			SDL_GL_SwapWindow(screen);
		}
	}

	GameSave(game);
	DeleteGame(game);

	for (int i = 0; i < nModDB; ++i) {
		delete databases[i];
	}

	SDL_Quit();

#if SEND_CRASH_LOGS
	// Empty the file - quit went just fine.
	{
		FILE* fp = FOpen( "UFO_Running.txt", "w" );
		if ( fp )
			fclose( fp );
	}
#endif

	MemLeakCheck();
	return 0;
}
示例#17
0
SDL_Surface* KrEncoder::Load32Surface(	const char* filename,
										Transparent* trans,
										int nTrans,
										gedString* error )
{
	// Make sure SetImageLoader has been called!
	GLASSERT( ImageLoader );
	if ( !ImageLoader )
	{
		return 0;
	}

	if ( !filename )
	{
		if ( error ) *error = "No filename for a surface specified";
		#ifdef DEBUG
			GLOUTPUT( "No filename for a surface specified\n" );
		#endif
		return 0;
	}

	// Try to load the file.
	SDL_Surface* surface = ImageLoader( filename );
	if ( !surface )
	{
		char buf[256];
		sprintf( buf, "Failed to load surface '%s'.", filename );

		if ( error ) *error = buf;
		#ifdef DEBUG
			GLOUTPUT( "No filename for a surface specified\n" );
		#endif
		return 0;
	}

	// The image can be 32 bits or less. A NON-32 bit image has
	// color(s) that are marked transparent. A 32 bit image
	// simply uses the alpha channel. To simplify things,
	// images are converted to 32 bit before they
	// are returned.
	// 
	// Oddly, SDL_Image will sometimes return a 32 bit image,
	// when it wasn't. This will *really* screw up kyra.

	if ( surface->format->BytesPerPixel < 4 )
	{
		SDL_Surface* s32 = SDL_CreateRGBSurface(	SDL_SWSURFACE,
													surface->w,
													surface->h,
													32,
													0xff000000,
													0x00ff0000,
													0x0000ff00,
													0x000000ff );
		GLASSERT( s32 );
		#ifdef DEBUG
			GLOUTPUT( "Creating 32 bit SDL surface.\n" );
		#endif

		// Now copy one surface to the other, 
		// set transparency as needed afterwards.
		SDL_BlitSurface( surface, 0, s32, 0 );
		
		int i;
		KrPainter painter( s32 );

		// Covert color keys to RGB values.
		for ( i=0; i<nTrans; i++ )
		{
			if ( trans[i].type != RGBA )
			{
				switch( trans[i].type )
				{
					case LowerLeft:
						painter.BreakPixel( 0, surface->h - 1, &trans[i].rgba );
						break;
					case UpperLeft:
						painter.BreakPixel( 0, 0, &trans[i].rgba );
						break;
					case LowerRight:
						painter.BreakPixel( surface->w - 1, surface->h - 1, &trans[i].rgba );
						break;
					case UpperRight:
						painter.BreakPixel( surface->w - 1, 0, &trans[i].rgba );
						break;
					default:
						GLASSERT( 0 );
				}
			}
		}

		// Now set the transparency. 
		int x, y;
		int nTransPixels = 0;

		for( x=0; x<surface->w; x++ )
		{
			for( y=0; y<surface->h; y++ )
			{
				KrRGBA rgba;
				painter.BreakPixel( x, y, &rgba );

				for ( i=0; i<nTrans; i++ )
				{
					if (	rgba.c.red   == trans[i].rgba.c.red 
						 && rgba.c.green == trans[i].rgba.c.green
						 && rgba.c.blue  == trans[i].rgba.c.blue )
					{
						rgba.c.alpha = KrRGBA::KR_TRANSPARENT;

						// Set the surface alpha to transparent.
						painter.SetPixel( x, y, rgba );
						nTransPixels++;
						break;
					}
				}
			}
		}

		#ifdef DEBUG
			GLOUTPUT( "Transparency converted=%d\n", nTransPixels );
		#endif
		SDL_FreeSurface( surface );
		return s32;
	}
	return surface;
}