1 module pixelperfectengine.map.mapdata;
2 /*
3  * Copyright (C) 2015-2017, by Laszlo Szeremi under the Boost license.
4  *
5  * Pixel Perfect Engine, map module
6  */
7 import std.stdio;
8 import std.file;
9 import std.conv;
10 import std.base64;
11 import pixelperfectengine.graphics.bitmap;
12 import pixelperfectengine.graphics.layers;
13 import pixelperfectengine.system.exc;
14 import pixelperfectengine.system.etc;
15 import core.stdc.stdlib;
16 import core.stdc.stdio;
17 import std.string;
18 
19 version(Windows){
20 	import core.sys.windows.windows;
21 	import std.windows.syserror;
22 }else{
23 	import core.stdc.errno;
24 }
25 
26 public import pixelperfectengine.system.exc;
27 
28 /**
29  * Contains the very basic data for the map binary file (*.mbf).
30  */
31 public struct MapDataHeader{
32 	public uint flags;		///Stores additional data about the binary map file as a boolean array. Bit 24-31 are user definable.
33 	public int sizeX;		///width of the map
34 	public int sizeY;		///Height of the map
35 	public enum RegisteredFlags {
36 		UD_PriorityField	=	1<<0,	///Priority field contains user-defined data
37 		UD_PalShiftField	=	1<<1,	///Palette-shift field contains user defined data
38 		Bit10AxisSwitch		=	1<<2,	///Bit 10 (bit 0 of priority field) switches X and Y axes
39 	}
40 	this(int sizeX, int sizeY){
41 		//this.fileLength = cast(uint)(sizeX * sizeY + MapDataHeader.sizeof);
42 		this.sizeX = sizeX;
43 		this.sizeY = sizeY;
44 	}
45 }
46 
47 /**
48  * Saves a map to an external file.
49  * Will be deprecated soon.
50  */
51 public void saveMapFile(MapDataHeader* header, ref MappingElement[] map, string name){
52 	FILE* outputStream = fopen(toStringz(name), "wb");
53 	if(outputStream is null){
54 		import std.conv;
55 		version(Windows){
56 			DWORD errorCode = GetLastError();
57 		}else version(Posix){
58 			int errorCode = errno;
59 		}
60 		throw new FileAccessException("File access error! Error number: " ~ to!string(errorCode));
61 	}
62 
63 	fwrite(cast(void*)header, MapDataHeader.sizeof, 1, outputStream);
64 	fwrite(cast(void*)map.ptr, MappingElement.sizeof, map.length, outputStream);
65 
66 	fclose(outputStream);
67 }
68 /**
69  * Saves a map to an external file.
70  * See documentation about the format.
71  */ 
72 public void saveMapFile(F = File)(MapDataHeader header, MappingElement[] map, F file) @trusted {
73 	ubyte[] writeBuf = toStream(header);
74 	file.rawWrite(writeBuf);
75 	file.rawWrite(map);
76 }
77 /**
78  * Loads a map from an external file.
79  */
80 public MappingElement[] loadMapFile(F = File)(F file, ref MapDataHeader header){
81 	ubyte[] readbuffer;
82 	MappingElement[] result;
83 	readbuffer.length = MapDataHeader.sizeof;
84 	readbuffer = file.rawRead(readbuffer);
85 	header = reinterpretGet!MapDataHeader(readbuffer);
86 	result.length = header.sizeX * header.sizeY;
87 	result = file.rawRead(result);
88 	return result;
89 }
90 
91 /**
92  * Loads a map from a BASE64 string.
93  */
94 public MappingElement[] loadMapFromBase64(in char[] input, int length){
95 	MappingElement[] result;
96 	result.length = length;
97 	Base64.decode(input, cast(ubyte[])cast(void[])result);
98 	return result;
99 }
100 
101 /**
102  * Saves a map to a BASE64 string.
103  */
104 public char[] saveMapToBase64(in MappingElement[] input){
105 	char[] result;
106 	Base64.encode(cast(ubyte[])cast(void[])input, result);
107 	return result;
108 }