/* ScummVM - Graphic Adventure Engine * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT * file distributed with this source distribution. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #include "hypno/grammar.h" #include "hypno/hypno.h" #include "common/events.h" #include "engines/metaengine.h" #include "engines/savestate.h" namespace Hypno { static const chapterEntry rawChapterTable[] = { {19, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 0, kHypnoNoColor}, {11, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 0, kHypnoNoColor}, {12, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 0, kHypnoNoColor}, {13, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 0, kHypnoNoColor}, {14, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 0, kHypnoNoColor}, {15, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 0, kHypnoNoColor}, {16, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 0, kHypnoNoColor}, {17, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 0, kHypnoNoColor}, {18, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 0, kHypnoNoColor}, {21, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 0, kHypnoNoColor}, {22, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 0, kHypnoNoColor}, {31, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 0, kHypnoNoColor}, {32, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 0, kHypnoNoColor}, {33, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 0, kHypnoNoColor}, {34, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 0, kHypnoNoColor}, {3591, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 0, kHypnoNoColor}, {3592, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 0, kHypnoNoColor}, {36, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 0, kHypnoNoColor}, {41, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 0, kHypnoNoColor}, {42, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 0, kHypnoNoColor}, {51, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 0, kHypnoNoColor}, {52, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 0, kHypnoNoColor}, {53, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 0, kHypnoNoColor}, {531, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 0, kHypnoNoColor}, {54, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 0, kHypnoNoColor}, {55, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 0, kHypnoNoColor}, {56, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 0, kHypnoNoColor}, {57, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 0, kHypnoNoColor}, {58, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 0, kHypnoNoColor}, {59, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 0, kHypnoNoColor}, {0, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 0, kHypnoNoColor} }; BoyzEngine::BoyzEngine(OSystem *syst, const ADGameDescription *gd) : HypnoEngine(syst, gd) { _screenW = 320; _screenH = 200; _lives = uint32(-1); // This counts the number of lives used _currentWeapon = 0; _currentActor = 0; _currentMode = NonInteractive; _crosshairsPalette = nullptr; _lastLevel = 0; _previousHealth = 0; _selectedCorrectBox = 0; _flashbackMode = false; const chapterEntry *entry = rawChapterTable; while (entry->id) { _ids.push_back(entry->id); entry++; } for (int i = 0; i < 6; i++) { _weaponMaxAmmo[i] = 0; } } BoyzEngine::~BoyzEngine() { free(_crosshairsPalette); } static const char *selectBoyz = "\ MENU preload\\slct_boy.smk\n\ HOTS /BBOX= 19 3 66 199\n\ SOND tollop1.raw 22K\n\ HOTS /BBOX= 69 3 116 199\n\ SOND tollam.raw 22K\n\ HOTS /BBOX= 119 3 166 199\n\ SOND tolvas1.raw 22K\n\ HOTS /BBOX= 169 3 216 199\n\ SOND tolbut1.raw 22K\n\ HOTS /BBOX= 219 3 266 199\n\ SOND tolbro1.raw 22K\n\ HOTS /BBOX= 269 3 316 170\n\ SOND tolmon1.raw 22K\n\ HOTS /BBOX= 262 172 312 194\n\ SOND pstlfire.raw\n\ END\n"; static const char *selectC3 = "\ MENU preload\\slct_c3.smk\n\ HOTS /BBOX= 143 78 286 138\n\ SOND tollopz2.raw 22K\n\ HOTS /BBOX= 159 141 319 197\n\ SOND tolbuts3.raw 22K\n\ HOTS /BBOX= 26 14 126 89\n\ SOND tolvasq1.raw 22K\n\ HOTS /BBOX= 24 114 126 190\n\ SOND tolmons1.raw 22K\n\ HOTS /BBOX= 190 4 292 76\n\ SOND tollamb1.raw 22K\n\ END\n"; static const char *selectHo = "\ MENU preload\\slct_ho.smk\n\ HOTS /BBOX= 19 18 85 199\n\ SOND tien1bb.raw 22K\n\ HOTS /BBOX= 87 36 143 199\n\ SOND lan1.raw 22K\n\ HOTS /BBOX= 144 36 193 199\n\ SOND mai1.raw 22K\n\ HOTS /BBOX= 195 55 249 199\n\ SOND hoa1b.raw 22K\n\ HOTS /BBOX= 250 32 301 199\n\ SOND van2.raw 22K\n\ END\n"; static const char *selectC5 = "\ MENU preload\\slct_c5.smk\n\ HOTS /BBOX= 212 108 306 192\n\ SOND tolvexp1.raw 22K\n\ HOTS /BBOX= 212 5 302 82\n\ SOND tollcom2.raw 22K\n\ HOTS /BBOX= 110 70 198 148\n\ SOND tolbwhr1.raw 22K\n\ HOTS /BBOX= 4 14 91 92\n\ SOND tolbwhr1.raw 22K\n\ HOTS /BBOX= 8 105 96 194\n\ SOND tolbwhr1.raw 22K\n\ END\n"; static const char *fterr = "\ MENU preload\\fterr%d.smk\n\ HOTS /BBOX= 13 151 68 164\n\ HOTS /BBOX= 19 48 146 59\n\ HOTS /BBOX= 19 64 146 75\n\ HOTS /BBOX= 19 80 146 91\n\ HOTS /BBOX= 19 96 146 107\n\ HOTS /BBOX= 19 112 146 123\n\ HOTS /BBOX= 170 48 305 59\n\ HOTS /BBOX= 170 64 305 75\n\ HOTS /BBOX= 170 80 305 91\n\ HOTS /BBOX= 170 96 305 107\n\ HOTS /BBOX= 170 112 305 123\n\ HOTS /BBOX= 170 128 305 139\n\ HOTS /BBOX= 170 144 305 155\n\ HOTS /BBOX= 170 160 305 171\n\ HOTS /BBOX= 170 176 305 187\n\ HOTS /BBOX= 170 48 305 59\n\ HOTS /BBOX= 170 64 305 75\n\ HOTS /BBOX= 170 48 305 59\n\ HOTS /BBOX= 170 64 305 75\n\ HOTS /BBOX= 170 80 305 91\n\ HOTS /BBOX= 170 96 305 107\n\ HOTS /BBOX= 170 112 305 123\n\ HOTS /BBOX= 170 128 305 139\n\ HOTS /BBOX= 170 48 305 59\n\ HOTS /BBOX= 170 64 305 75\n\ HOTS /BBOX= 170 48 305 59\n\ HOTS /BBOX= 170 64 305 75\n\ HOTS /BBOX= 170 80 305 91\n\ HOTS /BBOX= 170 96 305 107\n\ HOTS /BBOX= 170 112 305 123\n\ HOTS /BBOX= 170 128 305 139\n\ HOTS /BBOX= 170 144 305 155\n\ HOTS /BBOX= 170 160 305 171\n\ END\n"; void BoyzEngine::loadAssets() { LibFile *missions = loadLib("", "preload/missions.lib", true); Common::ArchiveMemberList files; if (missions->listMembers(files) == 0) error("Failed to load any files from missions.lib"); Transition *logos = new Transition(""); logos->intros.push_back("intro/dclogos.smk"); logos->intros.push_back("intro/mplogos.smk"); logos->intros.push_back("intro/hyplogos.smk"); logos->intros.push_back("intro/sblogos.smk"); _levels[""] = logos; Code *main_menu = new Code(""); _levels[""] = main_menu; _levels[""]->levelIfWin = ""; Code *difficulty_menu = new Code(""); _levels[""] = difficulty_menu; _levels[""]->levelIfWin = ""; Code *retry = new Code(""); _levels[""] = retry; Transition *territory_1 = new Transition("c19.mi_"); territory_1->intros.push_back("warnings/w17s.smk"); territory_1->intros.push_back("c1/c1t01.smk"); _levels[""] = territory_1; Transition *warning_1 = new Transition("c14.mi_"); warning_1->intros.push_back("warnings/w12s.smk"); _levels[""] = warning_1; loadArcadeLevel("c19.mi_", "c11.mi_", "", ""); loadArcadeLevel("c11.mi_", "c12.mi_", "", ""); loadArcadeLevel("c12.mi_", "", "", ""); loadArcadeLevel("c14.mi_", "c13.mi_", "", ""); loadArcadeLevel("c13.mi_", "c15.mi_", "", ""); loadArcadeLevel("c15.mi_", "c16.mi_", "", ""); loadArcadeLevel("c16.mi_", "c17.mi_", "", ""); loadArcadeLevel("c17.mi_", "c18.mi_", "", ""); loadArcadeLevel("c18.mi_", "", "", ""); Transition *territory_2 = new Transition("c21.mi_"); territory_2->intros.push_back("warnings/w13s.smk"); territory_2->intros.push_back("c2/c2t01.smk"); _levels[""] = territory_2; loadArcadeLevel("c21.mi_", "c22.mi_", "", ""); loadArcadeLevel("c22.mi_", "", "", ""); Transition *territory_3 = new Transition(""); territory_3->intros.push_back("warnings/w14s.smk"); territory_3->intros.push_back("c3/c3t01.smk"); _levels[""] = territory_3; loadArcadeLevel("c31.mi_", "", "", ""); loadArcadeLevel("c32.mi_", "", "", ""); loadArcadeLevel("c33.mi_", "", "", ""); // This is manually implemented, if objectives are completed ArcadeShooting *ar = (ArcadeShooting *) _levels["c33.mi_"]; ar->nextLevelVideo.clear(); loadArcadeLevel("c34.mi_", "", "", ""); loadArcadeLevel("c35.mi_", "", "", ""); ar = (ArcadeShooting *) _levels["c35.mi_"]; ar->backgroundVideo = ""; // This will be manually populated loadArcadeLevel("c351.mi_", "", "", ""); loadArcadeLevel("c352.mi_", "", "", ""); ar = (ArcadeShooting *) _levels["c352.mi_"]; // These objectives, as every others, are unused // We should remove them to avoid always failing the level ar->objKillsRequired[0] = 0; ar->objMissesAllowed[0] = 0; loadArcadeLevel("c353.mi_", "", "", ""); ar = (ArcadeShooting *) _levels["c353.mi_"]; ar->id = 353; // This corrects a mistake in the game scripts loadArcadeLevel("c354.mi_", "", "", ""); loadArcadeLevel("c355.mi_", "", "", ""); loadArcadeLevel("c36.mi_", "", "", ""); Transition *territory_4 = new Transition("c41.mi_"); territory_4->intros.push_back("warnings/w15s.smk"); territory_4->intros.push_back("c4/c4t01.smk"); _levels[""] = territory_4; loadArcadeLevel("c41.mi_", "c42.mi_", "", ""); loadArcadeLevel("c42.mi_", "", "", ""); ar = (ArcadeShooting *) _levels["c42.mi_"]; // We remove the last element, which plays c4/c4bro8s.smk // This transition is too close to the end of the level // and will likely not be executed ar->transitions.pop_back(); Transition *territory_5 = new Transition(""); territory_5->intros.push_back("warnings/w16s.smk"); territory_5->intros.push_back("c5/c5t01.smk"); territory_5->intros.push_back("c5/c5intras.smk"); _levels[""] = territory_5; loadArcadeLevel("c51.mi_", "", "", ""); loadArcadeLevel("c52.mi_", "", "", ""); loadArcadeLevel("c53.mi_", "", "", ""); loadArcadeLevel("c54.mi_", "c55.mi_", "", ""); loadArcadeLevel("c55.mi_", "c56.mi_", "", ""); loadArcadeLevel("c56.mi_", "c57.mi_", "", ""); loadArcadeLevel("c57.mi_", "c58.mi_", "", ""); loadArcadeLevel("c58.mi_", "c59.mi_", "", ""); loadArcadeLevel("c59.mi_", "", "", ""); Code *credits = new Code(""); _levels[""] = credits; Global *gl; ChangeLevel *cl; Cutscene *cs; Highlight *hl; loadSceneLevel(selectBoyz, "", "", ""); Scene *sc = (Scene *) _levels[""]; sc->intros.push_back("intro/c0o01s.smk"); sc->resolution = "320x200"; hl = new Highlight("GS_SWITCH1"); sc->hots[1].actions.push_back(hl); gl = new Global("GS_SWITCH1", "TURNON"); sc->hots[1].actions.push_back(gl); cs = new Cutscene("intro/c0i01s.smk"); sc->hots[1].actions.push_back(cs); hl = new Highlight("GS_SWITCH2"); sc->hots[2].actions.push_back(hl); gl = new Global("GS_SWITCH2", "TURNON"); sc->hots[2].actions.push_back(gl); cs = new Cutscene("intro/c0i02s.smk"); sc->hots[2].actions.push_back(cs); hl = new Highlight("GS_SWITCH3"); sc->hots[3].actions.push_back(hl); gl = new Global("GS_SWITCH3", "TURNON"); sc->hots[3].actions.push_back(gl); cs = new Cutscene("intro/c0i03s.smk"); sc->hots[3].actions.push_back(cs); hl = new Highlight("GS_SWITCH4"); sc->hots[4].actions.push_back(hl); gl = new Global("GS_SWITCH4", "TURNON"); sc->hots[4].actions.push_back(gl); cs = new Cutscene("intro/c0i04s.smk"); sc->hots[4].actions.push_back(cs); hl = new Highlight("GS_SWITCH5"); sc->hots[5].actions.push_back(hl); gl = new Global("GS_SWITCH5", "TURNON"); sc->hots[5].actions.push_back(gl); cs = new Cutscene("intro/c0i05s.smk"); sc->hots[5].actions.push_back(cs); hl = new Highlight("GS_SWITCH6"); sc->hots[6].actions.push_back(hl); gl = new Global("GS_SWITCH6", "TURNON"); sc->hots[6].actions.push_back(gl); cs = new Cutscene("intro/c0i06s.smk"); sc->hots[6].actions.push_back(cs); cl = new ChangeLevel(""); sc->hots[7].actions.push_back(cl); loadSceneLevel(selectC3, "", "", ""); sc = (Scene *) _levels[""]; sc->resolution = "320x200"; hl = new Highlight("GS_SEQ_31"); sc->hots[1].actions.push_back(hl); gl = new Global("GS_SEQ_31", "NCHECK"); sc->hots[1].actions.push_back(gl); cl = new ChangeLevel("c31.mi_"); sc->hots[1].actions.push_back(cl); hl = new Highlight("GS_SEQ_32"); sc->hots[2].actions.push_back(hl); gl = new Global("GS_SEQ_32", "NCHECK"); sc->hots[2].actions.push_back(gl); cl = new ChangeLevel("c32.mi_"); sc->hots[2].actions.push_back(cl); hl = new Highlight("GS_SEQ_33"); sc->hots[3].actions.push_back(hl); gl = new Global("GS_SEQ_33", "NCHECK"); sc->hots[3].actions.push_back(gl); cl = new ChangeLevel("c33.mi_"); sc->hots[3].actions.push_back(cl); hl = new Highlight("GS_SEQ_34"); sc->hots[4].actions.push_back(hl); gl = new Global("GS_SEQ_34", "NCHECK"); sc->hots[4].actions.push_back(gl); cl = new ChangeLevel("c34.mi_"); sc->hots[4].actions.push_back(cl); hl = new Highlight("GS_WONSHELLGAME"); sc->hots[5].actions.push_back(hl); gl = new Global("GS_WONSHELLGAME", "NCHECK"); gl = new Global("GS_HOTELDONE", "NCHECK"); sc->hots[5].actions.push_back(gl); cl = new ChangeLevel("c35.mi_"); sc->hots[5].actions.push_back(cl); loadSceneLevel(selectHo, "", "", ""); sc = (Scene *) _levels[""]; sc->resolution = "320x200"; hl = new Highlight("GS_SEQ_351"); sc->hots[1].actions.push_back(hl); gl = new Global("GS_SEQ_351", "NCHECK"); sc->hots[1].actions.push_back(gl); cl = new ChangeLevel("c351.mi_"); sc->hots[1].actions.push_back(cl); hl = new Highlight("GS_SEQ_352"); sc->hots[2].actions.push_back(hl); gl = new Global("GS_SEQ_352", "NCHECK"); sc->hots[2].actions.push_back(gl); cl = new ChangeLevel("c352.mi_"); sc->hots[2].actions.push_back(cl); hl = new Highlight("GS_SEQ_353"); sc->hots[3].actions.push_back(hl); gl = new Global("GS_SEQ_353", "NCHECK"); sc->hots[3].actions.push_back(gl); cl = new ChangeLevel("c353.mi_"); sc->hots[3].actions.push_back(cl); hl = new Highlight("GS_SEQ_354"); sc->hots[4].actions.push_back(hl); gl = new Global("GS_SEQ_354", "NCHECK"); sc->hots[4].actions.push_back(gl); cl = new ChangeLevel("c354.mi_"); sc->hots[4].actions.push_back(cl); hl = new Highlight("GS_SEQ_355"); sc->hots[5].actions.push_back(hl); gl = new Global("GS_SEQ_355", "NCHECK"); sc->hots[5].actions.push_back(gl); cl = new ChangeLevel("c355.mi_"); sc->hots[5].actions.push_back(cl); Code *check_c3 = new Code(""); _levels[""] = check_c3; Code *check_ho = new Code(""); _levels[""] = check_ho; Code *check_c5 = new Code(""); _levels[""] = check_c5; loadSceneLevel(selectC5, "", "", ""); sc = (Scene *) _levels[""]; sc->resolution = "320x200"; Code *alarm_c5 = new Code(""); _levels[""] = alarm_c5; hl = new Highlight("GS_SEQ_51"); sc->hots[1].actions.push_back(hl); gl = new Global("GS_SEQ_51", "NCHECK"); sc->hots[1].actions.push_back(gl); cl = new ChangeLevel("c51.mi_"); sc->hots[1].actions.push_back(cl); hl = new Highlight("GS_SEQ_52"); sc->hots[2].actions.push_back(hl); gl = new Global("GS_SEQ_52", "NCHECK"); sc->hots[2].actions.push_back(gl); cl = new ChangeLevel("c52.mi_"); sc->hots[2].actions.push_back(cl); hl = new Highlight("GS_SEQ_53"); sc->hots[3].actions.push_back(hl); gl = new Global("GS_SEQ_53", "NCHECK"); sc->hots[3].actions.push_back(gl); cl = new ChangeLevel("c53.mi_"); sc->hots[3].actions.push_back(cl); hl = new Highlight("GS_SWITCH7"); sc->hots[4].actions.push_back(hl); gl = new Global("GS_SWITCH7", "NCHECK"); sc->hots[4].actions.push_back(gl); gl = new Global("GS_SWITCH7", "TURNON"); sc->hots[4].actions.push_back(gl); cl = new ChangeLevel(""); sc->hots[4].actions.push_back(cl); hl = new Highlight("GS_SWITCH8"); sc->hots[5].actions.push_back(hl); gl = new Global("GS_SWITCH8", "NCHECK"); sc->hots[5].actions.push_back(gl); gl = new Global("GS_SWITCH8", "TURNON"); sc->hots[5].actions.push_back(gl); cl = new ChangeLevel(""); sc->hots[5].actions.push_back(cl); for (int t = 1; t <= 5; t++) { Common::String fterrMis = Common::String::format(fterr, t); Common::String fterrName = Common::String::format("", t); loadSceneLevel(fterrMis.c_str(), fterrName.c_str(), "", ""); sc = (Scene *) _levels[fterrName.c_str()]; sc->resolution = "320x200"; cl = new ChangeLevel(""); sc->hots[1].actions.push_back(cl); hl = new Highlight("GS_SEQ_19"); sc->hots[2].actions.push_back(hl); cl = new ChangeLevel(""); sc->hots[2].actions.push_back(cl); hl = new Highlight("GS_SEQ_21"); sc->hots[3].actions.push_back(hl); cl = new ChangeLevel(""); sc->hots[3].actions.push_back(cl); hl = new Highlight("GS_SEQ_31"); sc->hots[4].actions.push_back(hl); cl = new ChangeLevel(""); sc->hots[4].actions.push_back(cl); hl = new Highlight("GS_SEQ_41"); sc->hots[5].actions.push_back(hl); cl = new ChangeLevel(""); sc->hots[5].actions.push_back(cl); hl = new Highlight("GS_SEQ_51"); sc->hots[6].actions.push_back(hl); cl = new ChangeLevel(""); sc->hots[6].actions.push_back(cl); } sc = (Scene *) _levels[""]; hl = new Highlight("GS_SEQ_19"); sc->hots[7].actions.push_back(hl); gl = new Global("GS_SEQ_19", "CHECK"); sc->hots[7].actions.push_back(gl); cl = new ChangeLevel("c19.mi_"); sc->hots[7].actions.push_back(cl); hl = new Highlight("GS_SEQ_11"); sc->hots[8].actions.push_back(hl); gl = new Global("GS_SEQ_11", "CHECK"); sc->hots[8].actions.push_back(gl); cl = new ChangeLevel("c11.mi_"); sc->hots[8].actions.push_back(cl); hl = new Highlight("GS_SEQ_12"); sc->hots[9].actions.push_back(hl); gl = new Global("GS_SEQ_12", "CHECK"); sc->hots[9].actions.push_back(gl); cl = new ChangeLevel("c12.mi_"); sc->hots[9].actions.push_back(cl); hl = new Highlight("GS_SEQ_13"); sc->hots[10].actions.push_back(hl); gl = new Global("GS_SEQ_13", "CHECK"); sc->hots[10].actions.push_back(gl); cl = new ChangeLevel("c13.mi_"); sc->hots[10].actions.push_back(cl); hl = new Highlight("GS_SEQ_14"); sc->hots[11].actions.push_back(hl); gl = new Global("GS_SEQ_14", "CHECK"); sc->hots[11].actions.push_back(gl); cl = new ChangeLevel("c14.mi_"); sc->hots[11].actions.push_back(cl); hl = new Highlight("GS_SEQ_15"); sc->hots[12].actions.push_back(hl); gl = new Global("GS_SEQ_15", "CHECK"); sc->hots[12].actions.push_back(gl); cl = new ChangeLevel("c15.mi_"); sc->hots[12].actions.push_back(cl); hl = new Highlight("GS_SEQ_16"); sc->hots[13].actions.push_back(hl); gl = new Global("GS_SEQ_16", "CHECK"); sc->hots[13].actions.push_back(gl); cl = new ChangeLevel("c16.mi_"); sc->hots[13].actions.push_back(cl); hl = new Highlight("GS_SEQ_17"); sc->hots[14].actions.push_back(hl); gl = new Global("GS_SEQ_17", "CHECK"); sc->hots[14].actions.push_back(gl); cl = new ChangeLevel("c17.mi_"); sc->hots[14].actions.push_back(cl); hl = new Highlight("GS_SEQ_18"); sc->hots[15].actions.push_back(hl); gl = new Global("GS_SEQ_18", "CHECK"); sc->hots[15].actions.push_back(gl); cl = new ChangeLevel("c18.mi_"); sc->hots[15].actions.push_back(cl); sc = (Scene *) _levels[""]; hl = new Highlight("GS_SEQ_21"); sc->hots[7].actions.push_back(hl); gl = new Global("GS_SEQ_21", "CHECK"); sc->hots[7].actions.push_back(gl); cl = new ChangeLevel("c21.mi_"); sc->hots[7].actions.push_back(cl); hl = new Highlight("GS_SEQ_22"); sc->hots[8].actions.push_back(hl); gl = new Global("GS_SEQ_22", "CHECK"); sc->hots[8].actions.push_back(gl); cl = new ChangeLevel("c22.mi_"); sc->hots[8].actions.push_back(cl); sc = (Scene *) _levels[""]; hl = new Highlight("GS_SEQ_31"); sc->hots[7].actions.push_back(hl); gl = new Global("GS_SEQ_31", "CHECK"); sc->hots[7].actions.push_back(gl); cl = new ChangeLevel("c31.mi_"); sc->hots[7].actions.push_back(cl); hl = new Highlight("GS_SEQ_32"); sc->hots[8].actions.push_back(hl); gl = new Global("GS_SEQ_32", "CHECK"); sc->hots[8].actions.push_back(gl); cl = new ChangeLevel("c32.mi_"); sc->hots[8].actions.push_back(cl); hl = new Highlight("GS_SEQ_33"); sc->hots[9].actions.push_back(hl); gl = new Global("GS_SEQ_33", "CHECK"); sc->hots[9].actions.push_back(gl); cl = new ChangeLevel("c33.mi_"); sc->hots[9].actions.push_back(cl); hl = new Highlight("GS_SEQ_34"); sc->hots[10].actions.push_back(hl); gl = new Global("GS_SEQ_34", "CHECK"); sc->hots[10].actions.push_back(gl); cl = new ChangeLevel("c34.mi_"); sc->hots[10].actions.push_back(cl); hl = new Highlight("GS_SEQ_35"); sc->hots[11].actions.push_back(hl); gl = new Global("GS_SEQ_35", "CHECK"); sc->hots[11].actions.push_back(gl); cl = new ChangeLevel("c35.mi_"); sc->hots[11].actions.push_back(cl); hl = new Highlight("GS_SEQ_36"); sc->hots[12].actions.push_back(hl); gl = new Global("GS_SEQ_36", "CHECK"); sc->hots[12].actions.push_back(gl); cl = new ChangeLevel("c36.mi_"); sc->hots[12].actions.push_back(cl); sc = (Scene *) _levels[""]; hl = new Highlight("GS_SEQ_41"); sc->hots[7].actions.push_back(hl); gl = new Global("GS_SEQ_41", "CHECK"); sc->hots[7].actions.push_back(gl); cl = new ChangeLevel("c41.mi_"); sc->hots[7].actions.push_back(cl); hl = new Highlight("GS_SEQ_42"); sc->hots[8].actions.push_back(hl); gl = new Global("GS_SEQ_42", "CHECK"); sc->hots[8].actions.push_back(gl); cl = new ChangeLevel("c42.mi_"); sc->hots[8].actions.push_back(cl); sc = (Scene *) _levels[""]; hl = new Highlight("GS_SEQ_51"); sc->hots[7].actions.push_back(hl); gl = new Global("GS_SEQ_51", "CHECK"); sc->hots[7].actions.push_back(gl); cl = new ChangeLevel("c51.mi_"); sc->hots[7].actions.push_back(cl); hl = new Highlight("GS_SEQ_52"); sc->hots[8].actions.push_back(hl); gl = new Global("GS_SEQ_52", "CHECK"); sc->hots[8].actions.push_back(gl); cl = new ChangeLevel("c52.mi_"); sc->hots[8].actions.push_back(cl); hl = new Highlight("GS_SEQ_54"); sc->hots[9].actions.push_back(hl); gl = new Global("GS_SEQ_54", "CHECK"); sc->hots[9].actions.push_back(gl); cl = new ChangeLevel("c54.mi_"); sc->hots[9].actions.push_back(cl); hl = new Highlight("GS_SEQ_55"); sc->hots[10].actions.push_back(hl); gl = new Global("GS_SEQ_55", "CHECK"); sc->hots[10].actions.push_back(gl); cl = new ChangeLevel("c55.mi_"); sc->hots[10].actions.push_back(cl); hl = new Highlight("GS_SEQ_56"); sc->hots[11].actions.push_back(hl); gl = new Global("GS_SEQ_56", "CHECK"); sc->hots[11].actions.push_back(gl); cl = new ChangeLevel("c56.mi_"); sc->hots[11].actions.push_back(cl); hl = new Highlight("GS_SEQ_57"); sc->hots[12].actions.push_back(hl); gl = new Global("GS_SEQ_57", "CHECK"); sc->hots[12].actions.push_back(gl); cl = new ChangeLevel("c57.mi_"); sc->hots[12].actions.push_back(cl); hl = new Highlight("GS_SEQ_58"); sc->hots[13].actions.push_back(hl); gl = new Global("GS_SEQ_58", "CHECK"); sc->hots[13].actions.push_back(gl); cl = new ChangeLevel("c58.mi_"); sc->hots[13].actions.push_back(cl); hl = new Highlight("GS_SEQ_59"); sc->hots[14].actions.push_back(hl); gl = new Global("GS_SEQ_59", "CHECK"); sc->hots[14].actions.push_back(gl); cl = new ChangeLevel("c59.mi_"); sc->hots[14].actions.push_back(cl); loadLib("sound/", "misc/sound.lib", true); _weaponShootSound[0] = ""; _weaponShootSound[1] = "pstlfire.raw"; _weaponShootSound[2] = "ak47fire.raw"; _weaponShootSound[3] = "dblfire.raw"; _weaponShootSound[4] = "m16fire.raw"; _weaponShootSound[5] = "shotfire.raw"; _weaponShootSound[6] = "glm60fr.raw"; _weaponShootSound[7] = "dblfire.raw"; // Not sure _weaponReloadSound[0] = ""; _weaponReloadSound[1] = "pstlload.raw"; _weaponReloadSound[2] = "ak47load.raw"; _weaponReloadSound[3] = "dblload.raw"; _weaponReloadSound[4] = "m16load.raw"; _weaponReloadSound[5] = "shotload.raw"; _weaponReloadSound[6] = "glm60rl.raw"; _weaponReloadSound[7] = "dblload.raw"; // Not sure _deathDay[0] = ""; _deathDay[1] = "preload/deathd1s.smk"; _deathDay[2] = "preload/deathd2s.smk"; _deathDay[3] = "preload/deathd3s.smk"; _deathDay[4] = "preload/deathd4s.smk"; _deathDay[5] = "preload/deathd5s.smk"; _deathDay[6] = "preload/deathd6s.smk"; _deathNight[0] = ""; _deathNight[1] = ""; _deathNight[2] = "preload/deathn2s.smk"; _deathNight[3] = "preload/deathn3s.smk"; _deathNight[4] = "preload/deathn4s.smk"; _deathNight[5] = ""; _deathNight[6] = ""; _deathVideo.push_back("preload/cdeath1s.smk"); _deathVideo.push_back("preload/cdeath2s.smk"); _deathVideo.push_back("preload/cdeath3s.smk"); _heySound[0] = ""; _heySound[1] = "lopzheys.raw"; _heySound[2] = "lambheys.raw"; _heySound[3] = "vasqheyl.raw"; _heySound[4] = "butsheyl.raw"; _heySound[5] = "bropheys.raw"; _heySound[6] = "monsheys.raw"; Graphics::Surface *targets = decodeFrame("preload/targets.smk", 0, &_crosshairsPalette); Common::Rect cursorBox; // No weapon, same as pistol cursorBox = Common::Rect(62, 6, 83, 26); _crosshairsInactive[0].create(cursorBox.width(), cursorBox.height(), _pixelFormat); _crosshairsInactive[0].copyRectToSurface(*targets, 0, 0, cursorBox); cursorBox = Common::Rect(62, 38, 83, 58); _crosshairsActive[0].create(cursorBox.width(), cursorBox.height(), _pixelFormat); _crosshairsActive[0].copyRectToSurface(*targets, 0, 0, cursorBox); cursorBox = Common::Rect(62, 70, 83, 90); _crosshairsTarget[0].create(cursorBox.width(), cursorBox.height(), _pixelFormat); _crosshairsTarget[0].copyRectToSurface(*targets, 0, 0, cursorBox); // Pistol cursorBox = Common::Rect(62, 6, 83, 26); _crosshairsInactive[1].create(cursorBox.width(), cursorBox.height(), _pixelFormat); _crosshairsInactive[1].copyRectToSurface(*targets, 0, 0, cursorBox); cursorBox = Common::Rect(62, 38, 83, 58); _crosshairsActive[1].create(cursorBox.width(), cursorBox.height(), _pixelFormat); _crosshairsActive[1].copyRectToSurface(*targets, 0, 0, cursorBox); cursorBox = Common::Rect(62, 70, 83, 90); _crosshairsTarget[1].create(cursorBox.width(), cursorBox.height(), _pixelFormat); _crosshairsTarget[1].copyRectToSurface(*targets, 0, 0, cursorBox); // Double big crossair, shotgun? cursorBox = Common::Rect(104, 7, 136, 25); _crosshairsInactive[2].create(cursorBox.width(), cursorBox.height(), _pixelFormat); _crosshairsInactive[2].copyRectToSurface(*targets, 0, 0, cursorBox); cursorBox = Common::Rect(104, 39, 136, 57); _crosshairsActive[2].create(cursorBox.width(), cursorBox.height(), _pixelFormat); _crosshairsActive[2].copyRectToSurface(*targets, 0, 0, cursorBox); cursorBox = Common::Rect(104, 71, 136, 89); _crosshairsTarget[2].create(cursorBox.width(), cursorBox.height(), _pixelFormat); _crosshairsTarget[2].copyRectToSurface(*targets, 0, 0, cursorBox); cursorBox = Common::Rect(16, 8, 32, 24); _crosshairsInactive[3].create(cursorBox.width(), cursorBox.height(), _pixelFormat); _crosshairsInactive[3].copyRectToSurface(*targets, 0, 0, cursorBox); cursorBox = Common::Rect(16, 40, 32, 56); _crosshairsActive[3].create(cursorBox.width(), cursorBox.height(), _pixelFormat); _crosshairsActive[3].copyRectToSurface(*targets, 0, 0, cursorBox); cursorBox = Common::Rect(16, 72, 32, 88); _crosshairsTarget[3].create(cursorBox.width(), cursorBox.height(), _pixelFormat); _crosshairsTarget[3].copyRectToSurface(*targets, 0, 0, cursorBox); cursorBox = Common::Rect(163, 11, 173, 21); _crosshairsInactive[4].create(cursorBox.width(), cursorBox.height(), _pixelFormat); _crosshairsInactive[4].copyRectToSurface(*targets, 0, 0, cursorBox); cursorBox = Common::Rect(163, 43, 173, 53); _crosshairsActive[4].create(cursorBox.width(), cursorBox.height(), _pixelFormat); _crosshairsActive[4].copyRectToSurface(*targets, 0, 0, cursorBox); cursorBox = Common::Rect(163, 75, 173, 85); _crosshairsTarget[4].create(cursorBox.width(), cursorBox.height(), _pixelFormat); _crosshairsTarget[4].copyRectToSurface(*targets, 0, 0, cursorBox); // Shotgun cursorBox = Common::Rect(104, 7, 136, 25); _crosshairsInactive[5].create(cursorBox.width(), cursorBox.height(), _pixelFormat); _crosshairsInactive[5].copyRectToSurface(*targets, 0, 0, cursorBox); cursorBox = Common::Rect(104, 39, 136, 57); _crosshairsActive[5].create(cursorBox.width(), cursorBox.height(), _pixelFormat); _crosshairsActive[5].copyRectToSurface(*targets, 0, 0, cursorBox); cursorBox = Common::Rect(104, 71, 136, 88); _crosshairsTarget[5].create(cursorBox.width(), cursorBox.height(), _pixelFormat); _crosshairsTarget[5].copyRectToSurface(*targets, 0, 0, cursorBox); // Double small /* cursorBox = Common::Rect(203, 11, 229, 21); _crosshairsInactive[4].create(cursorBox.width(), cursorBox.height(), _pixelFormat); _crosshairsInactive[4].copyRectToSurface(*targets, 0, 0, cursorBox); cursorBox = Common::Rect(203, 43, 229, 53); _crosshairsActive[4].create(cursorBox.width(), cursorBox.height(), _pixelFormat); _crosshairsActive[4].copyRectToSurface(*targets, 0, 0, cursorBox); cursorBox = Common::Rect(203, 75, 229, 85); _crosshairsTarget[4].create(cursorBox.width(), cursorBox.height(), _pixelFormat); _crosshairsTarget[4].copyRectToSurface(*targets, 0, 0, cursorBox); */ // Granade cursorBox = Common::Rect(256, 2, 273, 29); _crosshairsInactive[6].create(cursorBox.width(), cursorBox.height(), _pixelFormat); _crosshairsInactive[6].copyRectToSurface(*targets, 0, 0, cursorBox); cursorBox = Common::Rect(256, 34, 273, 61); _crosshairsActive[6].create(cursorBox.width(), cursorBox.height(), _pixelFormat); _crosshairsActive[6].copyRectToSurface(*targets, 0, 0, cursorBox); cursorBox = Common::Rect(256, 66, 273, 93); _crosshairsTarget[6].create(cursorBox.width(), cursorBox.height(), _pixelFormat); _crosshairsTarget[6].copyRectToSurface(*targets, 0, 0, cursorBox); // Large crossair cursorBox = Common::Rect(56, 98, 88, 125); _crosshairsInactive[7].create(cursorBox.width(), cursorBox.height(), _pixelFormat); _crosshairsInactive[7].copyRectToSurface(*targets, 0, 0, cursorBox); cursorBox = Common::Rect(57, 130, 88, 158); _crosshairsActive[7].create(cursorBox.width(), cursorBox.height(), _pixelFormat); _crosshairsActive[7].copyRectToSurface(*targets, 0, 0, cursorBox); cursorBox = Common::Rect(57, 162, 88, 189); _crosshairsTarget[7].create(cursorBox.width(), cursorBox.height(), _pixelFormat); _crosshairsTarget[7].copyRectToSurface(*targets, 0, 0, cursorBox); // Additional pointers cursorBox = Common::Rect(4, 100, 33, 123); _leftArrowPointer.create(cursorBox.width(), cursorBox.height(), _pixelFormat); _leftArrowPointer.copyRectToSurface(*targets, 0, 0, cursorBox); cursorBox = Common::Rect(10, 134, 32, 155); _crossPointer.create(cursorBox.width(), cursorBox.height(), _pixelFormat); _crossPointer.copyRectToSurface(*targets, 0, 0, cursorBox); cursorBox = Common::Rect(8, 166, 38, 188); _rightArrowPointer.create(cursorBox.width(), cursorBox.height(), _pixelFormat); _rightArrowPointer.copyRectToSurface(*targets, 0, 0, cursorBox); _weaponMaxAmmo[0] = 0; _weaponMaxAmmo[1] = 10; _weaponMaxAmmo[2] = 2; // large shotgun _weaponMaxAmmo[3] = 8; _weaponMaxAmmo[4] = 6; // pistol? _weaponMaxAmmo[5] = 6; // small shotgun _weaponMaxAmmo[6] = 0; _weaponMaxAmmo[7] = 25; // Boat machine-gun _maxHealth = 100; _warningVideosDay.push_back(""); _warningVideosDay.push_back("warnings/w01s.smk"); _warningVideosDay.push_back("warnings/w02s.smk"); _warningVideosDay.push_back("warnings/w03s.smk"); _warningVideosDay.push_back("warnings/w04s.smk"); _warningVideosDay.push_back("warnings/w05s.smk"); _warningVideosDay.push_back("warnings/w06s.smk"); _warningVideosDay.push_back("warnings/w07s.smk"); _warningAlarmVideos.push_back("warnings/w10s.smk"); _warningAlarmVideos.push_back("warnings/w11s.smk"); _warningHostage = "warnings/w08s.smk"; // Set initial health for the team _health = _maxHealth; _previousHealth = _maxHealth; targets->free(); delete targets; loadLib("", "misc/fonts.lib", true); loadFonts(); _defaultCursor = "crosshair"; _defaultCursorIdx = uint32(-1); resetSceneState(); _nextLevel = ""; } void BoyzEngine::drawString(const Common::String &font, const Common::String &str, int x, int y, int w, uint32 color) { int offset = 0; if (font == "block05.fgx") { for (uint32 c = 0; c < str.size(); c++) { offset = 0; if (str[c] == ':') offset = 1; else if (str[c] == '.') offset = 4; for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { if (!_font05.get(275 + 40*str[c] + j*8 + i)) _compositeSurface->setPixel(x + 5 - i + 6*c, offset + y + j, color); } } } } else if (font == "scifi08.fgx") { for (uint32 c = 0; c < str.size(); c++) { if (str[c] == 0) continue; assert(str[c] >= 32); offset = 0; if (str[c] == 't') offset = 0; else if (str[c] == 'i' || str[c] == '%') offset = 1; else if (Common::isLower(str[c]) || str[c] == ':') offset = 2; for (int i = 0; i < 6; i++) { for (int j = 0; j < 8; j++) { if (!_font08.get(1554 + 72*(str[c]-32) + j*8 + i)) _compositeSurface->setPixel(x + 6 - i + 7*c, offset + y + j, color); } } } } else error("Invalid font: '%s'", font.c_str()); } void BoyzEngine::saveProfile(const Common::String &name, int levelId) { if (name.empty()) { debugC(1, kHypnoDebugMedia, "WARNING: refusing to save at last level %d with an empty name", _lastLevel); return; } SaveStateList saves = getMetaEngine()->listSaves(_targetName.c_str()); // Find the correct level index to before saving for (uint32 i = 0; i < _ids.size(); i++) { if (levelId == _ids[i]) { if (_lastLevel < int(i)) _lastLevel = int(i); break; } } uint32 slot = 0; for (SaveStateList::iterator save = saves.begin(); save != saves.end(); ++save) { if (save->getDescription() == name) break; slot++; } debugC(1, kHypnoDebugMedia, "Saving profile %s with last level %d", name.c_str(), _lastLevel); saveGameState(slot, name, false); } Common::Array BoyzEngine::listProfiles() { Common::Array profiles; SaveStateList saves = getMetaEngine()->listSaves(_targetName.c_str()); for (SaveStateList::iterator save = saves.begin(); save != saves.end(); ++save) { Common::String profile = save->getDescription(); profile.toUppercase(); profiles.push_back(profile); } return profiles; } bool BoyzEngine::loadProfile(const Common::String &name) { SaveStateList saves = getMetaEngine()->listSaves(_targetName.c_str()); uint32 slot = 0; for (SaveStateList::iterator save = saves.begin(); save != saves.end(); ++save) { if (save->getDescription() == name) break; slot++; } if (slot == saves.size()) { debugC(1, kHypnoDebugMedia, "Failed to load %s", name.c_str()); return false; } loadGameState(slot); return true; } Common::Error BoyzEngine::saveGameStream(Common::WriteStream *stream, bool isAutosave) { if (isAutosave) return Common::kNoError; if (_lastLevel < 0 || _lastLevel >= 30) error("Invalid last level!"); stream->writeString(_name); stream->writeByte(0); stream->writeString(_difficulty); stream->writeByte(0); stream->writeUint32LE(_lives); stream->writeUint32LE(_previousHealth); stream->writeUint32LE(_score); stream->writeUint32LE(_lastLevel); // Save current stats stream->writeUint32LE(_stats.livesUsed); stream->writeUint32LE(_stats.shootsFired); stream->writeUint32LE(_stats.enemyHits); stream->writeUint32LE(_stats.enemyTargets); stream->writeUint32LE(_stats.targetsDestroyed); stream->writeUint32LE(_stats.targetsMissed); stream->writeUint32LE(_stats.friendliesEncountered); stream->writeUint32LE(_stats.infoReceived); stream->writeUint32LE(_globalStats.livesUsed); stream->writeUint32LE(_globalStats.shootsFired); stream->writeUint32LE(_globalStats.enemyHits); stream->writeUint32LE(_globalStats.enemyTargets); stream->writeUint32LE(_globalStats.targetsDestroyed); stream->writeUint32LE(_globalStats.targetsMissed); stream->writeUint32LE(_globalStats.friendliesEncountered); stream->writeUint32LE(_globalStats.infoReceived); stream->writeUint32LE(_flashbackMode); saveSceneState(stream); return Common::kNoError; } Common::Error BoyzEngine::loadGameStream(Common::SeekableReadStream *stream) { _name = stream->readString(); _difficulty = stream->readString(); _lives = stream->readUint32LE(); _previousHealth = stream->readUint32LE(); _score = stream->readUint32LE(); _lastLevel = stream->readUint32LE(); // Load stats _stats.livesUsed = stream->readUint32LE(); _stats.shootsFired = stream->readUint32LE(); _stats.enemyHits = stream->readUint32LE(); _stats.enemyTargets = stream->readUint32LE(); _stats.targetsDestroyed = stream->readUint32LE(); _stats.targetsMissed = stream->readUint32LE(); _stats.friendliesEncountered = stream->readUint32LE(); _stats.infoReceived = stream->readUint32LE(); _globalStats.livesUsed = stream->readUint32LE(); _globalStats.shootsFired = stream->readUint32LE(); _globalStats.enemyHits = stream->readUint32LE(); _globalStats.enemyTargets = stream->readUint32LE(); _globalStats.targetsDestroyed = stream->readUint32LE(); _globalStats.targetsMissed = stream->readUint32LE(); _globalStats.friendliesEncountered = stream->readUint32LE(); _globalStats.infoReceived = stream->readUint32LE(); _flashbackMode = stream->readUint32LE(); loadSceneState(stream); if (_unlockAllLevels) { _nextLevel = ""; _flashbackMode = true; unlockAllLevels(); } else if (_flashbackMode) { _nextLevel = ""; } else if (_ids[_lastLevel] == 3591) _nextLevel = ""; else if (_ids[_lastLevel] == 3592) _nextLevel = ""; else if (_ids[_lastLevel] == 531) _nextLevel = ""; else _nextLevel = Common::String::format("c%d.mi_", _ids[_lastLevel]); return Common::kNoError; } Common::String BoyzEngine::findNextLevel(const Transition *trans) { if (trans->nextLevel.empty()) error("Invalid transition!"); return trans->nextLevel; } Common::String BoyzEngine::findNextLevel(const Common::String &level) { return level; } } // namespace Hypno