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 "cruise/cruise_main.h"
24 #include "common/file.h"
25 #include "cruise/cell.h"
26
27 namespace Cruise {
28
29 cellStruct cellHead;
30
resetPtr(cellStruct * ptr)31 void resetPtr(cellStruct *ptr) {
32 ptr->next = NULL;
33 ptr->prev = NULL;
34 }
35
freeMessageList(cellStruct * objPtr)36 void freeMessageList(cellStruct *objPtr) {
37 /* if (objPtr) {
38 if (objPtr->next)
39 MemFree(objPtr->next);
40
41 MemFree(objPtr);
42 } */
43 }
44
addCell(cellStruct * pHead,int16 overlayIdx,int16 objIdx,int16 type,int16 backgroundPlane,int16 scriptOverlay,int16 scriptNumber,int16 scriptType)45 cellStruct *addCell(cellStruct *pHead, int16 overlayIdx, int16 objIdx, int16 type, int16 backgroundPlane, int16 scriptOverlay, int16 scriptNumber, int16 scriptType) {
46 int16 var;
47
48 cellStruct *newElement;
49 cellStruct *currentHead = pHead;
50 cellStruct *currentHead2;
51 cellStruct *currentHead3;
52
53 if (getSingleObjectParam(overlayIdx, objIdx, 2, &var) < 0) {
54 return 0;
55 }
56
57 currentHead3 = currentHead;
58 currentHead2 = currentHead->next;
59
60 while (currentHead2 && (currentHead2->type != 3)) {
61
62 if (currentHead2->type != 5) {
63 int16 lvar2;
64
65 if (getSingleObjectParam(currentHead2->overlay, currentHead2->idx, 2, &lvar2) >= 0 && lvar2 >= var)
66 break;
67 }
68
69 currentHead3 = currentHead2;
70 currentHead2 = currentHead2->next;
71 }
72
73 if (currentHead2) {
74 if ((currentHead2->overlay == overlayIdx) &&
75 (currentHead2->backgroundPlane == backgroundPlane) &&
76 (currentHead2->idx == objIdx) &&
77 (currentHead2->type == type))
78
79 return NULL;
80 }
81
82 currentHead = currentHead2;
83
84 newElement = (cellStruct *) mallocAndZero(sizeof(cellStruct));
85
86 if (!newElement)
87 return 0;
88
89 newElement->next = currentHead3->next;
90 currentHead3->next = newElement;
91
92 newElement->idx = objIdx;
93 newElement->type = type;
94 newElement->backgroundPlane = backgroundPlane;
95 newElement->overlay = overlayIdx;
96 newElement->freeze = 0;
97 newElement->parent = scriptNumber;
98 newElement->parentOverlay = scriptOverlay;
99 newElement->gfxPtr = NULL;
100 newElement->followObjectIdx = objIdx;
101 newElement->followObjectOverlayIdx = overlayIdx;
102 newElement->parentType = scriptType;
103
104 newElement->animStart = 0;
105 newElement->animEnd = 0;
106 newElement->animWait = 0;
107 newElement->animSignal = 0;
108 newElement->animCounter = 0;
109 newElement->animType = 0;
110 newElement->animStep = 0;
111 newElement->animLoop = 0;
112
113 if (currentHead) {
114 newElement->prev = currentHead->prev;
115 currentHead->prev = newElement;
116 } else {
117 newElement->prev = pHead->prev;
118 pHead->prev = newElement;
119 }
120
121 return newElement;
122 }
123
createTextObject(cellStruct * pObject,int overlayIdx,int messageIdx,int x,int y,int width,int16 color,int backgroundPlane,int parentOvl,int parentIdx)124 void createTextObject(cellStruct *pObject, int overlayIdx, int messageIdx, int x, int y, int width, int16 color, int backgroundPlane, int parentOvl, int parentIdx) {
125
126 const char *ax;
127 cellStruct *savePObject = pObject;
128 cellStruct *cx;
129
130 cellStruct *pNewElement;
131 cellStruct *si = pObject->next;
132
133 while (si) {
134 pObject = si;
135 si = si->next;
136 }
137
138 pNewElement = (cellStruct *) MemAlloc(sizeof(cellStruct));
139 memset(pNewElement, 0, sizeof(cellStruct));
140
141 pNewElement->next = pObject->next;
142 pObject->next = pNewElement;
143
144 pNewElement->idx = messageIdx;
145 pNewElement->type = OBJ_TYPE_MESSAGE;
146 pNewElement->backgroundPlane = backgroundPlane;
147 pNewElement->overlay = overlayIdx;
148 pNewElement->x = x;
149 pNewElement->field_C = y;
150 pNewElement->spriteIdx = width;
151 pNewElement->color = color;
152 pNewElement->freeze = 0;
153 pNewElement->parent = parentIdx;
154 pNewElement->parentOverlay = parentOvl;
155 pNewElement->gfxPtr = NULL;
156
157 cx = savePObject;
158
159 pNewElement->prev = cx->prev;
160 cx->prev = pNewElement;
161
162 ax = getText(messageIdx, overlayIdx);
163
164 if (ax) {
165 pNewElement->gfxPtr = renderText(width, ax);
166 }
167
168 // WORKAROUND: This is needed for the new dirty rect handling so as to properly refresh the screen
169 // when the copy protection screen is being shown
170 if ((messageIdx == 0) && !strcmp(overlayTable[overlayIdx].overlayName, "XX2"))
171 backgroundChanged[0] = true;
172 }
173
removeCell(cellStruct * objPtr,int ovlNumber,int objectIdx,int objType,int backgroundPlane)174 void removeCell(cellStruct *objPtr, int ovlNumber, int objectIdx, int objType, int backgroundPlane) {
175 cellStruct *currentObj = objPtr->next;
176 cellStruct *previous;
177
178 while (currentObj) {
179 if (((currentObj->overlay == ovlNumber) || (ovlNumber == -1)) &&
180 ((currentObj->idx == objectIdx) || (objectIdx == -1)) &&
181 ((currentObj->type == objType) || (objType == -1)) &&
182 ((currentObj->backgroundPlane == backgroundPlane) || (backgroundPlane == -1))) {
183 currentObj->type = -1;
184 }
185
186 currentObj = currentObj->next;
187 }
188
189 previous = objPtr;
190 currentObj = objPtr->next;
191
192 while (currentObj) {
193 cellStruct *si;
194
195 si = currentObj;
196
197 if (si->type == -1) {
198 cellStruct *dx;
199 previous->next = si->next;
200
201 dx = si->next;
202
203 if (!si->next) {
204 dx = objPtr;
205 }
206
207 dx->prev = si->prev;
208
209 // Free the entry
210 if (si->gfxPtr)
211 freeGfx(si->gfxPtr);
212 MemFree(si);
213
214 currentObj = dx;
215 } else {
216 currentObj = si->next;
217 previous = si;
218 }
219 }
220 }
221
linkCell(cellStruct * pHead,int ovl,int obj,int type,int ovl2,int obj2)222 void linkCell(cellStruct *pHead, int ovl, int obj, int type, int ovl2, int obj2) {
223 while (pHead) {
224 if ((pHead->overlay == ovl) || (ovl == -1)) {
225 if ((pHead->idx == obj) || (obj == -1)) {
226 if ((pHead->type == type) || (type == -1)) {
227 pHead->followObjectIdx = obj2;
228 pHead->followObjectOverlayIdx = ovl2;
229 }
230 }
231 }
232
233 pHead = pHead->next;
234 }
235 }
236
freezeCell(cellStruct * pObject,int overlayIdx,int objIdx,int objType,int backgroundPlane,int oldFreeze,int newFreeze)237 void freezeCell(cellStruct * pObject, int overlayIdx, int objIdx, int objType, int backgroundPlane, int oldFreeze, int newFreeze) {
238 while (pObject) {
239 if ((pObject->overlay == overlayIdx) || (overlayIdx == -1)) {
240 if ((pObject->idx == objIdx) || (objIdx == -1)) {
241 if ((pObject->type == objType) || (objType == -1)) {
242 if ((pObject->backgroundPlane == backgroundPlane) || (backgroundPlane == -1)) {
243 if ((pObject->freeze == oldFreeze) || (oldFreeze == -1)) {
244 pObject->freeze = newFreeze;
245 }
246 }
247 }
248 }
249 }
250
251 pObject = pObject->next;
252 }
253 }
254
sortCells(int16 ovlIdx,int16 ovjIdx,cellStruct * objPtr)255 void sortCells(int16 ovlIdx, int16 ovjIdx, cellStruct *objPtr) {
256 cellStruct *pl, *pl2, *pl3, *pl4, *plz, *pllast;
257 cellStruct prov;
258 int16 newz, objz, sobjz;
259
260 pl4 = NULL;
261
262 getSingleObjectParam(ovlIdx, ovjIdx, 2, &sobjz);
263 pl = objPtr;
264 prov.next = NULL;
265 prov.prev = NULL;
266
267 pl2 = pl->next;
268 pllast = NULL;
269 plz = objPtr;
270
271 while (pl2) {
272 pl3 = pl2->next;
273 if ((pl2->overlay == ovlIdx) && (pl2->idx == ovjIdx)) {// found
274 pl->next = pl3;
275
276 if (pl3) {
277 pl3->prev = pl2->prev;
278 } else {
279 objPtr->prev = pl2->prev;
280 }
281
282 pl4 = prov.next;
283
284 if (pl4) {
285 pl4->prev = pl2;
286 } else {
287 prov.prev = pl2;
288 }
289
290 pl2->prev = NULL;
291 pl2->next = prov.next;
292 prov.next = pl2;
293
294 if (pllast == NULL) {
295 pllast = pl2;
296 }
297 } else {
298 if (pl2->type == 5) {
299 newz = 32000;
300 } else {
301 getSingleObjectParam(pl2->overlay, pl2->idx, 2, &objz);
302 newz = objz;
303 }
304
305 if (newz < sobjz) {
306 plz = pl2;
307 }
308
309 pl = pl->next;
310 }
311
312 pl2 = pl3;
313 }
314
315 if (pllast) {
316 pl2 = prov.next;
317 pl4 = plz->next;
318 plz->next = pl2;
319 pllast->next = pl4;
320
321 if (plz != objPtr)
322 pl2->prev = plz;
323 if (!pl4)
324 objPtr->prev = pllast;
325 else
326 pl4->prev = pllast;
327 }
328 }
329
330 } // End of namespace Cruise
331