3
0
Fork 0
forked from suyu/suyu

CAM: implement basic camera functions with a blank camera

This commit is contained in:
wwylele 2016-12-21 20:05:56 +02:00
parent 51dd13b8a0
commit cf3a272332
14 changed files with 1517 additions and 169 deletions

View file

@ -91,6 +91,21 @@ void Config::ReadValues() {
Settings::values.is_new_3ds = sdl2_config->GetBoolean("System", "is_new_3ds", false); Settings::values.is_new_3ds = sdl2_config->GetBoolean("System", "is_new_3ds", false);
Settings::values.region_value = sdl2_config->GetInteger("System", "region_value", 1); Settings::values.region_value = sdl2_config->GetInteger("System", "region_value", 1);
// Camera
using namespace Service::CAM;
Settings::values.camera_name[OuterRightCamera] =
sdl2_config->Get("Camera", "camera_outer_right_name", "blank");
Settings::values.camera_config[OuterRightCamera] =
sdl2_config->Get("Camera", "camera_outer_right_config", "");
Settings::values.camera_name[InnerCamera] =
sdl2_config->Get("Camera", "camera_inner_name", "blank");
Settings::values.camera_config[InnerCamera] =
sdl2_config->Get("Camera", "camera_inner_config", "");
Settings::values.camera_name[OuterLeftCamera] =
sdl2_config->Get("Camera", "camera_outer_left_name", "blank");
Settings::values.camera_config[OuterLeftCamera] =
sdl2_config->Get("Camera", "camera_outer_left_config", "");
// Miscellaneous // Miscellaneous
Settings::values.log_filter = sdl2_config->Get("Miscellaneous", "log_filter", "*:Info"); Settings::values.log_filter = sdl2_config->Get("Miscellaneous", "log_filter", "*:Info");

View file

@ -104,6 +104,22 @@ is_new_3ds =
# 0: Japan, 1: USA (default), 2: Europe, 3: Australia, 4: China, 5: Korea, 6: Taiwan # 0: Japan, 1: USA (default), 2: Europe, 3: Australia, 4: China, 5: Korea, 6: Taiwan
region_value = region_value =
[Camera]
# Which camera engine to use for the right outer camera
# blank (default): a dummy camera that always returns black image
camera_outer_right_name =
# A config string for the right outer camera. Its meaning is defined by the camera engine
camera_outer_right_config =
# ... for the left outer camera
camera_outer_left_name =
camera_outer_left_config =
# ... for the inner camera
camera_inner_name =
camera_inner_config =
[Miscellaneous] [Miscellaneous]
# A filter which removes logs below a certain logging level. # A filter which removes logs below a certain logging level.
# Examples: *:Debug Kernel.SVC:Trace Service.*:Critical # Examples: *:Debug Kernel.SVC:Trace Service.*:Critical

View file

@ -66,6 +66,22 @@ void Config::ReadValues() {
qt_config->value("enable_audio_stretching", true).toBool(); qt_config->value("enable_audio_stretching", true).toBool();
qt_config->endGroup(); qt_config->endGroup();
using namespace Service::CAM;
qt_config->beginGroup("Camera");
Settings::values.camera_name[OuterRightCamera] =
qt_config->value("camera_outer_right_name", "blank").toString().toStdString();
Settings::values.camera_config[OuterRightCamera] =
qt_config->value("camera_outer_right_config", "").toString().toStdString();
Settings::values.camera_name[InnerCamera] =
qt_config->value("camera_inner_name", "blank").toString().toStdString();
Settings::values.camera_config[InnerCamera] =
qt_config->value("camera_inner_config", "").toString().toStdString();
Settings::values.camera_name[OuterLeftCamera] =
qt_config->value("camera_outer_left_name", "blank").toString().toStdString();
Settings::values.camera_config[OuterLeftCamera] =
qt_config->value("camera_outer_left_config", "").toString().toStdString();
qt_config->endGroup();
qt_config->beginGroup("Data Storage"); qt_config->beginGroup("Data Storage");
Settings::values.use_virtual_sd = qt_config->value("use_virtual_sd", true).toBool(); Settings::values.use_virtual_sd = qt_config->value("use_virtual_sd", true).toBool();
qt_config->endGroup(); qt_config->endGroup();
@ -171,6 +187,22 @@ void Config::SaveValues() {
qt_config->setValue("enable_audio_stretching", Settings::values.enable_audio_stretching); qt_config->setValue("enable_audio_stretching", Settings::values.enable_audio_stretching);
qt_config->endGroup(); qt_config->endGroup();
using namespace Service::CAM;
qt_config->beginGroup("Camera");
qt_config->setValue("camera_outer_right_name",
QString::fromStdString(Settings::values.camera_name[OuterRightCamera]));
qt_config->setValue("camera_outer_right_config",
QString::fromStdString(Settings::values.camera_config[OuterRightCamera]));
qt_config->setValue("camera_inner_name",
QString::fromStdString(Settings::values.camera_name[InnerCamera]));
qt_config->setValue("camera_inner_config",
QString::fromStdString(Settings::values.camera_config[InnerCamera]));
qt_config->setValue("camera_outer_left_name",
QString::fromStdString(Settings::values.camera_name[OuterLeftCamera]));
qt_config->setValue("camera_outer_left_config",
QString::fromStdString(Settings::values.camera_config[OuterLeftCamera]));
qt_config->endGroup();
qt_config->beginGroup("Data Storage"); qt_config->beginGroup("Data Storage");
qt_config->setValue("use_virtual_sd", Settings::values.use_virtual_sd); qt_config->setValue("use_virtual_sd", Settings::values.use_virtual_sd);
qt_config->endGroup(); qt_config->endGroup();

View file

@ -29,6 +29,9 @@ set(SRCS
file_sys/ivfc_archive.cpp file_sys/ivfc_archive.cpp
file_sys/path_parser.cpp file_sys/path_parser.cpp
file_sys/savedata_archive.cpp file_sys/savedata_archive.cpp
frontend/camera/blank_camera.cpp
frontend/camera/factory.cpp
frontend/camera/interface.cpp
frontend/emu_window.cpp frontend/emu_window.cpp
frontend/key_map.cpp frontend/key_map.cpp
gdbstub/gdbstub.cpp gdbstub/gdbstub.cpp
@ -200,6 +203,9 @@ set(HEADERS
file_sys/ivfc_archive.h file_sys/ivfc_archive.h
file_sys/path_parser.h file_sys/path_parser.h
file_sys/savedata_archive.h file_sys/savedata_archive.h
frontend/camera/blank_camera.h
frontend/camera/factory.h
frontend/camera/interface.h
frontend/emu_window.h frontend/emu_window.h
frontend/key_map.h frontend/key_map.h
gdbstub/gdbstub.h gdbstub/gdbstub.h

View file

@ -0,0 +1,31 @@
// Copyright 2016 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "core/frontend/camera/blank_camera.h"
namespace Camera {
void BlankCamera::StartCapture() {}
void BlankCamera::StopCapture() {}
void BlankCamera::SetFormat(Service::CAM::OutputFormat output_format) {
output_rgb = output_format == Service::CAM::OutputFormat::RGB565;
}
void BlankCamera::SetResolution(const Service::CAM::Resolution& resolution) {
width = resolution.width;
height = resolution.height;
};
void BlankCamera::SetFlip(Service::CAM::Flip) {}
void BlankCamera::SetEffect(Service::CAM::Effect) {}
std::vector<u16> BlankCamera::ReceiveFrame() const {
// Note: 0x80008000 stands for two black pixels in YUV422
return std::vector<u16>(width * height, output_rgb ? 0 : 0x8000);
}
} // namespace Camera

View file

@ -0,0 +1,28 @@
// Copyright 2016 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include "core/frontend/camera/factory.h"
#include "core/frontend/camera/interface.h"
namespace Camera {
class BlankCamera final : public CameraInterface {
public:
void StartCapture() override;
void StopCapture() override;
void SetResolution(const Service::CAM::Resolution&) override;
void SetFlip(Service::CAM::Flip) override;
void SetEffect(Service::CAM::Effect) override;
void SetFormat(Service::CAM::OutputFormat) override;
std::vector<u16> ReceiveFrame() const override;
private:
int width = 0;
int height = 0;
bool output_rgb = false;
};
} // namespace Camera

View file

@ -0,0 +1,32 @@
// Copyright 2016 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <unordered_map>
#include "common/logging/log.h"
#include "core/frontend/camera/blank_camera.h"
#include "core/frontend/camera/factory.h"
namespace Camera {
static std::unordered_map<std::string, std::unique_ptr<CameraFactory>> factories;
CameraFactory::~CameraFactory() = default;
void RegisterFactory(const std::string& name, std::unique_ptr<CameraFactory> factory) {
factories[name] = std::move(factory);
}
std::unique_ptr<CameraInterface> CreateCamera(const std::string& name, const std::string& config) {
auto pair = factories.find(name);
if (pair != factories.end()) {
return pair->second->Create(config);
}
if (name != "blank") {
LOG_ERROR(Service_CAM, "Unknown camera \"%s\"", name.c_str());
}
return std::make_unique<BlankCamera>();
}
} // namespace Camera

View file

@ -0,0 +1,41 @@
// Copyright 2016 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <memory>
#include <string>
#include "core/frontend/camera/interface.h"
namespace Camera {
class CameraFactory {
public:
virtual ~CameraFactory();
/**
* Creates a camera object based on the configuration string.
* @params config Configuration string to create the camera. The implementation can decide the
* meaning of this string.
* @returns a unique_ptr to the created camera object.
*/
virtual std::unique_ptr<CameraInterface> Create(const std::string& config) const = 0;
};
/**
* Registers an external camera factory.
* @param name Identifier of the camera factory.
* @param factory Camera factory to register.
*/
void RegisterFactory(const std::string& name, std::unique_ptr<CameraFactory> factory);
/**
* Creates a camera from the factory.
* @param name Identifier of the camera factory.
* @param config Configuration string to create the camera. The meaning of this string is
* defined by the factory.
*/
std::unique_ptr<CameraInterface> CreateCamera(const std::string& name, const std::string& config);
} // namespace Camera

View file

@ -0,0 +1,11 @@
// Copyright 2016 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "core/frontend/camera/interface.h"
namespace Camera {
CameraInterface::~CameraInterface() = default;
} // namespace Camera

View file

@ -0,0 +1,61 @@
// Copyright 2016 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <vector>
#include "common/common_types.h"
#include "core/hle/service/cam/cam.h"
namespace Camera {
/// An abstract class standing for a camera. All camera implementations should inherit from this.
class CameraInterface {
public:
virtual ~CameraInterface();
/// Starts the camera for video capturing.
virtual void StartCapture() = 0;
/// Stops the camera for video capturing.
virtual void StopCapture() = 0;
/**
* Sets the video resolution from raw CAM service parameters.
* For the meaning of the parameters, please refer to Service::CAM::Resolution. Note that the
* actual camera implementation doesn't need to respect all the parameters. However, the width
* and the height parameters must be respected and be used to determine the size of output
* frames.
* @param resolution The resolution parameters to set
*/
virtual void SetResolution(const Service::CAM::Resolution& resolution) = 0;
/**
* Configures how received frames should be flipped by the camera.
* @param flip Flip applying to the frame
*/
virtual void SetFlip(Service::CAM::Flip flip) = 0;
/**
* Configures what effect should be applied to received frames by the camera.
* @param effect Effect applying to the frame
*/
virtual void SetEffect(Service::CAM::Effect effect) = 0;
/**
* Sets the output format of the all frames received after this function is called.
* @param format Output format of the frame
*/
virtual void SetFormat(Service::CAM::OutputFormat format) = 0;
/**
* Receives a frame from the camera.
* This function should be only called between a StartCapture call and a StopCapture call.
* @returns A std::vector<u16> containing pixels. The total size of the vector is width * height
* where width and height are set by a call to SetResolution.
*/
virtual std::vector<u16> ReceiveFrame() const = 0;
};
} // namespace Camera

File diff suppressed because it is too large Load diff

View file

@ -13,17 +13,12 @@
namespace Service { namespace Service {
namespace CAM { namespace CAM {
enum class Port : u8 { None = 0, Cam1 = 1, Cam2 = 2, Both = Cam1 | Cam2 }; enum CameraIndex {
OuterRightCamera = 0,
InnerCamera = 1,
OuterLeftCamera = 2,
enum class CameraSelect : u8 { NumCameras = 3,
None = 0,
Out1 = 1,
In1 = 2,
Out2 = 4,
In1Out1 = Out1 | In1,
Out1Out2 = Out1 | Out2,
In1Out2 = In1 | Out2,
All = Out1 | In1 | Out2,
}; };
enum class Effect : u8 { enum class Effect : u8 {
@ -35,13 +30,6 @@ enum class Effect : u8 {
Sepia01 = 5, Sepia01 = 5,
}; };
enum class Context : u8 {
None = 0,
A = 1,
B = 2,
Both = A | B,
};
enum class Flip : u8 { enum class Flip : u8 {
None = 0, None = 0,
Horizontal = 1, Horizontal = 1,
@ -160,8 +148,23 @@ struct StereoCameraCalibrationData {
static_assert(sizeof(StereoCameraCalibrationData) == 64, static_assert(sizeof(StereoCameraCalibrationData) == 64,
"StereoCameraCalibrationData structure size is wrong"); "StereoCameraCalibrationData structure size is wrong");
struct PackageParameterCameraSelect { /**
CameraSelect camera; * Resolution parameters for the camera.
* The native resolution of 3DS camera is 640 * 480. The captured image will be cropped in the
* region [crop_x0, crop_x1] * [crop_y0, crop_y1], and then scaled to size width * height as the
* output image. Note that all cropping coordinates are inclusive.
*/
struct Resolution {
u16 width;
u16 height;
u16 crop_x0;
u16 crop_y0;
u16 crop_x1;
u16 crop_y1;
};
struct PackageParameterWithoutContext {
u8 camera_select;
s8 exposure; s8 exposure;
WhiteBalance white_balance; WhiteBalance white_balance;
s8 sharpness; s8 sharpness;
@ -183,14 +186,43 @@ struct PackageParameterCameraSelect {
s16 auto_white_balance_window_height; s16 auto_white_balance_window_height;
}; };
static_assert(sizeof(PackageParameterCameraSelect) == 28, static_assert(sizeof(PackageParameterWithoutContext) == 28,
"PackageParameterCameraSelect structure size is wrong"); "PackageParameterCameraWithoutContext structure size is wrong");
struct PackageParameterWithContext {
u8 camera_select;
u8 context_select;
Flip flip;
Effect effect;
Size size;
INSERT_PADDING_BYTES(3);
Resolution GetResolution();
};
static_assert(sizeof(PackageParameterWithContext) == 8,
"PackageParameterWithContext structure size is wrong");
struct PackageParameterWithContextDetail {
u8 camera_select;
u8 context_select;
Flip flip;
Effect effect;
Resolution resolution;
Resolution GetResolution() {
return resolution;
}
};
static_assert(sizeof(PackageParameterWithContextDetail) == 16,
"PackageParameterWithContextDetail structure size is wrong");
/** /**
* Unknown * Starts capturing at the selected port.
* Inputs: * Inputs:
* 0: 0x00010040 * 0: 0x00010040
* 1: u8 Camera port (`Port` enum) * 1: u8 selected port
* Outputs: * Outputs:
* 0: 0x00010040 * 0: 0x00010040
* 1: ResultCode * 1: ResultCode
@ -198,21 +230,44 @@ static_assert(sizeof(PackageParameterCameraSelect) == 28,
void StartCapture(Service::Interface* self); void StartCapture(Service::Interface* self);
/** /**
* Unknown * Stops capturing from the selected port.
* Inputs: * Inputs:
* 0: 0x00020040 * 0: 0x00020040
* 1: u8 Camera port (`Port` enum) * 1: u8 selected port
* Outputs: * Outputs:
* 0: 0x00020040 * 0: 0x00020040
* 1: ResultCode * 1: ResultCode
*/ */
void StopCapture(Service::Interface* self); void StopCapture(Service::Interface* self);
/**
* Gets whether the selected port is currently capturing.
* Inputs:
* 0: 0x00030040
* 1: u8 selected port
* Outputs:
* 0: 0x00030080
* 1: ResultCode
* 2: 0 if not capturing, 1 if capturing
*/
void IsBusy(Service::Interface* self);
/**
* Clears the buffer of selected ports.
* Inputs:
* 0: 0x00040040
* 1: u8 selected port
* Outputs:
* 0: 0x00040040
* 2: ResultCode
*/
void ClearBuffer(Service::Interface* self);
/** /**
* Unknown * Unknown
* Inputs: * Inputs:
* 0: 0x00050040 * 0: 0x00050040
* 1: u8 Camera port (`Port` enum) * 1: u8 selected port
* Outputs: * Outputs:
* 0: 0x00050042 * 0: 0x00050042
* 1: ResultCode * 1: ResultCode
@ -225,7 +280,7 @@ void GetVsyncInterruptEvent(Service::Interface* self);
* Unknown * Unknown
* Inputs: * Inputs:
* 0: 0x00060040 * 0: 0x00060040
* 1: u8 Camera port (`Port` enum) * 1: u8 selected port
* Outputs: * Outputs:
* 0: 0x00060042 * 0: 0x00060042
* 1: ResultCode * 1: ResultCode
@ -241,9 +296,9 @@ void GetBufferErrorInterruptEvent(Service::Interface* self);
* Inputs: * Inputs:
* 0: 0x00070102 * 0: 0x00070102
* 1: Destination address in calling process * 1: Destination address in calling process
* 2: u8 Camera port (`Port` enum) * 2: u8 selected port
* 3: Image size (in bytes?) * 3: Image size (in bytes)
* 4: u16 Transfer unit size (in bytes?) * 4: u16 Transfer unit size (in bytes)
* 5: Descriptor: Handle * 5: Descriptor: Handle
* 6: Handle to destination process * 6: Handle to destination process
* Outputs: * Outputs:
@ -255,21 +310,34 @@ void GetBufferErrorInterruptEvent(Service::Interface* self);
void SetReceiving(Service::Interface* self); void SetReceiving(Service::Interface* self);
/** /**
* Unknown * Gets whether the selected port finished receiving a frame.
* Inputs:
* 0: 0x00080040
* 1: u8 selected port
* Outputs:
* 0: 0x00080080
* 1: ResultCode
* 2: 0 if not finished, 1 if finished
*/
void IsFinishedReceiving(Service::Interface* self);
/**
* Sets the number of lines the buffer contains.
* Inputs: * Inputs:
* 0: 0x00090100 * 0: 0x00090100
* 1: u8 Camera port (`Port` enum) * 1: u8 selected port
* 2: u16 Number of lines to transfer * 2: u16 Number of lines to transfer
* 3: u16 Width * 3: u16 Width
* 4: u16 Height * 4: u16 Height
* Outputs: * Outputs:
* 0: 0x00090040 * 0: 0x00090040
* 1: ResultCode * 1: ResultCode
* @todo figure out how the "buffer" actually works.
*/ */
void SetTransferLines(Service::Interface* self); void SetTransferLines(Service::Interface* self);
/** /**
* Unknown * Gets the maximum number of lines that fit in the buffer
* Inputs: * Inputs:
* 0: 0x000A0080 * 0: 0x000A0080
* 1: u16 Width * 1: u16 Width
@ -277,27 +345,58 @@ void SetTransferLines(Service::Interface* self);
* Outputs: * Outputs:
* 0: 0x000A0080 * 0: 0x000A0080
* 1: ResultCode * 1: ResultCode
* 2: Maximum number of lines that fit in the buffer(?) * 2: Maximum number of lines that fit in the buffer
* @todo figure out how the "buffer" actually works.
*/ */
void GetMaxLines(Service::Interface* self); void GetMaxLines(Service::Interface* self);
/** /**
* Unknown * Sets the number of bytes the buffer contains.
* Inputs:
* 0: 0x000B0100
* 1: u8 selected port
* 2: u16 Number of bytes to transfer
* 3: u16 Width
* 4: u16 Height
* Outputs:
* 0: 0x000B0040
* 1: ResultCode
* @todo figure out how the "buffer" actually works.
*/
void SetTransferBytes(Service::Interface* self);
/**
* Gets the number of bytes to the buffer contains.
* Inputs: * Inputs:
* 0: 0x000C0040 * 0: 0x000C0040
* 1: u8 Camera port (`Port` enum) * 1: u8 selected port
* Outputs: * Outputs:
* 0: 0x000C0080 * 0: 0x000C0080
* 1: ResultCode * 1: ResultCode
* 2: Total number of bytes for each frame with current settings(?) * 2: The number of bytes the buffer contains
* @todo figure out how the "buffer" actually works.
*/ */
void GetTransferBytes(Service::Interface* self); void GetTransferBytes(Service::Interface* self);
/** /**
* Unknown * Gets the maximum number of bytes that fit in the buffer.
* Inputs:
* 0: 0x000D0080
* 1: u16 Width
* 2: u16 Height
* Outputs:
* 0: 0x000D0080
* 1: ResultCode
* 2: Maximum number of bytes that fit in the buffer
* @todo figure out how the "buffer" actually works.
*/
void GetMaxBytes(Service::Interface* self);
/**
* Enables or disables trimming.
* Inputs: * Inputs:
* 0: 0x000E0080 * 0: 0x000E0080
* 1: u8 Camera port (`Port` enum) * 1: u8 selected port
* 2: u8 bool Enable trimming if true * 2: u8 bool Enable trimming if true
* Outputs: * Outputs:
* 0: 0x000E0040 * 0: 0x000E0040
@ -306,14 +405,58 @@ void GetTransferBytes(Service::Interface* self);
void SetTrimming(Service::Interface* self); void SetTrimming(Service::Interface* self);
/** /**
* Unknown * Gets whether trimming is enabled.
* Inputs:
* 0: 0x000F0040
* 1: u8 selected port
* Outputs:
* 0: 0x000F0080
* 1: ResultCode
* 2: u8 bool Enable trimming if true
*/
void IsTrimming(Service::Interface* self);
/**
* Sets the position to trim.
* Inputs:
* 0: 0x00100140
* 1: u8 selected port
* 2: x start
* 3: y start
* 4: x end (exclusive)
* 5: y end (exclusive)
* Outputs:
* 0: 0x00100040
* 1: ResultCode
*/
void SetTrimmingParams(Service::Interface* self);
/**
* Gets the position to trim.
* Inputs:
* 0: 0x00110040
* 1: u8 selected port
*
* Outputs:
* 0: 0x00110140
* 1: ResultCode
* 2: x start
* 3: y start
* 4: x end (exclusive)
* 5: y end (exclusive)
*/
void GetTrimmingParams(Service::Interface* self);
/**
* Sets the position to trim by giving the width and height. The trimming window is always at the
* center.
* Inputs: * Inputs:
* 0: 0x00120140 * 0: 0x00120140
* 1: u8 Camera port (`Port` enum) * 1: u8 selected port
* 2: s16 Trim width(?) * 2: s16 Trim width
* 3: s16 Trim height(?) * 3: s16 Trim height
* 4: s16 Camera width(?) * 4: s16 Camera width
* 5: s16 Camera height(?) * 5: s16 Camera height
* Outputs: * Outputs:
* 0: 0x00120040 * 0: 0x00120040
* 1: ResultCode * 1: ResultCode
@ -324,7 +467,7 @@ void SetTrimmingParamsCenter(Service::Interface* self);
* Selects up to two physical cameras to enable. * Selects up to two physical cameras to enable.
* Inputs: * Inputs:
* 0: 0x00130040 * 0: 0x00130040
* 1: u8 Cameras to activate (`CameraSelect` enum) * 1: u8 selected camera
* Outputs: * Outputs:
* 0: 0x00130040 * 0: 0x00130040
* 1: ResultCode * 1: ResultCode
@ -332,12 +475,24 @@ void SetTrimmingParamsCenter(Service::Interface* self);
void Activate(Service::Interface* self); void Activate(Service::Interface* self);
/** /**
* Unknown * Switches the context of camera settings.
* Inputs:
* 0: 0x00140080
* 1: u8 selected camera
* 2: u8 selected context
* Outputs:
* 0: 0x00140040
* 1: ResultCode
*/
void SwitchContext(Service::Interface* self);
/**
* Sets flipping of images
* Inputs: * Inputs:
* 0: 0x001D00C0 * 0: 0x001D00C0
* 1: u8 Camera select (`CameraSelect` enum) * 1: u8 selected camera
* 2: u8 Type of flipping to perform (`Flip` enum) * 2: u8 Type of flipping to perform (`Flip` enum)
* 3: u8 Context (`Context` enum) * 3: u8 selected context
* Outputs: * Outputs:
* 0: 0x001D0040 * 0: 0x001D0040
* 1: ResultCode * 1: ResultCode
@ -345,12 +500,30 @@ void Activate(Service::Interface* self);
void FlipImage(Service::Interface* self); void FlipImage(Service::Interface* self);
/** /**
* Unknown * Sets camera resolution from custom parameters. For more details see the Resolution struct.
* Inputs:
* 0: 0x001E0200
* 1: u8 selected camera
* 2: width
* 3: height
* 4: crop x0
* 5: crop y0
* 6: crop x1
* 7: crop y1
* 8: u8 selected context
* Outputs:
* 0: 0x001E0040
* 1: ResultCode
*/
void SetDetailSize(Service::Interface* self);
/**
* Sets camera resolution from preset resolution parameters. .
* Inputs: * Inputs:
* 0: 0x001F00C0 * 0: 0x001F00C0
* 1: u8 Camera select (`CameraSelect` enum) * 1: u8 selected camera
* 2: u8 Camera frame resolution (`Size` enum) * 2: u8 Camera frame resolution (`Size` enum)
* 3: u8 Context id (`Context` enum) * 3: u8 selected context
* Outputs: * Outputs:
* 0: 0x001F0040 * 0: 0x001F0040
* 1: ResultCode * 1: ResultCode
@ -358,10 +531,10 @@ void FlipImage(Service::Interface* self);
void SetSize(Service::Interface* self); void SetSize(Service::Interface* self);
/** /**
* Unknown * Sets camera framerate.
* Inputs: * Inputs:
* 0: 0x00200080 * 0: 0x00200080
* 1: u8 Camera select (`CameraSelect` enum) * 1: u8 selected camera
* 2: u8 Camera framerate (`FrameRate` enum) * 2: u8 Camera framerate (`FrameRate` enum)
* Outputs: * Outputs:
* 0: 0x00200040 * 0: 0x00200040
@ -369,6 +542,44 @@ void SetSize(Service::Interface* self);
*/ */
void SetFrameRate(Service::Interface* self); void SetFrameRate(Service::Interface* self);
/**
* Sets effect on the output image
* Inputs:
* 0: 0x002200C0
* 1: u8 selected camera
* 2: u8 image effect (`Effect` enum)
* 3: u8 selected context
* Outputs:
* 0: 0x00220040
* 1: ResultCode
*/
void SetEffect(Service::Interface* self);
/**
* Sets format of the output image
* Inputs:
* 0: 0x002500C0
* 1: u8 selected camera
* 2: u8 image format (`OutputFormat` enum)
* 3: u8 selected context
* Outputs:
* 0: 0x00250040
* 1: ResultCode
*/
void SetOutputFormat(Service::Interface* self);
/**
* Synchronizes the V-Sync timing of two cameras.
* Inputs:
* 0: 0x00290080
* 1: u8 selected camera 1
* 2: u8 selected camera 2
* Outputs:
* 0: 0x00280040
* 1: ResultCode
*/
void SynchronizeVsyncTiming(Service::Interface* self);
/** /**
* Returns calibration data relating the outside cameras to eachother, for use in AR applications. * Returns calibration data relating the outside cameras to eachother, for use in AR applications.
* *
@ -381,6 +592,45 @@ void SetFrameRate(Service::Interface* self);
*/ */
void GetStereoCameraCalibrationData(Service::Interface* self); void GetStereoCameraCalibrationData(Service::Interface* self);
/**
* Batch-configures context-free settings.
*
* Inputs:
* 0: 0x003302C0
* 1-7: struct PachageParameterWithoutContext
* 8-11: unused
* Outputs:
* 0: 0x00330040
* 1: ResultCode
*/
void SetPackageParameterWithoutContext(Service::Interface* self);
/**
* Batch-configures context-related settings with preset resolution parameters.
*
* Inputs:
* 0: 0x00340140
* 1-2: struct PackageParameterWithContext
* 3-5: unused
* Outputs:
* 0: 0x00340040
* 1: ResultCode
*/
void SetPackageParameterWithContext(Service::Interface* self);
/**
* Batch-configures context-related settings with custom resolution parameters
*
* Inputs:
* 0: 0x003501C0
* 1-4: struct PackageParameterWithContextDetail
* 5-7: unused
* Outputs:
* 0: 0x00350040
* 1: ResultCode
*/
void SetPackageParameterWithContextDetail(Service::Interface* self);
/** /**
* Unknown * Unknown
* Inputs: * Inputs:

View file

@ -11,24 +11,24 @@ namespace CAM {
const Interface::FunctionInfo FunctionTable[] = { const Interface::FunctionInfo FunctionTable[] = {
{0x00010040, StartCapture, "StartCapture"}, {0x00010040, StartCapture, "StartCapture"},
{0x00020040, StopCapture, "StopCapture"}, {0x00020040, StopCapture, "StopCapture"},
{0x00030040, nullptr, "IsBusy"}, {0x00030040, IsBusy, "IsBusy"},
{0x00040040, nullptr, "ClearBuffer"}, {0x00040040, ClearBuffer, "ClearBuffer"},
{0x00050040, GetVsyncInterruptEvent, "GetVsyncInterruptEvent"}, {0x00050040, GetVsyncInterruptEvent, "GetVsyncInterruptEvent"},
{0x00060040, GetBufferErrorInterruptEvent, "GetBufferErrorInterruptEvent"}, {0x00060040, GetBufferErrorInterruptEvent, "GetBufferErrorInterruptEvent"},
{0x00070102, SetReceiving, "SetReceiving"}, {0x00070102, SetReceiving, "SetReceiving"},
{0x00080040, nullptr, "IsFinishedReceiving"}, {0x00080040, IsFinishedReceiving, "IsFinishedReceiving"},
{0x00090100, SetTransferLines, "SetTransferLines"}, {0x00090100, SetTransferLines, "SetTransferLines"},
{0x000A0080, GetMaxLines, "GetMaxLines"}, {0x000A0080, GetMaxLines, "GetMaxLines"},
{0x000B0100, nullptr, "SetTransferBytes"}, {0x000B0100, SetTransferBytes, "SetTransferBytes"},
{0x000C0040, GetTransferBytes, "GetTransferBytes"}, {0x000C0040, GetTransferBytes, "GetTransferBytes"},
{0x000D0080, nullptr, "GetMaxBytes"}, {0x000D0080, GetMaxBytes, "GetMaxBytes"},
{0x000E0080, SetTrimming, "SetTrimming"}, {0x000E0080, SetTrimming, "SetTrimming"},
{0x000F0040, nullptr, "IsTrimming"}, {0x000F0040, IsTrimming, "IsTrimming"},
{0x00100140, nullptr, "SetTrimmingParams"}, {0x00100140, SetTrimmingParams, "SetTrimmingParams"},
{0x00110040, nullptr, "GetTrimmingParams"}, {0x00110040, GetTrimmingParams, "GetTrimmingParams"},
{0x00120140, SetTrimmingParamsCenter, "SetTrimmingParamsCenter"}, {0x00120140, SetTrimmingParamsCenter, "SetTrimmingParamsCenter"},
{0x00130040, Activate, "Activate"}, {0x00130040, Activate, "Activate"},
{0x00140080, nullptr, "SwitchContext"}, {0x00140080, SwitchContext, "SwitchContext"},
{0x00150080, nullptr, "SetExposure"}, {0x00150080, nullptr, "SetExposure"},
{0x00160080, nullptr, "SetWhiteBalance"}, {0x00160080, nullptr, "SetWhiteBalance"},
{0x00170080, nullptr, "SetWhiteBalanceWithoutBaseUp"}, {0x00170080, nullptr, "SetWhiteBalanceWithoutBaseUp"},
@ -38,18 +38,18 @@ const Interface::FunctionInfo FunctionTable[] = {
{0x001B0080, nullptr, "SetAutoWhiteBalance"}, {0x001B0080, nullptr, "SetAutoWhiteBalance"},
{0x001C0040, nullptr, "IsAutoWhiteBalance"}, {0x001C0040, nullptr, "IsAutoWhiteBalance"},
{0x001D00C0, FlipImage, "FlipImage"}, {0x001D00C0, FlipImage, "FlipImage"},
{0x001E0200, nullptr, "SetDetailSize"}, {0x001E0200, SetDetailSize, "SetDetailSize"},
{0x001F00C0, SetSize, "SetSize"}, {0x001F00C0, SetSize, "SetSize"},
{0x00200080, SetFrameRate, "SetFrameRate"}, {0x00200080, SetFrameRate, "SetFrameRate"},
{0x00210080, nullptr, "SetPhotoMode"}, {0x00210080, nullptr, "SetPhotoMode"},
{0x002200C0, nullptr, "SetEffect"}, {0x002200C0, SetEffect, "SetEffect"},
{0x00230080, nullptr, "SetContrast"}, {0x00230080, nullptr, "SetContrast"},
{0x00240080, nullptr, "SetLensCorrection"}, {0x00240080, nullptr, "SetLensCorrection"},
{0x002500C0, nullptr, "SetOutputFormat"}, {0x002500C0, SetOutputFormat, "SetOutputFormat"},
{0x00260140, nullptr, "SetAutoExposureWindow"}, {0x00260140, nullptr, "SetAutoExposureWindow"},
{0x00270140, nullptr, "SetAutoWhiteBalanceWindow"}, {0x00270140, nullptr, "SetAutoWhiteBalanceWindow"},
{0x00280080, nullptr, "SetNoiseFilter"}, {0x00280080, nullptr, "SetNoiseFilter"},
{0x00290080, nullptr, "SynchronizeVsyncTiming"}, {0x00290080, SynchronizeVsyncTiming, "SynchronizeVsyncTiming"},
{0x002A0080, nullptr, "GetLatestVsyncTiming"}, {0x002A0080, nullptr, "GetLatestVsyncTiming"},
{0x002B0000, GetStereoCameraCalibrationData, "GetStereoCameraCalibrationData"}, {0x002B0000, GetStereoCameraCalibrationData, "GetStereoCameraCalibrationData"},
{0x002C0400, nullptr, "SetStereoCameraCalibrationData"}, {0x002C0400, nullptr, "SetStereoCameraCalibrationData"},
@ -59,9 +59,9 @@ const Interface::FunctionInfo FunctionTable[] = {
{0x00300080, nullptr, "ReadMcuVariableI2cExclusive"}, {0x00300080, nullptr, "ReadMcuVariableI2cExclusive"},
{0x00310180, nullptr, "SetImageQualityCalibrationData"}, {0x00310180, nullptr, "SetImageQualityCalibrationData"},
{0x00320000, nullptr, "GetImageQualityCalibrationData"}, {0x00320000, nullptr, "GetImageQualityCalibrationData"},
{0x003302C0, nullptr, "SetPackageParameterWithoutContext"}, {0x003302C0, SetPackageParameterWithoutContext, "SetPackageParameterWithoutContext"},
{0x00340140, nullptr, "SetPackageParameterWithContext"}, {0x00340140, SetPackageParameterWithContext, "SetPackageParameterWithContext"},
{0x003501C0, nullptr, "SetPackageParameterWithContextDetail"}, {0x003501C0, SetPackageParameterWithContextDetail, "SetPackageParameterWithContextDetail"},
{0x00360000, GetSuitableY2rStandardCoefficient, "GetSuitableY2rStandardCoefficient"}, {0x00360000, GetSuitableY2rStandardCoefficient, "GetSuitableY2rStandardCoefficient"},
{0x00370202, nullptr, "PlayShutterSoundWithWave"}, {0x00370202, nullptr, "PlayShutterSoundWithWave"},
{0x00380040, PlayShutterSound, "PlayShutterSound"}, {0x00380040, PlayShutterSound, "PlayShutterSound"},

View file

@ -7,6 +7,7 @@
#include <array> #include <array>
#include <string> #include <string>
#include "common/common_types.h" #include "common/common_types.h"
#include "core/hle/service/cam/cam.h"
namespace Settings { namespace Settings {
@ -105,6 +106,10 @@ struct Values {
std::string sink_id; std::string sink_id;
bool enable_audio_stretching; bool enable_audio_stretching;
// Camera
std::array<std::string, Service::CAM::NumCameras> camera_name;
std::array<std::string, Service::CAM::NumCameras> camera_config;
// Debugging // Debugging
bool use_gdbstub; bool use_gdbstub;
u16 gdbstub_port; u16 gdbstub_port;