aboutsummaryrefslogtreecommitdiff
path: root/scumm
diff options
context:
space:
mode:
authorPaweł Kołodziejski2002-08-25 18:40:23 +0000
committerPaweł Kołodziejski2002-08-25 18:40:23 +0000
commit73b031515eadf2865871f3a8a09df9627f7c113e (patch)
tree4621a4faee1cf7a01efc5ca2748995409c231644 /scumm
parentb169ef13e38bf3bb69e6725f6988011aa9eb258c (diff)
downloadscummvm-rg350-73b031515eadf2865871f3a8a09df9627f7c113e.tar.gz
scummvm-rg350-73b031515eadf2865871f3a8a09df9627f7c113e.tar.bz2
scummvm-rg350-73b031515eadf2865871f3a8a09df9627f7c113e.zip
applied patch #599909
svn-id: r4855
Diffstat (limited to 'scumm')
-rw-r--r--scumm/gfx.cpp130
-rw-r--r--scumm/scumm.h12
2 files changed, 125 insertions, 17 deletions
diff --git a/scumm/gfx.cpp b/scumm/gfx.cpp
index 5431c1aac0..cda2598c70 100644
--- a/scumm/gfx.cpp
+++ b/scumm/gfx.cpp
@@ -674,7 +674,7 @@ void Scumm::fadeIn(int effect)
transitionEffect(effect - 1);
break;
case 128:
- unkScreenEffect6();
+ dissolveEffect(8, 8);
break;
case 130:
unkScreenEffect1();
@@ -689,7 +689,7 @@ void Scumm::fadeIn(int effect)
unkScreenEffect4();
break;
case 134:
- unkScreenEffect5(0);
+ dissolveEffect(1, 1);
break;
case 135:
unkScreenEffect5(1);
@@ -731,7 +731,7 @@ void Scumm::fadeOut(int a)
transitionEffect(a - 1);
break;
case 128:
- unkScreenEffect6();
+ dissolveEffect(8, 8);
break;
case 129:
// Just blit screen 0 to the display (i.e. display will be black)
@@ -739,7 +739,7 @@ void Scumm::fadeOut(int a)
updateDirtyScreen(0);
break;
case 134:
- unkScreenEffect5(0);
+ dissolveEffect(1, 1);
break;
case 135:
unkScreenEffect5(1);
@@ -1979,16 +1979,124 @@ void Scumm::transitionEffect(int a)
}
}
-void Scumm::unkScreenEffect6()
-{
- /* XXX: not implemented */
- warning("stub unkScreenEffect6");
+// Update width x height areas of the screen, in random order, until the whole
+// screen has been updated. For instance:
+//
+// dissolveEffect(1, 1) produces a pixel-by-pixel dissolve
+// dissolveEffect(8, 8) produces a square-by-square dissolve
+// dissolveEffect(virtsrc[0].width, 1) produces a line-by-line dissolve
+
+void Scumm::dissolveEffect(int width, int height) {
+ VirtScreen *vs = &virtscr[0];
+ int *offsets;
+ int blits_before_refresh, blits;
+ int x, y;
+ int w, h;
+ int i;
+
+ // There's probably some less memory-hungry way of doing this. But
+ // since we're only dealing with relatively small images, it shouldn't
+ // be too bad.
+
+ w = vs->width / width;
+ h = vs->height / height;
+
+ // When used used correctly, vs->width % width and vs->height % height
+ // should both be zero, but just to be safe...
+
+ if (vs->width % width)
+ w++;
+
+ if (vs->height % height)
+ h++;
+
+ offsets = (int *) malloc(w * h * sizeof(int));
+ if (offsets == NULL) {
+ warning("dissolveEffect: out of memory");
+ return;
+ }
+
+ // Create a permutation of offsets into the frame buffer
+
+ if (width == 1 && height == 1) {
+ // Optimized case for pixel-by-pixel dissolve
+
+ for (i = 0; i < vs->size; i++)
+ offsets[i] = i;
+
+ for (i = 1; i < w * h; i++) {
+ int j;
+
+ j = getRandomNumber(i - 1);
+ offsets[i] = offsets[j];
+ offsets[j] = i;
+ }
+ } else {
+ int *offsets2;
+
+ for (i = 0, x = 0; x < vs->width; x += width)
+ for (y = 0; y < vs->height; y += height)
+ offsets[i++] = y * vs->width + x;
+
+ offsets2 = (int *) malloc(w * h * sizeof(int));
+ if (offsets2 == NULL) {
+ warning("dissolveEffect: out of memory");
+ free(offsets);
+ return;
+ }
+
+ memcpy(offsets2, offsets, w * h * sizeof(int));
+
+ for (i = 1; i < w * h; i++) {
+ int j;
+
+ j = getRandomNumber(i - 1);
+ offsets[i] = offsets[j];
+ offsets[j] = offsets2[i];
+ }
+
+ free(offsets2);
+ }
+
+ // Blit the image piece by piece to the screen. The idea here is that
+ // the whole update should take about a quarter of a second, assuming
+ // most of the time is spent in waitForTimer(). It looks good to me,
+ // but might still need some tuning.
+
+ updatePalette();
+
+ blits = 0;
+ blits_before_refresh = (3 * w * h) / 25;
+
+ for (i = 0; i < w * h; i++) {
+ x = offsets[i] % vs->width;
+ y = offsets[i] / vs->width;
+ _system->copy_rect(vs->screenPtr + vs->xstart + y * vs->width + x, vs->width, x, y, width, height);
+
+ if (++blits >= blits_before_refresh) {
+ blits = 0;
+ _system->update_screen();
+ waitForTimer(30);
+ }
+ }
+
+ free(offsets);
+
+ if (blits != 0) {
+ _system->update_screen();
+ waitForTimer(30);
+ }
}
-void Scumm::unkScreenEffect5(int a)
-{
+void Scumm::unkScreenEffect5(int a) {
+ // unkScreenEffect5(0), which is used by FOA during the opening
+ // cutscene when Indy opens the small statue, has been replaced by
+ // dissolveEffect(1, 1).
+ //
+ // I still don't know what unkScreenEffect5(1) is supposed to do.
+
/* XXX: not implemented */
- warning("stub unkScreenEffect5(%d)", a);
+ warning("stub unkScreenEffect(%d)", a);
}
void Scumm::setShake(int mode)
diff --git a/scumm/scumm.h b/scumm/scumm.h
index 8147020f33..613cde7945 100644
--- a/scumm/scumm.h
+++ b/scumm/scumm.h
@@ -55,8 +55,8 @@ enum {
NUM_SCRIPT_SLOT = 40,
NUM_LOCALSCRIPT = 60,
NUM_SHADOW_PALETTE = 8,
- MAX_ACTORS = 30,
- KEY_SET_OPTIONS = 3456 // WinCE
+ MAX_ACTORS = 30,
+ KEY_SET_OPTIONS = 3456 // WinCE
};
enum {
@@ -292,9 +292,9 @@ enum GameFeatures {
GF_DEFAULT = GF_USE_KEY,
GF_SMALL_HEADER = 32,
- GF_EXTERNAL_CHARSET = GF_SMALL_HEADER,
- GF_SMALL_NAMES = 64,
- GF_OLD_BUNDLE = 128,
+ GF_EXTERNAL_CHARSET = GF_SMALL_HEADER,
+ GF_SMALL_NAMES = 64,
+ GF_OLD_BUNDLE = 128,
GF_16COLOR = 256,
GF_OLD256 = 512,
GF_AUDIOTRACKS = 1024,
@@ -833,8 +833,8 @@ public:
void unkScreenEffect3();
void unkScreenEffect4();
void unkScreenEffect5(int a);
- void unkScreenEffect6();
void transitionEffect(int a); // former unkScreenEffect7
+ void dissolveEffect(int width, int height); // former unkScreenEffect5(0) and unkScreenEffect6
void decompressBomp(byte *dst, byte *src, int w, int h);
uint _shakeFrame;