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,185 @@
1
+ // Simple 2D Shared functions and data
2
+
3
+ #include "../include/simple2d.h"
4
+
5
+ // Initalize S2D shared data
6
+ bool S2D_diagnostics = false;
7
+
8
+ // S2D initialization status
9
+ static bool initted = false;
10
+
11
+
12
+ /*
13
+ * Provide a `vasprintf()` implementation for Windows
14
+ */
15
+ #if WINDOWS && !MINGW
16
+ int vasprintf(char **strp, const char *fmt, va_list ap) {
17
+ int r = -1, size = _vscprintf(fmt, ap);
18
+ if ((size >= 0) && (size < INT_MAX)) {
19
+ *strp = (char *)malloc(size + 1);
20
+ if (*strp) {
21
+ r = vsnprintf(*strp, size + 1, fmt, ap);
22
+ if (r == -1) free(*strp);
23
+ }
24
+ } else { *strp = 0; }
25
+ return(r);
26
+ }
27
+ #endif
28
+
29
+
30
+ /*
31
+ * Checks if a file exists and can be accessed
32
+ */
33
+ bool S2D_FileExists(const char *path) {
34
+ if (!path) return false;
35
+
36
+ if (access(path, F_OK) != -1) {
37
+ return true;
38
+ } else {
39
+ return false;
40
+ }
41
+ }
42
+
43
+
44
+ /*
45
+ * Logs standard messages to the console
46
+ */
47
+ void S2D_Log(int type, const char *msg, ...) {
48
+
49
+ // Always log if diagnostics set, or if a warning or error message
50
+ if (S2D_diagnostics || type != S2D_INFO) {
51
+
52
+ va_list args;
53
+ va_start(args, msg);
54
+
55
+ switch (type) {
56
+ case S2D_INFO:
57
+ printf("\033[1;36mInfo:\033[0m ");
58
+ break;
59
+ case S2D_WARN:
60
+ printf("\033[1;33mWarning:\033[0m ");
61
+ break;
62
+ case S2D_ERROR:
63
+ printf("\033[1;31mError:\033[0m ");
64
+ break;
65
+ }
66
+
67
+ vprintf(msg, args);
68
+ printf("\n");
69
+ va_end(args);
70
+ }
71
+ }
72
+
73
+
74
+ /*
75
+ * Logs Simple 2D errors to the console, with caller and message body
76
+ */
77
+ void S2D_Error(const char *caller, const char *msg, ...) {
78
+ va_list args;
79
+ va_start(args, msg);
80
+ char *fmsg;
81
+ vasprintf(&fmsg, msg, args);
82
+ S2D_Log(S2D_ERROR, "(%s) %s", caller, fmsg);
83
+ free(fmsg);
84
+ va_end(args);
85
+ }
86
+
87
+
88
+ /*
89
+ * Enable/disable logging of diagnostics
90
+ */
91
+ void S2D_Diagnostics(bool status) {
92
+ S2D_diagnostics = status;
93
+ }
94
+
95
+
96
+ /*
97
+ * Enable terminal colors in Windows
98
+ */
99
+ void S2D_Windows_EnableTerminalColors() {
100
+ #if WINDOWS
101
+ HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
102
+ DWORD dwMode = 0;
103
+ GetConsoleMode(hOut, &dwMode);
104
+ dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
105
+ SetConsoleMode(hOut, dwMode);
106
+ #endif
107
+ }
108
+
109
+
110
+ /*
111
+ * Initialize Simple 2D subsystems
112
+ */
113
+ bool S2D_Init() {
114
+ if (initted) return true;
115
+
116
+ // Enable terminal colors in Windows
117
+ S2D_Windows_EnableTerminalColors();
118
+
119
+ S2D_Log(S2D_INFO, "Initializing Simple 2D");
120
+
121
+ // Initialize SDL
122
+ if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
123
+ S2D_Error("SDL_Init", SDL_GetError());
124
+ return false;
125
+ }
126
+
127
+ // Initialize SDL_ttf
128
+ if (TTF_Init() != 0) {
129
+ S2D_Error("TTF_Init", TTF_GetError());
130
+ return false;
131
+ }
132
+
133
+ // Initialize SDL_mixer
134
+ int mix_flags = MIX_INIT_FLAC | MIX_INIT_OGG | MIX_INIT_MP3;
135
+ int mix_initted = Mix_Init(mix_flags);
136
+
137
+ // Bug in SDL2_mixer 2.0.2:
138
+ // Mix_Init should return OR'ed flags if successful, but returns 0 instead.
139
+ // Fixed in: https://hg.libsdl.org/SDL_mixer/rev/7fa15b556953
140
+ const SDL_version *linked_version = Mix_Linked_Version();
141
+ if (linked_version->major == 2 && linked_version->minor == 0 && linked_version->patch == 2) {
142
+ // It's version 2.0.2, don't check for Mix_Init errors
143
+ } else {
144
+ if ((mix_initted&mix_flags) != mix_flags) {
145
+ S2D_Error("Mix_Init", Mix_GetError());
146
+ }
147
+ }
148
+
149
+ if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 4096) != 0) {
150
+ S2D_Error("Mix_OpenAudio", Mix_GetError());
151
+ return false;
152
+ }
153
+
154
+ // Call `S2D_Quit` at program exit
155
+ atexit(S2D_Quit);
156
+
157
+ // All subsystems initted
158
+ initted = true;
159
+ return true;
160
+ }
161
+
162
+
163
+ /*
164
+ * Gets the primary display's dimentions
165
+ */
166
+ void S2D_GetDisplayDimensions(int *w, int *h) {
167
+ S2D_Init();
168
+ SDL_DisplayMode dm;
169
+ SDL_GetCurrentDisplayMode(0, &dm);
170
+ *w = dm.w;
171
+ *h = dm.h;
172
+ }
173
+
174
+
175
+ /*
176
+ * Quits Simple 2D subsystems
177
+ */
178
+ void S2D_Quit() {
179
+ IMG_Quit();
180
+ Mix_CloseAudio();
181
+ Mix_Quit();
182
+ TTF_Quit();
183
+ SDL_Quit();
184
+ initted = false;
185
+ }
@@ -0,0 +1,56 @@
1
+ // sound.c
2
+
3
+ #include "../include/simple2d.h"
4
+
5
+
6
+ /*
7
+ * Create a sound, given an audio file path
8
+ */
9
+ S2D_Sound *S2D_CreateSound(const char *path) {
10
+ S2D_Init();
11
+
12
+ // Check if sound file exists
13
+ if (!S2D_FileExists(path)) {
14
+ S2D_Error("S2D_CreateSound", "Sound file `%s` not found", path);
15
+ return NULL;
16
+ }
17
+
18
+ // Allocate the sound structure
19
+ S2D_Sound *snd = (S2D_Sound *) malloc(sizeof(S2D_Sound));
20
+ if (!snd) {
21
+ S2D_Error("S2D_CreateSound", "Out of memory!");
22
+ return NULL;
23
+ }
24
+
25
+ // Load the sound data from file
26
+ snd->data = Mix_LoadWAV(path);
27
+ if (!snd->data) {
28
+ S2D_Error("Mix_LoadWAV", Mix_GetError());
29
+ free(snd);
30
+ return NULL;
31
+ }
32
+
33
+ // Initialize values
34
+ snd->path = path;
35
+
36
+ return snd;
37
+ }
38
+
39
+
40
+ /*
41
+ * Play the sound
42
+ */
43
+ void S2D_PlaySound(S2D_Sound *snd) {
44
+ if (!snd) return;
45
+ Mix_PlayChannel(-1, snd->data, 0);
46
+ }
47
+
48
+
49
+ /*
50
+ * Free the sound
51
+ */
52
+ void S2D_FreeSound(S2D_Sound *snd) {
53
+ if (!snd) return;
54
+ Mix_FreeChunk(snd->data);
55
+ free(snd);
56
+ }
@@ -0,0 +1,147 @@
1
+ // sprite.c
2
+
3
+ #include "../include/simple2d.h"
4
+
5
+
6
+ /*
7
+ * Create a sprite, given an image file path
8
+ */
9
+ S2D_Sprite *S2D_CreateSprite(const char *path) {
10
+
11
+ // Check if image file exists
12
+ if (!S2D_FileExists(path)) {
13
+ S2D_Error("S2D_CreateSprite", "Sprite image file `%s` not found", path);
14
+ return NULL;
15
+ }
16
+
17
+ // Allocate the sprite structure
18
+ S2D_Sprite *spr = (S2D_Sprite *) malloc(sizeof(S2D_Sprite));
19
+ if (!spr) {
20
+ S2D_Error("S2D_CreateSprite", "Out of memory!");
21
+ return NULL;
22
+ }
23
+
24
+ // Load the sprite image file
25
+ spr->img = S2D_CreateImage(path);
26
+ if (!spr->img) {
27
+ S2D_Error("S2D_CreateSprite", "Cannot create sprite image `%s`", path);
28
+ free(spr);
29
+ return NULL;
30
+ }
31
+
32
+ // Initialize values
33
+ spr->path = path;
34
+ spr->x = 0;
35
+ spr->y = 0;
36
+ spr->color.r = 1.f;
37
+ spr->color.g = 1.f;
38
+ spr->color.b = 1.f;
39
+ spr->color.a = 1.f;
40
+ spr->width = spr->img->width;
41
+ spr->height = spr->img->height;
42
+ spr->clip_width = spr->img->width;
43
+ spr->clip_height = spr->img->height;
44
+ spr->rotate = 0;
45
+ spr->rx = 0;
46
+ spr->ry = 0;
47
+ spr->tx1 = 0.f;
48
+ spr->ty1 = 0.f;
49
+ spr->tx2 = 1.f;
50
+ spr->ty2 = 0.f;
51
+ spr->tx3 = 1.f;
52
+ spr->ty3 = 1.f;
53
+ spr->tx4 = 0.f;
54
+ spr->ty4 = 1.f;
55
+
56
+ return spr;
57
+ }
58
+
59
+
60
+ /*
61
+ * Clip a sprite
62
+ */
63
+ void S2D_ClipSprite(S2D_Sprite *spr, int x, int y, int w, int h) {
64
+ if (!spr) return;
65
+
66
+ // Calculate ratios
67
+ // rw = ratio width; rh = ratio height
68
+ double rw = w / (double)spr->img->width;
69
+ double rh = h / (double)spr->img->height;
70
+
71
+ // Apply ratios to x, y coordinates
72
+ // cx = crop x coord; cy = crop y coord
73
+ double cx = x * rw;
74
+ double cy = y * rh;
75
+
76
+ // Convert given width, height to doubles
77
+ // cw = crop width; ch = crop height
78
+ double cw = (double)w;
79
+ double ch = (double)h;
80
+
81
+ // Apply ratio to texture width and height
82
+ // tw = texture width; th = texture height
83
+ double tw = rw * w;
84
+ double th = rh * h;
85
+
86
+ // Calculate and store sprite texture values
87
+
88
+ spr->tx1 = cx / cw;
89
+ spr->ty1 = cy / ch;
90
+
91
+ spr->tx2 = (cx + tw) / cw;
92
+ spr->ty2 = cy / ch;
93
+
94
+ spr->tx3 = (cx + tw) / cw;
95
+ spr->ty3 = (cy + th) / ch;
96
+
97
+ spr->tx4 = cx / cw;
98
+ spr->ty4 = (cy + th) / ch;
99
+
100
+ // Store the sprite dimensions
101
+ spr->width = (spr->width / (double)spr->clip_width ) * w;
102
+ spr->height = (spr->height / (double)spr->clip_height) * h;
103
+ spr->clip_width = w;
104
+ spr->clip_height = h;
105
+ }
106
+
107
+
108
+ /*
109
+ * Rotate a sprite
110
+ */
111
+ void S2D_RotateSprite(S2D_Sprite *spr, GLfloat angle, int position) {
112
+
113
+ S2D_GL_Point p = S2D_GetRectRotationPoint(
114
+ spr->x, spr->y, spr->width, spr->height, position
115
+ );
116
+
117
+ spr->rotate = angle;
118
+ spr->rx = p.x;
119
+ spr->ry = p.y;
120
+ }
121
+
122
+
123
+ /*
124
+ * Draw a sprite
125
+ */
126
+ void S2D_DrawSprite(S2D_Sprite *spr) {
127
+ if (!spr) return;
128
+
129
+ if (spr->img->texture_id == 0) {
130
+ S2D_GL_CreateTexture(&spr->img->texture_id, spr->img->format,
131
+ spr->img->width, spr->img->height,
132
+ spr->img->surface->pixels, GL_NEAREST);
133
+ SDL_FreeSurface(spr->img->surface);
134
+ }
135
+
136
+ S2D_GL_DrawSprite(spr);
137
+ }
138
+
139
+
140
+ /*
141
+ * Free a sprite
142
+ */
143
+ void S2D_FreeSprite(S2D_Sprite *spr) {
144
+ if (!spr) return;
145
+ S2D_FreeImage(spr->img);
146
+ free(spr);
147
+ }
@@ -0,0 +1,129 @@
1
+ // text.c
2
+
3
+ #include "../include/simple2d.h"
4
+
5
+
6
+ /*
7
+ * Create text, given a font file path, the message, and size
8
+ */
9
+ S2D_Text *S2D_CreateText(const char *font, const char *msg, int size) {
10
+ S2D_Init();
11
+
12
+ // Check if font file exists
13
+ if (!S2D_FileExists(font)) {
14
+ S2D_Error("S2D_CreateText", "Font file `%s` not found", font);
15
+ return NULL;
16
+ }
17
+
18
+ // `msg` cannot be an empty string or NULL for TTF_SizeText
19
+ if (msg == NULL || strlen(msg) == 0) msg = " ";
20
+
21
+ // Allocate the text structure
22
+ S2D_Text *txt = (S2D_Text *) malloc(sizeof(S2D_Text));
23
+ if (!txt) {
24
+ S2D_Error("S2D_CreateText", "Out of memory!");
25
+ return NULL;
26
+ }
27
+
28
+ // Open the font
29
+ txt->font_data = TTF_OpenFont(font, size);
30
+ if (!txt->font_data) {
31
+ S2D_Error("TTF_OpenFont", TTF_GetError());
32
+ free(txt);
33
+ return NULL;
34
+ }
35
+
36
+ // Initialize values
37
+ txt->font = font;
38
+ txt->msg = (char *) malloc(strlen(msg) + 1 * sizeof(char));
39
+ strcpy(txt->msg, msg);
40
+ txt->x = 0;
41
+ txt->y = 0;
42
+ txt->color.r = 1.f;
43
+ txt->color.g = 1.f;
44
+ txt->color.b = 1.f;
45
+ txt->color.a = 1.f;
46
+ txt->rotate = 0;
47
+ txt->rx = 0;
48
+ txt->ry = 0;
49
+ txt->texture_id = 0;
50
+
51
+ // Save the width and height of the text
52
+ TTF_SizeText(txt->font_data, txt->msg, &txt->width, &txt->height);
53
+
54
+ return txt;
55
+ }
56
+
57
+
58
+ /*
59
+ * Set the text message
60
+ */
61
+ void S2D_SetText(S2D_Text *txt, const char *msg, ...) {
62
+ if (!txt) return;
63
+
64
+ // `msg` cannot be an empty string or NULL for TTF_SizeText
65
+ if (msg == NULL || strlen(msg) == 0) msg = " ";
66
+
67
+ // Format and store new text string
68
+ va_list args;
69
+ va_start(args, msg);
70
+ free(txt->msg);
71
+ vasprintf(&txt->msg, msg, args);
72
+ va_end(args);
73
+
74
+ // Save the width and height of the text
75
+ TTF_SizeText(txt->font_data, txt->msg, &txt->width, &txt->height);
76
+
77
+ // Delete the current texture so a new one can be generated
78
+ S2D_GL_FreeTexture(&txt->texture_id);
79
+ }
80
+
81
+
82
+ /*
83
+ * Rotate text
84
+ */
85
+ void S2D_RotateText(S2D_Text *txt, GLfloat angle, int position) {
86
+
87
+ S2D_GL_Point p = S2D_GetRectRotationPoint(
88
+ txt->x, txt->y, txt->width, txt->height, position
89
+ );
90
+
91
+ txt->rotate = angle;
92
+ txt->rx = p.x;
93
+ txt->ry = p.y;
94
+ }
95
+
96
+
97
+ /*
98
+ * Draw text
99
+ */
100
+ void S2D_DrawText(S2D_Text *txt) {
101
+ if (!txt) return;
102
+
103
+ if (txt->texture_id == 0) {
104
+ SDL_Color color = { 255, 255, 255 };
105
+ txt->surface = TTF_RenderText_Blended(txt->font_data, txt->msg, color);
106
+ if (!txt->surface) {
107
+ S2D_Error("TTF_RenderText_Blended", TTF_GetError());
108
+ return;
109
+ }
110
+ S2D_GL_CreateTexture(&txt->texture_id, GL_RGBA,
111
+ txt->width, txt->height,
112
+ txt->surface->pixels, GL_NEAREST);
113
+ SDL_FreeSurface(txt->surface);
114
+ }
115
+
116
+ S2D_GL_DrawText(txt);
117
+ }
118
+
119
+
120
+ /*
121
+ * Free the text
122
+ */
123
+ void S2D_FreeText(S2D_Text *txt) {
124
+ if (!txt) return;
125
+ free(txt->msg);
126
+ S2D_GL_FreeTexture(&txt->texture_id);
127
+ TTF_CloseFont(txt->font_data);
128
+ free(txt);
129
+ }