DKC1 editor?

Share and discuss all facets of DKC ROM hacking...

DKC1 editor?

Postby rainbowsprinklez » February 26th, 2020, 1:17 pm

I'm working on a low level dkc editor... Does anybody know how to go from snes tile to image in c#? I already have an object mover. I am not interested in cameras, bananas, etc. Right now I have it so levels will break if you aren't careful. This doesn't properly order objects. This is essentially a glorified hex editor.
Veteran Venturer
Bananas received 108
Posts: 586
Joined: 2016

Re: DKC1 editor?

Postby Kingizor » February 26th, 2020, 5:02 pm

Tiles are either 2bpp, 4bpp or 8bpp (bpp = bits per plane). For 2bpp you basically have 8 pairs of bytes, so 16 bytes in all. The bits in the 1st byte would be the low bit of the resulting shade for each pixel in the top row of the resulting tile, then the 2nd byte would contain the second lowest bit. 3rd and 4th bytes would be the same for the second row, and so on. For 2bpp, you only have that one set of 16 bytes. For 4bpp, you have another 16 bytes so 32 in all, and for 8bpp you have 4x16=64.

NES does a single bit of the resulting shade in 8 bytes, then the next bit in the following 8 bytes which is a lot more natural. The SNES does it in pairs of bits and bytes because VRAM accesses are always in words. GB also does it the SNES way, but I'm not clear on the details.

Bitplanes are quite confusing and not at all easy to grasp. Some documents and explanations are exceptionally bad, which doesn't help. It finally clicked for me when I saw a diagram in a fairly old document titled "SNES Graphics Information" by a fellow called Qwertie.

Anyway, once you have the shade for a particular pixel in that 8x8 tile, you get the real colour by using the value as a lookup in the associated palette.

In some circumstances the colour isn't known, so some programs (e.g. Tile viewers) will show the shade as greyscale rather than guess a colour.

Here's a small C program that converts a few predefined tiles to greyscale images:

Spoiler!
Code: Select all
#include <stdio.h>

void snes2shade (unsigned char *tile, unsigned char *img, int depth) {
    int i,j,k;

    for (i = 0; i < 8; i++) { /* Each row */
    for (j = 0; j < 8; j++) { /* Each column */
        img[i*8+j] = 0;
        for (k = 0; k < depth/2; k++) {
            img[i*8+j] |= (((tile[i*2+k*16  ] >> (7 - j)) & 1) << (k*2  ))
                       |  (((tile[i*2+k*16+1] >> (7 - j)) & 1) << (k*2+1));
        }
    }
    }
}

/* Output a Greyscale Netpbm type image */
int output_pgm (unsigned char *img, char *name, int depth) {
    FILE *out = fopen(name, "wb");
    int i;

    if (out == NULL) {
        puts("Failed to open output file.");
        return 1;
    }

    fprintf(out, "P5\n%d %d\n%d\n", 8, 8, (1 << depth)-1);

    for (i = 0; i < 64; i++)
        fputc(img[i], out);

    fclose(out);
    return 0;
}

int main (void) {

    /* Some predefined tiles */
    unsigned char bpp2[] = {
        0x01,0x7E,0x02,0xBD,0x04,0xDB,0x08,0xE7,
        0x10,0xE7,0x20,0xDB,0x40,0xBD,0x80,0x7E
    };
    unsigned char bpp4[] = {
        0x00,0x00,0x4A,0x02,0x00,0x40,0x60,0x62,
        0x02,0x10,0x48,0x08,0x00,0x40,0x00,0x00,
        0x00,0x00,0x02,0x0A,0x00,0x10,0x22,0x02,
        0x42,0x12,0x40,0x08,0x44,0x04,0x00,0x00
    };
    unsigned char bpp8[] = {
        0x55,0x33,0x55,0x33,0x55,0x33,0x55,0x33,
        0x55,0x33,0x55,0x33,0x55,0x33,0x55,0x33,
        0x0F,0x00,0x0F,0xFF,0x0F,0x00,0x0F,0xFF,
        0x0F,0x00,0x0F,0xFF,0x0F,0x00,0x0F,0xFF,
        0x00,0x00,0x00,0x00,0xFF,0x00,0xFF,0x00,
        0x00,0xFF,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
    };

    /* A buffer to keep our image data */
    unsigned char img[64];

    snes2shade(bpp2, img, 2);
    output_pgm(img, "2bpp.pgm", 2);

    snes2shade(bpp4, img, 4);
    output_pgm(img, "4bpp.pgm", 4);

    snes2shade(bpp8, img, 8);
    output_pgm(img, "8bpp.pgm", 8);

    return 0;
}


