1 // Copyright 2015-2018 the openage authors. See copying.md for legal info.
2 
3 #pragma once
4 
5 #include <cstdint>
6 #include <vector>
7 
8 #include "../coord/phys.h"
9 #include "../gamedata/graphic.gen.h"
10 
11 namespace openage {
12 
13 class GameSpec;
14 class Texture;
15 class Sound;
16 
17 /**
18  * Handling animated and directional textures based on the game
19  * graphics data.
20  *
21  * These objects handle the drawing of regular textures to use a
22  * unit's direction and include delta graphics.
23  *
24  * This type can also deal with playing position based game sounds.
25  */
26 class UnitTexture {
27 public:
28 	/**
29 	 * Delta option specifies whether the delta graphics are included.
30 	 *
31 	 * Note that the game data contains loops in delta links
32 	 * which mean recursive loading should be avoided
33 	 */
34 	UnitTexture(GameSpec &spec, uint16_t graphic_id, bool delta=true);
35 	UnitTexture(GameSpec &spec, const gamedata::graphic *graphic, bool delta=true);
36 
37 	/**
38 	 * const attributes of the graphic
39 	 */
40 	const int16_t      id;
41 	const int16_t      sound_id;
42 	const unsigned int frame_count;
43 	const unsigned int angle_count;
44 	const int16_t      mirroring_mode;
45 	const float        frame_rate;
46 
47 	/**
48 	 * draw object with vertical orientation (arrows)
49 	 * adding an addtion degree of orientation
50 	 */
51 	const bool         use_up_angles;
52 
53 	/**
54 	 * use delta information
55 	 */
56 	const bool         use_deltas;
57 
58 	/**
59 	 * invalid unit textures will cause errors if drawn
60 	 */
61 	bool is_valid() const;
62 
63 	/**
64 	 * pixel size of this texture
65 	 */
66 	coord::viewport size() const;
67 
68 	/**
69 	 * a sample drawing for hud
70 	 */
71 	void sample(const coord::CoordManager &coord, const coord::camhud &draw_pos, unsigned color=1) const;
72 
73 	/**
74 	 * draw object with no direction
75 	 */
76 	void draw(const coord::CoordManager &coord, const coord::camgame &draw_pos, unsigned int frame, unsigned color) const;
77 
78 	/**
79 	 * draw object with direction
80 	 */
81 	void draw(const coord::CoordManager &coord, const coord::camgame &draw_pos, coord::phys3_delta &dir, unsigned int frame, unsigned color) const;
82 
83 	/**
84 	 * initialise graphic data
85 	 */
86 	void initialise(GameSpec &spec);
87 
88 private:
89 	/**
90 	 * use a regular texture for drawing
91 	 */
92 	const Texture *texture;
93 
94 	/**
95 	 * the above frame count covers the entire graphic (with deltas)
96 	 * the actual number in the base texture may be different
97 	 */
98 	unsigned int safe_frame_count;
99 	unsigned int angles_included;
100 	unsigned int angles_mirrored;
101 	unsigned int top_frame;
102 
103 	// avoid drawing missing graphics
104 	bool draw_this;
105 	const Sound *sound;
106 
107 	// delta graphic ids
108 	std::vector<gamedata::graphic_delta> delta_id;
109 
110 	// delta graphics
111 	std::vector<std::pair<std::unique_ptr<UnitTexture>, coord::camgame_delta>> deltas;
112 
113 	/**
114 	 * find which subtexture should be used for drawing this texture
115 	 */
116 	unsigned int subtexture(const Texture *t, unsigned int angle, unsigned int frame) const;
117 };
118 
119 /**
120  * the set of images to used based on unit direction,
121  * usually 8 directions to draw for each unit (3 are mirrored)
122  *
123  * @param dir a world space direction,
124  * @param angles number of angles, usually 8
125  * @param first_angle offset added to angle, modulo number of angles
126  * @return image set index
127  */
128 unsigned int dir_group(coord::phys3_delta dir, unsigned int angles=8);
129 
130 } // namespace openage
131