Short bit of background about my newer, but related, fileformat problem: I've been working on actually implementing the XML template stuff into my editor since my last post. I tried it by hand once, and I was up to 112 lines of code just to import a mesh template. And even then it was nowhere's even remotely close to being finished. I had the foundation laid out (Parsing a trimmed line of file to determine where the <'s were in the line of text, and it filled a texture parameter array. But that was about it. 112 lines of code roughly for that. More or less I was writing my own xml parser. Can you say "ouch"? lol. I've done my own scripting language (with nested IF's and variables and "special" variables so I have no desire to do something like that again lol. So I looked around, and found Chilkat has a nice freeware xml component. I've looked in the past over some xml stuff and it was extremely overcomplicated, things like treenodes, etc.. WTF is all I gotta say. Chilkat's seemed a bit more straightforward than what I've seen previously so I'm -trying- to use it but even that is still somewhat complicated.
The problem I'm having --
Ok here's my code in delphi, so far:
Function ExportMeshTemplate(MeshFile: String): Integer;
var
GroupNumber: Integer;
TempTexture: TV_Texture;
LookupIndex: Integer;
ContinueLookingUp: Boolean;
begin
MainRenderWindow.xml.Tag := 'MESH';
GroupNumber := 1;
while GroupNumber < 201 do
begin
MainRenderWindow.xNode0 := MainRenderWindow.xml.NewChild('GROUP_' + IntToStr(GroupNumber),'');
MainRenderWindow.xNode1 := MainRenderWindow.xNode0.NewChild('TEXTURE','');
If (MainRenderWindow.MeshData[MainRenderWindow.MeshSelected].Textures.TextureName[GroupNumber] <> '') then
begin
LookupIndex := 1;
ContinueLookingUp := true;
while ContinueLookingUp = true do
begin
if UpperCase(MainRenderWindow.MeshData[MainRenderWindow.MeshSelected].Textures.TextureName[GroupNumber]) = UpperCase(MainRenderWindow.TextureData[LookupIndex].TextureName) then
begin
MainRenderWindow.xNode2 := MainRenderWindow.xNode1.NewChild('NORMAL', '');
MainRenderWindow.xNode2.AddAttribute('TextureIsTemplate','False');
MainRenderWindow.xNode2.AddAttribute('TextureFile','\Media\Textures\' + MainRenderWindow.TextureData[LookupIndex].FileName);
MainRenderWindow.xNode2.AddAttribute('Width',MainRenderWindow.TextureData[LookupIndex].Width);
MainRenderWindow.xNode2.AddAttribute('Height',MainRenderWindow.TextureData[LookupIndex].Height);
MainRenderWindow.xNode2.AddAttribute('ColorKey',MainRenderWindow.TextureData[LookupIndex].ColorKey);
MainRenderWindow.xNode2.AddAttribute('FilterAndStretch',MainRenderWindow.TextureData[LookupIndex].FilterAndStretch);
ContinueLookingUp := False;
end
else
begin
LookupIndex := LookupIndex + 1;
If LookupIndex > MaxTextures Then
ContinueLookingUp := False;
end;
end;
end
else if (MainRenderWindow.MeshData[MainRenderWindow.MeshSelected].BumpTextures.BumpTextureName[GroupNumber] <> '') then
begin
LookupIndex := 1;
ContinueLookingUp := true;
while ContinueLookingUp = true do
begin
if UpperCase(MainRenderWindow.MeshData[MainRenderWindow.MeshSelected].BumpTextures.BumpTextureName[GroupNumber]) = UpperCase(MainRenderWindow.BumpTextureData[LookupIndex].TextureName) then
begin
MainRenderWindow.xNode2 := MainRenderWindow.xNode1.NewChild('BUMP', '');
MainRenderWindow.xNode2.AddAttribute('TextureIsTemplate','False');
MainRenderWindow.xNode2.AddAttribute('TextureFile','\Media\Textures\' + MainRenderWindow.BumpTextureData[LookupIndex].FileName);
MainRenderWindow.xNode2.AddAttribute('Width',MainRenderWindow.BumpTextureData[LookupIndex].Width);
MainRenderWindow.xNode2.AddAttribute('Height',MainRenderWindow.BumpTextureData[LookupIndex].Height);
MainRenderWindow.xNode2.AddAttribute('ColorKey',MainRenderWindow.BumpTextureData[LookupIndex].ColorKey);
if MainRenderWindow.BumpTextureData[LookupIndex].FilterAndStretch = true then
MainRenderWindow.xNode2.AddAttribute('FilterAndStretch','True')
else
MainRenderWindow.xNode2.AddAttribute('FilterAndStretch','False');
ContinueLookingUp := False;
end
else
begin
LookupIndex := LookupIndex + 1;
If LookupIndex > MaxTextures Then
ContinueLookingUp := False;
end;
end;
end;
MainRenderWindow.xNode1 := MainRenderWindow.xNode0.NewChild('MATERIAL','');
If (MainRenderWindow.MeshData[MainRenderWindow.MeshSelected].Materials.MaterialName[GroupNumber] <> '') then
begin
LookupIndex := 1;
ContinueLookingUp := true;
while ContinueLookingUp = true do
begin
if UpperCase(MainRenderWindow.MeshData[MainRenderWindow.MeshSelected].Materials.MaterialName[GroupNumber]) = UpperCase(MainRenderWindow.MaterialData[LookupIndex].MaterialName) then
begin
MainRenderWindow.xNode2.Content := 'MaterialIsTemplate=False';
MainRenderWindow.xNode2.Content := MainRenderWindow.xNode2.Content + 'Power=' + MainRenderWindow.MaterialData[LookupIndex].Power;
MainRenderWindow.xNode2.Content := MainRenderWindow.xNode2.Content + 'Opacity=' + MainRenderWindow.MaterialData[LookupIndex].Opacity;
MainRenderWindow.xNode2 := MainRenderWindow.xNode1.NewChild('Ambient', '');
MainRenderWindow.xNode2.AddAttribute('R',FloatToStr(MainRenderWindow.MaterialData[LookupIndex].AmbientColor.R));
MainRenderWindow.xNode2.AddAttribute('G',FloatToStr(MainRenderWindow.MaterialData[LookupIndex].AmbientColor.G));
MainRenderWindow.xNode2.AddAttribute('B',FloatToStr(MainRenderWindow.MaterialData[LookupIndex].AmbientColor.B));
MainRenderWindow.xNode2.AddAttribute('A',FloatToStr(MainRenderWindow.MaterialData[LookupIndex].AmbientColor.A));
MainRenderWindow.xNode2 := MainRenderWindow.xNode1.NewChild('Diffuse', '');
MainRenderWindow.xNode2.AddAttribute('R',FloatToStr(MainRenderWindow.MaterialData[LookupIndex].DiffuseColor.R));
MainRenderWindow.xNode2.AddAttribute('G',FloatToStr(MainRenderWindow.MaterialData[LookupIndex].DiffuseColor.G));
MainRenderWindow.xNode2.AddAttribute('B',FloatToStr(MainRenderWindow.MaterialData[LookupIndex].DiffuseColor.B));
MainRenderWindow.xNode2.AddAttribute('A',FloatToStr(MainRenderWindow.MaterialData[LookupIndex].DiffuseColor.A));
MainRenderWindow.xNode2 := MainRenderWindow.xNode1.NewChild('Specular', '');
MainRenderWindow.xNode2.AddAttribute('R',FloatToStr(MainRenderWindow.MaterialData[LookupIndex].SpecularColor.R));
MainRenderWindow.xNode2.AddAttribute('G',FloatToStr(MainRenderWindow.MaterialData[LookupIndex].SpecularColor.G));
MainRenderWindow.xNode2.AddAttribute('B',FloatToStr(MainRenderWindow.MaterialData[LookupIndex].SpecularColor.B));
MainRenderWindow.xNode2.AddAttribute('A',FloatToStr(MainRenderWindow.MaterialData[LookupIndex].SpecularColor.A));
MainRenderWindow.xNode2 := MainRenderWindow.xNode1.NewChild('Emissive', '');
MainRenderWindow.xNode2.AddAttribute('R',FloatToStr(MainRenderWindow.MaterialData[LookupIndex].EmissiveColor.R));
MainRenderWindow.xNode2.AddAttribute('G',FloatToStr(MainRenderWindow.MaterialData[LookupIndex].EmissiveColor.G));
MainRenderWindow.xNode2.AddAttribute('B',FloatToStr(MainRenderWindow.MaterialData[LookupIndex].EmissiveColor.B));
MainRenderWindow.xNode2.AddAttribute('A',FloatToStr(MainRenderWindow.MaterialData[LookupIndex].EmissiveColor.A));
//MainRenderWindow.xNode2.AddAttribute('TextureFile','\Media\Textures\' + MainRenderWindow.TextureData[LookupIndex].FileName);
//MainRenderWindow.xNode2.AddAttribute('Width',MainRenderWindow.TextureData[LookupIndex].Width);
//MainRenderWindow.xNode2.AddAttribute('Height',MainRenderWindow.TextureData[LookupIndex].Height);
//MainRenderWindow.xNode2.AddAttribute('ColorKey',MainRenderWindow.TextureData[LookupIndex].ColorKey);
//MainRenderWindow.xNode2.AddAttribute('FilterAndStretch',MainRenderWindow.TextureData[LookupIndex].FilterAndStretch);
ContinueLookingUp := False;
end
else
begin
LookupIndex := LookupIndex + 1;
If LookupIndex > MaxMaterials Then
ContinueLookingUp := False;
end;
end;
end;
GroupNumber := GroupNumber + 1;
end;
MainRenderWindow.xml.SaveXml('Mesh2.tme');
end;
Here's what I get as a template file:
<?xml version="1.0" encoding="utf-8" ?>
<MESH>
<GROUP_1>
<TEXTURE>
<NORMAL TextureIsTemplate="False" TextureFile="\Media\Textures\C:\Program Files\Borland\Delphi7\Projects\Council of Eight Game Client Revised (v2)\Media\Objects\Grass2.bmp" Width="Grass2.bmp" Height="756" ColorKey="" FilterAndStretch="False">MaterialIsTemplate=FalsePower=1Opacity=0</NORMAL>
</TEXTURE>
<MATERIAL>
<Ambient R="0.745098054409027" G="0.509803950786591" B="0" A="1" />
<Diffuse R="0.745098054409027" G="0.509803950786591" B="0" A="1" />
<Specular R="0.745098054409027" G="0.509803950786591" B="0" A="1" />
<Emissive R="0.745098054409027" G="0.509803950786591" B="0" A="1" />
</MATERIAL>
</GROUP_1>
<GROUP_2>
<TEXTURE>
<NORMAL TextureIsTemplate="False" TextureFile="\Media\Textures\C:\Program Files\Borland\Delphi7\Projects\Council of Eight Game Client Revised (v2)\Media\Objects\Grass2.bmp" Width="Grass2.bmp" Height="756" ColorKey="" FilterAndStretch="False">MaterialIsTemplate=FalsePower=1Opacity=0</NORMAL>
</TEXTURE>
<MATERIAL>
<Ambient R="0.745098054409027" G="0.509803950786591" B="0" A="1" />
<Diffuse R="0.745098054409027" G="0.509803950786591" B="0" A="1" />
<Specular R="0.745098054409027" G="0.509803950786591" B="0" A="1" />
<Emissive R="0.745098054409027" G="0.509803950786591" B="0" A="1" />
</MATERIAL>
</GROUP_2>
<GROUP_3>
...yadda,yadda,yadda.. -- Fairly technical term lol
The problem:
I want something along the lines of:
<Mesh>
File=\media\Objects\Mesh1.tvm
MeshName=Mesh1
LoadMaterials=False
LoadTextures=True
LoadShaders=True
MeshCastsShadows=True
AdditiveShadow=True
<Position>
...
<Texture>
<Normal>
TextureIsTemplate=False
TextureFile=\Media\Textures
TextureName=TestTexture
Width=
Height=
Colorkey=
FilterAndStretch=False
</Normal>
<bump>
...
</bump>
</Texture>
See how the parameters are not enclosed in <>'s? The closest I can get is a thing called attributes, but they enclose all attributes in a single set of <> and even if I could get each attribute in it's own set of <>'s (Without the prefix and postfix tags) it's still pretty ugly. A site on the net that I found this component at had an example that when completed, output a file that looks like this:
// <product>
// <properties>
// <price SellPrice="11.99"></price>
// <price BasePrice="11.99"></price>
// </properties>
// </product>
See how the attribute SellPrice and BasePrice are not only enclosed in the <> but also have the price xml-tag prefixed and postfixed to it? That's not what I want. I'm looking for as if it were just:
<product>
<properties>
SellPrice="11.99"
BasePrice="11.99"
</properties>
</product>
The component has a provision for adding "content" which seems to be what I'm looking for, but it seems to add it after it's finished the attributes, or it jumbles it around or something (Kinda hard to figure out it's pattern). So it would seem using the content method is sort of a hacked work-around. I'm wondering if there is a correct way of doing it, so I can add "content" anywhere...
-- StakFallT