コード例 #1
0
void JitBlockCache::InvalidateICache(u32 address, const u32 length) {
    // Convert the logical address to a physical address for the block map
    const u32 pAddr = address & 0x1FFFFFFF;
    const u32 pEnd = pAddr + length;

    // Blocks may start and end in overlapping ways, and destroying one invalidates iterators.
    // So after destroying one, we start over.
    do {
restart:
        auto next = block_map_.lower_bound(std::make_pair(pAddr, 0));
        auto last = block_map_.upper_bound(std::make_pair(pEnd + MAX_BLOCK_INSTRUCTIONS, 0));
        // Note that if next is end(), last will be end() too (equal.)
        for (; next != last; ++next) {
            const u32 blockStart = next->first.second;
            const u32 blockEnd = next->first.first;
            if (blockStart < pEnd && blockEnd > pAddr) {
                DestroyBlock(next->second, true);
                // Our iterator is now invalid.  Break and search again.
                // Most of the time there shouldn't be a bunch of matching blocks.
                goto restart;
            }
        }
        // We got here - it wasn't in the map at all (or anymore.)
    } while (false);
}
コード例 #2
0
ファイル: clientnetinterface.cpp プロジェクト: manpat/vox
void OnSetBlock(Packet& packet) {
	auto chmgr = ChunkManager::Get();
	u8 orientation;
	u16 chunkID, blockType;
	ivec3 vxPos;

	// Assume vxPos is in bounds
	packet.Read(chunkID);
	packet.Read<ivec3>(vxPos);
	packet.Read(blockType);

	orientation = blockType & 3;
	blockType >>= 2;

	auto ch = chmgr->GetChunk(chunkID);
	if(!ch) {
		logger << "Missing chunkID " << chunkID;
		return;
	}

	if(blockType) {
		auto blk = ch->CreateBlock(vxPos, blockType);
		if(blk) blk->orientation = orientation;
		else logger << "Block create failed at " << vxPos;
	}else{
		ch->DestroyBlock(vxPos);
	}
}
コード例 #3
0
// This clears the JIT cache. It's called from JitCache.cpp when the JIT cache
// is full and when saving and loading states.
void JitBlockCache::Clear() {
    block_map_.clear();
    proxyBlockMap_.clear();
    for (int i = 0; i < num_blocks_; i++)
        DestroyBlock(i, false);
    links_to_.clear();
    num_blocks_ = 0;

    blockMemRanges_[JITBLOCK_RANGE_SCRATCH] = std::make_pair(0xFFFFFFFF, 0x00000000);
    blockMemRanges_[JITBLOCK_RANGE_RAMBOTTOM] = std::make_pair(0xFFFFFFFF, 0x00000000);
    blockMemRanges_[JITBLOCK_RANGE_RAMTOP] = std::make_pair(0xFFFFFFFF, 0x00000000);
}
コード例 #4
0
void JitBlockCache::DestroyBlock(int block_num, bool invalidate) {
    if (block_num < 0 || block_num >= num_blocks_) {
        ERROR_LOG_REPORT(JIT, "DestroyBlock: Invalid block number %d", block_num);
        return;
    }
    JitBlock *b = &blocks_[block_num];
    // No point it being in there anymore.
    RemoveBlockMap(block_num);

    // Pure proxy blocks always point directly to a real block, there should be no chains of
    // proxy-only blocks pointing to proxy-only blocks.
    // Follow a block proxy chain.
    // Destroy the block that transitively has this as a proxy. Likely the root block once inlined
    // this block or its 'parent', so now that this block has changed, the root block must be destroyed.
    if (b->proxyFor) {
        for (size_t i = 0; i < b->proxyFor->size(); i++) {
            int proxied_blocknum = GetBlockNumberFromStartAddress((*b->proxyFor)[i], false);
            // If it was already cleared, we don't know which to destroy.
            if (proxied_blocknum != -1) {
                DestroyBlock(proxied_blocknum, invalidate);
            }
        }
        b->proxyFor->clear();
        delete b->proxyFor;
        b->proxyFor = 0;
    }
    auto range = proxyBlockMap_.equal_range(b->originalAddress);
    for (auto it = range.first; it != range.second; ++it) {
        if (it->second == block_num) {
            // Found it.  Delete and bail.
            proxyBlockMap_.erase(it);
            break;
        }
    }

    // TODO: Handle the case when there's a proxy block and a regular JIT block at the same location.
    // In this case we probably "leak" the proxy block currently (no memory leak but it'll stay enabled).

    if (b->invalid) {
        if (invalidate)
            ERROR_LOG(JIT, "Invalidating invalid block %d", block_num);
        return;
    }

    b->invalid = true;
    if (Memory::ReadUnchecked_U32(b->originalAddress) == GetEmuHackOpForBlock(block_num).encoding)
        Memory::Write_Opcode_JIT(b->originalAddress, b->originalFirstOpcode);

    // It's not safe to set normalEntry to 0 here, since we use a binary search
    // that looks at that later to find blocks. Marking it invalid is enough.

    UnlinkBlock(block_num);

#if defined(ARM)

    // Send anyone who tries to run this block back to the dispatcher.
    // Not entirely ideal, but .. pretty good.
    // I hope there's enough space...
    // checkedEntry is the only "linked" entrance so it's enough to overwrite that.
    ARMXEmitter emit((u8 *)b->checkedEntry);
    emit.MOVI2R(R0, b->originalAddress);
    emit.STR(R0, CTXREG, offsetof(MIPSState, pc));
    emit.B(MIPSComp::jit->dispatcher);
    emit.FlushIcache();

#elif defined(_M_IX86) || defined(_M_X64)

    // Send anyone who tries to run this block back to the dispatcher.
    // Not entirely ideal, but .. pretty good.
    // Spurious entrances from previously linked blocks can only come through checkedEntry
    XEmitter emit((u8 *)b->checkedEntry);
    emit.MOV(32, M(&mips_->pc), Imm32(b->originalAddress));
    emit.JMP(MIPSComp::jit->Asm().dispatcher, true);
#elif defined(PPC)
    PPCXEmitter emit((u8 *)b->checkedEntry);
    emit.MOVI2R(R3, b->originalAddress);
    emit.STW(R0, CTXREG, offsetof(MIPSState, pc));
    emit.B(MIPSComp::jit->dispatcher);
    emit.FlushIcache();
#endif
}
コード例 #5
0
ファイル: PlayerCombat.cpp プロジェクト: AlwaysGeeky/Vox
void Player::AttackAnimationTimerFinished()
{
	if (IsBow())
	{
	}
	else if (IsBoomerang())
	{
		vec3 boomerangSpawnPosition = GetCenter() + (m_forward*0.75f) + (GetRightVector()*-0.4f) + (GetUpVector()*0.5f);

		float cameraModification = (m_cameraForward.y*17.5f);
		if (m_cameraForward.y < 0.0f)
		{
			cameraModification = (m_cameraForward.y*5.0f);
		}

		vec3 boomerangTarget = boomerangSpawnPosition + m_forward*15.0f + (vec3(0.0f, 1.0f, 0.0f) * cameraModification);
		if (m_pTargetEnemy != NULL)
		{
			boomerangTarget = m_pTargetEnemy->GetProjectileHitboxCenter();
			if (m_pTargetEnemy->IsMoving())
			{
				boomerangTarget += m_pTargetEnemy->GetForwardVector() * (m_pTargetEnemy->GetMovementSpeed() / 3.0f);
			}
		}

		float curveTime = length(boomerangTarget - boomerangSpawnPosition) / 15.0f;
		if (curveTime <= 0.4f)
			curveTime = 0.4f;

		Projectile* pProjectile = m_pProjectileManager->CreateProjectile(boomerangSpawnPosition, vec3(0.0f, 0.0f, 0.0f), 0.0f, "media/gamedata/weapons/Boomerang/BoomerangThrown.weapon", 0.05f);
		pProjectile->SetProjectileType(true, false, false);
		pProjectile->SetOwner(this, NULL, NULL);
		pProjectile->SetGravityMultiplier(0.0f);
		pProjectile->SetReturnToPlayer(true);
		pProjectile->SetProjectileCurveParams(m_forward, boomerangTarget, curveTime);
		pProjectile->SetWorldCollisionEnabled(true);

		m_pVoxelCharacter->SetRenderRightWeapon(false);
	}
	else if (IsStaff())
	{
		float powerAmount = 25.0f;
		float cameraMultiplier = 25.0f;

		vec3 spellSpawnPosition = GetCenter() + (m_forward*1.25f) + (GetUpVector()*0.25f);

		if (VoxGame::GetInstance()->GetCameraMode() == CameraMode_FirstPerson)
		{
			cameraMultiplier = 30.0f;
			spellSpawnPosition.y += 0.75f;
		}

		vec3 spellSpawnVelocity = m_forward * powerAmount + vec3(0.0f, 1.0f, 0.0f) * (m_cameraForward.y*cameraMultiplier);

		if (m_pTargetEnemy != NULL)
		{
			vec3 toTarget = m_pTargetEnemy->GetProjectileHitboxCenter() - GetCenter();
			spellSpawnVelocity = (normalize(toTarget) * powerAmount);
		}

		Projectile* pProjectile = m_pProjectileManager->CreateProjectile(spellSpawnPosition, spellSpawnVelocity, 0.0f, "media/gamedata/items/Fireball/Fireball.item", 0.05f);
		pProjectile->SetProjectileType(true, false, false);
		pProjectile->SetOwner(this, NULL, NULL);
		pProjectile->SetGravityMultiplier(0.0f);
	}
	else if (IsWand())
	{
	}
	else if (IsBomb())
	{
		vec3 bombSpawnPosition = GetCenter() + (m_forward*0.75f) + (GetUpVector()*0.5f);

		float liftAmount = 8.0f;
		float powerAmount = 30.0f;
		float cameraMultiplier = 25.0f;

		if (VoxGame::GetInstance()->GetCameraMode() == CameraMode_FirstPerson)
		{
			cameraMultiplier = 30.0f;
		}

		vec3 bombSpawnVelocity;
		if (m_pTargetEnemy)
		{
			// Enemy target
			vec3 toTarget = m_pTargetEnemy->GetCenter() - GetCenter();
			float toTargetDistance = length(toTarget);
			liftAmount += toTargetDistance * 0.04f;
			bombSpawnVelocity = (normalize(toTarget) * powerAmount) + vec3(0.0f, liftAmount, 0.0f);
		}
		else
		{
			bombSpawnVelocity = (m_forward * powerAmount) + (GetUpVector() * liftAmount) + vec3(0.0f, 1.0f, 0.0f) * (m_cameraForward.y*cameraMultiplier);
		}

		Projectile* pProjectile = m_pProjectileManager->CreateProjectile(bombSpawnPosition, bombSpawnVelocity, 0.0f, "media/gamedata/items/Bomb/BombThrown.item", 0.05f);
		pProjectile->SetProjectileType(true, false, false);
		pProjectile->SetOwner(this, NULL, NULL);
		pProjectile->SetGravityMultiplier(3.5f);
		float explodeRadius = 3.5f - (GetRandomNumber(-150, 0, 2) * 0.01f);
		pProjectile->SetExplodingProjectile(true, explodeRadius);

		//m_pVoxelCharacter->SetRenderRightWeapon(false);

		InventoryItem* pItem = m_pInventoryManager->GetInventoryItemForEquipSlot(EquipSlot_RightHand);
		if (pItem != NULL)
		{
			if (pItem->m_quantity != -1)
			{
				pItem->m_quantity -= 1;
			}
			if (pItem->m_quantity == 0)
			{
				// Remove this item from the manager, and remove it from the inventory and GUI
				UnequipItem(EquipSlot_RightHand, false, false);
				m_pInventoryManager->RemoveInventoryItem(EquipSlot_RightHand);
				m_pActionBar->RemoveInventoryItemFromActionBar(pItem->m_title);
			}
		}
	}
	else if (IsConsumable())
	{
	}
	else if (IsDagger())
	{
	}
	else if (IsHammer())
	{
	}
	else if (IsMace())
	{
	}
	else if (IsSickle())
	{
	}
	else if (IsPickaxe())
	{
		Item* pInteractItem = VoxGame::GetInstance()->GetInteractItem();
		if (pInteractItem != NULL)
		{
			pInteractItem->Interact();
		}
		else
		{
			DestroyBlock();
		}
	}
	else if (IsAxe())
	{
	}
	else if (Is2HandedSword())
	{
	}
	else if (IsSword())
	{
	}
	else if (IsBlockPlacing())
	{
	}
	else if (IsItemPlacing())
	{
	}
	else if (IsSceneryPlacing())
	{
	}
	else if (IsSpellHands())
	{
		float powerAmount = 25.0f;
		float cameraMultiplier = 25.0f;

		vec3 spellSpawnPosition = GetCenter() + (m_forward*0.5f) + (GetUpVector()*0.0f);

		// For right hand
		spellSpawnPosition += -(GetRightVector()*0.4f);

		if (VoxGame::GetInstance()->GetCameraMode() == CameraMode_FirstPerson)
		{
			cameraMultiplier = 30.0f;
			spellSpawnPosition.y += 0.75f;
		}

		vec3 spellSpawnVelocity = m_forward * powerAmount + vec3(0.0f, 1.0f, 0.0f) * (m_cameraForward.y*cameraMultiplier);

		if (m_pTargetEnemy != NULL)
		{
			vec3 toTarget = m_pTargetEnemy->GetProjectileHitboxCenter() - GetCenter();
			spellSpawnVelocity = (normalize(toTarget) * powerAmount);
		}

		Projectile* pProjectile = m_pProjectileManager->CreateProjectile(spellSpawnPosition, spellSpawnVelocity, 0.0f, "media/gamedata/items/Fireball/FireballBlue.item", 0.05f);
		pProjectile->SetProjectileType(true, false, false);
		pProjectile->SetOwner(this, NULL, NULL);
		pProjectile->SetGravityMultiplier(0.0f);
	}
	else if (IsShield())
	{
	}
	else if (IsTorch())
	{
	}
}
コード例 #6
0
ファイル: terrain.cpp プロジェクト: minecube/minecube
void Terrain::DestroyTarget(Player *player) {
    PositionedBlock *block = CheckAim(player);
    if (!block) return;
    
    DestroyBlock(block);
}