From 930b6e56cd5c999b2b529ee9e19bbb18135f7b0b Mon Sep 17 00:00:00 2001 From: Peter Tillema Date: Tue, 8 Mar 2022 12:50:54 +0100 Subject: [PATCH 1/9] Add ellipse routines --- src/graphx/graphx.asm | 372 ++++++++++++++++++++++++++++++++++++++++++ src/graphx/graphx.h | 50 ++++++ 2 files changed, 422 insertions(+) diff --git a/src/graphx/graphx.asm b/src/graphx/graphx.asm index d41307d07..b57469dfd 100644 --- a/src/graphx/graphx.asm +++ b/src/graphx/graphx.asm @@ -133,6 +133,13 @@ library 'GRAPHX', 11 ; v10 functions ;------------------------------------------------------------------------------- export gfx_CopyRectangle +;------------------------------------------------------------------------------- +; v11 functions +;------------------------------------------------------------------------------- + export gfx_Ellipse + export gfx_Ellipse_NoClip + export gfx_FillEllipse + export gfx_FillEllipse_NoClip ;------------------------------------------------------------------------------- LcdSize := ti.lcdWidth*ti.lcdHeight @@ -636,6 +643,7 @@ _SetPixel_NoWait: ld hl,-ti.lcdHeight add hl,de ret c ; return if out of bounds +_SetPixel_NoClip_NoWait: ld hl,(CurrentBuffer) add hl,bc ld d,ti.lcdWidth / 2 @@ -1135,6 +1143,370 @@ assert .LcdSizeH and ti.lcdIntLNBU dec sp ; sp -= 3 to match pop hl later jr _WriteWaitQuickSMC +;------------------------------------------------------------------------------- +gfx_FillEllipse_NoClip: + ld hl,gfx_HorizLine_NoClip + db $FD ; ld hl,* -> ld iy,* + +;------------------------------------------------------------------------------- +gfx_FillEllipse: + ld hl,gfx_HorizLine + ld (_ellipse_line_routine_1),hl + ld (_ellipse_line_routine_2),hl + ld hl,_ellipse_draw_line + ld (_ellipse_loop_draw_2),hl + ld (_ellipse_loop_draw_3),hl + ld hl,_ellipse_ret + ld (_ellipse_loop_draw_1),hl + jr _Ellipse + +;------------------------------------------------------------------------------- +gfx_Ellipse_NoClip: + ld hl,_SetPixel_NoClip_NoWait + db $FD ; ld hl,* -> ld iy,* + +;------------------------------------------------------------------------------- +gfx_Ellipse: + ld hl,_SetPixel_NoWait + ld (_ellipse_pixel_routine_1),hl + ld (_ellipse_pixel_routine_2),hl + ld (_ellipse_pixel_routine_3),hl + ld (_ellipse_pixel_routine_4),hl + ld hl,_ellipse_draw_pixels + ld (_ellipse_loop_draw_1),hl + ld (_ellipse_loop_draw_3),hl + ld hl,_ellipse_ret + ld (_ellipse_loop_draw_2),hl + +el_x := 3 ; Current X coordinate of the ellipse +el_y := 6 ; Current Y coordinate of the ellipse +el_a2 := 9 ; X radius squared +el_b2 := 12 ; Y radius squared +el_fa2 := 15 ; X radius squared * 4 +el_fb2 := 18 ; Y radius squared * 4 +el_sigma := 21 ; Sigma +el_sigma_1 := 24 ; Offset to be added to sigma in loop 1 +el_sigma_2 := 27 ; Offset to be added to sigma in loop 2 +el_temp1 := 30 ; X radius as "int" instead of "uint8_t" +el_comp_a := 33 ; b2 * x +el_comp_b := 36 ; a2 * y +el_sigma_diff1 := 39 ; Offset to be added to sigma in loop 1 +el_sigma_diff2 := 42 ; Offset to be added to sigma in loop 2 + +_Ellipse: +; Draws an ellipse, either filled or not, either clipped or not +; Arguments: +; arg0 : X coordinate (ix+6) +; arg1 : Y coordinate (ix+9) +; arg2 : X radius (ix+12) +; arg3 : Y radius (ix+15) +; Returns: +; None + push ix + ld ix,0 + add ix,sp + lea hl,ix - 42 + ld sp,hl + +; First, setup all the variables + ld a,(ix + 12) + or a,a + ret z ; Make sure X radius is not 0 + ld l,a + ld h,a + mlt hl + ld (ix - el_a2),hl ; int a2 = a * a; + add hl,hl + ld (ix - el_sigma_diff2),hl ; Save a2 * 2 for later + add hl,hl + ld (ix - el_fa2),hl ; int fa2 = 4 * a2; + ld a,(ix + 15) + or a,a + ret z ; Make sure Y radius is not 0 + ld e,a + ld d,1 + mlt de + ld (ix - el_y),de ; int y = b; + ld hl,(ix - el_a2) + ld d,l + ld l,e + mlt de + mlt hl + add hl,hl + add hl,hl + add hl,hl + add hl,hl + add hl,hl + add hl,hl + add hl,hl + add hl,hl + add hl,de + add hl,hl + add hl,hl + ex de,hl + ld hl,(ix - el_fa2) + or a,a + sbc hl,de + ld (ix - el_sigma_1),hl ; int sigma_add_1 = fa2 * (1 - b); + ld l,a + ld h,a + mlt hl + ld (ix - el_b2),hl ; int b2 = b * b; + add hl,hl + ld (ix - el_sigma_diff1),hl ; Save b2 * 2 for later + add hl,hl + ld (ix - el_fb2),hl ; int fb2 = 4 * b2; + ld c,a + ld b,2 + mlt bc + or a,a + sbc hl,hl + ld (ix - el_x),hl ; int x = 0; + ld (ix - el_comp_a),hl + inc hl + sbc hl,bc + ld bc,(ix - el_a2) + call _MultiplyHLBC + ld bc,(ix - el_b2) + add hl,bc + add hl,bc + ld (ix - el_sigma),hl ; int sigma = 2 * b2 + a2 * (1 - 2 * b); + ld e,(ix + 12) + ld d,1 + mlt de + ld (ix - el_temp1),de ; Save int a for later + or a,a + sbc hl,hl + inc hl + sbc hl,de + ld bc,(ix - el_fb2) + call _MultiplyHLBC + ld (ix - el_sigma_2),hl ; int sigma_add_2 = fb2 * (1 - a); + + ld hl,(ix - el_a2) + ld bc,(ix - el_y) + call _MultiplyHLBC + ld (ix - el_comp_b),hl + + wait_quick + +.main_loop1: + call 0 +_ellipse_loop_draw_1 := $-3 + +; Eventually change sigma and y + ld hl,(ix - el_sigma) + add hl,hl + jr c,.loop1_jump ; if (sigma >= 0) { + + call 0 +_ellipse_loop_draw_2 := $-3 + + ld hl,(ix - el_sigma) ; sigma += sigma_add_1; + ld de,(ix - el_sigma_1) + add hl,de + ld (ix - el_sigma),hl + ld hl,(ix - el_fa2) + add hl,de + ld (ix - el_sigma_1),hl ; sigma_add_1 += fa2; + ld hl, (ix - el_y) + dec hl + ld (ix - el_y),hl ; y--; + ld hl,(ix - el_comp_b) + ld de,(ix - el_a2) + or a,a + sbc hl,de + ld (ix - el_comp_b),hl +.loop1_jump: ; } +; Change sigma and increment x + ld hl,(ix - el_sigma_diff1) + ld de,(ix - el_fb2) + add hl,de + ld (ix - el_sigma_diff1),hl + ld de,(ix - el_sigma) + add hl,de + ld (ix - el_sigma),hl ; sigma += b2 * (4 * x + 6); + ld hl,(ix - el_x) + inc hl + ld (ix - el_x),hl ; x++; + +; Update the comparison operands + ld hl,(ix - el_comp_a) + ld de,(ix - el_b2) + add hl,de + ld (ix - el_comp_a),hl + ld de,(ix - el_comp_b) + +; And compare + ld bc,0x800000 ; b2 * x <= a2 * y so hl <= de + add hl,bc + ex de,hl ; de <= hl + add hl,bc + or a,a + sbc hl,de + jq nc,.main_loop1 + +; Update few variables for the next loop + ld hl, (ix - el_temp1) + ld (ix - el_x),hl ; x = a + ld e,l + or a,a + sbc hl,hl + ld (ix - el_y),hl ; y = 0 + ld (ix - el_comp_a),hl + ld d,2 + mlt de + inc hl + sbc hl,de + ld bc,(ix - el_b2) + call _MultiplyHLBC + ld de,(ix - el_a2) + add hl,de + add hl,de + ld (ix - el_sigma), hl + + ld hl,(ix - el_b2) + ld bc,(ix - el_temp1) + call _MultiplyHLBC + ld (ix - el_comp_b),hl + +.main_loop2: + call 0 +_ellipse_loop_draw_3 := $-3 + +; Eventually update sigma and x + ld hl,(ix - el_sigma) + add hl,hl + jr c,.loop2_jump ; if (sigma >= 0) { + ld hl,(ix - el_sigma) + ld de,(ix - el_sigma_2) + add hl,de + ld (ix - el_sigma),hl ; sigma += sigma_add_2; + ld hl,(ix - el_fb2) + add hl,de + ld (ix - el_sigma_2),hl ; sigma_add_2 += fb2; + ld hl, (ix - el_x) + dec hl + ld (ix - el_x),hl ; x--; + ld hl,(ix - el_comp_b) + ld de,(ix - el_b2) + or a,a + sbc hl,de + ld (ix - el_comp_b),hl +.loop2_jump: +; Change sigma and increment y + ld hl,(ix - el_sigma_diff2) + ld de,(ix - el_fa2) + add hl,de + ld (ix - el_sigma_diff2),hl + ld de,(ix - el_sigma) + add hl,de + ld (ix - el_sigma),hl ; sigma += a2 * (4 * y + 6); + ld hl,(ix - el_y) + inc hl + ld (ix - el_y),hl ; y++; + ld hl,(ix - el_comp_a) + ld de,(ix - el_a2) + add hl,de + ld (ix - el_comp_a),hl + +; Compare the boolean operators + ld de,(ix - el_comp_b) + ld bc,0x800000 + add hl,bc + ex de,hl + add hl,bc + or a,a + sbc hl,de + jq nc,.main_loop2 + + ld sp,ix + pop ix +_ellipse_ret: + ret + +_ellipse_draw_pixels: +; bc = x coordinate +; e = y coordinate + ld hl,(ix + 9) + ld de,(ix - el_y) + add hl,de + ex de,hl ; yc + y + push de + ld hl,(ix + 6) + ld bc,(ix - el_x) + add hl,bc + push hl + pop bc ; xc + x + call _SetPixel_NoWait +_ellipse_pixel_routine_1 := $-3 + pop de + ld hl,(ix + 6) + ld bc,(ix - el_x) + or a,a + sbc hl,bc + push hl + pop bc ; xc - x + push bc + call _SetPixel_NoWait +_ellipse_pixel_routine_2 := $-3 + pop bc + ld hl,(ix + 9) + ld de,(ix - el_y) + or a,a + sbc hl,de + push hl + pop bc ; yc - y + push bc + call _SetPixel_NoWait +_ellipse_pixel_routine_3 := $-3 + pop bc + ld hl,(ix + 6) + ld de,(ix - el_x) + add hl,de + ex de,hl ; xc + x + jp _SetPixel_NoWait +_ellipse_pixel_routine_4 := $-3 + +_ellipse_draw_line: + ld hl,(ix - el_x) + add hl,hl + push hl + ld hl,(ix + 9) + ld de,(ix - el_y) + or a,a + sbc hl,de + push hl + ld hl,(ix + 6) + ld de,(ix - el_x) + or a,a + sbc hl,de + push hl + call 0 +_ellipse_line_routine_1 := $-3 + pop hl + pop hl + pop hl + ld hl,(ix - el_x) + add hl,hl + push hl + ld hl,(ix + 9) + ld de,(ix - el_y) + add hl,de + push hl + ld hl,(ix + 6) + ld de,(ix - el_x) + or a,a + sbc hl,de + push hl + call 0 +_ellipse_line_routine_2 := $-3 + pop hl + pop hl + pop hl + ret + + ;------------------------------------------------------------------------------- gfx_Circle: ; Draws a clipped circle outline diff --git a/src/graphx/graphx.h b/src/graphx/graphx.h index 7dad1321a..5a631b868 100644 --- a/src/graphx/graphx.h +++ b/src/graphx/graphx.h @@ -35,6 +35,7 @@ * @author Jacob "jacobly" Young * @author Zachary "Runer112" Wassall * @author Patrick "tr1p1ea" Prendergast + * @author Peter "PT_" Tillema * @author "grosged" */ @@ -756,6 +757,55 @@ void gfx_FillCircle_NoClip(uint24_t x, #define gfx_Circle_NoClip(x, y, radius) \ gfx_Circle((x), (y), (radius)) +/** + * Draws an unclipped filled ellipse. + * + * This is measured from the top left origin of the screen. + * Performs faster than using gfx_FillEllipse, but can cause corruption if used outside the bounds of the screen. + * @param x X coordinate. + * @param y Y coordinate. + * @param a The horizontal radius of the ellipse. + * @param b The vertical radius of the ellipse. + */ +void gfx_FillEllipse_NoClip(int x, + int y, + int a, + int b); + +/** + * Draws a filled ellipse. + * + * This is measured from the top left origin of the screen. + * @param x X coordinate. + * @param y Y coordinate. + * @param a The horizontal radius of the ellipse. + * @param b The vertical radius of the ellipse. + */ +void gfx_FillEllipse(int x, int y, int a, int b); + +/** + * Draws an unclipped ellipse. + * + * This is measured from the top left origin of the screen. + * Performs faster than using gfx_FillEllipse, but can cause corruption if used outside the bounds of the screen. + * @param x X coordinate. + * @param y Y coordinate. + * @param a The horizontal radius of the ellipse. + * @param b The vertical radius of the ellipse. + */ +void gfx_Ellipse_NoClip(int x, int y, int a, int b); + +/** + * Draws an ellipse. + * + * This is measured from the top left origin of the screen. + * @param x X coordinate. + * @param y Y coordinate. + * @param a The horizontal radius of the ellipse. + * @param b The vertical radius of the ellipse. + */ +void gfx_Ellipse(int x, int y, int a, int b); + /** * Draws a clipped polygon outline. * From 101c2ed13e384fdd95c47b099c50388f88372633 Mon Sep 17 00:00:00 2001 From: Peter Tillema Date: Tue, 8 Mar 2022 12:58:14 +0100 Subject: [PATCH 2/9] Fix return when radius is 0 --- src/graphx/graphx.asm | 10 +++++++--- src/graphx/graphx.h | 5 +---- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/graphx/graphx.asm b/src/graphx/graphx.asm index b57469dfd..c2f5cb907 100644 --- a/src/graphx/graphx.asm +++ b/src/graphx/graphx.asm @@ -1210,8 +1210,12 @@ _Ellipse: ; First, setup all the variables ld a,(ix + 12) - or a,a - ret z ; Make sure X radius is not 0 + jr nz,.valid_x_radius +.return: + ld sp,ix + pop ix + ret +.valid_x_radius: ld l,a ld h,a mlt hl @@ -1222,7 +1226,7 @@ _Ellipse: ld (ix - el_fa2),hl ; int fa2 = 4 * a2; ld a,(ix + 15) or a,a - ret z ; Make sure Y radius is not 0 + jr z,.return ; Make sure Y radius is not 0 ld e,a ld d,1 mlt de diff --git a/src/graphx/graphx.h b/src/graphx/graphx.h index 5a631b868..32aa64b22 100644 --- a/src/graphx/graphx.h +++ b/src/graphx/graphx.h @@ -767,10 +767,7 @@ gfx_Circle((x), (y), (radius)) * @param a The horizontal radius of the ellipse. * @param b The vertical radius of the ellipse. */ -void gfx_FillEllipse_NoClip(int x, - int y, - int a, - int b); +void gfx_FillEllipse_NoClip(int x, int y, int a, int b); /** * Draws a filled ellipse. From 14196a9ff01732658d4a4e3833f3560de1fca8b5 Mon Sep 17 00:00:00 2001 From: Peter Tillema Date: Tue, 8 Mar 2022 12:59:40 +0100 Subject: [PATCH 3/9] Fix comment tabs --- src/graphx/graphx.asm | 58 +++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/src/graphx/graphx.asm b/src/graphx/graphx.asm index c2f5cb907..0afed996d 100644 --- a/src/graphx/graphx.asm +++ b/src/graphx/graphx.asm @@ -1219,18 +1219,18 @@ _Ellipse: ld l,a ld h,a mlt hl - ld (ix - el_a2),hl ; int a2 = a * a; + ld (ix - el_a2),hl ; int a2 = a * a; add hl,hl - ld (ix - el_sigma_diff2),hl ; Save a2 * 2 for later + ld (ix - el_sigma_diff2),hl; Save a2 * 2 for later add hl,hl - ld (ix - el_fa2),hl ; int fa2 = 4 * a2; + ld (ix - el_fa2),hl ; int fa2 = 4 * a2; ld a,(ix + 15) or a,a - jr z,.return ; Make sure Y radius is not 0 + jr z,.return ; Make sure Y radius is not 0 ld e,a ld d,1 mlt de - ld (ix - el_y),de ; int y = b; + ld (ix - el_y),de ; int y = b; ld hl,(ix - el_a2) ld d,l ld l,e @@ -1251,21 +1251,21 @@ _Ellipse: ld hl,(ix - el_fa2) or a,a sbc hl,de - ld (ix - el_sigma_1),hl ; int sigma_add_1 = fa2 * (1 - b); + ld (ix - el_sigma_1),hl ; int sigma_add_1 = fa2 * (1 - b); ld l,a ld h,a mlt hl - ld (ix - el_b2),hl ; int b2 = b * b; + ld (ix - el_b2),hl ; int b2 = b * b; add hl,hl ld (ix - el_sigma_diff1),hl ; Save b2 * 2 for later add hl,hl - ld (ix - el_fb2),hl ; int fb2 = 4 * b2; + ld (ix - el_fb2),hl ; int fb2 = 4 * b2; ld c,a ld b,2 mlt bc or a,a sbc hl,hl - ld (ix - el_x),hl ; int x = 0; + ld (ix - el_x),hl ; int x = 0; ld (ix - el_comp_a),hl inc hl sbc hl,bc @@ -1274,18 +1274,18 @@ _Ellipse: ld bc,(ix - el_b2) add hl,bc add hl,bc - ld (ix - el_sigma),hl ; int sigma = 2 * b2 + a2 * (1 - 2 * b); + ld (ix - el_sigma),hl ; int sigma = 2 * b2 + a2 * (1 - 2 * b); ld e,(ix + 12) ld d,1 mlt de - ld (ix - el_temp1),de ; Save int a for later + ld (ix - el_temp1),de ; Save int a for later or a,a sbc hl,hl inc hl sbc hl,de ld bc,(ix - el_fb2) call _MultiplyHLBC - ld (ix - el_sigma_2),hl ; int sigma_add_2 = fb2 * (1 - a); + ld (ix - el_sigma_2),hl ; int sigma_add_2 = fb2 * (1 - a); ld hl,(ix - el_a2) ld bc,(ix - el_y) @@ -1301,27 +1301,27 @@ _ellipse_loop_draw_1 := $-3 ; Eventually change sigma and y ld hl,(ix - el_sigma) add hl,hl - jr c,.loop1_jump ; if (sigma >= 0) { + jr c,.loop1_jump ; if (sigma >= 0) { call 0 _ellipse_loop_draw_2 := $-3 - ld hl,(ix - el_sigma) ; sigma += sigma_add_1; + ld hl,(ix - el_sigma) ; sigma += sigma_add_1; ld de,(ix - el_sigma_1) add hl,de ld (ix - el_sigma),hl ld hl,(ix - el_fa2) add hl,de - ld (ix - el_sigma_1),hl ; sigma_add_1 += fa2; + ld (ix - el_sigma_1),hl ; sigma_add_1 += fa2; ld hl, (ix - el_y) dec hl - ld (ix - el_y),hl ; y--; + ld (ix - el_y),hl ; y--; ld hl,(ix - el_comp_b) ld de,(ix - el_a2) or a,a sbc hl,de ld (ix - el_comp_b),hl -.loop1_jump: ; } +.loop1_jump: ; } ; Change sigma and increment x ld hl,(ix - el_sigma_diff1) ld de,(ix - el_fb2) @@ -1329,10 +1329,10 @@ _ellipse_loop_draw_2 := $-3 ld (ix - el_sigma_diff1),hl ld de,(ix - el_sigma) add hl,de - ld (ix - el_sigma),hl ; sigma += b2 * (4 * x + 6); + ld (ix - el_sigma),hl ; sigma += b2 * (4 * x + 6); ld hl,(ix - el_x) inc hl - ld (ix - el_x),hl ; x++; + ld (ix - el_x),hl ; x++; ; Update the comparison operands ld hl,(ix - el_comp_a) @@ -1342,9 +1342,9 @@ _ellipse_loop_draw_2 := $-3 ld de,(ix - el_comp_b) ; And compare - ld bc,0x800000 ; b2 * x <= a2 * y so hl <= de + ld bc,0x800000 ; b2 * x <= a2 * y so hl <= de add hl,bc - ex de,hl ; de <= hl + ex de,hl ; de <= hl add hl,bc or a,a sbc hl,de @@ -1352,11 +1352,11 @@ _ellipse_loop_draw_2 := $-3 ; Update few variables for the next loop ld hl, (ix - el_temp1) - ld (ix - el_x),hl ; x = a + ld (ix - el_x),hl ; x = a ld e,l or a,a sbc hl,hl - ld (ix - el_y),hl ; y = 0 + ld (ix - el_y),hl ; y = 0 ld (ix - el_comp_a),hl ld d,2 mlt de @@ -1381,17 +1381,17 @@ _ellipse_loop_draw_3 := $-3 ; Eventually update sigma and x ld hl,(ix - el_sigma) add hl,hl - jr c,.loop2_jump ; if (sigma >= 0) { + jr c,.loop2_jump ; if (sigma >= 0) { ld hl,(ix - el_sigma) ld de,(ix - el_sigma_2) add hl,de - ld (ix - el_sigma),hl ; sigma += sigma_add_2; + ld (ix - el_sigma),hl ; sigma += sigma_add_2; ld hl,(ix - el_fb2) add hl,de - ld (ix - el_sigma_2),hl ; sigma_add_2 += fb2; + ld (ix - el_sigma_2),hl ; sigma_add_2 += fb2; ld hl, (ix - el_x) dec hl - ld (ix - el_x),hl ; x--; + ld (ix - el_x),hl ; x--; ld hl,(ix - el_comp_b) ld de,(ix - el_b2) or a,a @@ -1405,10 +1405,10 @@ _ellipse_loop_draw_3 := $-3 ld (ix - el_sigma_diff2),hl ld de,(ix - el_sigma) add hl,de - ld (ix - el_sigma),hl ; sigma += a2 * (4 * y + 6); + ld (ix - el_sigma),hl ; sigma += a2 * (4 * y + 6); ld hl,(ix - el_y) inc hl - ld (ix - el_y),hl ; y++; + ld (ix - el_y),hl ; y++; ld hl,(ix - el_comp_a) ld de,(ix - el_a2) add hl,de From 1e0a5fa1db36c2de045df1df5127d31a5636704d Mon Sep 17 00:00:00 2001 From: Peter Tillema Date: Tue, 8 Mar 2022 14:05:52 +0100 Subject: [PATCH 4/9] Fix location of points, fix incorrect nz check --- src/graphx/graphx.asm | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/graphx/graphx.asm b/src/graphx/graphx.asm index 0afed996d..4d7d46da5 100644 --- a/src/graphx/graphx.asm +++ b/src/graphx/graphx.asm @@ -2,7 +2,7 @@ include '../include/library.inc' ;------------------------------------------------------------------------------- -library 'GRAPHX', 11 +library 'GRAPHX', 12 ;------------------------------------------------------------------------------- ; no dependencies @@ -1210,6 +1210,7 @@ _Ellipse: ; First, setup all the variables ld a,(ix + 12) + or a,a jr nz,.valid_x_radius .return: ld sp,ix @@ -1435,14 +1436,14 @@ _ellipse_draw_pixels: ld hl,(ix + 9) ld de,(ix - el_y) add hl,de - ex de,hl ; yc + y + ex de,hl push de ld hl,(ix + 6) ld bc,(ix - el_x) add hl,bc push hl - pop bc ; xc + x - call _SetPixel_NoWait + pop bc + call _SetPixel_NoWait ; xc + x, yc + y _ellipse_pixel_routine_1 := $-3 pop de ld hl,(ix + 6) @@ -1450,26 +1451,26 @@ _ellipse_pixel_routine_1 := $-3 or a,a sbc hl,bc push hl - pop bc ; xc - x + pop bc push bc - call _SetPixel_NoWait + call _SetPixel_NoWait ; xc - x, yc + y _ellipse_pixel_routine_2 := $-3 pop bc ld hl,(ix + 9) ld de,(ix - el_y) or a,a sbc hl,de - push hl - pop bc ; yc - y - push bc - call _SetPixel_NoWait + ex de,hl + push de + call _SetPixel_NoWait ; xc - x, yc - y _ellipse_pixel_routine_3 := $-3 - pop bc + pop de ld hl,(ix + 6) - ld de,(ix - el_x) - add hl,de - ex de,hl ; xc + x - jp _SetPixel_NoWait + ld bc,(ix - el_x) + add hl,bc + push hl + pop bc + jp _SetPixel_NoWait ; xc + x, yc - y _ellipse_pixel_routine_4 := $-3 _ellipse_draw_line: From b06ce03e817fe63e9ea9a70e09e17698a457769c Mon Sep 17 00:00:00 2001 From: Peter Tillema Date: Wed, 9 Mar 2022 08:56:04 +0100 Subject: [PATCH 5/9] Fix versions in header of graphx.asm --- src/graphx/graphx.asm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/graphx/graphx.asm b/src/graphx/graphx.asm index 4d7d46da5..c74949107 100644 --- a/src/graphx/graphx.asm +++ b/src/graphx/graphx.asm @@ -132,9 +132,13 @@ library 'GRAPHX', 12 ;------------------------------------------------------------------------------- ; v10 functions ;------------------------------------------------------------------------------- - export gfx_CopyRectangle + ;------------------------------------------------------------------------------- ; v11 functions +;------------------------------------------------------------------------------- + export gfx_CopyRectangle +;------------------------------------------------------------------------------- +; v12 functions ;------------------------------------------------------------------------------- export gfx_Ellipse export gfx_Ellipse_NoClip From 03efe3b8bffc4d5469fc12051d87d89b2095f4e4 Mon Sep 17 00:00:00 2001 From: Peter Tillema Date: Wed, 9 Mar 2022 13:41:43 +0100 Subject: [PATCH 6/9] Clearify wording of x/y coordinates --- src/graphx/graphx.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/graphx/graphx.h b/src/graphx/graphx.h index 32aa64b22..50f3040fb 100644 --- a/src/graphx/graphx.h +++ b/src/graphx/graphx.h @@ -762,8 +762,8 @@ gfx_Circle((x), (y), (radius)) * * This is measured from the top left origin of the screen. * Performs faster than using gfx_FillEllipse, but can cause corruption if used outside the bounds of the screen. - * @param x X coordinate. - * @param y Y coordinate. + * @param x X coordinate of the center. + * @param y Y coordinate of the center. * @param a The horizontal radius of the ellipse. * @param b The vertical radius of the ellipse. */ @@ -773,8 +773,8 @@ void gfx_FillEllipse_NoClip(int x, int y, int a, int b); * Draws a filled ellipse. * * This is measured from the top left origin of the screen. - * @param x X coordinate. - * @param y Y coordinate. + * @param x X coordinate of the center. + * @param y Y coordinate of the center. * @param a The horizontal radius of the ellipse. * @param b The vertical radius of the ellipse. */ @@ -785,8 +785,8 @@ void gfx_FillEllipse(int x, int y, int a, int b); * * This is measured from the top left origin of the screen. * Performs faster than using gfx_FillEllipse, but can cause corruption if used outside the bounds of the screen. - * @param x X coordinate. - * @param y Y coordinate. + * @param x X coordinate of the center. + * @param y Y coordinate of the center. * @param a The horizontal radius of the ellipse. * @param b The vertical radius of the ellipse. */ @@ -796,8 +796,8 @@ void gfx_Ellipse_NoClip(int x, int y, int a, int b); * Draws an ellipse. * * This is measured from the top left origin of the screen. - * @param x X coordinate. - * @param y Y coordinate. + * @param x X coordinate of the center. + * @param y Y coordinate of the center. * @param a The horizontal radius of the ellipse. * @param b The vertical radius of the ellipse. */ From b16e157055360992ddef84cf6427671bc59f5a81 Mon Sep 17 00:00:00 2001 From: Peter Tillema Date: Mon, 14 Mar 2022 12:37:37 +0100 Subject: [PATCH 7/9] Add warning --- src/graphx/graphx.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/graphx/graphx.h b/src/graphx/graphx.h index 50f3040fb..9179ca1a6 100644 --- a/src/graphx/graphx.h +++ b/src/graphx/graphx.h @@ -762,6 +762,11 @@ gfx_Circle((x), (y), (radius)) * * This is measured from the top left origin of the screen. * Performs faster than using gfx_FillEllipse, but can cause corruption if used outside the bounds of the screen. + * + * @warning + * When using too large radii (> 128) the upper and lower half of the ellipse might get corrupted due to + * integer overflow. + * * @param x X coordinate of the center. * @param y Y coordinate of the center. * @param a The horizontal radius of the ellipse. @@ -773,6 +778,11 @@ void gfx_FillEllipse_NoClip(int x, int y, int a, int b); * Draws a filled ellipse. * * This is measured from the top left origin of the screen. + * + * @warning + * When using too large radii (> 128) the upper and lower half of the ellipse might get corrupted due to + * integer overflow. + * * @param x X coordinate of the center. * @param y Y coordinate of the center. * @param a The horizontal radius of the ellipse. @@ -785,6 +795,11 @@ void gfx_FillEllipse(int x, int y, int a, int b); * * This is measured from the top left origin of the screen. * Performs faster than using gfx_FillEllipse, but can cause corruption if used outside the bounds of the screen. + * + * @warning + * When using too large radii (> 128) the upper and lower half of the ellipse might get corrupted due to + * integer overflow. + * * @param x X coordinate of the center. * @param y Y coordinate of the center. * @param a The horizontal radius of the ellipse. @@ -796,6 +811,11 @@ void gfx_Ellipse_NoClip(int x, int y, int a, int b); * Draws an ellipse. * * This is measured from the top left origin of the screen. + * + * @warning + * When using too large radii (> 128) the upper and lower half of the ellipse might get corrupted due to + * integer overflow. + * * @param x X coordinate of the center. * @param y Y coordinate of the center. * @param a The horizontal radius of the ellipse. From 77daf5ad0cb58ee3ba563a80b08482c2b3aace30 Mon Sep 17 00:00:00 2001 From: Peter Tillema Date: Mon, 14 Mar 2022 12:48:45 +0100 Subject: [PATCH 8/9] Add ellipses to autotest --- examples/graphx/shapes/autotest.json | 25 +++++++++++++++++-------- examples/graphx/shapes/src/main.c | 19 +++++++++++++++++++ 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/examples/graphx/shapes/autotest.json b/examples/graphx/shapes/autotest.json index b72820457..ffde1d779 100644 --- a/examples/graphx/shapes/autotest.json +++ b/examples/graphx/shapes/autotest.json @@ -14,7 +14,7 @@ "delay|100", "hashWait|1", "key|enter", - "hashWait|2", + "hashWait|2", "key|enter", "hashWait|3", "key|enter", @@ -22,10 +22,12 @@ "key|enter", "hashWait|5", "key|enter", - "delay|2000", "hashWait|6", "key|enter", - "hashWait|7" + "delay|2000", + "hashWait|7", + "key|enter", + "hashWait|8" ], "hashes": { @@ -37,41 +39,48 @@ "expected_CRCs": [ "8DE8E699" ] }, "2": + { + "description": "Test ellipse display", + "start": "vram_start", + "size": "vram_8_size", + "expected_CRCs": [ "2138C183" ] + }, + "3": { "description": "Test rectangle outline display", "start": "vram_start", "size": "vram_8_size", "expected_CRCs": [ "6390F38B" ] }, - "3": + "4": { "description": "Test rectangle fill display", "start": "vram_start", "size": "vram_8_size", "expected_CRCs": [ "163F3B60" ] }, - "4": + "5": { "description": "Test triangle fill display", "start": "vram_start", "size": "vram_8_size", "expected_CRCs": [ "A1154AE5" ] }, - "5": + "6": { "description": "Test line display", "start": "vram_start", "size": "vram_8_size", "expected_CRCs": [ "08AE93E1" ] }, - "6": + "7": { "description": "Test pixel display", "start": "vram_start", "size": "vram_8_size", "expected_CRCs": [ "B6CCDD04" ] }, - "7": + "8": { "description": "Test program exit", "start": "vram_start", diff --git a/examples/graphx/shapes/src/main.c b/examples/graphx/shapes/src/main.c index 0a4b3f78b..7d0050593 100644 --- a/examples/graphx/shapes/src/main.c +++ b/examples/graphx/shapes/src/main.c @@ -40,6 +40,25 @@ int main(void) /* Waits for a key */ while (!os_GetCSC()); + + /* Clear the screen */ + gfx_FillScreen(255); + + /* Ellipse Drawing */ + gfx_SetColor(56); + for (i = 10; i < 50; i += 2) + { + gfx_Ellipse_NoClip(100, 100, i, 40); + } + gfx_SetColor(195); + gfx_Ellipse(300, 35, 140, 80); + gfx_SetColor(5); + gfx_FillEllipse_NoClip(200, 150, 120, 50); + gfx_SetColor(210); + gfx_FillEllipse(25, 200, 60, 90); + + /* Waits for a key */ + while (!os_GetCSC()); /* Clear the screen */ gfx_FillScreen(255); From ab90972f2d4704ba26e6b7d3057a118eac0395ef Mon Sep 17 00:00:00 2001 From: Peter Tillema Date: Mon, 14 Mar 2022 13:00:32 +0100 Subject: [PATCH 9/9] Fix tabs --- examples/graphx/shapes/autotest.json | 2 +- examples/graphx/shapes/src/main.c | 32 ++++++++++++++-------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/examples/graphx/shapes/autotest.json b/examples/graphx/shapes/autotest.json index ffde1d779..b09931c22 100644 --- a/examples/graphx/shapes/autotest.json +++ b/examples/graphx/shapes/autotest.json @@ -14,7 +14,7 @@ "delay|100", "hashWait|1", "key|enter", - "hashWait|2", + "hashWait|2", "key|enter", "hashWait|3", "key|enter", diff --git a/examples/graphx/shapes/src/main.c b/examples/graphx/shapes/src/main.c index 7d0050593..4fa3a96a1 100644 --- a/examples/graphx/shapes/src/main.c +++ b/examples/graphx/shapes/src/main.c @@ -40,24 +40,24 @@ int main(void) /* Waits for a key */ while (!os_GetCSC()); - - /* Clear the screen */ + + /* Clear the screen */ gfx_FillScreen(255); - - /* Ellipse Drawing */ - gfx_SetColor(56); - for (i = 10; i < 50; i += 2) + + /* Ellipse Drawing */ + gfx_SetColor(56); + for (i = 10; i < 50; i += 2) { - gfx_Ellipse_NoClip(100, 100, i, 40); - } - gfx_SetColor(195); - gfx_Ellipse(300, 35, 140, 80); - gfx_SetColor(5); - gfx_FillEllipse_NoClip(200, 150, 120, 50); - gfx_SetColor(210); - gfx_FillEllipse(25, 200, 60, 90); - - /* Waits for a key */ + gfx_Ellipse_NoClip(100, 100, i, 40); + } + gfx_SetColor(195); + gfx_Ellipse(300, 35, 140, 80); + gfx_SetColor(5); + gfx_FillEllipse_NoClip(200, 150, 120, 50); + gfx_SetColor(210); + gfx_FillEllipse(25, 200, 60, 90); + + /* Waits for a key */ while (!os_GetCSC()); /* Clear the screen */