rgss 0.0.1

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.
Files changed (64) hide show
  1. checksums.yaml +7 -0
  2. data/.clang-format +6 -0
  3. data/.gitignore +167 -0
  4. data/.yardopts +6 -0
  5. data/CHANGELOG.md +4 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.txt +21 -0
  8. data/Rakefile +9 -0
  9. data/ext/rgss/cglm-v0.7.9.tar.gz +0 -0
  10. data/ext/rgss/color.c +599 -0
  11. data/ext/rgss/entity.c +373 -0
  12. data/ext/rgss/extconf.rb +53 -0
  13. data/ext/rgss/font.c +135 -0
  14. data/ext/rgss/game.c +469 -0
  15. data/ext/rgss/game.h +99 -0
  16. data/ext/rgss/gl.c +3217 -0
  17. data/ext/rgss/glad.c +1140 -0
  18. data/ext/rgss/glad.h +2129 -0
  19. data/ext/rgss/glfw.c +1453 -0
  20. data/ext/rgss/graphics.c +324 -0
  21. data/ext/rgss/image.c +274 -0
  22. data/ext/rgss/input.c +745 -0
  23. data/ext/rgss/khrplatform.h +290 -0
  24. data/ext/rgss/mat4.c +279 -0
  25. data/ext/rgss/pax_global_header +1 -0
  26. data/ext/rgss/point.c +253 -0
  27. data/ext/rgss/rect.c +449 -0
  28. data/ext/rgss/rgss.c +56 -0
  29. data/ext/rgss/rgss.h +241 -0
  30. data/ext/rgss/stb_image.h +7762 -0
  31. data/ext/rgss/stb_image_write.h +1690 -0
  32. data/ext/rgss/stb_rect_pack.h +628 -0
  33. data/ext/rgss/stb_truetype.h +5011 -0
  34. data/ext/rgss/utf8.h +1652 -0
  35. data/ext/rgss/uthash.h +1133 -0
  36. data/ext/rgss/vec.c +114 -0
  37. data/ext/rgss/vec.h +192 -0
  38. data/ext/rgss/vec2.c +489 -0
  39. data/ext/rgss/vec3.c +751 -0
  40. data/ext/rgss/vec4.c +681 -0
  41. data/lib/rgss.rb +140 -0
  42. data/lib/rgss/batch.rb +57 -0
  43. data/lib/rgss/blend.rb +47 -0
  44. data/lib/rgss/game_object.rb +28 -0
  45. data/lib/rgss/plane.rb +95 -0
  46. data/lib/rgss/renderable.rb +158 -0
  47. data/lib/rgss/rgss.so +0 -0
  48. data/lib/rgss/shader.rb +94 -0
  49. data/lib/rgss/shaders/sprite-frag.glsl +40 -0
  50. data/lib/rgss/shaders/sprite-vert.glsl +17 -0
  51. data/lib/rgss/sprite.rb +139 -0
  52. data/lib/rgss/stubs/color.rb +318 -0
  53. data/lib/rgss/stubs/gl.rb +1999 -0
  54. data/lib/rgss/stubs/glfw.rb +626 -0
  55. data/lib/rgss/stubs/rect.rb +324 -0
  56. data/lib/rgss/stubs/rpg.rb +267 -0
  57. data/lib/rgss/stubs/tone.rb +65 -0
  58. data/lib/rgss/texture.rb +132 -0
  59. data/lib/rgss/tilemap.rb +116 -0
  60. data/lib/rgss/version.rb +3 -0
  61. data/lib/rgss/viewport.rb +67 -0
  62. data/rgss.gemspec +44 -0
  63. data/test.png +0 -0
  64. metadata +178 -0
