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