It is currently 16 Apr 2024, 18:33
   
Text Size

I managed to reverse engineer Shandalar's SPR file format

MicroProse's Shandalar Campaign Game, now with new cards & a new look!

Moderators: BAgate, drool66, Aswan jaguar, gmzombie, stassy, CCGHQ Admins

I managed to reverse engineer Shandalar's SPR file format

Postby CelestialAmber » 21 Aug 2019, 10:38

I can't upload a link to the tool because of the forum's limits on link posting, so here is the code that I wrote that handles parsing spr files. I tested it on many spr files, and it seems like it works for all of the spr files in Shandalar.
Code: Select all
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;



namespace PicDecode{
    public class SprDecoder{
       
        public static Bitmap[] GetSprites (byte[] data, Color[] palette){
            List<Bitmap> bitmaps = new List<Bitmap>();
            int offset = 0;
            int imageIndex = 0;
            while(offset < data.Length){
                int startOffset = offset;
                UInt32 imageDataSize = BitConverter.ToUInt32(data, offset);
                if (imageDataSize == 0xFFFFFFFF) break;
                offset += 4;
                int width = BitConverter.ToUInt16(data,offset);
                offset += 2;
                int height = BitConverter.ToUInt16(data,offset);
                offset += 2;
                int unknown1 = BitConverter.ToUInt16(data,offset);
                offset += 2;
                int unknown2 = BitConverter.ToUInt16(data, offset);
                offset += 2;
                int numberOfEmptyLinesAbove = BitConverter.ToUInt16(data, offset);
                offset += 2;
                int cutoffOffsetY = BitConverter.ToUInt16(data, offset); //how many lines after the transparent space in the image to start setting pixels as transparent
                offset += 2;
                Bitmap bitmap = new Bitmap(width,height);
                //Console.WriteLine("Image " + imageIndex + " information: offset: 0x" + startOffset.ToString("X") +  ", Image data size: 0x" + imageDataSize.ToString("X") +
                //   ", width: " + width + ", height: " + height + ", unknown1: 0x" +
                //    unknown1.ToString("X") + ", unknown2: 0x" + unknown2.ToString("X") + ",number of top empty lines: " + numberOfEmptyLinesAbove + ", cutoff y offset: " + cutoffOffsetY) ;

                bool lineHasTransparentPixels; //set to true when the line has intentionally transparent pixels
                int numberOfPixelsInData = 0;
                for (int y = 0; y < height; y++)
                {
                    if (y < numberOfEmptyLinesAbove || y >= cutoffOffsetY + numberOfEmptyLinesAbove)
                    {
                       
                        for (int x = 0; x < width; x++)
                        {
                           bitmap.SetPixel(x, y, Color.Transparent);
                        }
                        continue;
                       
                    }
                    //Console.WriteLine("Current offset: 0x" + offset.ToString("X") + ", y: " + y);
                    while (data[offset] == 0xFF) offset++;
                    if (offset >= startOffset + (int)imageDataSize)
                    {
                        for (int i = y; i < height; i++)
                        {
                            for (int x = 0; x < width; x++)
                            {
                                bitmap.SetPixel(x, i, Color.Transparent);
                            }
                        }
                        break;
                    }
                    int transparentPixelsAmount = data[offset];
                    offset++;
                    int unknown3 = data[offset];
                    offset++;
                    lineHasTransparentPixels = false;
                   
                   
                    if (unknown3 != 0xFE && unknown3 != 0xFF)
                    {
                        lineHasTransparentPixels = true;
                        numberOfPixelsInData = unknown3;
                    }
                    else
                    {
                        numberOfPixelsInData = data[offset];
                        offset++;
                    }
                    for (int x = 0; x < width; x++)
                    {
                        while(data[offset] == 0xFF && !lineHasTransparentPixels) offset++;
                       
                        if (x < transparentPixelsAmount || x >= numberOfPixelsInData + transparentPixelsAmount)
                        {
                           bitmap.SetPixel(x, y, Color.Transparent);
                        }
                        else if (lineHasTransparentPixels && data[offset] == 0)
                        {
                           bitmap.SetPixel(x, y, Color.Transparent);
                            offset++;
                        }
                        else
                        {
                            bitmap.SetPixel(x, y, palette[data[offset]]);

                            offset++;
                        }


                    }
               
                }

                offset = startOffset + (int)imageDataSize;
                bitmaps.Add(bitmap);
                imageIndex++;
            }
            return bitmaps.ToArray();

        }
    }
}
As an example, here's all the images stored in the Worlds.spr file.
Attachments
Worlds.zip
(58.92 KiB) Downloaded 282 times
User avatar
CelestialAmber
 
