diff --git a/docs/progress.svg b/docs/progress.svg index 58ed036f..2703ebfa 100644 --- a/docs/progress.svg +++ b/docs/progress.svg @@ -69,11 +69,11 @@ Tomb2.exe progress according to the physical function order: -2.67% (32) · 94.92% (1139) · 0.67% (8) · 1.75% (21) +5.50% (66) · 92.17% (1106) · 0.58% (7) · 1.75% (21) - - - + + + @@ -949,7 +949,7 @@ bool __cdecl WinInputInit(void); bool __cdecl DInputEnumDevices(JOYSTICK_LIST *joystickList); BOOL __stdcall DInputEnumDevicesCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef); -void __thiscall S_FlaggedString_Create(struct STRING_FLAGGED *string, DWORD size); +void __thiscall S_FlaggedString_Create(struct STRING_FLAGGED *string, int32_t size); JOYSTICK_NODE *__cdecl GetJoystick(GUID *lpGuid); void __cdecl DInputKeyboardCreate(void); void __cdecl DInputKeyboardRelease(void); @@ -970,24 +970,24 @@ sub_447B30 sub_447B40 sub_447B90 -struct SOUND_ADAPTER_NODE *__cdecl S_Audio_Sample_GetAdapter(GUID *guid); -void __cdecl S_Audio_Sample_CloseAllTracks(void); -bool __cdecl S_Audio_Sample_Load(int32_t sample_id, LPWAVEFORMATEX format, const void *data, int32_t data_size); -bool __cdecl S_Audio_Sample_IsTrackPlaying(int32_t track_id); -int32_t __cdecl S_Audio_Sample_Play(int32_t sample_id, int32_t volume, int32_t pitch, int32_t pan, int32_t flags); -int32_t __cdecl S_Audio_Sample_GetFreeTrackIndex(void); -void __cdecl S_Audio_Sample_AdjustTrackVolumeAndPan(int32_t track_id, int32_t volume, int32_t pan); -void __cdecl S_Audio_Sample_AdjustTrackPitch(int32_t track_id, int32_t pitch); -void __cdecl S_Audio_Sample_CloseTrack(int32_t track_id); -sub_447FA0 -bool __cdecl S_Audio_Sample_Init(void); -bool __cdecl S_Audio_Sample_DSoundEnumerate(struct SOUND_ADAPTER_LIST *adapter_list); -BOOL __stdcall S_Audio_Sample_DSoundEnumCallback(LPGUID guid, LPCTSTR description, LPCTSTR module, LPVOID context); -void __cdecl S_Audio_Sample_Init2(HWND hwnd); -bool __cdecl S_Audio_Sample_DSoundCreate(GUID *guid); -bool __cdecl S_Audio_Sample_DSoundBufferTest(void); -void __cdecl S_Audio_Sample_Shutdown(void); -bool __cdecl S_Audio_Sample_IsEnabled(void); +struct SOUND_ADAPTER_NODE *__cdecl S_Audio_Sample_GetAdapter(GUID *guid); +void __cdecl S_Audio_Sample_CloseAllTracks(void); +bool __cdecl S_Audio_Sample_Load(int32_t sample_id, LPWAVEFORMATEX format, const void *data, int32_t data_size); +bool __cdecl S_Audio_Sample_IsTrackPlaying(int32_t track_id); +int32_t __cdecl S_Audio_Sample_Play(int32_t sample_id, int32_t volume, int32_t pitch, int32_t pan, int32_t flags); +int32_t __cdecl S_Audio_Sample_GetFreeTrackIndex(void); +void __cdecl S_Audio_Sample_AdjustTrackVolumeAndPan(int32_t track_id, int32_t volume, int32_t pan); +void __cdecl S_Audio_Sample_AdjustTrackPitch(int32_t track_id, int32_t pitch); +void __cdecl S_Audio_Sample_CloseTrack(int32_t track_id); +sub_447FA0 +bool __cdecl S_Audio_Sample_Init(void); +bool __cdecl S_Audio_Sample_DSoundEnumerate(struct SOUND_ADAPTER_LIST *adapter_list); +BOOL __stdcall S_Audio_Sample_DSoundEnumCallback(LPGUID guid, LPCTSTR description, LPCTSTR module, LPVOID context); +void __cdecl S_Audio_Sample_Init2(HWND hwnd); +bool __cdecl S_Audio_Sample_DSoundCreate(GUID *guid); +bool __cdecl S_Audio_Sample_DSoundBufferTest(void); +void __cdecl S_Audio_Sample_Shutdown(void); +bool __cdecl S_Audio_Sample_IsEnabled(void); sub_448410 sub_448420 void __cdecl CreateScreenBuffers(void); @@ -1187,23 +1187,23 @@ void __cdecl CheckCheatMode(void); void __cdecl S_SaveSettings(void); void __cdecl S_LoadSettings(void); -int32_t __cdecl S_Audio_Sample_OutPlay(int32_t sample_id, uint16_t volume, int32_t pitch, int32_t pan); -int32_t __cdecl S_Audio_Sample_CalculateSampleVolume(int32_t volume); -int32_t __cdecl S_Audio_Sample_CalculateSamplePan(int16_t pan); -int32_t __cdecl S_Audio_Sample_OutPlayLooped(int32_t track_id, uint16_t volume, int32_t pitch, int32_t pan); -void __cdecl S_Audio_Sample_OutSetPanAndVolume(int32_t track_id, int32_t pan, uint16_t volume); -void __cdecl S_Audio_Sample_OutSetPitch(int32_t track_id, int32_t pitch); +int32_t __cdecl S_Audio_Sample_OutPlay(int32_t sample_id, uint16_t volume, int32_t pitch, int32_t pan); +int32_t __cdecl S_Audio_Sample_CalculateSampleVolume(int32_t volume); +int32_t __cdecl S_Audio_Sample_CalculateSamplePan(int16_t pan); +int32_t __cdecl S_Audio_Sample_OutPlayLooped(int32_t track_id, uint16_t volume, int32_t pitch, int32_t pan); +void __cdecl S_Audio_Sample_OutSetPanAndVolume(int32_t track_id, int32_t pan, uint16_t volume); +void __cdecl S_Audio_Sample_OutSetPitch(int32_t track_id, int32_t pitch); void __cdecl Sound_SetMasterVolume(int32_t volume); -void __cdecl S_Audio_Sample_OutCloseTrack(int32_t track_id); -void __cdecl S_Audio_Sample_OutCloseAllTracks(void); -BOOL __cdecl S_Audio_Sample_OutIsTrackPlaying(int32_t track_id); -bool __cdecl Music_Init(void); -void __cdecl Music_Shutdown(void); -void __cdecl Music_Play(int16_t track_id, bool is_looped); -void __cdecl Music_Stop(void); -bool __cdecl Music_PlaySynced(int32_t trackID); -int32_t __cdecl Music_GetFrames(void); -void __cdecl Music_SetVolume(int32_t volume); +void __cdecl S_Audio_Sample_OutCloseTrack(int32_t track_id); +void __cdecl S_Audio_Sample_OutCloseAllTracks(void); +BOOL __cdecl S_Audio_Sample_OutIsTrackPlaying(int32_t track_id); +bool __cdecl Music_Init(void); +void __cdecl Music_Shutdown(void); +void __cdecl Music_Play(int16_t track_id, bool is_looped); +void __cdecl Music_Stop(void); +bool __cdecl Music_PlaySynced(int32_t trackID); +int32_t __cdecl Music_GetFrames(void); +void __cdecl Music_SetVolume(int32_t volume); void __cdecl CopyBitmapPalette(RGB888 *srcPal, BYTE *srcBitmap, int32_t bitmapSize, RGB888 *destPal); BYTE __cdecl FindNearestPaletteEntry(RGB888 *palette, int32_t red, int32_t green, int32_t blue, bool ignoreSysPalette); void __cdecl SyncSurfacePalettes(void *srcData, int32_t width, int32_t height, int32_t srcPitch, RGB888 *srcPalette, void *dstData, int32_t dstPitch, RGB888 *dstPalette, bool preserveSysPalette); @@ -1281,11 +1281,11 @@ Tomb2.exe progress according to the function sizes: -2.94% · 96.73% · 0.02% · 0.31% +3.86% · 95.81% · 0.02% · 0.31% - - - + + + @@ -1531,7 +1531,7 @@ void __cdecl FireHarpoon(void); void __cdecl Output_InsertFlatRect_Sorted(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t z, uint8_t color_idx); void __cdecl ControlTwinkle(int16_t fx_num); -void __cdecl S_Audio_Sample_Init2(HWND hwnd); +void __cdecl S_Audio_Sample_Init2(HWND hwnd); void __cdecl SE_GraphicsDlgInit(HWND hwndDlg); void __cdecl SpinningBlade(int16_t item_num); void __cdecl LiftFloorCeiling(struct ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int32_t *floor, int32_t *ceiling); @@ -1625,7 +1625,7 @@ int16_t __cdecl TitleSequence(void); void __cdecl Inv_RingInit(struct RING_INFO *ring, int16_t type, struct INVENTORY_ITEM **list, int16_t qty, int16_t current, struct IMOTION_INFO *imo); void __cdecl ScreenShotPCX(void); -bool __cdecl S_Audio_Sample_Load(int32_t sample_id, LPWAVEFORMATEX format, const void *data, int32_t data_size); +bool __cdecl S_Audio_Sample_Load(int32_t sample_id, LPWAVEFORMATEX format, const void *data, int32_t data_size); void __cdecl lara_as_compress(struct ITEM_INFO *item, struct COLL_INFO *coll); void __cdecl CopterControl(int16_t item_num); void __cdecl ControlLavaBlob(int16_t fx_num); @@ -1676,7 +1676,7 @@ void __cdecl CalculateWibbleTable(void); void __cdecl Camera_RefreshFromTrigger(int16_t type, int16_t *data); int32_t __cdecl LaraTestWaterStepOut(struct ITEM_INFO *item, struct COLL_INFO *coll); -int32_t __cdecl S_Audio_Sample_Play(int32_t sample_id, int32_t volume, int32_t pitch, int32_t pan, int32_t flags); +int32_t __cdecl S_Audio_Sample_Play(int32_t sample_id, int32_t volume, int32_t pitch, int32_t pan, int32_t flags); void __cdecl LavaBurn(struct ITEM_INFO *item); void __cdecl RenderFinish(bool needToClearTextures); bool __cdecl DInputJoystickCreate(void); @@ -1685,7 +1685,7 @@ void __cdecl BigBowlControl(int16_t item_num); void __cdecl lara_slide_slope(struct ITEM_INFO *item, struct COLL_INFO *coll); bool __cdecl WinVidSpinMessageLoop(bool needWait); -BOOL __stdcall S_Audio_Sample_DSoundEnumCallback(LPGUID guid, LPCTSTR description, LPCTSTR module, LPVOID context); +BOOL __stdcall S_Audio_Sample_DSoundEnumCallback(LPGUID guid, LPCTSTR description, LPCTSTR module, LPVOID context); int32_t __cdecl TestWall(struct ITEM_INFO *item, int32_t front, int32_t right, int32_t down); int32_t __cdecl SkidooCheckGeton(int16_t item_num, struct COLL_INFO *coll); BOOL __cdecl SelectDrive(void); @@ -1734,7 +1734,7 @@ void __cdecl Output_QuickSort(int32_t left, int32_t right); void __cdecl LavaSpray(int16_t item_num); void __cdecl SmashWindow(int16_t item_num); -bool __cdecl S_Audio_Sample_DSoundBufferTest(void); +bool __cdecl S_Audio_Sample_DSoundBufferTest(void); BOOL __cdecl S_ReloadLevelGraphics(BOOL reloadPalettes, BOOL reloadTexPages); void __thiscall SE_LoadBitmapResource(BITMAP_RESOURCE *bmpRsrc, LPCTSTR lpName); void __cdecl Splash(struct ITEM_INFO *item); @@ -1821,7 +1821,7 @@ void __cdecl InitialiseFinalLevel(void); void __cdecl CreateClipper(void); void __cdecl ItemNewRoom(int16_t item_num, int16_t room_num); -bool __cdecl S_Audio_Sample_Init(void); +bool __cdecl S_Audio_Sample_Init(void); void __cdecl LaraCollideStop(struct ITEM_INFO *item, struct COLL_INFO *coll); void __cdecl swap_meshes_with_meshswap3(struct ITEM_INFO *item); void __cdecl LoadDemoExternal(LPCTSTR levelName); @@ -1853,7 +1853,7 @@ void __cdecl EffectNewRoom(int16_t fx_num, int16_t room_num); void __cdecl SE_AdvancedDlgUpdate(HWND hwndDlg); int32_t __cdecl GetFrames(struct ITEM_INFO *item, int16_t *frmptr[], int32_t *rate); -void __cdecl Music_SetVolume(int32_t volume); +void __cdecl Music_SetVolume(int32_t volume); int16_t *__cdecl Output_InsertObjectGT4_ZBuffered(int16_t *obj_ptr, int32_t num, enum SORT_TYPE sort_type); void __cdecl extra_as_sharkkill(struct ITEM_INFO *item, struct COLL_INFO *coll); bool __cdecl GetRegistryGuidValue(LPCTSTR lpValueName, GUID *value, GUID *defaultValue); @@ -1893,7 +1893,7 @@ void __cdecl lara_as_tread(struct ITEM_INFO *item, struct COLL_INFO *coll); int32_t __cdecl Targetable(struct ITEM_INFO *item, AI_INFO *info); void __cdecl lara_as_back(struct ITEM_INFO *item, struct COLL_INFO *coll); -bool __cdecl Music_PlaySynced(int32_t trackID); +bool __cdecl Music_PlaySynced(int32_t trackID); void __cdecl DrawSpriteItem(struct ITEM_INFO *item); void __cdecl lara_col_fallback(struct ITEM_INFO *item, struct COLL_INFO *coll); void __cdecl ControlBlood1(int16_t fx_num); @@ -1936,7 +1936,7 @@ void __cdecl LaraBubbles(struct ITEM_INFO *item); void __cdecl Door_Collision(int16_t item_num, struct ITEM_INFO *lara_item, struct COLL_INFO *coll); int32_t __cdecl Inv_RequestItem(int32_t itemNum); -bool __cdecl Music_Init(void); +bool __cdecl Music_Init(void); int16_t __cdecl Knife(int32_t x, int32_t y, int32_t z, int16_t speed, PHD_ANGLE yrot, int16_t room_num); void __cdecl DrawHair(void); void __cdecl lara_as_glide(struct ITEM_INFO *item, struct COLL_INFO *coll); @@ -1958,7 +1958,7 @@ void __cdecl CreatePictureBuffer(void); int32_t __cdecl Box_UpdateLOT(struct LOT_INFO *lot, int32_t expansion); void __cdecl RemoveDrawnItem(int16_t item_num); -void __cdecl Music_Play(int16_t track_id, bool is_looped); +void __cdecl Music_Play(int16_t track_id, bool is_looped); BOOL __cdecl UT_CenterWindow(HWND hWnd); void __cdecl UT_MemBlt(BYTE *dstBuf, DWORD dstX, DWORD dstY, DWORD width, DWORD height, DWORD dstPitch, BYTE *srcBuf, DWORD srcX, DWORD srcY, DWORD srcPitch); bool __cdecl Output_VisibleZClip(struct PHD_VBUF *vtx0, struct PHD_VBUF *vtx1, struct PHD_VBUF *vtx2); @@ -2000,7 +2000,7 @@ void __cdecl DecreaseScreenSize(void); void __cdecl InitialiseGameFlags(void); DWORD __cdecl CalculateCompatibleColor(COLOR_BIT_MASKS *mask, int32_t red, int32_t green, int32_t blue, int32_t alpha); -int32_t __cdecl Music_GetFrames(void); +int32_t __cdecl Music_GetFrames(void); bool __cdecl SE_RegisterSetupWindowClass(void); void __fastcall flatA(int32_t y0, int32_t y1, BYTE colorIdx); void __cdecl Inv_RingGetView(struct RING_INFO *ring, struct PHD_3DPOS *viewer); @@ -2063,7 +2063,7 @@ int32_t __cdecl LaraFallen(struct ITEM_INFO *item, struct COLL_INFO *coll); void __cdecl SmashItem(int16_t item_num, int32_t weapon_type); void __cdecl S_SetupBelowWater(BOOL underwater); -void __cdecl Music_Shutdown(void); +void __cdecl Music_Shutdown(void); bool __cdecl TIME_Init(void); LPCTSTR __cdecl GuidBinaryToString(GUID *guid); void __cdecl Creature_Underwater(struct ITEM_INFO *item, int32_t depth); @@ -2105,7 +2105,7 @@ int32_t __cdecl CalculateWindowWidth(int32_t width, int32_t height); DISPLAY_ADAPTER_NODE *__cdecl WinVidGetDisplayAdapter(GUID *lpGuid); DISPLAY_MODE *__thiscall InsertDisplayModeInListHead(DISPLAY_MODE_LIST *modeList); -struct SOUND_ADAPTER_NODE *__cdecl S_Audio_Sample_GetAdapter(GUID *guid); +struct SOUND_ADAPTER_NODE *__cdecl S_Audio_Sample_GetAdapter(GUID *guid); void __cdecl WinStopFMV(bool isPlayback); int32_t __fastcall Math_Atan(int32_t x, int32_t y); int32_t __cdecl Creature_Activate(int16_t item_num); @@ -2115,11 +2115,11 @@ HRESULT __cdecl DDrawSurfaceRestoreLost(LPDDS surface1, LPDDS surface2, bool blank); DWORD __cdecl GetRenderBitDepth(DWORD dwRGBBitCount); void __cdecl S_InsertBackPolygon(int32_t x0, int32_t y0, int32_t x1, int32_t y1); -int32_t __cdecl S_Audio_Sample_OutPlay(int32_t sample_id, uint16_t volume, int32_t pitch, int32_t pan); -int32_t __cdecl S_Audio_Sample_OutPlayLooped(int32_t track_id, uint16_t volume, int32_t pitch, int32_t pan); +int32_t __cdecl S_Audio_Sample_OutPlay(int32_t sample_id, uint16_t volume, int32_t pitch, int32_t pan); +int32_t __cdecl S_Audio_Sample_OutPlayLooped(int32_t track_id, uint16_t volume, int32_t pitch, int32_t pan); void __cdecl DrawGameInfo(int32_t timed); bool __thiscall CompareVideoModes(DISPLAY_MODE *mode1, DISPLAY_MODE *mode2); -bool __cdecl S_Audio_Sample_IsTrackPlaying(int32_t track_id); +bool __cdecl S_Audio_Sample_IsTrackPlaying(int32_t track_id); HRESULT __cdecl DDrawSurfaceCreate(LPDDSDESC dsp, LPDDS *surface); void __cdecl BitMaskGetNumberOfBits(DWORD bitMask, DWORD *bitDepth, DWORD *bitOffset); void __cdecl GetValidLevelsList(REQUEST_INFO *req); @@ -2159,7 +2159,7 @@ void __cdecl InitialiseRollingBall(int16_t item_num); int32_t __cdecl RenderErrorBox(int32_t errorCode); void __cdecl Shell_ExitSystem(const char *message); -void __cdecl S_Audio_Sample_OutCloseAllTracks(void); +void __cdecl S_Audio_Sample_OutCloseAllTracks(void); int32_t __cdecl CheckForHoldingState(int32_t state); int32_t __cdecl WeaponObject(int32_t weapon_type); void __cdecl DrawBridgeCeiling(struct ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int32_t *height); @@ -2180,10 +2180,10 @@ sub_447170 void __cdecl TempVideoRemove(void); sub_447B40 -int32_t __cdecl S_Audio_Sample_GetFreeTrackIndex(void); +int32_t __cdecl S_Audio_Sample_GetFreeTrackIndex(void); void __cdecl Shell_Shutdown(void); -void __cdecl S_Audio_Sample_OutSetPanAndVolume(int32_t track_id, int32_t pan, uint16_t volume); -void __cdecl Music_Stop(void); +void __cdecl S_Audio_Sample_OutSetPanAndVolume(int32_t track_id, int32_t pan, uint16_t volume); +void __cdecl Music_Stop(void); void __cdecl Output_DrawPolyGTMapPersp(int16_t *obj_ptr); void __cdecl Output_DrawPolyWGTMapPersp(int16_t *obj_ptr); void __cdecl Item_ShiftCol(struct ITEM_INFO *item, struct COLL_INFO *coll); @@ -2246,7 +2246,7 @@ void __cdecl phd_RotX_I(int16_t ang); void __cdecl phd_RotZ_I(int16_t ang); int32_t __cdecl GetRealTrack(int32_t track); -void __cdecl S_Audio_Sample_AdjustTrackPitch(int32_t track_id, int32_t pitch); +void __cdecl S_Audio_Sample_AdjustTrackPitch(int32_t track_id, int32_t pitch); void __cdecl S_CalculateStaticLight(int16_t adder); void __cdecl ControlRichochet1(int16_t fx_num); void __cdecl InitialiseFXArray(void); @@ -2265,8 +2265,8 @@ void __cdecl BridgeTilt2Floor(struct ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int32_t *height); sub_4471C0 sub_447B90 -void __cdecl S_Audio_Sample_CloseTrack(int32_t track_id); -void __cdecl S_Audio_Sample_CloseAllTracks(void); +void __cdecl S_Audio_Sample_CloseTrack(int32_t track_id); +void __cdecl S_Audio_Sample_CloseAllTracks(void); void __cdecl S_DrawScreenFBox(int32_t sx, int32_t sy, int32_t z, int32_t width, int32_t height, BYTE colorIdx, GOURAUD_FILL *gour, uint16_t flags); void __cdecl Demo_GetInput(void); int32_t __cdecl FlashIt(void); @@ -2279,7 +2279,7 @@ void __cdecl InitialiseMovingBlock(int16_t item_num); void __cdecl DrawBridgeCollision(int16_t item_num, struct ITEM_INFO *laraitem, struct COLL_INFO *coll); void __cdecl T_InitPrint(void); -void __cdecl S_Audio_Sample_AdjustTrackVolumeAndPan(int32_t track_id, int32_t volume, int32_t pan); +void __cdecl S_Audio_Sample_AdjustTrackVolumeAndPan(int32_t track_id, int32_t volume, int32_t pan); LPTSTR __cdecl UT_FindArg(LPCTSTR str); uint32_t __fastcall Math_Sqrt(uint32_t n); void __cdecl lara_as_slide(struct ITEM_INFO *item, struct COLL_INFO *coll); @@ -2289,9 +2289,9 @@ void __cdecl HWR_ResetColorKey(void); void __cdecl phd_PutPolygons_I(int16_t *ptr, int32_t clip); void __cdecl Sound_Init(void); -void __cdecl S_Audio_Sample_Shutdown(void); +void __cdecl S_Audio_Sample_Shutdown(void); void __cdecl S_UnloadLevelFile(void); -int32_t __cdecl S_Audio_Sample_CalculateSampleVolume(int32_t volume); +int32_t __cdecl S_Audio_Sample_CalculateSampleVolume(int32_t volume); LONG __cdecl SetRegistryBoolValue(LPCTSTR lpValueName, bool value); void __cdecl T_AddOutline(struct TEXTSTRING *textstring, int16_t enable, int16_t colour, uint16_t *gourptr, uint16_t flags); void __cdecl DInputKeyboardRelease(void); @@ -2306,7 +2306,7 @@ void __cdecl Inv_RingMotionRadius(struct RING_INFO *ring, int16_t target); LPCTSTR __cdecl GetFullPath(LPCTSTR fileName); void __cdecl ScreenClear(bool isPhdWinSize); -int32_t __cdecl S_Audio_Sample_CalculateSamplePan(int16_t pan); +int32_t __cdecl S_Audio_Sample_CalculateSamplePan(int16_t pan); void __cdecl FreeTexturePages(void); void __cdecl SE_PassMessageToImage(HWND hWnd, UINT uMsg, WPARAM wParam); void __cdecl Inv_RingMotionCameraPos(struct RING_INFO *ring, int16_t target); @@ -2347,8 +2347,8 @@ void __cdecl AssaultStop(struct ITEM_INFO *item); int32_t __cdecl GF_DoFrontEndSequence(void); bool __cdecl D3DCreate(void); -void __thiscall S_FlaggedString_Create(struct STRING_FLAGGED *string, DWORD size); -BOOL __cdecl S_Audio_Sample_OutIsTrackPlaying(int32_t track_id); +void __thiscall S_FlaggedString_Create(struct STRING_FLAGGED *string, int32_t size); +BOOL __cdecl S_Audio_Sample_OutIsTrackPlaying(int32_t track_id); bool __cdecl InitTextures(void); void __cdecl lara_col_slide(struct ITEM_INFO *item, struct COLL_INFO *coll); void __cdecl lara_as_climbend(struct ITEM_INFO *item, struct COLL_INFO *coll); @@ -2369,9 +2369,9 @@ void __cdecl StatueFX(struct ITEM_INFO *item); void __cdecl SetChangeFX(struct ITEM_INFO *item); void __cdecl lara_as_reach(struct ITEM_INFO *item, struct COLL_INFO *coll); -bool __cdecl S_Audio_Sample_DSoundCreate(GUID *guid); +bool __cdecl S_Audio_Sample_DSoundCreate(GUID *guid); void __cdecl S_DontDisplayPicture(void); -void __cdecl S_Audio_Sample_OutSetPitch(int32_t track_id, int32_t pitch); +void __cdecl S_Audio_Sample_OutSetPitch(int32_t track_id, int32_t pitch); int32_t __cdecl GetFreePaletteIndex(void); int32_t __cdecl GetFreeTexturePageIndex(void); void __thiscall SE_UpdateBitmapPalette(BITMAP_RESOURCE *bmpRsrc, HWND hWnd, HWND hSender); @@ -2382,7 +2382,7 @@ int32_t __fastcall Math_Sin(int16_t angle); bool __cdecl EnumerateDisplayAdapters(struct DISPLAY_ADAPTER_LIST *displayAdapterList); void __cdecl DInputRelease(void); -bool __cdecl S_Audio_Sample_DSoundEnumerate(struct SOUND_ADAPTER_LIST *adapter_list); +bool __cdecl S_Audio_Sample_DSoundEnumerate(struct SOUND_ADAPTER_LIST *adapter_list); int32_t __fastcall Math_SinImpl(int16_t angle); int32_t __cdecl GetDebouncedInput(int32_t input); bool __cdecl HWR_VertexBufferFull(void); @@ -2402,7 +2402,7 @@ void __cdecl WinInRunControlPanel(HWND hWnd); sub_44E860 void __cdecl SE_GraphicsAdapterSet(HWND hwndDlg, DISPLAY_ADAPTER_NODE *adapter); -void __cdecl S_Audio_Sample_OutCloseTrack(int32_t track_id); +void __cdecl S_Audio_Sample_OutCloseTrack(int32_t track_id); void __cdecl turn180_effect(struct ITEM_INFO *item); void __cdecl invisibility_off(struct ITEM_INFO *item); void __cdecl BridgeFlatFloor(struct ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int32_t *height); @@ -2467,7 +2467,7 @@ void __cdecl WinVidClearMinWindowSize(void); void __cdecl WinVidClearMaxWindowSize(void); bool __cdecl Direct3DInit(void); -bool __cdecl S_Audio_Sample_IsEnabled(void); +bool __cdecl S_Audio_Sample_IsEnabled(void); int32_t __cdecl LevelCompleteSequence(void); int32_t __cdecl GetRenderHeight(void); int32_t __cdecl GetRenderWidth(void); @@ -2477,7 +2477,7 @@ void __cdecl DoInventoryPicture(void); sub_444BB0 sub_4473A0 -sub_447FA0 +sub_447FA0 sub_448410 sub_4523A0 LONG __cdecl CloseGameRegistryKey(void); diff --git a/docs/progress.txt b/docs/progress.txt index 8f52cc26..b78af82e 100644 --- a/docs/progress.txt +++ b/docs/progress.txt @@ -1833,7 +1833,7 @@ typedef struct CINE_FRAME { 004473B0 0000007F -R bool __cdecl WinInputInit(void); 00447430 00000024 -R bool __cdecl DInputEnumDevices(JOYSTICK_LIST *joystickList); 00447460 000000E8 -R BOOL __stdcall DInputEnumDevicesCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef); -00447550 0000001F + void __thiscall S_FlaggedString_Create(struct STRING_FLAGGED *string, DWORD size); +00447550 0000001F + void __thiscall S_FlaggedString_Create(struct STRING_FLAGGED *string, int32_t size); 00447570 0000004E -R JOYSTICK_NODE *__cdecl GetJoystick(GUID *lpGuid); 004475C0 000000C9 -R void __cdecl DInputKeyboardCreate(void); 00447690 00000029 -R void __cdecl DInputKeyboardRelease(void); @@ -1854,24 +1854,24 @@ typedef struct CINE_FRAME { 00447B30 00000018 x sub_447B30 00447B40 00000039 x sub_447B40 00447B90 0000002F x sub_447B90 -00447BC0 00000048 - struct SOUND_ADAPTER_NODE *__cdecl S_Audio_Sample_GetAdapter(GUID *guid); -00447C10 0000002E - void __cdecl S_Audio_Sample_CloseAllTracks(void); -00447C40 0000010E - bool __cdecl S_Audio_Sample_Load(int32_t sample_id, LPWAVEFORMATEX format, const void *data, int32_t data_size); -00447D50 00000045 - bool __cdecl S_Audio_Sample_IsTrackPlaying(int32_t track_id); -00447DA0 000000E7 - int32_t __cdecl S_Audio_Sample_Play(int32_t sample_id, int32_t volume, int32_t pitch, int32_t pan, int32_t flags); -00447E90 00000039 - int32_t __cdecl S_Audio_Sample_GetFreeTrackIndex(void); -00447ED0 0000002C - void __cdecl S_Audio_Sample_AdjustTrackVolumeAndPan(int32_t track_id, int32_t volume, int32_t pan); -00447F00 00000031 - void __cdecl S_Audio_Sample_AdjustTrackPitch(int32_t track_id, int32_t pitch); -00447F40 0000002F - void __cdecl S_Audio_Sample_CloseTrack(int32_t track_id); -00447FA0 00000005 -R sub_447FA0 -00447FB0 0000009C - bool __cdecl S_Audio_Sample_Init(void); -00448050 0000001A - bool __cdecl S_Audio_Sample_DSoundEnumerate(struct SOUND_ADAPTER_LIST *adapter_list); -00448070 000000E2 - BOOL __stdcall S_Audio_Sample_DSoundEnumCallback(LPGUID guid, LPCTSTR description, LPCTSTR module, LPVOID context); -00448160 0000017C - void __cdecl S_Audio_Sample_Init2(HWND hwnd); -004482E0 0000001C - bool __cdecl S_Audio_Sample_DSoundCreate(GUID *guid); -00448300 000000C4 - bool __cdecl S_Audio_Sample_DSoundBufferTest(void); -004483D0 0000002A - void __cdecl S_Audio_Sample_Shutdown(void); -00448400 00000006 - bool __cdecl S_Audio_Sample_IsEnabled(void); +00447BC0 00000048 + struct SOUND_ADAPTER_NODE *__cdecl S_Audio_Sample_GetAdapter(GUID *guid); +00447C10 0000002E + void __cdecl S_Audio_Sample_CloseAllTracks(void); +00447C40 0000010E + bool __cdecl S_Audio_Sample_Load(int32_t sample_id, LPWAVEFORMATEX format, const void *data, int32_t data_size); +00447D50 00000045 + bool __cdecl S_Audio_Sample_IsTrackPlaying(int32_t track_id); +00447DA0 000000E7 + int32_t __cdecl S_Audio_Sample_Play(int32_t sample_id, int32_t volume, int32_t pitch, int32_t pan, int32_t flags); +00447E90 00000039 + int32_t __cdecl S_Audio_Sample_GetFreeTrackIndex(void); +00447ED0 0000002C + void __cdecl S_Audio_Sample_AdjustTrackVolumeAndPan(int32_t track_id, int32_t volume, int32_t pan); +00447F00 00000031 + void __cdecl S_Audio_Sample_AdjustTrackPitch(int32_t track_id, int32_t pitch); +00447F40 0000002F + void __cdecl S_Audio_Sample_CloseTrack(int32_t track_id); +00447FA0 00000005 +R sub_447FA0 +00447FB0 0000009C + bool __cdecl S_Audio_Sample_Init(void); +00448050 0000001A + bool __cdecl S_Audio_Sample_DSoundEnumerate(struct SOUND_ADAPTER_LIST *adapter_list); +00448070 000000E2 + BOOL __stdcall S_Audio_Sample_DSoundEnumCallback(LPGUID guid, LPCTSTR description, LPCTSTR module, LPVOID context); +00448160 0000017C + void __cdecl S_Audio_Sample_Init2(HWND hwnd); +004482E0 0000001C + bool __cdecl S_Audio_Sample_DSoundCreate(GUID *guid); +00448300 000000C4 + bool __cdecl S_Audio_Sample_DSoundBufferTest(void); +004483D0 0000002A + void __cdecl S_Audio_Sample_Shutdown(void); +00448400 00000006 + bool __cdecl S_Audio_Sample_IsEnabled(void); 00448410 00000005 -R sub_448410 00448420 00000001 -R sub_448420 00448430 0000013B -R void __cdecl CreateScreenBuffers(void); @@ -2071,23 +2071,23 @@ typedef struct CINE_FRAME { 00454D60 0000032D -R void __cdecl CheckCheatMode(void); 004550C0 0000007D -R void __cdecl S_SaveSettings(void); 00455140 000000DB -R void __cdecl S_LoadSettings(void); -00455220 00000046 - int32_t __cdecl S_Audio_Sample_OutPlay(int32_t sample_id, uint16_t volume, int32_t pitch, int32_t pan); -00455270 0000002A - int32_t __cdecl S_Audio_Sample_CalculateSampleVolume(int32_t volume); -004552A0 00000026 - int32_t __cdecl S_Audio_Sample_CalculateSamplePan(int16_t pan); -004552D0 00000046 - int32_t __cdecl S_Audio_Sample_OutPlayLooped(int32_t track_id, uint16_t volume, int32_t pitch, int32_t pan); -00455320 00000039 - void __cdecl S_Audio_Sample_OutSetPanAndVolume(int32_t track_id, int32_t pan, uint16_t volume); -00455360 0000001C - void __cdecl S_Audio_Sample_OutSetPitch(int32_t track_id, int32_t pitch); +00455220 00000046 + int32_t __cdecl S_Audio_Sample_OutPlay(int32_t sample_id, uint16_t volume, int32_t pitch, int32_t pan); +00455270 0000002A + int32_t __cdecl S_Audio_Sample_CalculateSampleVolume(int32_t volume); +004552A0 00000026 + int32_t __cdecl S_Audio_Sample_CalculateSamplePan(int16_t pan); +004552D0 00000046 + int32_t __cdecl S_Audio_Sample_OutPlayLooped(int32_t track_id, uint16_t volume, int32_t pitch, int32_t pan); +00455320 00000039 + void __cdecl S_Audio_Sample_OutSetPanAndVolume(int32_t track_id, int32_t pan, uint16_t volume); +00455360 0000001C + void __cdecl S_Audio_Sample_OutSetPitch(int32_t track_id, int32_t pitch); 00455380 0000000A + void __cdecl Sound_SetMasterVolume(int32_t volume); -00455390 00000017 - void __cdecl S_Audio_Sample_OutCloseTrack(int32_t track_id); -004553B0 0000003C - void __cdecl S_Audio_Sample_OutCloseAllTracks(void); -004553C0 0000001F - BOOL __cdecl S_Audio_Sample_OutIsTrackPlaying(int32_t track_id); -004553E0 00000077 - bool __cdecl Music_Init(void); -00455460 00000051 - void __cdecl Music_Shutdown(void); -00455500 0000006F - void __cdecl Music_Play(int16_t track_id, bool is_looped); -00455570 00000039 - void __cdecl Music_Stop(void); -004555B0 00000084 - bool __cdecl Music_PlaySynced(int32_t trackID); -00455640 00000061 - int32_t __cdecl Music_GetFrames(void); -004556B0 00000092 * void __cdecl Music_SetVolume(int32_t volume); +00455390 00000017 + void __cdecl S_Audio_Sample_OutCloseTrack(int32_t track_id); +004553B0 0000003C + void __cdecl S_Audio_Sample_OutCloseAllTracks(void); +004553C0 0000001F + BOOL __cdecl S_Audio_Sample_OutIsTrackPlaying(int32_t track_id); +004553E0 00000077 + bool __cdecl Music_Init(void); +00455460 00000051 + void __cdecl Music_Shutdown(void); +00455500 0000006F + void __cdecl Music_Play(int16_t track_id, bool is_looped); +00455570 00000039 + void __cdecl Music_Stop(void); +004555B0 00000084 + bool __cdecl Music_PlaySynced(int32_t trackID); +00455640 00000061 + int32_t __cdecl Music_GetFrames(void); +004556B0 00000092 + void __cdecl Music_SetVolume(int32_t volume); 004557A0 00000137 -R void __cdecl CopyBitmapPalette(RGB888 *srcPal, BYTE *srcBitmap, int32_t bitmapSize, RGB888 *destPal); 004558E0 000000C8 -R BYTE __cdecl FindNearestPaletteEntry(RGB888 *palette, int32_t red, int32_t green, int32_t blue, bool ignoreSysPalette); 004559B0 000000AE -R void __cdecl SyncSurfacePalettes(void *srcData, int32_t width, int32_t height, int32_t srcPitch, RGB888 *srcPalette, void *dstData, int32_t dstPitch, RGB888 *dstPalette, bool preserveSysPalette); diff --git a/meson.build b/meson.build index f9b07f3e..53bea87e 100644 --- a/meson.build +++ b/meson.build @@ -77,14 +77,19 @@ dll_sources = [ 'src/game/camera.c', 'src/game/math.c', 'src/game/matrix.c', + 'src/game/music.c', 'src/game/shell.c', 'src/game/sound.c', 'src/inject_exec.c', 'src/inject_util.c', + 'src/lib/winmm.c', 'src/log.c', 'src/main_dll.c', 'src/memory.c', + 'src/specific/s_audio_sample.c', 'src/specific/s_filesystem.c', + 'src/specific/s_music.c', + 'src/specific/s_pauld.c', 'src/specific/s_flagged_string.c', ] diff --git a/src/game/camera.c b/src/game/camera.c index 69242331..31f15754 100644 --- a/src/game/camera.c +++ b/src/game/camera.c @@ -2,6 +2,7 @@ #include "game/math.h" #include "game/matrix.h" +#include "game/music.h" #include "global/const.h" #include "global/funcs.h" #include "global/vars.h" diff --git a/src/game/music.c b/src/game/music.c new file mode 100644 index 00000000..4a9ab064 --- /dev/null +++ b/src/game/music.c @@ -0,0 +1,37 @@ +#include "global/types.h" +#include "specific/s_music.h" + +bool __cdecl Music_Init(void) +{ + return S_Music_Init(); +} + +void __cdecl Music_Shutdown(void) +{ + S_Music_Shutdown(); +} + +void __cdecl Music_Play(int16_t track_id, bool is_looped) +{ + S_Music_Play(track_id, is_looped); +} + +void __cdecl Music_Stop(void) +{ + S_Music_Stop(); +} + +bool __cdecl Music_PlaySynced(int32_t track_id) +{ + return S_Music_PlaySynced(track_id); +} + +uint32_t __cdecl Music_GetFrames(void) +{ + return S_Music_GetFrames(); +} + +void __cdecl Music_SetVolume(int32_t volume) +{ + S_Music_SetVolume(volume); +} diff --git a/src/game/music.h b/src/game/music.h new file mode 100644 index 00000000..7664a582 --- /dev/null +++ b/src/game/music.h @@ -0,0 +1,11 @@ +#pragma once + +#include "global/types.h" + +bool __cdecl Music_Init(void); +void __cdecl Music_Shutdown(void); +void __cdecl Music_Play(int16_t track_id, bool is_looped); +void __cdecl Music_Stop(void); +bool __cdecl Music_PlaySynced(int32_t track_id); +uint32_t __cdecl Music_GetFrames(void); +void __cdecl Music_SetVolume(int32_t volume); diff --git a/src/global/const.h b/src/global/const.h index 24daf7fa..98e92037 100644 --- a/src/global/const.h +++ b/src/global/const.h @@ -20,3 +20,6 @@ #define MIN_HEAD_ROTATION (-MAX_HEAD_ROTATION) // = -9100 #define MAX_HEAD_TILT_CAM (85 * PHD_DEGREE) // = 15470 #define MIN_HEAD_TILT_CAM (-MAX_HEAD_TILT_CAM) // = -15470 + +#define MAX_AUDIO_SAMPLE_BUFFERS 256 +#define MAX_AUDIO_SAMPLE_TRACKS 32 diff --git a/src/global/funcs.h b/src/global/funcs.h index 027da31b..308c9780 100644 --- a/src/global/funcs.h +++ b/src/global/funcs.h @@ -852,23 +852,6 @@ #define TempVideoRemove ((void __cdecl (*)(void))0x004479D0) #define S_FadeInInventory ((void __cdecl (*)(BOOL isFade))0x00447A10) #define S_FadeOutInventory ((void __cdecl (*)(BOOL isFade))0x00447A50) -#define S_Audio_Sample_GetAdapter ((struct SOUND_ADAPTER_NODE *__cdecl (*)(GUID *guid))0x00447BC0) -#define S_Audio_Sample_CloseAllTracks ((void __cdecl (*)(void))0x00447C10) -#define S_Audio_Sample_Load ((bool __cdecl (*)(int32_t sample_id, LPWAVEFORMATEX format, const void *data, int32_t data_size))0x00447C40) -#define S_Audio_Sample_IsTrackPlaying ((bool __cdecl (*)(int32_t track_id))0x00447D50) -#define S_Audio_Sample_Play ((int32_t __cdecl (*)(int32_t sample_id, int32_t volume, int32_t pitch, int32_t pan, int32_t flags))0x00447DA0) -#define S_Audio_Sample_GetFreeTrackIndex ((int32_t __cdecl (*)(void))0x00447E90) -#define S_Audio_Sample_AdjustTrackVolumeAndPan ((void __cdecl (*)(int32_t track_id, int32_t volume, int32_t pan))0x00447ED0) -#define S_Audio_Sample_AdjustTrackPitch ((void __cdecl (*)(int32_t track_id, int32_t pitch))0x00447F00) -#define S_Audio_Sample_CloseTrack ((void __cdecl (*)(int32_t track_id))0x00447F40) -#define S_Audio_Sample_Init ((bool __cdecl (*)(void))0x00447FB0) -#define S_Audio_Sample_DSoundEnumerate ((bool __cdecl (*)(struct SOUND_ADAPTER_LIST *adapter_list))0x00448050) -#define S_Audio_Sample_DSoundEnumCallback ((BOOL __stdcall (*)(LPGUID guid, LPCTSTR description, LPCTSTR module, LPVOID context))0x00448070) -#define S_Audio_Sample_Init2 ((void __cdecl (*)(HWND hwnd))0x00448160) -#define S_Audio_Sample_DSoundCreate ((bool __cdecl (*)(GUID *guid))0x004482E0) -#define S_Audio_Sample_DSoundBufferTest ((bool __cdecl (*)(void))0x00448300) -#define S_Audio_Sample_Shutdown ((void __cdecl (*)(void))0x004483D0) -#define S_Audio_Sample_IsEnabled ((bool __cdecl (*)(void))0x00448400) #define CreateScreenBuffers ((void __cdecl (*)(void))0x00448430) #define CreatePrimarySurface ((void __cdecl (*)(void))0x00448570) #define CreateBackBuffer ((void __cdecl (*)(void))0x00448610) @@ -1060,22 +1043,6 @@ #define CheckCheatMode ((void __cdecl (*)(void))0x00454D60) #define S_SaveSettings ((void __cdecl (*)(void))0x004550C0) #define S_LoadSettings ((void __cdecl (*)(void))0x00455140) -#define S_Audio_Sample_OutPlay ((int32_t __cdecl (*)(int32_t sample_id, uint16_t volume, int32_t pitch, int32_t pan))0x00455220) -#define S_Audio_Sample_CalculateSampleVolume ((int32_t __cdecl (*)(int32_t volume))0x00455270) -#define S_Audio_Sample_CalculateSamplePan ((int32_t __cdecl (*)(int16_t pan))0x004552A0) -#define S_Audio_Sample_OutPlayLooped ((int32_t __cdecl (*)(int32_t track_id, uint16_t volume, int32_t pitch, int32_t pan))0x004552D0) -#define S_Audio_Sample_OutSetPanAndVolume ((void __cdecl (*)(int32_t track_id, int32_t pan, uint16_t volume))0x00455320) -#define S_Audio_Sample_OutSetPitch ((void __cdecl (*)(int32_t track_id, int32_t pitch))0x00455360) -#define S_Audio_Sample_OutCloseTrack ((void __cdecl (*)(int32_t track_id))0x00455390) -#define S_Audio_Sample_OutCloseAllTracks ((void __cdecl (*)(void))0x004553B0) -#define S_Audio_Sample_OutIsTrackPlaying ((BOOL __cdecl (*)(int32_t track_id))0x004553C0) -#define Music_Init ((bool __cdecl (*)(void))0x004553E0) -#define Music_Shutdown ((void __cdecl (*)(void))0x00455460) -#define Music_Play ((void __cdecl (*)(int16_t track_id, bool is_looped))0x00455500) -#define Music_Stop ((void __cdecl (*)(void))0x00455570) -#define Music_PlaySynced ((bool __cdecl (*)(int32_t trackID))0x004555B0) -#define Music_GetFrames ((int32_t __cdecl (*)(void))0x00455640) -#define Music_SetVolume ((void __cdecl (*)(int32_t volume))0x004556B0) #define CopyBitmapPalette ((void __cdecl (*)(RGB888 *srcPal, BYTE *srcBitmap, int32_t bitmapSize, RGB888 *destPal))0x004557A0) #define FindNearestPaletteEntry ((BYTE __cdecl (*)(RGB888 *palette, int32_t red, int32_t green, int32_t blue, bool ignoreSysPalette))0x004558E0) #define SyncSurfacePalettes ((void __cdecl (*)(void *srcData, int32_t width, int32_t height, int32_t srcPitch, RGB888 *srcPalette, void *dstData, int32_t dstPitch, RGB888 *dstPalette, bool preserveSysPalette))0x004559B0) diff --git a/src/global/types.h b/src/global/types.h index 7f7167d5..53d9ecfd 100644 --- a/src/global/types.h +++ b/src/global/types.h @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -129,14 +130,14 @@ typedef struct SOUND_ADAPTER { } SOUND_ADAPTER; typedef struct SOUND_ADAPTER_NODE { - struct SoundAdapterNode_t *next; - struct SoundAdapterNode_t *previous; + struct SOUND_ADAPTER_NODE *next; + struct SOUND_ADAPTER_NODE *previous; SOUND_ADAPTER body; } SOUND_ADAPTER_NODE; typedef struct SOUND_ADAPTER_LIST { - struct SoundAdapterNode_t *head; - struct SoundAdapterNode_t *tail; + struct SOUND_ADAPTER_NODE *head; + struct SOUND_ADAPTER_NODE *tail; DWORD dwCount; } SOUND_ADAPTER_LIST; diff --git a/src/inject_exec.c b/src/inject_exec.c index 6d0a9a39..a409db9b 100644 --- a/src/inject_exec.c +++ b/src/inject_exec.c @@ -3,16 +3,20 @@ #include "game/camera.h" #include "game/math.h" #include "game/matrix.h" +#include "game/music.h" #include "game/shell.h" #include "game/sound.h" #include "inject_util.h" +#include "specific/s_audio_sample.h" #include "specific/s_flagged_string.h" static void Inject_Camera(void); static void Inject_Math(void); static void Inject_Matrix(void); static void Inject_Shell(void); +static void Inject_Music(void); static void Inject_Sound(void); +static void Inject_S_Audio_Sample(void); static void Inject_S_FlaggedString(void); static void Inject_Camera(void) @@ -58,16 +62,57 @@ static void Inject_Shell(void) INJECT(1, 0x0044E890, Shell_ExitSystem); } +static void Inject_Music(void) +{ + INJECT(1, 0x004553E0, Music_Init); + INJECT(1, 0x00455460, Music_Shutdown); + INJECT(1, 0x00455500, Music_Play); + INJECT(1, 0x00455570, Music_Stop); + INJECT(1, 0x004555B0, Music_PlaySynced); + INJECT(1, 0x00455640, Music_GetFrames); + INJECT(1, 0x004556B0, Music_SetVolume); +} + static void Inject_Sound(void) { INJECT(1, 0x00455380, Sound_SetMasterVolume); } +static void Inject_S_Audio_Sample(void) +{ + INJECT(1, 0x00447BC0, S_Audio_Sample_GetAdapter); + INJECT(1, 0x00447C10, S_Audio_Sample_CloseAllTracks); + INJECT(1, 0x00447C40, S_Audio_Sample_Load); + INJECT(1, 0x00447D50, S_Audio_Sample_IsTrackPlaying); + INJECT(1, 0x00447DA0, S_Audio_Sample_Play); + INJECT(1, 0x00447E90, S_Audio_Sample_GetFreeTrackIndex); + INJECT(1, 0x00447ED0, S_Audio_Sample_AdjustTrackVolumeAndPan); + INJECT(1, 0x00447F00, S_Audio_Sample_AdjustTrackPitch); + INJECT(1, 0x00447F40, S_Audio_Sample_CloseTrack); + INJECT(1, 0x00447FB0, S_Audio_Sample_Init); + INJECT(1, 0x00448050, S_Audio_Sample_DSoundEnumerate); + INJECT(1, 0x00448070, S_Audio_Sample_DSoundEnumCallback); + INJECT(1, 0x00448160, S_Audio_Sample_Init2); + INJECT(1, 0x004482E0, S_Audio_Sample_DSoundCreate); + INJECT(1, 0x00448300, S_Audio_Sample_DSoundBufferTest); + INJECT(1, 0x004483D0, S_Audio_Sample_Shutdown); + INJECT(1, 0x00448400, S_Audio_Sample_IsEnabled); + INJECT(1, 0x00455220, S_Audio_Sample_OutPlay); + INJECT(1, 0x00455270, S_Audio_Sample_CalculateSampleVolume); + INJECT(1, 0x004552A0, S_Audio_Sample_CalculateSamplePan); + INJECT(1, 0x004552D0, S_Audio_Sample_OutPlayLooped); + INJECT(1, 0x00455320, S_Audio_Sample_OutSetPanAndVolume); + INJECT(1, 0x00455360, S_Audio_Sample_OutSetPitch); + INJECT(1, 0x00455390, S_Audio_Sample_OutCloseTrack); + INJECT(1, 0x004553B0, S_Audio_Sample_OutCloseAllTracks); + INJECT(1, 0x004553C0, S_Audio_Sample_OutIsTrackPlaying); +} + static void Inject_S_FlaggedString(void) { INJECT(1, 0x00447550, S_FlaggedString_Create); - INJECT(1, 0x00445F00, S_FlaggedString_Delete); INJECT(1, 0x00446100, S_FlaggedString_InitAdapter); + INJECT(1, 0x00445F00, S_FlaggedString_Delete); } void Inject_Exec(void) @@ -76,7 +121,9 @@ void Inject_Exec(void) Inject_Math(); Inject_Matrix(); Inject_Shell(); + Inject_Music(); Inject_Sound(); + Inject_S_Audio_Sample(); Inject_S_FlaggedString(); } diff --git a/src/lib/dsound.h b/src/lib/dsound.h new file mode 100644 index 00000000..875275c4 --- /dev/null +++ b/src/lib/dsound.h @@ -0,0 +1,11 @@ +#pragma once + +#include + +#define DirectSoundCreate \ + ((HRESULT(__stdcall *)( \ + LPCGUID pcGuidDevice, LPDIRECTSOUND * ppDS, \ + LPUNKNOWN pUnkOuter))0x00458CEE) +#define DirectSoundEnumerateA \ + ((HRESULT(__stdcall *)( \ + LPDSENUMCALLBACKA pDSEnumCallback, LPVOID pContext))0x00458CE8) diff --git a/src/lib/winmm.c b/src/lib/winmm.c new file mode 100644 index 00000000..e9b74adb --- /dev/null +++ b/src/lib/winmm.c @@ -0,0 +1,11 @@ +#include "lib/winmm.h" + +MMRESULT(__stdcall *g_MM_auxGetDevCapsA) +(UINT_PTR uDeviceID, LPAUXCAPSA pac, UINT cbac); +UINT(__stdcall *g_MM_auxGetNumDevs)(void) = NULL; +MMRESULT(__stdcall *g_MM_auxSetVolume)(UINT uDeviceID, DWORD dwVolume) = NULL; +MCIERROR(__stdcall *g_MM_mciSendCommandA) +(MCIDEVICEID mciId, UINT uMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2) = NULL; +MCIERROR(__stdcall *g_MM_mciSendStringA) +(LPCSTR lpszCommand, LPSTR lpszReturnString, UINT cchReturn, + HANDLE hwndCallback) = NULL; diff --git a/src/lib/winmm.h b/src/lib/winmm.h new file mode 100644 index 00000000..35fe835f --- /dev/null +++ b/src/lib/winmm.h @@ -0,0 +1,19 @@ +#pragma once + +#include + +extern MMRESULT(__stdcall *g_MM_auxGetDevCapsA)( + UINT_PTR uDeviceID, LPAUXCAPSA pac, UINT cbac); +extern UINT(__stdcall *g_MM_auxGetNumDevs)(void); +extern MMRESULT(__stdcall *g_MM_auxSetVolume)(UINT uDeviceID, DWORD dwVolume); +extern MCIERROR(__stdcall *g_MM_mciSendCommandA)( + MCIDEVICEID mciId, UINT uMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2); +extern MCIERROR(__stdcall *g_MM_mciSendStringA)( + LPCSTR lpszCommand, LPSTR lpszReturnString, UINT cchReturn, + HANDLE hwndCallback); + +#define auxGetDevCapsA g_MM_auxGetDevCapsA +#define auxGetNumDevs g_MM_auxGetNumDevs +#define auxSetVolume g_MM_auxSetVolume +#define mciSendCommandA g_MM_mciSendCommandA +#define mciSendStringA g_MM_mciSendStringA diff --git a/src/main_dll.c b/src/main_dll.c index a2aee2a9..f6bcc6ba 100644 --- a/src/main_dll.c +++ b/src/main_dll.c @@ -1,9 +1,19 @@ #include "inject_exec.h" +#include "lib/winmm.h" #include "log.h" #include #include +static void LoadWinMM(void) +{ + HANDLE winmm = LoadLibrary("winmm.dll"); + auxGetNumDevs = GetProcAddress(winmm, "auxGetNumDevs"); + auxSetVolume = GetProcAddress(winmm, "auxSetVolume"); + mciSendCommandA = GetProcAddress(winmm, "mciSendCommandA"); + mciSendStringA = GetProcAddress(winmm, "mciSendStringA"); +} + BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { @@ -12,6 +22,7 @@ DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) Log_Init(); LOG_DEBUG("Injected\n"); + LoadWinMM(); Inject_Exec(); break; diff --git a/src/specific/s_audio_sample.c b/src/specific/s_audio_sample.c new file mode 100644 index 00000000..32df8a5d --- /dev/null +++ b/src/specific/s_audio_sample.c @@ -0,0 +1,428 @@ +#include "game/shell.h" +#include "global/const.h" +#include "global/funcs.h" +#include "global/types.h" +#include "global/vars.h" +#include "lib/dsound.h" +#include "lib/winmm.h" +#include "log.h" +#include "specific/s_audio_sample.h" +#include "specific/s_flagged_string.h" + +struct SOUND_ADAPTER_NODE *__cdecl S_Audio_Sample_GetAdapter(GUID *guid) +{ + struct SOUND_ADAPTER_NODE *adapter; + + if (guid != NULL) { + for (adapter = g_SoundAdapterList.head; adapter; + adapter = adapter->next) { + if (!memcmp(&adapter->body.adapterGuid, guid, sizeof(GUID))) { + return adapter; + } + } + } + return g_PrimarySoundAdapter; +} + +void __cdecl S_Audio_Sample_CloseAllTracks(void) +{ + if (!g_IsSoundEnabled) { + return; + } + + for (int32_t i = 0; i < MAX_AUDIO_SAMPLE_BUFFERS; ++i) { + if (g_SampleBuffers[i] != NULL) { + IDirectSound_Release(g_SampleBuffers[i]); + g_SampleBuffers[i] = NULL; + } + } +} + +bool __cdecl S_Audio_Sample_Load( + int32_t sample_idx, LPWAVEFORMATEX format, const void *data, + uint32_t data_size) +{ + LPVOID audio_ptr; + DWORD audio_bytes; + DSBUFFERDESC desc; + + if (!g_DSound || !g_IsSoundEnabled + || sample_idx >= MAX_AUDIO_SAMPLE_BUFFERS) { + return false; + } + + if (g_SampleBuffers[sample_idx] != NULL) { + IDirectSound_Release(g_SampleBuffers[sample_idx]); + g_SampleBuffers[sample_idx] = NULL; + } + + desc.dwSize = sizeof(DSBUFFERDESC); + desc.dwFlags = DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLPAN | DSBCAPS_CTRLFREQUENCY + | DSBCAPS_LOCSOFTWARE; + desc.dwBufferBytes = data_size; + desc.dwReserved = 0; + desc.lpwfxFormat = format; + + if FAILED (IDirectSound_CreateSoundBuffer( + g_DSound, &desc, &g_SampleBuffers[sample_idx], NULL)) { + return false; + } + + if FAILED (IDirectSoundBuffer_Lock( + g_SampleBuffers[sample_idx], 0, data_size, &audio_ptr, + &audio_bytes, NULL, NULL, 0)) { + return false; + } + + memcpy(audio_ptr, data, audio_bytes); + + if FAILED (IDirectSoundBuffer_Unlock( + g_SampleBuffers[sample_idx], audio_ptr, audio_bytes, NULL, + 0)) { + return false; + } + + g_SampleFreqs[sample_idx] = format->nSamplesPerSec; + return true; +} + +bool __cdecl S_Audio_Sample_IsTrackPlaying(int32_t track_id) +{ + DWORD status; + + if (!g_ChannelBuffers[track_id] + || FAILED(IDirectSoundBuffer_GetStatus( + g_ChannelBuffers[track_id], &status))) { + return false; + } + + if ((status & DSBSTATUS_PLAYING) == 0) { + IDirectSoundBuffer_Release(g_ChannelBuffers[track_id]); + g_ChannelBuffers[track_id] = NULL; + return false; + } + + return true; +} + +int32_t __cdecl S_Audio_Sample_Play( + int32_t sample_idx, int32_t volume, int32_t pitch, int32_t pan, + uint32_t flags) +{ + LPDIRECTSOUNDBUFFER dsBuffer = NULL; + int32_t track_id = S_Audio_Sample_GetFreeTrackIndex(); + + if (track_id < 0) { + return -1; + } + + if (FAILED(IDirectSound_DuplicateSoundBuffer( + g_DSound, g_SampleBuffers[sample_idx], &dsBuffer)) + || FAILED(IDirectSoundBuffer_SetVolume(dsBuffer, volume)) + || FAILED(IDirectSoundBuffer_SetFrequency( + dsBuffer, g_SampleFreqs[sample_idx] * pitch / PHD_ONE)) + || FAILED(IDirectSoundBuffer_SetPan(dsBuffer, pan)) + || FAILED(IDirectSoundBuffer_SetCurrentPosition(dsBuffer, 0)) + || FAILED(IDirectSoundBuffer_Play(dsBuffer, 0, 0, flags))) { + return -2; + } + + g_ChannelSamples[track_id] = sample_idx; + g_ChannelBuffers[track_id] = dsBuffer; + + return track_id; +} + +int32_t __cdecl S_Audio_Sample_GetFreeTrackIndex(void) +{ + for (int32_t i = 0; i < MAX_AUDIO_SAMPLE_TRACKS; ++i) { + if (!g_ChannelBuffers[i]) { + return i; + } + } + + for (int32_t i = 0; i < MAX_AUDIO_SAMPLE_TRACKS; ++i) { + if (!S_Audio_Sample_IsTrackPlaying(i)) { + return i; + } + } + + return -1; +} + +void __cdecl S_Audio_Sample_AdjustTrackVolumeAndPan( + int32_t track_id, int32_t volume, int32_t pan) +{ + if (track_id >= 0 && g_ChannelBuffers[track_id] != NULL) { + IDirectSoundBuffer_SetVolume(g_ChannelBuffers[track_id], volume); + IDirectSoundBuffer_SetPan(g_ChannelBuffers[track_id], pan); + } +} + +void __cdecl S_Audio_Sample_AdjustTrackPitch(int32_t track_id, int32_t pitch) +{ + if (track_id >= 0 && g_ChannelBuffers[track_id] != NULL) { + IDirectSoundBuffer_SetFrequency( + g_ChannelBuffers[track_id], + g_SampleFreqs[g_ChannelSamples[track_id]] * pitch / PHD_ONE); + } +} + +void __cdecl S_Audio_Sample_CloseTrack(int32_t track_id) +{ + if (track_id >= 0 && g_ChannelBuffers[track_id] != NULL) { + IDirectSoundBuffer_Stop(g_ChannelBuffers[track_id]); + IDirectSoundBuffer_Release(g_ChannelBuffers[track_id]); + g_ChannelBuffers[track_id] = NULL; + } +} + +bool __cdecl S_Audio_Sample_Init(void) +{ + struct SOUND_ADAPTER_NODE *node, *nextNode; + + for (node = g_SoundAdapterList.head; node; node = nextNode) { + nextNode = node->next; + S_FlaggedString_Delete(&node->body.module); + S_FlaggedString_Delete(&node->body.description); + free(node); + } + + g_SoundAdapterList.head = NULL; + g_SoundAdapterList.tail = NULL; + g_SoundAdapterList.dwCount = 0; + + g_PrimarySoundAdapter = NULL; + + if (!S_Audio_Sample_DSoundEnumerate(&g_SoundAdapterList)) { + LOG_ERROR("Failed to enumerate sound devices"); + return false; + } + + for (node = g_SoundAdapterList.head; node; node = node->next) { + if (!node->body.lpAdapterGuid) { + g_PrimarySoundAdapter = node; + break; + } + } + + LOG_ERROR("Finished loading sound"); + return true; +} + +bool __cdecl S_Audio_Sample_DSoundEnumerate( + struct SOUND_ADAPTER_LIST *adapter_list) +{ + return SUCCEEDED(DirectSoundEnumerateA( + S_Audio_Sample_DSoundEnumCallback, (LPVOID)adapter_list)); +} + +BOOL CALLBACK S_Audio_Sample_DSoundEnumCallback( + LPGUID guid, LPCTSTR description, LPCTSTR module, LPVOID context) +{ + struct SOUND_ADAPTER_LIST *adapter_list = + (struct SOUND_ADAPTER_LIST *)context; + struct SOUND_ADAPTER_NODE *adapter_node = + malloc(sizeof(struct SOUND_ADAPTER_NODE)); + + if (!adapter_node) { + return TRUE; + } + + adapter_node->next = NULL; + adapter_node->previous = adapter_list->tail; + + if (!adapter_list->head) { + adapter_list->head = adapter_node; + } + + if (adapter_list->tail) { + adapter_list->tail->next = adapter_node; + } + + adapter_list->tail = adapter_node; + adapter_list->dwCount++; + + if (!guid) { + memset(&adapter_node->body.adapterGuid, 0, sizeof(GUID)); + adapter_node->body.lpAdapterGuid = NULL; + } else { + adapter_node->body.adapterGuid = *guid; + adapter_node->body.lpAdapterGuid = &adapter_node->body.adapterGuid; + } + + S_FlaggedString_Create(&adapter_node->body.description, 256); + S_FlaggedString_Create(&adapter_node->body.module, 256); + lstrcpy(adapter_node->body.description.content, description); + lstrcpy(adapter_node->body.module.content, module); + + return TRUE; +} + +void __cdecl S_Audio_Sample_Init2(HWND hwnd) +{ + memset(g_SampleBuffers, 0, sizeof(g_SampleBuffers)); + memset(g_ChannelBuffers, 0, sizeof(g_ChannelBuffers)); + + g_Camera.is_lara_mic = g_SavedAppSettings.LaraMic; + g_IsSoundEnabled = false; + + if (!g_SavedAppSettings.SoundEnabled + || !g_SavedAppSettings.PreferredSoundAdapter) { + return; + } + + struct SOUND_ADAPTER *preferred = + &g_SavedAppSettings.PreferredSoundAdapter->body; + g_CurrentSoundAdapter = *preferred; + + S_FlaggedString_Copy( + &g_CurrentSoundAdapter.description, &preferred->description); + S_FlaggedString_Copy(&g_CurrentSoundAdapter.module, &preferred->module); + + if (!S_Audio_Sample_DSoundCreate(g_CurrentSoundAdapter.lpAdapterGuid)) { + return; + } + + if (!hwnd) { + hwnd = g_GameWindowHandle; + } + + if FAILED (IDirectSound_SetCooperativeLevel( + g_DSound, hwnd, DSSCL_EXCLUSIVE)) { + Shell_ExitSystem("Error: Can't set DSound cooperative level"); + } + + g_IsSoundEnabled = S_Audio_Sample_DSoundBufferTest(); +} + +bool __cdecl S_Audio_Sample_DSoundCreate(GUID *guid) +{ + return SUCCEEDED(DirectSoundCreate(guid, &g_DSound, NULL)); +} + +bool __cdecl S_Audio_Sample_DSoundBufferTest(void) +{ + WAVEFORMATEX format; + DSBUFFERDESC desc; + LPDIRECTSOUNDBUFFER dsBuffer; + + desc.dwSize = sizeof(DSBUFFERDESC); + desc.dwFlags = DSBCAPS_PRIMARYBUFFER; + desc.dwBufferBytes = 0; + desc.dwReserved = 0; + desc.lpwfxFormat = NULL; + + if FAILED (IDirectSound_CreateSoundBuffer( + g_DSound, &desc, &dsBuffer, NULL)) { + return false; + } + + format.wFormatTag = WAVE_FORMAT_PCM; + format.nChannels = 2; + format.nSamplesPerSec = 11025; + format.nAvgBytesPerSec = 44100; + format.nBlockAlign = 4; + format.wBitsPerSample = 16; + format.cbSize = 0; + + bool result = SUCCEEDED(IDirectSoundBuffer_SetFormat(dsBuffer, &format)); + IDirectSoundBuffer_Release(dsBuffer); + return result; +} + +void __cdecl S_Audio_Sample_Shutdown(void) +{ + S_Audio_Sample_CloseAllTracks(); + if (g_DSound != NULL) { + IDirectSound_Release(g_DSound); + g_DSound = NULL; + } +} + +bool __cdecl S_Audio_Sample_IsEnabled(void) +{ + return g_IsSoundEnabled; +} + +int32_t __cdecl S_Audio_Sample_OutPlay( + int32_t sample_id, int32_t volume, int32_t pitch, int32_t pan) +{ + if (!g_SoundIsActive) { + return -3; + } + + int32_t calc_pan = S_Audio_Sample_CalculateSamplePan(pan); + int32_t calc_volume = S_Audio_Sample_CalculateSampleVolume(volume); + return S_Audio_Sample_Play(sample_id, calc_volume, pitch, calc_pan, 0); +} + +int32_t __cdecl S_Audio_Sample_CalculateSampleVolume(int32_t volume) +{ + return ( + int32_t)(((double)(g_MasterVolume * volume) * 0.000000476837158203125 + - 1.0) + * 5000.0); + return (int32_t)(((double)(g_MasterVolume * volume) / 0x200000.p0 - 1.0) + * 5000.0); +} + +int32_t __cdecl S_Audio_Sample_CalculateSamplePan(int16_t pan) +{ + return pan / 16; +} + +int32_t __cdecl S_Audio_Sample_OutPlayLooped( + int32_t sample_id, int32_t volume, int32_t pitch, int32_t pan) +{ + if (!g_SoundIsActive) { + return -3; + } + + int32_t calc_pan = S_Audio_Sample_CalculateSamplePan(pan); + int32_t calc_volume = S_Audio_Sample_CalculateSampleVolume(volume); + return S_Audio_Sample_Play( + sample_id, calc_volume, pitch, calc_pan, DSBPLAY_LOOPING); +} + +void __cdecl S_Audio_Sample_OutSetPanAndVolume( + int32_t track_id, int32_t pan, int32_t volume) +{ + if (g_SoundIsActive) { + int32_t calc_pan = S_Audio_Sample_CalculateSamplePan(pan); + int32_t calc_volume = S_Audio_Sample_CalculateSampleVolume(volume); + S_Audio_Sample_AdjustTrackVolumeAndPan(track_id, calc_volume, calc_pan); + } +} + +void __cdecl S_Audio_Sample_OutSetPitch(int32_t track_id, int32_t pitch) +{ + if (g_SoundIsActive) { + S_Audio_Sample_AdjustTrackPitch(track_id, pitch); + } +} + +void __cdecl S_Audio_Sample_OutCloseTrack(int32_t track_id) +{ + if (g_SoundIsActive) { + S_Audio_Sample_CloseTrack(track_id); + } +} + +void __cdecl S_Audio_Sample_OutCloseAllTracks(void) +{ + if (g_SoundIsActive) { + for (int32_t i = 0; i < MAX_AUDIO_SAMPLE_TRACKS; ++i) { + S_Audio_Sample_CloseTrack(i); + } + } +} + +bool __cdecl S_Audio_Sample_OutIsTrackPlaying(int32_t track_id) +{ + if (!g_SoundIsActive) { + return FALSE; + } + + return S_Audio_Sample_IsTrackPlaying(track_id); +} diff --git a/src/specific/s_audio_sample.h b/src/specific/s_audio_sample.h new file mode 100644 index 00000000..28ebce4e --- /dev/null +++ b/src/specific/s_audio_sample.h @@ -0,0 +1,40 @@ +#pragma once + +#include "global/types.h" + +struct SOUND_ADAPTER_NODE *__cdecl S_Audio_Sample_GetAdapter(GUID *guid); +void __cdecl S_Audio_Sample_CloseAllTracks(void); +bool __cdecl S_Audio_Sample_Load( + int32_t sample_id, LPWAVEFORMATEX format, const void *data, + uint32_t data_size); +bool __cdecl S_Audio_Sample_IsTrackPlaying(int32_t track_id); +int32_t __cdecl S_Audio_Sample_Play( + int32_t sample_idx, int32_t volume, int32_t pitch, int32_t pan, + uint32_t flags); +int32_t __cdecl S_Audio_Sample_GetFreeTrackIndex(void); +void __cdecl S_Audio_Sample_AdjustTrackVolumeAndPan( + int32_t track_id, int32_t volume, int32_t pan); +void __cdecl S_Audio_Sample_AdjustTrackPitch(int32_t track_id, int32_t pitch); +void __cdecl S_Audio_Sample_CloseTrack(int32_t track_id); +bool __cdecl S_Audio_Sample_Init(void); +bool __cdecl S_Audio_Sample_DSoundEnumerate( + struct SOUND_ADAPTER_LIST *adapter_list); +BOOL CALLBACK S_Audio_Sample_DSoundEnumCallback( + LPGUID guid, LPCTSTR description, LPCTSTR module, LPVOID context); +void __cdecl S_Audio_Sample_Init2(HWND hwnd); +bool __cdecl S_Audio_Sample_DSoundCreate(GUID *guid); +bool __cdecl S_Audio_Sample_DSoundBufferTest(void); +void __cdecl S_Audio_Sample_Shutdown(void); +bool __cdecl S_Audio_Sample_IsEnabled(void); +int32_t __cdecl S_Audio_Sample_OutPlay( + int32_t channel, int32_t volume, int32_t pitch, int32_t pan); +int32_t __cdecl S_Audio_Sample_CalculateSampleVolume(int32_t volume); +int32_t __cdecl S_Audio_Sample_CalculateSamplePan(int16_t pan); +int32_t __cdecl S_Audio_Sample_OutPlayLooped( + int32_t channel, int32_t volume, int32_t pitch, int32_t pan); +void __cdecl S_Audio_Sample_OutSetPanAndVolume( + int32_t channel, int32_t pan, int32_t volume); +void __cdecl S_Audio_Sample_OutSetPitch(int32_t channel, int32_t pitch); +void __cdecl S_Audio_Sample_OutCloseTrack(int32_t channel); +void __cdecl S_Audio_Sample_OutCloseAllTracks(void); +bool __cdecl S_Audio_Sample_OutIsTrackPlaying(int32_t channel); diff --git a/src/specific/s_flagged_string.c b/src/specific/s_flagged_string.c index 2d918ccb..1909ebeb 100644 --- a/src/specific/s_flagged_string.c +++ b/src/specific/s_flagged_string.c @@ -26,3 +26,26 @@ void __thiscall S_FlaggedString_Delete(struct STRING_FLAGGED *string) string->is_valid = false; } } + +bool S_FlaggedString_Copy( + struct STRING_FLAGGED *dst, struct STRING_FLAGGED *src) +{ + if (dst == NULL || src == NULL || dst == src || !src->is_valid) { + return false; + } + + size_t src_len = lstrlen(src->content); + dst->is_valid = false; + dst->content = malloc(src_len + 1); + if (dst->content == NULL) { + return false; + } + + if (src_len > 0) { + lstrcpy(dst->content, src->content); + } else { + *dst->content = 0; + } + dst->is_valid = true; + return true; +} diff --git a/src/specific/s_flagged_string.h b/src/specific/s_flagged_string.h index 44d8fe39..e4b03834 100644 --- a/src/specific/s_flagged_string.h +++ b/src/specific/s_flagged_string.h @@ -8,3 +8,5 @@ void __thiscall S_FlaggedString_Create( struct STRING_FLAGGED *string, int32_t size); void __thiscall S_FlaggedString_Delete(struct STRING_FLAGGED *string); void __thiscall S_FlaggedString_InitAdapter(struct DISPLAY_ADAPTER *adapter); +bool S_FlaggedString_Copy( + struct STRING_FLAGGED *dst, struct STRING_FLAGGED *src); diff --git a/src/specific/s_music.c b/src/specific/s_music.c new file mode 100644 index 00000000..48ec144c --- /dev/null +++ b/src/specific/s_music.c @@ -0,0 +1,199 @@ +#include "specific/s_music.h" + +#include "global/const.h" +#include "global/funcs.h" +#include "global/vars.h" +#include "lib/winmm.h" +#include "log.h" +#include "specific/s_pauld.h" + +static bool g_PaulDActive = false; + +static HMODULE g_WinMM = NULL; + +static bool m_isCDAudioEnabled = false; +static int32_t m_CDVolume = 0; + +bool __cdecl S_Music_Init(void) +{ + MCI_OPEN_PARMS openParams; + MCI_SET_PARMS setParams; + + g_PaulDActive = PaulD_CD_Init(); + if (g_PaulDActive) { + return true; + } + + if (m_isCDAudioEnabled) { + return true; + } + + openParams.lpstrDeviceType = "cdaudio"; + if (mciSendCommand(0, MCI_OPEN, MCI_OPEN_TYPE, (DWORD_PTR)&openParams) + == 0) { + g_MciDeviceID = openParams.wDeviceID; + setParams.dwTimeFormat = MCI_FORMAT_TMSF; + mciSendCommand( + g_MciDeviceID, MCI_SET, MCI_SET_TIME_FORMAT, (DWORD_PTR)&setParams); + m_isCDAudioEnabled = true; + } + return true; +} + +void __cdecl S_Music_Shutdown(void) +{ + MCI_GENERIC_PARMS params; + + if (g_PaulDActive) { + PaulD_CD_Cleanup(); + return; + } + + if (!m_isCDAudioEnabled) { + return; + } + + mciSendCommand(g_MciDeviceID, MCI_STOP, 0, (DWORD_PTR)¶ms); + mciSendCommand(g_MciDeviceID, MCI_CLOSE, 0, (DWORD_PTR)¶ms); + m_isCDAudioEnabled = false; +} + +void __cdecl S_Music_Play(int16_t track_id, bool is_looped) +{ + S_Music_Init(); // TODO: this shouldn't be called here + LOG_DEBUG("track_id=%d is_looped=%d", track_id, is_looped); + int16_t track; + MCI_PLAY_PARMS playParams; + + if (g_PaulDActive) { + PaulD_CDPlay(track_id, is_looped); + return; + } + + if (g_OptionMusicVolume == 0) { + return; + } + + g_CD_TrackID = track_id; + track = GetRealTrack(track_id); + playParams.dwFrom = track; + playParams.dwTo = track + 1; + mciSendCommand( + g_MciDeviceID, MCI_PLAY, MCI_NOTIFY_FAILURE | MCI_NOTIFY_ABORTED, + (DWORD_PTR)&playParams); + + if (is_looped) { + g_CD_LoopTrack = track; + } +} + +void __cdecl S_Music_Stop(void) +{ + LOG_DEBUG(""); + MCI_GENERIC_PARMS params; + + if (g_PaulDActive) { + PaulD_CDStop(); + return; + } + + if (g_CD_TrackID > 0) { + mciSendCommand(g_MciDeviceID, MCI_STOP, 0, (DWORD_PTR)¶ms); + g_CD_TrackID = 0; + g_CD_LoopTrack = 0; + } +} + +bool __cdecl S_Music_PlaySynced(int32_t track_id) +{ + LOG_DEBUG("%d", track_id); + int16_t track; + MCI_PLAY_PARMS playParams; + MCI_SET_PARMS setParams; + + if (g_PaulDActive) { + return PaulD_StartSyncedAudio(track_id); + } + + g_CD_TrackID = track_id; + track = GetRealTrack(track_id); + + setParams.dwTimeFormat = MCI_FORMAT_TMSF; + if (mciSendCommand( + g_MciDeviceID, MCI_SET, MCI_SET_TIME_FORMAT, (DWORD_PTR)&setParams) + != 0) { + return FALSE; + } + + playParams.dwFrom = track; + playParams.dwTo = track + 1; + return ( + mciSendCommand( + g_MciDeviceID, MCI_PLAY, MCI_NOTIFY_FAILURE | MCI_NOTIFY_ABORTED, + (DWORD_PTR)&playParams) + == 0); +} + +uint32_t __cdecl S_Music_GetFrames(void) +{ + uint32_t pos; + MCI_STATUS_PARMS statusParams; + + if (g_PaulDActive) { + return PaulD_CDGetLoc(); + } + + statusParams.dwItem = MCI_STATUS_POSITION; + if (mciSendCommand( + g_MciDeviceID, MCI_STATUS, MCI_STATUS_ITEM, + (DWORD_PTR)&statusParams) + != 0) { + return 0; + } + + pos = statusParams.dwReturn; + return (MCI_TMSF_MINUTE(pos) * 60 + MCI_TMSF_SECOND(pos)) * 75 + + MCI_TMSF_FRAME(pos); +} + +void __cdecl S_Music_SetVolume(int32_t volume) +{ + if (!g_WinMM) { + return; + } + AUXCAPS caps; + bool isVolumeSet = false; + int32_t device_id = -1; + int32_t aux_dev_count = auxGetNumDevs(); + m_CDVolume = volume; + + if (g_PaulDActive) { + PaulD_CDVolume(volume); + return; + } + + if (aux_dev_count == 0) { + return; + } + + volume *= 0x100; + + for (int32_t i = 0; i < aux_dev_count; ++i) { + auxGetDevCaps(i, &caps, sizeof(AUXCAPS)); + + switch (caps.wTechnology) { + case AUXCAPS_CDAUDIO: + auxSetVolume(i, MAKELONG(volume, volume)); + isVolumeSet = true; + break; + + case AUXCAPS_AUXIN: + device_id = i; + break; + } + } + + if (!isVolumeSet && device_id != -1) { + auxSetVolume(device_id, MAKELONG(volume, volume)); + } +} diff --git a/src/specific/s_music.h b/src/specific/s_music.h new file mode 100644 index 00000000..9c0951ca --- /dev/null +++ b/src/specific/s_music.h @@ -0,0 +1,11 @@ +#pragma once + +#include "global/types.h" + +bool __cdecl S_Music_Init(void); +void __cdecl S_Music_Shutdown(void); +void __cdecl S_Music_Play(int16_t track_id, bool is_looped); +void __cdecl S_Music_Stop(void); +bool __cdecl S_Music_PlaySynced(int32_t track_id); +uint32_t __cdecl S_Music_GetFrames(void); +void __cdecl S_Music_SetVolume(int32_t volume); diff --git a/src/specific/s_pauld.c b/src/specific/s_pauld.c new file mode 100644 index 00000000..be3da6b9 --- /dev/null +++ b/src/specific/s_pauld.c @@ -0,0 +1,253 @@ +#include "specific/s_pauld.h" + +#include "global/funcs.h" +#include "global/types.h" +#include "global/vars.h" +#include "lib/winmm.h" +#include "log.h" + +#include + +#define CD_ALIAS "T2" +#define MAX_TRACKS 60 + +typedef struct TRACK_INFO { + DWORD from; + DWORD to; + bool active; +} TRACK_INFO; + +static TRACK_INFO g_Tracks[60]; +static bool m_IsCDAudioEnabled = false; + +bool __cdecl PaulD_CD_Init(void) +{ + static LPCTSTR audio_files[2] = { + "audio\\cdaudio.wav", + "audio\\cdaudio.mp3", + }; + + static LPCTSTR audio_types[2] = { + "waveaudio", + "mpegvideo", + }; + + HANDLE file; + DWORD file_size; + DWORD bytes_read; + DWORD offset; + char cmd_string[256]; + char *buf; + int32_t rc; + int32_t audio_type = -1; + + if (m_IsCDAudioEnabled) { + return true; + } + + for (int32_t i = 0; i < 2; ++i) { + file = CreateFile( + audio_files[i], GENERIC_READ, 0, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); + if (file != INVALID_HANDLE_VALUE) { + audio_type = i; + CloseHandle(file); + break; + } + } + if (audio_type < 0) { + return false; + } + + file = CreateFile( + "audio\\cdaudio.dat", GENERIC_READ, 0, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); + if (file == INVALID_HANDLE_VALUE) { + return false; + } + + file_size = GetFileSize(file, NULL); + buf = (char *)malloc(file_size); + if (buf == NULL) { + CloseHandle(file); + return false; + } + rc = ReadFile(file, buf, file_size, &bytes_read, NULL); + CloseHandle(file); + if (!rc || bytes_read == 0) { + return false; + } + + memset(g_Tracks, 0, sizeof(g_Tracks)); + offset = 0; + + while (offset < bytes_read) { + DWORD index, from, to; + + while (buf[offset] == 0x0A || buf[offset] == 0x0D) { + if (++offset >= bytes_read) { + goto PARSE_END; + } + } + rc = sscanf(&buf[offset], "%lu %lu %lu", &index, &from, &to); + if (rc == 3 && index > 0 && index <= 60) { + g_Tracks[index - 1].active = true; + g_Tracks[index - 1].from = from; + g_Tracks[index - 1].to = to; + } + while (buf[offset] != 0x0A && buf[offset] != 0x0D) { + if (++offset >= bytes_read) { + goto PARSE_END; + } + } + } + +PARSE_END: + free(buf); + + for (DWORD i = 0; i < MAX_TRACKS; ++i) { + if (!g_Tracks[i].active) { + continue; + } + if (g_Tracks[i].from >= g_Tracks[i].to && i < MAX_TRACKS - 1) { + for (DWORD j = i + 1; j < MAX_TRACKS; ++j) { + if (g_Tracks[j].active) { + g_Tracks[i].to = g_Tracks[j].from; + break; + } + } + } + if (g_Tracks[i].from >= g_Tracks[i].to && i > 0) { + for (int32_t j = i - 1; j >= 0; --j) { + if (g_Tracks[j].active) { + g_Tracks[i].from = g_Tracks[j].to; + break; + } + } + } + } + + wsprintf( + cmd_string, "open %s type %s alias " CD_ALIAS, audio_files[audio_type], + audio_types[audio_type]); + rc = mciSendStringA(cmd_string, NULL, 0, 0); + if (rc == 0) { + mciSendStringA("set " CD_ALIAS " time format ms", NULL, 0, 0); + m_IsCDAudioEnabled = true; + } + return true; +} + +void __cdecl PaulD_CD_Cleanup(void) +{ + if (!m_IsCDAudioEnabled) { + return; + } + + PaulD_CDStop(); + mciSendStringA("close " CD_ALIAS, NULL, 0, 0); + m_IsCDAudioEnabled = false; +} + +void __cdecl PaulD_CDPlay(int16_t track_id, bool is_looped) +{ + int16_t track; + char cmd_string[256]; + + if (g_OptionMusicVolume == 0) { + return; + } + + track = GetRealTrack(track_id); + if (track < 1 || !g_Tracks[track - 1].active) { + return; + } + + g_CD_TrackID = track_id; + + wsprintf( + cmd_string, "play " CD_ALIAS " from %lu to %lu", + g_Tracks[track - 1].from, g_Tracks[track - 1].to); + MMRESULT result = mciSendStringA(cmd_string, NULL, 0, 0); + + if (is_looped) { + g_CD_LoopTrack = track; + } +} + +void __cdecl PaulD_CDStop(void) +{ + if (g_CD_TrackID <= 0) { + return; + } + + mciSendStringA("stop " CD_ALIAS, NULL, 0, 0); + g_CD_TrackID = 0; + g_CD_LoopTrack = 0; +} + +bool __cdecl PaulD_StartSyncedAudio(int16_t track_id) +{ + int16_t track; + char cmd_string[256]; + + track = GetRealTrack(track_id); + if (track < 1 || !g_Tracks[track - 1].active) { + return false; + } + + g_CD_TrackID = track_id; + if (mciSendStringA("set " CD_ALIAS " time format ms", NULL, 0, 0) != 0) { + return false; + } + + wsprintf( + cmd_string, "play " CD_ALIAS " from %lu to %lu", + g_Tracks[track - 1].from, g_Tracks[track - 1].to); + return mciSendStringA(cmd_string, NULL, 0, 0) == 0; +} + +uint32_t __cdecl PaulD_CDGetLoc(void) +{ + int16_t track; + char status_string[32]; + + if (mciSendStringA( + "status " CD_ALIAS " position", status_string, + sizeof(status_string), 0) + != 0) { + return 0; + } + + track = GetRealTrack(g_CD_TrackID); + return (atol(status_string) - g_Tracks[track - 1].from) * 75 / 1000; +} + +void __cdecl PaulD_CDVolume(int32_t volume) +{ + char cmd_string[256]; + + if (volume > 0) { + volume = (volume - 5) * 4; + } + + wsprintf(cmd_string, "setaudio " CD_ALIAS " volume to %lu", volume); + mciSendStringA(cmd_string, NULL, 0, 0); + + char status_string[32]; + if (mciSendStringA( + "status " CD_ALIAS " mode", status_string, sizeof(status_string), 0) + != 0) { + return; + } + + if (volume > 0) { + if (!strncmp(status_string, "paused", sizeof(status_string))) { + mciSendStringA("resume " CD_ALIAS, NULL, 0, 0); + } + } else { + if (!strncmp(status_string, "playing", sizeof(status_string))) { + mciSendStringA("pause " CD_ALIAS, NULL, 0, 0); + } + } +} diff --git a/src/specific/s_pauld.h b/src/specific/s_pauld.h new file mode 100644 index 00000000..57354f65 --- /dev/null +++ b/src/specific/s_pauld.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2017-2018 Michael Chaban. All rights reserved. + * CD Audio solution in this file was designed by PaulD. + * Original game is created by Core Design Ltd. in 1997. + * Lara Croft and Tomb Raider are trademarks of Embracer Group AB. + * + * This file is part of TR2Main. + * + * TR2Main is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * TR2Main is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with TR2Main. If not, see . + */ + +#pragma once + +#include "global/types.h" + +#include +#include + +bool __cdecl PaulD_CD_Init(void); +void __cdecl PaulD_CD_Cleanup(void); +void __cdecl PaulD_CDPlay(int16_t track_id, bool is_looped); +void __cdecl PaulD_CDStop(void); +bool __cdecl PaulD_StartSyncedAudio(int16_t track_id); +uint32_t __cdecl PaulD_CDGetLoc(void); +void __cdecl PaulD_CDVolume(int32_t volume);