Created
December 13, 2021 01:24
-
-
Save samneggs/0ccdd47f924d23f8f490049743af4c3d to your computer and use it in GitHub Desktop.
Flying Filled Triangle in Viper with Assembly Conversion (core routine)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@micropython.viper | |
def fill_triangle(obj_source, width_source:int,color_offset:int, y_start:int): | |
source=ptr16(obj_source) | |
c=ptr16(color_l2) | |
y=y_start-2 | |
start_inside = 0 | |
while y: | |
x=width_source | |
inside=0 | |
erase = 0 | |
old_color=0 | |
color = 0 | |
while x: | |
i=y*width_source+x | |
if erase: | |
source[i]=c[(y+((color_offset*x)>>8))>>2] # erase color with background | |
x-=1 | |
continue | |
old_color=color | |
color=source[i] | |
if old_color and not color: # transistion off of line | |
if not inside: | |
start_inside = x | |
source[i]=c[(y+((color_offset*x)>>8))>>2] # fill outside | |
inside^=1 | |
elif inside: | |
source[i]=c[((start_inside-x)>>2)+32]#//6+32] # fill inside | |
if x==1: | |
inside = 0 | |
x=start_inside # go back to last edge | |
erase =1 # erase to end of row | |
else: | |
source[i]= c[(y+((color_offset*x)>>8))>>2] | |
x-=1 | |
y-=1 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CTL_HEIGHT =const(0) | |
CTL_COLOR_OFFSET=const(2) | |
CTL_OLD_COLOR =const(4) | |
CTL_NEW_COLOR =const(6) | |
CTL_START_INSIDE=const(8) | |
CTL_INSIDE =const(10) | |
CTL_ERASE =const(12) | |
CTL_THREAD =const(14) | |
# control CTL_HEIGHT,CTL_COLOR_OFFSET,CTL_OLD_COLOR, CTL_NEW_COLOR, CTL_START_INSIDE, CTL_INSIDE, CTL_ERASE | |
control=array.array('h',(SCREEN_CHUNK_H,0,0,0,0,0,0,1)) | |
control2=array.array('h',(SCREEN_CHUNK_H,0,0,0,0,0,0,0)) | |
@micropython.asm_thumb | |
def color_asm(r0,r1,r2): # r0=screen address,r1= color_l2 address, r2 = control | |
ldrh(r3, [r2, CTL_HEIGHT]) # r3 = working height from control | |
ldrh(r4, [r2, CTL_THREAD]) | |
sub(r3,r3,r4) | |
label(HLOOP) # height loop | |
mov(r4,0) # | |
strh(r4, [r2, CTL_INSIDE]) # inside=0 | |
strh(r4, [r2, CTL_OLD_COLOR]) # old_color=0 | |
strh(r4, [r2, CTL_NEW_COLOR]) # new_color=0 | |
strh(r4, [r2, CTL_ERASE]) # erase=0 | |
ldrh(r6, [r2, CTL_HEIGHT]) # r6 = working width from control (same as height) | |
label(WLOOP) # width loop | |
ldrh(r5, [r2, CTL_ERASE]) # recolor background | |
cmp(r5,0) | |
beq(NOT_ERASE) | |
bl(BACKCOLOR) | |
b(NEXT) | |
label(NOT_ERASE) | |
ldrh(r5, [r2, CTL_NEW_COLOR]) # r5 = new_color | |
strh(r5, [r2, CTL_OLD_COLOR]) # store in old_color | |
bl(SCREEN_ADDR) # r4= screen addr | |
ldrh(r5, [r4, 0]) # get color | |
strh(r5, [r2, CTL_NEW_COLOR]) # store in new_color | |
cmp(r5,0) | |
beq(CHECK_INSIDE) # skip if =0 | |
ldrh(r5, [r2, CTL_OLD_COLOR]) # r5 = new_color | |
cmp(r5,0) | |
bgt(CHECK_INSIDE) # skip if >0 | |
ldrh(r4, [r2, CTL_INSIDE]) # load inside | |
cmp(r4,1) | |
beq(INVERT_INSIDE) | |
strh(r6, [r2, CTL_START_INSIDE]) # start_inside = x | |
bl(BACKCOLOR) | |
label(INVERT_INSIDE) # inside^=1 | |
ldrh(r4, [r2, CTL_INSIDE]) | |
mov(r5,1) | |
eor(r4,r5) | |
strh(r4, [r2, CTL_INSIDE]) | |
b(NEXT) | |
label(CHECK_INSIDE) | |
ldrh(r4, [r2, CTL_INSIDE]) # inside==1? | |
cmp(r4,0) | |
beq(OUTSIDE) | |
label(INSIDE_COLOR) | |
cmp(r6,1) | |
bne(SKIP_ERASE) | |
mov(r4,0) | |
strh(r4, [r2, CTL_INSIDE]) # inside = 0 | |
ldrh(r6, [r2, CTL_START_INSIDE]) # x=start_inside | |
mov(r4,1) | |
strh(r6, [r2, CTL_ERASE]) # erase = 1 | |
b(NEXT) | |
label(SKIP_ERASE) | |
ldrh(r5, [r2, CTL_START_INSIDE]) # start_inside | |
sub(r5,r5,r6) # start_inside-x | |
asr(r5,r5,1) # (start_inside-x)>>1 | |
mov(r4,32)#32 | |
add(r5,r5,r4) | |
mov(r4, 0x1) # | |
bic(r5,r4) # align to even bit | |
bl(SCREEN_ADDR) # r4= screen addr | |
add(r5,r5,r1) # color_l2[r5] | |
ldrh(r5, [r5, 0]) | |
strh(r5, [r4, 0]) # screen[r0]=r4 | |
b(NEXT) | |
label(OUTSIDE) | |
bl(BACKCOLOR) | |
label(NEXT) | |
sub(r6,1) # dec working width | |
bgt(WLOOP) | |
sub(r3,2) # dec working height | |
bgt(HLOOP) | |
b(EXIT) | |
label(BACKCOLOR) # uses r4,r5,r6 calcs and writes pixel | |
ldrh(r5, [r2, CTL_COLOR_OFFSET]) # r5 = color_offset from control | |
mul(r5,r6) # color_offset*x | |
asr(r5,r5,8) # (color_offset*x)>>8) | |
add(r5,r5,r3) # (y+((color_offset*x)>>8) | |
asr(r5,r5,1) # (y+((color_offset*x)>>8))>>2 | |
mov(r4, 0x1) # | |
bic(r5,r4) # align to even bit | |
add(r5,r5,r1) # color_l2 + (y+((color_offset*x)>>8))>>2 | |
ldrh(r5, [r5, 0]) # r5 = color[r5] | |
label(SCREEN) # writes r5 to screen address | |
ldrh(r4, [r2, CTL_HEIGHT]) # height | |
mul(r4,r3) # y*height | |
add(r4,r4,r6) # (y*height)+x | |
add(r4,r4,r4) # double for 2 bytes | |
add(r4,r4,r0) # add to screen address | |
strh(r5, [r4, 0]) # screen[r0]=r4 | |
bx(lr) | |
label(SCREEN_ADDR) # returns screen address in r4 | |
ldrh(r4, [r2, CTL_HEIGHT]) # height | |
mul(r4,r3) # y*height | |
add(r4,r4,r6) # (y*height)+x | |
add(r4,r4,r4) # double for 2 bytes | |
add(r4,r4,r0) # add to screen address | |
bx(lr) | |
label(EXIT) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment