#include "sub.h"
#include "log.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
extern const  uint dword_2FED08[0xE];
// 0016A88C ^_^
//单元测试等级: 目测游戏表现
//单元测试内容: 1-5
//单元测试结果: 正常
//已测试分支 1
void sub_16A88C(fpointQ<PointType_18> &r0_pfpointQ,
                fpointQ<PointType_18> &r1_pfpointQ) {
    
  int r8_i = r1_pfpointQ.field_0;
  int r11_i = r1_pfpointQ.field_4;
  int r10_i = r1_pfpointQ.field_8;
  int r0_i = r1_pfpointQ.field_C;
  int i_sp8 = ((uint64)r8_i) * r8_i / 0x40000 +
              ((uint64)r11_i) * r11_i / 0x40000 +
              ((uint64)r10_i) * r10_i / 0x40000 + ((int64)r0_i) * r0_i / 0x40000;
  int r2_i = i_sp8 - 0x40000;
  if (i_sp8 < 0x40000) {
     // LOGE("sub_16A88C_1");
    r2_i = 0x40000 - i_sp8;
  }
  if (r2_i >= 0x80) {
    //  LOGE("sub_16A88C_2");
    // 0016A8DA
    int i_sp4;
    sub_16A818(&i_sp4, &i_sp8);
    // r0 r6 r7 sp0 =r1_pfpointQ
    r8_i = ((int64)r1_pfpointQ.field_0) * 0x40000 / i_sp4;
    r11_i = ((int64)r1_pfpointQ.field_4) * 0x40000 / i_sp4;
    r10_i = ((int64)r1_pfpointQ.field_8) * 0x40000 / i_sp4;
    r0_i = ((int64)r1_pfpointQ.field_C) * 0x40000 / i_sp4;
  }
  //LOGE("sub_16A88C_3");
  // loc_16A93E
  r0_pfpointQ.field_0 = r8_i;
  r0_pfpointQ.field_4 = r11_i;
  r0_pfpointQ.field_8 = r10_i;
  r0_pfpointQ.field_C = r0_i;
};
// 0016C3E2 ^_-
//单元测试等级: 目测游戏表现
//单元测试内容: 1-5
//单元测试结果: 正常
//已测试分支 1
void sub_16C3E2(fpointQ<PointType_18> &r0_pfpointQ,
                fpointQ<PointType_18> &r1_pfpointQ,
                fpointQ<PointType_18> &r2_pfpointQ) {
                   // LOGE("sub_16C3E2");
  int r12_i = r2_pfpointQ.field_0;
  int r4_i = r2_pfpointQ.field_4;
  int r8_i = r2_pfpointQ.field_8;
  int lr_i = r2_pfpointQ.field_C;

  int r6_i = r1_pfpointQ.field_0;
  int r9_i = r1_pfpointQ.field_4;
  int r5_i = r1_pfpointQ.field_8;
  int r1_i = r1_pfpointQ.field_C;

 r0_pfpointQ.field_0 = ((uint64)r12_i) * r1_i / 0x40000 + ((uint64)r6_i) * lr_i / 0x40000 +
             ((uint64)r5_i) * r4_i / 0x40000 - ((uint64)r8_i) * r9_i / 0x40000;
 r0_pfpointQ.field_4 = ((uint64)r9_i) * lr_i / 0x40000 + ((uint64)r4_i) * r1_i / 0x40000 -
             ((uint64)r5_i) * r12_i / 0x40000 + ((uint64)r8_i) * r6_i / 0x40000;

 r0_pfpointQ.field_8 = ((uint64)r9_i) * r12_i / 0x40000 - ((uint64)r4_i) * r6_i / 0x40000 +
             ((uint64)r5_i) * lr_i / 0x40000 + ((uint64)r8_i) * r1_i / 0x40000;

 r0_pfpointQ.field_C = ((uint64)r1_i) * lr_i / 0x40000 - ((uint64)r12_i) * r6_i / 0x40000 -
             ((uint64)r4_i) * r9_i / 0x40000 - ((uint64)r8_i) * r5_i / 0x40000;
};
// 0016C672 ^_-
//单元测试等级: 目测游戏表现
//单元测试内容: 1-5
//单元测试结果: 正常
//已测试分支 1
void sub_16C672(fpoint3<PointType_18> &r0_pfpoint3,
                fpoint3<PointType_18> &r1_pfpoint3,
                fpoint<PointType_18>* r2_pfpoint) {
  //LOGE("sub_16C672");
  r0_pfpoint3.x_0 = ((uint64)r1_pfpoint3.x_0) * r2_pfpoint->var_0 / 0x40000;
  r0_pfpoint3.y_4 = ((uint64)r1_pfpoint3.y_4) * r2_pfpoint->var_0 / 0x40000;
  r0_pfpoint3.z_8 = ((uint64)r1_pfpoint3.z_8) * r2_pfpoint->var_0 / 0x40000;
}

