]> git.localhorst.tv Git - blank.git/blob - src/app/init.cpp
fea5653cf1cf6499bb378b22286169cf2c15fff8
[blank.git] / src / app / init.cpp
1 #include "init.hpp"
2
3 #include <algorithm>
4 #include <alut.h>
5 #include <SDL.h>
6 #include <SDL_image.h>
7 #include <SDL_net.h>
8 #include <SDL_ttf.h>
9 #include <GL/glew.h>
10
11
12 namespace {
13
14 std::string sdl_error_append(std::string msg) {
15         const char *error = SDL_GetError();
16         if (*error != '\0') {
17                 msg += ": ";
18                 msg += error;
19                 SDL_ClearError();
20         }
21         return msg;
22 }
23
24 std::string net_error_append(std::string msg) {
25         const char *error = SDLNet_GetError();
26         if (*error != '\0') {
27                 msg += ": ";
28                 msg += error;
29         }
30         return msg;
31 }
32
33 std::string alut_error_append(ALenum num, std::string msg) {
34         const char *error = alutGetErrorString(num);
35         if (*error != '\0') {
36                 msg += ": ";
37                 msg += error;
38         }
39         return msg;
40 }
41
42 }
43
44 namespace blank {
45
46 AlutError::AlutError(ALenum num)
47 : std::runtime_error(alutGetErrorString(num)) {
48
49 }
50
51 AlutError::AlutError(ALenum num, const std::string &msg)
52 : std::runtime_error(alut_error_append(num, msg)) {
53
54 }
55
56
57 NetError::NetError()
58 : std::runtime_error(SDLNet_GetError()) {
59
60 }
61
62 NetError::NetError(const std::string &msg)
63 : std::runtime_error(net_error_append(msg)) {
64
65 }
66
67
68 SDLError::SDLError()
69 : std::runtime_error(SDL_GetError()) {
70
71 }
72
73 SDLError::SDLError(const std::string &msg)
74 : std::runtime_error(sdl_error_append(msg)) {
75
76 }
77
78
79 InitSDL::InitSDL() {
80         if (SDL_Init(SDL_INIT_EVENTS) != 0) {
81                 throw SDLError("SDL_Init(SDL_INIT_EVENTS)");
82         }
83 }
84
85 InitSDL::~InitSDL() {
86         SDL_Quit();
87 }
88
89
90 InitVideo::InitVideo() {
91         if (SDL_InitSubSystem(SDL_INIT_VIDEO) != 0) {
92                 throw SDLError("SDL_InitSubSystem(SDL_INIT_VIDEO)");
93         }
94         // SDL seems to start out in text input state
95         SDL_StopTextInput();
96 }
97
98 InitVideo::~InitVideo() {
99         SDL_QuitSubSystem(SDL_INIT_VIDEO);
100 }
101
102
103 InitIMG::InitIMG() {
104         if (IMG_Init(IMG_INIT_PNG) == 0) {
105                 throw SDLError("IMG_Init(IMG_INIT_PNG)");
106         }
107 }
108
109 InitIMG::~InitIMG() {
110         IMG_Quit();
111 }
112
113
114 InitNet::InitNet() {
115         if (SDLNet_Init() != 0) {
116                 throw SDLError("SDLNet_Init()");
117         }
118 }
119
120 InitNet::~InitNet() {
121         SDLNet_Quit();
122 }
123
124
125 InitTTF::InitTTF() {
126         if (TTF_Init() != 0) {
127                 throw SDLError("TTF_Init()");
128         }
129 }
130
131 InitTTF::~InitTTF() {
132         TTF_Quit();
133 }
134
135
136 InitAL::InitAL() {
137         if (!alutInit(nullptr, nullptr)) {
138                 throw AlutError(alutGetError(), "alutInit");
139         }
140 }
141
142 InitAL::~InitAL() {
143         if (!alutExit()) {
144                 throw AlutError(alutGetError(), "alutExit");
145         }
146 }
147
148
149 InitGL::InitGL(bool double_buffer, int sample_size) {
150         if (SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3) != 0) {
151                 throw SDLError("SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3)");
152         }
153         if (SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3) != 0) {
154                 throw SDLError("SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3)");
155         }
156         if (SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE) != 0) {
157                 throw SDLError("SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE)");
158         }
159
160         if (!double_buffer) {
161                 if (SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 0) != 0) {
162                         throw SDLError("SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 0)");
163                 }
164         }
165
166         if (sample_size > 1) {
167                 if (SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1) != 0) {
168                         throw SDLError("SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS)");
169                 }
170                 if (SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, sample_size) != 0) {
171                         throw SDLError("SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES)");
172                 }
173         }
174 }
175
176
177 Window::Window()
178 : handle(SDL_CreateWindow(
179         "blank",
180         SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
181         960, 600,
182         SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE
183 )) {
184         if (!handle) {
185                 throw SDLError("SDL_CreateWindow");
186         }
187 }
188
189 Window::~Window() {
190         SDL_DestroyWindow(handle);
191 }
192
193 void Window::GrabInput() {
194         SDL_SetWindowGrab(handle, SDL_TRUE);
195 }
196
197 void Window::ReleaseInput() {
198         SDL_SetWindowGrab(handle, SDL_FALSE);
199 }
200
201 void Window::GrabMouse() {
202         if (SDL_SetRelativeMouseMode(SDL_TRUE) != 0) {
203                 throw SDLError("SDL_SetRelativeMouseMode");
204         }
205 }
206
207 void Window::ReleaseMouse() {
208         if (SDL_SetRelativeMouseMode(SDL_FALSE) != 0) {
209                 throw SDLError("SDL_SetRelativeMouseMode");
210         }
211 }
212
213 void Window::Flip() {
214         SDL_GL_SwapWindow(handle);
215 }
216
217
218 GLContext::GLContext(SDL_Window *win)
219 : ctx(SDL_GL_CreateContext(win)) {
220         if (!ctx) {
221                 throw SDLError("SDL_GL_CreateContext");
222         }
223 }
224
225 GLContext::~GLContext() {
226         SDL_GL_DeleteContext(ctx);
227 }
228
229
230 InitGLEW::InitGLEW() {
231         glewExperimental = GL_TRUE;
232         GLenum glew_err = glewInit();
233         if (glew_err != GLEW_OK) {
234                 std::string msg("glewInit: ");
235                 const GLubyte *errBegin = glewGetErrorString(glew_err);
236                 const GLubyte *errEnd = errBegin;
237                 while (*errEnd != '\0') {
238                         ++errEnd;
239                 }
240                 msg.append(errBegin, errEnd);
241                 throw std::runtime_error(msg);
242         }
243 }
244
245
246 InitHeadless::InitHeadless()
247 : init_sdl()
248 , init_net() {
249
250 }
251
252 Init::Init(bool double_buffer, int sample_size)
253 : init_video()
254 , init_img()
255 , init_ttf()
256 , init_gl(double_buffer, sample_size)
257 , window()
258 , ctx(window.Handle())
259 , init_glew() {
260
261 }
262
263 }