/** * aSrcRect: Rect relative to the aSrc surface * aDestPoint: Point inside aDest surface */ void CopyRect(DataSourceSurface* aSrc, DataSourceSurface* aDest, IntRect aSrcRect, IntPoint aDestPoint) { if (aSrcRect.Overflows() || IntRect(aDestPoint, aSrcRect.Size()).Overflows()) { MOZ_CRASH("we should never be getting invalid rects at this point"); } MOZ_RELEASE_ASSERT(aSrc->GetFormat() == aDest->GetFormat(), "different surface formats"); MOZ_RELEASE_ASSERT(IntRect(IntPoint(), aSrc->GetSize()).Contains(aSrcRect), "source rect too big for source surface"); MOZ_RELEASE_ASSERT(IntRect(IntPoint(), aDest->GetSize()).Contains(IntRect(aDestPoint, aSrcRect.Size())), "dest surface too small"); if (aSrcRect.IsEmpty()) { return; } DataSourceSurface::ScopedMap srcMap(aSrc, DataSourceSurface::READ); DataSourceSurface::ScopedMap destMap(aDest, DataSourceSurface::WRITE); if (MOZ2D_WARN_IF(!srcMap.IsMapped() || !destMap.IsMapped())) { return; } uint8_t* sourceData = DataAtOffset(aSrc, srcMap.GetMappedSurface(), aSrcRect.TopLeft()); uint32_t sourceStride = srcMap.GetStride(); uint8_t* destData = DataAtOffset(aDest, destMap.GetMappedSurface(), aDestPoint); uint32_t destStride = destMap.GetStride(); if (BytesPerPixel(aSrc->GetFormat()) == 4) { for (int32_t y = 0; y < aSrcRect.height; y++) { PodCopy((int32_t*)destData, (int32_t*)sourceData, aSrcRect.width); sourceData += sourceStride; destData += destStride; } } else if (BytesPerPixel(aSrc->GetFormat()) == 1) { for (int32_t y = 0; y < aSrcRect.height; y++) { PodCopy(destData, sourceData, aSrcRect.width); sourceData += sourceStride; destData += destStride; } } }
void Execute(scriptID id, ScriptStack& scriptState) { Script script = scripts[id]; Script::const_iterator ins = script.begin(); Script::const_iterator end = script.end(); for (; ins != end; ++ins) { switch(ins->GetCode()) { ///////////////////////////////////////////////////////////////////////////// case op_noop: break; case op_push: { const unsigned char* data = ins->GetData(); ptr size = *(ptr*)data; // SIZE MISMATCH, fix it ppeas Phil unsigned char* value = (unsigned char*)DataAtOffset(data, 1); scriptState.push(value, size); } break; ///////////////////////////////////////////////////////////////////////////// case op_end: return; break; ///////////////////////////////////////////////////////////////////////////// case op_forceout: { // figure out our overlap and how much we have. const unsigned char* data = ins->GetData(); Actor* target = GetActor(scriptState.get(*data)); Actor* source = GetActor( scriptState.get(*DataAtOffset(data, 1)) ); const Box* sourceBox = source->GetCollision(); const Box* targetBox = target->GetCollision(); if ( !BoxesIntersect(sourceBox, targetBox) ) { return; } float x1, x2, x3, x4, y1, y2, y3, y4; x1 = sourceBox->GetUpperLeft().x; x2 = targetBox->GetUpperRight().x; x3 = sourceBox->GetUpperRight().x; x4 = targetBox->GetUpperLeft().x; y1 = sourceBox->GetLowerLeft().y; y2 = targetBox->GetUpperLeft().y; y3 = sourceBox->GetUpperLeft().y; y4 = targetBox->GetLowerLeft().y; float bottomOverlap = y1-y2+COLLISION_PADDING; float topOverlap = y3-y4-COLLISION_PADDING; float leftOverlap = x1-x2-COLLISION_PADDING; float rightOverlap = x3-x4+COLLISION_PADDING; float moveY = abs(topOverlap) > abs(bottomOverlap) ? bottomOverlap : topOverlap; float moveX = abs(leftOverlap) > abs(rightOverlap) ? rightOverlap : leftOverlap; Vector2 moveFirst, moveSecond; if (abs(moveX) < abs(moveY)) { moveFirst.x = moveX; moveSecond.y = moveY; } else { moveFirst.y = moveY; moveSecond.x = moveX; } target->Move(moveFirst); if ( BoxesIntersect(sourceBox, targetBox) ) { target->Move(moveSecond); } } break; ///////////////////////////////////////////////////////////////////////////// case op_playanim: { const unsigned char* data = ins->GetData(); Actor* target = GetActor(scriptState.get(*data)); unsigned char animName = (unsigned char)*( DataAtOffset(data, 1) ); target->GetAnimComponent()->PlayAnim((char*)scriptState.get(animName)); } break; ///////////////////////////////////////////////////////////////////////////// case op_kill: const unsigned char* data = ins->GetData(); Actor* target = (Actor*) scriptState.get(*(unsigned int*)data); target->MarkForCleanup(); break; } // end switch(instruction) } // end for } // end Execute