// 001699F4 ^_-
//单元测试等级: 目测游戏表现
//单元测试内容: 1-5
//单元测试结果: 正常
//已测试分支 未调用
void sub_1699F4(int *r0_pi, int *r1_pi) {
  long long r2r1_ll = *r1_pi;
  long long r12lr_ll = r2r1_ll * 0x4000;
  long long r4r2_ll = 0x4000000000000000;
  long long r3r1_ll;
  do {
    // loc_16A82E
    r3r1_ll = r4r2_ll;
    r4r2_ll >>= 2;
  } while (r12lr_ll < r4r2_ll);

  r4r2_ll = 0;
  while (r3r1_ll) {
    // loc_16A84C
    long long r6r5_ll = r3r1_ll + r4r2_ll;
    if (r12lr_ll < r6r5_ll) {  // 0016A85C
     // LOGE("sub_1699F4_branch1");
      r4r2_ll = r4r2_ll / 2;
    } else {  // loc_16A866
     // LOGE("sub_1699F4_branch2");
      r4r2_ll = r4r2_ll / 2;
      r4r2_ll += r3r1_ll;
      r12lr_ll -= r6r5_ll;
    }
    // loc_16A87A
    r3r1_ll >>= 2;
  }
  *r0_pi = r4r2_ll;
  // LOGE(" my=%x",*r0_pi);
  // LOGE("old");
  // f=(void (*) (int* x,int*y))address;
  // f(r0_pi,r1_pi);
  // LOGE("old end");
  // LOGE(" old=%x",*r0_pi);
}
// 00166CB2 ^_^
//单元测试等级: 目测游戏表现
//单元测试内容: 1-4
//单元测试结果: 正常
//已测试分支 函数未调用
void sub_166CB2(int *r0_pi, fpoint2<PointType_14> *r1_pfpoint) {
  //LOGE("sub_166CB2");
  int r2_i = r1_pfpoint->x_0;
  int r1_i = r1_pfpoint->y_4;
  unsigned long long r12r1_ull = ((unsigned long long)r1_i) * r1_i;
  unsigned long long r3r2_ull = ((unsigned long long)r2_i) * r2_i;
  r1_i = r12r1_ull / 0x4000;
  r2_i = r3r2_ull / 0x4000;
  r1_i += r2_i;
  sub_1699F4(r0_pi, &r1_i);
}
// 0016A818 ^_-
//已测试分支1 2 正常 1-6关
//单元测试等级: 目测游戏表现
//单元测试内容: 1-6
//单元测试结果: 正常
//已测试分支 1 2
void sub_16A818(int *r0_pi, int *r1_pi) {
  // LOGE("sub_16A818 address=%x",address);
  long long r2r1_ll = *r1_pi;
  long long r12lr_ll = r2r1_ll * 0x40000;
  long long r4r2_ll = 0x4000000000000000;
  long long r3r1_ll;
  do {
    // loc_16A82E
    r3r1_ll = r4r2_ll;
    r4r2_ll >>= 2;
  } while (r12lr_ll < r4r2_ll);

  r4r2_ll = 0;
  while (r3r1_ll) {
    // loc_16A84C
    long long r6r5_ll = r3r1_ll + r4r2_ll;
    if (r12lr_ll < r6r5_ll) {  // 0016A85C
     // LOGE("sub_16A818_branch1");
      r4r2_ll = r4r2_ll / 2;
    } else {  // loc_16A866
    //  LOGE("sub_16A818_branc");
      r4r2_ll = r4r2_ll / 2;
      r4r2_ll += r3r1_ll;
      r12lr_ll -= r6r5_ll;
    }
    // loc_16A87A
    r3r1_ll >>= 2;
  }
  *r0_pi = r4r2_ll;
 // LOGE("out=%x in=%x", *r0_pi, *r1_pi);
}



