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 "agos/agos.h"
24 #include "agos/intern.h"
25 #include "agos/vga.h"
26 
27 #include "common/system.h"
28 
29 #include "graphics/surface.h"
30 
31 namespace AGOS {
32 
setupVideoOpcodes(VgaOpcodeProc * op)33 void AGOSEngine_PN::setupVideoOpcodes(VgaOpcodeProc *op) {
34 	op[1] = &AGOSEngine::vc1_fadeOut;
35 	op[2] = &AGOSEngine::vc2_call;
36 	op[3] = &AGOSEngine::vc3_loadSprite;
37 	op[4] = &AGOSEngine::vc4_fadeIn;
38 	op[5] = &AGOSEngine::vc5_ifEqual;
39 	op[6] = &AGOSEngine::vc6_ifObjectHere;
40 	op[7] = &AGOSEngine::vc7_ifObjectNotHere;
41 	op[8] = &AGOSEngine::vc8_ifObjectIsAt;
42 	op[9] = &AGOSEngine::vc9_ifObjectStateIs;
43 	op[10] = &AGOSEngine::vc10_draw;
44 	op[11] = &AGOSEngine::vc11_onStop;
45 	op[13] = &AGOSEngine::vc12_delay;
46 	op[14] = &AGOSEngine::vc13_addToSpriteX;
47 	op[15] = &AGOSEngine::vc14_addToSpriteY;
48 	op[16] = &AGOSEngine::vc15_sync;
49 	op[17] = &AGOSEngine::vc16_waitSync;
50 	op[18] = &AGOSEngine::vc17_waitEnd;
51 	op[19] = &AGOSEngine::vc18_jump;
52 	op[20] = &AGOSEngine::vc19_loop;
53 	op[21] = &AGOSEngine::vc20_setRepeat;
54 	op[22] = &AGOSEngine::vc21_endRepeat;
55 	op[23] = &AGOSEngine::vc22_setPalette;
56 	op[24] = &AGOSEngine::vc23_setPriority;
57 	op[25] = &AGOSEngine::vc24_setSpriteXY;
58 	op[26] = &AGOSEngine::vc25_halt_sprite;
59 	op[27] = &AGOSEngine::vc26_setSubWindow;
60 	op[28] = &AGOSEngine::vc27_resetSprite;
61 	op[29] = &AGOSEngine::vc28_playSFX;
62 	op[30] = &AGOSEngine::vc29_stopAllSounds;
63 	op[31] = &AGOSEngine::vc30_setFrameRate;
64 	op[32] = &AGOSEngine::vc31_setWindow;
65 	op[33] = &AGOSEngine::vc32_saveScreen;
66 	op[34] = &AGOSEngine::vc33_setMouseOn;
67 	op[35] = &AGOSEngine::vc34_setMouseOff;
68 	op[36] = &AGOSEngine::vc36_pause;
69 	op[38] = &AGOSEngine::vc35_clearWindow;
70 	op[39] = &AGOSEngine::vc39_volume;
71 	op[40] = &AGOSEngine::vc36_setWindowImage;
72 	op[41] = &AGOSEngine::vc37_pokePalette;
73 	op[44] = &AGOSEngine::vc44_enableBox;
74 	op[45] = &AGOSEngine::vc45_disableBox;
75 	op[46] = &AGOSEngine::vc46_maxBox;
76 	op[48] = &AGOSEngine::vc48_specialEffect;
77 	op[50] = &AGOSEngine::vc50_setBox;
78 	op[51] = &AGOSEngine::vc38_ifVarNotZero;
79 	op[52] = &AGOSEngine::vc39_setVar;
80 	op[53] = &AGOSEngine::vc40_scrollRight;
81 	op[54] = &AGOSEngine::vc41_scrollLeft;
82 	op[55] = &AGOSEngine::vc55_scanFlag;
83 }
84 
ifObjectHere(uint16 a)85 bool AGOSEngine_PN::ifObjectHere(uint16 a) {
86 	if (getFeatures() & GF_DEMO)
87 		return false;
88 
89 	return _variableArray[39] == getptr(_quickptr[11] + a * _quickshort[4] + 2);
90 }
91 
ifObjectAt(uint16 a,uint16 b)92 bool AGOSEngine_PN::ifObjectAt(uint16 a, uint16 b) {
93 	if (getFeatures() & GF_DEMO)
94 		return false;
95 
96 	return b == getptr(_quickptr[11] + a * _quickshort[4] + 2);
97 }
98 
ifObjectState(uint16 a,int16 b)99 bool AGOSEngine_PN::ifObjectState(uint16 a, int16 b) {
100 	if (getFeatures() & GF_DEMO)
101 		return false;
102 
103 	return b == getptr(_quickptr[0] + a * _quickshort[0] + 2);
104 }
105 
vc36_pause()106 void AGOSEngine::vc36_pause() {
107 	const char *message1 = "Press any key to continue";
108 	bool oldWiped = _wiped;
109 	_wiped = 0;
110 
111 	_videoLockOut |= 8;
112 
113 	windowPutChar(_windowArray[2], 13);
114 
115 	for (; *message1; message1++)
116 		windowPutChar(_windowArray[2], *message1);
117 
118 	while (!shouldQuit()) {
119 		if (_keyPressed.ascii != 0)
120 			break;
121 		delay(1);
122 	}
123 
124 	_keyPressed.reset();
125 
126 	windowPutChar(_windowArray[2], 13);
127 	_wiped = oldWiped;
128 
129 	_videoLockOut &= ~8;
130 }
131 
vc39_volume()132 void AGOSEngine::vc39_volume() {
133 	_vcPtr += 2;
134 }
135 
vc44_enableBox()136 void AGOSEngine::vc44_enableBox() {
137 	HitArea *ha = _hitAreas + vcReadNextWord();
138 	ha->flags &= ~kOBFBoxDisabled;
139 }
140 
vc45_disableBox()141 void AGOSEngine::vc45_disableBox() {
142 	HitArea *ha = _hitAreas + vcReadNextWord();
143 	ha->flags |= kOBFBoxDisabled;
144 }
145 
vc46_maxBox()146 void AGOSEngine::vc46_maxBox() {
147 	HitArea *ha = _hitAreas + vcReadNextWord();
148 	ha->id = 0xFFFF;
149 }
150 
vc48_specialEffect()151 void AGOSEngine::vc48_specialEffect() {
152 	uint16 num = vcReadNextWord();
153 	vcReadNextWord();
154 
155 	if (getPlatform() == Common::kPlatformDOS) {
156 		if (num == 1) {
157 			Graphics::Surface *screen = _system->lockScreen();
158 			byte *dst = (byte *)screen->getPixels();
159 
160 			for (uint h = 0; h < _screenHeight; h++) {
161 				for (uint w = 0; w < _screenWidth; w++) {
162 					if (dst[w] == 15)
163 						dst[w] = 4;
164 				}
165 				dst += screen->pitch;
166 			}
167 			_system->unlockScreen();
168 		} else if (num == 2) {
169 			const char *str = "There are gurgling noises from the sink.";
170 			for (; *str; str++)
171 				windowPutChar(_textWindow, *str);
172 		}
173 	}
174 }
175 
vc50_setBox()176 void AGOSEngine::vc50_setBox() {
177 	uint16 id, x, y, w, h, msg1, msg2, flags;
178 	const uint16 *vlut;
179 
180 	id = vcReadNextWord();
181 	vlut = &_videoWindows[vcReadNextWord() * 4];
182 	x = vlut[0] * 16 + vcReadNextWord();
183 	y = vlut[1] + vcReadNextWord();
184 	h = vcReadNextWord();
185 	w = vcReadNextWord();
186 	msg1 = vcReadNextWord();
187 	msg2 = vcReadNextWord();
188 	flags = vcReadNextWord();
189 
190 	// Compressed string
191 	if (!(flags & kOBFUseMessageList)) {
192 		msg1 += 0x8000;
193 	}
194 
195 	defineBox(id, x, y, h, w, msg1, msg2, flags);
196 }
197 
vc55_scanFlag()198 void AGOSEngine::vc55_scanFlag() {
199 	_scanFlag = 1;
200 }
201 
clearVideoWindow(uint16 num,uint16 color)202 void AGOSEngine_PN::clearVideoWindow(uint16 num, uint16 color) {
203 	const uint16 *vlut = &_videoWindows[num * 4];
204 	uint16 xoffs = vlut[0] * 16;
205 	uint16 yoffs = vlut[1];
206 
207 	Graphics::Surface *screen = _system->lockScreen();
208 	byte *dst = (byte *)screen->getBasePtr(xoffs, yoffs);
209 	for (uint h = 0; h < vlut[3]; h++) {
210 		memset(dst, color, vlut[2] * 16);
211 		dst += screen->pitch;
212 	}
213 	 _system->unlockScreen();
214 }
215 
216 } // End of namespace AGOS
217