/** ** Load all. ** ** Call each module to load additional files (graphics,sounds). */ void LoadModules() { LoadFonts(); LoadIcons(); LoadCursors(PlayerRaces.Name[ThisPlayer->Race]); UI.Load(); #ifndef DYNAMIC_LOAD LoadMissileSprites(); #endif LoadConstructions(); LoadDecorations(); LoadUnitTypes(); InitPathfinder(); LoadUnitSounds(); MapUnitSounds(); if (SoundEnabled()) { InitSoundClient(); } SetPlayersPalette(); UI.Minimap.Create(); SetDefaultTextColors(UI.NormalFontColor, UI.ReverseFontColor); }
/** ** Map the sounds of all unit-types to the correct sound id. ** And overwrite the sound ranges. ** @todo the sound ranges should be configurable by user with CCL. */ void MapUnitSounds() { if (SoundEnabled() == false) { return; } // Parse all units sounds. for (std::vector<CUnitType *>::size_type i = 0; i < UnitTypes.size(); ++i) { CUnitType &type = *UnitTypes[i]; MapAnimSounds(type); type.Sound.Selected.MapSound(); type.Sound.Acknowledgement.MapSound(); // type.Sound.Acknowledgement.SetSoundRange(INFINITE_SOUND_RANGE); type.Sound.Attack.MapSound(); type.Sound.Build.MapSound(); type.Sound.Ready.MapSound(); type.Sound.Ready.SetSoundRange(INFINITE_SOUND_RANGE); type.Sound.Repair.MapSound(); for (int i = 0; i < MaxCosts; ++i) { type.Sound.Harvest[i].MapSound(); } type.Sound.Help.MapSound(); type.Sound.Help.SetSoundRange(INFINITE_SOUND_RANGE); for (int i = 0; i <= ANIMATIONS_DEATHTYPES; ++i) { type.Sound.Dead[i].MapSound(); } } }
/** ** Choose the sample to play */ static CSample *ChooseSample(CSound *sound, bool selection, Origin &source) { CSample *result = NULL; if (!sound || !SoundEnabled()) { return NULL; } if (sound->Number == TWO_GROUPS) { // handle a special sound (selection) if (SelectionHandler.Sound != NULL && (SelectionHandler.Source.Base == source.Base && SelectionHandler.Source.Id == source.Id)) { if (SelectionHandler.Sound == sound->Sound.TwoGroups.First) { result = SimpleChooseSample(*SelectionHandler.Sound); SelectionHandler.HowMany++; if (SelectionHandler.HowMany >= 3) { SelectionHandler.HowMany = 0; SelectionHandler.Sound = sound->Sound.TwoGroups.Second; } } else { //FIXME: checks for error // check whether the second group is really a group if (SelectionHandler.Sound->Number > 1) { result = SelectionHandler.Sound->Sound.OneGroup[SelectionHandler.HowMany]; SelectionHandler.HowMany++; if (SelectionHandler.HowMany >= SelectionHandler.Sound->Number) { SelectionHandler.HowMany = 0; SelectionHandler.Sound = sound->Sound.TwoGroups.First; } } else { result = SelectionHandler.Sound->Sound.OneSound; SelectionHandler.HowMany = 0; SelectionHandler.Sound = sound->Sound.TwoGroups.First; } } } else { SelectionHandler.Source = source; SelectionHandler.Sound = sound->Sound.TwoGroups.First; result = SimpleChooseSample(*SelectionHandler.Sound); SelectionHandler.HowMany = 1; } } else { // normal sound/sound group handling result = SimpleChooseSample(*sound); if (SelectionHandler.Source.Base == source.Base && SelectionHandler.Source.Id == source.Id) { SelectionHandler.HowMany = 0; SelectionHandler.Sound = NULL; } if (selection) { SelectionHandler.Source = source; } } return result; }
/** ** Play a sound sample ** ** @param sample Sample to play ** ** @return Channel number, -1 for error */ int PlaySample(CSample *sample, Origin *origin) { int channel = -1; SDL_LockMutex(Audio.Lock); if (SoundEnabled() && EffectsEnabled && sample && NextFreeChannel != MaxChannels) { channel = FillChannel(sample, EffectsVolume, 0, origin); } SDL_UnlockMutex(Audio.Lock); return channel; }
/** ** Toggle sound on / off. */ static void UiToggleSound() { if (SoundEnabled()) { if (IsEffectsEnabled()) { SetEffectsEnabled(false); SetMusicEnabled(false); } else { SetEffectsEnabled(true); SetMusicEnabled(true); CheckMusicFinished(true); } } if (SoundEnabled()) { if (IsEffectsEnabled()) { UI.StatusLine.Set(_("Sound is on.")); } else { UI.StatusLine.Set(_("Sound is off.")); } } }
/** ** Toggle music on / off. */ static void UiToggleMusic() { static int vol; if (SoundEnabled()) { if (GetMusicVolume()) { vol = GetMusicVolume(); SetMusicVolume(0); UI.StatusLine.Set(_("Music is off.")); } else { SetMusicVolume(vol); UI.StatusLine.Set(_("Music is on.")); } } }
/** ** Check if music is finished and play the next song */ void CheckMusicFinished(bool force) { bool proceed; SDL_LockMutex(MusicFinishedMutex); proceed = MusicFinished; MusicFinished = false; SDL_UnlockMutex(MusicFinishedMutex); if ((proceed || force) && SoundEnabled() && IsMusicEnabled() && CallbackMusic) { lua_getglobal(Lua, "MusicStopped"); if (!lua_isfunction(Lua, -1)) { fprintf(stderr, "No MusicStopped function in Lua\n"); StopMusic(); } else { LuaCall(0, 1); } } }
/** ** Play a music file. ** ** @param file Name of music file, format is automatically detected. ** ** @return 0 if music is playing, -1 if not. */ int PlayMusic(const std::string &file) { if (!SoundEnabled() || !IsMusicEnabled()) { return -1; } const std::string name = LibraryFileName(file.c_str()); DebugPrint("play music %s\n" _C_ name.c_str()); CSample *sample = LoadSample(name.c_str(), PlayAudioStream); if (sample) { StopMusic(); MusicChannel.Sample = sample; MusicPlaying = true; return 0; } else { DebugPrint("Could not play %s\n" _C_ file.c_str()); return -1; } }
/** ** Lookup the sound id's for the game sounds. */ void InitSoundClient(void) { if (!SoundEnabled()) { // No sound enabled return; } // let's map game sounds, look if already setup in ccl. if (!GameSounds.PlacementError.Sound) { GameSounds.PlacementError.Sound = SoundForName(GameSounds.PlacementError.Name); } if (!GameSounds.PlacementSuccess.Sound) { GameSounds.PlacementSuccess.Sound = SoundForName(GameSounds.PlacementSuccess.Name); } if (!GameSounds.Click.Sound) { GameSounds.Click.Sound = SoundForName(GameSounds.Click.Name); } if (!GameSounds.Docking.Sound) { GameSounds.Docking.Sound = SoundForName(GameSounds.Docking.Name); } if (!GameSounds.BuildingConstruction.Sound) { GameSounds.BuildingConstruction.Sound = SoundForName(GameSounds.BuildingConstruction.Name); } if (!GameSounds.Rescue.Sound && !GameSounds.Rescue.Name.empty()) { GameSounds.Rescue.Sound = SoundForName(GameSounds.Rescue.Name); } if (!GameSounds.ChatMessage.Sound && !GameSounds.ChatMessage.Name.empty()) { GameSounds.ChatMessage.Sound = SoundForName(GameSounds.ChatMessage.Name); } int MapWidth = (UI.MapArea.EndX - UI.MapArea.X + TileSizeX) / TileSizeX; int MapHeight = (UI.MapArea.EndY - UI.MapArea.Y + TileSizeY) / TileSizeY; DistanceSilent = 3 * std::max(MapWidth, MapHeight); ViewPointOffset = std::max(MapWidth / 2, MapHeight / 2); }
/** ** Lookup the sound id's for the game sounds. */ void InitSoundClient() { if (!SoundEnabled()) { // No sound enabled return; } // let's map game sounds, look if already setup in ccl. for (unsigned int i = 0; i < PlayerRaces.Count; ++i) { if (!GameSounds.PlacementError[i].Sound) { GameSounds.PlacementError[i].MapSound(); } } for (unsigned int i = 0; i < PlayerRaces.Count; ++i) { if (!GameSounds.PlacementSuccess[i].Sound) { GameSounds.PlacementSuccess[i].MapSound(); } } if (!GameSounds.Click.Sound) { GameSounds.Click.MapSound(); } if (!GameSounds.Docking.Sound) { GameSounds.Docking.MapSound(); } for (unsigned int i = 0; i < PlayerRaces.Count; ++i) { if (!GameSounds.BuildingConstruction[i].Sound) { GameSounds.BuildingConstruction[i].MapSound(); } } for (unsigned int i = 0; i < PlayerRaces.Count; ++i) { if (!GameSounds.WorkComplete[i].Sound) { GameSounds.WorkComplete[i].MapSound(); } } for (unsigned int i = 0; i < PlayerRaces.Count; ++i) { if (!GameSounds.ResearchComplete[i].Sound) { GameSounds.ResearchComplete[i].MapSound(); } } for (unsigned int i = 0; i < PlayerRaces.Count; ++i) { for (unsigned int j = 0; j < MaxCosts; ++j) { if (!GameSounds.NotEnoughRes[i][j].Sound) { GameSounds.NotEnoughRes[i][j].MapSound(); } } } for (unsigned int i = 0; i < PlayerRaces.Count; ++i) { if (!GameSounds.NotEnoughFood[i].Sound) { GameSounds.NotEnoughFood[i].MapSound(); } } for (unsigned int i = 0; i < PlayerRaces.Count; ++i) { if (!GameSounds.Rescue[i].Sound) { GameSounds.Rescue[i].MapSound(); } } if (!GameSounds.ChatMessage.Sound) { GameSounds.ChatMessage.MapSound(); } int MapWidth = (UI.MapArea.EndX - UI.MapArea.X + PixelTileSize.x) / PixelTileSize.x; int MapHeight = (UI.MapArea.EndY - UI.MapArea.Y + PixelTileSize.y) / PixelTileSize.y; DistanceSilent = 3 * std::max<int>(MapWidth, MapHeight); ViewPointOffset = std::max<int>(MapWidth / 2, MapHeight / 2); }
/** ** CreateGame. ** ** Load map, graphics, sounds, etc ** ** @param filename map filename ** @param map map loaded ** ** @todo FIXME: use in this function InitModules / LoadModules!!! */ void CreateGame(const char *filename, CMap *map) { int i; if (SaveGameLoading) { SaveGameLoading = 0; // Load game, already created game with Init/LoadModules CommandLog(NULL, NoUnitP, FlushCommands, -1, -1, NoUnitP, NULL, -1); return; } InitVisionTable(); // build vision table for fog of war InitPlayers(); if (Map.Info.Filename.empty() && filename) { char path[PATH_MAX]; Assert(filename); LibraryFileName(filename, path, sizeof(path)); if(strcasestr(filename, ".smp")) { LuaLoadFile(path); } } for (i = 0; i < PlayerMax; ++i) { int playertype = Map.Info.PlayerType[i]; // Network games only: if (GameSettings.Presets[i].Type != SettingsPresetMapDefault) { playertype = GameSettings.Presets[i].Type; } CreatePlayer(playertype); } if (filename) { if (CurrentMapPath != filename) { strcpy_s(CurrentMapPath, sizeof(CurrentMapPath), filename); } // // Load the map. // InitUnitTypes(1); LoadMap(filename, map); // HARDCODING FOG OF WAR TRUE. It doesn't currently use preferences on a game restart - Should be changed map->NoFogOfWar = true; Map.Reveal(); } GameCycle = 0; FastForwardCycle = 0; SyncHash = 0; InitSyncRand(); if (IsNetworkGame()) { // Prepare network play DebugPrint("Client setup: Calling InitNetwork2\n"); InitNetwork2(); } else { if (LocalPlayerName && strcmp(LocalPlayerName, "Anonymous")) { ThisPlayer->SetName(LocalPlayerName); } } CallbackMusicOn(); #if 0 GamePaused = true; #endif if (FlagRevealMap) { Map.Reveal(); } // // Setup game types // // FIXME: implement more game types if (GameSettings.GameType != SettingsGameTypeMapDefault) { switch (GameSettings.GameType) { case SettingsGameTypeMelee: break; case SettingsGameTypeFreeForAll: GameTypeFreeForAll(); break; case SettingsGameTypeTopVsBottom: GameTypeTopVsBottom(); break; case SettingsGameTypeLeftVsRight: GameTypeLeftVsRight(); break; case SettingsGameTypeManVsMachine: GameTypeManVsMachine(); break; case SettingsGameTypeManTeamVsMachine: GameTypeManTeamVsMachine(); // Future game type ideas #if 0 case SettingsGameTypeOneOnOne: break; case SettingsGameTypeCaptureTheFlag: break; case SettingsGameTypeGreed: break; case SettingsGameTypeSlaughter: break; case SettingsGameTypeSuddenDeath: break; case SettingsGameTypeTeamMelee: break; case SettingsGameTypeTeamCaptureTheFlag: break; #endif } } // // Graphic part // SetPlayersPalette(); InitIcons(); LoadIcons(); LoadCursors(PlayerRaces.Name[ThisPlayer->Race]); UnitUnderCursor = NoUnitP; InitMissileTypes(); #ifndef DYNAMIC_LOAD LoadMissileSprites(); #endif InitConstructions(); LoadConstructions(); LoadUnitTypes(); LoadDecorations(); InitSelections(); InitUserInterface(); UI.Load(); UI.Minimap.Create(); Map.Init(); PreprocessMap(); // // Sound part // LoadUnitSounds(); MapUnitSounds(); if (SoundEnabled()) { InitSoundClient(); } // // Spells // InitSpells(); // // Init units' groups // InitGroups(); // // Init players? // DebugPlayers(); PlayersInitAi(); // // Upgrades // InitUpgrades(); // // Dependencies // InitDependencies(); // // Buttons (botpanel) // InitButtons(); // // Triggers // InitTriggers(); SetDefaultTextColors(UI.NormalFontColor, UI.ReverseFontColor); #if 0 if (!UI.SelectedViewport) { UI.SelectedViewport = UI.Viewports; } #endif UI.SelectedViewport->Center( ThisPlayer->StartX, ThisPlayer->StartY, TileSizeX / 2, TileSizeY / 2); // // Various hacks wich must be done after the map is loaded. // // FIXME: must be done after map is loaded InitAStar(); // // FIXME: The palette is loaded after the units are created. // FIXME: This loops fixes the colors of the units. // for (i = 0; i < NumUnits; ++i) { // I don't really think that there can be any rescued // units at this point. if (Units[i]->RescuedFrom) { Units[i]->Colors = &Units[i]->RescuedFrom->UnitColors; } else { Units[i]->Colors = &Units[i]->Player->UnitColors; } } GameResult = GameNoResult; CommandLog(NULL, NoUnitP, FlushCommands, -1, -1, NoUnitP, NULL, -1); Video.ClearScreen(); }