示例#1
0
/**
**  Show a title image
*/
void TitleScreen::ShowTitleImage()
{
	const EventCallback *old_callbacks = GetCallbacks();
	EventCallback callbacks;

	WaitNoEvent = true;

	callbacks.ButtonPressed = WaitCallbackButtonPressed;
	callbacks.ButtonReleased = WaitCallbackButtonReleased;
	callbacks.MouseMoved = WaitCallbackMouse;
	callbacks.MouseExit = WaitCallbackExit;
	callbacks.KeyPressed = WaitCallbackKeyPressed;
	callbacks.KeyReleased = WaitCallbackKeyReleased;
	callbacks.KeyRepeated = WaitCallbackKeyRepeated;
	//callbacks.NetworkEvent = NetworkEvent;
	callbacks.NetworkEvent = nullptr;

	SetCallbacks(&callbacks);

	CGraphic *g = CGraphic::New(this->File);
	g->Load();
	if (this->StretchImage) {
		g->Resize(Video.Width, Video.Height);
	}

	int timeout = this->Timeout ? this->Timeout * CYCLES_PER_SECOND : -1;

	while (timeout-- && WaitNoEvent) {
		g->DrawClip((Video.Width - g->Width) / 2, (Video.Height - g->Height) / 2);
		this->ShowLabels();

		Invalidate();
		RealizeVideoMemory();
		WaitEventsOneFrame();
	}

	SetCallbacks(old_callbacks);
	CGraphic::Free(g);
}
示例#2
0
/**
**  Game main loop.
**
**  Unit actions.
**  Missile actions.
**  Players (AI).
**  Cyclic events (color cycle,...)
**  Display update.
**  Input/Network/Sound.
*/
void GameMainLoop(void)
{
	int player;
	const EventCallback *old_callbacks;

	InitGameCallbacks();

	old_callbacks = GetCallbacks();
	SetCallbacks(&GameCallbacks);

	SetVideoSync();
	GameCursor = UI.Point.Cursor;
	GameRunning = true;

	CParticleManager::init();

	MultiPlayerReplayEachCycle();

	CclCommand("GameStarting()");

	std::ofstream output;
	std::wstring templ;
	firstClock = std::clock();
        templateClock = 0;
	int messageNumber = 1;
	std::ofstream outputEventsPerSec;
	std::ofstream outputNT;
	outputEventsPerSec.open("/tmp/boswarseventspersec.csv",std::ios::out);
   	outputNT.open("/tmp/boswarsclocksperevents.csv",std::ios::out);

	output.open("/tmp/beepbeep.fifo",std::ios::out);

	templ = templ = L"<message>\n"
				L"  <units>\n"
				    L"{% for unit in units.tabunits %}"
				    L"  <unit>\n"
				    L"    <id>{$unit.id}</id>\n"
				    L"    <type>{$unit.type}</type>\n"
				    L"    <isbuilding>{$unit.isbuilding}</isbuilding>\n"
				    L"    <player>{$unit.player}</player>\n"
				    L"    <order>\n"
				    L"      <action>{$unit.action}</action>\n"
				    L"      <goal>{$unit.goal}</goal>\n"
				    L"    </order>\n"
				    L"    <neworder>\n"
				    L"       <action>{$unit.neworder}</action>\n"
				    L"       <goal>{$unit.newgoal}</goal>\n"
				    L"    </neworder>\n"
				    L"  </unit>\n"
				    L"{% endfor %}"
             		   	L"  </units>\n"
				L"<overhead>{$overhead}</overhead>\n"
            		L"</message>\n"; 

	

	while (GameRunning) {

		// Can't find a better place.
		SaveGameLoading = false;
		//
		// Game logic part
		//
		if (!GamePaused && NetworkInSync && !SkipGameCycle) {
			SinglePlayerReplayEachCycle();
			++GameCycle;
			MultiPlayerReplayEachCycle();
			NetworkCommands();  // Get network commands
			UnitActions();      // handle units
			MissileActions();   // handle missiles
			PlayersEachCycle(); // handle players
			UpdateTimer();      // update game timer

			//
			// Work todo each second.
			// Split into different frames, to reduce cpu time.
			// Increment mana of magic units.
			// Update mini-map.
			// Update map fog of war.
			// Call AI.
			// Check game goals.
			// Check rescue of units.
			//
			switch (GameCycle % CYCLES_PER_SECOND) {
				case 0: // At cycle 0, start all ai players...
					if (GameCycle == 0) {
						for (player = 0; player < NumPlayers; ++player) {
							PlayersEachSecond(player);
						}
					}
					break;
				case 1:
					break;
				case 2:
					break;
				case 3: // minimap update
					UI.Minimap.Update();
					break;
				case 4:
					break;
				case 5:
					break;
				case 6: // overtaking units
					RescueUnits();
					break;
				default:
					// FIXME: assume that NumPlayers < (CYCLES_PER_SECOND - 7)
					player = (GameCycle % CYCLES_PER_SECOND) - 7;
					Assert(player >= 0);
					if (player < NumPlayers) {
						PlayersEachSecond(player);
					}
			}

			////////////GET INFORMATION FOR MONITORING!!!////////////////////
			
						

			if(NumUnits > 0)
			{
				std::clock_t littleClock = std::clock();
	
				cpptempl::data_list theUnits;
		    
		    		std::stringstream ss;

				for(int i = 0; i < NumUnits; i++)
				{
					cpptempl::data_map uni;

					/////////ID/////////
					ss.str("");
					ss << Units[i]->Slot;
					std::string theID = ss.str();
					std::wstring wTheID;
					wTheID.assign(theID.begin(),theID.end());
					uni[L"id"] = cpptempl::make_data(wTheID);

					//////UNITTYPE//////
					ss.str("");
					ss << Units[i]->Type->Name;
					std::string theType = ss.str();
					std::wstring wTheType;
					wTheType.assign(theType.begin(),theType.end());
					uni[L"type"] = cpptempl::make_data(wTheType);

					//////ISBUILDING//////
					ss.str("");
					if (Units[i]->Type->Building == 1)
						ss << "true";
					else
						ss << "false";
					std::string theIsBuilding = ss.str();
					std::wstring wTheIsBuilding;
					wTheIsBuilding.assign(theIsBuilding.begin(),theIsBuilding.end());
					uni[L"isbuilding"] = cpptempl::make_data(wTheIsBuilding);

					//////PLAYER//////
					ss.str("");
					ss << Units[i]->Player;
					std::string thePlayer = ss.str();
					std::wstring wThePlayer;
					wThePlayer.assign(thePlayer.begin(),thePlayer.end());
					uni[L"player"] = cpptempl::make_data(wThePlayer);

					//////UnitAction//////
					ss.str("");
					switch(Units[i]->Orders[0]->Action)
					{
					  	case UnitActionNone: ss << "UnitActionNone"; break;
						case UnitActionStill: ss << "UnitActionStill"; break;  
						case UnitActionStandGround: ss << "UnitActionStandGround"; break;
						case UnitActionFollow: ss << "UnitActionFollow"; break;    
						case UnitActionMove: ss << "UnitActionMove"; break;      
						case UnitActionAttack: ss << "UnitActionAttack"; break;   
						case UnitActionAttackGround: ss << "UnitActionAttackGround"; break;
						case UnitActionDie: ss << "UnitActionDie"; break;     

						case UnitActionSpellCast: ss << "UnitActionSpellCast"; break; 

						case UnitActionTrain: ss << "UnitActionTrain"; break;  
						case UnitActionBuilt: ss << "UnitActionBuilt"; break;   
						case UnitActionBoard: ss << "UnitActionBoard"; break;    
						case UnitActionUnload: ss << "UnitActionUnload"; break; 
						case UnitActionPatrol: ss << "UnitActionPatrol"; break; 
						case UnitActionBuild: ss << "UnitActionBuild"; break;

						case UnitActionRepair: ss << "UnitActionRepair"; break; 
						case UnitActionResource: ss << "UnitActionResource"; break;
						default: ss << "None";  
					}

					std::string theAction = ss.str();
					std::wstring wTheAction;
					wTheAction.assign(theAction.begin(),theAction.end());
					uni[L"action"] = cpptempl::make_data(wTheAction);

					//////UnitGoal//////
					ss.str("");
					if(Units[i]->Orders[0]->Goal != NULL)
						ss << Units[i]->Orders[0]->Goal->Slot;
					else
						ss << "None";
					std::string theGoal = ss.str();
					std::wstring wTheGoal;
					wTheGoal.assign(theGoal.begin(),theGoal.end());
					uni[L"goal"] = cpptempl::make_data(wTheGoal);

					///////NEW ORDER/////////
					ss.str("");
					switch(Units[i]->NewOrder.Action)
					{
					  	case UnitActionNone: ss << "UnitActionNone"; break;
						case UnitActionStill: ss << "UnitActionStill"; break;  
						case UnitActionStandGround: ss << "UnitActionStandGround"; break;
						case UnitActionFollow: ss << "UnitActionFollow"; break;    
						case UnitActionMove: ss << "UnitActionMove"; break;      
						case UnitActionAttack: ss << "UnitActionAttack"; break;   
						case UnitActionAttackGround: ss << "UnitActionAttackGround"; break;
						case UnitActionDie: ss << "UnitActionDie"; break;     

						case UnitActionSpellCast: ss << "UnitActionSpellCast"; break; 

						case UnitActionTrain: ss << "UnitActionTrain"; break;  
						case UnitActionBuilt: ss << "UnitActionBuilt"; break;   
						case UnitActionBoard: ss << "UnitActionBoard"; break;    
						case UnitActionUnload: ss << "UnitActionUnload"; break; 
						case UnitActionPatrol: ss << "UnitActionPatrol"; break; 
						case UnitActionBuild: ss << "UnitActionBuild"; break;

						case UnitActionRepair: ss << "UnitActionRepair"; break; 
						case UnitActionResource: ss << "UnitActionResource"; break;
						default: ss << "None";  
					}

					std::string theNewOrder = ss.str();
					std::wstring wTheNewOrder;
					wTheNewOrder.assign(theNewOrder.begin(),theNewOrder.end());
					uni[L"neworder"] = cpptempl::make_data(wTheNewOrder);

					//////NEW GOAL//////
					ss.str("");
					if(Units[i]->NewOrder.Goal != NULL)
						ss << Units[i]->NewOrder.Goal->Slot;
					else
						ss << "None";
					std::string theNewGoal = ss.str();
					std::wstring wTheNewGoal;
					wTheNewGoal.assign(theNewGoal.begin(),theNewGoal.end());
					uni[L"newgoal"] = cpptempl::make_data(wTheNewGoal);
			
					theUnits.push_back((cpptempl::make_data(uni)));
				}
				

				cpptempl::data_map lesUnits;
		    		lesUnits[L"tabunits"] = cpptempl::make_data(theUnits);

				// Now set this in the data map
				cpptempl::data_map data;
				data[L"units"] = cpptempl::make_data(lesUnits);

				//////////////////TIMESTAMP/////////////////////////
				std::clock_t t = std::clock() - firstClock;
				double timeStamp = ((double)t/(double)CLOCKS_PER_SEC);
				ss.str("");
				ss << std::setprecision(8) << timeStamp;
				std::string sTimeStamp = ss.str();
				std::string gnuPlotStringT = ss.str();
				std::wstring wTimeStamp;
				wTimeStamp.assign(sTimeStamp.begin(),sTimeStamp.end());
				data[L"timestamp"] = cpptempl::make_data(wTimeStamp);

				///OVERHEAD/////
				templateClock += std::clock()-littleClock;
				long double overhead = (long double)templateClock / ((long double)std::clock()-(long double)firstClock)*(long double)100.0;
				ss.str("");
				ss << std::setprecision(10) << overhead;
				std::string sOverhead = ss.str();
				std::wstring wOverhead;
				wOverhead.assign(sOverhead.begin(),sOverhead.end());
				data[L"overhead"] = cpptempl::make_data(wOverhead);
				std::cout << overhead << "% overhead\n";
				//std::cout << std::clock() << " clocl\n";

				/////////////////MESSAGENUMBER/////////////////////////<
			        ss.str("");
			        ss << messageNumber;
			        std::string gnuPlotStringN = ss.str();
			        std::string sMessageNumber = ss.str();
			        std::wstring wMessageNumber;
			        wMessageNumber.assign(sMessageNumber.begin(),sMessageNumber.end());
			        data[L"messagenumber"] = cpptempl::make_data(wMessageNumber);

				std::wstring result = cpptempl::parse(templ, data);
				
				ss.str("");
				
				double templateTime = ((double)templateClock/(double)CLOCKS_PER_SEC)*(double)1000;
				ss << std::setprecision(8) << templateTime;
				std::string templTime = ss.str();				
				
				double totalT = ((std::clock()-firstClock)/(double)CLOCKS_PER_SEC);
				std::cout << totalT << "totaltime\n";
				std::cout << CYCLES_PER_SECOND << "cycles\n";
				std::string s;
		    		s.assign(result.begin(), result.end());
				
				if (messageNumber == 1)
				{
					std::ofstream traceoutput;
					traceoutput.open("/tmp/traceout.xml",std::ios::out);
					traceoutput << s;
					traceoutput.close();
				}

				messageNumber++;

				/////STATS/////
								

				output << s;
		
				std::string out = gnuPlotStringN + "," + gnuPlotStringT + "\n";
				outputEventsPerSec << out;
		
				//OutputNT
				//std::string theT;
				out = "";
				//ss.str("");
				//ss << templTime;
				//theT = ss.str();
				out = templTime + "," + gnuPlotStringN + "\n";
				outputNT << out;
				
			}
			/////////////////////////////////////////////////////////////////
		}

		TriggersEachCycle();      // handle triggers
		UpdateMessages();         // update messages
		ParticleManager.update(); // handle particles

		CheckMusicFinished();     // Check for next song

		//
		// Map scrolling
		//
		DoScrollArea(MouseScrollState | KeyScrollState, (KeyModifiers & ModifierControl) != 0);

		if (FastForwardCycle <= GameCycle || GameCycle <= 10 || !(GameCycle & 0x3f)) {
			//FIXME: this might be better placed somewhere at front of the
			// program, as we now still have a game on the background and
			// need to go through the game-menu or supply a map file
			UpdateDisplay();

			//
			// If double-buffered mode, we will display the contains of
			// VideoMemory. If direct mode this does nothing. In X11 it does
			// XFlush
			//
			RealizeVideoMemory();
		}

		if (FastForwardCycle <= GameCycle || !(GameCycle & 0x3f)) {
			WaitEventsOneFrame();
		}
		if (!NetworkInSync) {
			NetworkRecover(); // recover network
		}

		
	}

	output.close();
	outputNT.close();
    	outputEventsPerSec.close();
	//
	// Game over
	//
	NetworkQuit();
	EndReplayLog();

	CParticleManager::exit();

	FlagRevealMap = 0;
	ReplayRevealMap = 0;
	GamePaused = false;
	GodMode = false;

	SetCallbacks(old_callbacks);
}
示例#3
0
/**
**  Play a video file.
**
**  @param name   Filename of movie file.
**
**  @return       Non-zero if file isn't a supported movie.
*/
int PlayMovie(const std::string &name)
{
    OggData data;
    CFile f;
    SDL_Rect rect;
    SDL_Overlay *yuv_overlay;
    CSample *sample;
    const EventCallback *old_callbacks;
    EventCallback callbacks;
    unsigned int start_ticks;
    int need_data;
    int diff;
    char buffer[PATH_MAX];

    LibraryFileName(name.c_str(), buffer, sizeof(buffer));

    if (f.open(buffer, CL_OPEN_READ) == -1) {
        fprintf(stderr, "Can't open file `%s'\n", name.c_str());
        return -1;
    }

    memset(&data, 0, sizeof(data));
    if (OggInit(&f, &data) || !data.video) {
        OggFree(&data);
        f.close();
        return -1;
    }

    data.File = &f;

    if (data.tinfo.frame_width * 300 / 4 > data.tinfo.frame_height * 100) {
        rect.w = Video.Width;
        rect.h = Video.Width * data.tinfo.frame_height / data.tinfo.frame_width;
        rect.x = 0;
        rect.y = (Video.Height - rect.h) / 2;
    } else {
        rect.w = Video.Height * data.tinfo.frame_width / data.tinfo.frame_height;
        rect.h = Video.Height;
        rect.x = (Video.Width - rect.w) / 2;
        rect.y = 0;
    }

    yuv_overlay = SDL_CreateYUVOverlay(data.tinfo.frame_width,
                                       data.tinfo.frame_height, SDL_YV12_OVERLAY, TheScreen);

    if (yuv_overlay == NULL) {
        fprintf(stderr, "SDL_CreateYUVOverlay: %s\n", SDL_GetError());
        OggFree(&data);
        f.close();
        return 0;
    }

    StopMusic();
    if ((sample = LoadVorbis(buffer, PlayAudioStream))) {
        if ((sample->Channels != 1 && sample->Channels != 2) ||
                sample->SampleSize != 16) {
            fprintf(stderr, "Unsupported sound format in movie\n");
            delete sample;
            SDL_FreeYUVOverlay(yuv_overlay);
            OggFree(&data);
            f.close();
            return 0;
        }
        PlayMusic(sample);
    }

    callbacks.ButtonPressed = MovieCallbackButtonPressed;
    callbacks.ButtonReleased = MovieCallbackButtonReleased;
    callbacks.MouseMoved = MovieCallbackMouseMove;
    callbacks.MouseExit = MovieCallbackMouseExit;
    callbacks.KeyPressed = MovieCallbackKeyPressed;
    callbacks.KeyReleased = MovieCallbackKeyReleased;
    callbacks.KeyRepeated = MovieCallbackKeyRepeated;
    callbacks.NetworkEvent = NetworkEvent;

    old_callbacks = GetCallbacks();
    SetCallbacks(&callbacks);

    Invalidate();
    RealizeVideoMemory();

    MovieStop = false;
    start_ticks = SDL_GetTicks();
    need_data = 1;
    while (!MovieStop) {
        if (need_data) {
            if (TheoraProcessData(&data)) {
                break;
            }
            need_data = 0;
        }

        diff = SDL_GetTicks() - start_ticks - static_cast<int>(
                   theora_granule_time(&data.tstate, data.tstate.granulepos) * 1000);

        if (diff > 100) {
            // too far behind, skip some frames
            need_data = 1;
            continue;
        }
        if (diff > 0) {
            OutputTheora(&data, yuv_overlay, &rect);
            need_data = 1;
        }

        WaitEventsOneFrame();
    }

    StopMusic();
    SDL_FreeYUVOverlay(yuv_overlay);

    OggFree(&data);
    f.close();

    SetCallbacks(old_callbacks);

    return 0;
}
示例#4
0
static void GameLogicLoop()
{
	// Can't find a better place.
	// FIXME: We need find better place!
	SaveGameLoading = false;

	//
	// Game logic part
	//
	if (!GamePaused && NetworkInSync && !SkipGameCycle) {
		SinglePlayerReplayEachCycle();
		++GameCycle;
		MultiPlayerReplayEachCycle();
		NetworkCommands(); // Get network commands
		TriggersEachCycle();// handle triggers
		UnitActions();      // handle units
		MissileActions();   // handle missiles
		PlayersEachCycle(); // handle players
		UpdateTimer();      // update game timer


		//
		// Work todo each second.
		// Split into different frames, to reduce cpu time.
		// Increment mana of magic units.
		// Update mini-map.
		// Update map fog of war.
		// Call AI.
		// Check game goals.
		// Check rescue of units.
		//
		switch (GameCycle % CYCLES_PER_SECOND) {
			case 0: // At cycle 0, start all ai players...
				if (GameCycle == 0) {
					for (int player = 0; player < NumPlayers; ++player) {
						PlayersEachSecond(player);
					}
				}
				break;
			case 1:
				break;
			case 2:
				break;
			case 3: // minimap update
				UI.Minimap.UpdateCache = true;
				break;
			case 4:
				break;
			case 5: // forest grow
				Map.RegenerateForest();
				break;
			case 6: // overtaking units
				RescueUnits();
				break;
			default: {
				// FIXME: assume that NumPlayers < (CYCLES_PER_SECOND - 7)
				int player = (GameCycle % CYCLES_PER_SECOND) - 7;
				Assert(player >= 0);
				if (player < NumPlayers) {
					PlayersEachSecond(player);
				}
			}
		}
	}

	UpdateMessages();     // update messages
	ParticleManager.update(); // handle particles
	CheckMusicFinished(); // Check for next song

	if (FastForwardCycle <= GameCycle || !(GameCycle & 0x3f)) {
		WaitEventsOneFrame();
	}

	if (!NetworkInSync) {
		NetworkRecover(); // recover network
	}
}
示例#5
0
/**
**  Play a video file.
**
**  @param name   Filename of movie file.
**
**  @return       Non-zero if file isn't a supported movie.
*/
int PlayMovie(const std::string &name)
{
	int videoWidth, videoHeight;
#if defined(USE_OPENGL) || defined(USE_GLES)
	videoWidth  = Video.ViewportWidth;
	videoHeight = Video.ViewportHeight;
#else
	videoWidth  = Video.Width;
	videoHeight = Video.Height;
#endif

	const std::string filename = LibraryFileName(name.c_str());

	CFile f;
	if (f.open(filename.c_str(), CL_OPEN_READ) == -1) {
		fprintf(stderr, "Can't open file '%s'\n", name.c_str());
		return 0;
	}

	OggData data;
	memset(&data, 0, sizeof(data));
	if (OggInit(&f, &data) || !data.video) {
		OggFree(&data);
		f.close();
		return -1;
	}

	data.File = &f;
	SDL_Rect rect;

	if (data.tinfo.frame_width * 300 / 4 > data.tinfo.frame_height * 100) {
		rect.w = videoWidth;
		rect.h = videoWidth * data.tinfo.frame_height / data.tinfo.frame_width;
		rect.x = 0;
		rect.y = (videoHeight - rect.h) / 2;
	} else {
		rect.w = videoHeight * data.tinfo.frame_width / data.tinfo.frame_height;
		rect.h = videoHeight;
		rect.x = (videoWidth - rect.w) / 2;
		rect.y = 0;
	}

#ifdef USE_OPENGL
	// When SDL_OPENGL is used, it is not possible to call SDL_CreateYUVOverlay, so turn temporary OpenGL off
	// With GLES is all ok
	if (UseOpenGL) {
		SDL_SetVideoMode(Video.ViewportWidth, Video.ViewportHeight, Video.Depth, SDL_GetVideoSurface()->flags & ~SDL_OPENGL);
	}
#endif

	SDL_FillRect(SDL_GetVideoSurface(), NULL, 0);
	Video.ClearScreen();
	SDL_Overlay *yuv_overlay = SDL_CreateYUVOverlay(data.tinfo.frame_width, data.tinfo.frame_height, SDL_YV12_OVERLAY, TheScreen);

	if (yuv_overlay == NULL) {
		fprintf(stderr, "SDL_CreateYUVOverlay: %s\n", SDL_GetError());
		OggFree(&data);
		f.close();
		return 0;
	}

	StopMusic();
	CSample *sample = LoadVorbis(filename.c_str(), PlayAudioStream);
	if (sample) {
		if ((sample->Channels != 1 && sample->Channels != 2) || sample->SampleSize != 16) {
			fprintf(stderr, "Unsupported sound format in movie\n");
			delete sample;
			SDL_FreeYUVOverlay(yuv_overlay);
			OggFree(&data);
			f.close();
			return 0;
		}
		PlayMusic(sample);
	}

	EventCallback callbacks;

	callbacks.ButtonPressed = MovieCallbackButtonPressed;
	callbacks.ButtonReleased = MovieCallbackButtonReleased;
	callbacks.MouseMoved = MovieCallbackMouseMove;
	callbacks.MouseExit = MovieCallbackMouseExit;
	callbacks.KeyPressed = MovieCallbackKeyPressed;
	callbacks.KeyReleased = MovieCallbackKeyReleased;
	callbacks.KeyRepeated = MovieCallbackKeyRepeated;
	callbacks.NetworkEvent = NetworkEvent;

	const EventCallback *old_callbacks = GetCallbacks();
	SetCallbacks(&callbacks);

	Invalidate();
	RealizeVideoMemory();

	MovieStop = false;
	const unsigned int start_ticks = SDL_GetTicks();
	bool need_data = true;
	while (!MovieStop) {
		if (need_data) {
			if (TheoraProcessData(&data)) {
				break;
			}
			need_data = false;
		}

		const int diff = SDL_GetTicks() - start_ticks
						 - static_cast<int>(theora_granule_time(&data.tstate, data.tstate.granulepos) * 1000);

		if (diff > 100) {
			// too far behind, skip some frames
			need_data = true;
			continue;
		}
		if (diff > 0) {
			OutputTheora(&data, yuv_overlay, &rect);
			need_data = true;
		}

		WaitEventsOneFrame();
	}

	StopMusic();
	SDL_FreeYUVOverlay(yuv_overlay);

	OggFree(&data);
	f.close();

#ifdef USE_OPENGL
	if (UseOpenGL) {
		SDL_SetVideoMode(Video.ViewportWidth, Video.ViewportHeight, Video.Depth, SDL_GetVideoSurface()->flags | SDL_OPENGL);
		ReloadOpenGL();
	}
#endif

	SetCallbacks(old_callbacks);

	return 0;
}
示例#6
0
static void GameLogicLoop()
{
	// Can't find a better place.
	// FIXME: We need find better place!
	SaveGameLoading = false;

	//
	// Game logic part
	//
	if (!GamePaused && NetworkInSync && !SkipGameCycle) {
		SinglePlayerReplayEachCycle();
		++GameCycle;
		MultiPlayerReplayEachCycle();
		NetworkCommands(); // Get network commands
		TriggersEachCycle();// handle triggers
		UnitActions();      // handle units
		MissileActions();   // handle missiles
		PlayersEachCycle(); // handle players
		UpdateTimer();      // update game timer


		//
		// Work todo each second.
		// Split into different frames, to reduce cpu time.
		// Increment mana of magic units.
		// Update mini-map.
		// Update map fog of war.
		// Call AI.
		// Check game goals.
		// Check rescue of units.
		//
		switch (GameCycle % CYCLES_PER_SECOND) {
			case 0: // At cycle 0, start all ai players...
				if (GameCycle == 0) {
					for (int player = 0; player < NumPlayers; ++player) {
						PlayersEachSecond(player);
					}
				}
				break;
			case 1:
				break;
			case 2:
				break;
			case 3: // minimap update
				UI.Minimap.UpdateCache = true;
				break;
			case 4:
				break;
			case 5: // forest grow
				Map.RegenerateForest();
				break;
			case 6: // overtaking units
				RescueUnits();
				break;
			default: {
				// FIXME: assume that NumPlayers < (CYCLES_PER_SECOND - 7)
				int player = (GameCycle % CYCLES_PER_SECOND) - 7;
				Assert(player >= 0);
				if (player < NumPlayers) {
					PlayersEachSecond(player);
				}
			}
		}
		
		//Wyrmgus start
		if (GameCycle > 0 && GameCycle % (CYCLES_PER_SECOND * 10 * 3) == 0) { // every 10 seconds of gameplay = 1 hour for time of day calculations, change time of day every three hours
			if (!GameSettings.Inside) { // only change the time of the day if outdoors
				GameTimeOfDay += 1;
				if (GameTimeOfDay == MaxTimesOfDay) {
					GameTimeOfDay = 1;
				}
			} else {
				// indoors it is always dark (maybe would be better to allow a special setting to have bright indoor places?
				GameTimeOfDay = NoTimeOfDay; // make indoors have no time of day setting until it is possible to make light sources change their surrounding "time of day"
			}
			//update the sight of all units
			for (CUnitManager::Iterator it = UnitManager.begin(); it != UnitManager.end(); ++it) {
				CUnit &unit = **it;
				if (!unit.Destroyed) {
					MapUnmarkUnitSight(unit);
					UpdateUnitSightRange(unit);
					MapMarkUnitSight(unit);
				}
			}
		}
		//Wyrmgus end
		
		//Wyrmgus start
//		if (Preference.AutosaveMinutes != 0 && !IsNetworkGame() && GameCycle > 0 && (GameCycle % (CYCLES_PER_SECOND * 60 * Preference.AutosaveMinutes)) == 0) { // autosave every X minutes, if the option is enabled
		if (Preference.AutosaveMinutes != 0 && !IsNetworkGame() && !GrandStrategy && GameCycle > 0 && (GameCycle % (CYCLES_PER_SECOND * 60 * Preference.AutosaveMinutes)) == 0) { // autosave every X minutes, if the option is enabled
		//Wyrmgus end
			UI.StatusLine.Set(_("Autosave"));
			//Wyrmgus start
//			SaveGame("autosave.sav");
			CclCommand("if (RunSaveGame ~= nil) then RunSaveGame(\"autosave.sav\") end;");
			//Wyrmgus end
		}
	}

	UpdateMessages();     // update messages
	ParticleManager.update(); // handle particles
	CheckMusicFinished(); // Check for next song

	if (FastForwardCycle <= GameCycle || !(GameCycle & 0x3f)) {
		WaitEventsOneFrame();
	}

	if (!NetworkInSync) {
		NetworkRecover(); // recover network
	}
}
示例#7
0
/**
**  Game main loop.
**
**  Unit actions.
**  Missile actions.
**  Players (AI).
**  Cyclic events (color cycle,...)
**  Display update.
**  Input/Network/Sound.
*/
void GameMainLoop(void)
{
#ifdef DEBUG  // removes the setjmp warnings
	static bool showtip;
#else
	bool showtip;
#endif
	int player;
	int RealVideoSyncSpeed;
	const EventCallback *old_callbacks;

	InitGameCallbacks();

	old_callbacks = GetCallbacks();
	SetCallbacks(&GameCallbacks);

	SetVideoSync();
	GameCursor = UI.Point.Cursor;
	GameRunning = true;

	showtip = false;
	RealVideoSyncSpeed = VideoSyncSpeed;

	MultiPlayerReplayEachCycle();

	// StratagusAI MOD
	GamePaused = true;
	// Minimap.Update();
        
	while (GameRunning) {
		// StratagusAI MOD
		if ((GameCycle - socketInterface->lastPausedCycle) %
				socketInterface->cyclesPerTransition == 0) {
			socketInterface->handleInterface();
			if (socketInterface->warpSpeed)
				FastForwardCycle = GameCycle +
					socketInterface->cyclesPerTransition + 1;
		}

		// Can't find a better place.
		SaveGameLoading = 0;
		//
		// Game logic part
		//
		if (!GamePaused && NetworkInSync && !SkipGameCycle) {
			SinglePlayerReplayEachCycle();
			++GameCycle;
			MultiPlayerReplayEachCycle();
			NetworkCommands(); // Get network commands
			UnitActions();      // handle units
			MissileActions();   // handle missiles
			PlayersEachCycle(); // handle players
			UpdateTimer();      // update game timer

			//
			// Work todo each second.
			// Split into different frames, to reduce cpu time.
			// Increment mana of magic units.
			// Update mini-map.
			// Update map fog of war.
			// Call AI.
			// Check game goals.
			// Check rescue of units.
			//
			switch (GameCycle % CYCLES_PER_SECOND) {
				case 0: // At cycle 0, start all ai players...
					if (GameCycle == 0) {
						for (player = 0; player < NumPlayers; ++player) {
							PlayersEachSecond(player);
						}
					}
					break;
				case 1:
					break;
				case 2:
					break;
				case 3: // minimap update
					UI.Minimap.Update();
					break;
				case 4:
					break;
				case 5:
					break;
				case 6: // overtaking units
					RescueUnits();
					break;
				default:
					// FIXME: assume that NumPlayers < (CYCLES_PER_SECOND - 7)
					player = (GameCycle % CYCLES_PER_SECOND) - 7;
					Assert(player >= 0);
					if (player < NumPlayers) {
						PlayersEachSecond(player);
					}
			}
		}

		TriggersEachCycle();  // handle triggers
		UpdateMessages();     // update messages

		CheckMusicFinished(); // Check for next song

		//
		// Map scrolling
		//
		DoScrollArea(MouseScrollState | KeyScrollState, (KeyModifiers & ModifierControl) != 0);

		if (FastForwardCycle > GameCycle &&
				RealVideoSyncSpeed != VideoSyncSpeed) {
			RealVideoSyncSpeed = VideoSyncSpeed;
			VideoSyncSpeed = 3000;
		}

		// MOD
		if (socketInterface->cyclesPerVideoUpdate != -1 &&
				(GameCycle % socketInterface->cyclesPerVideoUpdate == 0 || GamePaused))
		{
			if (FastForwardCycle <= GameCycle || GameCycle <= 10 || !(GameCycle & 0x3f)) {
				//FIXME: this might be better placed somewhere at front of the
				// program, as we now still have a game on the background and
				// need to go through the game-menu or supply a map file
				UpdateDisplay();

				//
				// If double-buffered mode, we will display the contains of
				// VideoMemory. If direct mode this does nothing. In X11 it does
				// XFlush
				//
				RealizeVideoMemory();
			}
		}

		if (FastForwardCycle == GameCycle) {
			VideoSyncSpeed = RealVideoSyncSpeed;
		}
		if (FastForwardCycle <= GameCycle || !(GameCycle & 0x3f)) {
			WaitEventsOneFrame();
		}
		if (!NetworkInSync) {
			NetworkRecover(); // recover network
		}
	}

	//
	// Game over
	//
	if (FastForwardCycle > GameCycle) {
		VideoSyncSpeed = RealVideoSyncSpeed;
	}
	NetworkQuit();
	EndReplayLog();

	FlagRevealMap = 0;
	ReplayRevealMap = 0;
	GamePaused = false;
	GodMode = false;

	SetCallbacks(old_callbacks);
}
示例#8
0
static void GameLogicLoop()
{
	// Can't find a better place.
	// FIXME: We need find better place!
	SaveGameLoading = false;

#ifdef USE_OAML
	if (enableOAML && oaml) {
		// Time of day can change our main music loop, if the current playing track is set for this
		SetMusicCondition(OAML_CONDID_MAIN_LOOP, Map.TimeOfDay[CurrentMapLayer]);
	}
#endif

	//
	// Game logic part
	//
	if (!GamePaused && NetworkInSync && !SkipGameCycle) {
		SinglePlayerReplayEachCycle();
		++GameCycle;
		MultiPlayerReplayEachCycle();
		NetworkCommands(); // Get network commands
		TriggersEachCycle();// handle triggers
		UnitActions();      // handle units
		MissileActions();   // handle missiles
		PlayersEachCycle(); // handle players
		UpdateTimer();      // update game timer


		//
		// Work todo each second.
		// Split into different frames, to reduce cpu time.
		// Increment mana of magic units.
		// Update mini-map.
		// Update map fog of war.
		// Call AI.
		// Check game goals.
		// Check rescue of units.
		//
		switch (GameCycle % CYCLES_PER_SECOND) {
			case 0: // At cycle 0, start all ai players...
				if (GameCycle == 0) {
					for (int player = 0; player < NumPlayers; ++player) {
						PlayersEachSecond(player);
					}
				}
				break;
			case 1:
				break;
			case 2:
				break;
			case 3: // minimap update
				UI.Minimap.UpdateCache = true;
				break;
			case 4:
				break;
			case 5: // forest grow
				Map.RegenerateForest();
				break;
			case 6: // overtaking units
				RescueUnits();
				break;
			//Wyrmgus start
			/*
			default: {
				// FIXME: assume that NumPlayers < (CYCLES_PER_SECOND - 7)
				int player = (GameCycle % CYCLES_PER_SECOND) - 7;
				Assert(player >= 0);
				if (player < NumPlayers) {
					PlayersEachSecond(player);
				}
			}
			*/
			//Wyrmgus end
		}
		
		//Wyrmgus start
		int player = (GameCycle - 1) % CYCLES_PER_SECOND;
		Assert(player >= 0);
		if (player < NumPlayers) {
			PlayersEachSecond(player);
			if ((player + CYCLES_PER_SECOND) < NumPlayers) {
				PlayersEachSecond(player + CYCLES_PER_SECOND);
			}
		}
		
		player = (GameCycle - 1) % CYCLES_PER_MINUTE;
		Assert(player >= 0);
		if (player < NumPlayers) {
			PlayersEachMinute(player);
		}
		//Wyrmgus end
		
		//Wyrmgus start
		for (size_t z = 0; z < Map.Fields.size(); ++z) {
			if (GameSettings.Inside || GameSettings.NoTimeOfDay || !Map.TimeOfDaySeconds[z]) {
				// indoors it is always dark (maybe would be better to allow a special setting to have bright indoor places?
				Map.TimeOfDay[z] = NoTimeOfDay; // make indoors have no time of day setting until it is possible to make light sources change their surrounding "time of day"
				continue;
			}
			if (GameCycle > 0 && GameCycle % (CYCLES_PER_SECOND * Map.TimeOfDaySeconds[z]) == 0) { 
				Map.TimeOfDay[z] += 1;
				if (Map.TimeOfDay[z] == MaxTimesOfDay) {
					Map.TimeOfDay[z] = 1;
				}

#ifdef USE_OAML
				if (enableOAML && oaml && z == CurrentMapLayer) {
					// Time of day can change our main music loop, if the current playing track is set for this
					SetMusicCondition(OAML_CONDID_MAIN_LOOP, Map.TimeOfDay[z]);
				}
#endif

				//update the sight of all units
				for (CUnitManager::Iterator it = UnitManager.begin(); it != UnitManager.end(); ++it) {
					CUnit *unit = *it;
					if (
						unit && unit->IsAlive() && unit->MapLayer == z &&
						(
							((Map.TimeOfDay[z] == MorningTimeOfDay || Map.TimeOfDay[z] == DuskTimeOfDay) && unit->Variable[DAYSIGHTRANGEBONUS_INDEX].Value != 0) // if has day sight bonus and is entering or exiting day
							|| ((Map.TimeOfDay[z] == FirstWatchTimeOfDay || Map.TimeOfDay[z] == DawnTimeOfDay) && unit->Variable[NIGHTSIGHTRANGEBONUS_INDEX].Value != 0) // if has night sight bonus and is entering or exiting night
						)
					) {
						MapUnmarkUnitSight(*unit);
						UpdateUnitSightRange(*unit);
						MapMarkUnitSight(*unit);
					}
				}
			}
		}
		//Wyrmgus end
		
		//Wyrmgus start
//		if (Preference.AutosaveMinutes != 0 && !IsNetworkGame() && GameCycle > 0 && (GameCycle % (CYCLES_PER_SECOND * 60 * Preference.AutosaveMinutes)) == 0) { // autosave every X minutes, if the option is enabled
		if (Preference.AutosaveMinutes != 0 && !IsNetworkGame() && !GrandStrategy && GameCycle > 0 && (GameCycle % (CYCLES_PER_MINUTE * Preference.AutosaveMinutes)) == 0) { // autosave every X minutes, if the option is enabled
		//Wyrmgus end
			UI.StatusLine.Set(_("Autosave"));
			//Wyrmgus start
//			SaveGame("autosave.sav");
			CclCommand("if (RunSaveGame ~= nil) then RunSaveGame(\"autosave.sav\") end;");
			//Wyrmgus end
		}
	}

	UpdateMessages();     // update messages
	ParticleManager.update(); // handle particles
	CheckMusicFinished(); // Check for next song

	if (FastForwardCycle <= GameCycle || !(GameCycle & 0x3f)) {
		WaitEventsOneFrame();
	}

	if (!NetworkInSync) {
		NetworkRecover(); // recover network
	}
}