Important information: this site is currently scheduled to go offline indefinitely by end of the year.

Zork Nemesis/Zork Grand Inquisitor Image (TGA) Format

Get your graphics formats figures out here! Got details for others? Post here!
lordskylark
advanced
Posts: 40
Joined: Tue May 26, 2009 1:27 pm
Has thanked: 1 time

Zork Nemesis/Zork Grand Inquisitor Image (TGA) Format

Post by lordskylark »

The contents of this post was deleted because of possible forum rules violation.
User avatar
Balder
advanced
Posts: 71
Joined: Sat Jul 14, 2007 6:17 pm
Has thanked: 5 times
Been thanked: 11 times

Re: Zork Nemesis/Zork Grand Inquisitor Image (TGA) Format

Post by Balder »

I'd like to see those tga's but can't download from rapidshare/megaupload as it's blacklisted here.

If you could mirror or just attach I'll take a look.

Good night.
chrrox
Moderator
Posts: 2602
Joined: Sun May 18, 2008 3:01 pm
Has thanked: 57 times
Been thanked: 1422 times

Re: Zork Nemesis/Zork Grand Inquisitor Image (TGA) Format

Post by chrrox »

The contents of this post was deleted because of possible forum rules violation.
User avatar
Balder
advanced
Posts: 71
Joined: Sat Jul 14, 2007 6:17 pm
Has thanked: 5 times
Been thanked: 11 times

Re: Zork Nemesis/Zork Grand Inquisitor Image (TGA) Format

Post by Balder »

Thanks for the mirror, chrrox. I also think that this is some kind of compression I'm sure that's not a tga header and some experiments I did interpreting bytes like colours lead to random figures.

The signature "TGZ" at the beggining could induce to think that this is tar compression but it's structure doesn't match at all. (Nor gzip or similar ones)

If you could provide the equivalent of some of the images (TEN40S21C,... or any other) as a screenshot taken from the game in a format like png or bmp I can try to find out something. But I'm not sure I'll manage to do that. In fact, it would be enough if you know what one of those tgas represents in the game. I can take the screenshot for you (if you don't know how to do this).

For example, if we know the height and width of the image we can maybe find those value as a header in the compressed one, and width*height will give us an idea of the compression rate.

Again, I have only experience with decoding images with palette codes and don't expect a miracle.

see you guys!
chrrox
Moderator
Posts: 2602
Joined: Sun May 18, 2008 3:01 pm
Has thanked: 57 times
Been thanked: 1422 times

Re: Zork Nemesis/Zork Grand Inquisitor Image (TGA) Format

Post by chrrox »

If you upload the main game exe i can try to figure out what the compression used is.
lordskylark
advanced
Posts: 40
Joined: Tue May 26, 2009 1:27 pm
Has thanked: 1 time

Re: Zork Nemesis/Zork Grand Inquisitor Image (TGA) Format

Post by lordskylark »

I will be uploading the exe then here.

I think the largest images are extremely wide 360 panorama images. It would be hard to figure out which one goes to which scene. They would be very wide so that you can spin around in a complete 360 picture.
lordskylark
advanced
Posts: 40
Joined: Tue May 26, 2009 1:27 pm
Has thanked: 1 time

Re: Zork Nemesis/Zork Grand Inquisitor Image (TGA) Format

Post by lordskylark »

The contents of this post was deleted because of possible forum rules violation.
User avatar
Balder
advanced
Posts: 71
Joined: Sat Jul 14, 2007 6:17 pm
Has thanked: 5 times
Been thanked: 11 times

Re: Zork Nemesis/Zork Grand Inquisitor Image (TGA) Format

Post by Balder »

Great, so let's see if chrrox can reverse engineer that .exe to tell us what compression it's used :]
chrrox
Moderator
Posts: 2602
Joined: Sun May 18, 2008 3:01 pm
Has thanked: 57 times
Been thanked: 1422 times

Re: Zork Nemesis/Zork Grand Inquisitor Image (TGA) Format

Post by chrrox »

There is a compressed and uncompressed ico file in the games install directory.
I am not sure of the compression used.
here are the files attached.
You do not have the required permissions to view the files attached to this post.
lordskylark
advanced
Posts: 40
Joined: Tue May 26, 2009 1:27 pm
Has thanked: 1 time

Re: Zork Nemesis/Zork Grand Inquisitor Image (TGA) Format

Post by lordskylark »

The contents of this post was deleted because of possible forum rules violation.
lordskylark
advanced
Posts: 40
Joined: Tue May 26, 2009 1:27 pm
Has thanked: 1 time

Re: Zork Nemesis/Zork Grand Inquisitor Image (TGA) Format

Post by lordskylark »

The contents of this post was deleted because of possible forum rules violation.
Mr.Mouse
Site Admin
Posts: 4073
Joined: Wed Jan 15, 2003 6:45 pm
Location: Dungeons of Doom
Has thanked: 450 times
Been thanked: 682 times
Contact:

Re: Zork Nemesis/Zork Grand Inquisitor Image (TGA) Format

Post by Mr.Mouse »

I had to get some time, but here's the low down.

I took a look at the assembly code and found the decompress routine. I then realized that it was standard LZSS compression.

The executable uncompresses the bitmap data and fills in a BITMAPHEADER to show the actual .BMP file (not TGA). So basically, the .TGA files are Art files, with the magic word TGZ (Texture Graphics Zipped or something).

Code: Select all

Byte[4] "TGZ\0"
uint32 Original size of bitmap data
uint32 Width of image
uint32 Heigth of image
Byte[n] Bitmap data (LZSS compressed)

