add support to SDLBackend for rendering 24bit data
[openc2e.git] / caosVM_camera.cpp
blobf1cb99ee724bf0b2dcff5336cbe0b576c2b9cbde
1 /*
2 * caosVM_camera.cpp
3 * openc2e
5 * Created by Alyssa Milburn on Tue May 25 2004.
6 * Copyright (c) 2004 Alyssa Milburn. All rights reserved.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
20 #include "caosVM.h"
21 #include "World.h"
22 #include "CompoundAgent.h"
23 #include "CameraPart.h"
24 #include "MetaRoom.h"
26 Camera *caosVM::getCamera() {
27 Camera *c = camera.lock().get();
28 if (!c) c = &world.camera;
29 return c;
32 bool agentOnCamera(Agent *targ, bool checkall) {
33 // TODO: check non-main cameras
34 // TODO: do compound parts stick out of the agent?
36 if ((targ->x > (world.camera.getX() + world.camera.getWidth())) || ((targ->x + targ->getWidth()) < world.camera.getX()) ||
37 (targ->y > (world.camera.getY() + world.camera.getHeight())) || ((targ->y + targ->getHeight()) < world.camera.getY())) {
38 return false;
41 return true;
44 /**
45 VISI (integer) checkall (integer)
46 %status maybe
48 Returns 1 if the TARG agent is on camera, or 0 otherwise. If checkall is 0, only checks
49 main camera, otherwise checks all.
51 void caosVM::v_VISI() {
52 VM_PARAM_INTEGER(checkall)
54 valid_agent(targ);
56 if (agentOnCamera(targ, checkall))
57 result.setInt(1);
58 else
59 result.setInt(0);
62 /**
63 ONTV (integer) agent (agent) checkall (integer)
64 %status maybe
66 Returns 1 if the specified agent is on camera, or 0 otherwise. If checkall is 0, only checks
67 main camera, otherwise checks all.
69 void caosVM::v_ONTV() {
70 VM_PARAM_INTEGER(checkall)
71 VM_PARAM_VALIDAGENT(agent)
73 if (agentOnCamera(agent.get(), checkall))
74 result.setInt(1);
75 else
76 result.setInt(0);
79 /**
80 META (command) metaroom_id (integer) camera_x (integer) camera_y (integer) transition (integer)
81 %status maybe
83 Sets the metaroom that the current camera is pointing at. Coordinates point to top left of new
84 camera position. Set a coordinate to -1 to use the top-left corner of the metaroom.
86 Transition: 0 for none, 1 for flip horzizontally, 2 for burst.
88 void caosVM::c_META() {
89 VM_VERIFY_SIZE(4)
90 VM_PARAM_INTEGER(transition)
91 VM_PARAM_INTEGER(camera_y)
92 VM_PARAM_INTEGER(camera_x)
93 VM_PARAM_INTEGER(metaroom_id)
95 caos_assert(metaroom_id >= 0);
96 MetaRoom *m = world.map.getMetaRoom(metaroom_id);
97 if (!m) return; // DS does 'meta 0 -1 -1 0' in !map.cos for some stupid reason
99 int camerax = camera_x; if (camerax == -1) camerax = m->x();
100 int cameray = camera_y; if (cameray == -1) cameray = m->y();
102 getCamera()->goToMetaRoom(metaroom_id, camerax, cameray, (cameratransition)transition);
106 META (integer)
107 %status maybe
109 Returns the metaroom the current camera is looking at.
111 void caosVM::v_META() {
112 if (getCamera()->getMetaRoom())
113 result.setInt(getCamera()->getMetaRoom()->id);
114 else // this is a hack for empathic vendor.cos in DS, which uses META before it's setup
115 // TODO: work out what we should do instead of the hack
116 result.setInt(-1);
120 CMRT (command) pan (integer)
121 %status maybe
123 Focuses the current camera on the TARG agent.
125 Set pan to 0 for no panning (jump), 1 for smooth scrolling if in the same metaroom, or 2
126 for smooth scrolling if the given location is already visible.
128 void caosVM::c_CMRT() {
129 VM_VERIFY_SIZE(1)
130 VM_PARAM_INTEGER(pan)
132 valid_agent(targ);
134 MetaRoom *r = world.map.metaRoomAt(targ->x, targ->y);
135 int xpos = (int)(targ->x - (getCamera()->getWidth() / 2.0f) + (targ->getWidth() / 2.0f));
136 int ypos = (int)(targ->y - (getCamera()->getHeight() / 2.0f) + (targ->getHeight() / 2.0f));
137 if (r)
138 getCamera()->goToMetaRoom(r->id, xpos, ypos, (cameratransition)pan); // TODO: pan okay?
142 CMRA (command) x (integer) y (integer) pan (integer)
143 %status maybe
145 Sets the position of the current camera so that the top left corner of the view is at the
146 given coordinates.
148 Set pan to 0 for no panning (jump), or 1 for smooth scrolling if in the same metaroom.
150 void caosVM::c_CMRA() {
151 VM_VERIFY_SIZE(3)
152 VM_PARAM_INTEGER(pan)
153 VM_PARAM_INTEGER(y)
154 VM_PARAM_INTEGER(x)
156 getCamera()->moveTo(x, y, (panstyle)pan);
160 CMRP (command) x (integer) y (integer) pan (integer)
161 %status maybe
163 Sets the position of the current camera so that the view centers on the given coordinates.
165 Set pan to 0 for no panning (jump), 1 for smooth scrolling if in the same metaroom, or 2
166 for smooth scrolling if the given location is already visible.
168 void caosVM::c_CMRP() {
169 VM_VERIFY_SIZE(3)
170 VM_PARAM_INTEGER(pan)
171 VM_PARAM_INTEGER(y)
172 VM_PARAM_INTEGER(x)
174 getCamera()->moveTo(x - (getCamera()->getWidth() / 2), y - (getCamera()->getHeight() / 2), (panstyle)pan);
178 CMRX (integer)
179 %status maybe
180 %pragma variants c2 cv c3
182 Returns the X position at the center of the current camera's view.
184 void caosVM::v_CMRX() {
185 VM_VERIFY_SIZE(0)
187 result.setInt(getCamera()->getXCentre());
191 CMRY (integer)
192 %status maybe
193 %pragma variants c2 cv c3
195 Returns the Y position at the center of the current camera's view.
197 void caosVM::v_CMRY() {
198 VM_VERIFY_SIZE(0)
200 result.setInt(getCamera()->getYCentre());
204 WNDW (integer)
205 %status maybe
207 Returns the width of the current camera's view.
209 void caosVM::v_WNDW() {
210 VM_VERIFY_SIZE(0)
212 result.setInt(getCamera()->getWidth());
216 WNDH (integer)
217 %status maybe
219 Returns the height of the current camera's view.
221 void caosVM::v_WNDH() {
222 VM_VERIFY_SIZE(0)
224 result.setInt(getCamera()->getHeight());
228 WNDB (integer)
229 %status maybe
231 Returns the position of the bottom edge of the current camera's view.
233 void caosVM::v_WNDB() {
234 VM_VERIFY_SIZE(0)
236 result.setInt(getCamera()->getY() + getCamera()->getHeight());
240 WNDL (integer)
241 %status maybe
243 Returns the position of the left edge of the current camera's view.
245 void caosVM::v_WNDL() {
246 VM_VERIFY_SIZE(0)
248 result.setInt(getCamera()->getX());
252 WNDR (integer)
253 %status maybe
255 Returns the position of the right edge of the current camera's view.
257 void caosVM::v_WNDR() {
258 VM_VERIFY_SIZE(0)
260 result.setInt(getCamera()->getX() + getCamera()->getWidth());
264 WNDT (integer)
265 %status maybe
267 Returns the position of the top edge of the current camera's view.
269 void caosVM::v_WNDT() {
270 VM_VERIFY_SIZE(0)
272 result.setInt(getCamera()->getY());
276 WDOW (command)
277 %status stub
279 Toggles full-screen mode on and off.
281 void caosVM::c_WDOW() {
282 // TODO
286 WDOW (integer)
287 %status stub
289 Returns 1 if in full-screen mode, or 0 otherwise (windowed).
291 void caosVM::v_WDOW() {
292 result.setInt(0);
296 TRCK (command) agent (agent) xpercent (integer) ypercent (integer) style (integer) transition (integer)
297 %status maybe
299 Tell the current camera to track the specified agent, or set to NULL to stop tracking.
300 xpercent and ypercent define a rectangle on the screen which the camera should keep the tracked agent inside.
301 Style 0 is brittle-- tracking is broken easily. Style 1 is flexible-- moving the camera
302 back inside the rectangle resumes tracking. Style 3 is hard-- you can't move outside the
303 rectangle.
304 Rransition: 0 for none, 1 for flip horizontal, 2 for burst.
306 void caosVM::c_TRCK() {
307 VM_PARAM_INTEGER(transition)
308 VM_PARAM_INTEGER(style)
309 VM_PARAM_INTEGER(ypercent)
310 VM_PARAM_INTEGER(xpercent)
311 VM_PARAM_AGENT(agent)
313 getCamera()->trackAgent(agent, xpercent, ypercent, (trackstyle)style, (cameratransition)transition);
317 TRCK (agent)
318 %status maybe
320 Returns agent being tracked by the current camera, if any.
322 void caosVM::v_TRCK() {
323 result.setAgent(getCamera()->trackedAgent());
327 LINE (command) x1 (integer) y1 (integer) x2 (integer) y2 (integer) r (integer) g (integer) b (integer) stipple_on (integer) stipple_off (integer)
328 %status stub
330 Draw a line between two endpoints with the given coordinates, in the color specified by
331 the given red, green, and blue values.
333 Set stipple_on to a number of pixels to alternate for stippling, or set stipple_off to
334 turn stippling off.
336 Setting the the endpoints to the same point will remove all lines for the agent.
338 void caosVM::c_LINE() {
339 VM_PARAM_INTEGER(stipple_off)
340 VM_PARAM_INTEGER(stipple_on)
341 VM_PARAM_INTEGER(b)
342 VM_PARAM_INTEGER(g)
343 VM_PARAM_INTEGER(r)
344 VM_PARAM_INTEGER(y2)
345 VM_PARAM_INTEGER(x2)
346 VM_PARAM_INTEGER(y1)
347 VM_PARAM_INTEGER(x1)
349 valid_agent(targ);
350 // TODO
354 SNAX (integer) filename (string)
355 %status maybe
357 Determines whether or not the given image file exists in the world
358 images directory (0 or 1).
360 void caosVM::v_SNAX() {
361 VM_PARAM_STRING(filename)
363 result.setInt(0);
364 if (!world.findFile(std::string("/Images/") + filename + ".s16").empty())
365 result.setInt(1);
366 else if (!world.findFile(std::string("/Images/") + filename + ".c16").empty())
367 result.setInt(1);
371 SCAM (command) agent (agent) part (integer)
372 %status maybe
374 Sets which camera to use in camera macro commands. If 'agent' and
375 'part' are NULL, the main camera will be used.
377 void caosVM::c_SCAM() {
378 VM_PARAM_INTEGER(part)
379 VM_PARAM_AGENT(agent)
381 if (!agent) {
382 camera.reset();
383 return;
386 CompoundAgent *a = dynamic_cast<CompoundAgent *>(agent.get());
387 caos_assert(a);
388 CompoundPart *p = a->part(part);
389 caos_assert(p);
390 CameraPart *c = dynamic_cast<CameraPart *>(p);
391 caos_assert(c);
393 camera = c->getCamera();
397 ZOOM (command) pixels (integer) x (integer) y (integer)
398 %status stub
400 Zoom the current camera by the given number of pixels on the given x/y
401 coordinates in the world. If the coordinates are set to -1, the
402 current center position of the camera's view will be used.
404 void caosVM::c_ZOOM() {
405 VM_PARAM_INTEGER(y)
406 VM_PARAM_INTEGER(x)
407 VM_PARAM_INTEGER(pixels)
409 // TODO
413 SNAP (command) filename (string) x (integer) y (integer) width (integer) height (integer) zoom (integer)
414 %status stub
416 Take a snapshot and save it to the given filename (don't include the extension). x/y are the centerpoint, width/height the size, and zoom the percentage to zoom out.
418 void caosVM::c_SNAP() {
419 VM_PARAM_INTEGER(zoom)
420 VM_PARAM_INTEGER(height)
421 VM_PARAM_INTEGER(width)
422 VM_PARAM_INTEGER(y)
423 VM_PARAM_INTEGER(x)
424 VM_PARAM_STRING(filename)
426 // TODO
430 LOFT (integer) filename (string)
431 %status stub
433 void caosVM::v_LOFT() {
434 VM_PARAM_STRING(filename)
436 result.setInt(0); // TODO
440 BKGD (command) metaroom_id (integer) background (string) transition (integer)
441 %status stub
443 void caosVM::c_BKGD() {
444 VM_PARAM_INTEGER(transition)
445 VM_PARAM_STRING(background)
446 VM_PARAM_INTEGER(metaroomid)
448 MetaRoom *metaroom = world.map.getMetaRoom(metaroomid);
449 caos_assert(metaroom);
451 // TODO
455 BKGD (string) metaroom_id (integer)
456 %status stub
458 void caosVM::v_BKGD() {
459 VM_PARAM_INTEGER(metaroomid)
461 MetaRoom *metaroom = world.map.getMetaRoom(metaroomid);
462 caos_assert(metaroom);
464 result.setString(""); // TODO
468 FRSH (command)
469 %status stub
471 void caosVM::c_FRSH() {
472 // TODO
476 SYS: CMRP (command) x (integer) y (integer)
477 %status maybe
478 %pragma variants c2
480 Smooth scroll the camera so that the specified coordinates are in the center of the window.
481 (Yes, this differs from what the incorrect C2 documentation says.)
483 void caosVM::c_SYS_CMRP() {
484 VM_PARAM_INTEGER(y)
485 VM_PARAM_INTEGER(x)
487 getCamera()->moveTo(x - (getCamera()->getWidth() / 2), y - (getCamera()->getWidth() / 2), smoothscroll);
491 SYS: CMRA (command) x (integer) y (integer)
492 %status maybe
493 %pragma variants c1 c2
495 void caosVM::c_SYS_CMRA() {
496 VM_PARAM_INTEGER(y)
497 VM_PARAM_INTEGER(x)
499 getCamera()->moveTo(x, y);
503 SYS: CAMT (command)
504 %status maybe
505 %pragma variants c1 c2
507 void caosVM::c_SYS_CAMT() {
508 // TODO: does CAMT behave like this in c1/c2?
509 int xpos = (int)(targ->x - (getCamera()->getWidth() / 2.0f) + (targ->getWidth() / 2.0f));
510 int ypos = (int)(targ->y - (getCamera()->getHeight() / 2.0f) + (targ->getHeight() / 2.0f));
511 getCamera()->moveTo(xpos, ypos);
515 SYS: WTOP (command)
516 %status stub
517 %pragma variants c1 c2
519 Move the main window to the front of the screen.
521 void caosVM::c_SYS_WTOP() {
522 // TODO
525 /* vim: set noet: */