// 0016D8B2 ^_^
//已测试分支
//单元测试等级: 目测游戏表现
//单元测试内容: 前10关未调用
//单元测试结果:
//已测试分支
void sub_16D8B2(int *r0_pi, fpoint3<PointType_18> &r1_pfpoint3) {
//  LOGE("sub_16D8B2");
  int i_sp4 = ((long long)r1_pfpoint3.x_0) * r1_pfpoint3.x_0 / 0x40000 +
              ((long long)r1_pfpoint3.y_4) * r1_pfpoint3.y_4 / 0x40000 +
              ((long long)r1_pfpoint3.z_8) * r1_pfpoint3.z_8 / 0x40000;
  sub_16A818(r0_pi, &i_sp4);
}
// 0016C7DC ^_-
//已测试分支
//单元测试等级: 目测游戏表现
//单元测试内容: 前10关未调用
//单元测试结果:
//已测试分支
void sub_16C7DC(fpoint3<PointType_18> &r0_pfpoint3,fpoint3<PointType_18> &r1_pfpoint3,fpoint3<PointType_18> &r2_pfpoint3) {
  //LOGE("sub_16C7DC");
  int r12_i = r2_pfpoint3.x_0;
  int r3_i = r2_pfpoint3.y_4;
  int lr_i = r2_pfpoint3.z_8;
  int r2_i = r1_pfpoint3.x_0;
  int r4_i = r1_pfpoint3.y_4;
  int r1_i = r1_pfpoint3.z_8;
  r0_pfpoint3.x_0 = ((unsigned long long)r4_i) * lr_i / 0x40000 -
                    ((unsigned long long)r1_i) * r3_i / 0x40000;
  r0_pfpoint3.y_4 =
      ((unsigned long long)r1_i) * r12_i / 0x40000 -
      ((unsigned long long)r2_i) * lr_i / 0x40000;  //乘法smull 寄存器顺序不同
  r0_pfpoint3.z_8 = ((unsigned long long)r3_i) * r2_i / 0x40000 -
                    ((unsigned long long)r4_i) * r12_i / 0x40000;
}
// 0016C74C ^_^
//已测试分支
//单元测试等级: 目测游戏表现
//单元测试内容: 前10关未调用
//单元测试结果:
//已测试分支
void sub_16C74C(fpoint<PointType_18> &r0_pfpoint,fpoint3<PointType_18> &r1_pfpoint3,fpoint3<PointType_18> &r2_pfpoint3) {
//  LOGE("sub_16C74C");
  int r3_i = r1_pfpoint3.x_0;
  int r12_i = r1_pfpoint3.y_4;
  int lr_i = r1_pfpoint3.z_8;
  int r1_i = r2_pfpoint3.x_0;
  int r4_i = r2_pfpoint3.y_4;
  int r2_i = r2_pfpoint3.z_8;

  r0_pfpoint.var_0 = ((unsigned long long)r1_i * r3_i) / 0x40000 +
                     ((unsigned long long)r4_i * r12_i) / 0x40000 +
                     ((unsigned long long)r2_i * lr_i) / 0x40000;
}


