Rogue-like Update: Implemented the C64 User-Defined Characters

in GAME DEV2 days ago

image.png

As you can see above, I have most of the characterset implemented in-game. There are a few I need to draw, redraw, or otherwise decide on.

Of course, all things are up to change later as I test and share for playtesting. Software plans are always fluid when faced with the reality of users!

image.png

I started by just adding the characters to RAM if the compiler was for C64, but then I pondered how to translate the map characters to the changed tiles.

This is because the map is defined using ASCII characters, for example 'g' for goblin and 'r' for rat. I wanted to keep the actual alphanumeric characters (though I did draw new bitmaps for them to make it a nice fancy font) so rather than redefine 'g' I wanted to swap it out, but only when displayed.

// Translate the character C to a selected character from the 
// new character set using a lookup table but only for c64 currently
void translate_cputcxy(int col, int row, char c) {

    // if c64 then translate the character
    #ifdef __C64__
        c = translate_char(c);
    #else
        // pass to cputcxy without changes
    #endif

    cputcxy(col, row, c);   

}

This was the first part of my solution. When the game needs to put a character at an X, Y coordinate it calls cputxy which is a conio.h function (or my function that works in its place). CC65 uses this library but I didn't want to switch it out like I do on other platforms so instead I have an intermediary function that places the character and translates if C64.

For the translation, I intended to use a lookup table, which is a high-performance option. That was right up to actually doing the table and I slacked off and used a switch statement instead. Much more human-writable and readable. I can always create a lookup table later. I'll also need to do the same thing for Atari as that also had its own PETSCII equivalent.

char translate_char(char c) {
    // Translate characters to the new character set using a switch statement
    #ifdef __C64__
    switch(c) {
        case 'h': return 'S';
        case 'i': return 'X';
        case '+': return '?'; 
        case '*': return 'Q';
        case 'k': return '%';
        case 'g': return '&';
        case 'r': return 126;
        default: return c;
    }
    #else
    return c;
    #endif
}  

When I get to the other platforms I can refactor, but for now this works.

I did discover I made a mistake. The question mark symbol is being used for the door graphic. Oops.

A really good browser-based tool for this, sprites, and PETSCII screens is petscii.krissz.hu

image.png

It even allows you to export in exactly the format I need for my char array. Fun too!

Just a little more tweaking and then I will set about creating more bad guys.

Having a variety of enemies will make a big difference to the fun and longevity of the game. Currently I have one that is random and one which attacks you.

An idea I have in mind is a "Cultist" who would try to protect the idols that are our mission to collect. It could move to try and get between the closest idol and you. Not sure if the logic might be too much for 8 bit systems, but I am going to think about it.

Sort:  

I used to spend a lot of time looking at ASCII tables. I seem to remember calculating the binary for bitmaps too. Happy days :)

did some coloring with that website you shared.
Screenshot 2025-03-09 at 1.58.27 PM.png

Screenshot 2025-03-09 at 2.00.20 PM.png

so those "sprites" in the game are just characters, that look like the thing in the game.

but you made some custom ones too? like that rat, and the night guy with the shield .

i like the quote

Software plans are always fluid when faced with the reality of users!

cant way to play test this thing! hehe

Yep essentially for the C64 (and others down the line) you can swap out the existing characterset for your own designs, like switching the font. Then when I put a @ on screen it actually is my little guy with the shield.

I just posted, you can play now in your web browser :)