Sprite and Sound APIs

Chat about anything CX16 related that doesn't fit elsewhere
rje
Posts: 1263
Joined: Mon Apr 27, 2020 10:00 pm
Location: Dallas Area

Sprite and Sound APIs

Post by rje »



7 hours ago, Ed Minchau said:




Yes, the sprite data should already be in VRAM.  The sprite attribute table at 1FC00 will point to the start location of the sprite data in VRAM.



I found @SlithyMatt's sprite tutorial on YouTube very helpful. 



Ah, does he use the KERNAL sprite routines?  (https://github.com/commanderx16/x16-docs/blob/master/Commander X16 Programmer's Reference Guide.md#function-name-sprite_set_image)

SlithyMatt
Posts: 913
Joined: Tue Apr 28, 2020 2:45 am

Sprite and Sound APIs

Post by SlithyMatt »



1 hour ago, rje said:




Ah, does he use the KERNAL sprite routines?



No, I just use direct manipulation of VRAM. The Kernal routines are limited, and not terribly useful unless you are doing something exactly like what they were written for, and the VRAM interface is really just as simple to use.

Here's the video: 





 

ZeroByte
Posts: 714
Joined: Wed Feb 10, 2021 2:40 pm

Sprite and Sound APIs

Post by ZeroByte »



12 hours ago, Snickers11001001 said:




Thanks!   Well, that's some extra maths I guess I need to work on, LOL. 



ETA:   That also seems to answer another question I had about the need for 10 bits to represent the vertical position given a 480 pixel high screen.   Thanks again! 



 



If you're using C, just use int16_t (signed) variables to hold the X and Y positions, and it works itself out.

rje
Posts: 1263
Joined: Mon Apr 27, 2020 10:00 pm
Location: Dallas Area

Sprite and Sound APIs

Post by rje »



10 hours ago, SlithyMatt said:




No, I just use direct manipulation of VRAM. The Kernal routines are limited, and not terribly useful unless you are doing something exactly like what they were written for,



That's what I thought - and thanks for that about the Kernal routines.  THAT's what I was trying to find out.

 


Quote




and the VRAM interface is really just as simple to use.



There's a VRAM interface?  OK I'll look at your tutorial.

See, I was going on the register documentation for VERA... and that is a jolly pain to work with, at least in BASIC.  VPOKEs with unfriendly bit packing.

In C, at least I can encapsulate things into a library, and from there perhaps develop assembly language routines.

My BASIC code would resemble this:

POKE $9F29,($40 OR PEEK($9F29)) :REM ENABLE SPRITES
rem ship
s0 = $fc10
x = px + 164
y = py + 164
bk = 2
ls = int(rnd(1)*8) * 32
fl = 0
po = 0 :rem pallette offset

VPOKE $F, S0+0, %00000000+ls :REM LSB
VPOKE $F, S0+1, %10000000+bk :REM R...BBBB
VPOKE $F, S0+2, X AND 255    :REM X
VPOKE $F, S0+3, X  / 256     :REM X MSB
VPOKE $F, S0+4, Y AND 255    :REM Y
VPOKE $F, S0+5, Y  / 256     :REM Y MSB
VPOKE $F, S0+6, %00001100+FL :REM coll,ZZ,FLIP
VPOKE $F, S0+7, %10100000+PO :REM HHWW..PO

ZeroByte
Posts: 714
Joined: Wed Feb 10, 2021 2:40 pm

Sprite and Sound APIs

Post by ZeroByte »


The VERA registers are the VRAM interface. The bit packing / shifting does get crazy. I just made some macros to convert between the various formats.

// Macros to convert VRAM addresses into Hi/Low Addr bytes in SPR regs.

#define SPRlo(a)    ((a)>>5  & 0xff)

#define SPRhi(a)    ((a)>>13 & 0x0f)

#define SPRadr(a)    (SPRlo(a) | SPRhi(a) << 8 )

rje
Posts: 1263
Joined: Mon Apr 27, 2020 10:00 pm
Location: Dallas Area

Sprite and Sound APIs

Post by rje »



1 hour ago, ZeroByte said:




The VERA registers are the VRAM interface. The bit packing / shifting does get crazy. I just made some macros to convert between the various formats.



// Macros to convert VRAM addresses into Hi/Low Addr bytes in SPR regs.



#define SPRlo(a)    ((a)>>5  & 0xff)

#define SPRhi(a)    ((a)>>13 & 0x0f)

#define SPRadr(a)    (SPRlo(a) | SPRhi(a) << 8 )



Heck, I was thinking about using a bitfield struct.  Macros work, too.

 

ZeroByte
Posts: 714
Joined: Wed Feb 10, 2021 2:40 pm

Sprite and Sound APIs

Post by ZeroByte »


there would be plenty of benefits to using a bitfield struct as well. Your program would be able to just use the various fields directly w/o having to bit-pack / unpack all the time. I knew my game wasn't going to require tons of performance, so I didn't bother optimizing that much for speed. I mean, I tried to be conscious of it (I couldn't help myself) but in the end, I was more concerned with doing useful abstractions / generalizations.

Scott Robison
Posts: 952
Joined: Fri Mar 19, 2021 9:06 pm

Sprite and Sound APIs

Post by Scott Robison »



37 minutes ago, ZeroByte said:




there would be plenty of benefits to using a bitfield struct as well. Your program would be able to just use the various fields directly w/o having to bit-pack / unpack all the time. I knew my game wasn't going to require tons of performance, so I didn't bother optimizing that much for speed. I mean, I tried to be conscious of it (I couldn't help myself) but in the end, I was more concerned with doing useful abstractions / generalizations.



There is a lot to be said for source code quality and convenience of using bit fields, but remember that the compiler will be doing packing and unpacking of the fields just like you would have to. That's not a reason to avoid using that feature, but it isn't likely to improve performance (assuming the same technique is used in manually written code as is used in compiler generated code).

ZeroByte
Posts: 714
Joined: Wed Feb 10, 2021 2:40 pm

Sprite and Sound APIs

Post by ZeroByte »



44 minutes ago, Scott Robison said:




There is a lot to be said for source code quality and convenience of using bit fields, but remember that the compiler will be doing packing and unpacking of the fields just like you would have to. That's not a reason to avoid using that feature, but it isn't likely to improve performance (assuming the same technique is used in manually written code as is used in compiler generated code).



This is true - the assembly that cc65 generates to reference/index into arrays and structs and so forth isn't exactly free from clutter - there're several JSRs to little routines it uses, and if your data structure isn't sized in power-of-two-sized chunks, then it gets ugly under the hood.

The most efficient data structures (as I read somewhere) are structs of arrays instead of arrays of structs - at least for 6502 targets.



But if you do a good bit of dipping into the various values of bit-packed / shifted fields, but store them as arrays of uint8_t bytes, then you potentially only have to pack them once per screen update. It depends on how your code does things, obviously.

rje
Posts: 1263
Joined: Mon Apr 27, 2020 10:00 pm
Location: Dallas Area

Sprite and Sound APIs

Post by rje »


Okay, then,

ASSUME I have to use the registers, 

THEN I'm thinking of these functions:

 

void sprite_define(
        int8_t  spritenum,
        int8_t  mode,
        int16_t block,
        int8_t  collision_mask,
        int8_t  layer,
        int8_t  height,
        int8_t  width);

void sprite_palette(
        int8_t spritenum,
        int8_t  palette_offset );

void sprite_vflip(int8_t spritenum);
void sprite_hflip(int8_t spritenum);

void sprite_move(
        int8_t spritenum,
        int16_t x,
        int16_t y);

 

Post Reply