[Scummvm-cvs-logs] SF.net SVN: scummvm: [23578] scummvm/trunk/tools

dreammaster at users.sourceforge.net dreammaster at users.sourceforge.net
Sun Jul 23 15:08:35 CEST 2006


Revision: 23578
Author:   dreammaster
Date:     2006-07-23 06:08:22 -0700 (Sun, 23 Jul 2006)
ViewCVS:  http://svn.sourceforge.net/scummvm/?rev=23578&view=rev

Log Message:
-----------
Initial commit of tool to create lure.dat file

Added Paths:
-----------
    scummvm/trunk/tools/create_lure/
    scummvm/trunk/tools/create_lure/Makefile
    scummvm/trunk/tools/create_lure/create_lure_dat.cpp
    scummvm/trunk/tools/create_lure/create_lure_dat.h
    scummvm/trunk/tools/create_lure/process_actions.cpp
Added: scummvm/trunk/tools/create_lure/Makefile
===================================================================
--- scummvm/trunk/tools/create_lure/Makefile	                        (rev 0)
+++ scummvm/trunk/tools/create_lure/Makefile	2006-07-23 13:08:22 UTC (rev 23578)
@@ -0,0 +1,4 @@
+# $Id$
+
+all:
+	g++ -I../.. create_lure_dat.cpp process_actions.cpp -o create_lure


Property changes on: scummvm/trunk/tools/create_lure/Makefile
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + Date Rev Author URL Id
Name: svn:eol-style
   + native

