Initial commit

This commit is contained in:
2026-02-02 04:50:13 +01:00
commit 5b11698731
22592 changed files with 7677434 additions and 0 deletions

View File

@@ -0,0 +1,225 @@
/* 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 3 of the License, or
* 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "ags/plugins/ags_snow_rain/ags_snow_rain.h"
namespace AGS3 {
namespace Plugins {
namespace AGSSnowRain {
AGSSnowRain::AGSSnowRain() : PluginBase(),
_rain(false, _screenWidth, _screenHeight, _engine),
_snow(true, _screenWidth, _screenHeight, _engine) {
}
const char *AGSSnowRain::AGS_GetPluginName() {
// Return the plugin description
return "Snow/Rain plugin recreation";
}
void AGSSnowRain::AGS_EngineStartup(IAGSEngine *engine) {
PluginBase::AGS_EngineStartup(engine);
if (_engine->version < 13)
_engine->AbortGame("Engine interface is too old, need newer version of AGS.");
SCRIPT_METHOD(srSetSnowDriftRange, AGSSnowRain::srSetSnowDriftRange);
SCRIPT_METHOD(srSetSnowDriftSpeed, AGSSnowRain::srSetSnowDriftSpeed);
SCRIPT_METHOD(srSetSnowFallSpeed, AGSSnowRain::srSetSnowFallSpeed);
SCRIPT_METHOD(srChangeSnowAmount, AGSSnowRain::srChangeSnowAmount);
SCRIPT_METHOD(srSetSnowBaseline, AGSSnowRain::srSetSnowBaseline);
SCRIPT_METHOD(srSetSnowTransparency, AGSSnowRain::srSetSnowTransparency);
SCRIPT_METHOD(srSetSnowDefaultView, AGSSnowRain::srSetSnowDefaultView);
SCRIPT_METHOD(srSetSnowWindSpeed, AGSSnowRain::srSetSnowWindSpeed);
SCRIPT_METHOD(srSetSnowAmount, AGSSnowRain::srSetSnowAmount);
SCRIPT_METHOD(srSetSnowView, AGSSnowRain::srSetSnowView);
SCRIPT_METHOD(srSetRainDriftRange, AGSSnowRain::srSetRainDriftRange);
SCRIPT_METHOD(srSetRainDriftSpeed, AGSSnowRain::srSetRainDriftSpeed);
SCRIPT_METHOD(srSetRainFallSpeed, AGSSnowRain::srSetRainFallSpeed);
SCRIPT_METHOD(srChangeRainAmount, AGSSnowRain::srChangeRainAmount);
SCRIPT_METHOD(srSetRainBaseline, AGSSnowRain::srSetRainBaseline);
SCRIPT_METHOD(srSetRainTransparency, AGSSnowRain::srSetRainTransparency);
SCRIPT_METHOD(srSetRainDefaultView, AGSSnowRain::srSetRainDefaultView);
SCRIPT_METHOD(srSetRainWindSpeed, AGSSnowRain::srSetRainWindSpeed);
SCRIPT_METHOD(srSetRainAmount, AGSSnowRain::srSetRainAmount);
SCRIPT_METHOD(srSetRainView, AGSSnowRain::srSetRainView);
SCRIPT_METHOD(srSetWindSpeed, AGSSnowRain::srSetWindSpeed);
SCRIPT_METHOD(srSetBaseline, AGSSnowRain::srSetBaseline);
_engine->RequestEventHook(AGSE_PREGUIDRAW);
_engine->RequestEventHook(AGSE_ENTERROOM);
_engine->RequestEventHook(AGSE_SAVEGAME);
_engine->RequestEventHook(AGSE_RESTOREGAME);
}
int64 AGSSnowRain::AGS_EngineOnEvent(int event, NumberPtr data) {
if (event == AGSE_PREGUIDRAW) {
if (_rain.IsActive())
_rain.Update();
if (_snow.IsActive())
_snow.UpdateWithDrift();
} else if (event == AGSE_ENTERROOM) {
// Get screen size when entering a room
_engine->GetScreenDimensions(&_screenWidth, &_screenHeight, &_screenColorDepth);
_rain.EnterRoom();
_snow.EnterRoom();
} else if (event == AGSE_RESTOREGAME) {
Serializer s(_engine, data, true);
_rain.syncGame(s);
_snow.syncGame(s);
} else if (event == AGSE_SAVEGAME) {
Serializer s(_engine, data, false);
_rain.syncGame(s);
_snow.syncGame(s);
}
return 0;
}
void AGSSnowRain::srSetWindSpeed(ScriptMethodParams &params) {
PARAMS1(int, value);
_snow.SetWindSpeed(value);
_rain.SetWindSpeed(value);
}
void AGSSnowRain::srSetBaseline(ScriptMethodParams &params) {
PARAMS2(int, top, int, bottom);
// FIXME: The original seems to take co-ordinates in 320x200,
// but still displays correctly at 640x400. So doubling must
// occur somewhere. For now, doing it here
if (_screenHeight == 400) {
top *= 2;
bottom *= 2;
}
_snow.SetBaseline(top, bottom);
_rain.SetBaseline(top, bottom);
}
void AGSSnowRain::srSetSnowDriftRange(ScriptMethodParams &params) {
PARAMS2(int, min_value, int, max_value);
_snow.SetDriftRange(min_value, max_value);
}
void AGSSnowRain::srSetSnowDriftSpeed(ScriptMethodParams &params) {
PARAMS2(int, min_value, int, max_value);
_snow.SetDriftSpeed(min_value, max_value);
}
void AGSSnowRain::srChangeSnowAmount(ScriptMethodParams &params) {
PARAMS1(int, amount);
_snow.ChangeAmount(amount);
}
void AGSSnowRain::srSetSnowView(ScriptMethodParams &params) {
PARAMS4(int, kind_id, int, event, int, view, int, loop);
_snow.SetView(kind_id, event, view, loop);
}
void AGSSnowRain::srSetSnowDefaultView(ScriptMethodParams &params) {
PARAMS2(int, view, int, loop);
_snow.SetDefaultView(view, loop);
}
void AGSSnowRain::srSetSnowTransparency(ScriptMethodParams &params) {
PARAMS2(int, min_value, int, max_value);
_snow.SetTransparency(min_value, max_value);
}
void AGSSnowRain::srSetSnowWindSpeed(ScriptMethodParams &params) {
PARAMS1(int, value);
_snow.SetWindSpeed(value);
}
void AGSSnowRain::srSetSnowBaseline(ScriptMethodParams &params) {
PARAMS2(int, top, int, bottom);
_snow.SetBaseline(top, bottom);
}
void AGSSnowRain::srSetSnowAmount(ScriptMethodParams &params) {
PARAMS1(int, amount);
_snow.SetAmount(amount);
}
void AGSSnowRain::srSetSnowFallSpeed(ScriptMethodParams &params) {
PARAMS2(int, min_value, int, max_value);
_snow.SetFallSpeed(min_value, max_value);
}
void AGSSnowRain::srSetRainDriftRange(ScriptMethodParams &params) {
PARAMS2(int, min_value, int, max_value);
_rain.SetDriftRange(min_value, max_value);
}
void AGSSnowRain::srSetRainDriftSpeed(ScriptMethodParams &params) {
PARAMS2(int, min_value, int, max_value);
_rain.SetDriftSpeed(min_value, max_value);
}
void AGSSnowRain::srChangeRainAmount(ScriptMethodParams &params) {
PARAMS1(int, amount);
_rain.ChangeAmount(amount);
}
void AGSSnowRain::srSetRainView(ScriptMethodParams &params) {
PARAMS4(int, kind_id, int, event, int, view, int, loop);
_rain.SetView(kind_id, event, view, loop);
}
void AGSSnowRain::srSetRainDefaultView(ScriptMethodParams &params) {
PARAMS2(int, view, int, loop);
_rain.SetDefaultView(view, loop);
}
void AGSSnowRain::srSetRainTransparency(ScriptMethodParams &params) {
PARAMS2(int, min_value, int, max_value);
_rain.SetTransparency(min_value, max_value);
}
void AGSSnowRain::srSetRainWindSpeed(ScriptMethodParams &params) {
PARAMS1(int, value);
_rain.SetWindSpeed(value);
}
void AGSSnowRain::srSetRainBaseline(ScriptMethodParams &params) {
PARAMS2(int, top, int, bottom);
_rain.SetBaseline(top, bottom);
}
void AGSSnowRain::srSetRainAmount(ScriptMethodParams &params) {
PARAMS1(int, amount);
_rain.SetAmount(amount);
}
void AGSSnowRain::srSetRainFallSpeed(ScriptMethodParams &params) {
PARAMS2(int, min_value, int, max_value);
_rain.SetFallSpeed(min_value, max_value);
}
} // namespace AGSSnowRain
} // namespace Plugins
} // namespace AGS3

View File

@@ -0,0 +1,81 @@
/* 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 3 of the License, or
* 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef AGS_PLUGINS_AGS_SNOW_RAIN_AGS_SNOW_RAIN_H
#define AGS_PLUGINS_AGS_SNOW_RAIN_AGS_SNOW_RAIN_H
#include "ags/plugins/ags_plugin.h"
#include "ags/plugins/ags_snow_rain/weather.h"
namespace AGS3 {
namespace Plugins {
namespace AGSSnowRain {
/**
* This is not the original AGS SnowRain plugin, but a workalike
* plugin created for the AGS engine PSP port.
*/
class AGSSnowRain : public PluginBase {
SCRIPT_HASH(AGSSnowRain)
private:
int32 _screenWidth = 320;
int32 _screenHeight = 200;
int32 _screenColorDepth = 32;
Weather _rain;
Weather _snow;
private:
void srSetWindSpeed(ScriptMethodParams &params);
void srSetBaseline(ScriptMethodParams &params);
void srSetSnowDriftRange(ScriptMethodParams &params);
void srSetSnowDriftSpeed(ScriptMethodParams &params);
void srChangeSnowAmount(ScriptMethodParams &params);
void srSetSnowView(ScriptMethodParams &params);
void srSetSnowDefaultView(ScriptMethodParams &params);
void srSetSnowTransparency(ScriptMethodParams &params);
void srSetSnowWindSpeed(ScriptMethodParams &params);
void srSetSnowBaseline(ScriptMethodParams &params);
void srSetSnowAmount(ScriptMethodParams &params);
void srSetSnowFallSpeed(ScriptMethodParams &params);
void srSetRainDriftRange(ScriptMethodParams &params);
void srSetRainDriftSpeed(ScriptMethodParams &params);
void srChangeRainAmount(ScriptMethodParams &params);
void srSetRainView(ScriptMethodParams &params);
void srSetRainDefaultView(ScriptMethodParams &params);
void srSetRainTransparency(ScriptMethodParams &params);
void srSetRainWindSpeed(ScriptMethodParams &params);
void srSetRainBaseline(ScriptMethodParams &params);
void srSetRainAmount(ScriptMethodParams &params);
void srSetRainFallSpeed(ScriptMethodParams &params);
public:
AGSSnowRain();
virtual ~AGSSnowRain() {}
const char *AGS_GetPluginName() override;
void AGS_EngineStartup(IAGSEngine *lpEngine) override;
int64 AGS_EngineOnEvent(int event, NumberPtr data) override;
};
} // namespace AGSSnowRain
} // namespace Plugins
} // namespace AGS3
#endif