If I take the bitmap data and show it this is what you get for the first screen of the game (near the Temple):
3.tga.jpg
Missing colours, but it show how the executable rotates the image when needed to give the 360 degrees impression in the game. Okay, so I took another look at the executable and noticed that it filled in a .BMP header with standard values for each image, and filling up the colour table in the .BMP with 0 (the bitmap values are also the RGB values! 16 bitcounts!)

So, I recreated the header and inserted that before my uncompressed bitmap data:
3.tga_final.jpg
BINGO!

Now for coolness, let's rotate it and make it smaller to fit here:
3.tga_final_rotated.jpg
:D

Thus, I decided to make a quick and dirty tool, and wrote a quickbms script to do the uncompression, wrapping it in a small GUI: unTGZ
untgz.jpg
(oh here's the bms script : )

Code: Select all

idstring "TGZ\0"
comtype lzss
get SIZE asize
math SIZE -= 16
get UNC_SIZE long
get WIDTH long
get HEIGHT long
savepos OFFSET
get NAME filename
string NAME += ".dec"
clog NAME OFFSET SIZE UNC_SIZE
And here's unTGZ:
untgz.zip
It's usage it simple. Point to a .TGA file, click Uncompress and quickbms will bother you will questions. it will uncompress the data for you and you'll see a preview. That means you will now find a .BMP file also in that folder with the unpacked image data!

Have fun! ;)
EA20S11C.JPG
You do not have the required permissions to view the files attached to this post.
lordskylark
advanced
Posts: 40
Joined: Tue May 26, 2009 1:27 pm
Has thanked: 1 time

Re: Zork Nemesis/Zork Grand Inquisitor Image (TGA) Format

Post by lordskylark »

Amazing! I can't wait to put it to use.
lordskylark
advanced
Posts: 40
Joined: Tue May 26, 2009 1:27 pm
Has thanked: 1 time

Re: Zork Nemesis/Zork Grand Inquisitor Image (TGA) Format

Post by lordskylark »

There is a problem, and I'm not sure if it's the viewer or how the images are stored, but...

All the photos need to be rotated 180 degrees, and flipped horizontally...

This is how they all come out
You do not have the required permissions to view the files attached to this post.
Mr.Mouse
Site Admin
Posts: 4073
Joined: Wed Jan 15, 2003 6:45 pm
Location: Dungeons of Doom
Has thanked: 450 times
Been thanked: 682 times
Contact:

Re: Zork Nemesis/Zork Grand Inquisitor Image (TGA) Format

Post by Mr.Mouse »

Well, thats just a minor problem, considering the effort that was put in the work.

I think the executable rotates the imagedata. In BMP files image data is stored "upside down". I don't rotate the data, but just put it in the .BMP files. I'll see if I can change that in unTGZ when I get the time.

By the way, I'm 99% sure the programmers of Zork have used this code to achieve the decompression:

Code: Select all

/*
 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
 *
 * @APPLE_LICENSE_HEADER_START@
 * 
 * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
 * 
 * This file contains Original Code and/or Modifications of Original Code
 * as defined in and that are subject to the Apple Public Source License
 * Version 2.0 (the 'License'). You may not use this file except in
 * compliance with the License. Please obtain a copy of the License at
 * http://www.opensource.apple.com/apsl/ and read it before using this
 * file.
 * 
 * The Original Code and all software distributed under the License are
 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 * Please see the License for the specific language governing rights and
 * limitations under the License.
 * 
 * @APPLE_LICENSE_HEADER_END@
 */
/**************************************************************
 LZSS.C -- A Data Compression Program
***************************************************************
    4/6/1989 Haruhiko Okumura
    Use, distribute, and modify this program freely.
    Please send me your improved versions.
        PC-VAN      SCIENCE
        NIFTY-Serve PAF01022
        CompuServe  74050,1022

**************************************************************/
/*
 *  lzss.c - Package for decompressing lzss compressed objects
 *
 *  Copyright (c) 2003 Apple Computer, Inc.
 *
 *  DRI: Josh de Cesare
 */

#include <sl.h>

#define N         4096  /* size of ring buffer - must be power of 2 */
#define F         18    /* upper limit for match_length */
#define THRESHOLD 2     /* encode string into position and length
                           if match_length is greater than this */
#define NIL       N     /* index for root of binary search trees */

int
decompress_lzss(u_int8_t *dst, u_int8_t *src, u_int32_t srclen)
{
    /* ring buffer of size N, with extra F-1 bytes to aid string comparison */
    u_int8_t text_buf[N + F - 1];
    u_int8_t *dststart = dst;
    u_int8_t *srcend = src + srclen;
    int  i, j, k, r, c;
    unsigned int flags;
    
    dst = dststart;
    srcend = src + srclen;
    for (i = 0; i < N - F; i++)
        text_buf[i] = ' ';
    r = N - F;
    flags = 0;
    for ( ; ; ) {
        if (((flags >>= 1) & 0x100) == 0) {
            if (src < srcend) c = *src++; else break;
            flags = c | 0xFF00;  /* uses higher byte cleverly */
        }   /* to count eight */
        if (flags & 1) {
            if (src < srcend) c = *src++; else break;
            *dst++ = c;
            text_buf[r++] = c;
            r &= (N - 1);
        } else {
            if (src < srcend) i = *src++; else break;
            if (src < srcend) j = *src++; else break;
            i |= ((j & 0xF0) << 4);
            j  =  (j & 0x0F) + THRESHOLD;
            for (k = 0; k <= j; k++) {
                c = text_buf[(i + k) & (N - 1)];
                *dst++ = c;
                text_buf[r++] = c;
                r &= (N - 1);
            }
        }
    }
    
    return dst - dststart;
}
Post Reply