From 7af3cd565c2c62d4733b2272a841e0ead49988cd Mon Sep 17 00:00:00 2001 From: Bertrand Augereau Date: Sun, 26 Jun 2011 15:17:19 +0200 Subject: DREAMWEB: C++-isation of a part of the sprite subsystem --- engines/dreamweb/dreamgen.cpp | 173 ------------------------------------------ engines/dreamweb/dreamgen.h | 22 ++---- engines/dreamweb/stubs.cpp | 170 ++++++++++++++++++++++++++++++++++++++++- engines/dreamweb/stubs.h | 10 +-- 4 files changed, 180 insertions(+), 195 deletions(-) (limited to 'engines/dreamweb') diff --git a/engines/dreamweb/dreamgen.cpp b/engines/dreamweb/dreamgen.cpp index 5b057686e9..90cffed8f4 100644 --- a/engines/dreamweb/dreamgen.cpp +++ b/engines/dreamweb/dreamgen.cpp @@ -2170,35 +2170,6 @@ forcenext: _cmp(al, al); } -void DreamGenContext::clearsprites() { - STACK_CHECK; - es = data.word(kBuffers); - di = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768); - al = 255; - cx = (32)*16; - _stosb(cx, true); -} - -void DreamGenContext::makesprite() { - STACK_CHECK; - es = data.word(kBuffers); - bx = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768); -_tmp17: - _cmp(es.byte(bx+15), 255); - if (flags.z()) - goto _tmp17a; - _add(bx, (32)); - goto _tmp17; -_tmp17a: - es.word(bx) = cx; - es.word(bx+10) = si; - es.word(bx+6) = dx; - es.word(bx+8) = di; - es.word(bx+2) = 0x0ffff; - es.byte(bx+15) = 0; - es.byte(bx+18) = 0; -} - void DreamGenContext::delsprite() { STACK_CHECK; di = bx; @@ -2207,117 +2178,6 @@ void DreamGenContext::delsprite() { _stosb(cx, true); } -void DreamGenContext::spriteupdate() { - STACK_CHECK; - es = data.word(kBuffers); - bx = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768); - al = data.byte(kRyanon); - es.byte(bx+31) = al; - es = data.word(kBuffers); - bx = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768); - cx = 16; -_tmp18: - push(cx); - push(bx); - ax = es.word(bx); - _cmp(ax, 0x0ffff); - if (flags.z()) - goto _tmp18a; - push(es); - push(ds); - cx = es.word(bx+2); - es.word(bx+24) = cx; - __dispatch_call(ax); - ds = pop(); - es = pop(); -_tmp18a: - bx = pop(); - cx = pop(); - _cmp(data.byte(kNowinnewroom), 1); - if (flags.z()) - return /* ($18b) */; - _add(bx, (32)); - if (--cx) - goto _tmp18; -} - -void DreamGenContext::printsprites() { - STACK_CHECK; - es = data.word(kBuffers); - cx = 0; -priorityloop: - push(cx); - data.byte(kPriority) = cl; - bx = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768); - cx = 16; -prtspriteloop: - push(cx); - push(bx); - ax = es.word(bx); - _cmp(ax, 0x0ffff); - if (flags.z()) - goto skipsprite; - al = data.byte(kPriority); - _cmp(al, es.byte(bx+23)); - if (!flags.z()) - goto skipsprite; - _cmp(es.byte(bx+31), 1); - if (flags.z()) - goto skipsprite; - printasprite(); -skipsprite: - bx = pop(); - cx = pop(); - _add(bx, (32)); - if (--cx) - goto prtspriteloop; - cx = pop(); - _inc(cx); - _cmp(cx, 7); - if (!flags.z()) - goto priorityloop; -} - -void DreamGenContext::printasprite() { - STACK_CHECK; - push(es); - push(bx); - si = bx; - ds = es.word(si+6); - al = es.byte(si+11); - ah = 0; - _cmp(al, 220); - if (flags.c()) - goto notnegative1; - ah = 255; -notnegative1: - bx = ax; - _add(bx, data.word(kMapady)); - al = es.byte(si+10); - ah = 0; - _cmp(al, 220); - if (flags.c()) - goto notnegative2; - ah = 255; -notnegative2: - di = ax; - _add(di, data.word(kMapadx)); - al = es.byte(si+15); - ah = 0; - _cmp(es.byte(si+30), 0); - if (flags.z()) - goto steadyframe; - ah = 8; -steadyframe: - _cmp(data.byte(kPriority), 6); - if (!flags.z()) - goto notquickp; -notquickp: - showframe(); - bx = pop(); - es = pop(); -} - void DreamGenContext::checkone() { STACK_CHECK; push(cx); @@ -8501,33 +8361,6 @@ _tmp28a: goto _tmp28; } -void DreamGenContext::eraseoldobs() { - STACK_CHECK; - _cmp(data.byte(kNewobs), 0); - if (flags.z()) - return /* (donterase) */; - es = data.word(kBuffers); - bx = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768); - cx = 16; -oberase: - push(cx); - push(bx); - ax = es.word(bx+20); - _cmp(ax, 0x0ffff); - if (flags.z()) - goto notthisob; - di = bx; - al = 255; - cx = (32); - _stosb(cx, true); -notthisob: - bx = pop(); - cx = pop(); - _add(bx, (32)); - if (--cx) - goto oberase; -} - void DreamGenContext::showallobs() { STACK_CHECK; es = data.word(kBuffers); @@ -22131,12 +21964,7 @@ void DreamGenContext::__dispatch_call(uint16 addr) { case addr_addtopeoplelist: addtopeoplelist(); break; case addr_showgamereel: showgamereel(); break; case addr_checkspeed: checkspeed(); break; - case addr_clearsprites: clearsprites(); break; - case addr_makesprite: makesprite(); break; case addr_delsprite: delsprite(); break; - case addr_spriteupdate: spriteupdate(); break; - case addr_printsprites: printsprites(); break; - case addr_printasprite: printasprite(); break; case addr_checkone: checkone(); break; case addr_findsource: findsource(); break; case addr_initman: initman(); break; @@ -22323,7 +22151,6 @@ void DreamGenContext::__dispatch_call(uint16 addr) { case addr_addalong: addalong(); break; case addr_addlength: addlength(); break; case addr_drawflags: drawflags(); break; - case addr_eraseoldobs: eraseoldobs(); break; case addr_showallobs: showallobs(); break; case addr_makebackob: makebackob(); break; case addr_showallfree: showallfree(); break; diff --git a/engines/dreamweb/dreamgen.h b/engines/dreamweb/dreamgen.h index 857d912ad0..dc9aebe4c0 100644 --- a/engines/dreamweb/dreamgen.h +++ b/engines/dreamweb/dreamgen.h @@ -490,7 +490,6 @@ public: static const uint16 addr_showallfree = 0xc44c; static const uint16 addr_makebackob = 0xc448; static const uint16 addr_showallobs = 0xc444; - static const uint16 addr_eraseoldobs = 0xc440; static const uint16 addr_drawflags = 0xc43c; static const uint16 addr_addlength = 0xc438; static const uint16 addr_addalong = 0xc434; @@ -677,12 +676,7 @@ public: static const uint16 addr_initman = 0xc134; static const uint16 addr_findsource = 0xc130; static const uint16 addr_checkone = 0xc12c; - static const uint16 addr_printasprite = 0xc128; - static const uint16 addr_printsprites = 0xc124; - static const uint16 addr_spriteupdate = 0xc120; static const uint16 addr_delsprite = 0xc11c; - static const uint16 addr_makesprite = 0xc118; - static const uint16 addr_clearsprites = 0xc114; static const uint16 addr_checkspeed = 0xc110; static const uint16 addr_showgamereel = 0xc10c; static const uint16 addr_addtopeoplelist = 0xc108; @@ -892,7 +886,7 @@ public: const static uint16 kSavex = 178; const static uint16 kSavey = 179; const static uint16 kCurrentob = 180; - const static uint16 kPriority = 181; + const static uint16 kPrioritydep = 181; const static uint16 kDestpos = 182; const static uint16 kReallocation = 183; const static uint16 kRoomnum = 184; @@ -1328,7 +1322,6 @@ public: void drawitall(); void clearstartpal(); void femalefan(); - void greyscalesum(); void showgamereel(); void identifyob(); void trysoundalloc(); @@ -1464,6 +1457,7 @@ public: //void convertkey(); void outofopen(); void dealwithspecial(); + //void eraseoldobs(); void dircom(); void liftsprite(); void dumpkeypad(); @@ -1526,7 +1520,7 @@ public: void hotelbell(); void loadspeech(); //void cls(); - void printsprites(); + //void printsprites(); void dumptimedtext(); void showallobs(); void getnumber(); @@ -1558,7 +1552,7 @@ public: void usekey(); void locklighton(); void useladderb(); - void spriteupdate(); + //void spriteupdate(); void usetempcharset(); void discops(); void printdirect(); @@ -1873,7 +1867,7 @@ public: void finalframe(); void plotreel(); void swapwithopen(); - void makesprite(); + //void makesprite(); void dreamweb(); void droperror(); void openfilenocheck(); @@ -1916,12 +1910,12 @@ public: void gettingshot(); void settopleft(); void searchforstring(); - void clearsprites(); + //void clearsprites(); void obpicture(); void selectopenob(); void widedoor(); void security(); - void printasprite(); + //void printasprite(); void buttonfive(); void soundonreels(); void usegun(); @@ -1949,7 +1943,7 @@ public: //void width160(); void incryanpage(); void dodoor(); - void eraseoldobs(); + void greyscalesum(); void buttoneight(); void opensarters(); void findexobject(); diff --git a/engines/dreamweb/stubs.cpp b/engines/dreamweb/stubs.cpp index 2d3c819561..5123655795 100644 --- a/engines/dreamweb/stubs.cpp +++ b/engines/dreamweb/stubs.cpp @@ -532,11 +532,16 @@ void DreamGenContext::frameoutv() { uint16 pitch = dx; uint16 width = cx & 0xff; uint16 height = cx >> 8; - uint16 stride = pitch - width; const uint8* src = ds.ptr(si, width * height); - uint8* base = es.ptr(di, stride * height); - uint8* dst = base + pitch * bx; + uint8* dst = es.ptr(di, pitch * height); + + frameoutv(dst, src, pitch, width, height); +} + +void DreamGenContext::frameoutv(uint8* dst, const uint8* src, uint16 pitch, uint16 width, uint16 height) { + uint16 stride = pitch - width; + dst += pitch * bx; // NB: Original code assumes non-zero width and height, "for" are unneeded, do-while would suffice but would be less readable for (uint16 y = 0; y < height; ++y) { @@ -550,6 +555,165 @@ void DreamGenContext::frameoutv() { } } +Sprite* DreamGenContext::spritetable() { + push(es); + push(bx); + + es = data.word(kBuffers); + bx = kSpritetable; + Sprite *sprite = (Sprite*)es.ptr(bx, 16*sizeof(Sprite)); + + bx = pop(); + es = pop(); + + return sprite; +} + +void DreamGenContext::printsprites() { + for (size_t priority = 0; priority < 7; ++priority) { + Sprite *sprites = spritetable(); + for (size_t j = 0; j < 16; ++j) { + const Sprite &sprite = sprites[j]; + if (READ_LE_UINT16(&sprite.updateCallback) == 0x0ffff) + continue; + if (priority != sprite.priority) + continue; + if (sprite.hidden == 1) + continue; + printasprite(&sprite); + } + } +} + +void DreamGenContext::printasprite(const Sprite* sprite) { + push(es); + push(bx); + ds = READ_LE_UINT16(&sprite->w6); + ax = sprite->y; + if (al >= 220) { + bx = data.word(kMapady) - (256 - al); + } else { + bx = ax + data.word(kMapady); + } + + ax = sprite->x; + if (al >= 220) { + di = data.word(kMapadx) - (256 - al); + } else { + di = ax + data.word(kMapadx); + } + + ax = sprite->b15; + if (sprite->type != 0) + ah = 8; + showframe(); // NB: Params in ax, bx, di, ds:dx + + bx = pop(); + es = pop(); +} + +void DreamGenContext::eraseoldobs() { + if (data.byte(kNewobs) == 0) + return; + + Sprite *sprites = spritetable(); + for (size_t i=0; i<16; ++i) { + Sprite &sprite = sprites[i]; + if (READ_LE_UINT16(&sprite.obj_data) != 0xffff) { + memset(&sprite, 0xff, sizeof(Sprite)); + } + } +} + +void DreamGenContext::clearsprites() { + memset(spritetable(), 0xff, sizeof(Sprite)*16); +} + +Sprite* DreamGenContext::makesprite(uint8 x, uint8 y, uint16 updateCallback, uint16 somethingInDx, uint16 somethingInDi) { + Sprite *sprite = spritetable(); + while (sprite->b15 != 0xff) { // NB: No boundchecking in the original code either + ++sprite; + } + + WRITE_LE_UINT16(&sprite->updateCallback, updateCallback); + sprite->x = x; + sprite->y = y; + WRITE_LE_UINT16(&sprite->w6, somethingInDx); + WRITE_LE_UINT16(&sprite->w8, somethingInDi); + sprite->w2 = 0xffff; + sprite->b15 = 0; + sprite->b18 = 0; + return sprite; +} + +void DreamGenContext::makesprite() { // NB: returns new sprite in es:bx + Sprite *sprite = makesprite(si & 0xff, si >> 8, cx, dx, di); + + // Recover es:bx from sprite + es = data.word(kBuffers); + bx = kSpritetable; + Sprite *sprites = (Sprite*)es.ptr(bx, sizeof(Sprite)*16); + bx += sizeof(Sprite)*(sprite-sprites); + // +} + +void DreamGenContext::spriteupdate() { + Sprite *sprites = spritetable(); + sprites[0].hidden = data.byte(kRyanon); + + Sprite *sprite = sprites; + for (size_t i=0; i<16; ++i) { + uint16 updateCallback = READ_LE_UINT16(&sprite->updateCallback); + if (updateCallback != 0xffff) { + sprite->w24 = sprite->w2; + if (updateCallback == addr_mainman) // NB : Let's consider the callback as an enum while more code is not ported to C++ + mainmanCPP(sprite); + else { + assert(updateCallback == addr_backobject); + backobjectCPP(sprite); + } + } + + if (data.byte(kNowinnewroom) == 1) + break; + ++sprite; + } +} + +void DreamGenContext::mainmanCPP(Sprite* sprite) { + push(es); + push(ds); + + // Recover es:bx from sprite + es = data.word(kBuffers); + bx = kSpritetable; + Sprite *sprites = (Sprite*)es.ptr(bx, sizeof(Sprite)*16); + bx += 32*(sprite-sprites); + // + + mainman(); + + ds = pop(); + es = pop(); +} + +void DreamGenContext::backobjectCPP(Sprite* sprite) { + push(es); + push(ds); + + // Recover es:bx from sprite + es = data.word(kBuffers); + bx = kSpritetable; + Sprite *sprites = (Sprite*)es.ptr(bx, sizeof(Sprite)*16); + bx += 32*(sprite-sprites); + // + + backobject(); + + ds = pop(); + es = pop(); +} + void DreamGenContext::modifychar() { al = engine->modifyChar(al); } diff --git a/engines/dreamweb/stubs.h b/engines/dreamweb/stubs.h index 8b46989a7f..7f1e3b9f0c 100644 --- a/engines/dreamweb/stubs.h +++ b/engines/dreamweb/stubs.h @@ -5,7 +5,7 @@ void multiget(); void convertkey(); void cls(); - //void printsprites(); + void printsprites(); void quickquit(); void readoneblock(); void printundermon(); @@ -17,11 +17,11 @@ void printasprite(const Sprite* sprite); void width160(); void multiput(); - //void eraseoldobs(); - //void clearsprites(); - //void makesprite(); + void eraseoldobs(); + void clearsprites(); + void makesprite(); Sprite* makesprite(uint8 x, uint8 y, uint16 updateCallback, uint16 somethingInDx, uint16 somethingInDi); - //void spriteupdate(); + void spriteupdate(); void mainmanCPP(Sprite* sprite); void backobjectCPP(Sprite* sprite); void modifychar(); -- cgit v1.2.3