static VALUE Game_initialize(int argc, VALUE* argv, VALUE self) { if (!NIL_P(Game_s_current(rb_cGame))) { rb_raise(strb_GetStarRubyErrorClass(), "already run"); } volatile VALUE rbWidth, rbHeight, rbOptions; rb_scan_args(argc, argv, "21", &rbWidth, &rbHeight, &rbOptions); if (NIL_P(rbOptions)) { rbOptions = rb_hash_new(); } else { Check_Type(rbOptions, T_HASH); } Game* game; Data_Get_Struct(self, Game, game); if (SDL_InitSubSystem(SDL_INIT_VIDEO | SDL_INIT_TIMER)) { rb_raise_sdl_error(); } const int width = NUM2INT(rbWidth); const int height = NUM2INT(rbHeight); volatile VALUE rbFps = rb_hash_aref(rbOptions, symbol_fps); Game_fps_eq(self, !NIL_P(rbFps) ? rbFps : INT2FIX(30)); volatile VALUE rbTitle = rb_hash_aref(rbOptions, symbol_title); Game_title_eq(self, !NIL_P(rbTitle) ? rbTitle : rb_str_new2("")); bool cursor = false; volatile VALUE val; Check_Type(rbOptions, T_HASH); if (!NIL_P(val = rb_hash_aref(rbOptions, symbol_cursor))) { cursor = RTEST(val); } if (!NIL_P(val = rb_hash_aref(rbOptions, symbol_fullscreen))) { game->isFullscreen = RTEST(val); } if (!NIL_P(val = rb_hash_aref(rbOptions, symbol_window_scale))) { game->windowScale = NUM2INT(val); if (game->windowScale < 1) { rb_raise(rb_eArgError, "invalid window scale: %d", game->windowScale); } } if (!NIL_P(val = rb_hash_aref(rbOptions, symbol_vsync))) { game->isVsync = RTEST(val); } SDL_ShowCursor(cursor ? SDL_ENABLE : SDL_DISABLE); volatile VALUE rbScreen = rb_class_new_instance(2, (VALUE[]){INT2NUM(width), INT2NUM(height)}, strb_GetTextureClass()); game->screen = rbScreen; InitializeScreen(game); rb_iv_set(rb_cGame, "current", self); return Qnil; }
// Picture type of the frame, nil if unknown VALUE video_frame_picture_type(VALUE self) { VideoFrameInternal * internal; Data_Get_Struct(self, VideoFrameInternal, internal); return internal->picture_type; }
static VALUE rb_gsl_multimin_function_fdf_n(VALUE obj) { gsl_multimin_function_fdf *F = NULL; Data_Get_Struct(obj, gsl_multimin_function_fdf, F); return INT2FIX(F->n); }
// Format of the frame, nil if not available VALUE video_frame_format(VALUE self) { VideoFrameInternal * internal; Data_Get_Struct(self, VideoFrameInternal, internal); return av_pixel_format_to_symbol(internal->format); }
// Video frame height (in pixels) VALUE video_frame_height(VALUE self) { VideoFrameInternal * internal; Data_Get_Struct(self, VideoFrameInternal, internal); return INT2NUM(internal->height); }
/* * call-seq: * ctx.setup => Qtrue # first time * ctx.setup => nil # thereafter * * This method is called automatically when a new SSLSocket is created. * Normally you do not need to call this method (unless you are writing an extension in C). */ static VALUE ossl_sslctx_setup(VALUE self) { SSL_CTX *ctx; X509 *cert = NULL, *client_ca = NULL; X509_STORE *store; EVP_PKEY *key = NULL; char *ca_path = NULL, *ca_file = NULL; int i, verify_mode; VALUE val; if(OBJ_FROZEN(self)) return Qnil; Data_Get_Struct(self, SSL_CTX, ctx); #if !defined(OPENSSL_NO_DH) if (RTEST(ossl_sslctx_get_tmp_dh_cb(self))){ SSL_CTX_set_tmp_dh_callback(ctx, ossl_tmp_dh_callback); } else{ SSL_CTX_set_tmp_dh_callback(ctx, ossl_default_tmp_dh_callback); } #endif SSL_CTX_set_ex_data(ctx, ossl_ssl_ex_ptr_idx, (void*)self); val = ossl_sslctx_get_cert_store(self); if(!NIL_P(val)){ /* * WORKAROUND: * X509_STORE can count references, but * X509_STORE_free() doesn't care it. * So we won't increment it but mark it by ex_data. */ store = GetX509StorePtr(val); /* NO NEED TO DUP */ SSL_CTX_set_cert_store(ctx, store); SSL_CTX_set_ex_data(ctx, ossl_ssl_ex_store_p, (void*)1); } val = ossl_sslctx_get_extra_cert(self); if(!NIL_P(val)){ rb_block_call(val, rb_intern("each"), 0, 0, ossl_sslctx_add_extra_chain_cert_i, self); } /* private key may be bundled in certificate file. */ val = ossl_sslctx_get_cert(self); cert = NIL_P(val) ? NULL : GetX509CertPtr(val); /* NO DUP NEEDED */ val = ossl_sslctx_get_key(self); key = NIL_P(val) ? NULL : GetPKeyPtr(val); /* NO DUP NEEDED */ if (cert && key) { if (!SSL_CTX_use_certificate(ctx, cert)) { /* Adds a ref => Safe to FREE */ ossl_raise(eSSLError, "SSL_CTX_use_certificate:"); } if (!SSL_CTX_use_PrivateKey(ctx, key)) { /* Adds a ref => Safe to FREE */ ossl_raise(eSSLError, "SSL_CTX_use_PrivateKey:"); } if (!SSL_CTX_check_private_key(ctx)) { ossl_raise(eSSLError, "SSL_CTX_check_private_key:"); } } val = ossl_sslctx_get_client_ca(self); if(!NIL_P(val)){ if(TYPE(val) == T_ARRAY){ for(i = 0; i < RARRAY_LEN(val); i++){ client_ca = GetX509CertPtr(RARRAY_PTR(val)[i]); if (!SSL_CTX_add_client_CA(ctx, client_ca)){ /* Copies X509_NAME => FREE it. */ ossl_raise(eSSLError, "SSL_CTX_add_client_CA"); } } } else{ client_ca = GetX509CertPtr(val); /* NO DUP NEEDED. */ if (!SSL_CTX_add_client_CA(ctx, client_ca)){ /* Copies X509_NAME => FREE it. */ ossl_raise(eSSLError, "SSL_CTX_add_client_CA"); } } } val = ossl_sslctx_get_ca_file(self); ca_file = NIL_P(val) ? NULL : StringValuePtr(val); val = ossl_sslctx_get_ca_path(self); ca_path = NIL_P(val) ? NULL : StringValuePtr(val); if(ca_file || ca_path){ if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_path)) rb_warning("can't set verify locations"); } val = ossl_sslctx_get_verify_mode(self); verify_mode = NIL_P(val) ? SSL_VERIFY_NONE : NUM2INT(val); SSL_CTX_set_verify(ctx, verify_mode, ossl_ssl_verify_callback); if (RTEST(ossl_sslctx_get_client_cert_cb(self))) SSL_CTX_set_client_cert_cb(ctx, ossl_client_cert_cb); val = ossl_sslctx_get_timeout(self); if(!NIL_P(val)) SSL_CTX_set_timeout(ctx, NUM2LONG(val)); val = ossl_sslctx_get_verify_dep(self); if(!NIL_P(val)) SSL_CTX_set_verify_depth(ctx, NUM2LONG(val)); val = ossl_sslctx_get_options(self); if(!NIL_P(val)) SSL_CTX_set_options(ctx, NUM2LONG(val)); rb_obj_freeze(self); val = ossl_sslctx_get_sess_id_ctx(self); if (!NIL_P(val)){ StringValue(val); if (!SSL_CTX_set_session_id_context(ctx, RSTRING_PTR(val), RSTRING_LEN(val))){ ossl_raise(eSSLError, "SSL_CTX_set_session_id_context:"); } } if (RTEST(rb_iv_get(self, "@session_get_cb"))) { SSL_CTX_sess_set_get_cb(ctx, ossl_sslctx_session_get_cb); OSSL_Debug("SSL SESSION get callback added"); } if (RTEST(rb_iv_get(self, "@session_new_cb"))) { SSL_CTX_sess_set_new_cb(ctx, ossl_sslctx_session_new_cb); OSSL_Debug("SSL SESSION new callback added"); } if (RTEST(rb_iv_get(self, "@session_remove_cb"))) { SSL_CTX_sess_set_remove_cb(ctx, ossl_sslctx_session_remove_cb); OSSL_Debug("SSL SESSION remove callback added"); } return Qtrue; }
// Best effort timestamp (in seconds), nil if not available VALUE video_frame_timestamp(VALUE self) { VideoFrameInternal * internal; Data_Get_Struct(self, VideoFrameInternal, internal); return internal->timestamp; }
/* * call-seq: * attr.node_type -> num * * Obtain this node's type identifier. */ static VALUE rxml_attr_node_type(VALUE self) { xmlAttrPtr xattr; Data_Get_Struct(self, xmlAttr, xattr); return INT2NUM(xattr->type); }
static VALUE initializeConnection(int argc, VALUE *argv, VALUE self) { ConnectionHandle *connection = NULL; ISC_STATUS status[20]; short length = 0; char *file = NULL, *dpb = NULL; VALUE user = Qnil, password = Qnil, options = Qnil; if(argc < 1) { rb_raise(rb_eArgError, "Wrong number of arguments (%d for %d).", argc, 1); } if(TYPE(argv[0]) != T_DATA || RDATA(argv[0])->dfree != (RUBY_DATA_FUNC)databaseFree) { rb_ibruby_raise(NULL, "Invalid database specified for connection."); } file = STR2CSTR(rb_iv_get(argv[0], "@file")); Data_Get_Struct(self, ConnectionHandle, connection); /* Extract parameters. */ if(argc > 1) { user = argv[1]; } if(argc > 2) { password = argv[2]; } if(argc > 3) { options = argv[3]; } /* Open the connection connection. */ dpb = createDPB(user, password, options, &length); if(isc_attach_database(status, strlen(file), file, &connection->handle, length, dpb) != 0) { /* Generate an error. */ free(dpb); rb_ibruby_raise(status, "Error opening database connection."); } free(dpb); /* Store connection attributes. */ rb_iv_set(self, "@database", argv[0]); rb_iv_set(self, "@user", user); rb_iv_set(self, "@transactions", rb_ary_new()); return(self); }
/* * call-seq: * document * * Get the document for this Node */ static VALUE document(VALUE self) { xmlNodePtr node; Data_Get_Struct(self, xmlNode, node); return DOC_RUBY_OBJECT(node->doc); }
/* * call-seq: * blank? * * Is this node blank? */ static VALUE blank_eh(VALUE self) { xmlNodePtr node; Data_Get_Struct(self, xmlNode, node); return (1 == xmlIsBlankNode(node)) ? Qtrue : Qfalse ; }
/* :nodoc: */ static VALUE reparent_node_with(VALUE pivot_obj, VALUE reparentee_obj, pivot_reparentee_func prf) { VALUE reparented_obj ; xmlNodePtr reparentee, pivot, reparented, next_text, new_next_text ; if(!rb_obj_is_kind_of(reparentee_obj, cNokogiriXmlNode)) rb_raise(rb_eArgError, "node must be a Nokogiri::XML::Node"); if(rb_obj_is_kind_of(reparentee_obj, cNokogiriXmlDocument)) rb_raise(rb_eArgError, "node must be a Nokogiri::XML::Node"); Data_Get_Struct(reparentee_obj, xmlNode, reparentee); Data_Get_Struct(pivot_obj, xmlNode, pivot); if(XML_DOCUMENT_NODE == reparentee->type || XML_HTML_DOCUMENT_NODE == reparentee->type) rb_raise(rb_eArgError, "cannot reparent a document node"); xmlUnlinkNode(reparentee); if (reparentee->doc != pivot->doc || reparentee->type == XML_TEXT_NODE) { /* * if the reparentee is a text node, there's a very good chance it will be * merged with an adjacent text node after being reparented, and in that case * libxml will free the underlying C struct. * * since we clearly have a ruby object which references the underlying * memory, we can't let the C struct get freed. let's pickle the original * reparentee by rooting it; and then we'll reparent a duplicate of the * node that we don't care about preserving. * * alternatively, if the reparentee is from a different document than the * pivot node, libxml2 is going to get confused about which document's * "dictionary" the node's strings belong to (this is an otherwise * uninteresting libxml2 implementation detail). as a result, we cannot * reparent the actual reparentee, so we reparent a duplicate. */ NOKOGIRI_ROOT_NODE(reparentee); if (!(reparentee = xmlDocCopyNode(reparentee, pivot->doc, 1))) { rb_raise(rb_eRuntimeError, "Could not reparent node (xmlDocCopyNode)"); } } if (reparentee->type == XML_TEXT_NODE && pivot->next && pivot->next->type == XML_TEXT_NODE) { /* * libxml merges text nodes in a right-to-left fashion, meaning that if * there are two text nodes who would be adjacent, the right (or following, * or next) node will be merged into the left (or preceding, or previous) * node. * * and by "merged" I mean the string contents will be concatenated onto the * left node's contents, and then the node will be freed. * * which means that if we have a ruby object wrapped around the right node, * its memory would be freed out from under it. * * so, we detect this edge case and unlink-and-root the text node before it gets * merged. then we dup the node and insert that duplicate back into the * document where the real node was. * * yes, this is totally lame. */ next_text = pivot->next ; new_next_text = xmlDocCopyNode(next_text, pivot->doc, 1) ; xmlUnlinkNode(next_text); NOKOGIRI_ROOT_NODE(next_text); xmlAddNextSibling(pivot, new_next_text); } /* TODO: I really want to remove this. We shouldn't support 2.6.16 anymore */ if ( reparentee->type == XML_TEXT_NODE && pivot->type == XML_TEXT_NODE && is_2_6_16() ) { /* work around a string-handling bug in libxml 2.6.16. we'd rather leak than segfault. */ pivot->content = xmlStrdup(pivot->content); } if(!(reparented = (*prf)(pivot, reparentee))) { rb_raise(rb_eRuntimeError, "Could not reparent node"); } /* * make sure the ruby object is pointed at the just-reparented node, which * might be a duplicate (see above) or might be the result of merging * adjacent text nodes. */ DATA_PTR(reparentee_obj) = reparented ; relink_namespace(reparented); reparented_obj = Nokogiri_wrap_xml_node(Qnil, reparented); rb_funcall(reparented_obj, decorate_bang, 0); return reparented_obj ; }
VALUE rb_ca_unbound_repeat (int argc, VALUE *argv, VALUE self) { CArray *ca; ca_size_t rank, dim[CA_RANK_MAX]; int32_t rep_rank; ca_size_t rep_dim[CA_RANK_MAX]; ca_size_t count, i; Data_Get_Struct(self, CArray, ca); if ( argc == 1 && argv[0] == ID2SYM(rb_intern("*")) ) { CAUnboundRepeat *cr = (CAUnboundRepeat *) ca; volatile VALUE args; int repeatable = 0; args = rb_ary_new(); if ( rb_obj_is_kind_of(self, rb_cCAUnboundRepeat) ) { repeatable = 1; for (i=0; i<cr->rep_rank; i++) { if ( cr->rep_dim[i] == 1 ) { rb_ary_push(args, ID2SYM(rb_intern("*"))); repeatable = 1; } else if ( cr->rep_dim[i] > 1 ) { rb_ary_push(args, Qnil); } else { rb_ary_push(args, ID2SYM(rb_intern("*"))); } } } else { for (i=0; i<ca->rank; i++) { if ( ca->dim[i] == 1 ) { rb_ary_push(args, ID2SYM(rb_intern("*"))); repeatable = 1; } else { rb_ary_push(args, Qnil); } } } if ( ! repeatable ) { return self; } else { return rb_ca_unbound_repeat((int)RARRAY_LEN(args), RARRAY_PTR(args), self); } } else if ( argc == 2 && argv[0] == ID2SYM(rb_intern("*")) && rb_obj_is_carray(argv[1]) ) { volatile VALUE args, obj; args = ID2SYM(rb_intern("*")); obj = rb_ca_unbound_repeat(1, (VALUE*)&args, self); return ca_ubrep_bind_with(obj, argv[1]); } else if ( argc == 2 && argv[1] == ID2SYM(rb_intern("*")) && rb_obj_is_carray(argv[0]) ) { volatile VALUE args, obj; args = ID2SYM(rb_intern("*")); obj = rb_ca_unbound_repeat(1, (VALUE*)&args, self); return ca_ubrep_bind_with(obj, argv[0]); } rep_rank = argc; count = 0; rank = 0; for (i=0; i<rep_rank; i++) { if ( rb_obj_is_kind_of(argv[i], rb_cSymbol) ) { if ( argv[i] == ID2SYM(rb_intern("*")) ) { rep_dim[i] = 0; if ( ca->dim[count] == 1 ) { count++; } } else { rb_raise(rb_eArgError, "unknown symbol (!= ':*') in arguments"); } } else { if ( ! NIL_P(argv[i]) ) { rb_raise(rb_eArgError, "invalid argument"); } rep_dim[i] = ca->dim[count]; dim[rank] = ca->dim[count]; count++; rank++; } } if ( count != ca->rank ) { rb_raise(rb_eRuntimeError, "too small # of nil"); } if ( rank != ca->rank ) { volatile VALUE par, obj; par = rb_ca_refer_new(self, ca->data_type, rank, dim, ca->bytes, 0); obj = rb_ca_ubrep_new(par, rep_rank, rep_dim); rb_ivar_set(obj, rb_intern("__real_parent__"), par); rb_ca_set_parent(obj, self); return obj; } else { return rb_ca_ubrep_new(self, rep_rank, rep_dim); } }
static VALUE Game_update_screen(VALUE self) { const Game* game; Data_Get_Struct(self, Game, game); CheckDisposed(game); volatile VALUE rbScreen = game->screen; const Texture* texture; Data_Get_Struct(rbScreen, Texture, texture); strb_CheckDisposedTexture(texture); const Pixel* src = texture->pixels; SDL_Surface* sdlScreenBuffer = game->sdlScreenBuffer; SDL_LockSurface(sdlScreenBuffer); Pixel* dst = (Pixel*)sdlScreenBuffer->pixels; const int screenPadding = sdlScreenBuffer->pitch / sdlScreenBuffer->format->BytesPerPixel - sdlScreenBuffer->w; const int textureWidth = texture->width; const int textureHeight = texture->height; const int heightPadding = sdlScreenBuffer->w - texture->width + screenPadding; for (int j = 0; j < textureHeight; j++, dst += heightPadding) { for (int i = 0; i < textureWidth; i++, src++, dst++) { const uint8_t alpha = src->color.alpha; if (alpha == 255) { *dst = *src; } else if (alpha) { dst->color.red = DIV255(src->color.red * alpha); dst->color.green = DIV255(src->color.green * alpha); dst->color.blue = DIV255(src->color.blue * alpha); } else { dst->color.red = 0; dst->color.green = 0; dst->color.blue = 0; } } } SDL_UnlockSurface(sdlScreenBuffer); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, sdlScreenBuffer->w, sdlScreenBuffer->h, 0, GL_BGRA, GL_UNSIGNED_BYTE, sdlScreenBuffer->pixels); glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0, 1.0, 1.0); glBegin(GL_QUADS); { int x1, y1, x2, y2; if (!game->isFullscreen) { x1 = 0; y1 = 0; x2 = game->sdlScreen->w; y2 = game->sdlScreen->h; } else { x1 = (game->sdlScreen->w - textureWidth) / 2; y1 = (game->sdlScreen->h - textureHeight) / 2; x2 = x1 + textureWidth; y2 = y1 + textureHeight; } const double tu = (double)textureWidth / sdlScreenBuffer->w; const double tv = (double)textureHeight / sdlScreenBuffer->h; glTexCoord2f(0.0, 0.0); glVertex3i(x1, y1, 0); glTexCoord2f(tu, 0.0); glVertex3i(x2, y1, 0); glTexCoord2f(tu, tv); glVertex3i(x2, y2, 0); glTexCoord2f(0.0, tv); glVertex3i(x1, y2, 0); } glEnd(); SDL_GL_SwapBuffers(); return Qnil; }
// Expected input format VALUE video_resampler_src_format(VALUE self) { VideoResamplerInternal * internal; Data_Get_Struct(self, VideoResamplerInternal, internal); return av_pixel_format_to_symbol(internal->src_format); }
static VALUE closeConnection(VALUE self) { VALUE result = Qnil; ConnectionHandle *connection = NULL; Data_Get_Struct(self, ConnectionHandle, connection); if(connection->handle != 0) { VALUE transactions = rb_iv_get(self, "@transactions"), transaction = Qnil; ISC_STATUS status[20]; /* Roll back an outstanding transactions. */ while((transaction = rb_ary_pop(transactions)) != Qnil) { VALUE active = rb_funcall(transaction, rb_intern("active?"), 0); if(active == Qtrue) { rb_funcall(transaction, rb_intern("rollback"), 0); } } /* Detach from the database. */ if(isc_detach_database(status, &connection->handle) == 0) { connection->handle = 0; result = self; } else { /* Generate an error. */ rb_ibruby_raise(status, "Error closing connection."); } } return(result); }
// Resulting output width (in pixels) VALUE video_resampler_dst_width(VALUE self) { VideoResamplerInternal * internal; Data_Get_Struct(self, VideoResamplerInternal, internal); return INT2NUM(internal->dst_width); }
static inline VALUE Context_thnum(VALUE self) { debug_context_t *context; Data_Get_Struct(self, debug_context_t, context); return INT2FIX(context->thnum); }
static splaytree* get_tree_from_self(VALUE self) { splaytree *tree; Data_Get_Struct(self, splaytree, tree); return tree; }
static VALUE rb_git_indexentry_ctime_GET(VALUE self) { git_index_entry *entry; Data_Get_Struct(self, git_index_entry, entry); return rb_time_new(entry->ctime.seconds, entry->ctime.nanoseconds / 1000); }
// Duration of this frame (in seconds), nil if not available VALUE video_frame_duration(VALUE self) { VideoFrameInternal * internal; Data_Get_Struct(self, VideoFrameInternal, internal); return internal->duration; }
static VALUE rb_git_index_get_entry_count(VALUE self) { git_index *index; Data_Get_Struct(self, git_index, index); return INT2FIX(git_index_entrycount(index)); }
// Video frame width (in pixels) VALUE video_frame_width(VALUE self) { VideoFrameInternal * internal; Data_Get_Struct(self, VideoFrameInternal, internal); return INT2NUM(internal->width); }
// Interpolation filter VALUE video_resampler_filter(VALUE self) { VideoResamplerInternal * internal; Data_Get_Struct(self, VideoResamplerInternal, internal); return interpolation_filter_to_symbol(internal->filter); }
// Video pixel aspect ratio, nil if not available VALUE video_frame_aspect_ratio(VALUE self) { VideoFrameInternal * internal; Data_Get_Struct(self, VideoFrameInternal, internal); return internal->aspect_ratio; }
// Initialize resampler // // Generic // ::new(src_width, src_height, src_format, dst_factor) - Resize by percentage // ::new(src_width, src_height, src_format, dst_format) - Change color format // ::new(src_width, src_height, src_format, dst_width, dst_height) - Resize to width and height // ::new(src_width, src_height, src_format, dst_width, dst_height, filter) - Resize with interpolation filter // ::new(src_width, src_height, src_format, dst_width, dst_height, dst_format, filter) - Resize with filter and change color format // // From Object // ::new(source, dst_factor) - Resize by percentage // ::new(source, dst_format) - Change color format // ::new(source, dst_width, dst_height) - Resize to width and height // ::new(source, dst_width, dst_height, filter) - Resize with interpolation filter // ::new(source, dst_width, dst_height, dst_format, filter) - Resize with filter and change color format VALUE video_resampler_initialize(int argc, VALUE * argv, VALUE self) { VideoResamplerInternal * internal; Data_Get_Struct(self, VideoResamplerInternal, internal); if (argc && TYPE(argv[0]) == T_FIXNUM) { // Called generic form if (argc < 4) rb_raise(rb_eArgError, "Missing argument(s)"); else if (argc > 7) rb_raise(rb_eArgError, "Too many arguments"); internal->src_width = NUM2INT(argv[0]); internal->src_height = NUM2INT(argv[1]); internal->src_format = symbol_to_av_pixel_format(argv[2]); argc -= 3; argv += 3; } else { // Called with object if (argc < 2) rb_raise(rb_eArgError, "Missing argument(s)"); else if (argc > 5) rb_raise(rb_eArgError, "Too many arguments"); internal->src_width = NUM2INT(rb_funcall(argv[0], rb_intern("width"), 0)); internal->src_height = NUM2INT(rb_funcall(argv[0], rb_intern("height"), 0)); internal->src_format = symbol_to_av_pixel_format(rb_funcall(argv[0], rb_intern("format"), 0)); argc -= 1; argv += 1; } internal->dst_width = internal->src_width; internal->dst_height = internal->src_height; internal->dst_format = internal->src_format; internal->filter = SWS_FAST_BILINEAR; switch (argc) { case 1: { if (TYPE(argv[0]) != T_SYMBOL) { // Resize by percentage internal->dst_width = (int)(internal->src_width * NUM2DBL(argv[0])); internal->dst_height = (int)(internal->src_height * NUM2DBL(argv[0])); } else { // Change color format internal->dst_format = symbol_to_av_pixel_format(argv[0]); } break; } case 2: { // Resize to width and height internal->dst_width = NUM2INT(argv[0]); internal->dst_height = NUM2INT(argv[1]); break; } case 3: { // Resize to width and height using interpolation filter internal->dst_width = NUM2INT(argv[0]); internal->dst_height = NUM2INT(argv[1]); internal->filter = symbol_to_interpolation_filter(argv[2]); break; } case 4: { // Resize to width and height using interpolation filter and change color format internal->dst_width = NUM2INT(argv[0]); internal->dst_height = NUM2INT(argv[1]); internal->dst_format = symbol_to_av_pixel_format(argv[2]); internal->filter = symbol_to_interpolation_filter(argv[3]); break; } } if (internal->src_format == PIX_FMT_NONE) rb_raise(rb_eArgError, "Unknown input color format"); if (internal->dst_format == PIX_FMT_NONE) rb_raise(rb_eArgError, "Unknown output color format"); if (internal->filter == 0) rb_raise(rb_eArgError, "Unknown interpolation method"); // Create scaler context internal->context = sws_getContext(internal->src_width, internal->src_height, internal->src_format, internal->dst_width, internal->dst_height, internal->dst_format, internal->filter, NULL, NULL, NULL); if (!internal->context) rb_raise(rb_eRuntimeError, "Failed to create rescaling context"); return self; }
// Is this a key frame? VALUE video_frame_key(VALUE self) { VideoFrameInternal * internal; Data_Get_Struct(self, VideoFrameInternal, internal); return internal->key; }
// Expected input height (in pixels) VALUE video_resampler_src_height(VALUE self) { VideoResamplerInternal * internal; Data_Get_Struct(self, VideoResamplerInternal, internal); return INT2NUM(internal->src_height); }
static VALUE rb_gsl_multimin_function_fdf_params(VALUE obj) { gsl_multimin_function_fdf *F = NULL; Data_Get_Struct(obj, gsl_multimin_function_fdf, F); return rb_ary_entry((VALUE) F->params, 3); }
static void InitializeScreen(Game* game) { const int bpp = 32; VALUE rbScreen = game->screen; const Texture* screen; Data_Get_Struct(rbScreen, Texture, screen); strb_CheckDisposedTexture(screen); const int width = screen->width; const int height = screen->height; int screenWidth = 0; int screenHeight = 0; Uint32 options = 0; options |= SDL_OPENGL; if (game->isFullscreen) { options |= SDL_HWSURFACE | SDL_FULLSCREEN; game->windowScale = 1; SDL_Rect** modes = SDL_ListModes(NULL, options); if (!modes) { rb_raise(rb_eRuntimeError, "not supported fullscreen resolution"); } if (modes != (SDL_Rect**)-1) { for (int i = 0; modes[i]; i++) { int realBpp = SDL_VideoModeOK(modes[i]->w, modes[i]->h, bpp, options); if (width <= modes[i]->w && height <= modes[i]->h && realBpp == bpp) { screenWidth = modes[i]->w; screenHeight = modes[i]->h; } else { break; } } if (screenWidth == 0 || screenHeight == 0) { rb_raise(rb_eRuntimeError, "not supported fullscreen resolution"); } } else { // any resolution are available screenWidth = width; screenHeight = height; } } else { screenWidth = width * game->windowScale; screenHeight = height * game->windowScale; options |= SDL_SWSURFACE; } SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, game->isVsync ? 1 : 0); game->sdlScreen = SDL_SetVideoMode(screenWidth, screenHeight, bpp, options); if (!game->sdlScreen) { rb_raise_sdl_error(); } SDL_PixelFormat* format = game->sdlScreen->format; game->sdlScreenBuffer = SDL_CreateRGBSurface(SDL_SWSURFACE, Power2(width), Power2(height), bpp, format->Bmask, format->Gmask, format->Bmask, format->Amask); if (!game->sdlScreenBuffer) { rb_raise_sdl_error(); } glClearColor(0.0, 0.0, 0.0, 0.0); glOrtho(0.0, screenWidth, screenHeight, 0.0, -1.0, 1.0); glEnable(GL_TEXTURE_2D); glGenTextures(1, &game->glScreen); glBindTexture(GL_TEXTURE_2D, game->glScreen); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); }