/* 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 Display.set_mode), 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(vx)->len < 4 ) { rb_raise(rb_eArgError,"Array is too short to be a Rect (%s for 4)", RARRAY(vx)->len); } 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; }