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