2017-05-26 05:24:38 +02:00
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers , whose names
* are too numerous to list here . Please refer to the COPYRIGHT
* file distributed with this source distribution .
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; either version 2
* of the License , or ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA .
*
*/
2017-05-29 07:51:40 +02:00
# include "image/png.h"
2017-06-05 19:10:47 +02:00
2017-07-20 19:08:53 +02:00
# include "sludge/event.h"
2017-06-05 19:10:47 +02:00
# include "sludge/fileset.h"
2017-07-19 13:37:54 +02:00
# include "sludge/graphics.h"
2017-07-20 19:08:53 +02:00
# include "sludge/imgloader.h"
# include "sludge/newfatal.h"
2017-12-19 21:24:31 +01:00
# include "sludge/speech.h"
2017-07-15 15:33:43 +02:00
# include "sludge/statusba.h"
2017-06-05 19:10:47 +02:00
# include "sludge/sludge.h"
# include "sludge/sludger.h"
# include "sludge/variable.h"
2017-07-20 00:41:13 +02:00
# include "sludge/version.h"
2021-05-07 01:29:32 +02:00
# include "sludge/zbuffer.h"
2017-05-26 05:24:38 +02:00
2017-05-26 21:25:11 +02:00
namespace Sludge {
2017-05-26 05:24:38 +02:00
2021-05-13 23:48:25 +02:00
void GraphicsManager : : killParallax ( ) {
if ( ! _parallaxLayers )
return ;
2017-07-19 13:37:54 +02:00
2021-05-13 23:48:25 +02:00
for ( ParallaxLayers : : iterator it = _parallaxLayers - > begin ( ) ; it ! = _parallaxLayers - > end ( ) ; + + it ) {
2017-07-19 13:37:54 +02:00
( * it ) - > surface . free ( ) ;
delete ( * it ) ;
( * it ) = nullptr ;
}
2021-05-13 23:48:25 +02:00
_parallaxLayers - > clear ( ) ;
delete _parallaxLayers ;
_parallaxLayers = nullptr ;
2017-07-19 13:37:54 +02:00
}
2021-05-13 23:48:25 +02:00
bool GraphicsManager : : loadParallax ( uint16 v , uint16 fracX , uint16 fracY ) {
if ( ! _parallaxLayers )
_parallaxLayers = new ParallaxLayers ;
2017-07-19 13:37:54 +02:00
setResourceForFatal ( v ) ;
if ( ! g_sludge - > _resMan - > openFileFromNum ( v ) )
return fatal ( " Can't open parallax image " ) ;
ParallaxLayer * nP = new ParallaxLayer ;
if ( ! checkNew ( nP ) )
return false ;
2021-05-13 23:48:25 +02:00
_parallaxLayers - > push_back ( nP ) ;
2017-07-19 13:37:54 +02:00
2021-05-06 15:00:12 +02:00
if ( ! ImgLoader : : loadImage ( v , " parallax " , g_sludge - > _resMan - > getData ( ) , & nP - > surface , 0 ) )
2017-07-19 13:37:54 +02:00
return false ;
nP - > fileNum = v ;
nP - > fractionX = fracX ;
nP - > fractionY = fracY ;
// 65535 is the value of AUTOFIT constant in Sludge
if ( fracX = = 65535 ) {
nP - > wrapS = false ;
2021-05-14 00:28:11 +02:00
if ( nP - > surface . w < _winWidth ) {
fatal ( " For AUTOFIT parallax backgrounds, the image must be at least as wide as the game window/screen. " ) ;
return false ;
}
2017-07-19 13:37:54 +02:00
} else {
nP - > wrapS = true ;
}
if ( fracY = = 65535 ) {
nP - > wrapT = false ;
2021-05-14 00:28:11 +02:00
if ( nP - > surface . h < _winHeight ) {
fatal ( " For AUTOFIT parallax backgrounds, the image must be at least as tall as the game window/screen. " ) ;
return false ;
}
2017-07-19 13:37:54 +02:00
} else {
nP - > wrapT = true ;
}
g_sludge - > _resMan - > finishAccess ( ) ;
setResourceForFatal ( - 1 ) ;
return true ;
}
2021-05-13 23:48:25 +02:00
void GraphicsManager : : drawParallax ( ) {
if ( ! _parallaxLayers | | _parallaxLayers - > empty ( ) )
return ;
2021-05-13 23:54:03 +02:00
// TODO: simulate image repeating effect
warning ( " Drawing parallaxStuff " ) ;
// display parallax from bottom to top
for ( ParallaxLayers : : iterator it = _parallaxLayers - > begin ( ) ; it ! = _parallaxLayers - > end ( ) ; + + it ) {
2021-05-14 00:28:11 +02:00
ParallaxLayer * p = * it ;
p - > cameraX = sortOutPCamera ( _cameraX , p - > fractionX , ( int ) ( _sceneWidth - ( float ) _winWidth / _cameraZoom ) , ( int ) ( p - > surface . w - ( float ) _winWidth / _cameraZoom ) ) ;
p - > cameraY = sortOutPCamera ( _cameraY , p - > fractionY , ( int ) ( _sceneHeight - ( float ) _winHeight / _cameraZoom ) , ( int ) ( p - > surface . h - ( float ) _winHeight / _cameraZoom ) ) ;
2021-05-13 23:54:03 +02:00
2021-05-14 00:28:11 +02:00
uint w = p - > wrapS ? _sceneWidth : p - > surface . w ;
uint h = p - > wrapT ? _sceneHeight : p - > surface . h ;
2021-05-13 23:54:03 +02:00
2021-05-14 00:28:11 +02:00
warning ( " camX: %d camY: %d dims: %d x %d sceneDims: %d x %d winDims: %d x %d surf: %d x %d " , p - > cameraX , p - > cameraY , w , h , _sceneWidth , _sceneHeight , _winWidth , _winHeight , p - > surface . w , p - > surface . h ) ;
2021-05-13 23:54:03 +02:00
2017-07-19 13:37:54 +02:00
#if 0
2021-05-13 23:54:03 +02:00
const GLfloat vertices [ ] = {
( GLfloat ) - ( * it ) - > cameraX , ( GLfloat ) - ( * it ) - > cameraY , 0.1f ,
w - ( * it ) - > cameraX , ( GLfloat ) - ( * it ) - > cameraY , 0.1f ,
( GLfloat ) - ( * it ) - > cameraX , h - ( * it ) - > cameraY , 0.1f ,
w - ( * it ) - > cameraX , h - ( * it ) - > cameraY , 0.1f
} ;
const GLfloat texCoords [ ] = {
0.0f , 0.0f ,
texw , 0.0f ,
0.0f , texh ,
texw , texh
} ;
2017-07-19 13:37:54 +02:00
drawQuad ( shader . smartScaler , vertices , 1 , texCoords ) ;
# endif
2021-05-13 23:54:03 +02:00
}
2017-07-19 13:37:54 +02:00
}
2021-05-13 23:48:25 +02:00
void GraphicsManager : : saveParallax ( Common : : WriteStream * stream ) {
2017-07-19 13:37:54 +02:00
ParallaxLayers : : iterator it ;
2021-05-13 23:48:25 +02:00
for ( it = _parallaxLayers - > begin ( ) ; it ! = _parallaxLayers - > end ( ) ; + + it ) {
2017-07-19 13:37:54 +02:00
stream - > writeByte ( 1 ) ;
stream - > writeUint16BE ( ( * it ) - > fileNum ) ;
stream - > writeUint16BE ( ( * it ) - > fractionX ) ;
stream - > writeUint16BE ( ( * it ) - > fractionY ) ;
}
}
2017-07-20 00:41:13 +02:00
void GraphicsManager : : nosnapshot ( ) {
if ( _snapshotSurface . getPixels ( ) )
_snapshotSurface . free ( ) ;
2017-05-26 05:24:38 +02:00
}
2017-07-20 00:41:13 +02:00
void GraphicsManager : : saveSnapshot ( Common : : WriteStream * stream ) {
if ( _snapshotSurface . getPixels ( ) ) {
2017-05-30 09:59:56 +02:00
stream - > writeByte ( 1 ) ; // 1 for snapshot follows
2017-07-20 00:41:13 +02:00
Image : : writePNG ( * stream , _snapshotSurface ) ;
2017-05-26 05:24:38 +02:00
} else {
2017-05-30 09:59:56 +02:00
stream - > writeByte ( 0 ) ;
2017-05-26 05:24:38 +02:00
}
2017-05-27 20:16:54 +02:00
}
2017-05-26 05:24:38 +02:00
2017-07-20 00:41:13 +02:00
bool GraphicsManager : : snapshot ( ) {
2017-05-26 05:24:38 +02:00
nosnapshot ( ) ;
2017-05-29 07:51:40 +02:00
if ( ! freeze ( ) )
return false ;
2017-05-26 05:24:38 +02:00
2017-07-20 02:48:21 +02:00
// draw snapshot to rendersurface
2017-07-15 15:33:43 +02:00
displayBase ( ) ;
2017-12-19 21:24:31 +01:00
_vm - > _speechMan - > display ( ) ;
2021-05-06 23:42:38 +02:00
g_sludge - > _statusBar - > draw ( ) ;
2017-05-26 05:24:38 +02:00
2017-07-15 15:33:43 +02:00
// copy backdrop to snapshot
2017-07-20 02:48:21 +02:00
_snapshotSurface . copyFrom ( _renderSurface ) ;
2017-07-15 15:33:43 +02:00
2017-05-26 05:24:38 +02:00
unfreeze ( false ) ;
return true ;
}
2017-07-20 00:41:13 +02:00
bool GraphicsManager : : restoreSnapshot ( Common : : SeekableReadStream * stream ) {
2021-05-06 15:00:12 +02:00
if ( ! ( ImgLoader : : loadImage ( - 1 , NULL , stream , & _snapshotSurface ) ) ) {
2017-05-26 05:24:38 +02:00
return false ;
}
return true ;
}
2017-07-20 00:41:13 +02:00
void GraphicsManager : : killBackDrop ( ) {
if ( _backdropSurface . getPixels ( ) )
_backdropSurface . free ( ) ;
_backdropExists = false ;
2017-05-26 05:24:38 +02:00
}
2017-07-20 00:41:13 +02:00
void GraphicsManager : : killLightMap ( ) {
if ( _lightMap . getPixels ( ) ) {
_lightMap . free ( ) ;
2017-05-31 01:11:28 +02:00
}
2017-07-20 00:41:13 +02:00
_lightMapNumber = 0 ;
2017-05-26 05:24:38 +02:00
}
2017-07-20 00:41:13 +02:00
bool GraphicsManager : : reserveBackdrop ( ) {
_cameraX = 0 ;
_cameraY = 0 ;
2017-07-20 19:08:53 +02:00
_vm - > _evtMan - > mouseX ( ) = ( int ) ( ( float ) _vm - > _evtMan - > mouseX ( ) * _cameraZoom ) ;
_vm - > _evtMan - > mouseY ( ) = ( int ) ( ( float ) _vm - > _evtMan - > mouseY ( ) * _cameraZoom ) ;
2017-07-20 00:41:13 +02:00
_cameraZoom = 1.0 ;
2017-07-20 19:08:53 +02:00
_vm - > _evtMan - > mouseX ( ) = ( int ) ( ( float ) _vm - > _evtMan - > mouseX ( ) / _cameraZoom ) ;
_vm - > _evtMan - > mouseY ( ) = ( int ) ( ( float ) _vm - > _evtMan - > mouseY ( ) / _cameraZoom ) ;
2017-05-26 05:24:38 +02:00
2017-08-03 08:04:00 +02:00
_backdropSurface . create ( _sceneWidth , _sceneHeight , * _vm - > getScreenPixelFormat ( ) ) ;
2017-05-26 05:24:38 +02:00
return true ;
}
2017-07-20 00:41:13 +02:00
void GraphicsManager : : killAllBackDrop ( ) {
2017-05-26 05:24:38 +02:00
killLightMap ( ) ;
killBackDrop ( ) ;
2017-07-19 13:37:54 +02:00
g_sludge - > _gfxMan - > killParallax ( ) ;
2017-05-26 05:24:38 +02:00
killZBuffer ( ) ;
2017-05-31 01:11:28 +02:00
}
2017-07-20 00:41:13 +02:00
bool GraphicsManager : : resizeBackdrop ( int x , int y ) {
2017-08-02 16:35:09 +02:00
debugC ( 1 , kSludgeDebugGraphics , " Load HSI " ) ;
2017-07-20 00:41:13 +02:00
_sceneWidth = x ;
_sceneHeight = y ;
2017-05-26 05:24:38 +02:00
return reserveBackdrop ( ) ;
}
2017-07-20 00:41:13 +02:00
bool GraphicsManager : : killResizeBackdrop ( int x , int y ) {
2017-05-31 01:11:28 +02:00
killAllBackDrop ( ) ;
return resizeBackdrop ( x , y ) ;
}
2017-07-20 00:41:13 +02:00
void GraphicsManager : : loadBackDrop ( int fileNum , int x , int y ) {
2017-08-02 16:35:09 +02:00
debugC ( 1 , kSludgeDebugGraphics , " Load back drop of num %i at position %i, %i " , fileNum , x , y ) ;
2017-05-26 05:24:38 +02:00
setResourceForFatal ( fileNum ) ;
2017-07-18 19:03:45 +02:00
if ( ! g_sludge - > _resMan - > openFileFromNum ( fileNum ) ) {
2017-05-26 05:24:38 +02:00
fatal ( " Can't load overlay image " ) ;
return ;
}
2021-05-06 15:00:12 +02:00
if ( ! loadHSI ( fileNum , g_sludge - > _resMan - > getData ( ) , x , y , false ) ) {
2017-07-20 00:41:13 +02:00
Common : : String mess = Common : : String : : format ( " Can't paste overlay image outside scene dimensions \n \n X = %i \n Y = %i \n Width = %i \n Height = %i " , x , y , _sceneWidth , _sceneHeight ) ;
2017-05-26 05:24:38 +02:00
fatal ( mess ) ;
}
2017-07-18 19:03:45 +02:00
g_sludge - > _resMan - > finishAccess ( ) ;
2017-05-26 05:24:38 +02:00
setResourceForFatal ( - 1 ) ;
2017-07-01 22:01:26 +02:00
2017-07-20 01:55:21 +02:00
// reset zBuffer
if ( _zBuffer - > originalNum > = 0 ) {
setZBuffer ( _zBuffer - > originalNum ) ;
2017-07-01 22:01:26 +02:00
}
2017-05-26 05:24:38 +02:00
}
2017-07-20 00:41:13 +02:00
void GraphicsManager : : mixBackDrop ( int fileNum , int x , int y ) {
2017-08-02 16:35:09 +02:00
debugC ( 1 , kSludgeDebugGraphics , " Mix back drop of num %i at position %i, %i " , fileNum , x , y ) ;
2017-05-26 05:24:38 +02:00
setResourceForFatal ( fileNum ) ;
2017-07-18 19:03:45 +02:00
if ( ! g_sludge - > _resMan - > openFileFromNum ( fileNum ) ) {
2017-05-26 05:24:38 +02:00
fatal ( " Can't load overlay image " ) ;
return ;
}
2021-05-06 15:00:12 +02:00
if ( ! mixHSI ( fileNum , g_sludge - > _resMan - > getData ( ) , x , y ) ) {
2017-05-26 05:24:38 +02:00
fatal ( " Can't paste overlay image outside screen dimensions " ) ;
}
2017-07-18 19:03:45 +02:00
g_sludge - > _resMan - > finishAccess ( ) ;
2017-05-26 05:24:38 +02:00
setResourceForFatal ( - 1 ) ;
}
2017-07-20 00:41:13 +02:00
void GraphicsManager : : blankScreen ( int x1 , int y1 , int x2 , int y2 ) {
2017-07-20 01:55:21 +02:00
// in case of no backdrop added at all, create it
2017-07-20 00:41:13 +02:00
if ( ! _backdropSurface . getPixels ( ) ) {
2017-07-20 01:55:21 +02:00
_backdropSurface . create ( _winWidth , _winHeight , _renderSurface . format ) ;
2017-07-04 23:59:02 +02:00
}
2017-05-26 05:24:38 +02:00
2017-05-29 07:51:40 +02:00
if ( y1 < 0 )
y1 = 0 ;
if ( x1 < 0 )
x1 = 0 ;
2017-07-20 00:41:13 +02:00
if ( x2 > ( int ) _sceneWidth )
x2 = ( int ) _sceneWidth ;
if ( y2 > ( int ) _sceneHeight )
y2 = ( int ) _sceneHeight ;
2017-05-26 05:24:38 +02:00
2017-07-20 00:41:13 +02:00
_backdropSurface . fillRect ( Common : : Rect ( x1 , y1 , x2 , y2 ) , _currentBlankColour ) ;
2017-08-02 09:15:40 +02:00
// reset zBuffer
if ( _zBuffer - > originalNum > = 0 ) {
setZBuffer ( _zBuffer - > originalNum ) ;
}
2017-07-20 00:41:13 +02:00
}
void GraphicsManager : : blankAllScreen ( ) {
blankScreen ( 0 , 0 , _sceneWidth , _sceneHeight ) ;
2017-05-26 05:24:38 +02:00
}
2017-07-15 16:20:16 +02:00
// This function is very useful for scrolling credits, but very little else
2017-07-20 00:41:13 +02:00
void GraphicsManager : : hardScroll ( int distance ) {
2017-07-15 16:20:16 +02:00
// scroll 0 distance, return
2017-05-29 07:51:40 +02:00
if ( ! distance )
return ;
2017-05-26 05:24:38 +02:00
2017-07-15 16:20:16 +02:00
// blank screen
2017-07-20 00:41:13 +02:00
blankAllScreen ( ) ;
2017-05-26 05:24:38 +02:00
2017-07-15 16:20:16 +02:00
// scroll more than backdrop height, screen stay blank
2017-07-20 00:41:13 +02:00
if ( ABS ( distance ) > = ( int ) _sceneHeight ) {
2017-07-15 16:20:16 +02:00
return ;
}
2017-05-26 05:24:38 +02:00
2017-07-15 16:20:16 +02:00
// copy part of the backdrop to it
if ( distance > 0 ) {
2017-07-20 00:41:13 +02:00
_backdropSurface . copyRectToSurface ( _origBackdropSurface , 0 , 0 ,
Common : : Rect ( 0 , distance , _backdropSurface . w , _backdropSurface . h ) ) ;
2017-07-15 16:20:16 +02:00
} else {
2017-07-20 00:41:13 +02:00
_backdropSurface . copyRectToSurface ( _origBackdropSurface , 0 , - distance ,
Common : : Rect ( 0 , 0 , _backdropSurface . w , _backdropSurface . h + distance ) ) ;
2017-05-26 05:24:38 +02:00
}
}
2017-07-20 00:41:13 +02:00
void GraphicsManager : : drawLine ( uint x1 , uint y1 , uint x2 , uint y2 ) {
_backdropSurface . drawLine ( x1 , y1 , x2 , y2 , _backdropSurface . format . ARGBToColor ( 255 , 0 , 0 , 0 ) ) ;
2017-05-26 05:24:38 +02:00
}
2017-07-20 00:41:13 +02:00
void GraphicsManager : : drawVerticalLine ( uint x , uint y1 , uint y2 ) {
drawLine ( x , y1 , x , y2 ) ;
2017-05-26 05:24:38 +02:00
}
2017-07-20 00:41:13 +02:00
void GraphicsManager : : drawHorizontalLine ( uint x1 , uint y , uint x2 ) {
drawLine ( x1 , y , x2 , y ) ;
2017-05-26 05:24:38 +02:00
}
2017-07-20 00:41:13 +02:00
void GraphicsManager : : darkScreen ( ) {
Graphics : : TransparentSurface tmp ( _backdropSurface , false ) ;
2021-05-12 23:09:58 +02:00
tmp . blit ( _backdropSurface , 0 , 0 , Graphics : : FLIP_NONE , nullptr , TS_ARGB ( 255 > > 1 , 0 , 0 , 0 ) ) ;
2017-08-02 09:15:40 +02:00
// reset zBuffer
if ( _zBuffer - > originalNum > = 0 ) {
setZBuffer ( _zBuffer - > originalNum ) ;
}
2017-05-26 05:24:38 +02:00
}
2017-07-20 00:41:13 +02:00
void GraphicsManager : : drawBackDrop ( ) {
2017-07-15 15:58:28 +02:00
// TODO: apply lightmap shader
2017-07-20 00:41:13 +02:00
drawParallax ( ) ;
2017-05-26 05:24:38 +02:00
2017-07-20 00:41:13 +02:00
if ( ! _backdropExists )
return ;
2017-07-15 15:58:28 +02:00
// draw backdrop
2017-07-20 00:41:13 +02:00
Graphics : : TransparentSurface tmp ( _backdropSurface , false ) ;
2019-06-17 23:56:51 +02:00
tmp . blit ( _renderSurface , - _cameraX , - _cameraY ) ;
2017-05-26 05:24:38 +02:00
}
2017-07-20 00:41:13 +02:00
bool GraphicsManager : : loadLightMap ( int v ) {
2017-05-26 05:24:38 +02:00
setResourceForFatal ( v ) ;
2017-07-18 19:03:45 +02:00
if ( ! g_sludge - > _resMan - > openFileFromNum ( v ) )
2017-06-05 11:49:19 +02:00
return fatal ( " Can't open light map. " ) ;
2017-05-26 05:24:38 +02:00
2017-05-31 01:11:28 +02:00
killLightMap ( ) ;
2017-07-20 00:41:13 +02:00
_lightMapNumber = v ;
2017-08-08 18:15:36 +02:00
_lightMap . create ( _sceneWidth , _sceneWidth , * _vm - > getScreenPixelFormat ( ) ) ;
2017-05-26 05:24:38 +02:00
2017-08-08 18:15:36 +02:00
Graphics : : TransparentSurface tmp ;
2021-05-06 15:00:12 +02:00
if ( ! ImgLoader : : loadImage ( v , " lightmap " , g_sludge - > _resMan - > getData ( ) , & tmp ) )
2017-05-31 01:11:28 +02:00
return false ;
2017-05-26 05:24:38 +02:00
2017-08-08 18:15:36 +02:00
if ( tmp . w ! = _sceneWidth | | tmp . h ! = _sceneHeight ) {
if ( _lightMapMode = = LIGHTMAPMODE_HOTSPOT ) {
2017-05-26 05:24:38 +02:00
return fatal ( " Light map width and height don't match scene width and height. That is required for lightmaps in HOTSPOT mode. " ) ;
2017-08-08 18:15:36 +02:00
} else if ( _lightMapMode = = LIGHTMAPMODE_PIXEL ) {
2019-10-03 04:57:18 +01:00
tmp . blit ( _lightMap , 0 , 0 , Graphics : : FLIP_NONE , nullptr , TS_ARGB ( ( uint ) 255 , ( uint ) 255 , ( uint ) 255 , ( uint ) 255 ) , ( int ) _sceneWidth , ( int ) _sceneHeight ) ;
2017-08-08 18:15:36 +02:00
} else {
_lightMap . copyFrom ( tmp ) ;
2017-05-26 05:24:38 +02:00
}
2017-08-08 18:15:36 +02:00
} else {
_lightMap . copyFrom ( tmp ) ;
2017-05-26 05:24:38 +02:00
}
2017-08-08 18:15:36 +02:00
tmp . free ( ) ;
2017-07-18 19:03:45 +02:00
g_sludge - > _resMan - > finishAccess ( ) ;
2017-05-26 05:24:38 +02:00
setResourceForFatal ( - 1 ) ;
return true ;
}
2017-07-20 00:41:13 +02:00
void GraphicsManager : : saveLightMap ( Common : : WriteStream * stream ) {
if ( _lightMap . getPixels ( ) ) {
stream - > writeByte ( 1 ) ;
stream - > writeUint16BE ( _lightMapNumber ) ;
} else {
stream - > writeByte ( 0 ) ;
}
stream - > writeByte ( _lightMapMode ) ;
2018-04-29 09:52:48 +02:00
stream - > writeByte ( _fadeMode ) ;
2017-07-20 00:41:13 +02:00
}
bool GraphicsManager : : loadLightMap ( int ssgVersion , Common : : SeekableReadStream * stream ) {
if ( stream - > readByte ( ) ) {
if ( ! loadLightMap ( stream - > readUint16BE ( ) ) )
return false ;
}
if ( ssgVersion > = VERSION ( 1 , 4 ) ) {
_lightMapMode = stream - > readByte ( ) % 3 ;
}
2018-04-29 09:52:48 +02:00
_fadeMode = stream - > readByte ( ) ;
2017-07-20 00:41:13 +02:00
return true ;
}
2021-05-06 15:00:12 +02:00
bool GraphicsManager : : loadHSI ( int num , Common : : SeekableReadStream * stream , int x , int y , bool reserve ) {
2017-08-02 16:35:09 +02:00
debugC ( 1 , kSludgeDebugGraphics , " Load HSI " ) ;
2017-05-31 01:11:28 +02:00
if ( reserve ) {
killAllBackDrop ( ) ; // kill all
}
2017-05-28 10:41:01 +02:00
2017-07-20 01:55:21 +02:00
Graphics : : Surface tmp ;
2021-05-06 15:00:12 +02:00
if ( ! ImgLoader : : loadImage ( num , " hsi " , stream , & tmp , ( int ) reserve ) )
2017-05-28 10:41:01 +02:00
return false ;
2017-05-31 01:11:28 +02:00
2017-07-20 01:55:21 +02:00
uint realPicWidth = tmp . w ;
uint realPicHeight = tmp . h ;
2017-05-31 01:11:28 +02:00
2017-07-15 17:33:10 +02:00
// resize backdrop
if ( reserve ) {
2017-06-05 11:49:19 +02:00
if ( ! resizeBackdrop ( realPicWidth , realPicHeight ) )
return false ;
2017-05-31 01:11:28 +02:00
}
if ( x = = IN_THE_CENTRE )
2017-07-20 00:41:13 +02:00
x = ( _sceneWidth - realPicWidth ) > > 1 ;
2017-05-31 01:11:28 +02:00
if ( y = = IN_THE_CENTRE )
2017-07-20 00:41:13 +02:00
y = ( _sceneHeight - realPicHeight ) > > 1 ;
if ( x < 0 | | x + realPicWidth > _sceneWidth | | y < 0 | | y + realPicHeight > _sceneHeight ) {
2017-08-02 16:35:09 +02:00
debugC ( 0 , kSludgeDebugGraphics , " Illegal back drop size " ) ;
2017-05-31 01:11:28 +02:00
return false ;
}
2017-05-28 10:41:01 +02:00
2017-07-20 01:55:21 +02:00
// copy surface loaded to backdrop
2017-08-03 03:50:15 +02:00
Graphics : : TransparentSurface tmp_trans ( tmp , false ) ;
tmp_trans . blit ( _backdropSurface , x , y ) ;
2017-07-20 01:55:21 +02:00
tmp . free ( ) ;
2017-07-20 00:41:13 +02:00
_origBackdropSurface . copyFrom ( _backdropSurface ) ;
_backdropExists = true ;
2017-07-01 22:01:26 +02:00
2017-05-26 05:24:38 +02:00
return true ;
}
2021-05-06 15:00:12 +02:00
bool GraphicsManager : : mixHSI ( int num , Common : : SeekableReadStream * stream , int x , int y ) {
2017-08-02 16:35:09 +02:00
debugC ( 1 , kSludgeDebugGraphics , " Load mixHSI " ) ;
2017-06-16 18:01:58 +02:00
Graphics : : Surface mixSurface ;
2021-05-06 15:00:12 +02:00
if ( ! ImgLoader : : loadImage ( num , " mixhsi " , stream , & mixSurface , 0 ) )
2017-05-31 01:11:28 +02:00
return false ;
2017-05-26 05:24:38 +02:00
2017-07-13 23:26:47 +02:00
uint realPicWidth = mixSurface . w ;
uint realPicHeight = mixSurface . h ;
2017-05-26 05:24:38 +02:00
2017-06-05 11:49:19 +02:00
if ( x = = IN_THE_CENTRE )
2017-07-20 00:41:13 +02:00
x = ( _sceneWidth - realPicWidth ) > > 1 ;
2017-06-05 11:49:19 +02:00
if ( y = = IN_THE_CENTRE )
2017-07-20 00:41:13 +02:00
y = ( _sceneHeight - realPicHeight ) > > 1 ;
if ( x < 0 | | x + realPicWidth > _sceneWidth | | y < 0 | | y + realPicHeight > _sceneHeight )
2017-06-05 11:49:19 +02:00
return false ;
2017-06-16 18:01:58 +02:00
Graphics : : TransparentSurface tmp ( mixSurface , false ) ;
2021-05-12 23:09:58 +02:00
tmp . blit ( _backdropSurface , x , y , Graphics : : FLIP_NONE , nullptr , TS_ARGB ( 255 > > 1 , 255 , 255 , 255 ) ) ;
2017-06-16 18:01:58 +02:00
mixSurface . free ( ) ;
2017-05-27 20:16:54 +02:00
2017-05-26 05:24:38 +02:00
return true ;
}
2017-07-20 00:41:13 +02:00
void GraphicsManager : : saveHSI ( Common : : WriteStream * stream ) {
Image : : writePNG ( * stream , _backdropSurface ) ;
2017-05-26 05:24:38 +02:00
}
2018-04-27 19:12:30 +02:00
void GraphicsManager : : saveBackdrop ( Common : : WriteStream * stream ) {
stream - > writeUint16BE ( _cameraX ) ;
stream - > writeUint16BE ( _cameraY ) ;
stream - > writeFloatLE ( _cameraZoom ) ;
stream - > writeByte ( _brightnessLevel ) ;
saveHSI ( stream ) ;
}
void GraphicsManager : : loadBackdrop ( int ssgVersion , Common : : SeekableReadStream * stream ) {
_cameraX = stream - > readUint16BE ( ) ;
_cameraY = stream - > readUint16BE ( ) ;
if ( ssgVersion > = VERSION ( 2 , 0 ) ) {
_cameraZoom = stream - > readFloatLE ( ) ;
} else {
_cameraZoom = 1.0 ;
}
_brightnessLevel = stream - > readByte ( ) ;
2021-05-06 15:00:12 +02:00
loadHSI ( - 1 , stream , 0 , 0 , true ) ;
2018-04-27 19:12:30 +02:00
}
2017-05-26 05:24:38 +02:00
2017-07-20 10:39:24 +02:00
bool GraphicsManager : : getRGBIntoStack ( uint x , uint y , StackHandler * sH ) {
2017-07-20 00:41:13 +02:00
if ( x > = _sceneWidth | | y > = _sceneHeight ) {
2017-05-26 05:24:38 +02:00
return fatal ( " Co-ordinates are outside current scene! " ) ;
}
2017-07-20 10:39:24 +02:00
Variable newValue ;
2017-05-26 05:24:38 +02:00
newValue . varType = SVT_NULL ;
2017-07-20 00:41:13 +02:00
byte * target = ( byte * ) _renderSurface . getBasePtr ( x , y ) ;
2017-05-26 05:24:38 +02:00
2018-05-31 18:51:42 +02:00
newValue . setVariable ( SVT_INT , target [ 1 ] ) ;
2017-05-28 09:48:25 +02:00
if ( ! addVarToStackQuick ( newValue , sH - > first ) ) return false ;
sH - > last = sH - > first ;
2017-05-26 05:24:38 +02:00
2018-05-31 18:51:42 +02:00
newValue . setVariable ( SVT_INT , target [ 2 ] ) ;
2017-05-28 09:48:25 +02:00
if ( ! addVarToStackQuick ( newValue , sH - > first ) ) return false ;
2017-05-26 05:24:38 +02:00
2018-05-31 18:51:42 +02:00
newValue . setVariable ( SVT_INT , target [ 3 ] ) ;
2017-05-28 09:48:25 +02:00
if ( ! addVarToStackQuick ( newValue , sH - > first ) ) return false ;
2017-07-15 16:28:19 +02:00
2017-05-26 05:24:38 +02:00
return true ;
}
2017-05-26 21:25:11 +02:00
} // End of namespace Sludge