Initial commit
This commit is contained in:
199
engines/ags/plugins/ags_waves/ags_waves.cpp
Normal file
199
engines/ags/plugins/ags_waves/ags_waves.cpp
Normal file
@@ -0,0 +1,199 @@
|
||||
/* 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_waves/ags_waves.h"
|
||||
#include "ags/plugins/serializer.h"
|
||||
#include "ags/ags.h"
|
||||
#include "ags/globals.h"
|
||||
|
||||
namespace AGS3 {
|
||||
namespace Plugins {
|
||||
namespace AGSWaves {
|
||||
|
||||
AGSWaves::AGSWaves() : PluginBase(), Vars() {
|
||||
_mixer = ::AGS::g_vm->_mixer;
|
||||
}
|
||||
|
||||
const char *AGSWaves::AGS_GetPluginName() {
|
||||
return "AGS Waves";
|
||||
}
|
||||
|
||||
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.");
|
||||
|
||||
StartingValues();
|
||||
|
||||
Character_GetX = _engine->GetScriptFunctionAddress("Character::get_X");
|
||||
Character_GetY = _engine->GetScriptFunctionAddress("Character::get_Y");
|
||||
Character_ID = _engine->GetScriptFunctionAddress("Character::ID");
|
||||
|
||||
// Newer versions (after the 2025/04 update) no longer use the plugin to play sounds, so these
|
||||
// bindings are not needed
|
||||
if (_G(loaded_game_file_version) < 3060021) {
|
||||
SCRIPT_METHOD(SFX_Play, AGSWaves::SFX_Play);
|
||||
SCRIPT_METHOD(SFX_SetVolume, AGSWaves::SFX_SetVolume);
|
||||
SCRIPT_METHOD(SFX_GetVolume, AGSWaves::SFX_GetVolume);
|
||||
SCRIPT_METHOD(Music_Play, AGSWaves::Music_Play);
|
||||
SCRIPT_METHOD(Music_GetVolume, AGSWaves::Music_GetVolume);
|
||||
SCRIPT_METHOD(Music_SetVolume, AGSWaves::Music_SetVolume);
|
||||
SCRIPT_METHOD(SFX_Stop, AGSWaves::SFX_Stop);
|
||||
SCRIPT_METHOD(SFX_SetPosition, AGSWaves::SFX_SetPosition);
|
||||
SCRIPT_METHOD(SFX_SetGlobalVolume, AGSWaves::SFX_SetGlobalVolume);
|
||||
SCRIPT_METHOD(Load_SFX, AGSWaves::Load_SFX);
|
||||
SCRIPT_METHOD(Audio_Apply_Filter, AGSWaves::Audio_Apply_Filter);
|
||||
SCRIPT_METHOD(Audio_Remove_Filter, AGSWaves::Audio_Remove_Filter);
|
||||
SCRIPT_METHOD(SFX_AllowOverlap, AGSWaves::SFX_AllowOverlap);
|
||||
SCRIPT_METHOD(SFX_Filter, AGSWaves::SFX_Filter);
|
||||
}
|
||||
|
||||
SCRIPT_METHOD(DrawScreenEffect, AGSWaves::DrawScreenEffect);
|
||||
SCRIPT_METHOD(DrawBlur, AGSWaves::DrawBlur);
|
||||
SCRIPT_METHOD(DrawTunnel, AGSWaves::DrawTunnel);
|
||||
SCRIPT_METHOD(DrawCylinder, AGSWaves::DrawCylinder);
|
||||
SCRIPT_METHOD(DrawForceField, AGSWaves::DrawForceField);
|
||||
SCRIPT_METHOD(Grayscale, AGSWaves::Grayscale);
|
||||
SCRIPT_METHOD(ReadWalkBehindIntoSprite, AGSWaves::ReadWalkBehindIntoSprite);
|
||||
SCRIPT_METHOD(AdjustSpriteFont, AGSWaves::AdjustSpriteFont);
|
||||
SCRIPT_METHOD(SpriteGradient, AGSWaves::SpriteGradient);
|
||||
SCRIPT_METHOD(Outline, AGSWaves::Outline);
|
||||
SCRIPT_METHOD(OutlineOnly, AGSWaves::OutlineOnly);
|
||||
SCRIPT_METHOD(SaveVariable, AGSWaves::SaveVariable);
|
||||
SCRIPT_METHOD(ReadVariable, AGSWaves::ReadVariable);
|
||||
SCRIPT_METHOD(GameDoOnceOnly, AGSWaves::GameDoOnceOnly);
|
||||
SCRIPT_METHOD(SetGDState, AGSWaves::SetGDState);
|
||||
SCRIPT_METHOD(GetGDState, AGSWaves::GetGDState);
|
||||
SCRIPT_METHOD(ResetAllGD, AGSWaves::ResetAllGD);
|
||||
SCRIPT_METHOD(SpriteSkew, AGSWaves::SpriteSkew);
|
||||
SCRIPT_METHOD(FireUpdate, AGSWaves::FireUpdate);
|
||||
SCRIPT_METHOD(WindUpdate, AGSWaves::WindUpdate);
|
||||
SCRIPT_METHOD(SetWindValues, AGSWaves::SetWindValues);
|
||||
SCRIPT_METHOD(ReturnWidth, AGSWaves::ReturnWidth);
|
||||
SCRIPT_METHOD(ReturnHeight, AGSWaves::ReturnHeight);
|
||||
SCRIPT_METHOD(ReturnNewHeight, AGSWaves::ReturnNewHeight);
|
||||
SCRIPT_METHOD(ReturnNewWidth, AGSWaves::ReturnNewWidth);
|
||||
SCRIPT_METHOD(Warper, AGSWaves::Warper);
|
||||
SCRIPT_METHOD(SetWarper, AGSWaves::SetWarper);
|
||||
SCRIPT_METHOD(RainUpdate, AGSWaves::RainUpdate);
|
||||
SCRIPT_METHOD(BlendTwoSprites, AGSWaves::BlendTwoSprites);
|
||||
SCRIPT_METHOD(Blend, AGSWaves::Blend);
|
||||
SCRIPT_METHOD(Dissolve, AGSWaves::Dissolve);
|
||||
SCRIPT_METHOD(ReverseTransparency, AGSWaves::ReverseTransparency);
|
||||
SCRIPT_METHOD(NoiseCreator, AGSWaves::NoiseCreator);
|
||||
SCRIPT_METHOD(TintProper, AGSWaves::TintProper);
|
||||
SCRIPT_METHOD(GetWalkbehindBaserine, AGSWaves::GetWalkbehindBaserine);
|
||||
SCRIPT_METHOD(SetWalkbehindBaserine, AGSWaves::SetWalkbehindBaserine);
|
||||
|
||||
engine->RequestEventHook(AGSE_PREGUIDRAW);
|
||||
engine->RequestEventHook(AGSE_PRESCREENDRAW);
|
||||
engine->RequestEventHook(AGSE_SAVEGAME);
|
||||
engine->RequestEventHook(AGSE_RESTOREGAME);
|
||||
engine->RequestEventHook(AGSE_ENTERROOM);
|
||||
}
|
||||
|
||||
AGSWaves::~AGSWaves() {
|
||||
stopAllSounds();
|
||||
}
|
||||
|
||||
void AGS_EngineShutdown() {
|
||||
}
|
||||
|
||||
|
||||
int64 AGSWaves::AGS_EngineOnEvent(int event, NumberPtr data) {
|
||||
switch (event) {
|
||||
case AGSE_PREGUIDRAW:
|
||||
// Update();
|
||||
break;
|
||||
|
||||
case AGSE_RESTOREGAME: {
|
||||
stopAllSounds();
|
||||
|
||||
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) {
|
||||
SFX[j]._playing = _mixer->isSoundHandleActive(SFX[j]._soundHandle);
|
||||
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:
|
||||
// The original unloads sfx that are not playing and are not on repeat
|
||||
// I don't think we need to do anything here.
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AGSWaves::StartingValues() {
|
||||
GeneralAudio.NumOfChannels = 0;
|
||||
GeneralAudio.Initialized = false;
|
||||
GeneralAudio.Disabled = false;
|
||||
GeneralAudio.FilterFrequency = 10;
|
||||
GeneralAudio.SoundValue = 0;
|
||||
MFXStream.ID = 0;
|
||||
MFXStream.Channel = -1;
|
||||
MFXStream.Switch = false;
|
||||
MFXStream.FadeTime = 0;
|
||||
MFXStream.FadeRate = 0.0;
|
||||
MFXStream.FadeVolume = 0.0;
|
||||
MFXStream.HaltedZero = false;
|
||||
MFXStream.HaltedOne = false;
|
||||
|
||||
int j = 0;
|
||||
while (j < 2) {
|
||||
globalStream[j].Filename = nullptr;
|
||||
globalStream[j].repeat = 0;
|
||||
globalStream[j].volume = 0;
|
||||
globalStream[j].Vorbis = nullptr;
|
||||
globalStream[j].fix_click = false;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace AGSWaves
|
||||
} // namespace Plugins
|
||||
} // namespace AGS3
|
||||
189
engines/ags/plugins/ags_waves/ags_waves.h
Normal file
189
engines/ags/plugins/ags_waves/ags_waves.h
Normal file
@@ -0,0 +1,189 @@
|
||||
/* 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_WAVES_AGS_WAVES_H
|
||||
#define AGS_PLUGINS_AGS_WAVES_AGS_WAVES_H
|
||||
|
||||
#include "audio/mixer.h"
|
||||
#include "common/fs.h"
|
||||
#include "ags/plugins/ags_plugin.h"
|
||||
#include "ags/plugins/ags_waves/vars.h"
|
||||
|
||||
namespace AGS3 {
|
||||
namespace Plugins {
|
||||
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);
|
||||
void SFX_SetVolume(ScriptMethodParams ¶ms);
|
||||
void SFX_GetVolume(ScriptMethodParams ¶ms);
|
||||
void Music_Play(ScriptMethodParams ¶ms);
|
||||
void Music_GetVolume(ScriptMethodParams ¶ms);
|
||||
void Music_SetVolume(ScriptMethodParams ¶ms);
|
||||
void SFX_Stop(ScriptMethodParams ¶ms);
|
||||
void SFX_SetPosition(ScriptMethodParams ¶ms);
|
||||
void SFX_SetGlobalVolume(ScriptMethodParams ¶ms);
|
||||
void Load_SFX(ScriptMethodParams ¶ms);
|
||||
void Audio_Apply_Filter(ScriptMethodParams ¶ms);
|
||||
void Audio_Remove_Filter(ScriptMethodParams ¶ms);
|
||||
void SFX_AllowOverlap(ScriptMethodParams ¶ms);
|
||||
void SFX_Filter(ScriptMethodParams ¶ms);
|
||||
void DrawBlur(ScriptMethodParams ¶ms);
|
||||
void DrawTunnel(ScriptMethodParams ¶ms);
|
||||
void DrawCylinder(ScriptMethodParams ¶ms);
|
||||
void DrawForceField(ScriptMethodParams ¶ms);
|
||||
void Grayscale(ScriptMethodParams ¶ms);
|
||||
void ReadWalkBehindIntoSprite(ScriptMethodParams ¶ms);
|
||||
void AdjustSpriteFont(ScriptMethodParams ¶ms);
|
||||
void SpriteGradient(ScriptMethodParams ¶ms);
|
||||
void Outline(ScriptMethodParams ¶ms);
|
||||
void OutlineOnly(ScriptMethodParams ¶ms);
|
||||
void SaveVariable(ScriptMethodParams ¶ms);
|
||||
void ReadVariable(ScriptMethodParams ¶ms);
|
||||
void GameDoOnceOnly(ScriptMethodParams ¶ms);
|
||||
void SetGDState(ScriptMethodParams ¶ms);
|
||||
void GetGDState(ScriptMethodParams ¶ms);
|
||||
void ResetAllGD(ScriptMethodParams ¶ms);
|
||||
void SpriteSkew(ScriptMethodParams ¶ms);
|
||||
void FireUpdate(ScriptMethodParams ¶ms);
|
||||
void WindUpdate(ScriptMethodParams ¶ms);
|
||||
void SetWindValues(ScriptMethodParams ¶ms);
|
||||
void ReturnWidth(ScriptMethodParams ¶ms);
|
||||
void ReturnHeight(ScriptMethodParams ¶ms);
|
||||
void ReturnNewHeight(ScriptMethodParams ¶ms);
|
||||
void ReturnNewWidth(ScriptMethodParams ¶ms);
|
||||
void Warper(ScriptMethodParams ¶ms);
|
||||
void SetWarper(ScriptMethodParams ¶ms);
|
||||
void RainUpdate(ScriptMethodParams ¶ms);
|
||||
void BlendTwoSprites(ScriptMethodParams ¶ms);
|
||||
void Blend(ScriptMethodParams ¶ms);
|
||||
void Dissolve(ScriptMethodParams ¶ms);
|
||||
void ReverseTransparency(ScriptMethodParams ¶ms);
|
||||
void NoiseCreator(ScriptMethodParams ¶ms);
|
||||
void TintProper(ScriptMethodParams ¶ms);
|
||||
void GetWalkbehindBaserine(ScriptMethodParams ¶ms);
|
||||
void SetWalkbehindBaserine(ScriptMethodParams ¶ms);
|
||||
|
||||
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);
|
||||
int Random(int threshold);
|
||||
|
||||
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 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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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));
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
// 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);
|
||||
|
||||
/**
|
||||
* Stops a playing sound effect
|
||||
*/
|
||||
void StopSFX(int sfxNum);
|
||||
|
||||
/**
|
||||
* Loads a ScummVM OGG stream for playback
|
||||
*/
|
||||
Audio::AudioStream *loadOGG(const Common::ArchiveMemberPtr &member);
|
||||
|
||||
void playStream(Audio::Mixer::SoundType type, Audio::SoundHandle *handle, Audio::AudioStream *stream, int repeat);
|
||||
|
||||
void stopAllSounds();
|
||||
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();
|
||||
virtual ~AGSWaves();
|
||||
|
||||
const char *AGS_GetPluginName() override;
|
||||
void AGS_EngineStartup(IAGSEngine *engine) override;
|
||||
int64 AGS_EngineOnEvent(int event, NumberPtr data) override;
|
||||
};
|
||||
|
||||
} // namespace AGSWaves
|
||||
} // namespace Plugins
|
||||
} // namespace AGS3
|
||||
|
||||
#endif
|
||||
133
engines/ags/plugins/ags_waves/data.cpp
Normal file
133
engines/ags/plugins/ags_waves/data.cpp
Normal file
@@ -0,0 +1,133 @@
|
||||
/* 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 "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] == nullptr) {
|
||||
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] != nullptr)
|
||||
free(Token[i]);
|
||||
Token[i] = nullptr;
|
||||
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
|
||||
1176
engines/ags/plugins/ags_waves/draw.cpp
Normal file
1176
engines/ags/plugins/ags_waves/draw.cpp
Normal file
File diff suppressed because it is too large
Load Diff
295
engines/ags/plugins/ags_waves/sound.cpp
Normal file
295
engines/ags/plugins/ags_waves/sound.cpp
Normal file
@@ -0,0 +1,295 @@
|
||||
/* 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 "audio/decoders/vorbis.h"
|
||||
#include "common/util.h"
|
||||
#include "ags/plugins/ags_waves/ags_waves.h"
|
||||
#include "ags/shared/util/stdio_compat.h"
|
||||
#include "ags/ags.h"
|
||||
|
||||
namespace AGS3 {
|
||||
namespace Plugins {
|
||||
namespace AGSWaves {
|
||||
|
||||
//const float PI = 3.14159265f;
|
||||
|
||||
void AGSWaves::SFX_Play(ScriptMethodParams ¶ms) {
|
||||
PARAMS2(int, sfxNum, int, repeat);
|
||||
|
||||
SoundEffect &effect = SFX[sfxNum];
|
||||
if (_mixer->isSoundHandleActive(effect._soundHandle)) {
|
||||
if (effect._allow == 1) {
|
||||
// In this case we should start the sound on a new channel, not stopping
|
||||
// the one currently playing.
|
||||
warning("TODO: play overlapping sound with SFX_Play");
|
||||
}
|
||||
return;
|
||||
}
|
||||
_mixer->stopHandle(effect._soundHandle);
|
||||
|
||||
Common::ArchiveMemberPtr member = getFile(Common::String::format("sounds/sound%d.sfx", sfxNum).c_str());
|
||||
|
||||
Audio::AudioStream *sound = loadOGG(member);
|
||||
|
||||
if (sound != nullptr) {
|
||||
effect._volume = 255;
|
||||
|
||||
playStream(Audio::Mixer::kSFXSoundType, &effect._soundHandle, sound, repeat);
|
||||
|
||||
if (OGG_Filter && effect._filter && effect._volume > 1) {
|
||||
warning("TODO: Mix_RegisterEffect(grabChan, LPEffect, NULL, NULL);");
|
||||
}
|
||||
|
||||
effect._repeat = repeat;
|
||||
} else {
|
||||
debug(0, "AGSWaves::SFX_Play couldn't load sfx %d", sfxNum);
|
||||
}
|
||||
}
|
||||
|
||||
void AGSWaves::SFX_SetVolume(ScriptMethodParams ¶ms) {
|
||||
PARAMS2(int, sfxNum, int, volume);
|
||||
|
||||
SoundEffect &effect = SFX[sfxNum];
|
||||
_mixer->setChannelVolume(effect._soundHandle, volume);
|
||||
effect._volume = volume;
|
||||
}
|
||||
|
||||
void AGSWaves::SFX_GetVolume(ScriptMethodParams ¶ms) {
|
||||
PARAMS1(int, sfxNum);
|
||||
|
||||
SoundEffect &effect = SFX[sfxNum];
|
||||
params._result = _mixer->getChannelVolume(effect._soundHandle);
|
||||
}
|
||||
|
||||
void AGSWaves::Music_Play(ScriptMethodParams ¶ms) {
|
||||
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);
|
||||
_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, volume);
|
||||
}
|
||||
|
||||
void AGSWaves::Music_GetVolume(ScriptMethodParams ¶ms) {
|
||||
params._result = _mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType);
|
||||
}
|
||||
|
||||
void AGSWaves::SFX_Stop(ScriptMethodParams ¶ms) {
|
||||
PARAMS1(int, sfxNum); //, int, fademsOUT);
|
||||
StopSFX(sfxNum);
|
||||
}
|
||||
|
||||
void AGSWaves::SFX_SetPosition(ScriptMethodParams ¶ms) {
|
||||
#if 0
|
||||
PARAMS4(int, sfxNum, int, xS, int, yS, int, intensity);
|
||||
|
||||
SoundEffect &effect = SFX[sfxNum];
|
||||
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
debug(0, "TODO: SFX_Setposition positional sound not yet implemented");
|
||||
}
|
||||
|
||||
void AGSWaves::SFX_SetGlobalVolume(ScriptMethodParams ¶ms) {
|
||||
PARAMS1(int, volume);
|
||||
_mixer->setVolumeForSoundType(Audio::Mixer::kPlainSoundType, volume);
|
||||
}
|
||||
|
||||
void AGSWaves::Load_SFX(ScriptMethodParams ¶ms) {
|
||||
// PARAMS1(int, sfxNum);
|
||||
// LoadSFX(sfxNum);
|
||||
}
|
||||
|
||||
void AGSWaves::Audio_Apply_Filter(ScriptMethodParams ¶ms) {
|
||||
PARAMS1(int, Frequency);
|
||||
|
||||
GlitchFix();
|
||||
ApplyFilter(Frequency);
|
||||
}
|
||||
|
||||
void AGSWaves::Audio_Remove_Filter(ScriptMethodParams ¶ms) {
|
||||
}
|
||||
|
||||
void AGSWaves::SFX_AllowOverlap(ScriptMethodParams ¶ms) {
|
||||
PARAMS2(int, sfxNum, int, allow);
|
||||
SFX[sfxNum]._allow = allow;
|
||||
}
|
||||
|
||||
void AGSWaves::SFX_Filter(ScriptMethodParams ¶ms) {
|
||||
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;
|
||||
}
|
||||
|
||||
Audio::AudioStream *AGSWaves::loadOGG(const Common::ArchiveMemberPtr &member) {
|
||||
#ifdef USE_VORBIS
|
||||
if (member) {
|
||||
Audio::AudioStream *stream = Audio::makeVorbisStream(member->createReadStream(), DisposeAfterUse::YES);
|
||||
return stream;
|
||||
}
|
||||
#endif
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void AGSWaves::playStream(Audio::Mixer::SoundType type, Audio::SoundHandle *handle, Audio::AudioStream *stream, int repeat) {
|
||||
if (!handle || !stream)
|
||||
return;
|
||||
|
||||
if (repeat != 0) {
|
||||
Audio::SeekableAudioStream *sas =
|
||||
dynamic_cast<Audio::SeekableAudioStream *>(stream);
|
||||
assert(sas);
|
||||
|
||||
// -1 for infinite, >0 number of successive repeats
|
||||
Audio::LoopingAudioStream *las =
|
||||
new Audio::LoopingAudioStream(sas, repeat + 1);
|
||||
_mixer->playStream(type, handle, las);
|
||||
} else {
|
||||
_mixer->playStream(type, handle, stream);
|
||||
}
|
||||
}
|
||||
|
||||
void AGSWaves::StopSFX(int sfxNum) {
|
||||
SoundEffect &effect = SFX[sfxNum];
|
||||
_mixer->stopHandle(effect._soundHandle);
|
||||
effect._playing = 0;
|
||||
effect._repeat = 0;
|
||||
effect._channel = -2;
|
||||
}
|
||||
|
||||
void AGSWaves::stopAllSounds() {
|
||||
for (int i = 0; i < 500; ++i)
|
||||
StopSFX(i);
|
||||
|
||||
_mixer->stopHandle(MFXStream._soundHandle);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// Stop any previous music
|
||||
_mixer->stopHandle(MFXStream._soundHandle);
|
||||
|
||||
// Load OGG file for music
|
||||
Common::ArchiveMemberPtr member = getFile(Common::String::format("music/music%d.mfx", MusicToPlay).c_str());
|
||||
Audio::AudioStream *musicStream = loadOGG(member);
|
||||
if (!musicStream)
|
||||
return;
|
||||
|
||||
bool samefile = currentMusic != MusicToPlay;
|
||||
if (forceplay)
|
||||
samefile = true;
|
||||
|
||||
if (samefile) {
|
||||
currentMusicRepeat = repeat;
|
||||
currentMusicFadein = fadeinMS;
|
||||
currentMusic = MusicToPlay;
|
||||
|
||||
if (!MFXStream.Switch) {
|
||||
MFXStream.Channel = 0;
|
||||
|
||||
playStream(Audio::Mixer::kMusicSoundType,
|
||||
&MFXStream._soundHandle, musicStream, repeat);
|
||||
|
||||
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;
|
||||
|
||||
playStream(Audio::Mixer::kMusicSoundType,
|
||||
&MFXStream._soundHandle, musicStream, repeat);
|
||||
|
||||
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
|
||||
} // namespace Plugins
|
||||
} // namespace AGS3
|
||||
225
engines/ags/plugins/ags_waves/vars.h
Normal file
225
engines/ags/plugins/ags_waves/vars.h
Normal 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef AGS_PLUGINS_AGS_WAVES_VARS_H
|
||||
#define AGS_PLUGINS_AGS_WAVES_VARS_H
|
||||
|
||||
#include "audio/audiostream.h"
|
||||
|
||||
namespace AGS3 {
|
||||
namespace Plugins {
|
||||
namespace AGSWaves {
|
||||
|
||||
#define texWidth 240
|
||||
#define texHeight 240
|
||||
#define screenWidth 640
|
||||
#define screenHeight 360
|
||||
|
||||
// TODO: Dummy definitions that need to be fixed
|
||||
typedef void *stb_vorbis;
|
||||
typedef void *Mix_Chunk;
|
||||
typedef int SDL_AudioSpec;
|
||||
typedef int SDL_AudioDeviceID;
|
||||
|
||||
struct Particle {
|
||||
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;
|
||||
};
|
||||
|
||||
/*---------------------------------------------*/
|
||||
|
||||
typedef int (*SCAPI_CHARACTER_GETX)(AGSCharacter *ch);
|
||||
typedef int (*SCAPI_CHARACTER_GETY)(AGSCharacter *ch);
|
||||
typedef int (*SCAPI_CHARACTER_ID) (AGSCharacter *ch);
|
||||
|
||||
//WAVE SOUNDS FILES
|
||||
struct SoundEffect {
|
||||
Audio::SoundHandle _soundHandle;
|
||||
int _repeat = 0;
|
||||
int _volume = 0;
|
||||
int _allow = 0;
|
||||
int _channel = 0;
|
||||
int _filter = 0;
|
||||
int _playing = 0;
|
||||
};
|
||||
|
||||
struct Aud {
|
||||
int NumOfChannels = 0;
|
||||
bool Initialized = false;
|
||||
bool Disabled = false;
|
||||
int FilterFrequency = 0;
|
||||
int SoundValue = 0;
|
||||
};
|
||||
|
||||
struct Mus {
|
||||
int ID = 0;
|
||||
int FadeTime = 0;
|
||||
float FadeRate = 0;
|
||||
float FadeVolume = 0;
|
||||
int Channel = 0;
|
||||
bool Switch = 0;
|
||||
bool HaltedZero = 0;
|
||||
bool HaltedOne = 0;
|
||||
Audio::SoundHandle _soundHandle;
|
||||
};
|
||||
|
||||
struct RainParticle {
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int fx = 0;
|
||||
int fy = 0;
|
||||
int life = 0;
|
||||
int trans = 0;
|
||||
bool active = 0;
|
||||
int translay = 0;
|
||||
int transhold = 0;
|
||||
};
|
||||
|
||||
struct MusicStream {
|
||||
int volume = 0;
|
||||
const char *Filename = nullptr;
|
||||
int repeat = 0;
|
||||
stb_vorbis *Vorbis = 0;
|
||||
bool fix_click = false;
|
||||
};
|
||||
|
||||
struct DustParticle {
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int transp = 0;
|
||||
int life = 0;
|
||||
bool active = false;
|
||||
int dx = 0;
|
||||
int dy = 0;
|
||||
int mlay = 0;
|
||||
int timlay = 0;
|
||||
int movedport = 0;
|
||||
int translay = 0;
|
||||
int translayHold = 0;
|
||||
};
|
||||
|
||||
struct Vars {
|
||||
int32 screen_width = 640;
|
||||
int32 screen_height = 360;
|
||||
int32 screen_color_depth = 32;
|
||||
AGSCharacter *playerCharacter = nullptr;
|
||||
|
||||
PluginMethod Character_GetX;
|
||||
PluginMethod Character_GetY;
|
||||
PluginMethod Character_ID;
|
||||
|
||||
SoundEffect SFX[500];
|
||||
RainParticle RainParticles[400];
|
||||
RainParticle RainParticlesFore[400];
|
||||
RainParticle RainParticlesBack[800];
|
||||
Aud GeneralAudio;
|
||||
Mus MFXStream;
|
||||
|
||||
int currentMusic = -1;
|
||||
int currentMusicRepeat = -1;
|
||||
int currentMusicFadein = 0;
|
||||
|
||||
double xv[3];
|
||||
double yv[3];
|
||||
double xvOGG[3];
|
||||
double yvOGG[3];
|
||||
|
||||
Particle particles[110];
|
||||
Particle particlesF[10];
|
||||
Particle particles2[12];
|
||||
int WForceX[400];
|
||||
int WForceY[400];
|
||||
|
||||
int raysizeF = 4;
|
||||
int dsizeF = 0;
|
||||
int raysize = 100;
|
||||
int dsize = 0;
|
||||
int raysize2 = 12;
|
||||
int dsize2 = 0;
|
||||
int creationdelayf = 0;
|
||||
int ww;
|
||||
int hh;
|
||||
int proom;
|
||||
int prevroom;
|
||||
bool OGG_Filter = false;
|
||||
|
||||
SDL_AudioSpec spec[2];
|
||||
MusicStream globalStream[2];
|
||||
SDL_AudioDeviceID getDevice[2];
|
||||
bool AudioEnabled = false;
|
||||
float ix = 0, iy = 0, ua = 0;
|
||||
float b_time[5];
|
||||
float d_time = 0;
|
||||
|
||||
// Y-coordinate first because we use horizontal scanlines
|
||||
uint32 texture[texHeight][texWidth];
|
||||
int distanceTable[screenHeight][screenWidth];
|
||||
int angleTable[screenHeight][screenWidth];
|
||||
bool generateonce = false;
|
||||
|
||||
DustParticle dusts[200];
|
||||
int waitBy = 6;
|
||||
int raysizeDust = 200;
|
||||
int dsizeDust = 0;
|
||||
int creationdelay = 0;
|
||||
int Walkbehind[20];
|
||||
char *GameDatavalue[40000];
|
||||
char *Token[10000];
|
||||
int TokenUnUsed[10000];
|
||||
int usedTokens = 0;
|
||||
|
||||
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
|
||||
} // namespace Plugins
|
||||
} // namespace AGS3
|
||||
|
||||
#endif
|
||||
185
engines/ags/plugins/ags_waves/warper.cpp
Normal file
185
engines/ags/plugins/ags_waves/warper.cpp
Normal file
@@ -0,0 +1,185 @@
|
||||
/* 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 "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);
|
||||
int32 refsrc_width = 640;
|
||||
int32 refsrc_height = 360;
|
||||
int32 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);
|
||||
int32 src_width = 640;
|
||||
int32 src_height = 360;
|
||||
int32 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
|
||||
1076
engines/ags/plugins/ags_waves/weather.cpp
Normal file
1076
engines/ags/plugins/ags_waves/weather.cpp
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user