Skip to content

Commit

Permalink
Merge branch 'master' of github.com:nba-emu/NanoBoyAdvance into stabl…
Browse files Browse the repository at this point in the history
…e-release
  • Loading branch information
fleroviux committed Apr 1, 2024
2 parents f119f2a + f531718 commit b473a4c
Show file tree
Hide file tree
Showing 29 changed files with 372 additions and 131 deletions.
75 changes: 63 additions & 12 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,20 @@ jobs:
run:
shell: msys2 {0}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: msys2/setup-msys2@v2
with:
install: make mingw-w64-x86_64-gcc mingw-w64-x86_64-cmake mingw-w64-x86_64-SDL2 mingw-w64-x86_64-glew mingw-w64-x86_64-qt5-static
install: make mingw-w64-x86_64-gcc mingw-w64-x86_64-cmake mingw-w64-x86_64-python-jinja mingw-w64-x86_64-python-lxml mingw-w64-x86_64-SDL2 mingw-w64-x86_64-qt5-static
- name: Build NanoBoyAdvance
run: |
cmake \
-Bbuild \
-G"Unix Makefiles" \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_FLAGS="-s" \
-DPython_EXECUTABLE="$(which python3)" \
-DPLATFORM_QT_STATIC=ON \
-DUSE_STATIC_SDL=ON \
-DGLEW_USE_STATIC_LIBS=ON \
-DRELEASE_BUILD=ON \
-DQT5_STATIC_DIR="/c/tools/msys64/mingw64/qt5-static"
cd build
Expand All @@ -32,7 +32,7 @@ jobs:
mkdir upload
cp -r build/bin/qt/{NanoBoyAdvance.exe,config.toml} upload
- name: Upload artifacts
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: NanoBoyAdvance-win64
path: upload
Expand All @@ -41,11 +41,11 @@ jobs:
build-linux:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Setup dependencies
run: |
sudo apt-get update -qq
sudo apt-get install -y libsdl2-dev libglew-dev qtbase5-dev
sudo apt-get install -y python3-jinja2 python3-lxml libsdl2-dev qtbase5-dev
- name: Build NanoBoyAdvance
run: |
cmake -Bbuild -DCMAKE_BUILD_TYPE=Release -DRELEASE_BUILD=ON
Expand All @@ -56,7 +56,7 @@ jobs:
mkdir upload
cp -r build/bin/qt/{NanoBoyAdvance,config.toml} upload
- name: Upload artifacts
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: NanoBoyAdvance-linux
path: upload
Expand All @@ -65,20 +65,71 @@ jobs:
build-macOS:
runs-on: macos-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Setup dependencies
env:
HOMEBREW_NO_ANALYTICS: 1
run: brew install sdl2 glew qt@5
run: |
brew install sdl2 qt@5
python3 -m pip install Jinja2
- name: Build NanoBoyAdvance
run: |
cmake -Bbuild \
-DCMAKE_CXX_FLAGS="-s" \
-DUSE_STATIC_SDL=ON \
-DGLEW_USE_STATIC_LIBS=ON \
-DCMAKE_BUILD_TYPE=Release \
<<<<<<< HEAD
-DRELEASE_BUILD=ON \
-DCMAKE_PREFIX_PATH="$(brew --prefix qt@5);$(brew --prefix glew)" \
=======
-DCMAKE_PREFIX_PATH="$(brew --prefix qt@5)" \
>>>>>>> f53171877606cd6916c5b13c022b06bde3e93aa5
-DMACOS_BUILD_APP_BUNDLE=ON \
-DMACOS_BUNDLE_QT=ON
cd build
make -j$(getconf _NPROCESSORS_ONLN)
- name: Create disk image
run: |
mkdir dmg
cp -a build/bin/qt/NanoBoyAdvance.app dmg/NanoBoyAdvance.app
codesign -s - --deep -f dmg/NanoBoyAdvance.app
ln -s /Applications dmg/Applications
hdiutil create \
-fs HFS+ \
-volname NanoBoyAdvance \
-srcfolder dmg \
-ov -format UDBZ \
NanoBoyAdvance.dmg
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: NanoBoyAdvance-${{ runner.os }}-x64
path: NanoBoyAdvance.dmg
if-no-files-found: error

