Page 1 of 1

Translate BASIC sprite example to C (CC65) ?

Posted: Thu Oct 19, 2023 8:10 am
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).

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

Posted: Fri Oct 20, 2023 6:09 pm
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!

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

Posted: Fri Oct 20, 2023 11:19 pm
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?

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

Posted: Sat Oct 21, 2023 9:58 am
by desertfish
use bitwise or, | , not logical or operator.

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

Posted: Sat Oct 21, 2023 11:33 am
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.

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

Posted: Sat Oct 21, 2023 3:28 pm
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).

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

Posted: Sat Oct 21, 2023 10:05 pm
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!