home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #6 / amigaacscoverdisc1998-061998.iso / games / descent / source / main / soscodec.asm < prev    next >
Assembly Source File  |  1998-06-08  |  24KB  |  690 lines

  1. ;THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
  2. ;SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
  3. ;END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
  4. ;ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
  5. ;IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
  6. ;SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
  7. ;FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
  8. ;CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
  9. ;AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.  
  10. ;COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
  11. ;
  12. ; $Source: f:/miner/source/main/rcs/soscodec.asm $
  13. ; $Revision: 2.0 $
  14. ; $Author: john $
  15. ; $Date: 1995/02/27 11:29:36 $
  16. ; Routines for compressing digital sounds.
  17. ; $Log: soscodec.asm $
  18. ; Revision 2.0  1995/02/27  11:29:36  john
  19. ; New version 2.0, which has no anonymous unions, builds with
  20. ; Watcom 10.0, and doesn't require parsing BITMAPS.TBL.
  21. ; Revision 1.2  1994/11/30  14:08:46  john
  22. ; First version.
  23. ; Revision 1.1  1994/11/29  14:33:51  john
  24. ; Initial revision
  25.  
  26.  
  27.  
  28. .386
  29.     option    oldstructs
  30.  
  31.     .nolist
  32.     include    types.inc
  33.     include    psmacros.inc
  34.     .list
  35.  
  36.     assume    cs:_TEXT, ds:_DATA
  37.  
  38. _DATA    segment    dword public USE32 'DATA'
  39.  
  40. rcsid    db    "$Id: soscodec.asm 2.0 1995/02/27 11:29:36 john Exp $"
  41.     align    4
  42.  
  43. ; public declarations
  44.                         public   sosCODECDecompressData_
  45.                         public   sosCODECCompressData_
  46.                         public   sosCODECInitStream_
  47.  
  48. ; structure definitions
  49. sCompressInfo           struc
  50.  
  51.    Source                 dd    0           ; pointer to compressed data
  52.    Dest                   dd    0           ; pointer to uncompressed data
  53.  
  54.    dwCompSize           dd    0           ; compressed size
  55.    dwUnCompSize         dd    0           ; uncompressed size
  56.  
  57.    dwSampleIndex        dd    0           ; index into sample
  58.    dwPredicted          dd    0           ; next predicted value
  59.    dwDifference         dd    0           ; difference from last sample
  60.  
  61.    wCodeBuf             dw    0           ; holds 2 nibbles for decompression
  62.    wCode                dw    0           ; current 4 bit code
  63.    wStep                dw    0           ; step value in table
  64.    wIndex               dw    0           ; index into step table
  65.  
  66.    wBitSize             dw    0           ; bit size for decompression
  67.  
  68. sCompressInfo           ends
  69.  
  70. ; index table for stepping into step table
  71. ;
  72. wCODECIndexTab          dw    -1,-1,-1,-1, 2, 4, 6, 8
  73.             dw    -1,-1,-1,-1, 2, 4, 6, 8
  74.  
  75. wCODECStepTab           dw    7, 8, 9, 10, 11, 12, 13, 14
  76.                         dw    16,  17,  19,  21,  23,  25,  28
  77.                         dw    31,  34,  37,  41,  45,  50,  55
  78.                         dw    60,  66,  73,  80,  88,  97, 107
  79.                         dw    118, 130, 143, 157, 173, 190, 209
  80.                         dw    230, 253, 279, 307, 337, 371, 408
  81.                         dw    449, 494, 544, 598, 658, 724, 796
  82.                         dw    876, 963,1060,1166,1282,1411,1552
  83.                         dw    1707,1878
  84.                         dw    2066,2272,2499,2749,3024,3327,3660,4026
  85.                         dw    4428,4871,5358,5894,6484,7132,7845,8630
  86.                         dw    9493,10442,11487,12635,13899,15289,16818
  87.                         dw    18500,20350,22385,24623,27086,29794,32767
  88.  
  89. ; byte index counter
  90. wCODECByteIndex         dd    0
  91.  
  92. ; total bytes processed
  93. wCODECBytesProcessed    dd    0
  94.  
  95. ; current mask value
  96. wCODECMask              dw    0
  97.  
  98. ; temp step value
  99. dwCODECTempStep         dd    0
  100.  
  101.  
  102. _DATA    ends
  103.  
  104.  
  105.  
  106. _TEXT    segment    dword public USE32 'CODE'
  107.  
  108.  
  109.  
  110. sosCODECInitStream_:
  111.                         ; save used registers
  112.                         push  ebx
  113.  
  114.                         ; 
  115.                         ; set up pointer to _SOS_COMPRESS_INFO
  116.                         ; structure in EBX.
  117.                         ;
  118.                         mov   ebx, eax
  119.  
  120.                         ;
  121.                         ; init members of compression stream
  122.                         ;
  123.                         mov   word ptr [ ebx ].wIndex, 0
  124.                         mov   word ptr [ ebx ].wStep, 7
  125.                         mov   dword ptr [ ebx ].dwPredicted, 0
  126.                         mov   dword ptr [ ebx ].dwSampleIndex, 0
  127.  
  128.                         ; restore registers
  129.                         pop   ebx
  130.  
  131.                         ret
  132.  
  133. ;
  134. ; DWORD sosCODECDecompressData( _SOS_COMPRESS_INFO * sSOSInfo, DWORD wBytes )
  135. ;
  136. ; decompress data from a 4:1 ADPCM compressed file.  the number of
  137. ; bytes decompressed is returned.
  138. ;
  139. ;
  140. sosCODECDecompressData_:
  141.         ; eax = sSOSInfo
  142.         ; edx = wBytes
  143.  
  144.                         ;
  145.                         ; save registers used
  146.                         ;
  147.                         push  esi
  148.                         push  edi
  149.                         push  ebx
  150.                         push  ecx
  151.                         push  edx
  152.  
  153.                         ;
  154.                         ; set up EBX as a pointer to 
  155.                         ; info structure.
  156.                         ;
  157.                         mov   ebx, eax
  158.  
  159.                         ;
  160.                         ; set up byte counter. if 16 bit data
  161.                         ; divide bytes by two since we will
  162.                         ; spit out two bytes @ a time.
  163.                         ;
  164.                         mov   eax, edx
  165.                         mov   wCODECBytesProcessed, eax
  166.  
  167.                         mov   wCODECByteIndex, eax
  168.  
  169.                         ;
  170.                         ; set up source and destination 
  171.                         ; pointers
  172.                         ;
  173.                         mov    esi, [ ebx ].Source
  174.                         mov    edi, [ ebx ].Dest
  175.  
  176. Decompmainloop:
  177.                         ;
  178.                         ; determine if sample index is even
  179.                         ; or odd. this will determine if we
  180.                         ; need to get a new token or not.
  181.                         ;
  182.                         test  dword ptr [ ebx ].dwSampleIndex, 1
  183.                         je    short DecompfetchToken
  184.  
  185.                         ;
  186.                         ; get token 
  187.                         ;
  188.                         movzx eax, word ptr [ ebx ].wCodeBuf
  189.                         shr   eax, 4
  190.                         and   eax, 000fh
  191.                         mov   word ptr [ ebx ].wCode, ax
  192.                         jmp   short DecompcalcDifference
  193. DecompfetchToken:
  194.                         ;
  195.                         ; fetch new token
  196.                         ;
  197.                         xor   eax, eax
  198.                         mov   al, byte ptr [ esi ]
  199.                         mov   word ptr [ ebx ].wCodeBuf, ax
  200.                         inc   esi
  201.                         and   eax, 000fh
  202.                         mov   word ptr [ ebx ].wCode, ax
  203. DecompcalcDifference:
  204.                         ;
  205.                         ; reset difference
  206.                         ;
  207.                         mov   dword ptr [ ebx ].dwDifference, 0
  208.  
  209.                         ;
  210.                         ; set up ECX as the step value
  211.                         ;
  212.                         movzx ecx, word ptr [ ebx ].wStep
  213.  
  214.                         ; 
  215.                         ; check for wCode & 4
  216.                         ;
  217.                         test  eax, 4
  218.                         je    short Decompno4
  219.  
  220.                         ; add wStep
  221.                         add   dword ptr [ ebx ].dwDifference, ecx
  222. Decompno4:
  223.                         ;
  224.                         ; check for wCode & 2
  225.                         ;
  226.                         test  eax, 2
  227.                         je    short Decompno2
  228.  
  229.                         ; add wStep >> 1
  230.                         mov   edx, ecx
  231.                         shr   edx, 1
  232.                         add   dword ptr [ ebx ].dwDifference, edx
  233.  
  234. Decompno2:
  235.                         ;
  236.                         ; check for wCode & 1
  237.                         ;
  238.                         test  eax, 1
  239.                         je    short Decompno1
  240.  
  241.                         ; add wStep >> 2
  242.                         mov   edx, ecx
  243.                         shr   edx, 2
  244.                         add   dword ptr [ ebx ].dwDifference, edx
  245. Decompno1:
  246.                         ;
  247.                         ; add in wStep >> 3
  248.                         ;
  249.                         mov   edx, ecx
  250.                         shr   edx, 3
  251.                         add   dword ptr [ ebx ].dwDifference, edx
  252.  
  253.                         ;
  254.                         ; check for wCode & 8
  255.                         ;
  256.                         test  eax, 8
  257.                         je    short Decompno8
  258.  
  259.                         ; negate difference
  260.                         neg   dword ptr [ ebx ].dwDifference
  261. Decompno8:
  262.                         ;
  263.                         ; add difference to predicted
  264.                         ; value.
  265.                         ;
  266.                         mov   eax, [ ebx ].dwPredicted
  267.                         add   eax, [ ebx ].dwDifference
  268.  
  269.                         ;
  270.                         ; make sure there is no under or 
  271.                         ; overflow.
  272.                         ;
  273.                         cmp   eax, 7fffh
  274.                         jl    short DecompnoOverflow
  275.                         mov   eax, 7fffh
  276. DecompnoOverflow:
  277.                         cmp   eax, 0ffff8000h
  278.                         jg    short DecompnoUnderflow
  279.                         mov   eax, 0ffff8000h
  280. DecompnoUnderflow:
  281.                         mov   dword ptr [ ebx ].dwPredicted, eax
  282.  
  283.                         ;
  284.                         ; output 8 bit sample
  285.                         ;
  286.                         xor   ah, 80h
  287.                         mov   al, ah
  288.                         stosb
  289.  
  290.                         ;
  291.                         ; adjust index 
  292.                         ;
  293.                         movzx ecx, word ptr [ ebx ].wCode
  294.                         movzx eax, word ptr wCODECIndexTab[ ecx * 2 ]
  295.                         add   word ptr [ ebx ].wIndex, ax
  296.  
  297.                         ;
  298.                         ; check if wIndex < 0
  299.                         ;
  300.                         cmp   word ptr [ ebx ].wIndex, 8000h
  301.                         jb    short DecompcheckOverflow
  302.  
  303.                         ; reset index to zero
  304.                         mov   word ptr [ ebx ].wIndex, 0
  305.                         jmp   short DecompadjustStep
  306. DecompcheckOverflow:
  307.                         ;
  308.                         ; check if wIndex > 88
  309.                         ;
  310.                         cmp   word ptr [ ebx ].wIndex, 88
  311.                         jbe   short DecompadjustStep
  312.  
  313.                         ; reset index to 88
  314.                         mov   word ptr [ ebx ].wIndex, 88
  315. DecompadjustStep:
  316.                         ;
  317.                         ; fetch wIndex so we can fetch
  318.                         ; new step value
  319.                         ;
  320.                         movzx ecx, word ptr [ ebx ].wIndex
  321.                         movzx eax, word ptr wCODECStepTab[ ecx * 2 ]
  322.  
  323.                         ;
  324.                         ; advance index and store step value
  325.                         ;
  326.                         add   dword ptr [ ebx ].dwSampleIndex, 1
  327.                         mov   word ptr [ ebx ].wStep, ax
  328.  
  329.                         ;
  330.                         ; decrement bytes processed
  331.                         ; and loop back.
  332.                         ;
  333.                         dec   wCODECByteIndex
  334.                         jne   Decompmainloop
  335.  
  336.                         ;
  337.                         ; save off ESI and EDI back into
  338.                         ; compress info structure.
  339.                         ;
  340.                         mov   dword ptr [ ebx ].Source, esi
  341.                         mov   dword ptr [ ebx ].Dest, edi
  342.  
  343.                         ;
  344.                         ; set up return value for number
  345.                         ; of bytes processed.
  346.                         ;
  347.                         mov   eax, wCODECBytesProcessed
  348.  
  349.                         ;
  350.                         ; restore registers
  351.                         ;
  352.                         pop   edx
  353.                         pop   ecx
  354.                         pop   ebx
  355.                         pop   edi
  356.                         pop   esi
  357.  
  358.                         ret
  359.  
  360. ;
  361. ; DWORD sosCODECCompressData( _SOS_COMPRESS_INFO * sSOSInfo, DWORD wBytes )
  362. ;
  363. ; Compresses a data stream into 4:1 ADPCM.  16 bit data is compressed 4:1
  364. ; 8 bit data is compressed 2:1.
  365. ;
  366. ;
  367. sosCODECCompressData_:
  368.         ; eax = sSOSInfo 
  369.         ; edx = wBytes
  370.  
  371.                         ;
  372.                         ; save registers used
  373.                         ;
  374.                         push  esi
  375.                         push  edi
  376.                         push  ebx
  377.                         push  ecx
  378.                         push  edx
  379.  
  380.                         ;
  381.                         ; set up EBX as a pointer to 
  382.                         ; info structure.
  383.                         ;
  384.                         mov   ebx, eax
  385.  
  386.                         ;
  387.                         ; set up byte counter. if 16 bit data
  388.                         ; divide bytes by two since we will
  389.                         ; spit out two bytes @ a time.
  390.                         ;
  391.                         mov   eax, edx
  392.                         mov   wCODECBytesProcessed, eax
  393.  
  394.                         ;
  395.                         ; check for 16 bit decompression
  396.                         ;
  397.                         cmp   word ptr [ ebx ].wBitSize, 16
  398.                         jne   short CompskipByteDivide
  399.  
  400.                         ;
  401.                         ; divide size requested by two
  402.                         ;
  403.                         shr   eax, 1
  404. CompskipByteDivide:
  405.                         mov   wCODECByteIndex, eax
  406.  
  407.                         ;
  408.                         ; set up source and destination 
  409.                         ; pointers
  410.                         ;
  411.                         mov    esi, [ ebx ].Source
  412.                         mov    edi, [ ebx ].Dest
  413.  
  414. Compmainloop:
  415.                         ;
  416.                         ; determine bit size for input
  417.                         ;
  418.                         cmp   word ptr [ ebx ].wBitSize, 16
  419.                         jne   short Compinput8Bit
  420.  
  421.                         ;
  422.                         ; get 16 bit sample
  423.                         ;
  424.                         movsx eax, word ptr [ esi ]
  425.                         add   esi, 2
  426.                         jmp   short CompcomputeDiff
  427. Compinput8Bit:
  428.                         ;
  429.                         ; get 8 bit sample
  430.                         ;
  431.                         mov   ah, byte ptr [ esi ]
  432.                         inc   esi
  433.                         xor   al, al
  434.                         xor   ah, 80h
  435.                         movsx eax, ax
  436. CompcomputeDiff:
  437.                         ;
  438.                         ; compute difference
  439.                         ;
  440.                         movsx ecx, word ptr [ ebx ].dwPredicted
  441.                         sub   eax, ecx
  442.  
  443.                         ;
  444.                         ; check if dwDifference > 0.  ECX is the
  445.                         ; sign bit, it is initialized to positive.
  446.                         ;
  447.                         xor   ecx, ecx
  448.                         cmp   eax, 0
  449.                         jge   Comppositive
  450.  
  451.                         ;
  452.                         ; negate difference
  453.                         ;
  454.                         neg   eax
  455.                         or    ecx, 8
  456. Comppositive:
  457.                         ;
  458.                         ; store code value
  459.                         ;
  460.                         mov   word ptr [ ebx ].wCode, cx
  461.  
  462.                         ;
  463.                         ; set up to quantize difference. initialize 
  464.                         ; wCODECTempStep = step value.
  465.                         ;
  466.                         movsx ecx, word ptr [ ebx ].wStep
  467.                         mov   dwCODECTempStep, ecx
  468.                         mov   edx, 4
  469.                         mov   ecx, 3
  470. CompquantizeLoop:
  471.                         ;
  472.                         ; check to see if difference > tempstep
  473.                         ; value.
  474.                         ;
  475.                         cmp   eax, dwCODECTempStep
  476.                         jl    short CompnextQLoop
  477.  
  478.                         ;
  479.                         ; OR in mask value into code and
  480.                         ; adjust difference.
  481.                         ;
  482.                         or    word ptr [ ebx ].wCode, dx
  483.                         sub   eax, dwCODECTempStep
  484. CompnextQLoop:
  485.                         ;
  486.                         ; shift down tempstep and mask
  487.                         ;
  488.                         shr   dwCODECTempStep, 1
  489.                         shr   edx, 1
  490.  
  491.                         loop  CompquantizeLoop
  492.  
  493.                         ;
  494.                         ; store off new difference value
  495.                         ;
  496.                         mov   dword ptr [ ebx ].dwDifference, eax
  497.  
  498.                         ;
  499.                         ; determine if sample index is even
  500.                         ; or odd. this will determine if we
  501.                         ; need to get a new token or not.
  502.                         ;
  503.                         test  dword ptr [ ebx ].dwSampleIndex, 1
  504.                         jne   short CompstoreToken
  505.  
  506.                         ;
  507.                         ; get token 
  508.                         ;
  509.                         movzx eax, word ptr [ ebx ].wCode
  510.                         and   eax, 0fh
  511.                         mov   word ptr [ ebx ].wCodeBuf, ax
  512.                         jmp   short CompcalcDifference
  513. CompstoreToken:
  514.                         ;
  515.                         ; fetch new token
  516.                         ;
  517.                         movzx eax, word ptr [ ebx ].wCode
  518.                         shl   eax, 4
  519.                         or    ax, word ptr [ ebx ].wCodeBuf
  520.                         mov   byte ptr [ edi ], al
  521.                         inc   edi
  522. CompcalcDifference:
  523.                         ;
  524.                         ; reset difference
  525.                         ;
  526.                         mov   dword ptr [ ebx ].dwDifference, 0
  527.  
  528.                         ;
  529.                         ; set up ECX as the step value
  530.                         ;
  531.                         movzx ecx, word ptr [ ebx ].wStep
  532.  
  533.                         ;
  534.                         ; get code in AX
  535.                         ;
  536.                         movzx eax, word ptr [ ebx ].wCode
  537.  
  538.                         ; 
  539.                         ; check for wCode & 4
  540.                         ;
  541.                         test  eax, 4
  542.                         je    short Compno4
  543.  
  544.                         ; add wStep
  545.                         add   dword ptr [ ebx ].dwDifference, ecx
  546. Compno4:
  547.                         ;
  548.                         ; check for wCode & 2
  549.                         ;
  550.                         test  eax, 2
  551.                         je    short Compno2
  552.  
  553.                         ; add wStep >> 1
  554.                         mov   edx, ecx
  555.                         shr   edx, 1
  556.                         add   dword ptr [ ebx ].dwDifference, edx
  557.  
  558. Compno2:
  559.                         ;
  560.                         ; check for wCode & 1
  561.                         ;
  562.                         test  eax, 1
  563.                         je    short Compno1
  564.  
  565.                         ; add wStep >> 2
  566.                         mov   edx, ecx
  567.                         shr   edx, 2
  568.                         add   dword ptr [ ebx ].dwDifference, edx
  569. Compno1:
  570.                         ;
  571.                         ; add in wStep >> 3
  572.                         ;
  573.                         mov   edx, ecx
  574.                         shr   edx, 3
  575.                         add   dword ptr [ ebx ].dwDifference, edx
  576.  
  577.                         ;
  578.                         ; check for wCode & 8
  579.                         ;
  580.                         test  eax, 8
  581.                         je    short Compno8
  582.  
  583.                         ; negate difference
  584.                         neg   dword ptr [ ebx ].dwDifference
  585. Compno8:
  586.                         ;
  587.                         ; add difference to predicted
  588.                         ; value.
  589.                         ;
  590.                         mov   eax, [ ebx ].dwPredicted
  591.                         add   eax, [ ebx ].dwDifference
  592.  
  593.                         ;
  594.                         ; make sure there is no under or 
  595.                         ; overflow.
  596.                         ;
  597.                         cmp   eax, 7fffh
  598.                         jl    short CompnoOverflow
  599.                         mov   eax, 7fffh
  600. CompnoOverflow:
  601.                         cmp   eax, 0ffff8000h
  602.                         jg    short CompnoUnderflow
  603.                         mov   eax, 0ffff8000h
  604. CompnoUnderflow:
  605.                         mov   dword ptr [ ebx ].dwPredicted, eax
  606.  
  607.                         ;
  608.                         ; adjust index 
  609.                         ;
  610.                         movzx ecx, word ptr [ ebx ].wCode
  611.                         movzx eax, word ptr wCODECIndexTab[ ecx * 2 ]
  612.                         add   word ptr [ ebx ].wIndex, ax
  613.  
  614.                         ;
  615.                         ; check if wIndex < 0
  616.                         ;
  617.                         cmp   word ptr [ ebx ].wIndex, 8000h
  618.                         jb    short CompcheckOverflow
  619.  
  620.                         ; reset index to zero
  621.                         mov   word ptr [ ebx ].wIndex, 0
  622.                         jmp   short CompadjustStep
  623. CompcheckOverflow:
  624.                         ;
  625.                         ; check if wIndex > 88
  626.                         ;
  627.                         cmp   word ptr [ ebx ].wIndex, 88
  628.                         jbe   short CompadjustStep
  629.  
  630.                         ; reset index to 88
  631.                         mov   word ptr [ ebx ].wIndex, 88
  632. CompadjustStep:
  633.                         ;
  634.                         ; fetch wIndex so we can fetch
  635.                         ; new step value
  636.                         ;
  637.                         movzx ecx, word ptr [ ebx ].wIndex
  638.                         movzx eax, word ptr wCODECStepTab[ ecx * 2 ]
  639.  
  640.                         ;
  641.                         ; advance index and store step value
  642.                         ;
  643.                         add   dword ptr [ ebx ].dwSampleIndex, 1
  644.                         mov   word ptr [ ebx ].wStep, ax
  645.  
  646.                         ;
  647.                         ; decrement bytes processed
  648.                         ; and loop back.
  649.                         ;
  650.                         dec   wCODECByteIndex
  651.                         jne   Compmainloop
  652.  
  653.                         ;
  654.                         ; save off ESI and EDI back into
  655.                         ; compress info structure.
  656.                         ;
  657.                         mov   dword ptr [ ebx ].Source, esi
  658.                         mov   dword ptr [ ebx ].Dest, edi
  659.  
  660.                         ;
  661.                         ; set up return value for number
  662.                         ; of bytes processed.
  663.                         ;
  664.                         mov   eax, wCODECBytesProcessed
  665.                         shr   eax, 2
  666.  
  667.                         ;
  668.                         ; restore registers
  669.                         ;
  670.                         pop   edx
  671.                         pop   ecx
  672.                         pop   ebx
  673.                         pop   edi
  674.                         pop   esi
  675.  
  676.                         ret
  677.  
  678.  
  679. _TEXT    ends
  680.  
  681.     end
  682.  
  683. 
  684.