From 595421da3908a2d3e7a1b063605bb3f2a3adb65b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?eray=20or=C3=A7unus?= Date: Wed, 30 Sep 2020 20:02:47 +0300 Subject: Fixes, mouse AUX buttons, joystick detect menu --- src/core/Frontend.cpp | 21 ++++++++++++--- src/core/Game.cpp | 1 - src/core/Pad.h | 2 ++ src/core/config.h | 3 +++ src/core/re3.cpp | 73 ++++++++++++++++++++++++++++++++++++++++++++++----- src/core/timebars.cpp | 2 +- 6 files changed, 90 insertions(+), 12 deletions(-) (limited to 'src/core') diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp index 9ead2a0a..2cb27730 100644 --- a/src/core/Frontend.cpp +++ b/src/core/Frontend.cpp @@ -854,6 +854,13 @@ CMenuManager::Draw() str = TheText.Get(aScreens[m_nCurrScreen].m_aEntries[0].m_EntryName); break; default: +#ifdef CUSTOM_FRONTEND_OPTIONS + if (aScreens[m_nCurrScreen].m_aEntries[0].m_SaveSlot == SAVESLOT_CFO) { + FrontendOption& option = customFrontendOptions[aScreens[m_nCurrScreen].m_aEntries[0].m_TargetMenu]; + str = (wchar*)option.leftText; + } + else +#endif str = TheText.Get(aScreens[m_nCurrScreen].m_aEntries[0].m_EntryName); break; } @@ -3443,6 +3450,7 @@ CMenuManager::LoadSettings() CFileMgr::Read(fileHandle, m_PrefsSkinFile, 256); CFileMgr::Read(fileHandle, (char*)&m_ControlMethod, 1); CFileMgr::Read(fileHandle, (char*)&m_PrefsLanguage, 1); +/* #ifdef CUSTOM_FRONTEND_OPTIONS for (int i = 0; i < numCustomFrontendOptions; i++) { FrontendOption& option = customFrontendOptions[i]; @@ -3456,6 +3464,7 @@ CMenuManager::LoadSettings() CFileMgr::Read(fileHandle, (char *)&CMenuManager::m_PrefsIslandLoading, 1); CMenuManager::m_DisplayIslandLoading = CMenuManager::m_PrefsIslandLoading; #endif +*/ } } @@ -3546,6 +3555,7 @@ CMenuManager::SaveSettings() CFileMgr::Write(fileHandle, m_PrefsSkinFile, 256); CFileMgr::Write(fileHandle, (char*)&m_ControlMethod, 1); CFileMgr::Write(fileHandle, (char*)&m_PrefsLanguage, 1); +/* #ifdef CUSTOM_FRONTEND_OPTIONS for (int i = 0; i < numCustomFrontendOptions; i++) { FrontendOption &option = customFrontendOptions[i]; @@ -3557,6 +3567,7 @@ CMenuManager::SaveSettings() #ifdef NO_ISLAND_LOADING CFileMgr::Write(fileHandle, (char *)&CMenuManager::m_PrefsIslandLoading, 1); #endif +*/ } CFileMgr::CloseFile(fileHandle); @@ -3880,7 +3891,10 @@ CMenuManager::Process(void) MouseButtonJustClicked = 4; else if (CPad::GetPad(0)->GetMouseWheelDownJustUp()) MouseButtonJustClicked = 5; - // TODO two more buttons + else if (CPad::GetPad(0)->GetMouseX1JustUp()) + MouseButtonJustClicked = 6; + else if (CPad::GetPad(0)->GetMouseX2JustUp()) + MouseButtonJustClicked = 7; JoyButtonJustClicked = ControlsManager.GetJoyButtonJustDown(); @@ -5106,7 +5120,8 @@ CMenuManager::ProcessButtonPresses(void) *option.value = option.lastSavedValue = option.displayedValue; } else if (option.type == FEOPTION_DYNAMIC) { - option.buttonPressFunc(FEOPTION_ACTION_SELECT); + if (option.buttonPressFunc) + option.buttonPressFunc(FEOPTION_ACTION_SELECT); } else if (option.type == FEOPTION_REDIRECT) { ChangeScreen(option.to, option.option, true, option.fadeIn); } else if (option.type == FEOPTION_GOBACK) { @@ -5349,7 +5364,7 @@ CMenuManager::ProcessButtonPresses(void) option.changeFunc(option.displayedValue); *option.value = option.lastSavedValue = option.displayedValue; } - } else if (option.type == FEOPTION_DYNAMIC) { + } else if (option.type == FEOPTION_DYNAMIC && option.buttonPressFunc) { option.buttonPressFunc(changeValueBy > 0 ? FEOPTION_ACTION_RIGHT : FEOPTION_ACTION_LEFT); } DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); diff --git a/src/core/Game.cpp b/src/core/Game.cpp index e944512a..bb9df1a2 100644 --- a/src/core/Game.cpp +++ b/src/core/Game.cpp @@ -297,7 +297,6 @@ bool CGame::InitialiseOnceAfterRW(void) #ifdef CUSTOM_FRONTEND_OPTIONS if (numCustomFrontendOptions == 0 && numCustomFrontendScreens == 0) { CustomFrontendOptionsPopulate(); - FrontEndMenuManager.LoadSettings(); } #endif return true; diff --git a/src/core/Pad.h b/src/core/Pad.h index 8c3bc752..8c5d7ba3 100644 --- a/src/core/Pad.h +++ b/src/core/Pad.h @@ -277,6 +277,8 @@ public: bool GetMiddleMouseJustUp() { return !!(!NewMouseControllerState.MMB && OldMouseControllerState.MMB); } bool GetMouseWheelUpJustUp() { return !!(!NewMouseControllerState.WHEELUP && OldMouseControllerState.WHEELUP); } bool GetMouseWheelDownJustUp() { return !!(!NewMouseControllerState.WHEELDN && OldMouseControllerState.WHEELDN); } + bool GetMouseX1JustUp() { return !!(!NewMouseControllerState.MXB1 && OldMouseControllerState.MXB1); } + bool GetMouseX2JustUp() { return !!(!NewMouseControllerState.MXB2 && OldMouseControllerState.MXB2); } bool GetLeftMouse() { return NewMouseControllerState.LMB; } bool GetRightMouse() { return NewMouseControllerState.RMB; } diff --git a/src/core/config.h b/src/core/config.h index e8e15ebe..0f3cb2ef 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -226,6 +226,9 @@ enum Config { #if !defined(RW_GL3) && defined(_WIN32) #define XINPUT #endif +#if defined(RW_GL3) && !defined(__SWITCH__) // TODO +#define DONT_TRUST_RECOGNIZED_JOYSTICKS // Then we'll only rely on GLFW gamepad DB, and want user to enter Cpntroller->Detect joysticks if his joystick isn't on that list. +#endif #define DETECT_PAD_INPUT_SWITCH // Adds automatic switch of pad related stuff between controller and kb/m #define KANGAROO_CHEAT #define ALLCARSHELI_CHEAT diff --git a/src/core/re3.cpp b/src/core/re3.cpp index 13cb6283..b892ca36 100644 --- a/src/core/re3.cpp +++ b/src/core/re3.cpp @@ -32,6 +32,7 @@ #include "MBlur.h" #include "postfx.h" #include "custompipes.h" +#include "ControllerConfig.h" #ifndef _WIN32 #include "assert.h" @@ -195,6 +196,7 @@ wchar* MultiSamplingDraw(bool *disabled, bool userHovering) { return unicodeTemp; } } +char* multisamplingKey = "MultiSampling"; #endif #ifdef MORE_LANGUAGES @@ -247,6 +249,8 @@ void FreeCamChange(int8 displayedValue) TheCamera.bFreeCam = !!displayedValue; FrontEndMenuManager.SaveSettings(); } +const wchar* freeCamText = (wchar*)L"FREE CAM"; +char* freeCamKey = "FreeCam"; #endif #ifdef CUTSCENE_BORDERS_SWITCH @@ -255,6 +259,7 @@ void BorderModeChange(int8 displayedValue) CMenuManager::m_PrefsCutsceneBorders = !!displayedValue; FrontEndMenuManager.SaveSettings(); } +char* cutsceneBordersKey = "CutsceneBorders"; #endif #ifdef PS2_ALPHA_TEST @@ -263,11 +268,52 @@ void PS2AlphaTestChange(int8 displayedValue) gPS2alphaTest = !!displayedValue; FrontEndMenuManager.SaveSettings(); } +char* ps2alphaKey = "PS2AlphaTest"; #endif +#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS +const wchar* detectJoystickText = (wchar*)L"Detect Joystick"; +const wchar* detectJoystickExplanation = (wchar*)L"Press any key on your preferred joystick that you would like to use on the game."; +const wchar* detectedJoystickText = (wchar*)L"Detected Joystick"; +wchar selectedJoystickUnicode[128]; + +wchar* DetectJoystickDraw(bool* disabled, bool userHovering) { + int numButtons; + int found = -1; + const char *joyname; + if (userHovering) { + for (int i = 0; i <= GLFW_JOYSTICK_LAST; i++) { + if (joyname = glfwGetJoystickName(i)) { + const uint8* buttons = glfwGetJoystickButtons(i, &numButtons); + for (int j = 0; j < numButtons; j++) { + if (buttons[j]) { + strcpy(gSelectedJoystickName, joyname); + found = i; + break; + } + } + if (found != -1) + break; + } + } + + if (found != -1 && PSGLOBAL(joy1id) != found) { + if (PSGLOBAL(joy1id) != -1 && PSGLOBAL(joy1id) != found) + PSGLOBAL(joy2id) = PSGLOBAL(joy1id); + else + PSGLOBAL(joy2id) = -1; + + PSGLOBAL(joy1id) = found; + } + } + AsciiToUnicode(gSelectedJoystickName, selectedJoystickUnicode); + + return selectedJoystickUnicode; +} +#endif // Important: Make sure to read the warnings/informations in frontendoption.h!! -// For texts: Either use TheText.Get, or use wcsdup(wchar version of strdup) +// If you won't use GXT entry as text, you may want to declare them globally, to not alloc them on each reload. (static declared texts has some problems on Linux etc.) void CustomFrontendOptionsPopulate(void) { @@ -342,14 +388,14 @@ CustomFrontendOptionsPopulate(void) #ifdef MULTISAMPLING SWITCH_TO_GRAPHICS_MENU - FrontendOptionAddDynamic(TheText.Get("FED_AAS"), MultiSamplingDraw, (int8*)&FrontEndMenuManager.m_nPrefsMSAALevel, MultiSamplingButtonPress, MultiSamplingGoBack, true); + FrontendOptionAddDynamic(TheText.Get("FED_AAS"), MultiSamplingDraw, (int8*)&FrontEndMenuManager.m_nPrefsMSAALevel, MultiSamplingButtonPress, MultiSamplingGoBack, multisamplingKey); #endif CLONE_OPTION(TheText.Get("FED_TRA"), MENUACTION_TRAILS, nil, nil); #ifdef PS2_ALPHA_TEST SWITCH_TO_GRAPHICS_MENU - FrontendOptionAddSelect(TheText.Get("FEM_2PR"), off_on, 2, (int8*)&gPS2alphaTest, false, PS2AlphaTestChange, nil, true); + FrontendOptionAddSelect(TheText.Get("FEM_2PR"), off_on, 2, (int8*)&gPS2alphaTest, false, PS2AlphaTestChange, nil, ps2alphaKey); #endif ADD_RESTORE_DEFAULTS(RestoreDefGraphics) @@ -365,13 +411,12 @@ CustomFrontendOptionsPopulate(void) #ifdef CUTSCENE_BORDERS_SWITCH SWITCH_TO_DISPLAY_MENU - FrontendOptionAddSelect(TheText.Get("FEM_CSB"), off_on, 2, (int8 *)&CMenuManager::m_PrefsCutsceneBorders, false, BorderModeChange, nil, true); + FrontendOptionAddSelect(TheText.Get("FEM_CSB"), off_on, 2, (int8 *)&CMenuManager::m_PrefsCutsceneBorders, false, BorderModeChange, nil, cutsceneBordersKey); #endif #ifdef FREE_CAM SWITCH_TO_DISPLAY_MENU - static const wchar* text = (wchar*)wcsdup(L"FREE CAM"); - FrontendOptionAddSelect(text, off_on, 2, (int8*)&TheCamera.bFreeCam, false, FreeCamChange, nil, true); + FrontendOptionAddSelect(freeCamText, off_on, 2, (int8*)&TheCamera.bFreeCam, false, FreeCamChange, nil, freeCamKey); #endif CLONE_OPTION(TheText.Get("FED_SUB"), MENUACTION_SUBTITLES, nil, nil); @@ -388,7 +433,21 @@ CustomFrontendOptionsPopulate(void) #endif ADD_RESTORE_DEFAULTS(RestoreDefDisplay) - ADD_BACK + ADD_BACK + +#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS + int detectJoystickMenu = FrontendScreenAdd("FET_CON", MENUSPRITE_MAINMENU, MENUPAGE_CONTROLLER_PC, 50, 60, 20, + FONT_BANK, MEDIUMTEXT_X_SCALE, MEDIUMTEXT_Y_SCALE, FESCREEN_LEFT_ALIGN, false); + + FrontendOptionSetCursor(detectJoystickMenu, 0); + + FrontendOptionAddBuiltinAction(detectJoystickExplanation, MENUACTION_LABEL, nil, nil); + FrontendOptionAddDynamic(detectedJoystickText, DetectJoystickDraw, nil, nil, nil); + FrontendOptionAddBackButton(TheText.Get("FEDS_TB")); + + FrontendOptionSetCursor(MENUPAGE_CONTROLLER_PC, 2); + FrontendOptionAddRedirect(detectJoystickText, detectJoystickMenu, 1); +#endif } #endif diff --git a/src/core/timebars.cpp b/src/core/timebars.cpp index 5ac5565d..94051b25 100644 --- a/src/core/timebars.cpp +++ b/src/core/timebars.cpp @@ -89,7 +89,7 @@ void tbDisplay() CFont::SetScale(0.48f, 1.12f); CFont::SetCentreOff(); CFont::SetJustifyOff(); - CFont::SetWrapx(640.0f); + CFont::SetWrapx(SCREEN_STRETCH_X(DEFAULT_SCREEN_WIDTH)); CFont::SetRightJustifyOff(); CFont::SetPropOn(); CFont::SetFontStyle(FONT_BANK); -- cgit v1.2.3 From 01ea7801fdd51852a4312350cd6c8bf91efe8666 Mon Sep 17 00:00:00 2001 From: Andrew Udvare Date: Tue, 29 Sep 2020 20:39:18 -0400 Subject: macOS support; thanks to @MrYadro This should support ARM64 and x86-64. -target flag based on information from https://developer.apple.com/documentation/xcode/building_a_universal_macos_binary#3618377. --- src/core/CdStreamPosix.cpp | 73 +++++++++++++++++++++++++++++++--------------- 1 file changed, 49 insertions(+), 24 deletions(-) (limited to 'src/core') diff --git a/src/core/CdStreamPosix.cpp b/src/core/CdStreamPosix.cpp index e114a29a..895143a4 100644 --- a/src/core/CdStreamPosix.cpp +++ b/src/core/CdStreamPosix.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -21,6 +22,30 @@ #define CDDEBUG(f, ...) debug ("%s: " f "\n", "cdvd_stream", ## __VA_ARGS__) #define CDTRACE(f, ...) printf("%s: " f "\n", "cdvd_stream", ## __VA_ARGS__) +#ifdef __APPLE__ +#define COMPAT_SEM_T sem_t * +int compat_sem_init(sem_t **ptr, __attribute__((unused)) int x, __attribute__((unused)) int y) { + *ptr = sem_open("/semaphore", O_CREAT, 0644, 1); + return *ptr == SEM_FAILED ? -1 : 0; +} +int compat_sem_post(sem_t **sem) { + return sem_post(*sem); +} +int compat_sem_wait(sem_t **sem) { + return sem_wait(*sem); +} +int compat_sem_destroy(sem_t **sem, const char * name) { + sem_close(*sem); + sem_unlink(name); +} +#else +#define COMPAT_SEM_T sem_t +#define compat_sem_post sem_post +#define compat_sem_destroy(x, y) sem_destroy(x) +#define compat_sem_init sem_init +#define compat_sem_wait sem_wait +#endif + // #define ONE_THREAD_PER_CHANNEL // Don't use if you're not on SSD/Flash. (Also you may want to benefit from this via using all channels in Streaming.cpp) bool flushStream[MAX_CDCHANNELS]; @@ -35,11 +60,11 @@ struct CdReadInfo int32 nStatus; #ifdef ONE_THREAD_PER_CHANNEL int8 nThreadStatus; // 0: created 1:initalized 2:abort now - pthread_t pChannelThread; - sem_t pStartSemaphore; + pthread_t pChannelThread; + COMPAT_SEM_T pStartSemaphore; #endif - sem_t pDoneSemaphore; // used for CdStreamSync - int32 hFile; + COMPAT_SEM_T pDoneSemaphore; // used for CdStreamSync + int32 hFile; }; char gCdImageNames[MAX_CDIMAGES+1][64]; @@ -51,7 +76,7 @@ char *gImgNames[MAX_CDIMAGES]; #ifndef ONE_THREAD_PER_CHANNEL pthread_t _gCdStreamThread; -sem_t gCdStreamSema; // released when we have new thing to read(so channel is set) +COMPAT_SEM_T gCdStreamSema; // released when we have new thing to read(so channel is set) int8 gCdStreamThreadStatus; // 0: created 1:initalized 2:abort now Queue gChannelRequestQ; bool _gbCdStreamOverlapped; @@ -76,7 +101,7 @@ CdStreamInitThread(void) gChannelRequestQ.tail = 0; gChannelRequestQ.size = gNumChannels + 1; ASSERT(gChannelRequestQ.items != nil ); - status = sem_init(&gCdStreamSema, 0, 0); + status = compat_sem_init(&gCdStreamSema, 0, 0); #endif @@ -91,7 +116,7 @@ CdStreamInitThread(void) { for ( int32 i = 0; i < gNumChannels; i++ ) { - status = sem_init(&gpReadInfo[i].pDoneSemaphore, 0, 0); + status = compat_sem_init(&gpReadInfo[i].pDoneSemaphore, 0, 0); if (status == -1) { @@ -100,7 +125,7 @@ CdStreamInitThread(void) return; } #ifdef ONE_THREAD_PER_CHANNEL - status = sem_init(&gpReadInfo[i].pStartSemaphore, 0, 0); + status = compat_sem_init(&gpReadInfo[i].pStartSemaphore, 0, 0); if (status == -1) { @@ -214,13 +239,13 @@ CdStreamShutdown(void) // Destroying semaphores and free(gpReadInfo) will be done at threads #ifndef ONE_THREAD_PER_CHANNEL gCdStreamThreadStatus = 2; - sem_post(&gCdStreamSema); + compat_sem_post(&gCdStreamSema); #endif #ifdef ONE_THREAD_PER_CHANNEL for ( int32 i = 0; i < gNumChannels; i++ ) { gpReadInfo[i].nThreadStatus = 2; - sem_post(&gpReadInfo[i].pStartSemaphore); + compat_sem_post(&gpReadInfo[i].pStartSemaphore); } #endif } @@ -254,10 +279,10 @@ CdStreamRead(int32 channel, void *buffer, uint32 offset, uint32 size) #ifndef ONE_THREAD_PER_CHANNEL AddToQueue(&gChannelRequestQ, channel); - if ( sem_post(&gCdStreamSema) != 0 ) + if ( compat_sem_post(&gCdStreamSema) != 0 ) printf("Signal Sema Error\n"); #else - if ( sem_post(&gpReadInfo[channel].pStartSemaphore) != 0 ) + if ( compat_sem_post(&gpReadInfo[channel].pStartSemaphore) != 0 ) printf("Signal Sema Error\n"); #endif @@ -332,7 +357,7 @@ CdStreamSync(int32 channel) { pChannel->bLocked = true; - sem_wait(&pChannel->pDoneSemaphore); + compat_sem_wait(&pChannel->pDoneSemaphore); } pChannel->bReading = false; @@ -383,12 +408,12 @@ void *CdStreamThread(void *param) #ifndef ONE_THREAD_PER_CHANNEL while (gCdStreamThreadStatus != 2) { - sem_wait(&gCdStreamSema); + compat_sem_wait(&gCdStreamSema); int32 channel = GetFirstInQueue(&gChannelRequestQ); #else int channel = *((int*)param); while (gpReadInfo[channel].nThreadStatus != 2){ - sem_wait(&gpReadInfo[channel].pStartSemaphore); + compat_sem_wait(&gpReadInfo[channel].pStartSemaphore); #endif ASSERT( channel < gNumChannels ); @@ -437,22 +462,22 @@ void *CdStreamThread(void *param) if ( pChannel->bLocked ) { - sem_post(&pChannel->pDoneSemaphore); + compat_sem_post(&pChannel->pDoneSemaphore); } pChannel->bReading = false; } #ifndef ONE_THREAD_PER_CHANNEL - for ( int32 i = 0; i < gNumChannels; i++ ) - { - sem_destroy(&gpReadInfo[i].pDoneSemaphore); - } - sem_destroy(&gCdStreamSema); + for ( int32 i = 0; i < gNumChannels; i++ ) + { + compat_sem_destroy(&gpReadInfo[i].pDoneSemaphore, "/semaphoredone"); + } + compat_sem_destroy(&gCdStreamSema, "/semaphore"); free(gChannelRequestQ.items); #else - sem_destroy(&gpReadInfo[channel].pStartSemaphore); - sem_destroy(&gpReadInfo[channel].pDoneSemaphore); + compat_sem_destroy(&gpReadInfo[channel].pStartSemaphore, "/semaphorestart"); + compat_sem_destroy(&gpReadInfo[channel].pDoneSemaphore, "/semaphoredone"); #endif - free(gpReadInfo); + free(gpReadInfo); pthread_exit(nil); } -- cgit v1.2.3 From bbb578c5b1cd603b61ebd5f6fec184477f1c5dd4 Mon Sep 17 00:00:00 2001 From: Andrew Udvare Date: Thu, 1 Oct 2020 03:21:06 -0400 Subject: core/CdStreamPosix: switch to named semaphores to support macOS macOS does not support unnamed semaphores. The functions return ENOSYS. --- src/core/CdStreamPosix.cpp | 87 ++++++++++++++++++---------------------------- 1 file changed, 33 insertions(+), 54 deletions(-) (limited to 'src/core') diff --git a/src/core/CdStreamPosix.cpp b/src/core/CdStreamPosix.cpp index 895143a4..3d9316c9 100644 --- a/src/core/CdStreamPosix.cpp +++ b/src/core/CdStreamPosix.cpp @@ -4,7 +4,6 @@ #include #include #include -#include #include #include #include @@ -22,30 +21,6 @@ #define CDDEBUG(f, ...) debug ("%s: " f "\n", "cdvd_stream", ## __VA_ARGS__) #define CDTRACE(f, ...) printf("%s: " f "\n", "cdvd_stream", ## __VA_ARGS__) -#ifdef __APPLE__ -#define COMPAT_SEM_T sem_t * -int compat_sem_init(sem_t **ptr, __attribute__((unused)) int x, __attribute__((unused)) int y) { - *ptr = sem_open("/semaphore", O_CREAT, 0644, 1); - return *ptr == SEM_FAILED ? -1 : 0; -} -int compat_sem_post(sem_t **sem) { - return sem_post(*sem); -} -int compat_sem_wait(sem_t **sem) { - return sem_wait(*sem); -} -int compat_sem_destroy(sem_t **sem, const char * name) { - sem_close(*sem); - sem_unlink(name); -} -#else -#define COMPAT_SEM_T sem_t -#define compat_sem_post sem_post -#define compat_sem_destroy(x, y) sem_destroy(x) -#define compat_sem_init sem_init -#define compat_sem_wait sem_wait -#endif - // #define ONE_THREAD_PER_CHANNEL // Don't use if you're not on SSD/Flash. (Also you may want to benefit from this via using all channels in Streaming.cpp) bool flushStream[MAX_CDCHANNELS]; @@ -60,11 +35,11 @@ struct CdReadInfo int32 nStatus; #ifdef ONE_THREAD_PER_CHANNEL int8 nThreadStatus; // 0: created 1:initalized 2:abort now - pthread_t pChannelThread; - COMPAT_SEM_T pStartSemaphore; + pthread_t pChannelThread; + sem_t *pStartSemaphore; #endif - COMPAT_SEM_T pDoneSemaphore; // used for CdStreamSync - int32 hFile; + sem_t *pDoneSemaphore; // used for CdStreamSync + int32 hFile; }; char gCdImageNames[MAX_CDIMAGES+1][64]; @@ -76,7 +51,7 @@ char *gImgNames[MAX_CDIMAGES]; #ifndef ONE_THREAD_PER_CHANNEL pthread_t _gCdStreamThread; -COMPAT_SEM_T gCdStreamSema; // released when we have new thing to read(so channel is set) +sem_t *gCdStreamSema; // released when we have new thing to read(so channel is set) int8 gCdStreamThreadStatus; // 0: created 1:initalized 2:abort now Queue gChannelRequestQ; bool _gbCdStreamOverlapped; @@ -101,11 +76,11 @@ CdStreamInitThread(void) gChannelRequestQ.tail = 0; gChannelRequestQ.size = gNumChannels + 1; ASSERT(gChannelRequestQ.items != nil ); - status = compat_sem_init(&gCdStreamSema, 0, 0); + gCdStreamSema = sem_open("/semaphore_cd_stream", O_CREAT, 0644, 1); #endif - if (status == -1) { + if (gCdStreamSema == SEM_FAILED) { CDTRACE("failed to create stream semaphore"); ASSERT(0); return; @@ -116,18 +91,18 @@ CdStreamInitThread(void) { for ( int32 i = 0; i < gNumChannels; i++ ) { - status = compat_sem_init(&gpReadInfo[i].pDoneSemaphore, 0, 0); + gpReadInfo[i].pDoneSemaphore = sem_open("/semaphore_done", O_CREAT, 0644, 1); - if (status == -1) + if (gpReadInfo[i].pDoneSemaphore == SEM_FAILED) { CDTRACE("failed to create sync semaphore"); ASSERT(0); return; } #ifdef ONE_THREAD_PER_CHANNEL - status = compat_sem_init(&gpReadInfo[i].pStartSemaphore, 0, 0); + gpReadInfo[i].pStartSemaphore = sem_open("/semaphore_start", O_CREAT, 0644, 1); - if (status == -1) + if (gpReadInfo[i].pStartSemaphore == SEM_FAILED) { CDTRACE("failed to create start semaphore"); ASSERT(0); @@ -160,7 +135,7 @@ CdStreamInitThread(void) return; } #else - debug("Using seperate streaming threads for each channel\n"); + debug("Using separate streaming threads for each channel\n"); #endif } @@ -239,13 +214,13 @@ CdStreamShutdown(void) // Destroying semaphores and free(gpReadInfo) will be done at threads #ifndef ONE_THREAD_PER_CHANNEL gCdStreamThreadStatus = 2; - compat_sem_post(&gCdStreamSema); + sem_post(gCdStreamSema); #endif #ifdef ONE_THREAD_PER_CHANNEL for ( int32 i = 0; i < gNumChannels; i++ ) { gpReadInfo[i].nThreadStatus = 2; - compat_sem_post(&gpReadInfo[i].pStartSemaphore); + sem_post(&gpReadInfo[i].pStartSemaphore); } #endif } @@ -279,10 +254,10 @@ CdStreamRead(int32 channel, void *buffer, uint32 offset, uint32 size) #ifndef ONE_THREAD_PER_CHANNEL AddToQueue(&gChannelRequestQ, channel); - if ( compat_sem_post(&gCdStreamSema) != 0 ) + if ( sem_post(gCdStreamSema) != 0 ) printf("Signal Sema Error\n"); #else - if ( compat_sem_post(&gpReadInfo[channel].pStartSemaphore) != 0 ) + if ( sem_post(&gpReadInfo[channel].pStartSemaphore) != 0 ) printf("Signal Sema Error\n"); #endif @@ -357,7 +332,7 @@ CdStreamSync(int32 channel) { pChannel->bLocked = true; - compat_sem_wait(&pChannel->pDoneSemaphore); + sem_wait(pChannel->pDoneSemaphore); } pChannel->bReading = false; @@ -408,12 +383,12 @@ void *CdStreamThread(void *param) #ifndef ONE_THREAD_PER_CHANNEL while (gCdStreamThreadStatus != 2) { - compat_sem_wait(&gCdStreamSema); + sem_wait(gCdStreamSema); int32 channel = GetFirstInQueue(&gChannelRequestQ); #else int channel = *((int*)param); while (gpReadInfo[channel].nThreadStatus != 2){ - compat_sem_wait(&gpReadInfo[channel].pStartSemaphore); + sem_wait(&gpReadInfo[channel].pStartSemaphore); #endif ASSERT( channel < gNumChannels ); @@ -462,22 +437,26 @@ void *CdStreamThread(void *param) if ( pChannel->bLocked ) { - compat_sem_post(&pChannel->pDoneSemaphore); + sem_post(pChannel->pDoneSemaphore); } pChannel->bReading = false; } #ifndef ONE_THREAD_PER_CHANNEL - for ( int32 i = 0; i < gNumChannels; i++ ) - { - compat_sem_destroy(&gpReadInfo[i].pDoneSemaphore, "/semaphoredone"); - } - compat_sem_destroy(&gCdStreamSema, "/semaphore"); - free(gChannelRequestQ.items); + for ( int32 i = 0; i < gNumChannels; i++ ) + { + sem_close(gpReadInfo[i].pDoneSemaphore); + sem_unlink("/semaphore_done"); + } + sem_close(gCdStreamSema); + sem_unlink("/semaphore_cd_stream"); + free(gChannelRequestQ.items); #else - compat_sem_destroy(&gpReadInfo[channel].pStartSemaphore, "/semaphorestart"); - compat_sem_destroy(&gpReadInfo[channel].pDoneSemaphore, "/semaphoredone"); + sem_close(gpReadInfo[channel].pStartSemaphore); + sem_unlink("/semaphore_start"); + sem_close(gpReadInfo[channel].pDoneSemaphore); + sem_unlink("/semaphore_done"); #endif - free(gpReadInfo); + free(gpReadInfo); pthread_exit(nil); } -- cgit v1.2.3 From f6bc2b654c4b6f8ae27646f1a166d3214f6f56aa Mon Sep 17 00:00:00 2001 From: Andrew Udvare Date: Thu, 1 Oct 2020 20:45:38 -0400 Subject: CdStreamPosix: fix type issues --- src/core/CdStreamPosix.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/core') diff --git a/src/core/CdStreamPosix.cpp b/src/core/CdStreamPosix.cpp index 3d9316c9..40000f03 100644 --- a/src/core/CdStreamPosix.cpp +++ b/src/core/CdStreamPosix.cpp @@ -163,7 +163,7 @@ CdStreamInit(int32 numChannels) debug("Using no buffered loading for streaming\n"); } */ - void *pBuffer = (void *)RwMallocAlign(CDSTREAM_SECTOR_SIZE, fsInfo.f_bsize); + void *pBuffer = (void *)RwMallocAlign(CDSTREAM_SECTOR_SIZE, (RwUInt32)fsInfo.f_bsize); ASSERT( pBuffer != nil ); gNumImages = 0; @@ -205,7 +205,7 @@ GetGTA3ImgSize(void) return 0; } ok: - return statbuf.st_size; + return (uint32)statbuf.st_size; } void -- cgit v1.2.3 From 3bd333022778cee8dd95b58b02a7263870546c1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?eray=20or=C3=A7unus?= Date: Fri, 2 Oct 2020 17:36:56 +0300 Subject: Load and write our settings in re3.ini & fixes --- src/core/Frontend.cpp | 37 ++++------------- src/core/Game.cpp | 5 +++ src/core/common.h | 4 +- src/core/config.h | 7 ++-- src/core/main.h | 5 +++ src/core/re3.cpp | 113 ++++++++++++++++++++++++++++++++++++++++---------- 6 files changed, 116 insertions(+), 55 deletions(-) (limited to 'src/core') diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp index 2cb27730..db3774a7 100644 --- a/src/core/Frontend.cpp +++ b/src/core/Frontend.cpp @@ -3450,21 +3450,6 @@ CMenuManager::LoadSettings() CFileMgr::Read(fileHandle, m_PrefsSkinFile, 256); CFileMgr::Read(fileHandle, (char*)&m_ControlMethod, 1); CFileMgr::Read(fileHandle, (char*)&m_PrefsLanguage, 1); -/* -#ifdef CUSTOM_FRONTEND_OPTIONS - for (int i = 0; i < numCustomFrontendOptions; i++) { - FrontendOption& option = customFrontendOptions[i]; - if (option.save) { - CFileMgr::Read(fileHandle, (char*)option.value, 1); - option.lastSavedValue = option.displayedValue = *option.value; - } - } -#endif -#ifdef NO_ISLAND_LOADING - CFileMgr::Read(fileHandle, (char *)&CMenuManager::m_PrefsIslandLoading, 1); - CMenuManager::m_DisplayIslandLoading = CMenuManager::m_PrefsIslandLoading; -#endif -*/ } } @@ -3481,8 +3466,11 @@ CMenuManager::LoadSettings() m_bLanguageLoaded = false; else { m_bLanguageLoaded = true; + // Already called in InitialiseChangedLanguageSettings + /* TheText.Unload(); TheText.Load(); + */ m_bFrontEnd_ReloadObrTxtGxt = true; InitialiseChangedLanguageSettings(); @@ -3555,23 +3543,14 @@ CMenuManager::SaveSettings() CFileMgr::Write(fileHandle, m_PrefsSkinFile, 256); CFileMgr::Write(fileHandle, (char*)&m_ControlMethod, 1); CFileMgr::Write(fileHandle, (char*)&m_PrefsLanguage, 1); -/* -#ifdef CUSTOM_FRONTEND_OPTIONS - for (int i = 0; i < numCustomFrontendOptions; i++) { - FrontendOption &option = customFrontendOptions[i]; - if (option.save) { - CFileMgr::Write(fileHandle, (char*)option.value, 1); - } - } -#endif -#ifdef NO_ISLAND_LOADING - CFileMgr::Write(fileHandle, (char *)&CMenuManager::m_PrefsIslandLoading, 1); -#endif -*/ } CFileMgr::CloseFile(fileHandle); CFileMgr::SetDir(""); + +#ifdef LOAD_INI_SETTINGS + SaveINISettings(); +#endif } bool DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha); @@ -6332,4 +6311,4 @@ CMenuManager::ConstructStatLine(int rowIdx) #undef GetBackJustDown #undef ChangeScreen -#endif \ No newline at end of file +#endif diff --git a/src/core/Game.cpp b/src/core/Game.cpp index bb9df1a2..93f0d1b0 100644 --- a/src/core/Game.cpp +++ b/src/core/Game.cpp @@ -295,9 +295,14 @@ bool CGame::InitialiseOnceAfterRW(void) CWorld::Players[0].SetPlayerSkin(CMenuManager::m_PrefsSkinFile); #ifdef CUSTOM_FRONTEND_OPTIONS + // Apparently this func. can be run multiple times at the start. if (numCustomFrontendOptions == 0 && numCustomFrontendScreens == 0) { + // needs stored language and TheText to be loaded, and last TheText reload is at the start of here CustomFrontendOptionsPopulate(); } +#endif +#ifdef LOAD_INI_SETTINGS + LoadINISettings(); // needs frontend options to be loaded #endif return true; } diff --git a/src/core/common.h b/src/core/common.h index 9b5c2369..ef3da265 100644 --- a/src/core/common.h +++ b/src/core/common.h @@ -219,6 +219,8 @@ public: extern int strcasecmp(const char *str1, const char *str2); #endif +extern wchar *AllocUnicode(const char*src); + #define clamp(v, low, high) ((v)<(low) ? (low) : (v)>(high) ? (high) : (v)) inline float sq(float x) { return x*x; } @@ -444,4 +446,4 @@ inline T *WriteSaveBuf(uint8 *&buf, const T &value) assert(ReadSaveBuf(buf) == size); -void cprintf(char*, ...); \ No newline at end of file +void cprintf(char*, ...); diff --git a/src/core/config.h b/src/core/config.h index 0f3cb2ef..171c6be9 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -198,6 +198,7 @@ enum Config { #define FIX_BUGS // fixes bugs that we've came across during reversing, TODO: use this more #define MORE_LANGUAGES // Add more translations to the game #define COMPATIBLE_SAVES // this allows changing structs while keeping saves compatible +#define LOAD_INI_SETTINGS // Rendering/display #define ASPECT_RATIO_SCALE // Not just makes everything scale with aspect ratio, also adds support for all aspect ratios @@ -226,8 +227,8 @@ enum Config { #if !defined(RW_GL3) && defined(_WIN32) #define XINPUT #endif -#if defined(RW_GL3) && !defined(__SWITCH__) // TODO -#define DONT_TRUST_RECOGNIZED_JOYSTICKS // Then we'll only rely on GLFW gamepad DB, and want user to enter Cpntroller->Detect joysticks if his joystick isn't on that list. +#if !defined(_WIN32) && !defined(__SWITCH__) +#define DONT_TRUST_RECOGNIZED_JOYSTICKS // Then we'll only rely on GLFW gamepad DB, and expect user to enter Controller->Detect joysticks if his joystick isn't on that list. #endif #define DETECT_PAD_INPUT_SWITCH // Adds automatic switch of pad related stuff between controller and kb/m #define KANGAROO_CHEAT @@ -309,4 +310,4 @@ enum Config { #undef NO_ISLAND_LOADING #define PC_PARTICLE #define VC_PED_PORTS // To not process collisions always. But should be tested if that's really beneficial -#endif \ No newline at end of file +#endif diff --git a/src/core/main.h b/src/core/main.h index 96fbef05..7eb080cb 100644 --- a/src/core/main.h +++ b/src/core/main.h @@ -36,3 +36,8 @@ void ResetLoadingScreenBar(void); #ifndef MASTER void TheModelViewer(void); #endif + +#ifdef LOAD_INI_SETTINGS +void LoadINISettings(); +void SaveINISettings(); +#endif diff --git a/src/core/re3.cpp b/src/core/re3.cpp index b892ca36..069320ec 100644 --- a/src/core/re3.cpp +++ b/src/core/re3.cpp @@ -1,6 +1,7 @@ #include #define WITHWINDOWS #include "common.h" +#include "platform.h" #include "crossplatform.h" #include "Renderer.h" #include "Credits.h" @@ -16,7 +17,6 @@ #include "Heli.h" #include "Automobile.h" #include "Ped.h" -#include "Particle.h" #include "Console.h" #include "Debug.h" #include "Hud.h" @@ -32,15 +32,12 @@ #include "MBlur.h" #include "postfx.h" #include "custompipes.h" -#include "ControllerConfig.h" #ifndef _WIN32 #include "assert.h" #include #endif -#include - #ifdef RWLIBS extern "C" int vsprintf(char* const _Buffer, char const* const _Format, va_list _ArgList); #endif @@ -74,7 +71,6 @@ mysrand(unsigned int seed) #ifdef CUSTOM_FRONTEND_OPTIONS #include "frontendoption.h" -#include "platform.h" #include "Font.h" void ReloadFrontendOptions(void) @@ -196,7 +192,7 @@ wchar* MultiSamplingDraw(bool *disabled, bool userHovering) { return unicodeTemp; } } -char* multisamplingKey = "MultiSampling"; +const char* multisamplingKey = "MultiSampling"; #endif #ifdef MORE_LANGUAGES @@ -249,8 +245,7 @@ void FreeCamChange(int8 displayedValue) TheCamera.bFreeCam = !!displayedValue; FrontEndMenuManager.SaveSettings(); } -const wchar* freeCamText = (wchar*)L"FREE CAM"; -char* freeCamKey = "FreeCam"; +const char* freeCamKey = "FreeCam"; #endif #ifdef CUTSCENE_BORDERS_SWITCH @@ -259,7 +254,7 @@ void BorderModeChange(int8 displayedValue) CMenuManager::m_PrefsCutsceneBorders = !!displayedValue; FrontEndMenuManager.SaveSettings(); } -char* cutsceneBordersKey = "CutsceneBorders"; +const char* cutsceneBordersKey = "CutsceneBorders"; #endif #ifdef PS2_ALPHA_TEST @@ -268,13 +263,10 @@ void PS2AlphaTestChange(int8 displayedValue) gPS2alphaTest = !!displayedValue; FrontEndMenuManager.SaveSettings(); } -char* ps2alphaKey = "PS2AlphaTest"; +const char* ps2alphaKey = "PS2AlphaTest"; #endif #ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS -const wchar* detectJoystickText = (wchar*)L"Detect Joystick"; -const wchar* detectJoystickExplanation = (wchar*)L"Press any key on your preferred joystick that you would like to use on the game."; -const wchar* detectedJoystickText = (wchar*)L"Detected Joystick"; wchar selectedJoystickUnicode[128]; wchar* DetectJoystickDraw(bool* disabled, bool userHovering) { @@ -287,7 +279,6 @@ wchar* DetectJoystickDraw(bool* disabled, bool userHovering) { const uint8* buttons = glfwGetJoystickButtons(i, &numButtons); for (int j = 0; j < numButtons; j++) { if (buttons[j]) { - strcpy(gSelectedJoystickName, joyname); found = i; break; } @@ -303,17 +294,21 @@ wchar* DetectJoystickDraw(bool* disabled, bool userHovering) { else PSGLOBAL(joy2id) = -1; + strcpy(gSelectedJoystickName, joyname); PSGLOBAL(joy1id) = found; } } - AsciiToUnicode(gSelectedJoystickName, selectedJoystickUnicode); + if (PSGLOBAL(joy1id) == -1) + AsciiToUnicode("Not found", selectedJoystickUnicode); + else + AsciiToUnicode(gSelectedJoystickName, selectedJoystickUnicode); return selectedJoystickUnicode; } #endif // Important: Make sure to read the warnings/informations in frontendoption.h!! -// If you won't use GXT entry as text, you may want to declare them globally, to not alloc them on each reload. (static declared texts has some problems on Linux etc.) +// If you will hardcode any text, please use AllocUnicode! wchar_t size differs between platforms void CustomFrontendOptionsPopulate(void) { @@ -416,7 +411,7 @@ CustomFrontendOptionsPopulate(void) #ifdef FREE_CAM SWITCH_TO_DISPLAY_MENU - FrontendOptionAddSelect(freeCamText, off_on, 2, (int8*)&TheCamera.bFreeCam, false, FreeCamChange, nil, freeCamKey); + FrontendOptionAddSelect(TheText.Get("FEC_FRC"), off_on, 2, (int8*)&TheCamera.bFreeCam, false, FreeCamChange, nil, freeCamKey); #endif CLONE_OPTION(TheText.Get("FED_SUB"), MENUACTION_SUBTITLES, nil, nil); @@ -433,24 +428,96 @@ CustomFrontendOptionsPopulate(void) #endif ADD_RESTORE_DEFAULTS(RestoreDefDisplay) - ADD_BACK + ADD_BACK #ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS - int detectJoystickMenu = FrontendScreenAdd("FET_CON", MENUSPRITE_MAINMENU, MENUPAGE_CONTROLLER_PC, 50, 60, 20, + int detectJoystickMenu = FrontendScreenAdd("FEC_JOD", MENUSPRITE_MAINMENU, MENUPAGE_CONTROLLER_PC, 40, 60, 20, FONT_BANK, MEDIUMTEXT_X_SCALE, MEDIUMTEXT_Y_SCALE, FESCREEN_LEFT_ALIGN, false); FrontendOptionSetCursor(detectJoystickMenu, 0); - FrontendOptionAddBuiltinAction(detectJoystickExplanation, MENUACTION_LABEL, nil, nil); - FrontendOptionAddDynamic(detectedJoystickText, DetectJoystickDraw, nil, nil, nil); + FrontendOptionAddBuiltinAction(TheText.Get("FEC_JPR"), MENUACTION_LABEL, nil, nil); + FrontendOptionAddDynamic(TheText.Get("FEC_JDE"), DetectJoystickDraw, nil, nil, nil); FrontendOptionAddBackButton(TheText.Get("FEDS_TB")); FrontendOptionSetCursor(MENUPAGE_CONTROLLER_PC, 2); - FrontendOptionAddRedirect(detectJoystickText, detectJoystickMenu, 1); + FrontendOptionAddRedirect(TheText.Get("FEC_JOD"), detectJoystickMenu, 1); #endif } #endif +#ifdef LOAD_INI_SETTINGS +#include "ini_parser.hpp" +void LoadINISettings() +{ + linb::ini cfg; + cfg.load_file("re3.ini"); + char defaultStr[4]; + +#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS + strcpy(gSelectedJoystickName, cfg.get("DetectJoystick", "JoystickName", "").c_str()); + _InputInitialiseJoys(); +#endif + +#ifdef CUSTOM_FRONTEND_OPTIONS + for (int i = 0; i < numCustomFrontendOptions; i++) { + FrontendOption& option = customFrontendOptions[i]; + if (option.save) { + // CFO only supports saving uint8 right now + sprintf(defaultStr, "%u", *option.value); + option.lastSavedValue = option.displayedValue = *option.value = atoi(cfg.get("FrontendOptions", option.save, defaultStr).c_str()); + } + } +#endif + +#ifdef NO_ISLAND_LOADING + sprintf(defaultStr, "%u", CMenuManager::m_PrefsIslandLoading); + CMenuManager::m_PrefsIslandLoading = atoi(cfg.get("FrontendOptions", "NoIslandLoading", defaultStr).c_str()); + CMenuManager::m_DisplayIslandLoading = CMenuManager::m_PrefsIslandLoading; +#endif + +} + +void SaveINISettings() +{ + linb::ini cfg; + cfg.load_file("re3.ini"); + bool changed = false; + char temp[4]; + +#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS + if (strncmp(cfg.get("DetectJoystick", "JoystickName", "").c_str(), gSelectedJoystickName, strlen(gSelectedJoystickName)) != 0) { + changed = true; + cfg.set("DetectJoystick", "JoystickName", gSelectedJoystickName); + } +#endif +#ifdef CUSTOM_FRONTEND_OPTIONS + for (int i = 0; i < numCustomFrontendOptions; i++) { + FrontendOption &option = customFrontendOptions[i]; + if (option.save) { + if (atoi(cfg.get("FrontendOptions", option.save, "xxx").c_str()) != *option.value) { // if .ini doesn't have that key compare with xxx, so we can add it + changed = true; + sprintf(temp, "%u", *option.value); + cfg.set("FrontendOptions", option.save, temp); + } + } + } +#endif +#ifdef NO_ISLAND_LOADING + if (atoi(cfg.get("FrontendOptions", "NoIslandLoading", "xxx").c_str()) != CMenuManager::m_PrefsIslandLoading) { + changed = true; + sprintf(temp, "%u", CMenuManager::m_PrefsIslandLoading); + cfg.set("FrontendOptions", "NoIslandLoading", temp); + } +#endif + + if (changed) + cfg.write_file("re3.ini"); +} + +#endif + + #ifdef DEBUGMENU void WeaponCheat(); void HealthCheat(); @@ -598,6 +665,8 @@ static const char *carnames[] = { "yankee", "escape", "borgnine", "toyz", "ghost", }; +//#include + static CTweakVar** TweakVarsList; static int TweakVarsListSize = -1; static bool bAddTweakVarsNow = false; -- cgit v1.2.3 From 0ac2be00934ce3789d87ce4efb8b991f308de521 Mon Sep 17 00:00:00 2001 From: Filip Gawin Date: Sat, 3 Oct 2020 16:17:24 +0200 Subject: Fix unsigned comparison in CStreaming::MakeSpaceFor(int32 size) --- src/core/Streaming.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'src/core') diff --git a/src/core/Streaming.cpp b/src/core/Streaming.cpp index 507815fa..4e12ab6d 100644 --- a/src/core/Streaming.cpp +++ b/src/core/Streaming.cpp @@ -2436,12 +2436,17 @@ CStreaming::DeleteRwObjectsNotInFrustumInSectorList(CPtrList &list, size_t mem) void CStreaming::MakeSpaceFor(int32 size) { - // BUG: ms_memoryAvailable can be uninitialized - // the code still happens to work in that case because ms_memoryAvailable is unsigned - // but it's not nice.... - +#ifdef FIX_BUGS +#define MB (1024 * 1024) + if(ms_memoryAvailable == 0) { + extern size_t _dwMemAvailPhys; + ms_memoryAvailable = (_dwMemAvailPhys - 10 * MB) / 2; + if(ms_memoryAvailable < 50 * MB) ms_memoryAvailable = 50 * MB; + } +#undef MB +#endif while(ms_memoryUsed >= ms_memoryAvailable - size) - if(!RemoveLeastUsedModel()){ + if(!RemoveLeastUsedModel()) { DeleteRwObjectsBehindCamera(ms_memoryAvailable - size); return; } -- cgit v1.2.3 From 8c170a62ee5960bcb752630807101efd67d76e00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?eray=20or=C3=A7unus?= Date: Sun, 4 Oct 2020 22:39:54 +0300 Subject: Fix some sanitizer errors, improve POSIX streamer --- src/core/CdStreamPosix.cpp | 288 ++++++++++++++++++++++++--------------------- src/core/FileLoader.cpp | 4 + src/core/FileMgr.cpp | 10 +- src/core/Streaming.cpp | 120 +++++++++++++++++++ src/core/common.h | 2 +- 5 files changed, 281 insertions(+), 143 deletions(-) (limited to 'src/core') diff --git a/src/core/CdStreamPosix.cpp b/src/core/CdStreamPosix.cpp index 40000f03..04a5de4b 100644 --- a/src/core/CdStreamPosix.cpp +++ b/src/core/CdStreamPosix.cpp @@ -34,9 +34,9 @@ struct CdReadInfo bool bReading; int32 nStatus; #ifdef ONE_THREAD_PER_CHANNEL - int8 nThreadStatus; // 0: created 1:initalized 2:abort now - pthread_t pChannelThread; - sem_t *pStartSemaphore; + int8 nThreadStatus; // 0: created 1:priority set up 2:abort now + pthread_t pChannelThread; + sem_t *pStartSemaphore; #endif sem_t *pDoneSemaphore; // used for CdStreamSync int32 hFile; @@ -52,7 +52,7 @@ char *gImgNames[MAX_CDIMAGES]; #ifndef ONE_THREAD_PER_CHANNEL pthread_t _gCdStreamThread; sem_t *gCdStreamSema; // released when we have new thing to read(so channel is set) -int8 gCdStreamThreadStatus; // 0: created 1:initalized 2:abort now +int8 gCdStreamThreadStatus; // 0: created 1:priority set up 2:abort now Queue gChannelRequestQ; bool _gbCdStreamOverlapped; #endif @@ -69,15 +69,14 @@ void CdStreamInitThread(void) { int status; - + char semName[20]; #ifndef ONE_THREAD_PER_CHANNEL gChannelRequestQ.items = (int32 *)calloc(gNumChannels + 1, sizeof(int32)); gChannelRequestQ.head = 0; gChannelRequestQ.tail = 0; gChannelRequestQ.size = gNumChannels + 1; ASSERT(gChannelRequestQ.items != nil ); - gCdStreamSema = sem_open("/semaphore_cd_stream", O_CREAT, 0644, 1); -#endif + gCdStreamSema = sem_open("/semaphore_cd_stream", O_CREAT, 0644, 1); if (gCdStreamSema == SEM_FAILED) { @@ -85,33 +84,35 @@ CdStreamInitThread(void) ASSERT(0); return; } - +#endif if ( gNumChannels > 0 ) { for ( int32 i = 0; i < gNumChannels; i++ ) { - gpReadInfo[i].pDoneSemaphore = sem_open("/semaphore_done", O_CREAT, 0644, 1); + sprintf(semName,"/semaphore_done%d",i); + gpReadInfo[i].pDoneSemaphore = sem_open(semName, O_CREAT, 0644, 1); - if (gpReadInfo[i].pDoneSemaphore == SEM_FAILED) + if (gpReadInfo[i].pDoneSemaphore == SEM_FAILED) { CDTRACE("failed to create sync semaphore"); ASSERT(0); return; } #ifdef ONE_THREAD_PER_CHANNEL - gpReadInfo[i].pStartSemaphore = sem_open("/semaphore_start", O_CREAT, 0644, 1); + sprintf(semName,"/semaphore_start%d",i); + gpReadInfo[i].pStartSemaphore = sem_open(semName, O_CREAT, 0644, 1); - if (gpReadInfo[i].pStartSemaphore == SEM_FAILED) + if (gpReadInfo[i].pStartSemaphore == SEM_FAILED) { CDTRACE("failed to create start semaphore"); ASSERT(0); return; } - gpReadInfo[i].nThreadStatus = 0; + gpReadInfo[i].nThreadStatus = 0; int *channelI = (int*)malloc(sizeof(int)); *channelI = i; - status = pthread_create(&gpReadInfo[i].pChannelThread, NULL, CdStreamThread, (void*)channelI); + status = pthread_create(&gpReadInfo[i].pChannelThread, NULL, CdStreamThread, (void*)channelI); if (status == -1) { @@ -124,32 +125,32 @@ CdStreamInitThread(void) } #ifndef ONE_THREAD_PER_CHANNEL - debug("Using one streaming thread for all channels\n"); - status = pthread_create(&_gCdStreamThread, NULL, CdStreamThread, nil); - gCdStreamThreadStatus = 0; - - if (status == -1) - { - CDTRACE("failed to create sync thread"); - ASSERT(0); - return; - } + debug("Using one streaming thread for all channels\n"); + gCdStreamThreadStatus = 0; + status = pthread_create(&_gCdStreamThread, NULL, CdStreamThread, nil); + + if (status == -1) + { + CDTRACE("failed to create sync thread"); + ASSERT(0); + return; + } #else - debug("Using separate streaming threads for each channel\n"); + debug("Using separate streaming threads for each channel\n"); #endif } void CdStreamInit(int32 numChannels) { - struct statvfs fsInfo; - - if((statvfs("models/gta3.img", &fsInfo)) < 0) - { - CDTRACE("can't get filesystem info"); - ASSERT(0); - return; - } + struct statvfs fsInfo; + + if((statvfs("models/gta3.img", &fsInfo)) < 0) + { + CDTRACE("can't get filesystem info"); + ASSERT(0); + return; + } #ifdef __linux__ _gdwCdStreamFlags = O_RDONLY | O_NOATIME; #else @@ -185,26 +186,26 @@ uint32 GetGTA3ImgSize(void) { ASSERT( gImgFiles[0] > 0 ); - struct stat statbuf; + struct stat statbuf; - char path[PATH_MAX]; - realpath(gImgNames[0], path); - if (stat(path, &statbuf) == -1) { + char path[PATH_MAX]; + realpath(gImgNames[0], path); + if (stat(path, &statbuf) == -1) { // Try case-insensitivity char* real = casepath(gImgNames[0], false); if (real) { realpath(real, path); free(real); - if (stat(path, &statbuf) != -1) + if (stat(path, &statbuf) != -1) goto ok; } - CDTRACE("can't get size of gta3.img"); - ASSERT(0); - return 0; - } -ok: + CDTRACE("can't get size of gta3.img"); + ASSERT(0); + return 0; + } + ok: return (uint32)statbuf.st_size; } @@ -213,15 +214,13 @@ CdStreamShutdown(void) { // Destroying semaphores and free(gpReadInfo) will be done at threads #ifndef ONE_THREAD_PER_CHANNEL - gCdStreamThreadStatus = 2; - sem_post(gCdStreamSema); -#endif - -#ifdef ONE_THREAD_PER_CHANNEL - for ( int32 i = 0; i < gNumChannels; i++ ) { - gpReadInfo[i].nThreadStatus = 2; - sem_post(&gpReadInfo[i].pStartSemaphore); - } + gCdStreamThreadStatus = 2; + sem_post(gCdStreamSema); +#else + for ( int32 i = 0; i < gNumChannels; i++ ) { + gpReadInfo[i].nThreadStatus = 2; + sem_post(gpReadInfo[i].pStartSemaphore); + } #endif } @@ -243,25 +242,28 @@ CdStreamRead(int32 channel, void *buffer, uint32 offset, uint32 size) pChannel->hFile = hImage - 1; - if ( pChannel->nSectorsToRead != 0 || pChannel->bReading ) - return STREAM_NONE; + if ( pChannel->nSectorsToRead != 0 || pChannel->bReading ) { + flushStream[channel] = 1; + CdStreamSync(channel); + //return STREAM_NONE; + } - pChannel->nStatus = STREAM_NONE; - pChannel->nSectorOffset = _GET_OFFSET(offset); - pChannel->nSectorsToRead = size; - pChannel->pBuffer = buffer; - pChannel->bLocked = 0; + pChannel->nStatus = STREAM_NONE; + pChannel->nSectorOffset = _GET_OFFSET(offset); + pChannel->nSectorsToRead = size; + pChannel->pBuffer = buffer; + pChannel->bLocked = 0; #ifndef ONE_THREAD_PER_CHANNEL - AddToQueue(&gChannelRequestQ, channel); - if ( sem_post(gCdStreamSema) != 0 ) - printf("Signal Sema Error\n"); + AddToQueue(&gChannelRequestQ, channel); + if ( sem_post(gCdStreamSema) != 0 ) + printf("Signal Sema Error\n"); #else - if ( sem_post(&gpReadInfo[channel].pStartSemaphore) != 0 ) - printf("Signal Sema Error\n"); + if ( sem_post(pChannel->pStartSemaphore) != 0 ) + printf("Signal Sema Error\n"); #endif - return STREAM_SUCCESS; + return STREAM_SUCCESS; } int32 @@ -272,29 +274,29 @@ CdStreamGetStatus(int32 channel) ASSERT( pChannel != nil ); #ifdef ONE_THREAD_PER_CHANNEL - if (pChannel->nThreadStatus == 2) - return STREAM_NONE; + if (pChannel->nThreadStatus == 2) + return STREAM_NONE; #else - if (gCdStreamThreadStatus == 2) - return STREAM_NONE; + if (gCdStreamThreadStatus == 2) + return STREAM_NONE; #endif - if ( pChannel->bReading ) - return STREAM_READING; + if ( pChannel->bReading ) + return STREAM_READING; - if ( pChannel->nSectorsToRead != 0 ) - return STREAM_WAITING; + if ( pChannel->nSectorsToRead != 0 ) + return STREAM_WAITING; - if ( pChannel->nStatus != STREAM_NONE ) - { - int32 status = pChannel->nStatus; + if ( pChannel->nStatus != STREAM_NONE ) + { + int32 status = pChannel->nStatus; - pChannel->nStatus = STREAM_NONE; + pChannel->nStatus = STREAM_NONE; - return status; - } + return status; + } - return STREAM_NONE; + return STREAM_NONE; } int32 @@ -314,30 +316,34 @@ CdStreamSync(int32 channel) if (flushStream[channel]) { #ifdef ONE_THREAD_PER_CHANNEL pChannel->nSectorsToRead = 0; - pthread_kill(gpReadInfo[channel].pChannelThread, SIGINT); + pthread_kill(pChannel->pChannelThread, SIGINT); + if (pChannel->bReading) { + pChannel->bLocked = true; + sem_wait(pChannel->pDoneSemaphore); + } #else + pChannel->nSectorsToRead = 0; if (pChannel->bReading) { - pChannel->nSectorsToRead = 0; + pChannel->bLocked = true; pthread_kill(_gCdStreamThread, SIGINT); - } else { - pChannel->nSectorsToRead = 0; + sem_wait(pChannel->pDoneSemaphore); } #endif pChannel->bReading = false; flushStream[channel] = false; - return STREAM_NONE; + return STREAM_NONE; } - if ( pChannel->nSectorsToRead != 0 ) - { - pChannel->bLocked = true; + if ( pChannel->nSectorsToRead != 0 ) + { + pChannel->bLocked = true; - sem_wait(pChannel->pDoneSemaphore); - } + sem_wait(pChannel->pDoneSemaphore); + } - pChannel->bReading = false; + pChannel->bReading = false; - return pChannel->nStatus; + return pChannel->nStatus; } void @@ -382,53 +388,52 @@ void *CdStreamThread(void *param) debug("Created cdstream thread\n"); #ifndef ONE_THREAD_PER_CHANNEL - while (gCdStreamThreadStatus != 2) { + while (gCdStreamThreadStatus != 2) { sem_wait(gCdStreamSema); - int32 channel = GetFirstInQueue(&gChannelRequestQ); + int32 channel = GetFirstInQueue(&gChannelRequestQ); #else - int channel = *((int*)param); - while (gpReadInfo[channel].nThreadStatus != 2){ - sem_wait(&gpReadInfo[channel].pStartSemaphore); + int channel = *((int*)param); + while (gpReadInfo[channel].nThreadStatus != 2){ + sem_wait(gpReadInfo[channel].pStartSemaphore); #endif - ASSERT( channel < gNumChannels ); CdReadInfo *pChannel = &gpReadInfo[channel]; ASSERT( pChannel != nil ); -#ifdef ONE_THREAD_PER_CHANNEL - if (gpReadInfo[channel].nThreadStatus == 0){ - gpReadInfo[channel].nThreadStatus = 1; -#else - if (gCdStreamThreadStatus == 0){ - gCdStreamThreadStatus = 1; -#endif - -#ifdef __linux__ - pid_t tid = syscall(SYS_gettid); - int ret = setpriority(PRIO_PROCESS, tid, getpriority(PRIO_PROCESS, getpid()) + 1); -#endif - } - // spurious wakeup or we sent interrupt signal for flushing if(pChannel->nSectorsToRead == 0) - continue; + continue; pChannel->bReading = true; + // Not standard POSIX :shrug: +#ifdef __linux__ +#ifdef ONE_THREAD_PER_CHANNEL + if (gpReadInfo[channel].nThreadStatus == 0){ + gpReadInfo[channel].nThreadStatus = 1; +#else + if (gCdStreamThreadStatus == 0){ + gCdStreamThreadStatus = 1; +#endif + pid_t tid = syscall(SYS_gettid); + int ret = setpriority(PRIO_PROCESS, tid, getpriority(PRIO_PROCESS, getpid()) + 1); + } +#endif if ( pChannel->nStatus == STREAM_NONE ) { - ASSERT(pChannel->hFile >= 0); - ASSERT(pChannel->pBuffer != nil ); + ASSERT(pChannel->hFile >= 0); + ASSERT(pChannel->pBuffer != nil ); lseek(pChannel->hFile, pChannel->nSectorOffset * CDSTREAM_SECTOR_SIZE, SEEK_SET); - if (read(pChannel->hFile, pChannel->pBuffer, pChannel->nSectorsToRead * CDSTREAM_SECTOR_SIZE) == -1) { + if (read(pChannel->hFile, pChannel->pBuffer, pChannel->nSectorsToRead * CDSTREAM_SECTOR_SIZE) == -1) { // pChannel->nSectorsToRead == 0 at this point means we wanted to flush channel - pChannel->nStatus = pChannel->nSectorsToRead == 0 ? STREAM_NONE : STREAM_ERROR; - } else { - pChannel->nStatus = STREAM_NONE; - } + // STREAM_WAITING is a little hack to make CStreaming not process this data + pChannel->nStatus = pChannel->nSectorsToRead == 0 ? STREAM_WAITING : STREAM_ERROR; + } else { + pChannel->nStatus = STREAM_NONE; + } } - + #ifndef ONE_THREAD_PER_CHANNEL RemoveFirstInQueue(&gChannelRequestQ); #endif @@ -437,26 +442,33 @@ void *CdStreamThread(void *param) if ( pChannel->bLocked ) { - sem_post(pChannel->pDoneSemaphore); + sem_post(pChannel->pDoneSemaphore); } pChannel->bReading = false; } + char semName[20]; #ifndef ONE_THREAD_PER_CHANNEL - for ( int32 i = 0; i < gNumChannels; i++ ) - { - sem_close(gpReadInfo[i].pDoneSemaphore); - sem_unlink("/semaphore_done"); - } - sem_close(gCdStreamSema); - sem_unlink("/semaphore_cd_stream"); - free(gChannelRequestQ.items); + for ( int32 i = 0; i < gNumChannels; i++ ) + { + sem_close(gpReadInfo[i].pDoneSemaphore); + sprintf(semName,"/semaphore_done%d",i); + sem_unlink(semName); + } + sem_close(gCdStreamSema); + sem_unlink("/semaphore_cd_stream"); + free(gChannelRequestQ.items); #else - sem_close(gpReadInfo[channel].pStartSemaphore); - sem_unlink("/semaphore_start"); - sem_close(gpReadInfo[channel].pDoneSemaphore); - sem_unlink("/semaphore_done"); + sem_close(gpReadInfo[channel].pStartSemaphore); + sprintf(semName,"/semaphore_start%d",channel); + sem_unlink(semName); + + sem_close(gpReadInfo[channel].pDoneSemaphore); + sprintf(semName,"/semaphore_done%d",channel); + sem_unlink(semName); #endif - free(gpReadInfo); + if (gpReadInfo) + free(gpReadInfo); + gpReadInfo = nil; pthread_exit(nil); } @@ -473,7 +485,7 @@ CdStreamAddImage(char const *path) char* real = casepath(path, false); if (real) { - gImgFiles[gNumImages] = open(real, _gdwCdStreamFlags); + gImgFiles[gNumImages] = open(real, _gdwCdStreamFlags); free(real); } } @@ -506,8 +518,10 @@ CdStreamGetImageName(int32 cd) void CdStreamRemoveImages(void) { - for ( int32 i = 0; i < gNumChannels; i++ ) + for ( int32 i = 0; i < gNumChannels; i++ ) { + flushStream[i] = 1; CdStreamSync(i); + } for ( int32 i = 0; i < gNumImages; i++ ) { diff --git a/src/core/FileLoader.cpp b/src/core/FileLoader.cpp index b4da1a5e..ff50575f 100644 --- a/src/core/FileLoader.cpp +++ b/src/core/FileLoader.cpp @@ -980,7 +980,11 @@ CFileLoader::Load2dEffect(const char *line) &effect->attractor.dir.z, &probability); effect->attractor.type = flags; +#ifdef FIX_BUGS + effect->attractor.probability = clamp(probability, 0, 255); +#else effect->attractor.probability = probability; +#endif break; } diff --git a/src/core/FileMgr.cpp b/src/core/FileMgr.cpp index ac51f8de..6e6a8efc 100644 --- a/src/core/FileMgr.cpp +++ b/src/core/FileMgr.cpp @@ -142,17 +142,17 @@ static size_t myfread(void *buf, size_t elt, size_t n, int fd) { if(myfiles[fd].isText){ - char *p; + unsigned char *p; size_t i; int c; n *= elt; - p = (char*)buf; + p = (unsigned char*)buf; for(i = 0; i < n; i++){ c = myfgetc(fd); if(c == EOF) break; - *p++ = c; + *p++ = (unsigned char)c; } return i / elt; } @@ -163,12 +163,12 @@ static size_t myfwrite(void *buf, size_t elt, size_t n, int fd) { if(myfiles[fd].isText){ - char *p; + unsigned char *p; size_t i; int c; n *= elt; - p = (char*)buf; + p = (unsigned char*)buf; for(i = 0; i < n; i++){ c = *p++; myfputc(c, fd); diff --git a/src/core/Streaming.cpp b/src/core/Streaming.cpp index 507815fa..4d14ff63 100644 --- a/src/core/Streaming.cpp +++ b/src/core/Streaming.cpp @@ -45,7 +45,11 @@ CStreamingInfo CStreaming::ms_endRequestedList; int32 CStreaming::ms_oldSectorX; int32 CStreaming::ms_oldSectorY; int32 CStreaming::ms_streamingBufferSize; +#ifndef ONE_THREAD_PER_CHANNEL int8 *CStreaming::ms_pStreamingBuffer[2]; +#else +int8 *CStreaming::ms_pStreamingBuffer[4]; +#endif size_t CStreaming::ms_memoryUsed; CStreamingChannel CStreaming::ms_channel[2]; int32 CStreaming::ms_channelError; @@ -198,6 +202,10 @@ CStreaming::Init2(void) ms_pStreamingBuffer[0] = (int8*)RwMallocAlign(ms_streamingBufferSize*CDSTREAM_SECTOR_SIZE, CDSTREAM_SECTOR_SIZE); ms_streamingBufferSize /= 2; ms_pStreamingBuffer[1] = ms_pStreamingBuffer[0] + ms_streamingBufferSize*CDSTREAM_SECTOR_SIZE; +#ifdef ONE_THREAD_PER_CHANNEL + ms_pStreamingBuffer[2] = (int8*)RwMallocAlign(ms_streamingBufferSize*2*CDSTREAM_SECTOR_SIZE, CDSTREAM_SECTOR_SIZE); + ms_pStreamingBuffer[3] = ms_pStreamingBuffer[2] + ms_streamingBufferSize*CDSTREAM_SECTOR_SIZE; +#endif debug("Streaming buffer size is %d sectors", ms_streamingBufferSize); // PC only, figure out how much memory we got @@ -1831,6 +1839,109 @@ CStreaming::LoadRequestedModels(void) } } + +// Let's load models first, then process it. Unfortunately processing models are still single-threaded. +// Currently only supported on POSIX streamer. +#ifdef ONE_THREAD_PER_CHANNEL +void +CStreaming::LoadAllRequestedModels(bool priority) +{ + static bool bInsideLoadAll = false; + int imgOffset, streamId, status; + int i; + uint32 posn, size; + + if(bInsideLoadAll) + return; + + FlushChannels(); + imgOffset = GetCdImageOffset(CdStreamGetLastPosn()); + + int streamIds[ARRAY_SIZE(ms_pStreamingBuffer)]; + int streamSizes[ARRAY_SIZE(ms_pStreamingBuffer)]; + int streamPoses[ARRAY_SIZE(ms_pStreamingBuffer)]; + bool first = true; + int processI = 0; + + while (true) { + // Enumerate files and start reading + for (int i=0; i (uint32)ms_streamingBufferSize) { + if (i + 1 == ARRAY_SIZE(ms_pStreamingBuffer)) + continue; + else if (!first && streamIds[i+1] != -1) + continue; + } else { + if (i != 0 && streamIds[i-1] != -1 && streamSizes[i-1] > (uint32)ms_streamingBufferSize) + continue; + } + ms_aInfoForModel[streamId].RemoveFromList(); + DecrementRef(streamId); + + streamIds[i] = streamId; + streamSizes[i] = size; + streamPoses[i] = posn; + CdStreamRead(i, ms_pStreamingBuffer[i], imgOffset+posn, size); + processI = i; + } else { + ms_aInfoForModel[streamId].RemoveFromList(); + DecrementRef(streamId); + + ms_aInfoForModel[streamId].m_loadState = STREAMSTATE_LOADED; + streamIds[i] = -1; + } + } else + streamIds[i] = -1; + } + + first = false; + + // Now process + if (streamIds[processI] == -1) + break; + + // Try again on error + while (CdStreamSync(processI) != STREAM_NONE) { + CdStreamRead(processI, ms_pStreamingBuffer[processI], imgOffset+streamPoses[processI], streamSizes[processI]); + } + ms_aInfoForModel[streamIds[processI]].m_loadState = STREAMSTATE_READING; + + MakeSpaceFor(streamSizes[processI] * CDSTREAM_SECTOR_SIZE); + ConvertBufferToObject(ms_pStreamingBuffer[processI], streamIds[processI]); + if(ms_aInfoForModel[streamIds[processI]].m_loadState == STREAMSTATE_STARTED) + FinishLoadingLargeFile(ms_pStreamingBuffer[processI], streamIds[processI]); + + if(streamIds[processI] < STREAM_OFFSET_TXD){ + CSimpleModelInfo *mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(streamIds[processI]); + if(mi->IsSimple()) + mi->m_alpha = 255; + } + streamIds[processI] = -1; + } + + ms_bLoadingBigModel = false; + for(i = 0; i < 4; i++){ + ms_channel[1].streamIds[i] = -1; + ms_channel[1].offsets[i] = -1; + } + ms_channel[1].state = CHANNELSTATE_IDLE; + bInsideLoadAll = false; +} +#else void CStreaming::LoadAllRequestedModels(bool priority) { @@ -1883,6 +1994,7 @@ CStreaming::LoadAllRequestedModels(bool priority) ms_channel[1].state = CHANNELSTATE_IDLE; bInsideLoadAll = false; } +#endif void CStreaming::FlushChannels(void) @@ -1914,6 +2026,14 @@ CStreaming::FlushRequestList(void) next = si->m_next; RemoveModel(si - ms_aInfoForModel); } +#ifndef _WIN32 + if(ms_channel[0].state == CHANNELSTATE_READING) { + flushStream[0] = 1; + } + if(ms_channel[1].state == CHANNELSTATE_READING) { + flushStream[1] = 1; + } +#endif FlushChannels(); } diff --git a/src/core/common.h b/src/core/common.h index ef3da265..48b20884 100644 --- a/src/core/common.h +++ b/src/core/common.h @@ -106,7 +106,7 @@ typedef uint16_t wchar; inline uint32 dpb(uint32 b, uint32 p, uint32 s, uint32 w) { uint32 m = MASK(p,s); - return w & ~m | b<

