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(); }
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 ); }
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 ); } }
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] ); } }
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(); }
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; }
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; }
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; }
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; }
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 }
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 ); }
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; }
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 }
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(); } }
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; }
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; }
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; }