📄 gameswf_impl.cpp
字号:
else { bi = render::create_bitmap_info_empty(); } // Create bitmap character. bitmap_character* ch = new bitmap_character(bi); m->add_bitmap_character(character_id, ch); } void define_bits_lossless_2_loader(stream* in, int tag_type, movie_definition_sub* m) { assert(tag_type == 20 || tag_type == 36); Uint16 character_id = in->read_u16(); Uint8 bitmap_format = in->read_u8(); // 3 == 8 bit, 4 == 16 bit, 5 == 32 bit Uint16 width = in->read_u16(); Uint16 height = in->read_u16(); IF_VERBOSE_PARSE(log_msg(" defbitslossless2: tag_type = %d, id = %d, fmt = %d, w = %d, h = %d\n", tag_type, character_id, bitmap_format, width, height)); bitmap_info* bi = NULL; if (m->get_create_bitmaps() == DO_LOAD_BITMAPS) {#if TU_CONFIG_LINK_TO_ZLIB == 0 log_error("gameswf is not linked to zlib -- can't load zipped image data!\n"); return;#else if (tag_type == 20) { // RGB image data. image::rgb* image = image::create_rgb(width, height); if (bitmap_format == 3) { // 8-bit data, preceded by a palette. const int bytes_per_pixel = 1; int color_table_size = in->read_u8(); color_table_size += 1; // !! SWF stores one less than the actual size int pitch = (width * bytes_per_pixel + 3) & ~3; int buffer_bytes = color_table_size * 3 + pitch * height; Uint8* buffer = new Uint8[buffer_bytes]; inflate_wrapper(in->get_underlying_stream(), buffer, buffer_bytes); assert(in->get_position() <= in->get_tag_end_position()); Uint8* color_table = buffer; for (int j = 0; j < height; j++) { Uint8* image_in_row = buffer + color_table_size * 3 + j * pitch; Uint8* image_out_row = image::scanline(image, j); for (int i = 0; i < width; i++) { Uint8 pixel = image_in_row[i * bytes_per_pixel]; image_out_row[i * 3 + 0] = color_table[pixel * 3 + 0]; image_out_row[i * 3 + 1] = color_table[pixel * 3 + 1]; image_out_row[i * 3 + 2] = color_table[pixel * 3 + 2]; } } delete [] buffer; } else if (bitmap_format == 4) { // 16 bits / pixel const int bytes_per_pixel = 2; int pitch = (width * bytes_per_pixel + 3) & ~3; int buffer_bytes = pitch * height; Uint8* buffer = new Uint8[buffer_bytes]; inflate_wrapper(in->get_underlying_stream(), buffer, buffer_bytes); assert(in->get_position() <= in->get_tag_end_position()); for (int j = 0; j < height; j++) { Uint8* image_in_row = buffer + j * pitch; Uint8* image_out_row = image::scanline(image, j); for (int i = 0; i < width; i++) { Uint16 pixel = image_in_row[i * 2] | (image_in_row[i * 2 + 1] << 8); // @@ How is the data packed??? I'm just guessing here that it's 565! image_out_row[i * 3 + 0] = (pixel >> 8) & 0xF8; // red image_out_row[i * 3 + 1] = (pixel >> 3) & 0xFC; // green image_out_row[i * 3 + 2] = (pixel << 3) & 0xF8; // blue } } delete [] buffer; } else if (bitmap_format == 5) { // 32 bits / pixel, input is ARGB format (???) const int bytes_per_pixel = 4; int pitch = width * bytes_per_pixel; int buffer_bytes = pitch * height; Uint8* buffer = new Uint8[buffer_bytes]; inflate_wrapper(in->get_underlying_stream(), buffer, buffer_bytes); assert(in->get_position() <= in->get_tag_end_position()); // Need to re-arrange ARGB into RGB. for (int j = 0; j < height; j++) { Uint8* image_in_row = buffer + j * pitch; Uint8* image_out_row = image::scanline(image, j); for (int i = 0; i < width; i++) { Uint8 a = image_in_row[i * 4 + 0]; Uint8 r = image_in_row[i * 4 + 1]; Uint8 g = image_in_row[i * 4 + 2]; Uint8 b = image_in_row[i * 4 + 3]; image_out_row[i * 3 + 0] = r; image_out_row[i * 3 + 1] = g; image_out_row[i * 3 + 2] = b; a = a; // Inhibit warning. } } delete [] buffer; }// bitmap_character* ch = new bitmap_character(image); bi = render::create_bitmap_info_rgb(image); delete image;// // add image to movie, under character id.// m->add_bitmap_character(character_id, ch); } else { // RGBA image data. assert(tag_type == 36); image::rgba* image = image::create_rgba(width, height); if (bitmap_format == 3) { // 8-bit data, preceded by a palette. const int bytes_per_pixel = 1; int color_table_size = in->read_u8(); color_table_size += 1; // !! SWF stores one less than the actual size int pitch = (width * bytes_per_pixel + 3) & ~3; int buffer_bytes = color_table_size * 4 + pitch * height; Uint8* buffer = new Uint8[buffer_bytes]; inflate_wrapper(in->get_underlying_stream(), buffer, buffer_bytes); assert(in->get_position() <= in->get_tag_end_position()); Uint8* color_table = buffer; for (int j = 0; j < height; j++) { Uint8* image_in_row = buffer + color_table_size * 4 + j * pitch; Uint8* image_out_row = image::scanline(image, j); for (int i = 0; i < width; i++) { Uint8 pixel = image_in_row[i * bytes_per_pixel]; image_out_row[i * 4 + 0] = color_table[pixel * 4 + 0]; image_out_row[i * 4 + 1] = color_table[pixel * 4 + 1]; image_out_row[i * 4 + 2] = color_table[pixel * 4 + 2]; image_out_row[i * 4 + 3] = color_table[pixel * 4 + 3]; } } delete [] buffer; } else if (bitmap_format == 4) { // 16 bits / pixel const int bytes_per_pixel = 2; int pitch = (width * bytes_per_pixel + 3) & ~3; int buffer_bytes = pitch * height; Uint8* buffer = new Uint8[buffer_bytes]; inflate_wrapper(in->get_underlying_stream(), buffer, buffer_bytes); assert(in->get_position() <= in->get_tag_end_position()); for (int j = 0; j < height; j++) { Uint8* image_in_row = buffer + j * pitch; Uint8* image_out_row = image::scanline(image, j); for (int i = 0; i < width; i++) { Uint16 pixel = image_in_row[i * 2] | (image_in_row[i * 2 + 1] << 8); // @@ How is the data packed??? I'm just guessing here that it's 565! image_out_row[i * 4 + 0] = 255; // alpha image_out_row[i * 4 + 1] = (pixel >> 8) & 0xF8; // red image_out_row[i * 4 + 2] = (pixel >> 3) & 0xFC; // green image_out_row[i * 4 + 3] = (pixel << 3) & 0xF8; // blue } } delete [] buffer; } else if (bitmap_format == 5) { // 32 bits / pixel, input is ARGB format inflate_wrapper(in->get_underlying_stream(), image->m_data, width * height * 4); assert(in->get_position() <= in->get_tag_end_position()); // Need to re-arrange ARGB into RGBA. for (int j = 0; j < height; j++) { Uint8* image_row = image::scanline(image, j); for (int i = 0; i < width; i++) { Uint8 a = image_row[i * 4 + 0]; Uint8 r = image_row[i * 4 + 1]; Uint8 g = image_row[i * 4 + 2]; Uint8 b = image_row[i * 4 + 3]; image_row[i * 4 + 0] = r; image_row[i * 4 + 1] = g; image_row[i * 4 + 2] = b; image_row[i * 4 + 3] = a; } } } bi = render::create_bitmap_info_rgba(image);// bitmap_character* ch = new bitmap_character(image); delete image;// // add image to movie, under character id.// m->add_bitmap_character(character_id, ch); }#endif // TU_CONFIG_LINK_TO_ZLIB } else { bi = render::create_bitmap_info_empty(); } assert(bi->get_ref_count() == 0); bitmap_character* ch = new bitmap_character(bi); // add image to movie, under character id. m->add_bitmap_character(character_id, ch); } void define_shape_loader(stream* in, int tag_type, movie_definition_sub* m) { assert(tag_type == 2 || tag_type == 22 || tag_type == 32); Uint16 character_id = in->read_u16(); IF_VERBOSE_PARSE(log_msg(" shape_loader: id = %d\n", character_id)); shape_character_def* ch = new shape_character_def; ch->read(in, tag_type, true, m); IF_VERBOSE_PARSE(log_msg(" bound rect:"); ch->get_bound().print()); m->add_character(character_id, ch); } void define_shape_morph_loader(stream* in, int tag_type, movie_definition_sub* m) { assert(tag_type == 46); Uint16 character_id = in->read_u16(); IF_VERBOSE_PARSE(log_msg(" shape_morph_loader: id = %d\n", character_id)); morph2_character_def* morph = new morph2_character_def; morph->read(in, tag_type, true, m); m->add_character(character_id, morph); } // // font loaders // void define_font_loader(stream* in, int tag_type, movie_definition_sub* m) // Load a DefineFont or DefineFont2 tag. { assert(tag_type == 10 || tag_type == 48); Uint16 font_id = in->read_u16(); font* f = new font; f->read(in, tag_type, m); m->add_font(font_id, f); // Automatically keeping fonts in fontlib is // problematic. The app should be responsible for // optionally adding fonts to fontlib. // //fontlib::add_font(f); } void define_font_info_loader(stream* in, int tag_type, movie_definition_sub* m) // Load a DefineFontInfo tag. This adds information to an // existing font. { assert(tag_type == 13); Uint16 font_id = in->read_u16(); font* f = m->get_font(font_id); if (f) { f->read_font_info(in); } else { log_error("define_font_info_loader: can't find font w/ id %d\n", font_id); } } // // swf_event // // For embedding event handlers in place_object_2 struct swf_event { // NOTE: DO NOT USE THESE AS VALUE TYPES IN AN // array<>! They cannot be moved! The private // operator=(const swf_event&) should help guard // against that. event_id m_event; action_buffer m_action_buffer; as_value m_method; swf_event() { } void attach_to(character* ch) const { ch->set_event_handler(m_event, m_method); } void read(stream* in, Uint32 flags) { assert(flags != 0); // Scream if more than one bit is set, since we're not set up to handle // that, and it doesn't seem possible to express in ActionScript source, // so it's important to know if this ever occurs in the wild. if (flags & (flags - 1)) { log_error("error: swf_event::read() -- more than one event type encoded! " "unexpected! flags = 0x%x\n", flags); } // 14 bits reserved, 18 bits used static const event_id s_code_bits[18] = { event_id::LOAD, event_id::ENTER_FRAME, event_id::UNLOAD, event_id::MOUSE_MOVE, event_id::MOUSE_DOWN, event_id::MOUSE_UP, event_id::KEY_DOWN, event_id::KEY_UP, event_id::DATA, event_id::INITIALIZE, event_id::PRESS, event_id::RELEASE, event_id::RELEASE_OUTSIDE, event_id::ROLL_OVER, event_id::ROLL_OUT, event_id::DRAG_OVER, event_id::DRAG_OUT, }; for (int i = 0, mask = 1; i < int(sizeof(s_code_bits)/sizeof(s_code_bits[0])); i++, mask <<= 1) { if (flags & mask) { m_event = s_code_bits[i]; break; } } // what to do w/ key_press??? Is the data in the reserved parts of the flags??? if (flags & (1 << 17)) { log_error("swf_event::read -- KEY_PRESS found, not handled yet, flags = 0x%x\n", flags); } Uint32 event_length = in->read_u32(); UNUSED(event_length); // Read the actions. IF_VERBOSE_ACTION(log_msg("---- actions for event %s\n", m_event.get_function_name().c_str())); m_action_buffer.read(in); if (m_action_buffer.get_length() != (int) event_length) { log_error("error -- swf_event::read(), event_length = %d, but read %d\n", event_length, m_action_buffer.get_length()); // @@ discard this event handler?? } // Create a function to execute the actions. array<with_stack_entry> empty_with_stack; as_as_function* func = new as_as_function(&m_action_buffer, NULL, 0, empty_with_stack); func->set_length(m_action_buffer.get_length()); m_method.set_as_as_function(func); } private: // DON'T USE THESE swf_event(const swf_event& s) { assert(0); } void operator=(const swf_event& s) { assert(0); } }; // // place_object_2 // struct place_object_2 : public execute_tag { int m_tag_type; char* m_name; float m_ratio; cxform m_color_transform; matrix m_matrix; bool m_has_matrix; bool m_has_cxform; Uint16 m_depth; Uint16 m_character_id; Uint16 m_clip_depth; enum place_type { PLACE, MOVE, REPLACE, } m_place_type; array<swf_event*> m_event_handlers; place_object_2() : m_tag_type(0), m_name(NULL), m_ratio(0), m_has_matrix(false), m_has_cxform(false), m_depth(0), m_character_id(0), m_clip_depth(0), m_place_type(PLACE) { } ~place_object_2() { delete [] m_name; m_name = NULL; for (int i = 0, n = m_event_handlers.size(); i < n; i++) { delete m_event_handlers[i]; } m_event_handlers.resize(0); } void read(stream* in, int tag_type, int movie_version) { assert(tag_type == 4 || tag_type == 26); m_tag_type = tag_type; if (tag_type == 4) { // Original place_object tag; very simple. m_character_id = in->read_u16(); m_depth = in->read_u16(); m_matrix.read(in); IF_VERBOSE_PARSE( log_msg(" char_id = %d\n" " depth = %d\n" " mat = \n", m_character_id, m_depth); m_matrix.print()); if (in->get_position() < in->get_tag_end_position()) { m_color_transform.read_rgb(in); IF_VERBOSE_PARSE(log_msg(" cxform:\n"); m_color_transform.print()); } } else if (tag_type == 26) { in->align(); bool has_actions = in->read_uint(1) ? true : false; bool has_clip_bracket = in->read_uint(1) ? true : false; bool has_name = in->read_uint(1) ? true : false;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -