256 lines
7.3 KiB
C++

// 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<Kernel::Event> completion_event;
static Kernel::SharedPtr<Kernel::Event> interrupt_error_event;
static Kernel::SharedPtr<Kernel::Event> 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