cam: Ensure camera implementation is not null before using it (#7368)
* cam: Use PopEnum and update result names * cam: Make sure impl is not null before using it
This commit is contained in:
		@@ -10,7 +10,6 @@
 | 
			
		||||
#include "core/core.h"
 | 
			
		||||
#include "core/core_timing.h"
 | 
			
		||||
#include "core/frontend/camera/factory.h"
 | 
			
		||||
#include "core/hle/ipc.h"
 | 
			
		||||
#include "core/hle/ipc_helpers.h"
 | 
			
		||||
#include "core/hle/kernel/event.h"
 | 
			
		||||
#include "core/hle/kernel/process.h"
 | 
			
		||||
@@ -77,10 +76,10 @@ constexpr std::array<int, 13> LATENCY_BY_FRAME_RATE{{
 | 
			
		||||
    33,  // Rate_30_To_10
 | 
			
		||||
}};
 | 
			
		||||
 | 
			
		||||
const Result ERROR_INVALID_ENUM_VALUE(ErrorDescription::InvalidEnumValue, ErrorModule::CAM,
 | 
			
		||||
                                      ErrorSummary::InvalidArgument, ErrorLevel::Usage);
 | 
			
		||||
const Result ERROR_OUT_OF_RANGE(ErrorDescription::OutOfRange, ErrorModule::CAM,
 | 
			
		||||
                                ErrorSummary::InvalidArgument, ErrorLevel::Usage);
 | 
			
		||||
constexpr Result ResultInvalidEnumValue(ErrorDescription::InvalidEnumValue, ErrorModule::CAM,
 | 
			
		||||
                                        ErrorSummary::InvalidArgument, ErrorLevel::Usage);
 | 
			
		||||
constexpr Result ResultOutOfRange(ErrorDescription::OutOfRange, ErrorModule::CAM,
 | 
			
		||||
                                  ErrorSummary::InvalidArgument, ErrorLevel::Usage);
 | 
			
		||||
 | 
			
		||||
void Module::PortConfig::Clear() {
 | 
			
		||||
    completion_event->Clear();
 | 
			
		||||
@@ -261,27 +260,32 @@ void Module::Interface::StartCapture(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
 | 
			
		||||
    if (port_select.IsValid()) {
 | 
			
		||||
        for (int i : port_select) {
 | 
			
		||||
            if (!cam->ports[i].is_busy) {
 | 
			
		||||
                if (!cam->ports[i].is_active) {
 | 
			
		||||
                    // This doesn't return an error, but seems to put the camera in an undefined
 | 
			
		||||
                    // state
 | 
			
		||||
                    LOG_ERROR(Service_CAM, "port {} hasn't been activated", i);
 | 
			
		||||
                } else {
 | 
			
		||||
                    cam->cameras[cam->ports[i].camera_id].impl->StartCapture();
 | 
			
		||||
                    cam->ports[i].is_busy = true;
 | 
			
		||||
                    if (cam->ports[i].is_pending_receiving) {
 | 
			
		||||
                        cam->ports[i].is_pending_receiving = false;
 | 
			
		||||
                        cam->StartReceiving(i);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
            auto& port = cam->ports[i];
 | 
			
		||||
            if (port.is_busy) {
 | 
			
		||||
                LOG_WARNING(Service_CAM, "port {} already started", i);
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            if (!port.is_active) {
 | 
			
		||||
                // This doesn't return an error, but seems to put the camera in an undefined
 | 
			
		||||
                // state
 | 
			
		||||
                LOG_ERROR(Service_CAM, "port {} hasn't been activated", i);
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            auto& camera = cam->cameras[port.camera_id];
 | 
			
		||||
            if (!camera.impl) {
 | 
			
		||||
                cam->LoadCameraImplementation(camera, port.camera_id);
 | 
			
		||||
            }
 | 
			
		||||
            camera.impl->StartCapture();
 | 
			
		||||
            port.is_busy = true;
 | 
			
		||||
            if (port.is_pending_receiving) {
 | 
			
		||||
                port.is_pending_receiving = false;
 | 
			
		||||
                cam->StartReceiving(i);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        rb.Push(ResultSuccess);
 | 
			
		||||
    } else {
 | 
			
		||||
        LOG_ERROR(Service_CAM, "invalid port_select={}", port_select.m_val);
 | 
			
		||||
        rb.Push(ERROR_INVALID_ENUM_VALUE);
 | 
			
		||||
        rb.Push(ResultInvalidEnumValue);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    LOG_DEBUG(Service_CAM, "called, port_select={}", port_select.m_val);
 | 
			
		||||
@@ -306,7 +310,7 @@ void Module::Interface::StopCapture(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
        rb.Push(ResultSuccess);
 | 
			
		||||
    } else {
 | 
			
		||||
        LOG_ERROR(Service_CAM, "invalid port_select={}", port_select.m_val);
 | 
			
		||||
        rb.Push(ERROR_INVALID_ENUM_VALUE);
 | 
			
		||||
        rb.Push(ResultInvalidEnumValue);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    LOG_DEBUG(Service_CAM, "called, port_select={}", port_select.m_val);
 | 
			
		||||
@@ -328,7 +332,7 @@ void Module::Interface::IsBusy(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
        rb.Push(is_busy);
 | 
			
		||||
    } else {
 | 
			
		||||
        LOG_ERROR(Service_CAM, "invalid port_select={}", port_select.m_val);
 | 
			
		||||
        rb.Push(ERROR_INVALID_ENUM_VALUE);
 | 
			
		||||
        rb.Push(ResultInvalidEnumValue);
 | 
			
		||||
        rb.Skip(1, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -356,7 +360,7 @@ void Module::Interface::GetVsyncInterruptEvent(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
        rb.PushCopyObjects(cam->ports[port].vsync_interrupt_event);
 | 
			
		||||
    } else {
 | 
			
		||||
        LOG_ERROR(Service_CAM, "invalid port_select={}", port_select.m_val);
 | 
			
		||||
        rb.Push(ERROR_INVALID_ENUM_VALUE);
 | 
			
		||||
        rb.Push(ResultInvalidEnumValue);
 | 
			
		||||
        rb.PushCopyObjects<Kernel::Object>(nullptr);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -374,7 +378,7 @@ void Module::Interface::GetBufferErrorInterruptEvent(Kernel::HLERequestContext&
 | 
			
		||||
        rb.PushCopyObjects(cam->ports[port].buffer_error_interrupt_event);
 | 
			
		||||
    } else {
 | 
			
		||||
        LOG_ERROR(Service_CAM, "invalid port_select={}", port_select.m_val);
 | 
			
		||||
        rb.Push(ERROR_INVALID_ENUM_VALUE);
 | 
			
		||||
        rb.Push(ResultInvalidEnumValue);
 | 
			
		||||
        rb.PushCopyObjects<Kernel::Object>(nullptr);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -409,7 +413,7 @@ void Module::Interface::SetReceiving(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
        rb.PushCopyObjects(port.completion_event);
 | 
			
		||||
    } else {
 | 
			
		||||
        LOG_ERROR(Service_CAM, "invalid port_select={}", port_select.m_val);
 | 
			
		||||
        rb.Push(ERROR_INVALID_ENUM_VALUE);
 | 
			
		||||
        rb.Push(ResultInvalidEnumValue);
 | 
			
		||||
        rb.PushCopyObjects<Kernel::Object>(nullptr);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -429,7 +433,7 @@ void Module::Interface::IsFinishedReceiving(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
        rb.Push(!is_busy);
 | 
			
		||||
    } else {
 | 
			
		||||
        LOG_ERROR(Service_CAM, "invalid port_select={}", port_select.m_val);
 | 
			
		||||
        rb.Push(ERROR_INVALID_ENUM_VALUE);
 | 
			
		||||
        rb.Push(ResultInvalidEnumValue);
 | 
			
		||||
        rb.Skip(1, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -451,7 +455,7 @@ void Module::Interface::SetTransferLines(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
        rb.Push(ResultSuccess);
 | 
			
		||||
    } else {
 | 
			
		||||
        LOG_ERROR(Service_CAM, "invalid port_select={}", port_select.m_val);
 | 
			
		||||
        rb.Push(ERROR_INVALID_ENUM_VALUE);
 | 
			
		||||
        rb.Push(ResultInvalidEnumValue);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    LOG_WARNING(Service_CAM, "(STUBBED) called, port_select={}, lines={}, width={}, height={}",
 | 
			
		||||
@@ -469,7 +473,7 @@ void Module::Interface::GetMaxLines(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
    constexpr u32 MIN_TRANSFER_UNIT = 256;
 | 
			
		||||
    constexpr u32 MAX_BUFFER_SIZE = 2560;
 | 
			
		||||
    if (width * height * 2 % MIN_TRANSFER_UNIT != 0) {
 | 
			
		||||
        rb.Push(ERROR_OUT_OF_RANGE);
 | 
			
		||||
        rb.Push(ResultOutOfRange);
 | 
			
		||||
        rb.Skip(1, false);
 | 
			
		||||
    } else {
 | 
			
		||||
        u32 lines = MAX_BUFFER_SIZE / width;
 | 
			
		||||
@@ -480,7 +484,7 @@ void Module::Interface::GetMaxLines(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
        while (height % lines != 0 || (lines * width * 2 % MIN_TRANSFER_UNIT != 0)) {
 | 
			
		||||
            --lines;
 | 
			
		||||
            if (lines == 0) {
 | 
			
		||||
                result = ERROR_OUT_OF_RANGE;
 | 
			
		||||
                result = ResultOutOfRange;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -506,7 +510,7 @@ void Module::Interface::SetTransferBytes(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
        rb.Push(ResultSuccess);
 | 
			
		||||
    } else {
 | 
			
		||||
        LOG_ERROR(Service_CAM, "invalid port_select={}", port_select.m_val);
 | 
			
		||||
        rb.Push(ERROR_INVALID_ENUM_VALUE);
 | 
			
		||||
        rb.Push(ResultInvalidEnumValue);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    LOG_WARNING(Service_CAM, "(STUBBED)called, port_select={}, bytes={}, width={}, height={}",
 | 
			
		||||
@@ -524,7 +528,7 @@ void Module::Interface::GetTransferBytes(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
        rb.Push(cam->ports[port].transfer_bytes);
 | 
			
		||||
    } else {
 | 
			
		||||
        LOG_ERROR(Service_CAM, "invalid port_select={}", port_select.m_val);
 | 
			
		||||
        rb.Push(ERROR_INVALID_ENUM_VALUE);
 | 
			
		||||
        rb.Push(ResultInvalidEnumValue);
 | 
			
		||||
        rb.Skip(1, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -542,7 +546,7 @@ void Module::Interface::GetMaxBytes(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
    constexpr u32 MIN_TRANSFER_UNIT = 256;
 | 
			
		||||
    constexpr u32 MAX_BUFFER_SIZE = 2560;
 | 
			
		||||
    if (width * height * 2 % MIN_TRANSFER_UNIT != 0) {
 | 
			
		||||
        rb.Push(ERROR_OUT_OF_RANGE);
 | 
			
		||||
        rb.Push(ResultOutOfRange);
 | 
			
		||||
        rb.Skip(1, false);
 | 
			
		||||
    } else {
 | 
			
		||||
        u32 bytes = MAX_BUFFER_SIZE;
 | 
			
		||||
@@ -571,7 +575,7 @@ void Module::Interface::SetTrimming(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
        rb.Push(ResultSuccess);
 | 
			
		||||
    } else {
 | 
			
		||||
        LOG_ERROR(Service_CAM, "invalid port_select={}", port_select.m_val);
 | 
			
		||||
        rb.Push(ERROR_INVALID_ENUM_VALUE);
 | 
			
		||||
        rb.Push(ResultInvalidEnumValue);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    LOG_DEBUG(Service_CAM, "called, port_select={}, trim={}", port_select.m_val, trim);
 | 
			
		||||
@@ -588,7 +592,7 @@ void Module::Interface::IsTrimming(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
        rb.Push(cam->ports[port].is_trimming);
 | 
			
		||||
    } else {
 | 
			
		||||
        LOG_ERROR(Service_CAM, "invalid port_select={}", port_select.m_val);
 | 
			
		||||
        rb.Push(ERROR_INVALID_ENUM_VALUE);
 | 
			
		||||
        rb.Push(ResultInvalidEnumValue);
 | 
			
		||||
        rb.Skip(1, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -614,7 +618,7 @@ void Module::Interface::SetTrimmingParams(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
        rb.Push(ResultSuccess);
 | 
			
		||||
    } else {
 | 
			
		||||
        LOG_ERROR(Service_CAM, "invalid port_select={}", port_select.m_val);
 | 
			
		||||
        rb.Push(ERROR_INVALID_ENUM_VALUE);
 | 
			
		||||
        rb.Push(ResultInvalidEnumValue);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    LOG_DEBUG(Service_CAM, "called, port_select={}, x0={}, y0={}, x1={}, y1={}", port_select.m_val,
 | 
			
		||||
@@ -635,7 +639,7 @@ void Module::Interface::GetTrimmingParams(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
        rb.Push(cam->ports[port].y1);
 | 
			
		||||
    } else {
 | 
			
		||||
        LOG_ERROR(Service_CAM, "invalid port_select={}", port_select.m_val);
 | 
			
		||||
        rb.Push(ERROR_INVALID_ENUM_VALUE);
 | 
			
		||||
        rb.Push(ResultInvalidEnumValue);
 | 
			
		||||
        rb.Skip(4, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -661,7 +665,7 @@ void Module::Interface::SetTrimmingParamsCenter(Kernel::HLERequestContext& ctx)
 | 
			
		||||
        rb.Push(ResultSuccess);
 | 
			
		||||
    } else {
 | 
			
		||||
        LOG_ERROR(Service_CAM, "invalid port_select={}", port_select.m_val);
 | 
			
		||||
        rb.Push(ERROR_INVALID_ENUM_VALUE);
 | 
			
		||||
        rb.Push(ResultInvalidEnumValue);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    LOG_DEBUG(Service_CAM, "called, port_select={}, trim_w={}, trim_h={}, cam_w={}, cam_h={}",
 | 
			
		||||
@@ -687,7 +691,7 @@ void Module::Interface::Activate(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
            rb.Push(ResultSuccess);
 | 
			
		||||
        } else if (camera_select[0] && camera_select[1]) {
 | 
			
		||||
            LOG_ERROR(Service_CAM, "camera 0 and 1 can't be both activated");
 | 
			
		||||
            rb.Push(ERROR_INVALID_ENUM_VALUE);
 | 
			
		||||
            rb.Push(ResultInvalidEnumValue);
 | 
			
		||||
        } else {
 | 
			
		||||
            if (camera_select[0]) {
 | 
			
		||||
                cam->ActivatePort(0, 0);
 | 
			
		||||
@@ -702,7 +706,7 @@ void Module::Interface::Activate(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        LOG_ERROR(Service_CAM, "invalid camera_select={}", camera_select.m_val);
 | 
			
		||||
        rb.Push(ERROR_INVALID_ENUM_VALUE);
 | 
			
		||||
        rb.Push(ResultInvalidEnumValue);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    LOG_DEBUG(Service_CAM, "called, camera_select={}", camera_select.m_val);
 | 
			
		||||
@@ -728,7 +732,7 @@ void Module::Interface::SwitchContext(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
    } else {
 | 
			
		||||
        LOG_ERROR(Service_CAM, "invalid camera_select={}, context_select={}", camera_select.m_val,
 | 
			
		||||
                  context_select.m_val);
 | 
			
		||||
        rb.Push(ERROR_INVALID_ENUM_VALUE);
 | 
			
		||||
        rb.Push(ResultInvalidEnumValue);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    LOG_DEBUG(Service_CAM, "called, camera_select={}, context_select={}", camera_select.m_val,
 | 
			
		||||
@@ -738,24 +742,29 @@ void Module::Interface::SwitchContext(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
void Module::Interface::FlipImage(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
    IPC::RequestParser rp(ctx);
 | 
			
		||||
    const CameraSet camera_select(rp.Pop<u8>());
 | 
			
		||||
    const Flip flip = static_cast<Flip>(rp.Pop<u8>());
 | 
			
		||||
    const Flip flip = rp.PopEnum<Flip>();
 | 
			
		||||
    const ContextSet context_select(rp.Pop<u8>());
 | 
			
		||||
 | 
			
		||||
    IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
 | 
			
		||||
    if (camera_select.IsValid() && context_select.IsValid()) {
 | 
			
		||||
        for (int camera : camera_select) {
 | 
			
		||||
        for (int index : camera_select) {
 | 
			
		||||
            auto& camera = cam->cameras[index];
 | 
			
		||||
            for (int context : context_select) {
 | 
			
		||||
                cam->cameras[camera].contexts[context].flip = flip;
 | 
			
		||||
                if (cam->cameras[camera].current_context == context) {
 | 
			
		||||
                    cam->cameras[camera].impl->SetFlip(flip);
 | 
			
		||||
                camera.contexts[context].flip = flip;
 | 
			
		||||
                if (camera.current_context != context) {
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
                if (!camera.impl) {
 | 
			
		||||
                    cam->LoadCameraImplementation(camera, index);
 | 
			
		||||
                }
 | 
			
		||||
                camera.impl->SetFlip(flip);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        rb.Push(ResultSuccess);
 | 
			
		||||
    } else {
 | 
			
		||||
        LOG_ERROR(Service_CAM, "invalid camera_select={}, context_select={}", camera_select.m_val,
 | 
			
		||||
                  context_select.m_val);
 | 
			
		||||
        rb.Push(ERROR_INVALID_ENUM_VALUE);
 | 
			
		||||
        rb.Push(ResultInvalidEnumValue);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    LOG_DEBUG(Service_CAM, "called, camera_select={}, flip={}, context_select={}",
 | 
			
		||||
@@ -776,19 +785,24 @@ void Module::Interface::SetDetailSize(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
 | 
			
		||||
    IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
 | 
			
		||||
    if (camera_select.IsValid() && context_select.IsValid()) {
 | 
			
		||||
        for (int camera : camera_select) {
 | 
			
		||||
        for (int index : camera_select) {
 | 
			
		||||
            auto& camera = cam->cameras[index];
 | 
			
		||||
            for (int context : context_select) {
 | 
			
		||||
                cam->cameras[camera].contexts[context].resolution = resolution;
 | 
			
		||||
                if (cam->cameras[camera].current_context == context) {
 | 
			
		||||
                    cam->cameras[camera].impl->SetResolution(resolution);
 | 
			
		||||
                camera.contexts[context].resolution = resolution;
 | 
			
		||||
                if (camera.current_context != context) {
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
                if (!camera.impl) {
 | 
			
		||||
                    cam->LoadCameraImplementation(camera, index);
 | 
			
		||||
                }
 | 
			
		||||
                camera.impl->SetResolution(resolution);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        rb.Push(ResultSuccess);
 | 
			
		||||
    } else {
 | 
			
		||||
        LOG_ERROR(Service_CAM, "invalid camera_select={}, context_select={}", camera_select.m_val,
 | 
			
		||||
                  context_select.m_val);
 | 
			
		||||
        rb.Push(ERROR_INVALID_ENUM_VALUE);
 | 
			
		||||
        rb.Push(ResultInvalidEnumValue);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    LOG_DEBUG(Service_CAM,
 | 
			
		||||
@@ -806,19 +820,24 @@ void Module::Interface::SetSize(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
 | 
			
		||||
    IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
 | 
			
		||||
    if (camera_select.IsValid() && context_select.IsValid()) {
 | 
			
		||||
        for (int camera : camera_select) {
 | 
			
		||||
        for (int index : camera_select) {
 | 
			
		||||
            auto& camera = cam->cameras[index];
 | 
			
		||||
            for (int context : context_select) {
 | 
			
		||||
                cam->cameras[camera].contexts[context].resolution = PRESET_RESOLUTION[size];
 | 
			
		||||
                if (cam->cameras[camera].current_context == context) {
 | 
			
		||||
                    cam->cameras[camera].impl->SetResolution(PRESET_RESOLUTION[size]);
 | 
			
		||||
                camera.contexts[context].resolution = PRESET_RESOLUTION[size];
 | 
			
		||||
                if (camera.current_context != context) {
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
                if (!camera.impl) {
 | 
			
		||||
                    cam->LoadCameraImplementation(camera, index);
 | 
			
		||||
                }
 | 
			
		||||
                camera.impl->SetResolution(PRESET_RESOLUTION[size]);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        rb.Push(ResultSuccess);
 | 
			
		||||
    } else {
 | 
			
		||||
        LOG_ERROR(Service_CAM, "invalid camera_select={}, context_select={}", camera_select.m_val,
 | 
			
		||||
                  context_select.m_val);
 | 
			
		||||
        rb.Push(ERROR_INVALID_ENUM_VALUE);
 | 
			
		||||
        rb.Push(ResultInvalidEnumValue);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    LOG_DEBUG(Service_CAM, "called, camera_select={}, size={}, context_select={}",
 | 
			
		||||
@@ -828,18 +847,22 @@ void Module::Interface::SetSize(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
void Module::Interface::SetFrameRate(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
    IPC::RequestParser rp(ctx);
 | 
			
		||||
    const CameraSet camera_select(rp.Pop<u8>());
 | 
			
		||||
    const FrameRate frame_rate = static_cast<FrameRate>(rp.Pop<u8>());
 | 
			
		||||
    const FrameRate frame_rate = rp.PopEnum<FrameRate>();
 | 
			
		||||
 | 
			
		||||
    IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
 | 
			
		||||
    if (camera_select.IsValid()) {
 | 
			
		||||
        for (int camera : camera_select) {
 | 
			
		||||
            cam->cameras[camera].frame_rate = frame_rate;
 | 
			
		||||
            cam->cameras[camera].impl->SetFrameRate(frame_rate);
 | 
			
		||||
        for (int index : camera_select) {
 | 
			
		||||
            auto& camera = cam->cameras[index];
 | 
			
		||||
            camera.frame_rate = frame_rate;
 | 
			
		||||
            if (!camera.impl) {
 | 
			
		||||
                cam->LoadCameraImplementation(camera, index);
 | 
			
		||||
            }
 | 
			
		||||
            camera.impl->SetFrameRate(frame_rate);
 | 
			
		||||
        }
 | 
			
		||||
        rb.Push(ResultSuccess);
 | 
			
		||||
    } else {
 | 
			
		||||
        LOG_ERROR(Service_CAM, "invalid camera_select={}", camera_select.m_val);
 | 
			
		||||
        rb.Push(ERROR_INVALID_ENUM_VALUE);
 | 
			
		||||
        rb.Push(ResultInvalidEnumValue);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    LOG_WARNING(Service_CAM, "(STUBBED) called, camera_select={}, frame_rate={}",
 | 
			
		||||
@@ -849,24 +872,29 @@ void Module::Interface::SetFrameRate(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
void Module::Interface::SetEffect(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
    IPC::RequestParser rp(ctx);
 | 
			
		||||
    const CameraSet camera_select(rp.Pop<u8>());
 | 
			
		||||
    const Effect effect = static_cast<Effect>(rp.Pop<u8>());
 | 
			
		||||
    const Effect effect = rp.PopEnum<Effect>();
 | 
			
		||||
    const ContextSet context_select(rp.Pop<u8>());
 | 
			
		||||
 | 
			
		||||
    IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
 | 
			
		||||
    if (camera_select.IsValid() && context_select.IsValid()) {
 | 
			
		||||
        for (int camera : camera_select) {
 | 
			
		||||
        for (int index : camera_select) {
 | 
			
		||||
            auto& camera = cam->cameras[index];
 | 
			
		||||
            for (int context : context_select) {
 | 
			
		||||
                cam->cameras[camera].contexts[context].effect = effect;
 | 
			
		||||
                if (cam->cameras[camera].current_context == context) {
 | 
			
		||||
                    cam->cameras[camera].impl->SetEffect(effect);
 | 
			
		||||
                camera.contexts[context].effect = effect;
 | 
			
		||||
                if (camera.current_context != context) {
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
                if (!camera.impl) {
 | 
			
		||||
                    cam->LoadCameraImplementation(camera, index);
 | 
			
		||||
                }
 | 
			
		||||
                camera.impl->SetEffect(effect);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        rb.Push(ResultSuccess);
 | 
			
		||||
    } else {
 | 
			
		||||
        LOG_ERROR(Service_CAM, "invalid camera_select={}, context_select={}", camera_select.m_val,
 | 
			
		||||
                  context_select.m_val);
 | 
			
		||||
        rb.Push(ERROR_INVALID_ENUM_VALUE);
 | 
			
		||||
        rb.Push(ResultInvalidEnumValue);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    LOG_DEBUG(Service_CAM, "called, camera_select={}, effect={}, context_select={}",
 | 
			
		||||
@@ -876,24 +904,29 @@ void Module::Interface::SetEffect(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
void Module::Interface::SetOutputFormat(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
    IPC::RequestParser rp(ctx);
 | 
			
		||||
    const CameraSet camera_select(rp.Pop<u8>());
 | 
			
		||||
    const OutputFormat format = static_cast<OutputFormat>(rp.Pop<u8>());
 | 
			
		||||
    const OutputFormat format = rp.PopEnum<OutputFormat>();
 | 
			
		||||
    const ContextSet context_select(rp.Pop<u8>());
 | 
			
		||||
 | 
			
		||||
    IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
 | 
			
		||||
    if (camera_select.IsValid() && context_select.IsValid()) {
 | 
			
		||||
        for (int camera : camera_select) {
 | 
			
		||||
        for (int index : camera_select) {
 | 
			
		||||
            auto& camera = cam->cameras[index];
 | 
			
		||||
            for (int context : context_select) {
 | 
			
		||||
                cam->cameras[camera].contexts[context].format = format;
 | 
			
		||||
                if (cam->cameras[camera].current_context == context) {
 | 
			
		||||
                    cam->cameras[camera].impl->SetFormat(format);
 | 
			
		||||
                camera.contexts[context].format = format;
 | 
			
		||||
                if (camera.current_context != context) {
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
                if (!camera.impl) {
 | 
			
		||||
                    cam->LoadCameraImplementation(camera, index);
 | 
			
		||||
                }
 | 
			
		||||
                camera.impl->SetFormat(format);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        rb.Push(ResultSuccess);
 | 
			
		||||
    } else {
 | 
			
		||||
        LOG_ERROR(Service_CAM, "invalid camera_select={}, context_select={}", camera_select.m_val,
 | 
			
		||||
                  context_select.m_val);
 | 
			
		||||
        rb.Push(ERROR_INVALID_ENUM_VALUE);
 | 
			
		||||
        rb.Push(ResultInvalidEnumValue);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    LOG_DEBUG(Service_CAM, "called, camera_select={}, format={}, context_select={}",
 | 
			
		||||
@@ -919,7 +952,7 @@ void Module::Interface::GetLatestVsyncTiming(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
 | 
			
		||||
    if (!port_select.IsSingle() || count > MaxVsyncTimings) {
 | 
			
		||||
        IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
 | 
			
		||||
        rb.Push(ERROR_OUT_OF_RANGE);
 | 
			
		||||
        rb.Push(ResultOutOfRange);
 | 
			
		||||
        rb.PushStaticBuffer({}, 0);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
@@ -1003,7 +1036,7 @@ Result Module::SetPackageParameter(const PackageParameterType& package) {
 | 
			
		||||
    } else {
 | 
			
		||||
        LOG_ERROR(Service_CAM, "invalid camera_select={}, context_select={}", package.camera_select,
 | 
			
		||||
                  package.context_select);
 | 
			
		||||
        return ERROR_INVALID_ENUM_VALUE;
 | 
			
		||||
        return ResultInvalidEnumValue;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user