allegro4r 0.0.1-x86-mswin32-60
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
}
|