[Scummvm-git-logs] scummvm master -> 6e9f7abc7becd04131126b36ae5639e2c2b585ac
athrxx
noreply at scummvm.org
Tue Jul 11 12:35:55 UTC 2023
This automated email contains information about 6 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
3c64b08d7a KYRA: (EOB II/PC98) - minor sound code adjustments
a15ce9a202 KYRA: (LOL/ZH) - text displayer fixes
5e8333f638 KYRA: (EOB II/ZH) - fix/improve text display
1831f02c36 KYRA: (EOB/LOL) - reduce text displayer hacks
8510798d44 KYRA: (EOB II/ZH) - add missing kyradat resources
6e9f7abc7b KYRA: (EOB II/ZH) - fix dialogue buttons
Commit: 3c64b08d7aa7dbdeeae79762f6b187d8ceea3251
https://github.com/scummvm/scummvm/commit/3c64b08d7aa7dbdeeae79762f6b187d8ceea3251
Author: athrxx (athrxx at scummvm.org)
Date: 2023-07-11T14:34:31+02:00
Commit Message:
KYRA: (EOB II/PC98) - minor sound code adjustments
Changed paths:
engines/kyra/sound/drivers/capcom98.cpp
diff --git a/engines/kyra/sound/drivers/capcom98.cpp b/engines/kyra/sound/drivers/capcom98.cpp
index edbb0be0eda..8a130bf426d 100644
--- a/engines/kyra/sound/drivers/capcom98.cpp
+++ b/engines/kyra/sound/drivers/capcom98.cpp
@@ -21,9 +21,11 @@
#ifdef ENABLE_EOB
+#include "kyra/kyra_v1.h"
#include "kyra/sound/drivers/capcom98.h"
#include "audio/mixer.h"
#include "audio/softsynth/fmtowns_pc98/pc98_audio.h"
+#include "common/debug.h"
#include "common/func.h"
#include "common/system.h"
@@ -103,12 +105,12 @@ private:
const uint16 _playFlags;
};
-class CapcomPC98_MIDI final : public CapcomPC98Player {
+class CapcomPC98Player_MIDI final : public CapcomPC98Player {
public:
typedef Common::Functor0Mem<PC98AudioCore::MutexLock, CapcomPC98AudioDriverInternal> MutexProc;
- CapcomPC98_MIDI(MidiDriver::DeviceHandle dev, bool isMT32, MutexProc &mutexProc);
- ~CapcomPC98_MIDI();
+ CapcomPC98Player_MIDI(MidiDriver::DeviceHandle dev, bool isMT32, MutexProc &mutexProc);
+ ~CapcomPC98Player_MIDI();
bool init() override;
void deinit() override {}
@@ -132,10 +134,10 @@ private:
MutexProc &_mproc;
};
-class CapcomPC98_FM_Channel {
+class CapcomPC98_FMChannel {
public:
- CapcomPC98_FM_Channel(uint8 id, PC98AudioCore *&ac, const Common::Array<const uint8*>&instruments, const uint8 &fadeState);
- ~CapcomPC98_FM_Channel();
+ CapcomPC98_FMChannel(uint8 id, PC98AudioCore *&ac, const Common::Array<const uint8*>&instruments, const uint8 &fadeState);
+ ~CapcomPC98_FMChannel();
void reset();
@@ -157,7 +159,7 @@ public:
void processSounds();
private:
- typedef Common::Functor0Mem<void, CapcomPC98_FM_Channel> VbrHandlerProc;
+ typedef Common::Functor0Mem<void, CapcomPC98_FMChannel> VbrHandlerProc;
const uint8 _regOffset;
uint8 _program;
@@ -230,12 +232,12 @@ private:
static const uint8 _volTablePara[128];
};
-class CapcomPC98_FM final : public CapcomPC98Player, PC98AudioPluginDriver {
+class CapcomPC98Player_FM final : public CapcomPC98Player, PC98AudioPluginDriver {
public:
typedef Common::Functor0Mem<void, CapcomPC98AudioDriverInternal> CBProc;
- CapcomPC98_FM(Audio::Mixer *mixer, CBProc &cbproc, bool playerPrio, uint16 playFlags, uint8 chanReserveFlags, uint8 chanDisableFlags, uint16 volControlMask, bool needsTimer);
- ~CapcomPC98_FM() override;
+ CapcomPC98Player_FM(Audio::Mixer *mixer, CBProc &cbproc, bool playerPrio, uint16 playFlags, uint8 chanReserveFlags, uint8 chanDisableFlags, uint16 volControlMask, bool needsTimer);
+ ~CapcomPC98Player_FM() override;
bool init() override;
void deinit() override;
@@ -256,7 +258,7 @@ private:
void restoreStateIntern() override;
PC98AudioCore *_ac;
- CapcomPC98_FM_Channel **_chan;
+ CapcomPC98_FMChannel **_chan;
Common::Array<const uint8*>_instruments;
CBProc &_cbProc;
@@ -301,9 +303,9 @@ private:
void updateMasterVolume();
CapcomPC98Player *_players[2];
- CapcomPC98_FM *_fmDevice;
- CapcomPC98_FM::CBProc *_timerProc;
- CapcomPC98_MIDI::MutexProc *_mutexProc;
+ CapcomPC98Player_FM *_fmDevice;
+ CapcomPC98Player_FM::CBProc *_timerProc;
+ CapcomPC98Player_MIDI::MutexProc *_mutexProc;
static CapcomPC98AudioDriverInternal *_refInstance;
static int _refCount;
@@ -355,6 +357,7 @@ void CapcomPC98Player::fadeOut(uint16 speed) {
if (speed) {
_fadeTicker =_fadeSpeed = speed;
_fadeState = 0;
+ PC98AudioCore::MutexLock lock = lockMutex();
_flags |= kFadeOut;
} else {
stopSound();
@@ -362,6 +365,7 @@ void CapcomPC98Player::fadeOut(uint16 speed) {
}
void CapcomPC98Player::allNotesOff(uint16 chanFlags) {
+ PC98AudioCore::MutexLock lock = lockMutex();
for (int i = 0; i < 16; ++i) {
if ((1 << i) & chanFlags)
send(0x007BB0 | i);
@@ -369,11 +373,13 @@ void CapcomPC98Player::allNotesOff(uint16 chanFlags) {
}
void CapcomPC98Player::setMusicVolume (int vol) {
+ PC98AudioCore::MutexLock lock = lockMutex();
_musicVolume = vol;
updateMasterVolume();
}
void CapcomPC98Player::setSoundEffectVolume (int vol) {
+ PC98AudioCore::MutexLock lock = lockMutex();
_sfxVolume = vol;
updateMasterVolume();
}
@@ -482,7 +488,7 @@ void CapcomPC98Player::restorePlayer() {
_storedEvents.clear();
}
-CapcomPC98_MIDI::CapcomPC98_MIDI(MidiDriver::DeviceHandle dev, bool isMT32, MutexProc &mutexProc) : CapcomPC98Player(true, kStdPlay, 0xFFFF, 0), _isMT32(isMT32), _mproc(mutexProc), _midi(nullptr), _programMapping(nullptr) {
+CapcomPC98Player_MIDI::CapcomPC98Player_MIDI(MidiDriver::DeviceHandle dev, bool isMT32, MutexProc &mutexProc) : CapcomPC98Player(true, kStdPlay, 0xFFFF, 0), _isMT32(isMT32), _mproc(mutexProc), _midi(nullptr), _programMapping(nullptr) {
_midi = MidiDriver::createMidi(dev);
uint8 *map = new uint8[128];
assert(map);
@@ -498,13 +504,13 @@ CapcomPC98_MIDI::CapcomPC98_MIDI(MidiDriver::DeviceHandle dev, bool isMT32, Mute
memset(_chanVolume, 0, sizeof(_chanVolume));
}
-CapcomPC98_MIDI::~CapcomPC98_MIDI() {
+CapcomPC98Player_MIDI::~CapcomPC98Player_MIDI() {
_midi->close();
delete _midi;
delete[] _programMapping;
}
-bool CapcomPC98_MIDI::init() {
+bool CapcomPC98Player_MIDI::init() {
if (!_midi || !_programMapping)
return false;
@@ -527,16 +533,18 @@ bool CapcomPC98_MIDI::init() {
return true;
}
-void CapcomPC98_MIDI::reset() {
+void CapcomPC98Player_MIDI::reset() {
memset(_chanVolume, 0x7F, sizeof(_chanVolume));
}
-void CapcomPC98_MIDI::send(uint32 evt) {
+void CapcomPC98Player_MIDI::send(uint32 evt) {
uint8 cmd = evt & 0xF0;
uint8 ch = evt & 0x0F;
uint8 p1 = (evt >> 8) & 0xFF;
uint8 p2 = (evt >> 16) & 0xFF;
+ debugC(5, kDebugLevelSound, "CapcomPC98Player_MIDI::send(): [0x%02x] [0x%02x] [0x%02x]", evt & 0xff, p1, p2);
+
if (cmd == 0xC0) {
evt = (evt & 0xFF) | (_programMapping[p1] << 8);
} else if (cmd == 0xB0) {
@@ -546,25 +554,29 @@ void CapcomPC98_MIDI::send(uint32 evt) {
} else if (((evt >> 8) & 0xFF) == 7) {
_chanVolume[ch] = p2;
}
+ } else if (evt == 0xF0) {
+ // This doesn't seem to be used at all. So I haven't implemented it (yet).
+ warning("CapcomPC98Player_MIDI::send(): Unhandled sysex message encountered");
}
+
_midi->send(evt);
}
-void CapcomPC98_MIDI::processSounds() {
+void CapcomPC98Player_MIDI::processSounds() {
if (_fadeState) {
for (int i = 0; i < 16; ++i)
_midi->send(0x0007B0 | i | (CLIP<int>(_chanVolume[i] - _fadeState, 0, 127) << 16));
}
}
-PC98AudioCore::MutexLock CapcomPC98_MIDI::lockMutex() {
+PC98AudioCore::MutexLock CapcomPC98Player_MIDI::lockMutex() {
if (!_mproc.isValid())
error("CapcomPC98_MIDI::lockMutex(): Invalid call");
return _mproc();
}
-void CapcomPC98_MIDI::updateMasterVolume() {
- // This driver is not used for sound effects. So I don't add support for sound effects volume control.
+void CapcomPC98Player_MIDI::updateMasterVolume() {
+ // This player is not used for sound effects. So I don't add support for sound effects volume control here.
if (_isMT32) {
byte vol = _musicVolume * 100 / Audio::Mixer::kMaxMixerVolume;
byte mt32VolSysEx[9] = { 0x41, 0x10, 0x16, 0x12, 0x10, 0x00, 0x16, vol, 0x00 };
@@ -584,7 +596,7 @@ void CapcomPC98_MIDI::updateMasterVolume() {
}
// This is not identical to the one we have in our common code (not even similar).
-const uint8 CapcomPC98_MIDI::_programMapping_mt32ToGM[128] = {
+const uint8 CapcomPC98Player_MIDI::_programMapping_mt32ToGM[128] = {
0x00, 0x02, 0x01, 0x03, 0x04, 0x05, 0x10, 0x13, 0x16, 0x65, 0x0a, 0x00, 0x68, 0x67, 0x2e, 0x25,
0x08, 0x09, 0x0a, 0x0c, 0x0d, 0x0e, 0x57, 0x38, 0x3b, 0x3c, 0x3d, 0x3e, 0x3b, 0x3b, 0x3b, 0x1f,
0x3d, 0x1c, 0x1c, 0x1c, 0x1c, 0x1e, 0x1f, 0x1f, 0x35, 0x38, 0x37, 0x38, 0x36, 0x33, 0x39, 0x70,
@@ -595,17 +607,17 @@ const uint8 CapcomPC98_MIDI::_programMapping_mt32ToGM[128] = {
0x70, 0x71, 0x72, 0x76, 0x75, 0x74, 0x73, 0x77, 0x78, 0x79, 0x7a, 0x7c, 0x7b, 0x7d, 0x7e, 0x7f
};
-CapcomPC98_FM_Channel::CapcomPC98_FM_Channel(uint8 id, PC98AudioCore *&ac, const Common::Array<const uint8*>&instruments, const uint8 &fadeState) : _regOffset(id), _ac(ac), _instruments(instruments),
+CapcomPC98_FMChannel::CapcomPC98_FMChannel(uint8 id, PC98AudioCore *&ac, const Common::Array<const uint8*>&instruments, const uint8 &fadeState) : _regOffset(id), _ac(ac), _instruments(instruments),
_isPlaying(false), _note(0), _carrier(0), _volume(0), _velocity(0), _noteEffCur(0), _program(0), _noteEffPrev(0), _breathControl(0), _frequency(0), _modWheel(0), _pitchBendSensitivity(0),
_pitchBendPara(0), _pitchBendEff(0), _vbrState(0), _vbrStep(0), _vbrCycleTicker(0), _vbrDelayTicker(0), _vbrHandler(nullptr), _prtEnable(false),
_prtTime(0), _prtState(0), _prtStep(0), _prtCycleLength(0), _fadeState(fadeState) {
- typedef void (CapcomPC98_FM_Channel::*Proc)();
+ typedef void (CapcomPC98_FMChannel::*Proc)();
static const Proc procs[] = {
- &CapcomPC98_FM_Channel::vbrHandler0,
- &CapcomPC98_FM_Channel::vbrHandler1,
- &CapcomPC98_FM_Channel::vbrHandler2,
- &CapcomPC98_FM_Channel::vbrHandler3,
- &CapcomPC98_FM_Channel::dummyProc
+ &CapcomPC98_FMChannel::vbrHandler0,
+ &CapcomPC98_FMChannel::vbrHandler1,
+ &CapcomPC98_FMChannel::vbrHandler2,
+ &CapcomPC98_FMChannel::vbrHandler3,
+ &CapcomPC98_FMChannel::dummyProc
};
assert(ARRAYSIZE(_vbrHandlers) == ARRAYSIZE(procs));
@@ -621,14 +633,14 @@ CapcomPC98_FM_Channel::CapcomPC98_FM_Channel(uint8 id, PC98AudioCore *&ac, const
reset();
}
-CapcomPC98_FM_Channel::~CapcomPC98_FM_Channel() {
+CapcomPC98_FMChannel::~CapcomPC98_FMChannel() {
for (int i = 0; i < ARRAYSIZE(_vbrHandlers); ++i)
delete _vbrHandlers[i];
delete[] _instrument.regData;
}
-void CapcomPC98_FM_Channel::reset() {
+void CapcomPC98_FMChannel::reset() {
_vbrHandler = _vbrHandlers[4];
_frequency = 0xFFFF;
_vbrState = 0;
@@ -646,18 +658,18 @@ void CapcomPC98_FM_Channel::reset() {
_modWheel = 0;
}
-void CapcomPC98_FM_Channel::keyOff() {
+void CapcomPC98_FMChannel::keyOff() {
_ac->writeReg(0, 0x28, _regOffset);
}
-void CapcomPC98_FM_Channel::noteOff(uint8 note) {
+void CapcomPC98_FMChannel::noteOff(uint8 note) {
if (!_isPlaying || _note != note)
return;
keyOff();
_isPlaying = false;
}
-void CapcomPC98_FM_Channel::noteOn(uint8 note, uint8 velo) {
+void CapcomPC98_FMChannel::noteOn(uint8 note, uint8 velo) {
_noteEffPrev = _noteEffCur;
_note = note;
_velocity = velo;
@@ -683,7 +695,7 @@ void CapcomPC98_FM_Channel::noteOn(uint8 note, uint8 velo) {
_isPlaying = true;
}
-void CapcomPC98_FM_Channel::programChange(uint8 prg) {
+void CapcomPC98_FMChannel::programChange(uint8 prg) {
if (prg >= _instruments.size())
return;
@@ -709,45 +721,45 @@ void CapcomPC98_FM_Channel::programChange(uint8 prg) {
setupVibrato();
}
-void CapcomPC98_FM_Channel::pitchBend(uint16 pb) {
+void CapcomPC98_FMChannel::pitchBend(uint16 pb) {
_pitchBendPara = (pb - 0x2000) << 2;
updatePitchBend();
}
-void CapcomPC98_FM_Channel::restore() {
+void CapcomPC98_FMChannel::restore() {
programChange(_program);
_frequency = 0xFFFF;
}
-void CapcomPC98_FM_Channel::modWheel(uint8 mw) {
+void CapcomPC98_FMChannel::modWheel(uint8 mw) {
_modWheel = mw;
}
-void CapcomPC98_FM_Channel::breathControl(uint8 bc) {
+void CapcomPC98_FMChannel::breathControl(uint8 bc) {
_breathControl = bc;
updateVolume();
}
-void CapcomPC98_FM_Channel::pitchBendSensitivity(uint8 pbs) {
+void CapcomPC98_FMChannel::pitchBendSensitivity(uint8 pbs) {
_pitchBendSensitivity = pbs;
pitchBend(_pitchBendPara);
}
-void CapcomPC98_FM_Channel::portamentoTime(uint8 pt) {
+void CapcomPC98_FMChannel::portamentoTime(uint8 pt) {
_prtTime = pt;
}
-void CapcomPC98_FM_Channel::volume(uint8 vol) {
+void CapcomPC98_FMChannel::volume(uint8 vol) {
_volume = vol;
if (_isPlaying)
updateVolume();
}
-void CapcomPC98_FM_Channel::togglePortamento(uint8 enable) {
+void CapcomPC98_FMChannel::togglePortamento(uint8 enable) {
_prtEnable = (enable >= 0x40);
}
-void CapcomPC98_FM_Channel::allNotesOff() {
+void CapcomPC98_FMChannel::allNotesOff() {
_isPlaying = false;
for (int i = _regOffset; i < 16 + _regOffset; i += 4) {
_ac->writeReg(0, 0x40 + i, 0x7F);
@@ -756,7 +768,7 @@ void CapcomPC98_FM_Channel::allNotesOff() {
_ac->writeReg(0, 0x28, _regOffset);
}
-void CapcomPC98_FM_Channel::processSounds() {
+void CapcomPC98_FMChannel::processSounds() {
if (!_isPlaying)
return;
@@ -769,7 +781,7 @@ void CapcomPC98_FM_Channel::processSounds() {
updateVolume();
}
-void CapcomPC98_FM_Channel::loadInstrument(const uint8 *in) {
+void CapcomPC98_FMChannel::loadInstrument(const uint8 *in) {
memcpy(_instrument.name, in, 8);
in += 8;
_instrument.fbl_alg = *in++;
@@ -788,12 +800,12 @@ void CapcomPC98_FM_Channel::loadInstrument(const uint8 *in) {
memcpy(_instrument.regData, in, 52);
}
-void CapcomPC98_FM_Channel::updatePitchBend() {
+void CapcomPC98_FMChannel::updatePitchBend() {
_pitchBendEff = (_pitchBendPara * (_pitchBendSensitivity << 1)) >> 16;
updateFrequency();
}
-void CapcomPC98_FM_Channel::updateVolume() {
+void CapcomPC98_FMChannel::updateVolume() {
uint8 cr = _carrier;
const uint8 *s = _instrument.regData;
for (int i = _regOffset; i < 16 + _regOffset; i += 4) {
@@ -839,7 +851,7 @@ void CapcomPC98_FM_Channel::updateVolume() {
}
}
-void CapcomPC98_FM_Channel::updatePortamento() {
+void CapcomPC98_FMChannel::updatePortamento() {
if (_prtCycleLength) {
_prtCycleLength--;
_prtState += _prtStep;
@@ -848,7 +860,7 @@ void CapcomPC98_FM_Channel::updatePortamento() {
}
}
-void CapcomPC98_FM_Channel::updateFrequency() {
+void CapcomPC98_FMChannel::updateFrequency() {
int16 tone = (MIN<int16>(_modWheel + _instrument.vbrSensitivity, 255) * (_vbrState >> 16)) >> 8;
tone = CLIP<int16>(tone + (_noteEffCur << 8), 0, 0x5FFF);
tone = CLIP<int16>(tone + _pitchBendEff, 0, 0x5FFF);
@@ -867,7 +879,7 @@ void CapcomPC98_FM_Channel::updateFrequency() {
_ac->writeReg(0, 0xA0 + _regOffset, freq & 0xFF);
}
-void CapcomPC98_FM_Channel::setupPortamento() {
+void CapcomPC98_FMChannel::setupPortamento() {
if (!_prtTime || !_prtEnable) {
_prtCycleLength = 0;
_prtState = 0;
@@ -880,7 +892,7 @@ void CapcomPC98_FM_Channel::setupPortamento() {
_prtState = (-diff << 16);
}
-void CapcomPC98_FM_Channel::setupVibrato() {
+void CapcomPC98_FMChannel::setupVibrato() {
_vbrHandler = _vbrHandlers[4];
if (_instrument.vbrCycleLength == 0 || _instrument.vbrType > 4)
@@ -898,7 +910,7 @@ void CapcomPC98_FM_Channel::setupVibrato() {
break;
case 1:
- _vbrState = _vbrDelayTicker ? 0 : 3072 << 16;
+ _vbrState = _vbrDelayTicker ? 0 : (3072 << 16);
_vbrCycleTicker = 0;
_vbrHandler = _vbrHandlers[1];
break;
@@ -906,7 +918,7 @@ void CapcomPC98_FM_Channel::setupVibrato() {
case 2:
case 3:
_vbrStep = (6144 << 16) / _instrument.vbrCycleLength;
- _vbrState = _vbrDelayTicker ? 0 : (_instrument.vbrType == 2 ? -3072 : 3072) << 16;
+ _vbrState = _vbrDelayTicker ? 0 : ((_instrument.vbrType == 2 ? -3072 : 3072) << 16);
_vbrCycleTicker = _instrument.vbrCycleLength - 1;
_vbrHandler = _vbrHandlers[_instrument.vbrType];
@@ -917,7 +929,7 @@ void CapcomPC98_FM_Channel::setupVibrato() {
}
}
-void CapcomPC98_FM_Channel::vbrHandler0() {
+void CapcomPC98_FMChannel::vbrHandler0() {
if (_vbrDelayTicker) {
_vbrDelayTicker--;
return;
@@ -934,7 +946,7 @@ void CapcomPC98_FM_Channel::vbrHandler0() {
}
}
-void CapcomPC98_FM_Channel::vbrHandler1() {
+void CapcomPC98_FMChannel::vbrHandler1() {
if (_vbrDelayTicker) {
_vbrDelayTicker--;
return;
@@ -946,7 +958,7 @@ void CapcomPC98_FM_Channel::vbrHandler1() {
_vbrCycleTicker = 0;
}
-void CapcomPC98_FM_Channel::vbrHandler2() {
+void CapcomPC98_FMChannel::vbrHandler2() {
if (_vbrDelayTicker) {
_vbrDelayTicker--;
return;
@@ -960,7 +972,7 @@ void CapcomPC98_FM_Channel::vbrHandler2() {
}
}
-void CapcomPC98_FM_Channel::vbrHandler3() {
+void CapcomPC98_FMChannel::vbrHandler3() {
if (_vbrDelayTicker) {
_vbrDelayTicker--;
return;
@@ -974,11 +986,11 @@ void CapcomPC98_FM_Channel::vbrHandler3() {
}
}
-const uint16 CapcomPC98_FM_Channel::_freqMSBTable[] = {
+const uint16 CapcomPC98_FMChannel::_freqMSBTable[] = {
0x026a, 0x028f, 0x02b6, 0x02df, 0x030b, 0x0339, 0x036a, 0x039e, 0x03d5, 0x0410, 0x044e, 0x048f
};
-const uint8 CapcomPC98_FM_Channel::_freqLSBTables[12][64] = {
+const uint8 CapcomPC98_FMChannel::_freqLSBTables[12][64] = {
{
0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, 0x08, 0x08, 0x09,
0x09, 0x0a, 0x0a, 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x0f, 0x10, 0x11, 0x11, 0x12,
@@ -1053,7 +1065,7 @@ const uint8 CapcomPC98_FM_Channel::_freqLSBTables[12][64] = {
}
};
-const uint8 CapcomPC98_FM_Channel::_volTablesInst[4][128] = {
+const uint8 CapcomPC98_FMChannel::_volTablesInst[4][128] = {
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
@@ -1095,7 +1107,7 @@ const uint8 CapcomPC98_FM_Channel::_volTablesInst[4][128] = {
}
};
-const uint8 CapcomPC98_FM_Channel::_volTableCarrier[] = {
+const uint8 CapcomPC98_FMChannel::_volTableCarrier[] = {
0x2a, 0x2a, 0x29, 0x29, 0x29, 0x28, 0x28, 0x28, 0x27, 0x27, 0x27, 0x26, 0x26, 0x26, 0x25, 0x25,
0x25, 0x24, 0x24, 0x24, 0x23, 0x23, 0x23, 0x22, 0x22, 0x22, 0x21, 0x21, 0x21, 0x20, 0x20, 0x20,
0x1f, 0x1f, 0x1f, 0x1e, 0x1e, 0x1e, 0x1d, 0x1d, 0x1d, 0x1c, 0x1c, 0x1c, 0x1b, 0x1b, 0x1b, 0x1a,
@@ -1106,7 +1118,7 @@ const uint8 CapcomPC98_FM_Channel::_volTableCarrier[] = {
0x05, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00
};
-const uint8 CapcomPC98_FM_Channel::_volTablePara[] = {
+const uint8 CapcomPC98_FMChannel::_volTablePara[] = {
0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0x7a, 0x79, 0x78, 0x77, 0x76, 0x75, 0x74, 0x73, 0x72, 0x71, 0x70,
0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x69, 0x68, 0x67, 0x66, 0x65, 0x64, 0x63, 0x62, 0x61, 0x60,
0x5f, 0x5e, 0x5d, 0x5c, 0x5b, 0x5a, 0x59, 0x58, 0x57, 0x56, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50,
@@ -1117,16 +1129,16 @@ const uint8 CapcomPC98_FM_Channel::_volTablePara[] = {
0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00
};
-CapcomPC98_FM::CapcomPC98_FM(Audio::Mixer *mixer, CBProc &proc, bool playerPrio, uint16 playFlags, uint8 chanReserveFlags, uint8 chanDisableFlags, uint16 volControlMask, bool needsTimer) : CapcomPC98Player(playerPrio, playFlags, chanReserveFlags, chanDisableFlags), PC98AudioPluginDriver(), _cbProc(proc), _volControlMask(volControlMask), _ac(nullptr), _chan(nullptr), _ready(false) {
+CapcomPC98Player_FM::CapcomPC98Player_FM(Audio::Mixer *mixer, CBProc &proc, bool playerPrio, uint16 playFlags, uint8 chanReserveFlags, uint8 chanDisableFlags, uint16 volControlMask, bool needsTimer) : CapcomPC98Player(playerPrio, playFlags, chanReserveFlags, chanDisableFlags), PC98AudioPluginDriver(), _cbProc(proc), _volControlMask(volControlMask), _ac(nullptr), _chan(nullptr), _ready(false) {
_ac = new PC98AudioCore(mixer, needsTimer ? this : nullptr, kType26);
assert(_ac);
- _chan = new CapcomPC98_FM_Channel*[3];
+ _chan = new CapcomPC98_FMChannel*[3];
assert(_chan);
for (int i = 0; i < 3; ++i)
- _chan[i] = new CapcomPC98_FM_Channel(i, _ac, _instruments, _fadeState);
+ _chan[i] = new CapcomPC98_FMChannel(i, _ac, _instruments, _fadeState);
}
-CapcomPC98_FM::~CapcomPC98_FM() {
+CapcomPC98Player_FM::~CapcomPC98Player_FM() {
delete _ac;
if (_chan) {
for (int i = 0; i < 3; ++i)
@@ -1135,7 +1147,7 @@ CapcomPC98_FM::~CapcomPC98_FM() {
}
}
-bool CapcomPC98_FM::init() {
+bool CapcomPC98Player_FM::init() {
if (!(_chan && _ac && _ac->init()))
return false;
@@ -1172,12 +1184,12 @@ bool CapcomPC98_FM::init() {
return true;
}
-void CapcomPC98_FM::deinit() {
+void CapcomPC98Player_FM::deinit() {
PC98AudioCore::MutexLock lock = _ac->stackLockMutex();
_ready = false;
}
-void CapcomPC98_FM::reset() {
+void CapcomPC98Player_FM::reset() {
for (int i = 0; i < 3; ++i)
_chan[i]->reset();
@@ -1188,7 +1200,7 @@ void CapcomPC98_FM::reset() {
_chan[i]->programChange(0);
}
-void CapcomPC98_FM::loadInstruments(const uint8 *data, uint16 number) {
+void CapcomPC98Player_FM::loadInstruments(const uint8 *data, uint16 number) {
_instruments.clear();
while (number--) {
_instruments.push_back(data);
@@ -1196,17 +1208,19 @@ void CapcomPC98_FM::loadInstruments(const uint8 *data, uint16 number) {
}
}
-PC98AudioCore::MutexLock CapcomPC98_FM::lockMutex() {
+PC98AudioCore::MutexLock CapcomPC98Player_FM::lockMutex() {
if (!_ready)
error("CapcomPC98_FM::lockMutex(): Invalid call");
return _ac->stackLockMutex();
}
-void CapcomPC98_FM::send(uint32 evt) {
+void CapcomPC98Player_FM::send(uint32 evt) {
uint8 ch = evt & 0x0F;
uint8 p1 = (evt >> 8) & 0xFF;
uint8 p2 = (evt >> 16) & 0xFF;
+ debugC(5, kDebugLevelSound, "CapcomPC98Player_FM::send(): [0x%02x] [0x%02x] [0x%02x]", evt & 0xff, p1, p2);
+
if (ch > 2)
return;
@@ -1234,24 +1248,24 @@ void CapcomPC98_FM::send(uint32 evt) {
}
}
-void CapcomPC98_FM::timerCallbackA() {
+void CapcomPC98Player_FM::timerCallbackA() {
if (_ready && _cbProc.isValid()) {
PC98AudioCore::MutexLock lock = _ac->stackLockMutex();
_cbProc();
}
}
-void CapcomPC98_FM::processSounds() {
+void CapcomPC98Player_FM::processSounds() {
for (int i = 0; i < 3; ++i)
_chan[i]->processSounds();
}
-void CapcomPC98_FM::updateMasterVolume() {
+void CapcomPC98Player_FM::updateMasterVolume() {
_ac->setMusicVolume(_musicVolume);
_ac->setSoundEffectVolume(_sfxVolume);
}
-void CapcomPC98_FM::controlChange(uint8 ch, uint8 control, uint8 val) {
+void CapcomPC98Player_FM::controlChange(uint8 ch, uint8 control, uint8 val) {
if (ch > 2)
return;
@@ -1285,7 +1299,7 @@ void CapcomPC98_FM::controlChange(uint8 ch, uint8 control, uint8 val) {
}
}
-void CapcomPC98_FM::restoreStateIntern() {
+void CapcomPC98Player_FM::restoreStateIntern() {
for (int i = 0; i < 3; ++i) {
if ((1 << i) & _chanReserveFlags)
continue;
@@ -1293,11 +1307,11 @@ void CapcomPC98_FM::restoreStateIntern() {
}
}
-void CapcomPC98_FM::setVolControlMask() {
+void CapcomPC98Player_FM::setVolControlMask() {
_ac->setSoundEffectChanMask(_volControlMask);
}
-const uint8 CapcomPC98_FM::_initData[72] = {
+const uint8 CapcomPC98Player_FM::_initData[72] = {
0x49, 0x4e, 0x49, 0x54, 0x5f, 0x56, 0x4f, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x7f, 0x1f, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x7f, 0x1f,
0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x7f, 0x1f, 0x00, 0x00, 0x0f, 0x00, 0x00,
@@ -1309,18 +1323,18 @@ int CapcomPC98AudioDriverInternal::_refCount = 0;
CapcomPC98AudioDriverInternal::CapcomPC98AudioDriverInternal(Audio::Mixer *mixer, MidiDriver::DeviceHandle dev) : _ready(false), _fmDevice(nullptr), _timerProc(nullptr), _mutexProc(nullptr), _marker(0), _musicVolume(0), _sfxVolume(0) {
MusicType type = MidiDriver::getMusicType(dev);
- _timerProc = new CapcomPC98_FM::CBProc(this, &CapcomPC98AudioDriverInternal::timerCallback);
+ _timerProc = new CapcomPC98Player_FM::CBProc(this, &CapcomPC98AudioDriverInternal::timerCallback);
assert(_timerProc);
- _mutexProc = new CapcomPC98_MIDI::MutexProc(this, &CapcomPC98AudioDriverInternal::lockMutex);
+ _mutexProc = new CapcomPC98Player_MIDI::MutexProc(this, &CapcomPC98AudioDriverInternal::lockMutex);
assert(_mutexProc);
if (type == MT_MT32 || type == MT_GM) {
- _players[0] = new CapcomPC98_MIDI(dev, type == MT_MT32, *_mutexProc);
- _players[1] = _fmDevice = new CapcomPC98_FM(mixer, *_timerProc, true, CapcomPC98Player::kPrioPlay, 4, (uint8)~4, 0xFFFF, true);
+ _players[0] = new CapcomPC98Player_MIDI(dev, type == MT_MT32, *_mutexProc);
+ _players[1] = _fmDevice = new CapcomPC98Player_FM(mixer, *_timerProc, true, CapcomPC98Player::kPrioPlay, 4, (uint8)~4, 0xFFFF, true);
_marker = 1;
} else {
- _players[0] = new CapcomPC98_FM(mixer, *_timerProc, false, CapcomPC98Player::kStdPlay, 3, 0, 0, false);
- _players[1] = _fmDevice = new CapcomPC98_FM(mixer, *_timerProc, true, CapcomPC98Player::kPrioPlay | CapcomPC98Player::kPrioClaim, 4, (uint8)~4, 4, true);
+ _players[0] = new CapcomPC98Player_FM(mixer, *_timerProc, false, CapcomPC98Player::kStdPlay, 3, 0, 0, false);
+ _players[1] = _fmDevice = new CapcomPC98Player_FM(mixer, *_timerProc, true, CapcomPC98Player::kPrioPlay | CapcomPC98Player::kPrioClaim, 4, (uint8)~4, 4, true);
}
bool ready = true;
Commit: a15ce9a202ac0ead49753624333e3592368334af
https://github.com/scummvm/scummvm/commit/a15ce9a202ac0ead49753624333e3592368334af
Author: athrxx (athrxx at scummvm.org)
Date: 2023-07-11T14:34:38+02:00
Commit Message:
KYRA: (LOL/ZH) - text displayer fixes
The original does not use the text displayer code. I can find
it in the executable, but apparently only as dead code. The
text wrapping is done with a much simpler method. I have
adapted the code to fix some glitches with the "More"
button (which the Chinese version apparently does not use
for the single-line console).
It seems fine, now, but there are also glitches in EOB II, so
I'll have a look at that separately...
Changed paths:
engines/kyra/resource/staticres_lol.cpp
engines/kyra/text/text_rpg.cpp
diff --git a/engines/kyra/resource/staticres_lol.cpp b/engines/kyra/resource/staticres_lol.cpp
index 7323c00c50b..cb9244512d1 100644
--- a/engines/kyra/resource/staticres_lol.cpp
+++ b/engines/kyra/resource/staticres_lol.cpp
@@ -605,7 +605,7 @@ const ScreenDim Screen_LoL::_screenDimTable256C[] = {
};
const ScreenDim Screen_LoL::_screenDimTableZH[] = {
- { 0x00, 0x00, 0x28, 0xC8, 0xC7, 0xCF, 0x00, 0x00 }, // Taken from Intro // Fuul screen // Looks good
+ { 0x00, 0x00, 0x28, 0xC8, 0xC7, 0xCF, 0x00, 0x00 }, // Taken from Intro // Full screen // Looks good
{ 0x08, 0x48, 0x18, 0x38, 0xFE, 0x01, 0x00, 0x00 }, // Not checked
{ 0x0E, 0x00, 0x16, 0x78, 0xFE, 0x01, 0x00, 0x00 }, // Not checked
{ 0x0B, 0x7B, 0x1C, 0x12, 0xFE, 0xFC, 0x00, 0x00 }, // Not checked
@@ -816,7 +816,7 @@ const KyraRpgGUISettings LoLEngine::_guiSettings = {
};
const KyraRpgGUISettings LoLEngine::_guiSettingsZH = {
- { _dlgButtonPosX_Def, _dlgButtonPosY_Def, 144, 254, 60, 18, 2, 66, { 0, 0 }, { 0, 0 }, { 0, 0 } },
+ { _dlgButtonPosX_Def, _dlgButtonPosY_Def, 144, 254, 68, 18, 2, 66, { 0, 0 }, { 0, 0 }, { 0, 0 } },
{ 136, 251, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ { 0, 0, 0 }, { 0, 0, 0 }, 0, 0,
{ 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
diff --git a/engines/kyra/text/text_rpg.cpp b/engines/kyra/text/text_rpg.cpp
index 6a98d6926fd..e02dcf21f53 100644
--- a/engines/kyra/text/text_rpg.cpp
+++ b/engines/kyra/text/text_rpg.cpp
@@ -343,8 +343,8 @@ void TextDisplayer_rpg::printLine(char *str) {
int sjisOffs = (sjisTextMode || _vm->game() != GI_LOL) ? 8 : 9;
int fh;
- if (_screen->_currentFont == Screen::FID_CHINESE_FNT && _vm->_flags.lang == Common::Language::ZH_TWN && _vm->_flags.gameID == GI_EOB2)
- fh = 14;
+ if (_screen->_currentFont == Screen::FID_CHINESE_FNT && _vm->_flags.lang == Common::Language::ZH_TWN)
+ fh = _vm->_flags.gameID == GI_EOB2 ? 14 : 15;
else if (_screen->_currentFont == Screen::FID_SJIS_TEXTMODE_FNT)
fh = 9;
else
@@ -381,7 +381,6 @@ void TextDisplayer_rpg::printLine(char *str) {
char c = 0;
uint8 twoByteCharOffs = 0;
-
if (sjisTextMode) {
bool ct = true;
@@ -412,6 +411,13 @@ void TextDisplayer_rpg::printLine(char *str) {
}
s = n2;
}
+ } else if (_isChinese) {
+ s = strlen(str);
+ twoByteCharOffs = 16;
+ if ((lw + _textDimData[sdx].column) >= w) {
+ s -= ((lw + _textDimData[sdx].column) - w) >> 3;
+ w -= _textDimData[sdx].column;
+ }
} else {
if (_vm->gameFlags().lang == Common::JA_JPN) {
for (int i = 0; i < s; ++i) {
@@ -421,12 +427,12 @@ void TextDisplayer_rpg::printLine(char *str) {
}
}
- if (_isChinese) {
+ /*if (_isChinese) {
for (int i = 0; i < s; ++i) {
if (str[i] & 0x80)
twoByteCharOffs = 16;
}
- }
+ }*/
if ((lw + _textDimData[sdx].column) >= w) {
if ((lines - 1) <= _lineCount && _allowPageBreak)
@@ -445,10 +451,10 @@ void TextDisplayer_rpg::printLine(char *str) {
for (strPos = 0; strPos < s; ++strPos) {
uint8 cu = (uint8) str[strPos];
- if (_isChinese && (cu & 0x80)) {
+ /*if (_isChinese && (cu & 0x80)) {
lw += twoByteCharOffs;
strPos++;
- } else if (cu >= 0xE0 || (cu > 0x80 && cu < 0xA0)) {
+ } else */if (cu >= 0xE0 || (cu > 0x80 && cu < 0xA0)) {
lw += sjisOffs;
strPos++;
} else {
@@ -504,7 +510,6 @@ void TextDisplayer_rpg::printLine(char *str) {
s = lineLastCharPos;
}
}
-
}
}
@@ -567,7 +572,8 @@ void TextDisplayer_rpg::printLine(char *str) {
_textDimData[sdx].line++;
_lineCount++;
- printLine(str);
+ if (_numCharsLeft || !_isChinese)
+ printLine(str);
}
void TextDisplayer_rpg::printDialogueText(int stringId, const char *pageBreakString, const char*) {
Commit: 5e8333f638b58c249c8da04a995a122a680a893d
https://github.com/scummvm/scummvm/commit/5e8333f638b58c249c8da04a995a122a680a893d
Author: athrxx (athrxx at scummvm.org)
Date: 2023-07-11T14:34:52+02:00
Commit Message:
KYRA: (EOB II/ZH) - fix/improve text display
The text display glitches in many different ways, since the
original devs did some pretty ugly hacks that we have to
emulate somehow. This commit fixes a couple of things
(spacing, pixel/line overdrawing, shadow, original
linebreak style). There are still several things that have to
be addressed separately, like various text colors, the
whole character portrait/stats pages, etc.
Changed paths:
engines/kyra/engine/eobcommon.cpp
engines/kyra/engine/lol.cpp
engines/kyra/engine/magic_eob.cpp
engines/kyra/engine/timer_eob.cpp
engines/kyra/graphics/screen_eob.cpp
engines/kyra/gui/debugger.cpp
engines/kyra/gui/gui_eob.cpp
engines/kyra/resource/staticres_eob.cpp
engines/kyra/script/script_eob.cpp
engines/kyra/text/text_rpg.cpp
engines/kyra/text/text_rpg.h
diff --git a/engines/kyra/engine/eobcommon.cpp b/engines/kyra/engine/eobcommon.cpp
index 96eb9e67bda..103caef5c89 100644
--- a/engines/kyra/engine/eobcommon.cpp
+++ b/engines/kyra/engine/eobcommon.cpp
@@ -730,6 +730,10 @@ void EoBCoreEngine::runLoop() {
_drawSceneTimer = _system->getMillis();
_screen->setFont(_conFont);
_screen->setScreenDim(7);
+ if (_flags.lang == Common::ZH_TWN) {
+ _txt->setShadowColor(guiSettings()->colors.fill);
+ _txt->setLineSpacing(-1);
+ }
_runFlag = true;
@@ -1612,6 +1616,11 @@ void EoBCoreEngine::initDialogueSequence() {
delete s;
_txt->setupField(9, 0);
+
+ if (_flags.lang == Common::ZH_TWN) {
+ _txt->setShadowColor(guiSettings()->colors.guiColorBlack);
+ _txt->setLineSpacing(0);
+ }
}
void EoBCoreEngine::restoreAfterDialogueSequence() {
@@ -1624,6 +1633,11 @@ void EoBCoreEngine::restoreAfterDialogueSequence() {
//_allowSkip = false;
_screen->setScreenDim(7);
+ if (_flags.lang == Common::ZH_TWN) {
+ _txt->setShadowColor(guiSettings()->colors.fill);
+ _txt->setLineSpacing(-1);
+ }
+
if (_flags.gameID == GI_EOB2)
snd_playSoundEffect(2);
@@ -1712,6 +1726,9 @@ int EoBCoreEngine::runDialogue(int dialogueTextId, int numStr, int loopButtonId,
void EoBCoreEngine::restParty_displayWarning(const char *str) {
int od = _screen->curDimIndex();
_screen->setScreenDim(7);
+ int osh = (_flags.lang == Common::ZH_TWN) ? _txt->setShadowColor(guiSettings()->colors.fill) : 0xFFFF;
+ int ols = (_flags.lang == Common::ZH_TWN) ? _txt->setLineSpacing(-1) : 0xFFFF;
+
Screen::FontId of = _screen->setFont(_conFont);
_screen->setCurPage(0);
@@ -1719,6 +1736,11 @@ void EoBCoreEngine::restParty_displayWarning(const char *str) {
_screen->setFont(of);
_screen->setScreenDim(od);
+
+ if (osh != 0xFFFF)
+ _txt->setShadowColor(osh);
+ if (ols != 0xFFFF)
+ _txt->setLineSpacing(ols);
}
bool EoBCoreEngine::restParty_updateMonsters() {
@@ -1737,10 +1759,18 @@ bool EoBCoreEngine::restParty_updateMonsters() {
Screen::FontId of = _screen->setFont(_conFont);
int od = _screen->curDimIndex();
_screen->setScreenDim(7);
+ int osh = (_flags.lang == Common::ZH_TWN) ? _txt->setShadowColor(guiSettings()->colors.fill) : 0xFFFF;
+ int ols = (_flags.lang == Common::ZH_TWN) ? _txt->setLineSpacing(-1) : 0xFFFF;
+
updateMonsters(0);
updateMonsters(1);
timerProcessFlyingObjects(0);
+
_screen->setScreenDim(od);
+ if (osh != 0xFFFF)
+ _txt->setShadowColor(osh);
+ if (ols != 0xFFFF)
+ _txt->setLineSpacing(ols);
_screen->setFont(of);
_partyResting = false;
diff --git a/engines/kyra/engine/lol.cpp b/engines/kyra/engine/lol.cpp
index 8623dfb1e1a..1b4b720ca69 100644
--- a/engines/kyra/engine/lol.cpp
+++ b/engines/kyra/engine/lol.cpp
@@ -393,6 +393,7 @@ Common::Error LoLEngine::init() {
}
_txt = new TextDisplayer_LoL(this, _screen);
+ _txt->setLineSpacing(_flags.lang == Common::JA_JPN && _flags.use16ColorMode ? 1 : (_flags.lang == Common::ZH_TWN ? -1 : 0));
_screen->setAnimBlockPtr(10000);
_screen->setScreenDim(0);
diff --git a/engines/kyra/engine/magic_eob.cpp b/engines/kyra/engine/magic_eob.cpp
index 2502f063011..6fc51eef9bc 100644
--- a/engines/kyra/engine/magic_eob.cpp
+++ b/engines/kyra/engine/magic_eob.cpp
@@ -219,11 +219,13 @@ void EoBCoreEngine::castSpell(int spell, int weaponSlot) {
}
}
-
int cs = (_flags.platform == Common::kPlatformSegaCD && _flags.lang == Common::JA_JPN) ? _screen->setFontStyles(_screen->_currentFont, Font::kStyleNarrow1) : -1;
_txt->printMessage(_magicStrings1[4], -1, c->name, s->name);
+ if (_flags.lang == Common::ZH_TWN)
+ _txt->printMessage("\r", -1);
+
if (cs != -1)
_screen->setFontStyles(_screen->_currentFont, cs);
@@ -245,8 +247,16 @@ void EoBCoreEngine::removeCharacterEffect(int spell, int charIndex, int showWarn
int od = _screen->curDimIndex();
Screen::FontId of = _screen->setFont(_conFont);
_screen->setScreenDim(7);
+ int osh = (_flags.lang == Common::ZH_TWN) ? _txt->setShadowColor(guiSettings()->colors.fill) : 0xFFFF;
+ int ols = (_flags.lang == Common::ZH_TWN) ? _txt->setLineSpacing(-1) : 0xFFFF;
+
printWarning(Common::String::format(_magicStrings3[_flags.gameID == GI_EOB1 ? 3 : 2], c->name, s->name).c_str());
+
_screen->setScreenDim(od);
+ if (osh != 0xFFFF)
+ _txt->setShadowColor(osh);
+ if (ols != 0xFFFF)
+ _txt->setLineSpacing(ols);
_screen->setFont(of);
}
diff --git a/engines/kyra/engine/timer_eob.cpp b/engines/kyra/engine/timer_eob.cpp
index ffe8278a48c..9d88733ac42 100644
--- a/engines/kyra/engine/timer_eob.cpp
+++ b/engines/kyra/engine/timer_eob.cpp
@@ -306,6 +306,8 @@ void EoBCoreEngine::timerSpecialCharacterUpdate(int timerNum) {
int od = _screen->curDimIndex();
Screen::FontId of = _screen->setFont(_conFont);
_screen->setScreenDim(7);
+ int osh = (_flags.lang == Common::ZH_TWN) ? _txt->setShadowColor(guiSettings()->colors.fill) : 0xFFFF;
+ int ols = (_flags.lang == Common::ZH_TWN) ? _txt->setLineSpacing(-1) : 0xFFFF;
switch (evt) {
case 2:
@@ -369,6 +371,10 @@ void EoBCoreEngine::timerSpecialCharacterUpdate(int timerNum) {
}
_screen->setScreenDim(od);
+ if (osh != 0xFFFF)
+ _txt->setShadowColor(osh);
+ if (ols != 0xFFFF)
+ _txt->setLineSpacing(ols);
_screen->setFont(of);
}
diff --git a/engines/kyra/graphics/screen_eob.cpp b/engines/kyra/graphics/screen_eob.cpp
index 25b8fdaf4bd..fdbee787ed6 100644
--- a/engines/kyra/graphics/screen_eob.cpp
+++ b/engines/kyra/graphics/screen_eob.cpp
@@ -2272,7 +2272,10 @@ void OldDOSFont::unload() {
}
uint16 ChineseTwoByteFontEoB::translateBig5(uint16 in) const {
- if (in < 0x80)
+ // The original explicitly turns the braces '<' and '>' into '"'.
+ if (in == '<' || in == '>')
+ return '\"';
+ else if (in < 0x80)
return in;
in = ((in & 0xff00) >> 8) | ((in & 0xff) << 8);
if (_big5->hasGlyphForBig5Char(in))
@@ -2287,7 +2290,7 @@ int ChineseTwoByteFontEoB::getCharWidth(uint16 c) const {
int ChineseTwoByteFontEoB::getCharHeight(uint16 c) const {
uint16 t = translateBig5(c);
- return (t < 0x80) ? _singleByte->getCharHeight(t) : _big5->getFontHeight() + 1;
+ return (t < 0x80) ? _singleByte->getCharHeight(t) : _big5->getFontHeight();
}
void ChineseTwoByteFontEoB::drawChar(uint16 c, byte *dst, int pitch, int bpp) const {
diff --git a/engines/kyra/gui/debugger.cpp b/engines/kyra/gui/debugger.cpp
index 1e86329f951..6bb28cab858 100644
--- a/engines/kyra/gui/debugger.cpp
+++ b/engines/kyra/gui/debugger.cpp
@@ -605,6 +605,10 @@ bool Debugger_EoB::cmdSetPosition(int argc, const char **argv) {
_vm->generateTempData();
_vm->txt()->removePageBreakFlag();
_vm->screen()->setScreenDim(7);
+ if (_vm->gameFlags().lang == Common::ZH_TWN) {
+ _vm->txt()->setShadowColor(_vm->guiSettings()->colors.fill);
+ _vm->txt()->setLineSpacing(0);
+ }
_vm->loadLevel(level, sub);
diff --git a/engines/kyra/gui/gui_eob.cpp b/engines/kyra/gui/gui_eob.cpp
index 962c4597805..1598221eb32 100644
--- a/engines/kyra/gui/gui_eob.cpp
+++ b/engines/kyra/gui/gui_eob.cpp
@@ -51,12 +51,11 @@ void EoBCoreEngine::gui_drawPlayField(bool refresh) {
int cp = _screen->setCurPage(2);
if (_flags.lang == Common::Language::ZH_TWN) {
Screen::FontId of = _screen->setFont(Screen::FID_CHINESE_FNT);
- _screen->fillRect(290, 180, 318, 194, guiSettings()->colors.fill);
+ _screen->fillRect(291, 180, 317, 195, guiSettings()->colors.fill);
_screen->printShadedText("\xbf\xef?" /* � */, 292, 181, guiSettings()->colors.guiColorYellow, guiSettings()->colors.fill, guiSettings()->colors.guiColorBlack, -1);
_screen->setFont(of);
-
- _screen->fillRect(3, 170, 290, 198, guiSettings()->colors.fill);
- _screen->fillRect(4, 171, 289, 197, guiSettings()->colors.guiColorBlack);
+ _screen->fillRect(4, 171, 289, 198, guiSettings()->colors.guiColorBlack);
+ _screen->drawBox(3, 170, 290, 199, guiSettings()->colors.fill);
}
gui_drawCompass(true);
@@ -3967,6 +3966,11 @@ bool GUI_EoB::restParty() {
else
_screen->sega_clearTextBuffer(0);
+ if (_vm->gameFlags().lang == Common::ZH_TWN)
+ _screen->drawBox(3, 170, 290, 199, 0xb7);
+
+ int osh = (_vm->gameFlags().lang == Common::ZH_TWN) ? _vm->txt()->setShadowColor(_vm->guiSettings()->colors.fill) : 0xFFFF;
+ int ols = (_vm->gameFlags().lang == Common::ZH_TWN) ? _vm->txt()->setLineSpacing(-1) : 0xFFFF;
Screen::FontId of = _screen->setFont(_vm->_conFont);
restParty_updateRestTime(hours, true);
@@ -4187,6 +4191,10 @@ bool GUI_EoB::restParty() {
_vm->removeInputTop();
_screen->setScreenDim(4);
_screen->setFont(of);
+ if (osh != 0xFFFF)
+ _vm->txt()->setShadowColor(osh);
+ if (ols != 0xFFFF)
+ _vm->txt()->setLineSpacing(ols);
if (!res) {
if (!injured)
@@ -4208,6 +4216,8 @@ void GUI_EoB::printScribeScrollSpellString(const int16 *menuItems, int id, bool
bool GUI_EoB::confirmDialogue(int id) {
int od = _screen->curDimIndex();
+ int osh = (_vm->gameFlags().lang == Common::ZH_TWN) ? _vm->txt()->setShadowColor(_vm->guiSettings()->colors.guiColorBlack) : 0xFFFF;
+ int ols = (_vm->gameFlags().lang == Common::ZH_TWN) ? _vm->txt()->setLineSpacing(0) : 0xFFFF;
Screen::FontId of = _screen->setFont(_menuFont);
Button *buttonList = initMenu(5);
@@ -4264,6 +4274,10 @@ bool GUI_EoB::confirmDialogue(int id) {
_screen->setFont(of);
_screen->setScreenDim(od);
+ if (osh != 0xFFFF)
+ _vm->txt()->setShadowColor(osh);
+ if (ols != 0xFFFF)
+ _vm->txt()->setLineSpacing(ols);
return result;
}
@@ -4579,6 +4593,8 @@ void GUI_EoB::drawMenuButtonBox(int x, int y, int w, int h, bool clicked, bool n
void GUI_EoB::drawTextBox(int dim, int id) {
int od = _screen->curDimIndex();
_screen->setScreenDim(dim);
+ int osh = (_vm->gameFlags().lang == Common::ZH_TWN) ? _vm->txt()->setShadowColor(_vm->guiSettings()->colors.guiColorBlack) : 0xFFFF;
+ int ols = (_vm->gameFlags().lang == Common::ZH_TWN) ? _vm->txt()->setLineSpacing(0) : 0xFFFF;
Screen::FontId of = _screen->setFont(_menuFont);
int cs = (_vm->gameFlags().platform == Common::kPlatformPC98 && !_vm->gameFlags().use16ColorMode) ? _screen->setFontStyles(_menuFont, Font::kStyleFat) : -1;
@@ -4595,6 +4611,11 @@ void GUI_EoB::drawTextBox(int dim, int id) {
_screen->setCurPage(0);
_screen->copyRegion(0, 0, dm->sx << 3, dm->sy, dm->w << 3, dm->h, 2, 0, Screen::CR_NO_P_CHECK);
_screen->updateScreen();
+
+ if (osh != 0xFFFF)
+ _vm->txt()->setShadowColor(osh);
+ if (ols != 0xFFFF)
+ _vm->txt()->setLineSpacing(ols);
_screen->setScreenDim(od);
if (cs != -1)
@@ -4827,6 +4848,8 @@ void GUI_EoB::restParty_updateRestTime(int hours, bool init) {
Screen::FontId of = _screen->setFont(_menuFont);
int od = _screen->curDimIndex();
_screen->setScreenDim(10);
+ int osh = (_vm->gameFlags().lang == Common::ZH_TWN) ? _vm->txt()->setShadowColor(_vm->guiSettings()->colors.guiColorBlack) : 0xFFFF;
+ int ols = (_vm->gameFlags().lang == Common::ZH_TWN) ? _vm->txt()->setLineSpacing(0) : 0xFFFF;
if (init) {
_screen->setCurPage(0);
@@ -4843,6 +4866,10 @@ void GUI_EoB::restParty_updateRestTime(int hours, bool init) {
_screen->set16bitShadingLevel(0);
_screen->updateScreen();
_vm->delay(160);
+ if (osh != 0xFFFF)
+ _vm->txt()->setShadowColor(osh);
+ if (ols != 0xFFFF)
+ _vm->txt()->setLineSpacing(ols);
_screen->setScreenDim(od);
_screen->setFont(of);
}
diff --git a/engines/kyra/resource/staticres_eob.cpp b/engines/kyra/resource/staticres_eob.cpp
index 585e082dd6e..dcb60c5a222 100644
--- a/engines/kyra/resource/staticres_eob.cpp
+++ b/engines/kyra/resource/staticres_eob.cpp
@@ -186,7 +186,7 @@ const ScreenDim Screen_EoB::_screenDimTableZH[] = {
{ 0x02, 0x18, 0x14, 0x78, 0x0F, 0x02, 0x03, 0x00 },
{ 0x00, 0x00, 0x16, 0x78, 0x0F, 0x0D, 0x00, 0x00 },
{ 0x0A, 0x6C, 0x15, 0x28, 0x0F, 0x00, 0x00, 0x00 },
- { 0x01, 0xAB, 0x23, 0x1C, 0x0F, 0x0C, 0x00, 0x00 },
+ { 0x01, 0xAB, 0x23, 0x1C, 0x0F, 0x00, 0x00, 0x00 },
{ 0x02, 0x18, 0x14, 0x00, 0x0F, 0x02, 0x03, 0x00 },
{ 0x01, 0x7D, 0x26, 0x40, 0x0F, 0x00, 0x03, 0x00 },
{ 0x00, 0x00, 0x16, 0x90, 0x0F, 0x02, 0x00, 0x00 },
diff --git a/engines/kyra/script/script_eob.cpp b/engines/kyra/script/script_eob.cpp
index 62e03818d61..7749354b346 100644
--- a/engines/kyra/script/script_eob.cpp
+++ b/engines/kyra/script/script_eob.cpp
@@ -1326,6 +1326,10 @@ int EoBInfProcessor::oeob_loadNewLevelOrMonsters(int8 *data) {
_vm->generateTempData();
_vm->txt()->removePageBreakFlag();
_screen->setScreenDim(7);
+ if (_vm->gameFlags().lang == Common::ZH_TWN) {
+ _vm->txt()->setShadowColor(_vm->guiSettings()->colors.fill);
+ _vm->txt()->setLineSpacing(-1);
+ }
_vm->loadLevel(index, cmd);
debugC(5, kDebugLevelScript, " - entering level '%d', sub level '%d', start block '0x%.04X', start direction '%d'", index, cmd, _vm->_currentBlock, _vm->_currentDirection);
@@ -1542,7 +1546,13 @@ int EoBInfProcessor::oeob_sequence(int8 *data) {
_vm->npcSequence(cmd);
break;
}
+
_vm->screen()->setScreenDim(7);
+ if (_vm->gameFlags().lang == Common::ZH_TWN) {
+ _vm->txt()->setShadowColor(_vm->guiSettings()->colors.fill);
+ _vm->txt()->setLineSpacing(-1);
+ }
+
return pos - data;
}
diff --git a/engines/kyra/text/text_rpg.cpp b/engines/kyra/text/text_rpg.cpp
index e02dcf21f53..65211178de6 100644
--- a/engines/kyra/text/text_rpg.cpp
+++ b/engines/kyra/text/text_rpg.cpp
@@ -33,9 +33,9 @@ enum {
};
TextDisplayer_rpg::TextDisplayer_rpg(KyraRpgEngine *engine, Screen *scr) : _vm(engine), _screen(scr),
- _lineCount(0), _printFlag(false), _lineWidth(0), _numCharsTotal(0), _allowPageBreak(true),
+_lineCount(0), _printFlag(false), _lineWidth(0), _numCharsTotal(0), _allowPageBreak(true),
_numCharsLeft(0), _numCharsPrinted(0), _sjisTextModeLineBreak(false), _waitButtonMode(1),
- _pc98TextMode(engine->gameFlags().use16ColorMode && engine->game() == GI_LOL),
+ _pc98TextMode(engine->gameFlags().use16ColorMode && engine->game() == GI_LOL), _shadowColor(0), _lineSpacing(0), _preventHalfWidthLineEnd(false),
_waitButtonFont(Screen::FID_6_FNT), _isChinese(_vm->gameFlags().lang == Common::Language::ZH_TWN || _vm->gameFlags().lang == Common::Language::ZH_CHN) {
static const uint8 amigaColorMap[16] = {
@@ -55,6 +55,8 @@ TextDisplayer_rpg::TextDisplayer_rpg(KyraRpgEngine *engine, Screen *scr) : _vm(e
else if ((_vm->game() == GI_LOL && _vm->gameFlags().lang == Common::Language::ZH_TWN))
_waitButtonFont = Screen::FID_CHINESE_FNT;
+ _preventHalfWidthLineEnd = ((_vm->gameFlags().lang == Common::JA_JPN && _vm->game() == GI_EOB1) || (_vm->gameFlags().lang == Common::Language::ZH_TWN && _vm->game() == GI_EOB2));
+
_textDimData = new TextDimData[_screen->screenDimTableCount()];
for (int i = 0; i < 256; ++i)
@@ -77,7 +79,7 @@ TextDisplayer_rpg::TextDisplayer_rpg(KyraRpgEngine *engine, Screen *scr) : _vm(e
_table2 = new char[16]();
_tempString1 = _tempString2 = 0;
-
+ _ctrl[0] = _ctrl[1] = _ctrl[2] = '\0';
_waitButtonSpace = 0;
}
@@ -183,7 +185,7 @@ void TextDisplayer_rpg::displayText(char *str, ...) {
_currentLine[_numCharsLeft] = '\0';
_lineWidth += sjisOffs;
- if (_vm->game() == GI_EOB1 && ((sd->w << 3) - sjisOffs) <= (_textDimData[sdx].column + _lineWidth))
+ if (_preventHalfWidthLineEnd && ((sd->w << 3) - sjisOffs) <= (_textDimData[sdx].column + _lineWidth))
printLine(_currentLine);
c = parseCommand();
continue;
@@ -201,6 +203,8 @@ void TextDisplayer_rpg::displayText(char *str, ...) {
_currentLine[_numCharsLeft] = '\0';
_lineWidth += Graphics::Big5Font::kChineseTraditionalWidth;
+ if (_preventHalfWidthLineEnd && (_textDimData[sdx].column + _lineWidth + Graphics::Big5Font::kChineseTraditionalWidth) > (sd->w << 3))
+ printLine(_currentLine);
c = parseCommand();
continue;
}
@@ -263,6 +267,7 @@ void TextDisplayer_rpg::displayText(char *str, ...) {
default:
if (_vm->game() == GI_EOB1 || _vm->game() == GI_LOL || (unsigned char)c > 30) {
_lineWidth += (sjisTextMode ? 4 : (_screen->_currentFont == Screen::FID_SJIS_TEXTMODE_FNT ? 9 : _screen->getCharWidth((uint8)c)));
+
_currentLine[_numCharsLeft++] = c;
_currentLine[_numCharsLeft] = 0;
@@ -342,13 +347,7 @@ void TextDisplayer_rpg::printLine(char *str) {
bool sjisTextMode = _pc98TextMode && (sdx == 3 || sdx == 4 || sdx == 5 || sdx == 15) ? true : false;
int sjisOffs = (sjisTextMode || _vm->game() != GI_LOL) ? 8 : 9;
- int fh;
- if (_screen->_currentFont == Screen::FID_CHINESE_FNT && _vm->_flags.lang == Common::Language::ZH_TWN)
- fh = _vm->_flags.gameID == GI_EOB2 ? 14 : 15;
- else if (_screen->_currentFont == Screen::FID_SJIS_TEXTMODE_FNT)
- fh = 9;
- else
- fh = _screen->getFontHeight() + _screen->_lineSpacing;
+ int fh = _screen->getFontHeight() + _screen->_lineSpacing + _lineSpacing;
int lines = (sd->h - _screen->_lineSpacing) / fh;
while (_textDimData[sdx].line >= lines) {
@@ -365,6 +364,11 @@ void TextDisplayer_rpg::printLine(char *str) {
if (h2)
_screen->copyRegion(sd->sx << 3, sd->sy + fh, sd->sx << 3, sd->sy, sd->w << 3, h2, _screen->_curPage, _screen->_curPage, Screen::CR_NO_P_CHECK);
+ // In Chinese EOBII some characters overdraw the valid boundaries by one pixel
+ // (at least the ',' does). So, the original redraws the border here. We do the same...
+ if (_isChinese && _vm->_flags.gameID == GI_EOB2 && sdx == 7)
+ _screen->drawBox(3, 170, 290, 199, 0xb7);
+
_screen->set16bitShadingLevel(4);
_screen->fillRect(sd->sx << 3, sd->sy + h1, ((sd->sx + sd->w) << 3) - 1, sd->sy + sd->h - 1, _textDimData[sdx].color2);
_screen->set16bitShadingLevel(0);
@@ -427,13 +431,6 @@ void TextDisplayer_rpg::printLine(char *str) {
}
}
- /*if (_isChinese) {
- for (int i = 0; i < s; ++i) {
- if (str[i] & 0x80)
- twoByteCharOffs = 16;
- }
- }*/
-
if ((lw + _textDimData[sdx].column) >= w) {
if ((lines - 1) <= _lineCount && _allowPageBreak)
// cut off line to leave space for "MORE" button
@@ -451,10 +448,7 @@ void TextDisplayer_rpg::printLine(char *str) {
for (strPos = 0; strPos < s; ++strPos) {
uint8 cu = (uint8) str[strPos];
- /*if (_isChinese && (cu & 0x80)) {
- lw += twoByteCharOffs;
- strPos++;
- } else */if (cu >= 0xE0 || (cu > 0x80 && cu < 0xA0)) {
+ if (cu >= 0xE0 || (cu > 0x80 && cu < 0xA0)) {
lw += sjisOffs;
strPos++;
} else {
@@ -543,7 +537,18 @@ void TextDisplayer_rpg::printLine(char *str) {
}
_screen->printText(str, x1 & ~3, (y + 8) & ~7, col, 0);
} else {
- _screen->printText(str, x1, y, col, _textDimData[sdx].color2);
+ uint8 col2 = _textDimData[sdx].color2;
+ if (_shadowColor) {
+ _screen->printText(str, x1 - 1, y, _shadowColor, col2);
+ _screen->printText(str, x1, y + 1, _shadowColor, 0);
+ _screen->printText(str, x1 - 1, y + 1, _shadowColor, 0);
+ // Another hack for Chinese EOBII. Due to the reduced line spacing - while still drawing a shadow for the font - the
+ // lines will overdraw by one pixel if we don't clear the bottom line. This will otherwise cause glitches when doing line feeds.
+ for (int i = 0; i < -_lineSpacing && y + fh + i < sd->sy + sd->h; ++i)
+ _screen->drawClippedLine(x1 - 1, y + fh + i, x1 + lw, y + fh + i, _textDimData[sdx].color2);
+ col2 = 0;
+ }
+ _screen->printText(str, x1, y, col, col2);
}
_textDimData[sdx].column += lw;
@@ -643,10 +648,24 @@ int TextDisplayer_rpg::clearDim(int dim) {
void TextDisplayer_rpg::clearCurDim() {
int d = _screen->curDimIndex();
const ScreenDim *tmp = _screen->getScreenDim(d);
+
+ int xOffs = 0;
+ int wOffs = 0;
+ int hOffs = 0;
+
+ if (_shadowColor) {
+ if (tmp->sx > 0)
+ xOffs = wOffs = 1;
+ if (tmp->sy + tmp->h < Screen::SCREEN_H)
+ hOffs = 1;
+ }
+
if (_pc98TextMode) {
- _screen->fillRect(tmp->sx << 3, tmp->sy, ((tmp->sx + tmp->w) << 3) - 2, (tmp->sy + tmp->h) - 2, _textDimData[d].color2);
- } else
- _screen->fillRect(tmp->sx << 3, tmp->sy, ((tmp->sx + tmp->w) << 3) - 1, (tmp->sy + tmp->h) - 1, _textDimData[d].color2);
+ --wOffs;
+ --hOffs;
+ }
+
+ _screen->fillRect((tmp->sx << 3) - xOffs, tmp->sy, ((tmp->sx + tmp->w) << 3) - 1 + wOffs, (tmp->sy + tmp->h) - 1 + hOffs, _textDimData[d].color2);
_lineCount = 0;
_textDimData[d].column = _textDimData[d].line = 0;
diff --git a/engines/kyra/text/text_rpg.h b/engines/kyra/text/text_rpg.h
index 42ca83c4a13..9a2f0c264d8 100644
--- a/engines/kyra/text/text_rpg.h
+++ b/engines/kyra/text/text_rpg.h
@@ -53,6 +53,8 @@ public:
void allowPageBreak(bool mode) { _allowPageBreak = mode; }
void setWaitButtonMode(int mode) { _waitButtonMode = mode; }
+ int setShadowColor(int col) { SWAP(col, _shadowColor); return col; }
+ int setLineSpacing(int spacing) { SWAP(spacing, _lineSpacing); return spacing; }
int lineCount() const { return _lineCount; }
const uint8 *colorMap() const { return _colorMap; }
@@ -107,6 +109,9 @@ protected:
private:
Screen *_screen;
+ int _lineSpacing;
+ int _shadowColor;
+ bool _preventHalfWidthLineEnd;
char *_table1;
char *_table2;
Commit: 1831f02c364d231ae0ef3704e5fff4d85fff9748
https://github.com/scummvm/scummvm/commit/1831f02c364d231ae0ef3704e5fff4d85fff9748
Author: athrxx (athrxx at scummvm.org)
Date: 2023-07-11T14:34:56+02:00
Commit Message:
KYRA: (EOB/LOL) - reduce text displayer hacks
Trying to make this code a bit less ugly. It has been
hacked up by basically every Japanese and Chinese
version in different ways. This is a start to revert some
of the hacks.
Changed paths:
engines/kyra/engine/darkmoon.cpp
engines/kyra/engine/eob.cpp
engines/kyra/engine/eobcommon.cpp
engines/kyra/engine/lol.cpp
engines/kyra/engine/magic_eob.cpp
engines/kyra/engine/timer_eob.cpp
engines/kyra/gui/debugger.cpp
engines/kyra/gui/gui_eob.cpp
engines/kyra/resource/staticres_eob.cpp
engines/kyra/script/script_eob.cpp
engines/kyra/script/script_eob.h
engines/kyra/text/text_lol.cpp
engines/kyra/text/text_rpg.cpp
engines/kyra/text/text_rpg.h
diff --git a/engines/kyra/engine/darkmoon.cpp b/engines/kyra/engine/darkmoon.cpp
index 4aea8b53b01..b772ccc2387 100644
--- a/engines/kyra/engine/darkmoon.cpp
+++ b/engines/kyra/engine/darkmoon.cpp
@@ -76,6 +76,10 @@ Common::Error DarkMoonEngine::init() {
_screen->modifyScreenDim(27, 0, 0, 21, 5);
} else if (_flags.lang == Common::Language::ZH_TWN) {
_screen->modifyScreenDim(6, 10, 72, 21, 40);
+ _txt->setShadowColor(-1, guiSettings()->colors.guiColorBlack);
+ _txt->setLineSpacing(7, -1);
+ _txt->setColorMapping(7, 12, 0);
+ _txt->setShadowColor(7, guiSettings()->colors.fill);
}
return Common::kNoError;
diff --git a/engines/kyra/engine/eob.cpp b/engines/kyra/engine/eob.cpp
index 7dc3b51a06b..e6d3d3dfe97 100644
--- a/engines/kyra/engine/eob.cpp
+++ b/engines/kyra/engine/eob.cpp
@@ -127,6 +127,7 @@ Common::Error EoBEngine::init() {
if (_flags.platform == Common::kPlatformPC98) {
_screen->modifyScreenDim(28, 0x0A, 0xA4, 0x15, 0x18);
_screen->modifyScreenDim(12, 0x01, 0x04, 0x14, 0x9A);
+ _txt->setColorMapping(-1, 12, 0);
} else if (_flags.platform == Common::kPlatformSegaCD) {
_screen->modifyScreenDim(27, 0x00, 0x02, 0x11, 0x03);
_screen->modifyScreenDim(28, 0x07, 0xA0, 0x17, 0x24);
diff --git a/engines/kyra/engine/eobcommon.cpp b/engines/kyra/engine/eobcommon.cpp
index 103caef5c89..7f741d196a9 100644
--- a/engines/kyra/engine/eobcommon.cpp
+++ b/engines/kyra/engine/eobcommon.cpp
@@ -472,6 +472,12 @@ Common::Error EoBCoreEngine::init() {
assert(_gui);
_txt = new TextDisplayer_rpg(this, _screen);
assert(_txt);
+
+ if (_flags.platform == Common::kPlatformAmiga) {
+ static const uint8 cmap[16] = { 0x00, 0x06, 0x1d, 0x1b, 0x1a, 0x17, 0x18, 0x0e, 0x19, 0x1c, 0x1c, 0x1e, 0x13, 0x0a, 0x11, 0x1f };
+ for (int i = 0; i < ARRAYSIZE(cmap); ++i)
+ _txt->setColorMapping(-1, i, cmap[i]);
+ }
}
_inf = new EoBInfProcessor(this, _screen);
@@ -730,11 +736,6 @@ void EoBCoreEngine::runLoop() {
_drawSceneTimer = _system->getMillis();
_screen->setFont(_conFont);
_screen->setScreenDim(7);
- if (_flags.lang == Common::ZH_TWN) {
- _txt->setShadowColor(guiSettings()->colors.fill);
- _txt->setLineSpacing(-1);
- }
-
_runFlag = true;
while (!shouldQuit() && _runFlag) {
@@ -1616,11 +1617,6 @@ void EoBCoreEngine::initDialogueSequence() {
delete s;
_txt->setupField(9, 0);
-
- if (_flags.lang == Common::ZH_TWN) {
- _txt->setShadowColor(guiSettings()->colors.guiColorBlack);
- _txt->setLineSpacing(0);
- }
}
void EoBCoreEngine::restoreAfterDialogueSequence() {
@@ -1633,11 +1629,6 @@ void EoBCoreEngine::restoreAfterDialogueSequence() {
//_allowSkip = false;
_screen->setScreenDim(7);
- if (_flags.lang == Common::ZH_TWN) {
- _txt->setShadowColor(guiSettings()->colors.fill);
- _txt->setLineSpacing(-1);
- }
-
if (_flags.gameID == GI_EOB2)
snd_playSoundEffect(2);
@@ -1726,8 +1717,6 @@ int EoBCoreEngine::runDialogue(int dialogueTextId, int numStr, int loopButtonId,
void EoBCoreEngine::restParty_displayWarning(const char *str) {
int od = _screen->curDimIndex();
_screen->setScreenDim(7);
- int osh = (_flags.lang == Common::ZH_TWN) ? _txt->setShadowColor(guiSettings()->colors.fill) : 0xFFFF;
- int ols = (_flags.lang == Common::ZH_TWN) ? _txt->setLineSpacing(-1) : 0xFFFF;
Screen::FontId of = _screen->setFont(_conFont);
_screen->setCurPage(0);
@@ -1736,11 +1725,6 @@ void EoBCoreEngine::restParty_displayWarning(const char *str) {
_screen->setFont(of);
_screen->setScreenDim(od);
-
- if (osh != 0xFFFF)
- _txt->setShadowColor(osh);
- if (ols != 0xFFFF)
- _txt->setLineSpacing(ols);
}
bool EoBCoreEngine::restParty_updateMonsters() {
@@ -1759,18 +1743,12 @@ bool EoBCoreEngine::restParty_updateMonsters() {
Screen::FontId of = _screen->setFont(_conFont);
int od = _screen->curDimIndex();
_screen->setScreenDim(7);
- int osh = (_flags.lang == Common::ZH_TWN) ? _txt->setShadowColor(guiSettings()->colors.fill) : 0xFFFF;
- int ols = (_flags.lang == Common::ZH_TWN) ? _txt->setLineSpacing(-1) : 0xFFFF;
updateMonsters(0);
updateMonsters(1);
timerProcessFlyingObjects(0);
_screen->setScreenDim(od);
- if (osh != 0xFFFF)
- _txt->setShadowColor(osh);
- if (ols != 0xFFFF)
- _txt->setLineSpacing(ols);
_screen->setFont(of);
_partyResting = false;
diff --git a/engines/kyra/engine/lol.cpp b/engines/kyra/engine/lol.cpp
index 1b4b720ca69..1506fa65339 100644
--- a/engines/kyra/engine/lol.cpp
+++ b/engines/kyra/engine/lol.cpp
@@ -48,6 +48,7 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraRpgEngine(sy
_screen = 0;
_gui = 0;
_tim = 0;
+ _txt = 0;
_lang = 0;
_langIntern = 0;
@@ -393,7 +394,29 @@ Common::Error LoLEngine::init() {
}
_txt = new TextDisplayer_LoL(this, _screen);
- _txt->setLineSpacing(_flags.lang == Common::JA_JPN && _flags.use16ColorMode ? 1 : (_flags.lang == Common::ZH_TWN ? -1 : 0));
+ if (_flags.lang == Common::JA_JPN && _flags.use16ColorMode) {
+ for (int i = 0; i < _screen->screenDimTableCount(); ++i) {
+ _txt->setLineSpacing(i, 1);
+ if ((i >= 3 && i <= 5) || i == 15) {
+ for (int ii = 0; ii < 256; ++ii)
+ _txt->setColorMapping(i, ii, 1);
+ _txt->setColorMapping(i, 0, 0);
+ _txt->setColorMapping(i, 0x11, 0x11);
+ _txt->setColorMapping(i, 0x18, 0x61);
+ _txt->setColorMapping(i, 0x33, 0xE1);
+ _txt->setColorMapping(i, 0x44, 0x44);
+ _txt->setColorMapping(i, 0x55, 0x81);
+ _txt->setColorMapping(i, 0x88, 0x41);
+ _txt->setColorMapping(i, 0x99, 0xA1);
+ _txt->setColorMapping(i, 0xAA, 0x21);
+ _txt->setVisualLineSpacingAdjust(i, -1);
+ } else {
+ _txt->setCharSpacing(i, 1);
+ }
+ }
+ } else if (_flags.lang == Common::ZH_TWN) {
+ _txt->setLineSpacing(-1, -1);
+ }
_screen->setAnimBlockPtr(10000);
_screen->setScreenDim(0);
@@ -625,7 +648,7 @@ void LoLEngine::checkFloatingPointerRegions() {
Common::Point p = getMousePos();
- if (!(_updateFlags & 4) & !_floatingCursorControl) {
+ if (!(_updateFlags & 4) && !_floatingCursorControl) {
if (posWithinRect(p.x, p.y, 96, 0, 303, 136)) {
if (!posWithinRect(p.x, p.y, 128, 16, 271, 119)) {
if (posWithinRect(p.x, p.y, 112, 0, 287, 15))
@@ -2267,6 +2290,8 @@ int LoLEngine::processMagicHeal(int charNum, int spellLevel) {
uint16 pY = 138;
uint16 diff[4];
uint16 pts[4];
+ memset(pX, 0, sizeof(pX));
+ memset(diff, 0, sizeof(diff));
memset(pts, 0, sizeof(pts));
while (charNum < n) {
diff --git a/engines/kyra/engine/magic_eob.cpp b/engines/kyra/engine/magic_eob.cpp
index 6fc51eef9bc..5349ca82234 100644
--- a/engines/kyra/engine/magic_eob.cpp
+++ b/engines/kyra/engine/magic_eob.cpp
@@ -247,16 +247,10 @@ void EoBCoreEngine::removeCharacterEffect(int spell, int charIndex, int showWarn
int od = _screen->curDimIndex();
Screen::FontId of = _screen->setFont(_conFont);
_screen->setScreenDim(7);
- int osh = (_flags.lang == Common::ZH_TWN) ? _txt->setShadowColor(guiSettings()->colors.fill) : 0xFFFF;
- int ols = (_flags.lang == Common::ZH_TWN) ? _txt->setLineSpacing(-1) : 0xFFFF;
printWarning(Common::String::format(_magicStrings3[_flags.gameID == GI_EOB1 ? 3 : 2], c->name, s->name).c_str());
_screen->setScreenDim(od);
- if (osh != 0xFFFF)
- _txt->setShadowColor(osh);
- if (ols != 0xFFFF)
- _txt->setLineSpacing(ols);
_screen->setFont(of);
}
diff --git a/engines/kyra/engine/timer_eob.cpp b/engines/kyra/engine/timer_eob.cpp
index 9d88733ac42..ffe8278a48c 100644
--- a/engines/kyra/engine/timer_eob.cpp
+++ b/engines/kyra/engine/timer_eob.cpp
@@ -306,8 +306,6 @@ void EoBCoreEngine::timerSpecialCharacterUpdate(int timerNum) {
int od = _screen->curDimIndex();
Screen::FontId of = _screen->setFont(_conFont);
_screen->setScreenDim(7);
- int osh = (_flags.lang == Common::ZH_TWN) ? _txt->setShadowColor(guiSettings()->colors.fill) : 0xFFFF;
- int ols = (_flags.lang == Common::ZH_TWN) ? _txt->setLineSpacing(-1) : 0xFFFF;
switch (evt) {
case 2:
@@ -371,10 +369,6 @@ void EoBCoreEngine::timerSpecialCharacterUpdate(int timerNum) {
}
_screen->setScreenDim(od);
- if (osh != 0xFFFF)
- _txt->setShadowColor(osh);
- if (ols != 0xFFFF)
- _txt->setLineSpacing(ols);
_screen->setFont(of);
}
diff --git a/engines/kyra/gui/debugger.cpp b/engines/kyra/gui/debugger.cpp
index 6bb28cab858..1e86329f951 100644
--- a/engines/kyra/gui/debugger.cpp
+++ b/engines/kyra/gui/debugger.cpp
@@ -605,10 +605,6 @@ bool Debugger_EoB::cmdSetPosition(int argc, const char **argv) {
_vm->generateTempData();
_vm->txt()->removePageBreakFlag();
_vm->screen()->setScreenDim(7);
- if (_vm->gameFlags().lang == Common::ZH_TWN) {
- _vm->txt()->setShadowColor(_vm->guiSettings()->colors.fill);
- _vm->txt()->setLineSpacing(0);
- }
_vm->loadLevel(level, sub);
diff --git a/engines/kyra/gui/gui_eob.cpp b/engines/kyra/gui/gui_eob.cpp
index 1598221eb32..0ff4aac72c3 100644
--- a/engines/kyra/gui/gui_eob.cpp
+++ b/engines/kyra/gui/gui_eob.cpp
@@ -3967,10 +3967,8 @@ bool GUI_EoB::restParty() {
_screen->sega_clearTextBuffer(0);
if (_vm->gameFlags().lang == Common::ZH_TWN)
- _screen->drawBox(3, 170, 290, 199, 0xb7);
+ _screen->drawBox(3, 170, 290, 199, _vm->guiSettings()->colors.fill);
- int osh = (_vm->gameFlags().lang == Common::ZH_TWN) ? _vm->txt()->setShadowColor(_vm->guiSettings()->colors.fill) : 0xFFFF;
- int ols = (_vm->gameFlags().lang == Common::ZH_TWN) ? _vm->txt()->setLineSpacing(-1) : 0xFFFF;
Screen::FontId of = _screen->setFont(_vm->_conFont);
restParty_updateRestTime(hours, true);
@@ -4191,10 +4189,6 @@ bool GUI_EoB::restParty() {
_vm->removeInputTop();
_screen->setScreenDim(4);
_screen->setFont(of);
- if (osh != 0xFFFF)
- _vm->txt()->setShadowColor(osh);
- if (ols != 0xFFFF)
- _vm->txt()->setLineSpacing(ols);
if (!res) {
if (!injured)
@@ -4216,8 +4210,6 @@ void GUI_EoB::printScribeScrollSpellString(const int16 *menuItems, int id, bool
bool GUI_EoB::confirmDialogue(int id) {
int od = _screen->curDimIndex();
- int osh = (_vm->gameFlags().lang == Common::ZH_TWN) ? _vm->txt()->setShadowColor(_vm->guiSettings()->colors.guiColorBlack) : 0xFFFF;
- int ols = (_vm->gameFlags().lang == Common::ZH_TWN) ? _vm->txt()->setLineSpacing(0) : 0xFFFF;
Screen::FontId of = _screen->setFont(_menuFont);
Button *buttonList = initMenu(5);
@@ -4274,10 +4266,6 @@ bool GUI_EoB::confirmDialogue(int id) {
_screen->setFont(of);
_screen->setScreenDim(od);
- if (osh != 0xFFFF)
- _vm->txt()->setShadowColor(osh);
- if (ols != 0xFFFF)
- _vm->txt()->setLineSpacing(ols);
return result;
}
@@ -4593,9 +4581,6 @@ void GUI_EoB::drawMenuButtonBox(int x, int y, int w, int h, bool clicked, bool n
void GUI_EoB::drawTextBox(int dim, int id) {
int od = _screen->curDimIndex();
_screen->setScreenDim(dim);
- int osh = (_vm->gameFlags().lang == Common::ZH_TWN) ? _vm->txt()->setShadowColor(_vm->guiSettings()->colors.guiColorBlack) : 0xFFFF;
- int ols = (_vm->gameFlags().lang == Common::ZH_TWN) ? _vm->txt()->setLineSpacing(0) : 0xFFFF;
-
Screen::FontId of = _screen->setFont(_menuFont);
int cs = (_vm->gameFlags().platform == Common::kPlatformPC98 && !_vm->gameFlags().use16ColorMode) ? _screen->setFontStyles(_menuFont, Font::kStyleFat) : -1;
@@ -4612,10 +4597,6 @@ void GUI_EoB::drawTextBox(int dim, int id) {
_screen->copyRegion(0, 0, dm->sx << 3, dm->sy, dm->w << 3, dm->h, 2, 0, Screen::CR_NO_P_CHECK);
_screen->updateScreen();
- if (osh != 0xFFFF)
- _vm->txt()->setShadowColor(osh);
- if (ols != 0xFFFF)
- _vm->txt()->setLineSpacing(ols);
_screen->setScreenDim(od);
if (cs != -1)
@@ -4848,8 +4829,6 @@ void GUI_EoB::restParty_updateRestTime(int hours, bool init) {
Screen::FontId of = _screen->setFont(_menuFont);
int od = _screen->curDimIndex();
_screen->setScreenDim(10);
- int osh = (_vm->gameFlags().lang == Common::ZH_TWN) ? _vm->txt()->setShadowColor(_vm->guiSettings()->colors.guiColorBlack) : 0xFFFF;
- int ols = (_vm->gameFlags().lang == Common::ZH_TWN) ? _vm->txt()->setLineSpacing(0) : 0xFFFF;
if (init) {
_screen->setCurPage(0);
@@ -4866,10 +4845,6 @@ void GUI_EoB::restParty_updateRestTime(int hours, bool init) {
_screen->set16bitShadingLevel(0);
_screen->updateScreen();
_vm->delay(160);
- if (osh != 0xFFFF)
- _vm->txt()->setShadowColor(osh);
- if (ols != 0xFFFF)
- _vm->txt()->setLineSpacing(ols);
_screen->setScreenDim(od);
_screen->setFont(of);
}
diff --git a/engines/kyra/resource/staticres_eob.cpp b/engines/kyra/resource/staticres_eob.cpp
index dcb60c5a222..585e082dd6e 100644
--- a/engines/kyra/resource/staticres_eob.cpp
+++ b/engines/kyra/resource/staticres_eob.cpp
@@ -186,7 +186,7 @@ const ScreenDim Screen_EoB::_screenDimTableZH[] = {
{ 0x02, 0x18, 0x14, 0x78, 0x0F, 0x02, 0x03, 0x00 },
{ 0x00, 0x00, 0x16, 0x78, 0x0F, 0x0D, 0x00, 0x00 },
{ 0x0A, 0x6C, 0x15, 0x28, 0x0F, 0x00, 0x00, 0x00 },
- { 0x01, 0xAB, 0x23, 0x1C, 0x0F, 0x00, 0x00, 0x00 },
+ { 0x01, 0xAB, 0x23, 0x1C, 0x0F, 0x0C, 0x00, 0x00 },
{ 0x02, 0x18, 0x14, 0x00, 0x0F, 0x02, 0x03, 0x00 },
{ 0x01, 0x7D, 0x26, 0x40, 0x0F, 0x00, 0x03, 0x00 },
{ 0x00, 0x00, 0x16, 0x90, 0x0F, 0x02, 0x00, 0x00 },
diff --git a/engines/kyra/script/script_eob.cpp b/engines/kyra/script/script_eob.cpp
index 7749354b346..377daa3ae91 100644
--- a/engines/kyra/script/script_eob.cpp
+++ b/engines/kyra/script/script_eob.cpp
@@ -540,18 +540,11 @@ int EoBInfProcessor::oeob_printMessage_v1(int8 *data) {
col[3] = *pos++;
}
- if (_vm->gameFlags().platform == Common::kPlatformAmiga) {
- assert((uint8)col[1] < 16);
- assert((uint8)col[3] < 16);
- col[1] = _amigaColorMap[(uint8)col[1]];
- col[3] = _amigaColorMap[(uint8)col[3]];
- }
-
_vm->txt()->printMessage(col);
_vm->txt()->printMessage(str);
- col[1] = _vm->gameFlags().platform == Common::kPlatformSegaCD ? 0xFF : _vm->txt()->colorMap()[_screen->_curDim->col1];
- col[3] = _vm->txt()->colorMap()[_screen->_curDim->col2];
+ col[1] = _vm->gameFlags().platform == Common::kPlatformSegaCD ? 0xFF : _screen->_curDim->col1;
+ col[3] = _screen->_curDim->col2;
_vm->txt()->printMessage(col);
if (lineBreak)
@@ -570,10 +563,6 @@ int EoBInfProcessor::oeob_printMessage_v2(int8 *data) {
int c = 0;
_vm->_dialogueFieldAmiga = true;
- if (_vm->gameFlags().platform == Common::kPlatformAmiga) {
- assert(col < 16);
- col = _amigaColorMap[col];
- }
if (_activeCharacter == -1) {
c = _vm->rollDice(1, 6, -1);
@@ -1326,10 +1315,6 @@ int EoBInfProcessor::oeob_loadNewLevelOrMonsters(int8 *data) {
_vm->generateTempData();
_vm->txt()->removePageBreakFlag();
_screen->setScreenDim(7);
- if (_vm->gameFlags().lang == Common::ZH_TWN) {
- _vm->txt()->setShadowColor(_vm->guiSettings()->colors.fill);
- _vm->txt()->setLineSpacing(-1);
- }
_vm->loadLevel(index, cmd);
debugC(5, kDebugLevelScript, " - entering level '%d', sub level '%d', start block '0x%.04X', start direction '%d'", index, cmd, _vm->_currentBlock, _vm->_currentDirection);
@@ -1548,10 +1533,6 @@ int EoBInfProcessor::oeob_sequence(int8 *data) {
}
_vm->screen()->setScreenDim(7);
- if (_vm->gameFlags().lang == Common::ZH_TWN) {
- _vm->txt()->setShadowColor(_vm->guiSettings()->colors.fill);
- _vm->txt()->setLineSpacing(-1);
- }
return pos - data;
}
@@ -1668,10 +1649,6 @@ int EoBInfProcessor::oeob_specialEvent(int8 *data) {
return pos - data;
}
-const uint8 EoBInfProcessor::_amigaColorMap[16] = {
- 0x00, 0x06, 0x1d, 0x1b, 0x1a, 0x17, 0x18, 0x0e, 0x19, 0x1c, 0x1c, 0x1e, 0x13, 0x0a, 0x11, 0x1f
-};
-
const uint8 EoBInfProcessor::_segaCDColorMap[16] = {
0x00, 0xFF, 0x99, 0x55, 0xFF, 0x99, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};
diff --git a/engines/kyra/script/script_eob.h b/engines/kyra/script/script_eob.h
index 0e9683293b8..041f3d19b34 100644
--- a/engines/kyra/script/script_eob.h
+++ b/engines/kyra/script/script_eob.h
@@ -120,7 +120,6 @@ private:
int8 _activeCharacter;
- static const uint8 _amigaColorMap[16];
static const uint8 _segaCDColorMap[16];
const int _commandMin;
diff --git a/engines/kyra/text/text_lol.cpp b/engines/kyra/text/text_lol.cpp
index 98cb883a747..22882f41560 100644
--- a/engines/kyra/text/text_lol.cpp
+++ b/engines/kyra/text/text_lol.cpp
@@ -139,11 +139,11 @@ void TextDisplayer_LoL::printDialogueText2(int dim, const char *str, EMCState *s
if (dim == 3) {
if (_vm->_updateFlags & 2) {
oldDim = clearDim(4);
- _textDimData[4].color1 = _vm->gameFlags().use16ColorMode ? 0x33 : 254;
+ _textDimData[4].color1= _vm->gameFlags().use16ColorMode ? 0x33 : 254;
_textDimData[4].color2 = _screen->_curDim->col2;
} else {
oldDim = clearDim(3);
- _textDimData[3].color1 = _vm->gameFlags().use16ColorMode ? 0x33 : 192;
+ _textDimData[3].color1= _vm->gameFlags().use16ColorMode ? 0x33 : 192;
_textDimData[3].color2 = _screen->_curDim->col2;
if (!_vm->gameFlags().use16ColorMode)
_screen->copyColor(192, 254);
@@ -155,7 +155,7 @@ void TextDisplayer_LoL::printDialogueText2(int dim, const char *str, EMCState *s
oldDim = _screen->curDimIndex();
_screen->setScreenDim(dim);
_lineCount = 0;
- _textDimData[dim].color1 = _vm->gameFlags().use16ColorMode ? 0x33 : 254;
+ _textDimData[dim].color1= _vm->gameFlags().use16ColorMode ? 0x33 : 254;
_textDimData[dim].color2 = _screen->_curDim->col2;
}
@@ -194,14 +194,14 @@ void TextDisplayer_LoL::printMessage(uint16 type, const char *str, ...) {
if (_vm->_updateFlags & 2) {
clearDim(4);
- _textDimData[4].color1 = col;
+ _textDimData[4].color1= col;
} else {
clearDim(3);
if (_vm->gameFlags().use16ColorMode) {
- _textDimData[3].color1 = col;
+ _textDimData[3].color1= col;
} else {
_screen->copyColor(192, col);
- _textDimData[3].color1 = 192;
+ _textDimData[3].color1= 192;
}
_vm->enableTimer(11);
}
diff --git a/engines/kyra/text/text_rpg.cpp b/engines/kyra/text/text_rpg.cpp
index 65211178de6..f4e056a33a8 100644
--- a/engines/kyra/text/text_rpg.cpp
+++ b/engines/kyra/text/text_rpg.cpp
@@ -33,17 +33,12 @@ enum {
};
TextDisplayer_rpg::TextDisplayer_rpg(KyraRpgEngine *engine, Screen *scr) : _vm(engine), _screen(scr),
-_lineCount(0), _printFlag(false), _lineWidth(0), _numCharsTotal(0), _allowPageBreak(true),
- _numCharsLeft(0), _numCharsPrinted(0), _sjisTextModeLineBreak(false), _waitButtonMode(1),
- _pc98TextMode(engine->gameFlags().use16ColorMode && engine->game() == GI_LOL), _shadowColor(0), _lineSpacing(0), _preventHalfWidthLineEnd(false),
+ _lineCount(0), _printFlag(false), _lineWidth(0), _numCharsTotal(0), _allowPageBreak(true), _dimCount(scr ? scr->screenDimTableCount() : 0),
+ _numCharsLeft(0), _numCharsPrinted(0), _twoByteLineBreakFlag(false), _waitButtonMode(1),
+ _pc98TextMode(engine->gameFlags().use16ColorMode && engine->game() == GI_LOL),
_waitButtonFont(Screen::FID_6_FNT), _isChinese(_vm->gameFlags().lang == Common::Language::ZH_TWN || _vm->gameFlags().lang == Common::Language::ZH_CHN) {
- static const uint8 amigaColorMap[16] = {
- 0x00, 0x06, 0x1d, 0x1b, 0x1a, 0x17, 0x18, 0x0e, 0x19, 0x1c, 0x1c, 0x1e, 0x13, 0x0a, 0x11, 0x1f
- };
-
_dialogueBuffer = new char[kEoBTextBufferSize]();
-
_currentLine = new char[85]();
if (_pc98TextMode)
@@ -55,22 +50,18 @@ _lineCount(0), _printFlag(false), _lineWidth(0), _numCharsTotal(0), _allowPageBr
else if ((_vm->game() == GI_LOL && _vm->gameFlags().lang == Common::Language::ZH_TWN))
_waitButtonFont = Screen::FID_CHINESE_FNT;
- _preventHalfWidthLineEnd = ((_vm->gameFlags().lang == Common::JA_JPN && _vm->game() == GI_EOB1) || (_vm->gameFlags().lang == Common::Language::ZH_TWN && _vm->game() == GI_EOB2));
+ _textDimData = new TextDimData[_dimCount];
+ memset(_textDimData, 0, sizeof(TextDimData) * _dimCount);
- _textDimData = new TextDimData[_screen->screenDimTableCount()];
+ applySetting(-1, kNoHalfWidthLineEnd, ((_vm->gameFlags().lang == Common::JA_JPN && _vm->game() == GI_EOB1) || (_vm->gameFlags().lang == Common::Language::ZH_TWN && _vm->game() == GI_EOB2)) ? 1 : 0);
for (int i = 0; i < 256; ++i)
_colorMap[i] = i;
- if (_vm->gameFlags().platform == Common::kPlatformAmiga)
- memcpy(_colorMap, amigaColorMap, 16);
- else if (_vm->game() == GI_EOB1 && _vm->gameFlags().platform == Common::kPlatformPC98)
- _colorMap[12] = 0;
-
- for (int i = 0; i < _screen->screenDimTableCount(); i++) {
+ for (int i = 0; i < _dimCount; ++i) {
const ScreenDim *d = _screen->getScreenDim(i);
- _textDimData[i].color1 = _colorMap[d->col1];
- _textDimData[i].color2 = _colorMap[d->col2];
+ _textDimData[i].color1= d->col1;
+ _textDimData[i].color2 = d->col2;
_textDimData[i].line = d->line;
_textDimData[i].column = d->column;
}
@@ -84,6 +75,7 @@ _lineCount(0), _printFlag(false), _lineWidth(0), _numCharsTotal(0), _allowPageBr
}
TextDisplayer_rpg::~TextDisplayer_rpg() {
+ setColorMapping(-1, 0 ,0);
delete[] _dialogueBuffer;
delete[] _currentLine;
delete[] _textDimData;
@@ -127,6 +119,23 @@ void TextDisplayer_rpg::removePageBreakFlag() {
_allowPageBreak = false;
}
+void TextDisplayer_rpg::setColorMapping(int sd, uint8 from, uint8 to) {
+ if (sd < -1 || sd >= _dimCount)
+ error("TextDisplayer_rpg::mapColor(): arg out of range");
+
+ if (sd == -1) {
+ for (int i = 0; i < _dimCount; ++i) {
+ delete[] _textDimData[i].colorMap;
+ _textDimData[i].colorMap = 0;
+ }
+ _colorMap[from] = to;
+ } else {
+ if (_textDimData[sd].colorMap == nullptr)
+ _textDimData[sd].colorMap = new uint8[256];
+ _textDimData[sd].colorMap[from] = to;
+ }
+}
+
void TextDisplayer_rpg::displayText(char *str, ...) {
convertString(str);
_printFlag = false;
@@ -151,7 +160,6 @@ void TextDisplayer_rpg::displayText(char *str, ...) {
int sdx = _screen->curDimIndex();
bool sjisTextMode = (_pc98TextMode && (sdx == 3 || sdx == 4 || sdx == 5 || sdx == 15)) ? true : false;
- int sjisOffs = (sjisTextMode || _vm->game() != GI_LOL) ? 8 : 9;
Screen::FontId of = (_vm->game() == GI_EOB2 && _vm->gameFlags().platform == Common::kPlatformFMTowns) ? _screen->setFont(Screen::FID_8_FNT) : _screen->_currentFont;
uint16 charsPerLine = (sd->w << 3) / (_screen->getFontWidth() + _screen->_charSpacing);
@@ -174,40 +182,22 @@ void TextDisplayer_rpg::displayText(char *str, ...) {
c = parseCommand();
}
- if (_vm->gameFlags().lang == Common::JA_JPN) {
- uint8 cu = (uint8) c;
- if (cu >= 0xE0 || (cu > 0x80 && cu < 0xA0)) {
- if ((_textDimData[sdx].column + _lineWidth + sjisOffs) > (sd->w << 3))
- printLine(_currentLine);
-
- _currentLine[_numCharsLeft++] = c;
- _currentLine[_numCharsLeft++] = parseCommand();
- _currentLine[_numCharsLeft] = '\0';
-
- _lineWidth += sjisOffs;
- if (_preventHalfWidthLineEnd && ((sd->w << 3) - sjisOffs) <= (_textDimData[sdx].column + _lineWidth))
- printLine(_currentLine);
- c = parseCommand();
- continue;
- }
- }
+ if (isTwoByteChar(c)) {
+ char next = parseCommand();
+ int cw = _screen->getCharWidth((uint8)c | (uint8)next << 8) + _textDimData[sdx].charSpacing;
+ if (_textDimData[sdx].column + _lineWidth + cw > (sd->w << 3))
+ printLine(_currentLine);
- if (_isChinese) {
- uint8 cu = (uint8) c;
- if (cu & 0x80) {
- if ((_textDimData[sdx].column + _lineWidth + Graphics::Big5Font::kChineseTraditionalWidth) > (sd->w << 3))
- printLine(_currentLine);
+ _currentLine[_numCharsLeft++] = c;
+ _currentLine[_numCharsLeft++] = next;
+ _currentLine[_numCharsLeft] = '\0';
- _currentLine[_numCharsLeft++] = c;
- _currentLine[_numCharsLeft++] = parseCommand();
- _currentLine[_numCharsLeft] = '\0';
+ _lineWidth += cw;
+ if (_textDimData[sdx].noHalfWidthLineEnd && (_textDimData[sdx].column + _lineWidth + cw >= (sd->w << 3)))
+ printLine(_currentLine);
- _lineWidth += Graphics::Big5Font::kChineseTraditionalWidth;
- if (_preventHalfWidthLineEnd && (_textDimData[sdx].column + _lineWidth + Graphics::Big5Font::kChineseTraditionalWidth) > (sd->w << 3))
- printLine(_currentLine);
- c = parseCommand();
- continue;
- }
+ c = parseCommand();
+ continue;
}
uint16 dv = _textDimData[sdx].column / (_screen->getFontWidth() + _screen->_charSpacing);
@@ -223,17 +213,11 @@ void TextDisplayer_rpg::displayText(char *str, ...) {
case 1:
printLine(_currentLine);
_textDimData[sdx].color2 = parseCommand();
- // EOB II Amiga does not use a color table here. EOB I doesn't do any color mapping here.
- /*if (_vm->gameFlags().platform == Common::kPlatformAmiga)
- _textDimData[sdx].color2 = _colorMap[_textDimData[sdx].color2];*/
break;
case 5:
printLine(_currentLine);
- _textDimData[sdx].color1 = parseCommand();
- // EOB I doesn't do any color mapping here.
- if (_vm->gameFlags().platform == Common::kPlatformAmiga && _vm->game() == GI_EOB2)
- _textDimData[sdx].color1 = _colorMap[_textDimData[sdx].color1];
+ _textDimData[sdx].color1= parseCommand();
break;
case 8:
@@ -247,9 +231,9 @@ void TextDisplayer_rpg::displayText(char *str, ...) {
case 12:
if (sjisTextMode)
- _sjisTextModeLineBreak = true;
+ _twoByteLineBreakFlag = true;
printLine(_currentLine);
- _sjisTextModeLineBreak = false;
+ _twoByteLineBreakFlag = false;
//_lineWidth = 0;
_lineCount++;
_textDimData[sdx].column = 0;
@@ -266,7 +250,8 @@ void TextDisplayer_rpg::displayText(char *str, ...) {
default:
if (_vm->game() == GI_EOB1 || _vm->game() == GI_LOL || (unsigned char)c > 30) {
- _lineWidth += (sjisTextMode ? 4 : (_screen->_currentFont == Screen::FID_SJIS_TEXTMODE_FNT ? 9 : _screen->getCharWidth((uint8)c)));
+ int cw = _screen->getCharWidth((uint8)c) + _textDimData[sdx].charSpacing;
+ _lineWidth += cw;
_currentLine[_numCharsLeft++] = c;
_currentLine[_numCharsLeft] = 0;
@@ -345,9 +330,8 @@ void TextDisplayer_rpg::printLine(char *str) {
const ScreenDim *sd = _screen->_curDim;
int sdx = _screen->curDimIndex();
bool sjisTextMode = _pc98TextMode && (sdx == 3 || sdx == 4 || sdx == 5 || sdx == 15) ? true : false;
- int sjisOffs = (sjisTextMode || _vm->game() != GI_LOL) ? 8 : 9;
- int fh = _screen->getFontHeight() + _screen->_lineSpacing + _lineSpacing;
+ int fh = _screen->getFontHeight() + _screen->_lineSpacing + _textDimData[sdx].lineSpacing;
int lines = (sd->h - _screen->_lineSpacing) / fh;
while (_textDimData[sdx].line >= lines) {
@@ -364,13 +348,14 @@ void TextDisplayer_rpg::printLine(char *str) {
if (h2)
_screen->copyRegion(sd->sx << 3, sd->sy + fh, sd->sx << 3, sd->sy, sd->w << 3, h2, _screen->_curPage, _screen->_curPage, Screen::CR_NO_P_CHECK);
- // In Chinese EOBII some characters overdraw the valid boundaries by one pixel
- // (at least the ',' does). So, the original redraws the border here. We do the same...
+ // HACK: In Chinese EOBII some characters overdraw the valid boundaries by one pixel
+ // (at least the ',' does). So, the original redraws the border here. We do the same
+ // since for now I don't have any good idea how to do this less ugly...
if (_isChinese && _vm->_flags.gameID == GI_EOB2 && sdx == 7)
- _screen->drawBox(3, 170, 290, 199, 0xb7);
+ _screen->drawBox(3, 170, 290, 199, _vm->guiSettings()->colors.fill);
_screen->set16bitShadingLevel(4);
- _screen->fillRect(sd->sx << 3, sd->sy + h1, ((sd->sx + sd->w) << 3) - 1, sd->sy + sd->h - 1, _textDimData[sdx].color2);
+ _screen->fillRect(sd->sx << 3, sd->sy + h1, ((sd->sx + sd->w) << 3) - 1, sd->sy + sd->h - 1, remapColor(sdx, _textDimData[sdx].color2));
_screen->set16bitShadingLevel(0);
if (_textDimData[sdx].line)
@@ -378,11 +363,10 @@ void TextDisplayer_rpg::printLine(char *str) {
}
int x1 = (sd->sx << 3) + _textDimData[sdx].column;
- int y = sd->sy + (sjisTextMode ? (_textDimData[sdx].line << 3) : (fh * _textDimData[sdx].line));
+ int y = sd->sy + (fh + _textDimData[sdx].visualLineSpacingAdjust) * _textDimData[sdx].line;
int w = sd->w << 3;
int lw = _lineWidth;
int s = _numCharsLeft;
- char c = 0;
uint8 twoByteCharOffs = 0;
if (sjisTextMode) {
@@ -393,7 +377,7 @@ void TextDisplayer_rpg::printLine(char *str) {
// cut off line to leave space for "MORE" button
w -= _vm->guiSettings()->buttons.waitReserve;
} else {
- if (!_sjisTextModeLineBreak || (_lineCount + 1 < lines - 1))
+ if (!_twoByteLineBreakFlag || (_lineCount + 1 < lines - 1))
ct = false;
else
// cut off line to leave space for "MORE" button
@@ -407,31 +391,26 @@ void TextDisplayer_rpg::printLine(char *str) {
int n1 = (w / 4) - 1;
while (n2 < n1 && n2 < s) {
- c = str[n2];
- uint8 cu = (uint8) c;
- if (cu >= 0xE0 || (cu > 0x80 && cu < 0xA0))
+ if (isTwoByteChar(str[n2]))
n2++;
n2++;
}
s = n2;
}
- } else if (_isChinese) {
- s = strlen(str);
- twoByteCharOffs = 16;
- if ((lw + _textDimData[sdx].column) >= w) {
- s -= ((lw + _textDimData[sdx].column) - w) >> 3;
- w -= _textDimData[sdx].column;
- }
} else {
- if (_vm->gameFlags().lang == Common::JA_JPN) {
- for (int i = 0; i < s; ++i) {
- uint8 cu = (uint8) str[i];
- if (cu >= 0xE0 || (cu > 0x80 && cu < 0xA0))
- twoByteCharOffs = (_vm->game() == GI_EOB1) ? 16 : 8;
- }
+ for (int i = 0; i < s; ++i) {
+ if (isTwoByteChar(str[i]))
+ twoByteCharOffs = (_vm->game() == GI_EOB1 || _isChinese) ? 16 : 8;
}
- if ((lw + _textDimData[sdx].column) >= w) {
+ if (_isChinese) {
+ s = strlen(str);
+ if ((lw + _textDimData[sdx].column) >= w) {
+ s -= ((lw + _textDimData[sdx].column - w) >> 3);
+ w -= _textDimData[sdx].column;
+ }
+
+ } else if ((lw + _textDimData[sdx].column) >= w) {
if ((lines - 1) <= _lineCount && _allowPageBreak)
// cut off line to leave space for "MORE" button
w -= _vm->guiSettings()->buttons.waitReserve;
@@ -444,16 +423,13 @@ void TextDisplayer_rpg::printLine(char *str) {
if (twoByteCharOffs) {
lw = 0;
int prevStrPos = 0;
- c = str[0];
for (strPos = 0; strPos < s; ++strPos) {
- uint8 cu = (uint8) str[strPos];
- if (cu >= 0xE0 || (cu > 0x80 && cu < 0xA0)) {
- lw += sjisOffs;
- strPos++;
- } else {
- lw += _screen->getCharWidth((uint8)c);
- }
+ uint8 c = str[strPos];
+ if (isTwoByteChar(c))
+ lw += (_screen->getCharWidth(c | (uint8)str[++strPos] << 8) + _textDimData[sdx].charSpacing);
+ else
+ lw += _screen->getCharWidth(c);
if (!lineLastCharPos && w < lw + twoByteCharOffs)
lineLastCharPos = prevStrPos;
@@ -464,7 +440,6 @@ void TextDisplayer_rpg::printLine(char *str) {
break;
}
prevStrPos = strPos;
- c = (char) cu;
}
if (!lineLastCharPos) {
@@ -480,9 +455,8 @@ void TextDisplayer_rpg::printLine(char *str) {
} else {
while (strPos > 0) {
//cut off line after last space
- c = str[strPos];
-
- lw -= _screen->getCharWidth((uint8)c);
+ uint8 c = str[strPos];
+ lw -= _screen->getCharWidth(c);
if (!lineLastCharPos && lw <= w)
lineLastCharPos = strPos;
@@ -507,58 +481,35 @@ void TextDisplayer_rpg::printLine(char *str) {
}
}
- c = str[s];
+ char lastChr = str[s];
str[s] = 0;
- uint8 col = _textDimData[sdx].color1;
+ uint8 col1 = remapColor(sdx, _textDimData[sdx].color1);
+ uint8 col2 = remapColor(sdx, _textDimData[sdx].color2);
if (sjisTextMode && (sdx == 2 || sdx == 3 || sdx == 4 || sdx == 5 || sdx == 15)) {
- switch (_textDimData[sdx].color1) {
- case 0x88:
- col = 0x41;
- break;
- case 0x55:
- col = 0x81;
- break;
- case 0xAA:
- col = 0x21;
- break;
- case 0x99:
- col = 0xA1;
- break;
- case 0x33:
- col = 0xE1;
- break;
- case 0x18:
- col = 0x61;
- break;
- default:
- col = 1;
- break;
- }
- _screen->printText(str, x1 & ~3, (y + 8) & ~7, col, 0);
- } else {
- uint8 col2 = _textDimData[sdx].color2;
- if (_shadowColor) {
- _screen->printText(str, x1 - 1, y, _shadowColor, col2);
- _screen->printText(str, x1, y + 1, _shadowColor, 0);
- _screen->printText(str, x1 - 1, y + 1, _shadowColor, 0);
- // Another hack for Chinese EOBII. Due to the reduced line spacing - while still drawing a shadow for the font - the
- // lines will overdraw by one pixel if we don't clear the bottom line. This will otherwise cause glitches when doing line feeds.
- for (int i = 0; i < -_lineSpacing && y + fh + i < sd->sy + sd->h; ++i)
- _screen->drawClippedLine(x1 - 1, y + fh + i, x1 + lw, y + fh + i, _textDimData[sdx].color2);
- col2 = 0;
- }
- _screen->printText(str, x1, y, col, col2);
+ x1 &= ~3;
+ y = (y + 8) & ~7;
+ col2 = 0;
}
+ if (_textDimData[sdx].shadowColor) {
+ _screen->printText(str, x1 - 1, y, _textDimData[sdx].shadowColor, col2);
+ _screen->printText(str, x1, y + 1, _textDimData[sdx].shadowColor, 0);
+ _screen->printText(str, x1 - 1, y + 1, _textDimData[sdx].shadowColor, 0);
+ // Another hack for Chinese EOBII. Due to the reduced line spacing - while still drawing a shadow for the font - the
+ // lines will overdraw by one pixel if we don't clear the bottom line. This will otherwise cause glitches when doing line feeds.
+ for (int i = 0; i < -_textDimData[sdx].lineSpacing && y + fh + i < sd->sy + sd->h; ++i)
+ _screen->drawClippedLine(x1 - 1, y + fh + i, x1 + lw, y + fh + i, col2);
+ col2 = 0;
+ }
+ _screen->printText(str, x1, y, col1, col2);
+
_textDimData[sdx].column += lw;
_numCharsPrinted += strlen(str);
- str[s] = c;
-
- if (c == ' ')
+ str[s] = lastChr;
+ if (lastChr == ' ')
s++;
-
if (str[s] == ' ')
s++;
@@ -568,7 +519,7 @@ void TextDisplayer_rpg::printLine(char *str) {
str[len] = 0;
_numCharsLeft = strlen(str);
- _lineWidth = sjisTextMode ? (_numCharsLeft << 2) : (_screen->_currentFont == Screen::FID_SJIS_TEXTMODE_FNT ? _numCharsLeft * 9 : _screen->getTextWidth(str));
+ _lineWidth = _screen->getTextWidth(str) + _textDimData[sdx].charSpacing * _numCharsLeft;
if (!_numCharsLeft && (_textDimData[sdx].column + twoByteCharOffs) <= (sd->w << 3))
return;
@@ -620,7 +571,7 @@ void TextDisplayer_rpg::printMessage(const char *str, int textColor, ...) {
int tc = _textDimData[_screen->curDimIndex()].color1;
if (textColor != -1)
- _textDimData[_screen->curDimIndex()].color1 = textColor;
+ _textDimData[_screen->curDimIndex()].color1= textColor;
va_list args;
va_start(args, textColor);
@@ -630,7 +581,7 @@ void TextDisplayer_rpg::printMessage(const char *str, int textColor, ...) {
displayText(_dialogueBuffer, textColor);
if (_vm->game() != GI_EOB1)
- _textDimData[_screen->curDimIndex()].color1 = tc;
+ _textDimData[_screen->curDimIndex()].color1= tc;
if (!_screen->_curPage)
_screen->updateScreen();
@@ -639,8 +590,9 @@ void TextDisplayer_rpg::printMessage(const char *str, int textColor, ...) {
int TextDisplayer_rpg::clearDim(int dim) {
int res = _screen->curDimIndex();
_screen->setScreenDim(dim);
- _textDimData[dim].color1 = _colorMap[_screen->_curDim->col1];
- _textDimData[dim].color2 = (_vm->game() == GI_LOL || _vm->gameFlags().platform == Common::kPlatformAmiga) ? _colorMap[_screen->_curDim->col2] : _vm->guiSettings()->colors.fill;
+ _textDimData[dim].color1= _screen->_curDim->col1;
+ _textDimData[dim].color2 = (_vm->game() == GI_LOL || _vm->gameFlags().platform == Common::kPlatformAmiga) ? _screen->_curDim->col2 : _vm->guiSettings()->colors.fill;
+
clearCurDim();
return res;
}
@@ -653,11 +605,9 @@ void TextDisplayer_rpg::clearCurDim() {
int wOffs = 0;
int hOffs = 0;
- if (_shadowColor) {
+ if (_textDimData[d].shadowColor) {
if (tmp->sx > 0)
xOffs = wOffs = 1;
- if (tmp->sy + tmp->h < Screen::SCREEN_H)
- hOffs = 1;
}
if (_pc98TextMode) {
@@ -665,7 +615,7 @@ void TextDisplayer_rpg::clearCurDim() {
--hOffs;
}
- _screen->fillRect((tmp->sx << 3) - xOffs, tmp->sy, ((tmp->sx + tmp->w) << 3) - 1 + wOffs, (tmp->sy + tmp->h) - 1 + hOffs, _textDimData[d].color2);
+ _screen->fillRect((tmp->sx << 3) - xOffs, tmp->sy, ((tmp->sx + tmp->w) << 3) - 1 + wOffs, (tmp->sy + tmp->h) - 1 + hOffs, remapColor(d, _textDimData[d].color2));
_lineCount = 0;
_textDimData[d].column = _textDimData[d].line = 0;
@@ -698,7 +648,8 @@ void TextDisplayer_rpg::textPageBreak() {
if (_vm->speechEnabled() && _vm->_activeVoiceFileTotalTime && _numCharsTotal)
speechPartTime = _vm->_system->getMillis() + ((_numCharsPrinted * _vm->_activeVoiceFileTotalTime) / _numCharsTotal);
- const ScreenDim *dim = _screen->getScreenDim(_screen->curDimIndex());
+ int sdx = _screen->curDimIndex();
+ const ScreenDim *dim = _screen->getScreenDim(sdx);
int x = ((dim->sx + dim->w) << 3) - (_vm->_dialogueButtonWidth + 3);
int y = 0;
@@ -776,9 +727,9 @@ void TextDisplayer_rpg::textPageBreak() {
_screen->set16bitShadingLevel(4);
if (_vm->game() == GI_LOL && _vm->gameFlags().use16ColorMode)
- _screen->fillRect(x + 8, y, x + 57, y + _vm->guiSettings()->buttons.height, _textDimData[_screen->curDimIndex()].color2);
+ _screen->fillRect(x + 8, y, x + 57, y + _vm->guiSettings()->buttons.height, remapColor(sdx, _textDimData[sdx].color2));
else
- _screen->fillRect(x, y, x + w - 1, y + _vm->guiSettings()->buttons.height - 1, _textDimData[_screen->curDimIndex()].color2);
+ _screen->fillRect(x, y, x + w - 1, y + _vm->guiSettings()->buttons.height - 1, remapColor(sdx, _textDimData[sdx].color2));
clearCurDim();
_screen->set16bitShadingLevel(0);
@@ -858,6 +809,46 @@ void TextDisplayer_rpg::convertString(char *str) {
}
}
+bool TextDisplayer_rpg::isTwoByteChar(uint8 c) const {
+ if (_vm->gameFlags().lang == Common::JA_JPN)
+ return (c >= 0xE0 || (c > 0x80 && c < 0xA0));
+ else if (_vm->gameFlags().lang == Common::ZH_TWN)
+ return (c & 0x80);
+ return false;
+}
+
+void TextDisplayer_rpg::applySetting(int sd, int ix, int val) {
+ if (sd < -1 || sd >= _dimCount || ix >= kOutOfRange)
+ error("TextDisplayer_rpg::applySetting(): arg out of range");
+
+ const int *memberAddr[] = {
+ &_textDimData[0].lineSpacing,
+ &_textDimData[0].visualLineSpacingAdjust,
+ &_textDimData[0].charSpacing,
+ &_textDimData[0].shadowColor,
+ &_textDimData[0].noHalfWidthLineEnd
+ };
+
+ int offset = (const byte*)memberAddr[ix] - (const byte*)&_textDimData[0];
+
+ if (sd == -1) {
+ for (int i = 0; i < _dimCount; ++i)
+ *(int*)((byte*)&_textDimData[i] + offset) = val;
+ } else {
+ *(int*)((byte*)&_textDimData[sd] + offset) = val;
+ }
+}
+
+uint8 TextDisplayer_rpg::remapColor(int sd, uint8 color) const {
+ if (sd < -1 || sd >= _dimCount)
+ error("TextDisplayer_rpg::applySetting(): arg out of range");
+
+ if (sd != -1 && _textDimData[sd].colorMap != nullptr)
+ return _textDimData[sd].colorMap[color];
+
+ return _colorMap[color];
+}
+
} // End of namespace Kyra
#endif // (ENABLE_EOB || ENABLE_LOL)
diff --git a/engines/kyra/text/text_rpg.h b/engines/kyra/text/text_rpg.h
index 9a2f0c264d8..6fa673141e4 100644
--- a/engines/kyra/text/text_rpg.h
+++ b/engines/kyra/text/text_rpg.h
@@ -53,10 +53,17 @@ public:
void allowPageBreak(bool mode) { _allowPageBreak = mode; }
void setWaitButtonMode(int mode) { _waitButtonMode = mode; }
- int setShadowColor(int col) { SWAP(col, _shadowColor); return col; }
- int setLineSpacing(int spacing) { SWAP(spacing, _lineSpacing); return spacing; }
int lineCount() const { return _lineCount; }
- const uint8 *colorMap() const { return _colorMap; }
+ //const uint8 *colorMap() const { return _colorMap; }
+
+ // These methods are ScummVM specific. They are supposed to make necessary modifications
+ // to the text displayer for the various Japanese and Chinese versions without too much
+ // hackery...
+ void setColorMapping(int sd, uint8 from, uint8 to);
+ void setShadowColor(int sd, int col) { applySetting(sd, kShadowColor, col); }
+ void setLineSpacing(int sd, int spacing) { applySetting(sd, kLineSpacing, spacing); }
+ void setVisualLineSpacingAdjust(int sd, int adj) { applySetting(sd, kVisualLineSpacingAdjust, adj); }
+ void setCharSpacing(int sd, int spacing) { applySetting(sd, kCharSpacing, spacing); }
protected:
virtual KyraRpgEngine *vm() { return _vm; }
@@ -84,7 +91,7 @@ protected:
uint32 _numCharsPrinted;
bool _printFlag;
- bool _sjisTextModeLineBreak;
+ bool _twoByteLineBreakFlag;
const bool _pc98TextMode;
Common::String _pageBreakString;
@@ -102,17 +109,36 @@ protected:
uint8 color2;
uint16 column;
uint8 line;
+ // These properties don't appear in the original code. The various Japanese and Chinese versions
+ // just had their modifications hacked in in whatever way the devs felt like. These properties
+ // help making the necessary adjustments without too much hackery...
+ int lineSpacing;
+ int visualLineSpacingAdjust; // LOL PC-98 has the worst hack here. The visual line spacing is different than the one that is used to measure the text field space.
+ int charSpacing;
+ int shadowColor;
+ int noHalfWidthLineEnd;
+ uint8 *colorMap;
};
TextDimData *_textDimData;
+ const int _dimCount;
KyraRpgEngine *_vm;
private:
- Screen *_screen;
- int _lineSpacing;
- int _shadowColor;
- bool _preventHalfWidthLineEnd;
+ bool isTwoByteChar(uint8 c) const;
+ void applySetting(int sd, int ix, int val);
+ uint8 remapColor(int sd, uint8 color) const;
+
+ enum TextFieldVar {
+ kLineSpacing = 0,
+ kVisualLineSpacingAdjust,
+ kCharSpacing,
+ kShadowColor,
+ kNoHalfWidthLineEnd,
+ kOutOfRange
+ };
+ Screen *_screen;
char *_table1;
char *_table2;
Commit: 8510798d44c9b23d89512fe3b36bd7372cc22d11
https://github.com/scummvm/scummvm/commit/8510798d44c9b23d89512fe3b36bd7372cc22d11
Author: athrxx (athrxx at scummvm.org)
Date: 2023-07-11T14:35:03+02:00
Commit Message:
KYRA: (EOB II/ZH) - add missing kyradat resources
The kyradat resources should now be complete. I also
added some specific Chinese grammar handling logic
for magic items.
Changed paths:
devtools/create_kyradat/resources.cpp
devtools/create_kyradat/resources/eob2_dos_chinese.h
dists/engine-data/kyra.dat
engines/kyra/engine/items_eob.cpp
diff --git a/devtools/create_kyradat/resources.cpp b/devtools/create_kyradat/resources.cpp
index 4eb076c58e0..3967b2fde5b 100644
--- a/devtools/create_kyradat/resources.cpp
+++ b/devtools/create_kyradat/resources.cpp
@@ -3561,7 +3561,7 @@ static const ResourceProvider resourceProviders[] = {
{ kEoBBaseSaveThrwLvlIndex, kEoB2, kPlatformDOS, kTalkieVersion, UNK_LANG, &kEoB2SaveThrwLvlIndexDOSProvider },
{ kEoBBaseSaveThrwModDiv, kEoB2, kPlatformDOS, kTalkieVersion, UNK_LANG, &kEoB2SaveThrwModDivDOSProvider },
{ kEoBBaseSaveThrwModExt, kEoB2, kPlatformDOS, kTalkieVersion, UNK_LANG, &kEoB2SaveThrwModExtDOSProvider },
- { kEoBBaseEnchantedString, kEoB2, kPlatformDOS, kTalkieVersion, UNK_LANG, &kEoB2EnchantedStringDOSProvider },
+ { kEoBBaseEnchantedString, kEoB2, kPlatformDOS, kTalkieVersion, UNK_LANG, &kEoB2EnchantedStringDOSChineseProvider },
{ kEoBBaseMenuStringsSpellNo, kEoB2, kPlatformDOS, kTalkieVersion, UNK_LANG, &kEoB2MenuStringsSpellNoDOSProvider },
{ kEoBBaseSpellLevelsMage, kEoB2, kPlatformDOS, kTalkieVersion, UNK_LANG, &kEoB2SpellLevelsMageDOSProvider },
{ kEoBBaseSpellLevelsCleric, kEoB2, kPlatformDOS, kTalkieVersion, UNK_LANG, &kEoB2SpellLevelsClericDOSProvider },
diff --git a/devtools/create_kyradat/resources/eob2_dos_chinese.h b/devtools/create_kyradat/resources/eob2_dos_chinese.h
index ab21e37060b..944d21c1337 100644
--- a/devtools/create_kyradat/resources/eob2_dos_chinese.h
+++ b/devtools/create_kyradat/resources/eob2_dos_chinese.h
@@ -181,6 +181,12 @@ static const char *const kEoB2CursedStringDOSChinese[1] = {
static const StringListProvider kEoB2CursedStringDOSChineseProvider = { ARRAYSIZE(kEoB2CursedStringDOSChinese), kEoB2CursedStringDOSChinese };
+static const char *const kEoB2EnchantedStringDOSChinese[1] = {
+ "+%d%s"
+};
+
+static const StringListProvider kEoB2EnchantedStringDOSChineseProvider = { ARRAYSIZE(kEoB2EnchantedStringDOSChinese), kEoB2EnchantedStringDOSChinese };
+
static const char *const kEoB2MagicObjectStringsDOSChinese[5] = {
"\xa7\xc5\xae\x76", /* "巫師"; */
"\xaa\xaa\xae\x76", /* "ç§å¸«"; */
@@ -192,37 +198,38 @@ static const char *const kEoB2MagicObjectStringsDOSChinese[5] = {
static const StringListProvider kEoB2MagicObjectStringsDOSChineseProvider = { ARRAYSIZE(kEoB2MagicObjectStringsDOSChinese), kEoB2MagicObjectStringsDOSChinese };
static const char *const kEoB2MagicObjectString5DOSChinese[1] = {
- "Stick"
+ "\xac\x50\xa4\xf5\xc4\x5f\xa7\xfa", /* "æç«å¯¶æ"; */
};
static const StringListProvider kEoB2MagicObjectString5DOSChineseProvider = { ARRAYSIZE(kEoB2MagicObjectString5DOSChinese), kEoB2MagicObjectString5DOSChinese };
-static const char *const kEoB2PatternSuffixDOSChinese[1] = {
- "%s of %s"
+static const char *const kEoB2PatternSuffixDOSChinese[2] = {
+ "%s""\xaa\xba""%s""\xaa""k""\xb3""N""\xb1\xb2\xb6""b", /* %sç%sæ³è¡æ²è»¸ */
+ "%s""\xaa\xba""%s" /* %sç%s */
};
static const StringListProvider kEoB2PatternSuffixDOSChineseProvider = { ARRAYSIZE(kEoB2PatternSuffixDOSChinese), kEoB2PatternSuffixDOSChinese };
static const char *const kEoB2PatternGrFix1DOSChinese[1] = {
- "%s of %s"
+ "\xa7\xc5\xae""v" /* 巫師 */
};
static const StringListProvider kEoB2PatternGrFix1DOSChineseProvider = { ARRAYSIZE(kEoB2PatternGrFix1DOSChinese), kEoB2PatternGrFix1DOSChinese };
static const char *const kEoB2PatternGrFix2DOSChinese[1] = {
- "%s of %s"
+ "\xaa\xaa\xae""v" /* ç§å¸« */
};
static const StringListProvider kEoB2PatternGrFix2DOSChineseProvider = { ARRAYSIZE(kEoB2PatternGrFix2DOSChinese), kEoB2PatternGrFix2DOSChinese };
static const char *const kEoB2ValidateArmorStringDOSChinese[1] = {
- "%s can't wear that type of armor.\r"
+ "%s""\xa4\xa3\xbe""A""\xa6""X""\xac\xef\xc0\xb9""%s.\r", /* %sä¸é©åç©¿æ´%s.\r */
};
static const StringListProvider kEoB2ValidateArmorStringDOSChineseProvider = { ARRAYSIZE(kEoB2ValidateArmorStringDOSChinese), kEoB2ValidateArmorStringDOSChinese };
static const char *const kEoB2ValidateCursedStringDOSChinese[1] = {
- "%s cannot release the weapon! It is cursed!\r"
+ "%s""\xb5""L""\xaa""k""\xa9\xf1\xb6""}""\xb3""o%s,""\xa6""]""\xac\xb0\xa5\xa6\xa4""w""\xb3""Q""\xa4""U""\xb6""A""\xa9""G""\xa4""F!\r" /* %sç¡æ³æ¾éé%s,å çºå®å·²è¢«ä¸è©åäº!\r */
};
static const StringListProvider kEoB2ValidateCursedStringDOSChineseProvider = { ARRAYSIZE(kEoB2ValidateCursedStringDOSChinese), kEoB2ValidateCursedStringDOSChinese };
@@ -247,9 +254,9 @@ static const char *const kEoB2WandStringsDOSChinese[1] = {
static const StringListProvider kEoB2WandStringsDOSChineseProvider = { ARRAYSIZE(kEoB2WandStringsDOSChinese), kEoB2WandStringsDOSChinese };
static const char *const kEoB2ItemMisuseStringsDOSChinese[3] = {
- "%s can not use this item.\r",
- "This item automatically used when worn.\r",
- "This item is not used in this way.\r"
+ "%s\xa4\xa3\xb7""|""\xa8\xcf\xa5\xce\xb3""o""\xb6\xb5\xaa\xab\xab""~.\r", /* %sä¸æä½¿ç¨éé
ç©å.\r */
+ "\xb3""o""\xaa\xab\xab""~""\xa4""w""\xb8""g""\xb3""Q""\xb8\xcb\xb0""t""\xa6""b""\xa8\xad\xa4""W""\xa8\xcf\xa5\xce\xa4""F.\r", /* éç©åå·²ç¶è¢«è£é
å¨èº«ä¸ä½¿ç¨äº.\r */
+ "\xb3""o""\xb6\xb5\xaa\xab\xab""~""\xa4\xa3\xaf\xe0\xa6""b""\xb3""o""\xb8\xcc\xa8\xcf\xa5\xce"".\r" /* éé
ç©åä¸è½å¨é裡使ç¨.\r */
};
static const StringListProvider kEoB2ItemMisuseStringsDOSChineseProvider = { ARRAYSIZE(kEoB2ItemMisuseStringsDOSChinese), kEoB2ItemMisuseStringsDOSChinese };
@@ -274,14 +281,14 @@ static const char *const kEoB2PotionEffectStringsDOSChinese[8] = {
static const StringListProvider kEoB2PotionEffectStringsDOSChineseProvider = { ARRAYSIZE(kEoB2PotionEffectStringsDOSChinese), kEoB2PotionEffectStringsDOSChinese };
static const char *const kEoB2YesNoStringsDOSChinese[2] = {
- "yes",
- "no"
+ "\xac""O ""\xaa\xba", /* æ¯ ç */
+ "\xa4\xa3"" ""\xad""n" /* ä¸ è¦ */
};
static const StringListProvider kEoB2YesNoStringsDOSChineseProvider = { ARRAYSIZE(kEoB2YesNoStringsDOSChinese), kEoB2YesNoStringsDOSChinese };
static const char *const kEoB2MoreStringsDOSChinese[1] = {
- "MORE"
+ "\xc4""~ ""\xc4\xf2" /* ç¹¼ çº */
};
static const StringListProvider kEoB2MoreStringsDOSChineseProvider = { ARRAYSIZE(kEoB2MoreStringsDOSChinese), kEoB2MoreStringsDOSChinese };
@@ -293,7 +300,7 @@ static const char *const kEoB2NpcMaxStringsDOSChinese[1] = {
static const StringListProvider kEoB2NpcMaxStringsDOSChineseProvider = { ARRAYSIZE(kEoB2NpcMaxStringsDOSChinese), kEoB2NpcMaxStringsDOSChinese };
static const char *const kEoB2OkStringsDOSChinese[1] = {
- "OK"
+ "\xa7\xb9\xb2\xa6" /* å®ç¢ */
};
static const StringListProvider kEoB2OkStringsDOSChineseProvider = { ARRAYSIZE(kEoB2OkStringsDOSChinese), kEoB2OkStringsDOSChinese };
@@ -305,13 +312,13 @@ static const char *const kEoB2NpcJoinStringsDOSChinese[1] = {
static const StringListProvider kEoB2NpcJoinStringsDOSChineseProvider = { ARRAYSIZE(kEoB2NpcJoinStringsDOSChinese), kEoB2NpcJoinStringsDOSChinese };
static const char *const kEoB2CancelStringsDOSChinese[1] = {
- "CANCEL"
+ "\xa7\xb9\xa6\xa8" /* 宿 */
};
static const StringListProvider kEoB2CancelStringsDOSChineseProvider = { ARRAYSIZE(kEoB2CancelStringsDOSChinese), kEoB2CancelStringsDOSChinese };
static const char *const kEoB2AbortStringsDOSChinese[1] = {
- "ABORT"
+ "\xa9\xf1"" ""\xb1\xf3" /* æ¾ æ£ */
};
static const StringListProvider kEoB2AbortStringsDOSChineseProvider = { ARRAYSIZE(kEoB2AbortStringsDOSChinese), kEoB2AbortStringsDOSChinese };
diff --git a/dists/engine-data/kyra.dat b/dists/engine-data/kyra.dat
index f14d95d1967..7a2a15fbebb 100644
Binary files a/dists/engine-data/kyra.dat and b/dists/engine-data/kyra.dat differ
diff --git a/engines/kyra/engine/items_eob.cpp b/engines/kyra/engine/items_eob.cpp
index 008476006a9..a2a9949a68a 100644
--- a/engines/kyra/engine/items_eob.cpp
+++ b/engines/kyra/engine/items_eob.cpp
@@ -245,7 +245,7 @@ int EoBCoreEngine::validateInventorySlotForItem(Item item, int charIndex, int sl
return 1;
if (slot == 17 && item && !itemUsableByCharacter(charIndex, item)) {
- _txt->printMessage(_validateArmorString[0], -1, _characters[charIndex].name);
+ _txt->printMessage(_validateArmorString[0], -1, _characters[charIndex].name, _itemNames[_items[item].nameUnid]);
return 0;
}
@@ -254,7 +254,7 @@ int EoBCoreEngine::validateInventorySlotForItem(Item item, int charIndex, int sl
if (_items[itm].flags & 0x20 && (_flags.gameID == GI_EOB1 || slot < 2)) {
if (_flags.gameID == GI_EOB2 && ex > 0 && ex < 4)
- _txt->printMessage(_validateCursedString[0], -1, _characters[charIndex].name);
+ _txt->printMessage(_validateCursedString[0], -1, _characters[charIndex].name, _itemNames[_items[item].nameUnid]);
return 0;
}
@@ -477,10 +477,14 @@ void EoBCoreEngine::printFullItemName(Item item) {
break;
}
-
if (tstr3) {
if (!tstr2) {
tmpString = tstr3;
+ } else if (_flags.lang == Common::ZH_TWN) {
+ if (!correctSuffixCase)
+ SWAP(tstr2, tstr3);
+ Common::String t2(tstr2);
+ tmpString = Common::String::format(_patternSuffix[t2.contains(_patternGrFix1[0]) || t2.contains(_patternGrFix2[0]) ? 0 : 1], tstr2, tstr3);
} else {
if (_flags.lang == Common::JA_JPN)
SWAP(tstr2, tstr3);
Commit: 6e9f7abc7becd04131126b36ae5639e2c2b585ac
https://github.com/scummvm/scummvm/commit/6e9f7abc7becd04131126b36ae5639e2c2b585ac
Author: athrxx (athrxx at scummvm.org)
Date: 2023-07-11T14:35:10+02:00
Commit Message:
KYRA: (EOB II/ZH) - fix dialogue buttons
I have tested only the dialgue sequences in the forest
and in the temple entrance hall, but these now look
accurate when comparing to DOSBox
Changed paths:
engines/kyra/engine/darkmoon.cpp
engines/kyra/engine/darkmoon.h
engines/kyra/engine/eobcommon.cpp
engines/kyra/engine/kyra_rpg.cpp
engines/kyra/engine/kyra_rpg.h
engines/kyra/gui/gui_rpg.cpp
engines/kyra/resource/staticres_eob.cpp
engines/kyra/resource/staticres_lol.cpp
engines/kyra/text/text_rpg.cpp
diff --git a/engines/kyra/engine/darkmoon.cpp b/engines/kyra/engine/darkmoon.cpp
index b772ccc2387..524c2c08e64 100644
--- a/engines/kyra/engine/darkmoon.cpp
+++ b/engines/kyra/engine/darkmoon.cpp
@@ -794,6 +794,8 @@ const KyraRpgGUISettings *DarkMoonEngine::guiSettings() const {
return &_guiSettingsFMTowns;
else if (_flags.platform == Common::kPlatformPC98)
return &_guiSettingsPC98;
+ else if (_flags.lang == Common::ZH_TWN)
+ return &_guiSettingsDOS_ZH;
else
return &_guiSettingsDOS;
}
diff --git a/engines/kyra/engine/darkmoon.h b/engines/kyra/engine/darkmoon.h
index 372af40ee50..d6f22666c85 100644
--- a/engines/kyra/engine/darkmoon.h
+++ b/engines/kyra/engine/darkmoon.h
@@ -149,10 +149,14 @@ private:
const char *const *_utilMenuStrings;
static const KyraRpgGUISettings _guiSettingsDOS;
+ static const KyraRpgGUISettings _guiSettingsDOS_ZH;
static const KyraRpgGUISettings _guiSettingsFMTowns;
static const KyraRpgGUISettings _guiSettingsPC98;
static const KyraRpgGUISettings _guiSettingsAmiga;
static const uint8 _egaDefaultPalette[];
+
+ static const uint16 _dlgButtonPosX_ZH[17];
+ static const uint8 _dlgButtonPosY_ZH[17];
};
} // End of namespace Kyra
diff --git a/engines/kyra/engine/eobcommon.cpp b/engines/kyra/engine/eobcommon.cpp
index 7f741d196a9..8c15d1b19a4 100644
--- a/engines/kyra/engine/eobcommon.cpp
+++ b/engines/kyra/engine/eobcommon.cpp
@@ -1574,8 +1574,16 @@ void EoBCoreEngine::setupDialogueButtons(int presetfirst, int numStr, va_list &a
_dialogueButtonPosX = &guiSettings()->buttons.posX[presetfirst];
_dialogueButtonPosY = &guiSettings()->buttons.posY[presetfirst];
- _dialogueButtonXoffs = (_flags.platform == Common::kPlatformSegaCD) ? 8 : 0;
- _dialogueButtonYoffs = (_flags.platform == Common::kPlatformSegaCD) ? 160 : yOffs;
+ _dialogueButtonXoffs = 0;
+
+ if (_flags.lang == Common::ZH_TWN) {
+ _dialogueButtonYoffs = numStr > 3 ? 166 : 184;
+ } else if (_flags.platform == Common::kPlatformSegaCD) {
+ _dialogueButtonXoffs = 8;
+ _dialogueButtonYoffs = 160;
+ } else {
+ _dialogueButtonYoffs = yOffs;
+ }
drawDialogueButtons();
diff --git a/engines/kyra/engine/kyra_rpg.cpp b/engines/kyra/engine/kyra_rpg.cpp
index 1e40a8fdc3d..54897612050 100644
--- a/engines/kyra/engine/kyra_rpg.cpp
+++ b/engines/kyra/engine/kyra_rpg.cpp
@@ -267,8 +267,13 @@ void KyraRpgEngine::drawDialogueButtons() {
screen()->set16bitShadingLevel(4);
gui_drawBox(x, (_dialogueButtonYoffs + _dialogueButtonPosY[i]), _dialogueButtonWidth, guiSettings()->buttons.height, guiSettings()->colors.frame1, guiSettings()->colors.frame2, guiSettings()->colors.fill);
screen()->set16bitShadingLevel(0);
- screen()->printText(_dialogueButtonString[i], x + (_dialogueButtonWidth >> 1) - (screen()->getTextWidth(_dialogueButtonString[i])) / 2,
- (_dialogueButtonYoffs + _dialogueButtonPosY[i]) + yOffset, _dialogueHighlightedButton == i ? _dialogueButtonLabelColor1 : _dialogueButtonLabelColor2, 0);
+ if (guiSettings()->buttons.labelShadow && _flags.gameID != GI_LOL) {
+ ((Screen_EoB*)screen())->printShadedText(_dialogueButtonString[i], x + (_dialogueButtonWidth >> 1) - (screen()->getTextWidth(_dialogueButtonString[i])) / 2,
+ (_dialogueButtonYoffs + _dialogueButtonPosY[i]) + yOffset, _dialogueHighlightedButton == i ? _dialogueButtonLabelColor1 : _dialogueButtonLabelColor2, 0, guiSettings()->colors.guiColorBlack);
+ } else {
+ screen()->printText(_dialogueButtonString[i], x + (_dialogueButtonWidth >> 1) - (screen()->getTextWidth(_dialogueButtonString[i])) / 2,
+ (_dialogueButtonYoffs + _dialogueButtonPosY[i]) + yOffset, _dialogueHighlightedButton == i ? _dialogueButtonLabelColor1 : _dialogueButtonLabelColor2, 0);
+ }
}
}
if (cs != -1)
diff --git a/engines/kyra/engine/kyra_rpg.h b/engines/kyra/engine/kyra_rpg.h
index e5482b05b49..e759ab34143 100644
--- a/engines/kyra/engine/kyra_rpg.h
+++ b/engines/kyra/engine/kyra_rpg.h
@@ -92,6 +92,7 @@ struct KyraRpgGUISettings {
const uint8 *posY;
uint8 labelColor1;
uint8 labelColor2;
+ bool labelShadow;
uint16 width;
uint16 height;
int16 txtOffsY;
diff --git a/engines/kyra/gui/gui_rpg.cpp b/engines/kyra/gui/gui_rpg.cpp
index 96a3cba6755..74351f80040 100644
--- a/engines/kyra/gui/gui_rpg.cpp
+++ b/engines/kyra/gui/gui_rpg.cpp
@@ -41,6 +41,7 @@ void KyraRpgEngine::removeInputTop() {
void KyraRpgEngine::gui_drawBox(int x, int y, int w, int h, int frameColor1, int frameColor2, int fillColor) {
w--;
h--;
+
if (fillColor != -1)
screen()->fillRect(x + 1, y + 1, x + w - 1, y + h - 1, fillColor);
diff --git a/engines/kyra/resource/staticres_eob.cpp b/engines/kyra/resource/staticres_eob.cpp
index 585e082dd6e..1c17fc6163e 100644
--- a/engines/kyra/resource/staticres_eob.cpp
+++ b/engines/kyra/resource/staticres_eob.cpp
@@ -1663,7 +1663,7 @@ void EoBEngine::initSpells() {
}
const KyraRpgGUISettings EoBEngine::_guiSettingsVGA = {
- { _dlgButtonPosX_Def, _dlgButtonPosY_Def, 9, 15, 95, 9, 2, 7, { 285, 139 }, { 189, 162 }, { 31, 31 } },
+ { _dlgButtonPosX_Def, _dlgButtonPosY_Def, 9, 15, false, 95, 9, 2, 7, { 285, 139 }, { 189, 162 }, { 31, 31 } },
{ 135, 130, 132, 180, 133, 17, 23, 20, 184, 177, 180, 184, 177, 180, 15, 6, 8, 9, 2, 5, 4, 3, 12 },
{ { 184, 256, -1}, { 2, 54, 106 }, 64, 50,
{ 8, 80, -1 }, { 11, 63, 115 }, { 181, -1, -1 }, { 3, -1, -1 },
@@ -1674,7 +1674,7 @@ const KyraRpgGUISettings EoBEngine::_guiSettingsVGA = {
};
const KyraRpgGUISettings EoBEngine::_guiSettingsEGA = {
- { _dlgButtonPosX_Def, _dlgButtonPosY_Def, 9, 15, 95, 9, 2, 7, { 285, 139 }, { 189, 162 }, { 31, 31 } },
+ { _dlgButtonPosX_Def, _dlgButtonPosY_Def, 9, 15, false, 95, 9, 2, 7, { 285, 139 }, { 189, 162 }, { 31, 31 } },
{ 13, 9, 2, 14, 2, 6, 13, 8, 13, 15, 14, 13, 15, 14, 15, 6, 8, 9, 2, 5, 4, 3, 12 },
{ { 184, 256, -1}, { 2, 54, 106 }, 64, 50,
{ 8, 80, -1 }, { 11, 63, 115 }, { 181, -1, -1 }, { 3, -1, -1 },
@@ -1685,7 +1685,7 @@ const KyraRpgGUISettings EoBEngine::_guiSettingsEGA = {
};
const KyraRpgGUISettings EoBEngine::_guiSettingsPC98 = {
- { _dlgButtonPosX_Def, _dlgButtonPosY_Def, 9, 15, 95, 11, 1, 7, { 285, 139 }, { 189, 162 }, { 31, 31 } },
+ { _dlgButtonPosX_Def, _dlgButtonPosY_Def, 9, 15, false, 95, 11, 1, 7, { 285, 139 }, { 189, 162 }, { 31, 31 } },
{ 13, 9, 2, 14, 2, 6, 13, 8, 13, 15, 14, 13, 15, 14, 15, 6, 8, 9, 2, 5, 4, 3, 12 },
{ { 184, 256, -1}, { 2, 54, 106 }, 64, 50,
{ 8, 80, -1 }, { 11, 63, 115 }, { 181, -1, -1 }, { 3, -1, -1 },
@@ -1696,7 +1696,7 @@ const KyraRpgGUISettings EoBEngine::_guiSettingsPC98 = {
};
const KyraRpgGUISettings EoBEngine::_guiSettingsAmiga = {
- { _dlgButtonPosX_Def, _dlgButtonPosY_Def, 28, 31, 95, 9, 2, 7, { 285, 139 }, { 189, 162 }, { 31, 31 } },
+ { _dlgButtonPosX_Def, _dlgButtonPosY_Def, 28, 31, false, 95, 9, 2, 7, { 285, 139 }, { 189, 162 }, { 31, 31 } },
{ 18, 17, 10, 17, 11, 24, 22, 25, 18, 9, 10, 18, 9, 10, 31, 24, 25, 28, 29, 7, 26, 27, 19 },
{ { 184, 256, -1}, { 2, 54, 106 }, 64, 50,
{ 8, 80, -1 }, { 11, 63, 115 }, { 181, -1, -1 }, { 3, -1, -1 },
@@ -1707,7 +1707,7 @@ const KyraRpgGUISettings EoBEngine::_guiSettingsAmiga = {
};
const KyraRpgGUISettings EoBEngine::_guiSettingsAmigaMainMenu = {
- { _dlgButtonPosX_Def, _dlgButtonPosY_Def, 28, 31, 95, 9, 2, 7, { 285, 139 }, { 189, 162 }, { 31, 31 } },
+ { _dlgButtonPosX_Def, _dlgButtonPosY_Def, 28, 31, false, 95, 9, 2, 7, { 285, 139 }, { 189, 162 }, { 31, 31 } },
{ 22, 28, 30, 17, 11, 24, 22, 25, 18, 9, 10, 18, 9, 10, 31, 24, 25, 28, 29, 7, 26, 27, 19 },
{ { 184, 256, -1}, { 2, 54, 106 }, 64, 50,
{ 8, 80, -1 }, { 11, 63, 115 }, { 181, -1, -1 }, { 3, -1, -1 },
@@ -1718,7 +1718,7 @@ const KyraRpgGUISettings EoBEngine::_guiSettingsAmigaMainMenu = {
};
const KyraRpgGUISettings EoBEngine::_guiSettingsSegaCD = {
- { _dlgButtonPosX_Sega, _dlgButtonPosY_Sega, 0x66, 0xFF, 90, 14, 2, 7, { 285, 139 }, { 189, 162 }, { 31, 31 } },
+ { _dlgButtonPosX_Sega, _dlgButtonPosY_Sega, 0x66, 0xFF, false, 90, 14, 2, 7, { 285, 139 }, { 189, 162 }, { 31, 31 } },
{ 135, 130, 132, 180, 0x00, 17, 23, 20, 184, 177, 180, 184, 177, 180, 15, 6, 0x31, 9, 2, 0x35, 4, 0x33, 0x3C },
{ { 184, 256, -1}, { 1, 57, 113 }, 64, 55,
{ 8, 80, -1 }, { 16, 72, 128 }, { 184, -1, -1 }, { 8, -1, -1 },
@@ -1939,7 +1939,7 @@ void DarkMoonEngine::initSpells() {
}
const KyraRpgGUISettings DarkMoonEngine::_guiSettingsFMTowns = {
- { _dlgButtonPosX_Def, _dlgButtonPosY_Def, 9, 15, 95, 11, 1, 7, { 221, 76 }, { 187, 162 }, { 95, 95 } },
+ { _dlgButtonPosX_Def, _dlgButtonPosY_Def, 9, 15, false, 95, 11, 1, 7, { 221, 76 }, { 187, 162 }, { 95, 95 } },
{ 186, 181, 183, 183, 184, 17, 23, 20, 186, 181, 183, 182, 177, 180, 15, 6, 8, 9, 2, 5, 4, 3, 12 },
{ { 184, 256, -1}, { 2, 54, 106 }, 64, 50,
{ 8, 80, -1 }, { 11, 63, 115 }, { 181, -1, -1 }, { 3, -1, -1 },
@@ -1950,7 +1950,7 @@ const KyraRpgGUISettings DarkMoonEngine::_guiSettingsFMTowns = {
};
const KyraRpgGUISettings DarkMoonEngine::_guiSettingsPC98 = {
- { _dlgButtonPosX_Def, _dlgButtonPosY_Def, 9, 15, 95, 11, 2, 7, { 221, 76 }, { 189, 162 }, { 95, 95 } },
+ { _dlgButtonPosX_Def, _dlgButtonPosY_Def, 9, 15, false, 95, 11, 2, 7, { 221, 76 }, { 189, 162 }, { 95, 95 } },
{ 186, 181, 183, 183, 184, 17, 23, 20, 186, 181, 183, 182, 177, 180, 15, 6, 8, 9, 2, 5, 4, 3, 12 },
{ { 184, 256, -1}, { 2, 54, 106 }, 64, 50,
{ 8, 80, -1 }, { 11, 63, 115 }, { 181, -1, -1 }, { 3, -1, -1 },
@@ -1961,7 +1961,18 @@ const KyraRpgGUISettings DarkMoonEngine::_guiSettingsPC98 = {
};
const KyraRpgGUISettings DarkMoonEngine::_guiSettingsDOS = {
- { _dlgButtonPosX_Def, _dlgButtonPosY_Def, 9, 15, 95, 9, 2, 7, { 221, 76 }, { 189, 162 }, { 95, 95 } },
+ { _dlgButtonPosX_Def, _dlgButtonPosY_Def, 9, 15, false, 95, 9, 2, 7, { 221, 76 }, { 189, 162 }, { 95, 95 } },
+ { 186, 181, 183, 183, 184, 17, 23, 20, 186, 181, 183, 182, 177, 180, 15, 6, 8, 9, 2, 5, 4, 3, 12 },
+ { { 184, 256, -1}, { 2, 54, 106 }, 64, 50,
+ { 8, 80, -1 }, { 11, 63, 115 }, { 181, -1, -1 }, { 3, -1, -1 },
+ { 40, 112, -1 }, { 11, 27, 63, 79, 115, 131 },
+ { 23, 95, -1}, { 46, 98, 150 }, 38, 3, { 250, 250, -1}, { 16, 25, -1 }, 51, 5,
+ 13, 30
+ }
+};
+
+const KyraRpgGUISettings DarkMoonEngine::_guiSettingsDOS_ZH = {
+ { _dlgButtonPosX_ZH, _dlgButtonPosY_ZH, 9, 15, true, 69, 16, 1, 7, { 246, 86 }, { 184, 184 }, { 69, 69 } },
{ 186, 181, 183, 183, 184, 17, 23, 20, 186, 181, 183, 182, 177, 180, 15, 6, 8, 9, 2, 5, 4, 3, 12 },
{ { 184, 256, -1}, { 2, 54, 106 }, 64, 50,
{ 8, 80, -1 }, { 11, 63, 115 }, { 181, -1, -1 }, { 3, -1, -1 },
@@ -1972,7 +1983,7 @@ const KyraRpgGUISettings DarkMoonEngine::_guiSettingsDOS = {
};
const KyraRpgGUISettings DarkMoonEngine::_guiSettingsAmiga = {
- { _dlgButtonPosX_Def, _dlgButtonPosY_Def, 28, 31, 95, 9, 2, 7, { 221, 76 }, { 189, 162 }, { 95, 95 } },
+ { _dlgButtonPosX_Def, _dlgButtonPosY_Def, 28, 31, false, 95, 9, 2, 7, { 221, 76 }, { 189, 162 }, { 95, 95 } },
{ 18, 17, 10, 17, 11, 10, 12, 25, 18, 9, 10, 18, 9, 10, 31, 24, 25, 28, 29, 7, 26, 27, 19 },
{ { 184, 256, -1}, { 2, 54, 106 }, 64, 50,
{ 8, 80, -1 }, { 11, 63, 115 }, { 181, -1, -1 }, { 3, -1, -1 },
@@ -1982,6 +1993,10 @@ const KyraRpgGUISettings DarkMoonEngine::_guiSettingsAmiga = {
}
};
+const uint16 DarkMoonEngine::_dlgButtonPosX_ZH[17] = { 62, 192, 6, 86, 166, 246, 6, 86, 166, 246, 168, 250, 32, 174, 248, 0 };
+
+const uint8 DarkMoonEngine::_dlgButtonPosY_ZH[17] = { 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 36, 36, 36, 36, 54, 54, 54 };
+
const uint8 DarkMoonEngine::_egaDefaultPalette[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
};
diff --git a/engines/kyra/resource/staticres_lol.cpp b/engines/kyra/resource/staticres_lol.cpp
index cb9244512d1..80e49f4bae0 100644
--- a/engines/kyra/resource/staticres_lol.cpp
+++ b/engines/kyra/resource/staticres_lol.cpp
@@ -805,7 +805,7 @@ const int8 LoLEngine::_mapCoords[12][4] = {
// And it is hardly worth the time to add any usage for this, since the only significant version difference would
// be the PC-98 16 color version. That said, I have filled all the unused parts of the struct with zeroes.
const KyraRpgGUISettings LoLEngine::_guiSettings = {
- { _dlgButtonPosX_Def, _dlgButtonPosY_Def, 144, 254, 74, 9, 2, 80, { 0, 0 }, { 0, 0 }, { 0, 0 } },
+ { _dlgButtonPosX_Def, _dlgButtonPosY_Def, 144, 254, false, 74, 9, 2, 80, { 0, 0 }, { 0, 0 }, { 0, 0 } },
{ 136, 251, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ { 0, 0, 0 }, { 0, 0, 0 }, 0, 0,
{ 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
@@ -816,7 +816,7 @@ const KyraRpgGUISettings LoLEngine::_guiSettings = {
};
const KyraRpgGUISettings LoLEngine::_guiSettingsZH = {
- { _dlgButtonPosX_Def, _dlgButtonPosY_Def, 144, 254, 68, 18, 2, 66, { 0, 0 }, { 0, 0 }, { 0, 0 } },
+ { _dlgButtonPosX_Def, _dlgButtonPosY_Def, 144, 254, false, 68, 18, 2, 66, { 0, 0 }, { 0, 0 }, { 0, 0 } },
{ 136, 251, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ { 0, 0, 0 }, { 0, 0, 0 }, 0, 0,
{ 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
diff --git a/engines/kyra/text/text_rpg.cpp b/engines/kyra/text/text_rpg.cpp
index f4e056a33a8..c46ca96ee94 100644
--- a/engines/kyra/text/text_rpg.cpp
+++ b/engines/kyra/text/text_rpg.cpp
@@ -126,12 +126,15 @@ void TextDisplayer_rpg::setColorMapping(int sd, uint8 from, uint8 to) {
if (sd == -1) {
for (int i = 0; i < _dimCount; ++i) {
delete[] _textDimData[i].colorMap;
- _textDimData[i].colorMap = 0;
+ _textDimData[i].colorMap = nullptr;
}
_colorMap[from] = to;
} else {
- if (_textDimData[sd].colorMap == nullptr)
+ if (_textDimData[sd].colorMap == nullptr) {
_textDimData[sd].colorMap = new uint8[256];
+ for (int i = 0; i < 256; ++i)
+ _textDimData[sd].colorMap[i] = i;
+ }
_textDimData[sd].colorMap[from] = to;
}
}
@@ -334,6 +337,11 @@ void TextDisplayer_rpg::printLine(char *str) {
int fh = _screen->getFontHeight() + _screen->_lineSpacing + _textDimData[sdx].lineSpacing;
int lines = (sd->h - _screen->_lineSpacing) / fh;
+ // Another hack for Chinese EOB II...The original prints text at the very bottom of the text field,
+ // even if there is a good risk of printing text over the dialogue buttons.
+ if (_isChinese && _allowPageBreak)
+ ++lines;
+
while (_textDimData[sdx].line >= lines) {
if ((lines - _waitButtonSpace) <= _lineCount && _allowPageBreak) {
_lineCount = 0;
@@ -656,7 +664,7 @@ void TextDisplayer_rpg::textPageBreak() {
int w = _vm->_dialogueButtonWidth;
if (_vm->game() == GI_LOL) {
- if (_vm->gameFlags().lang == Common::Language::ZH_TWN) {
+ if (_isChinese) {
y = dim->sy + dim->h - 15;
} else if (_vm->_needSceneRestore && (_vm->_updateFlags & 2)) {
if (_vm->_currentControlMode || !(_vm->_updateFlags & 2)) {
@@ -681,7 +689,10 @@ void TextDisplayer_rpg::textPageBreak() {
_screen->set16bitShadingLevel(4);
_vm->gui_drawBox(x, y, w, _vm->guiSettings()->buttons.height, _vm->guiSettings()->colors.frame1, _vm->guiSettings()->colors.frame2, _vm->guiSettings()->colors.fill);
_screen->set16bitShadingLevel(0);
- _screen->printText(_pageBreakString.c_str(), x + (w >> 1) - (_vm->screen()->getTextWidth(_pageBreakString.c_str()) >> 1), y + _vm->guiSettings()->buttons.txtOffsY, _vm->_dialogueButtonLabelColor1, 0);
+ if (_vm->guiSettings()->buttons.labelShadow && _vm->game() != GI_LOL)
+ ((Screen_EoB*)screen())->printShadedText(_pageBreakString.c_str(), x + (w >> 1) - (_vm->screen()->getTextWidth(_pageBreakString.c_str()) >> 1), y + _vm->guiSettings()->buttons.txtOffsY, _vm->_dialogueButtonLabelColor1, 0, _vm->guiSettings()->colors.guiColorBlack);
+ else
+ _screen->printText(_pageBreakString.c_str(), x + (w >> 1) - (_vm->screen()->getTextWidth(_pageBreakString.c_str()) >> 1), y + _vm->guiSettings()->buttons.txtOffsY, _vm->_dialogueButtonLabelColor1, 0);
}
_vm->removeInputTop();
@@ -731,6 +742,10 @@ void TextDisplayer_rpg::textPageBreak() {
else
_screen->fillRect(x, y, x + w - 1, y + _vm->guiSettings()->buttons.height - 1, remapColor(sdx, _textDimData[sdx].color2));
+ // Fix border overdraw glitch
+ if (_vm->game() == GI_EOB2 && _isChinese && y + _vm->guiSettings()->buttons.height == 200)
+ _screen->drawClippedLine(x, 199, x + w - 1, 199, _vm->guiSettings()->colors.frame1);
+
clearCurDim();
_screen->set16bitShadingLevel(0);
_screen->updateScreen();
@@ -784,7 +799,7 @@ void TextDisplayer_rpg::displayWaitButton() {
clearCurDim();
_screen->set16bitShadingLevel(0);
_screen->updateScreen();
- _vm->_dialogueButtonWidth = 95;
+ _vm->_dialogueButtonWidth = _vm->guiSettings()->buttons.width;
SWAP(_vm->_dialogueButtonLabelColor1, _vm->_dialogueButtonLabelColor2);
}
@@ -812,7 +827,7 @@ void TextDisplayer_rpg::convertString(char *str) {
bool TextDisplayer_rpg::isTwoByteChar(uint8 c) const {
if (_vm->gameFlags().lang == Common::JA_JPN)
return (c >= 0xE0 || (c > 0x80 && c < 0xA0));
- else if (_vm->gameFlags().lang == Common::ZH_TWN)
+ else if (_isChinese)
return (c & 0x80);
return false;
}
More information about the Scummvm-git-logs
mailing list