Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions .github/workflows/dreamcast.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,23 @@ concurrency:
jobs:
build:
runs-on: ubuntu-latest
container: azihassan/kallistios:docker
container: azihassan/kallistios:8c7fbfcf3c38c4da82bc067e1719b74c2f93f755
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Patch KOS for streaming a large quantity of files
run: |
source /opt/toolchains/dc/kos/environ.sh && \
cd /opt/toolchains/dc/kos && \
sed -i 's/THD_KERNEL_STACK_SIZE (64 \* 1024)/THD_KERNEL_STACK_SIZE (256 \* 1024)/g' /opt/toolchains/dc/kos/kernel/arch/dreamcast/include/arch/arch.h && \
echo "THD_KERNEL_STACK_SIZE changed to $(cat /opt/toolchains/dc/kos/kernel/arch/dreamcast/include/arch/arch.h | grep THD_KERNEL_STACK_SIZE)" && \
sed -i 's/THD_STACK_SIZE 32768/THD_STACK_SIZE (128*1024)/g' /opt/toolchains/dc/kos/kernel/arch/dreamcast/include/arch/arch.h && \
echo "THD_STACK_SIZE changed to $(cat /opt/toolchains/dc/kos/kernel/arch/dreamcast/include/arch/arch.h | grep THD_STACK_SIZE)" && \
make clean && make CFLAGS+="-DFS_CD_MAX_FILES=4096 -DFD_SETSIZE=4096"

- name: Build unpack_and_minify_mpq
run: |
git clone https://github.com/diasurgical/devilutionx-mpq-tools/ && \
Expand Down Expand Up @@ -82,7 +92,7 @@ jobs:

- name: Build DevilutionX
run: |
source /opt/toolchains/dc/kos/environ.sh && cd build && kos-make
source /opt/toolchains/dc/kos/environ.sh && cd build && kos-make -j4

- name: Generate .cdi
run: |
Expand Down
2 changes: 1 addition & 1 deletion 3rdParty/libfmt/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,6 @@ if(TARGET_PLATFORM STREQUAL "rg99" OR PLATFORM_DREAMCAST)
endif()

# https://github.com/fmtlib/fmt/issues/4189
if(NINTENDO_3DS OR NINTENDO_SWITCH OR VITA)
if(NINTENDO_3DS OR NINTENDO_SWITCH OR VITA OR PLATFORM_DREAMCAST)
target_compile_definitions(fmt PUBLIC FMT_USE_FALLBACK_FILE=1)
endif()
15 changes: 12 additions & 3 deletions CMake/platforms/dreamcast.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ set(DEFAULT_WIDTH 640)
set(DEFAULT_HEIGHT 480)
set(DEVILUTIONX_GAMEPAD_TYPE Nintendo)

