[Scummvm-git-logs] scummvm master -> cd502d62c41fd6680311fcce23afe2e18238477a
neuromancer
noreply at scummvm.org
Tue Mar 31 17:20:37 UTC 2026
This automated email contains information about 3 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
4b842f5fed FREESCAPE: better parsing for eclipse2 c64
a5b5303d6f FREESCAPE: allow to move diagonally pressing more than one key
cd502d62c4 FREESCAPE: implement sound in eclipse c64
Commit: 4b842f5feda15ed99578aef103ff18571553ead0
https://github.com/scummvm/scummvm/commit/4b842f5feda15ed99578aef103ff18571553ead0
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2026-03-31T19:20:23+02:00
Commit Message:
FREESCAPE: better parsing for eclipse2 c64
Changed paths:
engines/freescape/games/eclipse/c64.cpp
engines/freescape/games/eclipse/eclipse.cpp
diff --git a/engines/freescape/games/eclipse/c64.cpp b/engines/freescape/games/eclipse/c64.cpp
index cded7fcc8a8..6e969cbc0cb 100644
--- a/engines/freescape/games/eclipse/c64.cpp
+++ b/engines/freescape/games/eclipse/c64.cpp
@@ -50,11 +50,11 @@ void EclipseEngine::loadAssetsC64FullGame() {
// size should be the size of the decompressed data
Common::MemoryReadStream dfile(_extraBuffer, size, DisposeAfterUse::NO);
- loadMessagesFixedSize(&dfile, 0x1d84, 16, 30);
+ loadMessagesFixedSize(&dfile, 0x1d84, 16, isEclipse2() ? 34 : 30);
loadFonts(&dfile, 0xc3e);
load8bitBinary(&dfile, 0x9a3e, 16);
} else if (_variant & GF_C64_DISC) {
- loadMessagesFixedSize(&file, 0x1534, 16, 30);
+ loadMessagesFixedSize(&file, isEclipse2() ? 0x1538 : 0x1534, 16, isEclipse2() ? 34 : 30);
loadFonts(&file, 0x3f2);
if (isEclipse2())
load8bitBinary(&file, 0x7ac4, 16);
@@ -85,16 +85,45 @@ void EclipseEngine::loadAssetsC64FullGame() {
for (auto &it : _indicators)
it->convertToInPlace(_gfx->_texturePixelFormat);
- Common::File musicFile;
- musicFile.open("totec1.prg");
- if (musicFile.isOpen()) {
- uint16 loadAddress = musicFile.readUint16LE();
- if (loadAddress == 0x0410) {
- _c64MusicData.resize(musicFile.size() - 2);
- musicFile.read(_c64MusicData.data(), _c64MusicData.size());
+ if (isEclipse2()) {
+ // Eclipse 2 has music embedded in the game data file.
+ // Both disc and tape versions contain the same music engine and data.
+ if (_variant & GF_C64_DISC) {
+ // Disc data file starts at load address 0x0410, same as totec1.prg
+ file.close();
+ file.open("totaleclipse2.c64.data");
+ if (file.isOpen()) {
+ uint16 loadAddress = file.readUint16LE();
+ if (loadAddress == 0x0410) {
+ _c64MusicData.resize(file.size() - 2);
+ file.read(_c64MusicData.data(), _c64MusicData.size());
+ delete _playerC64Music;
+ _playerC64Music = new EclipseC64MusicPlayer(_c64MusicData);
+ }
+ }
+ } else if ((_variant & GF_C64_TAPE) && _extraBuffer) {
+ // Tape decompressed data has music at a 0x0C3F offset from disc addresses.
+ // The music player expects data indexed from load address 0x0410.
+ // Remap: musicData[i] = decompressed[i + 0x084E]
+ static const int kTapeMusicShift = 0x084E;
+ static const int kMusicRegionSize = 0x1100; // covers 0x0410..0x14FF
+ _c64MusicData.resize(kMusicRegionSize);
+ memcpy(_c64MusicData.data(), _extraBuffer + kTapeMusicShift, kMusicRegionSize);
delete _playerC64Music;
_playerC64Music = new EclipseC64MusicPlayer(_c64MusicData);
}
+ } else {
+ Common::File musicFile;
+ musicFile.open("totec1.prg");
+ if (musicFile.isOpen()) {
+ uint16 loadAddress = musicFile.readUint16LE();
+ if (loadAddress == 0x0410) {
+ _c64MusicData.resize(musicFile.size() - 2);
+ musicFile.read(_c64MusicData.data(), _c64MusicData.size());
+ delete _playerC64Music;
+ _playerC64Music = new EclipseC64MusicPlayer(_c64MusicData);
+ }
+ }
}
}
diff --git a/engines/freescape/games/eclipse/eclipse.cpp b/engines/freescape/games/eclipse/eclipse.cpp
index a5bdef6b4fa..14edb5b6b3c 100644
--- a/engines/freescape/games/eclipse/eclipse.cpp
+++ b/engines/freescape/games/eclipse/eclipse.cpp
@@ -524,8 +524,15 @@ void EclipseEngine::drawInfoMenu() {
_eventManager->purgeKeyboardEvents();
saveGameDialog();
_gfx->setViewport(_viewArea);
- } else if (isDOS() && event.customType == kActionToggleSound) {
- playSound(_soundIndexMenu, false, _soundFxHandle);
+ } else if (event.customType == kActionToggleSound) {
+ if (isC64() && _playerC64Music) {
+ if (_playerC64Music->isPlaying())
+ _playerC64Music->stopMusic();
+ else
+ _playerC64Music->startMusic();
+ } else {
+ playSound(_soundIndexMenu, false, _soundFxHandle);
+ }
} else if ((isDOS() || isCPC() || isSpectrum()) && event.customType == kActionEscape) {
_forceEndGame = true;
cont = false;
Commit: a5b5303d6fc06445016d62e6bdac9df974c9a101
https://github.com/scummvm/scummvm/commit/a5b5303d6fc06445016d62e6bdac9df974c9a101
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2026-03-31T19:20:23+02:00
Commit Message:
FREESCAPE: allow to move diagonally pressing more than one key
Changed paths:
engines/freescape/movement.cpp
diff --git a/engines/freescape/movement.cpp b/engines/freescape/movement.cpp
index a6fe607b099..1773634a6a5 100644
--- a/engines/freescape/movement.cpp
+++ b/engines/freescape/movement.cpp
@@ -486,11 +486,11 @@ void FreescapeEngine::updatePlayerMovementSmooth(float deltaTime) {
if (_moveForward)
moveDir += _cameraFront;
- else if (_moveBackward)
+ if (_moveBackward)
moveDir -= _cameraFront;
- else if (_strafeLeft)
+ if (_strafeLeft)
moveDir += _cameraRight;
- else if (_strafeRight)
+ if (_strafeRight)
moveDir -= _cameraRight;
if (_flyMode) {
Commit: cd502d62c41fd6680311fcce23afe2e18238477a
https://github.com/scummvm/scummvm/commit/cd502d62c41fd6680311fcce23afe2e18238477a
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2026-03-31T19:20:23+02:00
Commit Message:
FREESCAPE: implement sound in eclipse c64
Changed paths:
A engines/freescape/games/eclipse/c64.sfx.cpp
A engines/freescape/games/eclipse/c64.sfx.h
A engines/freescape/sid.h
engines/freescape/games/dark/c64.sfx.cpp
engines/freescape/games/dark/c64.sfx.h
engines/freescape/games/driller/c64.sfx.h
engines/freescape/games/eclipse/c64.cpp
engines/freescape/games/eclipse/eclipse.cpp
engines/freescape/games/eclipse/eclipse.h
engines/freescape/module.mk
diff --git a/engines/freescape/games/dark/c64.sfx.cpp b/engines/freescape/games/dark/c64.sfx.cpp
index 9ba591e692b..06e22df9b20 100644
--- a/engines/freescape/games/dark/c64.sfx.cpp
+++ b/engines/freescape/games/dark/c64.sfx.cpp
@@ -30,7 +30,7 @@ namespace Freescape {
// 25 SFX entries extracted from dark2.prg at $C802 (address $C802-$CBEA).
// Each entry is 40 bytes in the original 6502 format.
// See SOUND_ANALYSIS.md for full documentation.
-static const DarkSideSFXData kDarkSideSFXData[25] = {
+static const C64SFXData kC64SFXData[25] = {
// SFX #1: Shoot (Noise, highâsilence)
{2, 1, 0,
{0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -244,7 +244,7 @@ void DarkSideC64SFXPlayer::initSID() {
for (int i = 0; i < 0x19; i++)
sidWrite(i, 0);
- sidWrite(kDarkSIDVolume, 0x0F);
+ sidWrite(kSIDVolume, 0x0F);
_sid->start(new Common::Functor0Mem<void, DarkSideC64SFXPlayer>(this, &DarkSideC64SFXPlayer::onTimer), 50);
}
@@ -272,7 +272,7 @@ void DarkSideC64SFXPlayer::stopAllSfx() {
void DarkSideC64SFXPlayer::silenceV1() {
// $CE5C: zero V1 SID registers ($D400-$D406), clear state
_state = 0;
- for (int i = kDarkSIDV1FreqLo; i <= kDarkSIDV1SR; i++)
+ for (int i = kSIDV1FreqLo; i <= kSIDV1SR; i++)
sidWrite(i, 0);
}
@@ -281,7 +281,7 @@ void DarkSideC64SFXPlayer::silenceAll() {
_state = 0;
for (int i = 0; i <= 0x13; i++)
sidWrite(i, 0);
- sidWrite(kDarkSIDVolume, 0x0F);
+ sidWrite(kSIDVolume, 0x0F);
}
// Signed 32÷16 division matching the original $2122 routine.
@@ -293,7 +293,7 @@ static int16 signedDivide(int16 dividend, uint8 divisor) {
}
void DarkSideC64SFXPlayer::setupSfx(int index) {
- const DarkSideSFXData &sfx = kDarkSideSFXData[index];
+ const C64SFXData &sfx = kC64SFXData[index];
debugC(1, kFreescapeDebugMedia, "Dark Side C64 SFX: setup #%d (notes=%d repeat=%d wf=$%02X)",
index + 1, sfx.numNotes, sfx.repeatCount, sfx.waveform);
@@ -302,13 +302,13 @@ void DarkSideC64SFXPlayer::setupSfx(int index) {
silenceV1();
// Gate off
- sidWrite(kDarkSIDV1Ctrl, 0);
+ sidWrite(kSIDV1Ctrl, 0);
// Load SID registers from descriptor
- sidWrite(kDarkSIDV1PwLo, sfx.pwLo);
- sidWrite(kDarkSIDV1PwHi, sfx.pwHi);
- sidWrite(kDarkSIDV1AD, sfx.attackDecay);
- sidWrite(kDarkSIDV1SR, sfx.sustainRelease);
+ sidWrite(kSIDV1PwLo, sfx.pwLo);
+ sidWrite(kSIDV1PwHi, sfx.pwHi);
+ sidWrite(kSIDV1AD, sfx.attackDecay);
+ sidWrite(kSIDV1SR, sfx.sustainRelease);
// Store working copies
_numNotes = sfx.numNotes;
@@ -391,14 +391,14 @@ void DarkSideC64SFXPlayer::tickStart() {
uint16 freq = (uint16)_startFreqs[0];
_curFreqLo = freq & 0xFF;
_curFreqHi = (freq >> 8) & 0xFF;
- sidWrite(kDarkSIDV1FreqLo, _curFreqLo);
- sidWrite(kDarkSIDV1FreqHi, _curFreqHi);
+ sidWrite(kSIDV1FreqLo, _curFreqLo);
+ sidWrite(kSIDV1FreqHi, _curFreqHi);
// Load first duration
_durCounter = _durCopies[0];
// Gate on: waveform | 0x01
- sidWrite(kDarkSIDV1Ctrl, _waveform | 0x01);
+ sidWrite(kSIDV1Ctrl, _waveform | 0x01);
// Transition to slide state
_state = 2;
@@ -422,8 +422,8 @@ void DarkSideC64SFXPlayer::tickSlide() {
_curFreqLo = freq & 0xFF;
_curFreqHi = (freq >> 8) & 0xFF;
- sidWrite(kDarkSIDV1FreqLo, _curFreqLo);
- sidWrite(kDarkSIDV1FreqHi, _curFreqHi);
+ sidWrite(kSIDV1FreqLo, _curFreqLo);
+ sidWrite(kSIDV1FreqHi, _curFreqHi);
// Decrement duration
_durCounter--;
@@ -445,8 +445,8 @@ void DarkSideC64SFXPlayer::tickSlide() {
freq = (uint16)_startFreqs[noteIdx];
_curFreqLo = freq & 0xFF;
_curFreqHi = (freq >> 8) & 0xFF;
- sidWrite(kDarkSIDV1FreqLo, _curFreqLo);
- sidWrite(kDarkSIDV1FreqHi, _curFreqHi);
+ sidWrite(kSIDV1FreqLo, _curFreqLo);
+ sidWrite(kSIDV1FreqHi, _curFreqHi);
return;
}
@@ -463,8 +463,8 @@ void DarkSideC64SFXPlayer::tickSlide() {
freq = (uint16)_startFreqs[0];
_curFreqLo = freq & 0xFF;
_curFreqHi = (freq >> 8) & 0xFF;
- sidWrite(kDarkSIDV1FreqLo, _curFreqLo);
- sidWrite(kDarkSIDV1FreqHi, _curFreqHi);
+ sidWrite(kSIDV1FreqLo, _curFreqLo);
+ sidWrite(kSIDV1FreqHi, _curFreqHi);
_durCounter = _durCopies[0];
return;
@@ -472,7 +472,7 @@ void DarkSideC64SFXPlayer::tickSlide() {
// Sequence finished: gate off
_state = 0;
- sidWrite(kDarkSIDV1Ctrl, _waveform & 0xFE); // Clear gate bit
+ sidWrite(kSIDV1Ctrl, _waveform & 0xFE); // Clear gate bit
}
} // End of namespace Freescape
diff --git a/engines/freescape/games/dark/c64.sfx.h b/engines/freescape/games/dark/c64.sfx.h
index 58ec8fe9172..e57e1b42c7d 100644
--- a/engines/freescape/games/dark/c64.sfx.h
+++ b/engines/freescape/games/dark/c64.sfx.h
@@ -23,58 +23,10 @@
#define FREESCAPE_DARK_C64_SFX_H
#include "audio/sid.h"
+#include "freescape/sid.h"
namespace Freescape {
-// SID register offsets (shared with Driller SFX player)
-enum DarkSIDRegs {
- kDarkSIDV1FreqLo = 0x00,
- kDarkSIDV1FreqHi = 0x01,
- kDarkSIDV1PwLo = 0x02,
- kDarkSIDV1PwHi = 0x03,
- kDarkSIDV1Ctrl = 0x04,
- kDarkSIDV1AD = 0x05,
- kDarkSIDV1SR = 0x06,
-
- kDarkSIDV2FreqLo = 0x07,
- kDarkSIDV2FreqHi = 0x08,
- kDarkSIDV2PwLo = 0x09,
- kDarkSIDV2PwHi = 0x0A,
- kDarkSIDV2Ctrl = 0x0B,
- kDarkSIDV2AD = 0x0C,
- kDarkSIDV2SR = 0x0D,
-
- kDarkSIDV3FreqLo = 0x0E,
- kDarkSIDV3FreqHi = 0x0F,
- kDarkSIDV3PwLo = 0x10,
- kDarkSIDV3PwHi = 0x11,
- kDarkSIDV3Ctrl = 0x12,
- kDarkSIDV3AD = 0x13,
- kDarkSIDV3SR = 0x14,
-
- kDarkSIDFilterLo = 0x15,
- kDarkSIDFilterHi = 0x16,
- kDarkSIDFilterCtrl = 0x17,
- kDarkSIDVolume = 0x18
-};
-
-// 40-byte SFX descriptor from the data table at $C802 in dark2.prg
-struct DarkSideSFXData {
- uint8 numNotes; // Number of frequency transitions
- uint8 repeatCount; // Times to replay the full sequence
- uint8 reserved;
- uint8 freqWaypoints[20]; // Up to 10 frequency waypoints (lo,hi pairs)
- uint8 padding; // Offset 23
- uint8 durations[9]; // Duration for each transition (in speed units)
- uint8 speed; // Frames per speed unit
- uint8 padding2; // Offset 34
- uint8 pwLo; // Pulse Width low byte
- uint8 pwHi; // Pulse Width high byte
- uint8 waveform; // SID control register (gate bit managed separately)
- uint8 attackDecay; // SID Attack/Decay register
- uint8 sustainRelease; // SID Sustain/Release register
-};
-
class DarkSideC64SFXPlayer {
public:
DarkSideC64SFXPlayer();
diff --git a/engines/freescape/games/driller/c64.sfx.h b/engines/freescape/games/driller/c64.sfx.h
index e63b4201323..de66d3aa485 100644
--- a/engines/freescape/games/driller/c64.sfx.h
+++ b/engines/freescape/games/driller/c64.sfx.h
@@ -23,41 +23,10 @@
#define FREESCAPE_DRILLER_C64_SFX_H
#include "audio/sid.h"
+#include "freescape/sid.h"
namespace Freescape {
-// SID register offsets
-enum SIDRegs {
- kSIDV1FreqLo = 0x00,
- kSIDV1FreqHi = 0x01,
- kSIDV1PwLo = 0x02,
- kSIDV1PwHi = 0x03,
- kSIDV1Ctrl = 0x04,
- kSIDV1AD = 0x05,
- kSIDV1SR = 0x06,
-
- kSIDV2FreqLo = 0x07,
- kSIDV2FreqHi = 0x08,
- kSIDV2PwLo = 0x09,
- kSIDV2PwHi = 0x0A,
- kSIDV2Ctrl = 0x0B,
- kSIDV2AD = 0x0C,
- kSIDV2SR = 0x0D,
-
- kSIDV3FreqLo = 0x0E,
- kSIDV3FreqHi = 0x0F,
- kSIDV3PwLo = 0x10,
- kSIDV3PwHi = 0x11,
- kSIDV3Ctrl = 0x12,
- kSIDV3AD = 0x13,
- kSIDV3SR = 0x14,
-
- kSIDFilterLo = 0x15,
- kSIDFilterHi = 0x16,
- kSIDFilterCtrl = 0x17,
- kSIDVolume = 0x18
-};
-
class DrillerC64SFXPlayer {
public:
DrillerC64SFXPlayer();
diff --git a/engines/freescape/games/eclipse/c64.cpp b/engines/freescape/games/eclipse/c64.cpp
index 6e969cbc0cb..59e954280fb 100644
--- a/engines/freescape/games/eclipse/c64.cpp
+++ b/engines/freescape/games/eclipse/c64.cpp
@@ -23,6 +23,7 @@
#include "freescape/freescape.h"
#include "freescape/games/eclipse/c64.music.h"
+#include "freescape/games/eclipse/c64.sfx.h"
#include "freescape/games/eclipse/eclipse.h"
#include "freescape/language/8bitDetokeniser.h"
@@ -32,6 +33,24 @@ void EclipseEngine::initC64() {
_viewArea = Common::Rect(32, 32, 288, 136);
_maxEnergy = 35;
+
+ // SFX indices mapped from totec1.prg disassembly (JSR $CB4B call sites)
+ _soundIndexShoot = 1; // $5F27: opcode $16 destroy handler
+ _soundIndexCollide = 12; // $4E80/$4F50: deferred via $1549
+ _soundIndexStepDown = 12; // same as collide (matches CPC pattern)
+ _soundIndexStepUp = 12; // same as collide (matches CPC pattern)
+ _soundIndexStart = 7; // $4118: game start after title screen
+ _soundIndexAreaChange = 7; // $66CF: FCL opcode $12 area change
+ _soundIndexStartFalling = 6; // $790B: deferred via $1549
+ _soundIndexEndFalling = 8; // $792D: deferred via $1549
+ _soundIndexFall = 5; // $7C20/$7C45: death/fall animation
+ _soundIndexNoShield = 5; // game-over conditions reuse fall sound
+ _soundIndexNoEnergy = -1;
+ _soundIndexFallen = 5;
+ _soundIndexTimeout = 5;
+ _soundIndexForceEndGame = 5;
+ _soundIndexCrushed = 5;
+ _soundIndexMissionComplete = -1;
}
extern byte kC64Palette[16][3];
@@ -125,6 +144,36 @@ void EclipseEngine::loadAssetsC64FullGame() {
}
}
}
+
+ // Only one SID instance can be active at a time; music is the default.
+ // Create the inactive player first so its SID is destroyed before
+ // the active player's SID is created.
+ _playerC64Sfx = new EclipseC64SFXPlayer();
+ _playerC64Sfx->destroySID();
+}
+
+void EclipseEngine::playSoundC64(int index) {
+ debugC(1, kFreescapeDebugMedia, "Playing Eclipse C64 SFX %d", index);
+ if (_playerC64Sfx && _c64UseSFX)
+ _playerC64Sfx->playSfx(index);
+}
+
+void EclipseEngine::toggleC64Sound() {
+ if (_c64UseSFX) {
+ if (_playerC64Sfx)
+ _playerC64Sfx->destroySID();
+ if (_playerC64Music) {
+ _playerC64Music->initSID();
+ _playerC64Music->startMusic();
+ }
+ _c64UseSFX = false;
+ } else {
+ if (_playerC64Music)
+ _playerC64Music->destroySID();
+ if (_playerC64Sfx)
+ _playerC64Sfx->initSID();
+ _c64UseSFX = true;
+ }
}
diff --git a/engines/freescape/games/eclipse/c64.sfx.cpp b/engines/freescape/games/eclipse/c64.sfx.cpp
new file mode 100644
index 00000000000..e16208289af
--- /dev/null
+++ b/engines/freescape/games/eclipse/c64.sfx.cpp
@@ -0,0 +1,410 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "freescape/games/eclipse/c64.sfx.h"
+#include "freescape/freescape.h"
+
+#include "common/debug.h"
+#include "common/textconsole.h"
+
+namespace Freescape {
+
+// 21 SFX entries extracted from totec2.prg at $C802 (address $C802-$CB49).
+// Each entry is 40 bytes. Same descriptor format as Dark Side C64.
+static const C64SFXData kEclipseSFXData[21] = {
+ // SFX #1: Noise, 2 notes, repeat 1
+ {2, 1, 0,
+ {0x00, 0x44, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0,
+ {4, 0, 0, 0, 0, 0, 0, 0, 0}, 1, 0,
+ 0xEA, 0x01, 0x80, 0x15, 0x30},
+
+ // SFX #2: Pulse, 4 notes, repeat 1
+ {4, 1, 0,
+ {0x00, 0x24, 0x00, 0x84, 0x00, 0x28, 0x00, 0x80, 0x00, 0x24,
+ 0x00, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0,
+ {2, 2, 2, 6, 1, 0, 0, 0, 0}, 1, 0,
+ 0xEA, 0x06, 0x40, 0x19, 0x13},
+
+ // SFX #3: Sawtooth, 2 notes, repeat 1
+ {2, 1, 0,
+ {0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0,
+ {8, 0, 0, 0, 0, 0, 0, 0, 0}, 1, 0,
+ 0x9E, 0x02, 0x20, 0x0C, 0x04},
+
+ // SFX #4: Triangle, 2 notes, repeat 1
+ {2, 1, 0,
+ {0x00, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0,
+ {55, 0, 0, 0, 0, 0, 0, 0, 0}, 1, 0,
+ 0xA0, 0x00, 0x10, 0x1E, 0x11},
+
+ // SFX #5: Noise, 2 notes, repeat 1
+ {2, 1, 0,
+ {0x00, 0x88, 0x00, 0x00, 0x00, 0x34, 0x00, 0x14, 0x00, 0x30,
+ 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0,
+ {28, 9, 4, 13, 14, 0, 0, 0, 0}, 1, 0,
+ 0x3A, 0x0D, 0x80, 0x19, 0x10},
+
+ // SFX #6: Triangle, 2 notes, repeat 1
+ {2, 1, 0,
+ {0x00, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0,
+ {55, 0, 0, 0, 0, 0, 0, 0, 0}, 1, 0,
+ 0xA0, 0x00, 0x10, 0x1E, 0x11},
+
+ // SFX #7: Pulse, 3 notes, repeat 4
+ {3, 4, 0,
+ {0x00, 0x00, 0x00, 0x2C, 0x00, 0x24, 0x00, 0x28, 0x00, 0x58,
+ 0x00, 0x68, 0x00, 0x6C, 0x00, 0x64, 0x00, 0x54, 0x00, 0x3C}, 0,
+ {3, 1, 7, 7, 4, 5, 14, 8, 3}, 1, 0,
+ 0x62, 0x07, 0x40, 0x6B, 0xD4},
+
+ // SFX #8: Noise, 7 notes, repeat 1
+ {7, 1, 0,
+ {0x00, 0x00, 0x00, 0x04, 0x00, 0x10, 0x00, 0x30, 0x00, 0x50,
+ 0x00, 0xA0, 0x00, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0,
+ {9, 12, 11, 5, 4, 2, 0, 0, 0}, 1, 0,
+ 0x80, 0x02, 0x80, 0x35, 0xF9},
+
+ // SFX #9: Triangle, 2 notes, repeat 5
+ {2, 5, 0,
+ {0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0,
+ {6, 0, 0, 0, 0, 0, 0, 0, 0}, 2, 0,
+ 0xD0, 0x02, 0x10, 0x19, 0xF7},
+
+ // SFX #10: Noise, 3 notes, repeat 1
+ {3, 1, 0,
+ {0x00, 0x1C, 0x00, 0x00, 0x00, 0x18, 0x00, 0x7C, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0,
+ {4, 7, 2, 21, 0, 0, 0, 0, 0}, 1, 0,
+ 0x38, 0x0F, 0x80, 0x38, 0xFC},
+
+ // SFX #11: Triangle, 4 notes, repeat 1
+ {4, 1, 0,
+ {0x00, 0x90, 0x00, 0xC0, 0x00, 0x4C, 0x00, 0x4C, 0x00, 0x54,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0,
+ {7, 10, 6, 8, 0, 0, 0, 0, 0}, 1, 0,
+ 0xC8, 0x00, 0x10, 0x32, 0xF4},
+
+ // SFX #12: Noise, 3 notes, repeat 1
+ {3, 1, 0,
+ {0x00, 0xD4, 0x00, 0x00, 0x00, 0xD4, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0,
+ {4, 5, 0, 0, 0, 0, 0, 0, 0}, 1, 0,
+ 0xA2, 0x03, 0x80, 0x2A, 0x32},
+
+ // SFX #13: Triangle, 4 notes, repeat 3
+ {4, 3, 0,
+ {0x00, 0xAC, 0x00, 0x84, 0x00, 0xAC, 0x00, 0x84, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0,
+ {4, 2, 5, 0, 0, 0, 0, 0, 0}, 1, 0,
+ 0xAA, 0x05, 0x10, 0x16, 0xF8},
+
+ // SFX #14: Sawtooth, 2 notes, repeat 5
+ {2, 5, 0,
+ {0x00, 0x34, 0x00, 0x4C, 0x00, 0x50, 0x00, 0x44, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0,
+ {7, 4, 4, 0, 0, 0, 0, 0, 0}, 1, 0,
+ 0x90, 0x01, 0x20, 0x33, 0xFA},
+
+ // SFX #15: Noise, 3 notes, repeat 1
+ {3, 1, 0,
+ {0x00, 0xB8, 0x00, 0xD4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0,
+ {8, 7, 0, 0, 0, 0, 0, 0, 0}, 1, 0,
+ 0xEA, 0x06, 0x80, 0x15, 0xF7},
+
+ // SFX #16: Sawtooth, 5 notes, repeat 1
+ {5, 1, 0,
+ {0x00, 0x14, 0x00, 0x50, 0x00, 0x98, 0x00, 0xC4, 0x00, 0x94,
+ 0x00, 0xC0, 0x00, 0x34, 0x00, 0x74, 0x00, 0x48, 0x00, 0x88}, 0,
+ {24, 15, 6, 6, 18, 4, 4, 5, 2}, 1, 3,
+ 0xEA, 0x0B, 0x20, 0x32, 0xF8},
+
+ // SFX #17: Sawtooth, 2 notes, repeat 1
+ {2, 1, 0,
+ {0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0,
+ {25, 7, 0, 0, 0, 0, 0, 0, 0}, 4, 0,
+ 0x06, 0x04, 0x20, 0x65, 0xF0},
+
+ // SFX #18: Noise, 3 notes, repeat 1
+ {3, 1, 0,
+ {0x00, 0x0C, 0x00, 0x0C, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0,
+ {2, 6, 0, 0, 0, 0, 0, 0, 0}, 1, 0,
+ 0xB2, 0x02, 0x80, 0x29, 0x11},
+
+ // SFX #19: Pulse, 4 notes, repeat 1
+ {4, 1, 0,
+ {0x00, 0x08, 0x00, 0x08, 0x00, 0x28, 0x00, 0x60, 0x00, 0x68,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0,
+ {8, 18, 9, 0, 0, 0, 0, 0, 0}, 2, 0,
+ 0xEE, 0x02, 0x40, 0x4A, 0x11},
+
+ // SFX #20: Pulse, 4 notes, repeat 1
+ {4, 1, 0,
+ {0x00, 0x00, 0x00, 0x18, 0x00, 0x50, 0x00, 0x94, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0,
+ {21, 11, 8, 5, 0, 0, 0, 0, 0}, 2, 0,
+ 0x72, 0x06, 0x40, 0x35, 0xF4},
+
+ // SFX #21: Noise, 2 notes, repeat 1
+ {2, 1, 0,
+ {0x00, 0x4C, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0,
+ {15, 0, 0, 0, 0, 0, 0, 0, 0}, 1, 0,
+ 0x20, 0x0E, 0x80, 0x26, 0x00},
+};
+
+static int16 signedDivide(int16 dividend, uint8 divisor) {
+ if (divisor == 0)
+ return 0;
+ return dividend / (int16)divisor;
+}
+
+EclipseC64SFXPlayer::EclipseC64SFXPlayer()
+ : _sid(nullptr),
+ _state(0),
+ _numNotes(0), _repeatCount(0), _waveform(0), _speed(1),
+ _repeatLeft(0), _notesLeft(0), _freqIndex(0), _durIndex(0),
+ _durCounter(0), _speedCounter(0),
+ _curFreqLo(0), _curFreqHi(0) {
+ memset(_startFreqs, 0, sizeof(_startFreqs));
+ memset(_deltas, 0, sizeof(_deltas));
+ memset(_durCopies, 0, sizeof(_durCopies));
+}
+
+EclipseC64SFXPlayer::~EclipseC64SFXPlayer() {
+ destroySID();
+}
+
+void EclipseC64SFXPlayer::destroySID() {
+ if (_sid) {
+ _sid->stop();
+ delete _sid;
+ _sid = nullptr;
+ }
+}
+
+void EclipseC64SFXPlayer::initSID() {
+ if (_sid) {
+ _sid->stop();
+ delete _sid;
+ }
+
+ _sid = SID::Config::create(SID::Config::kSidPAL);
+ if (!_sid || !_sid->init())
+ error("Failed to initialise SID emulator for Eclipse SFX");
+
+ for (int i = 0; i < 0x19; i++)
+ sidWrite(i, 0);
+ sidWrite(kSIDVolume, 0x0F);
+
+ _sid->start(new Common::Functor0Mem<void, EclipseC64SFXPlayer>(this, &EclipseC64SFXPlayer::onTimer), 50);
+}
+
+void EclipseC64SFXPlayer::sidWrite(int reg, uint8 data) {
+ if (_sid) {
+ debugC(4, kFreescapeDebugMedia, "Eclipse SFX SID Write: Reg $%02X = $%02X", reg, data);
+ _sid->writeReg(reg, data);
+ }
+}
+
+void EclipseC64SFXPlayer::onTimer() {
+ sfxTick();
+}
+
+bool EclipseC64SFXPlayer::isSfxActive() const {
+ return _state != 0;
+}
+
+void EclipseC64SFXPlayer::stopAllSfx() {
+ _state = 0;
+ silenceAll();
+}
+
+void EclipseC64SFXPlayer::silenceV1() {
+ _state = 0;
+ for (int i = kSIDV1FreqLo; i <= kSIDV1SR; i++)
+ sidWrite(i, 0);
+}
+
+void EclipseC64SFXPlayer::silenceAll() {
+ _state = 0;
+ for (int i = 0; i <= 0x13; i++)
+ sidWrite(i, 0);
+ sidWrite(kSIDVolume, 0x0F);
+}
+
+void EclipseC64SFXPlayer::setupSfx(int index) {
+ const C64SFXData &sfx = kEclipseSFXData[index];
+
+ debugC(1, kFreescapeDebugMedia, "Eclipse C64 SFX: setup #%d (notes=%d repeat=%d wf=$%02X)",
+ index + 1, sfx.numNotes, sfx.repeatCount, sfx.waveform);
+
+ silenceV1();
+
+ sidWrite(kSIDV1Ctrl, 0);
+ sidWrite(kSIDV1PwLo, sfx.pwLo);
+ sidWrite(kSIDV1PwHi, sfx.pwHi);
+ sidWrite(kSIDV1AD, sfx.attackDecay);
+ sidWrite(kSIDV1SR, sfx.sustainRelease);
+
+ _numNotes = sfx.numNotes;
+ _repeatCount = sfx.repeatCount;
+ _waveform = sfx.waveform;
+ _speed = sfx.speed;
+
+ int numTransitions = sfx.numNotes;
+ for (int i = 0; i < numTransitions && i < 9; i++) {
+ uint16 freqStart = sfx.freqWaypoints[i * 2] | (sfx.freqWaypoints[i * 2 + 1] << 8);
+ uint16 freqEnd = sfx.freqWaypoints[(i + 1) * 2] | (sfx.freqWaypoints[(i + 1) * 2 + 1] << 8);
+
+ _startFreqs[i] = (int16)freqStart;
+
+ int16 diff = (int16)(freqEnd - freqStart);
+ _deltas[i] = signedDivide(diff, sfx.durations[i]);
+
+ _durCopies[i] = sfx.durations[i];
+
+ debugC(2, kFreescapeDebugMedia, " Note %d: freq $%04X->$%04X dur=%d delta=%d",
+ i, freqStart, freqEnd, sfx.durations[i], _deltas[i]);
+ }
+
+ _state = 1;
+}
+
+void EclipseC64SFXPlayer::playSfx(int sfxIndex) {
+ if (sfxIndex < 1 || sfxIndex > 21) {
+ debugC(1, kFreescapeDebugMedia, "Eclipse C64 SFX: invalid index %d", sfxIndex);
+ return;
+ }
+
+ if (_state != 0) {
+ debugC(2, kFreescapeDebugMedia, "Eclipse C64 SFX: busy, dropping #%d", sfxIndex);
+ return;
+ }
+
+ setupSfx(sfxIndex - 1);
+}
+
+void EclipseC64SFXPlayer::sfxTick() {
+ if (_state == 0)
+ return;
+
+ if (_state == 1) {
+ tickStart();
+ return;
+ }
+
+ if (_state == 2) {
+ tickSlide();
+ return;
+ }
+
+ _state = 0;
+}
+
+void EclipseC64SFXPlayer::tickStart() {
+ _repeatLeft = _repeatCount;
+
+ _notesLeft = _numNotes - 1;
+ _freqIndex = 0;
+ _durIndex = 0;
+
+ _speedCounter = _speed;
+
+ uint16 freq = (uint16)_startFreqs[0];
+ _curFreqLo = freq & 0xFF;
+ _curFreqHi = (freq >> 8) & 0xFF;
+ sidWrite(kSIDV1FreqLo, _curFreqLo);
+ sidWrite(kSIDV1FreqHi, _curFreqHi);
+
+ _durCounter = _durCopies[0];
+
+ sidWrite(kSIDV1Ctrl, _waveform | 0x01);
+
+ _state = 2;
+}
+
+void EclipseC64SFXPlayer::tickSlide() {
+ _speedCounter--;
+ if (_speedCounter != 0)
+ return;
+
+ _speedCounter = _speed;
+
+ int noteIdx = _freqIndex / 2;
+ uint16 freq = (_curFreqHi << 8) | _curFreqLo;
+ freq = (uint16)((int16)freq + _deltas[noteIdx]);
+ _curFreqLo = freq & 0xFF;
+ _curFreqHi = (freq >> 8) & 0xFF;
+
+ sidWrite(kSIDV1FreqLo, _curFreqLo);
+ sidWrite(kSIDV1FreqHi, _curFreqHi);
+
+ _durCounter--;
+ if (_durCounter != 0)
+ return;
+
+ _freqIndex += 2;
+ _durIndex++;
+ _notesLeft--;
+
+ if (_notesLeft != 0) {
+ noteIdx = _freqIndex / 2;
+ _durCounter = _durCopies[_durIndex];
+ _speedCounter = _speed;
+
+ freq = (uint16)_startFreqs[noteIdx];
+ _curFreqLo = freq & 0xFF;
+ _curFreqHi = (freq >> 8) & 0xFF;
+ sidWrite(kSIDV1FreqLo, _curFreqLo);
+ sidWrite(kSIDV1FreqHi, _curFreqHi);
+ return;
+ }
+
+ _repeatLeft--;
+ if (_repeatLeft != 0) {
+ _notesLeft = _numNotes - 1;
+ _freqIndex = 0;
+ _durIndex = 0;
+ _speedCounter = _speed;
+
+ freq = (uint16)_startFreqs[0];
+ _curFreqLo = freq & 0xFF;
+ _curFreqHi = (freq >> 8) & 0xFF;
+ sidWrite(kSIDV1FreqLo, _curFreqLo);
+ sidWrite(kSIDV1FreqHi, _curFreqHi);
+
+ _durCounter = _durCopies[0];
+ return;
+ }
+
+ _state = 0;
+ sidWrite(kSIDV1Ctrl, _waveform & 0xFE);
+}
+
+} // End of namespace Freescape
diff --git a/engines/freescape/games/eclipse/c64.sfx.h b/engines/freescape/games/eclipse/c64.sfx.h
new file mode 100644
index 00000000000..24cb414ed20
--- /dev/null
+++ b/engines/freescape/games/eclipse/c64.sfx.h
@@ -0,0 +1,79 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef FREESCAPE_ECLIPSE_C64_SFX_H
+#define FREESCAPE_ECLIPSE_C64_SFX_H
+
+#include "audio/sid.h"
+#include "freescape/sid.h"
+
+namespace Freescape {
+
+class EclipseC64SFXPlayer {
+public:
+ EclipseC64SFXPlayer();
+ ~EclipseC64SFXPlayer();
+
+ void playSfx(int sfxIndex);
+ void sfxTick();
+ void stopAllSfx();
+
+ bool isSfxActive() const;
+ void initSID();
+ void destroySID();
+
+private:
+ SID::SID *_sid;
+
+ void sidWrite(int reg, uint8 data);
+ void onTimer();
+
+ uint8 _state;
+
+ uint8 _numNotes;
+ uint8 _repeatCount;
+ uint8 _waveform;
+ uint8 _speed;
+
+ uint8 _repeatLeft;
+ uint8 _notesLeft;
+ uint8 _freqIndex;
+ uint8 _durIndex;
+ uint8 _durCounter;
+ uint8 _speedCounter;
+
+ uint8 _curFreqLo;
+ uint8 _curFreqHi;
+
+ int16 _startFreqs[16];
+ int16 _deltas[16];
+ uint8 _durCopies[9];
+
+ void silenceV1();
+ void silenceAll();
+ void setupSfx(int index);
+ void tickStart();
+ void tickSlide();
+};
+
+} // namespace Freescape
+
+#endif // FREESCAPE_ECLIPSE_C64_SFX_H
diff --git a/engines/freescape/games/eclipse/eclipse.cpp b/engines/freescape/games/eclipse/eclipse.cpp
index 14edb5b6b3c..7bebd6313b4 100644
--- a/engines/freescape/games/eclipse/eclipse.cpp
+++ b/engines/freescape/games/eclipse/eclipse.cpp
@@ -31,6 +31,7 @@
#include "freescape/freescape.h"
#include "freescape/games/eclipse/c64.music.h"
+#include "freescape/games/eclipse/c64.sfx.h"
#include "freescape/games/eclipse/eclipse.h"
#include "freescape/language/8bitDetokeniser.h"
@@ -42,6 +43,8 @@ Audio::AudioStream *makeEclipseAtariMusicStream(const byte *data, uint32 dataSiz
EclipseEngine::EclipseEngine(OSystem *syst, const ADGameDescription *gd) : FreescapeEngine(syst, gd) {
_playerC64Music = nullptr;
+ _playerC64Sfx = nullptr;
+ _c64UseSFX = false;
// These sounds can be overriden by the class of each platform
_soundIndexStartFalling = -1;
@@ -104,6 +107,7 @@ EclipseEngine::EclipseEngine(OSystem *syst, const ADGameDescription *gd) : Frees
EclipseEngine::~EclipseEngine() {
delete _playerC64Music;
+ delete _playerC64Sfx;
}
void EclipseEngine::initGameState() {
@@ -525,11 +529,9 @@ void EclipseEngine::drawInfoMenu() {
saveGameDialog();
_gfx->setViewport(_viewArea);
} else if (event.customType == kActionToggleSound) {
- if (isC64() && _playerC64Music) {
- if (_playerC64Music->isPlaying())
- _playerC64Music->stopMusic();
- else
- _playerC64Music->startMusic();
+ if (isC64() && _playerC64Sfx) {
+ toggleC64Sound();
+ _eventManager->purgeKeyboardEvents();
} else {
playSound(_soundIndexMenu, false, _soundFxHandle);
}
diff --git a/engines/freescape/games/eclipse/eclipse.h b/engines/freescape/games/eclipse/eclipse.h
index 5a4296bf8ee..32f0317f8a6 100644
--- a/engines/freescape/games/eclipse/eclipse.h
+++ b/engines/freescape/games/eclipse/eclipse.h
@@ -26,6 +26,7 @@
namespace Freescape {
class EclipseC64MusicPlayer;
+class EclipseC64SFXPlayer;
enum EclipseReleaseFlags {
GF_ZX_DEMO_CRASH = (1 << 0),
@@ -115,6 +116,10 @@ public:
Common::Array<byte> _musicData; // TEMUSIC.ST TEXT segment (Atari ST)
Common::Array<byte> _c64MusicData;
EclipseC64MusicPlayer *_playerC64Music;
+ EclipseC64SFXPlayer *_playerC64Sfx;
+ bool _c64UseSFX;
+ void playSoundC64(int index) override;
+ void toggleC64Sound();
// Atari ST UI sprites (extracted from binary, pre-converted to target format)
Font _fontScore; // Font B (10 score digit glyphs, 4-plane at $249BE)
diff --git a/engines/freescape/module.mk b/engines/freescape/module.mk
index 914af1a0015..7e671a7d4b7 100644
--- a/engines/freescape/module.mk
+++ b/engines/freescape/module.mk
@@ -37,6 +37,7 @@ MODULE_OBJS := \
games/eclipse/atari.music.o \
games/eclipse/c64.o \
games/eclipse/c64.music.o \
+ games/eclipse/c64.sfx.o \
games/eclipse/dos.o \
games/eclipse/eclipse.o \
games/eclipse/cpc.o \
diff --git a/engines/freescape/sid.h b/engines/freescape/sid.h
new file mode 100644
index 00000000000..faa6acf29b5
--- /dev/null
+++ b/engines/freescape/sid.h
@@ -0,0 +1,81 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef FREESCAPE_SID_H
+#define FREESCAPE_SID_H
+
+#include "common/scummsys.h"
+
+namespace Freescape {
+
+// SID register offsets (matches C64 $D400-$D418)
+enum SIDRegs {
+ kSIDV1FreqLo = 0x00,
+ kSIDV1FreqHi = 0x01,
+ kSIDV1PwLo = 0x02,
+ kSIDV1PwHi = 0x03,
+ kSIDV1Ctrl = 0x04,
+ kSIDV1AD = 0x05,
+ kSIDV1SR = 0x06,
+
+ kSIDV2FreqLo = 0x07,
+ kSIDV2FreqHi = 0x08,
+ kSIDV2PwLo = 0x09,
+ kSIDV2PwHi = 0x0A,
+ kSIDV2Ctrl = 0x0B,
+ kSIDV2AD = 0x0C,
+ kSIDV2SR = 0x0D,
+
+ kSIDV3FreqLo = 0x0E,
+ kSIDV3FreqHi = 0x0F,
+ kSIDV3PwLo = 0x10,
+ kSIDV3PwHi = 0x11,
+ kSIDV3Ctrl = 0x12,
+ kSIDV3AD = 0x13,
+ kSIDV3SR = 0x14,
+
+ kSIDFilterLo = 0x15,
+ kSIDFilterHi = 0x16,
+ kSIDFilterCtrl = 0x17,
+ kSIDVolume = 0x18
+};
+
+// 40-byte SFX descriptor used by the Wally Beben C64 SFX engine
+// (shared by Dark Side, Total Eclipse, and possibly other Freescape titles).
+struct C64SFXData {
+ uint8 numNotes;
+ uint8 repeatCount;
+ uint8 reserved;
+ uint8 freqWaypoints[20];
+ uint8 padding;
+ uint8 durations[9];
+ uint8 speed;
+ uint8 padding2;
+ uint8 pwLo;
+ uint8 pwHi;
+ uint8 waveform;
+ uint8 attackDecay;
+ uint8 sustainRelease;
+};
+
+} // namespace Freescape
+
+#endif // FREESCAPE_SID_H
More information about the Scummvm-git-logs
mailing list