cosmetix
[dd2d.git] / d2dgfx.d
blobe96d94b72140086d6416ddff71762f0e45612835
1 /* DooM2D: Midnight on the Firing Line
2 * coded by Ketmar // Invisible Vector <ketmar@ketmar.no-ip.org>
3 * Understanding is not required. Only obedience.
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 module d2dgfx is aliced;
19 private:
21 import arsd.color;
22 import iv.stream;
24 import glutils;
25 import console;
26 import wadarc;
29 // ////////////////////////////////////////////////////////////////////////// //
30 public __gshared Color[256] d2dpal;
33 public void loadPalette () {
34 auto fl = openFile("playpal.pal");
35 foreach (immutable idx; 0..256) {
36 ubyte r = cast(ubyte)(fl.readNum!ubyte()*4);
37 ubyte g = cast(ubyte)(fl.readNum!ubyte()*4);
38 ubyte b = cast(ubyte)(fl.readNum!ubyte()*4);
39 d2dpal[idx].r = r;
40 d2dpal[idx].g = g;
41 d2dpal[idx].b = b;
42 d2dpal[idx].a = 255;
44 // color 0 is transparent
45 d2dpal[0].asUint = 0;
49 // ////////////////////////////////////////////////////////////////////////// //
50 public final class D2DImage {
51 public:
52 int sx, sy;
53 int width, height;
54 ubyte[] data;
55 TrueColorImage img;
56 Texture tex;
58 this (string name) {
59 try {
60 auto fl = openFile(name);
61 load(fl, false);
62 return;
63 } catch (Exception) {}
64 import std.algorithm : endsWith;
65 if (name.endsWith("_mirrored.vga")) {
66 auto fl = openFile(name[0..$-13]~".vga");
67 load(fl, true);
68 return;
70 auto fl = openFile(name); // throw error message
73 @property bool valid () const pure nothrow @safe @nogc { pragma(inline, true); return (data !is null && width > 0 && height > 0); }
75 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)); }
77 void clear () {
78 if (tex !is null) tex.clear;
79 //if (img !is null) img.clear;
80 tex = null;
81 img = null;
82 data = null;
83 width = height = 0;
84 sx = sy = 0;
87 @property TrueColorImage asTCImage () {
88 if (img is null && valid) {
89 img = new TrueColorImage(width, height);
90 auto cols = img.imageData.colors.ptr;
91 foreach (int y; 0..height) {
92 foreach (int x; 0..width) {
93 ubyte c = data.ptr[y*width+x];
94 if (c == 0) {
95 *cols = Color(0, 0, 0, 0); // transparent
96 } else {
97 *cols = d2dpal[c];
99 ++cols;
103 return img;
106 void createGLTex () {
107 if (tex is null && valid) tex = new Texture(asTCImage, Texture.Option.Nearest);
110 @property Texture asGLTex () {
111 if (tex is null && valid) tex = new Texture(asTCImage, Texture.Option.Nearest);
112 return tex;
115 // for bottom-up view
116 void drawAtXY (int x, int y) {
117 asGLTex();
118 if (tex !is null) {
119 y += sy-height;
120 glutils.drawAtXY(tex, x-sx, y);
124 private:
125 void load(ST) (auto ref ST fi, bool mirrored) if (isReadableStream!ST) {
126 width = fi.readNum!ushort();
127 height = fi.readNum!ushort();
128 if (width < 1) assert(0);
129 if (height < 1) assert(0);
130 sx = fi.readNum!short();
131 sy = fi.readNum!short();
132 data = new ubyte[width*height];
133 fi.rawReadExact(data[]);
134 if (mirrored) mirrorVga();
137 void mirrorVga () {
138 auto nd = new ubyte[](data.length);
139 foreach (int y; 0..height) {
140 int npos = y*width+width-1;
141 foreach (int x; 0..width) {
142 nd[npos--] = data[y*width+x];
145 data = nd;