/* 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 . * */ #include "ags/lib/allegro.h" #include "ags/plugins/ags_flashlight/ags_flashlight.h" #include "ags/shared/core/platform.h" #include "common/str.h" namespace AGS3 { namespace Plugins { namespace AGSFlashlight { const uint32 Magic = 0xBABE0000; const uint32 Version = 2; const uint32 SaveMagic = Magic + Version; const char *AGSFlashlight::AGS_GetPluginName() { return "Flashlight plugin recreation"; } void AGSFlashlight::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(SetFlashlightTint, AGSFlashlight::SetFlashlightTint); SCRIPT_METHOD(GetFlashlightTintRed, AGSFlashlight::GetFlashlightTintRed); SCRIPT_METHOD(GetFlashlightTintGreen, AGSFlashlight::GetFlashlightTintGreen); SCRIPT_METHOD(GetFlashlightTintBlue, AGSFlashlight::GetFlashlightTintBlue); SCRIPT_METHOD(GetFlashlightMinLightLevel, AGSFlashlight::GetFlashlightMinLightLevel); SCRIPT_METHOD(GetFlashlightMaxLightLevel, AGSFlashlight::GetFlashlightMaxLightLevel); SCRIPT_METHOD(SetFlashlightDarkness, AGSFlashlight::SetFlashlightDarkness); SCRIPT_METHOD(GetFlashlightDarkness, AGSFlashlight::GetFlashlightDarkness); SCRIPT_METHOD(SetFlashlightDarknessSize, AGSFlashlight::SetFlashlightDarknessSize); SCRIPT_METHOD(GetFlashlightDarknessSize, AGSFlashlight::GetFlashlightDarknessSize); SCRIPT_METHOD(SetFlashlightBrightness, AGSFlashlight::SetFlashlightBrightness); SCRIPT_METHOD(GetFlashlightBrightness, AGSFlashlight::GetFlashlightBrightness); SCRIPT_METHOD(SetFlashlightBrightnessSize, AGSFlashlight::SetFlashlightBrightnessSize); SCRIPT_METHOD(GetFlashlightBrightnessSize, AGSFlashlight::GetFlashlightBrightnessSize); SCRIPT_METHOD(SetFlashlightPosition, AGSFlashlight::SetFlashlightPosition); SCRIPT_METHOD(GetFlashlightPositionX, AGSFlashlight::GetFlashlightPositionX); SCRIPT_METHOD(GetFlashlightPositionY, AGSFlashlight::GetFlashlightPositionY); SCRIPT_METHOD(SetFlashlightFollowMouse, AGSFlashlight::SetFlashlightFollowMouse); SCRIPT_METHOD(GetFlashlightFollowMouse, AGSFlashlight::GetFlashlightFollowMouse); SCRIPT_METHOD(SetFlashlightFollowCharacter, AGSFlashlight::SetFlashlightFollowCharacter); SCRIPT_METHOD(GetFlashlightFollowCharacter, AGSFlashlight::GetFlashlightFollowCharacter); SCRIPT_METHOD(GetFlashlightCharacterDX, AGSFlashlight::GetFlashlightCharacterDX); SCRIPT_METHOD(GetFlashlightCharacterDY, AGSFlashlight::GetFlashlightCharacterDY); SCRIPT_METHOD(GetFlashlightCharacterHorz, AGSFlashlight::GetFlashlightCharacterHorz); SCRIPT_METHOD(GetFlashlightCharacterVert, AGSFlashlight::GetFlashlightCharacterVert); SCRIPT_METHOD(SetFlashlightMask, AGSFlashlight::SetFlashlightMask); SCRIPT_METHOD(GetFlashlightMask, AGSFlashlight::GetFlashlightMask); _engine->RequestEventHook(AGSE_PREGUIDRAW); _engine->RequestEventHook(AGSE_PRESCREENDRAW); _engine->RequestEventHook(AGSE_SAVEGAME); _engine->RequestEventHook(AGSE_RESTOREGAME); } int64 AGSFlashlight::AGS_EngineOnEvent(int event, NumberPtr data) { if (event == AGSE_PREGUIDRAW) { Update(); } else if (event == AGSE_RESTOREGAME) { Serializer s(_engine, data, true); syncGame(s); } else if (event == AGSE_SAVEGAME) { Serializer s(_engine, data, false); syncGame(s); } else if (event == AGSE_PRESCREENDRAW) { // Get screen size once here. _engine->GetScreenDimensions(&screen_width, &screen_height, &screen_color_depth); // TODO: There's no reliable way to figure out if a game is running in legacy upscale mode from the // plugin interface, so for now let's just play it conservatively and check it per-game AGSGameInfo *gameInfo = new AGSGameInfo; gameInfo->Version = 26; _engine->GetGameInfo(gameInfo); if (gameInfo->UniqueId == 1050154255 || // MMD, MMM04, MMM13, MMM28, MMM46, MMM56, MMM57, MMM68, MMM78, MMMD9, MMMH5 gameInfo->UniqueId == 1161197869) // MMM70 g_ScaleFactor = (screen_width > 320) ? 2 : 1; delete gameInfo; _engine->UnrequestEventHook(AGSE_PRESCREENDRAW); } return 0; } void AGSFlashlight::syncGame(Serializer &s) { uint32 SaveVersion = SaveMagic; s.syncAsInt(SaveVersion); if (s.isLoading() && SaveVersion != SaveMagic) { // The real AGSFlashlight, or at least the one included with // Maniac Mansion Deluxe, doesn't persist any fields. // So in such a case, revert the 4 bytes and skip everything else s.unreadInt(); } else { s.syncAsInt(g_RedTint); s.syncAsInt(g_GreenTint); s.syncAsInt(g_BlueTint); s.syncAsInt(g_DarknessLightLevel); s.syncAsInt(g_BrightnessLightLevel); s.syncAsInt(g_DarknessSize); s.syncAsInt(g_DarknessDiameter); s.syncAsInt(g_BrightnessSize); s.syncAsInt(g_FlashlightX); s.syncAsInt(g_FlashlightY); s.syncAsInt(g_FlashlightFollowMouse); s.syncAsInt(g_FollowCharacterId); s.syncAsInt(g_FollowCharacterDx); s.syncAsInt(g_FollowCharacterDy); s.syncAsInt(g_FollowCharacterHorz); s.syncAsInt(g_FollowCharacterVert); if (s.isLoading()) { if (g_FollowCharacterId != 0) g_FollowCharacter = _engine->GetCharacter(g_FollowCharacterId); g_BitmapMustBeUpdated = true; } } } void AGSFlashlight::SetFlashlightTint(ScriptMethodParams ¶ms) { PARAMS3(int, RedTint, int, GreenTint, int, BlueTint); ClipToRange(RedTint, -31, 31); ClipToRange(GreenTint, -31, 31); ClipToRange(BlueTint, -31, 31); if ((RedTint != g_RedTint) || (GreenTint != g_GreenTint) || (BlueTint != g_BlueTint)) g_BitmapMustBeUpdated = true; g_RedTint = RedTint; g_GreenTint = GreenTint; g_BlueTint = BlueTint; } void AGSFlashlight::GetFlashlightTintRed(ScriptMethodParams ¶ms) { params._result = g_RedTint; } void AGSFlashlight::GetFlashlightTintGreen(ScriptMethodParams ¶ms) { params._result = g_GreenTint; } void AGSFlashlight::GetFlashlightTintBlue(ScriptMethodParams ¶ms) { params._result = g_BlueTint; } void AGSFlashlight::GetFlashlightMinLightLevel(ScriptMethodParams ¶ms) { params._result = 0; } void AGSFlashlight::GetFlashlightMaxLightLevel(ScriptMethodParams ¶ms) { params._result = 100; } void AGSFlashlight::SetFlashlightDarkness(ScriptMethodParams ¶ms) { PARAMS1(int, LightLevel); ClipToRange(LightLevel, 0, 100); if (LightLevel != g_DarknessLightLevel) { g_BitmapMustBeUpdated = true; g_DarknessLightLevel = LightLevel; if (g_DarknessLightLevel > g_BrightnessLightLevel) g_BrightnessLightLevel = g_DarknessLightLevel; } } void AGSFlashlight::GetFlashlightDarkness(ScriptMethodParams ¶ms) { params._result = g_DarknessLightLevel; } void AGSFlashlight::SetFlashlightDarknessSize(ScriptMethodParams ¶ms) { PARAMS1(int, Size); if (Size * g_ScaleFactor != g_DarknessSize) { g_BitmapMustBeUpdated = true; g_DarknessSize = Size * g_ScaleFactor; g_DarknessDiameter = g_DarknessSize * 2; if (g_BrightnessSize > g_DarknessSize) { ScriptMethodParams p(g_DarknessSize / g_ScaleFactor); SetFlashlightBrightnessSize(p); } } } void AGSFlashlight::GetFlashlightDarknessSize(ScriptMethodParams ¶ms) { params._result = (g_DarknessSize / g_ScaleFactor); } void AGSFlashlight::SetFlashlightBrightness(ScriptMethodParams ¶ms) { PARAMS1(int, LightLevel); ClipToRange(LightLevel, 0, 100); if (LightLevel != g_BrightnessLightLevel) { g_BitmapMustBeUpdated = true; g_BrightnessLightLevel = LightLevel; if (g_BrightnessLightLevel < g_DarknessLightLevel) g_DarknessLightLevel = g_BrightnessLightLevel; } } void AGSFlashlight::GetFlashlightBrightness(ScriptMethodParams ¶ms) { params._result = g_BrightnessLightLevel; } void AGSFlashlight::SetFlashlightBrightnessSize(ScriptMethodParams ¶ms) { PARAMS1(int, Size); if (Size * g_ScaleFactor != g_BrightnessSize) { g_BitmapMustBeUpdated = true; g_BrightnessSize = Size * g_ScaleFactor; if (g_DarknessSize < g_BrightnessSize) { ScriptMethodParams p(g_BrightnessSize / g_ScaleFactor); SetFlashlightDarknessSize(p); } } } void AGSFlashlight::GetFlashlightBrightnessSize(ScriptMethodParams ¶ms) { params._result = g_BrightnessSize / g_ScaleFactor; } void AGSFlashlight::SetFlashlightPosition(ScriptMethodParams ¶ms) { PARAMS2(int, X, int, Y); g_FlashlightX = X; g_FlashlightY = Y; } void AGSFlashlight::GetFlashlightPositionX(ScriptMethodParams ¶ms) { params._result = g_FlashlightX; } void AGSFlashlight::GetFlashlightPositionY(ScriptMethodParams ¶ms) { params._result = g_FlashlightY; } void AGSFlashlight::SetFlashlightFollowMouse(ScriptMethodParams ¶ms) { PARAMS1(int, OnOff); g_FlashlightFollowMouse = (OnOff != 0); } void AGSFlashlight::GetFlashlightFollowMouse(ScriptMethodParams ¶ms) { params._result = g_FlashlightFollowMouse ? 1 : 0; } void AGSFlashlight::SetFlashlightFollowCharacter(ScriptMethodParams ¶ms) { PARAMS5(int, CharacterId, int, dx, int, dy, int, horz, int, vert); g_FollowCharacterId = CharacterId; g_FollowCharacterDx = dx; g_FollowCharacterDy = dy; g_FollowCharacterHorz = horz; g_FollowCharacterVert = vert; g_FollowCharacter = _engine->GetCharacter(CharacterId); } void AGSFlashlight::GetFlashlightFollowCharacter(ScriptMethodParams ¶ms) { params._result = g_FollowCharacterId; } void AGSFlashlight::GetFlashlightCharacterDX(ScriptMethodParams ¶ms) { params._result = g_FollowCharacterDx; } void AGSFlashlight::GetFlashlightCharacterDY(ScriptMethodParams ¶ms) { params._result = g_FollowCharacterDy; } void AGSFlashlight::GetFlashlightCharacterHorz(ScriptMethodParams ¶ms) { params._result = g_FollowCharacterHorz; } void AGSFlashlight::GetFlashlightCharacterVert(ScriptMethodParams ¶ms) { params._result = g_FollowCharacterVert; } void AGSFlashlight::SetFlashlightMask(ScriptMethodParams ¶ms) { //PARAMS1(int, SpriteSlot); // Not implemented. } void AGSFlashlight::GetFlashlightMask(ScriptMethodParams ¶ms) { params._result = 0; } } // namespace AGSFlashlight } // namespace Plugins } // namespace AGS3