#ifndef D_CAMERA_H #define D_CAMERA_H #include "common.h" #include "d/d_base.h" #include "egg/gfx/eggCamera.h" #include "m/m_angle.h" #include "m/m_frustum.h" #include "m/m_mtx.h" #include "m/m_vec.h" #include "toBeSorted/d_camera_base.h" #include "toBeSorted/d_camera_event.h" #include "toBeSorted/d_camera_game.h" #include "toBeSorted/d_camera_map.h" class dCamera_c : public dBase_c { private: class substruct_1 { public: substruct_1() : mActive(false), mFSStickAngle(0), field_0x04(0) {} void setCamera(dCamera_c *cam); void fn_8019E890(); mAng fn_8019E930() const; void fn_8019E940(); private: void fn_8019E8D0(const mAng &ang); /* 0x00 */ bool mActive; /* 0x02 */ mAng mFSStickAngle; /* 0x04 */ mAng field_0x04; /* 0x08 */ dCamera_c *mpCamera; }; class screen_shaker { public: screen_shaker() {} void init(dCamera_c *cam) { mpCamera = cam; mScreenShakeIntensity = 0.0f; mShakeOffset = mVec3_c::Zero; } void setScreenShakeIntensity(f32 val) { mScreenShakeIntensity = val; } bool execute(); mVec3_c getShakeOffset() const; private: /* 0x00 */ dCamera_c *mpCamera; /* 0x04 */ f32 mScreenShakeIntensity; /* 0x08 */ mVec3_c mShakeOffset; }; enum CameraIdx_e { CAM_GAME_0, CAM_GAME_1, CAM_EVENT, CAM_MAP, CAM_MAX, }; enum Flags_e { CAM_FLAGS_MAP = (1 << 1), CAM_FLAGS_0x4 = (1 << 2), CAM_FLAGS_0x10 = (1 << 4), CAM_FLAGS_EVENT = (1 << 5), CAM_FLAGS_UNDERWATER = (1 << 6), CAM_FLAGS_IN_EVENT = (1 << 7), CAM_FLAGS_0x100 = (1 << 8), CAM_FLAGS_NO_LETTERBOX_IN_EVENT = (1 << 9), }; public: dCamera_c(); virtual int create() override; virtual int doDelete() override; virtual int execute() override; virtual int draw() override; void setWorldOffset(f32 x, f32 z); void setFrustum(f32 fov, f32 near, f32 far); dCameraGame_c *getGameCam1() { return static_cast(mpCameras[CAM_GAME_0]); } dCameraGame_c *getGameCam2() { return static_cast(mpCameras[CAM_GAME_1]); } dCameraEvent_c *getEventCam() { return static_cast(mpCameras[CAM_EVENT]); } dCameraMap_c *getMapCam() { return static_cast(mpCameras[CAM_MAP]); } const mVec3_c &getPosition() const { return mView.mPosition; } const mVec3_c &getTarget() const { return mView.mTarget; } f32 getWaterHeight() const { return mWaterHeight; } // TODO what makes this different? mAng getYRot() const; void setScreenShakeIntensity(f32 val) { mScreenShaker.setScreenShakeIntensity(val); } UNKWORD getField_0xDA8() const { return mActiveCameraIdx; } bool isUnderwater() const; f32 getUnderwaterDepth() const; bool fn_8019EA70(bool); bool setEventCamView(const mVec3_c &, const mVec3_c &, f32, f32); mAng getYAngle() const; mAng getXZAngle() const; void apply(); bool fn_8019E3C0() const; void enterMap(); void leaveMap(); bool fn_8019E4D0() const; f32 fn_8019EB90(); private: void onFlag(u32 flag) { mFlags |= flag; } void offFlag(u32 flag) { mFlags &= ~flag; } bool checkFlag(u32 flag) const { return mFlags & flag; } void updateView(); void applyTilt(); s32 setActiveCamera(s32 newCamIdx); void fn_8019DB80(); f32 fn_8019E1F0(); void checkCameraChange(); f32 getEventLetterboxAmount(); void updateUnderwaterDepth(const mVec3_c &pos); bool isUnderwater_() const; /* 0x068 */ s32 mMyCameraIndex; /* 0x06C */ CamView mView; /* 0x08C */ mVec3_c field_0x08C; /* 0x098 */ mAng mYAngle; /* 0x09A */ mAng mXZAngle; /* 0x09C */ mFrustum_c mFrustum; /* 0x18C */ mMtx_c mMtx; /* 0x1BC */ mMtx_c mMtxInv; /* 0x1EC */ u8 field_0x1EC[0x1F8 - 0x1EC]; /* 0x1F8 */ UNKWORD field_0x1F8; /* 0x1FC */ u8 field_0x1FC; /* 0x200 */ EGG::Screen *mpScreen; /* 0x204 */ EGG::LookAtCamera mLookAtCamera; /* 0x28C */ f32 mLetterboxAmount; /* 0x290 */ f32 field_0x290; /* 0x294 */ f32 mGlobalAlpha; /* 0x298 */ u8 field_0x298; /* 0x299 */ u8 field_0x299; /* 0x29C */ f32 field_0x29C; /* 0x2A0 */ u8 field_0x2A0; /* 0x2A1 */ u8 field_0x2A1; /* 0x2A4 */ f32 mUnderwaterDepth; /* 0x2A8 */ f32 mWaterHeight; /* 0x2AC */ bool mIsUnderwater; /* 0x2B0 */ u32 mFlags; /* 0x2B4 */ dCameraGame_c mGameCam1; /* 0x728 */ dCameraGame_c mGameCam2; /* 0xB9C */ dCameraEvent_c mEventCam; /* 0xCD0 */ dCameraMap_c mMapCam; /* 0xD98 */ dCameraBase_c *mpCameras[CAM_MAX]; /* 0xDA8 */ s32 mActiveCameraIdx; /* 0xDAC */ screen_shaker mScreenShaker; /* 0xDC0 */ substruct_1 field_0xDC0; /* 0xDCC */ bool field_0xDCC; /* 0xDD0 */ CamView mView1; }; #endif