Added: scummvm/trunk/tools/create_lure/create_lure_dat.cpp
===================================================================
--- scummvm/trunk/tools/create_lure/create_lure_dat.cpp	                        (rev 0)
+++ scummvm/trunk/tools/create_lure/create_lure_dat.cpp	2006-07-23 13:08:22 UTC (rev 23578)
@@ -0,0 +1,1147 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * 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$
+ *
+ * This is a utility for extracting needed resource data from the Lure of the Temptress
+ * lure.exe file into a new file lure.dat - this file is required for the ScummVM
+ * Lure of the Temptress module to work properly
+ *
+ * TODO: 
+ * Some of the field values, such as hotspot tick proc offsets, will vary with
+ * different language versions. These will need to be remapped to a language independant
+ * value once I've fully implemented the English version.
+ * Some areas of the data segment are still to be decoded
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "create_lure_dat.h"
+
+File lure_exe;
+
+uint16 animOffsets[MAX_NUM_ANIM_RECORDS];
+int animIndex = 0;
+uint16 actionOffsets[MAX_NUM_ACTION_RECORDS];
+int actionIndex = 0;
+
+
+void add_anim_record(uint16 offset) {
+	for (int ctr = 0; ctr < animIndex; ++ctr)
+		if (animOffsets[ctr] == offset) return;
+	if (animIndex == MAX_NUM_ANIM_RECORDS) {
+		printf("Animation record offset table size exceeded\n");
+		exit(1);
+	}
+	animOffsets[animIndex++] = offset;
+}
+
+void add_action_list(uint16 offset) {
+	for (int ctr = 0; ctr < actionIndex; ++ctr)
+		if (actionOffsets[ctr] == offset) return;
+	if (actionIndex == MAX_NUM_ACTION_RECORDS) {
+		printf("Action record offset table size exceeded\n");
+		exit(1);
+	}
+	actionOffsets[actionIndex++] = offset;
+}
+
+void read_basic_palette(byte *&data, uint16 &totalSize) {
+	totalSize = PALETTE_SIZE;
+	lure_exe.seek(PALETTE_OFFSET);
+	data = (byte *) malloc(PALETTE_SIZE);
+	lure_exe.read(data, totalSize);
+}
+
+#define ALT_PALETTE_1 0x1757
+#define ALT_PALETTE_1_SIZE 180
+#define ALT_PALETTE_2 0x180B
+#define ALT_PALETTE_2_SIZE 24
+
+void read_replacement_palette(byte *&data, uint16 &totalSize) {
+	totalSize = ALT_PALETTE_1_SIZE + ALT_PALETTE_2_SIZE;
+	data = (byte *) malloc(totalSize);
+
+	lure_exe.seek(DATA_SEGMENT + ALT_PALETTE_1);
+	lure_exe.read(data, ALT_PALETTE_1_SIZE);
+	lure_exe.seek(DATA_SEGMENT + ALT_PALETTE_2);
+	lure_exe.read(data + ALT_PALETTE_1_SIZE, ALT_PALETTE_2_SIZE);
+}
+
+void read_dialog_data(byte *&data, uint16 &totalSize) {
+	totalSize = DIALOG_SIZE;
+	lure_exe.seek(DIALOG_OFFSET);
+	data = (byte *) malloc(DIALOG_SIZE);
+	lure_exe.read(data, totalSize);
+}
+
+void read_talk_dialog_data(byte *&data, uint16 &totalSize) {
+	totalSize = TALK_DIALOG_SIZE;
+	lure_exe.seek(TALK_DIALOG_OFFSET, SEEK_SET);
+	data = (byte *) malloc(TALK_DIALOG_SIZE);
+	lure_exe.read(data, totalSize);
+}
+
+void read_room_data(byte *&data, uint16 &totalSize) 
+{
+	data = (byte *) malloc(MAX_DATA_SIZE);
+	memset(data, 0, MAX_DATA_SIZE);
+
+	uint16 *offsetPtr = (uint16 *) data;
+	uint16 offset = (ROOM_NUM_ENTRIES + 1) * sizeof(uint16);
+	uint16 pixelOffset;
+	RoomResource buffer;
+	int outputIndex = 0;
+	RoomHeaderEntry headerEntry;
+	RoomRectIn bounds;
+
+	for (int index = 0; index < ROOM_NUM_ENTRIES; ++index) {
+
+		lure_exe.seek(DATA_SEGMENT + ROOM_TABLE + index * 9);
+		lure_exe.read(&headerEntry, sizeof(RoomHeaderEntry));
+
+		if ((FROM_LE_16(headerEntry.offset) != 0) && 
+			(FROM_LE_16(headerEntry.offset) != 0xffff) &&
+			(FROM_LE_16(headerEntry.roomNumber) != 0xc09) && 
+			(FROM_LE_16(headerEntry.roomNumber) != 0)) {
+			// Store offset of room entry
+			*offsetPtr++ = TO_LE_16(offset);
+
+			// Copy over basic room details
+			lure_exe.seek(DATA_SEGMENT + headerEntry.offset);
+			lure_exe.read(&buffer, sizeof(RoomResource));
+
+			RoomResourceOutput *rec = (RoomResourceOutput *) (data + offset);
+			rec->roomNumber = headerEntry.roomNumber;
+			rec->descId = headerEntry.descId;
+			rec->numLayers = buffer.numLayers;
+			memcpy(rec->layers, buffer.layers, 8);
+			rec->sequenceOffset = buffer.sequenceOffset;			
+			rec->clippingXStart = TO_LE_16(FROM_LE_16(buffer.clippingXStart) - 0x80);
+			rec->clippingXEnd = (FROM_LE_16(buffer.clippingXEnd) == 0) ? 0 : 
+			  TO_LE_16(FROM_LE_16(buffer.clippingXEnd) - 0x80);
+			rec->numExits = 0;
+
+			offset += sizeof(RoomResourceOutput);
+
+			// Copy over room exits
+			for (;;) {
+				RoomResourceExit1 *p = (RoomResourceExit1 *) (data + offset);
+				lure_exe.read(p, sizeof(RoomResourceExit1));
+				if (FROM_LE_16(p->xs) == 0xffff) break;
+
+				rec->numExits = TO_LE_16(FROM_LE_16(rec->numExits) + 1);
+				p->xs = TO_LE_16(FROM_LE_16(p->xs) - 0x80);
+				p->ys = TO_LE_16(FROM_LE_16(p->ys) - 0x80);
+				p->xe = TO_LE_16(FROM_LE_16(p->xe) - 0x80);
+				p->ye = TO_LE_16(FROM_LE_16(p->ye) - 0x80);
+				offset += sizeof(RoomResourceExit1);
+				RoomResourceExit2 *p2 = (RoomResourceExit2 *) (data + offset);
+
+				if (FROM_LE_16(p->sequenceOffset) == 0xffff) {
+					lure_exe.read(p2, sizeof(RoomResourceExit2));
+					p2->newRoomX = TO_LE_16(FROM_LE_16(p2->newRoomX) - 0x80);
+					p2->newRoomY = TO_LE_16(FROM_LE_16(p2->newRoomY) - 0x80);
+				} else {
+					p2->newRoom = 0;
+					p2->direction = 0;
+					p2->newRoomX = 0;
+					p2->newRoomY = 0;
+				}
+
+				offset += sizeof(RoomResourceExit2);
+			}
+
+			// Handle the random destination walk bounds for the room
+			lure_exe.seek(DATA_SEGMENT + WALK_AREAS_OFFSET + 
+				buffer.walkBoundsIndex * sizeof(RoomRectIn));
+			lure_exe.read(&bounds, sizeof(RoomRectIn));
+			rec->walkBounds.xs = TO_LE_16(FROM_LE_16(bounds.xs) - 0x80);
+			rec->walkBounds.xe = TO_LE_16(FROM_LE_16(bounds.xe) - 0x80);
+			rec->walkBounds.ys = TO_LE_16(FROM_LE_16(bounds.ys) - 0x80);
+			rec->walkBounds.ye = TO_LE_16(FROM_LE_16(bounds.ye) - 0x80);
+
+			// If the room has a default pixel blocks list, add the references
+			if (buffer.pixelListOffset != 0) {
+				lure_exe.seek(DATA_SEGMENT + FROM_LE_16(buffer.pixelListOffset));
+				pixelOffset = lure_exe.readWord();
+				while (pixelOffset != 0) {
+					add_anim_record(pixelOffset);
+					pixelOffset = lure_exe.readWord();
+				}
+			}
+		}
+	}
+
+	WRITE_LE_UINT16(offsetPtr, 0xffff);
+	totalSize = offset;
+}
+
+void read_hotspot_data(byte *&data, uint16 &totalSize) 
+{
+	uint16 offsets[4] = {0x5d98, 0x5eb8, 0x623e, 0x63b1};
+	uint16 startId[4] = {0x3e8, 0x408, 0x2710, 0x7530};
+	int walkNumEntries = 0;
+	int walkCtr;
+	int numEntries;
+	HotspotWalkToRecord rec;
+	HotspotWalkToRecord *walkList;
+	HotspotHeaderEntry entryHeader;
+	HotspotResource entry;
+	uint16 dataSize;
+	HotspotResourceOutput *r;
+	CurrentActionInput action;
+
+	// Allocate enough space for output hotspot list
+	data = (byte *) malloc(MAX_HOTSPOTS * sizeof(HotspotResourceOutput));
+
+	// Determine number of hotspot walk to entries
+	lure_exe.seek(DATA_SEGMENT + HOTSPOT_WALK_TO_OFFSET);
+	do {
+		++walkNumEntries;
+		lure_exe.read(&rec, sizeof(HotspotWalkToRecord));
+	} while (TO_LE_16(rec.hotspotId) != 0);
+	--walkNumEntries;
+
+	dataSize = walkNumEntries * sizeof(HotspotWalkToRecord);
+	walkList = (HotspotWalkToRecord *) malloc(dataSize);
+	lure_exe.seek(DATA_SEGMENT + HOTSPOT_WALK_TO_OFFSET);
+	lure_exe.read(walkList, sizeof(HotspotWalkToRecord) * walkNumEntries);
+
+	// Main code for creating the hotspot list
+
+	r = (HotspotResourceOutput *) data;
+	numEntries = 0;
+
+	for (int tableNum = 0; tableNum < 4; ++tableNum) {
+		uint16 hotspotIndex = 0;
+		for (;;) {
+			lure_exe.seek(DATA_SEGMENT + offsets[tableNum] +  hotspotIndex * 9);
+			lure_exe.read(&entryHeader, sizeof(HotspotHeaderEntry));
+			if (FROM_LE_16(entryHeader.offset) == 0xffff) break;
+
+			memset(r, 0, sizeof(HotspotResourceOutput));
+			r->hotspotId = TO_LE_16(startId[tableNum] + hotspotIndex);
+			r->nameId = TO_LE_16(FROM_LE_16(entryHeader.resourceId) & 0x1fff);
+			r->descId = TO_LE_16(FROM_LE_16(entryHeader.descId) & 0x1fff);
+			r->descId2 = TO_LE_16(FROM_LE_16(entryHeader.descId2) & 0x1fff);
+			r->hdrFlags = entryHeader.hdrFlags;
+
+			// Get the hotspot data
+			lure_exe.seek(DATA_SEGMENT + entryHeader.offset);
+			lure_exe.read(&entry, sizeof(HotspotResource));
+			
+			r->actions = entry.actions;
+			r->roomNumber = entry.roomNumber;
+			r->startX = TO_LE_16(FROM_LE_16(entry.startX) - 0x80);
+			r->startY = TO_LE_16(FROM_LE_16(entry.startY) - 0x80);
+
+			r->width = entry.width;
+			r->height = entry.height;
+			r->widthCopy = entry.widthCopy;
+			r->heightCopy = entry.heightCopy;
+			r->yCorrection = entry.yCorrection;
+			r->talkX = entry.talkX;
+			r->talkY = entry.talkY;
+			r->characterMode = entry.characterMode;
+			r->delayCtr = entry.delayCtr;
+			r->tickSequenceOffset = entry.tickSequenceOffset;
+
+			r->layer = entry.layer;
+			r->scriptLoadFlag = entry.scriptLoadFlag;
+			r->loadOffset = entry.loadOffset;
+			r->colourOffset = entry.colourOffset;
+			r->sequenceOffset = entry.sequenceOffset;
+			r->tickProcOffset = entry.tickProcOffset;
+			r->flags = entry.flags;
+
+			// Find the walk-to coordinates for the hotspot
+			walkCtr = 0;
+			while ((walkCtr < walkNumEntries) &&
+				   (FROM_LE_16(walkList[walkCtr].hotspotId) != FROM_LE_16(r->hotspotId)))
+				++walkCtr;
+			if (walkCtr == walkNumEntries) {
+				r->walkX = 0;
+				r->walkY = 0;
+			} else {
+				r->walkX = TO_LE_16(FROM_LE_16(walkList[walkCtr].x) - 0x80);
+				uint16 y = FROM_LE_16(walkList[walkCtr].y);
+				r->walkY = TO_LE_16((y & 0x8000) | (uint16) ((int16) (y & 0x7fff) - 0x80));
+			}
+
+			// Use the offset of the animation data as a dummy Id for the data
+			r->animRecordId = entry.animOffset;
+			r->tickTimeout = entry.tickTimeout;
+			add_anim_record(FROM_LE_16(entry.animOffset));
+
+			// Add in the actions offset table
+			r->actionsOffset = entry.actionsOffset;
+			if (FROM_LE_16(entry.actionsOffset) != 0)
+				add_action_list(FROM_LE_16(entry.actionsOffset));
+
+			if (FROM_LE_16(r->hotspotId) >= 0x408) {
+				// Hotspot is not an NPC
+				r->npcSchedule = 0;
+			} else {
+				// Check for an NPC schedule
+				lure_exe.seek(DATA_SEGMENT + entryHeader.offset + 0x63);
+				lure_exe.read(&action, sizeof(CurrentActionInput));
+
+				if (action.action != 2) 
+					r->npcSchedule = 0;
+				else {
+					r->npcSchedule = get_sequence_index(FROM_LE_16(action.dataOffset));
+				}
+			}
+
+			++hotspotIndex;
+			++r;
+			++numEntries;
+
+			if (numEntries == MAX_HOTSPOTS) {
+				printf("Ran out of stack spaces for hotspot copying\n");
+				exit(1);
+			}
+		}
+	}
+
+	r->hotspotId = TO_LE_16(0xffff);
+	totalSize = numEntries * sizeof(HotspotResourceOutput) + 2;
+
+	// Dispose of hotspot walk-to co-ordinate list
+	free(walkList);
+}
+
+void read_hotspot_override_data(byte *&data, uint16 &totalSize) 
+{
+	lure_exe.seek(DATA_SEGMENT + HOTSPOT_OVERRIDE_OFFSET);
+	int numOverrides = 0;
+	HotspotOverride rec;
+
+	// Determine number of hotspot overrides
+	do {
+		++numOverrides;
+		lure_exe.read(&rec, sizeof(HotspotOverride));
+	} while (FROM_LE_16(rec.hotspotId) != 0);
+	--numOverrides;
+
+	// Prepare output data and read in all entries at once
+	totalSize = numOverrides * sizeof(HotspotOverride) + 2;
+	data = (byte *) malloc(totalSize);
+	lure_exe.seek(DATA_SEGMENT + HOTSPOT_OVERRIDE_OFFSET);
+	lure_exe.read(data, totalSize - 2);
+	WRITE_LE_UINT16(data + totalSize - 2, 0xffff);
+
+	// Post-process the coordinates
+	HotspotOverride *p = (HotspotOverride *) data;
+	for (int overrideCtr = 0; overrideCtr < numOverrides; ++overrideCtr, ++p) {
+		p->xs = TO_LE_16(FROM_LE_16(p->xs) - 0x80);
+		p->xe = TO_LE_16(FROM_LE_16(p->xe) - 0x80);
+		p->ys = TO_LE_16(FROM_LE_16(p->ys) - 0x80);
+		p->ye = TO_LE_16(FROM_LE_16(p->ye) - 0x80);
+	}
+}
+
+void read_room_exits(byte *&data, uint16 &totalSize) {
+	RoomExitHotspotRecord rec;
+	uint16 offsets[NUM_ROOM_EXITS];
+	uint16 numEntries[NUM_ROOM_EXITS];
+	int roomCtr;
+	totalSize = (NUM_ROOM_EXITS + 1) * sizeof(uint16);
+
+	lure_exe.seek(DATA_SEGMENT + ROOM_EXITS_OFFSET);
+	for (roomCtr = 0; roomCtr < NUM_ROOM_EXITS; ++roomCtr)
+		offsets[roomCtr] = lure_exe.readWord();
+
+	// First loop to find total of room exit records there are
+	for (roomCtr = 0; roomCtr < NUM_ROOM_EXITS; ++roomCtr) {
+		numEntries[roomCtr] = 0;
+		if (offsets[roomCtr] == 0) continue;
+
+		// Get number of exits for the room
+		lure_exe.seek(DATA_SEGMENT + offsets[roomCtr]);
+		lure_exe.read(&rec, sizeof(RoomExitHotspotRecord));
+		while (FROM_LE_16(rec.xs) != 0) {
+			totalSize += sizeof(RoomExitHotspotOutputRecord);
+			numEntries[roomCtr]++;
+			lure_exe.read(&rec, sizeof(RoomExitHotspotRecord));
+		}
+		totalSize += sizeof(uint16); // save room for room list end flag
+	}
+
+	// Alloacte the total needed space
+	data = (byte *) malloc(totalSize);
+	uint16 *offset = (uint16 *) data;
+	uint16 destIndex = (NUM_ROOM_EXITS + 1) * sizeof(uint16);
+	uint16 entryCtr;
+	
+	// Loop to build up the result table
+
+	for (roomCtr = 0; roomCtr < NUM_ROOM_EXITS; ++roomCtr) {
+		if (offsets[roomCtr] == 0) {
+			*offset++ = 0;		// No entries
+		} else {
+			// Read in the entries for the room
+			*offset++ = TO_LE_16(destIndex);
+
+			RoomExitHotspotOutputRecord *destP = (RoomExitHotspotOutputRecord *) 
+				(data + destIndex);
+
+			lure_exe.seek(DATA_SEGMENT + offsets[roomCtr]);
+
+			for (entryCtr = 0; entryCtr < numEntries[roomCtr]; ++entryCtr, ++destP) {
+				lure_exe.read(&rec, sizeof(RoomExitHotspotRecord));
+
+				// Copy over the record
+				destP->xs = TO_LE_16(FROM_LE_16(rec.xs) - 0x80);
+				destP->xe = TO_LE_16(FROM_LE_16(rec.xe) - 0x80);
+				destP->ys = TO_LE_16(FROM_LE_16(rec.ys) - 0x80);
+				destP->ye = TO_LE_16(FROM_LE_16(rec.ye) - 0x80);
+				destP->hotspotId = rec.hotspotId;
+				destP->cursorNum = rec.cursorNum;
+				destP->destRoomNumber = rec.destRoomNumber;
+			}
+			
+			destIndex += numEntries[roomCtr] * sizeof(RoomExitHotspotOutputRecord);
+			WRITE_LE_UINT16(data + destIndex, 0xffff);
+			destIndex += sizeof(uint16);
+		}
+	}
+	WRITE_LE_UINT16(offset, 0xffff);
+}
+
+void read_room_exit_joins(byte *&data, uint16 &totalSize) {
+	RoomExitHotspotJoinRecord rec, *p;
+	lure_exe.seek(DATA_SEGMENT + ROOM_EXIT_JOINS_OFFSET);
+	int numRecords = 0;
+	uint32 unused;
+
+	lure_exe.seek(DATA_SEGMENT + ROOM_EXIT_JOINS_OFFSET);
+	do {
+		lure_exe.read(&rec, sizeof(RoomExitHotspotJoinRecord));
+		lure_exe.read(&unused, sizeof(uint32));
+		++numRecords;
+	} while (FROM_LE_16(rec.hotspot1Id) != 0);
+	--numRecords;
+
+	// Allocate the data and read in all the records
+	totalSize = (numRecords * sizeof(RoomExitHotspotJoinRecord)) + 2;
+	data = (byte *) malloc(totalSize);
+	lure_exe.seek(DATA_SEGMENT + ROOM_EXIT_JOINS_OFFSET);
+	
+	p = (RoomExitHotspotJoinRecord *) data;
+	for (int recordCtr = 0; recordCtr < numRecords; ++recordCtr)
+	{
+		lure_exe.read(p, sizeof(RoomExitHotspotJoinRecord));
+		lure_exe.read(&unused, sizeof(uint32));
+		++p;
+	}
+	WRITE_LE_UINT16(p, 0xffff);
+}
+
+// This next method reads in the animation and movement data. At the moment I
+// figure out which animations have valid movement record sets by finding
+// animations whose four direction offsets are near each other. There's 
+// probably a better method than this, but it'll do for now
+
+void read_anim_data(byte *&data, uint16 &totalSize) {
+	// Add special pixel records
+	add_anim_record(0x5c95);
+
+	// Get the animation data records
+	AnimRecord inRec;
+	MovementRecord move;
+	MovementRecord *destMove;
+	uint16 offset, moveOffset;
+	uint16 startOffset;
+	int ctr, dirCtr;
+	int movementSize = 0;
+	bool *includeAnim = (bool *) malloc(animIndex);
+
+	// Loop to figure out the total number of movement records there are
+	for (ctr = 0; ctr < animIndex; ++ctr) {
+		lure_exe.seek(DATA_SEGMENT + animOffsets[ctr]);
+		lure_exe.read(&inRec, sizeof(AnimRecord));
+
+		if ((FROM_LE_16(inRec.leftOffset) < 0x5000) || 
+			(FROM_LE_16(inRec.rightOffset) < 0x5000) ||
+			(abs(FROM_LE_16(inRec.leftOffset)-FROM_LE_16(inRec.rightOffset)) > 0x800) ||
+			(abs(FROM_LE_16(inRec.rightOffset)-FROM_LE_16(inRec.upOffset)) > 0x800) ||
+			(abs(FROM_LE_16(inRec.upOffset)-FROM_LE_16(inRec.downOffset)) > 0x800)) {
+			// Animation doesn't have valid movement data
+			includeAnim[ctr] = false;
+		} else {
+			includeAnim[ctr] = true;
+			for (dirCtr=0; dirCtr<4; ++dirCtr) {
+				switch (dirCtr) {
+				case 0:
+					offset = FROM_LE_16(inRec.leftOffset);
+					break;
+				case 1:
+					offset = FROM_LE_16(inRec.rightOffset);
+					break;
+				case 2:
+					offset = FROM_LE_16(inRec.upOffset);
+					break;
+				default:
+					offset = FROM_LE_16(inRec.downOffset);
+				}
+
+				if (offset != 0) {
+					lure_exe.seek(DATA_SEGMENT + offset);
+					lure_exe.read(&move, sizeof(MovementRecord));
+
+					while (FROM_LE_16(move.frameNumber) != 0xffff) {
+						movementSize += sizeof(MovementRecord);
+						lure_exe.read(&move, sizeof(MovementRecord));
+					}
+					movementSize += 2;
+				}
+			}
+		}
+	}
+
+	totalSize = animIndex * sizeof(AnimRecordOutput) + 2 + movementSize;
+	AnimRecordOutput *rec = (AnimRecordOutput *) malloc(totalSize);
+	data = (byte *) rec;
+	moveOffset = animIndex * sizeof(AnimRecordOutput) + 2;
+
+	// Loop to get in the animation records
+	for (ctr = 0; ctr < animIndex; ++ctr, ++rec) {
+		lure_exe.seek(DATA_SEGMENT + animOffsets[ctr]);
+		lure_exe.read(&inRec, sizeof(AnimRecord));
+
+		rec->animRecordId = animOffsets[ctr];
+		rec->animId = inRec.animId;
+		rec->flags = TO_LE_16(inRec.flags);
+
+		rec->leftOffset = 0; 
+		rec->rightOffset = 0;
+		rec->upOffset = 0;
+		rec->downOffset = 0;
+
+		rec->upFrame = inRec.upFrame;
+		rec->downFrame = inRec.downFrame;
+		rec->leftFrame = inRec.leftFrame;
+		rec->rightFrame = inRec.rightFrame;
+
+		if (includeAnim[ctr]) {
+			// Loop to get movement records
+			uint16 *inDirs[4] = {&inRec.leftOffset, &inRec.rightOffset,
+				&inRec.upOffset, &inRec.downOffset};
+			uint16 *outDirs[4] = {&rec->leftOffset, &rec->rightOffset,
+				&rec->upOffset, &rec->downOffset};
+
+			for (dirCtr=0; dirCtr<4; ++dirCtr) {
+				offset = READ_LE_UINT16(inDirs[dirCtr]);
+
+				if (offset == 0) {
+					startOffset = 0;
+				} else {
+					startOffset = moveOffset;
+
+					lure_exe.seek(DATA_SEGMENT + offset);
+					lure_exe.read(&move, sizeof(MovementRecord));
+					destMove = (MovementRecord *) (data + moveOffset);
+
+					while (FROM_LE_16(move.frameNumber) != 0xffff) {
+						destMove->frameNumber = move.frameNumber;
+						destMove->xChange = move.xChange;
+						destMove->yChange = move.yChange;
+
+						moveOffset += sizeof(MovementRecord);
+						++destMove;
+						lure_exe.read(&move, sizeof(MovementRecord));
+					}
+					
+					destMove->frameNumber = TO_LE_16(0xffff);
+					moveOffset += 2;
+				}
+
+				WRITE_LE_UINT16(outDirs[dirCtr], startOffset);
+			}
+		}
+	}
+
+	rec->animRecordId = TO_LE_16(0xffff);
+	delete includeAnim;
+}
+
+void read_script_data(byte *&data, uint16 &totalSize) {
+	lure_exe.seek(SCRIPT_SEGMENT);
+	
+	totalSize = SCRIPT_SEGMENT_SIZE;
+	data = (byte *) malloc(totalSize);
+	lure_exe.read(data, totalSize);
+}
+
+void read_script2_data(byte *&data, uint16 &totalSize) {
+	lure_exe.seek(SCRIPT2_SEGMENT);
+	
+	totalSize = SCRIPT2_SEGMENT_SIZE;
+	data = (byte *) malloc(totalSize);
+	lure_exe.read(data, totalSize);
+}
+
+void read_hotspot_script_offsets(byte *&data, uint16 &totalSize) {
+	lure_exe.seek(DATA_SEGMENT + HOTSPOT_SCRIPT_LIST);
+	
+	totalSize = HOTSPOT_SCRIPT_SIZE;
+	data = (byte *) malloc(totalSize);
+	lure_exe.read(data, totalSize);
+}
+
+void read_messages_segment(byte *&data, uint16 &totalSize) {
+	lure_exe.seek(MESSAGES_SEGMENT);
+	totalSize = MESSAGES_SEGMENT_SIZE;
+	data = (byte *) malloc(totalSize);
+	lure_exe.read(data, totalSize);
+}
+
+// Reads in the list of actions used
+
+void read_actions_list(byte *&data, uint16 &totalSize) {
+	// Allocate enough space for output action list
+	data = (byte *) malloc(MAX_DATA_SIZE);
+	HotspotActionsRecord *header = (HotspotActionsRecord *) data;
+	uint16 offset = actionIndex * sizeof(HotspotActionsRecord) + sizeof(uint16);
+
+	for (int ctr = 0; ctr < actionIndex; ++ctr) {
+		header->recordId = actionOffsets[ctr];
+		header->offset = offset;
+		++header;
+
+		lure_exe.seek(DATA_SEGMENT + actionOffsets[ctr]);
+		uint16 *numItems = (uint16 *) (data + offset);
+		lure_exe.read(numItems, sizeof(uint16));
+		offset += 2;
+
+		if (READ_UINT16(numItems) > 0) {
+			lure_exe.read(data + offset, READ_UINT16(numItems) * 3);
+			offset += READ_UINT16(numItems) * 3;
+		}
+	}
+	header->recordId = TO_LE_16(0xffff);
+}
+
+// Reads in the talk data 
+
+#define TALK_OFFSET 0x505c
+#define TALK_NUM_ENTRIES 28
+#define MAX_TALK_LISTS 300
+
+uint16 talkOffsets[MAX_TALK_LISTS];
+int talkOffsetIndex = 0;
+
+void add_talk_offset(uint16 offset) {
+	for (int ctr = 0; ctr < talkOffsetIndex; ++ctr) 
+		if (talkOffsets[ctr] == offset) return;
+	if (talkOffsetIndex == MAX_TALK_LISTS) {
+		printf("Exceeded maximum talk offset list size\n");
+		exit(1);
+	}
+
+	talkOffsets[talkOffsetIndex++] = offset;
+}
+
+struct TalkEntry {
+	uint16 hotspotId;
+	uint16 offset;
+};
+
+void read_talk_headers(byte *&data, uint16 &totalSize) {
+	TalkEntry entries[TALK_NUM_ENTRIES];
+	uint16 sortedOffsets[TALK_NUM_ENTRIES+1];
+	int entryCtr, subentryCtr;
+
+	lure_exe.seek(DATA_SEGMENT + TALK_OFFSET);
+	lure_exe.read(&entries[0], sizeof(TalkEntry) * TALK_NUM_ENTRIES);
+
+	// Sort the entry offsets into a list - this is used to figure out each entry's size
+	int currVal, prevVal = 0;
+	for (entryCtr = 0; entryCtr < TALK_NUM_ENTRIES; ++entryCtr) {
+		currVal = 0xffff;
+		for (subentryCtr = 0; subentryCtr < TALK_NUM_ENTRIES; ++subentryCtr) {
+			if ((FROM_LE_16(entries[subentryCtr].offset) < currVal) &&
+				(FROM_LE_16(entries[subentryCtr].offset) > prevVal)) 
+				currVal = FROM_LE_16(entries[subentryCtr].offset);
+		}
+		if (currVal == 0xffff) break;
+
+		sortedOffsets[entryCtr] = currVal;
+		prevVal = currVal;
+	}
+	sortedOffsets[entryCtr] = 0x5540; // end for end record
+
+	data = (byte *) malloc(MAX_DATA_SIZE);
+	TalkEntry *entry = (TalkEntry *) data;
+	uint16 offset = TALK_NUM_ENTRIES * sizeof(TalkEntry) + sizeof(uint16);
+
+	for (int entryCtr = 0; entryCtr < TALK_NUM_ENTRIES; ++entryCtr) {
+		entry->hotspotId = entries[entryCtr].hotspotId;
+		entry->offset = TO_LE_16(offset);
+		++entry;
+
+		// Find the following offset in a sorted list
+		int startOffset = FROM_LE_16(entries[entryCtr].offset);
+		int nextOffset = 0;
+		for (subentryCtr = 0; subentryCtr < TALK_NUM_ENTRIES; ++subentryCtr) {
+			if (sortedOffsets[subentryCtr] == startOffset) {
+				nextOffset = sortedOffsets[subentryCtr+1];
+				break;
+			}
+		}
+		if (nextOffset == 0) 
+			exit(1);
+
+		// Read in line entries into the data
+		lure_exe.seek(DATA_SEGMENT + startOffset);
+		int size = nextOffset - startOffset;
+		uint16 *talkOffset = (uint16 *) (data + offset);
+		lure_exe.read(talkOffset, size);
+
+		while (size > 0) {
+			if (READ_UINT16(talkOffset) != 0) 
+				add_talk_offset(READ_UINT16(talkOffset));
+			size -= sizeof(uint16);
+			offset += sizeof(uint16);
+			talkOffset++;
+		}
+
+		WRITE_LE_UINT16(talkOffset, 0xffff);
+		offset += 2;
+	}
+
+	add_talk_offset(0xffff);
+	entry->hotspotId = TO_LE_16(0xffff);
+	totalSize = offset + 2;
+}
+
+// Reads in the contents of the previously loaded talk lists
+
+struct TalkRecord {
+	uint16 recordId;
+	uint16 listOffset;
+	uint16 responsesOffset;
+};
+
+uint16 giveTalkIds[6] = {0xCF5E, 0xCF14, 0xCF90, 0xCFAA, 0xCFD0, 0xCFF6};
+
+void read_talk_data(byte *&data, uint16 &totalSize) {
+	uint16 responseOffset;
+	int talkCtr, subentryCtr;
+	uint16 size;
+
+	for (talkCtr = 0; talkCtr < 6; ++talkCtr)
+		add_talk_offset(giveTalkIds[talkCtr]);
+
+	data = (byte *) malloc(MAX_DATA_SIZE);
+	TalkRecord *header = (TalkRecord *) data;
+	uint16 offset = talkOffsetIndex * sizeof(TalkRecord) + sizeof(uint16);
+
+	uint16 *sortedList = (uint16 *) malloc((talkOffsetIndex+1) * sizeof(uint16));
+	memset(sortedList, 0, (talkOffsetIndex+1) * sizeof(uint16));
+
+	// Sort the entry offsets into a list - this is used to figure out each entry's size
+	int currVal, prevVal = 0;
+	for (talkCtr = 0; talkCtr < talkOffsetIndex; ++talkCtr) {
+		currVal = 0xffff;
+		for (subentryCtr = 0; subentryCtr < talkOffsetIndex; ++subentryCtr) {
+			if ((talkOffsets[subentryCtr] < currVal) &&
+				(talkOffsets[subentryCtr] > prevVal)) 
+				currVal = talkOffsets[subentryCtr];
+		}
+		if (currVal == 0xffff) break;
+
+		sortedList[talkCtr] = currVal;
+		prevVal = currVal;
+	}
+	sortedList[talkCtr] = 0xf010;
+	int numTalks = talkCtr;
+
+	// Loop through the talk list
+
+	for (talkCtr = 0; talkCtr < numTalks; ++talkCtr) {
+		uint16 startOffset = sortedList[talkCtr];
+		uint16 nextOffset = sortedList[talkCtr+1];
+
+		header->recordId = startOffset;
+		header->listOffset = offset;
+		
+		lure_exe.seek(DATA_SEGMENT + startOffset);
+		responseOffset = lure_exe.readWord();
+		startOffset += 2;
+
+		// Special handling for entry at 0d930h
+		if (responseOffset == 0x8000) continue;
+
+		// Calculate talk data size - if response is within record range,
+		// use simple calculation size. Otherwise, read in full data until
+		// end of record
+		if ((responseOffset < startOffset) || (responseOffset >= nextOffset))
+			size = nextOffset - startOffset;
+		else
+			size = responseOffset - startOffset;
+		if ((size % 6) == 2) size -= 2;
+		if ((size % 6) != 0) {
+			printf("Failure reading talk data\n");
+			exit(1);
+		}
+
+		// Read in the list of talk entries
+		lure_exe.read(data + offset, size);
+		offset += size;
+		memset(data + offset, 0xff, 2);
+		offset += 2;
+
+		// Handle the response data
+		header->responsesOffset = offset;
+
+		// Scan through the list of record offsets and find the offset of
+		// the following record. This is done because although the talk
+		// records and responses are normally sequential, it can also
+		// point into another record's talk responses
+
+		nextOffset = 0;
+		for (subentryCtr = 0; subentryCtr < numTalks; ++subentryCtr) {
+			if ((responseOffset >= sortedList[subentryCtr]) &&
+				(responseOffset < sortedList[subentryCtr+1])) {
+				// Found a record				
+				nextOffset = sortedList[subentryCtr+1];
+				break;
+			}
+		}
+		if (nextOffset < responseOffset) {
+			printf("Failure reading talk data\n");
+			exit(1);
+		}
+		
+		size = nextOffset - responseOffset;
+		if ((size % 6) != 0) size -= (size % 6);
+
+		if ((size % 6) != 0) {
+			printf("Failure reading talk data\n");
+			exit(1);
+		}
+
+		lure_exe.read(data + offset, size);
+		offset += size;
+		WRITE_LE_UINT16(data + offset, 0xffff);
+		offset += 2;
+
+		++header;
+	}
+
+	header->recordId = TO_LE_16(0xffff);
+	totalSize = offset;
+	free(sortedList);
+}
+
+void read_room_pathfinding_data(byte *&data, uint16 &totalSize) {
+	lure_exe.seek(DATA_SEGMENT + PATHFIND_OFFSET);
+	
+	totalSize = PATHFIND_SIZE;
+	data = (byte *) malloc(totalSize);
+	lure_exe.read(data, totalSize);
+}
+
+void read_room_exit_coordinate_data(byte *&data, uint16 &totalSize) 
+{
+	// Read in the exit coordinates list	
+	int roomNum, entryNum;
+
+	totalSize = EXIT_COORDINATES_NUM_ROOMS * sizeof(RoomExitCoordinateEntryResource) + 2; 
+	data = (byte *) malloc(totalSize);
+	lure_exe.seek(DATA_SEGMENT + EXIT_COORDINATES_OFFSET);
+	lure_exe.read(data, totalSize - 2);
+	WRITE_LE_UINT16(data + totalSize - 2, 0xffff);
+
+	// Post process the list to adjust data
+	RoomExitCoordinateEntryResource *rec = (RoomExitCoordinateEntryResource *) data;
+	for (roomNum = 0; roomNum < EXIT_COORDINATES_NUM_ROOMS; ++roomNum, ++rec) {
+		for (entryNum = 0; entryNum < ROOM_EXIT_COORDINATES_NUM_ENTRIES; ++entryNum) {
+			if ((rec->entries[entryNum].x != 0) || (rec->entries[entryNum].y != 0)) {
+				rec->entries[entryNum].x = TO_LE_16(FROM_LE_16(rec->entries[entryNum].x) - 0x80);
+				uint16 tempY = FROM_LE_16(rec->entries[entryNum].y);
+				rec->entries[entryNum].y = TO_LE_16(
+					((tempY & 0xfff) - 0x80) | (tempY & 0xf000));
+			}
+		}
+
+		for (entryNum = 0; entryNum < ROOM_EXIT_COORDINATES_ENTRY_NUM_ROOMS; ++entryNum) {
+			rec->roomIndex[entryNum] = TO_LE_16(FROM_LE_16(rec->roomIndex[entryNum]) / 6);
+		}
+	}
+}
+
+void read_room_exit_hotspots_data(byte *&data, uint16 &totalSize) {
+	totalSize = 0;
+	data = (byte *) malloc(MAX_DATA_SIZE);
+
+	RoomExitIndexedHotspotResource *rec = (RoomExitIndexedHotspotResource *) data;
+	lure_exe.seek(DATA_SEGMENT + EXIT_HOTSPOTS_OFFSET);
+
+	lure_exe.read(rec, sizeof(RoomExitIndexedHotspotResource));
+	while (FROM_LE_16(rec->roomNumber) != 0) {
+		++rec;
+		totalSize += sizeof(RoomExitIndexedHotspotResource);
+		lure_exe.read(rec, sizeof(RoomExitIndexedHotspotResource));
+	}
+
+	WRITE_LE_UINT16(rec, 0xffff);
+	totalSize += sizeof(uint16);
+}
+
+void getEntry(uint8 entryIndex, uint16 &resourceId, byte *&data, uint16 &size)
+{
+	resourceId = 0x3f01 + entryIndex;
+
+	switch (entryIndex) 
+	{
+	case 0:
+		// Copy the default palette to file
+		read_basic_palette(data, size);
+		break;
+
+	case 1:
+		// Copy the replacement palette fragments to file
+		read_replacement_palette(data, size);
+		break;
+
+	case 2:
+		// Copy the dialog segment data into the new vga file
+		read_dialog_data(data, size);
+		break;
+
+	case 3:
+		// Copy the talk dialog segment data into the new vga file
+		read_talk_dialog_data(data, size);
+		break;
+
+	case 4:
+		// Get the room info data
+		read_room_data(data, size);
+		break;
+
+	case 5:
+		// Get the action sequence set for NPC characters
+		read_action_sequence(data, size);
+		break;
+
+	case 6:
+		// Get the hotspot info data
+		read_hotspot_data(data, size);
+		break;
+
+	case 7:
+		// Get the hotspot override info data
+		read_hotspot_override_data(data, size);
+		break;
+
+	case 8:
+		// Get the list of room exits
+		read_room_exits(data, size);
+		break;
+
+	case 9:
+		// Get the list of room exit joins
+		read_room_exit_joins(data, size);
+		break;
+
+	case 10:
+		// Get the hotspot animation record data
+		read_anim_data(data, size);
+		break;
+
+	case 11:
+		// Get the script segment data
+		read_script_data(data, size);
+		break;
+
+	case 12:
+		// Get the second script segment data
+		read_script2_data(data, size);
+		break;
+
+	case 13:
+		// Get a list of hotspot script offsets
+		read_hotspot_script_offsets(data, size);
+		break;
+
+	case 14:
+		// Get the messages segment 
+		read_messages_segment(data, size);
+		break;
+
+	case 15:
+		// Get the actions list
+		read_actions_list(data, size);
+		break;
+
+	case 16:
+		// Get the talk header information
+		read_talk_headers(data, size);
+		break;
+
+	case 17:
+		// Get the talk data
+		read_talk_data(data, size);
+		break;
+
+	case 18:
+		// Get the pathfinding data
+		read_room_pathfinding_data(data, size);
+		break;
+
+	case 19:
+		// Get the room exit coordinate list
+		read_room_exit_coordinate_data(data, size);
+		break;
+
+	case 20:
+		// Read the room exit hotspot list
+		read_room_exit_hotspots_data(data, size);
+		break;
+
+	default:
+		data = NULL;
+		size = 0;
+		resourceId = 0xffff;
+		break;
+	}
+}
+
+void createFile(const char *outFilename)
+{
+	FileEntry rec;
+	uint32 startOffset, numBytes;
+	uint16 resourceId;
+	uint16 resourceSize;
+	byte *resourceData;
+	bool resourceFlag;
+	byte tempBuffer[32];
+
+	File f;
+	f.open(outFilename, kFileWriteMode);
+	memset(tempBuffer, 0, 32);
+
+	// Write header
+	f.write("heywow", 6);
+	f.writeWord(0);
+
+	startOffset = 0x600;
+	resourceFlag = true;
+	for (int resIndex=0; resIndex<0xBE; ++resIndex)
+	{
+		resourceData = NULL;
+
+		// Get next data entry
+		if (resourceFlag)
+			// Get resource details
+			getEntry(resIndex, resourceId, resourceData, resourceSize); 
+
+		// Write out the next header entry
+		f.seek(8 + resIndex * 8);
+		if (resourceSize == 0) 
+		{
+			// Unused entry
+			memset(&rec, 0xff, sizeof(FileEntry));
+			resourceFlag = false;
+		}
+		else
+		{
+			rec.id = TO_LE_16(resourceId);
+			rec.offset = TO_LE_16(startOffset >> 5);
+			rec.sizeExtension = (uint8) ((resourceSize >> 16) & 0xff);
+			rec.size = TO_LE_16(resourceSize & 0xffff);
+			rec.unused = 0xff;
+		}
+
+		f.write(&rec, sizeof(FileEntry));
+
+		// Write out the resource
+		if (resourceFlag)
+		{
+			f.seek(startOffset);
+			f.write(resourceData, resourceSize);
+			startOffset += resourceSize;
+			free(resourceData);		// Free the data block
+
+			// Write out enough bytes to move to the next 32 byte boundary
+			numBytes = 0x20 * ((startOffset + 0x1f) / 0x20) - startOffset;
+			if (numBytes != 0) 
+			{
+				f.write(tempBuffer, numBytes);
+				startOffset += numBytes;
+			}
+		}
+	}
+
+	// Store file version in final file slot
+	f.seek(0xBF * 8);
+	FileEntry fileVersion;
+	memset(&fileVersion, 0xff, sizeof(FileEntry));
+	fileVersion.unused = VERSION_MAJOR;
+	fileVersion.sizeExtension = VERSION_MINOR;
+	f.write(&fileVersion, sizeof(FileEntry));
+
+	f.close();
+}
+
+// validate_executable
+// Validates that the correct executable is being used to generate the
+// resource file. Eventually the resource file creator will need to work
+// with the other language executables, but for now just make 
+
+#define NUM_BYTES_VALIDATE 1024
+#define FILE_CHECKSUM 64880
+
+void validate_executable() {
+	uint32 sumTotal = 0;
+	byte buffer[NUM_BYTES_VALIDATE];
+	lure_exe.read(buffer, NUM_BYTES_VALIDATE);
+	for (int ctr = 0; ctr < NUM_BYTES_VALIDATE; ++ctr) 
+		sumTotal += buffer[ctr];
+
+	if (sumTotal != FILE_CHECKSUM) {
+		printf("Lure executable not correct English version\n");
+		exit(1);
+	}
+}
+
+
+int main(int argc, char *argv[])
+{
+	const char *inFilename = (argc >= 2) ? argv[1] : "f:\\games\\lure\\lure.exe";
+	const char *outFilename = (argc == 3) ? argv[2] : "f:\\games\\lure\\lure.dat";
+
+	if (!lure_exe.open(inFilename))
+	{
+		if (argc == 1) 
+			printf("Format: %s input_exe_filename output_filename\n");
+		else
+			printf("Could not open file: %s\n", inFilename);
+	} 
+	else 
+	{
+		validate_executable();
+		createFile(outFilename);	
+		lure_exe.close();
+	}
+}


Property changes on: scummvm/trunk/tools/create_lure/create_lure_dat.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + Date Rev Author URL Id
Name: svn:eol-style
   + native

Added: scummvm/trunk/tools/create_lure/create_lure_dat.h
===================================================================
--- scummvm/trunk/tools/create_lure/create_lure_dat.h	                        (rev 0)
+++ scummvm/trunk/tools/create_lure/create_lure_dat.h	2006-07-23 13:08:22 UTC (rev 23578)
@@ -0,0 +1,401 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * 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$
+ *
+ */
+
+#ifndef __createlure_dat__
+#define __createlure_dat__
+
+#include "common/stdafx.h"
+#include "common/endian.h"
+
+#define VERSION_MAJOR 1
+#define VERSION_MINOR 10
+#define ENGLISH_LURE 
+
+#define DATA_SEGMENT 0xac50
+
+#define DIALOG_OFFSET 0x1dcb0
+#define DIALOG_SIZE 0x150
+
+#define TALK_DIALOG_OFFSET 0x1de00
+#define TALK_DIALOG_SIZE 0x30
+
+#define PALETTE_OFFSET 0xc0a7
+#define PALETTE_SIZE 0x300
+
+#define ROOM_TABLE 0xbf40
+#define ROOM_NUM_ENTRIES 51
+
+#define HOTSPOT_OVERRIDE_OFFSET 0x2A01
+
+#define SCRIPT_SEGMENT 0x1df00
+#define SCRIPT_SEGMENT_SIZE 0x2c57
+#define SCRIPT2_SEGMENT 0x19c70
+#define SCRIPT2_SEGMENT_SIZE 0x2800
+
+#define HOTSPOT_SCRIPT_LIST 0x57e0
+#define HOTSPOT_SCRIPT_SIZE 0x30
+
+#define MAX_NUM_ANIM_RECORDS 0x200
+#define MAX_NUM_ACTION_RECORDS 0x100
+
+#define ROOM_EXITS_OFFSET 0x2f61
+#define NUM_ROOM_EXITS 50
+#define ROOM_EXIT_JOINS_OFFSET 0xce30
+
+#define MESSAGES_SEGMENT 0x20b60
+#define MESSAGES_SEGMENT_SIZE 0x490
+
+#define MAX_HOTSPOTS 0x100
+#define MAX_DATA_SIZE 0x4000
+
+#define PATHFIND_OFFSET 0x984A
+#define PATHFIND_SIZE (120 * ROOM_NUM_ENTRIES) 
+
+#define HOTSPOT_WALK_TO_OFFSET 0xBC4B
+#define EXIT_COORDINATES_OFFSET 0x1929
+#define EXIT_COORDINATES_NUM_ROOMS 49
+
+#define TABLED_ACTIONS_OFFSET 0x1380
+#define NUM_TABLED_ACTION_BLOCKS 18
+
+#define WALK_AREAS_OFFSET 0x2EB1
+
+#define EXIT_HOTSPOTS_OFFSET 0x2E57
+
+#pragma pack(1)
+
+// Rect currently copied from common/rect.h - if I try directly including it,
+// the link complains about an unresolved external token Common.String.__dtor
+
+struct Rect {
+	int16 top, left;		//!< The point at the top left of the rectangle (part of the rect).
+	int16 bottom, right;	//!< The point at the bottom right of the rectangle (not part of the rect).
+};
+
+struct FileEntry {
+	uint16 id;
+	byte unused;
+	byte sizeExtension;
+	uint16 size;
+	uint16 offset;
+};
+
+struct RoomHeaderEntry {
+	uint16 offset;
+	uint16 roomNumber;
+	uint16 descId;
+	byte unused[3];
+};
+
+struct HotspotHeaderEntry {
+	uint16 offset;
+	uint16 resourceId;
+	uint16 descId, descId2;
+	byte hdrFlags;
+};
+
+struct HotspotResource {
+	uint32 actions;
+	uint16 actionsOffset;
+	uint16 roomNumber;
+	byte scriptLoadFlag;
+	uint16 loadOffset;
+	uint16 unused;
+	uint16 startX;
+	uint16 startY;
+	uint16 width;
+	uint16 height;
+	byte layer;
+	byte flags;
+	uint16 tickProcOffset;
+	uint16 widthCopy;
+	uint16 heightCopy;
+	uint16 yCorrection;
+	uint16 tickTimeout;
+	uint16 animOffset;
+	byte colourOffset;
+	uint16 sequenceOffset;
+	byte unknown4[15];
+	int8 talkX;
+	int8 talkY;
+	byte unused5[11];
+	uint16 delayCtr;
+	uint8 characterMode;
+	uint16 tickSequenceOffset;
+};
+
+struct CurrentActionInput {
+	uint8 action;
+	uint16 dataOffset;
+	uint16 roomNumber;
+};
+
+struct HotspotResourceOutput {
+	uint16 hotspotId;
+	uint16 nameId;
+	uint16 descId;
+	uint16 descId2;
+	uint32 actions;
+	uint16 actionsOffset;
+	uint16 roomNumber;
+	byte layer;
+	byte scriptLoadFlag;
+	uint16 loadOffset;
+	uint16 startX;
+	uint16 startY;
+	uint16 width;
+	uint16 height;
+	uint16 widthCopy;
+	uint16 heightCopy;
+	uint16 yCorrection;
+	int16 walkX;
+	uint16 walkY;
+	int8 talkX;
+	int8 talkY;
+	uint16 colourOffset;
+	uint16 animRecordId;
+	uint16 sequenceOffset;
+	uint16 tickProcOffset;
+	uint16 tickTimeout;
+	uint16 tickSequenceOffset;
+	uint16 npcSchedule;
+	uint16 characterMode;
+	uint16 delayCtr;
+	byte flags;
+	byte hdrFlags;
+};
+
+struct RoomResource {
+	byte unknown1[6];
+	uint16 pixelListOffset;
+	byte numLayers;
+	uint16 layers[4];
+	uint16 sequenceOffset;
+	byte unknown3[5];
+	uint8 walkBoundsIndex;
+	int16 clippingXStart;
+	int16 clippingXEnd;
+};
+
+struct RoomRectIn {
+	uint16 xs, xe;
+	uint16 ys, ye;
+};
+
+struct RoomRectOut {
+	int16 xs, xe;
+	int16 ys, ye;
+};
+
+struct RoomResourceOutput {
+	uint16 roomNumber;
+	uint16 descId;
+	uint16 numLayers;
+	uint16 layers[4];
+	uint16 sequenceOffset;
+	int16 clippingXStart;
+	int16 clippingXEnd;
+	RoomRectOut walkBounds;
+	uint16 numExits;
+};
+
+struct RoomResourceExit1 {
+	int16 xs, xe, ys, ye;
+	uint16 sequenceOffset;
+};
+
+struct RoomResourceExit2 {
+	uint8 newRoom;
+	uint8 direction;
+	int16 newRoomX, newRoomY;
+};
+
+struct HotspotOverride {
+	uint16 hotspotId;
+	uint16 xs, xe, ys, ye;
+};
+
+struct AnimRecord {
+	uint16 animId;
+	uint8 flags;
+	uint8 unused[6];
+	uint16 upOffset;
+	uint16 downOffset;
+	uint16 leftOffset;
+	uint16 rightOffset;
+	uint8 upFrame;
+	uint8 downFrame;
+	uint8 leftFrame;
+	uint8 rightFrame;
+};
+
+struct AnimRecordOutput {
+	uint16 animRecordId;
+	uint16 animId;
+	uint16 flags;
+	uint16 upOffset;
+	uint16 downOffset;
+	uint16 leftOffset;
+	uint16 rightOffset;
+	uint8 upFrame;
+	uint8 downFrame;
+	uint8 leftFrame;
+	uint8 rightFrame;
+};
+
+struct MovementRecord {
+	uint16 frameNumber;
+	int16 xChange;
+	int16 yChange;
+};
+
+struct RoomExitHotspotRecord {
+	int16 xs, xe;
+	int16 ys, ye;
+	uint16 cursorNum;
+	uint16 hotspotId;
+	uint16 destRoomNumber;
+};
+
+struct RoomExitHotspotOutputRecord {
+	uint16 hotspotId;
+	int16 xs, xe;
+	int16 ys, ye;
+	uint16 cursorNum;
+	uint16 destRoomNumber;
+};
+
+struct RoomExitHotspotJoinRecord {
+	uint16 hotspot1Id;
+	byte h1CurrentFrame;
+	byte h1DestFrame;
+	byte h1OpenSound;
+	byte h1CloseSound;
+	uint16 hotspot2Id;
+	byte h2CurrentFrame;
+	byte h2DestFrame;
+	byte h2OpenSound;
+	byte h2CloseSound;
+	byte blocked;
+};
+
+struct HotspotActionSequenceRecord {
+	byte actionNumber;
+	uint16 sequenceOffset;
+};
+
+struct HotspotActionsRecord {
+	uint16 recordId;
+	uint16 offset;
+};
+
+struct RoomExitCoordinateResource {
+	int16 x;
+	int16 y;
+	uint16 roomNumber;
+};
+
+struct HotspotWalkToRecord {
+	uint16 hotspotId;
+	int16 x;
+	uint16 y;
+};
+
+struct RoomExitIndexedHotspotResource {
+	uint8 roomNumber;
+	uint8 hotspotIndex;
+	uint16 hotspotId;
+};
+
+
+#define ROOM_EXIT_COORDINATES_NUM_ENTRIES 6
+#define ROOM_EXIT_COORDINATES_ENTRY_NUM_ROOMS 52
+
+struct RoomExitCoordinateEntryResource {
+	RoomExitCoordinateResource entries[ROOM_EXIT_COORDINATES_NUM_ENTRIES];
+	uint8 roomIndex[ROOM_EXIT_COORDINATES_ENTRY_NUM_ROOMS];
+};
+
+enum CurrentAction {NO_ACTION, START_WALKING, DISPATCH_ACTION, EXEC_HOTSPOT_SCRIPT, 
+	PROCESSING_PATH, WALKING};
+
+extern void read_action_sequence(byte *&data, uint16 &totalSize);
+
+extern uint16 get_sequence_index(uint16 offset, int supportIndex = -1);
+
+enum AccessMode {
+	kFileReadMode = 1,
+	kFileWriteMode = 2
+};
+
+class File {
+private:
+	FILE *f;
+public:
+	bool open(const char *filename, AccessMode mode = kFileReadMode) {
+		f = fopen(filename, (mode == kFileReadMode) ? "rb" : "wb");
+		return (f != NULL);
+	}
+	void close() {
+		fclose(f);
+		f = NULL;
+	}
+	int seek(int32 offset, int whence = SEEK_SET) {
+		return fseek(f, offset, whence);
+	}
+	long read(void *buffer, int len) {
+		return fread(buffer, 1, len, f);
+	}
+	void write(const void *buffer, int len) {
+		fwrite(buffer, 1, len, f);
+	}
+	byte readByte() { 
+		byte v;
+		read(&v, sizeof(byte));
+		return v;
+	}
+	uint16 readWord() {
+		uint16 v;
+		read(&v, sizeof(uint16));
+		return FROM_LE_16(v);
+	}
+	uint16 readLong() {
+		uint32 v;
+		read(&v, sizeof(uint32));
+		return FROM_LE_32(v);
+	}
+	void writeByte(byte v) { 
+		write(&v, sizeof(byte));
+	}
+	void writeWord(uint16 v) { 
+		uint16 vTemp = TO_LE_16(v);
+		write(&vTemp, sizeof(uint16));
+	}
+	void writeLong(uint32 v) { 
+		uint32 vTemp = TO_LE_32(v);
+		write(&vTemp, sizeof(uint32));
+	}
+};
+
+extern File lure_exe;
+
+#endif


