mirror of
https://github.com/libretro/bsnes-libretro.git
synced 2024-11-23 00:49:40 +00:00
Merge branch 'bsnes-emu:master' into master
This commit is contained in:
commit
9c688ea5cb
66
.cirrus.yml
66
.cirrus.yml
@ -1,33 +1,9 @@
|
||||
linux-x86_64-binaries_task:
|
||||
container:
|
||||
image: ubuntu:latest
|
||||
|
||||
setup_script:
|
||||
- apt-get update && DEBIAN_FRONTEND=noninteractive apt-get -y install build-essential libgtk2.0-dev libpulse-dev mesa-common-dev libcairo2-dev libsdl2-dev libxv-dev libao-dev libopenal-dev libudev-dev zip
|
||||
|
||||
compile_script:
|
||||
- make -C bsnes local=false
|
||||
|
||||
package_script:
|
||||
- mkdir bsnes-nightly
|
||||
- mkdir bsnes-nightly/Database
|
||||
- mkdir bsnes-nightly/Firmware
|
||||
- cp -a bsnes/out/bsnes bsnes-nightly/bsnes
|
||||
- cp -a bsnes/Database/* bsnes-nightly/Database
|
||||
- cp -a shaders bsnes-nightly/Shaders
|
||||
- cp -a GPLv3.txt bsnes-nightly
|
||||
- cp -a extras/* bsnes-nightly
|
||||
- zip -r bsnes-nightly.zip bsnes-nightly
|
||||
|
||||
bsnes-nightly_artifacts:
|
||||
path: "bsnes-nightly.zip"
|
||||
|
||||
freebsd-x86_64-binaries_task:
|
||||
freebsd_instance:
|
||||
image_family: freebsd-12-2
|
||||
|
||||
setup_script:
|
||||
- pkg install --yes gmake gdb gcc8 pkgconf sdl2 openal-soft gtk2 libXv zip
|
||||
- pkg install --yes gmake gdb gcc8 pkgconf sdl2 openal-soft gtk3 gtksourceview3 libXv zip
|
||||
|
||||
compile_script:
|
||||
- gmake -C bsnes local=false
|
||||
@ -45,43 +21,3 @@ freebsd-x86_64-binaries_task:
|
||||
|
||||
bsnes-nightly_artifacts:
|
||||
path: "bsnes-nightly.zip"
|
||||
|
||||
windows-x86_64-binaries_task:
|
||||
container:
|
||||
image: ubuntu:latest
|
||||
|
||||
setup_script:
|
||||
- apt-get update && DEBIAN_FRONTEND=noninteractive apt-get -y install build-essential mingw-w64 zip
|
||||
|
||||
compile_script:
|
||||
- make -C bsnes local=false platform=windows compiler="x86_64-w64-mingw32-g++" windres="x86_64-w64-mingw32-windres"
|
||||
|
||||
package_script:
|
||||
- mkdir bsnes-nightly
|
||||
- mkdir bsnes-nightly/Database
|
||||
- mkdir bsnes-nightly/Firmware
|
||||
- cp -a bsnes/out/bsnes.exe bsnes-nightly/bsnes.exe
|
||||
- cp -a bsnes/Database/* bsnes-nightly/Database
|
||||
- cp -a shaders bsnes-nightly/Shaders
|
||||
- cp -a GPLv3.txt bsnes-nightly
|
||||
- cp -a extras/* bsnes-nightly
|
||||
- zip -r bsnes-nightly.zip bsnes-nightly
|
||||
|
||||
bsnes-nightly_artifacts:
|
||||
path: "bsnes-nightly.zip"
|
||||
|
||||
macOS-aarch64-binaries_task:
|
||||
macos_instance:
|
||||
image: ghcr.io/cirruslabs/macos-ventura-base:latest
|
||||
compile_script:
|
||||
- make -C bsnes local=false
|
||||
|
||||
package_script:
|
||||
- mkdir bsnes-nightly
|
||||
- cp -a bsnes/out/bsnes.app bsnes-nightly
|
||||
- cp -a GPLv3.txt bsnes-nightly
|
||||
- cp -a extras/* bsnes-nightly
|
||||
- zip -r bsnes-nightly.zip bsnes-nightly
|
||||
|
||||
bsnes-nightly_artifacts:
|
||||
path: "bsnes-nightly.zip"
|
||||
|
158
.github/workflows/build.yml
vendored
158
.github/workflows/build.yml
vendored
@ -5,6 +5,8 @@ on:
|
||||
tags: [ 'v*' ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
permissions:
|
||||
contents: write
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
@ -18,33 +20,33 @@ jobs:
|
||||
version: latest
|
||||
runs-on: ${{ matrix.os.name }}-${{ matrix.os.version }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install Dependencies
|
||||
if: matrix.os.name == 'ubuntu'
|
||||
run: |
|
||||
sudo apt-get update -y -qq
|
||||
sudo apt-get install \
|
||||
libgtk2.0-dev libpulse-dev mesa-common-dev libcairo2-dev \
|
||||
libsdl2-dev libxv-dev libao-dev libopenal-dev libudev-dev
|
||||
sudo apt-get install libsdl2-dev libgtk-3-dev gtksourceview-3.0 libao-dev libopenal-dev
|
||||
- name: Make
|
||||
run: make -j4 -C bsnes local=false
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: bsnes-${{ matrix.os.name }}
|
||||
path: bsnes/out/bsnes*
|
||||
|
||||
release:
|
||||
if: github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/')
|
||||
# Prevent multiple conflicting release jobs from running at once.
|
||||
concurrency: release-${{ github.ref == 'refs/heads/master' && 'nightly' || github.ref }}
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- build
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
path: 'src'
|
||||
- name: Download Artifacts
|
||||
uses: actions/download-artifact@v2
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
path: 'bin'
|
||||
- name: Package Artifacts
|
||||
@ -85,103 +87,53 @@ jobs:
|
||||
|
||||
cd -
|
||||
done
|
||||
- name: Create Release
|
||||
id: release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Calculate release info
|
||||
id: relinfo
|
||||
run: |
|
||||
set -eu
|
||||
github_rest()
|
||||
{
|
||||
local method="${1}"
|
||||
local url="https://api.github.com${2}"
|
||||
shift 2
|
||||
>&2 echo "${method} ${url}"
|
||||
curl \
|
||||
--fail \
|
||||
-H "Accept: application/vnd.github.v3+json" \
|
||||
-H "Authorization: token ${GITHUB_TOKEN}" \
|
||||
-X "${method}" \
|
||||
"${url}" \
|
||||
"$@"
|
||||
echo "datetime=$(date -u +"%Y-%m-%d %T %Z")" >> $GITHUB_OUTPUT
|
||||
echo "date=$(date +"%Y-%m-%d")" >> $GITHUB_OUTPUT
|
||||
- name: Delete old nightly release
|
||||
uses: actions/github-script@v7
|
||||
id: release
|
||||
if: ${{!startsWith(github.ref, 'refs/tags/')}}
|
||||
with:
|
||||
retries: 3
|
||||
script: |
|
||||
const {owner, repo} = context.repo;
|
||||
try {
|
||||
const release = await github.rest.repos.getReleaseByTag({owner, repo, tag: "nightly"});
|
||||
if (release && release.status === 200) {
|
||||
await github.rest.repos.deleteRelease({owner, repo, release_id: release.data.id});
|
||||
}
|
||||
github_get_release_id_for_tag()
|
||||
{
|
||||
payload=$(github_rest GET "/repos/${GITHUB_REPOSITORY}/releases/tags/${1}") || return
|
||||
echo "${payload}" | jq .id
|
||||
} catch (e) {
|
||||
console.log(`error deleting old release: ${e}`);
|
||||
}
|
||||
github_delete_release_by_id()
|
||||
{
|
||||
github_rest DELETE "/repos/${GITHUB_REPOSITORY}/releases/${1}"
|
||||
try {
|
||||
await github.rest.git.deleteRef({owner, repo, ref: "tags/nightly"});
|
||||
} catch (e) {
|
||||
console.log(`error trying to delete ref: ${e}`);
|
||||
}
|
||||
github_delete_tag()
|
||||
{
|
||||
github_rest DELETE "/repos/${GITHUB_REPOSITORY}/git/refs/tags/${1}"
|
||||
}
|
||||
github_create_release()
|
||||
{
|
||||
local payload="{
|
||||
\"tag_name\": \"${1}\",
|
||||
\"target_commitish\": \"${2}\",
|
||||
\"name\": \"${3}\",
|
||||
\"body\": \"${4}\",
|
||||
\"draft\": ${5},
|
||||
\"prerelease\": ${6}
|
||||
}"
|
||||
github_rest POST "/repos/${GITHUB_REPOSITORY}/releases" -d "${payload}"
|
||||
}
|
||||
make_nightly_release()
|
||||
{
|
||||
github_create_release \
|
||||
nightly \
|
||||
"${GITHUB_SHA}" \
|
||||
"bsnes nightly $(date +"%Y-%m-%d")" \
|
||||
"Auto-generated nightly release on $(date -u +"%Y-%m-%d %T %Z")" \
|
||||
false \
|
||||
true
|
||||
}
|
||||
make_version_release()
|
||||
{
|
||||
github_create_release \
|
||||
"${1}" \
|
||||
"${GITHUB_SHA}" \
|
||||
"bsnes ${1}" \
|
||||
"This is bsnes ${1}, released on $(date +"%Y-%m-%d")." \
|
||||
false \
|
||||
false
|
||||
}
|
||||
case ${GITHUB_REF} in
|
||||
refs/tags/*)
|
||||
# Create a new version release using the current revision.
|
||||
echo "UPLOAD_URL=$(make_version_release ${GITHUB_REF#refs/tags/} | jq -r .upload_url)" >> $GITHUB_ENV
|
||||
;;
|
||||
refs/heads/master)
|
||||
# Check for an existing nightly release.
|
||||
{ release_id=$(github_get_release_id_for_tag nightly); status=$?; } || true
|
||||
# Delete existing nightly release if it exists.
|
||||
case ${status} in
|
||||
0)
|
||||
github_delete_release_by_id "${release_id}"
|
||||
# Deleting the 'nightly' release doesn't delete
|
||||
# the 'nightly' tag, so let's do it manually.
|
||||
github_delete_tag nightly
|
||||
;;
|
||||
22) >&2 echo "No current nightly release; skipping tag deletion." ;;
|
||||
*) >&2 echo "API call failed unexpectedly." && exit 1 ;;
|
||||
esac
|
||||
# Create a new nightly release using the current revision.
|
||||
echo "UPLOAD_URL=$(make_nightly_release | jq -r .upload_url)" >> $GITHUB_ENV
|
||||
;;
|
||||
esac
|
||||
- name: Upload bsnes-ubuntu
|
||||
uses: actions/upload-release-asset@v1
|
||||
env: { GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' }
|
||||
with: { upload_url: '${{ env.UPLOAD_URL }}', asset_path: 'bsnes-ubuntu.zip', asset_name: 'bsnes-ubuntu.zip', asset_content_type: 'application/zip' }
|
||||
- name: Upload bsnes-windows
|
||||
uses: actions/upload-release-asset@v1
|
||||
env: { GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' }
|
||||
with: { upload_url: '${{ env.UPLOAD_URL }}', asset_path: 'bsnes-windows.zip', asset_name: 'bsnes-windows.zip', asset_content_type: 'application/zip' }
|
||||
- name: Upload bsnes-macos
|
||||
uses: actions/upload-release-asset@v1
|
||||
env: { GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' }
|
||||
with: { upload_url: '${{ env.UPLOAD_URL }}', asset_path: 'bsnes-macos.zip', asset_name: 'bsnes-macos.zip', asset_content_type: 'application/zip' }
|
||||
await github.rest.git.createTag({
|
||||
owner,
|
||||
repo,
|
||||
tag: "nightly",
|
||||
message: "nightly release",
|
||||
object: context.sha,
|
||||
type: "commit",
|
||||
})
|
||||
- name: Create nightly release
|
||||
uses: softprops/action-gh-release@v1
|
||||
if: ${{!startsWith(github.ref, 'refs/tags/')}}
|
||||
with:
|
||||
tag_name: nightly
|
||||
name: bsnes nightly ${{steps.relinfo.outputs.date}}
|
||||
body: Auto-generated nightly release on ${{steps.relinfo.outputs.datetime}}
|
||||
files: bsnes*.zip
|
||||
prerelease: true
|
||||
- name: Create version release
|
||||
uses: softprops/action-gh-release@v1
|
||||
if: ${{startsWith(github.ref, 'refs/tags/')}}
|
||||
with:
|
||||
name: bsnes ${{github.ref_name}}
|
||||
body: This is bsnes ${{github.ref_name}}, released on ${{steps.relinfo.outputs.date}}.
|
||||
files: bsnes*.zip
|
||||
|
11
README.md
11
README.md
@ -4,7 +4,7 @@ bsnes
|
||||
![bsnes logo](bsnes/target-bsnes/resource/logo.png)
|
||||
|
||||
bsnes is a multi-platform Super Nintendo (Super Famicom) emulator, originally
|
||||
developed by [Near](https://near.sh), which focuses on performance,
|
||||
developed by Near, which focuses on performance,
|
||||
features, and ease of use.
|
||||
|
||||
Unique Features
|
||||
@ -62,11 +62,10 @@ Links
|
||||
Nightly Builds
|
||||
--------------
|
||||
|
||||
- [Download](https://github.com/bsnes-emu/bsnes/releases/tag/nightly)
|
||||
- ![Build status](https://api.cirrus-ci.com/github/bsnes-emu/bsnes.svg?task=windows-x86_64-binaries)
|
||||
- ![Build status](https://api.cirrus-ci.com/github/bsnes-emu/bsnes.svg?task=macOS-x86_64-binaries)
|
||||
- ![Build status](https://api.cirrus-ci.com/github/bsnes-emu/bsnes.svg?task=linux-x86_64-binaries)
|
||||
- ![Build status](https://api.cirrus-ci.com/github/bsnes-emu/bsnes.svg?task=freebsd-x86_64-binaries)
|
||||
- [Windows](https://github.com/bsnes-emu/bsnes/releases/download/nightly/bsnes-windows.zip)
|
||||
- [macOS](https://github.com/bsnes-emu/bsnes/releases/download/nightly/bsnes-macos.zip)
|
||||
- [Linux](https://github.com/bsnes-emu/bsnes/releases/download/nightly/bsnes-ubuntu.zip)
|
||||
- [FreeBSD](https://api.cirrus-ci.com/v1/artifact/github/bsnes-emu/bsnes/freebsd-x86_64-binaries/bsnes-nightly/bsnes-nightly.zip)
|
||||
|
||||
Preview
|
||||
-------
|
||||
|
@ -113,8 +113,8 @@ auto WDC65816::instructionIndexedIndirectRead8(alu8 op) -> void {
|
||||
U.l = fetch();
|
||||
idle2();
|
||||
idle();
|
||||
V.l = readDirect(U.l + X.w + 0);
|
||||
V.h = readDirect(U.l + X.w + 1);
|
||||
V.l = readDirectX(U.l + X.w, 0);
|
||||
V.h = readDirectX(U.l + X.w, 1);
|
||||
L W.l = readBank(V.w + 0);
|
||||
alu(W.l);
|
||||
}
|
||||
@ -123,8 +123,8 @@ auto WDC65816::instructionIndexedIndirectRead16(alu16 op) -> void {
|
||||
U.l = fetch();
|
||||
idle2();
|
||||
idle();
|
||||
V.l = readDirect(U.l + X.w + 0);
|
||||
V.h = readDirect(U.l + X.w + 1);
|
||||
V.l = readDirectX(U.l + X.w, 0);
|
||||
V.h = readDirectX(U.l + X.w, 1);
|
||||
W.l = readBank(V.w + 0);
|
||||
L W.h = readBank(V.w + 1);
|
||||
alu(W.w);
|
||||
|
@ -90,8 +90,8 @@ auto WDC65816::instructionIndexedIndirectWrite8() -> void {
|
||||
U.l = fetch();
|
||||
idle2();
|
||||
idle();
|
||||
V.l = readDirect(U.l + X.w + 0);
|
||||
V.h = readDirect(U.l + X.w + 1);
|
||||
V.l = readDirectX(U.l + X.w, 0);
|
||||
V.h = readDirectX(U.l + X.w, 1);
|
||||
L writeBank(V.w + 0, A.l);
|
||||
}
|
||||
|
||||
@ -99,8 +99,8 @@ auto WDC65816::instructionIndexedIndirectWrite16() -> void {
|
||||
U.l = fetch();
|
||||
idle2();
|
||||
idle();
|
||||
V.l = readDirect(U.l + X.w + 0);
|
||||
V.h = readDirect(U.l + X.w + 1);
|
||||
V.l = readDirectX(U.l + X.w, 0);
|
||||
V.h = readDirectX(U.l + X.w, 1);
|
||||
writeBank(V.w + 0, A.l);
|
||||
L writeBank(V.w + 1, A.h);
|
||||
}
|
||||
|
@ -59,6 +59,13 @@ auto WDC65816::writeDirect(uint address, uint8 data) -> void {
|
||||
write(D.w + address & 0xffff, data);
|
||||
}
|
||||
|
||||
auto WDC65816::readDirectX(uint address, uint offset) -> uint8 {
|
||||
// The (direct,X) addressing mode has a bug in which the high byte is
|
||||
// wrapped within the page if E = 1 and D&0xFF != 0.
|
||||
if(EF && D.l) return read(((D.w + address) & 0xffff00) | ((D.w + address + offset) & 0xff));
|
||||
else return readDirect(address + offset);
|
||||
}
|
||||
|
||||
auto WDC65816::readDirectN(uint address) -> uint8 {
|
||||
return read(D.w + address & 0xffff);
|
||||
}
|
||||
|
@ -58,6 +58,7 @@ struct WDC65816 {
|
||||
alwaysinline auto pushN(uint8 data) -> void;
|
||||
alwaysinline auto readDirect(uint address) -> uint8;
|
||||
alwaysinline auto writeDirect(uint address, uint8 data) -> void;
|
||||
alwaysinline auto readDirectX(uint address, uint offset) -> uint8;
|
||||
alwaysinline auto readDirectN(uint address) -> uint8;
|
||||
alwaysinline auto readBank(uint address) -> uint8;
|
||||
alwaysinline auto writeBank(uint address, uint8 data) -> void;
|
||||
|
@ -39,6 +39,8 @@ auto SA1::BWRAM::writeCPU(uint address, uint8 data) -> void {
|
||||
address = sa1.mmio.sbm * 0x2000 + (address & 0x1fff);
|
||||
}
|
||||
|
||||
//note: BW-RAM protection works only when both SWEN and CWEN are disabled.
|
||||
if(!sa1.mmio.swen && !sa1.mmio.cwen && (address & 0x3ffff) < 0x100 << sa1.mmio.bwp) return;
|
||||
return write(address, data);
|
||||
}
|
||||
|
||||
@ -71,6 +73,15 @@ auto SA1::BWRAM::readLinear(uint address, uint8 data) -> uint8 {
|
||||
}
|
||||
|
||||
auto SA1::BWRAM::writeLinear(uint address, uint8 data) -> void {
|
||||
//note: BW-RAM protection works only when both SWEN and CWEN are disabled.
|
||||
//this is required for Kirby's Dream Land 3 to work:
|
||||
//* BWPA = 02 (protect 400000-4003ff)
|
||||
//* SWEN = 80 (writes enabled)
|
||||
//* CWEN = 00 (writes disabled)
|
||||
//KDL3 proceeds to write to 4001ax and 40032x which must succeed.
|
||||
//note: BWPA also affects SA-1 protection
|
||||
if(!sa1.mmio.swen && !sa1.mmio.cwen && (address & 0x3ffff) < 0x100 << sa1.mmio.bwp) return;
|
||||
|
||||
return write(address, data);
|
||||
}
|
||||
|
||||
|
@ -108,8 +108,16 @@ auto SA1::writeIOCPU(uint address, uint8 data) -> void {
|
||||
//(CCNT) SA-1 control
|
||||
case 0x2200: {
|
||||
if(mmio.sa1_resb && !(data & 0x20)) {
|
||||
//reset SA-1 CPU (PC bank set to 0x00)
|
||||
//reset SA-1 CPU (PC bank and data bank set to 0x00, clear STP status)
|
||||
r.pc.d = mmio.crv;
|
||||
r.b = 0x00;
|
||||
r.stp = false;
|
||||
//todo: probably needs a SA-1 CPU reset
|
||||
//reset r.s, r.e, r.wai ...
|
||||
|
||||
//reset io status
|
||||
//todo: reset timing is unknown, CIWP is set to 0 at reset
|
||||
mmio.ciwp = 0x00;
|
||||
}
|
||||
|
||||
mmio.sa1_irq = (data & 0x80);
|
||||
|
@ -37,7 +37,7 @@ auto SA1::read(uint address) -> uint8 {
|
||||
}
|
||||
|
||||
if((address & 0x40e000) == 0x006000 //00-3f,80-bf:6000-7fff
|
||||
|| (address & 0xf00000) == 0x400000 //40-4f:0000-ffff
|
||||
|| (address & 0xe00000) == 0x400000 //40-5f:0000-ffff
|
||||
|| (address & 0xf00000) == 0x600000 //60-6f:0000-ffff
|
||||
) {
|
||||
step();
|
||||
@ -81,7 +81,7 @@ auto SA1::write(uint address, uint8 data) -> void {
|
||||
}
|
||||
|
||||
if((address & 0x40e000) == 0x006000 //00-3f,80-bf:6000-7fff
|
||||
|| (address & 0xf00000) == 0x400000 //40-4f:0000-ffff
|
||||
|| (address & 0xe00000) == 0x400000 //40-5f:0000-ffff
|
||||
|| (address & 0xf00000) == 0x600000 //60-6f:0000-ffff
|
||||
) {
|
||||
step();
|
||||
|
@ -32,7 +32,7 @@ endif
|
||||
|
||||
ifneq ($(filter $(platform),linux bsd),)
|
||||
ifeq ($(hiro),)
|
||||
hiro := gtk2
|
||||
hiro := gtk3
|
||||
endif
|
||||
|
||||
ifeq ($(hiro),gtk2)
|
||||
|
@ -82,6 +82,8 @@ auto pApplication::state() -> State& {
|
||||
|
||||
auto pApplication::initialize() -> void {
|
||||
#if defined(DISPLAY_XORG)
|
||||
// If running on Wayland, force usage of XWayland
|
||||
setenv("GDK_BACKEND", "x11", 1);
|
||||
state().display = XOpenDisplay(nullptr);
|
||||
state().screenSaverXDG = (bool)execute("xdg-screensaver", "--version").output.find("xdg-screensaver");
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user