diff --git a/src/graphx/graphx.asm b/src/graphx/graphx.asm index 00539f678..73c2fb367 100644 --- a/src/graphx/graphx.asm +++ b/src/graphx/graphx.asm @@ -1992,14 +1992,15 @@ gfx_Line: call _ComputeOutcode ld (iy-2),a CohenSutherlandLoop: - ld b,(iy-1) ; b = outcode0 ld a,(iy-2) ; a = outcode1 +.skip_ld_A: + ld b,(iy-1) ; b = outcode0 tst a,b - jp nz,TrivialReject ; if(outcode0|outcode1) + jr nz,TrivialReject ; if(outcode0|outcode1) or a,a jr nz,GetOutOutcode or a,b - jp z,TrivialAccept + jr z,TrivialAccept GetOutOutcode: ; select correct outcode push af ; a = outoutcode rra @@ -2042,6 +2043,14 @@ NotBottom: ld hl,ti.lcdWidth-1 smcWord _XMaxMinus1 jr ComputeNewY + +TrivialReject: + ld sp, iy + ret +TrivialAccept: + ld sp, iy + jr _Line_NoClip ; line routine handler + NotRight: rra jr nc,FinishComputations ; if (outcodeOut & LEFT) @@ -2085,17 +2094,7 @@ OutcodeOutOutcode1: ld (iy+12),de call _ComputeOutcode ld (iy-2),a ; c = outcode1 - jp CohenSutherlandLoop -TrivialReject: - inc sp - inc sp - inc sp - ret -TrivialAccept: - inc sp - inc sp - inc sp -; jr _Line_NoClip ; line routine handler + jp CohenSutherlandLoop.skip_ld_A ;------------------------------------------------------------------------------- gfx_Line_NoClip: @@ -2109,19 +2108,21 @@ gfx_Line_NoClip: ; None ld iy,0 add iy,sp +_Line_NoClip: ld hl,(iy+3) ld de,(iy+9) ld b,(iy+6) ld c,(iy+12) ; line from hl,b to de,c - or a,a +; or a,a sbc hl,de add hl,de - jr c,+_ ; draw left to right + jr c,_draw_left_to_right ; draw left to right ex de,hl ld a,b ld b,c ld c,a -_: push bc +_draw_left_to_right: + push bc pop iy push hl ld hl,(CurrentBuffer) @@ -2146,17 +2147,18 @@ _: push bc sbc hl,hl ld l,a ; y0 sbc hl,de - jr nc,$+9 + jr nc,.positive_dy ex de,hl + or a, a sbc hl,hl - ccf - sbc hl,de - inc hl ; abs(dy) + sbc hl,de ; abs(dy) +.positive_dy: ld a,iyl sub a,iyh ld iy,-320 - jr c,$+7 + jr c,.use_negative_IY ld iy,320 +.use_negative_IY: or a,a sbc hl,bc add hl,bc ; hl = dy @@ -2165,15 +2167,15 @@ dl_horizontal: ld a,l or a,h ld a,$38 - jr nz,$+4 + jr nz,.dl_nz xor a,$20 +.dl_nz: ld (_smc_dl_jr_0 + 0),a ; write smc ld (_smc_dl_width_1 + 1),iy ; write smc ex de,hl +; or a,a ; or a,h clears carry sbc hl,hl - ccf sbc hl,de - inc hl ex de,hl ; de = -dy pop hl ; restore buffer ld (_smc_dl_dx_1 + 1),bc ; write smc @@ -3998,8 +4000,7 @@ gfx_SetFontData: ; Returns: ; Pointer to previous font data pop de - pop hl - push hl ; hl -> custom font data + ex (sp), hl ; hl -> custom font data push de add hl,de or a,a @@ -4050,8 +4051,7 @@ gfx_SetFontSpacing: ; Returns: ; None pop de - pop hl - push hl ; hl -> custom font width + ex (sp), hl ; hl -> custom font width push de add hl,de or a,a @@ -4069,11 +4069,10 @@ gfx_SetMonospaceFont: ; arg0 : Monospace spacing amount ; Returns: ; None - pop hl pop de + ex (sp), hl push de - push hl - ld a,e ; a = width + ld a,l ; a = width ld (_TextFixedWidth),a ; store the value of the monospace width ret @@ -4215,9 +4214,6 @@ _FillTriangle: push de call 0 ; horizline(a, y0, b-a+1); .line0 := $-3 - pop bc - pop bc - pop bc ld sp,ix pop ix ret ; return; @@ -4402,131 +4398,387 @@ _FillTriangle: ret .cmp70: jp po,.secondloop +_Return: ld sp,ix pop ix ret ;------------------------------------------------------------------------------- -gfx_Polygon_NoClip: -; Draws a clipped polygon outline -; Arguments: -; arg0 : Pointer to polygon points -; arg1 : length of polygon point array -; Returns: -; None - ld hl,gfx_Line_NoClip -; jr _Polygon ; emulated by dummifying next instruction: - db $FD ; ld hl,* -> ld iy,* -;------------------------------------------------------------------------------- -gfx_Polygon: -; Draws a clipped polygon outline +gfx_FloodFill: +; Implements a flood fill so no one hopefully crashes the stack +; Maximum stack depth is 3224 bytes ; Arguments: -; arg0 : Pointer to polygon points -; arg1 : length of polygon point array +; arg0 : X Coordinate +; arg1 : Y Coordinate +; arg2 : New Color Index ; Returns: ; None - ld hl,gfx_Line -_Polygon: - ld (.line0),hl - ld (.line1),hl - push ix - ld ix,0 - add ix,sp - ld sp,hl - ld iy,(ix+6) - jr .startloop -.loop: - push iy - ld bc,(iy+9) - push bc - ld bc,(iy+6) - push bc - ld bc,(iy+3) - push bc - ld bc,(iy+0) - push bc - call 0 -.line0 := $-3 - pop bc - pop bc - pop bc - pop bc - pop iy - lea iy,iy+6 -.startloop: - ld hl,(ix+9) - dec hl - ld (ix+9),hl - add hl,bc - or a,a - sbc hl,bc - jr nz,.loop - ld bc,(iy+3) - push bc - ld bc,(iy+0) - push bc - ld iy,(ix+6) + ld hl,-3224 + call ti._frameset + + ld e,(ix+9) + ld bc,(ix+6) + call _GetPixel ; ov = p(x, y); + + ld (.oldcolor0),a + ld (.oldcolor1),a + ld (.oldcolor2),a + ld b,(ix+12) + cp a,b ; return if same color + jr z,_Return + + ld a,b + ld (.newcolor0),a + ld (.newcolor1),a + + lea iy,ix + ld bc,-3224 + add iy,bc + ld (.stack),iy + + ld a,(ix+9) + ld hl,(ix+6) + ld (iy+0),hl ; sp->xl = x; + ld (iy+3),hl ; sp->xr = x; + ld (iy+6),a ; sp->y = y; + ld (iy+7),1 ; sp->dy = 1; + lea iy,iy+8 ; sp++; + + inc a + ld (iy+6),a ; sp->y = y+1; + ld (iy+0),hl ; sp->xl = x; + ld (iy+3),hl ; sp->xr = x; + ld (iy+7),255 ; sp->dy = -1; + lea iy,iy+8 ; sp++; + + call gfx_Wait + +.dowhileloop: ; do { + lea iy,iy-8 ; sp--; + ld a,(iy+7) + ld (ix-4),a ; dy = sp->dy; + add a,(iy+6) ; y = sp->y+dy; + ld (ix+9),a ld bc,(iy+3) - push bc + ld (ix-15),bc ; x2 = sp->xr; ld bc,(iy+0) - push bc - call 0 -.line1 := $-3 - ld sp,ix - pop ix - ret + ld (ix-8),bc ; x1 = sp->xl; -;------------------------------------------------------------------------------- -gfx_Reserved: -; Deprecated unused function (available for use) - ret + ld hl,(CurrentBuffer) + ld e,a + ld d,ti.lcdWidth / 2 + mlt de + add hl,de + add hl,de + ld de,0 +smcWord _XMin + ex de,hl + add hl,de + ex de,hl ; de -> draw location at xmin, y + add hl,bc ; hl -> draw location at x, y + ld a,0 +.oldcolor0 = $-1 -;------------------------------------------------------------------------------- -gfx_Deprecated: -; Decompresses a sprite that is LZ77 compressed from ConvPNG (Deprecated) - ld hl,-23 - call ti._frameset - ld hl,(ix+6) - ld e,(hl) - inc hl - ld d,(hl) - ex.s de,hl - inc hl - inc hl - ld (ix-17),hl - ld bc,3 - ld (ix-3),bc - ld iy,(ix+6) - ld a,(iy+2) - ld (ix-8),a + jr .begin +.forloop0: ; for (x=x1; x>=xmin && p(x, y) == ov; x--) { s(x, y); } + ld (hl),0 +.newcolor0 = $-1 + dec bc + scf +.begin: + sbc hl,de + jr c,.nonnegative + add hl,de + cp a,(hl) + jr z,.forloop0 or a,a - sbc hl,hl - ld (ix-6),hl -d_17: ld bc,(ix-3) +.nonnegative: + ld (ix+6),bc + ld bc,(ix-8) ld hl,(ix+6) + jr c,.check + sbc hl,bc + jp nc,.skip ; if (x>=xmin && (unsigned)x>=x1) goto skip; add hl,bc +.check: + inc hl + ld (ix-11),hl ; l = x+1; + xor a,a + sbc hl,bc + ld e,(ix+9) + jr nc,.badpush0 ; if (l draw location + ; do { +.forloop1start: + ld hl,ti.lcdWidth-1 +smcWord _XMaxMinus1 + jr .atov ; for (; (unsigned)x<=xmax && p(x, y) == ov; x++) { s(x, y); } +.forloop1: + ld a,0 +.newcolor1 = $-1 + ld (de),a + inc de + inc bc +.atov: + sbc hl,bc + jr c,.ovat + add hl,bc + ld a,(de) + cp a,0 +.oldcolor1 = $-1 + jr z,.forloop1 + +.ovat: + ld (ix+6),bc + lea de,ix-24 ; push(y, l, x-1, dy); + lea hl,iy + or a,a + sbc hl,de + jr nc,.badpush1 + ld a,(ix-4) + add a,(ix+9) + sub a,0 ; check if y coordinate is in bounds +smcByte _YMin + cp a,ti.lcdHeight +smcByte _YSpan + jr nc,.badpush1 + dec bc + ld (iy+3),bc + ld a,(ix+9) + ld (iy+6),a + ld bc,(ix-11) + ld (iy+0),bc + ld a,(ix-4) + ld (iy+7),a + lea iy,iy+8 +.badpush1: + ld hl,(ix-15) ; if (x>x2+1) { push(y, x2+1, x-1, -dy); } + ld bc,(ix+6) + inc hl + or a,a + sbc hl,bc + jr nc,.skip + lea de,ix-24 + lea hl,iy + or a,a + sbc hl,de + jr nc,.badpush2 + ld a,(ix+9) + sub a,(ix-4) + sub a,0 ; check if y coordinate is in bounds +smcByte _YMin + cp a,ti.lcdHeight +smcByte _YSpan + jr nc,.badpush2 + dec bc + ld (iy+3),bc + ld bc,(ix-15) + inc bc + ld (iy+0),bc + xor a,a + sub a,(ix-4) + ld (iy+7),a + ld a,(ix+9) + ld (iy+6),a + lea iy,iy+8 +.skip: +.badpush2: ; skip: for (x++; (unsigned)x<=x2 && p(x, y) != ov; x++); + ld bc,(ix+6) + inc bc + + ld hl,(CurrentBuffer) + add hl,bc + ld e,(ix+9) + ld d,ti.lcdWidth / 2 + mlt de + add hl,de + add hl,de + ex de,hl ; de -> draw location + ld hl,(ix-15) + + jr .whileloop +.forloop2: + inc bc + inc de +.whileloop: + or a,a + sbc hl,bc + add hl,bc + jr c,.done + ld a,(de) + cp a,0 +.oldcolor2 = $-1 + jr nz,.forloop2 + +.done: + ld (ix+6),bc + ld (ix-11),bc ; l = x; + or a,a + sbc hl,bc + jp nc,.forloop1start ; } while ((unsigned)x<=x2); + + ld hl,0 +.stack = $-3 + lea de,iy + or a,a + sbc hl,de + jp c,.dowhileloop ; } while (sp>stack); + ld sp,ix + pop ix + ret + +;------------------------------------------------------------------------------- +gfx_Polygon_NoClip: +; Draws a clipped polygon outline +; Arguments: +; arg0 : Pointer to polygon points +; arg1 : length of polygon point array +; Returns: +; None + ld hl,gfx_Line_NoClip +; jr _Polygon ; emulated by dummifying next instruction: + db $FD ; ld hl,* -> ld iy,* +;------------------------------------------------------------------------------- +gfx_Polygon: +; Draws a clipped polygon outline +; Arguments: +; arg0 : Pointer to polygon points +; arg1 : length of polygon point array +; Returns: +; None + ld hl,gfx_Line +_Polygon: + ld (.line0),hl + ld (.line1),hl + push ix + ld ix,0 + add ix,sp + ld sp,hl + ld iy,(ix+6) + jr .startloop +.loop: + push iy + ld bc,(iy+9) + push bc + ld bc,(iy+6) + push bc + ld bc,(iy+3) + push bc + ld bc,(iy+0) + push bc + call 0 +.line0 := $-3 + pop bc + pop bc + pop bc + pop bc + pop iy + lea iy,iy+6 +.startloop: + ld hl,(ix+9) + dec hl + ld (ix+9),hl + add hl,bc + or a,a + sbc hl,bc + jr nz,.loop + ld bc,(iy+3) + push bc + ld bc,(iy+0) + push bc + ld iy,(ix+6) + ld bc,(iy+3) + push bc + ld bc,(iy+0) + push bc + call 0 +.line1 := $-3 + ld sp,ix + pop ix + ret + +;------------------------------------------------------------------------------- +gfx_Reserved: +; Deprecated unused function (available for use) + ret + +;------------------------------------------------------------------------------- +gfx_Deprecated: +; Decompresses a sprite that is LZ77 compressed from ConvPNG (Deprecated) + ld hl,-23 + call ti._frameset + ld hl,(ix+6) + ld e,(hl) + inc hl + ld d,(hl) + ex.s de,hl + inc hl + inc hl + ld (ix-17),hl + ld bc,3 + ld (ix-3),bc + ld iy,(ix+6) + ld a,(iy+2) + ld (ix-8),a + or a,a + sbc hl,hl + ld (ix-6),hl +d_17: ld bc,(ix-3) + ld hl,(ix+6) + add hl,bc + inc bc + ld (ix-3),bc + ld a,(hl) + ld (ix-7),a + cp a,(ix-8) + jp nz,d_16 + ld bc,(ix-3) + ld hl,(ix+6) + add hl,bc + ld (ix-14),hl + ld a,(hl) + or a,a + jr nz,d_13 + ld bc,(ix-6) + ld hl,(ix+9) + add hl,bc + inc bc + ld (ix-6),bc + ld a,(ix-8) + ld (hl),a + ld bc,(ix-3) + inc bc ld (ix-3),bc jr d_18 d_13: ld bc,(ix-14) @@ -5320,21 +5572,23 @@ _smc_dsrs_sinf_1: ; smc = sinf getSinCos: ; returns a = sin/cos(a) * 128 - ld c,a - bit 7,a - jr z,$+4 - sub a,128 - bit 6,a - jr z,$+6 - ld e,a - ld a,128 - sub a,e - ld de,0 - ld e,a - ld hl,_SineTable - add hl,de - ld a,(hl) - bit 7,c + ld de, $80 + ld c, a + bit 7, a + jr z, .bit7 + sub a, e ; sub a, 128 +.bit7: + bit 6, a + jr z, .bit6 + ; A = 128 - A + neg + add a, e ; add a, 128 +.bit6: + ld e, a + ld hl, _SineTable + add hl, de + ld a, (hl) + bit 7, c ret z neg ret @@ -5401,263 +5655,6 @@ _16Mul16SignedNeg: ld h,d ret -;------------------------------------------------------------------------------- -gfx_FloodFill: -; Implements a flood fill so no one hopefully crashes the stack -; Maximum stack depth is 3224 bytes -; Arguments: -; arg0 : X Coordinate -; arg1 : Y Coordinate -; arg2 : New Color Index -; Returns: -; None - ld hl,-3224 - call ti._frameset - - ld e,(ix+9) - ld bc,(ix+6) - call _GetPixel ; ov = p(x, y); - - ld (.oldcolor0),a - ld (.oldcolor1),a - ld (.oldcolor2),a - ld b,(ix+12) - cp a,b ; return if same color - jq z,.return - - ld a,b - ld (.newcolor0),a - ld (.newcolor1),a - - lea iy,ix - ld bc,-3224 - add iy,bc - ld (.stack),iy - - ld a,(ix+9) - ld hl,(ix+6) - ld (iy+0),hl ; sp->xl = x; - ld (iy+3),hl ; sp->xr = x; - ld (iy+6),a ; sp->y = y; - ld (iy+7),1 ; sp->dy = 1; - lea iy,iy+8 ; sp++; - - inc a - ld (iy+6),a ; sp->y = y+1; - ld (iy+0),hl ; sp->xl = x; - ld (iy+3),hl ; sp->xr = x; - ld (iy+7),255 ; sp->dy = -1; - lea iy,iy+8 ; sp++; - - call gfx_Wait - -.dowhileloop: ; do { - lea iy,iy-8 ; sp--; - ld a,(iy+7) - ld (ix-4),a ; dy = sp->dy; - add a,(iy+6) ; y = sp->y+dy; - ld (ix+9),a - ld bc,(iy+3) - ld (ix-15),bc ; x2 = sp->xr; - ld bc,(iy+0) - ld (ix-8),bc ; x1 = sp->xl; - - ld hl,(CurrentBuffer) - ld e,a - ld d,ti.lcdWidth / 2 - mlt de - add hl,de - add hl,de - ld de,0 -smcWord _XMin - ex de,hl - add hl,de - ex de,hl ; de -> draw location at xmin, y - add hl,bc ; hl -> draw location at x, y - ld a,0 -.oldcolor0 = $-1 - - jr .begin -.forloop0: ; for (x=x1; x>=xmin && p(x, y) == ov; x--) { s(x, y); } - ld (hl),0 -.newcolor0 = $-1 - dec bc - scf -.begin: - sbc hl,de - jr c,.nonnegative - add hl,de - cp a,(hl) - jr z,.forloop0 - or a,a -.nonnegative: - ld (ix+6),bc - ld bc,(ix-8) - ld hl,(ix+6) - jr c,.check - sbc hl,bc - jp nc,.skip ; if (x>=xmin && (unsigned)x>=x1) goto skip; - add hl,bc -.check: - inc hl - ld (ix-11),hl ; l = x+1; - xor a,a - sbc hl,bc - ld e,(ix+9) - jr nc,.badpush0 ; if (l draw location - ; do { -.forloop1start: - ld hl,ti.lcdWidth-1 -smcWord _XMaxMinus1 - jr .atov ; for (; (unsigned)x<=xmax && p(x, y) == ov; x++) { s(x, y); } -.forloop1: - ld a,0 -.newcolor1 = $-1 - ld (de),a - inc de - inc bc -.atov: - sbc hl,bc - jr c,.ovat - add hl,bc - ld a,(de) - cp a,0 -.oldcolor1 = $-1 - jr z,.forloop1 - -.ovat: - ld (ix+6),bc - lea de,ix-24 ; push(y, l, x-1, dy); - lea hl,iy - or a,a - sbc hl,de - jr nc,.badpush1 - ld a,(ix-4) - add a,(ix+9) - sub a,0 ; check if y coordinate is in bounds -smcByte _YMin - cp a,ti.lcdHeight -smcByte _YSpan - jr nc,.badpush1 - dec bc - ld (iy+3),bc - ld a,(ix+9) - ld (iy+6),a - ld bc,(ix-11) - ld (iy+0),bc - ld a,(ix-4) - ld (iy+7),a - lea iy,iy+8 -.badpush1: - ld hl,(ix-15) ; if (x>x2+1) { push(y, x2+1, x-1, -dy); } - ld bc,(ix+6) - inc hl - or a,a - sbc hl,bc - jr nc,.skip - lea de,ix-24 - lea hl,iy - or a,a - sbc hl,de - jr nc,.badpush2 - ld a,(ix+9) - sub a,(ix-4) - sub a,0 ; check if y coordinate is in bounds -smcByte _YMin - cp a,ti.lcdHeight -smcByte _YSpan - jr nc,.badpush2 - dec bc - ld (iy+3),bc - ld bc,(ix-15) - inc bc - ld (iy+0),bc - xor a,a - sub a,(ix-4) - ld (iy+7),a - ld a,(ix+9) - ld (iy+6),a - lea iy,iy+8 -.skip: -.badpush2: ; skip: for (x++; (unsigned)x<=x2 && p(x, y) != ov; x++); - ld bc,(ix+6) - inc bc - - ld hl,(CurrentBuffer) - add hl,bc - ld e,(ix+9) - ld d,ti.lcdWidth / 2 - mlt de - add hl,de - add hl,de - ex de,hl ; de -> draw location - ld hl,(ix-15) - - jr .whileloop -.forloop2: - inc bc - inc de -.whileloop: - or a,a - sbc hl,bc - add hl,bc - jr c,.done - ld a,(de) - cp a,0 -.oldcolor2 = $-1 - jr nz,.forloop2 - -.done: - ld (ix+6),bc - ld (ix-11),bc ; l = x; - or a,a - sbc hl,bc - jp nc,.forloop1start ; } while ((unsigned)x<=x2); - - ld hl,0 -.stack = $-3 - lea de,iy - or a,a - sbc hl,de - jp c,.dowhileloop ; } while (sp>stack); - -.return: - ld sp,ix - pop ix - ret - ;------------------------------------------------------------------------------- gfx_RLETSprite: ; Draws a sprite with RLE transparency with clipping.