1 // -*- Mode: C++; tab-width:2; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 // vi:tw=80:et:ts=2:sts=2 3 // 4 // ----------------------------------------------------------------------- 5 // 6 // This file is part of RLVM, a RealLive virtual machine clone. 7 // 8 // ----------------------------------------------------------------------- 9 // 10 // Copyright (C) 2006, 2007 Elliot Glaysher 11 // 12 // This program is free software; you can redistribute it and/or modify 13 // it under the terms of the GNU General Public License as published by 14 // the Free Software Foundation; either version 3 of the License, or 15 // (at your option) any later version. 16 // 17 // This program is distributed in the hope that it will be useful, 18 // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 // GNU General Public License for more details. 21 // 22 // You should have received a copy of the GNU General Public License 23 // along with this program; if not, write to the Free Software 24 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. 25 // 26 // ----------------------------------------------------------------------- 27 28 #ifndef SRC_SYSTEMS_BASE_GRAPHICS_OBJECT_H_ 29 #define SRC_SYSTEMS_BASE_GRAPHICS_OBJECT_H_ 30 31 #include <boost/scoped_ptr.hpp> 32 #include <boost/shared_ptr.hpp> 33 #include <boost/serialization/access.hpp> 34 #include <boost/serialization/version.hpp> 35 36 #include <string> 37 #include <vector> 38 39 #include "systems/base/colour.h" 40 #include "systems/base/rect.h" 41 42 class RLMachine; 43 class GraphicsObject; 44 class GraphicsObjectSlot; 45 class GraphicsObjectData; 46 class ObjectMutator; 47 48 // Describes an independent, movable graphical object on the 49 // screen. GraphicsObject, internally, references a copy-on-write 50 // datastructure, which in turn has optional components to save 51 // memory. 52 // 53 // TODO(erg): I want to put index checks on a lot of these accessors. 54 class GraphicsObject { 55 public: 56 GraphicsObject(); 57 GraphicsObject(const GraphicsObject& obj); 58 ~GraphicsObject(); 59 GraphicsObject& operator=(const GraphicsObject& obj); 60 61 // Object Position Accessors 62 63 // This code, while a boolean, uses an int so that we can get rid 64 // of one template parameter in one of the generic operation 65 // functors. visible()66 int visible() const { return impl_->visible_; } 67 void SetVisible(const int in); 68 x()69 int x() const { return impl_->x_; } 70 void SetX(const int x); 71 y()72 int y() const { return impl_->y_; } 73 void SetY(const int y); 74 x_adjustment(int idx)75 int x_adjustment(int idx) const { return impl_->adjust_x_[idx]; } 76 int GetXAdjustmentSum() const; 77 void SetXAdjustment(int idx, int x); 78 y_adjustment(int idx)79 int y_adjustment(int idx) const { return impl_->adjust_y_[idx]; } 80 int GetYAdjustmentSum() const; 81 void SetYAdjustment(int idx, int y); 82 vert()83 int vert() const { return impl_->whatever_adjust_vert_operates_on_; } 84 void SetVert(const int vert); 85 origin_x()86 int origin_x() const { return impl_->origin_x_; } 87 void SetOriginX(const int x); 88 origin_y()89 int origin_y() const { return impl_->origin_y_; } 90 void SetOriginY(const int y); 91 rep_origin_x()92 int rep_origin_x() const { return impl_->rep_origin_x_; } 93 void SetRepOriginX(const int x); 94 rep_origin_y()95 int rep_origin_y() const { return impl_->rep_origin_y_; } 96 void SetRepOriginY(const int y); 97 98 // Note: width/height are object scale percentages. width()99 int width() const { return impl_->width_; } 100 void SetWidth(const int in); height()101 int height() const { return impl_->height_; } 102 void SetHeight(const int in); 103 104 // Note: width/height are object scale factors out of 1000. hq_width()105 int hq_width() const { return impl_->hq_width_; } 106 void SetHqWidth(const int in); hq_height()107 int hq_height() const { return impl_->hq_height_; } 108 void SetHqHeight(const int in); 109 110 float GetWidthScaleFactor() const; 111 float GetHeightScaleFactor() const; 112 rotation()113 int rotation() const { return impl_->rotation_; } 114 void SetRotation(const int in); 115 116 int PixelWidth() const; 117 int PixelHeight() const; 118 119 // Object attribute accessors 120 int GetPattNo() const; 121 void SetPattNo(const int in); 122 mono()123 int mono() const { return impl_->mono_; } 124 void SetMono(const int in); 125 invert()126 int invert() const { return impl_->invert_; } 127 void SetInvert(const int in); 128 light()129 int light() const { return impl_->light_; } 130 void SetLight(const int in); 131 tint()132 const RGBColour& tint() const { return impl_->tint_; } tint_red()133 int tint_red() const { return impl_->tint_.r(); } tint_green()134 int tint_green() const { return impl_->tint_.g(); } tint_blue()135 int tint_blue() const { return impl_->tint_.b(); } 136 void SetTint(const RGBColour& colour); 137 void SetTintRed(const int in); 138 void SetTintGreen(const int in); 139 void SetTintBlue(const int in); 140 colour()141 const RGBAColour& colour() const { return impl_->colour_; } colour_red()142 int colour_red() const { return impl_->colour_.r(); } colour_green()143 int colour_green() const { return impl_->colour_.g(); } colour_blue()144 int colour_blue() const { return impl_->colour_.b(); } colour_level()145 int colour_level() const { return impl_->colour_.a(); } 146 void SetColour(const RGBAColour& colour); 147 void SetColourRed(const int in); 148 void SetColourGreen(const int in); 149 void SetColourBlue(const int in); 150 void SetColourLevel(const int in); 151 composite_mode()152 int composite_mode() const { return impl_->composite_mode_; } 153 void SetCompositeMode(const int in); 154 scroll_rate_x()155 int scroll_rate_x() const { return impl_->scroll_rate_x_; } 156 void SetScrollRateX(const int x); 157 scroll_rate_y()158 int scroll_rate_y() const { return impl_->scroll_rate_y_; } 159 void SetScrollRateY(const int y); 160 161 // Three level zorder. z_order()162 int z_order() const { return impl_->z_order_; } 163 void SetZOrder(const int in); z_layer()164 int z_layer() const { return impl_->z_layer_; } 165 void SetZLayer(const int in); z_depth()166 int z_depth() const { return impl_->z_depth_; } 167 void SetZDepth(const int in); 168 169 int GetComputedAlpha() const; raw_alpha()170 int raw_alpha() const { return impl_->alpha_; } 171 void SetAlpha(const int alpha); 172 alpha_adjustment(int idx)173 int alpha_adjustment(int idx) const { return impl_->adjust_alpha_[idx]; } 174 void SetAlphaAdjustment(int idx, int alpha); 175 clip_rect()176 const Rect& clip_rect() const { return impl_->clip_; } has_clip_rect()177 bool has_clip_rect() const { 178 return impl_->clip_.width() >= 0 || impl_->clip_.height() >= 0; 179 } 180 void ClearClipRect(); 181 void SetClipRect(const Rect& rec); 182 own_clip_rect()183 const Rect& own_clip_rect() const { return impl_->own_clip_; } has_own_clip_rect()184 bool has_own_clip_rect() const { 185 return impl_->own_clip_.width() >= 0 || impl_->own_clip_.height() >= 0; 186 } 187 void ClearOwnClipRect(); 188 void SetOwnClipRect(const Rect& rec); 189 has_object_data()190 bool has_object_data() const { return object_data_.get(); } 191 192 GraphicsObjectData& GetObjectData(); 193 void SetObjectData(GraphicsObjectData* obj); 194 195 // Render! 196 void Render(int objNum, const GraphicsObject* parent, std::ostream* tree); 197 198 // Frees the object data. Corresponds to objFree, but is also invoked by 199 // other commands. 200 void FreeObjectData(); 201 202 // Resets/reinitializes all the object parameters without deleting the loaded 203 // graphics object data. 204 void InitializeParams(); 205 206 // Both frees the object data and initializes parameters. 207 void FreeDataAndInitializeParams(); 208 wipe_copy()209 int wipe_copy() const { return impl_->wipe_copy_; } 210 void SetWipeCopy(const int wipe_copy); 211 212 // Called each pass through the gameloop to see if this object needs 213 // to force a redraw, or something. 214 void Execute(RLMachine& machine); 215 216 // Text Object accessors 217 void SetTextText(const std::string& utf8str); 218 const std::string& GetTextText() const; 219 220 void SetTextOps(int size, 221 int xspace, 222 int yspace, 223 int char_count, 224 int colour, 225 int shadow); 226 int GetTextSize() const; 227 int GetTextXSpace() const; 228 int GetTextYSpace() const; 229 int GetTextCharCount() const; 230 int GetTextColour() const; 231 int GetTextShadowColour() const; 232 233 // Drift object accessors 234 void SetDriftOpts(int count, 235 int use_animation, 236 int start_pattern, 237 int end_pattern, 238 int total_animation_time_ms, 239 int yspeed, 240 int period, 241 int amplitude, 242 int use_drift, 243 int unknown_drift_property, 244 int driftspeed, 245 Rect driftarea); 246 247 int GetDriftParticleCount() const; 248 int GetDriftUseAnimation() const; 249 int GetDriftStartPattern() const; 250 int GetDriftEndPattern() const; 251 int GetDriftAnimationTime() const; 252 int GetDriftYSpeed() const; 253 int GetDriftPeriod() const; 254 int GetDriftAmplitude() const; 255 int GetDriftUseDrift() const; 256 int GetDriftUnknown() const; 257 int GetDriftDriftSpeed() const; 258 Rect GetDriftArea() const; 259 260 // Digit object accessors 261 void SetDigitValue(int value); 262 void SetDigitOpts(int digits, int zero, int sign, int pack, int space); 263 264 int GetDigitValue() const; 265 int GetDigitDigits() const; 266 int GetDigitZero() const; 267 int GetDigitSign() const; 268 int GetDigitPack() const; 269 int GetDigitSpace() const; 270 271 // Button object accessors 272 void SetButtonOpts(int action, int se, int group, int button_number); 273 void SetButtonState(int state); 274 275 int IsButton() const; 276 int GetButtonAction() const; 277 int GetButtonSe() const; 278 int GetButtonGroup() const; 279 int GetButtonNumber() const; 280 int GetButtonState() const; 281 282 // Called only from ButtonObjectSelectLongOperation. Sets override 283 // properties. 284 void SetButtonOverrides(int override_pattern, 285 int override_x_offset, 286 int override_y_offset); 287 void ClearButtonOverrides(); 288 289 bool GetButtonUsingOverides() const; 290 int GetButtonPatternOverride() const; 291 int GetButtonXOffsetOverride() const; 292 int GetButtonYOffsetOverride() const; 293 294 // Adds a mutator to the list of active mutators. GraphicsSystem takes 295 // ownership of the passed in object. 296 void AddObjectMutator(std::unique_ptr<ObjectMutator> mutator); 297 298 // Returns true if a mutator matching the following parameters is currently 299 // running. 300 bool IsMutatorRunningMatching(int repno, const std::string& name); 301 302 // Ends all mutators that match the given parameters. 303 void EndObjectMutatorMatching(RLMachine& machine, 304 int repno, 305 const std::string& name, 306 int speedup); 307 308 // Returns a string for each mutator. 309 std::vector<std::string> GetMutatorNames() const; 310 311 // Returns the number of GraphicsObject instances sharing the 312 // internal copy-on-write object. Only used in unit testing. reference_count()313 int32_t reference_count() const { return impl_.use_count(); } 314 315 // Whether we have the default shared data. Only used in unit testing. is_cleared()316 bool is_cleared() const { return impl_ == s_empty_impl; } 317 318 private: 319 // Makes the internal copy for our copy-on-write semantics. This function 320 // checks to see if our Impl object has only one reference to it. If it 321 // doesn't, a local copy is made. 322 void MakeImplUnique(); 323 324 // Immediately delete all mutators; doesn't run their SetToEnd() method. 325 void DeleteObjectMutators(); 326 327 // Implementation data structure. GraphicsObject::Impl is the internal data 328 // store for GraphicsObjects' copy-on-write semantics. 329 struct Impl { 330 Impl(); 331 Impl(const Impl& rhs); 332 ~Impl(); 333 334 Impl& operator=(const Impl& rhs); 335 336 // Visibility. Different from whether an object is in the bg or fg layer 337 bool visible_; 338 339 // The positional coordinates of the object 340 int x_, y_; 341 342 // Eight additional parameters that are added to x and y during 343 // rendering. 344 int adjust_x_[8], adjust_y_[8]; 345 346 // Whatever obj_adjust_vert operates on; what's this used for? 347 int whatever_adjust_vert_operates_on_; 348 349 // The origin 350 int origin_x_, origin_y_; 351 352 // "Rep" origin. This second origin is added to the normal origin 353 // only in cases of rotating and scaling. 354 int rep_origin_x_, rep_origin_y_; 355 356 // The size of the object, given in integer percentages of [0, 357 // 100]. Used for scaling. 358 int width_, height_; 359 360 // A second scaling factor, given between [0, 1000]. 361 int hq_width_, hq_height_; 362 363 // The rotation degree / 10 364 int rotation_; 365 366 // Object attributes. 367 368 // The region ("pattern") in g00 bitmaps 369 int patt_no_; 370 371 // The source alpha for this image 372 int alpha_; 373 374 // Eight additional alphas that are averaged during rendering. 375 int adjust_alpha_[8]; 376 377 // The clipping region for this image 378 Rect clip_; 379 380 // A second clipping region in the object's own space. 381 Rect own_clip_; 382 383 // The monochrome transformation 384 int mono_; 385 386 // The invert transformation 387 int invert_; 388 389 int light_; 390 391 RGBColour tint_; 392 393 // Applies a colour to the object by blending it directly at the 394 // alpha components opacity. 395 RGBAColour colour_; 396 397 int composite_mode_; 398 399 int scroll_rate_x_, scroll_rate_y_; 400 401 // Three deep zordering. 402 int z_order_, z_layer_, z_depth_; 403 404 // Text Object properties 405 struct TextProperties { 406 TextProperties(); 407 408 std::string value; 409 410 int text_size, xspace, yspace; 411 412 int char_count; 413 int colour; 414 int shadow_colour; 415 416 // boost::serialization support 417 template <class Archive> 418 void serialize(Archive& ar, unsigned int version); 419 }; 420 421 void MakeSureHaveTextProperties(); 422 boost::scoped_ptr<TextProperties> text_properties_; 423 424 // Drift Object properties 425 struct DriftProperties { 426 DriftProperties(); 427 428 int count; 429 430 int use_animation; 431 int start_pattern; 432 int end_pattern; 433 int total_animation_time_ms; 434 435 int yspeed; 436 437 int period; 438 int amplitude; 439 440 int use_drift; 441 int unknown_drift_property; 442 int driftspeed; 443 444 Rect drift_area; 445 446 // boost::serialization support 447 template <class Archive> 448 void serialize(Archive& ar, unsigned int version); 449 }; 450 451 void MakeSureHaveDriftProperties(); 452 boost::scoped_ptr<DriftProperties> drift_properties_; 453 454 // Digit Object properties 455 struct DigitProperties { 456 DigitProperties(); 457 458 int value; 459 460 int digits; 461 int zero; 462 int sign; 463 int pack; 464 int space; 465 466 // boost::serialization support 467 template <class Archive> 468 void serialize(Archive& ar, unsigned int version); 469 }; 470 471 void MakeSureHaveDigitProperties(); 472 boost::scoped_ptr<DigitProperties> digit_properties_; 473 474 // Button Object properties 475 struct ButtonProperties { 476 ButtonProperties(); 477 478 int is_button; 479 480 int action; 481 int se; 482 int group; 483 int button_number; 484 485 int state; 486 487 bool using_overides; 488 int pattern_override; 489 int x_offset_override; 490 int y_offset_override; 491 492 // boost::serialization support 493 template <class Archive> 494 void serialize(Archive& ar, unsigned int version); 495 }; 496 497 void MakeSureHaveButtonProperties(); 498 boost::scoped_ptr<ButtonProperties> button_properties_; 499 500 // The wipe_copy bit 501 int wipe_copy_; 502 503 friend class boost::serialization::access; 504 505 // boost::serialization support 506 template <class Archive> 507 void serialize(Archive& ar, unsigned int version); 508 }; 509 510 // Default empty GraphicsObject::Impl. This variable is allocated 511 // once, and then is used as the initial value of impl_, where it 512 // is cloned on write. 513 static const boost::shared_ptr<GraphicsObject::Impl> s_empty_impl; 514 515 // Our actual implementation data 516 boost::shared_ptr<GraphicsObject::Impl> impl_; 517 518 // The actual data used to render the object 519 boost::scoped_ptr<GraphicsObjectData> object_data_; 520 521 // Tasks that run every tick. Used to mutate object parameters over time (and 522 // how we check from a blocking LongOperation if the mutation is ongoing). 523 // 524 // I think R23 mentioned that these were called "Parameter Events" in the 525 // RLMAX SDK. 526 std::vector<std::unique_ptr<ObjectMutator>> object_mutators_; 527 528 friend class boost::serialization::access; 529 530 // boost::serialization support 531 template <class Archive> 532 void serialize(Archive& ar, unsigned int version); 533 }; 534 535 BOOST_CLASS_VERSION(GraphicsObject::Impl, 7) 536 537 static const int OBJ_FG = 0; 538 static const int OBJ_BG = 1; 539 540 #endif // SRC_SYSTEMS_BASE_GRAPHICS_OBJECT_H_ 541