Shaos wrote:А потом портировал его на ZX-SpectrumShaos wrote:По просьбе Axora вспомнил и запрограммировал алгоритм генерации скал

Вот собственно оно - исходник на языке RW1 от 1 января 2006 года (исходнику уже больше года):
Code: Select all
robot "Gory"
author "Shaos"
+inc/rw1p2.rwi
+inc/rw1_std.rwi
@DX=256
@DY=192
@MAXT=512 // 16*16*2
@MAXP=867 // 17*17*3
@MAXS=51 // 17*3
@MAXG=256
@TRAN=128
@TRAM=16
@PIDX(2)=g_step*(((@1)*3)+((@2)*@MAXS))
main()
{
text "\ === Начало главной функции ==="
def ztile[9]
text "\ Массив COS[16] для вычисления косинусов сдвинутых на 6 бит"
def cos[16] = {64,60,45,23,0,-23,-45,-60,-64,-60,-45,-23,0,23,45,60}
text "\ Массив SIN[16] для вычисления синусов сдвинутых на 6 бит"
def sin[16] = {0,23,45,60,64,60,45,23,0,-23,-45,-60,-64,-60,-45,-23}
text "\ Массивы для треугольников и их вершин"
def p1[@MAXT]
def p2[@MAXT]
def p3[@MAXT]
def po[@MAXP]
text "\ Установить в качестве текущего цвета зеленый (с черным фоном)"
color #07
text "\ Начальные установки"
d_line = 0 // for DD()
g_step = 16
g_num = 1
g_m = @TRAM
g_a = 6
g_tmax = 1
p1[0] = @PIDX(0,0)
p2[0] = @PIDX(0,1)
p3[0] = @PIDX(1,1)
p1[1] = @PIDX(0,0)
p2[1] = @PIDX(1,0)
p3[1] = @PIDX(1,1)
g_buf = 0
text "\ Главный цикл"
while(1)
{
clr()
points()
drawtri()
say "PRESS SP,O,P or Q to quit"
text "\ Ожидание нажатия клавиши"
while(g_buf==0)
{
recv g_buf
}
if(N==@keyboard)
{
text "\ Клавиша нажата - анализ"
if(g_buf=='Q') break
if(g_buf==#20 && g_step > 1)
{
g_step = g_step>>1
g_num = 16/g_step
newtri()
}
if(g_buf=='O')
{
g_a = g_a + 1
if(g_a==16) g_a=0
}
if(g_buf=='P')
{
g_a = g_a - 1
if(g_a==-1) g_a=15
}
g_buf = 0
}
}
say "--- OK ---"
text "\ === Конец главной функции ==="
ret
}
clr()
{
text "\ --- CLR - Очистка экрана"
A = #D000 // Address of ztile ???
command @P2_TERMCLR
say "(c) 2005, A.A.SHABARSHIN "
text "\ --- CLR - Конец подпрограммы"
}
moveto() // A-x B-y
{
text "\ --- MOVETO - Запомнить начальные координаты"
last_x = A
last_y = B
text "\ --- MOVETO - Конец подпрограммы"
}
lineto() // A-x B-y
{
text "\ --- LINETO - Нарисовать линию из запомненных координат в заданные"
l_x = A
l_y = B
l_dx = 0
l_xlen = 0
if(l_x > last_x)
{
l_dx = 1
l_xlen = l_x - last_x
}
if(l_x < last_x)
{
l_dx = -1
l_xlen = last_x - l_x
}
l_dy = 0
l_ylen = 0
if(l_y > last_y)
{
l_dy = 1
l_ylen = l_y - last_y
}
if(l_y < last_y)
{
l_dy = -1
l_ylen = last_y - l_y
}
if(l_dy==0)
{
l_step = 0
l_mode = 1
}
if(l_dx==0)
{
l_step = 0
l_mode = 2
}
if(l_dx!=0 && l_dy!=0)
{
if(l_xlen > l_ylen)
{
l_step = (l_xlen<<7)/l_ylen
l_mode = 3
}
else
{
l_step = (l_ylen<<7)/l_xlen
l_mode = 4
}
}
l_curs = l_step
while(1)
{
if(last_x < 0 || last_x >= @DX || last_y <0 || last_y >= @DY) break
pixel last_x last_y
C = 0
if(l_dx >= 0 && l_x-last_x < 2) C=C+1
if(l_dx < 0 && last_x-l_x < 2) C=C+1
if(l_dy >= 0 && l_y-last_y < 2) C=C+1
if(l_dy < 0 && last_y-l_y < 2) C=C+1
if(C==2)
{
if(l_x!=last_x || l_y!=last_y)
{
pixel l_x l_y
last_x = l_x
last_y = l_y
}
break
}
if(l_mode==1)
{
last_x = last_x + l_dx
continue
}
if(l_mode==2)
{
last_y = last_y + l_dy
continue
}
if(l_mode==3)
{
last_x = last_x + l_dx
l_curs = l_curs - #80
if(l_curs < #80)
{
l_curs = l_curs + l_step
last_y = last_y + l_dy
}
continue
}
if(l_mode==4)
{
last_y = last_y + l_dy
l_curs = l_curs - #80
if(l_curs < #80)
{
l_curs = l_curs + l_step
last_x = last_x + l_dx
}
continue
}
say "LINE ERROR"
break
}
text "\ --- LINETO - Конец подпрограммы"
}
points()
{
text "\ --- POINTS - Пересчитать координаты точек для экрана"
for(B=0;B<=g_num;B++)
{
for(A=0;A<=g_num;A++)
{
p_idx=@PIDX(A,B)
p_x=A*g_step*g_m-@TRAN
p_y=B*g_step*g_m-@TRAN
p_z=(po[p_idx+2]>>8)&255
p_x1=p_x*cos[g_a]-p_y*sin[g_a]
p_y1=p_x*sin[g_a]+p_y*cos[g_a]
p_xe=128+p_x1/100
p_ye=14+20736/((p_y1>>6)+309)
p_ze=(p_z<<7)/309
po[p_idx]=p_xe
po[p_idx+1]=p_ye
po[p_idx+2]=(p_z<<8)|(p_ze&255)
}
}
text "\ --- POINTS - Конец подпрограммы"
}
newtri() // A - number of points
{
text "\ --- NEWTRI - Добавить следующую степень точности"
t_k = 0
t_m = g_step*g_m
t_d = t_m>>2
for(t_j=1;t_j<=g_num;t_j=t_j+2)
{
for(t_i=1;t_i<=g_num;t_i=t_i+2)
{
t_0_0 = @PIDX(t_i-1,t_j-1)
t_1_0 = @PIDX(t_i,t_j-1)
t_2_0 = @PIDX(t_i+1,t_j-1)
t_0_1 = @PIDX(t_i-1,t_j)
t_1_1 = @PIDX(t_i,t_j)
t_2_1 = @PIDX(t_i+1,t_j)
t_0_2 = @PIDX(t_i-1,t_j+1)
t_1_2 = @PIDX(t_i,t_j+1)
t_2_2 = @PIDX(t_i+1,t_j+1)
t_z00 = (po[t_0_0+2]>>8)&255
t_z01 = (po[t_0_2+2]>>8)&255
t_z10 = (po[t_2_0+2]>>8)&255
t_z11 = (po[t_2_2+2]>>8)&255
t_rand = R
t_z = ((t_z00+t_z10)>>1)-t_d+(t_rand%t_m)
if(t_z<0) t_z=0
if(t_z>255) t_z=255
po[t_1_0+2] = t_z<<8
t_rand = R
t_z = ((t_z00+t_z01)>>1)-t_d+(t_rand%t_m)
if(t_z<0) t_z=0
if(t_z>255) t_z=255
po[t_0_1+2] = t_z<<8
t_rand = R
t_z = ((t_z00+t_z11)>>1)-t_d+(t_rand%t_m)
if(t_z<0) t_z=0
if(t_z>255) t_z=255
po[t_1_1+2] = t_z<<8
t_rand = R
t_z = ((t_z10+t_z11)>>1)-t_d+(t_rand%t_m)
if(t_z<0) t_z=0
if(t_z>255) t_z=255
po[t_2_1+2] = t_z<<8
t_rand = R
t_z = ((t_z01+t_z11)>>1)-t_d+(t_rand%t_m)
if(t_z<0) t_z=0
if(t_z>255) t_z=255
po[t_1_2+2] = t_z<<8
p1[t_k] = t_0_0
p2[t_k] = t_0_1
p3[t_k] = t_1_1
t_k = t_k+1
p1[t_k] = t_0_0
p2[t_k] = t_1_0
p3[t_k] = t_1_1
t_k = t_k+1
p1[t_k] = t_1_0
p2[t_k] = t_1_1
p3[t_k] = t_2_1
t_k = t_k+1
p1[t_k] = t_1_0
p2[t_k] = t_2_0
p3[t_k] = t_2_1
t_k = t_k+1
p1[t_k] = t_0_1
p2[t_k] = t_0_2
p3[t_k] = t_1_2
t_k = t_k+1
p1[t_k] = t_0_1
p2[t_k] = t_1_1
p3[t_k] = t_1_2
t_k = t_k+1
p1[t_k] = t_1_1
p2[t_k] = t_1_2
p3[t_k] = t_2_2
t_k = t_k+1
p1[t_k] = t_1_1
p2[t_k] = t_2_1
p3[t_k] = t_2_2
t_k = t_k+1
}
}
g_tmax = t_k-1
text "\ --- NEWTRI - Конец подпрограммы"
}
drawtri()
{
text "\ --- DRAWTRI - Нарисовать треугольники"
for(t_i=0;t_i<=g_tmax;t_i++)
{
t_z1 = po[p1[t_i]+2]&255
t_y1 = po[p1[t_i]+1]-t_z1
t_x1 = po[p1[t_i]]
t_z2 = po[p2[t_i]+2]&255
t_y2 = po[p2[t_i]+1]-t_z2
t_x2 = po[p2[t_i]]
t_z3 = po[p3[t_i]+2]&255
t_y3 = po[p3[t_i]+1]-t_z3
t_x3 = po[p3[t_i]]
moveto(t_x1,t_y1)
lineto(t_x2,t_y2)
lineto(t_x3,t_y3)
lineto(t_x1,t_y1)
}
text "\ --- DRAWTRI - Конец подпрограммы"
}
dd()
{
A=0
B=d_line
C=1
command @P2_SETSAY
d_line=d_line+1
}