//CReplay - [2020-04-13 11:57:47]
#ifndef _CREPLAY_H_
#define _CREPLAY_H_

#include "common.h"
#include "XMATH.h"

/*
001760EC CReplay::RecordFrame()
00176200 CReplay::Playing()
0017623C CReplay::FillFrame(TReplayFrame *)
0017643C CReplay::SetInfoPos(int,TPoint)
001764C0 CReplay::InitFirstFrame()
001765E0 CReplay::Available()
00176614 CReplay::SetState(EReplayState)
00176624 CReplay::SetExcludedPlayers()
00176674 CReplay::Play()
0017690C CReplay::GetState()
0017691C CReplay::ApplyFrameBlend(TReplayFrame *,TReplayFrame *,int,int)
00176F50 CReplay::Stop()
00176F64 CReplay::Shutdown()
00177014 CReplay::ShouldTranslateToUniform()
0017704C CReplay::IsPaused()
00177094 CReplay::RemovePreviousOffsideFlags()
001770C4 CReplay::SetView(EReplayView)
001770D4 CReplay::SetType(EReplayType)
001771D0 CReplay::GetView()
001771E0 CReplay::GetType()
001771F0 CReplay::IsAutoReplay()
00177208 CReplay::CheckFlipX(int)
0017721C CReplay::CheckFlipY(int)
00177230 CReplay::CheckFlipRot(int)
00177264 CReplay::ApplyFrame(TReplayFrame *)
001773E4 CReplay::Init()
00177438 CReplay::Reset(bool)
001774E4 CReplay::Free()
00177524 CReplay::PerformPendingSave()
00177590 CReplay::SetInfo(TReplayInfo *)
0017767C CReplay::Save(char *)
00177698 CReplay::Load(char *)
*/

//szieof = 0x16
#pragma pack(push,2)
struct TReplayFrame_PlayerInfo {
  ushort  us_0;
  ushort  us_2;
  uchar   uc_4;
  //uchar   unknown_5; // 
  ushort  us_6;
  ushort  us_8;

  union {
    struct {
      unsigned int a:8;
      unsigned int b:8;
      unsigned int c:4;
      unsigned int d:8;
    }s_0;
    uint    ui_0;
  } u_A;
  //uint    ui_A;

  uchar   uc_E; // 
  //uchar   unknown_F; // 
  short   sPosX_10;
  short   sPosY_12;
  short   sPosZ_14;
};

#pragma pack(pop)
//sizeof = 0x31C
struct TReplayFrame {
  TReplayFrame_PlayerInfo   tPlayersInfo_0[0x21];
  short                     sPosX_2D6;
  short                     sPosY_2D8;
  ushort                    usPosZ_2DA;
  uchar                     unknown_2DC[0x0C];
  signed char               cSfxBeingPlayed_2E8;
  char                      cSfxBeingPlayed_2E9; // ²¹Æë
  short                     sCommentaryBeingPlayed_2EA;
  signed char               cCrowdBeingPlayed_2EC;
  uchar                     uc_2ED;
  uchar                     ucFlags_2EE;
  uchar                     unknown_2EF[5];
  TQuat                     tQuat_2F4;
  uchar                     unknown_304[4];
  short                     s_308;
  short                     s_30A;
  bool                      bInControl_30C;
  bool                      bFirstControl_30D;
  float                     f_310;
  float                     f_314;
  float                     f_318;
};

enum EReplayState {
  EReplayState_0,
  EReplayState_1,
  EReplayState_2,
  EReplayState_3,
  EReplayState_4,
  EReplayState_5,
};

enum EReplayView {
  EReplayView_0,
  EReplayView_1,
  EReplayView_2,
  EReplayView_3,
  EReplayView_4,
  EReplayView_5,
  EReplayView_6,
  EReplayView_7,
  EReplayView_8,
  EReplayView_9,
};

enum EReplayType {
  EReplayType_0,
  EReplayType_1,
  EReplayType_2,
  EReplayType_3,
  EReplayType_4,
  EReplayType_5,
  EReplayType_6,
  EReplayType_7,
  EReplayType_8,
};

