ruby2d 0.9.3 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/assets/README.md +7 -9
- data/assets/Rakefile +85 -0
- data/assets/include/SDL2/SDL.h +4 -1
- data/assets/include/SDL2/SDL_assert.h +3 -1
- data/assets/include/SDL2/SDL_atomic.h +20 -2
- data/assets/include/SDL2/SDL_audio.h +47 -14
- data/assets/include/SDL2/SDL_bits.h +10 -1
- data/assets/include/SDL2/SDL_blendmode.h +10 -7
- data/assets/include/SDL2/SDL_clipboard.h +1 -1
- data/assets/include/SDL2/SDL_config.h +24 -390
- data/assets/include/SDL2/SDL_config_android.h +182 -0
- data/assets/include/SDL2/SDL_config_iphoneos.h +207 -0
- data/assets/include/SDL2/SDL_config_macosx.h +266 -0
- data/assets/include/SDL2/SDL_config_minimal.h +85 -0
- data/assets/include/SDL2/SDL_config_os2.h +188 -0
- data/assets/include/SDL2/SDL_config_pandora.h +135 -0
- data/assets/include/SDL2/SDL_config_psp.h +165 -0
- data/assets/include/SDL2/SDL_config_windows.h +288 -0
- data/assets/include/SDL2/SDL_config_winrt.h +243 -0
- data/assets/include/SDL2/SDL_config_wiz.h +149 -0
- data/assets/include/SDL2/SDL_copying.h +20 -0
- data/assets/include/SDL2/SDL_cpuinfo.h +119 -8
- data/assets/include/SDL2/SDL_egl.h +4 -1
- data/assets/include/SDL2/SDL_endian.h +6 -3
- data/assets/include/SDL2/SDL_error.h +38 -2
- data/assets/include/SDL2/SDL_events.h +67 -28
- data/assets/include/SDL2/SDL_filesystem.h +1 -1
- data/assets/include/SDL2/SDL_gamecontroller.h +160 -9
- data/assets/include/SDL2/SDL_gesture.h +1 -1
- data/assets/include/SDL2/SDL_haptic.h +10 -1
- data/assets/include/SDL2/SDL_hints.h +460 -17
- data/assets/include/SDL2/SDL_image.h +2 -2
- data/assets/include/SDL2/SDL_joystick.h +115 -24
- data/assets/include/SDL2/SDL_keyboard.h +1 -1
- data/assets/include/SDL2/SDL_keycode.h +11 -9
- data/assets/include/SDL2/SDL_loadso.h +1 -1
- data/assets/include/SDL2/SDL_locale.h +101 -0
- data/assets/include/SDL2/SDL_log.h +3 -3
- data/assets/include/SDL2/SDL_main.h +28 -16
- data/assets/include/SDL2/SDL_messagebox.h +6 -4
- data/assets/include/SDL2/SDL_metal.h +117 -0
- data/assets/include/SDL2/SDL_misc.h +75 -0
- data/assets/include/SDL2/SDL_mouse.h +1 -1
- data/assets/include/SDL2/SDL_mutex.h +1 -1
- data/assets/include/SDL2/SDL_name.h +1 -1
- data/assets/include/SDL2/SDL_opengl.h +1 -1
- data/assets/include/SDL2/SDL_opengl_glext.h +3 -0
- data/assets/include/SDL2/SDL_opengles.h +1 -1
- data/assets/include/SDL2/SDL_opengles2.h +1 -1
- data/assets/include/SDL2/SDL_pixels.h +27 -18
- data/assets/include/SDL2/SDL_platform.h +1 -1
- data/assets/include/SDL2/SDL_power.h +1 -1
- data/assets/include/SDL2/SDL_quit.h +1 -1
- data/assets/include/SDL2/SDL_rect.h +29 -3
- data/assets/include/SDL2/SDL_render.h +230 -3
- data/assets/include/SDL2/SDL_revision.h +2 -2
- data/assets/include/SDL2/SDL_rwops.h +51 -22
- data/assets/include/SDL2/SDL_scancode.h +2 -2
- data/assets/include/SDL2/SDL_sensor.h +28 -12
- data/assets/include/SDL2/SDL_shape.h +1 -1
- data/assets/include/SDL2/SDL_stdinc.h +44 -4
- data/assets/include/SDL2/SDL_surface.h +12 -2
- data/assets/include/SDL2/SDL_system.h +50 -4
- data/assets/include/SDL2/SDL_syswm.h +39 -9
- data/assets/include/SDL2/SDL_test.h +1 -1
- data/assets/include/SDL2/SDL_test_assert.h +1 -1
- data/assets/include/SDL2/SDL_test_common.h +32 -2
- data/assets/include/SDL2/SDL_test_compare.h +1 -1
- data/assets/include/SDL2/SDL_test_crc32.h +1 -1
- data/assets/include/SDL2/SDL_test_font.h +1 -1
- data/assets/include/SDL2/SDL_test_fuzzer.h +1 -1
- data/assets/include/SDL2/SDL_test_harness.h +1 -1
- data/assets/include/SDL2/SDL_test_images.h +1 -1
- data/assets/include/SDL2/SDL_test_log.h +1 -1
- data/assets/include/SDL2/SDL_test_md5.h +1 -1
- data/assets/include/SDL2/SDL_test_memory.h +3 -3
- data/assets/include/SDL2/SDL_test_random.h +1 -1
- data/assets/include/SDL2/SDL_thread.h +34 -11
- data/assets/include/SDL2/SDL_timer.h +1 -1
- data/assets/include/SDL2/SDL_touch.h +17 -1
- data/assets/include/SDL2/SDL_types.h +1 -1
- data/assets/include/SDL2/SDL_version.h +2 -2
- data/assets/include/SDL2/SDL_video.h +11 -5
- data/assets/include/SDL2/SDL_vulkan.h +9 -11
- data/assets/include/SDL2/begin_code.h +8 -9
- data/assets/include/SDL2/close_code.h +4 -1
- data/assets/macos/lib/libFLAC.a +0 -0
- data/assets/macos/lib/libSDL2.a +0 -0
- data/assets/macos/lib/libSDL2_image.a +0 -0
- data/assets/macos/lib/libSDL2_mixer.a +0 -0
- data/assets/macos/lib/libSDL2_ttf.a +0 -0
- data/assets/macos/lib/libfreetype.a +0 -0
- data/assets/macos/lib/libjpeg.a +0 -0
- data/assets/macos/lib/libmpg123.a +0 -0
- data/assets/macos/lib/libogg.a +0 -0
- data/assets/macos/lib/libpng16.a +0 -0
- data/assets/macos/lib/libtiff.a +0 -0
- data/assets/macos/lib/libvorbis.a +0 -0
- data/assets/macos/lib/libvorbisfile.a +0 -0
- data/assets/macos/lib/libwebp.a +0 -0
- data/assets/mingw/bin/SDL2.dll +0 -0
- data/assets/mingw/bin/SDL2_image.dll +0 -0
- data/assets/mingw/bin/libpng16-16.dll +0 -0
- data/assets/mingw/bin/libtiff-5.dll +0 -0
- data/assets/mingw/bin/libwebp-7.dll +0 -0
- data/assets/mingw/lib/libSDL2.a +0 -0
- data/assets/mingw/lib/libSDL2.dll.a +0 -0
- data/assets/mingw/lib/libSDL2_image.a +0 -0
- data/assets/mingw/lib/libSDL2_image.dll.a +0 -0
- data/assets/mingw/lib/libSDL2_test.a +0 -0
- data/assets/mingw/lib/libSDL2main.a +0 -0
- data/bin/ruby2d +1 -0
- data/{assets/linux/simple2d/src/simple2d.c → ext/ruby2d/common.c} +32 -32
- data/{assets/linux/simple2d/src → ext/ruby2d}/controllers.c +17 -17
- data/ext/ruby2d/extconf.rb +36 -58
- data/ext/ruby2d/font.c +35 -0
- data/{assets/linux/simple2d/src → ext/ruby2d}/gl.c +72 -100
- data/ext/ruby2d/gl2.c +86 -0
- data/ext/ruby2d/gl3.c +305 -0
- data/{assets/linux/simple2d/src → ext/ruby2d}/gles.c +22 -81
- data/ext/ruby2d/image.c +58 -0
- data/{assets/linux/simple2d/src → ext/ruby2d}/input.c +8 -8
- data/{assets/linux/simple2d/src → ext/ruby2d}/music.c +30 -17
- data/ext/ruby2d/ruby2d.c +449 -439
- data/ext/ruby2d/ruby2d.h +652 -0
- data/{assets/linux/simple2d/src → ext/ruby2d}/shapes.c +18 -18
- data/ext/ruby2d/sound.c +118 -0
- data/ext/ruby2d/text.c +22 -0
- data/{assets/linux/simple2d/src → ext/ruby2d}/window.c +73 -62
- data/lib/ruby2d/circle.rb +21 -3
- data/lib/ruby2d/cli/build.rb +4 -7
- data/lib/ruby2d/dsl.rb +16 -9
- data/lib/ruby2d/entity.rb +17 -0
- data/lib/ruby2d/font.rb +23 -3
- data/lib/ruby2d/image.rb +35 -7
- data/lib/ruby2d/line.rb +23 -1
- data/lib/ruby2d/music.rb +5 -0
- data/lib/ruby2d/pixel.rb +17 -0
- data/lib/ruby2d/quad.rb +21 -1
- data/lib/ruby2d/rectangle.rb +12 -3
- data/lib/ruby2d/renderable.rb +4 -20
- data/lib/ruby2d/sound.rb +30 -0
- data/lib/ruby2d/sprite.rb +57 -75
- data/lib/ruby2d/square.rb +10 -1
- data/lib/ruby2d/text.rb +55 -12
- data/lib/ruby2d/texture.rb +28 -0
- data/lib/ruby2d/tileset.rb +87 -0
- data/lib/ruby2d/triangle.rb +19 -1
- data/lib/ruby2d/version.rb +1 -1
- data/lib/ruby2d/vertices.rb +84 -0
- data/lib/ruby2d/window.rb +259 -22
- data/lib/ruby2d.rb +6 -1
- metadata +41 -26
- data/assets/include/simple2d.h +0 -735
- data/assets/linux/simple2d/Makefile +0 -257
- data/assets/linux/simple2d/bin/simple2d.sh +0 -1312
- data/assets/linux/simple2d/include/simple2d.h +0 -735
- data/assets/linux/simple2d/src/gl2.c +0 -146
- data/assets/linux/simple2d/src/gl3.c +0 -275
- data/assets/linux/simple2d/src/image.c +0 -138
- data/assets/linux/simple2d/src/sound.c +0 -56
- data/assets/linux/simple2d/src/sprite.c +0 -147
- data/assets/linux/simple2d/src/text.c +0 -129
- data/assets/macos/lib/libsimple2d.a +0 -0
- data/assets/mingw/lib/libsimple2d.a +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// shapes.c
|
|
2
2
|
|
|
3
|
-
#include "
|
|
3
|
+
#include "ruby2d.h"
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
/*
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* rx The x coordinate to rotate around
|
|
12
12
|
* ry The y coordinate to rotate around
|
|
13
13
|
*/
|
|
14
|
-
|
|
14
|
+
R2D_GL_Point R2D_RotatePoint(R2D_GL_Point p, GLfloat angle, GLfloat rx, GLfloat ry) {
|
|
15
15
|
|
|
16
16
|
// Convert from degrees to radians
|
|
17
17
|
angle = angle * M_PI / 180.0;
|
|
@@ -39,28 +39,28 @@ S2D_GL_Point S2D_RotatePoint(S2D_GL_Point p, GLfloat angle, GLfloat rx, GLfloat
|
|
|
39
39
|
/*
|
|
40
40
|
* Get the point to be rotated around given a position in a rectangle
|
|
41
41
|
*/
|
|
42
|
-
|
|
42
|
+
R2D_GL_Point R2D_GetRectRotationPoint(int x, int y, int w, int h, int position) {
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
R2D_GL_Point p;
|
|
45
45
|
|
|
46
46
|
switch (position) {
|
|
47
|
-
case
|
|
47
|
+
case R2D_CENTER:
|
|
48
48
|
p.x = x + (w / 2.0);
|
|
49
49
|
p.y = y + (h / 2.0);
|
|
50
50
|
break;
|
|
51
|
-
case
|
|
51
|
+
case R2D_TOP_LEFT:
|
|
52
52
|
p.x = x;
|
|
53
53
|
p.y = y;
|
|
54
54
|
break;
|
|
55
|
-
case
|
|
55
|
+
case R2D_TOP_RIGHT:
|
|
56
56
|
p.x = x + w;
|
|
57
57
|
p.y = y;
|
|
58
58
|
break;
|
|
59
|
-
case
|
|
59
|
+
case R2D_BOTTOM_LEFT:
|
|
60
60
|
p.x = x;
|
|
61
61
|
p.y = y + h;
|
|
62
62
|
break;
|
|
63
|
-
case
|
|
63
|
+
case R2D_BOTTOM_RIGHT:
|
|
64
64
|
p.x = x + w;
|
|
65
65
|
p.y = y + h;
|
|
66
66
|
break;
|
|
@@ -73,14 +73,14 @@ S2D_GL_Point S2D_GetRectRotationPoint(int x, int y, int w, int h, int position)
|
|
|
73
73
|
/*
|
|
74
74
|
* Draw a triangle
|
|
75
75
|
*/
|
|
76
|
-
void
|
|
76
|
+
void R2D_DrawTriangle(GLfloat x1, GLfloat y1,
|
|
77
77
|
GLfloat r1, GLfloat g1, GLfloat b1, GLfloat a1,
|
|
78
78
|
GLfloat x2, GLfloat y2,
|
|
79
79
|
GLfloat r2, GLfloat g2, GLfloat b2, GLfloat a2,
|
|
80
80
|
GLfloat x3, GLfloat y3,
|
|
81
81
|
GLfloat r3, GLfloat g3, GLfloat b3, GLfloat a3) {
|
|
82
82
|
|
|
83
|
-
|
|
83
|
+
R2D_GL_DrawTriangle(x1, y1, r1, g1, b1, a1,
|
|
84
84
|
x2, y2, r2, g2, b2, a2,
|
|
85
85
|
x3, y3, r3, g3, b3, a3);
|
|
86
86
|
}
|
|
@@ -89,7 +89,7 @@ void S2D_DrawTriangle(GLfloat x1, GLfloat y1,
|
|
|
89
89
|
/*
|
|
90
90
|
* Draw a quad, using two triangles
|
|
91
91
|
*/
|
|
92
|
-
void
|
|
92
|
+
void R2D_DrawQuad(GLfloat x1, GLfloat y1,
|
|
93
93
|
GLfloat r1, GLfloat g1, GLfloat b1, GLfloat a1,
|
|
94
94
|
GLfloat x2, GLfloat y2,
|
|
95
95
|
GLfloat r2, GLfloat g2, GLfloat b2, GLfloat a2,
|
|
@@ -98,11 +98,11 @@ void S2D_DrawQuad(GLfloat x1, GLfloat y1,
|
|
|
98
98
|
GLfloat x4, GLfloat y4,
|
|
99
99
|
GLfloat r4, GLfloat g4, GLfloat b4, GLfloat a4) {
|
|
100
100
|
|
|
101
|
-
|
|
101
|
+
R2D_GL_DrawTriangle(x1, y1, r1, g1, b1, a1,
|
|
102
102
|
x2, y2, r2, g2, b2, a2,
|
|
103
103
|
x3, y3, r3, g3, b3, a3);
|
|
104
104
|
|
|
105
|
-
|
|
105
|
+
R2D_GL_DrawTriangle(x3, y3, r3, g3, b3, a3,
|
|
106
106
|
x4, y4, r4, g4, b4, a4,
|
|
107
107
|
x1, y1, r1, g1, b1, a1);
|
|
108
108
|
};
|
|
@@ -111,7 +111,7 @@ void S2D_DrawQuad(GLfloat x1, GLfloat y1,
|
|
|
111
111
|
/*
|
|
112
112
|
* Draw a line from a quad
|
|
113
113
|
*/
|
|
114
|
-
void
|
|
114
|
+
void R2D_DrawLine(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2,
|
|
115
115
|
GLfloat width,
|
|
116
116
|
GLfloat r1, GLfloat g1, GLfloat b1, GLfloat a1,
|
|
117
117
|
GLfloat r2, GLfloat g2, GLfloat b2, GLfloat a2,
|
|
@@ -122,7 +122,7 @@ void S2D_DrawLine(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2,
|
|
|
122
122
|
double x = ((x2 - x1) / length) * width / 2;
|
|
123
123
|
double y = ((y2 - y1) / length) * width / 2;
|
|
124
124
|
|
|
125
|
-
|
|
125
|
+
R2D_DrawQuad(
|
|
126
126
|
x1 - y, y1 + x, r1, g1, b1, a1,
|
|
127
127
|
x1 + y, y1 - x, r2, g2, b2, a2,
|
|
128
128
|
x2 + y, y2 - x, r3, g3, b3, a3,
|
|
@@ -134,7 +134,7 @@ void S2D_DrawLine(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2,
|
|
|
134
134
|
/*
|
|
135
135
|
* Draw a circle from triangles
|
|
136
136
|
*/
|
|
137
|
-
void
|
|
137
|
+
void R2D_DrawCircle(GLfloat x, GLfloat y, GLfloat radius, int sectors,
|
|
138
138
|
GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
|
|
139
139
|
|
|
140
140
|
double angle = 2 * M_PI / sectors;
|
|
@@ -147,7 +147,7 @@ void S2D_DrawCircle(GLfloat x, GLfloat y, GLfloat radius, int sectors,
|
|
|
147
147
|
GLfloat x2 = x + radius * cos((i - 1) * angle);
|
|
148
148
|
GLfloat y2 = y + radius * sin((i - 1) * angle);
|
|
149
149
|
|
|
150
|
-
|
|
150
|
+
R2D_GL_DrawTriangle( x, y, r, g, b, a,
|
|
151
151
|
x1, y1, r, g, b, a,
|
|
152
152
|
x2, y2, r, g, b, a);
|
|
153
153
|
}
|
data/ext/ruby2d/sound.c
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
// sound.c
|
|
2
|
+
|
|
3
|
+
#include "ruby2d.h"
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
/*
|
|
7
|
+
* Create a sound, given an audio file path
|
|
8
|
+
*/
|
|
9
|
+
R2D_Sound *R2D_CreateSound(const char *path) {
|
|
10
|
+
R2D_Init();
|
|
11
|
+
|
|
12
|
+
// Check if sound file exists
|
|
13
|
+
if (!R2D_FileExists(path)) {
|
|
14
|
+
R2D_Error("R2D_CreateSound", "Sound file `%s` not found", path);
|
|
15
|
+
return NULL;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Allocate the sound structure
|
|
19
|
+
R2D_Sound *snd = (R2D_Sound *) malloc(sizeof(R2D_Sound));
|
|
20
|
+
if (!snd) {
|
|
21
|
+
R2D_Error("R2D_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
|
+
R2D_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 R2D_PlaySound(R2D_Sound *snd) {
|
|
44
|
+
if (!snd) return;
|
|
45
|
+
Mix_PlayChannel(-1, snd->data, 0);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
/*
|
|
50
|
+
* Get the sound's length in seconds
|
|
51
|
+
*/
|
|
52
|
+
int R2D_GetSoundLength(R2D_Sound *snd) {
|
|
53
|
+
float points = 0;
|
|
54
|
+
float frames = 0;
|
|
55
|
+
int frequency = 0;
|
|
56
|
+
Uint16 format = 0;
|
|
57
|
+
int channels = 0;
|
|
58
|
+
|
|
59
|
+
// Populate the frequency, format and channel variables
|
|
60
|
+
if (!Mix_QuerySpec(&frequency, &format, &channels)) return -1; // Querying audio details failed
|
|
61
|
+
if (!snd) return -1;
|
|
62
|
+
|
|
63
|
+
// points = bytes / samplesize
|
|
64
|
+
points = (snd->data->alen / ((format & 0xFF) / 8));
|
|
65
|
+
|
|
66
|
+
// frames = sample points / channels
|
|
67
|
+
frames = (points / channels);
|
|
68
|
+
|
|
69
|
+
// frames / frequency is seconds of audio
|
|
70
|
+
return ceil(frames / frequency);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
/*
|
|
75
|
+
* Get the sound's volume
|
|
76
|
+
*/
|
|
77
|
+
int R2D_GetSoundVolume(R2D_Sound *snd) {
|
|
78
|
+
if (!snd) return -1;
|
|
79
|
+
return ceil(Mix_VolumeChunk(snd->data, -1) * (100.0 / MIX_MAX_VOLUME));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
/*
|
|
84
|
+
* Set the sound's volume a given percentage
|
|
85
|
+
*/
|
|
86
|
+
void R2D_SetSoundVolume(R2D_Sound *snd, int volume) {
|
|
87
|
+
if (!snd) return;
|
|
88
|
+
// Set volume to be a percentage of the maximum mix volume
|
|
89
|
+
Mix_VolumeChunk(snd->data, (volume / 100.0) * MIX_MAX_VOLUME);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
/*
|
|
94
|
+
* Get the sound mixer volume
|
|
95
|
+
*/
|
|
96
|
+
int R2D_GetSoundMixVolume() {
|
|
97
|
+
return ceil(Mix_Volume(-1, -1) * (100.0 / MIX_MAX_VOLUME));
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
/*
|
|
102
|
+
* Set the sound mixer volume a given percentage
|
|
103
|
+
*/
|
|
104
|
+
void R2D_SetSoundMixVolume(int volume) {
|
|
105
|
+
// This sets the volume value across all channels
|
|
106
|
+
// Set volume to be a percentage of the maximum mix volume
|
|
107
|
+
Mix_Volume(-1, (volume / 100.0) * MIX_MAX_VOLUME);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
/*
|
|
112
|
+
* Free the sound
|
|
113
|
+
*/
|
|
114
|
+
void R2D_FreeSound(R2D_Sound *snd) {
|
|
115
|
+
if (!snd) return;
|
|
116
|
+
Mix_FreeChunk(snd->data);
|
|
117
|
+
free(snd);
|
|
118
|
+
}
|
data/ext/ruby2d/text.c
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// text.c
|
|
2
|
+
|
|
3
|
+
#include "ruby2d.h"
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
/*
|
|
7
|
+
* Create a SDL_Surface that contains the pixel data to render text, given a font and message
|
|
8
|
+
*/
|
|
9
|
+
SDL_Surface *R2D_TextCreateSurface(TTF_Font *font, const char *message) {
|
|
10
|
+
// `msg` cannot be an empty string or NULL for TTF_SizeText
|
|
11
|
+
if (message == NULL || strlen(message) == 0) message = " ";
|
|
12
|
+
|
|
13
|
+
SDL_Color color = {255, 255, 255};
|
|
14
|
+
SDL_Surface *surface = TTF_RenderUTF8_Blended(font, message, color);
|
|
15
|
+
if (!surface)
|
|
16
|
+
{
|
|
17
|
+
R2D_Error("TTF_RenderUTF8_Blended", TTF_GetError());
|
|
18
|
+
return NULL;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return surface;
|
|
22
|
+
}
|
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
// window.c
|
|
2
2
|
|
|
3
|
-
#include "
|
|
3
|
+
#include "ruby2d.h"
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
/*
|
|
7
7
|
* Create a window
|
|
8
8
|
*/
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
R2D_Window *R2D_CreateWindow(const char *title, int width, int height,
|
|
10
|
+
R2D_Update update, R2D_Render render, int flags) {
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
R2D_Init();
|
|
13
13
|
|
|
14
14
|
SDL_DisplayMode dm;
|
|
15
15
|
SDL_GetCurrentDisplayMode(0, &dm);
|
|
16
|
-
|
|
16
|
+
R2D_Log(R2D_INFO, "Current display mode is %dx%dpx @ %dhz", dm.w, dm.h, dm.refresh_rate);
|
|
17
17
|
|
|
18
|
-
width = width ==
|
|
19
|
-
height = height ==
|
|
18
|
+
width = width == R2D_DISPLAY_WIDTH ? dm.w : width;
|
|
19
|
+
height = height == R2D_DISPLAY_HEIGHT ? dm.h : height;
|
|
20
20
|
|
|
21
21
|
// Allocate window and set default values
|
|
22
|
-
|
|
22
|
+
R2D_Window *window = (R2D_Window *) malloc(sizeof(R2D_Window));
|
|
23
23
|
window->sdl = NULL;
|
|
24
24
|
window->glcontext = NULL;
|
|
25
25
|
window->title = title;
|
|
@@ -29,7 +29,7 @@ S2D_Window *S2D_CreateWindow(const char *title, int width, int height,
|
|
|
29
29
|
window->orig_height = height;
|
|
30
30
|
window->viewport.width = width;
|
|
31
31
|
window->viewport.height = height;
|
|
32
|
-
window->viewport.mode =
|
|
32
|
+
window->viewport.mode = R2D_SCALE;
|
|
33
33
|
window->update = update;
|
|
34
34
|
window->render = render;
|
|
35
35
|
window->flags = flags;
|
|
@@ -53,10 +53,10 @@ S2D_Window *S2D_CreateWindow(const char *title, int width, int height,
|
|
|
53
53
|
/*
|
|
54
54
|
* Show the window
|
|
55
55
|
*/
|
|
56
|
-
int
|
|
56
|
+
int R2D_Show(R2D_Window *window) {
|
|
57
57
|
|
|
58
58
|
if (!window) {
|
|
59
|
-
|
|
59
|
+
R2D_Error("R2D_Show", "Window cannot be shown (because it's NULL)");
|
|
60
60
|
return 1;
|
|
61
61
|
}
|
|
62
62
|
|
|
@@ -68,8 +68,8 @@ int S2D_Show(S2D_Window *window) {
|
|
|
68
68
|
SDL_WINDOW_OPENGL | window->flags // flags
|
|
69
69
|
);
|
|
70
70
|
|
|
71
|
-
if (!window->sdl)
|
|
72
|
-
if (window->icon)
|
|
71
|
+
if (!window->sdl) R2D_Error("SDL_CreateWindow", SDL_GetError());
|
|
72
|
+
if (window->icon) R2D_SetIcon(window, window->icon);
|
|
73
73
|
|
|
74
74
|
// The window created by SDL might not actually be the requested size.
|
|
75
75
|
// If it's not the same, retrieve and store the actual window size.
|
|
@@ -77,7 +77,7 @@ int S2D_Show(S2D_Window *window) {
|
|
|
77
77
|
SDL_GetWindowSize(window->sdl, &actual_width, &actual_height);
|
|
78
78
|
|
|
79
79
|
if ((window->width != actual_width) || (window->height != actual_height)) {
|
|
80
|
-
|
|
80
|
+
R2D_Log(R2D_INFO,
|
|
81
81
|
"Scaling window to %ix%i (requested size was %ix%i)",
|
|
82
82
|
actual_width, actual_height, window->width, window->height
|
|
83
83
|
);
|
|
@@ -89,7 +89,13 @@ int S2D_Show(S2D_Window *window) {
|
|
|
89
89
|
|
|
90
90
|
// Set Up OpenGL /////////////////////////////////////////////////////////////
|
|
91
91
|
|
|
92
|
-
|
|
92
|
+
R2D_GL_Init(window);
|
|
93
|
+
|
|
94
|
+
// SDL 2.0.10 and macOS 10.15 fix ////////////////////////////////////////////
|
|
95
|
+
|
|
96
|
+
#if MACOS
|
|
97
|
+
SDL_SetWindowSize(window->sdl, window->width, window->height);
|
|
98
|
+
#endif
|
|
93
99
|
|
|
94
100
|
// Set Main Loop Data ////////////////////////////////////////////////////////
|
|
95
101
|
|
|
@@ -110,7 +116,7 @@ int S2D_Show(S2D_Window *window) {
|
|
|
110
116
|
// Enable VSync
|
|
111
117
|
if (window->vsync) {
|
|
112
118
|
if (!SDL_SetHint(SDL_HINT_RENDER_VSYNC, "1")) {
|
|
113
|
-
|
|
119
|
+
R2D_Log(R2D_WARN, "VSync cannot be enabled");
|
|
114
120
|
}
|
|
115
121
|
}
|
|
116
122
|
|
|
@@ -122,7 +128,7 @@ int S2D_Show(S2D_Window *window) {
|
|
|
122
128
|
|
|
123
129
|
// Clear Frame /////////////////////////////////////////////////////////////
|
|
124
130
|
|
|
125
|
-
|
|
131
|
+
R2D_GL_Clear(window->background);
|
|
126
132
|
|
|
127
133
|
// Set FPS /////////////////////////////////////////////////////////////////
|
|
128
134
|
|
|
@@ -158,8 +164,8 @@ int S2D_Show(S2D_Window *window) {
|
|
|
158
164
|
|
|
159
165
|
case SDL_KEYDOWN:
|
|
160
166
|
if (window->on_key && e.key.repeat == 0) {
|
|
161
|
-
|
|
162
|
-
.type =
|
|
167
|
+
R2D_Event event = {
|
|
168
|
+
.type = R2D_KEY_DOWN, .key = SDL_GetScancodeName(e.key.keysym.scancode)
|
|
163
169
|
};
|
|
164
170
|
window->on_key(event);
|
|
165
171
|
}
|
|
@@ -167,8 +173,8 @@ int S2D_Show(S2D_Window *window) {
|
|
|
167
173
|
|
|
168
174
|
case SDL_KEYUP:
|
|
169
175
|
if (window->on_key) {
|
|
170
|
-
|
|
171
|
-
.type =
|
|
176
|
+
R2D_Event event = {
|
|
177
|
+
.type = R2D_KEY_UP, .key = SDL_GetScancodeName(e.key.keysym.scancode)
|
|
172
178
|
};
|
|
173
179
|
window->on_key(event);
|
|
174
180
|
}
|
|
@@ -176,11 +182,11 @@ int S2D_Show(S2D_Window *window) {
|
|
|
176
182
|
|
|
177
183
|
case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP:
|
|
178
184
|
if (window->on_mouse) {
|
|
179
|
-
|
|
180
|
-
|
|
185
|
+
R2D_GetMouseOnViewport(window, e.button.x, e.button.y, &mx, &my);
|
|
186
|
+
R2D_Event event = {
|
|
181
187
|
.button = e.button.button, .x = mx, .y = my
|
|
182
188
|
};
|
|
183
|
-
event.type = e.type == SDL_MOUSEBUTTONDOWN ?
|
|
189
|
+
event.type = e.type == SDL_MOUSEBUTTONDOWN ? R2D_MOUSE_DOWN : R2D_MOUSE_UP;
|
|
184
190
|
event.dblclick = e.button.clicks == 2 ? true : false;
|
|
185
191
|
window->on_mouse(event);
|
|
186
192
|
}
|
|
@@ -188,8 +194,8 @@ int S2D_Show(S2D_Window *window) {
|
|
|
188
194
|
|
|
189
195
|
case SDL_MOUSEWHEEL:
|
|
190
196
|
if (window->on_mouse) {
|
|
191
|
-
|
|
192
|
-
.type =
|
|
197
|
+
R2D_Event event = {
|
|
198
|
+
.type = R2D_MOUSE_SCROLL, .direction = e.wheel.direction,
|
|
193
199
|
.delta_x = e.wheel.x, .delta_y = -e.wheel.y
|
|
194
200
|
};
|
|
195
201
|
window->on_mouse(event);
|
|
@@ -198,9 +204,9 @@ int S2D_Show(S2D_Window *window) {
|
|
|
198
204
|
|
|
199
205
|
case SDL_MOUSEMOTION:
|
|
200
206
|
if (window->on_mouse) {
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
.type =
|
|
207
|
+
R2D_GetMouseOnViewport(window, e.motion.x, e.motion.y, &mx, &my);
|
|
208
|
+
R2D_Event event = {
|
|
209
|
+
.type = R2D_MOUSE_MOVE,
|
|
204
210
|
.x = mx, .y = my, .delta_x = e.motion.xrel, .delta_y = e.motion.yrel
|
|
205
211
|
};
|
|
206
212
|
window->on_mouse(event);
|
|
@@ -209,8 +215,8 @@ int S2D_Show(S2D_Window *window) {
|
|
|
209
215
|
|
|
210
216
|
case SDL_CONTROLLERAXISMOTION:
|
|
211
217
|
if (window->on_controller) {
|
|
212
|
-
|
|
213
|
-
.which = e.caxis.which, .type =
|
|
218
|
+
R2D_Event event = {
|
|
219
|
+
.which = e.caxis.which, .type = R2D_AXIS,
|
|
214
220
|
.axis = e.caxis.axis, .value = e.caxis.value
|
|
215
221
|
};
|
|
216
222
|
window->on_controller(event);
|
|
@@ -218,9 +224,9 @@ int S2D_Show(S2D_Window *window) {
|
|
|
218
224
|
break;
|
|
219
225
|
|
|
220
226
|
case SDL_JOYAXISMOTION:
|
|
221
|
-
if (window->on_controller && !
|
|
222
|
-
|
|
223
|
-
.which = e.jaxis.which, .type =
|
|
227
|
+
if (window->on_controller && !R2D_IsController(e.jbutton.which)) {
|
|
228
|
+
R2D_Event event = {
|
|
229
|
+
.which = e.jaxis.which, .type = R2D_AXIS,
|
|
224
230
|
.axis = e.jaxis.axis, .value = e.jaxis.value
|
|
225
231
|
};
|
|
226
232
|
window->on_controller(event);
|
|
@@ -229,35 +235,35 @@ int S2D_Show(S2D_Window *window) {
|
|
|
229
235
|
|
|
230
236
|
case SDL_CONTROLLERBUTTONDOWN: case SDL_CONTROLLERBUTTONUP:
|
|
231
237
|
if (window->on_controller) {
|
|
232
|
-
|
|
238
|
+
R2D_Event event = {
|
|
233
239
|
.which = e.cbutton.which, .button = e.cbutton.button
|
|
234
240
|
};
|
|
235
|
-
event.type = e.type == SDL_CONTROLLERBUTTONDOWN ?
|
|
241
|
+
event.type = e.type == SDL_CONTROLLERBUTTONDOWN ? R2D_BUTTON_DOWN : R2D_BUTTON_UP;
|
|
236
242
|
window->on_controller(event);
|
|
237
243
|
}
|
|
238
244
|
break;
|
|
239
245
|
|
|
240
246
|
case SDL_JOYBUTTONDOWN: case SDL_JOYBUTTONUP:
|
|
241
|
-
if (window->on_controller && !
|
|
242
|
-
|
|
247
|
+
if (window->on_controller && !R2D_IsController(e.jbutton.which)) {
|
|
248
|
+
R2D_Event event = {
|
|
243
249
|
.which = e.jbutton.which, .button = e.jbutton.button
|
|
244
250
|
};
|
|
245
|
-
event.type = e.type == SDL_JOYBUTTONDOWN ?
|
|
251
|
+
event.type = e.type == SDL_JOYBUTTONDOWN ? R2D_BUTTON_DOWN : R2D_BUTTON_UP;
|
|
246
252
|
window->on_controller(event);
|
|
247
253
|
}
|
|
248
254
|
break;
|
|
249
255
|
|
|
250
256
|
case SDL_JOYDEVICEADDED:
|
|
251
|
-
|
|
252
|
-
|
|
257
|
+
R2D_Log(R2D_INFO, "Controller connected (%i total)", SDL_NumJoysticks());
|
|
258
|
+
R2D_OpenControllers();
|
|
253
259
|
break;
|
|
254
260
|
|
|
255
261
|
case SDL_JOYDEVICEREMOVED:
|
|
256
|
-
if (
|
|
257
|
-
|
|
262
|
+
if (R2D_IsController(e.jdevice.which)) {
|
|
263
|
+
R2D_Log(R2D_INFO, "Controller #%i: %s removed (%i remaining)", e.jdevice.which, SDL_GameControllerName(SDL_GameControllerFromInstanceID(e.jdevice.which)), SDL_NumJoysticks());
|
|
258
264
|
SDL_GameControllerClose(SDL_GameControllerFromInstanceID(e.jdevice.which));
|
|
259
265
|
} else {
|
|
260
|
-
|
|
266
|
+
R2D_Log(R2D_INFO, "Controller #%i: %s removed (%i remaining)", e.jdevice.which, SDL_JoystickName(SDL_JoystickFromInstanceID(e.jdevice.which)), SDL_NumJoysticks());
|
|
261
267
|
SDL_JoystickClose(SDL_JoystickFromInstanceID(e.jdevice.which));
|
|
262
268
|
}
|
|
263
269
|
break;
|
|
@@ -268,13 +274,13 @@ int S2D_Show(S2D_Window *window) {
|
|
|
268
274
|
// Store new window size, set viewport
|
|
269
275
|
window->width = e.window.data1;
|
|
270
276
|
window->height = e.window.data2;
|
|
271
|
-
|
|
277
|
+
R2D_GL_SetViewport(window);
|
|
272
278
|
break;
|
|
273
279
|
}
|
|
274
280
|
break;
|
|
275
281
|
|
|
276
282
|
case SDL_QUIT:
|
|
277
|
-
|
|
283
|
+
R2D_Close(window);
|
|
278
284
|
break;
|
|
279
285
|
}
|
|
280
286
|
}
|
|
@@ -286,8 +292,8 @@ int S2D_Show(S2D_Window *window) {
|
|
|
286
292
|
for (int i = 0; i < num_keys; i++) {
|
|
287
293
|
if (window->on_key) {
|
|
288
294
|
if (key_state[i] == 1) {
|
|
289
|
-
|
|
290
|
-
.type =
|
|
295
|
+
R2D_Event event = {
|
|
296
|
+
.type = R2D_KEY_HELD, .key = SDL_GetScancodeName(i)
|
|
291
297
|
};
|
|
292
298
|
window->on_key(event);
|
|
293
299
|
}
|
|
@@ -297,7 +303,7 @@ int S2D_Show(S2D_Window *window) {
|
|
|
297
303
|
// Get and store mouse position relative to the viewport
|
|
298
304
|
int wx, wy; // mouse x, y coordinates relative to the window
|
|
299
305
|
SDL_GetMouseState(&wx, &wy);
|
|
300
|
-
|
|
306
|
+
R2D_GetMouseOnViewport(window, wx, wy, &window->mouse.x, &window->mouse.y);
|
|
301
307
|
|
|
302
308
|
// Update Window State /////////////////////////////////////////////////////
|
|
303
309
|
|
|
@@ -313,6 +319,11 @@ int S2D_Show(S2D_Window *window) {
|
|
|
313
319
|
if (window->render) window->render();
|
|
314
320
|
|
|
315
321
|
// Draw Frame //////////////////////////////////////////////////////////////
|
|
322
|
+
|
|
323
|
+
// Render and flush all OpenGL buffers
|
|
324
|
+
R2D_GL_FlushBuffers();
|
|
325
|
+
|
|
326
|
+
// Swap buffers to display drawn contents in the window
|
|
316
327
|
SDL_GL_SwapWindow(window->sdl);
|
|
317
328
|
}
|
|
318
329
|
|
|
@@ -323,14 +334,14 @@ int S2D_Show(S2D_Window *window) {
|
|
|
323
334
|
/*
|
|
324
335
|
* Set the icon for the window
|
|
325
336
|
*/
|
|
326
|
-
void
|
|
327
|
-
|
|
328
|
-
if (
|
|
337
|
+
void R2D_SetIcon(R2D_Window *window, const char *icon) {
|
|
338
|
+
SDL_Surface *iconSurface = R2D_CreateImageSurface(icon);
|
|
339
|
+
if (iconSurface) {
|
|
329
340
|
window->icon = icon;
|
|
330
|
-
SDL_SetWindowIcon(window->sdl,
|
|
331
|
-
|
|
341
|
+
SDL_SetWindowIcon(window->sdl, iconSurface);
|
|
342
|
+
SDL_FreeSurface(iconSurface);
|
|
332
343
|
} else {
|
|
333
|
-
|
|
344
|
+
R2D_Log(R2D_WARN, "Could not set window icon");
|
|
334
345
|
}
|
|
335
346
|
}
|
|
336
347
|
|
|
@@ -338,10 +349,10 @@ void S2D_SetIcon(S2D_Window *window, const char *icon) {
|
|
|
338
349
|
/*
|
|
339
350
|
* Take a screenshot of the window
|
|
340
351
|
*/
|
|
341
|
-
void
|
|
352
|
+
void R2D_Screenshot(R2D_Window *window, const char *path) {
|
|
342
353
|
|
|
343
354
|
#if GLES
|
|
344
|
-
|
|
355
|
+
R2D_Error("R2D_Screenshot", "Not supported in OpenGL ES");
|
|
345
356
|
#else
|
|
346
357
|
// Create a surface the size of the window
|
|
347
358
|
SDL_Surface *surface = SDL_CreateRGBSurface(
|
|
@@ -357,7 +368,7 @@ void S2D_Screenshot(S2D_Window *window, const char *path) {
|
|
|
357
368
|
|
|
358
369
|
void *temp_row = (void *)malloc(surface->pitch);
|
|
359
370
|
if (!temp_row) {
|
|
360
|
-
|
|
371
|
+
R2D_Error("R2D_Screenshot", "Out of memory!");
|
|
361
372
|
SDL_FreeSurface(surface);
|
|
362
373
|
return;
|
|
363
374
|
}
|
|
@@ -382,9 +393,9 @@ void S2D_Screenshot(S2D_Window *window, const char *path) {
|
|
|
382
393
|
/*
|
|
383
394
|
* Close the window
|
|
384
395
|
*/
|
|
385
|
-
int
|
|
396
|
+
int R2D_Close(R2D_Window *window) {
|
|
386
397
|
if (!window->close) {
|
|
387
|
-
|
|
398
|
+
R2D_Log(R2D_INFO, "Closing window");
|
|
388
399
|
window->close = true;
|
|
389
400
|
}
|
|
390
401
|
return 0;
|
|
@@ -394,8 +405,8 @@ int S2D_Close(S2D_Window *window) {
|
|
|
394
405
|
/*
|
|
395
406
|
* Free all resources
|
|
396
407
|
*/
|
|
397
|
-
int
|
|
398
|
-
|
|
408
|
+
int R2D_FreeWindow(R2D_Window *window) {
|
|
409
|
+
R2D_Close(window);
|
|
399
410
|
SDL_GL_DeleteContext(window->glcontext);
|
|
400
411
|
SDL_DestroyWindow(window->sdl);
|
|
401
412
|
free(window);
|