]> git.localhorst.tv Git - blank.git/blob - src/app/init.cpp
handle events in headless environment
[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 }
95
96 InitVideo::~InitVideo() {
97         SDL_QuitSubSystem(SDL_INIT_VIDEO);
98 }
99
100
101 InitIMG::InitIMG() {
102         if (IMG_Init(IMG_INIT_PNG) == 0) {
103                 throw SDLError("IMG_Init(IMG_INIT_PNG)");
104         }
105 }
106
107 InitIMG::~InitIMG() {
108         IMG_Quit();
109 }
110
111
112 InitNet::InitNet() {
113         if (SDLNet_Init() != 0) {
114                 throw SDLError("SDLNet_Init()");
115         }
116 }
117
118 InitNet::~InitNet() {
119         SDLNet_Quit();
120 }
121
122
123 InitTTF::InitTTF() {
124         if (TTF_Init() != 0) {
125                 throw SDLError("TTF_Init()");
126         }
127 }
128
129 InitTTF::~InitTTF() {
130         TTF_Quit();
131 }
132
133
134 InitAL::InitAL() {
135         if (!alutInit(nullptr, nullptr)) {
136                 throw AlutError(alutGetError(), "alutInit");
137         }
138 }
139
140 InitAL::~InitAL() {
141         if (!alutExit()) {
142                 throw AlutError(alutGetError(), "alutExit");
143         }
144 }
145
146
147 InitGL::InitGL(bool double_buffer, int sample_size) {
148         if (SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3) != 0) {
149                 throw SDLError("SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3)");
150         }
151         if (SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3) != 0) {
152                 throw SDLError("SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3)");
153         }
154         if (SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE) != 0) {
155                 throw SDLError("SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE)");
156         }
157
158         if (double_buffer) {
159                 if (SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1) != 0) {
160                         throw SDLError("SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1)");
161                 }
162         }
163
164         if (sample_size > 1) {
165                 if (SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1) != 0) {
166                         throw SDLError("SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS)");
167                 }
168                 if (SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, sample_size) != 0) {
169                         throw SDLError("SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES)");
170                 }
171         }
172 }
173
174
175 Window::Window()
176 : handle(SDL_CreateWindow(
177         "blank",
178         SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
179         960, 600,
180         SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE
181 )) {
182         if (!handle) {
183                 throw SDLError("SDL_CreateWindow");
184         }
185 }
186
187 Window::~Window() {
188         SDL_DestroyWindow(handle);
189 }
190
191 void Window::GrabInput() {
192         SDL_SetWindowGrab(handle, SDL_TRUE);
193 }
194
195 void Window::ReleaseInput() {
196         SDL_SetWindowGrab(handle, SDL_FALSE);
197 }
198
199 void Window::GrabMouse() {
200         if (SDL_SetRelativeMouseMode(SDL_TRUE) != 0) {
201                 throw SDLError("SDL_SetRelativeMouseMode");
202         }
203 }
204
205 void Window::ReleaseMouse() {
206         if (SDL_SetRelativeMouseMode(SDL_FALSE) != 0) {
207                 throw SDLError("SDL_SetRelativeMouseMode");
208         }
209 }
210
211 void Window::Flip() {
212         SDL_GL_SwapWindow(handle);
213 }
214
215
216 GLContext::GLContext(SDL_Window *win)
217 : ctx(SDL_GL_CreateContext(win)) {
218         if (!ctx) {
219                 throw SDLError("SDL_GL_CreateContext");
220         }
221 }
222
223 GLContext::~GLContext() {
224         SDL_GL_DeleteContext(ctx);
225 }
226
227
228 InitGLEW::InitGLEW() {
229         glewExperimental = GL_TRUE;
230         GLenum glew_err = glewInit();
231         if (glew_err != GLEW_OK) {
232                 std::string msg("glewInit: ");
233                 const GLubyte *errBegin = glewGetErrorString(glew_err);
234                 const GLubyte *errEnd = errBegin;
235                 while (*errEnd != '\0') {
236                         ++errEnd;
237                 }
238                 msg.append(errBegin, errEnd);
239                 throw std::runtime_error(msg);
240         }
241 }
242
243
244 InitHeadless::InitHeadless()
245 : init_sdl()
246 , init_net() {
247
248 }
249
250 Init::Init(bool double_buffer, int sample_size)
251 : init_video()
252 , init_img()
253 , init_ttf()
254 , init_gl(double_buffer, sample_size)
255 , window()
256 , ctx(window.Handle())
257 , init_glew() {
258
259 }
260
261 }