struct TReplayInfo {
  int un_0;
};
//sizeof = 0x5D4D4
class CReplay {
public:
  static void RecordFrame();                                              //001760EC
  static bool Playing();                                           //00176200
  static void FillFrame(TReplayFrame *);                                  //0017623C
  static void SetInfoPos(int, TPoint);                                    //0017643C
  static void InitFirstFrame();                                           //001764C0
  static bool Available();                                                //001765E0
  static void SetState(EReplayState);                                     //00176614
  static void SetExcludedPlayers();                                       //00176624
  static void Play();                                                     //00176674
  static void GetState();                                                 //0017690C
  static void ApplyFrameBlend(TReplayFrame *, TReplayFrame *, int, int);  //0017691C
  static void Stop();                                                     //00176F50
  static void Shutdown();                                                 //00176F64
  static void ShouldTranslateToUniform();                                 //00177014
  static bool IsPaused();                                           //0017704C
  static void RemovePreviousOffsideFlags();                        //00177094
  static void SetView(EReplayView);                                       //001770C4
  static void SetType(EReplayType);                                       //001770D4
  static void GetView();                                                  //001771D0
  static void GetType();                                                  //001771E0
  static void IsAutoReplay();                                             //001771F0
  static void CheckFlipX(int);                                            //00177208
  static void CheckFlipY(int);                                            //0017721C
  static int CheckFlipRot(int);                                          //00177230
  static void ApplyFrame(TReplayFrame *);                                 //00177264
  static void Init();                                              //001773E4
  static void Reset(bool);                                                //00177438
  static void Free();                                              //001774E4
  static bool PerformPendingSave();                                       //00177524
  static void SetInfo(TReplayInfo *);                                     //00177590
  static void Save(char *);                                               //0017767C
  static bool Load(char *);                                               //00177698

  static int s_iScoreCam; //003A413C 
  static int s_iFrameAbs; //003A4138 
  static int s_iPlayCur;  //003A4134
  static int s_iLastControl;   //003A4130
  static int s_iControl;   //003A412C 
  static EReplayType s_eReplayType;   //003A4128 
  static EReplayView s_eReplayView;   //003A4124 
  static uint s_eReplayState;   //003A4120 
  static char s_cPendingSave[0x20];   //003A4100 
  static bool m_bReplayAudio;   //003A40FF 
  static bool s_bPlayerExcluded[0x21];   //003A40DE 
  static int s_MRbReplayViewer; //003A40DD 
  static bool s_bUploadProcess;//003A40DC 
  static TReplayFrame* s_pCurrentFrame; //003A40D8 
  static int s_iReplayLastTick; //003A40D4 
  static bool s_bPlayersSetExplicit; //003A40D1 
  static int8 s_iReplayFlags;//003A40D0 
  static int s_vReplayView; //003A40C8 
  static int8 s_iFocusPlayer; //003A40C6 
  static int s_iReplayStep; //003A40C5 
  static bool s_bReplayFlipY; //003A40C4 
  static bool s_bReplayFlipX; //003A40C3 
  static int8 s_iPlaySpeed; //003A40C2 
  static bool s_bActualReplayAllowed; //003A40C1 
  static bool s_bReplaySlow; //003A40C0 
  static int s_iReplayPlayLen; //003A40BC 
  static CReplay* s_pReplayPlay; //003A40B8 
  static CReplay* s_pReplayRec; //003A40B4 
  static TPoint s_oldpos[0x21];    //003A3FAC 
  static TReplayFrame s_oldstate;  //003A3C90  

  TReplayFrame    m_tFrames_0[0x1E0];
  TPoint3D        m_tPt3D_5D480;
  TPoint3D        m_tPt3D_5D48C;
  TPoint3D        m_tPt3D_5D498;

  int             m_i_5D4A4;  // Last Frame Index?
  int             m_i_5D4A8;
  int             m_i_5D4AC;  // XX Len*0x10
  int             m_i_5D4B0;  // XX Frame Index?
  int             m_iMinutes_5D4B4;
  int             m_i_5D4B8;
  int             m_i_5D4BC;
  int             m_i_5D4C0;
  int             m_i_5D4C4;
  int             m_i_5D4C8;
  int             m_i_5D4CC;
  int             m_i_5D4D0;
};

#endif  //_CREPLAY_H_