From 39a8c71f776254b272e68a36fa5355293c0ae5f9 Mon Sep 17 00:00:00 2001 From: Denis Kasak Date: Mon, 8 Jun 2009 22:18:52 +0000 Subject: Adding Draci Historie engine skeleton (engine stub, BAR archiver, rudimentary GPL disassembler) svn-id: r41390 --- engines/draci/gpldisasm.cpp | 329 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 329 insertions(+) create mode 100644 engines/draci/gpldisasm.cpp (limited to 'engines/draci/gpldisasm.cpp') diff --git a/engines/draci/gpldisasm.cpp b/engines/draci/gpldisasm.cpp new file mode 100644 index 0000000000..1749136702 --- /dev/null +++ b/engines/draci/gpldisasm.cpp @@ -0,0 +1,329 @@ +/* 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 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +/** + * @brief GPL2 bytecode disassembler + * @param gplcode A pointer to the bytecode + * len Length of the bytecode + * + * GPL2 is short for Game Programming Language 2 which is the script language + * used by Draci Historie. This is a simple disassembler for the language. + * + * A compiled GPL2 program consists of a stream of bytes representing commands + * and their parameters. The syntax is as follows: + * + * Syntax of a command: + * + * + * Syntax of a parameter: + * - 1: integer number literally passed to the program + * - 2-1: string stored in the reservouir of game strings (i.e. something to be + * displayed) and stored as an index in this list + * - 2-2: string resolved by the compiler (i.e., a path to another file) and + * replaced by an integer index of this entity in the appropriate namespace + * (e.g., the index of the palette, location, ...) + * - 3-0: relative jump to a label defined in this code. Each label must be + * first declared in the beginning of the program. + * - 3-1 .. 3-9: index of an entity in several namespaces, defined in file ident + * - 4: mathematical expression compiled into a postfix format + * + * In the compiled program, parameters of type 1..3 are represented by a single + * 16-bit integer. The called command knows by its definition what namespace the + * value comes from. + */ + +#include "common/debug.h" +#include "common/stream.h" + +#include "draci/gpldisasm.h" +#include "draci/barchive.h" +#include "draci/draci.h" + +#define skipParams(x) for(unsigned int i = 0; i < (x); ++i) reader.readUint16LELE() +#define CMDPAIR(x, y) (((x) << 8) | y) + +namespace Draci { + +// FIXME: Handle math expressions properly instead of just skipping them +void handleMathExpression(Common::MemoryReadStream &reader) { + uint16 temp; + while (1) { + temp = reader.readUint16LE(); + if (temp == 0) { + break; + } + temp = reader.readUint16LE(); + } + return; +} + +int gpldisasm(byte *gplcode, uint16 len) { + Common::MemoryReadStream reader(gplcode, len); + + while (!reader.eos()) { + // read in command pair + uint16 cmdpair = reader.readUint16BE(); + + uint16 param1, param2, param3; + + switch (cmdpair) { + case CMDPAIR(5,1): + param1 = reader.readUint16LE(); + param2 = reader.readUint16LE(); + debugC(2, kDraciBytecodeDebugLevel, "C_Load %hu %hu", param1, param2); + break; + case CMDPAIR(4,1): + param1 = reader.readUint16LE(); + param2 = reader.readUint16LE(); + debugC(2, kDraciBytecodeDebugLevel, "C_Start %hu %hu", param1, param2); + break; + case CMDPAIR(5,2): + param1 = reader.readUint16LE(); + param2 = reader.readUint16LE(); + debugC(2, kDraciBytecodeDebugLevel, "C_StartPlay %hu %hu", + param1, param2); + break; + case CMDPAIR(5,3): + debugC(2, kDraciBytecodeDebugLevel, "C_JustTalk"); + break; + case CMDPAIR(5,4): + debugC(2, kDraciBytecodeDebugLevel, "C_JustStay"); + break; + case CMDPAIR(10,2): + param1 = reader.readUint16LE(); + param2 = reader.readUint16LE(); + param3 = reader.readUint16LE(); + debugC(2, kDraciBytecodeDebugLevel, "C_StayOn %hu %hu %hu", + param1, param2, param3); + break; + case CMDPAIR(10,1): + param1 = reader.readUint16LE(); + param2 = reader.readUint16LE(); + param3 = reader.readUint16LE(); + debugC(2, kDraciBytecodeDebugLevel, "C_WalkOn %hu %hu %hu", + param1, param2, param3); + break; + case CMDPAIR(10,3): + param1 = reader.readUint16LE(); + param2 = reader.readUint16LE(); + param3 = reader.readUint16LE(); + debugC(2, kDraciBytecodeDebugLevel, "C_WalkOnPlay %hu %hu %hu", + param1, param2, param3); + break; + case CMDPAIR(7,1): + param1 = reader.readUint16LE(); + param2 = reader.readUint16LE(); + debugC(2, kDraciBytecodeDebugLevel, "C_ObjStat %hu %hu", + param1, param2); + break; + case CMDPAIR(7,2): + param1 = reader.readUint16LE(); + param2 = reader.readUint16LE(); + debugC(2, kDraciBytecodeDebugLevel, "C_ObjStat_On %hu %hu", + param1, param2); + break; + case CMDPAIR(8,1): + param1 = reader.readUint16LE(); + param2 = reader.readUint16LE(); + debugC(2, kDraciBytecodeDebugLevel, "C_IcoStat %hu %hu", + param1, param2); + break; + case CMDPAIR(14,1): + param1 = reader.readUint16LE(); + param2 = reader.readUint16LE(); + debugC(2, kDraciBytecodeDebugLevel, "C_NewRoom %hu %hu", + param1, param2); + break; + case CMDPAIR(6,1): + param1 = reader.readUint16LE(); + param2 = reader.readUint16LE(); + debugC(2, kDraciBytecodeDebugLevel, "C_Talk %hu %hu", + param1, param2); + break; + case CMDPAIR(2,1): + param1 = reader.readUint16LE(); + handleMathExpression(reader); + debugC(2, kDraciBytecodeDebugLevel, "C_Let %hu", param1); + break; + case CMDPAIR(15,1): + param1 = reader.readUint16LE(); + debugC(2, kDraciBytecodeDebugLevel, "C_ExecInit %hu", param1); + break; + case CMDPAIR(15,2): + param1 = reader.readUint16LE(); + debugC(2, kDraciBytecodeDebugLevel, "C_ExecLook %hu", param1); + break; + case CMDPAIR(15,3): + param1 = reader.readUint16LE(); + debugC(2, kDraciBytecodeDebugLevel, "C_ExecUse %hu", param1); + break; + case CMDPAIR(16,1): + debugC(2, kDraciBytecodeDebugLevel, "C_RepaintInventory"); + break; + case CMDPAIR(16,2): + debugC(2, kDraciBytecodeDebugLevel, "C_ExitInventory"); + break; + case CMDPAIR(1,1): + param1 = reader.readUint16LE(); + debugC(2, kDraciBytecodeDebugLevel, "C_goto %hu", param1); + break; + case CMDPAIR(3,1): + handleMathExpression(reader); + param1 = reader.readUint16LE(); + debugC(2, kDraciBytecodeDebugLevel, "C_if %hu", param1); + break; + case CMDPAIR(9,1): + param1 = reader.readUint16LE(); + debugC(2, kDraciBytecodeDebugLevel, "C_Dialogue %hu", param1); + break; + case CMDPAIR(9,2): + debugC(2, kDraciBytecodeDebugLevel, "C_ExitDialogue"); + break; + case CMDPAIR(9,3): + debugC(2, kDraciBytecodeDebugLevel, "C_ResetDialogue"); + break; + case CMDPAIR(9,4): + debugC(2, kDraciBytecodeDebugLevel, "C_ResetDialogueFrom"); + break; + case CMDPAIR(9,5): + param1 = reader.readUint16LE(); + debugC(2, kDraciBytecodeDebugLevel, "C_ResetBlock %hu", param1); + break; + case CMDPAIR(11,1): + param1 = reader.readUint16LE(); + debugC(2, kDraciBytecodeDebugLevel, "C_LoadPalette %hu", param1); + break; + case CMDPAIR(12,1): + debugC(2, kDraciBytecodeDebugLevel, "C_SetPalette"); + break; + case CMDPAIR(12,2): + debugC(2, kDraciBytecodeDebugLevel, "C_BlackPalette"); + break; + case CMDPAIR(13,1): + param1 = reader.readUint16LE(); + param2 = reader.readUint16LE(); + param3 = reader.readUint16LE(); + debugC(2, kDraciBytecodeDebugLevel, "C_FadePalette %hu %hu %hu", + param1, param2, param3); + break; + case CMDPAIR(13,2): + param1 = reader.readUint16LE(); + param2 = reader.readUint16LE(); + param3 = reader.readUint16LE(); + debugC(2, kDraciBytecodeDebugLevel, "C_FadePalettePlay %hu %hu %hu", + param1, param2, param3); + break; + case CMDPAIR(17,1): + debugC(2, kDraciBytecodeDebugLevel, "C_ExitMap"); + break; + case CMDPAIR(18,1): + param1 = reader.readUint16LE(); + debugC(2, kDraciBytecodeDebugLevel, "C_LoadMusic %hu", param1); + break; + case CMDPAIR(18,2): + debugC(2, kDraciBytecodeDebugLevel, "C_StartMusic"); + break; + case CMDPAIR(18,3): + debugC(2, kDraciBytecodeDebugLevel, "C_StopMusic"); + break; + case CMDPAIR(18,4): + param1 = reader.readUint16LE(); + debugC(2, kDraciBytecodeDebugLevel, "C_FadeOutMusic %hu", param1); + break; + case CMDPAIR(18,5): + param1 = reader.readUint16LE(); + debugC(2, kDraciBytecodeDebugLevel, "C_FadeInMusic %hu", param1); + break; + case CMDPAIR(19,1): + debugC(2, kDraciBytecodeDebugLevel, "C_Mark"); + break; + case CMDPAIR(19,2): + debugC(2, kDraciBytecodeDebugLevel, "C_Release"); + break; + case CMDPAIR(20,1): + debugC(2, kDraciBytecodeDebugLevel, "C_Play"); + break; + case CMDPAIR(21,1): + param1 = reader.readUint16LE(); + debugC(2, kDraciBytecodeDebugLevel, "C_LoadMap %hu", param1); + break; + case CMDPAIR(21,2): + debugC(2, kDraciBytecodeDebugLevel, "C_RoomMap"); + break; + case CMDPAIR(22,1): + debugC(2, kDraciBytecodeDebugLevel, "C_DisableQuickHero"); + break; + case CMDPAIR(22,2): + debugC(2, kDraciBytecodeDebugLevel, "C_EnableQuickHero"); + break; + case CMDPAIR(23,1): + debugC(2, kDraciBytecodeDebugLevel, "C_DisableSpeedText"); + break; + case CMDPAIR(23,2): + debugC(2, kDraciBytecodeDebugLevel, "C_EnableSpeedText"); + break; + case CMDPAIR(24,1): + debugC(2, kDraciBytecodeDebugLevel, "C_QuitGame"); + break; + case CMDPAIR(25,1): + debugC(2, kDraciBytecodeDebugLevel, "C_PushNewRoom"); + break; + case CMDPAIR(25,2): + debugC(2, kDraciBytecodeDebugLevel, "C_PopNewRoom"); + break; + case CMDPAIR(26,1): + debugC(2, kDraciBytecodeDebugLevel, "C_ShowCheat"); + break; + case CMDPAIR(26,2): + debugC(2, kDraciBytecodeDebugLevel, "C_HideCheat"); + break; + case CMDPAIR(26,3): + param1 = reader.readUint16LE(); + debugC(2, kDraciBytecodeDebugLevel, "C_ClearCheat %hu", param1); + break; + case CMDPAIR(27,1): + param1 = reader.readUint16LE(); + param2 = reader.readUint16LE(); + param3 = reader.readUint16LE(); + debugC(2, kDraciBytecodeDebugLevel, "C_FeedPassword %hu %hu %hu", + param1, param2, param3); + break; + case CMDPAIR(0, 0): + debugC(2, kDraciBytecodeDebugLevel, "gplend"); + break; + case CMDPAIR(0, 1): + debugC(2, kDraciBytecodeDebugLevel, "exit"); + break; + default: + debugC(2, kDraciBytecodeDebugLevel, "Unknown opcode %hu, %hu", + (cmdpair >> 8) & 0xFF, cmdpair & 0xFF); + } + } + + return 0; +} + +} + -- cgit v1.2.3