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 "scumm/he/intern_he.h"
24 #include "scumm/he/moonbase/moonbase.h"
25 #include "scumm/he/moonbase/ai_main.h"
26 #ifdef USE_SDL_NET
27 #include "scumm/he/moonbase/net_main.h"
28 #endif
29
30 namespace Scumm {
31
Moonbase(ScummEngine_v100he * vm)32 Moonbase::Moonbase(ScummEngine_v100he *vm) : _vm(vm) {
33 initFOW();
34
35 _ai = new AI(_vm);
36 #ifdef USE_SDL_NET
37 _net = new Net(_vm);
38 #endif
39 }
40
~Moonbase()41 Moonbase::~Moonbase() {
42 delete _ai;
43 #ifdef USE_SDL_NET
44 delete _net;
45 #endif
46 }
47
readFromArray(int array,int y,int x)48 int Moonbase::readFromArray(int array, int y, int x) {
49 _vm->VAR(_vm->VAR_U32_ARRAY_UNK) = array;
50
51 return _vm->readArray(_vm->VAR_U32_ARRAY_UNK, y, x);
52 }
53
deallocateArray(int array)54 void Moonbase::deallocateArray(int array) {
55 _vm->VAR(_vm->VAR_U32_ARRAY_UNK) = array;
56
57 return _vm->nukeArray(_vm->VAR_U32_ARRAY_UNK);
58 }
59
callScummFunction(int scriptNumber,int paramCount,...)60 int Moonbase::callScummFunction(int scriptNumber, int paramCount,...) {
61 va_list va_params;
62 va_start(va_params, paramCount);
63 int args[25];
64
65 memset(args, 0, sizeof(args));
66
67 Common::String str;
68 str = Common::String::format("callScummFunction(%d, [", scriptNumber);
69
70 for (int i = 0; i < paramCount; i++) {
71 args[i] = va_arg(va_params, int);
72
73 str += Common::String::format("%d ", args[i]);
74 }
75 str += "])";
76
77 debug(0, "%s", str.c_str());
78
79
80 va_end(va_params);
81
82 _vm->runScript(scriptNumber, 0, 1, args);
83
84 return _vm->pop();
85 }
86
87
blitT14WizImage(uint8 * dst,int dstw,int dsth,int dstPitch,const Common::Rect * clipBox,uint8 * wizd,int x,int y,int rawROP,int paramROP)88 void Moonbase::blitT14WizImage(uint8 *dst, int dstw, int dsth, int dstPitch, const Common::Rect *clipBox,
89 uint8 *wizd, int x, int y, int rawROP, int paramROP) {
90 bool premulAlpa = false;
91
92 if (rawROP == 1)
93 premulAlpa = true;
94
95 Common::Rect clippedDstRect(dstw, dsth);
96 if (clipBox) {
97 Common::Rect clip(clipBox->left, clipBox->top, clipBox->right, clipBox->bottom);
98 if (clippedDstRect.intersects(clip)) {
99 clippedDstRect.clip(clip);
100 } else {
101 return;
102 }
103 }
104
105 int width = READ_LE_UINT16(wizd + 0x8 + 0);
106 int height = READ_LE_UINT16(wizd + 0x8 + 2);
107
108 Common::Rect srcLimitsRect(width, height);
109 Common::Rect dstOperation(x, y, x + width, y + height);
110 if (!clippedDstRect.intersects(dstOperation))
111 return;
112 Common::Rect clippedRect = clippedDstRect.findIntersectingRect(dstOperation);
113
114 int cx = clippedRect.right - clippedRect.left;
115 int cy = clippedRect.bottom - clippedRect.top;
116
117 int sx = ((clippedRect.left - x) + srcLimitsRect.left);
118 int sy = ((clippedRect.top - y) + srcLimitsRect.top);
119
120 dst += clippedRect.top * dstPitch + clippedRect.left * 2;
121
122 int headerSize = READ_LE_UINT32(wizd + 0x4);
123 uint8 *dataPointer = wizd + 0x8 + headerSize;
124
125 for (int i = 0; i < sy; i++) {
126 uint16 lineSize = READ_LE_UINT16(dataPointer + 0);
127
128 dataPointer += lineSize;
129 }
130
131 for (int i = 0; i < cy; i++) {
132 uint16 lineSize = READ_LE_UINT16(dataPointer + 0);
133 uint8 *singlesOffset = READ_LE_UINT16(dataPointer + 2) + dataPointer;
134 uint8 *quadsOffset = READ_LE_UINT16(dataPointer + 4) + dataPointer;
135
136 int pixels = 0;
137 byte *dst1 = dst;
138 byte *codes = dataPointer + 6;
139
140 while (1) {
141 int code = *codes - 2;
142 codes++;
143
144 if (code <= 0) { // quad or single
145 uint8 *src;
146 int cnt;
147 if (code == 0) { // quad
148 src = quadsOffset;
149 quadsOffset += 8;
150 cnt = 4; // 4 pixels
151 } else { // single
152 src = singlesOffset;
153 singlesOffset += 2;
154 cnt = 1;
155 }
156
157 for (int c = 0; c < cnt; c++) {
158 if (pixels >= sx) {
159 if (rawROP == 1) { // MMX_PREMUL_ALPHA_COPY
160 WRITE_LE_UINT16(dst1, READ_LE_UINT16(src));
161 } else if (rawROP == 2) { // MMX_ADDITIVE
162 uint16 color = READ_LE_UINT16(src);
163 uint16 orig = READ_LE_UINT16(dst1);
164
165 uint32 r = MIN<uint32>(0x7c00, (orig & 0x7c00) + (color & 0x7c00));
166 uint32 g = MIN<uint32>(0x03e0, (orig & 0x03e0) + (color & 0x03e0));
167 uint32 b = MIN<uint32>(0x001f, (orig & 0x001f) + (color & 0x001f));
168 WRITE_LE_UINT16(dst1, (r | g | b));
169 } else if (rawROP == 5) { // MMX_CHEAP_50_50
170 uint16 color = (READ_LE_UINT16(src) >> 1) & 0x3DEF;
171 uint16 orig = (READ_LE_UINT16(dst1) >> 1) & 0x3DEF;
172 WRITE_LE_UINT16(dst1, (color + orig));
173 }
174 dst1 += 2;
175 }
176 src += 2;
177 pixels++;
178 if (pixels >= cx + sx)
179 break;
180 }
181 } else { // skip
182 if ((code & 1) == 0) {
183 code >>= 1;
184
185 for (int j = 0; j < code; j++) {
186 if (pixels >= sx)
187 dst1 += 2;
188 pixels++;
189 if (pixels >= cx + sx)
190 break;
191 }
192 } else { // special case
193 if (pixels >= sx) {
194 int alpha = code >> 1;
195 uint16 color = READ_LE_UINT16(singlesOffset);
196 uint32 orig = READ_LE_UINT16(dst1);
197
198 if (!premulAlpa) {
199 WRITE_LE_UINT16(dst1, color); // ENABLE_PREMUL_ALPHA = 0
200 } else {
201 if (alpha > 32) {
202 alpha -= 32;
203
204 uint32 oR = orig & 0x7c00;
205 uint32 oG = orig & 0x03e0;
206 uint32 oB = orig & 0x1f;
207 uint32 dR = ((((color & 0x7c00) - oR) * alpha) >> 5) + oR;
208 uint32 dG = ((((color & 0x3e0) - oG) * alpha) >> 5) + oG;
209 uint32 dB = ((((color & 0x1f) - oB) * alpha) >> 5) + oB;
210
211 WRITE_LE_UINT16(dst1, (dR & 0x7c00) | (dG & 0x3e0) | (dB & 0x1f));
212 } else {
213 uint32 pix = ((orig << 16) | orig) & 0x3e07c1f;
214 pix = (((pix * alpha) & 0xffffffff) >> 5) & 0x3e07c1f;
215 pix = ((pix >> 16) + pix + color) & 0xffff;
216 WRITE_LE_UINT16(dst1, pix);
217 }
218 }
219
220 dst1 += 2;
221 }
222 singlesOffset += 2;
223 pixels++;
224 }
225 }
226
227 if (pixels >= cx + sx)
228 break;
229 }
230
231 dataPointer += lineSize;
232 dst += dstPitch;
233 }
234 }
235
236 } // End of namespace Scumm
237