#include "stdafx.h"

#include "UI.h"

#include <stdio.h>

#include "Objects.h"
#include "Dispatch.h"
#include "CSB.h"
#include "Data.h"

pnt TAG005088(i16 P1, i16 P2, i16 *P3, i16 *P4)
{
  dReg D0, D4, D5, D6, D7;
  aReg A2, A3, A3a;
  pnt pnt_4;
//;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  D7W = P1;
  A2 = &d.Byte5696[2*D7W];
  if (P2 > 32) P2 = 32;
  D6W = sw((P2 * (UI8)(A2[0]) + P2/2) / 32);
  //D6W += P2/2;
  //D6W /= 32;
  D5W = sw((P2 * (UI8)(A2[1]) + P2/2) / 32);
  //D5W += P1/2;
  //D5 /= 32;
  if ( (P2==32) && (D7W!=3) )
  {
    A3 = GetGraphicAddress(D7W+348);
  }
  else
  {
    D4W = sw(14*D7W + P2/2 +436);
    D0W = TAG022c90(D4W);
    if (D0W != 0)
    {
      A3 = TAG022d38(D4W);
    }
    else
    {
      pnt_4 = GetGraphicAddress(Smaller(D7W, 2)+348);
      if (D7W == 3)
      {
        A3 = d.Byte5712;
      }
      else
      {
        A3 = d.Byte156;
      };
      ShrinkBLT(pnt_4,                //src
                A3a = TAG022d38(D4W),//dst
                2 * (UI8)(A2[0]),        //src width
                (UI8)(A2[1]),            //src height
                2 * D6W,             //dst width
                D5W,                 //dst height
                A3);                  // ??
      A3 = A3a;
      TAG022d5e(D4W);
    };
  };
  *P3 = D6W;
  *P4 = D5W;
  return A3;
}
//*********************************************************
//
//*********************************************************
//   TAG0051a4
void DrawRoomObjects(RN firstObject,
                     i32 facing,
                     i32 mapX,
                     i32 mapY,
                     i32 RelativeCellNumber,
                     i16 DrawingOrder)
{ // Drawing Order executed four bits at a time from
  // the bottom. Numbered from 1 clockwise starting in
  // far left corner.
  //
//;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	dReg           D0, D1, D3, D4, D5, D7;
  aReg           A0, A2, A3;
  ui8           *uA3;
  ITEM6         *pI6_A2;
  ITEM12        *pI12_A2;
  ITEM110       *pI110_A0;
  ITEM110s      *pI110s_A0;
  static ITEM16 staticITEM16;
  RN             objD7;
  i16            w_192;
  i16            MonsterAbsFacing_182;//0=north, 1=east, etc
  i16            LOCAL_172;
  i8             b_170[8];
  i16            w_162;
  i16            w_160;
  i16            LOCAL_158=0;
  i16            w_156;
  i16           *pw_154;
  DBCOMMON      *pdb_150;
  DB15          *pDB15_146;
  i16            w_142;
  i16            w_140;
  i16            w_138=-1;
  i16            CurrentRelativePosition=-1;
  i16            LOCAL_132;
  i16            MissilePresent;//134;
  i16            w_130;
  i16            w_128;
  i16            w_126;
  i16            w_124;
  i16            w_122=-1;
  i8             b_120[2];
  DB14          *pDB14_118;
  i16            w_114;
  i16            w_112;
  i16            LOCAL_110;
  i16            LOCAL_108=0;
  i16            w_106;
  i16            w_104;
  i16            w_102=-1;
  i16            w_100;
  i16            w_98;
  i16            LOCAL_96; // boolean value?
  i16            w_94;
  i16            w_90;
  i16            w_88;
  i16            w_86;
  i16            w_84;
  i16            MonsterIndex_82;
  i16            w_78;
  i16            w_76=-1;
  i16            MonsterRelFacing_74;//0=away,1=right,2=toward,3=left
  i16            MonsterSize_72=-1;
  ITEM12        *pI12_70=NULL;
  MONSTERDESC   *pmtDesc;
  ITEM16        *pi16_62 = NULL;
  DB4           *pDB4_58=NULL;
  RN             objMonster_54(RNnul);
  i16            w_52=-1;
  i16            LOCAL_50;
  i16            PositionListIndex;//48//which nibble we are processing
  i16            RelativeCell_46;
  RN             FirstObject; //44// set to parameter 'firstObject' forever
  RectPos        rect_42;
  bool           LOCAL_38;
  bool           LOCAL_36;
  i16            LOCAL_34;
  i16            LOCAL_32;
  i16            LOCAL_30;
  ui16           CurAbsPos; //28//contains position
  i32            MiddleLeftRight;//26// 0, 1, or 2
  i16            LOCAL_24; // Graphic height?
  i16            LOCAL_22;
  i16            ZeroDrawingOrder_20;//Initially specified order = 0
  i16            w_18=-1;
  ui8           *pub_16;
  pnt            LOCAL_12;
  pnt            LOCAL_8;
  i32            PositionList;
  A3 = NULL;
  //D7L = -1;
#ifdef _VERIFYPPQ
  verifyppq();
#endif
	objD7 = firstObject;
	//D6W = relativeCellNum;
	if (objD7 == RNeof) return;
  pDB4_58 = NULL;
  objMonster_54 = RN(RNnul);
  LOCAL_108 = 0;
  MissilePresent = 0;
  LOCAL_158 = 0;
  PositionListIndex = 0; // start with rightmost nibble
  FirstObject = objD7;
//  D0W = P6 & 8;
  if ((DrawingOrder & 8) != 0)
  {
    LOCAL_110 = sw((DrawingOrder & 1) + 1);
    DrawingOrder = (I16)((DrawingOrder>>4) & 0xfff);
  }
  else
  {
    LOCAL_110 = 0;
  };
  PositionList = (ui16)DrawingOrder;

  ZeroDrawingOrder_20 = (I16)((PositionList == 0)?1:0);
  RelativeCell_46 = sw(RelativeCellNumber);
  MiddleLeftRight = (RelativeCellNumber+3) % 3;
  SET(D0B, (d.Word1836 & 0xfe) == 10);
  if (D0B != 0)
  {
    D0W = 136;
  };
  SET(D0B, D0B!=0);
  LOCAL_172 = (I16)(D0W & 1);
NextPosition:
  if (ZeroDrawingOrder_20 != 0)
  {
    D5W = 4;
    CurAbsPos = (I16)((facing+2) & 3);
    LOCAL_50 = 2;
  }
  else
  {
    D5W = (I16)((PositionList & 15) - 1);
    CurrentRelativePosition = D5W;
    PositionList >>= 4;//Put next nibble at bottom
    PositionListIndex++;//Advance to next nibble
    CurAbsPos = (I16)((D5W + facing) & 3);//position in cell
    objD7 = FirstObject;
    RelativeCellNumber = RelativeCell_46;
    LOCAL_50 = 0;
  };
  LOCAL_50 = sw(LOCAL_50 + ((CurAbsPos & 1) << 3));
  LOCAL_132 = 0;
NextObject:
  // Loop here for each object in the room.
    ASSERT(objD7 != RNnul);
  D0W = D4W = sw(objD7.dbType());
  if (D4W <= dbACTUATOR)
  {
    objD7 = GetDBRecordLink(objD7);
    if (objD7 != RNeof) goto NextObject;
    goto PositionCompleted;
  };
  if (D4W != dbMONSTER) goto tag0052d6;
  objMonster_54 = objD7;
  goto tag0057d0;
tag0052d6:
  if (D4W == dbTELEPORTER) goto tag0057d0;
  if (D4W != dbMISSILE) goto tag0052e6;
  MissilePresent = 1; // Set if db==14 (fireball, eg)
  goto tag0057d0;
tag0052e6:
  if (D4W != dbCLOUD) goto tag0052f6;
  LOCAL_158 = 1;
  goto tag0057d0;
tag0052f6:
  if (RelativeCellNumber < 0) goto tag0057d0;
  if (RelativeCellNumber > 9) goto tag0057d0;
  if (CurAbsPos != objD7.pos()) goto tag0057d0;
  D0W = GetObjectIndex(objD7);
  D0W = d.ObjDesc[D0W].byte2;
  pI6_A2 = &d.s5604[D0W];
  D4W = 360;
  D3W = (UI8)(pI6_A2->byte0);
  D4W = sw(D4W + D3W); // Graphic number?
  if (ZeroDrawingOrder_20 != 0)
  {
    D0W = (I16)(pI6_A2->byte4 & 16);
  };
  SET(D0B, (ZeroDrawingOrder_20!=0)&&(D0W!=0));
  if (D0B != 0)
  {
    D0W = sw(MiddleLeftRight); // Middle
    SET(D0B, D0W==0);
  };
  LOCAL_34 = (I16)(D0W & 1);
  if (LOCAL_34)
  {
    D4W++;
  };
  //D0 = 100 * (UI8)(psA2->byte5);
  //D0 += d.Byte6090;
  pub_16 = (ui8 *)&d.s6090[pI6_A2->byte5].s[RelativeCellNumber].byte0[2*D5W];
  //A0 += 2*D5W;
  //pnt_16 = A0;
  if (pub_16[1] == 0) goto tag0057d0;
tag0053a0:
  D0W = (I16)(pI6_A2->byte4 & 1);
  if (D0W != 0)
  {
    D0W = LOCAL_34;
    SET(D0W, D0W==0);
  };
  SET(D0B, D0W!=0);
  if (D0B != 0)
  {
    SET(D0B, MiddleLeftRight==2);
    if (D0B == 0)
    {
      D0W = sw(MiddleLeftRight); // Middle
      SET(D0B, D0W==0);
      if (D0B != 0)
      {
        SET(D0B, D5W==1);
        if (D0B == 0)
        {
          SET(D0B, D5W==2);
        };
      };
    };
  };
  LOCAL_36 = D0W & 1;
  LOCAL_30 = 0;
  if (   (RelativeCellNumber ==9)
      || ( (RelativeCellNumber>=6) && (D5W>=2) ) )
  {
    D0W = sw(MiddleLeftRight);
    SET(D0B, D0W==0);
    if (D0B != 0)
    {
      SET(D0B, LOCAL_132 == 0);
    };
    LOCAL_38 = D0W&1;
    w_52 = 0;
    A3 = GetGraphicAddress(D4W);
    LOCAL_22 = (UI8)(pI6_A2->byte2);
    LOCAL_24 = (UI8)(pI6_A2->byte3);
    if (LOCAL_36)
    {
      MakeMirror(A3, d.Pointer1848, LOCAL_22, LOCAL_24);
      A3 = d.Pointer1848;
    };
  }
  else
  {
    LOCAL_38 = 0;
    D3W = pI6_A2->uByte1;
    w_18 = sw(D3W + 104);

    if (   (RelativeCellNumber>=6)
        || ( (RelativeCellNumber>=3) && (D5W>=2) ) )
    {
      w_18 += 1;
      w_52 = 1;
      LOCAL_22 = sw(((UI8)(pI6_A2->byte2) * 20 + 10)>>5); //times 20/32
      LOCAL_24 = sw((pI6_A2->byte3 * 20 + 10)>>5); //times 20/32
      LOCAL_8 = d.Byte5744;
    }
    else
    {
      w_52 = 2;
      LOCAL_22 = sw(((UI8)(pI6_A2->byte2) * 16 + 8)>>5); // width in bytes
      LOCAL_24 = sw(((UI8)(pI6_A2->byte3) * 16 + 8)>>5); //height
      LOCAL_8 = d.Byte5728;
    };
    if (LOCAL_36)
    {
      w_18 += 2;
      LOCAL_30 = sw((7 - ((LOCAL_22 - 1) & 7)) << 1);
    }
    else
    {
      if (LOCAL_34)
      {
        w_18 += 4;
      };
    };
    D0W = TAG022c90(w_18);
    if (D0W)
    {
      A3 = TAG022d38(w_18);
    }
    else
    {
      LOCAL_12 = GetGraphicAddress(D4W);
      ShrinkBLT(LOCAL_12,              //src
               A3 = TAG022d38(w_18),   //dest
               (UI8)(pI6_A2->byte2) << 1, //src width
               (UI8)(pI6_A2->byte3),      //src height
               LOCAL_22 << 1,          //dst width
               LOCAL_24,               //dst height
               LOCAL_8);
      if (LOCAL_36)
      {
        Mirror(A3,
               (LOCAL_22+7)&0xfff8, // width
               LOCAL_24);      // height
      };
      TAG022d5e(w_18);
    };
  };
  D4W = *pub_16; // Viewport X
  rect_42.b.y2 = *(pub_16+1); // Viewport Y

  if (LOCAL_132 == 0)
  {
    D0B = d.Byte5790[2 * LOCAL_50];
    D1L = (w_52 & 0xffff) << 3;
    A0 = d.Byte6652;
    A0 += D1L;
    A0 += D0W&0xff;
    D0W = *A0;
    D4W = sw(D4W + D0W);
    D0B = *(d.Byte5790 + 2*LOCAL_50 + 1);
    D1L = (w_52&0xffff)<<3;
    A0 = d.Byte6652;
    A0 += D1L;
    A0 += D0W & 0xff;
    D0B = *A0;
    rect_42.b.y2 = ub(rect_42.b.y2 + D0B);
    LOCAL_50++;
    if (ZeroDrawingOrder_20)
    {
      if (LOCAL_50 >= 14)
      {
        LOCAL_50 = 2;
      };
    }
    else
    {
      LOCAL_50 &= 15;
    };
  };
  rect_42.b.y1 = ub(rect_42.b.y2 - (LOCAL_24-1));
  if (rect_42.b.y2 > 135)
  {
    rect_42.b.y2 = 135;
  };
  D0W = sw(Smaller(223, D4W + LOCAL_22));
  rect_42.b.x2 = D0B;
  rect_42.b.x1 = (ui8)Larger(0, D4W-LOCAL_22+1);
  if (rect_42.b.x1 != 0)
  {
    if (LOCAL_36)
    {
      D4W = LOCAL_30;
    }
    else
    {
      D4W = 0;
    }
  }
  else
  {
    D4W = sw(LOCAL_22 - D4W - 1);
  };
  if (LOCAL_38)
  {
    //LOCAL_12 = A3; // Save A3 no longer necessary
    uA3 = d.ViewportObjectButtons[D5W];
    if (*uA3 == 255)
    {
      MemMove((pnt)&rect_42, (pnt)uA3, 4);
      D0W = uA3[3];
      D3W = uA3[2];
      LOCAL_32 = sw(D0W - D3W);
      if (LOCAL_32 < 14)
      {
        LOCAL_32 >>= 1;
        uA3[2] = ub(uA3[2] + LOCAL_24 - 7);
        if (LOCAL_32 < 4)
        {
          uA3[3] = ub(uA3[3] - (LOCAL_32 - 3));
        };
      };
    }
    else
    {
      uA3[0] = ub(Smaller(uA3[0], rect_42.b.x1));
      uA3[1] = ub(Larger(rect_42.b.x2, uA3[1]));
      uA3[2] = ub(Smaller(uA3[2], rect_42.b.y1));
      uA3[3] = ub(Larger(uA3[3], rect_42.b.y2));
    };
    //A3 = LOCAL_12; //Restore A3 no longer necessary
    d.rn10574[D5W] = objD7;
  };
  TAG0088b2(A3,
            d.pViewportBMP,
            &rect_42,
            D4W,
            0,
            (LOCAL_22 + 7) & 0xfff8,
            112,
            10);
  if (LOCAL_132) goto tag006584;
tag0057d0:
  objD7 = GetDBRecordLink(objD7);
  if (objD7 != RNeof) goto NextObject;
  // We have drawn all objects at this position.  If we saw
  // a monster then perhaps we should draw it now.
  // D5 should have the current relative position being
  // drawn.  0=far left, 1 = far right, etc.
PositionCompleted:
  if ( (D5W == 4) || (RelativeCellNumber < 0) )goto tag0065bc;
  LOCAL_96 =   ((D5W <= 1) || (PositionListIndex==1))
            && ((PositionList==0) || ((PositionList&15) >= 3));

  if ( (objMonster_54 == RNnul) || (LOCAL_108!=0) ) goto CheckNextPosition;

  if (pDB4_58 == NULL)
  {
    pDB4_58 = GetRecordAddressDB4(objMonster_54);
    //D0L = 16 * pDB4_58->uByte(5);
    //ASSERT(pDB4_58->uByte(5) < d.MaxITEM16);
    if (pDB4_58->groupIndex() >= d.MaxITEM16)
      pi16_62 = &staticITEM16;
    else
      pi16_62 = &d.Item16[pDB4_58->groupIndex()];
    pmtDesc = &d.MonsterDescriptor[pDB4_58->monsterType()];
    pI12_70 = &d.Item6414[pmtDesc->uByte0];
    MonsterSize_72 = pmtDesc->horizontalSize();
    w_76 = pmtDesc->word4;
  };
  pI12_A2 = pI12_70; // Monster's graphic information
  D7W = OrdinalOfMonsterAtPosition(pDB4_58, CurAbsPos);//TAG00abae
  if (D7W)
  { // At least part of a monster is here!
    D7W--; // index of monster seen at this position
    MonsterIndex_82 = D7W;
  }
  else
  {
    if (MonsterSize_72 == 1)
    {
      D7W = 0;
      MonsterIndex_82 = -1;
    }
    else
    {
      goto CheckNextPosition;
    };
  };
//  MonsterAbsFacing_182 = (I16)((pi16_62->facings() >> 2*D7W) & 3);//monster facing
  MonsterAbsFacing_182 = (I16)(TwoBitNibble(pi16_62->facings(),D7W));//monster facing
  MonsterRelFacing_74 = (I16)((facing - MonsterAbsFacing_182) & 3);//facing relative to party facing
  w_94 = 0;
  D4W = pi16_62->positions();
  if (D4W == 255)
  {
    if ( (PositionList) || (LOCAL_110==1) ) goto CheckNextPosition;
    LOCAL_108 = 1;
    if ( (MonsterSize_72==1) && (MonsterRelFacing_74 & 1) )
    {
      D5W = 3;
    }
    else
    {
      D5W = 4;
    };
  }
  else
  {
    if (  (MonsterSize_72==1) //2-square monster
        &&((LOCAL_96) || (PositionList==0) || (MonsterIndex_82<0)) )
    {
      if ( (LOCAL_96) && (LOCAL_110!=2) )
      {
        if ( (MonsterIndex_82>=0) && (MonsterRelFacing_74&1) )
        {
          D5W = 2;
        }
        else
        {
          goto CheckNextPosition;
        };
      }
      else
      {
        if ( (LOCAL_110!=1) && (PositionList==0) )
        {
          if (MonsterRelFacing_74 & 1)
          {
            if (MonsterIndex_82 >= 0)
            {
              D5W = 4;
            }
            else
            {
              goto CheckNextPosition;
            };
          }
          else
          {
            LOCAL_108 = 1;
            if (MonsterIndex_82 < 0)
            {
              MonsterIndex_82 = 0;
            };
            w_94 = pDB4_58->numMonM1(); //#monsters-1
//            D4W = sw((D4W >> (2*D7W)) & 3);//position of this monster
            D4W = sw(TwoBitNibble(D4W,D7W));//position of this monster
            if ( (D4W==facing) || (D4W==((facing-1)&3)) )
            {
              D5W = 0;
            }
            else
            {
              D5W = 1;
            };
          };
        }
        else
        {
        goto CheckNextPosition;
        };
      };
    }
    else
    {
      if (MonsterSize_72) goto CheckNextPosition;
    };
  };
  w_78 = pi16_62->uByte12[MonsterIndex_82];
  if (RelativeCellNumber > 9)
  {
    RelativeCellNumber--;
  };
tag005a60:
  //D1W = D6W;
  D0W = pI12_A2->uByte10;
  //D0L = 110 * BITS4_7(D0W);
  pI110_A0 = &d.s6982[BITS4_7(D0W)];
  //D1L = 10 * D6W;
  pI110s_A0 = &pI110_A0->s[RelativeCellNumber];
  A0 = &pI110s_A0->byte0[2*D5W];
  pub_16 = (ui8 *)A0;
  if (pub_16[1] == 0) goto tag00600c;
  D7W = w_76;
  D4W = sw(446 + pI12_A2->word0);
  w_18 = pI12_A2->word2;

  D0W = (I16)(D7W & 8);
  if (D0W != 0)
  {
    D0W = (I16)(MonsterRelFacing_74 & 1);
  };
  SET(D0B, D0W!=0);
  w_98 = (I16)(D0W&1);
  if (w_98)
  {
    w_100 = 0;
    w_104 = 0;
    w_106 = 0;
    D4W++;
    w_18 += 2;
    LOCAL_22 = pI12_A2->uByte6;
    w_86 = LOCAL_22;
    LOCAL_24 = pI12_A2->uByte7;
    w_88 = LOCAL_24;
  }
  else
  {
    D0W = (I16)(D7W & 16);
    if (D0W != 0)
    {
      SET(D0B, MonsterRelFacing_74==0);
    };
    SET(D0B, D0B!=0);
    w_100 = (I16)(D0W & 1);
    SET(D0W, w_100 == 0);
    if (D0B != 0)
    {
      D0W = (I16)(w_78 & 128);
    }
    SET(D0W, D0W!=0);
    if (D0W != 0)
    {
      D0W = (I16)(D7W & 32);
    };
    SET(D0W, D0W!=0);
    w_104 = (I16)(D0W & 1);
    if (w_104 != 0)
    {
      w_106 = 0;
      LOCAL_22 = pI12_A2->uByte8;
      w_86 = LOCAL_22;
      LOCAL_24 = pI12_A2->uByte9;
      w_88 = LOCAL_24;
      D4W++;
      w_18 += 2;
      if (D7W & 8)
      {
        D4W++;
        w_18 += 2;
      };
      if (D7W & 16)
      {
        D4W++;
        w_18 += 2;
      };
    }
    else
    {
      LOCAL_22 = pI12_A2->uByte4;
      w_86 = LOCAL_22;
      LOCAL_24 = pI12_A2->uByte5;
      w_88 = LOCAL_24;
      if (w_100)
      {
        w_106 = 0;
        if (D7W & 8)
        {
          D4W += 2;
          w_18 += 4;
        }
        else
        {
          D4W++;
          w_18 += 2;
        };
      }
      else
      {
        D0W = (I16)(D7W & 4);
        if (D0W != 0)
        {
          D0W = (I16)(w_78 & 64);
        };
        SET(D0W, D0W!=0);
        w_106 = (I16)(D0W & 1);
        if (w_106 != 0)
        {
          w_18 += 2;
          if (D7W & 8)
          {
            w_18 += 2;
          };
          if (D7W & 16)
          {
            w_18 += 2;
          };
          if (D7W & 32)
          {
            w_18 += 2;
          };
        };
      };
    };
  };
  if (RelativeCellNumber >= 6)
  {
    w_90 = 0;
    w_52 = 0;
    w_84 = (I16)(pI12_A2->uByte10 & 15);
    if (w_98)
    {
      A3 = GetGraphicAddress(D4W);
      if (MonsterRelFacing_74 == 1)
      {
        MakeMirror(A3, d.Pointer1848, LOCAL_22, LOCAL_24);
        A3 = d.Pointer1848;
      };
    }
    else
    {
      if ( (w_100!=0) || (w_106==0) )
      {
        A3 = GetGraphicAddress(D4W);
        if (w_104)
        {
          if (w_78 & 64)
          {
            MakeMirror(A3, d.Pointer1848, LOCAL_22, LOCAL_24);
            A3 = d.Pointer1848;
          };
        };
      }
      else
      {
        D0W = TAG022c90(w_18);
        if (D0W)
        {
          A3 = TAG022d38(w_18);
        }
        else
        {
          LOCAL_12 = GetGraphicAddress(D4W);
          if (D7W & 4)
          {
//
            MakeMirror(LOCAL_12,
                       A3 = TAG022d38(w_18),
                       LOCAL_22,
                       LOCAL_24);
          };
          TAG022d5e(w_18);
        };
      };
    };
  }
  else
  {
    if (w_106)
    {
      w_18++;
    };
    if (RelativeCellNumber >= 3)
    {
      w_18++;
      w_52 = 1;

      D0W = (I16)(D7W & 128);
      if (D0W != 0)
      {
        SET(D0W, w_98==0);
      };
      SET(D0W, D0W!=0);
      if (D0B !=0)
      {
        SET(D0W, w_100==0);
      };
      if (D0W != 0)
      {
        SET(D0W, w_104==0);
      };
      w_102 = (I16)(D0W & 1);
      LOCAL_8 = d.Byte6628;
      w_112 = 20;
    }
    else
    {
      w_52 = 2;
      w_106 = 0;
      LOCAL_8 = d.Byte6612;
      w_112 = 16;
    };
    D0L = w_86 * w_112;
    D0W = sw(D0W + (w_112 >> 1));
    LOCAL_22 = sw(D0W >> 5);
    D0L = w_88 * w_112;
    D0W = sw(D0W + (w_112 >> 1));
    LOCAL_24 = sw(D0W >> 5);
    D0W = (I16)(pI12_A2->uByte10 & 15);
    D0W = (UI8)(LOCAL_8[D0W]);
    w_84 = sw(D0W / 10);
    w_114 = TAG022c90(w_18);
    if (w_114)
    {
      A3 = TAG022d38(w_18);
    }
    else
    {
      LOCAL_12 = GetGraphicAddress(D4W);
      ShrinkBLT(LOCAL_12,
                A3 = TAG022d38(w_18),
                2 * w_86,
                w_88,
                2 * LOCAL_22,
                LOCAL_24,
                LOCAL_8);
      TAG022d5e(w_18);
    };
    if (w_98 == 0) goto tag005e60;
    if (MonsterRelFacing_74 == 1) goto tag005e8c;
tag005e60:
    if (w_104 == 0) goto tag005e70;
    if (w_78 & 64) goto tag005e8c;
tag005e70:
    if (w_102 == 0) goto tag005e7e;
    if (D7W & 256) goto tag005e8c;
tag005e7e:
    if (w_106 == 0) goto tag005ee8;
    if ((D7W & 4)==0) goto tag005ee8;
tag005e8c:
    if (w_106==0) goto tag005e98;
    if (w_114 != 0) goto tag005ed0;
tag005e98:
    D4W = (UI16)((LOCAL_22 +7) & 0xfff8);
    if (w_106 == 0)
    {
      MemMove(A3, d.Pointer1848, (ui16)D4W*(ui16)LOCAL_24);
      A3 = d.Pointer1848;
    };
    Mirror(A3, D4W, LOCAL_24);
tag005ed0:
    D1W = (I16)((LOCAL_22-1)&7);
    D0W = sw(7-D1W);
    w_90 = sw(D0W << 1);
    goto tag005eec;
tag005ee8:
    w_90 = 0;
tag005eec:
    A0 = (pnt)pub_16;
  };
  D4W = (UI8)(A0[1]);
  D0W = (I16)((w_78>>3) & 7);
  D1L = (UI16)(w_52) >> 3;
  D4W = sw(D4W + sb(d.Byte6652[D1L+D0W]));
  rect_42.b.y2 = ub(Smaller(D4W, 135));
  rect_42.b.y1 = ub(Larger(0, D4W - LOCAL_24 + 1));
  D4W = pub_16[0];
  D0W = (I16)(w_78 & 7);
  D1L = (UI16)(w_52) << 3;
  D4W = sw(D4W + d.Byte6652[D1L + D0W]);
  if (MiddleLeftRight == 1) // Left side
  {
    D4W -= 100;
  }
  else
  {
    if (MiddleLeftRight) // if left or right
    {
      D4W += 100;
    };
  };
  rect_42.b.x2 = (ui8)ApplyLimits(0, D4W+LOCAL_22, 223);
  if (rect_42.b.x2)
  {
    rect_42.b.x1 = (ui8)ApplyLimits(0, D4W-LOCAL_22+1, 223);
    if (rect_42.b.x1)
    {
      if (rect_42.b.x1 == 223)
      {
        goto tag00600c;
      };
      D7W = w_90;
    }
    else
    {
      D7W = w_90;
      D7W = sw(D7W + LOCAL_22 - D4W - 1);
    };
    TAG0088b2(A3,
              d.pViewportBMP,
              &rect_42,
              D7W,
              0,
              (LOCAL_22 + 7) & 0xfff8,
              112,
              w_84);
  };
tag00600c:
  if (w_94)
  {
    w_94 = 0;
    SET(D0W, MonsterIndex_82==0);
    D0W &= 1;
    w_78 = pi16_62->uByte12[D0W];
    if (D5W == 1)
    {
      D5W = 0;
    }
    else
    {
      D5W = 1;
    };
    goto tag005a60;
  };
CheckNextPosition:
//
  if (   (MissilePresent==0)
      || ((RelativeCellNumber = RelativeCell_46)>9) ) goto tag0065b4;
  D5W = CurrentRelativePosition;
  A0 = &d.s6090[0].s[RelativeCellNumber].byte0[2*D5W];//roomobject[relativeRoom][position]
  D0W = *((ui8 *)A0);
  w_122 = D0W; // x position within viewport
  if (w_122 == 0) goto tag0065b4;
  objD7 = FirstObject;
tag006080:
  if (objD7.dbType() != dbMISSILE) goto tag006584; // fireball is 14
  if (objD7.pos() != CurAbsPos) goto tag006584;
  pDB14_118 = GetRecordAddressDB14(objD7);
  D4W = TAG0093d4(pDB14_118->flyingObject());
  if (D4W >= 0) goto tag006548;
  //D0L = -6 * D4W;
  A2 = &d.Byte5688[-6*D4W-6];
  D4W = sw((UI8)(*A2) + 316);
  w_126 = (I16)(LE16(wordGear(A2+4)) & 3);
  SET(D0W, (LE16(wordGear(A2+4))&0x100)==0);
  w_130 = (I16)(D0W & 1);
//
//
  if (   ((w_130!=0) || (pDB14_118->energyRemaining()==255))
      && (RelativeCellNumber==9) )
  {
    w_112 = 0;
    LOCAL_22 = (UI8)(A2[2]);
    LOCAL_24 = (UI8)(A2[3]);
  }
  else
  {
    w_52 = sw(2 * (RelativeCellNumber / 3) + D5W/2);
    w_112 = (UI8)(d.Byte5752[w_52]);
    if (w_130 == 0)
    {
      w_192 = sw(Larger(96, pDB14_118->energyRemaining()+1));
      w_112 = sw((w_112 * w_192) >> 8);
    };
    D0W = sw((UI8)(A2[2]) * w_112);
    D1W = sw(w_112 >> 1);
    LOCAL_22 = sw((D0W + D1W) >> 5);
    D0W = sw((UI8)(A2[3]) * w_112);
    D1W = sw(w_112 >> 1);
    LOCAL_24 = sw((D0W + D1W) >> 5);
  };
  SET(D0W, w_126==0);
  w_140 = (I16)(D0W & 1);
  if (w_140 != 0)
  {
    w_138 = (I16)((mapX + mapY) & 1);
  };
  if (w_126 == 3)
  {
    w_128 = 0;
    LOCAL_36 = 0;
    w_142 = 0;
  }
  else
  {
    D0W = pDB14_118->timerIndex();
    D0W = d.Timers[D0W].timerWord8();
    w_124 = BITS10_11(D0W);
    D0W = (I16)(w_124 & 1);
    D1W = (I16)(facing & 1);
    if (D1W != D0W)
    {
      if (w_126 == 2)
      {
        w_128 = 1;
      }
      else
      {
        w_128 = 2;
      };
      D0W = w_140;
      if (D0W != 0)
      {
        SET(D0W, D5W==0);
        if (D0B == 0)
        {
          SET(D0W, D5W==3);
        };
        LOCAL_36 = D0W & 1;
        w_142 = w_138;
        if (w_142 == 0)
        {
          SET(D0W, LOCAL_36==0);
          LOCAL_36 = D0W & 1;
        };
      }
      else
      {
        w_142 = 0;
        SET(D0W, ((facing+1)&3)==w_124);
        LOCAL_36 = D0W & 1;
      };
    }
    else
    {
      if (w_126 >= 2) goto tag0062d6;
      if (w_126 != 1) goto tag0062ca;
      if (w_124 != facing) goto tag0062d6;
tag0062ca:
      if (w_140 == 0) goto tag0062dc;
      if (w_138 == 0) goto tag0062dc;
tag0062d6:
      w_128 = 0;
      goto tag0062e2;
tag0062dc:
      w_128 = 1;
tag0062e2:
      D0W = w_140;
      if (D0W != 0)
      {
        SET(D0W, D5W < 2);
      };
      SET(D0W, D0W!=0);
      w_142 = (I16)(D0W & 1);
      D0W = wordGear(A2+4);
      if (D0W != 0)
      {
        SET(D0W, MiddleLeftRight==2); // right side
        if (D0B == 0)
        {
          SET(D0W, MiddleLeftRight==0);
          if (D0B != 0)
          {
            SET(D0W, D5W==1);
            if (D0B == 0)
            {
              SET(D0W, D5W==2);
            };
          };
        };
        SET(D0W, D0B==0);
      };
      SET(D0W, D0W!=0);
      LOCAL_36 = D0W & 1;
    };
  };
  D4W = sw(D4W + w_128);
  LOCAL_30 = 0;
  if (w_112 == 0)
  {
    A3 = GetGraphicAddress(D4W);
  }
  else
  {
    if (LOCAL_36 != 0)
    {
      LOCAL_30 = sw((7 - ((LOCAL_22-1)&7))<<1);
    };
    if (w_130 != 0)
    {
      D3W = (UI8)(A2[1]);
      D0W = sw(282 + D3W);
      D0W = sw(D0W + 6*w_128 + w_52);
      w_18 = D0W;
      D0W = TAG022c90(w_18);
      if (D0W==0) goto tag0063be;
      A3 = TAG022d38(w_18);
    }
    else
    {
tag0063be:
      LOCAL_12 = GetGraphicAddress(D4W);
      if (w_130 != 0)
      {
        A3 = TAG022d38(w_18);
      }
      else
      {
        A3 = d.Pointer1848;
      };
      D0W = sw(w_52 >> 1);
      ShrinkBLT(LOCAL_12,
                A3,
                (UI8)(A2[2])<<1,
                (UI8)(A2[3]),
                LOCAL_22 <<1,
                LOCAL_24,
                d.Pointer1864[D0W]);
      if (w_130 != 0)
      {
        TAG022d5e(w_18);
      };
    };
  };

  if ( (LOCAL_36!=0) || (w_142!=0) )
  {
    D4W = (I16)((LOCAL_22 + 7) & 0xfff8);//width in bytes?
    if (A3 != d.Pointer1848)
    {
      MemMove(A3, d.Pointer1848, D4W * LOCAL_24);
      A3 = d.Pointer1848;
    };
    if (w_142 != 0)
    {
      TAG008840(A3, D4W, LOCAL_24); // pnt, width, height??
    };
    if (LOCAL_36 != 0)
    {
      Mirror(A3, D4W, LOCAL_24);//pnt,width,height??
    };
  };
  rect_42.b.y2 = ub(47 + (LOCAL_24>>1));
  D0W = sw(47 - (LOCAL_24 >> 1));
  D1W = (I16)(LOCAL_24 & 1);
  SET(D1W, (LOCAL_24&1)==0);
  rect_42.b.y1 = ub(D0W + (D1W&1));
  rect_42.b.x2 = ub(Smaller(223, w_122 + LOCAL_22));
  rect_42.b.x1 = ub(Larger(0, w_122 - LOCAL_22 +1));
  if (rect_42.b.x1 != 0)
  {
    if (LOCAL_36 != 0)
    {
      D4W = LOCAL_30;
    }
    else
    {
      D4W = 0;
    };
  }
  else
  {
    D4W = sw(Larger(LOCAL_30, LOCAL_22 - w_122 -1));
  };
  TAG0088b2(A3,
            d.pViewportBMP,
            &rect_42,
            D4W,
            0,
            (LOCAL_22+7)&0xfff8,
            112,
            10);
  goto tag006584;
tag006548:
  LOCAL_34 = 0;
  b_120[0] = (i8)w_122;
  b_120[1] = 47;
  pub_16 = (ui8 *)b_120;
  pI6_A2 = &d.s5604[D4W];
  D4W = sw((UI8)(pI6_A2->byte0) + 360);
  LOCAL_132 = 1;
  goto tag0053a0;
tag006584:
  objD7 = GetDBRecordLink(objD7);
  if (objD7 != RNeof) goto tag006080;
  if (LOCAL_172 != 0)
  {
    LOCAL_172 = 0;
    d.Word1836 += 6;
    if (d.Word1836 > 16)
    {
      d.Word1836 -= 3;
    };
  };
tag0065b4:
  if (PositionList != 0) goto NextPosition;
tag0065bc:
  if (LOCAL_158 == 0) return;
  pdb_150 = NULL;
  RelativeCellNumber = RelativeCell_46 + 3;
  RelativeCell_46 = sw(RelativeCellNumber / 3);
  objD7 = FirstObject;
tag0065e0:
  if (objD7.dbType() != dbCLOUD) goto tag006ab6;
  D5W = objD7.pos();
  pDB15_146 = GetRecordAddressDB15(objD7);
  D4W = pDB15_146->type();
  SET(D0B, D4W >= 100);
  w_160 = (I16)(D0W & 1);
//
  if (   (w_160!=0)
      && (  (RelativeCellNumber<3)
          ||(RelativeCellNumber>9)
          ||(D5W!=CurAbsPos) ) ) goto tag006ab6;
  w_162 = 0;
  if ( (D4W==0) || (D4W==2) || (D4W==101) )
  {
    D4W = 0;
  }
  else
  {
    if ((D4W==6) || (D4W==7))
    {
      D4W = 2;
      goto tag006774;
    }
    if (D4W ==40)
    {
      w_162 = 1;
      D4W = 3;
    }
    else
    {
      if (D4W == 100)
      {
        D0W = TAG0093d4(RN(RNLightning));
        D0W = sw(-D0W);
        A2 = d.Byte5688+6*(D0W-1);
        A3 = GetGraphicAddress((UI8)(A2[0]) + 317);
        ASSERT(RelativeCellNumber >= 3);
        pw_154 = &d.Word7246[3*(RelativeCellNumber-3)];
        D0L = (UI8)(A2[2]) * pw_154[2];
        LOCAL_22 = sw((D0W + pw_154[2]/2)>>5);
        D0W = (UI8)(A2[3]);
        D0L = D0W * pw_154[2];
        LOCAL_24 = sw((D0W + pw_154[2]/2)>>5);
        if (RelativeCellNumber != 9)
        {
          ShrinkBLT(A3,
                    d.Pointer1848,
                    2*(UI8)(A2[2]),
                    (UI8)(A2[3]),
                    2*LOCAL_22,
                    LOCAL_24,
                    d.Byte156);
          A3 = d.Pointer1848;
        };
        goto tag006932;
      };
      if (D4W == 50)
      {
        if (RelativeCellNumber >= 4)
        {
          pdb_150 = pDB15_146;
        };
        goto tag006ab6;
      };
      D4W = 1;
    };
  };
tag006774:
  if (RelativeCellNumber == 12)
  {
    if (w_162 != 0)
    {
      D4W--;
    };
    D4W *= 3;
    D5W = sw(pDB15_146->value() >> 5);
    if (D5W != 0)
    {
      D4W++;
      if (D5W >3)
      {
        D4W++;
      };
    };
    TAG022c90(0);
    A3 = GetGraphicAddress(D4W + 351);
    if (w_162 != 0)
    {
      ShrinkBLT(A3,             //src
                d.Pointer1848,  //dst
                48,             //src width
                32,             //src height
                48,             //dst width
                32,             //dst height
                d.Byte5712);    //???
      A3 = d.Pointer1848;
    };
    TAG008c98(A3,
              d.pViewportBMP,
              0,
              TAG022d38(0),
              (RectPos *)d.Word2530,
              sw(STRandom0_3() + 87),
              sw(STRandom() & 63),
              112,
              138,
              0,
              0);
    TAG022d5e(0);
    DeleteGraphic((ui16)0x8000);
    goto tag006852;
    //D0W = TAG01385a(&d.Byte11678);
    //goto tag006852;
    //d.Word4012 = 3217;
tag006852:
    goto tag006ab6;
  }
  else
  {
    if (w_160 != 0)
    {
      pw_154 = d.Word7222+3*RelativeCellNumber;
      w_156 = pw_154[2];
    }
    else
    {
      if (pDB15_146->b7())
      {
        pw_154 = d.Word7042 + 2*RelativeCellNumber;
      }
      else
      {
//
        if ( (D5W==facing) || (D5W==((facing-1)&3)) )
        {
          D5W = 0;
        }
        else
        {
          D5W = 1;
        };
        pw_154 = d.Word7162 + 4*RelativeCellNumber + 2*D5W;
      };
      D0W = sw(Larger(48, pDB15_146->value()+1));
      D1W = (UI8)(d.Byte5758[RelativeCell_46]);
      D0W = sw(Larger(4, D1W*D0W >>8));
      w_156 = (UI16)(D0W & 0xfffe);
    };
    A3 = TAG005088(D4W, w_156, &LOCAL_22, &LOCAL_24);
tag006932:
    w_142 = STRandomBool();
    LOCAL_30 = 0;
    LOCAL_36 = STRandomBool()!=0;
    if (LOCAL_36)
    {
      LOCAL_30 = sw(2 * (7 - ((LOCAL_22-1)&7)));
    };
    rect_42.b.y2 = ub(Smaller(135,
                            pw_154[1] + LOCAL_24/2));
    D0W = pw_154[1];
    D0W = sw(D0W - LOCAL_24/2);
    D1W = sw((LOCAL_24 & 1) == 0 ? 1 : 0);
    D4W = sw(Larger(0, D0W + D1W));
    if (D4W < 136)
    {
      rect_42.b.y1 = D4UB;
      D4W = sw(Smaller(223, pw_154[0]+LOCAL_22));
      if (D4W >= 0)
      {
        rect_42.b.x2 = D4UB;
        D4W = pw_154[0];
        rect_42.b.x1 = (ui8)ApplyLimits(0,D4W-LOCAL_22 +1, 223);
        if (rect_42.b.x1 != 0)
        {
          D4W = LOCAL_30;
        }
        else
        {
          D4W = sw(Larger(LOCAL_30, LOCAL_22-D4W-1));
        };
        if (rect_42.b.x2 > rect_42.b.x1)
        {
          LOCAL_22 = (UI16)((LOCAL_22+7)&0xfff8);
          if ( (LOCAL_36!=0) || (w_142!=0) )
          {
            MemMove(A3, d.Pointer1848, LOCAL_22*LOCAL_24);
            A3 = d.Pointer1848;
          };
          if (LOCAL_36 != 0)
          {
            Mirror(A3, LOCAL_22, LOCAL_24);
          };
          if (w_142 != 0)
          {
            TAG008840(A3, LOCAL_22, LOCAL_24);
          };
          TAG0088b2(A3,
                    d.pViewportBMP,
                    &rect_42,
                    D4W,
                    0,
                    LOCAL_22,
                    112,
                    10);
        };
      };
    };
  };
tag006ab6:
  objD7 = GetDBRecordLink(objD7);
  if (objD7 != RNeof) goto tag0065e0;
  if ( (pdb_150!=NULL) && (LOCAL_110!=1) && (d.Word1868==0) )
  {
    RelativeCellNumber -= 3;
    MemMove(d.Byte4010 + 8*RelativeCellNumber, b_170, 8);
    b_170[0]++;
    TAG004f82(b_170, (RectPos *)(d.Byte3074 + 8*RelativeCellNumber));
  };
  return;
  // */
}

