mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-12-22 21:29:50 +00:00
Removed some tests.
This commit is contained in:
parent
0eed4e7857
commit
a473e963d6
364
src/main/fragment/cache/fragment-cache-mos6502x.asm
vendored
364
src/main/fragment/cache/fragment-cache-mos6502x.asm
vendored
@ -19615,3 +19615,367 @@ ror {z1}
|
||||
dex
|
||||
bne !-
|
||||
!e:
|
||||
//FRAGMENT vwuz1=vwuc1_plus_vbuz2
|
||||
lda {z2}
|
||||
clc
|
||||
adc #<{c1}
|
||||
sta {z1}
|
||||
lda #>{c1}
|
||||
adc #0
|
||||
sta {z1}+1
|
||||
//FRAGMENT qbuz1_derefidx_vbuc1=pbuz2
|
||||
ldy #{c1}
|
||||
lda {z2}
|
||||
sta ({z1}),y
|
||||
iny
|
||||
lda {z2}+1
|
||||
sta ({z1}),y
|
||||
//FRAGMENT qwuz1_derefidx_vbuc1=pwuz2
|
||||
ldy #{c1}
|
||||
lda {z2}
|
||||
sta ({z1}),y
|
||||
iny
|
||||
lda {z2}+1
|
||||
sta ({z1}),y
|
||||
//FRAGMENT vwuz1=pwuz2_derefidx_vbuc1
|
||||
ldy #{c1}
|
||||
lda ({z2}),y
|
||||
sta {z1}
|
||||
iny
|
||||
lda ({z2}),y
|
||||
sta {z1}+1
|
||||
//FRAGMENT vwuz1=vwuc1_plus_vbuaa
|
||||
clc
|
||||
adc #<{c1}
|
||||
sta {z1}
|
||||
lda #>{c1}
|
||||
adc #0
|
||||
sta {z1}+1
|
||||
//FRAGMENT vwuz1=vwuc1_plus_vbuxx
|
||||
txa
|
||||
clc
|
||||
adc #<{c1}
|
||||
sta {z1}
|
||||
lda #>{c1}
|
||||
adc #0
|
||||
sta {z1}+1
|
||||
//FRAGMENT vwuz1=vwuc1_plus_vbuyy
|
||||
tya
|
||||
clc
|
||||
adc #<{c1}
|
||||
sta {z1}
|
||||
lda #>{c1}
|
||||
adc #0
|
||||
sta {z1}+1
|
||||
//FRAGMENT vbuz1_eq__deref_pbuc1_then_la1
|
||||
lda {c1}
|
||||
cmp {z1}
|
||||
beq {la1}
|
||||
//FRAGMENT _deref_pbuc1_eq_0_then_la1
|
||||
lda {c1}
|
||||
cmp #0
|
||||
beq {la1}
|
||||
//FRAGMENT vbuz1=_deref_pbuc1_rol_4
|
||||
lda {c1}
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
sta {z1}
|
||||
//FRAGMENT vbuz1=vbuz2_bor__deref_pbuc1
|
||||
lda {c1}
|
||||
ora {z2}
|
||||
sta {z1}
|
||||
//FRAGMENT vduz1=vduz2_plus_vbuz3
|
||||
lda {z3}
|
||||
clc
|
||||
adc {z2}
|
||||
sta {z1}
|
||||
lda {z2}+1
|
||||
adc #0
|
||||
sta {z1}+1
|
||||
lda {z2}+2
|
||||
adc #0
|
||||
sta {z1}+2
|
||||
lda {z2}+3
|
||||
adc #0
|
||||
sta {z1}+3
|
||||
//FRAGMENT pbuc1_derefidx_vbuz1=_dec_pbuc1_derefidx_vbuz1
|
||||
ldx {z1}
|
||||
dec {c1},x
|
||||
//FRAGMENT _deref_pbuz1=pbuc1_derefidx_(pbuc2_derefidx_vbuz2)
|
||||
ldx {z2}
|
||||
ldy {c2},x
|
||||
lda {c1},y
|
||||
ldy #0
|
||||
sta ({z1}),y
|
||||
//FRAGMENT pbuc1_derefidx_vbuz1_le_pbuc2_derefidx_vbuz1_then_la1
|
||||
ldy {z1}
|
||||
lda {c2},y
|
||||
cmp {c1},y
|
||||
bcs {la1}
|
||||
//FRAGMENT vbuz1=_deref_pbuz2_bor_vbuc1
|
||||
lda #{c1}
|
||||
ldy #0
|
||||
ora ({z2}),y
|
||||
sta {z1}
|
||||
//FRAGMENT pbuc1_derefidx_vbuz1=pbuz2_derefidx_vbuz1
|
||||
ldy {z1}
|
||||
lda ({z2}),y
|
||||
sta {c1},y
|
||||
//FRAGMENT vwuz1=vwuc1_plus_vwuz2
|
||||
clc
|
||||
lda {z2}
|
||||
adc #<{c1}
|
||||
sta {z1}
|
||||
lda {z2}+1
|
||||
adc #>{c1}
|
||||
sta {z1}+1
|
||||
//FRAGMENT vbuxx_eq__deref_pbuc1_then_la1
|
||||
cpx {c1}
|
||||
beq {la1}
|
||||
//FRAGMENT vbuaa=_deref_pbuc1_rol_4
|
||||
lda {c1}
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
//FRAGMENT vbuxx=_deref_pbuc1_rol_4
|
||||
lda {c1}
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
tax
|
||||
//FRAGMENT vbuyy=_deref_pbuc1_rol_4
|
||||
lda {c1}
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
tay
|
||||
//FRAGMENT vbuaa=vbuz1_bor__deref_pbuc1
|
||||
lda {c1}
|
||||
ora {z1}
|
||||
//FRAGMENT vbuxx=vbuz1_bor__deref_pbuc1
|
||||
lda {c1}
|
||||
ora {z1}
|
||||
tax
|
||||
//FRAGMENT vbuyy=vbuz1_bor__deref_pbuc1
|
||||
lda {c1}
|
||||
ora {z1}
|
||||
tay
|
||||
//FRAGMENT vbuz1=vbuaa_bor__deref_pbuc1
|
||||
ora {c1}
|
||||
sta {z1}
|
||||
//FRAGMENT vbuaa=vbuaa_bor__deref_pbuc1
|
||||
ora {c1}
|
||||
//FRAGMENT vbuxx=vbuaa_bor__deref_pbuc1
|
||||
ora {c1}
|
||||
tax
|
||||
//FRAGMENT vbuyy=vbuaa_bor__deref_pbuc1
|
||||
ora {c1}
|
||||
tay
|
||||
//FRAGMENT vbuz1=vbuxx_bor__deref_pbuc1
|
||||
txa
|
||||
ora {c1}
|
||||
sta {z1}
|
||||
//FRAGMENT vbuaa=vbuxx_bor__deref_pbuc1
|
||||
txa
|
||||
ora {c1}
|
||||
//FRAGMENT vbuxx=vbuxx_bor__deref_pbuc1
|
||||
txa
|
||||
ora {c1}
|
||||
tax
|
||||
//FRAGMENT vbuyy=vbuxx_bor__deref_pbuc1
|
||||
txa
|
||||
ora {c1}
|
||||
tay
|
||||
//FRAGMENT vbuz1=vbuyy_bor__deref_pbuc1
|
||||
tya
|
||||
ora {c1}
|
||||
sta {z1}
|
||||
//FRAGMENT vbuaa=vbuyy_bor__deref_pbuc1
|
||||
tya
|
||||
ora {c1}
|
||||
//FRAGMENT vbuxx=vbuyy_bor__deref_pbuc1
|
||||
tya
|
||||
ora {c1}
|
||||
tax
|
||||
//FRAGMENT vbuyy=vbuyy_bor__deref_pbuc1
|
||||
tya
|
||||
ora {c1}
|
||||
tay
|
||||
//FRAGMENT vduz1=vduz2_plus_vbuxx
|
||||
txa
|
||||
clc
|
||||
adc {z2}
|
||||
sta {z1}
|
||||
lda {z2}+1
|
||||
adc #0
|
||||
sta {z1}+1
|
||||
lda {z2}+2
|
||||
adc #0
|
||||
sta {z1}+2
|
||||
lda {z2}+3
|
||||
adc #0
|
||||
sta {z1}+3
|
||||
//FRAGMENT vduz1=vduz2_plus_vbuyy
|
||||
tya
|
||||
clc
|
||||
adc {z2}
|
||||
sta {z1}
|
||||
lda {z2}+1
|
||||
adc #0
|
||||
sta {z1}+1
|
||||
lda {z2}+2
|
||||
adc #0
|
||||
sta {z1}+2
|
||||
lda {z2}+3
|
||||
adc #0
|
||||
sta {z1}+3
|
||||
//FRAGMENT pbuz1_derefidx_vbuz2=pbuc1_derefidx_(pbuc2_derefidx_vbuaa)
|
||||
tax
|
||||
ldy {c2},x
|
||||
lda {c1},y
|
||||
ldy {z2}
|
||||
sta ({z1}),y
|
||||
//FRAGMENT pbuz1_derefidx_vbuz2=pbuc1_derefidx_(pbuc2_derefidx_vbuxx)
|
||||
ldy {c2},x
|
||||
lda {c1},y
|
||||
ldy {z2}
|
||||
sta ({z1}),y
|
||||
//FRAGMENT pbuz1_derefidx_vbuz2=pbuc1_derefidx_(pbuc2_derefidx_vbuyy)
|
||||
ldx {c2},y
|
||||
lda {c1},x
|
||||
ldy {z2}
|
||||
sta ({z1}),y
|
||||
//FRAGMENT pbuz1_derefidx_vbuaa=pbuc1_derefidx_(pbuc2_derefidx_vbuz2)
|
||||
ldy {z2}
|
||||
ldx {c2},y
|
||||
tay
|
||||
lda {c1},x
|
||||
sta ({z1}),y
|
||||
//FRAGMENT pbuz1_derefidx_vbuaa=pbuc1_derefidx_(pbuc2_derefidx_vbuaa)
|
||||
tay
|
||||
ldx {c2},y
|
||||
lda {c1},x
|
||||
sta ({z1}),y
|
||||
//FRAGMENT pbuz1_derefidx_vbuaa=pbuc1_derefidx_(pbuc2_derefidx_vbuxx)
|
||||
ldy {c2},x
|
||||
ldx {c1},y
|
||||
tay
|
||||
txa
|
||||
sta ({z1}),y
|
||||
//FRAGMENT pbuz1_derefidx_vbuaa=pbuc1_derefidx_(pbuc2_derefidx_vbuyy)
|
||||
ldx {c2},y
|
||||
tay
|
||||
lda {c1},x
|
||||
sta ({z1}),y
|
||||
//FRAGMENT pbuz1_derefidx_vbuxx=pbuc1_derefidx_(pbuc2_derefidx_vbuz2)
|
||||
ldy {z2}
|
||||
txa
|
||||
ldx {c2},y
|
||||
tay
|
||||
lda {c1},x
|
||||
sta ({z1}),y
|
||||
//FRAGMENT pbuz1_derefidx_vbuxx=pbuc1_derefidx_(pbuc2_derefidx_vbuaa)
|
||||
tay
|
||||
txa
|
||||
ldx {c2},y
|
||||
tay
|
||||
lda {c1},x
|
||||
sta ({z1}),y
|
||||
//FRAGMENT pbuz1_derefidx_vbuxx=pbuc1_derefidx_(pbuc2_derefidx_vbuxx)
|
||||
txa
|
||||
tay
|
||||
ldx {c2},y
|
||||
lda {c1},x
|
||||
sta ({z1}),y
|
||||
//FRAGMENT pbuz1_derefidx_vbuxx=pbuc1_derefidx_(pbuc2_derefidx_vbuyy)
|
||||
txa
|
||||
ldx {c2},y
|
||||
tay
|
||||
lda {c1},x
|
||||
sta ({z1}),y
|
||||
//FRAGMENT pbuz1_derefidx_vbuyy=pbuc1_derefidx_(pbuc2_derefidx_vbuz2)
|
||||
ldx {z2}
|
||||
lda {c2},x
|
||||
tax
|
||||
lda {c1},x
|
||||
sta ({z1}),y
|
||||
//FRAGMENT pbuz1_derefidx_vbuyy=pbuc1_derefidx_(pbuc2_derefidx_vbuaa)
|
||||
tax
|
||||
lda {c2},x
|
||||
tax
|
||||
lda {c1},x
|
||||
sta ({z1}),y
|
||||
//FRAGMENT pbuz1_derefidx_vbuyy=pbuc1_derefidx_(pbuc2_derefidx_vbuxx)
|
||||
lda {c2},x
|
||||
tax
|
||||
lda {c1},x
|
||||
sta ({z1}),y
|
||||
//FRAGMENT pbuz1_derefidx_vbuyy=pbuc1_derefidx_(pbuc2_derefidx_vbuyy)
|
||||
ldx {c2},y
|
||||
lda {c1},x
|
||||
sta ({z1}),y
|
||||
//FRAGMENT pbuc1_derefidx_vbuxx=_dec_pbuc1_derefidx_vbuxx
|
||||
dec {c1},x
|
||||
//FRAGMENT _deref_pbuz1=pbuc1_derefidx_(pbuc2_derefidx_vbuxx)
|
||||
ldy {c2},x
|
||||
lda {c1},y
|
||||
ldy #0
|
||||
sta ({z1}),y
|
||||
//FRAGMENT pbuc1_derefidx_vbuxx_le_pbuc2_derefidx_vbuxx_then_la1
|
||||
txa
|
||||
tay
|
||||
lda {c2},x
|
||||
cmp {c1},y
|
||||
bcs {la1}
|
||||
//FRAGMENT vbuaa=_deref_pbuz1_bor_vbuc1
|
||||
lda #{c1}
|
||||
ldy #0
|
||||
ora ({z1}),y
|
||||
//FRAGMENT vbuxx=_deref_pbuz1_bor_vbuc1
|
||||
lda #{c1}
|
||||
ldy #0
|
||||
ora ({z1}),y
|
||||
tax
|
||||
//FRAGMENT vbuyy=_deref_pbuz1_bor_vbuc1
|
||||
lda #{c1}
|
||||
ldy #0
|
||||
ora ({z1}),y
|
||||
tay
|
||||
//FRAGMENT pbuc1_derefidx_vbuaa=pbuz1_derefidx_vbuaa
|
||||
tay
|
||||
lda ({z1}),y
|
||||
sta {c1},y
|
||||
//FRAGMENT vduz1=vduz1_plus_vbuxx
|
||||
txa
|
||||
clc
|
||||
adc {z1}
|
||||
sta {z1}
|
||||
lda {z1}+1
|
||||
adc #0
|
||||
sta {z1}+1
|
||||
lda {z1}+2
|
||||
adc #0
|
||||
sta {z1}+2
|
||||
lda {z1}+3
|
||||
adc #0
|
||||
sta {z1}+3
|
||||
//FRAGMENT vwuz1=vwuz1_band_vwuc1
|
||||
lda {z1}
|
||||
and #<{c1}
|
||||
sta {z1}
|
||||
lda {z1}+1
|
||||
and #>{c1}
|
||||
sta {z1}+1
|
||||
//FRAGMENT vwuz1=vwuc1_plus_vwuz1
|
||||
clc
|
||||
lda {z1}
|
||||
adc #<{c1}
|
||||
sta {z1}
|
||||
lda {z1}+1
|
||||
adc #>{c1}
|
||||
sta {z1}+1
|
||||
|
@ -1,345 +0,0 @@
|
||||
// Clears start screen throwing around the letters (by turning them into sprites)
|
||||
#include <stdlib.h>
|
||||
#include <sqr.h>
|
||||
#include <atan2.h>
|
||||
#include <multiply.h>
|
||||
#include <c64.h>
|
||||
|
||||
// Generate debug code (raster time usage etc.)
|
||||
const bool DEBUG = false;
|
||||
|
||||
// Address of the screen
|
||||
byte* const SCREEN = 0x0400;
|
||||
// Sprite data for the animating sprites
|
||||
byte* const SPRITE_DATA = 0x2000;
|
||||
// Values added to VX
|
||||
const unsigned int VXSIN[40] = kickasm {{
|
||||
.for(var i=0; i<40; i++) {
|
||||
.word -sin(toRadians([i*360]/40))*4
|
||||
}
|
||||
}};
|
||||
|
||||
// Values added to VY
|
||||
const unsigned int VYSIN[25] = kickasm {{
|
||||
.for(var i=0; i<25; i++) {
|
||||
.word -sin(toRadians([i*360]/25))*4
|
||||
}
|
||||
}};
|
||||
|
||||
// Copy of the screen used for finding chars to process
|
||||
byte* SCREEN_COPY = malloc(1000);
|
||||
|
||||
// Screen containing bytes representing the distance to the center
|
||||
byte* SCREEN_DIST = malloc(1000);
|
||||
|
||||
// Max number of chars processed at once
|
||||
const byte NUM_PROCESSING = 8;
|
||||
|
||||
// Struct holding char being processed
|
||||
struct ProcessingChar {
|
||||
// x-position (0-39)
|
||||
char x;
|
||||
// y-position (0-24)
|
||||
char y;
|
||||
// squared distance to center (0-569)
|
||||
char dist;
|
||||
};
|
||||
|
||||
// Distance value meaning not found
|
||||
const byte NOT_FOUND = 0xff;
|
||||
|
||||
// Struct holding sprite being processed
|
||||
struct ProcessingSprite {
|
||||
// sprite x-position. Fixed point [12.4]. Values (24-336)
|
||||
unsigned int x;
|
||||
// sprite y-position. Fixed point [12.4]. Values (30-228)
|
||||
unsigned int y;
|
||||
// sprite x velocity. Fixed point [12.4]
|
||||
unsigned int vx;
|
||||
// sprite y velocity. Fixed point [12.4]
|
||||
unsigned int vy;
|
||||
// sprite ID (0-7)
|
||||
char id;
|
||||
// sprite pointer (0-255)
|
||||
char ptr;
|
||||
// sprite color
|
||||
char col;
|
||||
// status of the processing
|
||||
enum { STATUS_FREE, STATUS_NEW, STATUS_PROCESSING } status;
|
||||
// Pointer to screen char being processed (used for deletion)
|
||||
char* screenPtr;
|
||||
};
|
||||
|
||||
// Sprites currently being processed in the interrupt
|
||||
struct ProcessingSprite PROCESSING[NUM_PROCESSING];
|
||||
|
||||
void main() {
|
||||
// Initialize the screen containing distance to the center
|
||||
init_angle_screen(SCREEN_DIST);
|
||||
// Copy screen to screen copy
|
||||
for( char *src=SCREEN, *dst=SCREEN_COPY; src!=SCREEN+1000; src++, dst++) *dst = *src;
|
||||
// Init processing array
|
||||
for( char i: 0..NUM_PROCESSING-1 ) PROCESSING[i] = { 0, 0, 0, 0, 0, 0, 0, STATUS_FREE, 0};
|
||||
// Init sprites
|
||||
initSprites();
|
||||
// Set-up raster interrupts
|
||||
setupRasterIrq(RASTER_IRQ_TOP, &irqTop);
|
||||
// Main loop
|
||||
do {
|
||||
// Look for the non-space closest to the screen center
|
||||
struct ProcessingChar center = getCharToProcess();
|
||||
if(center.dist==NOT_FOUND)
|
||||
break;
|
||||
startProcessing(center);
|
||||
} while(true);
|
||||
(*(SCREEN+999)) = '.';
|
||||
do {
|
||||
(*(COLS+999))++;
|
||||
} while (true);
|
||||
}
|
||||
|
||||
// Find the non-space char closest to the center of the screen
|
||||
// If no non-space char is found the distance will be 0xffff
|
||||
struct ProcessingChar getCharToProcess() {
|
||||
struct ProcessingChar closest = { 0, 0, NOT_FOUND };
|
||||
char* screen_line = SCREEN_COPY;
|
||||
char* dist_line = SCREEN_DIST;
|
||||
for( char y: 0..24) {
|
||||
for( char x: 0..39) {
|
||||
if(screen_line[x]!=' ') {
|
||||
char dist = dist_line[x];
|
||||
if(dist<closest.dist) {
|
||||
// Update closest char
|
||||
closest = { x, y, dist };
|
||||
}
|
||||
}
|
||||
}
|
||||
screen_line += 40;
|
||||
dist_line += 40;
|
||||
}
|
||||
if(closest.dist != NOT_FOUND) {
|
||||
// clear the found char on the screen copy
|
||||
*(SCREEN_COPY+(unsigned int)closest.y*40+closest.x) = ' ';
|
||||
}
|
||||
return closest;
|
||||
}
|
||||
|
||||
// Start processing a char - by inserting it into the PROCESSING array
|
||||
void startProcessing(struct ProcessingChar center) {
|
||||
// Busy-wait while finding an empty slot in the PROCESSING array
|
||||
char freeIdx = 0xff;
|
||||
do {
|
||||
for( char i: 0..NUM_PROCESSING-1 ) {
|
||||
if(PROCESSING[i].status==STATUS_FREE) {
|
||||
freeIdx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (freeIdx==0xff);
|
||||
// Found a free sprite
|
||||
char spriteIdx = freeIdx;
|
||||
// Copy char into sprite
|
||||
unsigned int offset = (unsigned int)center.y*40+center.x;
|
||||
char* colPtr = COLS+offset;
|
||||
char spriteCol = *colPtr;
|
||||
char* screenPtr = SCREEN+offset;
|
||||
char* spriteData = SPRITE_DATA+(unsigned int)spriteIdx*64;
|
||||
char ch = (*screenPtr);
|
||||
char* chargenData = CHARGEN+(unsigned int)ch*8;
|
||||
asm { sei }
|
||||
*PROCPORT = PROCPORT_RAM_CHARROM;
|
||||
for( char i: 0..7) {
|
||||
*spriteData = *chargenData;
|
||||
spriteData += 3;
|
||||
chargenData++;
|
||||
}
|
||||
*PROCPORT = PROCPORT_RAM_IO;
|
||||
asm { cli }
|
||||
unsigned int spriteX = (BORDER_XPOS_LEFT + (unsigned int)center.x*8) << 4;
|
||||
unsigned int spriteY = (BORDER_YPOS_TOP + (unsigned int)center.y*8) << 4;
|
||||
char spritePtr = (char)(SPRITE_DATA/64)+spriteIdx;
|
||||
// Put the sprite into the PROCESSING array
|
||||
PROCESSING[spriteIdx] = { spriteX, spriteY, (unsigned int)(spriteIdx*8), 60, spriteIdx, spritePtr, spriteCol, STATUS_NEW, screenPtr };
|
||||
}
|
||||
|
||||
const unsigned int XPOS_LEFTMOST = (unsigned int)(BORDER_XPOS_LEFT-8)<<4;
|
||||
const unsigned int XPOS_RIGHTMOST = (unsigned int)(BORDER_XPOS_RIGHT)<<4;
|
||||
const unsigned int YPOS_TOPMOST = (unsigned int)(BORDER_YPOS_TOP-8)<<4;
|
||||
const unsigned int YPOS_BOTTOMMOST = (unsigned int)(BORDER_YPOS_BOTTOM)<<4;
|
||||
|
||||
|
||||
// Process any chars in the PROCESSING array
|
||||
void processChars() {
|
||||
char numActive = 0;
|
||||
for( char i: 0..NUM_PROCESSING-1 ) {
|
||||
struct ProcessingSprite* processing = PROCESSING+i;
|
||||
char bitmask = 1<<processing->id;
|
||||
if(processing->status!=STATUS_FREE) {
|
||||
if(processing->status==STATUS_NEW) {
|
||||
// Clear the char on the screen
|
||||
*(processing->screenPtr) = ' ';
|
||||
// Enable the sprite
|
||||
*SPRITES_ENABLE |= bitmask;
|
||||
// Set the sprite color
|
||||
SPRITES_COLOR[processing->id] = processing->col;
|
||||
// Set sprite pointer
|
||||
*(SCREEN+OFFSET_SPRITE_PTRS+processing->id) = processing->ptr;
|
||||
// Set status
|
||||
processing->status = STATUS_PROCESSING;
|
||||
}
|
||||
unsigned int xpos = processing->x >> 4;
|
||||
// Set sprite position
|
||||
if(>xpos) {
|
||||
*SPRITES_XMSB |= bitmask;
|
||||
} else {
|
||||
*SPRITES_XMSB &= 0xff ^ bitmask;
|
||||
}
|
||||
SPRITES_XPOS[i*2] = (char)xpos;
|
||||
char ypos = (char)(processing->y>>4);
|
||||
SPRITES_YPOS[i*2] = ypos;
|
||||
|
||||
// Move sprite
|
||||
if(processing->x < XPOS_LEFTMOST || processing->x > XPOS_RIGHTMOST || processing->y < YPOS_TOPMOST|| processing->y > YPOS_BOTTOMMOST ) {
|
||||
// Set status to FREE
|
||||
processing->status = STATUS_FREE;
|
||||
// Disable the sprite
|
||||
*SPRITES_ENABLE &= 0xff ^ bitmask;
|
||||
} else {
|
||||
char xchar = (char)(xpos/8) - BORDER_XPOS_LEFT/8;
|
||||
processing->vx += VXSIN[xchar];
|
||||
processing->x += processing->vx;
|
||||
char ychar = (char)(ypos/8) - BORDER_YPOS_TOP/8;
|
||||
processing->vy += VYSIN[ychar];
|
||||
processing->y += processing->vy;
|
||||
}
|
||||
numActive++;
|
||||
}
|
||||
}
|
||||
if(DEBUG) {
|
||||
*(SCREEN+999) = '0'+numActive;
|
||||
}
|
||||
}
|
||||
|
||||
// Populates 1000 chars (a screen) with values representing the distance to the center.
|
||||
// The actual value stored is distance*2 to increase precision
|
||||
void init_dist_screen(char* screen) {
|
||||
NUM_SQUARES = 0x30;
|
||||
init_squares();
|
||||
char* screen_topline = screen;
|
||||
char *screen_bottomline = screen+40*24;
|
||||
for(char y: 0..12) {
|
||||
char y2 = y*2;
|
||||
char yd = (y2>=24)?(y2-24):(24-y2);
|
||||
unsigned int yds = sqr(yd);
|
||||
for( char x=0,xb=39; x<=19; x++, xb--) {
|
||||
char x2 = x*2;
|
||||
char xd = (x2>=39)?(x2-39):(39-x2);
|
||||
unsigned int xds = sqr(xd);
|
||||
unsigned int ds = xds+yds;
|
||||
char d = sqrt(ds);
|
||||
screen_topline[x] = d;
|
||||
screen_bottomline[x] = d;
|
||||
screen_topline[xb] = d;
|
||||
screen_bottomline[xb] = d;
|
||||
}
|
||||
screen_topline += 40;
|
||||
screen_bottomline -= 40;
|
||||
}
|
||||
}
|
||||
|
||||
// Populates 1000 chars (a screen) with values representing the angle to the center.
|
||||
// Utilizes symmetry around the center
|
||||
void init_angle_screen(char* screen) {
|
||||
char* screen_topline = screen+40*12;
|
||||
char *screen_bottomline = screen+40*12;
|
||||
for(char y: 0..12) {
|
||||
for( char x=0,xb=39; x<=19; x++, xb--) {
|
||||
signed int xw = (signed int)(unsigned int){ 39-x*2, 0 };
|
||||
signed int yw = (signed int)(unsigned int){ y*2, 0 };
|
||||
unsigned int angle_w = atan2_16(xw, yw);
|
||||
char ang_w = >(angle_w+0x0080);
|
||||
screen_bottomline[xb] = ang_w;
|
||||
screen_topline[xb] = -ang_w;
|
||||
screen_topline[x] = 0x80+ang_w;
|
||||
screen_bottomline[x] = 0x80-ang_w;
|
||||
}
|
||||
screen_topline -= 40;
|
||||
screen_bottomline += 40;
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize sprites
|
||||
void initSprites() {
|
||||
// Clear sprite data
|
||||
for( char* sp = SPRITE_DATA; sp<SPRITE_DATA+NUM_PROCESSING*64; sp++) *sp = 0;
|
||||
// Initialize sprite registers
|
||||
for( char i: 0..7) {
|
||||
SPRITES_COLOR[i] = LIGHT_BLUE;
|
||||
}
|
||||
*SPRITES_MC = 0;
|
||||
*SPRITES_EXPAND_X = 0;
|
||||
*SPRITES_EXPAND_Y = 0;
|
||||
}
|
||||
|
||||
// Setup Raster IRQ
|
||||
void setupRasterIrq(unsigned int raster, void()* irqRoutine) {
|
||||
asm { sei }
|
||||
// Disable kernal & basic
|
||||
*PROCPORT_DDR = PROCPORT_DDR_MEMORY_MASK;
|
||||
*PROCPORT = PROCPORT_RAM_IO;
|
||||
// Disable CIA 1 Timer IRQ
|
||||
CIA1->INTERRUPT = CIA_INTERRUPT_CLEAR;
|
||||
if(raster<0x100) {
|
||||
*VICII_CONTROL &=0x7f;
|
||||
} else {
|
||||
*VICII_CONTROL |=0x80;
|
||||
}
|
||||
*RASTER = <raster;
|
||||
// Enable Raster Interrupt
|
||||
*IRQ_ENABLE = IRQ_RASTER;
|
||||
// Set the IRQ routine
|
||||
*HARDWARE_IRQ = irqRoutine;
|
||||
asm { cli }
|
||||
}
|
||||
|
||||
const char RASTER_IRQ_TOP = 0x30;
|
||||
|
||||
// Raster Interrupt at the top of the screen
|
||||
__interrupt(hardware_clobber) void irqTop() {
|
||||
if(DEBUG) {
|
||||
for( char i: 0..4) {}
|
||||
*BORDER_COLOR = WHITE;
|
||||
*BG_COLOR = WHITE;
|
||||
for( char i: 0..7) {}
|
||||
*BORDER_COLOR = LIGHT_BLUE;
|
||||
*BG_COLOR = BLUE;
|
||||
}
|
||||
|
||||
// Trigger IRQ at the middle of the screen
|
||||
*RASTER = RASTER_IRQ_MIDDLE;
|
||||
*HARDWARE_IRQ = &irqBottom;
|
||||
// Acknowledge the IRQ
|
||||
*IRQ_STATUS = IRQ_RASTER;
|
||||
}
|
||||
|
||||
const char RASTER_IRQ_MIDDLE = 0xff;
|
||||
|
||||
// Raster Interrupt at the bottom of the screen
|
||||
__interrupt(hardware_clobber) void irqBottom() {
|
||||
if(DEBUG) {
|
||||
for( char i: 0..4) {}
|
||||
*BORDER_COLOR = WHITE;
|
||||
*BG_COLOR = WHITE;
|
||||
}
|
||||
processChars();
|
||||
if(DEBUG) {
|
||||
*BORDER_COLOR = LIGHT_BLUE;
|
||||
*BG_COLOR = BLUE;
|
||||
}
|
||||
|
||||
// Trigger IRQ at the top of the screen
|
||||
*RASTER = RASTER_IRQ_TOP;
|
||||
*HARDWARE_IRQ = &irqTop;
|
||||
// Acknowledge the IRQ
|
||||
*IRQ_STATUS = IRQ_RASTER;
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
// Chunky DYPP with arbitrary sine
|
||||
// First implemented as dyppa.asm in 2011
|
||||
|
||||
#pragma emulator("C64Debugger")
|
||||
|
||||
#include <c64.h>
|
||||
#include <string.h>
|
||||
|
||||
// The DYPPA charset containing the sloped offset characters
|
||||
char __address(0x2000) DYPPA_CHARSET[0x0800] = kickasm(resource "dyppacharset.bin") {{
|
||||
.var dyppaFile = LoadBinary("dyppacharset.bin", "Charset=$000,Tables=$800")
|
||||
.fill dyppaFile.getCharsetSize(), dyppaFile.getCharset(i)
|
||||
}};
|
||||
|
||||
// The DYPPA tables mapping the slopes, offsets and pixels to the right character in the charset
|
||||
// for(offset:0..7) for(slope:0..f) for(pixels: 0..f) glyph_id(offset,slope,pixels)
|
||||
char __align(0x100) DYPPA_TABLE[0x0800] = kickasm(resource "dyppacharset.bin") {{
|
||||
.var dyppaFile2 = LoadBinary("dyppacharset.bin", "Charset=$000,Tables=$800")
|
||||
.fill dyppaFile2.getTablesSize(), dyppaFile2.getTables(i)
|
||||
}};
|
||||
|
||||
void main() {
|
||||
VICII->MEMORY = toD018(DEFAULT_SCREEN, DYPPA_CHARSET);
|
||||
memset(DEFAULT_SCREEN, DYPPA_TABLE[0], 1000);
|
||||
|
||||
for(;;) {
|
||||
(*(DEFAULT_SCREEN+999))++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
Binary file not shown.
@ -1,136 +0,0 @@
|
||||
// Quadratic Spline Library
|
||||
// Implements an iterative algorithm using only addition for calculating quadratic splines
|
||||
//
|
||||
// A quadratic spline is a curve defined by 3 points: P0, P1 and P2.
|
||||
// The curve connects P0 to P2 through a smooth curve that moves towards P1, but does usually not touch it.
|
||||
//
|
||||
// The general formula for the quadratic spline is as follows:
|
||||
// A = P2 - 2*P1 + P0
|
||||
// B = 2*P1 - 2*P0
|
||||
// C = P0
|
||||
// P(t) = A*t*t + B*t + C
|
||||
// for 0 <= t <= 1
|
||||
//
|
||||
// This library implements a iterative algorithm using multiplications in the initialization and only additions for calculating each point on the spline.
|
||||
// The iterative algorithm is based on the following:
|
||||
// P(t+Dt) = P(t) + A*Dt*Dt + 2*A*t*Dt + B*Dt
|
||||
//
|
||||
// init:
|
||||
// N = 16 (number of plots)
|
||||
// Dt = 1/N
|
||||
// P = C
|
||||
// I = A*Dt*Dt + B*Dt
|
||||
// J = 2*A*Dt*Dt
|
||||
// loop(N times):
|
||||
// plot(P)
|
||||
// P = P + I
|
||||
// I = I + J
|
||||
// When N=16 then Dt[0.16] = $0.1000 Dt^2[0.16] = $0.0100
|
||||
// When N=8 then Dt[0.16] = $0.2000 Dt^2[0.16] = $0.0400
|
||||
|
||||
// Vector with 16-coordinates that is part of a spline
|
||||
struct SplineVector16 {
|
||||
// x-position s[16.0]
|
||||
signed int x;
|
||||
// y-position s[16.0]
|
||||
signed int y;
|
||||
};
|
||||
|
||||
// Vector with 32-bit coordinates that is part of a spline
|
||||
struct SplineVector32 {
|
||||
// x-position s[16.16]
|
||||
signed long x;
|
||||
// y-position s[16.16]
|
||||
signed long y;
|
||||
};
|
||||
|
||||
// Array filled with spline segment points by splinePlot_16()
|
||||
struct SplineVector16 SPLINE_16SEG[17];
|
||||
|
||||
// Generate a 16-segment quadratic spline using 32-bit fixed point 1/$10000-format math 16 decimal bits).
|
||||
// This function can handle all signed int values in the points.
|
||||
// The resulting spline segment points are returned in SPLINE_16SEG[]
|
||||
// A quadratic spline is a curve defined by 3 points: P0, P1 and P2.
|
||||
// The curve connects P0 to P2 through a smooth curve that moves towards P1, but does usually not touch it.
|
||||
void spline_16seg(struct SplineVector16 p0, struct SplineVector16 p1, struct SplineVector16 p2) {
|
||||
// A = P2 - 2*P1 + P0
|
||||
struct SplineVector16 a = { p2.x - p1.x*2 + p0.x, p2.y - p1.y*2 + p0.y};
|
||||
// B = 2*P1 - 2*P0
|
||||
struct SplineVector16 b = { (p1.x - p0.x)*2, (p1.y - p0.y)*2 };
|
||||
// I = A*Dt*Dt + B*Dt - Fixed point s[16.16]
|
||||
// Dt = 1/16 and Dt*Dt=1/256 - we can multiply using only bitshifts
|
||||
struct SplineVector32 i = { (signed long)a.x*0x100 + (signed long)b.x*0x100*0x10, (signed long)a.y*0x100 + (signed long)b.y*0x100*0x10 };
|
||||
// J = 2*A*Dt*Dt - Fixed point s[16.16]
|
||||
// Dt = 1/16 and Dt*Dt=1/256 - we can multiply using only bitshifts
|
||||
struct SplineVector32 j = { (signed long)a.x*0x100*2, (signed long)a.y*0x100*2 };
|
||||
// P = P0 - Fixed point s[16.16]
|
||||
struct SplineVector32 p = { (signed long)p0.x*0x10000, (signed long)p0.y*0x10000 };
|
||||
for( char n: 0..15) {
|
||||
SPLINE_16SEG[n] = { (signed word)>(p.x+0x8000), (signed word)>(p.y+0x8000) };
|
||||
// P = P + I;
|
||||
p = { p.x+i.x, p.y+i.y };
|
||||
// I = I + J;
|
||||
i = { i.x+j.x, i.y+j.y };
|
||||
}
|
||||
SPLINE_16SEG[16] = { (signed word)>(p.x+0x8000), (signed word)>(p.y+0x8000) };
|
||||
}
|
||||
|
||||
// Array filled with spline segment points by splinePlot_8()
|
||||
struct SplineVector16 SPLINE_8SEG[9];
|
||||
|
||||
// Generate a 8-segment quadratic spline using 32-bit fixed point 1/$10000-format math 16 decimal bits).
|
||||
// The resulting spline segment points are returned in SPLINE_8SEG[]
|
||||
// This function can handle all signed int values in the points.
|
||||
// A quadratic spline is a curve defined by 3 points: P0, P1 and P2.
|
||||
// The curve connects P0 to P2 through a smooth curve that moves towards P1, but does usually not touch it.
|
||||
void spline_8seg(struct SplineVector16 p0, struct SplineVector16 p1, struct SplineVector16 p2) {
|
||||
// A = P2 - 2*P1 + P0
|
||||
struct SplineVector16 a = { p2.x - p1.x*2 + p0.x, p2.y - p1.y*2 + p0.y};
|
||||
// B = 2*P1 - 2*P0
|
||||
struct SplineVector16 b = { (p1.x - p0.x)*2, (p1.y - p0.y)*2 };
|
||||
// I = A*Dt*Dt + B*Dt - Fixed point s[16.16]
|
||||
// Dt = 1/8 and Dt*Dt=1/64 - we can multiply using only bitshifts
|
||||
struct SplineVector32 i = { (signed long)a.x*0x100*0x4 + (signed long)b.x*0x100*0x20, (signed long)a.y*0x100*0x4 + (signed long)b.y*0x100*0x20 };
|
||||
// J = 2*A*Dt*Dt - Fixed point s[16.16]
|
||||
// Dt = 1/8 and Dt*Dt=1/64 - we can multiply using only bitshifts
|
||||
struct SplineVector32 j = { (signed long)a.x*0x100*0x8, (signed long)a.y*0x100*0x8 };
|
||||
// P = P0 - Fixed point s[16.16]
|
||||
struct SplineVector32 p = { (signed long)p0.x*0x10000, (signed long)p0.y*0x10000 };
|
||||
for( char n: 0..7) {
|
||||
SPLINE_8SEG[n] = { (signed word)>(p.x+0x8000), (signed word)>(p.y+0x8000) };
|
||||
// P = P + I;
|
||||
p = { p.x+i.x, p.y+i.y };
|
||||
// I = I + J;
|
||||
i = { i.x+j.x, i.y+j.y };
|
||||
}
|
||||
SPLINE_8SEG[8] = { (signed word)>(p.x+0x8000), (signed word)>(p.y+0x8000) };
|
||||
}
|
||||
|
||||
// Generate a 8-segment quadratic spline using 16-bit fixed point 1/64-format math (6 decimal bits).
|
||||
// The resulting spline segment points are returned in SPLINE_8SEG[]
|
||||
// Point values must be within [-200 ; 1ff] for the calculation to not overflow.
|
||||
// A quadratic spline is a curve defined by 3 points: P0, P1 and P2.
|
||||
// The curve connects P0 to P2 through a smooth curve that moves towards P1, but does usually not touch it.
|
||||
void spline_8segB(struct SplineVector16 p0, struct SplineVector16 p1, struct SplineVector16 p2) {
|
||||
// A = P2 - 2*P1 + P0
|
||||
struct SplineVector16 a = { p2.x - p1.x*2 + p0.x, p2.y - p1.y*2 + p0.y};
|
||||
// B = 2*P1 - 2*P0
|
||||
struct SplineVector16 b = { (p1.x - p0.x)*2, (p1.y - p0.y)*2 };
|
||||
// I = A*Dt*Dt + B*Dt - I is in fixed point 1/64-format (6 decimal bits) [-200 ; 1ff]
|
||||
// Dt = 1/8 and Dt*Dt=1/64 - we can multiply using only bitshifts. Dt*Dt is exactly==1 in the fixed point format.
|
||||
struct SplineVector16 i = { a.x + b.x*8, a.y + b.y*8};
|
||||
// J = 2*A*Dt*Dt - J is in fixed point 1/64-format (6 decimal bits) [-200 ; 1ff]
|
||||
// Dt = 1/8 and Dt*Dt=1/64 - we can multiply using only bitshifts. Dt*Dt is exactly==1 in the fixed point format.
|
||||
struct SplineVector16 j = { a.x*2, a.y*2 };
|
||||
// P = P0 - P is in fixed point 1/64-format (6 decimal bits) [-200 ; 1ff]
|
||||
struct SplineVector16 p = { p0.x*0x40, p0.y*0x40 };
|
||||
for( char n: 0..7) {
|
||||
// Get the rounded result
|
||||
SPLINE_8SEG[n] = { (p.x+0x20)/0x40, (p.y+0x20)/0x40 };
|
||||
// P = P + I;
|
||||
p = { p.x+i.x, p.y+i.y };
|
||||
// I = I + J;
|
||||
i = { i.x+j.x, i.y+j.y };
|
||||
}
|
||||
SPLINE_8SEG[8] = { (p.x+0x20)/0x40, (p.y+0x20)/0x40 };
|
||||
}
|
@ -1,128 +0,0 @@
|
||||
// Show a few simple splines using the splines library
|
||||
|
||||
#include "splines.c"
|
||||
#include <bitmap2.h>
|
||||
#include <time.h>
|
||||
#include <print.h>
|
||||
#include <fastmultiply.h>
|
||||
#include <c64.h>
|
||||
|
||||
char* const PRINT_SCREEN = 0x0400;
|
||||
char* const BITMAP_SCREEN = 0x5c00;
|
||||
char* const BITMAP_GRAPHICS = 0x6000;
|
||||
|
||||
// A segment of a spline
|
||||
struct Segment {
|
||||
enum SegmentType { MOVE_TO, SPLINE_TO, LINE_TO} type;
|
||||
struct SplineVector16 to;
|
||||
struct SplineVector16 via;
|
||||
};
|
||||
|
||||
// True type letter c
|
||||
struct Segment letter_c[22] = {
|
||||
{ MOVE_TO, {108,146}, {0,0} },
|
||||
{ SPLINE_TO, {89,182}, {103,169} },
|
||||
{ SPLINE_TO, {59,195}, {75,195} },
|
||||
{ SPLINE_TO, {23,178}, {38,195} },
|
||||
{ SPLINE_TO, {9,132}, {9,161} },
|
||||
{ SPLINE_TO, {25,87}, {9,104} },
|
||||
{ SPLINE_TO, {65,69}, {42,69} },
|
||||
{ SPLINE_TO, {93,79}, {82,69} },
|
||||
{ SPLINE_TO, {105,98}, {105,88} },
|
||||
{ SPLINE_TO, {102,106}, {105,103} },
|
||||
{ SPLINE_TO, {93,109}, {98,109} },
|
||||
{ SPLINE_TO, {81,104}, {85,109} },
|
||||
{ SPLINE_TO, {78,93}, {79,101} },
|
||||
{ SPLINE_TO, {73,82}, {78,86} },
|
||||
{ SPLINE_TO, {61,78}, {69,78} },
|
||||
{ SPLINE_TO, {40,88}, {48,78} },
|
||||
{ SPLINE_TO, {29,121}, {29,100} },
|
||||
{ SPLINE_TO, {40,158}, {29,142} },
|
||||
{ SPLINE_TO, {68,174}, {50,174} },
|
||||
{ SPLINE_TO, {91,166}, {80,174} },
|
||||
{ SPLINE_TO, {104,144}, {98,160} },
|
||||
{ LINE_TO, {108,146}, {0,0} }
|
||||
};
|
||||
|
||||
void main() {
|
||||
mulf_init();
|
||||
bitmap_init(BITMAP_GRAPHICS, BITMAP_SCREEN);
|
||||
bitmap_clear(BLACK, WHITE);
|
||||
vicSelectGfxBank(BITMAP_SCREEN);
|
||||
*D018 = toD018(BITMAP_SCREEN, BITMAP_GRAPHICS);
|
||||
*D011 = VICII_BMM|VICII_DEN|VICII_RSEL|3;
|
||||
|
||||
char angle = 0;
|
||||
while(true) {
|
||||
bitmap_clear(BLACK, WHITE);
|
||||
show_letter(angle);
|
||||
for ( byte w: 0..60) {
|
||||
do {} while(*RASTER!=0xfe);
|
||||
do {} while(*RASTER!=0xff);
|
||||
}
|
||||
angle += 9;
|
||||
}
|
||||
|
||||
while(true) { (*(PRINT_SCREEN+999))++; }
|
||||
}
|
||||
|
||||
void show_letter(char angle) {
|
||||
struct SplineVector16 current = {0,0};
|
||||
for( byte i: 0..21) {
|
||||
struct SplineVector16 to = letter_c[i].to;
|
||||
to = { to.x - 50, to.y - 150};
|
||||
to = rotate(to, angle);
|
||||
to = { to.x + 100, to.y + 100};
|
||||
struct SplineVector16 via = letter_c[i].via;
|
||||
via = { via.x - 50, via.y - 150};
|
||||
via = rotate(via, angle);
|
||||
via = { via.x + 100, via.y + 100};
|
||||
struct Segment segment = { letter_c[i].type, to, via};
|
||||
if(segment.type==MOVE_TO) {
|
||||
//bitmap_plot((unsigned int)segment.to.x, (unsigned char)segment.to.y);
|
||||
current = segment.to;
|
||||
} else if(segment.type==SPLINE_TO) {
|
||||
spline_8segB(current, segment.via, segment.to);
|
||||
bitmap_plot_spline_8seg();
|
||||
//bitmap_plot((unsigned int)segment.to.x, (unsigned char)segment.to.y);
|
||||
//bitmap_plot((unsigned int)segment.via.x, (unsigned char)segment.via.y);
|
||||
current = segment.to;
|
||||
} else {
|
||||
bitmap_line((unsigned int)current.x, (unsigned int)current.y, (unsigned int)segment.to.x, (unsigned int)segment.to.y);
|
||||
current = segment.to;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Plot the spline in the SPLINE_8SEG array
|
||||
void bitmap_plot_spline_8seg() {
|
||||
struct SplineVector16 current = SPLINE_8SEG[0];
|
||||
for(char n:1..8) {
|
||||
bitmap_line((unsigned int)current.x, (unsigned int)current.y, (unsigned int)SPLINE_8SEG[n].x, (unsigned int)SPLINE_8SEG[n].y);
|
||||
//bitmap_plot((unsigned int)current.x, (unsigned char)current.y);
|
||||
current = SPLINE_8SEG[n];
|
||||
}
|
||||
}
|
||||
|
||||
// Sine and Cosine tables
|
||||
// Angles: $00=0, $80=PI,$100=2*PI
|
||||
// Sine/Cosine: signed fixed [-$7f,$7f]
|
||||
signed char __align(0x40) SIN[0x140] = kickasm {{
|
||||
.for(var i=0;i<$140;i++)
|
||||
.byte >round($7fff*sin(i*2*PI/256))
|
||||
}};
|
||||
|
||||
signed char* COS = SIN+$40; // sin(x) = cos(x+PI/2)
|
||||
|
||||
// 2D-rotate a vector by an angle
|
||||
struct SplineVector16 rotate(struct SplineVector16 vector, char angle) {
|
||||
signed int cos_a = (signed int) COS[angle]; // signed fixed[0.7]
|
||||
signed int xr = (signed int )mulf16s(cos_a, vector.x)*2; // signed fixed[8.8]
|
||||
signed int yr = (signed int )mulf16s(cos_a, vector.y)*2; // signed fixed[8.8]
|
||||
signed int sin_a = (signed int) SIN[angle]; // signed fixed[0.7]
|
||||
xr -= (signed int)mulf16s(sin_a, vector.y)*2; // signed fixed[8.8]
|
||||
yr += (signed int)mulf16s(sin_a, vector.x)*2; // signed fixed[8.8]
|
||||
struct SplineVector16 rotated = { (signed int)(signed char)>xr, (signed int)(signed char)>yr };
|
||||
return rotated;
|
||||
}
|
Loading…
Reference in New Issue
Block a user