1 /** 2 * Copyright: © 2012-2014 Anton Gushcha 3 * License: Subject to the terms of the MIT license, as written in the included LICENSE file. 4 * Authors: NCrashed <ncrashed@gmail.com>, 5 * LeMarwin <lemarwin42@gmail.com>, 6 * Nazgull09 <nazgull90@gmail.com> 7 */ 8 module ant.app; 9 10 import std.stdio; 11 import std.process; 12 import std.exception; 13 import std.conv; 14 import std.string; 15 import std.concurrency; 16 import core.time; 17 import core.thread; 18 19 import derelict.sdl2.sdl; 20 import derelict.sdl2.ttf; 21 22 import devol.singleton; 23 import devol.population; 24 25 import ant.progtype; 26 import ant.util; 27 28 class App: Singleton!App 29 { 30 public: 31 this() 32 { 33 version(linux) 34 DerelictSDL2.load(); 35 version(Windows) 36 DerelictSDL2.load(); 37 38 writeln("Loaded derelict"); 39 40 enforce(SDL_Init(SDL_INIT_EVERYTHING) == 0, text("Could not initialize SDL: ", SDL_GetError())); 41 writeln("SDL initilized!"); 42 43 /*if(TTF_Init() < 0) 44 { 45 writefln("Could not initialize SDL_TTF: %s.\n", SDL_GetError()); 46 return; 47 }*/ 48 49 window = SDL_CreateWindow("Ant evolution!", 100, 100, 1024, 1024, SDL_WINDOW_SHOWN); 50 enforce(window !is null, "Failed to create window! ", SDL_GetError().fromStringz); 51 writeln("Window is created!"); 52 53 renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); 54 enforce(renderer !is null, "Failed to create renderer! ", SDL_GetError().fromStringz); 55 56 auto info = new SDL_RendererInfo(); 57 SDL_GetRendererInfo(renderer, info); 58 writeln("Renderer is initialized! Information: ", info.name.fromStringz); 59 60 empty = loadSurface("../media/textures/Empty.bmp"); 61 food = loadSurface("../media/textures/Cherry.bmp"); 62 wall = loadSurface("../media/textures/Wall.bmp"); 63 64 ants[Ant.Faces.NORTH] = loadSurface("../media/textures/AntN.bmp"); 65 ants[Ant.Faces.SOUTH] = loadSurface("../media/textures/AntS.bmp"); 66 ants[Ant.Faces.EAST] = loadSurface("../media/textures/AntE.bmp"); 67 ants[Ant.Faces.WEST] = loadSurface("../media/textures/AntW.bmp"); 68 69 SDL_RenderClear(renderer); 70 eventThreadTid = spawn(&eventThread, thisTid); 71 } 72 73 bool shouldExit() 74 { 75 static bool done = false; 76 77 auto res = receiveTimeout(10.dur!"msecs", (bool v) {}); 78 if(res) done = true; 79 80 return done; 81 } 82 83 static void eventThread(Tid tid) 84 { 85 Thread.getThis.isDaemon(true); 86 SDL_Event event; 87 88 89 bool done = false; 90 while ( !done && SDL_WaitEvent(&event) ) 91 { 92 const ubyte* state = SDL_GetKeyboardState(null); 93 switch (event.type) { 94 case SDL_KEYDOWN: 95 if(state[SDL_SCANCODE_ESCAPE]) 96 { 97 tid.send(true); 98 } 99 break; 100 default: 101 102 break; 103 } 104 } 105 } 106 107 SDL_Texture* loadSurface(string name) 108 { 109 SDL_Surface* bmp = SDL_LoadBMP(name.toStringz); 110 if(bmp is null) 111 { 112 enforce(false, text("Failed to load surface ", name, "! ", SDL_GetError().fromStringz)); 113 } 114 115 SDL_Texture* tex = SDL_CreateTextureFromSurface(renderer, bmp); 116 SDL_FreeSurface(bmp); 117 if (tex is null) 118 { 119 enforce(false, text("Failed to create texture from surface ", name, "! ", SDL_GetError().fromStringz)); 120 } 121 122 return tex; 123 } 124 125 void clear() 126 { 127 if(drawFrame) SDL_RenderClear(renderer); 128 } 129 130 void draw(SDL_Texture* tex, uint x, uint y, uint w, uint h) 131 { 132 if(drawFrame) 133 SDL_RenderCopy(renderer, tex, null, new SDL_Rect(x, y, w, h)); 134 135 } 136 137 void present() 138 { 139 drawFrame = !drawFrame; 140 SDL_RenderPresent(renderer); 141 } 142 143 ~this() 144 { 145 SDL_DestroyTexture(empty); 146 SDL_DestroyTexture(food); 147 SDL_DestroyTexture(wall); 148 foreach(tex; ants) 149 { 150 SDL_DestroyTexture(tex); 151 } 152 153 SDL_DestroyRenderer(renderer); 154 SDL_DestroyWindow(window); 155 SDL_Quit(); 156 } 157 158 SDL_Texture* empty; 159 SDL_Texture* food; 160 SDL_Texture* wall; 161 SDL_Texture*[Ant.Faces] ants; 162 SDL_Texture* screen; 163 164 private 165 { 166 SDL_Window* window; 167 SDL_Renderer* renderer; 168 SDL_Event event; 169 bool drawFrame = true; 170 Tid eventThreadTid; 171 } 172 } 173 174