aboutsummaryrefslogtreecommitdiff
path: root/engines/agi
diff options
context:
space:
mode:
Diffstat (limited to 'engines/agi')
-rw-r--r--engines/agi/agi.cpp78
-rw-r--r--engines/agi/agi.h120
-rw-r--r--engines/agi/detection.cpp227
-rw-r--r--engines/agi/graphics.cpp258
-rw-r--r--engines/agi/graphics.h10
-rw-r--r--engines/agi/keyboard.cpp8
-rw-r--r--engines/agi/menu.cpp8
-rw-r--r--engines/agi/predictive.cpp17
-rw-r--r--engines/agi/saveload.cpp26
-rw-r--r--engines/agi/sound.cpp180
-rw-r--r--engines/agi/text.cpp4
11 files changed, 745 insertions, 191 deletions
diff --git a/engines/agi/agi.cpp b/engines/agi/agi.cpp
index 0839b7de99..1c1c53dee7 100644
--- a/engines/agi/agi.cpp
+++ b/engines/agi/agi.cpp
@@ -178,7 +178,7 @@ void AgiEngine::processEvents() {
case Common::KEYCODE_MINUS:
key = '-';
break;
- case Common::KEYCODE_9:
+ case Common::KEYCODE_TAB:
key = 0x0009;
break;
case Common::KEYCODE_F1:
@@ -448,6 +448,12 @@ int AgiEngine::agiInit() {
loadGame(saveNameBuffer, false); // Do not check game id
}
+#ifdef __DS__
+ // Normally, the engine loads the predictive text dictionary when the predictive dialog
+ // is shown. On the DS version, the word completion feature needs the dictionary too.
+ loadDict();
+#endif
+
return ec;
}
@@ -535,6 +541,67 @@ static const GameSettings agiSettings[] = {
{NULL, NULL, 0, 0, NULL}
};
+AgiTextColor AgiButtonStyle::getColor(bool hasFocus, bool pressed, bool positive) const {
+ if (_amigaStyle) {
+ if (positive) {
+ if (pressed) { // Positive pressed Amiga-style button
+ if (_olderAgi) {
+ return AgiTextColor(amigaBlack, amigaOrange);
+ } else {
+ return AgiTextColor(amigaBlack, amigaPurple);
+ }
+ } else { // Positive unpressed Amiga-style button
+ return AgiTextColor(amigaWhite, amigaGreen);
+ }
+ } else { // _amigaStyle && !positive
+ if (pressed) { // Negative pressed Amiga-style button
+ return AgiTextColor(amigaBlack, amigaCyan);
+ } else { // Negative unpressed Amiga-style button
+ return AgiTextColor(amigaWhite, amigaRed);
+ }
+ }
+ } else { // PC-style button
+ if (hasFocus || pressed) { // A pressed or in focus PC-style button
+ return AgiTextColor(pcWhite, pcBlack);
+ } else { // An unpressed PC-style button without focus
+ return AgiTextColor(pcBlack, pcWhite);
+ }
+ }
+}
+
+AgiTextColor AgiButtonStyle::getColor(bool hasFocus, bool pressed, int baseFgColor, int baseBgColor) const {
+ return getColor(hasFocus, pressed, AgiTextColor(baseFgColor, baseBgColor));
+}
+
+AgiTextColor AgiButtonStyle::getColor(bool hasFocus, bool pressed, const AgiTextColor &baseColor) const {
+ if (hasFocus || pressed)
+ return baseColor.swap();
+ else
+ return baseColor;
+}
+
+int AgiButtonStyle::getTextOffset(bool hasFocus, bool pressed) const {
+ return (pressed && !_amigaStyle) ? 1 : 0;
+}
+
+bool AgiButtonStyle::getBorder(bool hasFocus, bool pressed) const {
+ return _amigaStyle && !_authenticAmiga && (hasFocus || pressed);
+}
+
+void AgiButtonStyle::setAmigaStyle(bool amigaStyle, bool olderAgi, bool authenticAmiga) {
+ _amigaStyle = amigaStyle;
+ _olderAgi = olderAgi;
+ _authenticAmiga = authenticAmiga;
+}
+
+void AgiButtonStyle::setPcStyle(bool pcStyle) {
+ setAmigaStyle(!pcStyle);
+}
+
+AgiButtonStyle::AgiButtonStyle(Common::RenderMode renderMode) {
+ setAmigaStyle(renderMode == Common::kRenderAmiga);
+}
+
AgiEngine::AgiEngine(OSystem *syst) : Engine(syst) {
// Setup mixer
@@ -635,6 +702,8 @@ void AgiEngine::initialize() {
}
}
+ _buttonStyle = AgiButtonStyle(_renderMode);
+ _defaultButtonStyle = AgiButtonStyle();
_console = new Console(this);
_gfx = new GfxMgr(this);
_sound = new SoundMgr(this, _mixer);
@@ -676,6 +745,13 @@ void AgiEngine::initialize() {
}
AgiEngine::~AgiEngine() {
+ // If the engine hasn't been initialized yet via AgiEngine::initialize(), don't attempt to free any resources,
+ // as they haven't been allocated. Fixes bug #1742432 - AGI: Engine crashes if no game is detected
+ if (_game.state == STATE_INIT) {
+ delete _rnd; // delete _rnd, as it is allocated in the constructor, not in initialize()
+ return;
+ }
+
agiDeinit();
_sound->deinitSound();
delete _sound;
diff --git a/engines/agi/agi.h b/engines/agi/agi.h
index 01db2acb23..f37b61478e 100644
--- a/engines/agi/agi.h
+++ b/engines/agi/agi.h
@@ -81,6 +81,7 @@ typedef signed int Err;
#define MSG_BOX_COLOUR 0x0f /* White */
#define MSG_BOX_TEXT 0x00 /* Black */
#define MSG_BOX_LINE 0x04 /* Red */
+#define BUTTON_BORDER 0x00 /* Black */
#define STATUS_FG 0x00 /* Black */
#define STATUS_BG 0x0f /* White */
@@ -110,7 +111,9 @@ enum AgiGameFeatures {
GF_AGI256_2 = (1 << 3),
GF_AGIPAL = (1 << 4),
GF_MACGOLDRUSH = (1 << 5),
- GF_FANMADE = (1 << 6)
+ GF_FANMADE = (1 << 6),
+ GF_MENUS = (1 << 7),
+ GF_ESCPAUSE = (1 << 8)
};
enum AgiGameID {
@@ -153,6 +156,7 @@ enum AGIErrors {
errNoLoopsInView,
errViewDataError,
errNoGameList,
+ errIOError,
errUnk = 127
};
@@ -317,6 +321,118 @@ struct AgiBlock {
uint8 *buffer; /* used for window background */
};
+/** AGI text color (Background and foreground color). */
+struct AgiTextColor {
+ /** Creates an AGI text color. Uses black text on white background by default. */
+ AgiTextColor(int fgColor = 0x00, int bgColor = 0x0F) : fg(fgColor), bg(bgColor) {}
+
+ /** Get an AGI text color with swapped foreground and background color. */
+ AgiTextColor swap() const { return AgiTextColor(bg, fg); }
+
+ int fg; ///< Foreground color (Used for text).
+ int bg; ///< Background color (Used for text's background).
+};
+
+/**
+ * AGI button style (Amiga or PC).
+ *
+ * Supports positive and negative button types (Used with Amiga-style only):
+ * Positive buttons do what the dialog was opened for.
+ * Negative buttons cancel what the dialog was opened for.
+ * Restart-dialog example: Restart-button is positive, Cancel-button negative.
+ * Paused-dialog example: Continue-button is positive.
+ */
+struct AgiButtonStyle {
+// Public constants etc
+public:
+ static const int
+ // Amiga colors (Indexes into the Amiga-ish palette)
+ amigaBlack = 0x00, ///< Accurate, is #000000 (24-bit RGB)
+ amigaWhite = 0x0F, ///< Practically accurate, is close to #FFFFFF (24-bit RGB)
+ amigaGreen = 0x02, ///< Quite accurate, should be #008A00 (24-bit RGB)
+ amigaOrange = 0x0C, ///< Inaccurate, too much blue, should be #FF7500 (24-bit RGB)
+ amigaPurple = 0x0D, ///< Inaccurate, too much green, should be #FF00FF (24-bit RGB)
+ amigaRed = 0x04, ///< Quite accurate, should be #BD0000 (24-bit RGB)
+ amigaCyan = 0x0B, ///< Inaccurate, too much red, should be #00FFDE (24-bit RGB)
+ // PC colors (Indexes into the EGA-palette)
+ pcBlack = 0x00,
+ pcWhite = 0x0F;
+
+// Public methods
+public:
+ /**
+ * Get the color of the button with the given state and type using current style.
+ *
+ * @param hasFocus True if button has focus, false otherwise.
+ * @param pressed True if button is being pressed, false otherwise.
+ * @param positive True if button is positive, false if button is negative. Only matters for Amiga-style buttons.
+ */
+ AgiTextColor getColor(bool hasFocus, bool pressed, bool positive = true) const;
+
+ /**
+ * Get the color of a button with the given base color and state ignoring current style.
+ * Swaps foreground and background color when the button has focus or is being pressed.
+ *
+ * @param hasFocus True if button has focus, false otherwise.
+ * @param pressed True if button is being pressed, false otherwise.
+ * @param baseFgColor Foreground color of the button when it has no focus and is not being pressed.
+ * @param baseBgColor Background color of the button when it has no focus and is not being pressed.
+ */
+ AgiTextColor getColor(bool hasFocus, bool pressed, int baseFgColor, int baseBgColor) const;
+
+ /**
+ * Get the color of a button with the given base color and state ignoring current style.
+ * Swaps foreground and background color when the button has focus or is being pressed.
+ *
+ * @param hasFocus True if button has focus, false otherwise.
+ * @param pressed True if button is being pressed, false otherwise.
+ * @param baseColor Color of the button when it has no focus and is not being pressed.
+ */
+ AgiTextColor getColor(bool hasFocus, bool pressed, const AgiTextColor &baseColor) const;
+
+ /**
+ * How many pixels to offset the shown text diagonally down and to the right.
+ * Currently only used for pressed PC-style buttons.
+ */
+ int getTextOffset(bool hasFocus, bool pressed) const;
+
+ /**
+ * Show border around the button?
+ * Currently border is only used for in focus or pressed Amiga-style buttons
+ * when in inauthentic Amiga-style mode.
+ */
+ bool getBorder(bool hasFocus, bool pressed) const;
+
+ /**
+ * Set Amiga-button style.
+ *
+ * @param amigaStyle Set Amiga-button style if true, otherwise set PC-button style.
+ * @param olderAgi If true then use older AGI style in Amiga-mode, otherwise use newer.
+ * @param authenticAmiga If true then don't use a border around buttons in Amiga-mode, otherwise use.
+ */
+ void setAmigaStyle(bool amigaStyle = true, bool olderAgi = false, bool authenticAmiga = false);
+
+ /**
+ * Set PC-button style.
+ * @param pcStyle Set PC-button style if true, otherwise set default Amiga-button style.
+ */
+ void setPcStyle(bool pcStyle = true);
+
+// Public constructors
+public:
+ /**
+ * Create a button style based on the given rendering mode.
+ * @param renderMode If Common::kRenderAmiga then creates default Amiga-button style, otherwise PC-style.
+ */
+ AgiButtonStyle(Common::RenderMode renderMode = Common::kRenderDefault);
+
+// Private member variables
+private:
+ bool _amigaStyle; ///< Use Amiga-style buttons if true, otherwise use PC-style buttons.
+ bool _olderAgi; ///< Use older AGI style in Amiga-style mode.
+ bool _authenticAmiga; ///< Don't use border around buttons in Amiga-style mode.
+};
+
#define EGO_VIEW_TABLE 0
#define HORIZON 36
#define _WIDTH 160
@@ -594,6 +710,8 @@ public:
int _oldMode;
Menu* _menu;
+ AgiButtonStyle _buttonStyle;
+ AgiButtonStyle _defaultButtonStyle;
char _lastSentence[40];
diff --git a/engines/agi/detection.cpp b/engines/agi/detection.cpp
index 1ab59c0806..79e3be3238 100644
--- a/engines/agi/detection.cpp
+++ b/engines/agi/detection.cpp
@@ -125,7 +125,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == AGI Demo 1 (PC) 05/87 [AGI 2.425]
+ // AGI Demo 1 (PC) 05/87 [AGI 2.425]
{
"agidemo",
"Demo 1 1987-05-20",
@@ -142,7 +142,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == AGI Demo 2 (IIgs) 1.0C (Censored)
+ // AGI Demo 2 (IIgs) 1.0C (Censored)
{
"agidemo",
"Demo 2 1987-11-24 1.0C",
@@ -159,7 +159,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == AGI Demo 2 (PC 3.5") 11/87 [AGI 2.915]
+ // AGI Demo 2 (PC 3.5") 11/87 [AGI 2.915]
{
"agidemo",
"Demo 2 1987-11-24 3.5\"",
@@ -176,7 +176,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == AGI Demo 2 (PC 5.25") 11/87 [v1] [AGI 2.915]
+ // AGI Demo 2 (PC 5.25") 11/87 [v1] [AGI 2.915]
{
"agidemo",
"Demo 2 1987-11-24 [version 1] 5.25\"",
@@ -193,7 +193,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == AGI Demo 2 (PC 5.25") 01/88 [v2] [AGI 2.917]
+ // AGI Demo 2 (PC 5.25") 01/88 [v2] [AGI 2.917]
{
"agidemo",
"Demo 2 1988-01-25 [version 2] 5.25\"",
@@ -210,7 +210,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == AGI Demo 3 (PC) 09/88 [AGI 3.002.102]
+ // AGI Demo 3 (PC) 09/88 [AGI 3.002.102]
{
"agidemo",
"Demo 3 1988-09-13",
@@ -227,7 +227,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == Black Cauldron (Amiga) 2.00 6/14/87
+ // Black Cauldron (Amiga) 2.00 6/14/87
{
"bc",
"2.00 1987-06-14",
@@ -244,7 +244,8 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == Black Cauldron (Apple IIgs) 1.0O 2/24/89 (CE)
+ // Black Cauldron (Apple IIgs) 1.0O 2/24/89 (CE)
+ // Menus not tested
{
"bc",
"1.0O 1989-02-24 (CE)",
@@ -261,7 +262,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == Black Cauldron (PC) 2.00 6/14/87 [AGI 2.439]
+ // Black Cauldron (PC) 2.00 6/14/87 [AGI 2.439]
{
"bc",
"2.00 1987-06-14",
@@ -278,7 +279,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == Black Cauldron (PC 5.25") 2.10 11/10/88 [AGI 3.002.098]
+ // Black Cauldron (PC 5.25") 2.10 11/10/88 [AGI 3.002.098]
{
"bc",
"2.10 1988-11-10 5.25\"",
@@ -297,7 +298,8 @@ static const AGIGameDescription gameDescriptions[] = {
// These aren't supposed to work now as they require unsupported agi engine 2.01
#if 0
{
- // Sarien Name == Donald Duck's Playground (Amiga) 1.0C
+ // Donald Duck's Playground (Amiga) 1.0C
+ // Menus not tested
{
"ddp",
"1.0C 1987-04-27",
@@ -314,7 +316,8 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == Donald Duck's Playground (ST) 1.0A 8/8/86
+ // Donald Duck's Playground (ST) 1.0A 8/8/86
+ // Menus not tested
{
"ddp",
"1.0A 1986-08-08",
@@ -332,6 +335,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
// reported by Filippos (thebluegr) in bugreport #1654500
+ // Menus not tested
{
"ddp",
"1.0C 1986-06-09", // verify date
@@ -348,7 +352,7 @@ static const AGIGameDescription gameDescriptions[] = {
#endif
{
- // Sarien Name == Gold Rush! (Amiga) 1.01 1/13/89 aka 2.05 3/9/89 # 2.316
+ // Gold Rush! (Amiga) 1.01 1/13/89 aka 2.05 3/9/89 # 2.316
{
"goldrush",
"1.01 1989-01-13 aka 2.05 1989-03-09",
@@ -365,7 +369,8 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == Gold Rush! (Apple IIgs) 1.0M 2/28/89 (CE) aka 2.01 12/22/88
+ // Gold Rush! (Apple IIgs) 1.0M 2/28/89 (CE) aka 2.01 12/22/88
+ // Menus not tested
{
"goldrush",
"1.0M 1989-02-28 (CE) aka 2.01 1988-12-22",
@@ -382,7 +387,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == Gold Rush! (ST) 1.01 1/13/89 aka 2.01 12/22/88
+ // Gold Rush! (ST) 1.01 1/13/89 aka 2.01 12/22/88
{
"goldrush",
"1.01 1989-01-13 aka 2.01 1988-12-22",
@@ -399,7 +404,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == Gold Rush! (PC 5.25") 2.01 12/22/88 [AGI 3.002.149]
+ // Gold Rush! (PC 5.25") 2.01 12/22/88 [AGI 3.002.149]
{
"goldrush",
"2.01 1988-12-22 5.25\"",
@@ -416,7 +421,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == Gold Rush! (PC 3.5") 2.01 12/22/88 [AGI 3.002.149]
+ // Gold Rush! (PC 3.5") 2.01 12/22/88 [AGI 3.002.149]
{
"goldrush",
"2.01 1988-12-22 3.5\"",
@@ -433,7 +438,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == Gold Rush! (PC 5.25") 2.01 12/22/88 [AGI 3.002.149]
+ // Gold Rush! (PC 5.25") 2.01 12/22/88 [AGI 3.002.149]
{
"goldrush",
"2.01 1988-12-22",
@@ -454,7 +459,8 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == King's Quest 1 (Amiga) 1.0U # 2.082
+ // King's Quest 1 (Amiga) 1.0U # 2.082
+ // The original game did not have menus, they are enabled under ScummVM
{
"kq1",
"1.0U 1986",
@@ -465,13 +471,14 @@ static const AGIGameDescription gameDescriptions[] = {
},
GID_KQ1,
GType_V2,
- 0,
+ GF_MENUS,
0x2440,
},
{
- // Sarien Name == King's Quest 1 (ST) 1.0V
+ // King's Quest 1 (ST) 1.0V
+ // The original game did not have menus, they are enabled under ScummVM
{
"kq1",
"1.0V 1986",
@@ -482,13 +489,14 @@ static const AGIGameDescription gameDescriptions[] = {
},
GID_KQ1,
GType_V2,
- 0,
+ GF_MENUS,
0x2272,
},
{
- // Sarien Name == King's Quest 1 (IIgs) 1.0S-88223
+ // King's Quest 1 (IIgs) 1.0S-88223
+ // Menus not tested
{
"kq1",
"1.0S 1988-02-23",
@@ -505,7 +513,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == King's Quest 1 (Mac) 2.0C
+ // King's Quest 1 (Mac) 2.0C
{
"kq1",
"2.0C 1987-03-26",
@@ -522,7 +530,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == King's Quest 1 (PC 5.25"/3.5") 2.0F [AGI 2.917]
+ // King's Quest 1 (PC 5.25"/3.5") 2.0F [AGI 2.917]
{
"kq1",
"2.0F 1987-05-05 5.25\"/3.5\"",
@@ -539,7 +547,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == King's Quest 2 (IIgs) 2.0A 6/16/88 (CE)
+ // King's Quest 2 (IIgs) 2.0A 6/16/88 (CE)
{
"kq2",
"2.0A 1988-06-16 (CE)",
@@ -556,7 +564,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == King's Quest 2 (Amiga) 2.0J (Broken)
+ // King's Quest 2 (Amiga) 2.0J (Broken)
{
"kq2",
"2.0J 1987-01-29 [OBJECT decrypted]",
@@ -573,7 +581,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == King's Quest 2 (Mac) 2.0R
+ // King's Quest 2 (Mac) 2.0R
{
"kq2",
"2.0R 1988-03-23",
@@ -607,7 +615,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == King's Quest 2 (PC 5.25"/3.5") 2.2 [AGI 2.426]
+ // King's Quest 2 (PC 5.25"/3.5") 2.2 [AGI 2.426]
{
"kq2",
"2.2 1987-05-07 5.25\"/3.5\"",
@@ -624,7 +632,8 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == King's Quest 3 (Amiga) 1.01 11/8/86
+ // King's Quest 3 (Amiga) 1.01 11/8/86
+ // The original game did not have menus, they are enabled under ScummVM
{
"kq3",
"1.01 1986-11-08",
@@ -635,13 +644,14 @@ static const AGIGameDescription gameDescriptions[] = {
},
GID_KQ3,
GType_V2,
- 0,
+ GF_MENUS,
0x2440,
},
{
- // Sarien Name == King's Quest 3 (ST) 1.02 11/18/86
+ // King's Quest 3 (ST) 1.02 11/18/86
+ // Does not have menus, crashes if menus are enforced. Therefore, ESC pauses the game
{
"kq3",
"1.02 1986-11-18",
@@ -652,13 +662,13 @@ static const AGIGameDescription gameDescriptions[] = {
},
GID_KQ3,
GType_V2,
- 0,
+ GF_ESCPAUSE,
0x2272,
},
{
- // Sarien Name == King's Quest 3 (Mac) 2.14 3/15/88
+ // King's Quest 3 (Mac) 2.14 3/15/88
{
"kq3",
"2.14 1988-03-15",
@@ -675,7 +685,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == King's Quest 3 (IIgs) 2.0A 8/28/88 (CE)
+ // King's Quest 3 (IIgs) 2.0A 8/28/88 (CE)
{
"kq3",
"2.0A 1988-08-28 (CE)",
@@ -692,7 +702,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == King's Quest 3 (Amiga) 2.15 11/15/89 # 2.333
+ // King's Quest 3 (Amiga) 2.15 11/15/89 # 2.333
{
"kq3",
"2.15 1989-11-15",
@@ -709,7 +719,8 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == King's Quest 3 (PC) 1.01 11/08/86 [AGI 2.272]
+ // King's Quest 3 (PC) 1.01 11/08/86 [AGI 2.272]
+ // Does not have menus, crashes if menus are enforced. Therefore, ESC pauses the game
{
"kq3",
"1.01 1986-11-08",
@@ -720,13 +731,13 @@ static const AGIGameDescription gameDescriptions[] = {
},
GID_KQ3,
GType_V2,
- 0,
+ GF_ESCPAUSE,
0x2272,
},
{
- // Sarien Name == King's Quest 3 (PC 5.25") 2.00 5/25/87 [AGI 2.435]
+ // King's Quest 3 (PC 5.25") 2.00 5/25/87 [AGI 2.435]
{
"kq3",
"2.00 1987-05-25 5.25\"",
@@ -743,7 +754,8 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == King's Quest 3 (Mac) 2.14 3/15/88
+ // King's Quest 3 (Mac) 2.14 3/15/88
+ // Menus not tested
{
"kq3",
"2.14 1988-03-15 5.25\"",
@@ -760,7 +772,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == King's Quest 3 (PC 3.5") 2.14 3/15/88 [AGI 2.936]
+ // King's Quest 3 (PC 3.5") 2.14 3/15/88 [AGI 2.936]
{
"kq3",
"2.14 1988-03-15 3.5\"",
@@ -777,7 +789,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == King's Quest 4 (PC 5.25") 2.3 9/27/88 [AGI 3.002.086]
+ // King's Quest 4 (PC 5.25") 2.3 9/27/88 [AGI 3.002.086]
{
"kq4",
"2.3 1988-09-27",
@@ -794,7 +806,8 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == King's Quest 4 (IIgs) 1.0K 11/22/88 (CE)
+ // King's Quest 4 (IIgs) 1.0K 11/22/88 (CE)
+ // Menus not tested
{
"kq4",
"1.0K 1988-11-22",
@@ -811,7 +824,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == King's Quest 4 (PC 3.5") 2.0 7/27/88 [AGI 3.002.086]
+ // King's Quest 4 (PC 3.5") 2.0 7/27/88 [AGI 3.002.086]
{
"kq4",
"2.0 1988-07-27 3.5\"",
@@ -828,7 +841,8 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == King's Quest 4 (PC 3.5") 2.2 9/27/88 [AGI 3.002.086]
+ // King's Quest 4 (PC 3.5") 2.2 9/27/88 [AGI 3.002.086]
+ // Menus not tested
{
"kq4",
"2.2 1988-09-27 3.5\"",
@@ -845,7 +859,8 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == King's Quest 4 demo (PC) [AGI 3.002.102]
+ // King's Quest 4 demo (PC) [AGI 3.002.102]
+ // Menus not tested
{
"kq4",
"Demo 1988-12-20",
@@ -862,7 +877,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == Leisure Suit Larry 1 (PC 5.25"/3.5") 1.00 6/1/87 [AGI 2.440]
+ // Leisure Suit Larry 1 (PC 5.25"/3.5") 1.00 6/1/87 [AGI 2.440]
{
"lsl1",
"1.00 1987-06-01 5.25\"/3.5\"",
@@ -879,7 +894,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == Leisure Suit Larry 1 (ST) 1.04 6/18/87
+ // Leisure Suit Larry 1 (ST) 1.04 6/18/87
{
"lsl1",
"1.04 1987-06-18",
@@ -896,7 +911,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == Leisure Suit Larry 1 (Amiga) 1.05 6/26/87 # x.yyy
+ // Leisure Suit Larry 1 (Amiga) 1.05 6/26/87 # x.yyy
{
"lsl1",
"1.05 1987-06-26",
@@ -913,7 +928,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == Leisure Suit Larry 1 (IIgs) 1.0E
+ // Leisure Suit Larry 1 (IIgs) 1.0E
{
"lsl1",
"1.0E 1987",
@@ -930,7 +945,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == Leisure Suit Larry 1 (Mac) 1.05 6/26/87
+ // Leisure Suit Larry 1 (Mac) 1.05 6/26/87
{
"lsl1",
"1.05 1987-06-26",
@@ -947,7 +962,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == Manhunter NY (ST) 1.03 10/20/88
+ // Manhunter NY (ST) 1.03 10/20/88
{
"mh1",
"1.03 1988-10-20",
@@ -964,7 +979,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == Manhunter NY (IIgs) 2.0E 10/05/88 (CE)
+ // Manhunter NY (IIgs) 2.0E 10/05/88 (CE)
{
"mh1",
"2.0E 1988-10-05 (CE)",
@@ -981,7 +996,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == Manhunter NY (Amiga) 1.06 3/18/89
+ // Manhunter NY (Amiga) 1.06 3/18/89
{
"mh1",
"1.06 1989-03-18",
@@ -999,7 +1014,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
// reported by Filippos (thebluegr) in bugreport #1654500
- // Sarien Name == Manhunter NY (PC 5.25") 1.22 8/31/88 [AGI 3.002.107]
+ // Manhunter NY (PC 5.25") 1.22 8/31/88 [AGI 3.002.107]
{
"mh1",
"1.22 1988-08-31",
@@ -1016,7 +1031,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == Manhunter NY (PC 3.5") 1.22 8/31/88 [AGI 3.002.102]
+ // Manhunter NY (PC 3.5") 1.22 8/31/88 [AGI 3.002.102]
{
"mh1",
"1.22 1988-08-31",
@@ -1033,7 +1048,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == Manhunter SF (ST) 1.0 7/29/89
+ // Manhunter SF (ST) 1.0 7/29/89
{
"mh2",
"1.0 1989-07-29",
@@ -1050,7 +1065,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == Manhunter SF (Amiga) 3.06 8/17/89 # 2.333
+ // Manhunter SF (Amiga) 3.06 8/17/89 # 2.333
{
"mh2",
"3.06 1989-08-17",
@@ -1067,7 +1082,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == Manhunter SF (PC 5.25") 3.03 8/17/89 [AGI 3.002.149]
+ // Manhunter SF (PC 5.25") 3.03 8/17/89 [AGI 3.002.149]
{
"mh2",
"3.03 1989-08-17 5.25\"",
@@ -1084,7 +1099,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == Manhunter SF (PC 3.5") 3.02 7/26/89 [AGI 3.002.149]
+ // Manhunter SF (PC 3.5") 3.02 7/26/89 [AGI 3.002.149]
{
"mh2",
"3.02 1989-07-26 3.5\"",
@@ -1099,9 +1114,11 @@ static const AGIGameDescription gameDescriptions[] = {
0x3149,
},
-
+#if 0
{
- // Sarien Name == Mixed-Up Mother Goose (Amiga) 1.1
+ // Mixed-Up Mother Goose (Amiga) 1.1
+ // Problematic: crashes
+ // Menus not tested
{
"mixedup",
"1.1 1986-12-10",
@@ -1115,10 +1132,10 @@ static const AGIGameDescription gameDescriptions[] = {
0,
0x3086,
},
-
+#endif
{
- // Sarien Name == Mixed Up Mother Goose (IIgs)
+ // Mixed Up Mother Goose (IIgs)
{
"mixedup",
"1987",
@@ -1135,7 +1152,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == Mixed-Up Mother Goose (PC) [AGI 2.915]
+ // Mixed-Up Mother Goose (PC) [AGI 2.915]
{
"mixedup",
"1987-11-10",
@@ -1153,7 +1170,8 @@ static const AGIGameDescription gameDescriptions[] = {
#if 0
{
- // Sarien Name == Mixed Up Mother Goose (PC) [AGI 2.915] (Broken)
+ // Mixed Up Mother Goose (PC) [AGI 2.915] (Broken)
+ // Menus not tested
{
"mixedup",
"[corrupt/OBJECT from disk 1]",
@@ -1171,7 +1189,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == Police Quest 1 (PC) 2.0E 11/17/87 [AGI 2.915]
+ // Police Quest 1 (PC) 2.0E 11/17/87 [AGI 2.915]
{
"pq1",
"2.0E 1987-11-17",
@@ -1188,7 +1206,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == Police Quest 1 (Mac) 2.0G 12/3/87
+ // Police Quest 1 (Mac) 2.0G 12/3/87
{
"pq1",
"2.0G 1987-12-03",
@@ -1205,7 +1223,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == Police Quest 1 (IIgs) 2.0B-88421
+ // Police Quest 1 (IIgs) 2.0B-88421
{
"pq1",
"2.0B 1988-04-21",
@@ -1222,7 +1240,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == Police Quest 1 (Amiga) 2.0B 2/22/89 # 2.310
+ // Police Quest 1 (Amiga) 2.0B 2/22/89 # 2.310
{
"pq1",
"2.0B 1989-02-22",
@@ -1239,7 +1257,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == Police Quest 1 (IIgs) 2.0A-88318
+ // Police Quest 1 (IIgs) 2.0A-88318
{
"pq1",
"2.0A 1988-03-18",
@@ -1256,7 +1274,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == Police Quest 1 (PC) 2.0A 10/23/87 [AGI 2.903/2.911]
+ // Police Quest 1 (PC) 2.0A 10/23/87 [AGI 2.903/2.911]
{
"pq1",
"2.0A 1987-10-23",
@@ -1273,7 +1291,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == Police Quest 1 (Mac) 2.0G 12/3/87
+ // Police Quest 1 (Mac) 2.0G 12/3/87
{
"pq1",
"2.0G 1987-12-03 5.25\"/ST",
@@ -1307,7 +1325,8 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == Space Quest 1 (ST) 1.1A
+ // Space Quest 1 (ST) 1.1A
+ // The original game did not have menus, they are enabled under ScummVM
{
"sq1",
"1.1A 1986-02-06",
@@ -1318,13 +1337,14 @@ static const AGIGameDescription gameDescriptions[] = {
},
GID_SQ1,
GType_V2,
- 0,
+ GF_MENUS,
0x2440,
},
{
- // Sarien Name == Space Quest 1 (PC) 1.1A [AGI 2.272]
+ // Space Quest 1 (PC) 1.1A [AGI 2.272]
+ // The original game did not have menus, they are enabled under ScummVM
{
"sq1",
"1.1A 1986-11-13",
@@ -1335,13 +1355,14 @@ static const AGIGameDescription gameDescriptions[] = {
},
GID_SQ1,
GType_V2,
- 0,
+ GF_MENUS,
0x2272,
},
{
- // Sarien Name == Space Quest 1 (Amiga) 1.2 # 2.082
+ // Space Quest 1 (Amiga) 1.2 # 2.082
+ // The original game did not have menus, they are enabled under ScummVM
{
"sq1",
"1.2 1986",
@@ -1352,13 +1373,13 @@ static const AGIGameDescription gameDescriptions[] = {
},
GID_SQ1,
GType_V2,
- 0,
+ GF_MENUS,
0x2440,
},
{
- // Sarien Name == Space Quest 1 (Mac) 1.5D
+ // Space Quest 1 (Mac) 1.5D
{
"sq1",
"1.5D 1987-04-02",
@@ -1375,7 +1396,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == Space Quest 1 (IIgs) 2.2
+ // Space Quest 1 (IIgs) 2.2
{
"sq1",
"2.2 1987",
@@ -1392,7 +1413,8 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == Space Quest 1 (PC) 1.0X [AGI 2.089]
+ // Space Quest 1 (PC) 1.0X [AGI 2.089]
+ // Does not have menus, crashes if menus are enforced. Therefore, ESC pauses the game
{
"sq1",
"1.0X 1986-09-24",
@@ -1403,30 +1425,14 @@ static const AGIGameDescription gameDescriptions[] = {
},
GID_SQ1,
GType_V2,
- 0,
+ GF_ESCPAUSE,
0x2089,
},
- {
- // Sarien Name == Space Quest 1 (PC) 1.1A [AGI 2.272]
- {
- "sq1",
- "1.1A 1986-11-13",
- AD_ENTRY1("logdir", "8d8c20ab9f4b6e4817698637174a1cb6"),
- Common::EN_ANY,
- Common::kPlatformPC,
- Common::ADGF_NO_FLAGS
- },
- GID_SQ1,
- GType_V2,
- 0,
- 0x2272,
- },
-
{
- // Sarien Name == Space Quest 1 (PC 5.25"/3.5") 2.2 [AGI 2.426/2.917]
+ // Space Quest 1 (PC 5.25"/3.5") 2.2 [AGI 2.426/2.917]
{
"sq1",
"2.2 1987-05-07 5.25\"/3.5\"",
@@ -1444,7 +1450,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == Space Quest 2 (PC 3.5") 2.0D [AGI 2.936]
+ // Space Quest 2 (PC 3.5") 2.0D [AGI 2.936]
{
"sq2",
"2.0D 1988-03-14 3.5\"",
@@ -1461,7 +1467,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == Space Quest 2 (IIgs) 2.0A 7/25/88 (CE)
+ // Space Quest 2 (IIgs) 2.0A 7/25/88 (CE)
{
"sq2",
"2.0A 1988-07-25 (CE)",
@@ -1478,7 +1484,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == Space Quest 2 (Amiga) 2.0F
+ // Space Quest 2 (Amiga) 2.0F
{
"sq2",
"2.0F 1986-12-09 [VOL.2->PICTURE.16 broken]",
@@ -1499,7 +1505,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == Space Quest 2 (Mac) 2.0D
+ // Space Quest 2 (Mac) 2.0D
{
"sq2",
"2.0D 1988-04-04",
@@ -1517,7 +1523,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
// reported by Filippos (thebluegr) in bugreport #1654500
- // Sarien Name == Space Quest 2 (PC 5.25") 2.0A [AGI 2.912]
+ // Space Quest 2 (PC 5.25") 2.0A [AGI 2.912]
{
"sq2",
"2.0A 1987-11-06 5.25\"",
@@ -1534,7 +1540,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == Space Quest 2 (PC 3.5") 2.0A [AGI 2.912]
+ // Space Quest 2 (PC 3.5") 2.0A [AGI 2.912]
{
"sq2",
"2.0A 1987-11-06 3.5\"",
@@ -1551,7 +1557,8 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == Space Quest 2 (PC 5.25"/ST) 2.0C/A [AGI 2.915]
+ // Space Quest 2 (PC 5.25"/ST) 2.0C/A [AGI 2.915]
+ // Menus not tested
{
"sq2",
"2.0C/A 5.25\"/ST",
@@ -1568,7 +1575,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == Space Quest 2 (PC 3.5") 2.0F [AGI 2.936]
+ // Space Quest 2 (PC 3.5") 2.0F [AGI 2.936]
{
"sq2",
"2.0F 1989-01-05 3.5\"",
@@ -1585,7 +1592,7 @@ static const AGIGameDescription gameDescriptions[] = {
{
- // Sarien Name == Xmas Card 1986 (PC) [AGI 2.272]
+ // Xmas Card 1986 (PC) [AGI 2.272]
{
"xmascard",
"1986-11-13 [version 1]",
@@ -1675,7 +1682,7 @@ static const AGIGameDescription gameDescriptions[] = {
FANMADE("Good Man (demo v3.41)", "3facd8a8f856b7b6e0f6c3200274d88c"),
{
- // Sarien Name == Groza
+ // Groza
{
"agi-fanmade",
"Groza (russian) [AGDS sample]",
diff --git a/engines/agi/graphics.cpp b/engines/agi/graphics.cpp
index 54f1783d83..b6430e0f81 100644
--- a/engines/agi/graphics.cpp
+++ b/engines/agi/graphics.cpp
@@ -68,6 +68,158 @@ uint8 egaPalette[16 * 3] = {
};
/**
+ * Atari ST AGI palette.
+ * Used by all of the tested Atari ST AGI games
+ * from Donald Duck's Playground (1986) to Manhunter II (1989).
+ * 16 RGB colors. 3 bits per color component.
+ */
+uint8 atariStAgiPalette[16 * 3] = {
+ 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x7,
+ 0x0, 0x4, 0x0,
+ 0x0, 0x5, 0x4,
+ 0x5, 0x0, 0x0,
+ 0x5, 0x3, 0x6,
+ 0x4, 0x3, 0x0,
+ 0x5, 0x5, 0x5,
+ 0x3, 0x3, 0x2,
+ 0x0, 0x5, 0x7,
+ 0x0, 0x6, 0x0,
+ 0x0, 0x7, 0x6,
+ 0x7, 0x2, 0x3,
+ 0x7, 0x4, 0x7,
+ 0x7, 0x7, 0x4,
+ 0x7, 0x7, 0x7
+};
+
+/**
+ * Second generation Apple IIGS AGI palette.
+ * A 16-color, 12-bit RGB palette.
+ *
+ * Used by at least the following Apple IIGS AGI versions:
+ * 1.003 (Leisure Suit Larry I v1.0E, intro says 1987)
+ * 1.005 (AGI Demo 2 1987-06-30?)
+ * 1.006 (King's Quest I v1.0S 1988-02-23)
+ * 1.007 (Police Quest I v2.0B 1988-04-21 8:00am)
+ * 1.013 (King's Quest II v2.0A 1988-06-16 (CE))
+ * 1.013 (Mixed-Up Mother Goose v2.0A 1988-05-31 10:00am)
+ * 1.014 (King's Quest III v2.0A 1988-08-28 (CE))
+ * 1.014 (Space Quest II v2.0A, LOGIC.141 says 1988)
+ * 2.004 (Manhunter I v2.0E 1988-10-05 (CE))
+ * 2.006 (King's Quest IV v1.0K 1988-11-22 (CE))
+ * 3.001 (Black Cauldron v1.0O 1989-02-24 (CE))
+ * 3.003 (Gold Rush! v1.0M 1989-02-28 (CE))
+ */
+uint8 appleIIgsAgiPaletteV2[16 * 3] = {
+ 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0xF,
+ 0x0, 0x8, 0x0,
+ 0x0, 0xD, 0xB,
+ 0xC, 0x0, 0x0,
+ 0xB, 0x7, 0xD,
+ 0x8, 0x5, 0x0,
+ 0xB, 0xB, 0xB,
+ 0x7, 0x7, 0x7,
+ 0x0, 0xB, 0xF,
+ 0x0, 0xE, 0x0,
+ 0x0, 0xF, 0xD,
+ 0xF, 0x9, 0x8,
+ 0xD, 0x9, 0xF, // Only this differs from the 1st generation palette
+ 0xE, 0xE, 0x0,
+ 0xF, 0xF, 0xF
+};
+
+/**
+ * First generation Amiga & Apple IIGS AGI palette.
+ * A 16-color, 12-bit RGB palette.
+ *
+ * Used by at least the following Amiga AGI versions:
+ * 2.082 (King's Quest I v1.0U 1986)
+ * 2.082 (Space Quest I v1.2 1986)
+ * 2.090 (King's Quest III v1.01 1986-11-08)
+ * 2.107 (King's Quest II v2.0J 1987-01-29)
+ * x.yyy (Black Cauldron v2.00 1987-06-14)
+ * x.yyy (Larry I v1.05 1987-06-26)
+ *
+ * Also used by at least the following Apple IIGS AGI versions:
+ * 1.002 (Space Quest I, intro says v2.2 1987)
+ */
+uint8 amigaAgiPaletteV1[16 * 3] = {
+ 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0xF,
+ 0x0, 0x8, 0x0,
+ 0x0, 0xD, 0xB,
+ 0xC, 0x0, 0x0,
+ 0xB, 0x7, 0xD,
+ 0x8, 0x5, 0x0,
+ 0xB, 0xB, 0xB,
+ 0x7, 0x7, 0x7,
+ 0x0, 0xB, 0xF,
+ 0x0, 0xE, 0x0,
+ 0x0, 0xF, 0xD,
+ 0xF, 0x9, 0x8,
+ 0xF, 0x7, 0x0,
+ 0xE, 0xE, 0x0,
+ 0xF, 0xF, 0xF
+};
+
+/**
+ * Second generation Amiga AGI palette.
+ * A 16-color, 12-bit RGB palette.
+ *
+ * Used by at least the following Amiga AGI versions:
+ * 2.202 (Space Quest II v2.0F. Intro says 1988. ScummVM 0.10.0 detects as 1986-12-09)
+ */
+uint8 amigaAgiPaletteV2[16 * 3] = {
+ 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0xF,
+ 0x0, 0x8, 0x0,
+ 0x0, 0xD, 0xB,
+ 0xC, 0x0, 0x0,
+ 0xB, 0x7, 0xD,
+ 0x8, 0x5, 0x0,
+ 0xB, 0xB, 0xB,
+ 0x7, 0x7, 0x7,
+ 0x0, 0xB, 0xF,
+ 0x0, 0xE, 0x0,
+ 0x0, 0xF, 0xD,
+ 0xF, 0x9, 0x8,
+ 0xD, 0x0, 0xF,
+ 0xE, 0xE, 0x0,
+ 0xF, 0xF, 0xF
+};
+
+/**
+ * Third generation Amiga AGI palette.
+ * A 16-color, 12-bit RGB palette.
+ *
+ * Used by at least the following Amiga AGI versions:
+ * 2.310 (Police Quest I v2.0B 1989-02-22)
+ * 2.316 (Gold Rush! v2.05 1989-03-09)
+ * x.yyy (Manhunter I v1.06 1989-03-18)
+ * 2.333 (Manhunter II v3.06 1989-08-17)
+ * 2.333 (King's Quest III v2.15 1989-11-15)
+ */
+uint8 amigaAgiPaletteV3[16 * 3] = {
+ 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0xB,
+ 0x0, 0xB, 0x0,
+ 0x0, 0xB, 0xB,
+ 0xB, 0x0, 0x0,
+ 0xB, 0x0, 0xB,
+ 0xC, 0x7, 0x0,
+ 0xB, 0xB, 0xB,
+ 0x7, 0x7, 0x7,
+ 0x0, 0x0, 0xF,
+ 0x0, 0xF, 0x0,
+ 0x0, 0xF, 0xF,
+ 0xF, 0x0, 0x0,
+ 0xF, 0x0, 0xF,
+ 0xF, 0xF, 0x0,
+ 0xF, 0xF, 0xF
+};
+
+/**
* 16 color amiga-ish palette.
*/
uint8 newPalette[16 * 3] = {
@@ -554,13 +706,42 @@ void GfxMgr::printCharacter(int x, int y, char c, int fg, int bg) {
}
/**
- * Draw button
+ * Draw a default style button.
+ * Swaps background and foreground color if button is in focus or being pressed.
* @param x x coordinate of the button
* @param y y coordinate of the button
* @param a set if the button has focus
* @param p set if the button is pressed
+ * @param fgcolor foreground color of the button when it is neither in focus nor being pressed
+ * @param bgcolor background color of the button when it is neither in focus nor being pressed
*/
-void GfxMgr::drawButton(int x, int y, const char *s, int a, int p, int fgcolor, int bgcolor) {
+void GfxMgr::drawDefaultStyleButton(int x, int y, const char *s, int a, int p, int fgcolor, int bgcolor) {
+ int textOffset = _vm->_defaultButtonStyle.getTextOffset(a > 0, p > 0);
+ AgiTextColor color = _vm->_defaultButtonStyle.getColor (a > 0, p > 0, fgcolor, bgcolor);
+ bool border = _vm->_defaultButtonStyle.getBorder (a > 0, p > 0);
+
+ rawDrawButton(x, y, s, color.fg, color.bg, border, textOffset);
+}
+
+/**
+ * Draw a button using the currently chosen style.
+ * Amiga-style is used for the Amiga-rendering mode, PC-style is used otherwise.
+ * @param x x coordinate of the button
+ * @param y y coordinate of the button
+ * @param hasFocus set if the button has focus
+ * @param pressed set if the button is pressed
+ * @param positive set if button is positive, otherwise button is negative (Only matters with Amiga-style buttons)
+ * TODO: Make Amiga-style buttons a bit wider as they were in Amiga AGI games.
+ */
+void GfxMgr::drawCurrentStyleButton(int x, int y, const char *label, bool hasFocus, bool pressed, bool positive) {
+ int textOffset = _vm->_buttonStyle.getTextOffset(hasFocus, pressed);
+ AgiTextColor color = _vm->_buttonStyle.getColor(hasFocus, pressed, positive);
+ bool border = _vm->_buttonStyle.getBorder(hasFocus, pressed);
+
+ rawDrawButton(x, y, label, color.fg, color.bg, border, textOffset);
+}
+
+void GfxMgr::rawDrawButton(int x, int y, const char *s, int fgcolor, int bgcolor, bool border, int textOffset) {
int len = strlen(s);
int x1, y1, x2, y2;
@@ -569,8 +750,12 @@ void GfxMgr::drawButton(int x, int y, const char *s, int a, int p, int fgcolor,
x2 = x + CHAR_COLS * len + 2;
y2 = y + CHAR_LINES + 2;
+ // Draw a filled rectangle that's larger than the button. Used for drawing
+ // a border around the button as the button itself is drawn after this.
+ drawRectangle(x1, y1, x2, y2, border ? BUTTON_BORDER : MSG_BOX_COLOUR);
+
while (*s) {
- putTextCharacter(0, x + (!!p), y + (!!p), *s++, a ? bgcolor : fgcolor, a ? fgcolor : bgcolor);
+ putTextCharacter(0, x + textOffset, y + textOffset, *s++, fgcolor, bgcolor);
x += CHAR_COLS;
}
@@ -623,39 +808,26 @@ int GfxMgr::keypress() {
/**
* Initialize the color palette
- * This function initializes the color palette using the specified 16-color
+ * This function initializes the color palette using the specified
* RGB palette.
- * @param p A pointer to the 16-color RGB palette.
+ * @param p A pointer to the source RGB palette.
+ * @param colorCount Count of colors in the source palette.
+ * @param fromBits Bits per source color component.
+ * @param toBits Bits per destination color component.
*/
-void GfxMgr::initPalette(uint8 *p) {
- int i;
-
- for (i = 0; i < 48; i++) {
- _palette[i] = p[i];
+void GfxMgr::initPalette(uint8 *p, uint colorCount, uint fromBits, uint toBits) {
+ const uint srcMax = (1 << fromBits) - 1;
+ const uint destMax = (1 << toBits) - 1;
+ for (uint col = 0; col < colorCount; col++) {
+ for (uint comp = 0; comp < 3; comp++) { // Convert RGB components
+ _palette[col * 4 + comp] = (p[col * 3 + comp] * destMax) / srcMax;
+ }
+ _palette[col * 4 + 3] = 0; // Set alpha to zero
}
}
void GfxMgr::gfxSetPalette() {
- int i;
- byte pal[256 * 4];
-
- if (!(_vm->getFeatures() & (GF_AGI256 | GF_AGI256_2))) {
- for (i = 0; i < 16; i++) {
- pal[i * 4 + 0] = _palette[i * 3 + 0] << 2;
- pal[i * 4 + 1] = _palette[i * 3 + 1] << 2;
- pal[i * 4 + 2] = _palette[i * 3 + 2] << 2;
- pal[i * 4 + 3] = 0;
- }
- g_system->setPalette(pal, 0, 16);
- } else {
- for (i = 0; i < 256; i++) {
- pal[i * 4 + 0] = vgaPalette[i * 3 + 0];
- pal[i * 4 + 1] = vgaPalette[i * 3 + 1];
- pal[i * 4 + 2] = vgaPalette[i * 3 + 2];
- pal[i * 4 + 3] = 0;
- }
- g_system->setPalette(pal, 0, 256);
- }
+ g_system->setPalette(_palette, 0, 256);
}
//Gets AGIPAL Data
@@ -739,7 +911,27 @@ static const byte sciMouseCursor[] = {
};
/**
- * RGBA-palette for the black and white SCI-style arrow cursor.
+ * A black and white Apple IIGS style arrow cursor (9x11).
+ * 0 = Transparent.
+ * 1 = Black (#000000 in 24-bit RGB).
+ * 2 = White (#FFFFFF in 24-bit RGB).
+ */
+static const byte appleIIgsMouseCursor[] = {
+ 2,2,0,0,0,0,0,0,0,
+ 2,1,2,0,0,0,0,0,0,
+ 2,1,1,2,0,0,0,0,0,
+ 2,1,1,1,2,0,0,0,0,
+ 2,1,1,1,1,2,0,0,0,
+ 2,1,1,1,1,1,2,0,0,
+ 2,1,1,1,1,1,1,2,0,
+ 2,1,1,1,1,1,1,1,2,
+ 2,1,1,2,1,1,2,2,0,
+ 2,2,2,0,2,1,1,2,0,
+ 0,0,0,0,0,2,2,2,0
+};
+
+/**
+ * RGBA-palette for the black and white SCI and Apple IIGS arrow cursors.
*/
static const byte sciMouseCursorPalette[] = {
0x00, 0x00, 0x00, 0x00, // Black
@@ -819,7 +1011,9 @@ void GfxMgr::setCursor(bool amigaStyleCursor) {
* @see deinit_video()
*/
int GfxMgr::initVideo() {
- if (_vm->_renderMode == Common::kRenderEGA)
+ if (_vm->getFeatures() & (GF_AGI256 | GF_AGI256_2))
+ initPalette(vgaPalette, 256, 8);
+ else if (_vm->_renderMode == Common::kRenderEGA)
initPalette(egaPalette);
else
initPalette(newPalette);
diff --git a/engines/agi/graphics.h b/engines/agi/graphics.h
index b1f9c0e1d7..e06af90f5d 100644
--- a/engines/agi/graphics.h
+++ b/engines/agi/graphics.h
@@ -41,7 +41,7 @@ class GfxMgr {
private:
AgiEngine *_vm;
- uint8 _palette[16 * 3];
+ uint8 _palette[256 * 4];
uint8 *_agiScreen;
unsigned char *_screen;
@@ -50,6 +50,9 @@ private:
uint8 _agipalPalette[16 * 3];
int _agipalFileNum;
+private:
+ void rawDrawButton(int x, int y, const char *s, int fgcolor, int bgcolor, bool border, int textOffset);
+
public:
GfxMgr(AgiEngine *vm);
@@ -74,12 +77,13 @@ public:
void clearScreen(int);
void clearConsoleScreen(int);
void drawBox(int, int, int, int, int, int, int);
- void drawButton(int, int, const char *, int, int, int fgcolor = 0, int bgcolor = 0);
+ void drawDefaultStyleButton(int, int, const char *, int, int, int fgcolor = 0, int bgcolor = 0);
+ void drawCurrentStyleButton(int x, int y, const char *label, bool hasFocus, bool pressed = false, bool positive = true);
int testButton(int, int, const char *);
void drawRectangle(int, int, int, int, int);
void saveBlock(int, int, int, int, uint8 *);
void restoreBlock(int, int, int, int, uint8 *);
- void initPalette(uint8 *);
+ void initPalette(uint8 *p, uint colorCount = 16, uint fromBits = 6, uint toBits = 8);
void setAGIPal(int);
int getAGIPalFileNum();
void drawFrame(int x1, int y1, int x2, int y2, int c1, int c2);
diff --git a/engines/agi/keyboard.cpp b/engines/agi/keyboard.cpp
index 3acc81ddff..2b7559f754 100644
--- a/engines/agi/keyboard.cpp
+++ b/engines/agi/keyboard.cpp
@@ -107,8 +107,10 @@ int AgiEngine::handleController(int key) {
VtEntry *v = &_game.viewTable[0];
int i;
- /* AGI 3.149 games and The Black Cauldron need KEY_ESCAPE to use menus */
- if (key == 0 || (key == KEY_ESCAPE && agiGetRelease() != 0x3149 && getGameID() != GID_BC) )
+ // AGI 3.149 games and The Black Cauldron need KEY_ESCAPE to use menus
+ // Games with the GF_ESCPAUSE flag need KEY_ESCAPE to pause the game
+ if (key == 0 ||
+ (key == KEY_ESCAPE && agiGetRelease() != 0x3149 && getGameID() != GID_BC && !(getFeatures() & GF_ESCPAUSE)) )
return false;
if ((getGameID() == GID_MH1 || getGameID() == GID_MH2) && (key == KEY_ENTER) &&
@@ -127,7 +129,7 @@ int AgiEngine::handleController(int key) {
}
if (key == BUTTON_LEFT) {
- if (getflag(fMenusWork) && g_mouse.y <= CHAR_LINES) {
+ if ((getflag(fMenusWork) || (getFeatures() & GF_MENUS)) && g_mouse.y <= CHAR_LINES) {
newInputMode(INPUT_MENU);
return true;
}
diff --git a/engines/agi/menu.cpp b/engines/agi/menu.cpp
index 5edaaf0ded..7aa7f5e55d 100644
--- a/engines/agi/menu.cpp
+++ b/engines/agi/menu.cpp
@@ -267,7 +267,7 @@ bool Menu::keyhandler(int key) {
static int menuActive = false;
static int buttonUsed = 0;
- if (!_vm->getflag(fMenusWork))
+ if (!_vm->getflag(fMenusWork) && !(_vm->getFeatures() & GF_MENUS))
return false;
if (!menuActive) {
@@ -351,6 +351,12 @@ bool Menu::keyhandler(int key) {
debugC(6, kDebugLevelMenu | kDebugLevelInput, "event %d registered", d->event);
_vm->_game.evKeyp[d->event].occured = true;
_vm->_game.evKeyp[d->event].data = d->event;
+ // In LSL1, event 0x20 is set when changing the game speed to normal via the menu
+ // Do not set the event data to 0x20, as this event is then incorrectly triggered
+ // when the spacebar is pressed, which has a keycode equal to 0x20 as well
+ // Fixes bug #1751390 - "LSL: after changing game speed, space key turn unfunctional"
+ if (d->event == 0x20)
+ _vm->_game.evKeyp[d->event].data = d->event + 1;
goto exit_menu;
}
}
diff --git a/engines/agi/predictive.cpp b/engines/agi/predictive.cpp
index 67ebed5f05..eef4360cbf 100644
--- a/engines/agi/predictive.cpp
+++ b/engines/agi/predictive.cpp
@@ -30,6 +30,10 @@
#include "common/func.h"
#include "common/config-manager.h"
+#ifdef __DS__
+#include "wordcompletion.h"
+#endif
+
namespace Agi {
#define kModePre 0
@@ -200,9 +204,9 @@ bool AgiEngine::predictiveDialog(void) {
color2 = 7;
}
if (i == 14) {
- _gfx->drawButton(bx[i], by[i], modes[mode], i == active, 0, color1, color2);
+ _gfx->drawDefaultStyleButton(bx[i], by[i], modes[mode], i == active, 0, color1, color2);
} else {
- _gfx->drawButton(bx[i], by[i], buttons[i], i == active, 0, color1, color2);
+ _gfx->drawDefaultStyleButton(bx[i], by[i], buttons[i], i == active, 0, color1, color2);
}
}
@@ -521,6 +525,10 @@ void AgiEngine::loadDict(void) {
while ((ptr = strchr(ptr, '\n'))) {
*ptr = 0;
ptr++;
+#ifdef __DS__
+ // Pass the line on to the DS word list
+ DS::addAutoCompleteLine(_predictiveDictLine[i - 1]);
+#endif
_predictiveDictLine[i++] = ptr;
}
if (_predictiveDictLine[lines - 1][0] == 0)
@@ -529,6 +537,11 @@ void AgiEngine::loadDict(void) {
_predictiveDictLineCount = lines;
debug("Loaded %d lines", _predictiveDictLineCount);
+#ifdef __DS__
+ // Sort the DS word completion list, to allow for a binary chop later (in the ds backend)
+ DS::sortAutoCompleteWordList();
+#endif
+
uint32 time3 = _system->getMillis();
printf("Time to parse pred.dic: %d, total: %d\n", time3-time2, time3-time1);
}
diff --git a/engines/agi/saveload.cpp b/engines/agi/saveload.cpp
index 9144dae96c..05ce80b1a3 100644
--- a/engines/agi/saveload.cpp
+++ b/engines/agi/saveload.cpp
@@ -55,6 +55,7 @@ int AgiEngine::saveGame(const char *fileName, const char *description) {
int i;
struct ImageStackElement *ptr = _imageStack;
Common::OutSaveFile *out;
+ int result = errOK;
debugC(3, kDebugLevelMain | kDebugLevelSavegame, "AgiEngine::saveGame(%s, %s)", fileName, description);
if (!(out = _saveFileMan->openForSaving(fileName))) {
@@ -206,14 +207,15 @@ int AgiEngine::saveGame(const char *fileName, const char *description) {
out->writeSint16BE(_gfx->getAGIPalFileNum());
out->finalize();
- if (out->ioFailed())
+ if (out->ioFailed()) {
warning("Can't write file '%s'. (Disk full?)", fileName);
- else
+ result = errIOError;
+ } else
debugC(1, kDebugLevelMain | kDebugLevelSavegame, "Saved game %s in file %s", description, fileName);
delete out;
debugC(3, kDebugLevelMain | kDebugLevelSavegame, "Closed %s", fileName);
- return errOK;
+ return result;
}
int AgiEngine::loadGame(const char *fileName, bool checkId) {
@@ -516,7 +518,7 @@ int AgiEngine::selectSlot() {
buttonY = (vm + 17) * CHAR_LINES;
for (i = 0; i < 2; i++)
- _gfx->drawButton(buttonX[i], buttonY, buttonText[i], 0, 0, MSG_BOX_TEXT, MSG_BOX_COLOUR);
+ _gfx->drawCurrentStyleButton(buttonX[i], buttonY, buttonText[i], false, false, i == 0);
AllowSyntheticEvents on(this);
int oldFirstSlot = _firstSlot + 1;
@@ -751,20 +753,24 @@ int AgiEngine::saveGameDialog() {
sprintf(fileName, "%s", getSavegameFilename(slot));
debugC(8, kDebugLevelMain | kDebugLevelResources, "file is [%s]", fileName);
- saveGame(fileName, desc);
+ int result = saveGame(fileName, desc);
- messageBox("Game saved.");
+ if (result == errOK)
+ messageBox("Game saved.");
+ else
+ messageBox("Error saving game.");
- return errOK;
+ return result;
}
int AgiEngine::saveGameSimple() {
char fileName[MAX_PATH];
sprintf(fileName, "%s", getSavegameFilename(0));
- saveGame(fileName, "Default savegame");
-
- return errOK;
+ int result = saveGame(fileName, "Default savegame");
+ if (result != errOK)
+ messageBox("Error saving game.");
+ return result;
}
int AgiEngine::loadGameDialog() {
diff --git a/engines/agi/sound.cpp b/engines/agi/sound.cpp
index 954cca8f8f..b083b77440 100644
--- a/engines/agi/sound.cpp
+++ b/engines/agi/sound.cpp
@@ -40,26 +40,43 @@ namespace Agi {
#ifdef USE_IIGS_SOUND
-/**
- * AGI engine sound envelope structure.
- */
-struct SoundEnvelope {
+struct IIgsEnvelopeSegment {
uint8 bp;
- uint8 incHi;
- uint8 inc_lo;
+ uint16 inc; ///< 8b.8b fixed point, big endian?
};
-struct SoundWavelist {
+#define ENVELOPE_SEGMENT_COUNT 8
+struct IIgsEnvelope {
+ IIgsEnvelopeSegment seg[ENVELOPE_SEGMENT_COUNT];
+};
+
+// 2**(1/12) i.e. the 12th root of 2
+#define SEMITONE 1.059463094359295
+
+struct IIgsWaveInfo {
uint8 top;
uint8 addr;
uint8 size;
+// Oscillator channel (Bits 4-7 of mode-byte). Simplified to use only stereo here.
+#define MASK_OSC_CHANNEL (1 << 4)
+#define OSC_CHANNEL_LEFT (1 << 4)
+#define OSC_CHANNEL_RIGHT (0 << 4)
+// Oscillator halt bit (Bit 0 of mode-byte)
+#define MASK_OSC_HALT (1 << 0)
+#define OSC_HALT (1 << 0)
+// Oscillator mode (Bits 1 and 2 of mode-byte)
+#define MASK_OSC_MODE (3 << 1)
+#define OSC_MODE_LOOP (0 << 1)
+#define OSC_MODE_ONESHOT (1 << 1)
+#define OSC_MODE_SYNC_AM (2 << 1)
+#define OSC_MODE_SWAP (3 << 1)
uint8 mode;
- uint8 relHi;
- uint8 relLo;
+ uint16 relPitch; ///< 8b.8b fixed point, big endian?
};
-struct SoundInstrument {
- struct SoundEnvelope env[8];
+#define MAX_WAVE_COUNT 8
+struct IIgsInstrumentHeader {
+ IIgsEnvelope env;
uint8 relseg;
uint8 priority;
uint8 bendrange;
@@ -68,19 +85,19 @@ struct SoundInstrument {
uint8 spare;
uint8 wac;
uint8 wbc;
- struct SoundWavelist wal[8];
- struct SoundWavelist wbl[8];
+ IIgsWaveInfo wal[MAX_WAVE_COUNT];
+ IIgsWaveInfo wbl[MAX_WAVE_COUNT];
};
-struct SoundIIgsSample {
- uint8 typeLo;
- uint8 typeHi;
- uint8 srateLo;
- uint8 srateHi;
- uint16 unknown[2];
- uint8 sizeLo;
- uint8 sizeHi;
- uint16 unknown2[13];
+struct IIgsSampleHeader {
+ uint16 type;
+ uint8 pitch; ///< Logarithmic, base is 2**(1/12), unknown multiplier (Possibly in range 1040-1080)
+ uint8 unknownByte_Ofs3; // 0x7F in Gold Rush's sound resource 60, 0 in all others.
+ uint8 volume; ///< Current guess: Logarithmic in 6 dB steps
+ uint8 unknownByte_Ofs5; ///< 0 in all tested samples.
+ uint16 instrumentSize; ///< Little endian. 44 in all tested samples. A guess.
+ uint16 sampleSize; ///< Little endian. Accurate in all tested samples excluding Manhunter I's sound resource 16.
+ IIgsInstrumentHeader instrument;
};
#if 0
@@ -89,6 +106,117 @@ static int numInstruments;
static uint8 *wave;
#endif
+bool readIIgsEnvelope(IIgsEnvelope &envelope, Common::SeekableReadStream &stream) {
+ for (int segNum = 0; segNum < ENVELOPE_SEGMENT_COUNT; segNum++) {
+ envelope.seg[segNum].bp = stream.readByte();
+ envelope.seg[segNum].inc = stream.readUint16BE();
+ }
+ return !stream.ioFailed();
+}
+
+bool readIIgsWaveInfo(IIgsWaveInfo &waveInfo, Common::SeekableReadStream &stream) {
+ waveInfo.top = stream.readByte();
+ waveInfo.addr = stream.readByte();
+ waveInfo.size = stream.readByte();
+ waveInfo.mode = stream.readByte();
+ waveInfo.relPitch = stream.readUint16BE();
+ return !stream.ioFailed();
+}
+
+/**
+ * Read an Apple IIGS instrument header from the given stream.
+ * @param header The header to which to write the data.
+ * @param stream The source stream from which to read the data.
+ * @return True if successful, false otherwise.
+ */
+bool readIIgsInstrumentHeader(IIgsInstrumentHeader &header, Common::SeekableReadStream &stream) {
+ readIIgsEnvelope(header.env, stream);
+ header.relseg = stream.readByte();
+ header.priority = stream.readByte();
+ header.bendrange = stream.readByte();
+ header.vibdepth = stream.readByte();
+ header.vibspeed = stream.readByte();
+ header.spare = stream.readByte();
+ header.wac = stream.readByte();
+ header.wbc = stream.readByte();
+ for (int waveA = 0; waveA < header.wac; waveA++) // Read A wave lists
+ readIIgsWaveInfo(header.wal[waveA], stream);
+ for (int waveB = 0; waveB < header.wbc; waveB++) // Read B wave lists
+ readIIgsWaveInfo(header.wbl[waveB], stream);
+ return !stream.ioFailed();
+}
+
+/**
+ * Read an Apple IIGS AGI sample header from the given stream.
+ * @param header The header to which to write the data.
+ * @param stream The source stream from which to read the data.
+ * @return True if successful, false otherwise.
+ */
+bool readIIgsSampleHeader(IIgsSampleHeader &header, Common::SeekableReadStream &stream) {
+ header.type = stream.readUint16LE();
+ header.pitch = stream.readByte();
+ header.unknownByte_Ofs3 = stream.readByte();
+ header.volume = stream.readByte();
+ header.unknownByte_Ofs5 = stream.readByte();
+ header.instrumentSize = stream.readUint16LE();
+ header.sampleSize = stream.readUint16LE();
+ return readIIgsInstrumentHeader(header.instrument, stream);
+}
+
+/**
+ * Load an Apple IIGS AGI sample resource from the given stream and
+ * create an AudioStream out of it.
+ *
+ * @param stream The source stream.
+ * @param resnum Sound resource number. Optional. Used for error messages.
+ * @return A non-null AudioStream pointer if successful, NULL otherwise.
+ * @note In case of failure (i.e. NULL is returned), stream is reset back
+ * to its original position and its I/O failed -status is cleared.
+ * TODO: Add better handling of invalid resource number when printing error messages.
+ * TODO: Add support for looping sounds.
+ * FIXME: Fix sample rate calculation, it's probably not accurate at the moment.
+ */
+Audio::AudioStream *makeIIgsSampleStream(Common::SeekableReadStream &stream, int resnum = -1) {
+ const uint32 startPos = stream.pos();
+ IIgsSampleHeader header;
+ Audio::AudioStream *result = NULL;
+ bool readHeaderOk = readIIgsSampleHeader(header, stream);
+
+ // Check that the header was read ok and that it's of the correct type
+ // and that there's room for the sample data in the stream.
+ if (readHeaderOk && header.type == AGI_SOUND_SAMPLE) { // An Apple IIGS AGI sample resource
+ uint32 tailLen = stream.size() - stream.pos();
+ if (tailLen < header.sampleSize) { // Check if there's no room for the sample data in the stream
+ // Apple IIGS Manhunter I: Sound resource 16 has only 16074 bytes
+ // of sample data although header says it should have 16384 bytes.
+ warning("Apple IIGS sample (%d) too short (%d bytes. Should be %d bytes). Using the part that's left", resnum, tailLen, header.sampleSize);
+ header.sampleSize = (uint16) tailLen; // Use the part that's left
+ }
+ if (header.pitch > 0x7F) { // Check if the pitch is invalid
+ warning("Apple IIGS sample (%d) has too high pitch (0x%02x)", resnum, header.pitch);
+ header.pitch &= 0x7F; // Apple IIGS AGI probably did it this way too
+ }
+ // Allocate memory for the sample data and read it in
+ byte *sampleData = (byte *) malloc(header.sampleSize);
+ uint32 readBytes = stream.read(sampleData, header.sampleSize);
+ if (readBytes == header.sampleSize) { // Check that we got all the data we requested
+ // Make an audio stream from the mono, 8 bit, unsigned input data
+ byte flags = Audio::Mixer::FLAG_AUTOFREE | Audio::Mixer::FLAG_UNSIGNED;
+ int rate = (int) (1076 * pow(SEMITONE, header.pitch));
+ result = Audio::makeLinearInputStream(sampleData, header.sampleSize, rate, flags, 0, 0);
+ }
+ }
+
+ // If couldn't make a sample out of the input stream for any reason then
+ // rewind back to stream's starting position and clear I/O failed -status.
+ if (result == NULL) {
+ stream.seek(startPos);
+ stream.clearIOFailed();
+ }
+
+ return result;
+}
+
#endif
static int playing;
@@ -169,7 +297,7 @@ void SoundMgr::unloadSound(int resnum) {
}
void SoundMgr::decodeSound(int resnum) {
-#ifdef USE_IIGS_SOUND
+#if 0
int type, size;
int16 *buf;
uint8 *src;
@@ -190,12 +318,12 @@ void SoundMgr::decodeSound(int resnum) {
_vm->_game.sounds[resnum].rdata = (uint8 *) buf;
free(src);
}
-#endif /* USE_IIGS_SOUND */
+#endif
}
void SoundMgr::startSound(int resnum, int flag) {
int i, type;
-#ifdef USE_IIGS_SOUND
+#if 0
struct SoundIIgsSample *smp;
#endif
@@ -218,7 +346,7 @@ void SoundMgr::startSound(int resnum, int flag) {
song = (uint8 *)_vm->_game.sounds[resnum].rdata;
switch (type) {
-#ifdef USE_IIGS_SOUND
+#if 0
case AGI_SOUND_SAMPLE:
debugC(3, kDebugLevelSound, "IIGS sample");
smp = (struct SoundIIgsSample *)_vm->_game.sounds[resnum].rdata;
diff --git a/engines/agi/text.cpp b/engines/agi/text.cpp
index 565e94fa26..1d653a9415 100644
--- a/engines/agi/text.cpp
+++ b/engines/agi/text.cpp
@@ -364,7 +364,7 @@ int AgiEngine::selectionBox(const char *m, const char **b) {
debugC(4, kDebugLevelText, "waiting...");
for (;;) {
for (i = 0; b[i]; i++)
- _gfx->drawButton(bx[i], by[i], b[i], i == active, 0, MSG_BOX_TEXT, MSG_BOX_COLOUR);
+ _gfx->drawCurrentStyleButton(bx[i], by[i], b[i], i == active, false, i == 0);
_gfx->pollTimer(); /* msdos driver -> does nothing */
key = doPollKeyboard();
@@ -555,7 +555,7 @@ char *AgiEngine::agiSprintf(const char *s) {
break;
case 's':
i = strtoul(s, NULL, 10);
- safeStrcat(p, _game.strings[i]);
+ safeStrcat(p, agiSprintf(_game.strings[i]));
break;
case 'm':
i = strtoul(s, NULL, 10) - 1;