summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreeki <treeki@gmail.com>2011-03-08 05:17:56 +0100
committerTreeki <treeki@gmail.com>2011-03-08 05:17:56 +0100
commit7d391e33a0b3d9793c95fce832abb2c6d9002186 (patch)
tree075f8ec6272ad3ea12be44a8c2083f89b0d55228
parente962fd89af865d6e01522e9752f5fbd855ce128a (diff)
downloadnw4rtools-7d391e33a0b3d9793c95fce832abb2c6d9002186.tar.gz
nw4rtools-7d391e33a0b3d9793c95fce832abb2c6d9002186.zip
late night commit! obj importer is basic but working. also, tidied up DL stuff
Diffstat (limited to '')
-rw-r--r--NW4RTools.userprefs15
-rw-r--r--NW4RTools/DisplayListWriter.cs83
-rw-r--r--NW4RTools/Enums.cs8
-rw-r--r--NW4RTools/Models/Material.cs2
-rw-r--r--NW4RTools/Models/OpenGL/GLModel.cs10
-rw-r--r--NW4RTools/NW4RTools.csproj1
-rw-r--r--NW4RTools/NW4RTools.pidbbin579951 -> 579951 bytes
-rwxr-xr-xNW4RTools/ObjImporter.cs389
-rw-r--r--NW4RTools/OutputStream.cs6
-rwxr-xr-xNW4RTools/bin/Debug/NW4RTools.dllbin232960 -> 235008 bytes
-rw-r--r--NW4RTools/bin/Debug/NW4RTools.dll.mdbbin112922 -> 113704 bytes
-rw-r--r--TestApp/Main.cs73
-rw-r--r--TestApp/RenderWindow.cs20
-rw-r--r--TestApp/TestApp.pidbbin4240 -> 4427 bytes
-rwxr-xr-xTestApp/bin/Debug/NW4RTools.dllbin232960 -> 233472 bytes
-rw-r--r--TestApp/bin/Debug/NW4RTools.dll.mdbbin112922 -> 112974 bytes
-rwxr-xr-xTestApp/bin/Debug/TestApp.exebin5632 -> 7168 bytes
-rw-r--r--TestApp/bin/Debug/TestApp.exe.mdbbin979 -> 1243 bytes
18 files changed, 359 insertions, 248 deletions
diff --git a/NW4RTools.userprefs b/NW4RTools.userprefs
index d7da209..5273e53 100644
--- a/NW4RTools.userprefs
+++ b/NW4RTools.userprefs
@@ -2,21 +2,22 @@
<MonoDevelop.Ide.Workspace ActiveConfiguration="Debug" />
<MonoDevelop.Ide.Workbench ActiveDocument="NW4RTools/ObjImporter.cs">
<Files>
- <File FileName="NW4RTools/ObjImporter.cs" Line="635" Column="18" />
+ <File FileName="NW4RTools/ObjImporter.cs" Line="244" Column="37" />
<File FileName="NW4RTools/ObjExporter.cs" Line="105" Column="25" />
<File FileName="NW4RTools/BrresReader.cs" Line="784" Column="11" />
- <File FileName="NW4RTools/BrresWriter.cs" Line="648" Column="21" />
+ <File FileName="NW4RTools/BrresWriter.cs" Line="499" Column="36" />
<File FileName="NW4RTools/Models/Model.cs" Line="1" Column="1" />
<File FileName="NW4RTools/Models/ByteCode.cs" Line="1" Column="1" />
- <File FileName="TestApp/Main.cs" Line="19" Column="1" />
+ <File FileName="TestApp/Main.cs" Line="76" Column="1" />
<File FileName="NW4RTools/Types.cs" Line="1" Column="1" />
- <File FileName="NW4RTools/Models/Material.cs" Line="1" Column="1" />
+ <File FileName="NW4RTools/Models/Material.cs" Line="27" Column="18" />
<File FileName="NW4RTools/VertexSettings.cs" Line="184" Column="46" />
<File FileName="NW4RTools/Models/VertexData.cs" Line="238" Column="31" />
<File FileName="NW4RTools/Enums.cs" Line="23" Column="27" />
- <File FileName="NW4RTools/Models/OpenGL/GLModel.cs" Line="302" Column="1" />
- <File FileName="NW4RTools/InputStream.cs" Line="66" Column="1" />
- <File FileName="TestApp/RenderWindow.cs" Line="19" Column="1" />
+ <File FileName="NW4RTools/Models/OpenGL/GLModel.cs" Line="218" Column="7" />
+ <File FileName="NW4RTools/InputStream.cs" Line="86" Column="1" />
+ <File FileName="TestApp/RenderWindow.cs" Line="36" Column="78" />
+ <File FileName="NW4RTools/Models/OpenGL/GLDisplayList.cs" Line="20" Column="1" />
</Files>
</MonoDevelop.Ide.Workbench>
<MonoDevelop.Ide.DebuggingService.Breakpoints>
diff --git a/NW4RTools/DisplayListWriter.cs b/NW4RTools/DisplayListWriter.cs
new file mode 100644
index 0000000..d75bc8d
--- /dev/null
+++ b/NW4RTools/DisplayListWriter.cs
@@ -0,0 +1,83 @@
+using System;
+namespace NW4RTools {
+ public class DisplayListWriter : OutputStream {
+ public DisplayListWriter() : base(ByteEndian.BigEndian) {
+ }
+
+
+ public void End() {
+ AlignTo(0x20);
+ }
+
+
+ public void Nop() {
+ WriteByte(0);
+ }
+
+ public void LoadBPReg(UInt32 value) {
+ WriteByte((byte)GXCommand.LoadBPReg);
+ WriteUInt32(value);
+ }
+
+ public void LoadCPReg(byte command, UInt32 value) {
+ WriteByte((byte)GXCommand.LoadCPReg);
+ WriteByte(command);
+ WriteUInt32(value);
+ }
+
+ public void LoadXFReg(ushort address, byte[] data) {
+ if ((data.Length & 3) != 0) {
+ throw new ArgumentException("Data length passed to LoadXFReg() is not aligned to 4 bytes", "data");
+ }
+
+ if (data.Length < 4 || data.Length > 0x44) {
+ throw new ArgumentException("Data length passed to LoadXFReg() must be at least 4 bytes and at most 0x44 bytes", "data");
+ }
+
+ WriteByte((byte)GXCommand.LoadXFReg);
+ WriteByte(0);
+ WriteByte((byte)((data.Length / 4) - 1));
+ WriteUInt16(address);
+ WriteBytes(data);
+ }
+
+ public void LoadPosMtxFromArray(uint number) {
+ WriteByte((byte)GXCommand.LoadPosMtxFromArray);
+ WriteUInt32(number);
+ }
+
+ public void LoadNrmMtxFromArray(uint number) {
+ WriteByte((byte)GXCommand.LoadNrmMtxFromArray);
+ WriteUInt32(number);
+ }
+
+ public void LoadTexCoordMtxFromArray(uint number) {
+ WriteByte((byte)GXCommand.LoadTexCoordMtxFromArray);
+ WriteUInt32(number);
+ }
+
+ public void LoadLightFromArray(uint number) {
+ WriteByte((byte)GXCommand.LoadLightFromArray);
+ WriteUInt32(number);
+ }
+
+ public void CallDisplayList(uint pointer, uint size) {
+ WriteByte((byte)GXCommand.CallDL);
+ WriteUInt32(pointer);
+ WriteUInt32(size);
+ }
+
+ public void UnknownMetrics() {
+ WriteByte((byte)GXCommand.UnknownMetrics);
+ }
+
+ public void BeginPrimitives(PrimitiveType type, int vatIndex, ushort vtxCount) {
+ byte command = (byte)GXCommand.DrawPrimitiveMask;
+ command |= (byte)((byte)type << (byte)GXCommand.PrimitiveShiftAmount);
+ command |= (byte)vatIndex;
+ WriteByte(command);
+ WriteUInt16(vtxCount);
+ }
+ }
+}
+
diff --git a/NW4RTools/Enums.cs b/NW4RTools/Enums.cs
index 1ee089f..80c2283 100644
--- a/NW4RTools/Enums.cs
+++ b/NW4RTools/Enums.cs
@@ -13,11 +13,17 @@ namespace NW4RTools {
public enum GXCommand {
- // Missing many!!
+ Nop = 0,
+ LoadBPReg = 0x61,
+ LoadCPReg = 0x08,
+ LoadXFReg = 0x10,
LoadPosMtxFromArray = 0x20,
LoadNrmMtxFromArray = 0x28,
LoadTexCoordMtxFromArray = 0x30,
LoadLightFromArray = 0x38,
+ CallDL = 0x40,
+ UnknownMetrics = 0x44,
+ InvalidateVC = 0x48,
DrawPrimitiveMask = 0x80,
// TODO: Figure out some better way to store this
PrimitiveShiftAmount = 3
diff --git a/NW4RTools/Models/Material.cs b/NW4RTools/Models/Material.cs
index 519790c..a28240c 100644
--- a/NW4RTools/Models/Material.cs
+++ b/NW4RTools/Models/Material.cs
@@ -24,7 +24,7 @@ namespace NW4RTools.Models {
ScaleY = 1.0f;
CameraID = 0xFF;
- LightID = 0xFf;
+ LightID = 0xFF;
Flags = 1;
TexMatrix.Identity();
diff --git a/NW4RTools/Models/OpenGL/GLModel.cs b/NW4RTools/Models/OpenGL/GLModel.cs
index 072ea00..18e5f6f 100644
--- a/NW4RTools/Models/OpenGL/GLModel.cs
+++ b/NW4RTools/Models/OpenGL/GLModel.cs
@@ -199,14 +199,14 @@ namespace NW4RTools.Models.OpenGL {
displayList.Begin();
if (m.TextureInfos.Count > 0) {
- GL.Enable(EnableCap.Texture2D);
-
TextureInfo[] texInfoArray = new TextureInfo[8];
foreach (var texInfo in m.TextureInfos) {
texInfoArray[texInfo.TexMapID] = texInfo;
}
+ GL.Enable(EnableCap.Texture2D);
+
for (int i = 0; i < 8; i++) {
GL.ActiveTexture(TextureUnits[i]);
GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.TextureEnvMode, (int)TextureEnvMode.Modulate);
@@ -215,6 +215,7 @@ namespace NW4RTools.Models.OpenGL {
GL.BindTexture(TextureTarget.Texture2D, 0);
} else {
BindTextureInfo(texInfoArray[i]);
+ GL.Enable(EnableCap.Texture2D);
}
}
@@ -302,8 +303,9 @@ namespace NW4RTools.Models.OpenGL {
GL.MultiTexCoord2(TextureUnits[j], shape.TexCoordData[j].Data[vtxs[i].TexCoords[j]]);
}
}
-
- // TODO: normals
+
+ if (vs.NormalDesc != VertexSettings.DescType.None)
+ GL.Normal3(shape.NrmData.Data[vtxs[i].Normal]);
GL.Vertex3(shape.PosData.Data[vtxs[i].Position]);
}
diff --git a/NW4RTools/NW4RTools.csproj b/NW4RTools/NW4RTools.csproj
index 07fec58..02239cf 100644
--- a/NW4RTools/NW4RTools.csproj
+++ b/NW4RTools/NW4RTools.csproj
@@ -77,6 +77,7 @@
<Compile Include="ColladaExporter.cs" />
<Compile Include="ObjExporter.cs" />
<Compile Include="ObjImporter.cs" />
+ <Compile Include="DisplayListWriter.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
diff --git a/NW4RTools/NW4RTools.pidb b/NW4RTools/NW4RTools.pidb
index 757d6c2..e7aef3c 100644
--- a/NW4RTools/NW4RTools.pidb
+++ b/NW4RTools/NW4RTools.pidb
Binary files differ
diff --git a/NW4RTools/ObjImporter.cs b/NW4RTools/ObjImporter.cs
index 41b9ea4..81fcf81 100755
--- a/NW4RTools/ObjImporter.cs
+++ b/NW4RTools/ObjImporter.cs
@@ -12,6 +12,8 @@ namespace NW4RTools {
+ private const bool Lightmaps = true;
+
string BasePath;
ResFile CurrentFile;
Models.Model CurrentModel;
@@ -54,6 +56,27 @@ namespace NW4RTools {
// Set current material (usemtl):
// -- A different material will be assigned for the current shape.
+ if (Lightmaps) {
+ var lm01m = new Texture();
+
+ lm01m.Images = new System.Drawing.Bitmap[1];
+ lm01m.Images[0] = new System.Drawing.Bitmap(Path.Combine(BasePath, "images/lm_01m.png"));
+
+ lm01m.Format = TextureFormat.I8;
+
+ var lm02m = new Texture();
+
+ lm02m.Images = new System.Drawing.Bitmap[1];
+ lm02m.Images[0] = new System.Drawing.Bitmap(Path.Combine(BasePath, "images/lm_02m.png"));
+
+ lm02m.Format = TextureFormat.I8;
+
+ CurrentFile.GetTextureGroup().Add("lm_01m", lm01m);
+ CurrentFile.GetTextureGroup().Add("lm_02m", lm02m);
+ }
+
+
+
CurrentModel = new Model();
modelGroup.Add(modelName, CurrentModel);
@@ -138,20 +161,22 @@ namespace NW4RTools {
if (line.Length == 0 || line[0] == '#')
continue;
- var parsed = line.Split(' ');
+ var parsed = line.Split(new char[] { ' '}, StringSplitOptions.RemoveEmptyEntries);
switch (parsed[0]) {
case "mtllib":
LoadMaterialLibrary(string.Join(" ", parsed, 1, parsed.Length - 1));
break;
case "v":
- Positions.Add(ParseFloatArray(parsed, 1));
+ Positions.Add(ParseFloatArray(parsed, 1, 3));
break;
case "vn":
- Normals.Add(ParseFloatArray(parsed, 1));
+ Normals.Add(ParseFloatArray(parsed, 1, 3));
break;
case "vt":
- TexCoords.Add(ParseFloatArray(parsed, 1));
+ var vtEntry = ParseFloatArray(parsed, 1, 2);
+ vtEntry[1] = 1.0f - vtEntry[1];
+ TexCoords.Add(vtEntry);
break;
case "f":
AddFace(parsed);
@@ -178,10 +203,14 @@ namespace NW4RTools {
private float[] ParseFloatArray(string[] src, int index) {
- var output = new float[src.Length - index];
+ return ParseFloatArray(src, index, src.Length - index);
+ }
- for (int i = index; i < src.Length; i++) {
- output[i - index] = float.Parse(src[i]);
+ private float[] ParseFloatArray(string[] src, int index, int count) {
+ var output = new float[count];
+
+ for (int i = 0; i < count; i++) {
+ output[i] = float.Parse(src[i + index]);
}
return output;
@@ -203,7 +232,7 @@ namespace NW4RTools {
if (line.Length == 0 || line[0] == '#')
continue;
- var parsed = line.Split(' ');
+ var parsed = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
switch (parsed[0]) {
case "newmtl":
@@ -216,7 +245,7 @@ namespace NW4RTools {
currentMaterial.TevStageCount = 2;
currentMaterial.IndStageCount = 0;
-// This might need changing
+ // This might need changing
currentMaterial.CullMode = 2;
currentMaterial.SRTSettings[0] = new SRTSettingInfo();
@@ -233,106 +262,68 @@ namespace NW4RTools {
currentMaterial.ChanCtrls[1].MatColor.Rgba = 0x000000FF;
currentMaterial.ChanCtrls[1].AmbColor.Rgba = 0x00000000;
currentMaterial.ChanCtrls[1].FlagC = 0;
- currentMaterial.ChanCtrls[1].FlagA = 0;
+ currentMaterial.ChanCtrls[1].FlagA = 0;
+
+ currentMaterial.LightSetID = 1;
-// Default display lists, taken from test_lift
- // The current version of MonoDevelop likes to make an awful mess
- // of the indentation. There's nothing I can do about it. :/
- currentMaterial.PixDL = new byte[] {
- 0x61, 0xF3, 0x1E, 0xFF, 0x80,
- 0x61, 0x40, 0x00, 0x00, 0x17,
- 0x61, 0xFE, 0x00, 0xFF, 0xE3,
- 0x61, 0x41, 0x00, 0x34, 0xA0,
- 0x61, 0x42, 0x00, 0x00, 0x00,
-/* Padding */
- 0, 0, 0, 0, 0,
- 0, 0
- };
-
- currentMaterial.TevColorDL = new byte[] {
- 0x61, 0xE2, 0x00, 0x00, 0xFF,
- 0x61, 0xE3, 0x0F, 0xF0, 0xFF,
- 0x61, 0xE3, 0x0F, 0xF0, 0xFF,
- 0x61, 0xE3, 0x0F, 0xF0, 0xFF,
- 0x61, 0xE4, 0x00, 0x00, 0x00,
- 0x61, 0xE5, 0x00, 0x00, 0x00,
- 0x61, 0xE5, 0x00, 0x00, 0x00,
- 0x61, 0xE5, 0x00, 0x00, 0x00,
- 0x61, 0xE6, 0x00, 0x00, 0x00,
- 0x61, 0xE7, 0x00, 0x00, 0x00,
- 0x61, 0xE7, 0x00, 0x00, 0x00,
- 0x61, 0xE7, 0x00, 0x00, 0x00,
- /* Padding */
- 0, 0, 0, 0,
- 0x61, 0xE0, 0x80, 0x00, 0x00,
- 0x61,
- 0xE1, 0x80, 0x00, 0x00,
- 0x61, 0xE2, 0x80, 0x00, 0x00,
- 0x61,
- 0xE3, 0x80, 0x00, 0x00,
- 0x61, 0xE4, 0x80, 0x00, 0x00,
- 0x61,
- 0xE5, 0x80, 0x00, 0x00,
- 0x61, 0xE6, 0x80, 0x00, 0x00,
- 0x61,
- 0xE7, 0x80, 0x00, 0x00,
-/* More padding */
- 0, 0, 0, 0, 0, 0,
- 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0
- };
-
- currentMaterial.IndMtxAndScaleDL = new byte[] {
- 0x61, 0x25, 0x00, 0x00, 0x00,
- 0x61, 0x26, 0x00, 0x00, 0x00,
- /* Padding */
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0
- };
-
- currentMaterial.TexCoordGenDL = new byte[] {
- 0x10, 0x00, 0x00, 0x10, 0x40, 0x00, 0x00, 0x52,
- 0x80, 0x10,
- 0x00, 0x00, 0x10, 0x50, 0x00, 0x00,
-/* Padding? */
- 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0,
-0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
-0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,
-0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
-0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0,
-0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
-0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,
-0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-CurrentModel.Materials.Add(parsed[1], currentMaterial);
-
-
-Shader thisShader = CreateShader();
+ // Default display lists, taken from test_lift
+ var pixDL = new DisplayListWriter();
+ pixDL.LoadBPReg(0xF31EFF80);
+ pixDL.LoadBPReg(0x40000017);
+ pixDL.LoadBPReg(0xFE00FFE3);
+ pixDL.LoadBPReg(0x410034A0);
+ pixDL.LoadBPReg(0x42000000);
+ pixDL.End();
+
+ currentMaterial.PixDL = pixDL.GetBuffer();
+
+ var tevColorDL = new DisplayListWriter();
+ tevColorDL.LoadBPReg(0xE20000FF);
+ tevColorDL.LoadBPReg(0xE30FF0FF);
+ tevColorDL.LoadBPReg(0xE30FF0FF);
+ tevColorDL.LoadBPReg(0xE30FF0FF);
+ tevColorDL.LoadBPReg(0xE4000000);
+ tevColorDL.LoadBPReg(0xE5000000);
+ tevColorDL.LoadBPReg(0xE5000000);
+ tevColorDL.LoadBPReg(0xE5000000);
+ tevColorDL.LoadBPReg(0xE6000000);
+ tevColorDL.LoadBPReg(0xE7000000);
+ tevColorDL.LoadBPReg(0xE7000000);
+ tevColorDL.LoadBPReg(0xE7000000);
+ tevColorDL.AddPadding(4);
+ tevColorDL.LoadBPReg(0xE0800000);
+ tevColorDL.LoadBPReg(0xE1800000);
+ tevColorDL.LoadBPReg(0xE2800000);
+ tevColorDL.LoadBPReg(0xE3800000);
+ tevColorDL.LoadBPReg(0xE4800000);
+ tevColorDL.LoadBPReg(0xE5800000);
+ tevColorDL.LoadBPReg(0xE6800000);
+ tevColorDL.LoadBPReg(0xE7800000);
+ tevColorDL.AddPadding(24);
+ tevColorDL.End();
+
+ currentMaterial.TevColorDL = tevColorDL.GetBuffer();
+
+ var indMtxAndScaleDL = new DisplayListWriter();
+ indMtxAndScaleDL.LoadBPReg(0x25000000);
+ indMtxAndScaleDL.LoadBPReg(0x26000000);
+ indMtxAndScaleDL.AddPadding(54);
+ indMtxAndScaleDL.End();
+
+ currentMaterial.IndMtxAndScaleDL = indMtxAndScaleDL.GetBuffer();
+
+ var texCoordGenDL = new DisplayListWriter();
+ texCoordGenDL.LoadXFReg(0x1040, new byte[] { 0x00, 0x00, 0x52, 0x80 });
+ texCoordGenDL.LoadXFReg(0x1050, new byte[] { 0x00, 0x00, 0x00, 0x00 });
+ texCoordGenDL.AddPadding(110);
+ texCoordGenDL.End();
+
+ currentMaterial.TexCoordGenDL = texCoordGenDL.GetBuffer();
+
+ CurrentModel.Materials.Add(parsed[1], currentMaterial);
+
+
+ Shader thisShader = CreateShader();
CurrentModel.Shaders.Add(parsed[1], thisShader);
currentMaterial.ShaderRef = thisShader;
@@ -340,7 +331,7 @@ Shader thisShader = CreateShader();
case "map_Kd":
var rawTexName = string.Join(" ", parsed, 1, parsed.Length - 1);
-// TODO: fix this to use the mtllib path
+ // TODO: fix this to use the mtllib path
var texPath = Path.Combine(BasePath, rawTexName);
var texName = Path.GetFileNameWithoutExtension(texPath);
@@ -386,43 +377,39 @@ Shader thisShader = CreateShader();
shader.TevStageCount = 2;
shader.Unk1 = 0x00FFFFFF;
shader.Unk2 = 0xFFFFFFFF;
- shader.DisplayList = new byte[] {
- 0x61, 0xFE, 0x00, 0x00, 0x0F,
- 0x61, 0xF6, 0x00, 0x00, 0x04,
- 0x61, 0xFE, 0x00, 0x00, 0x0F,
- 0x61, 0xF7, 0x00, 0x00, 0x0E,
- 0x61, 0xFE, 0x00, 0x00, 0x0F,
- 0x61, 0xF8, 0x00, 0x00, 0x00,
- 0x61, 0xFE, 0x00, 0x00, 0x0F,
- 0x61, 0xF9, 0x00, 0x00, 0x0C,
- 0x61, 0xFE, 0x00, 0x00, 0x0F,
- 0x61, 0xFA, 0x00, 0x00, 0x05,
- 0x61, 0xFE, 0x00, 0x00, 0x0F,
- 0x61, 0xFB, 0x00, 0x00, 0x0D,
- 0x61, 0xFE, 0x00, 0x00, 0x0F,
- 0x61, 0xFC, 0x00, 0x00, 0x0A,
- 0x61, 0xFE, 0x00, 0x00, 0x0F,
- 0x61, 0xFD, 0x00, 0x00, 0x0E,
- 0x61, 0x27, 0xFF, 0xFF, 0xFF,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0x61, 0xFE, 0xFF, 0xFF,
- 0xF0,
- 0x61, 0xF6, 0xE3, 0x38, 0xC0,
- 0x61, 0x28, 0x03, 0xF0,
- 0x40,
- 0x61, 0xC0, 0x08, 0xF8, 0xAF,
- 0x61, 0xC2, 0x08, 0xF2,
- 0x0F,
- 0x61, 0xC1, 0x08, 0xF2, 0xF0,
- 0x61, 0xC3, 0x08, 0x1F,
- 0xF0,
-0x61, 0x10, 0x00, 0x00, 0x00,
-0x61, 0x11, 0x00, 0x00,
- 0x00
-};
-
- Array.Resize<byte>(ref shader.DisplayList, 0x1E0);
+
+ var dl = new DisplayListWriter();
+ dl.LoadBPReg(0xFE00000F);
+ dl.LoadBPReg(0xF6000004);
+ dl.LoadBPReg(0xFE00000F);
+ dl.LoadBPReg(0xF700000E);
+ dl.LoadBPReg(0xFE00000F);
+ dl.LoadBPReg(0xF8000000);
+ dl.LoadBPReg(0xFE00000F);
+ dl.LoadBPReg(0xF900000C);
+ dl.LoadBPReg(0xFE00000F);
+ dl.LoadBPReg(0xFA000005);
+ dl.LoadBPReg(0xFE00000F);
+ dl.LoadBPReg(0xFB00000D);
+ dl.LoadBPReg(0xFE00000F);
+ dl.LoadBPReg(0xFC00000A);
+ dl.LoadBPReg(0xFE00000F);
+ dl.LoadBPReg(0xFD00000E);
+ dl.LoadBPReg(0x27FFFFFF);
+ dl.AddPadding(11);
+ dl.LoadBPReg(0xFEFFFFF0);
+ dl.LoadBPReg(0xF6E338C0);
+ dl.LoadBPReg(0x2803F040);
+ dl.LoadBPReg(0xC008F8AF);
+ dl.LoadBPReg(0xC208F20F);
+ dl.LoadBPReg(0xC108F2F0);
+ dl.LoadBPReg(0xC3081FF0);
+ dl.LoadBPReg(0x10000000);
+ dl.LoadBPReg(0x11000000);
+ dl.PadToSize(0x1E0);
+ dl.End();
+
+ shader.DisplayList = dl.GetBuffer();
return shader;
}
@@ -555,53 +542,31 @@ Shader thisShader = CreateShader();
vs.GetDesc(out vd1, out vd2);
vs.GetAttrFmt(out vat1, out vat2, out vat3);
-
- // Todo: a Display List generator class
-
- CurrentShape.DLBufferSize1 = 0xE0;
- CurrentShape.DisplayList1 = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0x08, 0x50,
- (byte)((vd1 & 0xFF000000) >> 24),
- (byte)((vd1 & 0x00FF0000) >> 16),
- (byte)((vd1 & 0x0000FF00) >> 8),
- (byte)((vd1 & 0x000000FF)),
- 0x08, 0x60,
- (byte)((vd2 & 0xFF000000) >> 24),
- (byte)((vd2 & 0x00FF0000) >> 16),
- (byte)((vd2 & 0x0000FF00) >> 8),
- (byte)((vd2 & 0x000000FF)),
- 0x10, 0x00, 0x00, 0x10, 0x08, 0x00, 0x00, 0x00,
- 0x14, 0,
- 0x08, 0x70,
- (byte)((vat1 & 0xFF000000) >> 24),
- (byte)((vat1 & 0x00FF0000) >> 16),
- (byte)((vat1 & 0x0000FF00) >> 8),
- (byte)((vat1 & 0x000000FF)),
- 0x08, 0x80,
- (byte)((vat2 & 0xFF000000) >> 24),
- (byte)((vat2 & 0x00FF0000) >> 16),
- (byte)((vat2 & 0x0000FF00) >> 8),
- (byte)((vat2 & 0x000000FF)),
- 0x08, 0x90,
- (byte)((vat3 & 0xFF000000) >> 24),
- (byte)((vat3 & 0x00FF0000) >> 16),
- (byte)((vat3 & 0x0000FF00) >> 8),
- (byte)((vat3 & 0x000000FF))
- };
-
-
// I might need to create XFMEM_VTXSPECS...
// test_lift uses 0x14. According to Dolphin's src, this means:
// numcolors = 0, numnormals = 1 (just normal), numtextures = 1. Makes sense.
byte vtxSpecs = 0 | (1 << 2) | (1 << 4);
- CurrentShape.DisplayList1[0x1E] = vtxSpecs;
+
+ var dl1 = new DisplayListWriter();
+ dl1.AddPadding(10);
+ dl1.LoadCPReg(0x50, vd1);
+ dl1.LoadCPReg(0x60, vd2);
+ dl1.LoadXFReg(0x1008, new byte[] { 0x00, 0x00, 0x00, vtxSpecs });
+ dl1.Nop();
+ dl1.LoadCPReg(0x70, vat1);
+ dl1.LoadCPReg(0x80, vat2);
+ dl1.LoadCPReg(0x90, vat3);
// extend it
// should it be bigger if more texcoords are used? maybe...
- Array.Resize<byte>(ref CurrentShape.DisplayList1, 0x80);
+ dl1.PadToSize(0x80);
+ dl1.End();
+
+ CurrentShape.DLBufferSize1 = 0xE0;
+ CurrentShape.DisplayList1 = dl1.GetBuffer();
-// Display List 2 is where all the primitive-related fun happens
+ // Display List 2 is where all the primitive-related fun happens
// However, before we do that, let's compute the vertex data arrays
ushort[] posIndexes, texCoordIndexes, normalIndexes;
@@ -619,7 +584,7 @@ Shader thisShader = CreateShader();
posData.Data = posDataArray;
posData.Save();
- CurrentModel.VtxPosData.Add("Pos" + CurrentModel.VtxPosData.Count.ToString(), posData);
+ CurrentModel.VtxPosData.Add("P_" + CurrentModel.VtxPosData.Count.ToString(), posData);
var tcData = new VertexTexCoordData();
tcData.ComponentCount = VertexSettings.CompCount.TexCoord2;
@@ -630,9 +595,7 @@ Shader thisShader = CreateShader();
tcData.Data = tcDataArray;
tcData.Save();
- CurrentModel.VtxTexCoordData.Add("TexCoord" + CurrentModel.VtxTexCoordData.Count.ToString(), tcData);
-
- // TODO: Flip texcoords
+ CurrentModel.VtxTexCoordData.Add("T_" + CurrentModel.VtxTexCoordData.Count.ToString(), tcData);
var nrmData = new VertexNrmData();
nrmData.ComponentCount = VertexSettings.CompCount.Normal3;
@@ -643,52 +606,54 @@ Shader thisShader = CreateShader();
nrmData.Data = nrmDataArray;
nrmData.Save();
- CurrentModel.VtxNrmData.Add("Nrm" + CurrentModel.VtxNrmData.Count.ToString(), nrmData);
+ CurrentModel.VtxNrmData.Add("N_" + CurrentModel.VtxNrmData.Count.ToString(), nrmData);
CurrentShape.PosData = posData;
CurrentShape.TexCoordData[0] = tcData;
CurrentShape.NrmData = nrmData;
- var dl = new OutputStream();
-
+ var dl = new DisplayListWriter();
+
+ // face writing here is reversed because the wind order seems to be wrong
+ // dunno if it applies to models exported from everything, or just Maya
+ // or maybe it's a setting specified in one of the structs
+
if (Triangles.Count > 0) {
- dl.WriteByte((byte)GXCommand.DrawPrimitiveMask | ((byte)PrimitiveType.Triangles << (byte)GXCommand.PrimitiveShiftAmount));
- dl.WriteUInt16((ushort)(Triangles.Count * 3));
-
+ dl.BeginPrimitives(PrimitiveType.Triangles, 0, (ushort)(Triangles.Count * 3));
+
foreach (var tri in Triangles) {
- dl.WriteUInt16(posIndexes[tri[0]]);
- dl.WriteUInt16(normalIndexes[tri[1]]);
- dl.WriteUInt16(texCoordIndexes[tri[2]]);
- dl.WriteUInt16(posIndexes[tri[3]]);
- dl.WriteUInt16(normalIndexes[tri[4]]);
- dl.WriteUInt16(texCoordIndexes[tri[5]]);
dl.WriteUInt16(posIndexes[tri[6]]);
dl.WriteUInt16(normalIndexes[tri[7]]);
dl.WriteUInt16(texCoordIndexes[tri[8]]);
+ dl.WriteUInt16(posIndexes[tri[3]]);
+ dl.WriteUInt16(normalIndexes[tri[4]]);
+ dl.WriteUInt16(texCoordIndexes[tri[5]]);
+ dl.WriteUInt16(posIndexes[tri[0]]);
+ dl.WriteUInt16(normalIndexes[tri[1]]);
+ dl.WriteUInt16(texCoordIndexes[tri[2]]);
}
}
if (Quads.Count > 0) {
- dl.WriteByte((byte)GXCommand.DrawPrimitiveMask | ((byte)PrimitiveType.Quads << (byte)GXCommand.PrimitiveShiftAmount));
- dl.WriteUInt16((ushort)(Quads.Count * 3));
+ dl.BeginPrimitives(PrimitiveType.Quads, 0, (ushort)(Quads.Count * 4));
foreach (var quad in Quads) {
- dl.WriteUInt16(posIndexes[quad[0]]);
- dl.WriteUInt16(normalIndexes[quad[1]]);
- dl.WriteUInt16(texCoordIndexes[quad[2]]);
- dl.WriteUInt16(posIndexes[quad[3]]);
- dl.WriteUInt16(normalIndexes[quad[4]]);
- dl.WriteUInt16(texCoordIndexes[quad[5]]);
- dl.WriteUInt16(posIndexes[quad[6]]);
- dl.WriteUInt16(normalIndexes[quad[7]]);
- dl.WriteUInt16(texCoordIndexes[quad[8]]);
dl.WriteUInt16(posIndexes[quad[9]]);
dl.WriteUInt16(normalIndexes[quad[10]]);
dl.WriteUInt16(texCoordIndexes[quad[11]]);
+ dl.WriteUInt16(posIndexes[quad[6]]);
+ dl.WriteUInt16(normalIndexes[quad[7]]);
+ dl.WriteUInt16(texCoordIndexes[quad[8]]);
+ dl.WriteUInt16(posIndexes[quad[3]]);
+ dl.WriteUInt16(normalIndexes[quad[4]]);
+ dl.WriteUInt16(texCoordIndexes[quad[5]]);
+ dl.WriteUInt16(posIndexes[quad[0]]);
+ dl.WriteUInt16(normalIndexes[quad[1]]);
+ dl.WriteUInt16(texCoordIndexes[quad[2]]);
}
}
- dl.AlignTo(0x20);
+ dl.End();
CurrentShape.DisplayList2 = dl.GetBuffer();
CurrentShape.DLBufferSize2 = (uint)CurrentShape.DisplayList2.Length;
diff --git a/NW4RTools/OutputStream.cs b/NW4RTools/OutputStream.cs
index e934158..2243d90 100644
--- a/NW4RTools/OutputStream.cs
+++ b/NW4RTools/OutputStream.cs
@@ -49,7 +49,7 @@ namespace NW4RTools {
}
public void AddPadding(int count) {
- if (count == 0)
+ if (count <= 0)
return;
else if (count == 1)
WriteByte(0);
@@ -58,6 +58,10 @@ namespace NW4RTools {
WriteByte(0);
}
+ public void PadToSize(int size) {
+ AddPadding(size - Position);
+ }
+
public void WriteBytes(byte[] data) {
BaseStream.Write(data, 0, data.Length);
}
diff --git a/NW4RTools/bin/Debug/NW4RTools.dll b/NW4RTools/bin/Debug/NW4RTools.dll
index e4c2ea1..497cebb 100755
--- a/NW4RTools/bin/Debug/NW4RTools.dll
+++ b/NW4RTools/bin/Debug/NW4RTools.dll
Binary files differ
diff --git a/NW4RTools/bin/Debug/NW4RTools.dll.mdb b/NW4RTools/bin/Debug/NW4RTools.dll.mdb
index 62014b8..e36c23e 100644
--- a/NW4RTools/bin/Debug/NW4RTools.dll.mdb
+++ b/NW4RTools/bin/Debug/NW4RTools.dll.mdb
Binary files differ
diff --git a/TestApp/Main.cs b/TestApp/Main.cs
index a5db889..fbaa7dc 100644
--- a/TestApp/Main.cs
+++ b/TestApp/Main.cs
@@ -11,39 +11,30 @@ namespace TestApp {
public static void Main(string[] args) {
string mdlPath = "/home/me/Games/Newer/ModelRev/";
- /*//string mdlName = "CS_W1";
- //string mdlName = "bgB_4502";
- //string mdlName = "cobKoopaCastle";
- string mdlName = "waterPlate_W4boss";
- mdlName = "test_lift";
+ //skawo();
+ //oldBehaviour();
+ //return;
- string whatever = (mdlName == "CS_W2" || mdlName == "CS_W3" || mdlName == "CS_W6") ? "a" : "";
- byte[] file = File.ReadAllBytes(mdlPath + mdlName + ".brres");
- ResFile rf = BrresReader.LoadFile(file);
+ // Going to create a model!
+ //string filename = "crapmap", resmdlname = "CrapMap";
+ string filename = "GoldwoodBase", resmdlname = "GoldwoodBase";
- File.WriteAllBytes(mdlPath + mdlName + "_rewritten.brres", BrresWriter.WriteFile(rf));*/
- // Going to create a model!
ResFile rf = new ResFile();
- ObjImporter.ImportModel(mdlPath, File.OpenText(mdlPath + "crapmap.obj"), rf, "CrapMap");
+ ObjImporter.ImportModel(mdlPath, File.OpenText(mdlPath + filename + ".obj"), rf, resmdlname);
- File.WriteAllBytes(mdlPath + "crapmap.brres", BrresWriter.WriteFile(rf));
+ File.WriteAllBytes(mdlPath + filename + ".brres", BrresWriter.WriteFile(rf));
- ResFile rf2 = BrresReader.LoadFile(File.ReadAllBytes(mdlPath + "crapmap.brres"));
+ ResFile rf2 = BrresReader.LoadFile(File.ReadAllBytes(mdlPath + filename + ".brres"));
using (var gw = new RenderWindow()) {
- gw.Title = "crapmap";
- gw.SetModel(rf2, "CrapMap");
+ gw.Title = filename;
+ gw.SetModel(rf2, resmdlname);
gw.Run(1, 1);
}
- /*using (var gw = new RenderWindow()) {
- gw.Title = mdlName;
- gw.SetModel(rf, mdlName);
- gw.Run(1, 1);
- }*/
@@ -60,6 +51,48 @@ namespace TestApp {
ColladaWriter.WriteModel(objFile, rf, mdlName + whatever);
objFile.Close();*/
}
+
+
+ private static void skawo() {
+ string mdlPath = "/home/me/Games/Newer/ModelRev/";
+ string skawopath = "/home/me/Dropbox/NEWERsmbw/Nowy folder/obj/";
+ ResFile rf = new ResFile();
+
+ ObjImporter.ImportModel(skawopath, File.OpenText(skawopath + "edited.obj"), rf, "Skawo");
+
+ File.WriteAllBytes(skawopath + "skawo.brres", BrresWriter.WriteFile(rf));
+
+
+ ResFile rf2 = BrresReader.LoadFile(File.ReadAllBytes(skawopath + "skawo.brres"));
+ using (var gw = new RenderWindow()) {
+ gw.Title = "Skawo";
+ gw.SetModel(rf2, "Skawo");
+ gw.Run(1, 1);
+ }
+ }
+
+ private static void oldBehaviour() {
+ string mdlPath = "/home/me/Games/Newer/ModelRev/";
+ string mdlName = "CS_W1";
+ //string mdlName = "bgB_4502";
+ //string mdlName = "cobKoopaCastle";
+ //string mdlName = "waterPlate_W4boss";
+ //mdlName = "test_lift";
+
+ string whatever = (mdlName == "CS_W2" || mdlName == "CS_W3" || mdlName == "CS_W6") ? "a" : "";
+
+ byte[] file = File.ReadAllBytes(mdlPath + mdlName + ".brres");
+ ResFile rf = BrresReader.LoadFile(file);
+
+ using (var gw = new RenderWindow()) {
+ gw.Title = mdlName;
+ gw.SetModel(rf, mdlName);
+ gw.Run(1, 1);
+ }
+
+ //File.WriteAllBytes(mdlPath + mdlName + "_rewritten.brres", BrresWriter.WriteFile(rf));
+
+ }
}
}
diff --git a/TestApp/RenderWindow.cs b/TestApp/RenderWindow.cs
index 2f29d0f..6013724 100644
--- a/TestApp/RenderWindow.cs
+++ b/TestApp/RenderWindow.cs
@@ -27,6 +27,22 @@ namespace TestApp {
GL.Enable(EnableCap.Blend);
GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
+ GL.Disable(EnableCap.CullFace);
+
+ GL.Enable(EnableCap.Lighting);
+
+ GL.ShadeModel(ShadingModel.Smooth);
+
+ GL.Light(LightName.Light0, LightParameter.Position, new Vector4(0, 500, 1000, 0));
+ GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Specular, new Color4(1, 1, 1, 1));
+ GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Shininess, 50);
+ GL.Enable(EnableCap.Light0);
+
+ GL.Light(LightName.Light1, LightParameter.Position, new Vector4(1000, 500, 0, 0));
+ GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Specular, new Color4(1, 1, 1, 1));
+ GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Shininess, 50);
+ GL.Enable(EnableCap.Light1);
+
m_glModel.Prepare(Context);
}
@@ -45,8 +61,8 @@ namespace TestApp {
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
- //Matrix4 modelview = Matrix4.LookAt(new Vector3(1000, 600, 1000), new Vector3(1000, 0, 0), Vector3.UnitY);
- Matrix4 modelview = Matrix4.LookAt(new Vector3(0, 2, 4), new Vector3(0, 0, 0), Vector3.UnitY);
+ Matrix4 modelview = Matrix4.LookAt(new Vector3(1000, 400, 1000), new Vector3(1000, 0, 0), Vector3.UnitY);
+ //Matrix4 modelview = Matrix4.LookAt(new Vector3(-3, 2, 3), new Vector3(0, 0, 0), Vector3.UnitY);
GL.MatrixMode(MatrixMode.Modelview);
GL.LoadMatrix(ref modelview);
diff --git a/TestApp/TestApp.pidb b/TestApp/TestApp.pidb
index bbc694a..e8df7af 100644
--- a/TestApp/TestApp.pidb
+++ b/TestApp/TestApp.pidb
Binary files differ
diff --git a/TestApp/bin/Debug/NW4RTools.dll b/TestApp/bin/Debug/NW4RTools.dll
index e4c2ea1..40356de 100755
--- a/TestApp/bin/Debug/NW4RTools.dll
+++ b/TestApp/bin/Debug/NW4RTools.dll
Binary files differ
diff --git a/TestApp/bin/Debug/NW4RTools.dll.mdb b/TestApp/bin/Debug/NW4RTools.dll.mdb
index 62014b8..92742d0 100644
--- a/TestApp/bin/Debug/NW4RTools.dll.mdb
+++ b/TestApp/bin/Debug/NW4RTools.dll.mdb
Binary files differ
diff --git a/TestApp/bin/Debug/TestApp.exe b/TestApp/bin/Debug/TestApp.exe
index a5251b0..5b808e0 100755
--- a/TestApp/bin/Debug/TestApp.exe
+++ b/TestApp/bin/Debug/TestApp.exe
Binary files differ
diff --git a/TestApp/bin/Debug/TestApp.exe.mdb b/TestApp/bin/Debug/TestApp.exe.mdb
index 7508ce0..8ec2779 100644
--- a/TestApp/bin/Debug/TestApp.exe.mdb
+++ b/TestApp/bin/Debug/TestApp.exe.mdb
Binary files differ