Date: Fri, 9 Oct 2020 02:19:49 +0300 Subject: Fix POSIX streaming --- src/core/CdStreamPosix.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src/core') diff --git a/src/core/CdStreamPosix.cpp b/src/core/CdStreamPosix.cpp index 04a5de4b..a6ab62bc 100644 --- a/src/core/CdStreamPosix.cpp +++ b/src/core/CdStreamPosix.cpp @@ -240,14 +240,17 @@ CdStreamRead(int32 channel, void *buffer, uint32 offset, uint32 size) CdReadInfo *pChannel = &gpReadInfo[channel]; ASSERT( pChannel != nil ); - pChannel->hFile = hImage - 1; if ( pChannel->nSectorsToRead != 0 || pChannel->bReading ) { + if (pChannel->nSectorOffset == _GET_OFFSET(offset) && pChannel->nSectorsToRead >= size) + return STREAM_SUCCESS; + flushStream[channel] = 1; CdStreamSync(channel); //return STREAM_NONE; } + pChannel->hFile = hImage - 1; pChannel->nStatus = STREAM_NONE; pChannel->nSectorOffset = _GET_OFFSET(offset); pChannel->nSectorsToRead = size; @@ -316,7 +319,7 @@ CdStreamSync(int32 channel) if (flushStream[channel]) { #ifdef ONE_THREAD_PER_CHANNEL pChannel->nSectorsToRead = 0; - pthread_kill(pChannel->pChannelThread, SIGINT); + pthread_kill(pChannel->pChannelThread, SIGUSR1); if (pChannel->bReading) { pChannel->bLocked = true; sem_wait(pChannel->pDoneSemaphore); @@ -325,8 +328,9 @@ CdStreamSync(int32 channel) pChannel->nSectorsToRead = 0; if (pChannel->bReading) { pChannel->bLocked = true; - pthread_kill(_gCdStreamThread, SIGINT); + pthread_kill(_gCdStreamThread, SIGUSR1); sem_wait(pChannel->pDoneSemaphore); + } #endif pChannel->bReading = false; -- cgit v1.2.3