PageRenderTime 58ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 1ms

/engines/kyra/graphics/animator_tim.cpp

http://github.com/scummvm/scummvm
C++ | 235 lines | 174 code | 37 blank | 24 comment | 48 complexity | 3d4072e467842c657677ce16bbb8503f MD5 | raw file
Possible License(s): GPL-3.0, LGPL-2.1, GPL-2.0
  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. #include "kyra/script/script_tim.h"
  23. #include "kyra/graphics/wsamovie.h"
  24. #include "kyra/graphics/screen_lol.h"
  25. #ifdef ENABLE_LOL
  26. #include "kyra/engine/lol.h"
  27. #else
  28. #include "kyra/graphics/screen_v2.h"
  29. #endif
  30. #include "common/system.h"
  31. namespace Kyra {
  32. #ifdef ENABLE_LOL
  33. TimAnimator::TimAnimator(LoLEngine *engine, Screen_v2 *screen_v2, OSystem *system, bool useParts) : _vm(engine), _screen(screen_v2), _system(system), _useParts(useParts) {
  34. #else
  35. TimAnimator::TimAnimator(KyraEngine_v1 *engine, Screen_v2 *screen_v2, OSystem *system, bool useParts) : _vm(engine), _screen(screen_v2), _system(system), _useParts(useParts) {
  36. #endif
  37. _animations = new Animation[TIM::kWSASlots];
  38. memset(_animations, 0, TIM::kWSASlots * sizeof(Animation));
  39. if (_useParts) {
  40. for (int i = 0; i < TIM::kWSASlots; i++) {
  41. _animations[i].parts = new AnimPart[TIM::kAnimParts];
  42. memset(_animations[i].parts, 0, TIM::kAnimParts * sizeof(AnimPart));
  43. }
  44. }
  45. }
  46. TimAnimator::~TimAnimator() {
  47. for (int i = 0; i < TIM::kWSASlots; i++) {
  48. delete _animations[i].wsa;
  49. if (_useParts)
  50. delete[] _animations[i].parts;
  51. }
  52. delete[] _animations;
  53. }
  54. void TimAnimator::init(int animIndex, Movie *wsa, int x, int y, int wsaCopyParams, int frameDelay) {
  55. Animation *anim = &_animations[animIndex];
  56. anim->wsa = wsa;
  57. anim->x = x;
  58. anim->y = y;
  59. anim->wsaCopyParams = wsaCopyParams;
  60. anim->frameDelay = frameDelay;
  61. anim->enable = 0;
  62. anim->lastPart = -1;
  63. }
  64. void TimAnimator::reset(int animIndex, bool clearStruct) {
  65. Animation *anim = &_animations[animIndex];
  66. if (!anim)
  67. return;
  68. anim->field_D = 0;
  69. anim->enable = 0;
  70. delete anim->wsa;
  71. anim->wsa = 0;
  72. if (clearStruct) {
  73. if (_useParts)
  74. delete[] anim->parts;
  75. memset(anim, 0, sizeof(Animation));
  76. if (_useParts) {
  77. anim->parts = new AnimPart[TIM::kAnimParts];
  78. memset(anim->parts, 0, TIM::kAnimParts * sizeof(AnimPart));
  79. }
  80. }
  81. }
  82. void TimAnimator::displayFrame(int animIndex, int page, int frame, int flags) {
  83. Animation *anim = &_animations[animIndex];
  84. if ((anim->wsaCopyParams & 0x4000) != 0)
  85. page = 2;
  86. // WORKAROUND for some bugged scripts that will try to display frames of non-existent animations
  87. if (anim->wsa)
  88. anim->wsa->displayFrame(frame, page, anim->x, anim->y, (flags == -1) ? (anim->wsaCopyParams & 0xF0FF) : flags, 0, 0);
  89. if (!page)
  90. _screen->updateScreen();
  91. }
  92. #ifdef ENABLE_LOL
  93. void TimAnimator::setupPart(int animIndex, int part, int firstFrame, int lastFrame, int cycles, int nextPart, int partDelay, int f, int sfxIndex, int sfxFrame) {
  94. AnimPart *a = &_animations[animIndex].parts[part];
  95. a->firstFrame = firstFrame;
  96. a->lastFrame = lastFrame;
  97. a->cycles = cycles;
  98. a->nextPart = nextPart;
  99. a->partDelay = partDelay;
  100. a->field_A = f;
  101. a->sfxIndex = sfxIndex;
  102. a->sfxFrame = sfxFrame;
  103. }
  104. void TimAnimator::start(int animIndex, int part) {
  105. if (!_vm || !_system || !_screen)
  106. return;
  107. Animation *anim = &_animations[animIndex];
  108. anim->curPart = part;
  109. AnimPart *p = &anim->parts[part];
  110. anim->enable = 1;
  111. anim->nextFrame = _system->getMillis() + anim->frameDelay * _vm->_tickLength;
  112. anim->curFrame = p->firstFrame;
  113. anim->cyclesCompleted = 0;
  114. // WORKAROUND for some bugged scripts that will try to display frames of non-existent animations
  115. if (anim->wsa)
  116. anim->wsa->displayFrame(anim->curFrame - 1, 0, anim->x, anim->y, 0, 0, 0);
  117. }
  118. void TimAnimator::stop(int animIndex) {
  119. Animation *anim = &_animations[animIndex];
  120. anim->enable = 0;
  121. anim->field_D = 0;
  122. if (animIndex == 5) {
  123. delete anim->wsa;
  124. anim->wsa = 0;
  125. }
  126. }
  127. void TimAnimator::update(int animIndex) {
  128. if (!_vm || !_system || !_screen)
  129. return;
  130. Animation *anim = &_animations[animIndex];
  131. if (!anim->enable || anim->nextFrame >= _system->getMillis())
  132. return;
  133. AnimPart *p = &anim->parts[anim->curPart];
  134. anim->nextFrame = 0;
  135. int step = 0;
  136. if (p->lastFrame >= p->firstFrame) {
  137. step = 1;
  138. anim->curFrame++;
  139. } else {
  140. step = -1;
  141. anim->curFrame--;
  142. }
  143. if (anim->curFrame == (p->lastFrame + step)) {
  144. anim->cyclesCompleted++;
  145. if ((anim->cyclesCompleted > p->cycles) || anim->field_D) {
  146. anim->lastPart = anim->curPart;
  147. if ((p->nextPart == -1) || (anim->field_D && p->field_A)) {
  148. anim->enable = 0;
  149. anim->field_D = 0;
  150. return;
  151. }
  152. anim->nextFrame += (p->partDelay * _vm->_tickLength);
  153. anim->curPart = p->nextPart;
  154. p = &anim->parts[anim->curPart];
  155. anim->curFrame = p->firstFrame;
  156. anim->cyclesCompleted = 0;
  157. } else {
  158. anim->curFrame = p->firstFrame;
  159. }
  160. }
  161. if (p->sfxIndex != -1 && p->sfxFrame == anim->curFrame)
  162. _vm->snd_playSoundEffect(p->sfxIndex, -1);
  163. anim->nextFrame += (anim->frameDelay * _vm->_tickLength);
  164. anim->wsa->displayFrame(anim->curFrame - 1, 0, anim->x, anim->y, 0, 0, 0);
  165. anim->nextFrame += _system->getMillis();
  166. }
  167. void TimAnimator::playPart(int animIndex, int firstFrame, int lastFrame, int delay) {
  168. if (!_vm || !_system || !_screen)
  169. return;
  170. Animation *anim = &_animations[animIndex];
  171. // WORKAROUND for some bugged scripts that will try to play invalid animations
  172. if (!anim->wsa)
  173. return;
  174. int step = (lastFrame >= firstFrame) ? 1 : -1;
  175. for (int i = firstFrame; i != (lastFrame + step); i += step) {
  176. uint32 next = _system->getMillis() + delay * _vm->_tickLength;
  177. if (anim->wsaCopyParams & 0x4000) {
  178. _screen->copyRegion(112, 0, 112, 0, 176, 120, 6, 2);
  179. anim->wsa->displayFrame(i - 1, 2, anim->x, anim->y, anim->wsaCopyParams & 0x1000 ? 0x5000 : 0x4000, _vm->_transparencyTable1, _vm->_transparencyTable2);
  180. _screen->copyRegion(112, 0, 112, 0, 176, 120, 2, 0);
  181. _screen->updateScreen();
  182. } else {
  183. anim->wsa->displayFrame(i - 1, 0, anim->x, anim->y, 0, 0, 0);
  184. _screen->updateScreen();
  185. }
  186. int32 del = (int32)(next - _system->getMillis());
  187. if (del > 0)
  188. _vm->delay(del, true);
  189. }
  190. }
  191. int TimAnimator::resetLastPart(int animIndex) {
  192. Animation *anim = &_animations[animIndex];
  193. int8 res = -1;
  194. SWAP(res, anim->lastPart);
  195. return res;
  196. }
  197. #endif
  198. } // End of namespace Kyra