1 module d2d.rendering.spritesheet;
2 
3 import std.algorithm;
4 import std.conv;
5 import std.file : read;
6 import std.path;
7 
8 import d2d.rendering.texture;
9 
10 import crunch;
11 
12 struct Spritesheet
13 {
14 	Texture[] textures;
15 	Crunch sprites;
16 
17 	version (BindSDL_Image) void load(string path)
18 	{
19 		load(cast(ubyte[]) read(path), dirName(path));
20 	}
21 
22 	version (BindSDL_Image) void load(ubyte[] data, string cwd)
23 	{
24 		sprites = crunchFromCompact(data, false);
25 		textures.length = sprites.textures.length;
26 
27 		foreach (i, tex; sprites.textures)
28 			textures[i] = new Texture(buildPath(cwd, tex.name ~ ".png"), TextureFilterMode.Nearest,
29 					TextureFilterMode.Nearest, TextureClampMode.ClampToEdge, TextureClampMode.ClampToEdge);
30 	}
31 
32 	auto buildLookup(Names...)(int texture)
33 	{
34 		static immutable string[] names = buildNameList!Names;
35 		union Data
36 		{
37 			mixin(buildLookupStructCode(names));
38 			Crunch.Image[names.length] images;
39 		}
40 
41 		Data ret;
42 		int index = 0;
43 		int texIndex = 0;
44 		while (index < names.length && texIndex < sprites.textures[texture].images.length)
45 		{
46 			if (sprites.textures[texture].images[texIndex].name == names[index])
47 			{
48 				ret.images[index] = sprites.textures[texture].images[texIndex];
49 				index++;
50 			}
51 			texIndex++;
52 		}
53 		if (index != names.length)
54 			throw new Exception(
55 					"Not all images loaded! Got " ~ index.to!string ~ " out of " ~ names.length.to!string);
56 		return ret.lookup;
57 	}
58 }
59 
60 private string[] buildNameList(Names...)()
61 {
62 	string[] ret = [Names];
63 	ret.sort!"a<b";
64 	return ret;
65 }
66 
67 private string buildLookupStructCode(in string[] names)
68 {
69 	string ret = "struct Lookup {";
70 	foreach (string name; names)
71 		ret ~= "Crunch.Image " ~ name ~ ";";
72 	ret ~= "} Lookup lookup;";
73 	return ret;
74 }