rubygame 2.3.0-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/CREDITS +60 -0
- data/LICENSE +504 -0
- data/NEWS +252 -0
- data/README +123 -0
- data/ROADMAP +109 -0
- data/Rakefile +440 -0
- data/doc/extended_readme.rdoc +49 -0
- data/doc/getting_started.rdoc +47 -0
- data/doc/macosx_install.rdoc +70 -0
- data/doc/windows_install.rdoc +123 -0
- data/ext/rubygame/rubygame_core.so +0 -0
- data/ext/rubygame/rubygame_event.c +644 -0
- data/ext/rubygame/rubygame_event.h +48 -0
- data/ext/rubygame/rubygame_event.obj +0 -0
- data/ext/rubygame/rubygame_gfx.c +942 -0
- data/ext/rubygame/rubygame_gfx.h +101 -0
- data/ext/rubygame/rubygame_gfx.obj +0 -0
- data/ext/rubygame/rubygame_gfx.so +0 -0
- data/ext/rubygame/rubygame_gl.c +154 -0
- data/ext/rubygame/rubygame_gl.h +32 -0
- data/ext/rubygame/rubygame_gl.obj +0 -0
- data/ext/rubygame/rubygame_image.c +252 -0
- data/ext/rubygame/rubygame_image.h +41 -0
- data/ext/rubygame/rubygame_image.obj +0 -0
- data/ext/rubygame/rubygame_image.so +0 -0
- data/ext/rubygame/rubygame_joystick.c +247 -0
- data/ext/rubygame/rubygame_joystick.h +41 -0
- data/ext/rubygame/rubygame_joystick.obj +0 -0
- data/ext/rubygame/rubygame_main.c +155 -0
- data/ext/rubygame/rubygame_main.h +36 -0
- data/ext/rubygame/rubygame_main.obj +0 -0
- data/ext/rubygame/rubygame_mixer.c +1024 -0
- data/ext/rubygame/rubygame_mixer.h +36 -0
- data/ext/rubygame/rubygame_mixer.obj +0 -0
- data/ext/rubygame/rubygame_mixer.so +0 -0
- data/ext/rubygame/rubygame_music.c +1017 -0
- data/ext/rubygame/rubygame_music.h +29 -0
- data/ext/rubygame/rubygame_music.obj +0 -0
- data/ext/rubygame/rubygame_screen.c +448 -0
- data/ext/rubygame/rubygame_screen.h +43 -0
- data/ext/rubygame/rubygame_screen.obj +0 -0
- data/ext/rubygame/rubygame_shared.c +272 -0
- data/ext/rubygame/rubygame_shared.h +68 -0
- data/ext/rubygame/rubygame_shared.obj +0 -0
- data/ext/rubygame/rubygame_sound.c +863 -0
- data/ext/rubygame/rubygame_sound.h +29 -0
- data/ext/rubygame/rubygame_sound.obj +0 -0
- data/ext/rubygame/rubygame_surface.c +1151 -0
- data/ext/rubygame/rubygame_surface.h +62 -0
- data/ext/rubygame/rubygame_surface.obj +0 -0
- data/ext/rubygame/rubygame_time.c +183 -0
- data/ext/rubygame/rubygame_time.h +32 -0
- data/ext/rubygame/rubygame_time.obj +0 -0
- data/ext/rubygame/rubygame_ttf.c +599 -0
- data/ext/rubygame/rubygame_ttf.h +69 -0
- data/ext/rubygame/rubygame_ttf.obj +0 -0
- data/ext/rubygame/rubygame_ttf.so +0 -0
- data/lib/rubygame.rb +41 -0
- data/lib/rubygame/clock.rb +128 -0
- data/lib/rubygame/color.rb +79 -0
- data/lib/rubygame/color/models/base.rb +111 -0
- data/lib/rubygame/color/models/hsl.rb +153 -0
- data/lib/rubygame/color/models/hsv.rb +149 -0
- data/lib/rubygame/color/models/rgb.rb +78 -0
- data/lib/rubygame/color/palettes/css.rb +49 -0
- data/lib/rubygame/color/palettes/palette.rb +100 -0
- data/lib/rubygame/color/palettes/x11.rb +177 -0
- data/lib/rubygame/constants.rb +238 -0
- data/lib/rubygame/event.rb +313 -0
- data/lib/rubygame/ftor.rb +370 -0
- data/lib/rubygame/hotspot.rb +265 -0
- data/lib/rubygame/keyconstants.rb +237 -0
- data/lib/rubygame/mediabag.rb +94 -0
- data/lib/rubygame/named_resource.rb +254 -0
- data/lib/rubygame/queue.rb +288 -0
- data/lib/rubygame/rect.rb +612 -0
- data/lib/rubygame/sfont.rb +223 -0
- data/lib/rubygame/sprite.rb +511 -0
- data/samples/FreeSans.ttf +0 -0
- data/samples/GPL.txt +340 -0
- data/samples/README +40 -0
- data/samples/chimp.bmp +0 -0
- data/samples/chimp.rb +302 -0
- data/samples/demo_gl.rb +151 -0
- data/samples/demo_gl_tex.rb +197 -0
- data/samples/demo_music.rb +77 -0
- data/samples/demo_rubygame.rb +296 -0
- data/samples/demo_sfont.rb +52 -0
- data/samples/demo_ttf.rb +193 -0
- data/samples/demo_utf8.rb +53 -0
- data/samples/fist.bmp +0 -0
- data/samples/load_and_blit.rb +22 -0
- data/samples/panda.png +0 -0
- data/samples/punch.wav +0 -0
- data/samples/ruby.png +0 -0
- data/samples/song.ogg +0 -0
- data/samples/term16.png +0 -0
- data/samples/whiff.wav +0 -0
- metadata +164 -0
@@ -0,0 +1,29 @@
|
|
1
|
+
/*
|
2
|
+
* Interface to SDL_mixer sound playback and mixing.
|
3
|
+
*--
|
4
|
+
* Rubygame -- Ruby code and bindings to SDL to facilitate game creation
|
5
|
+
* Copyright (C) 2004-2008 John Croisant
|
6
|
+
*
|
7
|
+
* This library is free software; you can redistribute it and/or
|
8
|
+
* modify it under the terms of the GNU Lesser General Public
|
9
|
+
* License as published by the Free Software Foundation; either
|
10
|
+
* version 2.1 of the License, or (at your option) any later version.
|
11
|
+
*
|
12
|
+
* This library is distributed in the hope that it will be useful,
|
13
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
15
|
+
* Lesser General Public License for more details.
|
16
|
+
*
|
17
|
+
* You should have received a copy of the GNU Lesser General Public
|
18
|
+
* License along with this library; if not, write to the Free Software
|
19
|
+
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
20
|
+
*++
|
21
|
+
*/
|
22
|
+
|
23
|
+
|
24
|
+
#ifndef _RUBYGAME_SOUND_H
|
25
|
+
#define _RUBYGAME_SOUND_H
|
26
|
+
|
27
|
+
extern void Rubygame_Init_Sound();
|
28
|
+
|
29
|
+
#endif
|
Binary file
|
@@ -0,0 +1,1151 @@
|
|
1
|
+
/*
|
2
|
+
* Rubygame binding to SDL Surface class.
|
3
|
+
*--
|
4
|
+
* Rubygame -- Ruby code and bindings to SDL to facilitate game creation
|
5
|
+
* Copyright (C) 2004-2007 John Croisant
|
6
|
+
*
|
7
|
+
* This library is free software; you can redistribute it and/or
|
8
|
+
* modify it under the terms of the GNU Lesser General Public
|
9
|
+
* License as published by the Free Software Foundation; either
|
10
|
+
* version 2.1 of the License, or (at your option) any later version.
|
11
|
+
*
|
12
|
+
* This library is distributed in the hope that it will be useful,
|
13
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
15
|
+
* Lesser General Public License for more details.
|
16
|
+
*
|
17
|
+
* You should have received a copy of the GNU Lesser General Public
|
18
|
+
* License along with this library; if not, write to the Free Software
|
19
|
+
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
20
|
+
*++
|
21
|
+
*/
|
22
|
+
|
23
|
+
#include "rubygame_shared.h"
|
24
|
+
#include "rubygame_surface.h"
|
25
|
+
|
26
|
+
void Rubygame_Init_Surface();
|
27
|
+
|
28
|
+
VALUE rbgm_surface_new(int, VALUE*, VALUE);
|
29
|
+
|
30
|
+
VALUE rbgm_surface_get_w(VALUE);
|
31
|
+
VALUE rbgm_surface_get_h(VALUE);
|
32
|
+
VALUE rbgm_surface_get_size(VALUE);
|
33
|
+
|
34
|
+
VALUE rbgm_surface_get_depth(VALUE);
|
35
|
+
VALUE rbgm_surface_get_flags(VALUE);
|
36
|
+
VALUE rbgm_surface_get_masks(VALUE);
|
37
|
+
|
38
|
+
VALUE rbgm_surface_get_alpha(VALUE);
|
39
|
+
VALUE rbgm_surface_set_alpha(int, VALUE*, VALUE);
|
40
|
+
|
41
|
+
VALUE rbgm_surface_get_colorkey(VALUE);
|
42
|
+
VALUE rbgm_surface_set_colorkey(int, VALUE*, VALUE);
|
43
|
+
|
44
|
+
VALUE rbgm_surface_blit(int, VALUE*, VALUE);
|
45
|
+
|
46
|
+
VALUE rbgm_surface_fill(int, VALUE*, VALUE);
|
47
|
+
|
48
|
+
VALUE rbgm_surface_getat(int, VALUE*, VALUE);
|
49
|
+
|
50
|
+
VALUE rbgm_surface_pixels(VALUE);
|
51
|
+
|
52
|
+
VALUE rbgm_surface_get_cliprect(VALUE);
|
53
|
+
VALUE rbgm_surface_set_cliprect(VALUE, VALUE);
|
54
|
+
|
55
|
+
VALUE rbgm_surface_convert(int, VALUE*, VALUE);
|
56
|
+
VALUE rbgm_surface_displayformat(VALUE);
|
57
|
+
VALUE rbgm_surface_displayformatalpha(VALUE);
|
58
|
+
|
59
|
+
VALUE rbgm_image_savebmp(VALUE, VALUE);
|
60
|
+
|
61
|
+
VALUE rbgm_transform_flip(VALUE, VALUE, VALUE);
|
62
|
+
|
63
|
+
/*
|
64
|
+
* call-seq:
|
65
|
+
* new(size, depth=0, flags=0) -> Surface
|
66
|
+
*
|
67
|
+
* Create and initialize a new Surface object.
|
68
|
+
*
|
69
|
+
* A Surface is a grid of image data which you blit (i.e. copy) onto other
|
70
|
+
* Surfaces. Since the Rubygame display is also a Surface (see the Screen
|
71
|
+
* class), Surfaces can be blit to the screen; this is the most common way
|
72
|
+
* to display images on the screen.
|
73
|
+
*
|
74
|
+
* This method may raise SDLError if the SDL video subsystem could
|
75
|
+
* not be initialized for some reason.
|
76
|
+
*
|
77
|
+
* This function takes these arguments:
|
78
|
+
* size:: requested surface size; an array of the form [width, height].
|
79
|
+
* depth:: requested color depth (in bits per pixel). If depth is 0 (default),
|
80
|
+
* automatically choose a color depth: either the depth of the Screen
|
81
|
+
* mode (if one has been set), or the greatest color depth available
|
82
|
+
* on the system.
|
83
|
+
* flags:: an Array or Bitwise-OR'd list of zero or more of the following
|
84
|
+
* flags (located in the Rubygame module, e.g. Rubygame::SWSURFACE).
|
85
|
+
* This argument may be omitted, in which case the Surface
|
86
|
+
* will be a normal software surface (this is not necessarily a bad
|
87
|
+
* thing).
|
88
|
+
* SWSURFACE:: (default) request a software surface.
|
89
|
+
* HWSURFACE:: request a hardware-accelerated surface (using a
|
90
|
+
* graphics card), if available. Creates a software
|
91
|
+
* surface if hardware surfaces are not available.
|
92
|
+
* SRCCOLORKEY:: request a colorkeyed surface. #set_colorkey will
|
93
|
+
* also enable colorkey as needed. For a description
|
94
|
+
* of colorkeys, see #set_colorkey.
|
95
|
+
* SRCALPHA:: request an alpha channel. #set_alpha will
|
96
|
+
* also enable alpha. as needed. For a description
|
97
|
+
* of alpha, see #alpha.
|
98
|
+
*/
|
99
|
+
VALUE rbgm_surface_new(int argc, VALUE *argv, VALUE class)
|
100
|
+
{
|
101
|
+
VALUE self;
|
102
|
+
SDL_Surface *self_surf;
|
103
|
+
SDL_PixelFormat* pixformat;
|
104
|
+
Uint32 flags, Rmask, Gmask, Bmask, Amask;
|
105
|
+
int w, h, depth;
|
106
|
+
VALUE vsize, vdepth, vflags;
|
107
|
+
|
108
|
+
rb_scan_args(argc, argv, "12", &vsize, &vdepth, &vflags);
|
109
|
+
|
110
|
+
if( SDL_GetVideoSurface() )
|
111
|
+
{
|
112
|
+
/* Pixel format is retrieved from the video surface. */
|
113
|
+
pixformat = (SDL_GetVideoSurface())->format;
|
114
|
+
}
|
115
|
+
else
|
116
|
+
{
|
117
|
+
/* We can only get the system color depth when the video system
|
118
|
+
* has been initialized. */
|
119
|
+
if( init_video_system() == 0 )
|
120
|
+
{
|
121
|
+
pixformat = SDL_GetVideoInfo()->vfmt;
|
122
|
+
}
|
123
|
+
else
|
124
|
+
{
|
125
|
+
rb_raise(eSDLError,"Could not initialize SDL video subsystem.");
|
126
|
+
return Qnil;
|
127
|
+
}
|
128
|
+
}
|
129
|
+
|
130
|
+
Rmask = pixformat->Rmask;
|
131
|
+
Gmask = pixformat->Gmask;
|
132
|
+
Bmask = pixformat->Bmask;
|
133
|
+
Amask = pixformat->Amask;
|
134
|
+
|
135
|
+
if( !NIL_P(vdepth) && NUM2INT(vdepth) > 0 )
|
136
|
+
{
|
137
|
+
/* TODO: We might want to check that the requested depth makes sense. */
|
138
|
+
depth = NUM2INT(vdepth);
|
139
|
+
}
|
140
|
+
else
|
141
|
+
{
|
142
|
+
depth = pixformat->BitsPerPixel;
|
143
|
+
}
|
144
|
+
|
145
|
+
|
146
|
+
/* Get width and height for new surface from vsize */
|
147
|
+
vsize = convert_to_array(vsize);
|
148
|
+
|
149
|
+
if(RARRAY(vsize)->len >= 2)
|
150
|
+
{
|
151
|
+
w = NUM2INT(rb_ary_entry(vsize,0));
|
152
|
+
h = NUM2INT(rb_ary_entry(vsize,1));
|
153
|
+
}
|
154
|
+
else
|
155
|
+
rb_raise(rb_eArgError,"Array is too short for Surface size (%d for 2)",\
|
156
|
+
RARRAY(vsize)->len);
|
157
|
+
|
158
|
+
flags = collapse_flags(vflags); /* in rubygame_shared */
|
159
|
+
|
160
|
+
/* Finally, we can create the new Surface! Or try, anyway... */
|
161
|
+
self_surf = SDL_CreateRGBSurface(flags,w,h,depth,Rmask,Gmask,Bmask,Amask);
|
162
|
+
|
163
|
+
if( self_surf == NULL )
|
164
|
+
rb_raise(eSDLError,"Could not create new surface: %s",SDL_GetError());
|
165
|
+
|
166
|
+
|
167
|
+
/* Wrap the new surface in a crunchy candy VALUE shell. */
|
168
|
+
self = Data_Wrap_Struct( cSurface,0,SDL_FreeSurface,self_surf );
|
169
|
+
/* The default initialize() does nothing, but may be overridden. */
|
170
|
+
rb_obj_call_init(self,argc,argv);
|
171
|
+
return self;
|
172
|
+
}
|
173
|
+
|
174
|
+
/* :nodoc: */
|
175
|
+
VALUE rbgm_surface_initialize(int argc, VALUE *argv, VALUE self)
|
176
|
+
{
|
177
|
+
return self;
|
178
|
+
}
|
179
|
+
|
180
|
+
|
181
|
+
/*
|
182
|
+
* call-seq:
|
183
|
+
* width
|
184
|
+
* w
|
185
|
+
*
|
186
|
+
* Return the width (in pixels) of the surface.
|
187
|
+
*/
|
188
|
+
VALUE rbgm_surface_get_w(VALUE self)
|
189
|
+
{
|
190
|
+
SDL_Surface *surf;
|
191
|
+
Data_Get_Struct(self, SDL_Surface, surf);
|
192
|
+
return INT2NUM(surf->w);
|
193
|
+
}
|
194
|
+
|
195
|
+
/*
|
196
|
+
* call-seq:
|
197
|
+
* height
|
198
|
+
* h
|
199
|
+
*
|
200
|
+
* Return the height (in pixels) of the surface.
|
201
|
+
*/
|
202
|
+
VALUE rbgm_surface_get_h(VALUE self)
|
203
|
+
{
|
204
|
+
SDL_Surface *surf;
|
205
|
+
Data_Get_Struct(self, SDL_Surface, surf);
|
206
|
+
return INT2NUM(surf->h);
|
207
|
+
}
|
208
|
+
|
209
|
+
/* call-seq:
|
210
|
+
* size -> [w,h]
|
211
|
+
*
|
212
|
+
* Return the surface's width and height (in pixels) in an Array.
|
213
|
+
*/
|
214
|
+
VALUE rbgm_surface_get_size(VALUE self)
|
215
|
+
{
|
216
|
+
SDL_Surface *surf;
|
217
|
+
Data_Get_Struct(self, SDL_Surface, surf);
|
218
|
+
return rb_ary_new3( 2, INT2NUM(surf->w), INT2NUM(surf->h) );
|
219
|
+
}
|
220
|
+
|
221
|
+
/* call-seq:
|
222
|
+
* depth
|
223
|
+
*
|
224
|
+
* Return the color depth (in bits per pixel) of the surface.
|
225
|
+
*/
|
226
|
+
VALUE rbgm_surface_get_depth(VALUE self)
|
227
|
+
{
|
228
|
+
SDL_Surface *surf;
|
229
|
+
Data_Get_Struct(self, SDL_Surface, surf);
|
230
|
+
return UINT2NUM(surf->format->BitsPerPixel);
|
231
|
+
}
|
232
|
+
|
233
|
+
/* call-seq:
|
234
|
+
* flags
|
235
|
+
*
|
236
|
+
* Return any flags the surface was initialized with
|
237
|
+
* (as a bitwise OR'd integer).
|
238
|
+
*/
|
239
|
+
VALUE rbgm_surface_get_flags(VALUE self)
|
240
|
+
{
|
241
|
+
SDL_Surface *surf;
|
242
|
+
Data_Get_Struct(self, SDL_Surface, surf);
|
243
|
+
return UINT2NUM(surf->flags);
|
244
|
+
}
|
245
|
+
|
246
|
+
/*
|
247
|
+
* call-seq:
|
248
|
+
* masks -> [r,g,b,a]
|
249
|
+
*
|
250
|
+
* Return the color masks [r,g,b,a] of the surface. Almost everyone can
|
251
|
+
* ignore this function. Color masks are used to separate an
|
252
|
+
* integer representation of a color into its seperate channels.
|
253
|
+
*/
|
254
|
+
VALUE rbgm_surface_get_masks(VALUE self)
|
255
|
+
{
|
256
|
+
SDL_Surface *surf;
|
257
|
+
SDL_PixelFormat *format;
|
258
|
+
|
259
|
+
Data_Get_Struct(self, SDL_Surface, surf);
|
260
|
+
format = surf->format;
|
261
|
+
return rb_ary_new3(4,\
|
262
|
+
UINT2NUM(format->Rmask),\
|
263
|
+
UINT2NUM(format->Gmask),\
|
264
|
+
UINT2NUM(format->Bmask),\
|
265
|
+
UINT2NUM(format->Amask));
|
266
|
+
}
|
267
|
+
|
268
|
+
/*
|
269
|
+
* call-seq:
|
270
|
+
* alpha
|
271
|
+
*
|
272
|
+
* Return the per-surface alpha (opacity; non-transparency) of the surface.
|
273
|
+
* It can range from 0 (full transparent) to 255 (full opaque).
|
274
|
+
*/
|
275
|
+
VALUE rbgm_surface_get_alpha(VALUE self)
|
276
|
+
{
|
277
|
+
SDL_Surface *surf;
|
278
|
+
Data_Get_Struct(self, SDL_Surface, surf);
|
279
|
+
return INT2NUM(surf->format->alpha);
|
280
|
+
}
|
281
|
+
|
282
|
+
/*
|
283
|
+
* call-seq:
|
284
|
+
* set_alpha(alpha, flags=Rubygame::SRC_ALPHA)
|
285
|
+
*
|
286
|
+
* Set the per-surface alpha (opacity; non-transparency) of the surface.
|
287
|
+
*
|
288
|
+
* This function takes these arguments:
|
289
|
+
* alpha:: requested opacity of the surface. Alpha must be from 0
|
290
|
+
* (fully transparent) to 255 (fully opaque).
|
291
|
+
* flags:: 0 or Rubygame::SRC_ALPHA (default). Most people will want the
|
292
|
+
* default, in which case this argument can be omitted. For advanced
|
293
|
+
* users: this flag affects the surface as described in the docs for
|
294
|
+
* the SDL C function, SDL_SetAlpha.
|
295
|
+
*/
|
296
|
+
VALUE rbgm_surface_set_alpha(int argc, VALUE *argv, VALUE self)
|
297
|
+
{
|
298
|
+
SDL_Surface *surf;
|
299
|
+
Uint8 alpha;
|
300
|
+
Uint32 flags = SDL_SRCALPHA;
|
301
|
+
VALUE valpha, vflags;
|
302
|
+
|
303
|
+
rb_scan_args(argc, argv, "11", &valpha, &vflags);
|
304
|
+
|
305
|
+
if( !NIL_P(vflags) )
|
306
|
+
{
|
307
|
+
flags = NUM2UINT(vflags);
|
308
|
+
}
|
309
|
+
|
310
|
+
alpha = NUM2UINT(valpha);
|
311
|
+
|
312
|
+
Data_Get_Struct(self, SDL_Surface, surf);
|
313
|
+
if( SDL_SetAlpha(surf,flags,alpha) != 0 )
|
314
|
+
rb_raise(eSDLError, "%s", SDL_GetError());
|
315
|
+
return self;
|
316
|
+
}
|
317
|
+
|
318
|
+
/*
|
319
|
+
* call-seq:
|
320
|
+
* colorkey -> [r,g,b] or nil
|
321
|
+
*
|
322
|
+
* Return the colorkey of the surface in the form [r,g,b] (or +nil+ if there
|
323
|
+
* is no key). The colorkey of a surface is the exact color which will be
|
324
|
+
* ignored when the surface is blitted, effectively turning that color
|
325
|
+
* transparent. This is often used to make a blue (for example) background
|
326
|
+
* on an image seem transparent.
|
327
|
+
*/
|
328
|
+
VALUE rbgm_surface_get_colorkey( VALUE self )
|
329
|
+
{
|
330
|
+
SDL_Surface *surf;
|
331
|
+
Uint32 colorkey;
|
332
|
+
Uint8 r,g,b;
|
333
|
+
|
334
|
+
Data_Get_Struct(self, SDL_Surface, surf);
|
335
|
+
colorkey = surf->format->colorkey;
|
336
|
+
if((int *)colorkey == NULL)
|
337
|
+
return Qnil;
|
338
|
+
SDL_GetRGB(colorkey, surf->format, &r, &g, &b);
|
339
|
+
return rb_ary_new3(3,UINT2NUM(r),UINT2NUM(g),UINT2NUM(b));
|
340
|
+
}
|
341
|
+
|
342
|
+
/*
|
343
|
+
* call-seq:
|
344
|
+
* set_colorkey(color,flags=0)
|
345
|
+
*
|
346
|
+
* Set the colorkey of the surface. See Surface#colorkey for a description
|
347
|
+
* of colorkeys.
|
348
|
+
*
|
349
|
+
* This method takes these arguments:
|
350
|
+
* color:: color to use as the key, in the form [r,g,b]. Can be +nil+ to
|
351
|
+
* un-set the colorkey.
|
352
|
+
* flags:: 0 or Rubygame::SRC_COLORKEY (default) or
|
353
|
+
* Rubygame::SRC_COLORKEY|Rubygame::SDL_RLEACCEL. Most people will
|
354
|
+
* want the default, in which case this argument can be omitted. For
|
355
|
+
* advanced users: this flag affects the surface as described in the
|
356
|
+
* docs for the SDL C function, SDL_SetColorkey.
|
357
|
+
*/
|
358
|
+
VALUE rbgm_surface_set_colorkey( int argc, VALUE *argv, VALUE self)
|
359
|
+
{
|
360
|
+
SDL_Surface *surf;
|
361
|
+
Uint32 color;
|
362
|
+
Uint32 flags;
|
363
|
+
Uint8 r,g,b;
|
364
|
+
VALUE vcolor, vflags;
|
365
|
+
|
366
|
+
Data_Get_Struct(self, SDL_Surface, surf);
|
367
|
+
|
368
|
+
rb_scan_args(argc, argv, "11", &vcolor, &vflags);
|
369
|
+
|
370
|
+
if( !NIL_P(vflags) )
|
371
|
+
{
|
372
|
+
flags = NUM2UINT(vflags);
|
373
|
+
}
|
374
|
+
else
|
375
|
+
{
|
376
|
+
flags = SDL_SRCCOLORKEY;
|
377
|
+
}
|
378
|
+
|
379
|
+
|
380
|
+
if( RTEST(vcolor) )
|
381
|
+
{
|
382
|
+
vcolor = convert_color(vcolor);
|
383
|
+
extract_rgb_u8_as_u8(vcolor, &r, &g, &b);
|
384
|
+
color = SDL_MapRGB(surf->format, r,g,b);
|
385
|
+
}
|
386
|
+
else
|
387
|
+
{
|
388
|
+
flags = 0;
|
389
|
+
color = 0;
|
390
|
+
}
|
391
|
+
|
392
|
+
if(SDL_SetColorKey(surf,flags,color)!=0)
|
393
|
+
rb_raise(eSDLError,"could not set colorkey: %s",SDL_GetError());
|
394
|
+
return self;
|
395
|
+
}
|
396
|
+
|
397
|
+
/*
|
398
|
+
* call-seq:
|
399
|
+
* blit(target,dest,source=nil) -> Rect
|
400
|
+
*
|
401
|
+
* Blit (copy) all or part of the surface's image to another surface,
|
402
|
+
* at a given position. Returns a Rect representing the area of
|
403
|
+
* +target+ which was affected by the blit.
|
404
|
+
*
|
405
|
+
* This method takes these arguments:
|
406
|
+
* target:: the target Surface on which to paste the image.
|
407
|
+
* dest:: the coordinates of the top-left corner of the blit. Affects the
|
408
|
+
* area of +other+ the image data is /pasted/ over.
|
409
|
+
* Can also be a Rect or an Array larger than 2, but
|
410
|
+
* width and height will be ignored.
|
411
|
+
* source:: a Rect representing the area of the source surface to get data
|
412
|
+
* from. Affects where the image data is /copied/ from.
|
413
|
+
* Can also be an Array of no less than 4 values.
|
414
|
+
*/
|
415
|
+
VALUE rbgm_surface_blit(int argc, VALUE *argv, VALUE self)
|
416
|
+
{
|
417
|
+
int left, top, right, bottom;
|
418
|
+
int blit_x,blit_y,blit_w,blit_h;
|
419
|
+
//int dest_x,dest_y,dest_w,dest_h;
|
420
|
+
int src_x,src_y,src_w,src_h;
|
421
|
+
VALUE returnrect;
|
422
|
+
SDL_Surface *src, *dest;
|
423
|
+
SDL_Rect *src_rect, *blit_rect;
|
424
|
+
|
425
|
+
VALUE vtarget, vdest, vsource;
|
426
|
+
|
427
|
+
rb_scan_args( argc, argv, "21", &vtarget, &vdest, &vsource );
|
428
|
+
|
429
|
+
Data_Get_Struct(self, SDL_Surface, src);
|
430
|
+
Data_Get_Struct(vtarget, SDL_Surface, dest);
|
431
|
+
|
432
|
+
vdest = convert_to_array(vdest);
|
433
|
+
blit_x = NUM2INT(rb_ary_entry(vdest,0));
|
434
|
+
blit_y = NUM2INT(rb_ary_entry(vdest,1));
|
435
|
+
|
436
|
+
/* did we get a src_rect argument or not? */
|
437
|
+
if( !NIL_P(vsource) )
|
438
|
+
{
|
439
|
+
/* it might be good to check that it's actually a rect */
|
440
|
+
vsource = convert_to_array(vsource);
|
441
|
+
src_x = NUM2INT( rb_ary_entry(vsource,0) );
|
442
|
+
src_y = NUM2INT( rb_ary_entry(vsource,1) );
|
443
|
+
src_w = NUM2INT( rb_ary_entry(vsource,2) );
|
444
|
+
src_h = NUM2INT( rb_ary_entry(vsource,3) );
|
445
|
+
}
|
446
|
+
else
|
447
|
+
{
|
448
|
+
src_x = 0;
|
449
|
+
src_y = 0;
|
450
|
+
src_w = src->w;
|
451
|
+
src_h = src->h;
|
452
|
+
}
|
453
|
+
src_rect = make_rect( src_x, src_y, src_w, src_h );
|
454
|
+
|
455
|
+
/* experimental (broken) rectangle cropping code */
|
456
|
+
/* crop if it went off left/top/right/bottom */
|
457
|
+
//left = max(blit_x,0);
|
458
|
+
//top = max(blit_y,0);
|
459
|
+
//right = min(blit_x+src_w,dest->w);
|
460
|
+
//bottom = min(blit_y+src_h,dest->h);
|
461
|
+
|
462
|
+
left = blit_x;
|
463
|
+
top = blit_y;
|
464
|
+
right = blit_x+src_w;
|
465
|
+
bottom = blit_y+src_h;
|
466
|
+
|
467
|
+
//blit_w = min(blit_x+blit_w,dest->w) - max(blit_x,0);
|
468
|
+
//blit_h = min(blit_y+blit_h,dest->h) - max(blit_y,0);
|
469
|
+
blit_w = right - left;
|
470
|
+
blit_h = bottom - top;
|
471
|
+
|
472
|
+
blit_rect = make_rect( left, top, blit_w, blit_h );
|
473
|
+
|
474
|
+
SDL_BlitSurface(src,src_rect,dest,blit_rect);
|
475
|
+
|
476
|
+
returnrect = rb_funcall(cRect,rb_intern("new"),4,
|
477
|
+
INT2NUM(left),INT2NUM(top),\
|
478
|
+
INT2NUM(blit_w),INT2NUM(blit_h));
|
479
|
+
|
480
|
+
free(blit_rect);
|
481
|
+
free(src_rect);
|
482
|
+
return returnrect;
|
483
|
+
}
|
484
|
+
|
485
|
+
/*
|
486
|
+
* call-seq:
|
487
|
+
* fill(color,rect=nil)
|
488
|
+
*
|
489
|
+
* Fill all or part of a Surface with a color.
|
490
|
+
*
|
491
|
+
* This method takes these arguments:
|
492
|
+
* color:: color to fill with, in the form +[r,g,b]+ or +[r,g,b,a]+ (for
|
493
|
+
* partially transparent fills).
|
494
|
+
* rect:: a Rubygame::Rect representing the area of the surface to fill
|
495
|
+
* with color. Omit to fill the entire surface.
|
496
|
+
*/
|
497
|
+
VALUE rbgm_surface_fill( int argc, VALUE *argv, VALUE self )
|
498
|
+
{
|
499
|
+
SDL_Surface *surf;
|
500
|
+
SDL_Rect *rect;
|
501
|
+
Uint32 color;
|
502
|
+
Uint8 r,g,b,a;
|
503
|
+
VALUE vcolor, vrect;
|
504
|
+
|
505
|
+
Data_Get_Struct(self, SDL_Surface, surf);
|
506
|
+
|
507
|
+
rb_scan_args(argc, argv, "11", &vcolor, &vrect);
|
508
|
+
|
509
|
+
vcolor = convert_color(vcolor);
|
510
|
+
extract_rgba_u8_as_u8(vcolor, &r, &g, &b, &a);
|
511
|
+
color = SDL_MapRGBA(surf->format, r,g,b,a);
|
512
|
+
|
513
|
+
if( NIL_P(vrect) )
|
514
|
+
{
|
515
|
+
SDL_FillRect(surf,NULL,color);
|
516
|
+
}
|
517
|
+
else
|
518
|
+
{
|
519
|
+
vrect = convert_to_array(vrect);
|
520
|
+
|
521
|
+
rect = make_rect(\
|
522
|
+
NUM2INT(rb_ary_entry(vrect,0)),\
|
523
|
+
NUM2INT(rb_ary_entry(vrect,1)),\
|
524
|
+
NUM2INT(rb_ary_entry(vrect,2)),\
|
525
|
+
NUM2INT(rb_ary_entry(vrect,3))\
|
526
|
+
);
|
527
|
+
SDL_FillRect(surf,rect,color);
|
528
|
+
free(rect);
|
529
|
+
}
|
530
|
+
|
531
|
+
return self;
|
532
|
+
}
|
533
|
+
|
534
|
+
/*
|
535
|
+
* call-seq:
|
536
|
+
* get_at(x,y)
|
537
|
+
* get_at([x,y]) # deprecated
|
538
|
+
*
|
539
|
+
* Return the color [r,g,b,a] of the pixel at the given coordinate.
|
540
|
+
*
|
541
|
+
* Raises IndexError if the coordinates are out of bounds.
|
542
|
+
*/
|
543
|
+
VALUE rbgm_surface_getat( int argc, VALUE *argv, VALUE self )
|
544
|
+
{
|
545
|
+
SDL_Surface *surf;
|
546
|
+
int x, y, locked;
|
547
|
+
Uint32 color;
|
548
|
+
Uint8 *pixels, *pix;
|
549
|
+
Uint8 r,g,b,a;
|
550
|
+
VALUE vx, vy;
|
551
|
+
|
552
|
+
Data_Get_Struct(self, SDL_Surface, surf);
|
553
|
+
|
554
|
+
rb_scan_args(argc, argv, "11", &vx, &vy);
|
555
|
+
|
556
|
+
/* Still support passing position as an Array... for now. */
|
557
|
+
switch( TYPE(vx) )
|
558
|
+
{
|
559
|
+
case T_ARRAY: {
|
560
|
+
x = NUM2INT( rb_ary_entry(vx,0) );
|
561
|
+
y = NUM2INT( rb_ary_entry(vx,1) );
|
562
|
+
break;
|
563
|
+
}
|
564
|
+
default: {
|
565
|
+
x = NUM2INT(vx);
|
566
|
+
y = NUM2INT(vy);
|
567
|
+
break;
|
568
|
+
}
|
569
|
+
}
|
570
|
+
|
571
|
+
if( x < 0 || x > surf->w )
|
572
|
+
rb_raise(rb_eIndexError,"x index out of bounds (%d, min 0, max %d)",\
|
573
|
+
x,surf->w);
|
574
|
+
if( y < 0 || y > surf->h )
|
575
|
+
rb_raise(rb_eIndexError,"y index out of bounds (%d, min 0, max %d)",\
|
576
|
+
y,surf->h);
|
577
|
+
|
578
|
+
locked = 0;
|
579
|
+
/* lock surface */
|
580
|
+
if(SDL_MUSTLOCK(surf))
|
581
|
+
{
|
582
|
+
if(SDL_LockSurface(surf)==0)
|
583
|
+
locked += 1;
|
584
|
+
else
|
585
|
+
rb_raise(eSDLError,"could not lock surface: %s",SDL_GetError());
|
586
|
+
}
|
587
|
+
|
588
|
+
/* borrowed from pygame */
|
589
|
+
pixels = (Uint8 *) surf->pixels;
|
590
|
+
|
591
|
+
switch(surf->format->BytesPerPixel)
|
592
|
+
{
|
593
|
+
case 1:
|
594
|
+
color = (Uint32)*((Uint8 *)(pixels + y * surf->pitch) + x);
|
595
|
+
break;
|
596
|
+
case 2:
|
597
|
+
color = (Uint32)*((Uint16 *)(pixels + y * surf->pitch) + x);
|
598
|
+
break;
|
599
|
+
case 3:
|
600
|
+
pix = ((Uint8 *)(pixels + y * surf->pitch) + x * 3);
|
601
|
+
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
|
602
|
+
color = (pix[0]) + (pix[1]<<8) + (pix[2]<<16);
|
603
|
+
#else
|
604
|
+
color = (pix[2]) + (pix[1]<<8) + (pix[0]<<16);
|
605
|
+
#endif
|
606
|
+
break;
|
607
|
+
default: /*case 4:*/
|
608
|
+
color = *((Uint32*)(pixels + y * surf->pitch) + x);
|
609
|
+
break;
|
610
|
+
}
|
611
|
+
|
612
|
+
/* end borrowed from pygame */
|
613
|
+
|
614
|
+
/* recursively unlock surface*/
|
615
|
+
while(locked>1)
|
616
|
+
{
|
617
|
+
SDL_UnlockSurface(surf);
|
618
|
+
locked -= 1;
|
619
|
+
}
|
620
|
+
|
621
|
+
if((int *)color == NULL)
|
622
|
+
{
|
623
|
+
VALUE zero = INT2NUM(0);
|
624
|
+
return rb_ary_new3(4,zero,zero,zero,zero);
|
625
|
+
}
|
626
|
+
|
627
|
+
SDL_GetRGBA(color, surf->format, &r, &g, &b, &a);
|
628
|
+
return rb_ary_new3(4,UINT2NUM(r),UINT2NUM(g),UINT2NUM(b),UINT2NUM(a));
|
629
|
+
}
|
630
|
+
|
631
|
+
|
632
|
+
/*
|
633
|
+
* call-seq:
|
634
|
+
* set_at([x,y], color)
|
635
|
+
*
|
636
|
+
* Set the color of the pixel at the given coordinate.
|
637
|
+
*
|
638
|
+
* color can be one of:
|
639
|
+
* * an Array, [r,g,b] or [r,g,b,a] with each component in 0-255
|
640
|
+
* * an instance of ColorRGB, ColorHSV, etc.
|
641
|
+
* * the name of a color in Rubygame::Color, as a Symbol or String
|
642
|
+
*
|
643
|
+
* Raises IndexError if the coordinates are out of bounds.
|
644
|
+
*
|
645
|
+
*--
|
646
|
+
*
|
647
|
+
* I'm lazy and just using SDL_FillRect. ;-P
|
648
|
+
* It's easier and less bug-prone this way.
|
649
|
+
* I have no idea about speed comparisons.
|
650
|
+
*
|
651
|
+
*/
|
652
|
+
VALUE rbgm_surface_setat( int argc, VALUE *argv, VALUE self )
|
653
|
+
{
|
654
|
+
SDL_Surface *surf;
|
655
|
+
SDL_Rect *rect;
|
656
|
+
Uint32 color;
|
657
|
+
Uint8 r,g,b,a;
|
658
|
+
VALUE vpos, vcolor;
|
659
|
+
|
660
|
+
Data_Get_Struct(self, SDL_Surface, surf);
|
661
|
+
|
662
|
+
rb_scan_args(argc, argv, "2", &vpos, &vcolor);
|
663
|
+
|
664
|
+
vcolor = convert_color(vcolor);
|
665
|
+
extract_rgba_u8_as_u8(vcolor, &r, &g, &b, &a);
|
666
|
+
color = SDL_MapRGBA(surf->format, r,g,b,a);
|
667
|
+
|
668
|
+
vpos = convert_to_array(vpos);
|
669
|
+
rect = make_rect( NUM2INT(rb_ary_entry(vpos,0)),
|
670
|
+
NUM2INT(rb_ary_entry(vpos,1)),
|
671
|
+
1, 1 );
|
672
|
+
|
673
|
+
SDL_FillRect(surf,rect,color);
|
674
|
+
|
675
|
+
free(rect);
|
676
|
+
|
677
|
+
return self;
|
678
|
+
}
|
679
|
+
|
680
|
+
|
681
|
+
|
682
|
+
/*
|
683
|
+
* call-seq:
|
684
|
+
* pixels -> String
|
685
|
+
*
|
686
|
+
* Return a string of pixel data for the Surface. Most users will not
|
687
|
+
* need to use this method. If you want to convert a Surface into an
|
688
|
+
* OpenGL texture, pass the returned string to the TexImage2D method
|
689
|
+
* of the ruby-opengl library. (See samples/demo_gl_tex.rb for an example.)
|
690
|
+
*
|
691
|
+
* (Please note that the dimensions of OpenGL textures must be powers of 2
|
692
|
+
* (e.g. 64x128, 512x512), so if you want to use a Surface as an OpenGL
|
693
|
+
* texture, the Surface's dimensions must also be powers of 2!)
|
694
|
+
*/
|
695
|
+
VALUE rbgm_surface_pixels( VALUE self )
|
696
|
+
{
|
697
|
+
SDL_Surface *surf;
|
698
|
+
Data_Get_Struct(self, SDL_Surface, surf);
|
699
|
+
return rb_str_new(surf->pixels, (long)surf->pitch * surf->h);
|
700
|
+
}
|
701
|
+
|
702
|
+
/*
|
703
|
+
* call-seq:
|
704
|
+
* clip -> Rect
|
705
|
+
*
|
706
|
+
* Return the clipping area for this Surface. See also #cliprect=.
|
707
|
+
*
|
708
|
+
* The clipping area of a Surface is the only part which can be drawn upon
|
709
|
+
* by other Surface's #blits. By default, the clipping area is the entire area
|
710
|
+
* of the Surface.
|
711
|
+
*/
|
712
|
+
VALUE rbgm_surface_get_clip( VALUE self )
|
713
|
+
{
|
714
|
+
SDL_Rect rect;
|
715
|
+
SDL_Surface *surf;
|
716
|
+
Data_Get_Struct(self, SDL_Surface, surf);
|
717
|
+
|
718
|
+
SDL_GetClipRect(surf, &rect);
|
719
|
+
|
720
|
+
return rb_funcall(cRect,rb_intern("new"),4,
|
721
|
+
INT2NUM(rect.x),INT2NUM(rect.y),
|
722
|
+
INT2NUM(rect.w),INT2NUM(rect.h));
|
723
|
+
}
|
724
|
+
|
725
|
+
/*
|
726
|
+
* call-seq:
|
727
|
+
* clip = Rect or nil
|
728
|
+
*
|
729
|
+
* Set the current clipping area of the Surface. See also #cliprect.
|
730
|
+
*
|
731
|
+
* The clipping area of a Surface is the only part which can be drawn upon
|
732
|
+
* by other Surface's #blits. The clipping area will be clipped to the edges
|
733
|
+
* of the surface so that the clipping area for a Surface can never fall
|
734
|
+
* outside the edges of the Surface.
|
735
|
+
*
|
736
|
+
* By default, the clipping area is the entire area of the Surface.
|
737
|
+
* You may set clip to +nil+, which will reset the clipping area to cover
|
738
|
+
* the entire Surface.
|
739
|
+
*/
|
740
|
+
VALUE rbgm_surface_set_clip( VALUE self, VALUE clip )
|
741
|
+
{
|
742
|
+
SDL_Rect *rect;
|
743
|
+
SDL_Surface *surf;
|
744
|
+
Data_Get_Struct(self, SDL_Surface, surf);
|
745
|
+
|
746
|
+
|
747
|
+
if( NIL_P(clip) )
|
748
|
+
{
|
749
|
+
SDL_SetClipRect(surf,NULL);
|
750
|
+
}
|
751
|
+
else
|
752
|
+
{
|
753
|
+
clip = convert_to_array(clip);
|
754
|
+
rect = make_rect(\
|
755
|
+
NUM2INT(rb_ary_entry(clip,0)),\
|
756
|
+
NUM2INT(rb_ary_entry(clip,1)),\
|
757
|
+
NUM2INT(rb_ary_entry(clip,2)),\
|
758
|
+
NUM2INT(rb_ary_entry(clip,3))\
|
759
|
+
);
|
760
|
+
|
761
|
+
SDL_SetClipRect(surf,rect);
|
762
|
+
free(rect);
|
763
|
+
}
|
764
|
+
|
765
|
+
return self;
|
766
|
+
}
|
767
|
+
|
768
|
+
/*
|
769
|
+
* call-seq:
|
770
|
+
* convert( other=nil, flags=nil ) -> Surface
|
771
|
+
*
|
772
|
+
* Copies the Surface to a new Surface with the pixel format of another
|
773
|
+
* Surface, for fast blitting. May raise SDLError if a problem occurs.
|
774
|
+
*
|
775
|
+
* This method takes these arguments:
|
776
|
+
* - other:: The Surface to match pixel format against. If +nil+, the
|
777
|
+
* display surface (i.e. Screen) is used, if available; if no
|
778
|
+
* display surface is available, raises SDLError.
|
779
|
+
* - flags:: An array of flags to pass when the new Surface is created.
|
780
|
+
* See Surface#new.
|
781
|
+
*
|
782
|
+
*/
|
783
|
+
VALUE rbgm_surface_convert(int argc, VALUE *argv, VALUE self)
|
784
|
+
{
|
785
|
+
SDL_Surface *surf, *othersurf, *newsurf;
|
786
|
+
Uint32 flags = 0;
|
787
|
+
VALUE vother, vflags;
|
788
|
+
|
789
|
+
Data_Get_Struct(self, SDL_Surface, surf);
|
790
|
+
|
791
|
+
rb_scan_args(argc, argv, "02", &vother, &vflags );
|
792
|
+
|
793
|
+
if( !NIL_P(vother) )
|
794
|
+
{
|
795
|
+
Data_Get_Struct(vother, SDL_Surface, othersurf);
|
796
|
+
}
|
797
|
+
else
|
798
|
+
{
|
799
|
+
othersurf = SDL_GetVideoSurface();
|
800
|
+
if( othersurf == NULL )
|
801
|
+
{
|
802
|
+
rb_raise(eSDLError, "Cannot convert Surface with no target given and no Screen made: %s", SDL_GetError());
|
803
|
+
}
|
804
|
+
}
|
805
|
+
|
806
|
+
flags = collapse_flags(vflags); /* in rubygame_shared.c */
|
807
|
+
|
808
|
+
if( init_video_system() == 0 )
|
809
|
+
{
|
810
|
+
newsurf = SDL_ConvertSurface( surf, othersurf->format, flags );
|
811
|
+
}
|
812
|
+
else
|
813
|
+
{
|
814
|
+
newsurf = NULL;
|
815
|
+
}
|
816
|
+
|
817
|
+
if( newsurf == NULL )
|
818
|
+
{
|
819
|
+
rb_raise(eSDLError,\
|
820
|
+
"Could not convert the Surface: %s",\
|
821
|
+
SDL_GetError());
|
822
|
+
}
|
823
|
+
|
824
|
+
return Data_Wrap_Struct( cSurface,0,SDL_FreeSurface,newsurf );
|
825
|
+
}
|
826
|
+
|
827
|
+
/*
|
828
|
+
* call-seq:
|
829
|
+
* to_display() -> Surface
|
830
|
+
*
|
831
|
+
* Copies the Surface to a new Surface with the pixel format of the display,
|
832
|
+
* suitable for fast blitting to the display surface (i.e. Screen).
|
833
|
+
* May raise SDLError if a problem occurs.
|
834
|
+
*
|
835
|
+
* If you want to take advantage of hardware colorkey or alpha blit
|
836
|
+
* acceleration, you should set the colorkey and alpha value before calling
|
837
|
+
* this function.
|
838
|
+
*
|
839
|
+
*/
|
840
|
+
VALUE rbgm_surface_dispform(VALUE self)
|
841
|
+
{
|
842
|
+
SDL_Surface *surf, *newsurf;
|
843
|
+
Data_Get_Struct(self, SDL_Surface, surf);
|
844
|
+
|
845
|
+
if( init_video_system() == 0 )
|
846
|
+
{
|
847
|
+
newsurf = SDL_DisplayFormat( surf );
|
848
|
+
}
|
849
|
+
else
|
850
|
+
{
|
851
|
+
newsurf = NULL;
|
852
|
+
}
|
853
|
+
|
854
|
+
if( newsurf == NULL )
|
855
|
+
{
|
856
|
+
rb_raise(eSDLError,\
|
857
|
+
"Could not convert the Surface to display format: %s",\
|
858
|
+
SDL_GetError());
|
859
|
+
}
|
860
|
+
|
861
|
+
return Data_Wrap_Struct( cSurface,0,SDL_FreeSurface,newsurf );
|
862
|
+
}
|
863
|
+
|
864
|
+
/*
|
865
|
+
* call-seq:
|
866
|
+
* to_display_alpha() -> Surface
|
867
|
+
*
|
868
|
+
* Like #to_display except the Surface has an extra channel for alpha (i.e.
|
869
|
+
* opacity). May raise SDLError if a problem occurs.
|
870
|
+
*
|
871
|
+
* This function can be used to convert a colorkey to an alpha channel, if the
|
872
|
+
* SRCCOLORKEY flag is set on the surface. The generated surface will then be
|
873
|
+
* transparent (alpha=0) where the pixels match the colorkey, and opaque
|
874
|
+
* (alpha=255) elsewhere.
|
875
|
+
*/
|
876
|
+
VALUE rbgm_surface_dispformalpha(VALUE self)
|
877
|
+
{
|
878
|
+
SDL_Surface *surf, *newsurf;
|
879
|
+
Data_Get_Struct(self, SDL_Surface, surf);
|
880
|
+
|
881
|
+
if( init_video_system() == 0 )
|
882
|
+
{
|
883
|
+
newsurf = SDL_DisplayFormatAlpha( surf );
|
884
|
+
}
|
885
|
+
else
|
886
|
+
{
|
887
|
+
newsurf = NULL;
|
888
|
+
}
|
889
|
+
|
890
|
+
if( newsurf == NULL )
|
891
|
+
{
|
892
|
+
rb_raise(eSDLError,\
|
893
|
+
"Could not convert the Surface to display format with alpha channel: %s",\
|
894
|
+
SDL_GetError());
|
895
|
+
}
|
896
|
+
|
897
|
+
return Data_Wrap_Struct( cSurface,0,SDL_FreeSurface,newsurf );
|
898
|
+
}
|
899
|
+
|
900
|
+
|
901
|
+
/*
|
902
|
+
* call-seq:
|
903
|
+
* savebmp( filename ) -> nil
|
904
|
+
*
|
905
|
+
* Save the Surface as a Windows Bitmap (BMP) file with the given filename.
|
906
|
+
*/
|
907
|
+
VALUE rbgm_image_savebmp( VALUE self, VALUE filename )
|
908
|
+
{
|
909
|
+
char *name;
|
910
|
+
SDL_Surface *surf;
|
911
|
+
|
912
|
+
name = StringValuePtr(filename);
|
913
|
+
Data_Get_Struct(self,SDL_Surface,surf);
|
914
|
+
if(SDL_SaveBMP(surf,name)!=0)
|
915
|
+
{
|
916
|
+
rb_raise(eSDLError,\
|
917
|
+
"Couldn't save surface to file %s: %s",name,SDL_GetError());
|
918
|
+
}
|
919
|
+
return Qnil;
|
920
|
+
}
|
921
|
+
|
922
|
+
|
923
|
+
/* --
|
924
|
+
* Borrowed from Pygame:
|
925
|
+
* ++
|
926
|
+
*/
|
927
|
+
static SDL_Surface* newsurf_fromsurf(SDL_Surface* surf, int width, int height)
|
928
|
+
{
|
929
|
+
SDL_Surface* newsurf;
|
930
|
+
|
931
|
+
if(surf->format->BytesPerPixel <= 0 || surf->format->BytesPerPixel > 4)
|
932
|
+
rb_raise(eSDLError,"unsupported Surface bit depth for transform");
|
933
|
+
|
934
|
+
newsurf = SDL_CreateRGBSurface(surf->flags, width, height, surf->format->BitsPerPixel,
|
935
|
+
surf->format->Rmask, surf->format->Gmask, surf->format->Bmask, surf->format->Amask);
|
936
|
+
if(!newsurf)
|
937
|
+
rb_raise(eSDLError,"%s",SDL_GetError());
|
938
|
+
|
939
|
+
/* Copy palette, colorkey, etc info */
|
940
|
+
if(surf->format->BytesPerPixel==1 && surf->format->palette)
|
941
|
+
SDL_SetColors(newsurf, surf->format->palette->colors, 0, surf->format->palette->ncolors);
|
942
|
+
if(surf->flags & SDL_SRCCOLORKEY)
|
943
|
+
SDL_SetColorKey(newsurf, (surf->flags&SDL_RLEACCEL)|SDL_SRCCOLORKEY, surf->format->colorkey);
|
944
|
+
|
945
|
+
return newsurf;
|
946
|
+
}
|
947
|
+
|
948
|
+
/*
|
949
|
+
* call-seq:
|
950
|
+
* flip(horz, vert) -> Surface
|
951
|
+
*
|
952
|
+
* Flips the source surface horizontally (if +horz+ is true), vertically
|
953
|
+
* (if +vert+ is true), or both (if both are true). This operation is
|
954
|
+
* non-destructive; the original image can be perfectly reconstructed by
|
955
|
+
* flipping the resultant image again.
|
956
|
+
*
|
957
|
+
* This operation does NOT require SDL_gfx.
|
958
|
+
*
|
959
|
+
* A similar effect can (supposedly) be achieved by giving X or Y zoom
|
960
|
+
* factors of -1 to #rotozoom (only if compiled with SDL_gfx 2.0.13 or
|
961
|
+
* greater). Your mileage may vary.
|
962
|
+
*/
|
963
|
+
VALUE rbgm_transform_flip(VALUE self, VALUE vhorz, VALUE vvert)
|
964
|
+
{
|
965
|
+
SDL_Surface *surf, *newsurf;
|
966
|
+
int xaxis, yaxis;
|
967
|
+
|
968
|
+
int loopx, loopy;
|
969
|
+
int pixsize, srcpitch, dstpitch;
|
970
|
+
Uint8 *srcpix, *dstpix;
|
971
|
+
|
972
|
+
xaxis = RTEST(vhorz);
|
973
|
+
yaxis = RTEST(vvert);
|
974
|
+
|
975
|
+
Data_Get_Struct(self,SDL_Surface,surf);
|
976
|
+
|
977
|
+
/* Borrowed from Pygame: */
|
978
|
+
newsurf = newsurf_fromsurf(surf, surf->w, surf->h);
|
979
|
+
if(!newsurf)
|
980
|
+
return Qnil;
|
981
|
+
|
982
|
+
pixsize = surf->format->BytesPerPixel;
|
983
|
+
srcpitch = surf->pitch;
|
984
|
+
dstpitch = newsurf->pitch;
|
985
|
+
|
986
|
+
SDL_LockSurface(newsurf);
|
987
|
+
|
988
|
+
srcpix = (Uint8*)surf->pixels;
|
989
|
+
dstpix = (Uint8*)newsurf->pixels;
|
990
|
+
|
991
|
+
if(!xaxis)
|
992
|
+
{
|
993
|
+
if(!yaxis)
|
994
|
+
{
|
995
|
+
for(loopy = 0; loopy < surf->h; ++loopy)
|
996
|
+
memcpy(dstpix+loopy*dstpitch, srcpix+loopy*srcpitch, surf->w*surf->format->BytesPerPixel);
|
997
|
+
}
|
998
|
+
else
|
999
|
+
{
|
1000
|
+
for(loopy = 0; loopy < surf->h; ++loopy)
|
1001
|
+
memcpy(dstpix+loopy*dstpitch, srcpix+(surf->h-1-loopy)*srcpitch, surf->w*surf->format->BytesPerPixel);
|
1002
|
+
}
|
1003
|
+
}
|
1004
|
+
else /*if (xaxis)*/
|
1005
|
+
{
|
1006
|
+
if(yaxis)
|
1007
|
+
{
|
1008
|
+
switch(surf->format->BytesPerPixel)
|
1009
|
+
{
|
1010
|
+
case 1:
|
1011
|
+
for(loopy = 0; loopy < surf->h; ++loopy) {
|
1012
|
+
Uint8* dst = (Uint8*)(dstpix+loopy*dstpitch);
|
1013
|
+
Uint8* src = ((Uint8*)(srcpix+(surf->h-1-loopy)*srcpitch)) + surf->w - 1;
|
1014
|
+
for(loopx = 0; loopx < surf->w; ++loopx)
|
1015
|
+
*dst++ = *src--;
|
1016
|
+
}break;
|
1017
|
+
case 2:
|
1018
|
+
for(loopy = 0; loopy < surf->h; ++loopy) {
|
1019
|
+
Uint16* dst = (Uint16*)(dstpix+loopy*dstpitch);
|
1020
|
+
Uint16* src = ((Uint16*)(srcpix+(surf->h-1-loopy)*srcpitch)) + surf->w - 1;
|
1021
|
+
for(loopx = 0; loopx < surf->w; ++loopx)
|
1022
|
+
*dst++ = *src--;
|
1023
|
+
}break;
|
1024
|
+
case 4:
|
1025
|
+
for(loopy = 0; loopy < surf->h; ++loopy) {
|
1026
|
+
Uint32* dst = (Uint32*)(dstpix+loopy*dstpitch);
|
1027
|
+
Uint32* src = ((Uint32*)(srcpix+(surf->h-1-loopy)*srcpitch)) + surf->w - 1;
|
1028
|
+
for(loopx = 0; loopx < surf->w; ++loopx)
|
1029
|
+
*dst++ = *src--;
|
1030
|
+
}break;
|
1031
|
+
case 3:
|
1032
|
+
for(loopy = 0; loopy < surf->h; ++loopy) {
|
1033
|
+
Uint8* dst = (Uint8*)(dstpix+loopy*dstpitch);
|
1034
|
+
Uint8* src = ((Uint8*)(srcpix+(surf->h-1-loopy)*srcpitch)) + surf->w*3 - 3;
|
1035
|
+
for(loopx = 0; loopx < surf->w; ++loopx)
|
1036
|
+
{
|
1037
|
+
dst[0] = src[0]; dst[1] = src[1]; dst[2] = src[2];
|
1038
|
+
dst += 3;
|
1039
|
+
src -= 3;
|
1040
|
+
}
|
1041
|
+
}break;
|
1042
|
+
}
|
1043
|
+
}
|
1044
|
+
else
|
1045
|
+
{
|
1046
|
+
switch(surf->format->BytesPerPixel)
|
1047
|
+
{
|
1048
|
+
case 1:
|
1049
|
+
for(loopy = 0; loopy < surf->h; ++loopy) {
|
1050
|
+
Uint8* dst = (Uint8*)(dstpix+loopy*dstpitch);
|
1051
|
+
Uint8* src = ((Uint8*)(srcpix+loopy*srcpitch)) + surf->w - 1;
|
1052
|
+
for(loopx = 0; loopx < surf->w; ++loopx)
|
1053
|
+
*dst++ = *src--;
|
1054
|
+
}break;
|
1055
|
+
case 2:
|
1056
|
+
for(loopy = 0; loopy < surf->h; ++loopy) {
|
1057
|
+
Uint16* dst = (Uint16*)(dstpix+loopy*dstpitch);
|
1058
|
+
Uint16* src = ((Uint16*)(srcpix+loopy*srcpitch)) + surf->w - 1;
|
1059
|
+
for(loopx = 0; loopx < surf->w; ++loopx)
|
1060
|
+
*dst++ = *src--;
|
1061
|
+
}break;
|
1062
|
+
case 4:
|
1063
|
+
for(loopy = 0; loopy < surf->h; ++loopy) {
|
1064
|
+
Uint32* dst = (Uint32*)(dstpix+loopy*dstpitch);
|
1065
|
+
Uint32* src = ((Uint32*)(srcpix+loopy*srcpitch)) + surf->w - 1;
|
1066
|
+
for(loopx = 0; loopx < surf->w; ++loopx)
|
1067
|
+
*dst++ = *src--;
|
1068
|
+
}break;
|
1069
|
+
case 3:
|
1070
|
+
for(loopy = 0; loopy < surf->h; ++loopy) {
|
1071
|
+
Uint8* dst = (Uint8*)(dstpix+loopy*dstpitch);
|
1072
|
+
Uint8* src = ((Uint8*)(srcpix+loopy*srcpitch)) + surf->w*3 - 3;
|
1073
|
+
for(loopx = 0; loopx < surf->w; ++loopx)
|
1074
|
+
{
|
1075
|
+
dst[0] = src[0]; dst[1] = src[1]; dst[2] = src[2];
|
1076
|
+
dst += 3;
|
1077
|
+
src -= 3;
|
1078
|
+
}
|
1079
|
+
}break;
|
1080
|
+
}
|
1081
|
+
}
|
1082
|
+
}
|
1083
|
+
|
1084
|
+
SDL_UnlockSurface(newsurf);
|
1085
|
+
/* Thanks, Pygame :) */
|
1086
|
+
|
1087
|
+
|
1088
|
+
if(newsurf == NULL)
|
1089
|
+
rb_raise(eSDLError,"Could not flip surface: %s",SDL_GetError());
|
1090
|
+
return Data_Wrap_Struct(cSurface,0,SDL_FreeSurface,newsurf);
|
1091
|
+
}
|
1092
|
+
|
1093
|
+
/*
|
1094
|
+
* See rubygame_image.c for the Surface class overview docs.
|
1095
|
+
* I hate RDoc's C parser.
|
1096
|
+
*
|
1097
|
+
*/
|
1098
|
+
void Rubygame_Init_Surface()
|
1099
|
+
{
|
1100
|
+
|
1101
|
+
#if 0
|
1102
|
+
mRubygame = rb_define_module("Rubygame");
|
1103
|
+
cSurface = rb_define_class_under(mRubygame,"Surface",rb_cObject);
|
1104
|
+
#endif
|
1105
|
+
|
1106
|
+
rb_define_singleton_method(cSurface,"new",rbgm_surface_new,-1);
|
1107
|
+
rb_define_method(cSurface,"initialize",rbgm_surface_initialize,-1);
|
1108
|
+
rb_define_method(cSurface,"w",rbgm_surface_get_w,0);
|
1109
|
+
rb_define_alias(cSurface,"width","w");
|
1110
|
+
rb_define_method(cSurface,"h",rbgm_surface_get_h,0);
|
1111
|
+
rb_define_alias(cSurface,"height","h");
|
1112
|
+
rb_define_method(cSurface,"size",rbgm_surface_get_size,0);
|
1113
|
+
rb_define_method(cSurface,"depth",rbgm_surface_get_depth,0);
|
1114
|
+
rb_define_method(cSurface,"flags",rbgm_surface_get_flags,0);
|
1115
|
+
rb_define_method(cSurface,"masks",rbgm_surface_get_masks,0);
|
1116
|
+
rb_define_method(cSurface,"alpha",rbgm_surface_get_alpha,0);
|
1117
|
+
rb_define_method(cSurface,"set_alpha",rbgm_surface_set_alpha,-1);
|
1118
|
+
rb_define_method(cSurface,"colorkey",rbgm_surface_get_colorkey,0);
|
1119
|
+
rb_define_method(cSurface,"set_colorkey",rbgm_surface_set_colorkey,-1);
|
1120
|
+
rb_define_method(cSurface,"blit",rbgm_surface_blit,-1);
|
1121
|
+
rb_define_method(cSurface,"fill",rbgm_surface_fill,-1);
|
1122
|
+
rb_define_method(cSurface,"get_at",rbgm_surface_getat,-1);
|
1123
|
+
rb_define_method(cSurface,"set_at",rbgm_surface_setat,-1);
|
1124
|
+
rb_define_method(cSurface,"pixels",rbgm_surface_pixels,0);
|
1125
|
+
rb_define_method(cSurface,"clip",rbgm_surface_get_clip,0);
|
1126
|
+
rb_define_method(cSurface,"clip=",rbgm_surface_set_clip,1);
|
1127
|
+
rb_define_method(cSurface,"convert",rbgm_surface_convert,-1);
|
1128
|
+
rb_define_method(cSurface,"to_display",rbgm_surface_dispform,0);
|
1129
|
+
rb_define_method(cSurface,"to_display_alpha",rbgm_surface_dispformalpha,0);
|
1130
|
+
rb_define_method(cSurface,"savebmp",rbgm_image_savebmp,1);
|
1131
|
+
rb_define_method(cSurface,"flip",rbgm_transform_flip,2);
|
1132
|
+
|
1133
|
+
|
1134
|
+
/* Include the Rubygame::NamedResource mixin module. */
|
1135
|
+
rg_include_named_resource(cSurface);
|
1136
|
+
|
1137
|
+
|
1138
|
+
/* Surface initialization flags */
|
1139
|
+
rb_define_const(mRubygame,"SWSURFACE",UINT2NUM(SDL_SWSURFACE));
|
1140
|
+
rb_define_const(mRubygame,"HWSURFACE",UINT2NUM(SDL_HWSURFACE));
|
1141
|
+
rb_define_const(mRubygame,"ASYNCBLIT",UINT2NUM(SDL_ASYNCBLIT));
|
1142
|
+
rb_define_const(mRubygame,"ANYFORMAT",UINT2NUM(SDL_ANYFORMAT));
|
1143
|
+
rb_define_const(mRubygame,"HWPALETTE",UINT2NUM(SDL_HWPALETTE));
|
1144
|
+
rb_define_const(mRubygame,"HWACCEL",UINT2NUM(SDL_HWACCEL));
|
1145
|
+
rb_define_const(mRubygame,"SRCCOLORKEY",UINT2NUM(SDL_SRCCOLORKEY));
|
1146
|
+
rb_define_const(mRubygame,"RLEACCELOK",UINT2NUM(SDL_RLEACCELOK));
|
1147
|
+
rb_define_const(mRubygame,"RLEACCEL",UINT2NUM(SDL_RLEACCEL));
|
1148
|
+
rb_define_const(mRubygame,"SRCALPHA",UINT2NUM(SDL_SRCALPHA));
|
1149
|
+
rb_define_const(mRubygame,"PREALLOC",UINT2NUM(SDL_PREALLOC));
|
1150
|
+
|
1151
|
+
}
|