cosmetix
[dd2d.git] / d2dgfx.d
blob87ede87e8f6c37b704fa27b5e13ef4a9ab145f11
1 module d2dgfx is aliced;
2 private:
4 import arsd.color;
5 import iv.stream;
7 import glutils;
8 import console;
9 import wadarc;
12 // ////////////////////////////////////////////////////////////////////////// //
13 public __gshared Color[256] d2dpal;
16 public void loadPalette () {
17 auto fl = openFile("playpal.pal");
18 foreach (immutable idx; 0..256) {
19 ubyte r = cast(ubyte)(fl.readNum!ubyte()*4);
20 ubyte g = cast(ubyte)(fl.readNum!ubyte()*4);
21 ubyte b = cast(ubyte)(fl.readNum!ubyte()*4);
22 d2dpal[idx].r = r;
23 d2dpal[idx].g = g;
24 d2dpal[idx].b = b;
25 d2dpal[idx].a = 255;
27 // color 0 is transparent
28 d2dpal[0].asUint = 0;
32 // ////////////////////////////////////////////////////////////////////////// //
33 public final class D2DImage {
34 private import std.stdio : File;
36 public:
37 int sx, sy;
38 int width, height;
39 ubyte[] data;
40 TrueColorImage img;
41 Texture tex;
43 this (string name) {
44 try {
45 auto fl = openFile(name);
46 load(fl, false);
47 return;
48 } catch (Exception) {}
49 import std.algorithm : endsWith;
50 if (name.endsWith("_mirrored.vga")) {
51 auto fl = openFile(name[0..$-13]~".vga");
52 load(fl, true);
53 return;
55 auto fl = openFile(name); // throw error message
58 @property bool valid () const pure nothrow @safe @nogc { /*pragma(inline, true);*/ return (data !is null && width > 0 && height > 0); }
60 Color opIndex (usize y, usize x) { pragma(inline, true); return (x < width && y < height ? d2dpal.ptr[data.ptr[y*width+x]] : Color(0, 0, 0, 0)); }
62 void clear () {
63 if (tex !is null) tex.clear;
64 //if (img !is null) img.clear;
65 tex = null;
66 img = null;
67 data = null;
68 width = height = 0;
69 sx = sy = 0;
72 @property TrueColorImage asTCImage () {
73 if (img is null && valid) {
74 img = new TrueColorImage(width, height);
75 auto cols = img.imageData.colors.ptr;
76 foreach (int y; 0..height) {
77 foreach (int x; 0..width) {
78 ubyte c = data.ptr[y*width+x];
79 if (c == 0) {
80 *cols = Color(0, 0, 0, 0); // transparent
81 } else {
82 *cols = d2dpal[c];
84 ++cols;
88 return img;
91 void createGLTex () {
92 if (tex is null && valid) tex = new Texture(asTCImage, Texture.Option.Nearest);
95 @property Texture asGLTex () {
96 if (tex is null && valid) tex = new Texture(asTCImage, Texture.Option.Nearest);
97 return tex;
100 // for bottom-up view
101 void drawAtXY (int x, int y) {
102 asGLTex();
103 if (tex !is null) {
104 y += sy-height;
105 glutils.drawAtXY(tex, x-sx, y);
109 private:
110 void load (File fi, bool mirrored) {
111 width = fi.readNum!ushort();
112 height = fi.readNum!ushort();
113 if (width < 1) assert(0);
114 if (height < 1) assert(0);
115 sx = fi.readNum!short();
116 sy = fi.readNum!short();
117 data = new ubyte[width*height];
118 fi.rawReadExact(data[]);
119 if (mirrored) mirrorVga();
122 void mirrorVga () {
123 auto nd = new ubyte[](data.length);
124 foreach (int y; 0..height) {
125 int npos = y*width+width-1;
126 foreach (int x; 0..width) {
127 nd[npos--] = data[y*width+x];
130 data = nd;