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/plugins/ags_parallax/ags_parallax.h"
24 #include "ags/shared/core/platform.h"
25 #include "common/endian.h"
26
27 namespace AGS3 {
28 namespace Plugins {
29 namespace AGSParallax {
30
31 const unsigned int Magic = 0xCAFE0000;
32 const unsigned int Version = 2;
33 const unsigned int SaveMagic = Magic + Version;
34
AGS_GetPluginName()35 const char *AGSParallax::AGS_GetPluginName() {
36 return "Parallax plugin recreation";
37 }
38
AGS_EngineStartup(IAGSEngine * engine)39 void AGSParallax::AGS_EngineStartup(IAGSEngine *engine) {
40 PluginBase::AGS_EngineStartup(engine);
41
42 if (_engine->version < 13)
43 _engine->AbortGame("Engine interface is too old, need newer version of AGS.");
44
45 SCRIPT_METHOD(pxDrawSprite, AGSParallax::pxDrawSprite);
46 SCRIPT_METHOD(pxDeleteSprite, AGSParallax::pxDeleteSprite);
47
48 _engine->RequestEventHook(AGSE_PREGUIDRAW);
49 _engine->RequestEventHook(AGSE_PRESCREENDRAW);
50 _engine->RequestEventHook(AGSE_ENTERROOM);
51 _engine->RequestEventHook(AGSE_SAVEGAME);
52 _engine->RequestEventHook(AGSE_RESTOREGAME);
53 }
54
AGS_EngineOnEvent(int event,NumberPtr data)55 int64 AGSParallax::AGS_EngineOnEvent(int event, NumberPtr data) {
56 if (event == AGSE_PREGUIDRAW) {
57 Draw(true);
58 } else if (event == AGSE_PRESCREENDRAW) {
59 // Get screen size and then draw
60 _engine->GetScreenDimensions(&_screenWidth, &_screenHeight, &_screenColorDepth);
61 Draw(false);
62 } else if (event == AGSE_ENTERROOM) {
63 // Reset all _sprites
64 clear();
65 } else if (event == AGSE_RESTOREGAME) {
66 Serializer s(_engine, data, true);
67 syncGame(s);
68 } else if (event == AGSE_SAVEGAME) {
69 Serializer s(_engine, data, false);
70 syncGame(s);
71 }
72
73 return 0;
74 }
75
clear()76 void AGSParallax::clear() {
77 for (int i = 0; i < MAX_SPRITES; i++) {
78 _sprites[i] = Sprite();
79 _sprites[i].slot = -1;
80 }
81
82 _enabled = false;
83 }
84
syncGame(Serializer & s)85 void AGSParallax::syncGame(Serializer &s) {
86 int saveVersion = SaveMagic;
87 s.syncAsInt(saveVersion);
88 if ((uint)saveVersion != SaveMagic) {
89 _engine->AbortGame("ags_parallax: bad save.");
90 return;
91 }
92
93 for (int i = 0; i < MAX_SPRITES; ++i)
94 _sprites[i].syncGame(s);
95 s.syncAsBool(_enabled);
96 }
97
Draw(bool foreground)98 void AGSParallax::Draw(bool foreground) {
99 if (!_enabled)
100 return;
101
102 BITMAP *bmp;
103 int i;
104
105 int32 offsetX = 0;
106 int32 offsetY = 0;
107 _engine->ViewportToRoom(&offsetX, &offsetY);
108
109 for (i = 0; i < MAX_SPRITES; i++) {
110 if (_sprites[i].slot > -1) {
111 if (foreground) {
112 if (_sprites[i].speed > 0) {
113 bmp = _engine->GetSpriteGraphic(_sprites[i].slot);
114 if (bmp)
115 _engine->BlitBitmap(_sprites[i].x - offsetX - (_sprites[i].speed * offsetX / 100), _sprites[i].y, bmp, 1);
116 }
117 } else {
118 if (_sprites[i].speed <= 0) {
119 bmp = _engine->GetSpriteGraphic(_sprites[i].slot);
120 if (bmp)
121 _engine->BlitBitmap(_sprites[i].x - offsetX - (_sprites[i].speed * offsetX / 1000), _sprites[i].y, bmp, 1);
122 }
123 }
124 }
125 }
126 }
127
pxDrawSprite(ScriptMethodParams & params)128 void AGSParallax::pxDrawSprite(ScriptMethodParams ¶ms) {
129 PARAMS5(int, id, int, x, int, y, int, slot, int, speed);
130
131 if ((id < 0) || (id >= MAX_SPRITES))
132 return;
133
134 if ((speed < -MAX_SPEED) || (speed > MAX_SPEED))
135 speed = 0;
136
137 _sprites[id].x = x;
138 _sprites[id].y = y;
139 _sprites[id].slot = slot;
140 _sprites[id].speed = speed;
141
142 _engine->RoomToViewport(&_sprites[id].x, &_sprites[id].y);
143
144 _enabled = true;
145 }
146
147
pxDeleteSprite(ScriptMethodParams & params)148 void AGSParallax::pxDeleteSprite(ScriptMethodParams ¶ms) {
149 PARAMS1(int, id);
150
151 if ((id < 0) || (id >= MAX_SPRITES))
152 return;
153
154 _sprites[id].slot = -1;
155 }
156
157 /*------------------------------------------------------------------*/
158
syncGame(Serializer & s)159 void Sprite::syncGame(Serializer &s) {
160 s.syncAsInt(x);
161 s.syncAsInt(y);
162 s.syncAsInt(slot);
163 s.syncAsInt(speed);
164 }
165
166 } // namespace AGSParallax
167 } // namespace Plugins
168 } // namespace AGS3
169