allegro4r 0.0.1-x86-mswin32-60
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.
- data/History.txt +4 -0
- data/Manifest.txt +59 -0
- data/README.txt +94 -0
- data/examples/exdbuf.rb +58 -0
- data/examples/exfixed.rb +46 -0
- data/examples/exflame.rb +200 -0
- data/examples/exflip.rb +87 -0
- data/examples/exfont.rb +70 -0
- data/examples/exhello.rb +46 -0
- data/examples/exjoy.rb +206 -0
- data/examples/exkeys.rb +216 -0
- data/examples/exmem.rb +50 -0
- data/examples/exmidi.rb +97 -0
- data/examples/exmouse.rb +149 -0
- data/examples/expal.rb +70 -0
- data/examples/expat.rb +62 -0
- data/examples/exsample.rb +89 -0
- data/examples/extimer.rb +84 -0
- data/examples/unifont.dat +0 -0
- data/ext/a4r_API_BITMAP.c +27 -0
- data/ext/a4r_API_DIGI_DRIVER.c +14 -0
- data/ext/a4r_API_GFX_DRIVER.c +14 -0
- data/ext/a4r_API_JOYSTICK_AXIS_INFO.c +53 -0
- data/ext/a4r_API_JOYSTICK_BUTTON_INFO.c +27 -0
- data/ext/a4r_API_JOYSTICK_DRIVER.c +14 -0
- data/ext/a4r_API_JOYSTICK_INFO.c +84 -0
- data/ext/a4r_API_JOYSTICK_STICK_INFO.c +62 -0
- data/ext/a4r_API_KEYBOARD_DRIVER.c +14 -0
- data/ext/a4r_API_MIDI_DRIVER.c +14 -0
- data/ext/a4r_API_MOUSE_DRIVER.c +14 -0
- data/ext/a4r_API_PALETTE.c +63 -0
- data/ext/a4r_API_RGB.c +118 -0
- data/ext/a4r_API_TIMER_DRIVER.c +14 -0
- data/ext/a4r_API_bitmap_objects.c +310 -0
- data/ext/a4r_API_blitting_and_sprites.c +86 -0
- data/ext/a4r_API_digital_sample_routines.c +83 -0
- data/ext/a4r_API_direct_access_to_video_memory.c +102 -0
- data/ext/a4r_API_drawing_primitives.c +114 -0
- data/ext/a4r_API_file_and_compression_routines.c +27 -0
- data/ext/a4r_API_fixed_point_math_routines.c +98 -0
- data/ext/a4r_API_fonts.c +147 -0
- data/ext/a4r_API_graphics_modes.c +155 -0
- data/ext/a4r_API_joystick_routines.c +213 -0
- data/ext/a4r_API_keyboard_routines.c +420 -0
- data/ext/a4r_API_misc.c +133 -0
- data/ext/a4r_API_mouse_routines.c +220 -0
- data/ext/a4r_API_music_routines_midi.c +147 -0
- data/ext/a4r_API_palette_routines.c +112 -0
- data/ext/a4r_API_sound_init_routines.c +29 -0
- data/ext/a4r_API_text_output.c +178 -0
- data/ext/a4r_API_timer_routines.c +250 -0
- data/ext/a4r_API_transparency_and_patterned_drawing.c +87 -0
- data/ext/a4r_API_truecolor_pixel_formats.c +44 -0
- data/ext/a4r_API_unicode_routines.c +53 -0
- data/ext/a4r_API_using_allegro.c +98 -0
- data/ext/allegro4r.c +866 -0
- data/ext/allegro4r.h +311 -0
- data/ext/allegro4r.so +0 -0
- data/ext/extconf.rb +11 -0
- metadata +113 -0
@@ -0,0 +1,250 @@
|
|
1
|
+
#include "allegro4r.h"
|
2
|
+
|
3
|
+
/*
|
4
|
+
* call-seq:
|
5
|
+
* install_timer -> int
|
6
|
+
*
|
7
|
+
* Installs the Allegro timer interrupt handler. You must do this before
|
8
|
+
* installing any user timer routines, and also before displaying a mouse
|
9
|
+
* pointer, playing FLI animations or MIDI music, and using any of the GUI
|
10
|
+
* routines.
|
11
|
+
*
|
12
|
+
* Return value: Returns zero on success, or a negative number on failure (but
|
13
|
+
* you may decide not to check the return value as this function is very
|
14
|
+
* unlikely to fail).
|
15
|
+
*/
|
16
|
+
VALUE a4r_API_install_timer(VALUE self)
|
17
|
+
{
|
18
|
+
return INT2FIX(install_timer());
|
19
|
+
}
|
20
|
+
|
21
|
+
/*
|
22
|
+
* call-seq:
|
23
|
+
* install_int(name, speed) -> int
|
24
|
+
*
|
25
|
+
* Installs a user timer handler, with the speed given as the number of
|
26
|
+
* milliseconds between ticks. This is the same thing as install_int_ex(name,
|
27
|
+
* MSEC_TO_TIMER(speed)). If you call this routine without having first
|
28
|
+
* installed the timer module, install_timer will be called automatically.
|
29
|
+
* Calling again this routine with the same timer handler as parameter allows
|
30
|
+
* you to adjust its speed.
|
31
|
+
*
|
32
|
+
* Return value: Returns zero on success, or a negative number if there is no
|
33
|
+
* room to add a new user timer.
|
34
|
+
*
|
35
|
+
* *** The Ruby method differs from the Allegro method. The Allegro method takes
|
36
|
+
* a function pointer as the first parameter, which it will use as the timer
|
37
|
+
* interrupt callback. The Ruby method takes a name which will be used to
|
38
|
+
* identify a predefined counter routine which will be used as the interrupt
|
39
|
+
* callback. To get the value for that counter, call timer_counter_get with the
|
40
|
+
* name.
|
41
|
+
*/
|
42
|
+
VALUE a4r_API_install_int(VALUE self, VALUE name, VALUE speed)
|
43
|
+
{
|
44
|
+
VALUE t_speed = LONG2NUM(MSEC_TO_TIMER(FIX2INT(speed)));
|
45
|
+
return a4r_API_install_int_ex(self, name, t_speed);
|
46
|
+
}
|
47
|
+
|
48
|
+
/*
|
49
|
+
* call-seq:
|
50
|
+
* install_int_ex(name, speed) -> int
|
51
|
+
*
|
52
|
+
* Adds a function to the list of user timer handlers or, if it is already
|
53
|
+
* installed, retroactively adjusts its speed (i.e makes as though the speed
|
54
|
+
* change occurred precisely at the last tick). The speed is given in hardware
|
55
|
+
* clock ticks, of which there are 1193181 a second. You can convert from other
|
56
|
+
* time formats to hardware clock ticks with the macros:
|
57
|
+
* SECS_TO_TIMER(secs) - give the number of seconds between each tick
|
58
|
+
* MSEC_TO_TIMER(msec) - give the number of milliseconds between ticks
|
59
|
+
* BPS_TO_TIMER(bps) - give the number of ticks each second
|
60
|
+
* BPM_TO_TIMER(bpm) - give the number of ticks per minute
|
61
|
+
*
|
62
|
+
* There can only be sixteen timers in use at a time, and some other parts of
|
63
|
+
* Allegro (the GUI code, the mouse pointer display routines, rest, the FLI
|
64
|
+
* player, and the MIDI player) need to install handlers of their own, so you
|
65
|
+
* should avoid using too many at the same time. If you call this routine
|
66
|
+
* without having first installed the timer module, install_timer will be called
|
67
|
+
* automatically.
|
68
|
+
*
|
69
|
+
* Return value: Returns zero on success, or a negative number if there is no
|
70
|
+
* room to add a new user timer.
|
71
|
+
*
|
72
|
+
* *** The Ruby method differs from the Allegro method. The Allegro method takes
|
73
|
+
* a function pointer as the first parameter, which it will use as the timer
|
74
|
+
* interrupt callback. The Ruby method takes a name which will be used to
|
75
|
+
* identify a predefined counter routine which will be used as the interrupt
|
76
|
+
* callback. To get the value for that counter, call timer_counter_get with the
|
77
|
+
* name.
|
78
|
+
*/
|
79
|
+
VALUE a4r_API_install_int_ex(VALUE self, VALUE name, VALUE speed)
|
80
|
+
{
|
81
|
+
VALUE i = find_timer_counter(name);
|
82
|
+
if (i == Qnil)
|
83
|
+
{
|
84
|
+
i = find_free_timer_counter();
|
85
|
+
rb_hash_aset(timer_counter_names, name, i);
|
86
|
+
timer_counters[FIX2INT(i)] = 0;
|
87
|
+
}
|
88
|
+
|
89
|
+
return INT2FIX(install_param_int_ex(&timer_counter_incr, (void *)&(timer_counters[FIX2INT(i)]), NUM2INT(speed)));
|
90
|
+
}
|
91
|
+
|
92
|
+
/*
|
93
|
+
* call-seq:
|
94
|
+
* LOCK_VARIABLE(variable_name) -> nil
|
95
|
+
*
|
96
|
+
* Due to interrupts, you are required to lock all the memory used by your timer
|
97
|
+
* routines. See the description of install_int_ex for a more detailed
|
98
|
+
* explanation and usage example.
|
99
|
+
*
|
100
|
+
* *** The Ruby method differs from the Allegro method. Due to the use of
|
101
|
+
* predefined timer routines, LOCK_VARIABLE and LOCK_FUNCTION do nothing, and
|
102
|
+
* are here simply for API consistency. They will raise warnings if the Ruby
|
103
|
+
* script is run with -w.
|
104
|
+
*/
|
105
|
+
VALUE a4r_API_LOCK_VARIABLE(VALUE self, VALUE variable_name)
|
106
|
+
{
|
107
|
+
rb_warning("Allegro4r::API::LOCK_VARIABLE does nothing.");
|
108
|
+
return Qnil;
|
109
|
+
}
|
110
|
+
|
111
|
+
/*
|
112
|
+
* call-seq:
|
113
|
+
* LOCK_FUNCTION(function_name) -> nil
|
114
|
+
*
|
115
|
+
* See LOCK_VARIABLE.
|
116
|
+
*/
|
117
|
+
VALUE a4r_API_LOCK_FUNCTION(VALUE self, VALUE function_name)
|
118
|
+
{
|
119
|
+
rb_warning("Allegro4r::API::LOCK_FUNCTION does nothing.");
|
120
|
+
return Qnil;
|
121
|
+
}
|
122
|
+
|
123
|
+
/*
|
124
|
+
* call-seq:
|
125
|
+
* retrace_count -> int
|
126
|
+
*
|
127
|
+
* If the retrace simulator is installed, this count is incremented on each
|
128
|
+
* vertical retrace; otherwise, if the refresh rate is known, the count is
|
129
|
+
* incremented at the same rate (ignoring retraces); otherwise, it is
|
130
|
+
* incremented 70 times a second. This provides a way of controlling the speed
|
131
|
+
* of your program without installing user timer functions.
|
132
|
+
*/
|
133
|
+
VALUE a4r_API_retrace_count(VALUE self)
|
134
|
+
{
|
135
|
+
// TODO: Convert to data struct or cached or hooked variable?
|
136
|
+
return INT2FIX(retrace_count);
|
137
|
+
}
|
138
|
+
|
139
|
+
/*
|
140
|
+
* call-seq:
|
141
|
+
* rest(time) -> nil
|
142
|
+
*
|
143
|
+
* This function waits for the specified number of milliseconds.
|
144
|
+
*
|
145
|
+
* Passing 0 as parameter will not wait, but just yield. This can be useful in
|
146
|
+
* order to "play nice" with other processes. Other values will cause CPU time
|
147
|
+
* to be dropped on most platforms. This will look better to users, and also
|
148
|
+
* does things like saving battery power and making fans less noisy.
|
149
|
+
*
|
150
|
+
* Note that calling this inside your active game loop is a bad idea, as you
|
151
|
+
* never know when the OS will give you the CPU back, so you could end up
|
152
|
+
* missing the vertical retrace and skipping frames. On the other hand, on
|
153
|
+
* multitasking operating systems it is good form to give up the CPU for a while
|
154
|
+
* if you will not be using it.
|
155
|
+
*/
|
156
|
+
VALUE a4r_API_rest(VALUE self, VALUE time)
|
157
|
+
{
|
158
|
+
rest(NUM2UINT(time));
|
159
|
+
return Qnil;
|
160
|
+
}
|
161
|
+
|
162
|
+
/*
|
163
|
+
* call-seq:
|
164
|
+
* SECS_TO_TIMER(secs) -> num
|
165
|
+
*
|
166
|
+
* Give the number of seconds between each tick
|
167
|
+
*/
|
168
|
+
VALUE a4r_API_SECS_TO_TIMER(VALUE self, VALUE secs)
|
169
|
+
{
|
170
|
+
return LONG2NUM(SECS_TO_TIMER(NUM2LONG(secs)));
|
171
|
+
}
|
172
|
+
|
173
|
+
/*
|
174
|
+
* call-seq:
|
175
|
+
* MSEC_TO_TIMER(msec) -> num
|
176
|
+
*
|
177
|
+
* Give the number of milliseconds between ticks
|
178
|
+
*/
|
179
|
+
VALUE a4r_API_MSEC_TO_TIMER(VALUE self, VALUE msec)
|
180
|
+
{
|
181
|
+
return LONG2NUM(MSEC_TO_TIMER(NUM2LONG(msec)));
|
182
|
+
}
|
183
|
+
|
184
|
+
/*
|
185
|
+
* call-seq:
|
186
|
+
* BPS_TO_TIMER(bps) -> num
|
187
|
+
*
|
188
|
+
* Give the number of ticks each second
|
189
|
+
*/
|
190
|
+
VALUE a4r_API_BPS_TO_TIMER(VALUE self, VALUE bps)
|
191
|
+
{
|
192
|
+
return LONG2NUM(BPS_TO_TIMER(NUM2LONG(bps)));
|
193
|
+
}
|
194
|
+
|
195
|
+
/*
|
196
|
+
* call-seq:
|
197
|
+
* BPM_TO_TIMER(bpm) -> num
|
198
|
+
*
|
199
|
+
* Give the number of ticks per minute
|
200
|
+
*/
|
201
|
+
VALUE a4r_API_BPM_TO_TIMER(VALUE self, VALUE bpm)
|
202
|
+
{
|
203
|
+
return LONG2NUM(BPM_TO_TIMER(NUM2LONG(bpm)));
|
204
|
+
}
|
205
|
+
|
206
|
+
/******************************************************************************/
|
207
|
+
// Predefined timer counter routines
|
208
|
+
|
209
|
+
VALUE timer_counter_names;
|
210
|
+
volatile int timer_counters[MAX_TIMER_COUNTERS];
|
211
|
+
|
212
|
+
void timer_counter_incr(void *param)
|
213
|
+
{
|
214
|
+
*((int *)param) += 1;
|
215
|
+
}
|
216
|
+
END_OF_FUNCTION(timer_counter_incr)
|
217
|
+
|
218
|
+
VALUE find_timer_counter(VALUE name)
|
219
|
+
{
|
220
|
+
return rb_hash_aref(timer_counter_names, name);
|
221
|
+
}
|
222
|
+
|
223
|
+
VALUE find_free_timer_counter()
|
224
|
+
{
|
225
|
+
int i;
|
226
|
+
ID f = rb_intern("has_value?");
|
227
|
+
for (i = 0; i < MAX_TIMER_COUNTERS; i++)
|
228
|
+
if (rb_funcall(timer_counter_names, f, 1, INT2FIX(i)) == Qfalse)
|
229
|
+
break;
|
230
|
+
|
231
|
+
if (i == MAX_TIMER_COUNTERS)
|
232
|
+
return Qnil;
|
233
|
+
return INT2FIX(i);
|
234
|
+
}
|
235
|
+
|
236
|
+
/*
|
237
|
+
* call-seq:
|
238
|
+
* timer_counter_get(name) -> int
|
239
|
+
*
|
240
|
+
* Returns the value of the specified timer counter.
|
241
|
+
*
|
242
|
+
* *** This is not an Allegro method. See the Ruby note under install_int_ex.
|
243
|
+
*/
|
244
|
+
VALUE a4r_API_timer_counter_get(VALUE self, VALUE name)
|
245
|
+
{
|
246
|
+
VALUE i = find_timer_counter(name);
|
247
|
+
if (i == Qnil)
|
248
|
+
return i;
|
249
|
+
return INT2FIX(timer_counters[FIX2INT(i)]);
|
250
|
+
}
|
@@ -0,0 +1,87 @@
|
|
1
|
+
#include "allegro4r.h"
|
2
|
+
|
3
|
+
/*
|
4
|
+
* call-seq:
|
5
|
+
* drawing_mode(mode, pattern, x_anchor, y_anchor) -> nil
|
6
|
+
*
|
7
|
+
* Sets the graphics drawing mode. This only affects the geometric routines like
|
8
|
+
* putpixel, lines, rectangles, circles, polygons, floodfill, etc, not the text
|
9
|
+
* output, blitting, or sprite drawing functions. The mode should be one of the
|
10
|
+
* following constants:
|
11
|
+
* DRAW_MODE_SOLID - the default, solid color drawing
|
12
|
+
* DRAW_MODE_XOR - exclusive-or drawing
|
13
|
+
* DRAW_MODE_COPY_PATTERN - multicolored pattern fill
|
14
|
+
* DRAW_MODE_SOLID_PATTERN - single color pattern fill
|
15
|
+
* DRAW_MODE_MASKED_PATTERN - masked pattern fill
|
16
|
+
* DRAW_MODE_TRANS - translucent color blending
|
17
|
+
*
|
18
|
+
* In DRAW_MODE_SOLID, pixels of the bitmap being drawn onto are simply replaced
|
19
|
+
* by those produced by the drawing function.
|
20
|
+
*
|
21
|
+
* In DRAW_MODE_XOR, pixels are written to the bitmap with an exclusive-or
|
22
|
+
* operation rather than a simple copy, so drawing the same shape twice will
|
23
|
+
* erase it. Because it involves reading as well as writing the bitmap memory,
|
24
|
+
* xor drawing is a lot slower than the normal replace mode.
|
25
|
+
*
|
26
|
+
* With the patterned modes, you provide a pattern bitmap which is tiled across
|
27
|
+
* the surface of the shape. Allegro stores a pointer to this bitmap rather than
|
28
|
+
* copying it, so you must not destroy the bitmap while it is still selected as
|
29
|
+
* the pattern. The width and height of the pattern must be powers of two, but
|
30
|
+
* they can be different, eg. a 64x16 pattern is fine, but a 17x3 one is not.
|
31
|
+
* The pattern is tiled in a grid starting at point (x_anchor, y_anchor).
|
32
|
+
* Normally you should just pass zero for these values, which lets you draw
|
33
|
+
* several adjacent shapes and have the patterns meet up exactly along the
|
34
|
+
* shared edges. Zero alignment may look peculiar if you are moving a patterned
|
35
|
+
* shape around the screen, however, because the shape will move but the pattern
|
36
|
+
* alignment will not, so in some situations you may wish to alter the anchor
|
37
|
+
* position.
|
38
|
+
*
|
39
|
+
* When you select DRAW_MODE_COPY_PATTERN, pixels are simply copied from the
|
40
|
+
* pattern bitmap onto the destination bitmap. This allows the use of
|
41
|
+
* multicolored patterns, and means that the color you pass to the drawing
|
42
|
+
* routine is ignored. This is the fastest of the patterned modes.
|
43
|
+
*
|
44
|
+
* In DRAW_MODE_SOLID_PATTERN, each pixel in the pattern bitmap is compared with
|
45
|
+
* the mask color, which is zero in 256-color modes or bright pink for truecolor
|
46
|
+
* data (maximum red and blue, zero green). If the pattern pixel is solid, a
|
47
|
+
* pixel of the color you passed to the drawing routine is written to the
|
48
|
+
* destination bitmap, otherwise a zero is written. The pattern is thus treated
|
49
|
+
* as a monochrome bitmask, which lets you use the same pattern to draw
|
50
|
+
* different shapes in different colors, but prevents the use of multicolored
|
51
|
+
* patterns.
|
52
|
+
*
|
53
|
+
* DRAW_MODE_MASKED_PATTERN is almost the same as DRAW_MODE_SOLID_PATTERN, but
|
54
|
+
* the masked pixels are skipped rather than being written as zeros, so the
|
55
|
+
* background shows through the gaps.
|
56
|
+
*
|
57
|
+
* In DRAW_MODE_TRANS, the global color_map table or truecolor blender functions
|
58
|
+
* are used to overlay pixels on top of the existing image. This must only be
|
59
|
+
* used after you have set up the color mapping table (for 256 color modes) or
|
60
|
+
* blender functions (for truecolor modes). Because it involves reading as well
|
61
|
+
* as writing the bitmap memory, translucent drawing is very slow if you draw
|
62
|
+
* directly to video RAM, so wherever possible you should use a memory bitmap
|
63
|
+
* instead.
|
64
|
+
*/
|
65
|
+
VALUE a4r_API_drawing_mode(VALUE self, VALUE mode, VALUE pattern, VALUE x_anchor, VALUE y_anchor)
|
66
|
+
{
|
67
|
+
BITMAP *bitmap;
|
68
|
+
if (pattern == Qnil)
|
69
|
+
bitmap = NULL;
|
70
|
+
else
|
71
|
+
Data_Get_Struct(pattern, BITMAP, bitmap);
|
72
|
+
drawing_mode(FIX2INT(mode), bitmap, FIX2INT(x_anchor), FIX2INT(y_anchor));
|
73
|
+
return Qnil;
|
74
|
+
}
|
75
|
+
|
76
|
+
/*
|
77
|
+
* call-seq:
|
78
|
+
* solid_mode -> nil
|
79
|
+
*
|
80
|
+
* This is a shortcut for selecting solid drawing mode. It is equivalent to
|
81
|
+
* calling drawing_mode(DRAW_MODE_SOLID, nil, 0, 0).
|
82
|
+
*/
|
83
|
+
VALUE a4r_API_solid_mode(VALUE self)
|
84
|
+
{
|
85
|
+
solid_mode();
|
86
|
+
return Qnil;
|
87
|
+
}
|
@@ -0,0 +1,44 @@
|
|
1
|
+
#include "allegro4r.h"
|
2
|
+
|
3
|
+
/*
|
4
|
+
* call-seq:
|
5
|
+
* make_col(r, g, b) -> a_rgb
|
6
|
+
*
|
7
|
+
* Converts colors from a hardware independent format (red, green, and blue
|
8
|
+
* values ranging 0-255) to the pixel format required by the current video mode,
|
9
|
+
* calling the preceding 8, 15, 16, 24, or 32-bit makecol functions as
|
10
|
+
* appropriate. Example:
|
11
|
+
* # Regardless of color depth, this will look green.
|
12
|
+
* green_color = makecol(0, 255, 0)
|
13
|
+
*
|
14
|
+
* Return value: Returns the requested RGB triplet in the current color depth.
|
15
|
+
*/
|
16
|
+
VALUE a4r_API_makecol(VALUE self, VALUE r, VALUE g, VALUE b)
|
17
|
+
{
|
18
|
+
return INT2FIX(makecol(FIX2INT(r), FIX2INT(g), FIX2INT(b)));
|
19
|
+
}
|
20
|
+
|
21
|
+
/*
|
22
|
+
* call-seq:
|
23
|
+
* palette_color -> ary
|
24
|
+
*
|
25
|
+
* Table mapping palette index colors (0-255) into whatever pixel format is
|
26
|
+
* being used by the current display mode. In a 256-color mode this just maps
|
27
|
+
* onto the array index. In truecolor modes it looks up the specified entry in
|
28
|
+
* the current palette, and converts that RGB value into the appropriate packed
|
29
|
+
* pixel format. Example:
|
30
|
+
* set_color_depth(32)
|
31
|
+
* ...
|
32
|
+
* set_palette(desktop_palette)
|
33
|
+
* # Put a pixel with the color 2 (green) of the palette
|
34
|
+
* putpixel(screen, 100, 100, palette_color[2])
|
35
|
+
*/
|
36
|
+
VALUE a4r_API_palette_color(VALUE self)
|
37
|
+
{
|
38
|
+
// TODO: Cache the array, and only update if changed, or use hooked variable?
|
39
|
+
VALUE ary = rb_ary_new2(PAL_SIZE);
|
40
|
+
int x;
|
41
|
+
for (x = 0; x < PAL_SIZE; x++)
|
42
|
+
rb_ary_store(ary, x, INT2FIX(pallete_color[x]));
|
43
|
+
return ary;
|
44
|
+
}
|
@@ -0,0 +1,53 @@
|
|
1
|
+
#include "allegro4r.h"
|
2
|
+
|
3
|
+
/*
|
4
|
+
* call-seq:
|
5
|
+
* ustrzncpy(src, n) -> str
|
6
|
+
*
|
7
|
+
* This function is like ustrzcpy except that no more than 'n' characters from
|
8
|
+
* 'src' are copied into 'dest'. If 'src' is shorter than 'n' characters, null
|
9
|
+
* characters are appended to 'dest' as padding until 'n' characters have been
|
10
|
+
* written. In any case, 'dest' is guaranteed to be null-terminated.
|
11
|
+
*
|
12
|
+
* Note that, even for empty strings, your destination string must have at least
|
13
|
+
* enough bytes to store the terminating null character of the string, and your
|
14
|
+
* parameter 'size' must reflect this. Otherwise, the debug version of Allegro
|
15
|
+
* will abort at an assertion, and the release version of Allegro will overrun
|
16
|
+
* the destination buffer.
|
17
|
+
*
|
18
|
+
* Return value: The return value is the value of 'dest'.
|
19
|
+
*
|
20
|
+
* *** The Ruby method signature differs from the Allegro method signature. The
|
21
|
+
* Allegro signature takes a dest by reference, and a size, but the Ruby
|
22
|
+
* signature returns a string containing the dest. The returned string will
|
23
|
+
* have null characters appended as per the description above.
|
24
|
+
*/
|
25
|
+
VALUE a4r_API_ustrzncpy(VALUE self, VALUE src, VALUE n)
|
26
|
+
{
|
27
|
+
int size = FIX2INT(n) + 1;
|
28
|
+
char *dest = ALLOC_N(char, size);
|
29
|
+
ustrzncpy(dest, size, StringValuePtr(src), size);
|
30
|
+
VALUE s = rb_str_new(dest, size - 1);
|
31
|
+
free(dest);
|
32
|
+
return s;
|
33
|
+
}
|
34
|
+
|
35
|
+
/*
|
36
|
+
* call-seq:
|
37
|
+
* usprintf(format) -> str
|
38
|
+
*
|
39
|
+
* This function writes formatted data into the output buffer. A NULL character
|
40
|
+
* is written to mark the end of the string. You should try to avoid this
|
41
|
+
* function because it is very easy to overflow the destination buffer. Use
|
42
|
+
* uszprintf instead.
|
43
|
+
*
|
44
|
+
* Return value: Returns the number of characters written, not including the
|
45
|
+
* terminating null character.
|
46
|
+
*
|
47
|
+
* *** The Ruby method differs from the Allegro method. The Allegro signature
|
48
|
+
* takes a dest but the Ruby signature returns a string containing the dest.
|
49
|
+
*/
|
50
|
+
VALUE a4r_API_usprintf(VALUE self, VALUE format)
|
51
|
+
{
|
52
|
+
return format;
|
53
|
+
}
|
@@ -0,0 +1,98 @@
|
|
1
|
+
#include "allegro4r.h"
|
2
|
+
|
3
|
+
static VALUE a4r_at_exit()
|
4
|
+
{
|
5
|
+
rb_funcall(rb_mKernel, rb_intern("at_exit"), 0);
|
6
|
+
}
|
7
|
+
|
8
|
+
/*
|
9
|
+
* call-seq:
|
10
|
+
* allegro_init -> int
|
11
|
+
*
|
12
|
+
* Macro which initialises the Allegro library. This is the same thing as
|
13
|
+
* calling install_allegro(SYSTEM_AUTODETECT, &errno, atexit).
|
14
|
+
*/
|
15
|
+
VALUE a4r_API_allegro_init(VALUE self)
|
16
|
+
{
|
17
|
+
int ret = allegro_init();
|
18
|
+
if (!ret)
|
19
|
+
rb_iterate(a4r_at_exit, 0, a4r_API_allegro_exit, self);
|
20
|
+
return INT2FIX(ret);
|
21
|
+
}
|
22
|
+
|
23
|
+
/*
|
24
|
+
* call-seq:
|
25
|
+
* allegro_exit -> nil
|
26
|
+
*
|
27
|
+
* Closes down the Allegro system. This includes returning the system to text
|
28
|
+
* mode and removing whatever mouse, keyboard, and timer routines have been
|
29
|
+
* installed. You don't normally need to bother making an explicit call to this
|
30
|
+
* function, because allegro_init installs it as an atexit routine so it will be
|
31
|
+
* called automatically when your program exits.
|
32
|
+
*
|
33
|
+
* Note that after you call this function, other functions like destroy_bitmap
|
34
|
+
* will most likely crash. This is a problem for C++ global destructors, which
|
35
|
+
* usually get called after atexit, so don't put Allegro calls in them. You can
|
36
|
+
* write the destructor code in another method which you can manually call
|
37
|
+
* before your program exits, avoiding this problem.
|
38
|
+
*/
|
39
|
+
VALUE a4r_API_allegro_exit(VALUE self)
|
40
|
+
{
|
41
|
+
allegro_exit();
|
42
|
+
return Qnil;
|
43
|
+
}
|
44
|
+
|
45
|
+
/*
|
46
|
+
* call-seq:
|
47
|
+
* allegro_error -> str
|
48
|
+
*
|
49
|
+
* Text string used by set_gfx_mode, install_sound and other functions to report
|
50
|
+
* error messages. If they fail and you want to tell the user why, this is the
|
51
|
+
* place to look for a description of the problem. Example:
|
52
|
+
* def abort_on_error(message)
|
53
|
+
* set_gfx_mode(GFX_TEXT, 0, 0, 0, 0) unless screen.nil?
|
54
|
+
*
|
55
|
+
* allegro_message("%s.\nLast Allegro error '%s'\n" %
|
56
|
+
* [message, allegro_error])
|
57
|
+
* exit -1
|
58
|
+
* end
|
59
|
+
* ...
|
60
|
+
* if some_allegro_function == ERROR_CODE
|
61
|
+
* abort_on_error("Error calling some function!")
|
62
|
+
* end
|
63
|
+
*/
|
64
|
+
VALUE a4r_API_allegro_error(VALUE self)
|
65
|
+
{
|
66
|
+
// TODO: Convert to data struct or cached or hooked variable?
|
67
|
+
return rb_str_new2(allegro_error);
|
68
|
+
}
|
69
|
+
|
70
|
+
/*
|
71
|
+
* call-seq:
|
72
|
+
* allegro_message(text) -> nil
|
73
|
+
*
|
74
|
+
* Outputs a message, using a printf format string. Usually you want to use this
|
75
|
+
* to report messages to the user in an OS independant way when some Allegro
|
76
|
+
* subsystem cannot be initialised. But you must not use this function if you
|
77
|
+
* are in a graphic mode, only before calling set_gfx_mode, or after a
|
78
|
+
* set_gfx_mode(GFX_TEXT). Also, this function depends on a system driver being
|
79
|
+
* installed, which means that it won't display the message at all on some
|
80
|
+
* platforms if Allegro has not been initialised correctly.
|
81
|
+
*
|
82
|
+
* On platforms featuring a windowing system, it will bring up a blocking GUI
|
83
|
+
* message box. If there is no windowing system, it will try to print the string
|
84
|
+
* to a text console, attempting to work around codepage differences by reducing
|
85
|
+
* any accented characters to 7-bit ASCII approximations. Example:
|
86
|
+
* exit 1 if allegro_init != 0
|
87
|
+
*
|
88
|
+
* if init_my_data != 0
|
89
|
+
* allegro_message("Sorry, missing game data!\n")
|
90
|
+
* exit 2
|
91
|
+
* end
|
92
|
+
*/
|
93
|
+
VALUE a4r_API_allegro_message(VALUE self, VALUE text)
|
94
|
+
{
|
95
|
+
// TODO: Allow parameter possing a lo printf for direct API consistency or force string only?
|
96
|
+
allegro_message(StringValuePtr(text));
|
97
|
+
return Qnil;
|
98
|
+
}
|