The relevant part is the 'snes2shade' function. It's a bit tricky to look at like most image processing functions.

The tile data is passed to the function. This will either be 2bpp (16 bytes), 4bpp (32 bytes) or 8bpp (64 bytes). The "depth" variable indicates which, either 2, 4 or 8. A 64-byte buffer called "img" to store the output is also passed. 64 = 8x8. Again, if you wanted to apply a specific palette, you would use the values here as a lookup.

The calculations... We have "i" to indicate rows and "j" for columns. These apply to both the input and the output. The "k" variable does a few things relating to depth. First we extract the relevant bit from the tile data, then shift it and place it in the image.

It's not the easiest thing to explain, but maybe some of it is helpful. :dixiecry:
Trailblazer
Bananas received 77
Posts: 248
Joined: 2010

Re: DKC1 editor?

Postby rainbowsprinklez » February 26th, 2020, 11:05 pm

Thank you very much! Hey. Anything is a help when I'm looking at this https://i.imgur.com/vmIC8qi.png :facepalm:
Veteran Venturer
Bananas received 108
Posts: 586
Joined: 2016

Re: DKC1 editor?

Postby Kingizor » February 26th, 2020, 11:38 pm

Hey, don't knock fullsnes. :bleak:

But yes that is quite confusing. At first I thought that grid was referring to rows and columns, but it's referring to planes. It was enough to make me think I had made a serious miscalculation, but no it does match up somehow.

Definitely not the worst I've seen though. There is one particularly horrible bitplane document that lurks in my memory. It's almost certainly cursed, because anyone who looks at it will instantly and completely forget how any of this works, so you would have to relearn all this from scratch. It happened to me once. The best I can do is warn you about it, but if you come across it it's already too late. Just don't blindly google bitplane documentation if you can help it.

The Qwertie document I mentioned has a nice little diagram. The SNES word pairing makes it a tiny bit trickier than it could be, but it's not too bad.

The kids these days are into YouTubes and things like that, so maybe there is a really concise explanation out there that we don't know about. *o*
Trailblazer
Bananas received 77
Posts: 248
Joined: 2010

Re: DKC1 editor?

Postby rainbowsprinklez » February 27th, 2020, 1:33 am

Thanks again! I'm realizing more and more I should just keep it low-level :P It works, somewhat, there's just a lot more features to add. Yes, it is still low-level :P Glorified hex editor.
Veteran Venturer
Bananas received 108
Posts: 586
Joined: 2016

Re: DKC1 editor?

Postby Kingizor » February 27th, 2020, 4:05 am

Ahem, turns out there was at least one small bug in that code preventing it from working. I think I made a small change before I posted it that looked as though it wouldn't make any difference but it actually did. I could have sworn it was working at that point, but oh well. Should be fine now, maybe. :?

It would have made sense to test it against some known good data instead of making sure it matched my own made up data, but oh well. Guessing is more fun anyway. :krool:
Trailblazer
Bananas received 77
Posts: 248
Joined: 2010

Re: DKC1 editor?

Postby rainbowsprinklez » February 27th, 2020, 8:22 am

I agree! Hey, if it runs fine in your head, what's the issue? :P

Also, I never said this yet, but a very special thank you to Simion32. I couldn't have done this without your object list! That thing has helped me SO much. Sometimes I forget that it is thanks to you I started down this path! :banana:
Veteran Venturer
Bananas received 108
Posts: 586
Joined: 2016

Re: DKC1 editor?

Postby rainbowsprinklez » June 3rd, 2020, 10:56 am

Kingizor! I'm late by a few months in mentioning this, but this clicked for me! This https://sneslab.net/wiki/Graphics_Format#4bpp helped.

Spoiler!
Image


Phew!
Veteran Venturer
Bananas received 108
Posts: 586
Joined: 2016


Return to ROM Hacking

Who is online

Users browsing this forum: No registered users and 2 guests