diff options
author | Eugene Sandulenko | 2005-03-14 21:13:35 +0000 |
---|---|---|
committer | Eugene Sandulenko | 2005-03-14 21:13:35 +0000 |
commit | ef57db4105d737a5f97f107aef32aed302fa53d2 (patch) | |
tree | 0143520631dc0de40ea573c71fc509c851bbf5c6 | |
parent | 8776504882864e2e9e558ef999733077c4ab39c8 (diff) | |
download | scummvm-rg350-ef57db4105d737a5f97f107aef32aed302fa53d2.tar.gz scummvm-rg350-ef57db4105d737a5f97f107aef32aed302fa53d2.tar.bz2 scummvm-rg350-ef57db4105d737a5f97f107aef32aed302fa53d2.zip |
First attempt to draw NES sprites. There are these problems:
o Position is not correct
o Colors are wrong
o No animation
o They're not wiped out correctly, maybe because of first problem
svn-id: r17137
-rw-r--r-- | scumm/costume.cpp | 299 | ||||
-rw-r--r-- | scumm/costume.h | 1 | ||||
-rw-r--r-- | scumm/scumm.cpp | 3 | ||||
-rw-r--r-- | scumm/scumm.h | 2 |
4 files changed, 167 insertions, 138 deletions
diff --git a/scumm/costume.cpp b/scumm/costume.cpp index f8946608b8..057b6ae1eb 100644 --- a/scumm/costume.cpp +++ b/scumm/costume.cpp @@ -583,15 +583,8 @@ static const int v1MMNEScostTables[2][6] = { void LoadedCostume::loadNEScostume(void) { const byte *src; int frameset, framenum; - int offset, numSprites, spritesOffset, maxSprites, numAnims; - byte *table, *ptr, *patTable, *spritesDefs, *spritesOffsetTab, *numSpritesTab; - bool flip; - int palette, tile; - byte patData[16 * 256]; - int len; - int i, j; - byte x, y; - int8 x1, y1; + int offset; + byte *table; _format = 0x01; _mirror = 0; @@ -603,7 +596,6 @@ void LoadedCostume::loadNEScostume(void) { src = _baseptr + 4; // Cost(a) offset = src[(frameset * 4 + framenum) * 2]; - numAnims = src[(frameset * 4 + framenum) * 2 + 1]; // Lookup & desc table = _vm->getResourceAddress(rtCostume, v1MMNEScostTables[_vm->_v1MMNESCostumeSet][0]); @@ -614,133 +606,6 @@ void LoadedCostume::loadNEScostume(void) { } else { _numAnim = (READ_LE_UINT16(table + v1MMNESLookup[_id] * 2 + 4) - offset) / 2; } - - // lens - numSpritesTab = _vm->getResourceAddress(rtCostume, v1MMNEScostTables[_vm->_v1MMNESCostumeSet][1]); - - // offs - spritesOffsetTab = _vm->getResourceAddress(rtCostume, v1MMNEScostTables[_vm->_v1MMNESCostumeSet][2]); - - // data - spritesDefs = _vm->getResourceAddress(rtCostume, v1MMNEScostTables[_vm->_v1MMNESCostumeSet][3]); - - // gfx - patTable = _vm->getResourceAddress(rtCostume, v1MMNEScostTables[_vm->_v1MMNESCostumeSet][4]); - - for (int frameNum = 0; frameNum < _numAnim; frameNum++) { - offset = READ_LE_UINT16(table + v1MMNESLookup[_id] * 2 + 2 + frameNum * 2); - numSprites = numSpritesTab[offset + 2] + 1; - spritesOffset = READ_LE_UINT16(spritesOffsetTab + offset * 2 + 2); - - - //printf("spritesOffset: %x", spritesOffset); - ptr = spritesDefs + spritesOffset + 2; - - byte mask; - // decode costumegfx and get data - maxSprites = patTable[3]; - len = READ_LE_UINT16(patTable); - - j = 0; - i = 3; - while (i < len) { - if (patTable[i] > 0x80) { - for (int cnt = (patTable[i++] & ~0x80); cnt > 0; cnt--) - patData[j++] = patTable[i++]; - } else { - for (int cnt = patTable[i++]; cnt > 0; cnt--) - patData[j++] = patTable[i]; - i++; - } - } - /* - printf("extracted len: %d", j); - - for (j = 0; j < 5; j++) { - for (i = 0; i < 16; i++) - printf("%02x ", patData[j * 16 + i]); - printf("\n"); - } - */ - - byte pic[256][256]; - for (i = 0; i < 256; i++) - for(j = 0; j < 256; j++) - pic[i][j] = ' '; - - for (int spr = 0; spr < numSprites; spr++) { - flip = ((*ptr & 0x80) != 0); - - y1 = *ptr++; - y1 |= (int8)0x80; - y1 += (int8)0x80; - y = y1; - - tile = *ptr++; - - x1 = *ptr >> 2; - - if (*ptr & 0x80) - x1 |= (int8)0xc0; - x1 += (int8)0x80; - x = x1; - - palette = *ptr++ & 0x3; - - mask = flip ? 0x01 : 0x80; - -#define SHIFT 0 - - for (i = 0; i < 8; i++) { - byte c = patData[tile * 16 + i]; - for (j = 0; j < 8; j++) { - pic[SHIFT + j + x][SHIFT + i + y] = (c & mask) ? '.' : ' '; - if (flip) - c >>= 1; - else - c <<= 1; - } - } - for (i = 0; i < 8; i++) { - byte c = patData[tile * 16 + i + 8]; - for (j = 0; j < 8; j++) { - if (pic[SHIFT + j + x][SHIFT + i + y] == '.') - pic[SHIFT + j + x][SHIFT + i + y] = (c & mask) ? '#' : '.'; - else - pic[SHIFT + j + x][SHIFT + i + y] = (c & mask) ? '*' : ' '; - if (flip) - c >>= 1; - else - c <<= 1; - } - } - //printf("flip: %d (%d), tile: %x, x: %d, y: %d, pal: %d", flip, (tile % 1) ? flip : !flip, tile, x, y, palette); - } - - int left = 256, top = 256, right = 0, bottom = 0; - - for (i = 0; i < 256; i++) - for(j = 0; j < 256; j++) - if (pic[j][i] != ' ') { - if (left > j) - left = j; - if (right < j) - right = j; - if (top > i) - top = i; - if (bottom < i) - bottom = i; - } - - /* - for (i = top; i <= bottom; i++) { - for(j = left; j <= right; j++) - printf("%c", pic[j][i]); - printf("\n"); - } - */ - } - } void LoadedCostume::loadCostume(int id) { @@ -806,6 +671,126 @@ void LoadedCostume::loadCostume(int id) { _animCmds = _baseptr + READ_LE_UINT16(ptr); } +void CostumeRenderer::drawNESCostume(const Actor *a, int limb) { + const byte *src; + int offset, numSprites, spritesOffset, numAnims; + byte *table, *ptr, *spritesDefs, *spritesOffsetTab, *numSpritesTab; + bool flip; + int palette, tile; + int i, j; + byte x, y; + int8 x1, y1; + const CostumeData &cost = a->_cost; + int frame = cost.frame[limb]; + + src = _loaded._dataOffsets; + + // Cost(a) + offset = src[frame * 2]; + numAnims = src[frame * 2 + 1]; + + // Lookup & desc + table = _vm->getResourceAddress(rtCostume, v1MMNEScostTables[_vm->_v1MMNESCostumeSet][0]); + offset = READ_LE_UINT16(table + v1MMNESLookup[_loaded._id] * 2 + 2); + + // lens + numSpritesTab = _vm->getResourceAddress(rtCostume, v1MMNEScostTables[_vm->_v1MMNESCostumeSet][1]); + + // offs + spritesOffsetTab = _vm->getResourceAddress(rtCostume, v1MMNEScostTables[_vm->_v1MMNESCostumeSet][2]); + + // data + spritesDefs = _vm->getResourceAddress(rtCostume, v1MMNEScostTables[_vm->_v1MMNESCostumeSet][3]); + + int frameNum = 0; + + offset = READ_LE_UINT16(table + v1MMNESLookup[_loaded._id] * 2 + 2 + frameNum * 2); + numSprites = numSpritesTab[offset + 2] + 1; + spritesOffset = READ_LE_UINT16(spritesOffsetTab + offset * 2 + 2); + + ptr = spritesDefs + spritesOffset + 2; + + byte mask; + + byte pic[256][256]; + for (i = 0; i < 256; i++) + for(j = 0; j < 256; j++) + pic[i][j] = 0; + + for (int spr = 0; spr < numSprites; spr++) { + flip = ((*ptr & 0x80) != 0); + + y1 = *ptr++; + y1 |= (int8)0x80; + y1 += (int8)0x80; + y = y1; + + tile = *ptr++; + + x1 = *ptr >> 2; + + if (*ptr & 0x80) + x1 |= (int8)0xc0; + x1 += (int8)0x80; + x = x1; + + palette = *ptr++ & 0x3; + + mask = flip ? 0x01 : 0x80; + +#define SHIFT 0 + + for (i = 0; i < 8; i++) { + byte c = _vm->_v1MMNESCostumeGfx[_vm->_v1MMNESCostumeSet][tile * 16 + i]; + for (j = 0; j < 8; j++) { + pic[SHIFT + j + x][SHIFT + i + y] = (c & mask) ? 1 : 0; + if (flip) + c >>= 1; + else + c <<= 1; + } + } + for (i = 0; i < 8; i++) { + byte c = _vm->_v1MMNESCostumeGfx[_vm->_v1MMNESCostumeSet][tile * 16 + i + 8]; + for (j = 0; j < 8; j++) { + if (pic[SHIFT + j + x][SHIFT + i + y] == 1) + pic[SHIFT + j + x][SHIFT + i + y] = (c & mask) ? 3 : 1; + else + pic[SHIFT + j + x][SHIFT + i + y] = (c & mask) ? 2 : 0; + if (flip) + c >>= 1; + else + c <<= 1; + } + } + } + + int left = 256, top = 256, right = 0, bottom = 0; + + for (i = 0; i < 256; i++) + for(j = 0; j < 256; j++) + if (pic[j][i] != 0) { + if (left > j) + left = j; + if (right < j) + right = j; + if (top > i) + top = i; + if (bottom < i) + bottom = i; + } + + byte *dest = (byte *)_out.pixels + (_actorY + top - 128) * _out.pitch + + _actorX + left - 128; + + for (i = top; i <= bottom; i++) { + for(j = left; j <= right; j++) + if (pic[j][i]) + dest[j - left] = pic[j][i]; + dest += _out.pitch; + } +} + byte CostumeRenderer::drawLimb(const Actor *a, int limb) { int i; int code; @@ -816,6 +801,11 @@ byte CostumeRenderer::drawLimb(const Actor *a, int limb) { if (cost.curpos[limb] == 0xFFFF || cost.stopped & (1 << limb)) return 0; + if (_vm->_features & GF_NES) { + drawNESCostume(a, limb); + return 0; + } + // Determine the position the limb is at i = cost.curpos[limb] & 0x7FFF; @@ -860,6 +850,35 @@ byte CostumeRenderer::drawLimb(const Actor *a, int limb) { } +void ScummEngine::cost_decodeNESCostumeGfx() { + for (int n = 0; n < 2; n++) { + byte *patTable = getResourceAddress(rtCostume, v1MMNEScostTables[n][4]); + int j = 0; + int i = 3; + int maxSprites = 256; //patTable[3]; + int len = READ_LE_UINT16(patTable); + + if (maxSprites == 0) + maxSprites = 256; + + _v1MMNESCostumeGfx[n] = (byte *)calloc(maxSprites * 16, 1); + + while (i < len) { + if (patTable[i] > 0x80) { + for (int cnt = (patTable[i++] & ~0x80); cnt > 0; cnt--) + _v1MMNESCostumeGfx[n][j++] = patTable[i++]; + } else { + for (int cnt = patTable[i++]; cnt > 0; cnt--) + _v1MMNESCostumeGfx[n][j++] = patTable[i]; + i++; + } + } + + // We will not need it anymore + nukeResource(rtCostume, v1MMNEScostTables[n][4]); + } +} + int ScummEngine::cost_frameToAnim(Actor *a, int frame) { return newDirToOldDir(a->getFacing()) + frame * 4; } @@ -881,7 +900,7 @@ void ScummEngine::cost_decodeData(Actor *a, int frame, uint usemask) { } if (_features & GF_NES) { - a->_cost.curpos[0] = 0xFFFF; + a->_cost.curpos[0] = 1; a->_cost.start[0] = 0; a->_cost.frame[0] = frame; return; @@ -997,6 +1016,10 @@ byte LoadedCostume::increaseAnim(Actor *a, int slot) { int i, end; byte code, nc; + if (_vm->_features & GF_NES) { + return 0; + } + if (a->_cost.curpos[slot] == 0xFFFF) return 0; diff --git a/scumm/costume.h b/scumm/costume.h index de1424bff4..1b233e1c81 100644 --- a/scumm/costume.h +++ b/scumm/costume.h @@ -71,6 +71,7 @@ public: protected: byte drawLimb(const Actor *a, int limb); + void drawNESCostume(const Actor *a, int limb); void proc3(Codec1 &v1); void proc3_ami(Codec1 &v1); diff --git a/scumm/scumm.cpp b/scumm/scumm.cpp index e4fceacdd7..716dc415ae 100644 --- a/scumm/scumm.cpp +++ b/scumm/scumm.cpp @@ -1492,6 +1492,9 @@ void ScummEngine::scummInit() { clearDrawObjectQueue(); + if (_features & GF_NES) + cost_decodeNESCostumeGfx(); + for (i = 0; i < 6; i++) { if (_version == 3) { // FIXME - what is this? _string[i]._default.xpos = 0; diff --git a/scumm/scumm.h b/scumm/scumm.h index 34a03aa454..99a7581aeb 100644 --- a/scumm/scumm.h +++ b/scumm/scumm.h @@ -472,6 +472,7 @@ public: BaseCostumeRenderer* _costumeRenderer; int _v1MMNESCostumeSet; + byte *_v1MMNESCostumeGfx[2]; char *_audioNames; int32 _numAudioNames; @@ -838,6 +839,7 @@ public: // Costume class void cost_decodeData(Actor *a, int frame, uint usemask); int cost_frameToAnim(Actor *a, int frame); + void cost_decodeNESCostumeGfx(); // Akos Class struct { |