[Scummvm-git-logs] scummvm master -> 6a4062d3fc75e888ba293c860e54b59c3b12f3f3
dreammaster
dreammaster at scummvm.org
Wed Jul 21 03:27:26 UTC 2021
This automated email contains information about 5 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
930be67a9f AGS: Adding AGSWaves draw methods
74be1d8fd7 AGS: Further fleshing out AGSWaves gfx methods
f5afbc964d AGS: Implemented AGSWaves weather methods
aadd100b9c AGS: Implementing AGSWaves sound methods
6a4062d3fc AGS: Fix some comments in call_function
Commit: 930be67a9f25d767837ce788e03a8924743dc4cb
https://github.com/scummvm/scummvm/commit/930be67a9f25d767837ce788e03a8924743dc4cb
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-20T20:25:53-07:00
Commit Message:
AGS: Adding AGSWaves draw methods
Changed paths:
engines/ags/plugins/ags_waves/ags_waves.cpp
engines/ags/plugins/ags_waves/ags_waves.h
engines/ags/plugins/ags_waves/draw.cpp
engines/ags/plugins/ags_waves/vars.h
diff --git a/engines/ags/plugins/ags_waves/ags_waves.cpp b/engines/ags/plugins/ags_waves/ags_waves.cpp
index 1c879ec951..b995fc7d71 100644
--- a/engines/ags/plugins/ags_waves/ags_waves.cpp
+++ b/engines/ags/plugins/ags_waves/ags_waves.cpp
@@ -99,11 +99,6 @@ void AGSWaves::AGS_EngineStartup(IAGSEngine *engine) {
SCRIPT_METHOD(SetWalkbehindBaserine, AGSWaves::SetWalkbehindBaserine);
}
-void AGSWaves::DrawScreenEffect(ScriptMethodParams ¶ms) {
- PARAMS4(int, sprite, int, sprite_prev, int, ide, int, n);
- DrawEffect(sprite, sprite_prev, ide, n);
-}
-
void AGSWaves::SFX_Play(ScriptMethodParams ¶ms) {
//PARAMS2(int, SFX, int, repeat);
}
@@ -160,22 +155,6 @@ void AGSWaves::SFX_Filter(ScriptMethodParams ¶ms) {
//PARAMS2(int, SFX, int, enable);
}
-void AGSWaves::DrawBlur(ScriptMethodParams ¶ms) {
- //PARAMS2(int, spriteD, int, radius);
-}
-
-void AGSWaves::DrawTunnel(ScriptMethodParams ¶ms) {
- //PARAMS3(int, spriteD, float, scale, float, speed);
-}
-
-void AGSWaves::DrawCylinder(ScriptMethodParams ¶ms) {
- //PARAMS2(int, spriteD, int, ogsprite);
-}
-
-void AGSWaves::DrawForceField(ScriptMethodParams ¶ms) {
- //PARAMS4(int, spriteD, int, scale, float, speed, int, id);
-}
-
void AGSWaves::Grayscale(ScriptMethodParams ¶ms) {
//PARAMS1(int, sprite);
}
diff --git a/engines/ags/plugins/ags_waves/ags_waves.h b/engines/ags/plugins/ags_waves/ags_waves.h
index 5b4e646172..1d1eb163cc 100644
--- a/engines/ags/plugins/ags_waves/ags_waves.h
+++ b/engines/ags/plugins/ags_waves/ags_waves.h
@@ -90,6 +90,31 @@ private:
void CastWave(int delayMax, int PixelsWide, int n);
void DrawEffect(int sprite_a, int sprite_b, int id, int n);
+ inline static int getRcolor(int color) {
+ return ((color >> 16) & 0xFF);
+ }
+ inline static int getGcolor(int color) {
+ return ((color >> 8) & 0xFF);
+ }
+ inline static int getBcolor(int color) {
+ return ((color >> 0) & 0xFF);
+ }
+ inline static int getAcolor(int color) {
+ return ((color >> 24) & 0xFF);
+ }
+ static int SetColorRGBA(int r, int g, int b, int a);
+ float noiseField(float tx, float ty, float tz);
+
+
+ static inline float fracts(float value) {
+ return value - floor(value);
+ }
+ static inline float lerp(float x, float y, float fn) {
+ return x * (1.0 - fn) + y * fn;
+ }
+ static inline float hasher(float n) {
+ return fracts(sin(n) * 153.5453123);
+ }
public:
AGSWaves() : PluginBase(), Vars() {}
virtual ~AGSWaves() {}
diff --git a/engines/ags/plugins/ags_waves/draw.cpp b/engines/ags/plugins/ags_waves/draw.cpp
index 53a7fe9fdd..35ca05c513 100644
--- a/engines/ags/plugins/ags_waves/draw.cpp
+++ b/engines/ags/plugins/ags_waves/draw.cpp
@@ -20,6 +20,7 @@
*
*/
+#include "common/util.h"
#include "ags/plugins/ags_waves/ags_waves.h"
#include "ags/ags.h"
@@ -27,6 +28,299 @@ namespace AGS3 {
namespace Plugins {
namespace AGSWaves {
+void AGSWaves::DrawScreenEffect(ScriptMethodParams ¶ms) {
+ PARAMS4(int, sprite, int, sprite_prev, int, ide, int, n);
+ DrawEffect(sprite, sprite_prev, ide, n);
+}
+
+void AGSWaves::DrawBlur(ScriptMethodParams ¶ms) {
+ PARAMS2(int, spriteD, int, radius);
+
+ int spriteD2 = spriteD;
+ BITMAP *src = _engine->GetSpriteGraphic(spriteD);
+ BITMAP *src2 = _engine->GetSpriteGraphic(spriteD2);
+
+ uint32 **pixelb = (uint32 **)_engine->GetRawBitmapSurface(src);
+ uint32 **pixela = (uint32 **)_engine->GetRawBitmapSurface(src2);
+ _engine->ReleaseBitmapSurface(src2);
+ int src_width = 640;
+ int src_height = 360;
+ int src_depth = 32;
+
+ _engine->GetBitmapDimensions(src, &src_width, &src_height, &src_depth);
+
+
+ int x, y;
+ for (y = 0; y < src_height; y++) {
+ for (x = 0; x < src_width; x++) {
+ int totalRed = 0;
+ int totalGreen = 0;
+ int totalBlue = 0;
+
+ int vx = -(radius);
+ int pixels_parsed = 0;
+
+ int setY = y;
+ if (setY < 0) setY = 0;
+ if (setY > src_height - 1) setY = src_height - 1;
+
+ while (vx < (radius)+1) {
+ int setX = x + vx;
+ if (setX < 0) setX = 0;
+ if (setX > src_width - 1) setX = src_width - 1;
+
+
+ int color = pixela[setY][setX];
+
+ totalRed += getRcolor(color);
+ totalGreen += getGcolor(color);
+ totalBlue += getBcolor(color);
+
+ pixels_parsed++;
+ vx++;
+ }
+
+ int rN = totalRed / pixels_parsed;
+ int gN = totalGreen / pixels_parsed;
+ int bN = totalBlue / pixels_parsed;
+
+ int r = CLIP(rN, 0, 255);
+ int g = CLIP(gN, 0, 255);
+ int b = CLIP(bN, 0, 255);
+
+ pixelb[y][x] = ((r << 16) | (g << 8) | (b << 0) | (255 << 24));
+ }
+ }
+
+
+ _engine->ReleaseBitmapSurface(src);
+ src = _engine->GetSpriteGraphic(spriteD);
+
+ x = 0;
+ y = 0;
+ for (y = 0; y < src_height; y++) {
+ for (x = 0; x < src_width; x++) {
+ int totalRed = 0;
+ int totalGreen = 0;
+ int totalBlue = 0;
+
+ int pixels_parsed = 0;
+ int setX = x;
+ if (setX < 0) setX = 0;
+ if (setX > src_width - 1) setX = src_width - 1;
+
+ int vy = -(radius);
+ while (vy < (radius)+1) {
+ int setY = y + vy;
+ if (setY < 0) setY = 0;
+ if (setY > src_height - 1) setY = src_height - 1;
+
+ int color = pixela[setY][setX];
+
+ totalRed += getRcolor(color);
+ totalGreen += getGcolor(color);
+ totalBlue += getBcolor(color);
+
+ pixels_parsed++;
+
+ vy++;
+ }
+
+ int rN = totalRed / pixels_parsed;
+ int gN = totalGreen / pixels_parsed;
+ int bN = totalBlue / pixels_parsed;
+
+ int r = CLIP(rN, 0, 255);
+ int g = CLIP(gN, 0, 255);
+ int b = CLIP(bN, 0, 255);
+
+ pixelb[y][x] = ((r << 16) | (g << 8) | (b << 0) | (255 << 24));
+ }
+ }
+
+ _engine->ReleaseBitmapSurface(src);
+}
+
+void AGSWaves::DrawTunnel(ScriptMethodParams ¶ms) {
+ PARAMS3(int, spriteD, float, scale, float, speed);
+
+ d_time = speed;
+ BITMAP *src = _engine->GetSpriteGraphic(spriteD);
+ uint32 **pixela = (uint32 **)_engine->GetRawBitmapSurface(src);
+ int src_width = 640;
+ int src_height = 360;
+ int src_depth = 32;
+ _engine->GetBitmapDimensions(src, &src_width, &src_height, &src_depth);
+
+ BITMAP *src2 = _engine->GetSpriteGraphic(int(scale));
+ uint32 **pixelb = (uint32 **)_engine->GetRawBitmapSurface(src2);
+ int h = screenHeight;
+ int w = screenWidth;
+ if (!generateonce) {
+ generateonce = true;
+ //generate texture
+ for (int y = 0; y < texHeight; y++) {
+ for (int x = 0; x < texWidth; x++) {
+ texture[y][x] = pixelb[y][x];
+ }
+ }
+
+ //generate non-linear transformation table
+ for (int y = 0; y < h; y++) {
+ for (int x = 0; x < w; x++) {
+ int angle, distance;
+ float ratio = 32.0;
+ distance = int(ratio * texHeight / sqrt((x - w / 2.0) * (x - w / 2.0) + (y - h / 2.0) * (y - h / 2.0))) % texHeight;
+ angle = (uint32)(0.5 * texWidth * atan2(y - h / 2.0, x - w / 2.0) / 3.1416);
+ distanceTable[y][x] = distance;///4.0;
+ angleTable[y][x] = angle;
+ }
+ }
+ }
+
+ int shiftX = int(texWidth * 0.75 * d_time);
+ int shiftY = int(texHeight * 1.0 * d_time);
+
+ for (int y = 0; y < h; y++) {
+ for (int x = 0; x < w; x++) {
+ //get the texel from the texture by using the tables, shifted with the animation values
+ int color = texture[(uint32)(distanceTable[y][x] + shiftX) % texWidth][(uint32)(angleTable[y][x] + shiftY) % texHeight];
+
+ pixela[y][x] = color;
+ }
+ }
+
+ _engine->ReleaseBitmapSurface(src2);
+ _engine->ReleaseBitmapSurface(src);
+}
+
+void AGSWaves::DrawCylinder(ScriptMethodParams ¶ms) {
+ PARAMS2(int, spriteD, int, ogsprite);
+
+ BITMAP *src = _engine->GetSpriteGraphic(spriteD);
+ uint32 **pixela = (uint32 **)_engine->GetRawBitmapSurface(src);
+ int src_width = 640;
+ int src_height = 640;
+ int src_depth = 32;
+ _engine->GetBitmapDimensions(src, &src_width, &src_height, &src_depth);
+
+ BITMAP *src2 = _engine->GetSpriteGraphic(ogsprite);
+ uint32 **pixelb = (uint32 **)_engine->GetRawBitmapSurface(src2);
+ _engine->ReleaseBitmapSurface(src2);
+ int height = src_height;
+ int width = src_width;
+
+ for (int y = 0; y < height; y++) {
+ for (int x = 0; x < width; x++) {
+ //convertPoint(x,y,width,height);
+
+ //center the point at 0,0
+ float pcx = x - width / 2;
+ float pcy = y - height / 2;
+
+ //these are your free parameters
+ float f = width / 2;
+ float r = width;
+
+ float omega = width / 2;
+ float z0 = f - sqrt(r * r - omega * omega);
+ float zc = (2 * z0 + sqrt(4 * z0 * z0 - 4 * (pcx * pcx / (f * f) + 1) * (z0 * z0 - r * r))) / (2 * (pcx * pcx / (f * f) + 1));
+
+ float finalpointx = pcx * zc / f;
+ float finalpointy = pcy * zc / f;
+ finalpointx += width / 2;
+ finalpointy += height / 2;
+
+
+ int cposx = finalpointx;
+ int cposy = finalpointy;
+ if (cposx < 0 ||
+ cposx > width - 1 ||
+ cposy < 0 ||
+ cposy > height - 1) {
+ pixela[y][x] = SetColorRGBA(0, 0, 0, 0);
+ } else {
+ pixela[y][x] = pixelb[cposy][cposx];
+ }
+ }
+ }
+
+ _engine->ReleaseBitmapSurface(src);
+}
+
+void AGSWaves::DrawForceField(ScriptMethodParams ¶ms) {
+ PARAMS4(int, spriteD, int, scale, float, speed, int, id);
+
+ if (id < 0 || id >4) {
+ return;
+ }
+ if (b_time[id] == NULL) b_time[id] = 1.0;
+ if (b_time[id] < 1.0) b_time[id] = 1.0;
+ b_time[id] += speed;
+ BITMAP *src = _engine->GetSpriteGraphic(spriteD);
+
+ uint32 **pixelb = (uint32 **)_engine->GetRawBitmapSurface(src);
+
+ int src_width = 640;
+ int src_height = 360;
+ int src_depth = 32;
+
+ _engine->GetBitmapDimensions(src, &src_width, &src_height, &src_depth);
+
+
+ int x, y;
+ for (y = 0; y < src_height; y++) {
+ for (x = 0; x < src_width; x++) {
+ int setY = y;
+ if (setY < 0) setY = 0;
+ int setX = x;
+ if (setX < 0) setX = 0;
+
+ float uvx = float(x) / float(scale);
+ float uvy = float(y) / float(scale);
+
+ float jx = uvx;
+ float jy = uvy + b_time[id] * 3.14;
+ float jz = sin(b_time[id]);
+ float jyy = uvy + b_time[id];
+ float jzz = cos(b_time[id] + 3.0);
+
+ float af = ABS(noiseField(jx, jy, jz) - noiseField(jx, jyy, jzz));
+ float newR = 0.5 - pow(af, float(0.2)) / 2.0;
+ float newG = 0.0;
+ float newB = 0.4 - pow(af, float(0.4));
+
+ int Rd = int(newR * 255.0);
+ int Gd = int(newG * 255.0);
+ int Bd = int(newB * 255.0);
+ int na = int(1.0 * 255.0);//pixelb[setY][setX];//int(1.0*255.0);
+
+ int highest = 0;
+ if (Rd > Gd) {
+ if (Rd > Bd) highest = Rd;
+ else highest = Bd;
+ } else {
+ if (Gd > Bd) highest = Gd;
+ else highest = Bd;
+ }
+
+ int grabA = getAcolor(pixelb[setY][setX]);
+
+ if (highest <= 40) {
+ na = int((float(highest * 2) / 100.0) * 255.0);
+ } else {
+ na = grabA;
+ }
+ pixelb[setY][setX] = SetColorRGBA(Rd, Gd, Bd, na);//
+
+
+ }
+ }
+
+ _engine->ReleaseBitmapSurface(src);
+}
+
+
void AGSWaves::CastWave(int delayMax, int PixelsWide, int n) {
tDy[n]++;
if (tDy[n] > delayMax) {
@@ -134,6 +428,32 @@ void AGSWaves::DrawEffect(int sprite_a, int sprite_b, int id, int n) {
_engine->ReleaseBitmapSurface(src_b);
}
+int AGSWaves::SetColorRGBA(int r, int g, int b, int a) {
+ r = CLIP(r, 0, 255);
+ g = CLIP(g, 0, 255);
+ b = CLIP(b, 0, 255);
+ a = CLIP(a, 0, 255);
+ return int((r << 16) | (g << 8) | (b << 0) | (a << 24));
+}
+
+float AGSWaves::noiseField(float tx, float ty, float tz) {
+ float px = floor(tx);
+ float fx = fracts(tx);
+ float py = floor(ty);
+ float fy = fracts(ty);
+ float pz = floor(tz);
+ float fz = fracts(tz);
+ fx = fx * fx * (3.0 - 2.0 * fx);
+ fy = fy * fy * (3.0 - 2.0 * fy);
+ fz = fz * fz * (3.0 - 2.0 * fz);
+
+ float n = px + py * 157.0 + 113.0 * pz;
+ return lerp(lerp(lerp(hasher(n + 0.0), hasher(n + 1.0), fx),
+ lerp(hasher(n + 157.0), hasher(n + 158.0), fx), fy),
+ lerp(lerp(hasher(n + 113.0), hasher(n + 114.0), fx),
+ lerp(hasher(n + 270.0), hasher(n + 271.0), fx), fy), fz);
+}
+
} // namespace AGSWaves
} // namespace Plugins
} // namespace AGS3
diff --git a/engines/ags/plugins/ags_waves/vars.h b/engines/ags/plugins/ags_waves/vars.h
index 45f4726649..8fced69c75 100644
--- a/engines/ags/plugins/ags_waves/vars.h
+++ b/engines/ags/plugins/ags_waves/vars.h
@@ -156,13 +156,13 @@ struct Vars {
int movedport;
int translay;
int translayHold;
- int width;
- int height;
- int fx;
- int fy;
+ int _width;
+ int _height;
+ int _fx;
+ int _fy;
bool doingcircle;
- float angle;
- float radius;
+ float _angle;
+ float _radius;
int doingCircleChance;
float angleLay;
int frame;
Commit: 74be1d8fd7d64bd847e6d0c5c98d9869b821bb7b
https://github.com/scummvm/scummvm/commit/74be1d8fd7d64bd847e6d0c5c98d9869b821bb7b
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-20T20:25:53-07:00
Commit Message:
AGS: Further fleshing out AGSWaves gfx methods
Changed paths:
A engines/ags/plugins/ags_waves/data.cpp
A engines/ags/plugins/ags_waves/sound.cpp
A engines/ags/plugins/ags_waves/warper.cpp
engines/ags/module.mk
engines/ags/plugins/ags_waves/ags_waves.cpp
engines/ags/plugins/ags_waves/ags_waves.h
engines/ags/plugins/ags_waves/draw.cpp
engines/ags/plugins/ags_waves/vars.h
diff --git a/engines/ags/module.mk b/engines/ags/module.mk
index 6f057102c3..5d3c4ef7ac 100644
--- a/engines/ags/module.mk
+++ b/engines/ags/module.mk
@@ -352,7 +352,10 @@ MODULE_OBJS = \
plugins/ags_tcp_ip/ags_tcp_ip.o \
plugins/ags_wadjet_util/ags_wadjet_util.o \
plugins/ags_waves/ags_waves.o \
- plugins/ags_waves/draw.o
+ plugins/ags_waves/data.o \
+ plugins/ags_waves/draw.o \
+ plugins/ags_waves/sound.o \
+ plugins/ags_waves/warper.o
ifdef ENABLE_AGS_TESTS
MODULE_OBJS += \
diff --git a/engines/ags/plugins/ags_waves/ags_waves.cpp b/engines/ags/plugins/ags_waves/ags_waves.cpp
index b995fc7d71..d8ebbf13f2 100644
--- a/engines/ags/plugins/ags_waves/ags_waves.cpp
+++ b/engines/ags/plugins/ags_waves/ags_waves.cpp
@@ -26,9 +26,9 @@ namespace AGS3 {
namespace Plugins {
namespace AGSWaves {
-const unsigned int Magic = 0xACAB0000;
-const unsigned int Version = 1;
-const unsigned int SaveMagic = Magic + Version;
+const uint32 Magic = 0xACAB0000;
+const uint32 Version = 1;
+const uint32 SaveMagic = Magic + Version;
const float PI = 3.14159265f;
const char *AGSWaves::AGS_GetPluginName() {
@@ -99,161 +99,6 @@ void AGSWaves::AGS_EngineStartup(IAGSEngine *engine) {
SCRIPT_METHOD(SetWalkbehindBaserine, AGSWaves::SetWalkbehindBaserine);
}
-void AGSWaves::SFX_Play(ScriptMethodParams ¶ms) {
- //PARAMS2(int, SFX, int, repeat);
-}
-
-void AGSWaves::SFX_SetVolume(ScriptMethodParams ¶ms) {
- //PARAMS2(int, SFX, int, volume);
-}
-
-void AGSWaves::SFX_GetVolume(ScriptMethodParams ¶ms) {
- //PARAMS1(int, SFX);
- params._result = 0;
-}
-
-void AGSWaves::Music_Play(ScriptMethodParams ¶ms) {
- //PARAMS6(int, MFX, int, repeat, int, fadeinMS, int, fadeoutMS, int, Position, bool, fixclick);
-}
-
-void AGSWaves::Music_SetVolume(ScriptMethodParams ¶ms) {
- //PARAMS1(int, volume);
-}
-
-void AGSWaves::Music_GetVolume(ScriptMethodParams ¶ms) {
- params._result = 0;
-}
-
-void AGSWaves::SFX_Stop(ScriptMethodParams ¶ms) {
- //PARAMS2(int, SFX, int, fademsOUT);
-}
-
-void AGSWaves::SFX_SetPosition(ScriptMethodParams ¶ms) {
- //PARAMS4(int, SFX, int, x, int, y, int, intensity);
-}
-
-void AGSWaves::SFX_SetGlobalVolume(ScriptMethodParams ¶ms) {
- //PARAMS1(int, volume);
-}
-
-void AGSWaves::Load_SFX(ScriptMethodParams ¶ms) {
- //PARAMS1(int, SFX);
-}
-
-void AGSWaves::Audio_Apply_Filter(ScriptMethodParams ¶ms) {
- //PARAMS1(int, Frequency);
-}
-
-void AGSWaves::Audio_Remove_Filter(ScriptMethodParams ¶ms) {
-}
-
-void AGSWaves::SFX_AllowOverlap(ScriptMethodParams ¶ms) {
- //PARAMS2(int, SFX, int, allow);
-}
-
-void AGSWaves::SFX_Filter(ScriptMethodParams ¶ms) {
- //PARAMS2(int, SFX, int, enable);
-}
-
-void AGSWaves::Grayscale(ScriptMethodParams ¶ms) {
- //PARAMS1(int, sprite);
-}
-
-void AGSWaves::ReadWalkBehindIntoSprite(ScriptMethodParams ¶ms) {
- //PARAMS3(int, sprite, int, bgsprite, int, walkbehindBaseline);
-}
-
-void AGSWaves::AdjustSpriteFont(ScriptMethodParams ¶ms) {
- //PARAMS5(int, sprite, int, rate, int, outlineRed, int, outlineGreen, int, outlineBlue);
-}
-
-void AGSWaves::SpriteGradient(ScriptMethodParams ¶ms) {
- //PARAMS3(int, sprite, int, rate, int, toy);
-}
-
-void AGSWaves::Outline(ScriptMethodParams ¶ms) {
- //PARAMS5(int, sprite, int, red, int, ged, int, bed, int, aed);
-}
-
-void AGSWaves::OutlineOnly(ScriptMethodParams ¶ms) {
- //PARAMS7(int, sprite, int, refsprite, int, red, int, ged, int, bed, int, aed, int, trans);
-}
-
-void AGSWaves::SaveVariable(ScriptMethodParams ¶ms) {
- //PARAMS2(const char *, value, int, id);
-}
-
-void AGSWaves::ReadVariable(ScriptMethodParams ¶ms) {
- //PARAMS1(int, id);
- params._result = (const char *)nullptr;
-}
-
-void AGSWaves::GameDoOnceOnly(ScriptMethodParams ¶ms) {
-// PARAMS1(const char *, value);
-
- GetGDState(params);
- if (params._result) {
- // Set state to false
- params.push_back(false);
- SetGDState(params);
-
- params._result = true;
- } else {
- params._result = false;
- }
-}
-
-void AGSWaves::SetGDState(ScriptMethodParams ¶ms) {
- PARAMS2(const char *, value, bool, setValue);
-
- int id = -1;
- for (int i = 0; i <= usedTokens; i++) {
- if (Token[i] != NULL && strcmp(Token[i], value) == 0) {
- id = i;
- TokenUnUsed[i] = setValue;
- i = usedTokens + 1;
- }
- }
-
- if (id == -1) {
- // It doesn't find it while trying to set its state
- // create the thing with said state
- id = usedTokens;
- TokenUnUsed[id] = setValue;
- if (Token[id] != NULL)
- free(Token[id]);
-
- Token[id] = scumm_strdup(value);
- usedTokens++;
- }
-}
-
-void AGSWaves::GetGDState(ScriptMethodParams ¶ms) {
- PARAMS1(const char *, value);
-
- int id = -1;
-
- for (int i = 0; i <= usedTokens; i++) {
- if (Token[i] != NULL && strcmp(Token[i], value) == 0) {
- id = i;
- i = usedTokens + 1;
- }
- }
-
- if (id == -1) {
- params._result = true;
- } else {
- params._result = TokenUnUsed[id];
- }
-}
-
-void AGSWaves::ResetAllGD(ScriptMethodParams ¶ms) {
-}
-
-void AGSWaves::SpriteSkew(ScriptMethodParams ¶ms) {
- //PARAMS5(int, sprite, float, xskewmin, float, yskewmin, float, xskewmax, float, yskewmax);
-}
-
void AGSWaves::FireUpdate(ScriptMethodParams ¶ms) {
//PARAMS2(int, getDynamicSprite, bool, Fire2Visible));
}
@@ -266,67 +111,14 @@ void AGSWaves::SetWindValues(ScriptMethodParams ¶ms) {
//PARAMS4(int, w, int, h, int, pr, int, prev);
}
-void AGSWaves::ReturnWidth(ScriptMethodParams ¶ms) {
- //PARAMS8(int, x1, int, y1, int, x2, int, y2, int, x3, int, y3, int, x4, int, y4);
- params._result = 0;
-}
-
-void AGSWaves::ReturnHeight(ScriptMethodParams ¶ms) {
- //PARAMS8(int, x1, int, y1, int, x2, int, y2, int, x3, int, y3, int, x4, int, y4);
- params._result = 0;
-}
-
-void AGSWaves::ReturnNewHeight(ScriptMethodParams ¶ms) {
-}
-
-void AGSWaves::ReturnNewWidth(ScriptMethodParams ¶ms) {
-}
-
-void AGSWaves::Warper(ScriptMethodParams ¶ms) {
- //PARAMS5(int, swarp, int, sadjust, int, x1, int, y1, int, x2);
-}
-
-void AGSWaves::SetWarper(ScriptMethodParams ¶ms) {
- //PARAMS5(int, y2x, int, x3x, int, y3x, int, x4x, int, y4x);
-}
-
void AGSWaves::RainUpdate(ScriptMethodParams ¶ms) {
//PARAMS7(int, rdensity, int, FX, int, FY, int, RW, int, RH, int, graphic, float, perc);
}
-void AGSWaves::BlendTwoSprites(ScriptMethodParams ¶ms) {
- //PARAMS2(int, graphic, int, refgraphic);
-}
-
-void AGSWaves::Blend(ScriptMethodParams ¶ms) {
- //PARAMS4(int, graphic, int, refgraphic, bool, screen, int, perc);
-}
-
-void AGSWaves::Dissolve(ScriptMethodParams ¶ms) {
- //PARAMS3(int, graphic, int, noisegraphic, int, disvalue);
-}
-
-void AGSWaves::ReverseTransparency(ScriptMethodParams ¶ms) {
- //PARAMS1(int, graphic);
-}
-
void AGSWaves::NoiseCreator(ScriptMethodParams ¶ms) {
//PARAMS2(int, graphic, int, setA);
}
-void AGSWaves::TintProper(ScriptMethodParams ¶ms) {
- //PARAMS7(int, sprite, int, lightx, int, lighty, int, radi, int, rex, int, grx, int, blx);
-}
-
-void AGSWaves::GetWalkbehindBaserine(ScriptMethodParams ¶ms) {
- //PARAMS1(int, id);
- params._result = 0;
-}
-
-void AGSWaves::SetWalkbehindBaserine(ScriptMethodParams ¶ms) {
- //PARAMS2(int, id, int, base);
-}
-
void AGSWaves::StartingValues() {
GeneralAudio.NumOfChannels = 0;
GeneralAudio.Initialized = false;
diff --git a/engines/ags/plugins/ags_waves/ags_waves.h b/engines/ags/plugins/ags_waves/ags_waves.h
index 1d1eb163cc..6f06bd879a 100644
--- a/engines/ags/plugins/ags_waves/ags_waves.h
+++ b/engines/ags/plugins/ags_waves/ags_waves.h
@@ -89,6 +89,7 @@ private:
void CastWave(int delayMax, int PixelsWide, int n);
void DrawEffect(int sprite_a, int sprite_b, int id, int n);
+ int Random(int threshold);
inline static int getRcolor(int color) {
return ((color >> 16) & 0xFF);
@@ -102,9 +103,19 @@ private:
inline static int getAcolor(int color) {
return ((color >> 24) & 0xFF);
}
+ static int BlendColor(int Ln, int Bn, int perc) {
+ return ((Ln < 128) ? (2 * Bn * Ln / perc) : (perc - 2 * (perc - Bn) * (perc - Ln) / perc));
+ }
+ static int BlendColorScreen(int Ln, int Bn, int perc) {
+ return (Bn == perc) ? Bn :
+ MIN(perc, (Ln * Ln / (perc - Bn)));
+ }
static int SetColorRGBA(int r, int g, int b, int a);
+ static int ConvertColorToGrayScale(int color);
+ static bool IsPixelTransparent(int color);
float noiseField(float tx, float ty, float tz);
+ int IntersectLines(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4);
static inline float fracts(float value) {
return value - floor(value);
@@ -115,6 +126,12 @@ private:
static inline float hasher(float n) {
return fracts(sin(n) * 153.5453123);
}
+ static float min4(float m1, float m2, float m3, float m4) {
+ return MIN(MIN(m1, m2), MIN(m3, m4));
+ }
+ static float max4(float m1, float m2, float m3, float m4) {
+ return MAX(MAX(m1, m2), MAX(m3, m4));
+ }
public:
AGSWaves() : PluginBase(), Vars() {}
virtual ~AGSWaves() {}
diff --git a/engines/ags/plugins/ags_waves/data.cpp b/engines/ags/plugins/ags_waves/data.cpp
new file mode 100644
index 0000000000..8c2eb6d5b0
--- /dev/null
+++ b/engines/ags/plugins/ags_waves/data.cpp
@@ -0,0 +1,134 @@
+/* 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.
+ *
+ */
+
+#include "common/util.h"
+#include "ags/plugins/ags_waves/ags_waves.h"
+
+namespace AGS3 {
+namespace Plugins {
+namespace AGSWaves {
+
+void AGSWaves::SaveVariable(ScriptMethodParams ¶ms) {
+ PARAMS2(const char *, value, int, id);
+
+ if (GameDatavalue[id] != nullptr) {
+ free(GameDatavalue[id]);
+ }
+ if (value != nullptr) {
+ GameDatavalue[id] = scumm_strdup(value);
+ } else {
+ GameDatavalue[id] = nullptr;
+ }
+}
+
+void AGSWaves::ReadVariable(ScriptMethodParams ¶ms) {
+ PARAMS1(int, id);
+
+ if (GameDatavalue[id] == NULL) {
+ params._result = _engine->CreateScriptString("");
+ } else {
+ params._result = _engine->CreateScriptString(GameDatavalue[id]);
+ }
+}
+
+void AGSWaves::GameDoOnceOnly(ScriptMethodParams ¶ms) {
+ // PARAMS1(const char *, value);
+
+ GetGDState(params);
+ if (params._result) {
+ // Set state to false
+ params.push_back(false);
+ SetGDState(params);
+
+ params._result = true;
+ } else {
+ params._result = false;
+ }
+}
+
+void AGSWaves::SetGDState(ScriptMethodParams ¶ms) {
+ PARAMS2(const char *, value, bool, setValue);
+
+ int id = -1;
+ for (int i = 0; i <= usedTokens; i++) {
+ if (Token[i] != nullptr && strcmp(Token[i], value) == 0) {
+ id = i;
+ TokenUnUsed[i] = setValue;
+ i = usedTokens + 1;
+ }
+ }
+
+ if (id == -1) {
+ // It doesn't find it while trying to set its state
+ // create the thing with said state
+ id = usedTokens;
+ TokenUnUsed[id] = setValue;
+ if (Token[id] != nullptr)
+ free(Token[id]);
+
+ Token[id] = scumm_strdup(value);
+ usedTokens++;
+ }
+}
+
+void AGSWaves::GetGDState(ScriptMethodParams ¶ms) {
+ PARAMS1(const char *, value);
+
+ int id = -1;
+
+ for (int i = 0; i <= usedTokens; i++) {
+ if (Token[i] != nullptr && strcmp(Token[i], value) == 0) {
+ id = i;
+ i = usedTokens + 1;
+ }
+ }
+
+ if (id == -1) {
+ params._result = true;
+ } else {
+ params._result = TokenUnUsed[id];
+ }
+}
+
+void AGSWaves::ResetAllGD(ScriptMethodParams ¶ms) {
+ for (int i = 0; i <= usedTokens; i++) {
+ if (Token[i] != NULL)
+ free(Token[i]);
+ Token[i] = NULL;
+ TokenUnUsed[i] = true;
+ }
+ usedTokens = 0;
+}
+
+void AGSWaves::GetWalkbehindBaserine(ScriptMethodParams ¶ms) {
+ PARAMS1(int, id);
+ params._result = Walkbehind[id];
+}
+
+void AGSWaves::SetWalkbehindBaserine(ScriptMethodParams ¶ms) {
+ PARAMS2(int, id, int, base);
+ Walkbehind[id] = base;
+}
+
+} // namespace AGSWaves
+} // namespace Plugins
+} // namespace AGS3
diff --git a/engines/ags/plugins/ags_waves/draw.cpp b/engines/ags/plugins/ags_waves/draw.cpp
index 35ca05c513..400cc9e148 100644
--- a/engines/ags/plugins/ags_waves/draw.cpp
+++ b/engines/ags/plugins/ags_waves/draw.cpp
@@ -320,6 +320,667 @@ void AGSWaves::DrawForceField(ScriptMethodParams ¶ms) {
_engine->ReleaseBitmapSurface(src);
}
+void AGSWaves::SpriteSkew(ScriptMethodParams ¶ms) {
+ PARAMS5(int, sprite, float, xskewmin, float, yskewmin, float, xskewmax, float, yskewmax);
+
+ BITMAP *src = _engine->GetSpriteGraphic(sprite);
+ uint32 **pixel_src = (uint32 **)_engine->GetRawBitmapSurface(src);
+
+ int src_width = 640;
+ int src_height = 360;
+ int src_depth = 32;
+ _engine->GetBitmapDimensions(src, &src_width, &src_height, &src_depth);
+ _engine->ReleaseBitmapSurface(src);
+
+ BITMAP *dest = _engine->GetSpriteGraphic(sprite);
+ uint32 **pixel_dest = (uint32 **)_engine->GetRawBitmapSurface(dest);
+
+ int x, y;
+
+ float raty = abs(yskewmin - yskewmax) / float(src_height * src_width);
+ float ratx = abs(xskewmin - xskewmax) / float(src_height * src_width);
+ float yskew = yskewmin;
+ float xskew = xskewmin;
+
+ for (y = 0; y < src_height; y++) {
+ for (x = 0; x < src_width; x++) {
+ int ry = int((float(x) * yskew) + float(y));
+ int rx = int(float(x) + (float(y) * xskew));
+
+ if (ry > src_height - 1) ry = src_height - 1;
+ if (rx > src_width - 1) rx = src_width - 1;
+ if (rx < 0) rx = 0;
+ if (ry < 0) ry = 0;
+
+ int getColor = pixel_src[ry][rx];
+ int red = getRcolor(getColor);
+ int green = getGcolor(getColor);
+ int blue = getBcolor(getColor);
+ int alpha = getAcolor(getColor);
+
+ pixel_dest[y][x] = SetColorRGBA(red, green, blue, alpha);
+
+ if (xskewmin < xskewmax) xskew += ratx;
+ else xskew -= ratx;
+
+ if (yskewmin < yskewmax) yskew += raty;
+ else yskew -= raty;
+ }
+ }
+
+ _engine->ReleaseBitmapSurface(dest);
+}
+
+void AGSWaves::ReturnWidth(ScriptMethodParams ¶ms) {
+ //PARAMS8(int, x1, int, y1, int, x2, int, y2, int, x3, int, y3, int, x4, int, y4);
+ int x1 = params[0];
+ int x2 = params[2];
+ int x3 = params[4];
+ int x4 = params[6];
+
+ float ax = float(x1);
+ float bx = float(x2);
+ float cx = float(x3);
+ float dx = float(x4);
+
+ params._result = (int(max4(ax, bx, cx, dx)) + 1);
+}
+
+void AGSWaves::ReturnHeight(ScriptMethodParams ¶ms) {
+ //PARAMS8(int, x1, int, y1, int, x2, int, y2, int, x3, int, y3, int, x4, int, y4);
+ int y1 = params[1];
+ int y2 = params[3];
+ int y3 = params[5];
+ int y4 = params[7];
+
+ float ay = float(y1);
+ float by = float(y2);
+ float cy = float(y3);
+ float dy = float(y4);
+
+ params._result = (int)max4(ay, by, cy, dy) + 1;
+}
+
+void AGSWaves::Grayscale(ScriptMethodParams ¶ms) {
+ PARAMS1(int, sprite);
+
+ BITMAP *src = _engine->GetSpriteGraphic(sprite);
+ uint32 **pixels = (uint32 **)_engine->GetRawBitmapSurface(src);
+
+ int src_width = 640;
+ int src_height = 360;
+ int src_depth = 32;
+
+ _engine->GetBitmapDimensions(src, &src_width, &src_height, &src_depth);
+
+ int x, y;
+ for (y = 0; y < src_height; y++) {
+ for (x = 0; x < src_width; x++) {
+ int color = ConvertColorToGrayScale(pixels[y][x]);
+ pixels[y][x] = color;
+ }
+ }
+
+
+ _engine->ReleaseBitmapSurface(src);
+}
+
+void AGSWaves::BlendTwoSprites(ScriptMethodParams ¶ms) {
+ PARAMS2(int, graphic, int, refgraphic);
+
+ BITMAP *src = _engine->GetSpriteGraphic(graphic);
+ int src_width = 640;
+ int src_height = 360;
+ int src_depth = 32;
+ _engine->GetBitmapDimensions(src, &src_width, &src_height, &src_depth);
+ uint32 **sprite_pixels = (uint32 **)_engine->GetRawBitmapSurface(src);
+
+ BITMAP *refsrc = _engine->GetSpriteGraphic(refgraphic);
+ int refsrc_width = 640;
+ int refsrc_height = 360;
+ int refsrc_depth = 32;
+ _engine->GetBitmapDimensions(refsrc, &refsrc_width, &refsrc_height, &refsrc_depth);
+ uint32 **refsprite_pixels = (uint32 **)_engine->GetRawBitmapSurface(refsrc);
+ _engine->ReleaseBitmapSurface(refsrc);
+
+ int x, y;
+
+ for (y = 0; y < src_height; y++) {
+ for (x = 0; x < src_width; x++) {
+ int getColor = sprite_pixels[y][x];
+ int rn = getRcolor(getColor);
+ int gn = getGcolor(getColor);
+ int bn = getBcolor(getColor);
+ int an = getAcolor(getColor);
+
+ if (an > 0.0 && rn > 4 && gn > 4 && bn > 4) {
+ int getColor2 = refsprite_pixels[y][x];
+ int rj = getRcolor(getColor2);
+ int gj = getGcolor(getColor2);
+ int bj = getBcolor(getColor2);
+ int aj = getAcolor(getColor2);
+
+ if (rj > 100 || gj > 100 || bj > 100) {
+ sprite_pixels[y][x] = SetColorRGBA(rj, gj, bj, aj);
+ }
+ }
+ }
+ }
+
+ _engine->ReleaseBitmapSurface(src);
+}
+
+void AGSWaves::Blend(ScriptMethodParams ¶ms) {
+ PARAMS4(int, graphic, int, refgraphic, bool, screen, int, perc);
+
+ BITMAP *src = _engine->GetSpriteGraphic(graphic);
+ int src_width = 640;
+ int src_height = 360;
+ int src_depth = 32;
+ _engine->GetBitmapDimensions(src, &src_width, &src_height, &src_depth);
+ uint32 **sprite_pixels = (uint32 **)_engine->GetRawBitmapSurface(src);
+
+ BITMAP *refsrc = _engine->GetSpriteGraphic(refgraphic);
+ int refsrc_width = 640;
+ int refsrc_height = 360;
+ int refsrc_depth = 32;
+ _engine->GetBitmapDimensions(refsrc, &refsrc_width, &refsrc_height, &refsrc_depth);
+ uint32 **refsprite_pixels = (uint32 **)_engine->GetRawBitmapSurface(refsrc);
+ _engine->ReleaseBitmapSurface(refsrc);
+
+ int x, y;
+
+ for (y = 0; y < src_height; y++) {
+ for (x = 0; x < src_width; x++) {
+ int getColor = sprite_pixels[y][x];
+ int rn = getRcolor(getColor);
+ int gn = getGcolor(getColor);
+ int bn = getBcolor(getColor);
+ int an = getAcolor(getColor);
+
+ if (an >= 0.0 && rn > 4 && gn > 4 && bn > 4) {
+ int getColor2 = refsprite_pixels[y][x];
+ int rj = getRcolor(getColor2);
+ int gj = getGcolor(getColor2);
+ int bj = getBcolor(getColor2);
+ int aj = getAcolor(getColor2);
+
+ if (!screen) {
+ rj = BlendColor(rn, rj, perc);
+ gj = BlendColor(gn, gj, perc);
+ bj = BlendColor(bn, bj, perc);
+ aj = BlendColor(an, aj, perc);
+ } else {
+ rj = BlendColorScreen(rn, rj, perc);
+ gj = BlendColorScreen(gn, gj, perc);
+ bj = BlendColorScreen(bn, bj, perc);
+ aj = BlendColorScreen(an, aj, perc);
+ }
+
+ sprite_pixels[y][x] = SetColorRGBA(rj, gj, bj, aj);
+ }
+ }
+ }
+
+ _engine->ReleaseBitmapSurface(src);
+}
+
+void AGSWaves::Dissolve(ScriptMethodParams ¶ms) {
+ PARAMS3(int, graphic, int, noisegraphic, int, disvalue);
+
+ BITMAP *src = _engine->GetSpriteGraphic(graphic);
+ int src_width = 640;
+ int src_height = 360;
+ int src_depth = 32;
+ _engine->GetBitmapDimensions(src, &src_width, &src_height, &src_depth);
+ uint32 **sprite_pixels = (uint32 **)_engine->GetRawBitmapSurface(src);
+
+ BITMAP *noisesrc = _engine->GetSpriteGraphic(noisegraphic);
+ int noisesrc_width = 640;
+ int noisesrc_height = 360;
+ int noisesrc_depth = 32;
+ _engine->GetBitmapDimensions(noisesrc, &noisesrc_width, &noisesrc_height, &noisesrc_depth);
+ uint32 **noise_pixels = (uint32 **)_engine->GetRawBitmapSurface(noisesrc);
+ _engine->ReleaseBitmapSurface(noisesrc);
+
+ int x, y;
+
+ for (y = 0; y < src_height; y++) {
+ for (x = 0; x < src_width; x++)//
+ {
+ int getColor = noise_pixels[y][x];
+ int gn = getRcolor(getColor);
+
+
+ int getColorx = sprite_pixels[y][x];
+ int rj = getRcolor(getColorx);
+ int gj = getGcolor(getColorx);
+ int bj = getBcolor(getColorx);
+ int originalA = getAcolor(getColorx);
+ int aj = 0;
+
+ //disvalue 0-255
+ //FOR EACH PIXEL IN THE NOISE GRAPHIC THAT IS < DISVALUE
+ if (gn < disvalue) {
+ if (gn > disvalue - 2) {
+ rj = 193 + Random(20);
+ gj = 132 + Random(20);
+ bj = 255 + Random(20);
+ aj = originalA;
+ } else if (gn > disvalue - 3) {
+ rj = 128 + Random(20);
+ gj = 0 + Random(20);
+ bj = 255 + Random(20);
+ aj = 150;
+ } else {
+ aj = 0;
+ }
+ } else aj = originalA;
+
+ if (originalA > 50) {
+ sprite_pixels[y][x] = SetColorRGBA(rj, gj, bj, aj);
+ }
+ }
+ }
+
+ _engine->ReleaseBitmapSurface(src);
+}
+
+void AGSWaves::ReverseTransparency(ScriptMethodParams ¶ms) {
+ PARAMS1(int, graphic);
+
+ BITMAP *noisesrc = _engine->GetSpriteGraphic(graphic);
+ int noisesrc_width = 640;
+ int noisesrc_height = 360;
+ int noisesrc_depth = 32;
+ _engine->GetBitmapDimensions(noisesrc, &noisesrc_width, &noisesrc_height, &noisesrc_depth);
+ uint32 **noise_pixels = (uint32 **)_engine->GetRawBitmapSurface(noisesrc);
+ _engine->ReleaseBitmapSurface(noisesrc);
+
+ BITMAP *src = _engine->GetSpriteGraphic(graphic);
+ int src_width = 640;
+ int src_height = 360;
+ int src_depth = 32;
+ _engine->GetBitmapDimensions(src, &src_width, &src_height, &src_depth);
+ uint32 **sprite_pixels = (uint32 **)_engine->GetRawBitmapSurface(src);
+
+ int x, y;
+
+ for (y = 0; y < src_height; y++) {
+ for (x = 0; x < src_width; x++) {
+ int getColors = noise_pixels[y][x];
+ int TranClr = getAcolor(getColors);
+
+ if (TranClr < 254) {
+ //PIXEL IS TRANSPARENT
+ sprite_pixels[y][x] = SetColorRGBA(255, 255, 255, 255);
+ } else {
+ //PIXEL IS VISIBLE
+ sprite_pixels[y][x] = SetColorRGBA(0, 0, 0, 0);
+ }
+ }
+ }
+
+ _engine->ReleaseBitmapSurface(src);
+}
+
+void AGSWaves::TintProper(ScriptMethodParams ¶ms) {
+ PARAMS7(int, sprite, int, lightx, int, lighty, int, radi, int, rex, int, grx, int, blx);
+
+ BITMAP *src = _engine->GetSpriteGraphic(sprite);
+ BITMAP *src2 = _engine->GetSpriteGraphic(lightx);
+ (void)lighty; // Unused
+
+ uint32 **pixelb = (uint32 **)_engine->GetRawBitmapSurface(src);
+ uint32 **pixela = (uint32 **)_engine->GetRawBitmapSurface(src2);
+ _engine->ReleaseBitmapSurface(src2);
+ int src_width = 640;
+ int src_height = 360;
+ int src_depth = 32;
+
+ _engine->GetBitmapDimensions(src, &src_width, &src_height, &src_depth);
+
+ int x, y;
+ for (y = 0; y < src_height; y++) {
+ for (x = 0; x < src_width; x++) {
+ int totalRed = 0;
+ int totalGreen = 0;
+ int totalBlue = 0;
+
+ int vx = -(radi);
+ int pixels_parsed = 0;
+
+ int setY = y;
+ if (setY < 0) setY = 0;
+ if (setY > src_height - 1) setY = src_height - 1;
+
+ while (vx < (radi)+1) {
+ int setX = x + vx;
+ if (setX < 0) setX = 0;
+ if (setX > src_width - 1) setX = src_width - 1;
+
+ int color = pixela[setY][setX];
+
+ totalRed += getRcolor(color);
+ totalGreen += getGcolor(color);
+ totalBlue += getBcolor(color);
+
+ pixels_parsed++;
+
+ vx++;
+ }
+
+ int rN = totalRed / pixels_parsed;
+ int gN = totalGreen / pixels_parsed;
+ int bN = totalBlue / pixels_parsed;
+
+ int r = int(CLIP(rN, 0, 255));
+ int g = int(CLIP(gN, 0, 255));
+ int b = int(CLIP(bN, 0, 255));
+
+ if (r > rex &&g > grx &&b > blx) {
+ pixelb[y][x] = ((r << 16) | (g << 8) | (b << 0) | (255 << 24));
+ } else {
+ pixelb[y][x] = SetColorRGBA(rex, grx, blx, 0);
+ }
+ }
+ }
+
+
+ _engine->ReleaseBitmapSurface(src);
+ src = _engine->GetSpriteGraphic(sprite);
+
+ x = 0;
+ y = 0;
+ for (y = 0; y < src_height; y++) {
+ for (x = 0; x < src_width; x++) {
+ int totalRed = 0;
+ int totalGreen = 0;
+ int totalBlue = 0;
+
+ int pixels_parsed = 0;
+ int setX = x;
+ if (setX < 0) setX = 0;
+ if (setX > src_width - 1) setX = src_width - 1;
+
+ int vy = -(radi);
+ while (vy < (radi)+1) {
+ int setY = y + vy;
+ if (setY < 0) setY = 0;
+ if (setY > src_height - 1) setY = src_height - 1;
+
+ int color = pixela[setY][setX];
+
+ totalRed += getRcolor(color);
+ totalGreen += getGcolor(color);
+ totalBlue += getBcolor(color);
+
+ pixels_parsed++;
+
+
+ vy++;
+ }
+
+ int rN = totalRed / pixels_parsed;
+ int gN = totalGreen / pixels_parsed;
+ int bN = totalBlue / pixels_parsed;
+
+ int r = CLIP(rN, 0, 255);
+ int g = CLIP(gN, 0, 255);
+ int b = CLIP(bN, 0, 255);
+
+ if (r > rex &&g > grx &&b > blx) {
+ pixelb[y][x] = ((r << 16) | (g << 8) | (b << 0) | (255 << 24));
+ } else {
+ pixelb[y][x] = SetColorRGBA(rex, grx, blx, 0);
+ }
+ }
+ }
+
+ _engine->ReleaseBitmapSurface(src);
+}
+
+void AGSWaves::ReadWalkBehindIntoSprite(ScriptMethodParams ¶ms) {
+ PARAMS3(int, sprite, int, bgsprite, int, walkbehindBaseline);
+
+ BITMAP *src = _engine->GetSpriteGraphic(sprite);
+ BITMAP *bgsrc = _engine->GetSpriteGraphic(bgsprite);
+ int src_width = 640;
+ int src_height = 360;
+ int src_depth = 32;
+
+ _engine->GetBitmapDimensions(src, &src_width, &src_height, &src_depth);
+ BITMAP *wbh = _engine->GetRoomMask(MASK_WALKBEHIND);
+
+ uint32 **sprite_pixels = (uint32 **)_engine->GetRawBitmapSurface(src);
+ uint32 **bgsprite_pixels = (uint32 **)_engine->GetRawBitmapSurface(bgsrc);
+ byte *walk_pixels = _engine->GetRawBitmapSurface(wbh); //8bit
+
+ _engine->ReleaseBitmapSurface(wbh);
+ _engine->ReleaseBitmapSurface(bgsrc);
+
+ // WE GRAB ALL OF THEM INTO A BITMAP and thus we know where they are drawn
+ int x, y;
+ for (y = 0; y < src_height; y++) {
+ for (x = 0; x < src_width; x++) {
+ //READ COLOR
+ if (walk_pixels[y * src_width + x] > 0) {
+ int grabBaseline = _engine->GetWalkbehindBaseline(walk_pixels[y * src_width + x]);
+
+ if (grabBaseline == walkbehindBaseline) {
+ sprite_pixels[y][x] = bgsprite_pixels[y][x];
+ }
+ }
+ }
+ }
+
+ _engine->ReleaseBitmapSurface(src);
+}
+
+void AGSWaves::AdjustSpriteFont(ScriptMethodParams ¶ms) {
+ PARAMS5(int, sprite, int, rate, int, outlineRed, int, outlineGreen, int, outlineBlue);
+
+ BITMAP *src = _engine->GetSpriteGraphic(sprite);
+ uint32 **pixel_src = (uint32 **)_engine->GetRawBitmapSurface(src);
+
+ int src_width = 640;
+ int src_height = 360;
+ int src_depth = 32;
+ _engine->GetBitmapDimensions(src, &src_width, &src_height, &src_depth);
+
+ int x, y;
+
+ int px = 1;
+ bool found = false;
+ for (y = 0; y < src_height; y++) {
+ if (found) {
+ px++;
+ }
+ //if (px >12) px=12;
+ bool havefound = false;
+ for (x = 0; x < src_width; x++) {
+ int getColor = pixel_src[y][x];
+ int red = getRcolor(getColor);
+ int green = getGcolor(getColor);
+ int blue = getBcolor(getColor);
+ int alpha = getAcolor(getColor);
+
+ if (alpha < 255.0 || (red <= 10 && green <= 10 && blue <= 10)) {
+ //px=1;
+ if (alpha == 255 && (red <= 10 && green <= 10 && blue <= 10)) {
+ pixel_src[y][x] = SetColorRGBA(outlineRed, outlineGreen, outlineBlue, 255);
+ }
+ } else {
+ havefound = true;
+ found = true;
+ red -= (px * rate);
+ green -= (px * rate);
+ blue -= (px * rate);
+
+ pixel_src[y][x] = SetColorRGBA(red, green, blue, 255);
+ }
+ }
+
+ if (havefound == false) {
+ if (found) {
+ px = 1;
+ found = false;
+ }
+ }
+ }
+
+ _engine->ReleaseBitmapSurface(src);
+}
+
+void AGSWaves::SpriteGradient(ScriptMethodParams ¶ms) {
+ PARAMS3(int, sprite, int, rate, int, toy);
+
+ BITMAP *src = _engine->GetSpriteGraphic(sprite);
+ uint32 **pixel_src = (uint32 **)_engine->GetRawBitmapSurface(src);
+
+ int src_width = 640;
+ int src_height = 360;
+ int src_depth = 32;
+ _engine->GetBitmapDimensions(src, &src_width, &src_height, &src_depth);
+
+ int x, y;
+ int setA = 0;
+
+ for (y = toy; y < src_height; y++) {
+ for (x = 0; x < src_width; x++) {
+ int getColor = pixel_src[y][x];
+ int red = getRcolor(getColor);
+ int green = getGcolor(getColor);
+ int blue = getBcolor(getColor);
+ int alpha = getAcolor(getColor) + setA;
+ if (alpha > 250) alpha = 250;
+
+ if (red > 10 && green > 10 && blue > 10) {
+ pixel_src[y][x] = SetColorRGBA(red, green, blue, alpha);
+ }
+
+ }
+ setA += rate;
+ }
+
+ _engine->ReleaseBitmapSurface(src);
+}
+
+void AGSWaves::Outline(ScriptMethodParams ¶ms) {
+ PARAMS5(int, sprite, int, red, int, ged, int, bed, int, aed);
+
+ BITMAP *src = _engine->GetSpriteGraphic(sprite);
+ uint32 **pixel_src = (uint32 **)_engine->GetRawBitmapSurface(src);
+
+ int src_width = 640;
+ int src_height = 360;
+ int src_depth = 32;
+ _engine->GetBitmapDimensions(src, &src_width, &src_height, &src_depth);
+
+ //OUTLINE
+ _engine->ReleaseBitmapSurface(src);
+
+
+ BITMAP *dst = _engine->GetSpriteGraphic(sprite);
+ uint32 **pixel_dst = (uint32 **)_engine->GetRawBitmapSurface(dst);
+
+ int x, y;
+ for (x = 0; x < src_width; x++) {
+ for (y = 0; y < src_height; y++) {
+ if (!IsPixelTransparent(pixel_src[y][x])) {
+ } else {
+ int pcount = 0;
+ int gy = -1;
+ while (gy < 2) {
+ int gx = -1;
+ while (gx < 2) {
+ int sx = x + gx;
+ int sy = y + gy;
+
+ if (sx < 0) sx = 0;
+ if (sy < 0) sy = 0;
+ if (sx > src_width - 1) sx = src_width - 1;
+ if (sy > src_height - 1) sy = src_height - 1;
+
+ if (!IsPixelTransparent(pixel_src[sy][sx])) {
+ pcount++;
+ }
+
+ gx++;
+ }
+ gy++;
+ }
+
+ if (pcount >= 2) {
+ int colorLeft = SetColorRGBA(red, ged, bed, aed);
+ pixel_dst[y][x] = colorLeft;
+ }
+ }
+ }
+ }
+
+ // OUTLINE
+ _engine->ReleaseBitmapSurface(dst);
+}
+
+void AGSWaves::OutlineOnly(ScriptMethodParams ¶ms) {
+ PARAMS7(int, sprite, int, refsprite, int, red, int, ged, int, bed, int, aed, int, trans);
+
+ BITMAP *src = _engine->GetSpriteGraphic(refsprite);
+ uint32 **pixel_src = (uint32 **)_engine->GetRawBitmapSurface(src);
+
+ int src_width = 640;
+ int src_height = 360;
+ int src_depth = 32;
+ _engine->GetBitmapDimensions(src, &src_width, &src_height, &src_depth);
+
+ // OUTLINE
+ _engine->ReleaseBitmapSurface(src);
+
+ BITMAP *dst = _engine->GetSpriteGraphic(sprite);
+ uint32 **pixel_dst = (uint32 **)_engine->GetRawBitmapSurface(dst);
+
+ int x, y;
+ for (x = 0; x < src_width; x++) {
+ for (y = 0; y < src_height; y++) {
+ if (!IsPixelTransparent(pixel_src[y][x])) {
+ int colorLeft = SetColorRGBA(red, ged, bed, trans);
+ pixel_dst[y][x] = colorLeft;
+ } else {
+ int pcount = 0;
+ int gy = -1;
+ while (gy < 2) {
+ int gx = -1;
+ while (gx < 2) {
+ int sx = x + gx;
+ int sy = y + gy;
+
+ if (sx < 0) sx = 0;
+ if (sy < 0) sy = 0;
+ if (sx > src_width - 1) sx = src_width - 1;
+ if (sy > src_height - 1) sy = src_height - 1;
+
+ if (!IsPixelTransparent(pixel_src[sy][sx])) {
+ pcount++;
+ }
+
+ gx++;
+ }
+ gy++;
+ }
+
+ if (pcount >= 2) {
+ int colorLeft = SetColorRGBA(red, ged, bed, aed);
+ pixel_dst[y][x] = colorLeft;
+ }
+ }
+ }
+ }
+
+ // OUTLINE
+ _engine->ReleaseBitmapSurface(dst);
+}
+
void AGSWaves::CastWave(int delayMax, int PixelsWide, int n) {
tDy[n]++;
@@ -428,6 +1089,10 @@ void AGSWaves::DrawEffect(int sprite_a, int sprite_b, int id, int n) {
_engine->ReleaseBitmapSurface(src_b);
}
+int AGSWaves::Random(int threshold) {
+ return ::AGS::g_vm->getRandomNumber(threshold - 1);
+}
+
int AGSWaves::SetColorRGBA(int r, int g, int b, int a) {
r = CLIP(r, 0, 255);
g = CLIP(g, 0, 255);
@@ -454,6 +1119,22 @@ float AGSWaves::noiseField(float tx, float ty, float tz) {
lerp(hasher(n + 270.0), hasher(n + 271.0), fx), fy), fz);
}
+int AGSWaves::ConvertColorToGrayScale(int color) {
+ int r = getRcolor(color);
+ int g = getGcolor(color);
+ int b = getBcolor(color);
+
+ float d = float((r * r + g * g + b * b) / 3);
+ int gr = int(sqrt(d));
+
+ return ((gr << 16) | (gr << 8) | (gr << 0) | (255 << 24));
+}
+
+bool AGSWaves::IsPixelTransparent(int color) {
+ int ad = getAcolor(color);
+ return ad < 255;
+}
+
} // namespace AGSWaves
} // namespace Plugins
} // namespace AGS3
diff --git a/engines/ags/plugins/ags_waves/sound.cpp b/engines/ags/plugins/ags_waves/sound.cpp
new file mode 100644
index 0000000000..224722d4cb
--- /dev/null
+++ b/engines/ags/plugins/ags_waves/sound.cpp
@@ -0,0 +1,89 @@
+/* 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.
+ *
+ */
+
+#include "common/util.h"
+#include "ags/plugins/ags_waves/ags_waves.h"
+
+namespace AGS3 {
+namespace Plugins {
+namespace AGSWaves {
+
+
+void AGSWaves::SFX_Play(ScriptMethodParams ¶ms) {
+ //PARAMS2(int, SFX, int, repeat);
+}
+
+void AGSWaves::SFX_SetVolume(ScriptMethodParams ¶ms) {
+ //PARAMS2(int, SFX, int, volume);
+}
+
+void AGSWaves::SFX_GetVolume(ScriptMethodParams ¶ms) {
+ //PARAMS1(int, SFX);
+ params._result = 0;
+}
+
+void AGSWaves::Music_Play(ScriptMethodParams ¶ms) {
+ //PARAMS6(int, MFX, int, repeat, int, fadeinMS, int, fadeoutMS, int, Position, bool, fixclick);
+}
+
+void AGSWaves::Music_SetVolume(ScriptMethodParams ¶ms) {
+ //PARAMS1(int, volume);
+}
+
+void AGSWaves::Music_GetVolume(ScriptMethodParams ¶ms) {
+ params._result = 0;
+}
+
+void AGSWaves::SFX_Stop(ScriptMethodParams ¶ms) {
+ //PARAMS2(int, SFX, int, fademsOUT);
+}
+
+void AGSWaves::SFX_SetPosition(ScriptMethodParams ¶ms) {
+ //PARAMS4(int, SFX, int, x, int, y, int, intensity);
+}
+
+void AGSWaves::SFX_SetGlobalVolume(ScriptMethodParams ¶ms) {
+ //PARAMS1(int, volume);
+}
+
+void AGSWaves::Load_SFX(ScriptMethodParams ¶ms) {
+ //PARAMS1(int, SFX);
+}
+
+void AGSWaves::Audio_Apply_Filter(ScriptMethodParams ¶ms) {
+ //PARAMS1(int, Frequency);
+}
+
+void AGSWaves::Audio_Remove_Filter(ScriptMethodParams ¶ms) {
+}
+
+void AGSWaves::SFX_AllowOverlap(ScriptMethodParams ¶ms) {
+ //PARAMS2(int, SFX, int, allow);
+}
+
+void AGSWaves::SFX_Filter(ScriptMethodParams ¶ms) {
+ //PARAMS2(int, SFX, int, enable);
+}
+
+} // namespace AGSWaves
+} // namespace Plugins
+} // namespace AGS3
diff --git a/engines/ags/plugins/ags_waves/vars.h b/engines/ags/plugins/ags_waves/vars.h
index 8fced69c75..662076f6fa 100644
--- a/engines/ags/plugins/ags_waves/vars.h
+++ b/engines/ags/plugins/ags_waves/vars.h
@@ -149,8 +149,8 @@ struct Vars {
int transp;
int life;
bool active;
- int dx;
- int dy;
+ int _dx;
+ int _dy;
int mlay;
int timlay;
int movedport;
@@ -215,6 +215,12 @@ struct Vars {
int dY[30];
int tDy[30];
int direction[30];
+
+ // Warper fields
+ int _newWidth = 0, _newHeight = 0;
+ int _y2 = 0;
+ int _x3 = 0, _y3 = 0;
+ int _x4 = 0, _y4 = 0;
};
} // namespace AGSWaves
diff --git a/engines/ags/plugins/ags_waves/warper.cpp b/engines/ags/plugins/ags_waves/warper.cpp
new file mode 100644
index 0000000000..9baf71061d
--- /dev/null
+++ b/engines/ags/plugins/ags_waves/warper.cpp
@@ -0,0 +1,186 @@
+/* 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.
+ *
+ */
+
+#include "common/util.h"
+#include "ags/plugins/ags_waves/ags_waves.h"
+
+namespace AGS3 {
+namespace Plugins {
+namespace AGSWaves {
+
+
+void AGSWaves::ReturnNewHeight(ScriptMethodParams ¶ms) {
+ params._result = _newHeight;
+}
+
+void AGSWaves::ReturnNewWidth(ScriptMethodParams ¶ms) {
+ params._result = _newWidth;
+}
+
+void AGSWaves::Warper(ScriptMethodParams ¶ms) {
+ PARAMS5(int, swarp, int, sadjust, int, x1, int, y1, int, x2);
+
+ ix = 0.0;
+ iy = 0.0;
+ ua = 0.0;
+ // some precautions against non-positive values for width and height
+
+ float ax = float(x1), ay = float(y1);
+ float bx = float(x2), by = float(_y2);
+ float cx = float(_x3), cy = float(_y3);
+ float dx = float(_x4), dy = float(_y4);
+
+ int w = int(max4(ax, bx, cx, dx)) + 1;
+ int h = int(max4(ay, by, cy, dy)) + 1;
+
+ BITMAP *refsrc = _engine->GetSpriteGraphic(swarp);
+ int refsrc_width = 640;
+ int refsrc_height = 360;
+ int refsrc_depth = 32;
+ _engine->GetBitmapDimensions(refsrc, &refsrc_width, &refsrc_height, &refsrc_depth);
+ unsigned int **refsprite_pixels = (unsigned int **)_engine->GetRawBitmapSurface(refsrc);
+ _engine->ReleaseBitmapSurface(refsrc);
+
+
+ // create temporary sprite holding the warped version
+ BITMAP *resizeb = _engine->GetSpriteGraphic(sadjust);
+ int src_width = 640;
+ int src_height = 360;
+ int src_depth = 32;
+ _engine->GetBitmapDimensions(resizeb, &src_width, &src_height, &src_depth);
+ unsigned int **sprite_pixels = (unsigned int **)_engine->GetRawBitmapSurface(resizeb);
+
+
+ int ow = refsrc_width, oh = refsrc_height;
+
+ int x, y; // pixel coords
+ float fx, fy; // original sprite's in between pixel coords
+
+ int il;
+
+ // calculate intersections of opposing sides
+ float orx_x, orx_y, ory_x, ory_y;
+ bool xp = false, yp = false; // parallel sides?
+
+ // AC and BD to get intersection of all "vertical lines"
+
+ il = IntersectLines(ax, ay, cx, cy, bx, by, dx, dy);
+ if (il == 0) {
+ // parallel sides, store directional vector
+ orx_x = cx - ax;
+ orx_y = cy - ay;
+ xp = true;
+ } else {
+ // store intersection of sides
+ orx_x = ix;
+ orx_y = iy;
+ }
+ // AB and CD to get intersection of all "horizontal lines"
+ il = IntersectLines(ax, ay, bx, by, cx, cy, dx, dy);
+ if (il == 0) {
+ // parallel sides, store directional vector
+ ory_x = bx - ax;
+ ory_y = by - ay;
+ yp = true;
+ } else {
+ // store intersection of sides
+ ory_x = ix;
+ ory_y = iy;
+ }
+
+ int xm = int(min4(ax, bx, cx, dx)); // x loop starts here
+
+ y = int(min4(ay, by, cy, dy));
+ while (y < h) {
+ x = xm;
+ while (x < w) {
+
+ // calculate original pixel
+
+ // x:
+ if (xp) il = IntersectLines(ax, ay, bx, by, float(x), float(y), float(x) + orx_x, float(y) + orx_y);
+ else il = IntersectLines(ax, ay, bx, by, float(x), float(y), orx_x, orx_y);
+ fx = float(ow - 1) * ua;
+
+ float ux = ua;
+
+ // y:
+ if (yp) il = IntersectLines(ax, ay, cx, cy, float(x), float(y), float(x) + ory_x, float(y) + ory_y);
+ else il = IntersectLines(ax, ay, cx, cy, float(x), float(y), ory_x, ory_y);
+ fy = float(oh - 1) * ua;
+
+ // only draw if within original sprite
+ if (ux >= 0.0 && ux <= 1.0 && ua >= 0.0 && ua <= 1.0) {
+ int refY = (int)CLIP(fy, (float)0.0, float(refsrc_height - 1));
+ int refX = (int)CLIP(fx, (float)0.0, float(refsrc_width - 1));
+
+ int setcolor = refsprite_pixels[refY][refX];
+
+ int setY = (int)CLIP((float)y, (float)0.0, (float)(src_height - 1));
+ int setX = (int)CLIP((float)x, (float)0.0, (float)(src_width - 1));
+
+ sprite_pixels[setY][setX] = setcolor;
+ }
+
+ x++;
+ }
+
+ y++;
+ }
+
+ _newWidth = w;
+ _newHeight = h;
+ _engine->ReleaseBitmapSurface(resizeb);
+}
+
+void AGSWaves::SetWarper(ScriptMethodParams ¶ms) {
+ //PARAMS5(int, y2x, int, x3x, int, y3x, int, x4x, int, y4x);
+}
+
+
+int AGSWaves::IntersectLines(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4) {
+ // check a
+ if (x1 == x2 && y1 == y2)
+ return -1;
+ // check b
+ if (x3 == x4 && y3 == y4)
+ return -1;
+ float den = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1);
+ float num12 = (x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3);
+ float num34 = (x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3);
+
+ if (den == 0.0) { // no intersection
+ if (num12 == 0.0 && num34 == 0.0)
+ return 2;
+ return 0;
+ }
+
+ ua = num12 / den;
+ ix = x1 + ua * (x2 - x1);
+ iy = y1 + ua * (y2 - y1);
+
+ return 1;
+}
+
+} // namespace AGSWaves
+} // namespace Plugins
+} // namespace AGS3
Commit: f5afbc964d2c3daf4f17aea674af184e4d62efbe
https://github.com/scummvm/scummvm/commit/f5afbc964d2c3daf4f17aea674af184e4d62efbe
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-20T20:25:54-07:00
Commit Message:
AGS: Implemented AGSWaves weather methods
Changed paths:
A engines/ags/plugins/ags_waves/weather.cpp
engines/ags/module.mk
engines/ags/plugins/ags_waves/ags_waves.cpp
engines/ags/plugins/ags_waves/ags_waves.h
engines/ags/plugins/ags_waves/sound.cpp
engines/ags/plugins/ags_waves/vars.h
diff --git a/engines/ags/module.mk b/engines/ags/module.mk
index 5d3c4ef7ac..60ba8f8ca6 100644
--- a/engines/ags/module.mk
+++ b/engines/ags/module.mk
@@ -355,7 +355,8 @@ MODULE_OBJS = \
plugins/ags_waves/data.o \
plugins/ags_waves/draw.o \
plugins/ags_waves/sound.o \
- plugins/ags_waves/warper.o
+ plugins/ags_waves/warper.o \
+ plugins/ags_waves/weather.o
ifdef ENABLE_AGS_TESTS
MODULE_OBJS += \
diff --git a/engines/ags/plugins/ags_waves/ags_waves.cpp b/engines/ags/plugins/ags_waves/ags_waves.cpp
index d8ebbf13f2..fec48d1129 100644
--- a/engines/ags/plugins/ags_waves/ags_waves.cpp
+++ b/engines/ags/plugins/ags_waves/ags_waves.cpp
@@ -99,26 +99,6 @@ void AGSWaves::AGS_EngineStartup(IAGSEngine *engine) {
SCRIPT_METHOD(SetWalkbehindBaserine, AGSWaves::SetWalkbehindBaserine);
}
-void AGSWaves::FireUpdate(ScriptMethodParams ¶ms) {
- //PARAMS2(int, getDynamicSprite, bool, Fire2Visible));
-}
-
-void AGSWaves::WindUpdate(ScriptMethodParams ¶ms) {
- //PARAMS4(int, ForceX, int, ForceY, int, Transparency, int, sprite);
-}
-
-void AGSWaves::SetWindValues(ScriptMethodParams ¶ms) {
- //PARAMS4(int, w, int, h, int, pr, int, prev);
-}
-
-void AGSWaves::RainUpdate(ScriptMethodParams ¶ms) {
- //PARAMS7(int, rdensity, int, FX, int, FY, int, RW, int, RH, int, graphic, float, perc);
-}
-
-void AGSWaves::NoiseCreator(ScriptMethodParams ¶ms) {
- //PARAMS2(int, graphic, int, setA);
-}
-
void AGSWaves::StartingValues() {
GeneralAudio.NumOfChannels = 0;
GeneralAudio.Initialized = false;
diff --git a/engines/ags/plugins/ags_waves/ags_waves.h b/engines/ags/plugins/ags_waves/ags_waves.h
index 6f06bd879a..700c5bad76 100644
--- a/engines/ags/plugins/ags_waves/ags_waves.h
+++ b/engines/ags/plugins/ags_waves/ags_waves.h
@@ -132,6 +132,17 @@ private:
static float max4(float m1, float m2, float m3, float m4) {
return MAX(MAX(m1, m2), MAX(m3, m4));
}
+
+ // Weather
+ void DrawLineCustom(int x1, int y1, int x2, int y2, int graphic, int setR, int setG, int setB, int setA, int TranDif);
+ void CreateParticle(int xx, int yy, int ForceX, int ForceY);
+ void CreateParticle2(int xx, int yy, int ForceX, int ForceY);
+ void CreateParticleF(int xx, int yy, int ForceX, int ForceY);
+ void CreateDustParticle(int xx, int yy);
+ void CreateRainParticleMid(int x, int y, int fx, int fy, int maxpart);
+ void CreateRainParticleFore(int x, int y, int fx, int fy, int maxpart);
+ void CreateRainParticleBack(int x, int y, int fx, int fy, int maxpart);
+
public:
AGSWaves() : PluginBase(), Vars() {}
virtual ~AGSWaves() {}
diff --git a/engines/ags/plugins/ags_waves/sound.cpp b/engines/ags/plugins/ags_waves/sound.cpp
index 224722d4cb..d573828f8a 100644
--- a/engines/ags/plugins/ags_waves/sound.cpp
+++ b/engines/ags/plugins/ags_waves/sound.cpp
@@ -27,6 +27,9 @@ namespace AGS3 {
namespace Plugins {
namespace AGSWaves {
+void AGSWaves::NoiseCreator(ScriptMethodParams ¶ms) {
+ //PARAMS2(int, graphic, int, setA);
+}
void AGSWaves::SFX_Play(ScriptMethodParams ¶ms) {
//PARAMS2(int, SFX, int, repeat);
diff --git a/engines/ags/plugins/ags_waves/vars.h b/engines/ags/plugins/ags_waves/vars.h
index 662076f6fa..352da1b326 100644
--- a/engines/ags/plugins/ags_waves/vars.h
+++ b/engines/ags/plugins/ags_waves/vars.h
@@ -39,7 +39,29 @@ typedef int SDL_AudioSpec;
typedef int SDL_AudioDeviceID;
struct Particle {
- int x, y;
+ int x;
+ int y;
+ int transp;
+ int life;
+ bool active;
+ int dx;
+ int dy;
+ int mlay;
+ int timlay;
+ int movedport;
+ int translay;
+ int translayHold;
+ int width;
+ int height;
+ int fx;
+ int fy;
+ bool doingcircle;
+ float angle;
+ float radius;
+ int doingCircleChance;
+ float angleLay;
+ int frame;
+ float anglespeed;
};
/*---------------------------------------------*/
@@ -144,30 +166,6 @@ struct Vars {
double xvOGG[3];
double yvOGG[3];
- int _x;
- int _y;
- int transp;
- int life;
- bool active;
- int _dx;
- int _dy;
- int mlay;
- int timlay;
- int movedport;
- int translay;
- int translayHold;
- int _width;
- int _height;
- int _fx;
- int _fy;
- bool doingcircle;
- float _angle;
- float _radius;
- int doingCircleChance;
- float angleLay;
- int frame;
- float anglespeed;
-
Particle particles[110];
Particle particlesF[10];
Particle particles2[12];
diff --git a/engines/ags/plugins/ags_waves/weather.cpp b/engines/ags/plugins/ags_waves/weather.cpp
new file mode 100644
index 0000000000..de74fe174f
--- /dev/null
+++ b/engines/ags/plugins/ags_waves/weather.cpp
@@ -0,0 +1,1079 @@
+/* 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.
+ *
+ */
+
+#include "ags/plugins/ags_waves/ags_waves.h"
+
+namespace AGS3 {
+namespace Plugins {
+namespace AGSWaves {
+
+void AGSWaves::FireUpdate(ScriptMethodParams ¶ms) {
+ PARAMS2(int, getDynamicSprite, bool, Fire2Visible);
+
+ BITMAP *src = _engine->GetSpriteGraphic(getDynamicSprite);
+ uint32 **pixel_src = (uint32 **)_engine->GetRawBitmapSurface(src);
+ int src_width = 640;
+ int src_height = 360;
+ int src_depth = 32;
+ _engine->GetBitmapDimensions(src, &src_width, &src_height, &src_depth);
+
+ //OUTLINE
+ creationdelay += int(2.0);
+ if (creationdelay > 4 && Fire2Visible) {
+ int by = 0;
+ while (by < 6) {
+ int dnx = 95 + (Random(535 - 95));
+ int dny = Random(236);
+
+ PluginMethod sfGetRegionXY = _engine->GetScriptFunctionAddress("GetRegionAt");
+ int getID = sfGetRegionXY(dnx, dny);
+
+ while (getID != 10) {
+ dnx = 95 + (Random(535 - 95));
+ dny = Random(236);
+ getID = sfGetRegionXY(dnx, dny);
+ }
+ CreateDustParticle(dnx, dny);
+ by++;
+ }
+
+ creationdelay = 0;
+ }
+ int h = dsizeDust - 1;
+ while (h > 0) {
+ if (dusts[h].life > 0) {
+ dusts[h].life -= int(2.0);
+
+ int setX = dusts[h].x;
+ int setY = dusts[h].y;
+
+ if (setX < 0) setX = 0;
+ if (setX > src_width) setX = src_width;
+
+ if (setY < 0) setY = 0;
+ if (setY > src_height) setY = src_height;
+
+ int Rf = Random(100);
+ int rv, gv, bv, av;
+
+ if (Rf < 50) {
+ rv = 255; gv = 128; bv = 0;
+ } else {
+ rv = 231; gv = 71; bv = 24;
+ }
+
+ av = int((float(255 * (150 - dusts[h].transp))) / 100.0);
+
+
+ pixel_src[setY][setX] = SetColorRGBA(rv, gv, bv, av);
+
+ //drawt.DrawImage(dusts[h].x, dusts[h].y, sg, dusts[h].transp);
+ dusts[h].timlay += int(8.0);
+ if (dusts[h].timlay > dusts[h].mlay) {
+ dusts[h].timlay = 0;
+ dusts[h].x += dusts[h].dx + Random(1);
+ dusts[h].y += dusts[h].dy - (Random(1));
+ }
+ dusts[h].translay += 2;
+ if (dusts[h].translay >= dusts[h].translayHold) {
+ if (dusts[h].transp <= 99) dusts[h].transp++;
+ else dusts[h].life = 0;
+ }
+ } else {
+ dusts[h].active = false;
+ }
+ h--;
+ }
+
+ _engine->ReleaseBitmapSurface(src);
+}
+
+void AGSWaves::WindUpdate(ScriptMethodParams ¶ms) {
+ PARAMS4(int, ForceX, int, ForceY, int, Transparency, int, sprite);
+
+ BITMAP *src = _engine->GetSpriteGraphic(sprite);
+ int src_width = 640;
+ int src_height = 360;
+ int src_depth = 32;
+ _engine->GetBitmapDimensions(src, &src_width, &src_height, &src_depth);
+ uint32 **sprite_pixels = (uint32 **)_engine->GetRawBitmapSurface(src);
+
+ int by = 0;
+ while (by < 2) {
+ int dnx = Random(ww + 250) - 250;
+ int dny = Random(hh);
+ CreateParticle(dnx, dny, ForceX, ForceY);
+ by++;
+ }
+
+ int dnx;
+ if (ForceX > 0) dnx = (Random(ww + 250) - 250) - (50 + Random(100));
+ else dnx = Random(ww + 250) - 250;
+ //
+ int dny = Random(hh);
+ CreateParticle2(dnx, dny, ForceX, ForceY);
+
+
+ dnx = -(20 + Random(50));//Random(ww);
+ if (dnx < -160) dnx = -160;
+ if (dnx > ww + 160) dnx = ww + 160;
+
+ dny = Random(hh);
+ CreateParticleF(dnx, dny, ForceX, ForceY);
+
+ int h = dsize - 1;
+
+ if (h < dsizeF - 1) {
+ h = dsizeF - 1;
+ }
+
+ int setByx = 0;
+ if (proom == 3 && prevroom == 14) {
+ setByx = 640;
+ }
+ if (proom == 4 && prevroom == 8) {
+ setByx -= 480;
+ }
+ while (h > 0) {
+ if (particles[h].life > 0) {
+ particles[h].life -= int(3.0);
+ particles[h].doingCircleChance -= 2;
+ int df = 100 - particles[h].transp;
+ df = 10 - (df / 4);
+
+ int pwidth = particles[h].width + df;
+ int pheight = particles[h].height + df;
+
+ int px = particles[h].x - (pwidth / 2);
+ int py = particles[h].y - (pheight / 2);
+ int tp = particles[h].transp + Transparency;
+
+ if (tp > 100) tp = 100;
+
+ int pgraph = 0;
+ int SplitBetweenTwo = Random(100);
+ if (SplitBetweenTwo <= 50) pgraph = 813;
+ else pgraph = 4466;
+
+ if (tp != 100) {
+
+ BITMAP *src2 = _engine->GetSpriteGraphic(pgraph + particles[h].frame);
+
+
+ int src2_width = 640;
+ int src2_height = 360;
+ int src2_depth = 32;
+ _engine->GetBitmapDimensions(src2, &src2_width, &src2_height, &src2_depth);
+ uint32 **sprite_pixels2 = (uint32 **)_engine->GetRawBitmapSurface(src2);
+ _engine->ReleaseBitmapSurface(src2);
+
+ int startx = px + setByx;
+ int endx = px + setByx + src2_width;
+ int starty = py;
+ int endy = py + src2_height;
+
+
+
+ int x, y;
+ int ny = 0;
+ for (y = starty; y < endy; y++) {
+ int nx = 0;
+ for (x = startx; x < endx; x++) {
+ int setX = nx;
+ int setY = ny;
+ if (setX < 0)setX = 0;
+ if (setX > src2_width - 1) setX = src2_width - 1;
+ if (setY < 0) setY = 0;
+ if (setY > src2_height - 1) setY = src2_height - 1;
+
+ int netX = x;
+ int netY = y;
+
+
+ if (netX < 0) netX = 0;
+ if (netX > src_width - 1) netX = src_width - 1;
+ if (netY < 0) netY = 0;
+ if (netY > src_height - 1) netY = src_height - 1;
+
+ int clr = sprite_pixels2[setY][setX];
+ int rv = getRcolor(clr);
+ int gv = getGcolor(clr);
+ int bv = getBcolor(clr);
+ int av = getAcolor(clr);
+
+ av = int(float((av * (100 - tp))) / 100.0);
+
+ sprite_pixels[netY][netX] = SetColorRGBA(rv, gv, bv, av);
+ nx++;
+ }
+ ny++;
+ }
+
+ }
+ particles[h].timlay += int(6.0);
+ if (particles[h].timlay > particles[h].mlay) {
+ particles[h].frame++;
+ if (particles[h].frame > 6) particles[h].frame = 0;
+ particles[h].timlay = 0;
+ particles[h].x += particles[h].dx + particles[h].fx;
+ particles[h].y += particles[h].dy + particles[h].fy;//Random(1);
+ }
+ particles[h].translay += 2;
+ if (particles[h].translay >= particles[h].translayHold) {
+ if (particles[h].transp <= 99) particles[h].transp++;
+ else {
+ particles[h].life = 0;
+ }
+ }
+ if (particles[h].x >= (ww - 90) + setByx || particles[h].x < 90 + setByx) {
+ if (particles[h].transp <= 99)particles[h].transp++;
+ else {
+ particles[h].life = 0;
+ }
+ }
+
+ if (!particles[h].doingcircle && particles[h].angle == 0.0
+ && particles[h].doingCircleChance <= 0) {
+ particles[h].doingcircle = true;
+ }
+ if (particles[h].doingcircle) {
+ particles[h].angleLay += float(1 + WForceX[h]) * 1.5;
+ if (particles[h].angleLay > 12.0) {
+ particles[h].angleLay = 0.0;
+ particles[h].angle += particles[h].anglespeed;
+ int Y = particles[h].y + int((sin(particles[h].angle) * particles[h].radius));
+ int X = particles[h].x + int((cos(particles[h].angle) * particles[h].radius));
+ particles[h].x = X;
+ particles[h].y = Y;
+ }
+ }
+ particles[h].fx = ForceX;
+ particles[h].fy = ForceY;
+
+ } else {
+ particles[h].active = false;
+ }
+
+
+
+
+
+
+ if (h <= 5 && particlesF[h].life > 0) {
+ int pwidth = particlesF[h].width;
+ int pheight = particlesF[h].height;
+ int px = particlesF[h].x - (pwidth / 2);
+ int py = particlesF[h].y - (pheight / 2);
+ int pgraph = 0;
+ int SplitBetweenTwo = Random(100);
+ if (SplitBetweenTwo <= 50) pgraph = 806;
+ else pgraph = 4459;
+
+ int tp = particlesF[h].transp + Transparency;
+ if (tp > 100) tp = 100;
+
+
+ if (tp != 100) {
+
+ BITMAP *src2 = _engine->GetSpriteGraphic(pgraph + particlesF[h].frame);
+ int src2_width = 640;
+ int src2_height = 360;
+ int src2_depth = 32;
+ _engine->GetBitmapDimensions(src2, &src2_width, &src2_height, &src2_depth);
+ uint32 **sprite_pixels2 = (uint32 **)_engine->GetRawBitmapSurface(src2);
+ _engine->ReleaseBitmapSurface(src2);
+
+ int startx = px + setByx;
+ int endx = px + setByx + src2_width;
+ int starty = py;
+ int endy = py + src2_height;
+
+
+ int x, y;
+ int ny = 0;
+ for (y = starty; y < endy; y++) {
+ int nx = 0;
+ for (x = startx; x < endx; x++) {
+ int setX = nx;
+ int setY = ny;
+ if (setX < 0)setX = 0;
+ if (setX > src2_width - 1) setX = src2_width - 1;
+ if (setY < 0) setY = 0;
+ if (setY > src2_height - 1) setY = src2_height - 1;
+
+ int netX = x;
+ int netY = y;
+
+
+ if (netX < 0) netX = 0;
+ if (netX > src_width - 1) netX = src_width - 1;
+ if (netY < 0) netY = 0;
+ if (netY > src_height - 1) netY = src_height - 1;
+
+ int clr = sprite_pixels2[setY][setX];
+ int rv = getRcolor(clr);
+ int gv = getGcolor(clr);
+ int bv = getBcolor(clr);
+ int av = getAcolor(clr);
+
+ av = int(float((av * (100 - tp))) / 100.0);
+
+ sprite_pixels[netY][netX] = SetColorRGBA(rv, gv, bv, av);
+
+ nx++;
+ }
+ ny++;
+ }
+
+
+
+
+ // drawt.DrawImage(px+setByx, py, , tp, pwidth, pheight);
+ }
+ particlesF[h].timlay += int(6.0);
+ if (particlesF[h].timlay > particlesF[h].mlay) {
+ particlesF[h].frame++;
+ if (particlesF[h].frame > 6) particlesF[h].frame = 0;
+ particlesF[h].timlay = 0;
+ particlesF[h].x += particlesF[h].dx + ForceX;
+ particlesF[h].y += particlesF[h].dy + ForceY;
+ }
+
+
+ if (particlesF[h].x >= ww - 90 || particlesF[h].x < 90) {
+ particlesF[h].translay += 2;
+ if (particlesF[h].translay >= particlesF[h].translayHold) {
+ if (particlesF[h].transp <= 99) particlesF[h].transp++;
+ else {
+ particlesF[h].life = 0;
+ }
+ }
+ }
+ } else {
+ if (h <= 9) particlesF[h].active = false;
+ }
+
+
+ //SECOND PARTICLES
+ if (h <= 10) {
+ if (particles2[h].life > 0) {
+ particles2[h].life -= int(3.0);
+ particles2[h].doingCircleChance -= 1;
+ int df = 100 - particles2[h].transp;//45-0
+ df = 10 - (df / 4);//10-0
+
+ int pwidth = particles2[h].width + df;
+ int pheight = particles2[h].height + df;
+
+ int px = particles2[h].x - (pwidth / 2);
+ int py = particles2[h].y - (pheight / 2);
+ int tp = particles2[h].transp + Transparency;
+
+ if (tp > 100) tp = 100;
+
+ int pgraph = 5224;
+
+ if (tp != 100) {
+
+ BITMAP *src2 = _engine->GetSpriteGraphic(pgraph + particles2[h].frame);
+
+
+ int src2_width = 640;
+ int src2_height = 360;
+ int src2_depth = 32;
+ _engine->GetBitmapDimensions(src2, &src2_width, &src2_height, &src2_depth);
+ uint32 **sprite_pixels2 = (uint32 **)_engine->GetRawBitmapSurface(src2);
+ _engine->ReleaseBitmapSurface(src2);
+
+ int startx = px + setByx;
+ int endx = px + setByx + src2_width;
+ int starty = py;
+ int endy = py + src2_height;
+
+
+
+ int x, y;
+ int ny = 0;
+ for (y = starty; y < endy; y++) {
+ int nx = 0;
+ for (x = startx; x < endx; x++) {
+ int setX = nx;
+ int setY = ny;
+ if (setX < 0)setX = 0;
+ if (setX > src2_width - 1) setX = src2_width - 1;
+ if (setY < 0) setY = 0;
+ if (setY > src2_height - 1) setY = src2_height - 1;
+
+ int netX = x;
+ int netY = y;
+
+
+ if (netX < 0) netX = 0;
+ if (netX > src_width - 1) netX = src_width - 1;
+ if (netY < 0) netY = 0;
+ if (netY > src_height - 1) netY = src_height - 1;
+
+ int clr = sprite_pixels2[setY][setX];
+ int rv = getRcolor(clr);
+ int gv = getGcolor(clr);
+ int bv = getBcolor(clr);
+ int av = getAcolor(clr);
+
+ av = int(float((av * (100 - tp))) / 100.0);
+
+ sprite_pixels[netY][netX] = SetColorRGBA(rv, gv, bv, av);
+ nx++;
+ }
+ ny++;
+ }
+
+
+ }
+ particles2[h].timlay += int(6.0);
+ if (particles2[h].timlay > particles2[h].mlay) {
+ particles2[h].frame++;
+ if (particles2[h].frame > 7) particles2[h].frame = 0;
+ particles2[h].timlay = 0;
+ particles2[h].x += particles2[h].dx + particles2[h].fx;
+ particles2[h].y += particles2[h].dy + particles2[h].fy;//Random(1);
+ }
+ particles2[h].translay += 2;
+ if (particles2[h].translay >= particles2[h].translayHold) {
+ if (particles2[h].transp <= 99) particles2[h].transp++;
+ else {
+ particles2[h].life = 0;
+ }
+ }
+ if (particles2[h].x >= (ww - 90) + setByx || particles2[h].x < 90 + setByx) {
+ if (particles2[h].transp <= 99)particles2[h].transp++;
+ else {
+ particles2[h].life = 0;
+ }
+ }
+
+ if (!particles2[h].doingcircle && particles2[h].angle == 0.0
+ && particles2[h].doingCircleChance <= 0) {
+ particles2[h].doingcircle = true;
+ }
+ if (particles2[h].doingcircle) {
+ particles2[h].angleLay += float((1 + WForceX[h + 200]));
+ if (particles2[h].angleLay > 12.0) {
+ particles2[h].angleLay = 0.0;
+ particles2[h].angle += particles2[h].anglespeed;
+ int Y = particles2[h].y + int((sin(particles2[h].angle) * particles2[h].radius));
+ int X = particles2[h].x + int((cos(particles2[h].angle) * particles2[h].radius));
+ particles2[h].x = X;
+ particles2[h].y = Y;
+ }
+ }
+ particles2[h].fx = int(float(ForceX) * 3.5);
+ particles2[h].fy = int(float(ForceY) * 3.5);
+
+ } else {
+ particles2[h].active = false;
+ }
+ }
+
+ // SECOND PARTICLES
+ h--;
+ }
+
+ _engine->ReleaseBitmapSurface(src);
+}
+
+void AGSWaves::SetWindValues(ScriptMethodParams ¶ms) {
+ PARAMS4(int, w, int, h, int, pr, int, prev);
+
+ ww = w;
+ hh = h;
+ proom = pr;
+ prevroom = prev;
+}
+
+void AGSWaves::RainUpdate(ScriptMethodParams ¶ms) {
+ PARAMS7(int, rdensity, int, FX, int, FY, int, RW, int, RH, int, graphic, float, perc);
+
+ bool drawBack = true;
+ bool drawMid = true;
+ bool drawFore = true;
+ int h = 0;
+
+ int cdelay = 0;
+ while (cdelay < rdensity) {
+ if (drawMid) CreateRainParticleMid(Random(640 * 4) - 640, -(20 + Random(50)), FX, FY, int((400.0 * perc) / 100.0));
+ if (drawFore) CreateRainParticleFore(Random(640 * 4) - 640, -(20 + Random(50)), FX, FY, int((40.0 * perc) / 100.0));
+ if (drawBack) {
+ CreateRainParticleBack(Random(640 * 4) - 640, -(20 + Random(50)), FX, FY, int((800.0 * perc) / 100.0));
+ CreateRainParticleBack(Random(640 * 4) - 640, -(20 + Random(50)), FX, FY, int((800.0 * perc) / 100.0));
+ }
+ cdelay++;
+ }
+
+ BITMAP *src = _engine->GetSpriteGraphic(graphic);
+ int src_width = 640;
+ int src_height = 360;
+ int src_depth = 32;
+ _engine->GetBitmapDimensions(src, &src_width, &src_height, &src_depth);
+// uint32 **sprite_pixels = (uint32 **)_engine->GetRawBitmapSurface(src);
+
+ int rotAngle = 6;
+ int rotTrans = 60 + Random(40 + 60);//Random(103)+122;
+ int rotX = -50;
+ int rotY = 120;
+ int totalTrans = 0;
+
+ int maxPart = 800;
+ if (!drawBack) maxPart = 400;
+ if (!drawMid) maxPart = 400;
+
+ while (h < maxPart) {
+ if (h < 400 && drawMid)RainParticles[h].x = RainParticles[h].x - RW;
+ if (h < 400 && drawFore)RainParticlesFore[h].x = RainParticlesFore[h].x - RW;
+ RainParticlesBack[h].x = RainParticlesBack[h].x - RW;
+
+ h++;
+ }
+
+ h = 0;
+ //BACK
+ while (h < maxPart) {
+ //FORE
+ if (h < 400 && drawFore) {
+ if (RainParticlesFore[h].life > 0 && RainParticlesFore[h].active) {
+ RainParticlesFore[h].life -= 4;
+ RainParticlesFore[h].translay += 2;
+ if (RainParticlesFore[h].translay > RainParticlesFore[h].transhold) {
+ RainParticlesFore[h].translay = 0;
+ RainParticlesFore[h].trans += 2;
+ }
+
+ int setRainTrans = RainParticlesFore[h].trans + 8 + Random(10) + totalTrans;
+ if (setRainTrans > 100) {
+ setRainTrans = 100;
+ }
+
+ if (RainParticlesFore[h].y > RH + 30
+ || RainParticlesFore[h].trans == 100) {
+ RainParticlesFore[h].active = false;
+ } else {
+ //int thick =3;
+ //DRAW LINE
+ int alpha = int(float((255 * (100 - setRainTrans))) / 100.0);
+
+ int x1 = RainParticlesFore[h].x;
+ int y1 = RainParticlesFore[h].y;
+ int x2 = RainParticlesFore[h].x + (RainParticlesFore[h].fx * 2);
+ int y2 = RainParticlesFore[h].y + (RainParticlesFore[h].fy * 2);
+
+ DrawLineCustom(x1, y1, x2, y2, graphic, 255 - 120, 255 - 120, 255 - 120, alpha - 80, 6);
+ DrawLineCustom(x1 - 1, y1, x2 - 1, y2, graphic, 255 - 120, 255 - 120, 255 - 120, alpha - 80, 6);
+
+ DrawLineCustom((x1 - rotX), y1 - rotY, (x2 - rotX) - rotAngle, y2 - rotY, graphic, 255 - 120, 255 - 120, 255 - 120, (alpha - 80) - rotTrans, 6);
+ DrawLineCustom((x1 - 1) - rotX, y1 - rotY, ((x2 - 1) - rotX) - rotAngle, y2 - rotY, graphic, 255 - 120, 255 - 120, 255 - 120, (alpha - 80) - rotTrans, 6);
+
+ RainParticlesFore[h].x += RainParticlesFore[h].fx;
+ RainParticlesFore[h].y += RainParticlesFore[h].fy;
+ }
+ } else {
+ RainParticlesFore[h].life = 0;
+ RainParticlesFore[h].active = false;
+ }
+ }
+ //FORE
+
+ //MID
+ if (!h && drawMid /* h < drawMid */) {
+ if (RainParticles[h].life > 0 && RainParticles[h].active) {
+ RainParticles[h].life -= 4;
+
+ RainParticles[h].translay += 2;
+ if (RainParticles[h].translay > RainParticles[h].transhold) {
+ RainParticles[h].translay = 0;
+ RainParticles[h].trans += 3;
+ }
+
+
+ int setRainTrans = RainParticles[h].trans + 4 + Random(5) + totalTrans;
+ if (setRainTrans > 100) {
+ setRainTrans = 100;
+ }
+
+ if (RainParticles[h].y > RH + 30
+ || RainParticles[h].trans == 100) {
+ RainParticles[h].active = false;
+ } else {
+ //int thick=2;
+ //DRAW LINE
+ int alpha = int(float((255 * (100 - setRainTrans))) / 100.0);
+
+ int x1 = RainParticles[h].x;
+ int y1 = RainParticles[h].y;
+ int x2 = RainParticles[h].x + RainParticles[h].fx;
+ int y2 = RainParticles[h].y + RainParticles[h].fy;
+
+ DrawLineCustom(x1, y1, x2, y2, graphic, 255 - 40, 255 - 40, 255 - 40, alpha, 6);
+ DrawLineCustom(x1 - 1, y1, x2 - 1, y2, graphic, 255 - 40, 255 - 40, 255 - 40, alpha, 6);
+
+ DrawLineCustom((x1)-rotX, y1 - rotY, (x2 - rotX) - rotAngle, y2 - rotY, graphic, 255 - 40, 255 - 40, 255 - 40, alpha - rotTrans, 6);
+ DrawLineCustom((x1 - 1) - rotX, y1 - rotY, ((x2 - 1) - rotX) - rotAngle, y2 - rotY, graphic, 255 - 40, 255 - 40, 255 - 40, alpha - rotTrans, 6);
+
+ RainParticles[h].x += RainParticles[h].fx;
+ RainParticles[h].y += RainParticles[h].fy;
+ }
+
+ } else {
+ RainParticles[h].life = 0;
+ RainParticles[h].active = false;
+ }
+ }
+ //MID
+ if (h < 800 && drawBack) {
+ if (RainParticlesBack[h].life > 0 && RainParticlesBack[h].active) {
+ RainParticlesBack[h].life -= 4;
+ RainParticlesBack[h].translay += 2;
+ if (RainParticlesBack[h].translay > RainParticlesBack[h].transhold) {
+ RainParticlesBack[h].translay = 0;
+ RainParticlesBack[h].trans++;
+ }
+
+ int setRainTrans = RainParticlesBack[h].trans + totalTrans;//+8+Random(10);
+ if (setRainTrans > 100) {
+ setRainTrans = 100;
+ }
+
+ if (RainParticlesBack[h].y > RH + 30
+ || RainParticlesBack[h].trans == 100) {
+ RainParticlesBack[h].active = false;
+ } else {
+ //int thick =1;
+ //DRAW LINE
+ int x1 = RainParticlesBack[h].x;
+ int y1 = RainParticlesBack[h].y;
+ int x2 = RainParticlesBack[h].x + RainParticlesBack[h].fx;
+ int y2 = RainParticlesBack[h].y + RainParticlesBack[h].fy;
+
+ int alpha = int(float((255 * (100 - setRainTrans))) / 100.0);
+ DrawLineCustom(x1, y1, x2, y2, graphic, 255 - 80, 255 - 80, 255 - 80, alpha, 3);
+ DrawLineCustom((x1 - rotX), y1 - rotY, (x2 - rotX) - rotAngle, y2 - rotY, graphic, 255 - 80, 255 - 80, 255 - 80, alpha - rotTrans, 3);
+
+ RainParticlesBack[h].x += RainParticlesBack[h].fx;
+ RainParticlesBack[h].y += RainParticlesBack[h].fy;
+ }
+ } else {
+ RainParticlesBack[h].life = 0;
+ RainParticlesBack[h].active = false;
+ }
+ }
+ h++;
+ }
+
+ // BACK
+ _engine->ReleaseBitmapSurface(src);
+}
+
+
+void AGSWaves::DrawLineCustom(int x1, int y1, int x2, int y2, int graphic, int setR, int setG, int setB, int setA, int TranDif) {
+ int ALine = 0;
+ BITMAP *src = _engine->GetSpriteGraphic(graphic);
+ int src_width = 640;
+ int src_height = 360;
+ int src_depth = 32;
+ _engine->GetBitmapDimensions(src, &src_width, &src_height, &src_depth);
+ uint32 **sprite_pixels = (uint32 **)_engine->GetRawBitmapSurface(src);
+
+ int DiffA = -26;
+
+ int x, y;
+ int xe;
+ int ye;
+ int dx = x2 - x1;
+ int dy = y2 - y1;
+ int dx1 = abs(dx);
+ int dy1 = abs(dy);
+ int px = (2 * dy1) - dx1;
+ int py = (2 * dx1) - dy1;
+ if (dy1 <= dx1) {
+ if (dx >= 0) {
+ x = x1;
+ y = y1;
+ xe = x2;
+ } else {
+ x = x2; y = y2; xe = x1;
+ }
+
+ int xx2 = x - 320;
+ int yy2 = y;
+
+ if (xx2 < 0 || xx2 > src_width - 1 || yy2 > src_height - 1 || yy2 < 0) {
+ } else {
+ sprite_pixels[yy2][xx2] = SetColorRGBA(setR, setG, setB, setA + DiffA + (ALine * TranDif));
+ }
+
+ int xx3 = x + 320;
+ int yy3 = y;
+
+ if (xx3 < 0 || xx3 > src_width - 1 || yy3 > src_height - 1 || yy3 < 0) {
+ } else {
+ sprite_pixels[yy3][xx3] = SetColorRGBA(setR, setG, setB, setA + DiffA + (ALine * TranDif));
+ }
+
+ int xx = x;
+ int yy = y;
+
+ if (xx < 0 || xx > src_width - 1 || yy > src_height - 1 || yy < 0) {
+ } else {
+ sprite_pixels[yy][xx] = SetColorRGBA(setR, setG, setB, setA + (ALine * TranDif));
+ ALine++;
+ }
+
+ int i = 0;
+ while (x < xe) {
+ x = x + 1;
+ if (px < 0) {
+ px = px + 2 * dy1;
+ } else {
+ if ((dx < 0 && dy < 0) || (dx > 0 && dy > 0)) {
+ y = y + 1;
+ } else {
+ y = y - 1;
+ }
+ px = px + 2 * (dy1 - dx1);
+ }
+
+ xx2 = x - 320;
+ yy2 = y;
+ if (xx2 < 0 || xx2 > src_width - 1 || yy2 > src_height - 1 || yy2 < 0) {
+ } else {
+ sprite_pixels[yy2][xx2] = SetColorRGBA(setR, setG, setB, setA + DiffA + (ALine * TranDif));
+ }
+ xx3 = x + 320;
+ yy3 = y;
+ if (xx3 < 0 || xx3 > src_width - 1 || yy3 > src_height - 1 || yy3 < 0) {
+ } else {
+ sprite_pixels[yy3][xx3] = SetColorRGBA(setR, setG, setB, setA + DiffA + (ALine * TranDif));
+ }
+
+ xx = x;
+ yy = y;
+ if (xx < 0 || xx > src_width - 1 || yy > src_height - 1 || yy < 0) {
+ } else {
+ sprite_pixels[yy][xx] = SetColorRGBA(setR, setG, setB, setA + (ALine * TranDif));
+ ALine++;
+ }
+
+ i++;
+ }
+ } else {
+ if (dy >= 0) {
+ x = x1;
+ y = y1;
+ ye = y2 - 1;
+ } else {
+ // Line is drawn top to bottom
+ x = x2;
+ y = y2;
+ ye = y1 - 1;
+ }
+
+ int xx2 = x - 320;
+ int yy2 = y;
+
+ if (xx2 < 0 || xx2 > src_width - 1 || yy2 > src_height - 1 || yy2 < 0) {
+ } else {
+ sprite_pixels[yy2][xx2] = SetColorRGBA(setR, setG, setB, setA + DiffA + (ALine * TranDif));
+ }
+
+ int xx3 = x + 320;
+ int yy3 = y;
+
+ if (xx3 < 0 || xx3 > src_width - 1 || yy3 > src_height - 1 || yy3 < 0) {
+ } else {
+ sprite_pixels[yy3][xx3] = SetColorRGBA(setR, setG, setB, setA + DiffA + (ALine * TranDif));
+ }
+ int xx = x;
+ int yy = y;
+
+ if (xx < 0 || xx > src_width - 1 || yy > src_height - 1 || yy < 0) {
+ } else {
+ sprite_pixels[yy][xx] = SetColorRGBA(setR, setG, setB, setA + (ALine * TranDif));
+ ALine++;
+ }
+
+ int i = 0;
+ while (y < ye) {
+ y = y + 1;
+ if (py <= 0) {
+ py = py + (2 * dx1);
+ } else {
+ if ((dx < 0 && dy < 0) || (dx > 0 && dy > 0)) {
+ x = x + 1;
+ } else {
+ x = x - 1;
+ }
+ py = py + 2 * (dx1 - dy1);
+ }
+ xx2 = x - 320;
+ yy2 = y;
+ if (xx2 < 0 || xx2 > src_width - 1 || yy2 > src_height - 1 || yy2 < 0) {
+ } else {
+ sprite_pixels[yy2][xx2] = SetColorRGBA(setR, setG, setB, setA + DiffA + (ALine * TranDif));
+ }
+ xx3 = x + 320;
+ yy3 = y;
+ if (xx3 < 0 || xx3 > src_width - 1 || yy3 > src_height - 1 || yy3 < 0) {
+ } else {
+ sprite_pixels[yy3][xx3] = SetColorRGBA(setR, setG, setB, setA + DiffA + (ALine * TranDif));
+ }
+ xx = x;
+ yy = y;
+ if (xx < 0 || xx > src_width - 1 || yy > src_height - 1 || yy < 0) {
+ } else {
+ sprite_pixels[yy][xx] = SetColorRGBA(setR, setG, setB, setA + (ALine * TranDif));
+ ALine++;
+ }
+ i++;
+ }
+ }
+
+ _engine->ReleaseBitmapSurface(src);
+}
+
+void AGSWaves::CreateParticle(int xx, int yy, int ForceX, int ForceY) {
+ int h = 0;
+ bool foundparticle = false;
+ int fid = -1;
+ while (h <= dsize && !foundparticle) {
+ if (particles[h].active == false) {
+ foundparticle = true;
+ fid = h;
+ }
+ h++;
+ }
+
+ if (foundparticle) {
+ int d = fid;
+ particles[d].x = xx;
+ particles[d].y = yy;
+ particles[d].dx = 0;
+ particles[d].dy = 0;
+ particles[d].life = 20000;
+ particles[d].transp = 55 + Random(10);
+ particles[d].active = true;
+ particles[d].mlay = 4 + Random(2);
+ particles[d].timlay = 0;
+ particles[d].translay = 0;
+ particles[d].translayHold = 19 + Random(15);
+ particles[d].width = 2 + Random(2);
+ particles[d].height = particles[d].width;
+ particles[d].fx = 0;
+ particles[d].fy = 0;
+ particles[d].doingcircle = false;
+ particles[d].angle = 0.0;
+ particles[d].radius = 4.0 + float(Random(6));
+ particles[d].doingCircleChance = Random(200);
+ particles[d].angleLay = 0.0;
+ particles[d].frame = 0;
+ particles[d].anglespeed = float(Random(20)) / 100.0;
+ WForceX[d] = ForceX;
+ WForceY[d] = ForceY;
+ if (dsize < (raysize - 1)) dsize++;
+ }
+}
+
+void AGSWaves::CreateParticle2(int xx, int yy, int ForceX, int ForceY) {
+ int h = 0;
+ bool foundparticle = false;
+ int fid = -1;
+ while (h <= dsize2 && !foundparticle) {
+ if (particles2[h].active == false) {
+ foundparticle = true;
+ fid = h;
+ }
+ h++;
+ }
+
+ if (foundparticle) {
+ int d = fid;
+ particles2[d].x = xx;
+ particles2[d].y = yy;
+ particles2[d].dx = 0;
+ particles2[d].dy = 0;
+ particles2[d].life = 20000;
+ particles2[d].transp = 65 + Random(15);
+ particles2[d].active = true;
+ particles2[d].mlay = 4 + Random(2);
+ particles2[d].timlay = 0;
+ particles2[d].translay = 0;
+ particles2[d].translayHold = 19 + Random(15);
+ particles2[d].width = 16;
+ particles2[d].height = particles[d].width;
+ particles2[d].fx = 0;
+ particles2[d].fy = 0;
+ particles2[d].doingcircle = false;
+ particles2[d].angle = 0.0;
+ particles2[d].radius = 4.0 + float(Random(6));
+ particles2[d].doingCircleChance = Random(200);
+ particles2[d].angleLay = 0.0;
+ particles2[d].frame = 0;
+ particles2[d].anglespeed = float(Random(20)) / 100.0;
+ WForceX[d + 200] = ForceX;
+ WForceY[d + 200] = ForceY;
+ if (dsize2 < (raysize2 - 1)) dsize2++;
+ }
+}
+
+void AGSWaves::CreateParticleF(int xx, int yy, int ForceX, int ForceY) {
+ int h = 0;
+ bool foundparticle = false;
+ int fid = -1;
+ while (h <= dsizeF && !foundparticle) {
+ if (particlesF[h].active == false) {
+ foundparticle = true;
+ fid = h;
+ }
+ h++;
+ }
+
+ if (foundparticle) {
+ int d = fid;
+ particlesF[d].x = xx;
+ particlesF[d].y = yy;
+ particlesF[d].dx = (-1) + Random(1);
+ particlesF[d].dy = (-1) + Random(1);
+ particlesF[d].life = 20000;
+ particlesF[d].transp = 45 + Random(10);
+ particlesF[d].active = true;
+ particlesF[d].mlay = 4 + Random(2);
+ particlesF[d].timlay = 0;
+ particlesF[d].translay = 0;
+ particlesF[d].translayHold = 19 + Random(15);
+ particlesF[d].width = 8 + Random(2);
+ particlesF[d].height = particlesF[d].width;
+ particlesF[d].fx = 0;
+ particlesF[d].fy = 0;
+ particlesF[d].doingcircle = false;
+ particlesF[d].angle = 0.0;
+ particlesF[d].radius = 4.0 + float(Random(6));
+ particlesF[d].doingCircleChance = Random(200);
+ particlesF[d].angleLay = 0.0;
+ WForceX[d + 100] = ForceX;
+ WForceY[d + 100] = ForceY;
+ particlesF[d].frame = 0;
+ if (dsizeF < (raysizeF - 1)) dsizeF++;
+
+ }
+}
+
+void AGSWaves::CreateDustParticle(int xx, int yy) {
+ int h = 0;
+ bool founddust = false;
+ int fid = -1;
+ while (h <= dsizeDust && !founddust) {
+ if (dusts[h].active == false) {
+ founddust = true;
+ fid = h;
+ }
+ h++;
+ }
+
+ if (founddust) {
+ int d = fid;
+ dusts[d].x = xx;
+ dusts[d].y = yy;
+ dusts[d].dx = (-1) + Random(1);
+ dusts[d].dy = (-1) + Random(1);
+ dusts[d].life = 20000;
+ dusts[d].transp = 55 + Random(10);
+ dusts[d].active = true;
+ dusts[d].mlay = 4 + Random(2);
+ dusts[d].timlay = 0;
+ dusts[d].translay = 0;
+ dusts[d].translayHold = 19 + Random(15);
+ if (dsizeDust < (raysizeDust - 1)) dsizeDust++;
+ }
+}
+
+void AGSWaves::CreateRainParticleMid(int x, int y, int fx, int fy, int maxpart) {
+ int s = 0;
+
+ while (s < maxpart) {
+ if (!RainParticles[s].active) {
+ RainParticles[s].active = true;
+ RainParticles[s].x = x;
+ RainParticles[s].y = y;
+ RainParticles[s].fx = fx;
+ RainParticles[s].fy = fy;
+ RainParticles[s].life = 2000;
+ RainParticles[s].trans = 70 + Random(25);
+ RainParticles[s].transhold = Random(3);
+ RainParticles[s].translay = 0;
+ return;
+ }
+ s++;
+ }
+}
+
+void AGSWaves::CreateRainParticleFore(int x, int y, int fx, int fy, int maxpart) {
+ int s = 0;
+
+ while (s < maxpart) {
+ if (!RainParticlesFore[s].active) {
+ RainParticlesFore[s].active = true;
+ RainParticlesFore[s].x = x;
+ RainParticlesFore[s].y = y;
+ RainParticlesFore[s].fx = fx;//int(1.5*float(fx));
+ RainParticlesFore[s].fy = fy;//int(1.5*float(fy));
+ RainParticlesFore[s].life = 2000;
+ RainParticlesFore[s].trans = 75 + Random(15);
+ RainParticlesFore[s].transhold = Random(3);
+ RainParticlesFore[s].translay = 0;
+ return;
+ }
+ s++;
+ }
+}
+
+void AGSWaves::CreateRainParticleBack(int x, int y, int fx, int fy, int maxpart) {
+ int s = 0;
+
+ while (s < maxpart) {
+ if (!RainParticlesBack[s].active) {
+ RainParticlesBack[s].active = true;
+ RainParticlesBack[s].x = x;
+ RainParticlesBack[s].y = y;
+ if (fx == 0) fx = 1;
+ if (fy == 0) fy = 1;
+ RainParticlesBack[s].fx = fx / 2;
+ RainParticlesBack[s].fy = fy / 2;
+ RainParticlesBack[s].life = 2000;
+ RainParticlesBack[s].trans = 70 + Random(15);
+ RainParticlesBack[s].transhold = 2 + Random(3);
+ RainParticlesBack[s].translay = 0;
+ return;
+ }
+ s++;
+ }
+}
+
+} // namespace AGSWaves
+} // namespace Plugins
+} // namespace AGS3
Commit: aadd100b9c8752933b07d12479bd2a05d3779c34
https://github.com/scummvm/scummvm/commit/aadd100b9c8752933b07d12479bd2a05d3779c34
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-20T20:25:54-07:00
Commit Message:
AGS: Implementing AGSWaves sound methods
Changed paths:
engines/ags/plugins/ags_waves/ags_waves.cpp
engines/ags/plugins/ags_waves/ags_waves.h
engines/ags/plugins/ags_waves/draw.cpp
engines/ags/plugins/ags_waves/sound.cpp
engines/ags/plugins/ags_waves/vars.h
engines/ags/plugins/serializer.h
diff --git a/engines/ags/plugins/ags_waves/ags_waves.cpp b/engines/ags/plugins/ags_waves/ags_waves.cpp
index fec48d1129..f7e7463721 100644
--- a/engines/ags/plugins/ags_waves/ags_waves.cpp
+++ b/engines/ags/plugins/ags_waves/ags_waves.cpp
@@ -21,15 +21,16 @@
*/
#include "ags/plugins/ags_waves/ags_waves.h"
+#include "ags/plugins/serializer.h"
+#include "ags/ags.h"
namespace AGS3 {
namespace Plugins {
namespace AGSWaves {
-const uint32 Magic = 0xACAB0000;
-const uint32 Version = 1;
-const uint32 SaveMagic = Magic + Version;
-const float PI = 3.14159265f;
+AGSWaves::AGSWaves() : PluginBase(), Vars() {
+ _mixer = ::AGS::g_vm->_mixer;
+}
const char *AGSWaves::AGS_GetPluginName() {
return "AGS Waves";
@@ -38,14 +39,14 @@ const char *AGSWaves::AGS_GetPluginName() {
void AGSWaves::AGS_EngineStartup(IAGSEngine *engine) {
PluginBase::AGS_EngineStartup(engine);
- if (engine->version < 13)
- engine->AbortGame("Engine interface is too old, need newer version of AGS.");
+ if (_engine->version < 13)
+ _engine->AbortGame("Engine interface is too old, need newer version of AGS.");
StartingValues();
- Character_GetX = engine->GetScriptFunctionAddress("Character::get_X");
- Character_GetY = engine->GetScriptFunctionAddress("Character::get_Y");
- Character_ID = engine->GetScriptFunctionAddress("Character::ID");
+ Character_GetX = _engine->GetScriptFunctionAddress("Character::get_X");
+ Character_GetY = _engine->GetScriptFunctionAddress("Character::get_Y");
+ Character_ID = _engine->GetScriptFunctionAddress("Character::ID");
SCRIPT_METHOD(DrawScreenEffect, AGSWaves::DrawScreenEffect);
SCRIPT_METHOD(SFX_Play, AGSWaves::SFX_Play);
@@ -99,6 +100,56 @@ void AGSWaves::AGS_EngineStartup(IAGSEngine *engine) {
SCRIPT_METHOD(SetWalkbehindBaserine, AGSWaves::SetWalkbehindBaserine);
}
+int64 AGSWaves::AGS_EngineOnEvent(int event, NumberPtr data) {
+ switch (event) {
+ case AGSE_PREGUIDRAW:
+// Update();
+ break;
+
+ case AGSE_RESTOREGAME: {
+ _mixer->stopAll();
+
+ Serializer s(_engine, data, true);
+ for (int j = 0; j < 500 - 1; ++j) {
+ s.syncAsInt(SFX[j]._repeat);
+ s.syncAsInt(SFX[j]._volume);
+ s.syncAsInt(SFX[j]._playing);
+ }
+ break;
+ }
+
+ case AGSE_SAVEGAME: {
+ Serializer s(_engine, data, true);
+ for (int j = 0; j < 500 - 1; ++j) {
+ s.syncAsInt(SFX[j]._repeat);
+ s.syncAsInt(SFX[j]._volume);
+ s.syncAsInt(SFX[j]._playing);
+ }
+ break;
+ }
+
+ case AGSE_PRESCREENDRAW:
+ // Get screen size once here.
+ _engine->GetScreenDimensions(&screen_width, &screen_height, &screen_color_depth);
+
+ //_engine->UnrequestEventHook(AGSE_SAVEGAME);
+ //_engine->UnrequestEventHook(AGSE_RESTOREGAME);
+ break;
+
+ case AGSE_ENTERROOM:
+ for (int j = 0; j < 500 - 1; ++j) {
+ if (!_mixer->isSoundHandleActive(SFX[j]._soundHandle))
+ UnloadSFX(j);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
void AGSWaves::StartingValues() {
GeneralAudio.NumOfChannels = 0;
GeneralAudio.Initialized = false;
diff --git a/engines/ags/plugins/ags_waves/ags_waves.h b/engines/ags/plugins/ags_waves/ags_waves.h
index 700c5bad76..a6f359947f 100644
--- a/engines/ags/plugins/ags_waves/ags_waves.h
+++ b/engines/ags/plugins/ags_waves/ags_waves.h
@@ -23,6 +23,7 @@
#ifndef AGS_PLUGINS_AGS_WAVES_AGS_WAVES_H
#define AGS_PLUGINS_AGS_WAVES_AGS_WAVES_H
+#include "audio/mixer.h"
#include "ags/plugins/ags_plugin.h"
#include "ags/plugins/ags_waves/vars.h"
@@ -32,6 +33,8 @@ namespace AGSWaves {
class AGSWaves : public PluginBase, public Vars {
SCRIPT_HASH(AGSWaves)
+private:
+ Audio::Mixer *_mixer;
private:
void DrawScreenEffect(ScriptMethodParams ¶ms);
void SFX_Play(ScriptMethodParams ¶ms);
@@ -86,6 +89,7 @@ private:
private:
void StartingValues();
+ void Update();
void CastWave(int delayMax, int PixelsWide, int n);
void DrawEffect(int sprite_a, int sprite_b, int id, int n);
@@ -143,12 +147,38 @@ private:
void CreateRainParticleFore(int x, int y, int fx, int fy, int maxpart);
void CreateRainParticleBack(int x, int y, int fx, int fy, int maxpart);
+ // Sound
+ /**
+ * Plays a sound from the sounds.sfx in the Sounds/ folder
+ * @param soundToPlay The sound to play
+ * @param repeat Times to repeat, -1 for indefine
+ */
+ void PlaySFX(int SoundToPlay, int repeat);
+
+ /**
+ * Loads a sound file to memory
+ * @param i Sound number to load
+ */
+ void LoadSFX(int i);
+
+ /**
+ * Unloads a sound file from memory
+ * @param i Sound number to unload
+ */
+ void UnloadSFX(int i);
+
+ void GlitchFix();
+ void ApplyFilter(int SetFrequency);
+ void SetFilterFrequency(int setFrequency);
+ void MusicPlay(int MusicToPlay, int repeat, int fadeinMS, int fadeoutMS, int pos, bool forceplay, bool fixclick);
+
public:
- AGSWaves() : PluginBase(), Vars() {}
+ AGSWaves();
virtual ~AGSWaves() {}
const char *AGS_GetPluginName() override;
void AGS_EngineStartup(IAGSEngine *engine) override;
+ int64 AGS_EngineOnEvent(int event, NumberPtr data) override;
};
} // namespace AGSWaves
diff --git a/engines/ags/plugins/ags_waves/draw.cpp b/engines/ags/plugins/ags_waves/draw.cpp
index 400cc9e148..b503b3d906 100644
--- a/engines/ags/plugins/ags_waves/draw.cpp
+++ b/engines/ags/plugins/ags_waves/draw.cpp
@@ -981,6 +981,32 @@ void AGSWaves::OutlineOnly(ScriptMethodParams ¶ms) {
_engine->ReleaseBitmapSurface(dst);
}
+void AGSWaves::NoiseCreator(ScriptMethodParams ¶ms) {
+ PARAMS2(int, graphic, int, setA);
+
+ BITMAP *src = _engine->GetSpriteGraphic(graphic);
+ int src_width = 640;
+ int src_height = 360;
+ int src_depth = 32;
+ _engine->GetBitmapDimensions(src, &src_width, &src_height, &src_depth);
+ uint32 **sprite_pixels = (uint32 **)_engine->GetRawBitmapSurface(src);
+
+ int x, y;
+ for (y = 0; y < src_height; y++) {
+ for (x = 0; x < src_width; x++) {
+ //int getColor = sprite_pixels[y][x];
+ int r = Random(256);
+ int g = Random(256);
+ int b = Random(256);
+ int a = setA;
+
+ sprite_pixels[y][x] = SetColorRGBA(r, g, b, a);
+
+ }
+ }
+
+ _engine->ReleaseBitmapSurface(src);
+}
void AGSWaves::CastWave(int delayMax, int PixelsWide, int n) {
tDy[n]++;
diff --git a/engines/ags/plugins/ags_waves/sound.cpp b/engines/ags/plugins/ags_waves/sound.cpp
index d573828f8a..e87491dfd4 100644
--- a/engines/ags/plugins/ags_waves/sound.cpp
+++ b/engines/ags/plugins/ags_waves/sound.cpp
@@ -20,6 +20,9 @@
*
*/
+#include "audio/decoders/wave.h"
+#include "common/file.h"
+#include "common/fs.h"
#include "common/util.h"
#include "ags/plugins/ags_waves/ags_waves.h"
@@ -27,53 +30,149 @@ namespace AGS3 {
namespace Plugins {
namespace AGSWaves {
-void AGSWaves::NoiseCreator(ScriptMethodParams ¶ms) {
- //PARAMS2(int, graphic, int, setA);
-}
+const float PI = 3.14159265f;
void AGSWaves::SFX_Play(ScriptMethodParams ¶ms) {
- //PARAMS2(int, SFX, int, repeat);
+ PARAMS2(int, sfxNum, int, repeat);
+
+ SoundEffect &effect = SFX[sfxNum];
+ if (effect._stream == nullptr) {
+ LoadSFX(sfxNum);
+ }
+
+ Audio::AudioStream *sound = effect._stream;
+ if (sound != nullptr) {
+ effect._volume = 255;
+
+ if (repeat != 1) {
+ assert(repeat != 0);
+ Audio::SeekableAudioStream *sas =
+ dynamic_cast<Audio::SeekableAudioStream *>(sound);
+ assert(sas);
+
+ Audio::LoopingAudioStream *las =
+ new Audio::LoopingAudioStream(sas, repeat, DisposeAfterUse::NO);
+ _mixer->playStream(Audio::Mixer::kSFXSoundType, &effect._soundHandle, las);
+ } else {
+ _mixer->playStream(Audio::Mixer::kSFXSoundType, &effect._soundHandle, sound,
+ -1, effect._volume, 0, DisposeAfterUse::YES);
+ }
+
+ if (OGG_Filter && effect._filter && effect._volume > 1) {
+ warning("TODO: Mix_RegisterEffect(grabChan, LPEffect, NULL, NULL);");
+ }
+
+ effect._repeat = repeat;
+ effect._playing = true;
+ }
}
void AGSWaves::SFX_SetVolume(ScriptMethodParams ¶ms) {
- //PARAMS2(int, SFX, int, volume);
+ PARAMS2(int, sfxNum, int, volume);
+
+ SoundEffect &effect = SFX[sfxNum];
+
+ if (effect._stream != nullptr) {
+ _mixer->setChannelVolume(effect._soundHandle, volume);
+ effect._volume = volume;
+ }
}
void AGSWaves::SFX_GetVolume(ScriptMethodParams ¶ms) {
- //PARAMS1(int, SFX);
- params._result = 0;
+ PARAMS1(int, sfxNum);
+
+ SoundEffect &effect = SFX[sfxNum];
+ params._result = effect._stream ? effect._volume : 0;
}
void AGSWaves::Music_Play(ScriptMethodParams ¶ms) {
- //PARAMS6(int, MFX, int, repeat, int, fadeinMS, int, fadeoutMS, int, Position, bool, fixclick);
+ PARAMS6(int, MFX, int, repeat, int, fadeinMS, int, fadeoutMS, int, Position, bool, fixclick);
+ MusicPlay(MFX, repeat, fadeinMS, fadeoutMS, Position, false, fixclick);
}
void AGSWaves::Music_SetVolume(ScriptMethodParams ¶ms) {
- //PARAMS1(int, volume);
+ PARAMS1(int, volume);
+ _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, volume);
}
void AGSWaves::Music_GetVolume(ScriptMethodParams ¶ms) {
- params._result = 0;
+ params._result = _mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType);
}
void AGSWaves::SFX_Stop(ScriptMethodParams ¶ms) {
- //PARAMS2(int, SFX, int, fademsOUT);
+ PARAMS1(int, sfxNum); //, int, fademsOUT);
+
+ SoundEffect &effect = SFX[sfxNum];
+
+ if (effect._stream != nullptr) {
+ _mixer->stopHandle(effect._soundHandle);
+ UnloadSFX(sfxNum);
+
+ effect._playing = false;
+ effect._repeat = 0;
+ effect._channel = -2;
+ }
}
void AGSWaves::SFX_SetPosition(ScriptMethodParams ¶ms) {
- //PARAMS4(int, SFX, int, x, int, y, int, intensity);
+ PARAMS4(int, sfxNum, int, xS, int, yS, int, intensity);
+
+ SoundEffect &effect = SFX[sfxNum];
+
+ if (effect._stream != nullptr) {
+ if (_mixer->isSoundHandleActive(effect._soundHandle)) {
+ int angle = 0;
+ int dist = 0;
+
+ if (xS != 0 && yS != 0) {
+ int pid = _engine->GetPlayerCharacter();
+ playerCharacter = _engine->GetCharacter(pid);
+
+ int x1 = Character_GetX((intptr_t)playerCharacter);
+ int y1 = Character_GetY((intptr_t)playerCharacter);
+
+ int x2 = xS;
+ int y2 = yS;
+
+ int defx = (x1 - x2) * (x1 - x2);
+ int defy = (y1 - y2) * (y1 - y2);
+
+ float SquareRoot = sqrt(float(defx + defy));
+ dist = int(SquareRoot) - intensity;
+ if (dist > 255) dist = 255;
+ if (dist < 0) dist = 0;
+
+ float xDiff = float(x2 - x1);
+ float yDiff = float(y2 - y1);
+ float at2 = atan2(yDiff, xDiff);
+
+ float angles = (at2 * 360.0 / PI);
+ angle = int(angles);//%360;
+ }
+
+ // TODO: Change Mix_SetPosition to ScummVM equivalent
+ //Mix_SetPosition(id, angle, dist);
+ (void)angle;
+ (void)dist;
+ }
+ }
}
void AGSWaves::SFX_SetGlobalVolume(ScriptMethodParams ¶ms) {
- //PARAMS1(int, volume);
+ PARAMS1(int, volume);
+ _mixer->setVolumeForSoundType(Audio::Mixer::kPlainSoundType, volume);
}
void AGSWaves::Load_SFX(ScriptMethodParams ¶ms) {
- //PARAMS1(int, SFX);
+ PARAMS1(int, sfxNum);
+ LoadSFX(sfxNum);
}
void AGSWaves::Audio_Apply_Filter(ScriptMethodParams ¶ms) {
- //PARAMS1(int, Frequency);
+ PARAMS1(int, Frequency);
+
+ GlitchFix();
+ ApplyFilter(Frequency);
}
void AGSWaves::Audio_Remove_Filter(ScriptMethodParams ¶ms) {
@@ -84,7 +183,91 @@ void AGSWaves::SFX_AllowOverlap(ScriptMethodParams ¶ms) {
}
void AGSWaves::SFX_Filter(ScriptMethodParams ¶ms) {
- //PARAMS2(int, SFX, int, enable);
+ PARAMS2(int, sfxNum, int, enable);
+
+ // THIS ENABLES/DISABLES the SFX LOW PASS FILTER,
+ // I think by default all sound effects are affected by low pass, but there are some that i've manually disabled from being affected by it with this command
+ SFX[sfxNum]._filter = enable;
+}
+
+
+void AGSWaves::LoadSFX(int i) {
+ Common::FSNode soundsFolder("sounds");
+ Common::FSNode soundFileNode = soundsFolder.getChild(
+ Common::String::format("sound%d.sfx", i));
+
+ Common::File *soundFile = new Common::File();
+ if (soundFile->open(soundFileNode)) {
+ SFX[i]._stream = Audio::makeWAVStream(soundFile, DisposeAfterUse::YES);
+
+ } else {
+ delete soundFile;
+ }
+}
+
+void AGSWaves::UnloadSFX(int i) {
+ if (SFX[i]._stream != nullptr) {
+ _mixer->stopHandle(SFX[i]._soundHandle);
+ delete SFX[i]._stream;
+ SFX[i]._stream = nullptr;
+ }
+}
+
+void AGSWaves::GlitchFix() {
+ // TODO: Implementation
+}
+
+void AGSWaves::ApplyFilter(int setFrequency) {
+ // THIS TURNS ON THE LOW PASS FILTER
+ OGG_Filter = true;
+ GeneralAudio.FilterFrequency = setFrequency;
+ SetFilterFrequency(setFrequency);
+}
+
+void AGSWaves::SetFilterFrequency(int setFrequency) {
+ // TODO: Implementation
+}
+
+void AGSWaves::MusicPlay(int MusicToPlay, int repeat, int fadeinMS, int fadeoutMS, int pos, bool forceplay, bool fixclick) {
+ if (GeneralAudio.Disabled) {
+ return;
+ }
+
+ bool samefile = currentMusic != MusicToPlay;
+ if (forceplay) samefile = true;
+
+ if (samefile) {
+ currentMusicRepeat = repeat;
+ currentMusicFadein = fadeinMS;
+ currentMusic = MusicToPlay;
+
+ if (!MFXStream.Switch) {
+ MFXStream.Channel = 0;
+
+ warning("TODO: OGGplayMusic(MusicLoads[MusicToPlay].musicPath, 0, repeat, 0, fixclick);");
+ MFXStream.ID = MusicToPlay;
+ MFXStream.FadeTime = (fadeinMS / 1000) * 40;
+ MFXStream.FadeRate = (float)_mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType)
+ / (float)MFXStream.FadeTime;
+ MFXStream.FadeVolume = 0.0;
+ MFXStream.HaltedZero = false;
+ //MusicVolCanBeAdjusted=true;
+ } else {
+ MFXStream.HaltedOne = false;
+ MFXStream.Channel = 1;
+
+ warning("TODO: OGGplayMusic(MusicLoads[MusicToPlay].musicPath, 0, repeat, 1, fixclick);");
+
+ MFXStream.ID = MusicToPlay;
+ MFXStream.FadeTime = (fadeoutMS / 1000) * 40;
+ MFXStream.FadeVolume = 0.0;//float(MusicGetVolume());
+ MFXStream.FadeRate = (float)_mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType)
+ / (float)MFXStream.FadeTime;
+ //MusicVolCanBeAdjusted=false;
+ }
+
+ MFXStream.Switch = !MFXStream.Switch;
+ }
}
} // namespace AGSWaves
diff --git a/engines/ags/plugins/ags_waves/vars.h b/engines/ags/plugins/ags_waves/vars.h
index 352da1b326..6da288a32c 100644
--- a/engines/ags/plugins/ags_waves/vars.h
+++ b/engines/ags/plugins/ags_waves/vars.h
@@ -23,6 +23,8 @@
#ifndef AGS_PLUGINS_AGS_WAVES_VARS_H
#define AGS_PLUGINS_AGS_WAVES_VARS_H
+#include "audio/audiostream.h"
+
namespace AGS3 {
namespace Plugins {
namespace AGSWaves {
@@ -75,22 +77,23 @@ struct getMus {
};
//WAVE SOUNDS FILES
-struct Soundeffect {
- Mix_Chunk *chunk;
- int repeat;
- int volume;
- int playing;
- int allow;
- int channel;
- int filter;
+struct SoundEffect {
+ Audio::AudioStream *_stream;
+ Audio::SoundHandle _soundHandle;
+ int _repeat;
+ int _volume;
+ bool _playing;
+ int _allow;
+ int _channel;
+ int _filter;
};
struct Aud {
- int NumOfChannels;
- bool Initialized;
- bool Disabled;
- int FilterFrequency;
- int SoundValue;
+ int NumOfChannels = 0;
+ bool Initialized = false;
+ bool Disabled = false;
+ int FilterFrequency = 0;
+ int SoundValue = 0;
};
struct Mus {
@@ -150,7 +153,7 @@ struct Vars {
PluginMethod Character_ID;
getMus MusicLoads[80];
- Soundeffect SFX[500];
+ SoundEffect SFX[500];
RainParticle RainParticles[400];
RainParticle RainParticlesFore[400];
RainParticle RainParticlesBack[800];
diff --git a/engines/ags/plugins/serializer.h b/engines/ags/plugins/serializer.h
index 97054c4fa8..14345a04ec 100644
--- a/engines/ags/plugins/serializer.h
+++ b/engines/ags/plugins/serializer.h
@@ -31,66 +31,66 @@ namespace Plugins {
class Serializer {
private:
-IAGSEngine *_engine;
-long _file;
-bool _isLoading;
-public:
-Serializer(IAGSEngine *engine, long file, bool isLoading) :
- _engine(engine), _file(file), _isLoading(isLoading) {}
+ IAGSEngine *_engine;
+ long _file;
+ bool _isLoading;
+ public:
+ Serializer(IAGSEngine *engine, long file, bool isLoading) :
+ _engine(engine), _file(file), _isLoading(isLoading) {}
-bool isLoading() const {
- return _isLoading;
-}
-bool isSaving() const {
- return !_isLoading;
-}
+ bool isLoading() const {
+ return _isLoading;
+ }
+ bool isSaving() const {
+ return !_isLoading;
+ }
-template<typename T>
-void syncAsInt(T &value) {
- byte buf[4];
- if (_isLoading) {
- _engine->FRead(buf, 4, _file);
- value = READ_LE_INT32(buf);
- } else {
- WRITE_LE_UINT32(buf, value);
- _engine->FWrite(buf, 4, _file);
+ template<typename T>
+ void syncAsInt(T &value) {
+ byte buf[4];
+ if (_isLoading) {
+ _engine->FRead(buf, 4, _file);
+ value = READ_LE_INT32(buf);
+ } else {
+ WRITE_LE_UINT32(buf, value);
+ _engine->FWrite(buf, 4, _file);
+ }
}
-}
-void syncAsBool(bool &value) {
- if (_isLoading)
- _engine->FRead(&value, 1, _file);
- else
- _engine->FWrite(&value, 1, _file);
-}
+ void syncAsBool(bool &value) {
+ if (_isLoading)
+ _engine->FRead(&value, 1, _file);
+ else
+ _engine->FWrite(&value, 1, _file);
+ }
-void syncAsInt8(int8 &value) {
- if (_isLoading)
- _engine->FRead(&value, 1, _file);
- else
- _engine->FWrite(&value, 1, _file);
-}
+ void syncAsInt8(int8 &value) {
+ if (_isLoading)
+ _engine->FRead(&value, 1, _file);
+ else
+ _engine->FWrite(&value, 1, _file);
+ }
-void syncAsByte(byte &value) {
- if (_isLoading)
- _engine->FRead(&value, 1, _file);
- else
- _engine->FWrite(&value, 1, _file);
-}
+ void syncAsByte(byte &value) {
+ if (_isLoading)
+ _engine->FRead(&value, 1, _file);
+ else
+ _engine->FWrite(&value, 1, _file);
+ }
-void syncAsFloat(float &value) {
- if (_isLoading)
- _engine->FRead(&value, sizeof(float), _file);
- else
- _engine->FWrite(&value, sizeof(float), _file);
-}
+ void syncAsFloat(float &value) {
+ if (_isLoading)
+ _engine->FRead(&value, sizeof(float), _file);
+ else
+ _engine->FWrite(&value, sizeof(float), _file);
+ }
-void syncAsDouble(double &value) {
- if (_isLoading)
- _engine->FRead(&value, sizeof(double), _file);
- else
- _engine->FWrite(&value, sizeof(double), _file);
-}
+ void syncAsDouble(double &value) {
+ if (_isLoading)
+ _engine->FRead(&value, sizeof(double), _file);
+ else
+ _engine->FWrite(&value, sizeof(double), _file);
+ }
};
} // namespace Plugins
Commit: 6a4062d3fc75e888ba293c860e54b59c3b12f3f3
https://github.com/scummvm/scummvm/commit/6a4062d3fc75e888ba293c860e54b59c3b12f3f3
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-20T20:25:54-07:00
Commit Message:
AGS: Fix some comments in call_function
Changed paths:
engines/ags/engine/script/script_runtime.cpp
diff --git a/engines/ags/engine/script/script_runtime.cpp b/engines/ags/engine/script/script_runtime.cpp
index f4e13c8b5e..d7f4c9a89e 100644
--- a/engines/ags/engine/script/script_runtime.cpp
+++ b/engines/ags/engine/script/script_runtime.cpp
@@ -166,7 +166,7 @@ int call_function(const Plugins::PluginMethod &method,
// AN IMPORTANT NOTE ON PARAMS
// The original AGS interpreter did a bunch of dodgy function pointers with
- // varying numbers of parameters, which were all int64_t. To simply matters
+ // varying numbers of parameters, which were all intptr_t. To simply matters
// now that we only supported plugins implemented in code, and not DLLs,
// we use a simplified Common::Array containing the parameters and result
@@ -183,8 +183,9 @@ int call_function(const Plugins::PluginMethod &method,
NumberPtr result = method(params);
// TODO: Though some script methods return pointers, the call_function only
- // supports a 32-bit result. In case they're actually used by any game, the
- // guard below will throw a wobbly if they're more than 32-bits
+ // supports a 32-bit result. To avoid weird problems on 64-bit systems that
+ // produce pointers above 32-bits, detect and throw a wobbly
+ // until such time as it can properly be fixed
if (result._ptr > (void *)0xffffffff)
error("Uhandled 64-bit pointer result from plugin method call");
More information about the Scummvm-git-logs
mailing list