mirror of
https://github.com/cc65/cc65.git
synced 2024-06-08 15:29:37 +00:00
CircleDraw
This commit is contained in:
parent
efd985a8df
commit
72f4d2e99f
|
@ -16,6 +16,17 @@ typedef unsigned char byte;
|
|||
|
||||
extern void ClearScreen(void); // In subs.asm
|
||||
extern void ScrollScreen(void); // In subs.asm
|
||||
extern void DrawCircle(void); // In subs.asm
|
||||
|
||||
extern int x1cord;
|
||||
extern int y1cord;
|
||||
extern int x2cord;
|
||||
extern int y2cord;
|
||||
|
||||
#pragma zpsym("x1cord")
|
||||
#pragma zpsym("x2cord")
|
||||
#pragma zpsym("y1cord")
|
||||
#pragma zpsym("y2cord")
|
||||
|
||||
// Screen memory is placed at A000-BFFF, 320x200 pixels, mapped right to left within each horizontal byte
|
||||
|
||||
|
@ -216,30 +227,12 @@ void DrawLine(int x0, int y0, int x1, int y1, byte val)
|
|||
//
|
||||
// Draw a circle without sin, cos, or floating point!
|
||||
|
||||
void DrawCircle(int x0, int y0, int radius, byte val)
|
||||
void DrawCircleC(int x0, int y0, int radius, byte)
|
||||
{
|
||||
int x = radius;
|
||||
int y = 0;
|
||||
int err = 0;
|
||||
|
||||
while (x >= y)
|
||||
{
|
||||
SETPIXEL(x0 + x, y0 + y, val);
|
||||
SETPIXEL(x0 + y, y0 + x, val);
|
||||
SETPIXEL(x0 - y, y0 + x, val);
|
||||
SETPIXEL(x0 - x, y0 + y, val);
|
||||
SETPIXEL(x0 - x, y0 - y, val);
|
||||
SETPIXEL(x0 - y, y0 - x, val);
|
||||
SETPIXEL(x0 + y, y0 - x, val);
|
||||
SETPIXEL(x0 + x, y0 - y, val);
|
||||
|
||||
y++;
|
||||
err += 1 + 2 * y;
|
||||
if (2 * (err - x) + 1 > 0) {
|
||||
x--;
|
||||
err += 1 - 2 * x;
|
||||
}
|
||||
}
|
||||
x1cord = x0;
|
||||
y1cord = y0;
|
||||
y2cord = radius;
|
||||
DrawCircle();
|
||||
}
|
||||
|
||||
// reverse_bits
|
||||
|
@ -308,7 +301,7 @@ int main (void)
|
|||
|
||||
// Print the numbers from 0-9999, forcing the screen to scroll
|
||||
for (i = 5; i < 75; i+=5)
|
||||
DrawCircle(SCREEN_WIDTH/2, SCREEN_HEIGHT/2, i, 1);
|
||||
DrawCircleC(SCREEN_WIDTH/2, SCREEN_HEIGHT/2, i, 1);
|
||||
|
||||
printf("Done, exiting...\r\n");
|
||||
return 0;
|
||||
|
|
|
@ -14,12 +14,24 @@
|
|||
|
||||
.export _ClearScreen
|
||||
.export _ScrollScreen
|
||||
.export _SetPixel
|
||||
.export _DrawCircle
|
||||
|
||||
SCREEN = $A000
|
||||
|
||||
.segment "ZEROPAGE"
|
||||
temp: .res 1
|
||||
btpt: .res 1
|
||||
_x1cord: .res 2
|
||||
_x2cord: .res 2
|
||||
_y1cord: .res 2
|
||||
_y2cord: .res 2
|
||||
|
||||
.exportzp _x1cord
|
||||
.exportzp _x2cord
|
||||
.exportzp _y1cord
|
||||
.exportzp _y2cord
|
||||
|
||||
|
||||
dest = $02
|
||||
dest_lo = dest
|
||||
|
@ -37,13 +49,6 @@ adp2 = $08
|
|||
adp2_lo = adp2
|
||||
adp2_hi = adp2+1
|
||||
|
||||
x1cord = $0A
|
||||
x1cord_lo = x1cord
|
||||
x1cord_hi = x1cord+1
|
||||
|
||||
y1cord = $0C
|
||||
y1cord_lo = y1cord
|
||||
y1cord_hi = y1cord+1
|
||||
|
||||
|
||||
.segment "CODE"
|
||||
|
@ -53,18 +58,18 @@ y1cord_hi = y1cord+1
|
|||
;-----------------------------------------------------------------------------------
|
||||
; Based on MTU PIXADR code
|
||||
;-----------------------------------------------------------------------------------
|
||||
; x - x1cord (16-bit)
|
||||
; y - y1cord (16-bit)
|
||||
; x - _x1cord (16-bit)
|
||||
; y - _y1cord (16-bit)
|
||||
; adp2 - address of pixel to set (16-bit)
|
||||
;-----------------------------------------------------------------------------------
|
||||
|
||||
_GetPixelAddress:
|
||||
lda x1cord ; compute bit address first
|
||||
sta adp1 ; also transfer x1cord to adp1
|
||||
lda _x1cord ; compute bit address first
|
||||
sta adp1 ; also transfer _x1cord to adp1
|
||||
and #$07 ; + which is simply the low 3 bits of x
|
||||
sta btpt
|
||||
|
||||
lda x1cord+1 ; finish transferring x1cord to adp1
|
||||
lda _x1cord+1 ; finish transferring _x1cord to adp1
|
||||
sta adp1+1
|
||||
lsr adp1+1 ; double shift adp1 right 3 to get
|
||||
ror adp1 ; int(xcord/8 )
|
||||
|
@ -72,34 +77,34 @@ _GetPixelAddress:
|
|||
ror adp1
|
||||
lsr adp1+1
|
||||
ror adp1
|
||||
lda #199 ; transfer (199-y1cord) to adp2
|
||||
lda #199 ; transfer (199-_y1cord) to adp2
|
||||
sec ; and temporary storage
|
||||
sbc y1cord
|
||||
sbc _y1cord
|
||||
sta adp2
|
||||
sta temp
|
||||
|
||||
lda #0
|
||||
sbc y1cord+1
|
||||
sbc _y1cord+1
|
||||
sta adp2+1
|
||||
sta temp+1
|
||||
asl adp2 ; compute 40*(199-y1cord)
|
||||
rol adp2+1 ; 2*(199-y1cord)
|
||||
asl adp2 ; compute 40*(199-_y1cord)
|
||||
rol adp2+1 ; 2*(199-_y1cord)
|
||||
asl adp2
|
||||
rol adp2+1 ; 4*(199-y1cord)
|
||||
lda adp2 ; add in temporary save of (199-y1cord)
|
||||
clc ; to make 5*(199-y1cord)
|
||||
rol adp2+1 ; 4*(199-_y1cord)
|
||||
lda adp2 ; add in temporary save of (199-_y1cord)
|
||||
clc ; to make 5*(199-_y1cord)
|
||||
adc temp
|
||||
sta adp2
|
||||
lda adp2+1
|
||||
adc temp+1
|
||||
sta adp2+1 ; 5*(199-y1cord)
|
||||
asl adp2 ; 10*(199-y1cord)
|
||||
sta adp2+1 ; 5*(199-_y1cord)
|
||||
asl adp2 ; 10*(199-_y1cord)
|
||||
rol adp2+1
|
||||
asl adp2 ; 20#(199-y1cord)
|
||||
asl adp2 ; 20#(199-_y1cord)
|
||||
rol adp2+1
|
||||
asl adp2 ; 40*(199-y1cord)
|
||||
asl adp2 ; 40*(199-_y1cord)
|
||||
rol adp2+1
|
||||
lda adp2 ; add in int(x1cord/8) computed earlier
|
||||
lda adp2 ; add in int(_x1cord/8) computed earlier
|
||||
clc
|
||||
adc adp1
|
||||
sta adp1
|
||||
|
@ -122,13 +127,13 @@ msktb2: .byte $7F,$BF,$DF,$EF,$F7,$FB,$FD,$FE
|
|||
;-----------------------------------------------------------------------------------
|
||||
; SetPixel - Set a pixel in the video memory
|
||||
;-----------------------------------------------------------------------------------
|
||||
; x - x1cord (16-bit)
|
||||
; y - y1cord (16-bit)
|
||||
; x - _x1cord (16-bit)
|
||||
; y - _y1cord (16-bit)
|
||||
;-----------------------------------------------------------------------------------
|
||||
; Mask tables for individual pixel subroutines
|
||||
;-----------------------------------------------------------------------------------
|
||||
|
||||
_SetPixel: jsr _GetPixelAddress
|
||||
_SetPixel: jsr _GetPixelAddress
|
||||
ldy btpt ; get bit number in y
|
||||
lda msktb1,y ; get a byte with that bit =1, others =0
|
||||
ldy #0
|
||||
|
@ -139,8 +144,8 @@ _SetPixel: jsr _GetPixelAddress
|
|||
;-----------------------------------------------------------------------------------
|
||||
; ClearPixel - Clears a pixel in the video memory
|
||||
;-----------------------------------------------------------------------------------
|
||||
; x - x1cord (16-bit)
|
||||
; y - y1cord (16-bit)
|
||||
; x - _x1cord (16-bit)
|
||||
; y - _y1cord (16-bit)
|
||||
;-----------------------------------------------------------------------------------
|
||||
|
||||
_ClearPixel: jsr _GetPixelAddress
|
||||
|
@ -175,6 +180,10 @@ _ClearScreen:
|
|||
|
||||
rts
|
||||
|
||||
;-----------------------------------------------------------------------------------
|
||||
; ScrollScreen - Scrolls the entire video memory (and thus the screen) up one row
|
||||
;-----------------------------------------------------------------------------------
|
||||
|
||||
_ScrollScreen:
|
||||
; Load the source (A140) and destination (A000) addresses. Each row of characters
|
||||
; occupies 320 bytes, so we start source as being one line ahead of the destination
|
||||
|
@ -210,6 +219,253 @@ _ScrollScreen:
|
|||
bne :-
|
||||
rts
|
||||
|
||||
;-----------------------------------------------------------------------------------
|
||||
; DrawCircle - Draws a circle in video memory of a given radius at a given coord
|
||||
;-----------------------------------------------------------------------------------
|
||||
; x - _x1cord (16-bit)
|
||||
; y - _y1cord (16-bit)
|
||||
; radius - _y2cord (16-bit)
|
||||
;-----------------------------------------------------------------------------------
|
||||
|
||||
xval: .res 2
|
||||
yval: .res 2
|
||||
err: .res 2
|
||||
tempsum: .res 2
|
||||
tempx: .res 2
|
||||
tempy: .res 2
|
||||
|
||||
_DrawCircle: lda _x1cord ; tempx = _x1cord
|
||||
sta tempx
|
||||
lda _x1cord+1
|
||||
sta tempx+1
|
||||
lda _y1cord ; tempy = _y1cord
|
||||
sta tempy
|
||||
lda _y1cord+1
|
||||
sta tempy+1
|
||||
|
||||
lda _y2cord ; x = radius
|
||||
sta xval
|
||||
lda _y2cord+1
|
||||
sta xval+1
|
||||
|
||||
lda #$0 ; yval = 0;
|
||||
sta yval
|
||||
sta yval+1
|
||||
sta err ; err = 0;
|
||||
sta err+1
|
||||
circleloop:
|
||||
lda xval+1 ; if (xval < yval) goto done;
|
||||
cmp yval+1
|
||||
bcs docircle
|
||||
lda xval
|
||||
cmp yval
|
||||
bcs docircle
|
||||
rts
|
||||
docircle:
|
||||
lda tempx
|
||||
clc
|
||||
adc yval
|
||||
sta _x1cord
|
||||
lda tempx+1
|
||||
adc yval+1
|
||||
sta _x1cord+1
|
||||
lda tempy
|
||||
sec
|
||||
sbc xval
|
||||
sta _y1cord
|
||||
lda tempy+1
|
||||
sbc xval+1
|
||||
sta _y1cord+1
|
||||
jsr _SetPixel ; SETPIXEL(x0 + y, y0 - x, val);
|
||||
|
||||
lda tempx
|
||||
sec
|
||||
sbc yval
|
||||
sta _x1cord
|
||||
lda tempx+1
|
||||
sbc yval+1
|
||||
sta _x1cord+1
|
||||
lda tempy
|
||||
sec
|
||||
sbc xval
|
||||
sta _y1cord
|
||||
lda tempy+1
|
||||
sbc xval+1
|
||||
sta _y1cord+1
|
||||
jsr _SetPixel ; SETPIXEL(x0 - y, y0 - x, val);
|
||||
|
||||
lda tempx
|
||||
sec
|
||||
sbc xval
|
||||
sta _x1cord
|
||||
lda tempx+1
|
||||
sbc xval+1
|
||||
sta _x1cord+1
|
||||
lda tempy
|
||||
sec
|
||||
sbc yval
|
||||
sta _y1cord
|
||||
lda tempy+1
|
||||
sbc yval+1
|
||||
sta _y1cord+1
|
||||
jsr _SetPixel ; SETPIXEL(x0 - x, y0 - y, val);
|
||||
|
||||
lda tempx
|
||||
sec
|
||||
sbc xval
|
||||
sta _x1cord
|
||||
lda tempx+1
|
||||
sbc xval+1
|
||||
sta _x1cord+1
|
||||
lda tempy
|
||||
clc
|
||||
adc yval
|
||||
sta _y1cord
|
||||
lda tempy+1
|
||||
adc yval+1
|
||||
sta _y1cord+1
|
||||
jsr _SetPixel ; SETPIXEL(x0 - x, y0 + y, val);
|
||||
|
||||
lda tempx
|
||||
clc
|
||||
adc yval
|
||||
sta _x1cord
|
||||
lda tempx+1
|
||||
adc yval+1
|
||||
sta _x1cord+1
|
||||
lda tempy
|
||||
clc
|
||||
adc xval
|
||||
sta _y1cord
|
||||
lda tempy+1
|
||||
adc xval+1
|
||||
sta _y1cord+1
|
||||
jsr _SetPixel ; SETPIXEL(x0 + y, y0 + x, val);
|
||||
|
||||
lda tempx
|
||||
clc
|
||||
adc xval
|
||||
sta _x1cord
|
||||
lda tempx+1
|
||||
adc xval+1
|
||||
sta _x1cord+1
|
||||
lda tempy
|
||||
clc
|
||||
adc yval
|
||||
sta _y1cord
|
||||
lda tempy+1
|
||||
adc yval+1
|
||||
sta _y1cord+1
|
||||
jsr _SetPixel ; SETPIXEL(x0 + x, y0 + y, val);
|
||||
|
||||
lda tempx
|
||||
clc
|
||||
adc xval
|
||||
sta _x1cord
|
||||
lda tempx+1
|
||||
adc xval+1
|
||||
sta _x1cord+1
|
||||
lda tempy
|
||||
sec
|
||||
sbc yval
|
||||
sta _y1cord
|
||||
lda tempy+1
|
||||
sbc yval+1
|
||||
sta _y1cord+1
|
||||
jsr _SetPixel ; SETPIXEL(x0 + x, y0 - y, val);
|
||||
|
||||
lda tempx
|
||||
sec
|
||||
sbc yval
|
||||
sta _x1cord
|
||||
lda tempx+1
|
||||
sbc yval+1
|
||||
sta _x1cord+1
|
||||
lda tempy
|
||||
clc
|
||||
adc xval
|
||||
sta _y1cord
|
||||
lda tempy+1
|
||||
adc xval+1
|
||||
sta _y1cord+1
|
||||
jsr _SetPixel ; SETPIXEL(x0 - y, y0 + x, val);
|
||||
|
||||
inc yval ; yval++;
|
||||
bcc :+
|
||||
inc yval+1
|
||||
:
|
||||
lda #0 ; tempsum = 2 * yval + 1;
|
||||
sta tempsum
|
||||
sta tempsum+1
|
||||
lda yval
|
||||
asl
|
||||
rol yval+1
|
||||
clc
|
||||
adc #01
|
||||
sta tempsum
|
||||
bcc :+
|
||||
inc tempsum+1
|
||||
|
||||
lda err ; err += tempsum
|
||||
clc
|
||||
adc tempsum
|
||||
sta err
|
||||
bcc :+
|
||||
lda err+1
|
||||
adc tempsum+1
|
||||
sta err+1
|
||||
:
|
||||
lda err ; tempsum = err-xval
|
||||
sec
|
||||
sbc xval
|
||||
sta tempsum
|
||||
bcs :+
|
||||
lda err+1
|
||||
sbc xval+1
|
||||
sta tempsum+1
|
||||
|
||||
asl tempsum ; tempsum = 2*(err-xval)
|
||||
rol tempsum+1
|
||||
|
||||
clc ; tempsum = 2*(err-xval)+1
|
||||
inc tempsum
|
||||
bcc :+
|
||||
inc tempsum+1
|
||||
:
|
||||
lda tempsum+1 ; if (tempsum <= 0) don't inc the xval
|
||||
beq noadd
|
||||
bmi noadd
|
||||
|
||||
sec ; xval--
|
||||
dec xval
|
||||
bcs noadd
|
||||
dec xval+1
|
||||
noadd:
|
||||
lda xval ; tempsum = xval * 2
|
||||
asl
|
||||
sta tempsum
|
||||
lda xval+1
|
||||
rol
|
||||
sta tempsum+1
|
||||
|
||||
|
||||
lda #1 ; tempsum = 1-(xval*2)
|
||||
sec
|
||||
sbc tempsum
|
||||
sta tempsum
|
||||
lda #0
|
||||
sbc tempsum+1
|
||||
sta tempsum+1
|
||||
|
||||
lda err ; err += 1-(xval*2)
|
||||
clc
|
||||
adc tempsum
|
||||
sta err
|
||||
lda err+1
|
||||
adc tempsum+1
|
||||
sta err+1
|
||||
|
||||
jmp circleloop
|
||||
donecircle:
|
||||
rts
|
||||
|
Loading…
Reference in New Issue
Block a user