1 module PixelPerfectEngine.graphics.bitmap;
2 //import std.bitmanip;
3 import std.stdio;
4 import PixelPerfectEngine.system.exc;
5 
6 /*
7  * Copyright (C) 2015-2017, by Laszlo Szeremi under the Boost license.
8  *
9  * Pixel Perfect Engine, graphics.bitmap module
10  */
11 
12 
13 public class Bitmap16Bit{
14 //	private BitArray collisionModel;
15     private ushort[] pixels;
16     private int iX;
17     private int iY;
18     //Creates an empty bitmap.
19     this(int x, int y){
20         iX=x;
21         iY=y;
22         pixels.length=x*y;
23 
24     }
25     //Creates a bitmap from an array.
26     this(ushort[] p, int x, int y){
27 		if (p.length < x * y)
28 			throw new BitmapFormatException("Incorrect Bitmap size exception!");
29         iX=x;
30         iY=y;
31         pixels=p;
32         
33     }
34     //Returns the pixel at the given position.
35     public ushort readPixel(int x, int y){
36 
37         return pixels[x+(iX*y)];
38 
39     }
40 	public ushort[] readRow(int row){
41 
42 		return pixels[(iX*row) .. ((iX*row)+iX)];
43 	}
44 	public ushort[] readRowReverse(int row){
45 		row = iY-row-1;
46 		return pixels[(iX*row) .. ((iX*row)+iX)];
47 	}
48 	public ushort[] readChunk(int row, int offsetL, int offsetR){
49 		return pixels[((iX*row)+offsetL) .. ((iX*row)+iX-offsetR)];
50 	}
51 	public ushort* getPtr(){
52 		return pixels.ptr;
53 	}
54     //Writes the pixel at the given position.
55     public void writePixel(int x, int y, ushort color){
56         pixels[x+(iX*y)]=color;
57 	}
58     //Resizes the bitmap.
59     //Might result in corrupting the data. Intended for use with effects.
60     public void resize(int x, int y){
61         pixels.length=x*y;
62     }
63    
64 	public void clear(){
65 		for(int i ; i < pixels.length ; i++)
66 			pixels[0] = 0;
67 	}
68 	//Getters for each sizes.
69     public int getX(){
70         return iX;
71     }
72     public int getY(){
73         return iY;
74     }
75     //Flips the bitmap.
76     public void swapX(){
77         /*ushort foo;
78         for(int i; i<iY; i++){
79             for(int j; j<iX/2; j++){
80                 foo=pixels[j+(iX*i)];
81                 pixels[j+(iX*i)]=pixels[(iX*i)+iX-j];
82                 pixels[(iX*i)+iX-j]=foo;
83             }
84         }*/
85     }
86     public void swapY(){
87 		ushort[] bar;
88 
89 		for(int y = iY -1 ; y >= 0 ; y--){
90 			bar ~= readRow(y);
91 		}
92 		pixels = bar;
93     }
94 	/*public bool isTransparent(int x, int y){
95 		return collisionModel[x+(iX*y)];
96 	}
97 	public BitArray getRowForDetection(int row, int from, int length, ubyte extraBits){
98 		BitArray ba = BitArray();
99 		if((extraBits == 1 || extraBits == 3) && collisionModel[(iX*row)+from-1]){
100 			ba ~= true;
101 		}else{
102 			ba ~= false;
103 		}
104 		ba ~= collisionModel[(iX*row)+from..(iX*row)+from+length];
105 		if((extraBits == 2 || extraBits == 3) && collisionModel[(iX*row)+from+length+1]){
106 			ba ~= true;
107 		}else{
108 			ba ~= false;
109 		}
110 		return ba;
111 	}*/
112 	public bool[] generateStandardCollisionModel(){
113 		bool[] ba;
114 		foreach(ushort c; pixels){
115 			if(c == 0){
116 				ba ~= false;
117 			}else{
118 				ba ~= true;
119 			}
120 		}
121 		return ba;
122 	}
123 	/*public void useExternalCollisionModel(BitArray ba){
124 		if(ba.length() != iX * iY){
125 			throw new BitmapFormatException("Collision model has a different size.");
126 		}
127 		collisionModel = ba;
128 	}*/
129 }
130 public class Bitmap32Bit{
131 	//private BitArray collisionModel;
132 	private ubyte[] pixels;
133 	private int iX, iY;
134 
135 	public this(int x, int y){
136 		iX = x;
137 		iY = y;
138 		pixels.length = x * y * 4;
139 	}
140 
141 	public this(ubyte[] p, int x, int y){
142 		if (p.length < x * y * 4)
143 			throw new BitmapFormatException("Incorrect Bitmap size exception!");
144 		iX = x;
145 		iY = y;
146 		this.pixels = p;
147 	}
148 
149 	public ubyte[4] readPixel(int x, int y){
150 		
151 		return *cast(ubyte[4]*)(pixels.ptr + x+(iX*y)*4);
152 		
153 	}
154 	public ubyte[] readRow(int row){
155 		
156 		return pixels[(iX*row*4) .. ((iX*row)+iX)*4];
157 	}
158 	public ubyte[] readRowReverse(int row){
159 		row = iY-row-1;
160 		return pixels[(iX*row*4) .. ((iX*row)+iX)*4];
161 	}
162 	public ubyte[] readChunk(int row, int offsetL, int offsetR){
163 		return pixels[((iX*row)+offsetL)*4 .. ((iX*row)+iX-offsetR)*4];
164 	}
165 	//Writes the pixel at the given position.
166 	public void writePixel(int x, int y, ubyte r, ubyte g, ubyte b, ubyte a){
167 		//writeln(x * (4 * y * iX));
168 		pixels[4 * x + (4 * y * iX)] = a;
169 		pixels[4 * x + (4 * y * iX) + 1] = r;
170 		pixels[4 * x + (4 * y * iX) + 2] = g;
171 		pixels[4 * x + (4 * y * iX) + 3] = b;
172 
173 	}
174 
175 	public ubyte* getPtr(){
176 		return pixels.ptr;
177 	}
178 
179 	public ubyte[] getRawdata(){
180 		return pixels;
181 	}
182 
183 	public bool[] generateStandardCollisionModel(){
184 		bool[] ba;
185 		for(int i; i < pixels.length; i+=4){
186 			if(pixels[i] == 0){
187 				ba ~= false;
188 			}else{
189 				ba ~= true;
190 			}
191 		}
192 		return ba;
193 	}
194 	//Getters for each sizes.
195 	public int getX(){
196 		return iX;
197 	}
198 	public int getY(){
199 		return iY;
200 	}
201 
202 }
203 /*public interface Collidable{
204 	public bool isTransparent(int x, int y);
205 	public BitArray getRowForDetection(int row, int from, int length, ubyte extraBits);
206 }*/