ScummVM API documentation
entity.h
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 modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (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, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef LASTEXPRESS_ENTITY_H
23 #define LASTEXPRESS_ENTITY_H
24 
25 #include "lastexpress/shared.h"
26 
27 #include "lastexpress/sound/sound.h"
28 
29 #include "lastexpress/helpers.h"
30 
31 #include "common/array.h"
32 #include "common/func.h"
33 #include "common/serializer.h"
34 #include "common/textconsole.h"
35 
36 namespace LastExpress {
37 
38 class LastExpressEngine;
39 class Sequence;
40 class SequenceFrame;
41 struct SavePoint;
42 
44 // Declaration
46 #define DECLARE_FUNCTION(name) \
47  void setup_##name(); \
48  void name(const SavePoint &savepoint);
49 
50 #define DECLARE_VFUNCTION(name) \
51  void setup_##name() override; \
52  void name(const SavePoint &savepoint);
53 
54 #define DECLARE_FUNCTION_1(name, param1) \
55  void setup_##name(param1); \
56  void name(const SavePoint &savepoint);
57 
58 #define DECLARE_VFUNCTION_1(name, param1) \
59  void setup_##name(param1) override; \
60  void name(const SavePoint &savepoint);
61 
62 #define DECLARE_FUNCTION_2(name, param1, param2) \
63  void setup_##name(param1, param2); \
64  void name(const SavePoint &savepoint);
65 
66 #define DECLARE_VFUNCTION_2(name, param1, param2) \
67  void setup_##name(param1, param2) override; \
68  void name(const SavePoint &savepoint);
69 
70 #define DECLARE_FUNCTION_3(name, param1, param2, param3) \
71  void setup_##name(param1, param2, param3); \
72  void name(const SavePoint &savepoint);
73 
74 #define DECLARE_FUNCTION_4(name, param1, param2, param3, param4) \
75  void setup_##name(param1, param2, param3, param4); \
76  void name(const SavePoint &savepoint);
77 
78 #define DECLARE_FUNCTION_NOSETUP(name) \
79  void name(const SavePoint &savepoint);
80 
81 #define DECLARE_NULL_FUNCTION() \
82  void setup_nullfunction();
83 
85 // Callbacks
87 #define ENTITY_CALLBACK(class, name, pointer) \
88  Common::Functor1Mem<const SavePoint&, void, class>(pointer, &class::name)
89 
90 #define ADD_CALLBACK_FUNCTION_TYPE(class, name, type) \
91  _callbacks.push_back(new ENTITY_CALLBACK(class, name, this)); \
92  _paramsTypeSetters.push_back(&EntityData::resetParametersType<EntityData::type, EntityData::EntityParametersIIII, EntityData::EntityParametersIIII>);
93 
94 #define ADD_CALLBACK_FUNCTION_TYPE2(class, name, type1, type2) \
95  _callbacks.push_back(new ENTITY_CALLBACK(class, name, this)); \
96  _paramsTypeSetters.push_back(&EntityData::resetParametersType<EntityData::type1, EntityData::type2, EntityData::EntityParametersIIII>);
97 
98 #define ADD_CALLBACK_FUNCTION_TYPE3(class, name, type1, type2, type3) \
99  _callbacks.push_back(new ENTITY_CALLBACK(class, name, this)); \
100  _paramsTypeSetters.push_back(&EntityData::resetParametersType<EntityData::type1, EntityData::type2, EntityData::type3>);
101 
102 #define ADD_CALLBACK_FUNCTION(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersIIII)
103 #define ADD_CALLBACK_FUNCTION_I(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersIIII)
104 #define ADD_CALLBACK_FUNCTION_II(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersIIII)
105 #define ADD_CALLBACK_FUNCTION_III(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersIIII)
106 #define ADD_CALLBACK_FUNCTION_S(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersSIIS)
107 #define ADD_CALLBACK_FUNCTION_SI(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersSIIS)
108 #define ADD_CALLBACK_FUNCTION_SII(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersSIII)
109 #define ADD_CALLBACK_FUNCTION_SIII(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersSIII)
110 #define ADD_CALLBACK_FUNCTION_SIIS(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersSIIS)
111 #define ADD_CALLBACK_FUNCTION_SS(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersSSII)
112 #define ADD_CALLBACK_FUNCTION_SSI(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersSSII)
113 #define ADD_CALLBACK_FUNCTION_IS(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersISII)
114 #define ADD_CALLBACK_FUNCTION_ISS(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersISSI)
115 #define ADD_CALLBACK_FUNCTION_IIS(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersIISI)
116 #define ADD_CALLBACK_FUNCTION_IISS(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersIISS)
117 
118 #define ADD_NULL_FUNCTION() \
119  _callbacks.push_back(new ENTITY_CALLBACK(Entity, nullfunction, this)); \
120  _paramsTypeSetters.push_back(&(EntityData::resetParametersType<EntityData::EntityParametersIIII, EntityData::EntityParametersIIII, EntityData::EntityParametersIIII>));
121 
122 #define WRAP_SETUP_FUNCTION(className, method) \
123  new Common::Functor0Mem<void, className>(this, &className::method)
124 
125 #define WRAP_SETUP_FUNCTION_S(className, method) \
126  new Common::Functor1Mem<const char *, void, className>(this, &className::method)
127 
128 #define WRAP_SETUP_FUNCTION_B(className, method) \
129  new Common::Functor1Mem<bool, void, className>(this, &className::method)
130 
132 // Parameters macros
134 #define CURRENT_PARAM(index, id) \
135  ((EntityData::EntityParametersIIII*)_data->getCurrentParameters(index))->param##id
136 
137 #define ENTITY_PARAM(index, id) \
138  ((EntityData::EntityParametersIIII*)_data->getParameters(8, index))->param##id
139 
141 // Misc
143 #define RESET_ENTITY_STATE(entity, class, function) \
144  getEntities()->resetState(entity); \
145  ((class *)getEntities()->get(entity))->function();
146 
148 // Implementation
150 
151 // Expose parameters and check validity
152 #define EXPOSE_PARAMS(type) \
153  type *params = (type *)_data->getCurrentParameters(); \
154  if (!params) \
155  error("[EXPOSE_PARAMS] Trying to call an entity function with invalid parameters"); \
156 
157 // function signature without setup (we keep the index for consistency but never use it)
158 #define IMPLEMENT_FUNCTION_NOSETUP(index, class, name) \
159  void class::name(const SavePoint &savepoint) { \
160  debugC(6, kLastExpressDebugLogic, "Entity: " #class "::" #name "(index=" #index ")");
161 
162 // simple setup with no parameters
163 #define IMPLEMENT_FUNCTION(index, class, name) \
164  void class::setup_##name() { \
165  Entity::setup(#class "::setup_" #name, index, _paramsTypeSetters[index]); \
166  } \
167  void class::name(const SavePoint &savepoint) { \
168  EXPOSE_PARAMS(EntityData::EntityParametersIIII) \
169  debugC(6, kLastExpressDebugLogic, "Entity: " #class "::" #name "() - action: %s", ACTION_NAME(savepoint.action));
170 
171 #define IMPLEMENT_FUNCTION_END }
172 
173 // nullfunction call
174 #define IMPLEMENT_NULL_FUNCTION(index, class) \
175  void class::setup_nullfunction() { \
176  Entity::setup(#class "::setup_nullfunction", index, _paramsTypeSetters[index]); \
177  }
178 
179 // setup with one uint parameter
180 #define IMPLEMENT_FUNCTION_I(index, class, name, paramType) \
181  void class::setup_##name(paramType param1) { \
182  Entity::setupI(#class "::setup_" #name, index, _paramsTypeSetters[index], param1); \
183  } \
184  void class::name(const SavePoint &savepoint) { \
185  EXPOSE_PARAMS(EntityData::EntityParametersIIII) \
186  debugC(6, kLastExpressDebugLogic, "Entity: " #class "::" #name "(%d) - action: %s", params->param1, ACTION_NAME(savepoint.action));
187 
188 // setup with two uint parameters
189 #define IMPLEMENT_FUNCTION_II(index, class, name, paramType1, paramType2) \
190  void class::setup_##name(paramType1 param1, paramType2 param2) { \
191  Entity::setupII(#class "::setup_" #name, index, _paramsTypeSetters[index], param1, param2); \
192  } \
193  void class::name(const SavePoint &savepoint) { \
194  EXPOSE_PARAMS(EntityData::EntityParametersIIII) \
195  debugC(6, kLastExpressDebugLogic, "Entity: " #class "::" #name "(%d, %d) - action: %s", params->param1, params->param2, ACTION_NAME(savepoint.action));
196 
197 // setup with three uint parameters
198 #define IMPLEMENT_FUNCTION_III(index, class, name, paramType1, paramType2, paramType3) \
199  void class::setup_##name(paramType1 param1, paramType2 param2, paramType3 param3) { \
200  Entity::setupIII(#class "::setup_" #name, index, _paramsTypeSetters[index], param1, param2, param3); \
201  } \
202  void class::name(const SavePoint &savepoint) { \
203  EXPOSE_PARAMS(EntityData::EntityParametersIIII) \
204  debugC(6, kLastExpressDebugLogic, "Entity: " #class "::" #name "(%d, %d, %d) - action: %s", params->param1, params->param2, params->param3, ACTION_NAME(savepoint.action));
205 
206 // setup with one char *parameter
207 #define IMPLEMENT_FUNCTION_S(index, class, name) \
208  void class::setup_##name(const char *seq1) { \
209  Entity::setupS(#class "::setup_" #name, index, _paramsTypeSetters[index], seq1); \
210  } \
211  void class::name(const SavePoint &savepoint) { \
212  EXPOSE_PARAMS(EntityData::EntityParametersSIIS) \
213  debugC(6, kLastExpressDebugLogic, "Entity: " #class "::" #name "(%s) - action: %s", (char *)&params->seq1, ACTION_NAME(savepoint.action));
214 
215 // setup with one char *parameter and one uint
216 #define IMPLEMENT_FUNCTION_SI(index, class, name, paramType2) \
217  void class::setup_##name(const char *seq1, paramType2 param4) { \
218  Entity::setupSI(#class "::setup_" #name, index, _paramsTypeSetters[index], seq1, param4); \
219  } \
220  void class::name(const SavePoint &savepoint) { \
221  EXPOSE_PARAMS(EntityData::EntityParametersSIIS) \
222  debugC(6, kLastExpressDebugLogic, "Entity: " #class "::" #name "(%s, %d) - action: %s", (char *)&params->seq1, params->param4, ACTION_NAME(savepoint.action));
223 
224 // setup with one char *parameter and two uints
225 #define IMPLEMENT_FUNCTION_SII(index, class, name, paramType2, paramType3) \
226  void class::setup_##name(const char *seq1, paramType2 param4, paramType3 param5) { \
227  Entity::setupSII(#class "::setup_" #name, index, _paramsTypeSetters[index], seq1, param4, param5); \
228  } \
229  void class::name(const SavePoint &savepoint) { \
230  EXPOSE_PARAMS(EntityData::EntityParametersSIII) \
231  debugC(6, kLastExpressDebugLogic, "Entity: " #class "::" #name "(%s, %d, %d) - action: %s", (char *)&params->seq, params->param4, params->param5, ACTION_NAME(savepoint.action));
232 
233 // setup with one char *parameter and three uints
234 #define IMPLEMENT_FUNCTION_SIII(index, class, name, paramType2, paramType3, paramType4) \
235  void class::setup_##name(const char *seq, paramType2 param4, paramType3 param5, paramType4 param6) { \
236  Entity::setupSIII(#class "::setup_" #name, index, _paramsTypeSetters[index], seq, param4, param5, param6); \
237  } \
238  void class::name(const SavePoint &savepoint) { \
239  EXPOSE_PARAMS(EntityData::EntityParametersSIII) \
240  debugC(6, kLastExpressDebugLogic, "Entity: " #class "::" #name "(%s, %d, %d, %d) - action: %s", (char *)&params->seq, params->param4, params->param5, params->param6, ACTION_NAME(savepoint.action));
241 
242 #define IMPLEMENT_FUNCTION_SIIS(index, class, name, paramType2, paramType3) \
243  void class::setup_##name(const char *seq1, paramType2 param4, paramType3 param5, const char *seq2) { \
244  Entity::setupSIIS(#class "::setup_" #name, index, _paramsTypeSetters[index], seq1, param4, param5, seq2); \
245  } \
246  void class::name(const SavePoint &savepoint) { \
247  EXPOSE_PARAMS(EntityData::EntityParametersSIIS) \
248  debugC(6, kLastExpressDebugLogic, "Entity: " #class "::" #name "(%s, %d, %d, %s) - action: %s", (char *)&params->seq1, params->param4, params->param5, (char *)&params->seq2, ACTION_NAME(savepoint.action));
249 
250 #define IMPLEMENT_FUNCTION_SS(index, class, name) \
251  void class::setup_##name(const char *seq1, const char *seq2) { \
252  Entity::setupSS(#class "::setup_" #name, index, _paramsTypeSetters[index], seq1, seq2); \
253  } \
254  void class::name(const SavePoint &savepoint) { \
255  EXPOSE_PARAMS(EntityData::EntityParametersSSII) \
256  debugC(6, kLastExpressDebugLogic, "Entity: " #class "::" #name "(%s, %s) - action: %s", (char *)&params->seq1, (char *)&params->seq2, ACTION_NAME(savepoint.action));
257 
258 #define IMPLEMENT_FUNCTION_SSI(index, class, name, paramType3) \
259  void class::setup_##name(const char *seq1, const char *seq2, paramType3 param7) { \
260  Entity::setupSSI(#class "::setup_" #name, index, _paramsTypeSetters[index], seq1, seq2, param7); \
261  } \
262  void class::name(const SavePoint &savepoint) { \
263  EXPOSE_PARAMS(EntityData::EntityParametersSSII) \
264  debugC(6, kLastExpressDebugLogic, "Entity: " #class "::" #name "(%s, %s, %d) - action: %s", (char *)&params->seq1, (char *)&params->seq2, params->param7, ACTION_NAME(savepoint.action));
265 
266 #define IMPLEMENT_FUNCTION_IS(index, class, name, paramType) \
267  void class::setup_##name(paramType param1, const char *seq) { \
268  Entity::setupIS(#class "::setup_" #name, index, _paramsTypeSetters[index], param1, seq); \
269  } \
270  void class::name(const SavePoint &savepoint) { \
271  EXPOSE_PARAMS(EntityData::EntityParametersISII) \
272  debugC(6, kLastExpressDebugLogic, "Entity: " #class "::" #name "(%d, %s) - action: %s", params->param1, (char *)&params->seq, ACTION_NAME(savepoint.action));
273 
274 #define IMPLEMENT_FUNCTION_ISS(index, class, name, paramType) \
275  void class::setup_##name(paramType param1, const char *seq1, const char *seq2) { \
276  Entity::setupISS(#class "::setup_" #name, index, _paramsTypeSetters[index], param1, seq1, seq2); \
277  } \
278  void class::name(const SavePoint &savepoint) { \
279  EXPOSE_PARAMS(EntityData::EntityParametersISSI) \
280  debugC(6, kLastExpressDebugLogic, "Entity: " #class "::" #name "(%d, %s, %s) - action: %s", params->param1, (char *)&params->seq1, (char *)&params->seq2, ACTION_NAME(savepoint.action));
281 
282 #define IMPLEMENT_FUNCTION_IIS(index, class, name, paramType1, paramType2) \
283  void class::setup_##name(paramType1 param1, paramType2 param2, const char *seq) { \
284  Entity::setupIIS(#class "::setup_" #name, index, _paramsTypeSetters[index], param1, param2, seq); \
285  } \
286  void class::name(const SavePoint &savepoint) { \
287  EXPOSE_PARAMS(EntityData::EntityParametersIISI) \
288  debugC(6, kLastExpressDebugLogic, "Entity: " #class "::" #name "(%d, %d, %s) - action: %s", params->param1, params->param2, (char *)&params->seq, ACTION_NAME(savepoint.action));
289 
290 #define IMPLEMENT_FUNCTION_IISS(index, class, name, paramType1, paramType2) \
291  void class::setup_##name(paramType1 param1, paramType2 param2, const char *seq1, const char *seq2) { \
292  Entity::setupIISS(#class "::setup_" #name, index, _paramsTypeSetters[index], param1, param2, seq1, seq2); \
293  } \
294  void class::name(const SavePoint &savepoint) { \
295  EXPOSE_PARAMS(EntityData::EntityParametersIISS) \
296  debugC(6, kLastExpressDebugLogic, "Entity: " #class "::" #name "(%d, %d, %s, %s) - action: %s", params->param1, params->param2, (char *)&params->seq1, (char *)&params->seq2, ACTION_NAME(savepoint.action));
297 
298 
300 class EntityData {
301 public:
302 
304  ~EntityParameters() override {}
305  virtual Common::String toString() = 0;
306 
307  virtual void update(uint32 index) = 0;
308 
309  void saveLoadWithSerializer(Common::Serializer &s) override = 0;
310  };
311 
313  uint param1;
314  uint param2;
315  uint param3;
316  uint param4;
317  uint param5;
318  uint param6;
319  uint param7;
320  uint param8;
321 
323  param1 = 0;
324  param2 = 0;
325  param3 = 0;
326  param4 = 0;
327  param5 = 0;
328  param6 = 0;
329  param7 = 0;
330  param8 = 0;
331  }
332 
333  bool hasNonNullParameter() {
334  return param1 || param2 || param3 || param4 || param5 || param6 || param7 || param8;
335  }
336 
337  Common::String toString() override {
338  return Common::String::format("IIII: %d %d %d %d %d %d %d %d\n", param1, param2, param3, param4, param5, param6, param7, param8);
339  }
340 
341  void update(uint32 index) override {
342  switch (index) {
343  default:
344  error("[EntityParametersIIII::update] Invalid index (was: %d)", index);
345 
346  case 0: param1 = 1; break;
347  case 1: param2 = 1; break;
348  case 2: param3 = 1; break;
349  case 3: param4 = 1; break;
350  case 4: param5 = 1; break;
351  case 5: param6 = 1; break;
352  case 6: param7 = 1; break;
353  case 7: param8 = 1; break;
354  }
355  }
356 
357  void saveLoadWithSerializer(Common::Serializer &s) override {
358  s.syncAsUint32LE(param1);
359  s.syncAsUint32LE(param2);
360  s.syncAsUint32LE(param3);
361  s.syncAsUint32LE(param4);
362  s.syncAsUint32LE(param5);
363  s.syncAsUint32LE(param6);
364  s.syncAsUint32LE(param7);
365  s.syncAsUint32LE(param8);
366  }
367  };
368 
370  char seq[13];
371  uint param4;
372  uint param5;
373  uint param6;
374  uint param7;
375  uint param8;
376 
378  memset(&seq, 0, 13);
379  param4 = 0;
380  param5 = 0;
381  param6 = 0;
382  param7 = 0;
383  param8 = 0;
384  }
385 
386  Common::String toString() override {
387  return Common::String::format("SIII: %s %d %d %d %d %d\n", seq, param4, param5, param6, param7, param8);
388  }
389 
390  void update(uint32 index) override {
391  switch (index) {
392  default:
393  error("[EntityParametersSIII::update] Invalid index (was: %d)", index);
394 
395  case 3: param4 = 1; break;
396  case 4: param5 = 1; break;
397  case 5: param6 = 1; break;
398  case 6: param7 = 1; break;
399  case 7: param8 = 1; break;
400  }
401  }
402 
403  void saveLoadWithSerializer(Common::Serializer &s) override {
404  s.syncBytes((byte *)&seq, 12);
405  s.syncAsUint32LE(param4);
406  s.syncAsUint32LE(param5);
407  s.syncAsUint32LE(param6);
408  s.syncAsUint32LE(param7);
409  s.syncAsUint32LE(param8);
410  }
411  };
412 
414  char seq1[13];
415  uint param4;
416  uint param5;
417  char seq2[13];
418 
420  memset(&seq1, 0, 13);
421  param4 = 0;
422  param5 = 0;
423  memset(&seq2, 0, 13);
424  }
425 
426  Common::String toString() override {
427  return Common::String::format("SIIS: %s %d %d %s\n", seq1, param4, param5, seq2);
428  }
429 
430  void update(uint32 index) override {
431  switch (index) {
432  default:
433  error("[EntityParametersSIIS::update] Invalid index (was: %d)", index);
434 
435  case 3: param4 = 1; break;
436  case 4: param5 = 1; break;
437  }
438  }
439 
440  void saveLoadWithSerializer(Common::Serializer &s) override {
441  s.syncBytes((byte *)&seq1, 12);
442  s.syncAsUint32LE(param4);
443  s.syncAsUint32LE(param5);
444  s.syncBytes((byte *)&seq2, 12);
445  }
446  };
447 
449  uint param1;
450  char seq1[13];
451  char seq2[13];
452  uint param8;
453 
455  param1 = 0;
456  memset(&seq1, 0, 13);
457  memset(&seq2, 0, 13);
458  param8 = 0;
459  }
460 
461  Common::String toString() override {
462  return Common::String::format("ISSI: %d %s %s %d\n", param1, seq1, seq2, param8);
463  }
464 
465  void update(uint32 index) override {
466  switch (index) {
467  default:
468  error("[EntityParametersISSI::update] Invalid index (was: %d)", index);
469 
470  case 0: param1 = 1; break;
471  case 7: param8 = 1; break;
472  }
473  }
474 
475  void saveLoadWithSerializer(Common::Serializer &s) override {
476  s.syncAsUint32LE(param1);
477  s.syncBytes((byte *)&seq1, 12);
478  s.syncBytes((byte *)&seq2, 12);
479  s.syncAsUint32LE(param8);
480  }
481  };
482 
484  uint param1;
485  char seq[13];
486  uint param5;
487  uint param6;
488  uint param7;
489  uint param8;
490 
492  param1 = 0;
493  memset(&seq, 0, 13);
494  param5 = 0;
495  param6 = 0;
496  param7 = 0;
497  param8 = 0;
498  }
499 
500  Common::String toString() override {
501  return Common::String::format("ISII: %d %s %d %d %d %d\n", param1, seq, param5, param6, param7, param8);
502  }
503 
504  void update(uint32 index) override {
505  switch (index) {
506  default:
507  error("[EntityParametersISII::update] Invalid index (was: %d)", index);
508 
509  case 0: param1 = 1; break;
510  case 4: param5 = 1; break;
511  case 5: param6 = 1; break;
512  case 6: param7 = 1; break;
513  case 7: param8 = 1; break;
514  }
515  }
516 
517  void saveLoadWithSerializer(Common::Serializer &s) override {
518  s.syncAsUint32LE(param1);
519  s.syncBytes((byte *)&seq, 12);
520  s.syncAsUint32LE(param5);
521  s.syncAsUint32LE(param6);
522  s.syncAsUint32LE(param7);
523  s.syncAsUint32LE(param8);
524  }
525  };
526 
528  char seq1[13];
529  char seq2[13];
530  uint param7;
531  uint param8;
532 
534  memset(&seq1, 0, 13);
535  memset(&seq2, 0, 13);
536  param7 = 0;
537  param8 = 0;
538  }
539 
540  Common::String toString() override {
541  return Common::String::format("SSII: %s %s %d %d\n", seq1, seq2, param7, param8);
542  }
543 
544  void update(uint32 index) override {
545  switch (index) {
546  default:
547  error("[EntityParametersSSII::update] Invalid index (was: %d)", index);
548 
549  case 6: param7 = 1; break;
550  case 7: param8 = 1; break;
551  }
552  }
553 
554  void saveLoadWithSerializer(Common::Serializer &s) override {
555  s.syncBytes((byte *)&seq1, 12);
556  s.syncBytes((byte *)&seq2, 12);
557  s.syncAsUint32LE(param7);
558  s.syncAsUint32LE(param8);
559  }
560  };
561 
563  char seq1[13];
564  char seq2[13];
565  char seq3[9];
566 
568  memset(&seq1, 0, 13);
569  memset(&seq2, 0, 13);
570  memset(&seq3, 0, 9);
571  }
572 
573  Common::String toString() override {
574  return Common::String::format("SSS: %s %s %s\n", seq1, seq2, seq3);
575  }
576 
577  void update(uint32) override {
578  error("[EntityParametersSSS::update] Cannot update this type of parameters");
579  }
580 
581  void saveLoadWithSerializer(Common::Serializer &s) override {
582  s.syncBytes((byte *)&seq1, 12);
583  s.syncBytes((byte *)&seq2, 12);
584  s.syncBytes((byte *)&seq3, 8);
585  }
586  };
587 
589  uint param1;
590  uint param2;
591  char seq1[13];
592  char seq2[13];
593 
595  param1 = 0;
596  param2 = 0;
597  memset(&seq1, 0, 13);
598  memset(&seq2, 0, 13);
599  }
600 
601  Common::String toString() override {
602  return Common::String::format("IISS: %d %d %s %s\n", param1, param2, seq1, seq2);
603  }
604 
605  void update(uint32 index) override {
606  switch (index) {
607  default:
608  error("[EntityParametersIISS::update] Invalid index (was: %d)", index);
609 
610  case 0: param1 = 1; break;
611  case 1: param2 = 1; break;
612  }
613  }
614 
615  void saveLoadWithSerializer(Common::Serializer &s) override {
616  s.syncAsUint32LE(param1);
617  s.syncAsUint32LE(param2);
618  s.syncBytes((byte *)&seq1, 12);
619  s.syncBytes((byte *)&seq2, 12);
620  }
621  };
622 
624  uint param1;
625  uint param2;
626  char seq[13];
627  uint param6;
628  uint param7;
629  uint param8;
630 
632  param1 = 0;
633  param2 = 0;
634  memset(&seq, 0, 13);
635  param6 = 0;
636  param7 = 0;
637  param8 = 0;
638  }
639 
640  Common::String toString() override {
641  return Common::String::format("IISI: %d %d %s %d %d %d\n", param1, param2, seq, param6, param7, param8);
642  }
643 
644  void update(uint32 index) override {
645  switch (index) {
646  default:
647  error("[EntityParametersIISI::update] Invalid index (was: %d)", index);
648 
649  case 0: param1 = 1; break;
650  case 1: param2 = 1; break;
651  case 5: param6 = 1; break;
652  case 6: param7 = 1; break;
653  case 7: param8 = 1; break;
654  }
655  }
656 
657  void saveLoadWithSerializer(Common::Serializer &s) override {
658  s.syncAsUint32LE(param1);
659  s.syncAsUint32LE(param2);
660  s.syncBytes((byte *)&seq, 12);
661  s.syncAsUint32LE(param6);
662  s.syncAsUint32LE(param7);
663  s.syncAsUint32LE(param8);
664  }
665  };
666 
668  uint param1;
669  uint param2;
670  uint param3;
671  char seq[13];
672  uint param7;
673  uint param8;
674 
676  param1 = 0;
677  param2 = 0;
678  param3 = 0;
679  memset(&seq, 0, 13);
680  param7 = 0;
681  param8 = 0;
682  }
683 
684  Common::String toString() override {
685  return Common::String::format("IIIS: %d %d %d %s %d %d\n", param1, param2, param3, seq, param7, param8);
686  }
687 
688  void update(uint32 index) override {
689  switch (index) {
690  default:
691  error("[EntityParametersIIIS::update] Invalid index (was: %d)", index);
692 
693  case 0: param1 = 1; break;
694  case 1: param2 = 1; break;
695  case 2: param3 = 1; break;
696  case 6: param7 = 1; break;
697  case 7: param8 = 1; break;
698  }
699  }
700 
701  void saveLoadWithSerializer(Common::Serializer &s) override {
702  s.syncAsUint32LE(param1);
703  s.syncAsUint32LE(param2);
704  s.syncAsUint32LE(param3);
705  s.syncBytes((byte *)&seq, 12);
706  s.syncAsUint32LE(param7);
707  s.syncAsUint32LE(param8);
708  }
709  };
710 
712  uint param1;
713  uint param2;
714  uint param3;
715  uint param4;
716  uint param5;
717  char seq[13];
718 
720  param1 = 0;
721  param2 = 0;
722  param3 = 0;
723  param4 = 0;
724  param5 = 0;
725  memset(&seq, 0, 13);
726  }
727 
728  Common::String toString() override {
729  return Common::String::format("I5S: %d %d %d %d %d %s\n", param1, param2, param3, param4, param5, seq);
730  }
731 
732  void update(uint32 index) override {
733  switch (index) {
734  default:
735  error("[EntityParametersI5S::update] Invalid index (was: %d)", index);
736 
737  case 0: param1 = 1; break;
738  case 1: param2 = 1; break;
739  case 2: param3 = 1; break;
740  case 3: param4 = 1; break;
741  case 4: param5 = 1; break;
742  }
743  }
744 
745  void saveLoadWithSerializer(Common::Serializer &s) override {
746  s.syncAsUint32LE(param1);
747  s.syncAsUint32LE(param2);
748  s.syncAsUint32LE(param3);
749  s.syncAsUint32LE(param4);
750  s.syncAsUint32LE(param5);
751  s.syncBytes((byte *)&seq, 12);
752  }
753  };
754 
756  EntityParameters *parameters[4];
757 
759  // We default to int parameters
760  for (int i = 0; i < 4; i++)
761  parameters[i] = new EntityParametersIIII();
762  }
763 
764  ~EntityCallParameters() override {
765  clear();
766  }
767 
768  void clear() {
769  for (int i = 0; i < 4; i++)
770  SAFE_DELETE(parameters[i]);
771  }
772 
773  // Serializable
774  void saveLoadWithSerializer(Common::Serializer &s) override {
775  for (uint i = 0; i < ARRAYSIZE(parameters); i++)
776  parameters[i]->saveLoadWithSerializer(s);
777  }
778  };
779 
781  byte callbacks[16];
782  byte currentCall;
783  EntityPosition entityPosition; // word
784  Location location; // word
785  CarIndex car; // word
786  byte field_497;
787  EntityIndex entity; // byte
788  InventoryItem inventoryItem; // byte
789  EntityDirection direction; // byte
790  int16 field_49B;
791  int16 currentFrame;
792  int16 currentFrame2;
793  int16 field_4A1;
794  int16 field_4A3;
795  ClothesIndex clothes; // byte
796  Position position;
797  CarIndex car2; // byte
798  bool doProcessEntity; // byte
799  bool field_4A9; // byte
800  bool field_4AA; // byte
801  EntityDirection directionSwitch;
802  Common::String sequenceName; // char[13]
803  Common::String sequenceName2; // char[13]
804  Common::String sequenceNamePrefix; // char[7]
805  Common::String sequenceNameCopy; // char[13]
806  SequenceFrame *frame;
807  SequenceFrame *frame1;
808  Sequence *sequence;
809  Sequence *sequence2;
810  Sequence *sequence3;
811 
816  memset(&callbacks, 0, 16 * sizeof(byte));
817  currentCall = 0;
818  entityPosition = kPositionNone;
819  location = kLocationOutsideCompartment;
820  car = kCarNone;
821  field_497 = 0;
822  entity = kEntityPlayer;
823  inventoryItem = kItemNone;
824  direction = kDirectionNone;
825  field_49B = 0;
826  currentFrame = 0;
827  currentFrame2 = 0;
828  field_4A1 = 0;
829  field_4A3 = 30;
830  clothes = kClothesDefault;
831  position = 0;
832  car2 = kCarNone;
833  doProcessEntity = false;
834  field_4A9 = false;
835  field_4AA = false;
836  directionSwitch = kDirectionNone;
837  frame = NULL;
838  frame1 = NULL;
839  sequence = NULL;
840  sequence2 = NULL;
841  sequence3 = NULL;
842  }
843 
844  ~EntityCallData() override;
845 
852  Common::String str = "";
853 
854  str += Common::String::format("Entity position: %d - Location: %d - Car: %d\n", entityPosition, location, car);
855  str += Common::String::format("Entity: %d - Item: %d - Direction: %d\n", entity, inventoryItem, direction);
856  str += Common::String::format("Clothes: %d - Position: %d - Direction switch: %d\n", clothes, position, directionSwitch);
857  str += "\n";
858  str += Common::String::format("field_497: %02d - field_49B: %i - field_4A1: %i\n", field_497, field_49B, field_4A1);
859  str += Common::String::format("field_4A9: %02d - field_4AA: %i - Car 2: %d\n", field_4A9, field_4AA, car2);
860  str += "\n";
861  str += "Sequence: " + sequenceName + " - Sequence 2: " + sequenceName2 + "\n";
862  str += "Sequence prefix: " + sequenceNamePrefix + " - Sequence copy: " + sequenceNameCopy + "\n";
863  str += Common::String::format("Current frame: %i - Current frame 2: %i - Process entity: %d\n", currentFrame, currentFrame2, doProcessEntity);
864  str += "\n";
865  str += Common::String::format("Current call: %d\n", currentCall);
866  str += Common::String::format("Functions: %d %d %d %d %d %d %d %d\n", callbacks[0], callbacks[1], callbacks[2], callbacks[3], callbacks[4], callbacks[5], callbacks[6], callbacks[7]);
867  str += Common::String::format("Callbacks: %d %d %d %d %d %d %d %d\n", callbacks[8], callbacks[9], callbacks[10], callbacks[11], callbacks[12], callbacks[13], callbacks[14], callbacks[15]);
868 
869  return str;
870  }
871 
879  void syncString(Common::Serializer &s, Common::String &string, uint length) const;
880 
881  // Serializable
882  void saveLoadWithSerializer(Common::Serializer &s) override;
883  };
884 
885  EntityData() {}
886 
887  template<class T1, class T2, class T3>
888  static void resetParametersType(EntityCallParameters* params) {
889  params->clear();
890  params->parameters[0] = new T1();
891  params->parameters[1] = new T2();
892  params->parameters[2] = new T3();
893  params->parameters[3] = new EntityParametersIIII();
894  }
895 
896  EntityCallData *getCallData() { return &_data; }
897 
898  EntityParameters *getParameters(uint callback, byte index) const;
899  EntityParameters *getCurrentParameters(byte index = 0) { return getParameters(_data.currentCall, index); }
900  EntityCallParameters *getCurrentCallParameters() { return &_parameters[_data.currentCall]; }
901 
902  byte getCallback(uint callback) const;
903  byte getCurrentCallback() { return getCallback(_data.currentCall); }
904  void setCallback(uint callback, byte index);
905  void setCurrentCallback(uint index) { setCallback(_data.currentCall, index); }
906 
907  void updateParameters(uint32 index) const;
908 
909  // Serializable
910  typedef void(*TypeSetter)(EntityCallParameters*);
911  void saveLoadWithSerializer(Common::Serializer &ser, const Common::Array<TypeSetter>* paramsTypeSetters);
912 
913 private:
914 
915  EntityCallData _data;
916  EntityCallParameters _parameters[9];
917 };
918 
920 public:
921  Entity(LastExpressEngine *engine, EntityIndex index);
922  ~Entity() override;
923 
924  // Accessors
925  EntityData *getParamData() { return _data; }
926  EntityData::EntityCallData *getData() { return _data->getCallData(); }
927 
928  // Callbacks
929  byte getCallback() { return _data->getCallback(_data->getCallData()->currentCall + 8); }
930  void setCallback(byte index) { _data->setCallback(_data->getCallData()->currentCall + 8, index); getData()->currentCall++; }
931 
932  // Setup
933  void setup(ChapterIndex index);
934 
935  virtual void setup_chapter1() = 0;
936  virtual void setup_chapter2() = 0;
937  virtual void setup_chapter3() = 0;
938  virtual void setup_chapter4() = 0;
939  virtual void setup_chapter5() = 0;
940 
941  // Shared functions
942  virtual void setup_savegame(SavegameType, uint32) { error("[Entity::setup_savegame] Trying to call the parent setup function. Use the specific entity function directly"); }
943  virtual void setup_enterExitCompartment(const char *, ObjectIndex) { error("[Entity::setup_enterExitCompartment] Trying to call the parent setup function. Use the specific entity function directly"); }
944  virtual void setup_updateEntity(CarIndex, EntityPosition) { error("[Entity::setup_updateEntity] Trying to call the parent setup function. Use the specific entity function directly"); }
945  virtual void setup_playSound(const char*) { error("[Entity::setup_playSound] Trying to call the parent setup function. Use the specific entity function directly"); }
946 
947  // Serializable
948  void saveLoadWithSerializer(Common::Serializer &ser) override { _data->saveLoadWithSerializer(ser, &_paramsTypeSetters); }
949 
950  void nullfunction(const SavePoint &savepoint) {}
951 
952 protected:
953  LastExpressEngine *_engine;
955 
956  EntityIndex _entityIndex;
957  EntityData *_data;
958  Common::Array<Callback *> _callbacks;
959  Common::Array<EntityData::TypeSetter> _paramsTypeSetters;
960 
968  void savegame(const SavePoint &savepoint);
969 
976  bool savegameBloodJacket(byte callback);
977 
986  void playSound(const SavePoint &savepoint, bool resetItem = false, SoundFlag flag = kSoundVolumeEntityDefault);
987 
996  void draw(const SavePoint &savepoint, bool handleExcuseMe = false);
997 
1006  void draw2(const SavePoint &savepoint);
1007 
1014  void updateFromTicks(const SavePoint &savepoint);
1015 
1022  void updateFromTime(const SavePoint &savepoint);
1023 
1031  void reset(const SavePoint &savepoint, ClothesIndex maxClothes = kClothesDefault, bool resetItem = false);
1032 
1038  void callbackActionOnDirection(const SavePoint &savepoint);
1039 
1045  void callbackActionRestaurantOrSalon(const SavePoint &savepoint);
1046 
1055  void updateEntity(const SavePoint &savepoint, bool handleExcuseMe = false);
1056 
1067  void callSavepoint(const SavePoint &savepoint, bool handleExcuseMe = false);
1068 
1079  void enterExitCompartment(const SavePoint &savepoint, EntityPosition position1 = kPositionNone, EntityPosition position2 = kPositionNone, CarIndex car = kCarNone, ObjectIndex compartment = kObjectNone, bool alternate = false, bool updateLocation = false);
1080 
1090  void goToCompartment(const SavePoint &savepoint, ObjectIndex compartmentFrom, EntityPosition positionFrom, Common::String sequenceFrom, Common::String sequenceTo);
1091 
1103  void goToCompartmentFromCompartment(const SavePoint &savepoint, ObjectIndex compartmentFrom, EntityPosition positionFrom, Common::String sequenceFrom, ObjectIndex compartmentTo, EntityPosition positionTo, Common::String sequenceTo);
1104 
1114  void updatePosition(const SavePoint &savepoint, bool handleExcuseMe = false);
1115 
1119  void callbackAction();
1120 
1122  // Setup functions
1124  void setup(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter);
1125  void setupI(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, uint param1);
1126  void setupII(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, uint param1, uint param2);
1127  void setupIII(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, uint param1, uint param2, uint param3);
1128  void setupS(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, const char *seq1);
1129  void setupSS(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, const char *seq1, const char *seq2);
1130  void setupSI(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, const char *seq1, uint param4);
1131  void setupSII(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, const char *seq1, uint param4, uint param5);
1132  void setupSIII(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, const char *seq, uint param4, uint param5, uint param6);
1133  void setupSIIS(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, const char *seq1, uint param4, uint param5, const char *seq2);
1134  void setupSSI(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, const char *seq1, const char *seq2, uint param7);
1135  void setupIS(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, uint param1, const char *seq);
1136  void setupISS(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, uint param1, const char *seq1, const char *seq2);
1137  void setupIIS(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, uint param1, uint param2, const char *seq);
1138  void setupIISS(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, uint param1, uint param2, const char *seq1, const char *seq2);
1139 
1141  // Helper functions
1143 
1144  bool updateParameter(uint &parameter, uint timeType, uint delta) const;
1145  bool updateParameterCheck(uint &parameter, uint timeType, uint delta) const;
1146  bool updateParameterTime(TimeValue timeValue, bool check, uint &parameter, uint delta) const;
1147 
1148  bool timeCheck(TimeValue timeValue, uint &parameter, Common::Functor0<void> *function) const;
1149  bool timeCheckCallback(TimeValue timeValue, uint &parameter, byte callback, Common::Functor0<void> *function);
1150  bool timeCheckCallback(TimeValue timeValue, uint &parameter, byte callback, const char *str, Common::Functor1<const char *, void> *function);
1151  bool timeCheckCallback(TimeValue timeValue, uint &parameter, byte callback, bool check, Common::Functor1<bool, void> *function);
1152  bool timeCheckCallbackInventory(TimeValue timeValue, uint &parameter, byte callback, Common::Functor0<void> *function);
1153  bool timeCheckCar(TimeValue timeValue, uint &parameter, byte callback, Common::Functor0<void> *function);
1154  void timeCheckSavepoint(TimeValue timeValue, uint &parameter, EntityIndex entity1, EntityIndex entity2, ActionIndex action) const;
1155  void timeCheckObject(TimeValue timeValue, uint &parameter, ObjectIndex index, ObjectModel model) const;
1156  bool timeCheckCallbackAction(TimeValue timeValue, uint &parameter);
1157  bool timeCheckPlaySoundUpdatePosition(TimeValue timeValue, uint &parameter, byte callback, const char* sound, EntityPosition position);
1158 
1159 };
1160 
1161 
1162 } // End of namespace LastExpress
1163 
1164 #endif // LASTEXPRESS_ENTITY_H
#define ARRAYSIZE(x)
Definition: util.h:92
void syncBytes(byte *buf, uint32 size, Version minVersion=0, Version maxVersion=kLastVersion)
Definition: serializer.h:204
Definition: str.h:59
static String format(MSVC_PRINTF const char *fmt,...) GCC_PRINTF(1
Definition: lastexpress.h:69
Definition: array.h:52
Definition: animation.h:45
Definition: serializer.h:79
Definition: entity.h:919
Common::String toString()
Definition: entity.h:851
Definition: savepoint.h:54
EntityCallData()
Definition: entity.h:815
Definition: sequence.h:151
Definition: serializer.h:307
Definition: sequence.h:183
Definition: func.h:437
void NORETURN_PRE error(MSVC_PRINTF const char *s,...) GCC_PRINTF(1
Definition: entity.h:300