void TAG008840(pnt P1,i16 width, i16 height)
{
  dReg D6, D7;
  aReg A0, A1;
  i32 D7U, dA2;
  i8 temp24[24];
  i32 temp4;
//;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  D7W = height;
  D6W = width;
  A0 = P1;
  A1 = A0 + width * (height-1);
  dA2 = 2 * D6W;
  D6W /= 8;
  do
  {
    D7W-=2;
    if (D7W < 0) break;
    D7U = D6W;
    do
    {
      D7U -= 3;
      if (D7U < 0) break;
      memmove(temp24,A0,24);
      memmove(A0, A1, 24);
      memmove(A1, temp24 ,24);
      A1 += 24;
      A0 += 24;
    } while (D7U != 0);
    if (D7U < 0) // If we 'broke' out of loop.
    {
      D7U += 2;
      do
      {
        temp4 = longGear(A0);
        longGear(A0) = longGear(A1);
        longGear(A1) = temp4;
        A0 += 4;
        A1 += 4;
        temp4 = longGear(A0);
        longGear(A0) = longGear(A1);
        longGear(A1) = temp4;
        A0 += 4;
        A1 += 4;
      } while ((D7U--) != 0);
    };
    A1 -= dA2;
  } while (D7W != 0); // each line
}


//   TAG009308
i16  GetObjectIndex(RN object)
{
  //UNKNOWN *unkA3;
  i32 DBType;
  i32 result;
//;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  //unkA3 = GetRecordAddress(object);
  DBType = -1;
  if (object != RNempty) DBType = object.dbType();
  switch (DBType)
  {
  case dbSCROLL:
      result = 0;
      break;
  case dbCHEST:
      result = BITS1_2(GetRecordAddressDB9(object)->word4())+1;
      break;
  case dbMISC:
      result = BITS0_6(GetRecordAddressDB10(object)->word2) + 127;
      break;
  case dbWEAPON:
      result = GetRecordAddressDB5(object)->weaponType() + 23;
      break;
  case dbCLOTHING:
    //result is object index
      result = GetRecordAddressDB6(object)->clothingType() + 69;
      break;
  case dbPOTION:
      //result is object index.
      result = GetRecordAddressDB8(object)->potionType() + 2;
      break;
  default:
      result = -1;
  };
  return sw(result);
}

