RunUO Community

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

Ultima SDK [UPDATED]

arul

Sorceror
Ultima SDK v2.2 [UPDATED]

UO SDK needs more love, so here it goes:

Changelog:

This version of Ultima SDK has been compiled against .NET 2.0.

Supported clients:
- 2.0.0.0 -> 6.0.10.0

Further release:
- Unicode text export support
- Multi-Client support (thanks Sairon for suggestion)
- Light bitmap export(thanks turley for suggestion)

New features:
- ASCII text export.
- Sound export.

Fixes:
- Calibration info & find location algorithm updated for the new client(6.0.9.2+)!
- Animation class now supports the ML exapnsion.
- Fixed the PeekChar() bug.
- TileMatrixPatch file names update (thanks Alari, HellRazor, Sotho Tal Ker).

Suggestions & bug reports strongly appreciated.

Thanks to rsmiller21 for suggestions on sounds.

Download UltimaSDK
 

rsmiller21

Wanderer
I have been working on a program dealing with the new Ultima.dll here and wanted to post a few code snippets.


Playing the sound:
Code:
[SIZE=2][COLOR=#0000ff]
public[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]static[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]void[/COLOR][/SIZE][SIZE=2] PlaySound([/SIZE][SIZE=2][COLOR=#008080]MemoryStream[/COLOR][/SIZE][SIZE=2] ms)
{
System.Media.[/SIZE][SIZE=2][COLOR=#008080]SoundPlayer[/COLOR][/SIZE][SIZE=2] sp = [/SIZE][SIZE=2][COLOR=#0000ff]new[/COLOR][/SIZE][SIZE=2] System.Media.[/SIZE][SIZE=2][COLOR=#008080]SoundPlayer[/COLOR][/SIZE][SIZE=2]();[/SIZE]
[SIZE=2]sp.Stream = ms;[/SIZE]
[SIZE=2]sp.Play();
}
[/SIZE]

Get sound file name with the sound id:
Code:
[SIZE=2][COLOR=#0000ff]
public[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]static[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]string[/COLOR][/SIZE][SIZE=2] GetSoundName([/SIZE][SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][SIZE=2] soundID)
{
[/SIZE][SIZE=2][COLOR=#0000ff]if[/COLOR][/SIZE][SIZE=2] (soundID < 0) { [/SIZE][SIZE=2][COLOR=#0000ff]return[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]null[/COLOR][/SIZE][SIZE=2]; }
 
m_Index.BaseStream.Seek(([/SIZE][SIZE=2][COLOR=#0000ff]long[/COLOR][/SIZE][SIZE=2])(soundID * 12), [/SIZE][SIZE=2][COLOR=#008080]SeekOrigin[/COLOR][/SIZE][SIZE=2].Begin);
 
[/SIZE][SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][SIZE=2] offset = m_Index.ReadInt32();
[/SIZE][SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][SIZE=2] length = m_Index.ReadInt32();
[/SIZE][SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][SIZE=2] extra = m_Index.ReadInt32();
[/SIZE][SIZE=2][COLOR=#0000ff]if[/COLOR][/SIZE][SIZE=2] ((offset < 0) || (length <= 0))
{
[/SIZE][SIZE=2][COLOR=#0000ff]if[/COLOR][/SIZE][SIZE=2] (!m_Translations.TryGetValue(soundID, [/SIZE][SIZE=2][COLOR=#0000ff]out[/COLOR][/SIZE][SIZE=2] soundID)) { [/SIZE][SIZE=2][COLOR=#0000ff]return[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]null[/COLOR][/SIZE][SIZE=2]; }
m_Index.BaseStream.Seek(([/SIZE][SIZE=2][COLOR=#0000ff]long[/COLOR][/SIZE][SIZE=2])(soundID * 12), [/SIZE][SIZE=2][COLOR=#008080]SeekOrigin[/COLOR][/SIZE][SIZE=2].Begin);
offset = m_Index.ReadInt32();
length = m_Index.ReadInt32();
extra = m_Index.ReadInt32();
}
[/SIZE][SIZE=2][COLOR=#0000ff]if[/COLOR][/SIZE][SIZE=2] ((offset < 0) || (length <= 0)) { [/SIZE][SIZE=2][COLOR=#0000ff]return[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]null[/COLOR][/SIZE][SIZE=2]; }
[/SIZE][SIZE=2][COLOR=#0000ff]byte[/COLOR][/SIZE][SIZE=2][] buffer = [/SIZE][SIZE=2][COLOR=#0000ff]new[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]byte[/COLOR][/SIZE][SIZE=2][40];
m_Stream.Seek(([/SIZE][SIZE=2][COLOR=#0000ff]long[/COLOR][/SIZE][SIZE=2])(offset), [/SIZE][SIZE=2][COLOR=#008080]SeekOrigin[/COLOR][/SIZE][SIZE=2].Begin);
m_Stream.Read(buffer, 0, 40);
[/SIZE][SIZE=2][COLOR=#0000ff]return[/COLOR][/SIZE][SIZE=2] System.Text.[/SIZE][SIZE=2][COLOR=#008080]Encoding[/COLOR][/SIZE][SIZE=2].UTF8.GetString(buffer);
}
[/SIZE]

Sorry, that was basicly a rip off from GetSound lol. I needed a quick fix and that should do it.
 

arul

Sorceror
Great idea!

I made some changes to the Sound class, so that now it should be easier to work with. Check out the new archives.

Thanks for the suggestion rsmiller21.
 

HellRazor

Knight
In the original source of the SDK the map dif files aren't named correctly, there is a minor typo. Which, if I was reading the source correctly, would result in the map patches never being loaded by the SDK.
 

turley

Sorceror
If you are interested i made a extension to read the light.mul:

Code:
using System;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;

namespace Ultima
{
    public class Light
    {
        private static FileIndex m_FileIndex = new FileIndex("lightidx.mul", "light.mul", 0x100, -1);
        public static FileIndex FileIndex { get { return m_FileIndex; } }

        private static Bitmap[] m_Cache = new Bitmap[0x100];

        public static Bitmap[] Cache { get { return m_Cache; } }

        public static int GetCount()
        {
            string idxPath=Client.GetFilePath("lightidx.mul");
            FileStream index = new FileStream( idxPath, FileMode.Open, FileAccess.Read, FileShare.Read );

            return (int)(index.Length/12);
        }

        public static bool TestLight(int index)
        {
            if (m_Cache[index] != null)
                return true;

            int length, extra;
            bool patched;

            Stream stream = m_FileIndex.Seek(index, out length, out extra, out patched);

            if (stream == null)
                return false;

            return true;
        }

        public unsafe static Bitmap GetLight(int index)
        {
            if (m_Cache[index] != null)
                return m_Cache[index];

            int length, extra;
            bool patched;

            Stream stream = m_FileIndex.Seek(index, out length, out extra, out patched);

            if (stream == null)
                return null;

            int width = (extra & 0xFFFF);
            int height = ((extra >> 16) & 0xFFFF);

            Bitmap bmp = new Bitmap(width, height, PixelFormat.Format16bppArgb1555);
            BitmapData bd = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format16bppArgb1555);
            BinaryReader bin = new BinaryReader(stream);

            ushort* line = (ushort*)bd.Scan0;
            int delta = bd.Stride >> 1;

            ushort read;

            for (int y = 0; y < height; ++y, line += delta)
            {
                ushort* cur = line;
                ushort* end = cur + width;

                while (cur < end)
                {
                    read = (ushort)bin.ReadSByte();

                    if (read == 0)
                        *cur++ = 255;
                    else
                        *cur++ = (ushort)((read ^0x8000));
                }
            }

            bmp.UnlockBits(bd);

            return m_Cache[index] = bmp;
        }
    }
}

TestLight(index) is a fast checkup to get existing entries
GetLight(index) gives you the bmp

I made it for my insideuo replacement based on ultimasdk, but because it was my first c# project i think the style is really bad, so i never published it to a bigger croud :)
 

arul

Sorceror
Thanks, I'll include your code in the next update :)

And don't worry about the code, it looks more than fine.
 

arul

Sorceror
Varchild;775539 said:
I suggest you to merge with stadard SDK release.
Most Generics tweaks are missing
I've been thinking about it. The problem is backwards compatibility with older programs. And after all, converting the code to use generics isn't that hot as it seems to be.
 

arul

Sorceror
HellRazor;775562 said:
FYI, the binary seems to be corrupt.
Tried reuploading it 4 times, always got the same error :/ Seems like forums are doing it.

I removed the compiled DLL for the time being, if you want to use this SDK you have to download the source and compile it yourself.

Thanks for letting me know.
 

HellRazor

Knight
megamandos;788987 said:
just wondering could this be used to build something like razor?

Not really, the Ultima SDK provides an easy means to read the client artwork, maps etc.

However, UOAI could possibly be used to write a Razor-like program:

UOAI Main Page
 
Top