1 /// main YSGE module containing everything you need to make a game 2 module ysge.project; 3 4 import std.file; 5 import std.path; 6 import std.string; 7 8 public import bindbc.sdl; 9 public import ysge.util; 10 public import ysge.scene; 11 public import ysge.types; 12 public import ysge.gameObject; 13 public import ysge.objects.tileMap; 14 public import ysge.objects.simpleBox; 15 public import ysge.uiBase; 16 public import ysge.ui.text; 17 public import ysge.ui.button; 18 public import ysge.ui.terminal; 19 20 /// used when something goes wrong in the project 21 class ProjectException : Exception { 22 this(string msg, string file = __FILE__, size_t line = __LINE__) { 23 super(msg, file, line); 24 } 25 } 26 27 /// main project class used for the game as a whole 28 class Project { 29 bool running; /// while true, update functions are called 30 SDL_Window* window; 31 SDL_Renderer* renderer; 32 TTF_Font* font; 33 Scene[] scenes; 34 Scene currentScene; 35 bool usingLogicalRes; /// DON'T MODIFY!!!! 36 Vec2!int logicalRes; /// DON'T MODIFY!!!! 37 Vec2!int mousePos; 38 ulong frames; /// how many frames have passed since the game was started 39 40 /// called once at the start 41 abstract void Init(); 42 43 /// creates the window 44 void InitWindow(string name, int w, int h) { 45 SDLSupport support; 46 47 version (Windows) { 48 support = loadSDL(cast(char*) (dirName(thisExePath()) ~ "/sdl2.dll")); 49 } 50 else { 51 support = loadSDL(); 52 } 53 54 if (support != sdlSupport) { 55 throw new ProjectException("Failed to load SDL"); 56 } 57 58 window = SDL_CreateWindow( 59 toStringz(name), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 60 w, h, SDL_WINDOW_RESIZABLE 61 ); 62 63 if (window is null) { 64 throw new ProjectException("Failed to create window"); 65 } 66 67 renderer = SDL_CreateRenderer( 68 window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC 69 ); 70 71 if (renderer is null) { 72 throw new ProjectException("Failed to create renderer"); 73 } 74 } 75 76 /// initialises the text library 77 void InitText() { 78 SDLTTFSupport support; 79 80 version (Windows) { 81 support = loadSDLTTF(cast(char*) (dirName(thisExePath()) ~ "/sdl2_ttf.dll")); 82 } 83 else { 84 support = loadSDLTTF(); 85 } 86 87 if (support < SDLTTFSupport.v2_0_12) { 88 throw new ProjectException("Failed to load SDL_TTF library"); 89 } 90 91 if (TTF_Init() < 0) { 92 throw new ProjectException("Failed to initialise SDL_TTF"); 93 } 94 } 95 96 void LoadFontFile(string path, int pointSize) { 97 font = TTF_OpenFont(toStringz(path), pointSize); 98 99 if (font is null) { 100 throw new ProjectException("Failed to load font"); 101 } 102 } 103 104 void LoadFontData(ubyte[] data) { 105 auto rw = SDL_RWFromMem(data.ptr, cast(int) data.length); 106 font = TTF_OpenFontRW(rw, 1, 16); 107 108 if (font is null) { 109 throw new ProjectException("Failed to load font"); 110 } 111 } 112 113 /// gets the resolution of the window 114 Vec2!int GetResolution() { 115 if (usingLogicalRes) { 116 return logicalRes; 117 } 118 else { 119 Vec2!int ret; 120 121 SDL_GetWindowSize(window, &ret.x, &ret.y); 122 123 return ret; 124 } 125 } 126 127 /// sets the logical resolution of the window 128 void SetResolution(uint w, uint h) { 129 SDL_RenderSetLogicalSize(renderer, w, h); 130 usingLogicalRes = true; 131 logicalRes = Vec2!int(w, h); 132 } 133 134 /// gets the directory the game executable is in 135 string GetGameDirectory() { 136 return dirName(thisExePath()); 137 } 138 139 /// checks if a key is pressed 140 bool KeyPressed(SDL_Scancode key) { 141 auto keys = SDL_GetKeyboardState(null); 142 143 return keys[key]? true : false; 144 } 145 146 /// adds a scene to the project scene array 147 void AddScene(Scene scene) { 148 scenes ~= scene; 149 } 150 151 /// sets the current scene to a scene from the project scene array 152 void SetScene(Scene scene) { 153 currentScene = scene; 154 currentScene.Init(this); 155 } 156 157 /// sets the current scene to a scene from the project scene array 158 void SetScene(size_t index) { 159 currentScene = scenes[index]; 160 currentScene.Init(this); 161 } 162 163 /// runs the game 164 void Run() { 165 running = true; 166 Init(); 167 168 if (currentScene is null) { 169 throw new ProjectException("Scene not set"); 170 } 171 172 if (font is null) { 173 throw new ProjectException("Font not loaded"); 174 } 175 176 while (running) { 177 ++ frames; 178 179 currentScene.UpdateObjects(this); 180 currentScene.Update(this); 181 currentScene.UpdateCamera(this); 182 currentScene.Render(this); 183 184 SDL_Event e; 185 while (SDL_PollEvent(&e)) { 186 switch (e.type) { 187 case SDL_QUIT: { 188 running = false; 189 return; 190 } 191 case SDL_MOUSEMOTION: { 192 mousePos = Vec2!int(e.motion.x, e.motion.y); 193 break; 194 } 195 default: { 196 if (currentScene.HandleUIEvent(this, e)) { 197 continue; 198 } 199 200 currentScene.HandleEvent(this, e); 201 break; 202 } 203 } 204 } 205 } 206 } 207 }