1 /*
2 Copyright (C) 2015, by Laszlo Szeremi under the Boost license.
3 
4 VDP Engine
5 */
6 
7 
8 module app;
9 
10 import std.stdio;
11 import std..string;
12 import std.conv;
13 import std.random;
14 
15 import derelict.sdl2.sdl;
16 import derelict.freeimage.freeimage;
17 
18 //import system.config;
19 
20 import PixelPerfectEngine.graphics.outputScreen;
21 import PixelPerfectEngine.graphics.raster;
22 import PixelPerfectEngine.graphics.layers;
23 
24 import PixelPerfectEngine.graphics.bitmap;
25 //import PixelPerfectEngine.collision;
26 import PixelPerfectEngine.system.inputHandler;
27 import PixelPerfectEngine.system.file;
28 import PixelPerfectEngine.system.etc;
29 //import system.tgaconv;
30 import PixelPerfectEngine.system.config;
31 import PixelPerfectEngine.system.binarySearchTree;
32 
33 import editor;
34 import PixelPerfectEngine.extbmp.extbmp;
35 
36 version(Windows){
37 	static const string sdlSource = "system\\SDL2.dll";
38 	static const string fiSource = "system\\FreeImage.dll";
39 }else{
40 	static const string sdlSource = "/system/SDL2.so";
41 	static const string fiSource = "/system/FreeImage.so";
42 }
43 
44 static this(){
45 	
46 	DerelictSDL2.load(sdlSource);
47 	DerelictFI.load(fiSource);
48 }
49 
50 static ~this(){
51 	
52 	//DerelictSDL2.unload();
53 	//DerelictFI.unload();
54 }
55 
56 int main(string[] args){
57 	//stdout.flush;
58     /*DerelictSDL2.load(sdlSource);
59 	DerelictFI.load(fiSource);*/
60 	
61 	//printf("aaaaaaaaaaaaaaaaaa");
62 	SDL_SetHint(SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING, "1");
63 	
64 	Editor e = new Editor(args);
65 	e.whereTheMagicHappens;
66     //e.destroy();
67 	//SDL_Quit();
68 	//testAdvBitArrays(128);
69 	//TileLayerTest prg = new TileLayerTest();
70 	//prg.whereTheMagicHappens;
71 	//testBinarySearchTrees(11, 1);
72 	return 0;
73 }
74 
75 void testBinarySearchTrees(int nOfElements, int nOfTimes){
76 	for(int i; i < nOfTimes; i++){
77 		writeln("start test no.",i);
78 		BinarySearchTree!(int,int) sequ, rand;
79 		//sequential element test
80 		for(int j; j < nOfElements; j++){
81 			sequ[j] = j;
82 		}
83 		writeln(sequ);
84 		//randomized element test
85 		for(int j; j < nOfElements; j++){
86 			int k = uniform(short.min,short.max);
87 			rand[k] = k;
88 		}
89 		writeln(rand);
90 		//rand.optimize();
91 		//writeln(rand);
92 	}
93 	readln();
94 }
95 
96 class TileLayerTest : SystemEventListener, InputListener{
97 	bool isRunning, up, down, left, right, scrup, scrdown, scrleft, scrright;
98 	OutputScreen output;
99 	Raster r;
100 	TileLayer t;
101 	TransformableTileLayer!(Bitmap16Bit,32,32) tt;
102 	ABitmap[] tiles;
103 	Bitmap16Bit dlangMan;
104 	SpriteLayer s;
105 	//Bitmap16Bit[wchar] tiles;
106 	InputHandler ih;
107 	float theta;
108 	//CollisionDetector c;
109 	this(){
110 		theta = 0;
111 		isRunning = true;
112 		ExtendibleBitmap tileSource = new ExtendibleBitmap("tiletest.xmp");
113 		ExtendibleBitmap spriteSource = new ExtendibleBitmap("collisionTest.xmp");
114 		//t = new TileLayer(32,32, LayerRenderingMode.COPY);
115 		tt = new TransformableTileLayer!(Bitmap16Bit,32,32)(LayerRenderingMode.COPY);
116 		s = new SpriteLayer(LayerRenderingMode.ALPHA_BLENDING);
117 		//c = new CollisionDetector();
118 		dlangMan = loadBitmapFromXMP!Bitmap16Bit(spriteSource,"DLangMan");
119 		//CollisionModel cm = new CollisionModel(dlangMan.width, dlangMan.height, dlangMan.generateStandardCollisionModel());
120 		dlangMan.offsetIndexes(256,false);
121 		s.addSprite(dlangMan,0,0,0,BitmapAttrib(false,false));
122 		for(int i = 1 ; i < 2 ; i++){
123 			s.addSprite(dlangMan,i,uniform(-31,320),uniform(-31,240),BitmapAttrib(false,false));
124 		}
125 		//s.collisionDetector[1] = c;
126 		//c.source = s;
127 		//c.addCollisionModel(cm,0);
128 		//c.addCollisionModel(cm,1);
129 		//c.addCollisionListener(this);
130 		tiles.length = tileSource.bitmapID.length;
131 		for(int i; i < tileSource.bitmapID.length; i++){
132 			string hex = tileSource.bitmapID[i];
133 			//writeln(hex[hex.length-4..hex.length]);
134 			ABitmap ab = loadBitmapFromXMP!Bitmap16Bit(tileSource, hex);
135 			tiles[i] = ab;
136 			tt.addTile(ab, to!wchar(parseHex(hex[hex.length-4..hex.length])));
137 		}
138 		//wchar[] mapping;
139 		MappingElement[] mapping;
140 		mapping.length = 8*8;
141 		//attrMapping.length = 256*256;
142 		for(int i; i < mapping.length; i++){
143 			//mapping[i] = to!wchar(uniform(0x0000,0x00AA));
144 			int rnd = uniform(0,1024);
145 			//attrMapping[i] = BitmapAttrib(rnd & 1 ? true : false, rnd & 2 ? true : false);
146 			mapping[i] = MappingElement(to!wchar(uniform(0x0000,0x00AA)), BitmapAttrib(rnd & 1 ? true : false, rnd & 2 ? true : false));
147 		}
148 		ih = new InputHandler();
149 		ih.sel ~= this;
150 		ih.il ~= this;
151 		ih.kb ~= KeyBinding(0, SDL_SCANCODE_UP,0, "up", Devicetype.KEYBOARD, KeyModifier.ANY);
152 		ih.kb ~= KeyBinding(0, SDL_SCANCODE_DOWN,0, "down", Devicetype.KEYBOARD, KeyModifier.ANY);
153 		ih.kb ~= KeyBinding(0, SDL_SCANCODE_LEFT,0, "left", Devicetype.KEYBOARD, KeyModifier.ANY);
154 		ih.kb ~= KeyBinding(0, SDL_SCANCODE_RIGHT,0, "right", Devicetype.KEYBOARD, KeyModifier.ANY);
155 		ih.kb ~= KeyBinding(0, ScanCode.np8,0, "scrup", Devicetype.KEYBOARD, KeyModifier.ANY);
156 		ih.kb ~= KeyBinding(0, ScanCode.np2,0, "scrdown", Devicetype.KEYBOARD, KeyModifier.ANY);
157 		ih.kb ~= KeyBinding(0, ScanCode.np4,0, "scrleft", Devicetype.KEYBOARD, KeyModifier.ANY);
158 		ih.kb ~= KeyBinding(0, ScanCode.np6,0, "scrright", Devicetype.KEYBOARD, KeyModifier.ANY);
159 		ih.kb ~= KeyBinding(0, ScanCode.F1,0, "A+", Devicetype.KEYBOARD, KeyModifier.ANY);
160 		ih.kb ~= KeyBinding(0, ScanCode.F2,0, "A-", Devicetype.KEYBOARD, KeyModifier.ANY);
161 		ih.kb ~= KeyBinding(0, ScanCode.F3,0, "B+", Devicetype.KEYBOARD, KeyModifier.ANY);
162 		ih.kb ~= KeyBinding(0, ScanCode.F4,0, "B-", Devicetype.KEYBOARD, KeyModifier.ANY);
163 		ih.kb ~= KeyBinding(0, ScanCode.F5,0, "C+", Devicetype.KEYBOARD, KeyModifier.ANY);
164 		ih.kb ~= KeyBinding(0, ScanCode.F6,0, "C-", Devicetype.KEYBOARD, KeyModifier.ANY);
165 		ih.kb ~= KeyBinding(0, ScanCode.F7,0, "D+", Devicetype.KEYBOARD, KeyModifier.ANY);
166 		ih.kb ~= KeyBinding(0, ScanCode.F8,0, "D-", Devicetype.KEYBOARD, KeyModifier.ANY);
167 		ih.kb ~= KeyBinding(0, ScanCode.F9,0, "x0+", Devicetype.KEYBOARD, KeyModifier.ANY);
168 		ih.kb ~= KeyBinding(0, ScanCode.F10,0, "x0-", Devicetype.KEYBOARD, KeyModifier.ANY);
169 		ih.kb ~= KeyBinding(0, ScanCode.PAGEUP,0, "y0+", Devicetype.KEYBOARD, KeyModifier.ANY);
170 		ih.kb ~= KeyBinding(0, ScanCode.PAGEDOWN,0, "y0-", Devicetype.KEYBOARD, KeyModifier.ANY);
171 		ih.kb ~= KeyBinding(0, ScanCode.NP_PLUS,0, "theta+", Devicetype.KEYBOARD, KeyModifier.ANY);
172 		ih.kb ~= KeyBinding(0, ScanCode.NP_MINUS,0, "theta-", Devicetype.KEYBOARD, KeyModifier.ANY);
173 
174 		tt.loadMapping(8,8,mapping);
175 		//tt.setWarpMode(true);
176 		//tt.hBlankInterrupt = &ttlHBlankInterrupt;
177 		//t.setWrapMode(true);
178 
179 		output = new OutputScreen("TileLayer test", 1280,960);
180 		r = new Raster(320,240,output);
181 		output.setMainRaster(r);
182 		loadPaletteFromXMP(tileSource, "default", r);
183 		/*for(int y ; y < 240 ; y++){
184 			for(int x ; x < 240 ; x++){
185 				writeln('[',x,',',y,"] : ", t.transformFunc([x,y]));
186 			}
187 		}*/
188 		r.addLayer(tt, 0);
189 		r.addLayer(s, 1);
190 		r.palette ~= cast(Color[])spriteSource.getPalette("default");
191 		r.palette[0].alpha = 255;
192 		r.palette[256].raw = 0;
193 		writeln(tt);
194 		//r.palette[0] = 255;
195 		//r.addRefreshListener(output, 0);
196 		
197 	}
198 	private @nogc void ttlHBlankInterrupt(ref short[4] localABCD, ref short[2] localsXsY, ref short[2] localx0y0, short y){
199 		localABCD[0]++;
200 	}
201 	public void whereTheMagicHappens(){
202 		while(isRunning){
203 			r.refresh();
204 			ih.test();
205 			if(up) s.relMoveSprite(0,0,-1);
206 			if(down) s.relMoveSprite(0,0,1);
207 			if(left) s.relMoveSprite(0,-1,0);
208 			if(right) s.relMoveSprite(0,1,0);
209 			if(scrup) tt.relScroll(0,-1);
210 			if(scrdown) tt.relScroll(0,1);
211 			if(scrleft) tt.relScroll(-1,0);
212 			if(scrright) tt.relScroll(1,0);
213 			//t.relScroll(1,0);
214 		}
215 	}
216 	override public void onQuit() {
217 		isRunning = false;
218 	}
219 	override public void controllerAdded(uint ID) {
220 		
221 	}
222 	override public void controllerRemoved(uint ID) {
223 		
224 	}
225 	override public void keyPressed(string ID,uint timestamp,uint devicenumber,uint devicetype) {
226 		//writeln(ID);
227 		switch(ID){
228 			case "up": up = true; break;
229 			case "down": down = true; break;
230 			case "left": left = true; break;
231 			case "right": right = true; break;
232 			case "scrup": scrup = true; break;
233 			case "scrdown": scrdown = true; break;
234 			case "scrleft": scrleft = true; break;
235 			case "scrright": scrright = true; break;
236 			case "A+": tt.A = cast(short)(tt.A + 16); 
237 				break;
238 			case "A-": tt.A = cast(short)(tt.A - 16); 
239 				break;
240 			case "B+": tt.B = cast(short)(tt.B + 16); break;
241 			case "B-": tt.B = cast(short)(tt.B - 16); break;
242 			case "C+": tt.C = cast(short)(tt.C + 16); break;
243 			case "C-": tt.C = cast(short)(tt.C - 16); break;
244 			case "D+": tt.D = cast(short)(tt.D + 16); break;
245 			case "D-": tt.D = cast(short)(tt.D - 16); break;
246 			case "x0+": tt.x_0 = cast(short)(tt.x_0 + 1); break;
247 			case "x0-": tt.x_0 = cast(short)(tt.x_0 - 1); break;
248 			case "y0+": tt.y_0 = cast(short)(tt.y_0 + 1); break;
249 			case "y0-": tt.y_0 = cast(short)(tt.y_0 - 1); break;
250 			/*case "theta+": theta += 1; tt.rotate(theta); break;
251 			case "theta-": theta -= 1; tt.rotate(theta); break;*/
252 			default: break;
253 		}
254 	}
255 	override public void keyReleased(string ID,uint timestamp,uint devicenumber,uint devicetype) {
256 		switch(ID){
257 			case "up": up = false; break;
258 			case "down": down = false; break;
259 			case "left": left = false; break;
260 			case "right": right = false; break;
261 			case "scrup": scrup = false; break;
262 			case "scrdown": scrdown = false; break;
263 			case "scrleft": scrleft = false; break;
264 			case "scrright": scrright = false; break;
265 			default: break;
266 		}
267 	}
268 /*public void spriteCollision(CollisionEvent ce){
269 		writeln("COLLISION!!!!11!1111!!!ONEONEONE!!!");
270 	}
271 	
272 	public void backgroundCollision(CollisionEvent ce){}*/
273 }