// 2D rotattion of 8 sprites 

import "c64"
import "fastmultiply"

byte* SCREEN = $0400;

// Sine and Cosine tables  
// Angles: $00=0, $80=PI,$100=2*PI
// Sine/Cosine: signed fixed [-$7f,$7f]
byte* COS = $2000;
byte* SIN = COS+$40; // sin(x) = cos(x+PI/2)
kickasm(pc COS) {{
    {
    .var min = -$7fff
    .var max = $7fff
    .var ampl = max-min;
    .for(var i=0;i<$140;i++) {
        .var rad = i*2*PI/256;
        .byte >round(min+(ampl/2)+(ampl/2)*cos(rad))
    }
    }
}}

void main() {
	asm { sei }
	init();
	anim();
}

void init() {
    mulf_init();	
    *SPRITES_ENABLE = %11111111;	
    byte* sprites_ptr = SCREEN+$3f8;
    for(byte i: 0..7) {
    	sprites_ptr[i] = (byte)(SPRITE/$40);
        SPRITES_COLS[i] = GREEN;
    }
}

// Positions to rotate
signed byte[8] xs = { -70, -70, -70,   0,   0,  70,  70,  70};
signed byte[8] ys = { -70,   0,  70, -70,  70, -70,   0,  70};

void anim() {
	byte angle = 0;
	while(true) {
		while(*RASTER!=$ff) {}
        (*BORDERCOL)++; 
        signed byte cos_a = (signed byte) COS[angle]; // signed fixed[0.7]
        signed byte sin_a = (signed byte) SIN[angle]; // signed fixed[0.7]
        byte sprite_msb = 0;
        for(byte i: 0..7) {             
            signed byte x = xs[i]; // signed fixed[7.0]
            signed byte y = ys[i]; // signed fixed[7.0]
            mulf8s_prepare(cos_a);
            signed word xr = mulf8s_prepared(x)<<1; // signed fixed[8.8] 
            signed word yr = mulf8s_prepared(y)<<1; // signed fixed[8.8] 
            mulf8s_prepare(sin_a);
	        xr -= mulf8s_prepared(y)<<1; // signed fixed[8.8] 
		    yr += mulf8s_prepared(x)<<1; // signed fixed[8.8] 
		    signed word xpos = ((signed byte) >xr) + 24 /*border*/ + 149 /*center*/;
            sprite_msb = sprite_msb>>1;
            if(>xpos!=0) {
                sprite_msb |= $80;
            }
            byte ypos = (>yr) + 89 /*center*/+ 51 /*border*/;  
            byte i2 = i<<1;
       	    SPRITES_XPOS[i2] = <xpos;
       	    SPRITES_YPOS[i2] = ypos;
        }
        *SPRITES_XMSB = sprite_msb;
		angle++;
		*BORDERCOL = LIGHT_BLUE;	
	}
}

// A single sprite
byte* SPRITE = $3000;
kickasm(pc SPRITE, resource "balloon.png") {{
    .var pic = LoadPicture("balloon.png", List().add($000000, $ffffff))
    .for (var y=0; y<21; y++)
        .for (var x=0;x<3; x++)
            .byte pic.getSinglecolorByte(x,y)
}}
