R
rmco2003
Guest
Awesome Tonberry, I'll check it out when I get home, as I've only got .NET on this computer. Thanks for all of your help, you'll be in the credits :wink:
Try the VB6 code first as it has less bugs. The problem you see may be with images that have a width not divisible by 4 as those images created corrupted BMPs. That's fixed with the VB6 version.There is one problem I noticed with extracting from attack information, namely it doesn't get anything from any table or image number I choose. Maybe these are the sprites without table data that you were talking about? Unless I'm remembering what you said wrong... I'd post one but I'm not sure if I'm allowed to (need confirmation halkun).
I don't think you'll have problems working with BMPs. The compatibility can be 100%, but you have to put each layer into a different BMP and you can select any color to be the mask.If BMP is a bad format to convert to for transparency, etc, then I'd gladly accept another format, I'd be using Paint Shop Pro X to edit these files, and that program can work with a large amount of file formats, so I'd go for 100% compatibility with the data rather than a common file format.
There are many possibilities for that:Also a final note, with some of the newer graphics, there is partial transparency (can't remember the exact term), sort of translucent, and the border around it completely transparent. It seems to use the same non-existant colour, I noticed this is a pure white, since the translucent colour is white. I noticed all of this when I extracted these menus and compared them to in-game screenshots.
That's a good idea. I'd even recommend you modify the program to export all the data and images at once, but that's practically a rewrite.Yes I think they are rectangular, I'm going to be coding the conversion in the morning, I'll probably make your code save things like the amount of tables and layers in one SPR file to a text file, so that it can be rebuilt properly.
That's the thing about BMPs and layers. As BMP doesn't support layers (and I didn't even know there where layers at first), you get 1 BMP for each layer.I've worked out now that the transparency is done in the second extracted layer, so it seems to be fine. One thing I'm not sure of though is when I'm making the SPR file, how would the layer thing work? In one of the files it extracts two images, the first image is the main one, and the second contains the transparencies, does this mean that they are stored as image 0, and image 1 in table 0? If this is so then it should be alright, I'm just wondering about how complicated the solution will be.
Here's a link: http://en.wikipedia.org/wiki/Windows_bitmapI've now got the code writing the file signiture, and image amount to an spr file, I've also got code for reading and writing the widths and heights but I need to know where they are written in the BMP header. I've currently got it reading 4 bytes from offset 0x48 for the width, and 4 bytes from offset 0x59 for the height for each bitmap image. It seems to store the data fine, but could you confirm that the offsets are correct please?
It's variable, but if you know the number of images that will be part of the SPR, you know the size. For each layer you have:I'm also confused about the pointers for the tables, how exactly would I implement the whole table structure? Do they have a set amount of 32 bit integers or is it variable? What is the base offset you need to multiply the half words by?
The second layer has a structure similar to the first layer:Also relating to the second table, is each image stored in a seperate table? Or is there a size limit for the amount of images in each table?
As I said above, all the layers have the same structure:You also mentioned that in some of the files the second table had an offset pointing to a group of 00's, does this mean it doesn't have anything in the second table? How can I tell what SPR files have second tables?
Be my guest.I'm trying to avoid running into size problems, where the game tries to read from the wrong location because the files haven't been padded, etc.
I'm seriously considering modifying your code to output structure information from the SPR files so that I can just read the data and transfer the BMP pixel data directly, I think it would be much easier, and safer.
Option ExplicitPrivate Const CNST_VERSION = 10 ' SPR version to compress data to. Valid: 0.5 and 10'Private Const CNST_VERSION = 0.5Private Sub Command1_Click() ' This algorithm encodes a row from an image to SPR format. ' To encode a complete image, all individual rows must be processed by this subroutine. ' Input parameters. Dim width As Long ' Image width. Dim row(0 To 319) As Long ' Row of pixels to compress. (Array from 0 to width-1.) Dim mask_color As Long ' Color used to encode the mask. ' Output parameters. Dim subblocks As Long ' Number of sub-blocks after compression. Dim compressed_row(0 To 480) As Long ' Array that holds compressed row. (Worst case: array from 0 to width*3/2) Dim compressed_x As Long ' Number of elements from 'compressed_row' that effectively hold compressed data. ' Auxiliary variables. Dim x As Long ' Column from 'row' being processed. Dim compressed As Long ' Number of consecutive pixels with mask color. Dim uncompressed As Long ' Number of consecutive pixels without mask color. Dim uncompressed_start As Long ' Used to hold the place in 'compressed_row' where the number of consecutive pixels without the mask color must be written. ' Initialization of input parameters. (For the example.) width = 320 mask_color = 0 'Put some values into the row just to test. row(10) = 8 row(11) = 9 row(12) = 8 row(55) = 7 row(57) = 7 ' Initialization. subblocks = 0 compressed_x = 0 x = 0 ' For every column... Do While x < width ' Get the number of consecutive compressed pixels. compressed = 0 Do While x < width If row(x) <> mask_color Then Exit Do End If compressed = compressed + 1 x = x + 1 Loop ' Add the number of consecutive compressed pixels to the compressed data. compressed_row(compressed_x) = compressed compressed_x = compressed_x + 1 ' Hold the position where the number of consecutive uncompressed pixels must be stored. uncompressed_start = compressed_x compressed_x = compressed_x + 1 ' Get the number of consecutive uncompressed pixels, while adding them to the compressed data. uncompressed = 0 Do While x < width If row(x) = mask_color Then Exit Do End If compressed_row(compressed_x) = row(x) ' *** TODO: Convert the pixel from 24bpp to 16bpp. compressed_x = compressed_x + 1 uncompressed = uncompressed + 1 x = x + 1 Loop ' Store the number of consecutive uncompressed pixels. compressed_row(uncompressed_start) = uncompressed ' End compressed row data depending on SPR version. Select Case CNST_VERSION Case 0.5 ' Version 0.5 simply adds last sub-block. subblocks = subblocks + 1 Case 10 ' Version 10 only adds last sub-block if it has uncompressed pixels. If (uncompressed = 0) Then compressed_x = uncompressed_start - 1 Else subblocks = subblocks + 1 End If End Select Loop ' End of subroutine. ' Show compressed data. Debug.Print subblocks For x = 0 To compressed_x - 1 Debug.Print compressed_row(x) & "; "; Next x Debug.PrintEnd Sub
[data]signature=DCSPRITE10imagecount=2[measure]width0=212height0=330width1=212height1=330[output]image0=D:\Documents and Settings\Rhys\Desktop\dr2_sub_001_0000_i0.bmpimage1=D:\Documents and Settings\Rhys\Desktop\dr2_sub_001_0000_i1.bmp
Put 3, , subblocksFor arraypos = 0 To (Width * 3 / 2) Put 3, , compressed_row(arraypos)Next arraypos
The first layer of the first image of "npc_priz_card.spr" has a compressed size of approx. 9KB. When extracted to a 24bpp BMP the size is 226KB.One of the problems is that the data is too small after compression to be realistic, think from something like 20k down to 2k, and when viewing the data there's a lot of blank space in between very small chunks of data. I'm just passing through to the files like this:
Avoid using "Put" when writing to a binary file (in this application); use the functions "Write1", "Write2" and "Write4" instead. You can find them in 'AuxFileIO.BAS'.Put 3, , subblocks
For arraypos = 0 To (Width * 3 / 2)
Put 3, , compressed_row(arraypos)
Next arraypos
Call Write2(3, subblocks)For arraypos = 0 To compressed_x - 1 Call Write2(3, compressed_row(arraypos))Next arraypos
How strange... I thought I'd put a function to do that, but it seems I forgot. Add this to 'Color.BAS': (I didn't test it.)I'm also having some trouble figuring out how to convert the pixels from 24bpp to 16bpp, your functions require quite a few different variables, and I'm assuming I have to convert it all to RGB and then to 16bpp, and visual basic won't allow me to do Function1(Function2 each being converson functions of yours.
' Convert 24bpp to 16bpp.Public Function Convert24bppTo16bpp(bpp24 As Long) As Long Dim R as Long Dim G As Long Dim B as Long Call Convert24bppToRGB(bpp24, R, G, B) Convert24bppTo16bpp = ConvertRGBTo16bpp(R, G, B)End Function
 For row = image_buffer.Height - 1 To 0 Step -1  For column = 0 To image_buffer.Width - 1   Call Read1(fh, blue)   Call Read1(fh, green)   Call Read1(fh, red)   Call mdlColor.ConvertRGBTo24bpp(image_buffer.Color(column, row), red, green, blue)  Next column
  For i = 1 To complete_row   Call Write1(fh, 0)  Next i
For row = image_buffer.Height - 1 To 0 Step -1 For column = 0 To image_buffer.Width - 1 blue = Read1(fh) green = Read1(fh) red = Read1(fh) image_buffer.Color(column, row) = mdlColor.ConvertRGBTo24bpp(red, green, blue) Next column For i = 1 To complete_row discard = Read1(fh) Next i Next row
I know it seems hard, but as I said before, it'd be better if you try to understand what the function is suposed to do and write it in your own terms. The code I wrote is simply an example and it may not do the things the way you intend them to, that's why it's important you use it simply as a guideline.I'm just replicating your function and switching things around to make it follow your instructions.
The images won't appear upside down because you started storing the first row of the BMP (the bottom row) in the last row of the image buffer. When saving the compressed rows just do the 'for' from 0 to 'height-1'.Some sudo code or something would be extremely helpful for doing all of this seeking, and need to know things like are the images going to be upside down and all of the rest of it, which I'd probably end up doing seeing as I don't know the first thing about working with files in this way.
The code above is all I've been able to do so far, I've also seen you're making a new image buffer when making a BMP so I added that code to the loop I've made to process the compression code for each image so it makes a new buffer for each image.
I'm really confused now.