view Engine/OurMath.cpp @ 2541:a902abdfc7f2

1. Renamed class Game to class Engine. 2. Separated game logic as state of FSM from game logic as engine. 3. Found out that many UI screen initializers were optimized away, intially they all returned newly created window as separate object like it is done in CharacterUI_Initialize.
author a.parshin
date Sun, 10 May 2015 01:29:11 +0200
parents 1bcadc6dd203
children
line wrap: on
line source

#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>

#include "OurMath.h"
#include "MM7_data.h"

//----- (00452969) --------------------------------------------------------
stru193_math::stru193_math()
{
  double v3; // ST18_8@2

  this->pTanTable[0] = 0;
  this->pCosTable[0] = 65536;
  this->pInvCosTable[0] = 65536;
  for(int i = 1; i < (signed int)this->uIntegerHalfPi; i++)
  {
    v3 = (double)i * pi_double / (double)uIntegerPi;
    pTanTable[i] = (signed __int64)(tan(v3) * (double)this->pCosTable[0] + 0.5);
    pCosTable[i] = (signed __int64)(cos(v3) * (double)this->pCosTable[0] + 0.5);
    pInvCosTable[i] = (signed __int64)(1.0 / cos(v3) * (double)this->pCosTable[0] + 0.5);
  }
  for(int i = this->uIntegerHalfPi; i < 520; i++)
  {
    this->pTanTable[i] = 0xEFFFFFFFu;
    this->pCosTable[i] = 0;
    this->pInvCosTable[i] = 0xEFFFFFFFu;
  }
}


//----- (00402CAE) --------------------------------------------------------
int stru193_math::Cos(int angle)
{
  int v2; // eax@1

  //a2: (angle - uIntegerHalfPi)    for  sin(angle)
  //    (angle)                     for  cos(angle)

  v2 = uDoublePiMask & angle;

  if ( v2 > uIntegerPi )
    v2 = uIntegerDoublePi - v2;
  if ( v2 >= uIntegerHalfPi )
    return -pCosTable[uIntegerPi - v2];
  else
    return pCosTable[v2];
}


//----- (0045281E) --------------------------------------------------------
//    Calculates atan2(y/x)
// return value: angle in integer format (multiplier of Pi/1024)  
unsigned int stru193_math::Atan2(int x, int y)
{
  signed int quadrant;
  __int64 dividend;
  int quotient;
  int lowIdx;
  int highIdx;
  int angle;

  int X = x;
  int Y = y;

  if ( abs(X) < 65536 )
  {
    if ( (abs(Y) >> 15) >= abs(X) )
      X = 0;
  }

  if ( !X )
  {
    if ( Y > 0 )
    {
      return uIntegerHalfPi;   //Pi/2
    }
    else
    {
      return uIntegerHalfPi + uIntegerPi; //3*(Pi/2)
    }
  }

  if ( Y )
  {
    if ( X < 0 )
    {
      X = -X;
      if ( Y > 0 )
      {
        quadrant = 4;        
      }
      else
      {
        quadrant = 3;        
      }      
    }
    else
    {
      if ( Y > 0 )
      {
        quadrant = 1;       
      }
      else
      {
        quadrant = 2;
      }      
    }

    if ( Y < 0 )
      Y = -Y;

    LODWORD(dividend) = Y << 16;
    HIDWORD(dividend) = Y >> 16;
    quotient = dividend / X;        

    //looks like binary search
    {
      int i;
      highIdx = uIntegerHalfPi;
      lowIdx = 0;

      for (i = 0; i < 6; ++i)
      {        
        if (quotient <= pTanTable[(lowIdx + highIdx) / 2])      
          highIdx = (lowIdx + highIdx) / 2;
        else
          lowIdx = (lowIdx + highIdx) / 2;    
      }
    }

    angle = lowIdx + 1;
    while ( angle < (highIdx - 1) && quotient >= pTanTable[angle] )
      ++angle;

    switch (quadrant)
    {
    case 1: //X > 0, Y > 0
      return angle;        

    case 2: //X > 0, Y < 0
      return uIntegerDoublePi - angle;   //2*Pi - angle

    case 3: //X > 0, Y < 0
      return uIntegerPi + angle;        //Pi + angle 

    case 4: //X < 0, Y > 0
      return uIntegerPi - angle;        //Pi - angle  
    }

    //should newer get here
    return 0;
  }

  if ( X < 0 )    //Y == 0, X < 0
    return uIntegerPi;  

  return 0;
}

//----- (0042EBDB) --------------------------------------------------------
int stru193_math::Sin(int angle)
{
  return Cos(angle - this->uIntegerHalfPi);
}

//----- (0042EBBE) --------------------------------------------------------
//----- (004453C0) mm6-----------------------------------------------------
//----- (004A1760) mm6_chinese---------------------------------------------
__int64 fixpoint_mul(int a1, int a2)
{
  return ((__int64)a1 * (__int64)a2) >> 16;
}

__int64 fixpoint_dot(int x1, int x2, int y1, int y2, int z1, int z2)
{
  return fixpoint_mul(x1, x2) +
    fixpoint_mul(y1, y2) +
    fixpoint_mul(z1, z2);
}

//----- (004A1780) mm6_chinese---------------------------------------------
__int64 fixpoint_div(int a1, int a2)
{
  return ((__int64)a1 << 16) / a2;
}

__int64 fixpoint_sub_unknown(int a1, int a2)
{
  return (((__int64)a1 << 16) * a2) >> 16;
}

//----- (0048B561) --------------------------------------------------------
int fixpoint_from_float(float val)
{
  //  float X.Yf -> int XXXX YYYY
  int left = floorf((val - 0.5f) + 0.5f);
  int right = floorf((val - left) * 65536.0f);
  return (left << 16) | right;
}

int fixpoint_from_int(int lhv, int rhv)
{
  return (lhv << 16) | rhv;
}


//----- (00452A9E) --------------------------------------------------------
int integer_sqrt(int val)
{
///////////////////////////////
//Получение квадратного корня//
///////////////////////////////

  signed int result; // eax@2
  unsigned int v2; // edx@3
  unsigned int v3; // edi@3
  int v5; // esi@4

  if (val < 1)
    return val;

  v2 = 0;
  v3 = val;
  result = 0;
  for (uint i = 0; i < 16; ++i)
  {
    result *= 2;
    v2 = (v3 >> 30) | 4 * v2;
    v5 = 2 * result + 1;
    v3 *= 4;
    if ( v2 >= v5 )
    {
      ++result;
      v2 -= v5;
    }
  }
  if ( val - result * result >= (unsigned int)(result - 1) )
    ++result;
  return result;
}

//----- (00452B2E) --------------------------------------------------------
int __fastcall GetDiceResult(unsigned int uNumDice, unsigned int uDiceSides)
{
  int v3; // esi@1

  v3 = 0;
  if ( uDiceSides )
  {
    for ( uint i = 0; i < uNumDice; ++i)
      v3 += rand() % uDiceSides + 1;
    return v3;
  }
  return 0;
}