Jump to content

SceneNavi - A simple Ocarina of Time level editor


xdaniel
 Share

Recommended Posts

Implementing Nini was really easy: Copypasta'd and modified/simplified an example class from Stack Overflow, manually added all the properties previously managed by Properties.Settings, then did a mass replace in the project from "Properties.Settings.Default" to "Configuration".

 

The resulting Configuration class as of right now:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

using Nini.Config;

namespace SceneNavi
{
    /* Based on http://stackoverflow.com/a/15869868 */

    static class Configuration
    {
        static readonly string ConfigName = "Main";

        static string configPath;
        static string configFilename;

        static IConfigSource source;

        public static string FullConfigFilename { get { return (Path.Combine(configPath, configFilename)); } }

        public static bool RenderRoomActors
        {
            get { return (source.Configs[ConfigName].GetBoolean("RenderRoomActors", true)); }
            set { source.Configs[ConfigName].Set("RenderRoomActors", value); }
        }

        public static bool RenderSpawnPoints
        {
            get { return (source.Configs[ConfigName].GetBoolean("RenderSpawnPoints", true)); }
            set { source.Configs[ConfigName].Set("RenderSpawnPoints", value); }
        }

        public static bool RenderTransitions
        {
            get { return (source.Configs[ConfigName].GetBoolean("RenderTransitions", true)); }
            set { source.Configs[ConfigName].Set("RenderTransitions", value); }
        }

        public static string LastROM
        {
            get { return (source.Configs[ConfigName].GetString("LastROM", string.Empty)); }
            set { source.Configs[ConfigName].Set("LastROM", value); }
        }

        public static bool RenderPathWaypoints
        {
            get { return (source.Configs[ConfigName].GetBoolean("RenderPathWaypoints", false)); }
            set { source.Configs[ConfigName].Set("RenderPathWaypoints", value); }
        }

        public static bool LinkAllWPinPath
        {
            get { return (source.Configs[ConfigName].GetBoolean("LinkAllWPinPath", true)); }
            set { source.Configs[ConfigName].Set("LinkAllWPinPath", value); }
        }

        public static bool RenderTextures
        {
            get { return (source.Configs[ConfigName].GetBoolean("RenderTextures", true)); }
            set { source.Configs[ConfigName].Set("RenderTextures", value); }
        }

        public static bool RenderCollision
        {
            get { return (source.Configs[ConfigName].GetBoolean("RenderCollision", false)); }
            set { source.Configs[ConfigName].Set("RenderCollision", value); }
        }

        public static bool RenderCollisionAsWhite
        {
            get { return (source.Configs[ConfigName].GetBoolean("RenderCollisionAsWhite", false)); }
            set { source.Configs[ConfigName].Set("RenderCollisionAsWhite", value); }
        }

        public static bool OGLVSync
        {
            get { return (source.Configs[ConfigName].GetBoolean("OGLVSync", true)); }
            set { source.Configs[ConfigName].Set("OGLVSync", value); }
        }

        public static SceneNavi.ToolModes LastToolMode
        {
            get { return ((SceneNavi.ToolModes)Enum.Parse(typeof(SceneNavi.ToolModes), (source.Configs[ConfigName].GetString("LastToolMode", "Camera")))); }
            set { source.Configs[ConfigName].Set("LastToolMode", value); }
        }

        public static string LastSceneFile
        {
            get { return (source.Configs[ConfigName].GetString("LastSceneFile", string.Empty)); }
            set { source.Configs[ConfigName].Set("LastSceneFile", value); }
        }

        public static string LastRoomFile
        {
            get { return (source.Configs[ConfigName].GetString("LastRoomFile", string.Empty)); }
            set { source.Configs[ConfigName].Set("LastRoomFile", value); }
        }

        public static SceneNavi.CombinerTypes CombinerType
        {
            get { return ((SceneNavi.CombinerTypes)Enum.Parse(typeof(SceneNavi.CombinerTypes), (source.Configs[ConfigName].GetString("CombinerType", "None")))); }
            set { source.Configs[ConfigName].Set("CombinerType", value); }
        }

        public static bool ShownExtensionWarning
        {
            get { return (source.Configs[ConfigName].GetBoolean("ShownExtensionWarning", false)); }
            set { source.Configs[ConfigName].Set("ShownExtensionWarning", value); }
        }

        public static bool ShownIntelWarning
        {
            get { return (source.Configs[ConfigName].GetBoolean("ShownIntelWarning", false)); }
            set { source.Configs[ConfigName].Set("ShownIntelWarning", value); }
        }

        public static bool RenderWaterboxes
        {
            get { return (source.Configs[ConfigName].GetBoolean("RenderWaterboxes", true)); }
            set { source.Configs[ConfigName].Set("RenderWaterboxes", value); }
        }

        public static bool ShowWaterboxesPerRoom
        {
            get { return (source.Configs[ConfigName].GetBoolean("ShowWaterboxesPerRoom", true)); }
            set { source.Configs[ConfigName].Set("ShowWaterboxesPerRoom", value); }
        }

