mirror of
https://github.com/dingusdev/dingusppc.git
synced 2025-01-11 20:29:46 +00:00
Merge pull request #55 from mihaip/upstreaming
Add Emscripten build target
This commit is contained in:
commit
8cad7ee509
@ -1,20 +1,23 @@
|
|||||||
cmake_minimum_required(VERSION 3.1)
|
cmake_minimum_required(VERSION 3.1)
|
||||||
project(dingusppc)
|
project(dingusppc)
|
||||||
|
|
||||||
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
|
||||||
|
include(PlatformGlob)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 20)
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
|
|
||||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
||||||
set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib)
|
set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib)
|
||||||
|
|
||||||
if (NOT WIN32)
|
if (NOT WIN32 AND NOT EMSCRIPTEN)
|
||||||
find_package(SDL2 REQUIRED)
|
find_package(SDL2 REQUIRED)
|
||||||
include_directories(${SDL2_INCLUDE_DIRS})
|
include_directories(${SDL2_INCLUDE_DIRS})
|
||||||
if (UNIX AND NOT APPLE)
|
if (UNIX AND NOT APPLE)
|
||||||
find_package (Threads)
|
find_package (Threads)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
else() # Windows build relies on vcpkg
|
elseif (WIN32) # Windows build relies on vcpkg
|
||||||
# pick up system wide vcpkg if exists
|
# pick up system wide vcpkg if exists
|
||||||
if (DEFINED ENV{VCPKG_ROOT} AND EXISTS $ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake)
|
if (DEFINED ENV{VCPKG_ROOT} AND EXISTS $ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake)
|
||||||
message(STATUS "Using system vcpkg at $ENV{VCPKG_ROOT}")
|
message(STATUS "Using system vcpkg at $ENV{VCPKG_ROOT}")
|
||||||
@ -40,6 +43,12 @@ else() # Windows build relies on vcpkg
|
|||||||
add_compile_definitions(SDL_MAIN_HANDLED)
|
add_compile_definitions(SDL_MAIN_HANDLED)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (EMSCRIPTEN)
|
||||||
|
message(STATUS "Targeting Emscripten")
|
||||||
|
# loguru tries to include excinfo.h, which is not available under Emscripten.
|
||||||
|
add_compile_definitions(LOGURU_STACKTRACES=0)
|
||||||
|
endif()
|
||||||
|
|
||||||
option(DPPC_BUILD_PPC_TESTS "Build PowerPC tests" OFF)
|
option(DPPC_BUILD_PPC_TESTS "Build PowerPC tests" OFF)
|
||||||
option(DPPC_BUILD_BENCHMARKS "Build benchmarking programs" OFF)
|
option(DPPC_BUILD_BENCHMARKS "Build benchmarking programs" OFF)
|
||||||
|
|
||||||
@ -83,11 +92,12 @@ add_subdirectory("${PROJECT_SOURCE_DIR}/machines/")
|
|||||||
add_subdirectory("${PROJECT_SOURCE_DIR}/utils/")
|
add_subdirectory("${PROJECT_SOURCE_DIR}/utils/")
|
||||||
add_subdirectory("${PROJECT_SOURCE_DIR}/thirdparty/loguru/")
|
add_subdirectory("${PROJECT_SOURCE_DIR}/thirdparty/loguru/")
|
||||||
|
|
||||||
set(BUILD_TESTS OFF CACHE BOOL "Build Cubeb tests")
|
if (NOT EMSCRIPTEN)
|
||||||
set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared libraries")
|
set(BUILD_TESTS OFF CACHE BOOL "Build Cubeb tests")
|
||||||
set(BUILD_TOOLS OFF CACHE BOOL "Build Cubeb tools")
|
set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared libraries")
|
||||||
|
set(BUILD_TOOLS OFF CACHE BOOL "Build Cubeb tools")
|
||||||
add_subdirectory(thirdparty/cubeb EXCLUDE_FROM_ALL)
|
add_subdirectory(thirdparty/cubeb EXCLUDE_FROM_ALL)
|
||||||
|
endif()
|
||||||
|
|
||||||
set(CLI11_ROOT ${PROJECT_SOURCE_DIR}/thirdparty/CLI11)
|
set(CLI11_ROOT ${PROJECT_SOURCE_DIR}/thirdparty/CLI11)
|
||||||
|
|
||||||
@ -101,7 +111,7 @@ include_directories("${PROJECT_SOURCE_DIR}"
|
|||||||
"${PROJECT_SOURCE_DIR}/thirdparty/CLI11/"
|
"${PROJECT_SOURCE_DIR}/thirdparty/CLI11/"
|
||||||
"${PROJECT_SOURCE_DIR}/thirdparty/cubeb/include")
|
"${PROJECT_SOURCE_DIR}/thirdparty/cubeb/include")
|
||||||
|
|
||||||
file(GLOB SOURCES "${PROJECT_SOURCE_DIR}/*.cpp"
|
platform_glob(SOURCES "${PROJECT_SOURCE_DIR}/*.cpp"
|
||||||
"${PROJECT_SOURCE_DIR}/*.c"
|
"${PROJECT_SOURCE_DIR}/*.c"
|
||||||
"${PROJECT_SOURCE_DIR}/*.hpp"
|
"${PROJECT_SOURCE_DIR}/*.hpp"
|
||||||
"${PROJECT_SOURCE_DIR}/*.h")
|
"${PROJECT_SOURCE_DIR}/*.h")
|
||||||
@ -118,6 +128,16 @@ add_executable(dingusppc ${SOURCES} $<TARGET_OBJECTS:core>
|
|||||||
|
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
target_link_libraries(dingusppc PRIVATE SDL2::SDL2 SDL2::SDL2main cubeb)
|
target_link_libraries(dingusppc PRIVATE SDL2::SDL2 SDL2::SDL2main cubeb)
|
||||||
|
elseif (EMSCRIPTEN)
|
||||||
|
target_link_libraries(dingusppc PRIVATE
|
||||||
|
${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT}
|
||||||
|
"-gsource-map"
|
||||||
|
# 256 MB max for emulated Mac RAM, plus 32 MB of emulator overhead
|
||||||
|
"-s INITIAL_MEMORY=301989888"
|
||||||
|
"-s MODULARIZE"
|
||||||
|
"-s EXPORT_ES6"
|
||||||
|
"-s EXPORT_NAME=emulator"
|
||||||
|
"-s 'EXTRA_EXPORTED_RUNTIME_METHODS=[\"FS\"]'")
|
||||||
else()
|
else()
|
||||||
target_link_libraries(dingusppc PRIVATE SDL2::SDL2 SDL2::SDL2main cubeb
|
target_link_libraries(dingusppc PRIVATE SDL2::SDL2 SDL2::SDL2main cubeb
|
||||||
${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT})
|
${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT})
|
||||||
|
21
cmake/PlatformGlob.cmake
Normal file
21
cmake/PlatformGlob.cmake
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# Detect platform suffix
|
||||||
|
if (EMSCRIPTEN)
|
||||||
|
set(PLATFORM_SUFFIX "_js$")
|
||||||
|
else()
|
||||||
|
set(PLATFORM_SUFFIX "_sdl|_cubeb$")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Function to perform a platform-specific glob
|
||||||
|
function(platform_glob RESULT_VAR)
|
||||||
|
set(PLATFORM_SOURCES)
|
||||||
|
foreach(GLOB_PATTERN ${ARGN})
|
||||||
|
file(GLOB GLOB_RESULT ${GLOB_PATTERN})
|
||||||
|
foreach(FILE_PATH ${GLOB_RESULT})
|
||||||
|
get_filename_component(BASE_NAME ${FILE_PATH} NAME_WE)
|
||||||
|
if("${BASE_NAME}" MATCHES ${PLATFORM_SUFFIX} OR NOT "${BASE_NAME}" MATCHES "_js$|_sdl|_cubeb$")
|
||||||
|
list(APPEND PLATFORM_SOURCES ${FILE_PATH})
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
endforeach()
|
||||||
|
set(${RESULT_VAR} ${PLATFORM_SOURCES} PARENT_SCOPE)
|
||||||
|
endfunction()
|
@ -2,7 +2,11 @@ include_directories("${PROJECT_SOURCE_DIR}"
|
|||||||
"${PROJECT_SOURCE_DIR}/thirdparty/loguru/"
|
"${PROJECT_SOURCE_DIR}/thirdparty/loguru/"
|
||||||
)
|
)
|
||||||
|
|
||||||
file(GLOB SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp")
|
platform_glob(SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp")
|
||||||
|
|
||||||
add_library(core OBJECT ${SOURCES})
|
add_library(core OBJECT ${SOURCES})
|
||||||
target_link_libraries(core PRIVATE SDL2::SDL2)
|
if (EMSCRIPTEN)
|
||||||
|
target_link_libraries(core PRIVATE)
|
||||||
|
else()
|
||||||
|
target_link_libraries(core PRIVATE SDL2::SDL2)
|
||||||
|
endif()
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
|
||||||
|
include(PlatformGlob)
|
||||||
|
|
||||||
include_directories("${PROJECT_SOURCE_DIR}"
|
include_directories("${PROJECT_SOURCE_DIR}"
|
||||||
"${PROJECT_SOURCE_DIR}/thirdparty/loguru/"
|
"${PROJECT_SOURCE_DIR}/thirdparty/loguru/"
|
||||||
)
|
)
|
||||||
|
|
||||||
file(GLOB SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp"
|
platform_glob(SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/common/*.cpp"
|
"${CMAKE_CURRENT_SOURCE_DIR}/common/*.cpp"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/common/adb/*.cpp"
|
"${CMAKE_CURRENT_SOURCE_DIR}/common/adb/*.cpp"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/common/i2c/*.cpp"
|
"${CMAKE_CURRENT_SOURCE_DIR}/common/i2c/*.cpp"
|
||||||
@ -20,4 +23,8 @@ file(GLOB SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp"
|
|||||||
)
|
)
|
||||||
|
|
||||||
add_library(devices OBJECT ${SOURCES})
|
add_library(devices OBJECT ${SOURCES})
|
||||||
target_link_libraries(devices PRIVATE cubeb SDL2::SDL2)
|
if (EMSCRIPTEN)
|
||||||
|
target_link_libraries(devices PRIVATE)
|
||||||
|
else()
|
||||||
|
target_link_libraries(devices PRIVATE cubeb SDL2::SDL2)
|
||||||
|
endif()
|
||||||
|
@ -301,7 +301,7 @@ FloppyImgConverter* open_floppy_image(std::string& img_path)
|
|||||||
img_file.open(img_path, std::ios::in | std::ios::binary);
|
img_file.open(img_path, std::ios::in | std::ios::binary);
|
||||||
if (img_file.fail()) {
|
if (img_file.fail()) {
|
||||||
img_file.close();
|
img_file.close();
|
||||||
LOG_F(ERROR, "Could not open specified floppy image!");
|
LOG_F(ERROR, "Could not open specified floppy image (%s)!", img_path.c_str());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,25 +34,14 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
#ifndef SOUND_SERVER_H
|
#ifndef SOUND_SERVER_H
|
||||||
#define SOUND_SERVER_H
|
#define SOUND_SERVER_H
|
||||||
|
|
||||||
#include <cubeb/cubeb.h>
|
|
||||||
#include <devices/common/hwcomponent.h>
|
#include <devices/common/hwcomponent.h>
|
||||||
|
|
||||||
enum {
|
#include <memory>
|
||||||
SND_SERVER_DOWN = 0,
|
|
||||||
SND_API_READY,
|
|
||||||
SND_SERVER_UP,
|
|
||||||
SND_STREAM_OPENED,
|
|
||||||
SND_STREAM_CLOSED
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class SoundServer : public HWComponent {
|
class SoundServer : public HWComponent {
|
||||||
public:
|
public:
|
||||||
SoundServer() {
|
SoundServer();
|
||||||
supports_types(HWCompType::SND_SERVER);
|
~SoundServer();
|
||||||
this->start();
|
|
||||||
};
|
|
||||||
~SoundServer() { this->shutdown(); };
|
|
||||||
|
|
||||||
int start();
|
int start();
|
||||||
void shutdown();
|
void shutdown();
|
||||||
@ -61,10 +50,8 @@ public:
|
|||||||
void close_out_stream();
|
void close_out_stream();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int status; /* server status */
|
class Impl; // Holds private fields
|
||||||
cubeb *cubeb_ctx;
|
std::unique_ptr<Impl> impl;
|
||||||
|
|
||||||
cubeb_stream *out_stream;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* SOUND_SERVER_H */
|
#endif /* SOUND_SERVER_H */
|
||||||
|
@ -29,60 +29,87 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
#include <objbase.h>
|
#include <objbase.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
enum {
|
||||||
|
SND_SERVER_DOWN = 0,
|
||||||
|
SND_API_READY,
|
||||||
|
SND_SERVER_UP,
|
||||||
|
SND_STREAM_OPENED,
|
||||||
|
SND_STREAM_CLOSED
|
||||||
|
};
|
||||||
|
|
||||||
|
class SoundServer::Impl {
|
||||||
|
public:
|
||||||
|
int status; /* server status */
|
||||||
|
cubeb *cubeb_ctx;
|
||||||
|
|
||||||
|
cubeb_stream *out_stream;
|
||||||
|
};
|
||||||
|
|
||||||
|
SoundServer::SoundServer(): impl(std::make_unique<Impl>())
|
||||||
|
{
|
||||||
|
supports_types(HWCompType::SND_SERVER);
|
||||||
|
this->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
SoundServer::~SoundServer()
|
||||||
|
{
|
||||||
|
this->shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
int SoundServer::start()
|
int SoundServer::start()
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
this->status = SND_SERVER_DOWN;
|
impl->status = SND_SERVER_DOWN;
|
||||||
|
|
||||||
this->soundio = soundio_create();
|
impl->soundio = soundio_create();
|
||||||
if (!this->soundio) {
|
if (!impl->soundio) {
|
||||||
LOG_F(ERROR, "Sound Server: out of memory");
|
LOG_F(ERROR, "Sound Server: out of memory");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((err = soundio_connect(this->soundio))) {
|
if ((err = soundio_connect(impl->soundio))) {
|
||||||
LOG_F(ERROR, "Unable to connect to backend: %s", soundio_strerror(err));
|
LOG_F(ERROR, "Unable to connect to backend: %s", soundio_strerror(err));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_F(INFO, "Connected to backend: %s", soundio_backend_name(soundio->current_backend));
|
LOG_F(INFO, "Connected to backend: %s", soundio_backend_name(soundio->current_backend));
|
||||||
|
|
||||||
soundio_flush_events(this->soundio);
|
soundio_flush_events(impl->soundio);
|
||||||
|
|
||||||
this->status = SND_API_READY;
|
impl->status = SND_API_READY;
|
||||||
|
|
||||||
this->out_dev_index = soundio_default_output_device_index(this->soundio);
|
impl->out_dev_index = soundio_default_output_device_index(impl->soundio);
|
||||||
if (this->out_dev_index < 0) {
|
if (impl->out_dev_index < 0) {
|
||||||
LOG_F(ERROR, "Sound Server: no output device found");
|
LOG_F(ERROR, "Sound Server: no output device found");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->out_device = soundio_get_output_device(this->soundio, this->out_dev_index);
|
impl->out_device = soundio_get_output_device(this->soundio, this->out_dev_index);
|
||||||
if (!this->out_device) {
|
if (!impl->out_device) {
|
||||||
LOG_F(ERROR, "Sound Server: out of memory");
|
LOG_F(ERROR, "Sound Server: out of memory");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_F(INFO, "Sound Server output device: %s", this->out_device->name);
|
LOG_F(INFO, "Sound Server output device: %s", impl->out_device->name);
|
||||||
|
|
||||||
this->status = SND_SERVER_UP;
|
impl->status = SND_SERVER_UP;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundServer::shutdown()
|
void SoundServer::shutdown()
|
||||||
{
|
{
|
||||||
switch (this->status) {
|
switch (impl->status) {
|
||||||
case SND_SERVER_UP:
|
case SND_SERVER_UP:
|
||||||
soundio_device_unref(this->out_device);
|
soundio_device_unref(impl->out_device);
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case SND_API_READY:
|
case SND_API_READY:
|
||||||
soundio_destroy(this->soundio);
|
soundio_destroy(impl->soundio);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->status = SND_SERVER_DOWN;
|
impl->status = SND_SERVER_DOWN;
|
||||||
|
|
||||||
LOG_F(INFO, "Sound Server shut down.");
|
LOG_F(INFO, "Sound Server shut down.");
|
||||||
}
|
}
|
||||||
@ -96,24 +123,24 @@ int SoundServer::start()
|
|||||||
CoInitialize(nullptr);
|
CoInitialize(nullptr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
this->status = SND_SERVER_DOWN;
|
impl->status = SND_SERVER_DOWN;
|
||||||
|
|
||||||
res = cubeb_init(&this->cubeb_ctx, "Dingus sound server", NULL);
|
res = cubeb_init(&impl->cubeb_ctx, "Dingus sound server", NULL);
|
||||||
if (res != CUBEB_OK) {
|
if (res != CUBEB_OK) {
|
||||||
LOG_F(ERROR, "Could not initialize Cubeb library");
|
LOG_F(ERROR, "Could not initialize Cubeb library");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_F(INFO, "Connected to backend: %s", cubeb_get_backend_id(this->cubeb_ctx));
|
LOG_F(INFO, "Connected to backend: %s", cubeb_get_backend_id(impl->cubeb_ctx));
|
||||||
|
|
||||||
this->status = SND_API_READY;
|
impl->status = SND_API_READY;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundServer::shutdown()
|
void SoundServer::shutdown()
|
||||||
{
|
{
|
||||||
switch (this->status) {
|
switch (impl->status) {
|
||||||
case SND_STREAM_OPENED:
|
case SND_STREAM_OPENED:
|
||||||
close_out_stream();
|
close_out_stream();
|
||||||
/* fall through */
|
/* fall through */
|
||||||
@ -122,10 +149,10 @@ void SoundServer::shutdown()
|
|||||||
case SND_SERVER_UP:
|
case SND_SERVER_UP:
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case SND_API_READY:
|
case SND_API_READY:
|
||||||
cubeb_destroy(this->cubeb_ctx);
|
cubeb_destroy(impl->cubeb_ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->status = SND_SERVER_DOWN;
|
impl->status = SND_SERVER_DOWN;
|
||||||
|
|
||||||
LOG_F(INFO, "Sound Server shut down.");
|
LOG_F(INFO, "Sound Server shut down.");
|
||||||
}
|
}
|
||||||
@ -189,7 +216,7 @@ int SoundServer::open_out_stream(uint32_t sample_rate, void *user_data)
|
|||||||
params.layout = CUBEB_LAYOUT_STEREO;
|
params.layout = CUBEB_LAYOUT_STEREO;
|
||||||
params.prefs = CUBEB_STREAM_PREF_NONE;
|
params.prefs = CUBEB_STREAM_PREF_NONE;
|
||||||
|
|
||||||
res = cubeb_get_min_latency(this->cubeb_ctx, ¶ms, &latency_frames);
|
res = cubeb_get_min_latency(impl->cubeb_ctx, ¶ms, &latency_frames);
|
||||||
if (res != CUBEB_OK) {
|
if (res != CUBEB_OK) {
|
||||||
LOG_F(ERROR, "Could not get minimum latency, error: %d", res);
|
LOG_F(ERROR, "Could not get minimum latency, error: %d", res);
|
||||||
return -1;
|
return -1;
|
||||||
@ -197,7 +224,7 @@ int SoundServer::open_out_stream(uint32_t sample_rate, void *user_data)
|
|||||||
LOG_F(9, "Minimum sound latency: %d frames", latency_frames);
|
LOG_F(9, "Minimum sound latency: %d frames", latency_frames);
|
||||||
}
|
}
|
||||||
|
|
||||||
res = cubeb_stream_init(this->cubeb_ctx, &this->out_stream, "SndOut stream",
|
res = cubeb_stream_init(impl->cubeb_ctx, &impl->out_stream, "SndOut stream",
|
||||||
NULL, NULL, NULL, ¶ms, latency_frames,
|
NULL, NULL, NULL, ¶ms, latency_frames,
|
||||||
sound_out_callback, status_callback, user_data);
|
sound_out_callback, status_callback, user_data);
|
||||||
if (res != CUBEB_OK) {
|
if (res != CUBEB_OK) {
|
||||||
@ -207,20 +234,20 @@ int SoundServer::open_out_stream(uint32_t sample_rate, void *user_data)
|
|||||||
|
|
||||||
LOG_F(9, "Sound output stream opened.");
|
LOG_F(9, "Sound output stream opened.");
|
||||||
|
|
||||||
this->status = SND_STREAM_OPENED;
|
impl->status = SND_STREAM_OPENED;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SoundServer::start_out_stream()
|
int SoundServer::start_out_stream()
|
||||||
{
|
{
|
||||||
return cubeb_stream_start(this->out_stream);
|
return cubeb_stream_start(impl->out_stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundServer::close_out_stream()
|
void SoundServer::close_out_stream()
|
||||||
{
|
{
|
||||||
cubeb_stream_stop(this->out_stream);
|
cubeb_stream_stop(impl->out_stream);
|
||||||
cubeb_stream_destroy(this->out_stream);
|
cubeb_stream_destroy(impl->out_stream);
|
||||||
this->status = SND_STREAM_CLOSED;
|
impl->status = SND_STREAM_CLOSED;
|
||||||
LOG_F(9, "Sound output stream closed.");
|
LOG_F(9, "Sound output stream closed.");
|
||||||
}
|
}
|
53
devices/video/display.h
Normal file
53
devices/video/display.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
DingusPPC - The Experimental PowerPC Macintosh emulator
|
||||||
|
Copyright (C) 2018-23 divingkatae and maximum
|
||||||
|
(theweirdo) spatium
|
||||||
|
|
||||||
|
(Contact divingkatae#1017 or powermax#2286 on Discord for more info)
|
||||||
|
|
||||||
|
This program 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.
|
||||||
|
|
||||||
|
This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @file Display/screen abstraction (implemented on each platform). */
|
||||||
|
|
||||||
|
#ifndef DISPLAY_H
|
||||||
|
#define DISPLAY_H
|
||||||
|
|
||||||
|
#include <core/hostevents.h>
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
class Display {
|
||||||
|
public:
|
||||||
|
Display();
|
||||||
|
~Display();
|
||||||
|
|
||||||
|
// Configures the display for the given width/height.
|
||||||
|
// Returns true if this is the first time the screen has been configured.
|
||||||
|
bool configure(int width, int height);
|
||||||
|
|
||||||
|
// Clears the display
|
||||||
|
void blank();
|
||||||
|
|
||||||
|
void update(std::function<void(uint8_t *dst_buf, int dst_pitch)> convert_fb_cb, bool draw_hw_cursor, int cursor_x, int cursor_y);
|
||||||
|
|
||||||
|
void handle_events(const WindowEvent& wnd_event);
|
||||||
|
void setup_hw_cursor(std::function<void(uint8_t *dst_buf, int dst_pitch)> draw_hw_cursor, int cursor_width, int cursor_height);
|
||||||
|
private:
|
||||||
|
class Impl; // Holds private fields
|
||||||
|
std::unique_ptr<Impl> impl;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // DISPLAY_H
|
157
devices/video/display_sdl.cpp
Normal file
157
devices/video/display_sdl.cpp
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
#include <devices/video/display.h>
|
||||||
|
#include <SDL.h>
|
||||||
|
#include <loguru.hpp>
|
||||||
|
|
||||||
|
class Display::Impl {
|
||||||
|
public:
|
||||||
|
bool resizing = false;
|
||||||
|
uint32_t disp_wnd_id = 0;
|
||||||
|
SDL_Window* display_wnd = 0;
|
||||||
|
SDL_Renderer* renderer = 0;
|
||||||
|
SDL_Texture* disp_texture = 0;
|
||||||
|
SDL_Texture* cursor_texture = 0;
|
||||||
|
SDL_Rect cursor_rect; // destination rectangle for cursor drawing
|
||||||
|
};
|
||||||
|
|
||||||
|
Display::Display(): impl(std::make_unique<Impl>())
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Display::~Display()
|
||||||
|
{
|
||||||
|
if (impl->cursor_texture) {
|
||||||
|
SDL_DestroyTexture(impl->cursor_texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (impl->disp_texture) {
|
||||||
|
SDL_DestroyTexture(impl->disp_texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (impl->renderer) {
|
||||||
|
SDL_DestroyRenderer(impl->renderer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (impl->display_wnd) {
|
||||||
|
SDL_DestroyWindow(impl->display_wnd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Display::configure(int width, int height)
|
||||||
|
{
|
||||||
|
bool is_initialization = false;
|
||||||
|
|
||||||
|
if (!impl->display_wnd) { // create display window
|
||||||
|
impl->display_wnd = SDL_CreateWindow(
|
||||||
|
"DingusPPC Display",
|
||||||
|
SDL_WINDOWPOS_UNDEFINED,
|
||||||
|
SDL_WINDOWPOS_UNDEFINED,
|
||||||
|
width, height,
|
||||||
|
SDL_WINDOW_OPENGL
|
||||||
|
);
|
||||||
|
|
||||||
|
impl->disp_wnd_id = SDL_GetWindowID(impl->display_wnd);
|
||||||
|
if (impl->display_wnd == NULL) {
|
||||||
|
ABORT_F("Display: SDL_CreateWindow failed with %s", SDL_GetError());
|
||||||
|
}
|
||||||
|
|
||||||
|
impl->renderer = SDL_CreateRenderer(impl->display_wnd, -1, SDL_RENDERER_ACCELERATED);
|
||||||
|
if (impl->renderer == NULL) {
|
||||||
|
ABORT_F("Display: SDL_CreateRenderer failed with %s", SDL_GetError());
|
||||||
|
}
|
||||||
|
|
||||||
|
is_initialization = true;
|
||||||
|
} else { // resize display window
|
||||||
|
SDL_SetWindowSize(impl->display_wnd, width, height);
|
||||||
|
impl->resizing = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (impl->disp_texture) {
|
||||||
|
SDL_DestroyTexture(impl->disp_texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl->disp_texture = SDL_CreateTexture(
|
||||||
|
impl->renderer,
|
||||||
|
SDL_PIXELFORMAT_ARGB8888,
|
||||||
|
SDL_TEXTUREACCESS_STREAMING,
|
||||||
|
width, height
|
||||||
|
);
|
||||||
|
|
||||||
|
if (impl->disp_texture == NULL) {
|
||||||
|
ABORT_F("Display: SDL_CreateTexture failed with %s", SDL_GetError());
|
||||||
|
}
|
||||||
|
|
||||||
|
return is_initialization;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Display::handle_events(const WindowEvent& wnd_event)
|
||||||
|
{
|
||||||
|
if (wnd_event.sub_type == SDL_WINDOWEVENT_SIZE_CHANGED &&
|
||||||
|
wnd_event.window_id == impl->disp_wnd_id)
|
||||||
|
impl->resizing = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Display::blank()
|
||||||
|
{
|
||||||
|
SDL_SetRenderDrawColor(impl->renderer, 0, 0, 0, 255);
|
||||||
|
SDL_RenderClear(impl->renderer);
|
||||||
|
SDL_RenderPresent(impl->renderer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Display::update(std::function<void(uint8_t *dst_buf, int dst_pitch)> convert_fb_cb, bool draw_hw_cursor, int cursor_x, int cursor_y)
|
||||||
|
{
|
||||||
|
if (impl->resizing)
|
||||||
|
return;
|
||||||
|
|
||||||
|
uint8_t* dst_buf;
|
||||||
|
int dst_pitch;
|
||||||
|
|
||||||
|
SDL_LockTexture(impl->disp_texture, NULL, (void **)&dst_buf, &dst_pitch);
|
||||||
|
|
||||||
|
// texture update callback to get ARGB data from guest framebuffer
|
||||||
|
convert_fb_cb(dst_buf, dst_pitch);
|
||||||
|
|
||||||
|
SDL_UnlockTexture(impl->disp_texture);
|
||||||
|
SDL_RenderClear(impl->renderer);
|
||||||
|
SDL_RenderCopy(impl->renderer, impl->disp_texture, NULL, NULL);
|
||||||
|
|
||||||
|
// draw HW cursor if enabled
|
||||||
|
if (draw_hw_cursor) {
|
||||||
|
impl->cursor_rect.x = cursor_x;
|
||||||
|
impl->cursor_rect.y = cursor_y;
|
||||||
|
SDL_RenderCopy(impl->renderer, impl->cursor_texture, NULL, &impl->cursor_rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_RenderPresent(impl->renderer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Display::setup_hw_cursor(std::function<void(uint8_t *dst_buf, int dst_pitch)> draw_hw_cursor, int cursor_width, int cursor_height)
|
||||||
|
{
|
||||||
|
uint8_t* dst_buf;
|
||||||
|
int dst_pitch;
|
||||||
|
|
||||||
|
if (impl->cursor_texture) {
|
||||||
|
SDL_DestroyTexture(impl->cursor_texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl->cursor_texture = SDL_CreateTexture(
|
||||||
|
impl->renderer,
|
||||||
|
SDL_PIXELFORMAT_ARGB8888,
|
||||||
|
SDL_TEXTUREACCESS_STREAMING,
|
||||||
|
cursor_width, cursor_height
|
||||||
|
);
|
||||||
|
|
||||||
|
if (impl->cursor_texture == NULL) {
|
||||||
|
ABORT_F("SDL_CreateTexture for HW cursor failed with %s", SDL_GetError());
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_LockTexture(impl->cursor_texture, NULL, (void **)&dst_buf, &dst_pitch);
|
||||||
|
SDL_SetTextureBlendMode(impl->cursor_texture, SDL_BLENDMODE_BLEND);
|
||||||
|
draw_hw_cursor(dst_buf, dst_pitch);
|
||||||
|
SDL_UnlockTexture(impl->cursor_texture);
|
||||||
|
|
||||||
|
impl->cursor_rect.x = 0;
|
||||||
|
impl->cursor_rect.y = 0;
|
||||||
|
impl->cursor_rect.w = cursor_width;
|
||||||
|
impl->cursor_rect.h = cursor_height;
|
||||||
|
}
|
@ -23,11 +23,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
|
|
||||||
#include <core/timermanager.h>
|
#include <core/timermanager.h>
|
||||||
#include <devices/video/videoctrl.h>
|
#include <devices/video/videoctrl.h>
|
||||||
#include <loguru.hpp>
|
|
||||||
#include <memaccess.h>
|
#include <memaccess.h>
|
||||||
#include <SDL.h>
|
|
||||||
|
|
||||||
#include <chrono>
|
|
||||||
#include <cinttypes>
|
#include <cinttypes>
|
||||||
|
|
||||||
VideoCtrlBase::VideoCtrlBase(int width, int height)
|
VideoCtrlBase::VideoCtrlBase(int width, int height)
|
||||||
@ -39,115 +36,45 @@ VideoCtrlBase::VideoCtrlBase(int width, int height)
|
|||||||
|
|
||||||
VideoCtrlBase::~VideoCtrlBase()
|
VideoCtrlBase::~VideoCtrlBase()
|
||||||
{
|
{
|
||||||
if (this->cursor_texture) {
|
|
||||||
SDL_DestroyTexture(this->cursor_texture);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->disp_texture) {
|
|
||||||
SDL_DestroyTexture(this->disp_texture);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->renderer) {
|
|
||||||
SDL_DestroyRenderer(this->renderer);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->display_wnd) {
|
|
||||||
SDL_DestroyWindow(this->display_wnd);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoCtrlBase::handle_events(const WindowEvent& wnd_event) {
|
void VideoCtrlBase::handle_events(const WindowEvent& wnd_event) {
|
||||||
if (wnd_event.sub_type == SDL_WINDOWEVENT_SIZE_CHANGED &&
|
this->display.handle_events(wnd_event);
|
||||||
wnd_event.window_id == this->disp_wnd_id)
|
|
||||||
this->resizing = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: consider renaming, since it's not always a window
|
||||||
void VideoCtrlBase::create_display_window(int width, int height)
|
void VideoCtrlBase::create_display_window(int width, int height)
|
||||||
{
|
{
|
||||||
if (!this->display_wnd) { // create display window
|
bool is_initialization = this->display.configure(width, height);
|
||||||
this->display_wnd = SDL_CreateWindow(
|
if (is_initialization) {
|
||||||
"DingusPPC Display",
|
|
||||||
SDL_WINDOWPOS_UNDEFINED,
|
|
||||||
SDL_WINDOWPOS_UNDEFINED,
|
|
||||||
width, height,
|
|
||||||
SDL_WINDOW_OPENGL
|
|
||||||
);
|
|
||||||
|
|
||||||
this->disp_wnd_id = SDL_GetWindowID(this->display_wnd);
|
|
||||||
|
|
||||||
if (this->display_wnd == NULL) {
|
|
||||||
ABORT_F("Display: SDL_CreateWindow failed with %s", SDL_GetError());
|
|
||||||
}
|
|
||||||
|
|
||||||
this->renderer = SDL_CreateRenderer(this->display_wnd, -1, SDL_RENDERER_ACCELERATED);
|
|
||||||
if (this->renderer == NULL) {
|
|
||||||
ABORT_F("Display: SDL_CreateRenderer failed with %s", SDL_GetError());
|
|
||||||
}
|
|
||||||
|
|
||||||
this->blank_on = true; // TODO: should be true!
|
this->blank_on = true; // TODO: should be true!
|
||||||
|
|
||||||
this->blank_display();
|
this->blank_display();
|
||||||
} else { // resize display window
|
|
||||||
SDL_SetWindowSize(this->display_wnd, width, height);
|
|
||||||
this->resizing = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this->active_width = width;
|
this->active_width = width;
|
||||||
this->active_height = height;
|
this->active_height = height;
|
||||||
|
|
||||||
if (this->disp_texture) {
|
|
||||||
SDL_DestroyTexture(this->disp_texture);
|
|
||||||
}
|
|
||||||
|
|
||||||
this->disp_texture = SDL_CreateTexture(
|
|
||||||
this->renderer,
|
|
||||||
SDL_PIXELFORMAT_ARGB8888,
|
|
||||||
SDL_TEXTUREACCESS_STREAMING,
|
|
||||||
width, height
|
|
||||||
);
|
|
||||||
|
|
||||||
if (this->disp_texture == NULL) {
|
|
||||||
ABORT_F("Display: SDL_CreateTexture failed with %s", SDL_GetError());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoCtrlBase::blank_display() {
|
void VideoCtrlBase::blank_display() {
|
||||||
SDL_SetRenderDrawColor(this->renderer, 0, 0, 0, 255);
|
this->display.blank();
|
||||||
SDL_RenderClear(this->renderer);
|
|
||||||
SDL_RenderPresent(this->renderer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoCtrlBase::update_screen()
|
void VideoCtrlBase::update_screen()
|
||||||
{
|
{
|
||||||
uint8_t* dst_buf;
|
|
||||||
int dst_pitch;
|
|
||||||
|
|
||||||
//auto start_time = std::chrono::steady_clock::now();
|
|
||||||
|
|
||||||
if (this->resizing)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (this->blank_on) {
|
if (this->blank_on) {
|
||||||
this->blank_display();
|
this->display.blank();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_LockTexture(this->disp_texture, NULL, (void **)&dst_buf, &dst_pitch);
|
int cursor_x = 0;
|
||||||
|
int cursor_y = 0;
|
||||||
// texture update callback to get ARGB data from guest framebuffer
|
|
||||||
this->convert_fb_cb(dst_buf, dst_pitch);
|
|
||||||
|
|
||||||
SDL_UnlockTexture(this->disp_texture);
|
|
||||||
SDL_RenderClear(this->renderer);
|
|
||||||
SDL_RenderCopy(this->renderer, this->disp_texture, NULL, NULL);
|
|
||||||
|
|
||||||
// draw HW cursor if enabled
|
|
||||||
if (this->cursor_on) {
|
if (this->cursor_on) {
|
||||||
this->get_cursor_position(cursor_rect.x, cursor_rect.y);
|
this->get_cursor_position(cursor_x, cursor_y);
|
||||||
SDL_RenderCopy(this->renderer, this->cursor_texture, NULL, &cursor_rect);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_RenderPresent(this->renderer);
|
this->display.update(
|
||||||
|
this->convert_fb_cb,
|
||||||
|
this->cursor_on, cursor_x, cursor_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoCtrlBase::start_refresh_task() {
|
void VideoCtrlBase::start_refresh_task() {
|
||||||
@ -200,34 +127,11 @@ void VideoCtrlBase::set_palette_color(uint8_t index, uint8_t r, uint8_t g, uint8
|
|||||||
|
|
||||||
void VideoCtrlBase::setup_hw_cursor(int cursor_width, int cursor_height)
|
void VideoCtrlBase::setup_hw_cursor(int cursor_width, int cursor_height)
|
||||||
{
|
{
|
||||||
uint8_t* dst_buf;
|
this->display.setup_hw_cursor(
|
||||||
int dst_pitch;
|
[this](uint8_t *dst_buf, int dst_pitch) {
|
||||||
|
|
||||||
if (this->cursor_texture) {
|
|
||||||
SDL_DestroyTexture(this->cursor_texture);
|
|
||||||
}
|
|
||||||
|
|
||||||
this->cursor_texture = SDL_CreateTexture(
|
|
||||||
this->renderer,
|
|
||||||
SDL_PIXELFORMAT_ARGB8888,
|
|
||||||
SDL_TEXTUREACCESS_STREAMING,
|
|
||||||
cursor_width, cursor_height
|
|
||||||
);
|
|
||||||
|
|
||||||
if (this->cursor_texture == NULL) {
|
|
||||||
ABORT_F("SDL_CreateTexture for HW cursor failed with %s", SDL_GetError());
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_LockTexture(this->cursor_texture, NULL, (void **)&dst_buf, &dst_pitch);
|
|
||||||
SDL_SetTextureBlendMode(this->cursor_texture, SDL_BLENDMODE_BLEND);
|
|
||||||
this->draw_hw_cursor(dst_buf, dst_pitch);
|
this->draw_hw_cursor(dst_buf, dst_pitch);
|
||||||
SDL_UnlockTexture(this->cursor_texture);
|
},
|
||||||
|
cursor_width, cursor_height);
|
||||||
this->cursor_rect.x = 0;
|
|
||||||
this->cursor_rect.y = 0;
|
|
||||||
this->cursor_rect.w = cursor_width;
|
|
||||||
this->cursor_rect.h = cursor_height;
|
|
||||||
|
|
||||||
this->cursor_on = true;
|
this->cursor_on = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
|
|
||||||
#include <core/hostevents.h>
|
#include <core/hostevents.h>
|
||||||
#include <devices/common/hwinterrupt.h>
|
#include <devices/common/hwinterrupt.h>
|
||||||
#include <SDL.h>
|
#include <devices/video/display.h>
|
||||||
|
|
||||||
#include <cinttypes>
|
#include <cinttypes>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
@ -61,7 +61,6 @@ protected:
|
|||||||
// CRT controller parameters
|
// CRT controller parameters
|
||||||
bool crtc_on = false;
|
bool crtc_on = false;
|
||||||
bool blank_on = true;
|
bool blank_on = true;
|
||||||
bool resizing = false;
|
|
||||||
bool cursor_on = false;
|
bool cursor_on = false;
|
||||||
int active_width; // width of the visible display area
|
int active_width; // width of the visible display area
|
||||||
int active_height; // height of the visible display area
|
int active_height; // height of the visible display area
|
||||||
@ -88,12 +87,7 @@ protected:
|
|||||||
std::function<void(uint8_t *dst_buf, int dst_pitch)> convert_fb_cb;
|
std::function<void(uint8_t *dst_buf, int dst_pitch)> convert_fb_cb;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t disp_wnd_id = 0;
|
Display display;
|
||||||
SDL_Window* display_wnd = 0;
|
|
||||||
SDL_Renderer* renderer = 0;
|
|
||||||
SDL_Texture* disp_texture = 0;
|
|
||||||
SDL_Texture* cursor_texture = 0;
|
|
||||||
SDL_Rect cursor_rect; // destination rectangle for cursor drawing
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // VIDEO_CTRL_H
|
#endif // VIDEO_CTRL_H
|
||||||
|
@ -7,4 +7,4 @@ include_directories("${PROJECT_SOURCE_DIR}"
|
|||||||
file(GLOB SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp")
|
file(GLOB SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp")
|
||||||
|
|
||||||
add_library(machines OBJECT ${SOURCES})
|
add_library(machines OBJECT ${SOURCES})
|
||||||
target_link_libraries(machines PRIVATE cubeb SDL2::SDL2)
|
target_link_libraries(machines PRIVATE)
|
||||||
|
12
main.cpp
12
main.cpp
@ -29,6 +29,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
#include <machines/machinefactory.h>
|
#include <machines/machinefactory.h>
|
||||||
#include <machines/machineproperties.h>
|
#include <machines/machineproperties.h>
|
||||||
#include <utils/profiler.h>
|
#include <utils/profiler.h>
|
||||||
|
#include <main.h>
|
||||||
|
|
||||||
#include <cinttypes>
|
#include <cinttypes>
|
||||||
#include <csignal>
|
#include <csignal>
|
||||||
@ -38,7 +39,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <CLI11.hpp>
|
#include <CLI11.hpp>
|
||||||
#include <SDL.h>
|
|
||||||
#include <loguru.hpp>
|
#include <loguru.hpp>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@ -49,7 +49,7 @@ void sigint_handler(int signum) {
|
|||||||
LOG_F(INFO, "Shutting down...");
|
LOG_F(INFO, "Shutting down...");
|
||||||
|
|
||||||
delete gMachineObj.release();
|
delete gMachineObj.release();
|
||||||
SDL_Quit();
|
cleanup();
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ void sigabrt_handler(int signum) {
|
|||||||
LOG_F(INFO, "Shutting down...");
|
LOG_F(INFO, "Shutting down...");
|
||||||
|
|
||||||
delete gMachineObj.release();
|
delete gMachineObj.release();
|
||||||
SDL_Quit();
|
cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
static string appDescription = string(
|
static string appDescription = string(
|
||||||
@ -166,8 +166,8 @@ int main(int argc, char** argv) {
|
|||||||
cout << "BootROM path: " << bootrom_path << endl;
|
cout << "BootROM path: " << bootrom_path << endl;
|
||||||
cout << "Execution mode: " << execution_mode << endl;
|
cout << "Execution mode: " << execution_mode << endl;
|
||||||
|
|
||||||
if (SDL_Init(SDL_INIT_VIDEO)) {
|
if (!init()) {
|
||||||
LOG_F(ERROR, "SDL_Init error: %s", SDL_GetError());
|
LOG_F(ERROR, "Cannot initialize");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,7 +217,7 @@ bail:
|
|||||||
|
|
||||||
delete gMachineObj.release();
|
delete gMachineObj.release();
|
||||||
|
|
||||||
SDL_Quit();
|
cleanup();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
25
main.h
Normal file
25
main.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
DingusPPC - The Experimental PowerPC Macintosh emulator
|
||||||
|
Copyright (C) 2018-23 divingkatae and maximum
|
||||||
|
(theweirdo) spatium
|
||||||
|
|
||||||
|
(Contact divingkatae#1017 or powermax#2286 on Discord for more info)
|
||||||
|
|
||||||
|
This program 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.
|
||||||
|
|
||||||
|
This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @file Platform-specific main functions. */
|
||||||
|
|
||||||
|
bool init();
|
||||||
|
void cleanup();
|
38
main_sdl.cpp
Normal file
38
main_sdl.cpp
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
DingusPPC - The Experimental PowerPC Macintosh emulator
|
||||||
|
Copyright (C) 2018-23 divingkatae and maximum
|
||||||
|
(theweirdo) spatium
|
||||||
|
|
||||||
|
(Contact divingkatae#1017 or powermax#2286 on Discord for more info)
|
||||||
|
|
||||||
|
This program 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.
|
||||||
|
|
||||||
|
This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @file SDL-specific main functions. */
|
||||||
|
|
||||||
|
#include <main.h>
|
||||||
|
#include <loguru.hpp>
|
||||||
|
#include <SDL.h>
|
||||||
|
|
||||||
|
bool init() {
|
||||||
|
if (SDL_Init(SDL_INIT_VIDEO)) {
|
||||||
|
LOG_F(ERROR, "SDL_Init error: %s", SDL_GetError());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cleanup() {
|
||||||
|
SDL_Quit();
|
||||||
|
}
|
@ -3,4 +3,4 @@ include_directories("${PROJECT_SOURCE_DIR}")
|
|||||||
file(GLOB SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp")
|
file(GLOB SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp")
|
||||||
|
|
||||||
add_library(utils OBJECT ${SOURCES})
|
add_library(utils OBJECT ${SOURCES})
|
||||||
target_link_libraries(utils PRIVATE cubeb)
|
target_link_libraries(utils PRIVATE)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user