void root::set_drag_state(character::drag_state& ds) { m_drag_state = ds; // do we need to calculate the offset? character* ch = ds.GetCharacter(); if (ch == NULL || ds.IsLockCentered()) { return; } // get the character's origin point origin(0, 0); matrix chMatrix = ch->get_world_matrix(); point worldOrigin; chMatrix.transform( &worldOrigin, origin ); // Get current mouse coordinates int x, y, buttons; get_mouse_state(&x, &y, &buttons); // ... in 'world' space (i.e. twips) point worldMouse(PIXELS_TO_TWIPS(x), PIXELS_TO_TWIPS(y)); // we need the offset from the origin of the character float xOffset = worldMouse.m_x - worldOrigin.m_x; float yOffset = worldMouse.m_y - worldOrigin.m_y; m_drag_state.SetOffset(xOffset, yOffset); }
void rect::pixels_to_twips() { m_x_min = PIXELS_TO_TWIPS(m_x_min); m_y_min = PIXELS_TO_TWIPS(m_y_min); m_x_max = PIXELS_TO_TWIPS(m_x_max); m_y_max = PIXELS_TO_TWIPS(m_y_max); }
void video_stream_definition::get_bound(rect* bound) { bound->m_x_min = 0; bound->m_y_min = 0; bound->m_x_max = PIXELS_TO_TWIPS(m_width); bound->m_y_max = PIXELS_TO_TWIPS(m_height); }
// Implement mouse-dragging for this movie. void root::do_mouse_drag() { character* draggingChar = m_drag_state.GetCharacter(); if (draggingChar == NULL) { return; } // handle if the character isn't valid anymore if (draggingChar->is_alive() == false) { // no longer valid m_drag_state.Reset(); return; } // get the current mouse int x, y, buttons; get_mouse_state( &x, &y, &buttons ); // ... in world coordinates (twips) point worldMouse( PIXELS_TO_TWIPS(x), PIXELS_TO_TWIPS(y) ); matrix parentWorldMat; if (draggingChar->m_parent != NULL) { parentWorldMat = draggingChar->m_parent->get_world_matrix(); } // if we're not locked to the center - adjust by the offset we started dragging by if(m_drag_state.IsLockCentered() == false) { worldMouse.m_x -= m_drag_state.OffsetX(); worldMouse.m_y -= m_drag_state.OffsetY(); } rect origBoundRect; if (m_drag_state.GetBounds(&origBoundRect)) { // bounds are in local coordinate space rect bounds; bounds.enclose_transformed_rect( parentWorldMat, origBoundRect ); // Clamp mouse coords within a defined rect. worldMouse.m_x = fclamp(worldMouse.m_x, bounds.m_x_min, bounds.m_x_max); worldMouse.m_y = fclamp(worldMouse.m_y, bounds.m_y_min, bounds.m_y_max); } point parentMouse; parentWorldMat.transform_by_inverse( &parentMouse, worldMouse ); // Place our origin so that it coincides with the mouse coords // in our parent frame. matrix local = draggingChar->get_matrix(); local.m_[0][2] = parentMouse.m_x;//set translation x local.m_[1][2] = parentMouse.m_y;//set translation y draggingChar->set_matrix( local ); }
// public lineTo(x:Number, y:Number) : Void void sprite_line_to(const fn_call& fn) { sprite_instance* sprite = sprite_getptr(fn); canvas* canva = sprite->get_canvas(); assert(canva); if (fn.nargs >= 2) { float x = PIXELS_TO_TWIPS(fn.arg(0).to_float()); float y = PIXELS_TO_TWIPS(fn.arg(1).to_float()); canva->line_to(x, y); } }
// setpos xy void CMenuFxObj::setPosition( int x, int y ) { if ( m_character ) { const gameswf::matrix& curMat = m_character->get_matrix(); gameswf::matrix mat; mat.concatenate_translation(PIXELS_TO_TWIPS(x), PIXELS_TO_TWIPS(y)); mat.set_scale_rotation( curMat.get_x_scale(), curMat.get_y_scale(), curMat.get_rotation() ); m_character->set_matrix(mat); } }
// public curveTo(controlX:Number, controlY:Number, anchorX:Number, anchorY:Number) : Void void sprite_curve_to(const fn_call& fn) { sprite_instance* sprite = sprite_getptr(fn); canvas* canva = sprite->get_canvas(); assert(canva); if (fn.nargs >= 4) { float cx = PIXELS_TO_TWIPS(fn.arg(0).to_float()); float cy = PIXELS_TO_TWIPS(fn.arg(1).to_float()); float ax = PIXELS_TO_TWIPS(fn.arg(2).to_float()); float ay = PIXELS_TO_TWIPS(fn.arg(3).to_float()); canva->curve_to(cx, cy, ax, ay); } }
void sprite_start_drag(const fn_call& fn) { sprite_instance* sprite = sprite_getptr(fn); character::drag_state ds; ds.SetCharacter(sprite); if (fn.nargs > 0) { // arguments have been given to startDrag ds.SetLockCentered(fn.arg(0).to_bool()); if (fn.nargs >= 5) { // bounds have been given tu_float x0 = PIXELS_TO_TWIPS(fn.arg(1).to_float()); tu_float y0 = PIXELS_TO_TWIPS(fn.arg(2).to_float()); tu_float x1 = PIXELS_TO_TWIPS(fn.arg(3).to_float()); tu_float y1 = PIXELS_TO_TWIPS(fn.arg(4).to_float()); float bx0, bx1, by0, by1; if (x0 < x1) { bx0 = x0; bx1 = x1; } else { bx0 = x1; bx1 = x0; } if (y0 < y1) { by0 = y0; by1 = y1; } else { by0 = y1; by1 = y0; } // we've got bounds ds.SetBounds(bx0, by0, bx1, by1); } } // inform the root fn.get_root()->set_drag_state(ds); }
void video_stream_instance::display() { if (m_ns != NULL) // is video attached ? { video_handler* vh = m_ns->get_video_handler(); assert(vh != NULL); rect bounds; bounds.m_x_min = 0.0f; bounds.m_y_min = 0.0f; bounds.m_x_max = PIXELS_TO_TWIPS(m_def->m_width); bounds.m_y_max = PIXELS_TO_TWIPS(m_def->m_height); cxform cx = get_world_cxform(); gameswf::rgba color = cx.transform(gameswf::rgba()); matrix m = get_world_matrix(); vh->display(&m, &bounds, color); } }
void CMenuFxObj::setAbsolutePosition( int x, int y ) { if ( m_character ) { gameswf::character *parent = m_character->get_parent(); gameswf::point ret(0,0), pos(0,0); while ( parent ) { parent->get_matrix().transform( &ret, pos ); pos = ret; parent = parent->get_parent(); } const gameswf::matrix& curMat = m_character->get_matrix(); gameswf::matrix mat; mat.concatenate_translation(PIXELS_TO_TWIPS(x)- pos.m_x, PIXELS_TO_TWIPS(y)- pos.m_y); mat.set_scale_rotation( curMat.get_x_scale(), curMat.get_y_scale(), curMat.get_rotation() ); m_character->set_matrix(mat); } }
// public lineStyle(thickness:Number, rgb:Number, alpha:Number, pixelHinting:Boolean, // noScale:String, capsStyle:String, jointStyle:String, miterLimit:Number) : Void void sprite_line_style(const fn_call& fn) { sprite_instance* sprite = sprite_getptr(fn); canvas* canva = sprite->get_canvas(); assert(canva); // If a thickness is not specified, or if the parameter is undefined, a line is not drawn if (fn.nargs == 0) { canva->m_current_line = 0; canva->add_path(false); return; } Uint16 width = (Uint16) PIXELS_TO_TWIPS(fclamp(fn.arg(0).to_float(), 0, 255)); rgba color(0, 0, 0, 255); if (fn.nargs >= 2) { color.set(fn.arg(1).to_float()); if (fn.nargs >= 3) { float alpha = fclamp(fn.arg(2).to_float(), 0, 100); color.m_a = Uint8(255 * (alpha/100)); // capsStyle:String - Added in Flash Player 8. // A string that specifies the type of caps at the end of lines. // Valid values are: "round", "square", and "none". // If a value is not indicated, Flash uses round caps. if (fn.nargs >= 6) { //TODO } } } canva->set_line_style(width, color); }
void root::advance(float delta_time) { // Lock gameswf engine. Video is running in separate thread and // it calls gameswf functions from separate thread to set // status of netstream object gameswf_engine_mutex().lock(); // Handle mouse dragging do_mouse_drag(); // Handle the mouse. character *te; m_movie->get_topmost_mouse_entity(te, PIXELS_TO_TWIPS(m_mouse_x), PIXELS_TO_TWIPS(m_mouse_y)); m_mouse_button_state.m_topmost_entity = te; m_mouse_button_state.m_mouse_button_state_current = (m_mouse_buttons & 1); generate_mouse_button_events(&m_mouse_button_state); // advance Action script objects (interval timers, xmlsocket, ...) m_listener.advance(delta_time); m_time_remainder += delta_time; if (m_time_remainder >= m_frame_time) { // mark all as garbage m_player->set_as_garbage(); // this should be called infinitely to not repeat // the game situation after restart tu_random::next_random(); if (m_on_event_load_called == false) { set_flash_vars(m_player->m_flash_vars); if (m_def->m_is_avm2) { const abc_def* adef = m_def->get_abc(); if (adef) { as_environment env(m_player.get_ptr()); gameswf::call_method(adef->get_script_function(), &env, as_value(m_movie.get_ptr()), 0, 0); } } } if (m_player->get_force_realtime_framerate() == true) { while (m_time_remainder >= m_frame_time) { m_movie->advance(m_frame_time); m_time_remainder -= m_frame_time; } } else { m_movie->advance(delta_time); m_time_remainder = fmod(m_time_remainder - m_frame_time, m_frame_time); } if (m_on_event_load_called == false) { // Must do loading events. For child sprites this is // done by the dlist, but root movies don't get added // to a dlist, so we do it here. m_on_event_load_called = true; m_movie->on_event(event_id::LOAD); } m_player->clear_garbage(); } gameswf_engine_mutex().unlock(); }
void point::pixels_to_twips() { m_x = PIXELS_TO_TWIPS(m_x); m_y = PIXELS_TO_TWIPS(m_y); }
// useless stuff ? void x3ds_instance::update_material() { GLint aux_buffers; glGetIntegerv(GL_AUX_BUFFERS, &aux_buffers); if (aux_buffers < 2) { static int n = 0; if (n < 1) { n++; log_error("Your video card does not have AUX buffers, can't snapshot movieclips\n"); } return; } glPushAttrib(GL_ALL_ATTRIB_BITS); // update textures for (stringi_hash<gc_ptr <bitmap_info> >::iterator it = m_material.begin(); it != m_material.end(); ++it) { as_value target = m_map[it->first]; character* ch = find_target(target); if (ch) { if (ch->get_parent() == NULL) { log_error("Can't snapshot _root movieclip, material '%s'\n", it->first.c_str()); continue; } GLint draw_buffer; glGetIntegerv(GL_DRAW_BUFFER, &draw_buffer); glDrawBuffer(GL_AUX1); glReadBuffer(GL_AUX1); // save "ch" matrix matrix ch_matrix = ch->get_matrix(); float ch_width = TWIPS_TO_PIXELS(ch->get_width()); float ch_height = TWIPS_TO_PIXELS(ch->get_height()); // get viewport size GLint vp[4]; glGetIntegerv(GL_VIEWPORT, vp); int vp_width = vp[2]; int vp_height = vp[3]; // get texture size int tw = 1; while (tw < ch_width) { tw <<= 1; } int th = 1; while (th < ch_height) { th <<= 1; } // texture size must be <= viewport size if (tw > vp_width) { tw = vp_width; } if (th > vp_height) { th = vp_height; } ch->set_member("_width", tw); ch->set_member("_height", th); rect bound; ch->get_bound(&bound); // parent world matrix moves point(0,0) to "pzero" matrix mparent = ch->get_parent()->get_world_matrix(); point pzero; mparent.transform_by_inverse(&pzero, point(0, 0)); // after transformation of "ch" matrix left-top corner is in point(bound.m_x_min, bound.m_y_min), // therefore we need to move point(bound.m_x_min, bound.m_y_min) to point(pzero.m_x, pzero.m_y) // that "ch" movieclip's left-top corner will be in point(0,0) of screen matrix m = ch->get_matrix(); float xt = (pzero.m_x - bound.m_x_min) / m.get_x_scale(); float yt = (pzero.m_y - bound.m_y_min) / m.get_y_scale(); // move "ch" to left-bottom corner (as point of origin of OpenGL is in left-bottom) // later glCopyTexImage2D will copy snapshot of "ch" into texture yt += PIXELS_TO_TWIPS(vp_height - th) / m.get_y_scale(); m.concatenate_translation(xt, yt); ch->set_matrix(m); glClearColor(1, 1, 1, 1); glClear(GL_COLOR_BUFFER_BIT); ch->display(); // restore "ch" matrix ch->set_matrix(ch_matrix); gc_ptr<bitmap_info> bi = it->second; if (bi->m_texture_id == 0) { glGenTextures(1, (GLuint*) &bi->m_texture_id); bi->m_original_height = (int) ch_height; bi->m_original_width = (int) ch_width; } glBindTexture(GL_TEXTURE_2D, bi->m_texture_id); glEnable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // GL_NEAREST ? glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0,0, tw, th, 0); glDisable(GL_TEXTURE_2D); glDrawBuffer(draw_buffer); glReadBuffer(draw_buffer); } } glPopAttrib(); }