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

577
actor.cpp

File diff suppressed because it is too large Load diff

666
akos.cpp

File diff suppressed because it is too large Load diff

466
boxes.cpp
View file

@ -24,71 +24,74 @@
#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) {
return(255); if (_features & GF_NO_SCALLING)
return (255);
Box *ptr = getBoxBaseAddr(box); Box *ptr = getBoxBaseAddr(box);
if (!box) if (!box)
return 255; return 255;
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;
checkRange(ptr[0]-1, 0, box, "Illegal box %d"); checkRange(ptr[0] - 1, 0, box, "Illegal box %d");
if(_features & GF_SMALL_HEADER) { if (_features & GF_SMALL_HEADER) {
if (_features & GF_OLD256) if (_features & GF_OLD256)
return (Box*)(ptr + box*(SIZEOF_BOX-2) + 1); return (Box *) (ptr + box * (SIZEOF_BOX - 2) + 1);
else else
return (Box*)(ptr + box*SIZEOF_BOX + 1); return (Box *) (ptr + box * SIZEOF_BOX + 1);
} else } else
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)))
return 0; return 0;
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,64 +99,57 @@ 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);
if (distanceFromPt(x, y, pt.x,pt.y) <= 4) if (distanceFromPt(x, y, pt.x, pt.y) <= 4)
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);
box->ul.y = (int16)FROM_LE_16(bp->uly); box->ul.y = (int16) FROM_LE_16(bp->uly);
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 {
} box->ll.x = (int16) FROM_LE_16(bp->llx);
else box->ll.y = (int16) FROM_LE_16(bp->lly);
{ box->lr.x = (int16) FROM_LE_16(bp->lrx);
box->ll.x = (int16)FROM_LE_16(bp->llx); box->lr.y = (int16) FROM_LE_16(bp->lry);
box->ll.y = (int16)FROM_LE_16(bp->lly);
box->lr.x = (int16)FROM_LE_16(bp->lrx);
box->lr.y = (int16)FROM_LE_16(bp->lry);
} }
} }
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);
if (diffx >= 0x100) if (diffx >= 0x100)
return 0xFFFF; return 0xFFFF;
@ -167,20 +163,24 @@ 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,
return (x-x1)*(y2-y1) <= (y-y1)*(x2-x1); int box)
{
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 lydiff,lxdiff; int y)
int32 dist,a,b,c; {
int x2,y2; int lydiff, lxdiff;
int32 dist, a, b, c;
int x2, y2;
ScummPoint pt; ScummPoint pt;
if (llx==ulx) { if (llx == ulx) {
x2 = ulx; x2 = ulx;
y2 = y; y2 = y;
} else if (lly==uly) { } else if (lly == uly) {
x2 = x; x2 = x;
y2 = uly; y2 = uly;
} else { } else {
@ -217,25 +217,31 @@ ScummPoint Scumm::closestPtOnLine(int ulx, int uly, int llx, int lly, int x, int
if (abs(lydiff) < abs(lxdiff)) { if (abs(lydiff) < abs(lxdiff)) {
if (lxdiff > 0) { if (lxdiff > 0) {
if (x2 < ulx) { if (x2 < ulx) {
type1:; type1:;
x2 = ulx; x2 = ulx;
y2 = uly; y2 = uly;
} else if (x2 > llx) { } else if (x2 > llx) {
type2:; type2:;
x2 = llx; x2 = llx;
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,48 +250,46 @@ 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;
getBoxCoordinates(b, &box); getBoxCoordinates(b, &box);
if (threshold==0) if (threshold == 0)
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;
uint bestdist = (uint)0xFFFF; uint bestdist = (uint) 0xFFFF;
BoxCoords box; BoxCoords box;
getBoxCoordinates(b, &box); getBoxCoordinates(b, &box);
pt = closestPtOnLine(box.ul.x,box.ul.y,box.ur.x,box.ur.y,x,y); pt = closestPtOnLine(box.ul.x, box.ul.y, box.ur.x, box.ur.y, x, y);
dist = distanceFromPt(x, y, pt.x, pt.y); dist = distanceFromPt(x, y, pt.x, pt.y);
if (dist < bestdist) { if (dist < bestdist) {
bestdist = dist; bestdist = dist;
@ -293,7 +297,7 @@ AdjustBoxResult Scumm::getClosestPtOnBox(int b, int x, int y) {
best.y = pt.y; best.y = pt.y;
} }
pt = closestPtOnLine(box.ur.x,box.ur.y,box.ll.x,box.ll.y,x,y); pt = closestPtOnLine(box.ur.x, box.ur.y, box.ll.x, box.ll.y, x, y);
dist = distanceFromPt(x, y, pt.x, pt.y); dist = distanceFromPt(x, y, pt.x, pt.y);
if (dist < bestdist) { if (dist < bestdist) {
bestdist = dist; bestdist = dist;
@ -301,7 +305,7 @@ AdjustBoxResult Scumm::getClosestPtOnBox(int b, int x, int y) {
best.y = pt.y; best.y = pt.y;
} }
pt = closestPtOnLine(box.ll.x,box.ll.y,box.lr.x,box.lr.y,x,y); pt = closestPtOnLine(box.ll.x, box.ll.y, box.lr.x, box.lr.y, x, y);
dist = distanceFromPt(x, y, pt.x, pt.y); dist = distanceFromPt(x, y, pt.x, pt.y);
if (dist < bestdist) { if (dist < bestdist) {
bestdist = dist; bestdist = dist;
@ -309,7 +313,7 @@ AdjustBoxResult Scumm::getClosestPtOnBox(int b, int x, int y) {
best.y = pt.y; best.y = pt.y;
} }
pt = closestPtOnLine(box.lr.x,box.lr.y,box.ul.x,box.ul.y,x,y); pt = closestPtOnLine(box.lr.x, box.lr.y, box.ul.x, box.ul.y, x, y);
dist = distanceFromPt(x, y, pt.x, pt.y); dist = distanceFromPt(x, y, pt.x, pt.y);
if (dist < bestdist) { if (dist < bestdist) {
bestdist = dist; bestdist = dist;
@ -321,22 +325,25 @@ 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;
if (from==to) if (from == to)
return to; return to;
boxm = getBoxMatrixBaseAddr(); boxm = getBoxMatrixBaseAddr();
i=0; i = 0;
while (i != from) { while (i != from) {
while (*boxm != 0xFF) while (*boxm != 0xFF)
boxm += 3; boxm += 3;
@ -344,30 +351,30 @@ int Scumm::getPathToDestBox(byte from, byte to) {
boxm++; boxm++;
} }
while (boxm[0]!=0xFF) { while (boxm[0] != 0xFF) {
if (boxm[0] <= to && boxm[1]>=to) if (boxm[0] <= to && boxm[1] >= to)
return boxm[2]; return boxm[2];
boxm+=3; boxm += 3;
} }
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;
int i,j; int i, j;
int flag; int flag;
int q,pos; int q, pos;
getBoxCoordinates(box1nr,&box1); getBoxCoordinates(box1nr, &box1);
getBoxCoordinates(box2nr,&box2); getBoxCoordinates(box2nr, &box2);
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);
@ -380,11 +387,11 @@ int Scumm::findPathTowards(Actor *a, byte box1nr, byte box2nr, byte box3nr) {
} }
if (box1.ul.y > box2.ur.y || box2.ul.y > box1.ur.y || if (box1.ul.y > box2.ur.y || box2.ul.y > box1.ur.y ||
(box1.ur.y==box2.ul.y || box2.ur.y==box1.ul.y) && (box1.ur.y == box2.ul.y || box2.ur.y == box1.ul.y) &&
box1.ul.y!=box1.ur.y && box2.ul.y!=box2.ur.y) { box1.ul.y != box1.ur.y && box2.ul.y != box2.ur.y) {
if (flag&1) if (flag & 1)
SWAP(box1.ul.y, box1.ur.y); SWAP(box1.ul.y, box1.ur.y);
if (flag&2) if (flag & 2)
SWAP(box2.ul.y, box2.ur.y); SWAP(box2.ul.y, box2.ur.y);
} else { } else {
if (box2nr == box3nr) { if (box2nr == box3nr) {
@ -392,12 +399,13 @@ int Scumm::findPathTowards(Actor *a, byte box1nr, byte box2nr, byte box3nr) {
int diffY = a->walkdata.desty - a->y; int diffY = a->walkdata.desty - a->y;
int boxDiffX = box1.ul.x - a->x; int boxDiffX = box1.ul.x - a->x;
if (diffX!=0) { if (diffX != 0) {
int t; int t;
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 {
@ -416,7 +424,7 @@ int Scumm::findPathTowards(Actor *a, byte box1nr, byte box2nr, byte box3nr) {
q = box1.ul.y; q = box1.ul.y;
if (q > box1.ur.y) if (q > box1.ur.y)
q = box1.ur.y; q = box1.ur.y;
if (q==pos && box2nr==box3nr) if (q == pos && box2nr == box3nr)
return 1; return 1;
_foundPathY = q; _foundPathY = q;
_foundPathX = box1.ul.x; _foundPathX = box1.ul.x;
@ -424,9 +432,8 @@ 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);
@ -439,11 +446,11 @@ int Scumm::findPathTowards(Actor *a, byte box1nr, byte box2nr, byte box3nr) {
} }
if (box1.ul.x > box2.ur.x || box2.ul.x > box1.ur.x || if (box1.ul.x > box2.ur.x || box2.ul.x > box1.ur.x ||
(box1.ur.x==box2.ul.x || box2.ur.x==box1.ul.x) && (box1.ur.x == box2.ul.x || box2.ur.x == box1.ul.x) &&
box1.ul.x!=box1.ur.x && box2.ul.x!=box2.ur.x) { box1.ul.x != box1.ur.x && box2.ul.x != box2.ur.x) {
if (flag&1) if (flag & 1)
SWAP(box1.ul.x, box1.ur.x); SWAP(box1.ul.x, box1.ur.x);
if (flag&2) if (flag & 2)
SWAP(box2.ul.x, box2.ur.x); SWAP(box2.ul.x, box2.ur.x);
} else { } else {
@ -453,7 +460,7 @@ int Scumm::findPathTowards(Actor *a, byte box1nr, byte box2nr, byte box3nr) {
int boxDiffY = box1.ul.y - a->y; int boxDiffY = box1.ul.y - a->y;
pos = a->x; pos = a->x;
if (diffY!=0) { if (diffY != 0) {
pos += diffX * boxDiffY / diffY; pos += diffX * boxDiffY / diffY;
} }
} else { } else {
@ -469,7 +476,7 @@ int Scumm::findPathTowards(Actor *a, byte box1nr, byte box2nr, byte box3nr) {
q = box1.ul.x; q = box1.ul.x;
if (q > box1.ur.x) if (q > box1.ur.x)
q = box1.ur.x; q = box1.ur.x;
if (q==pos && box2nr==box3nr) if (q == pos && box2nr == box3nr)
return 1; return 1;
_foundPathX = q; _foundPathX = q;
_foundPathY = box1.ul.y; _foundPathY = box1.ul.y;
@ -490,10 +497,11 @@ 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);
_extraBoxFlags[box] = val; _extraBoxFlags[box] = val;
} else { } else {
Box *b = getBoxBaseAddr(box); Box *b = getBoxBaseAddr(box);
@ -501,23 +509,25 @@ 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;
int table_1[66],table_2[66]; int table_1[66], table_2[66];
int counter,val; int counter, val;
int code; int code;
PathVertex *vtx; PathVertex *vtx;
PathNode *node, *node2=NULL; PathNode *node, *node2 = NULL;
_maxBoxVertexHeap = 1000; _maxBoxVertexHeap = 1000;
@ -535,19 +545,19 @@ void Scumm::createBoxMatrix() {
num = getNumBoxes(); num = getNumBoxes();
for (i=0; i<num; i++) { for (i = 0; i < num; i++) {
for (j=0; j<num; j++) { for (j = 0; j < num; j++) {
if (i==j) { if (i == j) {
_boxMatrixPtr3[i*64+j] = 0; _boxMatrixPtr3[i * 64 + j] = 0;
} else if (areBoxesNeighbours(i, j)) { } else if (areBoxesNeighbours(i, j)) {
_boxMatrixPtr3[i*64+j] = 1; _boxMatrixPtr3[i * 64 + j] = 1;
} else { } else {
_boxMatrixPtr3[i*64+j] = 250; _boxMatrixPtr3[i * 64 + j] = 250;
} }
} }
} }
for (j=0; j<num; j++) { for (j = 0; j < num; j++) {
flags = getBoxFlags(j); flags = getBoxFlags(j);
if (flags & 0x80) { if (flags & 0x80) {
addToBoxMatrix(0xFF); addToBoxMatrix(0xFF);
@ -556,11 +566,11 @@ void Scumm::createBoxMatrix() {
addToBoxMatrix(j); addToBoxMatrix(j);
} else { } else {
vtx = addPathVertex(); vtx = addPathVertex();
for (i=0; i<num; i++) { for (i = 0; i < num; i++) {
flags = getBoxFlags(j); flags = getBoxFlags(j);
if (!(flags&0x80)) { if (!(flags & 0x80)) {
node = unkMatrixProc2(vtx, i); node = unkMatrixProc2(vtx, i);
if (i==j) if (i == j)
node2 = node; node2 = node;
} }
} }
@ -571,11 +581,12 @@ void Scumm::createBoxMatrix() {
counter = 250; counter = 250;
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;
else else
table_2[node->index] = -1; table_2[node->index] = -1;
@ -588,7 +599,7 @@ void Scumm::createBoxMatrix() {
node2 = node = vtx->left; node2 = node = vtx->left;
while (node) { while (node) {
if ( table_1[node->index] < counter ) { if (table_1[node->index] < counter) {
counter = table_1[node->index]; counter = table_1[node->index];
node2 = node; node2 = node;
} }
@ -608,25 +619,25 @@ void Scumm::createBoxMatrix() {
} }
addToBoxMatrix(0xFF); addToBoxMatrix(0xFF);
for (i=1; i<num;) { for (i = 1; i < num;) {
if (table_2[i-1]!=-1) { if (table_2[i - 1] != -1) {
addToBoxMatrix(i-1); /* lo */ addToBoxMatrix(i - 1); /* lo */
if (table_2[i-1] != table_2[i]) { if (table_2[i - 1] != table_2[i]) {
addToBoxMatrix(i-1); /* hi */ addToBoxMatrix(i - 1); /* hi */
addToBoxMatrix(table_2[i-1]); /* dst */ addToBoxMatrix(table_2[i - 1]); /* dst */
} else { } else {
while (table_2[i-1] == table_2[i]) { while (table_2[i - 1] == table_2[i]) {
if (++i==num) if (++i == num)
break; break;
} }
addToBoxMatrix(i-1); /* hi */ addToBoxMatrix(i - 1); /* hi */
addToBoxMatrix(table_2[i-1]); /* dst */ addToBoxMatrix(table_2[i - 1]); /* dst */
} }
} }
if (++i==num && table_2[i-1]!=-1) { if (++i == num && table_2[i - 1] != -1) {
addToBoxMatrix(i-1); /* lo */ addToBoxMatrix(i - 1); /* lo */
addToBoxMatrix(i-1); /* hi */ addToBoxMatrix(i - 1); /* hi */
addToBoxMatrix(table_2[i-1]); /* dest */ addToBoxMatrix(table_2[i - 1]); /* dest */
} }
} }
} }
@ -637,8 +648,9 @@ 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;
if (!node->right) { if (!node->right) {
@ -659,21 +671,22 @@ 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)
return NULL; return NULL;
if (!vtx->right) { if (!vtx->right) {
node = (PathNode*)addToBoxVertexHeap(sizeof(PathNode)); node = (PathNode *) addToBoxVertexHeap(sizeof(PathNode));
vtx->left = vtx->right = node; vtx->left = vtx->right = node;
node->index = i; node->index = i;
node->left = 0; node->left = 0;
node->right = 0; node->right = 0;
} else { } else {
node = (PathNode*)addToBoxVertexHeap(sizeof(PathNode)); node = (PathNode *) addToBoxVertexHeap(sizeof(PathNode));
vtx->right->left = node; vtx->right->left = node;
node->right = vtx->right; node->right = vtx->right;
@ -687,14 +700,15 @@ 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;
BoxCoords box; BoxCoords box;
BoxCoords box2; BoxCoords box2;
if (getBoxFlags(box1nr)&0x80 || getBoxFlags(box2nr)&0x80) if (getBoxFlags(box1nr) & 0x80 || getBoxFlags(box2nr) & 0x80)
return false; return false;
getBoxCoordinates(box1nr, &box2); getBoxCoordinates(box1nr, &box2);
@ -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;
@ -721,9 +734,8 @@ bool Scumm::areBoxesNeighbours(int box1nr, int box2nr) {
if (box.ur.y < box2.ul.y || if (box.ur.y < box2.ul.y ||
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;
@ -756,9 +767,8 @@ bool Scumm::areBoxesNeighbours(int box1nr, int box2nr) {
if (box.ur.x < box2.ul.x || if (box.ur.x < box2.ul.x ||
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,16 +834,18 @@ 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;
p[1].x = actor->x; p[1].x = actor->x;
@ -845,22 +859,22 @@ int Scumm::findPathTowardsOld(Actor *a, byte trap1, byte trap2, byte final_trap)
p[4].y = actor->walkdata.desty; p[4].y = actor->walkdata.desty;
if (getMaskFromBox(trap1) == getMaskFromBox(trap2) || 1) { if (getMaskFromBox(trap1) == getMaskFromBox(trap2) || 1) {
if (CompareSlope(p[1].x,p[1].y,p[4].x,p[4].y, gate1ax,gate1ay) != if (CompareSlope(p[1].x, p[1].y, p[4].x, p[4].y, gate1ax, gate1ay) !=
CompareSlope(p[1].x,p[1].y,p[4].x,p[4].y, gate1bx,gate1by) && CompareSlope(p[1].x, p[1].y, p[4].x, p[4].y, gate1bx, gate1by) &&
CompareSlope(p[1].x,p[1].y,p[4].x,p[4].y, gate2ax,gate2ay) != CompareSlope(p[1].x, p[1].y, p[4].x, p[4].y, gate2ax, gate2ay) !=
CompareSlope(p[1].x,p[1].y,p[4].x,p[4].y, gate2bx,gate2by)) { CompareSlope(p[1].x, p[1].y, p[4].x, p[4].y, gate2bx, gate2by)) {
return 0; /* same zplane and between both gates? */ return 0; /* same zplane and between both gates? */
} }
} }
} }
pt=closestPtOnLine(gate2ax,gate2ay,gate2bx,gate2by,p[1].x,p[1].y); pt = closestPtOnLine(gate2ax, gate2ay, gate2bx, gate2by, p[1].x, p[1].y);
p[3].x = pt.x; p[3].x = pt.x;
p[3].y = pt.y; p[3].y = pt.y;
if (CompareSlope(p[1].x,p[1].y,p[3].x,p[3].y, gate1ax,gate1ay) == if (CompareSlope(p[1].x, p[1].y, p[3].x, p[3].y, gate1ax, gate1ay) ==
CompareSlope(p[1].x,p[1].y,p[3].x,p[3].y, gate1bx,gate1by)) { CompareSlope(p[1].x, p[1].y, p[3].x, p[3].y, gate1bx, gate1by)) {
closestPtOnLine(gate1ax,gate1ay,gate1bx,gate1by,p[1].x,p[1].y); closestPtOnLine(gate1ax, gate1ay, gate1bx, gate1by, p[1].x, p[1].y);
p[2].x = pt.x; /* if point 2 between gates, ignore! */ p[2].x = pt.x; /* if point 2 between gates, ignore! */
p[2].y = pt.y; p[2].y = pt.y;
} }
@ -868,18 +882,19 @@ 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 Closest1=0,Closest2=0,Closest3=0; int i;
int Dist[8]; int Closest1 = 0, Closest2 = 0, Closest3 = 0;
int Dist1,Dist2,Dist3; int Dist[8];
int Box1,Box2,Box3; int Dist1, Dist2, Dist3;
BoxCoords box; int Box1, Box2, Box3;
int polyx[8]; BoxCoords box;
int polyy[8]; int polyx[8];
AdjustBoxResult pt; int polyy[8];
AdjustBoxResult pt;
getBoxCoordinates(trap1,&box); getBoxCoordinates(trap1, &box);
polyx[0] = box.ul.x; polyx[0] = box.ul.x;
polyy[0] = box.ul.y; polyy[0] = box.ul.y;
polyx[1] = box.ur.x; polyx[1] = box.ur.x;
@ -888,14 +903,14 @@ AdjustBoxResult pt;
polyy[2] = box.ll.y; polyy[2] = box.ll.y;
polyx[3] = box.lr.x; polyx[3] = box.lr.x;
polyy[3] = box.lr.y; polyy[3] = box.lr.y;
for (i = 0 ; i < 4 ; i++) { for (i = 0; i < 4; i++) {
pt = getClosestPtOnBox(trap2,polyx[i],polyy[i]); pt = getClosestPtOnBox(trap2, polyx[i], polyy[i]);
Dist[i] = pt.dist; Dist[i] = pt.dist;
CloX[i] = pt.x; CloX[i] = pt.x;
CloY[i] = pt.y; CloY[i] = pt.y;
} }
getBoxCoordinates(trap2,&box); getBoxCoordinates(trap2, &box);
polyx[4] = box.ul.x; polyx[4] = box.ul.x;
polyy[4] = box.ul.y; polyy[4] = box.ul.y;
polyx[5] = box.ur.x; polyx[5] = box.ur.x;
@ -904,8 +919,8 @@ AdjustBoxResult pt;
polyy[6] = box.ll.y; polyy[6] = box.ll.y;
polyx[7] = box.lr.x; polyx[7] = box.lr.x;
polyy[7] = box.lr.y; polyy[7] = box.lr.y;
for (i = 4 ; i < 8 ; i++) { for (i = 4; i < 8; i++) {
pt = getClosestPtOnBox(trap1,polyx[i],polyy[i]); pt = getClosestPtOnBox(trap1, polyx[i], polyy[i]);
Dist[i] = pt.dist; Dist[i] = pt.dist;
CloX[i] = pt.x; CloX[i] = pt.x;
CloY[i] = pt.y; CloY[i] = pt.y;
@ -913,7 +928,7 @@ AdjustBoxResult pt;
Dist1 = 0xFFFF; Dist1 = 0xFFFF;
for (i = 0 ; i < 8 ; i++) { for (i = 0; i < 8; i++) {
if (Dist[i] < Dist1) { if (Dist[i] < Dist1) {
Dist1 = Dist[i]; Dist1 = Dist[i];
Closest1 = i; Closest1 = i;
@ -922,7 +937,7 @@ AdjustBoxResult pt;
Dist[Closest1] = 0xFFFF; Dist[Closest1] = 0xFFFF;
Dist2 = 0xFFFF; Dist2 = 0xFFFF;
for (i = 0 ; i < 8 ; i++) { for (i = 0; i < 8; i++) {
if (Dist[i] < Dist2) { if (Dist[i] < Dist2) {
Dist2 = Dist[i]; Dist2 = Dist[i];
Closest2 = i; Closest2 = i;
@ -931,7 +946,7 @@ AdjustBoxResult pt;
Dist[Closest2] = 0xFFFF; Dist[Closest2] = 0xFFFF;
Dist3 = 0xFFFF; Dist3 = 0xFFFF;
for (i = 0 ; i < 8 ; i++) { for (i = 0; i < 8; i++) {
if (Dist[i] < Dist3) { if (Dist[i] < Dist3) {
Dist3 = Dist[i]; Dist3 = Dist[i];
Closest3 = i; Closest3 = i;
@ -946,35 +961,36 @@ AdjustBoxResult pt;
Dist2 = (int)sqrt(Dist2); Dist2 = (int)sqrt(Dist2);
Dist3 = (int)sqrt(Dist3); Dist3 = (int)sqrt(Dist3);
if (Box1 == Box2 && abs(Dist1-Dist2) < 4) { if (Box1 == Box2 && abs(Dist1 - Dist2) < 4) {
SetGate(Closest1,Closest2,polyx,polyy); SetGate(Closest1, Closest2, polyx, polyy);
} else if (Box1 == Box2 && Dist1 == Dist2) { /* parallel */ } else if (Box1 == Box2 && Dist1 == Dist2) { /* parallel */
SetGate(Closest1,Closest2,polyx,polyy); SetGate(Closest1, Closest2, polyx, polyy);
} else if (Box1 == Box3 && Dist1 == Dist3) { /* parallel */ } else if (Box1 == Box3 && Dist1 == Dist3) { /* parallel */
SetGate(Closest1,Closest3,polyx,polyy); SetGate(Closest1, Closest3, polyx, polyy);
} else if (Box2 == Box3 && Dist2 == Dist3) { /* parallel */ } else if (Box2 == Box3 && Dist2 == Dist3) { /* parallel */
SetGate(Closest2,Closest3,polyx,polyy); SetGate(Closest2, Closest3, polyx, polyy);
} else if (Box1 == Box3 && abs(Dist1-Dist3) < 4) { } else if (Box1 == Box3 && abs(Dist1 - Dist3) < 4) {
SetGate(Closest1,Closest3,polyx,polyy); SetGate(Closest1, Closest3, polyx, polyy);
} else if (abs(Dist1-Dist3) < 4) { /* if 1 close to 3 then use 2-3 */ } else if (abs(Dist1 - Dist3) < 4) { /* if 1 close to 3 then use 2-3 */
SetGate(Closest2,Closest3,polyx,polyy); SetGate(Closest2, Closest3, polyx, polyy);
} else if (abs(Dist1-Dist2) < 4) { } else if (abs(Dist1 - Dist2) < 4) {
SetGate(Closest1,Closest2,polyx,polyy); SetGate(Closest1, Closest2, polyx, polyy);
} else { } else {
SetGate(Closest1,Closest1,polyx,polyy); SetGate(Closest1, Closest1, polyx, polyy);
} }
} }
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(1); return (0);
return (1);
} }
void Scumm::SetGate(int line1,int line2, int polyx[8], int polyy[8]) void Scumm::SetGate(int line1, int line2, int polyx[8], int polyy[8])
{ {
if (line1 < 4) { /* from box 1 to box 2 */ if (line1 < 4) { /* from box 1 to box 2 */

File diff suppressed because it is too large Load diff

131
debug.cpp
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:
@ -103,8 +103,8 @@ bool ScummDebugger::do_command() {
if (!_parameters[0]) { if (!_parameters[0]) {
printf("Enter a room number...\n"); printf("Enter a room number...\n");
} else { } else {
int room=atoi(_parameters); int room = atoi(_parameters);
_s->actor[_s->_vars[_s->VAR_EGO]].room=room; _s->actor[_s->_vars[_s->VAR_EGO]].room = room;
_s->startScene(room, 0, 0); _s->startScene(room, 0, 0);
_s->_fullRedraw = 1; _s->_fullRedraw = 1;
} }
@ -117,10 +117,9 @@ 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++;
} }
boxm++; boxm++;
@ -128,7 +127,7 @@ bool ScummDebugger::do_command() {
} }
printf("\nWalk boxes:\n"); printf("\nWalk boxes:\n");
for (i=0; i<num; i++) { for (i = 0; i < num; i++) {
BoxTest(i); BoxTest(i);
_s->getBoxCoordinates(i, &box); _s->getBoxCoordinates(i, &box);
printf("%d: [%d x %d] [%d x %d] [%d x %d] [%d x %d]\n", i, printf("%d: [%d x %d] [%d x %d] [%d x %d] [%d x %d]\n", i,
@ -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,25 +171,30 @@ 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)
enter(); enter();
} }
void ScummDebugger::detach() { void ScummDebugger::detach()
{
_s->_debugger = NULL; _s->_debugger = NULL;
_s = NULL; _s = NULL;
} }
@ -201,20 +206,21 @@ struct DebuggerCommands {
}; };
static const DebuggerCommands debugger_commands[] = { static const DebuggerCommands debugger_commands[] = {
{ "h", 1, CMD_HELP }, {"h", 1, CMD_HELP},
{ "q", 1, CMD_QUIT }, {"q", 1, CMD_QUIT},
{ "g", 1, CMD_GO }, {"g", 1, CMD_GO},
{ "a", 1, CMD_ACTOR }, {"a", 1, CMD_ACTOR},
{ "s", 1, CMD_SCRIPTS }, {"s", 1, CMD_SCRIPTS},
{ "r", 1, CMD_LOAD_ROOM }, {"r", 1, CMD_LOAD_ROOM},
{ "b", 1, CMD_DUMPBOX}, {"b", 1, CMD_DUMPBOX},
{ "v", 1, CMD_VAR}, {"v", 1, CMD_VAR},
{ "w", 1, CMD_WATCH}, {"w", 1, CMD_WATCH},
{ "e", 1, CMD_EXIT }, {"e", 1, CMD_EXIT},
{ "" , 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;
@ -228,22 +234,22 @@ int ScummDebugger::get_command() {
return CMD_QUIT; return CMD_QUIT;
i = strlen(_cmd_buffer); i = strlen(_cmd_buffer);
while (i>0 && _cmd_buffer[i-1]==10) while (i > 0 && _cmd_buffer[i - 1] == 10)
_cmd_buffer[--i] = 0; _cmd_buffer[--i] = 0;
if (i==0) if (i == 0)
continue; continue;
#else // yes we do have readline #else // yes we do have readline
if(buf) { if (buf) {
free(buf); free(buf);
} }
buf = readline("debug> "); buf = readline("debug> ");
if(!buf) { if (!buf) {
printf("\n"); printf("\n");
return CMD_QUIT; return CMD_QUIT;
} }
if(strlen(buf) == 0) { if (strlen(buf) == 0) {
continue; continue;
} }
add_history(buf); add_history(buf);
@ -252,50 +258,67 @@ int ScummDebugger::get_command() {
dc = debugger_commands; dc = debugger_commands;
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;
} }
} 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
for(i=1; i<_s->NUM_ACTORS; i++) { ("|# |room| x y |elev|cos|width|box|mov|zp|frame|scale|spd|dir|\n");
if (act==-1 || act==i) { printf
("+--+----+--------+----+---+-----+---+---+--+-----+-----+---+---+\n");
for (i = 1; i < _s->NUM_ACTORS; 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;
printf("+---------------------------------+\n"); printf("+---------------------------------+\n");
printf("|# |num|sta|typ|un1|un2|fc|cut|un5|\n"); printf("|# |num|sta|typ|un1|un2|fc|cut|un5|\n");
printf("+--+---+---+---+---+---+--+---+---+\n"); printf("+--+---+---+---+---+---+--+---+---+\n");
for(i=0; i<25; i++) { for (i = 0; i < 25; i++) {
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

@ -4,7 +4,7 @@
// A lot of this was ripped straight from the readline fileman.c example. // A lot of this was ripped straight from the readline fileman.c example.
char* _debugger_commands[] = { char *_debugger_commands[] = {
"help", "help",
"quit", "quit",
"go", "go",
@ -16,10 +16,11 @@ char* _debugger_commands[] = {
// forwards decls // forwards decls
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;
@ -36,7 +38,7 @@ char ** scumm_debugger_completion (const char *text, int start, int end) {
// If this word is at the start of the line, then it is a command // If this word is at the start of the line, then it is a command
// to complete. // to complete.
if (start == 0) { if (start == 0) {
matches = rl_completion_matches (text, scumm_debugger_command_generator); matches = rl_completion_matches(text, scumm_debugger_command_generator);
} else { } else {
// At some stage it'd be nice to have symbolic actor name completion // At some stage it'd be nice to have symbolic actor name completion
// or something similarly groovy. Not right now though. // or something similarly groovy. Not right now though.
@ -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,18 +66,16 @@ 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)
//return (dupstr(name)); //return (dupstr(name));
return strdup(name); return strdup(name);
} }

View file

@ -45,33 +45,33 @@
"\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);
} }
/* Parse the arguments */ /* Parse the arguments */
for (i=1; i < argc; i++) { for (i = 1; i < argc; i++) {
s = argv[i]; s = argv[i];
if (s && s[0]=='-') { if (s && s[0] == '-') {
s++; s++;
while (*s) { while (*s) {
switch(tolower(*s)) { switch (tolower(*s)) {
case 'a': case 'a':
_restore = true; _restore = true;
break; break;
case 'b': case 'b':
if (*(s+1) == '\0') if (*(s + 1) == '\0')
goto ShowHelpAndExit; goto ShowHelpAndExit;
_bootParam = atoi(s+1); _bootParam = atoi(s + 1);
goto NextArg; goto NextArg;
case 'f': case 'f':
_fullScreen = true; _fullScreen = true;
@ -83,92 +83,93 @@ void GameDetector::parseCommandLine(int argc, char **argv) {
_noSubtitles = true; _noSubtitles = true;
break; break;
case 's': case 's':
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__ " "
#ifdef SCUMMVM_PLATFORM_VERSION __TIME__ "\n");
#ifdef SCUMMVM_PLATFORM_VERSION
printf(" " SCUMMVM_PLATFORM_VERSION "\n"); printf(" " SCUMMVM_PLATFORM_VERSION "\n");
#endif #endif
exit(1); exit(1);
case 'p': case 'p':
if (*(s+1) == '\0') if (*(s + 1) == '\0')
goto ShowHelpAndExit; goto ShowHelpAndExit;
_gameDataPath = s+1; _gameDataPath = s + 1;
goto NextArg; goto NextArg;
case 't': case 't':
if (*(s+1) == '\0') if (*(s + 1) == '\0')
goto ShowHelpAndExit; goto ShowHelpAndExit;
_gameTempo = atoi(s+1); _gameTempo = atoi(s + 1);
goto NextArg; goto NextArg;
case 'm': { case 'm':{
if (*(s+1) == '\0') if (*(s + 1) == '\0')
goto ShowHelpAndExit; goto ShowHelpAndExit;
SoundEngine *se = (SoundEngine*)_soundEngine; SoundEngine *se = (SoundEngine *)_soundEngine;
if (se) if (se)
se->set_music_volume(atoi(s+1)); se->set_music_volume(atoi(s + 1));
goto NextArg; goto NextArg;
} }
case 'r': { case 'r':{
SoundEngine *se = (SoundEngine*)_soundEngine; SoundEngine *se = (SoundEngine *)_soundEngine;
if (se) if (se)
se->_mt32emulate = true; se->_mt32emulate = true;
break; break;
} }
case 'e': case 'e':
if (*(s+1) == '\0') if (*(s + 1) == '\0')
goto ShowHelpAndExit; goto ShowHelpAndExit;
_midi_driver = atoi(s+1); _midi_driver = atoi(s + 1);
goto NextArg; goto NextArg;
case 'g': case 'g':
if (*(s+1) == '\0') if (*(s + 1) == '\0')
goto ShowHelpAndExit; goto ShowHelpAndExit;
_videoMode = atoi(s+1); _videoMode = atoi(s + 1);
goto NextArg; goto NextArg;
case 'c': case 'c':
if (*(s+1) == '\0') if (*(s + 1) == '\0')
goto ShowHelpAndExit; goto ShowHelpAndExit;
_cdrom = atoi(s+1); _cdrom = atoi(s + 1);
goto NextArg; goto NextArg;
default: default:
ShowHelpAndExit:; ShowHelpAndExit:;
printf( USAGE_STRING ); printf(USAGE_STRING);
exit(1); exit(1);
} }
s++; s++;
} }
NextArg:; NextArg:;
} else { } else {
if (_exe_name) goto ShowHelpAndExit; if (_exe_name)
goto ShowHelpAndExit;
_exe_name = s; _exe_name = s;
} }
} }
#else #else
_midi_driver = 4; _midi_driver = 4;
_exe_name = *argv; _exe_name = *argv;
_gameDataPath = (char*)malloc(strlen(_exe_name) + 3); _gameDataPath = (char *)malloc(strlen(_exe_name) + 3);
sprintf(_gameDataPath, ":%s:", _exe_name); sprintf(_gameDataPath, ":%s:", _exe_name);
#endif #endif
} }
struct VersionSettings { struct VersionSettings {
const char *filename; const char *filename;
const char *gamename; const char *gamename;
byte id,major,middle,minor; byte id, major, middle, minor;
uint32 features; uint32 features;
}; };
@ -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,8 +262,9 @@ 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);
return strdup(buf); return strdup(buf);
@ -261,19 +284,19 @@ int GameDetector::detectMain(int argc, char **argv)
_videoMode = 0; _videoMode = 0;
_soundCardType = 3; _soundCardType = 3;
#ifdef WIN32 #ifdef WIN32
_midi_driver = MIDI_WINDOWS; _midi_driver = MIDI_WINDOWS;
#else #else
_midi_driver = MIDI_NULL; _midi_driver = MIDI_NULL;
#endif #endif
parseCommandLine(argc, argv); parseCommandLine(argc, argv);
if (_exe_name==NULL) { if (_exe_name == NULL) {
//launcherLoop(); //launcherLoop();
//setWindowName(this); //setWindowName(this);
warning("No game was specified..."); warning("No game was specified...");
return(-1); return (-1);
} }
@ -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);
} }

1395
gfx.cpp

File diff suppressed because it is too large Load diff

475
gui.cpp
View file

@ -25,17 +25,17 @@
#ifdef _WIN32_WCE #ifdef _WIN32_WCE
// Additional variables for Win32 specific GUI // Additional variables for Win32 specific GUI
#include "gapi_keys.h" #include "gapi_keys.h"
extern bool toolbar_drawn; extern bool toolbar_drawn;
extern bool draw_keyboard; extern bool draw_keyboard;
extern bool get_key_mapping; extern bool get_key_mapping;
extern struct keyops keyMapping; extern struct keyops keyMapping;
extern void registry_save(void); extern void registry_save(void);
uint16 _key_mapping_required; uint16 _key_mapping_required;
#else #else
#define registry_save() ; #define registry_save() ;
bool get_key_mapping; bool get_key_mapping;
uint16 _key_mapping_required; uint16 _key_mapping_required;
#endif #endif
enum { enum {
@ -49,19 +49,20 @@ 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)
end=start; end = start;
for (i=0; i<(int)(sizeof(_widgets) / sizeof(_widgets[0])); i++) { for (i = 0; i < (int)(sizeof(_widgets) / sizeof(_widgets[0])); i++) {
const GuiWidget *w = _widgets[i]; const GuiWidget *w = _widgets[i];
if (w) { if (w) {
_parentX = 0; _parentX = 0;
_parentY = 0; _parentY = 0;
while (w->_type != GUI_NONE) { while (w->_type != GUI_NONE) {
if (w->_id>=start && w->_id<=end && (w->_page&(1<<_cur_page)) ) { if (w->_id >= start && w->_id <= end && (w->_page & (1 << _cur_page))) {
drawWidget(w); drawWidget(w);
} }
if (w->_flags & GWF_PARENT) { if (w->_flags & GWF_PARENT) {
@ -74,15 +75,16 @@ 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--) {
const GuiWidget *w = _widgets[i]; const GuiWidget *w = _widgets[i];
if (w) { if (w) {
while (w->_type != GUI_NONE) { while (w->_type != GUI_NONE) {
if ((w->_page&(1<<_cur_page)) && w->_id && if ((w->_page & (1 << _cur_page)) && w->_id &&
(uint16)(x-w->_x) < w->_w && (uint16)(y-w->_y) < w->_h) (uint16)(x - w->_x) < w->_w && (uint16)(y - w->_y) < w->_h)
return w; return w;
if (w->_flags & GWF_PARENT) { if (w->_flags & GWF_PARENT) {
x -= w->_x; x -= w->_x;
@ -95,19 +97,23 @@ 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;
_color = _textcolor; _color = _textcolor;
tmp = &guifont[0]; tmp = &guifont[0];
tmp += 224 + (str + 1)*8; tmp += 224 + (str + 1) * 8;
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;
@ -126,7 +134,7 @@ void Gui::drawString(const char *str, int x, int y, int w, byte color, bool cent
st->right = x + w; st->right = x + w;
if (_s->_gameId) { /* If a game is active.. */ if (_s->_gameId) { /* If a game is active.. */
_s->_messagePtr = (byte*)str; _s->_messagePtr = (byte *)str;
_s->drawString(5); _s->drawString(5);
} else { } else {
for (uint letter = 0; letter < strlen(str); letter++) for (uint letter = 0; letter < strlen(str); letter++)
@ -134,9 +142,10 @@ 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;
x = w->_x; x = w->_x;
y = w->_y; y = w->_y;
@ -150,41 +159,45 @@ void Gui::drawWidget(const GuiWidget *w) {
y += 4; y += 4;
} }
switch(w->_type) { switch (w->_type) {
case GUI_CUSTOMTEXT: case GUI_CUSTOMTEXT:
case GUI_VARTEXT: case GUI_VARTEXT:
case GUI_KEYTEXT: case GUI_KEYTEXT:
case GUI_ACTIONTEXT: case GUI_ACTIONTEXT:
case GUI_RESTEXT: { case GUI_RESTEXT:{
char text[500]; char text[500];
text[0] = '\0'; text[0] = '\0';
switch(w->_type) { switch (w->_type) {
case GUI_CUSTOMTEXT: case GUI_CUSTOMTEXT:
strcpy(text, string_map_table_custom[w->_string_number]); strcpy(text, string_map_table_custom[w->_string_number]);
break; break;
case GUI_RESTEXT: case GUI_RESTEXT:
s = queryString(w->_string_number,w->_id); s = queryString(w->_string_number, w->_id);
if (s) if (s)
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
} }
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,81 +207,90 @@ 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;
y = wid->_y; y = wid->_y;
w = wid->_w; w = wid->_w;
h = wid->_h; h = wid->_h;
byte *ptr = getBasePtr(x,y); byte *ptr = getBasePtr(x, y);
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;
w-=2; w -= 2;
h-=2; h -= 2;
} }
while (--h>=0) { while (--h >= 0) {
for(i=0; i<w; i++) for (i = 0; i < w; i++)
ptr[i] = _bgcolor; ptr[i] = _bgcolor;
ptr += 320; ptr += 320;
} }
} }
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;
hline(x+1,y,x2-1); hline(x + 1, y, x2 - 1);
hline(x,y+1,x2); hline(x, y + 1, x2);
vline(x,y+1,y2-1); vline(x, y + 1, y2 - 1);
vline(x+1,y,y2); vline(x + 1, y, y2);
tmp = _color; tmp = _color;
_color = _shadowcolor; _color = _shadowcolor;
hline(x+1,y2-1,x2); hline(x + 1, y2 - 1, x2);
hline(x+1,y2,x2-1); hline(x + 1, y2, x2 - 1);
vline(x2,y+1,y2-1); vline(x2, y + 1, y2 - 1);
vline(x2-1,y+1,y2); vline(x2 - 1, y + 1, y2);
_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); {
lineto(x2,y); moveto(x, 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); {
lineto(x,y2); moveto(x, y);
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);
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;
@ -277,23 +299,23 @@ void Gui::lineto(int x, int y) {
_curY = y; _curY = y;
if (x2 < x) if (x2 < x)
x2^=x^=x2^=x; x2 ^= x ^= x2 ^= x;
if (y2 < y) if (y2 < y)
y2^=y^=y2^=y; y2 ^= y ^= y2 ^= y;
ptr = getBasePtr(x, y); ptr = getBasePtr(x, y);
if (ptr==NULL) if (ptr == NULL)
return; return;
if (x==x2) { if (x == x2) {
/* vertical line */ /* vertical line */
while (y++ <= y2) { while (y++ <= y2) {
*ptr = _color; *ptr = _color;
ptr += 320; ptr += 320;
} }
} else if (y==y2) { } else if (y == y2) {
/* horizontal line */ /* horizontal line */
while (x++ <= x2) { while (x++ <= x2) {
*ptr++ = _color; *ptr++ = _color;
@ -301,20 +323,21 @@ 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;
_clickTimer = 0; _clickTimer = 0;
old = _clickWidget; old = _clickWidget;
_clickWidget = w?w->_id : 0; _clickWidget = w ? w->_id : 0;
if (old) if (old)
draw(old); draw(old);
if (_clickWidget) { if (_clickWidget) {
draw(_clickWidget); draw(_clickWidget);
if(w->_flags&GWF_DELAY) if (w->_flags & GWF_DELAY)
_clickTimer = 5; _clickTimer = 5;
else else
handleCommand(_clickWidget); handleCommand(_clickWidget);
@ -324,71 +347,84 @@ void Gui::leftMouseClick(int x, int y) {
close(); close();
} }
const GuiWidget launcher_dialog[] = { const GuiWidget launcher_dialog[] = {
{GUI_STAT, 0xFF, GWF_DEFAULT, 0, 0, 320, 200, 0, 0 }, {GUI_STAT, 0xFF, GWF_DEFAULT, 0, 0, 320, 200, 0, 0},
{GUI_CUSTOMTEXT,0x01,GWF_CLEARBG, 5, 180, 45, 15, 20, 12}, {GUI_CUSTOMTEXT, 0x01, GWF_CLEARBG, 5, 180, 45, 15, 20, 12},
{GUI_CUSTOMTEXT,0x01,GWF_CLEARBG, 130, 180, 65, 15, 21,17}, {GUI_CUSTOMTEXT, 0x01, GWF_CLEARBG, 130, 180, 65, 15, 21, 17},
{GUI_CUSTOMTEXT,0x01,GWF_CLEARBG, 265, 180, 50, 15, 22, 7}, {GUI_CUSTOMTEXT, 0x01, GWF_CLEARBG, 265, 180, 50, 15, 22, 7},
{0,0,0,0,0,0,0,0,0} {0, 0, 0, 0, 0, 0, 0, 0, 0}
}; };
const GuiWidget keys_dialog[] = { const GuiWidget keys_dialog[] = {
{GUI_STAT, 0xFF, GWF_DEFAULT, 30, 10, 260, 130, 0, 0 }, {GUI_STAT, 0xFF, GWF_DEFAULT, 30, 10, 260, 130, 0, 0},
// 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},
{0,0,0,0,0,0,0,0,0} {0, 0, 0, 0, 0, 0, 0, 0, 0}
}; };
const GuiWidget about_dialog[] = { const GuiWidget about_dialog[] = {
{GUI_STAT, 0xFF, GWF_DEFAULT, 30, 20, 260, 120, 0, 0 }, {GUI_STAT, 0xFF, GWF_DEFAULT, 30, 20, 260, 120, 0, 0},
// {GUI_CUSTOMTEXT, 0x01, 0, 30 + 95, 20 + 10, 100, 15, 0, }, .. pocketscummvm // {GUI_CUSTOMTEXT, 0x01, 0, 30 + 95, 20 + 10, 100, 15, 0, }, .. pocketscummvm
{GUI_CUSTOMTEXT, 0x01, 0, 30 + 68, 20 + 10 + 15 + 5, 160, 15, 0, 9}, // Build {GUI_CUSTOMTEXT, 0x01, 0, 30 + 68, 20 + 10 + 15 + 5, 160, 15, 0, 9}, // Build
{GUI_CUSTOMTEXT, 0x01, 0, 30 + 10, 20 + 10 + 15 + 5 + 15, 230, 15, 0, 10}, // ScummVM Url {GUI_CUSTOMTEXT, 0x01, 0, 30 + 10, 20 + 10 + 15 + 5 + 15, 230, 15, 0, 10}, // ScummVM Url
{GUI_CUSTOMTEXT, 0x01, 0, 30 + 75, 20 + 10 + 15 + 5 + 15 + 15 + 15, 150, 15, 0, 11}, // Lucasarts {GUI_CUSTOMTEXT, 0x01, 0, 30 + 75, 20 + 10 + 15 + 5 + 15 + 15 + 15, 150, 15, 0, 11}, // Lucasarts
{GUI_RESTEXT, 0x01, GWF_BUTTON, 30 + 113, 20 + 96, 54, 16, 40, 9 }, {GUI_RESTEXT, 0x01, GWF_BUTTON, 30 + 113, 20 + 96, 54, 16, 40, 9},
{0,0,0,0,0,0,0,0,0} {0, 0, 0, 0, 0, 0, 0, 0, 0}
}; };
const GuiWidget options_dialog[] = { const GuiWidget options_dialog[] = {
{GUI_STAT, 0xFF, GWF_DEFAULT, 50, 80, 210, 35, 0, 0 }, {GUI_STAT, 0xFF, GWF_DEFAULT, 50, 80, 210, 35, 0, 0},
{GUI_CUSTOMTEXT, 0x01, GWF_BUTTON, 50 + 10 , 80 + 10, 40, 15, 1, 5}, // Sound {GUI_CUSTOMTEXT, 0x01, GWF_BUTTON, 50 + 10, 80 + 10, 40, 15, 1, 5}, // Sound
{GUI_CUSTOMTEXT, 0x01, GWF_BUTTON, 50 + 10 + 40 + 30 , 80 + 10, 40, 15 , 2, 6}, // Keys {GUI_CUSTOMTEXT, 0x01, GWF_BUTTON, 50 + 10 + 40 + 30, 80 + 10, 40, 15, 2, 6}, // Keys
{GUI_CUSTOMTEXT, 0x01, GWF_BUTTON, 50 + 10 + 40 + 30 + 40 + 30, 80 + 10, 40, 15, 3, 7}, // About {GUI_CUSTOMTEXT, 0x01, GWF_BUTTON, 50 + 10 + 40 + 30 + 40 + 30, 80 + 10, 40, 15, 3, 7}, // About
{0,0,0,0,0,0,0,0,0} {0, 0, 0, 0, 0, 0, 0, 0, 0}
}; };
const GuiWidget sound_dialog[] = { const GuiWidget sound_dialog[] = {
{GUI_STAT, 0xFF, GWF_DEFAULT, 30, 20, 260, 120, 0, 0 }, {GUI_STAT, 0xFF, GWF_DEFAULT, 30, 20, 260, 120, 0, 0},
{GUI_CUSTOMTEXT, 0x01, GWF_BUTTON, 30 + 11, 20 + 11, 15, 15, 1, 3}, // Plus {GUI_CUSTOMTEXT, 0x01, GWF_BUTTON, 30 + 11, 20 + 11, 15, 15, 1, 3}, // Plus
{GUI_CUSTOMTEXT, 0x01, GWF_BUTTON, 30 + 33, 20 + 11, 15, 15, 2, 4}, // Minus {GUI_CUSTOMTEXT, 0x01, GWF_BUTTON, 30 + 33, 20 + 11, 15, 15, 2, 4}, // Minus
{GUI_VARTEXT, 0x01, GWF_DEFAULT, 30 + 73, 20 + 11, 128, 15, 3, 0}, // Master {GUI_VARTEXT, 0x01, GWF_DEFAULT, 30 + 73, 20 + 11, 128, 15, 3, 0}, // Master
@ -398,55 +434,56 @@ const GuiWidget sound_dialog[] = {
{GUI_CUSTOMTEXT, 0x01, GWF_BUTTON, 30 + 11, 20 + 25 + 25 + 11, 15, 15, 21, 3}, // Plus {GUI_CUSTOMTEXT, 0x01, GWF_BUTTON, 30 + 11, 20 + 25 + 25 + 11, 15, 15, 21, 3}, // Plus
{GUI_CUSTOMTEXT, 0x01, GWF_BUTTON, 30 + 33, 20 + 25 + 25 + 11, 15, 15, 22, 4}, // Minus {GUI_CUSTOMTEXT, 0x01, GWF_BUTTON, 30 + 33, 20 + 25 + 25 + 11, 15, 15, 22, 4}, // Minus
{GUI_VARTEXT, 0x01, GWF_BUTTON, 30 + 73, 20 + 25 + 25 + 11, 128, 15, 23, 2}, // SFX {GUI_VARTEXT, 0x01, GWF_BUTTON, 30 + 73, 20 + 25 + 25 + 11, 128, 15, 23, 2}, // SFX
{GUI_RESTEXT,0x01,GWF_BUTTON,30 + (260 / 2) - 80, 20 + 25 + 25 + 11 + 25 ,54,16,40,9}, /* OK */ {GUI_RESTEXT, 0x01, GWF_BUTTON, 30 + (260 / 2) - 80, 20 + 25 + 25 + 11 + 25, 54, 16, 40, 9}, /* OK */
{GUI_RESTEXT,0x01,GWF_BUTTON,30 + (260 / 2), 20 + 25 + 25 + 11 + 25 ,54,16,50,7}, /* Cancel */ {GUI_RESTEXT, 0x01, GWF_BUTTON, 30 + (260 / 2), 20 + 25 + 25 + 11 + 25, 54, 16, 50, 7}, /* Cancel */
{0,0,0,0,0,0,0,0,0} {0, 0, 0, 0, 0, 0, 0, 0, 0}
}; };
const GuiWidget save_load_dialog[] = { const GuiWidget save_load_dialog[] = {
{GUI_STAT,0xFF,GWF_DEFAULT|GWF_PARENT,30,20,260,125,0,0}, {GUI_STAT, 0xFF, GWF_DEFAULT | GWF_PARENT, 30, 20, 260, 125, 0, 0},
{GUI_RESTEXT,0x01,0,40,5,128,16,0,1}, /* How may I serve you? */ {GUI_RESTEXT, 0x01, 0, 40, 5, 128, 16, 0, 1}, /* How may I serve you? */
{GUI_RESTEXT,0x02,0,40,5,128,16,0,2}, /* Select a game to LOAD */ {GUI_RESTEXT, 0x02, 0, 40, 5, 128, 16, 0, 2}, /* Select a game to LOAD */
{GUI_RESTEXT,0x04,0,40,5,128,16,0,3}, /* Name your SAVE game */ {GUI_RESTEXT, 0x04, 0, 40, 5, 128, 16, 0, 3}, /* Name your SAVE game */
{GUI_STAT,0xFF,GWF_DEFAULT,6,16,170,96,0,0}, {GUI_STAT, 0xFF, GWF_DEFAULT, 6, 16, 170, 96, 0, 0},
{GUI_RESTEXT,0x01,GWF_DEFAULT,180,20,16,40,0,0}, {GUI_RESTEXT, 0x01, GWF_DEFAULT, 180, 20, 16, 40, 0, 0},
{GUI_RESTEXT,0x01,GWF_DEFAULT,180,66,16,40,0,0}, {GUI_RESTEXT, 0x01, GWF_DEFAULT, 180, 66, 16, 40, 0, 0},
{GUI_RESTEXT,0xFE,GWF_DEFAULT,180,20,16,40,1,0}, {GUI_RESTEXT, 0xFE, GWF_DEFAULT, 180, 20, 16, 40, 1, 0},
{GUI_RESTEXT,0xFE,GWF_DEFAULT,180,66,16,40,2,0}, {GUI_RESTEXT, 0xFE, GWF_DEFAULT, 180, 66, 16, 40, 2, 0},
{GUI_RESTEXT,0x06,GWF_CLEARBG,10,20,160,10,20,0}, {GUI_RESTEXT, 0x06, GWF_CLEARBG, 10, 20, 160, 10, 20, 0},
{GUI_RESTEXT,0x06,GWF_CLEARBG,10,30,160,10,21,0}, {GUI_RESTEXT, 0x06, GWF_CLEARBG, 10, 30, 160, 10, 21, 0},
{GUI_RESTEXT,0x06,GWF_CLEARBG,10,40,160,10,22,0}, {GUI_RESTEXT, 0x06, GWF_CLEARBG, 10, 40, 160, 10, 22, 0},
{GUI_RESTEXT,0x06,GWF_CLEARBG,10,50,160,10,23,0}, {GUI_RESTEXT, 0x06, GWF_CLEARBG, 10, 50, 160, 10, 23, 0},
{GUI_RESTEXT,0x06,GWF_CLEARBG,10,60,160,10,24,0}, {GUI_RESTEXT, 0x06, GWF_CLEARBG, 10, 60, 160, 10, 24, 0},
{GUI_RESTEXT,0x06,GWF_CLEARBG,10,70,160,10,25,0}, {GUI_RESTEXT, 0x06, GWF_CLEARBG, 10, 70, 160, 10, 25, 0},
{GUI_RESTEXT,0x06,GWF_CLEARBG,10,80,160,10,26,0}, {GUI_RESTEXT, 0x06, GWF_CLEARBG, 10, 80, 160, 10, 26, 0},
{GUI_RESTEXT,0x06,GWF_CLEARBG,10,90,160,10,27,0}, {GUI_RESTEXT, 0x06, GWF_CLEARBG, 10, 90, 160, 10, 27, 0},
{GUI_RESTEXT,0x06,GWF_CLEARBG,10,100,160,10,28,0}, {GUI_RESTEXT, 0x06, GWF_CLEARBG, 10, 100, 160, 10, 28, 0},
{GUI_RESTEXT,0x01,GWF_BUTTON,200,25,54,16,3,4}, /* Save */ {GUI_RESTEXT, 0x01, GWF_BUTTON, 200, 25, 54, 16, 3, 4}, /* Save */
{GUI_RESTEXT,0x01,GWF_BUTTON,200,45,54,16,4,5}, /* Load */ {GUI_RESTEXT, 0x01, GWF_BUTTON, 200, 45, 54, 16, 4, 5}, /* Load */
{GUI_RESTEXT,0x01,GWF_BUTTON,200,65,54,16,5,6}, /* Play */ {GUI_RESTEXT, 0x01, GWF_BUTTON, 200, 65, 54, 16, 5, 6}, /* Play */
{GUI_CUSTOMTEXT,0x01,GWF_BUTTON,200,85,54,16,9,17}, /* Options */ {GUI_CUSTOMTEXT, 0x01, GWF_BUTTON, 200, 85, 54, 16, 9, 17}, /* Options */
{GUI_RESTEXT,0x01,GWF_BUTTON,200,105,54,16,6,8}, /* Quit */ {GUI_RESTEXT, 0x01, GWF_BUTTON, 200, 105, 54, 16, 6, 8}, /* Quit */
{GUI_RESTEXT,0x02,GWF_BUTTON,200,50,54,16,7,7}, /* Cancel */ {GUI_RESTEXT, 0x02, GWF_BUTTON, 200, 50, 54, 16, 7, 7}, /* Cancel */
{GUI_RESTEXT,0x04,GWF_BUTTON,200,45,54,16,8,9}, /* Ok */ {GUI_RESTEXT, 0x04, GWF_BUTTON, 200, 45, 54, 16, 8, 9}, /* Ok */
{GUI_RESTEXT,0x04,GWF_BUTTON,200,65,54,16,7,7}, /* Cancel */ {GUI_RESTEXT, 0x04, GWF_BUTTON, 200, 65, 54, 16, 7, 7}, /* Cancel */
{0,0,0,0,0,0,0,0,0} {0, 0, 0, 0, 0, 0, 0, 0, 0}
}; };
const GuiWidget pause_dialog[] = { const GuiWidget pause_dialog[] = {
{GUI_RESTEXT,0x01,GWF_DEFAULT,50,80,220,16,0,10}, {GUI_RESTEXT, 0x01, GWF_DEFAULT, 50, 80, 220, 16, 0, 10},
{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;
_s->_sound_volume_master = _gui_variables[0]; // Master _s->_sound_volume_master = _gui_variables[0]; // Master
_s->_sound_volume_music = _gui_variables[1]; // Music _s->_sound_volume_music = _gui_variables[1]; // Music
_s->_sound_volume_sfx = _gui_variables[2]; // SFX _s->_sound_volume_sfx = _gui_variables[2]; // SFX
@ -460,18 +497,18 @@ 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;
} }
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;
_gui_variables[0] = _s->_sound_volume_master; _gui_variables[0] = _s->_sound_volume_master;
@ -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,9 +566,10 @@ 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:
close(); close();
break; break;
@ -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);
@ -587,28 +627,28 @@ void Gui::handleCommand(int cmd) {
return; return;
} }
switch(cmd) { switch (cmd) {
case 1: /* up button */ case 1: /* up button */
if (_slotIndex==0) if (_slotIndex == 0)
return; return;
getSavegameNames(_slotIndex-9); getSavegameNames(_slotIndex - 9);
draw(20,28); draw(20, 28);
return; return;
case 2: case 2:
if (_slotIndex > 80) if (_slotIndex > 80)
return; return;
getSavegameNames(_slotIndex+9); getSavegameNames(_slotIndex + 9);
draw(20,28); draw(20, 28);
return; return;
case 3: /* save button */ case 3: /* save button */
_cur_page = 2; _cur_page = 2;
getSavegameNames(0); getSavegameNames(0);
draw(0,100); draw(0, 100);
return; return;
case 4: /* load button */ case 4: /* load button */
_cur_page = 1; _cur_page = 1;
getSavegameNames(0); getSavegameNames(0);
draw(0,100); draw(0, 100);
return; return;
case 5: /* play button */ case 5: /* play button */
close(); close();
@ -618,15 +658,16 @@ void Gui::handleCommand(int cmd) {
return; return;
case 7: /* cancel button */ case 7: /* cancel button */
_cur_page = 0; _cur_page = 0;
draw(0,100); draw(0, 100);
return; return;
case 8: case 8:
if (lastEdit==-1 || game_names[lastEdit][0]==0) if (lastEdit == -1 || game_names[lastEdit][0] == 0)
return; return;
_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 */
@ -634,16 +675,16 @@ void Gui::handleCommand(int cmd) {
draw(0, 100); draw(0, 100);
return; return;
default: default:
if (cmd>=20 && cmd<=28) { if (cmd >= 20 && cmd <= 28) {
if(_cur_page==1) { if (_cur_page == 1) {
if (valid_games[cmd-20]) { if (valid_games[cmd - 20]) {
_s->_saveLoadSlot = cmd-20+_slotIndex; _s->_saveLoadSlot = cmd - 20 + _slotIndex;
_s->_saveLoadCompatible = false; _s->_saveLoadCompatible = false;
_s->_saveLoadFlag = 2; _s->_saveLoadFlag = 2;
close(); close();
} }
return; return;
} else if (_cur_page==2) { } else if (_cur_page == 2) {
_clickWidget = cmd; _clickWidget = cmd;
editString(cmd - 20); editString(cmd - 20);
} }
@ -652,59 +693,61 @@ 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++) {
valid_games[i] = _s->getSavegameName(start, game_names[i]); valid_games[i] = _s->getSavegameName(start, game_names[i]);
} }
} }
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;
if (id>=20 && id<=28) { if (id >= 20 && id <= 28) {
sprintf(namebuf, "%2d. %s", id-20+_slotIndex, game_names[id-20]); sprintf(namebuf, "%2d. %s", id - 20 + _slotIndex, game_names[id - 20]);
return namebuf; return namebuf;
} }
if (stringno == 0) if (stringno == 0)
return NULL; return NULL;
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 if (_s->_features & GF_AFTER_V6)
string = _s->_vars[string_map_table_v6[stringno - 1].num];
else else
if (_s->_features&GF_AFTER_V6) string = string_map_table_v5[stringno - 1].num;
string = _s->_vars[string_map_table_v6[stringno-1].num];
else
string = string_map_table_v5[stringno-1].num;
result = (char*)_s->getStringAddress(string); result = (char *)_s->getStringAddress(string);
if (!result) // Gracelessly degrade to english :) if (!result) // Gracelessly degrade to english :)
if (_s->_features&GF_AFTER_V6) if (_s->_features & GF_AFTER_V6)
return string_map_table_v6[stringno-1].string; return string_map_table_v6[stringno - 1].string;
else else
return string_map_table_v5[stringno-1].string; return string_map_table_v5[stringno - 1].string;
return result; return result;
} }
void Gui::showCaret(bool show) { void Gui::showCaret(bool show)
{
int i; int i;
char *s; char *s;
if (_editString==-1) if (_editString == -1)
return; return;
i = _editLen; i = _editLen;
s = game_names[_editString]; s = game_names[_editString];
if (show) { if (show) {
if (i < SAVEGAME_NAME_LEN-1) { if (i < SAVEGAME_NAME_LEN - 1) {
s[i] = '_'; s[i] = '_';
s[i+1] = 0; s[i + 1] = 0;
} }
} else { } else {
s[i] = 0; s[i] = 0;
@ -716,9 +759,10 @@ 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;
*s = 0; *s = 0;
} }
@ -727,26 +771,27 @@ 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)
return; return;
if (letter==13) { if (letter == 13) {
handleCommand(8); handleCommand(8);
return; return;
} }
if (letter>=32 && letter<128 && _editLen < SAVEGAME_NAME_LEN-1) { if (letter >= 32 && letter < 128 && _editLen < SAVEGAME_NAME_LEN - 1) {
game_names[_editString][_editLen++] = letter; game_names[_editString][_editLen++] = letter;
} else if (letter==8 && _editLen>0) { } else if (letter == 8 && _editLen > 0) {
_editLen--; _editLen--;
} }
showCaret(true); showCaret(true);
break; break;
case PAUSE_DIALOG: case PAUSE_DIALOG:
if (letter==32) if (letter == 32)
close(); close();
break; break;
@ -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,18 +839,19 @@ 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++;
draw(0,200); // was 100 draw(0, 200); // was 100
_s->_cursorAnimate++; _s->_cursorAnimate++;
_s->gdi._cursorActive = 1; _s->gdi._cursorActive = 1;
_s->pauseSounds(true); _s->pauseSounds(true);
} }
_s->getKeyInput(0); _s->getKeyInput(0);
if (_s->_mouseButStat&MBS_LEFT_CLICK) { if (_s->_mouseButStat & MBS_LEFT_CLICK) {
leftMouseClick(_s->mouse.x, _s->mouse.y); leftMouseClick(_s->mouse.x, _s->mouse.y);
} else if (_s->_lastKeyHit) { } else if (_s->_lastKeyHit) {
if (_dialog != KEYS_DIALOG) if (_dialog != KEYS_DIALOG)
@ -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,69 +29,80 @@
#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,
_in = fopen((char*)buf, "rb"); (char *)fileName);
_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,
_in = fopen((char*)buf, "rb"); (char *)fileName);
_in = fopen((char *)buf, "rb");
} }
} }
void SmushPlayer::nextBlock() { void SmushPlayer::nextBlock()
{
_blockTag = fileReadBE32(); _blockTag = fileReadBE32();
_blockSize = fileReadBE32(); _blockSize = fileReadBE32();
if (_block != NULL) if (_block != NULL)
free(_block); free(_block);
_block = (byte*)malloc(_blockSize); _block = (byte *)malloc(_blockSize);
if (_block==NULL) if (_block == NULL)
error("cannot allocate memory"); error("cannot allocate memory");
fileRead(_block, _blockSize); fileRead(_block, _blockSize);
} }
bool SmushPlayer::parseTag() { bool SmushPlayer::parseTag()
switch(nextBlock(), _blockTag) { {
switch (nextBlock(), _blockTag) {
case 'AHDR': case 'AHDR':
parseAHDR(); parseAHDR();
@ -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,10 +140,11 @@ 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;
uint h = cd->h; uint h = cd->h;
if (!h || !cd->w) if (!h || !cd->w)
@ -143,8 +157,8 @@ void codec1(CodecData *cd) {
uint len, num; uint len, num;
uint x; uint x;
if ((uint)y >= (uint)cd->outheight) { if ((uint) y >= (uint) cd->outheight) {
src += *(uint16*)(src) + 2; src += *(uint16 *)(src) + 2;
continue; continue;
} }
@ -155,34 +169,36 @@ void codec1(CodecData *cd) {
do { do {
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) {
color = *src++; color = *src++;
// if ((color = *src++)!=0) { // if ((color = *src++)!=0) {
do { do {
if ((uint)x < (uint)cd->outwidth) if ((uint) x < (uint) cd->outwidth)
dest[x] = color; dest[x] = color;
} while (++x,--num); } while (++x, --num);
// } else { // } else {
// x += num; // x += num;
// } // }
} else { } else {
do { do {
color = *src++; color = *src++;
if (/*(color=*src++) != 0 &&*/ (uint)x < (uint)cd->outwidth) if ( /*(color=*src++) != 0 && */ (uint) x < (uint) cd->outwidth)
dest[x] = color; dest[x] = color;
} while (++x,--num); } while (++x, --num);
} }
} while (len); } while (len);
} while (dest += cd->pitch,y++,--h); } while (dest += cd->pitch, y++, --h);
} }
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;
@ -190,20 +206,22 @@ void codec37_bompdepack(byte *dst, byte *src, int len) {
do { do {
code = *src++; code = *src++;
if (code & 1) { if (code & 1) {
num = (code>>1) + 1; num = (code >> 1) + 1;
color = *src++; color = *src++;
memset(dst, color, num); memset(dst, color, num);
dst += num; dst += num;
} else { } else {
num = (code>>1) + 1; num = (code >> 1) + 1;
memcpy(dst,src,num); memcpy(dst, src, num);
dst += num; dst += num;
src += num; src += num;
} }
} 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;
@ -216,154 +234,157 @@ void codec37_proc5(byte *dst, byte *src, int next_offs, int bw, int bh, int pitc
i = bw; i = bw;
do { do {
code = *src++; code = *src++;
if (code==0xFF) { if (code == 0xFF) {
*(uint32*)(dst+0) = ((uint32*)src)[0]; *(uint32 *)(dst + 0) = ((uint32 *)src)[0];
*(uint32*)(dst+320) = ((uint32*)src)[1]; *(uint32 *)(dst + 320) = ((uint32 *)src)[1];
*(uint32*)(dst+320*2) = ((uint32*)src)[2]; *(uint32 *)(dst + 320 * 2) = ((uint32 *)src)[2];
*(uint32*)(dst+320*3) = ((uint32*)src)[3]; *(uint32 *)(dst + 320 * 3) = ((uint32 *)src)[3];
src += 16; src += 16;
dst += 4; dst += 4;
} else { } else {
tmp = dst + table[code] + next_offs; tmp = dst + table[code] + next_offs;
*(uint32*)(dst+0) = *(uint32*)(tmp); *(uint32 *)(dst + 0) = *(uint32 *)(tmp);
*(uint32*)(dst+320) = *(uint32*)(tmp+320); *(uint32 *)(dst + 320) = *(uint32 *)(tmp + 320);
*(uint32*)(dst+320*2) = *(uint32*)(tmp+320*2); *(uint32 *)(dst + 320 * 2) = *(uint32 *)(tmp + 320 * 2);
*(uint32*)(dst+320*3) = *(uint32*)(tmp+320*3); *(uint32 *)(dst + 320 * 3) = *(uint32 *)(tmp + 320 * 3);
dst += 4; dst += 4;
} }
} while(--i); } while (--i);
dst += 320*4 - 320; dst += 320 * 4 - 320;
} while (--bh); } while (--bh);
} }
static const int8 maketable_bytes[] = { static const int8 maketable_bytes[] = {
0, 0, 1, 0, 2, 0, 3, 0, 5, 0, 8, 0, 13, 0, 21, 0, 0, 0, 1, 0, 2, 0, 3, 0, 5, 0, 8, 0, 13, 0, 21, 0,
-1, 0, -2, 0, -3, 0, -5, 0, -8, 0, -13, 0, -17, 0, -21, 0, -1, 0, -2, 0, -3, 0, -5, 0, -8, 0, -13, 0, -17, 0, -21, 0,
0, 1, 1, 1, 2, 1, 3, 1, 5, 1, 8, 1, 13, 1, 21, 1, 0, 1, 1, 1, 2, 1, 3, 1, 5, 1, 8, 1, 13, 1, 21, 1,
-1, 1, -2, 1, -3, 1, -5, 1, -8, 1, -13, 1, -17, 1, -21, 1, -1, 1, -2, 1, -3, 1, -5, 1, -8, 1, -13, 1, -17, 1, -21, 1,
0, 2, 1, 2, 2, 2, 3, 2, 5, 2, 8, 2, 13, 2, 21, 2, 0, 2, 1, 2, 2, 2, 3, 2, 5, 2, 8, 2, 13, 2, 21, 2,
-1, 2, -2, 2, -3, 2, -5, 2, -8, 2, -13, 2, -17, 2, -21, 2, -1, 2, -2, 2, -3, 2, -5, 2, -8, 2, -13, 2, -17, 2, -21, 2,
0, 3, 1, 3, 2, 3, 3, 3, 5, 3, 8, 3, 13, 3, 21, 3, 0, 3, 1, 3, 2, 3, 3, 3, 5, 3, 8, 3, 13, 3, 21, 3,
-1, 3, -2, 3, -3, 3, -5, 3, -8, 3, -13, 3, -17, 3, -21, 3, -1, 3, -2, 3, -3, 3, -5, 3, -8, 3, -13, 3, -17, 3, -21, 3,
0, 5, 1, 5, 2, 5, 3, 5, 5, 5, 8, 5, 13, 5, 21, 5, 0, 5, 1, 5, 2, 5, 3, 5, 5, 5, 8, 5, 13, 5, 21, 5,
-1, 5, -2, 5, -3, 5, -5, 5, -8, 5, -13, 5, -17, 5, -21, 5, -1, 5, -2, 5, -3, 5, -5, 5, -8, 5, -13, 5, -17, 5, -21, 5,
0, 8, 1, 8, 2, 8, 3, 8, 5, 8, 8, 8, 13, 8, 21, 8, 0, 8, 1, 8, 2, 8, 3, 8, 5, 8, 8, 8, 13, 8, 21, 8,
-1, 8, -2, 8, -3, 8, -5, 8, -8, 8, -13, 8, -17, 8, -21, 8, -1, 8, -2, 8, -3, 8, -5, 8, -8, 8, -13, 8, -17, 8, -21, 8,
0, 13, 1, 13, 2, 13, 3, 13, 5, 13, 8, 13, 13, 13, 21, 13, 0, 13, 1, 13, 2, 13, 3, 13, 5, 13, 8, 13, 13, 13, 21, 13,
-1, 13, -2, 13, -3, 13, -5, 13, -8, 13, -13, 13, -17, 13, -21, 13, -1, 13, -2, 13, -3, 13, -5, 13, -8, 13, -13, 13, -17, 13, -21, 13,
0, 21, 1, 21, 2, 21, 3, 21, 5, 21, 8, 21, 13, 21, 21, 21, 0, 21, 1, 21, 2, 21, 3, 21, 5, 21, 8, 21, 13, 21, 21, 21,
-1, 21, -2, 21, -3, 21, -5, 21, -8, 21, -13, 21, -17, 21, -21, 21, -1, 21, -2, 21, -3, 21, -5, 21, -8, 21, -13, 21, -17, 21, -21, 21,
0, -1, 1, -1, 2, -1, 3, -1, 5, -1, 8, -1, 13, -1, 21, -1, 0, -1, 1, -1, 2, -1, 3, -1, 5, -1, 8, -1, 13, -1, 21, -1,
-1, -1, -2, -1, -3, -1, -5, -1, -8, -1, -13, -1, -17, -1, -21, -1, -1, -1, -2, -1, -3, -1, -5, -1, -8, -1, -13, -1, -17, -1, -21, -1,
0, -2, 1, -2, 2, -2, 3, -2, 5, -2, 8, -2, 13, -2, 21, -2, 0, -2, 1, -2, 2, -2, 3, -2, 5, -2, 8, -2, 13, -2, 21, -2,
-1, -2, -2, -2, -3, -2, -5, -2, -8, -2, -13, -2, -17, -2, -21, -2, -1, -2, -2, -2, -3, -2, -5, -2, -8, -2, -13, -2, -17, -2, -21, -2,
0, -3, 1, -3, 2, -3, 3, -3, 5, -3, 8, -3, 13, -3, 21, -3, 0, -3, 1, -3, 2, -3, 3, -3, 5, -3, 8, -3, 13, -3, 21, -3,
-1, -3, -2, -3, -3, -3, -5, -3, -8, -3, -13, -3, -17, -3, -21, -3, -1, -3, -2, -3, -3, -3, -5, -3, -8, -3, -13, -3, -17, -3, -21, -3,
0, -5, 1, -5, 2, -5, 3, -5, 5, -5, 8, -5, 13, -5, 21, -5, 0, -5, 1, -5, 2, -5, 3, -5, 5, -5, 8, -5, 13, -5, 21, -5,
-1, -5, -2, -5, -3, -5, -5, -5, -8, -5, -13, -5, -17, -5, -21, -5, -1, -5, -2, -5, -3, -5, -5, -5, -8, -5, -13, -5, -17, -5, -21, -5,
0, -8, 1, -8, 2, -8, 3, -8, 5, -8, 8, -8, 13, -8, 21, -8, 0, -8, 1, -8, 2, -8, 3, -8, 5, -8, 8, -8, 13, -8, 21, -8,
-1, -8, -2, -8, -3, -8, -5, -8, -8, -8, -13, -8, -17, -8, -21, -8, -1, -8, -2, -8, -3, -8, -5, -8, -8, -8, -13, -8, -17, -8, -21, -8,
0, -13, 1, -13, 2, -13, 3, -13, 5, -13, 8, -13, 13, -13, 21, -13, 0, -13, 1, -13, 2, -13, 3, -13, 5, -13, 8, -13, 13, -13, 21, -13,
-1, -13, -2, -13, -3, -13, -5, -13, -8, -13, -13, -13, -17, -13, -21, -13, -1, -13, -2, -13, -3, -13, -5, -13, -8, -13, -13, -13, -17, -13, -21, -13,
0, -17, 1, -17, 2, -17, 3, -17, 5, -17, 8, -17, 13, -17, 21, -17, 0, -17, 1, -17, 2, -17, 3, -17, 5, -17, 8, -17, 13, -17, 21, -17,
-1, -17, -2, -17, -3, -17, -5, -17, -8, -17, -13, -17, -17, -17, -21, -17, -1, -17, -2, -17, -3, -17, -5, -17, -8, -17, -13, -17, -17, -17, -21, -17,
0, -21, 1, -21, 2, -21, 3, -21, 5, -21, 8, -21, 13, -21, 21, -21, 0, -21, 1, -21, 2, -21, 3, -21, 5, -21, 8, -21, 13, -21, 21, -21,
-1, -21, -2, -21, -3, -21, -5, -21, -8, -21, -13, -21, -17, -21, 0, 0, -1, -21, -2, -21, -3, -21, -5, -21, -8, -21, -13, -21, -17, -21, 0, 0,
-8, -29, 8, -29, -18, -25, 17, -25, 0, -23, -6, -22, 6, -22, -13, -19, -8, -29, 8, -29, -18, -25, 17, -25, 0, -23, -6, -22, 6, -22, -13, -19,
12, -19, 0, -18, 25, -18, -25, -17, -5, -17, 5, -17, -10, -15, 10, -15, 12, -19, 0, -18, 25, -18, -25, -17, -5, -17, 5, -17, -10, -15, 10, -15,
0, -14, -4, -13, 4, -13, 19, -13, -19, -12, -8, -11, -2, -11, 0, -11, 0, -14, -4, -13, 4, -13, 19, -13, -19, -12, -8, -11, -2, -11, 0, -11,
2, -11, 8, -11, -15, -10, -4, -10, 4, -10, 15, -10, -6, -9, -1, -9, 2, -11, 8, -11, -15, -10, -4, -10, 4, -10, 15, -10, -6, -9, -1, -9,
1, -9, 6, -9, -29, -8, -11, -8, -8, -8, -3, -8, 3, -8, 8, -8, 1, -9, 6, -9, -29, -8, -11, -8, -8, -8, -3, -8, 3, -8, 8, -8,
11, -8, 29, -8, -5, -7, -2, -7, 0, -7, 2, -7, 5, -7, -22, -6, 11, -8, 29, -8, -5, -7, -2, -7, 0, -7, 2, -7, 5, -7, -22, -6,
-9, -6, -6, -6, -3, -6, -1, -6, 1, -6, 3, -6, 6, -6, 9, -6, -9, -6, -6, -6, -3, -6, -1, -6, 1, -6, 3, -6, 6, -6, 9, -6,
22, -6, -17, -5, -7, -5, -4, -5, -2, -5, 0, -5, 2, -5, 4, -5, 22, -6, -17, -5, -7, -5, -4, -5, -2, -5, 0, -5, 2, -5, 4, -5,
7, -5, 17, -5, -13, -4, -10, -4, -5, -4, -3, -4, -1, -4, 0, -4, 7, -5, 17, -5, -13, -4, -10, -4, -5, -4, -3, -4, -1, -4, 0, -4,
1, -4, 3, -4, 5, -4, 10, -4, 13, -4, -8, -3, -6, -3, -4, -3, 1, -4, 3, -4, 5, -4, 10, -4, 13, -4, -8, -3, -6, -3, -4, -3,
-3, -3, -2, -3, -1, -3, 0, -3, 1, -3, 2, -3, 4, -3, 6, -3, -3, -3, -2, -3, -1, -3, 0, -3, 1, -3, 2, -3, 4, -3, 6, -3,
8, -3, -11, -2, -7, -2, -5, -2, -3, -2, -2, -2, -1, -2, 0, -2, 8, -3, -11, -2, -7, -2, -5, -2, -3, -2, -2, -2, -1, -2, 0, -2,
1, -2, 2, -2, 3, -2, 5, -2, 7, -2, 11, -2, -9, -1, -6, -1, 1, -2, 2, -2, 3, -2, 5, -2, 7, -2, 11, -2, -9, -1, -6, -1,
-4, -1, -3, -1, -2, -1, -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, -4, -1, -3, -1, -2, -1, -1, -1, 0, -1, 1, -1, 2, -1, 3, -1,
4, -1, 6, -1, 9, -1, -31, 0, -23, 0, -18, 0, -14, 0, -11, 0, 4, -1, 6, -1, 9, -1, -31, 0, -23, 0, -18, 0, -14, 0, -11, 0,
-7, 0, -5, 0, -4, 0, -3, 0, -2, 0, -1, 0, 0, -31, 1, 0, -7, 0, -5, 0, -4, 0, -3, 0, -2, 0, -1, 0, 0, -31, 1, 0,
2, 0, 3, 0, 4, 0, 5, 0, 7, 0, 11, 0, 14, 0, 18, 0, 2, 0, 3, 0, 4, 0, 5, 0, 7, 0, 11, 0, 14, 0, 18, 0,
23, 0, 31, 0, -9, 1, -6, 1, -4, 1, -3, 1, -2, 1, -1, 1, 23, 0, 31, 0, -9, 1, -6, 1, -4, 1, -3, 1, -2, 1, -1, 1,
0, 1, 1, 1, 2, 1, 3, 1, 4, 1, 6, 1, 9, 1, -11, 2, 0, 1, 1, 1, 2, 1, 3, 1, 4, 1, 6, 1, 9, 1, -11, 2,
-7, 2, -5, 2, -3, 2, -2, 2, -1, 2, 0, 2, 1, 2, 2, 2, -7, 2, -5, 2, -3, 2, -2, 2, -1, 2, 0, 2, 1, 2, 2, 2,
3, 2, 5, 2, 7, 2, 11, 2, -8, 3, -6, 3, -4, 3, -2, 3, 3, 2, 5, 2, 7, 2, 11, 2, -8, 3, -6, 3, -4, 3, -2, 3,
-1, 3, 0, 3, 1, 3, 2, 3, 3, 3, 4, 3, 6, 3, 8, 3, -1, 3, 0, 3, 1, 3, 2, 3, 3, 3, 4, 3, 6, 3, 8, 3,
-13, 4, -10, 4, -5, 4, -3, 4, -1, 4, 0, 4, 1, 4, 3, 4, -13, 4, -10, 4, -5, 4, -3, 4, -1, 4, 0, 4, 1, 4, 3, 4,
5, 4, 10, 4, 13, 4, -17, 5, -7, 5, -4, 5, -2, 5, 0, 5, 5, 4, 10, 4, 13, 4, -17, 5, -7, 5, -4, 5, -2, 5, 0, 5,
2, 5, 4, 5, 7, 5, 17, 5, -22, 6, -9, 6, -6, 6, -3, 6, 2, 5, 4, 5, 7, 5, 17, 5, -22, 6, -9, 6, -6, 6, -3, 6,
-1, 6, 1, 6, 3, 6, 6, 6, 9, 6, 22, 6, -5, 7, -2, 7, -1, 6, 1, 6, 3, 6, 6, 6, 9, 6, 22, 6, -5, 7, -2, 7,
0, 7, 2, 7, 5, 7, -29, 8, -11, 8, -8, 8, -3, 8, 3, 8, 0, 7, 2, 7, 5, 7, -29, 8, -11, 8, -8, 8, -3, 8, 3, 8,
8, 8, 11, 8, 29, 8, -6, 9, -1, 9, 1, 9, 6, 9, -15, 10, 8, 8, 11, 8, 29, 8, -6, 9, -1, 9, 1, 9, 6, 9, -15, 10,
-4, 10, 4, 10, 15, 10, -8, 11, -2, 11, 0, 11, 2, 11, 8, 11, -4, 10, 4, 10, 15, 10, -8, 11, -2, 11, 0, 11, 2, 11, 8, 11,
19, 12, -19, 13, -4, 13, 4, 13, 0, 14, -10, 15, 10, 15, -5, 17, 19, 12, -19, 13, -4, 13, 4, 13, 0, 14, -10, 15, 10, 15, -5, 17,
5, 17, 25, 17, -25, 18, 0, 18, -12, 19, 13, 19, -6, 22, 6, 22, 5, 17, 25, 17, -25, 18, 0, 18, -12, 19, 13, 19, -6, 22, 6, 22,
0, 23, -17, 25, 18, 25, -8, 29, 8, 29, 0, 31, 0, 0, -6, -22, 0, 23, -17, 25, 18, 25, -8, 29, 8, 29, 0, 31, 0, 0, -6, -22,
6, -22, -13, -19, 12, -19, 0, -18, -5, -17, 5, -17, -10, -15, 10, -15, 6, -22, -13, -19, 12, -19, 0, -18, -5, -17, 5, -17, -10, -15, 10, -15,
0, -14, -4, -13, 4, -13, 19, -13, -19, -12, -8, -11, -2, -11, 0, -11, 0, -14, -4, -13, 4, -13, 19, -13, -19, -12, -8, -11, -2, -11, 0, -11,
2, -11, 8, -11, -15, -10, -4, -10, 4, -10, 15, -10, -6, -9, -1, -9, 2, -11, 8, -11, -15, -10, -4, -10, 4, -10, 15, -10, -6, -9, -1, -9,
1, -9, 6, -9, -11, -8, -8, -8, -3, -8, 0, -8, 3, -8, 8, -8, 1, -9, 6, -9, -11, -8, -8, -8, -3, -8, 0, -8, 3, -8, 8, -8,
11, -8, -5, -7, -2, -7, 0, -7, 2, -7, 5, -7, -22, -6, -9, -6, 11, -8, -5, -7, -2, -7, 0, -7, 2, -7, 5, -7, -22, -6, -9, -6,
-6, -6, -3, -6, -1, -6, 1, -6, 3, -6, 6, -6, 9, -6, 22, -6, -6, -6, -3, -6, -1, -6, 1, -6, 3, -6, 6, -6, 9, -6, 22, -6,
-17, -5, -7, -5, -4, -5, -2, -5, -1, -5, 0, -5, 1, -5, 2, -5, -17, -5, -7, -5, -4, -5, -2, -5, -1, -5, 0, -5, 1, -5, 2, -5,
4, -5, 7, -5, 17, -5, -13, -4, -10, -4, -5, -4, -3, -4, -2, -4, 4, -5, 7, -5, 17, -5, -13, -4, -10, -4, -5, -4, -3, -4, -2, -4,
-1, -4, 0, -4, 1, -4, 2, -4, 3, -4, 5, -4, 10, -4, 13, -4, -1, -4, 0, -4, 1, -4, 2, -4, 3, -4, 5, -4, 10, -4, 13, -4,
-8, -3, -6, -3, -4, -3, -3, -3, -2, -3, -1, -3, 0, -3, 1, -3, -8, -3, -6, -3, -4, -3, -3, -3, -2, -3, -1, -3, 0, -3, 1, -3,
2, -3, 3, -3, 4, -3, 6, -3, 8, -3, -11, -2, -7, -2, -5, -2, 2, -3, 3, -3, 4, -3, 6, -3, 8, -3, -11, -2, -7, -2, -5, -2,
-4, -2, -3, -2, -2, -2, -1, -2, 0, -2, 1, -2, 2, -2, 3, -2, -4, -2, -3, -2, -2, -2, -1, -2, 0, -2, 1, -2, 2, -2, 3, -2,
4, -2, 5, -2, 7, -2, 11, -2, -9, -1, -6, -1, -5, -1, -4, -1, 4, -2, 5, -2, 7, -2, 11, -2, -9, -1, -6, -1, -5, -1, -4, -1,
-3, -1, -2, -1, -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, 4, -1, -3, -1, -2, -1, -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, 4, -1,
5, -1, 6, -1, 9, -1, -23, 0, -18, 0, -14, 0, -11, 0, -7, 0, 5, -1, 6, -1, 9, -1, -23, 0, -18, 0, -14, 0, -11, 0, -7, 0,
-5, 0, -4, 0, -3, 0, -2, 0, -1, 0, 0, -23, 1, 0, 2, 0, -5, 0, -4, 0, -3, 0, -2, 0, -1, 0, 0, -23, 1, 0, 2, 0,
3, 0, 4, 0, 5, 0, 7, 0, 11, 0, 14, 0, 18, 0, 23, 0, 3, 0, 4, 0, 5, 0, 7, 0, 11, 0, 14, 0, 18, 0, 23, 0,
-9, 1, -6, 1, -5, 1, -4, 1, -3, 1, -2, 1, -1, 1, 0, 1, -9, 1, -6, 1, -5, 1, -4, 1, -3, 1, -2, 1, -1, 1, 0, 1,
1, 1, 2, 1, 3, 1, 4, 1, 5, 1, 6, 1, 9, 1, -11, 2, 1, 1, 2, 1, 3, 1, 4, 1, 5, 1, 6, 1, 9, 1, -11, 2,
-7, 2, -5, 2, -4, 2, -3, 2, -2, 2, -1, 2, 0, 2, 1, 2, -7, 2, -5, 2, -4, 2, -3, 2, -2, 2, -1, 2, 0, 2, 1, 2,
2, 2, 3, 2, 4, 2, 5, 2, 7, 2, 11, 2, -8, 3, -6, 3, 2, 2, 3, 2, 4, 2, 5, 2, 7, 2, 11, 2, -8, 3, -6, 3,
-4, 3, -3, 3, -2, 3, -1, 3, 0, 3, 1, 3, 2, 3, 3, 3, -4, 3, -3, 3, -2, 3, -1, 3, 0, 3, 1, 3, 2, 3, 3, 3,
4, 3, 6, 3, 8, 3, -13, 4, -10, 4, -5, 4, -3, 4, -2, 4, 4, 3, 6, 3, 8, 3, -13, 4, -10, 4, -5, 4, -3, 4, -2, 4,
-1, 4, 0, 4, 1, 4, 2, 4, 3, 4, 5, 4, 10, 4, 13, 4, -1, 4, 0, 4, 1, 4, 2, 4, 3, 4, 5, 4, 10, 4, 13, 4,
-17, 5, -7, 5, -4, 5, -2, 5, -1, 5, 0, 5, 1, 5, 2, 5, -17, 5, -7, 5, -4, 5, -2, 5, -1, 5, 0, 5, 1, 5, 2, 5,
4, 5, 7, 5, 17, 5, -22, 6, -9, 6, -6, 6, -3, 6, -1, 6, 4, 5, 7, 5, 17, 5, -22, 6, -9, 6, -6, 6, -3, 6, -1, 6,
1, 6, 3, 6, 6, 6, 9, 6, 22, 6, -5, 7, -2, 7, 0, 7, 1, 6, 3, 6, 6, 6, 9, 6, 22, 6, -5, 7, -2, 7, 0, 7,
2, 7, 5, 7, -11, 8, -8, 8, -3, 8, 0, 8, 3, 8, 8, 8, 2, 7, 5, 7, -11, 8, -8, 8, -3, 8, 0, 8, 3, 8, 8, 8,
11, 8, -6, 9, -1, 9, 1, 9, 6, 9, -15, 10, -4, 10, 4, 10, 11, 8, -6, 9, -1, 9, 1, 9, 6, 9, -15, 10, -4, 10, 4, 10,
15, 10, -8, 11, -2, 11, 0, 11, 2, 11, 8, 11, 19, 12, -19, 13, 15, 10, -8, 11, -2, 11, 0, 11, 2, 11, 8, 11, 19, 12, -19, 13,
-4, 13, 4, 13, 0, 14, -10, 15, 10, 15, -5, 17, 5, 17, 0, 18, -4, 13, 4, 13, 0, 14, -10, 15, 10, 15, -5, 17, 5, 17, 0, 18,
-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)
return; return;
pcd->table_last_pitch = pitch; pcd->table_last_pitch = pitch;
pcd->table_last_flags = idx; pcd->table_last_flags = idx;
assert(idx*255 + 254 < (int)(sizeof(maketable_bytes)/2)); assert(idx * 255 + 254 < (int)(sizeof(maketable_bytes) / 2));
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;
uint size; uint size;
bool result = false; bool result = false;
_frameChanged=1; _frameChanged = 1;
width_in_blocks = (cd->w + 3) >> 2; width_in_blocks = (cd->w + 3) >> 2;
height_in_blocks = (cd->h + 3) >> 2; height_in_blocks = (cd->h + 3) >> 2;
@ -371,84 +392,88 @@ int codec37(CodecData *cd, PersistentCodecData37 *pcd) {
codec37_maketable(pcd, src_pitch, cd->src[1]); codec37_maketable(pcd, src_pitch, cd->src[1]);
switch(cd->src[0]) { switch (cd->src[0]) {
case 0: { case 0:{
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;
} }
case 2: { case 2:{
size = *(uint32*)(cd->src + 4); size = *(uint32 *)(cd->src + 4);
curbuf = pcd->deltaBufs[pcd->curtable]; curbuf = pcd->deltaBufs[pcd->curtable];
if(size==64000) if (size == 64000)
codec37_bompdepack(curbuf, cd->src+16, size); codec37_bompdepack(curbuf, cd->src + 16, size);
else else
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;
} }
case 3: { case 3:{
uint16 number = *(uint16*)(cd->src + 2); uint16 number = *(uint16 *)(cd->src + 2);
if ( number && pcd->flags+1 != number) if (number && pcd->flags + 1 != number)
break; break;
if (number&1 && cd->src[12]&1 && cd->flags&0x10) { if (number & 1 && cd->src[12] & 1 && cd->flags & 0x10) {
_frameChanged = 0; _frameChanged = 0;
result=true; result = true;
break; break;
} }
if ((number&1) || !(cd->src[12]&1)) { if ((number & 1) || !(cd->src[12] & 1)) {
pcd->curtable ^= 1; pcd->curtable ^= 1;
} }
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;
} }
case 1: case 1:
case 4: case 4:
warning("code %d", cd->src[0]); warning("code %d", cd->src[0]);
return(1); return (1);
default: default:
error("codec37 default case"); error("codec37 default case");
} }
pcd->flags = *(uint16*)(cd->src + 2); pcd->flags = *(uint16 *)(cd->src + 2);
if (result) { if (result) {
pcd->curtable ^= 1; pcd->curtable ^= 1;
} else { } else {
memcpy(cd->out, pcd->deltaBufs[pcd->curtable], 320*200); memcpy(cd->out, pcd->deltaBufs[pcd->curtable], 320 * 200);
} }
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;
pcd->deltaBuf = (byte*)calloc(pcd->deltaSize, 1); pcd->deltaBuf = (byte *)calloc(pcd->deltaSize, 1);
pcd->deltaBufs[0] = pcd->deltaBuf + 0x3E00; pcd->deltaBufs[0] = pcd->deltaBuf + 0x3E00;
pcd->deltaBufs[1] = pcd->deltaBuf + width * height + 0xBA00; pcd->deltaBufs[1] = pcd->deltaBuf + width * height + 0xBA00;
pcd->curtable = 0; pcd->curtable = 0;
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;
@ -458,12 +483,12 @@ void SmushPlayer::parseFOBJ() {
cd.y = 0; cd.y = 0;
cd.x = 0; cd.x = 0;
cd.src = _cur + 0xE; cd.src = _cur + 0xE;
cd.w = *(uint16*)(_cur + 6); cd.w = *(uint16 *)(_cur + 6);
cd.h = *(uint16*)(_cur + 8); cd.h = *(uint16 *)(_cur + 8);
codec = _cur[0]; codec = _cur[0];
switch(codec) { switch (codec) {
case 1: case 1:
codec1(&cd); codec1(&cd);
break; break;
@ -475,48 +500,52 @@ 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;
num = *(uint16*)(_cur + 2); num = *(uint16 *)(_cur + 2);
if (num==0 || num==0x200) { if (num == 0 || num == 0x200) {
if (num==0x200) if (num == 0x200)
memcpy(_fluPalette, _cur + 0x604, 0x300); memcpy(_fluPalette, _cur + 0x604, 0x300);
for(i=0; i<0x300; i++) { for (i = 0; i < 0x300; i++) {
_fluPalMul129[i] = _fluPalette[i] * 129; _fluPalMul129[i] = _fluPalette[i] * 129;
_fluPalWords[i] = *(uint16*)(_cur + 4 + i*2); _fluPalWords[i] = *(uint16 *)(_cur + 4 + i * 2);
} }
return; return;
} }
parseNPAL(); parseNPAL();
for(i=0; i<0x300; i++) { for (i = 0; i < 0x300; i++) {
_fluPalMul129[i] += _fluPalWords[i]; _fluPalMul129[i] += _fluPalWords[i];
_fluPalette[i] = _fluPalMul129[i]>>7; _fluPalette[i] = _fluPalMul129[i] >> 7;
} }
_paletteChanged = true; _paletteChanged = true;
} }
void SmushPlayer::parseFRME() { void SmushPlayer::parseFRME()
{
_cur = _block; _cur = _block;
do { do {
_frmeTag = nextBE32(); _frmeTag = nextBE32();
_frmeSize = nextBE32(); _frmeSize = nextBE32();
switch(_frmeTag) { switch (_frmeTag) {
case 'NPAL': case 'NPAL':
parseNPAL(); parseNPAL();
break; break;
@ -547,63 +576,67 @@ 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++)
sm->_currentPalette[i]=_fluPalette[i]; sm->_currentPalette[i] = _fluPalette[i];
} }
void SmushPlayer::startVideo(short int arg, byte* videoFile) void SmushPlayer::startVideo(short int arg, byte *videoFile)
{ {
int frameIndex=0; int frameIndex = 0;
_in=NULL; _in = NULL;
_paletteChanged=0; _paletteChanged = 0;
_block=NULL; _block = NULL;
_blockTag=0; _blockTag = 0;
_blockSize=0; _blockSize = 0;
_cur=NULL; _cur = NULL;
_renderBitmap=NULL; _renderBitmap = NULL;
_frameSize=0; _frameSize = 0;
_frmeTag=0; _frmeTag = 0;
_frmeSize=0; _frmeSize = 0;
_deltaBuf=NULL; _deltaBuf = NULL;
_deltaBufSize=0; _deltaBufSize = 0;
pcd37.deltaBuf=NULL; pcd37.deltaBuf = NULL;
pcd37.deltaBufs[0]=NULL; pcd37.deltaBufs[0] = NULL;
pcd37.deltaBufs[1]=NULL; pcd37.deltaBufs[1] = NULL;
pcd37.deltaSize=0; pcd37.deltaSize = 0;
pcd37.width=0; pcd37.width = 0;
pcd37.height=0; pcd37.height = 0;
pcd37.curtable=0; pcd37.curtable = 0;
pcd37.unk2=0; pcd37.unk2 = 0;
pcd37.unk3=0; pcd37.unk3 = 0;
pcd37.flags=0; pcd37.flags = 0;
pcd37.table1=NULL; pcd37.table1 = NULL;
pcd37.table_last_pitch=0; pcd37.table_last_pitch = 0;
pcd37.table_last_flags=0; pcd37.table_last_flags = 0;
init(); init();
openFile(videoFile); openFile(videoFile);
if(_in==NULL) if (_in == NULL)
return; return;
if (fileReadBE32() != 'ANIM') if (fileReadBE32() != 'ANIM')
error("file is not an anim"); error("file is not an anim");
fileSize=fileReadBE32(); fileSize = fileReadBE32();
sm->videoFinished = 0; sm->videoFinished = 0;
sm->_insaneState = 1; sm->_insaneState = 1;
@ -613,10 +646,10 @@ void SmushPlayer::startVideo(short int arg, byte* videoFile)
do { do {
_frameChanged = 1; _frameChanged = 1;
if(ftell(_in)>=fileSize ) if (ftell(_in) >= fileSize)
return; return;
#ifdef INSANE_DEBUG #ifdef INSANE_DEBUG
warning("Playing frame %d",frameIndex); warning("Playing frame %d", frameIndex);
#endif #endif
parseTag(); parseTag();
@ -628,9 +661,8 @@ 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);
sm->delta = sm->_system->waitTick(sm->delta); sm->delta = sm->_system->waitTick(sm->delta);
@ -646,6 +678,3 @@ void SmushPlayer::startVideo(short int arg, byte* videoFile)
sm->exitCutscene(); sm->exitCutscene();
} }

View file

@ -83,7 +83,7 @@ int xing_parse(struct xing *xing, struct mad_bitptr ptr, unsigned int bitlen)
return 0; return 0;
fail: fail:
xing->flags = 0; xing->flags = 0;
return -1; return -1;
} }
@ -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,41 +165,44 @@ 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;
} }
fx = fa + (fb-fa)*(percent-a); fx = fa + (fb - fa) * (percent - a);
offset = (int)((1.0f/256.0f)*fx*_vbr_header.bytes); offset = (int)((1.0f / 256.0f) * fx * _vbr_header.bytes);
} }
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) {
@ -255,7 +256,7 @@ bool mp3_cd_play(Scumm *s, int track, int num_loops, int start_frame, int end_fr
/* see if it's enough */ /* see if it's enough */
mad_stream_init(&_mc->sound_data.mp3.stream); mad_stream_init(&_mc->sound_data.mp3.stream);
if (_mad_header.samplerate == 44100) if (_mad_header.samplerate == 44100)
mad_stream_options((mad_stream*)&_mc->sound_data.mp3.stream, mad_stream_options((mad_stream *) & _mc->sound_data.mp3.stream,
MAD_OPTION_HALFSAMPLERATE); MAD_OPTION_HALFSAMPLERATE);
mad_frame_init(&_mc->sound_data.mp3.frame); mad_frame_init(&_mc->sound_data.mp3.frame);
@ -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

File diff suppressed because it is too large Load diff

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.

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -26,35 +26,39 @@
#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;
debug(9, "scummInit"); debug(9, "scummInit");
if(_features & GF_SMALL_HEADER) if (_features & GF_SMALL_HEADER)
_resourceHeaderSize = 6; _resourceHeaderSize = 6;
else else
_resourceHeaderSize = 8; _resourceHeaderSize = 8;
if(!(_features & GF_SMALL_NAMES)) if (!(_features & GF_SMALL_NAMES))
loadCharset(1); loadCharset(1);
initScreens(0, 16, 320, 144); initScreens(0, 16, 320, 144);
@ -62,7 +66,7 @@ void Scumm::scummInit() {
setShake(0); setShake(0);
setupCursor(); setupCursor();
for (i=1,a=getFirstActor(); ++a,i<NUM_ACTORS; i++) { for (i = 1, a = getFirstActor(); ++a, i < NUM_ACTORS; i++) {
a->number = i; a->number = i;
initActor(a, 1); initActor(a, 1);
} }
@ -76,7 +80,7 @@ void Scumm::scummInit() {
memset(vm.cutScenePtr, 0, sizeof(vm.cutScenePtr)); memset(vm.cutScenePtr, 0, sizeof(vm.cutScenePtr));
memset(vm.cutSceneData, 0, sizeof(vm.cutSceneData)); memset(vm.cutSceneData, 0, sizeof(vm.cutSceneData));
for (i=0; i<_maxVerbs; i++) { for (i = 0; i < _maxVerbs; i++) {
_verbs[i].verbid = 0; _verbs[i].verbid = 0;
_verbs[i].right = 319; _verbs[i].right = 319;
_verbs[i].oldleft = -1; _verbs[i].oldleft = -1;
@ -86,11 +90,11 @@ void Scumm::scummInit() {
_verbs[i].charset_nr = 1; _verbs[i].charset_nr = 1;
_verbs[i].curmode = 0; _verbs[i].curmode = 0;
_verbs[i].saveid = 0; _verbs[i].saveid = 0;
_verbs[i].center=0; _verbs[i].center = 0;
_verbs[i].key = 0; _verbs[i].key = 0;
} }
if(!(_features & GF_AFTER_V7)) { if (!(_features & GF_AFTER_V7)) {
camera._leftTrigger = 10; camera._leftTrigger = 10;
camera._rightTrigger = 30; camera._rightTrigger = 30;
camera._mode = 0; camera._mode = 0;
@ -99,7 +103,7 @@ void Scumm::scummInit() {
virtscr[0].xstart = 0; virtscr[0].xstart = 0;
if(!(_features & GF_AFTER_V7)) { if (!(_features & GF_AFTER_V7)) {
_vars[VAR_V5_DRAWFLAGS] = 11; _vars[VAR_V5_DRAWFLAGS] = 11;
_vars[VAR_59] = 3; _vars[VAR_59] = 3;
} }
@ -136,9 +140,8 @@ 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 {
@ -157,15 +160,16 @@ void Scumm::scummInit() {
initScummVars(); initScummVars();
if (!(_features&GF_AFTER_V6)) if (!(_features & GF_AFTER_V6))
_vars[VAR_V5_TALK_STRING_Y] = -0x50; _vars[VAR_V5_TALK_STRING_Y] = -0x50;
getGraphicsPerformance(); getGraphicsPerformance();
} }
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();
_vars[VAR_SOUNDCARD] = _soundCardType; _vars[VAR_SOUNDCARD] = _soundCardType;
@ -175,19 +179,22 @@ void Scumm::initScummVars() {
_vars[VAR_SOUNDPARAM] = _soundParam; _vars[VAR_SOUNDPARAM] = _soundParam;
_vars[VAR_SOUNDPARAM2] = _soundParam2; _vars[VAR_SOUNDPARAM2] = _soundParam2;
_vars[VAR_SOUNDPARAM3] = _soundParam3; _vars[VAR_SOUNDPARAM3] = _soundParam3;
if (_features&GF_AFTER_V6) if (_features & GF_AFTER_V6)
_vars[VAR_V6_EMSSPACE] = 10000; _vars[VAR_V6_EMSSPACE] = 10000;
} }
} }
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,11 +217,12 @@ 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();
if(_features & GF_AFTER_V7) { if (_features & GF_AFTER_V7) {
_vars[VAR_CAMERA_POS_X] = camera._cur.x; _vars[VAR_CAMERA_POS_X] = camera._cur.x;
_vars[VAR_CAMERA_POS_Y] = camera._cur.y; _vars[VAR_CAMERA_POS_Y] = camera._cur.y;
} else { } else {
@ -230,19 +238,17 @@ int Scumm::scummLoop(int delta) {
if (_features & GF_AUDIOTRACKS) { if (_features & GF_AUDIOTRACKS) {
if (delta) { if (delta) {
if (++counter != 2) if (++counter != 2)
_vars[VAR_MI1_TIMER]+=5; _vars[VAR_MI1_TIMER] += 5;
else { else {
counter = 0; counter = 0;
_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) {
if (_saveLoadFlag==1) { if (_saveLoadFlag == 1) {
saveState(_saveLoadSlot, _saveLoadCompatible); saveState(_saveLoadSlot, _saveLoadCompatible);
if (_saveLoadCompatible) if (_saveLoadCompatible)
_vars[VAR_GAME_LOADED] = 201; _vars[VAR_GAME_LOADED] = 201;
@ -263,7 +269,7 @@ int Scumm::scummLoop(int delta) {
charset._hasMask = false; charset._hasMask = false;
redrawVerbs(); redrawVerbs();
_fullRedraw = true; _fullRedraw = true;
for (i=0,a=getFirstActor(); i<NUM_ACTORS; i++,a++) for (i = 0, a = getFirstActor(); i < NUM_ACTORS; i++, a++)
a->needRedraw = 1; a->needRedraw = 1;
} }
@ -271,7 +277,7 @@ int Scumm::scummLoop(int delta) {
checkExecVerbs(); checkExecVerbs();
checkAndRunVar33(); checkAndRunVar33();
if (_currentRoom==0) { if (_currentRoom == 0) {
gdi._cursorActive = 0; gdi._cursorActive = 0;
CHARSET_1(); CHARSET_1();
drawDirtyScreenParts(); drawDirtyScreenParts();
@ -282,12 +288,13 @@ int Scumm::scummLoop(int delta) {
moveCamera(); moveCamera();
fixObjectFlags(); fixObjectFlags();
CHARSET_1(); CHARSET_1();
if(!(_features & GF_AFTER_V7)) { if (!(_features & GF_AFTER_V7)) {
if (camera._cur.x != camera._last.x || _BgNeedsRedraw || _fullRedraw) { if (camera._cur.x != camera._last.x || _BgNeedsRedraw || _fullRedraw) {
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();
} }
} }
@ -320,7 +327,7 @@ int Scumm::scummLoop(int delta) {
drawDirtyScreenParts(); drawDirtyScreenParts();
removeEnqueuedObjects(); removeEnqueuedObjects();
if (!(_features&GF_AFTER_V6)) if (!(_features & GF_AFTER_V6))
playActorSounds(); playActorSounds();
processSoundQues(); processSoundQues();
@ -336,28 +343,29 @@ 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();
unkVirtScreen4(_switchRoomEffect2); unkVirtScreen4(_switchRoomEffect2);
_newEffect = _switchRoomEffect; _newEffect = _switchRoomEffect;
if (_currentScript!=0xFF) { if (_currentScript != 0xFF) {
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;
} }
} }
@ -368,13 +376,13 @@ void Scumm::startScene(int room, Actor *a, int objectNr) {
clearEnqueue(); clearEnqueue();
stopCycle(0); stopCycle(0);
for(i=1,at=getFirstActor(); ++at,i<NUM_ACTORS; i++) { for (i = 1, at = getFirstActor(); ++at, i < NUM_ACTORS; i++) {
if (at->visible) if (at->visible)
hideActor(at); hideActor(at);
} }
if (!(_features & GF_AFTER_V7)) { if (!(_features & GF_AFTER_V7)) {
for (i=0; i<0x100; i++) for (i = 0; i < 0x100; i++)
_shadowPalette[i] = i; _shadowPalette[i] = i;
} }
@ -389,13 +397,13 @@ void Scumm::startScene(int room, Actor *a, int objectNr) {
_vars[VAR_ROOM] = room; _vars[VAR_ROOM] = room;
// printf("startscene with room 0x%x\n", room); // printf("startscene with room 0x%x\n", room);
if (room >= 0x80) if (room >= 0x80)
_roomResource = _resourceMapper[room&0x7F]; _roomResource = _resourceMapper[room & 0x7F];
else else
_roomResource = room; _roomResource = room;
_vars[VAR_ROOM_RESOURCE] = _roomResource; _vars[VAR_ROOM_RESOURCE] = _roomResource;
if (room!=0) if (room != 0)
ensureResourceLoaded(1, room); ensureResourceLoaded(1, room);
if (_currentRoom == 0) { if (_currentRoom == 0) {
@ -405,22 +413,22 @@ void Scumm::startScene(int room, Actor *a, int objectNr) {
} }
initRoomSubBlocks(); initRoomSubBlocks();
if(_features & GF_SMALL_HEADER) if (_features & GF_SMALL_HEADER)
loadRoomObjectsSmall(); loadRoomObjectsSmall();
else else
loadRoomObjects(); loadRoomObjects();
if(!(_features & GF_AFTER_V7)) { if (!(_features & GF_AFTER_V7)) {
camera._mode = CM_NORMAL; camera._mode = CM_NORMAL;
camera._cur.x = camera._dest.x = 160; camera._cur.x = camera._dest.x = 160;
} }
if (_features&GF_AFTER_V6) { if (_features & GF_AFTER_V6) {
_vars[VAR_V6_SCREEN_WIDTH] = _scrWidth; _vars[VAR_V6_SCREEN_WIDTH] = _scrWidth;
_vars[VAR_V6_SCREEN_HEIGHT] = _scrHeight; _vars[VAR_V6_SCREEN_HEIGHT] = _scrHeight;
} }
if(_features & GF_AFTER_V7) { if (_features & GF_AFTER_V7) {
_vars[VAR_CAMERA_MIN_X] = 160; _vars[VAR_CAMERA_MIN_X] = 160;
_vars[VAR_CAMERA_MAX_X] = _scrWidth - 160; _vars[VAR_CAMERA_MAX_X] = _scrWidth - 160;
_vars[VAR_CAMERA_MIN_Y] = 100; _vars[VAR_CAMERA_MIN_Y] = 100;
@ -439,8 +447,9 @@ 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);
@ -452,7 +461,7 @@ void Scumm::startScene(int room, Actor *a, int objectNr) {
_egoPositioned = false; _egoPositioned = false;
runEntryScript(); runEntryScript();
if(!(_features & GF_AFTER_V7)) { if (!(_features & GF_AFTER_V7)) {
if (a && !_egoPositioned) { if (a && !_egoPositioned) {
getObjectXYPos(objectNr); getObjectXYPos(objectNr);
putActor(a, _xPos, _yPos, _currentRoom); putActor(a, _xPos, _yPos, _currentRoom);
@ -467,13 +476,13 @@ 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;
RoomHeader *rmhd; RoomHeader *rmhd;
_ENCD_offs = 0; _ENCD_offs = 0;
@ -484,14 +493,14 @@ void Scumm::initRoomSubBlocks() {
nukeResource(rtMatrix, 1); nukeResource(rtMatrix, 1);
nukeResource(rtMatrix, 2); nukeResource(rtMatrix, 2);
for (i=1; i<_maxScaleTable; i++) for (i = 1; i < _maxScaleTable; i++)
nukeResource(rtScaleTable, i); nukeResource(rtScaleTable, i);
roomptr = getResourceAddress(rtRoom, _roomResource); roomptr = getResourceAddress(rtRoom, _roomResource);
rmhd = (RoomHeader*)findResourceData(MKID('RMHD'), roomptr); rmhd = (RoomHeader *)findResourceData(MKID('RMHD'), roomptr);
if(_features & GF_AFTER_V7) { if (_features & GF_AFTER_V7) {
_scrWidth = READ_LE_UINT16(&(rmhd->v7.width)); _scrWidth = READ_LE_UINT16(&(rmhd->v7.width));
_scrHeight = READ_LE_UINT16(&(rmhd->v7.height)); _scrHeight = READ_LE_UINT16(&(rmhd->v7.height));
} else { } else {
@ -500,10 +509,12 @@ 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) {
@ -521,13 +532,13 @@ void Scumm::initRoomSubBlocks() {
#endif #endif
} }
if(_features & GF_SMALL_HEADER) { if (_features & GF_SMALL_HEADER) {
ptr = findResourceData(MKID('BOXD'), roomptr); ptr = findResourceData(MKID('BOXD'), roomptr);
if (ptr) { if (ptr) {
byte numOfBoxes=*(ptr); byte numOfBoxes = *(ptr);
int size; int size;
if (_features & GF_OLD256) if (_features & GF_OLD256)
size = numOfBoxes * (SIZEOF_BOX-2) + 1; size = numOfBoxes * (SIZEOF_BOX - 2) + 1;
else else
size = numOfBoxes * SIZEOF_BOX + 1; size = numOfBoxes * SIZEOF_BOX + 1;
@ -535,9 +546,9 @@ void Scumm::initRoomSubBlocks() {
createResource(rtMatrix, 2, size); createResource(rtMatrix, 2, size);
memcpy(getResourceAddress(rtMatrix, 2), ptr, size); memcpy(getResourceAddress(rtMatrix, 2), ptr, size);
ptr += size; ptr += size;
size = getResourceDataSize(ptr-size-6) - size; size = getResourceDataSize(ptr - size - 6) - size;
if(size>=0) { // do this :) if (size >= 0) { // do this :)
createResource(rtMatrix, 1, size); createResource(rtMatrix, 1, size);
memcpy(getResourceAddress(rtMatrix, 1), ptr, size); memcpy(getResourceAddress(rtMatrix, 1), ptr, size);
} }
@ -566,7 +577,7 @@ void Scumm::initRoomSubBlocks() {
ptr = findResourceData(MKID('SCAL'), roomptr); ptr = findResourceData(MKID('SCAL'), roomptr);
if (ptr) { if (ptr) {
offs = ptr - roomptr; offs = ptr - roomptr;
for (i=1; i<_maxScaleTable; i++, offs+=8) { for (i = 1; i < _maxScaleTable; i++, offs += 8) {
int a = READ_LE_UINT16(roomptr + offs); int a = READ_LE_UINT16(roomptr + offs);
int b = READ_LE_UINT16(roomptr + offs + 2); int b = READ_LE_UINT16(roomptr + offs + 2);
int c = READ_LE_UINT16(roomptr + offs + 4); int c = READ_LE_UINT16(roomptr + offs + 4);
@ -580,28 +591,28 @@ void Scumm::initRoomSubBlocks() {
memset(_localScriptList, 0, sizeof(_localScriptList)); memset(_localScriptList, 0, sizeof(_localScriptList));
searchptr = roomptr = getResourceAddress(rtRoom, _roomResource); searchptr = roomptr = getResourceAddress(rtRoom, _roomResource);
if(_features & GF_SMALL_HEADER) { if (_features & GF_SMALL_HEADER) {
while( (ptr = findResourceSmall(MKID('LSCR'), searchptr)) != NULL ) { while ((ptr = findResourceSmall(MKID('LSCR'), searchptr)) != NULL) {
int id = 0; int id = 0;
ptr += _resourceHeaderSize; /* skip tag & size */ ptr += _resourceHeaderSize; /* skip tag & size */
#ifdef DUMP_SCRIPTS #ifdef DUMP_SCRIPTS
do { do {
char buf[32]; char buf[32];
sprintf(buf,"room-%d-",_roomResource); sprintf(buf, "room-%d-", _roomResource);
dumpResource(buf, id, ptr - 6); dumpResource(buf, id, ptr - 6);
} while (0); } while (0);
#endif #endif
id = ptr[0]; id = ptr[0];
_localScriptList[id - _numGlobalScripts] = ptr + 1 - roomptr; _localScriptList[id - _numGlobalScripts] = ptr + 1 - roomptr;
searchptr = NULL; searchptr = NULL;
} }
} else { } else {
while( (ptr = findResource(MKID('LSCR'), searchptr)) != NULL ) { while ((ptr = findResource(MKID('LSCR'), searchptr)) != NULL) {
int id = 0; int id = 0;
ptr += _resourceHeaderSize; /* skip tag & size */ ptr += _resourceHeaderSize; /* skip tag & size */
if(_features & GF_AFTER_V7) { if (_features & GF_AFTER_V7) {
id = READ_LE_UINT16(ptr); id = READ_LE_UINT16(ptr);
checkRange(2050, 2000, id, "Invalid local script %d"); checkRange(2050, 2000, id, "Invalid local script %d");
_localScriptList[id - _numGlobalScripts] = ptr + 2 - roomptr; _localScriptList[id - _numGlobalScripts] = ptr + 2 - roomptr;
@ -612,7 +623,7 @@ void Scumm::initRoomSubBlocks() {
#ifdef DUMP_SCRIPTS #ifdef DUMP_SCRIPTS
do { do {
char buf[32]; char buf[32];
sprintf(buf,"room-%d-",_roomResource); sprintf(buf, "room-%d-", _roomResource);
dumpResource(buf, id, ptr - 8); dumpResource(buf, id, ptr - 8);
} while (0); } while (0);
#endif #endif
@ -620,7 +631,7 @@ void Scumm::initRoomSubBlocks() {
} }
} }
if( _features & GF_SMALL_HEADER) if (_features & GF_SMALL_HEADER)
ptr = findResourceSmall(MKID('EPAL'), roomptr); ptr = findResourceSmall(MKID('EPAL'), roomptr);
else else
ptr = findResource(MKID('EPAL'), roomptr); ptr = findResource(MKID('EPAL'), roomptr);
@ -628,7 +639,7 @@ void Scumm::initRoomSubBlocks() {
if (ptr) if (ptr)
_EPAL_offs = ptr - roomptr; _EPAL_offs = ptr - roomptr;
if( _features & GF_SMALL_HEADER) if (_features & GF_SMALL_HEADER)
ptr = findResourceSmall(MKID('CLUT'), roomptr); ptr = findResourceSmall(MKID('CLUT'), roomptr);
else else
ptr = findResourceData(MKID('CLUT'), roomptr); ptr = findResourceData(MKID('CLUT'), roomptr);
@ -638,7 +649,7 @@ void Scumm::initRoomSubBlocks() {
setPaletteFromRes(); setPaletteFromRes();
} }
if (_features&GF_AFTER_V6) { if (_features & GF_AFTER_V6) {
ptr = findResource(MKID('PALS'), roomptr); ptr = findResource(MKID('PALS'), roomptr);
if (ptr) { if (ptr) {
_PALS_offs = ptr - roomptr; _PALS_offs = ptr - roomptr;
@ -646,7 +657,7 @@ void Scumm::initRoomSubBlocks() {
} }
} }
if( _features & GF_SMALL_HEADER) if (_features & GF_SMALL_HEADER)
ptr = findResourceData(MKID('CYCL'), roomptr); ptr = findResourceData(MKID('CYCL'), roomptr);
else else
ptr = findResourceData(MKID('CYCL'), roomptr); ptr = findResourceData(MKID('CYCL'), roomptr);
@ -665,44 +676,48 @@ 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;
ptr = createResource(rtScaleTable, slot, 200); ptr = createResource(rtScaleTable, slot, 200);
if (a==c) if (a == c)
return; return;
cur = (b-d)*a; cur = (b - d) * a;
amounttoadd = d - b; amounttoadd = d - b;
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;
uint32 size; uint32 size;
if( _features & GF_SMALL_HEADER ) if (_features & GF_SMALL_HEADER)
size = READ_LE_UINT32(ptr); size = READ_LE_UINT32(ptr);
else else
size = READ_BE_UINT32_UNALIGNED(ptr+4); size = READ_BE_UINT32_UNALIGNED(ptr + 4);
#if defined(__APPLE__CW) #if defined(__APPLE__CW)
sprintf(buf, ":dumps:%s%d.dmp", tag,idx); sprintf(buf, ":dumps:%s%d.dmp", tag, idx);
#else #else
sprintf(buf, "dumps/%s%d.dmp", tag,idx); sprintf(buf, "dumps/%s%d.dmp", tag, idx);
#endif #endif
out = fopen(buf,"rb"); out = fopen(buf, "rb");
if (!out) { if (!out) {
out = fopen(buf, "wb"); out = fopen(buf, "wb");
if (!out) if (!out)
@ -713,59 +728,68 @@ 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;
_virtual_mouse_y = mouse.y; _virtual_mouse_y = mouse.y;
if(!(_features & GF_OLD256)) if (!(_features & GF_OLD256))
_virtual_mouse_y+=virtscr[0].topline; _virtual_mouse_y += virtscr[0].topline;
else else
_virtual_mouse_y-=16; _virtual_mouse_y -= 16;
if (_virtual_mouse_y < 0) if (_virtual_mouse_y < 0)
_virtual_mouse_y =-1; _virtual_mouse_y = -1;
if (_features & GF_OLD256) { if (_features & GF_OLD256) {
if (_virtual_mouse_y >= virtscr[0].height + virtscr[0].topline) if (_virtual_mouse_y >= virtscr[0].height + virtscr[0].topline)
_virtual_mouse_y = -1; _virtual_mouse_y = -1;
@ -777,37 +801,38 @@ void Scumm::processKbd() {
if (!_lastKeyHit) if (!_lastKeyHit)
return; return;
if (_lastKeyHit==KEY_SET_OPTIONS) { if (_lastKeyHit == KEY_SET_OPTIONS) {
setOptions(); setOptions();
return; return;
} }
if (_lastKeyHit==_vars[VAR_RESTART_KEY]) { if (_lastKeyHit == _vars[VAR_RESTART_KEY]) {
warning("Restart not implemented"); warning("Restart not implemented");
// pauseGame(true); // pauseGame(true);
return; return;
} }
if (_lastKeyHit==_vars[VAR_PAUSE_KEY]) { if (_lastKeyHit == _vars[VAR_PAUSE_KEY]) {
pauseGame(true); pauseGame(true);
/* pause */ /* pause */
return; return;
} }
if (_lastKeyHit==_vars[VAR_CUTSCENEEXIT_KEY]) { if (_lastKeyHit == _vars[VAR_CUTSCENEEXIT_KEY]) {
if (_insaneState) { if (_insaneState) {
videoFinished=1; videoFinished = 1;
} else } else
exitCutscene(); exitCutscene();
} else if (_lastKeyHit==_vars[VAR_SAVELOADDIALOG_KEY] && _currentRoom != 0) { } else if (_lastKeyHit == _vars[VAR_SAVELOADDIALOG_KEY]
if ( _features & GF_AFTER_V7) && _currentRoom != 0) {
runScript(_vars[VAR_UNK_SCRIPT],0,0,0); if (_features & GF_AFTER_V7)
((Gui*)_gui)->saveLoadDialog(this); runScript(_vars[VAR_UNK_SCRIPT], 0, 0, 0);
if ( _features & GF_AFTER_V7) ((Gui *)_gui)->saveLoadDialog(this);
runScript(_vars[VAR_UNK_SCRIPT_2],0,0,0); if (_features & GF_AFTER_V7)
} else if (_lastKeyHit==_vars[VAR_TALKSTOP_KEY]) { runScript(_vars[VAR_UNK_SCRIPT_2], 0, 0, 0);
} else if (_lastKeyHit == _vars[VAR_TALKSTOP_KEY]) {
_talkDelay = 0; _talkDelay = 0;
if (_sfxMode==2) if (_sfxMode == 2)
stopTalk(); stopTalk();
return; return;
} }
@ -815,32 +840,37 @@ 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;
_lastKeyHit = _vars[VAR_CUTSCENEEXIT_KEY]; _lastKeyHit = _vars[VAR_CUTSCENEEXIT_KEY];
} else if (_leftBtnPressed&msClicked) { } else if (_leftBtnPressed & msClicked) {
_mouseButStat = MBS_LEFT_CLICK; _mouseButStat = MBS_LEFT_CLICK;
} else if (_rightBtnPressed&msClicked) { } else if (_rightBtnPressed & msClicked) {
_mouseButStat = MBS_RIGHT_CLICK; _mouseButStat = MBS_RIGHT_CLICK;
} }
if(_features & GF_AFTER_V7) { if (_features & GF_AFTER_V7) {
// _vars[VAR_LEFTBTN_DOWN] = (_leftBtnPressed&msClicked) != 0; // _vars[VAR_LEFTBTN_DOWN] = (_leftBtnPressed&msClicked) != 0;
_vars[VAR_LEFTBTN_HOLD] = (_leftBtnPressed&msDown) != 0; _vars[VAR_LEFTBTN_HOLD] = (_leftBtnPressed & msDown) != 0;
// _vars[VAR_RIGHTBTN_DOWN] = (_rightBtnPressed&msClicked) != 0; // _vars[VAR_RIGHTBTN_DOWN] = (_rightBtnPressed&msClicked) != 0;
_vars[VAR_RIGHTBTN_HOLD] = (_rightBtnPressed&msDown) != 0; _vars[VAR_RIGHTBTN_HOLD] = (_rightBtnPressed & msDown) != 0;
} }
_leftBtnPressed &= ~msClicked; _leftBtnPressed &= ~msClicked;
@ -849,11 +879,12 @@ int Scumm::getKeyInput(int a) {
return _lastKeyHit; return _lastKeyHit;
} }
void Scumm::convertKeysToClicks() { void Scumm::convertKeysToClicks()
if (_lastKeyHit && _cursorState>0) { {
if (_lastKeyHit==9) { if (_lastKeyHit && _cursorState > 0) {
if (_lastKeyHit == 9) {
_mouseButStat = MBS_RIGHT_CLICK; _mouseButStat = MBS_RIGHT_CLICK;
} else if (_lastKeyHit==13) { } else if (_lastKeyHit == 13) {
_mouseButStat = MBS_LEFT_CLICK; _mouseButStat = MBS_LEFT_CLICK;
} else } else
return; return;
@ -861,25 +892,30 @@ 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) { {
warning("Invalid actor %d in %s (script %d, opcode 0x%x) - This is potentially a BIG problem.", id, errmsg, vm.slot[_curExecScript].number, _opcode); 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);
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;
for(i=0; i<size; i++) for (i = 0; i < size; i++)
if (_grabbedCursor[i] == (byte)a) if (_grabbedCursor[i] == (byte)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,12 +954,13 @@ 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)
return 2; return 2;
if (dir>=251 && dir<=289) if (dir >= 251 && dir <= 289)
return 0; return 0;
return 3; return 3;
} }
@ -932,20 +972,23 @@ 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++) {
if (dir >= dirtab[0] && dir <= dirtab[1]) if (dir >= dirtab[0] && dir <= dirtab[1])
return i; return i;
} }
@ -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,32 +1034,35 @@ 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;
va_start(va,s); va_start(va, s);
vsprintf(buf, s, va); vsprintf(buf, s, va);
va_end(va); va_end(va);
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;
if (level>5) if (level > 5)
return; return;
va_start(va,s); va_start(va, s);
vsprintf(buf, s, va); vsprintf(buf, s, va);
va_end(va); va_end(va);
printf("%s\n", buf); printf("%s\n", buf);
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,15 +1070,15 @@ 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);
} }
void Scumm::launch() void Scumm::launch()
@ -1044,7 +1093,7 @@ void Scumm::launch()
/* Init graphics and create a primary virtual screen */ /* Init graphics and create a primary virtual screen */
initGraphics(this, _fullScreen, _scale); initGraphics(this, _fullScreen, _scale);
allocResTypeData(rtBuffer, MKID('NONE'),10,"buffer",0); allocResTypeData(rtBuffer, MKID('NONE'), 10, "buffer", 0);
initVirtScreen(0, 0, 200, false, false); initVirtScreen(0, 0, 200, false, false);
if (_features & GF_AFTER_V7) if (_features & GF_AFTER_V7)
@ -1057,7 +1106,7 @@ void Scumm::launch()
else else
NUM_ACTORS = 13; NUM_ACTORS = 13;
if(_features & GF_AFTER_V7) if (_features & GF_AFTER_V7)
OF_OWNER_ROOM = 0xFF; OF_OWNER_ROOM = 0xFF;
else else
OF_OWNER_ROOM = 0x0F; OF_OWNER_ROOM = 0x0F;
@ -1065,7 +1114,7 @@ void Scumm::launch()
// if (_gameId==GID_MONKEY2 && _bootParam == 0) // if (_gameId==GID_MONKEY2 && _bootParam == 0)
// _bootParam = 10001; // _bootParam = 10001;
if (_gameId==GID_INDY4 && _bootParam==0) { if (_gameId == GID_INDY4 && _bootParam == 0) {
_bootParam = -7873; _bootParam = -7873;
} }
@ -1080,7 +1129,7 @@ void Scumm::launch()
scummInit(); scummInit();
if(!(_features & GF_AFTER_V7)) if (!(_features & GF_AFTER_V7))
_vars[VAR_VERSION] = 21; _vars[VAR_VERSION] = 21;
_vars[VAR_DEBUGMODE] = _debugMode; _vars[VAR_DEBUGMODE] = _debugMode;
@ -1090,7 +1139,7 @@ void Scumm::launch()
setupSound(); setupSound();
runScript(1,0,0,&_bootParam); runScript(1, 0, 0, &_bootParam);
// _scummTimer = 0; // _scummTimer = 0;

1200
sdl.cpp

File diff suppressed because it is too large Load diff

346
sound.cpp
View file

@ -26,71 +26,70 @@
#ifdef _WIN32_WCE #ifdef _WIN32_WCE
extern void *bsearch(const void *, const void *, size_t, 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);
addSoundToQueue2(sound); addSoundToQueue2(sound);
} }
if(_features & GF_AUDIOTRACKS) if (_features & GF_AUDIOTRACKS)
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;
int16 data[16]; int16 data[16];
SoundEngine *se; SoundEngine *se;
processSfxQueues(); processSfxQueues();
while (_soundQue2Pos){ while (_soundQue2Pos) {
d=_soundQue2[--_soundQue2Pos]; d = _soundQue2[--_soundQue2Pos];
if (d) if (d)
playSound(d); playSound(d);
} }
for (i=0; i<_soundQuePos; ) { for (i = 0; i < _soundQuePos;) {
num = _soundQue[i++]; num = _soundQue[i++];
if (i + num > _soundQuePos) { if (i + num > _soundQuePos) {
warning("processSoundQues: invalid num value"); warning("processSoundQues: invalid num value");
break; break;
} }
for (j=0; j<16; j++) for (j = 0; j < 16; j++)
data[j] = 0; data[j] = 0;
if (num>0) { if (num > 0) {
for (j=0; j<num; j++) for (j = 0; j < num; j++)
data[j] = _soundQue[i+j]; data[j] = _soundQue[i + j];
i += num; i += num;
se = (SoundEngine*)_soundEngine; se = (SoundEngine *)_soundEngine;
#if 0 #if 0
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,9 +97,10 @@ 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;
ptr = getResourceAddress(rtSound, sound); ptr = getResourceAddress(rtSound, sound);
if (ptr != NULL && READ_UINT32_UNALIGNED(ptr) == MKID('SOUN')) { if (ptr != NULL && READ_UINT32_UNALIGNED(ptr) == MKID('SOUN')) {
@ -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,23 +120,24 @@ 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;
if (_talk_sound_mode != 0) { if (_talk_sound_mode != 0) {
startTalkSound(_talk_sound_a, _talk_sound_b, _talk_sound_mode); startTalkSound(_talk_sound_a, _talk_sound_b, _talk_sound_mode);
_talk_sound_mode = 0; _talk_sound_mode = 0;
} }
if (_sfxMode==2) { if (_sfxMode == 2) {
act = _vars[VAR_TALK_ACTOR]; act = _vars[VAR_TALK_ACTOR];
finished = isSfxFinished(); finished = isSfxFinished();
if (act!=0 && (uint)act<0x80 && !string[0].no_talk_anim) { if (act != 0 && (uint) act < 0x80 && !string[0].no_talk_anim) {
a = derefActorSafe(act, "processSfxQueues"); a = derefActorSafe(act, "processSfxQueues");
if (a->room==_currentRoom && (finished || !_endOfMouthSync)) { if (a->room == _currentRoom && (finished || !_endOfMouthSync)) {
b = true; b = true;
if (!finished) if (!finished)
b = isMouthSyncOff(_curSoundPos); b = isMouthSyncOff(_curSoundPos);
@ -145,11 +147,11 @@ void Scumm::processSfxQueues() {
} }
} }
} }
if (finished && _talkDelay==0) { if (finished && _talkDelay == 0) {
stopTalk(); stopTalk();
_sfxMode = 0; _sfxMode = 0;
} }
} else if (_sfxMode==1) { } else if (_sfxMode == 1) {
if (isSfxFinished()) { if (isSfxFinished()) {
_sfxMode = 0; _sfxMode = 0;
} }
@ -157,14 +159,17 @@ 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;
if (!_sfxFile) { if (!_sfxFile) {
@ -172,16 +177,17 @@ void Scumm::startTalkSound(uint32 offset, uint32 b, int mode) {
return; return;
} }
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;
@ -201,12 +208,12 @@ void Scumm::startTalkSound(uint32 offset, uint32 b, int mode) {
size = -1; size = -1;
} }
fileSeek((FILE*)_sfxFile, offset, SEEK_SET); fileSeek((FILE *) _sfxFile, offset, SEEK_SET);
i = 0; i = 0;
while (num > 0) { while (num > 0) {
fileRead((FILE*)_sfxFile, &file_byte, sizeof(file_byte)); fileRead((FILE *) _sfxFile, &file_byte, sizeof(file_byte));
fileRead((FILE*)_sfxFile, &file_byte_2, sizeof(file_byte_2)); fileRead((FILE *) _sfxFile, &file_byte_2, sizeof(file_byte_2));
_mouthSyncTimes[i++] = file_byte | (file_byte_2<<8); _mouthSyncTimes[i++] = file_byte | (file_byte_2 << 8);
num--; num--;
} }
_mouthSyncTimes[i] = 0xFFFF; _mouthSyncTimes[i] = 0xFFFF;
@ -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;
@ -233,7 +242,7 @@ bool Scumm::isMouthSyncOff(uint pos) {
do { do {
val ^= 1; val ^= 1;
j = *ms++; j = *ms++;
if (j==0xFFFF) { if (j == 0xFFFF) {
_endOfMouthSync = true; _endOfMouthSync = true;
break; break;
} }
@ -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;
@ -261,14 +271,15 @@ int Scumm::isSoundRunning(int sound) {
if (!isResourceLoaded(rtSound, sound)) if (!isResourceLoaded(rtSound, sound))
return 0; return 0;
se = (SoundEngine*)_soundEngine; se = (SoundEngine *)_soundEngine;
if (!se) if (!se)
return 0; return 0;
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];
while (i < _soundQuePos) { while (i < _soundQuePos) {
@ -277,17 +288,18 @@ bool Scumm::isSoundInQueue(int sound) {
memset(table, 0, sizeof(table)); memset(table, 0, sizeof(table));
if (num > 0) { if (num > 0) {
for (j=0; j<num; j++) for (j = 0; j < num; j++)
table[j] = _soundQue[i+j]; table[j] = _soundQue[i + j];
i += num; i += num;
if (table[0] == 0x10F && table[1]==8 && table[2] == sound) if (table[0] == 0x10F && table[1] == 8 && table[2] == sound)
return 1; return 1;
} }
} }
return 0; return 0;
} }
void Scumm::stopSound(int a) { void Scumm::stopSound(int a)
{
SoundEngine *se; SoundEngine *se;
int i; int i;
@ -296,17 +308,18 @@ void Scumm::stopSound(int a) {
cd_stop(); cd_stop();
} }
se = (SoundEngine*)_soundEngine; se = (SoundEngine *)_soundEngine;
if (se) if (se)
se->stop_sound(a); se->stop_sound(a);
for (i=0; i<10; i++) for (i = 0; i < 10; i++)
if (_soundQue2[i] == (byte)a) if (_soundQue2[i] == (byte)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) {
current_cd_sound = 0; current_cd_sound = 0;
@ -321,16 +334,18 @@ 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;
if (list[0]==-1) { if (list[0] == -1) {
processSoundQues(); processSoundQues();
return; return;
} }
@ -339,13 +354,14 @@ void Scumm::soundKludge(int16 *list) {
ptr = _soundQue + _soundQuePos; ptr = _soundQue + _soundQuePos;
_soundQuePos += 8; _soundQuePos += 8;
for (i=0; i<8; i++) for (i = 0; i < 8; i++)
*ptr++ = list[i]; *ptr++ = list[i];
if (_soundQuePos > 0x100) if (_soundQuePos > 0x100)
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,8 +392,9 @@ 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);
_soundsPaused = pause; _soundsPaused = pause;
@ -383,23 +402,24 @@ void Scumm::pauseSounds(bool pause) {
enum { enum {
SOUND_HEADER_SIZE = 26, SOUND_HEADER_SIZE = 26,
SOUND_HEADER_BIG_SIZE = 26+8, SOUND_HEADER_BIG_SIZE = 26 + 8,
}; };
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];
uint size = 0,i; uint size = 0, i;
int rate,comp; int rate, comp;
byte *data; byte *data;
#ifdef COMPRESSED_SOUND_FILE #ifdef COMPRESSED_SOUND_FILE
if (file_size > 0) { if (file_size > 0) {
data = (byte *) calloc(file_size + MAD_BUFFER_GUARD, 1); data = (byte *)calloc(file_size + MAD_BUFFER_GUARD, 1);
if (fread(data, file_size, 1, (FILE*) file) != 1) { if (fread(data, file_size, 1, (FILE *) file) != 1) {
/* no need to free the memory since error will shut down */ /* no need to free the memory since error will shut down */
error("startSfxSound: cannot read %d bytes", size); error("startSfxSound: cannot read %d bytes", size);
return; return;
@ -408,60 +428,61 @@ void Scumm::startSfxSound(void *file, int file_size) {
return; return;
} }
#endif #endif
if ( fread(ident, 8, 1, (FILE*)file) != 1) if (fread(ident, 8, 1, (FILE *) file) != 1)
goto invalid; goto invalid;
if (!memcmp(ident, "VTLK", 4)) { if (!memcmp(ident, "VTLK", 4)) {
fseek((FILE*)file, SOUND_HEADER_BIG_SIZE - 8, SEEK_CUR); fseek((FILE *) file, SOUND_HEADER_BIG_SIZE - 8, SEEK_CUR);
} else if (!memcmp(ident, "Creative", 8)) { } else if (!memcmp(ident, "Creative", 8)) {
fseek((FILE*)file, SOUND_HEADER_SIZE - 8, SEEK_CUR); fseek((FILE *) file, SOUND_HEADER_SIZE - 8, SEEK_CUR);
} else { } else {
invalid:; invalid:;
warning("startSfxSound: invalid header"); warning("startSfxSound: invalid header");
return; return;
} }
block_type = getc( (FILE*)file ); block_type = getc((FILE *) file);
if (block_type != 1) { if (block_type != 1) {
warning("startSfxSound: Expecting block_type == 1, got %d", block_type); warning("startSfxSound: Expecting block_type == 1, got %d", block_type);
return; return;
} }
fread(work, 3, 1, (FILE*)file); fread(work, 3, 1, (FILE *) file);
size = ( work[0] | ( work[1] << 8 ) | ( work[2] << 16 ) ) - 2; size = (work[0] | (work[1] << 8) | (work[2] << 16)) - 2;
rate = getc( (FILE*)file ); rate = getc((FILE *) file);
comp = getc( (FILE*)file ); comp = getc((FILE *) file);
if (comp != 0) { if (comp != 0) {
warning("startSfxSound: Unsupported compression type %d", comp); warning("startSfxSound: Unsupported compression type %d", comp);
return; return;
} }
data = (byte*) malloc(size); data = (byte *)malloc(size);
if (data==NULL) { if (data == NULL) {
error("startSfxSound: out of memory"); error("startSfxSound: out of memory");
return; return;
} }
if (fread(data, size, 1, (FILE*)file) != 1) { if (fread(data, size, 1, (FILE *) file) != 1) {
/* no need to free the memory since error will shut down */ /* no need to free the memory since error will shut down */
error("startSfxSound: cannot read %d bytes", size); error("startSfxSound: cannot read %d bytes", size);
return; return;
} }
for(i=0;i<size; i++) { for (i = 0; i < size; i++) {
// Fixme: From WinCE port // Fixme: From WinCE port
if (_sound_volume_sfx != 100) if (_sound_volume_sfx != 100)
data[i] = _sound_volume_sfx * data[i] / 100; data[i] = _sound_volume_sfx * data[i] / 100;
data[i] ^= 0x80; data[i] ^= 0x80;
} }
playSfxSound(data, size, 1000000 / (256 - rate) ); playSfxSound(data, size, 1000000 / (256 - rate));
} }
#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,36 +564,40 @@ 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++) {
if (!mc->_sfx_sound) if (!mc->_sfx_sound)
return mc; return mc;
} }
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++) {
if (mc->_sfx_sound) if (mc->_sfx_sound)
mc->clear(); mc->clear();
} }
} }
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)
return false; return false;
return true; return true;
} }
#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) {
@ -634,11 +663,12 @@ void Scumm::playSfxSound(void *sound, uint32 size, uint rate) {
mc->sound_data.standard._sfx_fp_pos = 0; mc->sound_data.standard._sfx_fp_pos = 0;
#ifdef _WIN32_WCE #ifdef _WIN32_WCE
mc->sound_data.standard._sfx_fp_speed = (1<<16) * rate / 11025; mc->sound_data.standard._sfx_fp_speed = (1 << 16) * rate / 11025;
#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;
@ -679,18 +710,18 @@ void MixerChannel::mix(int16 *data, uint32 len) {
len = sound_data.standard._sfx_size; len = sound_data.standard._sfx_size;
sound_data.standard._sfx_size -= len; sound_data.standard._sfx_size -= len;
s = (int8*)_sfx_sound + sound_data.standard._sfx_pos; s = (int8 *) _sfx_sound + sound_data.standard._sfx_pos;
fp_pos = sound_data.standard._sfx_fp_pos; fp_pos = sound_data.standard._sfx_fp_pos;
fp_speed = sound_data.standard._sfx_fp_speed; fp_speed = sound_data.standard._sfx_fp_speed;
do { do {
fp_pos += fp_speed; fp_pos += fp_speed;
*data++ += (*s<<6); *data++ += (*s << 6);
s += fp_pos >> 16; s += fp_pos >> 16;
fp_pos &= 0x0000FFFF; fp_pos &= 0x0000FFFF;
} while (--len); } while (--len);
sound_data.standard._sfx_pos = s - (int8*)_sfx_sound; sound_data.standard._sfx_pos = s - (int8 *) _sfx_sound;
sound_data.standard._sfx_fp_speed = fp_speed; sound_data.standard._sfx_fp_speed = fp_speed;
sound_data.standard._sfx_fp_pos = fp_pos; sound_data.standard._sfx_fp_pos = fp_pos;
@ -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);
@ -763,9 +801,8 @@ void MixerChannel::mix(int16 *data, uint32 len) {
last_pos = ftell(sound_data.mp3_cdmusic.file); last_pos = ftell(sound_data.mp3_cdmusic.file);
// 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,21 +869,21 @@ 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,
not_decoded); not_decoded);
sound_data.mp3_cdmusic.size = sound_data.mp3_cdmusic.size =
fread((unsigned char*)_sfx_sound + not_decoded, 1, fread((unsigned char *)_sfx_sound + not_decoded, 1,
sound_data.mp3_cdmusic.buffer_size - not_decoded, sound_data.mp3_cdmusic.buffer_size - not_decoded,
sound_data.mp3_cdmusic.file); sound_data.mp3_cdmusic.file);
} }
@ -857,18 +891,21 @@ void MixerChannel::mix(int16 *data, uint32 len) {
sound_data.mp3_cdmusic.stream.error = MAD_ERROR_NONE; sound_data.mp3_cdmusic.stream.error = MAD_ERROR_NONE;
// 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,24 +930,24 @@ 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));
if (_soundsPaused) if (_soundsPaused)
return; return;
SoundEngine *se = (SoundEngine*)_soundEngine; SoundEngine *se = (SoundEngine *)_soundEngine;
if (se) { if (se) {
se->driver()->generate_samples(sounds, len); se->driver()->generate_samples(sounds, len);
} }
for(i=NUM_MIXER-1; i>=0;i--) { for (i = NUM_MIXER - 1; i >= 0; i--) {
_mixer_channel[i].mix(sounds, len); _mixer_channel[i].mix(sounds, len);
} }
if (_soundsPaused2) if (_soundsPaused2)
memset(sounds, 0x0, len * sizeof(int16)); memset(sounds, 0x0, len * sizeof(int16));
} }

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

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 {
if (midiOutOpen((HMIDIOUT*)&_mo, MIDI_MAPPER, NULL, NULL, 0) != MMSYSERR_NOERROR) #ifdef WIN32
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;
@ -158,17 +170,18 @@ int MidiDriver::connect_to_timidity(int port) {
sadd.sin_port = htons(port); sadd.sin_port = htons(port);
memcpy(&(sadd.sin_addr), serverhost->h_addr_list[0], serverhost->h_length); memcpy(&(sadd.sin_addr), serverhost->h_addr_list[0], serverhost->h_length);
s = socket(AF_INET,SOCK_STREAM,0); s = socket(AF_INET, SOCK_STREAM, 0);
if (s < 0) if (s < 0)
error("Could not open Timidity socket"); error("Could not open Timidity socket");
if (connect(s, (struct sockaddr *) &sadd, sizeof(struct sockaddr_in)) < 0) if (connect(s, (struct sockaddr *)&sadd, sizeof(struct sockaddr_in)) < 0)
error("Could not connect to Timidity server"); error("Could not connect to Timidity server");
#endif #endif
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;
@ -188,11 +201,12 @@ void MidiDriver::midiInitTimidity() {
printf(" => port = %d\n", newport); printf(" => port = %d\n", newport);
s2 = connect_to_timidity(newport); s2 = connect_to_timidity(newport);
_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,12 +248,13 @@ 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;
for (int i = 0 ; i < 15 ; i++) for (int i = 0; i < 15; i++)
qtNoteChannel[i] = NULL; qtNoteChannel[i] = NULL;
qtNoteAllocator = OpenDefaultComponent(kNoteAllocatorComponentType, 0); qtNoteAllocator = OpenDefaultComponent(kNoteAllocatorComponentType, 0);
@ -248,22 +263,26 @@ 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,
for (int i = 0 ; i < 15 ; i++) { qtErr);
for (int i = 0; i < 15; i++) {
if (qtNoteChannel[i] != NULL) if (qtNoteChannel[i] != NULL)
NADisposeNoteChannel(qtNoteAllocator, qtNoteChannel[i]); NADisposeNoteChannel(qtNoteAllocator, qtNoteChannel[i]);
} }
@ -273,14 +292,15 @@ 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;
midPacket.length = 3; midPacket.length = 3;
midiCmd[3] = (b & 0xFF000000)>>24; midiCmd[3] = (b & 0xFF000000) >> 24;
midiCmd[2] = (b & 0x00FF0000)>>16; midiCmd[2] = (b & 0x00FF0000) >> 16;
midiCmd[1] = (b & 0x0000FF00)>>8; midiCmd[1] = (b & 0x0000FF00) >> 8;
midiCmd[0] = b; midiCmd[0] = b;
unsigned char chanID = midiCmd[0] & 0x0F; unsigned char chanID = midiCmd[0] & 0x0F;
@ -290,37 +310,44 @@ 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
for (int i = 0 ; i < 128 ; i++) for (int i = 0; i < 128; i++)
NAPlayNote(qtNoteAllocator, qtNoteChannel[chanID], i, 0); NAPlayNote(qtNoteAllocator, qtNoteChannel[chanID], i, 0);
break; break;
@ -334,9 +361,11 @@ void MidiDriver::MidiOutQuicktime(void *a, int b) {
NASetInstrumentNumber(qtNoteAllocator, qtNoteChannel[chanID], midiCmd[1]); NASetInstrumentNumber(qtNoteAllocator, qtNoteChannel[chanID], midiCmd[1]);
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,14 +378,15 @@ 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 ;-)
ScummMidiRequest->amr_Std.io_Command = CMD_WRITE; ScummMidiRequest->amr_Std.io_Command = CMD_WRITE;
ScummMidiRequest->amr_Std.io_Data = &midi_data; ScummMidiRequest->amr_Std.io_Data = &midi_data;
ScummMidiRequest->amr_Std.io_Length = 4; ScummMidiRequest->amr_Std.io_Length = 4;
DoIO( (struct IORequest *)ScummMidiRequest ); DoIO((struct IORequest *)ScummMidiRequest);
} }
#endif #endif
} }
@ -367,94 +397,112 @@ 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];
_midi_driver.MidiOut(program<<8 | 0xC0 | chan); _midi_driver.MidiOut(program << 8 | 0xC0 | chan);
} }
} }
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((123<<8)|0xB0|chan); _midi_driver.MidiOut((64 << 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) {
mc->_actives[note>>4] |= (1<<(note&0xF)); mc->_actives[note >> 4] |= (1 << (note & 0xF));
midiNoteOn(mc->_chan, note, velocity); midiNoteOn(mc->_chan, note, velocity);
} else if (part->_percussion) { } else if (part->_percussion) {
midiVolume(SPECIAL_CHANNEL, part->_vol_eff); midiVolume(SPECIAL_CHANNEL, part->_vol_eff);
@ -463,38 +511,42 @@ 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) {
mc->_actives[note>>4] &= ~(1<<(note&0xF)); mc->_actives[note >> 4] &= ~(1 << (note & 0xF));
midiNoteOff(mc->_chan, note); midiNoteOff(mc->_chan, note);
} else if (part->_percussion) { } else if (part->_percussion) {
midiNoteOff(SPECIAL_CHANNEL, note); midiNoteOff(SPECIAL_CHANNEL, note);
} }
} }
void MidiSoundDriver::init(SoundEngine *eng) { void MidiSoundDriver::init(SoundEngine *eng)
{
int i; int i;
MidiChannelGM *mc; MidiChannelGM *mc;
_se = eng; _se = eng;
for(i=0,mc=_midi_channels; i!=ARRAYSIZE(_midi_channels);i++,mc++) for (i = 0, mc = _midi_channels; i != ARRAYSIZE(_midi_channels); i++, mc++)
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;
MidiChannelGM *mc,*lomc; MidiChannelGM *mc, *lomc;
while(true) { while (true) {
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;
} }
@ -505,12 +557,12 @@ void MidiSoundDriver::update_pris() {
lopri = 255; lopri = 255;
lomc = NULL; lomc = NULL;
for(i=ARRAYSIZE(_midi_channels),mc=_midi_channels;;mc++) { for (i = ARRAYSIZE(_midi_channels), mc = _midi_channels;; mc++) {
if (!mc->_part) { if (!mc->_part) {
lomc = mc; lomc = mc;
break; break;
} }
if (mc->_part->_pri_eff<=lopri) { if (mc->_part->_pri_eff <= lopri) {
lopri = mc->_part->_pri_eff; lopri = mc->_part->_pri_eff;
lomc = mc; lomc = mc;
} }
@ -529,21 +581,22 @@ 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; {
uint16 *act,mask,bits; int i, j;
uint16 *act, mask, bits;
int count = 0; int count = 0;
bits = 1<<part->_chan; bits = 1 << part->_chan;
act = part->_mc->gm()->_actives; act = part->_mc->gm()->_actives;
for(i=8; i; i--) { for (i = 8; i; i--) {
mask = *act++; mask = *act++;
if (mask) { if (mask) {
for(j=16; j; j--,mask>>=1,active++) { for (j = 16; j; j--, mask >>= 1, active++) {
if (mask&1 && !(*active&bits)) { if (mask & 1 && !(*active & bits)) {
*active|=bits; *active |= bits;
count++; count++;
} }
} }
@ -554,11 +607,12 @@ 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 */
if (what&pcProgram && part->_percussion) { if (what & pcProgram && part->_percussion) {
part->_percussion = false; part->_percussion = false;
update_pris(); update_pris();
} }
@ -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

File diff suppressed because it is too large Load diff

122
sys.cpp
View file

@ -23,47 +23,55 @@
#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);
if (mode==1) if (mode == 1)
return fopen(filename, "rb"); return fopen(filename, "rb");
if (mode==2) { if (mode == 2) {
error("fileOpen: write not supported"); error("fileOpen: write not supported");
} }
return NULL; return NULL;
} }
void Scumm::fileClose(void *file) { void Scumm::fileClose(void *file)
if (_fileMode==1 || _fileMode==2) {
fclose((FILE*)file); if (_fileMode == 1 || _fileMode == 2)
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) { {
case 1: case 2: switch (_fileMode) {
if (fseek((FILE*)file, offs, whence)!=0) case 1:
clearerr((FILE*)file); case 2:
if (fseek((FILE *) file, offs, whence) != 0)
clearerr((FILE *) file);
return; return;
case 3: case 3:
_whereInResToRead = offs; _whereInResToRead = offs;
@ -71,27 +79,28 @@ 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) {
case 1: case 1:
if (size==0) if (size == 0)
return; return;
if ((uint32)fread(ptr2, size, 1, (FILE*)file) != 1) { if ((uint32)fread(ptr2, size, 1, (FILE *) file) != 1) {
clearerr((FILE*)file); clearerr((FILE *) file);
_fileReadFailed = true; _fileReadFailed = true;
} }
do { do {
*ptr2++ ^= _encbyte; *ptr2++ ^= _encbyte;
} while(--size); } while (--size);
return; return;
case 3: case 3:
if (size==0) if (size == 0)
return; return;
src = getResourceAddress(rtTemp, 3) + _whereInResToRead; src = getResourceAddress(rtTemp, 3) + _whereInResToRead;
@ -103,14 +112,15 @@ void Scumm::fileRead(void *file, void *ptr, uint32 size) {
} }
} }
int Scumm::fileReadByte() { int Scumm::fileReadByte()
{
byte b; byte b;
byte *src; byte *src;
switch(_fileMode) { switch (_fileMode) {
case 1: case 1:
if (fread(&b,1,1,(FILE*)_fileHandle) != 1) { if (fread(&b, 1, 1, (FILE *) _fileHandle) != 1) {
clearerr((FILE*)_fileHandle); clearerr((FILE *) _fileHandle);
_fileReadFailed = true; _fileReadFailed = true;
} }
return b ^ _encbyte; return b ^ _encbyte;
@ -123,66 +133,76 @@ 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); {
if (me==NULL) byte *me = (byte *)::calloc(size + 4, 1);
if (me == NULL)
return NULL; return NULL;
*((uint32*)me) = 0xDEADBEEF; *((uint32 *)me) = 0xDEADBEEF;
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) {
error("Freeing invalid block."); error("Freeing invalid block.");
} }
*((uint32*)me) = 0xC007CAFE; *((uint32 *)me) = 0xC007CAFE;
::free(me); ::free(me);
} }
} }
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;
@ -41,7 +42,7 @@ void Scumm_v3::readIndexFile() {
if (fileReadFailed(_fileHandle)) if (fileReadFailed(_fileHandle))
break; break;
switch(blocktype) { switch (blocktype) {
case 0x4E52: case 0x4E52:
fileReadWordLE(); fileReadWordLE();
break; break;
@ -61,7 +62,7 @@ void Scumm_v3::readIndexFile() {
_numGlobalObjects = fileReadWordLE(); _numGlobalObjects = fileReadWordLE();
break; break;
} }
fileSeek(_fileHandle, itemsize-8,SEEK_CUR); fileSeek(_fileHandle, itemsize - 8, SEEK_CUR);
} }
clearFileReadFailed(_fileHandle); clearFileReadFailed(_fileHandle);
@ -81,7 +82,7 @@ void Scumm_v3::readIndexFile() {
_numGlobalScripts = 200; _numGlobalScripts = 200;
_shadowPaletteSize = 256; _shadowPaletteSize = 256;
_shadowPalette = (byte*)alloc(_shadowPaletteSize); // stupid for now. Need to be removed later _shadowPalette = (byte *)alloc(_shadowPaletteSize); // stupid for now. Need to be removed later
_numFlObject = 50; _numFlObject = 50;
allocateArrays(); allocateArrays();
@ -95,32 +96,32 @@ void Scumm_v3::readIndexFile() {
numblock++; numblock++;
switch(blocktype) { switch (blocktype) {
case 0x4E52: case 0x4E52:
fileSeek(_fileHandle, itemsize-6,SEEK_CUR); fileSeek(_fileHandle, itemsize - 6, SEEK_CUR);
break; break;
case 0x5230: case 0x5230:
readResTypeList(rtRoom,MKID('ROOM'),"room"); readResTypeList(rtRoom, MKID('ROOM'), "room");
break; break;
case 0x5330: case 0x5330:
readResTypeList(rtScript,MKID('SCRP'),"script"); readResTypeList(rtScript, MKID('SCRP'), "script");
break; break;
case 0x4E30: case 0x4E30:
readResTypeList(rtSound,MKID('SOUN'),"sound"); readResTypeList(rtSound, MKID('SOUN'), "sound");
break; break;
case 0x4330: case 0x4330:
readResTypeList(rtCostume,MKID('COST'),"costume"); readResTypeList(rtCostume, MKID('COST'), "costume");
break; break;
case 0x4F30: case 0x4F30:
num = fileReadWordLE(); num = fileReadWordLE();
assert(num == _numGlobalObjects); assert(num == _numGlobalObjects);
for (i=0; i!=num; i++) { for (i = 0; i != num; i++) {
uint32 bits = fileReadByte(); uint32 bits = fileReadByte();
byte tmp; byte tmp;
bits |= fileReadByte() << 8; bits |= fileReadByte() << 8;
@ -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,14 +144,15 @@ 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));
checkRange(4 ,0 ,no , "Loading illegal charset %d"); checkRange(4, 0, no, "Loading illegal charset %d");
openRoom(-1); openRoom(-1);
openRoom(98+no); openRoom(98 + no);
size = fileReadWordLE(); size = fileReadWordLE();

View file

@ -23,15 +23,17 @@
#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));
checkRange(4 ,0 ,no , "Loading illegal charset %d"); memset(_charsetData, 0, sizeof(_charsetData));
checkRange(4, 0, no, "Loading illegal charset %d");
openRoom(-1); openRoom(-1);
openRoom(900+no); openRoom(900 + no);
size = fileReadDwordLE(); size = fileReadDwordLE();

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;

113
verbs.cpp
View file

@ -23,25 +23,27 @@
#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;
if (_userPut<=0 || _mouseButStat==0) if (_userPut <= 0 || _mouseButStat == 0)
return; return;
if (_mouseButStat < MBS_MAX_KEY) { if (_mouseButStat < MBS_MAX_KEY) {
/* Check keypresses */ /* Check keypresses */
vs = &_verbs[1]; vs = &_verbs[1];
for (i=1; i<_maxVerbs; i++,vs++) { for (i = 1; i < _maxVerbs; i++, vs++) {
if (vs->verbid && vs->saveid==0 && vs->curmode==1) { if (vs->verbid && vs->saveid == 0 && vs->curmode == 1) {
if (_mouseButStat == vs->key) { if (_mouseButStat == vs->key) {
runInputScript(1, vs->verbid, 1); runInputScript(1, vs->verbid, 1);
return; return;
@ -49,44 +51,47 @@ 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);
return; return;
} }
runInputScript(2, 0, code); runInputScript(2, 0, code);
} else { } else {
over=checkMouseOver(mouse.x, mouse.y); over = checkMouseOver(mouse.x, mouse.y);
runInputScript(1, over!=0 ? _verbs[over].verbid : 0, code); runInputScript(1, over != 0 ? _verbs[over].verbid : 0, code);
} }
} }
} }
void Scumm::verbMouseOver(int verb) { void Scumm::verbMouseOver(int verb)
if (_verbMouseOver==verb) {
if (_verbMouseOver == verb)
return; return;
if (_verbs[_verbMouseOver].type!=1) { if (_verbs[_verbMouseOver].type != 1) {
drawVerb(_verbMouseOver, 0); drawVerb(_verbMouseOver, 0);
_verbMouseOver = verb; _verbMouseOver = verb;
} }
if (_verbs[verb].type!=1 && _verbs[verb].hicolor) { if (_verbs[verb].type != 1 && _verbs[verb].hicolor) {
drawVerb(verb, 1); drawVerb(verb, 1);
_verbMouseOver = verb; _verbMouseOver = 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;
vs = &_verbs[i]; vs = &_verbs[i];
do { do {
if (vs->curmode!=1 || !vs->verbid || vs->saveid || if (vs->curmode != 1 || !vs->verbid || vs->saveid ||
y < vs->y || y >= vs->bottom) y < vs->y || y >= vs->bottom)
continue; continue;
if (vs->center) { if (vs->center) {
@ -98,11 +103,12 @@ int Scumm::checkMouseOver(int x, int y) {
} }
return i; return i;
} while (--vs,--i); } while (--vs, --i);
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;
@ -113,7 +119,7 @@ void Scumm::drawVerb(int vrb, int mode) {
vs = &_verbs[vrb]; vs = &_verbs[vrb];
if (!vs->saveid && vs->curmode && vs->verbid) { if (!vs->saveid && vs->curmode && vs->verbid) {
if (vs->type==1) { if (vs->type == 1) {
drawVerbBitmap(vrb, vs->x, vs->y); drawVerbBitmap(vrb, vs->x, vs->y);
return; return;
} }
@ -129,7 +135,7 @@ void Scumm::drawVerb(int vrb, int mode) {
else else
color = vs->color; color = vs->color;
string[4].color = color; string[4].color = color;
if (vs->curmode==2) if (vs->curmode == 2)
string[4].color = vs->dimcolor; string[4].color = vs->dimcolor;
_messagePtr = getResourceAddress(rtVerb, vrb); _messagePtr = getResourceAddress(rtVerb, vrb);
@ -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,18 +171,19 @@ 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;
int ydiff, xstrip; int ydiff, xstrip;
int imgw, imgh; int imgw, imgh;
int i,tmp; int i, tmp;
byte *obim; byte *obim;
ImageHeader *imhd; ImageHeader *imhd;
uint32 size; uint32 size;
if ((vs=findVirtScreen(y)) == NULL) if ((vs = findVirtScreen(y)) == NULL)
return; return;
_lastXstart = virtscr[0].xstart; _lastXstart = virtscr[0].xstart;
@ -185,20 +193,20 @@ void Scumm::drawVerbBitmap(int vrb, int x, int y) {
twobufs = vs->alloctwobuffers; twobufs = vs->alloctwobuffers;
vs->alloctwobuffers = 0; vs->alloctwobuffers = 0;
xstrip = x>>3; xstrip = x >> 3;
ydiff = y - vs->topline; ydiff = y - vs->topline;
obim = getResourceAddress(rtVerb, vrb); obim = getResourceAddress(rtVerb, vrb);
if (_features & GF_SMALL_HEADER) { if (_features & GF_SMALL_HEADER) {
int obj; int obj;
obj = READ_LE_UINT16(obim+6); obj = READ_LE_UINT16(obim + 6);
size = READ_LE_UINT32(obim); size = READ_LE_UINT32(obim);
imgw = (*(obim+size+11)) ; imgw = (*(obim + size + 11));
imgh = (*(obim+size+17))>>3 ; imgh = (*(obim + size + 17)) >> 3;
imptr = (obim+8); imptr = (obim + 8);
} else { } else {
imhd = (ImageHeader*)findResourceData(MKID('IMHD'), obim); imhd = (ImageHeader *)findResourceData(MKID('IMHD'), obim);
if (_features & GF_AFTER_V7) { if (_features & GF_AFTER_V7) {
imgw = READ_LE_UINT16(&imhd->v7.width) >> 3; imgw = READ_LE_UINT16(&imhd->v7.width) >> 3;
imgh = READ_LE_UINT16(&imhd->v7.height) >> 3; imgh = READ_LE_UINT16(&imhd->v7.height) >> 3;
@ -211,15 +219,15 @@ void Scumm::drawVerbBitmap(int vrb, int x, int y) {
if (!imptr) if (!imptr)
error("No image for verb %d", vrb); error("No image for verb %d", vrb);
} }
for (i=0; i<imgw; i++) { for (i = 0; i < imgw; i++) {
tmp = xstrip + i; tmp = xstrip + i;
if ((uint)tmp < 40) if ((uint) tmp < 40)
gdi.drawBitmap(imptr, vs, tmp, ydiff, imgh<<3, i, 1, true); gdi.drawBitmap(imptr, vs, tmp, ydiff, imgh << 3, i, 1, true);
} }
vst = &_verbs[vrb]; vst = &_verbs[vrb];
vst->right = vst->x + imgw*8; vst->right = vst->x + imgw * 8;
vst->bottom = vst->y + imgh*8; vst->bottom = vst->y + imgh * 8;
vst->oldleft = vst->x; vst->oldleft = vst->x;
vst->oldright = vst->right; vst->oldright = vst->right;
vst->oldtop = vst->y; vst->oldtop = vst->y;
@ -230,9 +238,10 @@ 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) {
return i; return i;
} }
@ -240,10 +249,11 @@ 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)
return; return;
vs = &_verbs[slot]; vs = &_verbs[slot];
@ -252,14 +262,15 @@ void Scumm::killVerb(int slot) {
nukeResource(rtVerb, slot); nukeResource(rtVerb, slot);
if (vs->saveid==0){ if (vs->saveid == 0) {
drawVerb(slot, 0); drawVerb(slot, 0);
verbMouseOver(0); verbMouseOver(0);
} }
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;
@ -269,23 +280,23 @@ void Scumm::setVerbObject(uint room, uint object, uint verb) {
if (whereIsObject(object) == WIO_FLOBJECT) if (whereIsObject(object) == WIO_FLOBJECT)
error("Can't grab verb image from flobject"); error("Can't grab verb image from flobject");
if(_features & GF_SMALL_HEADER) { if (_features & GF_SMALL_HEADER) {
for(i = _numObjectsInRoom; i>0; i--) { for (i = _numObjectsInRoom; i > 0; i--) {
if(_objs[i].obj_nr == object) { if (_objs[i].obj_nr == object) {
findObjectInRoom(&foir, foImageHeader, object, room); findObjectInRoom(&foir, foImageHeader, object, room);
size = READ_LE_UINT32(foir.obim); size = READ_LE_UINT32(foir.obim);
obcdptr = getResourceAddress(rtRoom, room) + getOBCDOffs(object); obcdptr = getResourceAddress(rtRoom, room) + getOBCDOffs(object);
size2 = READ_LE_UINT32(obcdptr); size2 = READ_LE_UINT32(obcdptr);
createResource(rtVerb, verb, size+size2); createResource(rtVerb, verb, size + size2);
obimptr = getResourceAddress(rtRoom, room) - foir.roomptr + foir.obim; obimptr = getResourceAddress(rtRoom, room) - foir.roomptr + foir.obim;
obcdptr = getResourceAddress(rtRoom, room) + getOBCDOffs(object); obcdptr = getResourceAddress(rtRoom, room) + getOBCDOffs(object);
memcpy(getResourceAddress(rtVerb, verb), obimptr, size); memcpy(getResourceAddress(rtVerb, verb), obimptr, size);
memcpy(getResourceAddress(rtVerb, verb)+size, obcdptr, size2); memcpy(getResourceAddress(rtVerb, verb) + size, obcdptr, size2);
} }
} }
} else { } else {
findObjectInRoom(&foir, foImageHeader, object, room); findObjectInRoom(&foir, foImageHeader, object, room);
size = READ_BE_UINT32_UNALIGNED(foir.obim+4); size = READ_BE_UINT32_UNALIGNED(foir.obim + 4);
createResource(rtVerb, verb, size); createResource(rtVerb, verb, size);
obimptr = getResourceAddress(rtRoom, room) - foir.roomptr + foir.obim; obimptr = getResourceAddress(rtRoom, room) - foir.roomptr + foir.obim;
memcpy(getResourceAddress(rtVerb, verb), obimptr, size); memcpy(getResourceAddress(rtVerb, verb), obimptr, size);

View file

@ -88,16 +88,17 @@ public:
void setPalette(byte *ctab, int first, int num); void setPalette(byte *ctab, int first, int num);
void writeToScreen(); void writeToScreen();
void prepare_header(WAVEHDR *wh, int i); void prepare_header(WAVEHDR * wh, int i);
void sound_init(); void sound_init();
static DWORD _stdcall sound_thread(WndMan *wm); static DWORD _stdcall sound_thread(WndMan * wm);
#if USE_GDI #if USE_GDI
bool allocateDIB(int w, int h); bool allocateDIB(int w, int h);
#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,56 +115,70 @@ 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;
} }
return key; return 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,
WndMan *wm = (WndMan*)GetWindowLong(hWnd, GWL_USERDATA); LPARAM lParam)
{
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);
break; break;
case WM_KEYDOWN: case WM_KEYDOWN:
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;
wm->_scumm->_saveLoadCompatible = false; wm->_scumm->_saveLoadCompatible = false;
} }
if (GetAsyncKeyState(VK_CONTROL)<0) { if (GetAsyncKeyState(VK_CONTROL) < 0) {
if (wParam=='F') { if (wParam == 'F') {
wm->_scumm->_fastMode ^= 1; wm->_scumm->_fastMode ^= 1;
} }
if (wParam=='G') { if (wParam == 'G') {
veryFastMode ^= 1; veryFastMode ^= 1;
} }
if (wParam=='D') { if (wParam == 'D') {
debugger.attach(wm->_scumm); debugger.attach(wm->_scumm);
} }
if (wParam=='S') { if (wParam == 'S') {
wm->_scumm->resourceStats(); wm->_scumm->resourceStats();
} }
} }
@ -172,17 +187,17 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM l
break; break;
case WM_MOUSEMOVE: case WM_MOUSEMOVE:
wm->_scumm->mouse.x = ((int16*)&lParam)[0]; wm->_scumm->mouse.x = ((int16 *) & lParam)[0];
wm->_scumm->mouse.y = ((int16*)&lParam)[1]; wm->_scumm->mouse.y = ((int16 *) & lParam)[1];
break; break;
case WM_LBUTTONDOWN: case WM_LBUTTONDOWN:
wm->_scumm->_leftBtnPressed |= msClicked|msDown; wm->_scumm->_leftBtnPressed |= msClicked | msDown;
break; break;
case WM_LBUTTONUP: case WM_LBUTTONUP:
wm->_scumm->_leftBtnPressed &= ~msDown; wm->_scumm->_leftBtnPressed &= ~msDown;
break; break;
case WM_RBUTTONDOWN: case WM_RBUTTONDOWN:
wm->_scumm->_rightBtnPressed |= msClicked|msDown; wm->_scumm->_rightBtnPressed |= msClicked | msDown;
break; break;
case WM_RBUTTONUP: case WM_RBUTTONUP:
wm->_scumm->_rightBtnPressed &= ~msDown; wm->_scumm->_rightBtnPressed &= ~msDown;
@ -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];
@ -212,23 +228,25 @@ bool WndMan::allocateDIB(int w, int h) {
d.bih.biBitCount = 8; d.bih.biBitCount = 8;
d.bih.biCompression = BI_RGB; d.bih.biCompression = BI_RGB;
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;
#if DEST_WIDTH==320 #if DEST_WIDTH==320
if (_vgabuf) { if (_vgabuf) {
for (int y=0; y<200; y++) { for (int y = 0; y < 200; y++) {
memcpy(dib.buf + y*320,_vgabuf + y*320, 320); memcpy(dib.buf + y * 320, _vgabuf + y * 320, 320);
} }
} }
#endif #endif
@ -240,7 +258,7 @@ void WndMan::writeToScreen() {
dc = GetDC(hWnd); dc = GetDC(hWnd);
bmpdc = CreateCompatibleDC(dc); bmpdc = CreateCompatibleDC(dc);
bmpOld = (HBITMAP)SelectObject(bmpdc, dib.hSect); bmpOld = (HBITMAP) SelectObject(bmpdc, dib.hSect);
if (dib.new_pal) { if (dib.new_pal) {
dib.new_pal = false; dib.new_pal = false;
@ -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,13 +278,14 @@ 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++) {
dib.pal[i].rgbRed = ctab[i*3+0]; dib.pal[i].rgbRed = ctab[i * 3 + 0];
dib.pal[i].rgbGreen = ctab[i*3+1]; dib.pal[i].rgbGreen = ctab[i * 3 + 1];
dib.pal[i].rgbBlue = ctab[i*3+2]; dib.pal[i].rgbBlue = ctab[i * 3 + 2];
} }
dib.new_pal = true; dib.new_pal = true;
@ -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);
@ -284,13 +305,13 @@ void WndMan::init() {
WNDCLASSEX wcex; WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX); wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc; wcex.lpfnWndProc = (WNDPROC) WndProc;
wcex.cbClsExtra = 0; wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0; wcex.cbWndExtra = 0;
wcex.hInstance = hInst; wcex.hInstance = hInst;
wcex.hIcon = 0; wcex.hIcon = 0;
wcex.hCursor = ::LoadCursor(NULL, IDC_ARROW); wcex.hCursor =::LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
wcex.lpszMenuName = 0; wcex.lpszMenuName = 0;
wcex.lpszClassName = "ScummVM"; wcex.lpszClassName = "ScummVM";
wcex.hIconSm = 0; wcex.hIconSm = 0;
@ -299,10 +320,11 @@ 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);
dib.new_pal = false; dib.new_pal = false;
if (!allocateDIB(DEST_WIDTH, DEST_HEIGHT)) if (!allocateDIB(DEST_WIDTH, DEST_HEIGHT))
@ -314,14 +336,15 @@ 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))
return false; return false;
if (msg.message==WM_QUIT) { if (msg.message == WM_QUIT) {
terminated=true; terminated = true;
exit(1); exit(1);
return true; return true;
} }
@ -335,42 +358,40 @@ 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++) {
byte *p = s+y*40; byte *p = s + y * 40;
byte *pd = d + y*320; byte *pd = d + y * 320;
byte bits = 0x80, bdata = *p++; byte bits = 0x80, bdata = *p++;
for (x=0; x<w; x++) { for (x = 0; x < w; x++) {
*pd++ = (bdata & bits) ? 128 : 0; *pd++ = (bdata & bits) ? 128 : 0;
bits>>=1; bits >>= 1;
if (!bits) { if (!bits) {
bdata = *p++; bdata = *p++;
bits=0x80; bits = 0x80;
} }
} }
} }
} }
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,47 +399,58 @@ 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];
switch(disp) { switch (disp) {
case 0: case 0:
wm->_vgabuf = buf; wm->_vgabuf = buf;
memcpy(buf, wm->_vgabuf, 64000); memcpy(buf, wm->_vgabuf, 64000);
memcpy(buf,s->getResourceAddress(rtBuffer, 5),320*200); memcpy(buf, s->getResourceAddress(rtBuffer, 5), 320 * 200);
break; break;
case 1: case 1:
wm->_vgabuf = buf; wm->_vgabuf = buf;
memcpy(buf, wm->_vgabuf, 64000); memcpy(buf, wm->_vgabuf, 64000);
memcpy(buf,s->getResourceAddress(rtBuffer, 1),320*200); memcpy(buf, s->getResourceAddress(rtBuffer, 1), 320 * 200);
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;
do { do {
memcpy(dst, src, w); memcpy(dst, src, w);
@ -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,44 +477,51 @@ 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);
if (s->_fastMode) if (s->_fastMode)
delay=10; delay = 10;
Sleep(delay); Sleep(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;
waveOutPrepareHeader(_handle, wh, sizeof(WAVEHDR)); waveOutPrepareHeader(_handle, wh, sizeof(WAVEHDR));
fill_buffer((int16*)wh->lpData, wh->dwBufferLength>>1); fill_buffer((int16 *) wh->lpData, wh->dwBufferLength >> 1);
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,
SetThreadPriority((void*)_threadId, THREAD_PRIORITY_HIGHEST); this, 0, &_threadId);
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;
@ -521,10 +566,10 @@ DWORD _stdcall WndMan::sound_thread(WndMan *wm) {
signaled = WaitForSingleObject(wm->_event, time - cur) == WAIT_OBJECT_0; signaled = WaitForSingleObject(wm->_event, time - cur) == WAIT_OBJECT_0;
if (signaled) { if (signaled) {
for(i=0; i<2; i++) { for (i = 0; i < 2; i++) {
WAVEHDR *hdr = &wm->_hdr[i]; WAVEHDR *hdr = &wm->_hdr[i];
if (hdr->dwFlags & WHDR_DONE) { if (hdr->dwFlags & WHDR_DONE) {
fill_buffer((int16*)hdr->lpData, hdr->dwBufferLength>>1); fill_buffer((int16 *) hdr->lpData, hdr->dwBufferLength >> 1);
waveOutWrite(wm->_handle, hdr, sizeof(WAVEHDR)); waveOutWrite(wm->_handle, hdr, sizeof(WAVEHDR));
} }
} }
@ -534,14 +579,15 @@ 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();
wm->_vgabuf = (byte*)calloc(320,200); wm->_vgabuf = (byte *)calloc(320, 200);
wm->_scumm = &scumm; wm->_scumm = &scumm;
sound.initialize(&scumm,&snd_driv); sound.initialize(&scumm, &snd_driv);
wm->sound_init(); wm->sound_init();
@ -555,7 +601,7 @@ int main(int argc, char* argv[]) {
do { do {
updateScreen(&scumm); updateScreen(&scumm);
waitForTimer(&scumm, delta*15); waitForTimer(&scumm, delta * 15);
if (gui._active) { if (gui._active) {
gui.loop(); gui.loop();
@ -563,9 +609,11 @@ int main(int argc, char* argv[]) {
} else { } else {
delta = scumm.scummLoop(delta); delta = scumm.scummLoop(delta);
} }
} while(1); } while (1);
return 0; return 0;
} }
void BoxTest(int num) {;} // Test code void BoxTest(int num)
{;
} // Test code

190
x11.cpp
View file

@ -82,18 +82,21 @@ 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) +
((current_time.tv_usec - start_time.tv_usec) / 1000)); ((current_time.tv_usec - start_time.tv_usec) / 1000));
} }
#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];
@ -105,7 +108,7 @@ static void *sound_and_music_thread(void *params) {
exit(1); exit(1);
} }
param = 0; param = 0;
frag_size = FRAG_SIZE /* audio fragment size */; frag_size = FRAG_SIZE /* audio fragment size */ ;
while (frag_size) { while (frag_size) {
frag_size >>= 1; frag_size >>= 1;
param++; param++;
@ -149,10 +152,10 @@ static void *sound_and_music_thread(void *params) {
} }
while (1) { while (1) {
unsigned short *buf = (unsigned short *) sound_buffer; unsigned short *buf = (unsigned short *)sound_buffer;
int size, written; int size, written;
scumm.mixWaves((short *) sound_buffer, FRAG_SIZE >> 2); scumm.mixWaves((short *)sound_buffer, FRAG_SIZE >> 2);
/* Now convert to stereo */ /* Now convert to stereo */
for (int i = ((FRAG_SIZE >> 2) - 1); i >= 0; i--) { for (int i = ((FRAG_SIZE >> 2) - 1); i >= 0; i--) {
buf[2 * i + 1] = buf[2 * i] = buf[i]; buf[2 * i + 1] = buf[2 * i] = buf[i];
@ -168,49 +171,55 @@ 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);
XFreePixmap(display, pixmapBits); XFreePixmap(display, pixmapBits);
} }
XDefineCursor(display, window, cursor); XDefineCursor(display, window, cursor);
} }
/* 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;
XGCValues values; XGCValues values;
XTextProperty window_name; XTextProperty window_name;
char *name = (char *) &buf; char *name = (char *)&buf;
scale = scaleFactor; // not implemented yet! ignored. scale = scaleFactor; // not implemented yet! ignored.
@ -240,16 +249,20 @@ void initGraphics(Scumm *s, bool fullScreen, unsigned int scaleFactor) {
wm_hints->flags = InputHint | StateHint; wm_hints->flags = InputHint | StateHint;
wm_hints->input = True; wm_hints->input = True;
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;
shminfo.readOnly = False; shminfo.readOnly = False;
if (XShmAttach(display, &shminfo) == 0) { if (XShmAttach(display, &shminfo) == 0) {
@ -272,32 +285,35 @@ void initGraphics(Scumm *s, bool fullScreen, unsigned int scaleFactor) {
goto out_of_loop; goto out_of_loop;
} }
} }
out_of_loop: out_of_loop:
create_empty_cursor(display, screen, window); create_empty_cursor(display, screen, window);
/* And finally start the music thread */ /* And finally start the music thread */
pthread_create(&sound_thread, NULL, sound_and_music_thread, NULL); pthread_create(&sound_thread, NULL, sound_and_music_thread, NULL);
/* Initialize the 'local' frame buffer */ /* Initialize the 'local' frame buffer */
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;
/* For the window title */ /* For the window title */
sprintf(buf, "ScummVM - %s", gameName = s->getGameName()); sprintf(buf, "ScummVM - %s", gameName = s->getGameName());
free(gameName); free(gameName);
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,23 +434,28 @@ 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,
unsigned char *dst,*bak; bool visible)
{
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;
} }
if (hide_mouse) if (hide_mouse)
visible = false; visible = false;
assert(w<=BAK_WIDTH && h<=BAK_HEIGHT); assert(w <= BAK_WIDTH && h <= BAK_HEIGHT);
if (has_mouse) { if (has_mouse) {
int old_h = old_mouse_h; int old_h = old_mouse_h;
@ -510,25 +533,30 @@ 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;
unsigned char *data = s->_currentPalette; unsigned char *data = s->_currentPalette;
unsigned short *pal = &(palette[first]); unsigned short *pal = &(palette[first]);
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,19 +564,24 @@ 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 };
dirty_square dout = {320, 200, 0, 0 }; dirty_square dout = { 320, 200, 0, 0 };
if (s->_fastMode&2) if (s->_fastMode & 2)
return; return;
if (hide_mouse) { if (hide_mouse) {
@ -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,16 +641,17 @@ 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;
struct timeval tv; struct timeval tv;
XEvent event; XEvent event;
if (s->_fastMode&2) if (s->_fastMode & 2)
msec_delay = 0; msec_delay = 0;
else if (s->_fastMode&1) else if (s->_fastMode & 1)
msec_delay = 10; msec_delay = 10;
end_time = start_time + msec_delay; end_time = start_time + msec_delay;
@ -636,9 +670,9 @@ void waitForTimer(Scumm *s, int msec_delay) {
if (select(x11_socket + 1, &rfds, NULL, NULL, &tv) == 0) if (select(x11_socket + 1, &rfds, NULL, NULL, &tv) == 0)
break; /* This is the timeout */ break; /* This is the timeout */
while (XPending(display)) { while (XPending(display)) {
XNextEvent(display,&event); XNextEvent(display, &event);
switch (event.type) { switch (event.type) {
case Expose: { case Expose:{
int real_w, real_h; int real_w, real_h;
int real_x, real_y; int real_x, real_y;
real_x = event.xexpose.x; real_x = event.xexpose.x;
@ -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) {
@ -712,10 +749,11 @@ void waitForTimer(Scumm *s, int msec_delay) {
fake_right_mouse = 0; fake_right_mouse = 0;
break; break;
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;
} }
} }
@ -725,12 +763,12 @@ void waitForTimer(Scumm *s, int msec_delay) {
if (report_presses != 0) { if (report_presses != 0) {
if (event.xbutton.button == 1) { if (event.xbutton.button == 1) {
if (fake_right_mouse == 0) { if (fake_right_mouse == 0) {
s->_leftBtnPressed |= msClicked|msDown; s->_leftBtnPressed |= msClicked | msDown;
} else { } else {
s->_rightBtnPressed |= msClicked|msDown; s->_rightBtnPressed |= msClicked | msDown;
} }
} else if (event.xbutton.button == 3) } else if (event.xbutton.button == 3)
s->_rightBtnPressed |= msClicked|msDown; s->_rightBtnPressed |= msClicked | msDown;
} }
break; break;
@ -747,8 +785,8 @@ void waitForTimer(Scumm *s, int msec_delay) {
} }
break; break;
case MotionNotify: { case MotionNotify:{
int newx,newy; int newx, newy;
newx = event.xmotion.x - scumm_x; newx = event.xmotion.x - scumm_x;
newy = event.xmotion.y - scumm_y; newy = event.xmotion.y - scumm_y;
if ((newx != s->mouse.x) || (newy != s->mouse.y)) { if ((newx != s->mouse.x) || (newy != s->mouse.y)) {
@ -757,18 +795,21 @@ 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) ||
(window_height != event.xconfigure.height)) { (window_height != event.xconfigure.height)) {
window_width = event.xconfigure.width; window_width = event.xconfigure.width;
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;