build-macOS-arm:
runs-on: macos-14
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Setup dependencies
env:
HOMEBREW_NO_ANALYTICS: 1
run: |
brew install sdl2 qt@5
python3 -m pip install Jinja2
- name: Build NanoBoyAdvance
run: |
cmake -Bbuild \
-DCMAKE_CXX_FLAGS="-s" \
-DUSE_STATIC_SDL=ON \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_PREFIX_PATH="$(brew --prefix qt@5)" \
-DMACOS_BUILD_APP_BUNDLE=ON \
-DMACOS_BUNDLE_QT=ON
cd build
Expand All @@ -96,8 +147,8 @@ jobs:
-ov -format UDBZ \
NanoBoyAdvance.dmg
- name: Upload artifacts
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: NanoBoyAdvance-${{ runner.os }}
name: NanoBoyAdvance-${{ runner.os }}-arm64
path: NanoBoyAdvance.dmg
if-no-files-found: error
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.11...3.28)
project(NanoBoyAdvance LANGUAGES CXX)
project(NanoBoyAdvance LANGUAGES C CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
Expand Down
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ NanoBoyAdvance is a cycle-accurate Game Boy Advance emulator.<br>
It aims to be as accurate as possible, while also offering enhancements such as
improved audio quality.<br>

![screenshot1](docs/screenshot.png)

## Features
- Very high compatibility and accuracy (see [Accuracy](#accuracy))
- HQ audio mixer (for games which use Nintendo's MusicPlayer2000 sound engine)
Expand Down
6 changes: 3 additions & 3 deletions docs/ACCURACY.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,19 @@

Comparison of NBA and other emulators on the [mGBA test suite](https://github.com/mgba-emu/suite) by endrift:

Testname | Test Count | NanoBoyAdvance 1.8 | mGBA 0.10.3 | VBA-M 2.1.9 | Ares v135 | SkyEmu V3 |
Testname | Test Count | NanoBoyAdvance 1.8 | mGBA 0.10.3 | VBA-M 2.1.9 | Ares v137 | SkyEmu V3 |
--------------|------------|--------------------|-------------|----------------|-----------|------------|
Memory | 1552 | 1552 | 1552 | 1426 | 1552 | 1552 |
IO read | 130 | 130 | 120 | 100 | 130 | 130 |
Timing | 2020 | 2020 | 1768 | 1024 | 1608 | 2020 |
Timing | 2020 | 2020 | 1768 | 1024 | 1890 | 2020 |
Timer | 936 | 936 | 744 | 440 | 465 | 706 |
Timer IRQ | 90 | 90 | 70 | 8 | 0 | 90 |
Shifter | 140 | 140 | 140 | 132 | 140 | 140 |
Carry | 93 | 93 | 93 | 93 | 93 | 93 |
Multiply Long | 72 | 52 | 52 | 52 | 52 | 52 |
BIOS math | 615 | 615 | 615 | 615 | 615 | 615 |
DMA tests | 1256 | 1256 | 1232 | 1068 | 1212 | 1256 |
Misc Edge Case| 10 | 9 | 4 | 8 | 1 | 4 |
Misc Edge Case| 10 | 10 | 4 | 8 | 1 | 4 |
Layer Toggle | 1 | pass | fail | pass | fail | pass |
OAM Update | 1 | pass | fail | fail | fail | pass |

Expand Down
19 changes: 10 additions & 9 deletions docs/COMPILING.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ NanoBoyAdvance can be compiled on Windows, Linux, and macOS.

- Clang or GCC with C++17 support
- CMake 3.11 or higher
- Python modules Jinja and (optionally) lxml
- OpenGL (usually provided by the operating system)
- SDL2 library
- GLEW library
- Qt5 library
- SDL 2 library
- Qt 5 library

### Source Code

Expand All @@ -28,28 +28,29 @@ Here is a list of commands for popular distributions and macOS:
##### Arch Linux

```bash
pacman -S cmake sdl2 glew qt5-base
pacman -S cmake python-jinja python-lxml sdl2 qt5-base
```

##### Ubuntu or other Debian-derived distribution

```bash
apt install cmake libsdl2-dev libglew-dev qtbase5-dev libqt5opengl5-dev
apt install cmake python3-jinja2 python3-lxml libsdl2-dev qtbase5-dev libqt5opengl5-dev
```

##### macOS

Get [Brew](https://brew.sh/) and run:

``` bash
brew install cmake sdl2 glew qt@5
brew install cmake python@3 sdl2 qt@5
python3 -m pip install Jinja2
```

##### FreeBSD

```bash
su
pkg install cmake git sdl2 glew qt5 qt5-opengl
pkg install cmake git py39-Jinja2 py39-lxml sdl2 qt5 qt5-opengl
```

#### 2. Setup CMake build directory
Expand All @@ -67,7 +68,7 @@ NOTE: the location and name of the `build` directory is arbitrary.

```
cd /somewhere/on/your/system/NanoBoyAdvance
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$(brew --prefix qt@5);$(brew --prefix glew)"
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$(brew --prefix qt@5)"
```

NOTE: the location and name of the `build` directory is arbitrary.
Expand All @@ -94,7 +95,7 @@ This guide uses [MSYS2](https://www.msys2.org/) to install Mingw-w64 and other d
In your MSYS2 command line, run:

```bash
pacman -S make mingw-w64-x86_64-gcc mingw-w64-x86_64-cmake mingw-w64-x86_64-SDL2 mingw-w64-x86_64-glew mingw-w64-x86_64-qt5-static
pacman -S make mingw-w64-x86_64-gcc mingw-w64-x86_64-cmake mingw-w64-x86_64-python-jinja mingw-w64-x86_64-python-lxml mingw-w64-x86_64-SDL2 mingw-w64-x86_64-qt5-static
```

#### 2. Setup CMake build directory
Expand Down
Binary file removed docs/screenshot.png
Binary file not shown.
34 changes: 27 additions & 7 deletions src/nba/include/nba/log.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#pragma once

#include <array>
#include <fmt/color.h>
#include <fmt/format.h>
#include <string_view>
#include <utility>
Expand Down Expand Up @@ -38,16 +39,35 @@ namespace detail {
template<Level level, typename... Args>
inline void Log(std::string_view format, Args&&... args) {
if constexpr((detail::kLogMask & level) != 0) {
fmt::text_style style = {};
char const* prefix = "[?]";

if constexpr(level == Trace) prefix = "\e[36m[T]";
if constexpr(level == Debug) prefix = "\e[34m[D]";
if constexpr(level == Info) prefix = "\e[37m[I]";
if constexpr(level == Warn) prefix = "\e[33m[W]";
if constexpr(level == Error) prefix = "\e[35m[E]";
if constexpr(level == Fatal) prefix = "\e[31m[F]";
if constexpr(level == Trace) {
style = fmt::fg(fmt::terminal_color::cyan);
prefix = "[T]";
}
if constexpr(level == Debug) {
style = fmt::fg(fmt::terminal_color::blue);
prefix = "[D]";
}
if constexpr(level == Info) {
prefix = "[I]";
}
if constexpr(level == Warn) {
style = fmt::fg(fmt::terminal_color::yellow);
prefix = "[W]";
}
if constexpr(level == Error) {
style = fmt::fg(fmt::terminal_color::magenta);
prefix = "[E]";
}
if constexpr(level == Fatal) {
style = fmt::fg(fmt::terminal_color::red);
prefix = "[F]";
}

fmt::print("{} {}\n", prefix, fmt::format(format, std::forward<Args>(args)...));
const auto& style_ref = style;
fmt::print(style_ref, "{} {}\n", prefix, fmt::format(format, std::forward<Args>(args)...));
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/nba/src/bus/bus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ auto Bus::GetHostAddress(u32 address, size_t size) -> u8* {
}
}

Assert(false, "Bus: cannot get host address for 0x{:08X} ({} bytes)", address, size);
return nullptr;
}

} // namespace nba::core
12 changes: 6 additions & 6 deletions src/nba/src/core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,12 @@ void Core::Run(int cycles) {
while(scheduler.GetTimestampNow() < limit) {
if(bus.hw.haltcnt == HaltControl::Run) {
if(cpu.state.r15 == hle_audio_hook) {
// @todo: cache the SoundInfo pointer once we have it?
apu.GetMP2K().SoundMainRAM(
*bus.GetHostAddress<MP2K::SoundInfo>(
*bus.GetHostAddress<u32>(0x03007FF0)
)
);
const u32 sound_info_addr = *bus.GetHostAddress<u32>(0x03007FF0);
const auto sound_info = bus.GetHostAddress<MP2K::SoundInfo>(sound_info_addr);

if(sound_info != nullptr) {
apu.GetMP2K().SoundMainRAM(*sound_info);
}
}

cpu.Run();
Expand Down
4 changes: 2 additions & 2 deletions src/nba/src/hw/apu/apu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ void APU::StepMixer() {
if(psg.enable[channel][2]) psg_sample += mmio.psg3.GetSample();
if(psg.enable[channel][3]) psg_sample += mmio.psg4.GetSample();

sample[channel] += psg_sample * psg_volume * psg.master[channel] / (28.0 * 0x200);
sample[channel] += psg_sample * psg_volume * (psg.master[channel] + 1) / (32.0 * 0x200);

/* TODO: we assume that MP2K sends right channel to FIFO A and left channel to FIFO B,
* but we haven't verified that this is actually correct.
Expand Down Expand Up @@ -183,7 +183,7 @@ void APU::StepMixer() {
if(psg.enable[channel][2]) psg_sample += mmio.psg3.GetSample();
if(psg.enable[channel][3]) psg_sample += mmio.psg4.GetSample();

sample[channel] += psg_sample * psg_volume * psg.master[channel] / 28;
sample[channel] += psg_sample * psg_volume * (psg.master[channel] + 1) >> 5;

for(int fifo = 0; fifo < 2; fifo++) {
if(dma[fifo].enable[channel]) {
Expand Down
18 changes: 14 additions & 4 deletions src/nba/src/hw/apu/hle/mp2k.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,14 @@ void MP2K::SoundMainRAM(SoundInfo const& sound_info) {
}
hq_envelope_volume[0] = U8ToFloat(channel.envelope_attack);

const Sampler::WaveInfo* const wave_info = bus.GetHostAddress<Sampler::WaveInfo>(channel.wave_address);
if(wave_info == nullptr) {
Log<Warn>("MP2K: channel[{}] wave address is invalid: 0x{:08X}", channel.wave_address);
channel.status = 0; // Disable channel, there is no good way to deal with this.
continue;
}
sampler = {};
sampler.wave_info = *bus.GetHostAddress<Sampler::WaveInfo>(channel.wave_address);
sampler.wave_info = *wave_info;
if(sampler.wave_info.status & 0xC000) {
channel.status |= CHANNEL_LOOP;
}
Expand Down Expand Up @@ -205,9 +211,13 @@ void MP2K::RenderFrame() {
wave_size *= 33;
wave_size = (wave_size + 63) / 64;
}
sampler.wave_data = bus.GetHostAddress<u8>(
channel.wave_address + sizeof(Sampler::WaveInfo), wave_size
);
const u32 wave_data_begin = channel.wave_address + sizeof(Sampler::WaveInfo);
sampler.wave_data = bus.GetHostAddress<u8>(wave_data_begin, wave_size);
if(sampler.wave_data == nullptr) {
Log<Warn>("MP2K: channel[{}] sample data has bad memory range 0x{:08X} - 0x{:08X}.", i, wave_data_begin, wave_data_begin + wave_size);
channel.status = 0; // Disable channel, there is no good way to deal with this.
continue;
}
sampler.compressed = compressed;
}

Expand Down
1 change: 1 addition & 0 deletions src/nba/src/hw/rom/gpio/serialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ void GPIO::LoadState(SaveState const& state) {

for(auto& device : devices) {
device->LoadState(state);
device->SetPortDirections(wr_mask);
}
}

Expand Down
Loading

0 comments on commit b473a4c

Please sign in to comment.