How to load graphics or binara data in the cx16 various ram banks!
Would you know how to load various data (bitmaps, graphics, binary data etc) in the CX16 RAM banks? I've based a new sprite demo on the methods you've created earlier using kickasm, loading one sprite. But how can i load let's say 120 sprites in the 512KB of the CX16???
Any ideas?
Sven
// Example program for the Commander X16
// Displays 32 64*64 TUT sprites
#pragma target(cx16)
#include <cx16.h>
#include <6502.h>
#include <veralib.h>
#include <conio.h>
#include <printf.h>
const byte NUM_SPRITES = 17;
// A 64*64 8bpp TUT sprite and palette
char SPRITE_PIXELS[32+64*64*NUM_SPRITES/2] = kickasm(resource "Ship_1\ship_1_360_1.png") {{
.var pic = LoadPicture("Ship_1\ship_1_360_1.png")
// palette: rgb->idx
.var palette = Hashtable()
// RGB value for each palette index
.var palList = List()
// Next palette index
.var nxt_idx = 0;
// Extract palette while outputting pixels as palete index values
.for (var y=0; y<64; y++) {
.for (var x=0;x<64; x++) {
// Find palette index (add if not known)
.var rgb = pic.getPixel(x,y);
.var idx = palette.get(rgb)
.if(idx==null) {
.eval idx = nxt_idx++;
.eval palette.put(rgb,idx);
.eval palList.add(rgb)
}
}
}
.if(nxt_idx>16) .error "Image has too many colours "+nxt_idx
.for(var i=0;i<palList.size();i++) {
.var rgb = palList.get(i)
.var red = floor(rgb / [256*256])
.var green = floor(rgb/256) & 255
.var blue = rgb & 255
// bits 4-8: green, bits 0-3 blue
.byte green&$f0 | blue/16
// bits bits 0-3 red
.byte red/16
}
.for(var p=1;p<=NUM_SPRITES;p++) {
.var pic = LoadPicture("Ship_1\ship_1_360_" + p + ".png")
.for (var y=0; y<64; y++) {
.for (var x=0;x<64; x+=2) {
// Find palette index (add if not known)
.var rgb = pic.getPixel(x,y);
.var idx1 = palette.get(rgb)
.if(idx1==null) {
.printnow "unknown rgb value!"
}
// Find palette index (add if not known)
.eval rgb = pic.getPixel(x+1,y);
.var idx2 = palette.get(rgb)
.if(idx2==null) {
.printnow "unknown rgb value!"
}
.byte idx1*16+idx2;
}
}
}
}};
word sprite_offset = <(SPRITE_PIXELS_VRAM/32)|VERA_SPRITE_4BPP;
// Sprite attributes: 8bpp, in front, 64x64, address SPRITE_PIXELS_VRAM
struct VERA_SPRITE SPRITE_ATTR = { <(SPRITE_PIXELS_VRAM/32)|VERA_SPRITE_8BPP, 320-32, 240-32, 0x0c, 0xf1 };
word sprites[NUM_SPRITES];
// Address to use for sprite pixels in VRAM
const unsigned long SPRITE_PIXELS_VRAM = 0x00000;
void main() {
memcpy_in_vram(1, 0xF000, VERA_INC_1, 0, 0xF800, VERA_INC_1, 256*8); // We copy the 128 character set of 8 bytes each.
vera_layer_mode_tile(1, 0x14000, 0x1F000, 128, 64, 8, 8, 1);
screenlayer(1);
textcolor(WHITE);
bgcolor(BLUE);
clrscr();
printf("hello world");
// Copy sprite data to VRAM
memcpy_to_vram((char)>SPRITE_PIXELS_VRAM, <SPRITE_PIXELS_VRAM, SPRITE_PIXELS+32, 64*64*NUM_SPRITES/2);
// Copy sprite palette to VRAM
memcpy_to_vram((char)>VERA_PALETTE, <VERA_PALETTE+32, SPRITE_PIXELS, 32);
// Copy 8* sprite attributes to VRAM
char* vram_sprite_attr = <VERA_SPRITE_ATTR;
for(char s=0;s<NUM_SPRITES;s++) {
sprites[s] = sprite_offset;
SPRITE_ATTR.ADDR = sprite_offset;
SPRITE_ATTR.X += 68;
SPRITE_ATTR.Y = 100;
memcpy_to_vram((char)>VERA_SPRITE_ATTR, vram_sprite_attr, &SPRITE_ATTR, sizeof(SPRITE_ATTR));
vram_sprite_attr += sizeof(SPRITE_ATTR);
sprite_offset += 64;
}
// Enable sprites
*VERA_CTRL &= ~VERA_DCSEL;
*VERA_DC_VIDEO |= VERA_SPRITES_ENABLE;
// Enable VSYNC IRQ (also set line bit 8 to 0)
SEI();
*KERNEL_IRQ = &irq_vsync;
*VERA_IEN = VERA_VSYNC;
CLI();
}
volatile byte i = 0;
volatile byte a = 8;
// VSYNC Interrupt Routine
__interrupt(rom_sys_cx16) void irq_vsync() {
// Move the sprite around
a--;
if(a==0) {
a=8;
const char vram_sprite_attr_bank = (char)>VERA_SPRITE_ATTR;
char *vram_sprite_attr = <VERA_SPRITE_ATTR;
unsigned int i_x = 0;
unsigned int i_y = 0;
for(word s=0;s<NUM_SPRITES;s++) {
word x = s+i;
if(x>NUM_SPRITES) {
x-=NUM_SPRITES;
}
SPRITE_ATTR.ADDR = sprites[x];
SPRITE_ATTR.X = 40+(s&03)*68;
SPRITE_ATTR.Y = 100+(s>>2)*68;
// Copy sprite positions to VRAM (the 4 relevant bytes in VERA_SPRITE_ATTR)
memcpy_to_vram(vram_sprite_attr_bank, vram_sprite_attr, &SPRITE_ATTR, 6);
vram_sprite_attr += sizeof(SPRITE_ATTR);
}
i++;
if(i>NUM_SPRITES) i=0;
// Reset the VSYNC interrupt
*VERA_ISR = VERA_VSYNC;
}
}