tongwei il y a 3 ans
Parent
commit
665d26cf5d
49 fichiers modifiés avec 7749 ajouts et 0 suppressions
  1. 272 0
      src/jni/TGame.h
  2. 28 0
      src/jni/TGfxCrowdState.h
  3. 9 0
      src/jni/TMetricsOptions.cpp
  4. 16 0
      src/jni/TMetricsOptions.h
  5. 30 0
      src/jni/TNMVert.cpp
  6. 22 0
      src/jni/TNMVert.h
  7. 16 0
      src/jni/TPhoto.cpp
  8. 64 0
      src/jni/TPhoto.h
  9. 64 0
      src/jni/TPitchLineCircle.cpp
  10. 41 0
      src/jni/TPitchLineCircle.h
  11. 5 0
      src/jni/TPitchLineGen.cpp
  12. 38 0
      src/jni/TPitchLineGen.h
  13. 52 0
      src/jni/TPitchLineRect.cpp
  14. 53 0
      src/jni/TPitchLineRect.h
  15. 72 0
      src/jni/TPlayerInfo.h
  16. 10 0
      src/jni/TPlayerInfoLight.cpp
  17. 31 0
      src/jni/TPlayerInfoLight.h
  18. 27 0
      src/jni/TShadowAABB.cpp
  19. 95 0
      src/jni/TShadowAABB.h
  20. 5 0
      src/jni/TStageOperation.cpp
  21. 50 0
      src/jni/TStageOperation.h
  22. 16 0
      src/jni/TStateList.h
  23. 193 0
      src/jni/TStoryConfig.h
  24. 12 0
      src/jni/TStorySeason.cpp
  25. 94 0
      src/jni/TStorySeason.h
  26. 157 0
      src/jni/TTDList.h
  27. 189 0
      src/jni/TTList.h
  28. 103 0
      src/jni/TTSPtr.h
  29. 77 0
      src/jni/TTVector.h
  30. 9 0
      src/jni/TUV.h
  31. 22 0
      src/jni/UNITROT.h
  32. 81 0
      src/jni/Util.cpp
  33. 38 0
      src/jni/Util.h
  34. 140 0
      src/jni/XCTRL.cpp
  35. 76 0
      src/jni/XCTRL.h
  36. 59 0
      src/jni/XDBG.cpp
  37. 39 0
      src/jni/XDBG.h
  38. 533 0
      src/jni/XMATH.cpp
  39. 471 0
      src/jni/XMATH.h
  40. 827 0
      src/jni/XMATH_var.h
  41. 105 0
      src/jni/XML.cpp
  42. 87 0
      src/jni/XML.h
  43. 163 0
      src/jni/XSYS.cpp
  44. 39 0
      src/jni/XSYS.h
  45. 5 0
      src/jni/X_sCommFile.h
  46. 758 0
      src/jni/xsnprintf.cpp
  47. 10 0
      src/jni/xsnprintf.h
  48. 534 0
      src/jni/zconf.h
  49. 1912 0
      src/jni/zlib.h

+ 272 - 0
src/jni/TGame.h

@@ -0,0 +1,272 @@
+// TGame - [2020-04-13 11:57:46]
+#ifndef _TGAME_H_
+#define _TGAME_H_
+
+//001D5934 TGame::operator=(TGame const&)
+
+#include "CPlayer.h"
+#include "CTeam.h"
+
+struct PlayerSubstitute {
+  CPlayer *pCPlayer_0;
+  int field_4;
+  CPlayer *pCPlayer_8;
+  CPlayer *pCPlayer_C;
+  CPlayer *pCPlayer_10;
+};
+
+struct TLogic {
+  int field_0;
+  uchar field_4;
+  uchar field_5;   //	.text:00176026                 STRB.W          R0, [R1,R12]
+  uchar field_6;
+  uchar field_7;
+  int field_8;
+  int field_C;
+  int field_10;
+  int field_14;
+  int field_18;
+  int field_1C;
+  int field_20;
+  int field_24;
+  int field_28;
+  int field_2C;
+  int field_30;
+  int field_34;
+  int field_38;
+  int player_3C;
+  int team_40;
+  int field_44;
+  int field_48;
+  int field_4C;
+  sint8 field_50;     //0016DF68 确定的类型
+  char field_51;
+  char field_52;      //0016DF7C 确定的类型
+  char field_53;
+  int field_54;
+  int field_58;
+  int field_5C;
+  int team_60;
+  TPoint field_64;  //0016E03A 确定的类型
+  int field_6C;     //0016E012确定的类型
+  char player_70;    
+  char field_71;  
+  char field_72;  
+  char field_73;  
+  char field_74;
+  char field_75;
+  char field_76;
+  char field_77;
+  int field_78;
+  char field_7C;
+  char field_7D;
+  char field_7E;
+  char field_7F;
+  char field_80;
+  char field_81;
+  char field_82;                    //0016DFD8确定的类型
+  char field_83;
+  char field_84;
+  char field_85;
+  char field_86;
+  char field_87;
+  char field_88;
+  char field_89;
+  char field_8A;
+  char field_8B;
+  char field_8C;
+  char field_8D;
+  char field_8E;
+  char field_8F;
+  char field_90;
+  char field_91;
+  char field_92;
+  char field_93;
+  char field_94;
+  char field_95;
+  char field_96;
+  char field_97;
+  char field_98;                   //0016DF08确定的类型
+  char field_99;
+  char field_9A;
+  char field_9B;                  //0016E060确定的类型
+  char field_9C;                  //0016E060确定的类型
+  char field_9D;
+  char field_9E;
+  char field_9F;
+  int field_A0;                 //001D5826确定的类型
+  char field_A4[2];
+  char field_A6;
+  char field_A7;     
+  char field_A8;
+  bool bisRunning_A9;
+  char field_AA;
+  char field_AB;
+  int field_AC;
+  int field_B0;
+  int field_B4;
+  int field_B8;
+};
+
+struct struc_250 {
+  int field_0;
+  int field_4;
+};
+
+/* 0x88 */
+struct list_11_0x88 {
+  struc_250 field_0[11];
+};
+
+/* 1548 */
+struct TMath {
+  short buf_0;
+  int filed_4[22];
+  int filed_5C[22];
+  int buf_B4[22];
+  int field_10C[2];
+  int field_114[2];
+  int field_11c[2];
+  int field_124[2];//某种指针, 不是int
+  int field_12C[2];
+  CPlayer *pPlayer_134[2];
+  int pPlayer_13C[2];
+  bool field_144;
+  int8 field_145[2];
+  int field_148;
+  int field_14C;
+  int field_150[2];
+  int field_158;
+  int field_15C;
+  int filed_160[22];
+  int filed_1B8[2];
+  int filed_1C0[2];
+  int field_1C8[2];
+  int field_1D0[11];
+  list_11_0x88 list_1FC[2];
+  int field_2AC[22];
+  char filed_304[2][11];
+  char filed_31A[2];
+  int filed_31C;
+  char filed_320[4];
+  int filed_324;
+  int filed_328;
+  int field_32C;
+  int field_330;
+  int field_334[2];
+  char field_33C[2];
+  char field_33E[2];
+  int field_340[11];
+  int distance_36C;
+  TPoint3D field_370;
+  TPoint3D field_37C;
+  int field_388[2];
+  int field_390;
+  int field_394;
+  int field_398;
+  int field_39C;
+  int field_3A0;
+};
+
+struct PlayTeam {
+  CPlayer *teamlist_0[11];
+};
+
+struct TOffside {
+  uchar field_0 ;
+  uchar field_1;
+  ushort  field_2;
+  uint32  field_4[2];		//text:0015BCD2                 LDR.W           R0, [R5,R10]		//.text:0015BE98                 STR.W           R1, [R2,R10]  这里判断是数组
+ // uint32   field_8;
+  uint32   field_C;
+  uint32   field_10;
+  PlayTeam allplay_14[2];			//.text:0015BB9E                 LDR             R0, [R0,#0x14]
+  list_11_0x88 list_6C[2];
+  int field_11C;
+  int field_120;
+  int field_124;
+  int field_128;
+  int field_12C;
+  struc_250 list_130[2];
+};
+
+// sizeof = unknown
+struct TGame_70
+{
+  CPlayer*   pCPlayer_0;
+  int   i_4;
+};
+
+struct TPlayerInfos_st{
+  TPlayerInfo TPlayerInfo_0[0x20];
+  TPlayerInfo TPlayerInfo_1080[0x20];
+};
+
+//0x6CD8
+struct TGame {
+  int maybe_sound_0;
+  int dCurrentID_4;
+  CPlayer *field_8[3];         //0015B358 确定类型
+  PlayTeam allplay_14[2];  //001749A0 确定11个人的CPlayer* 为一个结构
+  CPlayer* field_6C;
+  TGame_70 *p_70;  //001EC9F0 确定
+  CPlayer *field_74[8];
+  TPlayerInfos_st TPlayerInfo_94;
+  TPlayerInfo TPlayerInfo_2194;
+  TPlayerInfo TPlayerInfo_2218;
+  uchar buf_229C[2500];
+  CTeam CTeam_2C60[2];
+  CPlayer CPlayer_3050[33];
+  uchar byte_6674;
+  TLogic mTLogic_6678;
+  TMath mTMath_6734;
+  int field_6AD8;
+  CPlayer *field_6ADC;
+  TOffside mTOffside_6AE0;
+  int field_6C20;
+  int field_6C24;
+  int field_6C28;
+  int field_6C2C;
+  int field_6C30;
+  int field_6C34;
+  int field_6C38;
+  int field_6C3C;
+  int field_6C40[2];//大小不确定, 先用2个表示
+  int field_6C48;
+  int field_6C4C;
+  int field_6C50;
+  int field_6C54;
+  int field_6C58;
+  int field_6C5C;
+  int field_6C60;
+  int field_6C64;
+  int field_6C68;
+  int field_6C6C;
+  int field_6C70;
+  int field_6C74;
+  int field_6C78;
+  int field_6C7C;
+  int field_6C80;
+  int field_6C84;
+  int field_6C88;
+  int field_6C8C;
+  int field_6C90;
+  int field_6C94;
+  int field_6C98;
+  int field_6C9C;
+  int m_i_6CA0;
+  int m_i_6CA4;
+  int field_6CA8;
+  int m_i_6CAC;
+  TPoint3D m_TPoint3D_6CB0;
+  TPoint3D  m_TPoint3D_6CBC;
+  TPoint3D  m_TPoint3D_6CC8;
+  uchar m_uc_6CD4;
+  uchar field_6CD5; // 补齐
+  uchar field_6CD6; // 补齐
+  uchar field_6CD7; // 补齐
+};
+
+extern TGame tGame;
+
+#endif  //_TGAME_H_

+ 28 - 0
src/jni/TGfxCrowdState.h

@@ -0,0 +1,28 @@
+//TGfxCrowdState - [2022-03-11 07:52:23]
+#ifndef _TGFXCROWDSTATE_H_
+#define _TGFXCROWDSTATE_H_
+#include "common.h"
+#include "CGfxCrowd.h"
+
+
+class TGfxCrowdState {
+public:
+//  TGfxCrowdState(){} // 自定义构造函数
+  TGfxCrowdState(float, ECrowdMemberType, uchar, bool);      //0019CA8C
+  void Process();                                            //001A1144
+  void ProcessState();                                       //001A1308
+  void ProcessFrame();                                       //001A1494
+  void UpdateState();                                        //001A1528
+public:
+  float  m_fField_0;
+  float  m_fField_4;
+  int    m_iField_8;
+  ECrowdMemberType   m_field_C;
+  bool   m_b_10;
+  uchar  m_field_11;
+  //uint16  m_field_12;
+  int16  m_field_12;
+  static uchar uSpan[0x140];
+};
+
+#endif // _TGFXCROWDSTATE_H_

+ 9 - 0
src/jni/TMetricsOptions.cpp

@@ -0,0 +1,9 @@
+//
+// Created by 86185 on 2021/4/19.
+//
+
+#include "TMetricsOptions.h"
+
+void TMetricsOptions::Serialize(CFTTSerialize *val2) {
+  return val2->SerializeInternal<int>(&filed_0, -1);
+}

+ 16 - 0
src/jni/TMetricsOptions.h

@@ -0,0 +1,16 @@
+//
+//Created by 86185 on 2021/4/19.
+//
+
+#ifndef MY_APPLICATION_TMETRICSOPTIONS_H
+#define MY_APPLICATION_TMETRICSOPTIONS_H
+#include "CFTTSerialize.h"
+
+class TMetricsOptions {
+public:
+  void Serialize(CFTTSerialize *val2);  //001CF440
+
+  int filed_0;
+};
+
+#endif  //MY_APPLICATION_TMETRICSOPTIONS_H

+ 30 - 0
src/jni/TNMVert.cpp

@@ -0,0 +1,30 @@
+#include "TNMVert.h"
+
+/*
+.text:00166CE6   PUSH            {R4,LR}
+.text:00166CE8   LDRD.W          R3, R12, [R1]
+.text:00166CEC   LDRD.W          LR, R0, [R0]
+.text:00166CF0   LDRD.W          R4, R2, [R2]
+.text:00166CF4   SUB.W           R0, R0, R12
+.text:00166CF8   SUB.W           R2, R2, R12
+.text:00166CFC   SUBS            R4, R4, R3
+.text:00166CFE   SUB.W           R3, R3, LR
+.text:00166D02   SMULL.W         R0, R4, R4, R0
+.text:00166D06   SMULL.W         R2, R3, R2, R3
+.text:00166D0A   LSRS            R0, R0, #0xE
+.text:00166D0C   ORR.W           R0, R0, R4,LSL#18
+.text:00166D10   LSRS            R2, R2, #0xE
+.text:00166D12   ORR.W           R2, R2, R3,LSL#18
+.text:00166D16   ADD             R0, R2
+.text:00166D18   MOVS            R2, #0
+.text:00166D1A   CMP             R0, #0
+.text:00166D1C   IT gt
+.text:00166D1E   MOVgt           R2, #1
+.text:00166D20   STRB            R2, [R1,#8]
+.text:00166D22   POP             {R4,PC}
+*/
+//-------------------------------------------------------------------------------------------------------
+//00166CE6
+void TNMVert::ConvexTest(TNMVert const*, TNMVert*, TNMVert const*) {
+}
+//-------------------------------------------------------------------------------------------------------

+ 22 - 0
src/jni/TNMVert.h

@@ -0,0 +1,22 @@
+//CFTTJob - [2020-04-13 11:57:46]
+#ifndef _TNMVERT_H_
+#define _TNMVERT_H_
+
+#include "common.h"
+
+/*
+00166CE6 TNMVert::ConvexTest(TNMVert const*,TNMVert*,TNMVert const*)
+*/
+
+class TNMVert {
+public:
+  void ConvexTest(TNMVert const*, TNMVert*, TNMVert const*);
+  int field_0;
+  int field_4;
+  bool byte_8;
+  bool field_9;  //没有用,仅用于对齐
+  bool field_A;  //没有用,仅用于对齐
+  bool field_B;  //没有用,仅用于对齐
+};
+
+#endif  //_TNMVERT_H_

+ 16 - 0
src/jni/TPhoto.cpp

@@ -0,0 +1,16 @@
+//
+// Created by 86185 on 2021/6/5.
+//
+
+#include "TPhoto.h"
+
+TPhotoPost::TPhotoPost() {
+  Filter_0 = 0;
+  Red_4 = 1.0;
+  Green_8 = 1.0;
+  Blue_c = 1.0;
+  Brightness_10 = 0.5;
+  Contrast_14 = 0.5;
+  Saturation_18 = 0.5;
+  Vignette_1c = 0.0;
+}

+ 64 - 0
src/jni/TPhoto.h

@@ -0,0 +1,64 @@
+//
+// Created by 86185 on 2021/6/5.
+//
+
+#ifndef MY_APPLICATION_TPHOTO_H
+#define MY_APPLICATION_TPHOTO_H
+#include "global_func.h"
+
+class TPhotoPost {
+public:
+  TPhotoPost();
+
+public:
+  int Filter_0;
+  float Red_4;
+  float Green_8;
+  float Blue_c;
+  float Brightness_10;
+  float Contrast_14;
+  float Saturation_18;
+  float Vignette_1c;
+};
+
+class TPlayer {
+public:
+  int Type_0;
+  TPointF3D Pox_4;
+  int Rot_10;
+  int AnimID_14;
+  float AnimFrame_18;
+};
+
+// 0xFC
+class TPhoto {
+public:
+  int PlayerCount_0;
+  TPlayer Players_4[4];
+  TPointF3D Target_74;
+  float Distance_80;
+  int Rot_84;
+  int Tilt_88;
+  int Rot_8c;
+  int Tilt_90;
+  int TOD_94;
+  float ClothAmbient_98;
+  float ClothDiffuse_9c;
+  float ClothSpecular_a0;
+  float SkinAmbient_a4;
+  float SkinDiffuse_a8;
+  float SkinSpecular_ac;
+  float BallAmbient_b0;
+  float BallDiffuse_b4;
+  float BallSpecular_b8;
+  TPhotoPost PhotoPost_bc;
+  int BGIndex_dc;
+  uint BGColour_e0;
+  bool ShowBall_e4;
+  char filed_e5[3];  //占位, 没啥用
+  int BallType_e8;
+  TPointF3D BallPos_ec;
+  int SleeveLength_f8;
+};
+
+#endif  // MY_APPLICATION_TPHOTO_H

+ 64 - 0
src/jni/TPitchLineCircle.cpp

@@ -0,0 +1,64 @@
+#include "TPitchLineCircle.h"
+#include "memctrl.h"
+
+int TPitchLineCircle::s_eType;
+//-------------------------------------------------------------------------------------------------
+//001BE194 经过单元测试,功能正常
+//^_^---
+//001BE1BA开始的三条指令的顺序不同
+//001BE1DE开始的三条指令的顺序不同
+//寄存器不同
+int LineCircleIntersection(CFTTVector32 cfttvector32_r0_begin,
+                           CFTTVector32 cfttvector32_r3_begin,
+                           float f_arg_8,
+                           CFTTVector32 cfttvector32_arg_c_begin,
+                           float f_arg_18,
+                           float* p_f_arg_1c) {
+  return 0;
+}
+//-------------------------------------------------------------------------------------------------
+//001BE690
+ TPitchLineCircle::~TPitchLineCircle() {
+   delete this;
+ }
+//-------------------------------------------------------------------------------------------------
+//001BE184
+int TPitchLineCircle::GetType() {
+  return TPitchLineCircle::s_eType;
+}
+//-------------------------------------------------------------------------------------------------
+//001BD85C
+void TPitchLineCircle::Clamp(CFTTVector32 vec32) {
+}
+//-------------------------------------------------------------------------------------------------
+//001BE378
+bool TPitchLineCircle::Identical(TPitchLineGen*) {
+  return false;
+}
+//-------------------------------------------------------------------------------------------------
+//001BE490
+void TPitchLineCircle::Render() {
+}
+//-------------------------------------------------------------------------------------------------
+//001BDDE0
+void TPitchLineCircle::Transform(uchar) {
+}
+//-------------------------------------------------------------------------------------------------
+//001BD846 //^_^
+void TPitchLineCircle::Translate(CFTTVector32 vec32) {
+  CFTTVector32 vec32_14 = vec32;
+  vec32_4 -= vec32_14;
+}
+//-------------------------------------------------------------------------------------------------
+//001BDD48 //^_^
+bool TPitchLineCircle::Valid() {
+  return f_1C != 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001BE650
+TPitchLineGen* TPitchLineCircle::Clone() {
+  TPitchLineCircle* pCircle = new TPitchLineCircle;
+
+  return (TPitchLineGen*)pCircle;
+}
+//-------------------------------------------------------------------------------------------------

+ 41 - 0
src/jni/TPitchLineCircle.h

@@ -0,0 +1,41 @@
+//TPitchLineCircle.h
+#ifndef _TPitchLineCircle_H
+#define _TPitchLineCircle_H
+
+#include "TPitchLineGen.h"
+
+/*
+001BE690 TPitchLineCircle::~TPitchLineCircle()
+001BE184 TPitchLineCircle::GetType()
+001BD85C TPitchLineCircle::Clamp(CFTTVector32)
+001BE378 TPitchLineCircle::Identical(TPitchLineGen *)
+001BE490 TPitchLineCircle::Render()
+001BDDE0 TPitchLineCircle::Transform(uchar)
+001BD846 TPitchLineCircle::Translate(CFTTVector32)
+001BDD48 TPitchLineCircle::Valid()
+001BE650 TPitchLineCircle::Clone()
+*/
+
+class TPitchLineCircle : public TPitchLineGen {
+public:
+  virtual ~TPitchLineCircle();             // 001BE690
+  virtual int GetType();                   // 001BE184
+  virtual void Clamp(CFTTVector32);        // 001BD85C
+  virtual bool Identical(TPitchLineGen*);  // 001BE378
+  virtual void Render();                   // 001BE490
+  virtual void Transform(uchar);           // 001BDDE0
+  virtual void Translate(CFTTVector32);    // 001BD846
+  virtual bool Valid();                    // 001BDD48
+  virtual TPitchLineGen* Clone();          // 001BE650
+
+  //vptr
+  CFTTVector32 vec32_4;
+  float field_10;
+  float field_14;
+  float field_18;
+  float f_1C;
+
+  static int s_eType;
+};
+
+#endif  //_TPitchLineCircle_H

+ 5 - 0
src/jni/TPitchLineGen.cpp

@@ -0,0 +1,5 @@
+#include "TPitchLineGen.h"
+
+TPitchLineGen::~TPitchLineGen() {
+    //empty
+}

+ 38 - 0
src/jni/TPitchLineGen.h

@@ -0,0 +1,38 @@
+//TPitchLineGen.h
+#ifndef _TPITCHLINEGEN_H_
+#define _TPITCHLINEGEN_H_
+
+#include "CFTTVector32.h"
+
+/*
+003237C8
+vptr_TPitchLineRect_3237C8:
+    TPitchLineGen::~TPitchLineGen()
+    TPitchLineRect::~TPitchLineRect()
+    TPitchLineRect::GetType(void)
+    TPitchLineRect::Clamp(CFTTVector32)
+    TPitchLineRect::Identical(TPitchLineGen *)
+    TPitchLineRect::Render(void)
+    TPitchLineRect::Transform(uchar)
+    TPitchLineRect::Translate(CFTTVector32)
+    TPitchLineRect::Valid(void)
+    TPitchLineRect::Clone(void)
+
+void (*)(TPitchLineGen* this)
+
+*/
+
+class TPitchLineGen {
+public:
+  virtual ~TPitchLineGen();
+  virtual int GetType() = 0;
+  virtual void Clamp(CFTTVector32) = 0;
+  virtual bool Identical(TPitchLineGen*) = 0;
+  virtual void Render() = 0;
+  virtual void Transform(uchar) = 0;
+  virtual void Translate(CFTTVector32) = 0;
+  virtual bool Valid() = 0;
+  virtual TPitchLineGen* Clone() = 0;
+};
+
+#endif  //_TPITCHLINEGEN_H_

+ 52 - 0
src/jni/TPitchLineRect.cpp

@@ -0,0 +1,52 @@
+#include "TPitchLineRect.h"
+#include "Matrix.h"
+#include "memctrl.h"
+
+int TPitchLineRect::s_eType = 1;  //00342D6C 某个枚举
+
+//-------------------------------------------------------------------------------------------------
+//001BE68C
+// TPitchLineRect::~TPitchLineRect() {
+//   //delete this;
+// }
+//-------------------------------------------------------------------------------------------------
+//001BDF28 //^_^
+int TPitchLineRect::GetType() {
+  return TPitchLineRect::s_eType;
+}
+//-------------------------------------------------------------------------------------------------
+//001BD74A //^_^
+void TPitchLineRect::Clamp(CFTTVector32 arg_vec32) {
+}
+//-------------------------------------------------------------------------------------------------
+//001BDF7C
+bool TPitchLineRect::Identical(TPitchLineGen* p_tpitchlinegen_r1) {
+  return false;
+}
+//-------------------------------------------------------------------------------------------------
+//001BE050
+void TPitchLineRect::Render() {
+}
+//-------------------------------------------------------------------------------------------------
+//001BDD5C  //^_^
+void TPitchLineRect::Transform(uchar uc_r1) {
+  // CFTTMatrix32 cfttmatrix32_v_90;
+
+}
+//-------------------------------------------------------------------------------------------------
+//001BD72C //^_^
+void TPitchLineRect::Translate(CFTTVector32 vec32_1) {
+
+}
+//-------------------------------------------------------------------------------------------------
+//001BD7FC //^_^
+bool TPitchLineRect::Valid() {
+  return true;
+}
+//-------------------------------------------------------------------------------------------------
+//001BE14C //^_^
+TPitchLineGen* TPitchLineRect::Clone() {
+  TPitchLineRect* pret = new TPitchLineRect;
+  return (TPitchLineGen*)pret;
+}
+//-------------------------------------------------------------------------------------------------

+ 53 - 0
src/jni/TPitchLineRect.h

@@ -0,0 +1,53 @@
+//TPitchLineGen.h
+#ifndef _TPITCHLINERECT_H_
+#define _TPITCHLINERECT_H_
+
+#include "TPitchLineGen.h"
+#include "CFTTVector32.h"
+
+/*
+001BE68C TPitchLineRect::~TPitchLineRect()
+001BDF28 TPitchLineRect::GetType()
+001BD74A TPitchLineRect::Clamp(CFTTVector32)
+001BDF7C TPitchLineRect::Identical(TPitchLineGen *)
+001BE050 TPitchLineRect::Render()
+001BDD5C TPitchLineRect::Transform(uchar)
+001BD72C TPitchLineRect::Translate(CFTTVector32)
+001BD7FC TPitchLineRect::Valid()
+001BE14C TPitchLineRect::Clone()
+
+003237C8
+vptr_TPitchLineRect_3237C8:
+    TPitchLineGen::~TPitchLineGen()
+    TPitchLineRect::~TPitchLineRect()
+    TPitchLineRect::GetType(void)
+    TPitchLineRect::Clamp(CFTTVector32)
+    TPitchLineRect::Identical(TPitchLineGen *)
+    TPitchLineRect::Render(void)
+    TPitchLineRect::Transform(uchar)
+    TPitchLineRect::Translate(CFTTVector32)
+    TPitchLineRect::Valid(void)
+    TPitchLineRect::Clone(void)
+
+0x34
+*/
+
+class TPitchLineRect : public TPitchLineGen {
+public:
+  //virtual ~TPitchLineRect();               //001BE68C
+  virtual int GetType();                   //001BDF28
+  virtual void Clamp(CFTTVector32);        //001BD74A
+  virtual bool Identical(TPitchLineGen*);  //001BDF7C
+  virtual void Render();                   //001BE050
+  virtual void Transform(uchar);           //001BDD5C
+  virtual void Translate(CFTTVector32);    //001BD72C
+  virtual bool Valid();                    //001BD7FC
+  virtual TPitchLineGen* Clone();          //001BE14C
+
+  //vptr
+  CFTTVector32 list_vec32_4[4];
+
+  static int s_eType;  //00342D6C 某个枚举
+};
+
+#endif  //_TPITCHLINERECT_H_

+ 72 - 0
src/jni/TPlayerInfo.h

@@ -0,0 +1,72 @@
+#ifndef _TPLAYERINFO_H_
+#define _TPLAYERINFO_H_
+
+#include "common_type.h"
+
+//0x84 结构不确定,先定义出来,编译通过
+#pragma pack(1)
+struct TPlayerInfo {
+  sint16 s_0;
+  wchar_t name_2[0x11];
+
+  wchar_t field_24[0x12];
+  uint8 field_48;
+  uint8 field_49;
+  uint8 field_4A;
+  uint8 field_4B;
+
+  uint8 field_4C;
+  uint8 field_4D;
+  uint8 field_4E;
+  uint8 field_4F;
+
+  uint8 field_50;
+  uint8 field_51;
+  uint8 field_52;
+  uint8 field_53;
+
+  int field_54;
+  int field_58;
+  uint8 field_5C;
+  uint8 field_5D;
+  uint8 field_5E;
+  uint8 shirtNum_5F;
+
+  uint8 field_60;
+  uint8 field_61;
+  uint8 field_62;
+  uint8 field_63;
+
+  uint8 field_64;
+  uint8 field_65;
+  uint8 field_66;
+  uint8 field_67;
+  uint8 field_68;
+  uint8 field_69;
+  uint8 field_6A;
+  uint8 field_6B;
+  uint8 field_6C;
+  uint8 field_6D;
+  uint8 field_6E;
+  uint8 field_6F;
+  uint8 field_70;
+  uint8 field_71;
+  uint8 field_72;
+  uint8 field_73;
+
+  int field_74;
+  int field_78;
+
+  uint8 field_7C;
+  uint8 field_7D;
+  uint8 field_7E;
+  uint8 field_7F;
+
+  uint8 field_80;
+  uint8 field_81;
+  sint8 field_82;
+  uint8 field_83;
+};
+#pragma pack()
+
+#endif  //_TPLAYERINFO_H_

+ 10 - 0
src/jni/TPlayerInfoLight.cpp

@@ -0,0 +1,10 @@
+//
+// Created by 86185 on 2021/6/1.
+//
+
+#include "TPlayerInfoLight.h"
+#include "memctrl.h"
+
+//0011AA80
+void TPlayerInfoLight::Serialize(CFTTSerialize &pCFTTSerializer1, int dr2) {
+}

+ 31 - 0
src/jni/TPlayerInfoLight.h

@@ -0,0 +1,31 @@
+//
+//Created by 86185 on 2021/6/1.
+//
+
+#ifndef _TPLAYERINFOLIGHT_H_
+#define _TPLAYERINFOLIGHT_H_
+
+#include "CFTTSerialize.h"
+
+class TPlayerInfoLight {
+public:
+  void Serialize(CFTTSerialize &pCFTTSerializer1, int dr2);
+  ushort field_0;
+  uchar field_2;
+  uchar country_3;
+  uchar field_4;
+  uchar field_5;
+  uchar field_6;
+  uchar field_7;
+  uchar field_8;
+  uchar field_9;
+  uchar field_a;
+  uchar field_b;
+  signed char field_c;
+  uchar field_d;
+  uchar field_e;
+  uchar shirtNum_f;
+  uchar field_10;
+};
+
+#endif  //_TPLAYERINFOLIGHT_H_

+ 27 - 0
src/jni/TShadowAABB.cpp

@@ -0,0 +1,27 @@
+#include "TShadowAABB.h"
+
+//-------------------------------------------------------------------------------------------------
+//001C5B48 //^_^
+TShadowAABB::TShadowAABB() {
+  //001C5B76
+}
+//-------------------------------------------------------------------------------------------------
+//001C5B8C
+//001C63CC //^_- 经过单元测试,功能正常
+TShadowAABB* TShadowAABB::MergeCasters(TShadowAABB& taabb0, TShadowAABB& taabb1, TShadowAABB& taabb2) {
+  LOGI("libMyHero.so call TShadowAABB::MergeCasters Entry==");
+  return 0;  // &taabb1;
+}
+//-------------------------------------------------------------------------------------------------
+//001C5C0A //^_-经过单元测试,功能正常
+TShadowAABB* TShadowAABB::Block(TShadowAABB& taabb0, TShadowAABB& taabb1, uint32 u2, uint32 u3) {
+  LOGI("libMyHero.so call TShadowAABB::Block Entry==");
+  return 0;
+}
+//-------------------------------------------------------------------------------------------------
+//001C5B8C //^_- 经过单元测试,功能正常
+int32 TShadowAABB::Overlap(const TAABB& taabb0, const TAABB& taabb1) {
+  LOGI("libMyHero.so call TShadowAABB::Overlap Entry==");
+  return 0;
+}
+//-------------------------------------------------------------------------------------------------

+ 95 - 0
src/jni/TShadowAABB.h

@@ -0,0 +1,95 @@
+//
+// Created by mac on 2022/1/6.
+//
+
+#ifndef MY_APPLICATION_TSHADOWAABB_H
+#define MY_APPLICATION_TSHADOWAABB_H
+#include <jni.h>
+#include <string>
+#include <cstdint>
+#include "common.h"
+#include "TAABB.h"
+
+//struct TPointInt8 {
+//    int8 field_0;
+//    int8 field_1;
+//
+//    TPointInt8& operator=(const TPointInt8& other) {
+//        this->field_0 = other.field_0;
+//        this->field_1 = other.field_1;
+//        return *this;
+//    };
+//};
+
+//001C5B48
+//#pragma pack(1)
+class TShadowAABB
+{
+public:
+    float   field_00;
+    float   field_04;
+    float   field_08;
+    float   field_0C;
+    float   field_10;
+    float   field_14;
+    float   field_18;
+    float   field_1C;
+    float   field_20;
+    float   field_24;
+    float   field_28;
+    float   field_2C;
+    uint32 field_30;
+    uint32 field_34;
+    uint32 field_38;
+    uint32 field_3C;
+    uint32 field_40;
+    uint32 field_44;
+    uint32 field_48;
+    uint32 field_4C;
+    uint32 field_50;
+    uint32 field_54;
+    uint32 field_58;
+    uint32 field_5C;
+    uint32 field_60;
+    uint32 field_64;
+    uint32 field_68;
+    uint32 field_6C;
+    uint32 field_70;
+    uint32 field_74;
+    uint32 field_78;
+    uint32 field_7C;
+    uint32 field_80;
+    uint32 field_84;
+    uint32 field_88;
+    uint32 field_8C;
+    uint32 field_90;
+    uint32 field_94;
+    uint32 field_98;
+    uint32 field_9C;
+    uint8  field_A0[32];
+    uint32 field_C0;
+    uint16 field_C4[32];
+    uint32 field_104;
+    uint8 field_108;
+    uint8 field_109;
+    uint8 field_10A;
+    uint8 field_10B;
+    uint8 field_10C;
+    uint8 field_10D;
+    uint8 field_10E;
+    uint8 field_10F;
+    uint32 field_110;
+    uint32 field_114;
+    uint32 field_118;
+    uint32 field_11C;
+    float field_120;
+    TShadowAABB();
+    static void MergeCasters(TShadowAABB& taabb0,TShadowAABB& taabb1,TShadowAABB& taabb2);
+    static void Block(TShadowAABB& taabb0,TShadowAABB&taabb1,uint32 u2,uint32 u3);
+    static int32_t Overlap(const TAABB &taabb0, const TAABB &taabb1);
+};
+//__attribute__ ((packed));
+//#pragma pack()
+
+
+#endif //MY_APPLICATION_TSHADOWAABB_H

+ 5 - 0
src/jni/TStageOperation.cpp

@@ -0,0 +1,5 @@
+#include "TStageOperation.h"
+
+//001EA458
+void TStageOperation::Serialize(CFTTSerialize& val1, int val2, int val3) {
+}

+ 50 - 0
src/jni/TStageOperation.h

@@ -0,0 +1,50 @@
+//TStageOperation - [2020-04-13 11:57:46]
+#ifndef _TSTAGEOPERATION_H_
+#define _TSTAGEOPERATION_H_
+
+#include "CFTTSerialize.h"
+#include "CDataBase.h"
+
+//001EA458 TStageOperation::Serialize(CFTTSerialize &,int,int)
+//0xA8 结构大小不确定,目前发现最大值是0xA8
+
+enum EStageOperation {
+  EStageOperation_0,
+  EStageOperation_1,
+  EStageOperation_2,
+  EStageOperation_3,
+  EStageOperation_4,
+  EStageOperation_5,
+  EStageOperation_6,
+  EStageOperation_7
+};
+
+enum ECharModelType {
+  ECharModelType_0,
+  ECharModelType_1,
+  ECharModelType_2,
+  ECharModelType_3,
+  ECharModelType_4,
+  ECharModelType_5,
+};
+
+class TStageOperation {
+public:
+  void Serialize(CFTTSerialize& val1, int val2, int val3);
+
+  EStageOperation v_0;
+  int v_4;
+  int v_8;
+  ELeague v_c;
+  int v_10;
+  int v_14;
+  char v_18[128];
+  int v_98;
+  int v_9c;
+  int v_A0;
+  ECharModelType v_A4;
+  int v_A8;
+  int v_AC;
+};
+
+#endif  //_TSTAGEOPERATION_H_

+ 16 - 0
src/jni/TStateList.h

@@ -0,0 +1,16 @@
+#ifndef _TSTATELIST_H_
+#define _TSTATELIST_H_
+
+//0x14
+struct TStateList{
+	ushort filed_0;
+	short filed_2;
+	int filed_4;
+	int16_t* filed_8;
+	short filed_c;
+	short filed_e;
+	short filed_10;
+	short filed_12;
+};
+
+#endif

+ 193 - 0
src/jni/TStoryConfig.h

@@ -0,0 +1,193 @@
+//
+//Created by 86185 on 2021/5/8.
+//
+
+#ifndef _TSTORYCONFIG_H_
+#define _TSTORYCONFIG_H_
+#include "global_func.h"
+
+struct TGoldenBootPack {
+  int num;
+  int Cost;
+};
+
+struct TPromoText {
+  int id;
+  char text[0x100];
+};
+
+struct TTrig {
+  int Type;
+  int Param;
+};
+
+//0x3A0
+struct TPromo {
+  bool Enabled_b50;
+  int ID_b54;
+  long DateStart_b58;
+  long EDateEnd_b5c;
+  int Depend_b64;
+  int Users_b64;
+  char IapID_b68[0x20];
+  int ProductIndex_b88;
+  int Start_b8c;
+  int StageIncrement_b90;
+  int MinsIncrement_b94;
+  int End_b98;
+  bool InSideStory_b9c;
+  int PerDay_ba0;
+  int Bux_ba4;
+  int MaxBux_ba8;
+  char Energy_bac;
+  int PurchaseMax_bb0;
+  char Shop_bb4;
+  char Boot_bb5;
+  int Savings_BB8;
+  struct TPromoText TitleText_BBc;
+  struct TPromoText DescText_CC0;
+  struct TPromoText PackText_DC4;
+  int DisplayTime_ec8;
+  int BlockTime_ecc;
+  struct TTrig TrigList_ed0[4];
+};
+
+//0xC
+struct TEEListRecord {
+  int ID;
+  float name;
+  int Credits;
+};
+
+//0x38
+struct TAdvertisingUserType {
+  int VideoInitialFE_63BC;
+  int VideoInitialInGame_63c0;
+  int VideoRepeatFE_63c4;
+  int VideoRepeatInGame_63c8;
+  int FullScreenInitial_63cc;
+  int FullScreenRepeat_63D0;
+  char LevelSelectVideos_63D4;
+  int IntroduceVideoEnergy_63D8;
+  int IntroduceVideoShop_63DC;
+  int IntroduceVideoPostStage_63e0;
+  int IntroduceVideoInGame_63e4;
+  int IntroduceFullPage_63e8;
+  int IntroduceBanner_63ec;
+  bool LevelsRefresh_63f0;
+};
+
+//69b4
+struct TStoryConfig {
+  bool v1_0;
+  int Version_4;
+  int ConfigFileRefreshTime_8;
+  int ConfigFileRefreshTime_c;
+  int SessionSignInLength_10;
+  int ReplayCamera_14;
+  char CameraName_18[32][32];
+  struct TPoint3D CameraPos_418[32];
+  char DisableSPC_598;
+  int FirstPurchasePercent_59C;
+  int Start_5a0;
+  int VideoClipCurrency_5a4;
+  int VideoClipEnergy_5a8;
+  int filed_5ac;
+  int filed_5b0;
+  int filed_5b4;
+  bool filed_5b8;
+  int SocialLogin_5bc;
+  int SocialLink_5c0;
+  int SocialPost_5c4;
+  int RewindCosts_5c8[10];
+  int UnlockMultiple_5F0;
+  int SeasonUnlockMaxClamp_5F4;
+  int SeasonUnlockMinClamp_5F8;
+  int CareerReset_5fc;
+  int EnergyRestoreAmount_600;
+  int EnergyRestoreTime_604;
+  int EnergyFailCost_608;
+  int EnergyRestoreCredits_60c;
+  int FreeRewind_610;
+  int GoldenBootsPackCount_614;
+  struct TGoldenBootPack *GoldenBootPackList_618;
+  char IapID_61c[5][256];
+  int Amount_B1C[5];
+  int BestValue_b30;
+  int MostPopular_b34;
+  char Amountstart_b38[5];
+  char filed_b3d[3];
+  int ToLow_b40;
+  int ToHigh_b44;
+  int ToFreeLTS_ToFreeLTNS_b48;
+  bool isToFreeLTS_b4c;
+  struct TPromo PromoNodeList_b50[20];
+  char UnlimitedIapID_53D0[256];
+  int Unlimited_54D0;
+  int PlayerCustomisationNumber_54D4[64];
+  int PlayerCustomisationHairStyle_55D4[64];
+  int PlayerCustomisationHairColour_56D4[64];
+  int PlayerCustomisationFacialHair_57D4[64];
+  int PlayerCustomisationBoots_58D4[64];
+  int PlayerCustomisationNumberCount_59D4;
+  int PlayerCustomisationHairStyleCount_59D8;
+  int PlayerCustomisationHairColourCount_59DC;
+  int PlayerCustomisationFacialHairCount_59E0;
+  int PlayerCustomisationBootsCount_59e4;
+  int PlayerCustomisationShirtNumbers_59E8[64];
+  int InitRangeStart_5AE8;
+  int InitRangeEnd_5AEC;
+  int ShirtOrderPos_5AF0[40];
+  bool ShowEventsBeforeActiveStage_5b90;
+  char StartupMessageText_5b91[2047];
+  int filed_6390;
+  int StartupMessageID_6394;
+  int filed_6398;
+  int DownloadListStages_639c;
+  int DownloadListAdBoards_63A0;
+  int DownloadListAdText_63A4;
+  int filed_63a8;
+  int filed_63ac;
+  int filed_63b0;
+  int filed_63b4;
+  int filed_63b8;
+  struct TAdvertisingUserType AdvertisingUserTypeList_63BC[7];
+  float RadiusScale_6544;
+  char Reveal_6548;
+  char filed_6549;
+  char filed_654a;
+  char filed_654b;
+  int filed_654c;
+  int filed_6550;
+  bool FBLogin_6554;
+  char FBScores_6555;
+  char FBLink_6556[128];
+  bool TWFollow_65D6;
+  char FBAPI_65D7[8];
+  int CrossPromotionText_65e0;
+  char CrossPromotionImage_65E4[128];
+  char CrossPromotionLink_6664[128];
+  int CrossPromotionShow_66e4;
+  int CrossPromotionStage_66e8;
+  int CrossPromotionUsers_66ec;
+  int CrossPromotionStart_66f0;
+  int CrossPromotionEnd_66f4;
+  char CrossPromotionPackageName_66F8[128];
+  bool IsSeasonUnlocked_6778;
+  bool Update_6779;
+  char filed_677a;
+  char filed_677b;
+  struct TEEListRecord EEListRecordc_677c[3];
+  char CCustomTextInfo_67a0;
+  char IAPValidate_67a1;
+  int EDTest_67a4;
+  int Housekeeping_67a8;
+  char DiamondMedal_67ac;
+  char ObsidianMedal_67ad;
+  char GoogleCloud_67ae;
+  char GfxOptHelp_67AF[512];
+  int TOSID_69b0;
+};
+
+extern TStoryConfig STY_tConfig;
+#endif  //_TSTORYCONFIG_H_

+ 12 - 0
src/jni/TStorySeason.cpp

@@ -0,0 +1,12 @@
+//
+// Created by 86185 on 2021/6/1.
+//
+
+#include "TStorySeason.h"
+//0x001EF63C ^_^
+TStorySeason::TStorySeason()
+{
+
+
+
+}

+ 94 - 0
src/jni/TStorySeason.h

@@ -0,0 +1,94 @@
+//
+//Created by 86185 on 2021/6/1.
+//
+
+#ifndef MY_APPLICATION_TSTORYSEASON_H
+#define MY_APPLICATION_TSTORYSEASON_H
+#include "global_func.h"
+#include "TPhoto.h"
+
+class TVideoAd {
+public:
+  int LinkedStage_0;
+  TPoint Map_4;
+  float Rot_c;
+};
+
+class TStage {
+public:
+  int ID_0;
+  int Version_4;
+  TPoint MapPos_8;
+  float LineCurve_10;
+  int TournamentType_14;
+  int Venue_18;
+  int Extra_1C;
+  char UnlockDate_20[0x10];
+  int UnlockSeconds_30;
+};
+
+class Sticker {
+public:
+  int LinkedStage_0;
+  int PhotoStage_4;
+  int RewardCredits_8;
+  char CaptionText_c[0x40];
+  TPoint MapPos_4c;
+  float Scale_54;
+  float Rot_58;
+  TPhoto Photo_5c;
+};
+
+class TStorySeason {
+public:
+  TStorySeason();
+
+public:
+  int SeasonID_0;
+  int Stars_4;
+  char Text_8[64];
+  char EndText_48[64];
+  char CompleteText_88[64];
+  int GrassCol_c8;
+  int GrassStyle_cc;
+  int StageCount_d0;
+  TStage TStage_d4[32];
+  int Sticker_Count_754;
+  Sticker field_758[5];
+  int field_e10;
+  TVideoAd field_e14[5];
+  bool SeasonEnabled_e64;
+  char field_e65;
+  char field_e66;
+  char field_e67;
+  int ActiveFromStage_e68;
+  uint BtnCol_e6c;
+  int EntryCost_e70;
+  bool National_e74;
+  char field_e75;
+  char field_e76;
+  char field_e77;
+  int SecondsVisibleBefore_e78;
+  char DateStart_e7c[0x10];
+  int DateStartSeconds_e8c;
+  char DateEnd_e90[0x10];
+  int DateEndSeconds_ea0;
+  char ActiveDateEnd_ea4[0x10];
+  int ActiveDateEndSeconds_eb4;
+  char Name_ea8[0x20];
+  char Type_ed8[0x20];
+  char UnlockText_ef8[0x20];
+  char OpeningNIS_f18[0x80];
+  int Comm_f98;
+  char Trophy_f9c[0x40];
+  int Diamond_fdc[5];
+  bool AlternateMusic_ff0;
+  char field_ff1;
+  char field_ff2;
+  char field_ff3;
+  int NumOppoLeagues_ff4;
+  int Leagues_ff8[5];
+};
+
+///0x870
+#endif  //MY_APPLICATION_TSTORYSEASON_H

+ 157 - 0
src/jni/TTDList.h

@@ -0,0 +1,157 @@
+//TTDList - [2020-04-13 11:57:47]
+#ifndef _TTDLIST_H_
+#define _TTDLIST_H_
+
+#include "common.h"
+
+/*
+00168B34 TTDList<TTSPtr<TNMVert>>::~TTDList()
+001677DE TTDList<TTSPtr<TNMVert>>::Insert(TTSPtr<TNMVert>,TTSPtr<TNMVert>)
+00167876 TTDList<TTSPtr<TNMVert>>::Insert(TTSPtr<TNMVert>)
+00167B14 TTDList<TTSPtr<TNMVert>>::Remove(TTSPtr<TNMVert>)
+
+            A                    B                      C                     D
+      +---+---+---+         +---+---+---+         +---+---+---+         +---+---+---+
+      | A |   | B |<------> | A |   | C |<------> | B |   | D |<------> | C |   | A | <-- pLast_0
+      +---+---+---+         +---+---+---+         +---+---+---+         +---+---+-+-+
+    (Prev)  ^  (Next)                                                             |
+            |                                                                     |
+            +<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+
+*/
+
+//环形双向链表,首尾相连
+template <typename T>
+class TTDList {
+public:
+  struct TTDListNode {
+    T m;
+    TTDListNode *next;
+    TTDListNode *prev;
+    TTDListNode() {
+      next = nullptr;
+      prev = nullptr;
+    };
+  };
+  //-------------------------------------------------------------------------------------------------
+  TTDList() {
+    pLast_0 = nullptr;
+    dCount_4 = 0;
+  };
+  //-------------------------------------------------------------------------------------------------
+  //00168B34
+  ~TTDList() {
+    int dr1 = 0;
+    if (pLast_0 == nullptr)
+      return;
+
+    TTDListNode *pr6 = pLast_0;
+    TTDListNode *pr0 = nullptr;
+    while (1) {
+      dr1 = dr1 << 31;
+      pr0 = pr6;
+      if (dr1 == 0 || pr0 != pLast_0) {  //需要头和尾两个限定条件才能正确删除环形双向链表
+        //loc_168B40
+        if (pr0 == nullptr)
+          return;
+        pr6 = pr0->prev;
+        dr1 = 1;
+        if (pr0 != nullptr) {  //00168B44
+          //00168B46
+          delete pr0;
+          dr1 = 1;
+        }
+      } else {
+        break;
+      }
+    }
+  };
+  //-------------------------------------------------------------------------------------------------
+  //001677DE
+  void Insert(TTDList<T> &list, T &t2, T &t3) {
+    TTDListNode *pNode = new TTDListNode;
+    pNode->m = t2;
+    dCount_4 = 0;
+    pLast_0 = nullptr;
+    int dr4 = 0;
+    TTDListNode *pr0 = list.pLast_0;
+    while ((dr4 << 31) == 0 || pr0 != list.pLast_0) {  //pr0 != pr1 保证只转一圈
+      //loc_16781A
+      if (pr0->m == t3) {  //在t3之前插入一个新的结点
+        //00167822
+        pNode->next = pr0;
+        pNode->prev = pr0->prev;
+        pr0->prev->next = pNode;
+        pr0->prev = pNode;
+        dCount_4 = 0;
+        //pLast_0 = pNode; //??? .text:00167830   STR R7, [R5] 实在不理解这行代码的逻辑, 很有可能是原码的BUG
+        pLast_0 = nullptr;  //暂时修正为nullptr
+        break;
+      } else {
+        pr0 = pr0->prev;
+        dr4 = 1;
+      }
+    }
+    //loc_167832
+    list.dCount_4++;
+  };
+
+  //-------------------------------------------------------------------------------------------------
+  //Insert 从结点队列的尾部插入,构成双向链表
+  //00167876
+  void Insert(T t) {
+    TTDListNode *pNode = new TTDListNode;
+    pNode->m = t;
+    if (pLast_0 != nullptr) {
+      //00167896
+      pNode->prev = pLast_0;
+      pNode->next = pLast_0->next;
+      pLast_0->next->prev = pNode;  //这行代码原始汇编里面并没有,应该是原始代码bug,否则不能够成双向循环链表
+      pLast_0->next = pNode;
+      pLast_0 = pNode;
+    } else {
+      //loc_1678A6
+      pLast_0 = pNode;
+      pNode->prev = pNode;
+      pLast_0->next = pLast_0;  //前后的指针,都指向自身
+    }
+    //loc_1678AE
+    dCount_4++;
+  };
+  //-------------------------------------------------------------------------------------------------
+  //00167B14
+  void Remove(T &t) {
+    int dr2 = 0;
+    TTDListNode *pr0 = pLast_0;
+    while (1) {
+      dr2 = dr2 << 31;
+      if (dr2 == 0 || pr0 != pLast_0) {
+        //loc_167B34
+        if (pr0->m == t) {
+          //00167B3A
+          pr0->prev->next = pr0->next;
+          pr0->next->prev = pr0->prev;
+          if (pLast_0->m == t) {  //如果要删除的结点是 pLast_0, 需要做特殊处理
+            pLast_0 = pr0->prev;
+          }
+          //00167B4E
+          delete pr0;
+          dCount_4--;
+          if (dCount_4 == 0)  //if语句代码也是自己加的,原始汇编里面没有, 应该是原始的汇编代码的bug
+            pLast_0 = nullptr;
+          return;
+        } else {
+          //loc_167B26
+          pr0 = pr0->prev;
+          dr2 = 1;
+        }
+      } else {
+        return;  //00167B30
+      }
+    }
+  };
+  //-------------------------------------------------------------------------------------------------
+  TTDListNode *pLast_0;
+  int8_t dCount_4;  //只用了一个字节表示结点长度,List最大长度只能是255
+};
+
+#endif  //_FTTLIST_H_

+ 189 - 0
src/jni/TTList.h

@@ -0,0 +1,189 @@
+//FTTList - [2020-04-13 11:57:47]
+#ifndef _TTLIST_H_
+#define _TTLIST_H_
+
+#include "common.h"
+
+/*
+00168F2E TTList<TTDListNode<TTSPtr<TNMVert>> *>::~TTList()
+00168CD4 TTList<TTDListNode<TTSPtr<TNMVert>> *>::Insert(TTDListNode<TTSPtr<TNMVert>> *)
+00168E60 TTList<TTDListNode<TTSPtr<TNMVert>> *>::Remove(TTDListNode<TTSPtr<TNMVert>> *)
+
+00169A68 TTList<fpoint2<14u>>::~TTList()
+00169694 TTList<fpoint2<14u>>::Insert(fpoint2<14u>)
+
+00168B5E TTList<TTDList<TTSPtr<TNMVert>> *>::Remove(TTDList<TTSPtr<TNMVert>> *)
+00168BA6 TTList<TTDList<TTSPtr<TNMVert>> *>::Insert(TTDList<TTSPtr<TNMVert>> *)
+00168F46 TTList<TTDList<TTSPtr<TNMVert>> *>::~TTList()
+
+00169824 TTList<TNMAStar *>::~TTList()
+00169604 TTList<TNMAStar *>::InsertSorted(TNMAStar *)
+00169670 TTList<TNMAStar *>::Pop()
+
+TTList_point
+*/
+
+typedef int (*pfun_TTList_unk1)(int*, int*);
+
+template <typename T>
+class TTList {
+public:
+  struct TTListNode {
+    T m;
+    TTListNode* next;
+  };
+
+  TTList() {
+    pBegin_0 = nullptr;
+    pEnd_4 = 0;
+    dCount_8 = false;
+    pFun_C = nullptr;
+  };
+
+  //00169824  TTList_point
+  ~TTList() {
+    for (TTListNode* p = pBegin_0; p != nullptr;) {
+      TTListNode* n = p->next;
+      delete p;
+      p = n;
+    }
+  };
+
+  //00168BA6
+  void Insert(T t) {
+    TTListNode* p = new TTListNode();
+    p->m = t;
+    p->next = nullptr;  //.text:00168BB8   STRD.W R5, R6, [R0]
+    if (pBegin_0 == nullptr) {
+      pBegin_0->next = p;
+    }
+    //loc_168BC2
+    if (pEnd_4) {
+      pEnd_4->next = p;
+    }
+    //loc_168BC8
+    pEnd_4 = p;
+    dCount_8++;
+  };
+
+  //00169604
+  void InsertSorted(T t) {
+    TTListNode* pnode = new TTListNode;
+    pnode->m = t;
+    pnode->next = nullptr;  //0016961C
+    int var_20;
+    T var_24;
+    TTListNode* dr6 = nullptr;
+    for (TTListNode* pr5 = &pBegin_0[0]; pr5 != nullptr; pr5 = pr5->next) {
+      //loc_16962A
+      var_24 = pr5->m;
+      if (pFun_C(&var_20, &var_24)) {  //??? pFun_C不知道在何时赋值的
+        //loc_169656
+        TTListNode* pr0 = pBegin_0;
+        if (dr6) {
+          //0016965A
+          pr0 = ++dr6;
+        }
+        pr0 = pnode;
+        pnode->next = pr5;
+        break;
+      }
+      //00169638
+      dr6 = pr5;
+    }
+
+    //00169642
+    if (dr6 == nullptr) {
+      pBegin_0 = pnode;
+    }
+    //loc_169648
+    if (pEnd_4 != nullptr) {
+      pEnd_4->next = pnode;
+      pEnd_4 = pnode;
+    }
+
+    //loc_169666
+    dCount_8++;
+  };
+
+  //00168B5E
+  void Remove(T t) {
+    if (pBegin_0 == nullptr)
+      return;  //locret_168B84
+    //00168B66
+    TTListNode** pr4 = &pBegin_0;
+    TTListNode* pPri_r3 = nullptr;
+    while (*pr4 != nullptr) {  //loc_168B7E
+      //loc_168B74
+      if (*pr4->m == t) {
+        //loc_168B86
+        if (pPri_r3) {
+          pPri_r3->next = (*pr4)->next;
+        }
+        //loc_168B8C
+        if (pBegin_0->m == t) {
+          pBegin_0 = (*pr4)->next;
+        }
+
+        if (pEnd_4->m == t) {
+          pEnd_4 = pPri_r3;
+        }
+
+        delete (*pr4);
+        dCount_8--;
+        return;
+      } else {
+        pPri_r3 = pr4;
+      }
+    }
+  };
+
+  //00169670
+  T Pop() {
+    /*
+    .text:00169670   PUSH            {R4,R5,R7,LR}
+    .text:00169672   MOV             R4, R0              R4 = R0 = this
+    .text:00169674   LDR             R0, [R0]            R0 = pBegin_0
+    .text:00169676   LDRD.W          R5, R1, [R0]        R5 = pBegin_0->m R1 = pBegin_0->next
+    .text:0016967A   CBNZ            R1, loc_169680
+    .text:0016967C   MOVS            R1, #0
+    .text:0016967E   STR             R1, [R4,#4]
+    .text:00169680
+    .text:00169680 loc_169680:                   @ CODE XREF: TTList<TNMAStar *>::Pop()+A↑j
+    .text:00169680   CMP             R0, #0
+    .text:00169682   STR             R1, [R4]
+    .text:00169684   Beq             loc_16968A
+    .text:00169686   BLX             j__ZdlPv    @ operator delete(void *)
+    .text:0016968A
+    .text:0016968A loc_16968A:                   @ CODE XREF: TTList<TNMAStar *>::Pop()+14↑j
+    .text:0016968A   LDRB            R0, [R4,#8]
+    .text:0016968C   SUBS            R0, #1
+    .text:0016968E   STRB            R0, [R4,#8]
+    .text:00169690   MOV             R0, R5
+    .text:00169692   POP             {R4,R5,R7,PC}
+    */
+    //这个函数的作用是弹出 pBegin_0 当中的第一个结点
+
+    T r = pBegin_0->m;  //原始的代码的当中没有考虑到pBegin_0是否为nullptr
+    TTListNode* pn = pBegin_0->next;
+    if (pBegin_0->next == nullptr) {  //0016967A
+      pEnd_4 = nullptr;
+      pn = nullptr;
+    }
+    //loc_169680
+    pBegin_0 = pn;
+    if (pBegin_0) {
+      delete pBegin_0;
+    }
+    //loc_16968A
+    dCount_8--;
+    return r;
+  };
+
+  TTListNode* pBegin_0;
+  TTListNode* pEnd_4;
+  int8_t dCount_8;          //只用了一个字节表示结点长度,List最大长度只能是255
+  pfun_TTList_unk1 pFun_C;  //??? 不知道,是在哪儿赋值的
+};
+
+#endif  //_FTTLIST_H_

+ 103 - 0
src/jni/TTSPtr.h

@@ -0,0 +1,103 @@
+//TTSPtr - [2020-04-13 11:57:47]
+#ifndef _TTSPTR_H_
+#define _TTSPTR_H_
+
+#include "common.h"
+
+/*
+0016779E TTSPtr<TNMVert>::TTSPtr()
+001677BE TTSPtr<TNMVert>::TTSPtr(TNMVert*)
+00166E50 TTSPtr<TNMVert>::~TTSPtr()
+00167840 TTSPtr<TNMVert>::operator=(TTSPtr<TNMVert> const&)
+00168AFC TTSPtr<TNMVert>::Release()
+
+struct TNMVert {
+  int field_0;
+  int field_4;
+};
+
+TTSPtr 智能指针
+外部指针不能重复绑定,否则会崩溃
+*/
+
+template <typename T>
+class TTSPtr {
+public:
+  //0016779E
+  TTSPtr() {
+    pT_0 = 0;
+    pRef_4 = new int;
+    *pRef_4 = 0;
+    ++(*pRef_4);
+  };
+  //-------------------------------------------------------------------------------------------------
+  //001677BE
+  TTSPtr(T *pNode) {
+    pT_0 = pNode;
+    pRef_4 = new int;
+    *pRef_4 = 0;
+    ++(*pRef_4);
+  };
+  //-------------------------------------------------------------------------------------------------
+  //00166E50 TTSPtr_TNMVert
+  ~TTSPtr() {
+    int dr1 = *pRef_4;
+    dr1--;
+    *pRef_4 = dr1;
+    if (dr1 == 0) {
+      if (pT_0)
+        delete pT_0;
+      //loc_166E66
+      if (pRef_4)
+        delete pRef_4;
+    }
+    //loc_166E6E
+  };
+  //-------------------------------------------------------------------------------------------------
+  //00167840
+  TTSPtr<T> &operator=(TTSPtr<T> const &other) {
+    if (this != &other) {
+      --(*pRef_4);
+      if (*pRef_4 == 0) {
+        if (pT_0)
+          delete pT_0;
+        if (pRef_4)
+          delete pRef_4;
+      }
+      //loc_167864
+      this->pT_0 = other.pT_0;
+      this->pRef_4 = other.pRef_4;
+      ++(*other.pRef_4);
+    }
+    //loc_167872
+    return *this;
+  };
+  //-------------------------------------------------------------------------------------------------
+  inline bool operator==(TTSPtr<T> const &other) { //合理的猜测这个函数是被inline
+    if (pT_0 == other.pT_0) {
+      return true;
+    }
+    return false;
+  }
+  //-------------------------------------------------------------------------------------------------
+  //00168AFC
+  void Release() {
+    --(*pRef_4);
+    if (*pRef_4 == 0) {
+      if (pT_0)
+        delete pT_0;
+      if (pRef_4)
+        delete pRef_4;
+    }
+    //loc_168B1A
+    pT_0 = nullptr;
+    pRef_4 = new int;
+    *pRef_4 = 0;
+    ++(*pRef_4);
+  };
+  //-------------------------------------------------------------------------------------------------
+  T *pT_0;
+  int *pRef_4;
+};
+
+#endif //_TTSPTR_H_

+ 77 - 0
src/jni/TTVector.h

@@ -0,0 +1,77 @@
+//FTTVector - [2020-04-13 11:57:47]
+#ifndef _TTVECTOR_H_
+#define _TTVECTOR_H_
+
+#include "common.h"
+
+/*
+
+0016D974 TTVector<TNMNeighbour>::~TTVector()
+00168EA8 TTVector<TNMNeighbour>::Insert(TNMNeighbour)
+
+0016D9A2 TTVector<TNMTri>::~TTVector()
+00168D00 TTVector<TNMTri>::Insert(TNMTri)
+
+0016D992 TTVector<fpoint2<14u>>::~TTVector()
+00169786 TTVector<fpoint2<14u>>::Insert(fpoint2<14u>)
+001696DE TTVector<fpoint2<14u>>::Append(TTVector<fpoint2<14u>> const&)
+
+0016D984 TTVector<uchar>::~TTVector()
+0016970C TTVector<uchar>::Append(TTVector<uchar> const&)
+0016972A TTVector<uchar>::Insert(uchar)
+*/
+
+template <typename T>
+class TTVector {
+public:
+  TTVector() {
+    pBuf_0 = nullptr;
+    dTotal_4 = 0;
+    dInsertPos_8 = 0;
+  };
+
+  ~TTVector() {
+    if (pBuf_0 != nullptr)
+      delete[] pBuf_0;
+  };
+
+  void Append(TTVector<T> const& other) {
+    for (int i = 0; i < other.dInsertPos_8; ++i)
+      Insert(other.pBuf_0[i]);
+  }
+
+  //这个函数没有完成??????
+  void Insert(T a) {
+    T* pDat = nullptr;
+    if (dTotal_4) {
+      //00169734
+      if (dInsertPos_8 == dTotal_4) {
+        //0016973E
+        int dr0 = dTotal_4 * 2;
+        pDat = new T[dTotal_4 * 2];
+        memcpy(pDat, pBuf_0, sizeof(T) * dTotal_4);
+        delete[] pBuf_0;
+        pBuf_0 = pDat;
+        dTotal_4 = dTotal_4 * 2;
+     //   pr7 =???????
+      } else {
+        //loc_16977A
+        pDat = pBuf_0;
+      }
+    } else {
+      //loc_169762
+      dTotal_4 = 1;
+      pBuf_0 = new T[dTotal_4];
+      pDat = pBuf_0;
+    }
+    //loc_16977C
+    pDat[dInsertPos_8] = a;
+    dInsertPos_8++;
+  }
+
+  T* pBuf_0;
+  int dTotal_4;
+  int dInsertPos_8;
+};
+
+#endif  //_FTTVECTOR_H_

+ 9 - 0
src/jni/TUV.h

@@ -0,0 +1,9 @@
+//TUV - [2020-04-13 11:57:47]
+#ifndef _TUV_H_
+#define _TUV_H_
+
+struct TUV {
+  float x;
+  float y;
+};
+#endif  //_TUV_H_

+ 22 - 0
src/jni/UNITROT.h

@@ -0,0 +1,22 @@
+// UNITROT.h - [2020-06-22 11:41:46]
+#ifndef _UNITROT_H_
+#define _UNITROT_H_
+
+#include "common.h"
+
+/*
+0016DB3C UNITROT_X(int)
+0016DB4C UNITROT_Y(int)
+00179E40 UNITROT_P(int)
+*/
+
+//0016DB3C
+uint UNITROT_X(int);
+
+//0016DB4C
+uint UNITROT_Y(int);
+
+//00179E40
+TPoint UNITROT_P(int);
+
+#endif  //_UNITROT_H_

+ 81 - 0
src/jni/Util.cpp

@@ -0,0 +1,81 @@
+#include "Util.h"
+#include "CFTTFileSystem_PAK.h"
+#include "memctrl.h"
+
+int g_iPakOpen[100];
+CFTTFileSystem_PAK *g_pPakFileSystem[100];
+CFTTFile *g_pPakFile[100];
+
+const char *sPakFile[] = {
+    "PKG:Data/flags.pak",
+    "PKG:Data/nis.pak"};
+
+//-------------------------------------------------------------------------------------------------
+//00178670
+void UTILCOL_CheckSpheresOverlap(TPoint3D, int, TPoint3D, int) {
+}
+//-------------------------------------------------------------------------------------------------
+//001786E4
+int UTILCOL_RayCircleTest(TPoint *, int, TPoint *, TPoint *, int) {
+  return 0;
+}
+//-------------------------------------------------------------------------------------------------
+//0017875C
+void UTILCOL_LengthenBone(TPoint3D *, TPoint3D *, int) {
+}
+//-------------------------------------------------------------------------------------------------
+//001787A0
+bool UTILCOL_CapsuleCapsuleCheck(TPoint3D, TPoint3D, TPoint3D, TPoint3D, int, int, int, int) {
+  return 0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F5080  //^_^ UtilOpenPak(0, "PAK");
+void UtilOpenPak(int a0, char const *pFileType) {
+  for (int dr6 = 0; dr6 <= 99; dr6++) {  //loc_1F50AC
+    //loc_1F5092
+    if (a0 == dr6) {
+      if (g_iPakOpen[a0] == 0)
+        continue;
+      return;
+    }
+    //loc_1F509E
+    if (g_iPakOpen[dr6] != 0) {
+      UtilClosePak(dr6);
+    }
+  }
+
+  //001F50B0
+  CFTTFile* r6_pFile = CFTTFileSystem::fopen(sPakFile[a0], "rb", EFTTMemHeapID_0);
+  g_pPakFileSystem[a0] = new CFTTFileSystem_PAK;
+  g_pPakFileSystem[a0]->Initialise(r6_pFile, EFTTMemHeapID_0);
+  CFTTFileSystem::Register(g_pPakFileSystem[a0], pFileType);
+  g_iPakOpen[a0] = 1;
+}
+//-------------------------------------------------------------------------------------------------
+//001F510C //^_^
+void UtilClosePak(int a0) {
+  if (g_iPakOpen[a0]) {
+    CFTTFileSystem::Deregister(g_pPakFileSystem[a0], nullptr);
+    //001F5136
+    if (g_pPakFileSystem[a0] != nullptr) {
+      delete g_pPakFileSystem[a0];
+    }
+    //001F5140
+    g_pPakFileSystem[a0] = nullptr;
+
+    if (g_pPakFile[a0] != nullptr) {
+      delete g_pPakFile[a0];
+    }
+
+    //loc_1F5154
+    g_pPakFile[a0] = nullptr;
+    g_iPakOpen[a0] = 0;
+  }
+  //locret_1F515E
+}
+//-------------------------------------------------------------------------------------------------
+//001F5170 //^_^
+bool UtilIsPackOpen(int a0) {
+  return g_iPakOpen[a0] != 0;
+}
+//-------------------------------------------------------------------------------------------------

+ 38 - 0
src/jni/Util.h

@@ -0,0 +1,38 @@
+//Util.h - [2020-06-22 11:41:46]
+#ifndef _UTIL_H_
+#define _UTIL_H_
+
+#include "common.h"
+
+/*
+00178670 UTILCOL_CheckSpheresOverlap(TPoint3D,int,TPoint3D,int)
+001786E4 UTILCOL_RayCircleTest(TPoint *,int,TPoint *,TPoint *,int)
+0017875C UTILCOL_LengthenBone(TPoint3D *,TPoint3D *,int)
+001787A0 UTILCOL_CapsuleCapsuleCheck(TPoint3D,TPoint3D,TPoint3D,TPoint3D,int,int,int,int)
+001F5080 UtilOpenPak(int,char const*)
+001F510C UtilClosePak(int)
+001F5170 UtilIsPackOpen(int)
+*/
+
+//00178670
+void UTILCOL_CheckSpheresOverlap(TPoint3D, int, TPoint3D, int);
+
+//001786E4
+int UTILCOL_RayCircleTest(TPoint *, int, TPoint *, TPoint *, int);
+
+//0017875C
+void UTILCOL_LengthenBone(TPoint3D *, TPoint3D *, int);
+
+//001787A0
+bool UTILCOL_CapsuleCapsuleCheck(TPoint3D, TPoint3D, TPoint3D, TPoint3D, int, int, int, int);
+
+//001F5080
+void UtilOpenPak(int a0, char const *pFileType);
+
+//001F510C
+void UtilClosePak(int a0);
+
+//001F5170
+bool UtilIsPackOpen(int a0);
+
+#endif  //_UTIL_H_

+ 140 - 0
src/jni/XCTRL.cpp

@@ -0,0 +1,140 @@
+#include "XCTRL.h"
+#include "FTTInput.h"
+#include "CFE.h"
+#include "GFXRENDER.h"
+
+struct XCTRL_Touch {
+  TPoint ttouchDownPos_0;
+  TPoint tpos_8;
+  uint8 bWipe_10;  //是否向右滑动
+  bool bisReleased_11;
+  bool bisPressed_12;
+  bool bisTouch_13;
+  bool bisDoubleTapped_14;  //是否双击
+  bool bfield_15;
+  bool bfield_16;
+  bool bfield_17;
+  int ilastTime_18;
+  int touchDownTime_1C;
+};
+
+MYSTATIC XCTRL_Touch gs_ptouchEventHW_34A490[4];
+MYSTATIC XCTRL_Touch gs_ptouchEvent_34A510[4];
+MYSTATIC int gs_icount_34A590;    //未使用会被优化掉
+MYSTATIC int gs_icountHW_34A594;  //未使用会被优化掉
+MYSTATIC int gs_i_34A598;         //未使用会被优化掉
+
+//0x0011AA24  ^_^
+void sub_11AA24() {
+}
+//-------------------------------------------------------------------------------------------------
+//0011A5C4
+void XCTRL_ProcessHW() {
+}
+//-------------------------------------------------------------------------------------------------
+//0011A5C8
+void XCTRL_SetHWToDevice() {
+}
+//-------------------------------------------------------------------------------------------------
+//0011A5CC
+void XCTRL_Process_ClearTriggers() {
+}
+//-------------------------------------------------------------------------------------------------
+//0011A5D0
+bool XCTRL_TouchHWIsPressed() {
+  return false;
+}
+//-------------------------------------------------------------------------------------------------
+//0011A5DC ^_^
+bool XCTRL_TouchHWIsReleased() {
+  return false;
+}
+//-------------------------------------------------------------------------------------------------
+//0011A5E8 ^_^
+bool XCTRL_TouchHWIsTouching() {
+  return false;
+}
+//-------------------------------------------------------------------------------------------------
+//0011A5F4
+TPoint XCTRL_TouchHWGetPos() {
+  TPoint d;
+  return d;
+}
+//-------------------------------------------------------------------------------------------------
+//0011A608
+int XCTRL_TouchGetCount() {
+  return 10;
+}
+//-------------------------------------------------------------------------------------------------
+//0011A614 ^_^
+bool XCTRL_TouchIsTouching(int i1) {
+  return false;
+}
+//-------------------------------------------------------------------------------------------------
+//0011A624
+TPoint XCTRL_TouchGetDownPos(int dIndex) {
+  TPoint d;
+  return d;
+}
+//-------------------------------------------------------------------------------------------------
+//0011A63C ^_^
+void XCTRL_TouchSetDownPos(int i1, TPoint tPoint2) {
+}
+//-------------------------------------------------------------------------------------------------
+//0011a654  ^_^
+int XCTRL_TouchGetDownTime(int i1) {
+  return 12;
+}
+//-------------------------------------------------------------------------------------------------
+//0011A664 //^_^
+TPoint XCTRL_TouchGetPos(int dIndex) {
+  TPoint d;
+  return d;
+}
+//-------------------------------------------------------------------------------------------------
+//0011A67C ^_^
+int XCTRL_TouchLastTime(int i1) {
+  return false;
+}
+//-------------------------------------------------------------------------------------------------
+//0011A68C ^_^
+bool XCTRL_TouchIsPressed(int i1) {
+  return false;
+}
+//-------------------------------------------------------------------------------------------------
+//0011A69C ^_^
+bool XCTRL_TouchIsReleased(int i1) {
+  return false;
+}
+//-------------------------------------------------------------------------------------------------
+//0011A6AC
+bool XCTRL_TouchIsDoubleTapped(int i1) {
+  return false;
+}
+//-------------------------------------------------------------------------------------------------
+//0011A6BC ^_^
+bool XCTRL_TouchGetSwipe(int i1) {
+  return false;
+}
+//-------------------------------------------------------------------------------------------------
+//0011A6CC
+void XCTRL_TouchResetHW() {
+}
+//-------------------------------------------------------------------------------------------------
+//0011A6EC ^_^
+void XCTRL_TouchReset() {
+}
+//-------------------------------------------------------------------------------------------------
+//0011A70C
+void XCTRL_TouchProcessHW() {
+  //loc_11A8D0
+}
+//-------------------------------------------------------------------------------------------------
+//0011A8F8  ^_^
+void XCTRL_TouchSetHWToDevice() {
+}
+//-------------------------------------------------------------------------------------------------
+//0011A9F4
+void XCTRL_TouchProcess_ClearTriggers() {
+}
+//-------------------------------------------------------------------------------------------------

+ 76 - 0
src/jni/XCTRL.h

@@ -0,0 +1,76 @@
+//AABB - [2020-06-22 11:41:46]
+#ifndef _XCTRL_H_
+#define _XCTRL_H_
+
+#include "common.h"
+
+//0011A5C4
+void XCTRL_ProcessHW();
+
+//0011A5C8
+void XCTRL_SetHWToDevice();
+
+//0011A5CC
+void XCTRL_Process_ClearTriggers();
+
+//0011A5D0
+bool XCTRL_TouchHWIsPressed();
+
+//0011A5DC
+bool XCTRL_TouchHWIsReleased();
+
+//0011A5E8
+bool XCTRL_TouchHWIsTouching();
+
+//0011A5F4
+TPoint XCTRL_TouchHWGetPos();
+
+//0011A608
+int XCTRL_TouchGetCount();
+
+//0011A614
+bool XCTRL_TouchIsTouching(int);
+
+//0011A624
+TPoint XCTRL_TouchGetDownPos(int);
+
+//0011A63C
+void XCTRL_TouchSetDownPos(int, TPoint);
+
+//0011A654
+int XCTRL_TouchGetDownTime(int);
+
+//0011A664
+TPoint XCTRL_TouchGetPos(int);
+
+//0011A67C
+int XCTRL_TouchLastTime(int);
+
+//0011A68C
+bool XCTRL_TouchIsPressed(int);
+
+//0011A69C
+bool XCTRL_TouchIsReleased(int);
+
+//0011A6AC
+bool XCTRL_TouchIsDoubleTapped(int);
+
+//0011A6BC
+bool XCTRL_TouchGetSwipe(int);
+
+//0011A6CC
+void XCTRL_TouchResetHW();
+
+//0011A6EC
+void XCTRL_TouchReset();
+
+//0011A70C
+void XCTRL_TouchProcessHW();
+
+//0011A8F8
+void XCTRL_TouchSetHWToDevice();
+
+//0011A9F4
+void XCTRL_TouchProcess_ClearTriggers();
+
+#endif  //_XCTRL_H_

+ 59 - 0
src/jni/XDBG.cpp

@@ -0,0 +1,59 @@
+#include "XDBG.h"
+
+//-------------------------------------------------------------------------------------------------
+//0011C31C
+void XDBG_CleanupDebugRenderers() {
+}
+//-------------------------------------------------------------------------------------------------
+//0011C358
+void XDBG_DrawDebugLine(CFTTVector32 *, CFTTVector32 *, uint) {
+}
+//-------------------------------------------------------------------------------------------------
+//0011C480
+void XDBG_CreateDebugCircleRenderHelper() {
+}
+//-------------------------------------------------------------------------------------------------
+//0011C520
+void XDBG_DrawDebugCircle(CFTTVector32 *, float, uint) {
+}
+//-------------------------------------------------------------------------------------------------
+//0011C620
+void XDBG_DrawDebugCircleFC(CFTTVector32 *, float, uint, bool) {
+}
+//-------------------------------------------------------------------------------------------------
+//0011C77C
+void XDBG_DrawDebugLineGame(TPoint, TPoint, uint) {
+}
+//-------------------------------------------------------------------------------------------------
+//0011C798
+void XDBG_DrawDebugLineGame(TPoint3D, TPoint3D, uint) {
+}
+//-------------------------------------------------------------------------------------------------
+//0011C818
+void XDBG_DrawDebugLineGameA(TPoint, TPoint, uint) {
+}
+//-------------------------------------------------------------------------------------------------
+//0011C89C
+void XDBG_DrawDebugCircleGame(TPoint3D, int, uint) {
+}
+//-------------------------------------------------------------------------------------------------
+//0011C8FC
+void XDBG_DrawDebugCircleGame(TPoint, int, uint) {
+}
+//-------------------------------------------------------------------------------------------------
+//0011C90C
+void XDBG_DrawDebugCircleGameFC(TPoint3D, int, uint, bool) {
+}
+//-------------------------------------------------------------------------------------------------
+//0011C96C
+void XDBG_DrawDebugCircleGameFC(TPoint, int, uint, bool) {
+}
+//-------------------------------------------------------------------------------------------------
+//0011C980
+void XDBG_RenderPlayerHUD() {
+}
+//-------------------------------------------------------------------------------------------------
+//0011C984
+void XDBG_RenderPlayerDebug() {
+}
+//-------------------------------------------------------------------------------------------------

+ 39 - 0
src/jni/XDBG.h

@@ -0,0 +1,39 @@
+//XDBG.h - [2020-06-22 11:41:46]
+#ifndef _XDBG_H_
+#define _XDBG_H_
+
+#include "CFTTVector32.h"
+
+/*
+0011C31C XDBG_CleanupDebugRenderers()
+0011C358 XDBG_DrawDebugLine(CFTTVector32 *,CFTTVector32 *,uint)
+0011C480 XDBG_CreateDebugCircleRenderHelper()
+0011C520 XDBG_DrawDebugCircle(CFTTVector32 *,float,uint)
+0011C620 XDBG_DrawDebugCircleFC(CFTTVector32 *,float,uint,bool)
+0011C77C XDBG_DrawDebugLineGame(TPoint,TPoint,uint)
+0011C798 XDBG_DrawDebugLineGame(TPoint3D,TPoint3D,uint)
+0011C818 XDBG_DrawDebugLineGameA(TPoint,TPoint,uint)
+0011C89C XDBG_DrawDebugCircleGame(TPoint3D,int,uint)
+0011C8FC XDBG_DrawDebugCircleGame(TPoint,int,uint)
+0011C90C XDBG_DrawDebugCircleGameFC(TPoint3D,int,uint,bool)
+0011C96C XDBG_DrawDebugCircleGameFC(TPoint,int,uint,bool)
+0011C980 XDBG_RenderPlayerHUD()
+0011C984 XDBG_RenderPlayerDebug()
+*/
+
+void XDBG_CleanupDebugRenderers();                               //0011C31C
+void XDBG_DrawDebugLine(CFTTVector32 *, CFTTVector32 *, uint);   //0011C358
+void XDBG_CreateDebugCircleRenderHelper();                       //0011C480
+void XDBG_DrawDebugCircle(CFTTVector32 *, float, uint);          //0011C520
+void XDBG_DrawDebugCircleFC(CFTTVector32 *, float, uint, bool);  //0011C620
+void XDBG_DrawDebugLineGame(TPoint, TPoint, uint);               //0011C77C
+void XDBG_DrawDebugLineGame(TPoint3D, TPoint3D, uint);           //0011C798
+void XDBG_DrawDebugLineGameA(TPoint, TPoint, uint);              //0011C818
+void XDBG_DrawDebugCircleGame(TPoint3D, int, uint);              //0011C89C
+void XDBG_DrawDebugCircleGame(TPoint, int, uint);                //0011C8FC
+void XDBG_DrawDebugCircleGameFC(TPoint3D, int, uint, bool);      //0011C90C
+void XDBG_DrawDebugCircleGameFC(TPoint, int, uint, bool);        //0011C96C
+void XDBG_RenderPlayerHUD();                                     //0011C980
+void XDBG_RenderPlayerDebug();                                   //0011C984
+
+#endif  //_XDBG_H_

+ 533 - 0
src/jni/XMATH.cpp

@@ -0,0 +1,533 @@
+#include "XMATH.h"
+#include "global_func.h"
+#include "XMATH_var.h"
+
+//-------------------------------------------------------------------------------------------------
+//001F3324 ^_^ 经过单元测试,功能正常
+int xsin(int a1) {
+  return 0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F3390 ^_^
+int xcos(int a1) {
+  return xsin(a1 + 4096);
+}
+//-------------------------------------------------------------------------------------------------
+//001F2368 //^_^ 经过单元测试,功能正常
+ushort XMATH_ArcTan(int d_r0_arg, int d_r1_arg) {
+  return 0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F2400
+float XMATH_RaySphereTest(TPoint3D *, int, TPoint3D *, TPoint3D *, int) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F248E
+float XMATH_DotProduct(TPoint3D *, TPoint3D *) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F24A8
+float XMATH_TendAngle(int, int) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F24F4 //^_^
+uint XMATH_CalcSqrt(uint ar0) {
+  return 0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F251C  //^_^
+uint64_t XMATH_CalcSqrt(uint64_t a1) {
+  return 0;
+}
+//-------------------------------------------------------------------------------------------------
+//001f2586 ^_^
+void XMATH_Normalize(TPoint3D *a1, int a2) {
+}
+//-------------------------------------------------------------------------------------------------
+//001f25f2 ^_^  除BL BLX 不一致 经过单元测试,功能正常
+void XMATH_Normalize(TPoint *a1, int a2) {
+}
+//-------------------------------------------------------------------------------------------------
+//001F2644 ^_^  bx  blx  除法 经过单元测试,功能正常
+TPoint3D XMATH_Normalize(TPoint3D a1, int a2) {
+  TPoint3D result;
+  return result;
+}
+//-------------------------------------------------------------------------------------------------
+//001f26b0 ^_^ 除法,我的是blx,原版是bl 经过单元测试,功能正常
+TPoint3D XMATH_Normalize2D(TPoint3D a1, int a2) {
+  TPoint3D ret;
+  return ret;
+}
+
+//-------------------------------------------------------------------------------------------------
+//001f2700 ^_^ 除法,我的是blx,原版是bl 经过单元测试,功能正常
+TPoint XMATH_Normalize(TPoint a1, int a2) {
+  TPoint ret;
+  return ret;
+}
+//-------------------------------------------------------------------------------------------------
+//001F2756
+float XMATH_Normalize(TPointF *, float) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F27AE
+float XMATH_Cross(TPoint3D *, TPoint3D *, TPoint3D *) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F2802
+float XMATH_Subtract(TPoint3D *, TPoint3D *, TPoint3D *) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F2824
+float XMATH_Add(TPoint3D *, TPoint3D *, TPoint3D *) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F2842
+float XMATH_Scale(TPoint3D *, int, TPoint3D *) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F2856
+float XMATH_IsDotPositive(TPoint *, TPoint *) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F2874
+float XMATH_IsSimilarDirection(TPoint *, TPoint *) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F28B6
+float XMATH_ClipVectorX(TPoint *, TPoint *, int) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001f2904 ^_^ 经过单元测试,功能正常
+void XMATH_ClipVectorY(TPoint *a1, TPoint *a2, int a3) {
+}
+//-------------------------------------------------------------------------------------------------
+//001f2952  ^_^  除法 bl  blx不一致 单元测试,没有运行到, 暂时无法验证正确性
+void XMATH_ClipVectorX(TPoint3D *a1, TPoint3D *a2, int a3) {
+  LOGI("XMATH_ClipVectorX 001f2952 %d", a3);
+}
+//-------------------------------------------------------------------------------------------------
+//001f29ca  ^_^ 除法 bl  blx不一致 经过单元测试,功能正常
+void XMATH_ClipVectorY(TPoint3D *a1, TPoint3D *a2, int a3) {
+}
+//-------------------------------------------------------------------------------------------------
+//001f2a44 经过单元测试,功能正常
+void XMATH_LineIntersect(const TPoint *a1, const TPoint *a2, const TPoint *a3, TPoint *a4, int *a5) {
+}
+//-------------------------------------------------------------------------------------------------
+//001F2B3C
+float XMATH_LineIntersect3D(TPoint3D const *, TPoint3D const *, TPoint3D const *, TPoint3D *, int *) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F2CA4
+float XMATH_DistPointToLineF(TPointF3D, TPointF3D, TPointF3D, TPointF3D *, float *) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F2D80
+float XMATH_Mag3D(TPointF3D const *) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F2DC2
+float XMATH_LineLineIntersect(TPoint const *, TPoint const *, TPoint const *, TPoint const *, TPoint *) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001f2f20 测试数据输出结果一致 经过单元测试,功能正常
+int XMATH_LineLineDistance(const TPoint3D *a1, const TPoint3D *a2, const TPoint3D *a3, const TPoint3D *a4, int *a5, int *a6) {
+  return 0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F322C
+float XMATH_Clamp64(long long, long long, long long) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001f3274	^_^  调用sqrt b blx的区别 经过单元测试,功能正常
+uint32_t XMATH_Mag3D(TPoint3D const *a1) {
+  return 0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F328A //^_- 经过单元测试,功能正常 _Z9XMATH_MagPK6TPoint
+//001F328A处:我的没有PUSH和POP //001F3298处:我的是B.W,原始是BLX
+uint64_t XMATH_Mag(TPoint const *p_tpoint_r0) {
+  return 0;
+}
+//-------------------------------------------------------------------------------------------------
+//001f329e	XMATH_Mag	16 经过单元测试,功能正常
+float XMATH_Mag(TPointF const *a1) {
+  return 0.0f;
+}
+//-------------------------------------------------------------------------------------------------
+//001F32D8
+uint64_t XMATH_Mag2D(TPoint3D const *pPoint3D0) {
+  return 0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F32DC ^_^ 经过单元测试,功能正常
+TPoint XMATH_Project(int a1, int a2) {
+  TPoint result;
+  return result;
+}
+//-------------------------------------------------------------------------------------------------
+//001f3398  ^_^ 经过单元测试,功能正常
+TPoint XMATH_PointProject(TPoint tpoint_a1, int i2, int i3) {
+  TPoint tpoint_sp4;
+  return tpoint_sp4;
+}
+//-------------------------------------------------------------------------------------------------
+//001F33CE 测试数据通过 汇编代码对栈地址做比较 经过单元测试,功能正常
+TPoint3D XMATH_PointProject(TPoint3D a1, int a2, int a3) {
+  TPoint3D tpoint_var24;
+  return tpoint_var24;
+}
+//-------------------------------------------------------------------------------------------------
+//001F3404
+float XMATH_Squeeze(TPoint3D *, TPoint3D *, int) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001f3490 ^_^ 经过单元测试,功能正常
+uint32_t XMATH_Distance3D(const TPoint3D *a1, const TPoint3D *a2) {
+  return 0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F34BA
+float XMATH_BlendAngle(int, int, int) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F3500
+float XMATH_InterpolateClampColor(float, float, float, uint, uint) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F363C //^_- 经过单元测试,功能正常
+//001F3682 这条CMP指令挪到下面去了,但逻辑相同
+float XMATH_InterpolateClampFloat(float f_r0_arg, float f_r1_arg, float f_r2_arg, float f_r3_arg, float f_arg_0) {
+  return 0.0f;
+}
+//-------------------------------------------------------------------------------------------------
+//001F36B0 //^_- 经过单元测试,功能正常
+//001F36B4 循环条件不一样,原始是0xFFFFFFE0 + ADD,我的是 0x20 + SUB
+uint XMATH_BitSum(unsigned int ud_r0) {
+  return 1;
+}
+//-------------------------------------------------------------------------------------------------
+//001f36ca 测试结果输出一致 经过单元测试,功能正常
+void XMATH_QuatNormalize(TQuat *a1, TQuat *a2) {
+}
+//-------------------------------------------------------------------------------------------------
+//001f372c ^_^ 经过单元测试,功能正常
+void XMATH_QuatMultiply(TQuat *a1, TQuat *a2, TQuat *a3) {
+}
+//-------------------------------------------------------------------------------------------------
+//001f37c8 ^_^ 经过单元测试,功能正常
+void XMATH_EulerToQuat(int a1, int a2, int a3, TQuat *a4) {
+}
+//-------------------------------------------------------------------------------------------------
+//001F38B0
+float XMATH_SetQuatIdentity(TQuat *) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001f38d0 ^_^
+//??? 测试没有运行到,暂时无法验证正确性
+TPoint XMATH_RotatePoint(TPoint *a1, int a2) {
+  TPoint ret;
+  return ret;
+}
+//-------------------------------------------------------------------------------------------------
+//001f3934 ^_^ 经过单元测试,功能正常
+void XMATH_QuatRotateEuler(TQuat *a1, TPoint3D *a2) {
+}
+//-------------------------------------------------------------------------------------------------
+//001f396e ^_- 一处加法顺序不一样,但汇编意思是一样的;除法,我的是blx,原版是bl
+void XMATH_QuatSlerp(TQuat *a1, TQuat *a2, TQuat *a3, int a4) {
+}
+//-------------------------------------------------------------------------------------------------
+//001f3b66	^_^ 没有运行,暂时无法测试
+void XMATH_QuatBlend(TQuat *a1, TQuat *a2, TQuat *a3, int a4) {
+  LOGI("XMATH_QuatBlend 001f3b66");
+}
+//-------------------------------------------------------------------------------------------------
+//001F3B7A
+float XMATH_EaseInOut(int, int, int) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F3B9E
+float XMATH_Power(int, int) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F3BAE
+float XMATH_ClampAngle(int, int, int) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F3BD4
+float XMATH_IsPowerOfTwo(int) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F3BE8 //^_^
+int XMATH_Clamp(int d_r0, int d_r1, int d_r2) {
+  return 0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F3BF8
+float XMATH_Clampu8(uchar, uchar, uchar) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F3C08 //^_^
+float XMATH_ClampFloat(float f0, float f1, float f2) {
+  return 1.45f;
+}
+//-------------------------------------------------------------------------------------------------
+//001f3c36 ^_^ 经过单元测试,功能正常
+float XMATH_WrapFloat(float a1, float a2, float a3) {
+  return 1.45f;
+}
+//-------------------------------------------------------------------------------------------------
+//001F3C80
+float XMATH_Wrap(int, int, int) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F3C98
+float XMATH_WrapLimit(int, int, int) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001f3caa ^_^ 经过单元测试,功能正常
+int XMATH_MagSq(TPoint const *a1) {
+  return 0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F3CC8
+float XMATH_ClampMag(TPoint *, int) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F3CF2
+float XMATH_ClampMagMin(TPoint *, int) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001f3d12 ^_^ 经过单元测试,功能正常
+int XMATH_DistanceSq(TPoint const *a1, TPoint const *a2) {
+  return 1;
+}
+//-------------------------------------------------------------------------------------------------
+//001f3d38 //没有运行到,暂进无法验证正确性
+int XMATH_Distance3DSq(const TPoint3D *a1, const TPoint3D *a2) {
+  LOGI("XMATH_Distance3DSq 001f3d38");
+  return 1;
+}
+//-------------------------------------------------------------------------------------------------
+//001f3d78 ^_^ 经过单元测试,功能正常
+uint64_t XMATH_Distance(const TPoint *a1, const TPoint *a2) {
+  return 1;
+}
+//-------------------------------------------------------------------------------------------------
+//001F3D94
+float XMATH_Distance3DF(TPointF3D *, TPointF3D *) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F3DD4
+float XMATH_Interpolate(int, int, int, int, int) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F3DF0
+float XMATH_InterpAngle(int, int, int, int, int) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F3E18
+float XMATH_InterpolateFloat(float, float, float, float, float) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001f3e4a ^_^ 调用除法代码不一致  and   bl  blx 经过单元测试,功能正常
+int XMATH_InterpolateClamp(int a1, int a2, int a3, int a4, int a5) {
+  return 1;
+}
+//-------------------------------------------------------------------------------------------------
+//001f3e92  ^_^	经过单元测试,功能正常
+int XMATH_SinInterpolateClamp(int a1, int a2, int a3, int a4, int a5) {
+  return 1;
+}
+//-------------------------------------------------------------------------------------------------
+//001f3eb8 ^_- 经过单元测试,功能正常
+// TODO 0x001f3eb8 ^_- 从xsin((int)temp)下一句汇编就不一样了,这边的汇编试了半天也无法和原版一样
+float XMATH_SinInterpolateClampFloat(float a1, float a2, float a3, float a4, float a5) {
+  return 12.34534f;
+}
+//-------------------------------------------------------------------------------------------------
+//001F3F20
+float XMATH_InterpolatePos(TPoint *, int, int, int, TPoint, TPoint) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001f3f74 ^_^ 经过单元测试,功能正常
+void XMATH_InterpolatePos3D(TPoint3D *pt3d_1, int i2, int i3, int i4, TPoint3D tp3D5, TPoint3D tp3D6) {
+}
+//-------------------------------------------------------------------------------------------------
+//001f3ffc  ^_^ 经过单元测试,功能正常
+void XMATH_SinInterpolatePos3D(TPoint3D *a1, int a2, int a3, int a4, TPoint3D a5, TPoint3D a6) {
+}
+//-------------------------------------------------------------------------------------------------
+//001F4084
+float XMATH_SetupRectI(TRectI *, int, int, int, int) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F408E //^_^
+void XMATH_SetupRect(TRect *p_trect_r0, float x, float y, float w, float h) {
+}
+//-------------------------------------------------------------------------------------------------
+//001F409C
+float XMATH_WrapToBounds(int, int, int) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F40AE
+float XMATH_RectOverlap(TRect, float, float, float, float) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F4138
+float XMATH_RectOverlap(TRect, TRect) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F41D4
+float XMATH_Dot_F(TPointF3D *, TPointF3D *) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F41FE
+float XMATH_DotProduct(TPoint *, TPoint *) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F4214 //^_^ 经过单元测试,功能正常
+uint XMATH_RGBDiff(uint ud_r0_arg, uint ud_r1_arg) {
+  return 1;
+}
+//-------------------------------------------------------------------------------------------------
+//001F424C
+float XMATH_MaxF(float, float) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F4268
+float XMATH_MinF(float, float) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001f4284 ^_^ 经过单元测试,功能正常
+bool XMATH_IsCrossingLine(int a1, int a2, int a3) {
+  return false;
+}
+//-------------------------------------------------------------------------------------------------
+//001F42AA
+float XMATH_IsCrossingLine2D(TPoint, TPoint, TPoint, TPoint) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F432C
+float XMATH_IsCrossingLineOneWay(int, int, int, int) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F4344
+float XMATH_IsStayingOneSideOf(int, int, int, int) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F435C
+float XMATH_IsStayingBetween(int, int, int, int) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F4376
+float XMATH_IsPwrTwo(int) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F438A //^_^ 经过单元测试,功能正常
+TPointF XMATH_GetCurvePosF(TPointF pf1, TPointF pf2, TPointF pf3, float f4) {
+  TPointF ret;
+  return ret;
+}
+//-------------------------------------------------------------------------------------------------
+//001F43E0
+float XMATH_CreateRandomIndexArray(int *, int) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F4416
+float XMATH_ShuffleArray(ushort *, int) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F4440
+float XMATH_CountNumDigits(int) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F445C
+float XMATH_RoundToNearest(int, int) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F4476 //^_^
+float XMATH_RoundFloatToNearestInt(float f_r0) {
+  return floor(f_r0 + 0.5);
+}
+//-------------------------------------------------------------------------------------------------
+//001F449E //^_^ 经过单元测试,功能正常
+CFTTVector32 XMATH_CatmullRom(CFTTVector32 const &v1,  // R1
+                              CFTTVector32 const &v2,  // R2
+                              CFTTVector32 const &v3,  // R3
+                              CFTTVector32 const &v4,  // stack
+                              float f5) {
+  CFTTVector32 vec;
+  return vec;
+}
+//-------------------------------------------------------------------------------------------------
+//001F459E
+float XMATH_StringToYardInt(char const *) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001f4638 ^_^ 经过单元测试,功能正常
+int XMATH_ClipPathBounds(TPoint3D *a1, TPoint3D *a2, int a3, int a4, int a5, int a6) {
+  int ret = 1;
+  return ret;
+}
+//-------------------------------------------------------------------------------------------------
+//001F4680
+float XMATH_ClipPathBounds(TPoint *, TPoint *, int, int, int, int) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------

+ 471 - 0
src/jni/XMATH.h

@@ -0,0 +1,471 @@
+//XMATH - [2020-06-22 11:41:46]
+#ifndef _XMATH_H_
+#define _XMATH_H_
+
+#include "CFTTVector32.h"
+#include "CFTTMatrix32.h"
+
+/*
+001F2368 XMATH_ArcTan(int,int)
+001F2400 XMATH_RaySphereTest(TPoint3D *,int,TPoint3D *,TPoint3D *,int)
+001F248E XMATH_DotProduct(TPoint3D *,TPoint3D *)
+001F24A8 XMATH_TendAngle(int,int)
+001F24F4 XMATH_CalcSqrt(uint)
+001F251C XMATH_CalcSqrt(uint64_t)
+001F2586 XMATH_Normalize(TPoint3D *,int)
+001F25F2 XMATH_Normalize(TPoint *,int)
+001F2644 XMATH_Normalize(TPoint3D,int)
+001F26B0 XMATH_Normalize2D(TPoint3D,int)
+001F2700 XMATH_Normalize(TPoint,int)
+001F2756 XMATH_Normalize(TPointF *,float)
+001F27AE XMATH_Cross(TPoint3D *,TPoint3D *,TPoint3D *)
+001F2802 XMATH_Subtract(TPoint3D *,TPoint3D *,TPoint3D *)
+001F2824 XMATH_Add(TPoint3D *,TPoint3D *,TPoint3D *)
+001F2842 XMATH_Scale(TPoint3D *,int,TPoint3D *)
+001F2856 XMATH_IsDotPositive(TPoint *,TPoint *)
+001F2874 XMATH_IsSimilarDirection(TPoint *,TPoint *)
+001F28B6 XMATH_ClipVectorX(TPoint *,TPoint *,int)
+001F2904 XMATH_ClipVectorY(TPoint *,TPoint *,int)
+001F2952 XMATH_ClipVectorX(TPoint3D *,TPoint3D *,int)
+001F29CA XMATH_ClipVectorY(TPoint3D *,TPoint3D *,int)
+001F2A44 XMATH_LineIntersect(TPoint const*,TPoint const*,TPoint const*,TPoint*,int *)
+001F2B3C XMATH_LineIntersect3D(TPoint3D const*,TPoint3D const*,TPoint3D const*,TPoint3D*,int *)
+001F2CA4 XMATH_DistPointToLineF(TPointF3D,TPointF3D,TPointF3D,TPointF3D*,float *)
+001F2D80 XMATH_Mag3D(TPointF3D const*)
+001F2DC2 XMATH_LineLineIntersect(TPoint const*,TPoint const*,TPoint const*,TPoint const*,TPoint*)
+001F2F20 XMATH_LineLineDistance(TPoint3D const*,TPoint3D const*,TPoint3D const*,TPoint3D const*,int *,int *)
+001F322C XMATH_Clamp64(long long,long long,long long)
+001F3274 XMATH_Mag3D(TPoint3D const*)
+001F328A XMATH_Mag(TPoint const*)
+001F329E XMATH_Mag(TPointF const*)
+001F32D8 XMATH_Mag2D(TPoint3D const*)
+001F32DC XMATH_Project(int,int)
+001F3398 XMATH_PointProject(TPoint,int,int)
+001F33CE XMATH_PointProject(TPoint3D,int,int)
+001F3404 XMATH_Squeeze(TPoint3D *,TPoint3D *,int)
+001F3490 XMATH_Distance3D(TPoint3D const*,TPoint3D const*)
+001F34BA XMATH_BlendAngle(int,int,int)
+001F3500 XMATH_InterpolateClampColor(float,float,float,uint,uint)
+001F363C XMATH_InterpolateClampFloat(float,float,float,float,float)
+001F36B0 XMATH_BitSum(uint)
+001F36CA XMATH_QuatNormalize(TQuat *,TQuat *)
+001F372C XMATH_QuatMultiply(TQuat *,TQuat *,TQuat *)
+001F37C8 XMATH_EulerToQuat(int,int,int,TQuat *)
+001F38B0 XMATH_SetQuatIdentity(TQuat *)
+001F38D0 XMATH_RotatePoint(TPoint *,int)
+001F3934 XMATH_QuatRotateEuler(TQuat *,TPoint3D *)
+001F396E XMATH_QuatSlerp(TQuat *,TQuat *,TQuat *,int)
+001F3B66 XMATH_QuatBlend(TQuat *,TQuat *,TQuat *,int)
+001F3B7A XMATH_EaseInOut(int,int,int)
+001F3B9E XMATH_Power(int,int)
+001F3BAE XMATH_ClampAngle(int,int,int)
+001F3BD4 XMATH_IsPowerOfTwo(int)
+001F3BE8 XMATH_Clamp(int,int,int)
+001F3BF8 XMATH_Clampu8(uchar,uchar,uchar)
+001F3C08 XMATH_ClampFloat(float,float,float)
+001F3C36 XMATH_WrapFloat(float,float,float)
+001F3C80 XMATH_Wrap(int,int,int)
+001F3C98 XMATH_WrapLimit(int,int,int)
+001F3CAA XMATH_MagSq(TPoint const*)
+001F3CC8 XMATH_ClampMag(TPoint *,int)
+001F3CF2 XMATH_ClampMagMin(TPoint *,int)
+001F3D12 XMATH_DistanceSq(TPoint const*,TPoint const*)
+001F3D38 XMATH_Distance3DSq(TPoint3D const*,TPoint3D const*)
+001F3D78 XMATH_Distance(TPoint const*,TPoint const*)
+001F3D94 XMATH_Distance3DF(TPointF3D *,TPointF3D *)
+001F3DD4 XMATH_Interpolate(int,int,int,int,int)
+001F3DF0 XMATH_InterpAngle(int,int,int,int,int)
+001F3E18 XMATH_InterpolateFloat(float,float,float,float,float)
+001F3E4A XMATH_InterpolateClamp(int,int,int,int,int)
+001F3E92 XMATH_SinInterpolateClamp(int,int,int,int,int)
+001F3EB8 XMATH_SinInterpolateClampFloat(float,float,float,float,float)
+001F3F20 XMATH_InterpolatePos(TPoint *,int,int,int,TPoint,TPoint)
+001F3F74 XMATH_InterpolatePos3D(TPoint3D *,int,int,int,TPoint3D,TPoint3D)
+001F3FFC XMATH_SinInterpolatePos3D(TPoint3D *,int,int,int,TPoint3D,TPoint3D)
+001F4084 XMATH_SetupRectI(TRectI *,int,int,int,int)
+001F408E XMATH_SetupRect(TRect *,float,float,float,float)
+001F409C XMATH_WrapToBounds(int,int,int)
+001F40AE XMATH_RectOverlap(TRect,float,float,float,float)
+001F4138 XMATH_RectOverlap(TRect,TRect)
+001F41D4 XMATH_Dot_F(TPointF3D *,TPointF3D *)
+001F41FE XMATH_DotProduct(TPoint *,TPoint *)
+001F4214 XMATH_RGBDiff(uint,uint)
+001F424C XMATH_MaxF(float,float)
+001F4268 XMATH_MinF(float,float)
+001F4284 XMATH_IsCrossingLine(int,int,int)
+001F42AA XMATH_IsCrossingLine2D(TPoint,TPoint,TPoint,TPoint)
+001F432C XMATH_IsCrossingLineOneWay(int,int,int,int)
+001F4344 XMATH_IsStayingOneSideOf(int,int,int,int)
+001F435C XMATH_IsStayingBetween(int,int,int,int)
+001F4376 XMATH_IsPwrTwo(int)
+001F438A XMATH_GetCurvePosF(TPointF,TPointF,TPointF,float)
+001F43E0 XMATH_CreateRandomIndexArray(int *,int)
+001F4416 XMATH_ShuffleArray(ushort *,int)
+001F4440 XMATH_CountNumDigits(int)
+001F445C XMATH_RoundToNearest(int,int)
+001F4476 XMATH_RoundFloatToNearestInt(float)
+001F449E XMATH_CatmullRom(CFTTVector32 const&,CFTTVector32 const&,CFTTVector32 const&,CFTTVector32 const&,float)
+001F459E XMATH_StringToYardInt(char const*)
+001F4638 XMATH_ClipPathBounds(TPoint3D *,TPoint3D *,int,int,int,int)
+001F4680 XMATH_ClipPathBounds(TPoint *,TPoint *,int,int,int,int)
+*/
+
+struct TRect {
+  float fx_0;
+  float fy_4;
+  float fWidth_8;
+  float fHeight_C;
+
+  TRect &operator=(const TRect &other) {
+    memcpy(this, &other, sizeof(TRect));
+    //fx_0 = o.fx_0;
+    //fy_4 = o.fy_4;
+    //fWidth_8 = o.fWidth_8;
+    //fHeight_C = o.fHeight_C;
+    return *this;
+  };
+};
+
+struct TRectI {
+  int ix_0;
+  int iy_4;
+  int iWidth_8;
+  int iHeight_C;
+
+  TRectI &operator=(const TRectI &o) {
+    ix_0 = o.ix_0;
+    iy_4 = o.iy_4;
+    iWidth_8 = o.iWidth_8;
+    iHeight_C = o.iHeight_C;
+    return *this;
+  };
+};
+
+//struct TQuat {
+// int field_0;
+// int field_4;
+// int field_8;
+// int field_C;
+//};
+
+struct TQuat {
+  int d1_0;
+  int d2_4;
+  int d3_8;
+  int d4_C;
+};
+
+//001F2368
+ushort XMATH_ArcTan(int, int);
+
+//001F2400
+float XMATH_RaySphereTest(TPoint3D *, int, TPoint3D *, TPoint3D *, int);
+
+//001F248E
+float XMATH_DotProduct(TPoint3D *, TPoint3D *);
+
+//001F24A8
+float XMATH_TendAngle(int, int);
+
+//001F24F4
+uint XMATH_CalcSqrt(uint);
+
+//001F251C
+uint64_t XMATH_CalcSqrt(uint64_t d);
+
+//001F2586
+void XMATH_Normalize(TPoint3D *, int);
+
+//001F25F2
+void XMATH_Normalize(TPoint *, int);
+
+//001F2644
+TPoint3D XMATH_Normalize(TPoint3D, int);
+
+//001F26B0
+TPoint3D XMATH_Normalize2D(TPoint3D, int);
+
+//001F2700
+TPoint XMATH_Normalize(TPoint, int);
+
+//001F2756
+float XMATH_Normalize(TPointF *, float);
+
+//001F27AE
+float XMATH_Cross(TPoint3D *, TPoint3D *, TPoint3D *);
+
+//001F2802
+float XMATH_Subtract(TPoint3D *, TPoint3D *, TPoint3D *);
+
+//001F2824
+float XMATH_Add(TPoint3D *, TPoint3D *, TPoint3D *);
+
+//001F2842
+float XMATH_Scale(TPoint3D *, int, TPoint3D *);
+
+//001F2856
+float XMATH_IsDotPositive(TPoint *, TPoint *);
+
+//001F2874
+float XMATH_IsSimilarDirection(TPoint *, TPoint *);
+
+//001F28B6
+float XMATH_ClipVectorX(TPoint *, TPoint *, int);
+
+//001F2904
+void XMATH_ClipVectorY(TPoint *, TPoint *, int);
+
+//001F2952
+void XMATH_ClipVectorX(TPoint3D *, TPoint3D *, int);
+
+//001F29CA
+void XMATH_ClipVectorY(TPoint3D *, TPoint3D *, int);
+
+//001F2A44
+void XMATH_LineIntersect(TPoint const *, TPoint const *, TPoint const *, TPoint *, int *);
+
+//001F2B3C
+float XMATH_LineIntersect3D(TPoint3D const *, TPoint3D const *, TPoint3D const *, TPoint3D *, int *);
+
+//001F2CA4
+float XMATH_DistPointToLineF(TPointF3D, TPointF3D, TPointF3D, TPointF3D *, float *);
+
+//001F2D80
+float XMATH_Mag3D(TPointF3D const *);
+
+//001F2DC2
+float XMATH_LineLineIntersect(TPoint const *, TPoint const *, TPoint const *, TPoint const *, TPoint *);
+
+//001F2F20
+int XMATH_LineLineDistance(TPoint3D const *, TPoint3D const *, TPoint3D const *, TPoint3D const *, int *, int *);
+
+//001F322C
+float XMATH_Clamp64(long long, long long, long long);
+
+//001F3274
+uint32_t XMATH_Mag3D(TPoint3D const *);
+
+//001F328A
+uint64_t XMATH_Mag(TPoint const *);
+
+//001F329E
+float XMATH_Mag(TPointF const *);
+
+//001F32D8
+uint64_t XMATH_Mag2D(TPoint3D const *);
+
+//001F32DC
+TPoint XMATH_Project(int, int);
+
+//001F3398
+TPoint XMATH_PointProject(TPoint, int, int);
+
+//001F33CE
+TPoint3D XMATH_PointProject(TPoint3D, int, int);
+
+//001F3404
+float XMATH_Squeeze(TPoint3D *, TPoint3D *, int);
+
+//001F3490
+uint32_t XMATH_Distance3D(TPoint3D const *, TPoint3D const *);
+
+//001F34BA
+float XMATH_BlendAngle(int, int, int);
+
+//001F3500
+float XMATH_InterpolateClampColor(float, float, float, uint, uint);
+
+//001F363C
+float XMATH_InterpolateClampFloat(float, float, float, float, float);
+
+//001F36B0
+uint XMATH_BitSum(uint);
+
+//001F36CA
+void XMATH_QuatNormalize(TQuat *, TQuat *);
+
+//001F372C
+void XMATH_QuatMultiply(TQuat *, TQuat *, TQuat *);
+
+//001F37C8
+void XMATH_EulerToQuat(int, int, int, TQuat *);
+
+//001F38B0
+float XMATH_SetQuatIdentity(TQuat *);
+
+//001F38D0
+TPoint XMATH_RotatePoint(TPoint *, int);
+
+//001F3934
+void XMATH_QuatRotateEuler(TQuat *, TPoint3D *);
+
+//001F396E
+void XMATH_QuatSlerp(TQuat *, TQuat *, TQuat *, int);
+
+//001F3B66
+void XMATH_QuatBlend(TQuat *, TQuat *, TQuat *, int);
+
+//001F3B7A
+float XMATH_EaseInOut(int, int, int);
+
+//001F3B9E
+float XMATH_Power(int, int);
+
+//001F3BAE
+float XMATH_ClampAngle(int, int, int);
+
+//001F3BD4
+float XMATH_IsPowerOfTwo(int);
+
+//001F3BE8
+int XMATH_Clamp(int, int, int);
+
+//001F3BF8
+float XMATH_Clampu8(uchar, uchar, uchar);
+
+//001F3C08
+float XMATH_ClampFloat(float, float, float);
+
+//001F3C36
+float XMATH_WrapFloat(float, float, float);
+
+//001F3C80
+float XMATH_Wrap(int, int, int);
+
+//001F3C98
+float XMATH_WrapLimit(int, int, int);
+
+//001F3CAA
+int XMATH_MagSq(TPoint const *);
+
+//001F3CC8
+float XMATH_ClampMag(TPoint *, int);
+
+//001F3CF2
+float XMATH_ClampMagMin(TPoint *, int);
+
+//001F3D12
+int XMATH_DistanceSq(TPoint const *, TPoint const *);
+
+//001F3D38
+int XMATH_Distance3DSq(TPoint3D const *, TPoint3D const *);
+
+//001F3D78
+uint64_t XMATH_Distance(TPoint const *, TPoint const *);
+
+//001F3D94
+float XMATH_Distance3DF(TPointF3D *, TPointF3D *);
+
+//001F3DD4
+float XMATH_Interpolate(int, int, int, int, int);
+
+//001F3DF0
+float XMATH_InterpAngle(int, int, int, int, int);
+
+//001F3E18
+float XMATH_InterpolateFloat(float, float, float, float, float);
+
+//001F3E4A
+int XMATH_InterpolateClamp(int, int, int, int, int);
+
+//001F3E92
+int XMATH_SinInterpolateClamp(int, int, int, int, int);
+
+//001F3EB8
+float XMATH_SinInterpolateClampFloat(float, float, float, float, float);
+
+//001F3F20
+float XMATH_InterpolatePos(TPoint *, int, int, int, TPoint, TPoint);
+
+//001F3F74
+void XMATH_InterpolatePos3D(TPoint3D *, int, int, int, TPoint3D, TPoint3D);
+
+//001F3FFC
+void XMATH_SinInterpolatePos3D(TPoint3D *, int, int, int, TPoint3D, TPoint3D);
+
+//001F4084
+float XMATH_SetupRectI(TRectI *, int, int, int, int);
+
+//001F408E
+void XMATH_SetupRect(TRect *, float, float, float, float);
+
+//001F409C
+float XMATH_WrapToBounds(int, int, int);
+
+//001F40AE
+float XMATH_RectOverlap(TRect, float, float, float, float);
+
+//001F4138
+float XMATH_RectOverlap(TRect, TRect);
+
+//001F41D4
+float XMATH_Dot_F(TPointF3D *, TPointF3D *);
+
+//001F41FE
+float XMATH_DotProduct(TPoint *, TPoint *);
+
+//001F4214
+uint XMATH_RGBDiff(uint, uint);
+
+//001F424C
+float XMATH_MaxF(float, float);
+
+//001F4268
+float XMATH_MinF(float, float);
+
+//001F4284
+bool XMATH_IsCrossingLine(int, int, int);
+
+//001F42AA
+float XMATH_IsCrossingLine2D(TPoint, TPoint, TPoint, TPoint);
+
+//001F432C
+float XMATH_IsCrossingLineOneWay(int, int, int, int);
+
+//001F4344
+float XMATH_IsStayingOneSideOf(int, int, int, int);
+
+//001F435C
+float XMATH_IsStayingBetween(int, int, int, int);
+
+//001F4376
+float XMATH_IsPwrTwo(int);
+
+//001F438A
+TPointF XMATH_GetCurvePosF(TPointF pf1, TPointF pf2, TPointF pf3, float f4);
+
+//001F43E0
+float XMATH_CreateRandomIndexArray(int *, int);
+
+//001F4416
+float XMATH_ShuffleArray(ushort *, int);
+
+//001F4440
+float XMATH_CountNumDigits(int);
+
+//001F445C
+float XMATH_RoundToNearest(int, int);
+
+//001F4476
+float XMATH_RoundFloatToNearestInt(float);
+
+//001F449E CFTTVector32 const&,CFTTVector32 const&,CFTTVector32 const&,CFTTVector32 const&,float
+CFTTVector32 XMATH_CatmullRom(CFTTVector32 const &v1,
+                              CFTTVector32 const &v2,
+                              CFTTVector32 const &v3,
+                              CFTTVector32 const &v4,
+                              float f5);
+
+//001F459E
+float XMATH_StringToYardInt(char const *);
+
+//001F4638
+int XMATH_ClipPathBounds(TPoint3D *, TPoint3D *, int, int, int, int);
+
+//001F4680
+float XMATH_ClipPathBounds(TPoint *, TPoint *, int, int, int, int);
+
+int xsin(int a1);
+int xcos(int a1);
+
+#endif  //_XMATH_H_

+ 827 - 0
src/jni/XMATH_var.h

@@ -0,0 +1,827 @@
+const ushort word_300924[] = {0, 1, 3, 4, 5, 6, 8, 9, 0xA, 0xB, 0xD, 0xE, 0xF, 0x11,
+                              0x12, 0x13, 0x14, 0x16, 0x17, 0x18, 0x19, 0x1B, 0x1C,
+                              0x1D, 0x1F, 0x20, 0x21, 0x22, 0x24, 0x25, 0x26, 0x27,
+                              0x29, 0x2A, 0x2B, 0x2D, 0x2E, 0x2F, 0x30, 0x32, 0x33,
+                              0x34, 0x35, 0x37, 0x38, 0x39, 0x3B, 0x3C, 0x3D, 0x3E,
+                              0x40, 0x41, 0x42, 0x43, 0x45, 0x46, 0x47, 0x49, 0x4A,
+                              0x4B, 0x4C, 0x4E, 0x4F, 0x50, 0x51, 0x53, 0x54, 0x55,
+                              0x57, 0x58, 0x59, 0x5A, 0x5C, 0x5D, 0x5E, 0x5F, 0x61,
+                              0x62, 0x63, 0x65, 0x66, 0x67, 0x68, 0x6A, 0x6B, 0x6C,
+                              0x6D, 0x6F, 0x70, 0x71, 0x73, 0x74, 0x75, 0x76, 0x78,
+                              0x79, 0x7A, 0x7B, 0x7D, 0x7E, 0x7F, 0x80, 0x82, 0x83,
+                              0x84, 0x86, 0x87, 0x88, 0x89, 0x8B, 0x8C, 0x8D, 0x8E,
+                              0x90, 0x91, 0x92, 0x94, 0x95, 0x96, 0x97, 0x99, 0x9A,
+                              0x9B, 0x9C, 0x9E, 0x9F, 0xA0, 0xA1, 0xA3, 0xA4, 0xA5,
+                              0xA7, 0xA8, 0xA9, 0xAA, 0xAC, 0xAD, 0xAE, 0xAF, 0xB1,
+                              0xB2, 0xB3, 0xB5, 0xB6, 0xB7, 0xB8, 0xBA, 0xBB, 0xBC,
+                              0xBD, 0xBF, 0xC0, 0xC1, 0xC2, 0xC4, 0xC5, 0xC6, 0xC8,
+                              0xC9, 0xCA, 0xCB, 0xCD, 0xCE, 0xCF, 0xD0, 0xD2, 0xD3,
+                              0xD4, 0xD5, 0xD7, 0xD8, 0xD9, 0xDA, 0xDC, 0xDD, 0xDE,
+                              0xE0, 0xE1, 0xE2, 0xE3, 0xE5, 0xE6, 0xE7, 0xE8, 0xEA,
+                              0xEB, 0xEC, 0xED, 0xEF, 0xF0, 0xF1, 0xF2, 0xF4, 0xF5,
+                              0xF6, 0xF8, 0xF9, 0xFA, 0xFB, 0xFD, 0xFE, 0xFF, 0x100,
+                              0x102, 0x103, 0x104, 0x105, 0x107, 0x108, 0x109, 0x10A,
+                              0x10C, 0x10D, 0x10E, 0x10F, 0x111, 0x112, 0x113, 0x115,
+                              0x116, 0x117, 0x118, 0x11A, 0x11B, 0x11C, 0x11D, 0x11F,
+                              0x120, 0x121, 0x122, 0x124, 0x125, 0x126, 0x127, 0x129,
+                              0x12A, 0x12B, 0x12C, 0x12E, 0x12F, 0x130, 0x131, 0x133,
+                              0x134, 0x135, 0x136, 0x138, 0x139, 0x13A, 0x13B, 0x13D,
+                              0x13E, 0x13F, 0x141, 0x142, 0x143, 0x144, 0x146, 0x147,
+                              0x148, 0x149, 0x14B, 0x14C, 0x14D, 0x14E, 0x150, 0x151,
+                              0x152, 0x153, 0x155, 0x156, 0x157, 0x158, 0x15A, 0x15B,
+                              0x15C, 0x15D, 0x15F, 0x160, 0x161, 0x162, 0x164, 0x165,
+                              0x166, 0x167, 0x169, 0x16A, 0x16B, 0x16C, 0x16E, 0x16F,
+                              0x170, 0x171, 0x173, 0x174, 0x175, 0x176, 0x178, 0x179,
+                              0x17A, 0x17B, 0x17D, 0x17E, 0x17F, 0x180, 0x182, 0x183,
+                              0x184, 0x185, 0x186, 0x188, 0x189, 0x18A, 0x18B, 0x18D,
+                              0x18E, 0x18F, 0x190, 0x192, 0x193, 0x194, 0x195, 0x197,
+                              0x198, 0x199, 0x19A, 0x19C, 0x19D, 0x19E, 0x19F, 0x1A1,
+                              0x1A2, 0x1A3, 0x1A4, 0x1A6, 0x1A7, 0x1A8, 0x1A9, 0x1AB,
+                              0x1AC, 0x1AD, 0x1AE, 0x1AF, 0x1B1, 0x1B2, 0x1B3, 0x1B4,
+                              0x1B6, 0x1B7, 0x1B8, 0x1B9, 0x1BB, 0x1BC, 0x1BD, 0x1BE,
+                              0x1C0, 0x1C1, 0x1C2, 0x1C3, 0x1C4, 0x1C6, 0x1C7, 0x1C8,
+                              0x1C9, 0x1CB, 0x1CC, 0x1CD, 0x1CE, 0x1D0, 0x1D1, 0x1D2,
+                              0x1D3, 0x1D5, 0x1D6, 0x1D7, 0x1D8, 0x1D9, 0x1DB, 0x1DC,
+                              0x1DD, 0x1DE, 0x1E0, 0x1E1, 0x1E2, 0x1E3, 0x1E5, 0x1E6,
+                              0x1E7, 0x1E8, 0x1E9, 0x1EB, 0x1EC, 0x1ED, 0x1EE, 0x1F0,
+                              0x1F1, 0x1F2, 0x1F3, 0x1F5, 0x1F6, 0x1F7, 0x1F8, 0x1F9,
+                              0x1FB, 0x1FC, 0x1FD, 0x1FE, 0x200, 0x201, 0x202, 0x203,
+                              0x204, 0x206, 0x207, 0x208, 0x209, 0x20B, 0x20C, 0x20D,
+                              0x20E, 0x20F, 0x211, 0x212, 0x213, 0x214, 0x216, 0x217,
+                              0x218, 0x219, 0x21A, 0x21C, 0x21D, 0x21E, 0x21F, 0x221,
+                              0x222, 0x223, 0x224, 0x225, 0x227, 0x228, 0x229, 0x22A,
+                              0x22B, 0x22D, 0x22E, 0x22F, 0x230, 0x232, 0x233, 0x234,
+                              0x235, 0x236, 0x238, 0x239, 0x23A, 0x23B, 0x23C, 0x23E,
+                              0x23F, 0x240, 0x241, 0x243, 0x244, 0x245, 0x246, 0x247,
+                              0x249, 0x24A, 0x24B, 0x24C, 0x24D, 0x24F, 0x250, 0x251,
+                              0x252, 0x253, 0x255, 0x256, 0x257, 0x258, 0x25A, 0x25B,
+                              0x25C, 0x25D, 0x25E, 0x260, 0x261, 0x262, 0x263, 0x264,
+                              0x266, 0x267, 0x268, 0x269, 0x26A, 0x26C, 0x26D, 0x26E,
+                              0x26F, 0x270, 0x272, 0x273, 0x274, 0x275, 0x276, 0x278,
+                              0x279, 0x27A, 0x27B, 0x27C, 0x27E, 0x27F, 0x280, 0x281,
+                              0x282, 0x284, 0x285, 0x286, 0x287, 0x288, 0x28A, 0x28B,
+                              0x28C, 0x28D, 0x28E, 0x290, 0x291, 0x292, 0x293, 0x294,
+                              0x296, 0x297, 0x298, 0x299, 0x29A, 0x29B, 0x29D, 0x29E,
+                              0x29F, 0x2A0, 0x2A1, 0x2A3, 0x2A4, 0x2A5, 0x2A6, 0x2A7,
+                              0x2A9, 0x2AA, 0x2AB, 0x2AC, 0x2AD, 0x2AF, 0x2B0, 0x2B1,
+                              0x2B2, 0x2B3, 0x2B4, 0x2B6, 0x2B7, 0x2B8, 0x2B9, 0x2BA,
+                              0x2BC, 0x2BD, 0x2BE, 0x2BF, 0x2C0, 0x2C1, 0x2C3, 0x2C4,
+                              0x2C5, 0x2C6, 0x2C7, 0x2C9, 0x2CA, 0x2CB, 0x2CC, 0x2CD,
+                              0x2CE, 0x2D0, 0x2D1, 0x2D2, 0x2D3, 0x2D4, 0x2D6, 0x2D7,
+                              0x2D8, 0x2D9, 0x2DA, 0x2DB, 0x2DD, 0x2DE, 0x2DF, 0x2E0,
+                              0x2E1, 0x2E2, 0x2E4, 0x2E5, 0x2E6, 0x2E7, 0x2E8, 0x2E9,
+                              0x2EB, 0x2EC, 0x2ED, 0x2EE, 0x2EF, 0x2F1, 0x2F2, 0x2F3,
+                              0x2F4, 0x2F5, 0x2F6, 0x2F8, 0x2F9, 0x2FA, 0x2FB, 0x2FC,
+                              0x2FD, 0x2FF, 0x300, 0x301, 0x302, 0x303, 0x304, 0x306,
+                              0x307, 0x308, 0x309, 0x30A, 0x30B, 0x30D, 0x30E, 0x30F,
+                              0x310, 0x311, 0x312, 0x313, 0x315, 0x316, 0x317, 0x318,
+                              0x319, 0x31A, 0x31C, 0x31D, 0x31E, 0x31F, 0x320, 0x321,
+                              0x323, 0x324, 0x325, 0x326, 0x327, 0x328, 0x329, 0x32B,
+                              0x32C, 0x32D, 0x32E, 0x32F, 0x330, 0x332, 0x333, 0x334,
+                              0x335, 0x336, 0x337, 0x338, 0x33A, 0x33B, 0x33C, 0x33D,
+                              0x33E, 0x33F, 0x340, 0x342, 0x343, 0x344, 0x345, 0x346,
+                              0x347, 0x349, 0x34A, 0x34B, 0x34C, 0x34D, 0x34E, 0x34F,
+                              0x351, 0x352, 0x353, 0x354, 0x355, 0x356, 0x357, 0x359,
+                              0x35A, 0x35B, 0x35C, 0x35D, 0x35E, 0x35F, 0x361, 0x362,
+                              0x363, 0x364, 0x365, 0x366, 0x367, 0x368, 0x36A, 0x36B,
+                              0x36C, 0x36D, 0x36E, 0x36F, 0x370, 0x372, 0x373, 0x374,
+                              0x375, 0x376, 0x377, 0x378, 0x379, 0x37B, 0x37C, 0x37D,
+                              0x37E, 0x37F, 0x380, 0x381, 0x382, 0x384, 0x385, 0x386,
+                              0x387, 0x388, 0x389, 0x38A, 0x38C, 0x38D, 0x38E, 0x38F,
+                              0x390, 0x391, 0x392, 0x393, 0x395, 0x396, 0x397, 0x398,
+                              0x399, 0x39A, 0x39B, 0x39C, 0x39D, 0x39F, 0x3A0, 0x3A1,
+                              0x3A2, 0x3A3, 0x3A4, 0x3A5, 0x3A6, 0x3A8, 0x3A9, 0x3AA,
+                              0x3AB, 0x3AC, 0x3AD, 0x3AE, 0x3AF, 0x3B0, 0x3B2, 0x3B3,
+                              0x3B4, 0x3B5, 0x3B6, 0x3B7, 0x3B8, 0x3B9, 0x3BA, 0x3BC,
+                              0x3BD, 0x3BE, 0x3BF, 0x3C0, 0x3C1, 0x3C2, 0x3C3, 0x3C4,
+                              0x3C6, 0x3C7, 0x3C8, 0x3C9, 0x3CA, 0x3CB, 0x3CC, 0x3CD,
+                              0x3CE, 0x3CF, 0x3D1, 0x3D2, 0x3D3, 0x3D4, 0x3D5, 0x3D6,
+                              0x3D7, 0x3D8, 0x3D9, 0x3DA, 0x3DC, 0x3DD, 0x3DE, 0x3DF,
+                              0x3E0, 0x3E1, 0x3E2, 0x3E3, 0x3E4, 0x3E5, 0x3E7, 0x3E8,
+                              0x3E9, 0x3EA, 0x3EB, 0x3EC, 0x3ED, 0x3EE, 0x3EF, 0x3F0,
+                              0x3F2, 0x3F3, 0x3F4, 0x3F5, 0x3F6, 0x3F7, 0x3F8, 0x3F9,
+                              0x3FA, 0x3FB, 0x3FC, 0x3FD, 0x3FF, 0x400, 0x401, 0x402,
+                              0x403, 0x404, 0x405, 0x406, 0x407, 0x408, 0x409, 0x40B,
+                              0x40C, 0x40D, 0x40E, 0x40F, 0x410, 0x411, 0x412, 0x413,
+                              0x414, 0x415, 0x416, 0x417, 0x419, 0x41A, 0x41B, 0x41C,
+                              0x41D, 0x41E, 0x41F, 0x420, 0x421, 0x422, 0x423, 0x424,
+                              0x425, 0x427, 0x428, 0x429, 0x42A, 0x42B, 0x42C, 0x42D,
+                              0x42E, 0x42F, 0x430, 0x431, 0x432, 0x433, 0x434, 0x436,
+                              0x437, 0x438, 0x439, 0x43A, 0x43B, 0x43C, 0x43D, 0x43E,
+                              0x43F, 0x440, 0x441, 0x442, 0x443, 0x444, 0x446, 0x447,
+                              0x448, 0x449, 0x44A, 0x44B, 0x44C, 0x44D, 0x44E, 0x44F,
+                              0x450, 0x451, 0x452, 0x453, 0x454, 0x455, 0x456, 0x458,
+                              0x459, 0x45A, 0x45B, 0x45C, 0x45D, 0x45E, 0x45F, 0x460,
+                              0x461, 0x462, 0x463, 0x464, 0x465, 0x466, 0x467, 0x468,
+                              0x469, 0x46A, 0x46B, 0x46D, 0x46E, 0x46F, 0x470, 0x471,
+                              0x472, 0x473, 0x474, 0x475, 0x476, 0x477, 0x478, 0x479,
+                              0x47A, 0x47B, 0x47C, 0x47D, 0x47E, 0x47F, 0x480, 0x481,
+                              0x482, 0x484, 0x485, 0x486, 0x487, 0x488, 0x489, 0x48A,
+                              0x48B, 0x48C, 0x48D, 0x48E, 0x48F, 0x490, 0x491, 0x492,
+                              0x493, 0x494, 0x495, 0x496, 0x497, 0x498, 0x499, 0x49A,
+                              0x49B, 0x49C, 0x49D, 0x49E, 0x49F, 0x4A0, 0x4A1, 0x4A2,
+                              0x4A4, 0x4A5, 0x4A6, 0x4A7, 0x4A8, 0x4A9, 0x4AA, 0x4AB,
+                              0x4AC, 0x4AD, 0x4AE, 0x4AF, 0x4B0, 0x4B1, 0x4B2, 0x4B3,
+                              0x4B4, 0x4B5, 0x4B6, 0x4B7, 0x4B8, 0x4B9, 0x4BA, 0x4BB,
+                              0x4BC, 0x4BD, 0x4BE, 0x4BF, 0x4C0, 0x4C1, 0x4C2, 0x4C3,
+                              0x4C4, 0x4C5, 0x4C6, 0x4C7, 0x4C8, 0x4C9, 0x4CA, 0x4CB,
+                              0x4CC, 0x4CD, 0x4CE, 0x4CF, 0x4D0, 0x4D1, 0x4D2, 0x4D3,
+                              0x4D4, 0x4D5, 0x4D6, 0x4D7, 0x4D8, 0x4D9, 0x4DA, 0x4DB,
+                              0x4DC, 0x4DD, 0x4DE, 0x4DF, 0x4E0, 0x4E1, 0x4E2, 0x4E3,
+                              0x4E4, 0x4E5, 0x4E6, 0x4E7, 0x4E8, 0x4E9, 0x4EA, 0x4EB,
+                              0x4EC, 0x4ED, 0x4EE, 0x4EF, 0x4F0, 0x4F1, 0x4F2, 0x4F3,
+                              0x4F4, 0x4F5, 0x4F6, 0x4F7, 0x4F8, 0x4F9, 0x4FA, 0x4FB,
+                              0x4FC, 0x4FD, 0x4FE, 0x4FF, 0x500, 0x501, 0x502, 0x503,
+                              0x504, 0x505, 0x506, 0x507, 0x508, 0x509, 0x50A, 0x50B,
+                              0x50C, 0x50D, 0x50E, 0x50F, 0x510, 0x511, 0x512, 0x513,
+                              0x514, 0x515, 0x516, 0x517, 0x518, 0x519, 0x51A, 0x51B,
+                              0x51C, 0x51D, 0x51E, 0x51F, 0x520, 0x521, 0x522, 0x523,
+                              0x524, 0x525, 0x526, 0x527, 0x528, 0x529, 0x52A, 0x52B,
+                              0x52B, 0x52C, 0x52D, 0x52E, 0x52F, 0x530, 0x531, 0x532,
+                              0x533, 0x534, 0x535, 0x536, 0x537, 0x538, 0x539, 0x53A,
+                              0x53B, 0x53C, 0x53D, 0x53E, 0x53F, 0x540, 0x541, 0x542,
+                              0x543, 0x544, 0x545, 0x546, 0x547, 0x548, 0x548, 0x549,
+                              0x54A, 0x54B, 0x54C, 0x54D, 0x54E, 0x54F, 0x550, 0x551,
+                              0x552, 0x553, 0x554, 0x555, 0x556, 0x557, 0x558, 0x559,
+                              0x55A, 0x55B, 0x55C, 0x55D, 0x55E, 0x55E, 0x55F, 0x560,
+                              0x561, 0x562, 0x563, 0x564, 0x565, 0x566, 0x567, 0x568,
+                              0x569, 0x56A, 0x56B, 0x56C, 0x56D, 0x56E, 0x56F, 0x570,
+                              0x570, 0x571, 0x572, 0x573, 0x574, 0x575, 0x576, 0x577,
+                              0x578, 0x579, 0x57A, 0x57B, 0x57C, 0x57D, 0x57E, 0x57F,
+                              0x580, 0x580, 0x581, 0x582, 0x583, 0x584, 0x585, 0x586,
+                              0x587, 0x588, 0x589, 0x58A, 0x58B, 0x58C, 0x58D, 0x58E,
+                              0x58E, 0x58F, 0x590, 0x591, 0x592, 0x593, 0x594, 0x595,
+                              0x596, 0x597, 0x598, 0x599, 0x59A, 0x59B, 0x59B, 0x59C,
+                              0x59D, 0x59E, 0x59F, 0x5A0, 0x5A1, 0x5A2, 0x5A3, 0x5A4,
+                              0x5A5, 0x5A6, 0x5A7, 0x5A7, 0x5A8, 0x5A9, 0x5AA, 0x5AB,
+                              0x5AC, 0x5AD, 0x5AE, 0x5AF, 0x5B0, 0x5B1, 0x5B2, 0x5B2,
+                              0x5B3, 0x5B4, 0x5B5, 0x5B6, 0x5B7, 0x5B8, 0x5B9, 0x5BA,
+                              0x5BB, 0x5BC, 0x5BC, 0x5BD, 0x5BE, 0x5BF, 0x5C0, 0x5C1,
+                              0x5C2, 0x5C3, 0x5C4, 0x5C5, 0x5C6, 0x5C6, 0x5C7, 0x5C8,
+                              0x5C9, 0x5CA, 0x5CB, 0x5CC, 0x5CD, 0x5CE, 0x5CF, 0x5CF,
+                              0x5D0, 0x5D1, 0x5D2, 0x5D3, 0x5D4, 0x5D5, 0x5D6, 0x5D7,
+                              0x5D8, 0x5D8, 0x5D9, 0x5DA, 0x5DB, 0x5DC, 0x5DD, 0x5DE,
+                              0x5DF, 0x5E0, 0x5E1, 0x5E1, 0x5E2, 0x5E3, 0x5E4, 0x5E5,
+                              0x5E6, 0x5E7, 0x5E8, 0x5E9, 0x5E9, 0x5EA, 0x5EB, 0x5EC,
+                              0x5ED, 0x5EE, 0x5EF, 0x5F0, 0x5F1, 0x5F1, 0x5F2, 0x5F3,
+                              0x5F4, 0x5F5, 0x5F6, 0x5F7, 0x5F8, 0x5F9, 0x5F9, 0x5FA,
+                              0x5FB, 0x5FC, 0x5FD, 0x5FE, 0x5FF, 0x600, 0x601, 0x601,
+                              0x602, 0x603, 0x604, 0x605, 0x606, 0x607, 0x608, 0x608,
+                              0x609, 0x60A, 0x60B, 0x60C, 0x60D, 0x60E, 0x60F, 0x60F,
+                              0x610, 0x611, 0x612, 0x613, 0x614, 0x615, 0x616, 0x616,
+                              0x617, 0x618, 0x619, 0x61A, 0x61B, 0x61C, 0x61C, 0x61D,
+                              0x61E, 0x61F, 0x620, 0x621, 0x622, 0x623, 0x623, 0x624,
+                              0x625, 0x626, 0x627, 0x628, 0x629, 0x629, 0x62A, 0x62B,
+                              0x62C, 0x62D, 0x62E, 0x62F, 0x62F, 0x630, 0x631, 0x632,
+                              0x633, 0x634, 0x635, 0x635, 0x636, 0x637, 0x638, 0x639,
+                              0x63A, 0x63B, 0x63B, 0x63C, 0x63D, 0x63E, 0x63F, 0x640,
+                              0x641, 0x641, 0x642, 0x643, 0x644, 0x645, 0x646, 0x646,
+                              0x647, 0x648, 0x649, 0x64A, 0x64B, 0x64C, 0x64C, 0x64D,
+                              0x64E, 0x64F, 0x650, 0x651, 0x651, 0x652, 0x653, 0x654,
+                              0x655, 0x656, 0x657, 0x657, 0x658, 0x659, 0x65A, 0x65B,
+                              0x65C, 0x65C, 0x65D, 0x65E, 0x65F, 0x660, 0x661, 0x661,
+                              0x662, 0x663, 0x664, 0x665, 0x666, 0x666, 0x667, 0x668,
+                              0x669, 0x66A, 0x66B, 0x66B, 0x66C, 0x66D, 0x66E, 0x66F,
+                              0x670, 0x670, 0x671, 0x672, 0x673, 0x674, 0x675, 0x675,
+                              0x676, 0x677, 0x678, 0x679, 0x679, 0x67A, 0x67B, 0x67C,
+                              0x67D, 0x67E, 0x67E, 0x67F, 0x680, 0x681, 0x682, 0x683,
+                              0x683, 0x684, 0x685, 0x686, 0x687, 0x687, 0x688, 0x689,
+                              0x68A, 0x68B, 0x68C, 0x68C, 0x68D, 0x68E, 0x68F, 0x690,
+                              0x690, 0x691, 0x692, 0x693, 0x694, 0x694, 0x695, 0x696,
+                              0x697, 0x698, 0x699, 0x699, 0x69A, 0x69B, 0x69C, 0x69D,
+                              0x69D, 0x69E, 0x69F, 0x6A0, 0x6A1, 0x6A1, 0x6A2, 0x6A3,
+                              0x6A4, 0x6A5, 0x6A5, 0x6A6, 0x6A7, 0x6A8, 0x6A9, 0x6A9,
+                              0x6AA, 0x6AB, 0x6AC, 0x6AD, 0x6AD, 0x6AE, 0x6AF, 0x6B0,
+                              0x6B1, 0x6B1, 0x6B2, 0x6B3, 0x6B4, 0x6B5, 0x6B5, 0x6B6,
+                              0x6B7, 0x6B8, 0x6B9, 0x6B9, 0x6BA, 0x6BB, 0x6BC, 0x6BD,
+                              0x6BD, 0x6BE, 0x6BF, 0x6C0, 0x6C1, 0x6C1, 0x6C2, 0x6C3,
+                              0x6C4, 0x6C5, 0x6C5, 0x6C6, 0x6C7, 0x6C8, 0x6C8, 0x6C9,
+                              0x6CA, 0x6CB, 0x6CC, 0x6CC, 0x6CD, 0x6CE, 0x6CF, 0x6D0,
+                              0x6D0, 0x6D1, 0x6D2, 0x6D3, 0x6D3, 0x6D4, 0x6D5, 0x6D6,
+                              0x6D7, 0x6D7, 0x6D8, 0x6D9, 0x6DA, 0x6DA, 0x6DB, 0x6DC,
+                              0x6DD, 0x6DE, 0x6DE, 0x6DF, 0x6E0, 0x6E1, 0x6E1, 0x6E2,
+                              0x6E3, 0x6E4, 0x6E5, 0x6E5, 0x6E6, 0x6E7, 0x6E8, 0x6E8,
+                              0x6E9, 0x6EA, 0x6EB, 0x6EC, 0x6EC, 0x6ED, 0x6EE, 0x6EF,
+                              0x6EF, 0x6F0, 0x6F1, 0x6F2, 0x6F2, 0x6F3, 0x6F4, 0x6F5,
+                              0x6F6, 0x6F6, 0x6F7, 0x6F8, 0x6F9, 0x6F9, 0x6FA, 0x6FB,
+                              0x6FC, 0x6FC, 0x6FD, 0x6FE, 0x6FF, 0x6FF, 0x700, 0x701,
+                              0x702, 0x702, 0x703, 0x704, 0x705, 0x706, 0x706, 0x707,
+                              0x708, 0x709, 0x709, 0x70A, 0x70B, 0x70C, 0x70C, 0x70D,
+                              0x70E, 0x70F, 0x70F, 0x710, 0x711, 0x712, 0x712, 0x713,
+                              0x714, 0x715, 0x715, 0x716, 0x717, 0x718, 0x718, 0x719,
+                              0x71A, 0x71B, 0x71B, 0x71C, 0x71D, 0x71E, 0x71E, 0x71F,
+                              0x720, 0x721, 0x721, 0x722, 0x723, 0x724, 0x724, 0x725,
+                              0x726, 0x727, 0x727, 0x728, 0x729, 0x729, 0x72A, 0x72B,
+                              0x72C, 0x72C, 0x72D, 0x72E, 0x72F, 0x72F, 0x730, 0x731,
+                              0x732, 0x732, 0x733, 0x734, 0x735, 0x735, 0x736, 0x737,
+                              0x737, 0x738, 0x739, 0x73A, 0x73A, 0x73B, 0x73C, 0x73D,
+                              0x73D, 0x73E, 0x73F, 0x740, 0x740, 0x741, 0x742, 0x742,
+                              0x743, 0x744, 0x745, 0x745, 0x746, 0x747, 0x748, 0x748,
+                              0x749, 0x74A, 0x74A, 0x74B, 0x74C, 0x74D, 0x74D, 0x74E,
+                              0x74F, 0x750, 0x750, 0x751, 0x752, 0x752, 0x753, 0x754,
+                              0x755, 0x755, 0x756, 0x757, 0x757, 0x758, 0x759, 0x75A,
+                              0x75A, 0x75B, 0x75C, 0x75C, 0x75D, 0x75E, 0x75F, 0x75F,
+                              0x760, 0x761, 0x761, 0x762, 0x763, 0x764, 0x764, 0x765,
+                              0x766, 0x766, 0x767, 0x768, 0x769, 0x769, 0x76A, 0x76B,
+                              0x76B, 0x76C, 0x76D, 0x76E, 0x76E, 0x76F, 0x770, 0x770,
+                              0x771, 0x772, 0x773, 0x773, 0x774, 0x775, 0x775, 0x776,
+                              0x777, 0x777, 0x778, 0x779, 0x77A, 0x77A, 0x77B, 0x77C,
+                              0x77C, 0x77D, 0x77E, 0x77E, 0x77F, 0x780, 0x781, 0x781,
+                              0x782, 0x783, 0x783, 0x784, 0x785, 0x785, 0x786, 0x787,
+                              0x788, 0x788, 0x789, 0x78A, 0x78A, 0x78B, 0x78C, 0x78C,
+                              0x78D, 0x78E, 0x78E, 0x78F, 0x790, 0x791, 0x791, 0x792,
+                              0x793, 0x793, 0x794, 0x795, 0x795, 0x796, 0x797, 0x797,
+                              0x798, 0x799, 0x799, 0x79A, 0x79B, 0x79C, 0x79C, 0x79D,
+                              0x79E, 0x79E, 0x79F, 0x7A0, 0x7A0, 0x7A1, 0x7A2, 0x7A2,
+                              0x7A3, 0x7A4, 0x7A4, 0x7A5, 0x7A6, 0x7A6, 0x7A7, 0x7A8,
+                              0x7A9, 0x7A9, 0x7AA, 0x7AB, 0x7AB, 0x7AC, 0x7AD, 0x7AD,
+                              0x7AE, 0x7AF, 0x7AF, 0x7B0, 0x7B1, 0x7B1, 0x7B2, 0x7B3,
+                              0x7B3, 0x7B4, 0x7B5, 0x7B5, 0x7B6, 0x7B7, 0x7B7, 0x7B8,
+                              0x7B9, 0x7B9, 0x7BA, 0x7BB, 0x7BB, 0x7BC, 0x7BD, 0x7BD,
+                              0x7BE, 0x7BF, 0x7BF, 0x7C0, 0x7C1, 0x7C1, 0x7C2, 0x7C3,
+                              0x7C3, 0x7C4, 0x7C5, 0x7C5, 0x7C6, 0x7C7, 0x7C7, 0x7C8,
+                              0x7C9, 0x7C9, 0x7CA, 0x7CB, 0x7CB, 0x7CC, 0x7CD, 0x7CD,
+                              0x7CE, 0x7CF, 0x7CF, 0x7D0, 0x7D1, 0x7D1, 0x7D2, 0x7D3,
+                              0x7D3, 0x7D4, 0x7D5, 0x7D5, 0x7D6, 0x7D7, 0x7D7, 0x7D8,
+                              0x7D9, 0x7D9, 0x7DA, 0x7DB, 0x7DB, 0x7DC, 0x7DD, 0x7DD,
+                              0x7DE, 0x7DE, 0x7DF, 0x7E0, 0x7E0, 0x7E1, 0x7E2, 0x7E2,
+                              0x7E3, 0x7E4, 0x7E4, 0x7E5, 0x7E6, 0x7E6, 0x7E7, 0x7E8,
+                              0x7E8, 0x7E9, 0x7EA, 0x7EA, 0x7EB, 0x7EB, 0x7EC, 0x7ED,
+                              0x7ED, 0x7EE, 0x7EF, 0x7EF, 0x7F0, 0x7F1, 0x7F1, 0x7F2,
+                              0x7F3, 0x7F3, 0x7F4, 0x7F4, 0x7F5, 0x7F6, 0x7F6, 0x7F7,
+                              0x7F8, 0x7F8, 0x7F9, 0x7FA, 0x7FA, 0x7FB, 0x7FC, 0x7FC,
+                              0x7FD, 0x7FD, 0x7FE, 0x7FF, 0x7FF, 0x800, 0};
+
+ushort sin_table[4098] = {0, 6, 0xD, 0x13, 0x19, 0x1F, 0x26, 0x2C, 0x32, 0x39,
+                          0x3F, 0x45, 0x4B, 0x52, 0x58, 0x5E, 0x65, 0x6B, 0x71,
+                          0x77, 0x7E, 0x84, 0x8A, 0x91, 0x97, 0x9D, 0xA3, 0xAA,
+                          0xB0, 0xB6, 0xBC, 0xC3, 0xC9, 0xCF, 0xD6, 0xDC, 0xE2,
+                          0xE8, 0xEF, 0xF5, 0xFB, 0x102, 0x108, 0x10E, 0x114,
+                          0x11B, 0x121, 0x127, 0x12E, 0x134, 0x13A, 0x140, 0x147,
+                          0x14D, 0x153, 0x15A, 0x160, 0x166, 0x16C, 0x173, 0x179,
+                          0x17F, 0x186, 0x18C, 0x192, 0x198, 0x19F, 0x1A5, 0x1AB,
+                          0x1B1, 0x1B8, 0x1BE, 0x1C4, 0x1CB, 0x1D1, 0x1D7, 0x1DD,
+                          0x1E4, 0x1EA, 0x1F0, 0x1F7, 0x1FD, 0x203, 0x209, 0x210,
+                          0x216, 0x21C, 0x223, 0x229, 0x22F, 0x235, 0x23C, 0x242,
+                          0x248, 0x24E, 0x255, 0x25B, 0x261, 0x268, 0x26E, 0x274,
+                          0x27A, 0x281, 0x287, 0x28D, 0x294, 0x29A, 0x2A0, 0x2A6,
+                          0x2AD, 0x2B3, 0x2B9, 0x2C0, 0x2C6, 0x2CC, 0x2D2, 0x2D9,
+                          0x2DF, 0x2E5, 0x2EB, 0x2F2, 0x2F8, 0x2FE, 0x305, 0x30B,
+                          0x311, 0x317, 0x31E, 0x324, 0x32A, 0x330, 0x337, 0x33D,
+                          0x343, 0x34A, 0x350, 0x356, 0x35C, 0x363, 0x369, 0x36F,
+                          0x375, 0x37C, 0x382, 0x388, 0x38F, 0x395, 0x39B, 0x3A1,
+                          0x3A8, 0x3AE, 0x3B4, 0x3BB, 0x3C1, 0x3C7, 0x3CD, 0x3D4,
+                          0x3DA, 0x3E0, 0x3E6, 0x3ED, 0x3F3, 0x3F9, 0x3FF, 0x406,
+                          0x40C, 0x412, 0x419, 0x41F, 0x425, 0x42B, 0x432, 0x438,
+                          0x43E, 0x444, 0x44B, 0x451, 0x457, 0x45E, 0x464, 0x46A,
+                          0x470, 0x477, 0x47D, 0x483, 0x489, 0x490, 0x496, 0x49C,
+                          0x4A2, 0x4A9, 0x4AF, 0x4B5, 0x4BC, 0x4C2, 0x4C8, 0x4CE,
+                          0x4D5, 0x4DB, 0x4E1, 0x4E7, 0x4EE, 0x4F4, 0x4FA, 0x500,
+                          0x507, 0x50D, 0x513, 0x51A, 0x520, 0x526, 0x52C, 0x533,
+                          0x539, 0x53F, 0x545, 0x54C, 0x552, 0x558, 0x55E, 0x565,
+                          0x56B, 0x571, 0x577, 0x57E, 0x584, 0x58A, 0x590, 0x597,
+                          0x59D, 0x5A3, 0x5AA, 0x5B0, 0x5B6, 0x5BC, 0x5C3, 0x5C9,
+                          0x5CF, 0x5D5, 0x5DC, 0x5E2, 0x5E8, 0x5EE, 0x5F5, 0x5FB,
+                          0x601, 0x607, 0x60E, 0x614, 0x61A, 0x620, 0x627, 0x62D,
+                          0x633, 0x639, 0x640, 0x646, 0x64C, 0x652, 0x659, 0x65F,
+                          0x665, 0x66B, 0x672, 0x678, 0x67E, 0x684, 0x68B, 0x691,
+                          0x697, 0x69D, 0x6A4, 0x6AA, 0x6B0, 0x6B6, 0x6BD, 0x6C3,
+                          0x6C9, 0x6CF, 0x6D6, 0x6DC, 0x6E2, 0x6E8, 0x6EF, 0x6F5,
+                          0x6FB, 0x701, 0x708, 0x70E, 0x714, 0x71A, 0x721, 0x727,
+                          0x72D, 0x733, 0x73A, 0x740, 0x746, 0x74C, 0x753, 0x759,
+                          0x75F, 0x765, 0x76C, 0x772, 0x778, 0x77E, 0x784, 0x78B,
+                          0x791, 0x797, 0x79D, 0x7A4, 0x7AA, 0x7B0, 0x7B6, 0x7BD,
+                          0x7C3, 0x7C9, 0x7CF, 0x7D6, 0x7DC, 0x7E2, 0x7E8, 0x7EF,
+                          0x7F5, 0x7FB, 0x801, 0x807, 0x80E, 0x814, 0x81A, 0x820,
+                          0x827, 0x82D, 0x833, 0x839, 0x840, 0x846, 0x84C, 0x852,
+                          0x858, 0x85F, 0x865, 0x86B, 0x871, 0x878, 0x87E, 0x884,
+                          0x88A, 0x891, 0x897, 0x89D, 0x8A3, 0x8A9, 0x8B0, 0x8B6,
+                          0x8BC, 0x8C2, 0x8C9, 0x8CF, 0x8D5, 0x8DB, 0x8E1, 0x8E8,
+                          0x8EE, 0x8F4, 0x8FA, 0x901, 0x907, 0x90D, 0x913, 0x919,
+                          0x920, 0x926, 0x92C, 0x932, 0x939, 0x93F, 0x945, 0x94B,
+                          0x951, 0x958, 0x95E, 0x964, 0x96A, 0x970, 0x977, 0x97D,
+                          0x983, 0x989, 0x990, 0x996, 0x99C, 0x9A2, 0x9A8, 0x9AF,
+                          0x9B5, 0x9BB, 0x9C1, 0x9C7, 0x9CE, 0x9D4, 0x9DA, 0x9E0,
+                          0x9E6, 0x9ED, 0x9F3, 0x9F9, 0x9FF, 0xA06, 0xA0C, 0xA12,
+                          0xA18, 0xA1E, 0xA25, 0xA2B, 0xA31, 0xA37, 0xA3D, 0xA44,
+                          0xA4A, 0xA50, 0xA56, 0xA5C, 0xA63, 0xA69, 0xA6F, 0xA75,
+                          0xA7B, 0xA82, 0xA88, 0xA8E, 0xA94, 0xA9A, 0xAA1, 0xAA7,
+                          0xAAD, 0xAB3, 0xAB9, 0xAC0, 0xAC6, 0xACC, 0xAD2, 0xAD8,
+                          0xADE, 0xAE5, 0xAEB, 0xAF1, 0xAF7, 0xAFD, 0xB04, 0xB0A,
+                          0xB10, 0xB16, 0xB1C, 0xB23, 0xB29, 0xB2F, 0xB35, 0xB3B,
+                          0xB41, 0xB48, 0xB4E, 0xB54, 0xB5A, 0xB60, 0xB67, 0xB6D,
+                          0xB73, 0xB79, 0xB7F, 0xB85, 0xB8C, 0xB92, 0xB98, 0xB9E,
+                          0xBA4, 0xBAB, 0xBB1, 0xBB7, 0xBBD, 0xBC3, 0xBC9, 0xBD0,
+                          0xBD6, 0xBDC, 0xBE2, 0xBE8, 0xBEF, 0xBF5, 0xBFB, 0xC01,
+                          0xC07, 0xC0D, 0xC14, 0xC1A, 0xC20, 0xC26, 0xC2C, 0xC32,
+                          0xC39, 0xC3F, 0xC45, 0xC4B, 0xC51, 0xC57, 0xC5E, 0xC64,
+                          0xC6A, 0xC70, 0xC76, 0xC7C, 0xC83, 0xC89, 0xC8F, 0xC95,
+                          0xC9B, 0xCA1, 0xCA7, 0xCAE, 0xCB4, 0xCBA, 0xCC0, 0xCC6,
+                          0xCCC, 0xCD3, 0xCD9, 0xCDF, 0xCE5, 0xCEB, 0xCF1, 0xCF8,
+                          0xCFE, 0xD04, 0xD0A, 0xD10, 0xD16, 0xD1C, 0xD23, 0xD29,
+                          0xD2F, 0xD35, 0xD3B, 0xD41, 0xD47, 0xD4E, 0xD54, 0xD5A,
+                          0xD60, 0xD66, 0xD6C, 0xD72, 0xD79, 0xD7F, 0xD85, 0xD8B,
+                          0xD91, 0xD97, 0xD9D, 0xDA4, 0xDAA, 0xDB0, 0xDB6, 0xDBC,
+                          0xDC2, 0xDC8, 0xDCF, 0xDD5, 0xDDB, 0xDE1, 0xDE7, 0xDED,
+                          0xDF3, 0xDF9, 0xE00, 0xE06, 0xE0C, 0xE12, 0xE18, 0xE1E,
+                          0xE24, 0xE2B, 0xE31, 0xE37, 0xE3D, 0xE43, 0xE49, 0xE4F,
+                          0xE55, 0xE5C, 0xE62, 0xE68, 0xE6E, 0xE74, 0xE7A, 0xE80,
+                          0xE86, 0xE8C, 0xE93, 0xE99, 0xE9F, 0xEA5, 0xEAB, 0xEB1,
+                          0xEB7, 0xEBD, 0xEC4, 0xECA, 0xED0, 0xED6, 0xEDC, 0xEE2,
+                          0xEE8, 0xEEE, 0xEF4, 0xEFB, 0xF01, 0xF07, 0xF0D, 0xF13,
+                          0xF19, 0xF1F, 0xF25, 0xF2B, 0xF31, 0xF38, 0xF3E, 0xF44,
+                          0xF4A, 0xF50, 0xF56, 0xF5C, 0xF62, 0xF68, 0xF6F, 0xF75,
+                          0xF7B, 0xF81, 0xF87, 0xF8D, 0xF93, 0xF99, 0xF9F, 0xFA5,
+                          0xFAB, 0xFB2, 0xFB8, 0xFBE, 0xFC4, 0xFCA, 0xFD0, 0xFD6,
+                          0xFDC, 0xFE2, 0xFE8, 0xFEE, 0xFF5, 0xFFB, 0x1001, 0x1007,
+                          0x100D, 0x1013, 0x1019, 0x101F, 0x1025, 0x102B, 0x1031,
+                          0x1037, 0x103D, 0x1044, 0x104A, 0x1050, 0x1056, 0x105C,
+                          0x1062, 0x1068, 0x106E, 0x1074, 0x107A, 0x1080, 0x1086,
+                          0x108C, 0x1093, 0x1099, 0x109F, 0x10A5, 0x10AB, 0x10B1,
+                          0x10B7, 0x10BD, 0x10C3, 0x10C9, 0x10CF, 0x10D5, 0x10DB,
+                          0x10E1, 0x10E7, 0x10ED, 0x10F4, 0x10FA, 0x1100, 0x1106,
+                          0x110C, 0x1112, 0x1118, 0x111E, 0x1124, 0x112A, 0x1130,
+                          0x1136, 0x113C, 0x1142, 0x1148, 0x114E, 0x1154, 0x115A,
+                          0x1160, 0x1167, 0x116D, 0x1173, 0x1179, 0x117F, 0x1185,
+                          0x118B, 0x1191, 0x1197, 0x119D, 0x11A3, 0x11A9, 0x11AF,
+                          0x11B5, 0x11BB, 0x11C1, 0x11C7, 0x11CD, 0x11D3, 0x11D9,
+                          0x11DF, 0x11E5, 0x11EB, 0x11F1, 0x11F7, 0x11FD, 0x1204,
+                          0x120A, 0x1210, 0x1216, 0x121C, 0x1222, 0x1228, 0x122E,
+                          0x1234, 0x123A, 0x1240, 0x1246, 0x124C, 0x1252, 0x1258,
+                          0x125E, 0x1264, 0x126A, 0x1270, 0x1276, 0x127C, 0x1282,
+                          0x1288, 0x128E, 0x1294, 0x129A, 0x12A0, 0x12A6, 0x12AC,
+                          0x12B2, 0x12B8, 0x12BE, 0x12C4, 0x12CA, 0x12D0, 0x12D6,
+                          0x12DC, 0x12E2, 0x12E8, 0x12EE, 0x12F4, 0x12FA, 0x1300,
+                          0x1306, 0x130C, 0x1312, 0x1318, 0x131E, 0x1324, 0x132A,
+                          0x1330, 0x1336, 0x133C, 0x1342, 0x1348, 0x134E, 0x1354,
+                          0x135A, 0x1360, 0x1366, 0x136C, 0x1372, 0x1378, 0x137E,
+                          0x1384, 0x138A, 0x1390, 0x1396, 0x139C, 0x13A2, 0x13A8,
+                          0x13AE, 0x13B4, 0x13BA, 0x13C0, 0x13C6, 0x13CC, 0x13D2,
+                          0x13D8, 0x13DE, 0x13E4, 0x13EA, 0x13F0, 0x13F6, 0x13FB,
+                          0x1401, 0x1407, 0x140D, 0x1413, 0x1419, 0x141F, 0x1425,
+                          0x142B, 0x1431, 0x1437, 0x143D, 0x1443, 0x1449, 0x144F,
+                          0x1455, 0x145B, 0x1461, 0x1467, 0x146D, 0x1473, 0x1479,
+                          0x147F, 0x1485, 0x148B, 0x1490, 0x1496, 0x149C, 0x14A2,
+                          0x14A8, 0x14AE, 0x14B4, 0x14BA, 0x14C0, 0x14C6, 0x14CC,
+                          0x14D2, 0x14D8, 0x14DE, 0x14E4, 0x14EA, 0x14F0, 0x14F6,
+                          0x14FB, 0x1501, 0x1507, 0x150D, 0x1513, 0x1519, 0x151F,
+                          0x1525, 0x152B, 0x1531, 0x1537, 0x153D, 0x1543, 0x1549,
+                          0x154E, 0x1554, 0x155A, 0x1560, 0x1566, 0x156C, 0x1572,
+                          0x1578, 0x157E, 0x1584, 0x158A, 0x1590, 0x1596, 0x159B,
+                          0x15A1, 0x15A7, 0x15AD, 0x15B3, 0x15B9, 0x15BF, 0x15C5,
+                          0x15CB, 0x15D1, 0x15D7, 0x15DC, 0x15E2, 0x15E8, 0x15EE,
+                          0x15F4, 0x15FA, 0x1600, 0x1606, 0x160C, 0x1612, 0x1617,
+                          0x161D, 0x1623, 0x1629, 0x162F, 0x1635, 0x163B, 0x1641,
+                          0x1647, 0x164C, 0x1652, 0x1658, 0x165E, 0x1664, 0x166A,
+                          0x1670, 0x1676, 0x167C, 0x1681, 0x1687, 0x168D, 0x1693,
+                          0x1699, 0x169F, 0x16A5, 0x16AB, 0x16B0, 0x16B6, 0x16BC,
+                          0x16C2, 0x16C8, 0x16CE, 0x16D4, 0x16DA, 0x16DF, 0x16E5,
+                          0x16EB, 0x16F1, 0x16F7, 0x16FD, 0x1703, 0x1709, 0x170E,
+                          0x1714, 0x171A, 0x1720, 0x1726, 0x172C, 0x1732, 0x1737,
+                          0x173D, 0x1743, 0x1749, 0x174F, 0x1755, 0x175B, 0x1760,
+                          0x1766, 0x176C, 0x1772, 0x1778, 0x177E, 0x1783, 0x1789,
+                          0x178F, 0x1795, 0x179B, 0x17A1, 0x17A6, 0x17AC, 0x17B2,
+                          0x17B8, 0x17BE, 0x17C4, 0x17C9, 0x17CF, 0x17D5, 0x17DB,
+                          0x17E1, 0x17E7, 0x17EC, 0x17F2, 0x17F8, 0x17FE, 0x1804,
+                          0x180A, 0x180F, 0x1815, 0x181B, 0x1821, 0x1827, 0x182D,
+                          0x1832, 0x1838, 0x183E, 0x1844, 0x184A, 0x184F, 0x1855,
+                          0x185B, 0x1861, 0x1867, 0x186C, 0x1872, 0x1878, 0x187E,
+                          0x1884, 0x1889, 0x188F, 0x1895, 0x189B, 0x18A1, 0x18A6,
+                          0x18AC, 0x18B2, 0x18B8, 0x18BE, 0x18C3, 0x18C9, 0x18CF,
+                          0x18D5, 0x18DB, 0x18E0, 0x18E6, 0x18EC, 0x18F2, 0x18F8,
+                          0x18FD, 0x1903, 0x1909, 0x190F, 0x1914, 0x191A, 0x1920,
+                          0x1926, 0x192C, 0x1931, 0x1937, 0x193D, 0x1943, 0x1948,
+                          0x194E, 0x1954, 0x195A, 0x1960, 0x1965, 0x196B, 0x1971,
+                          0x1977, 0x197C, 0x1982, 0x1988, 0x198E, 0x1993, 0x1999,
+                          0x199F, 0x19A5, 0x19AA, 0x19B0, 0x19B6, 0x19BC, 0x19C1,
+                          0x19C7, 0x19CD, 0x19D3, 0x19D8, 0x19DE, 0x19E4, 0x19EA,
+                          0x19EF, 0x19F5, 0x19FB, 0x1A01, 0x1A06, 0x1A0C, 0x1A12,
+                          0x1A18, 0x1A1D, 0x1A23, 0x1A29, 0x1A2F, 0x1A34, 0x1A3A,
+                          0x1A40, 0x1A46, 0x1A4B, 0x1A51, 0x1A57, 0x1A5C, 0x1A62,
+                          0x1A68, 0x1A6E, 0x1A73, 0x1A79, 0x1A7F, 0x1A84, 0x1A8A,
+                          0x1A90, 0x1A96, 0x1A9B, 0x1AA1, 0x1AA7, 0x1AAC, 0x1AB2,
+                          0x1AB8, 0x1ABE, 0x1AC3, 0x1AC9, 0x1ACF, 0x1AD4, 0x1ADA,
+                          0x1AE0, 0x1AE6, 0x1AEB, 0x1AF1, 0x1AF7, 0x1AFC, 0x1B02,
+                          0x1B08, 0x1B0D, 0x1B13, 0x1B19, 0x1B1F, 0x1B24, 0x1B2A,
+                          0x1B30, 0x1B35, 0x1B3B, 0x1B41, 0x1B46, 0x1B4C, 0x1B52,
+                          0x1B57, 0x1B5D, 0x1B63, 0x1B68, 0x1B6E, 0x1B74, 0x1B79,
+                          0x1B7F, 0x1B85, 0x1B8A, 0x1B90, 0x1B96, 0x1B9B, 0x1BA1,
+                          0x1BA7, 0x1BAC, 0x1BB2, 0x1BB8, 0x1BBD, 0x1BC3, 0x1BC9,
+                          0x1BCE, 0x1BD4, 0x1BDA, 0x1BDF, 0x1BE5, 0x1BEB, 0x1BF0,
+                          0x1BF6, 0x1BFC, 0x1C01, 0x1C07, 0x1C0D, 0x1C12, 0x1C18,
+                          0x1C1E, 0x1C23, 0x1C29, 0x1C2F, 0x1C34, 0x1C3A, 0x1C3F,
+                          0x1C45, 0x1C4B, 0x1C50, 0x1C56, 0x1C5C, 0x1C61, 0x1C67,
+                          0x1C6C, 0x1C72, 0x1C78, 0x1C7D, 0x1C83, 0x1C89, 0x1C8E,
+                          0x1C94, 0x1C99, 0x1C9F, 0x1CA5, 0x1CAA, 0x1CB0, 0x1CB6,
+                          0x1CBB, 0x1CC1, 0x1CC6, 0x1CCC, 0x1CD2, 0x1CD7, 0x1CDD,
+                          0x1CE2, 0x1CE8, 0x1CEE, 0x1CF3, 0x1CF9, 0x1CFF, 0x1D04,
+                          0x1D0A, 0x1D0F, 0x1D15, 0x1D1A, 0x1D20, 0x1D26, 0x1D2B,
+                          0x1D31, 0x1D36, 0x1D3C, 0x1D42, 0x1D47, 0x1D4D, 0x1D52,
+                          0x1D58, 0x1D5E, 0x1D63, 0x1D69, 0x1D6E, 0x1D74, 0x1D79,
+                          0x1D7F, 0x1D85, 0x1D8A, 0x1D90, 0x1D95, 0x1D9B, 0x1DA0,
+                          0x1DA6, 0x1DAC, 0x1DB1, 0x1DB7, 0x1DBC, 0x1DC2, 0x1DC7,
+                          0x1DCD, 0x1DD3, 0x1DD8, 0x1DDE, 0x1DE3, 0x1DE9, 0x1DEE,
+                          0x1DF4, 0x1DF9, 0x1DFF, 0x1E05, 0x1E0A, 0x1E10, 0x1E15,
+                          0x1E1B, 0x1E20, 0x1E26, 0x1E2B, 0x1E31, 0x1E36, 0x1E3C,
+                          0x1E42, 0x1E47, 0x1E4D, 0x1E52, 0x1E58, 0x1E5D, 0x1E63,
+                          0x1E68, 0x1E6E, 0x1E73, 0x1E79, 0x1E7E, 0x1E84, 0x1E89,
+                          0x1E8F, 0x1E94, 0x1E9A, 0x1E9F, 0x1EA5, 0x1EAB, 0x1EB0,
+                          0x1EB6, 0x1EBB, 0x1EC1, 0x1EC6, 0x1ECC, 0x1ED1, 0x1ED7,
+                          0x1EDC, 0x1EE2, 0x1EE7, 0x1EED, 0x1EF2, 0x1EF8, 0x1EFD,
+                          0x1F03, 0x1F08, 0x1F0E, 0x1F13, 0x1F19, 0x1F1E, 0x1F24,
+                          0x1F29, 0x1F2F, 0x1F34, 0x1F3A, 0x1F3F, 0x1F44, 0x1F4A,
+                          0x1F4F, 0x1F55, 0x1F5A, 0x1F60, 0x1F65, 0x1F6B, 0x1F70,
+                          0x1F76, 0x1F7B, 0x1F81, 0x1F86, 0x1F8C, 0x1F91, 0x1F97,
+                          0x1F9C, 0x1FA2, 0x1FA7, 0x1FAC, 0x1FB2, 0x1FB7, 0x1FBD,
+                          0x1FC2, 0x1FC8, 0x1FCD, 0x1FD3, 0x1FD8, 0x1FDE, 0x1FE3,
+                          0x1FE8, 0x1FEE, 0x1FF3, 0x1FF9, 0x1FFE, 0x2004, 0x2009,
+                          0x200F, 0x2014, 0x2019, 0x201F, 0x2024, 0x202A, 0x202F,
+                          0x2035, 0x203A, 0x203F, 0x2045, 0x204A, 0x2050, 0x2055,
+                          0x205B, 0x2060, 0x2065, 0x206B, 0x2070, 0x2076, 0x207B,
+                          0x2080, 0x2086, 0x208B, 0x2091, 0x2096, 0x209B, 0x20A1,
+                          0x20A6, 0x20AC, 0x20B1, 0x20B7, 0x20BC, 0x20C1, 0x20C7,
+                          0x20CC, 0x20D1, 0x20D7, 0x20DC, 0x20E2, 0x20E7, 0x20EC,
+                          0x20F2, 0x20F7, 0x20FD, 0x2102, 0x2107, 0x210D, 0x2112,
+                          0x2118, 0x211D, 0x2122, 0x2128, 0x212D, 0x2132, 0x2138,
+                          0x213D, 0x2142, 0x2148, 0x214D, 0x2153, 0x2158, 0x215D,
+                          0x2163, 0x2168, 0x216D, 0x2173, 0x2178, 0x217D, 0x2183,
+                          0x2188, 0x218E, 0x2193, 0x2198, 0x219E, 0x21A3, 0x21A8,
+                          0x21AE, 0x21B3, 0x21B8, 0x21BE, 0x21C3, 0x21C8, 0x21CE,
+                          0x21D3, 0x21D8, 0x21DE, 0x21E3, 0x21E8, 0x21EE, 0x21F3,
+                          0x21F8, 0x21FE, 0x2203, 0x2208, 0x220E, 0x2213, 0x2218,
+                          0x221E, 0x2223, 0x2228, 0x222D, 0x2233, 0x2238, 0x223D,
+                          0x2243, 0x2248, 0x224D, 0x2253, 0x2258, 0x225D, 0x2263,
+                          0x2268, 0x226D, 0x2272, 0x2278, 0x227D, 0x2282, 0x2288,
+                          0x228D, 0x2292, 0x2297, 0x229D, 0x22A2, 0x22A7, 0x22AD,
+                          0x22B2, 0x22B7, 0x22BC, 0x22C2, 0x22C7, 0x22CC, 0x22D2,
+                          0x22D7, 0x22DC, 0x22E1, 0x22E7, 0x22EC, 0x22F1, 0x22F6,
+                          0x22FC, 0x2301, 0x2306, 0x230B, 0x2311, 0x2316, 0x231B,
+                          0x2320, 0x2326, 0x232B, 0x2330, 0x2335, 0x233B, 0x2340,
+                          0x2345, 0x234A, 0x2350, 0x2355, 0x235A, 0x235F, 0x2365,
+                          0x236A, 0x236F, 0x2374, 0x237A, 0x237F, 0x2384, 0x2389,
+                          0x238E, 0x2394, 0x2399, 0x239E, 0x23A3, 0x23A9, 0x23AE,
+                          0x23B3, 0x23B8, 0x23BD, 0x23C3, 0x23C8, 0x23CD, 0x23D2,
+                          0x23D7, 0x23DD, 0x23E2, 0x23E7, 0x23EC, 0x23F1, 0x23F7,
+                          0x23FC, 0x2401, 0x2406, 0x240B, 0x2411, 0x2416, 0x241B,
+                          0x2420, 0x2425, 0x242B, 0x2430, 0x2435, 0x243A, 0x243F,
+                          0x2444, 0x244A, 0x244F, 0x2454, 0x2459, 0x245E, 0x2464,
+                          0x2469, 0x246E, 0x2473, 0x2478, 0x247D, 0x2483, 0x2488,
+                          0x248D, 0x2492, 0x2497, 0x249C, 0x24A1, 0x24A7, 0x24AC,
+                          0x24B1, 0x24B6, 0x24BB, 0x24C0, 0x24C5, 0x24CB, 0x24D0,
+                          0x24D5, 0x24DA, 0x24DF, 0x24E4, 0x24E9, 0x24EF, 0x24F4,
+                          0x24F9, 0x24FE, 0x2503, 0x2508, 0x250D, 0x2512, 0x2518,
+                          0x251D, 0x2522, 0x2527, 0x252C, 0x2531, 0x2536, 0x253B,
+                          0x2541, 0x2546, 0x254B, 0x2550, 0x2555, 0x255A, 0x255F,
+                          0x2564, 0x2569, 0x256E, 0x2574, 0x2579, 0x257E, 0x2583,
+                          0x2588, 0x258D, 0x2592, 0x2597, 0x259C, 0x25A1, 0x25A6,
+                          0x25AB, 0x25B1, 0x25B6, 0x25BB, 0x25C0, 0x25C5, 0x25CA,
+                          0x25CF, 0x25D4, 0x25D9, 0x25DE, 0x25E3, 0x25E8, 0x25ED,
+                          0x25F2, 0x25F8, 0x25FD, 0x2602, 0x2607, 0x260C, 0x2611,
+                          0x2616, 0x261B, 0x2620, 0x2625, 0x262A, 0x262F, 0x2634,
+                          0x2639, 0x263E, 0x2643, 0x2648, 0x264D, 0x2652, 0x2657,
+                          0x265C, 0x2661, 0x2666, 0x266B, 0x2671, 0x2676, 0x267B,
+                          0x2680, 0x2685, 0x268A, 0x268F, 0x2694, 0x2699, 0x269E,
+                          0x26A3, 0x26A8, 0x26AD, 0x26B2, 0x26B7, 0x26BC, 0x26C1,
+                          0x26C6, 0x26CB, 0x26D0, 0x26D5, 0x26DA, 0x26DF, 0x26E4,
+                          0x26E9, 0x26EE, 0x26F3, 0x26F8, 0x26FD, 0x2702, 0x2707,
+                          0x270C, 0x2711, 0x2715, 0x271A, 0x271F, 0x2724, 0x2729,
+                          0x272E, 0x2733, 0x2738, 0x273D, 0x2742, 0x2747, 0x274C,
+                          0x2751, 0x2756, 0x275B, 0x2760, 0x2765, 0x276A, 0x276F,
+                          0x2774, 0x2779, 0x277E, 0x2783, 0x2788, 0x278C, 0x2791,
+                          0x2796, 0x279B, 0x27A0, 0x27A5, 0x27AA, 0x27AF, 0x27B4,
+                          0x27B9, 0x27BE, 0x27C3, 0x27C8, 0x27CD, 0x27D1, 0x27D6,
+                          0x27DB, 0x27E0, 0x27E5, 0x27EA, 0x27EF, 0x27F4, 0x27F9,
+                          0x27FE, 0x2803, 0x2808, 0x280C, 0x2811, 0x2816, 0x281B,
+                          0x2820, 0x2825, 0x282A, 0x282F, 0x2834, 0x2838, 0x283D,
+                          0x2842, 0x2847, 0x284C, 0x2851, 0x2856, 0x285B, 0x2860,
+                          0x2864, 0x2869, 0x286E, 0x2873, 0x2878, 0x287D, 0x2882,
+                          0x2886, 0x288B, 0x2890, 0x2895, 0x289A, 0x289F, 0x28A4,
+                          0x28A8, 0x28AD, 0x28B2, 0x28B7, 0x28BC, 0x28C1, 0x28C6,
+                          0x28CA, 0x28CF, 0x28D4, 0x28D9, 0x28DE, 0x28E3, 0x28E7,
+                          0x28EC, 0x28F1, 0x28F6, 0x28FB, 0x2900, 0x2904, 0x2909,
+                          0x290E, 0x2913, 0x2918, 0x291C, 0x2921, 0x2926, 0x292B,
+                          0x2930, 0x2935, 0x2939, 0x293E, 0x2943, 0x2948, 0x294D,
+                          0x2951, 0x2956, 0x295B, 0x2960, 0x2965, 0x2969, 0x296E,
+                          0x2973, 0x2978, 0x297C, 0x2981, 0x2986, 0x298B, 0x2990,
+                          0x2994, 0x2999, 0x299E, 0x29A3, 0x29A7, 0x29AC, 0x29B1,
+                          0x29B6, 0x29BB, 0x29BF, 0x29C4, 0x29C9, 0x29CE, 0x29D2,
+                          0x29D7, 0x29DC, 0x29E1, 0x29E5, 0x29EA, 0x29EF, 0x29F4,
+                          0x29F8, 0x29FD, 0x2A02, 0x2A07, 0x2A0B, 0x2A10, 0x2A15,
+                          0x2A1A, 0x2A1E, 0x2A23, 0x2A28, 0x2A2C, 0x2A31, 0x2A36,
+                          0x2A3B, 0x2A3F, 0x2A44, 0x2A49, 0x2A4D, 0x2A52, 0x2A57,
+                          0x2A5C, 0x2A60, 0x2A65, 0x2A6A, 0x2A6E, 0x2A73, 0x2A78,
+                          0x2A7D, 0x2A81, 0x2A86, 0x2A8B, 0x2A8F, 0x2A94, 0x2A99,
+                          0x2A9D, 0x2AA2, 0x2AA7, 0x2AAB, 0x2AB0, 0x2AB5, 0x2AB9,
+                          0x2ABE, 0x2AC3, 0x2AC8, 0x2ACC, 0x2AD1, 0x2AD6, 0x2ADA,
+                          0x2ADF, 0x2AE4, 0x2AE8, 0x2AED, 0x2AF2, 0x2AF6, 0x2AFB,
+                          0x2AFF, 0x2B04, 0x2B09, 0x2B0D, 0x2B12, 0x2B17, 0x2B1B,
+                          0x2B20, 0x2B25, 0x2B29, 0x2B2E, 0x2B33, 0x2B37, 0x2B3C,
+                          0x2B40, 0x2B45, 0x2B4A, 0x2B4E, 0x2B53, 0x2B58, 0x2B5C,
+                          0x2B61, 0x2B65, 0x2B6A, 0x2B6F, 0x2B73, 0x2B78, 0x2B7D,
+                          0x2B81, 0x2B86, 0x2B8A, 0x2B8F, 0x2B94, 0x2B98, 0x2B9D,
+                          0x2BA1, 0x2BA6, 0x2BAB, 0x2BAF, 0x2BB4, 0x2BB8, 0x2BBD,
+                          0x2BC2, 0x2BC6, 0x2BCB, 0x2BCF, 0x2BD4, 0x2BD8, 0x2BDD,
+                          0x2BE2, 0x2BE6, 0x2BEB, 0x2BEF, 0x2BF4, 0x2BF8, 0x2BFD,
+                          0x2C02, 0x2C06, 0x2C0B, 0x2C0F, 0x2C14, 0x2C18, 0x2C1D,
+                          0x2C21, 0x2C26, 0x2C2B, 0x2C2F, 0x2C34, 0x2C38, 0x2C3D,
+                          0x2C41, 0x2C46, 0x2C4A, 0x2C4F, 0x2C53, 0x2C58, 0x2C5C,
+                          0x2C61, 0x2C66, 0x2C6A, 0x2C6F, 0x2C73, 0x2C78, 0x2C7C,
+                          0x2C81, 0x2C85, 0x2C8A, 0x2C8E, 0x2C93, 0x2C97, 0x2C9C,
+                          0x2CA0, 0x2CA5, 0x2CA9, 0x2CAE, 0x2CB2, 0x2CB7, 0x2CBB,
+                          0x2CC0, 0x2CC4, 0x2CC9, 0x2CCD, 0x2CD2, 0x2CD6, 0x2CDB,
+                          0x2CDF, 0x2CE4, 0x2CE8, 0x2CED, 0x2CF1, 0x2CF5, 0x2CFA,
+                          0x2CFE, 0x2D03, 0x2D07, 0x2D0C, 0x2D10, 0x2D15, 0x2D19,
+                          0x2D1E, 0x2D22, 0x2D27, 0x2D2B, 0x2D2F, 0x2D34, 0x2D38,
+                          0x2D3D, 0x2D41, 0x2D46, 0x2D4A, 0x2D4F, 0x2D53, 0x2D57,
+                          0x2D5C, 0x2D60, 0x2D65, 0x2D69, 0x2D6E, 0x2D72, 0x2D76,
+                          0x2D7B, 0x2D7F, 0x2D84, 0x2D88, 0x2D8D, 0x2D91, 0x2D95,
+                          0x2D9A, 0x2D9E, 0x2DA3, 0x2DA7, 0x2DAB, 0x2DB0, 0x2DB4,
+                          0x2DB9, 0x2DBD, 0x2DC1, 0x2DC6, 0x2DCA, 0x2DCF, 0x2DD3,
+                          0x2DD7, 0x2DDC, 0x2DE0, 0x2DE4, 0x2DE9, 0x2DED, 0x2DF2,
+                          0x2DF6, 0x2DFA, 0x2DFF, 0x2E03, 0x2E07, 0x2E0C, 0x2E10,
+                          0x2E15, 0x2E19, 0x2E1D, 0x2E22, 0x2E26, 0x2E2A, 0x2E2F,
+                          0x2E33, 0x2E37, 0x2E3C, 0x2E40, 0x2E44, 0x2E49, 0x2E4D,
+                          0x2E51, 0x2E56, 0x2E5A, 0x2E5E, 0x2E63, 0x2E67, 0x2E6B,
+                          0x2E70, 0x2E74, 0x2E78, 0x2E7D, 0x2E81, 0x2E85, 0x2E8A,
+                          0x2E8E, 0x2E92, 0x2E97, 0x2E9B, 0x2E9F, 0x2EA3, 0x2EA8,
+                          0x2EAC, 0x2EB0, 0x2EB5, 0x2EB9, 0x2EBD, 0x2EC2, 0x2EC6,
+                          0x2ECA, 0x2ECE, 0x2ED3, 0x2ED7, 0x2EDB, 0x2EE0, 0x2EE4,
+                          0x2EE8, 0x2EEC, 0x2EF1, 0x2EF5, 0x2EF9, 0x2EFD, 0x2F02,
+                          0x2F06, 0x2F0A, 0x2F0E, 0x2F13, 0x2F17, 0x2F1B, 0x2F20,
+                          0x2F24, 0x2F28, 0x2F2C, 0x2F30, 0x2F35, 0x2F39, 0x2F3D,
+                          0x2F41, 0x2F46, 0x2F4A, 0x2F4E, 0x2F52, 0x2F57, 0x2F5B,
+                          0x2F5F, 0x2F63, 0x2F68, 0x2F6C, 0x2F70, 0x2F74, 0x2F78,
+                          0x2F7D, 0x2F81, 0x2F85, 0x2F89, 0x2F8D, 0x2F92, 0x2F96,
+                          0x2F9A, 0x2F9E, 0x2FA2, 0x2FA7, 0x2FAB, 0x2FAF, 0x2FB3,
+                          0x2FB7, 0x2FBC, 0x2FC0, 0x2FC4, 0x2FC8, 0x2FCC, 0x2FD0,
+                          0x2FD5, 0x2FD9, 0x2FDD, 0x2FE1, 0x2FE5, 0x2FEA, 0x2FEE,
+                          0x2FF2, 0x2FF6, 0x2FFA, 0x2FFE, 0x3002, 0x3007, 0x300B,
+                          0x300F, 0x3013, 0x3017, 0x301B, 0x3020, 0x3024, 0x3028,
+                          0x302C, 0x3030, 0x3034, 0x3038, 0x303C, 0x3041, 0x3045,
+                          0x3049, 0x304D, 0x3051, 0x3055, 0x3059, 0x305D, 0x3062,
+                          0x3066, 0x306A, 0x306E, 0x3072, 0x3076, 0x307A, 0x307E,
+                          0x3082, 0x3087, 0x308B, 0x308F, 0x3093, 0x3097, 0x309B,
+                          0x309F, 0x30A3, 0x30A7, 0x30AB, 0x30AF, 0x30B3, 0x30B8,
+                          0x30BC, 0x30C0, 0x30C4, 0x30C8, 0x30CC, 0x30D0, 0x30D4,
+                          0x30D8, 0x30DC, 0x30E0, 0x30E4, 0x30E8, 0x30EC, 0x30F0,
+                          0x30F4, 0x30F9, 0x30FD, 0x3101, 0x3105, 0x3109, 0x310D,
+                          0x3111, 0x3115, 0x3119, 0x311D, 0x3121, 0x3125, 0x3129,
+                          0x312D, 0x3131, 0x3135, 0x3139, 0x313D, 0x3141, 0x3145,
+                          0x3149, 0x314D, 0x3151, 0x3155, 0x3159, 0x315D, 0x3161,
+                          0x3165, 0x3169, 0x316D, 0x3171, 0x3175, 0x3179, 0x317D,
+                          0x3181, 0x3185, 0x3189, 0x318D, 0x3191, 0x3195, 0x3199,
+                          0x319D, 0x31A1, 0x31A5, 0x31A9, 0x31AD, 0x31B1, 0x31B5,
+                          0x31B9, 0x31BC, 0x31C0, 0x31C4, 0x31C8, 0x31CC, 0x31D0,
+                          0x31D4, 0x31D8, 0x31DC, 0x31E0, 0x31E4, 0x31E8, 0x31EC,
+                          0x31F0, 0x31F4, 0x31F8, 0x31FC, 0x31FF, 0x3203, 0x3207,
+                          0x320B, 0x320F, 0x3213, 0x3217, 0x321B, 0x321F, 0x3223,
+                          0x3227, 0x322A, 0x322E, 0x3232, 0x3236, 0x323A, 0x323E,
+                          0x3242, 0x3246, 0x324A, 0x324E, 0x3251, 0x3255, 0x3259,
+                          0x325D, 0x3261, 0x3265, 0x3269, 0x326D, 0x3270, 0x3274,
+                          0x3278, 0x327C, 0x3280, 0x3284, 0x3288, 0x328B, 0x328F,
+                          0x3293, 0x3297, 0x329B, 0x329F, 0x32A3, 0x32A6, 0x32AA,
+                          0x32AE, 0x32B2, 0x32B6, 0x32BA, 0x32BD, 0x32C1, 0x32C5,
+                          0x32C9, 0x32CD, 0x32D0, 0x32D4, 0x32D8, 0x32DC, 0x32E0,
+                          0x32E4, 0x32E7, 0x32EB, 0x32EF, 0x32F3, 0x32F7, 0x32FA,
+                          0x32FE, 0x3302, 0x3306, 0x330A, 0x330D, 0x3311, 0x3315,
+                          0x3319, 0x331D, 0x3320, 0x3324, 0x3328, 0x332C, 0x332F,
+                          0x3333, 0x3337, 0x333B, 0x333E, 0x3342, 0x3346, 0x334A,
+                          0x334E, 0x3351, 0x3355, 0x3359, 0x335D, 0x3360, 0x3364,
+                          0x3368, 0x336B, 0x336F, 0x3373, 0x3377, 0x337A, 0x337E,
+                          0x3382, 0x3386, 0x3389, 0x338D, 0x3391, 0x3395, 0x3398,
+                          0x339C, 0x33A0, 0x33A3, 0x33A7, 0x33AB, 0x33AF, 0x33B2,
+                          0x33B6, 0x33BA, 0x33BD, 0x33C1, 0x33C5, 0x33C8, 0x33CC,
+                          0x33D0, 0x33D3, 0x33D7, 0x33DB, 0x33DF, 0x33E2, 0x33E6,
+                          0x33EA, 0x33ED, 0x33F1, 0x33F5, 0x33F8, 0x33FC, 0x3400,
+                          0x3403, 0x3407, 0x340B, 0x340E, 0x3412, 0x3416, 0x3419,
+                          0x341D, 0x3420, 0x3424, 0x3428, 0x342B, 0x342F, 0x3433,
+                          0x3436, 0x343A, 0x343E, 0x3441, 0x3445, 0x3448, 0x344C,
+                          0x3450, 0x3453, 0x3457, 0x345B, 0x345E, 0x3462, 0x3465,
+                          0x3469, 0x346D, 0x3470, 0x3474, 0x3477, 0x347B, 0x347F,
+                          0x3482, 0x3486, 0x3489, 0x348D, 0x3491, 0x3494, 0x3498,
+                          0x349B, 0x349F, 0x34A2, 0x34A6, 0x34AA, 0x34AD, 0x34B1,
+                          0x34B4, 0x34B8, 0x34BB, 0x34BF, 0x34C3, 0x34C6, 0x34CA,
+                          0x34CD, 0x34D1, 0x34D4, 0x34D8, 0x34DB, 0x34DF, 0x34E2,
+                          0x34E6, 0x34EA, 0x34ED, 0x34F1, 0x34F4, 0x34F8, 0x34FB,
+                          0x34FF, 0x3502, 0x3506, 0x3509, 0x350D, 0x3510, 0x3514,
+                          0x3517, 0x351B, 0x351E, 0x3522, 0x3525, 0x3529, 0x352C,
+                          0x3530, 0x3533, 0x3537, 0x353A, 0x353E, 0x3541, 0x3545,
+                          0x3548, 0x354C, 0x354F, 0x3553, 0x3556, 0x355A, 0x355D,
+                          0x3561, 0x3564, 0x3567, 0x356B, 0x356E, 0x3572, 0x3575,
+                          0x3579, 0x357C, 0x3580, 0x3583, 0x3587, 0x358A, 0x358D,
+                          0x3591, 0x3594, 0x3598, 0x359B, 0x359F, 0x35A2, 0x35A5,
+                          0x35A9, 0x35AC, 0x35B0, 0x35B3, 0x35B7, 0x35BA, 0x35BD,
+                          0x35C1, 0x35C4, 0x35C8, 0x35CB, 0x35CE, 0x35D2, 0x35D5,
+                          0x35D9, 0x35DC, 0x35DF, 0x35E3, 0x35E6, 0x35EA, 0x35ED,
+                          0x35F0, 0x35F4, 0x35F7, 0x35FB, 0x35FE, 0x3601, 0x3605,
+                          0x3608, 0x360B, 0x360F, 0x3612, 0x3615, 0x3619, 0x361C,
+                          0x3620, 0x3623, 0x3626, 0x362A, 0x362D, 0x3630, 0x3634,
+                          0x3637, 0x363A, 0x363E, 0x3641, 0x3644, 0x3648, 0x364B,
+                          0x364E, 0x3652, 0x3655, 0x3658, 0x365C, 0x365F, 0x3662,
+                          0x3665, 0x3669, 0x366C, 0x366F, 0x3673, 0x3676, 0x3679,
+                          0x367D, 0x3680, 0x3683, 0x3686, 0x368A, 0x368D, 0x3690,
+                          0x3694, 0x3697, 0x369A, 0x369D, 0x36A1, 0x36A4, 0x36A7,
+                          0x36AB, 0x36AE, 0x36B1, 0x36B4, 0x36B8, 0x36BB, 0x36BE,
+                          0x36C1, 0x36C5, 0x36C8, 0x36CB, 0x36CE, 0x36D2, 0x36D5,
+                          0x36D8, 0x36DB, 0x36DF, 0x36E2, 0x36E5, 0x36E8, 0x36EB,
+                          0x36EF, 0x36F2, 0x36F5, 0x36F8, 0x36FC, 0x36FF, 0x3702,
+                          0x3705, 0x3708, 0x370C, 0x370F, 0x3712, 0x3715, 0x3718,
+                          0x371C, 0x371F, 0x3722, 0x3725, 0x3728, 0x372C, 0x372F,
+                          0x3732, 0x3735, 0x3738, 0x373B, 0x373F, 0x3742, 0x3745,
+                          0x3748, 0x374B, 0x374E, 0x3752, 0x3755, 0x3758, 0x375B,
+                          0x375E, 0x3761, 0x3765, 0x3768, 0x376B, 0x376E, 0x3771,
+                          0x3774, 0x3777, 0x377B, 0x377E, 0x3781, 0x3784, 0x3787,
+                          0x378A, 0x378D, 0x3790, 0x3794, 0x3797, 0x379A, 0x379D,
+                          0x37A0, 0x37A3, 0x37A6, 0x37A9, 0x37AC, 0x37B0, 0x37B3,
+                          0x37B6, 0x37B9, 0x37BC, 0x37BF, 0x37C2, 0x37C5, 0x37C8,
+                          0x37CB, 0x37CE, 0x37D1, 0x37D5, 0x37D8, 0x37DB, 0x37DE,
+                          0x37E1, 0x37E4, 0x37E7, 0x37EA, 0x37ED, 0x37F0, 0x37F3,
+                          0x37F6, 0x37F9, 0x37FC, 0x37FF, 0x3802, 0x3805, 0x3808,
+                          0x380B, 0x380F, 0x3812, 0x3815, 0x3818, 0x381B, 0x381E,
+                          0x3821, 0x3824, 0x3827, 0x382A, 0x382D, 0x3830, 0x3833,
+                          0x3836, 0x3839, 0x383C, 0x383F, 0x3842, 0x3845, 0x3848,
+                          0x384B, 0x384E, 0x3851, 0x3854, 0x3857, 0x385A, 0x385D,
+                          0x3860, 0x3863, 0x3866, 0x3869, 0x386B, 0x386E, 0x3871,
+                          0x3874, 0x3877, 0x387A, 0x387D, 0x3880, 0x3883, 0x3886,
+                          0x3889, 0x388C, 0x388F, 0x3892, 0x3895, 0x3898, 0x389B,
+                          0x389E, 0x38A1, 0x38A3, 0x38A6, 0x38A9, 0x38AC, 0x38AF,
+                          0x38B2, 0x38B5, 0x38B8, 0x38BB, 0x38BE, 0x38C1, 0x38C3,
+                          0x38C6, 0x38C9, 0x38CC, 0x38CF, 0x38D2, 0x38D5, 0x38D8,
+                          0x38DB, 0x38DE, 0x38E0, 0x38E3, 0x38E6, 0x38E9, 0x38EC,
+                          0x38EF, 0x38F2, 0x38F5, 0x38F7, 0x38FA, 0x38FD, 0x3900,
+                          0x3903, 0x3906, 0x3909, 0x390B, 0x390E, 0x3911, 0x3914,
+                          0x3917, 0x391A, 0x391C, 0x391F, 0x3922, 0x3925, 0x3928,
+                          0x392B, 0x392D, 0x3930, 0x3933, 0x3936, 0x3939, 0x393B,
+                          0x393E, 0x3941, 0x3944, 0x3947, 0x394A, 0x394C, 0x394F,
+                          0x3952, 0x3955, 0x3958, 0x395A, 0x395D, 0x3960, 0x3963,
+                          0x3965, 0x3968, 0x396B, 0x396E, 0x3971, 0x3973, 0x3976,
+                          0x3979, 0x397C, 0x397E, 0x3981, 0x3984, 0x3987, 0x3989,
+                          0x398C, 0x398F, 0x3992, 0x3994, 0x3997, 0x399A, 0x399D,
+                          0x399F, 0x39A2, 0x39A5, 0x39A8, 0x39AA, 0x39AD, 0x39B0,
+                          0x39B2, 0x39B5, 0x39B8, 0x39BB, 0x39BD, 0x39C0, 0x39C3,
+                          0x39C5, 0x39C8, 0x39CB, 0x39CE, 0x39D0, 0x39D3, 0x39D6,
+                          0x39D8, 0x39DB, 0x39DE, 0x39E0, 0x39E3, 0x39E6, 0x39E8,
+                          0x39EB, 0x39EE, 0x39F0, 0x39F3, 0x39F6, 0x39F8, 0x39FB,
+                          0x39FE, 0x3A00, 0x3A03, 0x3A06, 0x3A08, 0x3A0B, 0x3A0E,
+                          0x3A10, 0x3A13, 0x3A16, 0x3A18, 0x3A1B, 0x3A1D, 0x3A20,
+                          0x3A23, 0x3A25, 0x3A28, 0x3A2B, 0x3A2D, 0x3A30, 0x3A32,
+                          0x3A35, 0x3A38, 0x3A3A, 0x3A3D, 0x3A3F, 0x3A42, 0x3A45,
+                          0x3A47, 0x3A4A, 0x3A4C, 0x3A4F, 0x3A52, 0x3A54, 0x3A57,
+                          0x3A59, 0x3A5C, 0x3A5F, 0x3A61, 0x3A64, 0x3A66, 0x3A69,
+                          0x3A6B, 0x3A6E, 0x3A71, 0x3A73, 0x3A76, 0x3A78, 0x3A7B,
+                          0x3A7D, 0x3A80, 0x3A82, 0x3A85, 0x3A88, 0x3A8A, 0x3A8D,
+                          0x3A8F, 0x3A92, 0x3A94, 0x3A97, 0x3A99, 0x3A9C, 0x3A9E,
+                          0x3AA1, 0x3AA3, 0x3AA6, 0x3AA8, 0x3AAB, 0x3AAD, 0x3AB0,
+                          0x3AB2, 0x3AB5, 0x3AB7, 0x3ABA, 0x3ABC, 0x3ABF, 0x3AC1,
+                          0x3AC4, 0x3AC6, 0x3AC9, 0x3ACB, 0x3ACE, 0x3AD0, 0x3AD3,
+                          0x3AD5, 0x3AD8, 0x3ADA, 0x3ADD, 0x3ADF, 0x3AE2, 0x3AE4,
+                          0x3AE6, 0x3AE9, 0x3AEB, 0x3AEE, 0x3AF0, 0x3AF3, 0x3AF5,
+                          0x3AF8, 0x3AFA, 0x3AFD, 0x3AFF, 0x3B01, 0x3B04, 0x3B06,
+                          0x3B09, 0x3B0B, 0x3B0E, 0x3B10, 0x3B12, 0x3B15, 0x3B17,
+                          0x3B1A, 0x3B1C, 0x3B1E, 0x3B21, 0x3B23, 0x3B26, 0x3B28,
+                          0x3B2A, 0x3B2D, 0x3B2F, 0x3B32, 0x3B34, 0x3B36, 0x3B39,
+                          0x3B3B, 0x3B3E, 0x3B40, 0x3B42, 0x3B45, 0x3B47, 0x3B49,
+                          0x3B4C, 0x3B4E, 0x3B50, 0x3B53, 0x3B55, 0x3B58, 0x3B5A,
+                          0x3B5C, 0x3B5F, 0x3B61, 0x3B63, 0x3B66, 0x3B68, 0x3B6A,
+                          0x3B6D, 0x3B6F, 0x3B71, 0x3B74, 0x3B76, 0x3B78, 0x3B7B,
+                          0x3B7D, 0x3B7F, 0x3B82, 0x3B84, 0x3B86, 0x3B88, 0x3B8B,
+                          0x3B8D, 0x3B8F, 0x3B92, 0x3B94, 0x3B96, 0x3B99, 0x3B9B,
+                          0x3B9D, 0x3B9F, 0x3BA2, 0x3BA4, 0x3BA6, 0x3BA9, 0x3BAB,
+                          0x3BAD, 0x3BAF, 0x3BB2, 0x3BB4, 0x3BB6, 0x3BB8, 0x3BBB,
+                          0x3BBD, 0x3BBF, 0x3BC1, 0x3BC4, 0x3BC6, 0x3BC8, 0x3BCA,
+                          0x3BCD, 0x3BCF, 0x3BD1, 0x3BD3, 0x3BD6, 0x3BD8, 0x3BDA,
+                          0x3BDC, 0x3BDE, 0x3BE1, 0x3BE3, 0x3BE5, 0x3BE7, 0x3BEA,
+                          0x3BEC, 0x3BEE, 0x3BF0, 0x3BF2, 0x3BF5, 0x3BF7, 0x3BF9,
+                          0x3BFB, 0x3BFD, 0x3C00, 0x3C02, 0x3C04, 0x3C06, 0x3C08,
+                          0x3C0A, 0x3C0D, 0x3C0F, 0x3C11, 0x3C13, 0x3C15, 0x3C17,
+                          0x3C1A, 0x3C1C, 0x3C1E, 0x3C20, 0x3C22, 0x3C24, 0x3C27,
+                          0x3C29, 0x3C2B, 0x3C2D, 0x3C2F, 0x3C31, 0x3C33, 0x3C36,
+                          0x3C38, 0x3C3A, 0x3C3C, 0x3C3E, 0x3C40, 0x3C42, 0x3C44,
+                          0x3C46, 0x3C49, 0x3C4B, 0x3C4D, 0x3C4F, 0x3C51, 0x3C53,
+                          0x3C55, 0x3C57, 0x3C59, 0x3C5B, 0x3C5E, 0x3C60, 0x3C62,
+                          0x3C64, 0x3C66, 0x3C68, 0x3C6A, 0x3C6C, 0x3C6E, 0x3C70,
+                          0x3C72, 0x3C74, 0x3C76, 0x3C79, 0x3C7B, 0x3C7D, 0x3C7F,
+                          0x3C81, 0x3C83, 0x3C85, 0x3C87, 0x3C89, 0x3C8B, 0x3C8D,
+                          0x3C8F, 0x3C91, 0x3C93, 0x3C95, 0x3C97, 0x3C99, 0x3C9B,
+                          0x3C9D, 0x3C9F, 0x3CA1, 0x3CA3, 0x3CA5, 0x3CA7, 0x3CA9,
+                          0x3CAB, 0x3CAD, 0x3CAF, 0x3CB1, 0x3CB3, 0x3CB5, 0x3CB7,
+                          0x3CB9, 0x3CBB, 0x3CBD, 0x3CBF, 0x3CC1, 0x3CC3, 0x3CC5,
+                          0x3CC7, 0x3CC9, 0x3CCB, 0x3CCD, 0x3CCF, 0x3CD1, 0x3CD3,
+                          0x3CD5, 0x3CD7, 0x3CD9, 0x3CDB, 0x3CDD, 0x3CDE, 0x3CE0,
+                          0x3CE2, 0x3CE4, 0x3CE6, 0x3CE8, 0x3CEA, 0x3CEC, 0x3CEE,
+                          0x3CF0, 0x3CF2, 0x3CF4, 0x3CF6, 0x3CF8, 0x3CF9, 0x3CFB,
+                          0x3CFD, 0x3CFF, 0x3D01, 0x3D03, 0x3D05, 0x3D07, 0x3D09,
+                          0x3D0B, 0x3D0C, 0x3D0E, 0x3D10, 0x3D12, 0x3D14, 0x3D16,
+                          0x3D18, 0x3D1A, 0x3D1B, 0x3D1D, 0x3D1F, 0x3D21, 0x3D23,
+                          0x3D25, 0x3D27, 0x3D28, 0x3D2A, 0x3D2C, 0x3D2E, 0x3D30,
+                          0x3D32, 0x3D34, 0x3D35, 0x3D37, 0x3D39, 0x3D3B, 0x3D3D,
+                          0x3D3F, 0x3D40, 0x3D42, 0x3D44, 0x3D46, 0x3D48, 0x3D49,
+                          0x3D4B, 0x3D4D, 0x3D4F, 0x3D51, 0x3D52, 0x3D54, 0x3D56,
+                          0x3D58, 0x3D5A, 0x3D5B, 0x3D5D, 0x3D5F, 0x3D61, 0x3D63,
+                          0x3D64, 0x3D66, 0x3D68, 0x3D6A, 0x3D6B, 0x3D6D, 0x3D6F,
+                          0x3D71, 0x3D72, 0x3D74, 0x3D76, 0x3D78, 0x3D79, 0x3D7B,
+                          0x3D7D, 0x3D7F, 0x3D80, 0x3D82, 0x3D84, 0x3D86, 0x3D87,
+                          0x3D89, 0x3D8B, 0x3D8D, 0x3D8E, 0x3D90, 0x3D92, 0x3D93,
+                          0x3D95, 0x3D97, 0x3D99, 0x3D9A, 0x3D9C, 0x3D9E, 0x3D9F,
+                          0x3DA1, 0x3DA3, 0x3DA4, 0x3DA6, 0x3DA8, 0x3DA9, 0x3DAB,
+                          0x3DAD, 0x3DAF, 0x3DB0, 0x3DB2, 0x3DB4, 0x3DB5, 0x3DB7,
+                          0x3DB9, 0x3DBA, 0x3DBC, 0x3DBD, 0x3DBF, 0x3DC1, 0x3DC2,
+                          0x3DC4, 0x3DC6, 0x3DC7, 0x3DC9, 0x3DCB, 0x3DCC, 0x3DCE,
+                          0x3DD0, 0x3DD1, 0x3DD3, 0x3DD4, 0x3DD6, 0x3DD8, 0x3DD9,
+                          0x3DDB, 0x3DDD, 0x3DDE, 0x3DE0, 0x3DE1, 0x3DE3, 0x3DE5,
+                          0x3DE6, 0x3DE8, 0x3DE9, 0x3DEB, 0x3DED, 0x3DEE, 0x3DF0,
+                          0x3DF1, 0x3DF3, 0x3DF4, 0x3DF6, 0x3DF8, 0x3DF9, 0x3DFB,
+                          0x3DFC, 0x3DFE, 0x3DFF, 0x3E01, 0x3E03, 0x3E04, 0x3E06,
+                          0x3E07, 0x3E09, 0x3E0A, 0x3E0C, 0x3E0D, 0x3E0F, 0x3E10,
+                          0x3E12, 0x3E13, 0x3E15, 0x3E17, 0x3E18, 0x3E1A, 0x3E1B,
+                          0x3E1D, 0x3E1E, 0x3E20, 0x3E21, 0x3E23, 0x3E24, 0x3E26,
+                          0x3E27, 0x3E29, 0x3E2A, 0x3E2C, 0x3E2D, 0x3E2F, 0x3E30,
+                          0x3E32, 0x3E33, 0x3E35, 0x3E36, 0x3E37, 0x3E39, 0x3E3A,
+                          0x3E3C, 0x3E3D, 0x3E3F, 0x3E40, 0x3E42, 0x3E43, 0x3E45,
+                          0x3E46, 0x3E48, 0x3E49, 0x3E4A, 0x3E4C, 0x3E4D, 0x3E4F,
+                          0x3E50, 0x3E52, 0x3E53, 0x3E54, 0x3E56, 0x3E57, 0x3E59,
+                          0x3E5A, 0x3E5C, 0x3E5D, 0x3E5E, 0x3E60, 0x3E61, 0x3E63,
+                          0x3E64, 0x3E65, 0x3E67, 0x3E68, 0x3E6A, 0x3E6B, 0x3E6C,
+                          0x3E6E, 0x3E6F, 0x3E71, 0x3E72, 0x3E73, 0x3E75, 0x3E76,
+                          0x3E77, 0x3E79, 0x3E7A, 0x3E7B, 0x3E7D, 0x3E7E, 0x3E80,
+                          0x3E81, 0x3E82, 0x3E84, 0x3E85, 0x3E86, 0x3E88, 0x3E89,
+                          0x3E8A, 0x3E8C, 0x3E8D, 0x3E8E, 0x3E90, 0x3E91, 0x3E92,
+                          0x3E94, 0x3E95, 0x3E96, 0x3E98, 0x3E99, 0x3E9A, 0x3E9B,
+                          0x3E9D, 0x3E9E, 0x3E9F, 0x3EA1, 0x3EA2, 0x3EA3, 0x3EA5,
+                          0x3EA6, 0x3EA7, 0x3EA8, 0x3EAA, 0x3EAB, 0x3EAC, 0x3EAD,
+                          0x3EAF, 0x3EB0, 0x3EB1, 0x3EB3, 0x3EB4, 0x3EB5, 0x3EB6,
+                          0x3EB8, 0x3EB9, 0x3EBA, 0x3EBB, 0x3EBD, 0x3EBE, 0x3EBF,
+                          0x3EC0, 0x3EC1, 0x3EC3, 0x3EC4, 0x3EC5, 0x3EC6, 0x3EC8,
+                          0x3EC9, 0x3ECA, 0x3ECB, 0x3ECC, 0x3ECE, 0x3ECF, 0x3ED0,
+                          0x3ED1, 0x3ED3, 0x3ED4, 0x3ED5, 0x3ED6, 0x3ED7, 0x3ED8,
+                          0x3EDA, 0x3EDB, 0x3EDC, 0x3EDD, 0x3EDE, 0x3EE0, 0x3EE1,
+                          0x3EE2, 0x3EE3, 0x3EE4, 0x3EE5, 0x3EE7, 0x3EE8, 0x3EE9,
+                          0x3EEA, 0x3EEB, 0x3EEC, 0x3EED, 0x3EEF, 0x3EF0, 0x3EF1,
+                          0x3EF2, 0x3EF3, 0x3EF4, 0x3EF5, 0x3EF7, 0x3EF8, 0x3EF9,
+                          0x3EFA, 0x3EFB, 0x3EFC, 0x3EFD, 0x3EFE, 0x3F00, 0x3F01,
+                          0x3F02, 0x3F03, 0x3F04, 0x3F05, 0x3F06, 0x3F07, 0x3F08,
+                          0x3F09, 0x3F0A, 0x3F0C, 0x3F0D, 0x3F0E, 0x3F0F, 0x3F10,
+                          0x3F11, 0x3F12, 0x3F13, 0x3F14, 0x3F15, 0x3F16, 0x3F17,
+                          0x3F18, 0x3F19, 0x3F1A, 0x3F1C, 0x3F1D, 0x3F1E, 0x3F1F,
+                          0x3F20, 0x3F21, 0x3F22, 0x3F23, 0x3F24, 0x3F25, 0x3F26,
+                          0x3F27, 0x3F28, 0x3F29, 0x3F2A, 0x3F2B, 0x3F2C, 0x3F2D,
+                          0x3F2E, 0x3F2F, 0x3F30, 0x3F31, 0x3F32, 0x3F33, 0x3F34,
+                          0x3F35, 0x3F36, 0x3F37, 0x3F38, 0x3F39, 0x3F3A, 0x3F3B,
+                          0x3F3C, 0x3F3D, 0x3F3E, 0x3F3F, 0x3F40, 0x3F41, 0x3F42,
+                          0x3F42, 0x3F43, 0x3F44, 0x3F45, 0x3F46, 0x3F47, 0x3F48,
+                          0x3F49, 0x3F4A, 0x3F4B, 0x3F4C, 0x3F4D, 0x3F4E, 0x3F4F,
+                          0x3F50, 0x3F51, 0x3F51, 0x3F52, 0x3F53, 0x3F54, 0x3F55,
+                          0x3F56, 0x3F57, 0x3F58, 0x3F59, 0x3F5A, 0x3F5A, 0x3F5B,
+                          0x3F5C, 0x3F5D, 0x3F5E, 0x3F5F, 0x3F60, 0x3F61, 0x3F62,
+                          0x3F62, 0x3F63, 0x3F64, 0x3F65, 0x3F66, 0x3F67, 0x3F68,
+                          0x3F68, 0x3F69, 0x3F6A, 0x3F6B, 0x3F6C, 0x3F6D, 0x3F6D,
+                          0x3F6E, 0x3F6F, 0x3F70, 0x3F71, 0x3F72, 0x3F72, 0x3F73,
+                          0x3F74, 0x3F75, 0x3F76, 0x3F77, 0x3F77, 0x3F78, 0x3F79,
+                          0x3F7A, 0x3F7B, 0x3F7B, 0x3F7C, 0x3F7D, 0x3F7E, 0x3F7F,
+                          0x3F7F, 0x3F80, 0x3F81, 0x3F82, 0x3F82, 0x3F83, 0x3F84,
+                          0x3F85, 0x3F86, 0x3F86, 0x3F87, 0x3F88, 0x3F89, 0x3F89,
+                          0x3F8A, 0x3F8B, 0x3F8C, 0x3F8C, 0x3F8D, 0x3F8E, 0x3F8F,
+                          0x3F8F, 0x3F90, 0x3F91, 0x3F92, 0x3F92, 0x3F93, 0x3F94,
+                          0x3F94, 0x3F95, 0x3F96, 0x3F97, 0x3F97, 0x3F98, 0x3F99,
+                          0x3F99, 0x3F9A, 0x3F9B, 0x3F9B, 0x3F9C, 0x3F9D, 0x3F9E,
+                          0x3F9E, 0x3F9F, 0x3FA0, 0x3FA0, 0x3FA1, 0x3FA2, 0x3FA2,
+                          0x3FA3, 0x3FA4, 0x3FA4, 0x3FA5, 0x3FA6, 0x3FA6, 0x3FA7,
+                          0x3FA8, 0x3FA8, 0x3FA9, 0x3FAA, 0x3FAA, 0x3FAB, 0x3FAB,
+                          0x3FAC, 0x3FAD, 0x3FAD, 0x3FAE, 0x3FAF, 0x3FAF, 0x3FB0,
+                          0x3FB0, 0x3FB1, 0x3FB2, 0x3FB2, 0x3FB3, 0x3FB4, 0x3FB4,
+                          0x3FB5, 0x3FB5, 0x3FB6, 0x3FB7, 0x3FB7, 0x3FB8, 0x3FB8,
+                          0x3FB9, 0x3FB9, 0x3FBA, 0x3FBB, 0x3FBB, 0x3FBC, 0x3FBC,
+                          0x3FBD, 0x3FBE, 0x3FBE, 0x3FBF, 0x3FBF, 0x3FC0, 0x3FC0,
+                          0x3FC1, 0x3FC1, 0x3FC2, 0x3FC3, 0x3FC3, 0x3FC4, 0x3FC4,
+                          0x3FC5, 0x3FC5, 0x3FC6, 0x3FC6, 0x3FC7, 0x3FC7, 0x3FC8,
+                          0x3FC8, 0x3FC9, 0x3FC9, 0x3FCA, 0x3FCA, 0x3FCB, 0x3FCB,
+                          0x3FCC, 0x3FCC, 0x3FCD, 0x3FCD, 0x3FCE, 0x3FCE, 0x3FCF,
+                          0x3FCF, 0x3FD0, 0x3FD0, 0x3FD1, 0x3FD1, 0x3FD2, 0x3FD2,
+                          0x3FD3, 0x3FD3, 0x3FD4, 0x3FD4, 0x3FD5, 0x3FD5, 0x3FD5,
+                          0x3FD6, 0x3FD6, 0x3FD7, 0x3FD7, 0x3FD8, 0x3FD8, 0x3FD9,
+                          0x3FD9, 0x3FD9, 0x3FDA, 0x3FDA, 0x3FDB, 0x3FDB, 0x3FDC,
+                          0x3FDC, 0x3FDC, 0x3FDD, 0x3FDD, 0x3FDE, 0x3FDE, 0x3FDE,
+                          0x3FDF, 0x3FDF, 0x3FE0, 0x3FE0, 0x3FE0, 0x3FE1, 0x3FE1,
+                          0x3FE2, 0x3FE2, 0x3FE2, 0x3FE3, 0x3FE3, 0x3FE3, 0x3FE4,
+                          0x3FE4, 0x3FE5, 0x3FE5, 0x3FE5, 0x3FE6, 0x3FE6, 0x3FE6,
+                          0x3FE7, 0x3FE7, 0x3FE7, 0x3FE8, 0x3FE8, 0x3FE8, 0x3FE9,
+                          0x3FE9, 0x3FE9, 0x3FEA, 0x3FEA, 0x3FEA, 0x3FEB, 0x3FEB,
+                          0x3FEB, 0x3FEC, 0x3FEC, 0x3FEC, 0x3FED, 0x3FED, 0x3FED,
+                          0x3FED, 0x3FEE, 0x3FEE, 0x3FEE, 0x3FEF, 0x3FEF, 0x3FEF,
+                          0x3FF0, 0x3FF0, 0x3FF0, 0x3FF0, 0x3FF1, 0x3FF1, 0x3FF1,
+                          0x3FF1, 0x3FF2, 0x3FF2, 0x3FF2, 0x3FF2, 0x3FF3, 0x3FF3,
+                          0x3FF3, 0x3FF3, 0x3FF4, 0x3FF4, 0x3FF4, 0x3FF4, 0x3FF5,
+                          0x3FF5, 0x3FF5, 0x3FF5, 0x3FF6, 0x3FF6, 0x3FF6, 0x3FF6,
+                          0x3FF6, 0x3FF7, 0x3FF7, 0x3FF7, 0x3FF7, 0x3FF8, 0x3FF8,
+                          0x3FF8, 0x3FF8, 0x3FF8, 0x3FF8, 0x3FF9, 0x3FF9, 0x3FF9,
+                          0x3FF9, 0x3FF9, 0x3FFA, 0x3FFA, 0x3FFA, 0x3FFA, 0x3FFA,
+                          0x3FFA, 0x3FFB, 0x3FFB, 0x3FFB, 0x3FFB, 0x3FFB, 0x3FFB,
+                          0x3FFC, 0x3FFC, 0x3FFC, 0x3FFC, 0x3FFC, 0x3FFC, 0x3FFC,
+                          0x3FFC, 0x3FFD, 0x3FFD, 0x3FFD, 0x3FFD, 0x3FFD, 0x3FFD,
+                          0x3FFD, 0x3FFD, 0x3FFE, 0x3FFE, 0x3FFE, 0x3FFE, 0x3FFE,
+                          0x3FFE, 0x3FFE, 0x3FFE, 0x3FFE, 0x3FFE, 0x3FFF, 0x3FFF,
+                          0x3FFF, 0x3FFF, 0x3FFF, 0x3FFF, 0x3FFF, 0x3FFF, 0x3FFF,
+                          0x3FFF, 0x3FFF, 0x3FFF, 0x3FFF, 0x3FFF, 0x3FFF, 0x4000,
+                          0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000,
+                          0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000,
+                          0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0};

+ 105 - 0
src/jni/XML.cpp

@@ -0,0 +1,105 @@
+#include "CFTTFileSystem.h"
+#include "XML.h"
+#include "CMyProfile.h"
+#include "zlib.h"
+#include "memctrl.h"
+
+int dword_477E9C = 0;
+//-------------------------------------------------------------------------------------------------
+//001F5994 //^_^
+bool XMLExists(CFTTXmlReaderNode a, char const* pName, char const* pChildName) {
+  //loc_1F59C4
+  return false;
+}
+//-------------------------------------------------------------------------------------------------
+//001F5E80 //^_^ 经过单元测试,功能正常
+TPoint XMLGetPos(CFTTXmlReaderNode a, char const* pName, char const* pChildName, TPoint def) {
+  LOGI("XMLGetPos entry");
+  TPoint ret;
+  return def;
+}
+//-------------------------------------------------------------------------------------------------
+//001F5EBA //^_^
+TPointF XMLGetPosF(CFTTXmlReaderNode a, char const* pName, char const* pChildName, TPointF def) {
+  TPointF ret;
+  return ret;
+}
+//-------------------------------------------------------------------------------------------------
+//001F5EF4 //^_^
+TPointF3D XMLGetPosF3D(CFTTXmlReaderNode a, char const* pName, char const* pChildName, TPointF3D def) {
+  TPointF3D ret;
+  return ret;
+}
+//-------------------------------------------------------------------------------------------------
+//001F5F2A //^_^
+TPoint3D XMLGetPos3D(CFTTXmlReaderNode a, char const* pName, char const* pChildName, TPoint3D def) {
+  TPoint3D ret;
+  return ret;
+}
+//-------------------------------------------------------------------------------------------------
+//001F5F60 //^_^
+uint XMLGetColour(CFTTXmlReaderNode a, char const* pName, char const* pChildName, uint def) {
+  uint ret;
+  return ret;
+}
+//-------------------------------------------------------------------------------------------------
+//001F6030 //^_- 经过单元测试,功能正常
+int XMLGetInt(CFTTXmlReaderNode a, char const* pName, char const* pChildName, int def) {
+  LOGI("XMLGetInt entry");
+  return 0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F6108 //^_- 经过单元测试,功能正常
+float XMLGetFloat(CFTTXmlReaderNode a, char const* pName, char const* pChildName, float def) {
+  LOGI("XMLGetFloat entry");
+  return 0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F613A //^_^
+char* XMLGetString(CFTTXmlReaderNode a, char const* pName, char const* pChildName, char const* pdef) {
+  char* pret = (char*)pdef;
+  return pret;
+}
+//-------------------------------------------------------------------------------------------------
+//001F6160 //^_^
+int XMLGetStringInt(CFTTXmlReaderNode a, char const* pName, char const* pChildName, char const** plist, int count, int def) {
+  return 0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F6198
+void XMLAddString(char const* pAdd, CFTTXmlWriterNode a, char const* pName, char const* pChildName) {
+}
+//-------------------------------------------------------------------------------------------------
+//001F61CC
+void XMLAddString(wchar_t const* pWAdd, CFTTXmlWriterNode a, char const* pName, char const* pChildName) {
+}
+//-------------------------------------------------------------------------------------------------
+//001F6228
+void XMLAddPosF3D(TPointF3D t3d, CFTTXmlWriterNode a, char const* pName, char const* pChildName) {
+}
+//-------------------------------------------------------------------------------------------------
+//001F62B0
+void XMLAddPos3D(TPoint3D t3d, CFTTXmlWriterNode a, char const* pName, char const* pChildName) {
+}
+//-------------------------------------------------------------------------------------------------
+//001F6354 //^_-
+void XMLAddPos(TPoint pos, CFTTXmlWriterNode a, char const* pName, char const* pChildName) {
+}
+//-------------------------------------------------------------------------------------------------
+//001F63E0
+void XMLAddColour(uint dAdd, CFTTXmlWriterNode a, char const* pName, char const* pChildName) {
+}
+//-------------------------------------------------------------------------------------------------
+//001F6450
+void XMLAddInt(int dAdd, CFTTXmlWriterNode a, char const* pName, char const* pChildName) {
+}
+//-------------------------------------------------------------------------------------------------
+//001F64B4
+void XMLAddFloat(float fAdd, CFTTXmlWriterNode a, char const* pName, char const* pChildName) {
+}
+//-------------------------------------------------------------------------------------------------
+//001F6524 经过单元测试,功能正常
+bool XMLValidateFile(char const* pFilePath, char const* pName) {
+  return false;
+}
+//-------------------------------------------------------------------------------------------------

+ 87 - 0
src/jni/XML.h

@@ -0,0 +1,87 @@
+//XML - [2020-06-22 11:41:46]
+#ifndef _XML_H_
+#define _XML_H_
+
+#include "CFTTXmlReaderNode.h"
+#include "CFTTXmlWriterNode.h"
+
+/*
+001F5994 XMLExists(CFTTXmlReaderNode,char const*,char const*)
+001F5E80 XMLGetPos(CFTTXmlReaderNode,char const*,char const*,TPoint)
+001F5EBA XMLGetPosF(CFTTXmlReaderNode,char const*,char const*,TPointF)
+001F5EF4 XMLGetPosF3D(CFTTXmlReaderNode,char const*,char const*,TPointF3D)
+001F5F2A XMLGetPos3D(CFTTXmlReaderNode,char const*,char const*,TPoint3D)
+001F5F60 XMLGetColour(CFTTXmlReaderNode,char const*,char const*,uint)
+001F6030 XMLGetInt(CFTTXmlReaderNode,char const*,char const*,int)
+001F6108 XMLGetFloat(CFTTXmlReaderNode,char const*,char const*,float)
+001F613A XMLGetString(CFTTXmlReaderNode,char const*,char const*,char const*)
+001F6160 XMLGetStringInt(CFTTXmlReaderNode,char const*,char const*,char const**,int,int)
+001F6198 XMLAddString(char const*,CFTTXmlWriterNode,char const*,char const*)
+001F61CC XMLAddString(wchar_t const*,CFTTXmlWriterNode,char const*,char const*)
+001F6228 XMLAddPosF3D(TPointF3D,CFTTXmlWriterNode,char const*,char const*)
+001F62B0 XMLAddPos3D(TPoint3D,CFTTXmlWriterNode,char const*,char const*)
+001F6354 XMLAddPos(TPoint,CFTTXmlWriterNode,char const*,char const*)
+001F63E0 XMLAddColour(uint,CFTTXmlWriterNode,char const*,char const*)
+001F6450 XMLAddInt(int,CFTTXmlWriterNode,char const*,char const*)
+001F64B4 XMLAddFloat(float,CFTTXmlWriterNode,char const*,char const*)
+001F6524 XMLValidateFile(char const*,char const*)
+*/
+
+//001F5994
+bool XMLExists(CFTTXmlReaderNode a, char const* pName, char const* pChildName);
+
+//001F5E80
+TPoint XMLGetPos(CFTTXmlReaderNode, char const*, char const*, TPoint);
+
+//001F5EBA
+TPointF XMLGetPosF(CFTTXmlReaderNode, char const*, char const*, TPointF);
+
+//001F5EF4
+TPointF3D XMLGetPosF3D(CFTTXmlReaderNode, char const*, char const*, TPointF3D);
+
+//001F5F2A
+TPoint3D XMLGetPos3D(CFTTXmlReaderNode, char const*, char const*, TPoint3D);
+
+//001F5F60
+uint XMLGetColour(CFTTXmlReaderNode a, char const* pName, char const* pChildName, uint def);
+
+//001F6030
+int XMLGetInt(CFTTXmlReaderNode a, char const* pName, char const* pChildName, int def);
+
+//001F6108
+float XMLGetFloat(CFTTXmlReaderNode a, char const* pName, char const* pChildName, float def);
+
+//001F613A
+char* XMLGetString(CFTTXmlReaderNode a, char const* pName, char const* pChildName, char const* pdef);
+
+//001F6160
+int XMLGetStringInt(CFTTXmlReaderNode a, char const* pName, char const* pChildName, char const** plist, int count, int def);
+
+//001F6198
+void XMLAddString(char const* pAdd, CFTTXmlWriterNode a, char const* pName, char const* pChildName);
+
+//001F61CC
+void XMLAddString(wchar_t const* pWAdd, CFTTXmlWriterNode a, char const* pName, char const* pChildName);
+
+//001F6228
+void XMLAddPosF3D(TPointF3D, CFTTXmlWriterNode, char const*, char const*);
+
+//001F62B0
+void XMLAddPos3D(TPoint3D, CFTTXmlWriterNode, char const*, char const*);
+
+//001F6354
+void XMLAddPos(TPoint, CFTTXmlWriterNode, char const*, char const*);
+
+//001F63E0
+void XMLAddColour(uint, CFTTXmlWriterNode, char const*, char const*);
+
+//001F6450
+void XMLAddInt(int, CFTTXmlWriterNode, char const*, char const*);
+
+//001F64B4
+void XMLAddFloat(float, CFTTXmlWriterNode, char const*, char const*);
+
+//001F6524
+bool XMLValidateFile(char const*, char const*);
+
+#endif  //_XML_H_

+ 163 - 0
src/jni/XSYS.cpp

@@ -0,0 +1,163 @@
+#include "XSYS.h"
+#include "CFTTServerTime.h"
+#include "byte_301950.h"
+#include "str_conv.h"
+
+int rand_seed;
+int rand_seed_nosync;
+//-------------------------------------------------------------------------------------------------
+int randGetRange(uint32_t a1) {
+  if (a1 == 0)
+    return 0;
+
+  int v1 = byte_301950[rand_seed & 0x3FFF];
+  int v2 = byte_301950[(rand_seed + 1) & 0x3FFF];
+  int v3 = byte_301950[(rand_seed + 2) & 0x3FFF];
+  int v4 = byte_301950[(rand_seed++ + 3) & 0x3FFF];
+  return (v4 | (v2 << 16) | (v1 << 24) | (uint32)(v3 << 8)) * (uint64)a1 >> 32;
+}
+//-------------------------------------------------------------------------------------------------
+int randGetRangeSeed(int a1, uint32_t a2) {
+  int result;
+  if (a2)
+    result = ((byte_301950[(a1 + 1) & 0x3FFF] << 16) |
+              (byte_301950[a1 & 0x3FFF] << 24) |
+              (byte_301950[(a1 + 2) & 0x3FFF] << 8) |
+              (uint32)byte_301950[(a1 + 3) & 0x3FFF]) *
+                 (uint64)a2 >>
+             32;
+  else
+    result = 0;
+  return result;
+}
+//-------------------------------------------------------------------------------------------------
+//001F4ED0 //^_^
+int randGetRangeNoSync(uint a1) {
+  if (!a1)
+    return 0;
+
+  int v1 = byte_301950[rand_seed_nosync & 0x3FFF];
+  int v2 = byte_301950[(rand_seed_nosync + 1) & 0x3FFF];
+  int v3 = byte_301950[(rand_seed_nosync + 2) & 0x3FFF];
+  int v4 = byte_301950[(rand_seed_nosync++ + 3) & 0x3FFF];
+  return (v4 | (v2 << 16) | (v1 << 24) | (uint32)(v3 << 8)) * (uint64)a1 >> 32;
+}
+//-------------------------------------------------------------------------------------------------
+//001F472A //^_^
+void XSYS_GetCurrentMatchDateTime(TMatchDateTime *pdtime) {
+  CFTTServerTime::GetCurDateTime(&pdtime->year,  // int *pyear,
+                                 &pdtime->mon,   // int *pmon,
+                                 &pdtime->day,   // int *pmday,
+                                 &pdtime->wday,  // int *pwday,
+                                 &pdtime->hour,  // int *phour,
+                                 &pdtime->min,   // int *pmin,
+                                 nullptr,        // int *psec,
+                                 nullptr,        // int *pisdst,
+                                 false);         // bool isGMT
+}
+//-------------------------------------------------------------------------------------------------
+//001F4754 //^_^
+int XSYS_GetCurrentDay() {
+  int y, m, d;
+  CFTTServerTime::GetCurDateTime(&y, &m, &d, nullptr, nullptr, nullptr, nullptr, nullptr, false);
+  return 10000 * y + 100 * m + d;
+}
+//-------------------------------------------------------------------------------------------------
+//001F4790 //???
+float XSYS_GetSunPos(int, int, int, int, int, float, float, float &, float &) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F4B08 //???
+float XSYS_GetSunSetRiseTime(bool, int, int, int, float, float, int, int &, int &) {
+  return 0.0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F4F28 //^_^
+int XSYS_RandomFromSeed(int a1, int a2) {
+  if (!a2)
+    return 0;
+  if (a2 <= -1)
+    return -randGetRangeSeed(a1, -a2);
+  return randGetRangeSeed(a1, a2);
+}
+//-------------------------------------------------------------------------------------------------
+//001F4F44 //^_^
+int XSYS_Random(int a1) {
+  if (a1) {
+    if (a1 <= -1) {
+      return -randGetRange(-a1);
+    }
+    return randGetRange(a1);
+  }
+  // loc_1F4F5C
+  return 0;
+}
+//-------------------------------------------------------------------------------------------------
+//001F4F60 //^_^
+int XSYS_RandomNoSync(int a1) {
+  int result;
+  if (a1)
+    result = randGetRangeNoSync(a1);
+  else
+    result = 0;
+  return result;
+}
+//-------------------------------------------------------------------------------------------------
+//001F4F6C //^_^
+void XSYS_RandomSetSeed(char const *pstr) {
+  rand_seed = 0;
+  int i = 0;
+  char const *p = pstr;
+  while (*p) {
+    i += *(uint8 *)p;
+    rand_seed = i;
+    p++;
+  }
+}
+//-------------------------------------------------------------------------------------------------
+//001F4F8C //^_^
+void XSYS_RandomSetSeed(int seed) {
+  rand_seed = seed;
+}
+//-------------------------------------------------------------------------------------------------
+//001F4F9C //^_^
+int XSYS_RandomGetSeed() {
+  return rand_seed;
+}
+//-------------------------------------------------------------------------------------------------
+//001F4FAC //^_^
+void XSYS_RandomSetSeedNoSync(int seed) {
+  rand_seed_nosync = seed;
+}
+//-------------------------------------------------------------------------------------------------
+//001F4FBC //^_^
+int XSYS_RandomGetSeedNoSync() {
+  return rand_seed_nosync;
+}
+//-------------------------------------------------------------------------------------------------
+//001F5020 //^_^
+float XSYS_RandomF(float a1) {
+  return (float)((float)randGetRange(10240) / 10240.0) * a1;
+}
+//-------------------------------------------------------------------------------------------------
+//001F5050 //^_^
+float XSYS_RandomNoSyncF(float a1) {
+  return (float)((float)randGetRangeNoSync(0x2800) / 10240.0) * a1;
+}
+//-------------------------------------------------------------------------------------------------
+//001F5188 //^_^
+void XSYS_WriteMemHeapDump(int) {
+  // empty
+}
+//-------------------------------------------------------------------------------------------------
+//001F52E2 //^_^
+// XSYS_ReplaceExt((char *)haystack, ".dat", ".xlc");
+void XSYS_ReplaceExt(char *str, const char *pOldExt, const char *pNewExt) {
+}
+//-------------------------------------------------------------------------------------------------
+//001F5304 //^_^
+int XSYS_GetPlatformUsedMem() {
+  return 0;
+}
+//-------------------------------------------------------------------------------------------------

+ 39 - 0
src/jni/XSYS.h

@@ -0,0 +1,39 @@
+//XSYS - [2020-06-22 11:41:46]
+#ifndef _XSYS_H_
+#define _XSYS_H_
+
+#include "common.h"
+
+struct TMatchDateTime {
+  int year;
+  int mon;
+  int day;
+  int wday;
+  int hour;
+  int min;
+  int sec;
+  int isdst;
+};
+
+void XSYS_GetCurrentMatchDateTime(TMatchDateTime *);                                 //001F472A
+int XSYS_GetCurrentDay();                                                            //001F4754
+float XSYS_GetSunPos(int, int, int, int, int, float, float, float &, float &);       //001F4790
+float XSYS_GetSunSetRiseTime(bool, int, int, int, float, float, int, int &, int &);  //001F4B08
+int XSYS_RandomFromSeed(int, int);                                                   //001F4F28
+int XSYS_Random(int);                                                                //001F4F44
+int XSYS_RandomNoSync(int);                                                          //001F4F60
+void XSYS_RandomSetSeed(char const *pstr);                                           //001F4F6C
+void XSYS_RandomSetSeed(int seed);                                                   //001F4F8C
+int XSYS_RandomGetSeed();                                                            //001F4F9C
+void XSYS_RandomSetSeedNoSync(int);                                                  //001F4FAC
+int XSYS_RandomGetSeedNoSync();                                                      //001F4FBC
+float XSYS_RandomF(float a1);                                                        //001F5020
+float XSYS_RandomNoSyncF(float a1);                                                  //001F5050
+void XSYS_WriteMemHeapDump(int);                                                     //001F5188
+void XSYS_ReplaceExt(char *, char const *, char const *);                            //001F52E2
+int XSYS_GetPlatformUsedMem();                                                       //001F5304
+
+int randGetRangeNoSync(uint32_t a1);  //001F4ED0
+int randGetRange(uint32_t a1);        //001F4E78
+
+#endif  //_XSYS_H_

+ 5 - 0
src/jni/X_sCommFile.h

@@ -0,0 +1,5 @@
+#ifndef XSCOMMFILE_H_
+#define XSCOMMFILE_H_
+
+extern const char *X_sCommFile[1956];
+#endif

+ 758 - 0
src/jni/xsnprintf.cpp

@@ -0,0 +1,758 @@
+#include "xsnprintf.h"
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+//#include "debug.h"
+#include <ctype.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <errno.h>
+#include "log.h"
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#include "str_conv.h"
+
+#define likely(x)   __builtin_expect(!!(x), 1)  //gcc内置函数, 帮助编译器分支优化
+#define unlikely(x) __builtin_expect(!!(x), 0)
+
+/** add padding to string */
+static void print_pad(wchar_t** at, size_t* left, int* ret, wchar_t p, int num) {
+  while (num--) {
+    if (*left > 1) {
+      *(*at)++ = p;
+      (*left)--;
+    }
+    (*ret)++;
+  }
+}
+
+/** get negative symbol, 0 if none */
+static wchar_t get_negsign(int negative, int plus, int space) {
+  if (negative)
+    return L'-';
+  if (plus)
+    return L'+';
+  if (space)
+    return L' ';
+  return 0;
+}
+
+#define PRINT_DEC_BUFSZ 32 /* 20 is enough for 64 bit decimals */
+/** print decimal into buffer, returns length */
+static int print_dec(wchar_t* buf, int max, unsigned int value) {
+  int i = 0;
+  if (value == 0) {
+    if (max > 0) {
+      buf[0] = L'0';
+      i = 1;
+    }
+  } else
+    while (value && i < max) {
+      buf[i++] = L'0' + value % 10;
+      value /= 10;
+    }
+  return i;
+}
+
+/** print long decimal into buffer, returns length */
+static int print_dec_l(wchar_t* buf, int max, unsigned long value) {
+  int i = 0;
+  if (value == 0) {
+    if (max > 0) {
+      buf[0] = L'0';
+      i = 1;
+    }
+  } else
+    while (value && i < max) {
+      buf[i++] = L'0' + value % 10;
+      value /= 10;
+    }
+  return i;
+}
+
+/** print long decimal into buffer, returns length */
+static int print_dec_ll(wchar_t* buf, int max, unsigned long long value) {
+  int i = 0;
+  if (value == 0) {
+    if (max > 0) {
+      buf[0] = L'0';
+      i = 1;
+    }
+  } else
+    while (value && i < max) {
+      buf[i++] = L'0' + value % 10;
+      value /= 10;
+    }
+  return i;
+}
+
+/** print hex into buffer, returns length */
+static int print_hex(wchar_t* buf, int max, unsigned int value) {
+  const wchar_t* h = L"0123456789abcdef";
+  int i = 0;
+  if (value == 0) {
+    if (max > 0) {
+      buf[0] = L'0';
+      i = 1;
+    }
+  } else
+    while (value && i < max) {
+      buf[i++] = h[value & 0x0f];
+      value >>= 4;
+    }
+  return i;
+}
+
+/** print long hex into buffer, returns length */
+static int print_hex_l(wchar_t* buf, int max, unsigned long value) {
+  const wchar_t* h = L"0123456789abcdef";
+  int i = 0;
+  if (value == 0) {
+    if (max > 0) {
+      buf[0] = L'0';
+      i = 1;
+    }
+  } else
+    while (value && i < max) {
+      buf[i++] = h[value & 0x0f];
+      value >>= 4;
+    }
+  return i;
+}
+
+/** print long long hex into buffer, returns length */
+static int print_hex_ll(wchar_t* buf, int max, unsigned long long value) {
+  const wchar_t* h = L"0123456789abcdef";
+  int i = 0;
+  if (value == 0) {
+    if (max > 0) {
+      buf[0] = '0';
+      i = 1;
+    }
+  } else
+    while (value && i < max) {
+      buf[i++] = h[value & 0x0f];
+      value >>= 4;
+    }
+  return i;
+}
+
+/** copy string into result, reversed */
+static void spool_str_rev(wchar_t** at, size_t* left, int* ret, const wchar_t* buf, int len) {
+  int i = len;
+  while (i) {
+    if (*left > 1) {
+      *(*at)++ = buf[--i];
+      (*left)--;
+    } else
+      --i;
+    (*ret)++;
+  }
+}
+
+/** copy string into result */
+static void spool_str(wchar_t** at, size_t* left, int* ret, const wchar_t* buf, int len) {
+  int i;
+  for (i = 0; i < len; i++) {
+    if (*left > 1) {
+      *(*at)++ = buf[i];
+      (*left)--;
+    }
+    (*ret)++;
+  }
+}
+
+/** print number formatted */
+static void print_num(wchar_t** at, size_t* left, int* ret, int minw, int precision,
+                      int prgiven, int zeropad, int minus, int plus, int space,
+                      int zero, int negative, wchar_t* buf, int len) {
+  int w = len; /* excludes minus sign */
+  wchar_t s = get_negsign(negative, plus, space);
+  if (minus) {
+    /* left adjust the number into the field, space padding */
+    /* calc numw = [sign][zeroes][number] */
+    int numw = w;
+    if (precision == 0 && zero) numw = 0;
+    if (numw < precision) numw = precision;
+    if (s) numw++;
+
+    /* sign */
+    if (s) print_pad(at, left, ret, s, 1);
+
+    /* number */
+    if (precision == 0 && zero) {
+      /* "" for the number */
+    } else {
+      if (w < precision)
+        print_pad(at, left, ret, L'0', precision - w);
+      spool_str_rev(at, left, ret, buf, len);
+    }
+    /* spaces */
+    if (numw < minw)
+      print_pad(at, left, ret, L' ', minw - numw);
+  } else {
+    /* pad on the left of the number */
+    /* calculate numw has width of [sign][zeroes][number] */
+    int numw = w;
+    if (precision == 0 && zero) numw = 0;
+    if (numw < precision) numw = precision;
+    if (!prgiven && zeropad && numw < minw)
+      numw = minw;
+    else if (s)
+      numw++;
+
+    /* pad with spaces */
+    if (numw < minw)
+      print_pad(at, left, ret, L' ', minw - numw);
+    /* print sign (and one less zeropad if so) */
+    if (s) {
+      print_pad(at, left, ret, s, 1);
+      numw--;
+    }
+    /* pad with zeroes */
+    if (w < numw)
+      print_pad(at, left, ret, L'0', numw - w);
+    if (precision == 0 && zero)
+      return;
+    /* print the characters for the value */
+    spool_str_rev(at, left, ret, buf, len);
+  }
+}
+
+/** print %d and %i */
+static void
+print_num_d(wchar_t** at, size_t* left, int* ret, int value,
+            int minw, int precision, int prgiven, int zeropad, int minus,
+            int plus, int space) {
+  wchar_t buf[PRINT_DEC_BUFSZ];
+  int negative = (value < 0);
+  int zero = (value == 0);
+  int len = print_dec(buf, (int)sizeof(buf),
+                      (unsigned int)(negative ? -value : value));
+  print_num(at, left, ret, minw, precision, prgiven, zeropad, minus,
+            plus, space, zero, negative, buf, len);
+}
+
+/** print %ld and %li */
+static void
+print_num_ld(wchar_t** at, size_t* left, int* ret, long value,
+             int minw, int precision, int prgiven, int zeropad, int minus,
+             int plus, int space) {
+  wchar_t buf[PRINT_DEC_BUFSZ];
+  int negative = (value < 0);
+  int zero = (value == 0);
+  int len = print_dec_l(buf, (int)sizeof(buf),
+                        (unsigned long)(negative ? -value : value));
+  print_num(at, left, ret, minw, precision, prgiven, zeropad, minus,
+            plus, space, zero, negative, buf, len);
+}
+
+/** print %lld and %lli */
+static void
+print_num_lld(wchar_t** at, size_t* left, int* ret, long long value,
+              int minw, int precision, int prgiven, int zeropad, int minus,
+              int plus, int space) {
+  wchar_t buf[PRINT_DEC_BUFSZ];
+  int negative = (value < 0);
+  int zero = (value == 0);
+  int len = print_dec_ll(buf, (int)sizeof(buf),
+                         (unsigned long long)(negative ? -value : value));
+  print_num(at, left, ret, minw, precision, prgiven, zeropad, minus,
+            plus, space, zero, negative, buf, len);
+}
+
+/** print %u */
+static void
+print_num_u(wchar_t** at, size_t* left, int* ret, unsigned int value,
+            int minw, int precision, int prgiven, int zeropad, int minus,
+            int plus, int space) {
+  wchar_t buf[PRINT_DEC_BUFSZ];
+  int negative = 0;
+  int zero = (value == 0);
+  int len = print_dec(buf, (int)sizeof(buf), value);
+  print_num(at, left, ret, minw, precision, prgiven, zeropad, minus,
+            plus, space, zero, negative, buf, len);
+}
+
+/** print %lu */
+static void
+print_num_lu(wchar_t** at, size_t* left, int* ret, unsigned long value,
+             int minw, int precision, int prgiven, int zeropad, int minus,
+             int plus, int space) {
+  wchar_t buf[PRINT_DEC_BUFSZ];
+  int negative = 0;
+  int zero = (value == 0);
+  int len = print_dec_l(buf, (int)sizeof(buf), value);
+  print_num(at, left, ret, minw, precision, prgiven, zeropad, minus,
+            plus, space, zero, negative, buf, len);
+}
+
+/** print %llu */
+static void
+print_num_llu(wchar_t** at, size_t* left, int* ret, unsigned long long value,
+              int minw, int precision, int prgiven, int zeropad, int minus,
+              int plus, int space) {
+  wchar_t buf[PRINT_DEC_BUFSZ];
+  int negative = 0;
+  int zero = (value == 0);
+  int len = print_dec_ll(buf, (int)sizeof(buf), value);
+  print_num(at, left, ret, minw, precision, prgiven, zeropad, minus,
+            plus, space, zero, negative, buf, len);
+}
+
+/** print %x */
+static void
+print_num_x(wchar_t** at, size_t* left, int* ret, unsigned int value,
+            int minw, int precision, int prgiven, int zeropad, int minus,
+            int plus, int space) {
+  wchar_t buf[PRINT_DEC_BUFSZ];
+  int negative = 0;
+  int zero = (value == 0);
+  int len = print_hex(buf, (int)sizeof(buf), value);
+  print_num(at, left, ret, minw, precision, prgiven, zeropad, minus,
+            plus, space, zero, negative, buf, len);
+}
+
+/** print %lx */
+static void
+print_num_lx(wchar_t** at, size_t* left, int* ret, unsigned long value,
+             int minw, int precision, int prgiven, int zeropad, int minus,
+             int plus, int space) {
+  wchar_t buf[PRINT_DEC_BUFSZ];
+  int negative = 0;
+  int zero = (value == 0);
+  int len = print_hex_l(buf, (int)sizeof(buf), value);
+  print_num(at, left, ret, minw, precision, prgiven, zeropad, minus,
+            plus, space, zero, negative, buf, len);
+}
+
+/** print %llx */
+static void
+print_num_llx(wchar_t** at, size_t* left, int* ret, unsigned long long value,
+              int minw, int precision, int prgiven, int zeropad, int minus,
+              int plus, int space) {
+  wchar_t buf[PRINT_DEC_BUFSZ];
+  int negative = 0;
+  int zero = (value == 0);
+  int len = print_hex_ll(buf, (int)sizeof(buf), value);
+  print_num(at, left, ret, minw, precision, prgiven, zeropad, minus,
+            plus, space, zero, negative, buf, len);
+}
+
+/** print %llp */
+static void
+print_num_llp(wchar_t** at, size_t* left, int* ret, void* value,
+              int minw, int precision, int prgiven, int zeropad, int minus,
+              int plus, int space) {
+  wchar_t buf[PRINT_DEC_BUFSZ];
+  int negative = 0;
+  int zero = (value == 0);
+#if defined(UINTPTR_MAX) && defined(UINT32_MAX) && (UINTPTR_MAX == UINT32_MAX)
+  /* avoid warning about upcast on 32bit systems */
+  unsigned long long llvalue = (unsigned long)value;
+#else
+  unsigned long long llvalue = (unsigned long long)value;
+#endif
+  int len = print_hex_ll(buf, (int)sizeof(buf), llvalue);
+  if (zero) {
+    buf[0] = ')';
+    buf[1] = 'l';
+    buf[2] = 'i';
+    buf[3] = 'n';
+    buf[4] = '(';
+    len = 5;
+  } else {
+    /* put '0x' in front of the (reversed) buffer result */
+    if (len < PRINT_DEC_BUFSZ)
+      buf[len++] = 'x';
+    if (len < PRINT_DEC_BUFSZ)
+      buf[len++] = '0';
+  }
+  print_num(at, left, ret, minw, precision, prgiven, zeropad, minus,
+            plus, space, zero, negative, buf, len);
+}
+
+#define PRINT_FLOAT_BUFSZ 64 /* xx.yy with 20.20 about the max */
+/** spool remainder after the decimal point to buffer, in reverse */
+static int
+print_remainder(wchar_t* buf, int max, double r, int prec) {
+  unsigned long long cap = 1;
+  unsigned long long value;
+  int len, i;
+  if (prec > 19) prec = 19; /* max we can do */
+  if (max < prec) return 0;
+  for (i = 0; i < prec; i++) {
+    cap *= 10;
+  }
+  r *= (double)cap;
+  value = (unsigned long long)r;
+  /* see if we need to round up */
+  if (((unsigned long long)((r - (double)value) * 10.0)) >= 5) {
+    value++;
+    /* that might carry to numbers before the comma, if so,
+     * just ignore that rounding. failure because 64bitprintout */
+    if (value >= cap)
+      value = cap - 1;
+  }
+  len = print_dec_ll(buf, max, value);
+  while (len < prec) { /* pad with zeroes, e.g. if 0.0012 */
+    buf[len++] = '0';
+  }
+  if (len < max)
+    buf[len++] = '.';
+  return len;
+}
+
+/** spool floating point to buffer */
+static int
+print_float(wchar_t* buf, int max, double value, int prec) {
+  /* as xxx.xxx  if prec==0, no '.', with prec decimals after . */
+  /* no conversion for NAN and INF, because we do not want to require
+     linking with -lm. */
+  /* Thus, the conversions use 64bit integers to convert the numbers,
+   * which makes 19 digits before and after the decimal point the max */
+  unsigned long long whole = (unsigned long long)value;
+  double remain = value - (double)whole;
+  int len = 0;
+  if (prec != 0)
+    len = print_remainder(buf, max, remain, prec);
+  len += print_dec_ll(buf + len, max - len, whole);
+  return len;
+}
+
+/** print %f */
+static void
+print_num_f(wchar_t** at, size_t* left, int* ret, double value,
+            int minw, int precision, int prgiven, int zeropad, int minus,
+            int plus, int space) {
+  wchar_t buf[PRINT_FLOAT_BUFSZ];
+  int negative = (value < 0);
+  int zero = 0;
+  int len;
+  if (!prgiven) precision = 6;
+  len = print_float(buf, (int)sizeof(buf), negative ? -value : value,
+                    precision);
+  print_num(at, left, ret, minw, 1, 0, zeropad, minus,
+            plus, space, zero, negative, buf, len);
+}
+
+/* rudimentary %g support */
+static int
+print_float_g(wchar_t* buf, int max, double value, int prec) {
+  unsigned long long whole = (unsigned long long)value;
+  double remain = value - (double)whole;
+  int before = 0;
+  int len = 0;
+
+  /* number of digits before the decimal point */
+  while (whole > 0) {
+    before++;
+    whole /= 10;
+  }
+  whole = (unsigned long long)value;
+
+  if (prec > before && remain != 0.0) {
+    /* see if the last decimals are zero, if so, skip them */
+    len = print_remainder(buf, max, remain, prec - before);
+    while (len > 0 && buf[0] == '0') {
+      memmove(buf, buf + 1, --len);
+    }
+  }
+  len += print_dec_ll(buf + len, max - len, whole);
+  return len;
+}
+
+/** print %g */
+static void
+print_num_g(wchar_t** at, size_t* left, int* ret, double value,
+            int minw, int precision, int prgiven, int zeropad, int minus,
+            int plus, int space) {
+  wchar_t buf[PRINT_FLOAT_BUFSZ];
+  int negative = (value < 0);
+  int zero = 0;
+  int len;
+  if (!prgiven) precision = 6;
+  if (precision == 0) precision = 1;
+  len = print_float_g(buf, (int)sizeof(buf), negative ? -value : value,
+                      precision);
+  print_num(at, left, ret, minw, 1, 0, zeropad, minus,
+            plus, space, zero, negative, buf, len);
+}
+
+/** strnlen (compat implementation) */
+static int
+my_strnlen(const wchar_t* s, int max) {
+  int i;
+  for (i = 0; i < max; i++)
+    if (s[i] == 0)
+      return i;
+  return max;
+}
+
+/** print %s */
+static void
+print_str(wchar_t** at, size_t* left, int* ret, wchar_t* s,
+          int minw, int precision, int prgiven, int minus) {
+  int w;
+  /* with prec: no more than x characters from this string, stop at 0 */
+  if (prgiven)
+    w = my_strnlen(s, precision);
+  else
+    w = xstrlen(s); /* up to the nul */
+  if (w < minw && !minus)
+    print_pad(at, left, ret, ' ', minw - w);
+  spool_str(at, left, ret, s, w);
+  if (w < minw && minus)
+    print_pad(at, left, ret, ' ', minw - w);
+}
+
+/** print %c */
+static void
+print_char(wchar_t** at, size_t* left, int* ret, int c,
+           int minw, int minus) {
+  if (1 < minw && !minus)
+    print_pad(at, left, ret, ' ', minw - 1);
+  print_pad(at, left, ret, c, 1);
+  if (1 < minw && minus)
+    print_pad(at, left, ret, ' ', minw - 1);
+}
+
+/**
+ * Print to string.
+ * str: string buffer for result. result will be null terminated.
+ * size: size of the buffer. null is put inside buffer.
+ * format: printf format string.
+ * arg: '...' arguments to print.
+ * returns number of characters. a null is printed after this.
+ * return number of bytes that would have been written
+ *	   if the buffer had been large enough.
+ *
+ * supported format specifiers:
+ * 	%s, %u, %d, %x, %i, %f, %g, %c, %p, %n.
+ * 	length: l, ll (for d, u, x).
+ * 	precision: 6.6d (for d, u, x)
+ * 		%f, %g precisions, 0.3f
+ * 		%20s, '.*s'
+ * 	and %%.
+ */
+//static
+int xvsnprintf(wchar_t* str, size_t size, const wchar_t* format, va_list arg) {
+  wchar_t* at = str;
+  size_t left = size;
+  int ret = 0;
+  const wchar_t* fmt = format;
+  int conv, minw, precision, prgiven, zeropad, minus, plus, space, length;
+  while (*fmt) {
+    /* copy string before % */
+    while (*fmt && *fmt != L'%') {
+      if (left > 1) {
+        *at++ = *fmt++;
+        left--;
+      } else
+        fmt++;
+      ret++;
+    }
+
+    /* see if we are at end */
+    if (!*fmt) break;
+
+    /* fetch next argument % designation from format string */
+    fmt++; /* skip the '%' */
+
+    /********************************/
+    /* get the argument designation */
+    /********************************/
+    /* we must do this vararg stuff inside this function for
+     * portability.  Hence, get_designation, and print_designation
+     * are not their own functions. */
+
+    /* printout designation:
+     * conversion specifier: x, d, u, s, c, n, m, p
+     * flags: # not supported
+     *        0 zeropad (on the left)
+     *	  - left adjust (right by default)
+     *	  ' ' printspace for positive number (in - position).
+     *	  + alwayssign
+     * fieldwidth: [1-9][0-9]* minimum field width.
+     * 	if this is * then type int next argument specifies the minwidth.
+     * 	if this is negative, the - flag is set (with positive width).
+     * precision: period[digits]*, %.2x.
+     * 	if this is * then type int next argument specifies the precision.
+     *	just '.' or negative value means precision=0.
+     *		this is mindigits to print for d, i, u, x
+     *		this is aftercomma digits for f
+     *		this is max number significant digits for g
+     *		maxnumber characters to be printed for s
+     * length: 0-none (int), 1-l (long), 2-ll (long long)
+     * 	notsupported: hh (char), h (short), L (long double), q, j, z, t
+     * Does not support %m$ and *m$ argument designation as array indices.
+     * Does not support %#x
+     *
+     */
+    minw = 0;
+    precision = 1;
+    prgiven = 0;
+    zeropad = 0;
+    minus = 0;
+    plus = 0;
+    space = 0;
+    length = 0;
+
+    /* get flags in any order */
+    for (;;) {
+      if (*fmt == L'0')
+        zeropad = 1;
+      else if (*fmt == L'-')
+        minus = 1;
+      else if (*fmt == L'+')
+        plus = 1;
+      else if (*fmt == L' ')
+        space = 1;
+      else
+        break;
+      fmt++;
+    }
+
+    /* field width */
+    if (*fmt == L'*') {
+      fmt++; /* skip char */
+      minw = va_arg(arg, int);
+      if (minw < 0) {
+        minus = 1;
+        minw = -minw;
+      }
+    } else
+      while (*fmt >= L'0' && *fmt <= L'9') {
+        minw = minw * 10 + (*fmt++) - L'0';
+      }
+
+    /* precision */
+    if (*fmt == L'.') {
+      fmt++; /* skip period */
+      prgiven = 1;
+      precision = 0;
+      if (*fmt == L'*') {
+        fmt++; /* skip char */
+        precision = va_arg(arg, int);
+        if (precision < 0)
+          precision = 0;
+      } else
+        while (*fmt >= L'0' && *fmt <= L'9') {
+          precision = precision * 10 + (*fmt++) - L'0';
+        }
+    }
+
+    /* length */
+    if (*fmt == L'l') {
+      fmt++; /* skip char */
+      length = 1;
+      if (*fmt == L'l') {
+        fmt++; /* skip char */
+        length = 2;
+      }
+    }
+
+    /* get the conversion */
+    if (!*fmt)
+      conv = 0;
+    else
+      conv = *fmt++;
+
+    /***********************************/
+    /* print that argument designation */
+    /***********************************/
+    switch (conv) {
+      case L'i':
+      case L'd':
+        if (length == 0)
+          print_num_d(&at, &left, &ret, va_arg(arg, int),
+                      minw, precision, prgiven, zeropad, minus, plus, space);
+        else if (length == 1)
+          print_num_ld(&at, &left, &ret, va_arg(arg, long),
+                       minw, precision, prgiven, zeropad, minus, plus, space);
+        else if (length == 2)
+          print_num_lld(&at, &left, &ret,
+                        va_arg(arg, long long),
+                        minw, precision, prgiven, zeropad, minus, plus, space);
+        break;
+      case L'u':
+        if (length == 0)
+          print_num_u(&at, &left, &ret,
+                      va_arg(arg, unsigned int),
+                      minw, precision, prgiven, zeropad, minus, plus, space);
+        else if (length == 1)
+          print_num_lu(&at, &left, &ret,
+                       va_arg(arg, unsigned long),
+                       minw, precision, prgiven, zeropad, minus, plus, space);
+        else if (length == 2)
+          print_num_llu(&at, &left, &ret,
+                        va_arg(arg, unsigned long long),
+                        minw, precision, prgiven, zeropad, minus, plus, space);
+        break;
+      case L'x':
+        if (length == 0)
+          print_num_x(&at, &left, &ret,
+                      va_arg(arg, unsigned int),
+                      minw, precision, prgiven, zeropad, minus, plus, space);
+        else if (length == 1)
+          print_num_lx(&at, &left, &ret,
+                       va_arg(arg, unsigned long),
+                       minw, precision, prgiven, zeropad, minus, plus, space);
+        else if (length == 2)
+          print_num_llx(&at, &left, &ret,
+                        va_arg(arg, unsigned long long),
+                        minw, precision, prgiven, zeropad, minus, plus, space);
+        break;
+      case L's':
+        print_str(&at, &left, &ret, va_arg(arg, wchar_t*),
+                  minw, precision, prgiven, minus);
+        break;
+      case L'c':
+        print_char(&at, &left, &ret, va_arg(arg, int),
+                   minw, minus);
+        break;
+      case L'n':
+        *va_arg(arg, int*) = ret;
+        break;
+      case L'm':
+        print_str(&at, &left, &ret, (wchar_t*)L"m", minw, precision, prgiven, minus);
+        break;
+      case L'p':
+        print_num_llp(&at, &left, &ret, va_arg(arg, void*),
+                      minw, precision, prgiven, zeropad, minus, plus, space);
+        break;
+      case L'%':
+        print_pad(&at, &left, &ret, '%', 1);
+        break;
+      case L'f':
+        print_num_f(&at, &left, &ret, va_arg(arg, double),
+                    minw, precision, prgiven, zeropad, minus, plus, space);
+        break;
+      case L'g':
+        print_num_g(&at, &left, &ret, va_arg(arg, double),
+                    minw, precision, prgiven, zeropad, minus, plus, space);
+        break;
+        /* unknown */
+      default:
+      case 0:
+        break;
+    }
+  }
+
+  /* zero terminate */
+  if (left > 0)
+    *at = 0;
+  return ret;
+}
+
+//xsnprintf(wchar_t*, unsigned int, wchar_t const*, ...)
+//002695D8 -_- 经过单元测试,功能正常
+size_t xsnprintf(wchar_t* buf, size_t len, const wchar_t* format, ...) {
+  va_list ap;
+  va_start(ap, format);
+  const size_t n = xvsnprintf(buf, len, format, ap);
+  va_end(ap);
+  return n;
+}

+ 10 - 0
src/jni/xsnprintf.h

@@ -0,0 +1,10 @@
+#ifndef _XSNPRINTF_H_
+#define _XSNPRINTF_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+
+//002695D8
+size_t xsnprintf(wchar_t* buf, size_t len, const wchar_t* format, ...);
+int xvsnprintf(wchar_t* str, size_t size, const wchar_t* format, va_list arg);
+#endif  //_XSNPRINTF_H_

+ 534 - 0
src/jni/zconf.h

@@ -0,0 +1,534 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZCONF_H
+#define ZCONF_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ * Even better than compiling with -DZ_PREFIX would be to use configure to set
+ * this permanently in zconf.h using "./configure --zprefix".
+ */
+#ifdef Z_PREFIX     /* may be set to #if 1 by ./configure */
+#  define Z_PREFIX_SET
+
+/* all linked symbols and init macros */
+#  define _dist_code            z__dist_code
+#  define _length_code          z__length_code
+#  define _tr_align             z__tr_align
+#  define _tr_flush_bits        z__tr_flush_bits
+#  define _tr_flush_block       z__tr_flush_block
+#  define _tr_init              z__tr_init
+#  define _tr_stored_block      z__tr_stored_block
+#  define _tr_tally             z__tr_tally
+#  define adler32               z_adler32
+#  define adler32_combine       z_adler32_combine
+#  define adler32_combine64     z_adler32_combine64
+#  define adler32_z             z_adler32_z
+#  ifndef Z_SOLO
+#    define compress              z_compress
+#    define compress2             z_compress2
+#    define compressBound         z_compressBound
+#  endif
+#  define crc32                 z_crc32
+#  define crc32_combine         z_crc32_combine
+#  define crc32_combine64       z_crc32_combine64
+#  define crc32_z               z_crc32_z
+#  define deflate               z_deflate
+#  define deflateBound          z_deflateBound
+#  define deflateCopy           z_deflateCopy
+#  define deflateEnd            z_deflateEnd
+#  define deflateGetDictionary  z_deflateGetDictionary
+#  define deflateInit           z_deflateInit
+#  define deflateInit2          z_deflateInit2
+#  define deflateInit2_         z_deflateInit2_
+#  define deflateInit_          z_deflateInit_
+#  define deflateParams         z_deflateParams
+#  define deflatePending        z_deflatePending
+#  define deflatePrime          z_deflatePrime
+#  define deflateReset          z_deflateReset
+#  define deflateResetKeep      z_deflateResetKeep
+#  define deflateSetDictionary  z_deflateSetDictionary
+#  define deflateSetHeader      z_deflateSetHeader
+#  define deflateTune           z_deflateTune
+#  define deflate_copyright     z_deflate_copyright
+#  define get_crc_table         z_get_crc_table
+#  ifndef Z_SOLO
+#    define gz_error              z_gz_error
+#    define gz_intmax             z_gz_intmax
+#    define gz_strwinerror        z_gz_strwinerror
+#    define gzbuffer              z_gzbuffer
+#    define gzclearerr            z_gzclearerr
+#    define gzclose               z_gzclose
+#    define gzclose_r             z_gzclose_r
+#    define gzclose_w             z_gzclose_w
+#    define gzdirect              z_gzdirect
+#    define gzdopen               z_gzdopen
+#    define gzeof                 z_gzeof
+#    define gzerror               z_gzerror
+#    define gzflush               z_gzflush
+#    define gzfread               z_gzfread
+#    define gzfwrite              z_gzfwrite
+#    define gzgetc                z_gzgetc
+#    define gzgetc_               z_gzgetc_
+#    define gzgets                z_gzgets
+#    define gzoffset              z_gzoffset
+#    define gzoffset64            z_gzoffset64
+#    define gzopen                z_gzopen
+#    define gzopen64              z_gzopen64
+#    ifdef _WIN32
+#      define gzopen_w              z_gzopen_w
+#    endif
+#    define gzprintf              z_gzprintf
+#    define gzputc                z_gzputc
+#    define gzputs                z_gzputs
+#    define gzread                z_gzread
+#    define gzrewind              z_gzrewind
+#    define gzseek                z_gzseek
+#    define gzseek64              z_gzseek64
+#    define gzsetparams           z_gzsetparams
+#    define gztell                z_gztell
+#    define gztell64              z_gztell64
+#    define gzungetc              z_gzungetc
+#    define gzvprintf             z_gzvprintf
+#    define gzwrite               z_gzwrite
+#  endif
+#  define inflate               z_inflate
+#  define inflateBack           z_inflateBack
+#  define inflateBackEnd        z_inflateBackEnd
+#  define inflateBackInit       z_inflateBackInit
+#  define inflateBackInit_      z_inflateBackInit_
+#  define inflateCodesUsed      z_inflateCodesUsed
+#  define inflateCopy           z_inflateCopy
+#  define inflateEnd            z_inflateEnd
+#  define inflateGetDictionary  z_inflateGetDictionary
+#  define inflateGetHeader      z_inflateGetHeader
+#  define inflateInit           z_inflateInit
+#  define inflateInit2          z_inflateInit2
+#  define inflateInit2_         z_inflateInit2_
+#  define inflateInit_          z_inflateInit_
+#  define inflateMark           z_inflateMark
+#  define inflatePrime          z_inflatePrime
+#  define inflateReset          z_inflateReset
+#  define inflateReset2         z_inflateReset2
+#  define inflateResetKeep      z_inflateResetKeep
+#  define inflateSetDictionary  z_inflateSetDictionary
+#  define inflateSync           z_inflateSync
+#  define inflateSyncPoint      z_inflateSyncPoint
+#  define inflateUndermine      z_inflateUndermine
+#  define inflateValidate       z_inflateValidate
+#  define inflate_copyright     z_inflate_copyright
+#  define inflate_fast          z_inflate_fast
+#  define inflate_table         z_inflate_table
+#  ifndef Z_SOLO
+#    define uncompress            z_uncompress
+#    define uncompress2           z_uncompress2
+#  endif
+#  define zError                z_zError
+#  ifndef Z_SOLO
+#    define zcalloc               z_zcalloc
+#    define zcfree                z_zcfree
+#  endif
+#  define zlibCompileFlags      z_zlibCompileFlags
+#  define zlibVersion           z_zlibVersion
+
+/* all zlib typedefs in zlib.h and zconf.h */
+#  define Byte                  z_Byte
+#  define Bytef                 z_Bytef
+#  define alloc_func            z_alloc_func
+#  define charf                 z_charf
+#  define free_func             z_free_func
+#  ifndef Z_SOLO
+#    define gzFile                z_gzFile
+#  endif
+#  define gz_header             z_gz_header
+#  define gz_headerp            z_gz_headerp
+#  define in_func               z_in_func
+#  define intf                  z_intf
+#  define out_func              z_out_func
+#  define uInt                  z_uInt
+#  define uIntf                 z_uIntf
+#  define uLong                 z_uLong
+#  define uLongf                z_uLongf
+#  define voidp                 z_voidp
+#  define voidpc                z_voidpc
+#  define voidpf                z_voidpf
+
+/* all zlib structs in zlib.h and zconf.h */
+#  define gz_header_s           z_gz_header_s
+#  define internal_state        z_internal_state
+
+#endif
+
+#if defined(__MSDOS__) && !defined(MSDOS)
+#  define MSDOS
+#endif
+#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
+#  define OS2
+#endif
+#if defined(_WINDOWS) && !defined(WINDOWS)
+#  define WINDOWS
+#endif
+#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
+#  ifndef WIN32
+#    define WIN32
+#  endif
+#endif
+#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
+#  if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
+#    ifndef SYS16BIT
+#      define SYS16BIT
+#    endif
+#  endif
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#ifdef SYS16BIT
+#  define MAXSEG_64K
+#endif
+#ifdef MSDOS
+#  define UNALIGNED_OK
+#endif
+
+#ifdef __STDC_VERSION__
+#  ifndef STDC
+#    define STDC
+#  endif
+#  if __STDC_VERSION__ >= 199901L
+#    ifndef STDC99
+#      define STDC99
+#    endif
+#  endif
+#endif
+#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
+#  define STDC
+#endif
+
+#if defined(__OS400__) && !defined(STDC)    /* iSeries (formerly AS/400). */
+#  define STDC
+#endif
+
+#ifndef STDC
+#  ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+#    define const       /* note: need a more gentle solution here */
+#  endif
+#endif
+
+#if defined(ZLIB_CONST) && !defined(z_const)
+#  define z_const const
+#else
+#  define z_const
+#endif
+
+#ifdef Z_SOLO
+   typedef unsigned long z_size_t;
+#else
+#  define z_longlong long long
+#  if defined(NO_SIZE_T)
+     typedef unsigned NO_SIZE_T z_size_t;
+#  elif defined(STDC)
+#    include <stddef.h>
+     typedef size_t z_size_t;
+#  else
+     typedef unsigned long z_size_t;
+#  endif
+#  undef z_longlong
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+#  ifdef MAXSEG_64K
+#    define MAX_MEM_LEVEL 8
+#  else
+#    define MAX_MEM_LEVEL 9
+#  endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+#  define MAX_WBITS   15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+            (1 << (windowBits+2)) +  (1 << (memLevel+9))
+ that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+     make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+   The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus about 7 kilobytes
+ for small objects.
+*/
+
+                        /* Type declarations */
+
+#ifndef OF /* function prototypes */
+#  ifdef STDC
+#    define OF(args)  args
+#  else
+#    define OF(args)  ()
+#  endif
+#endif
+
+#ifndef Z_ARG /* function prototypes for stdarg */
+#  if defined(STDC) || defined(Z_HAVE_STDARG_H)
+#    define Z_ARG(args)  args
+#  else
+#    define Z_ARG(args)  ()
+#  endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h.  If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#ifdef SYS16BIT
+#  if defined(M_I86SM) || defined(M_I86MM)
+     /* MSC small or medium model */
+#    define SMALL_MEDIUM
+#    ifdef _MSC_VER
+#      define FAR _far
+#    else
+#      define FAR far
+#    endif
+#  endif
+#  if (defined(__SMALL__) || defined(__MEDIUM__))
+     /* Turbo C small or medium model */
+#    define SMALL_MEDIUM
+#    ifdef __BORLANDC__
+#      define FAR _far
+#    else
+#      define FAR far
+#    endif
+#  endif
+#endif
+
+#if defined(WINDOWS) || defined(WIN32)
+   /* If building or using zlib as a DLL, define ZLIB_DLL.
+    * This is not mandatory, but it offers a little performance increase.
+    */
+#  ifdef ZLIB_DLL
+#    if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
+#      ifdef ZLIB_INTERNAL
+#        define ZEXTERN extern __declspec(dllexport)
+#      else
+#        define ZEXTERN extern __declspec(dllimport)
+#      endif
+#    endif
+#  endif  /* ZLIB_DLL */
+   /* If building or using zlib with the WINAPI/WINAPIV calling convention,
+    * define ZLIB_WINAPI.
+    * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
+    */
+#  ifdef ZLIB_WINAPI
+#    ifdef FAR
+#      undef FAR
+#    endif
+#    include <windows.h>
+     /* No need for _export, use ZLIB.DEF instead. */
+     /* For complete Windows compatibility, use WINAPI, not __stdcall. */
+#    define ZEXPORT WINAPI
+#    ifdef WIN32
+#      define ZEXPORTVA WINAPIV
+#    else
+#      define ZEXPORTVA FAR CDECL
+#    endif
+#  endif
+#endif
+
+#if defined (__BEOS__)
+#  ifdef ZLIB_DLL
+#    ifdef ZLIB_INTERNAL
+#      define ZEXPORT   __declspec(dllexport)
+#      define ZEXPORTVA __declspec(dllexport)
+#    else
+#      define ZEXPORT   __declspec(dllimport)
+#      define ZEXPORTVA __declspec(dllimport)
+#    endif
+#  endif
+#endif
+
+#ifndef ZEXTERN
+#  define ZEXTERN extern
+#endif
+#ifndef ZEXPORT
+#  define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+#  define ZEXPORTVA
+#endif
+
+#ifndef FAR
+#  define FAR
+#endif
+
+#if !defined(__MACTYPES__)
+typedef unsigned char  Byte;  /* 8 bits */
+#endif
+typedef unsigned int   uInt;  /* 16 bits or more */
+typedef unsigned long  uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+   /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+#  define Bytef Byte FAR
+#else
+   typedef Byte  FAR Bytef;
+#endif
+typedef char  FAR charf;
+typedef int   FAR intf;
+typedef uInt  FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+   typedef void const *voidpc;
+   typedef void FAR   *voidpf;
+   typedef void       *voidp;
+#else
+   typedef Byte const *voidpc;
+   typedef Byte FAR   *voidpf;
+   typedef Byte       *voidp;
+#endif
+
+#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)
+#  include <limits.h>
+#  if (UINT_MAX == 0xffffffffUL)
+#    define Z_U4 unsigned
+#  elif (ULONG_MAX == 0xffffffffUL)
+#    define Z_U4 unsigned long
+#  elif (USHRT_MAX == 0xffffffffUL)
+#    define Z_U4 unsigned short
+#  endif
+#endif
+
+#ifdef Z_U4
+   typedef Z_U4 z_crc_t;
+#else
+   typedef unsigned long z_crc_t;
+#endif
+
+#ifdef HAVE_UNISTD_H    /* may be set to #if 1 by ./configure */
+#  define Z_HAVE_UNISTD_H
+#endif
+
+#ifdef HAVE_STDARG_H    /* may be set to #if 1 by ./configure */
+#  define Z_HAVE_STDARG_H
+#endif
+
+#ifdef STDC
+#  ifndef Z_SOLO
+#    include <sys/types.h>      /* for off_t */
+#  endif
+#endif
+
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+#  ifndef Z_SOLO
+#    include <stdarg.h>         /* for va_list */
+#  endif
+#endif
+
+#ifdef _WIN32
+#  ifndef Z_SOLO
+#    include <stddef.h>         /* for wchar_t */
+#  endif
+#endif
+
+/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
+ * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
+ * though the former does not conform to the LFS document), but considering
+ * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
+ * equivalently requesting no 64-bit operations
+ */
+#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1
+#  undef _LARGEFILE64_SOURCE
+#endif
+
+#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
+#  define Z_HAVE_UNISTD_H
+#endif
+#ifndef Z_SOLO
+#  if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
+#    include <unistd.h>         /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
+#    ifdef VMS
+#      include <unixio.h>       /* for off_t */
+#    endif
+#    ifndef z_off_t
+#      define z_off_t off_t
+#    endif
+#  endif
+#endif
+
+#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0
+#  define Z_LFS64
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)
+#  define Z_LARGE64
+#endif
+
+#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64)
+#  define Z_WANT64
+#endif
+
+#if !defined(SEEK_SET) && !defined(Z_SOLO)
+#  define SEEK_SET        0       /* Seek from beginning of file.  */
+#  define SEEK_CUR        1       /* Seek from current position.  */
+#  define SEEK_END        2       /* Set file pointer to EOF plus "offset" */
+#endif
+
+#ifndef z_off_t
+#  define z_off_t long
+#endif
+
+#if !defined(_WIN32) && defined(Z_LARGE64)
+#  define z_off64_t off64_t
+#else
+#  if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)
+#    define z_off64_t __int64
+#  else
+#    define z_off64_t z_off_t
+#  endif
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+  #pragma map(deflateInit_,"DEIN")
+  #pragma map(deflateInit2_,"DEIN2")
+  #pragma map(deflateEnd,"DEEND")
+  #pragma map(deflateBound,"DEBND")
+  #pragma map(inflateInit_,"ININ")
+  #pragma map(inflateInit2_,"ININ2")
+  #pragma map(inflateEnd,"INEND")
+  #pragma map(inflateSync,"INSY")
+  #pragma map(inflateSetDictionary,"INSEDI")
+  #pragma map(compressBound,"CMBND")
+  #pragma map(inflate_table,"INTABL")
+  #pragma map(inflate_fast,"INFA")
+  #pragma map(inflate_copyright,"INCOPY")
+#endif
+
+#endif /* ZCONF_H */

+ 1912 - 0
src/jni/zlib.h

@@ -0,0 +1,1912 @@
+/* zlib.h -- interface of the 'zlib' general purpose compression library
+  version 1.2.11, January 15th, 2017
+
+  Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Jean-loup Gailly        Mark Adler
+  jloup@gzip.org          madler@alumni.caltech.edu
+
+
+  The data format used by the zlib library is described by RFCs (Request for
+  Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
+  (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).
+*/
+
+#ifndef ZLIB_H
+#define ZLIB_H
+
+#include "zconf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ZLIB_VERSION "1.2.11"
+#define ZLIB_VERNUM 0x12b0
+#define ZLIB_VER_MAJOR 1
+#define ZLIB_VER_MINOR 2
+#define ZLIB_VER_REVISION 11
+#define ZLIB_VER_SUBREVISION 0
+
+/*
+    The 'zlib' compression library provides in-memory compression and
+  decompression functions, including integrity checks of the uncompressed data.
+  This version of the library supports only one compression method (deflation)
+  but other algorithms will be added later and will have the same stream
+  interface.
+
+    Compression can be done in a single step if the buffers are large enough,
+  or can be done by repeated calls of the compression function.  In the latter
+  case, the application must provide more input and/or consume the output
+  (providing more output space) before each call.
+
+    The compressed data format used by default by the in-memory functions is
+  the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
+  around a deflate stream, which is itself documented in RFC 1951.
+
+    The library also supports reading and writing files in gzip (.gz) format
+  with an interface similar to that of stdio using the functions that start
+  with "gz".  The gzip format is different from the zlib format.  gzip is a
+  gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
+
+    This library can optionally read and write gzip and raw deflate streams in
+  memory as well.
+
+    The zlib format was designed to be compact and fast for use in memory
+  and on communications channels.  The gzip format was designed for single-
+  file compression on file systems, has a larger header than zlib to maintain
+  directory information, and uses a different, slower check method than zlib.
+
+    The library does not install any signal handler.  The decoder checks
+  the consistency of the compressed data, so the library should never crash
+  even in the case of corrupted input.
+*/
+
+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
+typedef void   (*free_func)  OF((voidpf opaque, voidpf address));
+
+struct internal_state;
+
+typedef struct z_stream_s {
+    z_const Bytef *next_in;     /* next input byte */
+    uInt     avail_in;  /* number of bytes available at next_in */
+    uLong    total_in;  /* total number of input bytes read so far */
+
+    Bytef    *next_out; /* next output byte will go here */
+    uInt     avail_out; /* remaining free space at next_out */
+    uLong    total_out; /* total number of bytes output so far */
+
+    z_const char *msg;  /* last error message, NULL if no error */
+    struct internal_state FAR *state; /* not visible by applications */
+
+    alloc_func zalloc;  /* used to allocate the internal state */
+    free_func  zfree;   /* used to free the internal state */
+    voidpf     opaque;  /* private data object passed to zalloc and zfree */
+
+    int     data_type;  /* best guess about the data type: binary or text
+                           for deflate, or the decoding state for inflate */
+    uLong   adler;      /* Adler-32 or CRC-32 value of the uncompressed data */
+    uLong   reserved;   /* reserved for future use */
+} z_stream;
+
+typedef z_stream FAR *z_streamp;
+
+/*
+     gzip header information passed to and from zlib routines.  See RFC 1952
+  for more details on the meanings of these fields.
+*/
+typedef struct gz_header_s {
+    int     text;       /* true if compressed data believed to be text */
+    uLong   time;       /* modification time */
+    int     xflags;     /* extra flags (not used when writing a gzip file) */
+    int     os;         /* operating system */
+    Bytef   *extra;     /* pointer to extra field or Z_NULL if none */
+    uInt    extra_len;  /* extra field length (valid if extra != Z_NULL) */
+    uInt    extra_max;  /* space at extra (only when reading header) */
+    Bytef   *name;      /* pointer to zero-terminated file name or Z_NULL */
+    uInt    name_max;   /* space at name (only when reading header) */
+    Bytef   *comment;   /* pointer to zero-terminated comment or Z_NULL */
+    uInt    comm_max;   /* space at comment (only when reading header) */
+    int     hcrc;       /* true if there was or will be a header crc */
+    int     done;       /* true when done reading gzip header (not used
+                           when writing a gzip file) */
+} gz_header;
+
+typedef gz_header FAR *gz_headerp;
+
+/*
+     The application must update next_in and avail_in when avail_in has dropped
+   to zero.  It must update next_out and avail_out when avail_out has dropped
+   to zero.  The application must initialize zalloc, zfree and opaque before
+   calling the init function.  All other fields are set by the compression
+   library and must not be updated by the application.
+
+     The opaque value provided by the application will be passed as the first
+   parameter for calls of zalloc and zfree.  This can be useful for custom
+   memory management.  The compression library attaches no meaning to the
+   opaque value.
+
+     zalloc must return Z_NULL if there is not enough memory for the object.
+   If zlib is used in a multi-threaded application, zalloc and zfree must be
+   thread safe.  In that case, zlib is thread-safe.  When zalloc and zfree are
+   Z_NULL on entry to the initialization function, they are set to internal
+   routines that use the standard library functions malloc() and free().
+
+     On 16-bit systems, the functions zalloc and zfree must be able to allocate
+   exactly 65536 bytes, but will not be required to allocate more than this if
+   the symbol MAXSEG_64K is defined (see zconf.h).  WARNING: On MSDOS, pointers
+   returned by zalloc for objects of exactly 65536 bytes *must* have their
+   offset normalized to zero.  The default allocation function provided by this
+   library ensures this (see zutil.c).  To reduce memory requirements and avoid
+   any allocation of 64K objects, at the expense of compression ratio, compile
+   the library with -DMAX_WBITS=14 (see zconf.h).
+
+     The fields total_in and total_out can be used for statistics or progress
+   reports.  After compression, total_in holds the total size of the
+   uncompressed data and may be saved for use by the decompressor (particularly
+   if the decompressor wants to decompress everything in a single step).
+*/
+
+                        /* constants */
+
+#define Z_NO_FLUSH      0
+#define Z_PARTIAL_FLUSH 1
+#define Z_SYNC_FLUSH    2
+#define Z_FULL_FLUSH    3
+#define Z_FINISH        4
+#define Z_BLOCK         5
+#define Z_TREES         6
+/* Allowed flush values; see deflate() and inflate() below for details */
+
+#define Z_OK            0
+#define Z_STREAM_END    1
+#define Z_NEED_DICT     2
+#define Z_ERRNO        (-1)
+#define Z_STREAM_ERROR (-2)
+#define Z_DATA_ERROR   (-3)
+#define Z_MEM_ERROR    (-4)
+#define Z_BUF_ERROR    (-5)
+#define Z_VERSION_ERROR (-6)
+/* Return codes for the compression/decompression functions. Negative values
+ * are errors, positive values are used for special but normal events.
+ */
+
+#define Z_NO_COMPRESSION         0
+#define Z_BEST_SPEED             1
+#define Z_BEST_COMPRESSION       9
+#define Z_DEFAULT_COMPRESSION  (-1)
+/* compression levels */
+
+#define Z_FILTERED            1
+#define Z_HUFFMAN_ONLY        2
+#define Z_RLE                 3
+#define Z_FIXED               4
+#define Z_DEFAULT_STRATEGY    0
+/* compression strategy; see deflateInit2() below for details */
+
+#define Z_BINARY   0
+#define Z_TEXT     1
+#define Z_ASCII    Z_TEXT   /* for compatibility with 1.2.2 and earlier */
+#define Z_UNKNOWN  2
+/* Possible values of the data_type field for deflate() */
+
+#define Z_DEFLATED   8
+/* The deflate compression method (the only one supported in this version) */
+
+#define Z_NULL  0  /* for initializing zalloc, zfree, opaque */
+
+#define zlib_version zlibVersion()
+/* for compatibility with versions < 1.0.2 */
+
+
+                        /* basic functions */
+
+ZEXTERN const char * ZEXPORT zlibVersion OF((void));
+/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
+   If the first character differs, the library code actually used is not
+   compatible with the zlib.h header file used by the application.  This check
+   is automatically made by deflateInit and inflateInit.
+ */
+
+/*
+ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
+
+     Initializes the internal stream state for compression.  The fields
+   zalloc, zfree and opaque must be initialized before by the caller.  If
+   zalloc and zfree are set to Z_NULL, deflateInit updates them to use default
+   allocation functions.
+
+     The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
+   1 gives best speed, 9 gives best compression, 0 gives no compression at all
+   (the input data is simply copied a block at a time).  Z_DEFAULT_COMPRESSION
+   requests a default compromise between speed and compression (currently
+   equivalent to level 6).
+
+     deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_STREAM_ERROR if level is not a valid compression level, or
+   Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
+   with the version assumed by the caller (ZLIB_VERSION).  msg is set to null
+   if there is no error message.  deflateInit does not perform any compression:
+   this will be done by deflate().
+*/
+
+
+ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
+/*
+    deflate compresses as much data as possible, and stops when the input
+  buffer becomes empty or the output buffer becomes full.  It may introduce
+  some output latency (reading input without producing any output) except when
+  forced to flush.
+
+    The detailed semantics are as follows.  deflate performs one or both of the
+  following actions:
+
+  - Compress more input starting at next_in and update next_in and avail_in
+    accordingly.  If not all input can be processed (because there is not
+    enough room in the output buffer), next_in and avail_in are updated and
+    processing will resume at this point for the next call of deflate().
+
+  - Generate more output starting at next_out and update next_out and avail_out
+    accordingly.  This action is forced if the parameter flush is non zero.
+    Forcing flush frequently degrades the compression ratio, so this parameter
+    should be set only when necessary.  Some output may be provided even if
+    flush is zero.
+
+    Before the call of deflate(), the application should ensure that at least
+  one of the actions is possible, by providing more input and/or consuming more
+  output, and updating avail_in or avail_out accordingly; avail_out should
+  never be zero before the call.  The application can consume the compressed
+  output when it wants, for example when the output buffer is full (avail_out
+  == 0), or after each call of deflate().  If deflate returns Z_OK and with
+  zero avail_out, it must be called again after making room in the output
+  buffer because there might be more output pending. See deflatePending(),
+  which can be used if desired to determine whether or not there is more ouput
+  in that case.
+
+    Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
+  decide how much data to accumulate before producing output, in order to
+  maximize compression.
+
+    If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
+  flushed to the output buffer and the output is aligned on a byte boundary, so
+  that the decompressor can get all input data available so far.  (In
+  particular avail_in is zero after the call if enough output space has been
+  provided before the call.) Flushing may degrade compression for some
+  compression algorithms and so it should be used only when necessary.  This
+  completes the current deflate block and follows it with an empty stored block
+  that is three bits plus filler bits to the next byte, followed by four bytes
+  (00 00 ff ff).
+
+    If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the
+  output buffer, but the output is not aligned to a byte boundary.  All of the
+  input data so far will be available to the decompressor, as for Z_SYNC_FLUSH.
+  This completes the current deflate block and follows it with an empty fixed
+  codes block that is 10 bits long.  This assures that enough bytes are output
+  in order for the decompressor to finish the block before the empty fixed
+  codes block.
+
+    If flush is set to Z_BLOCK, a deflate block is completed and emitted, as
+  for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to
+  seven bits of the current block are held to be written as the next byte after
+  the next deflate block is completed.  In this case, the decompressor may not
+  be provided enough bits at this point in order to complete decompression of
+  the data provided so far to the compressor.  It may need to wait for the next
+  block to be emitted.  This is for advanced applications that need to control
+  the emission of deflate blocks.
+
+    If flush is set to Z_FULL_FLUSH, all output is flushed as with
+  Z_SYNC_FLUSH, and the compression state is reset so that decompression can
+  restart from this point if previous compressed data has been damaged or if
+  random access is desired.  Using Z_FULL_FLUSH too often can seriously degrade
+  compression.
+
+    If deflate returns with avail_out == 0, this function must be called again
+  with the same value of the flush parameter and more output space (updated
+  avail_out), until the flush is complete (deflate returns with non-zero
+  avail_out).  In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
+  avail_out is greater than six to avoid repeated flush markers due to
+  avail_out == 0 on return.
+
+    If the parameter flush is set to Z_FINISH, pending input is processed,
+  pending output is flushed and deflate returns with Z_STREAM_END if there was
+  enough output space.  If deflate returns with Z_OK or Z_BUF_ERROR, this
+  function must be called again with Z_FINISH and more output space (updated
+  avail_out) but no more input data, until it returns with Z_STREAM_END or an
+  error.  After deflate has returned Z_STREAM_END, the only possible operations
+  on the stream are deflateReset or deflateEnd.
+
+    Z_FINISH can be used in the first deflate call after deflateInit if all the
+  compression is to be done in a single step.  In order to complete in one
+  call, avail_out must be at least the value returned by deflateBound (see
+  below).  Then deflate is guaranteed to return Z_STREAM_END.  If not enough
+  output space is provided, deflate will not return Z_STREAM_END, and it must
+  be called again as described above.
+
+    deflate() sets strm->adler to the Adler-32 checksum of all input read
+  so far (that is, total_in bytes).  If a gzip stream is being generated, then
+  strm->adler will be the CRC-32 checksum of the input read so far.  (See
+  deflateInit2 below.)
+
+    deflate() may update strm->data_type if it can make a good guess about
+  the input data type (Z_BINARY or Z_TEXT).  If in doubt, the data is
+  considered binary.  This field is only for information purposes and does not
+  affect the compression algorithm in any manner.
+
+    deflate() returns Z_OK if some progress has been made (more input
+  processed or more output produced), Z_STREAM_END if all input has been
+  consumed and all output has been produced (only when flush is set to
+  Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
+  if next_in or next_out was Z_NULL or the state was inadvertently written over
+  by the application), or Z_BUF_ERROR if no progress is possible (for example
+  avail_in or avail_out was zero).  Note that Z_BUF_ERROR is not fatal, and
+  deflate() can be called again with more input and more output space to
+  continue compressing.
+*/
+
+
+ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
+/*
+     All dynamically allocated data structures for this stream are freed.
+   This function discards any unprocessed input and does not flush any pending
+   output.
+
+     deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
+   stream state was inconsistent, Z_DATA_ERROR if the stream was freed
+   prematurely (some input or output was discarded).  In the error case, msg
+   may be set but then points to a static string (which must not be
+   deallocated).
+*/
+
+
+/*
+ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
+
+     Initializes the internal stream state for decompression.  The fields
+   next_in, avail_in, zalloc, zfree and opaque must be initialized before by
+   the caller.  In the current version of inflate, the provided input is not
+   read or consumed.  The allocation of a sliding window will be deferred to
+   the first call of inflate (if the decompression does not complete on the
+   first call).  If zalloc and zfree are set to Z_NULL, inflateInit updates
+   them to use default allocation functions.
+
+     inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+   version assumed by the caller, or Z_STREAM_ERROR if the parameters are
+   invalid, such as a null pointer to the structure.  msg is set to null if
+   there is no error message.  inflateInit does not perform any decompression.
+   Actual decompression will be done by inflate().  So next_in, and avail_in,
+   next_out, and avail_out are unused and unchanged.  The current
+   implementation of inflateInit() does not process any header information --
+   that is deferred until inflate() is called.
+*/
+
+
+ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
+/*
+    inflate decompresses as much data as possible, and stops when the input
+  buffer becomes empty or the output buffer becomes full.  It may introduce
+  some output latency (reading input without producing any output) except when
+  forced to flush.
+
+  The detailed semantics are as follows.  inflate performs one or both of the
+  following actions:
+
+  - Decompress more input starting at next_in and update next_in and avail_in
+    accordingly.  If not all input can be processed (because there is not
+    enough room in the output buffer), then next_in and avail_in are updated
+    accordingly, and processing will resume at this point for the next call of
+    inflate().
+
+  - Generate more output starting at next_out and update next_out and avail_out
+    accordingly.  inflate() provides as much output as possible, until there is
+    no more input data or no more space in the output buffer (see below about
+    the flush parameter).
+
+    Before the call of inflate(), the application should ensure that at least
+  one of the actions is possible, by providing more input and/or consuming more
+  output, and updating the next_* and avail_* values accordingly.  If the
+  caller of inflate() does not provide both available input and available
+  output space, it is possible that there will be no progress made.  The
+  application can consume the uncompressed output when it wants, for example
+  when the output buffer is full (avail_out == 0), or after each call of
+  inflate().  If inflate returns Z_OK and with zero avail_out, it must be
+  called again after making room in the output buffer because there might be
+  more output pending.
+
+    The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH,
+  Z_BLOCK, or Z_TREES.  Z_SYNC_FLUSH requests that inflate() flush as much
+  output as possible to the output buffer.  Z_BLOCK requests that inflate()
+  stop if and when it gets to the next deflate block boundary.  When decoding
+  the zlib or gzip format, this will cause inflate() to return immediately
+  after the header and before the first block.  When doing a raw inflate,
+  inflate() will go ahead and process the first block, and will return when it
+  gets to the end of that block, or when it runs out of data.
+
+    The Z_BLOCK option assists in appending to or combining deflate streams.
+  To assist in this, on return inflate() always sets strm->data_type to the
+  number of unused bits in the last byte taken from strm->next_in, plus 64 if
+  inflate() is currently decoding the last block in the deflate stream, plus
+  128 if inflate() returned immediately after decoding an end-of-block code or
+  decoding the complete header up to just before the first byte of the deflate
+  stream.  The end-of-block will not be indicated until all of the uncompressed
+  data from that block has been written to strm->next_out.  The number of
+  unused bits may in general be greater than seven, except when bit 7 of
+  data_type is set, in which case the number of unused bits will be less than
+  eight.  data_type is set as noted here every time inflate() returns for all
+  flush options, and so can be used to determine the amount of currently
+  consumed input in bits.
+
+    The Z_TREES option behaves as Z_BLOCK does, but it also returns when the
+  end of each deflate block header is reached, before any actual data in that
+  block is decoded.  This allows the caller to determine the length of the
+  deflate block header for later use in random access within a deflate block.
+  256 is added to the value of strm->data_type when inflate() returns
+  immediately after reaching the end of the deflate block header.
+
+    inflate() should normally be called until it returns Z_STREAM_END or an
+  error.  However if all decompression is to be performed in a single step (a
+  single call of inflate), the parameter flush should be set to Z_FINISH.  In
+  this case all pending input is processed and all pending output is flushed;
+  avail_out must be large enough to hold all of the uncompressed data for the
+  operation to complete.  (The size of the uncompressed data may have been
+  saved by the compressor for this purpose.)  The use of Z_FINISH is not
+  required to perform an inflation in one step.  However it may be used to
+  inform inflate that a faster approach can be used for the single inflate()
+  call.  Z_FINISH also informs inflate to not maintain a sliding window if the
+  stream completes, which reduces inflate's memory footprint.  If the stream
+  does not complete, either because not all of the stream is provided or not
+  enough output space is provided, then a sliding window will be allocated and
+  inflate() can be called again to continue the operation as if Z_NO_FLUSH had
+  been used.
+
+     In this implementation, inflate() always flushes as much output as
+  possible to the output buffer, and always uses the faster approach on the
+  first call.  So the effects of the flush parameter in this implementation are
+  on the return value of inflate() as noted below, when inflate() returns early
+  when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of
+  memory for a sliding window when Z_FINISH is used.
+
+     If a preset dictionary is needed after this call (see inflateSetDictionary
+  below), inflate sets strm->adler to the Adler-32 checksum of the dictionary
+  chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
+  strm->adler to the Adler-32 checksum of all output produced so far (that is,
+  total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
+  below.  At the end of the stream, inflate() checks that its computed Adler-32
+  checksum is equal to that saved by the compressor and returns Z_STREAM_END
+  only if the checksum is correct.
+
+    inflate() can decompress and check either zlib-wrapped or gzip-wrapped
+  deflate data.  The header type is detected automatically, if requested when
+  initializing with inflateInit2().  Any information contained in the gzip
+  header is not retained unless inflateGetHeader() is used.  When processing
+  gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output
+  produced so far.  The CRC-32 is checked against the gzip trailer, as is the
+  uncompressed length, modulo 2^32.
+
+    inflate() returns Z_OK if some progress has been made (more input processed
+  or more output produced), Z_STREAM_END if the end of the compressed data has
+  been reached and all uncompressed output has been produced, Z_NEED_DICT if a
+  preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
+  corrupted (input stream not conforming to the zlib format or incorrect check
+  value, in which case strm->msg points to a string with a more specific
+  error), Z_STREAM_ERROR if the stream structure was inconsistent (for example
+  next_in or next_out was Z_NULL, or the state was inadvertently written over
+  by the application), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR
+  if no progress was possible or if there was not enough room in the output
+  buffer when Z_FINISH is used.  Note that Z_BUF_ERROR is not fatal, and
+  inflate() can be called again with more input and more output space to
+  continue decompressing.  If Z_DATA_ERROR is returned, the application may
+  then call inflateSync() to look for a good compression block if a partial
+  recovery of the data is to be attempted.
+*/
+
+
+ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
+/*
+     All dynamically allocated data structures for this stream are freed.
+   This function discards any unprocessed input and does not flush any pending
+   output.
+
+     inflateEnd returns Z_OK if success, or Z_STREAM_ERROR if the stream state
+   was inconsistent.
+*/
+
+
+                        /* Advanced functions */
+
+/*
+    The following functions are needed only in some special applications.
+*/
+
+/*
+ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
+                                     int  level,
+                                     int  method,
+                                     int  windowBits,
+                                     int  memLevel,
+                                     int  strategy));
+
+     This is another version of deflateInit with more compression options.  The
+   fields next_in, zalloc, zfree and opaque must be initialized before by the
+   caller.
+
+     The method parameter is the compression method.  It must be Z_DEFLATED in
+   this version of the library.
+
+     The windowBits parameter is the base two logarithm of the window size
+   (the size of the history buffer).  It should be in the range 8..15 for this
+   version of the library.  Larger values of this parameter result in better
+   compression at the expense of memory usage.  The default value is 15 if
+   deflateInit is used instead.
+
+     For the current implementation of deflate(), a windowBits value of 8 (a
+   window size of 256 bytes) is not supported.  As a result, a request for 8
+   will result in 9 (a 512-byte window).  In that case, providing 8 to
+   inflateInit2() will result in an error when the zlib header with 9 is
+   checked against the initialization of inflate().  The remedy is to not use 8
+   with deflateInit2() with this initialization, or at least in that case use 9
+   with inflateInit2().
+
+     windowBits can also be -8..-15 for raw deflate.  In this case, -windowBits
+   determines the window size.  deflate() will then generate raw deflate data
+   with no zlib header or trailer, and will not compute a check value.
+
+     windowBits can also be greater than 15 for optional gzip encoding.  Add
+   16 to windowBits to write a simple gzip header and trailer around the
+   compressed data instead of a zlib wrapper.  The gzip header will have no
+   file name, no extra data, no comment, no modification time (set to zero), no
+   header crc, and the operating system will be set to the appropriate value,
+   if the operating system was determined at compile time.  If a gzip stream is
+   being written, strm->adler is a CRC-32 instead of an Adler-32.
+
+     For raw deflate or gzip encoding, a request for a 256-byte window is
+   rejected as invalid, since only the zlib header provides a means of
+   transmitting the window size to the decompressor.
+
+     The memLevel parameter specifies how much memory should be allocated
+   for the internal compression state.  memLevel=1 uses minimum memory but is
+   slow and reduces compression ratio; memLevel=9 uses maximum memory for
+   optimal speed.  The default value is 8.  See zconf.h for total memory usage
+   as a function of windowBits and memLevel.
+
+     The strategy parameter is used to tune the compression algorithm.  Use the
+   value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
+   filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no
+   string match), or Z_RLE to limit match distances to one (run-length
+   encoding).  Filtered data consists mostly of small values with a somewhat
+   random distribution.  In this case, the compression algorithm is tuned to
+   compress them better.  The effect of Z_FILTERED is to force more Huffman
+   coding and less string matching; it is somewhat intermediate between
+   Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY.  Z_RLE is designed to be almost as
+   fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data.  The
+   strategy parameter only affects the compression ratio but not the
+   correctness of the compressed output even if it is not set appropriately.
+   Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler
+   decoder for special applications.
+
+     deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid
+   method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is
+   incompatible with the version assumed by the caller (ZLIB_VERSION).  msg is
+   set to null if there is no error message.  deflateInit2 does not perform any
+   compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
+                                             const Bytef *dictionary,
+                                             uInt  dictLength));
+/*
+     Initializes the compression dictionary from the given byte sequence
+   without producing any compressed output.  When using the zlib format, this
+   function must be called immediately after deflateInit, deflateInit2 or
+   deflateReset, and before any call of deflate.  When doing raw deflate, this
+   function must be called either before any call of deflate, or immediately
+   after the completion of a deflate block, i.e. after all input has been
+   consumed and all output has been delivered when using any of the flush
+   options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH.  The
+   compressor and decompressor must use exactly the same dictionary (see
+   inflateSetDictionary).
+
+     The dictionary should consist of strings (byte sequences) that are likely
+   to be encountered later in the data to be compressed, with the most commonly
+   used strings preferably put towards the end of the dictionary.  Using a
+   dictionary is most useful when the data to be compressed is short and can be
+   predicted with good accuracy; the data can then be compressed better than
+   with the default empty dictionary.
+
+     Depending on the size of the compression data structures selected by
+   deflateInit or deflateInit2, a part of the dictionary may in effect be
+   discarded, for example if the dictionary is larger than the window size
+   provided in deflateInit or deflateInit2.  Thus the strings most likely to be
+   useful should be put at the end of the dictionary, not at the front.  In
+   addition, the current implementation of deflate will use at most the window
+   size minus 262 bytes of the provided dictionary.
+
+     Upon return of this function, strm->adler is set to the Adler-32 value
+   of the dictionary; the decompressor may later use this value to determine
+   which dictionary has been used by the compressor.  (The Adler-32 value
+   applies to the whole dictionary even if only a subset of the dictionary is
+   actually used by the compressor.) If a raw deflate was requested, then the
+   Adler-32 value is not computed and strm->adler is not set.
+
+     deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
+   parameter is invalid (e.g.  dictionary being Z_NULL) or the stream state is
+   inconsistent (for example if deflate has already been called for this stream
+   or if not at a block boundary for raw deflate).  deflateSetDictionary does
+   not perform any compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateGetDictionary OF((z_streamp strm,
+                                             Bytef *dictionary,
+                                             uInt  *dictLength));
+/*
+     Returns the sliding dictionary being maintained by deflate.  dictLength is
+   set to the number of bytes in the dictionary, and that many bytes are copied
+   to dictionary.  dictionary must have enough space, where 32768 bytes is
+   always enough.  If deflateGetDictionary() is called with dictionary equal to
+   Z_NULL, then only the dictionary length is returned, and nothing is copied.
+   Similary, if dictLength is Z_NULL, then it is not set.
+
+     deflateGetDictionary() may return a length less than the window size, even
+   when more than the window size in input has been provided. It may return up
+   to 258 bytes less in that case, due to how zlib's implementation of deflate
+   manages the sliding window and lookahead for matches, where matches can be
+   up to 258 bytes long. If the application needs the last window-size bytes of
+   input, then that would need to be saved by the application outside of zlib.
+
+     deflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the
+   stream state is inconsistent.
+*/
+
+ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
+                                    z_streamp source));
+/*
+     Sets the destination stream as a complete copy of the source stream.
+
+     This function can be useful when several compression strategies will be
+   tried, for example when there are several ways of pre-processing the input
+   data with a filter.  The streams that will be discarded should then be freed
+   by calling deflateEnd.  Note that deflateCopy duplicates the internal
+   compression state which can be quite large, so this strategy is slow and can
+   consume lots of memory.
+
+     deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+   (such as zalloc being Z_NULL).  msg is left unchanged in both source and
+   destination.
+*/
+
+ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
+/*
+     This function is equivalent to deflateEnd followed by deflateInit, but
+   does not free and reallocate the internal compression state.  The stream
+   will leave the compression level and any other attributes that may have been
+   set unchanged.
+
+     deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent (such as zalloc or state being Z_NULL).
+*/
+
+ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
+                                      int level,
+                                      int strategy));
+/*
+     Dynamically update the compression level and compression strategy.  The
+   interpretation of level and strategy is as in deflateInit2().  This can be
+   used to switch between compression and straight copy of the input data, or
+   to switch to a different kind of input data requiring a different strategy.
+   If the compression approach (which is a function of the level) or the
+   strategy is changed, and if any input has been consumed in a previous
+   deflate() call, then the input available so far is compressed with the old
+   level and strategy using deflate(strm, Z_BLOCK).  There are three approaches
+   for the compression levels 0, 1..3, and 4..9 respectively.  The new level
+   and strategy will take effect at the next call of deflate().
+
+     If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does
+   not have enough output space to complete, then the parameter change will not
+   take effect.  In this case, deflateParams() can be called again with the
+   same parameters and more output space to try again.
+
+     In order to assure a change in the parameters on the first try, the
+   deflate stream should be flushed using deflate() with Z_BLOCK or other flush
+   request until strm.avail_out is not zero, before calling deflateParams().
+   Then no more input data should be provided before the deflateParams() call.
+   If this is done, the old level and strategy will be applied to the data
+   compressed before deflateParams(), and the new level and strategy will be
+   applied to the the data compressed after deflateParams().
+
+     deflateParams returns Z_OK on success, Z_STREAM_ERROR if the source stream
+   state was inconsistent or if a parameter was invalid, or Z_BUF_ERROR if
+   there was not enough output space to complete the compression of the
+   available input data before a change in the strategy or approach.  Note that
+   in the case of a Z_BUF_ERROR, the parameters are not changed.  A return
+   value of Z_BUF_ERROR is not fatal, in which case deflateParams() can be
+   retried with more output space.
+*/
+
+ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
+                                    int good_length,
+                                    int max_lazy,
+                                    int nice_length,
+                                    int max_chain));
+/*
+     Fine tune deflate's internal compression parameters.  This should only be
+   used by someone who understands the algorithm used by zlib's deflate for
+   searching for the best matching string, and even then only by the most
+   fanatic optimizer trying to squeeze out the last compressed bit for their
+   specific input data.  Read the deflate.c source code for the meaning of the
+   max_lazy, good_length, nice_length, and max_chain parameters.
+
+     deflateTune() can be called after deflateInit() or deflateInit2(), and
+   returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
+ */
+
+ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
+                                       uLong sourceLen));
+/*
+     deflateBound() returns an upper bound on the compressed size after
+   deflation of sourceLen bytes.  It must be called after deflateInit() or
+   deflateInit2(), and after deflateSetHeader(), if used.  This would be used
+   to allocate an output buffer for deflation in a single pass, and so would be
+   called before deflate().  If that first deflate() call is provided the
+   sourceLen input bytes, an output buffer allocated to the size returned by
+   deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed
+   to return Z_STREAM_END.  Note that it is possible for the compressed size to
+   be larger than the value returned by deflateBound() if flush options other
+   than Z_FINISH or Z_NO_FLUSH are used.
+*/
+
+ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm,
+                                       unsigned *pending,
+                                       int *bits));
+/*
+     deflatePending() returns the number of bytes and bits of output that have
+   been generated, but not yet provided in the available output.  The bytes not
+   provided would be due to the available output space having being consumed.
+   The number of bits of output not provided are between 0 and 7, where they
+   await more bits to join them in order to fill out a full byte.  If pending
+   or bits are Z_NULL, then those values are not set.
+
+     deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+ */
+
+ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
+                                     int bits,
+                                     int value));
+/*
+     deflatePrime() inserts bits in the deflate output stream.  The intent
+   is that this function is used to start off the deflate output with the bits
+   leftover from a previous deflate stream when appending to it.  As such, this
+   function can only be used for raw deflate, and must be used before the first
+   deflate() call after a deflateInit2() or deflateReset().  bits must be less
+   than or equal to 16, and that many of the least significant bits of value
+   will be inserted in the output.
+
+     deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough
+   room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the
+   source stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
+                                         gz_headerp head));
+/*
+     deflateSetHeader() provides gzip header information for when a gzip
+   stream is requested by deflateInit2().  deflateSetHeader() may be called
+   after deflateInit2() or deflateReset() and before the first call of
+   deflate().  The text, time, os, extra field, name, and comment information
+   in the provided gz_header structure are written to the gzip header (xflag is
+   ignored -- the extra flags are set according to the compression level).  The
+   caller must assure that, if not Z_NULL, name and comment are terminated with
+   a zero byte, and that if extra is not Z_NULL, that extra_len bytes are
+   available there.  If hcrc is true, a gzip header crc is included.  Note that
+   the current versions of the command-line version of gzip (up through version
+   1.3.x) do not support header crc's, and will report that it is a "multi-part
+   gzip file" and give up.
+
+     If deflateSetHeader is not used, the default gzip header has text false,
+   the time set to zero, and os set to 255, with no extra, name, or comment
+   fields.  The gzip header is returned to the default state by deflateReset().
+
+     deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
+                                     int  windowBits));
+
+     This is another version of inflateInit with an extra parameter.  The
+   fields next_in, avail_in, zalloc, zfree and opaque must be initialized
+   before by the caller.
+
+     The windowBits parameter is the base two logarithm of the maximum window
+   size (the size of the history buffer).  It should be in the range 8..15 for
+   this version of the library.  The default value is 15 if inflateInit is used
+   instead.  windowBits must be greater than or equal to the windowBits value
+   provided to deflateInit2() while compressing, or it must be equal to 15 if
+   deflateInit2() was not used.  If a compressed stream with a larger window
+   size is given as input, inflate() will return with the error code
+   Z_DATA_ERROR instead of trying to allocate a larger window.
+
+     windowBits can also be zero to request that inflate use the window size in
+   the zlib header of the compressed stream.
+
+     windowBits can also be -8..-15 for raw inflate.  In this case, -windowBits
+   determines the window size.  inflate() will then process raw deflate data,
+   not looking for a zlib or gzip header, not generating a check value, and not
+   looking for any check values for comparison at the end of the stream.  This
+   is for use with other formats that use the deflate compressed data format
+   such as zip.  Those formats provide their own check values.  If a custom
+   format is developed using the raw deflate format for compressed data, it is
+   recommended that a check value such as an Adler-32 or a CRC-32 be applied to
+   the uncompressed data as is done in the zlib, gzip, and zip formats.  For
+   most applications, the zlib format should be used as is.  Note that comments
+   above on the use in deflateInit2() applies to the magnitude of windowBits.
+
+     windowBits can also be greater than 15 for optional gzip decoding.  Add
+   32 to windowBits to enable zlib and gzip decoding with automatic header
+   detection, or add 16 to decode only the gzip format (the zlib format will
+   return a Z_DATA_ERROR).  If a gzip stream is being decoded, strm->adler is a
+   CRC-32 instead of an Adler-32.  Unlike the gunzip utility and gzread() (see
+   below), inflate() will not automatically decode concatenated gzip streams.
+   inflate() will return Z_STREAM_END at the end of the gzip stream.  The state
+   would need to be reset to continue decoding a subsequent gzip stream.
+
+     inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+   version assumed by the caller, or Z_STREAM_ERROR if the parameters are
+   invalid, such as a null pointer to the structure.  msg is set to null if
+   there is no error message.  inflateInit2 does not perform any decompression
+   apart from possibly reading the zlib header if present: actual decompression
+   will be done by inflate().  (So next_in and avail_in may be modified, but
+   next_out and avail_out are unused and unchanged.) The current implementation
+   of inflateInit2() does not process any header information -- that is
+   deferred until inflate() is called.
+*/
+
+ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
+                                             const Bytef *dictionary,
+                                             uInt  dictLength));
+/*
+     Initializes the decompression dictionary from the given uncompressed byte
+   sequence.  This function must be called immediately after a call of inflate,
+   if that call returned Z_NEED_DICT.  The dictionary chosen by the compressor
+   can be determined from the Adler-32 value returned by that call of inflate.
+   The compressor and decompressor must use exactly the same dictionary (see
+   deflateSetDictionary).  For raw inflate, this function can be called at any
+   time to set the dictionary.  If the provided dictionary is smaller than the
+   window and there is already data in the window, then the provided dictionary
+   will amend what's there.  The application must insure that the dictionary
+   that was used for compression is provided.
+
+     inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
+   parameter is invalid (e.g.  dictionary being Z_NULL) or the stream state is
+   inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
+   expected one (incorrect Adler-32 value).  inflateSetDictionary does not
+   perform any decompression: this will be done by subsequent calls of
+   inflate().
+*/
+
+ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm,
+                                             Bytef *dictionary,
+                                             uInt  *dictLength));
+/*
+     Returns the sliding dictionary being maintained by inflate.  dictLength is
+   set to the number of bytes in the dictionary, and that many bytes are copied
+   to dictionary.  dictionary must have enough space, where 32768 bytes is
+   always enough.  If inflateGetDictionary() is called with dictionary equal to
+   Z_NULL, then only the dictionary length is returned, and nothing is copied.
+   Similary, if dictLength is Z_NULL, then it is not set.
+
+     inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the
+   stream state is inconsistent.
+*/
+
+ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
+/*
+     Skips invalid compressed data until a possible full flush point (see above
+   for the description of deflate with Z_FULL_FLUSH) can be found, or until all
+   available input is skipped.  No output is provided.
+
+     inflateSync searches for a 00 00 FF FF pattern in the compressed data.
+   All full flush points have this pattern, but not all occurrences of this
+   pattern are full flush points.
+
+     inflateSync returns Z_OK if a possible full flush point has been found,
+   Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point
+   has been found, or Z_STREAM_ERROR if the stream structure was inconsistent.
+   In the success case, the application may save the current current value of
+   total_in which indicates where valid compressed data was found.  In the
+   error case, the application may repeatedly call inflateSync, providing more
+   input each time, until success or end of the input data.
+*/
+
+ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
+                                    z_streamp source));
+/*
+     Sets the destination stream as a complete copy of the source stream.
+
+     This function can be useful when randomly accessing a large stream.  The
+   first pass through the stream can periodically record the inflate state,
+   allowing restarting inflate at those points when randomly accessing the
+   stream.
+
+     inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+   (such as zalloc being Z_NULL).  msg is left unchanged in both source and
+   destination.
+*/
+
+ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
+/*
+     This function is equivalent to inflateEnd followed by inflateInit,
+   but does not free and reallocate the internal decompression state.  The
+   stream will keep attributes that may have been set by inflateInit2.
+
+     inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent (such as zalloc or state being Z_NULL).
+*/
+
+ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm,
+                                      int windowBits));
+/*
+     This function is the same as inflateReset, but it also permits changing
+   the wrap and window size requests.  The windowBits parameter is interpreted
+   the same as it is for inflateInit2.  If the window size is changed, then the
+   memory allocated for the window is freed, and the window will be reallocated
+   by inflate() if needed.
+
+     inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent (such as zalloc or state being Z_NULL), or if
+   the windowBits parameter is invalid.
+*/
+
+ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
+                                     int bits,
+                                     int value));
+/*
+     This function inserts bits in the inflate input stream.  The intent is
+   that this function is used to start inflating at a bit position in the
+   middle of a byte.  The provided bits will be used before any bytes are used
+   from next_in.  This function should only be used with raw inflate, and
+   should be used before the first inflate() call after inflateInit2() or
+   inflateReset().  bits must be less than or equal to 16, and that many of the
+   least significant bits of value will be inserted in the input.
+
+     If bits is negative, then the input stream bit buffer is emptied.  Then
+   inflatePrime() can be called again to put bits in the buffer.  This is used
+   to clear out bits leftover after feeding inflate a block description prior
+   to feeding inflate codes.
+
+     inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+*/
+
+ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm));
+/*
+     This function returns two values, one in the lower 16 bits of the return
+   value, and the other in the remaining upper bits, obtained by shifting the
+   return value down 16 bits.  If the upper value is -1 and the lower value is
+   zero, then inflate() is currently decoding information outside of a block.
+   If the upper value is -1 and the lower value is non-zero, then inflate is in
+   the middle of a stored block, with the lower value equaling the number of
+   bytes from the input remaining to copy.  If the upper value is not -1, then
+   it is the number of bits back from the current bit position in the input of
+   the code (literal or length/distance pair) currently being processed.  In
+   that case the lower value is the number of bytes already emitted for that
+   code.
+
+     A code is being processed if inflate is waiting for more input to complete
+   decoding of the code, or if it has completed decoding but is waiting for
+   more output space to write the literal or match data.
+
+     inflateMark() is used to mark locations in the input data for random
+   access, which may be at bit positions, and to note those cases where the
+   output of a code may span boundaries of random access blocks.  The current
+   location in the input stream can be determined from avail_in and data_type
+   as noted in the description for the Z_BLOCK flush parameter for inflate.
+
+     inflateMark returns the value noted above, or -65536 if the provided
+   source stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
+                                         gz_headerp head));
+/*
+     inflateGetHeader() requests that gzip header information be stored in the
+   provided gz_header structure.  inflateGetHeader() may be called after
+   inflateInit2() or inflateReset(), and before the first call of inflate().
+   As inflate() processes the gzip stream, head->done is zero until the header
+   is completed, at which time head->done is set to one.  If a zlib stream is
+   being decoded, then head->done is set to -1 to indicate that there will be
+   no gzip header information forthcoming.  Note that Z_BLOCK or Z_TREES can be
+   used to force inflate() to return immediately after header processing is
+   complete and before any actual data is decompressed.
+
+     The text, time, xflags, and os fields are filled in with the gzip header
+   contents.  hcrc is set to true if there is a header CRC.  (The header CRC
+   was valid if done is set to one.) If extra is not Z_NULL, then extra_max
+   contains the maximum number of bytes to write to extra.  Once done is true,
+   extra_len contains the actual extra field length, and extra contains the
+   extra field, or that field truncated if extra_max is less than extra_len.
+   If name is not Z_NULL, then up to name_max characters are written there,
+   terminated with a zero unless the length is greater than name_max.  If
+   comment is not Z_NULL, then up to comm_max characters are written there,
+   terminated with a zero unless the length is greater than comm_max.  When any
+   of extra, name, or comment are not Z_NULL and the respective field is not
+   present in the header, then that field is set to Z_NULL to signal its
+   absence.  This allows the use of deflateSetHeader() with the returned
+   structure to duplicate the header.  However if those fields are set to
+   allocated memory, then the application will need to save those pointers
+   elsewhere so that they can be eventually freed.
+
+     If inflateGetHeader is not used, then the header information is simply
+   discarded.  The header is always checked for validity, including the header
+   CRC if present.  inflateReset() will reset the process to discard the header
+   information.  The application would need to call inflateGetHeader() again to
+   retrieve the header from the next gzip stream.
+
+     inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
+                                        unsigned char FAR *window));
+
+     Initialize the internal stream state for decompression using inflateBack()
+   calls.  The fields zalloc, zfree and opaque in strm must be initialized
+   before the call.  If zalloc and zfree are Z_NULL, then the default library-
+   derived memory allocation routines are used.  windowBits is the base two
+   logarithm of the window size, in the range 8..15.  window is a caller
+   supplied buffer of that size.  Except for special applications where it is
+   assured that deflate was used with small window sizes, windowBits must be 15
+   and a 32K byte window must be supplied to be able to decompress general
+   deflate streams.
+
+     See inflateBack() for the usage of these routines.
+
+     inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
+   the parameters are invalid, Z_MEM_ERROR if the internal state could not be
+   allocated, or Z_VERSION_ERROR if the version of the library does not match
+   the version of the header file.
+*/
+
+typedef unsigned (*in_func) OF((void FAR *,
+                                z_const unsigned char FAR * FAR *));
+typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
+
+ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
+                                    in_func in, void FAR *in_desc,
+                                    out_func out, void FAR *out_desc));
+/*
+     inflateBack() does a raw inflate with a single call using a call-back
+   interface for input and output.  This is potentially more efficient than
+   inflate() for file i/o applications, in that it avoids copying between the
+   output and the sliding window by simply making the window itself the output
+   buffer.  inflate() can be faster on modern CPUs when used with large
+   buffers.  inflateBack() trusts the application to not change the output
+   buffer passed by the output function, at least until inflateBack() returns.
+
+     inflateBackInit() must be called first to allocate the internal state
+   and to initialize the state with the user-provided window buffer.
+   inflateBack() may then be used multiple times to inflate a complete, raw
+   deflate stream with each call.  inflateBackEnd() is then called to free the
+   allocated state.
+
+     A raw deflate stream is one with no zlib or gzip header or trailer.
+   This routine would normally be used in a utility that reads zip or gzip
+   files and writes out uncompressed files.  The utility would decode the
+   header and process the trailer on its own, hence this routine expects only
+   the raw deflate stream to decompress.  This is different from the default
+   behavior of inflate(), which expects a zlib header and trailer around the
+   deflate stream.
+
+     inflateBack() uses two subroutines supplied by the caller that are then
+   called by inflateBack() for input and output.  inflateBack() calls those
+   routines until it reads a complete deflate stream and writes out all of the
+   uncompressed data, or until it encounters an error.  The function's
+   parameters and return types are defined above in the in_func and out_func
+   typedefs.  inflateBack() will call in(in_desc, &buf) which should return the
+   number of bytes of provided input, and a pointer to that input in buf.  If
+   there is no input available, in() must return zero -- buf is ignored in that
+   case -- and inflateBack() will return a buffer error.  inflateBack() will
+   call out(out_desc, buf, len) to write the uncompressed data buf[0..len-1].
+   out() should return zero on success, or non-zero on failure.  If out()
+   returns non-zero, inflateBack() will return with an error.  Neither in() nor
+   out() are permitted to change the contents of the window provided to
+   inflateBackInit(), which is also the buffer that out() uses to write from.
+   The length written by out() will be at most the window size.  Any non-zero
+   amount of input may be provided by in().
+
+     For convenience, inflateBack() can be provided input on the first call by
+   setting strm->next_in and strm->avail_in.  If that input is exhausted, then
+   in() will be called.  Therefore strm->next_in must be initialized before
+   calling inflateBack().  If strm->next_in is Z_NULL, then in() will be called
+   immediately for input.  If strm->next_in is not Z_NULL, then strm->avail_in
+   must also be initialized, and then if strm->avail_in is not zero, input will
+   initially be taken from strm->next_in[0 ..  strm->avail_in - 1].
+
+     The in_desc and out_desc parameters of inflateBack() is passed as the
+   first parameter of in() and out() respectively when they are called.  These
+   descriptors can be optionally used to pass any information that the caller-
+   supplied in() and out() functions need to do their job.
+
+     On return, inflateBack() will set strm->next_in and strm->avail_in to
+   pass back any unused input that was provided by the last in() call.  The
+   return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR
+   if in() or out() returned an error, Z_DATA_ERROR if there was a format error
+   in the deflate stream (in which case strm->msg is set to indicate the nature
+   of the error), or Z_STREAM_ERROR if the stream was not properly initialized.
+   In the case of Z_BUF_ERROR, an input or output error can be distinguished
+   using strm->next_in which will be Z_NULL only if in() returned an error.  If
+   strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning
+   non-zero.  (in() will always be called before out(), so strm->next_in is
+   assured to be defined if out() returns non-zero.)  Note that inflateBack()
+   cannot return Z_OK.
+*/
+
+ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
+/*
+     All memory allocated by inflateBackInit() is freed.
+
+     inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream
+   state was inconsistent.
+*/
+
+ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
+/* Return flags indicating compile-time options.
+
+    Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:
+     1.0: size of uInt
+     3.2: size of uLong
+     5.4: size of voidpf (pointer)
+     7.6: size of z_off_t
+
+    Compiler, assembler, and debug options:
+     8: ZLIB_DEBUG
+     9: ASMV or ASMINF -- use ASM code
+     10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention
+     11: 0 (reserved)
+
+    One-time table building (smaller code, but not thread-safe if true):
+     12: BUILDFIXED -- build static block decoding tables when needed
+     13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed
+     14,15: 0 (reserved)
+
+    Library content (indicates missing functionality):
+     16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking
+                          deflate code when not needed)
+     17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect
+                    and decode gzip streams (to avoid linking crc code)
+     18-19: 0 (reserved)
+
+    Operation variations (changes in library functionality):
+     20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate
+     21: FASTEST -- deflate algorithm with only one, lowest compression level
+     22,23: 0 (reserved)
+
+    The sprintf variant used by gzprintf (zero is best):
+     24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format
+     25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure!
+     26: 0 = returns value, 1 = void -- 1 means inferred string length returned
+
+    Remainder:
+     27-31: 0 (reserved)
+ */
+
+#ifndef Z_SOLO
+
+                        /* utility functions */
+
+/*
+     The following utility functions are implemented on top of the basic
+   stream-oriented functions.  To simplify the interface, some default options
+   are assumed (compression level and memory usage, standard memory allocation
+   functions).  The source code of these utility functions can be modified if
+   you need special options.
+*/
+
+ZEXTERN int ZEXPORT compress OF((Bytef *dest,   uLongf *destLen,
+                                 const Bytef *source, uLong sourceLen));
+/*
+     Compresses the source buffer into the destination buffer.  sourceLen is
+   the byte length of the source buffer.  Upon entry, destLen is the total size
+   of the destination buffer, which must be at least the value returned by
+   compressBound(sourceLen).  Upon exit, destLen is the actual size of the
+   compressed data.  compress() is equivalent to compress2() with a level
+   parameter of Z_DEFAULT_COMPRESSION.
+
+     compress returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_BUF_ERROR if there was not enough room in the output
+   buffer.
+*/
+
+ZEXTERN int ZEXPORT compress2 OF((Bytef *dest,   uLongf *destLen,
+                                  const Bytef *source, uLong sourceLen,
+                                  int level));
+/*
+     Compresses the source buffer into the destination buffer.  The level
+   parameter has the same meaning as in deflateInit.  sourceLen is the byte
+   length of the source buffer.  Upon entry, destLen is the total size of the
+   destination buffer, which must be at least the value returned by
+   compressBound(sourceLen).  Upon exit, destLen is the actual size of the
+   compressed data.
+
+     compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+   Z_STREAM_ERROR if the level parameter is invalid.
+*/
+
+ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
+/*
+     compressBound() returns an upper bound on the compressed size after
+   compress() or compress2() on sourceLen bytes.  It would be used before a
+   compress() or compress2() call to allocate the destination buffer.
+*/
+
+ZEXTERN int ZEXPORT uncompress OF((Bytef *dest,   uLongf *destLen,
+                                   const Bytef *source, uLong sourceLen));
+/*
+     Decompresses the source buffer into the destination buffer.  sourceLen is
+   the byte length of the source buffer.  Upon entry, destLen is the total size
+   of the destination buffer, which must be large enough to hold the entire
+   uncompressed data.  (The size of the uncompressed data must have been saved
+   previously by the compressor and transmitted to the decompressor by some
+   mechanism outside the scope of this compression library.) Upon exit, destLen
+   is the actual size of the uncompressed data.
+
+     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_BUF_ERROR if there was not enough room in the output
+   buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.  In
+   the case where there is not enough room, uncompress() will fill the output
+   buffer with the uncompressed data up to that point.
+*/
+
+ZEXTERN int ZEXPORT uncompress2 OF((Bytef *dest,   uLongf *destLen,
+                                    const Bytef *source, uLong *sourceLen));
+/*
+     Same as uncompress, except that sourceLen is a pointer, where the
+   length of the source is *sourceLen.  On return, *sourceLen is the number of
+   source bytes consumed.
+*/
+
+                        /* gzip file access functions */
+
+/*
+     This library supports reading and writing files in gzip (.gz) format with
+   an interface similar to that of stdio, using the functions that start with
+   "gz".  The gzip format is different from the zlib format.  gzip is a gzip
+   wrapper, documented in RFC 1952, wrapped around a deflate stream.
+*/
+
+typedef struct gzFile_s *gzFile;    /* semi-opaque gzip file descriptor */
+
+/*
+ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
+
+     Opens a gzip (.gz) file for reading or writing.  The mode parameter is as
+   in fopen ("rb" or "wb") but can also include a compression level ("wb9") or
+   a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only
+   compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F'
+   for fixed code compression as in "wb9F".  (See the description of
+   deflateInit2 for more information about the strategy parameter.)  'T' will
+   request transparent writing or appending with no compression and not using
+   the gzip format.
+
+     "a" can be used instead of "w" to request that the gzip stream that will
+   be written be appended to the file.  "+" will result in an error, since
+   reading and writing to the same gzip file is not supported.  The addition of
+   "x" when writing will create the file exclusively, which fails if the file
+   already exists.  On systems that support it, the addition of "e" when
+   reading or writing will set the flag to close the file on an execve() call.
+
+     These functions, as well as gzip, will read and decode a sequence of gzip
+   streams in a file.  The append function of gzopen() can be used to create
+   such a file.  (Also see gzflush() for another way to do this.)  When
+   appending, gzopen does not test whether the file begins with a gzip stream,
+   nor does it look for the end of the gzip streams to begin appending.  gzopen
+   will simply append a gzip stream to the existing file.
+
+     gzopen can be used to read a file which is not in gzip format; in this
+   case gzread will directly read from the file without decompression.  When
+   reading, this will be detected automatically by looking for the magic two-
+   byte gzip header.
+
+     gzopen returns NULL if the file could not be opened, if there was
+   insufficient memory to allocate the gzFile state, or if an invalid mode was
+   specified (an 'r', 'w', or 'a' was not provided, or '+' was provided).
+   errno can be checked to determine if the reason gzopen failed was that the
+   file could not be opened.
+*/
+
+ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
+/*
+     gzdopen associates a gzFile with the file descriptor fd.  File descriptors
+   are obtained from calls like open, dup, creat, pipe or fileno (if the file
+   has been previously opened with fopen).  The mode parameter is as in gzopen.
+
+     The next call of gzclose on the returned gzFile will also close the file
+   descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor
+   fd.  If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd,
+   mode);.  The duplicated descriptor should be saved to avoid a leak, since
+   gzdopen does not close fd if it fails.  If you are using fileno() to get the
+   file descriptor from a FILE *, then you will have to use dup() to avoid
+   double-close()ing the file descriptor.  Both gzclose() and fclose() will
+   close the associated file descriptor, so they need to have different file
+   descriptors.
+
+     gzdopen returns NULL if there was insufficient memory to allocate the
+   gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not
+   provided, or '+' was provided), or if fd is -1.  The file descriptor is not
+   used until the next gz* read, write, seek, or close operation, so gzdopen
+   will not detect if fd is invalid (unless fd is -1).
+*/
+
+ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size));
+/*
+     Set the internal buffer size used by this library's functions.  The
+   default buffer size is 8192 bytes.  This function must be called after
+   gzopen() or gzdopen(), and before any other calls that read or write the
+   file.  The buffer memory allocation is always deferred to the first read or
+   write.  Three times that size in buffer space is allocated.  A larger buffer
+   size of, for example, 64K or 128K bytes will noticeably increase the speed
+   of decompression (reading).
+
+     The new buffer size also affects the maximum length for gzprintf().
+
+     gzbuffer() returns 0 on success, or -1 on failure, such as being called
+   too late.
+*/
+
+ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
+/*
+     Dynamically update the compression level or strategy.  See the description
+   of deflateInit2 for the meaning of these parameters.  Previously provided
+   data is flushed before the parameter change.
+
+     gzsetparams returns Z_OK if success, Z_STREAM_ERROR if the file was not
+   opened for writing, Z_ERRNO if there is an error writing the flushed data,
+   or Z_MEM_ERROR if there is a memory allocation error.
+*/
+
+ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
+/*
+     Reads the given number of uncompressed bytes from the compressed file.  If
+   the input file is not in gzip format, gzread copies the given number of
+   bytes into the buffer directly from the file.
+
+     After reaching the end of a gzip stream in the input, gzread will continue
+   to read, looking for another gzip stream.  Any number of gzip streams may be
+   concatenated in the input file, and will all be decompressed by gzread().
+   If something other than a gzip stream is encountered after a gzip stream,
+   that remaining trailing garbage is ignored (and no error is returned).
+
+     gzread can be used to read a gzip file that is being concurrently written.
+   Upon reaching the end of the input, gzread will return with the available
+   data.  If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then
+   gzclearerr can be used to clear the end of file indicator in order to permit
+   gzread to be tried again.  Z_OK indicates that a gzip stream was completed
+   on the last gzread.  Z_BUF_ERROR indicates that the input file ended in the
+   middle of a gzip stream.  Note that gzread does not return -1 in the event
+   of an incomplete gzip stream.  This error is deferred until gzclose(), which
+   will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip
+   stream.  Alternatively, gzerror can be used before gzclose to detect this
+   case.
+
+     gzread returns the number of uncompressed bytes actually read, less than
+   len for end of file, or -1 for error.  If len is too large to fit in an int,
+   then nothing is read, -1 is returned, and the error state is set to
+   Z_STREAM_ERROR.
+*/
+
+ZEXTERN z_size_t ZEXPORT gzfread OF((voidp buf, z_size_t size, z_size_t nitems,
+                                     gzFile file));
+/*
+     Read up to nitems items of size size from file to buf, otherwise operating
+   as gzread() does.  This duplicates the interface of stdio's fread(), with
+   size_t request and return types.  If the library defines size_t, then
+   z_size_t is identical to size_t.  If not, then z_size_t is an unsigned
+   integer type that can contain a pointer.
+
+     gzfread() returns the number of full items read of size size, or zero if
+   the end of the file was reached and a full item could not be read, or if
+   there was an error.  gzerror() must be consulted if zero is returned in
+   order to determine if there was an error.  If the multiplication of size and
+   nitems overflows, i.e. the product does not fit in a z_size_t, then nothing
+   is read, zero is returned, and the error state is set to Z_STREAM_ERROR.
+
+     In the event that the end of file is reached and only a partial item is
+   available at the end, i.e. the remaining uncompressed data length is not a
+   multiple of size, then the final partial item is nevetheless read into buf
+   and the end-of-file flag is set.  The length of the partial item read is not
+   provided, but could be inferred from the result of gztell().  This behavior
+   is the same as the behavior of fread() implementations in common libraries,
+   but it prevents the direct use of gzfread() to read a concurrently written
+   file, reseting and retrying on end-of-file, when size is not 1.
+*/
+
+ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
+                                voidpc buf, unsigned len));
+/*
+     Writes the given number of uncompressed bytes into the compressed file.
+   gzwrite returns the number of uncompressed bytes written or 0 in case of
+   error.
+*/
+
+ZEXTERN z_size_t ZEXPORT gzfwrite OF((voidpc buf, z_size_t size,
+                                      z_size_t nitems, gzFile file));
+/*
+     gzfwrite() writes nitems items of size size from buf to file, duplicating
+   the interface of stdio's fwrite(), with size_t request and return types.  If
+   the library defines size_t, then z_size_t is identical to size_t.  If not,
+   then z_size_t is an unsigned integer type that can contain a pointer.
+
+     gzfwrite() returns the number of full items written of size size, or zero
+   if there was an error.  If the multiplication of size and nitems overflows,
+   i.e. the product does not fit in a z_size_t, then nothing is written, zero
+   is returned, and the error state is set to Z_STREAM_ERROR.
+*/
+
+ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...));
+/*
+     Converts, formats, and writes the arguments to the compressed file under
+   control of the format string, as in fprintf.  gzprintf returns the number of
+   uncompressed bytes actually written, or a negative zlib error code in case
+   of error.  The number of uncompressed bytes written is limited to 8191, or
+   one less than the buffer size given to gzbuffer().  The caller should assure
+   that this limit is not exceeded.  If it is exceeded, then gzprintf() will
+   return an error (0) with nothing written.  In this case, there may also be a
+   buffer overflow with unpredictable consequences, which is possible only if
+   zlib was compiled with the insecure functions sprintf() or vsprintf()
+   because the secure snprintf() or vsnprintf() functions were not available.
+   This can be determined using zlibCompileFlags().
+*/
+
+ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
+/*
+     Writes the given null-terminated string to the compressed file, excluding
+   the terminating null character.
+
+     gzputs returns the number of characters written, or -1 in case of error.
+*/
+
+ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
+/*
+     Reads bytes from the compressed file until len-1 characters are read, or a
+   newline character is read and transferred to buf, or an end-of-file
+   condition is encountered.  If any characters are read or if len == 1, the
+   string is terminated with a null character.  If no characters are read due
+   to an end-of-file or len < 1, then the buffer is left untouched.
+
+     gzgets returns buf which is a null-terminated string, or it returns NULL
+   for end-of-file or in case of error.  If there was an error, the contents at
+   buf are indeterminate.
+*/
+
+ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
+/*
+     Writes c, converted to an unsigned char, into the compressed file.  gzputc
+   returns the value that was written, or -1 in case of error.
+*/
+
+ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
+/*
+     Reads one byte from the compressed file.  gzgetc returns this byte or -1
+   in case of end of file or error.  This is implemented as a macro for speed.
+   As such, it does not do all of the checking the other functions do.  I.e.
+   it does not check to see if file is NULL, nor whether the structure file
+   points to has been clobbered or not.
+*/
+
+ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
+/*
+     Push one character back onto the stream to be read as the first character
+   on the next read.  At least one character of push-back is allowed.
+   gzungetc() returns the character pushed, or -1 on failure.  gzungetc() will
+   fail if c is -1, and may fail if a character has been pushed but not read
+   yet.  If gzungetc is used immediately after gzopen or gzdopen, at least the
+   output buffer size of pushed characters is allowed.  (See gzbuffer above.)
+   The pushed character will be discarded if the stream is repositioned with
+   gzseek() or gzrewind().
+*/
+
+ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
+/*
+     Flushes all pending output into the compressed file.  The parameter flush
+   is as in the deflate() function.  The return value is the zlib error number
+   (see function gzerror below).  gzflush is only permitted when writing.
+
+     If the flush parameter is Z_FINISH, the remaining data is written and the
+   gzip stream is completed in the output.  If gzwrite() is called again, a new
+   gzip stream will be started in the output.  gzread() is able to read such
+   concatenated gzip streams.
+
+     gzflush should be called only when strictly necessary because it will
+   degrade compression if called too often.
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
+                                   z_off_t offset, int whence));
+
+     Sets the starting position for the next gzread or gzwrite on the given
+   compressed file.  The offset represents a number of bytes in the
+   uncompressed data stream.  The whence parameter is defined as in lseek(2);
+   the value SEEK_END is not supported.
+
+     If the file is opened for reading, this function is emulated but can be
+   extremely slow.  If the file is opened for writing, only forward seeks are
+   supported; gzseek then compresses a sequence of zeroes up to the new
+   starting position.
+
+     gzseek returns the resulting offset location as measured in bytes from
+   the beginning of the uncompressed stream, or -1 in case of error, in
+   particular if the file is opened for writing and the new starting position
+   would be before the current position.
+*/
+
+ZEXTERN int ZEXPORT    gzrewind OF((gzFile file));
+/*
+     Rewinds the given file. This function is supported only for reading.
+
+     gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT    gztell OF((gzFile file));
+
+     Returns the starting position for the next gzread or gzwrite on the given
+   compressed file.  This position represents a number of bytes in the
+   uncompressed data stream, and is zero when starting, even if appending or
+   reading a gzip stream from the middle of a file using gzdopen().
+
+     gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file));
+
+     Returns the current offset in the file being read or written.  This offset
+   includes the count of bytes that precede the gzip stream, for example when
+   appending or when using gzdopen() for reading.  When reading, the offset
+   does not include as yet unused buffered input.  This information can be used
+   for a progress indicator.  On error, gzoffset() returns -1.
+*/
+
+ZEXTERN int ZEXPORT gzeof OF((gzFile file));
+/*
+     Returns true (1) if the end-of-file indicator has been set while reading,
+   false (0) otherwise.  Note that the end-of-file indicator is set only if the
+   read tried to go past the end of the input, but came up short.  Therefore,
+   just like feof(), gzeof() may return false even if there is no more data to
+   read, in the event that the last read request was for the exact number of
+   bytes remaining in the input file.  This will happen if the input file size
+   is an exact multiple of the buffer size.
+
+     If gzeof() returns true, then the read functions will return no more data,
+   unless the end-of-file indicator is reset by gzclearerr() and the input file
+   has grown since the previous end of file was detected.
+*/
+
+ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
+/*
+     Returns true (1) if file is being copied directly while reading, or false
+   (0) if file is a gzip stream being decompressed.
+
+     If the input file is empty, gzdirect() will return true, since the input
+   does not contain a gzip stream.
+
+     If gzdirect() is used immediately after gzopen() or gzdopen() it will
+   cause buffers to be allocated to allow reading the file to determine if it
+   is a gzip file.  Therefore if gzbuffer() is used, it should be called before
+   gzdirect().
+
+     When writing, gzdirect() returns true (1) if transparent writing was
+   requested ("wT" for the gzopen() mode), or false (0) otherwise.  (Note:
+   gzdirect() is not needed when writing.  Transparent writing must be
+   explicitly requested, so the application already knows the answer.  When
+   linking statically, using gzdirect() will include all of the zlib code for
+   gzip file reading and decompression, which may not be desired.)
+*/
+
+ZEXTERN int ZEXPORT    gzclose OF((gzFile file));
+/*
+     Flushes all pending output if necessary, closes the compressed file and
+   deallocates the (de)compression state.  Note that once file is closed, you
+   cannot call gzerror with file, since its structures have been deallocated.
+   gzclose must not be called more than once on the same file, just as free
+   must not be called more than once on the same allocation.
+
+     gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a
+   file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the
+   last read ended in the middle of a gzip stream, or Z_OK on success.
+*/
+
+ZEXTERN int ZEXPORT gzclose_r OF((gzFile file));
+ZEXTERN int ZEXPORT gzclose_w OF((gzFile file));
+/*
+     Same as gzclose(), but gzclose_r() is only for use when reading, and
+   gzclose_w() is only for use when writing or appending.  The advantage to
+   using these instead of gzclose() is that they avoid linking in zlib
+   compression or decompression code that is not used when only reading or only
+   writing respectively.  If gzclose() is used, then both compression and
+   decompression code will be included the application when linking to a static
+   zlib library.
+*/
+
+ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
+/*
+     Returns the error message for the last error which occurred on the given
+   compressed file.  errnum is set to zlib error number.  If an error occurred
+   in the file system and not in the compression library, errnum is set to
+   Z_ERRNO and the application may consult errno to get the exact error code.
+
+     The application must not modify the returned string.  Future calls to
+   this function may invalidate the previously returned string.  If file is
+   closed, then the string previously returned by gzerror will no longer be
+   available.
+
+     gzerror() should be used to distinguish errors from end-of-file for those
+   functions above that do not distinguish those cases in their return values.
+*/
+
+ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
+/*
+     Clears the error and end-of-file flags for file.  This is analogous to the
+   clearerr() function in stdio.  This is useful for continuing to read a gzip
+   file that is being written concurrently.
+*/
+
+#endif /* !Z_SOLO */
+
+                        /* checksum functions */
+
+/*
+     These functions are not related to compression but are exported
+   anyway because they might be useful in applications using the compression
+   library.
+*/
+
+ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
+/*
+     Update a running Adler-32 checksum with the bytes buf[0..len-1] and
+   return the updated checksum.  If buf is Z_NULL, this function returns the
+   required initial value for the checksum.
+
+     An Adler-32 checksum is almost as reliable as a CRC-32 but can be computed
+   much faster.
+
+   Usage example:
+
+     uLong adler = adler32(0L, Z_NULL, 0);
+
+     while (read_buffer(buffer, length) != EOF) {
+       adler = adler32(adler, buffer, length);
+     }
+     if (adler != original_adler) error();
+*/
+
+ZEXTERN uLong ZEXPORT adler32_z OF((uLong adler, const Bytef *buf,
+                                    z_size_t len));
+/*
+     Same as adler32(), but with a size_t length.
+*/
+
+/*
+ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
+                                          z_off_t len2));
+
+     Combine two Adler-32 checksums into one.  For two sequences of bytes, seq1
+   and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
+   each, adler1 and adler2.  adler32_combine() returns the Adler-32 checksum of
+   seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.  Note
+   that the z_off_t type (like off_t) is a signed integer.  If len2 is
+   negative, the result has no meaning or utility.
+*/
+
+ZEXTERN uLong ZEXPORT crc32   OF((uLong crc, const Bytef *buf, uInt len));
+/*
+     Update a running CRC-32 with the bytes buf[0..len-1] and return the
+   updated CRC-32.  If buf is Z_NULL, this function returns the required
+   initial value for the crc.  Pre- and post-conditioning (one's complement) is
+   performed within this function so it shouldn't be done by the application.
+
+   Usage example:
+
+     uLong crc = crc32(0L, Z_NULL, 0);
+
+     while (read_buffer(buffer, length) != EOF) {
+       crc = crc32(crc, buffer, length);
+     }
+     if (crc != original_crc) error();
+*/
+
+ZEXTERN uLong ZEXPORT crc32_z OF((uLong adler, const Bytef *buf,
+                                  z_size_t len));
+/*
+     Same as crc32(), but with a size_t length.
+*/
+
+/*
+ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
+
+     Combine two CRC-32 check values into one.  For two sequences of bytes,
+   seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
+   calculated for each, crc1 and crc2.  crc32_combine() returns the CRC-32
+   check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
+   len2.
+*/
+
+
+                        /* various hacks, don't look :) */
+
+/* deflateInit and inflateInit are macros to allow checking the zlib version
+ * and the compiler's view of z_stream:
+ */
+ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
+                                     const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
+                                     const char *version, int stream_size));
+ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int  level, int  method,
+                                      int windowBits, int memLevel,
+                                      int strategy, const char *version,
+                                      int stream_size));
+ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int  windowBits,
+                                      const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
+                                         unsigned char FAR *window,
+                                         const char *version,
+                                         int stream_size));
+#ifdef Z_PREFIX_SET
+#  define z_deflateInit(strm, level) \
+          deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream))
+#  define z_inflateInit(strm) \
+          inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream))
+#  define z_deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
+          deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
+                        (strategy), ZLIB_VERSION, (int)sizeof(z_stream))
+#  define z_inflateInit2(strm, windowBits) \
+          inflateInit2_((strm), (windowBits), ZLIB_VERSION, \
+                        (int)sizeof(z_stream))
+#  define z_inflateBackInit(strm, windowBits, window) \
+          inflateBackInit_((strm), (windowBits), (window), \
+                           ZLIB_VERSION, (int)sizeof(z_stream))
+#else
+#  define deflateInit(strm, level) \
+          deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream))
+#  define inflateInit(strm) \
+          inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream))
+#  define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
+          deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
+                        (strategy), ZLIB_VERSION, (int)sizeof(z_stream))
+#  define inflateInit2(strm, windowBits) \
+          inflateInit2_((strm), (windowBits), ZLIB_VERSION, \
+                        (int)sizeof(z_stream))
+#  define inflateBackInit(strm, windowBits, window) \
+          inflateBackInit_((strm), (windowBits), (window), \
+                           ZLIB_VERSION, (int)sizeof(z_stream))
+#endif
+
+#ifndef Z_SOLO
+
+/* gzgetc() macro and its supporting function and exposed data structure.  Note
+ * that the real internal state is much larger than the exposed structure.
+ * This abbreviated structure exposes just enough for the gzgetc() macro.  The
+ * user should not mess with these exposed elements, since their names or
+ * behavior could change in the future, perhaps even capriciously.  They can
+ * only be used by the gzgetc() macro.  You have been warned.
+ */
+struct gzFile_s {
+    unsigned have;
+    unsigned char *next;
+    z_off64_t pos;
+};
+ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file));  /* backward compatibility */
+#ifdef Z_PREFIX_SET
+#  undef z_gzgetc
+#  define z_gzgetc(g) \
+          ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g))
+#else
+#  define gzgetc(g) \
+          ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g))
+#endif
+
+/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or
+ * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if
+ * both are true, the application gets the *64 functions, and the regular
+ * functions are changed to 64 bits) -- in case these are set on systems
+ * without large file support, _LFS64_LARGEFILE must also be true
+ */
+#ifdef Z_LARGE64
+   ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+   ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
+   ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
+   ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
+   ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t));
+   ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t));
+#endif
+
+#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64)
+#  ifdef Z_PREFIX_SET
+#    define z_gzopen z_gzopen64
+#    define z_gzseek z_gzseek64
+#    define z_gztell z_gztell64
+#    define z_gzoffset z_gzoffset64
+#    define z_adler32_combine z_adler32_combine64
+#    define z_crc32_combine z_crc32_combine64
+#  else
+#    define gzopen gzopen64
+#    define gzseek gzseek64
+#    define gztell gztell64
+#    define gzoffset gzoffset64
+#    define adler32_combine adler32_combine64
+#    define crc32_combine crc32_combine64
+#  endif
+#  ifndef Z_LARGE64
+     ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+     ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int));
+     ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile));
+     ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile));
+     ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
+     ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
+#  endif
+#else
+   ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *));
+   ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int));
+   ZEXTERN z_off_t ZEXPORT gztell OF((gzFile));
+   ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile));
+   ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
+   ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
+#endif
+
+#else /* Z_SOLO */
+
+   ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
+   ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
+
+#endif /* !Z_SOLO */
+
+/* undocumented functions */
+ZEXTERN const char   * ZEXPORT zError           OF((int));
+ZEXTERN int            ZEXPORT inflateSyncPoint OF((z_streamp));
+ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table    OF((void));
+ZEXTERN int            ZEXPORT inflateUndermine OF((z_streamp, int));
+ZEXTERN int            ZEXPORT inflateValidate OF((z_streamp, int));
+ZEXTERN unsigned long  ZEXPORT inflateCodesUsed OF ((z_streamp));
+ZEXTERN int            ZEXPORT inflateResetKeep OF((z_streamp));
+ZEXTERN int            ZEXPORT deflateResetKeep OF((z_streamp));
+#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(Z_SOLO)
+ZEXTERN gzFile         ZEXPORT gzopen_w OF((const wchar_t *path,
+                                            const char *mode));
+#endif
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+#  ifndef Z_SOLO
+ZEXTERN int            ZEXPORTVA gzvprintf Z_ARG((gzFile file,
+                                                  const char *format,
+                                                  va_list va));
+#  endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ZLIB_H */