Translate BASIC sprite example to C (CC65) ?

All aspects of programming on the Commander X16.
Post Reply
Microdriver
Posts: 14
Joined: Tue Sep 19, 2023 9:58 pm

Translate BASIC sprite example to C (CC65) ?

Post by Microdriver »

Hi,
wanted to give C with CC65 a try, and thought, "So how do you create and move sprites?"
I found this interesting code in BASIC (video-demo here):

https://github.com/SlithyMatt/x16-sprit ... sprite.bas

and thought, "What, if I translated this to C?"
But I couldn't do it (yet). Not sure, how a POKE is done correctly, and in BASIC, the VPOKE seems to take three arguments, while "vpoke()" of CC65 only takes two. So I'm not sure, if it's the corresponding thing.
So, I wonder, if maybe somebody else wants to translate the example to C (for CC65).
totodilespy
Posts: 28
Joined: Sun Nov 01, 2020 7:23 pm
Location: United States

Re: Translate BASIC sprite example to C (CC65) ?

Post by totodilespy »

vpoke() is the right C function. In cc65, the first argument is the data to poke and the second argument is the VRAM address to poke to. It is 32 bits in cc65, the lower 17 which matter. the highest bit corresponds to BASIC's VPOKE's first argument.

So BASIC:
VPOKE $1,$FC10,$00
is equivalent to C:
vpoke(0x00, 0x1FC10);

Hope this helps!
Microdriver
Posts: 14
Joined: Tue Sep 19, 2023 9:58 pm

Re: Translate BASIC sprite example to C (CC65) ?

Post by Microdriver »

Ok, that's a start. Thank you!

Now, what about this line in BASIC, which should enable sprites:

Code: Select all

POKE $9F29,($40 OR PEEK($9F29))
I'm writing it as

Code: Select all

#include <peekpoke.h>
int main() {
    ...
    /* rem enable sprites */
    POKE(0x9f29,(0x40 || PEEK(0x9f29)));
    ...
}
but that just gives me a black screen. How would you translate it?
Last edited by Microdriver on Fri Oct 20, 2023 11:26 pm, edited 1 time in total.
User avatar
desertfish
Posts: 1079
Joined: Tue Aug 25, 2020 8:27 pm
Location: Netherlands

Re: Translate BASIC sprite example to C (CC65) ?

Post by desertfish »

use bitwise or, | , not logical or operator.
Microdriver
Posts: 14
Joined: Tue Sep 19, 2023 9:58 pm

Re: Translate BASIC sprite example to C (CC65) ?

Post by Microdriver »

desertfish wrote: Sat Oct 21, 2023 9:58 amuse bitwise or, | , not logical or operator.
Hey, that's great, thank you!
I'm still not too familiar with these bitwise operations, that's something, I still should learn. So thanks for the help!
Ok, so I'm seeing a sprite now (the movement is not yet implemented):

Code: Select all

#include <cx16.h>
#include <peekpoke.h>
/* sprite.c */

typedef unsigned char byte;

byte spritedata[5][128] = { {0x00,0x00,0x00,0x77,0x77,0x00,0x00,0x00, 
0x00,0x00,0x77,0x77,0x77,0x77,0x00,0x00,
0x00,0x07,0x77,0x77,0x77,0x77,0x70,0x00,
0x00,0x77,0x77,0x77,0x77,0x77,0x77,0x00,
0x07,0x77,0x77,0x77,0x77,0x77,0x77,0x70,
0x07,0x77,0x77,0x77,0x77,0x77,0x77,0x70,
0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
0x07,0x77,0x77,0x77,0x77,0x77,0x77,0x70,
0x07,0x77,0x77,0x77,0x77,0x77,0x77,0x70,
0x00,0x77,0x77,0x77,0x77,0x77,0x77,0x00,
0x00,0x07,0x77,0x77,0x77,0x77,0x70,0x00,
0x00,0x00,0x77,0x77,0x77,0x77,0x00,0x00,
0x00,0x00,0x00,0x77,0x77,0x00,0x00,0x00} };

void setupSprite() {
    byte i;
    byte u;
    long int adresses[5] = {0x0e000};
    for (i=0;i<5;i++) {
        for (u=0;u<128;u++) {
            vpoke(spritedata[i][u], adresses[i]+u);
        }
    }
}

int main() {
    /* rem sprint frame offsets */
    byte fh[] = {0x00, 0x04, 0x08, 0x04};
    byte fv[] = {0x00, 0x0c, 0x10, 0x0c};
    byte hz = 1;
    byte cf = 0; /* current frame */
    byte x = 128;
    byte y = 128;

    /* rem enable sprites */
    POKE(0x9f29,(0x40 | PEEK(0x9f29)));

    /* rem set sprite data; */
    vpoke(0x00, 0x1fc10);
    vpoke(0x07, 0x1fc11);
    vpoke(0x80, 0x1fc12); /* xpos 128 */
    vpoke(0x00, 0x1fc13);
    vpoke(0x80, 0x1fc14); /* ypos 128 */
    vpoke(0x00, 0x1fc15);
    vpoke(0x0c, 0x1fc16); /* no collision, zdepth 3, no flip */
    vpoke(0x50, 0x1fc17); /* 16x16 pixels, palette offset 0 */

    setupSprite();
    return 0;
}
Compilation- and run-scripts

Code: Select all

#!/bin/bash
export CC65_HOME="/usr/share/cc65"
cl65 -O -t cx16 sprite.c -o TEST.PRG

Code: Select all

#!/bin/bash
x16emu -rom ~/.x16emu/rom.bin -prg TEST.PRG
Coding-Notes:
- Variables have to be declared at the top of the function (as shown).
- PEEK and POKE are written in capital letters (when using "peekpoke.h" of CC65).
- Larger arrays can't be defined inside functions. Result would be "Too many variables"-error.
- To make this forum-posting smaller, only used one of the five sprite-images. Can handle all five though.

I'm still looking for a way to free the memory of the data-array again. Right now, the "free()"-function says "Not a heap object".

Well, next stop would be dealing with the keyboard input, but just seeing the sprite is already great.
Last edited by Microdriver on Sat Oct 21, 2023 11:35 am, edited 1 time in total.
Microdriver
Posts: 14
Joined: Tue Sep 19, 2023 9:58 pm

Re: Translate BASIC sprite example to C (CC65) ?

Post by Microdriver »

I finished the translation now.
It does work, but it's not faster than in BASIC. Maybe due to slow keyboard reading, using the function "cbm_k_getin()".
If you want, I can post my code on GitHub (I'd have to add license messages and such, that's why I haven't done already).
Last edited by Microdriver on Sat Oct 21, 2023 3:28 pm, edited 1 time in total.
Microdriver
Posts: 14
Joined: Tue Sep 19, 2023 9:58 pm

Re: Translate BASIC sprite example to C (CC65) ?

Post by Microdriver »

Ok, my translation can now be found on my GitHub page.

Without the keyboard input blocking, the C-code is actually quite fast (run option "2" in the example to experience the speed). It's much faster than the corresponding BASIC code.

Have fun!
Last edited by Microdriver on Sat Oct 21, 2023 10:06 pm, edited 1 time in total.
Post Reply