// 0016A57C 
//已测试分支
//单元测试内容: 1-10
//单元测试结果:未调用
//已测试分支
void sub_16A57C(int&r0_pi,int&r1_pi){
  LOGE("sub_16A57C");
  uint64 ull_sp0;
  int r10_i=r1_pi;
  if(r1_pi<=-411776){
    //0016A592
    ull_sp0=0xffffffff00000000;
    r10_i+=823550;
  }else{//loc_16A5A2
    if(r1_pi<=411775){

     ull_sp0=0x100000000;
    }else{
 
      ull_sp0=0xffffffff00000000;
      r10_i-=823550;
    }
    //i_sp0=0;
  }
  //loc_16A5B6
  //loc_16A602
  int i_sp10;
  int i_spC;
  int r8_i=0x40000;
  uint64 r6r11_ull=0x40000;
  for(int r9_i=0xE;r9_i!=0;r9_i--){
    //loc_16A5CA
    i_sp10=r8_i+0x40000;
    sub_16A818(&i_sp10,&i_spC);
    r6r11_ull = (int)(r6r11_ull*i_sp10/0x40000);
    r8_i/=4;
  }
  //0016A60A
  int r3_i=0x40000;
  r8_i = 0x40000;
  //loc_16A686
  int lr_i=0x0;
  for(int r1_i=0;r1_i!=0xE;r1_i++){
    //loc_16A622
    int r5_i=((r10_i>>31) & 0xFFF80000) | 0x40000;
    int r0_i= ((int64)r8_i*r5_i)/0x40000;
    int r2_i=(((uint64)dword_2FED08[r1_i]*r5_i))/0x40000;
    r10_i-=r2_i;
    r0_i=(((uint64)r0_i*r3_i))/0x40000;
    r2_i=((int64)lr_i*r5_i)/0x40000;
    lr_i+=r0_i;
    r0_i=((int64)r2_i*r3_i)/0x40000;
    r8_i-=r0_i;
    r3_i/=2;
  }
  //0016A68A

  r0_pi=(int64)(ull_sp0*lr_i/0x4000)/((int64)r6r11_ull);
}

// 0016A6CC 
//已测试分支  
//单元测试内容: 1-10
//单元测试结果:未调用
//已测试分支
void sub_16A6CC(int&r0_pi,int&r1_pi){
  uint64 ull_sp0;
  int r10_i=r1_pi;
  if(r1_pi<=-411776){
    //0016A6E2
    //check
    LOGE("sub_16A6CC_0");
    ull_sp0=0xffffffff00000000;
    r10_i+=823550;
  }else{//loc_16A6F2
    if(r1_pi<=411775){
     LOGE("sub_16A6CC_1");
     ull_sp0=0x100000000;
    }else{
      LOGE("sub_16A6CC_2");
      ull_sp0=0xffffffff00000000;
      r10_i-=823550;
    }
    //i_sp0=0;
  }
  //loc_16A706
  //loc_16A752

  int i_sp10;
  int i_spC;
  int r8_i=0x40000;
  uint64 r6r11_ull=0x40000;
  for(int r9_i=0;r9_i!=0xE;r9_i++){
    //loc_16A71A
    LOGE("sub_16A6CC_3");
    i_sp10=r8_i+0x40000;
    sub_16A818(&i_sp10,&i_spC);
    r6r11_ull = (int)(r6r11_ull*i_sp10/0x40000);//这里的乘法确定是uint64
    r8_i/=4;
  }
  //0016A758
  int r2_i=0x40000;
  int r4_i = 0x40000;
  int lr_i=0x0;
  //loc_16A7D4
  for(int r1_i=0;r1_i!=0xE;r1_i++){
    //loc_16A774
    LOGE("sub_16A6CC_4");
    int r5_i=((r10_i>>31) & 0xFFF80000) | 0x40000;
    int r0_i= ((uint64)r2_i*r5_i)/0x40000;
    int r3_i=((uint64)dword_2FED08[r1_i]*r5_i)/0x40000;
    r10_i-=r3_i;
    r0_i=((uint64)r0_i*r4_i)/0x40000;
    r3_i=((uint64)lr_i*r5_i)/0x40000;
    lr_i+=r0_i;
    r0_i=((uint64)r3_i*r4_i)/0x40000;
    r2_i-=r0_i;
    r4_i/=2;
  }
  //0016A7D8
  r0_pi=(int64)(ull_sp0*r2_i/0x4000)/(int64)(r6r11_ull);
  int64 base=0;
  LOGE("r0_pi=%x",r0_pi);
  // if(GetModuleBase(base,getpid(),"libHero.so")){
  //   LOGE("geted base=%x",(uint)base);
  //   p=(void (*)(int&,int&))(base+0x16A6CC);
  // }
}