Compare commits
47 Commits
Author | SHA1 | Date |
---|---|---|
![]() |
f352cf612a | |
![]() |
4aaea218c1 | |
![]() |
44b0704063 | |
![]() |
2499ec36c2 | |
![]() |
baad893bc0 | |
![]() |
ec2f7ee838 | |
![]() |
005ef9c9fc | |
![]() |
7b562f71b3 | |
![]() |
fd279bedc5 | |
![]() |
b2af96474f | |
![]() |
8cd2d972ab | |
![]() |
ab249fc913 | |
![]() |
8e163296d3 | |
![]() |
83b8f1ae47 | |
![]() |
fd74181f7d | |
![]() |
2d04222442 | |
![]() |
71edf793fc | |
![]() |
d7a4b2e8fe | |
![]() |
c65d490351 | |
![]() |
79f12de480 | |
![]() |
0b005abedf | |
![]() |
0d294e9373 | |
![]() |
7117178c2d | |
![]() |
d1eff4acf5 | |
![]() |
37ca75acb9 | |
![]() |
528f2495fc | |
![]() |
7baeb26e32 | |
![]() |
0e64a06c84 | |
![]() |
d6d820c013 | |
![]() |
9ed7e5803e | |
![]() |
0fcf1f6e3a | |
![]() |
63b468927e | |
![]() |
e8265df4bd | |
![]() |
15c3faa26e | |
![]() |
a9cce557d2 | |
![]() |
0c5dd28b1c | |
![]() |
c41951d49c | |
![]() |
be26878b4c | |
![]() |
66d1091330 | |
![]() |
72c86ade31 | |
![]() |
7d718ada39 | |
![]() |
817b409ec8 | |
![]() |
cba838dd52 | |
![]() |
730b488fe3 | |
![]() |
1d6c9023ff | |
![]() |
0db536c063 | |
![]() |
6a15dbfa12 |
|
@ -4,12 +4,13 @@ on:
|
|||
push:
|
||||
branches:
|
||||
- master
|
||||
- ci/vcpkg-update
|
||||
- ci/*
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
|
||||
env:
|
||||
VCPKG_COMMIT: 2ad004460f5db4d3b66f62f5799ff66c265c4b5d
|
||||
MELONDS_GIT_BRANCH: ${{ github.ref }}
|
||||
MELONDS_GIT_HASH: ${{ github.sha }}
|
||||
MELONDS_BUILD_PROVIDER: GitHub Actions
|
||||
|
@ -34,7 +35,7 @@ jobs:
|
|||
- name: Set up vcpkg
|
||||
uses: lukka/run-vcpkg@v11
|
||||
with:
|
||||
vcpkgGitCommitId: 10b7a178346f3f0abef60cecd5130e295afd8da4
|
||||
vcpkgGitCommitId: ${{ env.VCPKG_COMMIT }}
|
||||
- name: Build
|
||||
uses: lukka/run-cmake@v10
|
||||
with:
|
||||
|
|
|
@ -4,6 +4,7 @@ on:
|
|||
push:
|
||||
branches:
|
||||
- master
|
||||
- ci/*
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
|
@ -15,16 +16,24 @@ env:
|
|||
MELONDS_VERSION_SUFFIX: " RC"
|
||||
|
||||
jobs:
|
||||
build-x86_64:
|
||||
name: x86_64
|
||||
runs-on: ubuntu-22.04
|
||||
build:
|
||||
continue-on-error: true
|
||||
strategy:
|
||||
matrix:
|
||||
arch:
|
||||
- runner: ubuntu-22.04
|
||||
name: x86_64
|
||||
- runner: ubuntu-22.04-arm
|
||||
name: aarch64
|
||||
|
||||
name: ${{ matrix.arch.name }}
|
||||
runs-on: ${{ matrix.arch.runner }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
name: Check out sources
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo rm -f /etc/apt/sources.list.d/dotnetdev.list /etc/apt/sources.list.d/microsoft-prod.list
|
||||
sudo apt update
|
||||
sudo apt install --allow-downgrades cmake ninja-build extra-cmake-modules libpcap0.8-dev libsdl2-dev libenet-dev \
|
||||
qt6-{base,base-private,multimedia}-dev libqt6svg6-dev libarchive-dev libzstd-dev libfuse2
|
||||
|
@ -36,56 +45,19 @@ jobs:
|
|||
DESTDIR=AppDir cmake --install build
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: melonDS-ubuntu-x86_64
|
||||
name: melonDS-ubuntu-${{ matrix.arch.name }}
|
||||
path: AppDir/usr/bin/melonDS
|
||||
- name: Fetch AppImage tools
|
||||
run: |
|
||||
wget https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
|
||||
wget https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-x86_64.AppImage
|
||||
wget https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-${{ matrix.arch.name }}.AppImage
|
||||
wget https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-${{ matrix.arch.name }}.AppImage
|
||||
chmod a+x linuxdeploy-*.AppImage
|
||||
- name: Build the AppImage
|
||||
env:
|
||||
QMAKE: /usr/lib/qt6/bin/qmake
|
||||
run: |
|
||||
./linuxdeploy-x86_64.AppImage --appdir AppDir --plugin qt --output appimage
|
||||
./linuxdeploy-${{ matrix.arch.name }}.AppImage --appdir AppDir --plugin qt --output appimage
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: melonDS-appimage-x86_64
|
||||
name: melonDS-appimage-${{ matrix.arch.name }}
|
||||
path: melonDS*.AppImage
|
||||
|
||||
build-aarch64:
|
||||
name: aarch64
|
||||
runs-on: ubuntu-latest
|
||||
container: ubuntu:22.04
|
||||
|
||||
steps:
|
||||
- name: Prepare system
|
||||
shell: bash
|
||||
run: |
|
||||
dpkg --add-architecture arm64
|
||||
sh -c "sed \"s|^deb \([a-z\.:/]*\) \([a-z\-]*\) \(.*\)$|deb [arch=amd64] \1 \2 \3\ndeb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports \2 \3|\" /etc/apt/sources.list > /etc/apt/sources.list.new"
|
||||
rm /etc/apt/sources.list
|
||||
mv /etc/apt/sources.list{.new,}
|
||||
apt update
|
||||
apt -y full-upgrade
|
||||
apt -y install git {gcc-12,g++-12}-aarch64-linux-gnu cmake ninja-build extra-cmake-modules \
|
||||
{libsdl2,qt6-{base,base-private,multimedia},libqt6svg6,libarchive,libzstd,libenet}-dev:arm64 \
|
||||
pkg-config dpkg-dev
|
||||
- name: Check out source
|
||||
uses: actions/checkout@v4
|
||||
- name: Configure
|
||||
shell: bash
|
||||
run: |
|
||||
cmake -B build -G Ninja \
|
||||
-DPKG_CONFIG_EXECUTABLE=/usr/bin/aarch64-linux-gnu-pkg-config \
|
||||
-DCMAKE_C_COMPILER=aarch64-linux-gnu-gcc-12 \
|
||||
-DCMAKE_CXX_COMPILER=aarch64-linux-gnu-g++-12 \
|
||||
-DMELONDS_EMBED_BUILD_INFO=ON
|
||||
- name: Build
|
||||
shell: bash
|
||||
run: |
|
||||
cmake --build build
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: melonDS-ubuntu-aarch64
|
||||
path: build/melonDS
|
||||
|
|
|
@ -10,6 +10,7 @@ on:
|
|||
- master
|
||||
|
||||
env:
|
||||
VCPKG_COMMIT: 2ad004460f5db4d3b66f62f5799ff66c265c4b5d
|
||||
MELONDS_GIT_BRANCH: ${{ github.ref }}
|
||||
MELONDS_GIT_HASH: ${{ github.sha }}
|
||||
MELONDS_BUILD_PROVIDER: GitHub Actions
|
||||
|
@ -33,7 +34,7 @@ jobs:
|
|||
- name: Set up vcpkg
|
||||
uses: lukka/run-vcpkg@v11
|
||||
with:
|
||||
vcpkgGitCommitId: 10b7a178346f3f0abef60cecd5130e295afd8da4
|
||||
vcpkgGitCommitId: ${{ env.VCPKG_COMMIT }}
|
||||
- name: Configure
|
||||
run: cmake --preset=release-mingw-x86_64 -DMELONDS_EMBED_BUILD_INFO=ON
|
||||
- name: Build
|
||||
|
|
|
@ -9,6 +9,7 @@ set(CMAKE_POLICY_DEFAULT_CMP0069 NEW)
|
|||
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
|
||||
set(CMAKE_USER_MAKE_RULES_OVERRIDE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/DefaultBuildFlags.cmake")
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum OS X deployment version")
|
||||
|
||||
option(USE_VCPKG "Use vcpkg for dependency packages" OFF)
|
||||
if (USE_VCPKG)
|
||||
|
@ -29,8 +30,6 @@ include(CheckIPOSupported)
|
|||
include(SetupCCache)
|
||||
include(Sanitizers)
|
||||
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum OS X deployment version")
|
||||
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
|
|
@ -9,7 +9,8 @@ if (VCPKG_ROOT STREQUAL "${_DEFAULT_VCPKG_ROOT}")
|
|||
endif()
|
||||
FetchContent_Declare(vcpkg
|
||||
GIT_REPOSITORY "https://github.com/Microsoft/vcpkg.git"
|
||||
GIT_TAG 2024.10.21
|
||||
GIT_TAG 2ad004460f5db4d3b66f62f5799ff66c265c4b5d
|
||||
EXCLUDE_FROM_ALL
|
||||
SOURCE_DIR "${CMAKE_SOURCE_DIR}/vcpkg")
|
||||
FetchContent_MakeAvailable(vcpkg)
|
||||
endif()
|
||||
|
|
|
@ -7,3 +7,9 @@ endif()
|
|||
|
||||
string(REPLACE "-O2" "-O3" CMAKE_C_FLAGS_RELEASE_INIT "${CMAKE_C_FLAGS_RELEASE_INIT}")
|
||||
string(REPLACE "-O2" "-O3" CMAKE_CXX_FLAGS_RELEASE_INIT "${CMAKE_CXX_FLAGS_RELEASE_INIT}")
|
||||
|
||||
# Building with LTO causes an internal compiler error in GCC 15.1.0
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL GNU AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 15.0 AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 15.1.1)
|
||||
set(ENABLE_LTO_RELEASE OFF CACHE BOOL "Enable LTO for release builds" FORCE)
|
||||
set(ENABLE_LTO OFF CACHE BOOL "Enable LTO" FORCE)
|
||||
endif()
|
||||
|
|
12
flake.lock
12
flake.lock
|
@ -5,11 +5,11 @@
|
|||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1726560853,
|
||||
"narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=",
|
||||
"lastModified": 1731533236,
|
||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a",
|
||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -20,11 +20,11 @@
|
|||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1730531603,
|
||||
"narHash": "sha256-Dqg6si5CqIzm87sp57j5nTaeBbWhHFaVyG7V6L8k3lY=",
|
||||
"lastModified": 1739020877,
|
||||
"narHash": "sha256-mIvECo/NNdJJ/bXjNqIh8yeoSjVLAuDuTUzAo7dzs8Y=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "7ffd9ae656aec493492b44d0ddfb28e79a1ea25d",
|
||||
"rev": "a79cfe0ebd24952b580b1cf08cd906354996d547",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
|
@ -95,7 +95,13 @@
|
|||
libtool
|
||||
ninja
|
||||
pkg-config
|
||||
python3
|
||||
];
|
||||
|
||||
# Undo the SDK setup done by nixpkgs so we can use AppleClang
|
||||
shellHook = ''
|
||||
unset DEVELOPER_DIR SDKROOT MACOSX_DEPLOYMENT_TARGET
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
AS = arm-none-eabi-as
|
||||
LD = arm-none-eabi-ld
|
||||
OBJCOPY = arm-none-eabi-objcopy
|
||||
|
||||
BIN = melonDLDI
|
||||
|
||||
all:
|
||||
$(AS) $(BIN).s -o $(BIN).o
|
||||
$(LD) $(BIN).o -Ttext 0xBF800000 -e 0xBF800000 -o $(BIN).elf
|
||||
$(OBJCOPY) -O binary $(BIN).elf $(BIN).bin
|
||||
xxd -i -n $(BIN) -c 16 $(BIN).bin $(BIN).h
|
||||
|
||||
clean:
|
||||
rm -f $(BIN).h $(BIN).bin $(BIN).elf $(BIN).o
|
||||
|
|
@ -0,0 +1,172 @@
|
|||
.arm
|
||||
.text
|
||||
|
||||
.align 2
|
||||
|
||||
_start:
|
||||
.word 0xBF8DA5ED
|
||||
.string " Chishm"
|
||||
.byte 1
|
||||
.byte 9 @ size
|
||||
.byte 0
|
||||
.byte 0
|
||||
.string "melonDS DLDI driver"
|
||||
.align 6, 0
|
||||
.word _start, melon_end
|
||||
.word 0, 0
|
||||
.word 0, 0
|
||||
.word 0, 0
|
||||
.ascii "MELN"
|
||||
.word 0x23
|
||||
.word melon_startup
|
||||
.word melon_isInserted
|
||||
.word melon_readSectors
|
||||
.word melon_writeSectors
|
||||
.word melon_clearStatus
|
||||
.word melon_shutdown
|
||||
|
||||
|
||||
.align 2
|
||||
|
||||
melon_startup:
|
||||
mov r0, #1
|
||||
bx lr
|
||||
|
||||
|
||||
melon_isInserted:
|
||||
mov r0, #1
|
||||
bx lr
|
||||
|
||||
|
||||
@ r0=cmd r1=sector r2=out (0=none)
|
||||
_sendcmd:
|
||||
mov r12, #0x04000000
|
||||
add r12, r12, #0x1A0
|
||||
@ init
|
||||
mov r3, #0x8000
|
||||
strh r3, [r12]
|
||||
@ set cmd
|
||||
strb r0, [r12, #0x8]
|
||||
strb r1, [r12, #0xC]
|
||||
mov r1, r1, lsr #8
|
||||
strb r1, [r12, #0xB]
|
||||
mov r1, r1, lsr #8
|
||||
strb r1, [r12, #0xA]
|
||||
mov r1, r1, lsr #8
|
||||
strb r1, [r12, #0x9]
|
||||
mov r1, r1, lsr #8
|
||||
strb r1, [r12, #0xD]
|
||||
strh r1, [r12, #0xE]
|
||||
@ send
|
||||
mov r3, #0xA0000000
|
||||
orr r3, r3, r0, lsl #30
|
||||
cmp r2, #0
|
||||
orrne r3, r3, #0x01000000 @ block size
|
||||
orr r3, r3, #0x00400000 @ KEY2
|
||||
str r3, [r12, #0x4]
|
||||
mov r3, #0x04100000
|
||||
tst r0, #0x01
|
||||
bne __send_write
|
||||
@ receive data
|
||||
tst r2, #0x3
|
||||
bne __read_unal_loop
|
||||
__read_busyloop:
|
||||
ldr r0, [r12, #0x4]
|
||||
tst r0, #0x80000000
|
||||
bxeq lr
|
||||
tst r0, #0x00800000
|
||||
ldrne r1, [r3, #0x10] @ load data
|
||||
strne r1, [r2], #4
|
||||
b __read_busyloop
|
||||
__read_unal_loop:
|
||||
ldr r0, [r12, #0x4]
|
||||
tst r0, #0x80000000
|
||||
bxeq lr
|
||||
tst r0, #0x00800000
|
||||
beq __read_unal_loop
|
||||
ldr r1, [r3, #0x10] @ load data
|
||||
strb r1, [r2], #1
|
||||
mov r1, r1, lsr #8
|
||||
strb r1, [r2], #1
|
||||
mov r1, r1, lsr #8
|
||||
strb r1, [r2], #1
|
||||
mov r1, r1, lsr #8
|
||||
strb r1, [r2], #1
|
||||
b __read_unal_loop
|
||||
@ send data
|
||||
__send_write:
|
||||
mov r1, #0
|
||||
tst r2, #0x3
|
||||
bne __write_unal_loop
|
||||
__write_busyloop:
|
||||
ldr r0, [r12, #0x4]
|
||||
tst r0, #0x80000000
|
||||
bxeq lr
|
||||
tst r0, #0x00800000
|
||||
ldrne r1, [r2], #4
|
||||
strne r1, [r3, #0x10] @ store data
|
||||
b __write_busyloop
|
||||
__write_unal_loop:
|
||||
ldr r0, [r12, #0x4]
|
||||
tst r0, #0x80000000
|
||||
bxeq lr
|
||||
tst r0, #0x00800000
|
||||
beq __write_unal_loop
|
||||
ldrb r1, [r2], #1
|
||||
ldrb r0, [r2], #1
|
||||
orr r1, r1, r0, lsl #8
|
||||
ldrb r0, [r2], #1
|
||||
orr r1, r1, r0, lsl #16
|
||||
ldrb r0, [r2], #1
|
||||
orr r1, r1, r0, lsl #24
|
||||
str r1, [r3, #0x10] @ store data
|
||||
b __write_unal_loop
|
||||
|
||||
|
||||
@ r0=sector r1=numsectors r2=out
|
||||
melon_readSectors:
|
||||
stmdb sp!, {r3-r6, lr}
|
||||
mov r4, r0
|
||||
mov r5, r1
|
||||
mov r6, #0
|
||||
_readloop:
|
||||
mov r0, #0xC0
|
||||
add r1, r4, r6
|
||||
bl _sendcmd
|
||||
add r6, r6, #1
|
||||
cmp r6, r5
|
||||
bcc _readloop
|
||||
ldmia sp!, {r3-r6, lr}
|
||||
mov r0, #1
|
||||
bx lr
|
||||
|
||||
|
||||
@ r0=sector r1=numsectors r2=out
|
||||
melon_writeSectors:
|
||||
stmdb sp!, {r3-r6, lr}
|
||||
mov r4, r0
|
||||
mov r5, r1
|
||||
mov r6, #0
|
||||
_writeloop:
|
||||
mov r0, #0xC1
|
||||
add r1, r4, r6
|
||||
bl _sendcmd
|
||||
add r6, r6, #1
|
||||
cmp r6, r5
|
||||
bcc _writeloop
|
||||
ldmia sp!, {r3-r6, lr}
|
||||
mov r0, #1
|
||||
bx lr
|
||||
|
||||
|
||||
melon_clearStatus:
|
||||
mov r0, #1
|
||||
bx lr
|
||||
|
||||
|
||||
melon_shutdown:
|
||||
mov r0, #1
|
||||
bx lr
|
||||
|
||||
|
||||
melon_end:
|
|
@ -18,7 +18,7 @@ FILETYPE VFT_APP
|
|||
VALUE "FileVersion", "${melonDS_VERSION}"
|
||||
VALUE "FileDescription", "melonDS emulator"
|
||||
VALUE "InternalName", "SDnolem"
|
||||
VALUE "LegalCopyright", "2016-2023 melonDS team"
|
||||
VALUE "LegalCopyright", "2016-2025 melonDS team"
|
||||
VALUE "LegalTrademarks", ""
|
||||
VALUE "OriginalFilename", "melonDS.exe"
|
||||
VALUE "ProductName", "melonDS"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
@ -58,7 +58,8 @@ void AREngine::RunCheat(const ARCode& arcode)
|
|||
|
||||
for (;;)
|
||||
{
|
||||
if (code >= &arcode.Code[arcode.Code.size()])
|
||||
if (code > &arcode.Code[arcode.Code.size() - 1])
|
||||
// If the instruction pointer is past the end of the cheat code...
|
||||
break;
|
||||
|
||||
u32 a = *code++;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
@ -115,7 +115,7 @@ ARM::ARM(u32 num, bool jit, std::optional<GDBArgs> gdb, melonDS::NDS& nds) :
|
|||
Num(num), // well uh
|
||||
NDS(nds)
|
||||
{
|
||||
SetGdbArgs(jit ? gdb : std::nullopt);
|
||||
SetGdbArgs(jit ? std::nullopt : gdb);
|
||||
}
|
||||
|
||||
ARM::~ARM()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team, RSDuck
|
||||
Copyright 2016-2025 melonDS team, RSDuck
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team, RSDuck
|
||||
Copyright 2016-2025 melonDS team, RSDuck
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
@ -83,7 +83,7 @@ void Compiler::Comp_JumpTo(u32 addr, bool forceNonConstantCycles)
|
|||
// doesn't matter if we put garbage in the MSbs there
|
||||
if (addr & 0x2)
|
||||
{
|
||||
cpu9->CodeRead32(addr-2, true) >> 16;
|
||||
cpu9->CodeRead32(addr-2, true);
|
||||
cycles += cpu9->CodeCycles;
|
||||
cpu9->CodeRead32(addr+2, false);
|
||||
cycles += CurCPU->CodeCycles;
|
||||
|
@ -437,4 +437,4 @@ void Compiler::T_Comp_BL_Merged()
|
|||
Comp_JumpTo(target);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team, RSDuck
|
||||
Copyright 2016-2025 melonDS team, RSDuck
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team, RSDuck
|
||||
Copyright 2016-2025 melonDS team, RSDuck
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team, RSDuck
|
||||
Copyright 2016-2025 melonDS team, RSDuck
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team, RSDuck
|
||||
Copyright 2016-2025 melonDS team, RSDuck
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team, RSDuck
|
||||
Copyright 2016-2025 melonDS team, RSDuck
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team, RSDuck
|
||||
Copyright 2016-2025 melonDS team, RSDuck
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
@ -753,7 +753,7 @@ bool ARMJIT_Memory::IsFastMemSupported()
|
|||
|
||||
PageSize = RegularPageSize;
|
||||
#else
|
||||
PageSize = __sysconf(_SC_PAGESIZE);
|
||||
PageSize = sysconf(_SC_PAGESIZE);
|
||||
isSupported = PageSize == RegularPageSize || PageSize == LargePageSize;
|
||||
#endif
|
||||
PageShift = __builtin_ctz(PageSize);
|
||||
|
@ -900,7 +900,7 @@ ARMJIT_Memory::ARMJIT_Memory(melonDS::NDS& nds) : NDS(nds)
|
|||
}
|
||||
#else
|
||||
char fastmemPidName[snprintf(NULL, 0, "/melondsfastmem%d", getpid()) + 1];
|
||||
sprintf(fastmemPidName, "/melondsfastmem%d", getpid());
|
||||
snprintf(fastmemPidName, sizeof(fastmemPidName), "/melondsfastmem%d", getpid());
|
||||
MemoryFile = shm_open(fastmemPidName, O_RDWR | O_CREAT | O_EXCL, 0600);
|
||||
if (MemoryFile == -1)
|
||||
{
|
||||
|
@ -951,7 +951,6 @@ ARMJIT_Memory::~ARMJIT_Memory() noexcept
|
|||
MemoryBase = nullptr;
|
||||
FastMem9Start = nullptr;
|
||||
FastMem7Start = nullptr;
|
||||
printf("unmappinged everything\n");
|
||||
}
|
||||
|
||||
if (MemoryFile)
|
||||
|
@ -979,6 +978,8 @@ ARMJIT_Memory::~ARMJIT_Memory() noexcept
|
|||
MemoryFile = -1;
|
||||
}
|
||||
|
||||
Log(LogLevel::Info, "unmappinged everything\n");
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
if (Libandroid)
|
||||
{
|
||||
|
@ -1599,4 +1600,4 @@ void* ARMJIT_Memory::GetFuncForAddr(ARM* cpu, u32 addr, bool store, int size) co
|
|||
}
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
@ -29,7 +29,8 @@
|
|||
# if defined(__SWITCH__)
|
||||
# include <switch.h>
|
||||
# elif defined(_WIN32)
|
||||
#include <windows.h>
|
||||
# include <vector>
|
||||
# include <windows.h>
|
||||
# else
|
||||
# include <sys/mman.h>
|
||||
# include <sys/stat.h>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team, RSDuck
|
||||
Copyright 2016-2025 melonDS team, RSDuck
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team, RSDuck
|
||||
Copyright 2016-2025 melonDS team, RSDuck
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team, RSDuck
|
||||
Copyright 2016-2025 melonDS team, RSDuck
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ add_library(core STATIC
|
|||
FATStorage.cpp
|
||||
FIFO.h
|
||||
GBACart.cpp
|
||||
GBACartMotionPak.cpp
|
||||
GPU.cpp
|
||||
GPU2D.cpp
|
||||
GPU2D_Soft.cpp
|
||||
|
@ -102,6 +103,8 @@ if (ENABLE_JIT)
|
|||
dolphin/CommonFuncs.cpp)
|
||||
|
||||
if (WIN32)
|
||||
# Required for memory mapping-related functions introduced in Windows 8
|
||||
target_compile_definitions(core PRIVATE -D_WIN32_WINNT=_WIN32_WINNT_WIN8)
|
||||
target_link_libraries(core PRIVATE onecore)
|
||||
endif()
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
@ -90,6 +90,9 @@ void DSi_AES::Reset()
|
|||
*(u32*)&KeyX[1][8] = (u32)(consoleid >> 32) ^ 0xC80C4B72;
|
||||
*(u32*)&KeyX[1][12] = (u32)consoleid;
|
||||
|
||||
// slot 2: For 'Tad'
|
||||
std::memcpy(KeyX[2], &DSi.ARM9iBIOS[0x8B8C], 0x10);
|
||||
|
||||
// slot 3: console-unique eMMC crypto
|
||||
*(u32*)&KeyX[3][0] = (u32)consoleid;
|
||||
*(u32*)&KeyX[3][4] = (u32)consoleid ^ 0x24EE6906;
|
||||
|
@ -575,4 +578,4 @@ void DSi_AES::WriteKeyY(u32 slot, u32 offset, u32 val, u32 mask)
|
|||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
@ -128,6 +128,7 @@ void DSi_CamModule::TransferScanline(u32 line)
|
|||
|
||||
u32 tmpbuf[512];
|
||||
int datalen = CurCamera->TransferScanline(tmpbuf, 512);
|
||||
u32 numscan;
|
||||
|
||||
// TODO: must be tweaked such that each block has enough time to transfer
|
||||
u32 delay = datalen*4 + 16;
|
||||
|
@ -142,12 +143,7 @@ void DSi_CamModule::TransferScanline(u32 line)
|
|||
int ystart = (CropStart >> 16) & 0x1FF;
|
||||
int yend = (CropEnd >> 16) & 0x1FF;
|
||||
if (line < ystart || line > yend)
|
||||
{
|
||||
if (!CurCamera->TransferDone())
|
||||
DSi.ScheduleEvent(Event_DSi_CamTransfer, false, delay, 0, line+1);
|
||||
|
||||
return;
|
||||
}
|
||||
goto skip_line;
|
||||
|
||||
int xstart = (CropStart >> 1) & 0x1FF;
|
||||
int xend = (CropEnd >> 1) & 0x1FF;
|
||||
|
@ -206,7 +202,7 @@ void DSi_CamModule::TransferScanline(u32 line)
|
|||
memcpy(dstbuf, &tmpbuf[copystart], copylen*sizeof(u32));
|
||||
}
|
||||
|
||||
u32 numscan = Cnt & 0x000F;
|
||||
numscan = Cnt & 0x000F;
|
||||
if (BufferNumLines >= numscan)
|
||||
{
|
||||
BufferReadPos = 0; // checkme
|
||||
|
@ -221,8 +217,21 @@ void DSi_CamModule::TransferScanline(u32 line)
|
|||
BufferNumLines++;
|
||||
}
|
||||
|
||||
skip_line:
|
||||
if (CurCamera->TransferDone())
|
||||
{
|
||||
// when the frame is finished, transfer any remaining data if needed
|
||||
// (if the frame height isn't a multiple of the DMA interval)
|
||||
if (BufferNumLines > 0)
|
||||
{
|
||||
BufferReadPos = 0;
|
||||
BufferWritePos = 0;
|
||||
BufferNumLines = 0;
|
||||
DSi.CheckNDMAs(0, 0x0B);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
DSi.ScheduleEvent(Event_DSi_CamTransfer, false, delay, 0, line+1);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -323,7 +323,7 @@ void DSi_DSP::PDataDMAFetch()
|
|||
}
|
||||
void DSi_DSP::PDataDMAStart()
|
||||
{
|
||||
switch ((DSP_PSTS & (3<<2)) >> 2)
|
||||
switch ((DSP_PCFG & (3<<2)) >> 2)
|
||||
{
|
||||
case 0: PDataDMALen = 1; break;
|
||||
case 1: PDataDMALen = 8; break;
|
||||
|
@ -348,7 +348,7 @@ void DSi_DSP::PDataDMACancel()
|
|||
}
|
||||
u16 DSi_DSP::PDataDMAReadMMIO()
|
||||
{
|
||||
u16 ret;
|
||||
u16 ret = 0; // TODO: is this actually 0, or just open bus?
|
||||
|
||||
if (!PDATAReadFifo.IsEmpty())
|
||||
ret = PDATAReadFifo.Read();
|
||||
|
@ -362,15 +362,9 @@ u16 DSi_DSP::PDataDMAReadMMIO()
|
|||
|
||||
for (int i = 0; i < left; ++i)
|
||||
PDataDMAFetch();
|
||||
|
||||
ret = PDATAReadFifo.Read();
|
||||
}
|
||||
else
|
||||
{
|
||||
// ah, crap
|
||||
ret = 0; // TODO: is this actually 0, or just open bus?
|
||||
}
|
||||
|
||||
// TODO only trigger IRQ if enabled!!
|
||||
if (!PDATAReadFifo.IsEmpty() || PDATAReadFifo.IsFull())
|
||||
DSi.SetIRQ(0, IRQ_DSi_DSP);
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
@ -132,7 +132,6 @@ void DSi_NDMA::WriteCnt(u32 val)
|
|||
|
||||
// TODO: unsupported start modes:
|
||||
// * timers (00-03)
|
||||
// * camera (ARM9 0B)
|
||||
// * microphone (ARM7 0C)
|
||||
// * NDS-wifi?? (ARM7 07, likely not working)
|
||||
|
||||
|
@ -270,11 +269,18 @@ void DSi_NDMA::Run9()
|
|||
|
||||
if ((StartMode & 0x1F) == 0x10) // CHECKME
|
||||
{
|
||||
// no repeat
|
||||
Cnt &= ~(1<<31);
|
||||
if (Cnt & (1<<30)) DSi.SetIRQ(0, IRQ_DSi_NDMA0 + Num);
|
||||
}
|
||||
else if (!(Cnt & (1<<29)))
|
||||
else if (Cnt & (1<<29))
|
||||
{
|
||||
// repeat infinitely
|
||||
if (Cnt & (1<<30)) DSi.SetIRQ(0, IRQ_DSi_NDMA0 + Num);
|
||||
}
|
||||
else
|
||||
{
|
||||
// repeat until total count is reached
|
||||
if (TotalRemCount == 0)
|
||||
{
|
||||
Cnt &= ~(1<<31);
|
||||
|
@ -359,11 +365,18 @@ void DSi_NDMA::Run7()
|
|||
|
||||
if ((StartMode & 0x1F) == 0x10) // CHECKME
|
||||
{
|
||||
// no repeat
|
||||
Cnt &= ~(1<<31);
|
||||
if (Cnt & (1<<30)) DSi.SetIRQ(1, IRQ_DSi_NDMA0 + Num);
|
||||
}
|
||||
else if (!(Cnt & (1<<29)))
|
||||
else if (Cnt & (1<<29))
|
||||
{
|
||||
// repeat infinitely
|
||||
if (Cnt & (1<<30)) DSi.SetIRQ(1, IRQ_DSi_NDMA0 + Num);
|
||||
}
|
||||
else
|
||||
{
|
||||
// repeat until total count is reached
|
||||
if (TotalRemCount == 0)
|
||||
{
|
||||
Cnt &= ~(1<<31);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
@ -242,8 +242,6 @@ u16 CartGame::ROMRead(u32 addr) const
|
|||
case 0xC8: return GPIO.control;
|
||||
}
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
// CHECKME: does ROM mirror?
|
||||
|
@ -539,6 +537,57 @@ CartGameSolarSensor::CartGameSolarSensor(std::unique_ptr<u8[]>&& rom, u32 len, s
|
|||
{
|
||||
}
|
||||
|
||||
std::unique_ptr<CartGameSolarSensor> CreateFakeSolarSensorROM(const char* gamecode, const NDSCart::CartCommon& cart, void* userdata) noexcept
|
||||
{
|
||||
return CreateFakeSolarSensorROM(gamecode, cart.GetHeader().NintendoLogo, userdata);
|
||||
}
|
||||
|
||||
std::unique_ptr<CartGameSolarSensor> CreateFakeSolarSensorROM(const char* gamecode, const GBACart::CartGame& cart, void* userdata) noexcept
|
||||
{
|
||||
return CreateFakeSolarSensorROM(gamecode, cart.GetHeader().NintendoLogo, userdata);
|
||||
}
|
||||
|
||||
std::unique_ptr<CartGameSolarSensor> CreateFakeSolarSensorROM(const char* gamecode, const u8* logo, void* userdata) noexcept
|
||||
{
|
||||
if (!gamecode)
|
||||
return nullptr;
|
||||
|
||||
if (strnlen(gamecode, sizeof(GBAHeader::GameCode)) > sizeof(GBAHeader::GameCode))
|
||||
return nullptr;
|
||||
|
||||
bool solarsensor = false;
|
||||
for (const char* i : SOLAR_SENSOR_GAMECODES)
|
||||
{
|
||||
if (strcmp(gamecode, i) == 0) {
|
||||
solarsensor = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!solarsensor)
|
||||
return nullptr;
|
||||
|
||||
// just 256 bytes; we don't need a whole ROM!
|
||||
constexpr size_t FAKE_BOKTAI_ROM_LENGTH = 0x100;
|
||||
std::unique_ptr<u8[]> rom = std::make_unique<u8[]>(FAKE_BOKTAI_ROM_LENGTH);
|
||||
|
||||
// create a fake ROM
|
||||
GBAHeader& header = *reinterpret_cast<GBAHeader*>(rom.get());
|
||||
memcpy(header.Title, BOKTAI_STUB_TITLE, strnlen(BOKTAI_STUB_TITLE, sizeof(header.Title)));
|
||||
memcpy(header.GameCode, gamecode, strnlen(gamecode, sizeof(header.GameCode)));
|
||||
header.FixedValue = 0x96;
|
||||
if (logo)
|
||||
{
|
||||
memcpy(header.NintendoLogo, logo, sizeof(header.NintendoLogo));
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(header.NintendoLogo, 0xFF, sizeof(header.NintendoLogo));
|
||||
}
|
||||
|
||||
return std::make_unique<CartGameSolarSensor>(std::move(rom), FAKE_BOKTAI_ROM_LENGTH, nullptr, 0, userdata);
|
||||
}
|
||||
|
||||
const int CartGameSolarSensor::kLuxLevels[11] = {0, 5, 11, 18, 27, 42, 62, 84, 109, 139, 183};
|
||||
|
||||
void CartGameSolarSensor::Reset()
|
||||
|
@ -724,6 +773,27 @@ void CartRumblePak::ROMWrite(u32 addr, u16 val)
|
|||
}
|
||||
}
|
||||
|
||||
CartGuitarGrip::CartGuitarGrip(void* userdata) :
|
||||
CartCommon(GuitarGrip),
|
||||
UserData(userdata)
|
||||
{
|
||||
}
|
||||
|
||||
CartGuitarGrip::~CartGuitarGrip() = default;
|
||||
|
||||
u16 CartGuitarGrip::ROMRead(u32 addr) const
|
||||
{
|
||||
return 0xF9FF;
|
||||
}
|
||||
|
||||
u8 CartGuitarGrip::SRAMRead(u32 addr)
|
||||
{
|
||||
return ~((Platform::Addon_KeyDown(Platform::KeyGuitarGripGreen, UserData) ? 0x40 : 0)
|
||||
| (Platform::Addon_KeyDown(Platform::KeyGuitarGripRed, UserData) ? 0x20 : 0)
|
||||
| (Platform::Addon_KeyDown(Platform::KeyGuitarGripYellow, UserData) ? 0x10 : 0)
|
||||
| (Platform::Addon_KeyDown(Platform::KeyGuitarGripBlue, UserData) ? 0x08 : 0));
|
||||
}
|
||||
|
||||
GBACartSlot::GBACartSlot(melonDS::NDS& nds, std::unique_ptr<CartCommon>&& cart) noexcept : NDS(nds), Cart(std::move(cart))
|
||||
{
|
||||
}
|
||||
|
@ -843,7 +913,27 @@ std::unique_ptr<CartCommon> LoadAddon(int type, void* userdata)
|
|||
case GBAAddon_RumblePak:
|
||||
cart = std::make_unique<CartRumblePak>(userdata);
|
||||
break;
|
||||
|
||||
case GBAAddon_SolarSensorBoktai1:
|
||||
// US Boktai 1
|
||||
cart = CreateFakeSolarSensorROM("U3IE", nullptr, userdata);
|
||||
break;
|
||||
case GBAAddon_SolarSensorBoktai2:
|
||||
// US Boktai 2
|
||||
cart = CreateFakeSolarSensorROM("U32E", nullptr, userdata);
|
||||
break;
|
||||
case GBAAddon_SolarSensorBoktai3:
|
||||
// JP Boktai 3
|
||||
cart = CreateFakeSolarSensorROM("U33J", nullptr, userdata);
|
||||
break;
|
||||
case GBAAddon_MotionPakHomebrew:
|
||||
cart = std::make_unique<CartMotionPakHomebrew>(userdata);
|
||||
break;
|
||||
case GBAAddon_MotionPakRetail:
|
||||
cart = std::make_unique<CartMotionPakRetail>(userdata);
|
||||
break;
|
||||
case GBAAddon_GuitarGrip:
|
||||
cart = std::make_unique<CartGuitarGrip>(userdata);
|
||||
break;
|
||||
default:
|
||||
Log(LogLevel::Warn, "GBACart: !! invalid addon type %d\n", type);
|
||||
return nullptr;
|
||||
|
|
100
src/GBACart.h
100
src/GBACart.h
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
@ -33,8 +33,30 @@ enum CartType
|
|||
GameSolarSensor = 0x102,
|
||||
RAMExpansion = 0x201,
|
||||
RumblePak = 0x202,
|
||||
MotionPakHomebrew = 0x203,
|
||||
MotionPakRetail = 0x204,
|
||||
GuitarGrip = 0x205,
|
||||
};
|
||||
|
||||
// See https://problemkaputt.de/gbatek.htm#gbacartridgeheader for details
|
||||
struct GBAHeader
|
||||
{
|
||||
u32 EntryPoint;
|
||||
u8 NintendoLogo[156]; // must be valid
|
||||
char Title[12];
|
||||
char GameCode[4];
|
||||
char MakerCode[2];
|
||||
u8 FixedValue; // must be 0x96
|
||||
u8 MainUnitCode;
|
||||
u8 DeviceType;
|
||||
u8 Reserved0[7];
|
||||
u8 SoftwareVersion;
|
||||
u8 ComplementCheck;
|
||||
u8 Reserved1[2];
|
||||
};
|
||||
|
||||
static_assert(sizeof(GBAHeader) == 192, "GBAHeader should be 192 bytes");
|
||||
|
||||
// CartCommon -- base code shared by all cart types
|
||||
class CartCommon
|
||||
{
|
||||
|
@ -91,6 +113,8 @@ public:
|
|||
|
||||
[[nodiscard]] const u8* GetROM() const override { return ROM.get(); }
|
||||
[[nodiscard]] u32 GetROMLength() const override { return ROMLength; }
|
||||
[[nodiscard]] const GBAHeader& GetHeader() const noexcept { return *reinterpret_cast<const GBAHeader*>(ROM.get()); }
|
||||
[[nodiscard]] GBAHeader& GetHeader() noexcept { return *reinterpret_cast<GBAHeader*>(ROM.get()); }
|
||||
|
||||
u8* GetSaveMemory() const override;
|
||||
u32 GetSaveMemoryLength() const override;
|
||||
|
@ -211,11 +235,68 @@ private:
|
|||
u16 RumbleState = 0;
|
||||
};
|
||||
|
||||
// CartGuitarGrip -- DS Guitar Grip (used in various NDS games)
|
||||
class CartGuitarGrip : public CartCommon
|
||||
{
|
||||
public:
|
||||
CartGuitarGrip(void* userdata);
|
||||
~CartGuitarGrip() override;
|
||||
|
||||
u16 ROMRead(u32 addr) const override;
|
||||
u8 SRAMRead(u32 addr) override;
|
||||
|
||||
private:
|
||||
void* UserData;
|
||||
};
|
||||
|
||||
// CartMotionPakHomebrew -- DS Motion Pak (Homebrew)
|
||||
class CartMotionPakHomebrew : public CartCommon
|
||||
{
|
||||
public:
|
||||
CartMotionPakHomebrew(void* userdata);
|
||||
~CartMotionPakHomebrew() override;
|
||||
|
||||
void Reset() override;
|
||||
|
||||
void DoSavestate(Savestate* file) override;
|
||||
|
||||
u16 ROMRead(u32 addr) const override;
|
||||
u8 SRAMRead(u32 addr) override;
|
||||
|
||||
private:
|
||||
void* UserData;
|
||||
u16 ShiftVal = 0;
|
||||
};
|
||||
|
||||
// CartMotionPakRetail -- DS Motion Pack (Retail)
|
||||
class CartMotionPakRetail : public CartCommon
|
||||
{
|
||||
public:
|
||||
CartMotionPakRetail(void* userdata);
|
||||
~CartMotionPakRetail() override;
|
||||
|
||||
void Reset() override;
|
||||
|
||||
void DoSavestate(Savestate* file) override;
|
||||
|
||||
u16 ROMRead(u32 addr) const override;
|
||||
u8 SRAMRead(u32 addr) override;
|
||||
|
||||
private:
|
||||
void* UserData;
|
||||
u8 Value;
|
||||
u8 Step = 16;
|
||||
};
|
||||
|
||||
// possible inputs for GBA carts that might accept user input
|
||||
enum
|
||||
{
|
||||
Input_SolarSensorDown = 0,
|
||||
Input_SolarSensorUp,
|
||||
Input_GuitarGripGreen,
|
||||
Input_GuitarGripRed,
|
||||
Input_GuitarGripYellow,
|
||||
Input_GuitarGripBlue,
|
||||
};
|
||||
|
||||
class GBACartSlot
|
||||
|
@ -309,6 +390,23 @@ std::unique_ptr<CartCommon> ParseROM(std::unique_ptr<u8[]>&& romdata, u32 romlen
|
|||
|
||||
std::unique_ptr<CartCommon> LoadAddon(int type, void* userdata);
|
||||
|
||||
/// Creates a solar sensor-enabled GBA cart without needing a real Boktai ROM.
|
||||
/// This enables the solar sensor to be used in supported games.
|
||||
/// Will not contain any SRAM.
|
||||
/// @param gamecode
|
||||
/// @param logo The Nintendo logo data embedded in the headers for GBA ROMs and NDS ROMs.
|
||||
/// Required for the cart to be recognized as a valid GBA cart.
|
||||
/// Overloads that accept cart objects directly exist as well.
|
||||
/// If not provided, then it will have to be patched with equivalent data
|
||||
/// from a real ROM (NDS or GBA) before booting the emulator.
|
||||
/// @param userdata Optional user data to associate with the cart.
|
||||
/// @return A CartGameSolarSensor if the ROM was created successfully,
|
||||
/// or nullptr if any argument is wrong (e.g. an incorrect game code).
|
||||
std::unique_ptr<CartGameSolarSensor> CreateFakeSolarSensorROM(const char* gamecode, const u8* logo, void* userdata = nullptr) noexcept;
|
||||
std::unique_ptr<CartGameSolarSensor> CreateFakeSolarSensorROM(const char* gamecode, const NDSCart::CartCommon& cart, void* userdata = nullptr) noexcept;
|
||||
std::unique_ptr<CartGameSolarSensor> CreateFakeSolarSensorROM(const char* gamecode, const GBACart::CartGame& cart, void* userdata = nullptr) noexcept;
|
||||
|
||||
constexpr const char* BOKTAI_STUB_TITLE = "BOKTAI STUB";
|
||||
}
|
||||
|
||||
#endif // GBACART_H
|
||||
|
|
|
@ -0,0 +1,196 @@
|
|||
/*
|
||||
Copyright 2016-2024 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 <assert.h>
|
||||
#include "NDS.h"
|
||||
#include "GBACart.h"
|
||||
#include "Platform.h"
|
||||
#include <algorithm>
|
||||
#include "math.h"
|
||||
|
||||
namespace melonDS
|
||||
{
|
||||
using Platform::Log;
|
||||
using Platform::LogLevel;
|
||||
|
||||
namespace GBACart
|
||||
{
|
||||
|
||||
CartMotionPakHomebrew::CartMotionPakHomebrew(void* userdata) :
|
||||
CartCommon(MotionPakHomebrew),
|
||||
UserData(userdata)
|
||||
{
|
||||
}
|
||||
|
||||
CartMotionPakHomebrew::~CartMotionPakHomebrew() = default;
|
||||
|
||||
void CartMotionPakHomebrew::Reset()
|
||||
{
|
||||
ShiftVal = 0;
|
||||
}
|
||||
|
||||
void CartMotionPakHomebrew::DoSavestate(Savestate* file)
|
||||
{
|
||||
CartCommon::DoSavestate(file);
|
||||
file->Var16(&ShiftVal);
|
||||
}
|
||||
|
||||
u16 CartMotionPakHomebrew::ROMRead(u32 addr) const
|
||||
{
|
||||
// CHECKME: Does this apply to the homebrew cart as well?
|
||||
return 0xFCFF;
|
||||
}
|
||||
|
||||
static int AccelerationToMotionPak(float accel)
|
||||
{
|
||||
const float GRAVITY_M_S2 = 9.80665f;
|
||||
|
||||
return std::clamp(
|
||||
(int) ((accel / (5 * GRAVITY_M_S2) + 0.5) * 4096),
|
||||
0, 4095
|
||||
);
|
||||
}
|
||||
|
||||
static int AccelerationToMotionPakRetail(float accel)
|
||||
{
|
||||
const float GRAVITY_M_S2 = 9.80665f;
|
||||
|
||||
return std::clamp(
|
||||
(int) ((accel / (5 * GRAVITY_M_S2) + 0.5) * 256),
|
||||
0, 254
|
||||
);
|
||||
}
|
||||
|
||||
static int RotationToMotionPak(float rot)
|
||||
{
|
||||
const float DEGREES_PER_RAD = 180 / M_PI;
|
||||
const float COUNTS_PER_DEG_PER_SEC = 0.825;
|
||||
const int CENTER = 1680;
|
||||
|
||||
return std::clamp(
|
||||
(int) ((rot * DEGREES_PER_RAD * COUNTS_PER_DEG_PER_SEC) + CENTER + 0.5),
|
||||
0, 4095
|
||||
);
|
||||
}
|
||||
|
||||
u8 CartMotionPakHomebrew::SRAMRead(u32 addr)
|
||||
{
|
||||
// CHECKME: SRAM address mask
|
||||
addr &= 0xFFFF;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0:
|
||||
// Read next byte
|
||||
break;
|
||||
case 2:
|
||||
// Read X acceleration
|
||||
ShiftVal = AccelerationToMotionPak(Platform::Addon_MotionQuery(Platform::MotionAccelerationX, UserData)) << 4;
|
||||
// CHECKME: First byte returned when reading acceleration/rotation
|
||||
return 0;
|
||||
case 4:
|
||||
// Read Y acceleration
|
||||
ShiftVal = AccelerationToMotionPak(Platform::Addon_MotionQuery(Platform::MotionAccelerationY, UserData)) << 4;
|
||||
return 0;
|
||||
case 6:
|
||||
// Read Z acceleration
|
||||
ShiftVal = AccelerationToMotionPak(Platform::Addon_MotionQuery(Platform::MotionAccelerationZ, UserData)) << 4;
|
||||
return 0;
|
||||
case 8:
|
||||
// Read Z rotation
|
||||
// CHECKME: This is a guess, compare with real hardware
|
||||
ShiftVal = RotationToMotionPak(-Platform::Addon_MotionQuery(Platform::MotionRotationZ, UserData)) << 4;
|
||||
return 0;
|
||||
case 10:
|
||||
// Identify cart
|
||||
ShiftVal = 0xF00F;
|
||||
return 0;
|
||||
case 12:
|
||||
case 14:
|
||||
case 16:
|
||||
case 18:
|
||||
// Read/enable analog inputs
|
||||
//
|
||||
// These are not connected by defualt and require do-it-yourself cart
|
||||
// modification, so there is no reason to emulate them.
|
||||
ShiftVal = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
// Read high byte from the emulated shift register
|
||||
u8 val = ShiftVal >> 8;
|
||||
ShiftVal <<= 8;
|
||||
return val;
|
||||
}
|
||||
|
||||
CartMotionPakRetail::CartMotionPakRetail(void* userdata) :
|
||||
CartCommon(MotionPakRetail),
|
||||
UserData(userdata)
|
||||
{
|
||||
}
|
||||
|
||||
CartMotionPakRetail::~CartMotionPakRetail() = default;
|
||||
|
||||
void CartMotionPakRetail::Reset()
|
||||
{
|
||||
Value = 0;
|
||||
Step = 16;
|
||||
}
|
||||
|
||||
void CartMotionPakRetail::DoSavestate(Savestate* file)
|
||||
{
|
||||
CartCommon::DoSavestate(file);
|
||||
file->Var8(&Value);
|
||||
file->Var8(&Step);
|
||||
}
|
||||
|
||||
u16 CartMotionPakRetail::ROMRead(u32 addr) const
|
||||
{
|
||||
// A9-A8 is pulled low on a real Motion Pack.
|
||||
return 0xFCFF;
|
||||
}
|
||||
|
||||
u8 CartMotionPakRetail::SRAMRead(u32 addr)
|
||||
{
|
||||
switch (Step)
|
||||
{
|
||||
case 0: // Synchronization - read 0xFF
|
||||
Value = 0xFF;
|
||||
break;
|
||||
case 4: // X acceleration
|
||||
Value = AccelerationToMotionPakRetail(Platform::Addon_MotionQuery(Platform::MotionAccelerationX, UserData));
|
||||
break;
|
||||
case 8: // Y acceleration
|
||||
Value = AccelerationToMotionPakRetail(Platform::Addon_MotionQuery(Platform::MotionAccelerationY, UserData));
|
||||
break;
|
||||
case 12: // Z acceleration
|
||||
Value = AccelerationToMotionPakRetail(Platform::Addon_MotionQuery(Platform::MotionAccelerationZ, UserData));
|
||||
break;
|
||||
case 16: // Synchronization - read 0b00
|
||||
Step = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int shift = 6 - ((Step & 3) * 2);
|
||||
Step++;
|
||||
return (Value >> shift) & 0x03;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
@ -1219,7 +1219,7 @@ void GPU3D::SubmitPolygon() noexcept
|
|||
|
||||
u32 texfmt = (TexParam >> 26) & 0x7;
|
||||
u32 polyalpha = (CurPolygonAttr >> 16) & 0x1F;
|
||||
poly->Translucent = ((texfmt == 1 || texfmt == 6) && !(CurPolygonAttr & 0x10)) || (polyalpha > 0 && polyalpha < 31);
|
||||
poly->Translucent = (texfmt == 1 || texfmt == 6) || (polyalpha > 0 && polyalpha < 31);
|
||||
|
||||
poly->IsShadowMask = ((CurPolygonAttr & 0x3F000030) == 0x00000030);
|
||||
poly->IsShadow = ((CurPolygonAttr & 0x30) == 0x30) && !poly->IsShadowMask;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
Copyright 2016-2025 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue