aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--saga/actionmap.cpp16
-rw-r--r--saga/actor.cpp318
-rw-r--r--saga/actor.h123
-rw-r--r--saga/animation.cpp162
-rw-r--r--saga/animation.h13
-rw-r--r--saga/events.cpp68
-rw-r--r--saga/events.h7
-rw-r--r--saga/font.cpp29
-rw-r--r--saga/game.cpp64
-rw-r--r--saga/game.h4
-rw-r--r--saga/game_mod.h15
-rw-r--r--saga/ihnm_introproc.cpp1
-rw-r--r--saga/image.cpp11
-rw-r--r--saga/isomap.cpp29
-rw-r--r--saga/ite_introproc.cpp2
-rw-r--r--saga/list.h154
-rw-r--r--saga/music.cpp21
-rw-r--r--saga/objectmap.cpp20
-rw-r--r--saga/palanim.cpp9
-rw-r--r--saga/resnames.h2
-rw-r--r--saga/rscfile.cpp32
-rw-r--r--saga/rscfile_mod.h1
-rw-r--r--saga/saga.h1
-rw-r--r--saga/scene.cpp120
-rw-r--r--saga/scene.h11
-rw-r--r--saga/script.cpp47
-rw-r--r--saga/script.h10
-rw-r--r--saga/sdebug.cpp24
-rw-r--r--saga/sndres.cpp23
-rw-r--r--saga/sprite.cpp20
-rw-r--r--saga/sthread.cpp67
-rw-r--r--saga/stream.h56
-rw-r--r--saga/text.cpp49
-rw-r--r--saga/text.h10
-rw-r--r--saga/ys_dl_list.cpp239
-rw-r--r--saga/yslib.h90
36 files changed, 921 insertions, 947 deletions
diff --git a/saga/actionmap.cpp b/saga/actionmap.cpp
index e6d467dce9..e3d988c3a0 100644
--- a/saga/actionmap.cpp
+++ b/saga/actionmap.cpp
@@ -28,6 +28,8 @@
#include "saga/console.h"
#include "saga/actionmap.h"
+#include "saga/game_mod.h"
+#include "saga/stream.h"
namespace Saga {
@@ -39,10 +41,10 @@ ActionMap::ActionMap(SagaEngine *vm, const byte * exmap_res, size_t exmap_res_le
assert(exmap_res != NULL);
- MemoryReadStream readS(exmap_res, exmap_res_len);
+ MemoryReadStreamEndian readS(exmap_res, exmap_res_len, IS_BIG_ENDIAN);
// Load exits
- _nExits = readS.readSint16LE();
+ _nExits = readS.readSint16();
if (_nExits < 0) {
return;
}
@@ -59,8 +61,8 @@ ActionMap::ActionMap(SagaEngine *vm, const byte * exmap_res, size_t exmap_res_le
exmap_entry->nClickareas = readS.readByte();
exmap_entry->defaultVerb = readS.readByte();
readS.readByte();
- exmap_entry->exitScene = readS.readUint16LE();
- exmap_entry->entranceNum = readS.readUint16LE();
+ exmap_entry->exitScene = readS.readUint16();
+ exmap_entry->entranceNum = readS.readUint16();
exmap_entry->clickareas = (CLICKAREA *)malloc(exmap_entry->nClickareas * sizeof *(exmap_entry->clickareas));
@@ -72,7 +74,7 @@ ActionMap::ActionMap(SagaEngine *vm, const byte * exmap_res, size_t exmap_res_le
// Load all clickareas for this object
for (int k = 0; k < exmap_entry->nClickareas; k++) {
clickarea = &exmap_entry->clickareas[k];
- clickarea->n_points = readS.readUint16LE();
+ clickarea->n_points = readS.readUint16();
assert(clickarea->n_points != 0);
clickarea->points = (Point *)malloc(clickarea->n_points * sizeof *(clickarea->points));
@@ -84,8 +86,8 @@ ActionMap::ActionMap(SagaEngine *vm, const byte * exmap_res, size_t exmap_res_le
// Load all points for this clickarea
for (int m = 0; m < clickarea->n_points; m++) {
point = &clickarea->points[m];
- point->x = readS.readSint16LE();
- point->y = readS.readSint16LE();
+ point->x = readS.readSint16();
+ point->y = readS.readSint16();
}
}
}
diff --git a/saga/actor.cpp b/saga/actor.cpp
index 4e1d9e2d63..860f011be6 100644
--- a/saga/actor.cpp
+++ b/saga/actor.cpp
@@ -22,7 +22,6 @@
*/
#include "saga/saga.h"
-#include "saga/yslib.h"
#include "saga/gfx.h"
#include "saga/game_mod.h"
@@ -39,10 +38,20 @@
#include "saga/actor.h"
#include "saga/actordata.h"
+#include "saga/stream.h"
namespace Saga {
-static int zCompare(const void *elem1, const void *elem2);
+static int actorCompare(const ACTOR& actor1, const ACTOR& actor2) {
+ if (actor1.a_pt.y == actor2.a_pt.y) {
+ return 0;
+ } else if (actor1.a_pt.y < actor2.a_pt.y) {
+ return -1;
+ } else {
+ return 1;
+ }
+}
+static ActorList::iterator zeroActorIterator;
ACTIONTIMES ActionTDeltas[] = {
{ ACTION_IDLE, 80 },
@@ -59,33 +68,12 @@ Actor::Actor(SagaEngine *vm) : _vm(vm), _initialized(false) {
error("Actor::Actor(): Couldn't load actor module resource context.");
}
- // Create actor lookup table
- _tbl = (YS_DL_NODE **)malloc(ACTORCOUNT * sizeof(*_tbl));
- if (_tbl == NULL) {
- error("Actor::Actor(): Memory allocation error.");
- return;
- }
-
- for (i = 0; i < ACTORCOUNT; i++) {
- _tbl[i] = NULL;
- }
-
- // Create actor alias table
- _aliasTbl = (int *)malloc(ACTORCOUNT * sizeof(*_aliasTbl));
- if (_aliasTbl == NULL) {
- free(_tbl);
- error("Actor::Actor(): Memory allocation error.");
- return;
- }
// Initialize alias table so each index contains itself
for (i = 0; i < ACTORCOUNT; i++) {
_aliasTbl[i] = i;
}
- // Create actor list
- _list = ys_dll_create();
-
_count = 0;
_initialized = true;
}
@@ -94,29 +82,26 @@ Actor::~Actor() {
if (!_initialized) {
return;
}
-
- if (_tbl) {
- free(_tbl);
- }
}
int Actor::direct(int msec) {
- YS_DL_NODE *walk_p;
+ ActorList::iterator actorIterator;
ACTOR *actor;
- YS_DL_NODE *a_inode;
+ ActorIntentList::iterator actorIntentIterator;
ACTORINTENT *a_intent;
int o_idx;
int action_tdelta;
// Walk down the actor list and direct each actor
- for (walk_p = ys_dll_head(_list); walk_p != NULL; walk_p = ys_dll_next(walk_p)) {
- actor = (ACTOR *)ys_dll_get_data(walk_p);
+ for (actorIterator = _list.begin(); actorIterator != _list.end(); ++actorIterator) {
+ actor = actorIterator.operator->();
+
// Process the actor intent list
- a_inode = ys_dll_head(actor->a_intentlist);
- if (a_inode != NULL) {
- a_intent = (ACTORINTENT *)ys_dll_get_data(a_inode);
+ actorIntentIterator = actor->a_intentlist.begin();
+ if (actorIntentIterator != actor->a_intentlist.end()) {
+ a_intent = actorIntentIterator.operator->();
switch (a_intent->a_itype) {
case INTENT_NONE:
// Actor doesn't really feel like doing anything at all
@@ -144,8 +129,8 @@ int Actor::direct(int msec) {
// If this actor intent was flagged as completed, remove it.
if (a_intent->a_idone) {
- free(a_intent->a_data);
- ys_dll_delete(a_inode);
+ a_intent->deleteData();
+ actor->a_intentlist.erase(actorIntentIterator);
actor->action = actor->def_action;
actor->action_flags = actor->def_action_flags;
actor->action_frame = 0;
@@ -183,14 +168,14 @@ int Actor::direct(int msec) {
}
int Actor::drawList() {
- YS_DL_NODE *walk_p;
+ ActorList::iterator actorIterator;
ACTOR *actor;
- YS_DL_NODE *a_inode;
+ ActorIntentList::iterator actorIntentIterator;
ACTORINTENT *a_intent;
SPEAKINTENT *a_speakint;
- YS_DL_NODE *a_dnode;
+ ActorDialogList::iterator actorDialogIterator;
ACTORDIALOGUE *a_dialogue;
int o_idx; //Orientation index
@@ -202,8 +187,8 @@ int Actor::drawList() {
back_buf = _vm->_gfx->getBackBuffer();
- for (walk_p = ys_dll_head(_list); walk_p != NULL; walk_p = ys_dll_next(walk_p)) {
- actor = (ACTOR *)ys_dll_get_data(walk_p);
+ for (actorIterator = _list.begin(); actorIterator != _list.end(); ++actorIterator) {
+ actor = actorIterator.operator->();
o_idx = ActorOrientationLUT[actor->orient];
sprite_num = actor->act_tbl[actor->action].dir[o_idx].frame_index;
sprite_num += actor->action_frame;
@@ -211,14 +196,14 @@ int Actor::drawList() {
// If actor's current intent is to speak, oblige him by
// displaying his dialogue
- a_inode = ys_dll_head(actor->a_intentlist);
- if (a_inode != NULL) {
- a_intent = (ACTORINTENT *)ys_dll_get_data(a_inode);
+ actorIntentIterator = actor->a_intentlist.begin();
+ if (actorIntentIterator != actor->a_intentlist.end()) {
+ a_intent = actorIntentIterator.operator->();
if (a_intent->a_itype == INTENT_SPEAK) {
a_speakint = (SPEAKINTENT *)a_intent->a_data;
- a_dnode = ys_dll_head(a_speakint->si_diaglist);
- if (a_dnode != NULL) {
- a_dialogue = (ACTORDIALOGUE *)ys_dll_get_data(a_dnode);
+ actorDialogIterator = a_speakint->si_diaglist.begin();
+ if (actorDialogIterator != a_speakint->si_diaglist.end()) {
+ a_dialogue = actorDialogIterator.operator->();
diag_x = actor->s_pt.x;
diag_y = actor->s_pt.y;
diag_y -= ACTOR_DIALOGUE_HEIGHT;
@@ -237,37 +222,37 @@ int Actor::drawList() {
// dialogue entry if there is a current speak intent present.
int Actor::skipDialogue() {
- YS_DL_NODE *walk_p;
+ ActorList::iterator actorIterator;
ACTOR *actor;
- YS_DL_NODE *a_inode;
+ ActorIntentList::iterator actorIntentIterator;
ACTORINTENT *a_intent;
SPEAKINTENT *a_speakint;
- YS_DL_NODE *a_dnode;
+ ActorDialogList::iterator actorDialogIterator;
ACTORDIALOGUE *a_dialogue;
if (!_initialized) {
return FAILURE;
}
- for (walk_p = ys_dll_head(_list); walk_p != NULL; walk_p = ys_dll_next(walk_p)) {
- actor = (ACTOR *)ys_dll_get_data(walk_p);
+ for (actorIterator = _list.begin(); actorIterator != _list.end(); ++actorIterator) {
+ actor = actorIterator.operator->();
// Check the actor's current intent for a speak intent
- a_inode = ys_dll_head(actor->a_intentlist);
- if (a_inode != NULL) {
- a_intent = (ACTORINTENT *)ys_dll_get_data(a_inode);
+ actorIntentIterator = actor->a_intentlist.begin();
+ if (actorIntentIterator != actor->a_intentlist.end()) {
+ a_intent = actorIntentIterator.operator->();
if (a_intent->a_itype == INTENT_SPEAK) {
// Okay, found a speak intent. Remove one dialogue entry
// from it, releasing any semaphore */
a_speakint = (SPEAKINTENT *)a_intent->a_data;
- a_dnode = ys_dll_head(a_speakint->si_diaglist);
- if (a_dnode != NULL) {
- a_dialogue = (ACTORDIALOGUE *)ys_dll_get_data(a_dnode);
+ actorDialogIterator = a_speakint->si_diaglist.begin();
+ if (actorDialogIterator != a_speakint->si_diaglist.end()) {
+ a_dialogue = actorDialogIterator.operator->();
if (a_dialogue->d_sem != NULL) {
_vm->_script->SThreadReleaseSem(a_dialogue->d_sem);
}
- ys_dll_delete(a_dnode);
+ a_speakint->si_diaglist.erase(actorDialogIterator);
// And stop any currently playing voices
_vm->_sound->stopVoice();
}
@@ -300,7 +285,7 @@ int Actor::create(int actor_id, int x, int y) {
}
int Actor::addActor(ACTOR * actor) {
- YS_DL_NODE *new_node;
+ ActorList::iterator actorIterator;
int last_frame;
int i;
@@ -312,7 +297,7 @@ int Actor::addActor(ACTOR * actor) {
return FAILURE;
}
- if (_tbl[actor->id] != NULL) {
+ if (_tbl[actor->id] != zeroActorIterator) {
return FAILURE;
}
@@ -340,7 +325,6 @@ int Actor::addActor(ACTOR * actor) {
actor->flags = ActorTable[i].flags;
actor->a_dcolor = ActorTable[i].color;
actor->orient = ACTOR_DEFAULT_ORIENT;
- actor->a_intentlist = ys_dll_create();
actor->def_action = 0;
actor->def_action_flags = 0;
actor->action = 0;
@@ -348,35 +332,34 @@ int Actor::addActor(ACTOR * actor) {
actor->action_time = 0;
actor->action_frame = 0;
- new_node = ys_dll_insert(_list, actor, sizeof(*actor), zCompare);
-
- if (new_node == NULL) {
- return FAILURE;
- }
+ actorIterator = _list.pushBack(*actor, actorCompare);
- actor = (ACTOR *)ys_dll_get_data(new_node);
- actor->node = new_node;
+ actor = actorIterator.operator->();
- _tbl[i] = new_node;
+ _tbl[i] = actorIterator;
_count++;
return SUCCESS;
}
int Actor::getActorIndex(uint16 actor_id) {
- uint16 actor_idx;
+ uint16 actorIdx;
if (actor_id == 1) {
- actor_idx = 0;
+ actorIdx = 0;
} else {
- actor_idx = actor_id & ~0x2000;
+ actorIdx = actor_id & ~0x2000;
}
- if (_tbl[actor_idx] == NULL) {
+ if (actorIdx >= ACTORCOUNT) {
+ error("Wrong actorIdx=%i", actorIdx);
+ }
+
+ if (_tbl[actorIdx] == zeroActorIterator) {
return -1;
}
- return actor_idx;
+ return actorIdx;
}
int Actor::actorExists(uint16 actor_id) {
@@ -388,7 +371,7 @@ int Actor::actorExists(uint16 actor_id) {
actor_idx = actor_id & ~0x2000;
}
- if (_tbl[actor_idx] == NULL) {
+ if (_tbl[actor_idx] == zeroActorIterator) {
return 0;
}
@@ -396,9 +379,9 @@ int Actor::actorExists(uint16 actor_id) {
}
int Actor::speak(int index, const char *d_string, uint16 d_voice_rn, SEMAPHORE *sem) {
- YS_DL_NODE *node;
+ ActorList::iterator actorIterator;
ACTOR *actor;
- YS_DL_NODE *a_inode;
+ ActorIntentList::iterator actorIntentIterator;
ACTORINTENT *a_intent_p = NULL;
SPEAKINTENT *a_speakint;
ACTORINTENT a_intent;
@@ -411,20 +394,21 @@ int Actor::speak(int index, const char *d_string, uint16 d_voice_rn, SEMAPHORE *
a_dialogue.d_sem_held = 1;
a_dialogue.d_sem = sem;
- node = _tbl[index];
- if (node == NULL) {
+ actorIterator = _tbl[index];
+ if (actorIterator == zeroActorIterator) {
return FAILURE;
}
- actor = (ACTOR *)ys_dll_get_data(node);
+ actor = actorIterator.operator->();
// If actor's last registered intent is to speak, we can queue the
// requested dialogue on that intent context; so examine the last
// intent
- a_inode = ys_dll_tail(actor->a_intentlist);
- if (a_inode != NULL) {
- a_intent_p = (ACTORINTENT *)ys_dll_get_data(a_inode);
+ actorIntentIterator = actor->a_intentlist.end();
+ --actorIntentIterator;
+ if (actorIntentIterator != actor->a_intentlist.end()) {
+ a_intent_p = actorIntentIterator.operator->();
if (a_intent_p->a_itype == INTENT_SPEAK) {
use_existing_ai = 1;
}
@@ -433,25 +417,19 @@ int Actor::speak(int index, const char *d_string, uint16 d_voice_rn, SEMAPHORE *
if (use_existing_ai) {
// Store the current dialogue off the existing actor intent
a_speakint = (SPEAKINTENT *)a_intent_p->a_data;
- ys_dll_add_tail(a_speakint->si_diaglist, &a_dialogue, sizeof(a_dialogue));
+ a_speakint->si_diaglist.push_back(a_dialogue);
} else {
// Create a new actor intent
a_intent.a_itype = INTENT_SPEAK;
a_intent.a_idone = 0;
a_intent.a_iflags = 0;
+ a_intent.createData();
- a_speakint = (SPEAKINTENT *)malloc(sizeof(*a_speakint));
- if (a_speakint == NULL) {
- return FAILURE;
- }
-
- a_speakint->si_init = 0;
- a_speakint->si_diaglist = ys_dll_create();
+ a_speakint = (SPEAKINTENT *)a_intent.a_data;
a_speakint->si_last_action = actor->action;
- a_intent.a_data = a_speakint;
+ a_speakint->si_diaglist.push_back(a_dialogue);
- ys_dll_add_tail(a_speakint->si_diaglist, &a_dialogue, sizeof(a_dialogue));
- ys_dll_add_tail(actor->a_intentlist, &a_intent, sizeof(a_intent));
+ actor->a_intentlist.push_back(a_intent);
}
if (sem != NULL) {
@@ -462,8 +440,8 @@ int Actor::speak(int index, const char *d_string, uint16 d_voice_rn, SEMAPHORE *
}
int Actor::handleSpeakIntent(ACTOR *actor, SPEAKINTENT *a_speakint, int *complete_p, int msec) {
- YS_DL_NODE *a_dnode;
- YS_DL_NODE *a_dnext;
+ ActorDialogList::iterator actorDialogIterator;
+ ActorDialogList::iterator nextActorDialogIterator;
ACTORDIALOGUE *a_dialogue;
ACTORDIALOGUE *a_dialogue2;
long carry_time;
@@ -479,9 +457,9 @@ int Actor::handleSpeakIntent(ACTOR *actor, SPEAKINTENT *a_speakint, int *complet
}
// Process actor dialogue list
- a_dnode = ys_dll_head(a_speakint->si_diaglist);
- if (a_dnode != NULL) {
- a_dialogue = (ACTORDIALOGUE *)ys_dll_get_data(a_dnode);
+ actorDialogIterator = a_speakint->si_diaglist.begin();
+ if (actorDialogIterator != a_speakint->si_diaglist.end()) {
+ a_dialogue = actorDialogIterator.operator->();
if (!a_dialogue->d_playing) {
// Dialogue voice hasn't played yet - play it now
_vm->_sndRes->playVoice(a_dialogue->d_voice_rn);
@@ -502,19 +480,18 @@ int Actor::handleSpeakIntent(ACTOR *actor, SPEAKINTENT *a_speakint, int *complet
carry_time = a_dialogue->d_time;
- a_dnext = ys_dll_next(a_dnode);
- if (a_dnext != NULL) {
- a_dialogue2 = (ACTORDIALOGUE *)ys_dll_get_data(a_dnode);
+ nextActorDialogIterator = actorDialogIterator;
+ ++nextActorDialogIterator;
+ if (nextActorDialogIterator != a_speakint->si_diaglist.end()) {
+ a_dialogue2 = nextActorDialogIterator.operator->();
a_dialogue2->d_time -= carry_time;
}
- ys_dll_delete(a_dnode);
-
// Check if there are any dialogue nodes left. If not,
// flag this speech intent as complete
- a_dnode = ys_dll_head(a_speakint->si_diaglist);
- if (a_dnode == NULL) {
+ actorDialogIterator = a_speakint->si_diaglist.erase(actorDialogIterator);
+ if (actorDialogIterator != a_speakint->si_diaglist.end()) {
intent_complete = 1;
}
}
@@ -597,7 +574,7 @@ int Actor::setDefaultAction(int index, int action_n, uint16 action_flags) {
}
ACTOR *Actor::lookupActor(int index) {
- YS_DL_NODE *node;
+ ActorList::iterator actorIterator;
ACTOR *actor;
if (!_initialized) {
@@ -608,12 +585,12 @@ ACTOR *Actor::lookupActor(int index) {
return NULL;
}
- if (_tbl[index] == NULL) {
+ if (_tbl[index] == zeroActorIterator) {
return NULL;
}
- node = _tbl[index];
- actor = (ACTOR *)ys_dll_get_data(node);
+ actorIterator = _tbl[index];
+ actor = actorIterator.operator->();
return actor;
}
@@ -637,7 +614,7 @@ int Actor::loadActorSpriteIndex(ACTOR * actor, int si_rn, int *last_frame_p) {
debug(0, "Sprite resource contains %d sprite actions.", s_action_ct);
action_p = (ACTORACTION *)malloc(sizeof(ACTORACTION) * s_action_ct);
- MemoryReadStream readS(res_p, res_len);
+ MemoryReadStreamEndian readS(res_p, res_len, IS_BIG_ENDIAN);
if (action_p == NULL) {
warning("Couldn't allocate memory for sprite actions");
@@ -650,8 +627,8 @@ int Actor::loadActorSpriteIndex(ACTOR * actor, int si_rn, int *last_frame_p) {
for (i = 0; i < s_action_ct; i++) {
for (orient = 0; orient < 4; orient++) {
// Load all four orientations
- action_p[i].dir[orient].frame_index = readS.readUint16LE();
- action_p[i].dir[orient].frame_count = readS.readUint16LE();
+ action_p[i].dir[orient].frame_index = readS.readUint16();
+ action_p[i].dir[orient].frame_count = readS.readUint16();
if (action_p[i].dir[orient].frame_index > last_frame) {
last_frame = action_p[i].dir[orient].frame_index;
}
@@ -671,7 +648,7 @@ int Actor::loadActorSpriteIndex(ACTOR * actor, int si_rn, int *last_frame_p) {
}
int Actor::deleteActor(int index) {
- YS_DL_NODE *node;
+ ActorList::iterator actorIterator;
ACTOR *actor;
if (!_initialized) {
@@ -682,18 +659,19 @@ int Actor::deleteActor(int index) {
return FAILURE;
}
- if (_tbl[index] == NULL) {
+ actorIterator = _tbl[index];
+
+ if (actorIterator == zeroActorIterator) {
return FAILURE;
}
- node = _tbl[index];
- actor = (ACTOR *)ys_dll_get_data(node);
+ actor = actorIterator.operator->();
_vm->_sprite->freeSprite(actor->sl_p);
- ys_dll_delete(node);
+ _list.erase(actorIterator);
- _tbl[index] = NULL;
+ _tbl[index] = zeroActorIterator;
return SUCCESS;
}
@@ -701,8 +679,7 @@ int Actor::deleteActor(int index) {
int Actor::walkTo(int id, const Point *walk_pt, uint16 flags, SEMAPHORE *sem) {
ACTORINTENT actor_intent;
WALKINTENT *walk_intent;
- WALKINTENT zero_intent;
- YS_DL_NODE *node;
+ ActorList::iterator actorIterator;
ACTOR *actor;
assert(_initialized);
@@ -712,19 +689,18 @@ int Actor::walkTo(int id, const Point *walk_pt, uint16 flags, SEMAPHORE *sem) {
return FAILURE;
}
- if (_tbl[id] == NULL) {
+ if (_tbl[id] == zeroActorIterator) {
return FAILURE;
}
- node = _tbl[id];
- actor = (ACTOR *)ys_dll_get_data(node);
+ actorIterator = _tbl[id];
+ actor = actorIterator.operator->();
- walk_intent = (WALKINTENT *)malloc(sizeof(*walk_intent));
- if (walk_intent == NULL) {
- return MEM;
- }
-
- *walk_intent = zero_intent;
+ actor_intent.a_itype = INTENT_PATH;
+ actor_intent.a_iflags = 0;
+ actor_intent.createData();
+
+ walk_intent = (WALKINTENT*)actor_intent.a_data;
walk_intent->wi_flags = flags;
walk_intent->sem_held = 1;
@@ -734,11 +710,7 @@ int Actor::walkTo(int id, const Point *walk_pt, uint16 flags, SEMAPHORE *sem) {
walk_intent->wi_init = 0;
walk_intent->dst_pt = *walk_pt;
- actor_intent.a_itype = INTENT_PATH;
- actor_intent.a_iflags = 0;
- actor_intent.a_data = walk_intent;
-
- ys_dll_add_tail(actor->a_intentlist, &actor_intent, sizeof(actor_intent));
+ actor->a_intentlist.push_back(actor_intent);
if (sem != NULL) {
_vm->_script->SThreadHoldSem(sem);
@@ -754,19 +726,18 @@ int Actor::setPathNode(WALKINTENT *walk_int, Point *src_pt, Point *dst_pt, SEMAP
walk_int->org = *src_pt;
assert((walk_int != NULL) && (src_pt != NULL) && (dst_pt != NULL));
- assert(walk_int->nodelist != NULL);
new_node.node_pt = *dst_pt;
new_node.calc_flag = 0;
-
- ys_dll_add_tail(walk_int->nodelist, &new_node, sizeof(new_node));
-
+
+ walk_int->nodelist.push_back(new_node);
+
return SUCCESS;
}
int Actor::handleWalkIntent(ACTOR *actor, WALKINTENT *a_walkint, int *complete_p, int delta_time) {
- YS_DL_NODE *walk_p;
- YS_DL_NODE *next_p;
+ WalkNodeList::iterator walkNodeIterator;
+ WalkNodeList::iterator nextWalkNodeIterator;
WALKNODE *node_p;
int dx;
@@ -790,7 +761,6 @@ int Actor::handleWalkIntent(ACTOR *actor, WALKINTENT *a_walkint, int *complete_p
// Initialize walk intent
if (!a_walkint->wi_init) {
- a_walkint->nodelist = ys_dll_create();
setPathNode(a_walkint, &actor->a_pt, &a_walkint->dst_pt, a_walkint->sem);
setDefaultAction(actor->id, ACTION_IDLE, ACTION_NONE);
a_walkint->wi_init = 1;
@@ -798,10 +768,10 @@ int Actor::handleWalkIntent(ACTOR *actor, WALKINTENT *a_walkint, int *complete_p
assert(a_walkint->wi_active);
- walk_p = ys_dll_head(a_walkint->nodelist);
- next_p = ys_dll_next(walk_p);
+ walkNodeIterator = a_walkint->nodelist.begin();
+ nextWalkNodeIterator = walkNodeIterator;
- node_p = (WALKNODE *)ys_dll_get_data(walk_p);
+ node_p = walkNodeIterator.operator->();
if (node_p->calc_flag == 0) {
@@ -814,7 +784,7 @@ int Actor::handleWalkIntent(ACTOR *actor, WALKINTENT *a_walkint, int *complete_p
debug(0, "Vertical paths not implemented.");
- ys_dll_delete(walk_p);
+ a_walkint->nodelist.erase(walkNodeIterator);
a_walkint->wi_active = 0;
// Release path semaphore
@@ -883,7 +853,7 @@ int Actor::handleWalkIntent(ACTOR *actor, WALKINTENT *a_walkint, int *complete_p
int exitNum;
debug(2, "Path complete.");
- ys_dll_delete(walk_p);
+ a_walkint->nodelist.erase(walkNodeIterator);
a_walkint->wi_active = 0;
// Release path semaphore
@@ -913,28 +883,32 @@ int Actor::handleWalkIntent(ACTOR *actor, WALKINTENT *a_walkint, int *complete_p
actor->s_pt.x = actor->a_pt.x >> 2;
actor->s_pt.y = actor->a_pt.y >> 2;
- if (path_slope < 0) {
- ys_dll_reorder_up(_list, actor->node, zCompare);
-
+ ActorList::iterator actorIterator;
+ if (_list.locate(actor, actorIterator)) {
+ if (path_slope < 0) {
+ _list.reorderUp(actorIterator, actorCompare);
+ } else {
+ _list.reorderDown(actorIterator, actorCompare);
+ }
} else {
- ys_dll_reorder_down(_list, actor->node, zCompare);
+ error("Actor::handleWalkIntent() actor not found list");
}
return SUCCESS;
}
int Actor::move(int index, const Point *move_pt) {
- YS_DL_NODE *node;
+ ActorList::iterator actorIterator;
ACTOR *actor;
int move_up = 0;
- node = _tbl[index];
- if (node == NULL) {
+ actorIterator = _tbl[index];
+ if (actorIterator == zeroActorIterator) {
return FAILURE;
}
- actor = (ACTOR *)ys_dll_get_data(node);
+ actor = actorIterator.operator->();
if (move_pt->y < actor->a_pt.y) {
move_up = 1;
@@ -946,25 +920,24 @@ int Actor::move(int index, const Point *move_pt) {
AtoS(&actor->s_pt, &actor->a_pt);
if (move_up) {
- ys_dll_reorder_up(_list, actor->node, zCompare);
+ _list.reorderUp(actorIterator, actorCompare);
} else {
-
- ys_dll_reorder_down(_list, actor->node, zCompare);
+ _list.reorderDown(actorIterator, actorCompare);
}
return SUCCESS;
}
int Actor::moveRelative(int index, const Point *move_pt) {
- YS_DL_NODE *node;
+ ActorList::iterator actorIterator;
ACTOR *actor;
- node = _tbl[index];
- if (node == NULL) {
+ actorIterator = _tbl[index];
+ if (actorIterator == zeroActorIterator) {
return FAILURE;
}
- actor = (ACTOR *)ys_dll_get_data(node);
+ actor = actorIterator.operator->();
actor->a_pt.x += move_pt->x;
actor->a_pt.y += move_pt->y;
@@ -972,29 +945,14 @@ int Actor::moveRelative(int index, const Point *move_pt) {
AtoS(&actor->s_pt, &actor->a_pt);
if (actor->a_pt.y < 0) {
-
- ys_dll_reorder_up(_list, actor->node, zCompare);
+ _list.reorderUp(actorIterator, actorCompare);
} else {
-
- ys_dll_reorder_down(_list, actor->node, zCompare);
-
+ _list.reorderDown(actorIterator, actorCompare);
}
return SUCCESS;
}
-static int zCompare(const void *elem1, const void *elem2) {
- const ACTOR *actor1 = (const ACTOR *) elem1;
- const ACTOR *actor2 = (const ACTOR *) elem2;
-
- if (actor1->a_pt.y == actor2->a_pt.y) {
- return 0;
- } else if (actor1->a_pt.y < actor2->a_pt.y) {
- return -1;
- } else {
- return 1;
- }
-}
int Actor::AtoS(Point *screen, const Point *actor) {
screen->x = (actor->x / ACTOR_LMULT);
diff --git a/saga/actor.h b/saga/actor.h
index a1a6b7cafc..4df31a70a4 100644
--- a/saga/actor.h
+++ b/saga/actor.h
@@ -26,8 +26,9 @@
#ifndef SAGA_ACTOR_H__
#define SAGA_ACTOR_H__
-#include "saga/yslib.h"
#include "saga/sprite.h"
+#include "saga/actordata.h"
+#include "saga/list.h"
namespace Saga {
@@ -87,6 +88,16 @@ struct ACTORACTION {
ACTORACTIONITEM dir[4];
};
+struct WALKNODE {
+ int calc_flag;
+ Point node_pt;
+ WALKNODE() {
+ calc_flag = 0;
+ }
+};
+
+typedef Common::List<WALKNODE> WalkNodeList;
+
struct WALKINTENT {
int wi_active;
uint16 wi_flags;
@@ -99,24 +110,48 @@ struct WALKINTENT {
Point cur;
Point dst_pt;
- YS_DL_LIST *nodelist;
+ WalkNodeList nodelist;
int sem_held;
SEMAPHORE *sem;
- WALKINTENT() { memset(this, 0, sizeof(*this)); }
+ WALKINTENT() {
+ wi_active = 0;
+ wi_flags = 0;
+ wi_init = 0;
+
+ time = 0;
+ slope = 0;
+ x_dir = 0;
+
+ sem_held = 0;
+ sem = NULL;
+ }
};
-struct WALKNODE {
- int calc_flag;
- Point node_pt;
+
+struct ACTORDIALOGUE {
+ int d_playing;
+ const char *d_string;
+ uint16 d_voice_rn;
+ long d_time;
+ int d_sem_held;
+ SEMAPHORE *d_sem;
+ ACTORDIALOGUE() { memset(this, 0, sizeof(*this)); }
};
+typedef Common::List<ACTORDIALOGUE> ActorDialogList;
+
struct SPEAKINTENT {
int si_init;
uint16 si_flags;
int si_last_action;
- YS_DL_LIST *si_diaglist; /* Actor dialogue list */
+ ActorDialogList si_diaglist; /* Actor dialogue list */
+ SPEAKINTENT() {
+ si_init = 0;
+ si_flags = 0;
+ si_last_action = 0;
+ }
};
struct ACTORINTENT {
@@ -125,9 +160,42 @@ struct ACTORINTENT {
int a_idone;
void *a_data;
+ void createData() {
+ assert(a_data == NULL);
+
+ if(INTENT_SPEAK == a_itype) {
+ a_data = new SPEAKINTENT;
+ }
+ else
+ if(INTENT_PATH == a_itype) {
+ a_data = new WALKINTENT;
+ }
+ }
+ void deleteData() {
+
+ if(INTENT_SPEAK == a_itype) {
+ SPEAKINTENT *a_speakint;
+
+ assert(a_data);
+ a_speakint = (SPEAKINTENT *)a_data;
+ delete a_speakint;
+ }
+ else
+ if(INTENT_PATH == a_itype) {
+ WALKINTENT *a_walkint;
+
+ assert(a_data);
+ a_walkint = (WALKINTENT *)a_data;
+ delete a_walkint;
+ }
+ a_data = NULL;
+ }
+
ACTORINTENT() { memset(this, 0, sizeof(*this)); }
};
+typedef Common::List<ACTORINTENT> ActorIntentList;
+
struct ACTOR {
int id; // Actor id
int name_i; // Actor's index in actor name string list
@@ -151,7 +219,7 @@ struct ACTOR {
// intent before moving on to the next; thus actor movements, esp
// as described from scripts, can be serialized
- YS_DL_LIST *a_intentlist;
+ ActorIntentList a_intentlist;
// WALKPATH path;
@@ -165,19 +233,30 @@ struct ACTOR {
ACTORACTION *act_tbl; // Action lookup table
int action_ct; // Number of actions in the action LUT
- YS_DL_NODE *node; // Actor's node in the actor list
- ACTOR() { memset(this, 0, sizeof(*this)); }
+ ACTOR() {
+ id = 0;
+ name_i = 0;
+ flags = 0;
+ sl_rn = 0;
+ si_rn = 0;
+ sl_p = 0;
+ idle_time = 0;
+ orient = 0;
+ speaking = 0;
+ a_dcolor = 0;
+ def_action = 0;
+ def_action_flags = 0;
+ action = 0;
+ action_flags = 0;
+ action_frame = 0;
+ action_time = 0;
+ act_tbl = NULL;
+ action_ct = NULL;
+ }
};
-struct ACTORDIALOGUE {
- int d_playing;
- const char *d_string;
- uint16 d_voice_rn;
- long d_time;
- int d_sem_held;
- SEMAPHORE *d_sem;
- ACTORDIALOGUE() { memset(this, 0, sizeof(*this)); }
-};
+typedef SortedList<ACTOR> ActorList;
+
struct ACTIONTIMES {
int action;
@@ -235,9 +314,9 @@ private:
bool _initialized;
RSCFILE_CONTEXT *_actorContext;
uint16 _count;
- int *_aliasTbl;
- YS_DL_NODE **_tbl;
- YS_DL_LIST *_list;
+ int _aliasTbl[ACTORCOUNT];
+ ActorList::iterator _tbl[ACTORCOUNT];
+ ActorList _list;
};
} // End of namespace Saga
diff --git a/saga/animation.cpp b/saga/animation.cpp
index 7768ad2294..b92d81f296 100644
--- a/saga/animation.cpp
+++ b/saga/animation.cpp
@@ -31,6 +31,7 @@
#include "saga/render.h"
#include "saga/animation.h"
+#include "saga/stream.h"
namespace Saga {
@@ -105,7 +106,7 @@ int Anim::load(const byte *anim_resdata, size_t anim_resdata_len, uint16 *anim_i
getFrameOffset(anim_resdata, anim_resdata_len, i + 1, &new_anim->frame_offsets[i]);
}
} else {
- new_anim->cur_frame_p = anim_resdata + SAGA_FRAME_HEADER_LEN;
+ new_anim->cur_frame_p = anim_resdata + SAGA_FRAME_HEADER_LEN; // ? len - may vary
new_anim->cur_frame_len = anim_resdata_len - SAGA_FRAME_HEADER_LEN;
getNumFrames(anim_resdata, anim_resdata_len, &new_anim->n_frames);
}
@@ -372,12 +373,13 @@ int Anim::getNumFrames(const byte *anim_resource, size_t anim_resource_len, uint
if (!_initialized) {
return FAILURE;
}
+
- MemoryReadStream readS(anim_resource, anim_resource_len);
+ MemoryReadStreamEndian readS(anim_resource, anim_resource_len, IS_BIG_ENDIAN);
- ah.magic = readS.readUint16LE();
- ah.screen_w = readS.readUint16LE();
- ah.screen_h = readS.readUint16LE();
+ ah.magic = readS.readUint16LE(); // cause ALWAYS LE
+ ah.screen_w = readS.readUint16();
+ ah.screen_h = readS.readUint16();
ah.unknown06 = readS.readByte();
ah.unknown07 = readS.readByte();
@@ -394,7 +396,7 @@ int Anim::getNumFrames(const byte *anim_resource, size_t anim_resource_len, uint
}
magic = *(anim_resource + offset);
- if (magic == SAGA_FRAME_HEADER_MAGIC) {
+ if (magic == SAGA_FRAME_START) {
*n_frames = x;
return SUCCESS;
}
@@ -435,11 +437,11 @@ int Anim::ITE_DecodeFrame(const byte *resdata, size_t resdata_len, size_t frame_
return FAILURE;
}
- MemoryReadStream headerReadS(resdata, resdata_len);
+ MemoryReadStreamEndian headerReadS(resdata, resdata_len, IS_BIG_ENDIAN);
// Read animation header
ah.magic = headerReadS.readUint16LE();
- ah.screen_w = headerReadS.readUint16LE();
- ah.screen_h = headerReadS.readUint16LE();
+ ah.screen_w = headerReadS.readUint16();
+ ah.screen_h = headerReadS.readUint16();
ah.unknown06 = headerReadS.readByte();
ah.unknown07 = headerReadS.readByte();
ah.nframes = headerReadS.readByte();
@@ -456,22 +458,21 @@ int Anim::ITE_DecodeFrame(const byte *resdata, size_t resdata_len, size_t frame_
return FAILURE;
}
- // Read frame header
MemoryReadStream readS(resdata + frame_offset, resdata_len - frame_offset);
// Check for frame magic byte
magic = readS.readByte();
- if (magic != SAGA_FRAME_HEADER_MAGIC) {
+ if (magic != SAGA_FRAME_START) {
warning("ITE_DecodeFrame: Invalid frame offset");
return FAILURE;
}
- // For some strange reason, the animation header is in little
- // endian format, but the actual RLE encoded frame data,
- // including the frame header, is in big endian format.
fh.x_start = readS.readUint16BE();
- fh.y_start = readS.readByte();
+ if (IS_MAC_VERSION)
+ fh.y_start = readS.readUint16BE();
+ else
+ fh.y_start = readS.readByte();
readS.readByte(); /* Skip pad byte */
fh.x_pos = readS.readUint16BE();
fh.y_pos = readS.readUint16BE();
@@ -481,14 +482,25 @@ int Anim::ITE_DecodeFrame(const byte *resdata, size_t resdata_len, size_t frame_
x_start = fh.x_start;
y_start = fh.y_start;
+#if 1
+#define VALIDATE_WRITE_POINTER \
+ if ((write_p < buf) || (write_p >= (buf + screen_w * screen_h))) { \
+ warning("VALIDATE_WRITE_POINTER: write_p=%x buf=%x", write_p, buf); \
+ return FAILURE; \
+ }
+#else
+#define VALIDATE_WRITE_POINTER
+#endif
+
// Setup write pointer to the draw origin
write_p = (buf + (y_start * screen_w) + x_start);
+ VALIDATE_WRITE_POINTER;
// Begin RLE decompression to output buffer
do {
mark_byte = readS.readByte();
switch (mark_byte) {
- case 0x10: // Long Unencoded Run
+ case SAGA_FRAME_LONG_UNCOMPRESSED_RUN: // Long Unencoded Run
runcount = readS.readSint16BE();
for (i = 0; i < runcount; i++) {
data_byte = readS.readByte();
@@ -496,30 +508,39 @@ int Anim::ITE_DecodeFrame(const byte *resdata, size_t resdata_len, size_t frame_
*write_p = data_byte;
}
write_p++;
+ VALIDATE_WRITE_POINTER;
}
continue;
break;
- case 0x20: // Long encoded run
+ case SAGA_FRAME_LONG_COMPRESSED_RUN: // Long encoded run
runcount = readS.readSint16BE();
data_byte = readS.readByte();
for (i = 0; i < runcount; i++) {
*write_p++ = data_byte;
+ VALIDATE_WRITE_POINTER;
}
continue;
break;
- case 0x2F: // End of row
+ case SAGA_FRAME_ROW_END: // End of row
x_vector = readS.readSint16BE();
- new_row = readS.readByte();
+
+ if (IS_MAC_VERSION)
+ new_row = readS.readSint16BE();
+ else
+ new_row = readS.readByte();
+
// Set write pointer to the new draw origin
write_p = buf + ((y_start + new_row) * screen_w) + x_start + x_vector;
+ VALIDATE_WRITE_POINTER;
continue;
break;
- case 0x30: // Reposition command
+ case SAGA_FRAME_REPOSITION: // Reposition command
x_vector = readS.readSint16BE();
write_p += x_vector;
+ VALIDATE_WRITE_POINTER;
continue;
break;
- case 0x3F: // End of frame marker
+ case SAGA_FRAME_END: // End of frame marker
return SUCCESS;
break;
default:
@@ -530,22 +551,24 @@ int Anim::ITE_DecodeFrame(const byte *resdata, size_t resdata_len, size_t frame_
control_ch = mark_byte & 0xC0U;
param_ch = mark_byte & 0x3FU;
switch (control_ch) {
- case 0xC0: // 1100 0000
+ case SAGA_FRAME_EMPTY_RUN: // 1100 0000
// Run of empty pixels
runcount = param_ch + 1;
write_p += runcount;
+ VALIDATE_WRITE_POINTER;
continue;
break;
- case 0x80: // 1000 0000
+ case SAGA_FRAME_COMPRESSED_RUN: // 1000 0000
// Run of compressed data
runcount = param_ch + 1;
data_byte = readS.readByte();
for (i = 0; i < runcount; i++) {
*write_p++ = data_byte;
+ VALIDATE_WRITE_POINTER;
}
continue;
break;
- case 0x40: // 0100 0000
+ case SAGA_FRAME_UNCOMPRESSED_RUN: // 0100 0000
// Uncompressed run
runcount = param_ch + 1;
for (i = 0; i < runcount; i++) {
@@ -554,6 +577,7 @@ int Anim::ITE_DecodeFrame(const byte *resdata, size_t resdata_len, size_t frame_
*write_p = data_byte;
}
write_p++;
+ VALIDATE_WRITE_POINTER;
}
continue;
break;
@@ -586,7 +610,7 @@ int Anim::IHNM_DecodeFrame(byte *decode_buf, size_t decode_buf_len, const byte *
size_t in_ch_offset;
- MemoryReadStream readS(thisf_p, thisf_len);
+ MemoryReadStreamEndian readS(thisf_p, thisf_len, !IS_BIG_ENDIAN); // RLE has inversion BE<>LE
byte *outbuf_p = decode_buf;
byte *outbuf_endp = (decode_buf + decode_buf_len) - 1;
@@ -616,13 +640,13 @@ int Anim::IHNM_DecodeFrame(byte *decode_buf, size_t decode_buf_len, const byte *
return FAILURE;
}
- param1 = readS.readUint16BE();
- param2 = readS.readUint16BE();
+ param1 = readS.readUint16();
+ param2 = readS.readUint16();
readS.readByte(); // skip 1?
- param3 = readS.readUint16BE();
- param4 = readS.readUint16BE();
- param5 = readS.readUint16BE();
- param6 = readS.readUint16BE();
+ param3 = readS.readUint16();
+ param4 = readS.readUint16();
+ param5 = readS.readUint16();
+ param6 = readS.readUint16();
x_origin = param1;
y_origin = param2;
@@ -639,8 +663,8 @@ int Anim::IHNM_DecodeFrame(byte *decode_buf, size_t decode_buf_len, const byte *
continue;
}
break;
- case 0x10: // Long Unencoded Run
- runcount = readS.readSint16BE();
+ case SAGA_FRAME_LONG_UNCOMPRESSED_RUN: // Long Unencoded Run
+ runcount = readS.readSint16();
if (thisf_len - readS.pos() < runcount) {
warning("0x%02X: Input buffer underrun", in_ch);
return FAILURE;
@@ -672,13 +696,13 @@ int Anim::IHNM_DecodeFrame(byte *decode_buf, size_t decode_buf_len, const byte *
readS.readByte();
continue;
break;
- case 0x20: // Long compressed run
+ case SAGA_FRAME_LONG_COMPRESSED_RUN: // Long compressed run
if (thisf_len - readS.pos() <= 3) {
warning("0x%02X: Input buffer underrun", in_ch);
return FAILURE;
}
- runcount = readS.readSint16BE();
+ runcount = readS.readSint16();
data_pixel = readS.readByte();
for (c = 0; c < runcount; c++) {
@@ -689,27 +713,27 @@ int Anim::IHNM_DecodeFrame(byte *decode_buf, size_t decode_buf_len, const byte *
continue;
break;
- case 0x2F: // End of row
+ case SAGA_FRAME_ROW_END: // End of row
if (thisf_len - readS.pos() <= 4) {
return FAILURE;
}
- x_vector = readS.readSint16BE();
- new_row = readS.readSint16BE();
+ x_vector = readS.readSint16();
+ new_row = readS.readSint16();
outbuf_p = decode_buf + ((y_origin + new_row) * di.logical_w) + x_origin + x_vector;
outbuf_remain = (outbuf_endp - outbuf_p) + 1;
continue;
break;
- case 0x30: // Reposition command
+ case SAGA_FRAME_REPOSITION: // Reposition command
if (thisf_len - readS.pos() < 2) {
return FAILURE;
}
- x_vector = readS.readSint16BE();
+ x_vector = readS.readSint16();
if (((x_vector > 0) && ((size_t) x_vector > outbuf_remain)) || (-x_vector > outbuf_p - decode_buf)) {
- warning("0x30: Invalid x_vector");
+ warning("SAGA_FRAME_REPOSITION: Invalid x_vector");
return FAILURE;
}
@@ -718,8 +742,8 @@ int Anim::IHNM_DecodeFrame(byte *decode_buf, size_t decode_buf_len, const byte *
continue;
break;
- case 0x3F: // 68: Frame end marker
- debug(1, "0x3F: Frame end marker");
+ case SAGA_FRAME_END: // Frame end marker
+ debug(1, "SAGA_FRAME_END: Frame end marker");
if (decoded_data && (thisf_len - readS.pos() > 0)) {
*nextf_p = thisf_p + readS.pos();
*nextf_len = thisf_len - readS.pos();
@@ -740,7 +764,7 @@ int Anim::IHNM_DecodeFrame(byte *decode_buf, size_t decode_buf_len, const byte *
param_ch = in_ch & 0x3f;
switch (control_ch) {
- case 0xC0: // Run of empty pixels
+ case SAGA_FRAME_EMPTY_RUN: // Run of empty pixels
runcount = param_ch + 1;
if (outbuf_remain < runcount) {
return FAILURE;
@@ -750,7 +774,7 @@ int Anim::IHNM_DecodeFrame(byte *decode_buf, size_t decode_buf_len, const byte *
outbuf_remain -= runcount;
continue;
break;
- case 0x80: // Run of compressed data
+ case SAGA_FRAME_COMPRESSED_RUN: // Run of compressed data
runcount = param_ch + 1;
if ((outbuf_remain < runcount) || (thisf_len - readS.pos() <= 1)) {
return FAILURE;
@@ -765,7 +789,7 @@ int Anim::IHNM_DecodeFrame(byte *decode_buf, size_t decode_buf_len, const byte *
outbuf_remain -= runcount;
continue;
break;
- case 0x40: // Uncompressed run
+ case SAGA_FRAME_UNCOMPRESSED_RUN: // Uncompressed run
runcount = param_ch + 1;
if ((outbuf_remain < runcount) || (thisf_len - readS.pos() < runcount)) {
return FAILURE;
@@ -809,12 +833,13 @@ int Anim::getFrameOffset(const byte *resdata, size_t resdata_len, uint16 find_fr
return FAILURE;
}
- MemoryReadStream readS(resdata, resdata_len);
+
+ MemoryReadStreamEndian readS(resdata, resdata_len, IS_BIG_ENDIAN);
// Read animation header
ah.magic = readS.readUint16LE();
- ah.screen_w = readS.readUint16LE();
- ah.screen_h = readS.readUint16LE();
+ ah.screen_w = readS.readUint16();
+ ah.screen_h = readS.readUint16();
ah.unknown06 = readS.readByte();
ah.unknown07 = readS.readByte();
ah.nframes = readS.readByte();
@@ -828,9 +853,11 @@ int Anim::getFrameOffset(const byte *resdata, size_t resdata_len, uint16 find_fr
return FAILURE;
}
+ readS._bigEndian = !IS_BIG_ENDIAN; // RLE has inversion BE<>LE
+
for (current_frame = 1; current_frame < find_frame; current_frame++) {
magic = readS.readByte();
- if (magic != SAGA_FRAME_HEADER_MAGIC) {
+ if (magic != SAGA_FRAME_START) {
// Frame sync failure. Magic Number not found
return FAILURE;
}
@@ -839,33 +866,36 @@ int Anim::getFrameOffset(const byte *resdata, size_t resdata_len, uint16 find_fr
for (i = 0; i < SAGA_FRAME_HEADER_LEN; i++)
readS.readByte();
+
// For some strange reason, the animation header is in little
// endian format, but the actual RLE encoded frame data,
// including the frame header, is in big endian format. */
do {
mark_byte = readS.readByte();
+// debug(7, "_pos=%x mark_byte=%x", readS.pos(), mark_byte);
+
switch (mark_byte) {
- case 0x3F: // End of frame marker
+ case SAGA_FRAME_END: // End of frame marker
continue;
break;
- case 0x30: // Reposition command
- readS.readByte();
- readS.readByte();
+ case SAGA_FRAME_REPOSITION: // Reposition command
+ readS.readSint16BE();
continue;
break;
- case 0x2F: // End of row marker
- readS.readByte();
- readS.readByte();
- readS.readByte();
+ case SAGA_FRAME_ROW_END: // End of row marker
+ readS.readSint16BE();
+ if (IS_MAC_VERSION)
+ readS.readSint16BE();
+ else
+ readS.readByte();
continue;
break;
- case 0x20: // Long compressed run marker
- readS.readByte();
- readS.readByte();
+ case SAGA_FRAME_LONG_COMPRESSED_RUN: // Long compressed run marker
+ readS.readSint16BE();
readS.readByte();
continue;
break;
- case 0x10: // (16) 0001 0000
+ case SAGA_FRAME_LONG_UNCOMPRESSED_RUN: // (16) 0001 0000
// Long Uncompressed Run
runcount = readS.readSint16BE();
for (i = 0; i < runcount; i++)
@@ -879,16 +909,16 @@ int Anim::getFrameOffset(const byte *resdata, size_t resdata_len, uint16 find_fr
// Mask all but two high order (control) bits
control = mark_byte & 0xC0;
switch (control) {
- case 0xC0:
+ case SAGA_FRAME_EMPTY_RUN:
// Run of empty pixels
continue;
break;
- case 0x80:
+ case SAGA_FRAME_COMPRESSED_RUN:
// Run of compressed data
readS.readByte(); // Skip data byte
continue;
break;
- case 0x40:
+ case SAGA_FRAME_UNCOMPRESSED_RUN:
// Uncompressed run
runcount = (mark_byte & 0x3f) + 1;
for (i = 0; i < runcount; i++)
@@ -900,7 +930,7 @@ int Anim::getFrameOffset(const byte *resdata, size_t resdata_len, uint16 find_fr
return FAILURE;
break;
}
- } while (mark_byte != 63);
+ } while (mark_byte != SAGA_FRAME_END);
}
*frame_offset_p = readS.pos();
diff --git a/saga/animation.h b/saga/animation.h
index 4f41d8c75a..1fafe892f3 100644
--- a/saga/animation.h
+++ b/saga/animation.h
@@ -31,8 +31,17 @@ namespace Saga {
#define MAX_ANIMATIONS 7
#define DEFAULT_FRAME_TIME 140
-#define SAGA_FRAME_HEADER_MAGIC 15
-#define SAGA_FRAME_HEADER_LEN 12
+#define SAGA_FRAME_HEADER_LEN (IS_MAC_VERSION ? 13 : 12)
+
+#define SAGA_FRAME_START 0xF
+#define SAGA_FRAME_END 0x3F
+#define SAGA_FRAME_REPOSITION 0x30
+#define SAGA_FRAME_ROW_END 0x2F
+#define SAGA_FRAME_LONG_COMPRESSED_RUN 0x20
+#define SAGA_FRAME_LONG_UNCOMPRESSED_RUN 0x10
+#define SAGA_FRAME_COMPRESSED_RUN 0x80
+#define SAGA_FRAME_UNCOMPRESSED_RUN 0x40
+#define SAGA_FRAME_EMPTY_RUN 0xC0
// All animation resources begin with an ANIMATION_HEADER
// at 0x00, followed by a RLE code stream
diff --git a/saga/events.cpp b/saga/events.cpp
index f1bbdcc564..a1984f21b2 100644
--- a/saga/events.cpp
+++ b/saga/events.cpp
@@ -27,7 +27,6 @@
#include "saga/saga.h"
#include "saga/gfx.h"
-#include "saga/yslib.h"
#include "saga/animation.h"
#include "saga/console.h"
@@ -46,10 +45,7 @@ namespace Saga {
Events::Events(SagaEngine *vm) : _vm(vm), _initialized(false) {
debug(0, "Initializing event subsystem...");
- _eventList = ys_dll_create();
-
- if (_eventList)
- _initialized = true;
+ _initialized = true;
}
Events::~Events(void) {
@@ -61,9 +57,6 @@ Events::~Events(void) {
// First advances event times, then processes each event with the appropriate
// handler depending on the type of event.
int Events::handleEvents(long msec) {
- YS_DL_NODE *walk_node;
- YS_DL_NODE *next_node;
-
EVENT *event_p;
long delta_time;
@@ -73,11 +66,8 @@ int Events::handleEvents(long msec) {
processEventTime(msec);
// Process each event in list
- for (walk_node = ys_dll_head(_eventList); walk_node != NULL; walk_node = next_node) {
- event_p = (EVENT *)ys_dll_get_data(walk_node);
-
- // Save next event in case current event is handled and removed
- next_node = ys_dll_next(walk_node);
+ for (EventList::iterator eventi = _eventList.begin(); eventi != _eventList.end(); ++eventi) {
+ event_p = (EVENT *)eventi.operator->();
// Call the appropriate event handler for the specific event type
switch (event_p->type) {
@@ -109,19 +99,18 @@ int Events::handleEvents(long msec) {
if ((result == EVENT_DELETE) || (result == EVENT_INVALIDCODE)) {
// If there is no event chain, delete the base event.
if (event_p->chain == NULL) {
- ys_dll_delete(walk_node);
+ eventi=_eventList.eraseAndPrev(eventi);
} else {
// If there is an event chain present, move the next event
// in the chain up, adjust it by the previous delta time,
- // and reprocess the event by adjusting next_node. */
+ // and reprocess the event */
delta_time = event_p->time;
+ EVENT *from_chain=event_p->chain;
+ memcpy(event_p, from_chain,sizeof *event_p);
+ free(from_chain);
- ys_dll_replace(walk_node, event_p->chain, sizeof *event_p);
-
- event_p = (EVENT *)ys_dll_get_data(walk_node);
event_p->time += delta_time;
-
- next_node = walk_node;
+ --eventi;
}
} else if (result == EVENT_BREAK) {
break;
@@ -426,17 +415,10 @@ int Events::handleInterval(EVENT *event) {
// Schedules an event in the event list; returns a pointer to the scheduled
// event suitable for chaining if desired.
EVENT *Events::queue(EVENT *event) {
- YS_DL_NODE *new_node;
EVENT *queued_event;
event->chain = NULL;
- new_node = ys_dll_add_tail(_eventList, event, sizeof *event);
-
- if (new_node == NULL) {
- return NULL;
- }
-
- queued_event = (EVENT *)ys_dll_get_data(new_node);
+ queued_event = _eventList.pushBack(*event).operator->();
initializeEvent(queued_event);
@@ -490,16 +472,13 @@ int Events::initializeEvent(EVENT *event) {
}
int Events::clearList() {
- YS_DL_NODE *walk_node;
- YS_DL_NODE *next_node;
EVENT *chain_walk;
EVENT *next_chain;
EVENT *event_p;
// Walk down event list
- for (walk_node = ys_dll_head(_eventList); walk_node != NULL; walk_node = next_node) {
- next_node = ys_dll_next(walk_node);
- event_p = (EVENT *)ys_dll_get_data(walk_node);
+ for (EventList::iterator eventi = _eventList.begin(); eventi != _eventList.end(); ++eventi) {
+ event_p = (EVENT *)eventi.operator->();
// Only remove events not marked NODESTROY (engine events)
if (!(event_p->code & NODESTROY)) {
@@ -508,7 +487,7 @@ int Events::clearList() {
next_chain = chain_walk->chain;
free(chain_walk);
}
- ys_dll_delete(walk_node);
+ eventi=_eventList.eraseAndPrev(eventi);
}
}
@@ -517,24 +496,21 @@ int Events::clearList() {
// Removes all events from the list (even NODESTROY)
int Events::freeList() {
- YS_DL_NODE *walk_node;
- YS_DL_NODE *next_node;
EVENT *chain_walk;
EVENT *next_chain;
EVENT *event_p;
// Walk down event list
- for (walk_node = ys_dll_head(_eventList); walk_node != NULL; walk_node = next_node) {
- event_p = (EVENT *)ys_dll_get_data(walk_node);
- // Remove any events chained off current node
+ EventList::iterator eventi = _eventList.begin();
+ while (eventi != _eventList.end()) {
+ event_p = (EVENT *)eventi.operator->();
+
+ // Remove any events chained off this one */
for (chain_walk = event_p->chain; chain_walk != NULL; chain_walk = next_chain) {
next_chain = chain_walk->chain;
free(chain_walk);
}
-
- // Delete current node
- next_node = ys_dll_next(walk_node);
- ys_dll_delete(walk_node);
+ eventi=_eventList.erase(eventi);
}
return SUCCESS;
@@ -542,12 +518,12 @@ int Events::freeList() {
// Walks down the event list, updating event times by 'msec'.
int Events::processEventTime(long msec) {
- YS_DL_NODE *walk_node;
EVENT *event_p;
uint16 event_count = 0;
- for (walk_node = ys_dll_head(_eventList); walk_node != NULL; walk_node = ys_dll_next(walk_node)) {
- event_p = (EVENT *)ys_dll_get_data(walk_node);
+ for (EventList::iterator eventi = _eventList.begin(); eventi != _eventList.end(); ++eventi) {
+ event_p = (EVENT *)eventi.operator->();
+
event_p->time -= msec;
event_count++;
diff --git a/saga/events.h b/saga/events.h
index 454047f0a1..988a7f4b6b 100644
--- a/saga/events.h
+++ b/saga/events.h
@@ -26,7 +26,10 @@
#ifndef SAGA_EVENT_H
#define SAGA_EVENT_H
+#include "saga/list.h"
+
namespace Saga {
+
enum EVENT_TYPES {
ONESHOT_EVENT,
CONTINUOUS_EVENT,
@@ -119,6 +122,8 @@ struct EVENT {
EVENT() { memset(this, 0, sizeof(*this)); }
};
+typedef SortedList<EVENT> EventList;
+
#define EVENT_WARNINGCOUNT 1000
#define EVENT_MASK 0x00FF
@@ -151,7 +156,7 @@ class Events {
SagaEngine *_vm;
bool _initialized;
- YS_DL_LIST *_eventList;
+ EventList _eventList;
};
} // End of namespace Saga
diff --git a/saga/font.cpp b/saga/font.cpp
index d317b17a94..3fe61688d7 100644
--- a/saga/font.cpp
+++ b/saga/font.cpp
@@ -29,6 +29,7 @@
#include "saga/game_mod.h"
#include "saga/font.h"
+#include "saga/stream.h"
namespace Saga {
@@ -64,20 +65,20 @@ Font::~Font(void) {
debug(0, "Font::~Font(): Freeing fonts.");
/*
- for ( i = 0 ; i < FONT_COUNT ; i ++ ) {
- if ( _fonts[i] != NULL ) {
- if ( _fonts[i]->normal_loaded ) {
- free( _fonts[i]->normal->font_free_p );
- free( _fonts[i]->normal );
+ for (i = 0 ; i < FONT_COUNT ; i++) {
+ if (_fonts[i] != NULL) {
+ if (_fonts[i]->normal_loaded) {
+ free(_fonts[i]->normal->font_free_p);
+ free(_fonts[i]->normal);
}
- if ( _fonts[i]->outline_loaded ) {
- free( _fonts[i]->outline->font_free_p );
- free( _fonts[i]->outline );
+ if (_fonts[i]->outline_loaded) {
+ free(_fonts[i]->outline->font_free_p);
+ free(_fonts[i]->outline);
}
}
- free( _fonts[i] );
+ free(_fonts[i]);
}
*/
}
@@ -106,7 +107,7 @@ int Font::loadFont(uint32 font_rn, int font_id) {
return FAILURE;
}
- MemoryReadStream readS(fontres_p, fontres_len);
+ MemoryReadStreamEndian readS(fontres_p, fontres_len, IS_BIG_ENDIAN);
// Create new font structure
font = (FONT *)malloc(sizeof *font);
@@ -116,9 +117,9 @@ int Font::loadFont(uint32 font_rn, int font_id) {
}
// Read font header
- fh.c_height = readS.readUint16LE();
- fh.c_width = readS.readUint16LE();
- fh.row_length = readS.readUint16LE();
+ fh.c_height = readS.readUint16();
+ fh.c_width = readS.readUint16();
+ fh.row_length = readS.readUint16();
debug(1, "Font::loadFont(): Reading font resource #%d...", font_rn);
@@ -140,7 +141,7 @@ int Font::loadFont(uint32 font_rn, int font_id) {
normal_font->hdr.row_length = fh.row_length;
for (c = 0; c < FONT_CHARCOUNT; c++) {
- normal_font->fce[c].index = readS.readUint16LE();
+ normal_font->fce[c].index = readS.readUint16();
}
for (c = 0; c < FONT_CHARCOUNT; c++) {
diff --git a/saga/game.cpp b/saga/game.cpp
index d04ac2412f..9f24f651a8 100644
--- a/saga/game.cpp
+++ b/saga/game.cpp
@@ -50,12 +50,26 @@ GAME_FILEDESC ITEDEMO_GameFiles[] = {
GAME_FONTDESC ITEDEMO_GameFonts[] = {
{GAME_FONT_SMALL, 0},
{GAME_FONT_MEDIUM, 1}
-};
+};
GAME_SOUNDINFO ITEDEMO_GameSound = {
GAME_SOUND_VOC, 0, 0, 0
};
+// Inherit the Earth - MAC Wyrmkeep Demo version
+GAME_FILEDESC ITEMACDEMO_GameFiles[] = {
+ {"ITED.RSC", GAME_RESOURCEFILE},
+ {"SCRIPTSD.RSC", GAME_SCRIPTFILE},
+ {"SOUNDSD.RSC", GAME_SOUNDFILE},
+ {"VOICESD.RSC", GAME_VOICEFILE},
+ {"MUSICD.RSC", GAME_MUSICFILE}
+};
+
+GAME_FONTDESC ITEMACDEMO_GameFonts[] = {
+ {GAME_FONT_MEDIUM, 0},
+ {GAME_FONT_SMALL, 2}
+};
+
// Inherit the Earth - win32 Wyrmkeep Linux Demo version
GAME_FILEDESC ITEWINDEMO_GameFiles[] = {
{"ITED.RSC", GAME_RESOURCEFILE},
@@ -65,6 +79,11 @@ GAME_FILEDESC ITEWINDEMO_GameFiles[] = {
{"MUSICD.RSC", GAME_MUSICFILE}
};
+GAME_FONTDESC ITEWINDEMO_GameFonts[] = {
+ {GAME_FONT_MEDIUM, 0},
+ {GAME_FONT_SMALL, 2}
+};
+
// Inherit the Earth - win32 Wyrmkeep Demo version older release
GAME_FILEDESC ITEWINDEMOOld_GameFiles[] = {
{"ITED.RSC", GAME_RESOURCEFILE},
@@ -93,6 +112,13 @@ GAME_RESOURCEDESC ITE_Resources = {
ITE_DIALOGUE_PANEL
};
+GAME_RESOURCEDESC ITEMACDEMO_Resources = {
+ ITEMACDEMO_SCENE_LUT, // Scene lookup table RN
+ ITE_SCRIPT_LUT, // Script lookup table RN
+ ITE_COMMAND_PANEL,
+ ITE_DIALOGUE_PANEL
+};
+
GAME_SOUNDINFO ITE_GameSound = {
GAME_SOUND_VOC, 0, 0, 0
};
@@ -179,7 +205,26 @@ GAMEDESC GameDescs[] = {
ARRAYSIZE(ITEDEMO_GameFonts),
ITEDEMO_GameFonts,
&ITEDEMO_GameSound,
- 0 // features
+ 0, // features
+ },
+
+ // Inherit the earth - MAC Demo version
+ // Note: it should be before win32 version ???
+ {
+ "ite-demo",
+ GID_ITE,
+ GAME_ITE_MACDEMO,
+ "Inherit the Earth (MAC Demo)",
+ 320, 200,
+ 137,
+ ITE_DEFAULT_SCENE,
+ &ITEMACDEMO_Resources,
+ ARRAYSIZE(ITEMACDEMO_GameFiles),
+ ITEMACDEMO_GameFiles,
+ ARRAYSIZE(ITEMACDEMO_GameFonts),
+ ITEMACDEMO_GameFonts,
+ &ITECD_GameSound,
+ GF_VOX_VOICES | GF_BIG_ENDIAN_DATA
},
// Inherit the earth - Linux Demo version
@@ -213,8 +258,8 @@ GAMEDESC GameDescs[] = {
&ITE_Resources,
ARRAYSIZE(ITEWINDEMOOld_GameFiles),
ITEWINDEMO_GameFiles,
- ARRAYSIZE(ITECD_GameFonts),
- ITECD_GameFonts,
+ ARRAYSIZE(ITEWINDEMO_GameFonts),
+ ITEWINDEMO_GameFonts,
&ITECD_GameSound,
GF_VOX_VOICES
},
@@ -465,8 +510,11 @@ int LoadGame(uint16 game_n) {
return FAILURE;
}
- game_filect = GameDescs[game_n].gd_filect;
+ GameModule.game_number = game_n;
+ GameModule.gamedesc = &GameDescs[game_n];
+ game_filect = GameDescs[game_n].gd_filect;
+
GameModule.gfile_data = (GAME_FILEDATA *)malloc(game_filect * sizeof *GameModule.gfile_data);
if (GameModule.gfile_data == NULL) {
return MEM;
@@ -493,8 +541,6 @@ int LoadGame(uint16 game_n) {
GameModule.gd_fontdescs = GameDescs[game_n].gd_fontdescs;
// Finish initialization
- GameModule.game_number = game_n;
- GameModule.gamedesc = &GameDescs[game_n];
GameModule.game_init = 1;
return SUCCESS;
@@ -552,11 +598,11 @@ int GAME_GetSceneInfo(GAME_SCENEDESC *gs_desc) {
return SUCCESS;
}
-int GAME_GetGame() {
+GAME_IDS GAME_GetGame() {
return GameModule.gamedesc->gd_game_id;
}
-int GAME_GetGameType() {
+SAGAGameId GAME_GetGameType() {
return GameModule.gamedesc->gd_game_type;
}
diff --git a/saga/game.h b/saga/game.h
index d92a15dcc2..5fc021a535 100644
--- a/saga/game.h
+++ b/saga/game.h
@@ -47,8 +47,8 @@ struct GAME_FILEDESC {
struct GAMEDESC {
const char *name;
- int gd_game_type;
- uint32 gd_game_id;
+ SAGAGameId gd_game_type;
+ GAME_IDS gd_game_id;
const char *gd_title;
int gd_logical_w;
int gd_logical_h;
diff --git a/saga/game_mod.h b/saga/game_mod.h
index 3a8ba044e5..e9a522dd19 100644
--- a/saga/game_mod.h
+++ b/saga/game_mod.h
@@ -30,13 +30,18 @@
namespace Saga {
+#define IS_BIG_ENDIAN ((GAME_GetFeatures() & GF_BIG_ENDIAN_DATA) != 0)
+#define IS_MAC_VERSION (GAME_GetGame() == GAME_ITE_MACDEMO)
+
+
enum GAME_IDS {
GAME_ITE_DEMO = 0,
GAME_ITE_DISK = 1,
GAME_ITE_CD = 2,
GAME_IHNM_DEMO = 3,
GAME_IHNM_CD = 4,
- GAME_ITE_WINDEMO = 5
+ GAME_ITE_WINDEMO = 5,
+ GAME_ITE_MACDEMO = 6
};
enum GAME_FILETYPES {
@@ -68,7 +73,8 @@ enum GAME_FONT_IDS {
};
enum GAME_FEATURES {
- GF_VOX_VOICES = 1
+ GF_VOX_VOICES = 1,
+ GF_BIG_ENDIAN_DATA = 2
};
struct GAME_DISPLAYINFO {
@@ -109,11 +115,10 @@ int GAME_GetResourceInfo(GAME_RESOURCEDESC *);
int GAME_GetSoundInfo(GAME_SOUNDINFO *);
int GAME_GetDisplayInfo(GAME_DISPLAYINFO *);
int GAME_GetSceneInfo(GAME_SCENEDESC *);
-int GAME_GetGame();
-int GAME_GetGameType();
+GAME_IDS GAME_GetGame();
+SAGAGameId GAME_GetGameType();
DetectedGameList GAME_ProbeGame(const FSList &fslist);
uint32 GAME_GetFeatures();
-
} // End of namespace Saga
#endif
diff --git a/saga/ihnm_introproc.cpp b/saga/ihnm_introproc.cpp
index 6e3ea07e46..e95d3b6fd2 100644
--- a/saga/ihnm_introproc.cpp
+++ b/saga/ihnm_introproc.cpp
@@ -24,7 +24,6 @@
// "I Have No Mouth" Intro sequence scene procedures
#include "saga/saga.h"
-#include "saga/yslib.h"
#include "saga/gfx.h"
#include "saga/animation.h"
diff --git a/saga/image.cpp b/saga/image.cpp
index 7c98facc9c..d87a0e7f4f 100644
--- a/saga/image.cpp
+++ b/saga/image.cpp
@@ -27,6 +27,7 @@
#include "saga/game_mod.h"
#include "saga/image.h"
+#include "saga/stream.h"
namespace Saga {
@@ -64,13 +65,13 @@ int SagaEngine::decodeBGImage(const byte *image_data, size_t image_size,
return FAILURE;
}
- MemoryReadStream readS(image_data, image_size);
+ MemoryReadStreamEndian readS(image_data, image_size, IS_BIG_ENDIAN);
- hdr.width = readS.readUint16LE();
- hdr.height = readS.readUint16LE();
+ hdr.width = readS.readUint16();
+ hdr.height = readS.readUint16();
// The next four bytes of the image header aren't used.
- readS.readUint16LE();
- readS.readUint16LE();
+ readS.readUint16();
+ readS.readUint16();
RLE_data_ptr = image_data + SAGA_IMAGE_DATA_OFFSET;
RLE_data_len = image_size - SAGA_IMAGE_DATA_OFFSET;
diff --git a/saga/isomap.cpp b/saga/isomap.cpp
index 8b8397812b..c8cc4cde81 100644
--- a/saga/isomap.cpp
+++ b/saga/isomap.cpp
@@ -28,6 +28,7 @@
#include "saga/gfx.h"
#include "saga/isomap.h"
+#include "saga/stream.h"
namespace Saga {
@@ -46,10 +47,10 @@ int IsoMap::loadTileset(const byte *tileres_p, size_t tileres_len) {
assert((_init) && (!_tiles_loaded));
assert((tileres_p != NULL) && (tileres_len > 0));
- MemoryReadStream readS(tileres_p, tileres_len);
+ MemoryReadStreamEndian readS(tileres_p, tileres_len, IS_BIG_ENDIAN);
- readS.readUint16LE(); // skip
- first_entry.tile_offset = readS.readUint16LE();
+ readS.readUint16(); // skip
+ first_entry.tile_offset = readS.readUint16();
_tile_ct = first_entry.tile_offset / SAGA_ISOTILE_ENTRY_LEN;
@@ -63,9 +64,9 @@ int IsoMap::loadTileset(const byte *tileres_p, size_t tileres_len) {
for (i = 0; i < _tile_ct; i++) {
tile_tbl[i].tile_h = readS.readByte();
tile_tbl[i].mask_rule = readS.readByte();
- tile_tbl[i].tile_offset = readS.readUint16LE();
- tile_tbl[i].terrain_mask = readS.readSint16LE();
- tile_tbl[i].mask = readS.readSint16LE();
+ tile_tbl[i].tile_offset = readS.readUint16();
+ tile_tbl[i].terrain_mask = readS.readSint16();
+ tile_tbl[i].mask = readS.readSint16();
}
_tiles_loaded = 1;
@@ -85,7 +86,7 @@ int IsoMap::loadMetaTileset(const byte *mtileres_p, size_t mtileres_len) {
assert(_init);
assert((mtileres_p != NULL) && (mtileres_len > 0));
- MemoryReadStream readS(mtileres_p, mtileres_len);
+ MemoryReadStreamEndian readS(mtileres_p, mtileres_len, IS_BIG_ENDIAN);
mtile_ct = mtileres_len / SAGA_METATILE_ENTRY_LEN;
mtile_tbl = (ISO_METATILE_ENTRY *)malloc(mtile_ct * sizeof *mtile_tbl);
@@ -94,13 +95,13 @@ int IsoMap::loadMetaTileset(const byte *mtileres_p, size_t mtileres_len) {
}
for (ct = 0; ct < mtile_ct; ct++) {
- mtile_tbl[ct].mtile_n = readS.readUint16LE();
- mtile_tbl[ct].height = readS.readSint16LE();
- mtile_tbl[ct].highest_pixel = readS.readSint16LE();
+ mtile_tbl[ct].mtile_n = readS.readUint16();
+ mtile_tbl[ct].height = readS.readSint16();
+ mtile_tbl[ct].highest_pixel = readS.readSint16();
mtile_tbl[ct].v_bits = readS.readByte();
mtile_tbl[ct].u_bits = readS.readByte();
for (i = 0; i < SAGA_METATILE_SIZE; i++) {
- mtile_tbl[ct].tile_tbl[i] = readS.readUint16LE();
+ mtile_tbl[ct].tile_tbl[i] = readS.readUint16();
}
}
@@ -117,11 +118,11 @@ int IsoMap::loadMetaTileset(const byte *mtileres_p, size_t mtileres_len) {
int IsoMap::loadMetamap(const byte *mm_res_p, size_t mm_res_len) {
int i;
- MemoryReadStream readS(mm_res_p, mm_res_len);
- _metamap_n = readS.readSint16LE();
+ MemoryReadStreamEndian readS(mm_res_p, mm_res_len, IS_BIG_ENDIAN);
+ _metamap_n = readS.readSint16();
for (i = 0; i < SAGA_METAMAP_SIZE; i++) {
- _metamap_tbl[i] = readS.readUint16LE();
+ _metamap_tbl[i] = readS.readUint16();
}
_mm_res_p = mm_res_p;
diff --git a/saga/ite_introproc.cpp b/saga/ite_introproc.cpp
index 7050a4b196..9318b977a2 100644
--- a/saga/ite_introproc.cpp
+++ b/saga/ite_introproc.cpp
@@ -26,7 +26,6 @@
#include "saga/saga.h"
#include "saga/gfx.h"
-#include "saga/yslib.h"
#include "saga/animation.h"
#include "saga/events.h"
@@ -129,6 +128,7 @@ int Scene::ITEStartProc() {
SCENE_QUEUE first_scene;
GAME_SCENEDESC gs_desc;
+ int game_id = GAME_GetGame();
n_introscenes = ARRAYSIZE(ITE_IntroList);
for (i = 0; i < n_introscenes; i++) {
diff --git a/saga/list.h b/saga/list.h
new file mode 100644
index 0000000000..dbffc4176c
--- /dev/null
+++ b/saga/list.h
@@ -0,0 +1,154 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2004 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ *
+ */
+
+#ifndef SAGA_LIST_H__
+#define SAGA_LIST_H__
+
+#include "common/list.h"
+
+namespace Saga {
+
+
+template <class T>
+class SortedList : public Common::List<T> {
+public:
+ typedef int ( CompareFunction ) (const T& , const T&);
+
+ typedef typename Common::List<T>::iterator iterator;
+ typedef typename Common::List<T>::const_iterator const_iterator;
+
+public:
+
+ iterator pushFront(const T& element) {
+ return insert(begin(), element);
+ }
+
+ iterator pushBack(const T& element) {
+ return insert(end(), element);
+ }
+
+ iterator insert(iterator pos, const T& element) {
+ Common::List<T>::insert(pos, element);
+ return --pos;
+ }
+
+ iterator pushFront() {
+ return insert(begin());
+ }
+
+ iterator pushBack() {
+ return insert(end());
+ }
+
+ iterator insert(iterator pos) {
+ T init;
+ return insert(pos, init);
+ }
+
+ iterator pushFront(const T& element, CompareFunction* compareFunction) {
+ return insert(begin(), element, compareFunction);
+ }
+
+ iterator pushBack(const T& element, CompareFunction* compareFunction) {
+ return insert(end(), element, compareFunction);
+ }
+
+ iterator insert(iterator pos, const T& element, CompareFunction* compareFunction) {
+ int res;
+
+ for (iterator i = begin(); i != end(); ++i) {
+ res = compareFunction(element, i.operator*());
+ if (res < 0) {
+ return insert(i, element);
+ }
+ }
+ return pushBack(element);
+ }
+
+ void reorderUp(iterator pos, CompareFunction* compareFunction) {
+ iterator i(pos);
+ int res;
+
+ --i;
+ while (i != end()) {
+ res = compareFunction(i.operator*(), pos.operator*());
+ if (res <= 0) {
+
+ T temp(*pos);
+ erase(pos);
+ ++i;
+ Common::List<T>::insert(i, temp);
+ return;
+ }
+ --i;
+ }
+ }
+
+ void reorderDown(iterator pos, CompareFunction* compareFunction) {
+ iterator i(pos);
+ int res;
+
+ ++i;
+ while (i != end()) {
+ res = compareFunction(i.operator*(), pos.operator*());
+ if (res >= 0) {
+
+ T temp(*pos);
+ erase(pos);
+ Common::List<T>::insert(i, temp);
+ return;
+ }
+ ++i;
+ }
+ }
+
+ iterator eraseAndPrev(iterator pos) {
+ assert(pos != end());
+ iterator res(pos);
+
+ --res;
+ erase(pos);
+ return res;
+ }
+
+ void remove(const T* val) {
+ for (iterator i = begin(); i != end(); ++i)
+ if(val == i.operator->()) {
+ erase(i);
+ return;
+ }
+ }
+
+ bool locate(const T* val, iterator& foundedIterator) {
+
+ for (iterator i = begin(); i != end(); ++i)
+ if (val == i.operator->())
+ {
+ foundedIterator = i;
+ return true;
+ }
+
+ return false;
+ }
+};
+
+} // End of namespace Saga
+#endif
diff --git a/saga/music.cpp b/saga/music.cpp
index da4dce3681..dd10297b2c 100644
--- a/saga/music.cpp
+++ b/saga/music.cpp
@@ -25,6 +25,7 @@
#include "saga/music.h"
#include "saga/rscfile_mod.h"
#include "saga/game_mod.h"
+#include "saga/stream.h"
#include "sound/audiostream.h"
#include "sound/mididrv.h"
#include "sound/midiparser.h"
@@ -123,6 +124,7 @@ void RAWInputStream::refill() {
uint32 len_left;
byte *ptr = (byte *) _buf;
+
_file->seek(_file_pos, SEEK_SET);
@@ -137,6 +139,12 @@ void RAWInputStream::refill() {
if (len & 1)
len--;
+ if (GAME_GetFeatures() & GF_BIG_ENDIAN_DATA) {
+ uint16 *ptr16 = (uint16 *)ptr;
+ for (uint32 i = 0; i < (len / 2); i++)
+ ptr16[i] = TO_BE_16(ptr16[i]);
+ }
+
len_left -= len;
ptr += len;
@@ -292,6 +300,7 @@ Music::Music(SoundMixer *mixer, MidiDriver *driver, int enabled) : _mixer(mixer)
if (GAME_GetGameType() == GID_ITE) {
File file;
+ byte footerBuf[ARRAYSIZE(_digiTableITECD) * 8];
// The lookup table is stored at the end of music.rsc. I don't
// know why it has 27 elements, but the last one represents a
@@ -312,11 +321,17 @@ Music::Music(SoundMixer *mixer, MidiDriver *driver, int enabled) : _mixer(mixer)
_musicFname = RSC_FileName(_musicContext);
file.open(_musicFname);
+ assert(file.size() > sizeof(footerBuf));
+
file.seek(-ARRAYSIZE(_digiTableITECD) * 8, SEEK_END);
+ file.read(footerBuf, sizeof(footerBuf));
+
+ MemoryReadStreamEndian readS(footerBuf, sizeof(footerBuf), IS_BIG_ENDIAN);
+
for (int i = 0; i < ARRAYSIZE(_digiTableITECD); i++) {
- _digiTableITECD[i].start = file.readUint32LE();
- _digiTableITECD[i].length = file.readUint32LE();
+ _digiTableITECD[i].start = readS.readUint32();
+ _digiTableITECD[i].length = readS.readUint32();
}
file.close();
@@ -478,7 +493,7 @@ int Music::play(uint32 music_rn, uint16 flags) {
}
if (RSC_LoadResource(rsc_ctxt, music_rn, &resource_data,
- &resource_size) != SUCCESS ) {
+ &resource_size) != SUCCESS) {
warning("Music::play(): Resource load failed: %u", music_rn);
return FAILURE;
}
diff --git a/saga/objectmap.cpp b/saga/objectmap.cpp
index c5fe9782d7..b5d1e3102c 100644
--- a/saga/objectmap.cpp
+++ b/saga/objectmap.cpp
@@ -32,6 +32,8 @@
#include "saga/console.h"
#include "saga/font.h"
#include "saga/objectmap.h"
+#include "saga/game_mod.h"
+#include "saga/stream.h"
namespace Saga {
@@ -56,14 +58,14 @@ int ObjectMap::load(const byte *om_res, size_t om_res_len) {
int i, k, m;
- MemoryReadStream readS(om_res, om_res_len);
+ MemoryReadStreamEndian readS(om_res, om_res_len, IS_BIG_ENDIAN);
if (_objectsLoaded) {
freeMem();
}
// Obtain object count N and allocate space for N objects
- _nObjects = readS.readUint16LE();
+ _nObjects = readS.readUint16();
_objectMaps = (OBJECTMAP_ENTRY *)malloc(_nObjects * sizeof *_objectMaps);
@@ -79,8 +81,8 @@ int ObjectMap::load(const byte *om_res, size_t om_res_len) {
object_map->nClickareas = readS.readByte();
object_map->defaultVerb = readS.readByte();
readS.readByte();
- object_map->objectNum = readS.readUint16LE();
- object_map->scriptNum = readS.readUint16LE();
+ object_map->objectNum = readS.readUint16();
+ object_map->scriptNum = readS.readUint16();
object_map->clickareas = (CLICKAREA *)malloc(object_map->nClickareas * sizeof *(object_map->clickareas));
if (object_map->clickareas == NULL) {
@@ -103,8 +105,8 @@ int ObjectMap::load(const byte *om_res, size_t om_res_len) {
// Load all points for this clickarea
for (m = 0; m < clickarea->n_points; m++) {
point = &clickarea->points[m];
- point->x = readS.readSint16LE();
- point->y = readS.readSint16LE();
+ point->x = readS.readSint16();
+ point->y = readS.readSint16();
}
debug(2, "ObjectMap::load(): Read %d points for clickarea %d in object %d.",
clickarea->n_points, k, object_map->objectNum);
@@ -153,13 +155,13 @@ int ObjectMap::loadNames(const unsigned char *onl_res, size_t onl_res_len) {
int i;
- MemoryReadStream readS(onl_res, onl_res_len);
+ MemoryReadStreamEndian readS(onl_res, onl_res_len, IS_BIG_ENDIAN);
if (_namesLoaded) {
freeNames();
}
- table_len = readS.readUint16LE();
+ table_len = readS.readUint16();
n_names = table_len / 2 - 2;
_nNames = n_names;
@@ -173,7 +175,7 @@ int ObjectMap::loadNames(const unsigned char *onl_res, size_t onl_res_len) {
}
for (i = 0; i < n_names; i++) {
- name_offset = readS.readUint16LE();
+ name_offset = readS.readUint16();
_names[i] = (const char *)(onl_res + name_offset);
debug(3, "Loaded object name string: %s", _names[i]);
diff --git a/saga/palanim.cpp b/saga/palanim.cpp
index fb15019af4..3bb3ca6506 100644
--- a/saga/palanim.cpp
+++ b/saga/palanim.cpp
@@ -29,6 +29,7 @@
#include "saga/game_mod.h"
#include "saga/palanim.h"
+#include "saga/stream.h"
namespace Saga {
@@ -54,13 +55,13 @@ int PalAnim::loadPalAnim(const byte *resdata, size_t resdata_len) {
return FAILURE;
}
- MemoryReadStream readS(resdata, resdata_len);
+ MemoryReadStreamEndian readS(resdata, resdata_len, IS_BIG_ENDIAN);
if (GAME_GetGameType() == GID_IHNM) {
return SUCCESS;
}
- _entryCount = readS.readUint16LE();
+ _entryCount = readS.readUint16();
debug(0, "PalAnim::loadPalAnim(): Loading %d PALANIM entries.", _entryCount);
@@ -77,8 +78,8 @@ int PalAnim::loadPalAnim(const byte *resdata, size_t resdata_len) {
int pal_count;
int p, c;
- color_count = readS.readUint16LE();
- pal_count = readS.readUint16LE();
+ color_count = readS.readUint16();
+ pal_count = readS.readUint16();
_entries[i].pal_count = pal_count;
_entries[i].color_count = color_count;
diff --git a/saga/resnames.h b/saga/resnames.h
index fb4bc0f3d3..ea9f0f07e4 100644
--- a/saga/resnames.h
+++ b/saga/resnames.h
@@ -29,6 +29,7 @@
namespace Saga {
// Lookup tables
+#define ITEMACDEMO_SCENE_LUT 1804
#define ITE_SCENE_LUT 1806
#define ITE_SCRIPT_LUT 216
@@ -57,6 +58,7 @@ namespace Saga {
#define ITE_DEFAULT_PORTRAITS 125
// ITE Scene resource numbers
+#define ITEMACDEMO_INTRO_ANIM_SCENE 1536
#define ITE_INTRO_ANIM_SCENE 1538
#define ITE_CAVE_SCENE_1 1542
#define ITE_CAVE_SCENE_2 1545
diff --git a/saga/rscfile.cpp b/saga/rscfile.cpp
index 929c1c5f6e..cbfa60b484 100644
--- a/saga/rscfile.cpp
+++ b/saga/rscfile.cpp
@@ -26,6 +26,8 @@
#include "saga/rscfile_mod.h"
#include "saga/rscfile.h"
+#include "saga/game_mod.h"
+#include "saga/stream.h"
namespace Saga {
@@ -113,11 +115,11 @@ int RSC_LoadRSC(RSCFILE_CONTEXT *rsc) {
if (rsc->rc_file->read(tblinfo_buf, RSC_TABLEINFO_SIZE) != RSC_TABLEINFO_SIZE) {
return FAILURE;
}
+
+ MemoryReadStreamEndian readS(tblinfo_buf, RSC_TABLEINFO_SIZE, IS_BIG_ENDIAN);
- MemoryReadStream readS(tblinfo_buf, RSC_TABLEINFO_SIZE);
-
- res_tbl_offset = readS.readUint32LE();
- res_tbl_ct = readS.readUint32LE();
+ res_tbl_offset = readS.readUint32();
+ res_tbl_ct = readS.readUint32();
// Check for sane table offset
if (res_tbl_offset != rsc->rc_file->size() - RSC_TABLEINFO_SIZE - RSC_TABLEENTRY_SIZE * res_tbl_ct) {
@@ -146,11 +148,13 @@ int RSC_LoadRSC(RSCFILE_CONTEXT *rsc) {
return FAILURE;
}
- MemoryReadStream readS1(tbl_buf, tbl_len);
+ MemoryReadStreamEndian readS1(tbl_buf, tbl_len, IS_BIG_ENDIAN);
+ debug(9, "RSC %s", rsc->rc_file_fspec);
for (i = 0; i < res_tbl_ct; i++) {
- rsc_restbl[i].res_offset = readS1.readUint32LE();
- rsc_restbl[i].res_size = readS1.readUint32LE();
+ rsc_restbl[i].res_offset = readS1.readUint32();
+ rsc_restbl[i].res_size = readS1.readUint32();
+ //debug(9, "#%x Offset:%x Size:%x", i, rsc_restbl[i].res_offset, rsc_restbl[i].res_size);
if ((rsc_restbl[i].res_offset > rsc->rc_file->size()) || (rsc_restbl[i].res_size > rsc->rc_file->size())) {
free(tbl_buf);
free(rsc_restbl);
@@ -258,4 +262,18 @@ int RSC_FreeResource(byte *resource_ptr) {
return SUCCESS;
}
+int RSC_ConvertID(int id) {
+ int res = id;
+
+ if (IS_MAC_VERSION) {
+ if (res > 1537)
+ res -= 2;
+ else if (res == 1535 || res == 1536) {
+ error ("Wrong resource number %d for Mac ITE");
+ }
+ }
+
+ return res;
+}
+
} // End of namespace Saga
diff --git a/saga/rscfile_mod.h b/saga/rscfile_mod.h
index 4bcf7ce32c..b8c3f88fc2 100644
--- a/saga/rscfile_mod.h
+++ b/saga/rscfile_mod.h
@@ -40,6 +40,7 @@ int RSC_GetResourceOffset(RSCFILE_CONTEXT *, uint32, uint32 *);
int RSC_LoadResource(RSCFILE_CONTEXT *, uint32, byte **, size_t *);
int RSC_FreeResource(byte *);
const char *RSC_FileName(RSCFILE_CONTEXT *rsc);
+int RSC_ConvertID(int id);
} // End of namespace Saga
diff --git a/saga/saga.h b/saga/saga.h
index 7a7abe765b..04b301eaba 100644
--- a/saga/saga.h
+++ b/saga/saga.h
@@ -58,7 +58,6 @@ class Console;
class Events;
class PalAnim;
-using Common::MemoryReadStream;
#define PBOUNDS(n,max) (((n)>=(0))&&((n)<(max)))
#define MAXPATH 512
diff --git a/saga/scene.cpp b/saga/scene.cpp
index b001752730..6b81fa16fe 100644
--- a/saga/scene.cpp
+++ b/saga/scene.cpp
@@ -23,7 +23,6 @@
// Scene management module
#include "saga/saga.h"
-#include "saga/yslib.h"
#include "saga/gfx.h"
#include "saga/game_mod.h"
@@ -43,6 +42,7 @@
#include "saga/music.h"
#include "saga/scene.h"
+#include "saga/stream.h"
namespace Saga {
@@ -63,11 +63,6 @@ Scene::Scene(SagaEngine *vm) : _vm(vm), _initialized(false) {
return;
}
- // Initialize scene queue
- _sceneQueue = ys_dll_create();
- if (_sceneQueue == NULL) {
- return;
- }
// Load scene lookup table
debug(0, "Loading scene LUT from resource %u.", gs_desc.scene_lut_rn);
@@ -76,7 +71,10 @@ Scene::Scene(SagaEngine *vm) : _vm(vm), _initialized(false) {
warning("Scene::Scene(): Error: couldn't load scene LUT");
return;
}
-
+ if (scene_lut_len==0) {
+ warning("Scene::Scene(): scene_lut_len==0");
+ return;
+ }
_sceneCount = scene_lut_len / 2;
_sceneMax = _sceneCount - 1;
_sceneLUT = (int *)malloc(_sceneMax * sizeof *_sceneLUT);
@@ -85,10 +83,10 @@ Scene::Scene(SagaEngine *vm) : _vm(vm), _initialized(false) {
return;
}
- MemoryReadStream readS(scene_lut_p, scene_lut_len);
+ MemoryReadStreamEndian readS(scene_lut_p, scene_lut_len, IS_BIG_ENDIAN);
for (i = 0; i < _sceneMax; i++) {
- _sceneLUT[i] = readS.readUint16LE();
+ _sceneLUT[i] = readS.readUint16();
}
free(scene_lut_p);
@@ -119,7 +117,6 @@ Scene::Scene(SagaEngine *vm) : _vm(vm), _initialized(false) {
_resListEntries = 0;
_resList = NULL;
_animEntries = 0;
- _animList = NULL;
_sceneProc = NULL;
_objectMap = NULL;
_actionMap = NULL;
@@ -140,21 +137,20 @@ int Scene::queueScene(SCENE_QUEUE *scene_queue) {
assert(_initialized);
assert(scene_queue != NULL);
- ys_dll_add_tail(_sceneQueue, scene_queue, sizeof *scene_queue);
-
+ _sceneQueue.push_back(*scene_queue);
return SUCCESS;
}
int Scene::clearSceneQueue() {
assert(_initialized);
- ys_dll_delete_all(_sceneQueue);
+ _sceneQueue.clear();
return SUCCESS;
}
int Scene::startScene() {
- YS_DL_NODE *node;
+ SceneQueueList::iterator queueIterator;
SCENE_QUEUE *scene_qdat;
EVENT event;
@@ -188,13 +184,13 @@ int Scene::startScene() {
break;
}
- // Load the head node in scene queue
- node = ys_dll_head(_sceneQueue);
- if (node == NULL) {
+ // Load the head in scene queue
+ queueIterator = _sceneQueue.begin();
+ if (queueIterator == _sceneQueue.end()) {
return SUCCESS;
}
- scene_qdat = (SCENE_QUEUE *)ys_dll_get_data(node);
+ scene_qdat = queueIterator.operator->();
assert(scene_qdat != NULL);
loadScene(scene_qdat->scene_n, scene_qdat->load_flag, scene_qdat->scene_proc, scene_qdat->scene_desc, scene_qdat->fadeType);
@@ -203,7 +199,7 @@ int Scene::startScene() {
}
int Scene::nextScene() {
- YS_DL_NODE *node;
+ SceneQueueList::iterator queueIterator;
SCENE_QUEUE *scene_qdat;
assert(_initialized);
@@ -220,32 +216,29 @@ int Scene::nextScene() {
endScene();
- // Delete the current head node in scene queue
- node = ys_dll_head(_sceneQueue);
- if (node == NULL) {
+ // Delete the current head in scene queue
+ queueIterator = _sceneQueue.begin();
+ if (queueIterator == _sceneQueue.end()) {
return SUCCESS;
}
+
+ queueIterator = _sceneQueue.erase(queueIterator);
- ys_dll_delete(node);
-
- // Load the head node in scene queue
- node = ys_dll_head(_sceneQueue);
- if (node == NULL) {
+ if (queueIterator == _sceneQueue.end()) {
return SUCCESS;
}
- scene_qdat = (SCENE_QUEUE *)ys_dll_get_data(node);
+ // Load the head in scene queue
+ scene_qdat = queueIterator.operator->();
assert(scene_qdat != NULL);
- loadScene(scene_qdat->scene_n, scene_qdat->load_flag, scene_qdat->scene_proc, scene_qdat->scene_desc, scene_qdat->fadeType);
+ loadScene(RSC_ConvertID(scene_qdat->scene_n), scene_qdat->load_flag, scene_qdat->scene_proc, scene_qdat->scene_desc, scene_qdat->fadeType);
return SUCCESS;
}
int Scene::skipScene() {
- YS_DL_NODE *node;
- YS_DL_NODE *prev_node;
- YS_DL_NODE *skip_node = NULL;
+ SceneQueueList::iterator queueIterator;
SCENE_QUEUE *scene_qdat = NULL;
SCENE_QUEUE *skip_qdat = NULL;
@@ -263,29 +256,28 @@ int Scene::skipScene() {
}
// Walk down scene queue and try to find a skip target
- node = ys_dll_head(_sceneQueue);
- if (node == NULL) {
+ queueIterator = _sceneQueue.begin();
+ if (queueIterator == _sceneQueue.end()) {
warning("Scene::skip(): Error: Can't skip scene...no scenes in queue");
return FAILURE;
}
- for (node = ys_dll_next(node); node != NULL; node = ys_dll_next(node)) {
- scene_qdat = (SCENE_QUEUE *)ys_dll_get_data(node);
+ ++queueIterator;
+ while (queueIterator != _sceneQueue.end()) {
+ scene_qdat = queueIterator.operator->();
assert(scene_qdat != NULL);
if (scene_qdat->scene_skiptarget) {
- skip_node = node;
skip_qdat = scene_qdat;
break;
}
+ ++queueIterator;
}
// If skip target found, remove preceding scenes and load
- if (skip_node != NULL) {
- for (node = ys_dll_prev(skip_node); node != NULL; node = prev_node) {
- prev_node = ys_dll_prev(node);
- ys_dll_delete(node);
- }
+ if (skip_qdat != NULL) {
+ _sceneQueue.erase(_sceneQueue.begin(), queueIterator);
+
endScene();
loadScene(skip_qdat->scene_n, skip_qdat->load_flag, skip_qdat->scene_proc, skip_qdat->scene_desc, skip_qdat->fadeType);
}
@@ -419,7 +411,6 @@ int Scene::loadScene(int scene_num, int load_flag, SCENE_PROC scene_proc, SCENE_
return FAILURE;
}
- _animList = ys_dll_create();
_sceneMode = 0;
_loadDesc = true;
@@ -576,21 +567,16 @@ int Scene::loadSceneDescriptor(uint32 res_number) {
return FAILURE;
}
- if (scene_desc_len != SAGA_SCENE_DESC_LEN) {
- warning("Scene::loadSceneDescriptor(): Error: scene descriptor length invalid");
- return FAILURE;
- }
-
- MemoryReadStream readS(scene_desc_data, scene_desc_len);
+ MemoryReadStreamEndian readS(scene_desc_data, scene_desc_len, IS_BIG_ENDIAN);
- _desc.flags = readS.readSint16LE();
- _desc.resListRN = readS.readSint16LE();
- _desc.endSlope = readS.readSint16LE();
- _desc.beginSlope = readS.readSint16LE();
- _desc.scriptNum = readS.readUint16LE();
- _desc.sceneScriptNum = readS.readUint16LE();
- _desc.startScriptNum = readS.readUint16LE();
- _desc.musicRN = readS.readSint16LE();
+ _desc.flags = readS.readSint16();
+ _desc.resListRN = readS.readSint16();
+ _desc.endSlope = readS.readSint16();
+ _desc.beginSlope = readS.readSint16();
+ _desc.scriptNum = readS.readUint16();
+ _desc.sceneScriptNum = readS.readUint16();
+ _desc.startScriptNum = readS.readUint16();
+ _desc.musicRN = readS.readSint16();
RSC_FreeResource(scene_desc_data);
@@ -610,7 +596,7 @@ int Scene::loadSceneResourceList(uint32 reslist_rn) {
return FAILURE;
}
- MemoryReadStream readS(resource_list, resource_list_len);
+ MemoryReadStreamEndian readS(resource_list, resource_list_len, IS_BIG_ENDIAN);
// Allocate memory for scene resource list
_resListEntries = resource_list_len / SAGA_RESLIST_ENTRY_LEN;
@@ -627,8 +613,8 @@ int Scene::loadSceneResourceList(uint32 reslist_rn) {
debug(0, "Loading scene resource list...");
for (i = 0; i < _resListEntries; i++) {
- _resList[i].res_number = readS.readUint16LE();
- _resList[i].res_type = readS.readUint16LE();
+ _resList[i].res_number = readS.readUint16();
+ _resList[i].res_type = readS.readUint16();
}
RSC_FreeResource(resource_list);
@@ -754,26 +740,22 @@ int Scene::processSceneResources() {
case SAGA_ANIM_6:
case SAGA_ANIM_7:
{
- SCENE_ANIMINFO *new_animinfo;
uint16 new_anim_id;
debug(0, "Loading animation resource...");
- new_animinfo = (SCENE_ANIMINFO *)malloc(sizeof *new_animinfo);
- if (new_animinfo == NULL) {
- warning("Scene::ProcessSceneResources(): Memory allocation error");
- return MEM;
- }
-
if (_vm->_anim->load(_resList[i].res_data,
_resList[i].res_data_len, &new_anim_id) != SUCCESS) {
warning("Scene::ProcessSceneResources(): Error loading animation resource");
return FAILURE;
}
+ SCENE_ANIMINFO *new_animinfo;
+
+ new_animinfo = _animList.pushBack().operator->();
+
new_animinfo->anim_handle = new_anim_id;
new_animinfo->anim_res_number = _resList[i].res_number;
- ys_dll_add_tail(_animList, new_animinfo, sizeof *new_animinfo);
_animEntries++;
}
break;
@@ -874,7 +856,7 @@ int Scene::endScene() {
_objectMap = NULL;
_actionMap = NULL;
- ys_dll_destroy(_animList);
+ _animList.clear();
_animEntries = 0;
diff --git a/saga/scene.h b/saga/scene.h
index b4124573a4..3f821e460f 100644
--- a/saga/scene.h
+++ b/saga/scene.h
@@ -27,6 +27,7 @@
#define SAGA_SCENE_H
#include "saga/text.h"
+#include "saga/list.h"
namespace Saga {
@@ -136,9 +137,11 @@ struct SCENE_IMAGE {
struct SCENE_ANIMINFO {
int anim_res_number;
int anim_handle;
- SCENE_ANIMINFO *next;
+ //SCENE_ANIMINFO *next;
};
+typedef SortedList<SCENE_ANIMINFO> SceneAnimInfoList;
+
enum SCENE_FADE_TYPES {
SCENE_NOFADE = 0,
SCENE_FADE = 1,
@@ -154,6 +157,8 @@ struct SCENE_QUEUE {
int fadeType;
};
+typedef Common::List<SCENE_QUEUE> SceneQueueList;
+
///// IHNM-specific stuff
#define IHNM_PALFADE_TIME 1000
#define IHNM_INTRO_FRAMETIME 80
@@ -258,7 +263,7 @@ class Scene {
int *_sceneLUT;
int _sceneCount;
int _sceneMax;
- YS_DL_LIST *_sceneQueue;
+ SceneQueueList _sceneQueue;
int _firstScene;
bool _sceneLoaded;
int _sceneMode;
@@ -270,7 +275,7 @@ class Scene {
int _resListEntries;
SCENE_RESLIST *_resList;
int _animEntries;
- YS_DL_LIST *_animList;
+ SceneAnimInfoList _animList;
SCENE_PROC *_sceneProc;
TEXTLIST *_textList;
SCENE_IMAGE _bg;
diff --git a/saga/script.cpp b/saga/script.cpp
index 228b8f2191..fe4efa1fe4 100644
--- a/saga/script.cpp
+++ b/saga/script.cpp
@@ -23,7 +23,6 @@
// Scripting module: Script resource handling functions
#include "saga/saga.h"
-#include "saga/yslib.h"
#include "saga/gfx.h"
#include "saga/rscfile_mod.h"
@@ -31,6 +30,7 @@
#include "saga/console.h"
#include "saga/script.h"
+#include "saga/stream.h"
namespace Saga {
@@ -51,7 +51,6 @@ Script::Script() {
_voiceLUTPresent = false;
_scriptLUTEntryLen = 0;
_currentScript = 0;
- _threadList = 0;
_abortEnabled = true;
_skipSpeeches = false;
memset(_dataBuf, 0, sizeof(_dataBuf));
@@ -98,12 +97,12 @@ Script::Script() {
}
// Convert LUT resource to logical LUT
- MemoryReadStream scriptS(rsc_ptr, rsc_len);
+ MemoryReadStreamEndian scriptS(rsc_ptr, rsc_len, IS_BIG_ENDIAN);
for (i = 0; i < _scriptLUTMax; i++) {
prevTell = scriptS.pos();
- _scriptLUT[i].script_rn = scriptS.readUint16LE();
- _scriptLUT[i].diag_list_rn = scriptS.readUint16LE();
- _scriptLUT[i].voice_lut_rn = scriptS.readUint16LE();
+ _scriptLUT[i].script_rn = scriptS.readUint16();
+ _scriptLUT[i].diag_list_rn = scriptS.readUint16();
+ _scriptLUT[i].voice_lut_rn = scriptS.readUint16();
// Skip the unused portion of the structure
for (j = scriptS.pos(); j < prevTell + _scriptLUTEntryLen; j++) {
@@ -122,8 +121,6 @@ Script::Script() {
}
}
- // Initialize script submodules
- _threadList = ys_dll_create();
setupScriptFuncList();
@@ -132,8 +129,6 @@ Script::Script() {
// Shut down script module gracefully; free all allocated module resources
Script::~Script() {
- YS_DL_NODE *thread_node;
- SCRIPT_THREAD *thread;
if (!_initialized) {
error("Script not initialized");
@@ -143,15 +138,7 @@ Script::~Script() {
// Free script lookup table
free(_scriptLUT);
-
- // Stop all threads and destroy them
-
- for (thread_node = ys_dll_head(_threadList); thread_node != NULL;
- thread_node = ys_dll_next(thread_node)) {
- thread = (SCRIPT_THREAD *)ys_dll_get_data(thread_node);
- SThreadDestroy(thread);
- }
-
+
_initialized = false;
}
@@ -322,12 +309,14 @@ SCRIPT_BYTECODE *Script::loadBytecode(byte *bytecode_p, size_t bytecode_len) {
debug(0, "Loading script bytecode...");
- MemoryReadStream scriptS(bytecode_p, bytecode_len);
+ MemoryReadStreamEndian scriptS(bytecode_p, bytecode_len, IS_BIG_ENDIAN);
// The first two uint32 values are the number of entrypoints, and the
// offset to the entrypoint table, respectively.
- n_entrypoints = scriptS.readUint32LE();
- ep_tbl_offset = scriptS.readUint32LE();
+ n_entrypoints = scriptS.readUint16();
+ scriptS.readUint16(); //skip
+ ep_tbl_offset = scriptS.readUint16();
+ scriptS.readUint16(); //skip
// Check that the entrypoint table offset is valid.
if ((bytecode_len - ep_tbl_offset) < (n_entrypoints * SCRIPT_TBLENTRY_LEN)) {
@@ -365,8 +354,8 @@ SCRIPT_BYTECODE *Script::loadBytecode(byte *bytecode_p, size_t bytecode_len) {
// First uint16 is the offset of the entrypoint name from the start
// of the bytecode resource, second uint16 is the offset of the
// bytecode itself for said entrypoint
- bc_ep_tbl[i].name_offset = scriptS.readUint16LE();
- bc_ep_tbl[i].offset = scriptS.readUint16LE();
+ bc_ep_tbl[i].name_offset = scriptS.readUint16();
+ bc_ep_tbl[i].offset = scriptS.readUint16();
// Perform a simple range check on offset values
if ((bc_ep_tbl[i].name_offset > bytecode_len) || (bc_ep_tbl[i].offset > bytecode_len)) {
@@ -403,10 +392,10 @@ DIALOGUE_LIST *Script::loadDialogue(const byte *dialogue_p, size_t dialogue_len)
return NULL;
}
- MemoryReadStream scriptS(dialogue_p, dialogue_len);
+ MemoryReadStreamEndian scriptS(dialogue_p, dialogue_len, IS_BIG_ENDIAN);
// First uint16 is the offset of the first string
- offset = scriptS.readUint16LE();
+ offset = scriptS.readUint16();
if (offset > dialogue_len) {
warning("Error, invalid string offset");
return NULL;
@@ -434,7 +423,7 @@ DIALOGUE_LIST *Script::loadDialogue(const byte *dialogue_p, size_t dialogue_len)
// Read in tables from dialogue list resource
scriptS.seek(0);
for (i = 0; i < n_dialogue; i++) {
- offset = scriptS.readUint16LE();
+ offset = scriptS.readUint16();
if (offset > dialogue_len) {
warning("Error, invalid string offset");
free(dialogue_list->str);
@@ -474,10 +463,10 @@ VOICE_LUT *Script::loadVoiceLUT(const byte *voicelut_p, size_t voicelut_len, SCR
return NULL;
}
- MemoryReadStream scriptS(voicelut_p, voicelut_len);
+ MemoryReadStreamEndian scriptS(voicelut_p, voicelut_len, IS_BIG_ENDIAN);
for (i = 0; i < n_voices; i++) {
- voice_lut->voices[i] = scriptS.readUint16LE();
+ voice_lut->voices[i] = scriptS.readUint16();
}
return voice_lut;
diff --git a/saga/script.h b/saga/script.h
index 6777393c55..2e36dd87cb 100644
--- a/saga/script.h
+++ b/saga/script.h
@@ -27,7 +27,7 @@
#define SAGA_SCRIPT_H
#include "saga/text.h"
-#include "saga/yslib.h"
+#include "saga/list.h"
namespace Saga {
@@ -135,8 +135,12 @@ struct SCRIPT_THREAD {
assert(stackPtr < ARRAYSIZE(stackBuf));
return stackBuf[stackPtr++];
}
+
+ SCRIPT_THREAD() { memset(this, 0, sizeof(*this)); }
};
+typedef SortedList<SCRIPT_THREAD> ScriptThreadList;
+
struct PROC_TBLENTRY {
size_t name_offset;
size_t offset;
@@ -200,7 +204,7 @@ public:
SCRIPTDATA *currentScript() { return _currentScript; }
void setBuffer(int idx, SCRIPT_DATABUF *ptr) { _dataBuf[idx] = ptr; }
SCRIPT_DATABUF *dataBuffer(int idx) { return _dataBuf[idx]; }
- YS_DL_LIST *threadList() { return _threadList; }
+// YS_DL_LIST *threadList() { return _threadList; }
void scriptInfo();
void scriptExec(int argc, const char **argv);
@@ -214,7 +218,7 @@ protected:
uint16 _scriptLUTEntryLen;
SCRIPTDATA *_currentScript;
SCRIPT_DATABUF *_dataBuf[SCRIPT_DATABUF_NUM];
- YS_DL_LIST *_threadList;
+ ScriptThreadList _threadList;
bool _skipSpeeches;
bool _abortEnabled;
diff --git a/saga/sdebug.cpp b/saga/sdebug.cpp
index 2064533758..51ddab4305 100644
--- a/saga/sdebug.cpp
+++ b/saga/sdebug.cpp
@@ -30,11 +30,13 @@
#include "saga/font.h"
#include "saga/script.h"
+#include "saga/game_mod.h"
+#include "saga/stream.h"
namespace Saga {
#define SD_DISPLAY_LEN 128
-#define SD_ADDTXT( x ) strncat( disp_buf, x, SD_DISPLAY_LEN );
+#define SD_ADDTXT(x) strncat(disp_buf, x, SD_DISPLAY_LEN);
int Script::SDebugPrintInstr(SCRIPT_THREAD *thread) {
TEXTLIST_ENTRY tl_e;
@@ -64,10 +66,10 @@ int Script::SDebugPrintInstr(SCRIPT_THREAD *thread) {
tl_e.string = disp_buf;
tl_e.display = 1;
- MemoryReadStream readS(currentScript()->bytecode->bytecode_p
+ MemoryReadStream/*Endian*/ readS(currentScript()->bytecode->bytecode_p
+ thread->i_offset,
currentScript()->bytecode->bytecode_len
- - thread->i_offset);
+ - thread->i_offset/*, IS_BIG_ENDIAN*/);
in_char = readS.readByte();
sprintf(tmp_buf, "%04lX | %02X | ", thread->i_offset, in_char);
strncat(disp_buf, tmp_buf, SD_DISPLAY_LEN);
@@ -103,11 +105,11 @@ int Script::SDebugPrintInstr(SCRIPT_THREAD *thread) {
sprintf(tmp_buf, "%02X", param);
SD_ADDTXT(tmp_buf);
/*
- if(( param >= 0 ) && ( param < diag_list->n_dialogue )) {
- debug(2, " ; \"%.*s\"", SCRIPT_STRINGLIMIT, diag_list->str[param] );
+ if((param >= 0) && (param < diag_list->n_dialogue)) {
+ debug(2, " ; \"%.*s\"", SCRIPT_STRINGLIMIT, diag_list->str[param]);
}
else {
- debug(2, " ; Invalid dialogue string.\n" );
+ debug(2, " ; Invalid dialogue string.\n");
}
*/
}
@@ -243,9 +245,9 @@ int Script::SDebugPrintInstr(SCRIPT_THREAD *thread) {
sprintf(tmp_buf, "%04X ", param);
SD_ADDTXT(tmp_buf);
/*
- for( i = 0 ; i < script_list->n_scripts ; i++ ) {
- if( op_offset == script_list->scripts[i].offset ) {
- debug(2, "; Entrypoint \"%s\".", script_list->scriptl_p + script_list->scripts[i].name_offset );
+ for(i = 0 ; i < script_list->n_scripts ; i++) {
+ if(op_offset == script_list->scripts[i].offset) {
+ debug(2, "; Entrypoint \"%s\".", script_list->scriptl_p + script_list->scripts[i].name_offset);
break;
}
}
@@ -328,10 +330,10 @@ int Script::SDebugPrintInstr(SCRIPT_THREAD *thread) {
for (i = 0; i < n_switch; i++) {
switch_num = readS.readUint16LE();
switch_jmp = readS.readUint16LE();
- // printf( TAB "CASE %04X, %04X\n", switch_num, switch_jmp);
+ // printf(TAB "CASE %04X, %04X\n", switch_num, switch_jmp);
}
default_jmp = readS.readUint16LE();
- //printf( TAB "DEF %04X", default_jmp);
+ //printf(TAB "DEF %04X", default_jmp);
}
break;
// Random branch
diff --git a/saga/sndres.cpp b/saga/sndres.cpp
index da94ec664e..38e1fdfcae 100644
--- a/saga/sndres.cpp
+++ b/saga/sndres.cpp
@@ -30,6 +30,7 @@
#include "saga/sndres.h"
#include "saga/sound.h"
+#include "saga/stream.h"
#include "common/file.h"
@@ -175,7 +176,7 @@ int SndRes::load(RSCFILE_CONTEXT *snd_ctxt, uint32 snd_rn, SOUNDBUFFER *snd_buf_
}
int SndRes::loadVocSound(byte *snd_res, size_t snd_res_len, SOUNDBUFFER *snd_buf_i) {
- MemoryReadStream readS(snd_res, snd_res_len);
+ MemoryReadStreamEndian readS(snd_res, snd_res_len, IS_BIG_ENDIAN);
byte *data;
int rate;
int len;
@@ -188,11 +189,11 @@ int SndRes::loadVocSound(byte *snd_res, size_t snd_res_len, SOUNDBUFFER *snd_buf
snd_buf_i->s_freq = rate;
snd_buf_i->s_samplebits = 8;
- snd_buf_i->s_stereo = 0;
+ snd_buf_i->s_stereo = 0;
snd_buf_i->s_signed = 0;
snd_buf_i->s_buf = data;
snd_buf_i->s_buf_len = len;
-
+
return SUCCESS;
}
@@ -200,7 +201,7 @@ int SndRes::loadVocSound(byte *snd_res, size_t snd_res_len, SOUNDBUFFER *snd_buf
int SndRes::loadWavSound(byte *snd_res, size_t snd_res_len, SOUNDBUFFER *snd_buf_i) {
// TODO: This function should, perhaps, be made more robust.
- MemoryReadStream readS(snd_res, snd_res_len);
+ MemoryReadStreamEndian readS(snd_res, snd_res_len, IS_BIG_ENDIAN);
byte buf[4];
@@ -209,7 +210,7 @@ int SndRes::loadWavSound(byte *snd_res, size_t snd_res_len, SOUNDBUFFER *snd_buf
return FAILURE;
}
- readS.readUint32LE();
+ readS.readUint32();
readS.read(buf, sizeof(buf));
if (memcmp(buf, "WAVE", sizeof(buf)) != 0) {
@@ -221,13 +222,13 @@ int SndRes::loadWavSound(byte *snd_res, size_t snd_res_len, SOUNDBUFFER *snd_buf
return FAILURE;
}
- uint32 len = readS.readUint32LE();
+ uint32 len = readS.readUint32();
uint32 pos = readS.pos();
- readS.readUint16LE();
+ readS.readUint16();
- snd_buf_i->s_stereo = (readS.readUint16LE() == 2) ? 1 : 0;
- snd_buf_i->s_freq = readS.readUint16LE();
+ snd_buf_i->s_stereo = (readS.readUint16() == 2) ? 1 : 0;
+ snd_buf_i->s_freq = readS.readUint16();
snd_buf_i->s_samplebits = 16;
snd_buf_i->s_signed = 1;
@@ -239,11 +240,11 @@ int SndRes::loadWavSound(byte *snd_res, size_t snd_res_len, SOUNDBUFFER *snd_buf
break;
}
- len = readS.readUint32LE();
+ len = readS.readUint32();
readS.seek(len, SEEK_CUR);
}
- snd_buf_i->s_buf_len = readS.readUint32LE();
+ snd_buf_i->s_buf_len = readS.readUint32();
byte *data = (byte *)malloc(snd_buf_i->s_buf_len);
if (!data) {
diff --git a/saga/sprite.cpp b/saga/sprite.cpp
index 96631006e9..0e0645d2dc 100644
--- a/saga/sprite.cpp
+++ b/saga/sprite.cpp
@@ -33,6 +33,7 @@
#include "saga/font.h"
#include "saga/sprite.h"
+#include "saga/stream.h"
namespace Saga {
@@ -81,9 +82,9 @@ int Sprite::loadList(int resource_num, SPRITELIST **sprite_list_p) {
return FAILURE;
}
- MemoryReadStream readS(spritelist_data, spritelist_len);
+ MemoryReadStreamEndian readS(spritelist_data, spritelist_len, IS_BIG_ENDIAN);
- sprite_count = readS.readUint16LE();
+ sprite_count = readS.readUint16();
new_slist->sprite_count = sprite_count;
@@ -95,7 +96,7 @@ int Sprite::loadList(int resource_num, SPRITELIST **sprite_list_p) {
for (i = 0; i < sprite_count; i++) {
new_slist->offset_list[i].data_idx = 0;
- new_slist->offset_list[i].offset = readS.readUint16LE();
+ new_slist->offset_list[i].offset = readS.readUint16();
}
new_slist->slist_rn = resource_num;
@@ -124,9 +125,9 @@ int Sprite::appendList(int resource_num, SPRITELIST *spritelist) {
return FAILURE;
}
- MemoryReadStream readS(spritelist_data, spritelist_len);
+ MemoryReadStreamEndian readS(spritelist_data, spritelist_len, IS_BIG_ENDIAN);
- sprite_count = readS.readUint16LE();
+ sprite_count = readS.readUint16();
old_sprite_count = spritelist->sprite_count;
new_sprite_count = spritelist->sprite_count + sprite_count;
@@ -143,7 +144,7 @@ int Sprite::appendList(int resource_num, SPRITELIST *spritelist) {
for (i = old_sprite_count; i < spritelist->sprite_count; i++) {
spritelist->offset_list[i].data_idx = spritelist->append_count;
- spritelist->offset_list[i].offset = readS.readUint16LE();
+ spritelist->offset_list[i].offset = readS.readUint16();
}
spritelist->sprite_data[spritelist->append_count] = spritelist_data;
@@ -194,7 +195,8 @@ int Sprite::draw(SURFACE *ds, SPRITELIST *sprite_list, int sprite_num, int spr_x
sprite_p = sprite_list->sprite_data[offset_idx];
sprite_p += offset;
- MemoryReadStream readS(sprite_p, 5);
+ assert(sprite_p);
+ MemoryReadStreamEndian readS(sprite_p, 5, IS_BIG_ENDIAN);
x_align = readS.readSByte();
y_align = readS.readSByte();
@@ -302,7 +304,7 @@ int Sprite::drawOccluded(SURFACE *ds, SPRITELIST *sprite_list, int sprite_num, i
sprite_p = sprite_list->sprite_data[offset_idx];
sprite_p += offset;
- MemoryReadStream readS(sprite_p, 5);
+ MemoryReadStreamEndian readS(sprite_p, 5, IS_BIG_ENDIAN);
// Read sprite dimensions -- should probably cache this stuff in
// sprite list
@@ -383,7 +385,7 @@ int Sprite::drawOccluded(SURFACE *ds, SPRITELIST *sprite_list, int sprite_num, i
/*
{
char buf[1024] = { 0 };
- sprintf( buf, "dw: %d, dh: %d.", ci.draw_w, ci.draw_h );
+ sprintf(buf, "dw: %d, dh: %d.", ci.draw_w, ci.draw_h);
_vm->textDraw(2, ds, buf, spr_x - x_align, spr_y - y_align, 255, 0, FONT_OUTLINE);
}
diff --git a/saga/sthread.cpp b/saga/sthread.cpp
index e6fed99bff..f50524f80d 100644
--- a/saga/sthread.cpp
+++ b/saga/sthread.cpp
@@ -23,7 +23,6 @@
// Scripting module thread management component
#include "saga/saga.h"
-#include "saga/yslib.h"
#include "saga/gfx.h"
#include "saga/actor.h"
@@ -32,6 +31,8 @@
#include "saga/script.h"
#include "saga/sdata.h"
+#include "saga/game_mod.h"
+#include "saga/stream.h"
namespace Saga {
@@ -42,22 +43,13 @@ void Script::setFramePtr(SCRIPT_THREAD *thread, int newPtr) {
}
SCRIPT_THREAD *Script::SThreadCreate() {
- YS_DL_NODE *new_node;
SCRIPT_THREAD *new_thread;
if (!isInitialized()) {
return NULL;
}
- new_thread = (SCRIPT_THREAD *)calloc(1, sizeof *new_thread);
- if (new_thread == NULL) {
- return NULL;
- }
-
- new_node = ys_dll_add_head(threadList(), new_thread, sizeof *new_thread);
- free(new_thread);
-
- new_thread = (SCRIPT_THREAD *)ys_dll_get_data(new_node);
+ new_thread = _threadList.pushFront().operator->();
new_thread->stackPtr = ARRAYSIZE(new_thread->stackBuf) - 1;
setFramePtr(new_thread, new_thread->stackPtr);
@@ -71,45 +63,24 @@ SCRIPT_THREAD *Script::SThreadCreate() {
return new_thread;
}
-int Script::SThreadDestroy(SCRIPT_THREAD *thread) {
- YS_DL_NODE *walk_p;
- SCRIPT_THREAD *th;
-
- if (thread == NULL) {
- return FAILURE;
- }
-
- for (walk_p = ys_dll_head(threadList()); walk_p != NULL; walk_p = ys_dll_next(walk_p)) {
- th = (SCRIPT_THREAD *)ys_dll_get_data(walk_p);
- if (thread == th) {
- ys_dll_delete(walk_p);
- break;
- }
- }
-
- return SUCCESS;
-}
int Script::SThreadExecThreads(uint msec) {
- YS_DL_NODE *walk_p, *next_p;
SCRIPT_THREAD *thread;
if (!isInitialized()) {
return FAILURE;
}
- walk_p = ys_dll_head(threadList());
+ ScriptThreadList::iterator threadi = _threadList.begin();
- while (walk_p != NULL) {
- next_p = ys_dll_next(walk_p);
-
- thread = (SCRIPT_THREAD *)ys_dll_get_data(walk_p);
+ while (threadi != _threadList.end()) {
+ thread = (SCRIPT_THREAD *)threadi.operator->();
if (thread->flags & (kTFlagFinished | kTFlagAborted)) {
//if (thread->flags & kTFlagFinished) // FIXME. Missing function
- SThreadDestroy(thread);
- walk_p = next_p;
+
+ threadi = _threadList.erase(threadi);
continue;
}
@@ -131,14 +102,14 @@ int Script::SThreadExecThreads(uint msec) {
if (!(thread->flags & kTFlagWaiting))
SThreadRun(thread, STHREAD_TIMESLICE);
- walk_p = next_p;
+ ++threadi;
}
return SUCCESS;
}
void Script::SThreadCompleteThread(void) {
- for (int i = 0; i < 40 && (ys_dll_head(threadList()) != NULL); i++)
+ for (int i = 0; i < 40 && !_threadList.isEmpty() ; i++)
SThreadExecThreads(0);
}
@@ -260,7 +231,7 @@ int Script::SThreadRun(SCRIPT_THREAD *thread, int instr_limit) {
}
}
- MemoryReadStream scriptS(currentScript()->bytecode->bytecode_p, currentScript()->bytecode->bytecode_len);
+ MemoryReadStream/*Endian*/ scriptS(currentScript()->bytecode->bytecode_p, currentScript()->bytecode->bytecode_len/*, IS_BIG_ENDIAN*/);
dataBuffer(2)->len = currentScript()->bytecode->bytecode_len / sizeof(SDataWord_T);
dataBuffer(2)->data = (SDataWord_T *) currentScript()->bytecode->bytecode_p;
@@ -275,7 +246,6 @@ int Script::SThreadRun(SCRIPT_THREAD *thread, int instr_limit) {
in_char = scriptS.readByte();
debug(2, "Executing thread offset: %lu (%x) stack: %d", thread->i_offset, in_char, thread->stackSize());
-
switch (in_char) {
case 0x01: // nextblock
// Some sort of "jump to the start of the next memory
@@ -385,6 +355,7 @@ int Script::SThreadRun(SCRIPT_THREAD *thread, int instr_limit) {
if (func_num >= SFUNC_NUM) {
_vm->_console->DebugPrintf(S_ERROR_PREFIX "Invalid script function number: (%X)\n", func_num);
thread->flags |= kTFlagAborted;
+ debug(9, "Invalid script function number: (%X)\n", func_num);
break;
}
@@ -392,6 +363,7 @@ int Script::SThreadRun(SCRIPT_THREAD *thread, int instr_limit) {
sfuncRetVal = (this->*sfunc)(thread, n_args);
if (sfuncRetVal != SUCCESS) {
_vm->_console->DebugPrintf(S_WARN_PREFIX "%X: Script function %d failed.\n", thread->i_offset, func_num);
+ debug(9, "%X: Script function %d failed.\n", thread->i_offset, func_num);
}
if (func_num == 16) { // SF_gotoScene
@@ -421,6 +393,7 @@ int Script::SThreadRun(SCRIPT_THREAD *thread, int instr_limit) {
if (thread->stackSize() == 0) {
_vm->_console->DebugPrintf("Script execution complete.\n");
thread->flags |= kTFlagFinished;
+ debug(9, "Script execution complete.\n");
} else {
thread->i_offset = thread->pop();
/* int n_args = */ thread->pop();
@@ -520,6 +493,7 @@ int Script::SThreadRun(SCRIPT_THREAD *thread, int instr_limit) {
}
if (!branch_found) {
_vm->_console->DebugPrintf(S_ERROR_PREFIX "%X: Random jump target out of bounds.\n", thread->i_offset);
+ debug(9, "%X: Random jump target out of bounds.\n", thread->i_offset);
}
}
break;
@@ -758,6 +732,7 @@ int Script::SThreadRun(SCRIPT_THREAD *thread, int instr_limit) {
a_index = _vm->_actor->getActorIndex(param1);
if (a_index < 0) {
_vm->_console->DebugPrintf(S_WARN_PREFIX "%X: DLGP Actor id not found.\n", thread->i_offset);
+ debug(9, "%X: DLGP Actor id not found.\n", thread->i_offset);
}
for (i = 0; i < n_voices; i++) {
@@ -806,6 +781,7 @@ int Script::SThreadRun(SCRIPT_THREAD *thread, int instr_limit) {
_vm->_console->DebugPrintf(S_ERROR_PREFIX "%X: Invalid opcode encountered: (%X).\n", thread->i_offset, in_char);
thread->flags |= kTFlagAborted;
+ debug(9, "%X: Invalid opcode encountered: (%X).\n", thread->i_offset, in_char);
break;
}
@@ -813,11 +789,18 @@ int Script::SThreadRun(SCRIPT_THREAD *thread, int instr_limit) {
if (saved_offset == thread->i_offset) {
thread->i_offset = scriptS.pos();
} else {
- scriptS.seek(thread->i_offset);
+ if (thread->i_offset >= scriptS.size()) {
+ _vm->_console->DebugPrintf("Out of range script execution at %x size %x\n", thread->i_offset, scriptS.size());
+ thread->flags |= kTFlagFinished;
+ debug(9, "Out of range script execution at %x size %x\n", thread->i_offset, scriptS.size());
+ }
+ else
+ scriptS.seek(thread->i_offset);
}
if (unhandled) {
_vm->_console->DebugPrintf(S_ERROR_PREFIX "%X: Unhandled opcode.\n", thread->i_offset);
thread->flags |= kTFlagAborted;
+ debug(9, "%X: Unhandled opcode.\n", thread->i_offset);
}
if ((thread->flags == kTFlagNone) && debug_print) {
SDebugPrintInstr(thread);
diff --git a/saga/stream.h b/saga/stream.h
new file mode 100644
index 0000000000..2ac45c79c5
--- /dev/null
+++ b/saga/stream.h
@@ -0,0 +1,56 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2004 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ *
+ */
+
+#ifndef SAGA_STREAM_H__
+#define SAGA_STREAM_H__
+
+#include "common/stream.h"
+
+namespace Saga {
+
+using Common::MemoryReadStream;
+
+class MemoryReadStreamEndian : public Common::MemoryReadStream {
+private:
+public:
+ bool _bigEndian;
+ MemoryReadStreamEndian(const byte *buf, uint32 len, bool bigEndian = false) : MemoryReadStream(buf, len), _bigEndian(bigEndian) {}
+
+ uint16 readUint16() {
+ return (_bigEndian) ? readUint16BE(): readUint16LE();
+ }
+
+ uint32 readUint32() {
+ return (_bigEndian) ? readUint32BE(): readUint32LE();
+ }
+
+ inline int16 readSint16() {
+ return (int16)readUint16();
+ }
+
+
+ inline int32 readSint32() {
+ return (int32)readUint32();
+ }
+};
+
+} // End of namespace Saga
+#endif
diff --git a/saga/text.cpp b/saga/text.cpp
index be14528995..f7237e4006 100644
--- a/saga/text.cpp
+++ b/saga/text.cpp
@@ -24,7 +24,6 @@
// Text / dialogue display management module
#include "saga/saga.h"
-#include "saga/yslib.h"
#include "saga/gfx.h"
#include "saga/font.h"
@@ -149,25 +148,18 @@ int SagaEngine::textDraw(int font_id, SURFACE *ds, const char *string, int text_
TEXTLIST *SagaEngine::textCreateList() {
TEXTLIST *new_textlist;
- new_textlist = (TEXTLIST *)malloc(sizeof *new_textlist);
+ new_textlist = new TEXTLIST;
if (new_textlist == NULL) {
return NULL;
}
- new_textlist->list = ys_dll_create();
-
- if (new_textlist->list == NULL) {
- free(new_textlist);
- return NULL;
- }
-
return new_textlist;
}
void SagaEngine::textClearList(TEXTLIST *tlist) {
if (tlist != NULL) {
- ys_dll_delete_all(tlist->list);
+ tlist->clear();
}
return;
@@ -175,21 +167,18 @@ void SagaEngine::textClearList(TEXTLIST *tlist) {
void SagaEngine::textDestroyList(TEXTLIST *tlist) {
if (tlist != NULL) {
- ys_dll_destroy(tlist->list);
- }
- free(tlist);
-
+ delete tlist;
+ }
return;
}
int SagaEngine::textDrawList(TEXTLIST *textlist, SURFACE *ds) {
TEXTLIST_ENTRY *entry_p;
- YS_DL_NODE *walk_p;
assert((textlist != NULL) && (ds != NULL));
- for (walk_p = ys_dll_head(textlist->list); walk_p != NULL; walk_p = ys_dll_next(walk_p)) {
- entry_p = (TEXTLIST_ENTRY *)ys_dll_get_data(walk_p);
+ for (TEXTLIST::iterator texti = textlist->begin(); texti != textlist->end(); ++texti) {
+ entry_p = (TEXTLIST_ENTRY *)texti.operator->();
if (entry_p->display != 0) {
textDraw(entry_p->font_id, ds, entry_p->string, entry_p->text_x, entry_p->text_y, entry_p->color,
entry_p->effect_color, entry_p->flags);
@@ -201,16 +190,13 @@ int SagaEngine::textDrawList(TEXTLIST *textlist, SURFACE *ds) {
int SagaEngine::textProcessList(TEXTLIST *textlist, long ms) {
TEXTLIST_ENTRY *entry_p;
- YS_DL_NODE *walk_p;
- YS_DL_NODE *temp_p;
- for (walk_p = ys_dll_head(textlist->list); walk_p != NULL; walk_p = temp_p) {
- temp_p = ys_dll_next(walk_p);
- entry_p = (TEXTLIST_ENTRY *)ys_dll_get_data(walk_p);
+ for (TEXTLIST::iterator texti = textlist->begin(); texti != textlist->end(); ++texti) {
+ entry_p = (TEXTLIST_ENTRY *)texti.operator->();
if (entry_p->flags & TEXT_TIMEOUT) {
entry_p->time -= ms;
if (entry_p->time <= 0) {
- ys_dll_delete(walk_p);
+ texti=textlist->eraseAndPrev(texti);
}
}
}
@@ -220,13 +206,10 @@ int SagaEngine::textProcessList(TEXTLIST *textlist, long ms) {
}
TEXTLIST_ENTRY *SagaEngine::textAddEntry(TEXTLIST *textlist, TEXTLIST_ENTRY *entry) {
- YS_DL_NODE *new_node = NULL;
-
if (entry != NULL) {
- new_node = ys_dll_add_tail(textlist->list, entry, sizeof *entry);
+ return textlist->pushBack(*entry).operator->();
}
-
- return (new_node != NULL) ? (TEXTLIST_ENTRY *)new_node->data : NULL;
+ return NULL;
}
int SagaEngine::textSetDisplay(TEXTLIST_ENTRY *entry, int val) {
@@ -239,18 +222,12 @@ int SagaEngine::textSetDisplay(TEXTLIST_ENTRY *entry, int val) {
}
int SagaEngine::textDeleteEntry(TEXTLIST *textlist, TEXTLIST_ENTRY *entry) {
- YS_DL_NODE *walk_p;
if (entry == NULL) {
return FAILURE;
}
-
- for (walk_p = ys_dll_head(textlist->list); walk_p != NULL; walk_p = ys_dll_next(walk_p)) {
- if (entry == ys_dll_get_data(walk_p)) {
- ys_dll_delete(walk_p);
- break;
- }
- }
+
+ textlist->remove(entry);
return SUCCESS;
}
diff --git a/saga/text.h b/saga/text.h
index f56113f278..460d9f74b8 100644
--- a/saga/text.h
+++ b/saga/text.h
@@ -26,7 +26,7 @@
#ifndef SAGA_TEXT_H__
#define SAGA_TEXT_H__
-#include "saga/yslib.h"
+#include "saga/list.h"
namespace Saga {
@@ -34,17 +34,12 @@ namespace Saga {
#define TEXT_MARGIN 10
#define TEXT_LINESPACING 2
-struct TEXTLIST {
- YS_DL_LIST *list;
-};
enum TEXT_FLAGS {
TEXT_TIMEOUT = 0x01
};
struct TEXTLIST_ENTRY {
- TEXTLIST_ENTRY *next;
- TEXTLIST_ENTRY *prev;
int display;
int id;
int text_x;
@@ -58,6 +53,9 @@ struct TEXTLIST_ENTRY {
TEXTLIST_ENTRY() { memset(this, 0, sizeof(*this)); }
};
+typedef SortedList<TEXTLIST_ENTRY> TEXTLIST;
+
+#define TEXTLISTITERATOR TEXTLIST::iterator
} // End of namespace Saga
#endif
diff --git a/saga/ys_dl_list.cpp b/saga/ys_dl_list.cpp
deleted file mode 100644
index db7adfe4ce..0000000000
--- a/saga/ys_dl_list.cpp
+++ /dev/null
@@ -1,239 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2004 The ScummVM project
- *
- * The ReInherit Engine is (C)2000-2003 by Daniel Balsom.
- *
- * 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 "saga/saga.h"
-#include "saga/yslib.h"
-
-namespace Saga {
-
-YS_DL_LIST *ys_dll_create() {
- YS_DL_LIST *new_list;
-
- new_list = (YS_DL_LIST *)malloc(sizeof *new_list);
-
- if (new_list != NULL) {
- new_list->next = new_list;
- new_list->prev = new_list;
-
- // Sentinel is marked by self-referential node data.
- // No other link is permitted to do this
- new_list->data = new_list;
- }
-
- return new_list;
-}
-
-void ys_dll_destroy(YS_DL_LIST *list) {
- YS_DL_NODE *walk_p;
- YS_DL_NODE *temp_p;
-
- for (walk_p = list->next; walk_p != list; walk_p = temp_p) {
- temp_p = walk_p->next;
- free(walk_p->data);
- free(walk_p);
- }
-
- free(list);
-
- return;
-}
-
-void *ys_dll_get_data(YS_DL_NODE *node) {
- return node->data;
-}
-
-YS_DL_NODE *ys_dll_head(YS_DL_LIST *list) {
- return (list->next != list) ? list->next : NULL;
-}
-
-YS_DL_NODE *ys_dll_tail(YS_DL_LIST *list) {
- return (list->prev != list) ? list->prev : NULL;
-}
-
-YS_DL_NODE *ys_dll_next(YS_DL_NODE *node) {
- return (node->next != (YS_DL_LIST *) node->next->data) ? node->next : NULL;
-}
-
-YS_DL_NODE *ys_dll_prev(YS_DL_NODE *node) {
- return (node->prev != (YS_DL_LIST *) node->prev->data) ? node->prev : NULL;
-}
-
-YS_DL_NODE *ys_dll_add_head(YS_DL_LIST *list, void *data, size_t size) {
- YS_DL_NODE *new_node;
- void *new_data;
-
- new_node = (YS_DL_NODE *)malloc(sizeof *new_node);
-
- if (new_node) {
- new_data = malloc(size);
-
- if (new_data) {
- memcpy(new_data, data, size);
- new_node->data = new_data;
- new_node->prev = list;
- new_node->next = list->next;
- new_node->next->prev = new_node;
- list->next = new_node;
- }
- }
- return new_node;
-}
-
-YS_DL_NODE *ys_dll_add_tail(YS_DL_LIST *list, void *data, size_t size) {
- YS_DL_NODE *new_node;
- void *new_data;
-
- new_node = (YS_DL_NODE *)malloc(sizeof *new_node);
-
- if (new_node != NULL) {
- new_data = malloc(size);
-
- if (new_data != NULL) {
- memcpy(new_data, data, size);
- new_node->data = new_data;
- new_node->next = list;
- new_node->prev = list->prev;
- new_node->prev->next = new_node;
- list->prev = new_node;
- }
- }
- return new_node;
-}
-
-YS_DL_NODE *ys_dll_insert(YS_DL_NODE *list, void *data, size_t size, YS_COMPARE_FUNC *compare) {
- YS_DL_NODE *walk_p;
- YS_DL_NODE *new_node;
- int result;
-
- for (walk_p = list->next; walk_p != list; walk_p = walk_p->next) {
- result = compare(data, walk_p->data);
- if (result < 0) {
- new_node = ys_dll_preinsert(walk_p, data, size);
- return new_node;
- }
- }
-
- new_node = ys_dll_add_tail(list, data, size);
- return new_node;
-}
-
-int ys_dll_delete(YS_DL_NODE *node) {
- if (node == NULL) {
- return YS_E_FAILURE;
- }
-
- node->next->prev = node->prev;
- node->prev->next = node->next;
-
- free(node->data);
- free(node);
-
- return YS_E_SUCCESS;
-}
-
-void ys_dll_delete_all(YS_DL_LIST *list) {
- YS_DL_NODE *walk_p;
- YS_DL_NODE *temp_p;
-
- for (walk_p = list->next; walk_p != list; walk_p = temp_p) {
- temp_p = walk_p->next;
- free(walk_p->data);
- free(walk_p);
- }
-
- list->next = list;
- list->prev = list;
-}
-
-YS_DL_NODE *ys_dll_replace(YS_DL_NODE *node, void *data, size_t size) {
- void *new_data;
-
- if ((node == NULL) || (data == NULL) || (!size)) {
- return NULL;
- }
-
- new_data = malloc(size);
-
- if (new_data == NULL) {
- return NULL;
- }
-
- free(node->data);
- node->data = new_data;
- memcpy(new_data, data, size);
-
- return node;
-}
-
-int ys_dll_reorder_up(YS_DL_NODE *list, YS_DL_NODE *olink, YS_COMPARE_FUNC *compare) {
- YS_DL_NODE *walk_p;
- int result;
- int reorder = 0;
-
- for (walk_p = olink->prev; walk_p != list; walk_p = walk_p->prev) {
- result = compare(walk_p->data, olink->data);
- if (result <= 0) {
- reorder = 1;
- break;
- }
- }
-
- if (reorder) {
- // Unlink original link
- olink->next->prev = olink->prev;
- olink->prev->next = olink->next;
- // Reinsert after walk link
- olink->prev = walk_p;
- olink->next = walk_p->next;
- olink->next->prev = olink;
- walk_p->next = olink;
- }
- return YS_E_SUCCESS;
-}
-
-int ys_dll_reorder_down(YS_DL_NODE *list, YS_DL_NODE *olink, YS_COMPARE_FUNC *compare) {
- YS_DL_NODE *walk_p;
- int result;
- int reorder = 0;
-
- for (walk_p = olink->next; walk_p != list; walk_p = walk_p->next) {
- result = compare(walk_p->data, olink->data);
- if (result >= 0) {
- reorder = 1;
- break;
- }
- }
-
- if (reorder) {
- // Unlink original link
- olink->next->prev = olink->prev;
- olink->prev->next = olink->next;
- //Reinsert before walk link
- olink->next = walk_p;
- olink->prev = walk_p->prev;
- olink->prev->next = olink;
- walk_p->prev = olink;
- }
- return YS_E_SUCCESS;
-}
-
-} // End of namespace Saga
diff --git a/saga/yslib.h b/saga/yslib.h
deleted file mode 100644
index d6f9000c26..0000000000
--- a/saga/yslib.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2004 The ScummVM project
- *
- * The ReInherit Engine is (C)2000-2003 by Daniel Balsom.
- *
- * 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$
- *
- */
-#ifndef YSLIB_MAIN_H__
-#define YSLIB_MAIN_H__
-
-namespace Saga {
-
-enum YS_ERROR_STATES {
- YS_E_SUCCESS = 0,
- YS_E_FAILURE,
- YS_E_MEM
-};
-
-enum YS_CONFIRM_STATES {
- YS_CONFIRM_NO = 0,
- YS_CONFIRM_YES,
- YS_CONFIRM_CANCEL
-};
-
-// General purpose quantity-comparison function
-typedef int (YS_COMPARE_FUNC) (const void *, const void *);
-
-// General-purpose utility macros
-
-//#define YS_ASSUME_2S_COMP
-
-// Shared declarations for list modules
-enum YS_WALK_DIRECTIONS {
- YS_WALK_BACKWARD = 0,
- YS_WALK_FORWARD
-};
-
-typedef struct ys_dl_node_tag YS_DL_NODE;
-typedef struct ys_dl_node_tag YS_DL_LIST;
-
-struct ys_dl_node_tag {
- void *data;
- struct ys_dl_node_tag *next;
- struct ys_dl_node_tag *prev;
-};
-
-YS_DL_LIST *ys_dll_create();
-void ys_dll_destroy(YS_DL_LIST *);
-
-void *ys_dll_get_data(YS_DL_NODE *);
-
-YS_DL_NODE *ys_dll_head(YS_DL_LIST *);
-YS_DL_NODE *ys_dll_tail(YS_DL_LIST *);
-YS_DL_NODE *ys_dll_next(YS_DL_NODE *);
-YS_DL_NODE *ys_dll_prev(YS_DL_NODE *);
-
-YS_DL_NODE *ys_dll_add_head(YS_DL_LIST *, void *, size_t);
-YS_DL_NODE *ys_dll_add_tail(YS_DL_LIST *, void *, size_t);
-
-#define ys_dll_preinsert ys_dll_add_tail
-#define ys_dll_postinsert ys_dll_add_head
-
-YS_DL_NODE *ys_dll_insert(YS_DL_LIST *, void *, size_t, YS_COMPARE_FUNC *);
-int ys_dll_delete(YS_DL_NODE *);
-void ys_dll_delete_all(YS_DL_LIST *);
-
-YS_DL_NODE *ys_dll_replace(YS_DL_NODE *, void *, size_t);
-
-int ys_dll_reorder_up(YS_DL_LIST *, YS_DL_NODE *, YS_COMPARE_FUNC *);
-int ys_dll_reorder_down(YS_DL_LIST *, YS_DL_NODE *, YS_COMPARE_FUNC *);
-
-
-} // End of namespace Saga
-
-#endif