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 // Video script opcodes for Simon1/Simon2
24 
25 
26 #include "agos/agos.h"
27 #include "agos/intern.h"
28 
29 #include "common/system.h"
30 
31 #include "graphics/surface.h"
32 #include "graphics/palette.h"
33 
34 namespace AGOS {
35 
setupVideoOpcodes(VgaOpcodeProc * op)36 void AGOSEngine_Waxworks::setupVideoOpcodes(VgaOpcodeProc *op) {
37 	AGOSEngine_Elvira2::setupVideoOpcodes(op);
38 
39 	op[58] = &AGOSEngine::vc58_checkCodeWheel;
40 	op[60] = &AGOSEngine::vc60_stopAnimation;
41 	op[61] = &AGOSEngine::vc61;
42 	op[62] = &AGOSEngine::vc62_fastFadeOut;
43 	op[63] = &AGOSEngine::vc63_fastFadeIn;
44 }
45 
vcStopAnimation(uint16 zone,uint16 sprite)46 void AGOSEngine::vcStopAnimation(uint16 zone, uint16 sprite) {
47 	uint16 oldCurSpriteId, oldCurZoneNum;
48 	VgaSprite *vsp;
49 	VgaTimerEntry *vte;
50 	const byte *vcPtrOrg;
51 
52 	oldCurSpriteId = _vgaCurSpriteId;
53 	oldCurZoneNum = _vgaCurZoneNum;
54 	vcPtrOrg = _vcPtr;
55 
56 	_vgaCurZoneNum = zone;
57 	_vgaCurSpriteId = sprite;
58 
59 	vsp = findCurSprite();
60 	if (vsp->id) {
61 		vc25_halt_sprite();
62 
63 		vte = _vgaTimerList;
64 		while (vte->delay) {
65 			if (vte->id == _vgaCurSpriteId && vte->zoneNum == _vgaCurZoneNum) {
66 				deleteVgaEvent(vte);
67 				break;
68 			}
69 			vte++;
70 		}
71 	}
72 
73 	_vgaCurZoneNum = oldCurZoneNum;
74 	_vgaCurSpriteId = oldCurSpriteId;
75 	_vcPtr = vcPtrOrg;
76 }
77 
vcStopAnimation(uint16 zone,uint16 sprite)78 void AGOSEngine_Simon1::vcStopAnimation(uint16 zone, uint16 sprite) {
79 	uint16 oldCurSpriteId, oldCurZoneNum;
80 	VgaSleepStruct *vfs;
81 	VgaSprite *vsp;
82 	VgaTimerEntry *vte;
83 	const byte *vcPtrOrg;
84 
85 	oldCurSpriteId = _vgaCurSpriteId;
86 	oldCurZoneNum = _vgaCurZoneNum;
87 	vcPtrOrg = _vcPtr;
88 
89 	_vgaCurZoneNum = zone;
90 	_vgaCurSpriteId = sprite;
91 
92 	vfs = _waitSyncTable;
93 	while (vfs->ident != 0) {
94 		if (vfs->id == _vgaCurSpriteId && vfs->zoneNum == _vgaCurZoneNum) {
95 			while (vfs->ident != 0) {
96 				memcpy(vfs, vfs + 1, sizeof(VgaSleepStruct));
97 				vfs++;
98 			}
99 			break;
100 		}
101 		vfs++;
102 	}
103 
104 	vsp = findCurSprite();
105 	if (vsp->id) {
106 		vc25_halt_sprite();
107 
108 		vte = _vgaTimerList;
109 		while (vte->delay) {
110 			if (vte->id == _vgaCurSpriteId && vte->zoneNum == _vgaCurZoneNum) {
111 				deleteVgaEvent(vte);
112 				break;
113 			}
114 			vte++;
115 		}
116 	}
117 
118 	_vgaCurZoneNum = oldCurZoneNum;
119 	_vgaCurSpriteId = oldCurSpriteId;
120 	_vcPtr = vcPtrOrg;
121 }
122 
vc60_stopAnimation()123 void AGOSEngine::vc60_stopAnimation() {
124 	uint16 sprite, zoneNum;
125 
126 	if (getGameType() == GType_PP) {
127 		zoneNum = vcReadNextWord();
128 		sprite = vcReadVarOrWord();
129 	} else if (getGameType() == GType_SIMON2 || getGameType() == GType_FF) {
130 		zoneNum = vcReadNextWord();
131 		sprite = vcReadNextWord();
132 	} else {
133 		sprite = vcReadNextWord();
134 		zoneNum = sprite / 100;
135 	}
136 
137 	vcStopAnimation(zoneNum, sprite);
138 }
139 
vc61()140 void AGOSEngine::vc61() {
141 	uint16 a = vcReadNextWord();
142 	byte *src, *dst, *dstPtr;
143 	uint h, tmp;
144 
145 	Graphics::Surface *screen = _system->lockScreen();
146 	dstPtr = (byte *)screen->getPixels();
147 
148 	if (a == 6) {
149 		src = _curVgaFile2 + 800;
150 		dst = dstPtr;
151 
152 		for (int i = 0; i < _screenHeight; i++) {
153 			memcpy(dst, src, _screenWidth);
154 			src += 320;
155 			dst += screen->pitch;
156 		}
157 
158 		tmp = 4 - 1;
159 	} else {
160 		tmp = a - 1;
161 	}
162 
163 	src = _curVgaFile2 + 3840 * 16 + 3360;
164 	while (tmp--)
165 		src += 1536 * 16 + 1712;
166 
167 	src += 800;
168 
169 	if (a != 5) {
170 		dst = dstPtr + 23 * screen->pitch + 88;
171 		for (h = 0; h < 177; h++) {
172 			memcpy(dst, src, 144);
173 			src += 144;
174 			dst += screen->pitch;
175 		}
176 
177 		if (a != 6) {
178 			_system->unlockScreen();
179 			return;
180 		}
181 
182 		src = _curVgaFile2 + 9984 * 16 + 15344;
183 	}
184 
185 	dst = dstPtr + 157 * screen->pitch + 56;
186 	for (h = 0; h < 17; h++) {
187 		memcpy(dst, src, 208);
188 		src += 208;
189 		dst += screen->pitch;
190 	}
191 
192 	_system->unlockScreen();
193 
194 	if (a == 6)
195 		fullFade();
196 }
197 
vc62_fastFadeOut()198 void AGOSEngine::vc62_fastFadeOut() {
199 	vc29_stopAllSounds();
200 
201 	if (!_fastFadeOutFlag) {
202 		uint i, fadeSize, fadeCount;
203 
204 		_fastFadeCount = 256;
205 		if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
206 			if (_windowNum == 4)
207 				_fastFadeCount = 208;
208 		}
209 
210 		if (getGameType() == GType_FF || getGameType() == GType_PP) {
211 			if (getGameType() == GType_FF && getBitFlag(75)) {
212 				fadeCount = 4;
213 				fadeSize = 64;
214 			} else {
215 				fadeCount = 32;
216 				fadeSize = 8;
217 			}
218 		} else {
219 			fadeCount = 64;
220 			fadeSize = 4;
221 		}
222 
223 		for (i = fadeCount; i != 0; --i) {
224 			paletteFadeOut(_currentPalette, _fastFadeCount, fadeSize);
225 			_system->getPaletteManager()->setPalette(_currentPalette, 0, _fastFadeCount);
226 			delay(5);
227 		}
228 
229 		if (getGameType() == GType_WW || getGameType() == GType_FF || getGameType() == GType_PP) {
230 			clearSurfaces();
231 		} else {
232 			if (_windowNum != 4) {
233 				clearSurfaces();
234 			}
235 		}
236 	}
237 	if (getGameType() == GType_SIMON2) {
238 		if (_nextMusicToPlay != -1)
239 			loadMusic(_nextMusicToPlay);
240 	}
241 }
242 
vc63_fastFadeIn()243 void AGOSEngine::vc63_fastFadeIn() {
244 	if (getGameType() == GType_FF) {
245 		_fastFadeInFlag = 256;
246 	} else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
247 		_fastFadeInFlag = 208;
248 		if (_windowNum != 4) {
249 			_fastFadeInFlag = 256;
250 		}
251 	}
252 	_fastFadeOutFlag = false;
253 }
254 
255 } // End of namespace AGOS
256