Decrease memory stats in cellGemInit if needed

Also:
* fix state reset of cellGem
* Check max_connect == 0 in cellGemInit
This commit is contained in:
Eladash 2019-09-21 13:25:53 +03:00 committed by Megamouse
parent d91f8193b0
commit 3b06214f88

View File

@ -106,6 +106,7 @@ struct gem_config
u32 connected_controllers;
bool update_started{};
u32 camera_frame{};
u32 memory_ptr{};
shared_mutex mtx;
@ -191,7 +192,7 @@ static bool check_gem_num(const u32 gem_num)
*/
static bool map_to_ds3_input(const u32 port_no, be_t<u16>& digital_buttons, be_t<u16>& analog_t)
{
std::lock_guard lock(pad::g_pad_mutex);
std::scoped_lock lock(pad::g_pad_mutex);
const auto handler = pad::get_current_handler();
@ -279,7 +280,7 @@ static bool map_to_ds3_input(const u32 port_no, be_t<u16>& digital_buttons, be_t
*/
static bool map_ext_to_ds3_input(const u32 port_no, CellGemExtPortData& ext)
{
std::lock_guard lock(pad::g_pad_mutex);
std::scoped_lock lock(pad::g_pad_mutex);
const auto handler = pad::get_current_handler();
@ -313,6 +314,8 @@ error_code cellGemCalibrate(u32 gem_num)
const auto gem = g_fxo->get<gem_config>();
std::scoped_lock lock(gem->mtx);
if (!gem->state)
{
return CELL_GEM_ERROR_UNINITIALIZED;
@ -338,6 +341,8 @@ error_code cellGemClearStatusFlags(u32 gem_num, u64 mask)
const auto gem = g_fxo->get<gem_config>();
std::scoped_lock lock(gem->mtx);
if (!gem->state)
{
return CELL_GEM_ERROR_UNINITIALIZED;
@ -387,6 +392,8 @@ error_code cellGemEnableCameraPitchAngleCorrection(u32 enable_flag)
const auto gem = g_fxo->get<gem_config>();
std::scoped_lock lock(gem->mtx);
if (!gem->state)
{
return CELL_GEM_ERROR_UNINITIALIZED;
@ -403,6 +410,8 @@ error_code cellGemEnableMagnetometer(u32 gem_num, u32 enable)
const auto gem = g_fxo->get<gem_config>();
std::scoped_lock lock(gem->mtx);
if (!gem->state)
{
return CELL_GEM_ERROR_UNINITIALIZED;
@ -430,12 +439,19 @@ error_code cellGemEnd()
const auto gem = g_fxo->get<gem_config>();
if (!gem->state.compare_and_swap_test(1, 0))
std::scoped_lock lock(gem->mtx);
if (gem->state.compare_and_swap_test(1, 0))
{
return CELL_GEM_ERROR_UNINITIALIZED;
if (u32 addr = gem->memory_ptr)
{
sys_memory_free(addr);
}
return CELL_OK;
}
return CELL_OK;
return CELL_GEM_ERROR_UNINITIALIZED;
}
error_code cellGemFilterState(u32 gem_num, u32 enable)
@ -444,6 +460,8 @@ error_code cellGemFilterState(u32 gem_num, u32 enable)
const auto gem = g_fxo->get<gem_config>();
std::scoped_lock lock(gem->mtx);
if (!gem->state)
{
return CELL_GEM_ERROR_UNINITIALIZED;
@ -465,6 +483,8 @@ error_code cellGemForceRGB(u32 gem_num, float r, float g, float b)
const auto gem = g_fxo->get<gem_config>();
std::scoped_lock lock(gem->mtx);
if (!gem->state)
{
return CELL_GEM_ERROR_UNINITIALIZED;
@ -612,6 +632,8 @@ error_code cellGemGetInertialState(u32 gem_num, u32 state_flag, u64 timestamp, v
const auto gem = g_fxo->get<gem_config>();
std::scoped_lock lock(gem->mtx);
if (!gem->state)
{
return CELL_GEM_ERROR_UNINITIALIZED;
@ -643,6 +665,8 @@ error_code cellGemGetInfo(vm::ptr<CellGemInfo> info)
const auto gem = g_fxo->get<gem_config>();
std::shared_lock lock(gem->mtx);
if (!gem->state)
{
return CELL_GEM_ERROR_UNINITIALIZED;
@ -666,6 +690,11 @@ error_code cellGemGetInfo(vm::ptr<CellGemInfo> info)
return CELL_OK;
}
u32 GemGetMemorySize(s32 max_connect)
{
return max_connect <= 2 ? 0x120000 : 0x140000;
}
error_code cellGemGetMemorySize(s32 max_connect)
{
cellGem.warning("cellGemGetMemorySize(max_connect=%d)", max_connect);
@ -675,7 +704,7 @@ error_code cellGemGetMemorySize(s32 max_connect)
return CELL_GEM_ERROR_INVALID_PARAMETER;
}
return not_an_error(max_connect <= 2 ? 0x120000 : 0x140000);
return not_an_error(GemGetMemorySize(max_connect));
}
error_code cellGemGetRGB(u32 gem_num, vm::ptr<float> r, vm::ptr<float> g, vm::ptr<float> b)
@ -684,6 +713,8 @@ error_code cellGemGetRGB(u32 gem_num, vm::ptr<float> r, vm::ptr<float> g, vm::pt
const auto gem = g_fxo->get<gem_config>();
std::shared_lock lock(gem->mtx);
if (!gem->state)
{
return CELL_GEM_ERROR_UNINITIALIZED;
@ -708,6 +739,8 @@ error_code cellGemGetRumble(u32 gem_num, vm::ptr<u8> rumble)
const auto gem = g_fxo->get<gem_config>();
std::shared_lock lock(gem->mtx);
if (!gem->state)
{
return CELL_GEM_ERROR_UNINITIALIZED;
@ -729,6 +762,8 @@ error_code cellGemGetState(u32 gem_num, u32 flag, u64 time_parameter, vm::ptr<Ce
const auto gem = g_fxo->get<gem_config>();
std::shared_lock lock(gem->mtx);
if (!gem->state)
{
return CELL_GEM_ERROR_UNINITIALIZED;
@ -760,6 +795,8 @@ error_code cellGemGetStatusFlags(u32 gem_num, vm::ptr<u64> flags)
const auto gem = g_fxo->get<gem_config>();
std::shared_lock lock(gem->mtx);
if (!gem->state)
{
return CELL_GEM_ERROR_UNINITIALIZED;
@ -781,6 +818,8 @@ error_code cellGemGetTrackerHue(u32 gem_num, vm::ptr<u32> hue)
const auto gem = g_fxo->get<gem_config>();
std::shared_lock lock(gem->mtx);
if (!gem->state)
{
return CELL_GEM_ERROR_UNINITIALIZED;
@ -823,19 +862,41 @@ error_code cellGemInit(vm::cptr<CellGemAttribute> attribute)
const auto gem = g_fxo->get<gem_config>();
if (!attribute || !attribute->spurs_addr || attribute->max_connect > CELL_GEM_MAX_NUM)
if (!attribute || !attribute->spurs_addr || !attribute->max_connect || attribute->max_connect > CELL_GEM_MAX_NUM)
{
return CELL_GEM_ERROR_INVALID_PARAMETER;
}
std::scoped_lock lock(gem->mtx);
if (!gem->state.compare_and_swap_test(0, 1))
{
return CELL_GEM_ERROR_ALREADY_INITIALIZED;
}
if (!attribute->memory_ptr)
{
vm::var<u32> addr(0);
// Decrease memory stats
if (sys_memory_allocate(GemGetMemorySize(attribute->max_connect), SYS_MEMORY_PAGE_SIZE_64K, +addr) != CELL_OK)
{
return CELL_GEM_ERROR_RESOURCE_ALLOCATION_FAILED;
}
gem->memory_ptr = *addr;
}
else
{
gem->memory_ptr = 0;
}
gem->update_started = false;
gem->camera_frame = 0;
gem->status_flags = 0;
gem->attribute = *attribute;
for (auto gem_num = 0; gem_num < CELL_GEM_MAX_NUM; gem_num++)
for (int gem_num = 0; gem_num < CELL_GEM_MAX_NUM; gem_num++)
{
gem->reset_controller(gem_num);
}
@ -852,6 +913,8 @@ error_code cellGemInvalidateCalibration(s32 gem_num)
const auto gem = g_fxo->get<gem_config>();
std::scoped_lock lock(gem->mtx);
if (!gem->state)
{
return CELL_GEM_ERROR_UNINITIALIZED;
@ -997,6 +1060,8 @@ error_code cellGemSetRumble(u32 gem_num, u8 rumble)
const auto gem = g_fxo->get<gem_config>();
std::scoped_lock lock(gem->mtx);
if (!gem->state)
{
return CELL_GEM_ERROR_UNINITIALIZED;
@ -1024,6 +1089,8 @@ error_code cellGemTrackHues(vm::cptr<u32> req_hues, vm::ptr<u32> res_hues)
const auto gem = g_fxo->get<gem_config>();
std::scoped_lock lock(gem->mtx);
if (!gem->state)
{
return CELL_GEM_ERROR_UNINITIALIZED;