@@ -0,0 +1,373 @@
1
+ #include "game.h"
2
+
3
+ VALUE rb_cEntity;
4
+
5
+ vec3 AXIS_Z = { 0.0f, 0.0f, 1.0f };
6
+
7
+ typedef struct {
8
+ vec4 *model;
9
+ vec3 position;
10
+ vec3 velocity;
11
+ vec3 scale;
12
+ vec3 pivot;
13
+ float angle;
14
+ int depth;
15
+ vec3 size;
16
+ } RGSS_Entity;
17
+
18
+ // TODO: Use direct pointer with RUBY_NEVER_FREE instead of new vector?
19
+
20
+ static inline void RGSS_Entity_ParseArg(VALUE value, vec3 result)
21
+ {
22
+ if (!RTEST(value))
23
+ {
24
+ glm_vec3_zero(result);
25
+ return;
26
+ }
27
+
28
+ result[2] = 0.0f;
29
+ if (rb_obj_is_kind_of(value, rb_cPoint) == Qtrue || rb_obj_is_kind_of(value, rb_cSize) == Qtrue)
30
+ {
31
+ int *ivec = DATA_PTR(value);
32
+ result[0] = (float) ivec[0];
33
+ result[1] = (float) ivec[1];
34
+ }
35
+ else if (rb_obj_is_kind_of(value, rb_cVec2))
36
+ {
37
+ float *vec = DATA_PTR(value);
38
+ result[0] = vec[0];
39
+ result[1] = vec[1];
40
+ }
41
+ else if (rb_obj_is_kind_of(value, rb_cVec3))
42
+ {
43
+ glm_vec3_copy(DATA_PTR(value), result);
44
+ }
45
+ else
46
+ {
47
+ rb_raise(rb_eTypeError, "%s is not a Point, Size, Vec2, or Vec3", CLASS_NAME(value));
48
+ }
49
+ }
50
+
51
+ static void RGSS_Entity_Free(void *data)
52
+ {
53
+ if (data)
54
+ {
55
+ RGSS_Entity *entity = data;
56
+ if (entity->model)
57
+ {
58
+ free(entity->model);
59
+ entity->model = NULL;
60
+ }
61
+ xfree(data);
62
+ }
63
+ }
64
+
65
+ static VALUE RGSS_Entity_Alloc(VALUE klass)
66
+ {
67
+ RGSS_Entity *entity = ALLOC(RGSS_Entity);
68
+ entity->model = RGSS_MAT4_NEW;
69
+ glm_mat4_identity(entity->model);
70
+
71
+ glm_vec3_zero(entity->position);
72
+ glm_vec3_zero(entity->velocity);
73
+ glm_vec3_zero(entity->size);
74
+ glm_vec3_one(entity->scale);
75
+ glm_vec3_zero(entity->pivot);
76
+ entity->angle = 0.0f;
77
+ entity->depth = 0;
78
+
79
+ return Data_Wrap_Struct(klass, NULL, RGSS_Entity_Free, entity);
80
+ }
81
+
82
+ static VALUE RGSS_Entity_GetX(VALUE self)
83
+ {
84
+ RGSS_Entity *entity = DATA_PTR(self);
85
+ return INT2NUM((int) roundf(entity->position[0]));
86
+ }
87
+
88
+ static VALUE RGSS_Entity_SetX(VALUE self, VALUE value)
89
+ {
90
+ RGSS_Entity *entity = DATA_PTR(self);
91
+ entity->position[0] = NUM2FLT(value);
92
+ return self;
93
+ }
94
+
95
+ static VALUE RGSS_Entity_GetY(VALUE self)
96
+ {
97
+ RGSS_Entity *entity = DATA_PTR(self);
98
+ return INT2NUM((int) roundf(entity->position[1]));
99
+ }
100
+
101
+ static VALUE RGSS_Entity_SetY(VALUE self, VALUE value)
102
+ {
103
+ RGSS_Entity *entity = DATA_PTR(self);
104
+ entity->position[1] = NUM2FLT(value);
105
+ return self;
106
+ }
107
+
108
+ static VALUE RGSS_Entity_GetZ(VALUE self)
109
+ {
110
+ RGSS_Entity *entity = DATA_PTR(self);
111
+ return INT2NUM(entity->depth);
112
+ }
113
+
114
+ static VALUE RGSS_Entity_SetZ(VALUE self, VALUE value)
115
+ {
116
+ RGSS_Entity *entity = DATA_PTR(self);
117
+ entity->depth = NUM2INT(value);
118
+ return self;
119
+ }
120
+
121
+ static VALUE RGSS_Entity_GetLocation(VALUE self)
122
+ {
123
+ RGSS_Entity *entity = DATA_PTR(self);
124
+ return RGSS_Point_New((int) roundf(entity->position[0]), (int) roundf(entity->position[1]));
125
+ }
126
+
127
+ static VALUE RGSS_Entity_SetLocation(VALUE self, VALUE point)
128
+ {
129
+ RGSS_Entity *entity = DATA_PTR(self);
130
+ int *ivec = DATA_PTR(point);
131
+ entity->position[0] = (float) ivec[0];
132
+ entity->position[1] = (float) ivec[1];
133
+ return point;
134
+ }
135
+
136
+ static VALUE RGSS_Entity_Update(VALUE self, VALUE delta)
137
+ {
138
+ RGSS_Entity *entity = DATA_PTR(self);
139
+
140
+ vec3 scale;
141
+ glm_vec3_mul(entity->scale, entity->size, scale);
142
+
143
+ vec3 velocity;
144
+ glm_vec3_scale(entity->velocity, NUM2FLT(delta), velocity);
145
+
146
+ glm_vec3_add(entity->position, velocity, entity->position);
147
+
148
+
149
+ vec3 pivot;
150
+ glm_vec3_add(entity->pivot, entity->position, pivot);
151
+
152
+ glm_rotate_atm(entity->model, pivot, entity->angle, AXIS_Z);
153
+ glm_translate(entity->model, entity->position);
154
+ glm_scale(entity->model, scale);
155
+
156
+ return self;
157
+ }
158
+
159
+ static VALUE RGSS_Entity_GetModel(VALUE self)
160
+ {
161
+ RGSS_Entity *entity = DATA_PTR(self);
162
+ return Data_Wrap_Struct(rb_cMat4, NULL, RUBY_NEVER_FREE, entity->model);
163
+ }
164
+
165
+ static VALUE RGSS_Entity_SetModel(VALUE self, VALUE model)
166
+ {
167
+ RGSS_Entity *entity = DATA_PTR(self);
168
+ if (RTEST(model))
169
+ {
170
+ vec4 *mat = DATA_PTR(model);
171
+ glm_mat4_copy(mat, entity->model);
172
+ }
173
+ else
174
+ {
175
+ glm_mat4_identity(entity->model);
176
+ }
177
+ return model;
178
+ }
179
+
180
+ static VALUE RGSS_Entity_GetPosition(VALUE self)
181
+ {
182
+ RGSS_Entity *entity = DATA_PTR(self);
183
+ return RGSS_Vec2_New(entity->position[0], entity->position[1]);
184
+ }
185
+
186
+ static VALUE RGSS_Entity_SetPosition(VALUE self, VALUE value)
187
+ {
188
+ RGSS_Entity *entity = DATA_PTR(self);
189
+
190
+ vec3 vec;
191
+ RGSS_Entity_ParseArg(value, vec);
192
+
193
+ glm_vec3_copy(vec, entity->position);
194
+ return value;
195
+ }
196
+
197
+ static VALUE RGSS_Entity_GetVelocity(VALUE self)
198
+ {
199
+ RGSS_Entity *entity = DATA_PTR(self);
200
+ return RGSS_Vec2_New(entity->velocity[0], entity->velocity[1]);
201
+ }
202
+
203
+ static VALUE RGSS_Entity_SetVelocity(VALUE self, VALUE value)
204
+ {
205
+ RGSS_Entity *entity = DATA_PTR(self);
206
+
207
+ vec3 vec;
208
+ RGSS_Entity_ParseArg(value, vec);
209
+
210
+ glm_vec3_copy(vec, entity->velocity);
211
+ return value;
212
+ }
213
+
214
+ static VALUE RGSS_Entity_GetScale(VALUE self)
215
+ {
216
+ RGSS_Entity *entity = DATA_PTR(self);
217
+ return RGSS_Vec2_New(entity->scale[0], entity->scale[1]);
218
+ }
219
+
220
+ static VALUE RGSS_Entity_SetScale(VALUE self, VALUE value)
221
+ {
222
+ RGSS_Entity *entity = DATA_PTR(self);
223
+
224
+ vec3 vec;
225
+ RGSS_Entity_ParseArg(value, vec);
226
+
227
+ glm_vec3_copy(vec, entity->scale);
228
+ return value;
229
+ }
230
+
231
+ static VALUE RGSS_Entity_GetPivot(VALUE self)
232
+ {
233
+ RGSS_Entity *entity = DATA_PTR(self);
234
+ return RGSS_Vec2_New(entity->pivot[0], entity->pivot[1]);
235
+ }
236
+
237
+ static VALUE RGSS_Entity_SetPivot(VALUE self, VALUE value)
238
+ {
239
+ RGSS_Entity *entity = DATA_PTR(self);
240
+
241
+ vec3 vec;
242
+ RGSS_Entity_ParseArg(value, vec);
243
+
244
+ glm_vec3_copy(vec, entity->pivot);
245
+ return value;
246
+ }
247
+
248
+ static VALUE RGSS_Entity_GetSize(VALUE self)
249
+ {
250
+ RGSS_Entity *entity = DATA_PTR(self);
251
+ return RGSS_Size_New((int) roundf(entity->size[0]), (int) roundf(entity->size[1]));
252
+ }
253
+
254
+ static VALUE RGSS_Entity_SetSize(VALUE self, VALUE value)
255
+ {
256
+ RGSS_Entity *entity = DATA_PTR(self);
257
+
258
+ vec3 vec;
259
+ RGSS_Entity_ParseArg(value, vec);
260
+
261
+ glm_vec3_copy(vec, entity->size);
262
+ return value;
263
+ }
264
+
265
+ static VALUE RGSS_Entity_GetAngle(VALUE self)
266
+ {
267
+ RGSS_Entity *entity = DATA_PTR(self);
268
+ return DBL2NUM(entity->angle * (180.0 / M_PI));
269
+ }
270
+
271
+ static VALUE RGSS_Entity_SetAngle(VALUE self, VALUE degrees)
272
+ {
273
+ RGSS_Entity *entity = DATA_PTR(self);
274
+ entity->angle = NUM2DBL(degrees) * (M_PI / 180.0);
275
+ return degrees;
276
+ }
277
+
278
+ static VALUE RGSS_Entity_GetBounds(VALUE self)
279
+ {
280
+ RGSS_Entity *entity = DATA_PTR(self);
281
+ int *rect = xmalloc(sizeof(int) * 4);
282
+
283
+ rect[0] = (int) roundf(entity->position[0]);
284
+ rect[1] = (int) roundf(entity->position[1]);
285
+ rect[2] = (int) roundf(entity->size[0]);
286
+ rect[3] = (int) roundf(entity->size[1]);
287
+
288
+ return Data_Wrap_Struct(rb_cRect, NULL, RUBY_DEFAULT_FREE, rect);
289
+ }
290
+
291
+ static VALUE RGSS_Entity_Rotate(VALUE self, VALUE degrees, VALUE pivot)
292
+ {
293
+ RGSS_Entity *entity = DATA_PTR(self);
294
+
295
+ vec3 value;
296
+ RGSS_Entity_ParseArg(pivot, value);
297
+
298
+ entity->angle = NUM2DBL(degrees) * (M_PI / 180.0);
299
+ glm_vec3_copy(value, entity->pivot);
300
+
301
+ return self;
302
+ }
303
+
304
+ static VALUE RGSS_Entity_GetWidth(VALUE self)
305
+ {
306
+ RGSS_Entity *entity = DATA_PTR(self);
307
+ return INT2NUM((int) roundf(entity->size[0]));
308
+ }
309
+
310
+ static VALUE RGSS_Entity_GetHeight(VALUE self)
311
+ {
312
+ RGSS_Entity *entity = DATA_PTR(self);
313
+ return INT2NUM((int) roundf(entity->size[1]));
314
+ }
315
+
316
+ static VALUE RGSS_Entity_SetWidth(VALUE self, VALUE value)
317
+ {
318
+ RGSS_Entity *entity = DATA_PTR(self);
319
+ entity->size[0] = NUM2FLT(value);
320
+ return value;
321
+ }
322
+
323
+ static VALUE RGSS_Entity_SetHeight(VALUE self, VALUE value)
324
+ {
325
+ RGSS_Entity *entity = DATA_PTR(self);
326
+ entity->size[1] = NUM2FLT(value);
327
+ return value;
328
+ }
329
+
330
+ void RGSS_Init_Entity(VALUE parent)
331
+ {
332
+ rb_cEntity = rb_define_class_under(parent, "Entity", rb_cObject);
333
+ rb_define_alloc_func(rb_cEntity, RGSS_Entity_Alloc);
334
+
335
+ rb_define_method1(rb_cEntity, "update", RGSS_Entity_Update, 1);
336
+
337
+ rb_define_method0(rb_cEntity, "model", RGSS_Entity_GetModel, 0);
338
+ rb_define_method1(rb_cEntity, "model=", RGSS_Entity_SetModel, 1);
339
+ rb_define_method0(rb_cEntity, "position", RGSS_Entity_GetPosition, 0);
340
+ rb_define_method1(rb_cEntity, "position=", RGSS_Entity_SetPosition, 1);
341
+ rb_define_method0(rb_cEntity, "velocity", RGSS_Entity_GetVelocity, 0);
342
+ rb_define_method1(rb_cEntity, "velocity=", RGSS_Entity_SetVelocity, 1);
343
+ rb_define_method0(rb_cEntity, "scale", RGSS_Entity_GetScale, 0);
344
+ rb_define_method1(rb_cEntity, "scale=", RGSS_Entity_SetScale, 1);
345
+ rb_define_method0(rb_cEntity, "pivot", RGSS_Entity_GetPivot, 0);
346
+ rb_define_method1(rb_cEntity, "pivot=", RGSS_Entity_SetPivot, 1);
347
+ rb_define_method0(rb_cEntity, "angle", RGSS_Entity_GetAngle, 0);
348
+ rb_define_method1(rb_cEntity, "angle=", RGSS_Entity_SetAngle, 1);
349
+
350
+ rb_define_method0(rb_cEntity, "bounds", RGSS_Entity_GetBounds, 0);
351
+ rb_define_method2(rb_cEntity, "rotate", RGSS_Entity_Rotate, 2);
352
+
353
+ rb_define_method0(rb_cEntity, "x", RGSS_Entity_GetX, 0);
354
+ rb_define_method1(rb_cEntity, "x=", RGSS_Entity_SetX, 1);
355
+ rb_define_method0(rb_cEntity, "y", RGSS_Entity_GetY, 0);
356
+ rb_define_method1(rb_cEntity, "y=", RGSS_Entity_SetY, 1);
357
+ rb_define_method0(rb_cEntity, "z", RGSS_Entity_GetZ, 0);
358
+ rb_define_method1(rb_cEntity, "z=", RGSS_Entity_SetZ, 1);
359
+ rb_define_method0(rb_cEntity, "location", RGSS_Entity_GetLocation, 0);
360
+ rb_define_method1(rb_cEntity, "location=", RGSS_Entity_SetLocation, 1);
361
+ rb_define_method0(rb_cEntity, "size", RGSS_Entity_GetSize, 0);
362
+ rb_define_method0(rb_cEntity, "width", RGSS_Entity_GetWidth, 0);
363
+ rb_define_method0(rb_cEntity, "height", RGSS_Entity_GetHeight, 0);
364
+
365
+ rb_define_protected_method1(rb_cEntity, "size=", RGSS_Entity_SetSize, 1);
366
+ rb_define_protected_method1(rb_cEntity, "width=", RGSS_Entity_SetWidth, 1);
367
+ rb_define_protected_method1(rb_cEntity, "height=", RGSS_Entity_SetHeight, 1);
368
+
369
+ rb_define_alias(rb_cEntity, "depth", "z");
370
+
371
+ // rb_define_method0(rb_cEntity, "model", RGSS_Entity_GetModel, 0);
372
+ // rb_define_method1(rb_cEntity, "model", RGSS_Entity_SetModel, 1);
373
+ }
@@ -0,0 +1,53 @@
1
+ require 'mkmf'
2
+
3
+ require "mkmf"
4
+ require 'fileutils'
5
+ require 'rubygems/package'
6
+ require 'zlib'
7
+
8
+ CGLM_VERSION = '0.7.9'
9
+ cglm_source_url = "https://github.com/recp/cglm/archive/v#{CGLM_VERSION}.tar.gz"
10
+ cglm_tar_gz = File.expand_path("cglm-v#{CGLM_VERSION}.tar.gz", __dir__)
11
+ cglm_dir = File.expand_path("cglm-#{CGLM_VERSION }", __dir__)
12
+
13
+ # fetch cglm unless it's already on the file system
14
+ unless File.exist?(cglm_dir)
15
+ require 'open-uri'
16
+ # save tarfile
17
+ open(cglm_tar_gz, 'wb') do |file|
18
+ file << URI.open(cglm_source_url, 'rb').read
19
+ end
20
+
21
+ # extract tarfile
22
+ FileUtils.rm_rf cglm_dir if File.directory?(cglm_dir)
23
+ FileUtils.mkdir_p cglm_dir
24
+ tar_extract = Gem::Package::TarReader.new(Zlib::GzipReader.open(cglm_tar_gz))
25
+ tar_extract.rewind # The extract has to be rewinded after every iteration
26
+ tar_extract.each do |entry|
27
+ full_path = File.expand_path(entry.full_name, __dir__)
28
+ if entry.directory?
29
+ FileUtils.mkdir_p full_path
30
+ else
31
+ FileUtils.mkdir_p File.dirname(full_path)
32
+ File.open(full_path, 'wb') { |file| file << entry.read }
33
+ end
34
+ end
35
+ tar_extract.close
36
+ end
37
+
38
+ $INCFLAGS << " -I#{cglm_dir}/include"
39
+
40
+ require 'fiddle'
41
+ %w(
42
+ SIZEOF_VOIDP SIZEOF_CHAR SIZEOF_SHORT SIZEOF_INT SIZEOF_LONG SIZEOF_LONG_LONG
43
+ SIZEOF_FLOAT SIZEOF_DOUBLE SIZEOF_SIZE_T SIZEOF_SSIZE_T SIZEOF_PTRDIFF_T
44
+ SIZEOF_INTPTR_T SIZEOF_UINTPTR_T
45
+ ).each do |const_name|
46
+ if Fiddle.constants.include?(const_name.to_sym)
47
+ $CFLAGS << " -DHAVE_#{const_name}=1 -D#{const_name}=#{Fiddle.const_get(const_name.to_sym)}"
48
+ end
49
+ end
50
+
51
+ find_library('glfw', 'glfwInit')
52
+
53
+ create_makefile("rgss/rgss")
@@ -0,0 +1,135 @@
1
+ #if 1
2
+
3
+ #include "game.h"
4
+ #include "ruby/io.h"
5
+
6
+ #define STB_TRUETYPE_IMPLEMENTATION 1
7
+ #define STBTT_STATIC 1
8
+ #define STBTT_malloc(x, u) ((void)(u),xmalloc(x))
9
+ #define STBTT_free(x,u) ((void)(u),xfree(x))
10
+ #define STBTT_assert(x) RUBY_ASSERT(x)
11
+
12
+ #include "stb_rect_pack.h"
13
+ #include "stb_truetype.h"
14
+
15
+ VALUE rb_cTrueType;
16
+
17
+ typedef struct {
18
+ stbtt_fontinfo info;
19
+ unsigned char *buffer;
20
+ } RGSS_TrueType;
21
+
22
+ static void RGSS_TrueType_Free(void *data)
23
+ {
24
+ if (data == NULL)
25
+ return;
26
+
27
+ RGSS_TrueType *font = data;
28
+ if (font->buffer)
29
+ xfree(font->buffer);
30
+
31
+ xfree(font);
32
+ }
33
+
34
+ static VALUE RGSS_TrueType_Alloc(VALUE klass)
35
+ {
36
+ RGSS_TrueType *font = ALLOC(RGSS_TrueType);
37
+ memset(font, 0, sizeof(RGSS_TrueType));
38
+ return Data_Wrap_Struct(klass, NULL, RGSS_TrueType_Free, font);
39
+ }
40
+
41
+ static unsigned char* RGSS_TrueType_ReadFile(int fd)
42
+ {
43
+ if (fd == -1)
44
+ rb_raise(rb_eRuntimeError, "invalid file descriptor");
45
+
46
+ size_t len, result;
47
+
48
+ len = lseek(fd, 0, SEEK_END);
49
+ lseek(fd, 0, SEEK_SET);
50
+
51
+ void *buffer = xmalloc(len);
52
+ if (buffer == NULL)
53
+ rb_raise(rb_eNoMemError, "failed to allocate file read buffer");
54
+
55
+ result = read(fd, buffer, len);
56
+ if (result != len)
57
+ rb_raise(rb_eRuntimeError, "failed to read file");
58
+
59
+ return buffer;
60
+ }
61
+
62
+ static VALUE RGSS_TrueType_Initialize(VALUE self, VALUE source)
63
+ {
64
+ rb_io_t *fptr;
65
+ VALUE file;
66
+ int close;
67
+
68
+ if (RB_TYPE_P(source, T_STRING))
69
+ {
70
+ file = rb_file_open(StringValueCStr(source), "rb");
71
+ close = 1;
72
+ }
73
+ else if (RB_TYPE_P(source, T_FILE))
74
+ {
75
+ file = source;
76
+ close = 0;
77
+ }
78
+ else
79
+ {
80
+ rb_raise(rb_eTypeError, "%s is not a File or String", CLASS_NAME(source));
81
+ }
82
+
83
+ GetOpenFile(file, fptr);
84
+ unsigned char *buffer = RGSS_TrueType_ReadFile(fptr->fd);
85
+ if (close)
86
+ rb_io_close(file);
87
+
88
+ RGSS_TrueType *font = DATA_PTR(self);
89
+
90
+ font->buffer = buffer;
91
+ stbtt_InitFont(&font->info, buffer, stbtt_GetFontOffsetForIndex(buffer, 0));
92
+
93
+ return self;
94
+ }
95
+
96
+ static VALUE RGSS_TrueType_Scale(int argc, VALUE *argv, VALUE self)
97
+ {
98
+ VALUE height, opts;
99
+ rb_scan_args(argc, argv, "1:", &height, &opts);
100
+
101
+ int pixel = 1;
102
+ if (RTEST(opts))
103
+ {
104
+ VALUE mode = rb_hash_aref(opts, STR2SYM("mode"));
105
+ if (mode == STR2SYM("pixel"))
106
+ pixel = 1;
107
+ else if (mode == STR2SYM("em"))
108
+ pixel = 0;
109
+ else
110
+ rb_raise(rb_eArgError, "invalid scaling mode specified");
111
+ }
112
+
113
+ float value;
114
+ RGSS_TrueType *font = DATA_PTR(self);
115
+
116
+ if (pixel)
117
+ value = stbtt_ScaleForPixelHeight(&font->info, NUM2FLT(height));
118
+ else
119
+ value = stbtt_ScaleForMappingEmToPixels(&font->info, NUM2FLT(height));
120
+
121
+ return DBL2NUM(value);
122
+ }
123
+
124
+
125
+ void RGSS_Init_TrueType(VALUE parent)
126
+ {
127
+ rb_cTrueType = rb_define_class_under(parent, "TrueType", rb_cObject);
128
+ rb_define_alloc_func(rb_cTrueType, RGSS_TrueType_Alloc);
129
+
130
+
131
+ rb_define_method1(rb_cTrueType, "initialize", RGSS_TrueType_Initialize, 1);
132
+ rb_define_methodm1(rb_cTrueType, "scale", RGSS_TrueType_Scale, -1);
133
+ }
134
+
135
+ #endif /* */