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 "titanic/support/video_surface.h"
24 #include "titanic/support/image_decoders.h"
25 #include "titanic/support/screen_manager.h"
26 #include "titanic/support/transparency_surface.h"
27 #include "titanic/titanic.h"
28
29 namespace Titanic {
30
31 int CVideoSurface::_videoSurfaceCounter = 0;
32 byte CVideoSurface::_palette1[32][32];
33 byte CVideoSurface::_palette2[32][32];
34
CVideoSurface(CScreenManager * screenManager)35 CVideoSurface::CVideoSurface(CScreenManager *screenManager) :
36 _screenManager(screenManager), _rawSurface(nullptr), _movie(nullptr),
37 _pendingLoad(false), _flipVertically(false), _fastBlitFlag(false),
38 _transparencySurface(nullptr), _transparencyMode(TRANS_DEFAULT),
39 _freeTransparencySurface(DisposeAfterUse::NO), _hasFrame(true), _lockCount(0) {
40 _videoSurfaceNum = _videoSurfaceCounter++;
41 }
42
~CVideoSurface()43 CVideoSurface::~CVideoSurface() {
44 --_videoSurfaceCounter;
45
46 if (_freeTransparencySurface == DisposeAfterUse::YES)
47 delete _transparencySurface;
48 }
49
setupPalette(byte palette[32][32],byte val)50 void CVideoSurface::setupPalette(byte palette[32][32], byte val) {
51 for (uint idx1 = 0; idx1 < 32; ++idx1) {
52 for (uint idx2 = 0, base = 0; idx2 < 32; ++idx2, base += idx1) {
53 uint v = base / 31;
54 palette[idx1][idx2] = (byte)v;
55
56 if (val != 0xff && v != idx2) {
57 assert(0);
58 }
59 }
60 }
61 }
62
setSurface(CScreenManager * screenManager,DirectDrawSurface * surface)63 void CVideoSurface::setSurface(CScreenManager *screenManager, DirectDrawSurface *surface) {
64 _screenManager = screenManager;
65 _ddSurface = surface;
66 }
67
blitFrom(const Point & destPos,CVideoSurface * src,const Rect * srcRect)68 void CVideoSurface::blitFrom(const Point &destPos, CVideoSurface *src, const Rect *srcRect) {
69 if (loadIfReady() && src->loadIfReady() && _ddSurface && src->_ddSurface) {
70 Rect srcBounds, destBounds;
71 clipBounds(srcBounds, destBounds, src, srcRect, &destPos);
72
73 if (src->_flipVertically)
74 flippedBlitRect(srcBounds, destBounds, src);
75 else
76 blitRect(srcBounds, destBounds, src);
77 }
78 }
79
blitFrom(const Point & destPos,const Graphics::Surface * src)80 void CVideoSurface::blitFrom(const Point &destPos, const Graphics::Surface *src) {
81 lock();
82 _rawSurface->blitFrom(*src, destPos);
83 unlock();
84 }
85
clipBounds(Rect & srcRect,Rect & destRect,CVideoSurface * srcSurface,const Rect * subRect,const Point * destPos)86 void CVideoSurface::clipBounds(Rect &srcRect, Rect &destRect,
87 CVideoSurface *srcSurface, const Rect *subRect, const Point *destPos) {
88 // Figure out initial source rect and dest rect, based on whether
89 // specific subRect and/or destPos have been passed
90 if (destPos) {
91 destRect.left = destPos->x;
92 destRect.top = destPos->y;
93 } else {
94 destRect.left = destRect.top = 0;
95 }
96
97 if (subRect) {
98 destRect.right = destRect.left + subRect->width();
99 destRect.bottom = destRect.top + subRect->height();
100 srcRect = *subRect;
101 } else {
102 srcRect.right = srcRect.left + srcSurface->getWidth();
103 srcRect.bottom = srcRect.top + srcSurface->getHeight();
104 srcRect = Rect(0, 0, srcSurface->getWidth(), srcSurface->getHeight());
105 }
106
107 // Clip destination rect to be on-screen
108 if (destRect.left < 0) {
109 srcRect.left -= destRect.left;
110 destRect.left = 0;
111 }
112 if (destRect.top < 0) {
113 srcRect.top -= destRect.top;
114 destRect.top = 0;
115 }
116 if (destRect.right > getWidth()) {
117 srcRect.right += getWidth() - destRect.right;
118 destRect.right = getWidth();
119 }
120 if (destRect.bottom > getHeight()) {
121 srcRect.bottom += getHeight() - destRect.bottom;
122 destRect.bottom = getHeight();
123 }
124
125 // Clip source rect to be within the source surface
126 if (srcRect.left < 0) {
127 destRect.left -= srcRect.left;
128 srcRect.left = 0;
129 }
130 if (srcRect.top < 0) {
131 destRect.top -= srcRect.top;
132 srcRect.top = 0;
133 }
134 if (srcRect.right > srcSurface->getWidth()) {
135 destRect.right += srcSurface->getWidth() - srcRect.right;
136 srcRect.right = srcSurface->getWidth();
137 }
138 if (srcRect.bottom > srcSurface->getHeight()) {
139 destRect.bottom += srcSurface->getHeight() - srcRect.bottom;
140 srcRect.bottom = srcSurface->getHeight();
141 }
142
143 // Validate that the resulting rects are valid
144 if (destRect.left >= destRect.right || destRect.top >= destRect.bottom
145 || srcRect.left >= srcRect.right || srcRect.top >= srcRect.bottom)
146 error("Invalid rect");
147 }
148
blitRect(const Rect & srcRect,const Rect & destRect,CVideoSurface * src)149 void CVideoSurface::blitRect(const Rect &srcRect, const Rect &destRect, CVideoSurface *src) {
150 src->lock();
151 lock();
152
153 if (src->_fastBlitFlag) {
154 _rawSurface->blitFrom(*src->_rawSurface, srcRect, Point(destRect.left, destRect.top));
155 } else if (src->getTransparencySurface()) {
156 transBlitRect(srcRect, destRect, src, false);
157 } else if (lock()) {
158 if (src->lock()) {
159 const Graphics::ManagedSurface *srcSurface = src->_rawSurface;
160 Graphics::ManagedSurface *destSurface = _rawSurface;
161 const uint transColor = src->getTransparencyColor();
162
163 destSurface->transBlitFrom(*srcSurface, srcRect, destRect, transColor);
164
165 src->unlock();
166 }
167
168 unlock();
169 }
170 }
171
flippedBlitRect(const Rect & srcRect,const Rect & destRect,CVideoSurface * src)172 void CVideoSurface::flippedBlitRect(const Rect &srcRect, const Rect &destRect, CVideoSurface *src) {
173 if (src->getTransparencySurface()) {
174 transBlitRect(srcRect, destRect, src, true);
175 } else if (lock()) {
176 if (src->lock()) {
177 Graphics::ManagedSurface *srcSurface = src->_rawSurface;
178 Graphics::ManagedSurface *destSurface = _rawSurface;
179 const Graphics::Surface srcArea = srcSurface->getSubArea(srcRect);
180 const uint transColor = src->getTransparencyColor();
181
182 // Vertically flip the source area
183 Graphics::ManagedSurface flippedArea(srcArea.w, srcArea.h, srcArea.format);
184 for (int y = 0; y < srcArea.h; ++y) {
185 const byte *pSrc = (const byte *)srcArea.getBasePtr(0, y);
186 byte *pDest = (byte *)flippedArea.getBasePtr(0, flippedArea.h - y - 1);
187 Common::copy(pSrc, pSrc + srcArea.pitch, pDest);
188 }
189
190 destSurface->transBlitFrom(flippedArea,
191 Common::Point(destRect.left, destRect.top), transColor);
192
193 src->unlock();
194 }
195
196 unlock();
197 }
198 }
199
transBlitRect(const Rect & srcRect,const Rect & destRect,CVideoSurface * src,bool flipFlag)200 void CVideoSurface::transBlitRect(const Rect &srcRect, const Rect &destRect, CVideoSurface *src, bool flipFlag) {
201 assert(srcRect.width() == destRect.width() && srcRect.height() == destRect.height());
202 assert(src->getPixelDepth() == 2);
203
204 if (lock()) {
205 if (src->lock()) {
206 Graphics::ManagedSurface *srcSurface = src->_rawSurface;
207 Graphics::ManagedSurface *destSurface = _rawSurface;
208 Graphics::Surface destArea = destSurface->getSubArea(destRect);
209
210 const uint16 *srcPtr = (const uint16 *)srcSurface->getBasePtr(
211 srcRect.left, flipFlag ? srcRect.top : srcRect.bottom - 1);
212 uint16 *destPtr = (uint16 *)destArea.getBasePtr(0, destArea.h - 1);
213 bool isAlpha = src->_transparencyMode == TRANS_ALPHA0 ||
214 src->_transparencyMode == TRANS_ALPHA255;
215
216 CTransparencySurface transSurface(src->getTransparencySurface(), src->_transparencyMode);
217
218 for (int yCtr = 0; yCtr < srcRect.height(); ++yCtr) {
219 // Prepare for copying the line
220 const uint16 *lineSrcP = srcPtr;
221 uint16 *lineDestP = destPtr;
222 transSurface.setRow(flipFlag ? srcRect.top + yCtr : srcRect.bottom - yCtr - 1);
223 transSurface.setCol(srcRect.left);
224
225 for (int srcX = srcRect.left; srcX < srcRect.right; ++srcX) {
226 if (transSurface.isPixelOpaque())
227 *lineDestP = *lineSrcP;
228 else if (!transSurface.isPixelTransparent())
229 copyPixel(lineDestP, lineSrcP, transSurface.getAlpha() >> 3, srcSurface->format, isAlpha);
230
231 ++lineSrcP;
232 ++lineDestP;
233 transSurface.moveX();
234 }
235
236 // Move to next line
237 srcPtr = flipFlag ? srcPtr + (src->getPitch() / 2) :
238 srcPtr - (src->getPitch() / 2);
239 destPtr -= destArea.pitch / 2;
240 }
241
242 src->unlock();
243 }
244
245 unlock();
246 }
247 }
248
getTransparencyColor()249 uint CVideoSurface::getTransparencyColor() {
250 return getPixelDepth() == 2 ? 0xf81f : 0x7c1f;
251 }
252
hasFrame()253 bool CVideoSurface::hasFrame() {
254 if (_hasFrame) {
255 _hasFrame = false;
256 return true;
257 } else if (_movie) {
258 return _movie->hasVideoFrame();
259 } else {
260 return false;
261 }
262 }
263
264 #define RGB_SHIFT 3
copyPixel(uint16 * destP,const uint16 * srcP,byte alpha,const Graphics::PixelFormat & srcFormat,bool isAlpha)265 void CVideoSurface::copyPixel(uint16 *destP, const uint16 *srcP, byte alpha,
266 const Graphics::PixelFormat &srcFormat, bool isAlpha) {
267 const Graphics::PixelFormat destFormat = _ddSurface->getFormat();
268 alpha &= 0xff;
269 assert(alpha < 32);
270
271 // Get the source color
272 byte r, g, b;
273 srcFormat.colorToRGB(*srcP, r, g, b);
274 r >>= RGB_SHIFT;
275 g >>= RGB_SHIFT;
276 b >>= RGB_SHIFT;
277
278 if (isAlpha) {
279 r = _palette1[31 - alpha][r];
280 g = _palette1[31 - alpha][g];
281 b = _palette1[31 - alpha][b];
282 }
283
284 byte r2, g2, b2;
285 destFormat.colorToRGB(*destP, r2, g2, b2);
286 r2 >>= RGB_SHIFT;
287 g2 >>= RGB_SHIFT;
288 b2 >>= RGB_SHIFT;
289 r2 = _palette1[alpha][r2];
290 g2 = _palette1[alpha][g2];
291 b2 = _palette1[alpha][b2];
292
293 *destP = destFormat.RGBToColor((r + r2) << RGB_SHIFT,
294 (g + g2) << RGB_SHIFT, (b + b2) << RGB_SHIFT);
295 }
296
297 /*------------------------------------------------------------------------*/
298
OSVideoSurface(CScreenManager * screenManager,DirectDrawSurface * surface)299 OSVideoSurface::OSVideoSurface(CScreenManager *screenManager, DirectDrawSurface *surface) :
300 CVideoSurface(screenManager) {
301 _ddSurface = surface;
302 }
303
OSVideoSurface(CScreenManager * screenManager,const CResourceKey & key,bool pendingLoad)304 OSVideoSurface::OSVideoSurface(CScreenManager *screenManager, const CResourceKey &key, bool pendingLoad) :
305 CVideoSurface(screenManager) {
306 _ddSurface = nullptr;
307 _pendingLoad = pendingLoad;
308
309 if (_pendingLoad) {
310 loadResource(key);
311 } else {
312 _resourceKey = key;
313 load();
314 }
315 }
316
~OSVideoSurface()317 OSVideoSurface::~OSVideoSurface() {
318 if (_ddSurface)
319 _videoSurfaceCounter -= OSVideoSurface::freeSurface();
320 }
321
loadResource(const CResourceKey & key)322 void OSVideoSurface::loadResource(const CResourceKey &key) {
323 _resourceKey = key;
324 _pendingLoad = true;
325
326 if (hasSurface())
327 load();
328 }
329
loadTarga(const CResourceKey & key)330 void OSVideoSurface::loadTarga(const CResourceKey &key) {
331 // Decode the image
332 CTargaDecode decoder;
333 decoder.decode(*this, key.getString());
334
335 if (getPixelDepth() == 2)
336 shiftColors();
337
338 _resourceKey = key;
339
340 }
341
loadJPEG(const CResourceKey & key)342 void OSVideoSurface::loadJPEG(const CResourceKey &key) {
343 // Decode the image
344 CJPEGDecode decoder;
345 decoder.decode(*this, key.getString());
346
347 if (getPixelDepth() == 2)
348 shiftColors();
349
350 _resourceKey = key;
351 }
352
loadTarga(const CString & name)353 void OSVideoSurface::loadTarga(const CString &name) {
354 CResourceKey key(name);
355 loadTarga(key);
356 }
357
loadMovie(const CResourceKey & key,bool destroyFlag)358 void OSVideoSurface::loadMovie(const CResourceKey &key, bool destroyFlag) {
359 // Delete any prior movie
360 if (_movie) {
361 delete _movie;
362 _movie = nullptr;
363 }
364
365 // Create the new movie and load the first frame to the video surface
366 _movie = g_vm->_movieManager.createMovie(key, this);
367 _movie->setFrame(0);
368
369 // If flagged to destroy, then immediately destroy movie instance
370 if (destroyFlag) {
371 delete _movie;
372 _movie = nullptr;
373 }
374
375 _resourceKey = key;
376 }
377
lock()378 bool OSVideoSurface::lock() {
379 if (!loadIfReady())
380 return false;
381
382 ++_lockCount;
383 _rawSurface = _ddSurface->lock(nullptr, 0);
384 return true;
385 }
386
unlock()387 void OSVideoSurface::unlock() {
388 if (!--_lockCount) {
389 if (_rawSurface)
390 _ddSurface->unlock();
391 _rawSurface = nullptr;
392 }
393 }
394
hasSurface()395 bool OSVideoSurface::hasSurface() {
396 return _ddSurface != nullptr;
397 }
398
getWidth()399 int OSVideoSurface::getWidth() {
400 if (!loadIfReady())
401 error("Could not load resource");
402
403 return _ddSurface->getWidth();
404 }
405
getHeight()406 int OSVideoSurface::getHeight() {
407 if (!loadIfReady())
408 error("Could not load resource");
409
410 return _ddSurface->getHeight();
411 }
412
getPitch()413 int OSVideoSurface::getPitch() {
414 if (!loadIfReady())
415 error("Could not load resource");
416
417 return _ddSurface->getPitch();
418 }
419
getBpp()420 int OSVideoSurface::getBpp() {
421 if (!loadIfReady())
422 error("Could not load resource");
423
424 return getPixelDepth();
425 }
426
recreate(int width,int height,int bpp)427 void OSVideoSurface::recreate(int width, int height, int bpp) {
428 freeSurface();
429
430 _screenManager->resizeSurface(this, width, height, bpp);
431 if (_ddSurface)
432 _videoSurfaceCounter += _ddSurface->getSize();
433 }
434
resize(int width,int height,int bpp)435 void OSVideoSurface::resize(int width, int height, int bpp) {
436 if (!_ddSurface || _ddSurface->getWidth() != width ||
437 _ddSurface->getHeight() != height)
438 recreate(width, height, bpp);
439 }
440
detachSurface()441 void OSVideoSurface::detachSurface() {
442 _ddSurface = nullptr;
443 }
444
getPixelDepth()445 int OSVideoSurface::getPixelDepth() {
446 if (!loadIfReady())
447 error("Could not load resource");
448
449 lock();
450
451 int result = _rawSurface->format.bytesPerPixel;
452 if (result == 1)
453 // Paletted 8-bit images don't store the color directly in the pixels
454 result = 0;
455
456 unlock();
457 return result;
458 }
459
load()460 bool OSVideoSurface::load() {
461 if (!_resourceKey.scanForFile())
462 return false;
463
464 switch (_resourceKey.fileTypeSuffix()) {
465 case FILETYPE_IMAGE:
466 switch (_resourceKey.imageTypeSuffix()) {
467 case IMAGETYPE_TARGA:
468 loadTarga(_resourceKey);
469 break;
470 case IMAGETYPE_JPEG:
471 loadJPEG(_resourceKey);
472 break;
473 default:
474 break;
475 }
476 return true;
477
478 case FILETYPE_MOVIE:
479 loadMovie(_resourceKey);
480 return true;
481
482 default:
483 return false;
484 }
485 }
486
getPixel(const Common::Point & pt)487 uint16 OSVideoSurface::getPixel(const Common::Point &pt) {
488 if (!loadIfReady())
489 return 0;
490
491 if (pt.x >= 0 && pt.y >= 0 && pt.x < getWidth() && pt.y < getHeight()) {
492 if (_transparencySurface) {
493 // WORKAROUND: Original had the setRow _flipVertically check in reverse.
494 // Pretty sure putting it the way is below is the correct way
495 CTransparencySurface transSurface(&_transparencySurface->rawSurface(), _transparencyMode);
496 transSurface.setRow(_flipVertically ? getHeight() - pt.y - 1 : pt.y);
497 transSurface.setCol(pt.x);
498
499 if (transSurface.isPixelTransparent())
500 return getTransparencyColor();
501 }
502
503 lock();
504 uint16 pixel = *(uint16 *)_rawSurface->getBasePtr(pt.x, pt.y);
505 unlock();
506 return pixel;
507 } else {
508 return getTransparencyColor();
509 }
510 }
511
setPixel(const Point & pt,uint pixel)512 void OSVideoSurface::setPixel(const Point &pt, uint pixel) {
513 assert(getPixelDepth() == 2);
514
515 uint16 *pixelP = (uint16 *)_rawSurface->getBasePtr(pt.x, pt.y);
516 *pixelP = pixel;
517 }
518
shiftColors()519 void OSVideoSurface::shiftColors() {
520 if (!loadIfReady())
521 return;
522
523 // Currently no further processing is needed, since for ScummVM,
524 // we already convert 16-bit surfaces as soon as they're loaded
525 }
526
clear()527 void OSVideoSurface::clear() {
528 if (!loadIfReady())
529 error("Could not load resource");
530
531 _ddSurface->fill(nullptr, 0);
532 }
533
playMovie(uint flags,CGameObject * obj)534 void OSVideoSurface::playMovie(uint flags, CGameObject *obj) {
535 if (loadIfReady() && _movie)
536 _movie->play(flags, obj);
537 }
538
playMovie(uint startFrame,uint endFrame,uint flags,CGameObject * obj)539 void OSVideoSurface::playMovie(uint startFrame, uint endFrame, uint flags, CGameObject *obj) {
540 if (loadIfReady() && _movie) {
541 _movie->play(startFrame, endFrame, flags, obj);
542 _movie->pause();
543 }
544 }
545
playMovie(uint startFrame,uint endFrame,uint initialFrame,uint flags,CGameObject * obj)546 void OSVideoSurface::playMovie(uint startFrame, uint endFrame, uint initialFrame, uint flags, CGameObject *obj) {
547 if (loadIfReady() && _movie) {
548 _movie->play(startFrame, endFrame, initialFrame, flags, obj);
549 }
550 }
551
stopMovie()552 void OSVideoSurface::stopMovie() {
553 if (_movie)
554 _movie->stop();
555 }
556
setMovieFrame(uint frameNumber)557 void OSVideoSurface::setMovieFrame(uint frameNumber) {
558 if (loadIfReady() && _movie)
559 _movie->setFrame(frameNumber);
560 }
561
addMovieEvent(int frameNumber,CGameObject * obj)562 void OSVideoSurface::addMovieEvent(int frameNumber, CGameObject *obj) {
563 if (_movie)
564 _movie->addEvent(frameNumber, obj);
565 }
566
setMovieFrameRate(double rate)567 void OSVideoSurface::setMovieFrameRate(double rate) {
568 if (_movie)
569 _movie->setFrameRate(rate);
570 }
571
getMovieRangeInfo() const572 const CMovieRangeInfoList *OSVideoSurface::getMovieRangeInfo() const {
573 return _movie ? _movie->getMovieRangeInfo() : nullptr;
574 }
575
flipVertically(bool needsLock)576 void OSVideoSurface::flipVertically(bool needsLock) {
577 if (!loadIfReady() || !_flipVertically)
578 return;
579
580 if (needsLock)
581 lock();
582
583 byte lineBuffer[SCREEN_WIDTH * 2];
584 int pitch = getBpp() * getWidth();
585 assert(pitch < (SCREEN_WIDTH * 2));
586
587 for (int yp = 0; yp < (_rawSurface->h / 2); ++yp) {
588 byte *line1P = (byte *)_rawSurface->getBasePtr(0, yp);
589 byte *line2P = (byte *)_rawSurface->getBasePtr(0, _rawSurface->h - yp - 1);
590
591 Common::copy(line1P, line1P + pitch, lineBuffer);
592 Common::copy(line2P, line2P + pitch, line1P);
593 Common::copy(lineBuffer, lineBuffer + pitch, line1P);
594 }
595
596 _flipVertically = false;
597 if (needsLock)
598 unlock();
599 }
600
loadIfReady()601 bool OSVideoSurface::loadIfReady() {
602 _videoSurfaceNum = _videoSurfaceCounter;
603
604 if (hasSurface()) {
605 return true;
606 } else if (_pendingLoad) {
607 _hasFrame = true;
608 load();
609 return true;
610 } else {
611 return false;
612 }
613 }
614
transPixelate()615 void OSVideoSurface::transPixelate() {
616 if (!loadIfReady())
617 return;
618
619 lock();
620 Graphics::ManagedSurface *surface = _rawSurface;
621 uint transColor = getTransparencyColor();
622 // TODO: Check whether color is correct
623 uint pixelColor = surface->format.RGBToColor(0x50, 0, 0);
624
625 for (int yp = 0; yp < surface->h; ++yp) {
626 uint16 *pixelsP = (uint16 *)surface->getBasePtr(0, yp);
627 bool bitFlag = (yp % 2) == 0;
628 int replaceCtr = yp & 3;
629
630 for (int xp = 0; xp < surface->w; ++xp, ++pixelsP) {
631 if (bitFlag && *pixelsP == transColor && replaceCtr == 0)
632 *pixelsP = pixelColor;
633
634 bitFlag = !bitFlag;
635 replaceCtr = (replaceCtr + 1) & 3;
636 }
637 }
638
639 surface->markAllDirty();
640 unlock();
641 }
642
dupMovieTransparency() const643 Graphics::ManagedSurface *OSVideoSurface::dupMovieTransparency() const {
644 return _movie ? _movie->duplicateTransparency() : nullptr;
645 }
646
freeSurface()647 int OSVideoSurface::freeSurface() {
648 if (!_ddSurface)
649 return 0;
650 int surfaceSize = _ddSurface->getSize();
651
652 delete _movie;
653 _movie = nullptr;
654 delete _ddSurface;
655 _ddSurface = nullptr;
656
657 return surfaceSize;
658 }
659
getBasePtr(int x,int y)660 uint16 *OSVideoSurface::getBasePtr(int x, int y) {
661 assert(_rawSurface);
662 return (uint16 *)_rawSurface->getBasePtr(x, y);
663 }
664
665 } // End of namespace Titanic
666