        public static bool IsRestarting
        {
            get { return (source.Configs[ConfigName].GetBoolean("IsRestarting", false)); }
            set { source.Configs[ConfigName].Set("IsRestarting", value); }
        }

        public static int AntiAliasingSamples
        {
            get { return (source.Configs[ConfigName].GetInt("AntiAliasingSamples", 0)); }
            set { source.Configs[ConfigName].Set("AntiAliasingSamples", value); }
        }

        public static bool EnableAntiAliasing
        {
            get { return (source.Configs[ConfigName].GetBoolean("EnableAntiAliasing", false)); }
            set { source.Configs[ConfigName].Set("EnableAntiAliasing", value); }
        }

        public static bool EnableMipmaps
        {
            get { return (source.Configs[ConfigName].GetBoolean("EnableMipmaps", false)); }
            set { source.Configs[ConfigName].Set("EnableMipmaps", value); }
        }

        static Configuration()
        {
            PrepareConfig();

            source = new XmlConfigSource(FullConfigFilename);
            source.AutoSave = true;

            CreateConfigSections();
        }

        static void CreateConfigSections()
        {
            if (source.Configs[ConfigName] == null) source.AddConfig(ConfigName);
        }

        static void PrepareConfig()
        {
            configPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), System.Windows.Forms.Application.ProductName);
            configFilename = String.Format("{0}.xml", ConfigName);
            Directory.CreateDirectory(configPath);

            if (!File.Exists(FullConfigFilename)) File.WriteAllText(FullConfigFilename, "<Nini>\n</Nini>\n");
        }
    }
}
  • Like 1
Link to comment
Share on other sites

Nice, glad it was so simple, I was planning on using C# again for some tools so Nini will be a good choice for me.

I usually create my own configuration format, but for Sakura Engine I chose to use tinyxml.

 

Not the greatest looking thing in the world, but it gets the job done:

<?xml version="1.0" encoding="UTF-8" ?>
<Config>
    <Bind action="playerdown" key="down" mouseButton="unknown">
        <Joy id="0" button="-1" axis="unknown" isAxisNegative="false" />
        <Joy id="1" button="-1" axis="unknown" isAxisNegative="false" />
        <Joy id="2" button="-1" axis="unknown" isAxisNegative="false" />
        <Joy id="3" button="-1" axis="unknown" isAxisNegative="false" />
        <Joy id="4" button="-1" axis="unknown" isAxisNegative="false" />
        <Joy id="5" button="-1" axis="unknown" isAxisNegative="false" />
        <Joy id="6" button="-1" axis="unknown" isAxisNegative="false" />
        <Joy id="7" button="-1" axis="unknown" isAxisNegative="false" />
    </Bind>
    <CVar name="r_showfps" type="boolean">false</CVar>
    <CVar name="r_drawwire" type="boolean">false</CVar>
    <CVar name="r_clear" type="boolean">true</CVar>
    <CVar name="sys_title" type="literal">
        <![CDATA[A Link to the Past Remake 0.1 INTERNAL PRE-ALPHA]]>
</CVar>
    <CVar name="r_clearcolor" type="color" r="72" g="160" b="72" a="255" />
    <CVar name="vid_width" type="integer">640</CVar>
    <CVar name="sys_framelimit" type="integer">60</CVar>
    <CVar name="r_fullscreen" type="boolean">false</CVar>
    <CVar name="vid_height" type="integer">480</CVar>
    <CVar name="sys_vsync" type="boolean">true</CVar>
    <CVar name="sys_showstats" type="boolean">false</CVar>
</Config>

Need to add some checks to it, so I don't have to add all of those invalid bindings.

Link to comment
Share on other sites

Small changes to individual file mode as per petrie's suggestions: It now automatically selects the first stage/object set in the tree, the scene open dialog now has filters for *.zscene and *.*, and the room open dialog has filters for *.zmap/*.zroom and *.*.

 

Also changed room vertex selection; right-clicking a polygon's vertex now shows a pop-up menu with options to change its color and display its properties.

 

TAbzegt.png

 

Need to write up another preliminary changelog for Beta 9, I think; got bunch of small changes and fixes, a few new features...

  • Like 2
Link to comment
Share on other sites

So a few more actors have been added in this doc, still a wip.

 

http://pastebin.com/qGkumjx2

 

