Class: Rubygame::Screen
- Defined in:
- ext/rubygame/rubygame_screen.c,
ext/rubygame/rubygame_screen.c
Overview
Screen represents the display window for the game. The Screen is a special Surface that is displayed to the user. By changing and then updating the Screen many times per second, we can create the illusion of continous motion.
Screen inherits most of the Surface methods, and can be passed to methods which expect a Surface, including Surface#blit and the Draw functions. However, the Screen cannot have a colorkey or an alpha channel, so Surface#set_colorkey and Surface#set_alpha are not inherited.
Please note that only one Screen can exist, per application, at a time; this is a limitation of SDL. You must use Screen.new (or its alias, Screen.open) to create or modify the Screen.
Also note that no changes to the Screen will be seen until it is refreshed. See #update, #update_rects, and #flip for ways to refresh all or part of the Screen.
Class Method Summary collapse
-
.close ⇒ Object
Close the Screen, making the Rubygame window disappear.
-
.get_resolution ⇒ Array
Returns the pixel dimensions of the user’s display (i.e. monitor).
-
.get_surface ⇒ Object
Returns the current display window, or raises SDLError if it fails to get it (for example, if it doesn’t exist yet).
-
.instance(size, depth = 0, flags = [SWSURFACE]) ⇒ Screen
Deprecated alias for Screen.new.
-
.new(size, depth = 0, flags = [SWSURFACE]) ⇒ Screen
Create a new Rubygame window if there is none, or modify the existing one.
-
.open? ⇒ Boolean
True if there is an open Rubygame window.
-
.set_mode(size, depth = 0, flags = [SWSURFACE]) ⇒ Screen
Deprecated alias for Screen.new.
Instance Method Summary collapse
-
#flip ⇒ Object
If the Rubygame display is double-buffered (see Screen.new), flips the buffers and updates the whole screen.
-
#icon=(icon) ⇒ Object
Sets the window icon for the Screen.
-
#show_cursor=(value) ⇒ Boolean
Set whether the mouse cursor is displayed or not.
-
#show_cursor? ⇒ Boolean
Returns true if the mouse cursor is shown, or false if hidden.
-
#title ⇒ String
Returns the current window title for the Screen.
-
#title=(title) ⇒ Object
Sets the window title for the Screen.
-
#update(*args) ⇒ Object
Updates (refreshes) all or part of the Rubygame window, revealing to the user any changes that have been made since the last update.
-
#update_rects(rects) ⇒ Object
Updates (as Screen#update does) several areas of the screen.
Methods inherited from Surface
#alpha, autoload, #blit, #clip, #clip=, #colorkey, #convert, #depth, #draw_arc, #draw_arc_s, #draw_box, #draw_box_s, #draw_circle, #draw_circle_a, #draw_circle_s, #draw_ellipse, #draw_ellipse_a, #draw_ellipse_s, #draw_line, #draw_line_a, #draw_polygon, #draw_polygon_a, #draw_polygon_s, #fill, #flags, #get_at, #h, #initialize, load, load_from_string, load_image, #make_rect, #masks, #pixels, #rotozoom, rotozoom_size, #savebmp, #set_alpha, #set_at, #set_colorkey, #size, #to_display, #to_display_alpha, #w, #zoom, zoom_size, #zoom_to
Constructor Details
This class inherits a constructor from Rubygame::Surface
Class Method Details
.close ⇒ Object
Close the Screen, making the Rubygame window disappear. This method also exits from fullscreen mode, if needed.
After calling this method, you should discard any references to the old Screen surface, as it is no longer valid, even if you call Screen.new again.
(Note: You do not need to close the Screen to change its size or flags, you can simply call Screen.new while already open.)
181 182 183 184 185 |
# File 'ext/rubygame/rubygame_screen.c', line 181
VALUE rbgm_screen_close(VALUE module)
{
SDL_QuitSubSystem(SDL_INIT_VIDEO);
return Qnil;
}
|
.get_resolution ⇒ Array
Returns the pixel dimensions of the user’s display (i.e. monitor). (That is not the same as Screen#size, which only measures the Rubygame window.) You can use this information to detect how large of a Screen can fit on the user’s display.
This method can only be used when there is no open Screen instance. This method raises SDLError if there is a Screen instance (i.e. you have done Screen.new before). This is a limitation of the SDL function SDL_GetVideoInfo, which behaves differently when a Screen is open than when it is closed.
This method will also raise SDLError if it cannot get the display size for some other reason.
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 |
# File 'ext/rubygame/rubygame_screen.c', line 239
VALUE rbgm_screen_getresolution(VALUE module)
{
VALUE array;
const SDL_VideoInfo* hw;
init_video_system();
/* Test for existing Screen */
SDL_Surface *surface;
surface = SDL_GetVideoSurface();
if(surface != NULL)
{
rb_raise(eSDLError, "You cannot get resolution when there is " \
"an open Screen. See the docs for the reason.");
}
hw = SDL_GetVideoInfo();
if(hw==NULL)
{
rb_raise(eSDLError,"Couldn't get video info: %s",SDL_GetError());
}
array = rb_ary_new();
rb_ary_push(array, INT2NUM(hw->current_w));
rb_ary_push(array, INT2NUM(hw->current_h));
return array;
}
|
.get_surface ⇒ Object
Returns the current display window, or raises SDLError if it fails to get it (for example, if it doesn’t exist yet).
209 210 211 212 213 214 215 216 217 218 |
# File 'ext/rubygame/rubygame_screen.c', line 209
VALUE rbgm_screen_getsurface(VALUE module)
{
SDL_Surface *surface;
surface = SDL_GetVideoSurface();
if(surface==NULL)
{
rb_raise(eSDLError,"Couldn't get video surface: %s",SDL_GetError());
}
return Data_Wrap_Struct( cScreen,0,0,surface );
}
|
.instance(size, depth = 0, flags = [SWSURFACE]) ⇒ Screen
Deprecated alias for Screen.new. This method will be REMOVED
in Rubygame 3.0. You should use Screen.new (or its alias, Screen.open)
instead.
159 160 161 162 163 |
# File 'ext/rubygame/rubygame_screen.c', line 159
VALUE rbgm_screen_instance(int argc, VALUE *argv, VALUE module)
{
rg_deprecated("Rubygame::Screen.instance", "3.0");
return rbgm_screen_new(argc, argv, module);
}
|
.new(size, depth = 0, flags = [SWSURFACE]) ⇒ Screen
Create a new Rubygame window if there is none, or modify the existing one.
You cannot create more than one Screen; the existing one will be replaced.
(This is a limitation of SDL.)
Returns the resulting Screen.
This method takes these arguments:
size:: requested window size (in pixels), in the form [width,height]
depth:: requested color depth (in bits per pixel). If 0 (default), the
current system color depth.
flags:: an Array of zero or more of the following flags (located under the
Rubygame module).
SWSURFACE:: Create the video surface in system memory.
HWSURFACE:: Create the video surface in video memory.
ASYNCBLIT:: Enables the use of asynchronous updates of the
display surface. This will usually slow down
blitting on single CPU machines, but may provide a
speed increase on SMP systems.
ANYFORMAT:: Normally, if a video surface of the requested
bits-per-pixel (bpp) is not available, Rubygame
will emulate one with a shadow surface. Passing
+ANYFORMAT+ prevents this and causes Rubygame to
use the video surface regardless of its depth.
DOUBLEBUF:: Enable hardware double buffering; only valid with
+HWSURFACE+. Calling #flip will flip the
buffers and update the screen. All drawing will
take place on the surface that is not displayed at
the moment. If double buffering could not be
enabled then #flip will just update the
entire screen.
FULLSCREEN:: Rubygame will attempt to use a fullscreen mode. If
a hardware resolution change is not possible (for
whatever reason), the next higher resolution will
be used and the display window centered on a black
background.
OPENGL:: Create an OpenGL rendering context. You must set
proper OpenGL video attributes with GL#set_attrib
before calling this method with this flag. You can
then use separate opengl libraries (for example rbogl)
to do all OpenGL-related functions.
Please note that you can't blit or draw regular SDL
Surfaces onto an OpenGL-mode screen; you must use
OpenGL functions.
RESIZABLE:: Create a resizable window. When the window is
resized by the user, a ResizeEvent is
generated and this method can be called again
with the new size.
NOFRAME:: If possible, create a window with no title bar or
frame decoration.
Fullscreen modes automatically have this flag set.
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'ext/rubygame/rubygame_screen.c', line 105
VALUE rbgm_screen_new(int argc, VALUE *argv, VALUE module)
{
SDL_Surface *screen;
int w, h, depth;
Uint32 flags;
VALUE vsize, vdepth, vflags;
rb_scan_args(argc, argv, "12", &vsize, &vdepth, &vflags);
vsize = convert_to_array(vsize);
w = NUM2INT(rb_ary_entry(vsize,0));
h = NUM2INT(rb_ary_entry(vsize,1));
depth = 0;
if( RTEST(vdepth) )
{
depth = NUM2INT(vdepth);
}
flags = collapse_flags(vflags); /* in rubygame_shared */
screen = SDL_SetVideoMode( w,h,depth,flags );
if( screen==NULL )
{
rb_raise(eSDLError,"Couldn't set [%d x %d] %d bpp video mode: %s",
w, h, depth, SDL_GetError());
}
//format = screen->format;
//printf("New screen will be: %dx%d, %d bpp. Masks: %d, %d, %d, %d\n",w,h,depth,format->Rmask,format->Gmask,format->Bmask,format->Amask);
return Data_Wrap_Struct( cScreen,0,0,screen );
}
|
.open? ⇒ Boolean
True if there is an open Rubygame window. See Screen.new and Screen.close.
196 197 198 199 |
# File 'ext/rubygame/rubygame_screen.c', line 196
VALUE rbgm_screen_openp(VALUE module)
{
return (SDL_GetVideoSurface() == NULL) ? Qfalse : Qtrue;
}
|
.set_mode(size, depth = 0, flags = [SWSURFACE]) ⇒ Screen
Deprecated alias for Screen.new. This method will be REMOVED
in Rubygame 3.0. You should use Screen.new (or its alias, Screen.open)
instead.
146 147 148 149 150 |
# File 'ext/rubygame/rubygame_screen.c', line 146
VALUE rbgm_screen_setmode(int argc, VALUE *argv, VALUE module)
{
rg_deprecated("Rubygame::Screen.set_mode", "3.0");
return rbgm_screen_new(argc, argv, module);
}
|
Instance Method Details
#flip ⇒ Object
If the Rubygame display is double-buffered (see Screen.new), flips the buffers and updates the whole screen. Otherwise, just updates the whole screen.
469 470 471 472 473 474 475 |
# File 'ext/rubygame/rubygame_screen.c', line 469
VALUE rbgm_screen_flip(VALUE self)
{
SDL_Surface *screen;
Data_Get_Struct(self, SDL_Surface, screen);
SDL_Flip(screen);
return self;
}
|
#icon=(icon) ⇒ Object
Sets the window icon for the Screen.
- icon
-
a Rubygame::Surface to be displayed at the top of the Rubygame window (when not in fullscreen mode), and in other OS-specific areas (like the taskbar entry). If omitted or
nil, no icon will be shown at all.
NOTE: The SDL docs state that icons on Win32 systems must be 32x32 pixels. That may or may not be true anymore, but you might want to consider it when creating games to run on Windows.
325 326 327 328 329 330 331 332 333 |
# File 'ext/rubygame/rubygame_screen.c', line 325
VALUE rbgm_screen_seticon(VALUE self, VALUE data)
{
SDL_Surface *icon;
Data_Get_Struct(data, SDL_Surface, icon);
SDL_WM_SetIcon(icon, NULL);
return self;
}
|
#show_cursor=(value) ⇒ Boolean
Set whether the mouse cursor is displayed or not. If value is true, the cursor will be shown; if false, it will be hidden. See also #show_cursor?
495 496 497 498 499 500 501 502 503 504 |
# File 'ext/rubygame/rubygame_screen.c', line 495
VALUE rbgm_screen_setshowcursor(VALUE self, VALUE val)
{
int state;
if(val == Qtrue) { state = SDL_ENABLE; }
else if(val == Qfalse || val == Qnil) { state = SDL_DISABLE; }
else { return Qnil; }
return SDL_ShowCursor(state);
}
|
#show_cursor? ⇒ Boolean
Returns true if the mouse cursor is shown, or false if hidden. See also #show_cursor=
483 484 485 486 |
# File 'ext/rubygame/rubygame_screen.c', line 483
VALUE rbgm_screen_getshowcursor(VALUE self)
{
return SDL_ShowCursor(SDL_QUERY);
}
|
#title ⇒ String
Returns the current window title for the Screen. The default is an empty string.
276 277 278 279 280 281 282 283 284 285 |
# File 'ext/rubygame/rubygame_screen.c', line 276
VALUE rbgm_screen_getcaption(VALUE self)
{
char *title,*icon;
SDL_WM_GetCaption( &title,&icon );
if (title == NULL)
title = "\0";
/* We don't really care about icon. */
return rb_str_new2(title);
}
|
#title=(title) ⇒ Object
Sets the window title for the Screen.
- title
-
a String, (usually) displayed at the top of the Rubygame window (when not in fullscreen mode). If omitted or
nil,titlewill be an empty string. How this string is displayed (if at all) is system-dependent.
297 298 299 300 301 302 303 304 305 306 307 308 |
# File 'ext/rubygame/rubygame_screen.c', line 297
VALUE rbgm_screen_setcaption(VALUE self, VALUE title)
{
char *title_str;
title_str = ""; /* default to blank */
if( RTEST(title) )
{
title_str = StringValuePtr(title);
}
SDL_WM_SetCaption(title_str,title_str);
return self;
}
|
#update ⇒ Object #update(rect) ⇒ Object #update(x, y, w, h) ⇒ Object
Updates (refreshes) all or part of the Rubygame window, revealing to the user any changes that have been made since the last update. If you’re using a double-buffered display (see Screen.new), you should use Screen#flip instead.
This method takes these arguments:
- rect
-
a Rubygame::Rect representing the area of the screen to update. Can also be an length-4 Array, or given as 4 separate arguments. If omitted or nil, the entire screen is updated.
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 |
# File 'ext/rubygame/rubygame_screen.c', line 350
VALUE rbgm_screen_update(int argc, VALUE *argv, VALUE self)
{
int x,y,w,h;
SDL_Surface *screen;
Data_Get_Struct(self,SDL_Surface,screen);
VALUE vx, vy, vw, vh;
rb_scan_args(argc, argv, "04", &vx, &vy, &vw, &vh);
x = y = w = h = 0;
if( RTEST(vx) )
{
switch( TYPE(vx) ) {
case T_ARRAY: {
if( RARRAY_LEN(vx) < 4 )
{
rb_raise(rb_eArgError,"Array is too short to be a Rect (%s for 4)",
RARRAY_LEN(vx));
}
x = NUM2INT(rb_ary_entry(vx,0));
y = NUM2INT(rb_ary_entry(vx,1));
w = NUM2INT(rb_ary_entry(vx,2));
h = NUM2INT(rb_ary_entry(vx,3));
break;
}
case T_FLOAT:
case T_BIGNUM:
case T_FIXNUM: {
x = NUM2INT(vx);
y = NUM2INT(vy);
w = NUM2INT(vw);
h = NUM2INT(vh);
break;
}
default: {
rb_raise(rb_eTypeError,"Unrecognized type for x (wanted Array or Numeric).");
break;
}
}
}
Sint16 left,top,right,bottom;
left = min( max( 0, x ), screen->w );
top = min( max( 0, y ), screen->h );
right = min( max( left, x + w), screen->w );
bottom = min( max( top, y + h), screen->h );
x = left;
y = top;
w = right - left;
h = bottom - top;
SDL_UpdateRect(screen,x,y,w,h);
return self;
}
|
#update_rects(rects) ⇒ Object
Updates (as Screen#update does) several areas of the screen.
This method takes these arguments:
- rects
-
an Array containing any number of Rect objects, each rect representing a portion of the screen to update.
417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 |
# File 'ext/rubygame/rubygame_screen.c', line 417
VALUE rbgm_screen_updaterects(VALUE self, VALUE array_rects)
{
int i, num_rects;
VALUE each_rect;
SDL_Surface *screen;
SDL_Rect *rects;
/* unwrap the Screen instance from self (VALUE) */
Data_Get_Struct(self,SDL_Surface,screen);
/* prepare an (uninitialized) array of Rects */
array_rects = convert_to_array(array_rects);
num_rects = RARRAY_LEN(array_rects);
rects = ALLOCA_N(SDL_Rect, num_rects);
/* initialize the array of Rects from array_rects */
for( i=0; i < num_rects; i++ )
{
each_rect = convert_to_array(rb_ary_entry(array_rects,i));
Sint16 x,y,left,top,right,bottom;
Uint16 w,h;
x = NUM2INT(rb_ary_entry(each_rect,0));
y = NUM2INT(rb_ary_entry(each_rect,1));
w = NUM2INT(rb_ary_entry(each_rect,2));
h = NUM2INT(rb_ary_entry(each_rect,3));
left = min( max( 0, x ), screen->w );
top = min( max( 0, y ), screen->h );
right = min( max( left, x + w), screen->w );
bottom = min( max( top, y + h), screen->h );
rects[i].x = left;
rects[i].y = top;
rects[i].w = right - left;
rects[i].h = bottom - top;
}
/* call the SDL method to update from all these rects */
SDL_UpdateRects( screen, num_rects, rects );
return self;
}
|