diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/common/common_paths.h | 2 | ||||
-rw-r--r-- | src/common/file_util.cpp | 77 | ||||
-rw-r--r-- | src/core/arm/interpreter/arminit.cpp | 4 | ||||
-rw-r--r-- | src/core/arm/skyeye_common/armdefs.h | 23 | ||||
-rw-r--r-- | src/core/hle/service/y2r_u.cpp | 19 | ||||
-rw-r--r-- | src/video_core/debug_utils/debug_utils.cpp | 6 | ||||
-rw-r--r-- | src/video_core/rasterizer.cpp | 21 |
7 files changed, 116 insertions, 36 deletions
diff --git a/src/common/common_paths.h b/src/common/common_paths.h index 0ecf2d9de..eb43d589f 100644 --- a/src/common/common_paths.h +++ b/src/common/common_paths.h @@ -25,7 +25,7 @@ #ifdef USER_DIR #define EMU_DATA_DIR USER_DIR #else - #define EMU_DATA_DIR ".citra-emu" + #define EMU_DATA_DIR "citra-emu" #endif #endif diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp index 457376bf4..4ef4918d7 100644 --- a/src/common/file_util.cpp +++ b/src/common/file_util.cpp @@ -16,7 +16,10 @@ #include <tchar.h> #else #include <sys/param.h> +#include <sys/types.h> #include <dirent.h> +#include <pwd.h> +#include <unistd.h> #endif #if defined(__APPLE__) @@ -632,6 +635,55 @@ std::string& GetExeDirectory() } return exe_path; } +#else +/** + * @return The user’s home directory on POSIX systems + */ +static const std::string& GetHomeDirectory() { + static std::string home_path; + if (home_path.empty()) { + const char* envvar = getenv("HOME"); + if (envvar) { + home_path = envvar; + } else { + auto pw = getpwuid(getuid()); + ASSERT_MSG(pw, "$HOME isn’t defined, and the current user can’t be found in /etc/passwd."); + home_path = pw->pw_dir; + } + } + return home_path; +} + +/** + * Follows the XDG Base Directory Specification to get a directory path + * @param envvar The XDG environment variable to get the value from + * @return The directory path + * @sa http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html + */ +static const std::string GetUserDirectory(const std::string& envvar) { + const char* directory = getenv(envvar.c_str()); + + std::string user_dir; + if (directory) { + user_dir = directory; + } else { + std::string subdirectory; + if (envvar == "XDG_DATA_HOME") + subdirectory = DIR_SEP ".local" DIR_SEP "share"; + else if (envvar == "XDG_CONFIG_HOME") + subdirectory = DIR_SEP ".config"; + else if (envvar == "XDG_CACHE_HOME") + subdirectory = DIR_SEP ".cache"; + else + ASSERT_MSG(false, "Unknown XDG variable %s.", envvar.c_str()); + user_dir = GetHomeDirectory() + subdirectory; + } + + ASSERT_MSG(!user_dir.empty(), "User directory %s musn’t be empty.", envvar.c_str()); + ASSERT_MSG(user_dir[0] == '/', "User directory %s must be absolute.", envvar.c_str()); + + return user_dir; +} #endif std::string GetSysDirectory() @@ -661,20 +713,27 @@ const std::string& GetUserPath(const unsigned int DirIDX, const std::string &new if (paths[D_USER_IDX].empty()) { #ifdef _WIN32 - paths[D_USER_IDX] = GetExeDirectory() + DIR_SEP USERDATA_DIR DIR_SEP; + paths[D_USER_IDX] = GetExeDirectory() + DIR_SEP USERDATA_DIR DIR_SEP; + paths[D_CONFIG_IDX] = paths[D_USER_IDX] + CONFIG_DIR DIR_SEP; + paths[D_CACHE_IDX] = paths[D_USER_IDX] + CACHE_DIR DIR_SEP; #else - if (FileUtil::Exists(ROOT_DIR DIR_SEP USERDATA_DIR)) - paths[D_USER_IDX] = ROOT_DIR DIR_SEP USERDATA_DIR DIR_SEP; - else - paths[D_USER_IDX] = std::string(getenv("HOME") ? - getenv("HOME") : getenv("PWD") ? - getenv("PWD") : "") + DIR_SEP EMU_DATA_DIR DIR_SEP; + if (FileUtil::Exists(ROOT_DIR DIR_SEP USERDATA_DIR)) { + paths[D_USER_IDX] = ROOT_DIR DIR_SEP USERDATA_DIR DIR_SEP; + paths[D_CONFIG_IDX] = paths[D_USER_IDX] + CONFIG_DIR DIR_SEP; + paths[D_CACHE_IDX] = paths[D_USER_IDX] + CACHE_DIR DIR_SEP; + } else { + std::string data_dir = GetUserDirectory("XDG_DATA_HOME"); + std::string config_dir = GetUserDirectory("XDG_CONFIG_HOME"); + std::string cache_dir = GetUserDirectory("XDG_CACHE_HOME"); + + paths[D_USER_IDX] = data_dir + DIR_SEP EMU_DATA_DIR DIR_SEP; + paths[D_CONFIG_IDX] = config_dir + DIR_SEP EMU_DATA_DIR DIR_SEP; + paths[D_CACHE_IDX] = cache_dir + DIR_SEP EMU_DATA_DIR DIR_SEP; + } #endif - paths[D_CONFIG_IDX] = paths[D_USER_IDX] + CONFIG_DIR DIR_SEP; paths[D_GAMECONFIG_IDX] = paths[D_USER_IDX] + GAMECONFIG_DIR DIR_SEP; paths[D_MAPS_IDX] = paths[D_USER_IDX] + MAPS_DIR DIR_SEP; - paths[D_CACHE_IDX] = paths[D_USER_IDX] + CACHE_DIR DIR_SEP; paths[D_SDMC_IDX] = paths[D_USER_IDX] + SDMC_DIR DIR_SEP; paths[D_NAND_IDX] = paths[D_USER_IDX] + NAND_DIR DIR_SEP; paths[D_SYSDATA_IDX] = paths[D_USER_IDX] + SYSDATA_DIR DIR_SEP; diff --git a/src/core/arm/interpreter/arminit.cpp b/src/core/arm/interpreter/arminit.cpp index abafe226e..4ac827e0a 100644 --- a/src/core/arm/interpreter/arminit.cpp +++ b/src/core/arm/interpreter/arminit.cpp @@ -58,11 +58,7 @@ void ARMul_SelectProcessor(ARMul_State* state, unsigned properties) state->is_v4 = (properties & (ARM_v4_Prop | ARM_v5_Prop)) != 0; state->is_v5 = (properties & ARM_v5_Prop) != 0; state->is_v5e = (properties & ARM_v5e_Prop) != 0; - state->is_XScale = (properties & ARM_XScale_Prop) != 0; - state->is_iWMMXt = (properties & ARM_iWMMXt_Prop) != 0; state->is_v6 = (properties & ARM_v6_Prop) != 0; - state->is_ep9312 = (properties & ARM_ep9312_Prop) != 0; - state->is_pxa27x = (properties & ARM_PXA27X_Prop) != 0; state->is_v7 = (properties & ARM_v7_Prop) != 0; // Only initialse the coprocessor support once we diff --git a/src/core/arm/skyeye_common/armdefs.h b/src/core/arm/skyeye_common/armdefs.h index 070fcf7dc..16f3ac86c 100644 --- a/src/core/arm/skyeye_common/armdefs.h +++ b/src/core/arm/skyeye_common/armdefs.h @@ -185,10 +185,6 @@ So, if lateabtSig=1, then it means Late Abort Model(Base Updated Abort Model) bool is_v5e; // Are we emulating a v5e architecture? bool is_v6; // Are we emulating a v6 architecture? bool is_v7; // Are we emulating a v7 architecture? - bool is_XScale; // Are we emulating an XScale architecture? - bool is_iWMMXt; // Are we emulating an iWMMXt co-processor? - bool is_ep9312; // Are we emulating a Cirrus Maverick co-processor? - bool is_pxa27x; // Are we emulating a Intel PXA27x co-processor? // ARM_ARM A2-18 // 0 Base Restored Abort Model, 1 the Early Abort Model, 2 Base Updated Abort Model @@ -211,20 +207,11 @@ So, if lateabtSig=1, then it means Late Abort Model(Base Updated Abort Model) \***************************************************************************/ enum { - ARM_Nexec_Prop = 0x02, - ARM_Debug_Prop = 0x10, - ARM_Isync_Prop = ARM_Debug_Prop, - ARM_Lock_Prop = 0x20, - ARM_v4_Prop = 0x40, - ARM_v5_Prop = 0x80, - ARM_v6_Prop = 0xc0, - - ARM_v5e_Prop = 0x100, - ARM_XScale_Prop = 0x200, - ARM_ep9312_Prop = 0x400, - ARM_iWMMXt_Prop = 0x800, - ARM_PXA27X_Prop = 0x1000, - ARM_v7_Prop = 0x2000, + ARM_v4_Prop = 0x01, + ARM_v5_Prop = 0x02, + ARM_v5e_Prop = 0x04, + ARM_v6_Prop = 0x08, + ARM_v7_Prop = 0x10, }; /***************************************************************************\ diff --git a/src/core/hle/service/y2r_u.cpp b/src/core/hle/service/y2r_u.cpp index a58e04d6d..6607965e1 100644 --- a/src/core/hle/service/y2r_u.cpp +++ b/src/core/hle/service/y2r_u.cpp @@ -11,6 +11,8 @@ namespace Y2R_U { +static Kernel::SharedPtr<Kernel::Event> completion_event = 0; + /** * Y2R_U::IsBusyConversion service function * Outputs: @@ -26,13 +28,26 @@ static void IsBusyConversion(Service::Interface* self) { LOG_WARNING(Service, "(STUBBED) called"); } +/** + * Y2R_U::GetTransferEndEvent service function + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + * 3 : The handle of the completion event + */ +static void GetTransferEndEvent(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + cmd_buff[1] = RESULT_SUCCESS.raw; + cmd_buff[3] = Kernel::g_handle_table.Create(completion_event).MoveFrom(); +} + const Interface::FunctionInfo FunctionTable[] = { {0x00010040, nullptr, "SetInputFormat"}, {0x00030040, nullptr, "SetOutputFormat"}, {0x00050040, nullptr, "SetRotation"}, {0x00070040, nullptr, "SetBlockAlignment"}, {0x000D0040, nullptr, "SetTransferEndInterrupt"}, - {0x000F0000, nullptr, "GetTransferEndEvent"}, + {0x000F0000, GetTransferEndEvent, "GetTransferEndEvent"}, {0x00100102, nullptr, "SetSendingY"}, {0x00110102, nullptr, "SetSendingU"}, {0x00120102, nullptr, "SetSendingV"}, @@ -53,6 +68,8 @@ const Interface::FunctionInfo FunctionTable[] = { // Interface class Interface::Interface() { + completion_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "Y2R:Completed"); + Register(FunctionTable); } diff --git a/src/video_core/debug_utils/debug_utils.cpp b/src/video_core/debug_utils/debug_utils.cpp index 0beb72e6b..795449423 100644 --- a/src/video_core/debug_utils/debug_utils.cpp +++ b/src/video_core/debug_utils/debug_utils.cpp @@ -333,9 +333,9 @@ const Math::Vec4<u8> LookupTexture(const u8* source, int x, int y, const Texture // Interleave the lower 3 bits of each coordinate to get the intra-block offsets, which are // arranged in a Z-order curve. More details on the bit manipulation at: // https://fgiesen.wordpress.com/2009/12/13/decoding-morton-codes/ - unsigned int i = (x | (y << 8)) & 0x0707; // ---- -210 - i = (i ^ (i << 2)) & 0x1313; // ---2 --10 - i = (i ^ (i << 1)) & 0x1515; // ---2 -1-0 + unsigned int i = (x & 7) | ((y & 7) << 8); // ---- -210 + i = (i ^ (i << 2)) & 0x1313; // ---2 --10 + i = (i ^ (i << 1)) & 0x1515; // ---2 -1-0 i = (i | (i >> 7)) & 0x3F; if (info.format != Regs::TextureFormat::ETC1 && diff --git a/src/video_core/rasterizer.cpp b/src/video_core/rasterizer.cpp index 17f8f70ca..24dc37856 100644 --- a/src/video_core/rasterizer.cpp +++ b/src/video_core/rasterizer.cpp @@ -8,6 +8,7 @@ #include "common/math_util.h" #include "math.h" +#include "color.h" #include "pica.h" #include "rasterizer.h" #include "vertex_shader.h" @@ -37,6 +38,14 @@ static void DrawPixel(int x, int y, const Math::Vec4<u8>& color) { break; } + case registers.framebuffer.RGBA4: + { + u8* pixel = color_buffer + (x + y * registers.framebuffer.GetWidth()) * 2; + pixel[1] = (color.r() & 0xF0) | (color.g() >> 4); + pixel[0] = (color.b() & 0xF0) | (color.a() >> 4); + break; + } + default: LOG_CRITICAL(Render_Software, "Unknown framebuffer color format %x", registers.framebuffer.color_format); UNIMPLEMENTED(); @@ -60,6 +69,18 @@ static const Math::Vec4<u8> GetPixel(int x, int y) { ret.a() = pixel[0]; return ret; } + + case registers.framebuffer.RGBA4: + { + Math::Vec4<u8> ret; + u8* pixel = color_buffer + (x + y * registers.framebuffer.GetWidth()) * 2; + ret.r() = Color::Convert4To8(pixel[1] >> 4); + ret.g() = Color::Convert4To8(pixel[1] & 0x0F); + ret.b() = Color::Convert4To8(pixel[0] >> 4); + ret.a() = Color::Convert4To8(pixel[0] & 0x0F); + return ret; + } + default: LOG_CRITICAL(Render_Software, "Unknown framebuffer color format %x", registers.framebuffer.color_format); UNIMPLEMENTED(); |