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.
22 #include "CompoundAgent.h"
23 #include "CameraPart.h"
26 Camera
*caosVM::getCamera() {
27 Camera
*c
= camera
.lock().get();
28 if (!c
) c
= &world
.camera
;
32 bool agentOnCamera(Agent
*targ
, bool checkall
) {
33 MetaRoom
*m
= world
.map
.metaRoomAt(targ
->x
, targ
->y
);
34 if (!m
|| m
!= world
.camera
.getMetaRoom()) return false;
36 // TODO: check non-main cameras?
37 // TODO: do compound parts stick out of the agent?
39 // y coordinates don't wrap
40 if (targ
->y
+ targ
->getHeight() < world
.camera
.getY()) return false;
41 if (targ
->y
> world
.camera
.getY() + world
.camera
.getHeight()) return false;
43 // if an agent is off-camera to the right, it's not visible
44 if (targ
->x
> world
.camera
.getX() + world
.camera
.getWidth()) return false;
46 if (targ
->x
+ targ
->getWidth() < world
.camera
.getX()) {
47 // if an agent is off-camera to the left, it might be wrapping
48 if (!m
->wraparound() || (targ
->x
+ targ
->getWidth() + m
->width() < world
.camera
.getX()))
56 VISI (integer) checkall (integer)
59 Returns 1 if the TARG agent is on camera, or 0 otherwise. If checkall is 0, only checks
60 main camera, otherwise checks all.
62 void caosVM::v_VISI() {
63 VM_PARAM_INTEGER(checkall
)
67 if (agentOnCamera(targ
, checkall
))
74 ONTV (integer) agent (agent) checkall (integer)
77 Returns 1 if the specified agent is on camera, or 0 otherwise. If checkall is 0, only checks
78 main camera, otherwise checks all.
80 void caosVM::v_ONTV() {
81 VM_PARAM_INTEGER(checkall
)
82 VM_PARAM_VALIDAGENT(agent
)
84 if (agentOnCamera(agent
.get(), checkall
))
91 META (command) metaroom_id (integer) camera_x (integer) camera_y (integer) transition (integer)
94 Sets the metaroom that the current camera is pointing at. Coordinates point to top left of new
95 camera position. Set a coordinate to -1 to use the top-left corner of the metaroom.
97 Transition: 0 for none, 1 for flip horzizontally, 2 for burst.
99 void caosVM::c_META() {
101 VM_PARAM_INTEGER(transition
)
102 VM_PARAM_INTEGER(camera_y
)
103 VM_PARAM_INTEGER(camera_x
)
104 VM_PARAM_INTEGER(metaroom_id
)
106 caos_assert(metaroom_id
>= 0);
107 MetaRoom
*m
= world
.map
.getMetaRoom(metaroom_id
);
108 if (!m
) return; // DS does 'meta 0 -1 -1 0' in !map.cos for some stupid reason
110 int camerax
= camera_x
; if (camerax
== -1) camerax
= m
->x();
111 int cameray
= camera_y
; if (cameray
== -1) cameray
= m
->y();
113 getCamera()->goToMetaRoom(metaroom_id
, camerax
, cameray
, (cameratransition
)transition
);
120 Returns the metaroom the current camera is looking at.
122 void caosVM::v_META() {
123 if (getCamera()->getMetaRoom())
124 result
.setInt(getCamera()->getMetaRoom()->id
);
125 else // this is a hack for empathic vendor.cos in DS, which uses META before it's setup
126 // TODO: work out what we should do instead of the hack
131 CMRT (command) pan (integer)
134 Focuses the current camera on the TARG agent.
136 Set pan to 0 for no panning (jump), 1 for smooth scrolling if in the same metaroom, or 2
137 for smooth scrolling if the given location is already visible.
139 void caosVM::c_CMRT() {
141 VM_PARAM_INTEGER(pan
)
145 MetaRoom
*r
= world
.map
.metaRoomAt(targ
->x
, targ
->y
);
146 int xpos
= (int)(targ
->x
- (getCamera()->getWidth() / 2.0f
) + (targ
->getWidth() / 2.0f
));
147 int ypos
= (int)(targ
->y
- (getCamera()->getHeight() / 2.0f
) + (targ
->getHeight() / 2.0f
));
149 getCamera()->goToMetaRoom(r
->id
, xpos
, ypos
, (cameratransition
)pan
); // TODO: pan okay?
153 CMRA (command) x (integer) y (integer) pan (integer)
156 Sets the position of the current camera so that the top left corner of the view is at the
159 Set pan to 0 for no panning (jump), or 1 for smooth scrolling if in the same metaroom.
161 void caosVM::c_CMRA() {
163 VM_PARAM_INTEGER(pan
)
167 getCamera()->moveTo(x
, y
, (panstyle
)pan
);
171 CMRP (command) x (integer) y (integer) pan (integer)
174 Sets the position of the current camera so that the view centers on the given coordinates.
176 Set pan to 0 for no panning (jump), 1 for smooth scrolling if in the same metaroom, or 2
177 for smooth scrolling if the given location is already visible.
179 void caosVM::c_CMRP() {
181 VM_PARAM_INTEGER(pan
)
185 getCamera()->moveTo(x
- (getCamera()->getWidth() / 2), y
- (getCamera()->getHeight() / 2), (panstyle
)pan
);
191 %pragma variants c2 cv c3
193 Returns the X position at the center of the current camera's view.
195 void caosVM::v_CMRX() {
198 result
.setInt(getCamera()->getXCentre());
204 %pragma variants c2 cv c3
206 Returns the Y position at the center of the current camera's view.
208 void caosVM::v_CMRY() {
211 result
.setInt(getCamera()->getYCentre());
218 Returns the width of the current camera's view.
220 void caosVM::v_WNDW() {
223 result
.setInt(getCamera()->getWidth());
230 Returns the height of the current camera's view.
232 void caosVM::v_WNDH() {
235 result
.setInt(getCamera()->getHeight());
242 Returns the position of the bottom edge of the current camera's view.
244 void caosVM::v_WNDB() {
247 result
.setInt(getCamera()->getY() + getCamera()->getHeight());
254 Returns the position of the left edge of the current camera's view.
256 void caosVM::v_WNDL() {
259 result
.setInt(getCamera()->getX());
266 Returns the position of the right edge of the current camera's view.
268 void caosVM::v_WNDR() {
271 result
.setInt(getCamera()->getX() + getCamera()->getWidth());
278 Returns the position of the top edge of the current camera's view.
280 void caosVM::v_WNDT() {
283 result
.setInt(getCamera()->getY());
290 Toggles full-screen mode on and off.
292 void caosVM::c_WDOW() {
300 Returns 1 if in full-screen mode, or 0 otherwise (windowed).
302 void caosVM::v_WDOW() {
307 TRCK (command) agent (agent) xpercent (integer) ypercent (integer) style (integer) transition (integer)
310 Tell the current camera to track the specified agent, or set to NULL to stop tracking.
311 xpercent and ypercent define a rectangle on the screen which the camera should keep the tracked agent inside.
312 Style 0 is brittle-- tracking is broken easily. Style 1 is flexible-- moving the camera
313 back inside the rectangle resumes tracking. Style 3 is hard-- you can't move outside the
315 Rransition: 0 for none, 1 for flip horizontal, 2 for burst.
317 void caosVM::c_TRCK() {
318 VM_PARAM_INTEGER(transition
)
319 VM_PARAM_INTEGER(style
)
320 VM_PARAM_INTEGER(ypercent
)
321 VM_PARAM_INTEGER(xpercent
)
322 VM_PARAM_AGENT(agent
)
324 getCamera()->trackAgent(agent
, xpercent
, ypercent
, (trackstyle
)style
, (cameratransition
)transition
);
331 Returns agent being tracked by the current camera, if any.
333 void caosVM::v_TRCK() {
334 result
.setAgent(getCamera()->trackedAgent());
338 LINE (command) x1 (integer) y1 (integer) x2 (integer) y2 (integer) r (integer) g (integer) b (integer) stipple_on (integer) stipple_off (integer)
341 Draw a line between two endpoints with the given coordinates, in the color specified by
342 the given red, green, and blue values.
344 Set stipple_on to a number of pixels to alternate for stippling, or set stipple_off to
347 Setting the the endpoints to the same point will remove all lines for the agent.
349 void caosVM::c_LINE() {
350 VM_PARAM_INTEGER(stipple_off
)
351 VM_PARAM_INTEGER(stipple_on
)
365 SNAX (integer) filename (string)
368 Determines whether or not the given image file exists in the world
369 images directory (0 or 1).
371 void caosVM::v_SNAX() {
372 VM_PARAM_STRING(filename
)
375 if (!world
.findFile(std::string("/Images/") + filename
+ ".s16").empty())
377 else if (!world
.findFile(std::string("/Images/") + filename
+ ".c16").empty())
382 SCAM (command) agent (agent) part (integer)
385 Sets which camera to use in camera macro commands. If 'agent' and
386 'part' are NULL, the main camera will be used.
388 void caosVM::c_SCAM() {
389 VM_PARAM_INTEGER(part
)
390 VM_PARAM_AGENT(agent
)
397 CompoundAgent
*a
= dynamic_cast<CompoundAgent
*>(agent
.get());
399 CompoundPart
*p
= a
->part(part
);
401 CameraPart
*c
= dynamic_cast<CameraPart
*>(p
);
404 camera
= c
->getCamera();
408 ZOOM (command) pixels (integer) x (integer) y (integer)
411 Zoom the current camera by the given number of pixels on the given x/y
412 coordinates in the world. If the coordinates are set to -1, the
413 current center position of the camera's view will be used.
415 void caosVM::c_ZOOM() {
418 VM_PARAM_INTEGER(pixels
)
424 SNAP (command) filename (string) x (integer) y (integer) width (integer) height (integer) zoom (integer)
427 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.
429 void caosVM::c_SNAP() {
430 VM_PARAM_INTEGER(zoom
)
431 VM_PARAM_INTEGER(height
)
432 VM_PARAM_INTEGER(width
)
435 VM_PARAM_STRING(filename
)
441 LOFT (integer) filename (string)
444 void caosVM::v_LOFT() {
445 VM_PARAM_STRING(filename
)
447 result
.setInt(0); // TODO
451 BKGD (command) metaroom_id (integer) background (string) transition (integer)
454 void caosVM::c_BKGD() {
455 VM_PARAM_INTEGER(transition
)
456 VM_PARAM_STRING(background
)
457 VM_PARAM_INTEGER(metaroomid
)
459 MetaRoom
*metaroom
= world
.map
.getMetaRoom(metaroomid
);
460 caos_assert(metaroom
);
466 BKGD (string) metaroom_id (integer)
469 void caosVM::v_BKGD() {
470 VM_PARAM_INTEGER(metaroomid
)
472 MetaRoom
*metaroom
= world
.map
.getMetaRoom(metaroomid
);
473 caos_assert(metaroom
);
475 result
.setString(""); // TODO
482 void caosVM::c_FRSH() {
487 SYS: CMRP (command) x (integer) y (integer)
491 Smooth scroll the camera so that the specified coordinates are in the center of the window.
492 (Yes, this differs from what the incorrect C2 documentation says.)
494 void caosVM::c_SYS_CMRP() {
498 getCamera()->moveTo(x
- (getCamera()->getWidth() / 2), y
- (getCamera()->getWidth() / 2), smoothscroll
);
502 SYS: CMRA (command) x (integer) y (integer)
504 %pragma variants c1 c2
506 void caosVM::c_SYS_CMRA() {
510 getCamera()->moveTo(x
, y
);
516 %pragma variants c1 c2
518 void caosVM::c_SYS_CAMT() {
519 // TODO: does CAMT behave like this in c1/c2?
520 int xpos
= (int)(targ
->x
- (getCamera()->getWidth() / 2.0f
) + (targ
->getWidth() / 2.0f
));
521 int ypos
= (int)(targ
->y
- (getCamera()->getHeight() / 2.0f
) + (targ
->getHeight() / 2.0f
));
522 getCamera()->moveTo(xpos
, ypos
);
528 %pragma variants c1 c2
530 Move the main window to the front of the screen.
532 void caosVM::c_SYS_WTOP() {