aboutsummaryrefslogtreecommitdiff
path: root/scumm
diff options
context:
space:
mode:
authorMax Horn2005-03-27 00:23:38 +0000
committerMax Horn2005-03-27 00:23:38 +0000
commit446be21239727bcea559e201b77a48860fd5a34f (patch)
tree940fc942243ad1887ba0825ab5c462322b1f6c94 /scumm
parent49ad27e845c504e626116f92999f2bfb74e7e1e0 (diff)
downloadscummvm-rg350-446be21239727bcea559e201b77a48860fd5a34f.tar.gz
scummvm-rg350-446be21239727bcea559e201b77a48860fd5a34f.tar.bz2
scummvm-rg350-446be21239727bcea559e201b77a48860fd5a34f.zip
Started to overhaul the costume infrastructure a bit, properly separating the NES costume code in the process (sorry if I broke stuff for the NES folks, but I figure it is better to get this done properly now before we have to untangle the mess later)
svn-id: r17257
Diffstat (limited to 'scumm')
-rw-r--r--scumm/actor.cpp12
-rw-r--r--scumm/akos.h8
-rw-r--r--scumm/base-costume.cpp2
-rw-r--r--scumm/base-costume.h12
-rw-r--r--scumm/costume.cpp102
-rw-r--r--scumm/costume.h35
-rw-r--r--scumm/scumm.cpp4
-rw-r--r--scumm/scumm.h5
8 files changed, 126 insertions, 54 deletions
diff --git a/scumm/actor.cpp b/scumm/actor.cpp
index d13f79e51c..ee881d81c7 100644
--- a/scumm/actor.cpp
+++ b/scumm/actor.cpp
@@ -1127,6 +1127,8 @@ void Actor::animateCostume() {
_animProgress++;
if (_animProgress >= _animSpeed) {
_animProgress = 0;
+
+ BaseCostume *cost = 0;
if (_vm->_features & GF_NEW_COSTUMES) {
byte *akos = _vm->getResourceAddress(rtCostume, _costume);
@@ -1135,12 +1137,16 @@ void Actor::animateCostume() {
_needRedraw = true;
}
} else {
- LoadedCostume lc(_vm);
- lc.loadCostume(_costume);
- if (lc.increaseAnims(this)) {
+ if (_vm->_features & GF_NES)
+ cost = new NESCostume(_vm);
+ else
+ cost = new ClassicCostume(_vm);
+ cost->loadCostume(_costume);
+ if (cost->increaseAnims(this)) {
_needRedraw = true;
}
}
+ delete cost;
}
}
diff --git a/scumm/akos.h b/scumm/akos.h
index 90b99b63c2..f359c94e98 100644
--- a/scumm/akos.h
+++ b/scumm/akos.h
@@ -37,6 +37,14 @@ struct CostumeData;
struct AkosHeader;
struct AkosOffset;
+/* TODO:
+class AkosCostume : public BaseCostume {
+public:
+ void loadCostume(int id);
+ byte increaseAnims(Actor *a);
+};
+*/
+
class AkosRenderer : public BaseCostumeRenderer {
protected:
uint16 codec;
diff --git a/scumm/base-costume.cpp b/scumm/base-costume.cpp
index 8c3fe18ba7..b8609aaf49 100644
--- a/scumm/base-costume.cpp
+++ b/scumm/base-costume.cpp
@@ -90,6 +90,8 @@ bool ScummEngine::isCostumeInUse(int cost) const {
void ScummEngine::costumeDecodeData(Actor *a, int frame, uint usemask) {
if (_features & GF_NEW_COSTUMES)
akos_decodeData(a, frame, usemask);
+ else if (_features & GF_NES)
+ NES_cost_decodeData(a, frame, usemask);
else
cost_decodeData(a, frame, usemask);
}
diff --git a/scumm/base-costume.h b/scumm/base-costume.h
index 58e027c5af..04798c54a8 100644
--- a/scumm/base-costume.h
+++ b/scumm/base-costume.h
@@ -46,8 +46,17 @@ class Actor;
class ScummEngine;
struct VirtScreen;
+class BaseCostume {
+public:
+ virtual ~BaseCostume() {}
+
+ virtual void loadCostume(int id) = 0;
+ virtual byte increaseAnims(Actor *a) = 0;
+};
+
+
/**
- * Base class for both CostumeRenderer and AkosRenderer.
+ * Base class for both ClassicCostumeRenderer and AkosRenderer.
*/
class BaseCostumeRenderer {
public:
@@ -119,6 +128,7 @@ public:
_skipLimbs = 0;
_paletteNum = 0;
}
+ virtual ~BaseCostumeRenderer() {}
virtual void setPalette(byte *palette) = 0;
virtual void setFacing(const Actor *a) = 0;
diff --git a/scumm/costume.cpp b/scumm/costume.cpp
index 6acecb356e..2ace1dbdfa 100644
--- a/scumm/costume.cpp
+++ b/scumm/costume.cpp
@@ -74,7 +74,7 @@ const byte cost_scaleTable[256] = {
};
#endif
-byte CostumeRenderer::mainRoutine(int xmoveCur, int ymoveCur) {
+byte ClassicCostumeRenderer::mainRoutine(int xmoveCur, int ymoveCur) {
int i, skip = 0;
byte drawFlag = 1;
bool use_scaling;
@@ -330,7 +330,7 @@ static const int v1MMActorPalatte2[25] = {
dst[p + 1] = palette[pcolor]; \
}
-void CostumeRenderer::procC64(Codec1 &v1, int actor) {
+void ClassicCostumeRenderer::procC64(Codec1 &v1, int actor) {
const byte *mask, *src;
byte *dst;
byte len;
@@ -405,7 +405,7 @@ void CostumeRenderer::procC64(Codec1 &v1, int actor) {
#undef LINE
#undef MASK_AT
-void CostumeRenderer::proc3(Codec1 &v1) {
+void ClassicCostumeRenderer::proc3(Codec1 &v1) {
#ifdef __PALM_OS__
ARM_START(CostumeProc3Type)
ARM_INIT(SCUMM_PROC3)
@@ -501,7 +501,7 @@ void CostumeRenderer::proc3(Codec1 &v1) {
} while (1);
}
-void CostumeRenderer::proc3_ami(Codec1 &v1) {
+void ClassicCostumeRenderer::proc3_ami(Codec1 &v1) {
const byte *mask, *src;
byte *dst;
byte maskbit, len, height, width;
@@ -575,11 +575,14 @@ static const int v1MMNESLookup[25] = {
/**
* costume ID -> v1MMNESLookup[] -> desc -> lens & offs -> data -> Gfx & pal
*/
-void LoadedCostume::loadNEScostume(void) {
+void NESCostume::loadCostume(int id) {
const byte *src;
int frameset, framenum;
int offset;
+ _id = id;
+ _baseptr = _vm->getResourceAddress(rtCostume, id);
+
_format = 0x01;
_mirror = 0;
_dataOffsets = _baseptr + 4;
@@ -600,7 +603,7 @@ void LoadedCostume::loadNEScostume(void) {
}
}
-void LoadedCostume::loadCostume(int id) {
+void ClassicCostume::loadCostume(int id) {
_id = id;
byte *ptr = _vm->getResourceAddress(rtCostume, id);
@@ -615,10 +618,6 @@ void LoadedCostume::loadCostume(int id) {
_baseptr = ptr;
- if (_vm->_features & GF_NES) {
- loadNEScostume();
- return;
- }
_numAnim = ptr[6];
_format = ptr[7] & 0x7F;
_mirror = (ptr[7] & 0x80) != 0;
@@ -663,7 +662,7 @@ void LoadedCostume::loadCostume(int id) {
_animCmds = _baseptr + READ_LE_UINT16(ptr);
}
-void CostumeRenderer::drawNESCostume(const Actor *a, int limb) {
+byte NESCostumeRenderer::drawLimb(const Actor *a, int limb) {
const byte darkpalette[16] = {0x00,0x00,0x2D,0x3D,0x00,0x00,0x2D,0x3D,0x00,0x00,0x2D,0x3D,0x00,0x00,0x2D,0x3D};
const byte *palette;
const byte *src;
@@ -675,6 +674,10 @@ void CostumeRenderer::drawNESCostume(const Actor *a, int limb) {
byte *bgTransBuf = _vm->getMaskBuffer(0, 0, 0);
byte *gfxMaskBuf = _vm->getMaskBuffer(0, 0, 1);
+ // If the specified limb is stopped or not existing, do nothing.
+ if (cost.curpos[limb] == 0xFFFF || cost.stopped & (1 << limb))
+ return 0;
+
if (_vm->VAR(_vm->VAR_CURRENT_LIGHTS) & LIGHTMODE_actor_color)
palette = _vm->_NESPalette[1];
else
@@ -758,9 +761,11 @@ void CostumeRenderer::drawNESCostume(const Actor *a, int limb) {
_draw_bottom = bottom;
_vm->markRectAsDirty(kMainVirtScreen, left, right, top, bottom, _actorID);
+
+ return 0;
}
-byte CostumeRenderer::drawLimb(const Actor *a, int limb) {
+byte ClassicCostumeRenderer::drawLimb(const Actor *a, int limb) {
int i;
int code;
const byte *frameptr;
@@ -770,11 +775,6 @@ 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;
@@ -819,13 +819,43 @@ byte CostumeRenderer::drawLimb(const Actor *a, int limb) {
}
+void NESCostumeRenderer::setPalette(byte *palette) {
+ // TODO
+}
+
+void NESCostumeRenderer::setFacing(const Actor *a) {
+ _mirror = newDirToOldDir(a->getFacing()) != 0 || _loaded._mirror;
+}
+
+void NESCostumeRenderer::setCostume(int costume) {
+ _loaded.loadCostume(costume);
+}
+
+void ScummEngine::NES_cost_decodeData(Actor *a, int frame, uint usemask) {
+ int anim;
+ NESCostume lc(this);
+
+ lc.loadCostume(a->_costume);
+
+ anim = newDirToOldDir(a->getFacing()) + frame * 4;
+
+ if (anim > lc._numAnim) {
+ return;
+ }
+
+ a->_cost.curpos[0] = 0;
+ a->_cost.start[0] = 0;
+ a->_cost.end[0] = lc._baseptr[2 + 8 * frame + 2 * newDirToOldDir(a->getFacing()) + 1];
+ a->_cost.frame[0] = frame;
+}
+
void ScummEngine::cost_decodeData(Actor *a, int frame, uint usemask) {
const byte *r;
uint mask, j;
int i;
byte extra, cmd;
int anim;
- LoadedCostume lc(this);
+ ClassicCostume lc(this);
lc.loadCostume(a->_costume);
@@ -835,14 +865,6 @@ void ScummEngine::cost_decodeData(Actor *a, int frame, uint usemask) {
return;
}
- if (_features & GF_NES) {
- a->_cost.curpos[0] = 0;
- a->_cost.start[0] = 0;
- a->_cost.end[0] = getResourceAddress(rtCostume, a->_costume)[2 + 8 * frame + 2 * newDirToOldDir(a->getFacing()) + 1];
- a->_cost.frame[0] = frame;
- return;
- }
-
r = lc._baseptr + READ_LE_UINT16(lc._dataOffsets + anim * 2);
if (r == lc._baseptr) {
@@ -898,13 +920,11 @@ void ScummEngine::cost_decodeData(Actor *a, int frame, uint usemask) {
} while (mask&0xFFFF);
}
-void CostumeRenderer::setPalette(byte *palette) {
+void ClassicCostumeRenderer::setPalette(byte *palette) {
int i;
byte color;
- if (_vm->_features & GF_NES) {
- // TODO
- } else if (_loaded._format == 0x57) {
+ if (_loaded._format == 0x57) {
memcpy(_palette, palette, 13);
} else if (_vm->_features & GF_OLD_BUNDLE) {
if ((_vm->VAR(_vm->VAR_CURRENT_LIGHTS) & LIGHTMODE_actor_color)) {
@@ -929,15 +949,15 @@ void CostumeRenderer::setPalette(byte *palette) {
}
}
-void CostumeRenderer::setFacing(const Actor *a) {
+void ClassicCostumeRenderer::setFacing(const Actor *a) {
_mirror = newDirToOldDir(a->getFacing()) != 0 || _loaded._mirror;
}
-void CostumeRenderer::setCostume(int costume) {
+void ClassicCostumeRenderer::setCostume(int costume) {
_loaded.loadCostume(costume);
}
-byte LoadedCostume::increaseAnims(Actor *a) {
+byte ClassicCostume::increaseAnims(Actor *a) {
int i;
byte r = 0;
@@ -948,18 +968,18 @@ byte LoadedCostume::increaseAnims(Actor *a) {
return r;
}
-byte LoadedCostume::increaseAnim(Actor *a, int slot) {
+byte NESCostume::increaseAnim(Actor *a, int slot) {
+ a->_cost.curpos[slot]++;
+ if (a->_cost.curpos[slot] >= a->_cost.end[slot])
+ a->_cost.curpos[slot] = a->_cost.start[slot];
+ return 0;
+}
+
+byte ClassicCostume::increaseAnim(Actor *a, int slot) {
int highflag;
int i, end;
byte code, nc;
- if (_vm->_features & GF_NES) {
- a->_cost.curpos[slot]++;
- if (a->_cost.curpos[slot] >= a->_cost.end[slot])
- a->_cost.curpos[slot] = a->_cost.start[slot];
- return 0;
- }
-
if (a->_cost.curpos[slot] == 0xFFFF)
return 0;
diff --git a/scumm/costume.h b/scumm/costume.h
index 1b233e1c81..fb311608a4 100644
--- a/scumm/costume.h
+++ b/scumm/costume.h
@@ -25,7 +25,7 @@
namespace Scumm {
-class LoadedCostume {
+class ClassicCostume : public BaseCostume {
protected:
ScummEngine *_vm;
@@ -41,29 +41,36 @@ public:
byte _format;
bool _mirror;
- LoadedCostume(ScummEngine *vm) :
+ ClassicCostume(ScummEngine *vm) :
_vm(vm), _id(-1), _baseptr(0), _animCmds(0), _dataOffsets(0), _palette(0),
_frameOffsets(0), _numColors(0), _numAnim(0), _format(0), _mirror(false) {}
void loadCostume(int id);
byte increaseAnims(Actor *a);
- void loadNEScostume(void);
protected:
byte increaseAnim(Actor *a, int slot);
};
+class NESCostume : public ClassicCostume {
+public:
+ NESCostume(ScummEngine *vm) : ClassicCostume(vm) {}
+ void loadCostume(int id);
-class CostumeRenderer : public BaseCostumeRenderer {
protected:
- LoadedCostume _loaded;
+ byte increaseAnim(Actor *a, int slot);
+};
+
+class ClassicCostumeRenderer : public BaseCostumeRenderer {
+protected:
+ ClassicCostume _loaded;
byte _scaleIndexX; /* must wrap at 256 */
byte _scaleIndexY;
byte _palette[32];
public:
- CostumeRenderer(ScummEngine *vm) : BaseCostumeRenderer(vm), _loaded(vm) {}
+ ClassicCostumeRenderer(ScummEngine *vm) : BaseCostumeRenderer(vm), _loaded(vm) {}
void setPalette(byte *palette);
void setFacing(const Actor *a);
@@ -71,7 +78,6 @@ 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);
@@ -81,6 +87,21 @@ protected:
byte mainRoutine(int xmoveCur, int ymoveCur);
};
+class NESCostumeRenderer : public BaseCostumeRenderer {
+protected:
+ NESCostume _loaded;
+
+public:
+ NESCostumeRenderer(ScummEngine *vm) : BaseCostumeRenderer(vm), _loaded(vm) {}
+
+ void setPalette(byte *palette);
+ void setFacing(const Actor *a);
+ void setCostume(int costume);
+
+protected:
+ byte drawLimb(const Actor *a, int limb);
+};
+
} // End of namespace Scumm
#endif
diff --git a/scumm/scumm.cpp b/scumm/scumm.cpp
index 6ea7a3ba0a..8fe5f0080e 100644
--- a/scumm/scumm.cpp
+++ b/scumm/scumm.cpp
@@ -1272,8 +1272,10 @@ int ScummEngine::init(GameDetector &detector) {
// Create the costume renderer
if (_features & GF_NEW_COSTUMES)
_costumeRenderer = new AkosRenderer(this);
+ else if (_features & GF_NES)
+ _costumeRenderer = new NESCostumeRenderer(this);
else
- _costumeRenderer = new CostumeRenderer(this);
+ _costumeRenderer = new ClassicCostumeRenderer(this);
// Create FT INSANE object
if (_gameId == GID_FT)
diff --git a/scumm/scumm.h b/scumm/scumm.h
index 69611abed4..485619588e 100644
--- a/scumm/scumm.h
+++ b/scumm/scumm.h
@@ -848,8 +848,11 @@ public:
void costumeDecodeData(Actor *a, int frame, uint usemask);
bool isCostumeInUse(int i) const;
- // Costume class
+ // Classic costume class
void cost_decodeData(Actor *a, int frame, uint usemask);
+
+ // NEWS costume class
+ void NES_cost_decodeData(Actor *a, int frame, uint usemask);
void cost_decodeNESCostumeGfx();
// Akos Class