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