bool OptimizedTextureInfo::PlaceRect(ff::RectInt rect)
{
	ff::RectInt rectCells(
		rect.left / s_gridSize,
		rect.top  / s_gridSize,
		(rect.right  + s_gridSize - 1) / s_gridSize,
		(rect.bottom + s_gridSize - 1) / s_gridSize);

	assertRetVal(
		rect.left >= 0 && rect.right  <= _size.x &&
		rect.top  >= 0 && rect.bottom <= _size.y &&
		rect.Width() > 0 &&
		rect.Height() > 0, false);

	// Validate that the sprite doesn't overlap anything

	for (int y = rectCells.top - 1; y <= rectCells.bottom; y++)
	{
		if (y >= 0 && y < _size.y / s_gridSize && y < _countof(_rowRight))
		{
			// Must be a one cell gap between sprites
			assertRetVal(!_rowRight[y] ||
				_rowRight[y]   + 1 <= rectCells.left ||
				rectCells.right + 1 <= _rowLeft[y], false);
		}
	}

	// Invalidate the space taken up by the new sprite

	for (int y = rectCells.top; y < rectCells.bottom; y++)
	{
		if (y >= 0 && y < _size.y / s_gridSize && y < _countof(_rowRight))
		{
			if (_rowRight[y])
			{
				_rowLeft[y]  = std::min<BYTE>(_rowLeft[y],  rectCells.left);
				_rowRight[y] = std::max<BYTE>(_rowRight[y], rectCells.right);
			}
			else
			{
				_rowLeft[y]  = rectCells.left;
				_rowRight[y] = rectCells.right;
			}
		}
	}

	return true;
}
Exemple #2
0
ff::ComPtr<ff::ICommandRouter> ff::ViewWindow::CreateCommandRouter()
{
	ComPtr<ICommandRouter> router;
	assertRetVal(ff::CreateNullCommandRouter(&router), ComPtr<ICommandRouter>());

	return router;
}
static bool ConvertOptimizedTextures(
	DXGI_FORMAT format,
	size_t mipMapLevels,
	ff::Vector<ff::ComPtr<ff::IGraphTexture>> &textures,
	ff::Vector<ff::ComPtr<ff::IGraphTexture>> &finalTextures,
	ff::Vector<std::shared_ptr<DirectX::ScratchImage>> &alphaTextures)
{
	for (size_t i = 0; i < textures.Size(); i++)
	{
		ff::IGraphTexture *texture = textures[i];
		ff::IGraphDevice *device = texture->GetDevice();

		ff::ComPtr<ff::IGraphTexture> newTexture;
		assertRetVal(texture->Convert(format, mipMapLevels, &newTexture), false);
		finalTextures.Push(newTexture);

		DirectX::ScratchImage scratch;
		assertHrRetVal(DirectX::CaptureTexture(device->Get3d(), device->GetContext(), texture->GetTexture(), scratch), false);

		std::shared_ptr<DirectX::ScratchImage> alphaScratch = std::make_shared<DirectX::ScratchImage>();
		assertHrRetVal(DirectX::Convert(scratch.GetImages(), 1, scratch.GetMetadata(), DXGI_FORMAT_A8_UNORM, DirectX::TEX_FILTER_DEFAULT, 0, *alphaScratch), false);
		alphaTextures.Push(alphaScratch);
	}

	return true;
}
Exemple #4
0
bool ff::Value::CreateGuid(REFGUID guid, Value **ppValue)
{
	assertRetVal(ppValue, false);

	if (guid != GUID_NULL)
	{
		*ppValue = NewValueOneRef();
		(*ppValue)->SetType(Type::Guid);
		(*ppValue)->_guid = guid;
	}
	else
	{
		static Value::StaticValue s_data;
		static Value *s_val = nullptr;

		if (!s_val)
		{
			ScopeStaticValueAlloc scopeAlloc;

			if (!s_val)
			{
				s_val = s_data.AsValue();
				s_val->Value::Value();
				s_val->SetType(Type::Guid);
				s_val->_guid = GUID_NULL;
			}
		}

		*ppValue = s_val;
	}

	return true;
}
Exemple #5
0
ff::String ff::SmallDict::KeyAt(size_t index) const
{
	assertRetVal(index < Size(), ff::GetEmptyString());

	hash_t hash = _data->entries[index].hash;
	return _data->atomizer->GetString(hash);
}
Exemple #6
0
bool ff::Value::CreateRectF(const RectFloat &rect, Value **ppValue)
{
	assertRetVal(ppValue, false);

	if (!rect.IsNull())
	{
		*ppValue = NewValueOneRef();
		(*ppValue)->SetType(Type::RectF);
		(*ppValue)->InternalGetRectF() = rect;
	}
	else
	{
		static Value::StaticValue s_data;
		static Value *s_val = nullptr;

		if (!s_val)
		{
			ScopeStaticValueAlloc scopeAlloc;

			if (!s_val)
			{
				s_val = s_data.AsValue();
				s_val->Value::Value();
				s_val->SetType(Type::RectF);
				s_val->InternalGetRectF().SetRect(0, 0, 0, 0);
			}
		}

		*ppValue = s_val;
	}

	return true;
}
Exemple #7
0
bool ff::Value::CreateString(StringRef str, Value **ppValue)
{
	assertRetVal(ppValue, false);

	if (!str.length())
	{
		static Value::StaticValue s_data;
		static Value *s_val = nullptr;

		if (!s_val)
		{
			ScopeStaticValueAlloc scopeAlloc;

			if (!s_val)
			{
				s_val = s_data.AsValue();
				s_val->Value::Value();
				s_val->SetType(Type::String);
				s_val->InternalGetString().String::String();
			}
		}

		*ppValue = s_val;
	}
	else
	{
		*ppValue = NewValueOneRef();
		(*ppValue)->SetType(Type::String);
		(*ppValue)->InternalGetString().String::String(str);
	}

	return true;
}
Exemple #8
0
bool ff::Value::CreateObject(IUnknown *pObj, Value **ppValue)
{
	assertRetVal(ppValue, false);

	if (pObj)
	{
		*ppValue = NewValueOneRef();
		(*ppValue)->SetType(Type::Object);
		(*ppValue)->_object = GetAddRef(pObj);
	}
	else
	{
		static Value::StaticValue s_data;
		static Value *s_val = nullptr;

		if (!s_val)
		{
			ScopeStaticValueAlloc scopeAlloc;

			if (!s_val)
			{
				s_val = s_data.AsValue();
				s_val->Value::Value();
				s_val->SetType(Type::Object);
				s_val->_object = nullptr;
			}
		}

		*ppValue = s_val;
	}

	return true;
}
bool ff::EntityDomain::DeleteComponent(Entity entity, ComponentFactoryEntry *factoryEntry)
{
	assertRetVal(factoryEntry, false);
	EntityEntry *entityEntry = EntityEntry::FromEntity(entity);

	size_t i = (entityEntry->_componentBits & factoryEntry->_bit) != 0
		? entityEntry->_components.Find(factoryEntry)
		: INVALID_SIZE;

	if (i != INVALID_SIZE)
	{
		UnregisterEntityWithSystems(entityEntry, factoryEntry);
		verify(factoryEntry->_factory->Delete(entity));

		entityEntry->_components.Delete(i);
		entityEntry->_componentBits = 0;

		for (ComponentFactoryEntry *factoryEntry: entityEntry->_components)
		{
			entityEntry->_componentBits |= factoryEntry->_bit;
		}

		return true;
	}

	return false;
}
Exemple #10
0
bool ff::Value::CreateBool(bool val, Value **ppValue)
{
	assertRetVal(ppValue, false);

	static Value::StaticValue s_data[2];
	static bool s_init = false;

	if (!s_init)
	{
		ScopeStaticValueAlloc scopeAlloc;

		if (!s_init)
		{
			Value *pVal = s_data[0].AsValue();
			pVal->Value::Value();
			pVal->SetType(Type::Bool);
			pVal->_bool = false;

			pVal = s_data[1].AsValue();
			pVal->Value::Value();
			pVal->SetType(Type::Bool);
			pVal->_bool = true;

			s_init = true;
		}
	}

	*ppValue = s_data[val ? 1 : 0].AsValue();

	return true;
}
Exemple #11
0
bool ff::Value::CreateFloat(float val, Value **ppValue)
{
	assertRetVal(ppValue, false);

	if (val)
	{
		*ppValue = NewValueOneRef();
		(*ppValue)->SetType(Type::Float);
		(*ppValue)->_float = val;
	}
	else
	{
		static Value::StaticValue s_data;
		static Value *s_val = nullptr;

		if (!s_val)
		{
			ScopeStaticValueAlloc scopeAlloc;

			if (!s_val)
			{
				s_val = s_data.AsValue();
				s_val->Value::Value();
				s_val->SetType(Type::Float);
				s_val->_float = 0;
			}
		}

		*ppValue = s_val;
	}

	return true;
}
Exemple #12
0
bool ff::ViewWindow::Deactivate(bool hide)
{
	assertRetVal(IsValid(), true);

	if (_active)
	{
		_active = false;
#if !METRO_APP
		if (hide)
		{
			SetWindowPos(Handle(), HWND_TOP, RectInt(0, 0, 0, 0), SWP_HIDEWINDOW | SWP_NOOWNERZORDER);
		}

		if (_mainWindow != nullptr)
		{
			HWND child = GetChildWindow();
			if (child && ff::IsAncestor(child, Handle()))
			{
				_mainWindow->HideSharedViewTarget();
			}
		}
#endif
		OnDeactivated();
	}

	return true;
}
Exemple #13
0
bool ff::Value::CreatePointF(const PointFloat &point, Value **ppValue)
{
	assertRetVal(ppValue, false);

	if (point.x || point.y)
	{
		*ppValue = NewValueOneRef();
		(*ppValue)->SetType(Type::PointF);
		(*ppValue)->InternalGetPointF() = point;
	}
	else
	{
		static Value::StaticValue s_data;
		static Value *s_val = nullptr;

		if (!s_val)
		{
			ScopeStaticValueAlloc scopeAlloc;

			if (!s_val)
			{
				s_val = s_data.AsValue();
				s_val->Value::Value();
				s_val->SetType(Type::PointF);
				s_val->InternalGetPointF().SetPoint(0, 0);
			}
		}

		*ppValue = s_val;
	}

	return true;
}
bool ff::SaveBytes(IDataWriter *pWriter, const void *pMem, size_t nBytes)
{
	assertRetVal(pWriter, false);
	assertRetVal(pWriter->Write(pMem, nBytes), false);

	// Make sure that the data size is a multiple of 32 bits
	// STATIC_DATA (pod)
	static const BYTE padding[4] = { 0, 0, 0, 0 };
	size_t nPadding = RoundUpTo4(nBytes) - nBytes;

	if (nPadding)
	{
		assertRetVal(pWriter->Write(padding, nPadding), false);
	}

	return true;
}
bool ff::SaveData<ff::String>(ff::IDataWriter *pWriter, ff::StringRef data)
{
	DWORD nBytes = (DWORD)((data.length() + 1) * sizeof(wchar_t));

	assertRetVal(SaveData(pWriter, nBytes), false);

	return SaveBytes(pWriter, data.c_str(), nBytes);
}
bool ff::LoadBytes(IDataReader *pReader, size_t nBytes, IData **ppData)
{
	assertRetVal(pReader, false);

	ComPtr<IData> pData;
	size_t nNewPos = std::min(pReader->GetSize(), pReader->GetPos() + RoundUpTo4(nBytes));

	assertRetVal(pReader->Read(nBytes, ppData ? &pData : nullptr), false);
	assertRetVal(pReader->SetPos(nNewPos), false);

	if (ppData)
	{
		*ppData = pData.Detach();
	}

	return true;
}
Exemple #17
0
bool ff::WriteUnicodeBOM(IDataWriter *pWriter)
{
	assertRetVal(pWriter, false);

	WORD bom = 0xFEFF;

	return pWriter->Write(&bom, sizeof(bom));
}
ff::Component *ff::EntityDomain::CloneComponent(Entity entity, Entity sourceEntity, ComponentFactoryEntry *factoryEntry)
{
	assertRetVal(factoryEntry, nullptr);
	Component *component = LookupComponent(entity, factoryEntry);
	assertRetVal(component == nullptr, component);

	component = factoryEntry->_factory->Clone(entity, sourceEntity);
	EntityEntry *entityEntry = EntityEntry::FromEntity(entity);
	assert(entityEntry->_components.Find(factoryEntry) == INVALID_SIZE);

	entityEntry->_componentBits |= factoryEntry->_bit;
	entityEntry->_components.Push(factoryEntry);

	RegisterEntityWithSystems(entityEntry, factoryEntry);

	return component;
}
Exemple #19
0
bool ff::WriteUnicodeBOMToFile(HANDLE hFile)
{
	assertRetVal(hFile, false);

	WORD bom = 0xFEFF;

	return WriteFile(hFile, &bom, sizeof(bom));
}
Exemple #20
0
size_t ff::SetFilePointerToEnd(HANDLE hFile)
{
	assertRetVal(hFile, INVALID_SIZE);

	LARGE_INTEGER cur;
	LARGE_INTEGER move;
	move.QuadPart = 0;

	assertRetVal(::SetFilePointerEx(hFile, move, &cur, FILE_END), INVALID_SIZE);

#ifdef _WIN64
	return cur.QuadPart;
#else
	assertRetVal(!cur.HighPart, INVALID_SIZE);
	return cur.LowPart;
#endif
}
Exemple #21
0
bool ff::BufferCache::CreateBuffer(size_t nBytes, ID3D11Buffer **ppBuffer)
{
	assertRetVal(nBytes && ppBuffer && _device && _device->GetDX(), false);

	D3D11_BUFFER_DESC desc;
	ZeroObject(desc);

	desc.ByteWidth      = (UINT)nBytes;
	desc.Usage          = D3D11_USAGE_DYNAMIC;
	desc.BindFlags      = _binding;
	desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;

	assertRetVal(SUCCEEDED(_device->GetDX()->CreateBuffer(&desc, nullptr, ppBuffer)), false);
	assertRetVal(*ppBuffer, false);

	return true;
}
Exemple #22
0
ff::INativeHostControl *ff::ClrStartup(StringRef versionOrAssembly)
{
	// Use my own empty config file
	ComPtr<IDataFile> configFile;
	assertRetVal(GetAppConfig(&configFile), false);

	return ClrStartup(configFile->GetPath(), versionOrAssembly);
}
bool ff::OptimizeSprites(ISpriteList *pSprites, DXGI_FORMAT format, size_t nMipMapLevels, ISpriteList **ppOptimizedSprites)
{
	assertRetVal(pSprites && ppOptimizedSprites, false);

	// Create the return value
	ComPtr<ISpriteList> pNewSprites;
	assertRetVal(CreateSpriteList(pSprites->GetDevice(), &pNewSprites), false);

	// Cache all the sprites
	Vector<OptimizedSpriteInfo> sprites;
	sprites.Reserve(pSprites->GetCount());

	for (size_t i = 0; i < pSprites->GetCount(); i++)
	{
		OptimizedSpriteInfo sprite(pSprites->Get(i), i);
		sprites.Push(sprite);
	}

	// Sort the sprites by size
	if (!sprites.IsEmpty())
	{
		qsort(sprites.Data(), sprites.Size(), sizeof(OptimizedSpriteInfo), CompareSpriteInfo);
	}

	// Figure out how many textures to create
	Vector<OptimizedTextureInfo> textureInfos;
	Vector<ComPtr<IGraphTexture>> textures;
	Vector<ComPtr<IGraphTexture>> finalTextures;
	Vector<std::shared_ptr<DirectX::ScratchImage>> alphaTextures;

	assertRetVal(ComputeOptimizedSprites(sprites, textureInfos), false);
	assertRetVal(CreateOptimizedTextures(format, pSprites->GetDevice(), textureInfos, textures), false);

	if (!sprites.IsEmpty())
	{
		qsort(sprites.Data(), sprites.Size(), sizeof(OptimizedSpriteInfo), CompareSpriteInfoIndex);
	}

	assertRetVal(CopyOptimizedSprites(sprites, textures), false);
	assertRetVal(ConvertOptimizedTextures(format, nMipMapLevels, textures, finalTextures, alphaTextures), false);

	// Create final sprites
	for (size_t i = 0; i < sprites.Size(); i++)
	{
		OptimizedSpriteInfo &sprite = sprites[i];
		const SpriteData &data = sprite._sprite->GetSpriteData();
		SpriteType type = UpdateSpriteType(sprite, *alphaTextures[sprite._destTexture]);

		assertRetVal(pNewSprites->Add(
			finalTextures[sprite._destTexture],
			data._name,
			sprite._destRect.ToFloat(),
			sprite._srcHandle,
			sprite._srcScale,
			type), false);
	}

	*ppOptimizedSprites = pNewSprites.Detach();
	return true;
}
Exemple #24
0
ff::ValuePtr TextureTransformValue(ff::StringRef name, const ff::Dict &input)
{
	ff::String fileProp = input.GetString(PROP_FILE);
	size_t mipsProp = input.GetSize(PROP_MIPS, 1);
	ff::String formatProp = input.GetString(PROP_FORMAT, ff::String(L"rgba32"));
	DXGI_FORMAT format = ff::ParseTextureFormat(formatProp);
	assertRetVal(fileProp.size() && format != DXGI_FORMAT_UNKNOWN, nullptr);

	ff::String basePath = input.GetString(RES_BASE);
	ff::String fullFile = basePath;
	ff::AppendPathTail(fullFile, fileProp);

	ff::ComPtr<IUnknown> catParent = ff::ProcessGlobals::Get()->GetModules().CreateParentForCategory(ff::GetCategoryGraphicsObject(), nullptr);
	ff::ComPtr<ff::IGraphDevice> graph;
	assertRetVal(graph.QueryFrom(catParent), nullptr);

	ff::ComPtr<ff::IGraphTexture> texture;
	assertRetVal(ff::CreateGraphTexture(graph, fullFile, format, mipsProp, &texture), nullptr);

	ff::ComPtr<ff::IResourceSave> resourceSave;
	assertRetVal(resourceSave.QueryFrom(texture), nullptr);

	ff::Dict textureSave;
	assertRetVal(resourceSave->SaveResource(textureSave), nullptr);

	ff::ComPtr<ff::IData> textureData = textureSave.GetData(PROP_DATA);
	assertRetVal(textureData, nullptr);

	ff::ValuePtr outputValue;
	assertRetVal(ff::Value::CreateData(textureData, &outputValue), nullptr);

	return outputValue;
}
Exemple #25
0
bool ff::ViewWindow::Create(PWND parent, ViewType type)
{
	assertRetVal(parent, false);
	_viewType = type;

#if !METRO_APP
	ff::String viewName = String::from_acp(typeid(*this).name() + 6); // skip "class "
	assertRetVal(CreateBlank(viewName, parent, WS_CHILD), false);
	_allowLayout = true;
#endif

	assertRetVal((_commandRouter = CreateCommandRouter()) != nullptr, false);
	assertRetVal(Initialize(), false);

	// Don't do Layout() until the view is activated

	return true;
}
bool ff::LoadBytes(IDataReader *pReader, void *pMem, size_t nBytes)
{
	const BYTE* pData = LoadBytes(pReader, nBytes);
	assertRetVal(pData && pMem, false);

	CopyMemory(pMem, pData, nBytes);

	return true;
}
bool ff::EntityDomain::AddSystem(std::shared_ptr<EntitySystemBase> system)
{
	assertRetVal(system != nullptr && system->GetDomain() == this, false);

	SystemEntry &systemEntry = _systems.Insert();
	SetSystem(systemEntry, system);

	return true;
}
ff::Component *ff::EntityDomain::LookupComponent(Entity entity, ComponentFactoryEntry *factoryEntry)
{
	assertRetVal(factoryEntry, nullptr);
	EntityEntry *entityEntry = EntityEntry::FromEntity(entity);

	return ((entityEntry->_componentBits & factoryEntry->_bit) != 0)
		? factoryEntry->_factory->Lookup(entity)
		: nullptr;
}
Exemple #29
0
ff::RectFloat ff::SpriteData::GetTextureRectF() const
{
	assertRetVal(_texture, RectFloat(0, 0, 0, 0));

	PointFloat texSize = _texture->GetSize().ToFloat();
	RectFloat texRect = _textureUV * texSize;
	texRect.Normalize();

	return texRect;
}
Exemple #30
0
bool ff::Value::CreateSavedDict(ff::ISavedData *data, Value **ppValue)
{
	assertRetVal(data && ppValue, false);

	*ppValue = NewValueOneRef();
	(*ppValue)->SetType(Type::SavedDict);
	(*ppValue)->_savedData = ff::GetAddRef(data);

	return true;
}