[Scummvm-git-logs] scummvm master -> 66f10c6dc8ba729e9c40f12dd710f6d94d9917a7
mduggan
mgithub at guarana.org
Wed May 13 11:51:43 UTC 2020
This automated email contains information about 11 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
663848608a ULTIMA8: Add debug outputs to help crusader decoding
7c0a96452d ULTIMA8: Load more crusader data correctly
ff27f3393f ULTIMA8: Reset all intrinsics for crusader and begin decoding
ea1d415563 ULTIMA8: Improve item dumping to include uc class
8d262ad816 ULTIMA8: Only show avatar tomb on U8
9f335c5173 ULTIMA8: Fix debug output
10a5829d48 ULTIMA8: Add intrinsic to support crusder style SFX
d8befc8125 ULTIMA8: More remorse intrinsic decoding
782313a037 ULTIMA8: Add gumps for displaying crusader status bar
17974f9a5f ULTIMA8: Fix crusader avatar animations a bit
66f10c6dc8 ULTIMA8: Add a 'start crusader' process
Commit: 663848608ad39e8f558dbd90daf72d83f7196f39
https://github.com/scummvm/scummvm/commit/663848608ad39e8f558dbd90daf72d83f7196f39
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-05-13T20:43:25+09:00
Commit Message:
ULTIMA8: Add debug outputs to help crusader decoding
Changed paths:
engines/ultima/ultima8/world/actors/avatar_mover_process.cpp
engines/ultima/ultima8/world/item.cpp
diff --git a/engines/ultima/ultima8/world/actors/avatar_mover_process.cpp b/engines/ultima/ultima8/world/actors/avatar_mover_process.cpp
index 1c41def18a..aa7577aebb 100644
--- a/engines/ultima/ultima8/world/actors/avatar_mover_process.cpp
+++ b/engines/ultima/ultima8/world/actors/avatar_mover_process.cpp
@@ -565,12 +565,14 @@ void AvatarMoverProcess::step(Animation::Sequence action, int direction,
if (res == Animation::FAILURE ||
(action == Animation::step && res == Animation::END_OFF_LAND)) {
+ debug(6, "Step: end off land dir %d, try other dir", stepdir);
int altdir1 = (stepdir + 1) % 8;
int altdir2 = (stepdir + 7) % 8;
res = avatar->tryAnim(action, altdir1);
if (res == Animation::FAILURE ||
(action == Animation::step && res == Animation::END_OFF_LAND)) {
+ debug(6, "Step: end off land dir %d, altdir1 %d failed, try altdir2 %d", stepdir, altdir1, altdir2);
res = avatar->tryAnim(action, altdir2);
if (res == Animation::FAILURE ||
(action == Animation::step && res == Animation::END_OFF_LAND)) {
@@ -578,9 +580,11 @@ void AvatarMoverProcess::step(Animation::Sequence action, int direction,
// Try to take a smaller step
if (action == Animation::walk) {
+ debug(6, "Step: end off land both altdirs failed, smaller step (step)");
step(Animation::step, direction, true);
return;
} else if (action == Animation::run) {
+ debug(6, "Step: end off land both altdirs failed, smaller step (walk)");
step(Animation::walk, direction, true);
return;
}
@@ -599,6 +603,7 @@ void AvatarMoverProcess::step(Animation::Sequence action, int direction,
lastanim != Animation::keepBalance && !adjusted) {
if (checkTurn(stepdir, false))
return;
+ debug(6, "Step: end off land both altdirs failed, keep balance.");
waitFor(avatar->doAnim(Animation::keepBalance, stepdir));
return;
}
@@ -613,6 +618,7 @@ void AvatarMoverProcess::step(Animation::Sequence action, int direction,
if (checkTurn(stepdir, moving))
return;
+ debug(6, "Step: step ok: action %d dir %d", action, stepdir);
action = Animation::checkWeapon(action, lastanim);
waitFor(avatar->doAnim(action, stepdir));
}
@@ -730,6 +736,8 @@ void AvatarMoverProcess::turnToDirection(int direction) {
ProcId prevpid = 0;
+ // Create a sequence of turn animations from
+ // our current direction to the new one
for (int dir = curdir; dir != direction;) {
ProcId animpid = avatar->doAnim(turnanim, dir);
diff --git a/engines/ultima/ultima8/world/item.cpp b/engines/ultima/ultima8/world/item.cpp
index 68bca459f0..d91549c41c 100644
--- a/engines/ultima/ultima8/world/item.cpp
+++ b/engines/ultima/ultima8/world/item.cpp
@@ -1049,7 +1049,11 @@ uint32 Item::callUsecodeEvent(uint32 event, const uint8 *args, int argsize) {
#endif
// FIXME: Disabled usecode except for Use events in crusader for now
- if (GAME_IS_CRUSADER && event != 1) return 0;
+ if (GAME_IS_CRUSADER && event != 1) {
+ warning("Cusader: not running event %d for item %d shape %d",
+ event, _objId, _shape);
+ return 0;
+ }
return callUsecode(static_cast<uint16>(class_id),
static_cast<uint16>(offset),
Commit: 7c0a96452da7c3fa8c9f8f9d08649a69cc8530ff
https://github.com/scummvm/scummvm/commit/7c0a96452da7c3fa8c9f8f9d08649a69cc8530ff
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-05-13T20:43:25+09:00
Commit Message:
ULTIMA8: Load more crusader data correctly
In particular, support ambient sfx and animated shapes
Changed paths:
engines/ultima/ultima8/audio/audio_process.cpp
engines/ultima/ultima8/audio/audio_sample.cpp
engines/ultima/ultima8/audio/audio_sample.h
engines/ultima/ultima8/audio/raw_audio_sample.cpp
engines/ultima/ultima8/audio/sonarc_audio_sample.cpp
engines/ultima/ultima8/audio/sound_flex.cpp
engines/ultima/ultima8/games/game_data.cpp
engines/ultima/ultima8/graphics/palette_manager.h
engines/ultima/ultima8/graphics/shape.cpp
engines/ultima/ultima8/graphics/type_flags.cpp
engines/ultima/ultima8/world/item.cpp
diff --git a/engines/ultima/ultima8/audio/audio_process.cpp b/engines/ultima/ultima8/audio/audio_process.cpp
index cae1e477af..64eedcb644 100644
--- a/engines/ultima/ultima8/audio/audio_process.cpp
+++ b/engines/ultima/ultima8/audio/audio_process.cpp
@@ -34,6 +34,7 @@
#include "ultima/ultima8/world/get_object.h"
#include "ultima/ultima8/world/item.h"
#include "ultima/ultima8/world/camera_process.h"
+#include "ultima/ultima8/kernel/core_app.h"
#include "common/util.h"
namespace Ultima {
@@ -75,8 +76,15 @@ bool AudioProcess::calculateSoundVolume(ObjId objId, int16 &lVol, int16 &rVol) c
int x = (ix - iy) / 4;
int y = (ix + iy) / 8 - iz;
- // Fall off over 350 pixels
- int limit = 350 * 350;
+ // Fall off over 350 pixels, or 700 for crusader
+ // (double resolution)..
+
+ int limit;
+ if (GAME_IS_U8) {
+ limit = 350 * 350;
+ } else {
+ limit = 700 * 700;
+ }
int dist = limit - (x * x + y * y);
if (dist < 0) dist = 0;
dist = (dist * 256) / limit;
@@ -280,8 +288,8 @@ void AudioProcess::playSFX(int sfxNum, int priority, ObjId objId, int loops,
if (!sample) return;
if (lVol == -1 || rVol == -1) {
- lVol = 256;
- rVol = 256;
+ lVol = 255;
+ rVol = 255;
if (objId) calculateSoundVolume(objId, lVol, rVol);
}
diff --git a/engines/ultima/ultima8/audio/audio_sample.cpp b/engines/ultima/ultima8/audio/audio_sample.cpp
index 5aca2bfd91..b62354c849 100644
--- a/engines/ultima/ultima8/audio/audio_sample.cpp
+++ b/engines/ultima/ultima8/audio/audio_sample.cpp
@@ -26,14 +26,15 @@
namespace Ultima {
namespace Ultima8 {
-AudioSample::AudioSample(const uint8 *buffer, uint32 size, uint32 bits, bool stereo) :
+AudioSample::AudioSample(const uint8 *buffer, uint32 size, uint32 bits, bool stereo, bool deleteBuffer) :
_sampleRate(0), _bits(bits), _stereo(stereo),
_frameSize(0), _decompressorSize(0), _length(0),
- _bufferSize(size), _buffer(buffer) {
+ _bufferSize(size), _buffer(buffer), _deleteBuffer(deleteBuffer) {
}
AudioSample::~AudioSample(void) {
- delete [] _buffer;
+ if (_deleteBuffer)
+ delete [] _buffer;
}
} // End of namespace Ultima8
diff --git a/engines/ultima/ultima8/audio/audio_sample.h b/engines/ultima/ultima8/audio/audio_sample.h
index 38bd4bfed0..bd4b9a83fe 100644
--- a/engines/ultima/ultima8/audio/audio_sample.h
+++ b/engines/ultima/ultima8/audio/audio_sample.h
@@ -38,8 +38,10 @@ protected:
uint32 _bufferSize;
uint8 const *_buffer;
+ bool _deleteBuffer;
+
public:
- AudioSample(const uint8 *buffer, uint32 size, uint32 bits, bool stereo);
+ AudioSample(const uint8 *buffer, uint32 size, uint32 bits, bool stereo, bool deleteBuffer);
virtual ~AudioSample(void);
inline uint32 getRate() const {
diff --git a/engines/ultima/ultima8/audio/raw_audio_sample.cpp b/engines/ultima/ultima8/audio/raw_audio_sample.cpp
index 72e8cd02e4..cf63dda6e9 100644
--- a/engines/ultima/ultima8/audio/raw_audio_sample.cpp
+++ b/engines/ultima/ultima8/audio/raw_audio_sample.cpp
@@ -29,7 +29,7 @@ namespace Ultima8 {
RawAudioSample::RawAudioSample(const uint8 *buffer_, uint32 size, uint32 rate,
bool signedData, bool stereo)
- : AudioSample(buffer_, size, 8, stereo), _signedData(signedData) {
+ : AudioSample(buffer_, size, 8, stereo, false), _signedData(signedData) {
_sampleRate = rate;
_frameSize = 512;
_decompressorSize = sizeof(RawDecompData);
diff --git a/engines/ultima/ultima8/audio/sonarc_audio_sample.cpp b/engines/ultima/ultima8/audio/sonarc_audio_sample.cpp
index ec0ae111b5..55345f54d2 100644
--- a/engines/ultima/ultima8/audio/sonarc_audio_sample.cpp
+++ b/engines/ultima/ultima8/audio/sonarc_audio_sample.cpp
@@ -31,7 +31,7 @@ bool SonarcAudioSample::_generatedOneTable = false;
int SonarcAudioSample::_oneTable[256];
SonarcAudioSample::SonarcAudioSample(uint8 const *buffer, uint32 size) :
- AudioSample(buffer, size, 8, false), _srcOffset(0x20) {
+ AudioSample(buffer, size, 8, false, true), _srcOffset(0x20) {
if (!_generatedOneTable) GenerateOneTable();
_length = *_buffer;
diff --git a/engines/ultima/ultima8/audio/sound_flex.cpp b/engines/ultima/ultima8/audio/sound_flex.cpp
index 3947e0790b..5375581a09 100644
--- a/engines/ultima/ultima8/audio/sound_flex.cpp
+++ b/engines/ultima/ultima8/audio/sound_flex.cpp
@@ -96,9 +96,12 @@ void SoundFlex::cache(uint32 index) {
if (!buf || !size) return;
if (Std::strncmp(reinterpret_cast<const char *>(buf), "ASFX", 4) == 0) {
- // After the 32 byte header, ASFX (crusader audio) is just raw data in stereo
- // TODO: Check that 22050/stereo is correct (seems like it?)
- _samples[index] = new RawAudioSample(buf + 32, size - 32, 22050, true, true);
+ // After the 32 byte header, ASFX (crusader audio) is just raw data
+ // TODO: Check that 11025 is correct (seems like it?)
+ // TODO: Check if No Regret is Stereo and/or 16 bit?
+ const SoundFlexEntry &entry = _index[index];
+ debug(6, "SoundFlex: Playing sfx %d (%s) with data 0x%04X", index, entry._name.c_str(), entry._data);
+ _samples[index] = new RawAudioSample(buf + 32, size - 32, 11025, true, false);
} else {
_samples[index] = new SonarcAudioSample(buf, size);
}
diff --git a/engines/ultima/ultima8/games/game_data.cpp b/engines/ultima/ultima8/games/game_data.cpp
index 929aced5e1..db189bca77 100644
--- a/engines/ultima/ultima8/games/game_data.cpp
+++ b/engines/ultima/ultima8/games/game_data.cpp
@@ -589,14 +589,82 @@ void GameData::loadRemorseData() {
_gumps = new GumpShapeArchive(gumpds, GUMPS,
PaletteManager::get_instance()->getPalette(PaletteManager::Pal_Game));
-#if 0
- Common::SeekableReadStream *gumpageds = filesystem->ReadFile("@game/static/gumpage.dat");
- if (!gumpageds)
- error("Unable to load static/gumpage.dat");
+ Common::SeekableReadStream *dtableds = filesystem->ReadFile("@game/static/dtable.flx");
+ if (!dtableds)
+ error("Unable to load static/dtable.flx");
- _gumps->loadGumpage(gumpageds);
- delete gumpageds;
-#endif
+ RawArchive *dtableflex = new RawArchive(dtableds);
+
+ // TODO: What's in this flex file?
+ // Object 1: 35 * 142 byte blocks of .. something
+ // Object 2: 35 * 32-byte long names of NPCs?
+ //_dtable = new DtableDat();
+ //_dtable->load(dtableflex);
+
+ delete dtableflex;
+
+ Common::SeekableReadStream *damageds = filesystem->ReadFile("@game/static/damage.flx");
+ if (!damageds)
+ error("Unable to load static/damage.flx");
+
+ RawArchive *damageflex = new RawArchive(damageds);
+
+ // TODO: What's in this flex file?
+ // 1 object of 12288 bytes, mostly 0s
+ //_damage = new DamageDat();
+ //_damage->load(damageflex);
+
+ delete damageflex;
+
+ Common::SeekableReadStream *combatds = filesystem->ReadFile("@game/static/combat.dat");
+ if (!combatds)
+ error("Unable to load static/combat.dat");
+
+ RawArchive *combatflex = new RawArchive(combatds);
+
+ // TODO: What's in this flex file? Descriptions of combat tactics?
+ // 14 objects with contents:
+ // [ 16 Byte Name ]
+ // [ 4 * 16 bit numbers, alway 44, xx, 77, 78 ]
+ // [ 20 bytes of 0s ]
+ // [ variable number of bytes of data ]
+ //_combat = new CombatDat();
+ //_combat->load(combatflex);
+
+ delete combatflex;
+
+ Common::SeekableReadStream *stuffds = filesystem->ReadFile("@game/static/stuff.dat");
+ if (!stuffds)
+ error("Unable to load static/stuff.dat");
+
+ // TODO: What's in this dat file?
+ // 14 blocks of 323 bytes, references like W01 and I07
+ // (presumably weapon and inventory)
+ // shop data?
+
+ delete stuffds;
+
+ Common::SeekableReadStream *trigds = filesystem->ReadFile("@game/static/trig.dat");
+ if (!trigds)
+ error("Unable to load static/trig.dat");
+
+ // TODO: What's in this dat file?
+ // 12 x 256 bytes. Each block has consistently either 0000 or FFFF in the
+ //vsecond word of each DWORD
+
+ delete trigds;
+
+ Common::SeekableReadStream *xformpalds = filesystem->ReadFile("@game/static/xformpal.dat");
+ if (!xformpalds)
+ error("Unable to load static/xformpal.dat");
+ RawArchive *xformpalflex = new RawArchive(xformpalds);
+
+ // TODO: What's in this flex?
+ // Object 1: 32 bytes
+ // Object 2: 2304 bytes - presumably data for 3 palettes == 768 * 3
+ // almost no low numbers (so not raw palette data, would be missing black..)
+
+ delete xformpalflex;
// Note: No MusicFlex for Remorse, as the music is all in different AMF files.
// The remorse_music_process will load them.
diff --git a/engines/ultima/ultima8/graphics/palette_manager.h b/engines/ultima/ultima8/graphics/palette_manager.h
index 9cb12d3bda..1a060ca57c 100644
--- a/engines/ultima/ultima8/graphics/palette_manager.h
+++ b/engines/ultima/ultima8/graphics/palette_manager.h
@@ -43,11 +43,11 @@ public:
enum PalIndex {
Pal_Game = 0,
Pal_Movie = 1,
- Pal_Diff = 2, // Crusaders only - difficulty screen
+ Pal_Diff = 2, // Crusaders only - difficulty screen??
Pal_Misc = 3, // Crusaders only - game menu
- Pal_Misc2 = 4, // Crusaders only
- Pal_Star = 5, // Crusaders only
- Pal_Cred = 6, // Crusader: No regret only
+ Pal_Misc2 = 4, // Crusaders only - ??
+ Pal_Star = 5, // Crusaders only - ??
+ Pal_Cred = 6, // Crusader: No regret only (but mentioned in the no remorse exe!)
Pal_JPFontStart = 16
};
diff --git a/engines/ultima/ultima8/graphics/shape.cpp b/engines/ultima/ultima8/graphics/shape.cpp
index 2f33fa3d6a..84f4ffeede 100644
--- a/engines/ultima/ultima8/graphics/shape.cpp
+++ b/engines/ultima/ultima8/graphics/shape.cpp
@@ -172,7 +172,16 @@ Common::Array<RawShapeFrame *> Shape::loadGenericFormat(const uint8 *data, uint3
}
// Skip unknown
- ds.skip(format->_bytes_header_unk);
+ if (format->_bytes_header_unk && format != &Crusader2DShapeFormat) {
+ uint32 val = ds.readX(format->_bytes_header_unk);
+ uint16 lowval = val & 0xff;
+ uint16 highval = (val >> 16) & 0xff;
+ uint32 dummy = 0 + lowval + highval + val;
+ } else {
+ // Appears to be shape Width x Height for Crusader 2D shapes,
+ // not needed - we get them by frame.
+ ds.skip(format->_bytes_header_unk);
+ }
// Read framecount, default 1 if no
if (format->_bytes_num_frames) framecount = ds.readX(format->_bytes_num_frames);
@@ -187,7 +196,10 @@ Common::Array<RawShapeFrame *> Shape::loadGenericFormat(const uint8 *data, uint3
else frameoffset = format->_len_header + (format->_len_frameheader * i);
// Skip the unknown
- ds.skip(format->_bytes_frameheader_unk);
+ if (format->_bytes_frameheader_unk) {
+ uint32 val = ds.readX(format->_bytes_frameheader_unk);
+ uint32 dummy = 0 + val;
+ }
// Read frame_length
if (format->_bytes_frame_length) framesize = ds.readX(format->_bytes_frame_length) + format->_bytes_frame_length_kludge;
diff --git a/engines/ultima/ultima8/graphics/type_flags.cpp b/engines/ultima/ultima8/graphics/type_flags.cpp
index 5c7939440e..fe9419fbcf 100644
--- a/engines/ultima/ultima8/graphics/type_flags.cpp
+++ b/engines/ultima/ultima8/graphics/type_flags.cpp
@@ -136,6 +136,8 @@ void TypeFlags::load(Common::SeekableReadStream *rs) {
si._y = (data[3] >> 2) & 0x1F;
si._z = ((data[4] << 1) | (data[3] >> 7)) & 0x1F;
+ si._unknown = ((data[4] & 0xF0) << 24) & (data[5] << 16) & (data[7] << 8) & data[8];
+
if (data[6] & 0x01) si._flags |= ShapeInfo::SI_EDITOR;
if (data[6] & 0x02) si._flags |= ShapeInfo::SI_CRUSUNK61;
if (data[6] & 0x04) si._flags |= ShapeInfo::SI_CRUSUNK62;
@@ -145,7 +147,15 @@ void TypeFlags::load(Common::SeekableReadStream *rs) {
if (data[6] & 0x40) si._flags |= ShapeInfo::SI_CRUSUNK66;
if (data[6] & 0x80) si._flags |= ShapeInfo::SI_CRUSUNK67;
- si._animType = 0;
+ // FIXME: this is not exactly right, but it is close and at
+ // least it animates the main items that need
+ // continuously animating
+ si._animType = (data[4] & 0xF0) >> 4;
+ if (si._animType == 4) {
+ // FIXME: Only one object (Shape 360, a small glowing
+ // reactor) has this type what should it do?
+ si._animType = 1;
+ }
}
diff --git a/engines/ultima/ultima8/world/item.cpp b/engines/ultima/ultima8/world/item.cpp
index d91549c41c..e704b94579 100644
--- a/engines/ultima/ultima8/world/item.cpp
+++ b/engines/ultima/ultima8/world/item.cpp
@@ -82,7 +82,7 @@ Item::~Item() {
void Item::dumpInfo() const {
pout << "Item " << getObjId() << " (class "
- << GetClassType()._className << ", _shape "
+ << GetClassType()._className << ", shape "
<< getShape() << ", " << getFrame() << ", (";
if (_parent) {
@@ -95,8 +95,16 @@ void Item::dumpInfo() const {
pout << ") q:" << getQuality()
<< ", m:" << getMapNum() << ", n:" << getNpcNum()
- << ", f:" << Std::hex << getFlags() << ", ef:"
- << getExtFlags() << ")" << Std::dec << Std::endl;
+ << ", f: 0x" << Std::hex << getFlags() << ", ef:0x"
+ << getExtFlags();
+
+ ShapeInfo *info = getShapeInfo();
+ if (info) {
+ pout << " shapeinfo f:" << info->_flags << ", fam:"
+ << info->_family << ", et:" << info->_equipType;
+ }
+
+ pout << ")" << Std::dec << Std::endl;
}
Container *Item::getParentAsContainer() const {
@@ -2101,7 +2109,7 @@ uint32 Item::I_getTypeFlag(const uint8 *args, unsigned int /*argsize*/) {
if (GAME_IS_U8 && typeflag >= 64)
perr << "Invalid TypeFlag greater than 63 requested (" << typeflag << ") by Usecode" << Std::endl;
if (GAME_IS_CRUSADER && typeflag >= 72)
- perr << "Invalid TypeFlag greater than 63 requested (" << typeflag << ") by Usecode" << Std::endl;
+ perr << "Invalid TypeFlag greater than 72 requested (" << typeflag << ") by Usecode" << Std::endl;
if (info->getTypeFlag(typeflag))
return 1;
Commit: ff27f3393fbd446b41917d62df689b5f950b7b36
https://github.com/scummvm/scummvm/commit/ff27f3393fbd446b41917d62df689b5f950b7b36
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-05-13T20:43:25+09:00
Commit Message:
ULTIMA8: Reset all intrinsics for crusader and begin decoding
Changed paths:
A engines/ultima/ultima8/convert/crusader/convert_usecode_crusader.h
engines/ultima/ultima8/convert/u8/convert_usecode_u8.h
engines/ultima/ultima8/ultima8.cpp
engines/ultima/ultima8/ultima8.h
engines/ultima/ultima8/usecode/remorse_intrinsics.h
engines/ultima/ultima8/usecode/uc_machine.cpp
engines/ultima/ultima8/world/item.cpp
diff --git a/engines/ultima/ultima8/convert/crusader/convert_usecode_crusader.h b/engines/ultima/ultima8/convert/crusader/convert_usecode_crusader.h
new file mode 100644
index 0000000000..4333f0a20a
--- /dev/null
+++ b/engines/ultima/ultima8/convert/crusader/convert_usecode_crusader.h
@@ -0,0 +1,459 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ULTIMA8_CONVERT_U8_CONVERTUSECODECRUSADER_H
+#define ULTIMA8_CONVERT_U8_CONVERTUSECODECRUSADER_H
+
+#ifndef INCLUDE_CONVERTUSECODEU8_WITHOUT_BRINGING_IN_FOLD
+#include "ultima/ultima8/convert/convert.h"
+#else
+#include "ultima/ultima8/convert/u8/convert_usecode_u8.h"
+#endif
+
+namespace Ultima {
+namespace Ultima8 {
+
+class ConvertUsecodeCrusader : public ConvertUsecode {
+public:
+ const char* const *intrinsics() override { return _intrinsics; };
+ const char* const *event_names() override { return _event_names; };
+ void readheader(Common::SeekableReadStream *ucfile, UsecodeHeader &uch, uint32 &curOffset) override;
+ void readevents(Common::SeekableReadStream *ucfile, const UsecodeHeader &/*uch*/) override
+ {
+#ifndef INCLUDE_CONVERTUSECODEU8_WITHOUT_BRINGING_IN_FOLD
+ EventMap.clear();
+ uint32 num_crusader_routines = uch.offset / 6;
+ for (uint32 i=0; i<32; ++i)
+ {
+ /*uint32 size =*/ ucfile->readUint16LE();
+ uint32 offset = ucfile->readUint32LE();
+ EventMap[offset] = i;
+#ifdef DISASM_DEBUG
+ pout << "Crusader Routine: " << i << ": " << Std::hex << Std::setw(4) << offset << Std::dec << endl;
+#endif
+ }
+#endif
+ }
+
+ void readOp(TempOp &op, Common::SeekableReadStream *ucfile, uint32 &dbg_symbol_offset, Std::vector<DebugSymbol> &debugSymbols, bool &done) override
+ { readOpGeneric(op, ucfile, dbg_symbol_offset, debugSymbols, done, true); };
+ Node *readOp(Common::SeekableReadStream *ucfile, uint32 &dbg_symbol_offset, Std::vector<DebugSymbol> &debugSymbols, bool &done) override
+ { return readOpGeneric(ucfile, dbg_symbol_offset, debugSymbols, done, true); };
+
+private:
+ static const char* const _intrinsics[512];
+ static const char* const _event_names[];
+};
+
+// By convention, last pushed argument goes first on the list.
+const char* const ConvertUsecodeCrusader::_intrinsics[] = {
+ // 0000
+ "byte Ultima8Engine::I_getAlertActive(void)",
+ "int16 Item::I_getFrame(Item *)",
+ "void Item::I_setFrame(Item *, frame)",
+ "int16 Item::I_getSOMETHING_03(Item *)", // used to get passcode highbyte from valueboxes..
+ "int16 Item::I_getStatus(Item *)",
+ "void I_orStatus(Item *, uint16 flags)",
+ "int16 Intrinsic006(6 bytes)", // same coff as 0B5
+ "byte Item::I_getSOMETHING_07(Item *)", // called for gattling guns and camera
+ "byte Intrinsic008(4 bytes)",
+ "byte Item::I_getZ(Item *)",
+ "void Intrinsic00A(4 bytes)",
+ "int16 I_getSOMETHING_09(MainActor *???)",
+ "void Intrinsic00C(2 bytes)",
+ "byte Intrinsic00D(6 bytes)",
+ "int16 Intrinsic00E(8 bytes)",
+ "void I_playFlic(void), int16 I_playFlic(Item *, char *name, int16 sizex, int16 sizey)",
+ // 0010
+ "int16 Item::I_getQLo(Item *)", // same as 02B based on same coff as 02B, 066, 084, 0A1, 0AE, 0D9, 0EA
+ "int16 Intrinsic011(4 bytes)",
+ "void Intrinsic012(2 bytes)",
+ "int16 Item::getX(Item *)",
+ "int16 Item::getY(Item *)",
+ "void Intrinsic015(Item *, uint16 unk)",
+ "int16 Item::I_getShape(Item *)", // in STEAMBOX::func0A, is compared to 0x511 (the STEAM2 shape number) to determine direction
+ "void Intrinsic017(8 bytes)",
+ "int16 Intrinsic018(4 bytes not Item *)",
+ "byte Intrinsic019(14 bytes)",
+ "void Intrinsic01A(6 bytes)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "int16 Intrinsic01B(void)",
+ "byte Intrinsic01C(4 bytes)", // same coff as 112, 121
+ "int16 Intrinsic01D(4 bytes)", // part of same coff set 01D, 05A, 0B9, 0D7, 0E4, 124
+ "int16 Intrinsic01E(16 bytes)",
+ "byte Item::I_create(Item *, uint16 shapenum, uint16 framenum)", // probably - used in MISS1EGG referencing keycards and NPCDEATH in creating blood spills
+ // 0020
+ "void Item::I_popToCoords(Item *, uint16 x, uint16 y, uint16 z)", // set coords, used after creating blood spills in NPCDEATH
+ "void Intrinsic021(4 bytes)", // part of same coff set 021, 060, 073, 0A0, 0A8, 0D8, 0E7, 135
+ "void Intrinsic022(Item *)",
+ "int16 Intrinsic023(void)",
+ "void Intrinsic024(6 bytes)",
+ "void Intrinsic025(4 bytes)",
+ "int16 Item::I_getQHi(Item *)", // guess, based on variable name in BOUNCBOX::gotHit
+ "int16 Intrinsic027(14 bytes)",
+ "int16 Intrinsic028(12 bytes)", // part of same coff set 028, 08D, 0BD, 0C0, 0C2, 0C8, 0F7, 0F9, 118, 11D
+ "int16 Intrinsic029(void)",
+ "void AudioProcess::I_playAmbientSFXCru(Item *, sndno)",
+ "int16 Item::I_getQLo(Item *)", // guess, based on variable name in BOUNCBOX::gotHit
+ "byte Intrinsic02C(4 bytes)",
+ "void Item::I_setSOMETHING_2D(Item *, uint16 unk)",
+ "byte Intrinsic02E(Item *, 8 bytes)",
+ "byte Intrinsic02F(10 bytes)",
+ // 0030
+ "void Intrinsic030(4 bytes)",
+ "void Item::I_setSOMETHING_31(Item *, uint16 unk)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "void Intrinsic032(12 bytes)",
+ "byte Intrinsic033(4 bytes)",
+ "int16 Intrinsic034(8 bytes)",
+ "byte Intrinsic035(4 bytes)",
+ "int16 Intrinsic036(12 bytes)",
+ "byte Intrinsic037(4 bytes)", // same coff as 0B8
+ "void Intrinsic038(Item *, int16)",
+ "byte Intrinsic039(4 bytes)", // same coff as 122, 12E
+ "byte Intrinsic03A(Item *, int16 unk)",
+ "void Intrinsic03B(6 bytes)",
+ "int16 Intrinsic03C(4 bytes)",
+ "void Intrinsic03D(4 bytes)",
+ "void Intrinsic03E(4 bytes)",
+ "int16 Intrinsic03F(4 bytes)",
+ // 0040
+ "void Intrinsic040(8 bytes)",
+ "void Intrinsic041(2 bytes)",
+ "byte Intrinsic042(6 bytes)",
+ "void Intrinsic043(6 bytes)",
+ "byte Intrinsic044(6 bytes)", // part of same coff set 044, 046, 048, 04A, 04C, 04E, 0A5, 0BC, 0C5, 0DC, 0F1, 0FA, 12C
+ "int16 Item::I_getQHi(Item *)", // same as 026 based on same coff set 026, 045, 047, 049, 04B, 04D, 04F, 0AF, 0BE, 0C9, 0F0, 0F3, 0FB, 133
+ "byte Intrinsic046(6 bytes)", // part of same coff set 044, 046, 048, 04A, 04C, 04E, 0A5, 0BC, 0C5, 0DC, 0F1, 0FA, 12C
+ "int16 Item::I_getQHi(Item *)", // same as 026 based on same coff set 026, 045, 047, 049, 04B, 04D, 04F, 0AF, 0BE, 0C9, 0F0, 0F3, 0FB, 133
+ "byte Intrinsic048(6 bytes)", // part of same coff set 044, 046, 048, 04A, 04C, 04E, 0A5, 0BC, 0C5, 0DC, 0F1, 0FA, 12C
+ "int16 Item::I_getQHi(Item *)", // same as 026 based on same coff set 026, 045, 047, 049, 04B, 04D, 04F, 0AF, 0BE, 0C9, 0F0, 0F3, 0FB, 133
+ "byte Intrinsic04A(6 bytes)", // part of same coff set 044, 046, 048, 04A, 04C, 04E, 0A5, 0BC, 0C5, 0DC, 0F1, 0FA, 12C
+ "int16 Item::I_getQHi(Item *)", // same as 026 based on same coff set 026, 045, 047, 049, 04B, 04D, 04F, 0AF, 0BE, 0C9, 0F0, 0F3, 0FB, 133
+ "byte Intrinsic04C(6 bytes)", // part of same coff set 044, 046, 048, 04A, 04C, 04E, 0A5, 0BC, 0C5, 0DC, 0F1, 0FA, 12C
+ "int16 Item::I_getQHi(Item *)", // same as 026 based on same coff set 026, 045, 047, 049, 04B, 04D, 04F, 0AF, 0BE, 0C9, 0F0, 0F3, 0FB, 133
+ "byte Intrinsic04E(6 bytes)", // part of same coff set 044, 046, 048, 04A, 04C, 04E, 0A5, 0BC, 0C5, 0DC, 0F1, 0FA, 12C
+ "int16 Item::I_getQHi(Item *)", // same as 026 based on same coff set 026, 045, 047, 049, 04B, 04D, 04F, 0AF, 0BE, 0C9, 0F0, 0F3, 0FB, 133
+ // 0050
+ "int16 Intrinsic050(4 bytes)",
+ "void Intrinsic051(4 bytes)",
+ "void Intrinsic052(6 bytes)",
+ "void Intrinsic053(6 bytes)",
+ "void Intrinsic054(6 bytes)",
+ "void Intrinsic055(6 bytes)", // part of same coff set 055, 07D, 0CD, 0DB, 0F2, 131
+ "void Intrinsic056(2 bytes)",
+ "int16 Item::I_getSOMETHING_57(Item *)",
+ "byte Item::I_doSOMETHING_58(Item *, uint16 unk)",
+ "void Item::I_setFrame(Item *, frame)", // based on same coff as 002
+ "int16 Intrinsic05A(4 bytes)", // part of same coff set 01D, 05A, 0B9, 0D7, 0E4, 124
+ "byte Item::I_legalCreateAtPoint(Item *, int16 shape, int16 frame, Item *)", // I_legalCreateAtPoint ?? see PEPSIEW::use
+ "void Intrinsic05C(8 bytes)",
+ "void Intrinsic05D(void)",
+ "int16 Intrinsic05E(uint32, char *, int16 a, int16 b)", // Play video (as texture? parameters like (150, 250, "MVA11A") and other mvas)
+ "void Intrinsic05F(void)",
+ // 0060
+ "void Intrinsic060(4 bytes)", // part of same coff set 021, 060, 073, 0A0, 0A8, 0D8, 0E7, 135
+ "void Intrinsic061(8 bytes)",
+ "void Intrinsic062(void)",
+ "void Intrinsic063(12 bytes)",
+ "void Intrinsic064(16 bytes)", // same coff as 12D
+ "byte Intrinsic065(4 bytes)",
+ "int16 Item::I_getQLo(Item *)", // same as 02B based on same coff set 010, 02B, 066, 084, 0A1, 0AE, 0D9, 0EA
+ "int16 Intrinsic067(4 bytes)", // part of same coff set 067, 06D, 089, 08E, 0AD, 0F8, 100, 102, 105, 107, 109, 10B, 10D, 10F, 111, 115, 11C, 123, 129
+ "void Item::I_setQLo(Item *, uint16 qlow)", // probably, see VALUEBOX::ordinal20
+ "void Intrinsic069(6 bytes)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "void Intrinsic06A(10 bytes)",
+ "int16 Intrinsic06B(void)",
+ "void Intrinsic06C(sometimes Item *)", // TODO: when param not item, what is it?
+ "int16 Intrinsic06D(4 bytes)", // part of same coff set 067, 06D, 089, 08E, 0AD, 0F8, 100, 102, 105, 107, 109, 10B, 10D, 10F, 111, 115, 11C, 123, 129
+ "void Intrinsic06E(Item *, int16 unk)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "byte Intrinsic06F(6 bytes)",
+ // 0070
+ "byte Intrinsic070(void)",
+ "void Intrinsic071(void)",
+ "void Intrinsic072(void)",
+ "void Intrinsic073(4 bytes)", // part of same coff set 021, 060, 073, 0A0, 0A8, 0D8, 0E7, 135
+ "void Intrinsic074(void)",
+ "void Intrinsic075(void)",
+ "void Intrinsic076(4 bytes)",
+ "int16 Intrinsic077(void)",
+ "void Intrinsic078(void)",
+ "int16 Intrinsic079(6 bytes)",
+ "int16 Intrinsic07A(void)",
+ "void Intrinsic07B(4 bytes)", // same coff as 130
+ "int16 Intrinsic07C(4 bytes)",
+ "void Intrinsic07D(6 bytes)", // part of same coff set 055, 07D, 0CD, 0DB, 0F2, 131
+ "int16 Intrinsic07E(Item *)",
+ "void Intrinsic07F(6 bytes)", // same coff as 0BA, 125
+ // 0080
+ "int16 Intrinsic080(4 bytes)", // same coff as 0D0, 0D5
+ "int16 Intrinsic081(4 bytes)",
+ "int16 Intrinsic082(4 bytes)",
+ "void Intrinsic083(6 bytes)",
+ "int16 Item::I_getQLo(Item *)", // same as 02B based on same coff set 010, 02B, 066, 084, 0A1, 0AE, 0D9, 0EA
+ "void Intrinsic085(4 bytes)",
+ "int16 Intrinsic086(void)",
+ "int16 Intrinsic087(void)",
+ "void Item::I_setQHi(Item *, uint16 qhi)",
+ "int16 Intrinsic089(4 bytes)", // part of same coff set 067, 06D, 089, 08E, 0AD, 0F8, 100, 102, 105, 107, 109, 10B, 10D, 10F, 111, 115, 11C, 123, 129
+ "void Intrinsic08A(12 bytes)",
+ "int16 Intrinsic08B(4 bytes)",
+ "void Intrinsic08C(4 bytes)", // same coff as 119, 12A
+ "int16 Intrinsic08D(12 bytes)", // part of same coff set 028, 08D, 0BD, 0C0, 0C2, 0C8, 0F7, 0F9, 118, 11D
+ "int16 Intrinsic08E(4 bytes)", // part of same coff set 067, 06D, 089, 08E, 0AD, 0F8, 100, 102, 105, 107, 109, 10B, 10D, 10F, 111, 115, 11C, 123, 129
+ "void Intrinsic08F(void)",
+ // 0090
+ "void Intrinsic090(void)",
+ "void Intrinsic091(void)",
+ "void Intrinsic092(void)", // same coff as 0A9
+ "void Intrinsic093(void)",
+ "UNUSEDInt0094()",
+ "byte Intrinsic095(void)",
+ "int16 Intrinsic096(4 bytes)",
+ "void Intrinsic097(void)",
+ "void Intrinsic098(void)",
+ "void Intrinsic099(6 bytes)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "void Intrinsic09A(void)",
+ "int16 Intrinsic09B(2 bytes)",
+ "int16 Intrinsic09C(4 bytes)",
+ "int16 Intrinsic09D(2 bytes)",
+ "int16 Intrinsic09E(4 bytes)",
+ "int16 Intrinsic09F(10 bytes)",
+ // 00A0
+ "void Intrinsic0A0(4 bytes)", // part of same coff set 021, 060, 073, 0A0, 0A8, 0D8, 0E7, 135
+ "int16 Item::I_getQLo(Item *)", // same as 02B based on same coff set 010, 02B, 066, 084, 0A1, 0AE, 0D9, 0EA
+ "int16 Intrinsic0A2(4 bytes)",
+ "void Intrinsic0A3(6 bytes)",
+ "byte Intrinsic0A4(6 bytes)",
+ "byte Intrinsic0A5(6 bytes)", // part of same coff set 044, 046, 048, 04A, 04C, 04E, 0A5, 0BC, 0C5, 0DC, 0F1, 0FA, 12C
+ "int16 Intrinsic0A6(void)",
+ "int16 Intrinsic0A7(4 bytes)",
+ "void Intrinsic0A8(4 bytes)", // part of same coff set 021, 060, 073, 0A0, 0A8, 0D8, 0E7, 135
+ "void Intrinsic0A9(void)", // same coff as 092
+ "void Intrinsic0AA(2 bytes)", // same coff as 0D4
+ "byte Intrinsic0AB(4 bytes)",
+ "int16 Intrinsic0AC(2 bytes)",
+ "int16 Intrinsic0AD(4 bytes)", // part of same coff set 067, 06D, 089, 08E, 0AD, 0F8, 100, 102, 105, 107, 109, 10B, 10D, 10F, 111, 115, 11C, 123, 129
+ "int16 Item::I_getQLo(Item *)", // same as 02B based on same coff set 010, 02B, 066, 084, 0A1, 0AE, 0D9, 0EA
+ "int16 Item::I_getQHi(Item *)", // same as 026 based on same coff set 026, 045, 047, 049, 04B, 04D, 04F, 0AF, 0BE, 0C9, 0F0, 0F3, 0FB, 133
+ // 00B0
+ "int16 Intrinsic0B0(6 bytes)",
+ "int16 Intrinsic0B1(6 bytes)",
+ "void Item::I_setSOMETHING_B2(Item *, uint16 unk)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "int32 I_getCurrentTimerTick(void)",
+ "void Intrinsic0B4(void)",
+ "int16 Intrinsic0B5(6 bytes)",
+ "void Intrinsic0B6(void)",
+ "int16 Intrinsic0B7(void)",
+ "byte Intrinsic0B8(4 bytes)", // same coff as 037
+ "int16 Intrinsic0B9(4 bytes)", // part of same coff set 01D, 05A, 0B9, 0D7, 0E4, 124
+ "void Intrinsic0BA(6 bytes)", // same coff as 07F, 125
+ "byte Intrinsic0BB(8 bytes)",
+ "byte Intrinsic0BC(6 bytes)", // part of same coff set 044, 046, 048, 04A, 04C, 04E, 0A5, 0BC, 0C5, 0DC, 0F1, 0FA, 12C
+ "int16 Intrinsic0BD(12 bytes)", // part of same coff set 028, 08D, 0BD, 0C0, 0C2, 0C8, 0F7, 0F9, 118, 11D
+ "int16 Item::I_getQHi(Item *)", // same as 026 based on same coff set 026, 045, 047, 049, 04B, 04D, 04F, 0AF, 0BE, 0C9, 0F0, 0F3, 0FB, 133
+ "void Intrinsic0BF(6 bytes)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ // 00C0
+ "int16 Intrinsic0C0(12 bytes)", // part of same coff set 028, 08D, 0BD, 0C0, 0C2, 0C8, 0F7, 0F9, 118, 11D
+ "void Intrinsic0C1(6 bytes)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "int16 Intrinsic0C2(12 bytes)", // part of same coff set 028, 08D, 0BD, 0C0, 0C2, 0C8, 0F7, 0F9, 118, 11D
+ "void Intrinsic0C3(6 bytes)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "int16 Intrinsic0C4(2 bytes)",
+ "byte Intrinsic0C5(6 bytes)",
+ "void Intrinsic0C6(14 bytes)",
+ "byte Intrinsic0C7(6 bytes)",
+ "int16 Intrinsic0C8(12 bytes)", // part of same coff set 028, 08D, 0BD, 0C0, 0C2, 0C8, 0F7, 0F9, 118, 11D
+ "int16 Item::I_getQHi(Item *)", // same as 026 based on same coff set 026, 045, 047, 049, 04B, 04D, 04F, 0AF, 0BE, 0C9, 0F0, 0F3, 0FB, 133
+ "byte Intrinsic0CA(6 bytes)",
+ "void Intrinsic0CB(2 bytes)",
+ "byte Intrinsic0CC(4 bytes)",
+ "void Intrinsic0CD(6 bytes)", // part of same coff set 055, 07D, 0CD, 0DB, 0F2, 131
+ "int16 Intrinsic0CE(void)",
+ "void Intrinsic0CF(6 bytes)",
+ // 00D0
+ "int16 Intrinsic0D0(4 bytes)", // same coff as 080, 0D5
+ "UNUSEDInt00D1()",
+ "void Intrinsic0D2(void)",
+ "UNUSEDInt00D3()",
+ "void Intrinsic0D4(2 bytes)", // same coff as 0AA
+ "int16 Intrinsic0D5(4 bytes)", // same coff as 080, 0D0
+ "byte Intrinsic0D6(void)",
+ "int16 Intrinsic0D7(4 bytes)", // part of same coff set 01D, 05A, 0B9, 0D7, 0E4, 124
+ "void Intrinsic0D8(4 bytes)", // part of same coff set 021, 060, 073, 0A0, 0A8, 0D8, 0E7, 135
+ "int16 Item::I_getQLo(Item *)", // same as 02B based on same coff set 010, 02B, 066, 084, 0A1, 0AE, 0D9, 0EA
+ "void Intrinsic0DA(void)",
+ "void Intrinsic0DB(6 bytes)", // part of same coff set 055, 07D, 0CD, 0DB, 0F2, 131
+ "byte Intrinsic0DC(6 bytes)", // part of same coff set 044, 046, 048, 04A, 04C, 04E, 0A5, 0BC, 0C5, 0DC, 0F1, 0FA, 12C
+ "int16 Intrinsic0DD(4 bytes)",
+ "void Intrinsic0DE(6 bytes)",
+ "int16 Intrinsic0DF(6 bytes)",
+ // 00E0
+ "void Intrinsic0E0(8 bytes)",
+ "int16 Intrinsic0E1(4 bytes)",
+ "int16 Intrinsic0E2(4 bytes)",
+ "int16 Intrinsic0E3(4 bytes)",
+ "int16 Intrinsic0E4(4 bytes)", // part of same coff set 01D, 05A, 0B9, 0D7, 0E4, 124
+ "void Intrinsic0E5(6 bytes)",
+ "void Intrinsic0E6(6 bytes)",
+ "void Intrinsic0E7(4 bytes)", // part of same coff set 021, 060, 073, 0A0, 0A8, 0D8, 0E7, 135
+ "int16 Intrinsic0E8(6 bytes)",
+ "void Intrinsic0E9(6 bytes)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "int16 Item::I_getQLo(Item *)", // same as 02B based on same coff set 010, 02B, 066, 084, 0A1, 0AE, 0D9, 0EA
+ "int16 Intrinsic0EB(void)",
+ "void Intrinsic0EC(6 bytes)",
+ "void Intrinsic0ED(6 bytes)",
+ "void Intrinsic0EE(void)",
+ "int16 Intrinsic0EF(4 bytes)",
+ // 00F0
+ "int16 Item::I_getQHi(Item *)", // same as 026 based on same coff set 026, 045, 047, 049, 04B, 04D, 04F, 0AF, 0BE, 0C9, 0F0, 0F3, 0FB, 133
+ "byte Intrinsic0F1(6 bytes)", // part of same coff set 044, 046, 048, 04A, 04C, 04E, 0A5, 0BC, 0C5, 0DC, 0F1, 0FA, 12C
+ "void Intrinsic0F2(6 bytes)", // part of same coff set 055, 07D, 0CD, 0DB, 0F2, 131
+ "int16 Item::I_getQHi(Item *)", // same as 026 based on same coff set 026, 045, 047, 049, 04B, 04D, 04F, 0AF, 0BE, 0C9, 0F0, 0F3, 0FB, 133
+ "int16 Item::I_getSOMETHING_F4(Item *)",
+ "void Item::I_setSOMETHING_F5(Item *, uint16 unk)",
+ "void Intrinsic0F6(void)",
+ "int16 Intrinsic0F7(12 bytes)", // part of same coff set 028, 08D, 0BD, 0C0, 0C2, 0C8, 0F7, 0F9, 118, 11D
+ "int16 Intrinsic0F8(4 bytes)", // part of same coff set 067, 06D, 089, 08E, 0AD, 0F8, 100, 102, 105, 107, 109, 10B, 10D, 10F, 111, 115, 11C, 123, 129
+ "int16 Intrinsic0F9(12 bytes)", // part of same coff set 028, 08D, 0BD, 0C0, 0C2, 0C8, 0F7, 0F9, 118, 11D
+ "byte Intrinsic0FA(6 bytes)", // part of same coff set 044, 046, 048, 04A, 04C, 04E, 0A5, 0BC, 0C5, 0DC, 0F1, 0FA, 12C
+ "int16 Item::I_getQHi(Item *)", // same as 026 based on same coff set 026, 045, 047, 049, 04B, 04D, 04F, 0AF, 0BE, 0C9, 0F0, 0F3, 0FB, 133
+ "void Intrinsic0FC(6 bytes)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "byte Intrinsic0FD(2 bytes)",
+ "void Intrinsic0FE(4 bytes)",
+ "int16 UCMachine::I_numToStr(int16 num)", // same as 113 based on same coff set 0FF, 113, 126
+ // 0100
+ "int16 Intrinsic100(4 bytes)", // part of same coff set 067, 06D, 089, 08E, 0AD, 0F8, 100, 102, 105, 107, 109, 10B, 10D, 10F, 111, 115, 11C, 123, 129
+ "void Intrinsic101(6 bytes)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "int16 Intrinsic102(4 bytes)", // part of same coff set 067, 06D, 089, 08E, 0AD, 0F8, 100, 102, 105, 107, 109, 10B, 10D, 10F, 111, 115, 11C, 123, 129
+ "byte Intrinsic103(uint16 shapenum)",
+ "void Intrinsic104(6 bytes)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "int16 Intrinsic105(4 bytes)", // part of same coff set 067, 06D, 089, 08E, 0AD, 0F8, 100, 102, 105, 107, 109, 10B, 10D, 10F, 111, 115, 11C, 123, 129
+ "void Intrinsic106(6 bytes)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "int16 Intrinsic107(4 bytes)", // part of same coff set 067, 06D, 089, 08E, 0AD, 0F8, 100, 102, 105, 107, 109, 10B, 10D, 10F, 111, 115, 11C, 123, 129
+ "void Intrinsic108(6 bytes)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "int16 Intrinsic109(4 bytes)", // part of same coff set 067, 06D, 089, 08E, 0AD, 0F8, 100, 102, 105, 107, 109, 10B, 10D, 10F, 111, 115, 11C, 123, 129
+ "void Intrinsic10A(6 bytes)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "int16 Intrinsic10B(4 bytes)", // part of same coff set 067, 06D, 089, 08E, 0AD, 0F8, 100, 102, 105, 107, 109, 10B, 10D, 10F, 111, 115, 11C, 123, 129
+ "void Intrinsic10C(6 bytes)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "int16 Intrinsic10D(4 bytes)", // part of same coff set 067, 06D, 089, 08E, 0AD, 0F8, 100, 102, 105, 107, 109, 10B, 10D, 10F, 111, 115, 11C, 123, 129
+ "void Intrinsic10E(6 bytes)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "int16 Intrinsic10F(4 bytes)", // part of same coff set 067, 06D, 089, 08E, 0AD, 0F8, 100, 102, 105, 107, 109, 10B, 10D, 10F, 111, 115, 11C, 123, 129
+ // 0110
+ "void Intrinsic110(6 bytes)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "int16 Item::I_getSOMETHING_111(Item *)", // used to get passcode lowbyte from valueboxes.. // part of same coff set 067, 06D, 089, 08E, 0AD, 0F8, 100, 102, 105, 107, 109, 10B, 10D, 10F, 111, 115, 11C, 123, 129
+ "byte Intrinsic112(4 bytes)", // same coff as 01C, 121
+ "int16 UCMachine::I_numToStr(int16 num)", // based on VMAIL::func0A example usage
+ "void Intrinsic114(6 bytes)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "int16 Item::I_getSOMETHING_115(Item *)", // part of same coff set 067, 06D, 089, 08E, 0AD, 0F8, 100, 102, 105, 107, 109, 10B, 10D, 10F, 111, 115, 11C, 123, 129
+ "byte Intrinsic116(14 bytes)",
+ "void Intrinsic117(6 bytes)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "int16 Intrinsic118(12 bytes)", // part of same coff set 028, 08D, 0BD, 0C0, 0C2, 0C8, 0F7, 0F9, 118, 11D
+ "void Intrinsic119(4 bytes)", // same coff as 08C, 12A
+ "void Intrinsic11A(6 bytes)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "byte Intrinsic11B(6 bytes)",
+ "int16 Intrinsic11C(4 bytes)", // part of same coff set 067, 06D, 089, 08E, 0AD, 0F8, 100, 102, 105, 107, 109, 10B, 10D, 10F, 111, 115, 11C, 123, 129
+ "int16 Intrinsic11D(12 bytes)", // part of same coff set 028, 08D, 0BD, 0C0, 0C2, 0C8, 0F7, 0F9, 118, 11D
+ "int16 Intrinsic11E(4 bytes)", // same coff as 12B
+ "byte Intrinsic11F(4 bytes)",
+ // 0120
+ "int16 Intrinsic120(4 bytes)",
+ "byte Intrinsic121(4 bytes)", // same coff as 01C, 112
+ "byte Intrinsic122(4 bytes)", // same coff as 12E, 039
+ "int16 Intrinsic123(4 bytes)", // part of same coff set 067, 06D, 089, 08E, 0AD, 0F8, 100, 102, 105, 107, 109, 10B, 10D, 10F, 111, 115, 11C, 123, 129
+ "int16 Intrinsic124(4 bytes)", // part of same coff set 01D, 05A, 0B9, 0D7, 0E4, 124
+ "void Intrinsic125(6 bytes)", // same coff as 07F, 0BA
+ "int16 UCMachine::I_numToStr(int16 num)", // same as 113 based on same coff set 0FF, 113, 126
+ "byte Intrinsic127(8 bytes)",
+ "void Intrinsic128(6 bytes)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "int16 Intrinsic129(4 bytes)", // part of same coff set 067, 06D, 089, 08E, 0AD, 0F8, 100, 102, 105, 107, 109, 10B, 10D, 10F, 111, 115, 11C, 123, 129
+ "void Intrinsic12A(4 bytes)", // same coff as 08C, 119
+ "int16 Intrinsic12B(4 bytes)", // same coff as 11E
+ "byte Intrinsic12C(6 bytes)", // part of same coff set 044, 046, 048, 04A, 04C, 04E, 0A5, 0BC, 0C5, 0DC, 0F1, 0FA, 12C
+ "void Intrinsic12D(16 bytes)", // same coff as 064
+ "byte Intrinsic12E(4 bytes)", // same coff as 122, 039
+ "int16 Intrinsic12F(Item *, uint16 unk)",
+ // 0130
+ "void Intrinsic130(4 bytes)", // same coff as 07B
+ "void Intrinsic131(6 bytes)", // part of same coff set 055, 07D, 0CD, 0DB, 0F2, 131
+ "void Intrinsic132(6 bytes)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "int16 Item::I_getQHi(Item *)", // same as 026 based on same coff set 026, 045, 047, 049, 04B, 04D, 04F, 0AF, 0BE, 0C9, 0F0, 0F3, 0FB, 133
+ "void Intrinsic134(2 bytes)",
+ "void UNUSEDInt135(4 bytes)", // part of same coff set 021, 060, 073, 0A0, 0A8, 0D8, 0E7, 135
+ "void UNUSEDInt136()",
+ "void UNUSEDInt137()"
+};
+
+const char * const ConvertUsecodeCrusader::_event_names[] = {
+ "look()", // 0x00
+ "use()", // 0x01
+ "anim()", // 0x02
+ "setActivity()", // 0x03
+ "cachein()", // 0x04
+ "hit(uword, word)", // 0x05
+ "gotHit(uword, word)", // 0x06
+ "hatch()", // 0x07
+ "schedule()", // 0x08
+ "release()", // 0x09
+ "equip()", // 0x0A
+ "unequip()", // 0x0B
+ "combine()", // 0x0C
+ "func0D", // 0x0D
+ "calledFromAnim()", // 0x0E
+ "enterFastArea()", // 0x0F
+
+ "leaveFastArea()", // 0x10
+ "cast(uword)", // 0x11
+ "justMoved()", // 0x12
+ "AvatarStoleSomething(uword)", // 0x13
+ "animGetHit()", // 0x14
+ "guardianBark(word)", // 0x15
+ "func16", // 0x16
+ "func17", // 0x17
+ "func18", // 0x18
+ "func19", // 0x19
+ "func1A", // 0x1A
+ "func1B", // 0x1B
+ "func1C", // 0x1C
+ "func1D", // 0x1D
+ "func1E", // 0x1E
+ "func1F", // 0x1F
+ 0
+};
+
+void ConvertUsecodeCrusader::readheader(Common::SeekableReadStream *ucfile, UsecodeHeader &uch, uint32 &curOffset) {
+ #ifdef DISASM_DEBUG
+ perr << Std::setfill('0') << Std::hex;
+ perr << "unknown1: " << Std::setw(4) << ucfile->readUint32LE() << endl; // unknown
+ uch.maxOffset = ucfile->readUint32LE() - 0x0C; // file size
+ perr << "maxoffset: " << Std::setw(4) << maxOffset << endl;
+ perr << "unknown2: " << Std::setw(4) << ucfile->readUint32LE() << endl; // unknown
+ curOffset = 0;
+ #else
+ ucfile->readUint32LE(); // unknown
+ uch._maxOffset = ucfile->readUint32LE() - 0x0C; // file size
+ ucfile->readUint32LE(); // unknown
+ curOffset = 0;
+ #endif
+}
+
+} // End of namespace Ultima8
+} // End of namespace Ultima
+
+#endif
diff --git a/engines/ultima/ultima8/convert/u8/convert_usecode_u8.h b/engines/ultima/ultima8/convert/u8/convert_usecode_u8.h
index d73478a982..16988f0e12 100644
--- a/engines/ultima/ultima8/convert/u8/convert_usecode_u8.h
+++ b/engines/ultima/ultima8/convert/u8/convert_usecode_u8.h
@@ -40,7 +40,6 @@ public:
{
uint32 _maxOffset;
};
- uint32 readUint32LE(Common::SeekableReadStream *) { return 0; }
uint32 _curOffset;
virtual const char* const *intrinsics()=0;
@@ -67,7 +66,7 @@ class ConvertUsecodeU8 : public ConvertUsecode {
public:
const char* const *intrinsics() override { return _intrinsics; };
const char* const *event_names() override { return _event_names; };
- void readheader(Common::SeekableReadStream *ucfile, UsecodeHeader &uch, uint32 &curOffset_) override;
+ void readheader(Common::SeekableReadStream *ucfile, UsecodeHeader &uch, uint32 &curOffset) override;
void readevents(Common::SeekableReadStream *ucfile, const UsecodeHeader &/*uch*/) override
{
#ifndef INCLUDE_CONVERTUSECODEU8_WITHOUT_BRINGING_IN_FOLD
@@ -412,15 +411,15 @@ const char * const ConvertUsecodeU8::_event_names[] = {
void ConvertUsecodeU8::readheader(Common::SeekableReadStream *ucfile, UsecodeHeader &uch, uint32 &curOffset_) {
#ifdef DISASM_DEBUG
perr << Std::setfill('0') << Std::hex;
- perr << "unknown1: " << Std::setw(4) << readUint32LE(ucfile) << endl; // unknown
- uch.maxOffset = readUint32LE(ucfile) - 0x0C; // file size
+ perr << "unknown1: " << Std::setw(4) << ucfile->readUint32LE() << endl; // unknown
+ uch.maxOffset = ucfile->readUint32LE() - 0x0C; // file size
perr << "maxoffset: " << Std::setw(4) << maxOffset << endl;
- perr << "unknown2: " << Std::setw(4) << readUint32LE(ucfile) << endl; // unknown
+ perr << "unknown2: " << Std::setw(4) << ucfile->readUint32LE() << endl; // unknown
curOffset_ = 0;
#else
- readUint32LE(ucfile); // unknown
- uch._maxOffset = readUint32LE(ucfile) - 0x0C; // file size
- readUint32LE(ucfile); // unknown
+ ucfile->readUint32LE(); // unknown
+ uch._maxOffset = ucfile->readUint32LE() - 0x0C; // file size
+ ucfile->readUint32LE(); // unknown
curOffset_ = 0;
#endif
}
diff --git a/engines/ultima/ultima8/ultima8.cpp b/engines/ultima/ultima8/ultima8.cpp
index f19905d009..90abd9d1d0 100644
--- a/engines/ultima/ultima8/ultima8.cpp
+++ b/engines/ultima/ultima8/ultima8.cpp
@@ -141,7 +141,7 @@ Ultima8Engine::Ultima8Engine(OSystem *syst, const Ultima::UltimaGameDescription
_avatarInStasis(false), _paintEditorItems(false), _inversion(0), _painting(false),
_showTouching(false), _timeOffset(0), _hasCheated(false), _cheatsEnabled(false),
_ttfOverrides(false), _audioMixer(0), _scalerGump(nullptr),
- _inverterGump(nullptr), _lerpFactor(256), _inBetweenFrame(false) {
+ _inverterGump(nullptr), _lerpFactor(256), _inBetweenFrame(false), _alertActive(false) {
_application = this;
for (uint16 key = 0; key < HID_LAST; ++key) {
@@ -1496,6 +1496,11 @@ uint32 Ultima8Engine::I_getTimeInGameHours(const uint8 * /*args*/,
return get_instance()->getGameTimeInSeconds() / 900;
}
+uint32 Ultima8Engine::I_getAlertActive(const uint8 * /*args*/,
+ unsigned int /*argsize*/) {
+ return get_instance()->isAlertActive() ? 1 : 0;
+}
+
uint32 Ultima8Engine::I_getTimeInMinutes(const uint8 * /*args*/,
unsigned int /*argsize*/) {
// 60 seconds per minute
diff --git a/engines/ultima/ultima8/ultima8.h b/engines/ultima/ultima8/ultima8.h
index 51dd75aee6..bbf4ebe762 100644
--- a/engines/ultima/ultima8/ultima8.h
+++ b/engines/ultima/ultima8/ultima8.h
@@ -124,6 +124,7 @@ private:
uint32 _lastDown[HID_LAST+1];
bool _down[HID_LAST+1];
unsigned int _inversion;
+ bool _alertActive; //!< is intruder alert active (Crusader)
private:
/**
* Does engine deinitialization
@@ -225,6 +226,7 @@ public:
INTRINSIC(I_avatarCanCheat);
INTRINSIC(I_makeAvatarACheater);
INTRINSIC(I_closeItemGumps);
+ INTRINSIC(I_getAlertActive); // for Crusader
void setAvatarInStasis(bool stat) {
_avatarInStasis = stat;
@@ -248,6 +250,13 @@ public:
_showTouching = !_showTouching;
}
+ bool isAlertActive() const {
+ return _alertActive;
+ }
+ void setAlertActive(bool active) {
+ _alertActive = active;
+ }
+
uint32 getGameTimeInSeconds();
GameMapGump *getGameMapGump() {
diff --git a/engines/ultima/ultima8/usecode/remorse_intrinsics.h b/engines/ultima/ultima8/usecode/remorse_intrinsics.h
index 984751cf82..d699d9bdc6 100644
--- a/engines/ultima/ultima8/usecode/remorse_intrinsics.h
+++ b/engines/ultima/ultima8/usecode/remorse_intrinsics.h
@@ -30,335 +30,343 @@ namespace Ultima {
namespace Ultima8 {
// Crusader: No Remorse Intrinsics
+// Unknown function signatures were generate by the usecode disassembly
+// and looking at handling of SP and retval after function.
+// Most up-to-date version of unknown functions is in convert_usecode_crusader.h
Intrinsic RemorseIntrinsics[] = {
// 0x000
- 0,
- Item::I_getFrame,
- Item::I_setFrame,
- Item::I_getMapArray,
- Item::I_getStatus,
- Item::I_orStatus,
- 0,
- 0,
- 0,
- Item::I_getZ,
- 0,
- 0, // something with npcdata
- 0,
- 0,
- 0,
- 0,
+ Ultima8Engine::I_getAlertActive, // basically confirmed.. see eg, ALARM_NS::enterFastArea - set frame for alert siren based on value.
+ Item::I_getFrame, // ? int Intrinsic001(4 bytes)
+ Item::I_setFrame, // basically confirmed..
+ 0, //int16 Item::I_getSOMETHING_03(Item *), // used to get passcode highbyte from valueboxes, and called on MONSTER objects too
+ Item::I_getStatus, // probably - see usage in GATGUNEW::enterFastArea - always followed by an AND against a single bit
+ Item::I_orStatus, // probably - see usage in GATGUNEW::enterFastArea
+ 0, // void Intrinsic006(6 bytes)
+ 0, // ? byte Item::I_getSOMETHING_07(Item *)
+ 0, // ? byte Intrinsic008(4 bytes)
+ Item::I_getZ, // byte Intrinsic009(4 bytes) // probably, see PEPSIEW::use() variable names
+ 0, // void Intrinsic00A(4 bytes)
+ 0, // something with npcdata void Intrinsic00B(4 bytes)
+ 0, // void Intrinsic00C(2 bytes)
+ 0, // byte Intrinsic00D(6 bytes)
+ 0, // int Intrinsic00E(8 bytes)
+ 0, // based on TESTFLIC, appears to be I_playVideo(item*, char *vidname, int16 sizex, int16 sizey)
// 0x010
- Item::I_getQLo,
- 0,
- 0,
- Item::I_getX,
- Item::I_getY,
- 0, // something with sound?
- Item::I_getShape,
- 0,
- 0,
- 0,
- Item::I_setQLo,
- Item::I_popToCoords, // different than U8's?
- Item::I_andStatus,
- Item::I_create,
- 0,
- 0,
+ Item::I_getQLo, // Based on having same coff as 02B
+ 0, // int Intrinsic011(4 bytes)
+ 0, // void Intrinsic012(2 bytes)
+ Item::I_getX, //int Intrinsic013(4 bytes) // probably - see FREE::ordinal34
+ Item::I_getY, //int Intrinsic014(4 bytes) // probably - see FREE::ordinal34
+ 0, // Set something about items void Intrinsic015(6 bytes)
+ Item::I_getShape, // in STEAMBOX::func0A, is compared to 0x511 (the STEAM2 shape number) to determine direction
+ 0, // void Intrinsic017(8 bytes)
+ 0, // int16 Intrinsic018(4 bytes) // FIXME: Can get stuck in a loop calling this, waiting for some status?
+ 0, // byte Intrinsic019(14 bytes)
+ 0, // ? Item::I_setQLo, void Intrinsic01A(6 bytes)
+ 0, // ? Item::I_popToCoords, // different than U8's? int Intrinsic01B(void)
+ 0, // ? Item::I_andStatus, byte Intrinsic01C(4 bytes)
+ 0, // ? Item::I_create, int Intrinsic01D(4 bytes)
+ 0, // int Intrinsic01E(16 bytes)
+ Item::I_create, // probably - used in MISS1EGG creating keycards and NPCDEATH in creating blood spills
// 0x020
- 0,
- 0,
- Item::I_push,
- 0,
- Item::I_setShape, // different than U8's?
- Item::I_touch,
- Item::I_getQHi,
- 0,
- 0,
- 0,
- 0,
- Item::I_getQLo,
- 0,
- Item::I_setQHi,
- 0,
- 0,
+ Item::I_popToCoords, // void Intrinsic020(10 bytes)
+ 0, // void Intrinsic021(4 bytes)
+ 0, // ? Item::I_push, void Intrinsic022(4 bytes)
+ 0, // int Intrinsic023(void)
+ 0, // ? Item::I_setShape, // different than U8's? void Intrinsic024(6 bytes)
+ 0, // ? Item::I_touch, void Intrinsic025(4 bytes)
+ Item::I_getQHi, // int16 Intrinsic026(Item *), // guess, based on variable name in BOUNCBOX::gotHit
+ 0, // int Intrinsic027(14 bytes)
+ 0, // int Intrinsic028(12 bytes)
+ 0, // int Intrinsic029(void)
+ AudioProcess::I_playAmbientSFXCru, // Confirmed!
+ Item::I_getQLo, // int16 Intrinsic02B(4 bytes), // guess, based on variable name in BOUNCBOX::gotHit
+ 0, // byte Intrinsic02C(4 bytes)
+ 0, // ? Item::I_setQHi, void Intrinsic02D(6 bytes)
+ 0, // byte Intrinsic02E(12 bytes)
+ 0, // byte Intrinsic02F(10 bytes)
// 0x030
- Item::I_pop,
- Item::I_andStatus,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0, // something with sound?
- Item::I_getFamily,
- 0,
- 0,
- 0,
- 0,
+ 0, // ? Item::I_pop, void Intrinsic030(4 bytes)
+ 0, // ? Item::I_andStatus, void Intrinsic031(6 bytes)
+ 0, // void Intrinsic032(12 bytes)
+ 0, // int Intrinsic033(4 bytes)
+ 0, // void Intrinsic034(8 bytes)
+ 0, // int Intrinsic035(4 bytes)
+ 0, // void Intrinsic036(12 bytes)
+ 0, // int Intrinsic037(4 bytes)
+ 0, // void Intrinsic038(6 bytes)
+ 0, // int Intrinsic039(4 bytes)
+ 0, // something with sound? int Intrinsic03A(6 bytes)
+ 0, // ? Item::I_getFamily, void Intrinsic03B(6 bytes)
+ 0, // void Intrinsic03C(4 bytes)
+ 0, // void Intrinsic03D(4 bytes)
+ 0, // void Intrinsic03E(4 bytes)
+ 0, // void Intrinsic03F(4 bytes)
// 0x040
- 0,
- 0,
- 0,
- 0,
- Item::I_getQHi,
- 0,
- Item::I_getQHi,
- 0,
- Item::I_getQHi,
- 0,
- Item::I_getQHi,
- 0,
- Item::I_getQHi,
- 0,
- Item::I_getQHi,
- 0,
+ 0, // void Intrinsic040(8 bytes)
+ 0, // void Intrinsic041(2 bytes)
+ 0, // int Intrinsic042(6 bytes)
+ 0, // void Intrinsic043(6 bytes)
+ 0, // int Intrinsic044(6 bytes)
+ Item::I_getQHi, // based on same coff set as 026
+ 0, // int Intrinsic046(6 bytes)
+ Item::I_getQHi, // based on same coff set as 026
+ 0, // int Intrinsic048(6 bytes)
+ Item::I_getQHi, // based on same coff set as 026
+ 0, // int Intrinsic04A(6 bytes)
+ Item::I_getQHi, // based on same coff set as 026
+ 0, // int Intrinsic04C(6 bytes)
+ Item::I_getQHi, // based on same coff set as 026
+ 0, // int Intrinsic04E(6 bytes)
+ Item::I_getQHi, // based on same coff set as 026
// 0x050
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- Item::I_setFrame,
- 0,
- Item::I_legalCreateAtPoint,
- 0,
- 0,
- 0,
- 0,
- 0,
+ 0, // void Intrinsic050(4 bytes)
+ 0, // void Intrinsic051(4 bytes)
+ 0, // void Intrinsic052(6 bytes)
+ 0, // void Intrinsic053(6 bytes)
+ 0, // void Intrinsic054(6 bytes)
+ 0, // void Intrinsic055(6 bytes)
+ 0, // void Intrinsic056(2 bytes)
+ 0, // void Intrinsic057(4 bytes)
+ 0, // ? Item::I_setFrame, int Intrinsic058(6 bytes)
+ Item::I_setFrame, // based on same coff as 002
+ 0, // ? Item::I_legalCreateAtPoint, void Intrinsic05A(4 bytes)
+ Item::I_legalCreateAtPoint, // probably. see PEPSIEW::use
+ 0, // void Intrinsic05C(8 bytes)
+ 0, // void Intrinsic05D(void)
+ 0, // int16 Intrinsic05E(uint32, char *, int16 a, int16 b) // Play video (as texture? parameters like (150, 250, "MVA11A") and other mvas)
+ 0, // void Intrinsic05F(void)
// 0x060
- 0,
- 0,
- Item::I_legalCreateAtCoords,
- 0,
- Item::I_getQLo,
- Item::I_getNpcNum,
- 0,
- Item::I_andStatus,
- 0,
- 0,
- 0,
- Item::I_getNpcNum,
- Item::I_andStatus,
- 0,
- 0,
- 0,
+ 0, // void Intrinsic060(4 bytes)
+ 0, // void Intrinsic061(8 bytes)
+ 0, // void Intrinsic062(void)
+ 0, // void Intrinsic063(12 bytes)
+ 0, // ? Item::I_legalCreateAtCoords, void Intrinsic064(16 bytes)
+ 0, // ? Item::I_getNpcNum, int Intrinsic065(4 bytes)
+ Item::I_getQLo, // based on same coff set as 02B
+ 0, // ? Item::I_andStatus, void Intrinsic067(4 bytes)
+ Item::I_setQLo, // see VALUEBOX:ordinal20
+ 0, // void Intrinsic069(6 bytes)
+ 0, // void Intrinsic06A(10 bytes)
+ 0, // ? Item::I_getNpcNum, int16 Intrinsic06B(void)
+ 0, // ? Item::I_andStatus, void Intrinsic06C(4 bytes)
+ 0, // void Intrinsic06D(4 bytes)
+ 0, // void Intrinsic06E(6 bytes)
+ 0, // int Intrinsic06F(6 bytes)
// 0x070
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- Item::I_getQuality,
- Item::I_setQuality,
- Item::I_use, // different than U8's?
- 0,
- 0,
- 0,
- Item::I_getQLo,
- 0,
- 0,
+ 0, // int Intrinsic070(void)
+ 0, // void Intrinsic071(void)
+ 0, // void Intrinsic072(void)
+ 0, // void Intrinsic073(4 bytes)
+ 0, // void Intrinsic074(void)
+ 0, // void Intrinsic075(void)
+ 0, // void Intrinsic076(4 bytes)
+ 0, // ? Item::I_getQuality, void Intrinsic077(void)
+ 0, // ? Item::I_setQuality, void Intrinsic078(void)
+ 0, // ? Item::I_use, // different than U8's? void Intrinsic079(6 bytes)
+ 0, // void Intrinsic07A(void)
+ 0, // void Intrinsic07B(4 bytes)
+ 0, // void Intrinsic07C(4 bytes)
+ 0, // ? Item::I_getQLo, void Intrinsic07D(6 bytes)
+ 0, // void Intrinsic07E(4 bytes)
+ 0, // void Intrinsic07F(6 bytes)
// 0x080
- 0,
- 0,
- Item::I_getNpcNum,
- 0,
- 0,
- 0,
- 0,
- Item::I_getNpcNum,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
+ 0, // void Intrinsic080(4 bytes)
+ 0, // void Intrinsic081(4 bytes)
+ 0, // ? Item::I_getNpcNum, void Intrinsic082(4 bytes)
+ 0, // void Intrinsic083(6 bytes)
+ Item::I_getQLo, // based on same coff set as 02B
+ 0, // void Intrinsic085(4 bytes)
+ 0, // void Intrinsic086(void)
+ 0, // ? Item::I_getNpcNum, void Intrinsic087(void)
+ Item::I_setQHi, // void Intrinsic088(6 bytes) // setSomethingHighByte(something *, byte highbyte) (see VALUEBOX:ordinal20)
+ 0, // void Intrinsic089(4 bytes)
+ 0, // void Intrinsic08A(12 bytes)
+ 0, // void Intrinsic08B(4 bytes)
+ 0, // void Intrinsic08C(4 bytes)
+ 0, // void Intrinsic08D(12 bytes)
+ 0, // void Intrinsic08E(4 bytes)
+ 0, // void Intrinsic08F(void)
// 0x090
- 0,
- 0,
- Item::I_andStatus,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- Item::I_getQLo,
- Item::I_getUnkEggType,
- 0,
- 0,
- 0,
- 0,
+ 0, // void Intrinsic090(void)
+ 0, // void Intrinsic091(void)
+ 0, // ? Item::I_andStatus, void Intrinsic092(void)
+ 0, // void Intrinsic093(void)
+ 0, // UNUSEDInt0094()
+ 0, // int Intrinsic095(void)
+ 0, // void Intrinsic096(4 bytes)
+ 0, // void Intrinsic097(void)
+ 0, // void Intrinsic098(void)
+ 0, // void Intrinsic099(6 bytes)
+ 0, // ? Item::I_getQLo, void Intrinsic09A(void)
+ 0, // ? Item::I_getUnkEggType, void Intrinsic09B(2 bytes)
+ 0, // void Intrinsic09C(4 bytes)
+ 0, // void Intrinsic09D(2 bytes)
+ 0, // void Intrinsic09E(4 bytes)
+ 0, // void Intrinsic09F(10 bytes)
// 0x0A0
- 0,
- 0,
- 0,
- 0,
- 0,
- Item::I_getFamilyOfType,
- Item::I_getNpcNum,
- Item::I_getQLo,
- Item::I_getQHi,
- 0, // call usecode event B
- 0,
- Item::I_andStatus,
- Ultima8Engine::I_getCurrentTimerTick,
- 0,
- 0,
- 0,
+ 0, // void Intrinsic0A0(4 bytes)
+ Item::I_getQLo, // based on same coff set as 02B
+ 0, // void Intrinsic0A2(4 bytes)
+ 0, // void Intrinsic0A3(6 bytes)
+ 0, // int Intrinsic0A4(6 bytes)
+ 0, // ? Item::I_getFamilyOfType, int Intrinsic0A5(6 bytes)
+ 0, // ? Item::I_getNpcNum, void Intrinsic0A6(void)
+ 0, // ? Item::I_getQLo, void Intrinsic0A7(4 bytes)
+ 0, // ? Item::I_getQHi, void Intrinsic0A8(4 bytes)
+ 0, // call usecode event B void Intrinsic0A9(void)
+ 0, // void Intrinsic0AA(2 bytes)
+ 0, // ? Item::I_andStatus, int Intrinsic0AB(4 bytes)
+ 0, // ? Ultima8Engine::I_getCurrentTimerTick, void Intrinsic0AC(2 bytes)
+ 0, // void Intrinsic0AD(4 bytes)
+ Item::I_getQLo, // based on same coff set as 02B
+ Item::I_getQHi, // based on same coff set as 026
// 0x0B0
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- Item::I_getQHi,
- Item::I_andStatus,
- 0,
- Item::I_andStatus,
- 0,
- Item::I_andStatus,
- 0,
- 0,
- 0,
- 0,
+ 0, // void Intrinsic0B0(6 bytes)
+ 0, // void Intrinsic0B1(6 bytes)
+ 0, // void Intrinsic0B2(6 bytes)
+ Ultima8Engine::I_getCurrentTimerTick, // int32 Intrinsic0B3(void), probably, see FREE::ordinal32
+ 0, // void Intrinsic0B4(void)
+ 0, // void Intrinsic0B5(6 bytes)
+ 0, // ? Item::I_getQHi, void Intrinsic0B6(void)
+ 0, // ? Item::I_andStatus, void Intrinsic0B7(void)
+ 0, // int Intrinsic0B8(4 bytes)
+ 0, // ? Item::I_andStatus, void Intrinsic0B9(4 bytes)
+ 0, // void Intrinsic0BA(6 bytes)
+ 0, // ? Item::I_andStatus, int Intrinsic0BB(8 bytes)
+ 0, // int Intrinsic0BC(6 bytes)
+ 0, // void Intrinsic0BD(12 bytes)
+ Item::I_getQHi, // based on same coff set as 026
+ 0, // void Intrinsic0BF(6 bytes)
// 0x0C0
- 0,
- Item::I_getQHi,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
+ 0, // void Intrinsic0C0(12 bytes)
+ 0, // ? Item::I_getQHi, void Intrinsic0C1(6 bytes)
+ 0, // void Intrinsic0C2(12 bytes)
+ 0, // void Intrinsic0C3(6 bytes)
+ 0, // void Intrinsic0C4(2 bytes)
+ 0, // int Intrinsic0C5(6 bytes)
+ 0, // void Intrinsic0C6(14 bytes)
+ 0, // int Intrinsic0C7(6 bytes)
+ 0, // void Intrinsic0C8(12 bytes)
+ Item::I_getQHi, // based on same coff set as 026
+ 0, // int Intrinsic0CA(6 bytes)
+ 0, // void Intrinsic0CB(2 bytes)
+ 0, // int Intrinsic0CC(4 bytes)
+ 0, // void Intrinsic0CD(6 bytes)
+ 0, // void Intrinsic0CE(void)
+ 0, // void Intrinsic0CF(6 bytes)
// 0x0D0
- 0,
- Item::I_getQLo,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
+ 0, // void Intrinsic0D0(4 bytes)
+ 0, // UNUSEDInt00D1()
+ 0, // void Intrinsic0D2(void)
+ 0, // UNUSEDInt00D3()
+ 0, // void Intrinsic0D4(2 bytes)
+ 0, // void Intrinsic0D5(4 bytes)
+ 0, // int Intrinsic0D6(void)
+ 0, // void Intrinsic0D7(4 bytes)
+ 0, // void Intrinsic0D8(4 bytes)
+ Item::I_getQLo, // based on same coff set as 02B
+ 0, // void Intrinsic0DA(void)
+ 0, // void Intrinsic0DB(6 bytes)
+ 0, // int Intrinsic0DC(6 bytes)
+ 0, // void Intrinsic0DD(4 bytes)
+ 0, // void Intrinsic0DE(6 bytes)
+ 0, // void Intrinsic0DF(6 bytes)
// 0x0E0
- 0,
- 0,
- Item::I_andStatus,
- Item::I_getQLo,
- 0,
- 0,
- Item::I_popToContainer,
- 0,
- 0,
- Item::I_getQHi,
- 0,
- 0,
- Item::I_getQHi,
- Item::I_getQ,
- Item::I_setQ,
- 0,
+ 0, // void Intrinsic0E0(8 bytes)
+ 0, // void Intrinsic0E1(4 bytes)
+ 0, // ? Item::I_andStatus, void Intrinsic0E2(4 bytes)
+ 0, // ? Item::I_getQLo, void Intrinsic0E3(4 bytes)
+ 0, // void Intrinsic0E4(4 bytes)
+ 0, // void Intrinsic0E5(6 bytes)
+ 0, // ? Item::I_popToContainer, void Intrinsic0E6(6 bytes)
+ 0, // void Intrinsic0E7(4 bytes)
+ 0, // void Intrinsic0E8(6 bytes)
+ 0, // ? Item::I_getQHi, void Intrinsic0E9(6 bytes)
+ Item::I_getQLo, // based on same coff set as 02B
+ 0, // void Intrinsic0EB(void)
+ 0, // ? Item::I_getQHi, void Intrinsic0EC(6 bytes)
+ 0, // ? Item::I_getQ, void Intrinsic0ED(6 bytes)
+ 0, // ? Item::I_setQ, void Intrinsic0EE(void)
+ 0, // void Intrinsic0EF(4 bytes)
// 0x0F0
- 0,
- Item::I_getNpcNum,
- 0,
- 0,
- Item::I_getQHi,
- Item::I_andStatus,
- 0,
- 0,
- 0,
- 0,
- 0, // FA = integer to string
- Item::I_getNpcNum,
- Item::I_andStatus,
- Item::I_getNpcNum,
- 0,
- Item::I_isCrusTypeNPC,
+ Item::I_getQHi, // based on same coff set as 026
+ 0, // ? Item::I_getNpcNum, int Intrinsic0F1(6 bytes)
+ 0, // void Intrinsic0F2(6 bytes)
+ Item::I_getQHi, // based on same coff set as 026
+ 0, // ? Item::I_getQHi, void Intrinsic0F4(4 bytes)
+ 0, // ? Item::I_andStatus, void Intrinsic0F5(6 bytes)
+ 0, // void Intrinsic0F6(void)
+ 0, // void Intrinsic0F7(12 bytes)
+ 0, // void Intrinsic0F8(4 bytes)
+ 0, // void Intrinsic0F9(12 bytes)
+ 0, // FA = integer to string int Intrinsic0FA(6 bytes)
+ Item::I_getQHi, // based on same coff set as 026
+ 0, // ? Item::I_andStatus, void Intrinsic0FC(6 bytes)
+ 0, // ? Item::I_getNpcNum, int Intrinsic0FD(2 bytes)
+ 0, // void Intrinsic0FE(4 bytes)
+ UCMachine::I_numToStr, // same as 113 based on same coff set 0FF, 113, 126
// 0x100
- Item::I_andStatus,
- Item::I_getNpcNum,
- Item::I_andStatus,
- Item::I_getNpcNum,
- Item::I_andStatus,
- Item::I_getNpcNum,
- Item::I_andStatus,
- Item::I_getNpcNum,
- Item::I_andStatus,
- Item::I_getNpcNum,
- Item::I_andStatus,
- Item::I_getNpcNum,
- Item::I_andStatus,
- Item::I_getNpcNum,
- 0,
- Item::I_andStatus,
+ 0, // ? Item::I_andStatus, void Intrinsic100(4 bytes)
+ 0, // ? Item::I_getNpcNum, void Intrinsic101(6 bytes)
+ 0, // ? Item::I_andStatus, void Intrinsic102(4 bytes)
+ 0, // ? Item::I_getNpcNum, // byte Intrinsic103(uint16 shapenum),
+
+ 0, // ? Item::I_andStatus, void Intrinsic104(6 bytes)
+ 0, // ? Item::I_getNpcNum, void Intrinsic105(4 bytes)
+ 0, // ? Item::I_andStatus, void Intrinsic106(6 bytes)
+ 0, // ? Item::I_getNpcNum, void Intrinsic107(4 bytes)
+ 0, // ? Item::I_andStatus, void Intrinsic108(6 bytes)
+ 0, // ? Item::I_getNpcNum, void Intrinsic109(4 bytes)
+ 0, // ? Item::I_andStatus, void Intrinsic10A(6 bytes)
+ 0, // ? Item::I_getNpcNum, void Intrinsic10B(4 bytes)
+ 0, // ? Item::I_andStatus, void Intrinsic10C(6 bytes)
+ 0, // ? Item::I_getNpcNum, void Intrinsic10D(4 bytes)
+ 0, // void Intrinsic10E(6 bytes)
+ 0, // ? Item::I_andStatus, void Intrinsic10F(4 bytes)
// 0x110
- Item::I_getNpcNum,
- 0,
- Item::I_andStatus,
- 0,
- 0,
- Item::I_andStatus,
- Item::I_getTypeFlag,
- Item::I_getNpcNum,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- Item::I_getNpcNum,
+ 0, // ? Item::I_getNpcNum, void Intrinsic110(6 bytes)
+ 0, // int16 Intrinsic111(4 bytes)
+ 0, // ? Item::I_andStatus, byte Intrinsic112(4 bytes)
+ UCMachine::I_numToStr, // see VMAIL::func0A for example usage
+ 0, // void Intrinsic114(6 bytes)
+ 0, // ? Item::I_andStatus, int16 Intrinsic115(4 bytes)
+ 0, // ? Item::I_getTypeFlag, byte Intrinsic116(14 bytes)
+ 0, // ? Item::I_getNpcNum, void Intrinsic117(6 bytes)
+ 0, // int16 Intrinsic118(12 bytes)
+ 0, // void Intrinsic119(4 bytes)
+ 0, // void Intrinsic11A(6 bytes)
+ 0, // byte Intrinsic11B(6 bytes)
+ 0, // int16 Intrinsic11C(4 bytes)
+ 0, // int16 Intrinsic11D(12 bytes)
+ 0, // int16 Intrinsic11E(4 bytes)
+ 0, // ? Item::I_getNpcNum, byte Intrinsic11F(4 bytes)
// 0x120
- 0,
- 0,
- 0,
- 0,
- Item::I_andStatus,
- Item::I_getNpcNum,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- Item::I_getQHi,
+ 0, // void Intrinsic120(4 bytes)
+ 0, // int Intrinsic121(4 bytes)
+ 0, // int Intrinsic122(4 bytes)
+ 0, // void Intrinsic123(4 bytes)
+ 0, // ? Item::I_andStatus, void Intrinsic124(4 bytes)
+ 0, // ? Item::I_getNpcNum, void Intrinsic125(6 bytes)
+ UCMachine::I_numToStr, // same as 113 based on same coff set 0FF, 113, 126
+ 0, // int Intrinsic127(8 bytes)
+ 0, // void Intrinsic128(6 bytes) // maybe Item::andStatus?? see ITEM::ordinal22
+ 0, // void Intrinsic129(4 bytes)
+ 0, // void Intrinsic12A(4 bytes)
+ 0, // void Intrinsic12B(4 bytes)
+ 0, // int Intrinsic12C(6 bytes)
+ 0, // void Intrinsic12D(16 bytes)
+ 0, // int Intrinsic12E(4 bytes)
+ 0, // ? Item::I_getQHi, void Intrinsic12F(6 bytes)
// 0x130
- Item::I_andStatus,
- 0,
- 0,
- 0
+ 0, // ? Item::I_andStatus, void Intrinsic130(4 bytes)
+ 0, // void Intrinsic131(6 bytes)
+ 0, // void Intrinsic132(6 bytes)
+ Item::I_getQHi, // based on same coff set as 026
+ 0, // void Intrinsic134(2 bytes)
+ 0, // void UNUSEDInt135()
+ 0, // void UNUSEDInt136()
+ 0 // void UNUSEDInt137()
};
} // End of namespace Ultima8
diff --git a/engines/ultima/ultima8/usecode/uc_machine.cpp b/engines/ultima/ultima8/usecode/uc_machine.cpp
index b17bbcce21..cad57a7e59 100644
--- a/engines/ultima/ultima8/usecode/uc_machine.cpp
+++ b/engines/ultima/ultima8/usecode/uc_machine.cpp
@@ -38,6 +38,7 @@
#define INCLUDE_CONVERTUSECODEU8_WITHOUT_BRINGING_IN_FOLD
#include "ultima/ultima8/convert/u8/convert_usecode_u8.h"
+#include "ultima/ultima8/convert/crusader/convert_usecode_crusader.h"
#include "ultima/ultima8/world/actors/main_actor.h"
namespace Ultima {
@@ -88,7 +89,15 @@ UCMachine::UCMachine(Intrinsic *iset, unsigned int icount) {
// zero _globals
_globals = new BitSet(0x1000);
- _convUse = new ConvertUsecodeU8; //!...
+ if (GAME_IS_U8) {
+ _convUse = new ConvertUsecodeU8();
+ } else if (GAME_IS_REMORSE) {
+ _convUse = new ConvertUsecodeCrusader();
+ } else {
+ // TODO: Need a separate convertor for Regret
+ _convUse = new ConvertUsecodeCrusader();
+ }
+
loadIntrinsics(iset, icount); //!...
_listIDs = new idMan(1, 65534, 128);
@@ -348,12 +357,34 @@ void UCMachine::execProcess(UCProcess *p) {
//! TODO
uint16 arg_bytes = cs.readByte();
uint16 func = cs.readUint16LE();
- debug(MM_INFO, "calli\t\t%04Xh (%02Xh arg bytes) %s ", func, arg_bytes, _convUse->intrinsics()[func]);
+ debug(10, "calli\t\t%04Xh (%02Xh arg bytes) %s ", func, arg_bytes, _convUse->intrinsics()[func]);
// !constants
if (func >= _intrinsicCount || _intrinsics[func] == 0) {
+ Item *testItem = nullptr;
p->_temp32 = 0;
- perr << "Unhandled intrinsic \'" << _convUse->intrinsics()[func] << "\' (" << Std::hex << func << Std::dec << ") called" << Std::endl;
+
+ if (arg_bytes >= 4) {
+ // HACKHACKHACK to check what the argument is.
+ uint8 *args = new uint8[arg_bytes];
+ p->_stack.pop(args, arg_bytes);
+ p->_stack.addSP(-arg_bytes); // don't really pop the args
+ ARG_UC_PTR(iptr);
+ uint16 testItemId = ptrToObject(iptr);
+ testItem = getItem(testItemId);
+ }
+ perr << "Unhandled intrinsic << " << func << " \'" << _convUse->intrinsics()[func] << "\'? (";
+ if (testItem) {
+ perr << "item " << testItem->getObjId();
+ if (arg_bytes > 4)
+ perr << " + " << arg_bytes - 4 << " bytes";
+ } else {
+ perr << arg_bytes << " bytes";
+ }
+ perr << ") called" << Std::endl;
+ if (testItem) {
+ testItem->dumpInfo();
+ }
} else {
//!! hackish
if (_intrinsics[func] == UCMachine::I_dummyProcess ||
@@ -615,7 +646,7 @@ void UCMachine::execProcess(UCProcess *p) {
if (si16a != 0) {
p->_stack.push2(static_cast<uint16>(si16b / si16a));
} else {
- perr.Print("division by zero.\n");
+ perr.Print("0x20 division by zero.\n");
p->_stack.push2(0);
}
LOGPF(("div\n"));
@@ -629,7 +660,7 @@ void UCMachine::execProcess(UCProcess *p) {
if (si32a != 0) {
p->_stack.push4(static_cast<uint32>(si32b / si32a));
} else {
- perr.Print("division by zero.\n");
+ perr.Print("0x21 division by zero.\n");
p->_stack.push4(0);
}
LOGPF(("div\n"));
@@ -645,7 +676,7 @@ void UCMachine::execProcess(UCProcess *p) {
if (si16a != 0) {
p->_stack.push2(static_cast<uint16>(si16b % si16a));
} else {
- perr.Print("division by zero.\n");
+ perr.Print("0x22 division by zero.\n");
p->_stack.push2(0);
}
LOGPF(("mod\n"));
@@ -660,7 +691,7 @@ void UCMachine::execProcess(UCProcess *p) {
if (si32a != 0) {
p->_stack.push4(static_cast<uint32>(si32b % si32a));
} else {
- perr.Print("division by zero.\n");
+ perr.Print("0x23 division by zero.\n");
p->_stack.push4(0);
}
LOGPF(("mod long\n"));
@@ -1979,11 +2010,21 @@ void UCMachine::execProcess(UCProcess *p) {
error = true;
break;
- case 0x5B:
- case 0x5C: // debugging
- perr.Print("unhandled opcode %02X\n", opcode);
+ case 0x5B: {
+ ui16a = cs.readUint16LE(); // source line number
+ debug(10, "ignore debug opcode %02X: line offset %d", opcode, ui16a);
break;
-
+ }
+ case 0x5C: {
+ ui16a = cs.readUint16LE(); // source line number
+ char name[10] = {0};
+ for (int x = 0; x < 9; x++) {
+ // skip over class name and null terminator
+ name[x] = cs.readByte();
+ }
+ debug(10, "ignore debug opcode %02X: %s line offset %d", opcode, name, ui16a);
+ break;
+ }
default:
perr.Print("unhandled opcode %02X\n", opcode);
@@ -2144,7 +2185,7 @@ bool UCMachine::assignPointer(uint32 ptr, const uint8 *data, uint32 size) {
if (!proc) {
// segfault :-)
perr << "Trying to access stack of non-existent "
- << "process (_pid: " << segment << ")" << Std::endl;
+ << "process (pid: " << segment << ")" << Std::endl;
return false;
} else {
proc->_stack.assign(offset, data, size);
@@ -2181,7 +2222,7 @@ bool UCMachine::dereferencePointer(uint32 ptr, uint8 *data, uint32 size) {
if (!proc) {
// segfault :-)
perr << "Trying to access stack of non-existent "
- << "process (_pid: " << segment << ")" << Std::endl;
+ << "process (pid: " << segment << ")" << Std::endl;
return false;
} else {
Std::memcpy(data, proc->_stack.access(offset), size);
@@ -2220,7 +2261,7 @@ uint16 UCMachine::ptrToObject(uint32 ptr) {
if (!proc) {
// segfault :-)
perr << "Trying to access stack of non-existent "
- << "process (_pid: " << segment << ")" << Std::endl;
+ << "process (pid: " << segment << ")" << Std::endl;
return 0;
} else {
return proc->_stack.access2(offset);
diff --git a/engines/ultima/ultima8/world/item.cpp b/engines/ultima/ultima8/world/item.cpp
index e704b94579..cfb192a3e0 100644
--- a/engines/ultima/ultima8/world/item.cpp
+++ b/engines/ultima/ultima8/world/item.cpp
@@ -1049,20 +1049,21 @@ uint32 Item::callUsecodeEvent(uint32 event, const uint8 *args, int argsize) {
uint32 offset = u->get_class_event(class_id, event);
if (!offset) return 0; // event not found
-#ifdef DEBUG
- if (UCMachine::get_instance()->trace_event()) {
- pout.Print("Item: %d calling usecode event %d @ %04X:%04X\n",
- _objId, event, class_id, offset);
- }
-#endif
-
// FIXME: Disabled usecode except for Use events in crusader for now
if (GAME_IS_CRUSADER && event != 1) {
- warning("Cusader: not running event %d for item %d shape %d",
- event, _objId, _shape);
- return 0;
+ if (event != 15 ||
+ (_shape != 1098 && _shape != 1227 && _shape != 1297 && _shape != 1298 && _shape != 1274
+ && _shape != 1275 && _shape != 1301 && _shape != 1302
+ && _shape != 1290 && _shape != 809 && _shape != 73 && _shape != 447 && _shape != 470 && _shape != 336 && _shape != 33 && _shape != 1143 && _shape != 94 && _shape != 189 && _shape != 440 && _shape != 139 && _shape != 140 && _shape != 475 && _shape != 392 && _shape != 147 && _shape != 136)) { // run sounds for a few objects..
+ debug(6, "Cusader: not running event %d for item %d shape %d",
+ event, _objId, _shape);
+ return 0;
+ }
}
+ debug(6, "Item: %d (shape %d) calling usecode event %d @ %04X:%04X\n",
+ _objId, _shape, event, class_id, offset);
+
return callUsecode(static_cast<uint16>(class_id),
static_cast<uint16>(offset),
args, argsize);
@@ -2124,7 +2125,7 @@ uint32 Item::I_getStatus(const uint8 *args, unsigned int /*argsize*/) {
return item->getFlags();
}
-uint32 Item::I_orStatus(const uint8 *args, unsigned int /*argsize*/) {
+uint32 Item::I_orStatus(const uint8 *args, unsigned int argsize) {
ARG_ITEM_FROM_PTR(item);
ARG_UINT16(mask);
if (!item) return 0;
@@ -2133,7 +2134,7 @@ uint32 Item::I_orStatus(const uint8 *args, unsigned int /*argsize*/) {
return 0;
}
-uint32 Item::I_andStatus(const uint8 *args, unsigned int /*argsize*/) {
+uint32 Item::I_andStatus(const uint8 *args, unsigned int argsize) {
ARG_ITEM_FROM_PTR(item);
ARG_UINT16(mask);
if (!item) return 0;
Commit: ea1d415563921e57a6ca54f4e45af27395758b00
https://github.com/scummvm/scummvm/commit/ea1d415563921e57a6ca54f4e45af27395758b00
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-05-13T20:43:25+09:00
Commit Message:
ULTIMA8: Improve item dumping to include uc class
Changed paths:
engines/ultima/ultima8/world/item.cpp
diff --git a/engines/ultima/ultima8/world/item.cpp b/engines/ultima/ultima8/world/item.cpp
index cfb192a3e0..6202942e5b 100644
--- a/engines/ultima/ultima8/world/item.cpp
+++ b/engines/ultima/ultima8/world/item.cpp
@@ -83,7 +83,14 @@ Item::~Item() {
void Item::dumpInfo() const {
pout << "Item " << getObjId() << " (class "
<< GetClassType()._className << ", shape "
- << getShape() << ", " << getFrame() << ", (";
+ << getShape();
+
+ const char *ucname = GameData::get_instance()->getMainUsecode()->get_class_name(_shape);
+ if (ucname != nullptr) {
+ pout << " (uc:" << ucname << ")";
+ }
+
+ pout << ", " << getFrame() << ", (";
if (_parent) {
int32 gx, gy;
@@ -1049,8 +1056,7 @@ uint32 Item::callUsecodeEvent(uint32 event, const uint8 *args, int argsize) {
uint32 offset = u->get_class_event(class_id, event);
if (!offset) return 0; // event not found
- // FIXME: Disabled usecode except for Use events in crusader for now
- if (GAME_IS_CRUSADER && event != 1) {
+ /*if (GAME_IS_CRUSADER && event != 1) {
if (event != 15 ||
(_shape != 1098 && _shape != 1227 && _shape != 1297 && _shape != 1298 && _shape != 1274
&& _shape != 1275 && _shape != 1301 && _shape != 1302
@@ -1059,7 +1065,7 @@ uint32 Item::callUsecodeEvent(uint32 event, const uint8 *args, int argsize) {
event, _objId, _shape);
return 0;
}
- }
+ }*/
debug(6, "Item: %d (shape %d) calling usecode event %d @ %04X:%04X\n",
_objId, _shape, event, class_id, offset);
Commit: 8d262ad816a7d77b22e1a59aa4749514c10d8688
https://github.com/scummvm/scummvm/commit/8d262ad816a7d77b22e1a59aa4749514c10d8688
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-05-13T20:43:25+09:00
Commit Message:
ULTIMA8: Only show avatar tomb on U8
Changed paths:
engines/ultima/ultima8/world/actors/avatar_death_process.cpp
diff --git a/engines/ultima/ultima8/world/actors/avatar_death_process.cpp b/engines/ultima/ultima8/world/actors/avatar_death_process.cpp
index 863c133f59..f08e79d3b6 100644
--- a/engines/ultima/ultima8/world/actors/avatar_death_process.cpp
+++ b/engines/ultima/ultima8/world/actors/avatar_death_process.cpp
@@ -27,6 +27,7 @@
#include "ultima/ultima8/gumps/readable_gump.h"
#include "ultima/ultima8/games/game_data.h"
#include "ultima/ultima8/kernel/kernel.h"
+#include "ultima/ultima8/kernel/core_app.h"
#include "ultima/ultima8/gumps/main_menu_process.h"
#include "ultima/ultima8/gumps/gump_notify_process.h"
#include "ultima/ultima8/graphics/palette_manager.h"
@@ -64,15 +65,18 @@ void AvatarDeathProcess::run() {
PaletteManager *palman = PaletteManager::get_instance();
palman->untransformPalette(PaletteManager::Pal_Game);
- ReadableGump *gump = new ReadableGump(1, 27, 11,
- _TL_("HERE LIES*THE AVATAR*REST IN PEACE"));
- gump->InitGump(0);
- gump->setRelativePosition(Gump::CENTER);
- Process *gumpproc = gump->GetNotifyProcess();
-
Process *menuproc = new MainMenuProcess();
Kernel::get_instance()->addProcess(menuproc);
- menuproc->waitFor(gumpproc);
+
+ if (GAME_IS_U8) {
+ // TODO: What should this do in crusader?
+ ReadableGump *gump = new ReadableGump(1, 27, 11,
+ _TL_("HERE LIES*THE AVATAR*REST IN PEACE"));
+ gump->InitGump(0);
+ gump->setRelativePosition(Gump::CENTER);
+ Process *gumpproc = gump->GetNotifyProcess();
+ menuproc->waitFor(gumpproc);
+ }
// done
terminate();
Commit: 9f335c51738010af5141273930f568ddd5208070
https://github.com/scummvm/scummvm/commit/9f335c51738010af5141273930f568ddd5208070
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-05-13T20:43:25+09:00
Commit Message:
ULTIMA8: Fix debug output
Changed paths:
engines/ultima/ultima8/usecode/uc_machine.cpp
diff --git a/engines/ultima/ultima8/usecode/uc_machine.cpp b/engines/ultima/ultima8/usecode/uc_machine.cpp
index cad57a7e59..5a2fe2c4a9 100644
--- a/engines/ultima/ultima8/usecode/uc_machine.cpp
+++ b/engines/ultima/ultima8/usecode/uc_machine.cpp
@@ -367,8 +367,8 @@ void UCMachine::execProcess(UCProcess *p) {
if (arg_bytes >= 4) {
// HACKHACKHACK to check what the argument is.
uint8 *args = new uint8[arg_bytes];
- p->_stack.pop(args, arg_bytes);
- p->_stack.addSP(-arg_bytes); // don't really pop the args
+ p->_stack.pop(args, 4);
+ p->_stack.addSP(-4); // don't really pop the args
ARG_UC_PTR(iptr);
uint16 testItemId = ptrToObject(iptr);
testItem = getItem(testItemId);
Commit: 10a5829d48b5f8cf83dde8adddcbb4acd1739b25
https://github.com/scummvm/scummvm/commit/10a5829d48b5f8cf83dde8adddcbb4acd1739b25
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-05-13T20:43:25+09:00
Commit Message:
ULTIMA8: Add intrinsic to support crusder style SFX
Changed paths:
engines/ultima/ultima8/audio/audio_process.cpp
engines/ultima/ultima8/audio/audio_process.h
diff --git a/engines/ultima/ultima8/audio/audio_process.cpp b/engines/ultima/ultima8/audio/audio_process.cpp
index 64eedcb644..dbe2a09681 100644
--- a/engines/ultima/ultima8/audio/audio_process.cpp
+++ b/engines/ultima/ultima8/audio/audio_process.cpp
@@ -479,12 +479,12 @@ void AudioProcess::stopAllExceptSpeech() {
//
uint32 AudioProcess::I_playSFX(const uint8 *args, unsigned int argsize) {
- ARG_SINT16(_sfxNum);
+ ARG_SINT16(sfxNum);
- int16 _priority = 0x60;
+ int16 priority = 0x60;
if (argsize >= 4) {
ARG_SINT16(priority_);
- _priority = priority_;
+ priority = priority_;
}
ObjId objId = 0;
@@ -494,19 +494,19 @@ uint32 AudioProcess::I_playSFX(const uint8 *args, unsigned int argsize) {
}
AudioProcess *ap = AudioProcess::get_instance();
- if (ap) ap->playSFX(_sfxNum, _priority, objId, 0);
+ if (ap) ap->playSFX(sfxNum, priority, objId, 0);
else perr << "Error: No AudioProcess" << Std::endl;
return 0;
}
uint32 AudioProcess::I_playAmbientSFX(const uint8 *args, unsigned int argsize) {
- ARG_SINT16(_sfxNum);
+ ARG_SINT16(sfxNum);
- int16 _priority = 0x60;
+ int16 priority = 0x60;
if (argsize >= 4) {
ARG_SINT16(priority_);
- _priority = priority_;
+ priority = priority_;
}
ObjId objId = 0;
@@ -516,12 +516,29 @@ uint32 AudioProcess::I_playAmbientSFX(const uint8 *args, unsigned int argsize) {
}
AudioProcess *ap = AudioProcess::get_instance();
- if (ap) ap->playSFX(_sfxNum, _priority, objId, -1, true);
+ if (ap) ap->playSFX(sfxNum, priority, objId, -1, true);
else perr << "Error: No AudioProcess" << Std::endl;
return 0;
}
+uint32 AudioProcess::I_playSFXCru(const uint8 *args, unsigned int argsize) {
+ ARG_ITEM_FROM_PTR(item)
+ ARG_SINT16(sfxNum);
+
+ if (!item) {
+ warning("I_playSFXCru: Couldn't get item");
+ } else {
+ AudioProcess *ap = AudioProcess::get_instance();
+ if (ap)
+ ap->playSFX(sfxNum, 0x10, item->getObjId(), 0, true);
+ else
+ warning("I_playSFXCru Error: No AudioProcess");
+ }
+ return 0;
+}
+
+
uint32 AudioProcess::I_playAmbientSFXCru(const uint8 *args, unsigned int argsize) {
// Similar to I_playAmbientSFX, but the params are different.
ARG_ITEM_FROM_PTR(item)
diff --git a/engines/ultima/ultima8/audio/audio_process.h b/engines/ultima/ultima8/audio/audio_process.h
index 843b292399..bf19e482a0 100644
--- a/engines/ultima/ultima8/audio/audio_process.h
+++ b/engines/ultima/ultima8/audio/audio_process.h
@@ -76,6 +76,7 @@ public:
INTRINSIC(I_playSFX);
INTRINSIC(I_playAmbientSFX);
+ INTRINSIC(I_playSFXCru);
INTRINSIC(I_playAmbientSFXCru);
INTRINSIC(I_isSFXPlaying);
INTRINSIC(I_setVolumeSFX);
Commit: d8befc81251a6517bdf98f2c1413aacaf23239dc
https://github.com/scummvm/scummvm/commit/d8befc81251a6517bdf98f2c1413aacaf23239dc
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-05-13T20:43:25+09:00
Commit Message:
ULTIMA8: More remorse intrinsic decoding
Changed paths:
engines/ultima/ultima8/convert/crusader/convert_usecode_crusader.h
engines/ultima/ultima8/usecode/remorse_intrinsics.h
diff --git a/engines/ultima/ultima8/convert/crusader/convert_usecode_crusader.h b/engines/ultima/ultima8/convert/crusader/convert_usecode_crusader.h
index 4333f0a20a..5e704d9c08 100644
--- a/engines/ultima/ultima8/convert/crusader/convert_usecode_crusader.h
+++ b/engines/ultima/ultima8/convert/crusader/convert_usecode_crusader.h
@@ -89,12 +89,12 @@ const char* const ConvertUsecodeCrusader::_intrinsics[] = {
"void Intrinsic012(2 bytes)",
"int16 Item::getX(Item *)",
"int16 Item::getY(Item *)",
- "void Intrinsic015(Item *, uint16 unk)",
+ "void AudioProcess::I_playSFXCru(Item *, uint16 sfxnum)",
"int16 Item::I_getShape(Item *)", // in STEAMBOX::func0A, is compared to 0x511 (the STEAM2 shape number) to determine direction
"void Intrinsic017(8 bytes)",
"int16 Intrinsic018(4 bytes not Item *)",
- "byte Intrinsic019(14 bytes)",
- "void Intrinsic01A(6 bytes)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "byte Item::I_legalCreateAtCoords(Item *, int16 shapeno, int16 frame, int16 x, int16 y, int16 z)", // probably, see usage in DOOR2::ordinal37
+ "void Item::I_andStatus(Item *, uint16 status)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132. Always associated with a bitwise-not or bitmask
"int16 Intrinsic01B(void)",
"byte Intrinsic01C(4 bytes)", // same coff as 112, 121
"int16 Intrinsic01D(4 bytes)", // part of same coff set 01D, 05A, 0B9, 0D7, 0E4, 124
@@ -105,7 +105,7 @@ const char* const ConvertUsecodeCrusader::_intrinsics[] = {
"void Intrinsic021(4 bytes)", // part of same coff set 021, 060, 073, 0A0, 0A8, 0D8, 0E7, 135
"void Intrinsic022(Item *)",
"int16 Intrinsic023(void)",
- "void Intrinsic024(6 bytes)",
+ "void Intrinsic024(Item *, int16 shapeno)", // maybe setShape?
"void Intrinsic025(4 bytes)",
"int16 Item::I_getQHi(Item *)", // guess, based on variable name in BOUNCBOX::gotHit
"int16 Intrinsic027(14 bytes)",
@@ -114,12 +114,12 @@ const char* const ConvertUsecodeCrusader::_intrinsics[] = {
"void AudioProcess::I_playAmbientSFXCru(Item *, sndno)",
"int16 Item::I_getQLo(Item *)", // guess, based on variable name in BOUNCBOX::gotHit
"byte Intrinsic02C(4 bytes)",
- "void Item::I_setSOMETHING_2D(Item *, uint16 unk)",
+ "void Item::I_setQHi(Item *, uint16 unk)", // probably setQHi, see usage in FREE::ordinal2E where object position is copied
"byte Intrinsic02E(Item *, 8 bytes)",
"byte Intrinsic02F(10 bytes)",
// 0030
"void Intrinsic030(4 bytes)",
- "void Item::I_setSOMETHING_31(Item *, uint16 unk)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "void Item::I_andStatus(Item *, uint16 status)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
"void Intrinsic032(12 bytes)",
"byte Intrinsic033(4 bytes)",
"int16 Intrinsic034(8 bytes)",
@@ -129,7 +129,7 @@ const char* const ConvertUsecodeCrusader::_intrinsics[] = {
"void Intrinsic038(Item *, int16)",
"byte Intrinsic039(4 bytes)", // same coff as 122, 12E
"byte Intrinsic03A(Item *, int16 unk)",
- "void Intrinsic03B(6 bytes)",
+ "void Item::I_setQLo(Item *, int16 qlo)", // probably setQLo, see usage in FREE::ordinal2E where object position is copied
"int16 Intrinsic03C(4 bytes)",
"void Intrinsic03D(4 bytes)",
"void Intrinsic03E(4 bytes)",
@@ -163,7 +163,7 @@ const char* const ConvertUsecodeCrusader::_intrinsics[] = {
"byte Item::I_doSOMETHING_58(Item *, uint16 unk)",
"void Item::I_setFrame(Item *, frame)", // based on same coff as 002
"int16 Intrinsic05A(4 bytes)", // part of same coff set 01D, 05A, 0B9, 0D7, 0E4, 124
- "byte Item::I_legalCreateAtPoint(Item *, int16 shape, int16 frame, Item *)", // I_legalCreateAtPoint ?? see PEPSIEW::use
+ "byte Item::I_legalCreateAtPoint(Item *, int16 shape, int16 frame, Item *)", // see PEPSIEW::use
"void Intrinsic05C(8 bytes)",
"void Intrinsic05D(void)",
"int16 Intrinsic05E(uint32, char *, int16 a, int16 b)", // Play video (as texture? parameters like (150, 250, "MVA11A") and other mvas)
@@ -178,12 +178,12 @@ const char* const ConvertUsecodeCrusader::_intrinsics[] = {
"int16 Item::I_getQLo(Item *)", // same as 02B based on same coff set 010, 02B, 066, 084, 0A1, 0AE, 0D9, 0EA
"int16 Intrinsic067(4 bytes)", // part of same coff set 067, 06D, 089, 08E, 0AD, 0F8, 100, 102, 105, 107, 109, 10B, 10D, 10F, 111, 115, 11C, 123, 129
"void Item::I_setQLo(Item *, uint16 qlow)", // probably, see VALUEBOX::ordinal20
- "void Intrinsic069(6 bytes)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "void Item::I_andStatus(Item *, uint16 status)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
"void Intrinsic06A(10 bytes)",
"int16 Intrinsic06B(void)",
"void Intrinsic06C(sometimes Item *)", // TODO: when param not item, what is it?
"int16 Intrinsic06D(4 bytes)", // part of same coff set 067, 06D, 089, 08E, 0AD, 0F8, 100, 102, 105, 107, 109, 10B, 10D, 10F, 111, 115, 11C, 123, 129
- "void Intrinsic06E(Item *, int16 unk)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "void Item::I_andStatus(Item *, uint16 status)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
"byte Intrinsic06F(6 bytes)",
// 0070
"byte Intrinsic070(void)",
@@ -211,7 +211,7 @@ const char* const ConvertUsecodeCrusader::_intrinsics[] = {
"void Intrinsic085(4 bytes)",
"int16 Intrinsic086(void)",
"int16 Intrinsic087(void)",
- "void Item::I_setQHi(Item *, uint16 qhi)",
+ "void Item::I_setQHi(Item *, uint16 qhi)", // slightly suspicious of this one.. see VALUEBOX:ordinal20
"int16 Intrinsic089(4 bytes)", // part of same coff set 067, 06D, 089, 08E, 0AD, 0F8, 100, 102, 105, 107, 109, 10B, 10D, 10F, 111, 115, 11C, 123, 129
"void Intrinsic08A(12 bytes)",
"int16 Intrinsic08B(4 bytes)",
@@ -229,7 +229,7 @@ const char* const ConvertUsecodeCrusader::_intrinsics[] = {
"int16 Intrinsic096(4 bytes)",
"void Intrinsic097(void)",
"void Intrinsic098(void)",
- "void Intrinsic099(6 bytes)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "void Item::I_andStatus(Item *, uint16 status)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
"void Intrinsic09A(void)",
"int16 Intrinsic09B(2 bytes)",
"int16 Intrinsic09C(4 bytes)",
@@ -256,7 +256,7 @@ const char* const ConvertUsecodeCrusader::_intrinsics[] = {
// 00B0
"int16 Intrinsic0B0(6 bytes)",
"int16 Intrinsic0B1(6 bytes)",
- "void Item::I_setSOMETHING_B2(Item *, uint16 unk)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "void Item::I_andStatus(Item *, uint16 status)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
"int32 I_getCurrentTimerTick(void)",
"void Intrinsic0B4(void)",
"int16 Intrinsic0B5(6 bytes)",
@@ -269,12 +269,12 @@ const char* const ConvertUsecodeCrusader::_intrinsics[] = {
"byte Intrinsic0BC(6 bytes)", // part of same coff set 044, 046, 048, 04A, 04C, 04E, 0A5, 0BC, 0C5, 0DC, 0F1, 0FA, 12C
"int16 Intrinsic0BD(12 bytes)", // part of same coff set 028, 08D, 0BD, 0C0, 0C2, 0C8, 0F7, 0F9, 118, 11D
"int16 Item::I_getQHi(Item *)", // same as 026 based on same coff set 026, 045, 047, 049, 04B, 04D, 04F, 0AF, 0BE, 0C9, 0F0, 0F3, 0FB, 133
- "void Intrinsic0BF(6 bytes)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "void Item::I_andStatus(Item *, uint16 status)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
// 00C0
"int16 Intrinsic0C0(12 bytes)", // part of same coff set 028, 08D, 0BD, 0C0, 0C2, 0C8, 0F7, 0F9, 118, 11D
- "void Intrinsic0C1(6 bytes)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "void Item::I_andStatus(Item *, uint16 status)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
"int16 Intrinsic0C2(12 bytes)", // part of same coff set 028, 08D, 0BD, 0C0, 0C2, 0C8, 0F7, 0F9, 118, 11D
- "void Intrinsic0C3(6 bytes)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "void Item::I_andStatus(Item *, int16 status)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
"int16 Intrinsic0C4(2 bytes)",
"byte Intrinsic0C5(6 bytes)",
"void Intrinsic0C6(14 bytes)",
@@ -314,13 +314,13 @@ const char* const ConvertUsecodeCrusader::_intrinsics[] = {
"void Intrinsic0E6(6 bytes)",
"void Intrinsic0E7(4 bytes)", // part of same coff set 021, 060, 073, 0A0, 0A8, 0D8, 0E7, 135
"int16 Intrinsic0E8(6 bytes)",
- "void Intrinsic0E9(6 bytes)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "void Item::I_andStatus(Item *, int16 status)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
"int16 Item::I_getQLo(Item *)", // same as 02B based on same coff set 010, 02B, 066, 084, 0A1, 0AE, 0D9, 0EA
"int16 Intrinsic0EB(void)",
"void Intrinsic0EC(6 bytes)",
"void Intrinsic0ED(6 bytes)",
"void Intrinsic0EE(void)",
- "int16 Intrinsic0EF(4 bytes)",
+ "int16 Intrinsic0EF(4 bytes not Item *)",
// 00F0
"int16 Item::I_getQHi(Item *)", // same as 026 based on same coff set 026, 045, 047, 049, 04B, 04D, 04F, 0AF, 0BE, 0C9, 0F0, 0F3, 0FB, 133
"byte Intrinsic0F1(6 bytes)", // part of same coff set 044, 046, 048, 04A, 04C, 04E, 0A5, 0BC, 0C5, 0DC, 0F1, 0FA, 12C
@@ -334,39 +334,39 @@ const char* const ConvertUsecodeCrusader::_intrinsics[] = {
"int16 Intrinsic0F9(12 bytes)", // part of same coff set 028, 08D, 0BD, 0C0, 0C2, 0C8, 0F7, 0F9, 118, 11D
"byte Intrinsic0FA(6 bytes)", // part of same coff set 044, 046, 048, 04A, 04C, 04E, 0A5, 0BC, 0C5, 0DC, 0F1, 0FA, 12C
"int16 Item::I_getQHi(Item *)", // same as 026 based on same coff set 026, 045, 047, 049, 04B, 04D, 04F, 0AF, 0BE, 0C9, 0F0, 0F3, 0FB, 133
- "void Intrinsic0FC(6 bytes)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "void Item::I_andStatus(Item *, int16 status)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
"byte Intrinsic0FD(2 bytes)",
"void Intrinsic0FE(4 bytes)",
"int16 UCMachine::I_numToStr(int16 num)", // same as 113 based on same coff set 0FF, 113, 126
// 0100
"int16 Intrinsic100(4 bytes)", // part of same coff set 067, 06D, 089, 08E, 0AD, 0F8, 100, 102, 105, 107, 109, 10B, 10D, 10F, 111, 115, 11C, 123, 129
- "void Intrinsic101(6 bytes)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "void Item::I_andStatus(Item *, int16 status)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
"int16 Intrinsic102(4 bytes)", // part of same coff set 067, 06D, 089, 08E, 0AD, 0F8, 100, 102, 105, 107, 109, 10B, 10D, 10F, 111, 115, 11C, 123, 129
"byte Intrinsic103(uint16 shapenum)",
- "void Intrinsic104(6 bytes)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "void Item::I_andStatus(Item *, int16 status)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
"int16 Intrinsic105(4 bytes)", // part of same coff set 067, 06D, 089, 08E, 0AD, 0F8, 100, 102, 105, 107, 109, 10B, 10D, 10F, 111, 115, 11C, 123, 129
- "void Intrinsic106(6 bytes)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "void Item::I_andStatus(Item *, int16 status)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
"int16 Intrinsic107(4 bytes)", // part of same coff set 067, 06D, 089, 08E, 0AD, 0F8, 100, 102, 105, 107, 109, 10B, 10D, 10F, 111, 115, 11C, 123, 129
- "void Intrinsic108(6 bytes)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "void Item::I_andStatus(Item *, int16 status)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
"int16 Intrinsic109(4 bytes)", // part of same coff set 067, 06D, 089, 08E, 0AD, 0F8, 100, 102, 105, 107, 109, 10B, 10D, 10F, 111, 115, 11C, 123, 129
- "void Intrinsic10A(6 bytes)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "void Item::I_andStatus(Item *, int16 status)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
"int16 Intrinsic10B(4 bytes)", // part of same coff set 067, 06D, 089, 08E, 0AD, 0F8, 100, 102, 105, 107, 109, 10B, 10D, 10F, 111, 115, 11C, 123, 129
- "void Intrinsic10C(6 bytes)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "void Item::I_andStatus(Item *, int16 status)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
"int16 Intrinsic10D(4 bytes)", // part of same coff set 067, 06D, 089, 08E, 0AD, 0F8, 100, 102, 105, 107, 109, 10B, 10D, 10F, 111, 115, 11C, 123, 129
- "void Intrinsic10E(6 bytes)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "void Item::I_andStatus(Item *, int16 status)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
"int16 Intrinsic10F(4 bytes)", // part of same coff set 067, 06D, 089, 08E, 0AD, 0F8, 100, 102, 105, 107, 109, 10B, 10D, 10F, 111, 115, 11C, 123, 129
// 0110
- "void Intrinsic110(6 bytes)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "void Item::I_andStatus(Item *, int16 status)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
"int16 Item::I_getSOMETHING_111(Item *)", // used to get passcode lowbyte from valueboxes.. // part of same coff set 067, 06D, 089, 08E, 0AD, 0F8, 100, 102, 105, 107, 109, 10B, 10D, 10F, 111, 115, 11C, 123, 129
"byte Intrinsic112(4 bytes)", // same coff as 01C, 121
"int16 UCMachine::I_numToStr(int16 num)", // based on VMAIL::func0A example usage
- "void Intrinsic114(6 bytes)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "void Item::I_andStatus(Item *, int16 status)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
"int16 Item::I_getSOMETHING_115(Item *)", // part of same coff set 067, 06D, 089, 08E, 0AD, 0F8, 100, 102, 105, 107, 109, 10B, 10D, 10F, 111, 115, 11C, 123, 129
"byte Intrinsic116(14 bytes)",
- "void Intrinsic117(6 bytes)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "void Item::I_andStatus(Item *, int16 status)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
"int16 Intrinsic118(12 bytes)", // part of same coff set 028, 08D, 0BD, 0C0, 0C2, 0C8, 0F7, 0F9, 118, 11D
"void Intrinsic119(4 bytes)", // same coff as 08C, 12A
- "void Intrinsic11A(6 bytes)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "void Item::I_andStatus(Item *, int16 status)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
"byte Intrinsic11B(6 bytes)",
"int16 Intrinsic11C(4 bytes)", // part of same coff set 067, 06D, 089, 08E, 0AD, 0F8, 100, 102, 105, 107, 109, 10B, 10D, 10F, 111, 115, 11C, 123, 129
"int16 Intrinsic11D(12 bytes)", // part of same coff set 028, 08D, 0BD, 0C0, 0C2, 0C8, 0F7, 0F9, 118, 11D
@@ -381,7 +381,7 @@ const char* const ConvertUsecodeCrusader::_intrinsics[] = {
"void Intrinsic125(6 bytes)", // same coff as 07F, 0BA
"int16 UCMachine::I_numToStr(int16 num)", // same as 113 based on same coff set 0FF, 113, 126
"byte Intrinsic127(8 bytes)",
- "void Intrinsic128(6 bytes)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "void Item::I_andStatus(Item *, int16 status)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
"int16 Intrinsic129(4 bytes)", // part of same coff set 067, 06D, 089, 08E, 0AD, 0F8, 100, 102, 105, 107, 109, 10B, 10D, 10F, 111, 115, 11C, 123, 129
"void Intrinsic12A(4 bytes)", // same coff as 08C, 119
"int16 Intrinsic12B(4 bytes)", // same coff as 11E
@@ -392,7 +392,7 @@ const char* const ConvertUsecodeCrusader::_intrinsics[] = {
// 0130
"void Intrinsic130(4 bytes)", // same coff as 07B
"void Intrinsic131(6 bytes)", // part of same coff set 055, 07D, 0CD, 0DB, 0F2, 131
- "void Intrinsic132(6 bytes)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
+ "void Item::I_andStatus(Item *, int16 status)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
"int16 Item::I_getQHi(Item *)", // same as 026 based on same coff set 026, 045, 047, 049, 04B, 04D, 04F, 0AF, 0BE, 0C9, 0F0, 0F3, 0FB, 133
"void Intrinsic134(2 bytes)",
"void UNUSEDInt135(4 bytes)", // part of same coff set 021, 060, 073, 0A0, 0A8, 0D8, 0E7, 135
diff --git a/engines/ultima/ultima8/usecode/remorse_intrinsics.h b/engines/ultima/ultima8/usecode/remorse_intrinsics.h
index d699d9bdc6..3302d779f9 100644
--- a/engines/ultima/ultima8/usecode/remorse_intrinsics.h
+++ b/engines/ultima/ultima8/usecode/remorse_intrinsics.h
@@ -38,7 +38,7 @@ Intrinsic RemorseIntrinsics[] = {
Ultima8Engine::I_getAlertActive, // basically confirmed.. see eg, ALARM_NS::enterFastArea - set frame for alert siren based on value.
Item::I_getFrame, // ? int Intrinsic001(4 bytes)
Item::I_setFrame, // basically confirmed..
- 0, //int16 Item::I_getSOMETHING_03(Item *), // used to get passcode highbyte from valueboxes, and called on MONSTER objects too
+ 0, //int16 Item::I_getSOMETHING_03(Item *), // get passcode highbyte from valueboxes??, and called on MONSTER objects too
Item::I_getStatus, // probably - see usage in GATGUNEW::enterFastArea - always followed by an AND against a single bit
Item::I_orStatus, // probably - see usage in GATGUNEW::enterFastArea
0, // void Intrinsic006(6 bytes)
@@ -57,15 +57,15 @@ Intrinsic RemorseIntrinsics[] = {
0, // void Intrinsic012(2 bytes)
Item::I_getX, //int Intrinsic013(4 bytes) // probably - see FREE::ordinal34
Item::I_getY, //int Intrinsic014(4 bytes) // probably - see FREE::ordinal34
- 0, // Set something about items void Intrinsic015(6 bytes)
+ AudioProcess::I_playSFXCru, // pretty sure, see SWITCH::ordinal21 which plays various sfx related to access status
Item::I_getShape, // in STEAMBOX::func0A, is compared to 0x511 (the STEAM2 shape number) to determine direction
0, // void Intrinsic017(8 bytes)
0, // int16 Intrinsic018(4 bytes) // FIXME: Can get stuck in a loop calling this, waiting for some status?
- 0, // byte Intrinsic019(14 bytes)
- 0, // ? Item::I_setQLo, void Intrinsic01A(6 bytes)
- 0, // ? Item::I_popToCoords, // different than U8's? int Intrinsic01B(void)
- 0, // ? Item::I_andStatus, byte Intrinsic01C(4 bytes)
- 0, // ? Item::I_create, int Intrinsic01D(4 bytes)
+ Item::I_legalCreateAtCoords, // byte Intrinsic019(14 bytes), probably, see usage in DOOR2::ordinal37
+ Item::I_andStatus, // void Intrinsic01A(6 bytes)
+ 0, // // different than U8's? int Intrinsic01B(void)
+ 0, // byte Intrinsic01C(4 bytes)
+ 0, // int Intrinsic01D(4 bytes)
0, // int Intrinsic01E(16 bytes)
Item::I_create, // probably - used in MISS1EGG creating keycards and NPCDEATH in creating blood spills
// 0x020
@@ -82,12 +82,12 @@ Intrinsic RemorseIntrinsics[] = {
AudioProcess::I_playAmbientSFXCru, // Confirmed!
Item::I_getQLo, // int16 Intrinsic02B(4 bytes), // guess, based on variable name in BOUNCBOX::gotHit
0, // byte Intrinsic02C(4 bytes)
- 0, // ? Item::I_setQHi, void Intrinsic02D(6 bytes)
+ Item::I_setQHi, // ? Item::I_setQHi, void Intrinsic02D(6 bytes) -- see usage in FREE::ordinal2E where object position is also copied
0, // byte Intrinsic02E(12 bytes)
0, // byte Intrinsic02F(10 bytes)
// 0x030
0, // ? Item::I_pop, void Intrinsic030(4 bytes)
- 0, // ? Item::I_andStatus, void Intrinsic031(6 bytes)
+ Item::I_andStatus, // void Intrinsic031(6 bytes)
0, // void Intrinsic032(12 bytes)
0, // int Intrinsic033(4 bytes)
0, // void Intrinsic034(8 bytes)
@@ -96,8 +96,8 @@ Intrinsic RemorseIntrinsics[] = {
0, // int Intrinsic037(4 bytes)
0, // void Intrinsic038(6 bytes)
0, // int Intrinsic039(4 bytes)
- 0, // something with sound? int Intrinsic03A(6 bytes)
- 0, // ? Item::I_getFamily, void Intrinsic03B(6 bytes)
+ 0, // something with sound maybe? int Intrinsic03A(6 bytes)
+ Item::I_setQLo, // probably setQLo, see usage in FREE::ordinal2E where object position is copied void Intrinsic03B(6 bytes)
0, // void Intrinsic03C(4 bytes)
0, // void Intrinsic03D(4 bytes)
0, // void Intrinsic03E(4 bytes)
@@ -146,12 +146,12 @@ Intrinsic RemorseIntrinsics[] = {
Item::I_getQLo, // based on same coff set as 02B
0, // ? Item::I_andStatus, void Intrinsic067(4 bytes)
Item::I_setQLo, // see VALUEBOX:ordinal20
- 0, // void Intrinsic069(6 bytes)
+ Item::I_andStatus, // void Intrinsic069(6 bytes)
0, // void Intrinsic06A(10 bytes)
0, // ? Item::I_getNpcNum, int16 Intrinsic06B(void)
0, // ? Item::I_andStatus, void Intrinsic06C(4 bytes)
0, // void Intrinsic06D(4 bytes)
- 0, // void Intrinsic06E(6 bytes)
+ Item::I_andStatus, // void Intrinsic06E(6 bytes)
0, // int Intrinsic06F(6 bytes)
// 0x070
0, // int Intrinsic070(void)
@@ -197,7 +197,7 @@ Intrinsic RemorseIntrinsics[] = {
0, // void Intrinsic096(4 bytes)
0, // void Intrinsic097(void)
0, // void Intrinsic098(void)
- 0, // void Intrinsic099(6 bytes)
+ Item::I_andStatus, // void Intrinsic099(6 bytes)
0, // ? Item::I_getQLo, void Intrinsic09A(void)
0, // ? Item::I_getUnkEggType, void Intrinsic09B(2 bytes)
0, // void Intrinsic09C(4 bytes)
@@ -224,7 +224,7 @@ Intrinsic RemorseIntrinsics[] = {
// 0x0B0
0, // void Intrinsic0B0(6 bytes)
0, // void Intrinsic0B1(6 bytes)
- 0, // void Intrinsic0B2(6 bytes)
+ Item::I_andStatus, // void Intrinsic0B2(6 bytes)
Ultima8Engine::I_getCurrentTimerTick, // int32 Intrinsic0B3(void), probably, see FREE::ordinal32
0, // void Intrinsic0B4(void)
0, // void Intrinsic0B5(6 bytes)
@@ -237,12 +237,12 @@ Intrinsic RemorseIntrinsics[] = {
0, // int Intrinsic0BC(6 bytes)
0, // void Intrinsic0BD(12 bytes)
Item::I_getQHi, // based on same coff set as 026
- 0, // void Intrinsic0BF(6 bytes)
+ Item::I_andStatus, // void Intrinsic0BF(6 bytes)
// 0x0C0
0, // void Intrinsic0C0(12 bytes)
- 0, // ? Item::I_getQHi, void Intrinsic0C1(6 bytes)
+ Item::I_andStatus, // void Intrinsic0C1(6 bytes)
0, // void Intrinsic0C2(12 bytes)
- 0, // void Intrinsic0C3(6 bytes)
+ Item::I_andStatus, // void Intrinsic0C3(6 bytes)
0, // void Intrinsic0C4(2 bytes)
0, // int Intrinsic0C5(6 bytes)
0, // void Intrinsic0C6(14 bytes)
@@ -282,7 +282,7 @@ Intrinsic RemorseIntrinsics[] = {
0, // ? Item::I_popToContainer, void Intrinsic0E6(6 bytes)
0, // void Intrinsic0E7(4 bytes)
0, // void Intrinsic0E8(6 bytes)
- 0, // ? Item::I_getQHi, void Intrinsic0E9(6 bytes)
+ Item::I_andStatus, // void Intrinsic0E9(6 bytes)
Item::I_getQLo, // based on same coff set as 02B
0, // void Intrinsic0EB(void)
0, // ? Item::I_getQHi, void Intrinsic0EC(6 bytes)
@@ -302,40 +302,40 @@ Intrinsic RemorseIntrinsics[] = {
0, // void Intrinsic0F9(12 bytes)
0, // FA = integer to string int Intrinsic0FA(6 bytes)
Item::I_getQHi, // based on same coff set as 026
- 0, // ? Item::I_andStatus, void Intrinsic0FC(6 bytes)
+ Item::I_andStatus, // void Intrinsic0FC(6 bytes)
0, // ? Item::I_getNpcNum, int Intrinsic0FD(2 bytes)
0, // void Intrinsic0FE(4 bytes)
UCMachine::I_numToStr, // same as 113 based on same coff set 0FF, 113, 126
// 0x100
0, // ? Item::I_andStatus, void Intrinsic100(4 bytes)
- 0, // ? Item::I_getNpcNum, void Intrinsic101(6 bytes)
+ Item::I_andStatus, // ? Item::I_getNpcNum, void Intrinsic101(6 bytes)
0, // ? Item::I_andStatus, void Intrinsic102(4 bytes)
0, // ? Item::I_getNpcNum, // byte Intrinsic103(uint16 shapenum),
- 0, // ? Item::I_andStatus, void Intrinsic104(6 bytes)
+ Item::I_andStatus, // ? Item::I_andStatus, void Intrinsic104(6 bytes)
0, // ? Item::I_getNpcNum, void Intrinsic105(4 bytes)
- 0, // ? Item::I_andStatus, void Intrinsic106(6 bytes)
+ Item::I_andStatus, // ? Item::I_andStatus, void Intrinsic106(6 bytes)
0, // ? Item::I_getNpcNum, void Intrinsic107(4 bytes)
- 0, // ? Item::I_andStatus, void Intrinsic108(6 bytes)
+ Item::I_andStatus, // ? Item::I_andStatus, void Intrinsic108(6 bytes)
0, // ? Item::I_getNpcNum, void Intrinsic109(4 bytes)
- 0, // ? Item::I_andStatus, void Intrinsic10A(6 bytes)
+ Item::I_andStatus, // ? Item::I_andStatus, void Intrinsic10A(6 bytes)
0, // ? Item::I_getNpcNum, void Intrinsic10B(4 bytes)
- 0, // ? Item::I_andStatus, void Intrinsic10C(6 bytes)
+ Item::I_andStatus, // ? Item::I_andStatus, void Intrinsic10C(6 bytes)
0, // ? Item::I_getNpcNum, void Intrinsic10D(4 bytes)
- 0, // void Intrinsic10E(6 bytes)
+ Item::I_andStatus, // void Intrinsic10E(6 bytes)
0, // ? Item::I_andStatus, void Intrinsic10F(4 bytes)
// 0x110
- 0, // ? Item::I_getNpcNum, void Intrinsic110(6 bytes)
+ Item::I_andStatus, // ? Item::I_getNpcNum, void Intrinsic110(6 bytes)
0, // int16 Intrinsic111(4 bytes)
0, // ? Item::I_andStatus, byte Intrinsic112(4 bytes)
UCMachine::I_numToStr, // see VMAIL::func0A for example usage
- 0, // void Intrinsic114(6 bytes)
+ Item::I_andStatus, // void Intrinsic114(6 bytes)
0, // ? Item::I_andStatus, int16 Intrinsic115(4 bytes)
0, // ? Item::I_getTypeFlag, byte Intrinsic116(14 bytes)
- 0, // ? Item::I_getNpcNum, void Intrinsic117(6 bytes)
+ Item::I_andStatus, // ? Item::I_getNpcNum, void Intrinsic117(6 bytes)
0, // int16 Intrinsic118(12 bytes)
0, // void Intrinsic119(4 bytes)
- 0, // void Intrinsic11A(6 bytes)
+ Item::I_andStatus, // void Intrinsic11A(6 bytes)
0, // byte Intrinsic11B(6 bytes)
0, // int16 Intrinsic11C(4 bytes)
0, // int16 Intrinsic11D(12 bytes)
@@ -350,7 +350,7 @@ Intrinsic RemorseIntrinsics[] = {
0, // ? Item::I_getNpcNum, void Intrinsic125(6 bytes)
UCMachine::I_numToStr, // same as 113 based on same coff set 0FF, 113, 126
0, // int Intrinsic127(8 bytes)
- 0, // void Intrinsic128(6 bytes) // maybe Item::andStatus?? see ITEM::ordinal22
+ Item::I_andStatus, // void Intrinsic128(6 bytes) // maybe Item::andStatus?? see ITEM::ordinal22
0, // void Intrinsic129(4 bytes)
0, // void Intrinsic12A(4 bytes)
0, // void Intrinsic12B(4 bytes)
@@ -361,7 +361,7 @@ Intrinsic RemorseIntrinsics[] = {
// 0x130
0, // ? Item::I_andStatus, void Intrinsic130(4 bytes)
0, // void Intrinsic131(6 bytes)
- 0, // void Intrinsic132(6 bytes)
+ Item::I_andStatus, // void Intrinsic132(6 bytes)
Item::I_getQHi, // based on same coff set as 026
0, // void Intrinsic134(2 bytes)
0, // void UNUSEDInt135()
Commit: 782313a037f1c3218eece63b5bdc2afe03a5ac99
https://github.com/scummvm/scummvm/commit/782313a037f1c3218eece63b5bdc2afe03a5ac99
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-05-13T20:51:14+09:00
Commit Message:
ULTIMA8: Add gumps for displaying crusader status bar
Changed paths:
A engines/ultima/ultima8/gumps/cru_ammo_gump.cpp
A engines/ultima/ultima8/gumps/cru_ammo_gump.h
A engines/ultima/ultima8/gumps/cru_energy_gump.cpp
A engines/ultima/ultima8/gumps/cru_energy_gump.h
A engines/ultima/ultima8/gumps/cru_health_gump.cpp
A engines/ultima/ultima8/gumps/cru_health_gump.h
A engines/ultima/ultima8/gumps/cru_inventory_gump.cpp
A engines/ultima/ultima8/gumps/cru_inventory_gump.h
A engines/ultima/ultima8/gumps/cru_stat_gump.cpp
A engines/ultima/ultima8/gumps/cru_stat_gump.h
A engines/ultima/ultima8/gumps/cru_status_gump.cpp
A engines/ultima/ultima8/gumps/cru_status_gump.h
A engines/ultima/ultima8/gumps/cru_weapon_gump.cpp
A engines/ultima/ultima8/gumps/cru_weapon_gump.h
engines/ultima/module.mk
engines/ultima/ultima8/games/remorse_game.cpp
engines/ultima/ultima8/world/actors/actor.cpp
engines/ultima/ultima8/world/item.cpp
diff --git a/engines/ultima/module.mk b/engines/ultima/module.mk
index 44b04a2278..5aa3cd17b3 100644
--- a/engines/ultima/module.mk
+++ b/engines/ultima/module.mk
@@ -458,6 +458,13 @@ MODULE_OBJS := \
ultima8/gumps/book_gump.o \
ultima8/gumps/container_gump.o \
ultima8/gumps/credits_gump.o \
+ ultima8/gumps/cru_ammo_gump.o \
+ ultima8/gumps/cru_energy_gump.o \
+ ultima8/gumps/cru_health_gump.o \
+ ultima8/gumps/cru_inventory_gump.o \
+ ultima8/gumps/cru_stat_gump.o \
+ ultima8/gumps/cru_status_gump.o \
+ ultima8/gumps/cru_weapon_gump.o \
ultima8/gumps/desktop_gump.o \
ultima8/gumps/fast_area_vis_gump.o \
ultima8/gumps/game_map_gump.o \
diff --git a/engines/ultima/ultima8/games/remorse_game.cpp b/engines/ultima/ultima8/games/remorse_game.cpp
index c3b0999c6b..fc2ccff60d 100644
--- a/engines/ultima/ultima8/games/remorse_game.cpp
+++ b/engines/ultima/ultima8/games/remorse_game.cpp
@@ -27,6 +27,7 @@
#include "ultima/ultima8/filesys/idata_source.h"
#include "ultima/ultima8/graphics/palette_manager.h"
#include "ultima/ultima8/gumps/movie_gump.h"
+#include "ultima/ultima8/gumps/cru_status_gump.h"
#include "ultima/ultima8/kernel/object_manager.h"
#include "ultima/ultima8/kernel/process.h"
#include "ultima/ultima8/kernel/kernel.h"
@@ -58,11 +59,11 @@ RemorseGame::~RemorseGame() {
static bool loadPalette(const char *path, PaletteManager::PalIndex index) {
Common::SeekableReadStream *pf = FileSystem::get_instance()->ReadFile(path);
if (!pf) {
- perr << "Unable to load static/gamepal.pal." << Std::endl;
+ perr << "Unable to load static/*.pal." << Std::endl;
return false;
}
- Common::MemoryReadStream xfds(U8XFormPal, 1024);
+ Common::MemoryReadStream xfds(CruXFormPal, 1024);
PaletteManager::get_instance()->load(index, *pf, xfds);
delete pf;
@@ -72,6 +73,8 @@ static bool loadPalette(const char *path, PaletteManager::PalIndex index) {
bool RemorseGame::loadFiles() {
// Load palette
pout << "Load Palettes" << Std::endl;
+
+
if (!loadPalette("@game/static/gamepal.pal", PaletteManager::Pal_Game))
return false;
@@ -120,6 +123,9 @@ bool RemorseGame::startGame() {
}
World::get_instance()->switchMap(1);
+
+ Gump *statusGump = new CruStatusGump();
+ statusGump->InitGump(nullptr);
//Ultima8Engine::get_instance()->setAvatarInStasis(true);
Ultima8Engine::get_instance()->setCheatMode(true);
diff --git a/engines/ultima/ultima8/gumps/cru_ammo_gump.cpp b/engines/ultima/ultima8/gumps/cru_ammo_gump.cpp
new file mode 100644
index 0000000000..116aa56bfe
--- /dev/null
+++ b/engines/ultima/ultima8/gumps/cru_ammo_gump.cpp
@@ -0,0 +1,94 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "ultima/ultima8/misc/pent_include.h"
+#include "ultima/ultima8/gumps/cru_ammo_gump.h"
+
+#include "ultima/ultima8/games/game_data.h"
+#include "ultima/ultima8/graphics/gump_shape_archive.h"
+#include "ultima/ultima8/graphics/shape.h"
+#include "ultima/ultima8/graphics/shape_frame.h"
+#include "ultima/ultima8/world/actors/main_actor.h"
+#include "ultima/ultima8/graphics/render_surface.h"
+#include "ultima/ultima8/kernel/mouse.h"
+#include "ultima/ultima8/gumps/paperdoll_gump.h"
+#include "ultima/ultima8/world/get_object.h"
+
+namespace Ultima {
+namespace Ultima8 {
+
+static const int AMMO_GUMP_SHAPE = 4;
+
+DEFINE_RUNTIME_CLASSTYPE_CODE(CruAmmoGump, CruStatGump)
+
+CruAmmoGump::CruAmmoGump() : CruStatGump(), _ammoShape(nullptr) {
+
+}
+
+CruAmmoGump::CruAmmoGump(Shape *shape, int x)
+ : CruStatGump(shape, x), _ammoShape(nullptr) {
+ _frameNum = 1;
+}
+
+CruAmmoGump::~CruAmmoGump() {
+}
+
+void CruAmmoGump::InitGump(Gump *newparent, bool take_focus) {
+ CruStatGump::InitGump(newparent, take_focus);
+
+ GumpShapeArchive *gumpshapes = GameData::get_instance()->getGumps();
+ if (!gumpshapes) {
+ warning("failed to init stat gump: no gump shape archive");
+ return;
+ }
+
+ _ammoShape = gumpshapes->getShape(AMMO_GUMP_SHAPE);
+ if (!_ammoShape || !_ammoShape->getFrame(0)) {
+ warning("failed to init stat gump: no ammo shape");
+ return;
+ }
+}
+
+void CruAmmoGump::PaintThis(RenderSurface *surf, int32 lerp_factor, bool scaled) {
+ CruStatGump::PaintThis(surf, lerp_factor, scaled);
+
+ const MainActor *a = getMainActor();
+ if (!a) {
+ // avatar gone??
+ return;
+ }
+
+ uint16 weapon = a->getDamageType(); // ?? TODO: Where do we store current weapon?
+ const ShapeFrame *frame = _ammoShape->getFrame(weapon);
+ // TODO: Paint the current weapon
+}
+
+void CruAmmoGump::saveData(Common::WriteStream *ws) {
+ Gump::saveData(ws);
+}
+
+bool CruAmmoGump::loadData(Common::ReadStream *rs, uint32 version) {
+ return Gump::loadData(rs, version);
+}
+
+} // End of namespace Ultima8
+} // End of namespace Ultima
diff --git a/engines/ultima/ultima8/gumps/cru_ammo_gump.h b/engines/ultima/ultima8/gumps/cru_ammo_gump.h
new file mode 100644
index 0000000000..bfc9c01b80
--- /dev/null
+++ b/engines/ultima/ultima8/gumps/cru_ammo_gump.h
@@ -0,0 +1,60 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ULTIMA8_GUMPS_CRUAMMOGUMP_H
+#define ULTIMA8_GUMPS_CRUAMMOGUMP_H
+
+#include "ultima/ultima8/gumps/cru_stat_gump.h"
+#include "ultima/ultima8/misc/p_dynamic_cast.h"
+
+namespace Ultima {
+namespace Ultima8 {
+
+/**
+ * Second box along the bottom of the screen, shows current ammo
+ */
+class CruAmmoGump : public CruStatGump {
+public:
+ ENABLE_RUNTIME_CLASSTYPE()
+
+ CruAmmoGump();
+ CruAmmoGump(Shape *shape, int x);
+ ~CruAmmoGump() override;
+
+ // Init the gump, call after construction
+ void InitGump(Gump *newparent, bool take_focus = true) override;
+
+ // Paint this Gump
+ void PaintThis(RenderSurface *, int32 lerp_factor, bool scaled) override;
+
+ bool loadData(Common::ReadStream *rs, uint32 version);
+protected:
+ void saveData(Common::WriteStream *ws) override;
+
+private:
+ const Shape *_ammoShape;
+};
+
+} // End of namespace Ultima8
+} // End of namespace Ultima
+
+#endif
diff --git a/engines/ultima/ultima8/gumps/cru_energy_gump.cpp b/engines/ultima/ultima8/gumps/cru_energy_gump.cpp
new file mode 100644
index 0000000000..f2633c9b10
--- /dev/null
+++ b/engines/ultima/ultima8/gumps/cru_energy_gump.cpp
@@ -0,0 +1,83 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "ultima/ultima8/misc/pent_include.h"
+#include "ultima/ultima8/gumps/cru_energy_gump.h"
+
+#include "ultima/ultima8/games/game_data.h"
+#include "ultima/ultima8/graphics/gump_shape_archive.h"
+#include "ultima/ultima8/graphics/shape.h"
+#include "ultima/ultima8/graphics/shape_frame.h"
+#include "ultima/ultima8/world/actors/main_actor.h"
+#include "ultima/ultima8/graphics/render_surface.h"
+#include "ultima/ultima8/kernel/mouse.h"
+#include "ultima/ultima8/gumps/paperdoll_gump.h"
+#include "ultima/ultima8/world/get_object.h"
+
+namespace Ultima {
+namespace Ultima8 {
+
+static const uint32 ENERGY_BAR_COLOR = 0xFF9A0404; // RGB: (0, 48, 113)
+
+DEFINE_RUNTIME_CLASSTYPE_CODE(CruEnergyGump, CruStatGump)
+
+CruEnergyGump::CruEnergyGump() : CruStatGump() {
+
+}
+
+CruEnergyGump::CruEnergyGump(Shape *shape, int x)
+ : CruStatGump(shape, x) {
+ _frameNum = 3;
+}
+
+CruEnergyGump::~CruEnergyGump() {
+}
+
+void CruEnergyGump::InitGump(Gump *newparent, bool take_focus) {
+ CruStatGump::InitGump(newparent, take_focus);
+}
+
+void CruEnergyGump::PaintThis(RenderSurface *surf, int32 lerp_factor, bool scaled) {
+ CruStatGump::PaintThis(surf, lerp_factor, scaled);
+
+ const MainActor *a = getMainActor();
+ if (!a) {
+ // avatar gone??
+ return;
+ }
+
+ int16 energy = a->getMana();
+ int16 max_energy = a->getMaxMana();
+ int width = max_energy ? ((energy * 67) / max_energy) : 67;
+ surf->Fill32(ENERGY_BAR_COLOR, 34, 7, width, 14);
+}
+
+void CruEnergyGump::saveData(Common::WriteStream *ws) {
+ Gump::saveData(ws);
+}
+
+bool CruEnergyGump::loadData(Common::ReadStream *rs, uint32 version) {
+ return Gump::loadData(rs, version);
+}
+
+} // End of namespace Ultima8
+} // End of namespace Ultima
diff --git a/engines/ultima/ultima8/gumps/cru_energy_gump.h b/engines/ultima/ultima8/gumps/cru_energy_gump.h
new file mode 100644
index 0000000000..03af1f6758
--- /dev/null
+++ b/engines/ultima/ultima8/gumps/cru_energy_gump.h
@@ -0,0 +1,57 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ULTIMA8_GUMPS_CRUENERGYGUMP_H
+#define ULTIMA8_GUMPS_CRUENERGYGUMP_H
+
+#include "ultima/ultima8/gumps/cru_stat_gump.h"
+#include "ultima/ultima8/misc/p_dynamic_cast.h"
+
+namespace Ultima {
+namespace Ultima8 {
+
+/**
+ * Energy meter, the right-most box along the bottom of the screen.
+ */
+class CruEnergyGump : public CruStatGump {
+public:
+ ENABLE_RUNTIME_CLASSTYPE()
+
+ CruEnergyGump();
+ CruEnergyGump(Shape *shape, int x);
+ ~CruEnergyGump() override;
+
+ // Init the gump, call after construction
+ void InitGump(Gump *newparent, bool take_focus = true) override;
+
+ // Paint this Gump
+ void PaintThis(RenderSurface *, int32 lerp_factor, bool scaled) override;
+
+ bool loadData(Common::ReadStream *rs, uint32 version);
+protected:
+ void saveData(Common::WriteStream *ws) override;
+};
+
+} // End of namespace Ultima8
+} // End of namespace Ultima
+
+#endif
diff --git a/engines/ultima/ultima8/gumps/cru_health_gump.cpp b/engines/ultima/ultima8/gumps/cru_health_gump.cpp
new file mode 100644
index 0000000000..92527b684c
--- /dev/null
+++ b/engines/ultima/ultima8/gumps/cru_health_gump.cpp
@@ -0,0 +1,84 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "ultima/ultima8/misc/pent_include.h"
+#include "ultima/ultima8/gumps/cru_health_gump.h"
+
+#include "ultima/ultima8/games/game_data.h"
+#include "ultima/ultima8/graphics/gump_shape_archive.h"
+#include "ultima/ultima8/graphics/shape.h"
+#include "ultima/ultima8/graphics/shape_frame.h"
+#include "ultima/ultima8/world/actors/main_actor.h"
+#include "ultima/ultima8/graphics/render_surface.h"
+#include "ultima/ultima8/kernel/mouse.h"
+#include "ultima/ultima8/gumps/paperdoll_gump.h"
+#include "ultima/ultima8/world/get_object.h"
+
+namespace Ultima {
+namespace Ultima8 {
+
+static const uint32 HEALTH_BAR_COLOR = 0xFF003071; // RGB = (154, 4, 4)
+
+DEFINE_RUNTIME_CLASSTYPE_CODE(CruHealthGump, CruStatGump)
+
+CruHealthGump::CruHealthGump() : CruStatGump() {
+
+}
+
+CruHealthGump::CruHealthGump(Shape *shape, int x)
+ : CruStatGump(shape, x) {
+ _frameNum = 2;
+}
+
+CruHealthGump::~CruHealthGump() {
+}
+
+void CruHealthGump::InitGump(Gump *newparent, bool take_focus) {
+ CruStatGump::InitGump(newparent, take_focus);
+}
+
+void CruHealthGump::PaintThis(RenderSurface *surf, int32 lerp_factor, bool scaled) {
+ CruStatGump::PaintThis(surf, lerp_factor, scaled);
+
+ const MainActor *a = getMainActor();
+ if (!a) {
+ // avatar gone??
+ return;
+ }
+
+ int current_hp = a->getHP();
+ int max_hp = a->getMaxHP();
+ // max width = 67
+ int width = max_hp ? ((current_hp * 67) / max_hp) : 67;
+ surf->Fill32(HEALTH_BAR_COLOR, 34, 7, width, 14);
+}
+
+void CruHealthGump::saveData(Common::WriteStream *ws) {
+ Gump::saveData(ws);
+}
+
+bool CruHealthGump::loadData(Common::ReadStream *rs, uint32 version) {
+ return Gump::loadData(rs, version);
+}
+
+} // End of namespace Ultima8
+} // End of namespace Ultima
diff --git a/engines/ultima/ultima8/gumps/cru_health_gump.h b/engines/ultima/ultima8/gumps/cru_health_gump.h
new file mode 100644
index 0000000000..9debca5391
--- /dev/null
+++ b/engines/ultima/ultima8/gumps/cru_health_gump.h
@@ -0,0 +1,57 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ULTIMA8_GUMPS_CRUHEALTHGUMP_H
+#define ULTIMA8_GUMPS_CRUHEALTHGUMP_H
+
+#include "ultima/ultima8/gumps/cru_stat_gump.h"
+#include "ultima/ultima8/misc/p_dynamic_cast.h"
+
+namespace Ultima {
+namespace Ultima8 {
+
+/**
+ * Health bar, the 4th box along the bottom of the screen
+ */
+class CruHealthGump : public CruStatGump {
+public:
+ ENABLE_RUNTIME_CLASSTYPE()
+
+ CruHealthGump();
+ CruHealthGump(Shape *shape, int x);
+ ~CruHealthGump() override;
+
+ // Init the gump, call after construction
+ void InitGump(Gump *newparent, bool take_focus = true) override;
+
+ // Paint this Gump
+ void PaintThis(RenderSurface *, int32 lerp_factor, bool scaled) override;
+
+ bool loadData(Common::ReadStream *rs, uint32 version);
+protected:
+ void saveData(Common::WriteStream *ws) override;
+};
+
+} // End of namespace Ultima8
+} // End of namespace Ultima
+
+#endif
diff --git a/engines/ultima/ultima8/gumps/cru_inventory_gump.cpp b/engines/ultima/ultima8/gumps/cru_inventory_gump.cpp
new file mode 100644
index 0000000000..74dda19792
--- /dev/null
+++ b/engines/ultima/ultima8/gumps/cru_inventory_gump.cpp
@@ -0,0 +1,94 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "ultima/ultima8/misc/pent_include.h"
+#include "ultima/ultima8/gumps/cru_inventory_gump.h"
+
+#include "ultima/ultima8/games/game_data.h"
+#include "ultima/ultima8/graphics/gump_shape_archive.h"
+#include "ultima/ultima8/graphics/shape.h"
+#include "ultima/ultima8/graphics/shape_frame.h"
+#include "ultima/ultima8/world/actors/main_actor.h"
+#include "ultima/ultima8/graphics/render_surface.h"
+#include "ultima/ultima8/kernel/mouse.h"
+#include "ultima/ultima8/gumps/paperdoll_gump.h"
+#include "ultima/ultima8/world/get_object.h"
+
+namespace Ultima {
+namespace Ultima8 {
+
+static const int INVENTORY_GUMP_SHAPE = 3;
+
+DEFINE_RUNTIME_CLASSTYPE_CODE(CruInventoryGump, CruStatGump)
+
+CruInventoryGump::CruInventoryGump() : CruStatGump(), _inventoryShape(nullptr) {
+
+}
+
+CruInventoryGump::CruInventoryGump(Shape *shape, int x)
+ : CruStatGump(shape, x), _inventoryShape(nullptr) {
+ _frameNum = 0;
+}
+
+CruInventoryGump::~CruInventoryGump() {
+}
+
+void CruInventoryGump::InitGump(Gump *newparent, bool take_focus) {
+ CruStatGump::InitGump(newparent, take_focus);
+
+ GumpShapeArchive *gumpshapes = GameData::get_instance()->getGumps();
+ if (!gumpshapes) {
+ warning("failed to init stat gump: no gump shape archive");
+ return;
+ }
+
+ _inventoryShape = gumpshapes->getShape(INVENTORY_GUMP_SHAPE);
+ if (!_inventoryShape || !_inventoryShape->getFrame(0)) {
+ warning("failed to init stat gump: no inventory shape");
+ return;
+ }
+}
+
+void CruInventoryGump::PaintThis(RenderSurface *surf, int32 lerp_factor, bool scaled) {
+ CruStatGump::PaintThis(surf, lerp_factor, scaled);
+
+ const MainActor *a = getMainActor();
+ if (!a) {
+ // avatar gone??
+ return;
+ }
+
+ uint16 weapon = a->getDamageType(); // ?? TODO: Where do we store item weapon?
+ const ShapeFrame *frame = _inventoryShape->getFrame(weapon);
+ // TODO: Paint the current selected item
+}
+
+void CruInventoryGump::saveData(Common::WriteStream *ws) {
+ Gump::saveData(ws);
+}
+
+bool CruInventoryGump::loadData(Common::ReadStream *rs, uint32 version) {
+ return Gump::loadData(rs, version);
+}
+
+} // End of namespace Ultima8
+} // End of namespace Ultima
diff --git a/engines/ultima/ultima8/gumps/cru_inventory_gump.h b/engines/ultima/ultima8/gumps/cru_inventory_gump.h
new file mode 100644
index 0000000000..6ccda89398
--- /dev/null
+++ b/engines/ultima/ultima8/gumps/cru_inventory_gump.h
@@ -0,0 +1,60 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ULTIMA8_GUMPS_CRUINVENTORYGUMP_H
+#define ULTIMA8_GUMPS_CRUINVENTORYGUMP_H
+
+#include "ultima/ultima8/gumps/cru_stat_gump.h"
+#include "ultima/ultima8/misc/p_dynamic_cast.h"
+
+namespace Ultima {
+namespace Ultima8 {
+
+/**
+ * Inventory box, the 3rd box along the bottom of the screen
+ */
+class CruInventoryGump : public CruStatGump {
+public:
+ ENABLE_RUNTIME_CLASSTYPE()
+
+ CruInventoryGump();
+ CruInventoryGump(Shape *shape, int x);
+ ~CruInventoryGump() override;
+
+ // Init the gump, call after construction
+ void InitGump(Gump *newparent, bool take_focus = true) override;
+
+ // Paint this Gump
+ void PaintThis(RenderSurface *, int32 lerp_factor, bool scaled) override;
+
+ bool loadData(Common::ReadStream *rs, uint32 version);
+protected:
+ void saveData(Common::WriteStream *ws) override;
+
+private:
+ const Shape *_inventoryShape;
+};
+
+} // End of namespace Ultima8
+} // End of namespace Ultima
+
+#endif
diff --git a/engines/ultima/ultima8/gumps/cru_stat_gump.cpp b/engines/ultima/ultima8/gumps/cru_stat_gump.cpp
new file mode 100644
index 0000000000..75010e2034
--- /dev/null
+++ b/engines/ultima/ultima8/gumps/cru_stat_gump.cpp
@@ -0,0 +1,74 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "ultima/ultima8/misc/pent_include.h"
+#include "ultima/ultima8/gumps/cru_stat_gump.h"
+
+#include "ultima/ultima8/games/game_data.h"
+#include "ultima/ultima8/graphics/gump_shape_archive.h"
+#include "ultima/ultima8/graphics/shape.h"
+#include "ultima/ultima8/graphics/shape_frame.h"
+#include "ultima/ultima8/world/actors/main_actor.h"
+#include "ultima/ultima8/graphics/render_surface.h"
+#include "ultima/ultima8/kernel/mouse.h"
+#include "ultima/ultima8/gumps/paperdoll_gump.h"
+#include "ultima/ultima8/world/get_object.h"
+
+namespace Ultima {
+namespace Ultima8 {
+
+DEFINE_RUNTIME_CLASSTYPE_CODE(CruStatGump, Gump)
+
+CruStatGump::CruStatGump() : Gump() {
+
+}
+
+CruStatGump::CruStatGump(Shape *shape, int x)
+ : Gump(0, 0, 5, 5, 0) {
+ _shape = shape;
+ _x = x;
+ _y = 0;
+}
+
+CruStatGump::~CruStatGump() {
+}
+
+void CruStatGump::InitGump(Gump *newparent, bool take_focus) {
+ Gump::InitGump(newparent, take_focus);
+
+ UpdateDimsFromShape();
+}
+
+void CruStatGump::PaintThis(RenderSurface *surf, int32 lerp_factor, bool scaled) {
+ surf->PaintTranslucent(_shape, _frameNum, 0, 0);
+}
+
+void CruStatGump::saveData(Common::WriteStream *ws) {
+ Gump::saveData(ws);
+}
+
+bool CruStatGump::loadData(Common::ReadStream *rs, uint32 version) {
+ return Gump::loadData(rs, version);
+}
+
+} // End of namespace Ultima8
+} // End of namespace Ultima
diff --git a/engines/ultima/ultima8/gumps/cru_stat_gump.h b/engines/ultima/ultima8/gumps/cru_stat_gump.h
new file mode 100644
index 0000000000..da4d683a41
--- /dev/null
+++ b/engines/ultima/ultima8/gumps/cru_stat_gump.h
@@ -0,0 +1,57 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ULTIMA8_GUMPS_CRUSTATGUMP_H
+#define ULTIMA8_GUMPS_CRUSTATGUMP_H
+
+#include "ultima/ultima8/gumps/gump.h"
+#include "ultima/ultima8/misc/p_dynamic_cast.h"
+
+namespace Ultima {
+namespace Ultima8 {
+
+/**
+ * Superclass for the 5 status boxes along the bottom of the screen
+ */
+class CruStatGump : public Gump {
+public:
+ ENABLE_RUNTIME_CLASSTYPE()
+
+ CruStatGump();
+ CruStatGump(Shape *shape, int x);
+ ~CruStatGump() override;
+
+ // Init the gump, call after construction
+ void InitGump(Gump *newparent, bool take_focus = true) override;
+
+ // Paint this Gump
+ void PaintThis(RenderSurface *, int32 lerp_factor, bool scaled) override;
+
+ bool loadData(Common::ReadStream *rs, uint32 version);
+protected:
+ void saveData(Common::WriteStream *ws) override;
+};
+
+} // End of namespace Ultima8
+} // End of namespace Ultima
+
+#endif
diff --git a/engines/ultima/ultima8/gumps/cru_status_gump.cpp b/engines/ultima/ultima8/gumps/cru_status_gump.cpp
new file mode 100644
index 0000000000..13454f589f
--- /dev/null
+++ b/engines/ultima/ultima8/gumps/cru_status_gump.cpp
@@ -0,0 +1,111 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "ultima/ultima8/misc/pent_include.h"
+#include "ultima/ultima8/gumps/cru_status_gump.h"
+#include "ultima/ultima8/gumps/cru_weapon_gump.h"
+#include "ultima/ultima8/gumps/cru_ammo_gump.h"
+#include "ultima/ultima8/gumps/cru_inventory_gump.h"
+#include "ultima/ultima8/gumps/cru_health_gump.h"
+#include "ultima/ultima8/gumps/cru_energy_gump.h"
+
+#include "ultima/ultima8/games/game_data.h"
+#include "ultima/ultima8/graphics/gump_shape_archive.h"
+#include "ultima/ultima8/graphics/shape.h"
+#include "ultima/ultima8/graphics/shape_frame.h"
+#include "ultima/ultima8/graphics/render_surface.h"
+#include "ultima/ultima8/kernel/mouse.h"
+#include "ultima/ultima8/world/get_object.h"
+
+namespace Ultima {
+namespace Ultima8 {
+
+DEFINE_RUNTIME_CLASSTYPE_CODE(CruStatusGump, Gump)
+
+static const int PX_FROM_BOTTOM = 2; //! gap (y) between bottom of screen and bottom of a single item
+static const int PX_FROM_LEFT = 15; //! gap (x) from left of screen to weapon box
+static const int PX_GAP = 17; //! gap (x) between boxes in status bar
+
+static const int FRAME_GUMP_SHAPE = 1;
+
+CruStatusGump::CruStatusGump() : Gump() {
+
+}
+
+CruStatusGump::CruStatusGump(int x, int y, uint32 flags, int32 layer)
+ : Gump(0, 0, 5, 5, 0, flags, layer) {
+}
+
+CruStatusGump::~CruStatusGump() {
+}
+
+void CruStatusGump::InitGump(Gump *newparent, bool take_focus) {
+ Gump::InitGump(newparent, take_focus);
+
+ GumpShapeArchive *gumpshapes = GameData::get_instance()->getGumps();
+ if (!gumpshapes) {
+ warning("failed to init stats gump: no gump shape archive");
+ return;
+ }
+
+ Shape *frameShape = gumpshapes->getShape(FRAME_GUMP_SHAPE);
+ if (!frameShape || !frameShape->getFrame(0)) {
+ warning("failed to init stats gump: no gump frame");
+ return;
+ }
+
+ int w = frameShape->getFrame(0)->_width;
+ int h = frameShape->getFrame(0)->_height;
+
+ int xoff = 0;
+ Gump *weaponGump = new CruWeaponGump(frameShape, xoff);
+ weaponGump->InitGump(this);
+ Gump *ammoGump = new CruAmmoGump(frameShape, xoff + w + PX_GAP);
+ ammoGump->InitGump(this);
+ Gump *inventoryGump = new CruInventoryGump(frameShape, xoff + (w + PX_GAP) * 2);
+ inventoryGump->InitGump(this);
+ Gump *health = new CruHealthGump(frameShape, xoff + (w + PX_GAP) * 3);
+ health->InitGump(this);
+ Gump *energyGump = new CruEnergyGump(frameShape, xoff + (w + PX_GAP) * 4);
+ energyGump->InitGump(this);
+
+ _dims.w = w * 5 + PX_GAP * 4;
+ _dims.h = h;
+ setRelativePosition(BOTTOM_LEFT, PX_FROM_LEFT, -PX_FROM_BOTTOM);
+}
+
+void CruStatusGump::PaintThis(RenderSurface *surf, int32 lerp_factor, bool scaled) {
+ Gump::PaintThis(surf, lerp_factor, scaled);
+
+ // All the painting logic is in the children.
+}
+
+void CruStatusGump::saveData(Common::WriteStream *ws) {
+ Gump::saveData(ws);
+}
+
+bool CruStatusGump::loadData(Common::ReadStream *rs, uint32 version) {
+ return Gump::loadData(rs, version);
+}
+
+} // End of namespace Ultima8
+} // End of namespace Ultima
diff --git a/engines/ultima/ultima8/gumps/cru_status_gump.h b/engines/ultima/ultima8/gumps/cru_status_gump.h
new file mode 100644
index 0000000000..80abf54927
--- /dev/null
+++ b/engines/ultima/ultima8/gumps/cru_status_gump.h
@@ -0,0 +1,59 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ULTIMA8_GUMPS_CRUSTATUSGUMP_H
+#define ULTIMA8_GUMPS_CRUSTATUSGUMP_H
+
+#include "ultima/ultima8/gumps/gump.h"
+#include "ultima/ultima8/misc/p_dynamic_cast.h"
+
+namespace Ultima {
+namespace Ultima8 {
+
+/**
+ * Represents the collection of status boxes along the bottom of the screen.
+ * Each of the individual items is a class of CruStatGump.
+ */
+class CruStatusGump : public Gump {
+public:
+ ENABLE_RUNTIME_CLASSTYPE()
+
+ CruStatusGump();
+ CruStatusGump(int x, int y, uint32 flags = 0,
+ int32 layer = LAYER_NORMAL);
+ ~CruStatusGump() override;
+
+ // Init the gump, call after construction
+ void InitGump(Gump *newparent, bool take_focus = true) override;
+
+ // Paint this Gump
+ void PaintThis(RenderSurface *, int32 lerp_factor, bool scaled) override;
+
+ bool loadData(Common::ReadStream *rs, uint32 version);
+protected:
+ void saveData(Common::WriteStream *ws) override;
+};
+
+} // End of namespace Ultima8
+} // End of namespace Ultima
+
+#endif
diff --git a/engines/ultima/ultima8/gumps/cru_weapon_gump.cpp b/engines/ultima/ultima8/gumps/cru_weapon_gump.cpp
new file mode 100644
index 0000000000..10be23994d
--- /dev/null
+++ b/engines/ultima/ultima8/gumps/cru_weapon_gump.cpp
@@ -0,0 +1,94 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "ultima/ultima8/misc/pent_include.h"
+#include "ultima/ultima8/gumps/cru_weapon_gump.h"
+
+#include "ultima/ultima8/games/game_data.h"
+#include "ultima/ultima8/graphics/gump_shape_archive.h"
+#include "ultima/ultima8/graphics/shape.h"
+#include "ultima/ultima8/graphics/shape_frame.h"
+#include "ultima/ultima8/world/actors/main_actor.h"
+#include "ultima/ultima8/graphics/render_surface.h"
+#include "ultima/ultima8/kernel/mouse.h"
+#include "ultima/ultima8/gumps/paperdoll_gump.h"
+#include "ultima/ultima8/world/get_object.h"
+
+namespace Ultima {
+namespace Ultima8 {
+
+static const int WEAPON_GUMP_SHAPE = 3;
+
+DEFINE_RUNTIME_CLASSTYPE_CODE(CruWeaponGump, CruStatGump)
+
+CruWeaponGump::CruWeaponGump() : CruStatGump(), _weaponShape(nullptr) {
+
+}
+
+CruWeaponGump::CruWeaponGump(Shape *shape, int x)
+ : CruStatGump(shape, x), _weaponShape(nullptr) {
+ _frameNum = 0;
+}
+
+CruWeaponGump::~CruWeaponGump() {
+}
+
+void CruWeaponGump::InitGump(Gump *newparent, bool take_focus) {
+ CruStatGump::InitGump(newparent, take_focus);
+
+ GumpShapeArchive *gumpshapes = GameData::get_instance()->getGumps();
+ if (!gumpshapes) {
+ warning("failed to init stat gump: no gump shape archive");
+ return;
+ }
+
+ _weaponShape = gumpshapes->getShape(WEAPON_GUMP_SHAPE);
+ if (!_weaponShape || !_weaponShape->getFrame(0)) {
+ warning("failed to init stat gump: no weapon shape");
+ return;
+ }
+}
+
+void CruWeaponGump::PaintThis(RenderSurface *surf, int32 lerp_factor, bool scaled) {
+ CruStatGump::PaintThis(surf, lerp_factor, scaled);
+
+ const MainActor *a = getMainActor();
+ if (!a) {
+ // avatar gone??
+ return;
+ }
+
+ uint16 weapon = a->getDamageType(); // ?? TODO: Where do we store current weapon?
+ const ShapeFrame *frame = _weaponShape->getFrame(weapon);
+ // TODO: Paint the current weapon
+}
+
+void CruWeaponGump::saveData(Common::WriteStream *ws) {
+ Gump::saveData(ws);
+}
+
+bool CruWeaponGump::loadData(Common::ReadStream *rs, uint32 version) {
+ return Gump::loadData(rs, version);
+}
+
+} // End of namespace Ultima8
+} // End of namespace Ultima
diff --git a/engines/ultima/ultima8/gumps/cru_weapon_gump.h b/engines/ultima/ultima8/gumps/cru_weapon_gump.h
new file mode 100644
index 0000000000..eb0fd222f9
--- /dev/null
+++ b/engines/ultima/ultima8/gumps/cru_weapon_gump.h
@@ -0,0 +1,60 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ULTIMA8_GUMPS_CRUWEAPONGUMP_H
+#define ULTIMA8_GUMPS_CRUWEAPONGUMP_H
+
+#include "ultima/ultima8/gumps/cru_stat_gump.h"
+#include "ultima/ultima8/misc/p_dynamic_cast.h"
+
+namespace Ultima {
+namespace Ultima8 {
+
+/**
+ * Superclass for the 5 status boxes along the bottom of the screen
+ */
+class CruWeaponGump : public CruStatGump {
+public:
+ ENABLE_RUNTIME_CLASSTYPE()
+
+ CruWeaponGump();
+ CruWeaponGump(Shape *shape, int x);
+ ~CruWeaponGump() override;
+
+ // Init the gump, call after construction
+ void InitGump(Gump *newparent, bool take_focus = true) override;
+
+ // Paint this Gump
+ void PaintThis(RenderSurface *, int32 lerp_factor, bool scaled) override;
+
+ bool loadData(Common::ReadStream *rs, uint32 version);
+protected:
+ void saveData(Common::WriteStream *ws) override;
+
+private:
+ const Shape *_weaponShape;
+};
+
+} // End of namespace Ultima8
+} // End of namespace Ultima
+
+#endif
diff --git a/engines/ultima/ultima8/world/actors/actor.cpp b/engines/ultima/ultima8/world/actors/actor.cpp
index 0a538a0914..5ce6637288 100644
--- a/engines/ultima/ultima8/world/actors/actor.cpp
+++ b/engines/ultima/ultima8/world/actors/actor.cpp
@@ -56,12 +56,14 @@
namespace Ultima {
namespace Ultima8 {
+static const unsigned int BACKPACK_SHAPE = 529;
+
// p_dynamic_cast stuff
DEFINE_RUNTIME_CLASSTYPE_CODE(Actor, Container)
Actor::Actor() : _strength(0), _dexterity(0), _intelligence(0),
_hitPoints(0), _mana(0), _alignment(0), _enemyAlignment(0),
- _lastAnim(Animation::walk), _animFrame(0), _direction(0),
+ _lastAnim(Animation::stand), _animFrame(0), _direction(0),
_fallStart(0), _unk0C(0), _actorFlags(0) {
}
@@ -355,9 +357,8 @@ bool Actor::removeItem(Item *item) {
}
bool Actor::setEquip(Item *item, bool checkwghtvol) {
- const unsigned int backpack_shape = 529; //!! *cough* constant
uint32 equiptype = item->getShapeInfo()->_equipType;
- bool backpack = (item->getShape() == backpack_shape);
+ bool backpack = (item->getShape() == BACKPACK_SHAPE);
// valid item type?
if (equiptype == ShapeInfo::SE_NONE && !backpack) return false;
@@ -368,7 +369,7 @@ bool Actor::setEquip(Item *item, bool checkwghtvol) {
if ((*iter)->getObjId() == item->getObjId()) continue;
uint32 cet = (*iter)->getShapeInfo()->_equipType;
- bool cbackpack = ((*iter)->getShape() == backpack_shape);
+ bool cbackpack = ((*iter)->getShape() == BACKPACK_SHAPE);
// already have an item with the same equiptype
if (cet == equiptype || (cbackpack && backpack)) return false;
@@ -383,12 +384,10 @@ bool Actor::setEquip(Item *item, bool checkwghtvol) {
}
uint16 Actor::getEquip(uint32 type) const {
- const unsigned int backpack_shape = 529; //!! *cough* constant
-
Std::list<Item *>::const_iterator iter;
for (iter = _contents.begin(); iter != _contents.end(); ++iter) {
uint32 cet = (*iter)->getShapeInfo()->_equipType;
- bool cbackpack = ((*iter)->getShape() == backpack_shape);
+ bool cbackpack = ((*iter)->getShape() == BACKPACK_SHAPE);
if ((*iter)->hasFlags(FLG_EQUIPPED) &&
(cet == type || (cbackpack && type == 7))) { // !! constant
@@ -1613,7 +1612,7 @@ uint32 Actor::I_setEquip(const uint8 *args, unsigned int /*argsize*/) {
return 0;
// check it was added to the right slot
- assert(item->getZ() == type + 1 || (item->getShape() == 529 && type == 6));
+ assert(item->getZ() == type + 1 || (item->getShape() == BACKPACK_SHAPE && type == 6));
return 1;
}
diff --git a/engines/ultima/ultima8/world/item.cpp b/engines/ultima/ultima8/world/item.cpp
index 6202942e5b..5301d3bca5 100644
--- a/engines/ultima/ultima8/world/item.cpp
+++ b/engines/ultima/ultima8/world/item.cpp
@@ -1057,17 +1057,12 @@ uint32 Item::callUsecodeEvent(uint32 event, const uint8 *args, int argsize) {
if (!offset) return 0; // event not found
/*if (GAME_IS_CRUSADER && event != 1) {
- if (event != 15 ||
- (_shape != 1098 && _shape != 1227 && _shape != 1297 && _shape != 1298 && _shape != 1274
- && _shape != 1275 && _shape != 1301 && _shape != 1302
- && _shape != 1290 && _shape != 809 && _shape != 73 && _shape != 447 && _shape != 470 && _shape != 336 && _shape != 33 && _shape != 1143 && _shape != 94 && _shape != 189 && _shape != 440 && _shape != 139 && _shape != 140 && _shape != 475 && _shape != 392 && _shape != 147 && _shape != 136)) { // run sounds for a few objects..
- debug(6, "Cusader: not running event %d for item %d shape %d",
+ debug(6, "Crusader: not running event %d for item %d shape %d",
event, _objId, _shape);
- return 0;
- }
+ return 0;
}*/
- debug(6, "Item: %d (shape %d) calling usecode event %d @ %04X:%04X\n",
+ debug(6, "Item: %d (shape %d) calling usecode event %d @ %04X:%04X",
_objId, _shape, event, class_id, offset);
return callUsecode(static_cast<uint16>(class_id),
@@ -2244,21 +2239,21 @@ uint32 Item::I_ask(const uint8 *args, unsigned int /*argsize*/) {
uint32 Item::I_legalCreateAtPoint(const uint8 *args, unsigned int /*argsize*/) {
ARG_UC_PTR(itemptr); // need to store the item id at *itemptr
- ARG_UINT16(_shape);
- ARG_UINT16(_frame);
+ ARG_UINT16(shape);
+ ARG_UINT16(frame);
ARG_WORLDPOINT(point);
// check if item can exist
CurrentMap *cm = World::get_instance()->getCurrentMap();
bool valid = cm->isValidPosition(point.getX(), point.getY(), point.getZ(),
- _shape, 0, 0, 0);
+ shape, 0, 0, 0);
if (!valid)
return 0;
- Item *newitem = ItemFactory::createItem(_shape, _frame, 0, 0, 0, 0, 0, true);
+ Item *newitem = ItemFactory::createItem(shape, frame, 0, 0, 0, 0, 0, true);
if (!newitem) {
- perr << "I_legalCreateAtPoint failed to create item (" << _shape
- << "," << _frame << ")." << Std::endl;
+ perr << "I_legalCreateAtPoint failed to create item (" << shape
+ << "," << frame << ")." << Std::endl;
return 0;
}
uint16 objID = newitem->getObjId();
@@ -2274,27 +2269,27 @@ uint32 Item::I_legalCreateAtPoint(const uint8 *args, unsigned int /*argsize*/) {
uint32 Item::I_legalCreateAtCoords(const uint8 *args, unsigned int /*argsize*/) {
ARG_UC_PTR(itemptr); // need to store the item id at *itemptr
- ARG_UINT16(_shape);
- ARG_UINT16(_frame);
- ARG_UINT16(_x);
- ARG_UINT16(_y);
- ARG_UINT16(_z);
+ ARG_UINT16(shape);
+ ARG_UINT16(frame);
+ ARG_UINT16(x);
+ ARG_UINT16(y);
+ ARG_UINT16(z);
// check if item can exist
CurrentMap *cm = World::get_instance()->getCurrentMap();
- bool valid = cm->isValidPosition(_x, _y, _z, _shape, 0, 0, 0);
+ bool valid = cm->isValidPosition(x, y, z, shape, 0, 0, 0);
if (!valid)
return 0;
// if yes, create it
- Item *newitem = ItemFactory::createItem(_shape, _frame, 0, 0, 0, 0, 0, true);
+ Item *newitem = ItemFactory::createItem(shape, frame, 0, 0, 0, 0, 0, true);
if (!newitem) {
- perr << "I_legalCreateAtCoords failed to create item (" << _shape
- << "," << _frame << ")." << Std::endl;
+ perr << "I_legalCreateAtCoords failed to create item (" << shape
+ << "," << frame << ")." << Std::endl;
return 0;
}
uint16 objID = newitem->getObjId();
- newitem->move(_x, _y, _z);
+ newitem->move(x, y, z);
uint8 buf[2];
buf[0] = static_cast<uint8>(objID);
@@ -2306,8 +2301,8 @@ uint32 Item::I_legalCreateAtCoords(const uint8 *args, unsigned int /*argsize*/)
uint32 Item::I_legalCreateInCont(const uint8 *args, unsigned int /*argsize*/) {
ARG_UC_PTR(itemptr); // need to store the item id at *itemptr
- ARG_UINT16(_shape);
- ARG_UINT16(_frame);
+ ARG_UINT16(shape);
+ ARG_UINT16(frame);
ARG_CONTAINER_FROM_ID(container);
ARG_UINT16(unknown); // ?
@@ -2319,10 +2314,10 @@ uint32 Item::I_legalCreateInCont(const uint8 *args, unsigned int /*argsize*/) {
// Create an item and try to add it to the given container.
// If it fits, return id; otherwise return 0.
- Item *newitem = ItemFactory::createItem(_shape, _frame, 0, 0, 0, 0, 0, true);
+ Item *newitem = ItemFactory::createItem(shape, frame, 0, 0, 0, 0, 0, true);
if (!newitem) {
- perr << "I_legalCreateInCont failed to create item (" << _shape
- << "," << _frame << ")." << Std::endl;
+ perr << "I_legalCreateInCont failed to create item (" << shape
+ << "," << frame << ")." << Std::endl;
return 0;
}
@@ -2417,10 +2412,10 @@ uint32 Item::I_isOn(const uint8 *args, unsigned int /*argsize*/) {
}
uint32 Item::I_getFamilyOfType(const uint8 *args, unsigned int /*argsize*/) {
- ARG_UINT16(_shape);
+ ARG_UINT16(shape);
return GameData::get_instance()->getMainShapes()->
- getShapeInfo(_shape)->_family;
+ getShapeInfo(shape)->_family;
}
uint32 Item::I_push(const uint8 *args, unsigned int /*argsize*/) {
@@ -2434,13 +2429,13 @@ uint32 Item::I_push(const uint8 *args, unsigned int /*argsize*/) {
uint32 Item::I_create(const uint8 *args, unsigned int /*argsize*/) {
ARG_UC_PTR(itemptr); // need to store the item id at *itemptr (????)
- ARG_UINT16(_shape);
- ARG_UINT16(_frame);
+ ARG_UINT16(shape);
+ ARG_UINT16(frame);
- Item *newitem = ItemFactory::createItem(_shape, _frame, 0, 0, 0, 0, 0, true);
+ Item *newitem = ItemFactory::createItem(shape, frame, 0, 0, 0, 0, 0, true);
if (!newitem) {
- perr << "I_create failed to create item (" << _shape
- << "," << _frame << ")." << Std::endl;
+ perr << "I_create failed to create item (" << shape
+ << "," << frame << ")." << Std::endl;
return 0;
}
uint16 objID = newitem->getObjId();
@@ -2572,15 +2567,15 @@ uint32 Item::I_popToEnd(const uint8 *args, unsigned int /*argsize*/) {
uint32 Item::I_move(const uint8 *args, unsigned int /*argsize*/) {
ARG_ITEM_FROM_PTR(item);
- ARG_UINT16(_x);
- ARG_UINT16(_y);
- ARG_UINT16(_z);
+ ARG_UINT16(x);
+ ARG_UINT16(y);
+ ARG_UINT16(z);
if (!item) return 0;
//! What should this do to ethereal items?
- item->move(_x, _y, _z);
- //item->collideMove(_x, _y, _z, true, true);
+ item->move(x, y, z);
+ //item->collideMove(x, y, z, true, true);
return 0;
}
Commit: 17974f9a5f7587deec6ae1a01e5049f6e67db87e
https://github.com/scummvm/scummvm/commit/17974f9a5f7587deec6ae1a01e5049f6e67db87e
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-05-13T20:51:16+09:00
Commit Message:
ULTIMA8: Fix crusader avatar animations a bit
Changed paths:
engines/ultima/ultima8/games/remorse_game.cpp
engines/ultima/ultima8/graphics/anim_dat.cpp
engines/ultima/ultima8/graphics/anim_dat.h
engines/ultima/ultima8/world/actors/animation.h
engines/ultima/ultima8/world/actors/animation_tracker.cpp
diff --git a/engines/ultima/ultima8/games/remorse_game.cpp b/engines/ultima/ultima8/games/remorse_game.cpp
index fc2ccff60d..e79c3edac9 100644
--- a/engines/ultima/ultima8/games/remorse_game.cpp
+++ b/engines/ultima/ultima8/games/remorse_game.cpp
@@ -117,7 +117,7 @@ bool RemorseGame::startGame() {
ObjectManager::get_instance()->assignActorObjId(actor, 1);
if (GAME_IS_REMORSE) {
- actor->setLocation(60700, 59420, 16);
+ actor->setLocation(60716, 59400, 16);
} else {
actor->setLocation(58174, 56606, 16);
}
@@ -134,7 +134,7 @@ bool RemorseGame::startGame() {
}
bool RemorseGame::startInitialUsecode(int saveSlot) {
- //ProcId moviepid = Game::get_instance()->playIntroMovie(false);
+ /*ProcId moviepid =*/ Game::get_instance()->playIntroMovie(false);
//Process *movieproc = Kernel::get_instance()->getProcess(moviepid);
//if (movieproc) {
diff --git a/engines/ultima/ultima8/graphics/anim_dat.cpp b/engines/ultima/ultima8/graphics/anim_dat.cpp
index 7f5d541de2..32270aa36b 100644
--- a/engines/ultima/ultima8/graphics/anim_dat.cpp
+++ b/engines/ultima/ultima8/graphics/anim_dat.cpp
@@ -27,6 +27,7 @@
#include "ultima/ultima8/filesys/idata_source.h"
#include "ultima/ultima8/world/actors/actor_anim.h"
#include "ultima/ultima8/world/actors/anim_action.h"
+#include "ultima/ultima8/world/actors/animation.h"
#include "ultima/ultima8/kernel/core_app.h"
#include "ultima/ultima8/games/game_info.h"
@@ -57,6 +58,57 @@ AnimAction *AnimDat::getAnim(uint32 shape, uint32 action) const {
return _anims[shape]->getAction(action);
}
+uint32 AnimDat::getActionNumberForSequence(Animation::Sequence action) {
+ if (GAME_IS_U8) {
+ return static_cast<uint32>(action);
+ } else {
+ // For crusader the actions have different IDs. Rather than
+ // rewrite everything, we just translate them here for all the ones
+ // we want to use programmatically. There are more, but they are
+ // called from usecode so don't need translation.
+ switch (action) {
+ case Animation::stand:
+ return 0;
+ case Animation::step:
+ return 1; // Same as walk in crusader.
+ case Animation::walk:
+ return 1;
+ case Animation::retreat:
+ return 2; // TODO: 28 is also a retreat move, which is right?
+ case Animation::run:
+ return 3;
+ case Animation::combatStand:
+ return 4; // TODO: 8, 37 is also a combat stand for other weapons?
+ // Note: 5, 6, 9, 10 == nothing (for avatar)?
+ case Animation::unreadyWeapon:
+ return 11; // TODO: 16 is also a unready-weapon move, which is right?
+ case Animation::readyWeapon:
+ return 12; // TODO: 7 is also a ready-weapon move, which is right?
+ case Animation::attack:
+ return 13;
+ // Note: 14, 17, 21, 22, 29 == nothing for avatar
+ case Animation::fallBackwards:
+ return 18;
+ case Animation::die:
+ return 20; // maybe? falls over forwards
+ case Animation::advance:
+ return 36; // TODO: 44 is also advance
+ case Animation::startKneeling:
+ return 40;
+ case Animation::stopKneeling:
+ return 41;
+ case Animation::kneel:
+ return 46; // 47 is knee with a larger weapon
+ // 48 is nothing for avatar
+ case Animation::lookLeft:
+ return 14;
+ case Animation::lookRight:
+ return 14;
+ default:
+ return static_cast<uint32>(action);;
+ }
+ }
+}
void AnimDat::load(Common::SeekableReadStream *rs) {
AnimFrame f;
diff --git a/engines/ultima/ultima8/graphics/anim_dat.h b/engines/ultima/ultima8/graphics/anim_dat.h
index 7c196832e2..36d0ac86dc 100644
--- a/engines/ultima/ultima8/graphics/anim_dat.h
+++ b/engines/ultima/ultima8/graphics/anim_dat.h
@@ -24,6 +24,7 @@
#define ULTIMA8_GRAPHICS_ANIMDAT_H
#include "ultima/shared/std/containers.h"
+#include "ultima/ultima8/world/actors/animation.h"
namespace Ultima {
namespace Ultima8 {
@@ -41,6 +42,8 @@ public:
ActorAnim *getAnim(uint32 shape) const;
AnimAction *getAnim(uint32 shape, uint32 action) const;
+ //! Return the action number for a given animation sequence
+ static uint32 getActionNumberForSequence(Animation::Sequence action);
private:
Std::vector<ActorAnim *> _anims;
};
diff --git a/engines/ultima/ultima8/world/actors/animation.h b/engines/ultima/ultima8/world/actors/animation.h
index fbb6b50457..c37a808ef1 100644
--- a/engines/ultima/ultima8/world/actors/animation.h
+++ b/engines/ultima/ultima8/world/actors/animation.h
@@ -90,10 +90,27 @@ enum Sequence {
burn = 57,
kick = 58,
startBlock = 59,
- stopBlock = 60
+ stopBlock = 60,
//61: unused
//62: unused
//63: unused
+ // Some crusader-specific animations (some use the same IDs as above)
+ reload = 15,
+ combatRollLeft = 23,
+ combatRollRight = 24,
+ walkWithGun = 25,
+ kneelAndFire = 26,
+ slideRight = 29,
+ startRunWithLargeWeapon = 31,
+ teleportIn = 32,
+ teleportOut = 33,
+ startRunWithSmallWeapon = 34,
+ startRunWithLargeWeapon2 = 35,
+ startRun = 38,
+ stopRunningAndDrawWeapon = 39,
+ kneelAndFire2 = 42,
+ kneelAndFire3 = 43,
+ runWithLargeWeapon = 50
};
enum Result {
diff --git a/engines/ultima/ultima8/world/actors/animation_tracker.cpp b/engines/ultima/ultima8/world/actors/animation_tracker.cpp
index f213a1add2..ecad0e284f 100644
--- a/engines/ultima/ultima8/world/actors/animation_tracker.cpp
+++ b/engines/ultima/ultima8/world/actors/animation_tracker.cpp
@@ -27,6 +27,7 @@
#include "ultima/ultima8/world/world.h"
#include "ultima/ultima8/world/current_map.h"
#include "ultima/ultima8/graphics/main_shape_archive.h"
+#include "ultima/ultima8/graphics/anim_dat.h"
#include "ultima/ultima8/world/actors/anim_action.h"
#include "ultima/ultima8/misc/direction.h"
#include "ultima/ultima8/graphics/shape_info.h"
@@ -56,13 +57,15 @@ AnimationTracker::AnimationTracker() : _firstFrame(true), _done(false),
AnimationTracker::~AnimationTracker() {
}
+
bool AnimationTracker::init(const Actor *actor, Animation::Sequence action,
uint32 dir, const PathfindingState *state) {
assert(actor);
_actor = actor->getObjId();
uint32 shape = actor->getShape();
+ uint32 actionnum = AnimDat::getActionNumberForSequence(action);
_animAction = GameData::get_instance()->getMainShapes()->
- getAnim(shape, action);
+ getAnim(shape, actionnum);
if (!_animAction)
return false;
@@ -88,8 +91,8 @@ bool AnimationTracker::init(const Actor *actor, Animation::Sequence action,
#ifdef WATCHACTOR
if (actor && actor->getObjId() == watchactor) {
- pout << "AnimationTracker: playing " << _startFrame << "-" << _endFrame
- << " (_animAction flags: " << Std::hex << _animAction->flags
+ pout << "AnimationTracker: playing action " << actionnum << " " << _startFrame << "-" << _endFrame
+ << " (_animAction flags: " << Std::hex << _animAction->_flags
<< Std::dec << ")" << Std::endl;
}
@@ -280,7 +283,7 @@ bool AnimationTracker::step() {
#ifdef WATCHACTOR
if (a->getObjId() == watchactor) {
pout << "AnimationTracker: did sweepTest for large step; "
- << "collision at time " << it->hit_time << Std::endl;
+ << "collision at time " << it->_hitTime << Std::endl;
}
#endif
_blocked = true;
@@ -468,8 +471,8 @@ void AnimationTracker::checkWeaponHit() {
#ifdef WATCHACTOR
if (a->getObjId() == watchactor) {
pout << "AnimationTracker: Checking hit, range " << range << ", box "
- << abox._x << "," << abox._y << "," << abox._z << "," << abox.xd
- << "," << abox.yd << "," << abox.zd << ": ";
+ << abox._x << "," << abox._y << "," << abox._z << "," << abox._xd
+ << "," << abox._yd << "," << abox._zd << ": ";
}
#endif
Commit: 66f10c6dc8ba729e9c40f12dd710f6d94d9917a7
https://github.com/scummvm/scummvm/commit/66f10c6dc8ba729e9c40f12dd710f6d94d9917a7
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-05-13T20:51:16+09:00
Commit Message:
ULTIMA8: Add a 'start crusader' process
Changed paths:
A engines/ultima/ultima8/games/start_crusader_process.cpp
A engines/ultima/ultima8/games/start_crusader_process.h
engines/ultima/module.mk
engines/ultima/ultima8/audio/remorse_music_process.cpp
engines/ultima/ultima8/games/remorse_game.cpp
engines/ultima/ultima8/games/remorse_game.h
diff --git a/engines/ultima/module.mk b/engines/ultima/module.mk
index 5aa3cd17b3..27f9e1f4be 100644
--- a/engines/ultima/module.mk
+++ b/engines/ultima/module.mk
@@ -412,6 +412,7 @@ MODULE_OBJS := \
ultima8/games/game_data.o \
ultima8/games/game_info.o \
ultima8/games/remorse_game.o \
+ ultima8/games/start_crusader_process.o \
ultima8/games/start_u8_process.o \
ultima8/games/treasure_loader.o \
ultima8/games/u8_game.o \
diff --git a/engines/ultima/ultima8/audio/remorse_music_process.cpp b/engines/ultima/ultima8/audio/remorse_music_process.cpp
index cee7e32f9f..3ef1f766a2 100644
--- a/engines/ultima/ultima8/audio/remorse_music_process.cpp
+++ b/engines/ultima/ultima8/audio/remorse_music_process.cpp
@@ -69,7 +69,8 @@ RemorseMusicProcess::~RemorseMusicProcess() {
Audio::Mixer *mixer = Ultima8Engine::get_instance()->_mixer;
assert(mixer);
mixer->stopHandle(_soundHandle);
- delete _playingStream;
+ // FIXME: Some destruction order problem here..
+ //delete _playingStream;
}
}
diff --git a/engines/ultima/ultima8/games/remorse_game.cpp b/engines/ultima/ultima8/games/remorse_game.cpp
index e79c3edac9..dfa4fd8f2f 100644
--- a/engines/ultima/ultima8/games/remorse_game.cpp
+++ b/engines/ultima/ultima8/games/remorse_game.cpp
@@ -22,6 +22,7 @@
#include "ultima/ultima8/misc/pent_include.h"
#include "ultima/ultima8/games/remorse_game.h"
+#include "ultima/ultima8/games/start_crusader_process.h"
#include "ultima/ultima8/conf/setting_manager.h"
#include "ultima/ultima8/filesys/file_system.h"
#include "ultima/ultima8/filesys/idata_source.h"
@@ -73,8 +74,6 @@ static bool loadPalette(const char *path, PaletteManager::PalIndex index) {
bool RemorseGame::loadFiles() {
// Load palette
pout << "Load Palettes" << Std::endl;
-
-
if (!loadPalette("@game/static/gamepal.pal", PaletteManager::Pal_Game))
return false;
@@ -123,28 +122,13 @@ bool RemorseGame::startGame() {
}
World::get_instance()->switchMap(1);
-
- Gump *statusGump = new CruStatusGump();
- statusGump->InitGump(nullptr);
-
- //Ultima8Engine::get_instance()->setAvatarInStasis(true);
- Ultima8Engine::get_instance()->setCheatMode(true);
return true;
}
bool RemorseGame::startInitialUsecode(int saveSlot) {
- /*ProcId moviepid =*/ Game::get_instance()->playIntroMovie(false);
- //Process *movieproc = Kernel::get_instance()->getProcess(moviepid);
-
- //if (movieproc) {
- // waitFor(movieproc);
- // return;
- //}
-
-// Process* proc = new StartCrusaderProcess();
-// Kernel::get_instance()->addProcess(proc);
-
+ Process* proc = new StartCrusaderProcess();
+ Kernel::get_instance()->addProcess(proc);
return true;
}
@@ -162,10 +146,14 @@ static ProcId playMovie(const char *movieID, bool fade) {
}
ProcId RemorseGame::playIntroMovie(bool fade) {
+ return playMovie("T01", fade);
+}
+
+ProcId RemorseGame::playIntroMovie2(bool fade) {
return playMovie("T02", fade);
- // TODO: also play T02
}
+
ProcId RemorseGame::playEndgameMovie(bool fade) {
return playMovie("O01", fade);
}
diff --git a/engines/ultima/ultima8/games/remorse_game.h b/engines/ultima/ultima8/games/remorse_game.h
index b4816b367f..28ef88e89b 100644
--- a/engines/ultima/ultima8/games/remorse_game.h
+++ b/engines/ultima/ultima8/games/remorse_game.h
@@ -46,6 +46,7 @@ public:
void writeSaveInfo(Common::WriteStream *ws) override;
ProcId playIntroMovie(bool fade) override;
+ ProcId playIntroMovie2(bool fade);
ProcId playEndgameMovie(bool fade) override;
void playCredits() override;
void playQuotes() override { };
diff --git a/engines/ultima/ultima8/games/start_crusader_process.cpp b/engines/ultima/ultima8/games/start_crusader_process.cpp
new file mode 100644
index 0000000000..46dc8b1ce1
--- /dev/null
+++ b/engines/ultima/ultima8/games/start_crusader_process.cpp
@@ -0,0 +1,132 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "ultima/ultima8/misc/pent_include.h"
+
+#include "ultima/ultima8/games/start_crusader_process.h"
+#include "ultima/ultima8/games/game.h"
+#include "ultima/ultima8/games/remorse_game.h"
+#include "ultima/ultima8/world/loop_script.h"
+#include "ultima/ultima8/usecode/uc_list.h"
+#include "ultima/ultima8/world/current_map.h"
+#include "ultima/ultima8/world/egg.h"
+#include "ultima/ultima8/world/camera_process.h"
+#include "ultima/ultima8/world/world.h"
+#include "ultima/ultima8/ultima8.h"
+#include "ultima/ultima8/kernel/kernel.h"
+#include "ultima/ultima8/gumps/menu_gump.h"
+#include "ultima/ultima8/gumps/cru_status_gump.h"
+#include "ultima/ultima8/conf/setting_manager.h"
+#include "ultima/ultima8/world/get_object.h"
+#include "ultima/ultima8/graphics/palette_fader_process.h"
+#include "ultima/ultima8/audio/music_process.h"
+
+namespace Ultima {
+namespace Ultima8 {
+
+// p_dynamic_cast stuff
+DEFINE_RUNTIME_CLASSTYPE_CODE(StartCrusaderProcess, Process)
+
+StartCrusaderProcess::StartCrusaderProcess(int saveSlot) : Process(),
+ _initStage(PlayFirstMovie), _saveSlot(saveSlot), _skipStart(saveSlot >= 0) {
+}
+
+
+void StartCrusaderProcess::run() {
+ if (!_skipStart && _initStage == PlayFirstMovie) {
+ _initStage = PlaySecondMovie;
+ ProcId moviepid = Game::get_instance()->playIntroMovie(false);
+ Process *movieproc = Kernel::get_instance()->getProcess(moviepid);
+ if (movieproc) {
+ waitFor(movieproc);
+ return;
+ }
+ } else if (!_skipStart && _initStage == PlaySecondMovie) {
+ _initStage = ShowMenu;
+ RemorseGame *game = dynamic_cast<RemorseGame *>(Game::get_instance());
+ assert(game);
+ ProcId moviepid = game->playIntroMovie2(false);
+ Process *movieproc = Kernel::get_instance()->getProcess(moviepid);
+ if (movieproc) {
+ waitFor(movieproc);
+ return;
+ }
+ }
+
+ Gump *statusGump = new CruStatusGump();
+ statusGump->InitGump(nullptr);
+
+ // Try to load the save game, if succeeded this pointer will no longer be valid
+ if (_saveSlot >= 0 &&Ultima8Engine::get_instance()->loadGameState(_saveSlot).getCode() == Common::kNoError) {
+ //PaletteFaderProcess::I_fadeFromBlack(0, 0);
+ return;
+ }
+
+ Ultima8Engine::get_instance()->setCheatMode(true);
+
+ //CurrentMap *currentmap = World::get_instance()->getCurrentMap();
+ //UCList uclist(2);
+
+ if (!_skipStart) {
+ // TODO: Find the first MISS1EGG egg like in U8 - should teleport in
+ /*
+ LOOPSCRIPT(script, LS_AND(LS_SHAPE_EQUAL1(73), LS_Q_EQUAL(36)));
+ currentmap->areaSearch(&uclist, script, sizeof(script),
+ 0, 256, false, 16188, 7500);
+ if (uclist.getSize() < 1) {
+ perr << "Unable to find FIRST egg!" << Std::endl;
+ return;
+ }
+
+ uint16 objid = uclist.getuint16(0);
+ Egg *egg = p_dynamic_cast<Egg *>(getObject(objid));
+ int32 ix, iy, iz;
+ egg->getLocation(ix, iy, iz);
+ // Center on egg
+ CameraProcess::SetCameraProcess(new CameraProcess(ix, iy, iz));
+ egg->hatch();
+ */
+
+ }
+
+ MusicProcess::get_instance()->playMusic(2);
+
+ Ultima8Engine::get_instance()->setAvatarInStasis(false);
+
+
+ terminate();
+}
+
+void StartCrusaderProcess::saveData(Common::WriteStream *ws) {
+ CANT_HAPPEN();
+
+ Process::saveData(ws);
+}
+
+bool StartCrusaderProcess::loadData(Common::ReadStream *rs, uint32 version) {
+ if (!Process::loadData(rs, version)) return false;
+
+ return true;
+}
+
+} // End of namespace Ultima8
+} // End of namespace Ultima
diff --git a/engines/ultima/ultima8/games/start_crusader_process.h b/engines/ultima/ultima8/games/start_crusader_process.h
new file mode 100644
index 0000000000..da958a27c7
--- /dev/null
+++ b/engines/ultima/ultima8/games/start_crusader_process.h
@@ -0,0 +1,62 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ULTIMA8_GAMES_STARTCRUSADERPROCESS_H
+#define ULTIMA8_GAMES_STARTCRUSADERPROCESS_H
+
+#include "ultima/ultima8/kernel/process.h"
+#include "ultima/ultima8/misc/p_dynamic_cast.h"
+
+namespace Ultima {
+namespace Ultima8 {
+
+class Item;
+
+class StartCrusaderProcess : public Process {
+public:
+ enum CruInitStage {
+ PlayFirstMovie,
+ PlaySecondMovie,
+ ShowMenu
+ };
+
+protected:
+ CruInitStage _initStage;
+ bool _skipStart;
+ int _saveSlot;
+
+ void saveData(Common::WriteStream *ws) override;
+public:
+ StartCrusaderProcess(int saveSlot = -1);
+
+ // p_dynamic_cast stuff
+ ENABLE_RUNTIME_CLASSTYPE()
+
+ void run() override;
+
+ bool loadData(Common::ReadStream *rs, uint32 version);
+};
+
+} // End of namespace Ultima8
+} // End of namespace Ultima
+
+#endif
More information about the Scummvm-git-logs
mailing list