aboutsummaryrefslogtreecommitdiff
path: root/sword2/sword2.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sword2/sword2.cpp')
-rw-r--r--sword2/sword2.cpp572
1 files changed, 572 insertions, 0 deletions
diff --git a/sword2/sword2.cpp b/sword2/sword2.cpp
new file mode 100644
index 0000000000..c12d7bb09f
--- /dev/null
+++ b/sword2/sword2.cpp
@@ -0,0 +1,572 @@
+/* Copyright (C) 1994-2003 Revolution Software Ltd
+ *
+ * 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ */
+
+//------------------------------------------------------------------------------------
+#include <ctype.h>
+#include <stdio.h>
+//#include <windows.h>
+
+#include "driver/driver96.h"
+#include "common/gameDetector.h"
+#include "build_display.h"
+#include "console.h"
+#include "controls.h"
+#include "debug.h"
+#include "events.h"
+#include "header.h"
+#include "interpreter.h"
+#include "layers.h"
+#include "logic.h"
+#include "maketext.h"
+#include "memory.h"
+#include "mouse.h"
+#include "protocol.h"
+#include "resman.h"
+#include "scroll.h"
+#include "sound.h"
+#include "speech.h"
+#include "startup.h"
+#include "sword2.h"
+#include "sync.h"
+
+#define MAX_PATH 260
+
+void Start_game(void);
+
+int RunningFromCd();
+
+uint8 quitGame = 0;
+
+//------------------------------------------------------------------------------------
+// version & owner details
+
+//So version string is 18 bytes long :
+//Version String = <8 byte header,5 character version, \0, INT32 time>
+
+uint8 version_string[HEAD_LEN+10] = {1, 255, 37, 22, 45, 128, 34, 67};
+
+uint8 unencoded_name[HEAD_LEN+48] = {76, 185, 205, 23, 44, 34, 24, 34,
+ 'R','e','v','o','l','u','t','i','o','n',' ',
+ 'S','o','f','t','w','a','r','e',' ','L','t','d',
+ 0};
+
+uint8 encoded_name[HEAD_LEN+48] = {44, 32, 190, 222, 123, 65, 233, 99,
+ 179, 209, 225, 157, 222, 238, 219, 209, 143, 224, 133, 190,
+ 232, 209, 162, 177, 198, 228, 202, 146, 180, 232, 214, 65,
+ 65, 65, 116, 104, 116, 114, 107, 104, 32, 49, 64, 35, 123,
+ 125, 61, 45, 41, 40, 163, 36, 49, 123, 125, 10};
+
+//------------------------------------------------------------------------------------
+
+uint8 gamePaused=0; // James17jun97
+//uint32 pause_text_bloc_no=0; // James17jun97
+uint8 graphics_level_fudged=0; // James10july97
+uint8 stepOneCycle=0; // for use while game paused
+
+//------------------------------------------------------------------------------------
+void PauseGame(void); // James17jun97
+void UnpauseGame(void); // James17jun97
+//------------------------------------------------------------------------------------
+
+static const VersionSettings bs2_settings[] = {
+ /* Broken Sword 2 */
+ {"bs2", "Broken Sword II", GID_BS2_FIRST, 99, VersionSettings::ADLIB_DONT_CARE, GF_DEFAULT_TO_1X_SCALER, "players.clu" },
+ {NULL, NULL, 0, 0, VersionSettings::ADLIB_DONT_CARE, 0, NULL}
+};
+
+BS2State *g_bs2 = NULL;
+
+const VersionSettings *Engine_BS2_targetList() {
+ return bs2_settings;
+}
+
+Engine *Engine_BS2_create(GameDetector *detector, OSystem *syst) {
+ return new BS2State(detector, syst);
+}
+
+BS2State::BS2State(GameDetector *detector, OSystem *syst)
+ : Engine(detector, syst) {
+
+ _detector = detector;
+ _syst = syst;
+ g_bs2 = this;
+}
+
+
+void BS2State::errorString(const char *buf1, char *buf2) {
+ strcpy(buf2, buf1);
+}
+
+int32 InitialiseGame(void)
+{
+//init engine drivers
+
+ uint8 *file;
+
+ Zdebug("CALLING: Init_memory_manager");
+ Init_memory_manager(); // get some falling RAM and put it in your pocket, never let it slip away
+ Zdebug("RETURNED.");
+
+ Zdebug("CALLING: res_man.InitResMan");
+ res_man.InitResMan(); // initialise the resource manager
+ Zdebug("RETURNED from res_man.InitResMan");
+
+ // initialise global script variables
+ file=res_man.Res_open(1); // res 1 is the globals list
+ Zdebug("CALLING: SetGlobalInterpreterVariables");
+ SetGlobalInterpreterVariables((int32*)(file+sizeof(_standardHeader)));
+ Zdebug("RETURNED.");
+// res_man.Res_close(1); // DON'T CLOSE VARIABLES RESOURCE - KEEP IT OPEN AT VERY START OF MEMORY SO IT CAN'T MOVE!
+
+ file=res_man.Res_open(8); // DON'T CLOSE PLAYER OBJECT RESOURCE - KEEP IT OPEN IN MEMORY SO IT CAN'T MOVE!
+
+ //----------------------------------------
+ Zdebug("CALLING: InitialiseFontResourceFlags");
+ InitialiseFontResourceFlags(); // Set up font resource variables for this language version (James31july97)
+ // Also set the windows application name to the proper game name
+ Zdebug("RETURNED.");
+ //----------------------------------------
+
+ Zdebug("CALLING: Init_console");
+ Init_console(); // set up the console system
+ Zdebug("RETURNED.");
+
+ #ifdef _DEBUG
+ Zdebug("CALLING: Init_start_menu");
+ Init_start_menu(); // read in all the startup information
+ Zdebug("RETURNED from Init_start_menu");
+ #endif // _DEBUG
+
+
+
+ Zdebug("CALLING: Init_text_bloc_system");
+ Init_text_bloc_system(); // no blocs live
+ Zdebug("RETURNED.");
+
+ Zdebug("CALLING: Init_sync_system");
+ Init_sync_system();
+ Zdebug("RETURNED.");
+
+ Zdebug("CALLING: Init_event_system");
+ Init_event_system();
+ Zdebug("RETURNED.");
+
+ Zdebug("CALLING: Init_fx_queue");
+ Init_fx_queue(); // initialise the sound fx queue
+ Zdebug("RETURNED.");
+
+#ifdef _DEMO // demo only
+ DEMO=1; // set script variable
+#endif
+
+ return(0);
+}
+//------------------------------------------------------------------------------------
+void Close_game() //Tony11Oct96
+{
+ Zdebug("Close_game() STARTING:");
+//avoid corruption when windows kicks back in
+ EraseBackBuffer();
+ FlipScreens();
+ EraseBackBuffer();
+ FlipScreens();
+
+ Kill_music(); // Stop music instantly! (James22aug97)
+ Close_memory_manager(); // free the memory again
+ res_man.Close_ResMan();
+
+ Zdebug("Close_game() DONE.");
+}
+//------------------------------------------------------------------------------------
+int32 GameCycle(void)
+{
+//do one game cycle
+
+
+ {
+ if (LLogic.Return_run_list()) //got a screen to run?
+ {
+ do //run the logic session UNTIL a full loop has been performed
+ {
+ Reset_render_lists(); // reset the graphic 'buildit' list before a new logic list (see FN_register_frame)
+ Reset_mouse_list(); // reset the mouse hot-spot list (see FN_register_mouse & FN_register_frame)
+ }
+ while(LLogic.Process_session()); //keep going as long as new lists keep getting put in - i.e. screen changes
+ }
+ else //start the console and print the start options perhaps?
+ {
+ StartConsole();
+ Print_to_console("AWAITING START COMMAND: (Enter 's 1' then 'q' to start from beginning)");
+ }
+ }
+
+ if (this_screen.scroll_flag) // if this screen is wide
+ Set_scrolling(); // recompute the scroll offsets every game-cycle
+
+ Mouse_engine(); //check the mouse
+
+ Process_fx_queue();
+
+ res_man.Res_next_cycle(); // update age and calculate previous cycle memory usage
+
+ if (quitGame)
+ return(1);
+ else
+ return(0);
+}
+//------------------------------------------------------------------------------------
+// int main(int argc, char *argv[])
+// int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
+void BS2State::go()
+{
+ uint32 rv;
+ uint8 breakOut = 0;
+ char c;
+ int j=100;
+ uint32 pc=0;
+
+// Zdebug("[%s]", lpCmdLine);
+
+
+ #ifndef _DEBUG
+ DisableQuitKey(); // so cannot use Ctrl-Q from the release versions (full game or demo)
+ #endif
+
+
+ if (RunningFromCd()) //stop this game being run from CD
+ exit(-1);
+
+
+
+ // Call the application "Revolution" until the resource manager is ready to dig the name out of a text file
+ // See InitialiseGame() which calls InitialiseFontResourceFlags() in maketext.cpp
+ // Have to do it like this since we cannot really fire up the resource manager until a window
+ // has been created as any errors are displayed via a window, thus time becomes a loop.
+
+ Zdebug("CALLING: InitialiseWindow");
+ // rv = InitialiseWindow(hInstance, hPrevInstance, lpCmdLine, nCmdShow, "Revolution");
+ rv = RD_OK;
+ Zdebug("RETURNED with rv = %.8x", rv);
+ if (rv != RD_OK)
+ {
+ // ReportDriverError(rv);
+ return;
+ }
+
+ Zdebug("CALLING: InitialiseDisplay");
+ // rv = InitialiseDisplay(640, 480, 8, RD_FULLSCREEN);
+ _syst->init_size(640, 480);
+ rv = RD_OK;
+
+ Zdebug("RETURNED with rv = %.8x", rv);
+ if (rv != RD_OK)
+ {
+ // ReportDriverError(rv);
+ CloseAppWindow();
+ return;
+ }
+
+ Zdebug("CALLING: ReadOptionSettings");
+ ReadOptionSettings(); //restore the menu settings
+ Zdebug("RETURNED.");
+
+ Zdebug("CALLING: InitialiseSound");
+ rv = InitialiseSound(22050, 2, 16);
+ Zdebug("RETURNED with rv = %.8x", rv);
+ // don't care if this fails, because it should still work without sound cards
+ // but it should set a global system flag so that we can avoid loading sound fx & streaming music
+ // because they won't be heard anyway
+/*
+ if (rv != RD_OK)
+ {
+ ReportDriverError(rv);
+ CloseAppWindow();
+ return(0);
+ }
+*/
+
+ Zdebug("CALLING: InitialiseGame");
+ if (InitialiseGame())
+ {
+ Zdebug("RETURNED from InitialiseGame - closing game");
+ RestoreDisplay();
+ CloseAppWindow();
+ return;
+ }
+ Zdebug("RETURNED from InitialiseGame - ok");
+
+
+
+//check for restore game on startup - at the mo any passed argument is good enough to trigger this
+ // if (lpCmdLine[0]) //non zero
+ if (0)
+ {
+ Set_mouse(NORMAL_MOUSE_ID);
+
+ if (!Restore_control()) // restore a game
+ Start_game();
+ }
+ //-------------------------------------------------------------
+ // release versions only (full-game and demo)
+// #if NDEBUG // comment this out for debug versions to start game automatically!
+ else
+ Start_game();
+// #endif // comment this out for debug versions to start game automatically!
+ //-------------------------------------------------------------
+
+
+ Zdebug("CALLING: InitialiseRenderCycle");
+ InitialiseRenderCycle();
+ Zdebug("RETURNED.");
+
+ while (TRUE)
+ {
+ if (ServiceWindows() == RDERR_APPCLOSED)
+ {
+ break; // break out of main game loop
+ }
+
+
+ // check for events
+ parseEvents();
+#ifdef _DEBUG
+ if (grabbingSequences && (!console_status))
+ GrabScreenShot();
+#endif
+
+ while (!gotTheFocus)
+ {
+ if (ServiceWindows() == RDERR_APPCLOSED)
+ {
+ breakOut = 1;
+ break; // break out of this while-loop
+ }
+ }
+
+ if (breakOut) // if we are closing down the game
+ break; // break out of main game loop
+
+//-----
+
+#ifdef _DEBUG
+ if (console_status)
+ {
+ if (One_console())
+ {
+ EndConsole();
+ UnpauseAllSound(); // see sound.cpp
+ }
+ }
+#endif
+
+ if (!console_status) //not in console mode - if the console is quit we want to get a logic cycle in before
+ { //the screen is build. Mostly because of first scroll cycle stuff
+#ifdef _DEBUG
+ if (stepOneCycle) // if we've just stepped forward one cycle while the game was paused
+ {
+ PauseGame();
+ stepOneCycle=0;
+ }
+#endif
+ if (KeyWaiting())
+ {
+ ReadKey(&c);
+#ifdef _DEBUG
+ if (c==27) // ESC whether paused or not
+ {
+ PauseAllSound(); // see sound.cpp
+ StartConsole(); // start the console
+ }
+ else
+#endif
+ if (gamePaused) // if currently paused
+ {
+ if (toupper(c)=='P') // 'P' while paused = unpause!
+ {
+ UnpauseGame();
+ }
+#ifdef _DEBUG
+ else if (toupper(c)==' ') // SPACE bar while paused = step one frame!
+ {
+ stepOneCycle=1; // step through one game cycle
+ UnpauseGame();
+ }
+#endif // _DEBUG
+ }
+ else if (toupper(c)=='P') // 'P' while not paused = pause!
+ {
+ PauseGame();
+ }
+#ifdef _DEBUG // frame-skipping only allowed on debug version
+ else if (toupper(c)=='S') // 'S' toggles speed up (by skipping display rendering)
+ {
+ renderSkip = 1 - renderSkip;
+ }
+#endif // _DEBUG
+ }
+
+ if (gamePaused==0) // skip GameCycle if we're paused
+ {
+#ifdef _DEBUG
+ gameCycle += 1;
+#endif
+
+ if (GameCycle())
+ break; // break out of main game loop
+ }
+
+#ifdef _DEBUG
+ Build_debug_text(); // creates the debug text blocks
+#endif // _DEBUG
+ }
+//-----
+
+ // James (24mar97)
+
+#ifdef _DEBUG
+ if ((console_status)||(renderSkip==0)||(gameCycle%4 == 0)) // if not in console & 'renderSkip' is set, only render display once every 4 game-cycles
+ Build_display(); // create and flip the screen
+#else
+ Build_display(); // create and flip the screen
+#endif // _DEBUG
+
+ }
+
+ Close_game(); //close engine systems down
+ RestoreDisplay();
+ CloseAppWindow();
+
+ return; //quit the game
+}
+//------------------------------------------------------------------------------------
+int RunningFromCd()
+{
+ char sCDName[MAX_PATH];
+ char sRoot[MAX_PATH];
+ DWORD dwMaxCompLength, dwFSFlags;
+/*
+ GetModuleFileName(NULL , sRoot, _MAX_PATH);
+ *(strchr(sRoot,'\\')+1) = '\0';
+
+ if (!GetVolumeInformation(sRoot, sCDName,_MAX_PATH, NULL, &dwMaxCompLength, &dwFSFlags, NULL, 0))
+ return -1;
+ if (!scumm_strnicmp(sCDName,CD1_LABEL,6))
+ return 1;
+ if (!scumm_strnicmp(sCDName,CD2_LABEL,6))
+ return 2;
+*/
+ return 0;
+}
+//------------------------------------------------------------------------------------
+//------------------------------------------------------------------------------------
+//------------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------------
+void Start_game(void) //Tony29May97
+{
+//boot the game straight into a start script
+
+ Zdebug("Start_game() STARTING:");
+
+#ifdef _DEMO
+ #define SCREEN_MANAGER_ID 19 // DOCKS SECTION START
+#else
+ #define SCREEN_MANAGER_ID 949 // INTRO & PARIS START
+#endif
+
+ char *raw_script;
+ char *raw_data_ad;
+ uint32 null_pc=1; // the required start-scripts are both script #1 in the respective ScreenManager objects
+
+ raw_data_ad = (char*) (res_man.Res_open(8)); // open george object, ready for start script to reference
+ raw_script = (char*) (res_man.Res_open(SCREEN_MANAGER_ID)); // open the ScreenManager object
+
+ RunScript ( raw_script, raw_data_ad, &null_pc ); // run the start script now (because no console)
+
+ res_man.Res_close(SCREEN_MANAGER_ID); // close the ScreenManager object
+ res_man.Res_close(8); // close george
+
+ Zdebug("Start_game() DONE.");
+}
+//------------------------------------------------------------------------------------
+//------------------------------------------------------------------------------------
+void PauseGame(void) // James17jun97
+{
+// uint8 *text;
+
+// text = FetchTextLine( res_man.Res_open(3258), 449 ); // open text file & get the line "PAUSED"
+// pause_text_bloc_no = Build_new_block(text+2, 320, 210, 640, 184, RDSPR_TRANS+RDSPR_DISPLAYALIGN, SPEECH_FONT_ID, POSITION_AT_CENTRE_OF_BASE);
+// res_man.Res_close(3258); // now ok to close the text file
+
+ //---------------------------
+ // don't allow Pause while screen fading or while black (James 03sep97)
+ if(GetFadeStatus()!=RDFADE_NONE)
+ return;
+ //---------------------------
+
+ PauseAllSound();
+
+//make a normal mouse
+ ClearPointerText();
+// mouse_mode=MOUSE_normal;
+ SetLuggageAnim(NULL, NULL); //this is the only place allowed to do it this way
+ Set_mouse(NULL); // blank cursor
+ mouse_touching=1; //forces engine to choose a cursor
+
+ if (current_graphics_level==3) // if level at max
+ {
+ UpdateGraphicsLevel(3,2); // turn down because palette-matching won't work when dimmed
+ graphics_level_fudged=1;
+ }
+
+ if (stepOneCycle==0) // don't dim it if we're single-stepping through frames
+ {
+ DimPalette(); // dim the palette during the pause (James26jun97)
+ }
+
+ gamePaused=1;
+}
+//------------------------------------------------------------------------------------
+void UnpauseGame(void) // James17jun97
+{
+// Kill_text_bloc(pause_text_bloc_no); // removed "PAUSED" from screen
+
+ if ((OBJECT_HELD)&&(real_luggage_item))
+ Set_luggage(real_luggage_item);
+
+ UnpauseAllSound();
+
+ SetFullPalette(0xffffffff); // put back game screen palette; see Build_display.cpp (James26jun97)
+
+ if (graphics_level_fudged) // if level at max
+ {
+ UpdateGraphicsLevel(2,3); // turn up again
+ graphics_level_fudged=0;
+ }
+
+ gamePaused=0;
+ unpause_zone=2;
+
+ if ((!mouse_status)||(choosing)) //if mouse is about or we're in a chooser menu
+ Set_mouse(NORMAL_MOUSE_ID);
+}
+//------------------------------------------------------------------------------------
+//------------------------------------------------------------------------------------
+