Example #1
0
int CLayerQuads::BrushGrab(CLayerGroup *pBrush, CUIRect Rect)
{
	// create new layers
	CLayerQuads *pGrabbed = new CLayerQuads();
	pGrabbed->m_pEditor = m_pEditor;
	pGrabbed->m_Image = m_Image;
	pBrush->AddLayer(pGrabbed);
	
	//dbg_msg("", "%f %f %f %f", rect.x, rect.y, rect.w, rect.h);
	for(int i = 0; i < m_lQuads.size(); i++)
	{
		CQuad *q = &m_lQuads[i];
		float px = fx2f(q->m_aPoints[4].x);
		float py = fx2f(q->m_aPoints[4].y);
		
		if(px > Rect.x && px < Rect.x+Rect.w && py > Rect.y && py < Rect.y+Rect.h)
		{
			dbg_msg("", "grabbed one");
			CQuad n;
			n = *q;
			
			for(int p = 0; p < 5; p++)
			{
				n.m_aPoints[p].x -= f2fx(Rect.x);
				n.m_aPoints[p].y -= f2fx(Rect.y);
			}
			
			pGrabbed->m_lQuads.add(n);
		}
	}
	
	return pGrabbed->m_lQuads.size()?1:0;
}
Example #2
0
void CLayerQuads::GetSize(float *w, float *h)
{
	*w = 0; *h = 0;
	
	for(int i = 0; i < m_lQuads.size(); i++)
	{
		for(int p = 0; p < 5; p++)
		{
			*w = max(*w, fx2f(m_lQuads[i].m_aPoints[p].x));
			*h = max(*h, fx2f(m_lQuads[i].m_aPoints[p].y));
		}
	}
}
Example #3
0
void CLayerQuads::BrushRotate(float Amount)
{
	vec2 Center;
	GetSize(&Center.x, &Center.y);
	Center.x /= 2;
	Center.y /= 2;

	for(int i = 0; i < m_lQuads.size(); i++)
	{
		CQuad *q = &m_lQuads[i];
		
		for(int p = 0; p < 5; p++)
		{
			vec2 Pos(fx2f(q->m_aPoints[p].x), fx2f(q->m_aPoints[p].y));
			Rotate(&Center, &Pos, Amount);
			q->m_aPoints[p].x = f2fx(Pos.x);
			q->m_aPoints[p].y = f2fx(Pos.y);
		}
	}
}
Example #4
0
void CRenderTools::RenderQuads(CQuad *pQuads, int NumQuads, int RenderFlags, void (*pfnEval)(float TimeOffset, int Env, float *pChannels, void *pUser), void *pUser)
{
	if(g_Config.m_ClShowEntities && g_Config.m_ClDDRaceCheats)
		return;

	Graphics()->QuadsBegin();
	float Conv = 1/255.0f;
	for(int i = 0; i < NumQuads; i++)
	{
		CQuad *q = &pQuads[i];

		float r=1, g=1, b=1, a=1;

		if(q->m_ColorEnv >= 0)
		{
			float aChannels[4];
			pfnEval(q->m_ColorEnvOffset/1000.0f, q->m_ColorEnv, aChannels, pUser);
			r = aChannels[0];
			g = aChannels[1];
			b = aChannels[2];
			a = aChannels[3];
		}

		bool Opaque = false;
		if(a < 0.01f || (q->m_aColors[0].a < 0.01f && q->m_aColors[1].a < 0.01f && q->m_aColors[2].a < 0.01f && q->m_aColors[3].a < 0.01f))
			Opaque = true;

		if(Opaque && !(RenderFlags&LAYERRENDERFLAG_OPAQUE))
			continue;
		if(!Opaque && !(RenderFlags&LAYERRENDERFLAG_TRANSPARENT))
			continue;

		Graphics()->QuadsSetSubsetFree(
			fx2f(q->m_aTexcoords[0].x), fx2f(q->m_aTexcoords[0].y),
			fx2f(q->m_aTexcoords[1].x), fx2f(q->m_aTexcoords[1].y),
			fx2f(q->m_aTexcoords[2].x), fx2f(q->m_aTexcoords[2].y),
			fx2f(q->m_aTexcoords[3].x), fx2f(q->m_aTexcoords[3].y)
		);

		float OffsetX = 0;
		float OffsetY = 0;
		float Rot = 0;

		// TODO: fix this
		if(q->m_PosEnv >= 0)
		{
			float aChannels[4];
			pfnEval(q->m_PosEnvOffset/1000.0f, q->m_PosEnv, aChannels, pUser);
			OffsetX = aChannels[0];
			OffsetY = aChannels[1];
			Rot = aChannels[2]/360.0f*pi*2;
		}

		IGraphics::CColorVertex Array[4] = {
			IGraphics::CColorVertex(0, q->m_aColors[0].r*Conv*r, q->m_aColors[0].g*Conv*g, q->m_aColors[0].b*Conv*b, q->m_aColors[0].a*Conv*a),
			IGraphics::CColorVertex(1, q->m_aColors[1].r*Conv*r, q->m_aColors[1].g*Conv*g, q->m_aColors[1].b*Conv*b, q->m_aColors[1].a*Conv*a),
			IGraphics::CColorVertex(2, q->m_aColors[2].r*Conv*r, q->m_aColors[2].g*Conv*g, q->m_aColors[2].b*Conv*b, q->m_aColors[2].a*Conv*a),
			IGraphics::CColorVertex(3, q->m_aColors[3].r*Conv*r, q->m_aColors[3].g*Conv*g, q->m_aColors[3].b*Conv*b, q->m_aColors[3].a*Conv*a)};
		Graphics()->SetColorVertex(Array, 4);

		CPoint *pPoints = q->m_aPoints;

		if(Rot != 0)
		{
			static CPoint aRotated[4];
			aRotated[0] = q->m_aPoints[0];
			aRotated[1] = q->m_aPoints[1];
			aRotated[2] = q->m_aPoints[2];
			aRotated[3] = q->m_aPoints[3];
			pPoints = aRotated;

			Rotate(&q->m_aPoints[4], &aRotated[0], Rot);
			Rotate(&q->m_aPoints[4], &aRotated[1], Rot);
			Rotate(&q->m_aPoints[4], &aRotated[2], Rot);
			Rotate(&q->m_aPoints[4], &aRotated[3], Rot);
		}

		IGraphics::CFreeformItem Freeform(
			fx2f(pPoints[0].x)+OffsetX, fx2f(pPoints[0].y)+OffsetY,
			fx2f(pPoints[1].x)+OffsetX, fx2f(pPoints[1].y)+OffsetY,
			fx2f(pPoints[2].x)+OffsetX, fx2f(pPoints[2].y)+OffsetY,
			fx2f(pPoints[3].x)+OffsetX, fx2f(pPoints[3].y)+OffsetY);
		Graphics()->QuadsDrawFreeform(&Freeform, 1);
	}
	Graphics()->QuadsEnd();
}
Example #5
0
void CRenderTools::RenderEvalEnvelope(CEnvPoint *pPoints, int NumPoints, int Channels, float Time, float *pResult)
{
	if(NumPoints == 0)
	{
		pResult[0] = 0;
		pResult[1] = 0;
		pResult[2] = 0;
		pResult[3] = 0;
		return;
	}

	if(NumPoints == 1)
	{
		pResult[0] = fx2f(pPoints[0].m_aValues[0]);
		pResult[1] = fx2f(pPoints[0].m_aValues[1]);
		pResult[2] = fx2f(pPoints[0].m_aValues[2]);
		pResult[3] = fx2f(pPoints[0].m_aValues[3]);
		return;
	}

	Time = fmod(Time, pPoints[NumPoints-1].m_Time/1000.0f)*1000.0f;
	for(int i = 0; i < NumPoints-1; i++)
	{
		if(Time >= pPoints[i].m_Time && Time <= pPoints[i+1].m_Time)
		{
			float Delta = pPoints[i+1].m_Time-pPoints[i].m_Time;
			float a = (Time-pPoints[i].m_Time)/Delta;


			if(pPoints[i].m_Curvetype == CURVETYPE_SMOOTH)
				a = -2*a*a*a + 3*a*a; // second hermite basis
			else if(pPoints[i].m_Curvetype == CURVETYPE_SLOW)
				a = a*a*a;
			else if(pPoints[i].m_Curvetype == CURVETYPE_FAST)
			{
				a = 1-a;
				a = 1-a*a*a;
			}
			else if (pPoints[i].m_Curvetype == CURVETYPE_STEP)
				a = 0;
			else
			{
				// linear
			}

			for(int c = 0; c < Channels; c++)
			{
				float v0 = fx2f(pPoints[i].m_aValues[c]);
				float v1 = fx2f(pPoints[i+1].m_aValues[c]);
				pResult[c] = v0 + (v1-v0) * a;
			}

			return;
		}
	}

	pResult[0] = fx2f(pPoints[NumPoints-1].m_aValues[0]);
	pResult[1] = fx2f(pPoints[NumPoints-1].m_aValues[1]);
	pResult[2] = fx2f(pPoints[NumPoints-1].m_aValues[2]);
	pResult[3] = fx2f(pPoints[NumPoints-1].m_aValues[3]);
	return;
}
Example #6
0
int CEditor::PopupPoint(CEditor *pEditor, CUIRect View)
{
	CQuad *pQuad = pEditor->GetSelectedQuad();

	enum
	{
		PROP_POS_X=0,
		PROP_POS_Y,
		PROP_COLOR,
		PROP_TEX_U,
		PROP_TEX_V,
		NUM_PROPS,
	};

	int Color = 0;
	int x = 0, y = 0;
	int tu = 0, tv = 0;

	for(int v = 0; v < 4; v++)
	{
		if(pEditor->m_SelectedPoints&(1<<v))
		{
			Color = 0;
			Color |= pQuad->m_aColors[v].r<<24;
			Color |= pQuad->m_aColors[v].g<<16;
			Color |= pQuad->m_aColors[v].b<<8;
			Color |= pQuad->m_aColors[v].a;

			x = fx2i(pQuad->m_aPoints[v].x);
			y = fx2i(pQuad->m_aPoints[v].y);
			tu = fx2f(pQuad->m_aTexcoords[v].x)*1024;
			tv = fx2f(pQuad->m_aTexcoords[v].y)*1024;
		}
	}


	CProperty aProps[] = {
		{"Pos X", x, PROPTYPE_INT_SCROLL, -1000000, 1000000},
		{"Pos Y", y, PROPTYPE_INT_SCROLL, -1000000, 1000000},
		{"Color", Color, PROPTYPE_COLOR, -1, pEditor->m_Map.m_lEnvelopes.size()},
		{"Tex U", tu, PROPTYPE_INT_SCROLL, -1000000, 1000000},
		{"Tex V", tv, PROPTYPE_INT_SCROLL, -1000000, 1000000},
		{0},
	};

	static int s_aIds[NUM_PROPS] = {0};
	int NewVal = 0;
	int Prop = pEditor->DoProperties(&View, aProps, s_aIds, &NewVal);
	if(Prop != -1)
		pEditor->m_Map.m_Modified = true;

	if(Prop == PROP_POS_X)
	{
		for(int v = 0; v < 4; v++)
			if(pEditor->m_SelectedPoints&(1<<v))
				pQuad->m_aPoints[v].x = i2fx(NewVal);
	}
	if(Prop == PROP_POS_Y)
	{
		for(int v = 0; v < 4; v++)
			if(pEditor->m_SelectedPoints&(1<<v))
				pQuad->m_aPoints[v].y = i2fx(NewVal);
	}
	if(Prop == PROP_COLOR)
	{
		for(int v = 0; v < 4; v++)
		{
			if(pEditor->m_SelectedPoints&(1<<v))
			{
				pQuad->m_aColors[v].r = (NewVal>>24)&0xff;
				pQuad->m_aColors[v].g = (NewVal>>16)&0xff;
				pQuad->m_aColors[v].b = (NewVal>>8)&0xff;
				pQuad->m_aColors[v].a = NewVal&0xff;
			}
		}
	}
Example #7
0
void CMapReader::Generate(CGenInfo *pInfo)
{
	m_OverallBenchmark.Unpause();
	
	// create folders
	
	char aGeneratedFolder[256];
	sprintf(aGeneratedFolder, "%sgenerated/%s", pInfo->m_aCurrentDir, pInfo->m_aMap);
	
	char aGeneratedMapresFolder[256];
	sprintf(aGeneratedMapresFolder, "%s/mapres", aGeneratedFolder);
	
	MakeDir(aGeneratedFolder);
	MakeDir(aGeneratedMapresFolder);
	
	// check map version
	
	CMapItemVersion *pVersion = (CMapItemVersion *)m_Reader.FindItem(MAPITEMTYPE_VERSION, 0);
	if(!pVersion || pVersion->m_Version != 1)
		return;
	
	// create generating file
	
	char aGenerating[256];
	sprintf(aGenerating, "%s/generating", aGeneratedFolder);
	
	FILE *pGeneratingFile = fopen(aGenerating, "wb");
	if(pGeneratingFile)
		fclose(pGeneratingFile);
	
	// load images
	m_ImagesBenchmark.Unpause();
	
	int ImagesStart;
	int ImagesNum;
	m_Reader.GetType(MAPITEMTYPE_IMAGE, &ImagesStart, &ImagesNum);
	
	CMapItemImage *pImages = NULL;
	
	if(ImagesNum > 0)
	{
		pImages = new CMapItemImage[ImagesNum];
		
		for(int i = ImagesStart; i < ImagesStart+ImagesNum; i++)
		{
			CMapItemImage *pImage = (CMapItemImage *)m_Reader.GetItem(i, NULL, NULL);
			
			if(!pImage->m_External && pInfo->m_DumpEmbedded)
			{
				const char *pName = (char *)m_Reader.GetData(pImage->m_ImageName);
				unsigned char *pData = (unsigned char *)m_Reader.GetData(pImage->m_ImageData);
				
				char aImageFilename[512];
				sprintf(aImageFilename, "%s/%s.png", aGeneratedMapresFolder, pName);
				
				CImageWrite Image;
				Image.Open(aImageFilename, pImage->m_Width, pImage->m_Height);
				Image.SetPixels(pData);
				Image.Save();
			}
			
			pImages[i-ImagesStart] = *pImage;
		}
	}
	
	m_ImagesBenchmark.Pause();
	
	// load groups and layers
	
	int GroupsStart;
	int GroupsNum;
	m_Reader.GetType(MAPITEMTYPE_GROUP, &GroupsStart, &GroupsNum);
	
	int LayersStart;
	int LayersNum;
	m_Reader.GetType(MAPITEMTYPE_LAYER, &LayersStart, &LayersNum);
	
	for(int g = GroupsStart; g < GroupsStart+GroupsNum; g++)
	{
		CMapItemGroup *pGroup = (CMapItemGroup *)m_Reader.GetItem(g, NULL, NULL);
		
		if(pGroup->m_Version < 1 || pGroup->m_Version > 2)
			continue;
		
		for(int l = LayersStart + pGroup->m_StartLayer; l < LayersStart + pGroup->m_StartLayer+pGroup->m_NumLayers; l++)
		{
			if(l >= LayersStart+LayersNum)
				break;
			
			CMapItemLayer *pLayer = (CMapItemLayer *)m_Reader.GetItem(l, NULL, NULL);
			
			if(pLayer->m_Type == LAYERTYPE_TILES)
			{
				m_TilemapsBenchmark.Unpause();
				
				CMapItemLayerTilemap *pTilesLayer = (CMapItemLayerTilemap *)pLayer;
				
				bool GameLayer = (pTilesLayer->m_Flags & TILESLAYERFLAG_GAME) ? true : false;
				
				if((GameLayer && !pInfo->m_DumpGameTilemap) || (!GameLayer && !pInfo->m_DumpTilemaps))
					continue;
				
				if(!GameLayer && pTilesLayer->m_Image < 0)
					continue;
				
				CMapItemImage *pImage = NULL;
				if(!GameLayer)
					pImage = &pImages[pTilesLayer->m_Image];
				
				const char *pTilesetName;
				if(GameLayer)
					pTilesetName = pInfo->m_aEntities;
				else
					pTilesetName = (char *)m_Reader.GetData(pImage->m_ImageName);
				
				CTileset Src;
				if(GameLayer || pImage->m_External)
				{
					char aTilesetFilename[512];
					sprintf(aTilesetFilename, "%smapres/%s.png", pInfo->m_aCurrentDir, pTilesetName);
					
					bool Success = Src.Open(aTilesetFilename);
					if(!Success)
						continue;
				}
				else
				{
					bool Success = Src.OpenFromBuffer((unsigned char *)m_Reader.GetData(pImage->m_ImageData), pImage->m_Width, pImage->m_Height);
					if(!Success)
						continue;
				}
				
				char aTilemapFilename[512];
				if(GameLayer)
					sprintf(aTilemapFilename, "%s/tiles_game_%d.png", aGeneratedFolder, pTilesLayer->m_Data);
				else
					sprintf(aTilemapFilename, "%s/tiles_%d.png", aGeneratedFolder, pTilesLayer->m_Data);
				
				CTilemap Dest;
				bool Success = Dest.Open(aTilemapFilename, pTilesLayer->m_Width, pTilesLayer->m_Height, &Src, pInfo->m_TileSize);
				if(!Success)
					continue;
				
				CTile *pTilesData = (CTile *)m_Reader.GetData(pTilesLayer->m_Data);
				
				for(int x = 0; x < pTilesLayer->m_Width; x++)
				{
					for(int y = 0; y < pTilesLayer->m_Height; y++)
					{
						CTile *pTile = &pTilesData[y*pTilesLayer->m_Width + x];
						
						if(pTile->m_Index == 0)
							continue;
						
						Dest.SetTile(x, y, pTile->m_Index, pTile->m_Flags);
					}
				}
				
				Dest.Colorize(&pTilesLayer->m_Color);
				
				Dest.Save();
				Src.Close();
				
				m_TilemapsBenchmark.Pause();
			}
			
			else if(pLayer->m_Type == LAYERTYPE_QUADS)
			{
				m_QuadsBenchmark.Unpause();
				
				CMapItemLayerQuads *pQuadsLayer = (CMapItemLayerQuads *)pLayer;
				
				if(!pInfo->m_DumpQuads)
					continue;
				
				CImageRead Src;
				
				CMapItemImage *pImage = NULL;
				if(pQuadsLayer->m_Image >= 0)
					pImage = &pImages[pQuadsLayer->m_Image];
				
				if(pQuadsLayer->m_Image >= 0)
				{
					const char *pImageName = (char *)m_Reader.GetData(pImage->m_ImageName);
					
					if(pImage->m_External)
					{
						char aImageFilename[512];
						sprintf(aImageFilename, "%smapres/%s.png", pInfo->m_aCurrentDir, pImageName);
						
						bool Success = Src.Open(aImageFilename);
						if(!Success)
							continue;
					}
					else
					{
						bool Success = Src.OpenFromBuffer((unsigned char *)m_Reader.GetData(pImage->m_ImageData), pImage->m_Width, pImage->m_Height);
						if(!Success)
							continue;
					}
				}
				
				CQuad *pQuadsData = (CQuad *)m_Reader.GetData(pQuadsLayer->m_Data);
				
				for(int q = 0; q < pQuadsLayer->m_NumQuads; q++)
				{
					CQuad *pQuad = &pQuadsData[q];
					
					int MinX = min(min(min(pQuad->m_aPoints[0].x, pQuad->m_aPoints[1].x), pQuad->m_aPoints[2].x), pQuad->m_aPoints[3].x) / 1024;
					int MinY = min(min(min(pQuad->m_aPoints[0].y, pQuad->m_aPoints[1].y), pQuad->m_aPoints[2].y), pQuad->m_aPoints[3].y) / 1024;
					int MaxX = max(max(max(pQuad->m_aPoints[0].x, pQuad->m_aPoints[1].x), pQuad->m_aPoints[2].x), pQuad->m_aPoints[3].x) / 1024;
					int MaxY = max(max(max(pQuad->m_aPoints[0].y, pQuad->m_aPoints[1].y), pQuad->m_aPoints[2].y), pQuad->m_aPoints[3].y) / 1024;
					
					int Width = MaxX-MinX;
					int Height = MaxY-MinY;
					
					if(Width <= 0 || Height <= 0)
						continue;
					
					char aQuadsFilename[512];
					sprintf(aQuadsFilename, "%s/quads_%d_%d.png", aGeneratedFolder, pQuadsLayer->m_Data, q);
					
					CQuads Dest;
					bool Success = Dest.Open(aQuadsFilename, Width, Height, pInfo->m_TileSize);
					if(!Success)
						continue;
					
					if(pQuadsLayer->m_Image < 0)
						Dest.FillWhite();
					else
						Dest.DrawImage(&Src);
					
					Dest.DrawGradient(pQuad->m_aColors);
					
					Dest.Save();
				}
				
				m_QuadsBenchmark.Pause();
			}
		}
	}
	
	// dump metadata

	if(pInfo->m_DumpMetadata)
	{
		m_MetadataBenchmark.Unpause();
		
		CXMLDocument Doc;
		CXMLItem *pMainItem = Doc.Open("map");
		pMainItem->AddAttributeInt("version", pVersion->m_Version);
		
		for(int i = 0; i < ImagesNum; i++)
		{
			const char *pName = (char *)m_Reader.GetData(pImages[i].m_ImageName);

			CXMLItem *pImageItem = pMainItem->AddChild("image");
			pImageItem->AddAttributeInt("version", pImages[i].m_Version);
			pImageItem->AddAttributeInt("width", pImages[i].m_Width);
			pImageItem->AddAttributeInt("height", pImages[i].m_Height);
			pImageItem->AddAttributeBool("external", pImages[i].m_External);
			pImageItem->AddAttributeStr("name", pName);
		}
		
		for(int g = GroupsStart; g < GroupsStart+GroupsNum; g++)
		{
			CMapItemGroup *pGroup = (CMapItemGroup *)m_Reader.GetItem(g, NULL, NULL);
			
			CXMLItem *pGroupItem = pMainItem->AddChild("group");
			pGroupItem->AddAttributeInt("version", pGroup->m_Version);
			pGroupItem->AddAttributeInt("offset_x", pGroup->m_OffsetX);
			pGroupItem->AddAttributeInt("offset_y", pGroup->m_OffsetY);
			pGroupItem->AddAttributeInt("parallax_x", pGroup->m_ParallaxX);
			pGroupItem->AddAttributeInt("parallax_y", pGroup->m_ParallaxY);
			if(pGroup->m_Version >= 2)
			{
				pGroupItem->AddAttributeBool("use_clipping", pGroup->m_UseClipping);
				pGroupItem->AddAttributeInt("clip_x", pGroup->m_ClipX);
				pGroupItem->AddAttributeInt("clip_y", pGroup->m_ClipY);
				pGroupItem->AddAttributeInt("clip_w", pGroup->m_ClipW);
				pGroupItem->AddAttributeInt("clip_h", pGroup->m_ClipH);
			}
			
			for(int l = LayersStart + pGroup->m_StartLayer; l < LayersStart + pGroup->m_StartLayer+pGroup->m_NumLayers; l++)
			{
				if(l >= LayersStart+LayersNum)
					break;
				
				CMapItemLayer *pLayer = (CMapItemLayer *)m_Reader.GetItem(l, NULL, NULL);
				
				CXMLItem *pLayerItem = pGroupItem->AddChild("layer");
				if(pLayer->m_Type == LAYERTYPE_TILES)
					pLayerItem->AddAttributeStr("type", "tiles");
				else if(pLayer->m_Type == LAYERTYPE_QUADS)
					pLayerItem->AddAttributeStr("type", "quads");
				else
					pLayerItem->AddAttributeStr("type", "invalid");
				pLayerItem->AddAttributeBool("detail", pLayer->m_Flags&TILESLAYERFLAG_GAME);
				
				if(pLayer->m_Type == LAYERTYPE_TILES)
				{
					CMapItemLayerTilemap *pTilesLayer = (CMapItemLayerTilemap *)pLayer;
					
					const char *pImageName = "";
					if(pTilesLayer->m_Image >= 0 && pTilesLayer->m_Image < ImagesNum)
						pImageName = (char *)m_Reader.GetData(pImages[pTilesLayer->m_Image].m_ImageName);
					
					pLayerItem->AddAttributeInt("version", pTilesLayer->m_Version);
					pLayerItem->AddAttributeInt("width", pTilesLayer->m_Width);
					pLayerItem->AddAttributeInt("height", pTilesLayer->m_Height);
					pLayerItem->AddAttributeBool("game", pTilesLayer->m_Flags&TILESLAYERFLAG_GAME);
					pLayerItem->AddAttributeInt("color_env", pTilesLayer->m_ColorEnv);
					pLayerItem->AddAttributeInt("color_env_offset", pTilesLayer->m_ColorEnvOffset);
					pLayerItem->AddAttributeStr("image", pImageName);
					pLayerItem->AddAttributeInt("data", pTilesLayer->m_Data);
					
					CXMLItem *pColorItem = pLayerItem->AddChild("color");
					pColorItem->AddAttributeInt("r", pTilesLayer->m_Color.r);
					pColorItem->AddAttributeInt("g", pTilesLayer->m_Color.g);
					pColorItem->AddAttributeInt("b", pTilesLayer->m_Color.b);
					pColorItem->AddAttributeInt("a", pTilesLayer->m_Color.a);
				}
				else if(pLayer->m_Type == LAYERTYPE_QUADS)
				{
					CMapItemLayerQuads *pQuadsLayer = (CMapItemLayerQuads *)pLayer;
					
					const char *pImageName = "";
					if(pQuadsLayer->m_Image >= 0 && pQuadsLayer->m_Image < ImagesNum)
						pImageName = (char *)m_Reader.GetData(pImages[pQuadsLayer->m_Image].m_ImageName);
					
					pLayerItem->AddAttributeInt("version", pQuadsLayer->m_Version);
					pLayerItem->AddAttributeStr("image", pImageName);
					pLayerItem->AddAttributeInt("data", pQuadsLayer->m_Data);
					
					CQuad *pQuadsData = (CQuad *)m_Reader.GetData(pQuadsLayer->m_Data);
					
					for(int q = 0; q < pQuadsLayer->m_NumQuads; q++)
					{
						CQuad *pQuad = &pQuadsData[q];
						
						CXMLItem *pQuadItem = pLayerItem->AddChild("quad");
						pQuadItem->AddAttributeInt("pos_env", pQuad->m_PosEnv);
						pQuadItem->AddAttributeInt("pos_env_offset", pQuad->m_PosEnvOffset);
						pQuadItem->AddAttributeInt("color_env", pQuad->m_ColorEnv);
						pQuadItem->AddAttributeInt("color_env_offset", pQuad->m_ColorEnvOffset);
						pQuadItem->AddAttributeInt("data", q);
						
						for(int k = 0; k < 5; k++)
						{
							CXMLItem *pPointItem = pQuadItem->AddChild("point");
							pPointItem->AddAttributeInt("x", fx2f(pQuad->m_aPoints[k].x));
							pPointItem->AddAttributeInt("y", fx2f(pQuad->m_aPoints[k].y));
						}
						
						for(int k = 0; k < 4; k++)
						{
							CXMLItem *pColorItem = pQuadItem->AddChild("color");
							pColorItem->AddAttributeInt("r", pQuad->m_aColors[k].r);
							pColorItem->AddAttributeInt("g", pQuad->m_aColors[k].g);
							pColorItem->AddAttributeInt("b", pQuad->m_aColors[k].b);
							pColorItem->AddAttributeInt("a", pQuad->m_aColors[k].a);
						}
						
						for(int k = 0; k < 4; k++)
						{
							CXMLItem *pTexcoordItem = pQuadItem->AddChild("texcoord");
							pTexcoordItem->AddAttributeInt("x", fx2f(pQuad->m_aTexcoords[k].x));
							pTexcoordItem->AddAttributeInt("y", fx2f(pQuad->m_aTexcoords[k].y));
						}
					}
				}
			}
		}
		
		int EnvPointsStart;
		int EnvPointsNum;
		m_Reader.GetType(MAPITEMTYPE_ENVPOINTS, &EnvPointsStart, &EnvPointsNum);
		
		CEnvPoint *pPoints = 0;
		if(EnvPointsNum)
			pPoints = (CEnvPoint *)m_Reader.GetItem(EnvPointsStart, NULL, NULL);
		
		int EnvStart;
		int EnvNum;
		m_Reader.GetType(MAPITEMTYPE_ENVELOPE, &EnvStart, &EnvNum);
		
		for(int e = EnvStart; e < EnvStart+EnvNum; e++)
		{
			CMapItemEnvelope *pEnv = (CMapItemEnvelope *)m_Reader.GetItem(e, NULL, NULL);
			
			CXMLItem *pEnvItem = pMainItem->AddChild("envelope");
			pEnvItem->AddAttributeInt("version", pEnv->m_Version);
			if(pEnv->m_Channels == 3)
				pEnvItem->AddAttributeStr("type", "pos");
			else if(pEnv->m_Channels == 4)
				pEnvItem->AddAttributeStr("type", "color");
			else
				pEnvItem->AddAttributeStr("type", "invalid");
			if(pEnv->m_aName[0] != -1)
			{
				char aEnvName[64];
				IntsToStr(pEnv->m_aName, sizeof(pEnv->m_aName)/sizeof(int), aEnvName);
				pEnvItem->AddAttributeStr("name", aEnvName);
			}
			
			for(int p = pEnv->m_StartPoint; p < pEnv->m_StartPoint+pEnv->m_NumPoints; p++)
			{
				CXMLItem *pEnvPointItem = pEnvItem->AddChild("envpoint");
				pEnvPointItem->AddAttributeInt("time", pPoints[p].m_Time);
				if(p != pEnv->m_StartPoint+pEnv->m_NumPoints -1)
				{
					if(pPoints[p].m_Curvetype == CURVETYPE_STEP)
						pEnvPointItem->AddAttributeStr("curvetype", "step");
					else if(pPoints[p].m_Curvetype == CURVETYPE_LINEAR)
						pEnvPointItem->AddAttributeStr("curvetype", "linear");
					else if(pPoints[p].m_Curvetype == CURVETYPE_SLOW)
						pEnvPointItem->AddAttributeStr("curvetype", "slow");
					else if(pPoints[p].m_Curvetype == CURVETYPE_FAST)
						pEnvPointItem->AddAttributeStr("curvetype", "fast");
					else if(pPoints[p].m_Curvetype == CURVETYPE_SMOOTH)
						pEnvPointItem->AddAttributeStr("curvetype", "smooth");
					else
						pEnvPointItem->AddAttributeStr("curvetype", "invalid");
				}
				if(pEnv->m_Channels == 3)
				{
					pEnvPointItem->AddAttributeInt("x", fx2f(pPoints[p].m_aValues[0]));
					pEnvPointItem->AddAttributeInt("y", fx2f(pPoints[p].m_aValues[1]));
					pEnvPointItem->AddAttributeInt("r", fx2f(pPoints[p].m_aValues[2]));
				}
				else if(pEnv->m_Channels == 4)
				{
					pEnvPointItem->AddAttributeInt("r", fx2f(pPoints[p].m_aValues[0])*255);
					pEnvPointItem->AddAttributeInt("g", fx2f(pPoints[p].m_aValues[1])*255);
					pEnvPointItem->AddAttributeInt("b", fx2f(pPoints[p].m_aValues[2])*255);
					pEnvPointItem->AddAttributeInt("a", fx2f(pPoints[p].m_aValues[3])*255);
				}
			}
		}
		
		char aMetadataFilename[512];
		sprintf(aMetadataFilename, "%s/metadata.xml", aGeneratedFolder);
		Doc.Save(aMetadataFilename);
		Doc.Close();
		
		m_MetadataBenchmark.Pause();
	}
	
	if(ImagesNum > 0)
		delete pImages;
	
	remove(aGenerating);
	
	m_OverallBenchmark.Pause();
	
	if(pInfo->m_ShowBenchmark)
	{
		printf("Benchmark results:\n");
		printf("  Images dumping:\t%dms\n", m_ImagesBenchmark.GetTime());
		printf("  Tilemaps dumping:\t%dms\n", m_TilemapsBenchmark.GetTime());
		printf("  Quads dumping:\t%dms\n", m_QuadsBenchmark.GetTime());
		printf("  Metadata dumping:\t%dms\n", m_MetadataBenchmark.GetTime());
		printf("  Overall:\t\t%dms\n", m_OverallBenchmark.GetTime());
	}
}
Example #8
0
void CRenderTools::RenderQuads(CQuad *pQuads, int NumQuads, int RenderFlags, ENVELOPE_EVAL pfnEval, void *pUser)
{
	Graphics()->QuadsBegin();
	float Conv = 1/255.0f;
	for(int i = 0; i < NumQuads; i++)
	{
		CQuad *q = &pQuads[i];

		float r=1, g=1, b=1, a=1;

		if(q->m_ColorEnv >= 0)
		{
			float aChannels[4];
			pfnEval(q->m_ColorEnvOffset/1000.0f, q->m_ColorEnv, aChannels, pUser);
			r = aChannels[0];
			g = aChannels[1];
			b = aChannels[2];
			a = aChannels[3];
		}

		/*bool Opaque = false;
		 TODO: Analyze quadtexture
		if(a < 0.01f || (q->m_aColors[0].a < 0.01f && q->m_aColors[1].a < 0.01f && q->m_aColors[2].a < 0.01f && q->m_aColors[3].a < 0.01f))
			Opaque = true;

		if(Opaque && !(RenderFlags&LAYERRENDERFLAG_OPAQUE))
			continue;
		if(!Opaque && !(RenderFlags&LAYERRENDERFLAG_TRANSPARENT))
			continue;
		*/
		vec2 aTexCoords[4];
		for(int k = 0; k < 4; k++)
		{
			aTexCoords[k].x = fx2f(q->m_aTexcoords[k].x);
			aTexCoords[k].y = fx2f(q->m_aTexcoords[k].y);
		}

		// Check if we want to repeat the texture
		// Otherwise clamp to the edge to prevent texture bleeding
		bool RepeatU = false, RepeatV = false;
		for(int k = 0; k < 4; k++)
		{
			if(aTexCoords[k].x < 0.0f || aTexCoords[k].x > 1.0f)
				RepeatU = true;
			if(aTexCoords[k].y < 0.0f || aTexCoords[k].y > 1.0f)
				RepeatV = true;
		}
		Graphics()->WrapMode(
			RepeatU ? IGraphics::WRAP_REPEAT : IGraphics::WRAP_CLAMP,
			RepeatV ? IGraphics::WRAP_REPEAT : IGraphics::WRAP_CLAMP);

		Graphics()->QuadsSetSubsetFree(
			aTexCoords[0].x, aTexCoords[0].y,
			aTexCoords[1].x, aTexCoords[1].y,
			aTexCoords[2].x, aTexCoords[2].y,
			aTexCoords[3].x, aTexCoords[3].y);

		float OffsetX = 0;
		float OffsetY = 0;
		float Rot = 0;

		// TODO: fix this
		if(q->m_PosEnv >= 0)
		{
			float aChannels[4];
			pfnEval(q->m_PosEnvOffset/1000.0f, q->m_PosEnv, aChannels, pUser);
			OffsetX = aChannels[0];
			OffsetY = aChannels[1];
			Rot = aChannels[2]/360.0f*pi*2;
		}

		IGraphics::CColorVertex Array[4] = {
			IGraphics::CColorVertex(0, q->m_aColors[0].r*Conv*r*q->m_aColors[0].a*Conv*a, q->m_aColors[0].g*Conv*g*q->m_aColors[0].a*Conv*a, q->m_aColors[0].b*Conv*b*q->m_aColors[0].a*Conv*a, q->m_aColors[0].a*Conv*a),
			IGraphics::CColorVertex(1, q->m_aColors[1].r*Conv*r*q->m_aColors[1].a*Conv*a, q->m_aColors[1].g*Conv*g*q->m_aColors[1].a*Conv*a, q->m_aColors[1].b*Conv*b*q->m_aColors[1].a*Conv*a, q->m_aColors[1].a*Conv*a),
			IGraphics::CColorVertex(2, q->m_aColors[2].r*Conv*r*q->m_aColors[2].a*Conv*a, q->m_aColors[2].g*Conv*g*q->m_aColors[2].a*Conv*a, q->m_aColors[2].b*Conv*b*q->m_aColors[2].a*Conv*a, q->m_aColors[2].a*Conv*a),
			IGraphics::CColorVertex(3, q->m_aColors[3].r*Conv*r*q->m_aColors[3].a*Conv*a, q->m_aColors[3].g*Conv*g*q->m_aColors[3].a*Conv*a, q->m_aColors[3].b*Conv*b*q->m_aColors[3].a*Conv*a, q->m_aColors[3].a*Conv*a)};
		Graphics()->SetColorVertex(Array, 4);

		CPoint *pPoints = q->m_aPoints;

		if(Rot != 0)
		{
			static CPoint aRotated[4];
			aRotated[0] = q->m_aPoints[0];
			aRotated[1] = q->m_aPoints[1];
			aRotated[2] = q->m_aPoints[2];
			aRotated[3] = q->m_aPoints[3];
			pPoints = aRotated;

			Rotate(&q->m_aPoints[4], &aRotated[0], Rot);
			Rotate(&q->m_aPoints[4], &aRotated[1], Rot);
			Rotate(&q->m_aPoints[4], &aRotated[2], Rot);
			Rotate(&q->m_aPoints[4], &aRotated[3], Rot);
		}

		IGraphics::CFreeformItem Freeform(
			fx2f(pPoints[0].x)+OffsetX, fx2f(pPoints[0].y)+OffsetY,
			fx2f(pPoints[1].x)+OffsetX, fx2f(pPoints[1].y)+OffsetY,
			fx2f(pPoints[2].x)+OffsetX, fx2f(pPoints[2].y)+OffsetY,
			fx2f(pPoints[3].x)+OffsetX, fx2f(pPoints[3].y)+OffsetY);
		Graphics()->QuadsDrawFreeform(&Freeform, 1);
	}
	Graphics()->QuadsEnd();
	Graphics()->WrapNormal();
}
Example #9
0
void CRenderTools::RenderEvalEnvelope(CEnvPoint *pPoints, int NumPoints, int Channels, float Time, float *pResult)
{
	if(NumPoints == 0)
	{
		pResult[0] = 0;
		pResult[1] = 0;
		pResult[2] = 0;
		pResult[3] = 0;
		return;
	}

	if(NumPoints == 1)
	{
		pResult[0] = fx2f(pPoints[0].m_aValues[0]);
		pResult[1] = fx2f(pPoints[0].m_aValues[1]);
		pResult[2] = fx2f(pPoints[0].m_aValues[2]);
		pResult[3] = fx2f(pPoints[0].m_aValues[3]);
		return;
	}

	Time = fmod(Time, pPoints[NumPoints-1].m_Time/1000.0f)*1000.0f;

	for(int i = 0; i < NumPoints-1; i++)
	{
		if(Time >= pPoints[i].m_Time && Time <= pPoints[i+1].m_Time)
		{
			float Delta = pPoints[i+1].m_Time-pPoints[i].m_Time;
			float a = (Time-pPoints[i].m_Time)/Delta;

			switch(pPoints[i].m_Curvetype)
			{
			case CURVETYPE_STEP:
				a = 0;
				break;
			case CURVETYPE_SMOOTH:
				a = -2*a*a*a + 3*a*a; // second hermite basis
				break;
			case CURVETYPE_SLOW:
				a = a*a*a;
				break;
			case CURVETYPE_FAST:
				a = 1-a;
				a = 1-a*a*a;
				break;
			case CURVETYPE_BEZIER:
				for(int c = 0; c < Channels; c++)
				{
					// monotonic 2d cubic bezier curve
					vec2 p0, p1, p2, p3;
					vec2 inTang, outTang;

					p0 = vec2(pPoints[i].m_Time/1000.0f, fx2f(pPoints[i].m_aValues[c]));
					p3 = vec2(pPoints[i+1].m_Time/1000.0f, fx2f(pPoints[i+1].m_aValues[c]));

					outTang = vec2(pPoints[i].m_aOutTangentdx[c]/1000.0f, fx2f(pPoints[i].m_aOutTangentdy[c]));
					inTang = -vec2(pPoints[i+1].m_aInTangentdx[c]/1000.0f, fx2f(pPoints[i+1].m_aInTangentdy[c]));
					p1 = p0 + outTang;
					p2 = p3 - inTang;

					// validate bezier curve
					ValidateFCurve(p0, p1, p2, p3);

					// solve x(a) = time for a
					a = clamp(SolveBezier(Time/1000.0f, p0.x, p1.x, p2.x, p3.x), 0.0f, 1.0f);

					// value = y(t)
					pResult[c] =  bezier(p0.y, p1.y, p2.y, p3.y, a);
				}
				return;
			case CURVETYPE_LINEAR:
				break;
			}

			for(int c = 0; c < Channels; c++)
			{
				float v0 = fx2f(pPoints[i].m_aValues[c]);
				float v1 = fx2f(pPoints[i+1].m_aValues[c]);
				pResult[c] = mix(v0, v1, a);
			}

			return;
		}
	}

	pResult[0] = fx2f(pPoints[NumPoints-1].m_aValues[0]);
	pResult[1] = fx2f(pPoints[NumPoints-1].m_aValues[1]);
	pResult[2] = fx2f(pPoints[NumPoints-1].m_aValues[2]);
	pResult[3] = fx2f(pPoints[NumPoints-1].m_aValues[3]);
	return;
}