home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 February / chip_20022115.iso / amiga / chipgame / scummvm_aga.lha / ScummVM_AGA / src / costume.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2002-01-05  |  16.3 KB  |  782 lines

  1. /* ScummVM - Scumm Interpreter
  2.  * Copyright (C) 2001  Ludvig Strigeus
  3.  *
  4.  * This program is free software; you can redistribute it and/or
  5.  * modify it under the terms of the GNU General Public License
  6.  * as published by the Free Software Foundation; either version 2
  7.  * of the License, or (at your option) any later version.
  8.  
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  17.  *
  18.  * $Header: /cvsroot/scummvm/scummvm/costume.cpp,v 1.8 2001/11/06 20:00:47 strigeus Exp $
  19.  *
  20.  */
  21.  
  22. #include "stdafx.h"
  23. #include "scumm.h"
  24.  
  25. const byte revBitMask[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
  26.  
  27. void CostumeRenderer::ignorePakCols(int a) {
  28.     int n;
  29.     n = _height;
  30.     if (a>1) n *= a;
  31.     do {
  32.         _repcolor = *_srcptr++;
  33.         _replen = _repcolor&_maskval;
  34.         if (_replen==0) {
  35.             _replen = *_srcptr++;
  36.         }
  37.         do {
  38.             if (!--n) {
  39.                 _repcolor >>= _shrval;
  40.                 return;
  41.             }
  42.         } while (--_replen);
  43.     } while (1);
  44. }
  45.  
  46. const byte cost_scaleTable[256] = {
  47. 255, 253, 125, 189, 61, 221, 93, 157, 29, 237,
  48. 109, 173, 45, 205, 77, 141, 13, 245, 117, 181,
  49. 53, 213, 85, 149, 21, 229, 101, 165, 37, 197, 69,
  50. 133, 5, 249, 121, 185, 57, 217, 89, 153, 25, 233,
  51. 105, 169, 41, 201, 73, 137, 9, 241, 113, 177, 49,
  52. 209, 81, 145, 17, 225, 97, 161, 33, 193, 65, 129,
  53. 1, 251, 123, 187, 59, 219, 91, 155, 27, 235, 107,
  54. 171, 43, 203, 75, 139, 11, 243, 115, 179, 51, 211,
  55. 83, 147, 19, 227, 99, 163, 35, 195, 67, 131, 3,
  56. 247, 119, 183, 55, 215, 87, 151, 23, 231, 103,
  57. 167, 39, 199, 71, 135, 7, 239, 111, 175, 47, 207,
  58. 79, 143, 15, 223, 95, 159, 31, 191, 63, 127, 0,
  59. 128, 64, 192, 32, 160, 96, 224, 16, 144, 80, 208,
  60. 48, 176, 112, 240, 8, 136, 72, 200, 40, 168, 104,
  61. 232, 24, 152, 88, 216, 56, 184, 120, 248, 4, 132,
  62. 68, 196, 36, 164, 100, 228, 20, 148, 84, 212, 52,
  63. 180, 116, 244, 12, 140, 76, 204, 44, 172, 108,
  64. 236, 28, 156, 92, 220, 60, 188, 124, 252, 2, 130,
  65. 66, 194, 34, 162, 98, 226, 18, 146, 82, 210, 50,
  66. 178, 114, 242, 10, 138, 74, 202, 42, 170, 106,
  67. 234, 26, 154, 90, 218, 58, 186, 122, 250, 6, 134,
  68. 70, 198, 38, 166, 102, 230, 22, 150, 86, 214, 54,
  69. 182, 118, 246, 14, 142, 78, 206, 46, 174, 110,
  70. 238, 30, 158, 94, 222, 62, 190, 126, 254
  71. };
  72.  
  73. byte CostumeRenderer::mainRoutine(Actor *a, int slot, int frame) {
  74.     int xmove, ymove, i,b,s;
  75.     uint scal;
  76.     byte scaling;
  77.     byte charsetmask, masking;
  78.     byte unk19;
  79.     int ex1,ex2;
  80.  
  81.     CHECK_HEAP
  82.  
  83.     _maskval = 0xF;
  84.     _shrval = 4;
  85.     if (_numColors == 32) {
  86.         _maskval = 7;
  87.         _shrval = 3;
  88.     }
  89.     
  90.     _width2 = _srcptr[0];
  91.     _width = _width2;
  92.     _height2 = _srcptr[2];
  93.     _height = _height2;
  94.     xmove = (int16)READ_LE_UINT16(_srcptr+4) + _xmove;
  95.     ymove = (int16)READ_LE_UINT16(_srcptr+6) + _ymove;
  96.     _xmove += (int16)READ_LE_UINT16(_srcptr+8);
  97.     _ymove -= (int16)READ_LE_UINT16(_srcptr+10);
  98.     _srcptr += 12;
  99.  
  100.     switch(_ptr[7]&0x7F) {
  101.     case 0x60: case 0x61:
  102.         ex1 = _srcptr[0];
  103.         ex2 = _srcptr[1];
  104.         _srcptr += 2;
  105.         if (ex1!=0xFF || ex2!=0xFF) {
  106.             ex1=READ_LE_UINT16(_ptr + _numColors + 10 + ex1*2);
  107.             _srcptr = _ptr + READ_LE_UINT16(_ptr + ex1 + ex2*2) + 14;
  108.         }
  109.     } 
  110.  
  111.     _xpos = _actorX;
  112.     _ypos = _actorY;
  113.         
  114.     scaling = _scaleX==255 && _scaleY==255 ? 0 : 1;
  115.     s = 0;
  116.  
  117.     if (scaling) {
  118.         _scaleIndexXStep = -1;
  119.         if (xmove < 0) {
  120.             xmove = -xmove;
  121.             _scaleIndexXStep = 1;
  122.         }
  123.  
  124.         if(_mirror) {
  125.             unk19 = _scaleIndexX = 128 - xmove;
  126.             for (i=0; i<xmove; i++) {
  127.                 scal = cost_scaleTable[_scaleIndexX++];
  128.                 if (scal < _scaleX)
  129.                     _xpos -= _scaleIndexXStep;
  130.             }
  131.             _right = _left = _xpos;
  132.             _scaleIndexX = unk19;
  133.             for (i=0; i<_width; i++) {
  134.                 if (_right < 0) {
  135.                     s++;
  136.                     unk19 = _scaleIndexX;
  137.                 }
  138.                 scal = cost_scaleTable[_scaleIndexX++];
  139.                 if (scal < _scaleX)
  140.                     _right++;
  141.             }
  142.         } else {
  143.             unk19 = _scaleIndexX = xmove + 128;
  144.             for (i=0; i<xmove; i++) {
  145.                 scal = cost_scaleTable[_scaleIndexX--];
  146.                 if (scal < _scaleX)
  147.                     _xpos += _scaleIndexXStep;
  148.             }
  149.             _right = _left = _xpos;
  150.             _scaleIndexX = unk19;
  151.             for (i=0; i<_width; i++) {
  152.                 if (_left > 319) {
  153.                     s++;
  154.                     unk19 = _scaleIndexX;
  155.                 }
  156.                 scal = cost_scaleTable[_scaleIndexX--];
  157.                 if(scal < _scaleX)
  158.                     _left--;
  159.             }
  160.         }
  161.         _scaleIndexX = unk19;
  162.         if (s)
  163.             s--;
  164.         _scaleIndexYStep = -1;
  165.         if (ymove < 0) {
  166.             ymove = -ymove;
  167.             _scaleIndexYStep = 1;
  168.         }
  169.         _scaleIndexY = 128 - ymove;
  170.         for (i=0; i<ymove; i++) {
  171.             scal = cost_scaleTable[_scaleIndexY++];
  172.             if (scal < _scaleY)
  173.                 _ypos -= _scaleIndexYStep;
  174.         }
  175.         _top = _bottom = _ypos;
  176.         _scaleIndexY = 128 - ymove;
  177.         for (i=0; i<_height; i++) {
  178.             scal = cost_scaleTable[_scaleIndexY++];
  179.             if (scal < _scaleY) 
  180.                 _bottom++;
  181.         }
  182.         _scaleIndexY = _scaleIndexYTop = 128 - ymove;
  183.     } else {
  184.         if(_mirror==0)
  185.             xmove = -xmove;
  186.         _xpos += xmove;
  187.         _ypos += ymove;
  188.         if (_mirror) {
  189.             _left = _xpos;
  190.             _right = _xpos + _width;
  191.         } else {
  192.             _left = _xpos - _width;
  193.             _right = _xpos;
  194.         }
  195.         _top = _ypos;
  196.         _bottom = _top + _height;
  197.     }
  198.  
  199.     _scaleIndexXStep = -1;
  200.     if (_mirror)
  201.         _scaleIndexXStep = 1;
  202.     _ypostop = _ypos;
  203.     _vscreenheight = _vm->virtscr[0].height;
  204.     _vm->updateDirtyRect(0, _left, _right+1,_top,_bottom,1<<a->number);
  205.  
  206.     if (_top >= (int)_vscreenheight || _bottom <= 0)
  207.         return 0;
  208.  
  209.     _ypitch = _height * 320;
  210.     _docontinue = 0;
  211.     b = 1;
  212.     if (_left > 319 || _right <= 0)
  213.         return 0;
  214.     if (_mirror) {
  215.         _ypitch--;
  216.         if (scaling==0) {
  217.             s = -_xpos;
  218.         }
  219.         if (s > 0) {
  220.             _width2 -= s;
  221.             ignorePakCols(s);
  222.             _xpos = 0;
  223.             _docontinue = 1;
  224.         } else {
  225.             s = _right - 320;
  226.             if (s<=0) {
  227.                 b = 2;
  228.             } else {
  229.                 _width2 -= s;
  230.             }
  231.         }
  232.     } else {
  233.         _ypitch++;
  234.         if(scaling==0)
  235.             s = _right - 320;
  236.         if (s > 0) {
  237.             _width2 -= s;
  238.             ignorePakCols(s);
  239.             _xpos = 319;
  240.             _docontinue = 1;
  241.         } else {
  242.             s = -1 - _left;
  243.             if (s <= 0)
  244.                 b = 2;
  245.             else
  246.                 _width2 -= s;
  247.         }
  248.     }
  249.  
  250.     if (_width2==0)
  251.         return 0;
  252.  
  253.     if ((uint)_top > (uint)_vscreenheight)
  254.         _top = 0;
  255.  
  256.     if (_left<0) _left=0;
  257.  
  258.     if ((uint)_bottom > _vscreenheight)
  259.         _bottom = _vscreenheight;
  260.  
  261.     if (a->top > _top)
  262.         a->top = _top;
  263.  
  264.     if (a->bottom < _bottom)
  265.         a->bottom = _bottom;
  266.  
  267.     if (_height2 + _top >= 256) {
  268.         CHECK_HEAP
  269.         return 2;
  270.     }
  271.  
  272.  
  273.     _bgbak_ptr = _vm->getResourceAddress(rtBuffer, 5) + _vm->virtscr[0].xstart + _ypos*320 + _xpos;
  274.     _backbuff_ptr = _vm->getResourceAddress(rtBuffer, 1) + _vm->virtscr[0].xstart + _ypos*320 + _xpos;
  275.     charsetmask = _vm->hasCharsetMask(_left, _top + _vm->virtscr[0].topline, _right, _vm->virtscr[0].topline + _bottom);
  276.     masking = 0;
  277.  
  278.     if (_zbuf) {
  279.         masking = _vm->isMaskActiveAt(_left, _top, _right, _bottom,
  280.             _vm->getResourceAddress(rtBuffer, 9) + _vm->gdi._imgBufOffs[_zbuf] + _vm->_screenStartStrip
  281.         );
  282.     }
  283.  
  284.     if (_zbuf || charsetmask) {
  285.         _mask_ptr = _vm->getResourceAddress(rtBuffer, 9) + _ypos*40 + _vm->_screenStartStrip;
  286.  
  287.         _imgbufoffs = _vm->gdi._imgBufOffs[_zbuf];
  288.         if (!charsetmask && _zbuf!=0)
  289.             _mask_ptr += _imgbufoffs;
  290.         _mask_ptr_dest = _mask_ptr + _xpos / 8;
  291.     }
  292.  
  293.     CHECK_HEAP
  294.  
  295.     switch ((scaling<<2)|(masking<<1)|charsetmask) {
  296.     case 0: 
  297.         proc6();
  298.         break;
  299.     case 1: case 2:
  300.         proc5();
  301.         break;
  302.     case 3:
  303.         proc4();
  304.         break;
  305.     case 4:
  306.         proc1();
  307.         break;
  308.     case 5:case 6:
  309.         proc2();
  310.         break;
  311.     case 7:
  312.         proc3();
  313.         break;
  314.     }
  315.  
  316.     CHECK_HEAP
  317.     return b;
  318. }
  319.  
  320. void CostumeRenderer::proc6() {
  321.     byte len;
  322.     byte *src, *dst;
  323.     byte width,height,pcolor;
  324.     int color;
  325.     uint y;
  326.     uint scrheight;
  327.  
  328.     y = _ypos;
  329.     len = _replen;
  330.     src = _srcptr;
  331.     dst = _backbuff_ptr;
  332.     color = _repcolor;
  333.     scrheight = _vscreenheight;
  334.     width = _width2;
  335.     height = _height2;
  336.  
  337.     if (_docontinue) goto StartPos;
  338.  
  339.     do {
  340.         len = *src++;
  341.         color = len>>_shrval;
  342.         len &= _maskval;
  343.         if (!len) len = *src++;
  344.  
  345.         do {
  346.             if (color && y < scrheight) {
  347.                 pcolor = _palette[color];
  348.                 if (pcolor==13) {
  349.                     pcolor = _transEffect[*dst];
  350.                 }
  351.                 *dst = pcolor;
  352.             }
  353.  
  354.             dst += 320;
  355.             y++;
  356.             if (!--height) {
  357.                 if (!--width)
  358.                     return;
  359.                 height = _height;
  360.                 dst -= _ypitch;
  361.                 y = _ypostop;
  362.             }
  363. StartPos:;
  364.         } while (--len);
  365.     } while (1);
  366. }
  367.  
  368. void CostumeRenderer::proc5() {
  369.     byte *mask,*src,*dst;
  370.     byte maskbit,len,height,pcolor;
  371.     uint y,scrheight;
  372.     int color;
  373.  
  374.     mask = _mask_ptr = _mask_ptr_dest;
  375.     maskbit = revBitMask[_xpos&7];
  376.     y = _ypos;
  377.     src = _srcptr;
  378.     dst = _backbuff_ptr;
  379.     len = _replen;
  380.     color = _repcolor;
  381.     scrheight = _vscreenheight;
  382.     height = _height2;
  383.  
  384.     if (_docontinue) goto StartPos;
  385.  
  386.     do {
  387.         len = *src++;
  388.         color = len>>_shrval;
  389.         len &= _maskval;
  390.         if (!len) len = *src++;
  391.  
  392.         do {
  393.             if (color && y<scrheight && !(*mask&maskbit)) {
  394.                 pcolor = _palette[color];
  395.                 if (pcolor==13)
  396.                     pcolor = _transEffect[*dst];
  397.                 *dst = pcolor;
  398.             }
  399.             dst += 320;
  400.             y++;
  401.             mask += 40;
  402.             if (!--height) {
  403.                 if(!--_width2)
  404.                     return;
  405.                 height = _height;
  406.                 dst -= _ypitch;
  407.                 y = _ypostop;
  408.                 if(_scaleIndexXStep!=1) {
  409.                     maskbit<<=1;
  410.                     if (!maskbit) {
  411.                         maskbit=1;
  412.                         _mask_ptr--;
  413.                     }
  414.                 } else {
  415.                     maskbit>>=1;
  416.                     if (!maskbit) {
  417.                         maskbit=0x80;
  418.                         _mask_ptr++;
  419.                     }
  420.                 }
  421.                 mask = _mask_ptr;
  422.             }
  423. StartPos:;
  424.         } while (--len);
  425.     } while(1);
  426. }
  427.  
  428. void CostumeRenderer::proc4() {
  429.     byte *mask,*src,*dst;
  430.     byte maskbit,len,height,pcolor;
  431.     uint y,scrheight;
  432.     int color;
  433.     
  434.     mask = _mask_ptr = _mask_ptr_dest;
  435.     maskbit = revBitMask[_xpos&7];
  436.     y = _ypos;
  437.     src = _srcptr;
  438.     dst = _backbuff_ptr;
  439.     len = _replen;
  440.     color = _repcolor;
  441.     scrheight = _vscreenheight;
  442.     height = _height2;
  443.  
  444.     if (_docontinue) goto StartPos;
  445.  
  446.     do {
  447.         len = *src++;
  448.         color = len>>_shrval;
  449.         len &= _maskval;
  450.         if (!len) len = *src++;
  451.         
  452.         do {
  453.             if (color && y<scrheight && !((*mask|mask[_imgbufoffs])&maskbit)) {
  454.                 pcolor = _palette[color];
  455.                 if (pcolor==13)
  456.                     pcolor = _transEffect[*dst];
  457.                 *dst = pcolor;
  458.             }
  459.             dst += 320;
  460.             y++;
  461.             mask += 40;
  462.             if (!--height) {
  463.                 if(!--_width2)
  464.                     return;
  465.                 height = _height;
  466.                 dst -= _ypitch;
  467.                 y = _ypostop;
  468.                 if(_scaleIndexXStep!=1) {
  469.                     maskbit<<=1;
  470.                     if (!maskbit) {
  471.                         maskbit=1;
  472.                         _mask_ptr--;
  473.                     }
  474.                 } else {
  475.                     maskbit>>=1;
  476.                     if (!maskbit) {
  477.                         maskbit=0x80;
  478.                         _mask_ptr++;
  479.                     }
  480.                 }
  481.                 mask = _mask_ptr;
  482.             }
  483. StartPos:;
  484.         } while (--len);
  485.     } while(1);
  486. }
  487.  
  488. void CostumeRenderer::proc3() {
  489.     byte *mask,*src,*dst;
  490.     byte maskbit,len,height,pcolor,width;
  491.     int color,t;
  492.     uint y;
  493.     
  494.     mask = _mask_ptr_dest;
  495.     dst = _backbuff_ptr;
  496.     height = _height2;
  497.     width = _width2;
  498.     len = _replen;
  499.     color = _repcolor;
  500.     src = _srcptr;
  501.     maskbit = revBitMask[_xpos&7];
  502.     y = _ypos;
  503.  
  504.     if (_docontinue) goto StartPos;
  505.  
  506.     do {
  507.         len = *src++;
  508.         color = len>>_shrval;
  509.         len &= _maskval;
  510.         if (!len) len = *src++;
  511.         do {
  512.             if (cost_scaleTable[_scaleIndexY++] < _scaleY) {
  513.                 if (color && y < _vscreenheight && !((*mask|mask[_imgbufoffs])&maskbit)) {
  514.                     pcolor = _palette[color];
  515.                     if (pcolor==13)
  516.                         pcolor = _transEffect[*dst];
  517.                     *dst = pcolor;
  518.                 }
  519.                 dst += 320;
  520.                 mask += 40;
  521.                 y++;
  522.             }
  523.             if (!--height) {
  524.                 if(!--width)
  525.                     return;
  526.                 height = _height;
  527.                 y = _ypostop;
  528.                 _scaleIndexY = _scaleIndexYTop;
  529.                 t = _scaleIndexX;
  530.                 _scaleIndexX = t + _scaleIndexXStep;
  531.                 if (cost_scaleTable[t] < _scaleX) {
  532.                     _xpos += _scaleIndexXStep;
  533.                     if (_xpos >= 320)
  534.                         return;
  535.                     maskbit = revBitMask[_xpos&7];
  536.                     _backbuff_ptr += _scaleIndexXStep;
  537.                 }
  538.                 dst = _backbuff_ptr;
  539.                 mask = _mask_ptr + (_xpos>>3);
  540.             }
  541. StartPos:;
  542.         } while (--len);
  543.     } while(1);
  544. }
  545.  
  546. void CostumeRenderer::proc2() {
  547.     byte *mask,*src,*dst;
  548.     byte maskbit,len,height,pcolor,width;
  549.     int color,t;
  550.     uint y;
  551.     
  552.     mask = _mask_ptr_dest;
  553.     dst = _backbuff_ptr;
  554.     height = _height2;
  555.     width = _width2;
  556.     len = _replen;
  557.     color = _repcolor;
  558.     src = _srcptr;
  559.     maskbit = revBitMask[_xpos&7];
  560.     y = _ypos;
  561.  
  562.     if (_docontinue) goto StartPos;
  563.  
  564.     do {
  565.         len = *src++;
  566.         color = len>>_shrval;
  567.         len &= _maskval;
  568.         if (!len) len = *src++;
  569.         do {
  570.             if (cost_scaleTable[_scaleIndexY++] < _scaleY) {
  571.                 if (color && y < _vscreenheight && !(*mask&maskbit)) {
  572.                     pcolor = _palette[color];
  573.                     if (pcolor==13)
  574.                         pcolor = _transEffect[*dst];
  575.                     *dst = pcolor;
  576.                 }
  577.                 dst += 320;
  578.                 mask += 40;
  579.                 y++;
  580.             }
  581.             if (!--height) {
  582.                 if(!--width)
  583.                     return;
  584.                 height = _height;
  585.                 y = _ypostop;
  586.                 _scaleIndexY = _scaleIndexYTop;
  587.                 t = _scaleIndexX;
  588.                 _scaleIndexX = t + _scaleIndexXStep;
  589.                 if (cost_scaleTable[t] < _scaleX) {
  590.                     _xpos += _scaleIndexXStep;
  591.                     if (_xpos >= 320)
  592.                         return;
  593.                     maskbit = revBitMask[_xpos&7];
  594.                     _backbuff_ptr += _scaleIndexXStep;
  595.                 }
  596.                 dst = _backbuff_ptr;
  597.                 mask = _mask_ptr + (_xpos>>3);
  598.             }
  599. StartPos:;
  600.         } while (--len);
  601.     } while(1);
  602.  
  603. }
  604.  
  605. void CostumeRenderer::proc1() {
  606.     byte *mask,*src,*dst,*dstorg;
  607.     byte maskbit,len,height,pcolor,width;
  608.     uint y;
  609.     int color;
  610.     int t;
  611.  
  612.     mask = _mask_ptr = _mask_ptr_dest;
  613.     maskbit = revBitMask[_xpos&7];
  614.     y = _ypos;
  615.  
  616.     dstorg = dst = _backbuff_ptr;
  617.     height = _height2;
  618.     width = _width2;
  619.     len = _replen;
  620.     color = _repcolor;
  621.     src = _srcptr;
  622.  
  623.     if (_docontinue) goto StartPos;
  624.  
  625.     do {
  626.         len = *src++;
  627.         color = len>>_shrval;
  628.         len &= _maskval;
  629.         if (!len) len = *src++;
  630.         
  631.         do {
  632.             if (cost_scaleTable[_scaleIndexY++] < _scaleY) {
  633.                 if (color && y < _vscreenheight) {
  634.                     pcolor = _palette[color];
  635.                     if (pcolor==13)
  636.                         pcolor = _transEffect[*dst];
  637.                     *dst = pcolor;
  638.                 }
  639.                 dst += 320;
  640.                 y++;
  641.             }
  642.             if (!--height) {
  643.                 if(!--width)
  644.                     return;
  645.                 height = _height;
  646.                 y = _ypostop;
  647.                 _scaleIndexY = _scaleIndexYTop;
  648.                 t = _scaleIndexX;
  649.                 _scaleIndexX = t + _scaleIndexXStep;
  650.                 if (cost_scaleTable[t] < _scaleX) {
  651.                     _xpos += _scaleIndexXStep;
  652.                     if (_xpos >= 320)
  653.                         return;
  654.                     _backbuff_ptr += _scaleIndexXStep;
  655.                 }
  656.                 dst = _backbuff_ptr;
  657.             }
  658. StartPos:;
  659.         } while (--len);
  660.     } while(1);
  661. }
  662.  
  663. void CostumeRenderer::loadCostume(int id) {
  664.     _ptr = _vm->getResourceAddress(3, id);
  665.     
  666.     if (_vm->_majorScummVersion == 6) {
  667.         _ptr += 8;
  668.     } else {
  669.         _ptr += 2;
  670.     }
  671.  
  672.     switch(_ptr[7]&0x7F) {
  673.     case 0x58:
  674.         _numColors = 16;
  675.         break;
  676.     case 0x59:
  677.         _numColors = 32;
  678.         break;
  679.     case 0x60: /* New since version 6 */
  680.         _numColors = 16;
  681.         break;
  682.     case 0x61: /* New since version 6 */
  683.         _numColors = 32;
  684.         break;
  685.     default:
  686.         error("Costume %d is invalid", id);
  687.     }
  688.  
  689.     _dataptr = _ptr + READ_LE_UINT16(_ptr + _numColors + 8);
  690. }
  691.  
  692. byte CostumeRenderer::drawOneSlot(Actor *a, int slot) {
  693.     int i;
  694.     int code;
  695.     CostumeData *cd = &a->cost;
  696.  
  697.     if (cd->a[slot]==0xFFFF || cd->hdr & (1<<slot))
  698.         return 0;
  699.     
  700.     i = cd->a[slot]&0x7FFF;
  701.     _frameptr = _ptr + READ_LE_UINT16(_ptr + _numColors + slot*2 + 10);
  702.     code = _dataptr[i]&0x7F;
  703.     _srcptr = _ptr + READ_LE_UINT16(_frameptr + code*2);
  704.  
  705.     if (code != 0x7B) {
  706.         return mainRoutine(a, slot, code);
  707.     }
  708.  
  709.     return 0;
  710. }
  711.  
  712. byte CostumeRenderer::drawCostume(Actor *a) {
  713.     int i;
  714.     byte r = 0;
  715.  
  716.     _xmove = _ymove = 0;
  717.     for (i=0; i<16; i++)
  718.         r|=drawOneSlot(a, i);
  719.     return r;
  720. }
  721.  
  722. byte CostumeRenderer::animateOneSlot(Actor *a, int slot) {
  723.     int highflag;
  724.     int i,end;
  725.     byte code,nc;
  726.  
  727.     if (a->cost.a[slot]==0xFFFF)
  728.         return 0;
  729.  
  730.     highflag = a->cost.a[slot]&0x8000;
  731.     i = a->cost.a[slot]&0x7FFF;
  732.     end = a->cost.c[slot];
  733.     code=_dataptr[i]&0x7F;
  734.  
  735.     do {
  736.         if (!highflag) {
  737.             if (i++ >= end)
  738.                 i = a->cost.b[slot];
  739.         } else {
  740.             if (i != end)
  741.                 i++;
  742.         }
  743.  
  744.         nc = _dataptr[i];
  745.  
  746.         if (nc==0x7C) {
  747.             a->cost.animCounter1++;
  748.             if(a->cost.b[slot] != end)
  749.                 continue;
  750.         } else {
  751.             if (_vm->_majorScummVersion == 6) {
  752.                 if (nc>=0x71 && nc<=0x78) {
  753.                     _vm->addSoundToQueue2(a->sound[nc-0x71]);
  754.                     if(a->cost.b[slot] != end)
  755.                         continue;
  756.                 }
  757.             } else {
  758.                 if (nc==0x78) {
  759.                     a->cost.animCounter2++;
  760.                     if(a->cost.b[slot] != end)
  761.                         continue;
  762.                 }
  763.             }
  764.         }
  765.  
  766.         a->cost.a[slot] = i|highflag;
  767.         return (_dataptr[i]&0x7F) != code;
  768.     } while(1);
  769. }
  770.  
  771. byte CostumeRenderer::animate(Actor *a) {
  772.     int i;
  773.     byte r = 0;
  774.  
  775.     for (i=0; i<16; i++) {
  776.         if(a->cost.a[i]!=0xFFFF)
  777.             r+=animateOneSlot(a, i);
  778.     }
  779.     return r;
  780. }
  781.  
  782.