Posts: 6
Joined: 22 Sep 2018, 14:59
Has thanked: 0 time
Been thanked: 9 times

Re: I managed to reverse engineer Shandalar's SPR file forma

Postby Aswan jaguar » 21 Aug 2019, 11:33

Welcome to the forums and thanks for the contribution.
---
Trying to squash some bugs and playtesting.
User avatar
Aswan jaguar
Super Tester Elite
 
Posts: 8078
Joined: 13 May 2010, 12:17
Has thanked: 730 times
Been thanked: 458 times

Re: I managed to reverse engineer Shandalar's SPR file forma

Postby CelestialAmber » 21 Aug 2019, 11:38

Thanks! :)
User avatar
CelestialAmber
 
Posts: 6
Joined: 22 Sep 2018, 14:59
Has thanked: 0 time
Been thanked: 9 times

Re: I managed to reverse engineer Shandalar's SPR file forma

Postby doenerchef » 30 Aug 2019, 19:15

This seems significant, but at the peril of sounding stupid... what does this mean?
doenerchef
 
Posts: 75
Joined: 09 Dec 2011, 15:18
Has thanked: 10 times
Been thanked: 6 times

Re: I managed to reverse engineer Shandalar's SPR file forma

Postby CelestialAmber » 31 Aug 2019, 14:47

It would allow the images in the spr files to finally be able to be extracted, assuming no other tool for them has existed before, which I tried looking for, but couldn't find any, or even any information on the file format.
Last edited by CelestialAmber on 31 Aug 2019, 14:51, edited 1 time in total.
User avatar
CelestialAmber
 
Posts: 6
Joined: 22 Sep 2018, 14:59
Has thanked: 0 time
Been thanked: 9 times

Re: I managed to reverse engineer Shandalar's SPR file forma

Postby CelestialAmber » 31 Aug 2019, 14:49

Here is a link to the tool (since the forums now allows me to post links):
https://github.com/CelestialAmber/ShandalarImageToolbox
User avatar
CelestialAmber
 
Posts: 6
Joined: 22 Sep 2018, 14:59
Has thanked: 0 time
Been thanked: 9 times

Re: I managed to reverse engineer Shandalar's SPR file forma

Postby corlock » 21 Sep 2019, 17:00

This is pretty awesome. Much appreciated! Thanks for the hard work!
corlock
 
Posts: 2
Joined: 21 Sep 2019, 16:42
Has thanked: 3 times
Been thanked: 0 time

Re: I managed to reverse engineer Shandalar's SPR file forma

Postby CelestialAmber » 15 Apr 2020, 20:03

Update: My tool now supports opening and viewing and exporting all the card art images inside of both .cat files. I also added some other general fixes and improvements.
https://github.com/CelestialAmber/Shand ... x/releases
User avatar
CelestialAmber
 
Posts: 6
Joined: 22 Sep 2018, 14:59
Has thanked: 0 time
Been thanked: 9 times

Re: I managed to reverse engineer Shandalar's SPR file forma

Postby corlock » 15 Apr 2020, 20:29

Heck yea more updates! Going to see what new features you created this evening. :D =D>
corlock
 
Posts: 2
Joined: 21 Sep 2019, 16:42
Has thanked: 3 times
Been thanked: 0 time


Return to Shandalar

Who is online

Users browsing this forum: No registered users and 24 guests


Who is online

In total there are 24 users online :: 0 registered, 0 hidden and 24 guests (based on users active over the past 10 minutes)
Most users ever online was 4143 on 23 Jan 2024, 08:21

Users browsing this forum: No registered users and 24 guests

Login Form