ruby2d 0.9.0 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,110 @@
1
+ // controllers.c
2
+
3
+ #include "../include/simple2d.h"
4
+
5
+ // Stores the last joystick instance ID seen by the system. These instance IDs
6
+ // are unique and increment with each new joystick connected.
7
+ static int last_intance_id = -1;
8
+
9
+
10
+ /*
11
+ * Add controller mapping from string
12
+ */
13
+ void S2D_AddControllerMapping(const char *map) {
14
+ int result = SDL_GameControllerAddMapping(map);
15
+
16
+ char guid[33];
17
+ strncpy(guid, map, 32);
18
+
19
+ switch (result) {
20
+ case 1:
21
+ S2D_Log(S2D_INFO, "Mapping added for GUID: %s", guid);
22
+ break;
23
+ case 0:
24
+ S2D_Log(S2D_INFO, "Mapping updated for GUID: %s", guid);
25
+ break;
26
+ case -1:
27
+ S2D_Error("SDL_GameControllerAddMapping", SDL_GetError());
28
+ break;
29
+ }
30
+ }
31
+
32
+
33
+ /*
34
+ * Add controller mappings from the specified file
35
+ */
36
+ void S2D_AddControllerMappingsFromFile(const char *path) {
37
+ if (!S2D_FileExists(path)) {
38
+ S2D_Log(S2D_WARN, "Controller mappings file not found: %s", path);
39
+ return;
40
+ }
41
+
42
+ int mappings_added = SDL_GameControllerAddMappingsFromFile(path);
43
+ if (mappings_added == -1) {
44
+ S2D_Error("SDL_GameControllerAddMappingsFromFile", SDL_GetError());
45
+ } else {
46
+ S2D_Log(S2D_INFO, "Added %i controller mapping(s)", mappings_added);
47
+ }
48
+ }
49
+
50
+
51
+ /*
52
+ * Check if joystick is a controller
53
+ */
54
+ bool S2D_IsController(SDL_JoystickID id) {
55
+ return SDL_GameControllerFromInstanceID(id) == NULL ? false : true;
56
+ }
57
+
58
+
59
+ /*
60
+ * Open controllers and joysticks
61
+ */
62
+ void S2D_OpenControllers() {
63
+
64
+ char guid_str[33];
65
+
66
+ // Enumerate joysticks
67
+ for (int device_index = 0; device_index < SDL_NumJoysticks(); ++device_index) {
68
+
69
+ // Check if joystick supports SDL's game controller interface (a mapping is available)
70
+ if (SDL_IsGameController(device_index)) {
71
+ SDL_GameController *controller = SDL_GameControllerOpen(device_index);
72
+ SDL_JoystickID intance_id = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(controller));
73
+
74
+ SDL_JoystickGetGUIDString(
75
+ SDL_JoystickGetGUID(SDL_GameControllerGetJoystick(controller)),
76
+ guid_str, 33
77
+ );
78
+
79
+ if (intance_id > last_intance_id) {
80
+ if (controller) {
81
+ S2D_Log(S2D_INFO, "Controller #%i: %s\n GUID: %s", intance_id, SDL_GameControllerName(controller), guid_str);
82
+ } else {
83
+ S2D_Log(S2D_ERROR, "Could not open controller #%i: %s", intance_id, SDL_GetError());
84
+ }
85
+ last_intance_id = intance_id;
86
+ }
87
+
88
+ // Controller interface not supported, try to open as joystick
89
+ } else {
90
+ SDL_Joystick *joy = SDL_JoystickOpen(device_index);
91
+ SDL_JoystickID intance_id = SDL_JoystickInstanceID(joy);
92
+
93
+ if (!joy) {
94
+ S2D_Log(S2D_ERROR, "Could not open controller");
95
+ } else if(intance_id > last_intance_id) {
96
+ SDL_JoystickGetGUIDString(
97
+ SDL_JoystickGetGUID(joy),
98
+ guid_str, 33
99
+ );
100
+ S2D_Log(S2D_INFO,
101
+ "Controller #%i: %s\n GUID: %s\n Axes: %d\n Buttons: %d\n Balls: %d",
102
+ intance_id, SDL_JoystickName(joy), guid_str, SDL_JoystickNumAxes(joy),
103
+ SDL_JoystickNumButtons(joy), SDL_JoystickNumBalls(joy)
104
+ );
105
+ S2D_Log(S2D_WARN, "Controller #%i does not have a mapping available", intance_id);
106
+ last_intance_id = intance_id;
107
+ }
108
+ }
109
+ }
110
+ }
@@ -0,0 +1,426 @@
1
+ // Simple 2D OpenGL Functions
2
+
3
+ #include "../include/simple2d.h"
4
+
5
+ // Set to `true` to force OpenGL 2.1 (for testing)
6
+ static bool FORCE_GL2 = false;
7
+
8
+ // Flag set if using OpenGL 2.1
9
+ static bool S2D_GL2 = false;
10
+
11
+ // The orthographic projection matrix for 2D rendering.
12
+ // Elements 0 and 5 are set in S2D_GL_SetViewport.
13
+ static GLfloat orthoMatrix[16] =
14
+ { 0, 0, 0, 0,
15
+ 0, 0, 0, 0,
16
+ 0, 0, 0, 0,
17
+ -1.0f, 1.0f, -1.0f, 1.0f };
18
+
19
+
20
+ /*
21
+ * Prints current GL error
22
+ */
23
+ void S2D_GL_PrintError(char *error) {
24
+ S2D_Log(S2D_ERROR, "%s (%d)", error, glGetError());
25
+ }
26
+
27
+
28
+ /*
29
+ * Print info about the current OpenGL context
30
+ */
31
+ void S2D_GL_PrintContextInfo(S2D_Window *window) {
32
+ S2D_Log(S2D_INFO,
33
+ "OpenGL Context\n"
34
+ " GL_VENDOR: %s\n"
35
+ " GL_RENDERER: %s\n"
36
+ " GL_VERSION: %s\n"
37
+ " GL_SHADING_LANGUAGE_VERSION: %s",
38
+ window->S2D_GL_VENDOR,
39
+ window->S2D_GL_RENDERER,
40
+ window->S2D_GL_VERSION,
41
+ window->S2D_GL_SHADING_LANGUAGE_VERSION
42
+ );
43
+ }
44
+
45
+
46
+ /*
47
+ * Store info about the current OpenGL context
48
+ */
49
+ void S2D_GL_StoreContextInfo(S2D_Window *window) {
50
+ window->S2D_GL_VENDOR = glGetString(GL_VENDOR);
51
+ window->S2D_GL_RENDERER = glGetString(GL_RENDERER);
52
+ window->S2D_GL_VERSION = glGetString(GL_VERSION);
53
+
54
+ // These are not defined in GLES
55
+ #if GLES
56
+ window->S2D_GL_MAJOR_VERSION = 0;
57
+ window->S2D_GL_MINOR_VERSION = 0;
58
+ #else
59
+ glGetIntegerv(GL_MAJOR_VERSION, &window->S2D_GL_MAJOR_VERSION);
60
+ glGetIntegerv(GL_MINOR_VERSION, &window->S2D_GL_MINOR_VERSION);
61
+ #endif
62
+
63
+ window->S2D_GL_SHADING_LANGUAGE_VERSION = glGetString(GL_SHADING_LANGUAGE_VERSION);
64
+ };
65
+
66
+
67
+ /*
68
+ * Creates a shader object, loads shader string, and compiles.
69
+ * Returns 0 if shader could not be compiled.
70
+ */
71
+ GLuint S2D_GL_LoadShader(GLenum type, const GLchar *shaderSrc, char *shaderName) {
72
+
73
+ GLuint shader;
74
+ GLint compiled;
75
+
76
+ // Create the shader object
77
+ shader = glCreateShader(type);
78
+
79
+ if (shader == 0) {
80
+ S2D_GL_PrintError("Failed to create shader program");
81
+ return 0;
82
+ }
83
+
84
+ // Load the shader source
85
+ glShaderSource(shader, 1, &shaderSrc, NULL);
86
+
87
+ // Compile the shader
88
+ glCompileShader(shader);
89
+
90
+ // Check the compile status
91
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
92
+
93
+ if (!compiled) {
94
+
95
+ GLint infoLen = 0;
96
+
97
+ glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
98
+
99
+ if (infoLen > 1) {
100
+
101
+ char *infoLog = malloc(sizeof(char) * infoLen);
102
+
103
+ glGetShaderInfoLog(shader, infoLen, NULL, infoLog);
104
+ printf("Error compiling shader \"%s\":\n%s\n", shaderName, infoLog);
105
+
106
+ free(infoLog);
107
+ }
108
+
109
+ glDeleteShader(shader);
110
+ return 0;
111
+ }
112
+
113
+ return shader;
114
+ }
115
+
116
+
117
+ /*
118
+ * Check if shader program was linked
119
+ */
120
+ int S2D_GL_CheckLinked(GLuint program, char *name) {
121
+
122
+ GLint linked;
123
+ glGetProgramiv(program, GL_LINK_STATUS, &linked);
124
+
125
+ if (!linked) {
126
+
127
+ GLint infoLen = 0;
128
+ glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLen);
129
+
130
+ if (infoLen > 1) {
131
+
132
+ char *infoLog = malloc(sizeof(char) * infoLen);
133
+
134
+ glGetProgramInfoLog(program, infoLen, NULL, infoLog);
135
+ printf("Error linking program `%s`: %s\n", name, infoLog);
136
+
137
+ free(infoLog);
138
+ }
139
+
140
+ glDeleteProgram(program);
141
+ return GL_FALSE;
142
+ }
143
+
144
+ return GL_TRUE;
145
+ }
146
+
147
+
148
+ /*
149
+ * Calculate the viewport's scaled width and height
150
+ */
151
+ void S2D_GL_GetViewportScale(S2D_Window *window, int *w, int *h, double *scale) {
152
+
153
+ double s = fmin(
154
+ window->width / (double)window->viewport.width,
155
+ window->height / (double)window->viewport.height
156
+ );
157
+
158
+ *w = window->viewport.width * s;
159
+ *h = window->viewport.height * s;
160
+
161
+ if (scale) *scale = s;
162
+ }
163
+
164
+
165
+ /*
166
+ * Sets the viewport and matrix projection
167
+ */
168
+ void S2D_GL_SetViewport(S2D_Window *window) {
169
+
170
+ int ortho_w = window->viewport.width;
171
+ int ortho_h = window->viewport.height;
172
+ int x, y, w, h; // calculated GL viewport values
173
+
174
+ x = 0; y = 0; w = window->width; h = window->height;
175
+
176
+ switch (window->viewport.mode) {
177
+
178
+ case S2D_FIXED:
179
+ w = window->orig_width;
180
+ h = window->orig_height;
181
+ y = window->height - h;
182
+ break;
183
+
184
+ case S2D_EXPAND:
185
+ ortho_w = w;
186
+ ortho_h = h;
187
+ break;
188
+
189
+ case S2D_SCALE:
190
+ S2D_GL_GetViewportScale(window, &w, &h, NULL);
191
+ // Center the viewport
192
+ x = window->width / 2.0 - w/2.0;
193
+ y = window->height / 2.0 - h/2.0;
194
+ break;
195
+
196
+ case S2D_STRETCH:
197
+ break;
198
+ }
199
+
200
+ glViewport(x, y, w, h);
201
+
202
+ // Set orthographic projection matrix
203
+ orthoMatrix[0] = 2.0f / (GLfloat)ortho_w;
204
+ orthoMatrix[5] = -2.0f / (GLfloat)ortho_h;
205
+
206
+ #if GLES
207
+ S2D_GLES_ApplyProjection(orthoMatrix);
208
+ #else
209
+ if (S2D_GL2) {
210
+ S2D_GL2_ApplyProjection(ortho_w, ortho_h);
211
+ } else {
212
+ S2D_GL3_ApplyProjection(orthoMatrix);
213
+ }
214
+ #endif
215
+ }
216
+
217
+
218
+ /*
219
+ * Initialize OpenGL
220
+ */
221
+ int S2D_GL_Init(S2D_Window *window) {
222
+
223
+ // Specify OpenGL contexts and set attributes
224
+ #if GLES
225
+ SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
226
+ SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
227
+ SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
228
+ SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
229
+ #else
230
+ // Use legacy OpenGL 2.1
231
+ if (FORCE_GL2) {
232
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
233
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
234
+ // Request an OpenGL 3.3 forward-compatible core profile
235
+ } else {
236
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
237
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
238
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
239
+ }
240
+ #endif
241
+
242
+ // Create and store the OpenGL context
243
+ if (FORCE_GL2) {
244
+ window->glcontext = NULL;
245
+ } else {
246
+ // Ask SDL to create an OpenGL context
247
+ window->glcontext = SDL_GL_CreateContext(window->sdl);
248
+ }
249
+
250
+ // Check if a valid OpenGL context was created
251
+ if (window->glcontext) {
252
+ // Valid context found
253
+
254
+ // Initialize OpenGL ES 2.0
255
+ #if GLES
256
+ S2D_GLES_Init();
257
+ S2D_GL_SetViewport(window);
258
+
259
+ // Initialize OpenGL 3.3+
260
+ #else
261
+ // Initialize GLEW on Windows
262
+ #if WINDOWS
263
+ GLenum err = glewInit();
264
+ if (GLEW_OK != err) S2D_Error("GLEW", glewGetErrorString(err));
265
+ #endif
266
+ S2D_GL3_Init();
267
+ S2D_GL_SetViewport(window);
268
+ #endif
269
+
270
+ // Context could not be created
271
+ } else {
272
+
273
+ #if GLES
274
+ S2D_Error("GLES / SDL_GL_CreateContext", SDL_GetError());
275
+
276
+ #else
277
+ // Try to fallback using an OpenGL 2.1 context
278
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
279
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
280
+
281
+ // Try creating the context again
282
+ window->glcontext = SDL_GL_CreateContext(window->sdl);
283
+
284
+ // Check if this context was created
285
+ if (window->glcontext) {
286
+ // Valid context found
287
+ S2D_GL2 = true;
288
+ S2D_GL2_Init();
289
+ S2D_GL_SetViewport(window);
290
+
291
+ // Could not create any OpenGL contexts, hard failure
292
+ } else {
293
+ S2D_Error("GL2 / SDL_GL_CreateContext", SDL_GetError());
294
+ S2D_Log(S2D_ERROR, "An OpenGL context could not be created");
295
+ return -1;
296
+ }
297
+ #endif
298
+ }
299
+
300
+ // Store the context and print it if diagnostics is enabled
301
+ S2D_GL_StoreContextInfo(window);
302
+ if (S2D_diagnostics) S2D_GL_PrintContextInfo(window);
303
+
304
+ return 0;
305
+ }
306
+
307
+
308
+ /*
309
+ * Creates a texture for rendering
310
+ */
311
+ void S2D_GL_CreateTexture(GLuint *id, GLint format,
312
+ int w, int h,
313
+ const GLvoid *data, GLint filter) {
314
+
315
+ // If 0, then a new texture; generate name
316
+ if (*id == 0) glGenTextures(1, id);
317
+
318
+ // Bind the named texture to a texturing target
319
+ glBindTexture(GL_TEXTURE_2D, *id);
320
+
321
+ // Specifies the 2D texture image
322
+ glTexImage2D(
323
+ GL_TEXTURE_2D, 0, format, w, h,
324
+ 0, format, GL_UNSIGNED_BYTE, data
325
+ );
326
+
327
+ // Set the filtering mode
328
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
329
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
330
+ }
331
+
332
+
333
+ /*
334
+ * Free a texture
335
+ */
336
+ void S2D_GL_FreeTexture(GLuint *id) {
337
+ if (*id != 0) {
338
+ glDeleteTextures(1, id);
339
+ *id = 0;
340
+ }
341
+ }
342
+
343
+
344
+ /*
345
+ * Draw a triangle
346
+ */
347
+ void S2D_GL_DrawTriangle(GLfloat x1, GLfloat y1,
348
+ GLfloat r1, GLfloat g1, GLfloat b1, GLfloat a1,
349
+ GLfloat x2, GLfloat y2,
350
+ GLfloat r2, GLfloat g2, GLfloat b2, GLfloat a2,
351
+ GLfloat x3, GLfloat y3,
352
+ GLfloat r3, GLfloat g3, GLfloat b3, GLfloat a3) {
353
+
354
+ #if GLES
355
+ S2D_GLES_DrawTriangle(x1, y1, r1, g1, b1, a1,
356
+ x2, y2, r2, g2, b2, a2,
357
+ x3, y3, r3, g3, b3, a3);
358
+ #else
359
+ if (S2D_GL2) {
360
+ S2D_GL2_DrawTriangle(x1, y1, r1, g1, b1, a1,
361
+ x2, y2, r2, g2, b2, a2,
362
+ x3, y3, r3, g3, b3, a3);
363
+ } else {
364
+ S2D_GL3_DrawTriangle(x1, y1, r1, g1, b1, a1,
365
+ x2, y2, r2, g2, b2, a2,
366
+ x3, y3, r3, g3, b3, a3);
367
+ }
368
+ #endif
369
+ }
370
+
371
+
372
+ /*
373
+ * Draw an image
374
+ */
375
+ void S2D_GL_DrawImage(S2D_Image *img) {
376
+ #if GLES
377
+ S2D_GLES_DrawImage(img);
378
+ #else
379
+ if (S2D_GL2) {
380
+ S2D_GL2_DrawImage(img);
381
+ } else {
382
+ S2D_GL3_DrawImage(img);
383
+ }
384
+ #endif
385
+ }
386
+
387
+
388
+ /*
389
+ * Draw sprite
390
+ */
391
+ void S2D_GL_DrawSprite(S2D_Sprite *spr) {
392
+ #if GLES
393
+ S2D_GLES_DrawSprite(spr);
394
+ #else
395
+ if (S2D_GL2) {
396
+ S2D_GL2_DrawSprite(spr);
397
+ } else {
398
+ S2D_GL3_DrawSprite(spr);
399
+ }
400
+ #endif
401
+ }
402
+
403
+
404
+ /*
405
+ * Draw text
406
+ */
407
+ void S2D_GL_DrawText(S2D_Text *txt) {
408
+ #if GLES
409
+ S2D_GLES_DrawText(txt);
410
+ #else
411
+ if (S2D_GL2) {
412
+ S2D_GL2_DrawText(txt);
413
+ } else {
414
+ S2D_GL3_DrawText(txt);
415
+ }
416
+ #endif
417
+ }
418
+
419
+
420
+ /*
421
+ * Clear buffers to given color values
422
+ */
423
+ void S2D_GL_Clear(S2D_Color clr) {
424
+ glClearColor(clr.r, clr.g, clr.b, clr.a);
425
+ glClear(GL_COLOR_BUFFER_BIT);
426
+ }