Large pointless reindentation of all the code. Also fixed a few mistakes

in the object flags code cleanup.

Flags used:

indent *.cpp -br -bap -nbc -lp -ce -cdw -brs -nbad -nbc -npsl -nip
-ts2 -ncs -nbs -npcs -nbap -Tbyte -Tuint32 -Tuint8 -Tuint16 -TArrayHeader
-TMemBlkHeader -TVerbSlot -TObjectData -Tvoid -TImageHeader -TRoomHeader
-TCodeHeader -TResHdr -TBompHeader -TMidiChannelAdl -TGui -TScumm
-TSoundEngine -TPart -TPlayer

svn-id: r3908
This commit is contained in:
James Brown 2002-04-11 17:19:16 +00:00
parent 34747b792a
commit 7696081c54
34 changed files with 13662 additions and 12167 deletions

251
actor.cpp
View file

@ -24,7 +24,8 @@
#include "scumm.h" #include "scumm.h"
#include "math.h" #include "math.h"
void Scumm::initActor(Actor *a, int mode) { void Scumm::initActor(Actor * a, int mode)
{
if (mode == 1) { if (mode == 1) {
a->costume = 0; a->costume = 0;
a->room = 0; a->room = 0;
@ -80,12 +81,14 @@ void Scumm::initActor(Actor *a, int mode) {
} }
} }
void Scumm::stopActorMoving(Actor *a) { void Scumm::stopActorMoving(Actor * a)
{
stopScriptNr(a->walk_script); stopScriptNr(a->walk_script);
a->moving = 0; a->moving = 0;
} }
void Scumm::setActorWalkSpeed(Actor *a, uint speedx, uint speedy) { void Scumm::setActorWalkSpeed(Actor * a, uint speedx, uint speedy)
{
if (speedx == a->speedx && speedy == a->speedy) if (speedx == a->speedx && speedy == a->speedy)
return; return;
@ -97,7 +100,8 @@ void Scumm::setActorWalkSpeed(Actor *a, uint speedx, uint speedy) {
} }
} }
int Scumm::getAngleFromPos(int x, int y) { int Scumm::getAngleFromPos(int x, int y)
{
if (_gameId == GID_DIG) { if (_gameId == GID_DIG) {
double temp = atan2(x, -y); double temp = atan2(x, -y);
return normalizeAngle((int)(temp * 1.8e2 / 3.14)); return normalizeAngle((int)(temp * 1.8e2 / 3.14));
@ -114,7 +118,8 @@ int Scumm::getAngleFromPos(int x, int y) {
} }
} }
int Scumm::calcMovementFactor(Actor *a, int newX, int newY) { int Scumm::calcMovementFactor(Actor * a, int newX, int newY)
{
int actorX, actorY; int actorX, actorY;
int diffX, diffY; int diffX, diffY;
int32 XYFactor, YXFactor; int32 XYFactor, YXFactor;
@ -166,7 +171,8 @@ int Scumm::calcMovementFactor(Actor *a, int newX, int newY) {
return actorWalkStep(a); return actorWalkStep(a);
} }
int Scumm::remapDirection(Actor *a, int dir) { int Scumm::remapDirection(Actor * a, int dir)
{
int specdir; int specdir;
byte flags; byte flags;
byte dirflag; byte dirflag;
@ -202,16 +208,21 @@ int Scumm::remapDirection(Actor *a, int dir) {
return (dirflag & 1) ? 90 : 270; return (dirflag & 1) ? 90 : 270;
case 2: case 2:
return (dirflag & 2) ? 180 : 0; return (dirflag & 2) ? 180 : 0;
case 3: return 270; case 3:
case 4: return 90; return 270;
case 5: return 0; case 4:
case 6: return 180; return 90;
case 5:
return 0;
case 6:
return 180;
} }
} }
return normalizeAngle(dir); return normalizeAngle(dir);
} }
int Scumm::updateActorDirection(Actor *a) { int Scumm::updateActorDirection(Actor * a)
{
int from, to; int from, to;
int diff; int diff;
int dirType; int dirType;
@ -238,14 +249,16 @@ int Scumm::updateActorDirection(Actor *a) {
return fromSimpleDir(dirType, from & (num - 1)); return fromSimpleDir(dirType, from & (num - 1));
} }
void Scumm::setActorBox(Actor *a, int box) { void Scumm::setActorBox(Actor * a, int box)
{
a->walkbox = box; a->walkbox = box;
a->mask = getMaskFromBox(box); a->mask = getMaskFromBox(box);
setupActorScale(a); setupActorScale(a);
} }
int Scumm::actorWalkStep(Actor *a) { int Scumm::actorWalkStep(Actor * a)
{
int tmpX, tmpY; int tmpX, tmpY;
int actorX, actorY; int actorX, actorY;
int distX, distY; int distX, distY;
@ -273,10 +286,8 @@ int Scumm::actorWalkStep(Actor *a) {
distX = abs(a->walkdata.newx - a->walkdata.x); distX = abs(a->walkdata.newx - a->walkdata.x);
distY = abs(a->walkdata.newy - a->walkdata.y); distY = abs(a->walkdata.newy - a->walkdata.y);
if ( if (abs(actorX - a->walkdata.x) >= distX &&
abs(actorX - a->walkdata.x) >= distX && abs(actorY - a->walkdata.y) >= distY) {
abs(actorY - a->walkdata.y) >= distY
) {
a->moving &= ~MF_IN_LEG; a->moving &= ~MF_IN_LEG;
return 0; return 0;
} }
@ -305,7 +316,8 @@ int Scumm::actorWalkStep(Actor *a) {
} }
void Scumm::setupActorScale(Actor *a) { void Scumm::setupActorScale(Actor * a)
{
uint16 scale; uint16 scale;
byte *resptr; byte *resptr;
int y; int y;
@ -341,14 +353,25 @@ void Scumm::setupActorScale(Actor *a) {
a->scaley = (byte)scale; a->scaley = (byte)scale;
} }
void Scumm::startAnimActor(Actor *a, int frame) { void Scumm::startAnimActor(Actor * a, int frame)
{
if (_features & GF_NEW_COSTUMES) { if (_features & GF_NEW_COSTUMES) {
switch (frame) { switch (frame) {
case 1001: frame = a->initFrame; break; case 1001:
case 1002: frame = a->walkFrame; break; frame = a->initFrame;
case 1003: frame = a->standFrame; break; break;
case 1004: frame = a->talkFrame1; break; case 1002:
case 1005: frame = a->talkFrame2; break; frame = a->walkFrame;
break;
case 1003:
frame = a->standFrame;
break;
case 1004:
frame = a->talkFrame1;
break;
case 1005:
frame = a->talkFrame2;
break;
} }
if (a->costume != 0) { if (a->costume != 0) {
@ -393,7 +416,8 @@ void Scumm::startAnimActor(Actor *a, int frame) {
} }
} }
void Scumm::fixActorDirection(Actor *a, int direction) { void Scumm::fixActorDirection(Actor * a, int direction)
{
uint mask; uint mask;
int i; int i;
uint16 vald; uint16 vald;
@ -421,8 +445,10 @@ void Scumm::fixActorDirection(Actor *a, int direction) {
a->needBgReset = true; a->needBgReset = true;
} }
void Scumm::putActor(Actor *a, int x, int y, byte room) { void Scumm::putActor(Actor * a, int x, int y, byte room)
if (a->visible && _currentRoom!=room && _vars[VAR_TALK_ACTOR]==a->number) { {
if (a->visible && _currentRoom != room
&& _vars[VAR_TALK_ACTOR] == a->number) {
clearMsgQueue(); clearMsgQueue();
} }
@ -452,7 +478,8 @@ void Scumm::putActor(Actor *a, int x, int y, byte room) {
} }
} }
int Scumm::getActorXYPos(Actor *a) { int Scumm::getActorXYPos(Actor * a)
{
if (a->room != _currentRoom) if (a->room != _currentRoom)
return -1; return -1;
_xPos = a->x; _xPos = a->x;
@ -460,7 +487,9 @@ int Scumm::getActorXYPos(Actor *a) {
return 0; return 0;
} }
AdjustBoxResult Scumm::adjustXYToBeInBox(Actor *a, int x, int y, int pathfrom) { AdjustBoxResult Scumm::adjustXYToBeInBox(Actor * a, int x, int y,
int pathfrom)
{
// Yazoo: need to recheck with Loom for the class data flags (0x400000) // Yazoo: need to recheck with Loom for the class data flags (0x400000)
AdjustBoxResult abr, tmp; AdjustBoxResult abr, tmp;
uint threshold; uint threshold;
@ -478,7 +507,7 @@ AdjustBoxResult Scumm::adjustXYToBeInBox(Actor *a, int x, int y, int pathfrom) {
abr.y = y; abr.y = y;
abr.dist = 0; abr.dist = 0;
if ((_features & GF_SMALL_HEADER) && getClass(a->number, 21)) if ((_features & GF_SMALL_HEADER) && getClass(a->number, 22))
return abr; return abr;
if (a && a->ignoreBoxes == 0) { if (a && a->ignoreBoxes == 0) {
@ -486,7 +515,8 @@ AdjustBoxResult Scumm::adjustXYToBeInBox(Actor *a, int x, int y, int pathfrom) {
while (1) { while (1) {
iterations++; iterations++;
if (iterations > 1000) return abr; /* Safety net */ if (iterations > 1000)
return abr; /* Safety net */
box = getNumBoxes() - 1; box = getNumBoxes() - 1;
if (box == 0) if (box == 0)
return abr; return abr;
@ -494,7 +524,8 @@ AdjustBoxResult Scumm::adjustXYToBeInBox(Actor *a, int x, int y, int pathfrom) {
best = (uint) 0xFFFF; best = (uint) 0xFFFF;
b = 0; b = 0;
if(((_features & GF_SMALL_HEADER) && box) || !(_features & GF_SMALL_HEADER)) if (((_features & GF_SMALL_HEADER) && box)
|| !(_features & GF_SMALL_HEADER))
for (j = box; j >= firstValidBox; j--) { for (j = box; j >= firstValidBox; j--) {
flags = getBoxFlags(j); flags = getBoxFlags(j);
if (flags & 0x80 && (!(flags & 0x20) || getClass(a->number, 0x1F))) if (flags & 0x80 && (!(flags & 0x20) || getClass(a->number, 0x1F)))
@ -539,7 +570,8 @@ AdjustBoxResult Scumm::adjustXYToBeInBox(Actor *a, int x, int y, int pathfrom) {
return abr; return abr;
} }
void Scumm::adjustActorPos(Actor *a) { void Scumm::adjustActorPos(Actor * a)
{
AdjustBoxResult abr; AdjustBoxResult abr;
byte flags; byte flags;
@ -562,7 +594,8 @@ void Scumm::adjustActorPos(Actor *a) {
} }
} }
void Scumm::hideActor(Actor *a) { void Scumm::hideActor(Actor * a)
{
if (!a->visible) if (!a->visible)
return; return;
@ -576,7 +609,8 @@ void Scumm::hideActor(Actor *a) {
a->needBgReset = true; a->needBgReset = true;
} }
void Scumm::turnToDirection(Actor *a, int newdir) { void Scumm::turnToDirection(Actor * a, int newdir)
{
if (newdir == -1) if (newdir == -1)
return; return;
@ -588,7 +622,8 @@ void Scumm::turnToDirection(Actor *a, int newdir) {
} }
} }
void Scumm::showActor(Actor *a) { void Scumm::showActor(Actor * a)
{
if (_currentRoom == 0 || a->visible) if (_currentRoom == 0 || a->visible)
return; return;
@ -605,7 +640,8 @@ void Scumm::showActor(Actor *a) {
a->needRedraw = true; a->needRedraw = true;
} }
void Scumm::showActors() { void Scumm::showActors()
{
int i; int i;
Actor *a; Actor *a;
@ -616,7 +652,8 @@ void Scumm::showActors() {
} }
} }
void Scumm::stopTalk() { void Scumm::stopTalk()
{
int act; int act;
stopTalkSound(); stopTalkSound();
@ -637,12 +674,14 @@ void Scumm::stopTalk() {
restoreCharsetBg(); restoreCharsetBg();
} }
void Scumm::clearMsgQueue() { void Scumm::clearMsgQueue()
{
_messagePtr = (byte *)" "; _messagePtr = (byte *)" ";
stopTalk(); stopTalk();
} }
void Scumm::walkActors() { void Scumm::walkActors()
{
int i; int i;
Actor *a; Actor *a;
@ -657,7 +696,8 @@ void Scumm::walkActors() {
} }
/* Used in Scumm v5 only. Play sounds associated with actors */ /* Used in Scumm v5 only. Play sounds associated with actors */
void Scumm::playActorSounds() { void Scumm::playActorSounds()
{
int i; int i;
Actor *a; Actor *a;
@ -676,7 +716,8 @@ void Scumm::playActorSounds() {
} }
void Scumm::startWalkAnim(Actor *a, int cmd, int angle) { void Scumm::startWalkAnim(Actor * a, int cmd, int angle)
{
int16 args[16]; int16 args[16];
if (angle == -1) if (angle == -1)
@ -706,7 +747,8 @@ void Scumm::startWalkAnim(Actor *a, int cmd, int angle) {
} }
void Scumm::walkActor(Actor *a) { void Scumm::walkActor(Actor * a)
{
int j; int j;
if (!a->moving) if (!a->moving)
@ -735,7 +777,6 @@ void Scumm::walkActor(Actor *a) {
setActorBox(a, a->walkdata.curbox); setActorBox(a, a->walkdata.curbox);
a->moving &= 2; a->moving &= 2;
} }
#if OLD #if OLD
a->moving &= ~1; a->moving &= ~1;
@ -755,7 +796,8 @@ void Scumm::walkActor(Actor *a) {
} }
j = getPathToDestBox(a->walkbox, a->walkdata.destbox); j = getPathToDestBox(a->walkbox, a->walkdata.destbox);
if (j == -1) { if (j == -1) {
error("walkActor: no path found between %d and %d", a->walkbox, a->walkdata.destbox); error("walkActor: no path found between %d and %d", a->walkbox,
a->walkdata.destbox);
} }
a->walkdata.curbox = j; a->walkdata.curbox = j;
@ -784,11 +826,9 @@ void Scumm::walkActor(Actor *a) {
return; return;
} }
a->walkdata.curbox = j; a->walkdata.curbox = j;
if(_features & GF_OLD256) if (_features & GF_OLD256) {
{
findPathTowardsOld(a, a->walkbox, j, a->walkdata.destbox); findPathTowardsOld(a, a->walkbox, j, a->walkdata.destbox);
if (p[2].x == 32000 && p[3].x == 32000) if (p[2].x == 32000 && p[3].x == 32000) {
{
a->moving |= 8; a->moving |= 8;
calcMovementFactor(a, a->walkdata.destx, a->walkdata.desty); calcMovementFactor(a, a->walkdata.destx, a->walkdata.desty);
return; return;
@ -819,7 +859,8 @@ void Scumm::walkActor(Actor *a) {
#endif #endif
} }
void Scumm::processActors() { void Scumm::processActors()
{
int i; int i;
Actor *actors[MAX_ACTORS], *a, **ac, **ac2, *tmp; Actor *actors[MAX_ACTORS], *a, **ac, **ac2, *tmp;
int numactors = 0, cnt, cnt2; int numactors = 0, cnt, cnt2;
@ -851,16 +892,15 @@ void Scumm::processActors() {
do { do {
a = *ac; a = *ac;
if (a->costume) { if (a->costume) {
CHECK_HEAP CHECK_HEAP getMaskFromBox(a->walkbox);
getMaskFromBox(a->walkbox);
drawActorCostume(a); drawActorCostume(a);
CHECK_HEAP CHECK_HEAP actorAnimate(a);
actorAnimate(a);
} }
} while (ac++, --cnt); } while (ac++, --cnt);
} }
void Scumm::drawActorCostume(Actor *a) { void Scumm::drawActorCostume(Actor * a)
{
if (!(_features & GF_AFTER_V7)) { if (!(_features & GF_AFTER_V7)) {
CostumeRenderer cr; CostumeRenderer cr;
@ -945,7 +985,8 @@ void Scumm::drawActorCostume(Actor *a) {
} }
} }
void Scumm::actorAnimate(Actor *a) { void Scumm::actorAnimate(Actor * a)
{
byte *akos; byte *akos;
LoadedCostume lc; LoadedCostume lc;
@ -973,7 +1014,8 @@ void Scumm::actorAnimate(Actor *a) {
} }
} }
void Scumm::setActorRedrawFlags() { void Scumm::setActorRedrawFlags()
{
int i, j; int i, j;
uint32 bits; uint32 bits;
@ -991,7 +1033,8 @@ void Scumm::setActorRedrawFlags() {
} }
} }
int Scumm::getActorFromPos(int x, int y) { int Scumm::getActorFromPos(int x, int y)
{
uint32 drawbits; uint32 drawbits;
int i; int i;
@ -1000,20 +1043,23 @@ int Scumm::getActorFromPos(int x, int y) {
return 0; return 0;
for (i = 1; i < NUM_ACTORS; i++) { for (i = 1; i < NUM_ACTORS; i++) {
Actor *a = derefActor(i); Actor *a = derefActor(i);
if (drawbits&(1<<i) && !getClass(i, 32) && y >= a->top && y <= a->bottom) { if (drawbits & (1 << i) && !getClass(i, 32) && y >= a->top
&& y <= a->bottom) {
return i; return i;
} }
} }
return 0; return 0;
} }
void Scumm::actorTalk() { void Scumm::actorTalk()
{
int oldact; int oldact;
Actor *a; Actor *a;
_msgPtrToAdd = charset._buffer; _msgPtrToAdd = charset._buffer;
_messagePtr = addMessageToStack(_messagePtr); _messagePtr = addMessageToStack(_messagePtr);
assert((int)(_msgPtrToAdd - charset._buffer) < (int)(sizeof(charset._buffer))); assert((int)(_msgPtrToAdd - charset._buffer) <
(int)(sizeof(charset._buffer)));
if (_actorToPrintStrFor == 0xFF) { if (_actorToPrintStrFor == 0xFF) {
if (!_keepText) if (!_keepText)
@ -1051,7 +1097,8 @@ void Scumm::actorTalk() {
CHARSET_1(); CHARSET_1();
} }
void Scumm::setActorCostume(Actor *a, int c) { void Scumm::setActorCostume(Actor * a, int c)
{
int i; int i;
a->costumeNeedsInit = true; a->costumeNeedsInit = true;
@ -1070,7 +1117,8 @@ void Scumm::setActorCostume(Actor *a, int c) {
a->palette[i] = 0xFF; a->palette[i] = 0xFF;
} }
void Scumm::startWalkActor(Actor *a, int x, int y, int dir) { void Scumm::startWalkActor(Actor * a, int x, int y, int dir)
{
AdjustBoxResult abr; AdjustBoxResult abr;
abr = adjustXYToBeInBox(a, x, y, a->walkbox); abr = adjustXYToBeInBox(a, x, y, a->walkbox);
@ -1093,8 +1141,7 @@ void Scumm::startWalkActor(Actor *a, int x, int y, int dir) {
abr = adjustXYToBeInBox(a, abr.x, abr.y, a->walkbox); abr = adjustXYToBeInBox(a, abr.x, abr.y, a->walkbox);
} }
if (a->moving && a->walkdata.destdir == dir if (a->moving && a->walkdata.destdir == dir
&& a->walkdata.destx == abr.x && a->walkdata.destx == abr.x && a->walkdata.desty == abr.y)
&& a->walkdata.desty == abr.y)
return; return;
} }
@ -1113,14 +1160,16 @@ void Scumm::startWalkActor(Actor *a, int x, int y, int dir) {
a->walkdata.curbox = a->walkbox; a->walkdata.curbox = a->walkbox;
} }
byte *Scumm::getActorName(Actor *a) { byte *Scumm::getActorName(Actor * a)
{
byte *ptr = getResourceAddress(rtActorName, a->number); byte *ptr = getResourceAddress(rtActorName, a->number);
if (ptr == NULL) if (ptr == NULL)
return (byte *)" "; return (byte *)" ";
return ptr; return ptr;
} }
bool Scumm::isCostumeInUse(int cost) { bool Scumm::isCostumeInUse(int cost)
{
int i; int i;
Actor *a; Actor *a;
@ -1134,7 +1183,9 @@ bool Scumm::isCostumeInUse(int cost) {
return false; return false;
} }
void Scumm::remapActor(Actor *a, int r_fact, int g_fact, int b_fact, int threshold) { void Scumm::remapActor(Actor * a, int r_fact, int g_fact, int b_fact,
int threshold)
{
byte *akos, *rgbs, *akpl; byte *akos, *rgbs, *akpl;
int akpl_size, i; int akpl_size, i;
int r, g, b; int r, g, b;
@ -1162,7 +1213,8 @@ void Scumm::remapActor(Actor *a, int r_fact, int g_fact, int b_fact, int thresho
rgbs = findResource(MKID('RGBS'), akos); rgbs = findResource(MKID('RGBS'), akos);
if (!rgbs) { if (!rgbs) {
warning("Can't remap actor %d costume %d doesn't contain an RGB block",a->number,a->costume); warning("Can't remap actor %d costume %d doesn't contain an RGB block",
a->number, a->costume);
return; return;
} }
// skip resource header // skip resource header
@ -1177,15 +1229,20 @@ void Scumm::remapActor(Actor *a, int r_fact, int g_fact, int b_fact, int thresho
// allow remap of generic palette entry? // allow remap of generic palette entry?
if (!a->shadow_mode || akpl_color >= 16) { if (!a->shadow_mode || akpl_color >= 16) {
if (r_fact!=256) r = (r*r_fact) >> 8; if (r_fact != 256)
if (g_fact!=256) g = (g*g_fact) >> 8; r = (r * r_fact) >> 8;
if (b_fact!=256) b = (b*b_fact) >> 8; if (g_fact != 256)
g = (g * g_fact) >> 8;
if (b_fact != 256)
b = (b * b_fact) >> 8;
a->palette[i] = remapPaletteColor(r, g, b, threshold); a->palette[i] = remapPaletteColor(r, g, b, threshold);
} }
} }
} }
void Scumm::setupShadowPalette(int slot,int rfact,int gfact,int bfact,int from,int to) { void Scumm::setupShadowPalette(int slot, int rfact, int gfact, int bfact,
int from, int to)
{
byte *table; byte *table;
int i, num; int i, num;
byte *curpal; byte *curpal;
@ -1204,28 +1261,25 @@ void Scumm::setupShadowPalette(int slot,int rfact,int gfact,int bfact,int from,i
curpal = _currentPalette + from * 3; curpal = _currentPalette + from * 3;
num = to - from + 1; num = to - from + 1;
do { do {
*table++ = remapPaletteColor( *table++ = remapPaletteColor(curpal[0] * rfact >> 8,
curpal[0] * rfact >> 8,
curpal[1] * gfact >> 8, curpal[1] * gfact >> 8,
curpal[2] * bfact >> 8, curpal[2] * bfact >> 8, (uint) - 1);
(uint)-1);
curpal += 3; curpal += 3;
} while (--num); } while (--num);
} }
void Scumm::walkActorOld(Actor *a) { void Scumm::walkActorOld(Actor * a)
{
int new_dir, next_box; int new_dir, next_box;
if (!a->moving) if (!a->moving)
return; return;
if(a->moving&1) if (a->moving & 1) {
{
restart: restart:
a->moving &= ~1; a->moving &= ~1;
if (a->walkbox==0xFF) if (a->walkbox == 0xFF) {
{
a->walkbox = a->walkdata.destbox; a->walkbox = a->walkdata.destbox;
a->walkdata.curbox = a->walkdata.destbox; a->walkdata.curbox = a->walkdata.destbox;
a->moving |= 8; a->moving |= 8;
@ -1233,8 +1287,7 @@ restart:
return; return;
} }
if (a->walkbox==a->walkdata.destbox) if (a->walkbox == a->walkdata.destbox) {
{
a->moving |= 8; a->moving |= 8;
calcMovementFactor(a, a->walkdata.destx, a->walkdata.desty); calcMovementFactor(a, a->walkdata.destx, a->walkdata.desty);
return; return;
@ -1242,8 +1295,7 @@ restart:
next_box = getPathToDestBox(a->walkbox, a->walkdata.destbox); next_box = getPathToDestBox(a->walkbox, a->walkdata.destbox);
if( next_box == -1) if (next_box == -1) {
{
a->moving |= 8; a->moving |= 8;
return; return;
} }
@ -1251,17 +1303,14 @@ restart:
a->walkdata.curbox = next_box; a->walkdata.curbox = next_box;
findPathTowardsOld(a, a->walkbox, next_box, a->walkdata.destbox); findPathTowardsOld(a, a->walkbox, next_box, a->walkdata.destbox);
if(p[2].x == 32000 && p[3].x == 32000) if (p[2].x == 32000 && p[3].x == 32000) {
{
a->moving |= 8; a->moving |= 8;
calcMovementFactor(a, a->walkdata.destx, a->walkdata.desty); calcMovementFactor(a, a->walkdata.destx, a->walkdata.desty);
return; return;
} }
if(p[2].x != 32000) if (p[2].x != 32000) {
{ if (calcMovementFactor(a, p[2].x, p[2].y)) {
if(calcMovementFactor(a, p[2].x, p[2].y))
{
actor->walkdata.point3x = p[3].x; actor->walkdata.point3x = p[3].x;
actor->walkdata.point3y = p[3].y; actor->walkdata.point3y = p[3].y;
return; return;
@ -1277,24 +1326,20 @@ restart:
} }
if(a->moving & 2) if (a->moving & 2) {
{
if (actorWalkStep(a)) if (actorWalkStep(a))
return; return;
} }
if(a->moving & 8) if (a->moving & 8) {
{
a->moving = 0; a->moving = 0;
startWalkAnim(a, 3, a->walkdata.destdir); startWalkAnim(a, 3, a->walkdata.destdir);
return; return;
} }
if(a->moving & 4) if (a->moving & 4) {
{
new_dir = updateActorDirection(a); new_dir = updateActorDirection(a);
if (a->facing != new_dir) if (a->facing != new_dir) {
{
fixActorDirection(a, new_dir); fixActorDirection(a, new_dir);
return; return;
} }
@ -1302,10 +1347,8 @@ restart:
return; return;
} }
if(a->walkdata.point3x != 32000) if (a->walkdata.point3x != 32000) {
{ if (calcMovementFactor(a, a->walkdata.point3x, a->walkdata.point3y)) {
if(calcMovementFactor(a,a->walkdata.point3x,a->walkdata.point3y))
{
a->walkdata.point3x = 32000; a->walkdata.point3x = 32000;
return; return;
} }

208
akos.cpp
View file

@ -22,7 +22,8 @@
#include "stdafx.h" #include "stdafx.h"
#include "scumm.h" #include "scumm.h"
bool Scumm::akos_hasManyDirections(Actor *a) { bool Scumm::akos_hasManyDirections(Actor * a)
{
if (_features & GF_NEW_COSTUMES) { if (_features & GF_NEW_COSTUMES) {
byte *akos; byte *akos;
AkosHeader *akhd; AkosHeader *akhd;
@ -44,10 +45,8 @@ int Scumm::akos_findManyDirection(int16 ManyDirection, uint16 facing)
temp = many_direction_tab[ManyDirection]; temp = many_direction_tab[ManyDirection];
direction = temp + ManyDirection * 8; direction = temp + ManyDirection * 8;
do { do {
if(facing>=many_direction_tab[direction+1]) if (facing >= many_direction_tab[direction + 1]) {
{ if (facing <= many_direction_tab[direction + 2]) {
if(facing<=many_direction_tab[direction+2])
{
return (temp); return (temp);
} }
} }
@ -61,7 +60,8 @@ int Scumm::akos_findManyDirection(int16 ManyDirection, uint16 facing)
} }
int Scumm::akos_frameToAnim(Actor *a, int frame) { int Scumm::akos_frameToAnim(Actor * a, int frame)
{
bool ManyDirection; bool ManyDirection;
ManyDirection = akos_hasManyDirections(a); ManyDirection = akos_hasManyDirections(a);
@ -74,7 +74,8 @@ int Scumm::akos_frameToAnim(Actor *a, int frame) {
} }
} }
void Scumm::akos_decodeData(Actor *a, int frame, uint usemask) { void Scumm::akos_decodeData(Actor * a, int frame, uint usemask)
{
uint anim; uint anim;
byte *akos, *r; byte *akos, *r;
AkosHeader *akhd; AkosHeader *akhd;
@ -149,7 +150,8 @@ void Scumm::akos_decodeData(Actor *a, int frame, uint usemask) {
} while ((uint16)mask); } while ((uint16)mask);
} }
void Scumm::akos_setPalette(AkosRenderer *ar, byte *palette) { void Scumm::akos_setPalette(AkosRenderer * ar, byte *palette)
{
byte *akpl; byte *akpl;
uint size, i; uint size, i;
@ -164,7 +166,8 @@ void Scumm::akos_setPalette(AkosRenderer *ar, byte *palette) {
} }
} }
void Scumm::akos_setCostume(AkosRenderer *ar, int costume) { void Scumm::akos_setCostume(AkosRenderer * ar, int costume)
{
ar->akos = getResourceAddress(rtCostume, costume); ar->akos = getResourceAddress(rtCostume, costume);
assert(ar->akos); assert(ar->akos);
@ -177,13 +180,15 @@ void Scumm::akos_setCostume(AkosRenderer *ar, int costume) {
ar->codec = READ_LE_UINT16(&ar->akhd->codec); ar->codec = READ_LE_UINT16(&ar->akhd->codec);
} }
void Scumm::akos_setFacing(AkosRenderer *ar, Actor *a) { void Scumm::akos_setFacing(AkosRenderer * ar, Actor * a)
{
ar->mirror = (newDirToOldDir(a->facing) != 0 || ar->akhd->flags & 1); ar->mirror = (newDirToOldDir(a->facing) != 0 || ar->akhd->flags & 1);
if (a->flip) if (a->flip)
ar->mirror ^= 1; ar->mirror ^= 1;
} }
bool Scumm::akos_drawCostume(AkosRenderer *ar) { bool Scumm::akos_drawCostume(AkosRenderer * ar)
{
int i; int i;
bool result = false; bool result = false;
@ -193,7 +198,8 @@ bool Scumm::akos_drawCostume(AkosRenderer *ar) {
return result; return result;
} }
bool Scumm::akos_drawCostumeChannel(AkosRenderer *ar, int chan) { bool Scumm::akos_drawCostumeChannel(AkosRenderer * ar, int chan)
{
uint code; uint code;
byte *p; byte *p;
AkosOffset *off; AkosOffset *off;
@ -206,7 +212,8 @@ bool Scumm::akos_drawCostumeChannel(AkosRenderer *ar, int chan) {
p = ar->aksq + ar->cd->curpos[chan]; p = ar->aksq + ar->cd->curpos[chan];
code = p[0]; code = p[0];
if (code & 0x80) code = (code<<8)|p[1]; if (code & 0x80)
code = (code << 8) | p[1];
if (code == AKC_Return) if (code == AKC_Return)
return false; return false;
@ -214,7 +221,8 @@ bool Scumm::akos_drawCostumeChannel(AkosRenderer *ar, int chan) {
if (code != AKC_ComplexChan) { if (code != AKC_ComplexChan) {
off = ar->akof + (code & 0xFFF); off = ar->akof + (code & 0xFFF);
assert( (code & 0xFFF)*6 < READ_BE_UINT32_UNALIGNED((byte*)ar->akof - 4)-8 ); assert((code & 0xFFF) * 6 <
READ_BE_UINT32_UNALIGNED((byte *)ar->akof - 4) - 8);
assert((code & 0x7000) == 0); assert((code & 0x7000) == 0);
@ -247,7 +255,8 @@ bool Scumm::akos_drawCostumeChannel(AkosRenderer *ar, int chan) {
for (i = 0; i != extra; i++) { for (i = 0; i != extra; i++) {
code = p[4]; code = p[4];
if (code&0x80) code = ((code&0xF)<<8)|p[5]; if (code & 0x80)
code = ((code & 0xF) << 8) | p[5];
off = ar->akof + code; off = ar->akof + code;
ar->srcptr = ar->akcd + READ_LE_UINT32(&off->akcd); ar->srcptr = ar->akcd + READ_LE_UINT32(&off->akcd);
@ -280,7 +289,8 @@ bool Scumm::akos_drawCostumeChannel(AkosRenderer *ar, int chan) {
return true; return true;
} }
void akos_c1_0y_decode(AkosRenderer *ar) { void akos_c1_0y_decode(AkosRenderer * ar)
{
byte len, color; byte len, color;
byte *src, *dst; byte *src, *dst;
int height; int height;
@ -295,13 +305,15 @@ void akos_c1_0y_decode(AkosRenderer *ar) {
height = ar->height; height = ar->height;
y = ar->v1.y; y = ar->v1.y;
if (len) goto StartPos; if (len)
goto StartPos;
do { do {
len = *src++; len = *src++;
color = len >> ar->v1.shl; color = len >> ar->v1.shl;
len &= ar->v1.mask; len &= ar->v1.mask;
if (!len) len = *src++; if (!len)
len = *src++;
do { do {
if (color && y < scrheight) { if (color && y < scrheight) {
@ -322,7 +334,8 @@ StartPos:;
} while (1); } while (1);
} }
void akos_generic_decode(AkosRenderer *ar) { void akos_generic_decode(AkosRenderer * ar)
{
byte *src, *dst; byte *src, *dst;
byte len, height, maskbit; byte len, height, maskbit;
uint y, color; uint y, color;
@ -341,17 +354,21 @@ void akos_generic_decode(AkosRenderer *ar) {
maskbit = revBitMask[ar->v1.x & 7]; maskbit = revBitMask[ar->v1.x & 7];
mask = ar->v1.mask_ptr + (ar->v1.x >> 3); mask = ar->v1.mask_ptr + (ar->v1.x >> 3);
if (len) goto StartPos; if (len)
goto StartPos;
do { do {
len = *src++; len = *src++;
color = len >> ar->v1.shl; color = len >> ar->v1.shl;
len &= ar->v1.mask; len &= ar->v1.mask;
if (!len) len = *src++; if (!len)
len = *src++;
do { do {
if (*scaleytab++ < ar->scale_y) { if (*scaleytab++ < ar->scale_y) {
if (color && y < ar->outheight && (!ar->v1.mask_ptr || !((mask[0]|mask[ar->v1.imgbufoffs]) & maskbit)) ) { if (color && y < ar->outheight
&& (!ar->v1.mask_ptr
|| !((mask[0] | mask[ar->v1.imgbufoffs]) & maskbit))) {
*dst = ar->palette[color]; *dst = ar->palette[color];
} }
mask += 40; mask += 40;
@ -383,7 +400,8 @@ StartPos:;
} }
void akos_c1_spec1(AkosRenderer *ar) { void akos_c1_spec1(AkosRenderer * ar)
{
byte *src, *dst; byte *src, *dst;
byte len, height, pcolor, maskbit; byte len, height, pcolor, maskbit;
uint y, color; uint y, color;
@ -402,17 +420,21 @@ void akos_c1_spec1(AkosRenderer *ar) {
maskbit = revBitMask[ar->v1.x & 7]; maskbit = revBitMask[ar->v1.x & 7];
mask = ar->v1.mask_ptr + (ar->v1.x >> 3); mask = ar->v1.mask_ptr + (ar->v1.x >> 3);
if (len) goto StartPos; if (len)
goto StartPos;
do { do {
len = *src++; len = *src++;
color = len >> ar->v1.shl; color = len >> ar->v1.shl;
len &= ar->v1.mask; len &= ar->v1.mask;
if (!len) len = *src++; if (!len)
len = *src++;
do { do {
if (*scaleytab++ < ar->scale_y) { if (*scaleytab++ < ar->scale_y) {
if (color && y < ar->outheight && (!ar->v1.mask_ptr || !((mask[0]|mask[ar->v1.imgbufoffs]) & maskbit)) ) { if (color && y < ar->outheight
&& (!ar->v1.mask_ptr
|| !((mask[0] | mask[ar->v1.imgbufoffs]) & maskbit))) {
pcolor = ar->palette[color]; pcolor = ar->palette[color];
if (pcolor == 13) if (pcolor == 13)
pcolor = ar->shadow_table[*dst]; pcolor = ar->shadow_table[*dst];
@ -548,7 +570,8 @@ const byte default_scale_table[768] = {
}; };
void Scumm::akos_codec1(AkosRenderer *ar) { void Scumm::akos_codec1(AkosRenderer * ar)
{
int num_colors; int num_colors;
bool use_scaling; bool use_scaling;
int i, j; int i, j;
@ -633,7 +656,8 @@ void Scumm::akos_codec1(AkosRenderer *ar) {
} }
} }
if (skip) skip--; if (skip)
skip--;
step = -1; step = -1;
if (ar->move_y_cur < 0) { if (ar->move_y_cur < 0) {
@ -744,7 +768,8 @@ void Scumm::akos_codec1(AkosRenderer *ar) {
if (y_bottom > ar->draw_bottom) if (y_bottom > ar->draw_bottom)
ar->draw_bottom = y_bottom; ar->draw_bottom = y_bottom;
if (x==-1) x=0; /* ?? */ if (x == -1)
x = 0; /* ?? */
ar->v1.destptr = ar->outptr + x + y * ar->outwidth; ar->v1.destptr = ar->outptr + x + y * ar->outwidth;
@ -752,14 +777,17 @@ void Scumm::akos_codec1(AkosRenderer *ar) {
masking = false; masking = false;
if (ar->clipping) { if (ar->clipping) {
masking = isMaskActiveAt(x_left, y_top, x_right, y_bottom, masking = isMaskActiveAt(x_left, y_top, x_right, y_bottom,
getResourceAddress(rtBuffer, 9) + gdi._imgBufOffs[ar->clipping] + _screenStartStrip getResourceAddress(rtBuffer,
) != 0; 9) +
gdi._imgBufOffs[ar->clipping] +
_screenStartStrip) != 0;
} }
ar->v1.mask_ptr = NULL; ar->v1.mask_ptr = NULL;
if (masking || charsetmask || ar->shadow_mode) { if (masking || charsetmask || ar->shadow_mode) {
ar->v1.mask_ptr = getResourceAddress(rtBuffer, 9) + y*40 + _screenStartStrip; ar->v1.mask_ptr =
getResourceAddress(rtBuffer, 9) + y * 40 + _screenStartStrip;
ar->v1.imgbufoffs = gdi._imgBufOffs[ar->clipping]; ar->v1.imgbufoffs = gdi._imgBufOffs[ar->clipping];
if (!charsetmask && masking) { if (!charsetmask && masking) {
ar->v1.mask_ptr += ar->v1.imgbufoffs; ar->v1.mask_ptr += ar->v1.imgbufoffs;
@ -787,36 +815,59 @@ void Scumm::akos_codec1(AkosRenderer *ar) {
#if 0 #if 0
switch(((byte)y_clipping<<3) | ((byte)use_scaling<<2) | ((byte)masking<<1) | (byte)charsetmask) { switch (((byte)y_clipping << 3) | ((byte)use_scaling << 2) |
case 0: akos_c1_0_decode(ar); break; ((byte)masking << 1) | (byte)charsetmask) {
case 0+8: akos_c1_0y_decode(ar); break; case 0:
akos_c1_0_decode(ar);
break;
case 0 + 8:
akos_c1_0y_decode(ar);
break;
case 2: case 2:
case 1: akos_c1_12_decode(ar); break; case 1:
akos_c1_12_decode(ar);
break;
case 2 + 8: case 2 + 8:
case 1+8: akos_c1_12y_decode(ar); break; case 1 + 8:
akos_c1_12y_decode(ar);
break;
case 3 + 8: case 3 + 8:
case 3: akos_c1_3_decode(ar); break; case 3:
case 4: akos_c1_4_decode(ar); break; akos_c1_3_decode(ar);
case 4+8: akos_c1_4y_decode(ar); break; break;
case 4:
akos_c1_4_decode(ar);
break;
case 4 + 8:
akos_c1_4y_decode(ar);
break;
case 6: case 6:
case 5: akos_c1_56_decode(ar); break; case 5:
akos_c1_56_decode(ar);
break;
case 6 + 8: case 6 + 8:
case 5+8: akos_c1_56y_decode(ar); break; case 5 + 8:
akos_c1_56y_decode(ar);
break;
case 7: case 7:
case 7+8: akos_c1_7_decode(ar); break; case 7 + 8:
akos_c1_7_decode(ar);
break;
} }
#endif #endif
} }
void Scumm::akos_codec1_ignorePakCols(AkosRenderer *ar, int num) { void Scumm::akos_codec1_ignorePakCols(AkosRenderer * ar, int num)
{
int n; int n;
byte repcolor; byte repcolor;
byte replen; byte replen;
byte *src; byte *src;
n = ar->height; n = ar->height;
if (num>1) n *= num; if (num > 1)
n *= num;
src = ar->srcptr; src = ar->srcptr;
do { do {
repcolor = *src++; repcolor = *src++;
@ -836,16 +887,19 @@ void Scumm::akos_codec1_ignorePakCols(AkosRenderer *ar, int num) {
} }
void Scumm::akos_codec5(AkosRenderer *ar) { void Scumm::akos_codec5(AkosRenderer * ar)
{
warning("akos_codec5: not implemented"); warning("akos_codec5: not implemented");
} }
void Scumm::akos_codec16(AkosRenderer *ar) { void Scumm::akos_codec16(AkosRenderer * ar)
{
warning("akos_codec16: not implemented"); warning("akos_codec16: not implemented");
} }
bool Scumm::akos_increaseAnims(byte *akos, Actor *a) { bool Scumm::akos_increaseAnims(byte *akos, Actor * a)
{
byte *aksq, *akfo; byte *aksq, *akfo;
int i; int i;
uint size; uint size;
@ -869,7 +923,9 @@ bool Scumm::akos_increaseAnims(byte *akos, Actor *a) {
#define GUW(o) READ_LE_UINT16(aksq+curpos+(o)) #define GUW(o) READ_LE_UINT16(aksq+curpos+(o))
#define GB(o) aksq[curpos+(o)] #define GB(o) aksq[curpos+(o)]
bool Scumm::akos_increaseAnim(Actor *a, int chan, byte *aksq, uint16 *akfo, int numakfo) { bool Scumm::akos_increaseAnim(Actor * a, int chan, byte *aksq, uint16 *akfo,
int numakfo)
{
byte active; byte active;
uint old_curpos, curpos, end; uint old_curpos, curpos, end;
uint code; uint code;
@ -884,7 +940,8 @@ bool Scumm::akos_increaseAnim(Actor *a, int chan, byte *aksq, uint16 *akfo, int
do { do {
code = aksq[curpos]; code = aksq[curpos];
if (code & 0x80) code = (code<<8)|aksq[curpos+1]; if (code & 0x80)
code = (code << 8) | aksq[curpos + 1];
switch (active) { switch (active) {
case 6: case 6:
@ -962,7 +1019,8 @@ bool Scumm::akos_increaseAnim(Actor *a, int chan, byte *aksq, uint16 *akfo, int
} }
code = aksq[curpos]; code = aksq[curpos];
if (code & 0x80) code = (code<<8)|aksq[curpos+1]; if (code & 0x80)
code = (code << 8) | aksq[curpos + 1];
if (flag_value && code != AKC_ClearFlag) if (flag_value && code != AKC_ClearFlag)
continue; continue;
@ -970,10 +1028,11 @@ bool Scumm::akos_increaseAnim(Actor *a, int chan, byte *aksq, uint16 *akfo, int
switch (code) { switch (code) {
case AKC_StartAnimInActor: case AKC_StartAnimInActor:
akos_queCommand(4, akos_queCommand(4,
derefActorSafe(getAnimVar(a, GB(2)), "akos_increaseAnim:29"), derefActorSafe(getAnimVar(a, GB(2)),
getAnimVar(a, GB(3)), "akos_increaseAnim:29"), getAnimVar(a,
0 GB
); (3)),
0);
continue; continue;
case AKC_Random: case AKC_Random:
@ -1015,8 +1074,7 @@ bool Scumm::akos_increaseAnim(Actor *a, int chan, byte *aksq, uint16 *akfo, int
akos_queCommand(4, a, getAnimVar(a, GB(2)), 0); akos_queCommand(4, a, getAnimVar(a, GB(2)), 0);
continue; continue;
case AKC_SetVarInActor: case AKC_SetVarInActor:
setAnimVar( setAnimVar(derefActorSafe(getAnimVar(a, GB(2)), "akos_increaseAnim:9"),
derefActorSafe(getAnimVar(a, GB(2)),"akos_increaseAnim:9"),
GB(3), GW(4) GB(3), GW(4)
); );
continue; continue;
@ -1089,34 +1147,46 @@ bool Scumm::akos_increaseAnim(Actor *a, int chan, byte *aksq, uint16 *akfo, int
} while (1); } while (1);
int code2 = aksq[curpos]; int code2 = aksq[curpos];
if (code2 & 0x80) code2 = (code2<<8)|aksq[curpos+1]; if (code2 & 0x80)
assert((code2&0xC000)!=0xC000 || code2==AKC_ComplexChan || code2==AKC_Return); code2 = (code2 << 8) | aksq[curpos + 1];
assert((code2 & 0xC000) != 0xC000 || code2 == AKC_ComplexChan
|| code2 == AKC_Return);
a->cost.curpos[chan] = curpos; a->cost.curpos[chan] = curpos;
return curpos != old_curpos; return curpos != old_curpos;
} }
void Scumm::akos_queCommand(byte cmd, Actor *a, int param_1, int param_2) { void Scumm::akos_queCommand(byte cmd, Actor * a, int param_1, int param_2)
{
// warning("akos_queCommand(%d,%d,%d,%d)", cmd, a->number, param_1, param_2); // warning("akos_queCommand(%d,%d,%d,%d)", cmd, a->number, param_1, param_2);
} }
bool Scumm::akos_compare(int a, int b, byte cmd) { bool Scumm::akos_compare(int a, int b, byte cmd)
{
switch (cmd) { switch (cmd) {
case 0: return a==b; case 0:
case 1: return a!=b; return a == b;
case 2: return a<b; case 1:
case 3: return a<=b; return a != b;
case 4: return a>b; case 2:
default: return a>=b; return a < b;
case 3:
return a <= b;
case 4:
return a > b;
default:
return a >= b;
} }
} }
int Scumm::getAnimVar(Actor *a, byte var) { int Scumm::getAnimVar(Actor * a, byte var)
{
return a->animVariable[var]; return a->animVariable[var];
} }
void Scumm::setAnimVar(Actor *a, byte var, int value) { void Scumm::setAnimVar(Actor * a, byte var, int value)
{
a->animVariable[var] = value; a->animVariable[var] = value;
} }

178
boxes.cpp
View file

@ -24,21 +24,24 @@
#include "scumm.h" #include "scumm.h"
#include "math.h" #include "math.h"
byte Scumm::getMaskFromBox(int box) { byte Scumm::getMaskFromBox(int box)
{
Box *ptr = getBoxBaseAddr(box); Box *ptr = getBoxBaseAddr(box);
if (!ptr) if (!ptr)
return 0; return 0;
return ptr->mask; return ptr->mask;
} }
byte Scumm::getBoxFlags(int box) { byte Scumm::getBoxFlags(int box)
{
Box *ptr = getBoxBaseAddr(box); Box *ptr = getBoxBaseAddr(box);
if (!ptr) if (!ptr)
return 0; return 0;
return ptr->flags; return ptr->flags;
} }
int Scumm::getBoxScale(int box) { int Scumm::getBoxScale(int box)
{
if (_features & GF_NO_SCALLING) if (_features & GF_NO_SCALLING)
return (255); return (255);
Box *ptr = getBoxBaseAddr(box); Box *ptr = getBoxBaseAddr(box);
@ -47,13 +50,16 @@ int Scumm::getBoxScale(int box) {
return FROM_LE_16(ptr->scale); return FROM_LE_16(ptr->scale);
} }
byte Scumm::getNumBoxes() { byte Scumm::getNumBoxes()
{
byte *ptr = getResourceAddress(rtMatrix, 2); byte *ptr = getResourceAddress(rtMatrix, 2);
if (!ptr) return 0; if (!ptr)
return 0;
return ptr[0]; return ptr[0];
} }
Box *Scumm::getBoxBaseAddr(int box) { Box *Scumm::getBoxBaseAddr(int box)
{
byte *ptr = getResourceAddress(rtMatrix, 2); byte *ptr = getResourceAddress(rtMatrix, 2);
if (!ptr) if (!ptr)
return NULL; return NULL;
@ -67,7 +73,8 @@ Box *Scumm::getBoxBaseAddr(int box) {
return (Box *) (ptr + box * SIZEOF_BOX + 2); return (Box *) (ptr + box * SIZEOF_BOX + 2);
} }
bool Scumm::checkXYInBoxBounds(int b, int x, int y) { bool Scumm::checkXYInBoxBounds(int b, int x, int y)
{
BoxCoords box; BoxCoords box;
if (b == 0 && (!(_features & GF_SMALL_HEADER))) if (b == 0 && (!(_features & GF_SMALL_HEADER)))
@ -75,20 +82,16 @@ bool Scumm::checkXYInBoxBounds(int b, int x, int y) {
getBoxCoordinates(b, &box); getBoxCoordinates(b, &box);
if (x < box.ul.x && x < box.ur.x && if (x < box.ul.x && x < box.ur.x && x < box.ll.x && x < box.lr.x)
x < box.ll.x && x < box.lr.x)
return 0; return 0;
if (x > box.ul.x && x > box.ur.x && if (x > box.ul.x && x > box.ur.x && x > box.ll.x && x > box.lr.x)
x > box.ll.x && x > box.lr.x)
return 0; return 0;
if (y < box.ul.y && y < box.ur.y && if (y < box.ul.y && y < box.ur.y && y < box.ll.y && y < box.lr.y)
y < box.ll.y && y < box.lr.y)
return 0; return 0;
if (y > box.ul.y && y > box.ur.y && if (y > box.ul.y && y > box.ur.y && y > box.ll.y && y > box.lr.y)
y > box.ll.y && y > box.lr.y)
return 0; return 0;
if (box.ul.x == box.ur.x && if (box.ul.x == box.ur.x &&
@ -96,9 +99,7 @@ bool Scumm::checkXYInBoxBounds(int b, int x, int y) {
box.ll.x == box.lr.x && box.ll.x == box.lr.x &&
box.ll.y == box.lr.y || box.ll.y == box.lr.y ||
box.ul.x == box.lr.x && box.ul.x == box.lr.x &&
box.ul.y == box.lr.y && box.ul.y == box.lr.y && box.ur.x == box.ll.x && box.ur.y == box.ll.y) {
box.ur.x== box.ll.x &&
box.ur.y== box.ll.y) {
ScummPoint pt; ScummPoint pt;
pt = closestPtOnLine(box.ul.x, box.ul.y, box.ll.x, box.ll.y, x, y); pt = closestPtOnLine(box.ul.x, box.ul.y, box.ll.x, box.ll.y, x, y);
@ -106,26 +107,23 @@ bool Scumm::checkXYInBoxBounds(int b, int x, int y) {
return 1; return 1;
} }
if (!getSideOfLine( if (!getSideOfLine(box.ul.x, box.ul.y, box.ur.x, box.ur.y, x, y, b))
box.ul.x, box.ul.y, box.ur.x, box.ur.y, x,y,b))
return 0; return 0;
if (!getSideOfLine( if (!getSideOfLine(box.ur.x, box.ur.y, box.ll.x, box.ll.y, x, y, b))
box.ur.x, box.ur.y, box.ll.x, box.ll.y, x,y,b))
return 0; return 0;
if (!getSideOfLine( if (!getSideOfLine(box.ll.x, box.ll.y, box.lr.x, box.lr.y, x, y, b))
box.ll.x, box.ll.y, box.lr.x, box.lr.y, x,y,b))
return 0; return 0;
if (!getSideOfLine( if (!getSideOfLine(box.lr.x, box.lr.y, box.ul.x, box.ul.y, x, y, b))
box.lr.x, box.lr.y, box.ul.x, box.ul.y, x,y,b))
return 0; return 0;
return 1; return 1;
} }
void Scumm::getBoxCoordinates(int boxnum, BoxCoords *box) { void Scumm::getBoxCoordinates(int boxnum, BoxCoords * box)
{
Box *bp = getBoxBaseAddr(boxnum); Box *bp = getBoxBaseAddr(boxnum);
box->ul.x = (int16) FROM_LE_16(bp->ulx); box->ul.x = (int16) FROM_LE_16(bp->ulx);
@ -133,15 +131,12 @@ void Scumm::getBoxCoordinates(int boxnum, BoxCoords *box) {
box->ur.x = (int16) FROM_LE_16(bp->urx); box->ur.x = (int16) FROM_LE_16(bp->urx);
box->ur.y = (int16) FROM_LE_16(bp->ury); box->ur.y = (int16) FROM_LE_16(bp->ury);
if(_features & GF_OLD256) if (_features & GF_OLD256) {
{
box->ll.x = (int16) FROM_LE_16(bp->lrx); box->ll.x = (int16) FROM_LE_16(bp->lrx);
box->ll.y = (int16) FROM_LE_16(bp->lry); box->ll.y = (int16) FROM_LE_16(bp->lry);
box->lr.x = (int16) FROM_LE_16(bp->llx); box->lr.x = (int16) FROM_LE_16(bp->llx);
box->lr.y = (int16) FROM_LE_16(bp->lly); box->lr.y = (int16) FROM_LE_16(bp->lly);
} } else {
else
{
box->ll.x = (int16) FROM_LE_16(bp->llx); box->ll.x = (int16) FROM_LE_16(bp->llx);
box->ll.y = (int16) FROM_LE_16(bp->lly); box->ll.y = (int16) FROM_LE_16(bp->lly);
box->lr.x = (int16) FROM_LE_16(bp->lrx); box->lr.x = (int16) FROM_LE_16(bp->lrx);
@ -150,7 +145,8 @@ void Scumm::getBoxCoordinates(int boxnum, BoxCoords *box) {
} }
uint Scumm::distanceFromPt(int x, int y, int ptx, int pty) { uint Scumm::distanceFromPt(int x, int y, int ptx, int pty)
{
int diffx, diffy; int diffx, diffy;
diffx = abs(ptx - x); diffx = abs(ptx - x);
@ -167,11 +163,15 @@ uint Scumm::distanceFromPt(int x, int y, int ptx, int pty) {
return diffx + diffy; return diffx + diffy;
} }
bool Scumm::getSideOfLine(int x1,int y1, int x2, int y2, int x, int y, int box) { bool Scumm::getSideOfLine(int x1, int y1, int x2, int y2, int x, int y,
int box)
{
return (x - x1) * (y2 - y1) <= (y - y1) * (x2 - x1); return (x - x1) * (y2 - y1) <= (y - y1) * (x2 - x1);
} }
ScummPoint Scumm::closestPtOnLine(int ulx, int uly, int llx, int lly, int x, int y) { ScummPoint Scumm::closestPtOnLine(int ulx, int uly, int llx, int lly, int x,
int y)
{
int lydiff, lxdiff; int lydiff, lxdiff;
int32 dist, a, b, c; int32 dist, a, b, c;
int x2, y2; int x2, y2;
@ -226,16 +226,22 @@ type2:;
y2 = lly; y2 = lly;
} }
} else { } else {
if (x2 > ulx) goto type1; if (x2 > ulx)
if (x2 < llx) goto type2; goto type1;
if (x2 < llx)
goto type2;
} }
} else { } else {
if (lydiff > 0) { if (lydiff > 0) {
if (y2 < uly) goto type1; if (y2 < uly)
if (y2 > lly) goto type2; goto type1;
if (y2 > lly)
goto type2;
} else { } else {
if (y2 > uly) goto type1; if (y2 > uly)
if (y2 < lly) goto type2; goto type1;
if (y2 < lly)
goto type2;
} }
} }
@ -244,7 +250,8 @@ type2:;
return pt; return pt;
} }
bool Scumm::inBoxQuickReject(int b, int x, int y, int threshold) { bool Scumm::inBoxQuickReject(int b, int x, int y, int threshold)
{
int t; int t;
BoxCoords box; BoxCoords box;
@ -254,29 +261,26 @@ bool Scumm::inBoxQuickReject(int b, int x, int y, int threshold) {
return 1; return 1;
t = x - threshold; t = x - threshold;
if (t > box.ul.x && t > box.ur.x && if (t > box.ul.x && t > box.ur.x && t > box.ll.x && t > box.lr.x)
t > box.ll.x && t > box.lr.x)
return 0; return 0;
t = x + threshold; t = x + threshold;
if (t < box.ul.x && t < box.ur.x && if (t < box.ul.x && t < box.ur.x && t < box.ll.x && t < box.lr.x)
t < box.ll.x && t < box.lr.x)
return 0; return 0;
t = y - threshold; t = y - threshold;
if (t > box.ul.y && t > box.ur.y && if (t > box.ul.y && t > box.ur.y && t > box.ll.y && t > box.lr.y)
t > box.ll.y && t > box.lr.y)
return 0; return 0;
t = y + threshold; t = y + threshold;
if (t < box.ul.y && t < box.ur.y && if (t < box.ul.y && t < box.ur.y && t < box.ll.y && t < box.lr.y)
t < box.ll.y && t < box.lr.y)
return 0; return 0;
return 1; return 1;
} }
AdjustBoxResult Scumm::getClosestPtOnBox(int b, int x, int y) { AdjustBoxResult Scumm::getClosestPtOnBox(int b, int x, int y)
{
ScummPoint pt; ScummPoint pt;
AdjustBoxResult best; AdjustBoxResult best;
uint dist; uint dist;
@ -321,13 +325,16 @@ AdjustBoxResult Scumm::getClosestPtOnBox(int b, int x, int y) {
return best; return best;
} }
byte *Scumm::getBoxMatrixBaseAddr() { byte *Scumm::getBoxMatrixBaseAddr()
{
byte *ptr = getResourceAddress(rtMatrix, 1); byte *ptr = getResourceAddress(rtMatrix, 1);
if (*ptr==0xFF) ptr++; if (*ptr == 0xFF)
ptr++;
return ptr; return ptr;
} }
int Scumm::getPathToDestBox(byte from, byte to) { int Scumm::getPathToDestBox(byte from, byte to)
{
byte *boxm; byte *boxm;
byte i; byte i;
@ -352,7 +359,8 @@ int Scumm::getPathToDestBox(byte from, byte to) {
return -1; return -1;
} }
int Scumm::findPathTowards(Actor *a, byte box1nr, byte box2nr, byte box3nr) { int Scumm::findPathTowards(Actor * a, byte box1nr, byte box2nr, byte box3nr)
{
BoxCoords box1; BoxCoords box1;
BoxCoords box2; BoxCoords box2;
ScummPoint tmp; ScummPoint tmp;
@ -366,8 +374,7 @@ int Scumm::findPathTowards(Actor *a, byte box1nr, byte box2nr, byte box3nr) {
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) { for (j = 0; j < 4; j++) {
if (box1.ul.x == box1.ur.x && if (box1.ul.x == box1.ur.x &&
box1.ul.x==box2.ul.x && box1.ul.x == box2.ul.x && box1.ul.x == box2.ur.x) {
box1.ul.x==box2.ur.x) {
flag = 0; flag = 0;
if (box1.ul.y > box1.ur.y) { if (box1.ul.y > box1.ur.y) {
SWAP(box1.ul.y, box1.ur.y); SWAP(box1.ul.y, box1.ur.y);
@ -397,7 +404,8 @@ int Scumm::findPathTowards(Actor *a, byte box1nr, byte box2nr, byte box3nr) {
diffY *= boxDiffX; diffY *= boxDiffX;
t = diffY / diffX; t = diffY / diffX;
if (t==0 && (diffY<=0 || diffX<=0) && (diffY>=0 || diffX>=0)) if (t == 0 && (diffY <= 0 || diffX <= 0)
&& (diffY >= 0 || diffX >= 0))
t = -1; t = -1;
pos = a->y + t; pos = a->y + t;
} else { } else {
@ -425,8 +433,7 @@ int Scumm::findPathTowards(Actor *a, byte box1nr, byte box2nr, byte box3nr) {
} }
if (box1.ul.y == box1.ur.y && if (box1.ul.y == box1.ur.y &&
box1.ul.y==box2.ul.y && box1.ul.y == box2.ul.y && box1.ul.y == box2.ur.y) {
box1.ul.y==box2.ur.y) {
flag = 0; flag = 0;
if (box1.ul.x > box1.ur.x) { if (box1.ul.x > box1.ur.x) {
SWAP(box1.ul.x, box1.ur.x); SWAP(box1.ul.x, box1.ur.x);
@ -490,7 +497,8 @@ int Scumm::findPathTowards(Actor *a, byte box1nr, byte box2nr, byte box3nr) {
} }
return 0; return 0;
} }
void Scumm::setBoxFlags(int box, int val) { void Scumm::setBoxFlags(int box, int val)
{
/* FULL_THROTTLE stuff */ /* FULL_THROTTLE stuff */
if (val & 0xC000) { if (val & 0xC000) {
assert(box >= 0 && box < 65); assert(box >= 0 && box < 65);
@ -501,14 +509,16 @@ void Scumm::setBoxFlags(int box, int val) {
} }
} }
void Scumm::setBoxScale(int box, int scale) { void Scumm::setBoxScale(int box, int scale)
{
Box *b = getBoxBaseAddr(box); Box *b = getBoxBaseAddr(box);
b->scale = scale; b->scale = scale;
} }
#define BOX_MATRIX_SIZE 2000 #define BOX_MATRIX_SIZE 2000
void Scumm::createBoxMatrix() { void Scumm::createBoxMatrix()
{
byte *matrix_ptr; byte *matrix_ptr;
int num, i, j; int num, i, j;
byte flags; byte flags;
@ -573,7 +583,8 @@ void Scumm::createBoxMatrix() {
while (node) { while (node) {
val = _boxMatrixPtr3[j * 64 + node->index]; val = _boxMatrixPtr3[j * 64 + node->index];
table_1[node->index] = val; table_1[node->index] = val;
if (val<counter) counter=val; if (val < counter)
counter = val;
if (table_1[node->index] != 250) if (table_1[node->index] != 250)
table_2[node->index] = node->index; table_2[node->index] = node->index;
@ -637,7 +648,8 @@ void Scumm::createBoxMatrix() {
nukeResource(rtMatrix, 3); nukeResource(rtMatrix, 3);
} }
PathVertex *Scumm::unkMatrixProc1(PathVertex *vtx, PathNode *node) { PathVertex *Scumm::unkMatrixProc1(PathVertex * vtx, PathNode * node)
{
if (node == NULL || vtx == NULL) if (node == NULL || vtx == NULL)
return NULL; return NULL;
@ -659,7 +671,8 @@ PathVertex *Scumm::unkMatrixProc1(PathVertex *vtx, PathNode *node) {
return NULL; return NULL;
} }
PathNode *Scumm::unkMatrixProc2(PathVertex *vtx, int i) { PathNode *Scumm::unkMatrixProc2(PathVertex * vtx, int i)
{
PathNode *node; PathNode *node;
if (vtx == NULL) if (vtx == NULL)
@ -687,7 +700,8 @@ PathNode *Scumm::unkMatrixProc2(PathVertex *vtx, int i) {
} }
/* Check if two boxes are neighbours */ /* Check if two boxes are neighbours */
bool Scumm::areBoxesNeighbours(int box1nr, int box2nr) { bool Scumm::areBoxesNeighbours(int box1nr, int box2nr)
{
int j, k, m, n; int j, k, m, n;
int tmp_x, tmp_y; int tmp_x, tmp_y;
bool result; bool result;
@ -707,8 +721,7 @@ bool Scumm::areBoxesNeighbours(int box1nr, int box2nr) {
k = 4; k = 4;
do { do {
if (box2.ur.x == box2.ul.x && if (box2.ur.x == box2.ul.x &&
box.ul.x == box2.ul.x && box.ul.x == box2.ul.x && box.ur.x == box2.ur.x) {
box.ur.x == box2.ur.x) {
n = m = 0; n = m = 0;
if (box2.ur.y < box2.ul.y) { if (box2.ur.y < box2.ul.y) {
n = 1; n = 1;
@ -722,8 +735,7 @@ bool Scumm::areBoxesNeighbours(int box1nr, int box2nr) {
box.ul.y > box2.ur.y || box.ul.y > box2.ur.y ||
(box.ul.y == box2.ur.y || (box.ul.y == box2.ur.y ||
box.ur.y == box2.ul.y) && box.ur.y == box2.ul.y) &&
box2.ur.y != box2.ul.y && box2.ur.y != box2.ul.y && box.ul.y != box.ur.y) {
box.ul.y!=box.ur.y) {
if (n) { if (n) {
SWAP(box2.ur.y, box2.ul.y); SWAP(box2.ur.y, box2.ul.y);
} }
@ -742,8 +754,7 @@ bool Scumm::areBoxesNeighbours(int box1nr, int box2nr) {
} }
if (box2.ur.y == box2.ul.y && if (box2.ur.y == box2.ul.y &&
box.ul.y == box2.ul.y && box.ul.y == box2.ul.y && box.ur.y == box2.ur.y) {
box.ur.y == box2.ur.y) {
n = m = 0; n = m = 0;
if (box2.ur.x < box2.ul.x) { if (box2.ur.x < box2.ul.x) {
n = 1; n = 1;
@ -757,8 +768,7 @@ bool Scumm::areBoxesNeighbours(int box1nr, int box2nr) {
box.ul.x > box2.ur.x || box.ul.x > box2.ur.x ||
(box.ul.x == box2.ur.x || (box.ul.x == box2.ur.x ||
box.ur.x == box2.ul.x) && box.ur.x == box2.ul.x) &&
box2.ur.x != box2.ul.x && box2.ur.x != box2.ul.x && box.ul.x != box.ur.x) {
box.ul.x!=box.ur.x) {
if (n) { if (n) {
SWAP(box2.ur.x, box2.ul.x); SWAP(box2.ur.x, box2.ul.x);
@ -804,13 +814,15 @@ bool Scumm::areBoxesNeighbours(int box1nr, int box2nr) {
return result; return result;
} }
void Scumm::addToBoxMatrix(byte b) { void Scumm::addToBoxMatrix(byte b)
{
if (++_boxMatrixItem > BOX_MATRIX_SIZE) if (++_boxMatrixItem > BOX_MATRIX_SIZE)
error("Box matrix overflow"); error("Box matrix overflow");
*_boxMatrixPtr1++ = b; *_boxMatrixPtr1++ = b;
} }
void *Scumm::addToBoxVertexHeap(int size) { void *Scumm::addToBoxVertexHeap(int size)
{
byte *ptr = _boxMatrixPtr4; byte *ptr = _boxMatrixPtr4;
_boxMatrixPtr4 += size; _boxMatrixPtr4 += size;
@ -822,14 +834,16 @@ void *Scumm::addToBoxVertexHeap(int size) {
return ptr; return ptr;
} }
PathVertex *Scumm::addPathVertex() { PathVertex *Scumm::addPathVertex()
{
_boxMatrixPtr4 = getResourceAddress(rtMatrix, 4); _boxMatrixPtr4 = getResourceAddress(rtMatrix, 4);
_boxPathVertexHeapIndex = 0; _boxPathVertexHeapIndex = 0;
return (PathVertex *) addToBoxVertexHeap(sizeof(PathVertex)); return (PathVertex *) addToBoxVertexHeap(sizeof(PathVertex));
} }
int Scumm::findPathTowardsOld(Actor *a, byte trap1, byte trap2, byte final_trap) int Scumm::findPathTowardsOld(Actor * a, byte trap1, byte trap2,
byte final_trap)
{ {
GetGates(trap1, trap2); GetGates(trap1, trap2);
ScummPoint pt; ScummPoint pt;
@ -868,7 +882,8 @@ int Scumm::findPathTowardsOld(Actor *a, byte trap1, byte trap2, byte final_trap)
return 0; return 0;
} }
void Scumm::GetGates(int trap1,int trap2) { void Scumm::GetGates(int trap1, int trap2)
{
int i; int i;
int Closest1 = 0, Closest2 = 0, Closest3 = 0; int Closest1 = 0, Closest2 = 0, Closest3 = 0;
int Dist[8]; int Dist[8];
@ -970,7 +985,8 @@ AdjustBoxResult pt;
int Scumm::CompareSlope(int X1, int Y1, int X2, int Y2, int X3, int Y3) int Scumm::CompareSlope(int X1, int Y1, int X2, int Y2, int X3, int Y3)
{ {
if ((Y2 - Y1) * (X3 - X1) > (Y3 - Y1) * (X2 - X1)) return(0); if ((Y2 - Y1) * (X3 - X1) > (Y3 - Y1) * (X2 - X1))
return (0);
return (1); return (1);
} }

View file

@ -25,10 +25,12 @@
const byte revBitMask[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; const byte revBitMask[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
void CostumeRenderer::ignorePakCols(int a) { void CostumeRenderer::ignorePakCols(int a)
{
int n; int n;
n = _height; n = _height;
if (a>1) n *= a; if (a > 1)
n *= a;
do { do {
_repcolor = *_srcptr++; _repcolor = *_srcptr++;
_replen = _repcolor & _maskval; _replen = _repcolor & _maskval;
@ -71,7 +73,8 @@ const byte cost_scaleTable[256] = {
238, 30, 158, 94, 222, 62, 190, 126, 254 238, 30, 158, 94, 222, 62, 190, 126, 254
}; };
byte CostumeRenderer::mainRoutine(Actor *a, int slot, int frame) { byte CostumeRenderer::mainRoutine(Actor * a, int slot, int frame)
{
int xmove, ymove, i, b, s; int xmove, ymove, i, b, s;
uint scal; uint scal;
byte scaling; byte scaling;
@ -79,9 +82,7 @@ byte CostumeRenderer::mainRoutine(Actor *a, int slot, int frame) {
byte unk19; byte unk19;
int ex1, ex2; int ex1, ex2;
CHECK_HEAP CHECK_HEAP _maskval = 0xF;
_maskval = 0xF;
_shrval = 4; _shrval = 4;
if (_loaded._numColors == 32) { if (_loaded._numColors == 32) {
_maskval = 7; _maskval = 7;
@ -99,13 +100,15 @@ byte CostumeRenderer::mainRoutine(Actor *a, int slot, int frame) {
_srcptr += 12; _srcptr += 12;
switch (_loaded._ptr[7] & 0x7F) { switch (_loaded._ptr[7] & 0x7F) {
case 0x60: case 0x61: case 0x60:
case 0x61:
ex1 = _srcptr[0]; ex1 = _srcptr[0];
ex2 = _srcptr[1]; ex2 = _srcptr[1];
_srcptr += 2; _srcptr += 2;
if (ex1 != 0xFF || ex2 != 0xFF) { if (ex1 != 0xFF || ex2 != 0xFF) {
ex1 = READ_LE_UINT16(_loaded._ptr + _loaded._numColors + 10 + ex1 * 2); ex1 = READ_LE_UINT16(_loaded._ptr + _loaded._numColors + 10 + ex1 * 2);
_srcptr = _loaded._ptr + READ_LE_UINT16(_loaded._ptr + ex1 + ex2*2) + 14; _srcptr =
_loaded._ptr + READ_LE_UINT16(_loaded._ptr + ex1 + ex2 * 2) + 14;
} }
} }
@ -254,7 +257,8 @@ byte CostumeRenderer::mainRoutine(Actor *a, int slot, int frame) {
if ((uint) _top > (uint) _outheight) if ((uint) _top > (uint) _outheight)
_top = 0; _top = 0;
if (_left<0) _left=0; if (_left < 0)
_left = 0;
if ((uint) _bottom > _outheight) if ((uint) _bottom > _outheight)
_bottom = _outheight; _bottom = _outheight;
@ -266,23 +270,31 @@ byte CostumeRenderer::mainRoutine(Actor *a, int slot, int frame) {
a->bottom = _bottom; a->bottom = _bottom;
if (_height2 + _top >= 256) { if (_height2 + _top >= 256) {
CHECK_HEAP CHECK_HEAP return 2;
return 2;
} }
_bgbak_ptr = _vm->getResourceAddress(rtBuffer, 5) + _vm->virtscr[0].xstart + _ypos*320 + _xpos; _bgbak_ptr =
_backbuff_ptr = _vm->virtscr[0].screenPtr + _vm->virtscr[0].xstart + _ypos*320 + _xpos; _vm->getResourceAddress(rtBuffer,
charsetmask = _vm->hasCharsetMask(_left, _top + _vm->virtscr[0].topline, _right, _vm->virtscr[0].topline + _bottom); 5) + _vm->virtscr[0].xstart + _ypos * 320 + _xpos;
_backbuff_ptr =
_vm->virtscr[0].screenPtr + _vm->virtscr[0].xstart + _ypos * 320 + _xpos;
charsetmask =
_vm->hasCharsetMask(_left, _top + _vm->virtscr[0].topline, _right,
_vm->virtscr[0].topline + _bottom);
masking = 0; masking = 0;
if (_zbuf) { if (_zbuf) {
masking = _vm->isMaskActiveAt(_left, _top, _right, _bottom, masking = _vm->isMaskActiveAt(_left, _top, _right, _bottom,
_vm->getResourceAddress(rtBuffer, 9) + _vm->gdi._imgBufOffs[_zbuf] + _vm->_screenStartStrip _vm->getResourceAddress(rtBuffer,
); 9) +
_vm->gdi._imgBufOffs[_zbuf] +
_vm->_screenStartStrip);
} }
if (_zbuf || charsetmask) { if (_zbuf || charsetmask) {
_mask_ptr = _vm->getResourceAddress(rtBuffer, 9) + _ypos*40 + _vm->_screenStartStrip; _mask_ptr =
_vm->getResourceAddress(rtBuffer,
9) + _ypos * 40 + _vm->_screenStartStrip;
_imgbufoffs = _vm->gdi._imgBufOffs[_zbuf]; _imgbufoffs = _vm->gdi._imgBufOffs[_zbuf];
if (!charsetmask && _zbuf != 0) if (!charsetmask && _zbuf != 0)
@ -290,9 +302,7 @@ byte CostumeRenderer::mainRoutine(Actor *a, int slot, int frame) {
_mask_ptr_dest = _mask_ptr + _xpos / 8; _mask_ptr_dest = _mask_ptr + _xpos / 8;
} }
CHECK_HEAP CHECK_HEAP if (a->shadow_mode) {
if (a->shadow_mode) {
proc_special(a->shadow_mode); proc_special(a->shadow_mode);
return b; return b;
} }
@ -301,7 +311,8 @@ byte CostumeRenderer::mainRoutine(Actor *a, int slot, int frame) {
case 0: case 0:
proc6(); proc6();
break; break;
case 1: case 2: case 1:
case 2:
proc5(); proc5();
break; break;
case 3: case 3:
@ -310,7 +321,8 @@ byte CostumeRenderer::mainRoutine(Actor *a, int slot, int frame) {
case 4: case 4:
proc1(); proc1();
break; break;
case 5:case 6: case 5:
case 6:
proc2(); proc2();
break; break;
case 7: case 7:
@ -318,11 +330,11 @@ byte CostumeRenderer::mainRoutine(Actor *a, int slot, int frame) {
break; break;
} }
CHECK_HEAP CHECK_HEAP return b;
return b;
} }
void CostumeRenderer::proc6() { void CostumeRenderer::proc6()
{
byte len; byte len;
byte *src, *dst; byte *src, *dst;
byte width, height, pcolor; byte width, height, pcolor;
@ -339,13 +351,15 @@ void CostumeRenderer::proc6() {
width = _width2; width = _width2;
height = _height2; height = _height2;
if (_docontinue) goto StartPos; if (_docontinue)
goto StartPos;
do { do {
len = *src++; len = *src++;
color = len >> _shrval; color = len >> _shrval;
len &= _maskval; len &= _maskval;
if (!len) len = *src++; if (!len)
len = *src++;
do { do {
if (color && y < scrheight) { if (color && y < scrheight) {
@ -370,7 +384,8 @@ StartPos:;
} while (1); } while (1);
} }
void CostumeRenderer::proc5() { void CostumeRenderer::proc5()
{
byte *mask, *src, *dst; byte *mask, *src, *dst;
byte maskbit, len, height, pcolor; byte maskbit, len, height, pcolor;
uint y, scrheight; uint y, scrheight;
@ -386,13 +401,15 @@ void CostumeRenderer::proc5() {
scrheight = _outheight; scrheight = _outheight;
height = _height2; height = _height2;
if (_docontinue) goto StartPos; if (_docontinue)
goto StartPos;
do { do {
len = *src++; len = *src++;
color = len >> _shrval; color = len >> _shrval;
len &= _maskval; len &= _maskval;
if (!len) len = *src++; if (!len)
len = *src++;
do { do {
if (color && y < scrheight && !(*mask & maskbit)) { if (color && y < scrheight && !(*mask & maskbit)) {
@ -430,7 +447,8 @@ StartPos:;
} while (1); } while (1);
} }
void CostumeRenderer::proc4() { void CostumeRenderer::proc4()
{
byte *mask, *src, *dst; byte *mask, *src, *dst;
byte maskbit, len, height, pcolor; byte maskbit, len, height, pcolor;
uint y, scrheight; uint y, scrheight;
@ -446,13 +464,15 @@ void CostumeRenderer::proc4() {
scrheight = _outheight; scrheight = _outheight;
height = _height2; height = _height2;
if (_docontinue) goto StartPos; if (_docontinue)
goto StartPos;
do { do {
len = *src++; len = *src++;
color = len >> _shrval; color = len >> _shrval;
len &= _maskval; len &= _maskval;
if (!len) len = *src++; if (!len)
len = *src++;
do { do {
if (color && y < scrheight && !((*mask | mask[_imgbufoffs]) & maskbit)) { if (color && y < scrheight && !((*mask | mask[_imgbufoffs]) & maskbit)) {
@ -490,7 +510,8 @@ StartPos:;
} while (1); } while (1);
} }
void CostumeRenderer::proc3() { void CostumeRenderer::proc3()
{
byte *mask, *src, *dst; byte *mask, *src, *dst;
byte maskbit, len, height, pcolor, width; byte maskbit, len, height, pcolor, width;
int color, t; int color, t;
@ -506,16 +527,19 @@ void CostumeRenderer::proc3() {
maskbit = revBitMask[_xpos & 7]; maskbit = revBitMask[_xpos & 7];
y = _ypos; y = _ypos;
if (_docontinue) goto StartPos; if (_docontinue)
goto StartPos;
do { do {
len = *src++; len = *src++;
color = len >> _shrval; color = len >> _shrval;
len &= _maskval; len &= _maskval;
if (!len) len = *src++; if (!len)
len = *src++;
do { do {
if (cost_scaleTable[_scaleIndexY++] < _scaleY) { if (cost_scaleTable[_scaleIndexY++] < _scaleY) {
if (color && y < _outheight && !((*mask|mask[_imgbufoffs])&maskbit)) { if (color && y < _outheight
&& !((*mask | mask[_imgbufoffs]) & maskbit)) {
pcolor = _palette[color]; pcolor = _palette[color];
if (pcolor == 13) if (pcolor == 13)
pcolor = _transEffect[*dst]; pcolor = _transEffect[*dst];
@ -548,7 +572,8 @@ StartPos:;
} while (1); } while (1);
} }
void CostumeRenderer::proc2() { void CostumeRenderer::proc2()
{
byte *mask, *src, *dst; byte *mask, *src, *dst;
byte maskbit, len, height, pcolor, width; byte maskbit, len, height, pcolor, width;
int color, t; int color, t;
@ -564,13 +589,15 @@ void CostumeRenderer::proc2() {
maskbit = revBitMask[_xpos & 7]; maskbit = revBitMask[_xpos & 7];
y = _ypos; y = _ypos;
if (_docontinue) goto StartPos; if (_docontinue)
goto StartPos;
do { do {
len = *src++; len = *src++;
color = len >> _shrval; color = len >> _shrval;
len &= _maskval; len &= _maskval;
if (!len) len = *src++; if (!len)
len = *src++;
do { do {
if (cost_scaleTable[_scaleIndexY++] < _scaleY) { if (cost_scaleTable[_scaleIndexY++] < _scaleY) {
if (color && y < _outheight && !(*mask & maskbit)) { if (color && y < _outheight && !(*mask & maskbit)) {
@ -607,7 +634,8 @@ StartPos:;
} }
void CostumeRenderer::proc1() { void CostumeRenderer::proc1()
{
byte *mask, *src, *dst, *dstorg; byte *mask, *src, *dst, *dstorg;
byte maskbit, len, height, pcolor, width; byte maskbit, len, height, pcolor, width;
uint y; uint y;
@ -625,13 +653,15 @@ void CostumeRenderer::proc1() {
color = _repcolor; color = _repcolor;
src = _srcptr; src = _srcptr;
if (_docontinue) goto StartPos; if (_docontinue)
goto StartPos;
do { do {
len = *src++; len = *src++;
color = len >> _shrval; color = len >> _shrval;
len &= _maskval; len &= _maskval;
if (!len) len = *src++; if (!len)
len = *src++;
do { do {
if (cost_scaleTable[_scaleIndexY++] < _scaleY) { if (cost_scaleTable[_scaleIndexY++] < _scaleY) {
@ -665,12 +695,14 @@ StartPos:;
} while (1); } while (1);
} }
void CostumeRenderer::proc_special(byte code) { void CostumeRenderer::proc_special(byte code)
{
warning("stub CostumeRenderer::proc_special(%d) not implemented"); warning("stub CostumeRenderer::proc_special(%d) not implemented");
} }
#if 0 #if 0
void CostumeRenderer::loadCostume(int id) { void CostumeRenderer::loadCostume(int id)
{
_ptr = _vm->getResourceAddress(rtCostume, id); _ptr = _vm->getResourceAddress(rtCostume, id);
if (_vm->_features & GF_AFTER_V6) { if (_vm->_features & GF_AFTER_V6) {
@ -700,7 +732,8 @@ void CostumeRenderer::loadCostume(int id) {
} }
#endif #endif
void Scumm::initActorCostumeData(Actor *a) { void Scumm::initActorCostumeData(Actor * a)
{
CostumeData *cd = &a->cost; CostumeData *cd = &a->cost;
int i; int i;
@ -711,7 +744,8 @@ void Scumm::initActorCostumeData(Actor *a) {
} }
} }
byte CostumeRenderer::drawOneSlot(Actor *a, int slot) { byte CostumeRenderer::drawOneSlot(Actor * a, int slot)
{
if (!(_vm->_features & GF_AFTER_V7)) { if (!(_vm->_features & GF_AFTER_V7)) {
int i; int i;
@ -722,7 +756,9 @@ byte CostumeRenderer::drawOneSlot(Actor *a, int slot) {
return 0; return 0;
i = cd->curpos[slot] & 0x7FFF; i = cd->curpos[slot] & 0x7FFF;
_frameptr = _loaded._ptr + READ_LE_UINT16(_loaded._ptr + _loaded._numColors + slot*2 + 10); _frameptr =
_loaded._ptr + READ_LE_UINT16(_loaded._ptr + _loaded._numColors +
slot * 2 + 10);
code = _loaded._dataptr[i] & 0x7F; code = _loaded._dataptr[i] & 0x7F;
_srcptr = _loaded._ptr + READ_LE_UINT16(_frameptr + code * 2); _srcptr = _loaded._ptr + READ_LE_UINT16(_frameptr + code * 2);
@ -737,7 +773,8 @@ byte CostumeRenderer::drawOneSlot(Actor *a, int slot) {
} }
byte CostumeRenderer::drawCostume(Actor *a) { byte CostumeRenderer::drawCostume(Actor * a)
{
int i; int i;
byte r = 0; byte r = 0;
@ -747,11 +784,13 @@ byte CostumeRenderer::drawCostume(Actor *a) {
return r; return r;
} }
int Scumm::cost_frameToAnim(Actor *a, int frame) { int Scumm::cost_frameToAnim(Actor * a, int frame)
{
return newDirToOldDir(a->facing) + frame * 4; return newDirToOldDir(a->facing) + frame * 4;
} }
void Scumm::loadCostume(LoadedCostume *lc, int costume) { void Scumm::loadCostume(LoadedCostume * lc, int costume)
{
lc->_ptr = getResourceAddress(rtCostume, costume); lc->_ptr = getResourceAddress(rtCostume, costume);
if (_features & GF_AFTER_V6) { if (_features & GF_AFTER_V6) {
@ -780,7 +819,8 @@ void Scumm::loadCostume(LoadedCostume *lc, int costume) {
lc->_dataptr = lc->_ptr + READ_LE_UINT16(lc->_ptr + lc->_numColors + 8); lc->_dataptr = lc->_ptr + READ_LE_UINT16(lc->_ptr + lc->_numColors + 8);
} }
void Scumm::cost_decodeData(Actor *a, int frame, uint usemask) { void Scumm::cost_decodeData(Actor * a, int frame, uint usemask)
{
byte *p, *r; byte *p, *r;
uint mask, j; uint mask, j;
int i; int i;
@ -854,7 +894,8 @@ void Scumm::cost_decodeData(Actor *a, int frame, uint usemask) {
} while ((uint16)mask); } while ((uint16)mask);
} }
void Scumm::cost_setPalette(CostumeRenderer *cr, byte *palette) { void Scumm::cost_setPalette(CostumeRenderer * cr, byte *palette)
{
int i; int i;
byte color; byte color;
@ -866,15 +907,19 @@ void Scumm::cost_setPalette(CostumeRenderer *cr, byte *palette) {
} }
} }
void Scumm::cost_setFacing(CostumeRenderer *cr, Actor *a) { void Scumm::cost_setFacing(CostumeRenderer * cr, Actor * a)
cr->_mirror = newDirToOldDir(a->facing)!=0 || (cr->_loaded._ptr[7]&0x80); {
cr->_mirror = newDirToOldDir(a->facing) != 0
|| (cr->_loaded._ptr[7] & 0x80);
} }
void Scumm::cost_setCostume(CostumeRenderer *cr, int costume) { void Scumm::cost_setCostume(CostumeRenderer * cr, int costume)
{
loadCostume(&cr->_loaded, costume); loadCostume(&cr->_loaded, costume);
} }
byte Scumm::cost_increaseAnims(LoadedCostume *lc, Actor *a) { byte Scumm::cost_increaseAnims(LoadedCostume * lc, Actor * a)
{
int i; int i;
byte r = 0; byte r = 0;
@ -885,7 +930,8 @@ byte Scumm::cost_increaseAnims(LoadedCostume *lc, Actor *a) {
return r; return r;
} }
byte Scumm::cost_increaseAnim(LoadedCostume *lc, Actor *a, int slot) { byte Scumm::cost_increaseAnim(LoadedCostume * lc, Actor * a, int slot)
{
int highflag; int highflag;
int i, end; int i, end;
byte code, nc; byte code, nc;
@ -933,4 +979,3 @@ byte Scumm::cost_increaseAnim(LoadedCostume *lc, Actor *a, int slot) {
return (lc->_dataptr[i] & 0x7F) != code; return (lc->_dataptr[i] & 0x7F) != code;
} while (1); } while (1);
} }

View file

@ -47,7 +47,8 @@ enum {
CMD_EXIT CMD_EXIT
}; };
void ScummDebugger::attach(Scumm *s) { void ScummDebugger::attach(Scumm *s)
{
if (_s) if (_s)
detach(); detach();
@ -62,11 +63,11 @@ void ScummDebugger::attach(Scumm *s) {
} }
void BoxTest(int num); void BoxTest(int num);
bool ScummDebugger::do_command() { bool ScummDebugger::do_command()
{
switch (get_command()) { switch (get_command()) {
case CMD_HELP: case CMD_HELP:
printf( printf("Debugger commands:\n"
"Debugger commands:\n"
"(h)elp -> display this help text\n" "(h)elp -> display this help text\n"
"(q)uit -> quit the debugger\n" "(q)uit -> quit the debugger\n"
"(g)o [numframes] -> increase frame\n" "(g)o [numframes] -> increase frame\n"
@ -76,8 +77,7 @@ bool ScummDebugger::do_command() {
"(b)oxes -> list and draw boxen\n" "(b)oxes -> list and draw boxen\n"
"(v)ariable -> set or show a variable value\n" "(v)ariable -> set or show a variable value\n"
"(w)atch [varnum] -> set a variable watch. 0 means all variables.\n" "(w)atch [varnum] -> set a variable watch. 0 means all variables.\n"
"(e)xit -> exit game\n" "(e)xit -> exit game\n");
);
return true; return true;
case CMD_QUIT: case CMD_QUIT:
@ -117,8 +117,7 @@ bool ScummDebugger::do_command() {
num = _s->getNumBoxes(); num = _s->getNumBoxes();
printf("Walk matrix:\n"); printf("Walk matrix:\n");
for (i=0;i<num;i++) for (i = 0; i < num; i++) {
{
while (*boxm != 0xFF) { while (*boxm != 0xFF) {
printf("[%d] ", *boxm); printf("[%d] ", *boxm);
boxm++; boxm++;
@ -139,7 +138,8 @@ bool ScummDebugger::do_command() {
return true; return true;
case CMD_VAR: case CMD_VAR:
if (!_parameters[0]) { if (!_parameters[0]) {
printf("v 123 will show the value of 123, v 123 456 will set the value of 123 to 456.\n"); printf
("v 123 will show the value of 123, v 123 456 will set the value of 123 to 456.\n");
} else { } else {
char *tok = strtok(_parameters, " "); char *tok = strtok(_parameters, " ");
int var = atoi(tok); int var = atoi(tok);
@ -171,17 +171,21 @@ bool ScummDebugger::do_command() {
} }
} }
void ScummDebugger::enter() { void ScummDebugger::enter()
{
if (_welcome) { if (_welcome) {
_welcome = false; _welcome = false;
printf("Debugging Mode entered!, please switch to this console for input.\n" printf
("Debugging Mode entered!, please switch to this console for input.\n"
"Enter h to list all the debug commands\n"); "Enter h to list all the debug commands\n");
} }
while(do_command()) {} while (do_command()) {
}
} }
void ScummDebugger::on_frame() { void ScummDebugger::on_frame()
{
if (_go_amount == 0) if (_go_amount == 0)
return; return;
if (!--_go_amount) if (!--_go_amount)
@ -189,7 +193,8 @@ void ScummDebugger::on_frame() {
} }
void ScummDebugger::detach() { void ScummDebugger::detach()
{
_s->_debugger = NULL; _s->_debugger = NULL;
_s = NULL; _s = NULL;
} }
@ -214,7 +219,8 @@ static const DebuggerCommands debugger_commands[] = {
{"", 0, 0} {"", 0, 0}
}; };
int ScummDebugger::get_command() { int ScummDebugger::get_command()
{
const DebuggerCommands *dc; const DebuggerCommands *dc;
char *s; char *s;
int i; int i;
@ -253,7 +259,10 @@ int ScummDebugger::get_command() {
do { do {
if (!strncmp(buf, dc->text, dc->len)) { if (!strncmp(buf, dc->text, dc->len)) {
for (s = buf; *s; s++) { for (s = buf; *s; s++) {
if (*s==32) { s++; break; } if (*s == 32) {
s++;
break;
}
} }
_parameters = s; _parameters = s;
return _command = dc->id; return _command = dc->id;
@ -261,30 +270,43 @@ int ScummDebugger::get_command() {
} while ((++dc)->text[0]); } while ((++dc)->text[0]);
for (s = buf; *s; s++) for (s = buf; *s; s++)
if (*s==32) { *s=0; break; } if (*s == 32) {
printf("Invalid command '%s'. Type 'help' for a list of available commands.\n", buf); *s = 0;
break;
}
printf
("Invalid command '%s'. Type 'help' for a list of available commands.\n",
buf);
} while (1); } while (1);
} }
void ScummDebugger::printActors(int act) { void ScummDebugger::printActors(int act)
{
int i; int i;
Actor *a; Actor *a;
printf("+--------------------------------------------------------------+\n"); printf
printf("|# |room| x y |elev|cos|width|box|mov|zp|frame|scale|spd|dir|\n"); ("+--------------------------------------------------------------+\n");
printf("+--+----+--------+----+---+-----+---+---+--+-----+-----+---+---+\n"); printf
("|# |room| x y |elev|cos|width|box|mov|zp|frame|scale|spd|dir|\n");
printf
("+--+----+--------+----+---+-----+---+---+--+-----+-----+---+---+\n");
for (i = 1; i < _s->NUM_ACTORS; i++) { for (i = 1; i < _s->NUM_ACTORS; i++) {
if (act == -1 || act == i) { if (act == -1 || act == i) {
a = &_s->actor[i]; a = &_s->actor[i];
if (a->visible) if (a->visible)
printf("|%2d|%4d|%3d %3d|%4d|%3d|%5d|%3d|%3d|%2d|%5d|%5d|%3d|%3d|\n", printf("|%2d|%4d|%3d %3d|%4d|%3d|%5d|%3d|%3d|%2d|%5d|%5d|%3d|%3d|\n",
i,a->room,a->x,a->y,a->elevation,a->costume,a->width,a->walkbox,a->moving,a->forceClip,a->frame,a->scalex,a->speedx,a->facing); i, a->room, a->x, a->y, a->elevation, a->costume, a->width,
a->walkbox, a->moving, a->forceClip, a->frame, a->scalex,
a->speedx, a->facing);
} }
} }
printf("+--------------------------------------------------------------+\n"); printf
("+--------------------------------------------------------------+\n");
} }
void ScummDebugger::printScripts() { void ScummDebugger::printScripts()
{
int i; int i;
ScriptSlot *ss; ScriptSlot *ss;
@ -295,7 +317,8 @@ void ScummDebugger::printScripts() {
ss = &_s->vm.slot[i]; ss = &_s->vm.slot[i];
if (ss->number) { if (ss->number) {
printf("|%2d|%3d|%3d|%3d|%3d|%3d|%2d|%3d|%3d|\n", printf("|%2d|%3d|%3d|%3d|%3d|%3d|%2d|%3d|%3d|\n",
i, ss->number, ss->status, ss->where, ss->unk1, ss->unk2, ss->freezeCount, ss->cutsceneOverride, ss->unk5); i, ss->number, ss->status, ss->where, ss->unk1, ss->unk2,
ss->freezeCount, ss->cutsceneOverride, ss->unk5);
} }
} }
printf("+---------------------------------+\n"); printf("+---------------------------------+\n");

View file

@ -19,7 +19,8 @@ char* _debugger_commands[] = {
char **scumm_debugger_completion(const char *text, int start, int end); char **scumm_debugger_completion(const char *text, int start, int end);
char *scumm_debugger_command_generator(const char *text, int state); char *scumm_debugger_command_generator(const char *text, int state);
void initialize_readline () { void initialize_readline()
{
/* Allow conditional parsing of the ~/.inputrc file. */ /* Allow conditional parsing of the ~/.inputrc file. */
rl_readline_name = "scummvm"; rl_readline_name = "scummvm";
@ -27,7 +28,8 @@ void initialize_readline () {
rl_attempted_completion_function = scumm_debugger_completion; rl_attempted_completion_function = scumm_debugger_completion;
} }
char ** scumm_debugger_completion (const char *text, int start, int end) { char **scumm_debugger_completion(const char *text, int start, int end)
{
char **matches; char **matches;
@ -55,7 +57,8 @@ char ** scumm_debugger_completion (const char *text, int start, int end) {
/* Generator function for command completion. STATE lets us know whether /* Generator function for command completion. STATE lets us know whether
to start from scratch; without any state (i.e. STATE == 0), then we to start from scratch; without any state (i.e. STATE == 0), then we
start at the top of the list. */ start at the top of the list. */
char * scumm_debugger_command_generator (const char *text, int state) { char *scumm_debugger_command_generator(const char *text, int state)
{
static int list_index, len; static int list_index, len;
char *name; char *name;
@ -63,15 +66,13 @@ char * scumm_debugger_command_generator (const char *text, int state) {
/* If this is a new word to complete, initialize now. This includes /* If this is a new word to complete, initialize now. This includes
saving the length of TEXT for efficiency, and initializing the index saving the length of TEXT for efficiency, and initializing the index
variable to 0. */ variable to 0. */
if (!state) if (!state) {
{
list_index = 0; list_index = 0;
len = strlen(text); len = strlen(text);
} }
/* Return the next name which partially matches from the command list. */ /* Return the next name which partially matches from the command list. */
while (name = _debugger_commands[list_index]) while (name = _debugger_commands[list_index]) {
{
list_index++; list_index++;
if (strncmp(name, text, len) == 0) if (strncmp(name, text, len) == 0)

View file

@ -45,14 +45,14 @@
"\tg - graphics mode. 1 for 2xSai anti-aliasing\n" \ "\tg - graphics mode. 1 for 2xSai anti-aliasing\n" \
"\ta - load autosave game (for recovering from crashes)\n" "\ta - load autosave game (for recovering from crashes)\n"
void GameDetector::parseCommandLine(int argc, char **argv) { void GameDetector::parseCommandLine(int argc, char **argv)
{
#if !defined(__APPLE__CW) #if !defined(__APPLE__CW)
int i; int i;
char *s; char *s;
// check for arguments // check for arguments
if (argc < 2) if (argc < 2) {
{
printf(USAGE_STRING); printf(USAGE_STRING);
//exit(1); //exit(1);
} }
@ -86,15 +86,15 @@ void GameDetector::parseCommandLine(int argc, char **argv) {
if (*(s + 1) == '\0') if (*(s + 1) == '\0')
goto ShowHelpAndExit; goto ShowHelpAndExit;
_scale = atoi(s + 1); _scale = atoi(s + 1);
if (_scale == 0 || _scale > 3) if (_scale == 0 || _scale > 3) {
{
// bad scale - only 1, 2, 3 work for now // bad scale - only 1, 2, 3 work for now
printf("Invalid scale '%s' - valid values are 1, 2, 3\n", s + 1); printf("Invalid scale '%s' - valid values are 1, 2, 3\n", s + 1);
exit(1); exit(1);
} }
goto NextArg; goto NextArg;
case 'v': case 'v':
printf("ScummVM " SCUMMVM_VERSION "\nBuilt on " __DATE__ " " __TIME__ "\n"); printf("ScummVM " SCUMMVM_VERSION "\nBuilt on " __DATE__ " "
__TIME__ "\n");
#ifdef SCUMMVM_PLATFORM_VERSION #ifdef SCUMMVM_PLATFORM_VERSION
printf(" " SCUMMVM_PLATFORM_VERSION "\n"); printf(" " SCUMMVM_PLATFORM_VERSION "\n");
#endif #endif
@ -151,7 +151,8 @@ ShowHelpAndExit:;
} }
NextArg:; NextArg:;
} else { } else {
if (_exe_name) goto ShowHelpAndExit; if (_exe_name)
goto ShowHelpAndExit;
_exe_name = s; _exe_name = s;
} }
} }
@ -187,37 +188,58 @@ static const VersionSettings version_settings[] = {
// {"indy3", "Indiana Jones and the Last Crusade", GID_INDY3, 2, 0, 0,}, // {"indy3", "Indiana Jones and the Last Crusade", GID_INDY3, 2, 0, 0,},
/* Scumm Version 3 */ /* Scumm Version 3 */
{"indy3", "Indiana Jones and the Last Crusade (256)", GID_INDY3_256, 3, 0, 22, GF_SMALL_HEADER|GF_USE_KEY|GF_SMALL_NAMES|GF_OLD256|GF_NO_SCALLING}, {"indy3", "Indiana Jones and the Last Crusade (256)", GID_INDY3_256, 3, 0,
{"zak256", "Zak McKracken and the Alien Mindbenders (256)",GID_ZAK256, 3, 0, 0, GF_SMALL_HEADER|GF_USE_KEY|GF_SMALL_NAMES|GF_OLD256|GF_AUDIOTRACKS|GF_NO_SCALLING}, 22,
{"loom", "Loom", GID_LOOM, 3, 5, 40, GF_SMALL_HEADER|GF_USE_KEY|GF_SMALL_NAMES|GF_OLD_BUNDLE|GF_16COLOR|GF_NO_SCALLING}, GF_SMALL_HEADER | GF_USE_KEY | GF_SMALL_NAMES | GF_OLD256 |
GF_NO_SCALLING},
{"zak256", "Zak McKracken and the Alien Mindbenders (256)", GID_ZAK256, 3,
0, 0,
GF_SMALL_HEADER | GF_USE_KEY | GF_SMALL_NAMES | GF_OLD256 | GF_AUDIOTRACKS
| GF_NO_SCALLING},
{"loom", "Loom", GID_LOOM, 3, 5, 40,
GF_SMALL_HEADER | GF_USE_KEY | GF_SMALL_NAMES | GF_OLD_BUNDLE | GF_16COLOR
| GF_NO_SCALLING},
/* Scumm Version 4 */ /* Scumm Version 4 */
{"monkeyEGA", "Monkey Island 1 (EGA)", GID_MONKEY_EGA, 4, 0, 67, GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR}, // EGA version {"monkeyEGA", "Monkey Island 1 (EGA)", GID_MONKEY_EGA, 4, 0, 67, GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR}, // EGA version
/* Scumm version 5 */ /* Scumm version 5 */
{"loomcd", "Loom (256 color CD version)", GID_LOOM256, 5, 1, 42, GF_SMALL_HEADER|GF_USE_KEY|GF_AUDIOTRACKS}, {"loomcd", "Loom (256 color CD version)", GID_LOOM256, 5, 1, 42,
{"monkey", "Monkey Island 1", GID_MONKEY, 5, 2, 2, GF_USE_KEY|GF_AUDIOTRACKS}, GF_SMALL_HEADER | GF_USE_KEY | GF_AUDIOTRACKS},
{"monkey1", "Monkey Island 1 (alt)", GID_MONKEY, 5, 2, 2, GF_USE_KEY|GF_AUDIOTRACKS}, {"monkey", "Monkey Island 1", GID_MONKEY, 5, 2, 2,
{"monkey2", "Monkey Island 2: LeChuck's revenge", GID_MONKEY2, 5, 2, 2, GF_USE_KEY}, GF_USE_KEY | GF_AUDIOTRACKS},
{"atlantis", "Indiana Jones 4 and the Fate of Atlantis", GID_INDY4, 5, 5, 0, GF_USE_KEY}, {"monkey1", "Monkey Island 1 (alt)", GID_MONKEY, 5, 2, 2,
{"playfate", "Indiana Jones 4 and the Fate of Atlantis (Demo)", GID_INDY4, 5, 5, 0, GF_USE_KEY}, GF_USE_KEY | GF_AUDIOTRACKS},
{"monkey2", "Monkey Island 2: LeChuck's revenge", GID_MONKEY2, 5, 2, 2,
GF_USE_KEY},
{"atlantis", "Indiana Jones 4 and the Fate of Atlantis", GID_INDY4, 5, 5, 0,
GF_USE_KEY},
{"playfate", "Indiana Jones 4 and the Fate of Atlantis (Demo)", GID_INDY4,
5, 5, 0, GF_USE_KEY},
/* Scumm Version 6 */ /* Scumm Version 6 */
{"tentacle", "Day Of The Tentacle", GID_TENTACLE, 6, 4, 2, GF_NEW_OPCODES|GF_AFTER_V6|GF_USE_KEY}, {"tentacle", "Day Of The Tentacle", GID_TENTACLE, 6, 4, 2,
{"dottdemo", "Day Of The Tentacle (Demo)", GID_TENTACLE, 6, 3, 2, GF_NEW_OPCODES|GF_AFTER_V6|GF_USE_KEY}, GF_NEW_OPCODES | GF_AFTER_V6 | GF_USE_KEY},
{"samnmax", "Sam & Max", GID_SAMNMAX, 6, 4, 2, GF_NEW_OPCODES|GF_AFTER_V6|GF_USE_KEY|GF_DRAWOBJ_OTHER_ORDER}, {"dottdemo", "Day Of The Tentacle (Demo)", GID_TENTACLE, 6, 3, 2,
{"snmdemo", "Sam & Max (Demo)", GID_SAMNMAX, 6, 3, 0, GF_NEW_OPCODES|GF_AFTER_V6|GF_USE_KEY}, GF_NEW_OPCODES | GF_AFTER_V6 | GF_USE_KEY},
{"samnmax", "Sam & Max", GID_SAMNMAX, 6, 4, 2,
GF_NEW_OPCODES | GF_AFTER_V6 | GF_USE_KEY | GF_DRAWOBJ_OTHER_ORDER},
{"snmdemo", "Sam & Max (Demo)", GID_SAMNMAX, 6, 3, 0,
GF_NEW_OPCODES | GF_AFTER_V6 | GF_USE_KEY},
/* Scumm Version 7 */ /* Scumm Version 7 */
{"ft", "Full Throttle", GID_FT, 7, 3, 0, GF_NEW_OPCODES|GF_AFTER_V6|GF_AFTER_V7}, {"ft", "Full Throttle", GID_FT, 7, 3, 0,
{"dig", "The Dig", GID_DIG, 7, 5, 0, GF_NEW_OPCODES|GF_AFTER_V6|GF_AFTER_V7}, GF_NEW_OPCODES | GF_AFTER_V6 | GF_AFTER_V7},
{"dig", "The Dig", GID_DIG, 7, 5, 0,
GF_NEW_OPCODES | GF_AFTER_V6 | GF_AFTER_V7},
/* Scumm Version 8 */ /* Scumm Version 8 */
// {"curse", "The Curse of Monkey Island", GID_CMI, 8, 1, 0,}, // {"curse", "The Curse of Monkey Island", GID_CMI, 8, 1, 0,},
{NULL, NULL} {NULL, NULL}
}; };
bool GameDetector::detectGame() { bool GameDetector::detectGame()
{
const VersionSettings *gnl = version_settings; const VersionSettings *gnl = version_settings;
_gameId = 0; _gameId = 0;
@ -240,7 +262,8 @@ bool GameDetector::detectGame() {
return true; return true;
} }
char *GameDetector::getGameName() { char *GameDetector::getGameName()
{
if (_gameText == NULL) { if (_gameText == NULL) {
char buf[256]; char buf[256];
sprintf(buf, "Unknown game: \"%s\"", _exe_name); sprintf(buf, "Unknown game: \"%s\"", _exe_name);
@ -284,11 +307,11 @@ int GameDetector::detectMain(int argc, char **argv)
} }
if (!_gameDataPath) { if (!_gameDataPath) {
warning("No path was provided. Assuming that data file are in the current directory"); warning
("No path was provided. Assuming that data file are in the current directory");
_gameDataPath = (char *)malloc(sizeof(char) * 2); _gameDataPath = (char *)malloc(sizeof(char) * 2);
strcpy(_gameDataPath, ""); strcpy(_gameDataPath, "");
} }
return (0); return (0);
} }

697
gfx.cpp

File diff suppressed because it is too large Load diff

171
gui.cpp
View file

@ -49,7 +49,8 @@ enum {
}; };
void Gui::draw(int start,int end) { void Gui::draw(int start, int end)
{
int i; int i;
if (end == -1) if (end == -1)
@ -74,7 +75,8 @@ void Gui::draw(int start,int end) {
} }
} }
const GuiWidget *Gui::widgetFromPos(int x, int y) { const GuiWidget *Gui::widgetFromPos(int x, int y)
{
int i; int i;
for (i = sizeof(_widgets) / sizeof(_widgets[0]) - 1; i >= 0; i--) { for (i = sizeof(_widgets) / sizeof(_widgets[0]) - 1; i >= 0; i--) {
@ -95,7 +97,8 @@ const GuiWidget *Gui::widgetFromPos(int x, int y) {
return NULL; return NULL;
} }
void Gui::drawChar(const char str, int xx, int yy) { void Gui::drawChar(const char str, int xx, int yy)
{
unsigned int buffer = 0, mask = 0, x, y; unsigned int buffer = 0, mask = 0, x, y;
byte *tmp; byte *tmp;
int tempc = _color; int tempc = _color;
@ -107,7 +110,10 @@ void Gui::drawChar(const char str, int xx, int yy) {
for (y = 0; y < 8; y++) { for (y = 0; y < 8; y++) {
for (x = 0; x < 8; x++) { for (x = 0; x < 8; x++) {
unsigned char color; unsigned char color;
if ((mask >>= 1) == 0) {buffer = *tmp++; mask = 0x80;} if ((mask >>= 1) == 0) {
buffer = *tmp++;
mask = 0x80;
}
color = ((buffer & mask) != 0); color = ((buffer & mask) != 0);
if (color) if (color)
vline(xx + x, yy + y, yy + y); vline(xx + x, yy + y, yy + y);
@ -116,7 +122,9 @@ void Gui::drawChar(const char str, int xx, int yy) {
_color = tempc; _color = tempc;
} }
void Gui::drawString(const char *str, int x, int y, int w, byte color, bool center) { void Gui::drawString(const char *str, int x, int y, int w, byte color,
bool center)
{
StringTab *st = &_s->string[5]; StringTab *st = &_s->string[5];
st->charset = 1; st->charset = 1;
st->center = center; st->center = center;
@ -134,7 +142,8 @@ void Gui::drawString(const char *str, int x, int y, int w, byte color, bool cent
} }
} }
void Gui::drawWidget(const GuiWidget *w) { void Gui::drawWidget(const GuiWidget * w)
{
const char *s; const char *s;
int x, y; int x, y;
@ -169,14 +178,17 @@ void Gui::drawWidget(const GuiWidget *w) {
strcpy(text, s); strcpy(text, s);
break; break;
case GUI_VARTEXT: case GUI_VARTEXT:
sprintf(text, "%s %d", string_map_table_custom[w->_string_number], _gui_variables[w->_string_number]); sprintf(text, "%s %d", string_map_table_custom[w->_string_number],
_gui_variables[w->_string_number]);
break; break;
#ifdef _WIN32_WCE #ifdef _WIN32_WCE
case GUI_KEYTEXT: case GUI_KEYTEXT:
strcpy(text, getGAPIKeyName(getAction(w->_string_number - 1)->action_key)); strcpy(text,
getGAPIKeyName(getAction(w->_string_number - 1)->action_key));
break; break;
case GUI_ACTIONTEXT: case GUI_ACTIONTEXT:
strcpy(text, getActionName(getAction(w->_string_number - 1)->action_type)); strcpy(text,
getActionName(getAction(w->_string_number - 1)->action_type));
break; break;
#endif #endif
} }
@ -184,7 +196,8 @@ void Gui::drawWidget(const GuiWidget *w) {
if (*text) { if (*text) {
printf("drawString(%s)\n", text); printf("drawString(%s)\n", text);
drawString(text, x + _parentX, y + _parentY, w->_w, drawString(text, x + _parentX, y + _parentY, w->_w,
(_clickWidget && _clickWidget==w->_id) ? _textcolorhi : _textcolor, (_clickWidget
&& _clickWidget == w->_id) ? _textcolorhi : _textcolor,
false); false);
} }
break; break;
@ -194,7 +207,8 @@ void Gui::drawWidget(const GuiWidget *w) {
} }
} }
void Gui::widgetClear(const GuiWidget *wid) { void Gui::widgetClear(const GuiWidget * wid)
{
int x, y, w, h, i; int x, y, w, h, i;
x = wid->_x; x = wid->_x;
@ -206,7 +220,8 @@ void Gui::widgetClear(const GuiWidget *wid) {
if (ptr == NULL) if (ptr == NULL)
return; return;
_s->setVirtscreenDirty(_vs, x+_parentX, y+_parentY, x+_parentX+w, y+_parentY+h); _s->setVirtscreenDirty(_vs, x + _parentX, y + _parentY, x + _parentX + w,
y + _parentY + h);
if (wid->_flags & GWF_BORDER) { if (wid->_flags & GWF_BORDER) {
ptr += 320 + 1; ptr += 320 + 1;
@ -221,7 +236,8 @@ void Gui::widgetClear(const GuiWidget *wid) {
} }
} }
void Gui::widgetBorder(const GuiWidget *w) { void Gui::widgetBorder(const GuiWidget * w)
{
int x = w->_x, y = w->_y; int x = w->_x, y = w->_y;
int x2 = x + w->_w - 1, y2 = y + w->_h - 1; int x2 = x + w->_w - 1, y2 = y + w->_h - 1;
byte tmp; byte tmp;
@ -242,22 +258,26 @@ void Gui::widgetBorder(const GuiWidget *w) {
_color = tmp; _color = tmp;
} }
void Gui::hline(int x, int y, int x2) { void Gui::hline(int x, int y, int x2)
{
moveto(x, y); moveto(x, y);
lineto(x2, y); lineto(x2, y);
} }
void Gui::vline(int x, int y, int y2) { void Gui::vline(int x, int y, int y2)
{
moveto(x, y); moveto(x, y);
lineto(x, y2); lineto(x, y2);
} }
void Gui::moveto(int x, int y) { void Gui::moveto(int x, int y)
{
_curX = x; _curX = x;
_curY = y; _curY = y;
} }
byte *Gui::getBasePtr(int x, int y) { byte *Gui::getBasePtr(int x, int y)
{
x += _parentX; x += _parentX;
y += _parentY; y += _parentY;
_vs = _s->findVirtScreen(y); _vs = _s->findVirtScreen(y);
@ -265,10 +285,12 @@ byte *Gui::getBasePtr(int x, int y) {
if (_vs == NULL) if (_vs == NULL)
return NULL; return NULL;
return _vs->screenPtr + x + (y-_vs->topline)*320 + _s->_screenStartStrip*8; return _vs->screenPtr + x + (y - _vs->topline) * 320 +
_s->_screenStartStrip * 8;
} }
void Gui::lineto(int x, int y) { void Gui::lineto(int x, int y)
{
byte *ptr; byte *ptr;
int x2 = _curX; int x2 = _curX;
int y2 = _curY; int y2 = _curY;
@ -301,7 +323,8 @@ void Gui::lineto(int x, int y) {
} }
} }
void Gui::leftMouseClick(int x, int y) { void Gui::leftMouseClick(int x, int y)
{
const GuiWidget *w = widgetFromPos(x, y); const GuiWidget *w = widgetFromPos(x, y);
int old; int old;
@ -336,32 +359,45 @@ const GuiWidget keys_dialog[] = {
// First action // First action
{GUI_CUSTOMTEXT, 0x01, GWF_BUTTON, 30 + 11, 10 + 10, 15, 15, 10, 3}, // CUSTOMTEXT_PLUS {GUI_CUSTOMTEXT, 0x01, GWF_BUTTON, 30 + 11, 10 + 10, 15, 15, 10, 3}, // CUSTOMTEXT_PLUS
{GUI_CUSTOMTEXT, 0x01, GWF_BUTTON, 30 + 33, 10 + 10, 15, 15, 11, 4}, // CUSTOMTEXT_MINUS {GUI_CUSTOMTEXT, 0x01, GWF_BUTTON, 30 + 33, 10 + 10, 15, 15, 11, 4}, // CUSTOMTEXT_MINUS
{GUI_ACTIONTEXT, 0x01, GWF_BUTTON, 30 + 11 + 33 + 10, 10 + 10, 100, 15, 100, 1}, {GUI_ACTIONTEXT, 0x01, GWF_BUTTON, 30 + 11 + 33 + 10, 10 + 10, 100, 15, 100,
1},
{GUI_KEYTEXT, 0x01, 0, 30 + 11 + 33 + 120, 10 + 10 + 3, 100, 15, 1, 1}, {GUI_KEYTEXT, 0x01, 0, 30 + 11 + 33 + 120, 10 + 10 + 3, 100, 15, 1, 1},
//Second action //Second action
{GUI_CUSTOMTEXT, 0x01, GWF_BUTTON, 30 + 11, 10 + 10 + 15 + 5, 15, 15, 20, 3}, // CUSTOMTEXT_PLUS {GUI_CUSTOMTEXT, 0x01, GWF_BUTTON, 30 + 11, 10 + 10 + 15 + 5, 15, 15, 20, 3}, // CUSTOMTEXT_PLUS
{GUI_CUSTOMTEXT, 0x01, GWF_BUTTON, 30 + 33, 10 + 10 + 15 + 5, 15, 15, 21, 4}, // CUSTOMTEXT_MINUS {GUI_CUSTOMTEXT, 0x01, GWF_BUTTON, 30 + 33, 10 + 10 + 15 + 5, 15, 15, 21, 4}, // CUSTOMTEXT_MINUS
{GUI_ACTIONTEXT, 0x01, GWF_BUTTON, 30 + 10 + 33 + 10, 10 + 10 + 15 + 5, 100, 15, 101, 2}, {GUI_ACTIONTEXT, 0x01, GWF_BUTTON, 30 + 10 + 33 + 10, 10 + 10 + 15 + 5, 100,
{GUI_KEYTEXT, 0x01, 0, 30 + 11 + 33 + 120, 10 + 10 + 15 + 5 + 3, 100, 15, 2, 2}, 15, 101, 2},
{GUI_KEYTEXT, 0x01, 0, 30 + 11 + 33 + 120, 10 + 10 + 15 + 5 + 3, 100, 15, 2,
2},
//Third action //Third action
{GUI_CUSTOMTEXT, 0x01, GWF_BUTTON, 30 + 11, 10 + 10 + 15 + 5 + 15 + 5, 15, 15, 30, 3}, // CUSTOMTEXT_PLUS {GUI_CUSTOMTEXT, 0x01, GWF_BUTTON, 30 + 11, 10 + 10 + 15 + 5 + 15 + 5, 15, 15, 30, 3}, // CUSTOMTEXT_PLUS
{GUI_CUSTOMTEXT, 0x01, GWF_BUTTON, 30 + 33, 10 + 10 + 15 + 5 + 15 + 5, 15, 15, 31, 4}, // CUSTOMTEXT_MINUS {GUI_CUSTOMTEXT, 0x01, GWF_BUTTON, 30 + 33, 10 + 10 + 15 + 5 + 15 + 5, 15, 15, 31, 4}, // CUSTOMTEXT_MINUS
{GUI_ACTIONTEXT, 0x01, GWF_BUTTON, 30 + 10 + 33 + 10, 10 + 10 + 15 + 5 + 15 + 5, 100, 15, 102, 3}, {GUI_ACTIONTEXT, 0x01, GWF_BUTTON, 30 + 10 + 33 + 10,
{GUI_KEYTEXT, 0x01, 0, 30 + 11 + 33 + 120, 10 + 10 + 15 + 5 + 15 + 5 + 3, 100, 15, 3, 3}, 10 + 10 + 15 + 5 + 15 + 5, 100, 15, 102, 3},
{GUI_KEYTEXT, 0x01, 0, 30 + 11 + 33 + 120, 10 + 10 + 15 + 5 + 15 + 5 + 3,
100, 15, 3, 3},
//Fourth action //Fourth action
{GUI_CUSTOMTEXT, 0x01, GWF_BUTTON, 30 + 11, 10 + 10 + 15 + 5 + 15 + 5 + 15 + 5, 15, 15, 40, 3}, {GUI_CUSTOMTEXT, 0x01, GWF_BUTTON, 30 + 11,
{GUI_CUSTOMTEXT, 0x01, GWF_BUTTON, 30 + 33, 10 + 10 + 15 + 5 + 15 + 5 + 15 + 5, 15, 15, 41, 4}, 10 + 10 + 15 + 5 + 15 + 5 + 15 + 5, 15, 15, 40, 3},
{GUI_ACTIONTEXT, 0x01, GWF_BUTTON, 30 + 10 + 33 + 10, 10 + 10 + 15 + 5 + 15 + 5 + 15 + 5, 100, 15, 103, 4}, {GUI_CUSTOMTEXT, 0x01, GWF_BUTTON, 30 + 33,
{GUI_KEYTEXT, 0x01, 0, 30 + 11 + 33 + 120, 10 + 10 + 15 + 5 + 15 + 5 + 15 + 5 + 3, 100, 15, 4, 4}, 10 + 10 + 15 + 5 + 15 + 5 + 15 + 5, 15, 15, 41, 4},
{GUI_ACTIONTEXT, 0x01, GWF_BUTTON, 30 + 10 + 33 + 10,
10 + 10 + 15 + 5 + 15 + 5 + 15 + 5, 100, 15, 103, 4},
{GUI_KEYTEXT, 0x01, 0, 30 + 11 + 33 + 120,
10 + 10 + 15 + 5 + 15 + 5 + 15 + 5 + 3, 100, 15, 4, 4},
//Fifth action //Fifth action
{GUI_CUSTOMTEXT, 0x01, GWF_BUTTON, 30 + 11, 10 + 10 + 15 + 5 + 15 + 5 + 15 + 5 + 15 + 5, 15, 15, 50, 3}, {GUI_CUSTOMTEXT, 0x01, GWF_BUTTON, 30 + 11,
{GUI_CUSTOMTEXT, 0x01, GWF_BUTTON, 30 + 33, 10 + 10 + 15 + 5 + 15 + 5 + 15 + 5 + 15 + 5, 15, 15, 51, 4}, 10 + 10 + 15 + 5 + 15 + 5 + 15 + 5 + 15 + 5, 15, 15, 50, 3},
{GUI_ACTIONTEXT, 0x01, GWF_BUTTON, 30 + 10 + 33 + 10, 10 + 10 + 15 + 5 + 15 + 5 + 15 + 5 + 15 + 5, 100, 15, 104, 5}, {GUI_CUSTOMTEXT, 0x01, GWF_BUTTON, 30 + 33,
{GUI_KEYTEXT, 0x01, 0, 30 + 11 + 33 + 120, 10 + 10 + 15 + 5 + 15 + 5 + 15 + 5 + 15 + 5 + 3, 100, 15, 5, 5}, 10 + 10 + 15 + 5 + 15 + 5 + 15 + 5 + 15 + 5, 15, 15, 51, 4},
{GUI_ACTIONTEXT, 0x01, GWF_BUTTON, 30 + 10 + 33 + 10,
10 + 10 + 15 + 5 + 15 + 5 + 15 + 5 + 15 + 5, 100, 15, 104, 5},
{GUI_KEYTEXT, 0x01, 0, 30 + 11 + 33 + 120,
10 + 10 + 15 + 5 + 15 + 5 + 15 + 5 + 15 + 5 + 3, 100, 15, 5, 5},
//OK //OK
{GUI_RESTEXT, 0x01, GWF_BUTTON, 30 + 113, 10 + 106, 54, 16, 60, 9}, {GUI_RESTEXT, 0x01, GWF_BUTTON, 30 + 113, 10 + 106, 54, 16, 60, 9},
@ -443,7 +479,8 @@ const GuiWidget pause_dialog[] = {
{0, 0, 0, 0, 0, 0, 0, 0, 0} {0, 0, 0, 0, 0, 0, 0, 0, 0}
}; };
void Gui::handleSoundDialogCommand(int cmd) { void Gui::handleSoundDialogCommand(int cmd)
{
if (cmd == 40 || cmd == 50) { if (cmd == 40 || cmd == 50) {
if (cmd == 40) { if (cmd == 40) {
SoundEngine *se = (SoundEngine *)_s->_soundEngine; SoundEngine *se = (SoundEngine *)_s->_soundEngine;
@ -461,8 +498,7 @@ void Gui::handleSoundDialogCommand(int cmd) {
if ((cmd % 10) == 1) { if ((cmd % 10) == 1) {
if (_gui_variables[cmd / 10] < 100) if (_gui_variables[cmd / 10] < 100)
_gui_variables[cmd / 10] += 5; _gui_variables[cmd / 10] += 5;
} } else {
else {
if (_gui_variables[cmd / 10] > 0) if (_gui_variables[cmd / 10] > 0)
_gui_variables[cmd / 10] -= 5; _gui_variables[cmd / 10] -= 5;
} }
@ -470,7 +506,8 @@ void Gui::handleSoundDialogCommand(int cmd) {
draw((cmd / 10) * 10 + 3, (cmd / 10) * 10 + 3); draw((cmd / 10) * 10 + 3, (cmd / 10) * 10 + 3);
} }
void Gui::handleOptionsDialogCommand(int cmd) { void Gui::handleOptionsDialogCommand(int cmd)
{
switch (cmd) { switch (cmd) {
case 1: case 1:
_widgets[0] = sound_dialog; _widgets[0] = sound_dialog;
@ -502,7 +539,8 @@ void Gui::handleOptionsDialogCommand(int cmd) {
} }
} }
void Gui::handleKeysDialogCommand(int cmd) { void Gui::handleKeysDialogCommand(int cmd)
{
#ifdef _WIN32_WCE #ifdef _WIN32_WCE
if (cmd < 100 && cmd != 60) { if (cmd < 100 && cmd != 60) {
@ -528,7 +566,8 @@ void Gui::handleKeysDialogCommand(int cmd) {
#endif #endif
} }
void Gui::handleLauncherDialogCommand(int cmd) { void Gui::handleLauncherDialogCommand(int cmd)
{
printf("handle launcher command\n"); printf("handle launcher command\n");
switch (cmd) { switch (cmd) {
case 20: case 20:
@ -552,7 +591,8 @@ void Gui::handleLauncherDialogCommand(int cmd) {
} }
} }
void Gui::handleCommand(int cmd) { void Gui::handleCommand(int cmd)
{
int lastEdit = _editString; int lastEdit = _editString;
showCaret(false); showCaret(false);
@ -626,7 +666,8 @@ void Gui::handleCommand(int cmd) {
_s->_saveLoadSlot = lastEdit + _slotIndex; _s->_saveLoadSlot = lastEdit + _slotIndex;
_s->_saveLoadCompatible = false; _s->_saveLoadCompatible = false;
_s->_saveLoadFlag = 1; _s->_saveLoadFlag = 1;
memcpy(_s->_saveLoadName, game_names[lastEdit], sizeof(_s->_saveLoadName)); memcpy(_s->_saveLoadName, game_names[lastEdit],
sizeof(_s->_saveLoadName));
close(); close();
return; return;
case 9: /* options button */ case 9: /* options button */
@ -652,7 +693,8 @@ void Gui::handleCommand(int cmd) {
} }
void Gui::getSavegameNames(int start) { void Gui::getSavegameNames(int start)
{
int i; int i;
_slotIndex = start; _slotIndex = start;
for (i = 0; i < 9; i++, start++) { for (i = 0; i < 9; i++, start++) {
@ -660,7 +702,8 @@ void Gui::getSavegameNames(int start) {
} }
} }
const char *Gui::queryString(int stringno, int id) { const char *Gui::queryString(int stringno, int id)
{
static char namebuf[64]; static char namebuf[64];
char *result; char *result;
int string; int string;
@ -674,8 +717,7 @@ const char *Gui::queryString(int stringno, int id) {
if (_s->_features & GF_AFTER_V7) if (_s->_features & GF_AFTER_V7)
string = _s->_vars[string_map_table_v7[stringno - 1].num]; string = _s->_vars[string_map_table_v7[stringno - 1].num];
else else if (_s->_features & GF_AFTER_V6)
if (_s->_features&GF_AFTER_V6)
string = _s->_vars[string_map_table_v6[stringno - 1].num]; string = _s->_vars[string_map_table_v6[stringno - 1].num];
else else
string = string_map_table_v5[stringno - 1].num; string = string_map_table_v5[stringno - 1].num;
@ -691,7 +733,8 @@ const char *Gui::queryString(int stringno, int id) {
return result; return result;
} }
void Gui::showCaret(bool show) { void Gui::showCaret(bool show)
{
int i; int i;
char *s; char *s;
@ -716,7 +759,8 @@ void Gui::showCaret(bool show) {
_editString = -1; _editString = -1;
} }
void Gui::editString(int i) { void Gui::editString(int i)
{
char *s = game_names[i]; char *s = game_names[i];
if (!valid_games[i]) { if (!valid_games[i]) {
valid_games[i] = true; valid_games[i] = true;
@ -727,7 +771,8 @@ void Gui::editString(int i) {
showCaret(true); showCaret(true);
} }
void Gui::addLetter(byte letter) { void Gui::addLetter(byte letter)
{
switch (_dialog) { switch (_dialog) {
case SAVELOAD_DIALOG: case SAVELOAD_DIALOG:
if (_editString == -1) if (_editString == -1)
@ -762,20 +807,24 @@ void Gui::addLetter(byte letter) {
} }
} }
byte Gui::getDefaultColor(int color) { byte Gui::getDefaultColor(int color)
{
if ((_s->_features & GF_AFTER_V7) || (_s->_features & GF_SMALL_HEADER)) if ((_s->_features & GF_AFTER_V7) || (_s->_features & GF_SMALL_HEADER))
return 0; return 0;
if (_s->_features & GF_AFTER_V6) { if (_s->_features & GF_AFTER_V6) {
if (color==8) color=1; if (color == 8)
color = 1;
return _s->readArray(110, 0, color); return _s->readArray(110, 0, color);
} else { } else {
return _s->getStringAddress(21)[color]; return _s->getStringAddress(21)[color];
} }
} }
void Gui::init(Scumm *s) { void Gui::init(Scumm *s)
{
_s = s; _s = s;
if (_s->_gameId && !(_s->_features & GF_SMALL_HEADER) && !(_s->_features & GF_AFTER_V7)) { if (_s->_gameId && !(_s->_features & GF_SMALL_HEADER)
&& !(_s->_features & GF_AFTER_V7)) {
_bgcolor = getDefaultColor(0); _bgcolor = getDefaultColor(0);
_color = getDefaultColor(1); _color = getDefaultColor(1);
_textcolor = getDefaultColor(2); _textcolor = getDefaultColor(2);
@ -790,7 +839,8 @@ void Gui::init(Scumm *s) {
} }
} }
void Gui::loop(Scumm *s) { void Gui::loop(Scumm *s)
{
init(s); init(s);
if (_active == 1) { if (_active == 1) {
_active++; _active++;
@ -824,7 +874,8 @@ void Gui::loop(Scumm *s) {
_s->_mouseButStat = 0; _s->_mouseButStat = 0;
} }
void Gui::close() { void Gui::close()
{
_s->_fullRedraw = true; _s->_fullRedraw = true;
_s->_completeScreenRedraw = true; _s->_completeScreenRedraw = true;
_s->_cursorAnimate--; _s->_cursorAnimate--;
@ -841,7 +892,8 @@ void Gui::close() {
#endif #endif
} }
void Gui::saveLoadDialog(Scumm *s) { void Gui::saveLoadDialog(Scumm *s)
{
init(s); init(s);
_widgets[0] = save_load_dialog; _widgets[0] = save_load_dialog;
_editString = -1; _editString = -1;
@ -850,7 +902,8 @@ void Gui::saveLoadDialog(Scumm *s) {
_dialog = SAVELOAD_DIALOG; _dialog = SAVELOAD_DIALOG;
} }
void Gui::pause(Scumm *s) { void Gui::pause(Scumm *s)
{
init(s); init(s);
_widgets[0] = pause_dialog; _widgets[0] = pause_dialog;
_cur_page = 0; _cur_page = 0;
@ -858,7 +911,8 @@ void Gui::pause(Scumm *s) {
_dialog = PAUSE_DIALOG; _dialog = PAUSE_DIALOG;
} }
void Gui::options(Scumm *s) { void Gui::options(Scumm *s)
{
init(s); init(s);
_widgets[0] = options_dialog; _widgets[0] = options_dialog;
_active = true; _active = true;
@ -866,7 +920,8 @@ void Gui::options(Scumm *s) {
_dialog = OPTIONS_DIALOG; _dialog = OPTIONS_DIALOG;
} }
void Gui::launcher(Scumm *s) { void Gui::launcher(Scumm *s)
{
init(s); init(s);
_widgets[0] = launcher_dialog; _widgets[0] = launcher_dialog;
_active = true; _active = true;

View file

@ -23,7 +23,6 @@
#include"stdafx.h" #include"stdafx.h"
#include"scumm.h" #include"scumm.h"
Scumm::Scumm(void) Scumm::Scumm (void) {
{
/* No need to put anything here yet :) */ /* No need to put anything here yet :) */
} }

View file

@ -29,53 +29,63 @@
#define SWAP2(a) ((((a)>>24)&0xFF) | (((a)>>8)&0xFF00) | (((a)<<8)&0xFF0000) | (((a)<<24)&0xFF000000)) #define SWAP2(a) ((((a)>>24)&0xFF) | (((a)>>8)&0xFF00) | (((a)<<8)&0xFF0000) | (((a)<<24)&0xFF000000))
void invalidblock(uint32 tag) { void invalidblock(uint32 tag)
error("Encountered invalid block %c%c%c%c", tag>>24, tag>>16, tag>>8, tag); {
error("Encountered invalid block %c%c%c%c", tag >> 24, tag >> 16, tag >> 8,
tag);
} }
int _frameChanged; int _frameChanged;
uint32 SmushPlayer::nextBE32() { uint32 SmushPlayer::nextBE32()
{
uint32 a = *((uint32 *)_cur); uint32 a = *((uint32 *)_cur);
_cur += sizeof(uint32); _cur += sizeof(uint32);
return SWAP2(a); return SWAP2(a);
} }
void SmushPlayer::fileRead(void *mem, int len) { void SmushPlayer::fileRead(void *mem, int len)
{
if (fread(mem, len, 1, _in) != 1) if (fread(mem, len, 1, _in) != 1)
error("EOF while reading"); error("EOF while reading");
} }
uint32 SmushPlayer::fileReadBE32() { uint32 SmushPlayer::fileReadBE32()
{
uint32 number; uint32 number;
fileRead(&number, sizeof(number)); fileRead(&number, sizeof(number));
return SWAP2(number); return SWAP2(number);
} }
uint32 SmushPlayer::fileReadLE32() { uint32 SmushPlayer::fileReadLE32()
{
uint32 number; uint32 number;
fileRead(&number, sizeof(number)); fileRead(&number, sizeof(number));
return number; return number;
} }
void SmushPlayer::openFile(byte* fileName) { void SmushPlayer::openFile(byte *fileName)
{
byte buf[100]; byte buf[100];
sprintf((char*)buf,"%sVIDEO/%s",(char*)sm->_gameDataPath,(char*)fileName); sprintf((char *)buf, "%sVIDEO/%s", (char *)sm->_gameDataPath,
(char *)fileName);
_in = fopen((char *)buf, "rb"); _in = fopen((char *)buf, "rb");
if (_in == NULL) { if (_in == NULL) {
sprintf((char*)buf,"%svideo/%s",(char*)sm->_gameDataPath,(char*)fileName); sprintf((char *)buf, "%svideo/%s", (char *)sm->_gameDataPath,
(char *)fileName);
_in = fopen((char *)buf, "rb"); _in = fopen((char *)buf, "rb");
} }
} }
void SmushPlayer::nextBlock() { void SmushPlayer::nextBlock()
{
_blockTag = fileReadBE32(); _blockTag = fileReadBE32();
_blockSize = fileReadBE32(); _blockSize = fileReadBE32();
@ -90,7 +100,8 @@ void SmushPlayer::nextBlock() {
fileRead(_block, _blockSize); fileRead(_block, _blockSize);
} }
bool SmushPlayer::parseTag() { bool SmushPlayer::parseTag()
{
switch (nextBlock(), _blockTag) { switch (nextBlock(), _blockTag) {
case 'AHDR': case 'AHDR':
@ -110,7 +121,8 @@ bool SmushPlayer::parseTag() {
void SmushPlayer::parseAHDR() { void SmushPlayer::parseAHDR()
{
// memcpy(_fluPalette, _block, 0x300); // memcpy(_fluPalette, _block, 0x300);
_paletteChanged = true; _paletteChanged = true;
@ -119,7 +131,8 @@ void SmushPlayer::parseAHDR() {
void SmushPlayer::parseNPAL() { void SmushPlayer::parseNPAL()
{
memcpy(_fluPalette, _cur, 0x300); memcpy(_fluPalette, _cur, 0x300);
_paletteChanged = true; _paletteChanged = true;
@ -127,7 +140,8 @@ void SmushPlayer::parseNPAL() {
void codec1(CodecData *cd) { void codec1(CodecData * cd)
{
uint y = cd->y; uint y = cd->y;
byte *src = cd->src; byte *src = cd->src;
byte *dest = cd->out; byte *dest = cd->out;
@ -156,7 +170,8 @@ void codec1(CodecData *cd) {
byte code = *src++; byte code = *src++;
num = (code >> 1) + 1; num = (code >> 1) + 1;
if (num>len) num=len; if (num > len)
num = len;
len -= num; len -= num;
if (code & 1) { if (code & 1) {
@ -182,7 +197,8 @@ void codec1(CodecData *cd) {
void codec37_bompdepack(byte *dst, byte *src, int len) { void codec37_bompdepack(byte *dst, byte *src, int len)
{
byte code; byte code;
byte color; byte color;
int num; int num;
@ -203,7 +219,9 @@ void codec37_bompdepack(byte *dst, byte *src, int len) {
} while (len -= num); } while (len -= num);
} }
void codec37_proc5(byte *dst, byte *src, int next_offs, int bw, int bh, int pitch, int16 *table) { void codec37_proc5(byte *dst, byte *src, int next_offs, int bw, int bh,
int pitch, int16 * table)
{
byte code, *tmp; byte code, *tmp;
int i; int i;
@ -337,7 +355,8 @@ static const int8 maketable_bytes[] = {
-12, 19, 13, 19, -6, 22, 6, 22, 0, 23, -12, 19, 13, 19, -6, 22, 6, 22, 0, 23,
}; };
void codec37_maketable(PersistentCodecData37 *pcd, int pitch, byte idx) { void codec37_maketable(PersistentCodecData37 * pcd, int pitch, byte idx)
{
int i, j; int i, j;
if (pcd->table_last_pitch == pitch && pcd->table_last_flags == idx) if (pcd->table_last_pitch == pitch && pcd->table_last_flags == idx)
@ -350,13 +369,15 @@ void codec37_maketable(PersistentCodecData37 *pcd, int pitch, byte idx) {
for (i = 0; i < 255; i++) { for (i = 0; i < 255; i++) {
j = i + idx * 255; j = i + idx * 255;
pcd->table1[i] = maketable_bytes[j*2+1] * pitch + maketable_bytes[j*2]; pcd->table1[i] =
maketable_bytes[j * 2 + 1] * pitch + maketable_bytes[j * 2];
} }
} }
int codec37(CodecData *cd, PersistentCodecData37 *pcd) { int codec37(CodecData * cd, PersistentCodecData37 * pcd)
{
int width_in_blocks, height_in_blocks; int width_in_blocks, height_in_blocks;
int src_pitch; int src_pitch;
byte *curbuf; byte *curbuf;
@ -376,7 +397,8 @@ int codec37(CodecData *cd, PersistentCodecData37 *pcd) {
curbuf = pcd->deltaBufs[pcd->curtable]; curbuf = pcd->deltaBufs[pcd->curtable];
memset(pcd->deltaBuf, 0, curbuf - pcd->deltaBuf); memset(pcd->deltaBuf, 0, curbuf - pcd->deltaBuf);
size = *(uint32 *)(cd->src + 4); size = *(uint32 *)(cd->src + 4);
memset(curbuf + size, 0, pcd->deltaBuf + pcd->deltaSize - curbuf - size); memset(curbuf + size, 0,
pcd->deltaBuf + pcd->deltaSize - curbuf - size);
memcpy(curbuf, cd->src + 16, size); memcpy(curbuf, cd->src + 16, size);
break; break;
} }
@ -390,7 +412,8 @@ int codec37(CodecData *cd, PersistentCodecData37 *pcd) {
return (1); return (1);
memset(pcd->deltaBuf, 0, curbuf - pcd->deltaBuf); memset(pcd->deltaBuf, 0, curbuf - pcd->deltaBuf);
memset(curbuf + size, 0, pcd->deltaBuf + pcd->deltaSize - curbuf - size); memset(curbuf + size, 0,
pcd->deltaBuf + pcd->deltaSize - curbuf - size);
break; break;
} }
@ -411,9 +434,9 @@ int codec37(CodecData *cd, PersistentCodecData37 *pcd) {
} }
codec37_proc5(pcd->deltaBufs[pcd->curtable], cd->src + 16, codec37_proc5(pcd->deltaBufs[pcd->curtable], cd->src + 16,
pcd->deltaBufs[pcd->curtable^1] - pcd->deltaBufs[pcd->curtable], pcd->deltaBufs[pcd->curtable ^ 1] -
width_in_blocks, height_in_blocks, src_pitch, pcd->deltaBufs[pcd->curtable], width_in_blocks,
pcd->table1); height_in_blocks, src_pitch, pcd->table1);
break; break;
} }
@ -437,7 +460,8 @@ int codec37(CodecData *cd, PersistentCodecData37 *pcd) {
return (_frameChanged); return (_frameChanged);
} }
void codec37_init(PersistentCodecData37 *pcd, int width, int height) { void codec37_init(PersistentCodecData37 * pcd, int width, int height)
{
pcd->width = width; pcd->width = width;
pcd->height = height; pcd->height = height;
pcd->deltaSize = width * height * 2 + 0x3E00 + 0xBA00; pcd->deltaSize = width * height * 2 + 0x3E00 + 0xBA00;
@ -448,7 +472,8 @@ void codec37_init(PersistentCodecData37 *pcd, int width, int height) {
pcd->table1 = (int16 *) calloc(255, sizeof(uint16)); pcd->table1 = (int16 *) calloc(255, sizeof(uint16));
} }
void SmushPlayer::parseFOBJ() { void SmushPlayer::parseFOBJ()
{
byte codec; byte codec;
CodecData cd; CodecData cd;
@ -475,15 +500,18 @@ void SmushPlayer::parseFOBJ() {
} }
} }
void SmushPlayer::parsePSAD() { void SmushPlayer::parsePSAD()
{
//printf("parse PSAD\n"); //printf("parse PSAD\n");
} }
void SmushPlayer::parseTRES() { void SmushPlayer::parseTRES()
{
// printf("parse TRES\n"); // printf("parse TRES\n");
} }
void SmushPlayer::parseXPAL() { void SmushPlayer::parseXPAL()
{
int num; int num;
int i; int i;
@ -509,7 +537,8 @@ void SmushPlayer::parseXPAL() {
_paletteChanged = true; _paletteChanged = true;
} }
void SmushPlayer::parseFRME() { void SmushPlayer::parseFRME()
{
_cur = _block; _cur = _block;
do { do {
@ -547,16 +576,20 @@ void SmushPlayer::parseFRME() {
} while (_cur + 4 < _block + _blockSize); } while (_cur + 4 < _block + _blockSize);
} }
void SmushPlayer::init() { void SmushPlayer::init()
{
_renderBitmap = sm->_videoBuffer; _renderBitmap = sm->_videoBuffer;
codec37_init(&pcd37, 320, 200); codec37_init(&pcd37, 320, 200);
} }
void SmushPlayer::go() { void SmushPlayer::go()
while (parseTag()) {} {
while (parseTag()) {
}
} }
void SmushPlayer::setPalette() { void SmushPlayer::setPalette()
{
int i; int i;
for (i = 0; i < 768; i++) for (i = 0; i < 768; i++)
@ -628,8 +661,7 @@ void SmushPlayer::startVideo(short int arg, byte* videoFile)
sm->setDirtyColors(0, 255); sm->setDirtyColors(0, 255);
} }
if ( _frameChanged) if (_frameChanged) {
{
blitToScreen(sm, sm->_videoBuffer, 0, 0, 320, 200); blitToScreen(sm, sm->_videoBuffer, 0, 0, 320, 200);
updateScreen(sm); updateScreen(sm);
@ -646,6 +678,3 @@ void SmushPlayer::startVideo(short int arg, byte* videoFile)
sm->exitCutscene(); sm->exitCutscene();
} }

View file

@ -154,7 +154,8 @@ bool parse_xing_vbr_tag()
return (result != -1); return (result != -1);
} }
uint32 calc_cd_file_offset(int start_frame) { uint32 calc_cd_file_offset(int start_frame)
{
long offset; long offset;
if (!_vbr_header.flags) { if (!_vbr_header.flags) {
@ -164,28 +165,29 @@ uint32 calc_cd_file_offset(int start_frame) {
/* Constant bit rate - perhaps not fully accurate */ /* Constant bit rate - perhaps not fully accurate */
frame_size = 144 * _mad_header.bitrate / _mad_header.samplerate; frame_size = 144 * _mad_header.bitrate / _mad_header.samplerate;
offset = (long)((float)start_frame / (float)CD_FPS * 1000 / offset = (long)((float)start_frame / (float)CD_FPS * 1000 /
(float)((float)1152 / (float)_mad_header.samplerate * 1000) * (float)((float)1152 / (float)_mad_header.samplerate *
(float)(frame_size + 0.5)); 1000) * (float)(frame_size + 0.5));
} } else {
else {
/* DOES NOT WORK AT THE MOMENT */ /* DOES NOT WORK AT THE MOMENT */
/* see Xing SDK */ /* see Xing SDK */
long a; long a;
float fa, fb, fx; float fa, fb, fx;
float percent = (float)start_frame / (float)CD_FPS * 1000 / float percent = (float)start_frame / (float)CD_FPS * 1000 /
((float)((float)1152 / (float)_mad_header.samplerate * 1000) * _vbr_header.frames) * ((float)((float)1152 / (float)_mad_header.samplerate * 1000) *
100; _vbr_header.frames) * 100;
if( percent < 0.0f ) percent = 0.0f; if (percent < 0.0f)
if( percent > 100.0f ) percent = 100.0f; percent = 0.0f;
if (percent > 100.0f)
percent = 100.0f;
a = (int)percent; a = (int)percent;
if( a > 99 ) a = 99; if (a > 99)
a = 99;
fa = _vbr_header.toc[a]; fa = _vbr_header.toc[a];
if (a < 99) { if (a < 99) {
fb = _vbr_header.toc[a + 1]; fb = _vbr_header.toc[a + 1];
} } else {
else {
fb = 256.0f; fb = 256.0f;
} }
@ -198,7 +200,9 @@ uint32 calc_cd_file_offset(int start_frame) {
return offset; return offset;
} }
bool mp3_cd_play(Scumm *s, int track, int num_loops, int start_frame, int end_frame) { bool mp3_cd_play(Scumm *s, int track, int num_loops, int start_frame,
int end_frame)
{
// See if we are already playing this track, else try to open it // See if we are already playing this track, else try to open it
@ -213,15 +217,13 @@ bool mp3_cd_play(Scumm *s, int track, int num_loops, int start_frame, int end_fr
} }
if (!parse_xing_vbr_tag()) { if (!parse_xing_vbr_tag()) {
warning("Error parsing file header - ignoring file", warning("Error parsing file header - ignoring file", track);
track);
fclose(_mp3_track); fclose(_mp3_track);
return false; return false;
} }
if (_vbr_header.flags) { if (_vbr_header.flags) {
if (!( if (!((_vbr_header.flags & XING_TOC) &&
(_vbr_header.flags & XING_TOC) &&
(_vbr_header.flags & XING_BYTES) && (_vbr_header.flags & XING_BYTES) &&
(_vbr_header.flags & XING_FRAMES) (_vbr_header.flags & XING_FRAMES)
)) { )) {
@ -231,7 +233,6 @@ bool mp3_cd_play(Scumm *s, int track, int num_loops, int start_frame, int end_fr
return false; return false;
} }
} }
// Allocate the music mixer if necessary // Allocate the music mixer if necessary
if (!_mc) { if (!_mc) {
@ -278,9 +279,7 @@ bool mp3_cd_play(Scumm *s, int track, int num_loops, int start_frame, int end_fr
} }
mad_timer_set(&_mc->sound_data.mp3_cdmusic.duration, mad_timer_set(&_mc->sound_data.mp3_cdmusic.duration,
0, 0, end_frame, CD_FPS);
end_frame,
CD_FPS);
fseek(_mp3_track, where, SEEK_SET); fseek(_mp3_track, where, SEEK_SET);
_mc->sound_data.mp3_cdmusic.playing = true; _mc->sound_data.mp3_cdmusic.playing = true;
@ -292,4 +291,3 @@ bool mp3_cd_play(Scumm *s, int track, int num_loops, int start_frame, int end_fr
} }
#endif #endif

View file

@ -23,61 +23,78 @@
#include "stdafx.h" #include "stdafx.h"
#include "scumm.h" #include "scumm.h"
bool Scumm::getClass(int obj, int cls) { bool Scumm::getClass(int obj, int cls)
checkRange(_numGlobalObjects-1, 0, obj, "Object %d out of range in getClass"); {
checkRange(_numGlobalObjects - 1, 0, obj,
"Object %d out of range in getClass");
cls &= 0x7F; cls &= 0x7F;
checkRange(32, 1, cls, "Class %d out of range in getClass"); checkRange(32, 1, cls, "Class %d out of range in getClass");
if (_features & GF_SMALL_HEADER) { if (_features & GF_SMALL_HEADER) {
if (cls == 32) // CLASS_TOUCHABLE if (cls == 32) // CLASS_TOUCHABLE
cls = 23; cls = 24;
} }
return (_classData[obj] & (1 << (cls - 1))) != 0; return (_classData[obj] & (1 << (cls - 1))) != 0;
} }
void Scumm::putClass(int obj, int cls, bool set) { void Scumm::putClass(int obj, int cls, bool set)
checkRange(_numGlobalObjects-1, 0, obj, "Object %d out of range in putClass"); {
checkRange(_numGlobalObjects - 1, 0, obj,
"Object %d out of range in putClass");
cls &= 0x7F; cls &= 0x7F;
checkRange(32, 1, cls, "Class %d out of range in getClass"); checkRange(32, 1, cls, "Class %d out of range in getClass");
if (_features & GF_SMALL_HEADER) { if (_features & GF_SMALL_HEADER) {
if (cls == 32) // CLASS_TOUCHABLE if (cls == 32) // CLASS_TOUCHABLE
cls = 23; cls = 24;
} }
if (set) if (set)
_classData[obj] |= (1 << (cls - 1)); _classData[obj] |= (1 << (cls - 1));
else else
_classData[obj] &= ~(1 << (cls - 1)); _classData[obj] &= ~(1 << (cls - 1));
} }
int Scumm::getOwner(int obj) { int Scumm::getOwner(int obj)
checkRange(_numGlobalObjects-1, 0, obj, "Object %d out of range in getOwner"); {
checkRange(_numGlobalObjects - 1, 0, obj,
"Object %d out of range in getOwner");
return _objectOwnerTable[obj]; return _objectOwnerTable[obj];
} }
void Scumm::putOwner(int act, int owner) { void Scumm::putOwner(int act, int owner)
checkRange(_numGlobalObjects-1, 0, act, "Object %d out of range in putOwner"); {
checkRange(_numGlobalObjects - 1, 0, act,
"Object %d out of range in putOwner");
checkRange(0xFF, 0, owner, "Owner %d out of range in putOwner"); checkRange(0xFF, 0, owner, "Owner %d out of range in putOwner");
_objectOwnerTable[act] = owner; _objectOwnerTable[act] = owner;
} }
int Scumm::getState(int act) { int Scumm::getState(int act)
checkRange(_numGlobalObjects-1, 0, act, "Object %d out of range in getState"); {
checkRange(_numGlobalObjects - 1, 0, act,
"Object %d out of range in getState");
return _objectStateTable[act]; return _objectStateTable[act];
} }
void Scumm::putState(int act, int state) { void Scumm::putState(int act, int state)
checkRange(_numGlobalObjects-1, 0, act, "Object %d out of range in putState"); {
checkRange(_numGlobalObjects - 1, 0, act,
"Object %d out of range in putState");
checkRange(0xFF, 0, state, "State %d out of range in putState"); checkRange(0xFF, 0, state, "State %d out of range in putState");
_objectStateTable[act] = state; _objectStateTable[act] = state;
} }
int Scumm::getObjectRoom(int obj) { int Scumm::getObjectRoom(int obj)
checkRange(_numGlobalObjects-1, 0, obj, "Object %d out of range in getObjectRoom"); {
checkRange(_numGlobalObjects - 1, 0, obj,
"Object %d out of range in getObjectRoom");
return _objectRoomTable[obj]; return _objectRoomTable[obj];
} }
int Scumm::getObjectIndex(int object) { int Scumm::getObjectIndex(int object)
{
int i; int i;
/* OF_OWNER_ROOM should be 0xFF for full throttle, else 0xF */ /* OF_OWNER_ROOM should be 0xFF for full throttle, else 0xF */
@ -95,7 +112,8 @@ int Scumm::getObjectIndex(int object) {
} }
} }
int Scumm::whereIsObject(int object) { int Scumm::whereIsObject(int object)
{
int i; int i;
if (object >= _numGlobalObjects) if (object >= _numGlobalObjects)
@ -117,7 +135,8 @@ int Scumm::whereIsObject(int object) {
return WIO_NOT_FOUND; return WIO_NOT_FOUND;
} }
int Scumm::getObjectOrActorXY(int object) { int Scumm::getObjectOrActorXY(int object)
{
if (object < NUM_ACTORS) if (object < NUM_ACTORS)
return getActorXYPos(derefActorSafe(object, "getObjectOrActorXY")); return getActorXYPos(derefActorSafe(object, "getObjectOrActorXY"));
@ -126,7 +145,9 @@ int Scumm::getObjectOrActorXY(int object) {
return -1; return -1;
case WIO_INVENTORY: case WIO_INVENTORY:
if (_objectOwnerTable[object] < NUM_ACTORS) if (_objectOwnerTable[object] < NUM_ACTORS)
return getActorXYPos(derefActorSafe(_objectOwnerTable[object],"getObjectOrActorXY(2)")); return
getActorXYPos(derefActorSafe
(_objectOwnerTable[object], "getObjectOrActorXY(2)"));
else else
return 0xFF; return 0xFF;
} }
@ -137,7 +158,8 @@ int Scumm::getObjectOrActorXY(int object) {
/* Return the position of an object. /* Return the position of an object.
Returns X, Y and direction in angles Returns X, Y and direction in angles
*/ */
void Scumm::getObjectXYPos(int object) { void Scumm::getObjectXYPos(int object)
{
ObjectData *od = &_objs[getObjectIndex(object)]; ObjectData *od = &_objs[getObjectIndex(object)];
int state; int state;
byte *ptr; byte *ptr;
@ -183,7 +205,8 @@ void Scumm::getObjectXYPos(int object) {
} }
} }
int Scumm::getObjActToObjActDist(int a, int b) { int Scumm::getObjActToObjActDist(int a, int b)
{
int x, y; int x, y;
Actor *acta = NULL; Actor *acta = NULL;
Actor *actb = NULL; Actor *actb = NULL;
@ -216,11 +239,13 @@ int Scumm::getObjActToObjActDist(int a, int b) {
y = abs(y - _yPos); y = abs(y - _yPos);
x = abs(x - _xPos); x = abs(x - _xPos);
if (y>x) x=y; if (y > x)
x = y;
return x; return x;
} }
int Scumm::findObject(int x, int y) { int Scumm::findObject(int x, int y)
{
int i, b; int i, b;
byte a; byte a;
@ -234,8 +259,7 @@ int Scumm::findObject(int x, int y) {
if (b == 0) { if (b == 0) {
if (_objs[i].x_pos <= x && if (_objs[i].x_pos <= x &&
_objs[i].width + _objs[i].x_pos > x && _objs[i].width + _objs[i].x_pos > x &&
_objs[i].y_pos <= y && _objs[i].y_pos <= y && _objs[i].height + _objs[i].y_pos > y)
_objs[i].height + _objs[i].y_pos > y)
return _objs[i].obj_nr; return _objs[i].obj_nr;
break; break;
} }
@ -244,7 +268,8 @@ int Scumm::findObject(int x, int y) {
return 0; return 0;
} }
void Scumm::drawRoomObject(int i, int arg) { void Scumm::drawRoomObject(int i, int arg)
{
ObjectData *od; ObjectData *od;
byte a; byte a;
@ -262,7 +287,8 @@ void Scumm::drawRoomObject(int i, int arg) {
} while (od->state == a); } while (od->state == a);
} }
void Scumm::drawRoomObjects(int arg) { void Scumm::drawRoomObjects(int arg)
{
int i; int i;
if (_features & GF_DRAWOBJ_OTHER_ORDER) { if (_features & GF_DRAWOBJ_OTHER_ORDER) {
@ -293,7 +319,8 @@ const uint32 IMxx_tags[] = {
MKID('IM0F') MKID('IM0F')
}; };
void Scumm::drawObject(int obj, int arg) { void Scumm::drawObject(int obj, int arg)
{
ObjectData *od; ObjectData *od;
int xpos, ypos, height, width; int xpos, ypos, height, width;
byte *ptr; byte *ptr;
@ -312,7 +339,8 @@ void Scumm::drawObject(int obj, int arg) {
width = od->width >> 3; width = od->width >> 3;
height = od->height &= 0xF8; // Ender height = od->height &= 0xF8; // Ender
if (width==0 || xpos > _screenEndStrip || xpos + width < _screenStartStrip) if (width == 0 || xpos > _screenEndStrip
|| xpos + width < _screenStartStrip)
return; return;
if (od->fl_object_index) { if (od->fl_object_index) {
@ -350,11 +378,13 @@ void Scumm::drawObject(int obj, int arg) {
byte flags = Gdi::dbAllowMaskOr; byte flags = Gdi::dbAllowMaskOr;
if (_features & GF_AFTER_V7 && getClass(od->obj_nr, 22)) if (_features & GF_AFTER_V7 && getClass(od->obj_nr, 22))
flags |= Gdi::dbDrawMaskOnBoth; flags |= Gdi::dbDrawMaskOnBoth;
gdi.drawBitmap(ptr, _curVirtScreen, x, ypos, height, x-xpos, numstrip, flags); gdi.drawBitmap(ptr, _curVirtScreen, x, ypos, height, x - xpos, numstrip,
flags);
} }
} }
void Scumm::loadRoomObjects() { void Scumm::loadRoomObjects()
{
int i, j; int i, j;
ObjectData *od; ObjectData *od;
byte *ptr; byte *ptr;
@ -364,9 +394,7 @@ void Scumm::loadRoomObjects() {
RoomHeader *roomhdr; RoomHeader *roomhdr;
CodeHeader *cdhd; CodeHeader *cdhd;
CHECK_HEAP CHECK_HEAP room = getResourceAddress(rtRoom, _roomResource);
room = getResourceAddress(rtRoom, _roomResource);
roomhdr = (RoomHeader *)findResourceData(MKID('RMHD'), room); roomhdr = (RoomHeader *)findResourceData(MKID('RMHD'), room);
if (_features & GF_AFTER_V7) if (_features & GF_AFTER_V7)
@ -392,8 +420,7 @@ void Scumm::loadRoomObjects() {
if (_features & GF_AFTER_V7) if (_features & GF_AFTER_V7)
od->obj_nr = READ_LE_UINT16(&(cdhd->v7.obj_id)); od->obj_nr = READ_LE_UINT16(&(cdhd->v7.obj_id));
else else if (_features & GF_AFTER_V6)
if(_features & GF_AFTER_V6)
od->obj_nr = READ_LE_UINT16(&(cdhd->v6.obj_id)); od->obj_nr = READ_LE_UINT16(&(cdhd->v6.obj_id));
else else
od->obj_nr = READ_LE_UINT16(&(cdhd->v5.obj_id)); od->obj_nr = READ_LE_UINT16(&(cdhd->v5.obj_id));
@ -432,10 +459,10 @@ void Scumm::loadRoomObjects() {
setupRoomObject(od, room); setupRoomObject(od, room);
} }
CHECK_HEAP CHECK_HEAP}
}
void Scumm::loadRoomObjectsSmall() { void Scumm::loadRoomObjectsSmall()
{
int i, j; int i, j;
ObjectData *od; ObjectData *od;
byte *ptr; byte *ptr;
@ -443,9 +470,7 @@ void Scumm::loadRoomObjectsSmall() {
byte *room, *searchptr; byte *room, *searchptr;
RoomHeader *roomhdr; RoomHeader *roomhdr;
CHECK_HEAP CHECK_HEAP room = getResourceAddress(rtRoom, _roomResource);
room = getResourceAddress(rtRoom, _roomResource);
roomhdr = (RoomHeader *)findResourceData(MKID('RMHD'), room); roomhdr = (RoomHeader *)findResourceData(MKID('RMHD'), room);
_numObjectsInRoom = READ_LE_UINT16(&(roomhdr->old.numObjects)); _numObjectsInRoom = READ_LE_UINT16(&(roomhdr->old.numObjects));
@ -496,10 +521,10 @@ void Scumm::loadRoomObjectsSmall() {
setupRoomObject(od, room); setupRoomObject(od, room);
} }
CHECK_HEAP CHECK_HEAP}
}
void Scumm::setupRoomObject(ObjectData *od, byte *room) { void Scumm::setupRoomObject(ObjectData *od, byte *room)
{
CodeHeader *cdhd; CodeHeader *cdhd;
ImageHeader *imhd; ImageHeader *imhd;
@ -533,11 +558,12 @@ void Scumm::setupRoomObject(ObjectData *od, byte *room) {
return; return;
} }
cdhd = (CodeHeader*)findResourceData(MKID('CDHD'), room + od->offs_obcd_to_room); cdhd =
(CodeHeader *)findResourceData(MKID('CDHD'),
room + od->offs_obcd_to_room);
if (_features & GF_AFTER_V7) if (_features & GF_AFTER_V7)
od->obj_nr = READ_LE_UINT16(&(cdhd->v7.obj_id)); od->obj_nr = READ_LE_UINT16(&(cdhd->v7.obj_id));
else else if (_features & GF_AFTER_V6)
if(_features & GF_AFTER_V6)
od->obj_nr = READ_LE_UINT16(&(cdhd->v6.obj_id)); od->obj_nr = READ_LE_UINT16(&(cdhd->v6.obj_id));
else else
od->obj_nr = READ_LE_UINT16(&(cdhd->v5.obj_id)); od->obj_nr = READ_LE_UINT16(&(cdhd->v5.obj_id));
@ -574,7 +600,9 @@ void Scumm::setupRoomObject(ObjectData *od, byte *room) {
od->parent = cdhd->v7.parent; od->parent = cdhd->v7.parent;
od->parentstate = cdhd->v7.parentstate; od->parentstate = cdhd->v7.parentstate;
imhd = (ImageHeader*)findResourceData(MKID('IMHD'), room + od->offs_obim_to_room); imhd =
(ImageHeader *)findResourceData(MKID('IMHD'),
room + od->offs_obim_to_room);
od->x_pos = READ_LE_UINT16(&imhd->v7.x_pos); od->x_pos = READ_LE_UINT16(&imhd->v7.x_pos);
od->y_pos = READ_LE_UINT16(&imhd->v7.y_pos); od->y_pos = READ_LE_UINT16(&imhd->v7.y_pos);
od->width = READ_LE_UINT16(&imhd->v7.width); od->width = READ_LE_UINT16(&imhd->v7.width);
@ -585,7 +613,8 @@ void Scumm::setupRoomObject(ObjectData *od, byte *room) {
od->fl_object_index = 0; od->fl_object_index = 0;
} }
void Scumm::fixObjectFlags() { void Scumm::fixObjectFlags()
{
int i; int i;
ObjectData *od = &_objs[1]; ObjectData *od = &_objs[1];
for (i = 1; i <= _numObjectsInRoom; i++, od++) { for (i = 1; i <= _numObjectsInRoom; i++, od++) {
@ -593,7 +622,8 @@ void Scumm::fixObjectFlags() {
} }
} }
void Scumm::processDrawQue() { void Scumm::processDrawQue()
{
int i, j; int i, j;
for (i = 0; i < _drawObjectQueNr; i++) { for (i = 0; i < _drawObjectQueNr; i++) {
j = _drawObjectQue[i]; j = _drawObjectQue[i];
@ -603,7 +633,8 @@ void Scumm::processDrawQue() {
_drawObjectQueNr = 0; _drawObjectQueNr = 0;
} }
void Scumm::clearOwnerOf(int obj) { void Scumm::clearOwnerOf(int obj)
{
int i, j; int i, j;
uint16 *a; uint16 *a;
@ -643,7 +674,8 @@ void Scumm::clearOwnerOf(int obj) {
} }
} }
void Scumm::removeObjectFromRoom(int obj) { void Scumm::removeObjectFromRoom(int obj)
{
int i, cnt; int i, cnt;
uint32 *ptr; uint32 *ptr;
@ -662,17 +694,21 @@ void Scumm::removeObjectFromRoom(int obj) {
} }
} }
void Scumm::addObjectToDrawQue(int object) { void Scumm::addObjectToDrawQue(int object)
{
_drawObjectQue[_drawObjectQueNr++] = object; _drawObjectQue[_drawObjectQueNr++] = object;
if ((unsigned int)_drawObjectQueNr > sizeof(_drawObjectQue)/sizeof(_drawObjectQue[0])) if ((unsigned int)_drawObjectQueNr >
sizeof(_drawObjectQue) / sizeof(_drawObjectQue[0]))
error("Draw Object Que overflow"); error("Draw Object Que overflow");
} }
void Scumm::clearDrawObjectQueue() { void Scumm::clearDrawObjectQueue()
{
_drawObjectQueNr = 0; _drawObjectQueNr = 0;
} }
byte *Scumm::getObjOrActorName(int obj) { byte *Scumm::getObjOrActorName(int obj)
{
byte *objptr; byte *objptr;
if (obj < NUM_ACTORS) if (obj < NUM_ACTORS)
@ -694,7 +730,8 @@ byte *Scumm::getObjOrActorName(int obj) {
return findResourceData(MKID('OBNA'), objptr); return findResourceData(MKID('OBNA'), objptr);
} }
uint32 Scumm::getOBCDOffs(int object) { uint32 Scumm::getOBCDOffs(int object)
{
int i; int i;
if (_objectOwnerTable[object] != OF_OWNER_ROOM) if (_objectOwnerTable[object] != OF_OWNER_ROOM)
@ -709,7 +746,8 @@ uint32 Scumm::getOBCDOffs(int object) {
return 0; return 0;
} }
byte *Scumm::getOBCDFromObject(int obj) { byte *Scumm::getOBCDFromObject(int obj)
{
int i; int i;
if (_objectOwnerTable[obj] != OF_OWNER_ROOM) { if (_objectOwnerTable[obj] != OF_OWNER_ROOM) {
@ -722,14 +760,16 @@ byte *Scumm::getOBCDFromObject(int obj) {
if (_objs[i].obj_nr == obj) { if (_objs[i].obj_nr == obj) {
if (_objs[i].fl_object_index) if (_objs[i].fl_object_index)
return getResourceAddress(rtFlObject, _objs[i].fl_object_index) + 8; return getResourceAddress(rtFlObject, _objs[i].fl_object_index) + 8;
return getResourceAddress(rtRoom, _roomResource) + _objs[i].offs_obcd_to_room; return getResourceAddress(rtRoom,
_roomResource) + _objs[i].offs_obcd_to_room;
} }
} }
} }
return 0; return 0;
} }
void Scumm::addObjectToInventory(uint obj, uint room) { void Scumm::addObjectToInventory(uint obj, uint room)
{
int i, slot; int i, slot;
uint32 size; uint32 size;
byte *obcdptr, *ptr; byte *obcdptr, *ptr;
@ -737,9 +777,7 @@ void Scumm::addObjectToInventory(uint obj, uint room) {
debug(1, "Adding object %d from room %d into inventory", obj, room); debug(1, "Adding object %d from room %d into inventory", obj, room);
CHECK_HEAP CHECK_HEAP if (whereIsObject(obj) == WIO_FLOBJECT) {
if (whereIsObject(obj)==WIO_FLOBJECT) {
i = getObjectIndex(obj); i = getObjectIndex(obj);
ptr = getResourceAddress(rtFlObject, _objs[i].fl_object_index) + 8; ptr = getResourceAddress(rtFlObject, _objs[i].fl_object_index) + 8;
size = READ_BE_UINT32_UNALIGNED(ptr + 4); size = READ_BE_UINT32_UNALIGNED(ptr + 4);
@ -761,10 +799,11 @@ void Scumm::addObjectToInventory(uint obj, uint room) {
memcpy(getResourceAddress(rtInventory, slot), obcdptr, size); memcpy(getResourceAddress(rtInventory, slot), obcdptr, size);
} }
CHECK_HEAP CHECK_HEAP}
}
void Scumm::findObjectInRoom(FindObjectInRoom *fo, byte findWhat, uint id, uint room) { void Scumm::findObjectInRoom(FindObjectInRoom * fo, byte findWhat, uint id,
uint room)
{
CodeHeader *cdhd; CodeHeader *cdhd;
int i, numobj; int i, numobj;
byte *roomptr, *obcdptr, *obimptr, *searchptr; byte *roomptr, *obcdptr, *obimptr, *searchptr;
@ -776,7 +815,8 @@ void Scumm::findObjectInRoom(FindObjectInRoom *fo, byte findWhat, uint id, uint
if (findWhat & foCheckAlreadyLoaded && getObjectIndex(id) != -1) { if (findWhat & foCheckAlreadyLoaded && getObjectIndex(id) != -1) {
fo->obcd = obcdptr = getOBCDFromObject(id); fo->obcd = obcdptr = getOBCDFromObject(id);
assert((byte *)obcdptr > (byte *)256); assert((byte *)obcdptr > (byte *)256);
fo->obim = obimptr = obcdptr + READ_BE_UINT32_UNALIGNED(&((ResHdr*)obcdptr)->size); fo->obim = obimptr =
obcdptr + READ_BE_UINT32_UNALIGNED(&((ResHdr *)obcdptr)->size);
fo->cdhd = (CodeHeader *)findResourceData(MKID('CDHD'), obcdptr); fo->cdhd = (CodeHeader *)findResourceData(MKID('CDHD'), obcdptr);
fo->imhd = (ImageHeader *)findResourceData(MKID('IMHD'), obimptr); fo->imhd = (ImageHeader *)findResourceData(MKID('IMHD'), obimptr);
return; return;
@ -797,7 +837,8 @@ void Scumm::findObjectInRoom(FindObjectInRoom *fo, byte findWhat, uint id, uint
if (numobj == 0) if (numobj == 0)
error("findObjectInRoom: No object found in room %d", room); error("findObjectInRoom: No object found in room %d", room);
if (numobj > _numLocalObjects) if (numobj > _numLocalObjects)
error("findObjectInRoom: More (%d) than %d objects in room %d", numobj, _numLocalObjects, room); error("findObjectInRoom: More (%d) than %d objects in room %d", numobj,
_numLocalObjects, room);
if (findWhat & foCodeHeader) { if (findWhat & foCodeHeader) {
searchptr = roomptr; searchptr = roomptr;
@ -818,8 +859,7 @@ void Scumm::findObjectInRoom(FindObjectInRoom *fo, byte findWhat, uint id, uint
cdhd = (CodeHeader *)findResourceData(MKID('CDHD'), obcdptr); cdhd = (CodeHeader *)findResourceData(MKID('CDHD'), obcdptr);
if (_features & GF_AFTER_V7) if (_features & GF_AFTER_V7)
id2 = READ_LE_UINT16(&(cdhd->v7.obj_id)); id2 = READ_LE_UINT16(&(cdhd->v7.obj_id));
else else if (_features & GF_AFTER_V6)
if( _features & GF_AFTER_V6)
id2 = READ_LE_UINT16(&(cdhd->v6.obj_id)); id2 = READ_LE_UINT16(&(cdhd->v6.obj_id));
else else
id2 = READ_LE_UINT16(&(cdhd->v5.obj_id)); id2 = READ_LE_UINT16(&(cdhd->v5.obj_id));
@ -864,13 +904,15 @@ void Scumm::findObjectInRoom(FindObjectInRoom *fo, byte findWhat, uint id, uint
} }
} }
if (++i == numobj) if (++i == numobj)
error("findObjectInRoom: Object %d image not found in room %d", id, room); error("findObjectInRoom: Object %d image not found in room %d", id,
room);
searchptr = NULL; searchptr = NULL;
} }
} }
} }
int Scumm::getInventorySlot() { int Scumm::getInventorySlot()
{
int i; int i;
for (i = 1; i <= _maxInventoryItems; i++) { for (i = 1; i <= _maxInventoryItems; i++) {
if (_inventory[i] == 0) if (_inventory[i] == 0)
@ -879,12 +921,14 @@ int Scumm::getInventorySlot() {
error("Inventory full, %d max items", _maxInventoryItems); error("Inventory full, %d max items", _maxInventoryItems);
} }
void Scumm::SamInventoryHack(int obj) { // FIXME: Sam and Max hack void Scumm::SamInventoryHack(int obj)
{ // FIXME: Sam and Max hack
int base = 6; int base = 6;
while (base < 80) { while (base < 80) {
int value = readArray(178, 0, base); int value = readArray(178, 0, base);
if (value == obj) return; if (value == obj)
return;
if (value == 0) { if (value == 0) {
_vars[179]++; _vars[179]++;
writeArray(178, 0, base, obj); writeArray(178, 0, base, obj);
@ -894,7 +938,8 @@ void Scumm::SamInventoryHack(int obj) { // FIXME: Sam and Max hack
} }
} }
void Scumm::setOwnerOf(int obj, int owner) { void Scumm::setOwnerOf(int obj, int owner)
{
ScriptSlot *ss; ScriptSlot *ss;
if (owner == 0) { if (owner == 0) {
clearOwnerOf(obj); clearOwnerOf(obj);
@ -913,7 +958,8 @@ void Scumm::setOwnerOf(int obj, int owner) {
runHook(0); runHook(0);
} }
int Scumm::getObjX(int obj) { int Scumm::getObjX(int obj)
{
if (obj < NUM_ACTORS) { if (obj < NUM_ACTORS) {
if (obj < 1) if (obj < 1)
return 0; /* fix for indy4's map */ return 0; /* fix for indy4's map */
@ -926,7 +972,8 @@ int Scumm::getObjX(int obj) {
} }
} }
int Scumm::getObjY(int obj) { int Scumm::getObjY(int obj)
{
if (obj < NUM_ACTORS) { if (obj < NUM_ACTORS) {
if (obj < 1) if (obj < 1)
return 0; /* fix for indy4's map */ return 0; /* fix for indy4's map */
@ -939,7 +986,8 @@ int Scumm::getObjY(int obj) {
} }
} }
int Scumm::getObjOldDir(int obj) { int Scumm::getObjOldDir(int obj)
{
if (obj < NUM_ACTORS) { if (obj < NUM_ACTORS) {
return newDirToOldDir(derefActorSafe(obj, "getObjOldDir")->facing); return newDirToOldDir(derefActorSafe(obj, "getObjOldDir")->facing);
} else { } else {
@ -948,7 +996,8 @@ int Scumm::getObjOldDir(int obj) {
} }
} }
int Scumm::getObjNewDir(int obj) { int Scumm::getObjNewDir(int obj)
{
if (obj < NUM_ACTORS) { if (obj < NUM_ACTORS) {
return derefActorSafe(obj, "getObjNewDir")->facing; return derefActorSafe(obj, "getObjNewDir")->facing;
} else { } else {
@ -957,7 +1006,8 @@ int Scumm::getObjNewDir(int obj) {
} }
} }
int Scumm::findInventory(int owner, int idx) { int Scumm::findInventory(int owner, int idx)
{
int count = 1, i, obj; int count = 1, i, obj;
for (i = 0; i != _maxInventoryItems; i++) { for (i = 0; i != _maxInventoryItems; i++) {
obj = _inventory[i]; obj = _inventory[i];
@ -967,7 +1017,8 @@ int Scumm::findInventory(int owner, int idx) {
return 0; return 0;
} }
int Scumm::getInventoryCount(int owner) { int Scumm::getInventoryCount(int owner)
{
int i, obj; int i, obj;
int count = 0; int count = 0;
for (i = 0; i != _maxInventoryItems; i++) { for (i = 0; i != _maxInventoryItems; i++) {
@ -978,7 +1029,8 @@ int Scumm::getInventoryCount(int owner) {
return count; return count;
} }
void Scumm::setObjectState(int obj, int state, int x, int y) { void Scumm::setObjectState(int obj, int state, int x, int y)
{
int i; int i;
i = getObjectIndex(obj); i = getObjectIndex(obj);
@ -996,7 +1048,8 @@ void Scumm::setObjectState(int obj, int state, int x, int y) {
putState(obj, state); putState(obj, state);
} }
static int getDist(int x, int y, int x2, int y2) { static int getDist(int x, int y, int x2, int y2)
{
int a = abs(y - y2); int a = abs(y - y2);
int b = abs(x - x2); int b = abs(x - x2);
if (a > b) if (a > b)
@ -1004,7 +1057,9 @@ static int getDist(int x, int y, int x2, int y2) {
return b; return b;
} }
int Scumm::getDistanceBetween(bool is_obj_1, int b, int c, bool is_obj_2, int e, int f) { int Scumm::getDistanceBetween(bool is_obj_1, int b, int c, bool is_obj_2,
int e, int f)
{
int i, j; int i, j;
int x, y; int x, y;
int x2, y2; int x2, y2;
@ -1038,7 +1093,8 @@ int Scumm::getDistanceBetween(bool is_obj_1, int b, int c, bool is_obj_2, int e,
return getDist(x, y, x2, y2) * 0xFF / ((i + j) >> 1); return getDist(x, y, x2, y2) * 0xFF / ((i + j) >> 1);
} }
void Scumm::setCursorImg(uint img, uint room, uint imgindex) { void Scumm::setCursorImg(uint img, uint room, uint imgindex)
{
int w, h; int w, h;
byte *dataptr, *bomp; byte *dataptr, *bomp;
uint32 size; uint32 size;
@ -1047,15 +1103,14 @@ void Scumm::setCursorImg(uint img, uint room, uint imgindex) {
if (room == (uint) - 1) if (room == (uint) - 1)
room = getObjectRoom(img); room = getObjectRoom(img);
findObjectInRoom(&foir, foCodeHeader | foImageHeader | foCheckAlreadyLoaded, img, room); findObjectInRoom(&foir, foCodeHeader | foImageHeader | foCheckAlreadyLoaded,
img, room);
if (_features & GF_AFTER_V7) if (_features & GF_AFTER_V7)
setCursorHotspot2( setCursorHotspot2(READ_LE_UINT16(&foir.imhd->v7.hotspot[0].x),
READ_LE_UINT16(&foir.imhd->v7.hotspot[0].x),
READ_LE_UINT16(&foir.imhd->v7.hotspot[0].y)); READ_LE_UINT16(&foir.imhd->v7.hotspot[0].y));
else else
setCursorHotspot2( setCursorHotspot2(READ_LE_UINT16(&foir.imhd->old.hotspot[0].x),
READ_LE_UINT16(&foir.imhd->old.hotspot[0].x),
READ_LE_UINT16(&foir.imhd->old.hotspot[0].y)); READ_LE_UINT16(&foir.imhd->old.hotspot[0].y));
@ -1082,7 +1137,8 @@ void Scumm::setCursorImg(uint img, uint room, uint imgindex) {
} }
void Scumm::nukeFlObjects(int min, int max) { void Scumm::nukeFlObjects(int min, int max)
{
ObjectData *od; ObjectData *od;
int i; int i;
@ -1096,7 +1152,9 @@ void Scumm::nukeFlObjects(int min, int max) {
} }
} }
void Scumm::enqueueObject(int a, int b, int c, int d, int e, int f, int g, int h, int mode) { void Scumm::enqueueObject(int a, int b, int c, int d, int e, int f, int g,
int h, int mode)
{
EnqueuedObject *eo; EnqueuedObject *eo;
ObjectData *od; ObjectData *od;
@ -1129,7 +1187,8 @@ void Scumm::enqueueObject(int a, int b, int c, int d, int e, int f, int g, int h
eo->l = h; eo->l = h;
} }
void Scumm::drawEnqueuedObjects() { void Scumm::drawEnqueuedObjects()
{
EnqueuedObject *eo; EnqueuedObject *eo;
int i; int i;
@ -1140,7 +1199,8 @@ void Scumm::drawEnqueuedObjects() {
} }
void Scumm::drawEnqueuedObject(EnqueuedObject *eo) { void Scumm::drawEnqueuedObject(EnqueuedObject * eo)
{
VirtScreen *vs; VirtScreen *vs;
byte *roomptr, *bomp; byte *roomptr, *bomp;
byte *ptr; byte *ptr;
@ -1190,14 +1250,16 @@ void Scumm::drawEnqueuedObject(EnqueuedObject *eo) {
bdd.scale_x = (unsigned char)eo->j; bdd.scale_x = (unsigned char)eo->j;
bdd.scale_y = (unsigned char)eo->k; bdd.scale_y = (unsigned char)eo->k;
updateDirtyRect(vs->number, bdd.x, bdd.x+bdd.srcwidth, bdd.y, bdd.y+bdd.srcheight, 0); updateDirtyRect(vs->number, bdd.x, bdd.x + bdd.srcwidth, bdd.y,
bdd.y + bdd.srcheight, 0);
if (eo->a) { if (eo->a) {
drawBomp(&bdd); drawBomp(&bdd);
} }
} }
void Scumm::removeEnqueuedObjects() { void Scumm::removeEnqueuedObjects()
{
EnqueuedObject *eo; EnqueuedObject *eo;
int i; int i;
@ -1209,11 +1271,13 @@ void Scumm::removeEnqueuedObjects() {
clearEnqueue(); clearEnqueue();
} }
void Scumm::removeEnqueuedObject(EnqueuedObject *eo) { void Scumm::removeEnqueuedObject(EnqueuedObject * eo)
{
restoreBG(eo->x, eo->y, eo->x + eo->width, eo->y + eo->height); restoreBG(eo->x, eo->y, eo->x + eo->width, eo->y + eo->height);
} }
int Scumm::findFlObjectSlot() { int Scumm::findFlObjectSlot()
{
int i; int i;
for (i = 1; i < _maxFLObject; i++) { for (i = 1; i < _maxFLObject; i++) {
if (_baseFLObject[i] == NULL) if (_baseFLObject[i] == NULL)
@ -1222,7 +1286,8 @@ int Scumm::findFlObjectSlot() {
error("findFlObjectSlot: Out of FLObject slots"); error("findFlObjectSlot: Out of FLObject slots");
} }
void Scumm::loadFlObject(uint object, uint room) { void Scumm::loadFlObject(uint object, uint room)
{
FindObjectInRoom foir; FindObjectInRoom foir;
int slot; int slot;
ObjectData *od; ObjectData *od;

View file

@ -262,6 +262,19 @@ Windows example:
set SCUMMVM_SAVEPATH=C:\saved_games\ set SCUMMVM_SAVEPATH=C:\saved_games\
Coding style:
------------
For ScummVM coding, we use hugging braces, and two-space tab indents.
We occasionally run the following 'indent' parameters to ensure everything
is kept standard:
-br -bap -nbc -lp -ce -cdw -brs -nbad -nbc -npsl -nip -ts2 -ncs -nbs
-npcs -nbap -Tbyte -Tvoid -Tuint32 -Tuint8 -Tuint16 -Tint -Tint8
-Tint16 -Tint32 -TArrayHeader -TMemBlkHeader -TVerbSlot -TObjectData
-TImageHeader -TRoomHeader -TCodeHeader -TResHdr -TBompHeader
-TMidiChannelAdl -TGui -TScumm -TSoundEngine -TPart -TPlayer
------------------------------------------------------------------------ ------------------------------------------------------------------------
Good Luck and Happy Adventuring! Good Luck and Happy Adventuring!
The ScummVM team. The ScummVM team.

View file

@ -24,7 +24,8 @@
#include "scumm.h" #include "scumm.h"
/* Open a room */ /* Open a room */
void Scumm::openRoom(int room) { void Scumm::openRoom(int room)
{
int room_offs, roomlimit; int room_offs, roomlimit;
char buf[256]; char buf[256];
@ -49,7 +50,10 @@ void Scumm::openRoom(int room) {
#if REAL_CODE #if REAL_CODE
room_offs = _roomFileOffsets[room]; room_offs = _roomFileOffsets[room];
#else #else
if( _features & GF_SMALL_NAMES) roomlimit = 98; else roomlimit=900; if (_features & GF_SMALL_NAMES)
roomlimit = 98;
else
roomlimit = 900;
if (_features & GF_EXTERNAL_CHARSET && room >= roomlimit) if (_features & GF_EXTERNAL_CHARSET && room >= roomlimit)
room_offs = 0; room_offs = 0;
else else
@ -65,9 +69,11 @@ void Scumm::openRoom(int room) {
} }
if (!(_features & GF_SMALL_HEADER)) { if (!(_features & GF_SMALL_HEADER)) {
if (_features & GF_AFTER_V7) if (_features & GF_AFTER_V7)
sprintf(buf, "%s%s.la%d", _gameDataPath, _exe_name, room==0 ? 0 : res.roomno[rtRoom][room]); sprintf(buf, "%s%s.la%d", _gameDataPath, _exe_name,
room == 0 ? 0 : res.roomno[rtRoom][room]);
else else
sprintf(buf, "%s%s.%.3d", _gameDataPath, _exe_name, room==0 ? 0 : res.roomno[rtRoom][room]); sprintf(buf, "%s%s.%.3d", _gameDataPath, _exe_name,
room == 0 ? 0 : res.roomno[rtRoom][room]);
_encbyte = (_features & GF_USE_KEY) ? 0x69 : 0; _encbyte = (_features & GF_USE_KEY) ? 0x69 : 0;
} else if (!(_features & GF_SMALL_NAMES)) { } else if (!(_features & GF_SMALL_NAMES)) {
if (room == 0 || room >= 900) { if (room == 0 || room >= 900) {
@ -79,7 +85,8 @@ void Scumm::openRoom(int room) {
askForDisk(buf); askForDisk(buf);
} else { } else {
sprintf(buf, "%sdisk%.2d.lec",_gameDataPath,res.roomno[rtRoom][room]); sprintf(buf, "%sdisk%.2d.lec", _gameDataPath,
res.roomno[rtRoom][room]);
_encbyte = 0x69; _encbyte = 0x69;
} }
} else { } else {
@ -120,7 +127,8 @@ void Scumm::openRoom(int room) {
} }
/* Delete the currently loaded room offsets */ /* Delete the currently loaded room offsets */
void Scumm::deleteRoomOffsets() { void Scumm::deleteRoomOffsets()
{
if (!(_features & GF_SMALL_HEADER) && !_dynamicRoomOffsets) if (!(_features & GF_SMALL_HEADER) && !_dynamicRoomOffsets)
return; return;
@ -131,7 +139,8 @@ void Scumm::deleteRoomOffsets() {
} }
/* Read room offsets */ /* Read room offsets */
void Scumm::readRoomsOffsets() { void Scumm::readRoomsOffsets()
{
int num, room; int num, room;
debug(9, "readRoomOffsets()"); debug(9, "readRoomOffsets()");
@ -162,7 +171,8 @@ void Scumm::readRoomsOffsets() {
} }
} }
bool Scumm::openResourceFile(const char *filename) { bool Scumm::openResourceFile(const char *filename)
{
char buf[256]; char buf[256];
debug(9, "openResourceFile(%s)", filename); debug(9, "openResourceFile(%s)", filename);
@ -189,11 +199,13 @@ bool Scumm::openResourceFile(const char *filename) {
return _fileHandle != NULL; return _fileHandle != NULL;
} }
void Scumm::askForDisk(const char *filename) { void Scumm::askForDisk(const char *filename)
{
error("Cannot find '%s'", filename); error("Cannot find '%s'", filename);
} }
void Scumm::readIndexFile() { void Scumm::readIndexFile()
{
uint32 blocktype, itemsize; uint32 blocktype, itemsize;
int numblock = 0; int numblock = 0;
int num, i; int num, i;
@ -312,7 +324,8 @@ void Scumm::readIndexFile() {
break; break;
default: default:
error("Bad ID %c%c%c%c found in directory!", blocktype&0xFF, blocktype>>8, blocktype>>16, blocktype>>24); error("Bad ID %c%c%c%c found in directory!", blocktype & 0xFF,
blocktype >> 8, blocktype >> 16, blocktype >> 24);
return; return;
} }
} }
@ -323,7 +336,8 @@ void Scumm::readIndexFile() {
openRoom(-1); openRoom(-1);
} }
void Scumm::readArrayFromIndexFile() { void Scumm::readArrayFromIndexFile()
{
int num; int num;
int a, b, c; int a, b, c;
@ -338,7 +352,8 @@ void Scumm::readArrayFromIndexFile() {
} }
} }
void Scumm::readResTypeList(int id, uint32 tag, const char *name) { void Scumm::readResTypeList(int id, uint32 tag, const char *name)
{
int num; int num;
int i; int i;
@ -374,8 +389,11 @@ void Scumm::readResTypeList(int id, uint32 tag, const char *name) {
} }
void Scumm::allocResTypeData(int id, uint32 tag, int num, const char *name, int mode) { void Scumm::allocResTypeData(int id, uint32 tag, int num, const char *name,
debug(9, "allocResTypeData(%d,%x,%d,%s,%d)",id,FROM_LE_32(tag),num,name,mode); int mode)
{
debug(9, "allocResTypeData(%d,%x,%d,%s,%d)", id, FROM_LE_32(tag), num, name,
mode);
assert(id >= 0 && id < (int)(sizeof(res.mode) / sizeof(res.mode[0]))); assert(id >= 0 && id < (int)(sizeof(res.mode) / sizeof(res.mode[0])));
if (num >= 2000) { if (num >= 2000) {
@ -395,7 +413,8 @@ void Scumm::allocResTypeData(int id, uint32 tag, int num, const char *name, int
} }
} }
void Scumm::loadCharset(int no) { void Scumm::loadCharset(int no)
{
int i, line = 0; int i, line = 0;
byte *ptr; byte *ptr;
@ -415,12 +434,14 @@ void Scumm::loadCharset(int no) {
} }
} }
void Scumm::nukeCharset(int i) { void Scumm::nukeCharset(int i)
{
checkRange(_maxCharsets - 1, 1, i, "Nuking illegal charset %d"); checkRange(_maxCharsets - 1, 1, i, "Nuking illegal charset %d");
nukeResource(rtCharset, i); nukeResource(rtCharset, i);
} }
void Scumm::ensureResourceLoaded(int type, int i) { void Scumm::ensureResourceLoaded(int type, int i)
{
void *addr; void *addr;
debug(9, "ensureResourceLoaded(%d,%d)", type, i); debug(9, "ensureResourceLoaded(%d,%d)", type, i);
@ -443,7 +464,8 @@ void Scumm::ensureResourceLoaded(int type, int i) {
_vars[VAR_ROOM_FLAG] = 1; _vars[VAR_ROOM_FLAG] = 1;
} }
int Scumm::loadResource(int type, int idx) { int Scumm::loadResource(int type, int idx)
{
int roomNr, i; int roomNr, i;
uint32 fileOffs; uint32 fileOffs;
uint32 size, tag; uint32 size, tag;
@ -457,8 +479,7 @@ int Scumm::loadResource(int type, int idx) {
roomNr = getResourceRoomNr(type, idx); roomNr = getResourceRoomNr(type, idx);
if (roomNr == 0 || idx >= res.num[type]) { if (roomNr == 0 || idx >= res.num[type]) {
error("%s %d undefined", error("%s %d undefined", res.name[type], idx);
res.name[type],idx);
} }
if (type == rtRoom) { if (type == rtRoom) {
@ -518,7 +539,8 @@ int Scumm::loadResource(int type, int idx) {
} while (1); } while (1);
} }
int Scumm::readSoundResource(int type, int idx) { int Scumm::readSoundResource(int type, int idx)
{
uint32 pos, total_size, size, tag, basetag; uint32 pos, total_size, size, tag, basetag;
int pri, best_pri; int pri, best_pri;
uint32 best_size = 0, best_offs = 0; uint32 best_size = 0, best_offs = 0;
@ -533,7 +555,8 @@ int Scumm::readSoundResource(int type, int idx) {
if (_gameId == GID_SAMNMAX || _features & GF_AFTER_V7) { if (_gameId == GID_SAMNMAX || _features & GF_AFTER_V7) {
if (basetag == MKID('MIDI')) { if (basetag == MKID('MIDI')) {
fileSeek(_fileHandle, -8, SEEK_CUR); fileSeek(_fileHandle, -8, SEEK_CUR);
fileRead(_fileHandle,createResource(type, idx, total_size+8), total_size+8); fileRead(_fileHandle, createResource(type, idx, total_size + 8),
total_size + 8);
return 1; return 1;
} }
} else if (basetag == MKID('SOU ')) { } else if (basetag == MKID('SOU ')) {
@ -545,12 +568,19 @@ int Scumm::readSoundResource(int type, int idx) {
switch (tag) { switch (tag) {
#ifdef USE_ADLIB #ifdef USE_ADLIB
case MKID('ADL '): pri = 10; break; case MKID('ADL '):
pri = 10;
break;
#else #else
case MKID('ROL '): pri = 1; break; case MKID('ROL '):
case MKID('GMD '): pri = 2; break; pri = 1;
break;
case MKID('GMD '):
pri = 2;
break;
#endif #endif
default: pri = -1; default:
pri = -1;
} }
if (pri > best_pri) { if (pri > best_pri) {
@ -575,27 +605,26 @@ int Scumm::readSoundResource(int type, int idx) {
return 1; return 1;
} else { } else {
error("Unrecognized base tag %c%c%c%c in sound %d", error("Unrecognized base tag %c%c%c%c in sound %d",
basetag&0xff, basetag>>8, basetag>>16, basetag>>24, basetag & 0xff, basetag >> 8, basetag >> 16, basetag >> 24, idx);
idx);
} }
res.roomoffs[type][idx] = 0xFFFFFFFF; res.roomoffs[type][idx] = 0xFFFFFFFF;
return 0; return 0;
} }
int Scumm::getResourceRoomNr(int type, int idx) { int Scumm::getResourceRoomNr(int type, int idx)
{
if (type == rtRoom) if (type == rtRoom)
return idx; return idx;
return res.roomno[type][idx]; return res.roomno[type][idx];
} }
byte *Scumm::getResourceAddress(int type, int idx) { byte *Scumm::getResourceAddress(int type, int idx)
{
byte *ptr; byte *ptr;
debug(9, "getResourceAddress(%d,%d)", type, idx); debug(9, "getResourceAddress(%d,%d)", type, idx);
CHECK_HEAP CHECK_HEAP validateResource("getResourceAddress", type, idx);
validateResource("getResourceAddress", type, idx);
if (!res.address[type]) if (!res.address[type])
return NULL; return NULL;
@ -612,7 +641,8 @@ byte *Scumm::getResourceAddress(int type, int idx) {
return ptr + sizeof(MemBlkHeader); return ptr + sizeof(MemBlkHeader);
} }
byte *Scumm::getStringAddress(int i) { byte *Scumm::getStringAddress(int i)
{
byte *b = getResourceAddress(rtString, i); byte *b = getResourceAddress(rtString, i);
if (!b) if (!b)
return b; return b;
@ -622,7 +652,8 @@ byte *Scumm::getStringAddress(int i) {
return b; return b;
} }
void Scumm::setResourceCounter(int type, int idx, byte flag) { void Scumm::setResourceCounter(int type, int idx, byte flag)
{
res.flags[type][idx] &= ~RF_USAGE; res.flags[type][idx] &= ~RF_USAGE;
res.flags[type][idx] |= flag; res.flags[type][idx] |= flag;
} }
@ -630,12 +661,11 @@ void Scumm::setResourceCounter(int type, int idx, byte flag) {
/* 2 bytes safety area to make "precaching" of bytes in the gdi drawer easier */ /* 2 bytes safety area to make "precaching" of bytes in the gdi drawer easier */
#define SAFETY_AREA 2 #define SAFETY_AREA 2
byte *Scumm::createResource(int type, int idx, uint32 size) { byte *Scumm::createResource(int type, int idx, uint32 size)
{
byte *ptr; byte *ptr;
CHECK_HEAP CHECK_HEAP debug(9, "createResource(%d,%d,%d)", type, idx, size);
debug(9, "createResource(%d,%d,%d)", type, idx,size);
if (size > 65536 * 4 + 37856) if (size > 65536 * 4 + 37856)
warning("Probably invalid size allocating %d", size); warning("Probably invalid size allocating %d", size);
@ -645,9 +675,7 @@ byte *Scumm::createResource(int type, int idx, uint32 size) {
expireResources(size); expireResources(size);
CHECK_HEAP CHECK_HEAP ptr = (byte *)alloc(size + sizeof(MemBlkHeader) + SAFETY_AREA);
ptr = (byte*)alloc(size + sizeof(MemBlkHeader) + SAFETY_AREA);
if (ptr == NULL) { if (ptr == NULL) {
error("Out of memory while allocating %d", size); error("Out of memory while allocating %d", size);
} }
@ -660,19 +688,20 @@ byte *Scumm::createResource(int type, int idx, uint32 size) {
return ptr + sizeof(MemBlkHeader); /* skip header */ return ptr + sizeof(MemBlkHeader); /* skip header */
} }
void Scumm::validateResource(const char *str, int type, int idx) { void Scumm::validateResource(const char *str, int type, int idx)
{
if (type < rtFirst || type > rtLast || (uint) idx >= (uint) res.num[type]) { if (type < rtFirst || type > rtLast || (uint) idx >= (uint) res.num[type]) {
warning("%s Illegal Glob type %d num %d", str, type, idx); warning("%s Illegal Glob type %d num %d", str, type, idx);
} }
} }
void Scumm::nukeResource(int type, int idx) { void Scumm::nukeResource(int type, int idx)
{
byte *ptr; byte *ptr;
debug(9, "nukeResource(%d,%d)", type, idx); debug(9, "nukeResource(%d,%d)", type, idx);
CHECK_HEAP CHECK_HEAP if (!res.address[type])
if (!res.address[type])
return; return;
assert(idx >= 0 && idx < res.num[type]); assert(idx >= 0 && idx < res.num[type]);
@ -685,7 +714,8 @@ void Scumm::nukeResource(int type, int idx) {
} }
} }
byte *Scumm::findResourceData(uint32 tag, byte *ptr) { byte *Scumm::findResourceData(uint32 tag, byte *ptr)
{
if (_features & GF_SMALL_HEADER) { if (_features & GF_SMALL_HEADER) {
ptr = findResourceSmall(tag, ptr, 0); ptr = findResourceSmall(tag, ptr, 0);
if (ptr == NULL) if (ptr == NULL)
@ -699,7 +729,8 @@ byte *Scumm::findResourceData(uint32 tag, byte *ptr) {
return ptr + 8; return ptr + 8;
} }
int Scumm::getResourceDataSize(byte *ptr) { int Scumm::getResourceDataSize(byte *ptr)
{
if (ptr == NULL) if (ptr == NULL)
return 0; return 0;
@ -715,7 +746,8 @@ struct FindResourceState {
}; };
/* just O(N) complexity when iterating with this function */ /* just O(N) complexity when iterating with this function */
byte *findResource(uint32 tag, byte *searchin) { byte *findResource(uint32 tag, byte *searchin)
{
uint32 size; uint32 size;
static FindResourceState frs; static FindResourceState frs;
FindResourceState *f = &frs; /* easier to make it thread safe like this */ FindResourceState *f = &frs; /* easier to make it thread safe like this */
@ -743,7 +775,8 @@ StartScan:
return f->ptr; return f->ptr;
} }
byte *findResourceSmall(uint32 tag, byte *searchin) { byte *findResourceSmall(uint32 tag, byte *searchin)
{
uint32 size; uint32 size;
static FindResourceState frs; static FindResourceState frs;
FindResourceState *f = &frs; /* easier to make it thread safe like this */ FindResourceState *f = &frs; /* easier to make it thread safe like this */
@ -774,7 +807,8 @@ StartScan:
return f->ptr; return f->ptr;
} }
byte *findResource(uint32 tag, byte *searchin, int idx) { byte *findResource(uint32 tag, byte *searchin, int idx)
{
uint32 curpos, totalsize, size; uint32 curpos, totalsize, size;
assert(searchin); assert(searchin);
@ -791,9 +825,8 @@ byte *findResource(uint32 tag, byte *searchin, int idx) {
size = READ_BE_UINT32_UNALIGNED(searchin + 4); size = READ_BE_UINT32_UNALIGNED(searchin + 4);
if ((int32) size <= 0) { if ((int32) size <= 0) {
error("(%c%c%c%c) Not found in %d... illegal block len %d", error("(%c%c%c%c) Not found in %d... illegal block len %d",
tag&0xFF,(tag>>8)&0xFF,(tag>>16)&0xFF,(tag>>24)&0xFF, tag & 0xFF, (tag >> 8) & 0xFF, (tag >> 16) & 0xFF,
0, (tag >> 24) & 0xFF, 0, size);
size);
return NULL; return NULL;
} }
@ -804,7 +837,8 @@ byte *findResource(uint32 tag, byte *searchin, int idx) {
return NULL; return NULL;
} }
byte *findResourceSmall(uint32 tag, byte *searchin, int idx) { byte *findResourceSmall(uint32 tag, byte *searchin, int idx)
{
uint32 curpos, totalsize, size; uint32 curpos, totalsize, size;
uint16 smallTag; uint16 smallTag;
@ -824,8 +858,8 @@ byte *findResourceSmall(uint32 tag, byte *searchin, int idx) {
if ((int32) size <= 0) { if ((int32) size <= 0) {
error("(%c%c%c%c) Not found in %d... illegal block len %d", error("(%c%c%c%c) Not found in %d... illegal block len %d",
tag&0xFF,(tag>>8)&0xFF,(tag>>16)&0xFF,(tag>>24)&0xFF, tag & 0xFF, (tag >> 8) & 0xFF, (tag >> 16) & 0xFF,
0, size); (tag >> 24) & 0xFF, 0, size);
return NULL; return NULL;
} }
@ -836,21 +870,24 @@ byte *findResourceSmall(uint32 tag, byte *searchin, int idx) {
return NULL; return NULL;
} }
void Scumm::lock(int type, int i) { void Scumm::lock(int type, int i)
{
validateResource("Locking", type, i); validateResource("Locking", type, i);
res.flags[type][i] |= RF_LOCK; res.flags[type][i] |= RF_LOCK;
// debug(1, "locking %d,%d", type, i); // debug(1, "locking %d,%d", type, i);
} }
void Scumm::unlock(int type, int i) { void Scumm::unlock(int type, int i)
{
validateResource("Unlocking", type, i); validateResource("Unlocking", type, i);
res.flags[type][i] &= ~RF_LOCK; res.flags[type][i] &= ~RF_LOCK;
// debug(1, "unlocking %d,%d", type, i); // debug(1, "unlocking %d,%d", type, i);
} }
bool Scumm::isResourceInUse(int type, int i) { bool Scumm::isResourceInUse(int type, int i)
{
validateResource("isResourceInUse", type, i); validateResource("isResourceInUse", type, i);
switch (type) { switch (type) {
case rtRoom: case rtRoom:
@ -866,7 +903,8 @@ bool Scumm::isResourceInUse(int type, int i) {
} }
} }
void Scumm::increaseResourceCounter() { void Scumm::increaseResourceCounter()
{
int i, j; int i, j;
byte counter; byte counter;
@ -880,7 +918,8 @@ void Scumm::increaseResourceCounter() {
} }
} }
void Scumm::expireResources(uint32 size) { void Scumm::expireResources(uint32 size)
{
int i, j; int i, j;
byte flag; byte flag;
byte best_counter; byte best_counter;
@ -923,10 +962,12 @@ void Scumm::expireResources(uint32 size) {
increaseResourceCounter(); increaseResourceCounter();
debug(1, "Expired resources, mem %d -> %d", oldAllocatedSize, _allocatedSize); debug(1, "Expired resources, mem %d -> %d", oldAllocatedSize,
_allocatedSize);
} }
void Scumm::freeResources() { void Scumm::freeResources()
{
int i, j; int i, j;
for (i = rtFirst; i <= rtLast; i++) { for (i = rtFirst; i <= rtLast; i++) {
for (j = res.num[i]; --j >= 0;) { for (j = res.num[i]; --j >= 0;) {
@ -940,7 +981,8 @@ void Scumm::freeResources() {
} }
} }
void Scumm::loadPtrToResource(int type, int resindex, byte *source) { void Scumm::loadPtrToResource(int type, int resindex, byte *source)
{
byte *alloced; byte *alloced;
int i, len; int i, len;
@ -963,12 +1005,14 @@ void Scumm::loadPtrToResource(int type, int resindex, byte *source) {
} }
} }
bool Scumm::isResourceLoaded(int type, int idx) { bool Scumm::isResourceLoaded(int type, int idx)
{
validateResource("isLoaded", type, idx); validateResource("isLoaded", type, idx);
return res.address[type][idx] != NULL; return res.address[type][idx] != NULL;
} }
void Scumm::resourceStats() { void Scumm::resourceStats()
{
int i, j; int i, j;
uint32 lockedSize = 0, lockedNum = 0; uint32 lockedSize = 0, lockedNum = 0;
byte flag; byte flag;
@ -982,19 +1026,23 @@ void Scumm::resourceStats() {
} }
} }
printf("Total allocated size=%ld, locked=%ld(%ld)\n", _allocatedSize, lockedSize, lockedNum); printf("Total allocated size=%ld, locked=%ld(%ld)\n", _allocatedSize,
lockedSize, lockedNum);
} }
void Scumm::heapClear(int mode) { void Scumm::heapClear(int mode)
{
/* TODO: implement this */ /* TODO: implement this */
warning("heapClear: not implemented"); warning("heapClear: not implemented");
} }
void Scumm::unkHeapProc2(int a, int b) { void Scumm::unkHeapProc2(int a, int b)
{
warning("unkHeapProc2: not implemented"); warning("unkHeapProc2: not implemented");
} }
void Scumm::readMAXS() { void Scumm::readMAXS()
{
if (_features & GF_AFTER_V7) { if (_features & GF_AFTER_V7) {
fileSeek(_fileHandle, 50 + 50, SEEK_CUR); fileSeek(_fileHandle, 50 + 50, SEEK_CUR);
_numVariables = fileReadWordLE(); _numVariables = fileReadWordLE();
@ -1068,7 +1116,8 @@ void Scumm::readMAXS() {
_dynamicRoomOffsets = 1; _dynamicRoomOffsets = 1;
} }
void Scumm::allocateArrays() { void Scumm::allocateArrays()
{
// Note: Buffers are now allocated in scummMain to allow for // Note: Buffers are now allocated in scummMain to allow for
// early GUI init. // early GUI init.
@ -1085,8 +1134,8 @@ void Scumm::allocateArrays() {
_bitVars = (byte *)alloc(_numBitVariables >> 3); _bitVars = (byte *)alloc(_numBitVariables >> 3);
allocResTypeData(rtCostume, allocResTypeData(rtCostume,
(_features & GF_NEW_COSTUMES) ? MKID('AKOS') : MKID('COST'), (_features & GF_NEW_COSTUMES) ? MKID('AKOS') :
_numCostumes, "costume", 1); MKID('COST'), _numCostumes, "costume", 1);
allocResTypeData(rtRoom, MKID('ROOM'), _numRooms, "room", 1); allocResTypeData(rtRoom, MKID('ROOM'), _numRooms, "room", 1);
allocResTypeData(rtSound, MKID('SOUN'), _numSounds, "sound", 1); allocResTypeData(rtSound, MKID('SOUN'), _numSounds, "sound", 1);
@ -1103,7 +1152,8 @@ void Scumm::allocateArrays() {
allocResTypeData(rtMatrix, MKID('NONE'), 10, "boxes", 0); allocResTypeData(rtMatrix, MKID('NONE'), 10, "boxes", 0);
} }
uint16 newTag2Old(uint32 oldTag) { uint16 newTag2Old(uint32 oldTag)
{
switch (oldTag) { switch (oldTag) {
case (MKID('RMHD')): case (MKID('RMHD')):
return (0x4448); return (0x4448);
@ -1142,4 +1192,3 @@ uint16 newTag2Old(uint32 oldTag) {
return (0); return (0);
} }
} }

View file

@ -52,7 +52,8 @@ static uint32 _current_version = CURRENT_VER;
#endif #endif
bool Scumm::saveState(int slot, bool compat) { bool Scumm::saveState(int slot, bool compat)
{
char filename[256]; char filename[256];
SerializerStream out; SerializerStream out;
SaveGameHeader hdr; SaveGameHeader hdr;
@ -89,7 +90,8 @@ bool Scumm::saveState(int slot, bool compat) {
return true; return true;
} }
bool Scumm::loadState(int slot, bool compat) { bool Scumm::loadState(int slot, bool compat)
{
char filename[256]; char filename[256];
SerializerStream out; SerializerStream out;
int i, j; int i, j;
@ -107,7 +109,6 @@ bool Scumm::loadState(int slot, bool compat) {
out.fclose(); out.fclose();
return false; return false;
} }
#ifdef _MANAGE_OLD_SAVE #ifdef _MANAGE_OLD_SAVE
if (hdr.ver != VER_V8 && hdr.ver != VER_V7) { if (hdr.ver != VER_V8 && hdr.ver != VER_V7) {
@ -122,7 +123,6 @@ bool Scumm::loadState(int slot, bool compat) {
out.fclose(); out.fclose();
return false; return false;
} }
#ifdef _MANAGE_OLD_SAVE #ifdef _MANAGE_OLD_SAVE
_current_version = hdr.ver; _current_version = hdr.ver;
@ -133,9 +133,7 @@ bool Scumm::loadState(int slot, bool compat) {
pauseSounds(true); pauseSounds(true);
CHECK_HEAP CHECK_HEAP openRoom(-1);
openRoom(-1);
memset(_inventory, 0, sizeof(_inventory[0]) * _numInventory); memset(_inventory, 0, sizeof(_inventory[0]) * _numInventory);
/* Nuke all resources */ /* Nuke all resources */
@ -177,9 +175,7 @@ bool Scumm::loadState(int slot, bool compat) {
initBGBuffers(); initBGBuffers();
CHECK_HEAP CHECK_HEAP debug(1, "State loaded from '%s'", filename);
debug(1,"State loaded from '%s'", filename);
pauseSounds(false); pauseSounds(false);
@ -187,13 +183,15 @@ bool Scumm::loadState(int slot, bool compat) {
return true; return true;
} }
void Scumm::makeSavegameName(char *out, int slot, bool compatible) { void Scumm::makeSavegameName(char *out, int slot, bool compatible)
{
#ifndef _WIN32_WCE #ifndef _WIN32_WCE
#if !defined(__APPLE__CW) #if !defined(__APPLE__CW)
const char *dir = getenv("SCUMMVM_SAVEPATH"); const char *dir = getenv("SCUMMVM_SAVEPATH");
if (dir==NULL) dir=""; if (dir == NULL)
dir = "";
#else #else
const char *dir = ""; const char *dir = "";
#endif #endif
@ -203,12 +201,14 @@ void Scumm::makeSavegameName(char *out, int slot, bool compatible) {
#else #else
sprintf(out, "%s%s.%c%.2d", _savegame_dir, _exe_name, compatible ? 'c': 's', slot); sprintf(out, "%s%s.%c%.2d", _savegame_dir, _exe_name,
compatible ? 'c' : 's', slot);
#endif #endif
} }
bool Scumm::getSavegameName(int slot, char *desc) { bool Scumm::getSavegameName(int slot, char *desc)
{
char filename[256]; char filename[256];
SerializerStream out; SerializerStream out;
SaveGameHeader hdr; SaveGameHeader hdr;
@ -226,7 +226,6 @@ bool Scumm::getSavegameName(int slot, char *desc) {
strcpy(desc, "Invalid savegame"); strcpy(desc, "Invalid savegame");
return false; return false;
} }
#ifdef _MANAGE_OLD_SAVE #ifdef _MANAGE_OLD_SAVE
if (hdr.ver != VER_V8 && hdr.ver != VER_V7) { if (hdr.ver != VER_V8 && hdr.ver != VER_V7) {
@ -252,7 +251,8 @@ bool Scumm::getSavegameName(int slot, char *desc) {
#define MKARRAY(type,item,saveas,num) {OFFS(type,item),128|saveas,SIZE(type,item)}, {num,0,0} #define MKARRAY(type,item,saveas,num) {OFFS(type,item),128|saveas,SIZE(type,item)}, {num,0,0}
#define MKEND() {0xFFFF,0xFF,0xFF} #define MKEND() {0xFFFF,0xFF,0xFF}
void Scumm::saveOrLoad(Serializer *s) { void Scumm::saveOrLoad(Serializer * s)
{
const SaveLoadEntry objectEntries[] = { const SaveLoadEntry objectEntries[] = {
MKLINE(ObjectData, offs_obim_to_room, sleUint32), MKLINE(ObjectData, offs_obim_to_room, sleUint32),
MKLINE(ObjectData, offs_obcd_to_room, sleUint32), MKLINE(ObjectData, offs_obcd_to_room, sleUint32),
@ -659,7 +659,9 @@ void Scumm::saveOrLoad(Serializer *s) {
#ifdef _MANAGE_OLD_SAVE #ifdef _MANAGE_OLD_SAVE
s->saveLoadEntries(this, mainEntries1); s->saveLoadEntries(this, mainEntries1);
s->saveLoadEntries(this, (_current_version == VER_V8 ? mainEntries2V8 : mainEntries2V7)); s->saveLoadEntries(this,
(_current_version ==
VER_V8 ? mainEntries2V8 : mainEntries2V7));
s->saveLoadEntries(this, mainEntries3); s->saveLoadEntries(this, mainEntries3);
#else #else
@ -672,7 +674,8 @@ void Scumm::saveOrLoad(Serializer *s) {
// Probably not necessary anymore with latest NUM_ACTORS values // Probably not necessary anymore with latest NUM_ACTORS values
s->saveLoadArrayOf(actor, (_current_version == VER_V8 ? NUM_ACTORS : 13), sizeof(actor[0]), actorEntries); s->saveLoadArrayOf(actor, (_current_version == VER_V8 ? NUM_ACTORS : 13),
sizeof(actor[0]), actorEntries);
#else #else
@ -680,28 +683,35 @@ void Scumm::saveOrLoad(Serializer *s) {
#endif #endif
s->saveLoadArrayOf(vm.slot, NUM_SCRIPT_SLOT, sizeof(vm.slot[0]), scriptSlotEntries); s->saveLoadArrayOf(vm.slot, NUM_SCRIPT_SLOT, sizeof(vm.slot[0]),
s->saveLoadArrayOf(_objs, _numLocalObjects, sizeof(_objs[0]), objectEntries); scriptSlotEntries);
s->saveLoadArrayOf(_objs, _numLocalObjects, sizeof(_objs[0]),
objectEntries);
s->saveLoadArrayOf(_verbs, _numVerbs, sizeof(_verbs[0]), verbEntries); s->saveLoadArrayOf(_verbs, _numVerbs, sizeof(_verbs[0]), verbEntries);
s->saveLoadArrayOf(vm.nest, 16, sizeof(vm.nest[0]), nestedScriptEntries); s->saveLoadArrayOf(vm.nest, 16, sizeof(vm.nest[0]), nestedScriptEntries);
s->saveLoadArrayOf(sentence, 6, sizeof(sentence[0]), sentenceTabEntries); s->saveLoadArrayOf(sentence, 6, sizeof(sentence[0]), sentenceTabEntries);
s->saveLoadArrayOf(string, 6, sizeof(string[0]), stringTabEntries); s->saveLoadArrayOf(string, 6, sizeof(string[0]), stringTabEntries);
s->saveLoadArrayOf(_colorCycle, 16, sizeof(_colorCycle[0]), colorCycleEntries); s->saveLoadArrayOf(_colorCycle, 16, sizeof(_colorCycle[0]),
colorCycleEntries);
for (i = rtFirst; i <= rtLast; i++) for (i = rtFirst; i <= rtLast; i++)
if (res.mode[i] == 0) if (res.mode[i] == 0)
for (j = 1; j < res.num[i]; j++) for (j = 1; j < res.num[i]; j++)
saveLoadResource(s, i, j); saveLoadResource(s, i, j);
s->saveLoadArrayOf(_objectOwnerTable, _numGlobalObjects, sizeof(_objectOwnerTable[0]), sleByte); s->saveLoadArrayOf(_objectOwnerTable, _numGlobalObjects,
s->saveLoadArrayOf(_objectStateTable, _numGlobalObjects, sizeof(_objectStateTable[0]), sleByte); sizeof(_objectOwnerTable[0]), sleByte);
s->saveLoadArrayOf(_objectStateTable, _numGlobalObjects,
sizeof(_objectStateTable[0]), sleByte);
if (_objectRoomTable) if (_objectRoomTable)
s->saveLoadArrayOf(_objectRoomTable, _numGlobalObjects, sizeof(_objectRoomTable[0]), sleByte); s->saveLoadArrayOf(_objectRoomTable, _numGlobalObjects,
sizeof(_objectRoomTable[0]), sleByte);
if (_shadowPaletteSize) if (_shadowPaletteSize)
s->saveLoadArrayOf(_shadowPalette, _shadowPaletteSize, 1, sleByte); s->saveLoadArrayOf(_shadowPalette, _shadowPaletteSize, 1, sleByte);
s->saveLoadArrayOf(_classData, _numGlobalObjects, sizeof(_classData[0]), sleUint32); s->saveLoadArrayOf(_classData, _numGlobalObjects, sizeof(_classData[0]),
sleUint32);
var120Backup = _vars[120]; var120Backup = _vars[120];
var98Backup = _vars[98]; var98Backup = _vars[98];
@ -737,7 +747,8 @@ void Scumm::saveOrLoad(Serializer *s) {
} }
void Scumm::saveLoadResource(Serializer *ser, int type, int idx) { void Scumm::saveLoadResource(Serializer * ser, int type, int idx)
{
byte *ptr; byte *ptr;
uint32 size; uint32 size;
@ -772,7 +783,8 @@ void Scumm::saveLoadResource(Serializer *ser, int type, int idx) {
} }
} }
void Serializer::saveLoadBytes(void *b, int len) { void Serializer::saveLoadBytes(void *b, int len)
{
if (_saveOrLoad) if (_saveOrLoad)
_saveLoadStream.fwrite(b, 1, len); _saveLoadStream.fwrite(b, 1, len);
else else
@ -783,7 +795,8 @@ void Serializer::saveLoadBytes(void *b, int len) {
// Perhaps not necessary anymore with latest checks // Perhaps not necessary anymore with latest checks
bool Serializer::checkEOFLoadStream() { bool Serializer::checkEOFLoadStream()
{
if (!fseek(_saveLoadStream.out, 1, SEEK_CUR)) if (!fseek(_saveLoadStream.out, 1, SEEK_CUR))
return true; return true;
if (feof(_saveLoadStream.out)) if (feof(_saveLoadStream.out))
@ -795,39 +808,47 @@ bool Serializer::checkEOFLoadStream() {
#endif #endif
void Serializer::saveUint32(uint32 d) { void Serializer::saveUint32(uint32 d)
{
uint32 e = FROM_LE_32(d); uint32 e = FROM_LE_32(d);
saveLoadBytes(&e, 4); saveLoadBytes(&e, 4);
} }
void Serializer::saveWord(uint16 d) { void Serializer::saveWord(uint16 d)
{
uint16 e = FROM_LE_16(d); uint16 e = FROM_LE_16(d);
saveLoadBytes(&e, 2); saveLoadBytes(&e, 2);
} }
void Serializer::saveByte(byte b) { void Serializer::saveByte(byte b)
{
saveLoadBytes(&b, 1); saveLoadBytes(&b, 1);
} }
uint32 Serializer::loadUint32() { uint32 Serializer::loadUint32()
{
uint32 e; uint32 e;
saveLoadBytes(&e, 4); saveLoadBytes(&e, 4);
return FROM_LE_32(e); return FROM_LE_32(e);
} }
uint16 Serializer::loadWord() { uint16 Serializer::loadWord()
{
uint16 e; uint16 e;
saveLoadBytes(&e, 2); saveLoadBytes(&e, 2);
return FROM_LE_16(e); return FROM_LE_16(e);
} }
byte Serializer::loadByte() { byte Serializer::loadByte()
{
byte e; byte e;
saveLoadBytes(&e, 1); saveLoadBytes(&e, 1);
return e; return e;
} }
void Serializer::saveLoadArrayOf(void *b, int len, int datasize, byte filetype) { void Serializer::saveLoadArrayOf(void *b, int len, int datasize,
byte filetype)
{
byte *at = (byte *)b; byte *at = (byte *)b;
uint32 data; uint32 data;
@ -853,22 +874,38 @@ void Serializer::saveLoadArrayOf(void *b, int len, int datasize, byte filetype)
error("saveLoadArrayOf: invalid size %d", datasize); error("saveLoadArrayOf: invalid size %d", datasize);
} }
switch (filetype) { switch (filetype) {
case sleByte: saveByte((byte)data); break; case sleByte:
saveByte((byte)data);
break;
case sleUint16: case sleUint16:
case sleInt16:saveWord((int16)data); break; case sleInt16:
saveWord((int16) data);
break;
case sleInt32: case sleInt32:
case sleUint32:saveUint32(data); break; case sleUint32:
saveUint32(data);
break;
default: default:
error("saveLoadArrayOf: invalid filetype %d", filetype); error("saveLoadArrayOf: invalid filetype %d", filetype);
} }
} else { } else {
/* loading */ /* loading */
switch (filetype) { switch (filetype) {
case sleByte: data = loadByte(); break; case sleByte:
case sleUint16: data = loadWord(); break; data = loadByte();
case sleInt16: data = (int16)loadWord(); break; break;
case sleUint32: data = loadUint32(); break; case sleUint16:
case sleInt32: data = (int32)loadUint32(); break; data = loadWord();
break;
case sleInt16:
data = (int16) loadWord();
break;
case sleUint32:
data = loadUint32();
break;
case sleInt32:
data = (int32) loadUint32();
break;
default: default:
error("saveLoadArrayOf: invalid filetype %d", filetype); error("saveLoadArrayOf: invalid filetype %d", filetype);
} }
@ -888,7 +925,9 @@ void Serializer::saveLoadArrayOf(void *b, int len, int datasize, byte filetype)
} }
} }
void Serializer::saveLoadArrayOf(void *b, int num, int datasize, const SaveLoadEntry *sle) { void Serializer::saveLoadArrayOf(void *b, int num, int datasize,
const SaveLoadEntry * sle)
{
byte *data = (byte *)b; byte *data = (byte *)b;
while (--num >= 0) { while (--num >= 0) {
@ -898,7 +937,8 @@ void Serializer::saveLoadArrayOf(void *b, int num, int datasize, const SaveLoadE
} }
void Serializer::saveLoadEntries(void *d, const SaveLoadEntry *sle) { void Serializer::saveLoadEntries(void *d, const SaveLoadEntry * sle)
{
int replen; int replen;
byte type; byte type;
byte *at; byte *at;

View file

@ -24,7 +24,8 @@
#include "scumm.h" #include "scumm.h"
/* Start executing script 'script' with parameters 'a' and 'b' */ /* Start executing script 'script' with parameters 'a' and 'b' */
void Scumm::runScript(int script, int a, int b, int16 *lvarptr) { void Scumm::runScript(int script, int a, int b, int16 * lvarptr)
{
byte *scriptPtr; byte *scriptPtr;
uint32 scriptOffs; uint32 scriptOffs;
byte scriptType; byte scriptType;
@ -65,7 +66,8 @@ void Scumm::runScript(int script, int a, int b, int16 *lvarptr) {
} }
/* Stop script 'script' */ /* Stop script 'script' */
void Scumm::stopScriptNr(int script) { void Scumm::stopScriptNr(int script)
{
ScriptSlot *ss; ScriptSlot *ss;
NestedScript *nest; NestedScript *nest;
int i, num; int i, num;
@ -95,7 +97,8 @@ void Scumm::stopScriptNr(int script) {
num = _numNestedScripts; num = _numNestedScripts;
do { do {
if (nest->number == script && (nest->where==WIO_GLOBAL || nest->where==WIO_LOCAL)) { if (nest->number == script
&& (nest->where == WIO_GLOBAL || nest->where == WIO_LOCAL)) {
nest->number = 0xFF; nest->number = 0xFF;
nest->slot = 0xFF; nest->slot = 0xFF;
nest->where = 0xFF; nest->where = 0xFF;
@ -104,7 +107,8 @@ void Scumm::stopScriptNr(int script) {
} }
/* Stop an object script 'script'*/ /* Stop an object script 'script'*/
void Scumm::stopObjectScript(int script) { void Scumm::stopObjectScript(int script)
{
ScriptSlot *ss; ScriptSlot *ss;
NestedScript *nest; NestedScript *nest;
int i, num; int i, num;
@ -116,7 +120,9 @@ void Scumm::stopObjectScript(int script) {
for (i = 1; i < NUM_SCRIPT_SLOT; i++, ss++) { for (i = 1; i < NUM_SCRIPT_SLOT; i++, ss++) {
if (script == ss->number && (ss->where == WIO_ROOM || if (script == ss->number && (ss->where == WIO_ROOM ||
ss->where==WIO_INVENTORY || ss->where==WIO_FLOBJECT) && ss->status!=0) { ss->where == WIO_INVENTORY
|| ss->where == WIO_FLOBJECT)
&& ss->status != 0) {
if (ss->cutsceneOverride) if (ss->cutsceneOverride)
error("Object %d stopped with active cutscene/override", script); error("Object %d stopped with active cutscene/override", script);
ss->number = 0; ss->number = 0;
@ -144,7 +150,8 @@ void Scumm::stopObjectScript(int script) {
} }
/* Return a free script slot */ /* Return a free script slot */
int Scumm::getScriptSlot() { int Scumm::getScriptSlot()
{
ScriptSlot *ss; ScriptSlot *ss;
int i; int i;
ss = &vm.slot[1]; ss = &vm.slot[1];
@ -157,7 +164,8 @@ int Scumm::getScriptSlot() {
} }
/* Run script 'script' nested - eg, within the parent script.*/ /* Run script 'script' nested - eg, within the parent script.*/
void Scumm::runScriptNested(int script) { void Scumm::runScriptNested(int script)
{
NestedScript *nest; NestedScript *nest;
ScriptSlot *slot; ScriptSlot *slot;
@ -201,7 +209,8 @@ void Scumm::runScriptNested(int script) {
_currentScript = 0xFF; _currentScript = 0xFF;
} }
void Scumm::updateScriptPtr() { void Scumm::updateScriptPtr()
{
if (_currentScript == 0xFF) if (_currentScript == 0xFF)
return; return;
@ -209,7 +218,8 @@ void Scumm::updateScriptPtr() {
} }
/* Get the code pointer to a script */ /* Get the code pointer to a script */
void Scumm::getScriptBaseAddress() { void Scumm::getScriptBaseAddress()
{
ScriptSlot *ss; ScriptSlot *ss;
int idx; int idx;
@ -237,7 +247,8 @@ void Scumm::getScriptBaseAddress() {
case WIO_FLOBJECT: /* flobject script */ case WIO_FLOBJECT: /* flobject script */
idx = getObjectIndex(ss->number); idx = getObjectIndex(ss->number);
_scriptOrgPointer = getResourceAddress(rtFlObject,_objs[idx].fl_object_index); _scriptOrgPointer =
getResourceAddress(rtFlObject, _objs[idx].fl_object_index);
_lastCodePtr = &_baseFLObject[ss->number]; _lastCodePtr = &_baseFLObject[ss->number];
break; break;
default: default:
@ -246,14 +257,16 @@ void Scumm::getScriptBaseAddress() {
} }
void Scumm::getScriptEntryPoint() { void Scumm::getScriptEntryPoint()
{
if (_currentScript == 0xFF) if (_currentScript == 0xFF)
return; return;
_scriptPointer = _scriptOrgPointer + vm.slot[_currentScript].offs; _scriptPointer = _scriptOrgPointer + vm.slot[_currentScript].offs;
} }
/* Execute a script - Read opcode, and execute it from the table */ /* Execute a script - Read opcode, and execute it from the table */
void Scumm::executeScript() { void Scumm::executeScript()
{
OpcodeProc op; OpcodeProc op;
while (_currentScript != 0xFF) { while (_currentScript != 0xFF) {
_opcode = fetchScriptByte(); _opcode = fetchScriptByte();
@ -263,10 +276,10 @@ void Scumm::executeScript() {
op = getOpcode(_opcode); op = getOpcode(_opcode);
(this->*op) (); (this->*op) ();
} }
CHECK_HEAP CHECK_HEAP}
}
byte Scumm::fetchScriptByte() { byte Scumm::fetchScriptByte()
{
if (*_lastCodePtr + sizeof(MemBlkHeader) != _scriptOrgPointer) { if (*_lastCodePtr + sizeof(MemBlkHeader) != _scriptOrgPointer) {
uint32 oldoffs = _scriptPointer - _scriptOrgPointer; uint32 oldoffs = _scriptPointer - _scriptOrgPointer;
getScriptBaseAddress(); getScriptBaseAddress();
@ -275,7 +288,8 @@ byte Scumm::fetchScriptByte() {
return *_scriptPointer++; return *_scriptPointer++;
} }
int Scumm::fetchScriptWord() { int Scumm::fetchScriptWord()
{
int a; int a;
if (*_lastCodePtr + sizeof(MemBlkHeader) != _scriptOrgPointer) { if (*_lastCodePtr + sizeof(MemBlkHeader) != _scriptOrgPointer) {
uint32 oldoffs = _scriptPointer - _scriptOrgPointer; uint32 oldoffs = _scriptPointer - _scriptOrgPointer;
@ -291,7 +305,8 @@ int Scumm::fetchScriptWord() {
#define BYPASS_COPY_PROT #define BYPASS_COPY_PROT
#endif #endif
int Scumm::readVar(uint var) { int Scumm::readVar(uint var)
{
int a; int a;
#ifdef BYPASS_COPY_PROT #ifdef BYPASS_COPY_PROT
static byte copyprotbypassed; static byte copyprotbypassed;
@ -321,7 +336,8 @@ int Scumm::readVar(uint var) {
if (var & 0x8000) { if (var & 0x8000) {
var &= 0x7FFF; var &= 0x7FFF;
checkRange(_numBitVariables-1, 0, var, "Bit variable %d out of range(r)"); checkRange(_numBitVariables - 1, 0, var,
"Bit variable %d out of range(r)");
return (_bitVars[var >> 3] & (1 << (var & 7))) ? 1 : 0; return (_bitVars[var >> 3] & (1 << (var & 7))) ? 1 : 0;
} }
@ -334,19 +350,22 @@ int Scumm::readVar(uint var) {
error("Illegal varbits (r)"); error("Illegal varbits (r)");
} }
void Scumm::writeVar(uint var, int value) { void Scumm::writeVar(uint var, int value)
{
if (!(var & 0xF000)) { if (!(var & 0xF000)) {
checkRange(_numVariables - 1, 0, var, "Variable %d out of range(w)"); checkRange(_numVariables - 1, 0, var, "Variable %d out of range(w)");
_vars[var] = value; _vars[var] = value;
if ((_varwatch == (int)var) || (_varwatch == 0)) if ((_varwatch == (int)var) || (_varwatch == 0))
printf("vars[%d] = %d (via script %d)\n", var, value, vm.slot[_currentScript].number); printf("vars[%d] = %d (via script %d)\n", var, value,
vm.slot[_currentScript].number);
return; return;
} }
if (var & 0x8000) { if (var & 0x8000) {
var &= 0x7FFF; var &= 0x7FFF;
checkRange(_numBitVariables-1, 0, var, "Bit variable %d out of range(w)"); checkRange(_numBitVariables - 1, 0, var,
"Bit variable %d out of range(w)");
if (value) if (value)
_bitVars[var >> 3] |= (1 << (var & 7)); _bitVars[var >> 3] |= (1 << (var & 7));
else else
@ -364,7 +383,8 @@ void Scumm::writeVar(uint var, int value) {
error("Illegal varbits (w)"); error("Illegal varbits (w)");
} }
void Scumm::getResultPos() { void Scumm::getResultPos()
{
int a; int a;
_resultVarNumber = fetchScriptWord(); _resultVarNumber = fetchScriptWord();
@ -379,11 +399,13 @@ void Scumm::getResultPos() {
} }
} }
void Scumm::setResult(int value) { void Scumm::setResult(int value)
{
writeVar(_resultVarNumber, value); writeVar(_resultVarNumber, value);
} }
void Scumm::drawBox(int x, int y, int x2, int y2, int color) { void Scumm::drawBox(int x, int y, int x2, int y2, int color)
{
int top, bottom, count; int top, bottom, count;
VirtScreen *vs; VirtScreen *vs;
byte *backbuff, *bgbuff; byte *backbuff, *bgbuff;
@ -403,12 +425,18 @@ void Scumm::drawBox(int x, int y, int x2, int y2, int color) {
x2++; x2++;
y2++; y2++;
if (x>319) return; if (x > 319)
if (x<0) x=0; return;
if (y<0) y=0; if (x < 0)
if (x2<0) return; x = 0;
if (x2>320) x2=320; if (y < 0)
if (y2 > bottom) y2=bottom; y = 0;
if (x2 < 0)
return;
if (x2 > 320)
x2 = 320;
if (y2 > bottom)
y2 = bottom;
updateDirtyRect(vs->number, x, x2, y - top, y2 - top, 0); updateDirtyRect(vs->number, x, x2, y - top, y2 - top, 0);
@ -417,7 +445,9 @@ void Scumm::drawBox(int x, int y, int x2, int y2, int color) {
if (color == -1) { if (color == -1) {
if (vs->number != 0) if (vs->number != 0)
error("can only copy bg to main window"); error("can only copy bg to main window");
bgbuff = getResourceAddress(rtBuffer, vs->number+5) + vs->xstart + (y-top)*320 + x; bgbuff =
getResourceAddress(rtBuffer,
vs->number + 5) + vs->xstart + (y - top) * 320 + x;
blit(backbuff, bgbuff, x2 - x, y2 - y); blit(backbuff, bgbuff, x2 - x, y2 - y);
} else { } else {
count = y2 - y; count = y2 - y;
@ -430,7 +460,8 @@ void Scumm::drawBox(int x, int y, int x2, int y2, int color) {
} }
void Scumm::stopObjectCode() { void Scumm::stopObjectCode()
{
ScriptSlot *ss; ScriptSlot *ss;
ss = &vm.slot[_currentScript]; ss = &vm.slot[_currentScript];
@ -446,7 +477,8 @@ void Scumm::stopObjectCode() {
} }
} else { } else {
if (ss->cutsceneOverride) { if (ss->cutsceneOverride) {
warning("Script %d ending with active cutscene/override (%d)", ss->number, ss->cutsceneOverride); warning("Script %d ending with active cutscene/override (%d)",
ss->number, ss->cutsceneOverride);
ss->cutsceneOverride = 0; ss->cutsceneOverride = 0;
} }
} }
@ -455,7 +487,8 @@ void Scumm::stopObjectCode() {
_currentScript = 0xFF; _currentScript = 0xFF;
} }
bool Scumm::isScriptInUse(int script) { bool Scumm::isScriptInUse(int script)
{
ScriptSlot *ss; ScriptSlot *ss;
int i; int i;
@ -468,7 +501,8 @@ bool Scumm::isScriptInUse(int script) {
} }
void Scumm::runHook(int i) { void Scumm::runHook(int i)
{
int16 tmp[16]; int16 tmp[16];
tmp[0] = i; tmp[0] = i;
if (_vars[VAR_HOOK_SCRIPT]) { if (_vars[VAR_HOOK_SCRIPT]) {
@ -476,11 +510,13 @@ void Scumm::runHook(int i) {
} }
} }
void Scumm::freezeScripts(int flag) { void Scumm::freezeScripts(int flag)
{
int i; int i;
for (i = 1; i < NUM_SCRIPT_SLOT; i++) { for (i = 1; i < NUM_SCRIPT_SLOT; i++) {
if (_currentScript!=i && vm.slot[i].status!=ssDead && (vm.slot[i].unk1==0 || flag>=0x80)) { if (_currentScript != i && vm.slot[i].status != ssDead
&& (vm.slot[i].unk1 == 0 || flag >= 0x80)) {
vm.slot[i].status |= 0x80; vm.slot[i].status |= 0x80;
vm.slot[i].freezeCount++; vm.slot[i].freezeCount++;
} }
@ -495,7 +531,8 @@ void Scumm::freezeScripts(int flag) {
} }
} }
void Scumm::unfreezeScripts() { void Scumm::unfreezeScripts()
{
int i; int i;
for (i = 1; i < NUM_SCRIPT_SLOT; i++) { for (i = 1; i < NUM_SCRIPT_SLOT; i++) {
if (vm.slot[i].status & 0x80) { if (vm.slot[i].status & 0x80) {
@ -511,7 +548,8 @@ void Scumm::unfreezeScripts() {
} }
} }
void Scumm::runAllScripts() { void Scumm::runAllScripts()
{
int i; int i;
for (i = 0; i < NUM_SCRIPT_SLOT; i++) for (i = 0; i < NUM_SCRIPT_SLOT; i++)
@ -529,7 +567,8 @@ void Scumm::runAllScripts() {
} }
} }
void Scumm::runExitScript() { void Scumm::runExitScript()
{
if (_vars[VAR_EXIT_SCRIPT]) if (_vars[VAR_EXIT_SCRIPT])
runScript(_vars[VAR_EXIT_SCRIPT], 0, 0, 0); runScript(_vars[VAR_EXIT_SCRIPT], 0, 0, 0);
if (_EXCD_offs) { if (_EXCD_offs) {
@ -547,7 +586,8 @@ void Scumm::runExitScript() {
runScript(_vars[VAR_EXIT_SCRIPT2], 0, 0, 0); runScript(_vars[VAR_EXIT_SCRIPT2], 0, 0, 0);
} }
void Scumm::runEntryScript() { void Scumm::runEntryScript()
{
if (_vars[VAR_ENTRY_SCRIPT]) if (_vars[VAR_ENTRY_SCRIPT])
runScript(_vars[VAR_ENTRY_SCRIPT], 0, 0, 0); runScript(_vars[VAR_ENTRY_SCRIPT], 0, 0, 0);
if (_ENCD_offs) { if (_ENCD_offs) {
@ -565,7 +605,8 @@ void Scumm::runEntryScript() {
runScript(_vars[VAR_ENTRY_SCRIPT2], 0, 0, 0); runScript(_vars[VAR_ENTRY_SCRIPT2], 0, 0, 0);
} }
void Scumm::killScriptsAndResources() { void Scumm::killScriptsAndResources()
{
ScriptSlot *ss; ScriptSlot *ss;
int i; int i;
@ -574,11 +615,13 @@ void Scumm::killScriptsAndResources() {
for (i = 1; i < NUM_SCRIPT_SLOT; i++, ss++) { for (i = 1; i < NUM_SCRIPT_SLOT; i++, ss++) {
if (ss->where == WIO_ROOM || ss->where == WIO_FLOBJECT) { if (ss->where == WIO_ROOM || ss->where == WIO_FLOBJECT) {
if (ss->cutsceneOverride) if (ss->cutsceneOverride)
error("Object %d stopped with active cutscene/override in exit", ss->number); error("Object %d stopped with active cutscene/override in exit",
ss->number);
ss->status = 0; ss->status = 0;
} else if (ss->where == WIO_LOCAL) { } else if (ss->where == WIO_LOCAL) {
if (ss->cutsceneOverride) if (ss->cutsceneOverride)
error("Script %d stopped with active cutscene/override in exit", ss->number); error("Script %d stopped with active cutscene/override in exit",
ss->number);
ss->status = 0; ss->status = 0;
} }
} }
@ -602,7 +645,8 @@ void Scumm::killScriptsAndResources() {
} }
} }
void Scumm::checkAndRunVar33() { void Scumm::checkAndRunVar33()
{
int i; int i;
ScriptSlot *ss; ScriptSlot *ss;
@ -610,7 +654,8 @@ void Scumm::checkAndRunVar33() {
if (isScriptInUse(_vars[VAR_SENTENCE_SCRIPT])) { if (isScriptInUse(_vars[VAR_SENTENCE_SCRIPT])) {
ss = vm.slot; ss = vm.slot;
for (i = 0; i < NUM_SCRIPT_SLOT; i++, ss++) for (i = 0; i < NUM_SCRIPT_SLOT; i++, ss++)
if (ss->number==_vars[VAR_SENTENCE_SCRIPT] && ss->status!=0 && ss->freezeCount==0) if (ss->number == _vars[VAR_SENTENCE_SCRIPT] && ss->status != 0
&& ss->freezeCount == 0)
return; return;
} }
@ -632,7 +677,8 @@ void Scumm::checkAndRunVar33() {
runScript(_vars[VAR_SENTENCE_SCRIPT], 0, 0, _localParamList); runScript(_vars[VAR_SENTENCE_SCRIPT], 0, 0, _localParamList);
} }
void Scumm::runInputScript(int a, int cmd, int mode) { void Scumm::runInputScript(int a, int cmd, int mode)
{
int16 args[16]; int16 args[16];
memset(args, 0, sizeof(args)); memset(args, 0, sizeof(args));
args[0] = a; args[0] = a;
@ -642,7 +688,8 @@ void Scumm::runInputScript(int a, int cmd, int mode) {
runScript(_vars[VAR_VERB_SCRIPT], 0, 0, args); runScript(_vars[VAR_VERB_SCRIPT], 0, 0, args);
} }
void Scumm::decreaseScriptDelay(int amount) { void Scumm::decreaseScriptDelay(int amount)
{
ScriptSlot *ss = &vm.slot[0]; ScriptSlot *ss = &vm.slot[0];
int i; int i;
for (i = 0; i < NUM_SCRIPT_SLOT; i++, ss++) { for (i = 0; i < NUM_SCRIPT_SLOT; i++, ss++) {
@ -656,7 +703,8 @@ void Scumm::decreaseScriptDelay(int amount) {
} }
} }
void Scumm::runVerbCode(int object, int entry, int a, int b, int16 *vars) { void Scumm::runVerbCode(int object, int entry, int a, int b, int16 * vars)
{
uint32 obcd; uint32 obcd;
int slot, where, offs; int slot, where, offs;
@ -692,7 +740,8 @@ void Scumm::runVerbCode(int object, int entry, int a, int b, int16 *vars) {
runScriptNested(slot); runScriptNested(slot);
} }
void Scumm::initializeLocals(int slot, int16 *vars) { void Scumm::initializeLocals(int slot, int16 * vars)
{
int i; int i;
if (!vars) { if (!vars) {
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++)
@ -703,7 +752,8 @@ void Scumm::initializeLocals(int slot, int16 *vars) {
} }
} }
int Scumm::getVerbEntrypoint(int obj, int entry) { int Scumm::getVerbEntrypoint(int obj, int entry)
{
byte *objptr, *verbptr; byte *objptr, *verbptr;
int verboffs; int verboffs;
@ -741,18 +791,23 @@ int Scumm::getVerbEntrypoint(int obj, int entry) {
} }
void Scumm::push(int a) { void Scumm::push(int a)
assert(_scummStackPos >=0 && (unsigned int)_scummStackPos <= ARRAYSIZE(_scummStack)); {
assert(_scummStackPos >= 0
&& (unsigned int)_scummStackPos <= ARRAYSIZE(_scummStack));
_scummStack[_scummStackPos++] = a; _scummStack[_scummStackPos++] = a;
} }
int Scumm::pop() { int Scumm::pop()
assert(_scummStackPos >0 && (unsigned int)_scummStackPos <= ARRAYSIZE(_scummStack)); {
assert(_scummStackPos > 0
&& (unsigned int)_scummStackPos <= ARRAYSIZE(_scummStack));
return _scummStack[--_scummStackPos]; return _scummStack[--_scummStackPos];
} }
void Scumm::endCutscene() { void Scumm::endCutscene()
{
ScriptSlot *ss = &vm.slot[_currentScript]; ScriptSlot *ss = &vm.slot[_currentScript];
uint32 *csptr; uint32 *csptr;
int16 args[16]; int16 args[16];
@ -777,11 +832,13 @@ void Scumm::endCutscene() {
runScript(_vars[VAR_CUTSCENE_END_SCRIPT], 0, 0, args); runScript(_vars[VAR_CUTSCENE_END_SCRIPT], 0, 0, args);
} }
void Scumm::cutscene(int16 *args) { void Scumm::cutscene(int16 * args)
{
int scr = _currentScript; int scr = _currentScript;
vm.slot[scr].cutsceneOverride++; vm.slot[scr].cutsceneOverride++;
if (++vm.cutSceneStackPointer > sizeof(vm.cutSceneData)/sizeof(vm.cutSceneData[0])) if (++vm.cutSceneStackPointer >
sizeof(vm.cutSceneData) / sizeof(vm.cutSceneData[0]))
error("Cutscene stack overflow"); error("Cutscene stack overflow");
vm.cutSceneData[vm.cutSceneStackPointer] = args[0]; vm.cutSceneData[vm.cutSceneStackPointer] = args[0];
@ -794,7 +851,8 @@ void Scumm::cutscene(int16 *args) {
vm.cutSceneScriptIndex = 0xFF; vm.cutSceneScriptIndex = 0xFF;
} }
void Scumm::faceActorToObj(int act, int obj) { void Scumm::faceActorToObj(int act, int obj)
{
int x, dir; int x, dir;
if (getObjectOrActorXY(act) == -1) if (getObjectOrActorXY(act) == -1)
@ -809,7 +867,8 @@ void Scumm::faceActorToObj(int act, int obj) {
turnToDirection(derefActorSafe(act, "faceActorToObj"), dir); turnToDirection(derefActorSafe(act, "faceActorToObj"), dir);
} }
void Scumm::animateActor(int act, int anim) { void Scumm::animateActor(int act, int anim)
{
if (_features & GF_AFTER_V7) { if (_features & GF_AFTER_V7) {
int cmd, dir; int cmd, dir;
Actor *a; Actor *a;
@ -846,7 +905,8 @@ void Scumm::animateActor(int act, int anim) {
Actor *a; Actor *a;
a = derefActorSafe(act, "animateActor"); a = derefActorSafe(act, "animateActor");
if (!a) return; if (!a)
return;
dir = anim & 3; dir = anim & 3;
@ -869,7 +929,8 @@ void Scumm::animateActor(int act, int anim) {
} }
} }
bool Scumm::isScriptRunning(int script) { bool Scumm::isScriptRunning(int script)
{
int i; int i;
ScriptSlot *ss = vm.slot; ScriptSlot *ss = vm.slot;
for (i = 0; i < NUM_SCRIPT_SLOT; i++, ss++) for (i = 0; i < NUM_SCRIPT_SLOT; i++, ss++)
@ -879,7 +940,8 @@ bool Scumm::isScriptRunning(int script) {
return false; return false;
} }
bool Scumm::isRoomScriptRunning(int script) { bool Scumm::isRoomScriptRunning(int script)
{
int i; int i;
ScriptSlot *ss = vm.slot; ScriptSlot *ss = vm.slot;
for (i = 0; i < NUM_SCRIPT_SLOT; i++, ss++) for (i = 0; i < NUM_SCRIPT_SLOT; i++, ss++)
@ -891,7 +953,8 @@ bool Scumm::isRoomScriptRunning(int script) {
void Scumm::beginOverride() { void Scumm::beginOverride()
{
int idx; int idx;
uint32 *ptr; uint32 *ptr;
@ -909,7 +972,8 @@ void Scumm::beginOverride() {
_vars[VAR_OVERRIDE] = 0; _vars[VAR_OVERRIDE] = 0;
} }
void Scumm::endOverride() { void Scumm::endOverride()
{
int idx; int idx;
uint32 *ptr; uint32 *ptr;
@ -925,7 +989,8 @@ void Scumm::endOverride() {
} }
int Scumm::defineArray(int array, int type, int dim2, int dim1) { int Scumm::defineArray(int array, int type, int dim2, int dim1)
{
int id; int id;
int size; int size;
ArrayHeader *ah; ArrayHeader *ah;
@ -952,7 +1017,8 @@ int Scumm::defineArray(int array, int type, int dim2, int dim1) {
size *= dim1 + 1; size *= dim1 + 1;
size >>= 3; size >>= 3;
ah = (ArrayHeader*)createResource(rtString, id, size+sizeof(ArrayHeader)); ah =
(ArrayHeader *)createResource(rtString, id, size + sizeof(ArrayHeader));
ah->type = type; ah->type = type;
ah->dim1_size = dim1 + 1; ah->dim1_size = dim1 + 1;
@ -961,7 +1027,8 @@ int Scumm::defineArray(int array, int type, int dim2, int dim1) {
return id; return id;
} }
void Scumm::nukeArray(int a) { void Scumm::nukeArray(int a)
{
int data; int data;
data = readVar(a); data = readVar(a);
@ -973,7 +1040,8 @@ void Scumm::nukeArray(int a) {
writeVar(a, 0); writeVar(a, 0);
} }
int Scumm::getArrayId() { int Scumm::getArrayId()
{
byte **addr = _baseArrays; byte **addr = _baseArrays;
int i; int i;
@ -984,7 +1052,8 @@ int Scumm::getArrayId() {
error("Out of array pointers, %d max", _numArray); error("Out of array pointers, %d max", _numArray);
} }
void Scumm::arrayop_1(int a, byte *ptr) { void Scumm::arrayop_1(int a, byte *ptr)
{
ArrayHeader *ah; ArrayHeader *ah;
int r; int r;
int len = getStringLen(ptr); int len = getStringLen(ptr);
@ -994,7 +1063,8 @@ void Scumm::arrayop_1(int a, byte *ptr) {
copyString(ah->data, ptr, len); copyString(ah->data, ptr, len);
} }
void Scumm::copyString(byte *dst, byte *src, int len) { void Scumm::copyString(byte *dst, byte *src, int len)
{
if (!src) { if (!src) {
while (--len >= 0) while (--len >= 0)
*dst++ = fetchScriptByte(); *dst++ = fetchScriptByte();
@ -1004,7 +1074,8 @@ void Scumm::copyString(byte *dst, byte *src, int len) {
} }
} }
int Scumm::getStringLen(byte *ptr) { int Scumm::getStringLen(byte *ptr)
{
int len; int len;
byte c; byte c;
if (!ptr) if (!ptr)
@ -1012,7 +1083,8 @@ int Scumm::getStringLen(byte *ptr) {
len = 0; len = 0;
do { do {
c = *ptr++; c = *ptr++;
if (!c) break; if (!c)
break;
len++; len++;
if (c == 0xFF) if (c == 0xFF)
ptr += 3, len += 3; ptr += 3, len += 3;
@ -1020,7 +1092,8 @@ int Scumm::getStringLen(byte *ptr) {
return len + 1; return len + 1;
} }
void Scumm::exitCutscene() { void Scumm::exitCutscene()
{
uint32 offs = vm.cutScenePtr[vm.cutSceneStackPointer]; uint32 offs = vm.cutScenePtr[vm.cutSceneStackPointer];
if (offs) { if (offs) {
ScriptSlot *ss = &vm.slot[vm.cutSceneScript[vm.cutSceneStackPointer]]; ScriptSlot *ss = &vm.slot[vm.cutSceneScript[vm.cutSceneStackPointer]];
@ -1035,7 +1108,8 @@ void Scumm::exitCutscene() {
vm.cutScenePtr[vm.cutSceneStackPointer] = 0; vm.cutScenePtr[vm.cutSceneStackPointer] = 0;
} }
} }
void Scumm::doSentence(int c, int b, int a) { void Scumm::doSentence(int c, int b, int a)
{
if (_features & GF_AFTER_V7) { if (_features & GF_AFTER_V7) {
SentenceTab *st; SentenceTab *st;
@ -1044,8 +1118,7 @@ void Scumm::doSentence(int c, int b, int a) {
st = &sentence[_sentenceNum - 1]; st = &sentence[_sentenceNum - 1];
if (_sentenceNum && if (_sentenceNum && st->unk5 == c && st->unk4 == b && st->unk3 == a)
st->unk5 == c && st->unk4==b && st->unk3==a)
return; return;
_sentenceNum++; _sentenceNum++;

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -26,24 +26,28 @@
#include "string.h" #include "string.h"
extern void launcherLoop(); extern void launcherLoop();
void Scumm::initRandSeeds() { void Scumm::initRandSeeds()
{
_randSeed1 = 0xA943DE35; _randSeed1 = 0xA943DE35;
_randSeed2 = 0x37A9ED27; _randSeed2 = 0x37A9ED27;
} }
uint Scumm::getRandomNumber(uint max) { uint Scumm::getRandomNumber(uint max)
{
/* TODO: my own random number generator */ /* TODO: my own random number generator */
_randSeed1 = 0xDEADBEEF * (_randSeed1 + 1); _randSeed1 = 0xDEADBEEF * (_randSeed1 + 1);
_randSeed1 = (_randSeed1 >> 13) | (_randSeed1 << 19); _randSeed1 = (_randSeed1 >> 13) | (_randSeed1 << 19);
return _randSeed1 % max; return _randSeed1 % max;
} }
uint Scumm::getRandomNumberRng(uint min, uint max) { uint Scumm::getRandomNumberRng(uint min, uint max)
{
return getRandomNumber(max - min + 1) + min; return getRandomNumber(max - min + 1) + min;
} }
void Scumm::scummInit() { void Scumm::scummInit()
{
int i; int i;
Actor *a; Actor *a;
@ -137,8 +141,7 @@ void Scumm::scummInit() {
clearDrawObjectQueue(); clearDrawObjectQueue();
for (i = 0; i < 6; i++) { for (i = 0; i < 6; i++) {
if(_features & GF_OLD256) if (_features & GF_OLD256) {
{
string[i].t_xpos = 0; string[i].t_xpos = 0;
string[i].t_ypos = 0; string[i].t_ypos = 0;
} else { } else {
@ -164,7 +167,8 @@ void Scumm::scummInit() {
} }
void Scumm::initScummVars() { void Scumm::initScummVars()
{
if (!(_features & GF_AFTER_V7)) { if (!(_features & GF_AFTER_V7)) {
_vars[VAR_CURRENTDRIVE] = _currentDrive; _vars[VAR_CURRENTDRIVE] = _currentDrive;
_vars[VAR_FIXEDDISK] = checkFixedDisk(); _vars[VAR_FIXEDDISK] = checkFixedDisk();
@ -180,13 +184,16 @@ void Scumm::initScummVars() {
} }
} }
void Scumm::checkRange(int max, int min, int no, const char *str) { void Scumm::checkRange(int max, int min, int no, const char *str)
{
if (no < min || no > max) { if (no < min || no > max) {
error("Value %d is out of bounds (%d,%d) int script(%d) msg %s", no, min,max, vm.slot[_curExecScript].number, str); error("Value %d is out of bounds (%d,%d) int script(%d) msg %s", no, min,
max, vm.slot[_curExecScript].number, str);
} }
} }
int Scumm::scummLoop(int delta) { int Scumm::scummLoop(int delta)
{
static int counter = 0; static int counter = 0;
#ifndef _WIN32_WCE #ifndef _WIN32_WCE
@ -210,7 +217,8 @@ int Scumm::scummLoop(int delta) {
decreaseScriptDelay(delta); decreaseScriptDelay(delta);
_talkDelay -= delta; _talkDelay -= delta;
if (_talkDelay<0) _talkDelay=0; if (_talkDelay < 0)
_talkDelay = 0;
processKbd(); processKbd();
@ -236,9 +244,7 @@ int Scumm::scummLoop(int delta) {
_vars[VAR_MI1_TIMER] += 6; _vars[VAR_MI1_TIMER] += 6;
} }
} }
} } else if (_features & GF_OLD256)
else
if(_features & GF_OLD256)
_vars[VAR_MUSIC_FLAG]++; // ENDERFIX _vars[VAR_MUSIC_FLAG]++; // ENDERFIX
if (_saveLoadFlag) { if (_saveLoadFlag) {
@ -287,7 +293,8 @@ int Scumm::scummLoop(int delta) {
redrawBGAreas(); redrawBGAreas();
} }
} else { } else {
if (camera._cur.x != camera._last.x || camera._cur.y != camera._last.y || _BgNeedsRedraw || _fullRedraw) { if (camera._cur.x != camera._last.x || camera._cur.y != camera._last.y
|| _BgNeedsRedraw || _fullRedraw) {
redrawBGAreas(); redrawBGAreas();
} }
} }
@ -336,13 +343,12 @@ int Scumm::scummLoop(int delta) {
} }
void Scumm::startScene(int room, Actor *a, int objectNr) { void Scumm::startScene(int room, Actor * a, int objectNr)
{
int i, where; int i, where;
Actor *at; Actor *at;
CHECK_HEAP CHECK_HEAP debug(1, "Loading room %d", room);
debug(1,"Loading room %d", room);
clearMsgQueue(); clearMsgQueue();
@ -353,11 +359,13 @@ void Scumm::startScene(int room, Actor *a, int objectNr) {
if (vm.slot[_currentScript].where == WIO_ROOM || if (vm.slot[_currentScript].where == WIO_ROOM ||
vm.slot[_currentScript].where == WIO_FLOBJECT) { vm.slot[_currentScript].where == WIO_FLOBJECT) {
if (vm.slot[_currentScript].cutsceneOverride != 0) if (vm.slot[_currentScript].cutsceneOverride != 0)
error("Object %d stopped with active cutscene/override in exit", vm.slot[_currentScript].number); error("Object %d stopped with active cutscene/override in exit",
vm.slot[_currentScript].number);
_currentScript = 0xFF; _currentScript = 0xFF;
} else if (vm.slot[_currentScript].where == WIO_LOCAL) { } else if (vm.slot[_currentScript].where == WIO_LOCAL) {
if (vm.slot[_currentScript].cutsceneOverride != 0) if (vm.slot[_currentScript].cutsceneOverride != 0)
error("Script %d stopped with active cutscene/override in exit", vm.slot[_currentScript].number); error("Script %d stopped with active cutscene/override in exit",
vm.slot[_currentScript].number);
_currentScript = 0xFF; _currentScript = 0xFF;
} }
} }
@ -440,7 +448,8 @@ void Scumm::startScene(int room, Actor *a, int objectNr) {
if (a) { if (a) {
where = whereIsObject(objectNr); where = whereIsObject(objectNr);
if (where != WIO_ROOM && where != WIO_FLOBJECT) if (where != WIO_ROOM && where != WIO_FLOBJECT)
error("startScene: Object %d is not in room %d", objectNr, _currentRoom); error("startScene: Object %d is not in room %d", objectNr,
_currentRoom);
getObjectXYPos(objectNr); getObjectXYPos(objectNr);
putActor(a, _xPos, _yPos, _currentRoom); putActor(a, _xPos, _yPos, _currentRoom);
fixActorDirection(a, _dir + 180); fixActorDirection(a, _dir + 180);
@ -467,10 +476,10 @@ void Scumm::startScene(int room, Actor *a, int objectNr) {
_doEffect = true; _doEffect = true;
CHECK_HEAP CHECK_HEAP}
}
void Scumm::initRoomSubBlocks() { void Scumm::initRoomSubBlocks()
{
int i, offs; int i, offs;
byte *ptr; byte *ptr;
byte *roomptr, *searchptr; byte *roomptr, *searchptr;
@ -503,7 +512,9 @@ void Scumm::initRoomSubBlocks() {
if (_features & GF_SMALL_HEADER) if (_features & GF_SMALL_HEADER)
_IM00_offs = findResourceData(MKID('IM00'), roomptr) - roomptr; _IM00_offs = findResourceData(MKID('IM00'), roomptr) - roomptr;
else else
_IM00_offs = findResource(MKID('IM00'), findResource(MKID('RMIM'), roomptr)) - roomptr; _IM00_offs =
findResource(MKID('IM00'),
findResource(MKID('RMIM'), roomptr)) - roomptr;
ptr = findResourceData(MKID('EXCD'), roomptr); ptr = findResourceData(MKID('EXCD'), roomptr);
if (ptr) { if (ptr) {
@ -665,7 +676,8 @@ void Scumm::initRoomSubBlocks() {
memset(_extraBoxFlags, 0, sizeof(_extraBoxFlags)); memset(_extraBoxFlags, 0, sizeof(_extraBoxFlags));
} }
void Scumm::setScaleItem(int slot, int a, int b, int c, int d) { void Scumm::setScaleItem(int slot, int a, int b, int c, int d)
{
byte *ptr; byte *ptr;
int cur, amounttoadd, i, tmp; int cur, amounttoadd, i, tmp;
@ -679,14 +691,17 @@ void Scumm::setScaleItem(int slot, int a, int b, int c, int d) {
for (i = 200; i > 0; i--) { for (i = 200; i > 0; i--) {
tmp = cur / (c - a) + b; tmp = cur / (c - a) + b;
if (tmp<1) tmp=1; if (tmp < 1)
if (tmp>255) tmp=255; tmp = 1;
if (tmp > 255)
tmp = 255;
*ptr++ = tmp; *ptr++ = tmp;
cur += amounttoadd; cur += amounttoadd;
} }
} }
void Scumm::dumpResource(char *tag, int idx, byte *ptr) { void Scumm::dumpResource(char *tag, int idx, byte *ptr)
{
char buf[256]; char buf[256];
FILE *out; FILE *out;
@ -713,47 +728,56 @@ void Scumm::dumpResource(char *tag, int idx, byte *ptr) {
} }
void Scumm::clear_fullRedraw() { void Scumm::clear_fullRedraw()
{
_fullRedraw = 0; _fullRedraw = 0;
} }
void Scumm::clearClickedStatus() { void Scumm::clearClickedStatus()
{
checkKeyHit(); checkKeyHit();
_mouseButStat = 0; _mouseButStat = 0;
_leftBtnPressed = 0; _leftBtnPressed = 0;
_rightBtnPressed = 0; _rightBtnPressed = 0;
} }
int Scumm::checkKeyHit() { int Scumm::checkKeyHit()
{
int a = _keyPressed; int a = _keyPressed;
_keyPressed = 0; _keyPressed = 0;
return a; return a;
} }
void Scumm::unkRoomFunc3(int a, int b, int c, int d, int e) { void Scumm::unkRoomFunc3(int a, int b, int c, int d, int e)
{
warning("stub unkRoomFunc3(%d,%d,%d,%d,%d)", a, b, c, d, e); warning("stub unkRoomFunc3(%d,%d,%d,%d,%d)", a, b, c, d, e);
} }
void Scumm::unkRoomFunc4(int a, int b, int c, int d, int e) { void Scumm::unkRoomFunc4(int a, int b, int c, int d, int e)
{
/* TODO: implement this */ /* TODO: implement this */
warning("unkRoomFunc4: not implemented"); warning("unkRoomFunc4: not implemented");
} }
void Scumm::pauseGame(bool user) { void Scumm::pauseGame(bool user)
{
((Gui *)_gui)->pause(this); ((Gui *)_gui)->pause(this);
} }
void Scumm::setOptions() { void Scumm::setOptions()
{
((Gui *)_gui)->options(this); ((Gui *)_gui)->options(this);
} }
void Scumm::shutDown(int i) { void Scumm::shutDown(int i)
{
/* TODO: implement this */ /* TODO: implement this */
warning("shutDown: not implemented"); warning("shutDown: not implemented");
} }
void Scumm::processKbd() { void Scumm::processKbd()
{
getKeyInput(0); getKeyInput(0);
_virtual_mouse_x = mouse.x + virtscr[0].xstart; _virtual_mouse_x = mouse.x + virtscr[0].xstart;
@ -799,7 +823,8 @@ void Scumm::processKbd() {
videoFinished = 1; videoFinished = 1;
} else } else
exitCutscene(); exitCutscene();
} else if (_lastKeyHit==_vars[VAR_SAVELOADDIALOG_KEY] && _currentRoom != 0) { } else if (_lastKeyHit == _vars[VAR_SAVELOADDIALOG_KEY]
&& _currentRoom != 0) {
if (_features & GF_AFTER_V7) if (_features & GF_AFTER_V7)
runScript(_vars[VAR_UNK_SCRIPT], 0, 0, 0); runScript(_vars[VAR_UNK_SCRIPT], 0, 0, 0);
((Gui *)_gui)->saveLoadDialog(this); ((Gui *)_gui)->saveLoadDialog(this);
@ -815,17 +840,22 @@ void Scumm::processKbd() {
_mouseButStat = _lastKeyHit; _mouseButStat = _lastKeyHit;
} }
int Scumm::getKeyInput(int a) { int Scumm::getKeyInput(int a)
{
_mouseButStat = 0; _mouseButStat = 0;
_lastKeyHit = checkKeyHit(); _lastKeyHit = checkKeyHit();
if (a == 0) if (a == 0)
convertKeysToClicks(); convertKeysToClicks();
if (mouse.x<0) mouse.x=0; if (mouse.x < 0)
if (mouse.x>319) mouse.x=319; mouse.x = 0;
if (mouse.y<0) mouse.y=0; if (mouse.x > 319)
if (mouse.y>199) mouse.y=199; mouse.x = 319;
if (mouse.y < 0)
mouse.y = 0;
if (mouse.y > 199)
mouse.y = 199;
if (_leftBtnPressed & msClicked && _rightBtnPressed & msClicked) { if (_leftBtnPressed & msClicked && _rightBtnPressed & msClicked) {
_mouseButStat = 0; _mouseButStat = 0;
@ -849,7 +879,8 @@ int Scumm::getKeyInput(int a) {
return _lastKeyHit; return _lastKeyHit;
} }
void Scumm::convertKeysToClicks() { void Scumm::convertKeysToClicks()
{
if (_lastKeyHit && _cursorState > 0) { if (_lastKeyHit && _cursorState > 0) {
if (_lastKeyHit == 9) { if (_lastKeyHit == 9) {
_mouseButStat = MBS_RIGHT_CLICK; _mouseButStat = MBS_RIGHT_CLICK;
@ -861,15 +892,19 @@ void Scumm::convertKeysToClicks() {
} }
} }
Actor *Scumm::derefActorSafe(int id, const char *errmsg) { Actor *Scumm::derefActorSafe(int id, const char *errmsg)
{
if (id < 1 || id >= NUM_ACTORS) { if (id < 1 || id >= NUM_ACTORS) {
warning("Invalid actor %d in %s (script %d, opcode 0x%x) - This is potentially a BIG problem.", id, errmsg, vm.slot[_curExecScript].number, _opcode); warning
("Invalid actor %d in %s (script %d, opcode 0x%x) - This is potentially a BIG problem.",
id, errmsg, vm.slot[_curExecScript].number, _opcode);
return NULL; return NULL;
} }
return derefActor(id); return derefActor(id);
} }
void Scumm::makeCursorColorTransparent(int a) { void Scumm::makeCursorColorTransparent(int a)
{
int i, size; int i, size;
size = _cursorWidth * _cursorHeight; size = _cursorWidth * _cursorHeight;
@ -879,7 +914,8 @@ void Scumm::makeCursorColorTransparent(int a) {
_grabbedCursor[i] = 0xFF; _grabbedCursor[i] = 0xFF;
} }
void Scumm::setStringVars(int slot) { void Scumm::setStringVars(int slot)
{
StringTab *st = &string[slot]; StringTab *st = &string[slot];
st->xpos = st->t_xpos; st->xpos = st->t_xpos;
st->ypos = st->t_ypos; st->ypos = st->t_ypos;
@ -891,15 +927,18 @@ void Scumm::setStringVars(int slot) {
st->charset = st->t_charset; st->charset = st->t_charset;
} }
void Scumm::unkMiscOp9() { void Scumm::unkMiscOp9()
{
warning("stub unkMiscOp9()"); warning("stub unkMiscOp9()");
} }
void Scumm::startManiac() { void Scumm::startManiac()
{
warning("stub startManiac()"); warning("stub startManiac()");
} }
void Scumm::destroy() { void Scumm::destroy()
{
freeResources(); freeResources();
free(_objectStateTable); free(_objectStateTable);
@ -915,7 +954,8 @@ void Scumm::destroy() {
free(_classData); free(_classData);
} }
int Scumm::newDirToOldDir(int dir) { int Scumm::newDirToOldDir(int dir)
{
if (dir >= 71 && dir <= 109) if (dir >= 71 && dir <= 109)
return 1; return 1;
if (dir >= 109 && dir <= 251) if (dir >= 109 && dir <= 251)
@ -932,17 +972,20 @@ const int new_dir_table[4] = {
0, 0,
}; };
int Scumm::oldDirToNewDir(int dir) { int Scumm::oldDirToNewDir(int dir)
{
return new_dir_table[dir]; return new_dir_table[dir];
} }
int Scumm::numSimpleDirDirections(int dirType) { int Scumm::numSimpleDirDirections(int dirType)
{
return dirType ? 8 : 4; return dirType ? 8 : 4;
} }
/* Convert an angle to a simple direction */ /* Convert an angle to a simple direction */
int Scumm::toSimpleDir(int dirType, int dir) { int Scumm::toSimpleDir(int dirType, int dir)
{
int num = dirType ? 8 : 4, i; int num = dirType ? 8 : 4, i;
const uint16 *dirtab = &many_direction_tab[dirType * 8 + 2]; const uint16 *dirtab = &many_direction_tab[dirType * 8 + 2];
for (i = 1; i < num; i++, dirtab++) { for (i = 1; i < num; i++, dirtab++) {
@ -954,19 +997,23 @@ int Scumm::toSimpleDir(int dirType, int dir) {
} }
/* Convert a simple direction to an angle */ /* Convert a simple direction to an angle */
int Scumm::fromSimpleDir(int dirType, int dir) { int Scumm::fromSimpleDir(int dirType, int dir)
if (!dirType)dir+=dir; {
if (!dirType)
dir += dir;
return dir * 45; return dir * 45;
} }
int Scumm::normalizeAngle(int angle) { int Scumm::normalizeAngle(int angle)
{
return (angle + 360) % 360; return (angle + 360) % 360;
} }
extern Scumm *scumm; extern Scumm *scumm;
void NORETURN CDECL error(const char *s, ...) { void NORETURN CDECL error(const char *s, ...)
{
char buf[1024]; char buf[1024];
va_list va; va_list va;
@ -979,8 +1026,7 @@ void NORETURN CDECL error(const char *s, ...) {
fprintf(stderr, "Error(%d:%d:0x%X): %s!\n", fprintf(stderr, "Error(%d:%d:0x%X): %s!\n",
scumm->_roomResource, scumm->_roomResource,
ss->number, ss->number,
scumm->_scriptPointer - scumm->_scriptOrgPointer, scumm->_scriptPointer - scumm->_scriptOrgPointer, buf);
buf);
} else { } else {
fprintf(stderr, "Error: %s!\n", buf); fprintf(stderr, "Error: %s!\n", buf);
} }
@ -988,7 +1034,8 @@ void NORETURN CDECL error(const char *s, ...) {
exit(1); exit(1);
} }
void CDECL warning(const char *s, ...) { void CDECL warning(const char *s, ...)
{
char buf[1024]; char buf[1024];
va_list va; va_list va;
@ -999,7 +1046,8 @@ void CDECL warning(const char *s, ...) {
fprintf(stderr, "WARNING: %s!\n", buf); fprintf(stderr, "WARNING: %s!\n", buf);
} }
void CDECL debug(int level, const char *s, ...) { void CDECL debug(int level, const char *s, ...)
{
char buf[1024]; char buf[1024];
va_list va; va_list va;
@ -1013,7 +1061,8 @@ void CDECL debug(int level, const char *s, ...) {
fflush(stdout); fflush(stdout);
} }
void checkHeap() { void checkHeap()
{
#if defined(WIN32) #if defined(WIN32)
if (_heapchk() != _HEAPOK) { if (_heapchk() != _HEAPOK) {
error("Heap is invalid!"); error("Heap is invalid!");
@ -1021,12 +1070,12 @@ void checkHeap() {
#endif #endif
} }
void Scumm::mainRun() { void Scumm::mainRun()
{
delta = 0; delta = 0;
do do {
{
_system->waitTick(delta); _system->waitTick(delta);
delta = scummLoop(delta); delta = scummLoop(delta);
} while (1); } while (1);

588
sdl.cpp

File diff suppressed because it is too large Load diff

190
sound.cpp
View file

@ -29,7 +29,8 @@ extern void *bsearch(const void *, const void *, size_t,
size_t, int (*x) (const void *, const void *)); size_t, int (*x) (const void *, const void *));
#endif #endif
void Scumm::addSoundToQueue(int sound) { void Scumm::addSoundToQueue(int sound)
{
if (!(_features & GF_AFTER_V7)) { if (!(_features & GF_AFTER_V7)) {
_vars[VAR_LAST_SOUND] = sound; _vars[VAR_LAST_SOUND] = sound;
ensureResourceLoaded(rtSound, sound); ensureResourceLoaded(rtSound, sound);
@ -40,13 +41,15 @@ void Scumm::addSoundToQueue(int sound) {
warning("Requesting audio track: %d", sound); warning("Requesting audio track: %d", sound);
} }
void Scumm::addSoundToQueue2(int sound) { void Scumm::addSoundToQueue2(int sound)
{
if (_soundQue2Pos < 10) { if (_soundQue2Pos < 10) {
_soundQue2[_soundQue2Pos++] = sound; _soundQue2[_soundQue2Pos++] = sound;
} }
} }
void Scumm::processSoundQues() { void Scumm::processSoundQues()
{
byte d; byte d;
int i, j; int i, j;
int num; int num;
@ -79,18 +82,14 @@ void Scumm::processSoundQues() {
debug(1, "processSoundQues(%d,%d,%d,%d,%d,%d,%d,%d,%d)", debug(1, "processSoundQues(%d,%d,%d,%d,%d,%d,%d,%d,%d)",
data[0] >> 8, data[0] >> 8,
data[0] & 0xFF, data[0] & 0xFF,
data[1], data[1], data[2], data[3], data[4], data[5], data[6], data[7]
data[2],
data[3],
data[4],
data[5],
data[6],
data[7]
); );
#endif #endif
if (!(_features & GF_AFTER_V7)) { if (!(_features & GF_AFTER_V7)) {
if (se) if (se)
_vars[VAR_SOUNDRESULT] = (short)se->do_command(data[0],data[1],data[2],data[3],data[4],data[5],data[6],data[7]); _vars[VAR_SOUNDRESULT] =
(short)se->do_command(data[0], data[1], data[2], data[3], data[4],
data[5], data[6], data[7]);
} }
} }
@ -98,7 +97,8 @@ void Scumm::processSoundQues() {
_soundQuePos = 0; _soundQuePos = 0;
} }
void Scumm::playSound(int sound) { void Scumm::playSound(int sound)
{
byte *ptr; byte *ptr;
SoundEngine *se = (SoundEngine *)_soundEngine; SoundEngine *se = (SoundEngine *)_soundEngine;
@ -111,7 +111,8 @@ void Scumm::playSound(int sound) {
return; return;
} }
if (_features & GF_OLD256) return; /* FIXME */ if (_features & GF_OLD256)
return; /* FIXME */
if (se) { if (se) {
getResourceAddress(rtSound, sound); getResourceAddress(rtSound, sound);
@ -119,7 +120,8 @@ void Scumm::playSound(int sound) {
} }
} }
void Scumm::processSfxQueues() { void Scumm::processSfxQueues()
{
Actor *a; Actor *a;
int act; int act;
bool b, finished; bool b, finished;
@ -157,12 +159,15 @@ void Scumm::processSfxQueues() {
} }
#ifdef COMPRESSED_SOUND_FILE #ifdef COMPRESSED_SOUND_FILE
static int compar(const void *a, const void *b) { static int compar(const void *a, const void *b)
return ((MP3OffsetTable *) a)->org_offset - ((MP3OffsetTable *) b)->org_offset; {
return ((MP3OffsetTable *) a)->org_offset -
((MP3OffsetTable *) b)->org_offset;
} }
#endif #endif
void Scumm::startTalkSound(uint32 offset, uint32 b, int mode) { void Scumm::startTalkSound(uint32 offset, uint32 b, int mode)
{
int num = 0, i; int num = 0, i;
byte file_byte, file_byte_2; byte file_byte, file_byte_2;
int size; int size;
@ -175,13 +180,14 @@ void Scumm::startTalkSound(uint32 offset, uint32 b, int mode) {
if (b > 8) { if (b > 8) {
num = (b - 8) >> 1; num = (b - 8) >> 1;
} }
#ifdef COMPRESSED_SOUND_FILE #ifdef COMPRESSED_SOUND_FILE
if (offset_table != NULL) { if (offset_table != NULL) {
MP3OffsetTable *result = NULL, key; MP3OffsetTable *result = NULL, key;
key.org_offset = offset; key.org_offset = offset;
result = (MP3OffsetTable *) bsearch(&key, offset_table, num_sound_effects, sizeof(MP3OffsetTable), compar); result =
(MP3OffsetTable *) bsearch(&key, offset_table, num_sound_effects,
sizeof(MP3OffsetTable), compar);
if (result == NULL) { if (result == NULL) {
@ -189,7 +195,8 @@ void Scumm::startTalkSound(uint32 offset, uint32 b, int mode) {
return; return;
} }
if (2 * num != result->num_tags) { if (2 * num != result->num_tags) {
warning("startTalkSound: number of tags do not match (%d - %d) !", b, result->num_tags); warning("startTalkSound: number of tags do not match (%d - %d) !", b,
result->num_tags);
num = result->num_tags; num = result->num_tags;
} }
offset = result->new_offset; offset = result->new_offset;
@ -217,14 +224,16 @@ void Scumm::startTalkSound(uint32 offset, uint32 b, int mode) {
startSfxSound(_sfxFile, size); startSfxSound(_sfxFile, size);
} }
void Scumm::stopTalkSound() { void Scumm::stopTalkSound()
{
if (_sfxMode == 2) { if (_sfxMode == 2) {
stopSfxSound(); stopSfxSound();
_sfxMode = 0; _sfxMode = 0;
} }
} }
bool Scumm::isMouthSyncOff(uint pos) { bool Scumm::isMouthSyncOff(uint pos)
{
uint j; uint j;
bool val = true; bool val = true;
uint16 *ms = _mouthSyncTimes; uint16 *ms = _mouthSyncTimes;
@ -242,7 +251,8 @@ bool Scumm::isMouthSyncOff(uint pos) {
} }
int Scumm::isSoundRunning(int sound) { int Scumm::isSoundRunning(int sound)
{
SoundEngine *se; SoundEngine *se;
int i; int i;
@ -267,7 +277,8 @@ int Scumm::isSoundRunning(int sound) {
return se->get_sound_status(sound); return se->get_sound_status(sound);
} }
bool Scumm::isSoundInQueue(int sound) { bool Scumm::isSoundInQueue(int sound)
{
int i = 0, j, num; int i = 0, j, num;
int16 table[16]; int16 table[16];
@ -287,7 +298,8 @@ bool Scumm::isSoundInQueue(int sound) {
return 0; return 0;
} }
void Scumm::stopSound(int a) { void Scumm::stopSound(int a)
{
SoundEngine *se; SoundEngine *se;
int i; int i;
@ -305,7 +317,8 @@ void Scumm::stopSound(int a) {
_soundQue2[i] = 0; _soundQue2[i] = 0;
} }
void Scumm::stopAllSounds() { void Scumm::stopAllSounds()
{
SoundEngine *se = (SoundEngine *)_soundEngine; SoundEngine *se = (SoundEngine *)_soundEngine;
if (current_cd_sound != 0) { if (current_cd_sound != 0) {
@ -321,12 +334,14 @@ void Scumm::stopAllSounds() {
stopSfxSound(); stopSfxSound();
} }
void Scumm::clearSoundQue() { void Scumm::clearSoundQue()
{
_soundQue2Pos = 0; _soundQue2Pos = 0;
memset(_soundQue2, 0, sizeof(_soundQue2)); memset(_soundQue2, 0, sizeof(_soundQue2));
} }
void Scumm::soundKludge(int16 *list) { void Scumm::soundKludge(int16 * list)
{
int16 *ptr; int16 *ptr;
int i; int i;
@ -345,7 +360,8 @@ void Scumm::soundKludge(int16 *list) {
error("Sound que buffer overflow"); error("Sound que buffer overflow");
} }
void Scumm::talkSound(uint32 a, uint32 b, int mode) { void Scumm::talkSound(uint32 a, uint32 b, int mode)
{
_talk_sound_a = a; _talk_sound_a = a;
_talk_sound_b = b; _talk_sound_b = b;
_talk_sound_mode = mode; _talk_sound_mode = mode;
@ -358,12 +374,14 @@ void Scumm::talkSound(uint32 a, uint32 b, int mode) {
* is needed. * is needed.
*/ */
void Scumm::setupSound() { void Scumm::setupSound()
{
SoundEngine *se = (SoundEngine *)_soundEngine; SoundEngine *se = (SoundEngine *)_soundEngine;
SOUND_DRIVER_TYPE *driver = se->driver(); SOUND_DRIVER_TYPE *driver = se->driver();
if (se) { if (se) {
se->setBase(res.address[rtSound]); se->setBase(res.address[rtSound]);
if (se->get_music_volume() == 0) se->set_music_volume(60); if (se->get_music_volume() == 0)
se->set_music_volume(60);
se->set_master_volume(125); se->set_master_volume(125);
_sound_volume_sfx = 100; _sound_volume_sfx = 100;
@ -374,7 +392,8 @@ void Scumm::setupSound() {
_sfxFile = openSfxFile(); _sfxFile = openSfxFile();
} }
void Scumm::pauseSounds(bool pause) { void Scumm::pauseSounds(bool pause)
{
SoundEngine *se = (SoundEngine *)_soundEngine; SoundEngine *se = (SoundEngine *)_soundEngine;
if (se) if (se)
se->pause(pause); se->pause(pause);
@ -387,7 +406,8 @@ enum {
}; };
void Scumm::startSfxSound(void *file, int file_size) { void Scumm::startSfxSound(void *file, int file_size)
{
char ident[8]; char ident[8];
int block_type; int block_type;
byte work[8]; byte work[8];
@ -461,7 +481,8 @@ invalid:;
#ifdef COMPRESSED_SOUND_FILE #ifdef COMPRESSED_SOUND_FILE
static int get_int(FILE *f) { static int get_int(FILE * f)
{
int ret = 0; int ret = 0;
for (int size = 0; size < 4; size++) { for (int size = 0; size < 4; size++) {
int c = fgetc(f); int c = fgetc(f);
@ -475,7 +496,8 @@ static int get_int(FILE *f) {
} }
#endif #endif
void *Scumm::openSfxFile() { void *Scumm::openSfxFile()
{
char buf[50]; char buf[50];
FILE *file = NULL; FILE *file = NULL;
@ -542,7 +564,8 @@ void *Scumm::openSfxFile() {
return file; return file;
} }
MixerChannel *Scumm::allocateMixer() { MixerChannel *Scumm::allocateMixer()
{
int i; int i;
MixerChannel *mc = _mixer_channel; MixerChannel *mc = _mixer_channel;
for (i = 0; i < NUM_MIXER; i++, mc++) { for (i = 0; i < NUM_MIXER; i++, mc++) {
@ -552,7 +575,8 @@ MixerChannel *Scumm::allocateMixer() {
return NULL; return NULL;
} }
void Scumm::stopSfxSound() { void Scumm::stopSfxSound()
{
MixerChannel *mc = _mixer_channel; MixerChannel *mc = _mixer_channel;
int i; int i;
for (i = 0; i < NUM_MIXER; i++, mc++) { for (i = 0; i < NUM_MIXER; i++, mc++) {
@ -562,7 +586,8 @@ void Scumm::stopSfxSound() {
} }
bool Scumm::isSfxFinished() { bool Scumm::isSfxFinished()
{
int i; int i;
for (i = 0; i < NUM_MIXER; i++) for (i = 0; i < NUM_MIXER; i++)
if (_mixer_channel[i]._sfx_sound) if (_mixer_channel[i]._sfx_sound)
@ -571,7 +596,8 @@ bool Scumm::isSfxFinished() {
} }
#ifdef COMPRESSED_SOUND_FILE #ifdef COMPRESSED_SOUND_FILE
void Scumm::playSfxSound_MP3(void *sound, uint32 size) { void Scumm::playSfxSound_MP3(void *sound, uint32 size)
{
MixerChannel *mc = allocateMixer(); MixerChannel *mc = allocateMixer();
if (!mc) { if (!mc) {
@ -590,7 +616,8 @@ void Scumm::playSfxSound_MP3(void *sound, uint32 size) {
// 11 kHz on WinCE // 11 kHz on WinCE
mad_stream_options((mad_stream*)&mc->sound_data.mp3.stream, MAD_OPTION_HALFSAMPLERATE); mad_stream_options((mad_stream *) & mc->sound_data.mp3.stream,
MAD_OPTION_HALFSAMPLERATE);
#endif #endif
@ -616,11 +643,13 @@ void Scumm::playSfxSound_MP3(void *sound, uint32 size) {
} }
#endif #endif
void Scumm::playBundleSound(char *sound) { void Scumm::playBundleSound(char *sound)
{
warning("playBundleSound: %s", sound); warning("playBundleSound: %s", sound);
} }
void Scumm::playSfxSound(void *sound, uint32 size, uint rate) { void Scumm::playSfxSound(void *sound, uint32 size, uint rate)
{
MixerChannel *mc = allocateMixer(); MixerChannel *mc = allocateMixer();
if (!mc) { if (!mc) {
@ -638,7 +667,8 @@ void Scumm::playSfxSound(void *sound, uint32 size, uint rate) {
#else #else
mc->sound_data.standard._sfx_fp_speed = (1 << 16) * rate / 22050; mc->sound_data.standard._sfx_fp_speed = (1 << 16) * rate / 22050;
#endif #endif
while (size&0xFFFF0000) size>>=1, rate>>=1; while (size & 0xFFFF0000)
size >>= 1, rate >>= 1;
#ifdef _WIN32_WCE #ifdef _WIN32_WCE
@ -665,7 +695,8 @@ static inline int scale_sample(mad_fixed_t sample)
} }
#endif #endif
void MixerChannel::mix(int16 *data, uint32 len) { void MixerChannel::mix(int16 * data, uint32 len)
{
if (!_sfx_sound) if (!_sfx_sound)
return; return;
@ -701,9 +732,10 @@ void MixerChannel::mix(int16 *data, uint32 len) {
if (type == MIXER_MP3) { if (type == MIXER_MP3) {
mad_fixed_t const *ch; mad_fixed_t const *ch;
while (1) { while (1) {
ch = sound_data.mp3.synth.pcm.samples[0] + sound_data.mp3.pos_in_frame; ch =
while ((sound_data.mp3.pos_in_frame < sound_data.mp3.synth.pcm.length) && sound_data.mp3.synth.pcm.samples[0] + sound_data.mp3.pos_in_frame;
(len > 0)) { while ((sound_data.mp3.pos_in_frame < sound_data.mp3.synth.pcm.length)
&& (len > 0)) {
if (sound_data.mp3.silence_cut > 0) { if (sound_data.mp3.silence_cut > 0) {
sound_data.mp3.silence_cut--; sound_data.mp3.silence_cut--;
} else { } else {
@ -712,7 +744,8 @@ void MixerChannel::mix(int16 *data, uint32 len) {
} }
sound_data.mp3.pos_in_frame++; sound_data.mp3.pos_in_frame++;
} }
if (len == 0) return; if (len == 0)
return;
if (sound_data.mp3.position >= sound_data.mp3.size) { if (sound_data.mp3.position >= sound_data.mp3.size) {
clear(); clear();
@ -720,10 +753,13 @@ void MixerChannel::mix(int16 *data, uint32 len) {
} }
mad_stream_buffer(&sound_data.mp3.stream, mad_stream_buffer(&sound_data.mp3.stream,
((unsigned char *) _sfx_sound) + sound_data.mp3.position, ((unsigned char *)_sfx_sound) +
sound_data.mp3.size + MAD_BUFFER_GUARD - sound_data.mp3.position); sound_data.mp3.position,
sound_data.mp3.size + MAD_BUFFER_GUARD -
sound_data.mp3.position);
if (mad_frame_decode(&sound_data.mp3.frame, &sound_data.mp3.stream) == -1) { if (mad_frame_decode(&sound_data.mp3.frame, &sound_data.mp3.stream) ==
-1) {
/* End of audio... */ /* End of audio... */
if (sound_data.mp3.stream.error == MAD_ERROR_BUFLEN) { if (sound_data.mp3.stream.error == MAD_ERROR_BUFLEN) {
clear(); clear();
@ -734,10 +770,11 @@ void MixerChannel::mix(int16 *data, uint32 len) {
} }
mad_synth_frame(&sound_data.mp3.synth, &sound_data.mp3.frame); mad_synth_frame(&sound_data.mp3.synth, &sound_data.mp3.frame);
sound_data.mp3.pos_in_frame = 0; sound_data.mp3.pos_in_frame = 0;
sound_data.mp3.position = (unsigned char *) sound_data.mp3.stream.next_frame - (unsigned char *) _sfx_sound; sound_data.mp3.position =
(unsigned char *)sound_data.mp3.stream.next_frame -
(unsigned char *)_sfx_sound;
} }
} } else if (type == MIXER_MP3_CDMUSIC) {
else if (type == MIXER_MP3_CDMUSIC) {
mad_fixed_t const *ch; mad_fixed_t const *ch;
mad_timer_t frame_duration; mad_timer_t frame_duration;
static long last_pos = 0; static long last_pos = 0;
@ -752,7 +789,8 @@ void MixerChannel::mix(int16 *data, uint32 len) {
int skip_loop; int skip_loop;
// Read the new data // Read the new data
memset(_sfx_sound, 0, sound_data.mp3_cdmusic.buffer_size + MAD_BUFFER_GUARD); memset(_sfx_sound, 0,
sound_data.mp3_cdmusic.buffer_size + MAD_BUFFER_GUARD);
sound_data.mp3_cdmusic.size = sound_data.mp3_cdmusic.size =
fread(_sfx_sound, 1, sound_data.mp3_cdmusic.buffer_size, fread(_sfx_sound, 1, sound_data.mp3_cdmusic.buffer_size,
sound_data.mp3_cdmusic.file); sound_data.mp3_cdmusic.file);
@ -764,8 +802,7 @@ void MixerChannel::mix(int16 *data, uint32 len) {
// Resync // Resync
mad_stream_buffer(&sound_data.mp3_cdmusic.stream, mad_stream_buffer(&sound_data.mp3_cdmusic.stream,
(unsigned char *)_sfx_sound, (unsigned char *)_sfx_sound,
sound_data.mp3_cdmusic.size sound_data.mp3_cdmusic.size);
);
skip_loop = 2; skip_loop = 2;
while (skip_loop != 0) { while (skip_loop != 0) {
if (mad_frame_decode(&sound_data.mp3_cdmusic.frame, if (mad_frame_decode(&sound_data.mp3_cdmusic.frame,
@ -776,8 +813,7 @@ void MixerChannel::mix(int16 *data, uint32 len) {
mad_synth_frame(&sound_data.mp3_cdmusic.synth, mad_synth_frame(&sound_data.mp3_cdmusic.synth,
&sound_data.mp3_cdmusic.frame); &sound_data.mp3_cdmusic.frame);
} }
} } else {
else {
if (!MAD_RECOVERABLE(sound_data.mp3_cdmusic.stream.error)) { if (!MAD_RECOVERABLE(sound_data.mp3_cdmusic.stream.error)) {
debug(1, "Unrecoverable error while skipping !"); debug(1, "Unrecoverable error while skipping !");
sound_data.mp3_cdmusic.playing = false; sound_data.mp3_cdmusic.playing = false;
@ -795,8 +831,7 @@ void MixerChannel::mix(int16 *data, uint32 len) {
(unsigned char *)sound_data.mp3_cdmusic.stream.next_frame - (unsigned char *)sound_data.mp3_cdmusic.stream.next_frame -
(unsigned char *)_sfx_sound; (unsigned char *)_sfx_sound;
sound_data.mp3_cdmusic.pos_in_frame = 0; sound_data.mp3_cdmusic.pos_in_frame = 0;
} } else {
else {
sound_data.mp3_cdmusic.playing = false; sound_data.mp3_cdmusic.playing = false;
return; return;
} }
@ -806,8 +841,7 @@ void MixerChannel::mix(int16 *data, uint32 len) {
ch = sound_data.mp3_cdmusic.synth.pcm.samples[0] + ch = sound_data.mp3_cdmusic.synth.pcm.samples[0] +
sound_data.mp3_cdmusic.pos_in_frame; sound_data.mp3_cdmusic.pos_in_frame;
while ((sound_data.mp3_cdmusic.pos_in_frame < while ((sound_data.mp3_cdmusic.pos_in_frame <
sound_data.mp3_cdmusic.synth.pcm.length) && sound_data.mp3_cdmusic.synth.pcm.length) && (len > 0)) {
(len > 0)) {
*data++ += scale_sample(*ch++); *data++ += scale_sample(*ch++);
len--; len--;
sound_data.mp3_cdmusic.pos_in_frame++; sound_data.mp3_cdmusic.pos_in_frame++;
@ -815,7 +849,6 @@ void MixerChannel::mix(int16 *data, uint32 len) {
if (len == 0) { if (len == 0) {
return; return;
} }
// See if we have finished // See if we have finished
// May be incorrect to check the size at the end of a frame but I suppose // May be incorrect to check the size at the end of a frame but I suppose
// they are short enough :) // they are short enough :)
@ -824,7 +857,8 @@ void MixerChannel::mix(int16 *data, uint32 len) {
mad_timer_negate(&frame_duration); mad_timer_negate(&frame_duration);
mad_timer_add(&sound_data.mp3_cdmusic.duration, frame_duration); mad_timer_add(&sound_data.mp3_cdmusic.duration, frame_duration);
if (mad_timer_compare(sound_data.mp3_cdmusic.duration, mad_timer_zero) < 0) { if (mad_timer_compare(sound_data.mp3_cdmusic.duration, mad_timer_zero)
< 0) {
sound_data.mp3_cdmusic.playing = false; sound_data.mp3_cdmusic.playing = false;
} }
@ -835,14 +869,14 @@ void MixerChannel::mix(int16 *data, uint32 len) {
int not_decoded; int not_decoded;
if (!sound_data.mp3_cdmusic.stream.next_frame) { if (!sound_data.mp3_cdmusic.stream.next_frame) {
memset(_sfx_sound, 0, sound_data.mp3_cdmusic.buffer_size + MAD_BUFFER_GUARD); memset(_sfx_sound, 0,
sound_data.mp3_cdmusic.buffer_size + MAD_BUFFER_GUARD);
sound_data.mp3_cdmusic.size = sound_data.mp3_cdmusic.size =
fread(_sfx_sound, 1, sound_data.mp3_cdmusic.buffer_size, fread(_sfx_sound, 1, sound_data.mp3_cdmusic.buffer_size,
sound_data.mp3_cdmusic.file); sound_data.mp3_cdmusic.file);
sound_data.mp3_cdmusic.position = 0; sound_data.mp3_cdmusic.position = 0;
not_decoded = 0; not_decoded = 0;
} } else {
else {
not_decoded = sound_data.mp3_cdmusic.stream.bufend - not_decoded = sound_data.mp3_cdmusic.stream.bufend -
sound_data.mp3_cdmusic.stream.next_frame; sound_data.mp3_cdmusic.stream.next_frame;
memcpy(_sfx_sound, sound_data.mp3_cdmusic.stream.next_frame, memcpy(_sfx_sound, sound_data.mp3_cdmusic.stream.next_frame,
@ -858,17 +892,20 @@ void MixerChannel::mix(int16 *data, uint32 len) {
// Restream // Restream
mad_stream_buffer(&sound_data.mp3_cdmusic.stream, mad_stream_buffer(&sound_data.mp3_cdmusic.stream,
(unsigned char *)_sfx_sound, (unsigned char *)_sfx_sound,
sound_data.mp3_cdmusic.size + not_decoded sound_data.mp3_cdmusic.size + not_decoded);
); if (mad_frame_decode
if (mad_frame_decode(&sound_data.mp3_cdmusic.frame, &sound_data.mp3_cdmusic.stream) == -1) { (&sound_data.mp3_cdmusic.frame,
debug(1, "Error decoding after restream %d !", sound_data.mp3.stream.error); &sound_data.mp3_cdmusic.stream) == -1) {
debug(1, "Error decoding after restream %d !",
sound_data.mp3.stream.error);
} }
} else if (!MAD_RECOVERABLE(sound_data.mp3.stream.error)) { } else if (!MAD_RECOVERABLE(sound_data.mp3.stream.error)) {
error("MAD frame decode error in MP3 CDMUSIC !"); error("MAD frame decode error in MP3 CDMUSIC !");
} }
} }
mad_synth_frame(&sound_data.mp3_cdmusic.synth, &sound_data.mp3_cdmusic.frame); mad_synth_frame(&sound_data.mp3_cdmusic.synth,
&sound_data.mp3_cdmusic.frame);
sound_data.mp3_cdmusic.pos_in_frame = 0; sound_data.mp3_cdmusic.pos_in_frame = 0;
sound_data.mp3_cdmusic.position = sound_data.mp3_cdmusic.position =
(unsigned char *)sound_data.mp3_cdmusic.stream.next_frame - (unsigned char *)sound_data.mp3_cdmusic.stream.next_frame -
@ -879,7 +916,8 @@ void MixerChannel::mix(int16 *data, uint32 len) {
#endif #endif
} }
void MixerChannel::clear() { void MixerChannel::clear()
{
free(_sfx_sound); free(_sfx_sound);
_sfx_sound = NULL; _sfx_sound = NULL;
@ -892,7 +930,8 @@ void MixerChannel::clear() {
#endif #endif
} }
void Scumm::mixWaves(int16 *sounds, int len) { void Scumm::mixWaves(int16 * sounds, int len)
{
int i; int i;
memset(sounds, 0, len * sizeof(int16)); memset(sounds, 0, len * sizeof(int16));
@ -912,4 +951,3 @@ void Scumm::mixWaves(int16 *sounds, int len) {
if (_soundsPaused2) if (_soundsPaused2)
memset(sounds, 0x0, len * sizeof(int16)); memset(sounds, 0x0, len * sizeof(int16));
} }

View file

@ -45,7 +45,8 @@ const byte volume_table[] = {
62, 63, 63, 63 62, 63, 63, 63
}; };
int lookup_volume(int a, int b) { int lookup_volume(int a, int b)
{
if (b == 0) if (b == 0)
return 0; return 0;
@ -71,7 +72,8 @@ int lookup_volume(int a, int b) {
} }
} }
void create_lookup_table() { void create_lookup_table()
{
int i, j; int i, j;
int sum; int sum;
@ -86,7 +88,8 @@ void create_lookup_table() {
lookup_table[i][0] = 0; lookup_table[i][0] = 0;
} }
MidiChannelAdl *AdlibSoundDriver::allocate_midichan(byte pri) { MidiChannelAdl *AdlibSoundDriver::allocate_midichan(byte pri)
{
MidiChannelAdl *ac, *best = NULL; MidiChannelAdl *ac, *best = NULL;
int i; int i;
@ -106,12 +109,12 @@ MidiChannelAdl *AdlibSoundDriver::allocate_midichan(byte pri) {
if (best) if (best)
mc_off(best); mc_off(best);
else else; //debug(1, "Denying adlib channel request");
;//debug(1, "Denying adlib channel request");
return best; return best;
} }
void AdlibSoundDriver::init(SoundEngine *eng) { void AdlibSoundDriver::init(SoundEngine *eng)
{
int i; int i;
MidiChannelAdl *mc; MidiChannelAdl *mc;
@ -136,7 +139,8 @@ void AdlibSoundDriver::init(SoundEngine *eng) {
create_lookup_table(); create_lookup_table();
} }
void AdlibSoundDriver::adlib_write(byte port, byte value) { void AdlibSoundDriver::adlib_write(byte port, byte value)
{
if (_adlib_reg_cache[port] == value) if (_adlib_reg_cache[port] == value)
return; return;
_adlib_reg_cache[port] = value; _adlib_reg_cache[port] = value;
@ -144,7 +148,8 @@ void AdlibSoundDriver::adlib_write(byte port, byte value) {
OPLWriteReg(_opl, port, value); OPLWriteReg(_opl, port, value);
} }
void AdlibSoundDriver::adlib_key_off(int chan) { void AdlibSoundDriver::adlib_key_off(int chan)
{
byte port = chan + 0xB0; byte port = chan + 0xB0;
adlib_write(port, adlib_read(port) & ~0x20); adlib_write(port, adlib_read(port) & ~0x20);
} }
@ -183,7 +188,8 @@ static const AdlibSetParams adlib_setparam_table[] = {
{0xC0, 1, 14, 0} /* feedback */ {0xC0, 1, 14, 0} /* feedback */
}; };
void AdlibSoundDriver::adlib_set_param(int channel, byte param, int value) { void AdlibSoundDriver::adlib_set_param(int channel, byte param, int value)
{
const AdlibSetParams *as; const AdlibSetParams *as;
byte port; byte port;
@ -276,7 +282,8 @@ static const byte note_to_f_num[] = {
242, 243, 245, 247, 249, 251, 252, 254, 242, 243, 245, 247, 249, 251, 252, 254,
}; };
void AdlibSoundDriver::adlib_playnote(int channel, int note) { void AdlibSoundDriver::adlib_playnote(int channel, int note)
{
byte old, oct, notex; byte old, oct, notex;
int note2; int note2;
int i; int i;
@ -307,7 +314,8 @@ void AdlibSoundDriver::adlib_playnote(int channel, int note) {
adlib_write(channel + 0xB0, oct | 0x20); adlib_write(channel + 0xB0, oct | 0x20);
} }
void AdlibSoundDriver::adlib_note_on(int chan, byte note, int mod) { void AdlibSoundDriver::adlib_note_on(int chan, byte note, int mod)
{
int code; int code;
assert(chan >= 0 && chan < 9); assert(chan >= 0 && chan < 9);
code = (note << 7) + mod; code = (note << 7) + mod;
@ -315,7 +323,8 @@ void AdlibSoundDriver::adlib_note_on(int chan, byte note, int mod) {
adlib_playnote(chan, channel_table_2[chan] + code); adlib_playnote(chan, channel_table_2[chan] + code);
} }
void AdlibSoundDriver::adlib_note_on_ex(int chan, byte note, int mod) { void AdlibSoundDriver::adlib_note_on_ex(int chan, byte note, int mod)
{
int code; int code;
assert(chan >= 0 && chan < 9); assert(chan >= 0 && chan < 9);
code = (note << 7) + mod; code = (note << 7) + mod;
@ -324,7 +333,8 @@ void AdlibSoundDriver::adlib_note_on_ex(int chan, byte note, int mod) {
adlib_playnote(chan, code); adlib_playnote(chan, code);
} }
void AdlibSoundDriver::adlib_key_onoff(int channel) { void AdlibSoundDriver::adlib_key_onoff(int channel)
{
byte val; byte val;
byte port = channel + 0xB0; byte port = channel + 0xB0;
assert(channel >= 0 && channel < 9); assert(channel >= 0 && channel < 9);
@ -334,7 +344,9 @@ void AdlibSoundDriver::adlib_key_onoff(int channel) {
adlib_write(port, val | 0x20); adlib_write(port, val | 0x20);
} }
void AdlibSoundDriver::adlib_setup_channel(int chan, Instrument *instr, byte vol_1, byte vol_2) { void AdlibSoundDriver::adlib_setup_channel(int chan, Instrument * instr,
byte vol_1, byte vol_2)
{
byte port; byte port;
assert(chan >= 0 && chan < 9); assert(chan >= 0 && chan < 9);
@ -356,7 +368,8 @@ void AdlibSoundDriver::adlib_setup_channel(int chan, Instrument *instr, byte vol
adlib_write((byte)chan + 0xC0, instr->feedback); adlib_write((byte)chan + 0xC0, instr->feedback);
} }
int AdlibSoundDriver::adlib_read_param(int chan, byte param) { int AdlibSoundDriver::adlib_read_param(int chan, byte param)
{
const AdlibSetParams *as; const AdlibSetParams *as;
byte val; byte val;
byte port; byte port;
@ -389,7 +402,8 @@ int AdlibSoundDriver::adlib_read_param(int chan, byte param) {
return val; return val;
} }
void AdlibSoundDriver::generate_samples(int16 *data, int len) { void AdlibSoundDriver::generate_samples(int16 * data, int len)
{
int step; int step;
if (!_opl) { if (!_opl) {
@ -411,11 +425,13 @@ void AdlibSoundDriver::generate_samples(int16 *data, int len) {
} while (len -= step); } while (len -= step);
} }
void AdlibSoundDriver::reset_tick() { void AdlibSoundDriver::reset_tick()
{
_next_tick = 88; _next_tick = 88;
} }
void AdlibSoundDriver::on_timer() { void AdlibSoundDriver::on_timer()
{
MidiChannelAdl *mc; MidiChannelAdl *mc;
int i; int i;
@ -465,7 +481,8 @@ static const uint16 num_steps_table[] = {
600, 860, 1200, 1600 600, 860, 1200, 1600
}; };
int AdlibSoundDriver::random_nr(int a) { int AdlibSoundDriver::random_nr(int a)
{
static byte _rand_seed = 1; static byte _rand_seed = 1;
if (_rand_seed & 1) { if (_rand_seed & 1) {
_rand_seed >>= 1; _rand_seed >>= 1;
@ -476,7 +493,8 @@ int AdlibSoundDriver::random_nr(int a) {
return _rand_seed * a >> 8; return _rand_seed * a >> 8;
} }
void AdlibSoundDriver::struct10_setup(Struct10 *s10) { void AdlibSoundDriver::struct10_setup(Struct10 * s10)
{
int b, c, d, e, f, g, h; int b, c, d, e, f, g, h;
byte t; byte t;
@ -525,7 +543,8 @@ void AdlibSoundDriver::struct10_setup(Struct10 *s10) {
s10->speed_lo_counter = 0; s10->speed_lo_counter = 0;
} }
byte AdlibSoundDriver::struct10_ontimer(Struct10 *s10, Struct11 *s11) { byte AdlibSoundDriver::struct10_ontimer(Struct10 * s10, Struct11 * s11)
{
byte result = 0; byte result = 0;
int i; int i;
@ -568,7 +587,8 @@ byte AdlibSoundDriver::struct10_ontimer(Struct10 *s10, Struct11 *s11) {
return result; return result;
} }
void AdlibSoundDriver::struct10_init(Struct10 *s10, InstrumentExtra *ie) { void AdlibSoundDriver::struct10_init(Struct10 * s10, InstrumentExtra * ie)
{
s10->active = 1; s10->active = 1;
s10->cur_val = 0; s10->cur_val = 0;
s10->modwheel_last = 31; s10->modwheel_last = 31;
@ -588,7 +608,10 @@ void AdlibSoundDriver::struct10_init(Struct10 *s10, InstrumentExtra *ie) {
struct10_setup(s10); struct10_setup(s10);
} }
void AdlibSoundDriver::mc_init_stuff(MidiChannelAdl *mc, Struct10 *s10, Struct11 *s11, byte flags, InstrumentExtra *ie) { void AdlibSoundDriver::mc_init_stuff(MidiChannelAdl *mc, Struct10 * s10,
Struct11 * s11, byte flags,
InstrumentExtra * ie)
{
Part *part = mc->_part; Part *part = mc->_part;
s11->modify_val = 0; s11->modify_val = 0;
@ -626,7 +649,9 @@ void AdlibSoundDriver::mc_init_stuff(MidiChannelAdl *mc, Struct10 *s10, Struct11
struct10_init(s10, ie); struct10_init(s10, ie);
} }
void AdlibSoundDriver::mc_inc_stuff(MidiChannelAdl *mc, Struct10 *s10, Struct11 *s11) { void AdlibSoundDriver::mc_inc_stuff(MidiChannelAdl *mc, Struct10 * s10,
Struct11 * s11)
{
byte code; byte code;
Part *part = mc->_part; Part *part = mc->_part;
@ -636,12 +661,16 @@ void AdlibSoundDriver::mc_inc_stuff(MidiChannelAdl *mc, Struct10 *s10, Struct11
switch (s11->param) { switch (s11->param) {
case 0: case 0:
mc->_vol_2 = s10->start_value + s11->modify_val; mc->_vol_2 = s10->start_value + s11->modify_val;
part->_drv->adlib_set_param(mc->_channel, 0, volume_table[lookup_table[mc->_vol_2][part->_vol_eff>>2]]); part->_drv->adlib_set_param(mc->_channel, 0,
volume_table[lookup_table[mc->_vol_2]
[part->_vol_eff >> 2]]);
break; break;
case 13: case 13:
mc->_vol_1 = s10->start_value + s11->modify_val; mc->_vol_1 = s10->start_value + s11->modify_val;
if (mc->_twochan) { if (mc->_twochan) {
part->_drv->adlib_set_param(mc->_channel, 13, volume_table[lookup_table[mc->_vol_1][part->_vol_eff>>2]]); part->_drv->adlib_set_param(mc->_channel, 13,
volume_table[lookup_table[mc->_vol_1]
[part->_vol_eff >> 2]]);
} else { } else {
part->_drv->adlib_set_param(mc->_channel, 13, mc->_vol_1); part->_drv->adlib_set_param(mc->_channel, 13, mc->_vol_1);
} }
@ -653,7 +682,8 @@ void AdlibSoundDriver::mc_inc_stuff(MidiChannelAdl *mc, Struct10 *s10, Struct11
s11->s10->unk3 = (char)s11->modify_val; s11->s10->unk3 = (char)s11->modify_val;
break; break;
default: default:
part->_drv->adlib_set_param(mc->_channel, s11->param, s10->start_value + s11->modify_val); part->_drv->adlib_set_param(mc->_channel, s11->param,
s10->start_value + s11->modify_val);
break; break;
} }
} }
@ -662,7 +692,8 @@ void AdlibSoundDriver::mc_inc_stuff(MidiChannelAdl *mc, Struct10 *s10, Struct11
part->_drv->adlib_key_onoff(mc->_channel); part->_drv->adlib_key_onoff(mc->_channel);
} }
void AdlibSoundDriver::part_changed(Part *part,byte what) { void AdlibSoundDriver::part_changed(Part *part, byte what)
{
MidiChannelAdl *mc; MidiChannelAdl *mc;
if (what & pcProgram) { if (what & pcProgram) {
@ -673,15 +704,19 @@ void AdlibSoundDriver::part_changed(Part *part,byte what) {
if (what & pcMod) { if (what & pcMod) {
for (mc = part->_mc->adl(); mc; mc = mc->_next) { for (mc = part->_mc->adl(); mc; mc = mc->_next) {
adlib_note_on(mc->_channel, mc->_note + part->_transpose_eff, part->_pitchbend + part->_detune_eff); adlib_note_on(mc->_channel, mc->_note + part->_transpose_eff,
part->_pitchbend + part->_detune_eff);
} }
} }
if (what & pcVolume) { if (what & pcVolume) {
for (mc = part->_mc->adl(); mc; mc = mc->_next) { for (mc = part->_mc->adl(); mc; mc = mc->_next) {
adlib_set_param(mc->_channel, 0, volume_table[lookup_table[mc->_vol_2][part->_vol_eff>>2]]); adlib_set_param(mc->_channel, 0, volume_table[lookup_table[mc->_vol_2]
[part->_vol_eff >> 2]]);
if (mc->_twochan) { if (mc->_twochan) {
adlib_set_param(mc->_channel, 13, volume_table[lookup_table[mc->_vol_1][part->_vol_eff>>2]]); adlib_set_param(mc->_channel, 13,
volume_table[lookup_table[mc->_vol_1]
[part->_vol_eff >> 2]]);
} }
} }
} }
@ -705,7 +740,8 @@ void AdlibSoundDriver::part_changed(Part *part,byte what) {
} }
} }
void AdlibSoundDriver::mc_key_on(MidiChannel *mc2, byte note, byte velocity) { void AdlibSoundDriver::mc_key_on(MidiChannel * mc2, byte note, byte velocity)
{
MidiChannelAdl *mc = (MidiChannelAdl *)mc2; MidiChannelAdl *mc = (MidiChannelAdl *)mc2;
Part *part = mc->_part; Part *part = mc->_part;
Instrument *instr = &_part_instr[part->_slot]; Instrument *instr = &_part_instr[part->_slot];
@ -719,12 +755,16 @@ void AdlibSoundDriver::mc_key_on(MidiChannel *mc2, byte note, byte velocity) {
if (mc->_duration != 0) if (mc->_duration != 0)
mc->_duration *= 63; mc->_duration *= 63;
vol_1 = (instr->oplvl_1&0x3F) + lookup_table[velocity>>1][instr->waveform_1>>2]; vol_1 =
(instr->oplvl_1 & 0x3F) +
lookup_table[velocity >> 1][instr->waveform_1 >> 2];
if (vol_1 > 0x3F) if (vol_1 > 0x3F)
vol_1 = 0x3F; vol_1 = 0x3F;
mc->_vol_1 = vol_1; mc->_vol_1 = vol_1;
vol_2 = (instr->oplvl_2&0x3F) + lookup_table[velocity>>1][instr->waveform_2>>2]; vol_2 =
(instr->oplvl_2 & 0x3F) +
lookup_table[velocity >> 1][instr->waveform_2 >> 2];
if (vol_2 > 0x3F) if (vol_2 > 0x3F)
vol_2 = 0x3F; vol_2 = 0x3F;
mc->_vol_2 = vol_2; mc->_vol_2 = vol_2;
@ -736,29 +776,34 @@ void AdlibSoundDriver::mc_key_on(MidiChannel *mc2, byte note, byte velocity) {
vol_1 = volume_table[lookup_table[vol_1][c]]; vol_1 = volume_table[lookup_table[vol_1][c]];
adlib_setup_channel(mc->_channel, instr, vol_1, vol_2); adlib_setup_channel(mc->_channel, instr, vol_1, vol_2);
adlib_note_on_ex(mc->_channel, part->_transpose_eff + note, part->_detune_eff + part->_pitchbend); adlib_note_on_ex(mc->_channel, part->_transpose_eff + note,
part->_detune_eff + part->_pitchbend);
if (instr->flags_a & 0x80) { if (instr->flags_a & 0x80) {
mc_init_stuff(mc, &mc->_s10a, &mc->_s11a, instr->flags_a, &instr->extra_a); mc_init_stuff(mc, &mc->_s10a, &mc->_s11a, instr->flags_a,
&instr->extra_a);
} else { } else {
mc->_s10a.active = 0; mc->_s10a.active = 0;
} }
if (instr->flags_b & 0x80) { if (instr->flags_b & 0x80) {
mc_init_stuff(mc, &mc->_s10b, &mc->_s11b, instr->flags_b, &instr->extra_b); mc_init_stuff(mc, &mc->_s10b, &mc->_s11b, instr->flags_b,
&instr->extra_b);
} else { } else {
mc->_s10b.active = 0; mc->_s10b.active = 0;
} }
} }
void AdlibSoundDriver::set_instrument(uint slot, byte *data) { void AdlibSoundDriver::set_instrument(uint slot, byte *data)
{
if (slot < 32) { if (slot < 32) {
memcpy(&_glob_instr[slot], data, sizeof(Instrument)); memcpy(&_glob_instr[slot], data, sizeof(Instrument));
} }
} }
void AdlibSoundDriver::link_mc(Part *part, MidiChannelAdl *mc) { void AdlibSoundDriver::link_mc(Part *part, MidiChannelAdl *mc)
{
mc->_part = part; mc->_part = part;
mc->_next = (MidiChannelAdl *)part->_mc; mc->_next = (MidiChannelAdl *)part->_mc;
part->_mc = mc; part->_mc = mc;
@ -768,7 +813,8 @@ void AdlibSoundDriver::link_mc(Part *part, MidiChannelAdl *mc) {
mc->_next->_prev = mc; mc->_next->_prev = mc;
} }
void AdlibSoundDriver::part_key_on(Part *part, byte note, byte velocity) { void AdlibSoundDriver::part_key_on(Part *part, byte note, byte velocity)
{
MidiChannelAdl *mc; MidiChannelAdl *mc;
mc = allocate_midichan(part->_pri_eff); mc = allocate_midichan(part->_pri_eff);
@ -779,7 +825,8 @@ void AdlibSoundDriver::part_key_on(Part *part, byte note, byte velocity) {
mc_key_on(mc, note, velocity); mc_key_on(mc, note, velocity);
} }
void AdlibSoundDriver::part_key_off(Part *part, byte note) { void AdlibSoundDriver::part_key_off(Part *part, byte note)
{
MidiChannelAdl *mc; MidiChannelAdl *mc;
for (mc = (MidiChannelAdl *)part->_mc; mc; mc = mc->_next) { for (mc = (MidiChannelAdl *)part->_mc; mc; mc = mc->_next) {
@ -877,7 +924,8 @@ static const AdlibInstrSetParams adlib_instr_params[69] = {
}; };
#undef MKLINE #undef MKLINE
void AdlibSoundDriver::part_set_param(Part *part, byte param, int value) { void AdlibSoundDriver::part_set_param(Part *part, byte param, int value)
{
const AdlibInstrSetParams *sp = &adlib_instr_params[param]; const AdlibInstrSetParams *sp = &adlib_instr_params[param];
byte *p = (byte *)&_part_instr[part->_slot] + sp->param; byte *p = (byte *)&_part_instr[part->_slot] + sp->param;
*p = (*p & ~sp->mask) | (value << sp->shl); *p = (*p & ~sp->mask) | (value << sp->shl);
@ -891,7 +939,8 @@ void AdlibSoundDriver::part_set_param(Part *part, byte param, int value) {
} }
} }
void AdlibSoundDriver::part_off(Part *part) { void AdlibSoundDriver::part_off(Part *part)
{
MidiChannelAdl *mc = (MidiChannelAdl *)part->_mc; MidiChannelAdl *mc = (MidiChannelAdl *)part->_mc;
part->_mc = NULL; part->_mc = NULL;
for (; mc; mc = mc->_next) { for (; mc; mc = mc->_next) {
@ -899,7 +948,8 @@ void AdlibSoundDriver::part_off(Part *part) {
} }
} }
void AdlibSoundDriver::mc_off(MidiChannel *mc2) { void AdlibSoundDriver::mc_off(MidiChannel * mc2)
{
MidiChannelAdl *mc = (MidiChannelAdl *)mc2, *tmp; MidiChannelAdl *mc = (MidiChannelAdl *)mc2, *tmp;
adlib_key_off(mc->_channel); adlib_key_off(mc->_channel);
@ -915,12 +965,14 @@ void AdlibSoundDriver::mc_off(MidiChannel *mc2) {
mc->_part = NULL; mc->_part = NULL;
} }
void AdlibSoundDriver::part_set_instrument(Part *part, Instrument *instr) { void AdlibSoundDriver::part_set_instrument(Part *part, Instrument * instr)
{
Instrument *i = &_part_instr[part->_slot]; Instrument *i = &_part_instr[part->_slot];
memcpy(i, instr, sizeof(Instrument)); memcpy(i, instr, sizeof(Instrument));
} }
int AdlibSoundDriver::part_update_active(Part *part,uint16 *active) { int AdlibSoundDriver::part_update_active(Part *part, uint16 *active)
{
uint16 bits; uint16 bits;
int count = 0; int count = 0;
MidiChannelAdl *mc; MidiChannelAdl *mc;

View file

@ -85,8 +85,7 @@
#define ENV_MOD_AR 0x02 #define ENV_MOD_AR 0x02
/* -------------------- tables --------------------- */ /* -------------------- tables --------------------- */
static const int slot_array[32]= static const int slot_array[32] = {
{
0, 2, 4, 1, 3, 5, -1, -1, 0, 2, 4, 1, 3, 5, -1, -1,
6, 8, 10, 7, 9, 11, -1, -1, 6, 8, 10, 7, 9, 11, -1, -1,
12, 14, 16, 13, 15, 17, -1, -1, 12, 14, 16, 13, 15, 17, -1, -1,
@ -98,8 +97,7 @@ static const int slot_array[32]=
#define SC(mydb) ((UINT32) (mydb / (EG_STEP/2))) #define SC(mydb) ((UINT32) (mydb / (EG_STEP/2)))
static const UINT32 KSL_TABLE[8*16]= static const UINT32 KSL_TABLE[8 * 16] = {
{
/* OCT 0 */ /* OCT 0 */
SC(0.000), SC(0.000), SC(0.000), SC(0.000), SC(0.000), SC(0.000), SC(0.000), SC(0.000),
SC(0.000), SC(0.000), SC(0.000), SC(0.000), SC(0.000), SC(0.000), SC(0.000), SC(0.000),
@ -173,14 +171,15 @@ static INT32 ENV_CURVE[2*EG_ENT+1];
#define ML(x) (UINT32)(2*(x)) #define ML(x) (UINT32)(2*(x))
static const UINT32 MUL_TABLE[16] = { static const UINT32 MUL_TABLE[16] = {
/* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 */ /* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 */
ML(0.50), ML(1.00), ML(2.00), ML(3.00), ML(4.00), ML(5.00), ML(6.00), ML(7.00), ML(0.50), ML(1.00), ML(2.00), ML(3.00), ML(4.00), ML(5.00), ML(6.00),
ML(8.00), ML(9.00),ML(10.00),ML(10.00),ML(12.00),ML(12.00),ML(15.00),ML(15.00) ML(7.00),
ML(8.00), ML(9.00), ML(10.00), ML(10.00), ML(12.00), ML(12.00), ML(15.00),
ML(15.00)
}; };
#undef ML #undef ML
/* dummy attack / decay rate ( when rate == 0 ) */ /* dummy attack / decay rate ( when rate == 0 ) */
static INT32 RATE_0[16]= static INT32 RATE_0[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
/* -------------------- static state --------------------- */ /* -------------------- static state --------------------- */
@ -206,7 +205,8 @@ static INT32 feedback2; /* connect for SLOT 2 */
/* --------------------- subroutines --------------------- */ /* --------------------- subroutines --------------------- */
INLINE int Limit( int val, int max, int min ) { INLINE int Limit(int val, int max, int min)
{
if (val > max) if (val > max)
val = max; val = max;
else if (val < min) else if (val < min)
@ -220,13 +220,12 @@ INLINE void OPL_STATUS_SET(FM_OPL *OPL,int flag)
{ {
/* set status flag */ /* set status flag */
OPL->status |= flag; OPL->status |= flag;
if(!(OPL->status & 0x80)) if (!(OPL->status & 0x80)) {
{ if (OPL->status & OPL->statusmask) { /* IRQ on */
if(OPL->status & OPL->statusmask)
{ /* IRQ on */
OPL->status |= 0x80; OPL->status |= 0x80;
/* callback user interrupt handler (IRQ is OFF to ON) */ /* callback user interrupt handler (IRQ is OFF to ON) */
if(OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,1); if (OPL->IRQHandler)
(OPL->IRQHandler) (OPL->IRQParam, 1);
} }
} }
} }
@ -236,13 +235,12 @@ INLINE void OPL_STATUS_RESET(FM_OPL *OPL,int flag)
{ {
/* reset status flag */ /* reset status flag */
OPL->status &= ~flag; OPL->status &= ~flag;
if((OPL->status & 0x80)) if ((OPL->status & 0x80)) {
{ if (!(OPL->status & OPL->statusmask)) {
if (!(OPL->status & OPL->statusmask) )
{
OPL->status &= 0x7f; OPL->status &= 0x7f;
/* callback user interrupt handler (IRQ is ON to OFF) */ /* callback user interrupt handler (IRQ is ON to OFF) */
if(OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,0); if (OPL->IRQHandler)
(OPL->IRQHandler) (OPL->IRQParam, 0);
} }
} }
} }
@ -270,8 +268,7 @@ INLINE void OPL_KEYON(OPL_SLOT *SLOT)
/* ----- key off ----- */ /* ----- key off ----- */
INLINE void OPL_KEYOFF(OPL_SLOT * SLOT) INLINE void OPL_KEYOFF(OPL_SLOT * SLOT)
{ {
if( SLOT->evm > ENV_MOD_RR) if (SLOT->evm > ENV_MOD_RR) {
{
/* set envelope counter from envleope output */ /* set envelope counter from envleope output */
SLOT->evm = ENV_MOD_RR; SLOT->evm = ENV_MOD_RR;
if (!(SLOT->evc & EG_DST)) if (!(SLOT->evc & EG_DST))
@ -287,8 +284,7 @@ INLINE void OPL_KEYOFF(OPL_SLOT *SLOT)
INLINE UINT32 OPL_CALC_SLOT(OPL_SLOT * SLOT) INLINE UINT32 OPL_CALC_SLOT(OPL_SLOT * SLOT)
{ {
/* calcrate envelope generator */ /* calcrate envelope generator */
if( (SLOT->evc+=SLOT->evs) >= SLOT->eve ) if ((SLOT->evc += SLOT->evs) >= SLOT->eve) {
{
switch (SLOT->evm) { switch (SLOT->evm) {
case ENV_MOD_AR: /* ATTACK -> DECAY1 */ case ENV_MOD_AR: /* ATTACK -> DECAY1 */
/* next DR */ /* next DR */
@ -300,12 +296,9 @@ INLINE UINT32 OPL_CALC_SLOT( OPL_SLOT *SLOT )
case ENV_MOD_DR: /* DECAY -> SL or RR */ case ENV_MOD_DR: /* DECAY -> SL or RR */
SLOT->evc = SLOT->SL; SLOT->evc = SLOT->SL;
SLOT->eve = EG_DED; SLOT->eve = EG_DED;
if(SLOT->eg_typ) if (SLOT->eg_typ) {
{
SLOT->evs = 0; SLOT->evs = 0;
} } else {
else
{
SLOT->evm = ENV_MOD_RR; SLOT->evm = ENV_MOD_RR;
SLOT->evs = SLOT->evsr; SLOT->evs = SLOT->evsr;
} }
@ -338,8 +331,7 @@ INLINE void CALC_FCSLOT(OPL_CH *CH,OPL_SLOT *SLOT)
SLOT->Incr = CH->fc * SLOT->mul; SLOT->Incr = CH->fc * SLOT->mul;
ksr = CH->kcode >> SLOT->KSR; ksr = CH->kcode >> SLOT->KSR;
if( SLOT->ksr != ksr ) if (SLOT->ksr != ksr) {
{
SLOT->ksr = ksr; SLOT->ksr = ksr;
/* attack , decay rate recalcration */ /* attack , decay rate recalcration */
SLOT->evsa = SLOT->AR[ksr]; SLOT->evsa = SLOT->AR[ksr];
@ -373,8 +365,7 @@ INLINE void set_ksl_tl(FM_OPL *OPL,int slot,int v)
SLOT->ksl = ksl ? 3 - ksl : 31; SLOT->ksl = ksl ? 3 - ksl : 31;
SLOT->TL = (INT32) ((v & 0x3f) * (0.75 / EG_STEP)); /* 0.75db step */ SLOT->TL = (INT32) ((v & 0x3f) * (0.75 / EG_STEP)); /* 0.75db step */
if( !(OPL->mode&0x80) ) if (!(OPL->mode & 0x80)) { /* not CSM latch total level */
{ /* not CSM latch total level */
SLOT->TLL = SLOT->TL + (CH->ksl_base >> SLOT->ksl); SLOT->TLL = SLOT->TL + (CH->ksl_base >> SLOT->ksl);
} }
} }
@ -389,11 +380,13 @@ INLINE void set_ar_dr(FM_OPL *OPL,int slot,int v)
SLOT->AR = ar ? &OPL->AR_TABLE[ar << 2] : RATE_0; SLOT->AR = ar ? &OPL->AR_TABLE[ar << 2] : RATE_0;
SLOT->evsa = SLOT->AR[SLOT->ksr]; SLOT->evsa = SLOT->AR[SLOT->ksr];
if( SLOT->evm == ENV_MOD_AR ) SLOT->evs = SLOT->evsa; if (SLOT->evm == ENV_MOD_AR)
SLOT->evs = SLOT->evsa;
SLOT->DR = dr ? &OPL->DR_TABLE[dr << 2] : RATE_0; SLOT->DR = dr ? &OPL->DR_TABLE[dr << 2] : RATE_0;
SLOT->evsd = SLOT->DR[SLOT->ksr]; SLOT->evsd = SLOT->DR[SLOT->ksr];
if( SLOT->evm == ENV_MOD_DR ) SLOT->evs = SLOT->evsd; if (SLOT->evm == ENV_MOD_DR)
SLOT->evs = SLOT->evsd;
} }
/* set sustain level & release rate */ /* set sustain level & release rate */
@ -405,10 +398,12 @@ INLINE void set_sl_rr(FM_OPL *OPL,int slot,int v)
int rr = v & 0x0f; int rr = v & 0x0f;
SLOT->SL = SL_TABLE[sl]; SLOT->SL = SL_TABLE[sl];
if( SLOT->evm == ENV_MOD_DR ) SLOT->eve = SLOT->SL; if (SLOT->evm == ENV_MOD_DR)
SLOT->eve = SLOT->SL;
SLOT->RR = &OPL->DR_TABLE[rr << 2]; SLOT->RR = &OPL->DR_TABLE[rr << 2];
SLOT->evsr = SLOT->RR[SLOT->ksr]; SLOT->evsr = SLOT->RR[SLOT->ksr];
if( SLOT->evm == ENV_MOD_RR ) SLOT->evs = SLOT->evsr; if (SLOT->evm == ENV_MOD_RR)
SLOT->evs = SLOT->evsr;
} }
/* operator output calcrator */ /* operator output calcrator */
@ -423,35 +418,33 @@ INLINE void OPL_CALC_CH( OPL_CH *CH )
/* SLOT 1 */ /* SLOT 1 */
SLOT = &CH->SLOT[SLOT1]; SLOT = &CH->SLOT[SLOT1];
env_out = OPL_CALC_SLOT(SLOT); env_out = OPL_CALC_SLOT(SLOT);
if( env_out < EG_ENT-1 ) if (env_out < EG_ENT - 1) {
{
/* PG */ /* PG */
if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE); if (SLOT->vib)
else SLOT->Cnt += SLOT->Incr; SLOT->Cnt += (SLOT->Incr * vib / VIB_RATE);
else
SLOT->Cnt += SLOT->Incr;
/* connectoion */ /* connectoion */
if(CH->FB) if (CH->FB) {
{
int feedback1 = (CH->op1_out[0] + CH->op1_out[1]) >> CH->FB; int feedback1 = (CH->op1_out[0] + CH->op1_out[1]) >> CH->FB;
CH->op1_out[1] = CH->op1_out[0]; CH->op1_out[1] = CH->op1_out[0];
*CH->connect1 += CH->op1_out[0] = OP_OUT(SLOT, env_out, feedback1); *CH->connect1 += CH->op1_out[0] = OP_OUT(SLOT, env_out, feedback1);
} } else {
else
{
*CH->connect1 += OP_OUT(SLOT, env_out, 0); *CH->connect1 += OP_OUT(SLOT, env_out, 0);
} }
}else } else {
{
CH->op1_out[1] = CH->op1_out[0]; CH->op1_out[1] = CH->op1_out[0];
CH->op1_out[0] = 0; CH->op1_out[0] = 0;
} }
/* SLOT 2 */ /* SLOT 2 */
SLOT = &CH->SLOT[SLOT2]; SLOT = &CH->SLOT[SLOT2];
env_out = OPL_CALC_SLOT(SLOT); env_out = OPL_CALC_SLOT(SLOT);
if( env_out < EG_ENT-1 ) if (env_out < EG_ENT - 1) {
{
/* PG */ /* PG */
if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE); if (SLOT->vib)
else SLOT->Cnt += SLOT->Incr; SLOT->Cnt += (SLOT->Incr * vib / VIB_RATE);
else
SLOT->Cnt += SLOT->Incr;
/* connectoion */ /* connectoion */
outd[0] += OP_OUT(SLOT, env_out, feedback2); outd[0] += OP_OUT(SLOT, env_out, feedback2);
} }
@ -473,24 +466,21 @@ INLINE void OPL_CALC_RH( OPL_CH *CH )
/* SLOT 1 */ /* SLOT 1 */
SLOT = &CH[6].SLOT[SLOT1]; SLOT = &CH[6].SLOT[SLOT1];
env_out = OPL_CALC_SLOT(SLOT); env_out = OPL_CALC_SLOT(SLOT);
if( env_out < EG_ENT-1 ) if (env_out < EG_ENT - 1) {
{
/* PG */ /* PG */
if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE); if (SLOT->vib)
else SLOT->Cnt += SLOT->Incr; SLOT->Cnt += (SLOT->Incr * vib / VIB_RATE);
else
SLOT->Cnt += SLOT->Incr;
/* connectoion */ /* connectoion */
if(CH[6].FB) if (CH[6].FB) {
{
int feedback1 = (CH[6].op1_out[0] + CH[6].op1_out[1]) >> CH[6].FB; int feedback1 = (CH[6].op1_out[0] + CH[6].op1_out[1]) >> CH[6].FB;
CH[6].op1_out[1] = CH[6].op1_out[0]; CH[6].op1_out[1] = CH[6].op1_out[0];
feedback2 = CH[6].op1_out[0] = OP_OUT(SLOT, env_out, feedback1); feedback2 = CH[6].op1_out[0] = OP_OUT(SLOT, env_out, feedback1);
} } else {
else
{
feedback2 = OP_OUT(SLOT, env_out, 0); feedback2 = OP_OUT(SLOT, env_out, 0);
} }
}else } else {
{
feedback2 = 0; feedback2 = 0;
CH[6].op1_out[1] = CH[6].op1_out[0]; CH[6].op1_out[1] = CH[6].op1_out[0];
CH[6].op1_out[0] = 0; CH[6].op1_out[0] = 0;
@ -498,15 +488,15 @@ INLINE void OPL_CALC_RH( OPL_CH *CH )
/* SLOT 2 */ /* SLOT 2 */
SLOT = &CH[6].SLOT[SLOT2]; SLOT = &CH[6].SLOT[SLOT2];
env_out = OPL_CALC_SLOT(SLOT); env_out = OPL_CALC_SLOT(SLOT);
if( env_out < EG_ENT-1 ) if (env_out < EG_ENT - 1) {
{
/* PG */ /* PG */
if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE); if (SLOT->vib)
else SLOT->Cnt += SLOT->Incr; SLOT->Cnt += (SLOT->Incr * vib / VIB_RATE);
else
SLOT->Cnt += SLOT->Incr;
/* connectoion */ /* connectoion */
outd[0] += OP_OUT(SLOT, env_out, feedback2) * 2; outd[0] += OP_OUT(SLOT, env_out, feedback2) * 2;
} }
// SD (17) = mul14[fnum7] + white noise // SD (17) = mul14[fnum7] + white noise
// TAM (15) = mul15[fnum8] // TAM (15) = mul15[fnum8]
// TOP (18) = fnum6(mul18[fnum8]+whitenoise) // TOP (18) = fnum6(mul18[fnum8]+whitenoise)
@ -517,14 +507,22 @@ INLINE void OPL_CALC_RH( OPL_CH *CH )
env_hh = OPL_CALC_SLOT(SLOT7_1) + whitenoise; env_hh = OPL_CALC_SLOT(SLOT7_1) + whitenoise;
/* PG */ /* PG */
if(SLOT7_1->vib) SLOT7_1->Cnt += (2*SLOT7_1->Incr*vib/VIB_RATE); if (SLOT7_1->vib)
else SLOT7_1->Cnt += 2*SLOT7_1->Incr; SLOT7_1->Cnt += (2 * SLOT7_1->Incr * vib / VIB_RATE);
if(SLOT7_2->vib) SLOT7_2->Cnt += ((CH[7].fc*8)*vib/VIB_RATE); else
else SLOT7_2->Cnt += (CH[7].fc*8); SLOT7_1->Cnt += 2 * SLOT7_1->Incr;
if(SLOT8_1->vib) SLOT8_1->Cnt += (SLOT8_1->Incr*vib/VIB_RATE); if (SLOT7_2->vib)
else SLOT8_1->Cnt += SLOT8_1->Incr; SLOT7_2->Cnt += ((CH[7].fc * 8) * vib / VIB_RATE);
if(SLOT8_2->vib) SLOT8_2->Cnt += ((CH[8].fc*48)*vib/VIB_RATE); else
else SLOT8_2->Cnt += (CH[8].fc*48); SLOT7_2->Cnt += (CH[7].fc * 8);
if (SLOT8_1->vib)
SLOT8_1->Cnt += (SLOT8_1->Incr * vib / VIB_RATE);
else
SLOT8_1->Cnt += SLOT8_1->Incr;
if (SLOT8_2->vib)
SLOT8_2->Cnt += ((CH[8].fc * 48) * vib / VIB_RATE);
else
SLOT8_2->Cnt += (CH[8].fc * 48);
tone8 = OP_OUT(SLOT8_2, whitenoise, 0); tone8 = OP_OUT(SLOT8_2, whitenoise, 0);
@ -549,17 +547,18 @@ static void init_timetables( FM_OPL *OPL , int ARRATE , int DRRATE )
double rate; double rate;
/* make attack rate & decay rate tables */ /* make attack rate & decay rate tables */
for (i = 0;i < 4;i++) OPL->AR_TABLE[i] = OPL->DR_TABLE[i] = 0; for (i = 0; i < 4; i++)
OPL->AR_TABLE[i] = OPL->DR_TABLE[i] = 0;
for (i = 4; i <= 60; i++) { for (i = 4; i <= 60; i++) {
rate = OPL->freqbase; /* frequency rate */ rate = OPL->freqbase; /* frequency rate */
if( i < 60 ) rate *= 1.0+(i&3)*0.25; /* b0-1 : x1 , x1.25 , x1.5 , x1.75 */ if (i < 60)
rate *= 1.0 + (i & 3) * 0.25; /* b0-1 : x1 , x1.25 , x1.5 , x1.75 */
rate *= 1 << ((i >> 2) - 1); /* b2-5 : shift bit */ rate *= 1 << ((i >> 2) - 1); /* b2-5 : shift bit */
rate *= (double)(EG_ENT << ENV_BITS); rate *= (double)(EG_ENT << ENV_BITS);
OPL->AR_TABLE[i] = (int)(rate / ARRATE); OPL->AR_TABLE[i] = (int)(rate / ARRATE);
OPL->DR_TABLE[i] = (int)(rate / DRRATE); OPL->DR_TABLE[i] = (int)(rate / DRRATE);
} }
for (i = 60;i < 75;i++) for (i = 60; i < 75; i++) {
{
OPL->AR_TABLE[i] = EG_AED - 1; OPL->AR_TABLE[i] = EG_AED - 1;
OPL->DR_TABLE[i] = OPL->DR_TABLE[60]; OPL->DR_TABLE[i] = OPL->DR_TABLE[60];
} }
@ -576,19 +575,16 @@ static int OPLOpenTable( void )
/* allocate dynamic tables */ /* allocate dynamic tables */
if ((TL_TABLE = (INT32 *) malloc(TL_MAX * 2 * sizeof(INT32))) == NULL) if ((TL_TABLE = (INT32 *) malloc(TL_MAX * 2 * sizeof(INT32))) == NULL)
return 0; return 0;
if( (SIN_TABLE = (INT32**)malloc(SIN_ENT*4 *sizeof(INT32 *))) == NULL) if ((SIN_TABLE = (INT32 **) malloc(SIN_ENT * 4 * sizeof(INT32 *))) == NULL) {
{
free(TL_TABLE); free(TL_TABLE);
return 0; return 0;
} }
if( (AMS_TABLE = (INT32*)malloc(AMS_ENT*2 *sizeof(INT32))) == NULL) if ((AMS_TABLE = (INT32 *) malloc(AMS_ENT * 2 * sizeof(INT32))) == NULL) {
{
free(SIN_TABLE); free(SIN_TABLE);
free(TL_TABLE); free(TL_TABLE);
return 0; return 0;
} }
if( (VIB_TABLE = (INT32*)malloc(VIB_ENT*2 *sizeof(INT32))) == NULL) if ((VIB_TABLE = (INT32 *) malloc(VIB_ENT * 2 * sizeof(INT32))) == NULL) {
{
free(AMS_TABLE); free(AMS_TABLE);
free(TL_TABLE); free(TL_TABLE);
free(SIN_TABLE); free(SIN_TABLE);
@ -617,19 +613,21 @@ static int OPLOpenTable( void )
/* degree 0 - 90 , degree 180 - 90 : plus section */ /* degree 0 - 90 , degree 180 - 90 : plus section */
SIN_TABLE[s] = SIN_TABLE[SIN_ENT / 2 - s] = &TL_TABLE[j]; SIN_TABLE[s] = SIN_TABLE[SIN_ENT / 2 - s] = &TL_TABLE[j];
/* degree 180 - 270 , degree 360 - 270 : minus section */ /* degree 180 - 270 , degree 360 - 270 : minus section */
SIN_TABLE[SIN_ENT/2+s] = SIN_TABLE[SIN_ENT -s] = &TL_TABLE[TL_MAX+j]; SIN_TABLE[SIN_ENT / 2 + s] = SIN_TABLE[SIN_ENT - s] =
&TL_TABLE[TL_MAX + j];
/* LOG(LOG_INF,("sin(%3d) = %f:%f db\n",s,pom,(double)j * EG_STEP));*/ /* LOG(LOG_INF,("sin(%3d) = %f:%f db\n",s,pom,(double)j * EG_STEP));*/
} }
for (s = 0;s < SIN_ENT;s++) for (s = 0; s < SIN_ENT; s++) {
{ SIN_TABLE[SIN_ENT * 1 + s] =
SIN_TABLE[SIN_ENT*1+s] = s<(SIN_ENT/2) ? SIN_TABLE[s] : &TL_TABLE[EG_ENT]; s < (SIN_ENT / 2) ? SIN_TABLE[s] : &TL_TABLE[EG_ENT];
SIN_TABLE[SIN_ENT * 2 + s] = SIN_TABLE[s % (SIN_ENT / 2)]; SIN_TABLE[SIN_ENT * 2 + s] = SIN_TABLE[s % (SIN_ENT / 2)];
SIN_TABLE[SIN_ENT*3+s] = (s/(SIN_ENT/4))&1 ? &TL_TABLE[EG_ENT] : SIN_TABLE[SIN_ENT*2+s]; SIN_TABLE[SIN_ENT * 3 + s] =
(s / (SIN_ENT / 4)) & 1 ? &TL_TABLE[EG_ENT] : SIN_TABLE[SIN_ENT * 2 +
s];
} }
/* envelope counter -> envelope output table */ /* envelope counter -> envelope output table */
for (i=0; i<EG_ENT; i++) for (i = 0; i < EG_ENT; i++) {
{
/* ATTACK curve */ /* ATTACK curve */
pom = pow(((double)(EG_ENT - 1 - i) / EG_ENT), 8) * EG_ENT; pom = pow(((double)(EG_ENT - 1 - i) / EG_ENT), 8) * EG_ENT;
/* if( pom >= EG_ENT ) pom = EG_ENT-1; */ /* if( pom >= EG_ENT ) pom = EG_ENT-1; */
@ -640,15 +638,13 @@ static int OPLOpenTable( void )
/* off */ /* off */
ENV_CURVE[EG_OFF >> ENV_BITS] = EG_ENT - 1; ENV_CURVE[EG_OFF >> ENV_BITS] = EG_ENT - 1;
/* make LFO ams table */ /* make LFO ams table */
for (i=0; i<AMS_ENT; i++) for (i = 0; i < AMS_ENT; i++) {
{
pom = (1.0 + sin(2 * PI * i / AMS_ENT)) / 2; /* sin */ pom = (1.0 + sin(2 * PI * i / AMS_ENT)) / 2; /* sin */
AMS_TABLE[i] = (int)((1.0 / EG_STEP) * pom); /* 1dB */ AMS_TABLE[i] = (int)((1.0 / EG_STEP) * pom); /* 1dB */
AMS_TABLE[AMS_ENT + i] = (int)((4.8 / EG_STEP) * pom); /* 4.8dB */ AMS_TABLE[AMS_ENT + i] = (int)((4.8 / EG_STEP) * pom); /* 4.8dB */
} }
/* make LFO vibrate table */ /* make LFO vibrate table */
for (i=0; i<VIB_ENT; i++) for (i = 0; i < VIB_ENT; i++) {
{
/* 100cent = 1seminote = 6% ?? */ /* 100cent = 1seminote = 6% ?? */
pom = (double)VIB_RATE *0.06 * sin(2 * PI * i / VIB_ENT); /* +-100sect step */ pom = (double)VIB_RATE *0.06 * sin(2 * PI * i / VIB_ENT); /* +-100sect step */
VIB_TABLE[i] = (int)(VIB_RATE + (pom * 0.07)); /* +- 7cent */ VIB_TABLE[i] = (int)(VIB_RATE + (pom * 0.07)); /* +- 7cent */
@ -696,13 +692,16 @@ static void OPL_initalize(FM_OPL *OPL)
/* make time tables */ /* make time tables */
init_timetables(OPL, OPL_ARRATE, OPL_DRRATE); init_timetables(OPL, OPL_ARRATE, OPL_DRRATE);
/* make fnumber -> increment counter table */ /* make fnumber -> increment counter table */
for( fn=0 ; fn < 1024 ; fn++ ) for (fn = 0; fn < 1024; fn++) {
{
OPL->FN_TABLE[fn] = (int)(OPL->freqbase * fn * FREQ_RATE * (1 << 7) / 2); OPL->FN_TABLE[fn] = (int)(OPL->freqbase * fn * FREQ_RATE * (1 << 7) / 2);
} }
/* LFO freq.table */ /* LFO freq.table */
OPL->amsIncr = (INT32) (OPL->rate ? (double)AMS_ENT*(1<<AMS_SHIFT) / OPL->rate * 3.7 * ((double)OPL->clock/3600000) : 0); OPL->amsIncr =
OPL->vibIncr = (INT32) (OPL->rate ? (double)VIB_ENT*(1<<VIB_SHIFT) / OPL->rate * 6.4 * ((double)OPL->clock/3600000) : 0); (INT32) (OPL->rate ? (double)AMS_ENT * (1 << AMS_SHIFT) / OPL->rate *
3.7 * ((double)OPL->clock / 3600000) : 0);
OPL->vibIncr =
(INT32) (OPL->rate ? (double)VIB_ENT * (1 << VIB_SHIFT) / OPL->rate *
6.4 * ((double)OPL->clock / 3600000) : 0);
} }
/* ---------- write a OPL registers ---------- */ /* ---------- write a OPL registers ---------- */
@ -712,22 +711,17 @@ void OPLWriteReg(FM_OPL *OPL, int r, int v)
int slot; int slot;
unsigned int block_fnum; unsigned int block_fnum;
switch(r&0xe0) switch (r & 0xe0) {
{
case 0x00: /* 00-1f:controll */ case 0x00: /* 00-1f:controll */
switch(r&0x1f) switch (r & 0x1f) {
{
case 0x01: case 0x01:
/* wave selector enable */ /* wave selector enable */
if(OPL->type&OPL_TYPE_WAVESEL) if (OPL->type & OPL_TYPE_WAVESEL) {
{
OPL->wavesel = v & 0x20; OPL->wavesel = v & 0x20;
if(!OPL->wavesel) if (!OPL->wavesel) {
{
/* preset compatible mode */ /* preset compatible mode */
int c; int c;
for(c=0;c<OPL->max_ch;c++) for (c = 0; c < OPL->max_ch; c++) {
{
OPL->P_CH[c].SLOT[SLOT1].wavetable = &SIN_TABLE[0]; OPL->P_CH[c].SLOT[SLOT1].wavetable = &SIN_TABLE[0];
OPL->P_CH[c].SLOT[SLOT2].wavetable = &SIN_TABLE[0]; OPL->P_CH[c].SLOT[SLOT2].wavetable = &SIN_TABLE[0];
} }
@ -741,30 +735,27 @@ void OPLWriteReg(FM_OPL *OPL, int r, int v)
OPL->T[1] = (256 - v) * 16; OPL->T[1] = (256 - v) * 16;
return; return;
case 0x04: /* IRQ clear / mask and Timer enable */ case 0x04: /* IRQ clear / mask and Timer enable */
if(v&0x80) if (v & 0x80) { /* IRQ flag clear */
{ /* IRQ flag clear */
OPL_STATUS_RESET(OPL, 0x7f); OPL_STATUS_RESET(OPL, 0x7f);
} } else { /* set IRQ mask ,timer enable */
else
{ /* set IRQ mask ,timer enable*/
UINT8 st1 = v & 1; UINT8 st1 = v & 1;
UINT8 st2 = (v >> 1) & 1; UINT8 st2 = (v >> 1) & 1;
/* IRQRST,T1MSK,t2MSK,EOSMSK,BRMSK,x,ST2,ST1 */ /* IRQRST,T1MSK,t2MSK,EOSMSK,BRMSK,x,ST2,ST1 */
OPL_STATUS_RESET(OPL, v & 0x78); OPL_STATUS_RESET(OPL, v & 0x78);
OPL_STATUSMASK_SET(OPL, ((~v) & 0x78) | 0x01); OPL_STATUSMASK_SET(OPL, ((~v) & 0x78) | 0x01);
/* timer 2 */ /* timer 2 */
if(OPL->st[1] != st2) if (OPL->st[1] != st2) {
{
double interval = st2 ? (double)OPL->T[1] * OPL->TimerBase : 0.0; double interval = st2 ? (double)OPL->T[1] * OPL->TimerBase : 0.0;
OPL->st[1] = st2; OPL->st[1] = st2;
if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+1,interval); if (OPL->TimerHandler)
(OPL->TimerHandler) (OPL->TimerParam + 1, interval);
} }
/* timer 1 */ /* timer 1 */
if(OPL->st[0] != st1) if (OPL->st[0] != st1) {
{
double interval = st1 ? (double)OPL->T[0] * OPL->TimerBase : 0.0; double interval = st1 ? (double)OPL->T[0] * OPL->TimerBase : 0.0;
OPL->st[0] = st1; OPL->st[0] = st1;
if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+0,interval); if (OPL->TimerHandler)
(OPL->TimerHandler) (OPL->TimerParam + 0, interval);
} }
} }
return; return;
@ -772,27 +763,30 @@ void OPLWriteReg(FM_OPL *OPL, int r, int v)
break; break;
case 0x20: /* am,vib,ksr,eg type,mul */ case 0x20: /* am,vib,ksr,eg type,mul */
slot = slot_array[r & 0x1f]; slot = slot_array[r & 0x1f];
if(slot == -1) return; if (slot == -1)
return;
set_mul(OPL, slot, v); set_mul(OPL, slot, v);
return; return;
case 0x40: case 0x40:
slot = slot_array[r & 0x1f]; slot = slot_array[r & 0x1f];
if(slot == -1) return; if (slot == -1)
return;
set_ksl_tl(OPL, slot, v); set_ksl_tl(OPL, slot, v);
return; return;
case 0x60: case 0x60:
slot = slot_array[r & 0x1f]; slot = slot_array[r & 0x1f];
if(slot == -1) return; if (slot == -1)
return;
set_ar_dr(OPL, slot, v); set_ar_dr(OPL, slot, v);
return; return;
case 0x80: case 0x80:
slot = slot_array[r & 0x1f]; slot = slot_array[r & 0x1f];
if(slot == -1) return; if (slot == -1)
return;
set_sl_rr(OPL, slot, v); set_sl_rr(OPL, slot, v);
return; return;
case 0xa0: case 0xa0:
switch(r) switch (r) {
{
case 0xbd: case 0xbd:
/* amsep,vibdep,r,bd,sd,tom,tc,hh */ /* amsep,vibdep,r,bd,sd,tom,tc,hh */
{ {
@ -800,82 +794,74 @@ void OPLWriteReg(FM_OPL *OPL, int r, int v)
OPL->ams_table = &AMS_TABLE[v & 0x80 ? AMS_ENT : 0]; OPL->ams_table = &AMS_TABLE[v & 0x80 ? AMS_ENT : 0];
OPL->vib_table = &VIB_TABLE[v & 0x40 ? VIB_ENT : 0]; OPL->vib_table = &VIB_TABLE[v & 0x40 ? VIB_ENT : 0];
OPL->rythm = v & 0x3f; OPL->rythm = v & 0x3f;
if(OPL->rythm&0x20) if (OPL->rythm & 0x20) {
{
#if 0 #if 0
usrintf_showmessage("OPL Rythm mode select"); usrintf_showmessage("OPL Rythm mode select");
#endif #endif
/* BD key on/off */ /* BD key on/off */
if(rkey&0x10) if (rkey & 0x10) {
{ if (v & 0x10) {
if(v&0x10)
{
OPL->P_CH[6].op1_out[0] = OPL->P_CH[6].op1_out[1] = 0; OPL->P_CH[6].op1_out[0] = OPL->P_CH[6].op1_out[1] = 0;
OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT1]); OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT1]);
OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT2]); OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT2]);
} } else {
else
{
OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT1]); OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT1]);
OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT2]); OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT2]);
} }
} }
/* SD key on/off */ /* SD key on/off */
if(rkey&0x08) if (rkey & 0x08) {
{ if (v & 0x08)
if(v&0x08) OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT2]); OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT2]);
else OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT2]); else
OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT2]);
} /* TAM key on/off */ } /* TAM key on/off */
if(rkey&0x04) if (rkey & 0x04) {
{ if (v & 0x04)
if(v&0x04) OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT1]); OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT1]);
else OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT1]); else
OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT1]);
} }
/* TOP-CY key on/off */ /* TOP-CY key on/off */
if(rkey&0x02) if (rkey & 0x02) {
{ if (v & 0x02)
if(v&0x02) OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT2]); OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT2]);
else OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT2]); else
OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT2]);
} }
/* HH key on/off */ /* HH key on/off */
if(rkey&0x01) if (rkey & 0x01) {
{ if (v & 0x01)
if(v&0x01) OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT1]); OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT1]);
else OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT1]); else
OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT1]);
} }
} }
} }
return; return;
} }
/* keyon,block,fnum */ /* keyon,block,fnum */
if( (r&0x0f) > 8) return; if ((r & 0x0f) > 8)
return;
CH = &OPL->P_CH[r & 0x0f]; CH = &OPL->P_CH[r & 0x0f];
if(!(r&0x10)) if (!(r & 0x10)) { /* a0-a8 */
{ /* a0-a8 */
block_fnum = (CH->block_fnum & 0x1f00) | v; block_fnum = (CH->block_fnum & 0x1f00) | v;
} } else { /* b0-b8 */
else
{ /* b0-b8 */
int keyon = (v >> 5) & 1; int keyon = (v >> 5) & 1;
block_fnum = ((v & 0x1f) << 8) | (CH->block_fnum & 0xff); block_fnum = ((v & 0x1f) << 8) | (CH->block_fnum & 0xff);
if(CH->keyon != keyon) if (CH->keyon != keyon) {
{ if ((CH->keyon = keyon)) {
if( (CH->keyon=keyon) )
{
CH->op1_out[0] = CH->op1_out[1] = 0; CH->op1_out[0] = CH->op1_out[1] = 0;
OPL_KEYON(&CH->SLOT[SLOT1]); OPL_KEYON(&CH->SLOT[SLOT1]);
OPL_KEYON(&CH->SLOT[SLOT2]); OPL_KEYON(&CH->SLOT[SLOT2]);
} } else {
else
{
OPL_KEYOFF(&CH->SLOT[SLOT1]); OPL_KEYOFF(&CH->SLOT[SLOT1]);
OPL_KEYOFF(&CH->SLOT[SLOT2]); OPL_KEYOFF(&CH->SLOT[SLOT2]);
} }
} }
} }
/* update */ /* update */
if(CH->block_fnum != block_fnum) if (CH->block_fnum != block_fnum) {
{
int blockRv = 7 - (block_fnum >> 10); int blockRv = 7 - (block_fnum >> 10);
int fnum = block_fnum & 0x3ff; int fnum = block_fnum & 0x3ff;
CH->block_fnum = block_fnum; CH->block_fnum = block_fnum;
@ -883,14 +869,16 @@ void OPLWriteReg(FM_OPL *OPL, int r, int v)
CH->ksl_base = KSL_TABLE[block_fnum >> 6]; CH->ksl_base = KSL_TABLE[block_fnum >> 6];
CH->fc = OPL->FN_TABLE[fnum] >> blockRv; CH->fc = OPL->FN_TABLE[fnum] >> blockRv;
CH->kcode = CH->block_fnum >> 9; CH->kcode = CH->block_fnum >> 9;
if( (OPL->mode&0x40) && CH->block_fnum&0x100) CH->kcode |=1; if ((OPL->mode & 0x40) && CH->block_fnum & 0x100)
CH->kcode |= 1;
CALC_FCSLOT(CH, &CH->SLOT[SLOT1]); CALC_FCSLOT(CH, &CH->SLOT[SLOT1]);
CALC_FCSLOT(CH, &CH->SLOT[SLOT2]); CALC_FCSLOT(CH, &CH->SLOT[SLOT2]);
} }
return; return;
case 0xc0: case 0xc0:
/* FB,C */ /* FB,C */
if( (r&0x0f) > 8) return; if ((r & 0x0f) > 8)
return;
CH = &OPL->P_CH[r & 0x0f]; CH = &OPL->P_CH[r & 0x0f];
{ {
int feedback = (v >> 1) & 7; int feedback = (v >> 1) & 7;
@ -901,10 +889,10 @@ void OPLWriteReg(FM_OPL *OPL, int r, int v)
return; return;
case 0xe0: /* wave type */ case 0xe0: /* wave type */
slot = slot_array[r & 0x1f]; slot = slot_array[r & 0x1f];
if(slot == -1) return; if (slot == -1)
return;
CH = &OPL->P_CH[slot / 2]; CH = &OPL->P_CH[slot / 2];
if(OPL->wavesel) if (OPL->wavesel) {
{
/* LOG(LOG_INF,("OPL SLOT %d wave select %d\n",slot,v&3)); */ /* LOG(LOG_INF,("OPL SLOT %d wave select %d\n",slot,v&3)); */
CH->SLOT[slot & 1].wavetable = &SIN_TABLE[(v & 0x03) * SIN_ENT]; CH->SLOT[slot & 1].wavetable = &SIN_TABLE[(v & 0x03) * SIN_ENT];
} }
@ -916,12 +904,12 @@ void OPLWriteReg(FM_OPL *OPL, int r, int v)
static int OPL_LockTable(void) static int OPL_LockTable(void)
{ {
num_lock++; num_lock++;
if(num_lock>1) return 0; if (num_lock > 1)
return 0;
/* first time */ /* first time */
cur_chip = NULL; cur_chip = NULL;
/* allocate total level table (128kb space) */ /* allocate total level table (128kb space) */
if( !OPLOpenTable() ) if (!OPLOpenTable()) {
{
num_lock--; num_lock--;
return -1; return -1;
} }
@ -930,8 +918,10 @@ static int OPL_LockTable(void)
static void OPL_UnLockTable(void) static void OPL_UnLockTable(void)
{ {
if(num_lock) num_lock--; if (num_lock)
if(num_lock) return; num_lock--;
if (num_lock)
return;
/* last time */ /* last time */
cur_chip = NULL; cur_chip = NULL;
OPLCloseTable(); OPLCloseTable();
@ -969,8 +959,7 @@ void YM3812UpdateOne(FM_OPL *OPL, INT16 *buffer, int length)
vib_table = OPL->vib_table; vib_table = OPL->vib_table;
} }
R_CH = rythm ? &S_CH[6] : E_CH; R_CH = rythm ? &S_CH[6] : E_CH;
for( i=0; i < length ; i++ ) for (i = 0; i < length; i++) {
{
/* channel A channel B channel C */ /* channel A channel B channel C */
/* LFO */ /* LFO */
ams = ams_table[(amsCnt += amsIncr) >> AMS_SHIFT]; ams = ams_table[(amsCnt += amsIncr) >> AMS_SHIFT];
@ -1007,14 +996,13 @@ void OPLResetChip(FM_OPL *OPL)
OPLWriteReg(OPL, 0x02, 0); /* Timer1 */ OPLWriteReg(OPL, 0x02, 0); /* Timer1 */
OPLWriteReg(OPL, 0x03, 0); /* Timer2 */ OPLWriteReg(OPL, 0x03, 0); /* Timer2 */
OPLWriteReg(OPL, 0x04, 0); /* IRQ mask clear */ OPLWriteReg(OPL, 0x04, 0); /* IRQ mask clear */
for(i = 0xff ; i >= 0x20 ; i-- ) OPLWriteReg(OPL,i,0); for (i = 0xff; i >= 0x20; i--)
OPLWriteReg(OPL, i, 0);
/* reset OPerator paramater */ /* reset OPerator paramater */
for( c = 0 ; c < OPL->max_ch ; c++ ) for (c = 0; c < OPL->max_ch; c++) {
{
OPL_CH *CH = &OPL->P_CH[c]; OPL_CH *CH = &OPL->P_CH[c];
/* OPL->P_CH[c].PAN = OPN_CENTER; */ /* OPL->P_CH[c].PAN = OPN_CENTER; */
for(s = 0 ; s < 2 ; s++ ) for (s = 0; s < 2; s++) {
{
/* wave table */ /* wave table */
CH->SLOT[s].wavetable = &SIN_TABLE[0]; CH->SLOT[s].wavetable = &SIN_TABLE[0];
/* CH->SLOT[s].evm = ENV_MOD_RR; */ /* CH->SLOT[s].evm = ENV_MOD_RR; */
@ -1034,17 +1022,21 @@ FM_OPL *OPLCreate(int type, int clock, int rate)
int state_size; int state_size;
int max_ch = 9; /* normaly 9 channels */ int max_ch = 9; /* normaly 9 channels */
if( OPL_LockTable() ==-1) return NULL; if (OPL_LockTable() == -1)
return NULL;
/* allocate OPL state space */ /* allocate OPL state space */
state_size = sizeof(FM_OPL); state_size = sizeof(FM_OPL);
state_size += sizeof(OPL_CH) * max_ch; state_size += sizeof(OPL_CH) * max_ch;
/* allocate memory block */ /* allocate memory block */
ptr = (char *)malloc(state_size); ptr = (char *)malloc(state_size);
if(ptr==NULL) return NULL; if (ptr == NULL)
return NULL;
/* clear */ /* clear */
memset(ptr, 0, state_size); memset(ptr, 0, state_size);
OPL = (FM_OPL *)ptr; ptr+=sizeof(FM_OPL); OPL = (FM_OPL *) ptr;
OPL->P_CH = (OPL_CH *)ptr; ptr+=sizeof(OPL_CH)*max_ch; ptr += sizeof(FM_OPL);
OPL->P_CH = (OPL_CH *) ptr;
ptr += sizeof(OPL_CH) * max_ch;
/* set channel state pointer */ /* set channel state pointer */
OPL->type = type; OPL->type = type;
OPL->clock = clock; OPL->clock = clock;
@ -1066,7 +1058,8 @@ void OPLDestroy(FM_OPL *OPL)
/* ---------- Option handlers ---------- */ /* ---------- Option handlers ---------- */
void OPLSetTimerHandler(FM_OPL *OPL,OPL_TIMERHANDLER TimerHandler,int channelOffset) void OPLSetTimerHandler(FM_OPL * OPL, OPL_TIMERHANDLER TimerHandler,
int channelOffset)
{ {
OPL->TimerHandler = TimerHandler; OPL->TimerHandler = TimerHandler;
OPL->TimerParam = channelOffset; OPL->TimerParam = channelOffset;
@ -1076,7 +1069,8 @@ void OPLSetIRQHandler(FM_OPL *OPL,OPL_IRQHANDLER IRQHandler,int param)
OPL->IRQHandler = IRQHandler; OPL->IRQHandler = IRQHandler;
OPL->IRQParam = param; OPL->IRQParam = param;
} }
void OPLSetUpdateHandler(FM_OPL *OPL,OPL_UPDATEHANDLER UpdateHandler,int param) void OPLSetUpdateHandler(FM_OPL * OPL, OPL_UPDATEHANDLER UpdateHandler,
int param)
{ {
OPL->UpdateHandler = UpdateHandler; OPL->UpdateHandler = UpdateHandler;
OPL->UpdateParam = param; OPL->UpdateParam = param;
@ -1084,23 +1078,22 @@ void OPLSetUpdateHandler(FM_OPL *OPL,OPL_UPDATEHANDLER UpdateHandler,int param)
int OPLTimerOver(FM_OPL * OPL, int c) int OPLTimerOver(FM_OPL * OPL, int c)
{ {
if( c ) if (c) { /* Timer B */
{ /* Timer B */
OPL_STATUS_SET(OPL, 0x20); OPL_STATUS_SET(OPL, 0x20);
} } else { /* Timer A */
else
{ /* Timer A */
OPL_STATUS_SET(OPL, 0x40); OPL_STATUS_SET(OPL, 0x40);
/* CSM mode key,TL controll */ /* CSM mode key,TL controll */
if( OPL->mode & 0x80 ) if (OPL->mode & 0x80) { /* CSM mode total level latch and auto key on */
{ /* CSM mode total level latch and auto key on */
int ch; int ch;
if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam,0); if (OPL->UpdateHandler)
OPL->UpdateHandler(OPL->UpdateParam, 0);
for (ch = 0; ch < 9; ch++) for (ch = 0; ch < 9; ch++)
CSMKeyControll(&OPL->P_CH[ch]); CSMKeyControll(&OPL->P_CH[ch]);
} }
} }
/* reload timer */ /* reload timer */
if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+c,(double)OPL->T[c]*OPL->TimerBase); if (OPL->TimerHandler)
(OPL->TimerHandler) (OPL->TimerParam + c,
(double)OPL->T[c] * OPL->TimerBase);
return OPL->status >> 7; return OPL->status >> 7;
} }

View file

@ -35,12 +35,14 @@
#include "scumm.h" #include "scumm.h"
#include "gmidi.h" #include "gmidi.h"
void MidiSoundDriver::midiSetDriver(int devicetype) { void MidiSoundDriver::midiSetDriver(int devicetype)
{
_midi_driver.DeviceType = devicetype; _midi_driver.DeviceType = devicetype;
_midi_driver.midiInit(); _midi_driver.midiInit();
} }
void MidiDriver::midiInit() { void MidiDriver::midiInit()
{
if (MidiInitialized != true) { if (MidiInitialized != true) {
switch (DeviceType) { switch (DeviceType) {
case MIDI_NULL: case MIDI_NULL:
@ -71,7 +73,8 @@ void MidiDriver::midiInit() {
} }
} }
void MidiDriver::MidiOut(int b) { void MidiDriver::MidiOut(int b)
{
if (MidiInitialized != true) if (MidiInitialized != true)
midiInit(); midiInit();
@ -102,39 +105,47 @@ void MidiDriver::MidiOut(int b) {
} }
/*********** Windows */ /*********** Windows */
void MidiDriver::midiInitWindows() { void MidiDriver::midiInitWindows()
{
#ifdef WIN32 #ifdef WIN32
if (midiOutOpen((HMIDIOUT*)&_mo, MIDI_MAPPER, NULL, NULL, 0) != MMSYSERR_NOERROR) if (midiOutOpen((HMIDIOUT *) & _mo, MIDI_MAPPER, NULL, NULL, 0) !=
MMSYSERR_NOERROR)
error("midiOutOpen failed"); error("midiOutOpen failed");
#endif #endif
} }
void MidiDriver::MidiOutWindows(void *a, int b) { void MidiDriver::MidiOutWindows(void *a, int b)
{
#ifdef WIN32 #ifdef WIN32
midiOutShortMsg((HMIDIOUT) a, b); midiOutShortMsg((HMIDIOUT) a, b);
#endif #endif
} }
/*********** Raw midi support */ /*********** Raw midi support */
void MidiDriver::midiInitSeq() { void MidiDriver::midiInitSeq()
{
int device = open_sequencer_device(); int device = open_sequencer_device();
_mo = (void *)device; _mo = (void *)device;
} }
int MidiDriver::open_sequencer_device() { int MidiDriver::open_sequencer_device()
{
int device = 0; int device = 0;
#if !defined(__APPLE__CW) // No getenv support on Apple Carbon #if !defined(__APPLE__CW) // No getenv support on Apple Carbon
char *device_name = getenv("SCUMMVM_MIDI"); char *device_name = getenv("SCUMMVM_MIDI");
if (device_name != NULL) { if (device_name != NULL) {
device = (open((device_name), O_RDWR, 0)); device = (open((device_name), O_RDWR, 0));
} else { } else {
warning("You need to set-up the SCUMMVM_MIDI environment variable properly (see readme.txt) "); warning
("You need to set-up the SCUMMVM_MIDI environment variable properly (see readme.txt) ");
} }
if ((device_name == NULL) || (device < 0)) { if ((device_name == NULL) || (device < 0)) {
if (device_name == NULL) if (device_name == NULL)
warning("Opening /dev/null (no music will be heard) "); warning("Opening /dev/null (no music will be heard) ");
else else
warning("Cannot open rawmidi device %s - using /dev/null (no music will be heard) ", device_name); warning
("Cannot open rawmidi device %s - using /dev/null (no music will be heard) ",
device_name);
device = (open(("/dev/null"), O_RDWR, 0)); device = (open(("/dev/null"), O_RDWR, 0));
if (device < 0) if (device < 0)
error("Cannot open /dev/null to dump midi output"); error("Cannot open /dev/null to dump midi output");
@ -144,7 +155,8 @@ int MidiDriver::open_sequencer_device() {
} }
/*********** Timidity */ /*********** Timidity */
int MidiDriver::connect_to_timidity(int port) { int MidiDriver::connect_to_timidity(int port)
{
int s = 0; int s = 0;
#if !defined(__APPLE__CW) && !defined(__MORPHOS__) // No socket support on Apple Carbon or Morphos #if !defined(__APPLE__CW) && !defined(__MORPHOS__) // No socket support on Apple Carbon or Morphos
struct hostent *serverhost; struct hostent *serverhost;
@ -168,7 +180,8 @@ int MidiDriver::connect_to_timidity(int port) {
return s; return s;
} }
void MidiDriver::midiInitTimidity() { void MidiDriver::midiInitTimidity()
{
int s, s2; int s, s2;
int len; int len;
int dummy, newport; int dummy, newport;
@ -191,7 +204,8 @@ void MidiDriver::midiInitTimidity() {
_mo = (void *)s2; _mo = (void *)s2;
} }
void MidiDriver::MidiOutSeq(void *a, int b) { void MidiDriver::MidiOutSeq(void *a, int b)
{
int s = (int)a; int s = (int)a;
unsigned char buf[256]; unsigned char buf[256];
int position = 0; int position = 0;
@ -234,7 +248,8 @@ void MidiDriver::MidiOutSeq(void *a, int b) {
} }
/* Quicktime music support */ /* Quicktime music support */
void MidiDriver::midiInitQuicktime() { void MidiDriver::midiInitQuicktime()
{
#ifdef __APPLE__CW #ifdef __APPLE__CW
ComponentResult qtErr = noErr; ComponentResult qtErr = noErr;
qtNoteAllocator = NULL; qtNoteAllocator = NULL;
@ -248,21 +263,25 @@ void MidiDriver::midiInitQuicktime() {
simpleNoteRequest.info.flags = 0; simpleNoteRequest.info.flags = 0;
*(short *)(&simpleNoteRequest.info.polyphony) = EndianS16_NtoB(15); // simultaneous tones *(short *)(&simpleNoteRequest.info.polyphony) = EndianS16_NtoB(15); // simultaneous tones
*(Fixed *)(&simpleNoteRequest.info.typicalPolyphony) = EndianU32_NtoB(0x00010000); *(Fixed *) (&simpleNoteRequest.info.typicalPolyphony) =
EndianU32_NtoB(0x00010000);
qtErr = NAStuffToneDescription(qtNoteAllocator, 1, &simpleNoteRequest.tone); qtErr = NAStuffToneDescription(qtNoteAllocator, 1, &simpleNoteRequest.tone);
if (qtErr != noErr) if (qtErr != noErr)
goto bail; goto bail;
for (int i = 0; i < 15; i++) { for (int i = 0; i < 15; i++) {
qtErr = NANewNoteChannel(qtNoteAllocator, &simpleNoteRequest, &(qtNoteChannel[i])); qtErr =
NANewNoteChannel(qtNoteAllocator, &simpleNoteRequest,
&(qtNoteChannel[i]));
if ((qtErr != noErr) || (qtNoteChannel == NULL)) if ((qtErr != noErr) || (qtNoteChannel == NULL))
goto bail; goto bail;
} }
return; return;
bail: bail:
fprintf(stderr, "Init QT failed %x %x %d\n", qtNoteAllocator, qtNoteChannel, qtErr); fprintf(stderr, "Init QT failed %x %x %d\n", qtNoteAllocator, qtNoteChannel,
qtErr);
for (int i = 0; i < 15; i++) { for (int i = 0; i < 15; i++) {
if (qtNoteChannel[i] != NULL) if (qtNoteChannel[i] != NULL)
NADisposeNoteChannel(qtNoteAllocator, qtNoteChannel[i]); NADisposeNoteChannel(qtNoteAllocator, qtNoteChannel[i]);
@ -273,7 +292,8 @@ void MidiDriver::midiInitQuicktime() {
#endif #endif
} }
void MidiDriver::MidiOutQuicktime(void *a, int b) { void MidiDriver::MidiOutQuicktime(void *a, int b)
{
#ifdef __APPLE__CW #ifdef __APPLE__CW
MusicMIDIPacket midPacket; MusicMIDIPacket midPacket;
unsigned char *midiCmd = midPacket.data; unsigned char *midiCmd = midPacket.data;
@ -290,33 +310,40 @@ void MidiDriver::MidiOutQuicktime(void *a, int b) {
break; break;
case 0x90: // Note on case 0x90: // Note on
NAPlayNote(qtNoteAllocator, qtNoteChannel[chanID], midiCmd[1], midiCmd[2]); NAPlayNote(qtNoteAllocator, qtNoteChannel[chanID], midiCmd[1],
midiCmd[2]);
break; break;
case 0xB0: // Effect case 0xB0: // Effect
switch (midiCmd[1]) { switch (midiCmd[1]) {
case 0x01: // Modulation case 0x01: // Modulation
NASetController(qtNoteAllocator, qtNoteChannel[chanID], kControllerModulationWheel, midiCmd[2]<<8); NASetController(qtNoteAllocator, qtNoteChannel[chanID],
kControllerModulationWheel, midiCmd[2] << 8);
break; break;
case 0x07: // Volume case 0x07: // Volume
NASetController(qtNoteAllocator, qtNoteChannel[chanID], kControllerVolume, midiCmd[2]*300); NASetController(qtNoteAllocator, qtNoteChannel[chanID],
kControllerVolume, midiCmd[2] * 300);
break; break;
case 0x0A: // Pan case 0x0A: // Pan
NASetController(qtNoteAllocator, qtNoteChannel[chanID], kControllerPan, (midiCmd[2]<<1)+0xFF); NASetController(qtNoteAllocator, qtNoteChannel[chanID], kControllerPan,
(midiCmd[2] << 1) + 0xFF);
break; break;
case 0x40: // Sustain on/off case 0x40: // Sustain on/off
NASetController(qtNoteAllocator, qtNoteChannel[chanID], kControllerSustain, midiCmd[2]); NASetController(qtNoteAllocator, qtNoteChannel[chanID],
kControllerSustain, midiCmd[2]);
break; break;
case 0x5b: // ext effect depth case 0x5b: // ext effect depth
NASetController(qtNoteAllocator, qtNoteChannel[chanID], kControllerReverb, midiCmd[2]<<8); NASetController(qtNoteAllocator, qtNoteChannel[chanID],
kControllerReverb, midiCmd[2] << 8);
break; break;
case 0x5d: // chorus depth case 0x5d: // chorus depth
NASetController(qtNoteAllocator, qtNoteChannel[chanID], kControllerChorus, midiCmd[2]<<8); NASetController(qtNoteAllocator, qtNoteChannel[chanID],
kControllerChorus, midiCmd[2] << 8);
break; break;
case 0x7b: // mode message all notes off case 0x7b: // mode message all notes off
@ -335,8 +362,10 @@ void MidiDriver::MidiOutQuicktime(void *a, int b) {
break; break;
case 0xE0:{ // Pitch bend case 0xE0:{ // Pitch bend
long theBend = ((((long)midiCmd[1] + (long)(midiCmd[2] << 8)))-0x4000)/4; long theBend =
NASetController(qtNoteAllocator, qtNoteChannel[chanID], kControllerPitchBend, theBend); ((((long)midiCmd[1] + (long)(midiCmd[2] << 8))) - 0x4000) / 4;
NASetController(qtNoteAllocator, qtNoteChannel[chanID],
kControllerPitchBend, theBend);
} }
break; break;
@ -349,7 +378,8 @@ void MidiDriver::MidiOutQuicktime(void *a, int b) {
} }
/*********** MorphOS */ /*********** MorphOS */
void MidiDriver::MidiOutMorphOS(void *a, int b) { void MidiDriver::MidiOutMorphOS(void *a, int b)
{
#ifdef __MORPHOS__ #ifdef __MORPHOS__
if (ScummMidiRequest) { if (ScummMidiRequest) {
ULONG midi_data = b; // you never know about an int's size ;-) ULONG midi_data = b; // you never know about an int's size ;-)
@ -367,60 +397,73 @@ void MidiDriver::MidiOutMorphOS(void *a, int b) {
void MidiDriver::midiInitNull() {warning("Music not enabled - MIDI support selected with no MIDI driver available. Try Adlib");} void MidiDriver::midiInitNull()
{
warning
("Music not enabled - MIDI support selected with no MIDI driver available. Try Adlib");
}
/************************* Common midi code **********************/ /************************* Common midi code **********************/
void MidiSoundDriver::midiPitchBend(byte chan, int16 pitchbend) { void MidiSoundDriver::midiPitchBend(byte chan, int16 pitchbend)
{
uint16 tmp; uint16 tmp;
if (_midi_pitchbend_last[chan] != pitchbend) { if (_midi_pitchbend_last[chan] != pitchbend) {
_midi_pitchbend_last[chan] = pitchbend; _midi_pitchbend_last[chan] = pitchbend;
tmp = (pitchbend << 2) + 0x2000; tmp = (pitchbend << 2) + 0x2000;
_midi_driver.MidiOut(((tmp>>7)&0x7F)<<16 | (tmp&0x7F)<<8 | 0xE0 | chan); _midi_driver.
MidiOut(((tmp >> 7) & 0x7F) << 16 | (tmp & 0x7F) << 8 | 0xE0 | chan);
} }
} }
void MidiSoundDriver::midiVolume(byte chan, byte volume) { void MidiSoundDriver::midiVolume(byte chan, byte volume)
{
if (_midi_volume_last[chan] != volume) { if (_midi_volume_last[chan] != volume) {
_midi_volume_last[chan] = volume; _midi_volume_last[chan] = volume;
_midi_driver.MidiOut(volume << 16 | 7 << 8 | 0xB0 | chan); _midi_driver.MidiOut(volume << 16 | 7 << 8 | 0xB0 | chan);
} }
} }
void MidiSoundDriver::midiPedal(byte chan, bool pedal) { void MidiSoundDriver::midiPedal(byte chan, bool pedal)
{
if (_midi_pedal_last[chan] != pedal) { if (_midi_pedal_last[chan] != pedal) {
_midi_pedal_last[chan] = pedal; _midi_pedal_last[chan] = pedal;
_midi_driver.MidiOut(pedal << 16 | 64 << 8 | 0xB0 | chan); _midi_driver.MidiOut(pedal << 16 | 64 << 8 | 0xB0 | chan);
} }
} }
void MidiSoundDriver::midiModWheel(byte chan, byte modwheel) { void MidiSoundDriver::midiModWheel(byte chan, byte modwheel)
{
if (_midi_modwheel_last[chan] != modwheel) { if (_midi_modwheel_last[chan] != modwheel) {
_midi_modwheel_last[chan] = modwheel; _midi_modwheel_last[chan] = modwheel;
_midi_driver.MidiOut(modwheel << 16 | 1 << 8 | 0xB0 | chan); _midi_driver.MidiOut(modwheel << 16 | 1 << 8 | 0xB0 | chan);
} }
} }
void MidiSoundDriver::midiEffectLevel(byte chan, byte level) { void MidiSoundDriver::midiEffectLevel(byte chan, byte level)
{
if (_midi_effectlevel_last[chan] != level) { if (_midi_effectlevel_last[chan] != level) {
_midi_effectlevel_last[chan] = level; _midi_effectlevel_last[chan] = level;
_midi_driver.MidiOut(level << 16 | 91 << 8 | 0xB0 | chan); _midi_driver.MidiOut(level << 16 | 91 << 8 | 0xB0 | chan);
} }
} }
void MidiSoundDriver::midiChorus(byte chan, byte chorus) { void MidiSoundDriver::midiChorus(byte chan, byte chorus)
{
if (_midi_chorus_last[chan] != chorus) { if (_midi_chorus_last[chan] != chorus) {
_midi_chorus_last[chan] = chorus; _midi_chorus_last[chan] = chorus;
_midi_driver.MidiOut(chorus << 16 | 93 << 8 | 0xB0 | chan); _midi_driver.MidiOut(chorus << 16 | 93 << 8 | 0xB0 | chan);
} }
} }
void MidiSoundDriver::midiControl0(byte chan, byte value) { void MidiSoundDriver::midiControl0(byte chan, byte value)
{
_midi_driver.MidiOut(value << 16 | 0 << 8 | 0xB0 | chan); _midi_driver.MidiOut(value << 16 | 0 << 8 | 0xB0 | chan);
} }
void MidiSoundDriver::midiProgram(byte chan, byte program) { void MidiSoundDriver::midiProgram(byte chan, byte program)
{
if ((chan + 1) != 10) { /* Ignore percussion prededed by patch change */ if ((chan + 1) != 10) { /* Ignore percussion prededed by patch change */
if (_se->_mt32emulate) if (_se->_mt32emulate)
program = mt32_to_gmidi[program]; program = mt32_to_gmidi[program];
@ -429,28 +472,33 @@ void MidiSoundDriver::midiProgram(byte chan, byte program) {
} }
} }
void MidiSoundDriver::midiPan(byte chan, int8 pan) { void MidiSoundDriver::midiPan(byte chan, int8 pan)
{
if (_midi_pan_last[chan] != pan) { if (_midi_pan_last[chan] != pan) {
_midi_pan_last[chan] = pan; _midi_pan_last[chan] = pan;
_midi_driver.MidiOut(((pan - 64) & 0x7F) << 16 | 10 << 8 | 0xB0 | chan); _midi_driver.MidiOut(((pan - 64) & 0x7F) << 16 | 10 << 8 | 0xB0 | chan);
} }
} }
void MidiSoundDriver::midiNoteOn(byte chan, byte note, byte velocity) { void MidiSoundDriver::midiNoteOn(byte chan, byte note, byte velocity)
{
_midi_driver.MidiOut(velocity << 16 | note << 8 | 0x90 | chan); _midi_driver.MidiOut(velocity << 16 | note << 8 | 0x90 | chan);
} }
void MidiSoundDriver::midiNoteOff(byte chan, byte note) { void MidiSoundDriver::midiNoteOff(byte chan, byte note)
{
_midi_driver.MidiOut(note << 8 | 0x80 | chan); _midi_driver.MidiOut(note << 8 | 0x80 | chan);
} }
void MidiSoundDriver::midiSilence(byte chan) { void MidiSoundDriver::midiSilence(byte chan)
{
_midi_driver.MidiOut((64 << 8) | 0xB0 | chan); _midi_driver.MidiOut((64 << 8) | 0xB0 | chan);
_midi_driver.MidiOut((123 << 8) | 0xB0 | chan); _midi_driver.MidiOut((123 << 8) | 0xB0 | chan);
} }
void MidiSoundDriver::part_key_on(Part *part, byte note, byte velocity) { void MidiSoundDriver::part_key_on(Part *part, byte note, byte velocity)
{
MidiChannelGM *mc = part->_mc->gm(); MidiChannelGM *mc = part->_mc->gm();
if (mc) { if (mc) {
@ -463,7 +511,8 @@ void MidiSoundDriver::part_key_on(Part *part, byte note, byte velocity) {
} }
} }
void MidiSoundDriver::part_key_off(Part *part, byte note) { void MidiSoundDriver::part_key_off(Part *part, byte note)
{
MidiChannelGM *mc = part->_mc->gm(); MidiChannelGM *mc = part->_mc->gm();
if (mc) { if (mc) {
@ -474,7 +523,8 @@ void MidiSoundDriver::part_key_off(Part *part, byte note) {
} }
} }
void MidiSoundDriver::init(SoundEngine *eng) { void MidiSoundDriver::init(SoundEngine *eng)
{
int i; int i;
MidiChannelGM *mc; MidiChannelGM *mc;
@ -484,7 +534,8 @@ void MidiSoundDriver::init(SoundEngine *eng) {
mc->_chan = i; mc->_chan = i;
} }
void MidiSoundDriver::update_pris() { void MidiSoundDriver::update_pris()
{
Part *part, *hipart; Part *part, *hipart;
int i; int i;
byte hipri, lopri; byte hipri, lopri;
@ -494,7 +545,8 @@ void MidiSoundDriver::update_pris() {
hipri = 0; hipri = 0;
hipart = NULL; hipart = NULL;
for (i = 32, part = _se->parts_ptr(); i; i--, part++) { for (i = 32, part = _se->parts_ptr(); i; i--, part++) {
if (part->_player && !part->_percussion && part->_on && !part->_mc && part->_pri_eff>=hipri) { if (part->_player && !part->_percussion && part->_on && !part->_mc
&& part->_pri_eff >= hipri) {
hipri = part->_pri_eff; hipri = part->_pri_eff;
hipart = part; hipart = part;
} }
@ -529,7 +581,8 @@ void MidiSoundDriver::update_pris() {
} }
} }
int MidiSoundDriver::part_update_active(Part *part, uint16 *active) { int MidiSoundDriver::part_update_active(Part *part, uint16 *active)
{
int i, j; int i, j;
uint16 *act, mask, bits; uint16 *act, mask, bits;
int count = 0; int count = 0;
@ -554,7 +607,8 @@ int MidiSoundDriver::part_update_active(Part *part, uint16 *active) {
return count; return count;
} }
void MidiSoundDriver::part_changed(Part *part, byte what) { void MidiSoundDriver::part_changed(Part *part, byte what)
{
MidiChannelGM *mc; MidiChannelGM *mc;
/* Mark for re-schedule if program changed when in pre-state */ /* Mark for re-schedule if program changed when in pre-state */
@ -567,7 +621,9 @@ void MidiSoundDriver::part_changed(Part *part, byte what) {
return; return;
if (what & pcMod) if (what & pcMod)
midiPitchBend(mc->_chan, clamp(part->_pitchbend + part->_detune_eff + (part->_transpose_eff<<7), -2048, 2047)); midiPitchBend(mc->_chan,
clamp(part->_pitchbend + part->_detune_eff +
(part->_transpose_eff << 7), -2048, 2047));
if (what & pcVolume) if (what & pcVolume)
midiVolume(mc->_chan, part->_vol_eff); midiVolume(mc->_chan, part->_vol_eff);
@ -599,7 +655,8 @@ void MidiSoundDriver::part_changed(Part *part, byte what) {
} }
void MidiSoundDriver::part_off(Part *part) { void MidiSoundDriver::part_off(Part *part)
{
MidiChannelGM *mc = part->_mc->gm(); MidiChannelGM *mc = part->_mc->gm();
if (mc) { if (mc) {
part->_mc = NULL; part->_mc = NULL;

File diff suppressed because it is too large Load diff

View file

@ -23,7 +23,8 @@
#include "stdafx.h" #include "stdafx.h"
#include "scumm.h" #include "scumm.h"
int CharsetRenderer::getStringWidth(int arg, byte *text, int pos) { int CharsetRenderer::getStringWidth(int arg, byte *text, int pos)
{
byte *ptr; byte *ptr;
int width, offs, w; int width, offs, w;
byte chr; byte chr;
@ -38,7 +39,8 @@ int CharsetRenderer::getStringWidth(int arg, byte *text, int pos) {
break; break;
if (chr == '@') if (chr == '@')
continue; continue;
if (chr==254) chr=255; if (chr == 254)
chr = 255;
if (chr == 255) { if (chr == 255) {
chr = text[pos++]; chr = text[pos++];
if (chr == 3) if (chr == 3)
@ -82,7 +84,8 @@ int CharsetRenderer::getStringWidth(int arg, byte *text, int pos) {
return width; return width;
} }
void CharsetRenderer::addLinebreaks(int a, byte *str, int pos, int maxwidth) { void CharsetRenderer::addLinebreaks(int a, byte *str, int pos, int maxwidth)
{
int lastspace = -1; int lastspace = -1;
int curw = 1; int curw = 1;
int offs, w; int offs, w;
@ -96,7 +99,8 @@ void CharsetRenderer::addLinebreaks(int a, byte *str, int pos, int maxwidth) {
while ((chr = str[pos++]) != 0) { while ((chr = str[pos++]) != 0) {
if (chr == '@') if (chr == '@')
continue; continue;
if (chr==254) chr=255; if (chr == 254)
chr = 255;
if (chr == 255) { if (chr == 255) {
chr = str[pos++]; chr = str[pos++];
if (chr == 3) if (chr == 3)
@ -156,7 +160,8 @@ void CharsetRenderer::addLinebreaks(int a, byte *str, int pos, int maxwidth) {
} }
} }
void Scumm::unkMessage1() { void Scumm::unkMessage1()
{
byte buffer[100]; byte buffer[100];
_msgPtrToAdd = buffer; _msgPtrToAdd = buffer;
_messagePtr = addMessageToStack(_messagePtr); _messagePtr = addMessageToStack(_messagePtr);
@ -165,15 +170,17 @@ void Scumm::unkMessage1() {
uint32 a, b; uint32 a, b;
a = buffer[2] | (buffer[3] << 8) | (buffer[6] << 16) | (buffer[7] << 24); a = buffer[2] | (buffer[3] << 8) | (buffer[6] << 16) | (buffer[7] << 24);
b = buffer[10] | (buffer[11]<<8) | (buffer[14]<<16) | (buffer[15]<<24); b =
buffer[10] | (buffer[11] << 8) | (buffer[14] << 16) | (buffer[15] <<
24);
// if (_saveSound != 1) // if (_saveSound != 1)
talkSound(a, b, 1); talkSound(a, b, 1);
} }
// warning("unkMessage1(\"%s\")", buffer); // warning("unkMessage1(\"%s\")", buffer);
} }
void Scumm::unkMessage2() { void Scumm::unkMessage2()
{
byte buf[100], *tmp; byte buf[100], *tmp;
_msgPtrToAdd = buf; _msgPtrToAdd = buf;
@ -187,7 +194,8 @@ void Scumm::unkMessage2() {
} }
void Scumm::CHARSET_1() { void Scumm::CHARSET_1()
{
int s, i, t, c; int s, i, t, c;
int frme; int frme;
Actor *a; Actor *a;
@ -195,8 +203,8 @@ void Scumm::CHARSET_1() {
if (!(_features & GF_AFTER_V7)) { if (!(_features & GF_AFTER_V7)) {
if (!_haveMsg || (camera._dest.x >> 3) != (camera._cur.x >> 3) || if (!_haveMsg || (camera._dest.x >> 3) != (camera._cur.x >> 3) ||
camera._cur.x != camera._last.x camera._cur.x != camera._last.x)
) return; return;
} else { } else {
if (!_haveMsg) if (!_haveMsg)
return; return;
@ -212,7 +220,8 @@ void Scumm::CHARSET_1() {
if (_vars[VAR_V5_TALK_STRING_Y] < 0) { if (_vars[VAR_V5_TALK_STRING_Y] < 0) {
s = (a->scaley * (int)_vars[VAR_V5_TALK_STRING_Y]) / 0xFF; s = (a->scaley * (int)_vars[VAR_V5_TALK_STRING_Y]) / 0xFF;
string[0].ypos = ((_vars[VAR_V5_TALK_STRING_Y]-s)>>1) + s - a->elevation + a->y; string[0].ypos =
((_vars[VAR_V5_TALK_STRING_Y] - s) >> 1) + s - a->elevation + a->y;
} else { } else {
string[0].ypos = _vars[VAR_V5_TALK_STRING_Y]; string[0].ypos = _vars[VAR_V5_TALK_STRING_Y];
} }
@ -323,8 +332,7 @@ void Scumm::CHARSET_1() {
} }
if (c == 13) { if (c == 13) {
newLine:; newLine:;
if(_features & GF_OLD256) if (_features & GF_OLD256) {
{
charset._ypos2 = 8; charset._ypos2 = 8;
charset._xpos2 = 0; charset._xpos2 = 0;
continue; continue;
@ -342,7 +350,8 @@ newLine:;
} }
} }
if (c==0xFE) c=0xFF; if (c == 0xFE)
c = 0xFF;
if (c != 0xFF) { if (c != 0xFF) {
charset._left = charset._xpos2; charset._left = charset._xpos2;
@ -385,8 +394,11 @@ newLine:;
} else if (c == 10) { } else if (c == 10) {
uint32 a, b; uint32 a, b;
a = buffer[0] | (buffer[1]<<8) | (buffer[4]<<16) | (buffer[5]<<24); a =
b = buffer[8] | (buffer[9]<<8) | (buffer[12]<<16) | (buffer[13]<<24); buffer[0] | (buffer[1] << 8) | (buffer[4] << 16) | (buffer[5] << 24);
b =
buffer[8] | (buffer[9] << 8) | (buffer[12] << 16) | (buffer[13] <<
24);
talkSound(a, b, 2); talkSound(a, b, 2);
buffer += 14; buffer += 14;
} else if (c == 14) { } else if (c == 14) {
@ -399,7 +411,8 @@ newLine:;
charset._colorMap[i] = _charsetData[charset._curId][i - 12]; charset._colorMap[i] = _charsetData[charset._curId][i - 12];
else else
charset._colorMap[i] = _charsetData[charset._curId][i]; charset._colorMap[i] = _charsetData[charset._curId][i];
charset._ypos2 -= getResourceAddress(rtCharset,charset._curId)[30] - oldy; charset._ypos2 -=
getResourceAddress(rtCharset, charset._curId)[30] - oldy;
} else if (c == 12) { } else if (c == 12) {
int color; int color;
color = *buffer++; color = *buffer++;
@ -423,7 +436,8 @@ newLine:;
gdi._mask_bottom = charset._strBottom; gdi._mask_bottom = charset._strBottom;
} }
void Scumm::drawString(int a) { void Scumm::drawString(int a)
{
byte buf[256]; byte buf[256];
byte *charsetptr, *space; byte *charsetptr, *space;
int i; int i;
@ -465,13 +479,15 @@ void Scumm::drawString(int a) {
space = NULL; space = NULL;
while (*_msgPtrToAdd) { while (*_msgPtrToAdd) {
if (*_msgPtrToAdd == ' ') { if (*_msgPtrToAdd == ' ') {
if (!space) space = _msgPtrToAdd; if (!space)
space = _msgPtrToAdd;
} else { } else {
space = NULL; space = NULL;
} }
_msgPtrToAdd++; _msgPtrToAdd++;
} }
if(space) *space='\0'; if (space)
*space = '\0';
if (charset._center) { if (charset._center) {
charset._left -= charset.getStringWidth(a, buf, 0) >> 1; charset._left -= charset.getStringWidth(a, buf, 0) >> 1;
} }
@ -484,15 +500,19 @@ void Scumm::drawString(int a) {
} }
for (i = 0; (chr = buf[i++]) != 0;) { for (i = 0; (chr = buf[i++]) != 0;) {
if (chr==254) chr=255; if (chr == 254)
chr = 255;
if (chr == 255) { if (chr == 255) {
chr = buf[i++]; chr = buf[i++];
switch (chr) { switch (chr) {
case 9: case 9:
case 10: case 13: case 14: case 10:
case 13:
case 14:
i += 2; i += 2;
break; break;
case 1: case 8: case 1:
case 8:
if (charset._center) { if (charset._center) {
charset._left = charset._left2 - charset.getStringWidth(a, buf, i); charset._left = charset._left2 - charset.getStringWidth(a, buf, i);
} else { } else {
@ -528,7 +548,8 @@ void Scumm::drawString(int a) {
} }
} }
byte *Scumm::addMessageToStack(byte *msg) { byte *Scumm::addMessageToStack(byte *msg)
{
int num, numorg; int num, numorg;
byte *ptr, chr; byte *ptr, chr;
@ -587,7 +608,10 @@ byte *Scumm::addMessageToStack(byte *msg) {
break; break;
case 9: case 9:
//#if defined(DOTT) //#if defined(DOTT)
case 10: case 12: case 13: case 14: case 10:
case 12:
case 13:
case 14:
//#endif //#endif
*_msgPtrToAdd++ = 0xFF; *_msgPtrToAdd++ = 0xFF;
*_msgPtrToAdd++ = chr; *_msgPtrToAdd++ = chr;
@ -610,7 +634,8 @@ byte *Scumm::addMessageToStack(byte *msg) {
return msg; return msg;
} }
void Scumm::unkAddMsgToStack2(int var) { void Scumm::unkAddMsgToStack2(int var)
{
int num, max; int num, max;
byte flag; byte flag;
@ -629,11 +654,13 @@ void Scumm::unkAddMsgToStack2(int var) {
flag = 1; flag = 1;
} }
max /= 10; max /= 10;
if (max==1) flag=1; if (max == 1)
flag = 1;
} while (max); } while (max);
} }
void Scumm::unkAddMsgToStack3(int var) { void Scumm::unkAddMsgToStack3(int var)
{
int num, i; int num, i;
num = readVar(var); num = readVar(var);
@ -649,7 +676,8 @@ void Scumm::unkAddMsgToStack3(int var) {
} }
} }
void Scumm::unkAddMsgToStack4(int var) { void Scumm::unkAddMsgToStack4(int var)
{
int num; int num;
num = readVar(var); num = readVar(var);
@ -660,7 +688,8 @@ void Scumm::unkAddMsgToStack4(int var) {
} }
} }
void Scumm::unkAddMsgToStack5(int var) { void Scumm::unkAddMsgToStack5(int var)
{
byte *ptr; byte *ptr;
if (_features & GF_AFTER_V6) if (_features & GF_AFTER_V6)
@ -676,7 +705,8 @@ void Scumm::unkAddMsgToStack5(int var) {
addMessageToStack((byte *)""); addMessageToStack((byte *)"");
} }
void Scumm::initCharset(int charsetno) { void Scumm::initCharset(int charsetno)
{
int i; int i;
if (_features & GF_OLD256) if (_features & GF_OLD256)
@ -684,8 +714,7 @@ void Scumm::initCharset(int charsetno) {
if (_features & GF_SMALL_HEADER) if (_features & GF_SMALL_HEADER)
loadCharset(charsetno); loadCharset(charsetno);
else else if (!getResourceAddress(rtCharset, charsetno))
if (!getResourceAddress(rtCharset, charsetno))
loadCharset(charsetno); loadCharset(charsetno);
string[0].t_charset = charsetno; string[0].t_charset = charsetno;
@ -698,13 +727,15 @@ void Scumm::initCharset(int charsetno) {
charset._colorMap[i] = _charsetData[charset._curId][i]; charset._colorMap[i] = _charsetData[charset._curId][i];
} }
void CharsetRenderer::printCharOld(int chr) { // Loom3 / Zak256 void CharsetRenderer::printCharOld(int chr)
{ // Loom3 / Zak256
VirtScreen *vs; VirtScreen *vs;
byte *char_ptr, *dest_ptr; byte *char_ptr, *dest_ptr;
unsigned int buffer = 0, mask = 0, x = 0, y = 0; unsigned int buffer = 0, mask = 0, x = 0, y = 0;
unsigned char color; unsigned char color;
_vm->checkRange(_vm->_maxCharsets-1, 0, _curId, "Printing with bad charset %d"); _vm->checkRange(_vm->_maxCharsets - 1, 0, _curId,
"Printing with bad charset %d");
if ((vs = _vm->findVirtScreen(_top)) == NULL) if ((vs = _vm->findVirtScreen(_top)) == NULL)
return; return;
@ -721,11 +752,15 @@ void CharsetRenderer::printCharOld(int chr) { // Loom3 / Zak256
} }
char_ptr = _vm->getResourceAddress(rtCharset, _curId) + 224 + (chr + 1) * 8; char_ptr = _vm->getResourceAddress(rtCharset, _curId) + 224 + (chr + 1) * 8;
dest_ptr = vs->screenPtr + vs->xstart + (_top - vs->topline) * 320 + _left; dest_ptr = vs->screenPtr + vs->xstart + (_top - vs->topline) * 320 + _left;
_vm->updateDirtyRect(vs->number, _left, _left + 8, _top - vs->topline, _top - vs->topline + 8, 0); _vm->updateDirtyRect(vs->number, _left, _left + 8, _top - vs->topline,
_top - vs->topline + 8, 0);
for (y = 0; y < 8; y++) { for (y = 0; y < 8; y++) {
for (x = 0; x < 8; x++) { for (x = 0; x < 8; x++) {
if ((mask >>= 1) == 0) {buffer = *char_ptr++; mask = 0x80;} if ((mask >>= 1) == 0) {
buffer = *char_ptr++;
mask = 0x80;
}
color = ((buffer & mask) != 0); color = ((buffer & mask) != 0);
if (color) if (color)
*(dest_ptr + y * 320 + x) = _color; *(dest_ptr + y * 320 + x) = _color;
@ -743,11 +778,13 @@ void CharsetRenderer::printCharOld(int chr) { // Loom3 / Zak256
} }
void CharsetRenderer::printChar(int chr) { void CharsetRenderer::printChar(int chr)
{
int d, right; int d, right;
VirtScreen *vs; VirtScreen *vs;
_vm->checkRange(_vm->_maxCharsets-1, 1, _curId, "Printing with bad charset %d"); _vm->checkRange(_vm->_maxCharsets - 1, 1, _curId,
"Printing with bad charset %d");
if ((vs = _vm->findVirtScreen(_top)) == NULL) if ((vs = _vm->findVirtScreen(_top)) == NULL)
return; return;
@ -823,7 +860,8 @@ void CharsetRenderer::printChar(int chr) {
_strTop = _top; _strTop = _top;
_drawTop = _top - vs->topline; _drawTop = _top - vs->topline;
if (_drawTop<0) _drawTop = 0; if (_drawTop < 0)
_drawTop = 0;
_bottom = _drawTop + _height + _offsY; _bottom = _drawTop + _height + _offsY;
@ -852,8 +890,7 @@ void CharsetRenderer::printChar(int chr) {
} }
_mask_ptr = _vm->getResourceAddress(rtBuffer, 9) _mask_ptr = _vm->getResourceAddress(rtBuffer, 9)
+ _drawTop * 40 + _left/8 + _drawTop * 40 + _left / 8 + _vm->_screenStartStrip;
+ _vm->_screenStartStrip;
_revBitMask = revBitMask[_left & 7]; _revBitMask = revBitMask[_left & 7];
@ -877,7 +914,8 @@ void CharsetRenderer::printChar(int chr) {
_top -= _offsY; _top -= _offsY;
} }
void CharsetRenderer::drawBits() { void CharsetRenderer::drawBits()
{
bool usemask; bool usemask;
byte *dst, *mask, maskmask; byte *dst, *mask, maskmask;
int y, x; int y, x;
@ -923,7 +961,8 @@ void CharsetRenderer::drawBits() {
} }
} }
int CharsetRenderer::getSpacing(char chr) { int CharsetRenderer::getSpacing(char chr)
{
int space; int space;
if (_curId == 1) { // do spacing for variable width old-style font if (_curId == 1) { // do spacing for variable width old-style font
@ -953,8 +992,7 @@ int CharsetRenderer::getSpacing(char chr) {
default: default:
space = 6; space = 6;
} }
} } else
else
space = 7; space = 7;
return space; return space;
} }

60
sys.cpp
View file

@ -23,7 +23,8 @@
#include "stdafx.h" #include "stdafx.h"
#include "scumm.h" #include "scumm.h"
void *Scumm::fileOpen(const char *filename, int mode) { void *Scumm::fileOpen(const char *filename, int mode)
{
_fileMode = mode; _fileMode = mode;
_whereInResToRead = 0; _whereInResToRead = 0;
clearFileReadFailed(_fileHandle); clearFileReadFailed(_fileHandle);
@ -38,30 +39,37 @@ void *Scumm::fileOpen(const char *filename, int mode) {
return NULL; return NULL;
} }
void Scumm::fileClose(void *file) { void Scumm::fileClose(void *file)
{
if (_fileMode == 1 || _fileMode == 2) if (_fileMode == 1 || _fileMode == 2)
fclose((FILE *) file); fclose((FILE *) file);
} }
bool Scumm::fileReadFailed(void *file) { bool Scumm::fileReadFailed(void *file)
{
return _fileReadFailed != 0; return _fileReadFailed != 0;
} }
void Scumm::clearFileReadFailed(void *file) { void Scumm::clearFileReadFailed(void *file)
{
_fileReadFailed = false; _fileReadFailed = false;
} }
bool Scumm::fileEof(void *file) { bool Scumm::fileEof(void *file)
{
return feof((FILE *) file) != 0; return feof((FILE *) file) != 0;
} }
uint32 Scumm::filePos(void *handle) { uint32 Scumm::filePos(void *handle)
{
return ftell((FILE *) handle); return ftell((FILE *) handle);
} }
void Scumm::fileSeek(void *file, long offs, int whence) { void Scumm::fileSeek(void *file, long offs, int whence)
{
switch (_fileMode) { switch (_fileMode) {
case 1: case 2: case 1:
case 2:
if (fseek((FILE *) file, offs, whence) != 0) if (fseek((FILE *) file, offs, whence) != 0)
clearerr((FILE *) file); clearerr((FILE *) file);
return; return;
@ -71,7 +79,8 @@ void Scumm::fileSeek(void *file, long offs, int whence) {
} }
} }
void Scumm::fileRead(void *file, void *ptr, uint32 size) { void Scumm::fileRead(void *file, void *ptr, uint32 size)
{
byte *ptr2 = (byte *)ptr, *src; byte *ptr2 = (byte *)ptr, *src;
switch (_fileMode) { switch (_fileMode) {
@ -103,7 +112,8 @@ void Scumm::fileRead(void *file, void *ptr, uint32 size) {
} }
} }
int Scumm::fileReadByte() { int Scumm::fileReadByte()
{
byte b; byte b;
byte *src; byte *src;
@ -123,31 +133,36 @@ int Scumm::fileReadByte() {
return 0; return 0;
} }
uint Scumm::fileReadWordLE() { uint Scumm::fileReadWordLE()
{
uint a = fileReadByte(); uint a = fileReadByte();
uint b = fileReadByte(); uint b = fileReadByte();
return a | (b << 8); return a | (b << 8);
} }
uint32 Scumm::fileReadDwordLE() { uint32 Scumm::fileReadDwordLE()
{
uint a = fileReadWordLE(); uint a = fileReadWordLE();
uint b = fileReadWordLE(); uint b = fileReadWordLE();
return (b << 16) | a; return (b << 16) | a;
} }
uint Scumm::fileReadWordBE() { uint Scumm::fileReadWordBE()
{
uint b = fileReadByte(); uint b = fileReadByte();
uint a = fileReadByte(); uint a = fileReadByte();
return a | (b << 8); return a | (b << 8);
} }
uint32 Scumm::fileReadDwordBE() { uint32 Scumm::fileReadDwordBE()
{
uint b = fileReadWordBE(); uint b = fileReadWordBE();
uint a = fileReadWordBE(); uint a = fileReadWordBE();
return (b << 16) | a; return (b << 16) | a;
} }
byte *Scumm::alloc(int size) { byte *Scumm::alloc(int size)
{
byte *me = (byte *)::calloc(size + 4, 1); byte *me = (byte *)::calloc(size + 4, 1);
if (me == NULL) if (me == NULL)
return NULL; return NULL;
@ -156,7 +171,8 @@ byte *Scumm::alloc(int size) {
return me + 4; return me + 4;
} }
void Scumm::free(void *mem) { void Scumm::free(void *mem)
{
if (mem) { if (mem) {
byte *me = (byte *)mem - 4; byte *me = (byte *)mem - 4;
if (*((uint32 *)me) != 0xDEADBEEF) { if (*((uint32 *)me) != 0xDEADBEEF) {
@ -168,21 +184,25 @@ void Scumm::free(void *mem) {
} }
} }
bool Scumm::checkFixedDisk() { bool Scumm::checkFixedDisk()
{
return true; return true;
} }
#ifdef NEED_STRDUP #ifdef NEED_STRDUP
char *strdup(const char *s) { char *strdup(const char *s)
{
int len = strlen(s) + 1; int len = strlen(s) + 1;
char *d = (char *)malloc(len); char *d = (char *)malloc(len);
if (d) memcpy(d, s, len); if (d)
memcpy(d, s, len);
return d; return d;
} }
#endif /* NEED_STRDUP */ #endif /* NEED_STRDUP */
void *operator new(size_t size) { void *operator new(size_t size)
{
return calloc(size, 1); return calloc(size, 1);
} }

View file

@ -24,7 +24,8 @@
#include "scumm.h" #include "scumm.h"
void Scumm_v3::readIndexFile() { void Scumm_v3::readIndexFile()
{
uint16 blocktype; uint16 blocktype;
uint32 itemsize; uint32 itemsize;
int numblock = 0; int numblock = 0;
@ -134,7 +135,8 @@ void Scumm_v3::readIndexFile() {
break; break;
default: default:
error("Bad ID %c%c found in directory!", blocktype&0xFF, blocktype>>8); error("Bad ID %c%c found in directory!", blocktype & 0xFF,
blocktype >> 8);
return; return;
} }
} }
@ -142,7 +144,8 @@ void Scumm_v3::readIndexFile() {
openRoom(-1); openRoom(-1);
} }
void Scumm_v3::loadCharset(int no){ void Scumm_v3::loadCharset(int no)
{
uint32 size; uint32 size;
memset(_charsetData, 0, sizeof(_charsetData)); memset(_charsetData, 0, sizeof(_charsetData));

View file

@ -23,9 +23,11 @@
#include "stdafx.h" #include "stdafx.h"
#include "scumm.h" #include "scumm.h"
void Scumm_v4::loadCharset(int no) { void Scumm_v4::loadCharset(int no)
{
uint32 size; uint32 size;
memset(_charsetData, 0, sizeof(_charsetData)); memset(_charsetData, 0, sizeof(_charsetData));
checkRange(4, 0, no, "Loading illegal charset %d"); checkRange(4, 0, no, "Loading illegal charset %d");

View file

@ -24,7 +24,8 @@
#include "stdafx.h" #include "stdafx.h"
#include "scumm.h" #include "scumm.h"
void Scumm::setupScummVarsOld(){ void Scumm::setupScummVarsOld()
{
VAR_EGO = 1; VAR_EGO = 1;
VAR_CAMERA_POS_X = 2; VAR_CAMERA_POS_X = 2;
@ -114,7 +115,8 @@ void Scumm::setupScummVarsOld(){
} }
void Scumm::setupScummVarsNew() { void Scumm::setupScummVarsNew()
{
VAR_MOUSE_X = 1; VAR_MOUSE_X = 1;
VAR_MOUSE_Y = 2; VAR_MOUSE_Y = 2;

View file

@ -23,14 +23,16 @@
#include "stdafx.h" #include "stdafx.h"
#include "scumm.h" #include "scumm.h"
void Scumm::redrawVerbs() { void Scumm::redrawVerbs()
{
int i; int i;
for (i = 0; i < _maxVerbs; i++) for (i = 0; i < _maxVerbs; i++)
drawVerb(i, 0); drawVerb(i, 0);
verbMouseOver(0); verbMouseOver(0);
} }
void Scumm::checkExecVerbs() { void Scumm::checkExecVerbs()
{
int i, over; int i, over;
VerbSlot *vs; VerbSlot *vs;
@ -51,7 +53,8 @@ void Scumm::checkExecVerbs() {
runInputScript(4, _mouseButStat, 1); runInputScript(4, _mouseButStat, 1);
} else if (_mouseButStat & MBS_MOUSE_MASK) { } else if (_mouseButStat & MBS_MOUSE_MASK) {
byte code = _mouseButStat & MBS_LEFT_CLICK ? 1 : 2; byte code = _mouseButStat & MBS_LEFT_CLICK ? 1 : 2;
if (mouse.y >= virtscr[0].topline && mouse.y < virtscr[0].topline + virtscr[0].height) { if (mouse.y >= virtscr[0].topline
&& mouse.y < virtscr[0].topline + virtscr[0].height) {
over = checkMouseOver(mouse.x, mouse.y); over = checkMouseOver(mouse.x, mouse.y);
if (over != 0) { if (over != 0) {
runInputScript(1, _verbs[over].verbid, code); runInputScript(1, _verbs[over].verbid, code);
@ -65,7 +68,8 @@ void Scumm::checkExecVerbs() {
} }
} }
void Scumm::verbMouseOver(int verb) { void Scumm::verbMouseOver(int verb)
{
if (_verbMouseOver == verb) if (_verbMouseOver == verb)
return; return;
@ -80,7 +84,8 @@ void Scumm::verbMouseOver(int verb) {
} }
} }
int Scumm::checkMouseOver(int x, int y) { int Scumm::checkMouseOver(int x, int y)
{
VerbSlot *vs; VerbSlot *vs;
int i = _maxVerbs - 1; int i = _maxVerbs - 1;
@ -102,7 +107,8 @@ int Scumm::checkMouseOver(int x, int y) {
return 0; return 0;
} }
void Scumm::drawVerb(int vrb, int mode) { void Scumm::drawVerb(int vrb, int mode)
{
VerbSlot *vs; VerbSlot *vs;
byte color; byte color;
byte tmp; byte tmp;
@ -152,7 +158,8 @@ void Scumm::drawVerb(int vrb, int mode) {
} }
} }
void Scumm::restoreVerbBG(int verb) { void Scumm::restoreVerbBG(int verb)
{
VerbSlot *vs; VerbSlot *vs;
vs = &_verbs[verb]; vs = &_verbs[verb];
@ -164,7 +171,8 @@ void Scumm::restoreVerbBG(int verb) {
} }
} }
void Scumm::drawVerbBitmap(int vrb, int x, int y) { void Scumm::drawVerbBitmap(int vrb, int x, int y)
{
VirtScreen *vs; VirtScreen *vs;
VerbSlot *vst; VerbSlot *vst;
byte twobufs, *imptr; byte twobufs, *imptr;
@ -230,7 +238,8 @@ void Scumm::drawVerbBitmap(int vrb, int x, int y) {
vs->alloctwobuffers = twobufs; vs->alloctwobuffers = twobufs;
} }
int Scumm::getVerbSlot(int id, int mode) { int Scumm::getVerbSlot(int id, int mode)
{
int i; int i;
for (i = 1; i < _maxVerbs; i++) { for (i = 1; i < _maxVerbs; i++) {
if (_verbs[i].verbid == id && _verbs[i].saveid == mode) { if (_verbs[i].verbid == id && _verbs[i].saveid == mode) {
@ -240,7 +249,8 @@ int Scumm::getVerbSlot(int id, int mode) {
return 0; return 0;
} }
void Scumm::killVerb(int slot) { void Scumm::killVerb(int slot)
{
VerbSlot *vs; VerbSlot *vs;
if (slot == 0) if (slot == 0)
@ -259,7 +269,8 @@ void Scumm::killVerb(int slot) {
vs->saveid = 0; vs->saveid = 0;
} }
void Scumm::setVerbObject(uint room, uint object, uint verb) { void Scumm::setVerbObject(uint room, uint object, uint verb)
{
byte *obimptr; byte *obimptr;
byte *obcdptr; byte *obcdptr;
uint32 size, size2; uint32 size, size2;

View file

@ -97,7 +97,8 @@ public:
#endif #endif
}; };
void Error(const char *msg) { void Error(const char *msg)
{
OutputDebugString(msg); OutputDebugString(msg);
MessageBoxA(0, msg, "Error", MB_ICONSTOP); MessageBoxA(0, msg, "Error", MB_ICONSTOP);
exit(1); exit(1);
@ -114,9 +115,12 @@ WndMan wm[1];
byte veryFastMode; byte veryFastMode;
void modifyslot(int sel, int what); void modifyslot(int sel, int what);
void launcherLoop() {;} void launcherLoop()
{;
}
int mapKey(int key) { int mapKey(int key)
{
if (key >= VK_F1 && key <= VK_F9) { if (key >= VK_F1 && key <= VK_F9) {
return key - VK_F1 + 315; return key - VK_F1 + 315;
} }
@ -124,16 +128,26 @@ int mapKey(int key) {
} }
// FIXME: CD Music Stubs // FIXME: CD Music Stubs
void cd_playtrack(int track, int offset, int delay) {;} void cd_playtrack(int track, int offset, int delay)
void cd_play(Scumm *s, int track, int num_loops, int start_frame) {;} {;
void cd_stop() {;} }
int cd_is_running() {return 0;} void cd_play(Scumm *s, int track, int num_loops, int start_frame)
{;
}
void cd_stop()
{;
}
int cd_is_running()
{
return 0;
}
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
LPARAM lParam)
{
WndMan *wm = (WndMan *) GetWindowLong(hWnd, GWL_USERDATA); WndMan *wm = (WndMan *) GetWindowLong(hWnd, GWL_USERDATA);
switch (message) switch (message) {
{
case WM_DESTROY: case WM_DESTROY:
case WM_CLOSE: case WM_CLOSE:
exit(0); exit(0);
@ -143,7 +157,8 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM l
if (wParam >= '0' && wParam <= '9') { if (wParam >= '0' && wParam <= '9') {
wm->_scumm->_saveLoadSlot = wParam - '0'; wm->_scumm->_saveLoadSlot = wParam - '0';
if (GetAsyncKeyState(VK_SHIFT) < 0) { if (GetAsyncKeyState(VK_SHIFT) < 0) {
sprintf(wm->_scumm->_saveLoadName, "Quicksave %d", wm->_scumm->_saveLoadSlot); sprintf(wm->_scumm->_saveLoadName, "Quicksave %d",
wm->_scumm->_saveLoadSlot);
wm->_scumm->_saveLoadFlag = 1; wm->_scumm->_saveLoadFlag = 1;
} else if (GetAsyncKeyState(VK_CONTROL) < 0) } else if (GetAsyncKeyState(VK_CONTROL) < 0)
wm->_scumm->_saveLoadFlag = 2; wm->_scumm->_saveLoadFlag = 2;
@ -195,7 +210,8 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM l
#if USE_GDI #if USE_GDI
bool WndMan::allocateDIB(int w, int h) { bool WndMan::allocateDIB(int w, int h)
{
struct { struct {
BITMAPINFOHEADER bih; BITMAPINFOHEADER bih;
RGBQUAD rgb[256]; RGBQUAD rgb[256];
@ -215,13 +231,15 @@ bool WndMan::allocateDIB(int w, int h) {
memcpy(d.rgb, dib.pal, 256 * sizeof(RGBQUAD)); memcpy(d.rgb, dib.pal, 256 * sizeof(RGBQUAD));
dib.new_pal = false; dib.new_pal = false;
dib.hSect = CreateDIBSection(0, (BITMAPINFO*)&d, DIB_RGB_COLORS, (void**)&dib.buf, dib.hSect =
CreateDIBSection(0, (BITMAPINFO *) & d, DIB_RGB_COLORS, (void **)&dib.buf,
NULL, NULL); NULL, NULL);
return dib.hSect != NULL; return dib.hSect != NULL;
} }
void WndMan::writeToScreen() { void WndMan::writeToScreen()
{
RECT r; RECT r;
HDC dc, bmpdc; HDC dc, bmpdc;
HBITMAP bmpOld; HBITMAP bmpOld;
@ -250,7 +268,8 @@ void WndMan::writeToScreen() {
SetStretchBltMode(dc, BLACKONWHITE); SetStretchBltMode(dc, BLACKONWHITE);
#if DEST_WIDTH==320 #if DEST_WIDTH==320
StretchBlt(dc, r.left, r.top, r.right-r.left, r.bottom-r.top, bmpdc, 0, 0, 320,200, SRCCOPY); StretchBlt(dc, r.left, r.top, r.right - r.left, r.bottom - r.top, bmpdc, 0,
0, 320, 200, SRCCOPY);
#endif #endif
@ -259,7 +278,8 @@ void WndMan::writeToScreen() {
ReleaseDC(hWnd, dc); ReleaseDC(hWnd, dc);
} }
void WndMan::setPalette(byte *ctab, int first, int num) { void WndMan::setPalette(byte *ctab, int first, int num)
{
int i; int i;
for (i = 0; i < 256; i++) { for (i = 0; i < 256; i++) {
@ -275,7 +295,8 @@ void WndMan::setPalette(byte *ctab, int first, int num) {
HWND globWnd; HWND globWnd;
void WndMan::init() { void WndMan::init()
{
/* Retrieve the handle of this module */ /* Retrieve the handle of this module */
hInst = GetModuleHandle(NULL); hInst = GetModuleHandle(NULL);
@ -299,7 +320,8 @@ void WndMan::init() {
#if USE_GDI #if USE_GDI
globWnd = hWnd = CreateWindow("ScummVM", "ScummVM", WS_OVERLAPPEDWINDOW, globWnd = hWnd = CreateWindow("ScummVM", "ScummVM", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, DEST_WIDTH+10, DEST_HEIGHT+30, NULL, NULL, hInst, NULL); CW_USEDEFAULT, CW_USEDEFAULT, DEST_WIDTH + 10,
DEST_HEIGHT + 30, NULL, NULL, hInst, NULL);
SetWindowLong(hWnd, GWL_USERDATA, (long)this); SetWindowLong(hWnd, GWL_USERDATA, (long)this);
dib.pal = (RGBQUAD *) calloc(sizeof(RGBQUAD), 256); dib.pal = (RGBQUAD *) calloc(sizeof(RGBQUAD), 256);
@ -314,7 +336,8 @@ void WndMan::init() {
} }
bool WndMan::handleMessage() { bool WndMan::handleMessage()
{
MSG msg; MSG msg;
if (!PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) if (!PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
@ -335,24 +358,21 @@ bool WndMan::handleMessage() {
unsigned long rdtsc_timer; unsigned long rdtsc_timer;
void _declspec(naked) beginpentiumtest() { void _declspec(naked) beginpentiumtest()
{
_asm { _asm {
rdtsc rdtsc mov rdtsc_timer, eax ret}
mov rdtsc_timer,eax
ret
}
} }
int _declspec(naked) endpentiumtest() { int _declspec(naked) endpentiumtest()
{
_asm { _asm {
rdtsc rdtsc sub eax, rdtsc_timer ret}
sub eax,rdtsc_timer
ret
}
} }
void decompressMask(byte *d, byte *s, int w=320, int h=144) { void decompressMask(byte *d, byte *s, int w = 320, int h = 144)
{
int x, y; int x, y;
for (y = 0; y < h; y++) { for (y = 0; y < h; y++) {
@ -370,7 +390,8 @@ void decompressMask(byte *d, byte *s, int w=320, int h=144) {
} }
} }
void outputlittlemask(byte *mask, int w, int h) { void outputlittlemask(byte *mask, int w, int h)
{
byte *old = wm->_vgabuf; byte *old = wm->_vgabuf;
wm->_vgabuf = NULL; wm->_vgabuf = NULL;
decompressMask(wm->dib.buf, mask, w, h); decompressMask(wm->dib.buf, mask, w, h);
@ -378,7 +399,8 @@ void outputlittlemask(byte *mask, int w, int h) {
wm->_vgabuf = old; wm->_vgabuf = old;
} }
void outputdisplay2(Scumm *s, int disp) { void outputdisplay2(Scumm *s, int disp)
{
byte *old = wm->_vgabuf; byte *old = wm->_vgabuf;
byte buf[64000]; byte buf[64000];
@ -396,26 +418,36 @@ void outputdisplay2(Scumm *s, int disp) {
break; break;
case 2: case 2:
wm->_vgabuf = NULL; wm->_vgabuf = NULL;
decompressMask(wm->dib.buf, s->getResourceAddress(rtBuffer, 9)+s->_screenStartStrip); decompressMask(wm->dib.buf,
s->getResourceAddress(rtBuffer, 9) + s->_screenStartStrip);
break; break;
case 3: case 3:
wm->_vgabuf = NULL; wm->_vgabuf = NULL;
decompressMask(wm->dib.buf, s->getResourceAddress(rtBuffer, 9)+8160+s->_screenStartStrip); decompressMask(wm->dib.buf,
s->getResourceAddress(rtBuffer,
9) + 8160 + s->_screenStartStrip);
break; break;
case 4: case 4:
wm->_vgabuf = NULL; wm->_vgabuf = NULL;
decompressMask(wm->dib.buf, s->getResourceAddress(rtBuffer, 9)+8160*2+s->_screenStartStrip); decompressMask(wm->dib.buf,
s->getResourceAddress(rtBuffer,
9) + 8160 * 2 +
s->_screenStartStrip);
break; break;
case 5: case 5:
wm->_vgabuf = NULL; wm->_vgabuf = NULL;
decompressMask(wm->dib.buf, s->getResourceAddress(rtBuffer, 9)+8160*3+s->_screenStartStrip); decompressMask(wm->dib.buf,
s->getResourceAddress(rtBuffer,
9) + 8160 * 3 +
s->_screenStartStrip);
break; break;
} }
wm->writeToScreen(); wm->writeToScreen();
wm->_vgabuf = old; wm->_vgabuf = old;
} }
void blitToScreen(Scumm *s, byte *src,int x, int y, int w, int h) { void blitToScreen(Scumm *s, byte *src, int x, int y, int w, int h)
{
byte *dst; byte *dst;
dst = (byte *)wm->_vgabuf + y * 320 + x; dst = (byte *)wm->_vgabuf + y * 320 + x;
@ -428,12 +460,15 @@ void blitToScreen(Scumm *s, byte *src,int x, int y, int w, int h) {
} }
void setShakePos(Scumm *s, int shake_pos) {} void setShakePos(Scumm *s, int shake_pos)
{
}
int clock; int clock;
void updateScreen(Scumm *s) { void updateScreen(Scumm *s)
{
if (s->_palDirtyMax != -1) { if (s->_palDirtyMax != -1) {
wm->setPalette(s->_currentPalette, 0, 256); wm->setPalette(s->_currentPalette, 0, 256);
s->_palDirtyMax = -1; s->_palDirtyMax = -1;
@ -442,7 +477,8 @@ void updateScreen(Scumm *s) {
wm->writeToScreen(); wm->writeToScreen();
} }
void waitForTimer(Scumm *s, int delay) { void waitForTimer(Scumm *s, int delay)
{
wm->handleMessage(); wm->handleMessage();
if (!veryFastMode) { if (!veryFastMode) {
assert(delay < 5000); assert(delay < 5000);
@ -452,23 +488,28 @@ void waitForTimer(Scumm *s, int delay) {
} }
} }
void initGraphics(Scumm *s, bool fullScreen, unsigned int scaleFactor) { void initGraphics(Scumm *s, bool fullScreen, unsigned int scaleFactor)
{
if (fullScreen) if (fullScreen)
warning("Use SDL for fullscreen support"); warning("Use SDL for fullscreen support");
scale = scaleFactor; // not supported yet! ignored. scale = scaleFactor; // not supported yet! ignored.
} }
void drawMouse(Scumm *s, int, int, int, byte*, bool) { void drawMouse(Scumm *s, int, int, int, byte *, bool)
{
} }
void drawMouse(Scumm *s, int x, int y, int w, int h, byte *buf, bool visible) { void drawMouse(Scumm *s, int x, int y, int w, int h, byte *buf, bool visible)
{
} }
void fill_buffer(int16 *buf, int len) { void fill_buffer(int16 * buf, int len)
{
scumm.mixWaves(buf, len); scumm.mixWaves(buf, len);
} }
void WndMan::prepare_header(WAVEHDR *wh, int i) { void WndMan::prepare_header(WAVEHDR * wh, int i)
{
memset(wh, 0, sizeof(WAVEHDR)); memset(wh, 0, sizeof(WAVEHDR));
wh->lpData = (char *)malloc(BUFFER_SIZE); wh->lpData = (char *)malloc(BUFFER_SIZE);
wh->dwBufferLength = BUFFER_SIZE; wh->dwBufferLength = BUFFER_SIZE;
@ -479,7 +520,8 @@ void WndMan::prepare_header(WAVEHDR *wh, int i) {
waveOutWrite(_handle, wh, sizeof(WAVEHDR)); waveOutWrite(_handle, wh, sizeof(WAVEHDR));
} }
void WndMan::sound_init() { void WndMan::sound_init()
{
WAVEFORMATEX wfx; WAVEFORMATEX wfx;
memset(&wfx, 0, sizeof(wfx)); memset(&wfx, 0, sizeof(wfx));
@ -490,20 +532,23 @@ void WndMan::sound_init() {
wfx.wBitsPerSample = BITS_PER_SAMPLE; wfx.wBitsPerSample = BITS_PER_SAMPLE;
wfx.nBlockAlign = BITS_PER_SAMPLE * 1 / 8; wfx.nBlockAlign = BITS_PER_SAMPLE * 1 / 8;
CreateThread(NULL, 0, (unsigned long (__stdcall *)(void *))&sound_thread, this, 0, &_threadId); CreateThread(NULL, 0, (unsigned long (__stdcall *) (void *))&sound_thread,
this, 0, &_threadId);
SetThreadPriority((void *)_threadId, THREAD_PRIORITY_HIGHEST); SetThreadPriority((void *)_threadId, THREAD_PRIORITY_HIGHEST);
_event = CreateEvent(NULL, false, false, NULL); _event = CreateEvent(NULL, false, false, NULL);
memset(_hdr, 0, sizeof(_hdr)); memset(_hdr, 0, sizeof(_hdr));
waveOutOpen(&_handle, WAVE_MAPPER, &wfx, (long)_event, (long)this, CALLBACK_EVENT ); waveOutOpen(&_handle, WAVE_MAPPER, &wfx, (long)_event, (long)this,
CALLBACK_EVENT);
prepare_header(&_hdr[0], 0); prepare_header(&_hdr[0], 0);
prepare_header(&_hdr[1], 1); prepare_header(&_hdr[1], 1);
} }
DWORD _stdcall WndMan::sound_thread(WndMan *wm) { DWORD _stdcall WndMan::sound_thread(WndMan * wm)
{
int i; int i;
bool signaled; bool signaled;
int time = GetTickCount(), cur; int time = GetTickCount(), cur;
@ -534,7 +579,8 @@ DWORD _stdcall WndMan::sound_thread(WndMan *wm) {
#undef main #undef main
int main(int argc, char* argv[]) { int main(int argc, char *argv[])
{
int delta; int delta;
wm->init(); wm->init();
@ -568,4 +614,6 @@ int main(int argc, char* argv[]) {
return 0; return 0;
} }
void BoxTest(int num) {;} // Test code void BoxTest(int num)
{;
} // Test code

134
x11.cpp
View file

@ -82,10 +82,12 @@ static int num_of_dirty_square;
/* Milisecond-based timer management */ /* Milisecond-based timer management */
static struct timeval start_time; static struct timeval start_time;
static void init_timer(void) { static void init_timer(void)
{
gettimeofday(&start_time, NULL); gettimeofday(&start_time, NULL);
} }
static unsigned int get_ms_from_start(void) { static unsigned int get_ms_from_start(void)
{
struct timeval current_time; struct timeval current_time;
gettimeofday(&current_time, NULL); gettimeofday(&current_time, NULL);
return (((current_time.tv_sec - start_time.tv_sec) * 1000) + return (((current_time.tv_sec - start_time.tv_sec) * 1000) +
@ -93,7 +95,8 @@ static unsigned int get_ms_from_start(void) {
} }
#define FRAG_SIZE 4096 #define FRAG_SIZE 4096
static void *sound_and_music_thread(void *params) { static void *sound_and_music_thread(void *params)
{
/* Init sound */ /* Init sound */
int sound_fd, param, frag_size; int sound_fd, param, frag_size;
unsigned char sound_buffer[FRAG_SIZE]; unsigned char sound_buffer[FRAG_SIZE];
@ -168,16 +171,16 @@ static void *sound_and_music_thread(void *params) {
} }
/* Function used to hide the mouse cursor */ /* Function used to hide the mouse cursor */
static void create_empty_cursor(Display *display, static void create_empty_cursor(Display * display, int screen, Window window)
int screen, {
Window window) {
XColor bg; XColor bg;
Pixmap pixmapBits; Pixmap pixmapBits;
Cursor cursor = None; Cursor cursor = None;
static const char data[] = { 0 }; static const char data[] = { 0 };
bg.red = bg.green = bg.blue = 0x0000; bg.red = bg.green = bg.blue = 0x0000;
pixmapBits = XCreateBitmapFromData(display, XRootWindow(display, screen), data, 1, 1); pixmapBits =
XCreateBitmapFromData(display, XRootWindow(display, screen), data, 1, 1);
if (pixmapBits) { if (pixmapBits) {
cursor = XCreatePixmapCursor(display, pixmapBits, pixmapBits, cursor = XCreatePixmapCursor(display, pixmapBits, pixmapBits,
&bg, &bg, 0, 0); &bg, &bg, 0, 0);
@ -187,24 +190,30 @@ static void create_empty_cursor(Display *display,
} }
/* No CD on the iPAQ => stub functions */ /* No CD on the iPAQ => stub functions */
void cd_play(Scumm *s, int track, int num_loops, int start_frame, int end_frame) { void cd_play(Scumm *s, int track, int num_loops, int start_frame,
int end_frame)
{
#ifdef COMPRESSED_SOUND_FILE #ifdef COMPRESSED_SOUND_FILE
mp3_cd_play(s, track, num_loops, start_frame, end_frame); mp3_cd_play(s, track, num_loops, start_frame, end_frame);
#endif #endif
} }
int cd_is_running(void) { int cd_is_running(void)
{
return 1; return 1;
} }
void cd_stop(void) { void cd_stop(void)
{
} }
/* No debugger on the iPAQ => stub function */ /* No debugger on the iPAQ => stub function */
void BoxTest(int num) { void BoxTest(int num)
{
} }
/* Initialize the graphics sub-system */ /* Initialize the graphics sub-system */
void initGraphics(Scumm *s, bool fullScreen, unsigned int scaleFactor) { void initGraphics(Scumm *s, bool fullScreen, unsigned int scaleFactor)
{
char buf[512], *gameName; char buf[512], *gameName;
static XShmSegmentInfo shminfo; static XShmSegmentInfo shminfo;
XWMHints *wm_hints; XWMHints *wm_hints;
@ -242,12 +251,16 @@ void initGraphics(Scumm *s, bool fullScreen, unsigned int scaleFactor) {
wm_hints->initial_state = NormalState; wm_hints->initial_state = NormalState;
XStringListToTextProperty(&name, 1, &window_name); XStringListToTextProperty(&name, 1, &window_name);
XSetWMProperties(display, window, &window_name, &window_name, XSetWMProperties(display, window, &window_name, &window_name,
NULL /* argv */, 0 /* argc */, NULL /* size hints */, wm_hints, NULL /* class hints */ ); NULL /* argv */ , 0 /* argc */ , NULL /* size hints */ ,
wm_hints, NULL /* class hints */ );
XSelectInput(display, window, XSelectInput(display, window,
ExposureMask | KeyPressMask | KeyReleaseMask | PointerMotionMask | ExposureMask | KeyPressMask | KeyReleaseMask |
ButtonPressMask | ButtonReleaseMask | StructureNotifyMask); PointerMotionMask | ButtonPressMask | ButtonReleaseMask |
image = XShmCreateImage(display, DefaultVisual(display, screen), 16, ZPixmap, NULL, &shminfo, 320, 200); StructureNotifyMask);
image =
XShmCreateImage(display, DefaultVisual(display, screen), 16, ZPixmap,
NULL, &shminfo, 320, 200);
shminfo.shmid = shmget(IPC_PRIVATE, 320 * 200 * 2, IPC_CREAT | 0700); shminfo.shmid = shmget(IPC_PRIVATE, 320 * 200 * 2, IPC_CREAT | 0700);
shminfo.shmaddr = (char *)shmat(shminfo.shmid, 0, 0); shminfo.shmaddr = (char *)shmat(shminfo.shmid, 0, 0);
image->data = shminfo.shmaddr; image->data = shminfo.shmaddr;
@ -282,7 +295,8 @@ void initGraphics(Scumm *s, bool fullScreen, unsigned int scaleFactor) {
local_fb = (unsigned char *)malloc(320 * 200 * sizeof(unsigned char)); local_fb = (unsigned char *)malloc(320 * 200 * sizeof(unsigned char));
} }
void setWindowName(Scumm *s) { void setWindowName(Scumm *s)
{
char buf[512], *gameName; char buf[512], *gameName;
XTextProperty window_name; XTextProperty window_name;
char *name = (char *)&buf; char *name = (char *)&buf;
@ -293,11 +307,13 @@ void setWindowName(Scumm *s) {
XStringListToTextProperty(&name, 1, &window_name); XStringListToTextProperty(&name, 1, &window_name);
XSetWMProperties(display, window, &window_name, &window_name, XSetWMProperties(display, window, &window_name, &window_name,
NULL /* argv */, 0 /* argc */, NULL /* size hints */, NULL /* WM hints */, NULL /* class hints */ ); NULL /* argv */ , 0 /* argc */ , NULL /* size hints */ ,
NULL /* WM hints */ , NULL /* class hints */ );
} }
/* This simply shifts up or down the screen by 'shake pos' */ /* This simply shifts up or down the screen by 'shake pos' */
void setShakePos(Scumm *s, int shake_pos) { void setShakePos(Scumm *s, int shake_pos)
{
if (shake_pos != current_shake_pos) { if (shake_pos != current_shake_pos) {
int dirty_top = 0, dirty_height = 0; int dirty_top = 0, dirty_height = 0;
int line; int line;
@ -382,7 +398,8 @@ void setShakePos(Scumm *s, int shake_pos) {
ds[num_of_dirty_square].h = hi; \ ds[num_of_dirty_square].h = hi; \
num_of_dirty_square++; \ num_of_dirty_square++; \
} }
void blitToScreen(Scumm *s, byte *src, int x, int y, int w, int h) { void blitToScreen(Scumm *s, byte *src, int x, int y, int w, int h)
{
unsigned char *dst; unsigned char *dst;
y += current_shake_pos; y += current_shake_pos;
@ -397,7 +414,8 @@ void blitToScreen(Scumm *s, byte *src, int x, int y, int w, int h) {
dst = local_fb + 320 * y + x; dst = local_fb + 320 * y + x;
if (h<=0) return; if (h <= 0)
return;
hide_mouse = true; hide_mouse = true;
if (has_mouse) { if (has_mouse) {
@ -416,16 +434,21 @@ void blitToScreen(Scumm *s, byte *src, int x, int y, int w, int h) {
#define BAK_HEIGHT 40 #define BAK_HEIGHT 40
unsigned char old_backup[BAK_WIDTH * BAK_HEIGHT]; unsigned char old_backup[BAK_WIDTH * BAK_HEIGHT];
void drawMouse(Scumm *s, int xdraw, int ydraw, int w, int h, byte *buf, bool visible) { void drawMouse(Scumm *s, int xdraw, int ydraw, int w, int h, byte *buf,
bool visible)
{
unsigned char *dst, *bak; unsigned char *dst, *bak;
ydraw += current_shake_pos; ydraw += current_shake_pos;
if ((xdraw >= 320) || ((xdraw + w) <= 0) || if ((xdraw >= 320) || ((xdraw + w) <= 0) ||
(ydraw >= 200) || ((ydraw + h) <= 0)) { (ydraw >= 200) || ((ydraw + h) <= 0)) {
if (hide_mouse) visible = false; if (hide_mouse)
if (has_mouse) has_mouse = false; visible = false;
if (visible) has_mouse = true; if (has_mouse)
has_mouse = false;
if (visible)
has_mouse = true;
return; return;
} }
@ -510,7 +533,8 @@ void drawMouse(Scumm *s, int xdraw, int ydraw, int w, int h, byte *buf, bool vis
} }
static unsigned short palette[256]; static unsigned short palette[256];
static void update_palette(Scumm *s) { static void update_palette(Scumm *s)
{
int first = s->_palDirtyMin; int first = s->_palDirtyMin;
int num = s->_palDirtyMax - first + 1; int num = s->_palDirtyMax - first + 1;
int i; int i;
@ -519,16 +543,20 @@ static void update_palette(Scumm *s) {
data += first * 3; data += first * 3;
for (i = 0; i < num; i++, data += 3) { for (i = 0; i < num; i++, data += 3) {
*pal++ = ((data[0] & 0xF8) << 8) | ((data[1] & 0xFC) << 3) | (data[2] >> 3); *pal++ =
((data[0] & 0xF8) << 8) | ((data[1] & 0xFC) << 3) | (data[2] >> 3);
} }
s->_palDirtyMax = -1; s->_palDirtyMax = -1;
s->_palDirtyMin = 0x3E8; s->_palDirtyMin = 0x3E8;
} }
static void update_screen(Scumm *s, const dirty_square *d, dirty_square *dout) { static void update_screen(Scumm *s, const dirty_square * d,
dirty_square * dout)
{
int x, y; int x, y;
unsigned char *ptr_src = local_fb + (320 * d->y) + d->x; unsigned char *ptr_src = local_fb + (320 * d->y) + d->x;
unsigned short *ptr_dst = ((unsigned short *) image->data) + (320 * d->y) + d->x; unsigned short *ptr_dst =
((unsigned short *)image->data) + (320 * d->y) + d->x;
for (y = 0; y < d->h; y++) { for (y = 0; y < d->h; y++) {
for (x = 0; x < d->w; x++) { for (x = 0; x < d->w; x++) {
*ptr_dst++ = palette[*ptr_src++]; *ptr_dst++ = palette[*ptr_src++];
@ -536,13 +564,18 @@ static void update_screen(Scumm *s, const dirty_square *d, dirty_square *dout) {
ptr_dst += 320 - d->w; ptr_dst += 320 - d->w;
ptr_src += 320 - d->w; ptr_src += 320 - d->w;
} }
if (d->x < dout->x) dout->x = d->x; if (d->x < dout->x)
if (d->y < dout->y) dout->y = d->y; dout->x = d->x;
if ((d->x + d->w) > dout->w) dout->w = d->x + d->w; if (d->y < dout->y)
if ((d->y + d->h) > dout->h) dout->h = d->y + d->h; dout->y = d->y;
if ((d->x + d->w) > dout->w)
dout->w = d->x + d->w;
if ((d->y + d->h) > dout->h)
dout->h = d->y + d->h;
} }
void updateScreen(Scumm *s) { void updateScreen(Scumm *s)
{
bool full_redraw = false; bool full_redraw = false;
bool need_redraw = false; bool need_redraw = false;
static const dirty_square ds_full = { 0, 0, 320, 200 }; static const dirty_square ds_full = { 0, 0, 320, 200 };
@ -579,13 +612,13 @@ void updateScreen(Scumm *s) {
XShmPutImage(display, window, DefaultGC(display, screen), image, XShmPutImage(display, window, DefaultGC(display, screen), image,
dout.x, dout.y, dout.x, dout.y,
scumm_x + dout.x, scumm_y + dout.y, scumm_x + dout.x, scumm_y + dout.y,
dout.w - dout.x, dout.h - dout.y, dout.w - dout.x, dout.h - dout.y, 0);
0);
XFlush(display); XFlush(display);
} }
} }
void launcherLoop() { void launcherLoop()
{
int last_time, new_time; int last_time, new_time;
int delta = 0; int delta = 0;
last_time = get_ms_from_start(); last_time = get_ms_from_start();
@ -608,7 +641,8 @@ void launcherLoop() {
} }
/* This function waits for 'msec_delay' miliseconds and handles external events */ /* This function waits for 'msec_delay' miliseconds and handles external events */
void waitForTimer(Scumm *s, int msec_delay) { void waitForTimer(Scumm *s, int msec_delay)
{
int start_time = get_ms_from_start(); int start_time = get_ms_from_start();
int end_time; int end_time;
fd_set rfds; fd_set rfds;
@ -658,8 +692,10 @@ void waitForTimer(Scumm *s, int msec_delay) {
} else { } else {
real_y -= scumm_y; real_y -= scumm_y;
} }
if ((real_h <= 0) || (real_w <= 0)) break; if ((real_h <= 0) || (real_w <= 0))
if ((real_x >= 320) || (real_y >= 200)) break; break;
if ((real_x >= 320) || (real_y >= 200))
break;
if ((real_x + real_w) >= 320) { if ((real_x + real_w) >= 320) {
real_w = 320 - real_x; real_w = 320 - real_x;
@ -670,7 +706,8 @@ void waitForTimer(Scumm *s, int msec_delay) {
/* Compute the intersection of the expose event with the real ScummVM display zone */ /* Compute the intersection of the expose event with the real ScummVM display zone */
AddDirtyRec(real_x, real_y, real_w, real_h); AddDirtyRec(real_x, real_y, real_w, real_h);
} break; }
break;
case KeyPress: case KeyPress:
switch (event.xkey.keycode) { switch (event.xkey.keycode) {
@ -715,7 +752,8 @@ void waitForTimer(Scumm *s, int msec_delay) {
default:{ default:{
KeySym xsym; KeySym xsym;
xsym = XKeycodeToKeysym(display, event.xkey.keycode, 0); xsym = XKeycodeToKeysym(display, event.xkey.keycode, 0);
if ((xsym >= 'a') && (xsym <= 'z') && (event.xkey.state & 0x01)) xsym &= ~0x20; /* Handle shifted keys */ if ((xsym >= 'a') && (xsym <= 'z') && (event.xkey.state & 0x01))
xsym &= ~0x20; /* Handle shifted keys */
s->_keyPressed = xsym; s->_keyPressed = xsym;
} }
} }
@ -757,7 +795,8 @@ void waitForTimer(Scumm *s, int msec_delay) {
s->drawMouse(); s->drawMouse();
updateScreen(s); updateScreen(s);
} }
} break; }
break;
case ConfigureNotify:{ case ConfigureNotify:{
if ((window_width != event.xconfigure.width) || if ((window_width != event.xconfigure.width) ||
@ -766,9 +805,11 @@ void waitForTimer(Scumm *s, int msec_delay) {
window_height = event.xconfigure.height; window_height = event.xconfigure.height;
scumm_x = (window_width - 320) / 2; scumm_x = (window_width - 320) / 2;
scumm_y = (window_height - 200) / 2; scumm_y = (window_height - 200) / 2;
XFillRectangle(display, window, black_gc, 0, 0, window_width, window_height); XFillRectangle(display, window, black_gc, 0, 0, window_width,
window_height);
} }
} break; }
break;
default: default:
printf("%d\n", event.type); printf("%d\n", event.type);
@ -783,7 +824,8 @@ void waitForTimer(Scumm *s, int msec_delay) {
- initialize all the 'globals' (sound driver, Scumm object, ...) - initialize all the 'globals' (sound driver, Scumm object, ...)
- do the main loop of the game - do the main loop of the game
*/ */
int main(int argc, char* argv[]) { int main(int argc, char *argv[])
{
int delta; int delta;
int last_time, new_time; int last_time, new_time;