home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 5 / DATAFILE_PDCD5.iso / demos / baah / CakeHead2 / Cake2_Src / RssPart < prev    next >
Encoding:
Text File  |  1996-02-02  |  20.1 KB  |  462 lines

  1. ;                                     \|/
  2. ;                                     O O
  3. ; --------------------------------oOO--U--OOo--------------------------------
  4. ; |                                                                         |
  5. ; |              Randomly Shaded Splines (RSS) Shape Blending.              |
  6. ; |                 By Alain BROBECKER and Frederic ELISEI.                 |
  7. ; |                    (Baah and Armoric of Arm's Tech)                     |
  8. ; |                                                             Sept-Oct 95 |
  9. ; ---------------------------------------------------------------------------
  10. ;
  11. ; The source code is separated in three parts, which are...
  12. ;     - the main demo. (Shape blending between splines)
  13. ;     - filaments code generation.
  14. ;     - routine which draws a RSS.
  15. ;
  16. ;   The main part is, as usual not all that interesting. The main idea
  17. ; behind it is a linear interpolation between the control brows of the
  18. ; different splines composing the objects. I must admit that this shape
  19. ; blending is totally user defined. (Look at RSS_Ed)
  20. ;   The intersting idea in here is to draw a spline with a fixed amount of
  21. ; random shadedots around each of the points in the spline. My first version
  22. ; was totally realtime, but I spent a week-end at ArmOric' s house and he
  23. ; gave me the idea to use generated code for each random shadedots filament.
  24. ;
  25. ; >-------------------------------------------------------------------------<
  26. ; The full credits are going like this...
  27. ;     - Idea and coding by Baah / Arm' s Tech.
  28. ;     - Generated code idea by Armoric / Arm's Tech.
  29. ;     - Spline rout by Baah, with inspiration from Jan / BASS.
  30.  
  31. #set        rss_shift=6             ; premul factor=n.
  32. #set        rss_nb_pts=129          ; nb of points in the spline=1+2^(n+1).
  33. ;#set        rss_time = 300          ; Time a shape stays on screen.
  34. #set        rss_splines_nb = 16     ; Nb of splines per shape.
  35. #set        rss_images_nb = 7       ; Nb of successive shapes.
  36. #set        rss_routs_nb = 32       ; Nb of filaments routines to generate/2.
  37. #set        rss_nb_rnd = 13         ; Nb of points drawn per generated rout.
  38.  
  39. ;****************************************************************************
  40. ;*****                                                                  *****
  41. ;*****                        RSS Shape Blending                        *****
  42. ;*****                                                                  *****
  43. ;****************************************************************************
  44. ; This is the part of the proggy which actually displays the forms on the
  45. ; screen, with shape blending between two shapes. It is not very hard to
  46. ; understand, so I won' t talk more here.
  47. ; Parameter for this demo part....
  48. ;        r0 = adress of a megabuffer used for creation of the generated code.
  49.  
  50. .rss_part
  51.   stmfd     r13!,{r0-r12,r14}
  52.   str       r0,_megabuffer_ad       ; Generate code for the filaments.
  53.   add       r0,r0,#rss_nb_pts*8
  54.   bl        rss_generate_code
  55.   adr       r2,_rss_colors          ; Change colors.
  56.   bl        set_palette
  57.  
  58. ._shape_blending
  59.   mov       r0,#64                  ; Nb of steps for one shape blending.
  60.   str       r0,_blend_counter
  61. ._blend_one_frame
  62.   bl        wait_and_swap           ; Wait vsync, swap screens, r0=workscreen.
  63.   mov       r1,#&ff
  64.   bl        clear_mode9             ; Clear screen.
  65.   adr       r1,_animation           ; r1=adress of current shape.
  66.   ldr       r2,_current_inc_ad      ; r2=adress of current increments.
  67.   mov       r14,#rss_splines_nb     ; Nb of splines to blend.
  68. ._blend_one_spline
  69.   ldmia     r1,{r3-r6}              ; The 'shape blending' is in fact
  70.   ldmia     r2!,{r7-r10}            ; a stupid linear interpolation between
  71.   add       r3,r3,r7                ; the control brows of two images.
  72.   add       r4,r4,r8
  73.   add       r5,r5,r9
  74.   add       r6,r6,r10
  75.   stmia     r1!,{r3-r6}
  76.   ldmia     r1,{r3-r6}
  77.   ldmia     r2!,{r7-r10}
  78.   add       r3,r3,r7
  79.   add       r4,r4,r8
  80.   add       r5,r5,r9
  81.   add       r6,r6,r10
  82.   stmia     r1!,{r3-r6}
  83.   subS      r14,r14,#1              ; One spline 'blended'.
  84.   bNE       _blend_one_spline
  85.  
  86. ; Time to draw the image on screen.
  87.   sub       r2,r1,#32*rss_splines_nb ; r2 points on current shape.
  88.   ldr       r10,_megabuffer_ad      ; A buffer needed by the RSS routine.
  89.   add       r1,r10,#rss_nb_pts*8    ; r1 points on the filaments routines.
  90.   mov       r12,#rss_splines_nb     ; Nb of splines to draw.
  91. ._blending_draw
  92.   bl        random_shade_spline
  93.   add       r2,r2,#8*4              ; Next spline coords.
  94.   subS      r12,r12,#1              ; It was last spline?
  95.   bNE       _blending_draw
  96.  
  97.   ldr       r0,_blend_counter       ; r0=nb of times still to blend.
  98.   subS      r0,r0,#1
  99.   strNE     r0,_blend_counter
  100.   bNE       _blend_one_frame
  101.  
  102. ; Prepare things for next shape blending.
  103. ._next_image
  104.   ldr       r0,_current_inc_ad
  105.   add       r0,r0,#32*rss_splines_nb
  106.   str       r0,_current_inc_ad
  107.   ldr       r0,_image_counter
  108.   subS      r0,r0,#1
  109.   cmp       r0,#1
  110.   ldmLEfd   r13!,{r0-r12,pc}        ; Quit if it was last image.
  111.   str       r0,_image_counter
  112.  
  113. ; Ok, we had better let the shape as is for some time, else the demolovers
  114. ; won' t be able to look at the wonderfull graphics.
  115.   bl        fix_time
  116. ._wait_one_frame
  117.   bl        wait_and_swap           ; Wait vsync, swap screens, r0=workscreen.
  118.   mov       r1,#&ff
  119.   bl        clear_mode9             ; Clear screen.
  120.   ldr       r10,_megabuffer_ad      ; A buffer needed by the RSS routine.
  121.   add       r1,r10,#rss_nb_pts*8    ; r1 points on the routines.
  122.   adr       r2,_animation
  123.   mov       r12,#rss_splines_nb     ; Nb of splines to draw.
  124. ._wait_draw
  125.   bl        random_shade_spline
  126.   add       r2,r2,#8*4              ; Next spline coords.
  127.   subS      r12,r12,#1              ; It was last spline?
  128.   bNE       _wait_draw
  129.   bl        read_time               ; r0=time elapsed.
  130.   cmp       r0,#rss_time
  131.   bLE       _wait_one_frame
  132.  
  133.   b         _shape_blending
  134.  
  135. ; ===========================================================================
  136. ; =                                                                         =
  137. ; =                               MAIN DATAS                                =
  138. ; =                                                                         =
  139. ; ===========================================================================
  140.  
  141. ._rss_colors
  142.   dcb       &ff,&ff,&aa,&ff,&ee,&88,&ff,&dd,&66,&ff,&cc,&44
  143.   dcb       &ff,&bb,&22,&ff,&aa,&00,&ee,&88,&00,&dd,&66,&00
  144.   dcb       &cc,&44,&00,&bb,&22,&00,&aa,&00,&00,&88,&00,&00
  145.   dcb       &66,&00,&00,&44,&00,&00,&22,&00,&00,&00,&00,&00
  146.  
  147. ._megabuffer_ad
  148.   dcd       0
  149.  
  150. ._animation
  151.   incbin    RSS_Ed.RSS_anim
  152.  
  153. ._blend_counter
  154.   dcd       0
  155.  
  156. ._image_counter
  157.   dcd       rss_images_nb
  158.  
  159. ._current_inc_ad
  160.   dcd       _animation+32*rss_splines_nb
  161.  
  162.  
  163. ;****************************************************************************
  164. ;*****                                                                  *****
  165. ;*****                          Code Generator                          *****
  166. ;*****                                                                  *****
  167. ;****************************************************************************
  168. ;
  169. ;   This routine creates a certain amount of routine which are drawing random
  170. ; filaments. This allows fast shading (on Arm2 it proves much faster) because
  171. ; we don' t need to perform the random walk of the filament in realtime, but
  172. ; instead we randomly choose a filament routine. Also, when we shade pixel
  173. ; we exactly know where it is in the byte, and it is much easier. (At first
  174. ; I was using a shadedot routine accessing to longwords, with lotsa masking
  175. ; and the like) So the generated code is a succession of...
  176. ;   x even    ldrB     r6,[r7,#offset]    ; Load byte.
  177. ;             tst      r6,#&f             ; 4 lowerbits of r1=0?
  178. ;             subNE    r6,r6,#1           ; No, then shade the pixie.
  179. ;             strB     r6,[r7,#offset]    ; And save modified byte.
  180. ;   x odd     ldrB     r6,[r7,#offset]    ; Load byte.
  181. ;             subS     r6,r6,#1<<4        ; Shade pixel in the 4 upperbits.
  182. ;             strPLB   r6,[r7,#offset]    ; If pixel color>=0, save byte.
  183. ;
  184. ;    As I said earlier the idea of generating code was brought up by ArmOric.
  185. ; He told it to me, and after the night we both came with exactly the same
  186. ; instruction sequence (the one above), so I doubt you can find something
  187. ; faster on Arm2. I must admit that before we went to sleep Fred was knowing
  188. ; the solution, but I asked him not to tell it to me, so that I proved myself
  189. ; I' m able to be as good as Fred. (I was a bit ashamed when Fred talked
  190. ; about using generated code, cos I' m supposed to be the expert in this!)
  191. ;   Anyway, again lots of thanks to Fred for his help.
  192. ;
  193. ; >-------------------------------------------------------------------------<
  194. ; Parameters of the generated routines...
  195. ;           r0=videoram adress of the start of the filament.
  196. ;           r14=return adress.
  197. ;           r1 will be modified!
  198. ;
  199. ; >-------------------------------------------------------------------------<
  200. ; Parameters of generating routine...
  201. ;           r0=adress of a buffer, which will contain the table of all
  202. ;              the routines adresses, and after this table, the code of
  203. ;              the generated routines.
  204. ;   The routines between 0 and (rss_rout_nb-1) assumes x pos is even, and
  205. ; routines between rss_rout_n and (2*rss_rout_nb-1) assumes x pos is odd.
  206.  
  207. .rss_generate_code
  208.   stmfd     r13!,{r0-r12,r14}       ; Clean...
  209.   str       r13,rss_old_stack
  210.   add       r1,r0,#rss_routs_nb*8   ; r1 points where to generate code.
  211.   adr       r2,rss_directions
  212.   ldmdb     r2,{r3,r4}              ; r3 and r4 are random germs.
  213.   adr       r5,_opcodes             ; r5 points on opcodes used.
  214.   mov       r6,#rss_routs_nb*2      ; Counts the nb of generated routs.
  215. ._gen_one_rout
  216.   str       r1,[r0],#4              ; Save adress of the routine.
  217.   mov       r7,#rss_nb_rnd          ; r7=nb of rnd points per filament.
  218.   mov       r8,#0                   ; r8=x pos of first pixie,
  219.   cmp       r6,#rss_routs_nb        ;   =0 for the first routs.
  220.   movLE     r8,#1                   ;   =1 for the last ones.
  221.   mov       r9,#0                   ; r9=y offset.
  222. ._gen_one_pixie
  223.   add       r10,r9,r8,asr #1        ; r10=offset.
  224.   tst       r8,#1                   ; Pixel in upperbits or lowerbits?
  225.   bEQ       _gen_up
  226. ; The pixel is in the 4 lowerbits. Generate code for it.
  227.   ldmia     r5,{r11-r13}            ; Load opcodes.
  228.   cmp       r10,#0                  ; Offset negative?
  229.   bicMI     r11,r11,#1<<23          ; Yes, then notify it in ldrB & strB.
  230.   bicMI     r13,r13,#1<<23
  231.   rsbMI     r10,r10,#0              ; r10=abs(offset).
  232.   add       r11,r11,r10             ; r11='ldrB r6,[r6,#offset]'.
  233.   add       r13,r13,r10             ; r14='strPLB r6,[r7,#offset]'.
  234.   stmia     r1!,{r11-r13}           ; Generate code.
  235.   and       r10,r3,#%111            ; r10=rnd(8).
  236.   add       r10,r2,r10,lsl #3       ; r10 points on the good direction.
  237.   ldmia     r10!,{r10,r11}          ; r10=dx | r11=dy.
  238.   add       r8,r8,r10               ; x_pos+=dx.
  239.   add       r9,r9,r11               ; y_offset+=dy.
  240.   add       r3,r4,r3,ror #3         ; Next random number.
  241.   mov       r3,r3,ror r4
  242.   eor       r4,r3,r4,ror #7
  243.   subS      r7,r7,#1                ; One pixie generated
  244.   bNE       _gen_one_pixie
  245.   ldr       r10,[r5,#12]            ; r10='mov pc,r14'.
  246.   str       r10,[r1],#4             ; Generate it.
  247.   subS      r6,r6,#1                ; One filament routine generated.
  248.   bNE       _gen_one_rout
  249.   ldr       r13,rss_old_stack       ; Finished...
  250.   ldmfd     r13!,{r0-r12,pc}
  251.  
  252. ; The pixel is in the 4 upperbits. Generate code for it.
  253. ._gen_up
  254.   ldmdb     r5,{r11-r14}            ; Load opcodes.
  255.   cmp       r10,#0                  ; Offset negative?
  256.   bicMI     r11,r11,#1<<23          ; Yes, then notify it in ldrB & strB.
  257.   bicMI     r14,r14,#1<<23
  258.   rsbMI     r10,r10,#0              ; r10=abs(offset).
  259.   add       r11,r11,r10             ; r11='ldrB r6,[r7,#offset]'.
  260.   add       r14,r14,r10             ; r14='strNEB r6,[r7,#offset]'.
  261.   stmia     r1!,{r11-r14}           ; Generate code.
  262.   and       r10,r3,#%111            ; r10=rnd(8).
  263.   add       r10,r2,r10,lsl #3       ; r10 points on the good direction.
  264.   ldmia     r10!,{r10,r11}          ; r10=dx | r11=dy.
  265.   add       r8,r8,r10               ; x_pos+=dx.
  266.   add       r9,r9,r11               ; y_offset+=dy.
  267.   add       r3,r4,r3,ror #3         ; Next random number.
  268.   mov       r3,r3,ror r4
  269.   eor       r4,r3,r4,ror #7
  270.   subS      r7,r7,#1                ; One pixie generated
  271.   bNE       _gen_one_pixie
  272.   ldr       r10,[r5,#12]            ; r10='mov pc,r14'.
  273.   str       r10,[r1],#4             ; Generate it.
  274.   subS      r6,r6,#1                ; One filament routine generated.
  275.   bNE       _gen_one_rout
  276.   ldr       r13,rss_old_stack       ; Finished....
  277.   ldmfd     r13!,{r0-r12,pc}
  278.  
  279. ; The opcodes used by the generated code.
  280.   ldrB      r6,[r7,#0]              ; Routine when x is even.
  281.   tst       r6,#&f
  282.   subNE     r6,r6,#1
  283.   strNEB    r6,[r7,#0]
  284. ._opcodes
  285.   ldrB      r6,[r7,#0]              ; Routine when x is odd.
  286.   subS      r6,r6,#1<<4
  287.   strPLB    r6,[r7,#0]
  288.   mov       pc,r14                  ; Well, mysterious instruction, huh?
  289.  
  290. .random_germs
  291.   dcd       &eb1a2c37,&3fd2a145
  292. .rss_directions
  293.   dcd       0,160,0,-160,1,0,-1,0
  294.   dcd       1,160,-1,160,1,-160,-1,-160
  295.  
  296. .rss_old_stack                      ; Well...
  297.   dcd       0
  298.  
  299.  
  300.  
  301.  
  302. ;****************************************************************************
  303. ;*****                                                                  *****
  304. ;*****                      Randomly Shaded Spline                      *****
  305. ;*****                                                                  *****
  306. ;****************************************************************************
  307. ;
  308. ;   This routine draws a randomly shaded spline. We calculate a fixed amount
  309. ; of points in the spline, and save them in a table. Then, for each of this
  310. ; point, we randomly choose a filament, and jump at the corresponding rout.
  311. ;   The clipping is performed individually for each filament. If the box
  312. ; around the point (and 'radius' of the box being maximum length of filament)
  313. ; is out of the screen or even partially clipped, we quite simply don' t draw
  314. ; the filament.
  315. ;   The full incremental spline calculation trick was found in a spline rout
  316. ; by Jan/BASS, and then rewritten by me. (I don' t have exactly the same
  317. ; spline formulas as Jan does) As usual, Jan' s code is a very good source
  318. ; of inspiration. :)
  319. ;   The x clipping was 'removed' because it was unusefull in this demo.
  320. ;
  321. ; >-------------------------------------------------------------------------<
  322. ; Parameters are...
  323. ;           r0=adress of workscreen.
  324. ;           r1=adress of the table of routines adresses.
  325. ;           r2=adress of spline control brows. (x0,y0,x1,y1,x2,y2,x3,y3)*64
  326. ;           r10=adress of a 129*2 longs buffer.
  327.  
  328. .random_shade_spline
  329.   stmfd     r13!,{r0-r12,r14}       ; Be clean or crash!
  330.   ldmia     r2,{r2-r9}              ; Load spline control brows.
  331.   mov       r2,r2,asr #6            ; Take integer part of their x coord.
  332.   mov       r4,r4,asr #6
  333.   mov       r6,r6,asr #6
  334.   mov       r8,r8,asr #6
  335. ;  cmp       r2,#320                 ; If all the control brows are on right
  336. ;  cmpGE     r4,#320                 ;   of the screen, then the whole spline
  337. ;  cmpGE     r6,#320                 ;   is on right of the screen ->quit.
  338. ;  cmpGE     r8,#320
  339. ;  ldmGEfd   r13!,{r0-r12,pc}
  340. ;  cmp       r2,#0                   ; Same comment when all brows on left.
  341. ;  cmpLT     r4,#0
  342. ;  cmpLT     r6,#0
  343. ;  cmpLT     r8,#0
  344. ;  ldmLTfd   r13!,{r0-r12,pc}
  345.   mov       r3,r3,asr #6            ; Take integer part of y coords.
  346.   mov       r5,r5,asr #6
  347.   mov       r7,r7,asr #6
  348.   mov       r9,r9,asr #6
  349.   cmp       r3,#256                 ; All brows below?..
  350.   cmpGE     r5,#256
  351.   cmpGE     r7,#256
  352.   cmpGE     r9,#256
  353.   ldmGEfd   r13!,{r0-r12,pc}
  354.   cmp       r3,#0                   ; Or above the screen.
  355.   cmpLT     r5,#0
  356.   cmpLT     r7,#0
  357.   cmpLT     r9,#0
  358.   ldmLTfd   r13!,{r0-r12,pc}
  359.  
  360. ; Now, using the coords of the control brows, we calculate the x and y
  361. ; compounds of the cubic spline coefficients, which are...
  362. ;     a0=p0
  363. ;     a1=4*p1-4*p0
  364. ;     a2=-p3+4*p2-8*p1+5*p0
  365. ;     a3=2*p3-4*p2+4*p1-2*p0
  366.   mov       r4,r4,lsl #2            ; r4=4x1.
  367.   sub       r11,r4,r2,lsl #1
  368.   add       r11,r11,r8,lsl #1
  369.   sub       r11,r11,r6,lsl #2       ; r11=a3x=2x3-4x2+4x1-2x0.
  370.   rsb       r6,r8,r6,lsl #2
  371.   add       r6,r6,r2,lsl #2
  372.   add       r6,r6,r2
  373.   sub       r6,r6,r4,lsl #1         ; r6=a2x=-x3+4x2-8x1+5x0.
  374.   sub       r4,r4,r2,lsl #2         ; r4=a1x=4x1-4x0.
  375.   mov       r5,r5,lsl #2            ; r5=4y1.
  376.   sub       r12,r5,r3,lsl #1
  377.   add       r12,r12,r9,lsl #1
  378.   sub       r12,r12,r7,lsl #2       ; r12=a3y=2y3-4y2+4y1-2y0.
  379.   rsb       r7,r9,r7,lsl #2
  380.   add       r7,r7,r3,lsl #2
  381.   add       r7,r7,r3
  382.   sub       r7,r7,r5,lsl #1         ; r7=a2y=-y3+4y2-8y1+5y0.
  383.   sub       r5,r5,r3,lsl #2         ; r5=a1y=4y1-4y0.
  384. ; So, here we have the following...
  385. ;     r2  = a0x  |  r3   = a0y
  386. ;     r4  = a1x  |  r5   = a1y
  387. ;     r6  = a2x  |  r7   = a2y
  388. ;     r11 = a3x  |  r12  = a3y
  389. ; Now, in order to work in a totally incremental way, we calculate
  390. ;     inc1=a1*h+a2*h^2+a3*h^3
  391. ;     inc2=2*a2*h^2+6*a3*h^3
  392. ;     inc3=6*a3*h^3
  393. ; Please note that we must convert all values in fixed point.
  394.   mov       r2,r2,lsl #rss_shift*3  ; r2=a0x.
  395.   add       r4,r6,r4,lsl #rss_shift
  396.   add       r4,r11,r4,lsl #rss_shift ; r4=inc1x=a1x*h+a2x*h^2+a3x*h^3.
  397.   add       r8,r11,r11,lsl #1
  398.   mov       r8,r8,lsl #1            ; r8=inc3x=6*a3x*h^3.
  399.   add       r6,r8,r6,lsl #rss_shift+1 ; r6=inc2x=2*a2x*h^2+6*a3x*h^3.
  400.   mov       r3,r3,lsl #rss_shift*3  ; r3=a0y.
  401.   add       r5,r7,r5,lsl #rss_shift
  402.   add       r5,r12,r5,lsl #rss_shift ; r5=inc1y=a1y*h+a2y*h^2+a3y*h^3.
  403.   add       r9,r12,r12,lsl #1
  404.   mov       r9,r9,lsl #1            ; r9=inc3y=6*a3y*h^3.
  405.   add       r7,r9,r7,lsl #rss_shift+1 ; r7=inc2y=2*a2y*h^2+6*a3y*h^3.
  406. ; It' s time to calculate the points of the spline and save them in the
  407. ; buffer pointed by r1. Note that in order to increase the number of points
  408. ; in a convenient way, half of them are calculated using a stupid linear
  409. ; interpolation. Less accurate, but a bit faster.
  410. #rept 64
  411.   add       r11,r2,r4,asr #1        ; [r10|r11]=M+0.5*inc1.
  412.   add       r12,r3,r5,asr #1
  413.   stmia     r10!,{r2,r3,r11,r12}    ; Save M and M+0.5*inc1.
  414.   add       r2,r2,r4                ; M=M+inc1.
  415.   add       r3,r3,r5
  416.   add       r4,r4,r6                ; inc1=inc1+inc2.
  417.   add       r5,r5,r7
  418.   add       r6,r6,r8                ; inc2=inc2+inc3.
  419.   add       r7,r7,r9
  420. #endr
  421.   stmia     r10!,{r2,r3}            ; Save the last point.
  422.  
  423. ; Time to draw the filaments of the spline.
  424. ; Here we have the following...
  425. ;     r0=adress of workscreen.
  426. ;     r1=adress of the table of routines adresses.
  427. ;     r10 points after the points coords.
  428.   sub       r2,r10,#rss_nb_pts*8    ; r2 points on the coords buffer.
  429.   adr       r3,random_germs
  430.   ldmia     r3,{r3,r4}              ; r3 & r4 are random numbers.
  431.   mov       r5,#rss_nb_pts          ; Nb of filaments to draw.
  432.   adr       r14,rss_one_set         ; Return adress.
  433. .rss_one_set
  434.   add       r3,r4,r3,ror #3         ; Next random number generation.
  435.   mov       r3,r3,ror r4
  436.   eor       r4,r3,r4,ror #7
  437.   subS      r5,r5,#1                ; One filament processed.
  438.   bMI       rss_the_end
  439.   ldmia     r2!,{r6,r7}             ; r6=x<<rss_shift*3 | r7=y<<rss_shift*3.
  440.   mov       r6,r6,asr #rss_shift*3  ; r6=int(x).
  441. ;  cmp       r6,#rss_nb_rnd          ; Set of pixels clipped or out?
  442. ;  bMI       rss_one_set
  443. ;  cmp       r6,#320-rss_nb_rnd
  444. ;  bGE       rss_one_set
  445.   mov       r7,r7,asr #rss_shift*3  ; r7=int(y).
  446.   cmp       r7,#rss_nb_rnd          ; Set of pixels clipped or out?
  447.   bMI       rss_one_set
  448.   cmp       r7,#256-rss_nb_rnd
  449.   bGE       rss_one_set
  450.   add       r7,r7,r7,lsl #2         ; Make r6 point on good byte.
  451.   add       r7,r0,r7,lsl #5
  452.   add       r7,r7,r6,asr #1
  453.   tst       r6,#1                   ; Flags=int(x) and 1.
  454.   and       r6,r3,#rss_routs_nb-1   ; r6=rnd(rss_routs_nb-1).
  455.   addNE     r6,r6,#rss_routs_nb
  456.   ldr       pc,[r1,r6,lsl #2]       ; Execute the chosen routine.
  457.  
  458. .rss_the_end
  459.   adr       r2,random_germs
  460.   stmia     r2,{r3,r4}              ; Save the modified random germs.
  461.   ldmfd     r13!,{r0-r12,pc}        ; The end.
  462.