diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index af13521527..75ea01fe78 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -103,7 +103,6 @@ protected: std::stack m_call_stack; CellGcmControl* m_ctrl; Timer m_timer_sync; - double m_fps_limit = 59.94; public: GcmTileInfo m_tiles[m_tiles_count]; @@ -151,6 +150,7 @@ public: float m_height_scale; u32 m_draw_array_count; u32 m_draw_array_first; + double m_fps_limit = 59.94; public: std::mutex m_cs_main; diff --git a/rpcs3/Emu/SysCalls/Modules/cellCamera.cpp b/rpcs3/Emu/SysCalls/Modules/cellCamera.cpp index 467e18e214..d363ca072e 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellCamera.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellCamera.cpp @@ -6,10 +6,16 @@ #include "cellCamera.h" Module *cellCamera = nullptr; +const char* attributes[] = {"GAIN", "REDBLUEGAIN", "SATURATION", "EXPOSURE", "BRIGHTNESS", "AEC", "AGC", "AWB", "ABC", "LED", "AUDIOGAIN", "QS", "NONZEROCOEFFS", "YUVFLAG", + "JPEGFLAG", "BACKLIGHTCOMP", "MIRRORFLAG", "MEASUREDQS", "422FLAG", "USBLOAD", "GAMMA", "GREENGAIN", "AGCLIMIT", "DENOISE", "FRAMERATEADJUST", + "PIXELOUTLIERFILTER", "AGCLOW", "AGCHIGH", "DEVICELOCATION", "FORMATCAP", "FORMATINDEX", "NUMFRAME", "FRAMEINDEX", "FRAMESIZE", "INTERVALTYPE", + "INTERVALINDEX", "INTERVALVALUE", "COLORMATCHING", "PLFREQ", "DEVICEID", "DEVICECAP", "DEVICESPEED", "UVCREQCODE", "UVCREQDATA", "DEVICEID2", + "READMODE", "GAMEPID", "PBUFFER", "READFINISH", "ATTRIBUTE_UNKNOWN"}; struct cellCameraInternal { bool m_bInitialized; + CellCamera m_camera; cellCameraInternal() : m_bInitialized(false) @@ -26,7 +32,51 @@ int cellCameraInit() if (cellCameraInstance.m_bInitialized) return CELL_CAMERA_ERROR_ALREADY_INIT; - // TODO: Check if camera is connected, if not return CELL_CAMERA_ERROR_DEVICE_NOT_FOUND + if (Ini.Camera.GetValue() == 0) + return CELL_CAMERA_ERROR_DEVICE_NOT_FOUND; + + if (Ini.CameraType.GetValue() == 1) + { + CellCamera camera; + camera.attributes.SATURATION = 164; + camera.attributes.BRIGHTNESS = 96; + camera.attributes.AEC = 1; + camera.attributes.AGC = 1; + camera.attributes.AWB = 1; + camera.attributes.ABC = 0; + camera.attributes.LED = 1; + camera.attributes.QS = 0; + camera.attributes.NONZEROCOEFFS[0] = 32; + camera.attributes.NONZEROCOEFFS[1] = 32; + camera.attributes.YUVFLAG = 0; + camera.attributes.BACKLIGHTCOMP = 0; + camera.attributes.MIRRORFLAG = 1; + camera.attributes._422FLAG = 1; + camera.attributes.USBLOAD = 4; + cellCameraInstance.m_camera = camera; + } + else if (Ini.CameraType.GetValue() == 2) + { + CellCamera camera; + camera.attributes.SATURATION = 64; + camera.attributes.BRIGHTNESS = 8; + camera.attributes.AEC = 1; + camera.attributes.AGC = 1; + camera.attributes.AWB = 1; + camera.attributes.LED = 1; + camera.attributes.BACKLIGHTCOMP = 0; + camera.attributes.MIRRORFLAG = 1; + camera.attributes.GAMMA = 1; + camera.attributes.AGCLIMIT = 4; + camera.attributes.DENOISE = 0; + camera.attributes.FRAMERATEADJUST = 0; + camera.attributes.PIXELOUTLIERFILTER = 1; + camera.attributes.AGCLOW = 48; + camera.attributes.AGCHIGH = 64; + cellCameraInstance.m_camera = camera; + } + // TODO: Some other default attributes? Need to check the actual behaviour on a real PS3. + cellCameraInstance.m_bInitialized = true; return CELL_OK; @@ -122,23 +172,231 @@ int cellCameraIsStarted() return CELL_OK; } -int cellCameraGetAttribute() +int cellCameraGetAttribute(s32 dev_num, CellCameraAttribute attrib, vm::ptr arg1, vm::ptr arg2) { - UNIMPLEMENTED_FUNC(cellCamera); + cellCamera->Warning("cellCameraGetAttribute(dev_num=%d, attrib=%s(%d), arg1=0x%x, arg2=0x%x)", dev_num, attributes[attrib], arg1.addr(), arg2.addr()); if (!cellCameraInstance.m_bInitialized) return CELL_CAMERA_ERROR_NOT_INIT; + if (attrib == 0) + *arg1 = cellCameraInstance.m_camera.attributes.GAIN; + else if (attrib == 1) + *arg1 = cellCameraInstance.m_camera.attributes.REDBLUEGAIN; + else if (attrib == 2) + *arg1 = cellCameraInstance.m_camera.attributes.SATURATION; + else if (attrib == 3) + *arg1 = cellCameraInstance.m_camera.attributes.EXPOSURE; + else if (attrib == 4) + *arg1 = cellCameraInstance.m_camera.attributes.BRIGHTNESS; + else if (attrib == 5) + *arg1 = cellCameraInstance.m_camera.attributes.AEC; + else if (attrib == 6) + *arg1 = cellCameraInstance.m_camera.attributes.AGC; + else if (attrib == 7) + *arg1 = cellCameraInstance.m_camera.attributes.AWB; + else if (attrib == 8) + *arg1 = cellCameraInstance.m_camera.attributes.ABC; + else if (attrib == 9) + *arg1 = cellCameraInstance.m_camera.attributes.LED; + else if (attrib == 10) + *arg1 = cellCameraInstance.m_camera.attributes.AUDIOGAIN; + else if (attrib == 11) + *arg1 = cellCameraInstance.m_camera.attributes.QS; + else if (attrib == 12) + { + *arg1 = cellCameraInstance.m_camera.attributes.NONZEROCOEFFS[0]; + *arg2 = cellCameraInstance.m_camera.attributes.NONZEROCOEFFS[1]; + } + else if (attrib == 13) + *arg1 = cellCameraInstance.m_camera.attributes.YUVFLAG; + else if (attrib == 14) + *arg1 = cellCameraInstance.m_camera.attributes.JPEGFLAG; + else if (attrib == 15) + *arg1 = cellCameraInstance.m_camera.attributes.BACKLIGHTCOMP; + else if (attrib == 16) + *arg1 = cellCameraInstance.m_camera.attributes.MIRRORFLAG; + else if (attrib == 17) + *arg1 = cellCameraInstance.m_camera.attributes.MEASUREDQS; + else if (attrib == 18) + *arg1 = cellCameraInstance.m_camera.attributes._422FLAG; + else if (attrib == 19) + *arg1 = cellCameraInstance.m_camera.attributes.USBLOAD; + else if (attrib == 20) + *arg1 = cellCameraInstance.m_camera.attributes.GAMMA; + else if (attrib == 21) + *arg1 = cellCameraInstance.m_camera.attributes.GREENGAIN; + else if (attrib == 22) + *arg1 = cellCameraInstance.m_camera.attributes.AGCLIMIT; + else if (attrib == 23) + *arg1 = cellCameraInstance.m_camera.attributes.DENOISE; + else if (attrib == 24) + *arg1 = cellCameraInstance.m_camera.attributes.FRAMERATEADJUST; + else if (attrib == 25) + *arg1 = cellCameraInstance.m_camera.attributes.PIXELOUTLIERFILTER; + else if (attrib == 26) + *arg1 = cellCameraInstance.m_camera.attributes.AGCLOW; + else if (attrib == 27) + *arg1 = cellCameraInstance.m_camera.attributes.AGCHIGH; + else if (attrib == 28) + *arg1 = cellCameraInstance.m_camera.attributes.DEVICELOCATION; + else if (attrib == 29) + *arg1 = cellCameraInstance.m_camera.attributes.FORMATCAP; + else if (attrib == 30) + *arg1 = cellCameraInstance.m_camera.attributes.FORMATINDEX; + else if (attrib == 31) + *arg1 = cellCameraInstance.m_camera.attributes.NUMFRAME; + else if (attrib == 32) + *arg1 = cellCameraInstance.m_camera.attributes.FRAMEINDEX; + else if (attrib == 33) + *arg1 = cellCameraInstance.m_camera.attributes.FRAMESIZE; + else if (attrib == 34) + *arg1 = cellCameraInstance.m_camera.attributes.INTERVALTYPE; + else if (attrib == 35) + *arg1 = cellCameraInstance.m_camera.attributes.INTERVALINDEX; + else if (attrib == 36) + *arg1 = cellCameraInstance.m_camera.attributes.INTERVALVALUE; + else if (attrib == 37) + *arg1 = cellCameraInstance.m_camera.attributes.COLORMATCHING; + else if (attrib == 38) + *arg1 = cellCameraInstance.m_camera.attributes.PLFREQ; + else if (attrib == 39) + *arg1 = cellCameraInstance.m_camera.attributes.DEVICEID; + else if (attrib == 40) + *arg1 = cellCameraInstance.m_camera.attributes.DEVICECAP; + else if (attrib == 41) + *arg1 = cellCameraInstance.m_camera.attributes.DEVICESPEED; + else if (attrib == 42) + *arg1 = cellCameraInstance.m_camera.attributes.UVCREQCODE; + else if (attrib == 43) + *arg1 = cellCameraInstance.m_camera.attributes.UVCREQDATA; + else if (attrib == 44) + *arg1 = cellCameraInstance.m_camera.attributes.DEVICEID2; + else if (attrib == 45) + *arg1 = cellCameraInstance.m_camera.attributes.READMODE; + else if (attrib == 46) + *arg1 = cellCameraInstance.m_camera.attributes.GAMEPID; + else if (attrib == 47) + *arg1 = cellCameraInstance.m_camera.attributes.PBUFFER; + else if (attrib == 48) + *arg1 = cellCameraInstance.m_camera.attributes.READFINISH; + else if (attrib == 49) + *arg1 = cellCameraInstance.m_camera.attributes.ATTRIBUTE_UNKNOWN; + return CELL_OK; } -int cellCameraSetAttribute() +int cellCameraSetAttribute(s32 dev_num, CellCameraAttribute attrib, u32 arg1, u32 arg2) { - UNIMPLEMENTED_FUNC(cellCamera); + cellCamera->Warning("cellCameraSetAttribute(dev_num=%d, attrib=%s(%d), arg1=%d, arg2=%d)", dev_num, attributes[attrib], attrib, arg1, arg2); if (!cellCameraInstance.m_bInitialized) return CELL_CAMERA_ERROR_NOT_INIT; + if (attrib == 0) + cellCameraInstance.m_camera.attributes.GAIN = arg1; + else if (attrib == 1) + cellCameraInstance.m_camera.attributes.REDBLUEGAIN = arg1; + else if (attrib == 2) + cellCameraInstance.m_camera.attributes.SATURATION = arg1; + else if (attrib == 3) + cellCameraInstance.m_camera.attributes.EXPOSURE = arg1; + else if (attrib == 4) + cellCameraInstance.m_camera.attributes.BRIGHTNESS = arg1; + else if (attrib == 5) + cellCameraInstance.m_camera.attributes.AEC = arg1; + else if (attrib == 6) + cellCameraInstance.m_camera.attributes.AGC = arg1; + else if (attrib == 7) + cellCameraInstance.m_camera.attributes.AWB = arg1; + else if (attrib == 8) + cellCameraInstance.m_camera.attributes.ABC = arg1; + else if (attrib == 9) + cellCameraInstance.m_camera.attributes.LED = arg1; + else if (attrib == 10) + cellCameraInstance.m_camera.attributes.AUDIOGAIN = arg1; + else if (attrib == 11) + cellCameraInstance.m_camera.attributes.QS = arg1; + else if (attrib == 12) + { + cellCameraInstance.m_camera.attributes.NONZEROCOEFFS[0] = arg1; + cellCameraInstance.m_camera.attributes.NONZEROCOEFFS[1] = arg2; + } + else if (attrib == 13) + cellCameraInstance.m_camera.attributes.YUVFLAG = arg1; + else if (attrib == 14) + cellCameraInstance.m_camera.attributes.JPEGFLAG = arg1; + else if (attrib == 15) + cellCameraInstance.m_camera.attributes.BACKLIGHTCOMP = arg1; + else if (attrib == 16) + cellCameraInstance.m_camera.attributes.MIRRORFLAG = arg1; + else if (attrib == 17) + return CELL_CAMERA_ERROR_PARAM; + else if (attrib == 18) + cellCameraInstance.m_camera.attributes._422FLAG = arg1; + else if (attrib == 19) + cellCameraInstance.m_camera.attributes.USBLOAD = arg1; + else if (attrib == 20) + cellCameraInstance.m_camera.attributes.GAMMA = arg1; + else if (attrib == 21) + cellCameraInstance.m_camera.attributes.GREENGAIN = arg1; + else if (attrib == 22) + cellCameraInstance.m_camera.attributes.AGCLIMIT = arg1; + else if (attrib == 23) + cellCameraInstance.m_camera.attributes.DENOISE = arg1; + else if (attrib == 24) + cellCameraInstance.m_camera.attributes.FRAMERATEADJUST = arg1; + else if (attrib == 25) + cellCameraInstance.m_camera.attributes.PIXELOUTLIERFILTER = arg1; + else if (attrib == 26) + cellCameraInstance.m_camera.attributes.AGCLOW = arg1; + else if (attrib == 27) + cellCameraInstance.m_camera.attributes.AGCHIGH = arg1; + else if (attrib == 28) + cellCameraInstance.m_camera.attributes.DEVICELOCATION = arg1; + else if (attrib == 29) + cellCamera->Error("Tried to write to read-only (?) value: FORMATCAP"); + else if (attrib == 30) + cellCameraInstance.m_camera.attributes.FORMATINDEX = arg1; + else if (attrib == 31) + cellCameraInstance.m_camera.attributes.NUMFRAME = arg1; + else if (attrib == 32) + cellCameraInstance.m_camera.attributes.FRAMEINDEX = arg1; + else if (attrib == 33) + cellCameraInstance.m_camera.attributes.FRAMESIZE = arg1; + else if (attrib == 34) + cellCameraInstance.m_camera.attributes.INTERVALTYPE = arg1; + else if (attrib == 35) + cellCameraInstance.m_camera.attributes.INTERVALINDEX = arg1; + else if (attrib == 36) + cellCameraInstance.m_camera.attributes.INTERVALVALUE = arg1; + else if (attrib == 37) + cellCameraInstance.m_camera.attributes.COLORMATCHING = arg1; + else if (attrib == 38) + cellCameraInstance.m_camera.attributes.PLFREQ = arg1; + else if (attrib == 39) + return CELL_CAMERA_ERROR_PARAM; + else if (attrib == 40) + cellCameraInstance.m_camera.attributes.DEVICECAP = arg1; + else if (attrib == 41) + cellCameraInstance.m_camera.attributes.DEVICESPEED = arg1; + else if (attrib == 42) + cellCameraInstance.m_camera.attributes.UVCREQCODE = arg1; + else if (attrib == 43) + cellCameraInstance.m_camera.attributes.UVCREQDATA = arg1; + else if (attrib == 44) + return CELL_CAMERA_ERROR_PARAM; + else if (attrib == 45) + cellCamera->Error("Tried to write to read-only (?) value: READMODE"); + else if (attrib == 46) + cellCameraInstance.m_camera.attributes.GAMEPID = arg1; + else if (attrib == 47) + cellCameraInstance.m_camera.attributes.PBUFFER = arg1; + else if (attrib == 48) + cellCameraInstance.m_camera.attributes.READFINISH = arg1; + else if (attrib == 49) + cellCamera->Error("Tried to write to read-only (?) value: ATTRIBUTE_UNKNOWN"); + return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellCamera.h b/rpcs3/Emu/SysCalls/Modules/cellCamera.h index c56aae37fa..f9242a4660 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellCamera.h +++ b/rpcs3/Emu/SysCalls/Modules/cellCamera.h @@ -18,6 +18,179 @@ enum CELL_CAMERA_ERROR_FATAL = 0x8014080f, }; +// Event types +enum +{ + CELL_CAMERA_EFLAG_FRAME_UPDATE = 0x00000001, + CELL_CAMERA_EFLAG_OPEN = 0x00000002, + CELL_CAMERA_EFLAG_CLOSE = 0x00000004, + CELL_CAMERA_EFLAG_START = 0x00000008, + CELL_CAMERA_EFLAG_STOP = 0x00000010, + CELL_CAMERA_EFLAG_RESET = 0x00000020, +}; + +// Colormatching +enum +{ + CELL_CAMERA_CM_CP_UNSPECIFIED = 0, + CELL_CAMERA_CM_CP_BT709_sRGB = 1, + CELL_CAMERA_CM_CP_BT470_2M = 2, + CELL_CAMERA_CM_CP_BT470_2BG = 3, + CELL_CAMERA_CM_CP_SMPTE170M = 4, + CELL_CAMERA_CM_CP_SMPTE240M = 5, + + CELL_CAMERA_CM_TC_UNSPECIFIED = 0, + CELL_CAMERA_CM_TC_BT709 = 1, + CELL_CAMERA_CM_TC_BT470_2M = 2, + CELL_CAMERA_CM_TC_BT470_2BG = 3, + CELL_CAMERA_CM_TC_SMPTE170M = 4, + CELL_CAMERA_CM_TC_SMPTE240M = 5, + CELL_CAMERA_CM_TC_LINEAR = 6, + CELL_CAMERA_CM_TC_sRGB = 7, + + CELL_CAMERA_CM_MC_UNSPECIFIED = 0, + CELL_CAMERA_CM_MC_BT709 = 1, + CELL_CAMERA_CM_MC_FCC = 2, + CELL_CAMERA_CM_MC_BT470_2BG = 3, + CELL_CAMERA_CM_MC_SMPTE170M = 4, + CELL_CAMERA_CM_MC_SMPTE240M = 5, +}; + +// Power Line Frequency +enum +{ + CELL_CAMERA_PLFREQ_DISABLED = 0, + CELL_CAMERA_PLFREQ_50Hz = 1, + CELL_CAMERA_PLFREQ_60Hz = 2, +}; + +// DEVICECAP +enum +{ + CELL_CAMERA_CTC_SCANNING_MODE = (1 << 0), + CELL_CAMERA_CTC_AUTO_EXPOSURE_MODE = (1 << 1), + CELL_CAMERA_CTC_AUTO_EXPOSURE_PRIORITY = (1 << 2), + CELL_CAMERA_CTC_EXPOSURE_TIME_ABS = (1 << 3), + CELL_CAMERA_CTC_EXPOSURE_TIME_REL = (1 << 4), + CELL_CAMERA_CTC_FOCUS_ABS = (1 << 5), + CELL_CAMERA_CTC_FOCUS_REL = (1 << 6), + CELL_CAMERA_CTC_IRIS_ABS = (1 << 7), + CELL_CAMERA_CTC_IRIS_REL = (1 << 8), + CELL_CAMERA_CTC_ZOOM_ABS = (1 << 9), + CELL_CAMERA_CTC_ZOOM_REL = (1 << 10), + CELL_CAMERA_CTC_PANTILT_ABS = (1 << 11), + CELL_CAMERA_CTC_PANTILT_REL = (1 << 12), + CELL_CAMERA_CTC_ROLL_ABS = (1 << 13), + CELL_CAMERA_CTC_ROLL_REL = (1 << 14), + CELL_CAMERA_CTC_RESERVED_15 = (1 << 15), + CELL_CAMERA_CTC_RESERVED_16 = (1 << 16), + CELL_CAMERA_CTC_FOCUS_AUTO = (1 << 17), + CELL_CAMERA_CTC_PRIVACY = (1 << 18), + + CELL_CAMERA_PUC_BRIGHTNESS = (1 << 0), + CELL_CAMERA_PUC_CONTRAST = (1 << 1), + CELL_CAMERA_PUC_HUE = (1 << 2), + CELL_CAMERA_PUC_SATURATION = (1 << 3), + CELL_CAMERA_PUC_SHARPNESS = (1 << 4), + CELL_CAMERA_PUC_GAMMA = (1 << 5), + CELL_CAMERA_PUC_WHITE_BALANCE_TEMPERATURE = (1 << 6), + CELL_CAMERA_PUC_WHITE_BALANCE_COMPONENT = (1 << 7), + CELL_CAMERA_PUC_BACKLIGHT_COMPENSATION = (1 << 8), + CELL_CAMERA_PUC_GAIN = (1 << 9), + CELL_CAMERA_PUC_POWER_LINE_FREQUENCY = (1 << 10), + CELL_CAMERA_PUC_HUE_AUTO = (1 << 11), + CELL_CAMERA_PUC_WHITE_BALANCE_TEMPERATURE_AUTO = (1 << 12), + CELL_CAMERA_PUC_WHITE_BALANCE_COMPONENT_AUTO = (1 << 13), + CELL_CAMERA_PUC_DIGITAL_MULTIPLIER = (1 << 14), + CELL_CAMERA_PUC_DIGITAL_MULTIPLIER_LIMIT = (1 << 15), + CELL_CAMERA_PUC_ANALOG_VIDEO_STANDARD = (1 << 16), + CELL_CAMERA_PUC_ANALOG_VIDEO_LOCK_STATUS = (1 << 17), +}; + +// UVCREQCODE Control Selector +enum +{ + CELL_CAMERA_CS_SHIFT = 0, + CELL_CAMERA_CS_BITS = 0x000000ff, + CELL_CAMERA_CAP_SHIFT = 8, + CELL_CAMERA_CAP_BITS = 0x0000ff00, + CELL_CAMERA_NUM_SHIFT = 16, + CELL_CAMERA_NUM_BITS = 0x000f0000, + CELL_CAMERA_NUM_1 = 0x00010000, + CELL_CAMERA_NUM_2 = 0x00020000, + CELL_CAMERA_NUM_3 = 0x00030000, + CELL_CAMERA_NUM_4 = 0x00040000, + CELL_CAMERA_LEN_SHIFT = 20, + CELL_CAMERA_LEN_BITS = 0x00f00000, + CELL_CAMERA_LEN_1 = 0x00100000, + CELL_CAMERA_LEN_2 = 0x00200000, + CELL_CAMERA_LEN_4 = 0x00400000, + CELL_CAMERA_ID_SHIFT = 24, + CELL_CAMERA_ID_BITS = 0x0f000000, + CELL_CAMERA_ID_CT = 0x01000000, + CELL_CAMERA_ID_SU = 0x02000000, + CELL_CAMERA_ID_PU = 0x04000000, +}; + +// UVCREQCODE Camera Terminal Control +enum +{ + CELL_CAMERA_UVC_SCANNING_MODE = 0x01110001, + CELL_CAMERA_UVC_AUTO_EXPOSURE_MODE = 0x01110102, + CELL_CAMERA_UVC_AUTO_EXPOSURE_PRIORITY = 0x01110203, + CELL_CAMERA_UVC_EXPOSURE_TIME_ABS = 0x01410304, + CELL_CAMERA_UVC_EXPOSURE_TIME_REL = 0x01110405, + CELL_CAMERA_UVC_FOCUS_ABS = 0x01210506, + CELL_CAMERA_UVC_FOCUS_REL = 0x01120607, + CELL_CAMERA_UVC_FOCUS_AUTO = 0x01111108, + CELL_CAMERA_UVC_IRIS_ABS = 0x01210709, + CELL_CAMERA_UVC_IRIS_REL = 0x0111080a, + CELL_CAMERA_UVC_ZOOM_ABS = 0x0121090b, + CELL_CAMERA_UVC_ZOOM_REL = 0x01130a0c, + CELL_CAMERA_UVC_PANTILT_ABS = 0x01420b0d, + CELL_CAMERA_UVC_PANTILT_REL = 0x01140c0e, + CELL_CAMERA_UVC_ROLL_ABS = 0x01210d0f, + CELL_CAMERA_UVC_ROLL_REL = 0x01120e10, + CELL_CAMERA_UVC_PRIVACY = 0x01111211, +}; + +// UVCREQCODE Selector Unit Control/Processing Unit Control +enum +{ + CELL_CAMERA_UVC_INPUT_SELECT = 0x02110101, + + CELL_CAMERA_UVC_BACKLIGHT_COMPENSATION = 0x04210801, + CELL_CAMERA_UVC_BRIGHTNESS = 0x04210002, + CELL_CAMERA_UVC_CONTRAST = 0x04210103, + CELL_CAMERA_UVC_GAIN = 0x04210904, + CELL_CAMERA_UVC_POWER_LINE_FREQUENCY = 0x04110a05, + CELL_CAMERA_UVC_HUE = 0x04210206, + CELL_CAMERA_UVC_HUE_AUTO = 0x04110b10, + CELL_CAMERA_UVC_SATURATION = 0x04210307, + CELL_CAMERA_UVC_SHARPNESS = 0x04210408, + CELL_CAMERA_UVC_GAMMA = 0x04210509, + CELL_CAMERA_UVC_WHITE_BALANCE_TEMPERATURE = 0x0421060a, + CELL_CAMERA_UVC_WHITE_BALANCE_TEMPERATURE_AUTO = 0x04110c0b, + CELL_CAMERA_UVC_WHITE_BALANCE_COMPONENT = 0x0422070c, + CELL_CAMERA_UVC_WHITE_BALANCE_COMPONENT_AUTO = 0x04110d0d, + CELL_CAMERA_UVC_DIGITAL_MULTIPLIER = 0x04210e0e, + CELL_CAMERA_UVC_DIGITAL_MULTIPLIER_LIMIT = 0x04210f0f, + CELL_CAMERA_UVC_ANALOG_VIDEO_STANDARD = 0x04111011, + CELL_CAMERA_UVC_ANALOG_VIDEO_LOCK_STATUS = 0x04111112, +}; + +// UVCREQCODE Request code bits +enum +{ + CELL_CAMERA_RC_CUR = 0x81, + CELL_CAMERA_RC_MIN = 0x82, + CELL_CAMERA_RC_MAX = 0x83, + CELL_CAMERA_RC_RES = 0x84, + CELL_CAMERA_RC_LEN = 0x85, + CELL_CAMERA_RC_INFO = 0x86, + CELL_CAMERA_RC_DEF = 0x87, +}; + // Camera types enum CellCameraType { @@ -41,7 +214,7 @@ enum CellCameraFormat CELL_CAMERA_Y0_U_Y1_V = CELL_CAMERA_YUV422, }; -// Image resolutiom +// Image resolution enum CellCameraResolution { CELL_CAMERA_RESOLUTION_UNKNOWN, @@ -51,6 +224,64 @@ enum CellCameraResolution CELL_CAMERA_SPECIFIED_WIDTH_HEIGHT, }; +// Camera attributes +enum CellCameraAttribute +{ + CELL_CAMERA_GAIN, + CELL_CAMERA_REDBLUEGAIN, + CELL_CAMERA_SATURATION, + CELL_CAMERA_EXPOSURE, + CELL_CAMERA_BRIGHTNESS, + CELL_CAMERA_AEC, + CELL_CAMERA_AGC, + CELL_CAMERA_AWB, + CELL_CAMERA_ABC, + CELL_CAMERA_LED, + CELL_CAMERA_AUDIOGAIN, + CELL_CAMERA_QS, + CELL_CAMERA_NONZEROCOEFFS, + CELL_CAMERA_YUVFLAG, + CELL_CAMERA_JPEGFLAG, + CELL_CAMERA_BACKLIGHTCOMP, + CELL_CAMERA_MIRRORFLAG, + CELL_CAMERA_MEASUREDQS, + CELL_CAMERA_422FLAG, + CELL_CAMERA_USBLOAD, + CELL_CAMERA_GAMMA, + CELL_CAMERA_GREENGAIN, + CELL_CAMERA_AGCLIMIT, + CELL_CAMERA_DENOISE, + CELL_CAMERA_FRAMERATEADJUST, + CELL_CAMERA_PIXELOUTLIERFILTER, + CELL_CAMERA_AGCLOW, + CELL_CAMERA_AGCHIGH, + CELL_CAMERA_DEVICELOCATION, + + CELL_CAMERA_FORMATCAP = 100, + CELL_CAMERA_FORMATINDEX, + CELL_CAMERA_NUMFRAME, + CELL_CAMERA_FRAMEINDEX, + CELL_CAMERA_FRAMESIZE, + CELL_CAMERA_INTERVALTYPE, + CELL_CAMERA_INTERVALINDEX, + CELL_CAMERA_INTERVALVALUE, + CELL_CAMERA_COLORMATCHING, + CELL_CAMERA_PLFREQ, + CELL_CAMERA_DEVICEID, + CELL_CAMERA_DEVICECAP, + CELL_CAMERA_DEVICESPEED, + CELL_CAMERA_UVCREQCODE, + CELL_CAMERA_UVCREQDATA, + CELL_CAMERA_DEVICEID2, + + CELL_CAMERA_READMODE = 300, + CELL_CAMERA_GAMEPID, + CELL_CAMERA_PBUFFER, + CELL_CAMERA_READFINISH, + + CELL_CAMERA_ATTRIBUTE_UNKNOWN = 500, +}; + struct CellCameraInfoEx { CellCameraFormat format; @@ -68,6 +299,71 @@ struct CellCameraInfoEx be_t pbuf[2]; }; +// Custom struct for keeping track of camera attributes +struct CellCameraAttributes +{ + u32 GAIN; + u32 REDBLUEGAIN; + u32 SATURATION; + u32 EXPOSURE; + u32 BRIGHTNESS; + u32 AEC; + u32 AGC; + u32 AWB; + u32 ABC; + u32 LED; + u32 AUDIOGAIN; + u32 QS; + u32 NONZEROCOEFFS[1]; + u32 YUVFLAG; + u32 JPEGFLAG; + u32 BACKLIGHTCOMP; + u32 MIRRORFLAG; + u32 MEASUREDQS; + u32 _422FLAG; + u32 USBLOAD; + u32 GAMMA; + u32 GREENGAIN; + u32 AGCLIMIT; + u32 DENOISE; + u32 FRAMERATEADJUST; + u32 PIXELOUTLIERFILTER; + u32 AGCLOW; + u32 AGCHIGH; + u32 DEVICELOCATION; + + u32 FORMATCAP = 100; + u32 FORMATINDEX; + u32 NUMFRAME; + u32 FRAMEINDEX; + u32 FRAMESIZE; + u32 INTERVALTYPE; + u32 INTERVALINDEX; + u32 INTERVALVALUE; + u32 COLORMATCHING; + u32 PLFREQ; + u32 DEVICEID; + u32 DEVICECAP; + u32 DEVICESPEED; + u32 UVCREQCODE; + u32 UVCREQDATA; + u32 DEVICEID2; + + u32 READMODE = 300; + u32 GAMEPID; + u32 PBUFFER; + u32 READFINISH; + + u32 ATTRIBUTE_UNKNOWN = 500; +}; + +// Custom struct to keep track of cameras +struct CellCamera +{ + CellCameraAttributes attributes; + CellCameraInfoEx info; +}; + struct CellCameraReadEx { be_t version; diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp index 292ca71c30..23659a60e5 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp @@ -538,7 +538,7 @@ int cellGcmSetSecondVFrequency(u32 freq) switch (freq) { case CELL_GCM_DISPLAY_FREQUENCY_59_94HZ: - Emu.GetGSManager().GetRender().m_frequency_mode = freq; cellGcmSys->Todo("Unimplemented display frequency: 59.94Hz"); break; + Emu.GetGSManager().GetRender().m_frequency_mode = freq; Emu.GetGSManager().GetRender().m_fps_limit = 59.94; break; case CELL_GCM_DISPLAY_FREQUENCY_SCANOUT: Emu.GetGSManager().GetRender().m_frequency_mode = freq; cellGcmSys->Todo("Unimplemented display frequency: Scanout"); break; case CELL_GCM_DISPLAY_FREQUENCY_DISABLE: diff --git a/rpcs3/Emu/SysCalls/Modules/cellGem.cpp b/rpcs3/Emu/SysCalls/Modules/cellGem.cpp index 118a428a0a..2d629dd16d 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGem.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGem.cpp @@ -9,6 +9,7 @@ Module *cellGem = nullptr; struct cellGemInternal { bool m_bInitialized; + CellGemAttribute attribute; cellGemInternal() : m_bInitialized(false) @@ -180,13 +181,19 @@ int cellGemGetInertialState() return CELL_OK; } -int cellGemGetInfo() +int cellGemGetInfo(vm::ptr info) { - UNIMPLEMENTED_FUNC(cellGem); + cellGem->Warning("cellGemGetInfo(info=0x%x)", info.addr()); if (!cellGemInstance.m_bInitialized) return CELL_GEM_ERROR_UNINITIALIZED; + info->max_connect = cellGemInstance.attribute.max_connect; + // TODO: Support many controllers to be connected + info->now_connect = 1; + info->status[0] = CELL_GEM_STATUS_READY; + info->port[0] = 7; + return CELL_OK; } @@ -264,6 +271,7 @@ int cellGemInit(vm::ptr attribute) return CELL_GEM_ERROR_ALREADY_INITIALIZED; cellGemInstance.m_bInitialized = true; + cellGemInstance.attribute = *attribute; return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/cellFs.cpp b/rpcs3/Emu/SysCalls/lv2/cellFs.cpp index ca72b045ac..9a77ad0c51 100644 --- a/rpcs3/Emu/SysCalls/lv2/cellFs.cpp +++ b/rpcs3/Emu/SysCalls/lv2/cellFs.cpp @@ -41,7 +41,8 @@ struct FsRingBufferConfig s32 cellFsOpen(vm::ptr path, s32 flags, vm::ptr> fd, vm::ptr arg, u64 size) { - sys_fs->Log("cellFsOpen(path=0x%x, flags=0x%x, fd=0x%x, arg=0x%x, size=0x%llx)", path, flags, fd, arg, size); + sys_fs->Log("cellFsOpen(path_addr=0x%x, flags=0x%x, fd=0x%x, arg=0x%x, size=0x%llx)", path.addr(), flags, fd, arg, size); + sys_fs->Log("cellFsOpen(path='%s')", path.get_ptr()); const std::string _path = path.get_ptr(); @@ -171,7 +172,8 @@ s32 cellFsClose(u32 fd) s32 cellFsOpendir(vm::ptr path, vm::ptr fd) { - sys_fs->Warning("cellFsOpendir(path=0x%x, fd=0x%x)", path, fd); + sys_fs->Warning("cellFsOpendir(path_addr=0x%x, fd=0x%x)", path.addr(), fd); + sys_fs->Warning("cellFsOpendir(path='%s')", path.get_ptr()); std::shared_ptr dir(Emu.GetVFS().OpenDir(path.get_ptr())); if (!dir || !dir->IsOpened()) @@ -219,7 +221,8 @@ s32 cellFsClosedir(u32 fd) s32 cellFsStat(vm::ptr path, vm::ptr sb) { - sys_fs->Warning("cellFsStat(path=0x%x, sb=0x%x)", path, sb); + sys_fs->Warning("cellFsStat(path_addr=0x%x, sb=0x%x)", path.addr(), sb); + sys_fs->Warning("cellFsStat(path='%s')", path.get_ptr()); const std::string _path = path.get_ptr(); @@ -327,7 +330,8 @@ s32 cellFsFstat(u32 fd, vm::ptr sb) s32 cellFsMkdir(vm::ptr path, u32 mode) { - sys_fs->Warning("cellFsMkdir(path=0x%x, mode=0x%x)", path, mode); + sys_fs->Warning("cellFsMkdir(path_addr=0x%x, mode=0x%x)", path.addr(), mode); + sys_fs->Warning("cellFsMkdir(path='%s')", path.get_ptr()); const std::string _path = path.get_ptr(); @@ -343,7 +347,8 @@ s32 cellFsMkdir(vm::ptr path, u32 mode) s32 cellFsRename(vm::ptr from, vm::ptr to) { - sys_fs->Warning("cellFsRename(from=0x%x, to=0x%x)", from, to); + sys_fs->Warning("cellFsRename(from_addr=0x%x, to_addr=0x%x)", from.addr(), to.addr()); + sys_fs->Warning("cellFsRename(from='%s', to='%s')", from.get_ptr(), to.get_ptr()); std::string _from = from.get_ptr(); std::string _to = to.get_ptr(); @@ -377,7 +382,8 @@ s32 cellFsRename(vm::ptr from, vm::ptr to) } s32 cellFsChmod(vm::ptr path, u32 mode) { - sys_fs->Todo("cellFsChmod(path=0x%x, mode=0x%x)", path, mode); + sys_fs->Todo("cellFsChmod(path_addr=0x%x, mode=0x%x)", path.addr(), mode); + sys_fs->Todo("cellFsChmod(path='%s')", path.get_ptr()); // TODO: @@ -395,7 +401,8 @@ s32 cellFsFsync(u32 fd) s32 cellFsRmdir(vm::ptr path) { - sys_fs->Warning("cellFsRmdir(path=0x%x)", path); + sys_fs->Warning("cellFsRmdir(path_addr=0x%x)", path.addr()); + sys_fs->Warning("cellFsRmdir(path='%s')", path.get_ptr()); std::string _path = path.get_ptr(); @@ -412,7 +419,8 @@ s32 cellFsRmdir(vm::ptr path) s32 cellFsUnlink(vm::ptr path) { - sys_fs->Warning("cellFsUnlink(path=0x%x)", path); + sys_fs->Warning("cellFsUnlink(path_addr=0x%x)", path.addr()); + sys_fs->Warning("cellFsUnlink(path='%s')", path.get_ptr()); std::string _path = path.get_ptr(); @@ -484,7 +492,8 @@ s32 cellFsFtruncate(u32 fd, u64 size) s32 cellFsTruncate(vm::ptr path, u64 size) { - sys_fs->Warning("cellFsTruncate(path=0x%x, size=0x%llx)", path, size); + sys_fs->Warning("cellFsTruncate(path_addr=0x%x, size=0x%llx)", path.addr(), size); + sys_fs->Warning("cellFsTruncate(path='%s')", path.get_ptr()); vfsFile f(path.get_ptr(), vfsReadWrite); if (!f.IsOpened()) @@ -530,7 +539,8 @@ s32 cellFsFGetBlockSize(u32 fd, vm::ptr sector_size, vm::ptr block_siz s32 cellFsGetBlockSize(vm::ptr path, vm::ptr sector_size, vm::ptr block_size) { - sys_fs->Warning("cellFsGetBlockSize(path=0x%x, sector_size=0x%x, block_size=0x%x)", path, sector_size, block_size); + sys_fs->Warning("cellFsGetBlockSize(path_addr=0x%x, sector_size=0x%x, block_size=0x%x)", path.addr(), sector_size, block_size); + sys_fs->Warning("cellFsGetBlockSize(path='%s')", path.get_ptr()); *sector_size = 4096; // ? *block_size = 4096; // ? @@ -540,7 +550,8 @@ s32 cellFsGetBlockSize(vm::ptr path, vm::ptr sector_size, vm::p s32 cellFsGetFreeSize(vm::ptr path, vm::ptr block_size, vm::ptr block_count) { - sys_fs->Warning("cellFsGetFreeSize(path=0x%x, block_size=0x%x, block_count=0x%x)", path, block_size, block_count); + sys_fs->Warning("cellFsGetFreeSize(path_addr=0x%x, block_size=0x%x, block_count=0x%x)", path.addr(), block_size, block_count); + sys_fs->Warning("cellFsGetFreeSize(path='%s')", path.get_ptr()); // TODO: Get real values. Currently, it always returns 40 GB of free space divided in 4 KB blocks *block_size = 4096; // ? @@ -857,7 +868,8 @@ int sdata_unpack(const std::string& packed_file, const std::string& unpacked_fil s32 cellFsSdataOpen(vm::ptr path, s32 flags, vm::ptr> fd, vm::ptr arg, u64 size) { - sys_fs->Warning("cellFsSdataOpen(path=0x%x, flags=0x%x, fd=0x%x, arg=0x%x, size=0x%llx) -> cellFsOpen()", path, flags, fd, arg, size); + sys_fs->Warning("cellFsSdataOpen(path_addr=0x%x, flags=0x%x, fd=0x%x, arg=0x%x, size=0x%llx) -> cellFsOpen()", path.addr(), flags, fd, arg, size); + sys_fs->Warning("cellFsSdataOpen(path='%s')", path.get_ptr()); /*if (flags != CELL_O_RDONLY) return CELL_EINVAL; @@ -983,7 +995,8 @@ s32 cellFsAioWrite(vm::ptr aio, vm::ptr id, vm::ptr mount_point) { - sys_fs->Warning("cellFsAioInit(mount_point=0x%x)", mount_point); + sys_fs->Warning("cellFsAioInit(mount_point_addr=0x%x)", mount_point.addr()); + sys_fs->Warning("cellFsAioInit(mount_point='%s')", mount_point.get_ptr()); aio_init = true; return CELL_OK; @@ -991,7 +1004,8 @@ s32 cellFsAioInit(vm::ptr mount_point) s32 cellFsAioFinish(vm::ptr mount_point) { - sys_fs->Warning("cellFsAioFinish(mount_point=0x%x)", mount_point); + sys_fs->Warning("cellFsAioFinish(mount_point_addr=0x%x)", mount_point.addr()); + sys_fs->Warning("cellFsAioFinish(mount_point='%s')", mount_point.get_ptr()); //aio_init = false; return CELL_OK; diff --git a/rpcs3/Gui/MainFrame.cpp b/rpcs3/Gui/MainFrame.cpp index 975af52f18..72f992a999 100644 --- a/rpcs3/Gui/MainFrame.cpp +++ b/rpcs3/Gui/MainFrame.cpp @@ -475,6 +475,7 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event)) #endif cbox_camera->Append("Null"); + cbox_camera->Append("Connected"); cbox_camera_type->Append("Unknown"); cbox_camera_type->Append("EyeToy"); diff --git a/rpcs3/Ini.h b/rpcs3/Ini.h index 6b3b9b1e02..6f2b9a7a11 100644 --- a/rpcs3/Ini.h +++ b/rpcs3/Ini.h @@ -268,7 +268,7 @@ public: AudioConvertToU16.Load(false); // Camera - Camera.Load(0); + Camera.Load(1); CameraType.Load(2); // Input/Ouput