1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #ifndef NUVIE_CORE_TILE_MANAGER_H
24 #define NUVIE_CORE_TILE_MANAGER_H
25 
26 #include "ultima/nuvie/core/nuvie_defs.h"
27 #include "ultima/shared/std/string.h"
28 
29 namespace Ultima {
30 namespace Nuvie {
31 
32 class Configuration;
33 class Look;
34 
35 // tile types stored in masktype.vga
36 
37 #define U6TILE_PLAIN 0x0
38 #define U6TILE_TRANS 0x5
39 #define U6TILE_PBLCK 0xA
40 
41 #define TILEFLAG_WALL_MASK  0xf0 // 11110000
42 //flags1
43 #define TILEFLAG_WALL_NORTH 0x80
44 #define TILEFLAG_WALL_EAST  0x40
45 #define TILEFLAG_WALL_SOUTH 0x20
46 #define TILEFLAG_WALL_WEST  0x10
47 #define TILEFLAG_IMPEDANCE (TILEFLAG_WALL_NORTH|TILEFLAG_WALL_EAST|TILEFLAG_WALL_SOUTH|TILEFLAG_WALL_WEST)
48 #define TILEFLAG_IMPEDANCE_SHIFT 4
49 #define TILEFLAG_DAMAGING 0x8
50 #define TILEFLAG_WALL     0x4
51 #define TILEFLAG_BLOCKING 0x2
52 #define TILEFLAG_WATER    0x1
53 
54 //flags2
55 #define TILEFLAG_DOUBLE_WIDTH     0x80
56 #define TILEFLAG_DOUBLE_HEIGHT    0x40
57 #define TILEFLAG_MISSILE_BOUNDARY 0x20
58 #define TILEFLAG_TOPTILE          0x10
59 #define TILEFLAG_WINDOW           0x8
60 #define TILEFLAG_BOUNDARY         0x4
61 #define TILEFLAG_LIGHT_MSB        0x2
62 #define TILEFLAG_LIGHT_LSB        0x1
63 #define GET_TILE_LIGHT_LEVEL(x) (uint8)(x->flags2 & 0x3) // only use with a pointer
64 //flags3
65 #define TILEFLAG_ARTICLE_MSB     0x80 // 00 01 10 11
66 #define TILEFLAG_ARTICLE_LSB     0x40 // -  a  an the
67 #define TILEFLAG_UNKNOWN_3_5     0x20
68 #define TILEFLAG_IGNORE          0x10
69 #define TILEFLAG_UNKNOWN_3_3     0x8 // Flammable? Mostly_non_metal_object (not affected by acid-slug)?
70 #define TILEFLAG_FORCED_PASSABLE 0x4
71 #define TILEFLAG_CAN_PLACE_ONTOP 0x2
72 #define TILEFLAG_UNKNOWN_LAVA    0x1 // associated with some lava tiles
73 
74 // FIXME These should probably go else where.
75 #define TILE_U6_DIRECTION_CURSOR  364
76 #define TILE_U6_TARGET_CURSOR     365
77 
78 #define TILE_U6_GREEN_MAGIC 380
79 #define TILE_U6_PURPLE_MAGIC 381
80 #define TILE_U6_RED_MAGIC   382
81 #define TILE_U6_BLUE_MAGIC  383
82 #define TILE_U6_BLOCKED_EQUIP 389
83 #define TILE_U6_LIGHTNING   392
84 #define TILE_U6_FIREBALL    393
85 #define TILE_U6_SOME_KIND_OF_BLUE_FIELD 394 // ghost's outline for casting/going invis
86 #define TILE_U6_IS_THIS_AN_ICE_SHOT 395
87 #define TILE_U6_KILL_SHOT   396
88 #define TILE_U6_FIRE_SHOT   397
89 #define TILE_U6_SLING_STONE 398
90 #define TILE_U6_CANNONBALL  399
91 #define TILE_U6_EQUIP       410
92 #define TILE_U6_GARGOYLE_LENS_ANIM_1 440
93 #define TILE_U6_GARGOYLE_LENS_ANIM_2 441
94 #define TILE_U6_BRITANNIAN_LENS_ANIM_1 442
95 #define TILE_U6_BRITANNIAN_LENS_ANIM_2 443
96 #define TILE_U6_WIZARD_EYE  563
97 #define TILE_U6_ARROW       566
98 #define TILE_U6_BOLT        567
99 
100 #define TILE_SE_BLOCKED_EQUIP 391
101 #define TILE_SE_EQUIP         392
102 
103 #define TILE_MD_EQUIP         273
104 #define TILE_MD_BLOCKED_EQUIP 274
105 
106 #define TILE_MD_PURPLE_BERRY_MARKER 288
107 #define TILE_MD_GREEN_BERRY_MARKER 289
108 #define TILE_MD_BROWN_BERRY_MARKER 290
109 
110 #define TILE_WIDTH  16
111 #define TILE_HEIGHT 16
112 #define TILE_DATA_SIZE 256
113 
114 typedef struct {
115 	uint16 tile_num;
116 	bool passable;
117 	bool water;
118 	bool toptile;
119 	bool dbl_width;
120 	bool dbl_height;
121 	bool transparent;
122 	bool boundary;
123 	bool damages;
124 	uint8 article_n;
125 //uint8 qty;
126 //uint8 flags;
127 
128 	uint8 flags1;
129 	uint8 flags2;
130 	uint8 flags3;
131 
132 	unsigned char data[256];
133 } Tile;
134 
135 
136 typedef struct {
137 	uint16 number_of_tiles_to_animate;
138 	uint16 tile_to_animate[0x20];
139 	uint16 first_anim_frame[0x20];
140 	uint8 and_masks[0x20];
141 	uint8 shift_values[0x20];
142 	sint8 loop_count[0x20]; // times to animate (-1 = infinite)
143 	uint8 loop[0x20]; // 0 = loop forwards, 1 = backwards
144 } Animdata;
145 
146 class TileManager {
147 	Tile tile[2048];
148 	uint16 tileindex[2048]; //used for animated tiles
149 	uint16 game_counter, rgame_counter;
150 	Animdata animdata;
151 	Look *look;
152 
153 	char *desc_buf; // for look
154 	Configuration *config;
155 
156 	int game_type;
157 
158 	Tile *extendedTiles;
159 	uint16 numTiles;
160 
161 public:
162 
163 	TileManager(Configuration *cfg);
164 	~TileManager();
165 
166 	bool loadTiles();
167 	Tile *get_tile(uint16 tile_num);
168 	Tile *get_anim_base_tile(uint16 tile_num);
169 	Tile *get_original_tile(uint16 tile_num);
170 	void set_tile_index(uint16 tile_index, uint16 tile_num);
get_tile_index(uint16 tile_index)171 	uint16 get_tile_index(uint16 tile_index) {
172 		return (tileindex[tile_index]);
173 	}
174 	void set_anim_loop(uint16 tile_num, sint8 loopc, uint8 loop = 0);
175 
176 	const char *lookAtTile(uint16 tile_num, uint16 qty, bool show_prefix);
177 	bool tile_is_stackable(uint16 tile_num);
178 	void update();
179 	void update_timed_tiles(uint8 hour);
180 
get_number_of_animations()181 	uint8 get_number_of_animations() {
182 		return animdata.number_of_tiles_to_animate;
183 	}
get_anim_tile(uint8 anim_index)184 	uint16 get_anim_tile(uint8 anim_index) {
185 		return anim_index < animdata.number_of_tiles_to_animate ? animdata.tile_to_animate[anim_index] : 0;
186 	}
get_anim_first_frame(uint8 anim_index)187 	uint16 get_anim_first_frame(uint8 anim_index) {
188 		return anim_index < animdata.number_of_tiles_to_animate ? animdata.first_anim_frame[anim_index] : 0;
189 	}
190 	void set_anim_first_frame(uint16 anim_index, uint16 new_start_tile_num);
191 	void anim_play_repeated(uint8 anim_index);
192 	void anim_stop_playing(uint8 anim_index);
193 
194 
195 	Tile *get_rotated_tile(Tile *tile, float rotate, uint8 src_y_offset = 0);
196 	void get_rotated_tile(Tile *tile, Tile *dest_tile, float rotate, uint8 src_y_offset = 0);
197 
198 	Tile *get_cursor_tile();
199 	Tile *get_use_tile();
200 	const Tile *get_gump_cursor_tile();
201 
202 	Tile *loadCustomTiles(const Std::string filename, bool overwrite_tiles, bool copy_tileflags, uint16 tile_num_start_offset);
203 	void freeCustomTiles();
204 	void exportTilesetToBmpFile(Std::string filename, bool fixupU6Shoreline = true);
205 protected:
206 
207 	bool loadAnimData();
208 	bool loadTileFlag();
209 	void decodePixelBlockTile(unsigned char *tile_data, uint16 tile_num);
210 
211 	bool loadAnimMask();
212 
213 private:
214 
215 	Tile *get_extended_tile(uint16 tile_num);
216 	void copyTileMetaData(Tile *dest, Tile *src);
217 	Tile *addNewTiles(uint16 num_tiles);
218 
219 	void writeBmpTileData(unsigned char *data, Tile *t, bool transparent);
220 };
221 
222 } // End of namespace Nuvie
223 } // End of namespace Ultima
224 
225 #endif
226