[Scummvm-git-logs] scummvm master -> e04fca8b30288244cebbd8cc0feeb1e391ad9ded
criezy
criezy at scummvm.org
Mon May 31 22:46:36 UTC 2021
This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
c54bd2faf2 AGS: Implement pivot_sprite and rotate_sprite
e04fca8b30 GLK: Remove unnecessary TTS push state and pop state
Commit: c54bd2faf2b012f882129ab42a8e532aa646365b
https://github.com/scummvm/scummvm/commit/c54bd2faf2b012f882129ab42a8e532aa646365b
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2021-05-31T23:44:39+01:00
Commit Message:
AGS: Implement pivot_sprite and rotate_sprite
Changed paths:
A engines/ags/lib/allegro/rotate.cpp
A engines/ags/lib/allegro/rotate.h
engines/ags/lib/allegro/gfx.cpp
engines/ags/lib/allegro/gfx.h
engines/ags/module.mk
diff --git a/engines/ags/lib/allegro/gfx.cpp b/engines/ags/lib/allegro/gfx.cpp
index 88f7e98e5f..ed5432b34a 100644
--- a/engines/ags/lib/allegro/gfx.cpp
+++ b/engines/ags/lib/allegro/gfx.cpp
@@ -23,6 +23,7 @@
#include "ags/lib/allegro/gfx.h"
#include "ags/lib/allegro/color.h"
#include "ags/lib/allegro/flood.h"
+#include "ags/lib/allegro/rotate.h"
#include "ags/ags.h"
#include "ags/globals.h"
#include "common/textconsole.h"
@@ -170,11 +171,11 @@ void draw_sprite_vh_flip(BITMAP *bmp, const BITMAP *sprite, int x, int y) {
}
void rotate_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y, fixed angle) {
- error("TODO: rotate_sprite");
+ pivot_scaled_sprite(bmp, sprite, (x<<16) + (sprite->w * 0x10000) / 2, (y<<16) + (sprite->h * 0x10000) / 2, sprite->w << 15, sprite->h << 15, angle, 0x10000);
}
void pivot_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y, int cx, int cy, fixed angle) {
- error("TODO: pivot_sprite");
+ pivot_scaled_sprite(bmp, sprite, x<<16, y<<16, cx<<16, cy<<16, angle, 0x10000);
}
@@ -277,7 +278,7 @@ void _putpixel32(BITMAP *bmp, int x, int y, int color) {
*((uint32 *)p) = color;
}
-int getpixel(BITMAP *bmp, int x, int y) {
+int getpixel(const BITMAP *bmp, int x, int y) {
Graphics::ManagedSurface &surf = **bmp;
// Allegro returns -1 if the pixel lies outside the bitmap
@@ -300,7 +301,7 @@ int getpixel(BITMAP *bmp, int x, int y) {
error("Unsupported bpp");
}
-int _getpixel(BITMAP *bmp, int x, int y) {
+int _getpixel(const BITMAP *bmp, int x, int y) {
Graphics::ManagedSurface &surf = **bmp;
if (x < 0 || y < 0 || x >= surf.w || y >= surf.h)
return -1;
@@ -308,11 +309,11 @@ int _getpixel(BITMAP *bmp, int x, int y) {
return *((uint8 *)p);
}
-int _getpixel15(BITMAP *bmp, int x, int y) {
+int _getpixel15(const BITMAP *bmp, int x, int y) {
error("Unsupported bpp");
}
-int _getpixel16(BITMAP *bmp, int x, int y) {
+int _getpixel16(const BITMAP *bmp, int x, int y) {
Graphics::ManagedSurface &surf = **bmp;
if (x < 0 || y < 0 || x >= surf.w || y >= surf.h)
return -1;
@@ -320,11 +321,11 @@ int _getpixel16(BITMAP *bmp, int x, int y) {
return *((uint16 *)p);
}
-int _getpixel24(BITMAP *bmp, int x, int y) {
+int _getpixel24(const BITMAP *bmp, int x, int y) {
error("Unsupported bpp");
}
-int _getpixel32(BITMAP *bmp, int x, int y) {
+int _getpixel32(const BITMAP *bmp, int x, int y) {
Graphics::ManagedSurface &surf = **bmp;
if (x < 0 || y < 0 || x >= surf.w || y >= surf.h)
return -1;
diff --git a/engines/ags/lib/allegro/gfx.h b/engines/ags/lib/allegro/gfx.h
index d2907f8e6d..b74a5e1c13 100644
--- a/engines/ags/lib/allegro/gfx.h
+++ b/engines/ags/lib/allegro/gfx.h
@@ -224,12 +224,12 @@ extern void _putpixel15(BITMAP *bmp, int x, int y, int color);
extern void _putpixel16(BITMAP *bmp, int x, int y, int color);
extern void _putpixel24(BITMAP *bmp, int x, int y, int color);
extern void _putpixel32(BITMAP *bmp, int x, int y, int color);
-extern int getpixel(BITMAP *bmp, int x, int y);
-extern int _getpixel(BITMAP *bmp, int x, int y);
-extern int _getpixel15(BITMAP *bmp, int x, int y);
-extern int _getpixel16(BITMAP *bmp, int x, int y);
-extern int _getpixel24(BITMAP *bmp, int x, int y);
-extern int _getpixel32(BITMAP *bmp, int x, int y);
+extern int getpixel(const BITMAP *bmp, int x, int y);
+extern int _getpixel(const BITMAP *bmp, int x, int y);
+extern int _getpixel15(const BITMAP *bmp, int x, int y);
+extern int _getpixel16(const BITMAP *bmp, int x, int y);
+extern int _getpixel24(const BITMAP *bmp, int x, int y);
+extern int _getpixel32(const BITMAP *bmp, int x, int y);
extern void line(BITMAP *bmp, int x1, int y_1, int x2, int y2, int color);
extern void rect(BITMAP *bmp, int x1, int y_1, int x2, int y2, int color);
extern void rectfill(BITMAP *bmp, int x1, int y_1, int x2, int y2, int color);
diff --git a/engines/ags/lib/allegro/rotate.cpp b/engines/ags/lib/allegro/rotate.cpp
new file mode 100644
index 0000000000..b3a2b2e1ae
--- /dev/null
+++ b/engines/ags/lib/allegro/rotate.cpp
@@ -0,0 +1,374 @@
+#include "ags/lib/allegro/rotate.h"
+#include "ags/lib/allegro/gfx.h"
+#include "common/scummsys.h"
+
+namespace AGS3 {
+
+/* rotate_scale_coordinates:
+ * Calculates the coordinates for the rotated, scaled and flipped sprite,
+ * and passes them on to the given function.
+ */
+void rotate_scale_coordinates(fixed w, fixed h,
+ fixed x, fixed y, fixed cx, fixed cy,
+ fixed angle,
+ fixed scale_x, fixed scale_y,
+ fixed xs[4], fixed ys[4])
+{
+ // Setting angle to the range -180...180 degrees makes sin & cos more numerically stable.
+ // (Yes, this does have an effect for big angles!)
+ // Note that using "real" sin() and cos() gives much better precision than fixsin() and fixcos().
+ angle = angle & 0xffffff;
+ if (angle >= 0x800000)
+ angle -= 0x1000000;
+
+ double angle_radian = angle * (M_PI / (double)0x800000);
+ double sin_angle = sin(angle_radian);
+ double cos_angle = cos(angle_radian);
+
+ fixed fix_cos, fix_sin;
+ if (cos_angle >= 0)
+ fix_cos = (int)(cos_angle * 0x10000 + 0.5);
+ else
+ fix_cos = (int)(cos_angle * 0x10000 - 0.5);
+ if (sin_angle >= 0)
+ fix_sin = (int)(sin_angle * 0x10000 + 0.5);
+ else
+ fix_sin = (int)(sin_angle * 0x10000 - 0.5);
+
+ /* Decide what order to take corners in. */
+ int tl = 0, tr = 1, bl = 3, br = 2;
+
+ /* Calculate new coordinates of all corners. */
+ w = fixmul(w, scale_x);
+ h = fixmul(h, scale_y);
+ cx = fixmul(cx, scale_x);
+ cy = fixmul(cy, scale_y);
+
+ fixed xofs = x - fixmul(cx, fix_cos) + fixmul(cy, fix_sin);
+ fixed yofs = y - fixmul(cx, fix_sin) - fixmul(cy, fix_cos);
+
+ xs[tl] = xofs;
+ ys[tl] = yofs;
+ xs[tr] = xofs + fixmul(w, fix_cos);
+ ys[tr] = yofs + fixmul(w, fix_sin);
+ xs[bl] = xofs - fixmul(h, fix_sin);
+ ys[bl] = yofs + fixmul(h, fix_cos);
+
+ xs[br] = xs[tr] + xs[bl] - xs[tl];
+ ys[br] = ys[tr] + ys[bl] - ys[tl];
+}
+
+/* parallelogram_map:
+ * Worker routine for drawing rotated and/or scaled and/or flipped sprites:
+ * It actually maps the sprite to any parallelogram-shaped area of the
+ * bitmap. The top left corner is mapped to (xs[0], ys[0]), the top right to
+ * (xs[1], ys[1]), the bottom right to x (xs[2], ys[2]), and the bottom left
+ * to (xs[3], ys[3]). The corners are assumed to form a perfect
+ * parallelogram, i.e. xs[0]+xs[2] = xs[1]+xs[3]. The corners are given in
+ * fixed point format, so xs[] and ys[] are coordinates of the outer corners
+ * of corner pixels in clockwise order beginning with top left.
+ * All coordinates begin with 0 in top left corner of pixel (0, 0). So a
+ * rotation by 0 degrees of a sprite to the top left of a bitmap can be
+ * specified with coordinates (0, 0) for the top left pixel in source
+ * bitmap. With the default scanline drawer, a pixel in the destination
+ * bitmap is drawn if and only if its center is covered by any pixel in the
+ * sprite. The color of this covering sprite pixel is used to draw.
+ */
+void parallelogram_map(BITMAP *bmp, const BITMAP *spr, fixed xs[4], fixed ys[4]) {
+ // Get index of topmost point.
+ int top_index = 0;
+ if (ys[1] < ys[0])
+ top_index = 1;
+ if (ys[2] < ys[top_index])
+ top_index = 2;
+ if (ys[3] < ys[top_index])
+ top_index = 3;
+
+ // Get direction of points: clockwise or anti-clockwise.
+ int right_index = (double)(xs[(top_index+1) & 3] - xs[top_index]) *
+ (double)(ys[(top_index-1) & 3] - ys[top_index]) >
+ (double)(xs[(top_index-1) & 3] - xs[top_index]) *
+ (double)(ys[(top_index+1) & 3] - ys[top_index]) ? 1 : -1;
+
+ // Get coordinates of the corners.
+ // Coordinates in bmp and sprite ordered as top-right-bottom-left.
+ fixed corner_bmp_x[4], corner_bmp_y[4];
+ fixed corner_spr_x[4], corner_spr_y[4];
+ int index = top_index;
+ for (int i = 0; i < 4; i++) {
+ corner_bmp_x[i] = xs[index];
+ corner_bmp_y[i] = ys[index];
+ if (index < 2)
+ corner_spr_y[i] = 0;
+ else
+ // Need `- 1' since otherwise it would be outside sprite.
+ corner_spr_y[i] = (spr->h << 16) - 1;
+ if ((index == 0) || (index == 3))
+ corner_spr_x[i] = 0;
+ else
+ corner_spr_x[i] = (spr->w << 16) - 1;
+ index = (index + right_index) & 3;
+ }
+
+ // Get scanline starts, ends and deltas, and clipping coordinates.
+ #define top_bmp_y corner_bmp_y[0]
+ #define right_bmp_y corner_bmp_y[1]
+ #define bottom_bmp_y corner_bmp_y[2]
+ #define left_bmp_y corner_bmp_y[3]
+ #define top_bmp_x corner_bmp_x[0]
+ #define right_bmp_x corner_bmp_x[1]
+ #define bottom_bmp_x corner_bmp_x[2]
+ #define left_bmp_x corner_bmp_x[3]
+ #define top_spr_y corner_spr_y[0]
+ #define right_spr_y corner_spr_y[1]
+ #define bottom_spr_y corner_spr_y[2]
+ #define left_spr_y corner_spr_y[3]
+ #define top_spr_x corner_spr_x[0]
+ #define right_spr_x corner_spr_x[1]
+ #define bottom_spr_x corner_spr_x[2]
+ #define left_spr_x corner_spr_x[3]
+
+ // Calculate left and right clipping.
+ fixed clip_left, clip_right;
+ if (bmp->clip) {
+ clip_left = bmp->cl << 16;
+ clip_right = (bmp->cr << 16) - 1;
+ } else {
+ clip_left = 0;
+ clip_right = (bmp->w << 16) - 1;
+ }
+
+ // Stop if we're totally outside.
+ if ((left_bmp_x > clip_right) && (top_bmp_x > clip_right) && (bottom_bmp_x > clip_right))
+ return;
+ if ((right_bmp_x < clip_left) && (top_bmp_x < clip_left) && (bottom_bmp_x < clip_left))
+ return;
+
+ // Bottom clipping.
+ int clip_bottom_i = (bottom_bmp_y + 0x8000) >> 16;
+ if (bmp->clip) {
+ if (clip_bottom_i > bmp->cb)
+ clip_bottom_i = bmp->cb;
+ }
+
+ // Calculate y coordinate of first scanline.
+ int bmp_y_i = (top_bmp_y + 0x8000) >> 16;
+ if (bmp->clip) {
+ if (bmp_y_i < bmp->ct)
+ bmp_y_i = bmp->ct;
+ }
+
+ // Sprite is above or below bottom clipping area.
+ if (bmp_y_i >= clip_bottom_i)
+ return;
+
+ // Vertical gap between top corner and centre of topmost scanline.
+ fixed extra_scanline_fraction = (bmp_y_i << 16) + 0x8000 - top_bmp_y;
+ // Calculate x coordinate of beginning of scanline in bmp.
+ fixed l_bmp_dx = fixdiv(left_bmp_x - top_bmp_x, left_bmp_y - top_bmp_y);
+ fixed l_bmp_x = top_bmp_x + fixmul(extra_scanline_fraction, l_bmp_dx);
+ // Calculate x coordinate of beginning of scanline in spr.
+ // note: all these are rounded down which is probably a Good Thing (tm)
+ fixed l_spr_dx = fixdiv(left_spr_x - top_spr_x, left_bmp_y - top_bmp_y);
+ fixed l_spr_x = top_spr_x + fixmul(extra_scanline_fraction, l_spr_dx);
+ // Calculate y coordinate of beginning of scanline in spr.
+ fixed l_spr_dy = fixdiv(left_spr_y - top_spr_y, left_bmp_y - top_bmp_y);
+ fixed l_spr_y = top_spr_y + fixmul(extra_scanline_fraction, l_spr_dy);
+
+ // Calculate left loop bound.
+ int l_bmp_y_bottom_i = (left_bmp_y + 0x8000) >> 16;
+ if (l_bmp_y_bottom_i > clip_bottom_i)
+ l_bmp_y_bottom_i = clip_bottom_i;
+
+ // Calculate x coordinate of end of scanline in bmp.
+ fixed r_bmp_dx = fixdiv(right_bmp_x - top_bmp_x, right_bmp_y - top_bmp_y);
+ fixed r_bmp_x = top_bmp_x + fixmul(extra_scanline_fraction, r_bmp_dx);
+
+ // Calculate right loop bound.
+ int r_bmp_y_bottom_i = (right_bmp_y + 0x8000) >> 16;
+
+ // Get dx and dy, the offsets to add to the source coordinates as we move
+ // one pixel rightwards along a scanline. This formula can be derived by
+ // considering the 2x2 matrix that transforms the sprite to the
+ // parallelogram.
+ // We'd better use double to get this as exact as possible, since any
+ // errors will be accumulated along the scanline.
+ fixed spr_dx = (fixed)((ys[3] - ys[0]) * 65536.0 * (65536.0 * spr->w) /
+ ((xs[1] - xs[0]) * (double)(ys[3] - ys[0]) - (xs[3] - xs[0]) * (double)(ys[1] - ys[0])));
+ fixed spr_dy = (fixed)((ys[1] - ys[0]) * 65536.0 * (65536.0 * spr->h) /
+ ((xs[3] - xs[0]) * (double)(ys[1] - ys[0]) - (xs[1] - xs[0]) * (double)(ys[3] - ys[0])));
+
+ bool sameFormat = (spr->format == bmp->format);
+ uint32 transColor = 0, alphaMask = 0xff;
+ if (spr->format.bytesPerPixel != 1) {
+ transColor = spr->format.ARGBToColor(0, 255, 0, 255);
+ alphaMask = spr->format.ARGBToColor(255, 0, 0, 0);
+ alphaMask = ~alphaMask;
+ }
+
+ // Loop through scanlines.
+ while (1) {
+ // Has beginning of scanline passed a corner?
+ if (bmp_y_i >= l_bmp_y_bottom_i) {
+ // Are we done?
+ if (bmp_y_i >= clip_bottom_i)
+ break;
+
+ // Vertical gap between left corner and centre of scanline.
+ extra_scanline_fraction = (bmp_y_i << 16) + 0x8000 - left_bmp_y;
+ // Update x coordinate of beginning of scanline in bmp.
+ l_bmp_dx = fixdiv(bottom_bmp_x - left_bmp_x, bottom_bmp_y - left_bmp_y);
+ l_bmp_x = left_bmp_x + fixmul(extra_scanline_fraction, l_bmp_dx);
+ // Update x coordinate of beginning of scanline in spr.
+ l_spr_dx = fixdiv(bottom_spr_x - left_spr_x, bottom_bmp_y - left_bmp_y);
+ l_spr_x = left_spr_x + fixmul(extra_scanline_fraction, l_spr_dx);
+ // Update y coordinate of beginning of scanline in spr.
+ l_spr_dy = fixdiv(bottom_spr_y - left_spr_y, bottom_bmp_y - left_bmp_y);
+ l_spr_y = left_spr_y + fixmul(extra_scanline_fraction, l_spr_dy);
+
+ // Update loop bound.
+ l_bmp_y_bottom_i = (bottom_bmp_y + 0x8000) >> 16;
+ if (l_bmp_y_bottom_i > clip_bottom_i)
+ l_bmp_y_bottom_i = clip_bottom_i;
+ }
+
+ // Has end of scanline passed a corner?
+ if (bmp_y_i >= r_bmp_y_bottom_i) {
+ // Vertical gap between right corner and centre of scanline.
+ extra_scanline_fraction = (bmp_y_i << 16) + 0x8000 - right_bmp_y;
+ // Update x coordinate of end of scanline in bmp.
+ r_bmp_dx = fixdiv(bottom_bmp_x - right_bmp_x, bottom_bmp_y - right_bmp_y);
+ r_bmp_x = right_bmp_x + fixmul(extra_scanline_fraction, r_bmp_dx);
+
+ // Update loop bound: We aren't supposed to use this any more, so
+ // just set it to some big enough value.
+ r_bmp_y_bottom_i = clip_bottom_i;
+ }
+
+ // Make left bmp coordinate be an integer and clip it.
+ fixed l_bmp_x_rounded;
+ l_bmp_x_rounded = (l_bmp_x + 0x8000) & ~0xffff;
+ if (l_bmp_x_rounded < clip_left)
+ l_bmp_x_rounded = clip_left;
+
+ // ... and move starting point in sprite accordingly.
+ fixed l_spr_x_rounded = l_spr_x + fixmul(l_bmp_x_rounded + 0x7fff - l_bmp_x, spr_dx);
+ fixed l_spr_y_rounded = l_spr_y + fixmul(l_bmp_x_rounded + 0x7fff - l_bmp_x, spr_dy);
+
+ // Make right bmp coordinate be an integer and clip it.
+ fixed r_bmp_x_rounded = (r_bmp_x - 0x8000) & ~0xffff;
+ if (r_bmp_x_rounded > clip_right)
+ r_bmp_x_rounded = clip_right;
+
+ // Draw!
+ if (l_bmp_x_rounded <= r_bmp_x_rounded) {
+ /* The bodies of these ifs are only reached extremely seldom,
+ it's an ugly hack to avoid reading outside the sprite when
+ the rounding errors are accumulated the wrong way. It would
+ be nicer if we could ensure that this never happens by making
+ all multiplications and divisions be rounded up or down at
+ the correct places.
+ I did try another approach: recalculate the edges of the
+ scanline from scratch each scanline rather than incrementally.
+ Drawing a sprite with that routine took about 25% longer time
+ though.
+ */
+ if ((unsigned)(l_spr_x_rounded >> 16) >= (unsigned)spr->w) {
+ if (((l_spr_x_rounded < 0) && (spr_dx <= 0)) || ((l_spr_x_rounded > 0) && (spr_dx >= 0))) {
+ // This can happen.
+ goto skip_draw;
+ } else {
+ // I don't think this can happen, but I can't prove it.
+ do {
+ l_spr_x_rounded += spr_dx;
+ l_bmp_x_rounded += 65536;
+ if (l_bmp_x_rounded > r_bmp_x_rounded)
+ goto skip_draw;
+ } while ((unsigned)(l_spr_x_rounded >> 16) >= (unsigned)spr->w);
+ }
+ }
+ int right_edge_test = l_spr_x_rounded + ((r_bmp_x_rounded - l_bmp_x_rounded) >> 16) * spr_dx;
+ if ((unsigned)(right_edge_test >> 16) >= (unsigned)spr->w) {
+ if (((right_edge_test < 0) && (spr_dx <= 0)) || ((right_edge_test > 0) && (spr_dx >= 0))) {
+ // This can happen.
+ do {
+ r_bmp_x_rounded -= 65536;
+ right_edge_test -= spr_dx;
+ if (l_bmp_x_rounded > r_bmp_x_rounded)
+ goto skip_draw;
+ } while ((unsigned)(right_edge_test >> 16) >= (unsigned)spr->w);
+ } else {
+ // I don't think this can happen, but I can't prove it.
+ goto skip_draw;
+ }
+ }
+ if ((unsigned)(l_spr_y_rounded >> 16) >= (unsigned)spr->h) {
+ if (((l_spr_y_rounded < 0) && (spr_dy <= 0)) || ((l_spr_y_rounded > 0) && (spr_dy >= 0))) {
+ // This can happen.
+ goto skip_draw;
+ } else {
+ // I don't think this can happen, but I can't prove it.
+ do {
+ l_spr_y_rounded += spr_dy;
+ l_bmp_x_rounded += 65536;
+ if (l_bmp_x_rounded > r_bmp_x_rounded)
+ goto skip_draw;
+ } while (((unsigned)l_spr_y_rounded >> 16) >= (unsigned)spr->h);
+ }
+ }
+ right_edge_test = l_spr_y_rounded + ((r_bmp_x_rounded - l_bmp_x_rounded) >> 16) * spr_dy;
+ if ((unsigned)(right_edge_test >> 16) >= (unsigned)spr->h) {
+ if (((right_edge_test < 0) && (spr_dy <= 0)) || ((right_edge_test > 0) && (spr_dy >= 0))) {
+ // This can happen.
+ do {
+ r_bmp_x_rounded -= 65536;
+ right_edge_test -= spr_dy;
+ if (l_bmp_x_rounded > r_bmp_x_rounded)
+ goto skip_draw;
+ } while ((unsigned)(right_edge_test >> 16) >= (unsigned)spr->h);
+ } else {
+ // I don't think this can happen, but I can't prove it.
+ goto skip_draw;
+ }
+ }
+
+ // draw scanline
+ int r_bmp_x_i = (r_bmp_x_rounded >> 16);
+ int l_bmp_x_i = (l_bmp_x_rounded >> 16);
+ for (; l_bmp_x_i <= r_bmp_x_i; ++l_bmp_x_i) {
+ uint32 c = (uint32)getpixel(spr, l_spr_x_rounded >> 16, l_spr_y_rounded >> 16);
+ if ((c & alphaMask) != transColor) {
+ if (!sameFormat) {
+ uint8 a, r, g, b;
+ spr->format.colorToARGB(c, a, r, g, b);
+ c = bmp->format.ARGBToColor(a, r, g, b);
+ }
+ putpixel(bmp, l_bmp_x_i, bmp_y_i, c);
+ }
+ l_spr_x_rounded += spr_dx;
+ l_spr_y_rounded += spr_dy;
+ }
+ }
+ // I'm not going to apoligize for this label and its gotos.
+ // to get rid of it would just make the code look worse.
+ skip_draw:
+
+ // Jump to next scanline.
+ bmp_y_i++;
+ // Update beginning of scanline.
+ l_bmp_x += l_bmp_dx;
+ l_spr_x += l_spr_dx;
+ l_spr_y += l_spr_dy;
+ // Update end of scanline.
+ r_bmp_x += r_bmp_dx;
+ }
+}
+
+void pivot_scaled_sprite(BITMAP *bmp, const BITMAP *sprite, fixed x, fixed y, fixed cx, fixed cy, fixed angle, fixed scale) {
+ fixed xs[4], ys[4];
+ rotate_scale_coordinates(sprite->w << 16, sprite->h << 16,
+ x, y, cx, cy, angle, scale, scale, xs, ys);
+ parallelogram_map(bmp, sprite, xs, ys);
+}
+
+} // namespace AGS3
diff --git a/engines/ags/lib/allegro/rotate.h b/engines/ags/lib/allegro/rotate.h
new file mode 100644
index 0000000000..bcc73f7730
--- /dev/null
+++ b/engines/ags/lib/allegro/rotate.h
@@ -0,0 +1,36 @@
+
+/* 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef AGS_LIB_ALLEGRO_ROTATE_H
+#define AGS_LIB_ALLEGRO_ROTATE_H
+
+#include "ags/lib/allegro/surface.h"
+#include "ags/lib/allegro/fixed.h"
+
+namespace AGS3 {
+
+extern void pivot_scaled_sprite(BITMAP *bmp, const BITMAP *sprite, fixed x, fixed y, fixed cx, fixed cy, fixed angle, fixed scale);
+
+} // namespace AGS3
+
+#endif
diff --git a/engines/ags/module.mk b/engines/ags/module.mk
index 981b1f47b8..2bf9cd4492 100644
--- a/engines/ags/module.mk
+++ b/engines/ags/module.mk
@@ -23,6 +23,7 @@ MODULE_OBJS = \
lib/allegro/keyboard.o \
lib/allegro/math.o \
lib/allegro/mouse.o \
+ lib/allegro/rotate.o \
lib/allegro/surface.o \
lib/allegro/system.o \
lib/allegro/unicode.o \
Commit: e04fca8b30288244cebbd8cc0feeb1e391ad9ded
https://github.com/scummvm/scummvm/commit/e04fca8b30288244cebbd8cc0feeb1e391ad9ded
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2021-05-31T23:44:39+01:00
Commit Message:
GLK: Remove unnecessary TTS push state and pop state
Changed paths:
engines/glk/speech.cpp
diff --git a/engines/glk/speech.cpp b/engines/glk/speech.cpp
index dacb0a3b91..dda328e132 100644
--- a/engines/glk/speech.cpp
+++ b/engines/glk/speech.cpp
@@ -76,7 +76,6 @@ SpeechManager::SpeechManager() :
return;
_ttsMan = g_system->getTextToSpeechManager();
if (_ttsMan != nullptr) {
- _ttsMan->pushState();
// Language
_ttsMan->setLanguage(ConfMan.get("language"));
// Volume
@@ -101,10 +100,6 @@ SpeechManager::SpeechManager() :
SpeechManager::~SpeechManager() {
#if defined(USE_TTS)
debugC(kDebugSpeech, "Destroy Glk::SpeechManager");
- if (_ttsMan != nullptr) {
- _ttsMan->popState();
- _ttsMan = nullptr;
- }
#endif
}
More information about the Scummvm-git-logs
mailing list