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).
Translate BASIC sprite example to C (CC65) ?
-
- Posts: 14
- Joined: Tue Sep 19, 2023 9:58 pm
-
- Posts: 29
- Joined: Sun Nov 01, 2020 7:23 pm
- Location: United States
Re: Translate BASIC sprite example to C (CC65) ?
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(0x00, 0x1FC10);
Hope this helps!
So BASIC:
VPOKE $1,$FC10,$00is equivalent to C:
vpoke(0x00, 0x1FC10);
Hope this helps!
-
- Posts: 14
- Joined: Tue Sep 19, 2023 9:58 pm
Re: Translate BASIC sprite example to C (CC65) ?
Ok, that's a start. Thank you!
Now, what about this line in BASIC, which should enable sprites:
I'm writing it as
but that just gives me a black screen. How would you translate it?
Now, what about this line in BASIC, which should enable sprites:
Code: Select all
POKE $9F29,($40 OR PEEK($9F29))
Code: Select all
#include <peekpoke.h>
int main() {
...
/* rem enable sprites */
POKE(0x9f29,(0x40 || PEEK(0x9f29)));
...
}
Last edited by Microdriver on Fri Oct 20, 2023 11:26 pm, edited 1 time in total.
- desertfish
- Posts: 1096
- Joined: Tue Aug 25, 2020 8:27 pm
- Location: Netherlands
Re: Translate BASIC sprite example to C (CC65) ?
use bitwise or, | , not logical or operator.
-
- Posts: 14
- Joined: Tue Sep 19, 2023 9:58 pm
Re: Translate BASIC sprite example to C (CC65) ?
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;
}
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
- 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.
-
- Posts: 14
- Joined: Tue Sep 19, 2023 9:58 pm
Re: Translate BASIC sprite example to C (CC65) ?
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).
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.
-
- Posts: 14
- Joined: Tue Sep 19, 2023 9:58 pm
Re: Translate BASIC sprite example to C (CC65) ?
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!
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.