diff options
Diffstat (limited to 'engines/cge/bitmap.cpp')
-rw-r--r-- | engines/cge/bitmap.cpp | 673 |
1 files changed, 314 insertions, 359 deletions
diff --git a/engines/cge/bitmap.cpp b/engines/cge/bitmap.cpp index 1201b84fc6..1e5310a8e7 100644 --- a/engines/cge/bitmap.cpp +++ b/engines/cge/bitmap.cpp @@ -25,434 +25,389 @@ * Copyright (c) 1994-1995 Janus B. Wisniewski and L.K. Avalon */ -#include "cge/bitmap.h" -#include "cge/cfile.h" -#include "cge/jbw.h" - -#ifdef VOL - #include "cge/vol.h" -#endif - -#include <dos.h> +#include "cge/bitmap.h" +#include "cge/cfile.h" +#include "cge/jbw.h" +#include "cge/vol.h" +#include <dos.h> #include "cge/cfile.h" #include "common/system.h" namespace CGE { -//-------------------------------------------------------------------------- - - - - -DAC * BITMAP::Pal = NULL; - +DAC *BITMAP::Pal = NULL; #define MAXPATH 128 #pragma argsused -BITMAP::BITMAP (const char * fname, bool rem) -: M(NULL), V(NULL) -{ - char pat[MAXPATH]; - - ForceExt(pat, fname, ".VBM"); - - #if (BMP_MODE < 2) - if (rem && PIC_FILE::Exist(pat)) - { - PIC_FILE file(pat); - if (file.Error == 0) - if (! VBMLoad(&file)) - error("Bad VBM [%s]", fname); - } - else - #endif - { - #if (BMP_MODE) - ForceExt(pat, fname, ".BMP"); - PIC_FILE file(pat); - if (file.Error == 0) +BITMAP::BITMAP(const char *fname, bool rem) : M(NULL), V(NULL) { + char pat[MAXPATH]; + ForceExt(pat, fname, ".VBM"); + +#if (BMP_MODE < 2) + if (rem && PIC_FILE::Exist(pat)) { + PIC_FILE file(pat); + if ((file.Error == 0) && (!VBMLoad(&file))) + error("Bad VBM [%s]", fname); + } else +#endif { - if (BMPLoad(&file)) - { - Code(); - if (rem) - { - free(M); - M = NULL; +#if (BMP_MODE) + ForceExt(pat, fname, ".BMP"); + PIC_FILE file(pat); + if (file.Error == 0) { + if (BMPLoad(&file)) { + Code(); + if (rem) { + free(M); + M = NULL; + } + } else + error("Bad BMP [%s]", fname); } - } - else - error("Bad BMP [%s]", fname); +#else + error("Bad VBM [%s]", fname); +#endif } - #else - error("Bad VBM [%s]", fname); - #endif - } } - - - -BITMAP::BITMAP (uint16 w, uint16 h, uint8 * map) -: W(w), H(h), M(map), V(NULL) -{ - if (map) Code(); +BITMAP::BITMAP(uint16 w, uint16 h, uint8 *map) : W(w), H(h), M(map), V(NULL) { + if (map) + Code(); } - - // following routine creates filled rectangle // immediately as VGA video chunks, in near memory as fast as possible, // especially for text line real time display - -BITMAP::BITMAP (uint16 w, uint16 h, uint8 fill) -: W((w + 3) & ~3), // only full uint32 allowed! - H(h), - M(NULL) -{ - uint16 dsiz = W >> 2; // data size (1 plane line size) - uint16 lsiz = 2 + dsiz + 2; // uint16 for line header, uint16 for gap - uint16 psiz = H * lsiz; // - last gape, but + plane trailer - uint8 * v = new uint8[4 * psiz // the same for 4 planes - + H * sizeof(*B)]; // + room for wash table - if (v == NULL) - error("No core"); - - * (uint16 *) v = CPY | dsiz; // data chunk hader - memset(v+2, fill, dsiz); // data bytes - * (uint16 *) (v + lsiz - 2) = SKP | ((SCR_WID / 4) - dsiz); // gap - memcpy(v + lsiz, v, psiz - lsiz); // tricky replicate lines - * (uint16 *) (v + psiz - 2) = EOI; // plane trailer uint16 - memcpy(v + psiz, v, 3 * psiz); // tricky replicate planes - HideDesc * b = (HideDesc *) (v + 4 * psiz); - b->skip = (SCR_WID - W) >> 2; - b->hide = W >> 2; - memcpy(b+1, b, (H-1) * sizeof(*b)); // tricky fill entire table - b->skip = 0; // fix the first entry - V = v; - B = b; +BITMAP::BITMAP(uint16 w, uint16 h, uint8 fill) + : W((w + 3) & ~3), // only full uint32 allowed! + H(h), + M(NULL) { + uint16 dsiz = W >> 2; // data size (1 plane line size) + uint16 lsiz = 2 + dsiz + 2; // uint16 for line header, uint16 for gap + uint16 psiz = H * lsiz; // - last gape, but + plane trailer + uint8 *v = new uint8[4 * psiz + H * sizeof(*B)];// the same for 4 planes + // + room for wash table + if (v == NULL) + error("No core"); + + *(uint16 *) v = CPY | dsiz; // data chunk hader + memset(v + 2, fill, dsiz); // data bytes + *(uint16 *)(v + lsiz - 2) = SKP | ((SCR_WID / 4) - dsiz); // gap + memcpy(v + lsiz, v, psiz - lsiz); // tricky replicate lines + *(uint16 *)(v + psiz - 2) = EOI; // plane trailer uint16 + memcpy(v + psiz, v, 3 * psiz); // tricky replicate planes + HideDesc *b = (HideDesc *)(v + 4 * psiz); + b->skip = (SCR_WID - W) >> 2; + b->hide = W >> 2; + memcpy(b + 1, b, (H - 1) * sizeof(*b)); // tricky fill entire table + b->skip = 0; // fix the first entry + V = v; + B = b; } - - - - - -BITMAP::BITMAP (const BITMAP& bmp) -: W(bmp.W), H(bmp.H), - M(NULL), V(NULL) -{ - uint8 * v0 = bmp.V; - if (v0) - { - uint16 vsiz = (uint8*)(bmp.B) - (uint8*)(v0); - uint16 siz = vsiz + H * sizeof(HideDesc); - uint8 * v1 = farnew(uint8, siz); - if (v1 == NULL) - error("No core"); - memcpy(v1, v0, siz); - B = (HideDesc *) ((V = v1) + vsiz); - } +BITMAP::BITMAP(const BITMAP &bmp) : W(bmp.W), H(bmp.H), M(NULL), V(NULL) { + uint8 *v0 = bmp.V; + if (v0) { + uint16 vsiz = (uint8 *)(bmp.B) - (uint8 *)(v0); + uint16 siz = vsiz + H * sizeof(HideDesc); + uint8 *v1 = farnew(uint8, siz); + if (v1 == NULL) + error("No core"); + memcpy(v1, v0, siz); + B = (HideDesc *)((V = v1) + vsiz); + } } - - - -BITMAP::~BITMAP (void) -{ - switch (MemType(M)) - { - case FAR_MEM : free(M); break; - } - switch (MemType(V)) - { - case NEAR_MEM : delete[] (uint8 *) V; break; - case FAR_MEM : free(V); break; - } +BITMAP::~BITMAP(void) { + if (MemType(M) == FAR_MEM) + free(M); + + switch (MemType(V)) { + case NEAR_MEM : + delete[](uint8 *) V; + break; + case FAR_MEM : + free(V); + break; + } } - -BITMAP& BITMAP::operator = (const BITMAP& bmp) -{ - uint8 * v0 = bmp.V; - W = bmp.W; - H = bmp.H; - M = NULL; - if (MemType(V) == FAR_MEM) free(V); - if (v0 == NULL) V = NULL; - else - { - uint16 vsiz = (uint8*)bmp.B - (uint8*)v0; - uint16 siz = vsiz + H * sizeof(HideDesc); - uint8 * v1 = farnew(uint8, siz); - if (v1 == NULL) - error("No core"); - memcpy(v1, v0, siz); - B = (HideDesc *) ((V = v1) + vsiz); - } - return *this; +BITMAP &BITMAP::operator = (const BITMAP &bmp) { + uint8 *v0 = bmp.V; + W = bmp.W; + H = bmp.H; + M = NULL; + if (MemType(V) == FAR_MEM) + free(V); + if (v0 == NULL) + V = NULL; + else { + uint16 vsiz = (uint8 *)bmp.B - (uint8 *)v0; + uint16 siz = vsiz + H * sizeof(HideDesc); + uint8 *v1 = farnew(uint8, siz); + if (v1 == NULL) + error("No core"); + memcpy(v1, v0, siz); + B = (HideDesc *)((V = v1) + vsiz); + } + return *this; } - - - -uint16 BITMAP::MoveVmap (uint8 * buf) -{ - if (V) - { - uint16 vsiz = (uint8*)B - (uint8*)V; - uint16 siz = vsiz + H * sizeof(HideDesc); - memcpy(buf, V, siz); - if (MemType(V) == FAR_MEM) free(V); - B = (HideDesc *) ((V = buf) + vsiz); - return siz; - } - return 0; +uint16 BITMAP::MoveVmap(uint8 *buf) { + if (V) { + uint16 vsiz = (uint8 *)B - (uint8 *)V; + uint16 siz = vsiz + H * sizeof(HideDesc); + memcpy(buf, V, siz); + if (MemType(V) == FAR_MEM) + free(V); + B = (HideDesc *)((V = buf) + vsiz); + return siz; + } + return 0; } +BMP_PTR BITMAP::Code(void) { + if (M) { + uint16 i, cnt; + if (V) { // old X-map exists, so remove it + switch (MemType(V)) { + case NEAR_MEM : + delete[](uint8 *) V; + break; + case FAR_MEM : + free(V); + break; + } + V = NULL; + } + while (true) { // at most 2 times: for (V == NULL) & for allocated block; + uint8 *im = V + 2; + uint16 *cp = (uint16 *) V; + int bpl; + if (V) { // 2nd pass - fill the hide table + for (i = 0; i < H; i ++) { + B[i].skip = 0xFFFF; + B[i].hide = 0x0000; + } + } + for (bpl = 0; bpl < 4; bpl ++) { // once per each bitplane + uint8 *bm = M; + bool skip = (bm[bpl] == TRANS); + uint16 j; + + cnt = 0; + for (i = 0; i < H; i ++) { // once per each line + uint8 pix; + for (j = bpl; j < W; j += 4) { + pix = bm[j]; + if (V && pix != TRANS) { + if (j < B[i].skip) + B[i].skip = j; + + if (j >= B[i].hide) + B[i].hide = j + 1; + } + if ((pix == TRANS) != skip || cnt >= 0x3FF0) { // end of block + cnt |= (skip) ? SKP : CPY; + if (V) + *cp = cnt; // store block description uint16 + + cp = (uint16 *) im; + im += 2; + skip = (pix == TRANS); + cnt = 0; + } + if (! skip) { + if (V) + *im = pix; + ++ im; + } + ++ cnt; + } + + bm += W; + if (W < SCR_WID) { + if (skip) { + cnt += (SCR_WID - j + 3) / 4; + } else { + cnt |= CPY; + if (V) + *cp = cnt; + + cp = (uint16 *) im; + im += 2; + skip = true; + cnt = (SCR_WID - j + 3) / 4; + } + } + } + if (cnt && ! skip) { + cnt |= CPY; + if (V) + *cp = cnt; + + cp = (uint16 *) im; + im += 2; + } + if (V) + *cp = EOI; + cp = (uint16 *) im; + im += 2; + } + if (V) + break; + uint16 sizV = (uint16)(im - 2 - V); + V = farnew(uint8, sizV + H * sizeof(*B)); + if (! V) + error("No core"); -BMP_PTR BITMAP::Code (void) -{ - if (M) - { - uint16 i, cnt; - - if (V) // old X-map exists, so remove it - { - switch (MemType(V)) - { - case NEAR_MEM : delete[] (uint8 *) V; break; - case FAR_MEM : free(V); break; - } - V = NULL; - } - - while (true) // at most 2 times: for (V == NULL) & for allocated block; - { - uint8 * im = V+2; - uint16 * cp = (uint16 *) V; - int bpl; - - if (V) // 2nd pass - fill the hide table - { - for (i = 0; i < H; i ++) - { - B[i].skip = 0xFFFF; - B[i].hide = 0x0000; + B = (HideDesc *)(V + sizV); } - } - for (bpl = 0; bpl < 4; bpl ++) // once per each bitplane - { - uint8 * bm = M; - bool skip = (bm[bpl] == TRANS); - uint16 j; - - cnt = 0; - for (i = 0; i < H; i ++) // once per each line - { - uint8 pix; - for (j = bpl; j < W; j += 4) - { - pix = bm[j]; - if (V && pix != TRANS) - { - if (j < B[i].skip) B[i].skip = j; - if (j >= B[i].hide) B[i].hide = j+1; + cnt = 0; + for (i = 0; i < H; i ++) { + if (B[i].skip == 0xFFFF) { // whole line is skipped + B[i].skip = (cnt + SCR_WID) >> 2; + cnt = 0; + } else { + uint16 s = B[i].skip & ~3; + uint16 h = (B[i].hide + 3) & ~3; + B[i].skip = (cnt + s) >> 2; + B[i].hide = (h - s) >> 2; + cnt = SCR_WID - h; } - if ((pix == TRANS) != skip || cnt >= 0x3FF0) // end of block - { - cnt |= (skip) ? SKP : CPY; - if (V) - { - *cp = cnt; // store block description uint16 - } - cp = (uint16 *) im; - im += 2; - skip = (pix == TRANS); - cnt = 0; - } - if (! skip) - { - if (V) * im = pix; - ++ im; - } - ++ cnt; - } - - bm += W; - if (W < SCR_WID) - { - if (skip) - { - cnt += (SCR_WID - j + 3) / 4; - } - else - { - cnt |= CPY; - if (V) - { - *cp = cnt; - } - cp = (uint16 *) im; - im += 2; - skip = true; - cnt = (SCR_WID - j + 3) / 4; - } - } } - if (cnt && ! skip) - { - cnt |= CPY; - if (V) - { - *cp = cnt; - } - cp = (uint16 *) im; - im += 2; - } - if (V) *cp = EOI; - cp = (uint16 *) im; - im += 2; - } - if (V) break; - uint16 sizV = (uint16) (im - 2 - V); - V = farnew(uint8, sizV + H * sizeof(*B)); - if (! V) - { - error("No core"); - } - B = (HideDesc *) (V + sizV); - } - cnt = 0; - for (i = 0; i < H; i ++) - { - if (B[i].skip == 0xFFFF) // whole line is skipped - { - B[i].skip = (cnt + SCR_WID) >> 2; - cnt = 0; - } - else - { - uint16 s = B[i].skip & ~3; - uint16 h = (B[i].hide + 3) & ~3; - B[i].skip = (cnt + s) >> 2; - B[i].hide = (h - s) >> 2; - cnt = SCR_WID - h; - } } - } - return this; + return this; } +bool BITMAP::SolidAt(int x, int y) { + uint8 *m; + uint16 r, n, n0; + if ((x >= W) || (y >= H)) + return false; + m = V; + r = x % 4; + n0 = (SCR_WID * y + x) / 4, n = 0; + while (r) { + uint16 w, t; -bool BITMAP::SolidAt (int x, int y) -{ - uint8 * m; - uint16 r, n, n0; - - if (x >= W || y >= H) return false; + w = *(uint16 *) m; + m += 2; + t = w & 0xC000; + w &= 0x3FFF; - m = V; - r = x % 4; - n0 = (SCR_WID * y + x) / 4, n = 0; - - while (r) - { - uint16 w, t; - - w = * (uint16 *) m; - m += 2; - t = w & 0xC000; - w &= 0x3FFF; - - switch (t) - { - case EOI : -- r; - case SKP : w = 0; break; - case REP : w = 1; break; + switch (t) { + case EOI : + -- r; + case SKP : + w = 0; + break; + case REP : + w = 1; + break; + } + m += w; } - m += w; - } - - while (true) - { - uint16 w, t; - w = * (uint16 *) m; - m += 2; - t = w & 0xC000; - w &= 0x3FFF; - - if (n > n0) return false; - n += w; - switch (t) - { - case EOI : return false; - case SKP : w = 0; break; - case REP : - case CPY : if (n-w <= n0 && n > n0) return true; break; + while (true) { + uint16 w, t; + + w = * (uint16 *) m; + m += 2; + t = w & 0xC000; + w &= 0x3FFF; + + if (n > n0) + return false; + + n += w; + switch (t) { + case EOI : + return false; + case SKP : + w = 0; + break; + case REP : + case CPY : + if (n - w <= n0 && n > n0) + return true; + break; + } + m += (t == REP) ? 1 : w; } - m += (t == REP) ? 1 : w; - } } +bool BITMAP::VBMSave(XFILE *f) { + uint16 p = (Pal != NULL), + n = ((uint16)(((uint8 *)B) - V)) + H * sizeof(HideDesc); + if (f->Error == 0) + f->Write((uint8 *)&p, sizeof(p)); + + if (f->Error == 0) + f->Write((uint8 *)&n, sizeof(n)); + if (f->Error == 0) + f->Write((uint8 *)&W, sizeof(W)); + if (f->Error == 0) + f->Write((uint8 *)&H, sizeof(H)); + if (f->Error == 0) + if (p) + f->Write((uint8 *)Pal, 256 * sizeof(DAC)); -bool BITMAP::VBMSave (XFILE * f) -{ - uint16 p = (Pal != NULL), - n = ((uint16) (((uint8 *)B) - V)) + H * sizeof(HideDesc); - if (f->Error == 0) f->Write((uint8 *)&p, sizeof(p)); - if (f->Error == 0) f->Write((uint8 *)&n, sizeof(n)); - if (f->Error == 0) f->Write((uint8 *)&W, sizeof(W)); - if (f->Error == 0) f->Write((uint8 *)&H, sizeof(H)); - if (f->Error == 0) if (p) f->Write((uint8 *)Pal, 256 * sizeof(DAC)); - if (f->Error == 0) f->Write(V, n); - return (f->Error == 0); + if (f->Error == 0) + f->Write(V, n); + + return (f->Error == 0); } +bool BITMAP::VBMLoad(XFILE *f) { + uint16 p = 0, n = 0; + if (f->Error == 0) + f->Read((uint8 *)&p, sizeof(p)); + if (f->Error == 0) + f->Read((uint8 *)&n, sizeof(n)); + if (f->Error == 0) + f->Read((uint8 *)&W, sizeof(W)); -bool BITMAP::VBMLoad (XFILE * f) -{ - uint16 p = 0, n = 0; - if (f->Error == 0) f->Read((uint8 *)&p, sizeof(p)); - if (f->Error == 0) f->Read((uint8 *)&n, sizeof(n)); - if (f->Error == 0) f->Read((uint8 *)&W, sizeof(W)); - if (f->Error == 0) f->Read((uint8 *)&H, sizeof(H)); - if (f->Error == 0) - { - if (p) - { - if (Pal) f->Read((uint8 *)Pal, 256 * sizeof(DAC)); - else f->Seek(f->Mark() + 256 * sizeof(DAC)); + if (f->Error == 0) + f->Read((uint8 *)&H, sizeof(H)); + + if (f->Error == 0) { + if (p) { + if (Pal) + f->Read((uint8 *)Pal, 256 * sizeof(DAC)); + else + f->Seek(f->Mark() + 256 * sizeof(DAC)); + } } - } - if ((V = farnew(uint8, n)) == NULL) return false; - if (f->Error == 0) f->Read(V, n); - B = (HideDesc *) (V + n - H * sizeof(HideDesc)); - return (f->Error == 0); -} + if ((V = farnew(uint8, n)) == NULL) + return false; + if (f->Error == 0) + f->Read(V, n); + B = (HideDesc *)(V + n - H * sizeof(HideDesc)); + return (f->Error == 0); +} } // End of namespace CGE |