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) 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_GAN_GRAPHICS_OBJECT_DATA_H_
29 #define SRC_SYSTEMS_BASE_GAN_GRAPHICS_OBJECT_DATA_H_
30 
31 #include <boost/serialization/access.hpp>
32 #include <boost/serialization/split_member.hpp>
33 
34 #include <iosfwd>
35 #include <memory>
36 #include <string>
37 #include <vector>
38 
39 #include "machine/rlmachine.h"
40 #include "machine/serialization.h"
41 #include "systems/base/graphics_object_data.h"
42 
43 class Surface;
44 class System;
45 class RLMachine;
46 class GraphicsObject;
47 
48 // -----------------------------------------------------------------------
49 
50 // In-memory representation of a GAN file. Responsible for reading in,
51 // storing, and rendering GAN data as a GraphicsObjectData.
52 class GanGraphicsObjectData : public GraphicsObjectData {
53  public:
54   explicit GanGraphicsObjectData(System& system);
55   GanGraphicsObjectData(System& system,
56                         const std::string& ganfile,
57                         const std::string& imgfile);
58   virtual ~GanGraphicsObjectData();
59 
60   void LoadGANData();
61 
62   virtual int PixelWidth(const GraphicsObject& rendering_properties) override;
63   virtual int PixelHeight(const GraphicsObject& rendering_properties) override;
64 
65   virtual GraphicsObjectData* Clone() const override;
66   virtual void Execute(RLMachine& machine) override;
67 
IsAnimation()68   virtual bool IsAnimation() const override { return true; }
69   virtual void PlaySet(int set) override;
70 
71  protected:
72   // Resets to the first frame.
73   virtual void LoopAnimation() override;
74 
75   virtual std::shared_ptr<const Surface> CurrentSurface(
76       const GraphicsObject& go) override;
77   virtual Rect SrcRect(const GraphicsObject& go) override;
78   virtual Point DstOrigin(const GraphicsObject& go) override;
79   virtual int GetRenderingAlpha(const GraphicsObject& go,
80                                 const GraphicsObject* parent) override;
81   virtual void ObjectInfo(std::ostream& tree) override;
82 
83  private:
84   struct Frame {
85     int pattern;
86     int x;
87     int y;
88     int time;
89     int alpha;
90     int other;  // No idea what this is.
91   };
92 
93   typedef std::vector<std::vector<Frame>> AnimationSets;
94 
95   void TestFileMagic(const std::string& file_name,
96                      std::unique_ptr<char[]>& gan_data,
97                      int file_size);
98   void ReadData(const std::string& file_name,
99                 std::unique_ptr<char[]>& gan_data,
100                 int file_size);
101   Frame ReadSetFrame(const std::string& filename, const char*& data);
102 
103   // Throws an error on bad GAN files.
104   void ThrowBadFormat(const std::string& filename, const std::string& error);
105 
106   System& system_;
107 
108   AnimationSets animation_sets;
109 
110   std::string gan_filename_;
111   std::string img_filename_;
112 
113   int current_set_;
114   int current_frame_;
115   int time_at_last_frame_change_;
116 
117   // The image the above coordinates map into.
118   std::shared_ptr<const Surface> image_;
119 
120   friend class boost::serialization::access;
121 
122   // boost::serialization forward declaration
123   template <class Archive>
124   void save(Archive& ar, const unsigned int file_version) const;
125 
126   // boost::serialization forward declaration
127   template <class Archive>
128   void load(Archive& ar, const unsigned int file_version);
129 
130   BOOST_SERIALIZATION_SPLIT_MEMBER()
131 };
132 
133 // We need help creating GanGraphicsObjectData s since they don't have a
134 // default constructor:
135 namespace boost {
136 namespace serialization {
137 template <class Archive>
load_construct_data(Archive & ar,GanGraphicsObjectData * t,const unsigned int file_version)138 inline void load_construct_data(Archive& ar,
139                                 GanGraphicsObjectData* t,
140                                 const unsigned int file_version) {
141   ::new (t) GanGraphicsObjectData(Serialization::g_current_machine->system());
142 }
143 }  // namespace serialization
144 }  // namespace boost
145 
146 #endif  // SRC_SYSTEMS_BASE_GAN_GRAPHICS_OBJECT_DATA_H_
147