save/load dialog by pressing F5,

multiple sounds at the same time,
some other fixes

svn-id: r3477
This commit is contained in:
Ludvig Strigeus 2001-11-09 18:54:15 +00:00
parent 355df1bbd5
commit 7d6994caa6
11 changed files with 398 additions and 321 deletions

151
gfx.cpp
View file

@ -24,21 +24,19 @@
void Scumm::getGraphicsPerformance() { void Scumm::getGraphicsPerformance() {
int i; int i;
_scummTimer = 0;
for (i=10; i!=0; i--) { for (i=10; i!=0; i--) {
initScreens(0, 0, 320, 200); initScreens(0, 0, 320, 200);
} }
_vars[VAR_PERFORMANCE_1] = _scummTimer; _vars[VAR_PERFORMANCE_1] = 0;//_scummTimer;
_scummTimer = 0;
for (i=10; i!=0; i--) { for (i=10; i!=0; i--) {
setDirtyRange(0, 0, 200); setDirtyRange(0, 0, 200);
unkVirtScreen2(); drawDirtyScreenParts();
} }
_vars[VAR_PERFORMANCE_2] = _scummTimer; _vars[VAR_PERFORMANCE_2] = 0;//_scummTimer;
initScreens(0, 16, 320, 144); initScreens(0, 16, 320, 144);
} }
@ -103,7 +101,7 @@ void Scumm::setDirtyRange(int slot, int top, int bottom) {
} }
} }
void Scumm::unkVirtScreen2() { void Scumm::drawDirtyScreenParts() {
int i; int i;
VirtScreen *vs; VirtScreen *vs;
@ -340,21 +338,20 @@ void Scumm::setPaletteFromPtr(byte *ptr) {
dest = _currentPalette; dest = _currentPalette;
if (_videoMode==0x13) { for (i=0; i<numcolor; i++) {
for (i=0; i<numcolor; i++) { r = *ptr++;
r = *ptr++; g = *ptr++;
g = *ptr++; b = *ptr++;
b = *ptr++; if (i<=15 || r<252 || g<252 || b<252) {
if (i<=15 || r<252 || g<252 || b<252) { *dest++ = r>>2;
*dest++ = r>>2; *dest++ = g>>2;
*dest++ = g>>2; *dest++ = b>>2;
*dest++ = b>>2; } else {
} else { dest += 3;
dest += 3;
}
} }
} }
#if 0
if (_videoMode==0xE) { if (_videoMode==0xE) {
epal = getResourceAddress(rtRoom, _roomResource) + _EPAL_offs + 8; epal = getResourceAddress(rtRoom, _roomResource) + _EPAL_offs + 8;
for (i=0; i<256; i++,epal++) { for (i=0; i<256; i++,epal++) {
@ -362,7 +359,8 @@ void Scumm::setPaletteFromPtr(byte *ptr) {
_currentPalette[i+256] = *epal>>4; _currentPalette[i+256] = *epal>>4;
} }
} }
#endif
setDirtyColors(0, numcolor-1); setDirtyColors(0, numcolor-1);
} }
@ -424,9 +422,6 @@ void Scumm::cyclePalette() {
byte *start, *end; byte *start, *end;
byte tmp[3]; byte tmp[3];
if(_videoMode != 0x13)
return;
valueToAdd = _vars[VAR_TIMER]; valueToAdd = _vars[VAR_TIMER];
if (valueToAdd < _vars[VAR_TIMER_NEXT]) if (valueToAdd < _vars[VAR_TIMER_NEXT])
valueToAdd = _vars[VAR_TIMER_NEXT]; valueToAdd = _vars[VAR_TIMER_NEXT];
@ -1273,8 +1268,12 @@ void Scumm::updateDirtyRect(int virt, int left, int right, int top, int bottom,
} }
} }
rp = right >> 3; setVirtscreenDirty(vs, left, top, right, bottom);
lp = left >> 3; }
void Scumm::setVirtscreenDirty(VirtScreen *vs, int left, int top, int right, int bottom) {
int lp = left >> 3;
int rp = right >> 3;
if (lp>=40 || rp<0) if (lp>=40 || rp<0)
return; return;
@ -1287,7 +1286,7 @@ void Scumm::updateDirtyRect(int virt, int left, int right, int top, int bottom,
if (bottom > vs->bdirty[lp]) if (bottom > vs->bdirty[lp])
vs->bdirty[lp] = bottom; vs->bdirty[lp] = bottom;
lp++; lp++;
} }
} }
VirtScreen *Scumm::findVirtScreen(int y) { VirtScreen *Scumm::findVirtScreen(int y) {
@ -1667,16 +1666,10 @@ void Gdi::resetBackground(byte top, byte bottom, int strip) {
} }
void Scumm::setPalColor(int index, int r, int g, int b) { void Scumm::setPalColor(int index, int r, int g, int b) {
if(_videoMode==0x13) { _currentPalette[index*3+0] = r>>2;
_currentPalette[index*3+0] = r>>2; _currentPalette[index*3+1] = g>>2;
_currentPalette[index*3+1] = g>>2; _currentPalette[index*3+2] = b>>2;
_currentPalette[index*3+2] = b>>2; setDirtyColors(index,index);
setDirtyColors(index,index);
}
if (_videoMode==0xE) {
/* TODO: implement this */
warning("stub setPalColor(%d,%d,%d,%d)",index,r,g,b);
}
} }
void Scumm::drawMouse() { void Scumm::drawMouse() {
@ -1695,18 +1688,8 @@ void Scumm::drawMouse() {
_cursorWidth, _cursorWidth,
_cursorHeight, _cursorHeight,
_grabbedCursor, _grabbedCursor,
gdi._unk4>0 gdi._cursorActive>0
); );
/*
::drawMouse(this,
mouse.x - gdi._hotspot_x,
mouse.y - gdi._hotspot_y,
gdi._mouseColors[((++gdi._mouseColorIndex)>>2)&3],
gdi._mouseMask + ((gdi._drawMouseX&7)<<6),
gdi._unk4>0
);
*/
} }
void Scumm::setCursorHotspot(int cursor, int x, int y) { void Scumm::setCursorHotspot(int cursor, int x, int y) {
@ -1792,45 +1775,39 @@ void Scumm::darkenPalette(int a, int b, int c, int d, int e) {
int num; int num;
byte color; byte color;
if (_videoMode==0xE) { cptr = getPalettePtr();
warning("stub darkenPalette(%d,%d,%d,%d,%d)",a,b,c,d,e); cptr += 8 + a*3;
} cur = _currentPalette + a*3;
if (a <= b) {
if (_videoMode==0x13) { num = b - a + 1;
cptr = getPalettePtr();
cptr += 8 + a*3; do {
cur = _currentPalette + a*3; if (c != 0xFF) {
if (a <= b) { color = *cptr++ * (c>>2) / 0xFF;
num = b - a + 1; } else {
color = *cptr++ >> 2;
do { }
if (c != 0xFF) { if(color>63) color = 63;
color = *cptr++ * (c>>2) / 0xFF; *cur++=color;
} else {
color = *cptr++ >> 2; if (d != 0xFF) {
} color = *cptr++ * (d>>2) / 0xFF;
if(color>63) color = 63; } else {
*cur++=color; color = *cptr++ >> 2;
}
if (d != 0xFF) { if(color>63) color = 63;
color = *cptr++ * (d>>2) / 0xFF; *cur++=color;
} else {
color = *cptr++ >> 2; if (e != 0xFF) {
} color = *cptr++ * (e>>2) / 0xFF;
if(color>63) color = 63; } else {
*cur++=color; color = *cptr++ >> 2;
}
if (e != 0xFF) { if(color>63) color = 63;
color = *cptr++ * (e>>2) / 0xFF; *cur++=color;
} else { } while (--num);
color = *cptr++ >> 2;
}
if(color>63) color = 63;
*cur++=color;
} while (--num);
}
setDirtyColors(a,b);
} }
setDirtyColors(a,b);
} }
void Scumm::grabCursor(int x, int y, int w, int h) { void Scumm::grabCursor(int x, int y, int w, int h) {
@ -1881,7 +1858,7 @@ void Scumm::grabCursor(byte *ptr, int width, int height) {
_cursorWidth = width; _cursorWidth = width;
_cursorHeight = height; _cursorHeight = height;
_cursorAnimate = false; _cursorAnimate = 0;
dst = _grabbedCursor; dst = _grabbedCursor;
for(;height;height--) { for(;height;height--) {
@ -1923,7 +1900,7 @@ void Scumm::useBompCursor(byte *im, int width, int height) {
_cursorWidth = width; _cursorWidth = width;
_cursorHeight = height; _cursorHeight = height;
_cursorAnimate = false; _cursorAnimate = 0;
decompressBomp(_grabbedCursor, im+10, width, height); decompressBomp(_grabbedCursor, im+10, width, height);
} }

View file

@ -481,7 +481,6 @@ int Scumm::loadResource(int type, int index) {
#endif #endif
if (!fileReadFailed(_fileHandle)) { if (!fileReadFailed(_fileHandle)) {
_scummTimer = 0;
return 1; return 1;
} }

View file

@ -26,18 +26,25 @@ struct SaveGameHeader {
uint32 type; uint32 type;
uint32 size; uint32 size;
uint32 ver; uint32 ver;
char name[32];
}; };
#define CURRENT_VER 3 #define CURRENT_VER 4
bool Scumm::saveState(const char *filename) { bool Scumm::saveState(int slot, bool compat) {
FILE *out = fopen(filename,"wb"); char filename[256];
FILE *out;
SaveGameHeader hdr; SaveGameHeader hdr;
Serializer ser; Serializer ser;
makeSavegameName(filename, slot, compat);
out = fopen(filename,"wb");
if (out==NULL) if (out==NULL)
return false; return false;
memcpy(hdr.name, _saveLoadName, sizeof(hdr.name));
hdr.type = MKID('SCVM'); hdr.type = MKID('SCVM');
hdr.size = 0; hdr.size = 0;
hdr.ver = CURRENT_VER; hdr.ver = CURRENT_VER;
@ -53,13 +60,17 @@ bool Scumm::saveState(const char *filename) {
return true; return true;
} }
bool Scumm::loadState(const char *filename) { bool Scumm::loadState(int slot, bool compat) {
FILE *out = fopen(filename,"rb"); char filename[256];
FILE *out;
int i,j; int i,j;
SaveGameHeader hdr; SaveGameHeader hdr;
Serializer ser; Serializer ser;
int sb,sh; int sb,sh;
makeSavegameName(filename, slot, compat);
out = fopen(filename,"rb");
if (out==NULL) if (out==NULL)
return false; return false;
@ -75,6 +86,8 @@ bool Scumm::loadState(const char *filename) {
fclose(out); fclose(out);
return false; return false;
} }
memcpy(_saveLoadName, hdr.name, sizeof(hdr.name));
CHECK_HEAP CHECK_HEAP
@ -107,7 +120,7 @@ bool Scumm::loadState(const char *filename) {
initScreens(0, sb, 320, sh); initScreens(0, sb, 320, sh);
_completeScreenRedraw = 1; _completeScreenRedraw = true;
setDirtyColors(0,255); setDirtyColors(0,255);
_lastCodePtr = NULL; _lastCodePtr = NULL;
@ -124,6 +137,41 @@ bool Scumm::loadState(const char *filename) {
return true; return true;
} }
void Scumm::makeSavegameName(char *out, int slot, bool compatible) {
sprintf(out, "%s.%c%.2d", _exe_name, compatible ? 'c': 's', slot);
}
bool Scumm::getSavegameName(int slot, char *desc) {
char filename[256];
FILE *out;
SaveGameHeader hdr;
bool result;
int len;
makeSavegameName(filename, slot, false);
out = fopen(filename,"rb");
if (out==NULL) {
strcpy(desc,"");
return false;
}
len = fread(&hdr, sizeof(hdr), 1, out);
fclose(out);
if (len!=1 || hdr.type != MKID('SCVM')) {
strcpy(desc, "Invalid savegame");
return false;
}
if (hdr.ver != CURRENT_VER) {
strcpy(desc, "Invalid version");
return false;
}
memcpy(desc, hdr.name, sizeof(hdr.name));
desc[sizeof(hdr.name)-1] = 0;
return true;
}
#define OFFS(type,item) ((int)(&((type*)0)->item)) #define OFFS(type,item) ((int)(&((type*)0)->item))
#define SIZE(type,item) sizeof(((type*)0)->item) #define SIZE(type,item) sizeof(((type*)0)->item)
#define MKLINE(type,item,saveas) {OFFS(type,item),saveas,SIZE(type,item)} #define MKLINE(type,item,saveas) {OFFS(type,item),saveas,SIZE(type,item)}
@ -267,7 +315,6 @@ void Scumm::saveOrLoad(Serializer *s) {
MKLINE(Scumm,camera._lastPos,sleInt16), MKLINE(Scumm,camera._lastPos,sleInt16),
MKLINE(Scumm,_screenStartStrip,sleInt16), MKLINE(Scumm,_screenStartStrip,sleInt16),
MKLINE(Scumm,_screenEndStrip,sleInt16), MKLINE(Scumm,_screenEndStrip,sleInt16),
MKLINE(Scumm,_scummTimer,sleInt16),
MKLINE(Scumm,camera._mode,sleByte), MKLINE(Scumm,camera._mode,sleByte),
MKLINE(Scumm,camera._follows,sleByte), MKLINE(Scumm,camera._follows,sleByte),
MKLINE(Scumm,camera._leftTrigger,sleInt16), MKLINE(Scumm,camera._leftTrigger,sleInt16),
@ -295,7 +342,7 @@ void Scumm::saveOrLoad(Serializer *s) {
MKLINE(Scumm,_numNestedScripts,sleByte), MKLINE(Scumm,_numNestedScripts,sleByte),
MKLINE(Scumm,_userPut,sleByte), MKLINE(Scumm,_userPut,sleByte),
MKLINE(Scumm,_cursorState,sleByte), MKLINE(Scumm,_cursorState,sleByte),
MKLINE(Scumm,gdi._unk4,sleByte), MKLINE(Scumm,gdi._cursorActive,sleByte),
MKLINE(Scumm,gdi._currentCursor,sleByte), MKLINE(Scumm,gdi._currentCursor,sleByte),
MKLINE(Scumm,_doEffect,sleByte), MKLINE(Scumm,_doEffect,sleByte),

View file

@ -953,3 +953,16 @@ int Scumm::getStringLen(byte *ptr) {
} while (1); } while (1);
return len+1; return len+1;
} }
void Scumm::exitCutscene() {
uint32 offs = vm.cutScenePtr[vm.cutSceneStackPointer];
if (offs) {
ScriptSlot *ss = &vm.slot[vm.cutSceneScript[vm.cutSceneStackPointer]];
ss->offs = offs;
ss->status = 2;
ss->freezeCount = 0;
ss->cutsceneOverride--;
_vars[VAR_OVERRIDE] = 1;
vm.cutScenePtr[vm.cutSceneStackPointer] = 0;
}
}

View file

@ -712,6 +712,7 @@ void Scumm::o5_drawObject() {
default: default:
error("o5_drawObject: default case"); error("o5_drawObject: default case");
} }
index = getObjectIndex(obj); index = getObjectIndex(obj);
if (index==-1) if (index==-1)
return; return;

37
scumm.h
View file

@ -511,7 +511,7 @@ struct Gdi {
byte *_readPtr; byte *_readPtr;
uint _readOffs; uint _readOffs;
int8 _unk4; int8 _cursorActive;
int _numZBuffer; int _numZBuffer;
int _imgBufOffs[4]; int _imgBufOffs[4];
@ -591,8 +591,8 @@ struct Scumm {
byte _majorScummVersion; byte _majorScummVersion;
byte _middleScummVersion; byte _middleScummVersion;
byte _minorScummVersion; byte _minorScummVersion;
ScummDebugger *_debugger; ScummDebugger *_debugger;
void *_gui; /* actually a pointer to a Gui */
int _lastLoadedRoom; int _lastLoadedRoom;
int _roomResource; int _roomResource;
@ -675,7 +675,7 @@ struct Scumm {
uint16 _defaultTalkDelay; uint16 _defaultTalkDelay;
byte _haveMsg; byte _haveMsg;
byte _newEffect; byte _newEffect;
uint16 _fullRedraw; bool _fullRedraw;
uint16 _soundParam,_soundParam2,_soundParam3; uint16 _soundParam,_soundParam2,_soundParam3;
byte _switchRoomEffect2, _switchRoomEffect; byte _switchRoomEffect2, _switchRoomEffect;
@ -701,7 +701,7 @@ struct Scumm {
int _cursorHotspotX, _cursorHotspotY; int _cursorHotspotX, _cursorHotspotY;
int _cursorWidth, _cursorHeight; int _cursorWidth, _cursorHeight;
byte _cursorAnimateIndex; byte _cursorAnimateIndex;
bool _cursorAnimate; byte _cursorAnimate;
byte _charsetColor; byte _charsetColor;
@ -719,12 +719,9 @@ struct Scumm {
int16 _screenStartStrip; int16 _screenStartStrip;
int16 _screenEndStrip; int16 _screenEndStrip;
int16 _scummTimer;
byte _playBackFile;
byte _fastMode; byte _fastMode;
uint16 _completeScreenRedraw; bool _completeScreenRedraw;
int8 _userPut; int8 _userPut;
int8 _cursorState; int8 _cursorState;
@ -755,7 +752,6 @@ struct Scumm {
uint16 _currentDrive; uint16 _currentDrive;
uint16 _soundCardType; uint16 _soundCardType;
uint16 _videoMode;
byte _mousePresent; byte _mousePresent;
int16 _palManipStart; int16 _palManipStart;
@ -882,7 +878,9 @@ struct Scumm {
int _boxMatrixItem; int _boxMatrixItem;
byte _grabbedCursor[1024]; byte _grabbedCursor[1024];
char _saveLoadName[32];
OpcodeProc getOpcode(int i) { return _opcodes[i]; } OpcodeProc getOpcode(int i) { return _opcodes[i]; }
void openRoom(int room); void openRoom(int room);
@ -949,12 +947,10 @@ struct Scumm {
void initVirtScreen(int slot, int top, int height, bool twobufs, bool fourextra); void initVirtScreen(int slot, int top, int height, bool twobufs, bool fourextra);
void setDirtyRange(int slot, int a, int height); void setDirtyRange(int slot, int a, int height);
void unkVirtScreen2(); void drawDirtyScreenParts();
void updateDirtyScreen(int slot); void updateDirtyScreen(int slot);
void unkVirtScreen4(int a); void unkVirtScreen4(int a);
void restoreMouse(); void restoreMouse();
void initActor(Actor *a, int mode); void initActor(Actor *a, int mode);
bool checkFixedDisk(); bool checkFixedDisk();
@ -1462,8 +1458,8 @@ struct Scumm {
void dumpResource(char *tag, int index, byte *ptr); void dumpResource(char *tag, int index, byte *ptr);
bool saveState(const char *filename); bool saveState(int slot, bool compat);
bool loadState(const char *filename); bool loadState(int slot, bool compat);
void saveOrLoad(Serializer *s); void saveOrLoad(Serializer *s);
void saveLoadResource(Serializer *ser, int type, int index); void saveLoadResource(Serializer *ser, int type, int index);
@ -1572,13 +1568,21 @@ struct Scumm {
void decompressBomp(byte *dst, byte *src, int w, int h); void decompressBomp(byte *dst, byte *src, int w, int h);
void setupCursor() { _cursorAnimate = true; } void setupCursor() { _cursorAnimate = 1; }
void decompressDefaultCursor(int index); void decompressDefaultCursor(int index);
void allocateArrays(); void allocateArrays();
void initializeLocals(int slot, int16 *vars); void initializeLocals(int slot, int16 *vars);
static void setVirtscreenDirty(VirtScreen *vs, int left, int top, int right, int bottom);
int scummLoop(int delta);
bool getSavegameName(int slot, char *desc);
void makeSavegameName(char *out, int slot, bool compatible);
void exitCutscene();
}; };
struct ScummDebugger { struct ScummDebugger {
@ -1624,7 +1628,6 @@ struct Serializer {
bool _saveOrLoad; bool _saveOrLoad;
void saveLoadBytes(void *b, int len); void saveLoadBytes(void *b, int len);
void saveLoadArrayOf(void *b, int len, int datasize, byte filetype); void saveLoadArrayOf(void *b, int len, int datasize, byte filetype);
void saveLoadEntries(void *d, const SaveLoadEntry *sle); void saveLoadEntries(void *d, const SaveLoadEntry *sle);

View file

@ -21,6 +21,7 @@
#include "stdafx.h" #include "stdafx.h"
#include "scumm.h" #include "scumm.h"
#include "gui.h"
void Scumm::initThingsV5() { void Scumm::initThingsV5() {
readIndexFileV5(1); readIndexFileV5(1);
@ -137,7 +138,7 @@ void Scumm::scummInit() {
_userPut = 0; _userPut = 0;
_newEffect = 129; _newEffect = 129;
_fullRedraw = 1; _fullRedraw = true;
clearDrawObjectQueue(); clearDrawObjectQueue();
@ -167,7 +168,7 @@ void Scumm::initScummVars() {
_vars[VAR_CURRENTDRIVE] = _currentDrive; _vars[VAR_CURRENTDRIVE] = _currentDrive;
_vars[VAR_FIXEDDISK] = checkFixedDisk(); _vars[VAR_FIXEDDISK] = checkFixedDisk();
_vars[VAR_SOUNDCARD] = _soundCardType; _vars[VAR_SOUNDCARD] = _soundCardType;
_vars[VAR_VIDEOMODE] = _videoMode; _vars[VAR_VIDEOMODE] = 0x13;
_vars[VAR_HEAPSPACE] = 600; _vars[VAR_HEAPSPACE] = 600;
_vars[VAR_MOUSEPRESENT] = _mousePresent; _vars[VAR_MOUSEPRESENT] = _mousePresent;
_vars[VAR_SOUNDPARAM] = _soundParam; _vars[VAR_SOUNDPARAM] = _soundParam;
@ -195,8 +196,8 @@ void Scumm::scummMain(int argc, char **argv) {
_debugMode = 1; _debugMode = 1;
_maxHeapThreshold = 350000; _maxHeapThreshold = 500000;
_minHeapThreshold = 300000; _minHeapThreshold = 450000;
parseCommandLine(argc, argv); parseCommandLine(argc, argv);
@ -231,100 +232,76 @@ void Scumm::scummMain(int argc, char **argv) {
setupSound(); setupSound();
runScript(1,0,0,&_bootParam); runScript(1,0,0,&_bootParam);
_scummTimer = 0; // _scummTimer = 0;
}
do { int Scumm::scummLoop(int delta) {
if (_playBackFile) { if (_debugger)
while ((_scummTimer>>2) < _vars[VAR_TIMER_NEXT]) {} _debugger->on_frame();
_scummTimer = _vars[VAR_TIMER_NEXT] << 2;
} _vars[VAR_TMR_1] += delta;
_vars[VAR_TMR_2] += delta;
CHECK_HEAP _vars[VAR_TMR_3] += delta;
updateScreen(this); _vars[VAR_TMR_4] += delta;
if (_debugger) if (delta > 15)
_debugger->on_frame(); delta = 15;
if (!(++_expire_counter)) { decreaseScriptDelay(delta);
increaseResourceCounter();
}
_vars[VAR_TIMER] = _scummTimer >> 2; _talkDelay -= delta;
do { if (_talkDelay<0) _talkDelay=0;
waitForTimer(this);
tmr = _scummTimer >> 2;
if (_fastMode)
tmr += 15;
} while (tmr < _vars[VAR_TIMER_NEXT]);
_scummTimer = 0;
_vars[VAR_TMR_1] += tmr; processKbd();
_vars[VAR_TMR_2] += tmr;
_vars[VAR_TMR_3] += tmr;
_vars[VAR_TMR_4] += tmr;
if (tmr > 15) _vars[VAR_CAMERA_CUR_POS] = camera._curPos;
tmr = 15; _vars[VAR_HAVE_MSG] = _haveMsg;
_vars[VAR_VIRT_MOUSE_X] = _virtual_mouse_x;
_vars[VAR_VIRT_MOUSE_Y] = _virtual_mouse_y;
_vars[VAR_MOUSE_X] = mouse.x;
_vars[VAR_MOUSE_Y] = mouse.y;
_vars[VAR_DEBUGMODE] = _debugMode;
decreaseScriptDelay(tmr); if (_gameId==GID_MONKEY)
_vars[VAR_MI1_TIMER]+=40;
_talkDelay -= tmr; if (_saveLoadFlag) {
if (_talkDelay<0) _talkDelay=0; if (_saveLoadFlag==1) {
saveState(_saveLoadSlot, _saveLoadCompatible);
processKbd(); if (_saveLoadCompatible)
_vars[VAR_GAME_LOADED] = 201;
/* XXX: memory low check skipped */ } else {
_vars[VAR_CAMERA_CUR_POS] = camera._curPos; loadState(_saveLoadSlot, _saveLoadCompatible);
_vars[VAR_HAVE_MSG] = _haveMsg; if (_saveLoadCompatible) {
_vars[VAR_VIRT_MOUSE_X] = _virtual_mouse_x; _vars[VAR_GAME_LOADED] = 203;
_vars[VAR_VIRT_MOUSE_Y] = _virtual_mouse_y;
_vars[VAR_MOUSE_X] = mouse.x;
_vars[VAR_MOUSE_Y] = mouse.y;
_vars[VAR_DEBUGMODE] = _debugMode;
if (_gameId==GID_MONKEY)
_vars[VAR_MI1_TIMER]+=40;
if (_saveLoadFlag) {
char buf[256];
sprintf(buf, "%s.%c%.2d", _exe_name, _saveLoadCompatible ? 'c': 's', _saveLoadSlot);
if (_saveLoadFlag==1) {
saveState(buf);
if (_saveLoadCompatible)
_vars[VAR_GAME_LOADED] = 201;
} else {
loadState(buf);
if (_saveLoadCompatible) {
_vars[VAR_GAME_LOADED] = 203;
}
} }
_saveLoadFlag = 0;
} }
_saveLoadFlag = 0;
}
if (_completeScreenRedraw) { if (_completeScreenRedraw) {
_completeScreenRedraw = 0; int i;
gdi.clearUpperMask(); Actor *a;
charset._hasMask = false; _completeScreenRedraw = false;
redrawVerbs(); gdi.clearUpperMask();
_fullRedraw = 1; charset._hasMask = false;
for (i=0,a=getFirstActor(); i<13; i++,a++) redrawVerbs();
a->needRedraw = 1; _fullRedraw = true;
} for (i=0,a=getFirstActor(); i<13; i++,a++)
a->needRedraw = 1;
}
runAllScripts(); runAllScripts();
checkExecVerbs(); checkExecVerbs();
checkAndRunVar33(); checkAndRunVar33();
if (_currentRoom==0) {
gdi._unk4 = 0;
CHARSET_1();
unkVirtScreen2();
processSoundQues();
camera._lastPos = camera._curPos;
continue;
}
if (_currentRoom==0) {
gdi._cursorActive = 0;
CHARSET_1();
drawDirtyScreenParts();
processSoundQues();
camera._lastPos = camera._curPos;
} else {
walkActors(); walkActors();
moveCamera(); moveCamera();
fixObjectFlags(); fixObjectFlags();
@ -344,28 +321,47 @@ void Scumm::scummMain(int argc, char **argv) {
clear_fullRedraw(); clear_fullRedraw();
cyclePalette(); cyclePalette();
palManipulate(); palManipulate();
if (_doEffect) { if (_doEffect) {
_doEffect = false; _doEffect = false;
screenEffect(_newEffect); screenEffect(_newEffect);
clearClickedStatus(); clearClickedStatus();
} }
if (_cursorState > 0) { if (_cursorState > 0) {
verbMouseOver(checkMouseOver(mouse.x, mouse.y)); verbMouseOver(checkMouseOver(mouse.x, mouse.y));
} }
gdi._unk4 = _cursorState > 0; gdi._cursorActive = _cursorState > 0;
unkVirtScreen2(); drawDirtyScreenParts();
if (_majorScummVersion==5) if (_majorScummVersion==5)
playActorSounds(); playActorSounds();
processSoundQues(); processSoundQues();
camera._lastPos = camera._curPos; camera._lastPos = camera._curPos;
}
if (!(++_expire_counter)) {
increaseResourceCounter();
}
_vars[VAR_TIMER] = 0;
return _vars[VAR_TIMER_NEXT];
}
#if 0
void Scumm::scummMain(int argc, char **argv) {
do {
updateScreen(this);
} while (1); } while (1);
} }
#endif
void Scumm::parseCommandLine(int argc, char **argv) { void Scumm::parseCommandLine(int argc, char **argv) {
int i; int i;
@ -789,19 +785,10 @@ void Scumm::processKbd() {
} }
if (_lastKeyHit==_vars[VAR_CUTSCENEEXIT_KEY]) { if (_lastKeyHit==_vars[VAR_CUTSCENEEXIT_KEY]) {
uint32 offs = vm.cutScenePtr[vm.cutSceneStackPointer]; exitCutscene();
if (offs) { } else if (_lastKeyHit==_vars[VAR_SAVELOADDIALOG_KEY]) {
ScriptSlot *ss = &vm.slot[vm.cutSceneScript[vm.cutSceneStackPointer]]; ((Gui*)_gui)->saveLoadDialog();
ss->offs = offs; } else if (_lastKeyHit==_vars[VAR_TALKSTOP_KEY]) {
ss->status = 2;
ss->freezeCount = 0;
ss->cutsceneOverride--;
_vars[VAR_OVERRIDE] = 1;
vm.cutScenePtr[vm.cutSceneStackPointer] = 0;
}
}
if (_lastKeyHit==_vars[VAR_TALKSTOP_KEY]) {
_talkDelay = 0; _talkDelay = 0;
return; return;
} }

View file

@ -66,7 +66,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0 # PROP Ignore_Export_Lib 0
# PROP Target_Dir "" # PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "DUMP_SCRIPTS" /Yu"stdafx.h" /FD /GZ /c # ADD CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
# SUBTRACT CPP /Fr # SUBTRACT CPP /Fr
# ADD BASE RSC /l 0x41d /d "_DEBUG" # ADD BASE RSC /l 0x41d /d "_DEBUG"
# ADD RSC /l 0x41d /d "_DEBUG" # ADD RSC /l 0x41d /d "_DEBUG"
@ -153,6 +153,10 @@ SOURCE=.\gfx.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\gui.cpp
# End Source File
# Begin Source File
SOURCE=.\object.cpp SOURCE=.\object.cpp
!IF "$(CFG)" == "scummvm - Win32 Release" !IF "$(CFG)" == "scummvm - Win32 Release"
@ -319,6 +323,10 @@ SOURCE=.\verbs.cpp
# PROP Default_Filter "h;hpp;hxx;hm;inl" # PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File # Begin Source File
SOURCE=.\gui.h
# End Source File
# Begin Source File
SOURCE=.\scumm.h SOURCE=.\scumm.h
# End Source File # End Source File
# Begin Source File # Begin Source File

122
sdl.cpp
View file

@ -23,6 +23,7 @@
#include "stdafx.h" #include "stdafx.h"
#include "scumm.h" #include "scumm.h"
#include "gui.h"
#if defined(USE_IMUSE) #if defined(USE_IMUSE)
#include "sound.h" #include "sound.h"
@ -32,6 +33,7 @@
Scumm scumm; Scumm scumm;
ScummDebugger debugger; ScummDebugger debugger;
Gui gui;
#if defined(USE_IMUSE) #if defined(USE_IMUSE)
SoundEngine sound; SoundEngine sound;
@ -60,6 +62,16 @@ void updatePalette(Scumm *s) {
s->_palDirtyMin = 0x3E8; s->_palDirtyMin = 0x3E8;
} }
int mapKey(int key, byte mod) {
if (key>=SDLK_F1 && key<=SDLK_F9) {
return key - SDLK_F1 + 315;
} else if (key>='a' && key<='z' && mod&KMOD_SHIFT) {
key&=~0x20;
} else if (key>=SDLK_NUMLOCK && key<=SDLK_EURO)
return 0;
return key;
}
void waitForTimer(Scumm *s) { void waitForTimer(Scumm *s) {
SDL_Event event; SDL_Event event;
byte dontPause = true; byte dontPause = true;
@ -68,18 +80,19 @@ void waitForTimer(Scumm *s) {
while (SDL_PollEvent(&event)) { while (SDL_PollEvent(&event)) {
switch(event.type) { switch(event.type) {
case SDL_KEYDOWN: case SDL_KEYDOWN:
s->_keyPressed = event.key.keysym.sym; s->_keyPressed = mapKey(event.key.keysym.sym, event.key.keysym.mod);
if (event.key.keysym.sym >= '0' && event.key.keysym.sym<='9') { if (event.key.keysym.sym >= '0' && event.key.keysym.sym<='9') {
s->_saveLoadSlot = event.key.keysym.sym - '0'; s->_saveLoadSlot = event.key.keysym.sym - '0';
if (event.key.keysym.mod&KMOD_SHIFT) if (event.key.keysym.mod&KMOD_SHIFT) {
sprintf(s->_saveLoadName, "Quicksave %d", s->_saveLoadSlot);
s->_saveLoadFlag = 1; s->_saveLoadFlag = 1;
else if (event.key.keysym.mod&KMOD_CTRL) } else if (event.key.keysym.mod&KMOD_CTRL)
s->_saveLoadFlag = 2; s->_saveLoadFlag = 2;
s->_saveLoadCompatible = false; s->_saveLoadCompatible = false;
} }
if (event.key.keysym.sym=='z' && event.key.keysym.mod&KMOD_CTRL) { if (event.key.keysym.sym=='z' && event.key.keysym.mod&KMOD_CTRL) {
exit(1); exit(1);
} }
if (event.key.keysym.sym=='f' && event.key.keysym.mod&KMOD_CTRL) { if (event.key.keysym.sym=='f' && event.key.keysym.mod&KMOD_CTRL) {
s->_fastMode ^= 1; s->_fastMode ^= 1;
} }
@ -135,7 +148,6 @@ void waitForTimer(Scumm *s) {
SDL_Delay(dontPause ? 10 : 100); SDL_Delay(dontPause ? 10 : 100);
} while (!dontPause); } while (!dontPause);
s->_scummTimer+=3;
} }
#define MAX_DIRTY_RECTS 40 #define MAX_DIRTY_RECTS 40
@ -225,7 +237,6 @@ void updateScreen(Scumm *s) {
if (s->_fastMode&2) if (s->_fastMode&2)
return; return;
if (hide_mouse) { if (hide_mouse) {
hide_mouse = false; hide_mouse = false;
s->drawMouse(); s->drawMouse();
@ -466,37 +477,58 @@ void drawMouse(Scumm *s, int xdraw, int ydraw, int color, byte *mask, bool visib
#define BUFFER_SIZE (8192) #define BUFFER_SIZE (8192)
#define BITS_PER_SAMPLE 16 #define BITS_PER_SAMPLE 16
static void *_sfx_sound; struct MixerChannel {
static uint32 _sfx_pos; void *_sfx_sound;
static uint32 _sfx_size; uint32 _sfx_pos;
uint32 _sfx_size;
uint32 _sfx_fp_speed;
uint32 _sfx_fp_pos;
void mix(int16 *data, uint32 len);
void clear();
};
#define NUM_MIXER 4
static MixerChannel mixer_channel[NUM_MIXER];
MixerChannel *find_channel() {
int i;
MixerChannel *mc = mixer_channel;
for(i=0; i<NUM_MIXER; i++,mc++) {
if (!mc->_sfx_sound)
return mc;
}
return mc;
}
static uint32 _sfx_fp_speed;
static uint32 _sfx_fp_pos;
bool isSfxFinished() { bool isSfxFinished() {
return _sfx_size == 0; int i;
for(i=0; i<NUM_MIXER; i++)
if (mixer_channel[i]._sfx_sound)
return false;
return true;
} }
void playSfxSound(void *sound, uint32 size, uint rate) { void playSfxSound(void *sound, uint32 size, uint rate) {
if (_sfx_sound) { MixerChannel *mc = find_channel();
free(_sfx_sound);
} mc->_sfx_sound = sound;
_sfx_sound = sound; mc->_sfx_pos = 0;
_sfx_pos = 0; mc->_sfx_fp_speed = (1<<16) * rate / 22050;
_sfx_fp_speed = (1<<16) * rate / 22050; mc->_sfx_fp_pos = 0;
_sfx_fp_pos = 0;
// debug(1, "size=%d, rate=%d", size, rate);
while (size&0xFFFF0000) size>>=1, rate>>=1; while (size&0xFFFF0000) size>>=1, rate>>=1;
_sfx_size = size * 22050 / rate; mc->_sfx_size = size * 22050 / rate;
} }
void mix_sound(int16 *data, uint32 len) { void MixerChannel::mix(int16 *data, uint32 len) {
int8 *s; int8 *s;
int i; int i;
uint32 fp_pos, fp_speed; uint32 fp_pos, fp_speed;
if (!_sfx_size) if (!_sfx_sound)
return; return;
if (len > _sfx_size) if (len > _sfx_size)
len = _sfx_size; len = _sfx_size;
@ -516,15 +548,28 @@ void mix_sound(int16 *data, uint32 len) {
_sfx_pos = s - (int8*)_sfx_sound; _sfx_pos = s - (int8*)_sfx_sound;
_sfx_fp_speed = fp_speed; _sfx_fp_speed = fp_speed;
_sfx_fp_pos = fp_pos; _sfx_fp_pos = fp_pos;
if (!_sfx_size)
clear();
}
void MixerChannel::clear() {
free(_sfx_sound);
_sfx_sound = NULL;
} }
void fill_sound(void *userdata, Uint8 *stream, int len) { void fill_sound(void *userdata, Uint8 *stream, int len) {
int i;
#if defined(USE_IMUSE) #if defined(USE_IMUSE)
sound.generate_samples((int16*)stream, len>>1); sound.generate_samples((int16*)stream, len>>1);
#else #else
memset(stream, 0, len); memset(stream, 0, len);
#endif #endif
mix_sound((int16*)stream, len>>1);
for(i=NUM_MIXER-1; i>=0;i--) {
mixer_channel[i].mix((int16*)stream, len>>1);
}
} }
void initGraphics(Scumm *s, bool fullScreen) { void initGraphics(Scumm *s, bool fullScreen) {
@ -574,14 +619,39 @@ void initGraphics(Scumm *s, bool fullScreen) {
#undef main #undef main
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
scumm._videoMode = 0x13; int delta,tmp;
#if defined(USE_IMUSE) #if defined(USE_IMUSE)
sound.initialize(NULL); sound.initialize(NULL);
scumm._soundDriver = &sound; scumm._soundDriver = &sound;
#endif #endif
scumm._gui = &gui;
scumm.scummMain(argc, argv); scumm.scummMain(argc, argv);
gui.init(&scumm);
delta = 0;
do {
updateScreen(&scumm);
if (gui._active) {
gui.loop();
tmp = 5;
} else {
tmp = delta = scumm.scummLoop(delta);
tmp += tmp>>1;
if (scumm._fastMode)
tmp=1;
}
while(tmp>0) {
waitForTimer(&scumm);
tmp--;
}
} while(1);
return 0; return 0;
} }

View file

@ -759,7 +759,6 @@ void CharsetRenderer::printChar(int chr) {
_top -= _offsY; _top -= _offsY;
} }
void CharsetRenderer::drawBits() { void CharsetRenderer::drawBits() {
bool usemask; bool usemask;
byte *dst, *mask,maskmask; byte *dst, *mask,maskmask;

View file

@ -15,56 +15,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* *
* Change Log: * $Header$
* $Log$
* Revision 1.13 2001/11/06 21:29:23 strigeus
* fix in save game loader,
* sizeof(an element) * number of elements instead of sizeof(a pointer) fixed it,
* buffer out of bounds read fixed in Scumm::isMaskActiveAt
*
* Revision 1.12 2001/11/06 20:00:47 strigeus
* full screen flag,
* better mouse cursors,
* removed change log from individual files
*
* Revision 1.11 2001/11/06 07:47:00 strigeus
* fixed integer overflow for large sounds
*
* Revision 1.10 2001/11/05 20:44:34 strigeus
* speech support
*
* Revision 1.9 2001/11/05 19:21:49 strigeus
* bug fixes,
* speech in dott
*
* Revision 1.8 2001/10/26 17:34:50 strigeus
* bug fixes, code cleanup
*
* Revision 1.7 2001/10/23 19:51:50 strigeus
* recompile not needed when switching games
* debugger skeleton implemented
*
* Revision 1.6 2001/10/16 20:31:27 strigeus
* misc fixes
*
* Revision 1.5 2001/10/16 10:01:48 strigeus
* preliminary DOTT support
*
* Revision 1.4 2001/10/12 07:24:06 strigeus
* fast mode support
*
* Revision 1.3 2001/10/10 10:02:33 strigeus
* alternative mouse cursor
* basic save&load
*
* Revision 1.2 2001/10/09 19:02:28 strigeus
* command line parameter support
*
* Revision 1.1.1.1 2001/10/09 14:30:13 strigeus
*
* initial revision
*
*
*/ */
#if USE_DIRECTX #if USE_DIRECTX
@ -85,6 +36,12 @@
#include "sound.h" #include "sound.h"
#endif #endif
#include "gui.h"
#if !defined(ALLOW_GDI)
#error The GDI driver is not as complete as the SDL driver. You need to define ALLOW_GDI to use this driver.
#endif
#define SRC_WIDTH 320 #define SRC_WIDTH 320
#define SRC_HEIGHT 200 #define SRC_HEIGHT 200
#define SRC_PITCH (320) #define SRC_PITCH (320)
@ -177,6 +134,7 @@ void Error(const char *msg) {
int sel; int sel;
Scumm scumm; Scumm scumm;
ScummDebugger debugger; ScummDebugger debugger;
Gui gui;
#if defined(USE_IMUSE) #if defined(USE_IMUSE)
SoundEngine sound; SoundEngine sound;
@ -187,7 +145,6 @@ byte veryFastMode;
void modifyslot(int sel, int what); void modifyslot(int sel, int what);
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
WndMan *wm = (WndMan*)GetWindowLong(hWnd, GWL_USERDATA); WndMan *wm = (WndMan*)GetWindowLong(hWnd, GWL_USERDATA);
@ -207,29 +164,31 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM l
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);
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 (wParam=='F') { if (GetAsyncKeyState(VK_CONTROL)<0) {
wm->_scumm->_fastMode ^= 1; if (wParam=='F') {
} 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') {
wm->_scumm->resourceStats();
}
} }
if (wParam=='S') {
wm->_scumm->resourceStats();
}
break; break;
case WM_MOUSEMOVE: case WM_MOUSEMOVE:
@ -840,14 +799,6 @@ void outputdisplay2(Scumm *s, int disp) {
wm->_vgabuf = old; wm->_vgabuf = old;
} }
#if 0
void outputdisplay(Scumm *s) {
s->drawMouse();
wm->writeToScreen();
}
#endif
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;
SDL_Rect *r; SDL_Rect *r;
@ -930,9 +881,8 @@ void updateScreen(Scumm *s) {
void waitForTimer(Scumm *s) { void waitForTimer(Scumm *s) {
if (!veryFastMode) { if (!veryFastMode) {
Sleep(5); Sleep(10);
} }
s->_scummTimer+=2;
wm->handleMessage(); wm->handleMessage();
} }
@ -1007,8 +957,8 @@ DWORD _stdcall WndMan::sound_thread(WndMan *wm) {
#undef main #undef main
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
scumm._videoMode = 0x13; int delta;
int tmp;
wm->init(); wm->init();
wm->sound_init(); wm->sound_init();
@ -1020,7 +970,30 @@ int main(int argc, char* argv[]) {
scumm._soundDriver = &sound; scumm._soundDriver = &sound;
#endif #endif
scumm._gui = &gui;
scumm.scummMain(argc, argv); scumm.scummMain(argc, argv);
gui.init(&scumm);
delta = 0;
do {
updateScreen(&scumm);
if (gui._active) {
gui.loop();
tmp = 5;
} else {
tmp = delta = scumm.scummLoop(delta);
tmp += tmp>>1;
if (scumm._fastMode)
tmp=1;
}
while(tmp>0) {
waitForTimer(&scumm);
tmp--;
}
} while(1);
return 0; return 0;
} }