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, by |
---|
8 | * Jonathan Clark, or by Sam Hocevar. |
---|
9 | */ |
---|
10 | |
---|
11 | #ifndef _IMAGE_HPP_ |
---|
12 | #define _IMAGE_HPP_ |
---|
13 | |
---|
14 | #include <stdlib.h> |
---|
15 | #include "palette.h" |
---|
16 | #include "specs.h" |
---|
17 | #define MAX_DIRTY 200 |
---|
18 | |
---|
19 | void image_init(); |
---|
20 | void image_uninit(); |
---|
21 | extern Array<class AImage *> image_list; |
---|
22 | |
---|
23 | class ADirtyRect |
---|
24 | { |
---|
25 | public : |
---|
26 | inline ADirtyRect() {} |
---|
27 | |
---|
28 | ADirtyRect(ivec2 aa, ivec2 bb) |
---|
29 | { |
---|
30 | ASSERT(bb >= aa); |
---|
31 | m_aa = aa; |
---|
32 | m_bb = bb; |
---|
33 | } |
---|
34 | |
---|
35 | ivec2 m_aa, m_bb; |
---|
36 | }; |
---|
37 | |
---|
38 | class image_descriptor |
---|
39 | { |
---|
40 | friend class AImage; |
---|
41 | |
---|
42 | public: |
---|
43 | uint8_t keep_dirt; |
---|
44 | |
---|
45 | void *extended_descriptor; |
---|
46 | |
---|
47 | image_descriptor(ivec2 size, int keep_dirties = 1); |
---|
48 | int bound_x1(int x1) { return lol::max(x1, m_aa.x); } |
---|
49 | int bound_y1(int y1) { return lol::max(y1, m_aa.y); } |
---|
50 | int bound_x2(int x2) { return lol::min(x2, m_bb.x); } |
---|
51 | int bound_y2(int y2) { return lol::min(y2, m_bb.y); } |
---|
52 | inline int x1_clip() { return m_aa.x; } |
---|
53 | inline int y1_clip() { return m_aa.y; } |
---|
54 | inline int x2_clip() { return m_bb.x; } |
---|
55 | inline int y2_clip() { return m_bb.y; } |
---|
56 | void GetClip(ivec2 &aa, ivec2 &bb) |
---|
57 | { |
---|
58 | aa = m_aa; bb = m_bb; |
---|
59 | } |
---|
60 | void SetClip(ivec2 aa, ivec2 bb) |
---|
61 | { |
---|
62 | m_aa = lol::max(aa, ivec2(0)); |
---|
63 | m_bb = lol::min(lol::max(bb, m_aa + ivec2(1)), m_size); |
---|
64 | } |
---|
65 | void GetClip(int &x1, int &y1, int &x2, int &y2) |
---|
66 | { |
---|
67 | x1 = m_aa.x; y1 = m_aa.y; x2 = m_bb.x; y2 = m_bb.y; |
---|
68 | } |
---|
69 | void SetClip(int x1, int y1, int x2, int y2) |
---|
70 | { |
---|
71 | if(x2 < x1 + 1) x2 = x1 + 1; |
---|
72 | if(y2 < y1 + 1) y2 = y1 + 1; |
---|
73 | m_aa.x = lol::max(x1, 0); m_aa.y = lol::max(y1, 0); |
---|
74 | m_bb.x = lol::min(x2, m_size.x); m_bb.y = lol::min(y2, m_size.y); |
---|
75 | } |
---|
76 | void ReduceDirties(); |
---|
77 | void AddDirty(ivec2 aa, ivec2 bb); |
---|
78 | void DeleteDirty(ivec2 aa, ivec2 bb); |
---|
79 | void Resize(ivec2 size) |
---|
80 | { |
---|
81 | m_size = size; |
---|
82 | m_aa = ivec2(0); |
---|
83 | m_bb = size; |
---|
84 | } |
---|
85 | |
---|
86 | Array<ADirtyRect> m_dirties; /* Is public because of update_dirties() */ |
---|
87 | |
---|
88 | private: |
---|
89 | ivec2 m_size, m_aa, m_bb; |
---|
90 | }; |
---|
91 | |
---|
92 | class AImage |
---|
93 | { |
---|
94 | public: |
---|
95 | AImage(bFILE *fp, SpecEntry *e = NULL); |
---|
96 | AImage(ivec2 size, int create_descriptor = 0); |
---|
97 | ~AImage(); |
---|
98 | |
---|
99 | uint8_t Pixel(ivec2 pos); |
---|
100 | void PutPixel(ivec2 pos, uint8_t color); |
---|
101 | |
---|
102 | ivec2 Size() const { return m_size; } |
---|
103 | |
---|
104 | private: |
---|
105 | Array<uint8_t> m_data; |
---|
106 | ivec2 m_size; |
---|
107 | |
---|
108 | public: |
---|
109 | image_descriptor *m_special; |
---|
110 | |
---|
111 | inline uint8_t *scan_line(int y) |
---|
112 | { |
---|
113 | /* FIXME: use the following construct for runtime checks */ |
---|
114 | //return &m_data[y * m_size.x]; |
---|
115 | |
---|
116 | return m_data.Data() + y * m_size.x; |
---|
117 | } |
---|
118 | AImage *copy(); // makes a copy of an image |
---|
119 | void clear(int color = -1); // -1 is background color |
---|
120 | |
---|
121 | void PutImage(AImage *screen, ivec2 pos, int transparent = 0); |
---|
122 | void PutPart(AImage *screen, ivec2 pos, ivec2 aa, ivec2 bb, |
---|
123 | int transparent = 0); |
---|
124 | AImage *copy_part_dithered(int x1, int y1, int x2, int y2); |
---|
125 | void Bar(ivec2 p1, ivec2 p2, uint8_t color); |
---|
126 | void xor_bar(int x1, int y1, int x2, int y2, uint8_t color); |
---|
127 | void WidgetBar(ivec2 p1, ivec2 p2, |
---|
128 | uint8_t light, uint8_t med, uint8_t dark); |
---|
129 | void Line(ivec2 p1, ivec2 p2, uint8_t color); |
---|
130 | void Rectangle(ivec2 p1, ivec2 p2, uint8_t color); |
---|
131 | void burn_led(int x, int y, int32_t num, int color, int scale = 1); |
---|
132 | void SetClip(ivec2 aa, ivec2 bb); |
---|
133 | void GetClip(ivec2 &aa, ivec2 &bb); |
---|
134 | void InClip(ivec2 aa, ivec2 bb); |
---|
135 | void SetClip(int x1, int y1, int x2, int y2); |
---|
136 | void GetClip(int &x1, int &y1, int &x2, int &y2); |
---|
137 | void InClip(int x1, int y1, int x2, int y2); |
---|
138 | |
---|
139 | void dirt_off() |
---|
140 | { |
---|
141 | if(m_special && m_special->keep_dirt) m_special->keep_dirt = 0; |
---|
142 | } |
---|
143 | void dirt_on() |
---|
144 | { |
---|
145 | if(m_special) m_special->keep_dirt = 1; |
---|
146 | } |
---|
147 | |
---|
148 | void AddDirty(ivec2 aa, ivec2 bb) |
---|
149 | { |
---|
150 | if (m_special) m_special->AddDirty(aa, bb); |
---|
151 | } |
---|
152 | void DeleteDirty(ivec2 aa, ivec2 bb) |
---|
153 | { |
---|
154 | if (m_special) m_special->DeleteDirty(aa, bb); |
---|
155 | } |
---|
156 | void dither(Palette *pal); // use a b&w palette! |
---|
157 | void Scale(ivec2 size); |
---|
158 | void SetSize(ivec2 size); |
---|
159 | void flood_fill(int x, int y, uint8_t color); |
---|
160 | AImage *create_smooth(int smoothness = 1); // 0 no smoothness |
---|
161 | void unpack_scanline(int line, char bitsperpixel = 1); |
---|
162 | void FlipX(); |
---|
163 | void FlipY(); |
---|
164 | }; |
---|
165 | |
---|
166 | class image_controller |
---|
167 | { |
---|
168 | public: |
---|
169 | image_controller() |
---|
170 | { |
---|
171 | image_init(); |
---|
172 | } |
---|
173 | ~image_controller() |
---|
174 | { |
---|
175 | image_uninit(); |
---|
176 | } |
---|
177 | }; |
---|
178 | |
---|
179 | #endif /* _IMAGE_HPP_ */ |
---|
180 | |
---|