Edit: Found an odd bug, not sure if it's something needing fixing though since my xml def is wrong.

 

  <Definition Number="0x0117">
    <Item Index="0" ValueType="System.UInt16" DisplayStyle="Hexadecimal" Usage="ActorNumber" Description="Actor Type" ControlType="System.Windows.Forms.TextBox" />
    <Item Index="2" ValueType="System.Int16" Usage="PositionX" Description="Position (X)" ControlType="System.Windows.Forms.TextBox" Mask="0xFFFF" />
    <Item Index="4" ValueType="System.Int16" Usage="PositionY" Description="Position (Y)" ControlType="System.Windows.Forms.TextBox" Mask="0xFFFF" />
    <Item Index="6" ValueType="System.Int16" Usage="PositionZ" Description="Position (Z)" ControlType="System.Windows.Forms.TextBox" Mask="0xFFFF" />
    <Item Index="8" ValueType="System.Int16" DisplayStyle="Hexadecimal" Usage="RotationX" Description="Rotation (X)" ControlType="System.Windows.Forms.TextBox" Mask="0xFFFF" />
    <Item Index="10" ValueType="System.Int16" DisplayStyle="Hexadecimal" Usage="RotationY" Description="Rotation (Y)" ControlType="System.Windows.Forms.TextBox" Mask="0xFFFF" />
    <Item Index="12" ValueType="System.Int16" DisplayStyle="Hexadecimal" Usage="RotationZ" Description="Rotation (Z)" ControlType="System.Windows.Forms.TextBox" Mask="0xFFFF" />
    <Item Index="14" ValueType="System.Byte" DisplayStyle="Hexadecimal" Description="Type" ControlType="System.Windows.Forms.ComboBox" Mask="0x10">
      <Option Value="0x01" Description="Silver Rupee" />
      <Option Value="0x00" Description="Control Actor" />
    </Item>
    <Item Index="14" ValueType="System.UInt16" DisplayStyle="Decimal" Description="Rupees to Collect" ControlType="System.Windows.Forms.TextBox" Mask="0x0FC0" />
    <Item Index="15" ValueType="System.Byte" DisplayStyle="Hexadecimal" Description="Switch Flag" ControlType="System.Windows.Forms.TextBox" Mask="0x3F" />
  </Definition>
Note the "Type" item has a mask of 0x10, but has an option value of 0x01 (which is impossible) for Silver Rupee. Now if you open up map 12 of shadow temple (tested in decompressed 1.0 but should work in debug I think), scroll down the list of actors with the down arrow. The type combobox will be blanked for all but the control actor. Now, scroll up. Rather than a blank option like before, it will display the actor as being a Silver Rupee.
Link to comment
Share on other sites

So, I "kind of" picked up modding and custom scene making yesterday and therefor actually messed around a little with this tool, and I've come across the most annoying bug. It is driving me nuts.

If you hold an arrow key and move the camera in a direction while changing tab on the right side, then release the arrow key, it will still be registered as pressed, so the camera just keep moving...

I have to repress the key in question and then release it for the camera to stop.

This happens to me like once or twice per minute, because I try to multitask and move the camera around while navigating the menus. It sure is a pain when the camera just keep panning away.

The same goes for the space bar, etc.

Link to comment
Share on other sites

Edit: Found an odd bug, not sure if it's something needing fixing though since my xml def is wrong.

 

[...]

 

Note the "Type" item has a mask of 0x10, but has an option value of 0x01 (which is impossible) for Silver Rupee. Now if you open up map 12 of shadow temple (tested in decompressed 1.0 but should work in debug I think), scroll down the list of actors with the down arrow. The type combobox will be blanked for all but the control actor. Now, scroll up. Rather than a blank option like before, it will display the actor as being a Silver Rupee.

Hmm, worth looking into despite the wrong definition, as the program's behavior should be consistent regardless.

 


Would it be possible to implement a feature where it will highlight all polygons with the same collision type?

While it's only been meant to select and edit a single collision polygon at a time, this does sound useful to have, ex. for changing the type of multiple polygons at once, etc. Performance might be an issue, but I'll look into this as well.

 


 

If you hold an arrow key and move the camera in a direction while changing tab on the right side, then release the arrow key, it will still be registered as pressed, so the camera just keep moving...

I have to repress the key in question and then release it for the camera to stop.

I thought I had fixed this, but that might've been in another program... Should be an easy fix, likely just need to clear the keys pressed when the 3D view loses focus.

 

EDIT, fixed:

private void customGLControl_Leave(object sender, EventArgs e)
{
    keysDown.Fill(new bool[] { false });
}

Gotta work on SceneNavi again, huh? :P

Edited by xdaniel
Link to comment
Share on other sites

Despite the problem being fixed, to â–²ChriisTiianâ–² and everyone else who encounters errors in SceneNavi:

 

Always post as many details as possible about an error, about the ROM you used, about what you did with the ROM and in SceneNavi, etc.

 

There's always the chance that I might not be able to reproduce the problem on my end - as can be seen in this very thread, where ex. people's ROMs were simply messed up -, so without any details, I'd have to randomly take stabs in the dark to try and localize the source of the problem.

 

Edit, and this, yep:

Also take a screenshot of the error that pops up. They tell xDan what class and where in that class the error occurred (or at least give him a starting point). They also give him the actual error message (index out of bounds anyone?) :P

Edited by xdaniel
  • Like 2
Link to comment
Share on other sites

But I can't just put if(variable >= 0 && variable < array.Length)s and if(variable != null)s everywhere! Or shudder, try-catch statements! That would be work and proper technique! What do you think I am, application developer by trade? Well, if things work out, I might be two years from now, but right now, I'm not! :P

 

(But really, I know that better error handling wouldn't hurt, I'm just lazy...)

 

Link to comment
Share on other sites

 Share

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.