| 1 | /* |
|---|
| 2 | * Filename : simulation.cpp |
|---|
| 3 | * Author(s) : Chris Thielen (chris@luethy.net) |
|---|
| 4 | * Date Created : July 2006 |
|---|
| 5 | * Last Modified : Tuesday, June 23, 2009 |
|---|
| 6 | * Purpose : Contains the main game loop |
|---|
| 7 | * Notes : |
|---|
| 8 | */ |
|---|
| 9 | |
|---|
| 10 | #include "common.h" |
|---|
| 11 | #include "Engine/hud.h" |
|---|
| 12 | #include "Engine/simulation.h" |
|---|
| 13 | #include "Engine/alliances.h" |
|---|
| 14 | #include "Engine/starfield.h" |
|---|
| 15 | #include "Graphics/video.h" |
|---|
| 16 | #include "includes.h" |
|---|
| 17 | #include "Input/input.h" |
|---|
| 18 | #include "Sprites/player.h" |
|---|
| 19 | #include "Sprites/spritemanager.h" |
|---|
| 20 | #include "UI/ui.h" |
|---|
| 21 | #include "Utilities/camera.h" |
|---|
| 22 | #include "Utilities/log.h" |
|---|
| 23 | #include "Utilities/timer.h" |
|---|
| 24 | #include "Utilities/lua.h" |
|---|
| 25 | #include "AI/ai.h" |
|---|
| 26 | |
|---|
| 27 | float Simulation::currentFPS = 0.; |
|---|
| 28 | |
|---|
| 29 | Simulation::Simulation( void ) { |
|---|
| 30 | engines = Engines::Instance(); |
|---|
| 31 | planets = Planets::Instance(); |
|---|
| 32 | models = Models::Instance(); |
|---|
| 33 | alliances = Alliances::Instance(); |
|---|
| 34 | currentFPS = 0.; |
|---|
| 35 | } |
|---|
| 36 | |
|---|
| 37 | Simulation::Simulation( string filename ) { |
|---|
| 38 | engines = Engines::Instance(); |
|---|
| 39 | planets = Planets::Instance(); |
|---|
| 40 | models = Models::Instance(); |
|---|
| 41 | alliances = Alliances::Instance(); |
|---|
| 42 | currentFPS = 0.; |
|---|
| 43 | |
|---|
| 44 | this->filename = filename; |
|---|
| 45 | |
|---|
| 46 | Parse(); |
|---|
| 47 | } |
|---|
| 48 | |
|---|
| 49 | bool Simulation::Load( string filename ) { |
|---|
| 50 | this->filename = filename; |
|---|
| 51 | |
|---|
| 52 | return Parse(); |
|---|
| 53 | } |
|---|
| 54 | |
|---|
| 55 | bool Simulation::Run( void ) { |
|---|
| 56 | bool quit = false; |
|---|
| 57 | Input inputs; |
|---|
| 58 | int fpsCount = 0; // for FPS calculations |
|---|
| 59 | Uint32 fpsTS = 0; // timestamp |
|---|
| 60 | |
|---|
| 61 | // Grab the camera and give it coordinates |
|---|
| 62 | Camera *camera = Camera::Instance(); |
|---|
| 63 | camera->Focus(0, 0); |
|---|
| 64 | |
|---|
| 65 | // Generate a starfield |
|---|
| 66 | Starfield starfield( OPTION(int, "options/simulation/starfield-density") ); |
|---|
| 67 | |
|---|
| 68 | // Create a spritelist |
|---|
| 69 | SpriteManager sprites; |
|---|
| 70 | |
|---|
| 71 | Player *player = Player::Instance(); |
|---|
| 72 | |
|---|
| 73 | // Set player model based on simulation xml file settings |
|---|
| 74 | player->SetModel( models->GetModel( playerDefaultModel ) ); |
|---|
| 75 | sprites.Add( player->GetSprite() ); |
|---|
| 76 | |
|---|
| 77 | // Focus the camera on the sprite |
|---|
| 78 | camera->Focus( player->GetSprite() ); |
|---|
| 79 | |
|---|
| 80 | // Add the planets |
|---|
| 81 | planets->RegisterAll( &sprites ); |
|---|
| 82 | |
|---|
| 83 | // Start the Lua Universe |
|---|
| 84 | Lua::SetSpriteList( &sprites ); |
|---|
| 85 | Lua::Load("Lua/scripts/universe.lua"); |
|---|
| 86 | |
|---|
| 87 | // Ensure correct drawing order |
|---|
| 88 | sprites.Order(); |
|---|
| 89 | |
|---|
| 90 | |
|---|
| 91 | // Create the hud |
|---|
| 92 | Hud::Hud(); |
|---|
| 93 | |
|---|
| 94 | Hud::Alert( "Captain, we don't have the power! Pow = %d", 3 ); |
|---|
| 95 | |
|---|
| 96 | fpsTS = Timer::GetTicks(); |
|---|
| 97 | // main game loop |
|---|
| 98 | while( !quit ) { |
|---|
| 99 | quit = inputs.Update(); |
|---|
| 100 | Lua::Update(); |
|---|
| 101 | |
|---|
| 102 | // Erase cycle |
|---|
| 103 | Video::Erase(); |
|---|
| 104 | |
|---|
| 105 | // Update cycle |
|---|
| 106 | starfield.Update(); |
|---|
| 107 | camera->Update(); |
|---|
| 108 | sprites.Update(); |
|---|
| 109 | camera->Update(); |
|---|
| 110 | Hud::Update(); |
|---|
| 111 | UI::Run(); // runs only a few loops |
|---|
| 112 | |
|---|
| 113 | // Keep this last (I think) |
|---|
| 114 | Timer::Update(); |
|---|
| 115 | |
|---|
| 116 | // Draw cycle |
|---|
| 117 | starfield.Draw(); |
|---|
| 118 | sprites.Draw(); |
|---|
| 119 | Hud::Draw( sprites ); |
|---|
| 120 | UI::Draw(); |
|---|
| 121 | Video::Update(); |
|---|
| 122 | |
|---|
| 123 | // Don't kill the CPU (play nice) |
|---|
| 124 | Timer::Delay(); |
|---|
| 125 | |
|---|
| 126 | Coordinate playerPos = player->GetWorldPosition(); |
|---|
| 127 | |
|---|
| 128 | // Update FPS |
|---|
| 129 | fpsCount++; |
|---|
| 130 | |
|---|
| 131 | if((fpsTS + 1000) <= Timer::GetTicks()) { |
|---|
| 132 | Simulation::currentFPS = (float)fpsCount / (float)(Timer::GetTicks() - fpsTS); |
|---|
| 133 | fpsTS = Timer::GetTicks(); |
|---|
| 134 | fpsCount = 0; |
|---|
| 135 | } |
|---|
| 136 | } |
|---|
| 137 | |
|---|
| 138 | return true; |
|---|
| 139 | } |
|---|
| 140 | |
|---|
| 141 | float Simulation::GetFPS() { |
|---|
| 142 | return Simulation::currentFPS; |
|---|
| 143 | } |
|---|
| 144 | |
|---|
| 145 | bool Simulation::Parse( void ) { |
|---|
| 146 | xmlDocPtr doc; |
|---|
| 147 | xmlNodePtr cur; |
|---|
| 148 | int versionMajor = 0, versionMinor = 0, versionMacro = 0; |
|---|
| 149 | |
|---|
| 150 | doc = xmlParseFile( filename.c_str() ); |
|---|
| 151 | |
|---|
| 152 | if( doc == NULL ) { |
|---|
| 153 | Log::Warning( "Could not load '%s' simulation file.", filename.c_str() ); |
|---|
| 154 | return false; |
|---|
| 155 | } |
|---|
| 156 | |
|---|
| 157 | cur = xmlDocGetRootElement( doc ); |
|---|
| 158 | |
|---|
| 159 | if( cur == NULL ) { |
|---|
| 160 | Log::Warning( "'%s' file appears to be empty.", filename.c_str() ); |
|---|
| 161 | xmlFreeDoc( doc ); |
|---|
| 162 | return false; |
|---|
| 163 | } |
|---|
| 164 | |
|---|
| 165 | if( xmlStrcmp( cur->name, (const xmlChar *)"simulation" ) ) { |
|---|
| 166 | Log::Warning( "'%s' appears to be invalid. Root element was %s.", filename.c_str(), (char *)cur->name ); |
|---|
| 167 | xmlFreeDoc( doc ); |
|---|
| 168 | return false; |
|---|
| 169 | } else { |
|---|
| 170 | Log::Message( "'%s' file found and valid, parsing...", filename.c_str() ); |
|---|
| 171 | } |
|---|
| 172 | |
|---|
| 173 | cur = cur->xmlChildrenNode; |
|---|
| 174 | while( cur != NULL ) { |
|---|
| 175 | // Parse for the version information and any children nodes |
|---|
| 176 | if( ( !xmlStrcmp( cur->name, (const xmlChar *)"version-major" ) ) ) { |
|---|
| 177 | xmlChar *key = xmlNodeListGetString( doc, cur->xmlChildrenNode, 1 ); |
|---|
| 178 | versionMajor = atoi( (char *)key ); |
|---|
| 179 | xmlFree( key ); |
|---|
| 180 | } else if( ( !xmlStrcmp( cur->name, (const xmlChar *)"version-minor" ) ) ) { |
|---|
| 181 | xmlChar *key = xmlNodeListGetString( doc, cur->xmlChildrenNode, 1 ); |
|---|
| 182 | versionMinor = atoi( (char *)key ); |
|---|
| 183 | xmlFree( key ); |
|---|
| 184 | } else if( ( !xmlStrcmp( cur->name, (const xmlChar *)"version-macro" ) ) ) { |
|---|
| 185 | xmlChar *key = xmlNodeListGetString( doc, cur->xmlChildrenNode, 1 ); |
|---|
| 186 | versionMacro = atoi( (char *)key ); |
|---|
| 187 | xmlFree( key ); |
|---|
| 188 | } else { |
|---|
| 189 | char *sectionName = (char *)cur->name; |
|---|
| 190 | |
|---|
| 191 | if( !strcmp( sectionName, "planets" ) ) { |
|---|
| 192 | xmlChar *key = xmlNodeListGetString( doc, cur->xmlChildrenNode, 1 ); |
|---|
| 193 | planetsFilename = (char *)key; |
|---|
| 194 | xmlFree( key ); |
|---|
| 195 | Log::Message( "Planets filename is %s.", planetsFilename.c_str() ); |
|---|
| 196 | } |
|---|
| 197 | if( !strcmp( sectionName, "models" ) ) { |
|---|
| 198 | xmlChar *key = xmlNodeListGetString( doc, cur->xmlChildrenNode, 1 ); |
|---|
| 199 | modelsFilename = (char *)key; |
|---|
| 200 | xmlFree( key ); |
|---|
| 201 | Log::Message( "Models filename is %s.", modelsFilename.c_str() ); |
|---|
| 202 | } |
|---|
| 203 | if( !strcmp( sectionName, "engines" ) ) { |
|---|
| 204 | xmlChar *key = xmlNodeListGetString( doc, cur->xmlChildrenNode, 1 ); |
|---|
| 205 | enginesFilename = (char *)key; |
|---|
| 206 | xmlFree( key ); |
|---|
| 207 | Log::Message( "Engines filename is %s.", enginesFilename.c_str() ); |
|---|
| 208 | } |
|---|
| 209 | if( !strcmp( sectionName, "alliances" ) ) { |
|---|
| 210 | xmlChar *key = xmlNodeListGetString( doc, cur->xmlChildrenNode, 1 ); |
|---|
| 211 | alliancesFilename = (char *)key; |
|---|
| 212 | xmlFree( key ); |
|---|
| 213 | Log::Message( "Alliances filename is %s.", alliancesFilename.c_str() ); |
|---|
| 214 | } |
|---|
| 215 | if( !strcmp( sectionName, "playerDefaultModel" ) ) { |
|---|
| 216 | xmlChar *key = xmlNodeListGetString( doc, cur->xmlChildrenNode, 1 ); |
|---|
| 217 | playerDefaultModel = (char *)key; |
|---|
| 218 | xmlFree( key ); |
|---|
| 219 | Log::Message( "playerDefaultModel is %s.", playerDefaultModel.c_str() ); |
|---|
| 220 | } |
|---|
| 221 | } |
|---|
| 222 | |
|---|
| 223 | cur = cur->next; |
|---|
| 224 | } |
|---|
| 225 | |
|---|
| 226 | xmlFreeDoc( doc ); |
|---|
| 227 | |
|---|
| 228 | Log::Message( "'%s' parsing done. File is version %d.%d.%d.", filename.c_str(), versionMajor, versionMinor, versionMacro ); |
|---|
| 229 | |
|---|
| 230 | // Now load the various subsystems |
|---|
| 231 | if( planets->Load( planetsFilename ) != true ) { |
|---|
| 232 | Log::Warning( "There was an error loading the planets from '%s'.", planetsFilename.c_str() ); |
|---|
| 233 | } |
|---|
| 234 | if( engines->Load( enginesFilename ) != true ) { |
|---|
| 235 | Log::Error( "There was an error loading the engines from '%s'.", enginesFilename.c_str() ); |
|---|
| 236 | } |
|---|
| 237 | if( models->Load( modelsFilename ) != true ) { |
|---|
| 238 | Log::Error( "There was an error loading the models from '%s'.", modelsFilename.c_str() ); |
|---|
| 239 | } |
|---|
| 240 | if( alliances->Load( alliancesFilename ) != true ) { |
|---|
| 241 | Log::Error( "There was an error loading the alliances from '%s'.", alliancesFilename.c_str() ); |
|---|
| 242 | } |
|---|
| 243 | |
|---|
| 244 | return true; |
|---|
| 245 | } |
|---|