set(NOSOUND ON)
#set(NOSOUND ON)
set(DEVILUTIONX_STATIC_ZLIB ON)
set(UNPACKED_MPQS ON)
set(UNPACKED_SAVES ON)
Expand All @@ -21,7 +21,7 @@ set(DEVILUTIONX_DISABLE_STRIP ON)
set(DEVILUTIONX_ASSETS_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/data/")
set(BUILD_ASSETS_MPQ OFF)

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/threads-stub")
#list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/threads-stub")
list(APPEND DEVILUTIONX_PLATFORM_COMPILE_DEFINITIONS __DREAMCAST__)
add_compile_options(-fpermissive)

Expand All @@ -47,4 +47,13 @@ set(JOY_BUTTON_START 3)
set(SDL_INCLUDE_DIR /usr/include/SDL/)
set(SDL_LIBRARY /usr/lib/libSDL.a)

add_compile_options(-flto=none)
add_compile_options(-flto=auto)

# Must stream most of the audio due to RAM constraints.
set(STREAM_ALL_AUDIO_MIN_FILE_SIZE 1023)

# Must use a smaller audio buffer due to RAM constraints.
set(DEFAULT_AUDIO_BUFFER_SIZE 768)

# Use lower resampling quality for FPS.
set(DEFAULT_AUDIO_RESAMPLING_QUALITY 1)
12 changes: 11 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
FROM azihassan/kallistios:fdffe33635239d46bcccf0d5c4d59bb7d2d91f38
FROM azihassan/kallistios:8c7fbfcf3c38c4da82bc067e1719b74c2f93f755

RUN echo "Patching KOS for streaming a large quantity of files"
RUN source /opt/toolchains/dc/kos/environ.sh && \
cd /opt/toolchains/dc/kos && \
sed -i 's/THD_KERNEL_STACK_SIZE (64 \* 1024)/THD_KERNEL_STACK_SIZE (256 \* 1024)/g' /opt/toolchains/dc/kos/kernel/arch/dreamcast/include/arch/arch.h && \
echo "THD_KERNEL_STACK_SIZE changed to $(cat /opt/toolchains/dc/kos/kernel/arch/dreamcast/include/arch/arch.h | grep THD_KERNEL_STACK_SIZE)" && \
sed -i 's/THD_STACK_SIZE 32768/THD_STACK_SIZE (128*1024)/g' /opt/toolchains/dc/kos/kernel/arch/dreamcast/include/arch/arch.h && \
echo "THD_STACK_SIZE changed to $(cat /opt/toolchains/dc/kos/kernel/arch/dreamcast/include/arch/arch.h | grep THD_STACK_SIZE)" && \
make clean && \
make CFLAGS+="-DFS_CD_MAX_FILES=4096 -DFD_SETSIZE=4096"

RUN echo "Building unpack_and_minify_mpq..."
RUN git clone https://github.com/diasurgical/devilutionx-mpq-tools/ && \
Expand Down
3 changes: 3 additions & 0 deletions Source/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,9 @@ if(DEVILUTIONX_SCREENSHOT_FORMAT STREQUAL DEVILUTIONX_SCREENSHOT_FORMAT_PNG)
utils/surface_to_png.cpp
)
endif()
if(PLATFORM_DREAMCAST)
list(APPEND libdevilutionx_SRCS memory_stats.cpp)
endif()

