'CHAOS.INC


  'CRC-32
  =======
  'http://wiki.osdev.org/CRC32
  'https://www.lammertbies.nl/comm/info/crc-calculation.html

  int crc32_table[0x100]
  '
  void init_crc32_table()
  {
  % Polynomial = 0x04c11db7
  addr rsi,crc32_table
  xor edi,edi
  .ri
   cmp edi,255
   jg ni
   '
   'reflect8
   mov ecx,8
   xor eax,eax
   mov edx,edi
   .rf8
    shl dl,1
    rcr eax,1
    dec ecx
   jg rf8
   '
   mov ecx,8
   .rj
    dec ecx
    jl fwd nj
    shl eax,1
    jnc rj
    xor eax,Polynomial
   jmp rj
   .nj
   '
   'reflect32
   mov ecx,32
   mov edx,eax
   xor eax,eax
   '
   .rf32
    shl edx,1
    rcr eax,1
    dec ecx
   jg rf32
   '
   mov [rsi],eax
   add rsi,4
   inc edi
   jmp ri
   .ni
  }
  init_crc32_table


  int crc32(sys p,le)
  {
   mov ecx,le
   mov rsi,p
   mov eax,0xffffffff
   addr rdi,crc32_table
   .ri
    dec ecx
    jl fwd xi
    mov edx,eax
    xor dl,[rsi]
    and rdx,0xff
    shr eax,8
    xor eax,[rdi+rdx*4]
    inc esi
    jmp ri
   .xi
   not eax
   return
   '
  }

  'tests
  'string s="A" 'crc32 should be: D3D99E8B
  'string s="a" 'crc32 should be: E8B7BE43
  'string s="123456789" 'crc32 should be: CBF43926
  'print hex crc32 strptr s, len s



  'RANDOMIZERS
  ============

  int seed=0x12345678
  '
  sub randomize(int i)
  ====================
  seed=i
  end sub
  '
  function rnd() as float
  =======================
  '
  'returns float between -1.0 and 1.0
  '
  Static As float f, d=1/0x7fffffff
  mov eax,seed
  inc eax
  rol eax,13
  xor eax,0xdab5ca3a
  mov seed,eax
  push eax
  fild dword [esp]
  pop eax
  fmul dword d
  fstp dword f
  return f
  end function


  'ABS RANDOMISER
  '
  function arnd() as float
  ========================
  '
  'returns float between 0.0 and 1.0
  '
  return Abs(Rnd)
  end function


  function irnd(int z1, z2) as int
  ================================
  '
  'returns integer between z1 and z2
  '
  mov    eax,z2
  sub    eax,z1
  inc    eax
  imul   edx,Seed,0x8088405
  inc    edx
  mov    Seed,edx 'store new seed
  mul    edx 'multiply eax by edx
  return edx+z1
  end Function 


  function Interpolation(float a,b,c) as float
  ============================================
  return a+(b-a)*c*c*(3-2*c)
  end function


  function InterpLinear(float a,b,c) as float
  ===========================================
  return a*(1-c)+b*c;                                          
  end function


  function Noise(int v) as float
  ==============================
  static double d=1/0x7fffffff
  mov eax,v
  rol eax,5
  mul dword v
  xor eax,0x9595adad
  mul dword v
  rol eax,3
  mov v,eax
  return v*d 'range -1.0..1.0
  end function

  function NoiseA(int v) as float
  ===============================
  static double d=1/0x7fffffff
  mov eax,v
  rol eax,5
  mul dword v
  xor eax,0x9595adad
  mul dword v
  rol eax,3
  and eax,0x7fffffff 'always positive
  mov v,eax
  return v*d 'range 0..1.0
  end function

  'FOR COLORS ETC

  sub AddNoiseC(sys pp,wi,ht,st,r,g,b,a,ofs,optional mo)
  ======================================================
  'pixbase,width,height,stride,colorval,offset
  type pix
    byte r,g,b,a
    =
    int c
  end type
  pix p at pp
  long x,x1,x2,y,y1,y2,y3,y4,mk
  byte rr,gg,bb,aa
  float v1,v2,v3,v4,v5,v6,v7,dv
  dv=1/st
  mk=-st
  for y=0 to <ht
    y1=y and mk
    y2=y1+st
    y3=y1*wi+ofs
    y4=y2*wi+ofs
    for x=0 to <wi
      x1=x and mk
      x2=x1+st
      v1=noiseA(y3+x1)
      v2=noiseA(y3+x2)
      v3=noiseA(y4+x1)
      v4=noiseA(y4+x2)
      v5=interpolation(v1,v2,(x-x1)*dv)
      v6=interpolation(v3,v4,(x-x1)*dv)
      v7=interpolation(v5,v6,(y-y1)*dv)
      rr=r*v7
      gg=g*v7
      bb=b*v7
      aa=a*v7
      select mo
        case 1: aa=a : p.c=0               'clear pixel, constant alpha
        case 2: aa=a                       '             constant alpha
        case 3: rr=r : gg=g : bb=b : p.c=0 'clear pixel, constant rgb
        case 4: rr=r : gg=g : bb=b         '             constant rgb
      end select
      p.r+=rr
      p.g+=gg
      p.b+=bb
      p.a+=aa
      'p+=rr+gg*0x100+bb*0x10000+aa*0x1000000
      @p+=4
    next
  next
  end sub

  'FOR TERRAINS ETC

  sub AddNoiseF(sys pp,wi,ht,st,ofs,float sc)
  ===========================================
  'pixbase,width,height,stride,offset,scale
  int x,y,x1,x2,y1,y2,y3,y4,mk
  float v1,v2,v3,v4,v5,v6,v7,dv
  dv=1/st
  mk=-st
  for y=0 to <ht
    y1=y and mk
    y2=y1+st
    y3=y1*wi+ofs
    y4=y2*wi+ofs
    for x=0 to <wi
      x1=x and mk
      x2=x1+st
      v1=noise(y3+x1)
      v2=noise(y3+x2)
      v3=noise(y4+x1)
      v4=noise(y4+x2)
      v5=interpolation(v1,v2,(x-x1)*dv)
      v6=interpolation(v3,v4,(x-x1)*dv)
      v7=interpolation(v5,v6,(y-y1)*dv)
      float f at pp
      f+=sc*v7
      pp+=sizeof float
    next
  next
  end sub

