home *** CD-ROM | disk | FTP | other *** search
/ 17 Bit Software 2: Collection B / 17Bit_Collection_B.iso / files / 1843.dms / in.adf / Mandelbrot / ilbm_write.nd2 < prev    next >
Encoding:
Text File  |  1992-03-31  |  7.1 KB  |  228 lines

  1. \ Copyright 1989 NerveWare
  2. \ No portion of this code may used for commercial purposes,
  3. \ nor may any executable version of this code be disributed for 
  4. \ commercial purposes without the author's express written permission.
  5. \ This code is shareware, all rights reserved.
  6. \ Nick Didkovsky.
  7.  
  8. \ Some changes to Phil Burk's ilbm writing stuff.
  9. \ MOD: Put CMAP before BODY                                        ND 2/6/89
  10. \ MOD: split bitmap write into header, followed by cmap, then body ND 2/6/89
  11. \ MOD: bodyptr freeblock                                ND 2/18/89
  12.  
  13. \ MOD: Allocate memory for only 20 rows at a time,pack,write,repeat ND 3/28/89
  14. \ Memory allocation often ABORTed this program when user tried 
  15. \ to save a 640x400 mandelbrot image.  Instead of allocating a buffer
  16. \ for the whole image, these routines grab and process 20 rows of the image 
  17. \ at a time.  That way, the most that ever has to be allocated
  18. \ is 20 rows of a 640x400 image = 6400 bytes instead of all 400 rows = 128000.
  19. \ For lores 320x400 or 320x200, only need 4000 bytes.
  20. \ MOD: added CRNG chunks so dpaint won't hallucinate its own and crash. 5/3/89
  21.  
  22.  
  23. include? ilbm.write.bitmap jiff:ilbm_maker
  24. include? open.mandelscreen variscreen.jf
  25.  
  26. anew task_write-ilbm.ND
  27.  
  28. decimal
  29.  
  30. variable ND-PAD 16 allot    \ used to hold body size
  31. variable ND-CRNG-PAD 8 allot
  32.  
  33. \ These IFF.WRITE's are just like PLB's except they don't do an evenup 
  34. \ on #bytes. Only even-up when done, since these write's are called 
  35. \ once for every 20 rows.
  36.  
  37. : IFF.WRITE.ND ( addr #bytes -- #bytes , write to open IFF file)
  38.     iff-fileid @ -rot    fwrite
  39. ;
  40.  
  41. : IFF.WRITE?.ND ( addr #bytes -- , write to open IFF file or IFF.ERROR)
  42.     dup>r iff.write.nd r> -
  43.     IF ." IFF.WRITE?.ND failed!" cr iff.error
  44.     THEN
  45. ;
  46.  
  47. : ILBM.WRITE.BM.HEADER.ND ( bitmap -- , write BitMap header to file)
  48.    { bmap | bodyptr bsize -- }
  49. \ Write BitMapHeader
  50.     bmap ilbm-header ilbm.header.setup
  51.     ilbm-header sizeof() BitMapheader 'BMHD' iff.write.chunk
  52. ;
  53.  
  54. \ pack 20 rows up
  55. : BITMAP>BODY.20  { bmap bodyptr bsize compr startrow | bresult -- bsize'|-1 }
  56.     compr 0= compr 1 = OR 0=
  57.     IF ." Illegal compression = " compr . 0 exit
  58.     THEN
  59.     bodyptr -> bresult
  60.     startrow 20 + startrow    \ for 20 rows beginning at startrow
  61.     DO bmap ..@ bm_depth 0 ( for each plane )
  62.     DO
  63. \ next plane base
  64.         bmap .. bm_planes i cells + @ >rel ( src )
  65. \ offset to row
  66.         j bmap ..@ bm_bytesperrow * +
  67. \ place to put bytes
  68.             bodyptr  ( dst )
  69.         ( -- current-row body )
  70.         bmap ..@ bm_bytesperrow
  71.         bsize
  72.             compr 0=
  73.             IF pcopyrow  
  74.             ELSE packrow
  75.             THEN  ( -- dst' dst_many error? )
  76.         IF .s 2drop
  77.            -1 -> bresult
  78.            leave
  79.         THEN
  80.         -> bsize
  81.         -> bodyptr
  82.     LOOP
  83.     bresult 0= IF leave THEN
  84.     LOOP
  85.     bresult -1 -
  86.     IF bodyptr bresult -  ( calculate size )
  87.     ELSE -1
  88.     THEN
  89. ;
  90.  
  91.  
  92. : ILBM.MAKE.20.ROWS.ND { bmap bsize compr bodyptr startrow  --  bsize|-1 }
  93. \ Pack bitmap into BODY, 20 rows at a time
  94.         bmap bodyptr bsize compr startrow bitmap>body.20 dup -> bsize 0<
  95.         IF  bodyptr freeblock -1
  96.         ELSE bsize
  97.         THEN
  98. ;
  99.  
  100. variable even-up-byte
  101. : EVEN? ( num -- flag ) dup even-up = ;
  102.  
  103. \ Generate BODY in chunks of 20 rows, pack, write, repeat until done. ND
  104.  
  105. : ILBM.WRITE.BODY.ND ( bitmap -- , write BitMap BODY to ILBM, 20 row chunks )
  106.    { bmap | bodyptr bsizeout bsize -- }
  107. even-up-byte off
  108. \ remember where this chunk starts to update #bytes when done
  109.     iff.where                    ( -- BODYstartpos)
  110.     0 'BODY' iff.write.chkid            ( -- BODYstartpos)
  111.     0  ( memory type)
  112.     bmap ..@ bm_bytesPerRow  20 * bmap ..@ bm_depth *    
  113.     dup -> bsize allocblock ?dup     \ only 20 rows allocated
  114.         if -> bodyptr
  115. \                bsize . space ." bytes allocated" cr ( testing only)
  116.         else ." Couldn't allocate ILBM 20 row buffer" cr 
  117.              iff.close ABORT 
  118.         then
  119.     bmap ..@ bm_rows 20 /  0 DO        \ go by increments of 20 rows
  120.           bmap 
  121.      bsize 
  122.      ilbm-header ..@ bmh_compression 
  123.      bodyptr 
  124.      i 20 *             \ pass it the starting row#
  125.      ILBM.MAKE.20.ROWS.ND
  126.          -> bsizeout
  127.           bsizeout 0<
  128.          IF  ." ILBM.WRITE.BODY.ND - Couldn't make 'BODY'!" cr
  129.             iff.close iff.error
  130.          ELSE bodyptr bsizeout iff.write?.nd     \ tack on the new packed 20 rows
  131.         THEN
  132.     LOOP                    ( -- BODYstartpos)
  133. \ use nd-pad, calc BODY size, rewind, write it, fast forward, done!
  134.     dup>r            ( -- BODYstartpos) ( -r- BODYstartpos)
  135.     iff.where dup>r swap - 8 -    ( -- BODYsize)     ( -r- BODYstartpos endpos)
  136.     ND-PAD !            ( -- ,store size in pad)
  137.     r> r>            ( -- endpos BODYstartpos) ( -r- )
  138.     cell+ iff.seek        ( -- endpos ,go to count field)
  139.     ND-PAD cell iff.write?    ( -- endpos ,write BODY bytecount to file)
  140.     iff.seek            ( -- ,fastforward to end of BODY chunk)
  141. \ next line evens-up the file size
  142.     nd-pad @ even? if-not even-up-byte 1 iff.write?.nd    then    
  143.     bodyptr freeblock        ( -- ,cleanup)
  144. ;
  145.  
  146. \ CRNG chunk is:
  147.  
  148. \ WORD pad1   -- reserved for future use according to EA, store 0 here
  149. \ WORD rate   -- steps per second where decimal 16384 = 60 steps/sec
  150. \ WORD active -- store any nonzero value here to cycle colors
  151. \ UBYTE low   -- start cycling at this color register...
  152. \ UBYTE high  -- ... up through this color register
  153.  
  154. \ mandelbrot! iff images cycle from color reg 1 up through numcolors-1
  155.  
  156. \ create CRNG data depending on the number of colors in image
  157. : SET.CRNG.ND ( depth -- )
  158.   1- 2 swap ashift 1-            ( -- high color register)
  159.   nd-crng-pad 7 + c!            ( -- , store high color register)
  160.   1 nd-crng-pad 6 +  c!            ( -- , store low color register)
  161.   1 nd-crng-pad cell+  w!          ( -- , store active value)
  162.   $ 00002000 nd-crng-pad !        ( -- , store 0 and speed as 1 long word)
  163. ;
  164.  
  165. \ keep dpaint happy with stupid data
  166. : SET.CRNG.STUPID ( -- )
  167.   0 nd-crng-pad 7 + c!            ( -- , store high color register)
  168.   0 nd-crng-pad 6 +  c!            ( -- , store low color register)
  169.   1 nd-crng-pad cell+  w!          ( -- , store active value)
  170.   $ 00000AAA nd-crng-pad !        ( -- , store 0 and speed as 1 long word)
  171. ;
  172.  
  173. : ILBM.WRITE.ILBM.ND  { bmap ctable ctable# -- , write bitmap in ILBM file}
  174.     iff-fileid @ 0=
  175.     IF ." You must open an IFF file first using $IFF.OPEN" cr
  176.         abort
  177.     THEN
  178.     'ilbm' iff.begin.form  ( -- formpos )
  179.  
  180.   bmap ilbm.write.bm.header.nd
  181. \ Generate CMAP and write it.
  182.     ctable
  183.     IF  ctable pad ctable# ctable>cmap  ( use pad to pack cmap )
  184.         pad ctable# 3 * 'CMAP' iff.write.chunk
  185.     THEN
  186.  
  187. \ write one useful CRNG chunk for color cycling
  188.    bmap ..@ bm_depth set.crng.nd
  189.    nd-crng-pad 8 'CRNG' iff.write.chunk
  190. \ write three stupid CRNG chunks to keep dpaint happy
  191.    set.crng.stupid
  192.    nd-crng-pad 8 'CRNG' iff.write.chunk
  193.    nd-crng-pad 8 'CRNG' iff.write.chunk
  194.    nd-crng-pad 8 'CRNG' iff.write.chunk
  195.  
  196. \ Write Bitmap            ( -- formpos )
  197.     bmap ilbm.write.body.nd    ( -- formpos )
  198.  
  199. \ Close out 'FORM'
  200.     ( -- formpos ) iff.end.form
  201. ;
  202.  
  203. : $SCREEN>IFF.ND ( screen $filename -- , write screen IFF file )
  204.     new $iff.open
  205.     dup
  206.     .. sc_bitmap
  207.     swap .. sc_viewport
  208.     ..@ vp_colormap >rel
  209.     dup ..@ cm_ColorTable >rel
  210.     swap ..@ cm_count
  211.     ilbm.write.ilbm.ND
  212.     iff.close
  213. ;
  214.  
  215.  
  216. : TEST.SAVE ( -- )
  217. open.mandelscreen
  218. alldraw
  219. \ 0 0 gr.move
  220. \ 1 gr.color!
  221. \ 100 100 gr.draw
  222. \ 2 gr.color!
  223. \ 200 200 gr.draw
  224. new mscreen-ptr @ " ram:test2.iff" $screen>iff.nd
  225. close.mandelscreen
  226. ;
  227.