📄 gameswf_impl.cpp
字号:
assert(m != NULL); s_current_root = m; } const char* get_workdir() { return s_workdir.c_str(); } void set_workdir(const char* dir) { assert(dir != NULL); s_workdir = dir; } void clear_library() // Drop all library references to movie_definitions, so they // can be cleaned up. { s_movie_library.clear(); s_movie_library_inst.clear(); }// tulrich: Vitaly sent this code. I don't trust it though! It looks// like it may be dropping refs in order to remove cyclic references.// I would rather fix the source of any cyclic references directly.//// void clear_library()// // Drop all library references to movie_definitions, so they// // can be cleaned up.// {// {for (hash< movie_definition_sub*, smart_ptr<movie_interface> >::iterator it =// s_movie_library_inst.begin();// it != s_movie_library_inst.end();// ++it)// {// smart_ptr<movie_interface> obj = it->second;// while (obj->get_ref_count() > 2) // { // obj->drop_ref();// }// }}// s_movie_library_inst.clear();// // {for (stringi_hash< smart_ptr<movie_definition_sub> >::iterator it = s_movie_library.begin();// it != s_movie_library.end(); // ++it) // {// smart_ptr<movie_definition_sub> obj = it->second;// while (obj->get_ref_count() > 2) // { // obj->drop_ref();// }// }}// s_movie_library.clear();// } movie_definition* create_library_movie(const char* filename) // Try to load a movie from the given url, if we haven't // loaded it already. Add it to our library on success, and // return a pointer to it. { return create_library_movie_sub(filename); } movie_definition_sub* create_library_movie_sub(const char* filename) { tu_string fn(filename); // Is the movie already in the library? { smart_ptr<movie_definition_sub> m; s_movie_library.get(fn, &m); if (m != NULL) { // Return cached movie. m->add_ref(); return m.get_ptr(); } } // Try to open a file under the filename. movie_definition_sub* mov = create_movie_sub(filename); if (mov == NULL) { log_error("error: couldn't load library movie '%s'\n", filename); return NULL; } else { s_movie_library.add(fn, mov); } mov->add_ref(); return mov; } movie_interface* create_library_movie_inst(movie_definition* md) { return create_library_movie_inst_sub((movie_definition_sub*)md); } movie_interface* create_library_movie_inst_sub(movie_definition_sub* md) { // Is the movie instance already in the library? { smart_ptr<movie_interface> m; s_movie_library_inst.get(md, &m); if (m != NULL) { // Return cached movie instance. m->add_ref(); return m.get_ptr(); } } // Try to create movie interface movie_interface* mov = md->create_instance(); if (mov == NULL) { log_error("error: couldn't create instance\n"); return NULL; } else { s_movie_library_inst.add(md, mov); } mov->add_ref(); return mov; } void precompute_cached_data(movie_definition* movie_def) // Fill in cached data in movie_def. // @@@@ NEEDS TESTING -- MIGHT BE BROKEN!!! { assert(movie_def != NULL); // Temporarily install null render and sound handlers, // so we don't get output during preprocessing. // // Use automatic struct var to make sure we restore // when exiting the function. struct save_stuff { render_handler* m_original_rh; sound_handler* m_original_sh; save_stuff() { // Save. m_original_rh = get_render_handler(); m_original_sh = get_sound_handler(); set_render_handler(NULL); set_sound_handler(NULL); } ~save_stuff() { // Restore. set_render_handler(m_original_rh); set_sound_handler(m_original_sh); } } save_stuff_instance; // Need an instance. gameswf::movie_interface* m = movie_def->create_instance(); if (m == NULL) { log_error("error: precompute_cached_data can't create instance of movie\n"); return; } // Run through the movie's frames. // // @@ there might be cleaner ways to do this; e.g. do // execute_frame_tags(i, true) on movie and all child // sprites. int kick_count = 0; for (;;) { // @@ do we also have to run through all sprite frames // as well? // // @@ also, ActionScript can rescale things // dynamically -- we can't really do much about that I // guess? // // @@ Maybe we should allow the user to specify some // safety margin on scaled shapes. int last_frame = m->get_current_frame(); m->advance(0.010f); m->display(); if (m->get_current_frame() == movie_def->get_frame_count() - 1) { // Done. break; } if (m->get_play_state() == gameswf::movie_interface::STOP) { // Kick the movie. //printf("kicking movie, kick ct = %d\n", kick_count); m->goto_frame(last_frame + 1); m->set_play_state(gameswf::movie_interface::PLAY); kick_count++; if (kick_count > 10) { //printf("movie is stalled; giving up on playing it through.\n"); break; } } else if (m->get_current_frame() < last_frame) { // Hm, apparently we looped back. Skip ahead... log_error("loop back; jumping to frame %d\n", last_frame); m->goto_frame(last_frame + 1); } else { kick_count = 0; } } m->drop_ref(); } // // Some tag implementations // void null_loader(stream* in, int tag_type, movie_definition_sub* m) // Silently ignore the contents of this tag. { } void frame_label_loader(stream* in, int tag_type, movie_definition_sub* m) // Label the current frame of m with the name from the stream. { char* n = in->read_string(); m->add_frame_name(n); delete [] n; } struct set_background_color : public execute_tag { rgba m_color; void execute(movie* m) { float current_alpha = m->get_background_alpha(); m_color.m_a = frnd(current_alpha * 255.0f); m->set_background_color(m_color); } void execute_state(movie* m) { execute(m); } void read(stream* in) { m_color.read_rgb(in); IF_VERBOSE_PARSE(log_msg(" set_background_color: (%d %d %d)\n", m_color.m_r, m_color.m_g, m_color.m_b)); } }; void set_background_color_loader(stream* in, int tag_type, movie_definition_sub* m) { assert(tag_type == 9); assert(m); set_background_color* t = new set_background_color; t->read(in); m->add_execute_tag(t); }#if 0 // Bitmap character struct bitmap_character : public bitmap_character_def { bitmap_character(bitmap_info* bi) : m_bitmap_info(bi) { }// bitmap_character(image::rgb* image)// {// assert(image != 0);// // Create our bitmap info, from our image.// m_bitmap_info = gameswf::render::create_bitmap_info_rgb(image);// }// bitmap_character(image::rgba* image)// {// assert(image != 0);// // Create our bitmap info, from our image.// m_bitmap_info = gameswf::render::create_bitmap_info_rgba(image);// } gameswf::bitmap_info* get_bitmap_info() { return m_bitmap_info.get_ptr(); } private: smart_ptr<gameswf::bitmap_info> m_bitmap_info; };#endif void jpeg_tables_loader(stream* in, int tag_type, movie_definition_sub* m) // Load JPEG compression tables that can be used to load // images further along in the stream. { assert(tag_type == 8);#if TU_CONFIG_LINK_TO_JPEGLIB jpeg::input* j_in = jpeg::input::create_swf_jpeg2_header_only(in->get_underlying_stream()); assert(j_in); m->set_jpeg_loader(j_in);#endif // TU_CONFIG_LINK_TO_JPEGLIB } void define_bits_jpeg_loader(stream* in, int tag_type, movie_definition_sub* m) // A JPEG image without included tables; those should be in an // existing jpeg::input object stored in the movie. { assert(tag_type == 6); Uint16 character_id = in->read_u16(); // // Read the image data. // bitmap_info* bi = NULL; if (m->get_create_bitmaps() == DO_LOAD_BITMAPS) {#if TU_CONFIG_LINK_TO_JPEGLIB jpeg::input* j_in = m->get_jpeg_loader(); assert(j_in); j_in->discard_partial_buffer(); image::rgb* im = image::read_swf_jpeg2_with_tables(j_in); bi = render::create_bitmap_info_rgb(im); delete im;#else log_error("gameswf is not linked to jpeglib -- can't load jpeg image data!\n"); bi = render::create_bitmap_info_empty();#endif } else { bi = render::create_bitmap_info_empty(); } assert(bi->get_ref_count() == 0); bitmap_character* ch = new bitmap_character(bi); m->add_bitmap_character(character_id, ch); } void define_bits_jpeg2_loader(stream* in, int tag_type, movie_definition_sub* m) { assert(tag_type == 21); Uint16 character_id = in->read_u16(); IF_VERBOSE_PARSE(log_msg(" define_bits_jpeg2_loader: charid = %d pos = 0x%x\n", character_id, in->get_position())); // // Read the image data. // bitmap_info* bi = NULL; if (m->get_create_bitmaps() == DO_LOAD_BITMAPS) {#if TU_CONFIG_LINK_TO_JPEGLIB image::rgb* im = image::read_swf_jpeg2(in->get_underlying_stream()); bi = render::create_bitmap_info_rgb(im); delete im;#else log_error("gameswf is not linked to jpeglib -- can't load jpeg image data!\n"); bi = render::create_bitmap_info_empty();#endif } else { bi = render::create_bitmap_info_empty(); } assert(bi->get_ref_count() == 0); bitmap_character* ch = new bitmap_character(bi); m->add_bitmap_character(character_id, ch); }#if TU_CONFIG_LINK_TO_ZLIB void inflate_wrapper(tu_file* in, void* buffer, int buffer_bytes) // Wrapper function -- uses Zlib to uncompress in_bytes worth // of data from the input file into buffer_bytes worth of data // into *buffer. { assert(in); assert(buffer); assert(buffer_bytes > 0); int err; z_stream d_stream; /* decompression stream */ d_stream.zalloc = (alloc_func)0; d_stream.zfree = (free_func)0; d_stream.opaque = (voidpf)0; d_stream.next_in = 0; d_stream.avail_in = 0; d_stream.next_out = (Byte*) buffer; d_stream.avail_out = (uInt) buffer_bytes; err = inflateInit(&d_stream); if (err != Z_OK) { log_error("error: inflate_wrapper() inflateInit() returned %d\n", err); return; } Uint8 buf[1]; for (;;) { // Fill a one-byte (!) buffer. buf[0] = in->read_byte(); d_stream.next_in = &buf[0]; d_stream.avail_in = 1; err = inflate(&d_stream, Z_SYNC_FLUSH); if (err == Z_STREAM_END) break; if (err != Z_OK) { log_error("error: inflate_wrapper() inflate() returned %d\n", err); } } err = inflateEnd(&d_stream); if (err != Z_OK) { log_error("error: inflate_wrapper() inflateEnd() return %d\n", err); } }#endif // TU_CONFIG_LINK_TO_ZLIB void define_bits_jpeg3_loader(stream* in, int tag_type, movie_definition_sub* m) // loads a define_bits_jpeg3 tag. This is a jpeg file with an alpha // channel using zlib compression. { assert(tag_type == 35); Uint16 character_id = in->read_u16(); IF_VERBOSE_PARSE(log_msg(" define_bits_jpeg3_loader: charid = %d pos = 0x%x\n", character_id, in->get_position())); Uint32 jpeg_size = in->read_u32(); Uint32 alpha_position = in->get_position() + jpeg_size; bitmap_info* bi = NULL; if (m->get_create_bitmaps() == DO_LOAD_BITMAPS) {#if TU_CONFIG_LINK_TO_JPEGLIB == 0 || TU_CONFIG_LINK_TO_ZLIB == 0 log_error("gameswf is not linked to jpeglib/zlib -- can't load jpeg/zipped image data!\n"); bi = render::create_bitmap_info_empty();#else // // Read the image data. // // Read rgb data. image::rgba* im = image::read_swf_jpeg3(in->get_underlying_stream()); // Read alpha channel. in->set_position(alpha_position); int buffer_bytes = im->m_width * im->m_height; Uint8* buffer = new Uint8[buffer_bytes]; inflate_wrapper(in->get_underlying_stream(), buffer, buffer_bytes); for (int i = 0; i < buffer_bytes; i++) { im->m_data[4*i+3] = buffer[i]; } delete [] buffer; bi = render::create_bitmap_info_rgba(im); delete im;#endif }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -