[Scummvm-git-logs] scummvm master -> c360a6fa7ef09bb5959f56f5cc898f0da5414d6a
dreammaster
noreply at scummvm.org
Fri Aug 14 02:11:35 UTC 2026
This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
8d8b7b26fb MADS: NEBULAR: Greyscale fixes when looking at inventory objects
c360a6fa7e MADS: NEBULAR: Fix greyscale fade out examining inventory items
Commit: 8d8b7b26fb64c255d694c09d2226b3069be18741
https://github.com/scummvm/scummvm/commit/8d8b7b26fb64c255d694c09d2226b3069be18741
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2026-08-14T12:11:25+10:00
Commit Message:
MADS: NEBULAR: Greyscale fixes when looking at inventory objects
Changed paths:
engines/mads/core/sort.cpp
engines/mads/nebular/extra.cpp
engines/mads/nebular/extra.h
diff --git a/engines/mads/core/sort.cpp b/engines/mads/core/sort.cpp
index 17e275a722b..949f88e0a21 100644
--- a/engines/mads/core/sort.cpp
+++ b/engines/mads/core/sort.cpp
@@ -20,6 +20,8 @@
*/
#include "mads/core/general.h"
+#include "mads/mads.h"
+#include "mads/nebular/extra.h"
namespace MADS {
@@ -121,6 +123,11 @@ void sort_insertion_16(int elements, byte *id, word *value) {
}
void sort_insertion_8(int elements, byte *id, byte *value) {
+ if (g_engine->getGameID() == GType_RexNebular) {
+ RexNebular::sort_insertion_8(elements, id, value);
+ return;
+ }
+
int restart_mark = 0;
byte my_value;
byte my_id;
diff --git a/engines/mads/nebular/extra.cpp b/engines/mads/nebular/extra.cpp
index aa690a70b61..27c4828aa16 100644
--- a/engines/mads/nebular/extra.cpp
+++ b/engines/mads/nebular/extra.cpp
@@ -463,6 +463,64 @@ done:
return roomPtr;
}
+void sort_insertion_8(int elements, byte *id, byte *value) {
+ int endIndex = elements - 1;
+
+ for (;;) { // restart_sort
+ bool continueFlag = false;
+ if (endIndex <= 0)
+ return;
+
+ int di = 0;
+ for (;;) {
+ if (continueFlag)
+ break;
+
+ int palIndex = di;
+ byte v1 = value[di];
+ byte v2 = id[di];
+
+ if (value[di + 1] < v1) {
+ // Extract the out-of-place (larger) element, close the gap
+ int deletion = elements - di - 1;
+ if (deletion > 0) {
+ memmove(&value[di], &value[di + 1], deletion * sizeof(byte));
+ memmove(&id[di], &id[di + 1], deletion * sizeof(byte));
+ }
+
+ // Find the insertion point: just after the last element <= v1
+ int si = 0;
+ bool found = false;
+ while (endIndex > si) {
+ if (found)
+ break;
+ if (value[si] > v1)
+ found = true;
+ si++;
+ }
+
+ continueFlag = true;
+
+ int insertion = elements - si - 1;
+ if (insertion > 0) {
+ memmove(&value[si + 1], &value[si], insertion * sizeof(byte));
+ memmove(&id[si + 1], &id[si], insertion * sizeof(byte));
+ }
+ value[si] = v1;
+ id[si] = v2;
+ }
+
+ ++palIndex;
+ if (endIndex <= palIndex)
+ break;
+ di = palIndex;
+ }
+
+ if (!continueFlag)
+ return;
+ }
+}
+
int buffer_legal(const Buffer &special, int orig_wrap,
int x1, int y1, int x2, int y2) {
if (special.data == nullptr)
diff --git a/engines/mads/nebular/extra.h b/engines/mads/nebular/extra.h
index 2f45bdee869..21d3aa6dd6b 100644
--- a/engines/mads/nebular/extra.h
+++ b/engines/mads/nebular/extra.h
@@ -64,6 +64,21 @@ extern int room_load_variant(Load *load_handle, Buffer *depth, Buffer *walk, Buf
*/
extern int buffer_legal(const Buffer &special, int orig_wrap, int x1, int y1, int x2, int y2);
+/**
+ * Rex Nebular's version of sort_insertion_8() (see core/sort.h), called from it whenever
+ * the active game is Rex Nebular. Unlike the generic engine's version, this is a faithful,
+ * instruction-for-instruction port of Rex's own sort_insertion_8 disassembly, which is a
+ * genuinely different (and, unlike the generic version, stable) algorithm: on each pass it
+ * restarts the scan from index 0, and on finding an inversion extracts the earlier (larger)
+ * of the two out-of-order elements, closing the gap left behind, then re-inserts it just
+ * after the last remaining element that is <= it. This stability matters because
+ * magic_map_to_grey_ramp() (see core/magic.cpp) relies on tied elements keeping their
+ * original relative order to consistently bucket colors with identical grey-ramp hash
+ * values; the generic version's tie-breaking differs and produces a visibly different
+ * (incorrect) grey ramp for Rex.
+ */
+extern void sort_insertion_8(int elements, byte *id, byte *value);
+
} // namespace RexNebular
} // namespace MADS
Commit: c360a6fa7ef09bb5959f56f5cc898f0da5414d6a
https://github.com/scummvm/scummvm/commit/c360a6fa7ef09bb5959f56f5cc898f0da5414d6a
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2026-08-14T12:11:25+10:00
Commit Message:
MADS: NEBULAR: Fix greyscale fade out examining inventory items
Assisted-by: Claude Code:sonnet-5
Changed paths:
engines/mads/core/object.cpp
engines/mads/core/pal.cpp
engines/mads/core/popup.h
engines/mads/nebular/popup.cpp
engines/mads/nebular/popup.h
diff --git a/engines/mads/core/object.cpp b/engines/mads/core/object.cpp
index ddeac9c8deb..4817661ba0b 100644
--- a/engines/mads/core/object.cpp
+++ b/engines/mads/core/object.cpp
@@ -39,6 +39,7 @@
#include "mads/core/popup.h"
#include "mads/core/room.h"
#include "mads/core/speech.h"
+#include "mads/nebular/popup.h"
#include "mads/core/sprite.h"
#include "mads/core/text.h"
#include "mads/core/tile.h"
@@ -341,6 +342,9 @@ int object_examine(int number, long message, int speech) {
if (message) {
text_saves_screen = false;
+ if (isRex)
+ RexNebular::popup_shift_dialog_colors(-10);
+
memcpy(&cycling_palette[248].r, &master_palette[248].r, 8 * sizeof(RGBcolor));
if (speech) {
@@ -351,6 +355,9 @@ int object_examine(int number, long message, int speech) {
text_show(message);
+ if (isRex)
+ RexNebular::popup_shift_dialog_colors(10);
+
if (speech && speech_system_active && speech_on) {
speech_all_off();
}
diff --git a/engines/mads/core/pal.cpp b/engines/mads/core/pal.cpp
index 4571aa877c3..97bcbe9d09c 100644
--- a/engines/mads/core/pal.cpp
+++ b/engines/mads/core/pal.cpp
@@ -563,8 +563,8 @@ void pal_grey(Palette &fixpal, int base_color, int num_colors,
int level;
word accum = 0;
- dif = (high_grey - low_grey);
- level = low_grey;
+ dif = (low_grey - high_grey);
+ level = high_grey;
for (count = 0; count < num_colors; count++) {
fixpal[base_color + count].r = (byte)level;
diff --git a/engines/mads/core/popup.h b/engines/mads/core/popup.h
index 546bd613fa2..5002a18317b 100644
--- a/engines/mads/core/popup.h
+++ b/engines/mads/core/popup.h
@@ -99,19 +99,6 @@ namespace MADS {
#define popup_padding_width 3 /* Extra space on each side */
-enum {
- REX_PALETTE_CYCLING_AREA = 6,
- REX_DIALOG_CONTENT1_COLOR = 248,
- REX_DIALOG_CONTENT2_COLOR = 249,
- REX_DIALOG_EDGE_COLOR = 250,
- REX_DIALOG_BACKGROUND_COLOR = 251,
- REX_DIALOG_FC_COLOR = 252,
- REX_DIALOG_FD_COLOR = 253,
- REX_DIALOG_FE_COLOR = 254,
- REX_DIALOG_BLACK_COLOR = 0
-};
-
-
struct BoxParam {
SeriesPtr series; /* Sprite series for popup box */
diff --git a/engines/mads/nebular/popup.cpp b/engines/mads/nebular/popup.cpp
index fab74d6eada..9ba56827223 100644
--- a/engines/mads/nebular/popup.cpp
+++ b/engines/mads/nebular/popup.cpp
@@ -38,20 +38,56 @@ namespace RexNebular {
enum {
DIALOG_BLACK_COLOR = 0,
- PALETTE_CYCLING_AREA = 6,
- DIALOG_CONTENT1_COLOR = 248,
- DIALOG_CONTENT2_COLOR = 249,
- DIALOG_EDGE_COLOR = 250,
- DIALOG_BACKGROUND_COLOR = 251,
- DIALOG_FC_COLOR = 252,
- DIALOG_FD_COLOR = 253,
- DIALOG_FE_COLOR = 254
+ PALETTE_CYCLING_AREA = 8,
+
+ DIALOG_CONTENT1_IDX = 0,
+ DIALOG_CONTENT2_IDX,
+ DIALOG_EDGE_IDX,
+ DIALOG_BACKGROUND_IDX,
+ DIALOG_FC_IDX,
+ DIALOG_FD_IDX,
+ DIALOG_FE_IDX
};
+// Rex's object_examine temporarily shifts these down by 10 (via
+// popup_shift_dialog_colors()) while its item-description dialog is on
+// screen, then shifts them back afterwards, so they must be mutable state
+// rather than fixed constants. PALETTE_CYCLING_AREA (8) covers one byte
+// beyond DIALOG_FE_COLOR that the original also shifts, though nothing
+// else in the engine names or uses it.
+byte dialog_colors[PALETTE_CYCLING_AREA];
+
+#define DIALOG_CONTENT1_COLOR dialog_colors[DIALOG_CONTENT1_IDX]
+#define DIALOG_CONTENT2_COLOR dialog_colors[DIALOG_CONTENT2_IDX]
+#define DIALOG_EDGE_COLOR dialog_colors[DIALOG_EDGE_IDX]
+#define DIALOG_BACKGROUND_COLOR dialog_colors[DIALOG_BACKGROUND_IDX]
+#define DIALOG_FC_COLOR dialog_colors[DIALOG_FC_IDX]
+#define DIALOG_FD_COLOR dialog_colors[DIALOG_FD_IDX]
+#define DIALOG_FE_COLOR dialog_colors[DIALOG_FE_IDX]
+
int dialog_content_seed;
void popup_init() {
dialog_content_seed = -1;
+
+ dialog_colors[DIALOG_CONTENT1_IDX] = 248;
+ dialog_colors[DIALOG_CONTENT2_IDX] = 249;
+ dialog_colors[DIALOG_EDGE_IDX] = 250;
+ dialog_colors[DIALOG_BACKGROUND_IDX] = 251;
+ dialog_colors[DIALOG_FC_IDX] = 252;
+ dialog_colors[DIALOG_FD_IDX] = 253;
+ dialog_colors[DIALOG_FE_IDX] = 254;
+ dialog_colors[7] = 255;
+}
+
+// Shifts all of the dialog colors (including the one unnamed trailing byte -
+// see PALETTE_CYCLING_AREA above) by delta. Called by Rex's object_examine
+// with -10 before showing its item-description dialog and +10 afterwards,
+// so the dialog temporarily borrows a different part of the palette than
+// the object grey ramp it's being drawn over.
+void popup_shift_dialog_colors(int delta) {
+ for (int i = 0; i < PALETTE_CYCLING_AREA; ++i)
+ dialog_colors[i] = (byte)(dialog_colors[i] + delta);
}
static uint16 rotr16(uint16 value, int amount) {
@@ -110,18 +146,18 @@ void popup_draw() {
askY = (box_param.font->max_y_size + 1) * box->ask_y;
// Fill area
- buffer_rect_fill(scr_main, box->x, box->y, box->xs, box->ys, REX_DIALOG_BACKGROUND_COLOR);
+ buffer_rect_fill(scr_main, box->x, box->y, box->xs, box->ys, DIALOG_BACKGROUND_COLOR);
// Edge lines
- buffer_rect_fill(scr_main, box->x + 1, box->y + box->ys - 2, box->xs - 1, 1, REX_DIALOG_EDGE_COLOR);
- buffer_rect_fill(scr_main, box->x, box->y + box->ys - 1, box->xs, 1, REX_DIALOG_EDGE_COLOR);
+ buffer_rect_fill(scr_main, box->x + 1, box->y + box->ys - 2, box->xs - 1, 1, DIALOG_EDGE_COLOR);
+ buffer_rect_fill(scr_main, box->x, box->y + box->ys - 1, box->xs, 1, DIALOG_EDGE_COLOR);
// Right edge
- buffer_rect_fill(scr_main, box->x + box->xs - 2, box->y + 2, 1, box->ys - 2, REX_DIALOG_EDGE_COLOR);
- buffer_rect_fill(scr_main, box->x + box->xs - 1, box->y + 1, 1, box->ys - 1, REX_DIALOG_EDGE_COLOR);
+ buffer_rect_fill(scr_main, box->x + box->xs - 2, box->y + 2, 1, box->ys - 2, DIALOG_EDGE_COLOR);
+ buffer_rect_fill(scr_main, box->x + box->xs - 1, box->y + 1, 1, box->ys - 1, DIALOG_EDGE_COLOR);
dialog_content_seed = popup_draw_content(box->x + 2, box->y + 2, box->xs - 4, askY, 0,
- REX_DIALOG_CONTENT2_COLOR, REX_DIALOG_CONTENT1_COLOR, box->ys - 4, scr_main);
+ DIALOG_CONTENT2_COLOR, DIALOG_CONTENT1_COLOR, box->ys - 4, scr_main);
askY = box->y + 5;
diff --git a/engines/mads/nebular/popup.h b/engines/mads/nebular/popup.h
index 5d35612617c..c27e1270331 100644
--- a/engines/mads/nebular/popup.h
+++ b/engines/mads/nebular/popup.h
@@ -33,6 +33,14 @@ extern void popup_draw();
extern void popup_setup_cycle();
extern void popup_update_ask(const char *string, int maxlen);
+/**
+ * Shifts the dialog palette colors (see popup_setup_cycle()) by delta. Called by
+ * object_examine() (see core/object.cpp) with -10 before showing its item-description
+ * dialog and +10 afterwards, so the dialog temporarily borrows a different part of
+ * the palette than the object grey ramp it's drawn over.
+ */
+extern void popup_shift_dialog_colors(int delta);
+
} // namespace RexNebular
} // namespace MADS
More information about the Scummvm-git-logs
mailing list