mirror of
https://github.com/melonDS-emu/melonDS.git
synced 2024-11-14 13:27:41 -07:00
Merge 7f5a528db4
into 7c1d2a64f4
This commit is contained in:
commit
8bdf7dc46a
@ -106,3 +106,12 @@ add_subdirectory(src)
|
|||||||
if (BUILD_QT_SDL)
|
if (BUILD_QT_SDL)
|
||||||
add_subdirectory(src/frontend/qt_sdl)
|
add_subdirectory(src/frontend/qt_sdl)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
option(MELONDS_BUILD_TESTS "Build the melonDS test suite." OFF)
|
||||||
|
|
||||||
|
if (MELONDS_BUILD_TESTS)
|
||||||
|
include(CTest)
|
||||||
|
message(STATUS "Enabling melonDS test suite.")
|
||||||
|
enable_testing()
|
||||||
|
add_subdirectory(test)
|
||||||
|
endif()
|
64
test/CMakeLists.txt
Normal file
64
test/CMakeLists.txt
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
cmake_policy(SET CMP0110 NEW)
|
||||||
|
|
||||||
|
if (NOT NDS_ROM)
|
||||||
|
message(WARNING "NDS_ROM must be set to the path of an NDS ROM; tests that require one won't run.")
|
||||||
|
set(NDS_ROM "NDS_ROM-NOTFOUND" CACHE FILEPATH "Path to an NDS ROM" FORCE)
|
||||||
|
else()
|
||||||
|
message(DEBUG "NDS_ROM: ${NDS_ROM}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include(CMakePrintHelpers)
|
||||||
|
|
||||||
|
function(add_melonds_test)
|
||||||
|
set(options WILL_FAIL ARM7_BIOS ARM9_BIOS ARM7_DSI_BIOS ARM9_DSI_BIOS NDS_FIRMWARE DSI_FIRMWARE DSI_NAND DISABLED)
|
||||||
|
set(oneValueArgs TARGET NAME ROM)
|
||||||
|
set(multiValueArgs ARGS LABEL)
|
||||||
|
cmake_parse_arguments(PARSE_ARGV 0 MELONDS_TEST "${options}" "${oneValueArgs}" "${multiValueArgs}")
|
||||||
|
|
||||||
|
add_test(
|
||||||
|
NAME "${MELONDS_TEST_NAME}"
|
||||||
|
COMMAND "${MELONDS_TEST_TARGET}"
|
||||||
|
${MELONDS_TEST_ARGS}
|
||||||
|
COMMAND_EXPAND_LISTS
|
||||||
|
)
|
||||||
|
|
||||||
|
if (MELONDS_TEST_ROM)
|
||||||
|
list(APPEND REQUIRED_FILES "${MELONDS_TEST_ROM}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
macro(expose_system_file SYSFILE)
|
||||||
|
if (MELONDS_TEST_${SYSFILE})
|
||||||
|
list(APPEND REQUIRED_FILES "${${SYSFILE}}")
|
||||||
|
list(APPEND ENVIRONMENT "${SYSFILE}=${${SYSFILE}}")
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
expose_system_file(ARM7_BIOS)
|
||||||
|
expose_system_file(ARM9_BIOS)
|
||||||
|
expose_system_file(ARM7_DSI_BIOS)
|
||||||
|
expose_system_file(ARM9_DSI_BIOS)
|
||||||
|
expose_system_file(NDS_FIRMWARE)
|
||||||
|
expose_system_file(DSI_FIRMWARE)
|
||||||
|
expose_system_file(DSI_NAND)
|
||||||
|
|
||||||
|
set_tests_properties("${MELONDS_TEST_NAME}" PROPERTIES LABELS "${MELONDS_TEST_LABEL}") # This is already a list
|
||||||
|
set_tests_properties("${MELONDS_TEST_NAME}" PROPERTIES ENVIRONMENT "${ENVIRONMENT}")
|
||||||
|
set_tests_properties("${MELONDS_TEST_NAME}" PROPERTIES REQUIRED_FILES "${REQUIRED_FILES}")
|
||||||
|
|
||||||
|
if (MELONDS_TEST_WILL_FAIL)
|
||||||
|
set_tests_properties("${MELONDS_TEST_NAME}" PROPERTIES WILL_FAIL TRUE)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (MELONDS_TEST_DISABLED)
|
||||||
|
set_tests_properties("${MELONDS_TEST_NAME}" PROPERTIES DISABLED TRUE)
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
function(add_test_executable TEST_PROGRAM)
|
||||||
|
add_executable("${TEST_PROGRAM}" "${TEST_PROGRAM}.cpp")
|
||||||
|
target_link_libraries("${TEST_PROGRAM}" PRIVATE core melonDS-tests-common)
|
||||||
|
target_include_directories("${TEST_PROGRAM}" PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../src")
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
add_subdirectory(common)
|
||||||
|
add_subdirectory(cases)
|
5
test/cases/CMakeLists.txt
Normal file
5
test/cases/CMakeLists.txt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# Tests can be grouped into subdirectories for better organization.
|
||||||
|
# Each subdirectory must contain a CMakeLists.txt file
|
||||||
|
# that lists the test executables *and* the tests themselves.
|
||||||
|
|
||||||
|
add_subdirectory(basic)
|
22
test/cases/basic/CMakeLists.txt
Normal file
22
test/cases/basic/CMakeLists.txt
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# Test executables must be defined separately from the actual tests,
|
||||||
|
# as the same test executable might be used for multiple tests
|
||||||
|
# (with different parameters each time).
|
||||||
|
|
||||||
|
add_test_executable(NDSCreated)
|
||||||
|
add_test_executable(MultipleNDSCreated)
|
||||||
|
add_test_executable(MultipleNDSCreatedInDifferentOrder)
|
||||||
|
|
||||||
|
add_melonds_test(
|
||||||
|
NAME "NDS is created and destroyed"
|
||||||
|
TARGET NDSCreated
|
||||||
|
)
|
||||||
|
|
||||||
|
add_melonds_test(
|
||||||
|
NAME "Multiple NDS systems are created and destroyed"
|
||||||
|
TARGET MultipleNDSCreated
|
||||||
|
)
|
||||||
|
|
||||||
|
add_melonds_test(
|
||||||
|
NAME "Multiple NDS systems are created and destroyed in different orders"
|
||||||
|
TARGET MultipleNDSCreatedInDifferentOrder
|
||||||
|
)
|
28
test/cases/basic/MultipleNDSCreated.cpp
Normal file
28
test/cases/basic/MultipleNDSCreated.cpp
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2016-2023 melonDS team
|
||||||
|
|
||||||
|
This file is part of melonDS.
|
||||||
|
|
||||||
|
melonDS is free software: you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation, either version 3 of the License, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
melonDS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with melonDS. If not, see http://www.gnu.org/licenses/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "NDS.h"
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// volatile so it's not optimized out
|
||||||
|
volatile auto nds1 = std::make_unique<melonDS::NDS>();
|
||||||
|
volatile auto nds2 = std::make_unique<melonDS::NDS>();
|
||||||
|
volatile auto nds3 = std::make_unique<melonDS::NDS>();
|
||||||
|
volatile auto nds4 = std::make_unique<melonDS::NDS>();
|
||||||
|
}
|
34
test/cases/basic/MultipleNDSCreatedInDifferentOrder.cpp
Normal file
34
test/cases/basic/MultipleNDSCreatedInDifferentOrder.cpp
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2016-2023 melonDS team
|
||||||
|
|
||||||
|
This file is part of melonDS.
|
||||||
|
|
||||||
|
melonDS is free software: you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation, either version 3 of the License, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
melonDS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with melonDS. If not, see http://www.gnu.org/licenses/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include "NDS.h"
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// volatile so it's not optimized out
|
||||||
|
auto nds1 = std::make_unique<volatile melonDS::NDS>();
|
||||||
|
auto nds2 = std::make_unique<volatile melonDS::NDS>();
|
||||||
|
auto nds3 = std::make_unique<volatile melonDS::NDS>();
|
||||||
|
auto nds4 = std::make_unique<volatile melonDS::NDS>();
|
||||||
|
|
||||||
|
nds3 = nullptr;
|
||||||
|
nds1 = nullptr;
|
||||||
|
nds4 = nullptr;
|
||||||
|
nds2 = nullptr;
|
||||||
|
}
|
28
test/cases/basic/NDSCreated.cpp
Normal file
28
test/cases/basic/NDSCreated.cpp
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2016-2023 melonDS team
|
||||||
|
|
||||||
|
This file is part of melonDS.
|
||||||
|
|
||||||
|
melonDS is free software: you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation, either version 3 of the License, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
melonDS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with melonDS. If not, see http://www.gnu.org/licenses/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include "NDS.h"
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// volatile so it's not optimized out
|
||||||
|
volatile auto nds = std::make_unique<melonDS::NDS>();
|
||||||
|
|
||||||
|
// NDS is probably waaaay too big for the stack
|
||||||
|
}
|
13
test/common/CMakeLists.txt
Normal file
13
test/common/CMakeLists.txt
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
include(FixInterfaceIncludes)
|
||||||
|
|
||||||
|
add_library(melonDS-tests-common STATIC
|
||||||
|
Platform.cpp
|
||||||
|
TestCommon.cpp
|
||||||
|
TestCommon.h
|
||||||
|
)
|
||||||
|
|
||||||
|
# The test program is built with C++20 so we can use std::counting_semaphore
|
||||||
|
set_target_properties(melonDS-tests-common PROPERTIES CXX_STANDARD 20)
|
||||||
|
|
||||||
|
target_link_libraries(melonDS-tests-common PRIVATE core)
|
||||||
|
target_include_directories(melonDS-tests-common PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../../src")
|
316
test/common/Platform.cpp
Normal file
316
test/common/Platform.cpp
Normal file
@ -0,0 +1,316 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2016-2023 melonDS team
|
||||||
|
|
||||||
|
This file is part of melonDS.
|
||||||
|
|
||||||
|
melonDS is free software: you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation, either version 3 of the License, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
melonDS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with melonDS. If not, see http://www.gnu.org/licenses/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Platform.h"
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
|
#include <mutex>
|
||||||
|
#include <semaphore>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
namespace melonDS::Platform
|
||||||
|
{
|
||||||
|
void SignalStop(StopReason reason) {}
|
||||||
|
int InstanceID() { return 0; }
|
||||||
|
|
||||||
|
std::string InstanceFileSuffix() { return ""; }
|
||||||
|
|
||||||
|
constexpr char AccessMode(FileMode mode, bool file_exists)
|
||||||
|
{
|
||||||
|
if (!(mode & FileMode::Write))
|
||||||
|
// If we're only opening the file for reading...
|
||||||
|
return 'r';
|
||||||
|
|
||||||
|
if (mode & (FileMode::NoCreate))
|
||||||
|
// If we're not allowed to create a new file...
|
||||||
|
return 'r'; // Open in "r+" mode (IsExtended will add the "+")
|
||||||
|
|
||||||
|
if ((mode & FileMode::Preserve) && file_exists)
|
||||||
|
// If we're not allowed to overwrite a file that already exists...
|
||||||
|
return 'r'; // Open in "r+" mode (IsExtended will add the "+")
|
||||||
|
|
||||||
|
return 'w';
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool IsExtended(FileMode mode)
|
||||||
|
{
|
||||||
|
// fopen's "+" flag always opens the file for read/write
|
||||||
|
return (mode & FileMode::ReadWrite) == FileMode::ReadWrite;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string GetModeString(FileMode mode, bool file_exists)
|
||||||
|
{
|
||||||
|
std::string modeString;
|
||||||
|
|
||||||
|
modeString += AccessMode(mode, file_exists);
|
||||||
|
|
||||||
|
if (IsExtended(mode))
|
||||||
|
modeString += '+';
|
||||||
|
|
||||||
|
if (!(mode & FileMode::Text))
|
||||||
|
modeString += 'b';
|
||||||
|
|
||||||
|
return modeString;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileHandle* OpenFile(const std::string& path, FileMode mode)
|
||||||
|
{
|
||||||
|
if ((mode & FileMode::ReadWrite) == FileMode::None)
|
||||||
|
{ // If we aren't reading or writing, then we can't open the file
|
||||||
|
Log(LogLevel::Error, "Attempted to open \"%s\" in neither read nor write mode (FileMode 0x%x)\n", path.c_str(), mode);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool file_exists = std::filesystem::exists(path);
|
||||||
|
std::string modeString = GetModeString(mode, file_exists);
|
||||||
|
|
||||||
|
FILE* file = fopen(path.c_str(), modeString.c_str());
|
||||||
|
if (file)
|
||||||
|
{
|
||||||
|
Log(LogLevel::Debug, "Opened \"%s\" with FileMode 0x%x (effective mode \"%s\")\n", path.c_str(), mode, modeString.c_str());
|
||||||
|
return reinterpret_cast<FileHandle *>(file);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log(LogLevel::Warn, "Failed to open \"%s\" with FileMode 0x%x (effective mode \"%s\")\n", path.c_str(), mode, modeString.c_str());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FileHandle* OpenLocalFile(const std::string& path, FileMode mode)
|
||||||
|
{
|
||||||
|
return OpenFile(path, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CloseFile(FileHandle* file)
|
||||||
|
{
|
||||||
|
return fclose(reinterpret_cast<FILE *>(file)) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsEndOfFile(FileHandle* file)
|
||||||
|
{
|
||||||
|
return feof(reinterpret_cast<FILE *>(file)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FileReadLine(char* str, int count, FileHandle* file)
|
||||||
|
{
|
||||||
|
return fgets(str, count, reinterpret_cast<FILE *>(file)) != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FileExists(const std::string& name)
|
||||||
|
{
|
||||||
|
FileHandle* f = OpenFile(name, FileMode::Read);
|
||||||
|
if (!f) return false;
|
||||||
|
CloseFile(f);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LocalFileExists(const std::string& name)
|
||||||
|
{
|
||||||
|
FileHandle* f = OpenLocalFile(name, FileMode::Read);
|
||||||
|
if (!f) return false;
|
||||||
|
CloseFile(f);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FileSeek(FileHandle* file, s64 offset, FileSeekOrigin origin)
|
||||||
|
{
|
||||||
|
int stdorigin;
|
||||||
|
switch (origin)
|
||||||
|
{
|
||||||
|
case FileSeekOrigin::Start: stdorigin = SEEK_SET; break;
|
||||||
|
case FileSeekOrigin::Current: stdorigin = SEEK_CUR; break;
|
||||||
|
case FileSeekOrigin::End: stdorigin = SEEK_END; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fseek(reinterpret_cast<FILE *>(file), offset, stdorigin) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileRewind(FileHandle* file)
|
||||||
|
{
|
||||||
|
rewind(reinterpret_cast<FILE *>(file));
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 FileRead(void* data, u64 size, u64 count, FileHandle* file)
|
||||||
|
{
|
||||||
|
return fread(data, size, count, reinterpret_cast<FILE *>(file));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FileFlush(FileHandle* file)
|
||||||
|
{
|
||||||
|
return fflush(reinterpret_cast<FILE *>(file)) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 FileWrite(const void* data, u64 size, u64 count, FileHandle* file)
|
||||||
|
{
|
||||||
|
return fwrite(data, size, count, reinterpret_cast<FILE *>(file));
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 FileWriteFormatted(FileHandle* file, const char* fmt, ...)
|
||||||
|
{
|
||||||
|
if (fmt == nullptr)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
u64 ret = vfprintf(reinterpret_cast<FILE *>(file), fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 FileLength(FileHandle* file)
|
||||||
|
{
|
||||||
|
FILE* stdfile = reinterpret_cast<FILE *>(file);
|
||||||
|
long pos = ftell(stdfile);
|
||||||
|
fseek(stdfile, 0, SEEK_END);
|
||||||
|
long len = ftell(stdfile);
|
||||||
|
fseek(stdfile, pos, SEEK_SET);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Log(LogLevel level, const char* fmt, ...)
|
||||||
|
{
|
||||||
|
if (fmt == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
vfprintf(stderr, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Thread
|
||||||
|
{
|
||||||
|
std::thread thread;
|
||||||
|
};
|
||||||
|
|
||||||
|
Thread* Thread_Create(std::function<void()> func)
|
||||||
|
{
|
||||||
|
return new Thread { std::thread(func) };
|
||||||
|
}
|
||||||
|
|
||||||
|
void Thread_Free(Thread* thread)
|
||||||
|
{
|
||||||
|
if (thread)
|
||||||
|
{
|
||||||
|
thread->thread.join();
|
||||||
|
delete thread;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Thread_Wait(Thread* thread)
|
||||||
|
{
|
||||||
|
if (thread)
|
||||||
|
{
|
||||||
|
thread->thread.join();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Semaphore
|
||||||
|
{
|
||||||
|
std::counting_semaphore<> semaphore;
|
||||||
|
|
||||||
|
Semaphore() : semaphore(0) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
Semaphore* Semaphore_Create()
|
||||||
|
{
|
||||||
|
return new Semaphore;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Semaphore_Free(Semaphore* sema)
|
||||||
|
{
|
||||||
|
delete sema;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Semaphore_Reset(Semaphore* sema)
|
||||||
|
{
|
||||||
|
while (sema->semaphore.try_acquire());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Semaphore_Wait(Semaphore* sema)
|
||||||
|
{
|
||||||
|
sema->semaphore.acquire();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Semaphore_Post(Semaphore* sema, int count)
|
||||||
|
{
|
||||||
|
sema->semaphore.release(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Mutex
|
||||||
|
{
|
||||||
|
std::mutex mutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
Mutex* Mutex_Create()
|
||||||
|
{
|
||||||
|
return new Mutex;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mutex_Free(Mutex* mutex)
|
||||||
|
{
|
||||||
|
delete mutex;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mutex_Lock(Mutex* mutex)
|
||||||
|
{
|
||||||
|
if (mutex)
|
||||||
|
mutex->mutex.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mutex_Unlock(Mutex* mutex)
|
||||||
|
{
|
||||||
|
if (mutex)
|
||||||
|
mutex->mutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Mutex_TryLock(Mutex* mutex)
|
||||||
|
{
|
||||||
|
if (!mutex)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return mutex->mutex.try_lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteNDSSave(const u8* savedata, u32 savelen, u32 writeoffset, u32 writelen) {}
|
||||||
|
void WriteGBASave(const u8* savedata, u32 savelen, u32 writeoffset, u32 writelen) {}
|
||||||
|
void WriteFirmware(const Firmware& firmware, u32 writeoffset, u32 writelen) {}
|
||||||
|
void WriteDateTime(int year, int month, int day, int hour, int minute, int second) {}
|
||||||
|
bool MP_Init() { return false; }
|
||||||
|
void MP_DeInit() {}
|
||||||
|
void MP_Begin() {}
|
||||||
|
void MP_End() {}
|
||||||
|
int MP_SendPacket(u8* data, int len, u64 timestamp) { return 0; }
|
||||||
|
int MP_RecvPacket(u8* data, u64* timestamp) { return 0;}
|
||||||
|
int MP_SendCmd(u8* data, int len, u64 timestamp) { return 0; }
|
||||||
|
int MP_SendReply(u8* data, int len, u64 timestamp, u16 aid) { return 0;}
|
||||||
|
int MP_SendAck(u8* data, int len, u64 timestamp) { return 0; }
|
||||||
|
int MP_RecvHostPacket(u8* data, u64* timestamp) { return 0; }
|
||||||
|
u16 MP_RecvReplies(u8* data, u64 timestamp, u16 aidmask) { return 0; }
|
||||||
|
bool LAN_Init() { return false; }
|
||||||
|
void LAN_DeInit() {}
|
||||||
|
int LAN_SendPacket(u8* data, int len) { return 0; }
|
||||||
|
int LAN_RecvPacket(u8* data) { return 0; }
|
||||||
|
void Camera_Start(int num) {}
|
||||||
|
void Camera_Stop(int num) {}
|
||||||
|
void Camera_CaptureFrame(int num, u32* frame, int width, int height, bool yuv) {}
|
||||||
|
DynamicLibrary* DynamicLibrary_Load(const char* lib) { return nullptr;}
|
||||||
|
void DynamicLibrary_Unload(DynamicLibrary* lib) {}
|
||||||
|
void* DynamicLibrary_LoadFunction(DynamicLibrary* lib, const char* name) { return nullptr; }
|
||||||
|
}
|
23
test/common/TestCommon.cpp
Normal file
23
test/common/TestCommon.cpp
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2016-2023 melonDS team
|
||||||
|
|
||||||
|
This file is part of melonDS.
|
||||||
|
|
||||||
|
melonDS is free software: you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation, either version 3 of the License, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
melonDS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with melonDS. If not, see http://www.gnu.org/licenses/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "TestCommon.h"
|
||||||
|
|
||||||
|
namespace melonDS
|
||||||
|
{
|
||||||
|
}
|
25
test/common/TestCommon.h
Normal file
25
test/common/TestCommon.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2016-2023 melonDS team
|
||||||
|
|
||||||
|
This file is part of melonDS.
|
||||||
|
|
||||||
|
melonDS is free software: you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation, either version 3 of the License, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
melonDS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with melonDS. If not, see http://www.gnu.org/licenses/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MELONDS_TESTCOMMON_H
|
||||||
|
#define MELONDS_TESTCOMMON_H
|
||||||
|
|
||||||
|
namespace melonDS
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif //MELONDS_TESTCOMMON_H
|
Loading…
Reference in New Issue
Block a user