// Copyright 2015 Citra Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. #include "common/logging/log.h" #include "core/hle/service/service.h" #include "core/hle/service/cam/cam.h" #include "core/hle/service/cam/cam_c.h" #include "core/hle/service/cam/cam_q.h" #include "core/hle/service/cam/cam_s.h" #include "core/hle/service/cam/cam_u.h" #include "core/hle/kernel/event.h" #include "core/hle/kernel/shared_memory.h" #include "core/hle/hle.h" namespace Service { namespace CAM { static const u32 TRANSFER_BYTES = 5 * 1024; static Kernel::SharedPtr completion_event; static Kernel::SharedPtr interrupt_error_event; static Kernel::SharedPtr vsync_interrupt_error_event; void DriverInitialize(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[1] = RESULT_SUCCESS.raw; LOG_WARNING(Service_CAM, "(STUBBED) called"); } void DriverFinalize(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[1] = RESULT_SUCCESS.raw; LOG_WARNING(Service_CAM, "(STUBBED) called"); } void SetTransferLines(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u8 port = cmd_buff[1] & 0xFF; u16 transfer_lines = cmd_buff[2] & 0xFFFF; u16 width = cmd_buff[3] & 0xFFFF; u16 height = cmd_buff[4] & 0xFFFF; cmd_buff[1] = RESULT_SUCCESS.raw; LOG_WARNING(Service_CAM, "(STUBBED) called, port=%d, lines=%d, width=%d, height=%d", port, transfer_lines, width, height); } void GetMaxLines(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u16 width = cmd_buff[1] & 0xFFFF; u16 height = cmd_buff[2] & 0xFFFF; cmd_buff[1] = RESULT_SUCCESS.raw; cmd_buff[2] = TRANSFER_BYTES / (2 * width); LOG_WARNING(Service_CAM, "(STUBBED) called, width=%d, height=%d, lines = %d", width, height, cmd_buff[2]); } void GetBufferErrorInterruptEvent(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u8 port = cmd_buff[1] & 0xFF; cmd_buff[1] = RESULT_SUCCESS.raw; cmd_buff[3] = Kernel::g_handle_table.Create(interrupt_error_event).MoveFrom(); LOG_WARNING(Service_CAM, "(STUBBED) called, port=%d", port); } void GetVsyncInterruptEvent(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u8 port = cmd_buff[1] & 0xFF; cmd_buff[1] = RESULT_SUCCESS.raw; cmd_buff[3] = Kernel::g_handle_table.Create(vsync_interrupt_error_event).MoveFrom(); LOG_WARNING(Service_CAM, "(STUBBED) called, port=%d", port); } void SetSize(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u8 cam_select = cmd_buff[1] & 0xFF; u8 size = cmd_buff[2] & 0xFF; u8 context = cmd_buff[3] & 0xFF; cmd_buff[1] = RESULT_SUCCESS.raw; LOG_WARNING(Service_CAM, "(STUBBED) called, cam_select=%d, size=%d, context=%d", cam_select, size, context); } void Activate(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u8 cam_select = cmd_buff[1] & 0xFF; cmd_buff[1] = RESULT_SUCCESS.raw; LOG_WARNING(Service_CAM, "(STUBBED) called, cam_select=%d", cam_select); } void SetTrimming(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u8 port = cmd_buff[1] & 0xFF; bool trim = cmd_buff[2] & 0xFF; cmd_buff[1] = RESULT_SUCCESS.raw; LOG_WARNING(Service_CAM, "(STUBBED) called, port=%d, trim=%d", port, trim); } void SetTrimmingParamsCenter(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u8 port = cmd_buff[1] & 0xFF; s16 trimW = cmd_buff[2] & 0xFFFF; s16 trimH = cmd_buff[3] & 0xFFFF; s16 camW = cmd_buff[4] & 0xFFFF; s16 camH = cmd_buff[5] & 0xFFFF; cmd_buff[1] = RESULT_SUCCESS.raw; LOG_WARNING(Service_CAM, "(STUBBED) called, port=%d, trimW=%d, trimH=%d, camW=%d, camH=%d", port, trimW, trimH, camW, camH); } void FlipImage(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u8 cam_select = cmd_buff[1] & 0xFF; u8 flip = cmd_buff[2] & 0xFF; u8 context = cmd_buff[3] & 0xFF; cmd_buff[1] = RESULT_SUCCESS.raw; LOG_WARNING(Service_CAM, "(STUBBED) called, cam_select=%d, flip=%d, context=%d", cam_select, flip, context); } void SetFrameRate(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u8 cam_select = cmd_buff[1] & 0xFF; u8 frame_rate = cmd_buff[2] & 0xFF; cmd_buff[1] = RESULT_SUCCESS.raw; LOG_WARNING(Service_CAM, "(STUBBED) called, cam_select=%d, frame_rate=%d", cam_select, frame_rate); } void GetSuitableY2rStandardCoefficient(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[1] = RESULT_SUCCESS.raw; cmd_buff[2] = 0; LOG_WARNING(Service_CAM, "(STUBBED) called"); } void GetTransferBytes(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u8 port = cmd_buff[1] & 0xFF; cmd_buff[1] = RESULT_SUCCESS.raw; cmd_buff[2] = TRANSFER_BYTES; LOG_WARNING(Service_CAM, "(STUBBED) called, port=%d", port); } void SetReceiving(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u32 dest = cmd_buff[1]; // void* u8 port = cmd_buff[2] & 0xFF; u32 image_size = cmd_buff[3]; u16 trans_unit = cmd_buff[4] & 0xFFFF; cmd_buff[1] = RESULT_SUCCESS.raw; cmd_buff[3] = Kernel::g_handle_table.Create(completion_event).MoveFrom(); LOG_WARNING(Service_CAM, "(STUBBED) called, addr=0x%X, port=%d, image_size=%d, trans_unit=%d", dest, port, image_size, trans_unit); } void StartCapture(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u8 port = cmd_buff[1] & 0xFF; cmd_buff[1] = RESULT_SUCCESS.raw; LOG_WARNING(Service_CAM, "(STUBBED) called, port=%d", port); } void StopCapture(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u8 port = cmd_buff[1] & 0xFF; cmd_buff[1] = RESULT_SUCCESS.raw; LOG_WARNING(Service_CAM, "(STUBBED) called, port=%d", port); } void PlayShutterSound(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u8 sound_id = cmd_buff[1] & 0xFF; cmd_buff[1] = RESULT_SUCCESS.raw; LOG_WARNING(Service_CAM, "(STUBBED) called, sound_id=%d", sound_id); } void Init() { using namespace Kernel; AddService(new CAM_C_Interface); AddService(new CAM_Q_Interface); AddService(new CAM_S_Interface); AddService(new CAM_U_Interface); completion_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "CAM_U::completion_event"); interrupt_error_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "CAM_U::interrupt_error_event"); vsync_interrupt_error_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "CAM_U::vsync_interrupt_error_event"); } void Shutdown() { completion_event = nullptr; interrupt_error_event = nullptr; vsync_interrupt_error_event = nullptr; } } // namespace CAM } // namespace Service