1 | /* |
---|
2 | * Abuse - dark 2D side-scrolling platform game |
---|
3 | * Copyright (c) 1995 Crack dot Com |
---|
4 | * Copyright (c) 2005-2011 Sam Hocevar <sam@hocevar.net> |
---|
5 | * |
---|
6 | * This software was released into the Public Domain. As with most public |
---|
7 | * domain software, no warranty is made or implied by Crack dot Com or |
---|
8 | * Jonathan Clark. |
---|
9 | */ |
---|
10 | |
---|
11 | #ifndef _IMAGE_HPP_ |
---|
12 | #define _IMAGE_HPP_ |
---|
13 | |
---|
14 | #include <stdlib.h> |
---|
15 | #include "linked.h" |
---|
16 | #include "palette.h" |
---|
17 | #include "system.h" |
---|
18 | #include "specs.h" |
---|
19 | #define MAX_DIRTY 200 |
---|
20 | #define Inew(pointer,type); { make_block(sizeof(type)); pointer=new type; } |
---|
21 | |
---|
22 | extern char const *imerr_messages[]; // correspond to imERRORS |
---|
23 | #define imREAD_ERROR 1 |
---|
24 | #define imINCORRECT_FILETYPE 2 |
---|
25 | #define imFILE_CORRUPTED 3 |
---|
26 | #define imFILE_NOT_FOUND 4 |
---|
27 | #define imMEMORY_ERROR 5 |
---|
28 | #define imNOT_SUPPORTED 6 |
---|
29 | #define imWRITE_ERROR 7 |
---|
30 | #define imMAX_ERROR 7 |
---|
31 | |
---|
32 | int16_t current_error(); |
---|
33 | void clear_errors(); |
---|
34 | void set_error(int16_t x); |
---|
35 | int16_t last_error(); |
---|
36 | void make_block(size_t size); |
---|
37 | void image_init(); |
---|
38 | void image_uninit(); |
---|
39 | extern linked_list image_list; |
---|
40 | |
---|
41 | typedef struct image_color_t |
---|
42 | { |
---|
43 | uint16_t r; |
---|
44 | uint16_t g; |
---|
45 | uint16_t b; |
---|
46 | } image_color; |
---|
47 | |
---|
48 | class filter; |
---|
49 | |
---|
50 | |
---|
51 | class dirty_rect : public linked_node |
---|
52 | { |
---|
53 | public : |
---|
54 | int16_t dx1,dy1,dx2,dy2; |
---|
55 | dirty_rect(int16_t x1, int16_t y1, int16_t x2, int16_t y2) |
---|
56 | { dx1=x1; dy1=y1; dx2=x2; dy2=y2; |
---|
57 | if(x2<x1 || y2<y1) |
---|
58 | printf("add inccorect dirty\n"); |
---|
59 | } |
---|
60 | virtual int16_t compare(void *n1, int16_t field) |
---|
61 | { return((dirty_rect *)n1)->dy1>dy1; } |
---|
62 | } ; |
---|
63 | |
---|
64 | class image_descriptor |
---|
65 | { |
---|
66 | private: |
---|
67 | int16_t l, h; |
---|
68 | int16_t clipx1, clipy1, clipx2, clipy2; |
---|
69 | |
---|
70 | public: |
---|
71 | uint8_t keep_dirt, |
---|
72 | static_mem; // if set, don't free memory on exit |
---|
73 | |
---|
74 | linked_list dirties; |
---|
75 | void *extended_descriptor; |
---|
76 | |
---|
77 | image_descriptor(int16_t length, int16_t height, |
---|
78 | int keep_dirties = 1, int static_memory = 0); |
---|
79 | int16_t bound_x1(int16_t x1) { return x1 < clipx1 ? clipx1 : x1; } |
---|
80 | int16_t bound_y1(int16_t y1) { return y1 < clipy1 ? clipy1 : y1; } |
---|
81 | int16_t bound_x2(int16_t x2) { return x2 > clipx2 ? clipx2 : x2; } |
---|
82 | int16_t bound_y2(int16_t y2) { return y2 > clipy2 ? clipy2 : y2; } |
---|
83 | int16_t x1_clip() { return clipx1; } |
---|
84 | int16_t y1_clip() { return clipy1; } |
---|
85 | int16_t x2_clip() { return clipx2; } |
---|
86 | int16_t y2_clip() { return clipy2; } |
---|
87 | void dirty_area(int16_t x1, int16_t y1, int16_t x2, int16_t y2) { ; } |
---|
88 | void clean_area(int16_t x1, int16_t y1, int16_t x2, int16_t y2) { ; } |
---|
89 | void clear_dirties(); |
---|
90 | int16_t get_dirty_area(int16_t &x1, int16_t &y1, int16_t &x2, int16_t &y2) |
---|
91 | { |
---|
92 | return 0; |
---|
93 | } |
---|
94 | void get_clip(int16_t &x1, int16_t &y1, int16_t &x2, int16_t &y2) |
---|
95 | { |
---|
96 | x1 = clipx1; y1 = clipy1; x2 = clipx2; y2 = clipy2; |
---|
97 | } |
---|
98 | void set_clip(int16_t x1, int16_t y1, int16_t x2, int16_t y2) |
---|
99 | { |
---|
100 | if(x2 < x1) x2 = x1; |
---|
101 | if(y2 < y1) y2 = y1; |
---|
102 | if(x1 < 0) clipx1 = 0; else clipx1 = x1; |
---|
103 | if(y1 < 0) clipy1 = 0; else clipy1 = y1; |
---|
104 | if(x2 >= l) clipx2 = l - 1; else clipx2 = x2; |
---|
105 | if(y2 >= h) clipy2 = h - 1; else clipy2 = y2; |
---|
106 | } |
---|
107 | void reduce_dirties(); |
---|
108 | void add_dirty(int x1, int y1, int x2, int y2); |
---|
109 | void delete_dirty(int x1, int y1, int x2, int y2); |
---|
110 | void resize(int16_t length, int16_t height) |
---|
111 | { |
---|
112 | l = length; h = height; |
---|
113 | clipx1 = 0; clipy1 = 0; clipx2 = l - 1; clipy2 = h - 1; |
---|
114 | } |
---|
115 | }; |
---|
116 | |
---|
117 | class image : public linked_node |
---|
118 | { |
---|
119 | private: |
---|
120 | uint8_t *data; |
---|
121 | int16_t w, h; |
---|
122 | void make_page(int16_t width, int16_t height, uint8_t *page_buffer); |
---|
123 | void delete_page(); |
---|
124 | bool _locked; |
---|
125 | |
---|
126 | public: |
---|
127 | image_descriptor *special; |
---|
128 | |
---|
129 | image(spec_entry *e, bFILE *fp); |
---|
130 | image(bFILE *fp); |
---|
131 | image(int16_t width, int16_t height, |
---|
132 | uint8_t *page_buffer = NULL, int16_t create_descriptor = 0); |
---|
133 | ~image(); |
---|
134 | |
---|
135 | void lock(); |
---|
136 | void unlock(); |
---|
137 | |
---|
138 | uint8_t pixel(int16_t x, int16_t y); |
---|
139 | void putpixel(int16_t x, int16_t y, char color); |
---|
140 | uint8_t *scan_line(int16_t y) |
---|
141 | { |
---|
142 | return data + y * w; |
---|
143 | } |
---|
144 | uint8_t *next_line(int16_t lasty, uint8_t *last_scan) |
---|
145 | { |
---|
146 | return last_scan + w; |
---|
147 | } |
---|
148 | int32_t total_pixels(uint8_t background=0); |
---|
149 | image *copy(); // makes a copy of an image |
---|
150 | void clear(int16_t color = -1); // -1 is background color |
---|
151 | void to_24bit(palette &pal); |
---|
152 | int16_t width() |
---|
153 | { |
---|
154 | return (int16_t)w; |
---|
155 | } |
---|
156 | int16_t height() |
---|
157 | { |
---|
158 | return (int16_t)h; |
---|
159 | } |
---|
160 | int16_t pitch() |
---|
161 | { |
---|
162 | return (int16_t)w; // FIXME: for now, pitch == width |
---|
163 | } |
---|
164 | void scroll(int16_t x1, int16_t y1, int16_t x2, int16_t y2, |
---|
165 | int16_t xd, int16_t yd); |
---|
166 | void fill_image(image *screen, int16_t x1, int16_t y1, |
---|
167 | int16_t x2, int16_t y2, int16_t align = 1); |
---|
168 | void put_image(image *screen, int16_t x, int16_t y, char transparent = 0); |
---|
169 | void put_part(image *screen, int16_t x, int16_t y, int16_t x1, int16_t y1, |
---|
170 | int16_t x2, int16_t y2, char transparent = 0); |
---|
171 | void put_part_xrev(image *screen, int16_t x, int16_t y, |
---|
172 | int16_t x1, int16_t y1, int16_t x2, int16_t y2, |
---|
173 | char transparent = 0); |
---|
174 | void put_part_masked(image *screen, image *mask, int16_t x, int16_t y, |
---|
175 | int16_t maskx, int16_t masky, int16_t x1, int16_t y1, |
---|
176 | int16_t x2, int16_t y2); |
---|
177 | image *copy_part_dithered(int16_t x1, int16_t y1, int16_t x2, int16_t y2); |
---|
178 | void bar(int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint8_t color); |
---|
179 | void xor_bar(int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint8_t color); |
---|
180 | void widget_bar(int16_t x1, int16_t y1, int16_t x2, int16_t y2, |
---|
181 | uint8_t light, uint8_t med, uint8_t dark); |
---|
182 | void line(int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint8_t color); |
---|
183 | void rectangle(int16_t x1, int16_t y1, int16_t x2, int16_t y2, |
---|
184 | uint8_t color); |
---|
185 | void burn_led(int16_t x, int16_t y, int32_t num, int16_t color, |
---|
186 | int16_t scale = 1); |
---|
187 | void set_clip(int16_t x1, int16_t y1, int16_t x2, int16_t y2); |
---|
188 | void get_clip(int16_t &x1,int16_t &y1,int16_t &x2,int16_t &y2); |
---|
189 | void in_clip(int16_t x1, int16_t y1, int16_t x2, int16_t y2); |
---|
190 | |
---|
191 | void dirt_off() |
---|
192 | { |
---|
193 | if(special && special->keep_dirt) special->keep_dirt = 0; |
---|
194 | } |
---|
195 | void dirt_on() |
---|
196 | { |
---|
197 | if(special) special->keep_dirt = 1; |
---|
198 | } |
---|
199 | |
---|
200 | void add_dirty(int x1, int y1, int x2, int y2) |
---|
201 | { |
---|
202 | if(special) special->add_dirty(x1, y1, x2, y2); |
---|
203 | } |
---|
204 | void delete_dirty(int x1, int y1, int x2, int y2) |
---|
205 | { |
---|
206 | if(special) special->delete_dirty(x1, y1, x2, y2); |
---|
207 | } |
---|
208 | void clear_dirties() |
---|
209 | { |
---|
210 | if(special) special->clear_dirties(); |
---|
211 | } |
---|
212 | void dither(palette *pal); // use a b&w palette! |
---|
213 | void resize(int16_t new_width, int16_t new_height); |
---|
214 | void change_size(int16_t new_width, int16_t new_height, |
---|
215 | uint8_t *page = NULL); |
---|
216 | void flood_fill(int16_t x, int16_t y, uint8_t color); |
---|
217 | image *create_smooth(int16_t smoothness = 1); // 0 no smoothness |
---|
218 | void unpack_scanline(int16_t line, char bitsperpixel = 1); |
---|
219 | uint8_t brightest_color(palette *pal); |
---|
220 | void flip_x(); |
---|
221 | void flip_y(); |
---|
222 | void make_color(uint8_t color); |
---|
223 | uint8_t darkest_color(palette *pal, int16_t noblack = 0); |
---|
224 | }; |
---|
225 | |
---|
226 | class image_controller |
---|
227 | { |
---|
228 | public: |
---|
229 | image_controller() |
---|
230 | { |
---|
231 | image_init(); |
---|
232 | } |
---|
233 | ~image_controller() |
---|
234 | { |
---|
235 | image_uninit(); |
---|
236 | } |
---|
237 | }; |
---|
238 | |
---|
239 | #endif /* _IMAGE_HPP_ */ |
---|
240 | |
---|