00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "pent_include.h"
00020
00021 #include "GUIApp.h"
00022
00023 #include <SDL.h>
00024
00026 #include "Kernel.h"
00027 #include "FileSystem.h"
00028 #include "SettingManager.h"
00029 #include "ConfigFileManager.h"
00030 #include "ObjectManager.h"
00031 #include "GameInfo.h"
00032 #include "FontManager.h"
00033 #include "MemoryManager.h"
00034
00035 #include "HIDManager.h"
00036 #include "Joystick.h"
00037
00038 #include "RenderSurface.h"
00039 #include "Texture.h"
00040 #include "FixedWidthFont.h"
00041 #include "PaletteManager.h"
00042 #include "Palette.h"
00043 #include "GameData.h"
00044 #include "World.h"
00045 #include "Direction.h"
00046 #include "Game.h"
00047 #include "getObject.h"
00048
00049 #include "SavegameWriter.h"
00050 #include "Savegame.h"
00051 #include <ctime>
00052
00053 #include "Gump.h"
00054 #include "DesktopGump.h"
00055 #include "ConsoleGump.h"
00056 #include "GameMapGump.h"
00057 #include "InverterGump.h"
00058 #include "ScalerGump.h"
00059 #include "FastAreaVisGump.h"
00060 #include "MiniMapGump.h"
00061 #include "QuitGump.h"
00062 #include "MenuGump.h"
00063 #include "PentagramMenuGump.h"
00064
00065
00066 #include "BarkGump.h"
00067 #include "AskGump.h"
00068 #include "ModalGump.h"
00069
00070
00071 #include "QuickAvatarMoverProcess.h"
00072 #include "Actor.h"
00073 #include "ActorAnimProcess.h"
00074 #include "TargetedAnimProcess.h"
00075 #include "u8intrinsics.h"
00076 #include "remorseintrinsics.h"
00077 #include "Egg.h"
00078 #include "CurrentMap.h"
00079 #include "InverterProcess.h"
00080 #include "HealProcess.h"
00081 #include "SchedulerProcess.h"
00082
00083 #include "EggHatcherProcess.h"
00084 #include "UCProcess.h"
00085 #include "GumpNotifyProcess.h"
00086 #include "ActorBarkNotifyProcess.h"
00087 #include "DelayProcess.h"
00088 #include "AvatarGravityProcess.h"
00089 #include "MissileProcess.h"
00090 #include "TeleportToEggProcess.h"
00091 #include "ItemFactory.h"
00092 #include "PathfinderProcess.h"
00093 #include "AvatarMoverProcess.h"
00094 #include "ResurrectionProcess.h"
00095 #include "SplitItemProcess.h"
00096 #include "ClearFeignDeathProcess.h"
00097 #include "LoiterProcess.h"
00098 #include "AvatarDeathProcess.h"
00099 #include "GrantPeaceProcess.h"
00100 #include "CombatProcess.h"
00101 #include "FireballProcess.h"
00102 #include "DestroyItemProcess.h"
00103 #include "AmbushProcess.h"
00104 #include "Pathfinder.h"
00105
00106 #include "MovieGump.h"
00107 #include "ShapeViewerGump.h"
00108
00109 #include "AudioMixer.h"
00110
00111 #ifdef WIN32
00112 #include <windows.h>
00113 #endif
00114
00115 #if defined(WIN32) && defined(I_AM_COLOURLESS_EXPERIMENTING_WITH_HW_CURSORS)
00116 #include "Shape.h"
00117 #include "ShapeFrame.h"
00118 #include "SoftRenderSurface.h"
00119 #include "SDL_syswm.h"
00120
00121 struct HWMouseCursor {
00122 HICON hCursor;
00123 };
00124
00125 #endif
00126
00127 #include "XFormBlend.h"
00128
00129 #include "MusicProcess.h"
00130 #include "AudioProcess.h"
00131
00132 #include "util.h"
00133
00134 using std::string;
00135
00136 DEFINE_RUNTIME_CLASSTYPE_CODE(GUIApp,CoreApp);
00137
00138 GUIApp::GUIApp(int argc, const char* const* argv)
00139 : CoreApp(argc, argv), save_count(0), game(0), kernel(0), objectmanager(0),
00140 hidmanager(0), ucmachine(0), screen(0), fullscreen(false), palettemanager(0),
00141 gamedata(0), world(0), desktopGump(0), consoleGump(0), gameMapGump(0),
00142 avatarMoverProcess(0), runSDLInit(false),
00143 frameSkip(false), frameLimit(true), interpolate(false),
00144 animationRate(100), avatarInStasis(false), paintEditorItems(false),
00145 painting(false), showTouching(false), mouseX(0), mouseY(0),
00146 defMouse(0), flashingcursor(0),
00147 mouseOverGump(0), dragging(DRAG_NOT), dragging_offsetX(0),
00148 dragging_offsetY(0), inversion(0), timeOffset(0), has_cheated(false),
00149 drawRenderStats(false), ttfoverrides(false), audiomixer(0)
00150 {
00151 application = this;
00152
00153 for (int i = 0; i < MOUSE_LAST; ++i) {
00154 mouseButton[i].downGump = 0;
00155 mouseButton[i].lastDown = 0;
00156 mouseButton[i].state = MBS_HANDLED;
00157 }
00158
00159 con.AddConsoleCommand("quit", ConCmd_quit);
00160 con.AddConsoleCommand("GUIApp::quit", ConCmd_quit);
00161 con.AddConsoleCommand("QuitGump::verifyQuit", QuitGump::ConCmd_verifyQuit);
00162 con.AddConsoleCommand("ShapeViewerGump::U8ShapeViewer", ShapeViewerGump::ConCmd_U8ShapeViewer);
00163 con.AddConsoleCommand("MenuGump::showMenu", MenuGump::ConCmd_showMenu);
00164 con.AddConsoleCommand("GUIApp::drawRenderStats", ConCmd_drawRenderStats);
00165 con.AddConsoleCommand("GUIApp::engineStats", ConCmd_engineStats);
00166
00167 con.AddConsoleCommand("GUIApp::changeGame",ConCmd_changeGame);
00168 con.AddConsoleCommand("GUIApp::listGames",ConCmd_listGames);
00169
00170 con.AddConsoleCommand("GUIApp::setVideoMode",ConCmd_setVideoMode);
00171 con.AddConsoleCommand("GUIApp::toggleFullscreen",ConCmd_toggleFullscreen);
00172
00173 con.AddConsoleCommand("GUIApp::toggleAvatarInStasis",ConCmd_toggleAvatarInStasis);
00174 con.AddConsoleCommand("GUIApp::togglePaintEditorItems",ConCmd_togglePaintEditorItems);
00175 con.AddConsoleCommand("GUIApp::toggleShowTouchingItems",ConCmd_toggleShowTouchingItems);
00176
00177 con.AddConsoleCommand("GUIApp::closeItemGumps",ConCmd_closeItemGumps);
00178
00179 con.AddConsoleCommand("HIDManager::bind", HIDManager::ConCmd_bind);
00180 con.AddConsoleCommand("HIDManager::unbind", HIDManager::ConCmd_unbind);
00181 con.AddConsoleCommand("HIDManager::listbinds",
00182 HIDManager::ConCmd_listbinds);
00183 con.AddConsoleCommand("HIDManager::save", HIDManager::ConCmd_save);
00184 con.AddConsoleCommand("Kernel::processTypes", Kernel::ConCmd_processTypes);
00185 con.AddConsoleCommand("Kernel::processInfo", Kernel::ConCmd_processInfo);
00186 con.AddConsoleCommand("Kernel::listProcesses",
00187 Kernel::ConCmd_listProcesses);
00188 con.AddConsoleCommand("Kernel::toggleFrameByFrame",
00189 Kernel::ConCmd_toggleFrameByFrame);
00190 con.AddConsoleCommand("Kernel::advanceFrame", Kernel::ConCmd_advanceFrame);
00191 con.AddConsoleCommand("ObjectManager::objectTypes",
00192 ObjectManager::ConCmd_objectTypes);
00193 con.AddConsoleCommand("ObjectManager::objectInfo",
00194 ObjectManager::ConCmd_objectInfo);
00195 con.AddConsoleCommand("MemoryManager::MemInfo",
00196 MemoryManager::ConCmd_MemInfo);
00197 con.AddConsoleCommand("MemoryManager::test",
00198 MemoryManager::ConCmd_test);
00199
00200 con.AddConsoleCommand("QuickAvatarMoverProcess::startMoveUp",
00201 QuickAvatarMoverProcess::ConCmd_startMoveUp);
00202 con.AddConsoleCommand("QuickAvatarMoverProcess::startMoveDown",
00203 QuickAvatarMoverProcess::ConCmd_startMoveDown);
00204 con.AddConsoleCommand("QuickAvatarMoverProcess::startMoveLeft",
00205 QuickAvatarMoverProcess::ConCmd_startMoveLeft);
00206 con.AddConsoleCommand("QuickAvatarMoverProcess::startMoveRight",
00207 QuickAvatarMoverProcess::ConCmd_startMoveRight);
00208 con.AddConsoleCommand("QuickAvatarMoverProcess::startAscend",
00209 QuickAvatarMoverProcess::ConCmd_startAscend);
00210 con.AddConsoleCommand("QuickAvatarMoverProcess::startDescend",
00211 QuickAvatarMoverProcess::ConCmd_startDescend);
00212 con.AddConsoleCommand("QuickAvatarMoverProcess::stopMoveUp",
00213 QuickAvatarMoverProcess::ConCmd_stopMoveUp);
00214 con.AddConsoleCommand("QuickAvatarMoverProcess::stopMoveDown",
00215 QuickAvatarMoverProcess::ConCmd_stopMoveDown);
00216 con.AddConsoleCommand("QuickAvatarMoverProcess::stopMoveLeft",
00217 QuickAvatarMoverProcess::ConCmd_stopMoveLeft);
00218 con.AddConsoleCommand("QuickAvatarMoverProcess::stopMoveRight",
00219 QuickAvatarMoverProcess::ConCmd_stopMoveRight);
00220 con.AddConsoleCommand("QuickAvatarMoverProcess::stopAscend",
00221 QuickAvatarMoverProcess::ConCmd_stopAscend);
00222 con.AddConsoleCommand("QuickAvatarMoverProcess::stopDescend",
00223 QuickAvatarMoverProcess::ConCmd_stopDescend);
00224 con.AddConsoleCommand("QuickAvatarMoverProcess::toggleQuarterSpeed",
00225 QuickAvatarMoverProcess::ConCmd_toggleQuarterSpeed);
00226 con.AddConsoleCommand("QuickAvatarMoverProcess::toggleClipping",
00227 QuickAvatarMoverProcess::ConCmd_toggleClipping);
00228
00229 con.AddConsoleCommand("GameMapGump::toggleHighlightItems",
00230 GameMapGump::ConCmd_toggleHighlightItems);
00231 con.AddConsoleCommand("GameMapGump::dumpMap",
00232 GameMapGump::ConCmd_dumpMap);
00233
00234 con.AddConsoleCommand("AudioProcess::listSFX", AudioProcess::ConCmd_listSFX);
00235 con.AddConsoleCommand("AudioProcess::playSFX", AudioProcess::ConCmd_playSFX);
00236 con.AddConsoleCommand("AudioProcess::stopSFX", AudioProcess::ConCmd_stopSFX);
00237
00238
00239 }
00240
00241 GUIApp::~GUIApp()
00242 {
00243 shutdown();
00244
00245 con.RemoveConsoleCommand(GUIApp::ConCmd_quit);
00246 con.RemoveConsoleCommand(QuitGump::ConCmd_verifyQuit);
00247 con.RemoveConsoleCommand(ShapeViewerGump::ConCmd_U8ShapeViewer);
00248 con.RemoveConsoleCommand(MenuGump::ConCmd_showMenu);
00249 con.RemoveConsoleCommand(GUIApp::ConCmd_drawRenderStats);
00250 con.RemoveConsoleCommand(GUIApp::ConCmd_engineStats);
00251
00252 con.RemoveConsoleCommand(GUIApp::ConCmd_changeGame);
00253 con.RemoveConsoleCommand(GUIApp::ConCmd_listGames);
00254
00255 con.RemoveConsoleCommand(GUIApp::ConCmd_setVideoMode);
00256 con.RemoveConsoleCommand(GUIApp::ConCmd_toggleFullscreen);
00257
00258 con.RemoveConsoleCommand(GUIApp::ConCmd_toggleAvatarInStasis);
00259 con.RemoveConsoleCommand(GUIApp::ConCmd_togglePaintEditorItems);
00260 con.RemoveConsoleCommand(GUIApp::ConCmd_toggleShowTouchingItems);
00261
00262 con.RemoveConsoleCommand(GUIApp::ConCmd_closeItemGumps);
00263
00264 con.RemoveConsoleCommand(HIDManager::ConCmd_bind);
00265 con.RemoveConsoleCommand(HIDManager::ConCmd_unbind);
00266 con.RemoveConsoleCommand(HIDManager::ConCmd_listbinds);
00267 con.RemoveConsoleCommand(HIDManager::ConCmd_save);
00268 con.RemoveConsoleCommand(Kernel::ConCmd_processTypes);
00269 con.RemoveConsoleCommand(Kernel::ConCmd_processInfo);
00270 con.RemoveConsoleCommand(Kernel::ConCmd_listProcesses);
00271 con.RemoveConsoleCommand(Kernel::ConCmd_toggleFrameByFrame);
00272 con.RemoveConsoleCommand(Kernel::ConCmd_advanceFrame);
00273 con.RemoveConsoleCommand(ObjectManager::ConCmd_objectTypes);
00274 con.RemoveConsoleCommand(ObjectManager::ConCmd_objectInfo);
00275 con.RemoveConsoleCommand(MemoryManager::ConCmd_MemInfo);
00276 con.RemoveConsoleCommand(MemoryManager::ConCmd_test);
00277
00278 con.RemoveConsoleCommand(QuickAvatarMoverProcess::ConCmd_startMoveUp);
00279 con.RemoveConsoleCommand(QuickAvatarMoverProcess::ConCmd_startMoveDown);
00280 con.RemoveConsoleCommand(QuickAvatarMoverProcess::ConCmd_startMoveLeft);
00281 con.RemoveConsoleCommand(QuickAvatarMoverProcess::ConCmd_startMoveRight);
00282 con.RemoveConsoleCommand(QuickAvatarMoverProcess::ConCmd_startAscend);
00283 con.RemoveConsoleCommand(QuickAvatarMoverProcess::ConCmd_startDescend);
00284 con.RemoveConsoleCommand(QuickAvatarMoverProcess::ConCmd_stopMoveUp);
00285 con.RemoveConsoleCommand(QuickAvatarMoverProcess::ConCmd_stopMoveDown);
00286 con.RemoveConsoleCommand(QuickAvatarMoverProcess::ConCmd_stopMoveLeft);
00287 con.RemoveConsoleCommand(QuickAvatarMoverProcess::ConCmd_stopMoveRight);
00288 con.RemoveConsoleCommand(QuickAvatarMoverProcess::ConCmd_stopAscend);
00289 con.RemoveConsoleCommand(QuickAvatarMoverProcess::ConCmd_stopDescend);
00290 con.RemoveConsoleCommand(QuickAvatarMoverProcess::ConCmd_toggleQuarterSpeed);
00291 con.RemoveConsoleCommand(QuickAvatarMoverProcess::ConCmd_toggleClipping);
00292
00293 con.RemoveConsoleCommand(GameMapGump::ConCmd_toggleHighlightItems);
00294 con.RemoveConsoleCommand(GameMapGump::ConCmd_dumpMap);
00295
00296 con.RemoveConsoleCommand(AudioProcess::ConCmd_listSFX);
00297 con.RemoveConsoleCommand(AudioProcess::ConCmd_stopSFX);
00298 con.RemoveConsoleCommand(AudioProcess::ConCmd_playSFX);
00299
00300
00301
00302 FORGET_OBJECT(kernel);
00303 FORGET_OBJECT(defMouse);
00304 FORGET_OBJECT(objectmanager);
00305 FORGET_OBJECT(hidmanager);
00306 FORGET_OBJECT(audiomixer);
00307 FORGET_OBJECT(ucmachine);
00308 FORGET_OBJECT(palettemanager);
00309 FORGET_OBJECT(gamedata);
00310 FORGET_OBJECT(world);
00311 FORGET_OBJECT(ucmachine);
00312 FORGET_OBJECT(fontmanager);
00313 FORGET_OBJECT(screen);
00314 }
00315
00316
00317 void GUIApp::SDLInit()
00318 {
00319 con.Print(MM_INFO, "Initialising SDL...\n");
00320 SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK);
00321 atexit(SDL_Quit);
00322 }
00323
00324 void GUIApp::startup()
00325 {
00326 SDLInit();
00327
00328
00329 con.SetAutoPaint(conAutoPaint);
00330
00331 pout << "-- Initializing Pentagram -- " << std::endl;
00332
00333
00334 CoreApp::startup();
00335
00336 bool dataoverride;
00337 if (!settingman->get("dataoverride", dataoverride,
00338 SettingManager::DOM_GLOBAL))
00339 dataoverride = false;
00340 filesystem->initBuiltinData(dataoverride);
00341
00342 kernel = new Kernel();
00343
00345 kernel->addProcessLoader("DelayProcess",
00346 ProcessLoader<DelayProcess>::load);
00347 kernel->addProcessLoader("GravityProcess",
00348 ProcessLoader<GravityProcess>::load);
00349 kernel->addProcessLoader("AvatarGravityProcess",
00350 ProcessLoader<AvatarGravityProcess>::load);
00351 kernel->addProcessLoader("PaletteFaderProcess",
00352 ProcessLoader<PaletteFaderProcess>::load);
00353 kernel->addProcessLoader("TeleportToEggProcess",
00354 ProcessLoader<TeleportToEggProcess>::load);
00355 kernel->addProcessLoader("ActorAnimProcess",
00356 ProcessLoader<ActorAnimProcess>::load);
00357 kernel->addProcessLoader("TargetedAnimProcess",
00358 ProcessLoader<TargetedAnimProcess>::load);
00359 kernel->addProcessLoader("AvatarMoverProcess",
00360 ProcessLoader<AvatarMoverProcess>::load);
00361 kernel->addProcessLoader("QuickAvatarMoverProcess",
00362 ProcessLoader<QuickAvatarMoverProcess>::load);
00363 kernel->addProcessLoader("PathfinderProcess",
00364 ProcessLoader<PathfinderProcess>::load);
00365 kernel->addProcessLoader("SpriteProcess",
00366 ProcessLoader<SpriteProcess>::load);
00367 kernel->addProcessLoader("MissileProcess",
00368 ProcessLoader<MissileProcess>::load);
00369 kernel->addProcessLoader("CameraProcess",
00370 ProcessLoader<CameraProcess>::load);
00371 kernel->addProcessLoader("MusicProcess",
00372 ProcessLoader<MusicProcess>::load);
00373 kernel->addProcessLoader("AudioProcess",
00374 ProcessLoader<AudioProcess>::load);
00375 kernel->addProcessLoader("EggHatcherProcess",
00376 ProcessLoader<EggHatcherProcess>::load);
00377 kernel->addProcessLoader("UCProcess",
00378 ProcessLoader<UCProcess>::load);
00379 kernel->addProcessLoader("GumpNotifyProcess",
00380 ProcessLoader<GumpNotifyProcess>::load);
00381 kernel->addProcessLoader("ResurrectionProcess",
00382 ProcessLoader<ResurrectionProcess>::load);
00383 kernel->addProcessLoader("DeleteActorProcess",
00384 ProcessLoader<DestroyItemProcess>::load);
00385 kernel->addProcessLoader("DestroyItemProcess",
00386 ProcessLoader<DestroyItemProcess>::load);
00387 kernel->addProcessLoader("SplitItemProcess",
00388 ProcessLoader<SplitItemProcess>::load);
00389 kernel->addProcessLoader("ClearFeignDeathProcess",
00390 ProcessLoader<ClearFeignDeathProcess>::load);
00391 kernel->addProcessLoader("LoiterProcess",
00392 ProcessLoader<LoiterProcess>::load);
00393 kernel->addProcessLoader("AvatarDeathProcess",
00394 ProcessLoader<AvatarDeathProcess>::load);
00395 kernel->addProcessLoader("GrantPeaceProcess",
00396 ProcessLoader<GrantPeaceProcess>::load);
00397 kernel->addProcessLoader("CombatProcess",
00398 ProcessLoader<CombatProcess>::load);
00399 kernel->addProcessLoader("FireballProcess",
00400 ProcessLoader<FireballProcess>::load);
00401 kernel->addProcessLoader("HealProcess",
00402 ProcessLoader<HealProcess>::load);
00403 kernel->addProcessLoader("SchedulerProcess",
00404 ProcessLoader<SchedulerProcess>::load);
00405 kernel->addProcessLoader("InverterProcess",
00406 ProcessLoader<InverterProcess>::load);
00407 kernel->addProcessLoader("ActorBarkNotifyProcess",
00408 ProcessLoader<ActorBarkNotifyProcess>::load);
00409 kernel->addProcessLoader("JoystickCursorProcess",
00410 ProcessLoader<JoystickCursorProcess>::load);
00411 kernel->addProcessLoader("AmbushProcess",
00412 ProcessLoader<AmbushProcess>::load);
00413
00414 objectmanager = new ObjectManager();
00415
00416 GraphicSysInit();
00417
00418 SDL_ShowCursor(SDL_DISABLE);
00419 SDL_GetMouseState(&mouseX, &mouseY);
00420
00421 hidmanager = new HIDManager();
00422
00423
00424 audiomixer = new Pentagram::AudioMixer(22050,true,8);
00425
00426 pout << "-- Pentagram Initialized -- " << std::endl << std::endl;
00427
00428
00429 setupGameList();
00430 GameInfo* info = getDefaultGame();
00431 if (setupGame(info))
00432 startupGame();
00433 else
00434 startupPentagramMenu();
00435
00436
00437 con.SetAutoPaint(0);
00438
00439
00440 paint();
00441 }
00442
00443 void GUIApp::startupGame()
00444 {
00445 con.SetAutoPaint(conAutoPaint);
00446
00447 pout << std::endl << "-- Initializing Game: " << gameinfo->name << " --" << std::endl;
00448
00449 GraphicSysInit();
00450
00451
00452 std::string title = "Pentagram - ";
00453 title += getGameInfo()->getGameTitle();
00454 SDL_WM_SetCaption(title.c_str(), "");
00455
00456
00457 con.AddConsoleCommand("GUIApp::saveGame", ConCmd_saveGame);
00458 con.AddConsoleCommand("GUIApp::loadGame", ConCmd_loadGame);
00459 con.AddConsoleCommand("GUIApp::newGame", ConCmd_newGame);
00460 #ifdef DEBUG
00461 con.AddConsoleCommand("Pathfinder::visualDebug",
00462 Pathfinder::ConCmd_visualDebug);
00463 #endif
00464
00465
00466 con.AddConsoleCommand("MainActor::teleport", MainActor::ConCmd_teleport);
00467 con.AddConsoleCommand("MainActor::mark", MainActor::ConCmd_mark);
00468 con.AddConsoleCommand("MainActor::recall", MainActor::ConCmd_recall);
00469 con.AddConsoleCommand("MainActor::listmarks", MainActor::ConCmd_listmarks);
00470 con.AddConsoleCommand("Cheat::maxstats", MainActor::ConCmd_maxstats);
00471 con.AddConsoleCommand("Cheat::heal", MainActor::ConCmd_heal);
00472 con.AddConsoleCommand("Cheat::toggleInvincibility", MainActor::ConCmd_toggleInvincibility);
00473 con.AddConsoleCommand("MainActor::name", MainActor::ConCmd_name);
00474 con.AddConsoleCommand("MovieGump::play", MovieGump::ConCmd_play);
00475 con.AddConsoleCommand("MusicProcess::playMusic", MusicProcess::ConCmd_playMusic);
00476 con.AddConsoleCommand("InverterProcess::invertScreen",
00477 InverterProcess::ConCmd_invertScreen);
00478 con.AddConsoleCommand("FastAreaVisGump::toggle",
00479 FastAreaVisGump::ConCmd_toggle);
00480 con.AddConsoleCommand("MiniMapGump::toggle",
00481 MiniMapGump::ConCmd_toggle);
00482 con.AddConsoleCommand("MainActor::useBackpack",
00483 MainActor::ConCmd_useBackpack);
00484 con.AddConsoleCommand("MainActor::useInventory",
00485 MainActor::ConCmd_useInventory);
00486 con.AddConsoleCommand("MainActor::useRecall",
00487 MainActor::ConCmd_useRecall);
00488 con.AddConsoleCommand("MainActor::useBedroll",
00489 MainActor::ConCmd_useBedroll);
00490 con.AddConsoleCommand("MainActor::useKeyring",
00491 MainActor::ConCmd_useKeyring);
00492 con.AddConsoleCommand("MainActor::toggleCombat",
00493 MainActor::ConCmd_toggleCombat);
00494
00495 gamedata = new GameData();
00496
00497 std::string bindingsfile;
00498 if (GAME_IS_U8) {
00499 bindingsfile = "@data/u8bindings.ini";
00500 } else if (GAME_IS_REMORSE) {
00501 bindingsfile = "@data/remorsebindings.ini";
00502 }
00503 if (!bindingsfile.empty()) {
00504
00505 if (configfileman->readConfigFile(bindingsfile,
00506 "bindings", true))
00507 con.Printf(MM_INFO, "%s... Ok\n", bindingsfile.c_str());
00508 else
00509 con.Printf(MM_MINOR_WARN, "%s... Failed\n", bindingsfile.c_str());
00510 }
00511
00512 hidmanager->loadBindings();
00513
00514 if (GAME_IS_U8) {
00515 ucmachine = new UCMachine(U8Intrinsics, 256);
00516 } else if (GAME_IS_REMORSE) {
00517 ucmachine = new UCMachine(RemorseIntrinsics, 308);
00518 } else {
00519 CANT_HAPPEN_MSG("Invalid game type.");
00520 }
00521
00522 inBetweenFrame = 0;
00523 lerpFactor = 256;
00524
00525
00526 world = new World();
00527 world->initMaps();
00528
00529 game = Game::createGame(getGameInfo());
00530
00531 settingman->setDefault("ttf", false);
00532 settingman->get("ttf", ttfoverrides);
00533
00534 game->loadFiles();
00535 gamedata->setupFontOverrides();
00536
00537
00538 con.SetAutoPaint(0);
00539
00540
00541 if (getGameInfo()->type == GameInfo::GAME_U8)
00542 audiomixer->openMidiOutput();
00543
00544 #if 1
00545 newGame();
00546 #else
00547 loadGame("@save/quicksave");
00548 #endif
00549
00550 consoleGump->HideConsole();
00551
00552 pout << "-- Game Initialized --" << std::endl << std::endl;
00553 }
00554
00555 void GUIApp::startupPentagramMenu()
00556 {
00557 con.SetAutoPaint(conAutoPaint);
00558
00559 pout << std::endl << "-- Initializing Pentagram Menu -- " << std::endl;
00560
00561 setupGame(getGameInfo("pentagram"));
00562 assert(gameinfo);
00563
00564 GraphicSysInit();
00565
00566
00567 con.SetAutoPaint(0);
00568 consoleGump->HideConsole();
00569
00570 Pentagram::Rect dims;
00571 desktopGump->GetDims(dims);
00572
00573 Gump* menugump = new PentagramMenuGump(0,0,dims.w,dims.h);
00574 menugump->InitGump(0, true);
00575 }
00576
00577 void GUIApp::shutdown()
00578 {
00579 shutdownGame(false);
00580 }
00581
00582 void GUIApp::shutdownGame(bool reloading)
00583 {
00584 pout << "-- Shutting down Game -- " << std::endl;
00585
00586
00587
00588 SDL_WM_SetCaption("Pentagram", "");
00589
00590 textmodes.clear();
00591
00592
00593 while (!cursors.empty()) cursors.pop();
00594 pushMouseCursor();
00595
00596 if (audiomixer) {
00597 audiomixer->closeMidiOutput();
00598 audiomixer->reset();
00599 }
00600
00601 FORGET_OBJECT(world);
00602 objectmanager->reset();
00603 FORGET_OBJECT(ucmachine);
00604 kernel->reset();
00605 palettemanager->reset();
00606 fontmanager->resetGameFonts();
00607
00608 FORGET_OBJECT(game);
00609 FORGET_OBJECT(gamedata);
00610
00611 desktopGump = 0;
00612 consoleGump = 0;
00613 gameMapGump = 0;
00614 scalerGump = 0;
00615 inverterGump = 0;
00616
00617 timeOffset = -(sint32)Kernel::get_instance()->getFrameNum();
00618 inversion = 0;
00619 save_count = 0;
00620 has_cheated = false;
00621
00622
00623 con.RemoveConsoleCommand(GUIApp::ConCmd_saveGame);
00624 con.RemoveConsoleCommand(GUIApp::ConCmd_loadGame);
00625 con.RemoveConsoleCommand(GUIApp::ConCmd_newGame);
00626 #ifdef DEBUG
00627 con.RemoveConsoleCommand(Pathfinder::ConCmd_visualDebug);
00628 #endif
00629
00630
00631 con.RemoveConsoleCommand(MainActor::ConCmd_teleport);
00632 con.RemoveConsoleCommand(MainActor::ConCmd_mark);
00633 con.RemoveConsoleCommand(MainActor::ConCmd_recall);
00634 con.RemoveConsoleCommand(MainActor::ConCmd_listmarks);
00635 con.RemoveConsoleCommand(MainActor::ConCmd_maxstats);
00636 con.RemoveConsoleCommand(MainActor::ConCmd_heal);
00637 con.RemoveConsoleCommand(MainActor::ConCmd_toggleInvincibility);
00638 con.RemoveConsoleCommand(MainActor::ConCmd_name);
00639 con.RemoveConsoleCommand(MovieGump::ConCmd_play);
00640 con.RemoveConsoleCommand(MusicProcess::ConCmd_playMusic);
00641 con.RemoveConsoleCommand(InverterProcess::ConCmd_invertScreen);
00642 con.RemoveConsoleCommand(FastAreaVisGump::ConCmd_toggle);
00643 con.RemoveConsoleCommand(MiniMapGump::ConCmd_toggle);
00644 con.RemoveConsoleCommand(MainActor::ConCmd_useBackpack);
00645 con.RemoveConsoleCommand(MainActor::ConCmd_useInventory);
00646 con.RemoveConsoleCommand(MainActor::ConCmd_useRecall);
00647 con.RemoveConsoleCommand(MainActor::ConCmd_useBedroll);
00648 con.RemoveConsoleCommand(MainActor::ConCmd_useKeyring);
00649 con.RemoveConsoleCommand(MainActor::ConCmd_toggleCombat);
00650
00651
00652
00653 CoreApp::killGame();
00654
00655 pout << "-- Game Shutdown -- " << std::endl;
00656
00657 if (reloading) {
00658 Pentagram::Rect dims;
00659 screen->GetSurfaceDims(dims);
00660
00661 con.Print(MM_INFO, "Creating Desktop...\n");
00662 desktopGump = new DesktopGump(0,0, dims.w, dims.h);
00663 desktopGump->InitGump(0);
00664 desktopGump->MakeFocus();
00665
00666 con.Print(MM_INFO, "Creating Graphics Console...\n");
00667 consoleGump = new ConsoleGump(0, 0, dims.w, dims.h);
00668 consoleGump->InitGump(0);
00669
00670 enterTextMode(consoleGump);
00671 }
00672 }
00673
00674 void GUIApp::changeGame(Pentagram::istring newgame)
00675 {
00676 change_gamename = newgame;
00677 }
00678
00679 void GUIApp::DeclareArgs()
00680 {
00681
00682 CoreApp::DeclareArgs();
00683
00684
00685 }
00686
00687 void GUIApp::run()
00688 {
00689 isRunning = true;
00690
00691 sint32 next_ticks = SDL_GetTicks()*3;
00692
00693
00694
00695 bool repaint;
00696
00697 SDL_Event event;
00698 while (isRunning) {
00699 inBetweenFrame = true;
00700
00701 if (!frameLimit) {
00702 repaint = false;
00703
00704 if (kernel->runProcesses()) repaint = true;
00705 desktopGump->Run(kernel->getFrameNum());
00706 inBetweenFrame = false;
00707 next_ticks = animationRate + SDL_GetTicks()*3;
00708 lerpFactor = 256;
00709 }
00710 else
00711 {
00712 sint32 ticks = SDL_GetTicks()*3;
00713 sint32 diff = next_ticks - ticks;
00714 repaint = false;
00715
00716 while (diff < 0) {
00717 next_ticks += animationRate;
00718 if (kernel->runProcesses()) repaint = true;
00719 desktopGump->Run(kernel->getFrameNum());
00720 #if 0
00721 perr << "--------------------------------------" << std::endl;
00722 perr << "NEW FRAME" << std::endl;
00723 perr << "--------------------------------------" << std::endl;
00724 #endif
00725 inBetweenFrame = false;
00726
00727 ticks = SDL_GetTicks()*3;
00728
00729
00730
00731 if (!frameSkip && diff <= -animationRate*2) next_ticks = animationRate + ticks;
00732
00733 diff = next_ticks - ticks;
00734 if (!frameSkip) break;
00735 }
00736
00737
00738 lerpFactor = ((animationRate-diff)*256)/animationRate;
00739
00740 if (!interpolate || kernel->isPaused() || lerpFactor > 256)
00741 lerpFactor = 256;
00742 }
00743
00744
00745 repaint = true;
00746
00747
00748 while (isRunning && SDL_PollEvent(&event)) {
00749 handleEvent(event);
00750 }
00751 handleDelayedEvents();
00752 hidmanager->handleDelayedEvents();
00753
00754
00755 paint();
00756
00757 if (!change_gamename.empty()) {
00758 pout << "Changing Game to: " << change_gamename << std::endl;
00759
00760 GameInfo* info = getGameInfo(change_gamename);
00761
00762 if (info) {
00763 shutdownGame();
00764
00765 change_gamename.clear();
00766
00767 if (setupGame(info))
00768 startupGame();
00769 else
00770 startupPentagramMenu();
00771 }
00772 else {
00773 perr << "Game '" << change_gamename << "' not found" << std::endl;
00774 change_gamename.clear();
00775 }
00776 }
00777
00778
00779 SDL_Delay(5);
00780 }
00781 }
00782
00783
00784
00785 void GUIApp::conAutoPaint(void)
00786 {
00787 GUIApp *app = GUIApp::get_instance();
00788 if (app && !app->isPainting()) app->paint();
00789 }
00790
00791 #if defined(WIN32) && defined(I_AM_COLOURLESS_EXPERIMENTING_WITH_HW_CURSORS)
00792
00793 WNDPROC oldWindowProc = 0;
00794 bool allow_set_cursor = true;
00795
00796 LRESULT CALLBACK GUIApp::myWindowProc(
00797 HWND hwnd,
00798 UINT uMsg,
00799 WPARAM wParam,
00800 LPARAM lParam
00801 )
00802 {
00803 if (uMsg == WM_SETCURSOR) {
00804 if ( allow_set_cursor = (LOWORD(lParam) == HTCLIENT) ) {
00805 GUIApp *app = GUIApp::get_instance();
00806 GameData *gamedata = app->gamedata;
00807
00808 if (gamedata) {
00809 Shape* mouse = gamedata->getMouse();
00810 if (mouse) {
00811 int frame = app->getMouseFrame();
00812 if (frame >= 0)
00813 SetCursor(app->hwcursors[frame].hCursor);
00814 }
00815 }
00816 return TRUE;
00817 }
00818 }
00819
00820 return CallWindowProc(oldWindowProc, hwnd, uMsg, wParam, lParam);
00821 }
00822
00823 void GUIApp::CreateHWCursors()
00824 {
00825 Shape* mouse = gamedata->getMouse();
00826 hwcursors = new HWMouseCursor[mouse->frameCount()];
00827 std::memset (hwcursors, 0, sizeof(HWMouseCursor) * mouse->frameCount());
00828
00829 for (uint32 frame = 0; frame < mouse->frameCount(); frame++)
00830 {
00831 ShapeFrame *f = mouse->getFrame(frame);
00832 uint32 bpp = BaseSoftRenderSurface::format.s_bpp;
00833 int buf_width = f->width;
00834 int buf_height = f->height;
00835
00836
00837 if (bpp != 32) buf_width = (buf_width+1)&~1;
00838
00839 uint8 *buf = new uint8 [bpp/8 * buf_width * buf_height];
00840
00841 RenderSurface *surf;
00842
00843 if (bpp == 32)
00844 surf = new SoftRenderSurface<uint32>(buf_width, buf_height, buf);
00845 else
00846 surf = new SoftRenderSurface<uint16>(buf_width, buf_height, buf);
00847
00848 surf->BeginPainting();
00849 surf->Fill32(0x00FF00FF, 0, 0, buf_width, buf_height);
00850 surf->Paint(mouse, frame, f->xoff, f->yoff);
00851 surf->EndPainting();
00852
00853 int clear_col = PACK_RGB8(0xFF,0x00,0xFF);
00854
00855
00856
00857
00858
00859
00860 uint32 bit_width = (buf_width+15)&~15;
00861 uint8 *buf_mask = new uint8 [bit_width/8 * buf_height*2];
00862
00863
00864 std::memset(buf_mask, 0x00, bit_width/8 * buf_height * 2);
00865
00866
00867 if (bpp == 32)
00868 {
00869 uint32 *buf32 = (uint32*)buf;
00870 for (int y = 0; y < buf_height; y++)
00871 {
00872 for (int x = 0; x < buf_width; x++)
00873 {
00874 bool black = (x & 1) == (y & 1);
00875 uint32 bit = y * bit_width + x;
00876 uint32 byte = bit/8;
00877 bit = 7-(bit % 8);
00878
00879
00880 if (buf32[buf_width*y + x] == clear_col)
00881 {
00882 buf32[buf_width*y + x] = 0;
00883 buf_mask[byte] |= 1<< bit;
00884 }
00885
00886 else if (buf32[buf_width*y + x])
00887 buf_mask[byte+((buf_height*bit_width)/8)] |= 1<<bit;
00888 }
00889 }
00890 }
00891 else
00892 {
00893 uint16 *buf16 = (uint16*)buf;
00894 for (int y = 0; y < buf_height; y++)
00895 {
00896 for (int x = 0; x < buf_width; x++)
00897 {
00898 bool black = (x & 1) == (y & 1);
00899 uint32 bit = y * bit_width + x;
00900 uint32 byte = bit/8;
00901 bit = 7-(bit % 8);
00902
00903
00904 if (buf16[buf_width*y + x] == clear_col)
00905 {
00906 buf16[buf_width*y + x] = 0;
00907 buf_mask[byte] |= 1<< bit;
00908 }
00909
00910 else if (buf16[buf_width*y + x])
00911 buf_mask[byte+((buf_height*bit_width)/8)] |= 1<<bit;
00912 }
00913 }
00914 }
00915
00916
00917 ICONINFO iconinfo;
00918 iconinfo.fIcon = FALSE;
00919 iconinfo.xHotspot = f->xoff;
00920 iconinfo.yHotspot = f->yoff;
00921 iconinfo.hbmMask = CreateBitmap(buf_width, buf_height, 1, 1, buf_mask);
00922 iconinfo.hbmColor = CreateBitmap(buf_width, buf_height, 1, bpp, buf);
00923
00924 hwcursors[frame].hCursor = CreateIconIndirect (&iconinfo);
00925
00926 DeleteObject(iconinfo.hbmMask);
00927 DeleteObject(iconinfo.hbmColor);
00928
00929 delete [] buf;
00930 delete [] buf_mask;
00931 delete surf;
00932 }
00933
00934
00935 SDL_SysWMinfo info;
00936 info.version.major = SDL_MAJOR_VERSION;
00937 info.version.minor = SDL_MINOR_VERSION;
00938 info.version.patch = SDL_PATCHLEVEL;
00939 SDL_GetWMInfo(&info);
00940 oldWindowProc = (WNDPROC) GetWindowLongPtr(info.window, GWLP_WNDPROC);
00941 SetWindowLongPtr(info.window, GWLP_WNDPROC, (LONG) myWindowProc);
00942
00943 }
00944 #endif
00945
00946
00947 void GUIApp::paint()
00948 {
00949 if(!screen)
00950 return;
00951
00952 painting = true;
00953
00954
00955 screen->BeginPainting();
00956
00957
00958 Pentagram::Rect dims;
00959 screen->GetSurfaceDims(dims);
00960
00961 long before_gumps = SDL_GetTicks();
00962 desktopGump->Paint(screen, lerpFactor, false);
00963 long after_gumps = SDL_GetTicks();
00964
00965
00966 if (gamedata) {
00967 Shape* mouse = gamedata->getMouse();
00968 if (mouse) {
00969 int frame = getMouseFrame();
00970 if (frame >= 0)
00971 {
00972 #if defined(WIN32) && defined(I_AM_COLOURLESS_EXPERIMENTING_WITH_HW_CURSORS)
00973 if (allow_set_cursor) SetCursor(hwcursors[frame].hCursor);
00974 #else
00975 screen->Paint(mouse, frame, mouseX, mouseY, true);
00976 #endif
00977 }
00978 }
00979 }
00980 else {
00981 if (getMouseFrame() != -1)
00982 screen->Blit(defMouse, 0, 0, defMouse->width, defMouse->height, mouseX, mouseY);
00983 }
00984
00985 static long prev = 0;
00986 long now = SDL_GetTicks();
00987 long diff = now - prev;
00988 if (diff == 0) diff = 1;
00989 prev = now;
00990
00991 char buf[256];
00992 FixedWidthFont *confont = con.GetConFont();
00993 int v_offset = 0;
00994 int char_w = confont->width;
00995
00996 if (drawRenderStats)
00997 {
00998 snprintf(buf, 255, "Rendering time %li ms %li FPS ", diff, 1000/diff);
00999 screen->PrintTextFixed(confont, buf, dims.w-char_w*strlen(buf), v_offset);
01000 v_offset += confont->height;
01001
01002 snprintf(buf, 255, "Paint Gumps %li ms ", after_gumps-before_gumps);
01003 screen->PrintTextFixed(confont, buf, dims.w-char_w*strlen(buf), v_offset);
01004 v_offset += confont->height;
01005
01006 snprintf(buf, 255, "t %02d:%02d gh %i ", I_getTimeInMinutes(0,0), I_getTimeInSeconds(0,0)%60, I_getTimeInGameHours(0,0));
01007 screen->PrintTextFixed(confont, buf, dims.w-char_w*strlen(buf), v_offset);
01008 v_offset += confont->height;
01009 }
01010
01011
01012 screen->EndPainting();
01013
01014 painting = false;
01015 }
01016
01017 bool GUIApp::isMouseDown(MouseButton button)
01018 {
01019 return (mouseButton[button].state & MBS_DOWN);
01020 }
01021
01022 int GUIApp::getMouseLength(int mx, int my)
01023 {
01024 Pentagram::Rect dims;
01025 screen->GetSurfaceDims(dims);
01026
01027 int dx = mx - dims.w/2;
01028 int dy = (dims.h/2+14) - my;
01029
01030 int shortsq = (dims.w / 8);
01031 if (dims.h / 6 < shortsq)
01032 shortsq = (dims.h / 6);
01033 shortsq = shortsq*shortsq;
01034
01035 int mediumsq = ((dims.w * 4) / 10);
01036 if (((dims.h * 4) / 10) < mediumsq)
01037 mediumsq = ((dims.h * 4) / 10);
01038 mediumsq = mediumsq * mediumsq;
01039
01040 int dsq = dx*dx+dy*dy;
01041
01042
01043 if (dsq <= shortsq) {
01044 return 0;
01045 } else if (dsq <= mediumsq) {
01046 return 1;
01047 } else {
01048 return 2;
01049 }
01050 }
01051
01052 int GUIApp::getMouseDirection(int mx, int my)
01053 {
01054 Pentagram::Rect dims;
01055 screen->GetSurfaceDims(dims);
01056
01057 int dx = mx - dims.w/2;
01058 int dy = (dims.h/2+14) - my;
01059
01060 return ((Get_direction(dy*2, dx))+1)%8;
01061 }
01062
01063 int GUIApp::getMouseFrame()
01064 {
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080 MouseCursor cursor = cursors.top();
01081
01082 if (flashingcursor > 0) {
01083 if (SDL_GetTicks() < flashingcursor + 250)
01084 cursor = MOUSE_CROSS;
01085 else
01086 flashingcursor = 0;
01087 }
01088
01089
01090 switch (cursor) {
01091 case MOUSE_NORMAL:
01092 {
01093 bool combat = false;
01094 MainActor* av = getMainActor();
01095 if (av) { combat = av->isInCombat(); }
01096
01097
01098 int frame = getMouseDirection(mouseX, mouseY);
01099
01106 int offset = getMouseLength(mouseX, mouseY) * 8;
01107 if (combat && offset != 16)
01108 offset = 25;
01109 return frame + offset;
01110 }
01112 case MOUSE_NONE: return -1;
01113 case MOUSE_TARGET: return 34;
01114 case MOUSE_PENTAGRAM: return 35;
01115 case MOUSE_HAND: return 36;
01116 case MOUSE_QUILL: return 38;
01117 case MOUSE_MAGGLASS: return 39;
01118 case MOUSE_CROSS: return 40;
01119 default: return -1;
01120 }
01121
01122 }
01123
01124 void GUIApp::setMouseCoords(int mx, int my)
01125 {
01126 Pentagram::Rect dims;
01127 screen->GetSurfaceDims(dims);
01128
01129 if (mx < dims.x)
01130 mx = dims.x;
01131 else if (mx > dims.w)
01132 mx = dims.w;
01133
01134 if (my < dims.y)
01135 my = dims.y;
01136 else if (my > dims.h)
01137 my = dims.h;
01138
01139 mouseX = mx; mouseY = my;
01140 Gump * gump = desktopGump->OnMouseMotion(mx, my);
01141 if (gump && mouseOverGump != gump->getObjId())
01142 {
01143 Gump * oldGump = getGump(mouseOverGump);
01144 std::list<Gump*> oldgumplist;
01145 std::list<Gump*> newgumplist;
01146
01147
01148 if (oldGump) {
01149 while (oldGump) {
01150 oldgumplist.push_front(oldGump);
01151 oldGump = oldGump->GetParent();
01152 }
01153 }
01154 Gump* newGump = gump;
01155 while (newGump) {
01156 newgumplist.push_front(newGump);
01157 newGump = newGump->GetParent();
01158 }
01159
01160 std::list<Gump*>::iterator olditer = oldgumplist.begin();
01161 std::list<Gump*>::iterator newiter = newgumplist.begin();
01162
01163
01164 while (olditer != oldgumplist.end() &&
01165 newiter != newgumplist.end() &&
01166 *olditer == *newiter)
01167 {
01168 ++olditer; ++newiter;
01169 }
01170
01171
01172 for (; olditer != oldgumplist.end(); ++olditer)
01173 (*olditer)->OnMouseLeft();
01174
01175 mouseOverGump = gump->getObjId();
01176
01177 for (; newiter != newgumplist.end(); ++newiter)
01178 (*newiter)->OnMouseOver();
01179 }
01180
01181 if (dragging == DRAG_NOT) {
01182 if (mouseButton[BUTTON_LEFT].state & MBS_DOWN) {
01183 int startx = mouseButton[BUTTON_LEFT].downX;
01184 int starty = mouseButton[BUTTON_LEFT].downY;
01185 if (abs(startx - mx) > 2 ||
01186 abs(starty - my) > 2)
01187 {
01188 startDragging(startx, starty);
01189 }
01190 }
01191 }
01192
01193 if (dragging == DRAG_OK || dragging == DRAG_TEMPFAIL) {
01194 moveDragging(mx, my);
01195 }
01196 }
01197
01198 void GUIApp::setMouseCursor(MouseCursor cursor)
01199 {
01200 cursors.pop();
01201 cursors.push(cursor);
01202 }
01203
01204 void GUIApp::flashCrossCursor()
01205 {
01206 flashingcursor = SDL_GetTicks();
01207 }
01208
01209 void GUIApp::pushMouseCursor()
01210 {
01211 cursors.push(MOUSE_NORMAL);
01212 }
01213
01214 void GUIApp::popMouseCursor()
01215 {
01216 cursors.pop();
01217 }
01218
01219 void GUIApp::GraphicSysInit()
01220 {
01221 settingman->setDefault("fullscreen", false);
01222 settingman->setDefault("width", 640);
01223 settingman->setDefault("height", 480);
01224 settingman->setDefault("bpp", 32);
01225
01226 bool new_fullscreen;
01227 int width, height, bpp;
01228 settingman->get("fullscreen", new_fullscreen);
01229 settingman->get("width", width);
01230 settingman->get("height", height);
01231 settingman->get("bpp", bpp);
01232
01233 #ifdef UNDER_CE
01234 width = 240;
01235 height = 320;
01236 #endif
01237
01238 #if 0
01239
01240 settingman->set("width", width);
01241 settingman->set("height", height);
01242 settingman->set("bpp", bpp);
01243 settingman->set("fullscreen", new_fullscreen);
01244 #endif
01245
01246 if (screen) {
01247 Pentagram::Rect old_dims;
01248 screen->GetSurfaceDims(old_dims);
01249 if (new_fullscreen == fullscreen && width == old_dims.w && height == old_dims.h) return;
01250 bpp = RenderSurface::format.s_bpp;
01251
01252 delete screen;
01253 }
01254 screen = 0;
01255
01256 fullscreen = new_fullscreen;
01257
01258
01259 con.Printf(MM_INFO, "Setting Video Mode %ix%ix%i %s...\n", width, height, bpp, fullscreen?"fullscreen":"windowed");
01260
01261 RenderSurface *new_screen = RenderSurface::SetVideoMode(width, height, bpp, fullscreen, false);
01262
01263 if (!new_screen)
01264 {
01265 perr << "Unable to set new video mode. Trying 640x480x32 windowed" << std::endl;
01266 new_screen = RenderSurface::SetVideoMode(640, 480, 32, fullscreen=false, false);
01267 }
01268
01269 if (!new_screen)
01270 {
01271 perr << "Unable to set video mode. Exiting." << std::endl;
01272 std::exit(-1);
01273 }
01274
01275 if (desktopGump) {
01276 palettemanager->RenderSurfaceChanged(new_screen);
01277 static_cast<DesktopGump*>(desktopGump)->RenderSurfaceChanged(new_screen);
01278 screen = new_screen;
01279 paint();
01280 return;
01281 }
01282
01283
01284 SDL_WM_SetCaption("Pentagram", "");
01285
01286
01287 con.Print(MM_INFO, "Loading Default Mouse Cursor...\n");
01288 IDataSource *dm = filesystem->ReadFile("@data/mouse.tga");
01289 if (dm) defMouse = Texture::Create(dm, "@data/mouse.tga");
01290 else defMouse = 0;
01291 if (!defMouse)
01292 {
01293 perr << "Unable to load '@data/mouse.tga'" << ". Exiting" << std::endl;
01294 std::exit(-1);
01295 }
01296 delete dm;
01297 pushMouseCursor();
01298
01299 std::string alt_confont;
01300 bool confont_loaded = false;
01301
01302 if (settingman->get("console_font", alt_confont)) {
01303 con.Print(MM_INFO, "Alternate console font found...\n");
01304 confont_loaded = LoadConsoleFont(alt_confont);
01305 }
01306
01307 if (!confont_loaded) {
01308 con.Print(MM_INFO, "Loading default console font...\n");
01309 if (!LoadConsoleFont("@data/fixedfont.ini")) {
01310 perr << "Failed to load console font. Exiting" << std::endl;
01311 std::exit(-1);
01312 }
01313 }
01314
01315 desktopGump = new DesktopGump(0,0, width, height);
01316 desktopGump->InitGump(0);
01317 desktopGump->MakeFocus();
01318
01319 consoleGump = new ConsoleGump(0, 0, width, height);
01320 consoleGump->InitGump(0);
01321
01322 screen = new_screen;
01323
01324 bool ttf_antialiasing = true;
01325 settingman->setDefault("ttf_antialiasing", true);
01326 settingman->get("ttf_antialiasing", ttf_antialiasing);
01327
01328 fontmanager = new FontManager(ttf_antialiasing);
01329 palettemanager = new PaletteManager(new_screen);
01330
01331
01332 fontmanager->loadTTFont(0, "Vera.ttf", 18, 0xFFFFFF, 0);
01333 fontmanager->loadTTFont(1, "VeraBd.ttf", 12, 0xFFFFFF, 0);
01334
01335 fontmanager->loadTTFont(2, "Vera.ttf", 8, 0xA0A0A0, 0);
01336
01337 paint();
01338 }
01339
01340 void GUIApp::changeVideoMode(int width, int height, int new_fullscreen)
01341 {
01342 if (new_fullscreen == -2) settingman->set("fullscreen", !fullscreen);
01343 else if (new_fullscreen == 0) settingman->set("fullscreen", false);
01344 else if (new_fullscreen == 1) settingman->set("fullscreen", true);
01345
01346 if (width > 0) settingman->set("width", width);
01347 if (height > 0) settingman->set("height", height);
01348
01349 GraphicSysInit();
01350 }
01351
01352 bool GUIApp::LoadConsoleFont(std::string confontini)
01353 {
01354
01355 con.Printf(MM_INFO, "Loading console font config: %s... ", confontini.c_str());
01356 if(configfileman->readConfigFile(confontini, "confont", true))
01357 pout << "Ok" << std::endl;
01358 else {
01359 pout << "Failed" << std::endl;
01360 return false;
01361 }
01362
01363 FixedWidthFont *confont = FixedWidthFont::Create("confont");
01364
01365 if (!confont) {
01366 perr << "Failed to load Console Font." << std::endl;
01367 return false;
01368 }
01369
01370 con.SetConFont(confont);
01371
01372 return true;
01373 }
01374
01375 void GUIApp::enterTextMode(Gump *gump)
01376 {
01377 if (!textmodes.empty()) {
01378 textmodes.remove(gump->getObjId());
01379 } else {
01380 SDL_EnableUNICODE(1);
01381 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY,
01382 SDL_DEFAULT_REPEAT_INTERVAL);
01383 }
01384 textmodes.push_front(gump->getObjId());
01385 }
01386
01387 void GUIApp::leaveTextMode(Gump *gump)
01388 {
01389 if (textmodes.empty()) return;
01390 textmodes.remove(gump->getObjId());
01391 if (textmodes.empty()) {
01392 SDL_EnableUNICODE(0);
01393 SDL_EnableKeyRepeat(0, 0);
01394 }
01395 }
01396
01397 void GUIApp::handleEvent(const SDL_Event& event)
01398 {
01399 uint32 now = SDL_GetTicks();
01400 bool handled = false;
01401
01402
01403 if (!textmodes.empty()) {
01404 Gump *gump = 0;
01405
01406 while (!textmodes.empty())
01407 {
01408 gump = p_dynamic_cast<Gump*>(objectmanager->getObject(textmodes.front()));
01409 if (gump) break;
01410
01411 textmodes.pop_front();
01412 }
01413
01414 if (gump) {
01415 switch (event.type) {
01416 case SDL_KEYDOWN:
01417
01418
01419 if (event.key.keysym.sym == SDLK_BACKQUOTE ||
01420 event.key.keysym.sym == SDLK_F5)
01421 break;
01422
01423 #ifdef WIN32
01424
01425 if (event.key.keysym.sym == SDLK_v && event.key.keysym.mod & KMOD_CTRL)
01426 {
01427 if (!IsClipboardFormatAvailable(CF_TEXT))
01428 return ;
01429 if (!OpenClipboard(NULL))
01430 return;
01431
01432 HGLOBAL hglb = GetClipboardData(CF_TEXT);
01433 if (hglb != NULL)
01434 {
01435 LPTSTR lptstr = reinterpret_cast<LPTSTR>(GlobalLock(hglb));
01436 if (lptstr != NULL)
01437 {
01438
01439 while (*lptstr >= ' ') gump->OnTextInput(*lptstr++);
01440
01441 GlobalUnlock(hglb);
01442 }
01443 }
01444 CloseClipboard();
01445 return;
01446 }
01447 #endif
01448
01449 if (event.key.keysym.unicode >= ' ' &&
01450 event.key.keysym.unicode <= 255 &&
01451 !(event.key.keysym.unicode >= 0x7F &&
01452 event.key.keysym.unicode <= 0x9F))
01453 {
01454 gump->OnTextInput(event.key.keysym.unicode);
01455 }
01456
01457 gump->OnKeyDown(event.key.keysym.sym, event.key.keysym.mod);
01458 return;
01459
01460 case SDL_KEYUP:
01461
01462
01463 if (event.key.keysym.sym == SDLK_BACKQUOTE ||
01464 event.key.keysym.sym == SDLK_F5)
01465 break;
01466
01467
01468 gump->OnKeyUp(event.key.keysym.sym);
01469 return;
01470
01471 default: break;
01472 }
01473 }
01474 }
01475
01476
01477 switch (event.type) {
01478
01480
01481 case SDL_QUIT:
01482 {
01483 isRunning = false;
01484 }
01485 break;
01486
01487 case SDL_ACTIVEEVENT:
01488 {
01489
01490 }
01491 break;
01492
01493
01494
01495
01496
01497 case SDL_MOUSEBUTTONDOWN:
01498 {
01499 int button = event.button.button;
01500 int mx = event.button.x;
01501 int my = event.button.y;
01502
01503 if (button >= MOUSE_LAST)
01504 break;
01505
01506 Gump *mousedowngump = desktopGump->OnMouseDown(button, mx, my);
01507 if (mousedowngump)
01508 {
01509 mouseButton[button].downGump = mousedowngump->getObjId();
01510 handled = true;
01511 }
01512 else
01513 mouseButton[button].downGump = 0;
01514
01515 mouseButton[button].curDown = now;
01516 mouseButton[button].downX = mx;
01517 mouseButton[button].downY = my;
01518 mouseButton[button].state |= MBS_DOWN;
01519 mouseButton[button].state &= ~MBS_HANDLED;
01520
01521 if (now - mouseButton[button].lastDown < DOUBLE_CLICK_TIMEOUT) {
01522 if (dragging == DRAG_NOT) {
01523 Gump* gump = getGump(mouseButton[button].downGump);
01524 if (gump)
01525 {
01526 int mx2 = mx, my2 = my;
01527 Gump *parent = gump->GetParent();
01528 if (parent) parent->ScreenSpaceToGump(mx2,my2);
01529 gump->OnMouseDouble(button, mx2, my2);
01530 }
01531 mouseButton[button].state |= MBS_HANDLED;
01532 mouseButton[button].lastDown = 0;
01533 }
01534 }
01535 mouseButton[button].lastDown = now;
01536 }
01537 break;
01538
01539 case SDL_MOUSEBUTTONUP:
01540 {
01541 int button = event.button.button;
01542 int mx = event.button.x;
01543 int my = event.button.y;
01544
01545 if (button >= MOUSE_LAST)
01546 break;
01547
01548 mouseButton[button].state &= ~MBS_DOWN;
01549
01550
01551
01552 mouseButton[button].downX = mx;
01553 mouseButton[button].downY = my;
01554
01555
01556 Gump* gump = getGump(mouseButton[button].downGump);
01557 if (gump)
01558 {
01559 int mx2 = mx, my2 = my;
01560 Gump *parent = gump->GetParent();
01561 if (parent)
01562 parent->ScreenSpaceToGump(mx2,my2);
01563 gump->OnMouseUp(button, mx2, my2);
01564 handled = true;
01565 }
01566
01567 if (button == BUTTON_LEFT && dragging != DRAG_NOT) {
01568 stopDragging(mx, my);
01569 handled = true;
01570 break;
01571 }
01572 }
01573 break;
01574
01575 case SDL_MOUSEMOTION:
01576 {
01577 int mx = event.button.x;
01578 int my = event.button.y;
01579 setMouseCoords(mx, my);
01580 }
01581 break;
01582
01583 case SDL_KEYDOWN:
01584 {
01585 if (dragging != DRAG_NOT) break;
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605 }
01606 break;
01607
01608 case SDL_KEYUP:
01609 {
01610 if (dragging != DRAG_NOT) break;
01611
01612 switch (event.key.keysym.sym) {
01613 case SDLK_q:
01614 if (event.key.keysym.mod & KMOD_CTRL)
01615 ForceQuit();
01616 break;
01617 case SDLK_LEFTBRACKET: gameMapGump->IncSortOrder(-1); break;
01618 case SDLK_RIGHTBRACKET: gameMapGump->IncSortOrder(+1); break;
01619
01620 default: break;
01621 }
01622 }
01623 break;
01624
01625
01626
01627 default:
01628 break;
01629 }
01630
01631 if (dragging == DRAG_NOT && ! handled) {
01632 if (hidmanager->handleEvent(event))
01633 return;
01634 }
01635
01636 }
01637
01638 void GUIApp::handleDelayedEvents()
01639 {
01640 uint32 now = SDL_GetTicks();
01641 for (int button = 0; button < MOUSE_LAST; ++button) {
01642 if (!(mouseButton[button].state & (MBS_HANDLED | MBS_DOWN)) &&
01643 now - mouseButton[button].lastDown > DOUBLE_CLICK_TIMEOUT)
01644 {
01645 Gump* gump = getGump(mouseButton[button].downGump);
01646 if (gump)
01647 {
01648 int mx = mouseButton[button].downX;
01649 int my = mouseButton[button].downY;
01650 Gump *parent = gump->GetParent();
01651 if (parent) parent->ScreenSpaceToGump(mx,my);
01652 gump->OnMouseClick(button, mx, my);
01653 }
01654
01655 mouseButton[button].downGump = 0;
01656 mouseButton[button].state |= MBS_HANDLED;
01657 }
01658 }
01659
01660 }
01661
01662 void GUIApp::startDragging(int startx, int starty)
01663 {
01664 setDraggingOffset(0,0);
01665
01666 dragging_objid = desktopGump->TraceObjId(startx, starty);
01667
01668 Gump *gump = getGump(dragging_objid);
01669 Item *item = getItem(dragging_objid);
01670
01671
01672
01673 if (gump) {
01674 Gump *parent = gump->GetParent();
01675 assert(parent);
01676 int px = startx, py = starty;
01677 parent->ScreenSpaceToGump(px, py);
01678 if (gump->IsDraggable() && parent->StartDraggingChild(gump, px, py))
01679 dragging = DRAG_OK;
01680 else {
01681 dragging_objid = 0;
01682 return;
01683 }
01684 } else
01685
01686 if (item) {
01687
01688 gump = desktopGump->FindGump(startx, starty);
01689 int gx = startx, gy = starty;
01690 gump->ScreenSpaceToGump(gx, gy);
01691 bool ok = !isAvatarInStasis() &&
01692 gump->StartDraggingItem(item,gx,gy);
01693 if (!ok) {
01694 dragging = DRAG_INVALID;
01695 } else {
01696 dragging = DRAG_OK;
01697
01698
01699 dragging_item_startgump = gump->getObjId();
01700
01701
01702 dragging_item_lastgump = gump->getObjId();
01703 }
01704 } else {
01705 dragging = DRAG_INVALID;
01706 }
01707
01708 #if 0
01709 Object* obj = ObjectManager::get_instance()->getObject(dragging_objid);
01710 perr << "Dragging object " << dragging_objid << " (class=" << (obj ? obj->GetClassType().class_name : "NULL") << ")" << std::endl;
01711 #endif
01712
01713 pushMouseCursor();
01714 setMouseCursor(MOUSE_NORMAL);
01715
01716
01717 kernel->pause();
01718
01719 mouseButton[BUTTON_LEFT].state |= MBS_HANDLED;
01720
01721 if (dragging == DRAG_INVALID) {
01722 setMouseCursor(MOUSE_CROSS);
01723 }
01724 }
01725
01726 void GUIApp::moveDragging(int mx, int my)
01727 {
01728 Gump* gump = getGump(dragging_objid);
01729 Item *item = getItem(dragging_objid);
01730
01731 setMouseCursor(MOUSE_NORMAL);
01732
01733
01734 if (gump) {
01735 Gump *parent = gump->GetParent();
01736 assert(parent);
01737 int px = mx, py = my;
01738 parent->ScreenSpaceToGump(px, py);
01739 parent->DraggingChild(gump, px, py);
01740 } else
01741
01742 if (item) {
01743 gump = desktopGump->FindGump(mx, my);
01744 assert(gump);
01745
01746 if (gump->getObjId() != dragging_item_lastgump) {
01747
01748 Gump *last = getGump(dragging_item_lastgump);
01749 if (last) last->DraggingItemLeftGump(item);
01750 }
01751 dragging_item_lastgump = gump->getObjId();
01752 int gx = mx, gy = my;
01753 gump->ScreenSpaceToGump(gx, gy);
01754 bool ok = gump->DraggingItem(item,gx,gy);
01755 if (!ok) {
01756 dragging = DRAG_TEMPFAIL;
01757 } else {
01758 dragging = DRAG_OK;
01759 }
01760 } else {
01761 CANT_HAPPEN();
01762 }
01763
01764 if (dragging == DRAG_TEMPFAIL) {
01765 setMouseCursor(MOUSE_CROSS);
01766 }
01767 }
01768
01769
01770 void GUIApp::stopDragging(int mx, int my)
01771 {
01772
01773
01774 Gump *gump = getGump(dragging_objid);
01775 Item *item = getItem(dragging_objid);
01776
01777 if (gump) {
01778 Gump *parent = gump->GetParent();
01779 assert(parent);
01780 parent->StopDraggingChild(gump);
01781 } else
01782
01783 if (item) {
01784 if (dragging != DRAG_INVALID) {
01785 Gump *startgump = getGump(dragging_item_startgump);
01786 assert(startgump);
01787 bool moved = (dragging == DRAG_OK);
01788
01789 if (dragging != DRAG_OK) {
01790 Gump *last = getGump(dragging_item_lastgump);
01791 if (last && last != startgump)
01792 last->DraggingItemLeftGump(item);
01793 }
01794
01795 startgump->StopDraggingItem(item, moved);
01796 }
01797
01798 if (dragging == DRAG_OK) {
01799 item->movedByPlayer();
01800
01801 gump = desktopGump->FindGump(mx, my);
01802 int gx = mx, gy = my;
01803 gump->ScreenSpaceToGump(gx, gy);
01804 gump->DropItem(item,gx,gy);
01805 }
01806 } else {
01807 assert(dragging == DRAG_INVALID);
01808 }
01809
01810 dragging = DRAG_NOT;
01811
01812 kernel->unpause();
01813
01814 popMouseCursor();
01815 }
01816
01817 void GUIApp::writeSaveInfo(ODataSource* ods)
01818 {
01819 time_t t = std::time(0);
01820 struct tm *timeinfo = localtime (&t);
01821 ods->write2(static_cast<uint16>(timeinfo->tm_year + 1900));
01822 ods->write1(static_cast<uint8>(timeinfo->tm_mon+1));
01823 ods->write1(static_cast<uint8>(timeinfo->tm_mday));
01824 ods->write1(static_cast<uint8>(timeinfo->tm_hour));
01825 ods->write1(static_cast<uint8>(timeinfo->tm_min));
01826 ods->write1(static_cast<uint8>(timeinfo->tm_sec));
01827 ods->write4(save_count);
01828 ods->write4(getGameTimeInSeconds());
01829
01830 uint8 c = (has_cheated ? 1 : 0);
01831 ods->write1(c);
01832
01833
01834 game->writeSaveInfo(ods);
01835 }
01836
01837 bool GUIApp::saveGame(std::string filename, std::string desc,
01838 bool ignore_modals)
01839 {
01840
01841 if (!ignore_modals && desktopGump->FindGump<ModalGump>()) {
01842 pout << "Can't save: modal gump open." << std::endl;
01843 return false;
01844 }
01845
01846
01847
01848 MainActor* av = getMainActor();
01849 if (!av || (av->getActorFlags() & Actor::ACT_DEAD)) {
01850 pout << "Can't save: game over." << std::endl;
01851 return false;
01852 }
01853
01854 pout << "Saving..." << std::endl;
01855
01856 pout << "Savegame file: " << filename << std::endl;
01857 pout << "Description: " << desc << std::endl;
01858
01859
01860 Gump * gump = getGump(mouseOverGump);
01861 if (gump) gump->OnMouseLeft();
01862
01863 ODataSource* ods = filesystem->WriteFile(filename);
01864 if (!ods) return false;
01865
01866 save_count++;
01867
01868 SavegameWriter* sgw = new SavegameWriter(ods);
01869 sgw->writeVersion(Pentagram::savegame_version);
01870 sgw->writeDescription(desc);
01871
01872
01873 OAutoBufferDataSource buf(2048);
01874
01875 gameinfo->save(&buf);
01876 sgw->writeFile("GAME", &buf);
01877 buf.clear();
01878
01879 writeSaveInfo(&buf);
01880 sgw->writeFile("INFO", &buf);
01881 buf.clear();
01882
01883 kernel->save(&buf);
01884 sgw->writeFile("KERNEL", &buf);
01885 buf.clear();
01886
01887 objectmanager->save(&buf);
01888 sgw->writeFile("OBJECTS", &buf);
01889 buf.clear();
01890
01891 world->save(&buf);
01892 sgw->writeFile("WORLD", &buf);
01893 buf.clear();
01894
01895 world->saveMaps(&buf);
01896 sgw->writeFile("MAPS", &buf);
01897 buf.clear();
01898
01899 world->getCurrentMap()->save(&buf);
01900 sgw->writeFile("CURRENTMAP", &buf);
01901 buf.clear();
01902
01903 ucmachine->saveStrings(&buf);
01904 sgw->writeFile("UCSTRINGS", &buf);
01905 buf.clear();
01906
01907 ucmachine->saveGlobals(&buf);
01908 sgw->writeFile("UCGLOBALS", &buf);
01909 buf.clear();
01910
01911 ucmachine->saveLists(&buf);
01912 sgw->writeFile("UCLISTS", &buf);
01913 buf.clear();
01914
01915 save(&buf);
01916 sgw->writeFile("APP", &buf);
01917 buf.clear();
01918
01919 sgw->finish();
01920
01921 delete sgw;
01922
01923
01924 if (gump) gump->OnMouseOver();
01925
01926 pout << "Done" << std::endl;
01927
01928 return true;
01929 }
01930
01931 void GUIApp::resetEngine()
01932 {
01933 con.Print(MM_INFO, "-- Resetting Engine --\n");
01934
01935
01936 if (audiomixer) audiomixer->reset();
01937
01938
01939 world->reset();
01940 ucmachine->reset();
01941
01942
01943 objectmanager->reset();
01944 kernel->reset();
01945 palettemanager->resetTransforms();
01946
01947
01948 desktopGump = 0;
01949 consoleGump = 0;
01950 gameMapGump = 0;
01951 scalerGump = 0;
01952 inverterGump = 0;
01953
01954 textmodes.clear();
01955
01956
01957 while (!cursors.empty()) cursors.pop();
01958 pushMouseCursor();
01959
01960 kernel->addProcess(new JoystickCursorProcess(JOY1, 0, 1));
01961
01962 timeOffset = -(sint32)Kernel::get_instance()->getFrameNum();
01963 inversion = 0;
01964 save_count = 0;
01965 has_cheated = false;
01966
01967 con.Print(MM_INFO, "-- Engine Reset --\n");
01968 }
01969
01970 void GUIApp::setupCoreGumps()
01971 {
01972 con.Print(MM_INFO, "Setting up core game gumps...\n");
01973
01974 Pentagram::Rect dims;
01975 screen->GetSurfaceDims(dims);
01976
01977 con.Print(MM_INFO, "Creating Desktop...\n");
01978 desktopGump = new DesktopGump(0,0, dims.w, dims.h);
01979 desktopGump->InitGump(0);
01980 desktopGump->MakeFocus();
01981
01982 con.Print(MM_INFO, "Creating ScalerGump...\n");
01983 scalerGump = new ScalerGump(0, 0, dims.w, dims.h);
01984 scalerGump->InitGump(0);
01985
01986 Pentagram::Rect scaled_dims;
01987 scalerGump->GetDims(scaled_dims);
01988
01989 con.Print(MM_INFO, "Creating Graphics Console...\n");
01990 consoleGump = new ConsoleGump(0, 0, dims.w, dims.h);
01991 consoleGump->InitGump(0);
01992 consoleGump->HideConsole();
01993
01994 con.Print(MM_INFO, "Creating Inverter...\n");
01995 inverterGump = new InverterGump(0, 0, scaled_dims.w, scaled_dims.h);
01996 inverterGump->InitGump(0);
01997
01998 con.Print(MM_INFO, "Creating GameMapGump...\n");
01999 gameMapGump = new GameMapGump(0, 0, scaled_dims.w, scaled_dims.h);
02000 gameMapGump->InitGump(0);
02001
02002
02003
02004 assert(desktopGump->getObjId() == 256);
02005 assert(scalerGump->getObjId() == 257);
02006 assert(consoleGump->getObjId() == 258);
02007 assert(inverterGump->getObjId() == 259);
02008 assert(gameMapGump->getObjId() == 260);
02009
02010
02011 for (uint16 i = 261; i < 384; ++i)
02012 objectmanager->reserveObjId(i);
02013 }
02014
02015 bool GUIApp::newGame()
02016 {
02017 con.Print(MM_INFO, "Starting New Game...\n");
02018
02019 resetEngine();
02020
02021 setupCoreGumps();
02022
02023 game->startGame();
02024
02025 con.Print(MM_INFO, "Create Camera...\n");
02026 CameraProcess::SetCameraProcess(new CameraProcess(1));
02027
02028 con.Print(MM_INFO, "Create persistent Processes...\n");
02029 avatarMoverProcess = new AvatarMoverProcess();
02030 kernel->addProcess(avatarMoverProcess);
02031
02032 kernel->addProcess(new HealProcess());
02033
02034 kernel->addProcess(new SchedulerProcess());
02035
02036 if (audiomixer) audiomixer->createProcesses();
02037
02038
02039
02040
02041
02042
02043
02044
02045
02046
02047 game->startInitialUsecode();
02048
02049 return true;
02050 }
02051
02052 bool GUIApp::loadGame(std::string filename)
02053 {
02054 con.Print(MM_INFO, "Loading...\n");
02055
02056 IDataSource* ids = filesystem->ReadFile(filename);
02057 if (!ids) {
02058 perr << "Can't find file: " << filename << std::endl;
02059 return false;
02060 }
02061
02062 Savegame* sg = new Savegame(ids);
02063 uint32 version = sg->getVersion();
02064 if (version == 0) {
02065 perr << "Invalid or corrupt savegame." << std::endl;
02066 return false;
02067 }
02068
02069 if (version == 1 || version > Pentagram::savegame_version) {
02070 perr << "Unsupported savegame version (" << version << ")"
02071 << std::endl;
02072 return false;
02073 }
02074 IDataSource* ds;
02075 GameInfo saveinfo;
02076 ds = sg->getDataSource("GAME");
02077 bool ok = saveinfo.load(ds, version);
02078
02079 if (!ok) {
02080 perr << "Invalid or corrupt savegame: missing GameInfo" << std::endl;
02081 return false;
02082 }
02083
02084 if (!gameinfo->match(saveinfo)) {
02085 perr << "Game mismatch:" << std::endl;
02086 perr << "Running game: " << gameinfo->getPrintDetails() << std::endl;
02087 perr << "Savegame : " << saveinfo.getPrintDetails() << std::endl;
02088
02089 #ifdef DEBUG
02090 bool ignore;
02091 settingman->setDefault("ignore_savegame_mismatch", false);
02092 settingman->get("ignore_savegame_mismatch", ignore);
02093
02094 if (!ignore)
02095 return false;
02096 #else
02097 return false;
02098 #endif
02099 }
02100
02101 resetEngine();
02102
02103 setupCoreGumps();
02104
02105
02106 bool totalok = true;
02107
02108
02109
02110
02111 ds = sg->getDataSource("UCSTRINGS");
02112 ok = ucmachine->loadStrings(ds, version);
02113 totalok &= ok;
02114 perr << "UCSTRINGS: " << (ok ? "ok" : "failed") << std::endl;
02115 delete ds;
02116
02117 ds = sg->getDataSource("UCGLOBALS");
02118 ok = ucmachine->loadGlobals(ds, version);
02119 totalok &= ok;
02120 perr << "UCGLOBALS: " << (ok ? "ok" : "failed") << std::endl;
02121 delete ds;
02122
02123 ds = sg->getDataSource("UCLISTS");
02124 ok = ucmachine->loadLists(ds, version);
02125 totalok &= ok;
02126 perr << "UCLISTS: " << (ok ? "ok" : "failed")<< std::endl;
02127 delete ds;
02128
02129
02130
02131 ds = sg->getDataSource("KERNEL");
02132 ok = kernel->load(ds, version);
02133 totalok &= ok;
02134 perr << "KERNEL: " << (ok ? "ok" : "failed") << std::endl;
02135 delete ds;
02136
02137 ds = sg->getDataSource("APP");
02138 ok = load(ds, version);
02139 totalok &= ok;
02140 perr << "APP: " << (ok ? "ok" : "failed") << std::endl;
02141 delete ds;
02142
02143
02144 ds = sg->getDataSource("WORLD");
02145 ok = world->load(ds, version);
02146 totalok &= ok;
02147 perr << "WORLD: " << (ok ? "ok" : "failed") << std::endl;
02148 delete ds;
02149
02150 ds = sg->getDataSource("CURRENTMAP");
02151 ok = world->getCurrentMap()->load(ds, version);
02152 totalok &= ok;
02153 perr << "CURRENTMAP: " << (ok ? "ok" : "failed") << std::endl;
02154 delete ds;
02155
02156 ds = sg->getDataSource("OBJECTS");
02157 ok = objectmanager->load(ds, version);
02158 totalok &= ok;
02159 perr << "OBJECTS: " << (ok ? "ok" : "failed") << std::endl;
02160 delete ds;
02161
02162 ds = sg->getDataSource("MAPS");
02163 ok = world->loadMaps(ds, version);
02164 totalok &= ok;
02165 perr << "MAPS: " << (ok ? "ok" : "failed") << std::endl;
02166 delete ds;
02167
02168 if (!ok) {
02169 perr << "Loading failed!" << std::endl;
02170 exit(1);
02171 }
02172
02173 pout << "Done" << std::endl;
02174
02175 delete sg;
02176 return false;
02177 }
02178
02179 Gump* GUIApp::getGump(uint16 gumpid)
02180 {
02181 return p_dynamic_cast<Gump*>(ObjectManager::get_instance()->
02182 getObject(gumpid));
02183 }
02184
02185 void GUIApp::addGump(Gump* gump)
02186 {
02187
02188
02189
02190 assert(desktopGump);
02191
02192 if (gump->IsOfType<ShapeViewerGump>() || gump->IsOfType<MiniMapGump>() ||
02193 gump->IsOfType<ConsoleGump>() || gump->IsOfType<ScalerGump>() ||
02194 gump->IsOfType<PentagramMenuGump>()
02195
02196
02197 )
02198 {
02199
02200 desktopGump->AddChild(gump);
02201 }
02202 else if (gump->IsOfType<GameMapGump>())
02203 {
02204
02205 inverterGump->AddChild(gump);
02206 }
02207 else if (gump->IsOfType<InverterGump>())
02208 {
02209
02210 scalerGump->AddChild(gump);
02211 }
02212 else if (gump->IsOfType<DesktopGump>())
02213 {
02214 }
02215 else
02216 {
02217
02218 scalerGump->AddChild(gump);
02219 }
02220 }
02221
02222 uint32 GUIApp::getGameTimeInSeconds()
02223 {
02224
02225 return (Kernel::get_instance()->getFrameNum()+timeOffset)/30;
02226 }
02227
02228
02229 void GUIApp::save(ODataSource* ods)
02230 {
02231 uint8 s = (avatarInStasis ? 1 : 0);
02232 ods->write1(s);
02233
02234 sint32 absoluteTime = Kernel::get_instance()->getFrameNum()+timeOffset;
02235 ods->write4(static_cast<uint32>(absoluteTime));
02236 ods->write2(avatarMoverProcess->getPid());
02237
02238 Pentagram::Palette *pal = PaletteManager::get_instance()->getPalette(PaletteManager::Pal_Game);
02239 for (int i = 0; i < 12; i++) ods->write2(pal->matrix[i]);
02240 ods->write2(pal->transform);
02241
02242 ods->write2(static_cast<uint16>(inversion));
02243
02244 ods->write4(save_count);
02245
02246 uint8 c = (has_cheated ? 1 : 0);
02247 ods->write1(c);
02248 }
02249
02250 bool GUIApp::load(IDataSource* ids, uint32 version)
02251 {
02252 avatarInStasis = (ids->read1() != 0);
02253
02254
02255 mouseOverGump = 0;
02256
02257 sint32 absoluteTime = static_cast<sint32>(ids->read4());
02258 timeOffset = absoluteTime - Kernel::get_instance()->getFrameNum();
02259
02260 uint16 amppid = ids->read2();
02261 avatarMoverProcess = p_dynamic_cast<AvatarMoverProcess*>(Kernel::get_instance()->getProcess(amppid));
02262
02263 sint16 matrix[12];
02264 for (int i = 0; i < 12; i++)
02265 matrix[i] = ids->read2();
02266
02267 PaletteManager::get_instance()->transformPalette(PaletteManager::Pal_Game, matrix);
02268 Pentagram::Palette *pal = PaletteManager::get_instance()->getPalette(PaletteManager::Pal_Game);
02269 pal->transform = static_cast<Pentagram::PalTransforms>(ids->read2());
02270
02271 inversion = ids->read2();
02272
02273 save_count = ids->read4();
02274
02275 has_cheated = (ids->read1() != 0);
02276
02277 return true;
02278 }
02279
02280
02281
02282
02283
02284 void GUIApp::ConCmd_saveGame(const Console::ArgvType &argv)
02285 {
02286 if (argv.size()==1)
02287 {
02288 pout << "Usage: GUIApp::saveGame <filename>" << std::endl;
02289 return;
02290 }
02291
02292 std::string filename = "@save/";
02293 filename += argv[1].c_str();
02294 GUIApp::get_instance()->saveGame(filename, argv[1]);
02295 }
02296
02297 void GUIApp::ConCmd_loadGame(const Console::ArgvType &argv)
02298 {
02299 if (argv.size()==1)
02300 {
02301 pout << "Usage: GUIApp::loadGame <filename>" << std::endl;
02302 return;
02303 }
02304
02305 std::string filename = "@save/";
02306 filename += argv[1].c_str();
02307 GUIApp::get_instance()->loadGame(filename);
02308 }
02309
02310 void GUIApp::ConCmd_newGame(const Console::ArgvType &argv)
02311 {
02312 GUIApp::get_instance()->newGame();
02313 }
02314
02315
02316 void GUIApp::ConCmd_quit(const Console::ArgvType &argv)
02317 {
02318 GUIApp::get_instance()->isRunning = false;
02319 }
02320
02321 void GUIApp::ConCmd_drawRenderStats(const Console::ArgvType &argv)
02322 {
02323 if (argv.size() == 1)
02324 {
02325 pout << "GUIApp::drawRenderStats = " << GUIApp::get_instance()->drawRenderStats << std::endl;
02326 }
02327 else
02328 {
02329 GUIApp::get_instance()->drawRenderStats = std::strtol(argv[1].c_str(), 0, 0) != 0;
02330 }
02331 }
02332
02333 void GUIApp::ConCmd_engineStats(const Console::ArgvType &argv)
02334 {
02335 Kernel::get_instance()->kernelStats();
02336 ObjectManager::get_instance()->objectStats();
02337 UCMachine::get_instance()->usecodeStats();
02338 World::get_instance()->worldStats();
02339 }
02340
02341 void GUIApp::ConCmd_changeGame(const Console::ArgvType &argv)
02342 {
02343 if (argv.size() == 1)
02344 {
02345 pout << "Current game is: " << GUIApp::get_instance()->gameinfo->name << std::endl;
02346 }
02347 else
02348 {
02349 GUIApp::get_instance()->changeGame(argv[1]);
02350 }
02351 }
02352
02353 void GUIApp::ConCmd_listGames(const Console::ArgvType &argv)
02354 {
02355 GUIApp *app = GUIApp::get_instance();
02356 std::vector<Pentagram::istring> games;
02357 games = app->settingman->listGames();
02358 std::vector<Pentagram::istring>::iterator iter;
02359 for (iter = games.begin(); iter != games.end(); ++iter) {
02360 Pentagram::istring game = *iter;
02361 GameInfo* info = app->getGameInfo(game);
02362 con.Printf(MM_INFO, "%s: ", game.c_str());
02363 if (info) {
02364 std::string details = info->getPrintDetails();
02365 con.Print(MM_INFO, details.c_str());
02366 } else {
02367 con.Print(MM_INFO, "(unknown)");
02368 }
02369 con.Print(MM_INFO, "\n");
02370 }
02371 }
02372
02373 void GUIApp::ConCmd_setVideoMode(const Console::ArgvType &argv)
02374 {
02375 int fullscreen = -1;
02376
02377
02378
02379
02380
02381 if (argv.size() != 3)
02382 {
02383
02384 pout << "Usage: GUIApp::setVidMode width height" << std::endl;
02385 return;
02386 }
02387
02388 GUIApp::get_instance()->changeVideoMode(strtol(argv[1].c_str(), 0, 0), strtol(argv[2].c_str(), 0, 0), fullscreen);
02389 }
02390
02391 void GUIApp::ConCmd_toggleFullscreen(const Console::ArgvType &argv)
02392 {
02393 GUIApp::get_instance()->changeVideoMode(-1, -1, -2);
02394 }
02395
02396 void GUIApp::ConCmd_toggleAvatarInStasis(const Console::ArgvType &argv)
02397 {
02398 GUIApp * g = GUIApp::get_instance();
02399 g->toggleAvatarInStasis();
02400 pout << "avatarInStasis = " << g->isAvatarInStasis() << std::endl;
02401 }
02402
02403 void GUIApp::ConCmd_togglePaintEditorItems(const Console::ArgvType &argv)
02404 {
02405 GUIApp * g = GUIApp::get_instance();
02406 g->togglePaintEditorItems();
02407 pout << "paintEditorItems = " << g->isPaintEditorItems() << std::endl;
02408 }
02409
02410 void GUIApp::ConCmd_toggleShowTouchingItems(const Console::ArgvType &argv)
02411 {
02412 GUIApp * g = GUIApp::get_instance();
02413 g->toggleShowTouchingItems();
02414 pout << "ShowTouchingItems = " << g->isShowTouchingItems() << std::endl;
02415 }
02416
02417 void GUIApp::ConCmd_closeItemGumps(const Console::ArgvType &argv)
02418 {
02419 GUIApp * g = GUIApp::get_instance();
02420 g->getDesktopGump()->CloseItemDependents();
02421 }
02422
02423
02424
02425
02426
02427 uint32 GUIApp::I_makeAvatarACheater(const uint8* ,
02428 unsigned int )
02429 {
02430 GUIApp::get_instance()->makeCheater();
02431 return 0;
02432 }
02433
02434 uint32 GUIApp::I_getCurrentTimerTick(const uint8* ,
02435 unsigned int )
02436 {
02437
02438 return Kernel::get_instance()->getFrameNum()*2;
02439 }
02440
02441 uint32 GUIApp::I_setAvatarInStasis(const uint8* args, unsigned int )
02442 {
02443 ARG_SINT16(stasis);
02444 get_instance()->setAvatarInStasis(stasis!=0);
02445 return 0;
02446 }
02447
02448 uint32 GUIApp::I_getAvatarInStasis(const uint8* , unsigned int )
02449 {
02450 if (get_instance()->avatarInStasis)
02451 return 1;
02452 else
02453 return 0;
02454 }
02455
02456 uint32 GUIApp::I_getTimeInGameHours(const uint8* ,
02457 unsigned int )
02458 {
02459
02460 return get_instance()->getGameTimeInSeconds() / 900;
02461 }
02462
02463 uint32 GUIApp::I_getTimeInMinutes(const uint8* ,
02464 unsigned int )
02465 {
02466
02467 return get_instance()->getGameTimeInSeconds() / 60;
02468 }
02469
02470 uint32 GUIApp::I_getTimeInSeconds(const uint8* ,
02471 unsigned int )
02472 {
02473 return get_instance()->getGameTimeInSeconds();
02474 }
02475
02476 uint32 GUIApp::I_setTimeInGameHours(const uint8* args,
02477 unsigned int )
02478 {
02479 ARG_UINT16(newhour);
02480
02481
02482 sint32 absolute = newhour*27000;
02483 get_instance()->timeOffset = absolute-Kernel::get_instance()->getFrameNum();
02484
02485 return 0;
02486 }
02487
02488 uint32 GUIApp::I_closeItemGumps(const uint8* args, unsigned int )
02489 {
02490 GUIApp* g = GUIApp::get_instance();
02491 g->getDesktopGump()->CloseItemDependents();
02492
02493 return 0;
02494 }