koi moved to separate module
[dd2d.git] / d2dgfx.d
bloba26e77a46e16c29c307b8e8720df194f7a87577a
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 private import std.stdio : File;
53 public:
54 int sx, sy;
55 int width, height;
56 ubyte[] data;
57 TrueColorImage img;
58 Texture tex;
60 this (string name) {
61 try {
62 auto fl = openFile(name);
63 load(fl, false);
64 return;
65 } catch (Exception) {}
66 import std.algorithm : endsWith;
67 if (name.endsWith("_mirrored.vga")) {
68 auto fl = openFile(name[0..$-13]~".vga");
69 load(fl, true);
70 return;
72 auto fl = openFile(name); // throw error message
75 @property bool valid () const pure nothrow @safe @nogc { pragma(inline, true); return (data !is null && width > 0 && height > 0); }
77 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)); }
79 void clear () {
80 if (tex !is null) tex.clear;
81 //if (img !is null) img.clear;
82 tex = null;
83 img = null;
84 data = null;
85 width = height = 0;
86 sx = sy = 0;
89 @property TrueColorImage asTCImage () {
90 if (img is null && valid) {
91 img = new TrueColorImage(width, height);
92 auto cols = img.imageData.colors.ptr;
93 foreach (int y; 0..height) {
94 foreach (int x; 0..width) {
95 ubyte c = data.ptr[y*width+x];
96 if (c == 0) {
97 *cols = Color(0, 0, 0, 0); // transparent
98 } else {
99 *cols = d2dpal[c];
101 ++cols;
105 return img;
108 void createGLTex () {
109 if (tex is null && valid) tex = new Texture(asTCImage, Texture.Option.Nearest);
112 @property Texture asGLTex () {
113 if (tex is null && valid) tex = new Texture(asTCImage, Texture.Option.Nearest);
114 return tex;
117 // for bottom-up view
118 void drawAtXY (int x, int y) {
119 asGLTex();
120 if (tex !is null) {
121 y += sy-height;
122 glutils.drawAtXY(tex, x-sx, y);
126 private:
127 void load (File fi, bool mirrored) {
128 width = fi.readNum!ushort();
129 height = fi.readNum!ushort();
130 if (width < 1) assert(0);
131 if (height < 1) assert(0);
132 sx = fi.readNum!short();
133 sy = fi.readNum!short();
134 data = new ubyte[width*height];
135 fi.rawReadExact(data[]);
136 if (mirrored) mirrorVga();
139 void mirrorVga () {
140 auto nd = new ubyte[](data.length);
141 foreach (int y; 0..height) {
142 int npos = y*width+width-1;
143 foreach (int x; 0..width) {
144 nd[npos--] = data[y*width+x];
147 data = nd;