mirror of
https://github.com/Lime3DS/Lime3DS.git
synced 2026-04-07 18:01:26 -06:00
Create rcheevos integration stub
This commit is contained in:
parent
a5b7e9012f
commit
f993fa3da4
5
externals/CMakeLists.txt
vendored
5
externals/CMakeLists.txt
vendored
@ -513,4 +513,7 @@ elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|ARM64|armv8")
|
||||
else()
|
||||
target_compile_definitions(xxhash PRIVATE XXH_VECTOR=XXH_SCALAR)
|
||||
message(STATUS "Disabling SIMD for xxHash")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# rcheevos
|
||||
add_subdirectory(rcheevos)
|
||||
|
||||
30
externals/rcheevos/CMakeLists.txt
vendored
Normal file
30
externals/rcheevos/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
add_library(rcheevos STATIC
|
||||
rcheevos/src/rc_compat.c
|
||||
rcheevos/src/rc_client.c
|
||||
rcheevos/src/rc_util.c
|
||||
rcheevos/src/rc_version.c
|
||||
rcheevos/src/rcheevos/alloc.c
|
||||
rcheevos/src/rcheevos/condition.c
|
||||
rcheevos/src/rcheevos/condset.c
|
||||
rcheevos/src/rcheevos/consoleinfo.c
|
||||
rcheevos/src/rcheevos/format.c
|
||||
rcheevos/src/rcheevos/lboard.c
|
||||
rcheevos/src/rcheevos/memref.c
|
||||
rcheevos/src/rcheevos/operand.c
|
||||
rcheevos/src/rcheevos/rc_validate.c
|
||||
rcheevos/src/rcheevos/richpresence.c
|
||||
rcheevos/src/rcheevos/runtime.c
|
||||
rcheevos/src/rcheevos/runtime_progress.c
|
||||
rcheevos/src/rcheevos/trigger.c
|
||||
rcheevos/src/rcheevos/value.c
|
||||
rcheevos/src/rhash/md5.c
|
||||
rcheevos/src/rapi/rc_api_common.c
|
||||
rcheevos/src/rapi/rc_api_editor.c
|
||||
rcheevos/src/rapi/rc_api_info.c
|
||||
rcheevos/src/rapi/rc_api_runtime.c
|
||||
rcheevos/src/rapi/rc_api_user.c
|
||||
)
|
||||
|
||||
target_include_directories(rcheevos PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rcheevos/include
|
||||
)
|
||||
@ -188,6 +188,7 @@ add_subdirectory(video_core)
|
||||
add_subdirectory(audio_core)
|
||||
add_subdirectory(network)
|
||||
add_subdirectory(input_common)
|
||||
add_subdirectory(rcheevos_integration)
|
||||
|
||||
if (ENABLE_TESTS)
|
||||
add_subdirectory(tests)
|
||||
|
||||
@ -137,7 +137,8 @@ bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) {
|
||||
CLS(Movie) \
|
||||
CLS(Loader) \
|
||||
CLS(WebService) \
|
||||
CLS(RPC_Server)
|
||||
CLS(RPC_Server) \
|
||||
CLS(Rcheevos)
|
||||
|
||||
// GetClassName is a macro defined by Windows.h, grrr...
|
||||
const char* GetLogClassName(Class log_class) {
|
||||
|
||||
@ -106,6 +106,7 @@ enum class Class : u8 {
|
||||
WebService, ///< Interface to Citra Web Services
|
||||
RPC_Server, ///< RPC server
|
||||
Count, ///< Total number of logging classes
|
||||
Rcheevos, ///< RetroAchievements
|
||||
};
|
||||
|
||||
} // namespace Common::Log
|
||||
|
||||
@ -500,7 +500,7 @@ add_library(citra_core STATIC
|
||||
|
||||
create_target_directory_groups(citra_core)
|
||||
|
||||
target_link_libraries(citra_core PUBLIC citra_common PRIVATE audio_core network video_core)
|
||||
target_link_libraries(citra_core PUBLIC citra_common PRIVATE audio_core network video_core rcheevos_integration)
|
||||
target_link_libraries(citra_core PRIVATE Boost::boost Boost::serialization Boost::iostreams httplib)
|
||||
target_link_libraries(citra_core PUBLIC dds-ktx PRIVATE cryptopp fmt lodepng open_source_archives)
|
||||
|
||||
|
||||
@ -50,6 +50,7 @@
|
||||
#include "core/rpc/server.h"
|
||||
#endif
|
||||
#include "network/network.h"
|
||||
#include "rcheevos_integration/rcheevos_integration.h"
|
||||
#include "video_core/custom_textures/custom_tex_manager.h"
|
||||
#include "video_core/gpu.h"
|
||||
#include "video_core/renderer_base.h"
|
||||
@ -73,9 +74,13 @@ Core::Timing& Global() {
|
||||
return System::GetInstance().CoreTiming();
|
||||
}
|
||||
|
||||
System::System() : movie{*this}, cheat_engine{*this} {}
|
||||
System::System() : movie{*this}, cheat_engine{*this} {
|
||||
initialize_retroachievements_client();
|
||||
}
|
||||
|
||||
System::~System() = default;
|
||||
System::~System() {
|
||||
shutdown_retroachievements_client();
|
||||
}
|
||||
|
||||
System::ResultStatus System::RunLoop(bool tight_loop) {
|
||||
status = ResultStatus::Success;
|
||||
|
||||
6
src/rcheevos_integration/CMakeLists.txt
Normal file
6
src/rcheevos_integration/CMakeLists.txt
Normal file
@ -0,0 +1,6 @@
|
||||
add_library(rcheevos_integration STATIC
|
||||
rcheevos_integration.cpp
|
||||
rcheevos_integration.h
|
||||
)
|
||||
|
||||
target_link_libraries(rcheevos_integration PUBLIC rcheevos PRIVATE citra_common)
|
||||
102
src/rcheevos_integration/rcheevos_integration.cpp
Normal file
102
src/rcheevos_integration/rcheevos_integration.cpp
Normal file
@ -0,0 +1,102 @@
|
||||
#include "rcheevos_integration.h"
|
||||
|
||||
#include <rc_client.h>
|
||||
|
||||
#include "common/logging/log.h"
|
||||
|
||||
rc_client_t* g_client = NULL;
|
||||
|
||||
// This is the function the rc_client will use to read memory for the emulator. we don't need it yet,
|
||||
// so just provide a dummy function that returns "no memory read".
|
||||
static uint32_t read_memory(uint32_t address, uint8_t* buffer, uint32_t num_bytes, rc_client_t* client)
|
||||
{
|
||||
// TODO: implement later
|
||||
LOG_DEBUG(Rcheevos, "Attempting to read memory.");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// // This is the callback function for the asynchronous HTTP call (which is not provided in this example)
|
||||
// static void http_callback(int status_code, const char* content, size_t content_size, void* userdata, const char* error_message)
|
||||
// {
|
||||
// // Prepare a data object to pass the HTTP response to the callback
|
||||
// rc_api_server_response_t server_response;
|
||||
// memset(&server_response, 0, sizeof(server_response));
|
||||
// server_response.body = content;
|
||||
// server_response.body_length = content_size;
|
||||
// server_response.http_status_code = status_code;
|
||||
|
||||
// // handle non-http errors (socket timeout, no internet available, etc)
|
||||
// if (status_code == 0 && error_message) {
|
||||
// // assume no server content and pass the error through instead
|
||||
// server_response.body = error_message;
|
||||
// server_response.body_length = strlen(error_message);
|
||||
// // Let rc_client know the error was not catastrophic and could be retried. It may decide to retry or just
|
||||
// // immediately pass the error to the callback. To prevent possible retries, use RC_API_SERVER_RESPONSE_CLIENT_ERROR.
|
||||
// server_response.http_status_code = RC_API_SERVER_RESPONSE_RETRYABLE_CLIENT_ERROR;
|
||||
// }
|
||||
|
||||
// // Get the rc_client callback and call it
|
||||
// async_callback_data* async_data = (async_callback_data*)userdata;
|
||||
// async_data->callback(&server_response, async_data->callback_data);
|
||||
|
||||
// // Release the captured rc_client callback data
|
||||
// free(async_data);
|
||||
// }
|
||||
|
||||
// This is the HTTP request dispatcher that is provided to the rc_client. Whenever the client
|
||||
// needs to talk to the server, it will call this function.
|
||||
static void server_call(const rc_api_request_t* request,
|
||||
rc_client_server_callback_t callback, void* callback_data, rc_client_t* client)
|
||||
{
|
||||
LOG_DEBUG(Rcheevos, "Attempting to call server.");
|
||||
|
||||
// // RetroAchievements may not allow hardcore unlocks if we don't properly identify ourselves.
|
||||
// const char* user_agent = "MyClient/1.2";
|
||||
|
||||
// // callback must be called with callback_data, regardless of the outcome of the HTTP call.
|
||||
// // Since we're making the HTTP call asynchronously, we need to capture them and pass it
|
||||
// // through the async HTTP code.
|
||||
// async_callback_data* async_data = malloc(sizeof(async_callback_data));
|
||||
// async_data->callback = callback;
|
||||
// async_data->callback_data = callback_data;
|
||||
|
||||
// // If post data is provided, we need to make a POST request, otherwise, a GET request will suffice.
|
||||
// if (request->post_data)
|
||||
// async_http_post(request->url, request->post_data, user_agent, http_callback, async_data);
|
||||
// else
|
||||
// async_http_get(request->url, user_agent, http_callback, async_data);
|
||||
}
|
||||
|
||||
// Write log messages to the console
|
||||
static void log_message(const char* message, const rc_client_t* client)
|
||||
{
|
||||
LOG_DEBUG(Rcheevos, "Rcheevos internal message: \"{}\"", message);
|
||||
}
|
||||
|
||||
void initialize_retroachievements_client()
|
||||
{
|
||||
LOG_DEBUG(Rcheevos, "Initializing RA client.");
|
||||
|
||||
// Create the client instance (using a global variable simplifies this example)
|
||||
g_client = rc_client_create(read_memory, server_call);
|
||||
|
||||
// Provide a logging function to simplify debugging
|
||||
rc_client_enable_logging(g_client, RC_CLIENT_LOG_LEVEL_VERBOSE, log_message);
|
||||
|
||||
// Disable hardcore - if we goof something up in the implementation, we don't want our
|
||||
// account disabled for cheating.
|
||||
rc_client_set_hardcore_enabled(g_client, 0);
|
||||
}
|
||||
|
||||
void shutdown_retroachievements_client()
|
||||
{
|
||||
LOG_DEBUG(Rcheevos, "Shutting down RA client.");
|
||||
|
||||
if (g_client)
|
||||
{
|
||||
// Release resources associated to the client instance
|
||||
rc_client_destroy(g_client);
|
||||
g_client = NULL;
|
||||
}
|
||||
}
|
||||
8
src/rcheevos_integration/rcheevos_integration.h
Normal file
8
src/rcheevos_integration/rcheevos_integration.h
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <rc_client.h>
|
||||
|
||||
extern rc_client_t* g_client;
|
||||
|
||||
void initialize_retroachievements_client();
|
||||
void shutdown_retroachievements_client();
|
||||
Loading…
Reference in New Issue
Block a user