Property changes on: scummvm/trunk/tools/create_lure/create_lure_dat.h
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + Date Rev Author URL Id
Name: svn:eol-style
   + native

Added: scummvm/trunk/tools/create_lure/process_actions.cpp
===================================================================
--- scummvm/trunk/tools/create_lure/process_actions.cpp	                        (rev 0)
+++ scummvm/trunk/tools/create_lure/process_actions.cpp	2006-07-23 13:08:22 UTC (rev 23578)
@@ -0,0 +1,341 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * 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$
+ *
+ */
+
+#include "common/stdafx.h"
+#include "common/scummsys.h"
+#include "create_lure_dat.h"
+
+enum Action {
+	GET = 1, PUSH = 3, PULL = 4, OPERATE = 5, OPEN = 6,	CLOSE = 7, LOCK = 8,
+	UNLOCK = 9,	USE = 10, GIVE = 11, TALK_TO = 12, TELL = 13, BUY = 14,
+	LOOK = 15, LOOK_AT = 16, LOOK_THROUGH = 17,	ASK = 18, DRINK = 20,
+	STATUS = 21, GO_TO = 22, RETURN = 23, BRIBE = 24, EXAMINE = 25,
+	NPC_SET_ROOM_AND_BLOCKED_OFFSET = 28, NPC_UNKNOWN1 = 29, NPC_EXEC_SCRIPT = 30, 
+	NPC_UNKNOWN2 = 31, NPC_SET_RAND_DEST = 32, NPC_WALKING_CHECK = 33, 
+	NPC_SET_SUPPORT_OFFSET = 34, NPC_SUPPORT_OFFSET_COND = 35, 
+	NPC_DISPATCH_ACTION = 36, NPC_UNKNOWN3 = 37, NPC_UNKNOWN4 = 38, 
+	NPC_START_TALKING = 39, NPC_JUMP_ADDRESS = 40,
+	NONE = 0
+};
+
+struct CurrentActionOutput {
+	uint8 action;
+	uint8 hsAction;
+	uint16 roomNumber;
+	uint16 hotspotId;
+	uint16 usedId;
+};
+
+int numParams[NPC_JUMP_ADDRESS+1] = {0, 
+	1, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2, 0, 1,
+	0, 1, 1, 1, 1, 0, 0, 2, 0, 1, 0, 0, 1, 1, 2, 2, 5, 2, 2, 1};
+
+#ifdef ENGLISH_LURE
+#define NUM_JUMP_OFFSETS 2
+uint16 jumpOffsets[2] = {0x87be, 0x881c};
+#endif
+
+#define MAX_BUFFER_ENTRIES 50
+#define MAX_INSTRUCTION_ENTRIES 300
+#define SCHEDULE_DATA_OFFSET 0x60
+
+struct SupportStructure {
+	uint16 offset;
+	int numInstructions;
+	uint16 instructionOffsets[MAX_INSTRUCTION_ENTRIES];	
+	uint16 resourceOffset;
+};
+
+SupportStructure supportList[MAX_BUFFER_ENTRIES];
+uint16 numSupportEntries = 0;
+
+#define FORWARD_JUMP_ALLOWANCE 0x30
+
+
+uint16 get_sequence_index(uint16 offset, int supportIndex) {
+	int index;
+
+	if (supportIndex != -1) {
+		// Within a sequence, so if an offset is within it, it's a local jump
+		for (index = 0; index < supportList[supportIndex].numInstructions; ++index) {
+			if (supportList[supportIndex].instructionOffsets[index] == offset)
+				return index;
+		}
+	}
+
+	for (int index = 0; index <= numSupportEntries; ++index) {
+		SupportStructure &rec = supportList[index];
+
+		if ((rec.numInstructions > 0) &&
+			(offset >= rec.instructionOffsets[0]) && 
+			(offset <= rec.instructionOffsets[rec.numInstructions - 1])) {
+			// Scan through the entry's insruction list
+			for (int iIndex = 0; iIndex < rec.numInstructions; ++iIndex) {
+				if (rec.instructionOffsets[iIndex] == offset) {
+					return ((index + 1) << 10) | iIndex;
+				}
+			}
+		}
+	}
+
+	return 0xffff;
+}
+
+struct SymbolTableEntry {
+	uint16 *p;
+	bool globalNeeded;
+};
+
+uint16 process_action_sequence_entry(int supportIndex, byte *data, uint16 remainingSize) {
+	SupportStructure &rec = supportList[supportIndex];
+	uint16 startOffset = rec.offset;
+	uint16 maxOffset = 0;
+#ifdef ENGLISH_LURE
+	if (startOffset == 0x7dcb) { startOffset = 0x7d9d; maxOffset = 0x7dcb; }
+	if (startOffset == 0x7248) { startOffset = 0x71ce; maxOffset = 0x7248; }
+	if (startOffset == 0x79a8) { startOffset = 0x785c; maxOffset = 0x79a8; }
+	if (startOffset == 0x6f4f) { startOffset = 0x6e5d; maxOffset = 0x6fe5; }
+	if (startOffset == 0x734a) maxOffset = 0x77a2;
+#endif
+
+	SymbolTableEntry symbolTable[MAX_INSTRUCTION_ENTRIES];
+	uint16 numSymbols = 0;
+	uint16 offset = startOffset;
+	uint16 totalSize = 0;
+	uint16 actionNum = 0;
+	uint16 paramIndex;
+	uint16 params[5];
+	uint16 index;
+	uint16 *pOut = (uint16 *) data;
+
+	lure_exe.seek(DATA_SEGMENT + startOffset);
+	rec.numInstructions = 0;
+
+	for (;;) {
+		if (remainingSize < 10) {
+			printf("Ran out of space to process NPC action sequences\n");
+			exit(1);
+		}
+
+		// Check for end of sequence set with prior instruction
+		if ((actionNum == NPC_SET_SUPPORT_OFFSET) && ((maxOffset == 0) ||
+			(offset > maxOffset)))
+			break;
+
+		// Mark the offset of the next instruction
+		rec.instructionOffsets[rec.numInstructions++] = offset;
+		if (rec.numInstructions == MAX_INSTRUCTION_ENTRIES) {
+			printf("A method exceeded the maximum allowable number of instructions\n");
+			exit(1);
+		}
+
+		// Get in the next action
+		actionNum = lure_exe.readWord();
+
+//		printf("%xh - action=%d", offset, actionNum);
+
+		if (actionNum == 0) {
+			// At end of script block
+//			printf("\n");
+			break;
+		}
+		else if (actionNum > NPC_JUMP_ADDRESS) {
+			// Unknown action code - halt execution
+			printf("%xh - unknown action %d\n", offset, actionNum);
+			exit(1);
+		}
+
+		*pOut++ = TO_LE_16(actionNum);
+
+		// Read in any action parameters
+		for (int paramCtr = 0; paramCtr < numParams[actionNum]; ++paramCtr)
+			params[paramCtr] = lure_exe.readWord();
+
+		switch(actionNum) {
+		case NPC_SET_ROOM_AND_BLOCKED_OFFSET:
+		case NPC_SET_SUPPORT_OFFSET:
+		case NPC_SUPPORT_OFFSET_COND:
+		case NPC_DISPATCH_ACTION:
+			// These instructions have a support record parameter. Store the
+			// offset the parameter will be in the output data so we can come
+			// back at the end and resolve it
+			paramIndex = (actionNum == NPC_SET_SUPPORT_OFFSET) ? 0 : 1;
+			symbolTable[numSymbols].globalNeeded = actionNum == NPC_SET_ROOM_AND_BLOCKED_OFFSET;
+			symbolTable[numSymbols].p = pOut + paramIndex;
+			++numSymbols;
+
+			// Special check for forward references - it's considered to be in
+			// the same block if it's forward within 100h blocks
+			if ((params[paramIndex] > offset) && 
+				(params[paramIndex] < offset + FORWARD_JUMP_ALLOWANCE) &&
+				(params[paramIndex] > maxOffset)) {
+				maxOffset = params[paramIndex];
+			} 
+			break;
+
+		case NPC_JUMP_ADDRESS:
+			// Make sure the address is in the known list
+			index = 0;
+			while ((index < NUM_JUMP_OFFSETS) && (jumpOffsets[index] != params[0]))
+				++index;
+			
+			if (index != NUM_JUMP_OFFSETS)
+				// Replace code offset with an index			
+				params[0] = index;
+			else {
+				printf("Encountered unrecognised NPC code jump point: %xh\n", params[0]);
+				exit(1);
+			}
+			break;
+
+		default:
+			break;
+		}
+
+		// Output parameters
+		for (paramIndex = 0; paramIndex < numParams[actionNum]; ++paramIndex)
+			*pOut++ = TO_LE_16(params[paramIndex]);
+
+		// Increase size
+		totalSize += (numParams[actionNum] + 1) * sizeof(uint16); 
+		offset = startOffset + totalSize;
+		remainingSize -= (numParams[actionNum] + 1) * sizeof(uint16);
+	}
+
+	// Flag an end of the sequence
+	*pOut++ = 0;
+	totalSize += sizeof(uint16);
+
+	// handle post-processing of the symbol list
+
+	for (int symbolCtr = 0; symbolCtr < numSymbols; ++symbolCtr) {
+		if (READ_LE_UINT16(symbolTable[symbolCtr].p) == 0) 
+			// No Id special constant
+			WRITE_LE_UINT16(symbolTable[symbolCtr].p, 0xffff);
+		else {
+			// Handle resolving the constant
+			index = get_sequence_index(READ_LE_UINT16(symbolTable[symbolCtr].p), 
+				symbolTable[symbolCtr].globalNeeded ? -1 : supportIndex);
+//printf("Symbol %xh => %xh\n", *symbolTable[symbolCtr].p, index);
+			if (index != 0xffff) {
+				// Jump found - so replace symbol entry with it 
+				WRITE_LE_UINT16(symbolTable[symbolCtr].p, index);
+			} else {
+				printf("Sequence contained unknown offset %xh\n", 
+					READ_LE_UINT16(symbolTable[symbolCtr].p));
+				exit(1);
+			}
+		}
+	}
+
+	return totalSize;
+}
+
+void process_entry(uint16 offset, byte *data, uint16 &totalSize) {
+	if (get_sequence_index(offset) == 0xffff) {
+		// Process the next entry
+		supportList[numSupportEntries].offset = offset;
+		supportList[numSupportEntries].numInstructions = 0;
+		supportList[numSupportEntries].resourceOffset = totalSize;
+//printf("process_entry index=%d, offset=%xh\n", numSupportEntries + 1, offset);
+		totalSize += process_action_sequence_entry(numSupportEntries, 
+			data + totalSize,  MAX_DATA_SIZE - totalSize);
+
+		++numSupportEntries;
+		if (numSupportEntries == MAX_BUFFER_ENTRIES) {
+			printf("Ran out of buffer space in processing NPC schedules\n");
+			exit(1);
+		}
+	}
+}
+
+void read_action_sequence(byte *&data, uint16 &totalSize) 
+{
+	const uint16 hsOffset = 0x5d98;
+	const uint16 hsStartId = 0x3e8;
+	uint16 hotspotIndex;
+	HotspotHeaderEntry entryHeader;
+	CurrentActionInput action;
+	uint16 *pHeader;
+	int index;
+
+	// Allocate enough space for output sequence list
+	data = (byte *) malloc(MAX_DATA_SIZE);
+
+	// Get a list of offsets used in the script engine
+	uint16 offsetList[NUM_TABLED_ACTION_BLOCKS];
+	lure_exe.seek(DATA_SEGMENT + TABLED_ACTIONS_OFFSET, SEEK_SET);
+	for (index = 0; index < NUM_TABLED_ACTION_BLOCKS; ++index)
+		offsetList[index] = lure_exe.readWord();
+
+	totalSize = SCHEDULE_DATA_OFFSET;
+	numSupportEntries = 0;
+
+	// Handle required initial entries - the Lure engine refers to them directly by
+	// index, so they need to be first, and in that order
+#ifdef ENGLISH_LURE
+	process_entry(0x13c2, data, totalSize);
+	process_entry(0xbb95, data, totalSize);
+	process_entry(0x7060, data, totalSize);
+	process_entry(0x728a, data, totalSize);
+#endif
+
+	// Process the script engine list 
+	
+	for (index = 0; index < NUM_TABLED_ACTION_BLOCKS; ++index) 
+		process_entry(offsetList[index], data, totalSize);
+
+	// Next process each of the character hotspots
+
+	hotspotIndex = 0;
+	for (;;) {
+		lure_exe.seek(DATA_SEGMENT + hsOffset + 
+			hotspotIndex * sizeof(HotspotHeaderEntry));
+		lure_exe.read(&entryHeader, sizeof(HotspotHeaderEntry));
+		if (FROM_LE_16(entryHeader.offset) == 0xffff) break;
+		++hotspotIndex;
+
+		// Move to the action sequence area of the hotspot
+		lure_exe.seek(DATA_SEGMENT + entryHeader.offset + 0x63);
+		lure_exe.read(&action, sizeof(CurrentActionInput));
+		if (FROM_LE_16(action.action) == 2) 
+			process_entry(FROM_LE_16(action.dataOffset), data, totalSize);
+	}
+
+	// Output the list used in the script engine
+
+	pHeader = (uint16 *) data;
+	for (index = 0; index < NUM_TABLED_ACTION_BLOCKS; ++index) 
+		*pHeader++ = TO_LE_16(get_sequence_index(offsetList[index]));
+	*pHeader++ = 0xffff;
+
+	// Output the offsets of each action set
+
+	for (index = 0; index < numSupportEntries; ++index) 
+		*pHeader++ = TO_LE_16(supportList[index].resourceOffset);
+	*pHeader++ = 0xffff;
+
+	if ((int) ((byte *) pHeader - data) > SCHEDULE_DATA_OFFSET) {
+		printf("SCHEDULE_DATA_OFFSET was not high enough\n");
+		exit(1);
+	}
+}	


Property changes on: scummvm/trunk/tools/create_lure/process_actions.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + Date Rev Author URL Id
Name: svn:eol-style
   + native


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.





More information about the Scummvm-git-logs mailing list