Created
January 30, 2022 23:34
-
-
Save samneggs/2af38c548c517772a12fa438fc0f22c4 to your computer and use it in GitHub Desktop.
Raycaster with assembly routines
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
#------------------------YouTube-3DSage---------------------------------------- | |
#Full video: https://youtu.be/PC1RaETIx3Y | |
from raycast_maps import All_Textures,mapW,mapF,mapC | |
import gc9a01 | |
from machine import Pin, SPI, PWM, WDT | |
import framebuf | |
from time import sleep_ms, sleep_us, ticks_diff, ticks_us, sleep | |
from micropython import const | |
import array | |
from usys import exit | |
import gc | |
from math import sin,cos,pi,radians,sqrt,tan | |
#-----------------------------MAP---------------------------------------------- | |
MAXSCREEN_X = const(240) | |
MAXSCREEN_Y = const(200) #140 | |
MAXSCREEN = const(MAXSCREEN_X*MAXSCREEN_Y*2) | |
YMAX= const(400) #400 # 320 | |
mapX = const(8) #map width | |
mapY = const(8) #map height | |
mapS = const(64) #map cube size | |
SCALE = const(3) | |
UPDATE_SPEED = const(120)#20 | |
TEXTURES = const(1) | |
BLUE = const(0x1f00) | |
BLACK = const(0) | |
WHITE = const(0xffff) | |
GREEN = const(0xe00A) | |
BROWN = const(0xe091) | |
RED = const(0x07e0) | |
YELLOW=const(0x00fe) | |
TEXTURE_HEIGHT = const(32*8) #47 | |
TEXTURE_WIDTH = const(32) #90 | |
#------joystck pin declaration----- | |
joyRight = Pin(17,Pin.IN) | |
joyDown = Pin(18,Pin.IN) | |
joySel = Pin(19,Pin.IN) | |
joyLeft = Pin(20,Pin.IN) | |
joyUp = Pin(21,Pin.IN) | |
char_map=array.array('b',( | |
0x3E, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x3E, 0x00, # U+0030 (0) | |
0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x00, # U+0031 (1) | |
0x1E, 0x33, 0x30, 0x1C, 0x06, 0x33, 0x3F, 0x00, # U+0032 (2) | |
0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E, 0x00, # U+0033 (3) | |
0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x78, 0x00, # U+0034 (4) | |
0x3F, 0x03, 0x1F, 0x30, 0x30, 0x33, 0x1E, 0x00, # U+0035 (5) | |
0x1C, 0x06, 0x03, 0x1F, 0x33, 0x33, 0x1E, 0x00, # U+0036 (6) | |
0x3F, 0x33, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00, # U+0037 (7) | |
0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00, # U+0038 (8) | |
0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00)) # U+0039 (9) | |
All_Textures_array=array.array('b',All_Textures) | |
mapF_array=array.array('b',mapF) | |
mapW_array=array.array('b',mapW) | |
mapC_array=array.array('b',mapC) | |
All_Textures.clear() | |
mapF.clear() | |
mapW.clear() | |
mapC.clear() | |
isin=array.array('i',range(0,361)) | |
icos=array.array('i',range(0,361)) | |
itan=array.array('i',range(0,361)) | |
class Player(): | |
def __init__(self): | |
self.px = 350 | |
self.py = 250 | |
self.pdx = 0 | |
self.pdy = 0 | |
self.pa = 70 | |
self.floor = 0 | |
player=Player() | |
# http://www.penguintutor.com/programming/picodisplayanimations | |
def blit_image_file(filename,width,height,cw,ch): # file width, file height, char width, char height | |
print(filename,gc.mem_free()) | |
with open (filename, "rb") as file: | |
file_position = 0 | |
char_position = 0 | |
ecount = 0 | |
current_byte = file.read(4) # header | |
#tex_buffz = file.read() | |
#tex_buff[:] = tex_buffz | |
while file_position < (width * height * 2): | |
current_byte = file.read(1) | |
# if eof | |
if len(current_byte) == 0: | |
break | |
# copy to buffer | |
tex_buff[char_position] = ord(current_byte) #and LCD.red | |
char_position += 1 | |
file_position += 1 | |
#if char_position == (cw * ch* 2): | |
# char_position = 0 | |
file.close() | |
#screen.blit(texture,50,50) | |
#tft.blit_buffer(screen, 20, 0, MAXSCREEN_X, MAXSCREEN_Y) | |
#exit() | |
def init_isin(): # integer sin lookup table | |
for i in range(0,361): | |
isin[i]=int(sin(radians(i))*(1<<14)) | |
def init_icos(): # integer cos lookup table | |
for i in range(0,361): | |
icos[i]=int(cos(radians(i))*(1<<14)) | |
def init_itan(): # integer cos lookup table | |
for i in range(0,361): | |
itan[i]=int(tan(radians(i))*(1<<14)) | |
def bl_ctrl(duty): | |
pwm = PWM(Pin(13)) | |
pwm.freq(1000) | |
if(duty>=100): | |
pwm.duty_u16(65535) | |
else: | |
pwm.duty_u16(655*duty) | |
@micropython.viper | |
def screen_fps(n:int,p:int): | |
dest=ptr16(screen)#screen | |
c_map=ptr8(char_map) | |
huns = n//100 | |
tens = int((0xcc_cccd*n)>>27) # n//10 | |
ones = n-(tens*10) # n%10 | |
row = 8 | |
offset=p*8+50 | |
while(row): | |
row-=1 | |
col=8 | |
while(col): | |
col-=1 | |
r=(row*MAXSCREEN_X+col)+offset | |
#if c_map[(huns<<3)+row] & 1<<col: | |
# dest[r] = 0# 0xffff | |
if c_map[(tens<<3)+row] & 1<<col: | |
dest[r+8] = 0# 0xffff | |
if c_map[(ones<<3)+row] & 1<<col: | |
dest[r+16] = 0 #0xffff | |
def fade(input_color1, input_color2): | |
color1=input_color1<<8 | input_color1>>8 # byte swap to normal RBG565 | |
red1 =color1>>11& 0b11111 # extract red #13 | |
green1=color1>>6 & 0b11111 # extract green | |
blue1 =color1 & 0b11111 # extract blue | |
color2=input_color2<<8 | input_color2>>8 # byte swap | |
red2 =color2>>11& 0b11111 # extract red | |
green2=color2>>6 & 0b11111 # extract green | |
blue2 =color2 & 0b11111 # extract blue | |
inc_red =(red2- red1)/31 # find increment step | |
inc_green=(green2-green1)/31 | |
inc_blue =(blue2- blue1)/31 | |
for i in range(0,32): | |
red3 =red1 +int(i*inc_red) # build colors by steps | |
green3=green1+int(i*inc_green) | |
blue3 =blue1 +int(i*inc_blue) | |
color3=red3<<11 | green3<<6 | blue3 # combine RGB | |
color_l2.append((color3 & 0x00FF)<<8 | (color3>>8)) # byte swap to LCD RGB565 | |
def drawMap2D(): | |
y=0 | |
while y<mapY: | |
x=0 | |
while x<mapX: | |
if mapW_array[player.floor+y*mapX+x]>0: | |
color=0xffff | |
else: | |
color=0 | |
xo=x*mapS//SCALE | |
yo=y*mapS//SCALE | |
screen.fill_rect(xo+1,yo+1, mapS//SCALE-1, mapS//SCALE-1,color) | |
x+=1 | |
y+=1 | |
def drawPlayer2D(): | |
x=int(player.px//SCALE) | |
y=int(player.py//SCALE) | |
dx=int(player.pdx*11//SCALE) | |
dy=int(player.pdy*10//SCALE) | |
screen.fill_rect(x,y, 5,5,YELLOW) | |
screen.line(x,y, x+dx, y+dy,YELLOW) | |
def Buttons(fps): | |
pushed=0 | |
if(joyLeft.value() == 0): #(key=='a'): | |
player.pa=limit_deg(player.pa+UPDATE_SPEED//fps) | |
player.pdx=cos(radians(player.pa)) | |
player.pdy=-sin(radians(player.pa)) | |
if(joyRight.value() == 0): #(key=='d') | |
player.pa=limit_deg(player.pa-UPDATE_SPEED//fps) | |
player.pdx=cos(radians(player.pa)) | |
player.pdy=-sin(radians(player.pa)) | |
xo=0 | |
if(player.pdx<0): | |
xo=-20 | |
else: | |
xo=20 #x offset to check map | |
yo=0 | |
if(player.pdy<0): | |
yo=-20 | |
else: | |
yo=20 #y offset to check map | |
ipx=int(player.px>>6) | |
ipx_add_xo=int((player.px+xo)>>6) | |
ipx_sub_xo=int((player.px-xo)>>6) #x position and offset | |
ipy=int(player.py>>6) | |
ipy_add_yo=int((player.py+yo)>>6) | |
ipy_sub_yo=int((player.py-yo)>>6) #y position and offset | |
if(joyUp.value() == 0): #(key=='w'): | |
if(mapW_array[player.floor+ipy*mapX + ipx_add_xo]==0): | |
player.px+=int(player.pdx*UPDATE_SPEED//fps) #TURN_SPEED | |
if(mapW_array[player.floor+ipy_add_yo*mapX + ipx ]==0): | |
player.py+=int(player.pdy*UPDATE_SPEED//fps) | |
if(joyDown.value() == 0):#(key=='s'): | |
if(mapW_array[player.floor+ipy*mapX + ipx_sub_xo]==0): | |
player.px-=int(player.pdx*UPDATE_SPEED//fps) | |
if(mapW_array[player.floor+ipy_sub_yo*mapX + ipx ]==0): | |
player.py-=int(player.pdy*UPDATE_SPEED//fps) | |
if(joySel.value() == 0): | |
if player.pdx<0: | |
xo=-25 | |
else: | |
xo=25 | |
if player.pdy<0: | |
yo=-25 | |
else: | |
yo=25 | |
ipx=player.px>>6 | |
ipx_add_xo=int((player.px+xo)>>6) | |
ipy=player.py>>6 | |
ipy_add_yo=int((player.py+yo)>>6) | |
if(mapW_array[player.floor+ipy_add_yo*mapX+ipx_add_xo]==4): | |
mapW_array[player.floor+ipy_add_yo*mapX+ipx_add_xo]=0 | |
if(mapW_array[player.floor+ipy_add_yo*mapX+ipx_add_xo]==5): | |
player.floor+=64 | |
gc.collect() | |
blit_image_file('floor'+str(player.floor>>6)+'.bin',32,32*8,32,32) | |
player.pa=limit_deg(player.pa+180) | |
return | |
if(mapW_array[player.floor+ipy_add_yo*mapX+ipx_add_xo]==6): | |
player.floor-=64 | |
gc.collect() | |
blit_image_file('floor'+str(player.floor>>6)+'.bin',32,32*8,32,32) | |
player.pa=limit_deg(player.pa+180) | |
return | |
@micropython.viper | |
def draw_walls(lineH:int,tx:int,ty:int,shade:int,hmt:int,r:int,lineOff:int,ty_step:int,disH:int): | |
dest=ptr16(screen) | |
color_addr=ptr16(color_l2) | |
all_addr=ptr8(All_Textures_array) | |
texture_addr=ptr16(tex_buff) | |
draw_ctl_addr=ptr32(draw_ctl) | |
y=0 | |
r2=r<<2 | |
tx2=tx%(31) | |
shade2=(disH>>4)//shade | |
draw_ctl_addr[0] = lineH | |
draw_ctl_addr[1] = tx2 | |
draw_ctl_addr[2] = ty | |
draw_ctl_addr[3] = shade | |
draw_ctl_addr[4] = hmt | |
draw_ctl_addr[5] = r2 | |
draw_ctl_addr[6] = lineOff | |
draw_ctl_addr[7] = ty_step | |
draw_ctl_addr[8] = disH | |
#draw_ctl_addr[9] = color | |
draw_ctl_addr[10] = int(player.floor) | |
draw_asm(dest,draw_ctl_addr,texture_addr) | |
return | |
while y<lineH: | |
#c=all_addr[((ty>>14)<<5) + tx]<<4 | |
if(hmt==0): | |
color=96 # floor (not for walls) | |
color2=texture_addr[(0*32*32)+(((ty>>14)-(((ty>>14)>>5)<<5))<<5) + tx2] | |
if(hmt==1): | |
color=64 # wall 1 | |
# | |
color2=texture_addr[(1*32*32)+(((ty>>14)-(((ty>>14)>>5)<<5))<<5) + tx2] | |
if(hmt==2): | |
color=128 # wall 2 | |
c=all_addr[((ty>>14)<<5) + tx]<<4 | |
color2=color_addr[color-c+shade2] | |
color2=texture_addr[(2*32*32)+((ty>>14)%(32))*TEXTURE_WIDTH + (tx%(TEXTURE_WIDTH-1))] | |
if(hmt==3): | |
color=32 #door | |
#color2=color_addr[color-c+shade2] | |
color2=texture_addr[(3*32*32)+((ty>>14)%(32))*TEXTURE_WIDTH + (tx%(TEXTURE_WIDTH-1))] | |
if(hmt==4): # up | |
color2=texture_addr[(4*32*32)+((ty>>14)%(32))*TEXTURE_WIDTH + (tx%(TEXTURE_WIDTH-1))] | |
if(hmt==5): # down | |
color2=texture_addr[(5*32*32)+((ty>>14)%(32))*TEXTURE_WIDTH + (tx%(TEXTURE_WIDTH-1))] | |
if(hmt==6): # special | |
color2=texture_addr[(6*32*32)+((ty>>14)%(32 ))*TEXTURE_WIDTH + (tx%(TEXTURE_WIDTH-1))] | |
# color2=color_addr[color-c+shade2] | |
pos=((y+lineOff)>>1)*MAXSCREEN_X+r2 | |
if pos<MAXSCREEN: | |
dest[pos]=color2 | |
dest[pos+1]=color2 | |
dest[pos+2]=color2 | |
dest[pos+3]=color2 | |
#screen.line(r*4,(y+lineOff)//2,r*4+4,(y+lineOff)//2,color2) # floor safe mode | |
ty+=ty_step | |
y+=1 | |
LINEH_CTL = const(0) # lineH | |
TX2_CTL = const(4) # tx2 | |
TY_CTL = const(8) # ty | |
SHADE_CTL = const(12) # shade | |
HMT_CTL = const(16) # hmt | |
R2_CTL = const(20) # r2 | |
LINEOFF_CTL = const(24) # lineOff | |
TY_STEP_CTL = const(28) # ty_step | |
DISH_CTL = const(32) # disH | |
COLOR_CTL = const(36) # color2 | |
FLOOR_CTL = const(40) # player.floor | |
draw_ctl=array.array('i',(0,4,8,12,16,20,24,28,32,36,40,0x421085,0,0,0)) | |
@micropython.asm_thumb | |
def draw_asm(r0,r1,r2): # r0=screen, r1=CTL array, r2=texture_addr | |
ldr(r3,[r1,HMT_CTL]) # r4=hmt | |
cmp(r3,0) | |
beq(EXIT) | |
mov(r4,1) | |
mov(r5,11) | |
lsl(r4,r5) # r4= 1<<11 = 2048 = 32*32*2 | |
mul(r4,r3) # r4= hmt * 2048 | |
add(r5,r2,r4) # r5= texture_addr += 32*32*2 | |
mov(r2,0) # r2=y | |
label(LOOP) | |
# pos=((y+lineOff)>>1)*MAXSCREEN_X+r2 | |
ldr(r3,[r1,LINEOFF_CTL]) # r3=lineOff | |
add(r3,r2,r3) # r3=y+lineOff | |
mov(r4,1) | |
asr(r3,r4) # r3=(y+lineOff)>>1 | |
mov(r4,MAXSCREEN_X) | |
mul(r3,r4) # r3=(y+lineOff)>>1*MAXSCREEN_X | |
ldr(r4,[r1,R2_CTL]) | |
add(r3,r3,r4) # r4=(y+lineOff)>>1*MAXSCREEN_X+r2 | |
add(r3,r3,r3) # double for 2 bytes per pixel | |
add(r7,r3,r0) # dest[...] | |
# color2=texture_addr[(((ty>>14)-(((ty>>14)>>5)<<5))<<5) + tx2 ] | |
label(TEXTURE) | |
ldr(r3,[r1,TY_CTL]) # r3=ty | |
ldr(r4,[r1,TY_STEP_CTL]) # r4=ty_step | |
add(r4,r4,r3) # ty+=ty_step | |
str(r4,[r1,TY_CTL]) # | |
mov(r4,14) | |
asr(r3,r4) # r3= ty>>14 | |
mov(r4,5) | |
mov(r6,r3) # r6= ty>>14 | |
asr(r6,r4) # r6= (ty>>14)>>5 | |
lsl(r6,r4) # r6= ((ty>>14)>>5)<<5 | |
sub(r6,r3,r6) # r6= (ty>>14)-(((ty>>14)>>5)<<5) | |
lsl(r6,r4) # r6= (ty>>14)-(((ty>>14)>>5)<<5)<<5 | |
ldr(r3,[r1,TX2_CTL]) # r3=tx2 | |
add(r6,r3,r6) # r6= (ty>>14)-(((ty>>14)>>5)<<5) + tx2 | |
add(r6,r6,r6) # double for ldrh | |
add(r6,r5,r6) # r6= texture_addr[...] | |
ldrh(r6,[r6,0]) # r6= color | |
strh(r6, [r7, 0]) # r7=screen | |
strh(r6, [r7, 2]) | |
strh(r6, [r7, 4]) | |
strh(r6, [r7, 6]) | |
add(r2,r2,1) # y+=1 | |
ldr(r3,[r1,LINEH_CTL]) | |
cmp(r2,r3) # while y<lineH: | |
blt(LOOP) | |
label(EXIT) | |
@micropython.viper | |
def draw_floor(y:int,px:int,py:int,fixang:int,deg:int,r:int): | |
dest=ptr16(screen) | |
cos_addr=ptr32(icos) | |
sin_addr=ptr32(isin) | |
mapf_addr=ptr8(mapF_array) | |
mapc_addr=ptr8(mapC_array) | |
all_addr=ptr8(All_Textures_array) | |
color_addr=ptr16(color_l2) | |
texture_addr=ptr16(tex_buff) | |
px2=px>>1 | |
py2=py>>1 | |
cos_deg=cos_addr[deg]*158*32 | |
sin_deg=sin_addr[deg]*158*32 | |
cos_fixang=cos_addr[fixang] | |
r4=r<<2 | |
while(y<400): | |
dy=y-200 | |
tx=px2 + (cos_deg//(dy*cos_fixang)) | |
ty=py2 - (sin_deg//(dy*cos_fixang)) | |
#mp=mapf_addr[(ty>>5)*mapX+(tx>>5)]<<10 | |
#c=all_addr[((ty%31)<<5) + (tx%31)+mp]*color_addr[160+(dy>>3)] | |
c=texture_addr[((ty%(32-1))<<5) + (tx%(TEXTURE_WIDTH-1))] | |
pos=(y>>1)*MAXSCREEN_X+r4 | |
if pos<MAXSCREEN: | |
dest[pos]=c | |
dest[pos+1]=c | |
dest[pos+2]=c | |
dest[pos+3]=c | |
#mp=mapc_addr[(ty>>5)*mapX+(tx>>5)]<<10 | |
#c=texture_addr[(ty%(TEXTURE_HEIGHT-1))*TEXTURE_WIDTH + (tx%(TEXTURE_WIDTH-1))] | |
#pos=((400-y)>>1)*MAXSCREEN_X+r4 | |
#dest[pos]=c | |
#dest[pos+1]=c | |
#dest[pos+2]=c | |
#dest[pos+3]=c | |
#screen.line(r*4,y//3,r*4+4,y//3,c) # working floor | |
y+=2 | |
@micropython.viper | |
def limit_deg(deg:int)->int: | |
if(deg>359): | |
deg-=360 | |
if(deg<0): | |
deg+=360 | |
return deg | |
#rx,ry,disV,vmt | |
RX_IND = const(0) | |
RY_IND = const(1) | |
DISV_IND = const(2) | |
VMT_IND = const(3) | |
output_array=array.array('i',(0,0,0,0)) | |
@micropython.viper | |
def test_ray1(ra:int): | |
cos_addr=ptr32(icos) | |
sin_addr=ptr32(isin) | |
tan_addr=ptr32(itan) | |
color_addr=ptr16(color_l2) | |
mapW_addr=ptr8(mapW_array) | |
outputs_addr=ptr32(output_array) | |
pa=int(player.pa) | |
px=int(player.px) | |
py=int(player.py) | |
vmt=0 | |
hmt=0 #vertical and horizontal map texture number | |
dof=0 | |
side=0 | |
disV=100000 | |
cos_ra=cos_addr[ra] | |
sin_ra=sin_addr[ra] | |
Tan=tan_addr[ra] | |
if cos_ra > 16: # 0.001: | |
rx=((px>>6)<<6)+64 | |
ry=(((px-rx)*Tan)>>14)+py | |
xo= 64 | |
yo=-1*((xo*Tan)>>14) #looking left | |
elif cos_ra< -16: #-0.001: | |
rx=((px>>6)<<6)-1 #-0.0001 <--!!!! | |
ry=(((px-rx)*Tan)>>14)+py | |
xo=-64 | |
yo=-1*((xo*Tan)>>14) #looking right | |
else: | |
rx=px | |
ry=py | |
dof=8 #looking up or down. no hit | |
while(dof<8): | |
mx=int(rx)>>6 | |
my=int(ry)>>6 | |
mp=my*mapX+mx | |
if(mp>0 and mp<mapX*mapY and mapW_addr[int(player.floor)+mp]>0): | |
vmt=mapW_addr[int(player.floor)+mp]-1 | |
dof=8 | |
disV=((cos_ra*(rx-px))>>14)-((sin_ra*(ry-py))>>14) #hit | |
else: | |
rx+=xo | |
ry+=yo | |
dof+=1 #check next horizontal | |
outputs_addr[RX_IND]=rx | |
outputs_addr[RY_IND]=ry | |
outputs_addr[DISV_IND]=disV | |
outputs_addr[VMT_IND]=vmt | |
# rx,ry,disV,vmt | |
@micropython.viper | |
def draw_rays(): | |
#int r,mx,my,mp,dof,side; float vx,vy,rx,ry,ra,xo,yo,disV,disH; | |
cos_addr=ptr32(icos) | |
sin_addr=ptr32(isin) | |
tan_addr=ptr32(itan) | |
color_addr=ptr16(color_l2) | |
mapW_addr=ptr8(mapW_array) | |
inputs_addr=ptr32(output_array) | |
pa=int(player.pa) | |
px=int(player.px) | |
py=int(player.py) | |
ra=int(limit_deg(pa+30)) #ray set back 30 degrees | |
for r in range(60): | |
#---Vertical--- | |
vmt=0 | |
hmt=0 #vertical and horizontal map texture number | |
dof=0 | |
disV=100000 | |
cos_ra=cos_addr[ra] | |
sin_ra=sin_addr[ra] | |
Tan=tan_addr[ra] | |
test_ray1(ra) | |
rx=int(inputs_addr[RX_IND]) | |
ry=int(inputs_addr[RY_IND]) | |
disV=int(inputs_addr[DISV_IND]) | |
vmt=int(inputs_addr[VMT_IND]) | |
vx=rx | |
vy=ry | |
#---Horizontal--- | |
dof=0 | |
disH=100000 | |
if Tan!=0: | |
Tan=((1<<28)//Tan) | |
if sin_ra> 16: #0.001: | |
ry=((py>>6)<<6) -1 #-0.0001 <--!!! | |
rx=(((py-ry)*Tan)>>14)+px | |
yo= -64 | |
xo=-1*((yo*Tan)>>14) #looking up | |
elif sin_ra < -16: #-0.001: | |
ry=((py>>6)<<6)+64 | |
rx=(((py-ry)*Tan)>>14)+px | |
yo= 64 | |
xo=-1*((yo*Tan)>>14) #looking down | |
else: | |
rx=px | |
ry=py | |
dof=8 #looking straight left or right | |
while(dof<8): | |
mx=rx>>6 | |
my=ry>>6 | |
mp=my*mapX+mx | |
if(mp>0 and mp<(mapX*mapY) and mapW_addr[int(player.floor)+mp]>0): | |
hmt=mapW_addr[int(player.floor)+mp]-1 | |
dof=8 | |
disH=((cos_ra*(rx-px))>>14)-((sin_ra*(ry-py))>>14) | |
else: | |
rx+=xo | |
ry+=yo | |
dof+=1 #check next horizontal | |
shade=1 | |
color=RED | |
if(disV<disH): | |
hmt=vmt | |
shade=2 # 0.5 | |
rx=vx | |
ry=vy | |
disH=disV | |
#screen.line(int(px//SCALE),int(py//SCALE),int(rx//SCALE),int(ry//SCALE),GREEN) #draw 2D ray | |
ca=int(limit_deg(pa-ra)) | |
disH=(disH*cos_addr[ca])>>14 #fix fisheye | |
lineH = ((mapS*YMAX))//disH | |
if lineH!=0: | |
ty_step=(32<<14)//lineH | |
ty_off=0 | |
if(lineH>YMAX): | |
ty_off=(lineH-YMAX)>>1 | |
lineH=YMAX #Line height and limit | |
lineOff = int(200 - (lineH>>1)) #line offset (160) | |
#Draw Walls | |
tx=0 | |
ty=(ty_off*ty_step)+((hmt*32)<<14) | |
if shade==1: | |
tx=int(rx>>1)%32 | |
if ra>180: | |
tx=31-tx | |
else: | |
tx=int(ry>>1)%32 | |
if ra>90 and ra<270: | |
tx=31-tx | |
draw_walls(lineH,tx,ty,shade,hmt,r,lineOff,ty_step,disH) # 800uS | |
#---draw floors--- | |
y=lineOff+lineH | |
fixang=int(limit_deg(pa-ra)) | |
draw_floor(y,px,py,fixang,ra,r) # 300uS | |
#screen.fill_rect((r*4),lineOff//SCALE,4,(lineH)>>1,color_addr[int(disH)>>4]) # fast shaded line walls KEEP | |
ra=int(limit_deg(ra-1)) #go to next ray | |
if __name__=='__main__': | |
spi = SPI(1, baudrate=63_000_000, sck=Pin(10), mosi=Pin(11)) | |
tft = gc9a01.GC9A01( | |
spi, | |
MAXSCREEN_X, | |
240, | |
reset=Pin(12, Pin.OUT), | |
cs=Pin(9, Pin.OUT), | |
dc=Pin(8, Pin.OUT), | |
backlight=Pin(13, Pin.OUT), | |
rotation=0) | |
tft.init() | |
tft.rotation(0) | |
tft.fill(gc9a01.BLUE) | |
bl_ctrl(50) | |
sleep(0.5) | |
display_buffer=bytearray(MAXSCREEN_X * MAXSCREEN_Y * 2) | |
screen=framebuf.FrameBuffer(display_buffer, MAXSCREEN_X , MAXSCREEN_Y, framebuf.RGB565) | |
tex_buff=bytearray(TEXTURE_WIDTH*TEXTURE_HEIGHT*2) | |
texture=framebuf.FrameBuffer(tex_buff,TEXTURE_WIDTH,TEXTURE_HEIGHT,framebuf.RGB565) | |
blit_image_file('floor'+str(player.floor>>6)+'.bin',32,32*8,32,32) | |
fps=0 | |
color_l2 = array.array('H', []) | |
fade(BROWN,BLACK) # 0 | |
fade(GREEN,BLACK) # 32 | |
fade(YELLOW,BLACK) # 64 | |
fade(RED,BLACK) # 96 | |
fade(BLUE,BLACK) # 128 | |
fade(BLACK,WHITE) # 160 | |
init_isin() | |
init_icos() | |
init_itan() | |
wdt = WDT(timeout=8300) # Watchdog timer reset | |
gticks=ticks_us() | |
txt='PI PICO ' | |
t=0 | |
while(1): | |
wdt.feed() | |
#screen.fill(0) # 3580 uS | |
screen.fill_rect(0,0,MAXSCREEN_X-1,90,BLUE) #1480 uS sky | |
#screen.fill_rect(0,90,MAXSCREEN_X,MAXSCREEN_X-50,GREEN) #solid floor | |
#drawMap2D() | |
#drawPlayer2D() | |
#drawRays2D(0) | |
#textontexture(fps) | |
draw_rays() # 50000 uS | |
Buttons(fps+1) # 800uS | |
screen_fps(fps,8) # 180uS | |
tft.blit_buffer(screen, 0, 20, MAXSCREEN_X, MAXSCREEN_Y) # 16600uS 240x200 | |
fps=1_000_000//ticks_diff(ticks_us(), gticks) | |
gticks=ticks_us() | |
# gc.collect() | |
# print(gc.mem_free()) | |
# exit() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment