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/draw.h"
24 #include "ags/engine/ac/drawing_surface.h"
25 #include "ags/shared/ac/common.h"
26 #include "ags/engine/ac/character_cache.h"
27 #include "ags/engine/ac/display.h"
28 #include "ags/engine/ac/game.h"
29 #include "ags/shared/ac/game_setup_struct.h"
30 #include "ags/engine/ac/game_state.h"
31 #include "ags/engine/ac/global_translation.h"
32 #include "ags/engine/ac/object_cache.h"
33 #include "ags/engine/ac/room_object.h"
34 #include "ags/engine/ac/room_status.h"
35 #include "ags/engine/ac/string.h"
36 #include "ags/engine/ac/walk_behind.h"
37 #include "ags/engine/debugging/debug_log.h"
38 #include "ags/shared/font/fonts.h"
39 #include "ags/shared/gui/gui_main.h"
40 #include "ags/shared/ac/sprite_cache.h"
41 #include "ags/engine/script/runtime_script_value.h"
42 #include "ags/shared/gfx/gfx_def.h"
43 #include "ags/shared/debugging/out.h"
44 #include "ags/engine/script/script_api.h"
45 #include "ags/engine/script/script_runtime.h"
46 #include "ags/engine/gfx/gfx_util.h"
47 #include "ags/globals.h"
48 
49 namespace AGS3 {
50 
51 using namespace AGS::Shared;
52 using namespace AGS::Engine;
53 
54 // ** SCRIPT DRAWINGSURFACE OBJECT
55 
DrawingSurface_Release(ScriptDrawingSurface * sds)56 void DrawingSurface_Release(ScriptDrawingSurface *sds) {
57 	if (sds->roomBackgroundNumber >= 0) {
58 		if (sds->modified) {
59 			if (sds->roomBackgroundNumber == _GP(play).bg_frame) {
60 				invalidate_screen();
61 				mark_current_background_dirty();
62 			}
63 			_GP(play).raw_modified[sds->roomBackgroundNumber] = 1;
64 		}
65 
66 		sds->roomBackgroundNumber = -1;
67 	}
68 	if (sds->roomMaskType > kRoomAreaNone) {
69 		if (sds->roomMaskType == kRoomAreaWalkBehind) {
70 			recache_walk_behinds();
71 		}
72 		sds->roomMaskType = kRoomAreaNone;
73 	}
74 	if (sds->dynamicSpriteNumber >= 0) {
75 		if (sds->modified) {
76 			game_sprite_updated(sds->dynamicSpriteNumber);
77 		}
78 
79 		sds->dynamicSpriteNumber = -1;
80 	}
81 	if (sds->dynamicSurfaceNumber >= 0) {
82 		delete _G(dynamicallyCreatedSurfaces)[sds->dynamicSurfaceNumber];
83 		_G(dynamicallyCreatedSurfaces)[sds->dynamicSurfaceNumber] = nullptr;
84 		sds->dynamicSurfaceNumber = -1;
85 	}
86 	sds->modified = 0;
87 }
88 
PointToGameResolution(int * xcoord,int * ycoord)89 void ScriptDrawingSurface::PointToGameResolution(int *xcoord, int *ycoord) {
90 	ctx_data_to_game_coord(*xcoord, *ycoord, highResCoordinates != 0);
91 }
92 
SizeToGameResolution(int * width,int * height)93 void ScriptDrawingSurface::SizeToGameResolution(int *width, int *height) {
94 	ctx_data_to_game_size(*width, *height, highResCoordinates != 0);
95 }
96 
SizeToGameResolution(int * valueToAdjust)97 void ScriptDrawingSurface::SizeToGameResolution(int *valueToAdjust) {
98 	*valueToAdjust = ctx_data_to_game_size(*valueToAdjust, highResCoordinates != 0);
99 }
100 
101 // convert actual co-ordinate back to what the script is expecting
SizeToDataResolution(int * valueToAdjust)102 void ScriptDrawingSurface::SizeToDataResolution(int *valueToAdjust) {
103 	*valueToAdjust = game_to_ctx_data_size(*valueToAdjust, highResCoordinates != 0);
104 }
105 
DrawingSurface_CreateCopy(ScriptDrawingSurface * sds)106 ScriptDrawingSurface *DrawingSurface_CreateCopy(ScriptDrawingSurface *sds) {
107 	Bitmap *sourceBitmap = sds->GetBitmapSurface();
108 
109 	for (int i = 0; i < MAX_DYNAMIC_SURFACES; i++) {
110 		if (_G(dynamicallyCreatedSurfaces)[i] == nullptr) {
111 			_G(dynamicallyCreatedSurfaces)[i] = BitmapHelper::CreateBitmapCopy(sourceBitmap);
112 			ScriptDrawingSurface *newSurface = new ScriptDrawingSurface();
113 			newSurface->dynamicSurfaceNumber = i;
114 			newSurface->hasAlphaChannel = sds->hasAlphaChannel;
115 			ccRegisterManagedObject(newSurface, newSurface);
116 			return newSurface;
117 		}
118 	}
119 
120 	quit("!DrawingSurface.CreateCopy: too many copied surfaces created");
121 	return nullptr;
122 }
123 
DrawingSurface_DrawImageImpl(ScriptDrawingSurface * sds,Bitmap * src,int dst_x,int dst_y,int trans,int dst_width,int dst_height,int src_x,int src_y,int src_width,int src_height,int sprite_id,bool src_has_alpha)124 void DrawingSurface_DrawImageImpl(ScriptDrawingSurface *sds, Bitmap *src,
125 	int dst_x, int dst_y, int trans, int dst_width, int dst_height,
126 	int src_x, int src_y, int src_width, int src_height, int sprite_id, bool src_has_alpha) {
127 	Bitmap *ds = sds->GetBitmapSurface();
128 	if (src == ds) {
129 	} // ignore for now; bitmap lib supports, and may be used for effects
130 /* debug_script_warn("DrawingSurface.DrawImage: drawing onto itself"); */
131 	if ((trans < 0) || (trans > 100))
132 		debug_script_warn("DrawingSurface.DrawImage: invalid transparency %d, range is %d - %d", trans, 0, 100);
133 	trans = Math::Clamp(trans, 0, 100);
134 
135 	if (trans == 100)
136 		return; // fully transparent
137 	if (dst_width < 1 || dst_height < 1 || src_width < 1 || src_height < 1)
138 		return; // invalid src or dest rectangles
139 
140 	// Setup uninitialized arguments; convert coordinates for legacy script mode
141 	if (dst_width == SCR_NO_VALUE) {
142 		dst_width = src->GetWidth();
143 	} else {
144 		sds->SizeToGameResolution(&dst_width);
145 	}
146 	if (dst_height == SCR_NO_VALUE) {
147 		dst_height = src->GetHeight();
148 	} else {
149 		sds->SizeToGameResolution(&dst_height);
150 	}
151 
152 	if (src_x == SCR_NO_VALUE) {
153 		src_x = 0;
154 	}
155 	if (src_y == SCR_NO_VALUE) {
156 		src_y = 0;
157 	}
158 	sds->PointToGameResolution(&src_x, &src_y);
159 	if (src_width == SCR_NO_VALUE) {
160 		src_width = src->GetWidth();
161 	} else {
162 		sds->SizeToGameResolution(&src_width);
163 	}
164 	if (src_height == SCR_NO_VALUE) {
165 		src_height = src->GetHeight();
166 	} else {
167 		sds->SizeToGameResolution(&src_height);
168 	}
169 
170 	if (dst_x >= ds->GetWidth() || dst_x + dst_width <= 0 || dst_y >= ds->GetHeight() || dst_y + dst_height <= 0 ||
171 		src_x >= src->GetWidth() || src_x + src_width <= 0 || src_y >= src->GetHeight() || src_y + src_height <= 0)
172 		return; // source or destination rects lie completely off surface
173 	// Clamp the source rect to the valid limits to prevent exceptions (ignore dest, bitmap drawing deals with that)
174 	Math::ClampLength(src_x, src_width, 0, src->GetWidth());
175 	Math::ClampLength(src_y, src_height, 0, src->GetHeight());
176 
177 	// TODO: possibly optimize by not making a stretched intermediate bitmap
178 	// if simplier blit/draw_sprite could be called (no translucency with alpha channel).
179 	bool needToFreeBitmap = false;
180 	if (dst_width != src->GetWidth() || dst_height != src->GetHeight() ||
181 		src_width != src->GetWidth() || src_height != src->GetHeight()) {
182 		// Resize and/or partial copy specified
183 		Bitmap *newPic = BitmapHelper::CreateBitmap(dst_width, dst_height, src->GetColorDepth());
184 		newPic->StretchBlt(src,
185 			RectWH(src_x, src_y, src_width, src_height),
186 			RectWH(0, 0, dst_width, dst_height));
187 
188 		src = newPic;
189 		needToFreeBitmap = true;
190 		update_polled_stuff_if_runtime();
191 	}
192 
193 	ds = sds->StartDrawing();
194 	sds->PointToGameResolution(&dst_x, &dst_y);
195 
196 	if (src->GetColorDepth() != ds->GetColorDepth()) {
197 		if (sprite_id >= 0)
198 			debug_script_warn("DrawImage: Sprite %d colour depth %d-bit not same as background depth %d-bit", sprite_id, src->GetColorDepth(), ds->GetColorDepth());
199 		else
200 			debug_script_warn("DrawImage: Source image colour depth %d-bit not same as background depth %d-bit", src->GetColorDepth(), ds->GetColorDepth());
201 	}
202 
203 	draw_sprite_support_alpha(ds, sds->hasAlphaChannel != 0, dst_x, dst_y, src, src_has_alpha,
204 		kBlendMode_Alpha, GfxDef::Trans100ToAlpha255(trans));
205 
206 	sds->FinishedDrawing();
207 
208 	if (needToFreeBitmap)
209 		delete src;
210 }
211 
DrawingSurface_DrawImageEx(ScriptDrawingSurface * sds,int dst_x,int dst_y,int slot,int trans,int dst_width,int dst_height,int src_x,int src_y,int src_width,int src_height)212 void DrawingSurface_DrawImageEx(ScriptDrawingSurface *sds,
213 		int dst_x, int dst_y, int slot, int trans,
214 		int dst_width, int dst_height,
215 		int src_x, int src_y, int src_width, int src_height) {
216 	if ((slot < 0) || (_GP(spriteset)[slot] == nullptr))
217 		quit("!DrawingSurface.DrawImage: invalid sprite slot number specified");
218 	DrawingSurface_DrawImageImpl(sds, _GP(spriteset)[slot], dst_x, dst_y, trans, dst_width, dst_height,
219 		src_x, src_y, src_width, src_height, slot, (_GP(game).SpriteInfos[slot].Flags & SPF_ALPHACHANNEL) != 0);
220 }
221 
DrawingSurface_DrawImage(ScriptDrawingSurface * sds,int xx,int yy,int slot,int trans,int width,int height)222 void DrawingSurface_DrawImage(ScriptDrawingSurface *sds, int xx, int yy, int slot, int trans, int width, int height) {
223 	DrawingSurface_DrawImageEx(sds, xx, yy, slot, trans, width, height, 0, 0, SCR_NO_VALUE, SCR_NO_VALUE);
224 }
225 
DrawingSurface_DrawSurfaceEx(ScriptDrawingSurface * target,ScriptDrawingSurface * source,int trans,int dst_x,int dst_y,int dst_width,int dst_height,int src_x,int src_y,int src_width,int src_height)226 void DrawingSurface_DrawSurfaceEx(ScriptDrawingSurface *target, ScriptDrawingSurface *source, int trans,
227 		int dst_x, int dst_y, int dst_width, int dst_height,
228 		int src_x, int src_y, int src_width, int src_height) {
229 	DrawingSurface_DrawImageImpl(target, source->GetBitmapSurface(), dst_x, dst_y, trans, dst_width, dst_height,
230 		src_x, src_y, src_width, src_height, -1, source->hasAlphaChannel);
231 }
232 
DrawingSurface_DrawSurface(ScriptDrawingSurface * target,ScriptDrawingSurface * source,int trans)233 void DrawingSurface_DrawSurface(ScriptDrawingSurface *target, ScriptDrawingSurface *source, int trans) {
234 	DrawingSurface_DrawSurfaceEx(target, source, trans, 0, 0, SCR_NO_VALUE, SCR_NO_VALUE, 0, 0, SCR_NO_VALUE, SCR_NO_VALUE);
235 }
236 
DrawingSurface_SetDrawingColor(ScriptDrawingSurface * sds,int newColour)237 void DrawingSurface_SetDrawingColor(ScriptDrawingSurface *sds, int newColour) {
238 	sds->currentColourScript = newColour;
239 	// StartDrawing to set up ds to set the colour at the appropriate
240 	// depth for the background
241 	Bitmap *ds = sds->StartDrawing();
242 	if (newColour == SCR_COLOR_TRANSPARENT) {
243 		sds->currentColour = ds->GetMaskColor();
244 	} else {
245 		sds->currentColour = ds->GetCompatibleColor(newColour);
246 	}
247 	sds->FinishedDrawingReadOnly();
248 }
249 
DrawingSurface_GetDrawingColor(ScriptDrawingSurface * sds)250 int DrawingSurface_GetDrawingColor(ScriptDrawingSurface *sds) {
251 	return sds->currentColourScript;
252 }
253 
DrawingSurface_SetUseHighResCoordinates(ScriptDrawingSurface * sds,int highRes)254 void DrawingSurface_SetUseHighResCoordinates(ScriptDrawingSurface *sds, int highRes) {
255 	if (_GP(game).AllowRelativeRes())
256 		sds->highResCoordinates = (highRes) ? 1 : 0;
257 }
258 
DrawingSurface_GetUseHighResCoordinates(ScriptDrawingSurface * sds)259 int DrawingSurface_GetUseHighResCoordinates(ScriptDrawingSurface *sds) {
260 	return sds->highResCoordinates;
261 }
262 
DrawingSurface_GetHeight(ScriptDrawingSurface * sds)263 int DrawingSurface_GetHeight(ScriptDrawingSurface *sds) {
264 	Bitmap *ds = sds->StartDrawing();
265 	int height = ds->GetHeight();
266 	sds->FinishedDrawingReadOnly();
267 	sds->SizeToGameResolution(&height);
268 	return height;
269 }
270 
DrawingSurface_GetWidth(ScriptDrawingSurface * sds)271 int DrawingSurface_GetWidth(ScriptDrawingSurface *sds) {
272 	Bitmap *ds = sds->StartDrawing();
273 	int width = ds->GetWidth();
274 	sds->FinishedDrawingReadOnly();
275 	sds->SizeToGameResolution(&width);
276 	return width;
277 }
278 
DrawingSurface_Clear(ScriptDrawingSurface * sds,int colour)279 void DrawingSurface_Clear(ScriptDrawingSurface *sds, int colour) {
280 	Bitmap *ds = sds->StartDrawing();
281 	int allegroColor;
282 	if ((colour == -SCR_NO_VALUE) || (colour == SCR_COLOR_TRANSPARENT)) {
283 		allegroColor = ds->GetMaskColor();
284 	} else {
285 		allegroColor = ds->GetCompatibleColor(colour);
286 	}
287 	ds->Fill(allegroColor);
288 	sds->FinishedDrawing();
289 }
290 
DrawingSurface_DrawCircle(ScriptDrawingSurface * sds,int x,int y,int radius)291 void DrawingSurface_DrawCircle(ScriptDrawingSurface *sds, int x, int y, int radius) {
292 	sds->PointToGameResolution(&x, &y);
293 	sds->SizeToGameResolution(&radius);
294 
295 	Bitmap *ds = sds->StartDrawing();
296 	ds->FillCircle(Circle(x, y, radius), sds->currentColour);
297 	sds->FinishedDrawing();
298 }
299 
DrawingSurface_DrawRectangle(ScriptDrawingSurface * sds,int x1,int y1,int x2,int y2)300 void DrawingSurface_DrawRectangle(ScriptDrawingSurface *sds, int x1, int y1, int x2, int y2) {
301 	sds->PointToGameResolution(&x1, &y1);
302 	sds->PointToGameResolution(&x2, &y2);
303 
304 	Bitmap *ds = sds->StartDrawing();
305 	ds->FillRect(Rect(x1, y1, x2, y2), sds->currentColour);
306 	sds->FinishedDrawing();
307 }
308 
DrawingSurface_DrawTriangle(ScriptDrawingSurface * sds,int x1,int y1,int x2,int y2,int x3,int y3)309 void DrawingSurface_DrawTriangle(ScriptDrawingSurface *sds, int x1, int y1, int x2, int y2, int x3, int y3) {
310 	sds->PointToGameResolution(&x1, &y1);
311 	sds->PointToGameResolution(&x2, &y2);
312 	sds->PointToGameResolution(&x3, &y3);
313 
314 	Bitmap *ds = sds->StartDrawing();
315 	ds->DrawTriangle(Triangle(x1, y1, x2, y2, x3, y3), sds->currentColour);
316 	sds->FinishedDrawing();
317 }
318 
DrawingSurface_DrawString(ScriptDrawingSurface * sds,int xx,int yy,int font,const char * text)319 void DrawingSurface_DrawString(ScriptDrawingSurface *sds, int xx, int yy, int font, const char *text) {
320 	sds->PointToGameResolution(&xx, &yy);
321 	Bitmap *ds = sds->StartDrawing();
322 	// don't use wtextcolor because it will do a 16->32 conversion
323 	color_t text_color = sds->currentColour;
324 	if ((ds->GetColorDepth() <= 8) && (_GP(play).raw_color > 255)) {
325 		text_color = ds->GetCompatibleColor(1);
326 		debug_script_warn("RawPrint: Attempted to use hi-color on 256-col background");
327 	}
328 	wouttext_outline(ds, xx, yy, font, text_color, text);
329 	sds->FinishedDrawing();
330 }
331 
DrawingSurface_DrawStringWrapped_Old(ScriptDrawingSurface * sds,int xx,int yy,int wid,int font,int alignment,const char * msg)332 void DrawingSurface_DrawStringWrapped_Old(ScriptDrawingSurface *sds, int xx, int yy, int wid, int font, int alignment, const char *msg) {
333 	DrawingSurface_DrawStringWrapped(sds, xx, yy, wid, font, ConvertLegacyScriptAlignment((LegacyScriptAlignment)alignment), msg);
334 }
335 
DrawingSurface_DrawStringWrapped(ScriptDrawingSurface * sds,int xx,int yy,int wid,int font,int alignment,const char * msg)336 void DrawingSurface_DrawStringWrapped(ScriptDrawingSurface *sds, int xx, int yy, int wid, int font, int alignment, const char *msg) {
337 	int linespacing = getfontspacing_outlined(font);
338 	sds->PointToGameResolution(&xx, &yy);
339 	sds->SizeToGameResolution(&wid);
340 
341 	if (break_up_text_into_lines(msg, _GP(Lines), wid, font) == 0)
342 		return;
343 
344 	Bitmap *ds = sds->StartDrawing();
345 	color_t text_color = sds->currentColour;
346 
347 	for (size_t i = 0; i < _GP(Lines).Count(); i++) {
348 		int drawAtX = xx;
349 
350 		if (alignment & kMAlignHCenter) {
351 			drawAtX = xx + ((wid / 2) - wgettextwidth(_GP(Lines)[i].GetCStr(), font) / 2);
352 		} else if (alignment & kMAlignRight) {
353 			drawAtX = (xx + wid) - wgettextwidth(_GP(Lines)[i].GetCStr(), font);
354 		}
355 
356 		wouttext_outline(ds, drawAtX, yy + linespacing * i, font, text_color, _GP(Lines)[i].GetCStr());
357 	}
358 
359 	sds->FinishedDrawing();
360 }
361 
DrawingSurface_DrawMessageWrapped(ScriptDrawingSurface * sds,int xx,int yy,int wid,int font,int msgm)362 void DrawingSurface_DrawMessageWrapped(ScriptDrawingSurface *sds, int xx, int yy, int wid, int font, int msgm) {
363 	char displbuf[3000];
364 	get_message_text(msgm, displbuf);
365 	// it's probably too late but check anyway
366 	if (strlen(displbuf) > 2899)
367 		quit("!RawPrintMessageWrapped: message too long");
368 
369 	DrawingSurface_DrawStringWrapped_Old(sds, xx, yy, wid, font, kLegacyScAlignLeft, displbuf);
370 }
371 
DrawingSurface_DrawLine(ScriptDrawingSurface * sds,int fromx,int fromy,int tox,int toy,int thickness)372 void DrawingSurface_DrawLine(ScriptDrawingSurface *sds, int fromx, int fromy, int tox, int toy, int thickness) {
373 	sds->PointToGameResolution(&fromx, &fromy);
374 	sds->PointToGameResolution(&tox, &toy);
375 	sds->SizeToGameResolution(&thickness);
376 	int ii, jj, xx, yy;
377 	Bitmap *ds = sds->StartDrawing();
378 	// draw several lines to simulate the thickness
379 	color_t draw_color = sds->currentColour;
380 	for (ii = 0; ii < thickness; ii++) {
381 		xx = (ii - (thickness / 2));
382 		for (jj = 0; jj < thickness; jj++) {
383 			yy = (jj - (thickness / 2));
384 			ds->DrawLine(Line(fromx + xx, fromy + yy, tox + xx, toy + yy), draw_color);
385 		}
386 	}
387 	sds->FinishedDrawing();
388 }
389 
DrawingSurface_DrawPixel(ScriptDrawingSurface * sds,int x,int y)390 void DrawingSurface_DrawPixel(ScriptDrawingSurface *sds, int x, int y) {
391 	sds->PointToGameResolution(&x, &y);
392 	int thickness = 1;
393 	sds->SizeToGameResolution(&thickness);
394 	int ii, jj;
395 	Bitmap *ds = sds->StartDrawing();
396 	// draw several pixels to simulate the thickness
397 	color_t draw_color = sds->currentColour;
398 	for (ii = 0; ii < thickness; ii++) {
399 		for (jj = 0; jj < thickness; jj++) {
400 			ds->PutPixel(x + ii, y + jj, draw_color);
401 		}
402 	}
403 	sds->FinishedDrawing();
404 }
405 
DrawingSurface_GetPixel(ScriptDrawingSurface * sds,int x,int y)406 int DrawingSurface_GetPixel(ScriptDrawingSurface *sds, int x, int y) {
407 	sds->PointToGameResolution(&x, &y);
408 	Bitmap *ds = sds->StartDrawing();
409 	unsigned int rawPixel = ds->GetPixel(x, y);
410 	unsigned int maskColor = ds->GetMaskColor();
411 	int colDepth = ds->GetColorDepth();
412 
413 	if (rawPixel == maskColor) {
414 		rawPixel = (unsigned int)SCR_COLOR_TRANSPARENT;
415 	} else if (colDepth > 8) {
416 		int r = getr_depth(colDepth, rawPixel);
417 		int g = getg_depth(colDepth, rawPixel);
418 		int b = getb_depth(colDepth, rawPixel);
419 
420 		rawPixel = Game_GetColorFromRGB(r, g, b);
421 	}
422 
423 	sds->FinishedDrawingReadOnly();
424 
425 	return rawPixel;
426 }
427 
428 //=============================================================================
429 //
430 // Script API Functions
431 //
432 //=============================================================================
433 
434 // void (ScriptDrawingSurface *sds, int colour)
Sc_DrawingSurface_Clear(void * self,const RuntimeScriptValue * params,int32_t param_count)435 RuntimeScriptValue Sc_DrawingSurface_Clear(void *self, const RuntimeScriptValue *params, int32_t param_count) {
436 	API_OBJCALL_VOID_PINT(ScriptDrawingSurface, DrawingSurface_Clear);
437 }
438 
439 // ScriptDrawingSurface* (ScriptDrawingSurface *sds)
Sc_DrawingSurface_CreateCopy(void * self,const RuntimeScriptValue * params,int32_t param_count)440 RuntimeScriptValue Sc_DrawingSurface_CreateCopy(void *self, const RuntimeScriptValue *params, int32_t param_count) {
441 	API_OBJCALL_OBJAUTO(ScriptDrawingSurface, ScriptDrawingSurface, DrawingSurface_CreateCopy);
442 }
443 
444 // void (ScriptDrawingSurface *sds, int x, int y, int radius)
Sc_DrawingSurface_DrawCircle(void * self,const RuntimeScriptValue * params,int32_t param_count)445 RuntimeScriptValue Sc_DrawingSurface_DrawCircle(void *self, const RuntimeScriptValue *params, int32_t param_count) {
446 	API_OBJCALL_VOID_PINT3(ScriptDrawingSurface, DrawingSurface_DrawCircle);
447 }
448 
449 // void (ScriptDrawingSurface* sds, int xx, int yy, int slot, int trans, int width, int height)
Sc_DrawingSurface_DrawImage_6(void * self,const RuntimeScriptValue * params,int32_t param_count)450 RuntimeScriptValue Sc_DrawingSurface_DrawImage_6(void *self, const RuntimeScriptValue *params, int32_t param_count) {
451 	API_OBJCALL_VOID_PINT6(ScriptDrawingSurface, DrawingSurface_DrawImage);
452 }
453 
Sc_DrawingSurface_DrawImage(void * self,const RuntimeScriptValue * params,int32_t param_count)454 RuntimeScriptValue Sc_DrawingSurface_DrawImage(void *self, const RuntimeScriptValue *params, int32_t param_count) {
455 	ASSERT_OBJ_PARAM_COUNT(METHOD, 10);
456 	DrawingSurface_DrawImageEx((ScriptDrawingSurface *)self, params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue, params[4].IValue, params[5].IValue,
457 		params[6].IValue, params[7].IValue, params[8].IValue, params[9].IValue);
458 	return RuntimeScriptValue((int32_t)0);
459 }
460 
461 // void (ScriptDrawingSurface *sds, int fromx, int fromy, int tox, int toy, int thickness)
Sc_DrawingSurface_DrawLine(void * self,const RuntimeScriptValue * params,int32_t param_count)462 RuntimeScriptValue Sc_DrawingSurface_DrawLine(void *self, const RuntimeScriptValue *params, int32_t param_count) {
463 	API_OBJCALL_VOID_PINT5(ScriptDrawingSurface, DrawingSurface_DrawLine);
464 }
465 
466 // void (ScriptDrawingSurface *sds, int xx, int yy, int wid, int font, int msgm)
Sc_DrawingSurface_DrawMessageWrapped(void * self,const RuntimeScriptValue * params,int32_t param_count)467 RuntimeScriptValue Sc_DrawingSurface_DrawMessageWrapped(void *self, const RuntimeScriptValue *params, int32_t param_count) {
468 	API_OBJCALL_VOID_PINT5(ScriptDrawingSurface, DrawingSurface_DrawMessageWrapped);
469 }
470 
471 // void (ScriptDrawingSurface *sds, int x, int y)
Sc_DrawingSurface_DrawPixel(void * self,const RuntimeScriptValue * params,int32_t param_count)472 RuntimeScriptValue Sc_DrawingSurface_DrawPixel(void *self, const RuntimeScriptValue *params, int32_t param_count) {
473 	API_OBJCALL_VOID_PINT2(ScriptDrawingSurface, DrawingSurface_DrawPixel);
474 }
475 
476 // void (ScriptDrawingSurface *sds, int x1, int y1, int x2, int y2)
Sc_DrawingSurface_DrawRectangle(void * self,const RuntimeScriptValue * params,int32_t param_count)477 RuntimeScriptValue Sc_DrawingSurface_DrawRectangle(void *self, const RuntimeScriptValue *params, int32_t param_count) {
478 	API_OBJCALL_VOID_PINT4(ScriptDrawingSurface, DrawingSurface_DrawRectangle);
479 }
480 
481 // void (ScriptDrawingSurface *sds, int xx, int yy, int font, const char* texx, ...)
Sc_DrawingSurface_DrawString(void * self,const RuntimeScriptValue * params,int32_t param_count)482 RuntimeScriptValue Sc_DrawingSurface_DrawString(void *self, const RuntimeScriptValue *params, int32_t param_count) {
483 	API_OBJCALL_SCRIPT_SPRINTF(DrawingSurface_DrawString, 4);
484 	DrawingSurface_DrawString((ScriptDrawingSurface *)self, params[0].IValue, params[1].IValue, params[2].IValue, scsf_buffer);
485 	return RuntimeScriptValue((int32_t)0);
486 }
487 
488 // void (ScriptDrawingSurface *sds, int xx, int yy, int wid, int font, int alignment, const char *msg)
Sc_DrawingSurface_DrawStringWrapped_Old(void * self,const RuntimeScriptValue * params,int32_t param_count)489 RuntimeScriptValue Sc_DrawingSurface_DrawStringWrapped_Old(void *self, const RuntimeScriptValue *params, int32_t param_count) {
490 	API_OBJCALL_VOID_PINT5_POBJ(ScriptDrawingSurface, DrawingSurface_DrawStringWrapped_Old, const char);
491 }
492 
Sc_DrawingSurface_DrawStringWrapped(void * self,const RuntimeScriptValue * params,int32_t param_count)493 RuntimeScriptValue Sc_DrawingSurface_DrawStringWrapped(void *self, const RuntimeScriptValue *params, int32_t param_count) {
494 	API_OBJCALL_VOID_PINT5_POBJ(ScriptDrawingSurface, DrawingSurface_DrawStringWrapped, const char);
495 }
496 
497 // void (ScriptDrawingSurface* target, ScriptDrawingSurface* source, int translev)
Sc_DrawingSurface_DrawSurface_2(void * self,const RuntimeScriptValue * params,int32_t param_count)498 RuntimeScriptValue Sc_DrawingSurface_DrawSurface_2(void *self, const RuntimeScriptValue *params, int32_t param_count) {
499 	API_OBJCALL_VOID_POBJ_PINT(ScriptDrawingSurface, DrawingSurface_DrawSurface, ScriptDrawingSurface);
500 }
501 
Sc_DrawingSurface_DrawSurface(void * self,const RuntimeScriptValue * params,int32_t param_count)502 RuntimeScriptValue Sc_DrawingSurface_DrawSurface(void *self, const RuntimeScriptValue *params, int32_t param_count) {
503 	ASSERT_OBJ_PARAM_COUNT(METHOD, 10);
504 	DrawingSurface_DrawSurfaceEx((ScriptDrawingSurface *)self, (ScriptDrawingSurface *)params[0].Ptr,
505 		params[1].IValue, params[2].IValue, params[3].IValue, params[4].IValue, params[5].IValue,
506 		params[6].IValue, params[7].IValue, params[8].IValue, params[9].IValue);
507 	return RuntimeScriptValue((int32_t)0);
508 }
509 
510 // void (ScriptDrawingSurface *sds, int x1, int y1, int x2, int y2, int x3, int y3)
Sc_DrawingSurface_DrawTriangle(void * self,const RuntimeScriptValue * params,int32_t param_count)511 RuntimeScriptValue Sc_DrawingSurface_DrawTriangle(void *self, const RuntimeScriptValue *params, int32_t param_count) {
512 	API_OBJCALL_VOID_PINT6(ScriptDrawingSurface, DrawingSurface_DrawTriangle);
513 }
514 
515 // int (ScriptDrawingSurface *sds, int x, int y)
Sc_DrawingSurface_GetPixel(void * self,const RuntimeScriptValue * params,int32_t param_count)516 RuntimeScriptValue Sc_DrawingSurface_GetPixel(void *self, const RuntimeScriptValue *params, int32_t param_count) {
517 	API_OBJCALL_INT_PINT2(ScriptDrawingSurface, DrawingSurface_GetPixel);
518 }
519 
520 // void (ScriptDrawingSurface* sds)
Sc_DrawingSurface_Release(void * self,const RuntimeScriptValue * params,int32_t param_count)521 RuntimeScriptValue Sc_DrawingSurface_Release(void *self, const RuntimeScriptValue *params, int32_t param_count) {
522 	API_OBJCALL_VOID(ScriptDrawingSurface, DrawingSurface_Release);
523 }
524 
525 // int (ScriptDrawingSurface *sds)
Sc_DrawingSurface_GetDrawingColor(void * self,const RuntimeScriptValue * params,int32_t param_count)526 RuntimeScriptValue Sc_DrawingSurface_GetDrawingColor(void *self, const RuntimeScriptValue *params, int32_t param_count) {
527 	API_OBJCALL_INT(ScriptDrawingSurface, DrawingSurface_GetDrawingColor);
528 }
529 
530 // void (ScriptDrawingSurface *sds, int newColour)
Sc_DrawingSurface_SetDrawingColor(void * self,const RuntimeScriptValue * params,int32_t param_count)531 RuntimeScriptValue Sc_DrawingSurface_SetDrawingColor(void *self, const RuntimeScriptValue *params, int32_t param_count) {
532 	API_OBJCALL_VOID_PINT(ScriptDrawingSurface, DrawingSurface_SetDrawingColor);
533 }
534 
535 // int (ScriptDrawingSurface *sds)
Sc_DrawingSurface_GetHeight(void * self,const RuntimeScriptValue * params,int32_t param_count)536 RuntimeScriptValue Sc_DrawingSurface_GetHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) {
537 	API_OBJCALL_INT(ScriptDrawingSurface, DrawingSurface_GetHeight);
538 }
539 
540 // int (ScriptDrawingSurface *sds)
Sc_DrawingSurface_GetUseHighResCoordinates(void * self,const RuntimeScriptValue * params,int32_t param_count)541 RuntimeScriptValue Sc_DrawingSurface_GetUseHighResCoordinates(void *self, const RuntimeScriptValue *params, int32_t param_count) {
542 	API_OBJCALL_INT(ScriptDrawingSurface, DrawingSurface_GetUseHighResCoordinates);
543 }
544 
545 // void (ScriptDrawingSurface *sds, int highRes)
Sc_DrawingSurface_SetUseHighResCoordinates(void * self,const RuntimeScriptValue * params,int32_t param_count)546 RuntimeScriptValue Sc_DrawingSurface_SetUseHighResCoordinates(void *self, const RuntimeScriptValue *params, int32_t param_count) {
547 	API_OBJCALL_VOID_PINT(ScriptDrawingSurface, DrawingSurface_SetUseHighResCoordinates);
548 }
549 
550 // int (ScriptDrawingSurface *sds)
Sc_DrawingSurface_GetWidth(void * self,const RuntimeScriptValue * params,int32_t param_count)551 RuntimeScriptValue Sc_DrawingSurface_GetWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) {
552 	API_OBJCALL_INT(ScriptDrawingSurface, DrawingSurface_GetWidth);
553 }
554 
555 //=============================================================================
556 //
557 // Exclusive API for Plugins
558 //
559 //=============================================================================
560 
RegisterDrawingSurfaceAPI(ScriptAPIVersion base_api,ScriptAPIVersion compat_api)561 void RegisterDrawingSurfaceAPI(ScriptAPIVersion base_api, ScriptAPIVersion compat_api) {
562 	ccAddExternalObjectFunction("DrawingSurface::Clear^1", Sc_DrawingSurface_Clear);
563 	ccAddExternalObjectFunction("DrawingSurface::CreateCopy^0", Sc_DrawingSurface_CreateCopy);
564 	ccAddExternalObjectFunction("DrawingSurface::DrawCircle^3", Sc_DrawingSurface_DrawCircle);
565 	ccAddExternalObjectFunction("DrawingSurface::DrawImage^6", Sc_DrawingSurface_DrawImage_6);
566 	ccAddExternalObjectFunction("DrawingSurface::DrawImage^10", Sc_DrawingSurface_DrawImage);
567 	ccAddExternalObjectFunction("DrawingSurface::DrawLine^5", Sc_DrawingSurface_DrawLine);
568 	ccAddExternalObjectFunction("DrawingSurface::DrawMessageWrapped^5", Sc_DrawingSurface_DrawMessageWrapped);
569 	ccAddExternalObjectFunction("DrawingSurface::DrawPixel^2", Sc_DrawingSurface_DrawPixel);
570 	ccAddExternalObjectFunction("DrawingSurface::DrawRectangle^4", Sc_DrawingSurface_DrawRectangle);
571 	ccAddExternalObjectFunction("DrawingSurface::DrawString^104", Sc_DrawingSurface_DrawString);
572 	if (base_api < kScriptAPI_v350)
573 		ccAddExternalObjectFunction("DrawingSurface::DrawStringWrapped^6", Sc_DrawingSurface_DrawStringWrapped_Old);
574 	else
575 		ccAddExternalObjectFunction("DrawingSurface::DrawStringWrapped^6", Sc_DrawingSurface_DrawStringWrapped);
576 	ccAddExternalObjectFunction("DrawingSurface::DrawSurface^2", Sc_DrawingSurface_DrawSurface_2);
577 	ccAddExternalObjectFunction("DrawingSurface::DrawSurface^10", Sc_DrawingSurface_DrawSurface);
578 	ccAddExternalObjectFunction("DrawingSurface::DrawTriangle^6", Sc_DrawingSurface_DrawTriangle);
579 	ccAddExternalObjectFunction("DrawingSurface::GetPixel^2", Sc_DrawingSurface_GetPixel);
580 	ccAddExternalObjectFunction("DrawingSurface::Release^0", Sc_DrawingSurface_Release);
581 	ccAddExternalObjectFunction("DrawingSurface::get_DrawingColor", Sc_DrawingSurface_GetDrawingColor);
582 	ccAddExternalObjectFunction("DrawingSurface::set_DrawingColor", Sc_DrawingSurface_SetDrawingColor);
583 	ccAddExternalObjectFunction("DrawingSurface::get_Height", Sc_DrawingSurface_GetHeight);
584 	ccAddExternalObjectFunction("DrawingSurface::get_UseHighResCoordinates", Sc_DrawingSurface_GetUseHighResCoordinates);
585 	ccAddExternalObjectFunction("DrawingSurface::set_UseHighResCoordinates", Sc_DrawingSurface_SetUseHighResCoordinates);
586 	ccAddExternalObjectFunction("DrawingSurface::get_Width", Sc_DrawingSurface_GetWidth);
587 }
588 
589 } // namespace AGS3
590