View File

@@ -0,0 +1,389 @@
/* 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 3 of the License, or
* 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "ags/lib/allegro.h"
#include "ags/plugins/ags_snow_rain/weather.h"
#include "ags/plugins/ags_snow_rain/ags_snow_rain.h"
#include "ags/ags.h"
namespace AGS3 {
namespace Plugins {
namespace AGSSnowRain {
#define signum(x) ((x > 0) ? 1 : -1)
const unsigned int Magic = 0xCAFE0000;
const unsigned int Version = 2;
const unsigned int SaveMagic = Magic + Version;
void View::syncGame(Serializer &s) {
s.syncAsInt(view);
s.syncAsInt(loop);
s.syncAsBool(is_default);
// Pointer saved/loaded raw structure, which included bitmap pointer
int dummy = 0;
s.syncAsInt(dummy);
}
/*------------------------------------------------------------------*/
Weather::Weather(bool IsSnow, int32 &scrWidth, int32 &scrHeight, IAGSEngine *&engine) :
_mIsSnow(IsSnow), _screenWidth(scrWidth), _screenHeight(scrHeight), _engine(engine) {
Initialize();
}
void Weather::Update() {
if (_mTargetAmount > _mAmount)
_mAmount++;
else if (_mTargetAmount < _mAmount)
_mAmount--;
if (!ReinitializeViews())
return;
int i;
for (i = 0; i < _mAmount * 2; i++) {
_mParticles[i].y += _mParticles[i].speed;
_mParticles[i].x += _mWindSpeed;
if (_mParticles[i].x < 0)
_mParticles[i].x += _screenWidth;
if (_mParticles[i].x > _screenWidth - 1)
_mParticles[i].x -= _screenWidth;
if (_mParticles[i].y > _mParticles[i].max_y) {
_mParticles[i].y = -1 * (::AGS::g_vm->getRandomNumber(0x7fffffff) % _screenHeight);
_mParticles[i].x = ::AGS::g_vm->getRandomNumber(0x7fffffff) % _screenWidth;
_mParticles[i].alpha = ::AGS::g_vm->getRandomNumber(0x7fffffff) % _mDeltaAlpha + _mMinAlpha;
_mParticles[i].speed = (float)(::AGS::g_vm->getRandomNumber(0x7fffffff) % _mDeltaFallSpeed + _mMinFallSpeed) / 50.0f;
_mParticles[i].max_y = ::AGS::g_vm->getRandomNumber(0x7fffffff) % _mDeltaBaseline + _mTopBaseline;
} else if ((_mParticles[i].y > 0) && (_mParticles[i].alpha > 0))
_engine->BlitSpriteTranslucent(_mParticles[i].x, _mParticles[i].y, _mViews[_mParticles[i].kind_id].bitmap, _mParticles[i].alpha);
}
_engine->MarkRegionDirty(0, 0, _screenWidth, _screenHeight);
}
void Weather::UpdateWithDrift() {
if (_mTargetAmount > _mAmount)
_mAmount++;
else if (_mTargetAmount < _mAmount)
_mAmount--;
if (!ReinitializeViews())
return;
int i, drift;
for (i = 0; i < _mAmount * 2; i++) {
_mParticles[i].y += _mParticles[i].speed;
drift = _mParticles[i].drift * sin((float)(_mParticles[i].y +
_mParticles[i].drift_offset) * _mParticles[i].drift_speed * 2.0f * M_PI / 360.0f);
if (signum(_mWindSpeed) == signum(drift))
_mParticles[i].x += _mWindSpeed;
else
_mParticles[i].x += _mWindSpeed / 4;
if (_mParticles[i].x < 0)
_mParticles[i].x += _screenWidth;
if (_mParticles[i].x > _screenWidth - 1)
_mParticles[i].x -= _screenWidth;
if (_mParticles[i].y > _mParticles[i].max_y) {
_mParticles[i].y = -1 * (::AGS::g_vm->getRandomNumber(0x7fffffff) % _screenHeight);
_mParticles[i].x = ::AGS::g_vm->getRandomNumber(0x7fffffff) % _screenWidth;
_mParticles[i].alpha = ::AGS::g_vm->getRandomNumber(0x7fffffff) % _mDeltaAlpha + _mMinAlpha;
_mParticles[i].speed = (float)(::AGS::g_vm->getRandomNumber(0x7fffffff) % _mDeltaFallSpeed + _mMinFallSpeed) / 50.0f;
_mParticles[i].max_y = ::AGS::g_vm->getRandomNumber(0x7fffffff) % _mDeltaBaseline + _mTopBaseline;
_mParticles[i].drift = ::AGS::g_vm->getRandomNumber(0x7fffffff) % _mDeltaDrift + _mMinDrift;
_mParticles[i].drift_speed = (::AGS::g_vm->getRandomNumber(0x7fffffff) % _mDeltaDriftSpeed + _mMinDriftSpeed) / 50.0f;
} else if ((_mParticles[i].y > 0) && (_mParticles[i].alpha > 0))
_engine->BlitSpriteTranslucent(_mParticles[i].x + drift, _mParticles[i].y, _mViews[_mParticles[i].kind_id].bitmap, _mParticles[i].alpha);
}
_engine->MarkRegionDirty(0, 0, _screenWidth, _screenHeight);
}
void Weather::syncGame(Serializer &s) {
int saveVersion = SaveMagic;
s.syncAsInt(saveVersion);
if (s.isLoading() && (uint)saveVersion != SaveMagic) {
_engine->AbortGame("ags_snowrain: bad save.");
return;
}
// TODO: At some point check whether the original did a packed
// structure for Weather, or if bools were padded to 4 bytes
s.syncAsBool(_mIsSnow);
s.syncAsInt(_mMinDrift);
s.syncAsInt(_mMaxDrift);
s.syncAsInt(_mDeltaDrift);
s.syncAsInt(_mMinDriftSpeed);
s.syncAsInt(_mMaxDriftSpeed);
s.syncAsInt(_mDeltaDriftSpeed);
s.syncAsInt(_mAmount);
s.syncAsInt(_mTargetAmount);
s.syncAsInt(_mMinAlpha);
s.syncAsInt(_mMaxAlpha);
s.syncAsInt(_mDeltaAlpha);
s.syncAsFloat(_mWindSpeed);
s.syncAsInt(_mTopBaseline);
s.syncAsInt(_mBottomBaseline);
s.syncAsInt(_mDeltaBaseline);
s.syncAsInt(_mMinFallSpeed);
s.syncAsInt(_mMaxFallSpeed);
s.syncAsInt(_mDeltaFallSpeed);
for (int i = 0; i < 5; ++i)
_mViews[i].syncGame(s);
if (s.isLoading())
InitializeParticles();
}
bool Weather::ReinitializeViews() {
if ((_mViews[4].view == -1) || (_mViews[4].loop == -1))
return false;
AGSViewFrame *view_frame = _engine->GetViewFrame(_mViews[4].view, _mViews[4].loop, 0);
BITMAP *default_bitmap = _engine->GetSpriteGraphic(view_frame->pic);
int i;
for (i = 0; i < 5; i++) {
if (_mViews[i].bitmap != nullptr) {
if (_mViews[i].is_default)
_mViews[i].bitmap = default_bitmap;
else {
view_frame = _engine->GetViewFrame(_mViews[i].view, _mViews[i].loop, 0);
_mViews[i].bitmap = _engine->GetSpriteGraphic(view_frame->pic);
}
}
}
return true;
}
bool Weather::IsActive() {
return (_mAmount > 0) || (_mTargetAmount != _mAmount);
}
void Weather::EnterRoom() {
_mAmount = _mTargetAmount;
// If baseline is not fixed, reset and clamp to the new screenHeight
if (!_mBaselineFixed)
ResetBaseline();
}
void Weather::ClipToRange(int &variable, int min, int max) {
if (variable < min)
variable = min;
if (variable > max)
variable = max;
}
void Weather::Initialize() {
SetDriftRange(10, 100);
SetDriftSpeed(10, 120);
SetTransparency(0, 0);
SetWindSpeed(0);
ResetBaseline();
if (_mIsSnow)
SetFallSpeed(10, 70);
else
SetFallSpeed(100, 300);
_mViewsInitialized = false;
int i;
for (i = 0; i < 5; i++) {
_mViews[i].is_default = true;
_mViews[i].view = -1;
_mViews[i].loop = -1;
_mViews[i].bitmap = nullptr;
}
SetAmount(0);
}
void Weather::InitializeParticles() {
for (uint i = 0; i < ARRAYSIZE(_mParticles); i++) {
_mParticles[i].clear();
_mParticles[i].kind_id = ::AGS::g_vm->getRandomNumber(0x7fffffff) % 5;
_mParticles[i].y = ::AGS::g_vm->getRandomNumber(0x7fffffff) % (_screenHeight * 2) - _screenHeight;
_mParticles[i].x = ::AGS::g_vm->getRandomNumber(0x7fffffff) % _screenWidth;
_mParticles[i].alpha = ::AGS::g_vm->getRandomNumber(0x7fffffff) % _mDeltaAlpha + _mMinAlpha;
_mParticles[i].speed = (float)(::AGS::g_vm->getRandomNumber(0x7fffffff) % _mDeltaFallSpeed + _mMinFallSpeed) / 50.0f;
_mParticles[i].max_y = ::AGS::g_vm->getRandomNumber(0x7fffffff) % _mDeltaBaseline + _mTopBaseline;
_mParticles[i].drift = ::AGS::g_vm->getRandomNumber(0x7fffffff) % _mDeltaDrift + _mMinDrift;
_mParticles[i].drift_speed = (::AGS::g_vm->getRandomNumber(0x7fffffff) % _mDeltaDriftSpeed + _mMinDriftSpeed) / 50.0f;
_mParticles[i].drift_offset = ::AGS::g_vm->getRandomNumber(0x7fffffff) % 100;
}
}
void Weather::SetDriftRange(int min_value, int max_value) {
ClipToRange(min_value, 0, 100);
ClipToRange(max_value, 0, 100);
if (min_value > max_value)
min_value = max_value;
_mMinDrift = min_value / 2;
_mMaxDrift = max_value / 2;
_mDeltaDrift = _mMaxDrift - _mMinDrift;
if (_mDeltaDrift == 0)
_mDeltaDrift = 1;
}
void Weather::SetDriftSpeed(int min_value, int max_value) {
ClipToRange(min_value, 0, 200);
ClipToRange(max_value, 0, 200);
if (min_value > max_value)
min_value = max_value;
_mMinDriftSpeed = min_value;
_mMaxDriftSpeed = max_value;
_mDeltaDriftSpeed = _mMaxDriftSpeed - _mMinDriftSpeed;
if (_mDeltaDriftSpeed == 0)
_mDeltaDriftSpeed = 1;
}
void Weather::ChangeAmount(int amount) {
ClipToRange(amount, 0, 1000);
_mTargetAmount = amount;
}
void Weather::SetView(int kind_id, int event, int view, int loop) {
AGSViewFrame *view_frame = _engine->GetViewFrame(view, loop, 0);
_mViews[kind_id].bitmap = _engine->GetSpriteGraphic(view_frame->pic);
_mViews[kind_id].is_default = false;
_mViews[kind_id].view = view;
_mViews[kind_id].loop = loop;
if (!_mViewsInitialized)
SetDefaultView(view, loop);
}
void Weather::SetDefaultView(int view, int loop) {
AGSViewFrame *view_frame = _engine->GetViewFrame(view, loop, 0);
BITMAP *bitmap = _engine->GetSpriteGraphic(view_frame->pic);
_mViewsInitialized = true;
int i;
for (i = 0; i < 5; i++) {
if (_mViews[i].is_default) {
_mViews[i].view = view;
_mViews[i].loop = loop;
_mViews[i].bitmap = bitmap;
}
}
}
void Weather::SetTransparency(int min_value, int max_value) {
ClipToRange(min_value, 0, 100);
ClipToRange(max_value, 0, 100);
if (min_value > max_value)
min_value = max_value;
_mMinAlpha = 255 - floor((float)max_value * 2.55f + 0.5f);
_mMaxAlpha = 255 - floor((float)min_value * 2.55f + 0.5f);
_mDeltaAlpha = _mMaxAlpha - _mMinAlpha;
if (_mDeltaAlpha == 0)
_mDeltaAlpha = 1;
int i;
for (i = 0; i < 2000; i++)
_mParticles[i].alpha = ::AGS::g_vm->getRandomNumber(0x7fffffff) % _mDeltaAlpha + _mMinAlpha;
}
void Weather::SetWindSpeed(int value) {
ClipToRange(value, -200, 200);
_mWindSpeed = (float)value / 20.0f;
}
void Weather::SetBaseline(int top, int bottom) {
if (_screenHeight > 0) {
ClipToRange(top, 0, _screenHeight);
ClipToRange(bottom, 0, _screenHeight);
}
if (top > bottom)
top = bottom;
_mTopBaseline = top;
_mBottomBaseline = bottom;
_mDeltaBaseline = _mBottomBaseline - _mTopBaseline;
if (_mDeltaBaseline == 0)
_mDeltaBaseline = 1;
_mBaselineFixed = true;
}
void Weather::ResetBaseline() {
_mTopBaseline = 0;
_mBottomBaseline = _screenHeight;
_mDeltaBaseline = _screenHeight;
_mBaselineFixed = false;
}
void Weather::SetAmount(int amount) {
ClipToRange(amount, 0, 1000);
_mAmount = _mTargetAmount = amount;
InitializeParticles();
}
void Weather::SetFallSpeed(int min_value, int max_value) {
ClipToRange(min_value, 0, 1000);
ClipToRange(max_value, 0, 1000);
if (min_value > max_value)
min_value = max_value;
_mMinFallSpeed = min_value;
_mMaxFallSpeed = max_value;
_mDeltaFallSpeed = _mMaxFallSpeed - _mMinFallSpeed;
if (_mDeltaFallSpeed == 0)
_mDeltaFallSpeed = 1;
}
} // namespace AGSSnowRain
} // namespace Plugins
} // namespace AGS3

