/* call-seq:
* update()
* update(rect)
* update(x,y,w,h)
*
* 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.
*/
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;
}