home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 3 / PDCD_3.iso / utilities / utilsd / dithering / TestDither (.txt) < prev   
RISC OS BBC BASIC V Source  |  1994-02-08  |  15KB  |  425 lines

  1.  >TestDither
  2.  : Cy Booker
  3.  : 86 Church View
  4.  : Main Road
  5.  : Crockenhill
  6.  : Swanley
  7.  : Kent
  8.  : BR8 8 JW
  9.  run this in a 16 colour Wimp mode with default palette
  10.  the bottom half uses an accurate 2x2 dither algorithm
  11.  the top half uses ColourTrans
  12.  if change parameters to xdither_rgb then works in any mode/palette (upto 8bpp)
  13.  the suprising fact is that for 4bpp it looks as though we have changed
  14.  the working resolution from 0..255 to 0..65536 (extra 2.4 decimal places)
  15.  only doubles the "resolution"
  16.  all sub-routines conform to
  17.      parameters in R0, R1, R2, ...
  18.      returns in R0, R1, R2, ... [F0, F1, F2, ...]
  19.      corrupts R0-R3, ip, lr
  20.      preserves R4-R9, sl, gb, sp
  21.      if name has `x' prefix then
  22.              PSR_V set on SWI error, PSR_NZC undefined
  23.              PSR_V clear if OK,  PRS_NZC preserved
  24.      else if name has `v' prefix then
  25.              PSR_Z is state of R0, PSR_NCV preserved
  26.      else PSR_NZCV preserved
  27. $+ " ["+ 
  28. )+ "]"
  29.   sp = 13
  30.   lr = 14
  31. !3  gb = 12                       :
  32.  not APCS !!!
  33. "3  ip = 11                       :
  34.  not APCS !!!
  35.   PSR_V = &10000000
  36.   L% = 10240
  37.  code% L% : L% += code%
  38.  pass%= %1000 
  39.  %1010 
  40.     O% = 0 : P% = code%
  41.     [OPT pass%
  42.         
  43. udivide_255
  44.         
  45. udivide_3
  46.         
  47. udivmod
  48.         
  49. xdither_rgb
  50. .(        
  51. convert_paletteentry_to_rgb
  52. /(        
  53. convert_rgb_to_paletteentry
  54. 0E.Palette                        ; standard 16-colour wimp palette
  55.         EQUD    &FFFFFF00
  56.         EQUD    &DDDDDD00
  57.         EQUD    &BBBBBB00
  58.         EQUD    &99999900
  59.         EQUD    &77777700
  60.         EQUD    &55555500
  61.         EQUD    &33333300
  62.         EQUD    &00000000
  63.         EQUD    &99440000
  64.         EQUD    &00EEEE00
  65.         EQUD    &00CC0000
  66.         EQUD    &0000DD00
  67.         EQUD    &BBEEEE00
  68.         EQUD    &00885500
  69.         EQUD    &00BBFF00
  70.         EQUD    &FFBB0000
  71. .xdither
  72.         STMFD   (sp)!, {lr}
  73.         MOV     R3, #20
  74.         ADR     R4, Palette
  75.         MOV     R5, #4
  76.         BL      xdither_rgb
  77.         LDMvsFD (sp)!, {pc}
  78. H"        STMFD   (sp)!, {R0-R3}
  79. I"        STMFD   (sp)!, {R0-R3}
  80.         MOV     R0, #1 << 5
  81.         MOV     R1, sp
  82. L#        SWI     "XOS_SetColour"
  83. M"        ADD     sp, sp, #4*4*2
  84.         LDMFD   (sp)!, {pc}
  85. O        ]
  86.  pass%
  87.  s(2), e(2), c(2)
  88.   s() = 0.03, 0.80, 0.42
  89.   e() = 0.94, 0.05, 0.79
  90.  i%= 0 
  91.     s(i%) = 
  92.     e(i%) = 1 - (
  93. (1) < 0.7
  94. X        
  95.   nstep = 512
  96.  i= 0 
  97.  1.00 
  98.  1/nstep
  99.     c() = e()-s()
  100.     c() = i*c()
  101.     c() = c() + s()
  102.     A% = c(0)*&10000 + 0.5
  103.     B% = c(1)*&10000 + 0.5
  104.     C% = c(2)*&10000 + 0.5
  105.  xdither
  106. c(    
  107.  i*1024, 0, 1024/nstep, 512
  108.     A% = c(0)*&ff + 0.5
  109.     B% = c(1)*&ff + 0.5
  110.     C% = c(2)*&ff + 0.5
  111. gD    
  112.  "ColourTrans_SetGCOL", (A%<<8)+(B%<<16)+(C%<<24),,,&100,0
  113. h,    
  114.  i*1024, 512, 1024/nstep, 512  
  115.   *ScreenSave <d>.Tmp.screen
  116. link(a$):
  117. udivide_3
  118. [OPT pass%
  119. qS; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  120. r*; Calculates round(n/3) extremely fast
  121. ; In    R0 = n
  122. ; Out   R0 = round(n 
  123. .udivide_3
  124. x'        MOV     R2, R0, LSR #32 - 2
  125. y&        ADDS    R1, R0, R0, LSL #2
  126. zD        ADDcs   R2, R2, #1              ; R2.R1 = R0 * &00000005
  127. {'        ADD     R2, R2, R2, LSL #16
  128. |'        ADDS    R3, R1, R1, LSL #16
  129. }D        ADC     R2, R2, R1, LSR #32 - 16; R2.R3 = R0 * &00050005
  130. ~&        ADD     R2, R2, R2, LSL #8
  131. &        ADDS    R1, R3, R3, LSL #8
  132. D        ADC     R2, R2, R3, LSR #32 - 8 ; R2.R1 = R0 * &05050505
  133. &        ADD     R2, R2, R2, LSL #4
  134. &        ADDS    R3, R1, R1, LSL #4
  135. D        ADC     R0, R2, R1, LSR #32 - 4 ; R0.R3 = R0 * &55555555
  136. 6        ADDmi   R0, R0, #1              ; round up
  137.         MOVS    pc, lr
  138.     ]:= 0
  139. udivide_255
  140. [OPT pass%
  141. S; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  142. ,; Calculates round(n/255) extremely fast
  143. ; In    R0 = n
  144. ; Out   R0 = round(n 
  145.  255)
  146. .udivide_255
  147. '        MOV     R2, R0, LSR #32 - 8
  148. &        ADDS    R1, R0, R0, LSL #8
  149. D        ADDcs   R2, R2, #1              ; R2.R1 = R0 * &00000101
  150. '        ADD     R2, R2, R2, LSL #16
  151. '        ADDS    R3, R1, R1, LSL #16
  152. D        ADC     R0, R2, R1, LSR #32 - 16; R0.R3 = R0 * &01010101
  153. 6        ADDmi   R0, R0, #1              ; round up
  154.         MOVS    pc, lr
  155.     ]:= 0
  156. udivmod
  157. [OPT pass%
  158. R;~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
  159. ; In    R0 = unsigned
  160. #;       R1 = unsigned, non-zero
  161. 4; Out   R0 = R0 / R1 (rounded down towards zero)
  162. ;       R1 = R0 
  163. 6; Note  if R1 = 0 then get stuck in infinite loop!
  164. .udivmod
  165.         
  166. divrem(2, 0, 1, 3)
  167.         MOV     R1, R0
  168.         MOV     R0, R2
  169.         MOVS    pc, lr
  170.     ]:= 0
  171. xdither_rgb
  172.  L_TopLeft, L_BottomRight, L_TopRight, L_Mode, L_BPP
  173.  loop
  174.  first 3 words are accumulator (ie tl, tl+br, tl+br+tr)
  175.   L_TopLeft     = 3 << 2
  176.   L_BottomRight = 4 << 2
  177.   L_TopRight    = 5 << 2
  178. 7  L_Mode        = 6 << 2                :
  179.  implicit
  180. 7  L_BPP         = 7 << 2                :
  181.  implicit
  182. link("convert_paletteentry_to_rgb,convert_rgb_to_paletteentry,udivide_3")
  183. [OPT pass%
  184. S; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  185. R; Calculate a 2x2 dither pattern for an rgb given a mode and a palette pointer
  186. M; This routine needed since cant change palette when redirected output to
  187. ; sprite
  188. .; The algorithm based on colourtrans's, ie
  189. ;  tl = closest
  190. O;  br = 2.actual - tl              = actual - (tl - actual) = actual - diff
  191.  ;  tr = 2.actual - (tl+br)/2
  192. %;  bl = 2.actual - (tl+br+tr) / 3
  193. ; In    R0 = &000r.rrrr
  194. ;       R1 = &000g.gggg
  195. ;       R2 = &000b.bbbb
  196. ;       R3 = mode
  197. /;       R4 = pointer to colourtrans palette
  198. +;       R5 = bpp for mode {2, 4, 8, 16}
  199. 8; Out   R0 = top row of screen bytes (word expanded)
  200. ;;       R1 = bottom row of screen bytes (word expanded)
  201. ;       R2 = R0
  202. ;       R3 = R1
  203. .xdither_rgb
  204. :        STMFD   (sp)!, {R0, R1, R2, R3, R5, R6-R9, lr}
  205. J        LDMIA   (sp)!, {R6, R7, R8}             ; R6/R7/R8= rgb wanted
  206. #        SUB     sp, sp, #L_Mode
  207. /        BL      convert_rgb_to_paletteentry
  208. %        LDR     R1, [sp, #L_Mode]
  209.         MOV     R2, R4
  210. <        SWI     "XColourTrans_ReturnColourNumberForMode"
  211. $        Bvs     error_dither_rgb
  212. (        STR     R0, [sp, #L_TopLeft]
  213.         ;
  214. (        LDR     R0, [R4, R0, LSL #2]
  215. /        BL      convert_paletteentry_to_rgb
  216. B        STMIA   sp, {R0, R1, R2}                ; Stack tl rgb
  217. A        
  218. aux_dithers_rgb                       ; br = 2x - tl
  219. ,        STR     R0, [sp, #L_BottomRight]
  220.         ;
  221. (        LDR     R0, [R4, R0, LSL #2]
  222. /        BL      convert_paletteentry_to_rgb
  223. $        LDMIA   sp, {R3, ip, lr}
  224.         ADD     R0, R0, R3
  225.         ADD     R1, R1, ip
  226.         ADD     R2, R2, lr
  227. E        STMIA   sp, {R0, R1, R2}                ; Stack tl+br rgb
  228. "        MOVS    R0, R0, ASR #1
  229. K        ADDcs   R0, R0, #1                      ; ensure lsb is correct
  230. "        MOVS    R1, R1, ASR #1
  231.         ADDcs   R1, R1, #1
  232. "        MOVS    R2, R2, ASR #1
  233.         ADDcs   R2, R2, #1
  234. J        
  235. aux_dithers_rgb                       ; tr = 2x - (tl + br)/2
  236. )        STR     R0, [sp, #L_TopRight]
  237.         ;
  238. (        LDR     R0, [R4, R0, LSL #2]
  239. /        BL      convert_paletteentry_to_rgb
  240. $        LDMIA   sp, {R3, ip, lr}
  241. H        ADD     R5, R0, R3                      ; R5 = red(tl+br+tr)
  242. J        ADD     R9, R1, ip                      ; R9 = green(tl+br+tr)
  243. 4        ADD     R0, R2, lr                      
  244. Q        BL      udivide_3                       ; this ensures lsb is correct
  245. N        STR     R0, [sp, #8]                    ; stack blue(tl+br+tr) / 3
  246.         MOV     R0, R9 
  247.         BL      udivide_3
  248. O        STR     R0, [sp, #4]                    ; stack green(tl+br+tr) / 3
  249.         MOV     R0, R5
  250.         BL      udivide_3
  251.          LDMIB   sp, {R1, R2}
  252. K        
  253. aux_dithers_rgb                       ; bl = 2x - (tl+br+tr)/3
  254. $        LDR     R5, [sp, #L_BPP]
  255. ,        LDR     R2, [sp, #L_BottomRight]
  256. )        LDR     R3, [sp, #L_TopRight]
  257. (        LDR     R4, [sp, #L_TopLeft]
  258. C        
  259. R     R1, R2, R0, LSL R5              ; R1= bottom row
  260. @        
  261. R     R0, R3, R4, LSL R5              ; R0= top row
  262. .loop   ADD     R5, R5, R5
  263.         CMP     R5, #16
  264. K        
  265. Rls   R0, R0, R0, LSL R5              ; Expand into full words
  266. %        
  267. Rls   R1, R1, R1, L