ruby2d 0.9.0 → 0.9.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/assets/README.md +1 -0
- data/assets/linux/simple2d/Makefile +250 -0
- data/assets/linux/simple2d/bin/simple2d.sh +1249 -0
- data/assets/linux/simple2d/include/simple2d.h +735 -0
- data/assets/linux/simple2d/src/controllers.c +110 -0
- data/assets/linux/simple2d/src/gl.c +426 -0
- data/assets/linux/simple2d/src/gl2.c +146 -0
- data/assets/linux/simple2d/src/gl3.c +275 -0
- data/assets/linux/simple2d/src/gles.c +308 -0
- data/assets/linux/simple2d/src/image.c +138 -0
- data/assets/linux/simple2d/src/input.c +48 -0
- data/assets/linux/simple2d/src/music.c +114 -0
- data/assets/linux/simple2d/src/shapes.c +154 -0
- data/assets/linux/simple2d/src/simple2d.c +185 -0
- data/assets/linux/simple2d/src/sound.c +56 -0
- data/assets/linux/simple2d/src/sprite.c +147 -0
- data/assets/linux/simple2d/src/text.c +129 -0
- data/assets/linux/simple2d/src/window.c +403 -0
- data/ext/ruby2d/extconf.rb +110 -29
- data/lib/ruby2d/version.rb +1 -1
- metadata +19 -2
@@ -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
|
+
}
|