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

 
Вот собственно оно - исходник на языке 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
}
А вот архив с исходником RW1, а также собранными TAP и TRD: 
gory_01_2006.zip (16K)