1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or(at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #include "ags/lib/allegro.h"
24 #include "ags/plugins/ags_flashlight/ags_flashlight.h"
25 #include "ags/shared/core/platform.h"
26 #include "common/str.h"
27 
28 namespace AGS3 {
29 namespace Plugins {
30 namespace AGSFlashlight {
31 
32 const uint32 Magic = 0xBABE0000;
33 const uint32 Version = 2;
34 const uint32 SaveMagic = Magic + Version;
35 
AGS_GetPluginName()36 const char *AGSFlashlight::AGS_GetPluginName() {
37 	return "Flashlight plugin recreation";
38 }
39 
AGS_EngineStartup(IAGSEngine * engine)40 void AGSFlashlight::AGS_EngineStartup(IAGSEngine *engine) {
41 	PluginBase::AGS_EngineStartup(engine);
42 
43 	if (_engine->version < 13)
44 		_engine->AbortGame("Engine interface is too old, need newer version of AGS.");
45 
46 	SCRIPT_METHOD(SetFlashlightTint, AGSFlashlight::SetFlashlightTint);
47 	SCRIPT_METHOD(GetFlashlightTintRed, AGSFlashlight::GetFlashlightTintRed);
48 	SCRIPT_METHOD(GetFlashlightTintGreen, AGSFlashlight::GetFlashlightTintGreen);
49 	SCRIPT_METHOD(GetFlashlightTintBlue, AGSFlashlight::GetFlashlightTintBlue);
50 
51 	SCRIPT_METHOD(GetFlashlightMinLightLevel, AGSFlashlight::GetFlashlightMinLightLevel);
52 	SCRIPT_METHOD(GetFlashlightMaxLightLevel, AGSFlashlight::GetFlashlightMaxLightLevel);
53 
54 	SCRIPT_METHOD(SetFlashlightDarkness, AGSFlashlight::SetFlashlightDarkness);
55 	SCRIPT_METHOD(GetFlashlightDarkness, AGSFlashlight::GetFlashlightDarkness);
56 	SCRIPT_METHOD(SetFlashlightDarknessSize, AGSFlashlight::SetFlashlightDarknessSize);
57 	SCRIPT_METHOD(GetFlashlightDarknessSize, AGSFlashlight::GetFlashlightDarknessSize);
58 
59 	SCRIPT_METHOD(SetFlashlightBrightness, AGSFlashlight::SetFlashlightBrightness);
60 	SCRIPT_METHOD(GetFlashlightBrightness, AGSFlashlight::GetFlashlightBrightness);
61 	SCRIPT_METHOD(SetFlashlightBrightnessSize, AGSFlashlight::SetFlashlightBrightnessSize);
62 	SCRIPT_METHOD(GetFlashlightBrightnessSize, AGSFlashlight::GetFlashlightBrightnessSize);
63 
64 	SCRIPT_METHOD(SetFlashlightPosition, AGSFlashlight::SetFlashlightPosition);
65 	SCRIPT_METHOD(GetFlashlightPositionX, AGSFlashlight::GetFlashlightPositionX);
66 	SCRIPT_METHOD(GetFlashlightPositionY, AGSFlashlight::GetFlashlightPositionY);
67 
68 
69 	SCRIPT_METHOD(SetFlashlightFollowMouse, AGSFlashlight::SetFlashlightFollowMouse);
70 	SCRIPT_METHOD(GetFlashlightFollowMouse, AGSFlashlight::GetFlashlightFollowMouse);
71 
72 	SCRIPT_METHOD(SetFlashlightFollowCharacter, AGSFlashlight::SetFlashlightFollowCharacter);
73 	SCRIPT_METHOD(GetFlashlightFollowCharacter, AGSFlashlight::GetFlashlightFollowCharacter);
74 	SCRIPT_METHOD(GetFlashlightCharacterDX, AGSFlashlight::GetFlashlightCharacterDX);
75 	SCRIPT_METHOD(GetFlashlightCharacterDY, AGSFlashlight::GetFlashlightCharacterDY);
76 	SCRIPT_METHOD(GetFlashlightCharacterHorz, AGSFlashlight::GetFlashlightCharacterHorz);
77 	SCRIPT_METHOD(GetFlashlightCharacterVert, AGSFlashlight::GetFlashlightCharacterVert);
78 
79 	SCRIPT_METHOD(SetFlashlightMask, AGSFlashlight::SetFlashlightMask);
80 	SCRIPT_METHOD(GetFlashlightMask, AGSFlashlight::GetFlashlightMask);
81 
82 	_engine->RequestEventHook(AGSE_PREGUIDRAW);
83 	_engine->RequestEventHook(AGSE_PRESCREENDRAW);
84 	_engine->RequestEventHook(AGSE_SAVEGAME);
85 	_engine->RequestEventHook(AGSE_RESTOREGAME);
86 }
87 
AGS_EngineOnEvent(int event,NumberPtr data)88 int64 AGSFlashlight::AGS_EngineOnEvent(int event, NumberPtr data) {
89 	if (event == AGSE_PREGUIDRAW) {
90 		Update();
91 	} else if (event == AGSE_RESTOREGAME) {
92 		Serializer s(_engine, data, true);
93 		syncGame(s);
94 	} else if (event == AGSE_SAVEGAME) {
95 		Serializer s(_engine, data, false);
96 		syncGame(s);
97 	} else if (event == AGSE_PRESCREENDRAW) {
98 		// Get screen size once here.
99 		_engine->GetScreenDimensions(&screen_width, &screen_height, &screen_color_depth);
100 		_engine->UnrequestEventHook(AGSE_PRESCREENDRAW);
101 	}
102 
103 	return 0;
104 }
105 
syncGame(Serializer & s)106 void AGSFlashlight::syncGame(Serializer &s) {
107 	uint32 SaveVersion = SaveMagic;
108 	s.syncAsInt(SaveVersion);
109 
110 	if (s.isLoading() && SaveVersion != SaveMagic) {
111 		// The real AGSFlashlight, or at least the one included with
112 		// Maniac Mansion Deluxe, doesn't persist any fields.
113 		// So in such a case, revert the 4 bytes and skip everything else
114 		s.unreadInt();
115 
116 	} else {
117 		s.syncAsInt(g_RedTint);
118 		s.syncAsInt(g_GreenTint);
119 		s.syncAsInt(g_BlueTint);
120 
121 		s.syncAsInt(g_DarknessLightLevel);
122 		s.syncAsInt(g_BrightnessLightLevel);
123 		s.syncAsInt(g_DarknessSize);
124 		s.syncAsInt(g_DarknessDiameter);
125 		s.syncAsInt(g_BrightnessSize);
126 
127 		s.syncAsInt(g_FlashlightX);
128 		s.syncAsInt(g_FlashlightY);
129 
130 		s.syncAsInt(g_FlashlightFollowMouse);
131 
132 		s.syncAsInt(g_FollowCharacterId);
133 		s.syncAsInt(g_FollowCharacterDx);
134 		s.syncAsInt(g_FollowCharacterDy);
135 		s.syncAsInt(g_FollowCharacterHorz);
136 		s.syncAsInt(g_FollowCharacterVert);
137 
138 		if (s.isLoading()) {
139 			if (g_FollowCharacterId != 0)
140 				g_FollowCharacter = _engine->GetCharacter(g_FollowCharacterId);
141 
142 			g_BitmapMustBeUpdated = true;
143 		}
144 	}
145 }
146 
SetFlashlightTint(ScriptMethodParams & params)147 void AGSFlashlight::SetFlashlightTint(ScriptMethodParams &params) {
148 	PARAMS3(int, RedTint, int, GreenTint, int, BlueTint);
149 	ClipToRange(RedTint, -31, 31);
150 	ClipToRange(GreenTint, -31, 31);
151 	ClipToRange(BlueTint, -31, 31);
152 
153 	if ((RedTint != g_RedTint) || (GreenTint != g_GreenTint) || (BlueTint != g_BlueTint))
154 		g_BitmapMustBeUpdated = true;
155 
156 	g_RedTint = RedTint;
157 	g_GreenTint = GreenTint;
158 	g_BlueTint = BlueTint;
159 }
160 
GetFlashlightTintRed(ScriptMethodParams & params)161 void AGSFlashlight::GetFlashlightTintRed(ScriptMethodParams &params) {
162 	params._result = g_RedTint;
163 }
164 
GetFlashlightTintGreen(ScriptMethodParams & params)165 void AGSFlashlight::GetFlashlightTintGreen(ScriptMethodParams &params) {
166 	params._result = g_GreenTint;
167 }
168 
GetFlashlightTintBlue(ScriptMethodParams & params)169 void AGSFlashlight::GetFlashlightTintBlue(ScriptMethodParams &params) {
170 	params._result = g_BlueTint;
171 }
172 
GetFlashlightMinLightLevel(ScriptMethodParams & params)173 void AGSFlashlight::GetFlashlightMinLightLevel(ScriptMethodParams &params) {
174 	params._result = 0;
175 }
176 
GetFlashlightMaxLightLevel(ScriptMethodParams & params)177 void AGSFlashlight::GetFlashlightMaxLightLevel(ScriptMethodParams &params) {
178 	params._result = 100;
179 }
180 
SetFlashlightDarkness(ScriptMethodParams & params)181 void AGSFlashlight::SetFlashlightDarkness(ScriptMethodParams &params) {
182 	PARAMS1(int, LightLevel);
183 	ClipToRange(LightLevel, 0, 100);
184 
185 	if (LightLevel != g_DarknessLightLevel) {
186 		g_BitmapMustBeUpdated = true;
187 		g_DarknessLightLevel = LightLevel;
188 
189 		if (g_DarknessLightLevel > g_BrightnessLightLevel)
190 			g_BrightnessLightLevel = g_DarknessLightLevel;
191 	}
192 }
193 
GetFlashlightDarkness(ScriptMethodParams & params)194 void AGSFlashlight::GetFlashlightDarkness(ScriptMethodParams &params) {
195 	params._result = g_DarknessLightLevel;
196 }
197 
SetFlashlightDarknessSize(ScriptMethodParams & params)198 void AGSFlashlight::SetFlashlightDarknessSize(ScriptMethodParams &params) {
199 	PARAMS1(int, Size);
200 	if (Size != g_DarknessSize) {
201 		g_BitmapMustBeUpdated = true;
202 		g_DarknessSize = Size;
203 		g_DarknessDiameter = g_DarknessSize * 2;
204 
205 		if (g_BrightnessSize > g_DarknessSize) {
206 			ScriptMethodParams p(g_DarknessSize);
207 			SetFlashlightBrightnessSize(p);
208 		}
209 	}
210 }
211 
GetFlashlightDarknessSize(ScriptMethodParams & params)212 void AGSFlashlight::GetFlashlightDarknessSize(ScriptMethodParams &params) {
213 	params._result = g_DarknessSize;
214 }
215 
216 
SetFlashlightBrightness(ScriptMethodParams & params)217 void AGSFlashlight::SetFlashlightBrightness(ScriptMethodParams &params) {
218 	PARAMS1(int, LightLevel);
219 	ClipToRange(LightLevel, 0, 100);
220 
221 	if (LightLevel != g_BrightnessLightLevel) {
222 		g_BitmapMustBeUpdated = true;
223 		g_BrightnessLightLevel = LightLevel;
224 
225 		if (g_BrightnessLightLevel < g_DarknessLightLevel)
226 			g_DarknessLightLevel = g_BrightnessLightLevel;
227 	}
228 }
229 
GetFlashlightBrightness(ScriptMethodParams & params)230 void AGSFlashlight::GetFlashlightBrightness(ScriptMethodParams &params) {
231 	params._result = g_BrightnessLightLevel;
232 }
233 
SetFlashlightBrightnessSize(ScriptMethodParams & params)234 void AGSFlashlight::SetFlashlightBrightnessSize(ScriptMethodParams &params) {
235 	PARAMS1(int, Size);
236 	if (Size != g_BrightnessSize) {
237 		g_BitmapMustBeUpdated = true;
238 		g_BrightnessSize = Size;
239 
240 		if (g_DarknessSize < g_BrightnessSize) {
241 			ScriptMethodParams p(g_BrightnessSize);
242 			SetFlashlightDarknessSize(p);
243 		}
244 	}
245 }
246 
GetFlashlightBrightnessSize(ScriptMethodParams & params)247 void AGSFlashlight::GetFlashlightBrightnessSize(ScriptMethodParams &params) {
248 	params._result = g_BrightnessSize;
249 }
250 
SetFlashlightPosition(ScriptMethodParams & params)251 void AGSFlashlight::SetFlashlightPosition(ScriptMethodParams &params) {
252 	PARAMS2(int, X, int, Y);
253 	g_FlashlightX = X;
254 	g_FlashlightY = Y;
255 }
256 
GetFlashlightPositionX(ScriptMethodParams & params)257 void AGSFlashlight::GetFlashlightPositionX(ScriptMethodParams &params) {
258 	params._result = g_FlashlightX;
259 }
260 
GetFlashlightPositionY(ScriptMethodParams & params)261 void AGSFlashlight::GetFlashlightPositionY(ScriptMethodParams &params) {
262 	params._result = g_FlashlightY;
263 }
264 
SetFlashlightFollowMouse(ScriptMethodParams & params)265 void AGSFlashlight::SetFlashlightFollowMouse(ScriptMethodParams &params) {
266 	PARAMS1(int, OnOff);
267 	g_FlashlightFollowMouse = (OnOff != 0);
268 }
269 
GetFlashlightFollowMouse(ScriptMethodParams & params)270 void AGSFlashlight::GetFlashlightFollowMouse(ScriptMethodParams &params) {
271 	params._result = g_FlashlightFollowMouse ? 1 : 0;
272 }
273 
SetFlashlightFollowCharacter(ScriptMethodParams & params)274 void AGSFlashlight::SetFlashlightFollowCharacter(ScriptMethodParams &params) {
275 	PARAMS5(int, CharacterId, int, dx, int, dy, int, horz, int, vert);
276 	g_FollowCharacterId = CharacterId;
277 	g_FollowCharacterDx = dx;
278 	g_FollowCharacterDy = dy;
279 	g_FollowCharacterHorz = horz;
280 	g_FollowCharacterVert = vert;
281 
282 	g_FollowCharacter = _engine->GetCharacter(CharacterId);
283 }
284 
GetFlashlightFollowCharacter(ScriptMethodParams & params)285 void AGSFlashlight::GetFlashlightFollowCharacter(ScriptMethodParams &params) {
286 	params._result = g_FollowCharacterId;
287 }
288 
GetFlashlightCharacterDX(ScriptMethodParams & params)289 void AGSFlashlight::GetFlashlightCharacterDX(ScriptMethodParams &params) {
290 	params._result = g_FollowCharacterDx;
291 }
292 
GetFlashlightCharacterDY(ScriptMethodParams & params)293 void AGSFlashlight::GetFlashlightCharacterDY(ScriptMethodParams &params) {
294 	params._result = g_FollowCharacterDy;
295 }
296 
GetFlashlightCharacterHorz(ScriptMethodParams & params)297 void AGSFlashlight::GetFlashlightCharacterHorz(ScriptMethodParams &params) {
298 	params._result = g_FollowCharacterHorz;
299 }
300 
GetFlashlightCharacterVert(ScriptMethodParams & params)301 void AGSFlashlight::GetFlashlightCharacterVert(ScriptMethodParams &params) {
302 	params._result = g_FollowCharacterVert;
303 }
304 
SetFlashlightMask(ScriptMethodParams & params)305 void AGSFlashlight::SetFlashlightMask(ScriptMethodParams &params) {
306 	//PARAMS1(int, SpriteSlot);
307 	// Not implemented.
308 }
309 
GetFlashlightMask(ScriptMethodParams & params)310 void AGSFlashlight::GetFlashlightMask(ScriptMethodParams &params) {
311 	params._result = 0;
312 }
313 
314 } // namespace AGSFlashlight
315 } // namespace Plugins
316 } // namespace AGS3
317