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 "ags/engine/ac/dynobj/script_drawing_surface.h"
24 #include "ags/shared/ac/sprite_cache.h"
25 #include "ags/engine/ac/runtime_defines.h"
26 #include "ags/shared/ac/common.h"
27 #include "ags/engine/ac/drawing_surface.h"
28 #include "ags/engine/ac/game_state.h"
29 #include "ags/shared/ac/game_setup_struct.h"
30 #include "ags/shared/game/room_struct.h"
31 #include "ags/shared/gfx/bitmap.h"
32 #include "ags/globals.h"
33 
34 namespace AGS3 {
35 
36 using namespace AGS::Shared;
37 
GetBitmapSurface()38 Bitmap *ScriptDrawingSurface::GetBitmapSurface() {
39 	// TODO: consider creating weak_ptr here, and store one in the DrawingSurface!
40 	if (roomBackgroundNumber >= 0)
41 		return _GP(thisroom).BgFrames[roomBackgroundNumber].Graphic.get();
42 	else if (dynamicSpriteNumber >= 0)
43 		return _GP(spriteset)[dynamicSpriteNumber];
44 	else if (dynamicSurfaceNumber >= 0)
45 		return _G(dynamicallyCreatedSurfaces)[dynamicSurfaceNumber];
46 	else if (linkedBitmapOnly != nullptr)
47 		return linkedBitmapOnly;
48 	else if (roomMaskType > kRoomAreaNone)
49 		return _GP(thisroom).GetMask(roomMaskType);
50 	quit("!DrawingSurface: attempted to use surface after Release was called");
51 	return nullptr;
52 }
53 
StartDrawing()54 Bitmap *ScriptDrawingSurface::StartDrawing() {
55 	return this->GetBitmapSurface();
56 }
57 
FinishedDrawingReadOnly()58 void ScriptDrawingSurface::FinishedDrawingReadOnly() {
59 }
60 
FinishedDrawing()61 void ScriptDrawingSurface::FinishedDrawing() {
62 	FinishedDrawingReadOnly();
63 	modified = 1;
64 }
65 
Dispose(const char * address,bool force)66 int ScriptDrawingSurface::Dispose(const char *address, bool force) {
67 
68 	// dispose the drawing surface
69 	DrawingSurface_Release(this);
70 	delete this;
71 	return 1;
72 }
73 
GetType()74 const char *ScriptDrawingSurface::GetType() {
75 	return "DrawingSurface";
76 }
77 
Serialize(const char * address,char * buffer,int bufsize)78 int ScriptDrawingSurface::Serialize(const char *address, char *buffer, int bufsize) {
79 	StartSerialize(buffer);
80 	// pack mask type in the last byte of a negative integer
81 	// note: (-1) is reserved for "unused", for backward compatibility
82 	if (roomMaskType > 0)
83 		SerializeInt(0xFFFFFF00 | roomMaskType);
84 	else
85 		SerializeInt(roomBackgroundNumber);
86 	SerializeInt(dynamicSpriteNumber);
87 	SerializeInt(dynamicSurfaceNumber);
88 	SerializeInt(currentColour);
89 	SerializeInt(currentColourScript);
90 	SerializeInt(highResCoordinates);
91 	SerializeInt(modified);
92 	SerializeInt(hasAlphaChannel);
93 	SerializeInt(isLinkedBitmapOnly ? 1 : 0);
94 	return EndSerialize();
95 }
96 
Unserialize(int index,const char * serializedData,int dataSize)97 void ScriptDrawingSurface::Unserialize(int index, const char *serializedData, int dataSize) {
98 	StartUnserialize(serializedData, dataSize);
99 	int room_ds = UnserializeInt();
100 	if (room_ds >= 0)
101 		roomBackgroundNumber = room_ds;
102 	// negative value may contain a mask type
103 	else if ((room_ds & 0xFF) != 0xFF)
104 		roomMaskType = (RoomAreaMask)(room_ds & 0xFF);
105 	dynamicSpriteNumber = UnserializeInt();
106 	dynamicSurfaceNumber = UnserializeInt();
107 	currentColour = UnserializeInt();
108 	currentColourScript = UnserializeInt();
109 	highResCoordinates = UnserializeInt();
110 	modified = UnserializeInt();
111 	hasAlphaChannel = UnserializeInt();
112 	isLinkedBitmapOnly = (UnserializeInt() != 0);
113 	ccRegisterUnserializedObject(index, this, this);
114 }
115 
ScriptDrawingSurface()116 ScriptDrawingSurface::ScriptDrawingSurface() {
117 	roomBackgroundNumber = -1;
118 	roomMaskType = kRoomAreaNone;
119 	dynamicSpriteNumber = -1;
120 	dynamicSurfaceNumber = -1;
121 	isLinkedBitmapOnly = false;
122 	linkedBitmapOnly = nullptr;
123 	currentColour = _GP(play).raw_color;
124 	currentColourScript = 0;
125 	modified = 0;
126 	hasAlphaChannel = 0;
127 	highResCoordinates = 0;
128 	// NOTE: Normally in contemporary games coordinates ratio will always be 1:1.
129 	// But we still support legacy drawing, so have to set this up even for modern games,
130 	// otherwise we'd have to complicate conversion conditions further.
131 	if (_GP(game).IsLegacyHiRes() && _GP(game).IsDataInNativeCoordinates()) {
132 		highResCoordinates = 1;
133 	}
134 }
135 
136 } // namespace AGS3
137