add_devilutionx_library(libdevilutionx OBJECT ${libdevilutionx_SRCS})
target_include_directories(libdevilutionx PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
Expand Down
7 changes: 7 additions & 0 deletions Source/diablo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@
#include <gperftools/heap-profiler.h>
#endif

#ifdef __DREAMCAST__
#include "memory_stats.h"
#endif

namespace devilution {

uint32_t DungeonSeeds[NUMLEVELS];
Expand Down Expand Up @@ -2543,6 +2547,9 @@ void setOnInitialized(void (*callback)())

int DiabloMain(int argc, char **argv)
{
#ifdef __DREAMCAST__
set_system_ram();
#endif
#ifdef _DEBUG
SDL_LogSetAllPriority(SDL_LOG_PRIORITY_DEBUG);
#endif
Expand Down
10 changes: 9 additions & 1 deletion Source/effects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,8 +261,16 @@ void effects_cleanup_sfx()

void sound_init()
{
#ifdef __DREAMCAST__
bool isDreamcast = true;
#else
bool isDreamcast = false;
#endif
uint8_t mask = sfx_MISC;
if (gbIsMultiplayer) {
// only load the SFX of the current character on the dreamcast
// because it still doesn't have network multiplayer mode
// so we only need the sfx of the player's class
if (gbIsMultiplayer && !isDreamcast) {
mask |= sfx_WARRIOR;
if (!gbIsSpawn)
mask |= (sfx_ROGUE | sfx_SORCERER);
Expand Down
15 changes: 15 additions & 0 deletions Source/engine/sound.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@
#include "utils/str_cat.hpp"
#include "utils/stubs.h"

// todo remove this
// changing this value in dreamcast.cmake causes the whole project to recompile
// redefined here to only recompile sound.cpp
#define STREAM_ALL_AUDIO_MIN_FILE_SIZE 10 * 1024

namespace devilution {

bool gbSndInited;
Expand Down Expand Up @@ -71,6 +76,11 @@ bool LoadAudioFile(const char *path, bool stream, bool errorDialog, SoundSample
#endif
#endif

#ifdef __DREAMCAST__
Log(">AUDIO: Loading audio file {} with streaming {} ({} kilobytes)", foundPath, stream, ref.size() / 1024.0);
print_ram_stats();
Log("\n\n\n");
#endif
if (stream) {
if (result.SetChunkStream(foundPath, isMp3, /*logErrors=*/true) != 0) {
if (errorDialog) {
Expand All @@ -95,6 +105,7 @@ bool LoadAudioFile(const char *path, bool stream, bool errorDialog, SoundSample
return false;
}
const int error = result.SetChunk(waveFile, size, isMp3);

if (error != 0) {
if (errorDialog)
ErrSdl();
Expand Down Expand Up @@ -204,6 +215,9 @@ TSnd::~TSnd()

void snd_init()
{
#ifdef __DREAMCAST__
::snd_init();
#endif
sgOptions.Audio.soundVolume.SetValue(CapVolume(*sgOptions.Audio.soundVolume));
gbSoundOn = *sgOptions.Audio.soundVolume > VOLUME_MIN;
sgbSaveSoundOn = gbSoundOn;
Expand All @@ -228,6 +242,7 @@ void snd_init()
void snd_deinit()
{
if (gbSndInited) {
snd_shutdown();
Aulib::quit();
duplicateSoundsMutex = std::nullopt;
}
Expand Down
5 changes: 5 additions & 0 deletions Source/engine/sound.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@
#include "utils/attributes.h"

#ifndef NOSOUND
#ifdef __DREAMCAST__
#include "memory_stats.h"
#include <dc/sound/sound.h>
#endif

#include "utils/soundsample.h"
#endif

Expand Down
65 changes: 65 additions & 0 deletions Source/memory_stats.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// DREAMCAST memory stats related code

#include "memory_stats.h"

#include <dc/pvr.h>
#include <dc/sound/sound.h>

#include <malloc.h>
#include <stdio.h>

static unsigned long systemRam = 0x00000000;
static unsigned long elfOffset = 0x00000000;
static unsigned long stackSize = 0x00000000;

extern unsigned long end;
extern unsigned long start;

#define _end end
#define _start start
void print_VRAM_stats()
{
pvr_mem_available();
}

void set_system_ram()
{
systemRam = 0x8d000000 - 0x8c000000;
elfOffset = 0x8c000000;

stackSize = (int)&_end - (int)&_start + ((int)&_start - elfOffset);
}

unsigned long get_system_ram()
{
return systemRam;
}

unsigned long get_free_ram()
{
struct mallinfo mi = mallinfo();
return systemRam - (mi.usmblks + stackSize);
}

void print_ram_stats()
{
float sys_ram, free_ram, used_ram, pvr_ram, sound_ram;
sys_ram = (float)get_system_ram() / (float)(1024 * 1024);
free_ram = (float)get_free_ram() / (float)(1024 * 1024);
used_ram = (sys_ram - free_ram);
// pvr_ram = (float)pvr_mem_available() / (float)(1024*1024);
sound_ram = (float)snd_mem_available() / (float)(1024 * 1024);

printf("\n---------\nRAM stats (MB):\nTotal: %.2f, Free: %.2f, Used: %.2f, PVR: %.2f, Sound: %.2f\n---------\n", sys_ram, free_ram, used_ram, pvr_ram, sound_ram);
// printf("\n---------\nRAM stats (MB):\nTotal: %.2f, Free: %.2f, Used: %.2f\n---------\n", sys_ram, free_ram, used_ram);
}

void get_ram_stats(float *sys_ram, float *free_ram, float *used_ram, float *pvr_ram)
{
*sys_ram = (float)get_system_ram() / (float)(1024 * 1024);
*free_ram = (float)get_free_ram() / (float)(1024 * 1024);
*used_ram = (*sys_ram - *free_ram);
if (pvr_ram) {
//*pvr_ram = (float)pvr_mem_available() / (float)(1024*1024);
}
}
11 changes: 11 additions & 0 deletions Source/memory_stats.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#ifndef __MEMORY_STATS_H__
#define __MEMORY_STATS_H__ 1

void set_system_ram();
void print_VRAM_stats();
unsigned long get_system_ram();
unsigned long get_free_ram();
void print_ram_stats();
void get_ram_stats(float *sys_ram, float *free_ram, float *used_ram, float *pvr_ram);

#endif