View File

@@ -0,0 +1,139 @@
/* 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 3 of the License, or
* 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef AGS_PLUGINS_AGS_SNOW_RAIN_WEATHER_H
#define AGS_PLUGINS_AGS_SNOW_RAIN_WEATHER_H
#include "ags/plugins/plugin_base.h"
#include "ags/plugins/serializer.h"
namespace AGS3 {
namespace Plugins {
namespace AGSSnowRain {
struct View {
int view = 0;
int loop = 0;
bool is_default = false;
BITMAP *bitmap = nullptr;
void syncGame(Serializer &s);
};
struct Drop {
float x = 0;
float y = 0;
int alpha = 0;
float speed = 0;
int max_y = 0;
int kind_id = 0;
int drift = 0;
float drift_speed = 0;
float drift_offset = 0;
void clear() {
x = 0;
y = 0;
alpha = 0;
speed = 0;
max_y = 0;
kind_id = 0;
drift = 0;
drift_speed = 0;
drift_offset = 0;
}
};
class Weather {
private:
void ClipToRange(int &variable, int min, int max);
bool _mIsSnow;
int32 &_screenWidth;
int32 &_screenHeight;
IAGSEngine *&_engine;
int _mMinDrift = 0;
int _mMaxDrift = 0;
int _mDeltaDrift = 0;
int _mMinDriftSpeed = 0;
int _mMaxDriftSpeed = 0;
int _mDeltaDriftSpeed = 0;
int _mAmount = 0;
int _mTargetAmount = 0;
int _mMinAlpha = 0;
int _mMaxAlpha = 0;
int _mDeltaAlpha = 0;
float _mWindSpeed = 0;
bool _mBaselineFixed;
int _mTopBaseline = 0;
int _mBottomBaseline = 0;
int _mDeltaBaseline = 0;
int _mMinFallSpeed = 0;
int _mMaxFallSpeed = 0;
int _mDeltaFallSpeed = 0;
Drop _mParticles[2000];
View _mViews[5];
bool _mViewsInitialized;
public:
Weather(bool IsSnow, int32 &scrWidth, int32 &scrHeight, IAGSEngine *&engine);
void Initialize();
void InitializeParticles();
void syncGame(Serializer &s);
bool ReinitializeViews();
bool IsActive();
void Update();
void UpdateWithDrift();
void EnterRoom();
void SetDriftRange(int min_value, int max_value);
void SetDriftSpeed(int min_value, int max_value);
void ChangeAmount(int amount);
void SetView(int kind_id, int event, int view, int loop);
void SetDefaultView(int view, int loop);
void SetTransparency(int min_value, int max_value);
void SetWindSpeed(int value);
// Sets baseline and marks baseline as fixed
void SetBaseline(int top, int bottom);
// Resets baselines to the (0, screen_height);
// marks baseline for auto-update on screen change
void ResetBaseline();
void SetAmount(int amount);
void SetFallSpeed(int min_value, int max_value);
};
} // namespace AGSSnowRain
} // namespace Plugins
} // namespace AGS3
#endif