i16 TAG0093d4(RN P1)
{
  dReg D0, D5, D6;
  WEAPONDESC *weaponDescA3;
  RN objD7;
//;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  objD7 = P1;
  if (objD7.IsMagicSpell()) D6W = dbCLOUD;
  else  D6W = sw(objD7.dbType());
  if (D6W == dbCLOUD)
  {
    if (objD7 == RNFireball) return -11;
    if (objD7 == RNPoison) return -13;
    if (objD7 == RNLightning) return -4;
    if (objD7 == RNff86) return -14;
    if (objD7 == RNPoisonCloud) return -14;
    return -12;
  }
  else
  {
    if (D6W == dbWEAPON)
    {
      weaponDescA3 = TAG0099d2(objD7);
      D5W = BITS8_12(weaponDescA3->word4);
      if (D5W != 0)
      {
        return sw(-D5W);
      };
    };
  };
  D0W = GetObjectIndex(objD7);
  D0W = (UI8)(d.ObjDesc[D0W].byte2);
  return D0W;
}

//*********************************************************
//
//*********************************************************
WEAPONDESC *TAG0099d2(RN object)
{
  DB5 *pDB5_4;
//;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  ASSERT(object.dbType() == dbWEAPON);
  pDB5_4 = (DB5 *)GetCommonAddress(object);
  return &d.weapons[pDB5_4->weaponType()];
}