Compare commits

..

No commits in common. "master" and "2.0.1" have entirely different histories.

8778 changed files with 1036902 additions and 1230036 deletions

View File

@ -1,13 +0,0 @@
{
"version": 1,
"isRoot": true,
"tools": {
"powershell": {
"version": "7.4.2",
"commands": [
"pwsh"
],
"rollForward": false
}
}
}

View File

@ -2,136 +2,3 @@ root = true
[*]
indent_style = tab
[*.yml]
indent_style = space
[*.cs]
csharp_new_line_before_open_brace = all
csharp_new_line_before_else = true
csharp_new_line_before_catch = true
csharp_new_line_before_finally = true
csharp_space_after_cast = true
csharp_indent_switch_labels = true
csharp_indent_case_contents = true
csharp_indent_labels = one_less_than_current
trim_trailing_whitespace = true
# Style rules
# Can't be in .globalconfig because dotnet format doesn't respect that https://github.com/dotnet/format/issues/1643
# Remove `this` or `Me` qualification
dotnet_diagnostic.IDE0003.severity = silent
# Remove unnecessary cast
dotnet_diagnostic.IDE0004.severity = warning
# Remove unnecessary import
dotnet_diagnostic.IDE0005.severity = warning
# Use var instead of explicit type
dotnet_diagnostic.IDE0007.severity = suggestion
# Use explicit type instead of var
dotnet_diagnostic.IDE0008.severity = silent
# Add `this` or `Me` qualification
dotnet_diagnostic.IDE0009.severity = silent
# Inline variable declaration
dotnet_diagnostic.IDE0018.severity = warning
# Use pattern matching to avoid as followed by a null check
dotnet_diagnostic.IDE0019.severity = warning
# Use pattern matching to avoid is check followed by a cast (with variable)
dotnet_diagnostic.IDE0020.severity = warning
# Use expression body for constructors
dotnet_diagnostic.IDE0021.severity = silent # UseExpressionBodyDiagnosticAnalyzer very slow
# Use expression body for methods
dotnet_diagnostic.IDE0022.severity = silent # UseExpressionBodyDiagnosticAnalyzer very slow
# Use expression body for conversion operators
dotnet_diagnostic.IDE0023.severity = silent # UseExpressionBodyDiagnosticAnalyzer very slow
# Use expression body for operators
dotnet_diagnostic.IDE0024.severity = silent # UseExpressionBodyDiagnosticAnalyzer very slow
# Use expression body for properties
dotnet_diagnostic.IDE0025.severity = silent # UseExpressionBodyDiagnosticAnalyzer very slow
# Use expression body for indexers
dotnet_diagnostic.IDE0026.severity = silent # UseExpressionBodyDiagnosticAnalyzer very slow
# Use expression body for accessors
dotnet_diagnostic.IDE0027.severity = silent # UseExpressionBodyDiagnosticAnalyzer very slow
# Null check can be simplified
dotnet_diagnostic.IDE0029.severity = warning
# Null check can be simplified
dotnet_diagnostic.IDE0030.severity = warning
# Use null propagation
dotnet_diagnostic.IDE0031.severity = warning
# Use auto property
dotnet_diagnostic.IDE0032.severity = suggestion
# Simplify default expression
dotnet_diagnostic.IDE0034.severity = suggestion
# Use pattern matching to avoid is check followed by a cast (without variable)
dotnet_diagnostic.IDE0038.severity = warning
# Use is null check
dotnet_diagnostic.IDE0041.severity = warning
# Deconstruct variable declaration
dotnet_diagnostic.IDE0042.severity = suggestion
# dotnet_diagnostic.IDE0049.severity = error # see SA1121
# Remove unused private member
dotnet_diagnostic.IDE0051.severity = suggestion
# Remove unread private member
dotnet_diagnostic.IDE0052.severity = silent # TODO: should be warning imo, but there's too much violation currently
# Use compound assignment
dotnet_diagnostic.IDE0054.severity = warning
# Use index operator
dotnet_diagnostic.IDE0056.severity = suggestion
# Use range operator
dotnet_diagnostic.IDE0057.severity = suggestion
# Use expression body for local functions
dotnet_diagnostic.IDE0061.severity = silent # UseExpressionBodyDiagnosticAnalyzer very slow
# Use simple using statement
dotnet_diagnostic.IDE0063.severity = suggestion
# Make struct fields writable
dotnet_diagnostic.IDE0064.severity = error
# using directive placement
dotnet_diagnostic.IDE0065.severity = error
# Use switch expression
dotnet_diagnostic.IDE0066.severity = suggestion
# Use System.HashCode.Combine
dotnet_diagnostic.IDE0070.severity = warning
# Simplify interpolation
dotnet_diagnostic.IDE0071.severity = suggestion
# Use coalesce compound assignment
dotnet_diagnostic.IDE0074.severity = suggestion
# Use pattern matching
dotnet_diagnostic.IDE0078.severity = suggestion
# Convert typeof to nameof
dotnet_diagnostic.IDE0082.severity = warning
# Use pattern matching (not operator)
dotnet_diagnostic.IDE0083.severity = warning
# Simplify new expression
dotnet_diagnostic.IDE0090.severity = suggestion
# Remove unnecessary equality operator
dotnet_diagnostic.IDE0100.severity = warning
# Remove unnecessary discard
dotnet_diagnostic.IDE0110.severity = warning
# Simplify LINQ expression
dotnet_diagnostic.IDE0120.severity = error
# Namespace does not match folder structure
dotnet_diagnostic.IDE0130.severity = silent # should be warning imo
# Use tuple to swap values
dotnet_diagnostic.IDE0180.severity = suggestion
# Use UTF-8 string literal
dotnet_diagnostic.IDE0230.severity = warning
# Nullable directive is redundant
dotnet_diagnostic.IDE0240.severity = warning
# Nullable directive is unnecessary
dotnet_diagnostic.IDE0241.severity = warning
# Struct can be made 'readonly'
dotnet_diagnostic.IDE0250.severity = suggestion
# Use pattern matching
dotnet_diagnostic.IDE0260.severity = suggestion
# Use nameof
dotnet_diagnostic.IDE0280.severity = error
# Collection initialization can be simplified
dotnet_diagnostic.IDE0305.severity = silent
csharp_style_var_when_type_is_apparent = true
csharp_style_var_elsewhere = true
csharp_style_expression_bodied_methods = when_on_single_line
csharp_style_expression_bodied_properties = when_on_single_line
csharp_style_expression_bodied_indexers = when_on_single_line
csharp_style_expression_bodied_accessors = when_on_single_line

View File

@ -1,23 +0,0 @@
# This file can be used for git blame using --ignore-revs-file
# or by setting blame.ignoreRevsFile in the git config.
# Fix mixed line endings
ed3bf0e62b5f8b3046b8717dcef54c6b98cb7e77
# Spaces -> tabs, fix mixed newlines
fec63fb66afe70a22cf328eecdaf09e37c21ada5
# Convert spaces to tabs in ZX Spectrum and AmstradCPC cores
85be6af3d33be53d1c70cfbb11d0ebfde8cd417f
# Move projects to /src
3a3b22c03b422eda8fcd62c8cbbff3e838ba4f18
# EXTERMINATE SPACES (in main solution)
3ea71a2dda118b0cadd43c75ee6a577d01f5c6a9
# Fix indentation in `SpectrumBase.Media.cs`
5f29b5094034c4540a1c2a6a962ec4b22c72cb0e
# Remove line-end whitespace across main solution
605deb682dacec3342c650e76fb77972e5ffbe04

View File

@ -1,42 +0,0 @@
---
name: Bug report
about: Crashes, inaccurate emulation, nitpicks, or regressions
title: '(issue title -- summarise the summary)'
labels: ''
assignees: ''
---
[//]: # "This description supports Markdown syntax. There's a cheatsheet here: https://guides.github.com/features/mastering-markdown/"
[//]: # "These lines are comments, for letting you know what you should be writing. You can delete them or leave them in."
[//]: # "Also, please don't waste your time writing until you've checked for similar Issues. Remember to check closed Issues too!"
### Summary
[//]: # "Briefly describe what's broken. Include relevant details: loaded core, loaded rom's hash, open tools, running scripts... You can embed a screenshot if it's easier to show the bug, but if you need more than one please put them at the end."
Whenever my cat sits on the left side of my keyboard, games run too fast for me to react to.
### Repro
[//]: # "If you can't figure out the list of steps, delete this section and put 'heisenbug' in the summary somewhere. If a Lua script can cause the bug, you can embed that instead (as simple as possible please)."
1. first step
2. second step
3. et cetera
### Output
[//]: # "Paste the contents of the error dialog if there is one (try Ctrl+C, it usually works), or paste the output from the Lua Console, or delete this section."
```
System.InvalidOperationException: o noes
at BizHawk.Client.EmuHawk.HawkBiz.Crash()
at BizHawk.Client.EmuHawk.HawkBiz.RunWithoutCrashing()
```
### Host env.
[//]: # "List the computers you've found the bug with. If there's a version that doesn't have the bug, please put that in too. Here are some examples:"
- BizHawk 2.5.2; Win10 Pro 1903; AMD/AMD
- BizHawk 2.4.2; Win8.1; Intel/NVIDIA
- BizHawk dev build at 370996875; Win10 Home 1809; Intel/AMD
- BizHawk 2.5; Fedora 31; AMD/NVIDIA
[//]: # "(screenshots, if applicable)"
[//]: # "That's it! If you'd like to help more, you could try a dev build (see Testing in the readme) or an older release. Click submit now and you can edit it later."

View File

@ -1,33 +0,0 @@
---
name: Core port request
about: Request another emulator be ported into BizHawk
title: "[Core Port Req.] (name of emulator, and systems emulated if it's not obvious)"
type: Feature
labels: "Request: New core/port/re-port"
---
[//]: # "This description supports Markdown syntax. There's a cheatsheet here: https://guides.github.com/features/mastering-markdown/"
[//]: # "These lines are comments, for letting you know what you should be writing. You can delete them or leave them in."
[//]: # "Also, please don't waste your time writing until you've checked for duplicate core requests, both on the issue tracker and on this Wiki page: https://github.com/TASEmulators/BizHawk/wiki/Core-Requests"
### Upstream info
- [Website](https://example.com)
- Target platforms: (win/mac/tux)
- [Source repo](https://github.com/group/repo)
- Language(s): (programming language)
- Licence: (licence name/identifier)
### Merits
[//]: # "Briefly explain why this emulator is worth including in BizHawk. If it emulates the same system as an existing core, compare them."
(explanation)
### Technical details
[//]: # "Non-exhaustive list of things to consider:"
- (able to build .dll/.so for P/Invoke?)
- (frontend/backend separation--for example, can backend be built without SDL?)
- (can force single-threaded?)
- (has I/O abstraction accepting byte array, or only accepts file paths? for disc-based consoles, can swap out implementation for BizHawk's?)
- (savestate quality)
[//]: # "Code speaks louder than words: If you're able to make a proof-of-concept, pushing it to GitHub and putting a link here will speed up the process."

View File

@ -1,8 +0,0 @@
blank_issues_enabled: true
contact_links:
- name: "BEFORE OPENING AN ISSUE: Search for duplicates"
url: "https://github.com/TASVideos/BizHawk/issues?q=is:issue+<search+terms>"
about: "Use `is:issue <search terms>` to find open or closed issues that might be similar to your problem. (Clicking this option takes you back to the issue tracker index.)"
- name: "Chat with us on IRC"
url: "https://matrix.to/#/#bizhawk:libera.chat"
about: "Joins #bizhawk on Libera Chat with your browser. Please be patient as there isn't always somebody online."

View File

@ -1,13 +0,0 @@
[//]: # "This description supports Markdown syntax. There's a cheatsheet here: https://guides.github.com/features/mastering-markdown/"
[//]: # "These lines are comments, for letting you know what you should be writing. You can delete them or leave them in."
[//]: # "Also, please remember to link related Issues! If a bug hasn't been reported, you may submit a fix without creating an Issue."
[//]: # "A button which takes you to the automated builds, once they're been processed—fill in your GitHub username and the name of the branch"
[![dev build for branch | USERNAME:BRANCHNAME](https://img.shields.io/badge/dev_build_for_branch-USERNAME:BRANCHNAME-8250DF?logo=github&logoColor=333333&style=popout)](https://nightly.link/USERNAME/BizHawk/workflows/ci/BRANCHNAME?preview)
(describe changeset here)
[//]: # "Apart from the mandatory license signature, these tasks are optional, but doing them could save reviewers some time and get the PR merged sooner."
Check if completed:
- [ ] I have run any relevant test suites
- [ ] I, the commit author, have read the [licensing terms for contributors](https://github.com/TASEmulators/BizHawk/blob/master/contributing.md#copyrights-and-licensing) (last updated 2024-06-22) and am compliant

View File

@ -1,78 +0,0 @@
on: [push, pull_request, workflow_dispatch]
name: Build and test main solution
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
analyzer-build:
name: Build solution with analyzers
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install .NET 8
uses: actions/setup-dotnet@v4
with:
dotnet-version: "8"
- name: Debug build with analyzers
run: Dist/BuildDebug.sh -p:ContinuousIntegrationBuild=true -warnaserror
- name: Release build with analyzers
run: Dist/BuildRelease.sh -p:ContinuousIntegrationBuild=true -warnaserror
test:
name: Test
runs-on: ${{matrix.os.fullname}}
strategy:
fail-fast: false
matrix:
os:
- { prettyname: Windows, fullname: windows-latest }
- { prettyname: Linux, fullname: ubuntu-22.04 } # newer ubuntu versions don't ship with mono, so we need to pin for now, see https://github.com/actions/runner-images/issues/10636
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install .NET 8
uses: actions/setup-dotnet@v4
with:
dotnet-version: "8"
- name: Test
run: dotnet test BizHawk.sln -c Release -p:ContinuousIntegrationBuild=true
shell: pwsh
package:
name: Build and package output
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install .NET 8
uses: actions/setup-dotnet@v4
with:
dotnet-version: "8"
- name: Build solution
run: Dist/BuildRelease.sh
- name: Package (Linux)
run: Dist/Package.sh
- name: Upload Linux dev build
uses: actions/upload-artifact@v4
with:
name: BizHawk-dev-linux
path: packaged_output
- name: Package (Windows)
run: Dist/Package.sh windows-x64
- name: Upload Windows dev build
uses: actions/upload-artifact@v4
with:
name: BizHawk-dev-windows
path: packaged_output

View File

@ -1,60 +0,0 @@
name: Build mame (waterbox)
on:
pull_request:
branches: [ "master" ]
paths: [ "waterbox/emulibc/**", "waterbox/libco/**", "waterbox/libcxx/**", "waterbox/*", "waterbox/mame-arcade/**" ]
push:
branches: [ "master" ]
paths: [ "waterbox/emulibc/**", "waterbox/libco/**", "waterbox/libcxx/**", "waterbox/*", "waterbox/mame-arcade/**" ]
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
CC: clang-18
jobs:
build-waterbox:
uses: ./.github/workflows/waterbox.yml
build-mame:
runs-on: ubuntu-latest
needs: build-waterbox
steps:
- uses: actions/checkout@v4
- name: Getting submodule(s)
working-directory: ./waterbox/
run: git submodule update --init mame-arcade/mame
- name: Install clang 18
run: wget https://apt.llvm.org/llvm.sh;
chmod u+x llvm.sh;
sudo ./llvm.sh 18;
clang-18 --version;
- name: Download compiled waterbox
uses: actions/download-artifact@v4
with:
name: compiled-waterbox
path: waterbox/sysroot
- name: Give execution permission to compiler
working-directory: ./waterbox/sysroot
run: chmod u+x bin/*
- name: Build emulibc
working-directory: ./waterbox/emulibc
run: make -j
- name: Build libco
working-directory: ./waterbox/libco
run: make -j
- name: Build MAME
working-directory: ./waterbox/mame-arcade
run: make -j4 install
- name: Upload mame core
uses: actions/upload-artifact@v4
with:
name: mame-core
path: |
Assets/dll/libmamearcade.wbx.zst
retention-days: 90

View File

@ -1,25 +0,0 @@
name: Update nix dependencies
on:
push:
branches: [ "master" ]
paths: [ "Directory.Packages.props" ]
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
update-nix-dependencies:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: nixbuild/nix-quick-install-action@v32
- run: nix-build --pure -A emuhawk.fetch-deps && ./result
- name: Commit Dist/deps.nix
uses: stefanzweifel/git-auto-commit-action@v6
with:
commit_message: "Nix expr: Regen NuGet lockfile"
file_pattern: Dist/deps.nix

View File

@ -1,34 +0,0 @@
name: Build quickerNES core
on:
pull_request:
branches: [ "master" ]
paths: [ "quicknes/**" ]
push:
branches: [ "master" ]
paths: [ "quicknes/**" ]
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build-quickernes:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Getting submodule(s)
working-directory: ./quicknes
run: git submodule update --recursive --init core
- name: Building QuickerNES core (Linux)
working-directory: ./quicknes/make
run: make -j4; make install
- name: Upload quicknes core
uses: actions/upload-artifact@v4
with:
name: quicknes-core
path: |
Assets/dll/libquicknes.so
retention-days: 90

View File

@ -1,88 +0,0 @@
name: Build Waterbox Cores
on:
pull_request:
branches: [ "master" ]
paths: [ "waterbox/**" ]
push:
branches: [ "master" ]
paths: [ "waterbox/**" ]
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
CC: clang-18
jobs:
build-waterbox:
uses: ./.github/workflows/waterbox.yml
build-waterboxed-cores:
runs-on: ubuntu-latest
needs: build-waterbox
steps:
- uses: actions/checkout@v4
- name: Getting submodule(s)
working-directory: ./waterbox/
run: git submodule update --init snes9x;
git submodule update --init melon/melonDS;
git submodule update --init melon/BizPlatform/faad2;
git submodule update --init nyma/mednafen;
git submodule update --init ares64/ares/thirdparty/angrylion-rdp;
git submodule update --init gpgx/Genesis-Plus-GX;
git submodule update --init ../submodules/sameboy/libsameboy;
git submodule update --init uae/libretro-uae;
git submodule update --init stella/core;
git submodule update --init dsda/core;
git submodule update --init opera/opera-libretro;
git submodule update --init --recursive dosbox/dosbox-x;
- name: Install clang 18
run: wget https://apt.llvm.org/llvm.sh;
chmod u+x llvm.sh;
sudo ./llvm.sh 18;
clang-18 --version;
- name: Download compiled waterbox
uses: actions/download-artifact@v4
with:
name: compiled-waterbox
path: waterbox/sysroot
- name: Give execution permission to compiler
working-directory: ./waterbox/sysroot
run: chmod u+x bin/*
- name: Build all waterbox cores
working-directory: ./waterbox/
run: ./make-all-cores.sh install
- name: Upload waterbox cores
uses: actions/upload-artifact@v4
with:
name: waterbox-cores
path: |
Assets/dll/ares64_interpreter.wbx.zst
Assets/dll/ares64_recompiler.wbx.zst
Assets/dll/bsnes.wbx.zst
Assets/dll/dosbox.wbx.zst
Assets/dll/dsda.wbx.zst
Assets/dll/faust.wbx.zst
Assets/dll/gpgx.wbx.zst
Assets/dll/hyper.wbx.zst
Assets/dll/libsnes.wbx.zst
Assets/dll/melonDS.wbx.zst
Assets/dll/ngp.wbx.zst
Assets/dll/opera.wbx.zst
Assets/dll/pcfx.wbx.zst
Assets/dll/picodrive.wbx.zst
Assets/dll/shock.wbx.zst
Assets/dll/snes9x.wbx.zst
Assets/dll/ss.wbx.zst
Assets/dll/stella.wbx.zst
Assets/dll/tic80.wbx.zst
Assets/dll/turbo.wbx.zst
Assets/dll/uae.wbx.zst
Assets/dll/uzem.wbx.zst
Assets/dll/vb.wbx.zst
Assets/dll/virtualjaguar.wbx.zst
retention-days: 90

View File

@ -1,55 +0,0 @@
name: Build Waterbox
on: [workflow_dispatch, workflow_call]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-waterbox
cancel-in-progress: true
env:
CC: clang-18
jobs:
build-waterbox:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install clang 18
run: wget https://apt.llvm.org/llvm.sh;
chmod u+x llvm.sh;
sudo ./llvm.sh 18;
clang-18 --version;
- name: Set up env variables
run: echo "CLANG_VERSION=$(clang-18 -dumpversion)" >> $GITHUB_ENV;
echo "MUSL_COMMIT=$(git rev-parse HEAD:waterbox/musl)" >> $GITHUB_ENV;
- name: Cache waterbox
id: cache-waterbox
uses: actions/cache@v4
with:
path: waterbox/sysroot
key: waterbox-${{ hashFiles('waterbox/libcxx/configure-for-waterbox-phase-*', 'waterbox/libcxx/setup-llvm.sh', 'waterbox/libcxx/do-everything.sh') }}-${{ env.MUSL_COMMIT }}-${{ env.CLANG_VERSION }}
- if: ${{ steps.cache-waterbox.outputs.cache-hit != 'true' }}
name: Checkout submodule
working-directory: ./waterbox/
run: git submodule update --init musl
- if: ${{ steps.cache-waterbox.outputs.cache-hit != 'true' }}
name: Build musl
working-directory: ./waterbox/musl
run: ./wbox_configure.sh;
./wbox_build.sh;
- if: ${{ steps.cache-waterbox.outputs.cache-hit != 'true' }}
name: Build libcxx
working-directory: ./waterbox/libcxx
run: ./do-everything.sh
- if: ${{ steps.cache-waterbox.outputs.cache-hit != 'true' }}
name: Build nyma zlib
working-directory: ./waterbox/nyma
run: ./build-and-install-zlib.sh
- name: Upload compiled waterbox
uses: actions/upload-artifact@v4
with:
name: compiled-waterbox
path: waterbox/sysroot
retention-days: 90

65
.gitignore vendored
View File

@ -1,16 +1,17 @@
**/.vs/**
**/.vscode/
/snes9xgit
svnrev.cs
**/bin/**
**/obj/**
/output/**
/packaged_output
/result
/test_output
/output64/**
**/Release/**
**/Debug/**
**/ipch/**
/Assets/dll/*.wbx
Backup/
UpgradeLog.htm
*.ilk
*.il
*.tlog
*.obj
*.o
@ -18,13 +19,37 @@ UpgradeLog.htm
*.filters
*.opendb
/Dist/*.zip
/Dist/git_hooks/*.local.ps1
/BizHawk.Client.EmuHawk/tools/TAStudio/HistoryBox.Designer.cs
/BizHawk.Client.EmuHawk/tools/TAStudio/HistoryBox.cs
/BizHawk.Client.EmuHawk/tools/TAStudio/HistoryBox.resx
# mupen64plus-win32-deps is a submodule, so ignores should be in that repo
/BizHawk.Emulation.DiscSystem/Properties/svnrev.cs
/Build/*.vshost.*
/Dist/*.zip
/LuaInterface/LuaInterface/Properties
/Version/bin
/Version/obj
/Version/svnrev.cs
/attic/PsxHawk.API/Release
/attic/PsxHawk.Core/Debug
/attic/PsxHawk.Core/Release
/genplus-gx/libretro/msvc/ipch
/libmupen64plus/mupen64plus-video-z64/projects/msvc11/snes9xgit
/libmupen64plus/mupen64plus-win32-deps/SDL-1.2.14/docs
/libmupen64plus/mupen64plus-win32-deps/SDL-1.2.14/docs.html
/libsnes/vs2015/.vs
/libsnes/vs2015/.obj
/References/*.xml
*.opensdf
*.user
*.suo
@ -35,16 +60,16 @@ UpgradeLog.htm
.hgignore
.hgtags
/LuaInterface/Lua/src/.libs
/LuaInterface/Lua/src/Release-LUAPERKS
/LuaInterface/Release-LUAPERKS
ExternalCoreProjects/Virtu/bin/*.*
/psx/octoshock/bizhawk/Win32
/psx/octoshock/bizhawk/x64
/psx/octoshock/bizhawk/*.opendb
**/StyleCop.Cache
/waterbox/**/*.wbx
/waterbox/**/*.wbx.in
.idea
/packages
launchSettings.json
libsnes/vs2015/libsnes.VC.db
waterbox/**/*.wbx
waterbox/**/*.wbx.in

View File

@ -1,216 +0,0 @@
.disabled_not_a_job_include:
- template: Security/SAST.gitlab-ci.yml
variables:
CI_HAWK_ARTIFACT_NAME: "BizHawk_devbuild_${CI_COMMIT_SHORT_SHA}"
CI_HAWK_ARTIFACT_NAME_TAR: "$CI_HAWK_ARTIFACT_NAME.tar"
CI_HAWK_TMPARTIFACT_NAME: "BizHawk_tempbuild_${CI_COMMIT_REF_SLUG}_${CI_COMMIT_SHORT_SHA}"
workflow:
auto_cancel:
on_job_failure: all
stages:
- build
- test
- package
.with_cachix_mono:
before_script:
- nix-env -iA nixpkgs.cachix
- cachix use $CACHIX_CACHE_NAME
image: ${CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX}/nixos/nix:latest
variables:
CACHIX_CACHE_NAME: mono-for-bizhawk
build_asms_debug:
artifacts:
expire_in: "30 minutes"
name: "$CI_HAWK_TMPARTIFACT_NAME"
paths:
- output
image: mcr.microsoft.com/dotnet/sdk:8.0
script:
- Dist/BuildDebug.sh -v normal
stage: build
build_asms_release:
artifacts:
expire_in: "30 minutes"
name: "$CI_HAWK_TMPARTIFACT_NAME"
paths:
- output
image: mcr.microsoft.com/dotnet/sdk:8.0
script:
- if [ "$CI_COMMIT_REF_SLUG" == "release" ]; then Dist/UpdateVersionInfoForRelease.sh; fi
- Dist/BuildRelease.sh -v normal
stage: build
build_ext_projs:
allow_failure: true
image: mcr.microsoft.com/dotnet/sdk:8.0
rules:
- if: '$CI_PIPELINE_SOURCE == "schedule"'
when: always
script:
- for d in $CI_PROJECT_DIR/ExternalProjects/*; do if [ -e "$d/build_release.sh" -a "$(find "$d" -maxdepth 1 -name '*.csproj' -print -quit)" ]; then cd "$d"; ./build_release.sh -v normal || exit $?; fi; done
stage: test
build_ext_tools:
allow_failure: true
image: mcr.microsoft.com/dotnet/sdk:8.0
needs:
- build_asms_release
rules:
- if: '$CI_PIPELINE_SOURCE == "schedule"'
when: always
script:
- for d in $CI_PROJECT_DIR/ExternalToolProjects/*; do if [ -d "$d" ]; then cd "$d" && ./build_release.sh -v normal; fi; done
stage: test
build_nix_master:
# extends: .with_cachix_mono
image: ${CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX}/nixos/nix:latest
needs: []
rules:
- if: '$CI_PIPELINE_SOURCE == "schedule"'
when: always
script:
- nix-build --pure -A emuhawk
stage: test
build_nix_prev_release:
# extends: .with_cachix_mono
image: ${CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX}/nixos/nix:latest
needs: []
rules:
- if: '$CI_PIPELINE_SOURCE == "schedule"'
when: always
script:
- nix-build --pure -A emuhawk-latest
stage: test
check_style:
image: mcr.microsoft.com/dotnet/sdk:8.0
needs:
- job: build_asms_release
artifacts: false
rules:
- if: '$CI_PIPELINE_SOURCE == "schedule"'
when: always
allow_failure: true
- if: $BIZHAWKBUILD_USE_ANALYZERS != null
when: always
allow_failure: false
script:
- Dist/BuildRelease.sh -v normal
stage: test
.disabled_job_infersharp:
artifacts:
paths:
- infer-out/*
image: mcr.microsoft.com/infersharp:v1.0
needs:
- job: build_asms_release
rules:
- if: '$CI_PIPELINE_SOURCE == "schedule"'
when: always
script:
- mkdir "infer-in"
- find output -name "BizHawk.*.dll" -exec cp "{}" "infer-in" \;
- cp "output/EmuHawk.exe" "infer-in"
- /app/run_infersharp.sh "infer-in"
stage: test
.package_linux_x64:
artifacts:
expire_in: "1 month"
name: "$CI_HAWK_ARTIFACT_NAME"
paths:
- "$CI_HAWK_ARTIFACT_NAME_TAR"
image: ${CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX}/alpine:latest
needs:
- build_asms_release
- job: build_asms_debug
artifacts: false
script:
- Dist/Package.sh 'linux-x64'
- cd packaged_output
- tar -cf "../$CI_HAWK_ARTIFACT_NAME_TAR" *
stage: package
.package_windows_x64:
artifacts:
expire_in: "1 month"
name: "$CI_HAWK_ARTIFACT_NAME"
paths:
- ./*
image: ${CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX}/alpine:latest
needs:
- build_asms_release
- job: build_asms_debug
artifacts: false
script:
- Dist/Package.sh 'windows-x64'
# now we replace $CI_PROJECT_DIR with $CI_PROJECT_DIR/packaged_output, so that the archival step will put everything at the top level
- mv packaged_output ..
- cd ..
- rm -fr $CI_PROJECT_DIR
- mv packaged_output $CI_PROJECT_DIR
stage: package
package_devbuild_linux:
extends: .package_linux_x64
rules:
- if: $CI_COMMIT_REF_SLUG == "master"
when: always
package_devbuild_windows:
extends: .package_windows_x64
rules:
- if: $CI_COMMIT_REF_SLUG == "master"
when: always
package_release_linux:
extends: .package_linux_x64
rules:
- if: $CI_COMMIT_REF_SLUG == "release"
when: always
variables:
CI_HAWK_ARTIFACT_NAME: "BizHawk-VERSIONHERE-linux-x64.tar" # .zip is added automatically
CI_HAWK_ARTIFACT_NAME_TAR: "BizHawk-linux-x64-$CI_COMMIT_SHORT_SHA.tar"
package_release_windows:
extends: .package_windows_x64
rules:
- if: $CI_COMMIT_REF_SLUG == "release"
when: always
variables:
CI_HAWK_ARTIFACT_NAME: "BizHawk-VERSIONHERE-win-x64"
run_tests:
artifacts:
paths:
- test_output/*.coverage.xml
reports:
junit:
- test_output/*.coverage.xml
image: mcr.microsoft.com/dotnet/sdk:8.0
needs:
- job: build_asms_release
artifacts: false
script:
- apt-get update && apt-get install liblua5.4-0
- Dist/BuildTestRelease.sh -v normal -p:TestProjTargetFrameworkOverride=net8.0
stage: test
.disabled_job_sast:
variables:
SAST_EXCLUDED_ANALYZERS: bandit, brakeman, eslint, flawfinder, gosec, kubesec, nodejs-scan, phpcs-security-audit, pmd-apex, sobelow, spotbugs
stage: test
.disabled_not_a_job_cache:
key: "$CI_COMMIT_REF_SLUG"
paths:
- $HOME/.nuget/packages # probably won't work; set NUGET_PACKAGES to `BizHawk_master/.nuget_packages` and cache that

95
.gitmodules vendored
View File

@ -3,100 +3,11 @@
url = https://github.com/mupen64plus/mupen64plus-win32-deps.git
[submodule "libmupen64plus/GLideN64"]
path = libmupen64plus/GLideN64
url = https://github.com/TASEmulators/GLideN64.git
url = https://github.com/TASVideos/GLideN64.git
[submodule "libmupen64plus/mupen64plus-rsp-cxd4"]
path = libmupen64plus/mupen64plus-rsp-cxd4
url = https://github.com/TASEmulators/mupen64plus-rsp-cxd4.git
url = https://github.com/TASVideos/mupen64plus-rsp-cxd4.git
[submodule "waterbox/snes9x"]
path = waterbox/snes9x
url = https://github.com/TASEmulators/snes9x.git
url = https://github.com/TASVideos/snes9x.git
branch = bizsnes
[submodule "mgba"]
path = submodules/mgba
url = https://github.com/TASEmulators/mgba.git
branch = bizhawk-0.11
[submodule "waterbox/melon/melonDS"]
path = waterbox/melon/melonDS
url = https://github.com/TASEmulators/melonDS.git
branch = melonbiz
[submodule "waterbox/melon/BizPlatform/faad2"]
path = waterbox/melon/BizPlatform/faad2
url = https://github.com/knik0/faad2.git
[submodule "waterbox/musl"]
path = waterbox/musl
url = https://github.com/nattthebear/musl.git
[submodule "waterbox/nyma/mednafen"]
path = waterbox/nyma/mednafen
url = https://github.com/TASEmulators/mednafen.git
[submodule "submodules/gambatte"]
path = submodules/gambatte
url = https://github.com/pokemon-speedrunning/gambatte-core.git
[submodule "submodules/libdarm"]
path = submodules/libdarm
url = https://github.com/jbremer/darm.git
[submodule "submodules/libfwunpack"]
path = submodules/libfwunpack
url = https://github.com/TASEmulators/fwunpack.git
[submodule "submodules/libemu83"]
path = submodules/libemu83
url = https://github.com/CasualPokePlayer/Emu83.git
[submodule "submodules/sameboy/libsameboy"]
path = submodules/sameboy/libsameboy
url = https://github.com/LIJI32/SameBoy.git
[submodule "waterbox/ares64/ares/thirdparty/angrylion-rdp"]
path = waterbox/ares64/ares/thirdparty/angrylion-rdp
url = https://github.com/TASEmulators/angrylion-rdp.git
branch = ares
[submodule "libmupen64plus/mupen64plus-video-angrylion-rdp"]
path = libmupen64plus/mupen64plus-video-angrylion-rdp
url = https://github.com/TASEmulators/angrylion-rdp.git
branch = biz_mupen64plus
[submodule "waterbox/mame-arcade/mame"]
path = waterbox/mame-arcade/mame
url = https://github.com/TASEmulators/mame.git
branch = mamehawk0252
[submodule "ExternalProjects/librcheevos/rcheevos"]
path = ExternalProjects/librcheevos/rcheevos
url = https://github.com/RetroAchievements/rcheevos.git
[submodule "encore/encore"]
path = encore/encore
url = https://github.com/CasualPokePlayer/encore.git
branch = headless
[submodule "ExternalProjects/SDL2/SDL"]
path = ExternalProjects/SDL2/SDL
url = https://github.com/libsdl-org/SDL.git
branch = SDL2
[submodule "ExternalProjects/SDL2/libusb"]
path = ExternalProjects/SDL2/libusb
url = https://github.com/libusb/libusb.git
[submodule "quicknes/core"]
path = quicknes/core
url = https://github.com/TASEmulators/quickerNES.git
branch = main
[submodule "waterbox/gpgx/Genesis-Plus-GX"]
path = waterbox/gpgx/Genesis-Plus-GX
url = https://github.com/TASEmulators/Genesis-Plus-GX.git
branch = tasvideos-2.2
[submodule "waterbox/stella/core"]
path = waterbox/stella/core
url = https://github.com/TASEmulators/stella.git
branch = tasvideos-1
[submodule "waterbox/uae/libretro-uae"]
path = waterbox/uae/libretro-uae
url = https://github.com/TASEmulators/libretro-uae.git
branch = wbx-1
[submodule "ExternalProjects/FlooohChips/chips"]
path = ExternalProjects/FlooohChips/chips
url = https://github.com/floooh/chips.git
[submodule "waterbox/dosbox/dosbox-x"]
path = waterbox/dosbox/dosbox-x
url = https://github.com/TASEmulators/dosbox-x.git
branch = wbx
[submodule "waterbox/dsda/core"]
path = waterbox/dsda/core
url = https://github.com/TASEmulators/dsda-doom.git
branch = wbx
[submodule "waterbox/opera/opera-libretro"]
path = waterbox/opera/opera-libretro
url = https://github.com/TASEmulators/opera-libretro.git
branch = wbx

View File

@ -1,855 +0,0 @@
is_global = true
# Obsolete member 'memberA' overrides non-obsolete member 'memberB' (this simply doesn't work, see https://learn.microsoft.com/en-us/dotnet/csharp/misc/cs0809#methods-recognized-as-obsolete)
dotnet_diagnostic.CS0809.severity = error
## BizHawk internal rules
# Do not use anonymous delegates
dotnet_diagnostic.BHI1001.severity = error
# Do not use anonymous types (classes)
dotnet_diagnostic.BHI1002.severity = error
# Do not use query expression syntax
dotnet_diagnostic.BHI1003.severity = error
# Verbatim interpolated strings should begin $@, not @$
dotnet_diagnostic.BHI1004.severity = error
# Default branch of switch expression should throw InvalidOperationException/SwitchExpressionException or not throw
dotnet_diagnostic.BHI1005.severity = silent
# Do not discard local variables
dotnet_diagnostic.BHI1006.severity = error
# Don't use target-typed new for throw expressions
dotnet_diagnostic.BHI1007.severity = error
# Do not use init setter
dotnet_diagnostic.BHI1008.severity = error
# ref struct should not override ValueType.{Equals,GetHashCode}
dotnet_diagnostic.BHI1009.severity = error
# Don't call this.GetType() in sealed type, use typeof operator
dotnet_diagnostic.BHI1100.severity = error
# Don't call this.GetType(), use typeof operator (or replace subtype check with better encapsulation)
dotnet_diagnostic.BHI1101.severity = error
# Don't call typeof(T).Name, use nameof operator
dotnet_diagnostic.BHI1102.severity = error
# Don't call typeof(T).ToString(), use nameof operator or typeof(T).FullName
dotnet_diagnostic.BHI1103.severity = error
# Don't use ^= (XOR-assign) for inverting the value of booleans
dotnet_diagnostic.BHI1104.severity = error
# Use unambiguous decimal<=>float/double conversion methods
dotnet_diagnostic.BHI1105.severity = error
# Brackets of collection expression should be separated with spaces
dotnet_diagnostic.BHI1110.severity = warning
# Expression-bodied member should be flowed to next line correctly
dotnet_diagnostic.BHI1120.severity = silent
# Record type declaration missing class (or struct) keyword
dotnet_diagnostic.BHI1130.severity = error
# Check result of IDictionary.TryGetValue, or discard it if default(T) is desired
dotnet_diagnostic.BHI1200.severity = error
# Inferred type of branches of ternary expression in interpolation don't match
dotnet_diagnostic.BHI1210.severity = error
# Declare checked operators
dotnet_diagnostic.BHI1300.severity = warning
# Call to FirstOrDefault when elements are of a value type; FirstOrNull may have been intended
dotnet_diagnostic.BHI3100.severity = error
# Use .Order()/.OrderDescending() shorthand
dotnet_diagnostic.BHI3101.severity = warning
# Prefer specialised methods over LINQ on string receivers
dotnet_diagnostic.BHI3102.severity = error
# Use IsEmpty instead of checking Length
dotnet_diagnostic.BHI3103.severity = error
# Throw NotImplementedException from methods/props marked [FeatureNotImplemented]
dotnet_diagnostic.BHI3300.severity = error
## Design rules
# Do not declare static members on generic types
dotnet_diagnostic.CA1000.severity = error
# Properties should not be write only
dotnet_diagnostic.CA1044.severity = error
# Do not raise exceptions in unexpected locations
dotnet_diagnostic.CA1065.severity = error
## Globalization rules
# Specify IFormatProvider
dotnet_diagnostic.CA1305.severity = error
dotnet_code_quality.CA1305.excluded_symbol_names = T:System.Byte|T:System.SByte|T:System.Int16|T:System.UInt16|T:System.Int32|T:System.UInt32|T:System.Int64|T:System.UInt64|T:System.String|T:System.Text.StringBuilder|T:System.Convert
# Specify marshalling for P/Invoke string arguments
dotnet_diagnostic.CA2101.severity = suggestion
# Specify StringComparison for clarity
dotnet_diagnostic.CA1307.severity = silent # SpecifyStringComparisonAnalyzer very slow
# Specify StringComparison for correctness
dotnet_diagnostic.CA1310.severity = silent # SpecifyStringComparisonAnalyzer very slow
## Naming rules
# Identifiers should have correct prefix
dotnet_diagnostic.CA1715.severity = error
# Property names should not match get methods
dotnet_diagnostic.CA1721.severity = warning
## Performance rules
# Do not initialize unnecessarily
dotnet_diagnostic.CA1805.severity = silent
# Do not ignore method results
dotnet_diagnostic.CA1806.severity = error
# Test for empty strings using string length
dotnet_diagnostic.CA1820.severity = warning
# Mark members as static
dotnet_diagnostic.CA1822.severity = silent
# Avoid zero-length array allocations
dotnet_diagnostic.CA1825.severity = warning
# Use property instead of Linq Enumerable method
dotnet_diagnostic.CA1826.severity = error
dotnet_code_quality.CA1826.exclude_ordefault_methods = true
# Do not use Count()/LongCount() when Any() can be used
dotnet_diagnostic.CA1827.severity = error
# Do not use CountAsync/LongCountAsync when AnyAsync can be used
dotnet_diagnostic.CA1828.severity = error
# Use Length/Count property instead of Enumerable.Count method
dotnet_diagnostic.CA1829.severity = error
# Prefer IsEmpty over Count when available
dotnet_diagnostic.CA1836.severity = error
# Avoid StringBuilder parameters for P/Invokes
dotnet_diagnostic.CA1838.severity = suggestion
# Prefer the `IDictionary.TryGetValue(TKey, out TValue)` method
dotnet_diagnostic.CA1854.severity = warning
# Avoid using 'Enumerable.Any()' extension method
dotnet_diagnostic.CA1860.severity = error
# Use the 'StringComparison' method overloads to perform case-insensitive string comparisons
dotnet_diagnostic.CA1862.severity = error
# Unnecessary call to 'Contains' for sets
dotnet_diagnostic.CA1868.severity = warning
## Reliability rules
# `ThreadStatic` fields should not use inline initialization
dotnet_diagnostic.CA2019.severity = error
## Usage rules
# Call GC.SuppressFinalize correctly
dotnet_diagnostic.CA1816.severity = none
# Do not raise reserved exception types
dotnet_diagnostic.CA2201.severity = suggestion
# Do not call overridable methods in constructors
dotnet_diagnostic.CA2214.severity = warning
# Implement serialization constructors
dotnet_diagnostic.CA2229.severity = silent
# Opt in to preview features before using them
dotnet_diagnostic.CA2252.severity = silent # CSharpDetectPreviewFeatureAnalyzer very slow
## .NET DocumentationAnalyzers style rules
# Place text in paragraphs
dotnet_diagnostic.DOC100.severity = silent
# Use child blocks consistently
dotnet_diagnostic.DOC101.severity = silent
# Use child blocks consistently across elements of the same kind
dotnet_diagnostic.DOC102.severity = silent
# Use Unicode characters # unnecessary HTML entities also get picked up by CS1570, which seems more reliable
dotnet_diagnostic.DOC103.severity = error
# Prefer '<see langword="keyword"/>' to '<c>keyword</c>' for referencing language keywords
dotnet_diagnostic.DOC104.severity = warning
# Prefer '<paramref name="parameter"/>' to '<c>parameter</c>' for referencing parameters
dotnet_diagnostic.DOC105.severity = warning
# Prefer '<typeparamref name="type_parameter"/>' to '<c>type_parameter</c>' for referencing type parameters
dotnet_diagnostic.DOC106.severity = warning
# Prefer '<see cref="target"/>' to '<c>target</c>' for referencing code elements
dotnet_diagnostic.DOC107.severity = warning
# Avoid empty paragraphs
dotnet_diagnostic.DOC108.severity = error
## .NET DocumentationAnalyzers portability rules
# Use XML documentation syntax
dotnet_diagnostic.DOC200.severity = error
# Item should have description
dotnet_diagnostic.DOC201.severity = error
# Use section elements correctly
dotnet_diagnostic.DOC202.severity = error
# Use block elements correctly
dotnet_diagnostic.DOC203.severity = error
# Use inline elements correctly # but this doesn't pick up <seealso/> in <summary/>, for example...
dotnet_diagnostic.DOC204.severity = error
# 'langword' attribute value should be a language keyword
dotnet_diagnostic.DOC207.severity = error
# 'href' attribute value should be a URI # a lot of false negatives with this one too
dotnet_diagnostic.DOC209.severity = error
## Meziantou.Analyzers rules
# StringComparison is missing
dotnet_diagnostic.MA0001.severity = silent
# IEqualityComparer<string> or IComparer<string> is missing
dotnet_diagnostic.MA0002.severity = silent
# Add parameter name to improve readability
dotnet_diagnostic.MA0003.severity = silent
# Use Task.ConfigureAwait(false)
dotnet_diagnostic.MA0004.severity = silent
# Use Array.Empty<T>()
dotnet_diagnostic.MA0005.severity = silent # redundant with CA1825
# Use String.Equals instead of equality operator
dotnet_diagnostic.MA0006.severity = silent
# Add a comma after the last value
dotnet_diagnostic.MA0007.severity = silent
# Add StructLayoutAttribute
dotnet_diagnostic.MA0008.severity = silent
# Add regex evaluation timeout
dotnet_diagnostic.MA0009.severity = silent
# Mark attributes with AttributeUsageAttribute
dotnet_diagnostic.MA0010.severity = error
# IFormatProvider is missing
dotnet_diagnostic.MA0011.severity = silent
# Do not raise reserved exception type
dotnet_diagnostic.MA0012.severity = error
# Types should not extend System.ApplicationException
dotnet_diagnostic.MA0013.severity = error
# Do not raise System.ApplicationException type
dotnet_diagnostic.MA0014.severity = error
# Specify the parameter name in ArgumentException
dotnet_diagnostic.MA0015.severity = error
# Prefer returning collection abstraction instead of implementation
dotnet_diagnostic.MA0016.severity = silent
# Abstract types should not have public or internal constructors
dotnet_diagnostic.MA0017.severity = silent
# Use EventArgs.Empty
dotnet_diagnostic.MA0019.severity = error
# Use direct methods instead of LINQ methods
dotnet_diagnostic.MA0020.severity = error
# Use StringComparer.GetHashCode instead of string.GetHashCode
dotnet_diagnostic.MA0021.severity = silent
# Return Task.FromResult instead of returning null
dotnet_diagnostic.MA0022.severity = error
# Add RegexOptions.ExplicitCapture
dotnet_diagnostic.MA0023.severity = silent
# Use an explicit StringComparer when possible
dotnet_diagnostic.MA0024.severity = error
# Implement the functionality instead of throwing NotImplementedException
dotnet_diagnostic.MA0025.severity = silent
# Fix TODO comment
dotnet_diagnostic.MA0026.severity = silent
# Do not remove original exception
dotnet_diagnostic.MA0027.severity = error
# Optimize StringBuilder usage
dotnet_diagnostic.MA0028.severity = silent
# Combine LINQ methods
dotnet_diagnostic.MA0029.severity = error # redundant with IDE0120
# Remove useless OrderBy call
dotnet_diagnostic.MA0030.severity = error
# Optimize Enumerable.Count() usage
dotnet_diagnostic.MA0031.severity = error
# Use an overload with a CancellationToken argument
dotnet_diagnostic.MA0032.severity = silent # UseAnOverloadThatHasCancellationTokenAnalyzer very slow
# Do not tag instance fields with ThreadStaticAttribute
dotnet_diagnostic.MA0033.severity = error
# Do not use dangerous threading methods
dotnet_diagnostic.MA0035.severity = error
# Make class static
dotnet_diagnostic.MA0036.severity = silent
# Remove empty statement
dotnet_diagnostic.MA0037.severity = error
# Make method static
dotnet_diagnostic.MA0038.severity = silent
# Do not write your own certificate validation method
dotnet_diagnostic.MA0039.severity = error
# Flow the cancellation token
dotnet_diagnostic.MA0040.severity = silent # UseAnOverloadThatHasCancellationTokenAnalyzer very slow
# Make property static
dotnet_diagnostic.MA0041.severity = silent
# Do not use blocking calls in an async method
dotnet_diagnostic.MA0042.severity = silent # DoNotUseBlockingCallInAsyncContextAnalyzer very slow
# Use nameof operator in ArgumentException
dotnet_diagnostic.MA0043.severity = silent # redundant with CA1507
# Remove useless ToString call
dotnet_diagnostic.MA0044.severity = warning
# Do not use blocking call in a sync method (need to make containing method async)
dotnet_diagnostic.MA0045.severity = silent # DoNotUseBlockingCallInAsyncContextAnalyzer very slow
# Use EventHandler<T> to declare events
dotnet_diagnostic.MA0046.severity = silent
# Declare types in namespaces
dotnet_diagnostic.MA0047.severity = error
# File name must match type name
dotnet_diagnostic.MA0048.severity = silent
# Type name should not match containing namespace
dotnet_diagnostic.MA0049.severity = silent
# Validate arguments correctly in iterator methods
dotnet_diagnostic.MA0050.severity = error
# Method is too long
dotnet_diagnostic.MA0051.severity = silent
# Replace constant Enum.ToString with nameof
dotnet_diagnostic.MA0052.severity = error
# Make class sealed
dotnet_diagnostic.MA0053.severity = silent
# Embed the caught exception as innerException
dotnet_diagnostic.MA0054.severity = error
# Do not use finalizer
dotnet_diagnostic.MA0055.severity = silent
# Do not call overridable members in constructor
dotnet_diagnostic.MA0056.severity = silent
# Class name should end with 'Attribute'
dotnet_diagnostic.MA0057.severity = error
# Class name should end with 'Exception'
dotnet_diagnostic.MA0058.severity = error
# Class name should end with 'EventArgs'
dotnet_diagnostic.MA0059.severity = silent
# The value returned by Stream.Read/Stream.ReadAsync is not used
dotnet_diagnostic.MA0060.severity = error
# Method overrides should not change parameter defaults
dotnet_diagnostic.MA0061.severity = silent
# Non-flags enums should not be marked with "FlagsAttribute"
dotnet_diagnostic.MA0062.severity = silent
# Use Where before OrderBy
dotnet_diagnostic.MA0063.severity = error
# Avoid locking on publicly accessible instance
dotnet_diagnostic.MA0064.severity = silent
# Default ValueType.Equals or HashCode is used for struct's equality
dotnet_diagnostic.MA0065.severity = error
# Hash table unfriendly type is used in a hash table
dotnet_diagnostic.MA0066.severity = error
# Use Guid.Empty
dotnet_diagnostic.MA0067.severity = error
# Invalid parameter name for nullable attribute
dotnet_diagnostic.MA0068.severity = error
# Non-constant static fields should not be visible
dotnet_diagnostic.MA0069.severity = silent
# Obsolete attributes should include explanations
dotnet_diagnostic.MA0070.severity = warning
# Avoid using redundant else
dotnet_diagnostic.MA0071.severity = silent
# Do not throw from a finally block
dotnet_diagnostic.MA0072.severity = error
# Avoid comparison with bool constant
dotnet_diagnostic.MA0073.severity = silent
# Avoid implicit culture-sensitive methods
dotnet_diagnostic.MA0074.severity = silent
# Do not use implicit culture-sensitive ToString
dotnet_diagnostic.MA0075.severity = silent
# Do not use implicit culture-sensitive ToString in interpolated strings
dotnet_diagnostic.MA0076.severity = silent
# A class that provides Equals(T) should implement IEquatable<T>
dotnet_diagnostic.MA0077.severity = error
# Use 'Cast' instead of 'Select' to cast
dotnet_diagnostic.MA0078.severity = error
# Flow the cancellation token using .WithCancellation()
dotnet_diagnostic.MA0079.severity = silent # UseAnOverloadThatHasCancellationTokenAnalyzer very slow
# Use a cancellation token using .WithCancellation()
dotnet_diagnostic.MA0080.severity = silent # UseAnOverloadThatHasCancellationTokenAnalyzer very slow
# Method overrides should not omit params keyword
dotnet_diagnostic.MA0081.severity = error
# NaN should not be used in comparisons
dotnet_diagnostic.MA0082.severity = error
# ConstructorArgument parameters should exist in constructors
dotnet_diagnostic.MA0083.severity = error
# Local variable should not hide other symbols
dotnet_diagnostic.MA0084.severity = error
# Anonymous delegates should not be used to unsubscribe from Events
dotnet_diagnostic.MA0085.severity = error
# Do not throw from a finalizer
dotnet_diagnostic.MA0086.severity = error
# Parameters with [DefaultParameterValue] attributes should also be marked [Optional]
dotnet_diagnostic.MA0087.severity = error
# Use [DefaultParameterValue] instead of [DefaultValue]
dotnet_diagnostic.MA0088.severity = error
# Optimize string method usage
dotnet_diagnostic.MA0089.severity = error
# Remove empty else/finally block
dotnet_diagnostic.MA0090.severity = warning
# Sender should be 'this' for instance events
dotnet_diagnostic.MA0091.severity = error
# Sender should be 'null' for static events
dotnet_diagnostic.MA0092.severity = error
# EventArgs should not be null
dotnet_diagnostic.MA0093.severity = error
# A class that provides CompareTo(T) should implement IComparable<T>
dotnet_diagnostic.MA0094.severity = error
# A class that implements IEquatable<T> should override Equals(object)
dotnet_diagnostic.MA0095.severity = error
# A class that implements IComparable<T> should also implement IEquatable<T>
dotnet_diagnostic.MA0096.severity = silent
# A class that implements IComparable<T> or IComparable should override comparison operators
dotnet_diagnostic.MA0097.severity = silent
# Use indexer instead of LINQ methods
dotnet_diagnostic.MA0098.severity = warning
# Use Explicit enum value instead of 0
dotnet_diagnostic.MA0099.severity = silent
# Await task before disposing of resources
dotnet_diagnostic.MA0100.severity = error
# String contains an implicit end of line character
dotnet_diagnostic.MA0101.severity = silent
# Make member readonly
dotnet_diagnostic.MA0102.severity = silent
# Use SequenceEqual instead of equality operator
dotnet_diagnostic.MA0103.severity = error
# Do not create a type with a name from the BCL
dotnet_diagnostic.MA0104.severity = error
# Use the lambda parameters instead of using a closure
dotnet_diagnostic.MA0105.severity = error
# Avoid closure by using an overload with the 'factoryArgument' parameter
dotnet_diagnostic.MA0106.severity = error
# Do not use culture-sensitive object.ToString
dotnet_diagnostic.MA0107.severity = silent
# Remove redundant argument value
dotnet_diagnostic.MA0108.severity = error
# Consider adding an overload with a Span<T> or Memory<T>
dotnet_diagnostic.MA0109.severity = silent
# Use the Regex source generator
dotnet_diagnostic.MA0110.severity = error
# Use 'Count > 0' instead of 'Any()'
dotnet_diagnostic.MA0112.severity = error
# Raw String contains an implicit end of line character (if you compile on Windows you may get CRLFs in string literals)
dotnet_diagnostic.MA0136.severity = warning
# Both if and else branch have identical code
dotnet_diagnostic.MA0140.severity = warning
# Use pattern matching instead of inequality operators for null check
dotnet_diagnostic.MA0141.severity = silent
# Use pattern matching instead of equality operators for null check
dotnet_diagnostic.MA0142.severity = silent
# Use pattern matching instead of equality operators for discrete value
dotnet_diagnostic.MA0148.severity = silent
# Use pattern matching instead of inequality operators for discrete value
dotnet_diagnostic.MA0149.severity = silent
# Do not use async void methods
dotnet_diagnostic.MA0155.severity = error
# Use 'Async' suffix when a method returns IAsyncEnumerable<T>
dotnet_diagnostic.MA0156.severity = error
# Do not use 'Async' suffix when a method does not return IAsyncEnumerable<T>
dotnet_diagnostic.MA0157.severity = error
# Use ContainsKey instead of TryGetValue
dotnet_diagnostic.MA0160.severity = warning
# Use Process.Start overload with ProcessStartInfo
dotnet_diagnostic.MA0162.severity = error
# Use parentheses to make `not` pattern clearer
dotnet_diagnostic.MA0164.severity = error
# Forward the TimeProvider to methods that take one
dotnet_diagnostic.MA0166.severity = silent # redundant with MA0167
# Use an overload with a TimeProvider argument
dotnet_diagnostic.MA0167.severity = warning
# Use Equals method instead of operator (`==` call is non-overridden reference equality)
dotnet_diagnostic.MA0169.severity = error
# Type cannot be used as an attribute argument
dotnet_diagnostic.MA0170.severity = error
## Menees.Analyzers rules
# Line is too long
dotnet_diagnostic.MEN002.severity = silent
# Method is too long
dotnet_diagnostic.MEN003.severity = silent
# Property accessor is too long
dotnet_diagnostic.MEN004.severity = silent
# File is too long
dotnet_diagnostic.MEN005.severity = silent
# Use a single return
dotnet_diagnostic.MEN007.severity = silent
# File name should match type
dotnet_diagnostic.MEN008.severity = silent
# Use the preferred exception type
dotnet_diagnostic.MEN009.severity = silent
# Avoid magic numbers
dotnet_diagnostic.MEN010.severity = silent
# Flags should be powers of two
dotnet_diagnostic.MEN012.severity = silent
# Use UTC time
dotnet_diagnostic.MEN013.severity = silent
# Prefer TryGetValue
dotnet_diagnostic.MEN014.severity = warning
# Use Preferred Terms
dotnet_diagnostic.MEN015.severity = silent
# Use object-oriented methods instead of top-level statements
dotnet_diagnostic.MEN016.severity = silent
# Use Digit Separators
dotnet_diagnostic.MEN018.severity = warning
## Roslynator.Analyzers rules
# Put expression body on its own line
dotnet_diagnostic.RCS0062.severity = silent # doesn't work? we have BHI1120 ready to go anyway
# Use nameof operator
dotnet_diagnostic.RCS1015.severity = silent # redundant with CA1507
# Remove redundant boolean literal
dotnet_diagnostic.RCS1033.severity = silent # redundant with IDE0100
# Remove trailing white-space
dotnet_diagnostic.RCS1037.severity = silent # redundant with SA1028
# Remove 'partial' modifier from type with a single part
dotnet_diagnostic.RCS1043.severity = warning
# Remove original exception from throw statement
dotnet_diagnostic.RCS1044.severity = silent # redundant with MA0027
# Non-asynchronous method name should not end with 'Async'
dotnet_diagnostic.RCS1047.severity = silent # pending https://github.com/TASEmulators/BizHawk/issues/2888
# Use lambda expression instead of anonymous method
dotnet_diagnostic.RCS1048.severity = silent # redundant with BHI1001
# Simplify boolean comparison
dotnet_diagnostic.RCS1049.severity = silent # redundant with IDE0100
# Use compound assignment
dotnet_diagnostic.RCS1058.severity = silent # redundant with IDE0054
# Avoid locking on publicly accessible instance
dotnet_diagnostic.RCS1059.severity = silent
# Avoid empty catch clause that catches System.Exception
dotnet_diagnostic.RCS1075.severity = silent
# Optimize LINQ method call
dotnet_diagnostic.RCS1077.severity = silent # redundant with IDE0120
# Use 'Count/Length' property instead of 'Any' method
dotnet_diagnostic.RCS1080.severity = error
# Use --/++ operator instead of assignment
dotnet_diagnostic.RCS1089.severity = silent # redundant with IDE0054
# File contains no code
dotnet_diagnostic.RCS1093.severity = silent
# Remove redundant 'ToString' call
dotnet_diagnostic.RCS1097.severity = silent # redundant with MA0044
# Constant values should be placed on right side of comparisons
dotnet_diagnostic.RCS1098.severity = silent # comes for free w/ pattern matching
# Default label should be the last label in a switch section
dotnet_diagnostic.RCS1099.severity = silent
# Make class static
dotnet_diagnostic.RCS1102.severity = silent
# Simplify conditional expression
dotnet_diagnostic.RCS1104.severity = silent # redundant with IDE0075
# Declare type inside namespace
dotnet_diagnostic.RCS1110.severity = silent # redundant with MA0047
# Combine 'Enumerable.Where' method chain
dotnet_diagnostic.RCS1112.severity = silent # redundant with MA0029
# Add parentheses when necessary
dotnet_diagnostic.RCS1123.severity = silent
# Use coalesce expression
dotnet_diagnostic.RCS1128.severity = silent # redundant with IDE0074
# Bitwise operation on enum without Flags attribute
dotnet_diagnostic.RCS1130.severity = error
# Declare enum member with zero value (when enum has FlagsAttribute)
dotnet_diagnostic.RCS1135.severity = silent # redundant with CA1008
# Add summary to documentation comment
dotnet_diagnostic.RCS1138.severity = silent
# Add summary element to documentation comment
dotnet_diagnostic.RCS1139.severity = silent
# Use StringComparison when comparing strings
dotnet_diagnostic.RCS1155.severity = silent # redundant with CA1862
# Use string.Length instead of comparison with empty string
dotnet_diagnostic.RCS1156.severity = error
# Composite enum value contains undefined flag
dotnet_diagnostic.RCS1157.severity = warning
# Static member in generic type should use a type parameter
dotnet_diagnostic.RCS1158.severity = silent # redundant with CA1000/MA0018
# Use EventHandler<T>
dotnet_diagnostic.RCS1159.severity = silent
# Abstract type should not have public constructors
dotnet_diagnostic.RCS1160.severity = error
# Unused parameter
dotnet_diagnostic.RCS1163.severity = silent # redundant with IDE0060
# Value type object is never equal to null
dotnet_diagnostic.RCS1166.severity = silent # redundant with CS0472
# Make field read-only
dotnet_diagnostic.RCS1169.severity = silent # redundant with IDE0044
# Use read-only auto-implemented property
dotnet_diagnostic.RCS1170.severity = silent # redundant with MEN017
# Simplify lazy initialization
dotnet_diagnostic.RCS1171.severity = silent # redundant with IDE0074
# Unused 'this' parameter
dotnet_diagnostic.RCS1175.severity = silent # redundant with IDE0060
# Inline lazy initialization
dotnet_diagnostic.RCS1180.severity = silent # redundant with IDE0074
# Use constant instead of field
dotnet_diagnostic.RCS1187.severity = silent
# Declare enum value as combination of names
dotnet_diagnostic.RCS1191.severity = warning
# Overriding member should not change 'params' modifier
dotnet_diagnostic.RCS1193.severity = silent # redundant with MA0081
# Implement exception constructors
dotnet_diagnostic.RCS1194.severity = silent
# Use ^ operator
dotnet_diagnostic.RCS1195.severity = warning
# Use AttributeUsageAttribute
dotnet_diagnostic.RCS1203.severity = silent # redundant with MA0010
# Use EventArgs.Empty
dotnet_diagnostic.RCS1204.severity = silent # redundant with MA0019
# Order named arguments according to the order of parameters
dotnet_diagnostic.RCS1205.severity = silent
# Return completed task instead of returning null
dotnet_diagnostic.RCS1210.severity = silent # redundant with MA0022
# Remove unused member declaration
dotnet_diagnostic.RCS1213.severity = silent # redundant with CS0414
# Use pattern matching instead of combination of 'as' operator and null check
dotnet_diagnostic.RCS1221.severity = silent # redundant with IDE0019
# Merge preprocessor directives
dotnet_diagnostic.RCS1222.severity = silent
# Make method an extension method
dotnet_diagnostic.RCS1224.severity = warning
# Make class sealed
dotnet_diagnostic.RCS1225.severity = silent
# Add paragraph to documentation comment
dotnet_diagnostic.RCS1226.severity = warning
# Validate arguments correctly
dotnet_diagnostic.RCS1227.severity = error
# Use async/await when necessary
dotnet_diagnostic.RCS1229.severity = error
# Order elements in documentation comment
dotnet_diagnostic.RCS1232.severity = silent
# Duplicate enum value
dotnet_diagnostic.RCS1234.severity = silent
# Use exception filter
dotnet_diagnostic.RCS1236.severity = warning
# Operator is unnecessary
dotnet_diagnostic.RCS1240.severity = warning
# Do not pass non-read-only struct by read-only reference
dotnet_diagnostic.RCS1242.severity = silent
# Duplicate word in a comment
dotnet_diagnostic.RCS1243.severity = warning
# Use element access
dotnet_diagnostic.RCS1246.severity = warning
# Fix documentation comment tag
dotnet_diagnostic.RCS1247.severity = silent # redundant with DOC203
# Unnecessary null-forgiving operator
dotnet_diagnostic.RCS1249.severity = warning
# Normalize format of enum flag value
dotnet_diagnostic.RCS1254.severity = silent
# Invalid argument null check
dotnet_diagnostic.RCS1256.severity = error
# Use enum field explicitly
dotnet_diagnostic.RCS1257.severity = warning
# Unnecessary enum flag
dotnet_diagnostic.RCS1258.severity = warning
# Remove empty syntax
dotnet_diagnostic.RCS1259.severity = silent # `else`/`finally` redundant with MA0090, `;;` redundant with MA0037, obj. init. doesn't work, others useless
# Resource can be disposed asynchronously
dotnet_diagnostic.RCS1261.severity = error
# Unnecessary raw string literal
dotnet_diagnostic.RCS1262.severity = silent
# Invalid reference in a documentation comment
dotnet_diagnostic.RCS1263.severity = silent # redundant with CS1572
## Microsoft.CodeAnalysis.BannedApiAnalyzers rules
# Do not use banned APIs
dotnet_diagnostic.RS0030.severity = error
## StyleCop spacing rules
# Keywords should be spaced correctly
dotnet_diagnostic.SA1000.severity = silent
# Commas should be spaced correctly
dotnet_diagnostic.SA1001.severity = silent
# Semicolons should be spaced correctly
dotnet_diagnostic.SA1002.severity = silent
# Symbols should be spaced correctly
dotnet_diagnostic.SA1003.severity = silent
# Documentation lines should begin with single space
dotnet_diagnostic.SA1004.severity = silent
# Single line comments should begin with single space
dotnet_diagnostic.SA1005.severity = silent
# Preprocessor keywords should not be preceded by space
dotnet_diagnostic.SA1006.severity = silent # SA1006PreprocessorKeywordsMustNotBePrecededBySpace very slow
# Opening parenthesis should be spaced correctly
dotnet_diagnostic.SA1008.severity = silent
# Closing parenthesis should be spaced correctly
dotnet_diagnostic.SA1009.severity = silent
# Opening square brackets should be spaced correctly
dotnet_diagnostic.SA1010.severity = silent
# Closing square brackets should be spaced correctly
dotnet_diagnostic.SA1011.severity = silent
# Opening braces should be spaced correctly
dotnet_diagnostic.SA1012.severity = silent
# Closing braces should be spaced correctly
dotnet_diagnostic.SA1013.severity = silent
# Closing generic bracket should be followed by a space
dotnet_diagnostic.SA1015.severity = silent
# Member access symbols should be spaced correctly
dotnet_diagnostic.SA1019.severity = error
# Increment decrement symbols should be spaced correctly
dotnet_diagnostic.SA1020.severity = silent # SA1020IncrementDecrementSymbolsMustBeSpacedCorrectly very slow
# Negative signs should be spaced correctly
dotnet_diagnostic.SA1021.severity = silent
# Dereference and access of symbols should be spaced correctly
dotnet_diagnostic.SA1023.severity = silent
# Colons should be spaced correctly
dotnet_diagnostic.SA1024.severity = silent
# Code should not contain multiple whitespace in a row
dotnet_diagnostic.SA1025.severity = silent
# Use tabs correctly
dotnet_diagnostic.SA1027.severity = silent
# Code should not contain trailing whitespace
dotnet_diagnostic.SA1028.severity = error
## StyleCop readability rules
# Do not prefix calls with base unless local implementation exists
dotnet_diagnostic.SA1100.severity = error
# Prefix local calls with this
dotnet_diagnostic.SA1101.severity = silent
# Code should not contain multiple statements on one line
dotnet_diagnostic.SA1107.severity = silent
# Block statements should not contain embedded comments
dotnet_diagnostic.SA1108.severity = silent
# Opening parenthesis or bracket should be on declaration line
dotnet_diagnostic.SA1110.severity = silent
# Closing parenthesis should be on line of last parameter
dotnet_diagnostic.SA1111.severity = silent
# Parameter list should follow declaration
dotnet_diagnostic.SA1114.severity = silent
# Split parameters should start on line after declaration
dotnet_diagnostic.SA1116.severity = silent
# Parameters should be on same line or separate lines
dotnet_diagnostic.SA1117.severity = silent
# Parameter should not span multiple lines
dotnet_diagnostic.SA1118.severity = silent
# Comments should contain text
dotnet_diagnostic.SA1120.severity = warning
# Use built-in type alias
dotnet_diagnostic.SA1121.severity = silent # SA1121UseBuiltInTypeAlias very slow
# Use string.Empty for empty strings
dotnet_diagnostic.SA1122.severity = silent
# Generic type constraints should be on their own line
dotnet_diagnostic.SA1127.severity = silent
# Put constructor initializers on their own line
dotnet_diagnostic.SA1128.severity = silent
# Do not use default value type constructor
dotnet_diagnostic.SA1129.severity = error
# Use readable conditions
dotnet_diagnostic.SA1131.severity = silent
# Do not combine fields
dotnet_diagnostic.SA1132.severity = silent
# Do not combine attributes
dotnet_diagnostic.SA1133.severity = error
# Attributes should not share line
dotnet_diagnostic.SA1134.severity = silent
# Enum values should be on separate lines
dotnet_diagnostic.SA1136.severity = silent
# Elements should have the same indentation
dotnet_diagnostic.SA1137.severity = warning
## StyleCop ordering rules
# Elements should appear in the correct order
dotnet_diagnostic.SA1201.severity = silent
# Elements should be ordered by access
dotnet_diagnostic.SA1202.severity = silent
# Constants should appear before fields
dotnet_diagnostic.SA1203.severity = silent
# Static elements should appear before instance elements
dotnet_diagnostic.SA1204.severity = silent
# Partial elements should declare an access modifier
dotnet_diagnostic.SA1205.severity = error
# System using directives should be placed before other using directives
dotnet_diagnostic.SA1208.severity = error
# Using directives should be ordered alphabetically by namespace
dotnet_diagnostic.SA1210.severity = silent
# Using alias directives should be ordered alphabetically by alias name
dotnet_diagnostic.SA1211.severity = error
# Readonly fields should appear before non-readonly fields
dotnet_diagnostic.SA1214.severity = silent
## StyleCop naming rules
# Element should begin with upper-case letter
dotnet_diagnostic.SA1300.severity = silent
# Interface names should begin with I
dotnet_diagnostic.SA1302.severity = silent
# Const field names should begin with upper-case letter
dotnet_diagnostic.SA1303.severity = silent
# Non-private readonly fields should begin with upper-case letter
dotnet_diagnostic.SA1304.severity = silent
# Field names should begin with lower-case letter
dotnet_diagnostic.SA1306.severity = silent
# Accessible fields should begin with upper-case letter
dotnet_diagnostic.SA1307.severity = silent
# Variable names should not be prefixed
dotnet_diagnostic.SA1308.severity = silent
# Field names should not begin with underscore
dotnet_diagnostic.SA1309.severity = silent
# Field names should not contain underscore
dotnet_diagnostic.SA1310.severity = silent
# Static readonly fields should begin with upper-case letter
dotnet_diagnostic.SA1311.severity = silent
# Variable names should begin with lower-case letter
dotnet_diagnostic.SA1312.severity = silent
# Parameter names should begin with lower-case letter
dotnet_diagnostic.SA1313.severity = silent
## StyleCop maintainability rules
# Statement should not use unnecessary parenthesis # I put this rule in this section because the defaults put it here.
dotnet_diagnostic.SA1119.severity = silent
# Access modifier should be declared
dotnet_diagnostic.SA1400.severity = error
# Fields should be private
dotnet_diagnostic.SA1401.severity = silent
# File may only contain a single type
dotnet_diagnostic.SA1402.severity = silent
# Debug.Assert should provide message text
dotnet_diagnostic.SA1405.severity = silent
# Arithmetic expressions should declare precedence
dotnet_diagnostic.SA1407.severity = silent
# Conditional expressions should declare precedence
dotnet_diagnostic.SA1408.severity = silent
# Use trailing comma in multi-line initializers
dotnet_diagnostic.SA1413.severity = warning
## StyleCop layout rules
# Braces for multi-line statements should not share line
dotnet_diagnostic.SA1500.severity = silent
# Statement should not be on a single line
dotnet_diagnostic.SA1501.severity = silent
# Element should not be on a single line
dotnet_diagnostic.SA1502.severity = silent
# Braces should not be omitted
dotnet_diagnostic.SA1503.severity = silent
# Opening braces should not be followed by blank line
dotnet_diagnostic.SA1505.severity = silent
# Element documentation headers should not be followed by blank line
dotnet_diagnostic.SA1506.severity = warning
# Code should not contain multiple blank lines in a row
dotnet_diagnostic.SA1507.severity = silent
# Closing braces should not be preceded by blank line
dotnet_diagnostic.SA1508.severity = warning
# Opening braces should not be preceded by blank line
dotnet_diagnostic.SA1509.severity = silent
# Chained statement blocks should not be preceded by blank line
dotnet_diagnostic.SA1510.severity = silent
# Single-line comments should not be followed by blank line
dotnet_diagnostic.SA1512.severity = silent
# Closing brace should be followed by blank line
dotnet_diagnostic.SA1513.severity = silent
# Element documentation header should be preceded by blank line
dotnet_diagnostic.SA1514.severity = warning
# Single-line comment should be preceded by blank line
dotnet_diagnostic.SA1515.severity = silent
# Elements should be separated by blank line
dotnet_diagnostic.SA1516.severity = silent
# Code should not contain blank lines at start of file
dotnet_diagnostic.SA1517.severity = warning
# Use line endings correctly at end of file
dotnet_diagnostic.SA1518.severity = silent
# Braces should not be omitted from multi-line child statement
dotnet_diagnostic.SA1519.severity = silent
# Use braces consistently
dotnet_diagnostic.SA1520.severity = silent
## StyleCop documentation rules
# Element documentation should have summary text
dotnet_diagnostic.SA1606.severity = silent
# Property documentation should have value text
dotnet_diagnostic.SA1610.severity = silent
# Element parameter documentation should match element parameters
dotnet_diagnostic.SA1612.severity = silent
# Element parameter documentation should have text
dotnet_diagnostic.SA1614.severity = warning
# Element return value documentation should have text
dotnet_diagnostic.SA1616.severity = warning
# Generic type parameter documentation should have text
dotnet_diagnostic.SA1622.severity = warning
# Property summary documentation should match accessors
dotnet_diagnostic.SA1623.severity = silent
# Element documentation should not be copied and pasted
dotnet_diagnostic.SA1625.severity = silent
# Documentation text should not be empty
dotnet_diagnostic.SA1627.severity = silent
# Documentation text should end with a period
dotnet_diagnostic.SA1629.severity = silent
# File should have header
dotnet_diagnostic.SA1633.severity = silent
# Constructor summary documentation should begin with standard text
dotnet_diagnostic.SA1642.severity = silent
# File name should match first type name
dotnet_diagnostic.SA1649.severity = silent

View File

@ -1,26 +0,0 @@
{
"$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/1.2.0-beta.435/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
"settings": {
"documentationRules": {
"documentExposedElements": false,
"documentInterfaces": false,
"documentInternalElements": false
},
"indentation": {
"useTabs": true
},
"layoutRules": {
"allowConsecutiveUsings": false,
"newlineAtEndOfFile": "require"
},
"maintainabilityRules": {
"topLevelTypes": []
},
"namingRules": {
"allowedHungarianPrefixes": [ "dx", "dy", "k", "sa" ]
},
"orderingRules": {
"usingDirectivesPlacement": "outsideNamespace"
}
}
}

25
.vscode/launch.json vendored
View File

@ -1,25 +0,0 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": ".NET Launch (console)",
"type": "clr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/output/EmuHawk.exe",
"args": [],
"cwd": "${workspaceFolder}/output",
"console": "externalTerminal",
"stopAtEntry": false
},
{
"name": ".NET Attach",
"type": "clr",
"request": "attach",
"processId": "${command:pickProcess}"
}
]
}

View File

@ -1,7 +0,0 @@
{
"editor.insertSpaces": false,
"editor.tabSize": 4,
"search.exclude": {
"waterbox/**": true
}
}

24
.vscode/tasks.json vendored
View File

@ -1,24 +0,0 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "shell",
"args": [
"build",
// Ask dotnet build to generate full paths for file names.
"/property:GenerateFullPaths=true",
// Do not generate summary otherwise it leads to duplicate errors in Problems panel
"/consoleloggerparameters:NoSummary"
],
"group": "build",
"presentation": {
"reveal": "silent"
},
"problemMatcher": "$msCompile"
}
]
}

View File

@ -1,35 +0,0 @@
#!/bin/sh
cd "$(dirname "$(realpath "$0")")"
libpath=""
if [ "$(command -v lsb_release)" ]; then
case "$(lsb_release -i | head -n1 | cut -c17- | tr A-Z a-z)" in
"arch"|"artix"|"manjarolinux") libpath="/usr/lib";;
"fedora"|"gentoo"|"nobaralinux"|"opensuse") libpath="/usr/lib64";;
"nixos") libpath="/usr/lib"; printf "Running on NixOS? Why aren't you using the Nix expr?\n";;
"debian"|"linuxmint"|"pop"|"ubuntu") libpath="/usr/lib/x86_64-linux-gnu";;
esac
else
printf "Distro does not provide LSB release info API! (You've met with a terrible fate, haven't you?)\n"
fi
if [ -z "$libpath" ]; then
printf "%s\n" "Unknown distro, assuming system-wide libraries are in /usr/lib..."
libpath="/usr/lib"
fi
export LD_LIBRARY_PATH="$PWD/dll:$PWD:$libpath"
export MONO_CRASH_NOFILE=1
export MONO_WINFORMS_XIM_STYLE=disabled # see https://bugzilla.xamarin.com/show_bug.cgi?id=28047#c9
if [ "$1" = "--mono-no-redirect" ]; then
# printf "(passing --mono-no-redirect is no longer necessary)\n" #TODO uncomment later
shift
fi
if (ps -C "mono" -o "cmd" --no-headers | grep -Fq "EmuHawk.exe"); then
printf "(it seems EmuHawk is already running, NOT capturing output)\n" >&2
exec mono EmuHawk.exe "$@"
fi
o="$(mktemp -u)"
e="$(mktemp -u)"
mkfifo "$o" "$e"
printf "(capturing output in %s/EmuHawkMono_last*.txt)\n" "$PWD" >&2
tee EmuHawkMono_laststdout.txt <"$o" &
tee EmuHawkMono_laststderr.txt <"$e" | sed "s/.*/$(tput setaf 1)&$(tput sgr0)/" >&2 &
exec mono EmuHawk.exe "$@" >"$o" 2>"$e"

View File

@ -1,702 +0,0 @@
-- feos, 2025
-- CONSTANTS
local NULL_OBJECT = 0x88888888 -- no object at that index
local OUT_OF_BOUNDS = 0xFFFFFFFF -- no such index
local MINIMAL_ZOOM = 0.0001 -- ???
local ZOOM_FACTOR = 0.02
local PAN_FACTOR = 10
local CHAR_WIDTH = 10
local CHAR_HEIGHT = 16
local NEGATIVE_MAXIMUM = 1 << 63
local POSITIVE_MAXIMUM = ~NEGATIVE_MAXIMUM
-- sizes in bytes
local SHORT = 2
local INT = 4
local POINTER = 8
local LINE_SIZE = 256 -- sizeof(line_t) is 232, but we padded it for niceness
local MOBJ_SIZE = 512 -- sizeof(mobj_t) is 464, but we padded it for niceness
-- shortcuts
local rl = memory.read_u32_le
local rw = memory.read_u16_le
local rb = memory.read_u8_le
local rls = memory.read_s32_le
local rws = memory.read_s16_le
local rbs = memory.read_s8_le
local text = gui.text
local box = gui.drawBox
local line = gui.drawLine
--local text = gui.pixelText -- INSANELY SLOW
-- TOP LEVEL VARIABLES
local Zoom = 1
local LastSize = 0
local Init = true
-- tables
-- view offset
local Pan = {
x = 0,
y = 0
}
-- object positions bounds
local OB = {
top = POSITIVE_MAXIMUM,
left = POSITIVE_MAXIMUM,
bottom = NEGATIVE_MAXIMUM,
right = NEGATIVE_MAXIMUM
}
local LastScreenSize = {
w = client.screenwidth(),
h = client.screenheight()
}
-- forward declarations
local Offsets = {} -- mobj member offsets in bytes
local MobjType = {}
local SpriteNumber = {}
local Objects = {}
--gui.defaultPixelFont("fceux")
gui.use_surface("client")
local function mapify_x(coord)
return math.floor(((coord / 0xffff)+Pan.x)*Zoom)
end
local function mapify_y(coord)
return math.floor(((coord / 0xffff)+Pan.y)*Zoom)
end
local function in_range(var, minimum, maximum)
return var >= minimum and var <= maximum
end
local function reset_view()
Init = true
update_zoom()
end
local function zoom_out()
local newZoom = Zoom * (1 - ZOOM_FACTOR)
if newZoom < MINIMAL_ZOOM then return end
Zoom = newZoom
end
local function zoom_in()
Zoom = Zoom * (1 + ZOOM_FACTOR)
end
local function pan_left()
Pan.x = Pan.x + PAN_FACTOR/Zoom/2
end
local function pan_right()
Pan.x = Pan.x - PAN_FACTOR/Zoom/2
end
local function pan_up()
Pan.y = Pan.y + PAN_FACTOR/Zoom/2
end
local function pan_down()
Pan.y = Pan.y - PAN_FACTOR/Zoom/2
end
local function add_offset(size, name)
Offsets[name] = LastSize
-- print(name, string.format("%X \t\t %X", size, LastSize))
LastSize = size + LastSize
end
function maybe_swap(left, right)
if left > right then
local smallest = right
right = left
left = smallest
end
end
local function get_line_count(str)
local lines = 1
local longest = 0
local size = 0
for i = 1, #str do
local c = str:sub(i, i)
if c == '\n' then
lines = lines + 1
if size > longest then
longest = size
size = -1
end
end
size = size + 1
end
if size > longest then longest = size end
return lines, longest
end
local function iterate()
if Init then return end
for _, addr in ipairs(Objects) do
local x = rls(addr + Offsets.x)
local y = rls(addr + Offsets.y) * -1
local health = rls(addr + Offsets.health)
local radius = math.floor((rls(addr + Offsets.radius) >> 16) * Zoom)
local sprite = SpriteNumber[rls(addr + Offsets.sprite)]
local type = rl(addr + Offsets.type)
local pos = { x = mapify_x(x), y = mapify_y(y) }
local color = "white"
if type == 0
then type = "PLAYER" print("PLAYER")
else type = MobjType[type]
end
if health <= 0 then color = "red" end
--[[--
local z = rls(addr + Offsets.z) / 0xffff
local index = rl (addr + Offsets.index)
local tics = rl (addr + Offsets.tics)
--]]--
if in_range(pos.x, 0, client.screenwidth())
and in_range(pos.y, 0, client.screenheight())
then
text(pos.x, pos.y, string.format("%s", type), color)
box(pos.x - radius, pos.y - radius, pos.x + radius, pos.y + radius, color)
end
end
for i = 0, 100000 do
local addr = i * LINE_SIZE
if addr > 0xFFFFFF then break end
local id = rl(addr, "Lines") & 0xFFFFFFFF
if id == OUT_OF_BOUNDS then break end
if id ~= NULL_OBJECT then
local vertices_offset = 0xe8
local v1 = { x = rls(addr+vertices_offset , "Lines"),
y = -rls(addr+vertices_offset+ 4, "Lines") }
local v2 = { x = rls(addr+vertices_offset+ 8, "Lines"),
y = -rls(addr+vertices_offset+12, "Lines") }
line(
mapify_x(v1.x),
mapify_y(v1.y),
mapify_x(v2.x),
mapify_y(v2.y),
0xffcccccc)
end
end
end
local function init_objects()
for i = 0, 100000 do
local addr = i * MOBJ_SIZE
if addr > 0xFFFFFF then break end
local thinker = rl(addr) & 0xFFFFFFFF -- just to check if mobj is there
if thinker == OUT_OF_BOUNDS then break end
if thinker ~= NULL_OBJECT then
local x = rls(addr + Offsets.x) / 0xffff
local y = rls(addr + Offsets.y) / 0xffff * -1
local type = rl (addr + Offsets.type)
if type == 0
then type = "PLAYER" print("PLAYER")
else type = MobjType[type]
end
-- print(string.format("%d %f %f %02X", index, x, y, type))
if type
and not string.find(type, "MISC")
then
if x < OB.left then OB.left = x end
if x > OB.right then OB.right = x end
if y < OB.top then OB.top = y end
if y > OB.bottom then OB.bottom = y end
-- cache the Objects we need
table.insert(Objects, addr)
end
end
end
end
function update_zoom()
if not Init
and LastScreenSize.w == client.screenwidth()
and LastScreenSize.h == client.screenheight()
then return end
if OB.top ~= POSITIVE_MAXIMUM
and OB.left ~= POSITIVE_MAXIMUM
and OB.right ~= NEGATIVE_MAXIMUM
and OB.bottom ~= NEGATIVE_MAXIMUM
and not emu.islagged()
then
maybe_swap(OB.right, OB.left)
maybe_swap(OB.top, OB.bottom)
local span = { x = OB.right-OB.left+200, y = OB.bottom-OB.top+200 }
local scale = { x = client.screenwidth()/span.x, y = client.screenheight()/span.y }
local spanCenter = { x = OB.left+span.x/2, y = OB.top+span.y/2 }
Zoom = math.min(scale.x, scale.y)
local sreenCenter = { x = client.screenwidth()/Zoom/2, y = client.screenheight()/Zoom/2 }
Pan.x = -math.floor(spanCenter.x - sreenCenter.x)
Pan.y = -math.floor(spanCenter.y - sreenCenter.y)
Init = false
end
end
local function make_button(x, y, name, func)
local boxWidth = CHAR_WIDTH
local boxHeight = CHAR_HEIGHT
local lineCount, longest = get_line_count(name)
local textWidth = longest *CHAR_WIDTH
local textHeight = lineCount*CHAR_HEIGHT
local colors = { 0x66bbddff, 0xaabbddff, 0xaa88aaff }
local colorIndex = 1
if textWidth + 10 > boxWidth then boxWidth = textWidth + 10 end
if textHeight + 10 > boxHeight then boxHeight = textHeight + 10 end
local textX = x + boxWidth /2 - textWidth /2
local textY = y + boxHeight/2 - textHeight/2 - boxHeight
local mouse = input.getmouse()
local mousePos = client.transformPoint(mouse.X, mouse.Y)
if in_range(mousePos.x, x, x+boxWidth)
and in_range(mousePos.y, y-boxHeight, y ) then
if mouse.Left then
colorIndex = 3
func()
else colorIndex = 2 end
end
box(x, y, x+boxWidth, y-boxHeight, 0xaaffffff, colors[colorIndex])
text(textX, textY, name, colors[colorIndex] | 0xff000000) -- full alpha
end
--[[--
thinker 30 0
x 4 30
y 4 34
z 4 38
snext 8 3C
sprev 8 44
angle 4 4C
sprite 4 50
frame 4 54
bnext 8 58
bprev 8 60
subsector 8 68
floorz 4 70
ceilingz 4 74
dropoffz 4 78
radius 4 7C
height 4 80
momx 4 84
momy 4 88
momz 4 8C
validcount 4 90
type 4 94
info 8 98
tics 4 A0
state 8 A4
flags 8 AC
intflags 4 B4
health 4 B8
movedir 2 BC
movecount 2 BE
strafecount 2 C0
target 8 C2
reactiontime 2 CA
threshold 2 CC
pursuecount 2 CE
gear 2 D0
player 8 D2
lastlook 2 DA
spawnpoint 3A DC
tracer 8 116
lastenemy 8 11E
friction 4 126
movefactor 4 12A
touching_sectorlist 8 12E
PrevX 4 136
PrevY 4 13A
PrevZ 4 13E
pitch 4 142
index 4 146
patch_width 2 14A
iden_nums 4 14C
--]]--
add_offset(48, "thinker")
add_offset(INT, "x")
add_offset(INT, "y")
add_offset(INT, "z")
add_offset(INT, "padding1")
add_offset(POINTER, "snext")
add_offset(POINTER, "sprev")
add_offset(INT, "angle")
add_offset(INT, "sprite")
add_offset(INT, "frame")
add_offset(INT, "padding2")
add_offset(POINTER, "bnext")
add_offset(POINTER, "bprev")
add_offset(POINTER, "subsector")
add_offset(INT, "floorz")
add_offset(INT, "ceilingz")
add_offset(INT, "dropoffz")
add_offset(INT, "radius")
add_offset(INT, "height")
add_offset(INT, "momx")
add_offset(INT, "momy")
add_offset(INT, "momz")
add_offset(INT, "validcount")
add_offset(INT, "type")
add_offset(POINTER, "info")
add_offset(INT, "tics")
add_offset(INT, "padding3")
add_offset(POINTER, "state")
add_offset(8, "flags")
add_offset(INT, "intflags")
add_offset(INT, "health")
add_offset(SHORT, "movedir")
add_offset(SHORT, "movecount")
add_offset(SHORT, "strafecount")
add_offset(SHORT, "padding4")
add_offset(POINTER, "target")
add_offset(SHORT, "reactiontime")
add_offset(SHORT, "threshold")
add_offset(SHORT, "pursuecount")
add_offset(SHORT, "gear")
add_offset(POINTER, "player")
add_offset(SHORT, "lastlook")
add_offset(58, "spawnpoint")
add_offset(INT, "padding5") -- unsure where this one should be exactly
add_offset(POINTER, "tracer")
add_offset(POINTER, "lastenemy")
add_offset(INT, "friction")
add_offset(INT, "movefactor")
add_offset(POINTER, "touching_sectorlist")
add_offset(INT, "PrevX")
add_offset(INT, "PrevY")
add_offset(INT, "PrevZ")
add_offset(INT, "pitch")
add_offset(INT, "index")
add_offset(SHORT, "patch_width")
add_offset(INT, "iden_nums")
-- the rest are non-doom
-- print(Offsets)
MobjType = {
-- "NULL" = -1,
-- "ZERO",
-- "PLAYER = ZERO",
"POSSESSED",
"SHOTGUY",
"VILE",
"FIRE",
"UNDEAD",
"TRACER",
"SMOKE",
"FATSO",
"FATSHOT",
"CHAINGUY",
"TROOP",
"SERGEANT",
"SHADOWS",
"HEAD",
"BRUISER",
"BRUISERSHOT",
"KNIGHT",
"SKULL",
"SPIDER",
"BABY",
"CYBORG",
"PAIN",
"WOLFSS",
"KEEN",
"BOSSBRAIN",
"BOSSSPIT",
"BOSSTARGET",
"SPAWNSHOT",
"SPAWNFIRE",
"BARREL",
"TROOPSHOT",
"HEADSHOT",
"ROCKET",
"PLASMA",
"BFG",
"ARACHPLAZ",
"PUFF",
"BLOOD",
"TFOG",
"IFOG",
"TELEPORTMAN",
"EXTRABFG",
"MISC0",
"MISC1",
"MISC2",
"MISC3",
"MISC4",
"MISC5",
"MISC6",
"MISC7",
"MISC8",
"MISC9",
"MISC10",
"MISC11",
"MISC12",
"INV",
"MISC13",
"INS",
"MISC14",
"MISC15",
"MISC16",
"MEGA",
"CLIP",
"MISC17",
"MISC18",
"MISC19",
"MISC20",
"MISC21",
"MISC22",
"MISC23",
"MISC24",
"MISC25",
"CHAINGUN",
"MISC26",
"MISC27",
"MISC28",
"SHOTGUN",
"SUPERSHOTGUN",
"MISC29",
"MISC30",
"MISC31",
"MISC32",
"MISC33",
"MISC34",
"MISC35",
"MISC36",
"MISC37",
"MISC38",
"MISC39",
"MISC40",
"MISC41",
"MISC42",
"MISC43",
"MISC44",
"MISC45",
"MISC46",
"MISC47",
"MISC48",
"MISC49",
"MISC50",
"MISC51",
"MISC52",
"MISC53",
"MISC54",
"MISC55",
"MISC56",
"MISC57",
"MISC58",
"MISC59",
"MISC60",
"MISC61",
"MISC62",
"MISC63",
"MISC64",
"MISC65",
"MISC66",
"MISC67",
"MISC68",
"MISC69",
"MISC70",
"MISC71",
"MISC72",
"MISC73",
"MISC74",
"MISC75",
"MISC76",
"MISC77",
"MISC78",
"MISC79",
"MISC80",
"MISC81",
"MISC82",
"MISC83",
"MISC84",
"MISC85",
"MISC86",
"PUSH",
"PULL",
"DOGS",
"PLASMA1",
"PLASMA2"
}
SpriteNumber = {
-- "TROO",
"SHTG",
"PUNG",
"PISG",
"PISF",
"SHTF",
"SHT2",
"CHGG",
"CHGF",
"MISG",
"MISF",
"SAWG",
"PLSG",
"PLSF",
"BFGG",
"BFGF",
"BLUD",
"PUFF",
"BAL1",
"BAL2",
"PLSS",
"PLSE",
"MISL",
"BFS1",
"BFE1",
"BFE2",
"TFOG",
"IFOG",
"PLAY",
"POSS",
"SPOS",
"VILE",
"FIRE",
"FATB",
"FBXP",
"SKEL",
"MANF",
"FATT",
"CPOS",
"SARG",
"HEAD",
"BAL7",
"BOSS",
"BOS2",
"SKUL",
"SPID",
"BSPI",
"APLS",
"APBX",
"CYBR",
"PAIN",
"SSWV",
"KEEN",
"BBRN",
"BOSF",
"ARM1",
"ARM2",
"BAR1",
"BEXP",
"FCAN",
"BON1",
"BON2",
"BKEY",
"RKEY",
"YKEY",
"BSKU",
"RSKU",
"YSKU",
"STIM",
"MEDI",
"SOUL",
"PINV",
"PSTR",
"PINS",
"MEGA",
"SUIT",
"PMAP",
"PVIS",
"CLIP",
"AMMO",
"ROCK",
"BROK",
"CELL",
"CELP",
"SHEL",
"SBOX",
"BPAK",
"BFUG",
"MGUN",
"CSAW",
"LAUN",
"PLAS",
"SHOT",
"SGN2",
"COLU",
"SMT2",
"GOR1",
"POL2",
"POL5",
"POL4",
"POL3",
"POL1",
"POL6",
"GOR2",
"GOR3",
"GOR4",
"GOR5",
"SMIT",
"COL1",
"COL2",
"COL3",
"COL4",
"CAND",
"CBRA",
"COL6",
"TRE1",
"TRE2",
"ELEC",
"CEYE",
"FSKU",
"COL5",
"TBLU",
"TGRN",
"TRED",
"SMBT",
"SMGT",
"SMRT",
"HDB1",
"HDB2",
"HDB3",
"HDB4",
"HDB5",
"HDB6",
"POB1",
"POB2",
"BRS1",
"TLMP",
"TLP2",
"TNT1",
"DOGS",
"PLS1",
"PLS2",
"BON3",
"BON4",
"BLD2"
}
while true do
if Init then init_objects() end
iterate()
update_zoom()
make_button( 10, client.screenheight()-70, "Zoom\nIn", zoom_in )
make_button( 10, client.screenheight()-10, "Zoom\nOut", zoom_out )
make_button( 80, client.screenheight()-40, "Pan\nLeft", pan_left )
make_button(150, client.screenheight()-70, "Pan \nUp", pan_up )
make_button(150, client.screenheight()-10, "Pan\nDown", pan_down )
make_button(220, client.screenheight()-40, "Pan\nRight", pan_right )
make_button(300, client.screenheight()-10, "Reset\nView", reset_view)
text(10, client.screenheight()-170, string.format(
"Zoom: %.4f\nPanX: %s\nPanY: %s",
Zoom, Pan.x, Pan.y), 0xffbbddff)
LastScreenSize.w = client.screenwidth()
LastScreenSize.h = client.screenheight()
emu.frameadvance()
end

View File

@ -1,32 +0,0 @@
-- feos, 2019
local offX, offY, camX, camY
local addr_offX = 0x5B96
local addr_offY = 0x5B98
local addr_camX = 0x59D0
local addr_camY = 0x59D2
while true do
client.invisibleemulation(true)
local memorystate = memorysavestate.savecorestate()
offX = mainmemory.read_u16_le(addr_offX)
offY = mainmemory.read_u16_le(addr_offY)
camX = mainmemory.read_u16_le(addr_camX)
camY = mainmemory.read_u16_le(addr_camY)
Xval = camX + offX - 128
Yval = camY + offY - 80
mainmemory.write_u16_le(addr_camX, Xval)
mainmemory.write_u16_le(addr_camY, Yval)
client.seekframe(emu.framecount()+1)
client.invisibleemulation(false)
client.seekframe(emu.framecount()+1)
client.invisibleemulation(true)
memorysavestate.loadcorestate(memorystate)
memorysavestate.removestate(memorystate)
-- client.invisibleemulation(false)
emu.frameadvance()
end

View File

@ -26,8 +26,9 @@ local rl = memory.read_u32_be
local box = gui.drawBox
local text = gui.pixelText
local line = gui.drawLine
memory.usememorydomain("68K RAM")
local AND = bit.band
local SHIFTL = bit.lshift
local SHIFTR = bit.rshift
event.onframestart(function()
rngcount = 0
@ -57,7 +58,7 @@ local function PostRngRoll(object,x,y)
for i = 1, #MsgTable do
if (MsgTable[i]) then
if object==MsgTable[i].object_ then
local color = 0x00ff0000+((MsgTable[i].timer_-emu.framecount())*MsgStep << 24)
local color = 0x00ff0000+SHIFTL((MsgTable[i].timer_-emu.framecount())*MsgStep,24)
line(130,7*i+8,x,y,color)
text(120,7*i+8,string.format("%X",MsgTable[i].routine_),color)
end
@ -127,34 +128,34 @@ end
local function GetFloor(x, y)
if drawfloor==0 then return {0,0} end
x = x*16+(camx & 0xfff0)
y = y*16+(camy & 0xfff0)
local d6 = (y & 0xfff0) >> 3
x = x*16+AND(camx,0xfff0)
y = y*16+AND(camy,0xfff0)
local d6 = SHIFTR(AND(y,0xfff0),3)
local a0 = rw(d6+0xb4e8)
local d0 = x+0x10 >> 4
local d2 = x & 0xf
local d0 = SHIFTR(x+0x10,4)
local d2 = AND(x,0xf)
local a1 = 0xb806+rw(0xfb9e)
local a2 = 0x273e1e
local d3 = rw(a0+d0*2) >> 1
local d3 = SHIFTR(rw(a0+d0*2),1)
local temp = a1+d3
if temp>0xffff then return {0,0} end
local d5 = (rb(temp) << 4)+d2
local newd5 = (rb(a1+d3) << 4)+d2+15
local newd0 = rb(a2+newd5,"MD CART") & 0x1f
return { rb(a2+d5,"MD CART") & 0x1f, newd0 }
local d5 = SHIFTL(rb(temp),4)+d2
local newd5 = SHIFTL(rb(a1+d3),4)+d2+15
local newd0 = AND(rb(a2+newd5,"MD CART"),0x1f)
return {AND(rb(a2+d5,"MD CART"),0x1f), newd0}
end
local function GetWall(x, y)
if drawwalls==0 then return 0 end
x = x*16+(camx & 0xfff0)
y = y*16+(camy & 0xfff0)
x = x*16+AND(camx,0xfff0)
y = y*16+AND(camy,0xfff0)
if y<0 then return 0 end
local d6 = (y+6 & 0xfff0) >> 3
local d6 = SHIFTR(AND(y+6,0xfff0),3)
local a0 = rw(d6+0xb4e6)
local temp = a0+(x >> 4)*2
local temp = a0+SHIFTR(x,4)*2
if temp>0xffff then return 0 end
local d0 = rw(temp)
temp = 0xb808+(d0 >> 1)
temp = 0xb808+SHIFTR(d0,1)
if temp>0xffff then return 0 end
return rb(temp)
end
@ -165,10 +166,10 @@ local function DrawBG()
for i=1,21 do
local a0 = GetWall(i,j)
if a0>0 then
x1 = i*16-(camx & 0xf)-16
y1 = j*16-(camy & 0xf)-16
x2 = i*16-(camx & 0xf)-1
y2 = j*16-(camy & 0xf)-1
x1 = i*16-AND(camx,0xf)-16
y1 = j*16-AND(camy,0xf)-16
x2 = i*16-AND(camx,0xf)-1
y2 = j*16-AND(camy,0xf)-1
if a0==255 then -- normal
box(x1,y1,x2,y2,0xff00ffff,0x4400ffff)
elseif a0==228 then -- snot
@ -201,10 +202,10 @@ local function DrawBG()
if d0>0 then
local newd0 = GetFloor(i,j)[2]
if newd0>0 then
x1 = i*16-(camx & 0xf)
y1 = j*16-(camy & 0xf)+d0
x2 = i*16-(camx & 0xf)+15
y2 = j*16-(camy & 0xf)+newd0
x1 = i*16-AND(camx,0xf)
y1 = j*16-AND(camy,0xf)+d0
x2 = i*16-AND(camx,0xf)+15
y2 = j*16-AND(camy,0xf)+newd0
else
for k=-2,2 do
newd0 = GetFloor(i+1,j+k)[1]
@ -218,10 +219,10 @@ local function DrawBG()
elseif k==2 then
add = 1
end
x1 = i*16-(camx & 0xf)
y1 = j*16-(camy & 0xf)+d0
x2 = i*16-(camx & 0xf)+16
y2 = j*16-(camy & 0xf)-newd0+k*16+add
x1 = i*16-AND(camx,0xf)
y1 = j*16-AND(camy,0xf)+d0
x2 = i*16-AND(camx,0xf)+16
y2 = j*16-AND(camy,0xf)-newd0+k*16+add
--text(x1,y2,k,"red")
end
end
@ -273,7 +274,7 @@ local function Bounce()
end
local counter = rb(0xfc87)
local a0 = 0xfc88
local d0 = (rb(a0+counter) << 5)+offset
local d0 = SHIFTL(rb(a0+counter),5)+offset
local vel = rw(0x25d482+d0, "MD CART")
if vel == 0x200 then bounce = 3
elseif vel == 0x3e0 then bounce = 1
@ -333,5 +334,4 @@ while true do
Configs()
end
emu.frameadvance()
gui.clearGraphics()
end

View File

@ -1,521 +1,448 @@
-- Gargoyles, Genesis (BizHawk)
-- feos, 2015-2017
--== Shortcuts ==--
local rb = memory.read_u8
local rw = memory.read_u16_be
local rws = memory.read_s16_be
local r24 = memory.read_u24_be
local rl = memory.read_u32_be
local box = gui.drawBox
local text = gui.text
local ptext = gui.pixelText
local line = gui.drawLine
--== RAM addresses ==--
local levnum = 0xff00ba
local LevelFlr = 0xff00c0
local LevelCon = 0xff00c4
local mapline_tab = 0xff0244
local GlobalBase = 0xff1c76
local GolBase = 0xff2c76
local MapA_Buff = 0xff4af0
--== Camera Hack ==--
local camhack = false
local div = 1 -- scale
local size = 16/div -- block size
--== Block cache ==--
local col = 0 -- block color
local opout = 0x33000000 -- outer opacity
local opin = 0x66000000 -- inner opacity
local op = 0xff000000
local cache = {}
--== Other stuff ==--
local MsgCutoff = 20
local MsgTime = 1
local MsgStep = 14
local MsgOffs = 2
local MsgTable = {}
local XposLast = 0
local YposLast = 0
local room = 0
local workinglast = 0
local wSize = client.getwindowsize()
local lagcount = emu.lagcount()
gui.defaultTextBackground(0xff000000)
--== Object types ==--
local types = {
"Goliath","Orb","Health1PLR","Health2PLR","Health1NME","Health2NME","Numeral",
"BigExplode","SmallExplode","GlassDebris","MetalDebris","WoodDebris",
"WallDebris","SignPiece","SteamVent","BreakWall","SkyLight","BreakLight",
"ThrowCrate","BreakEdgeLeft","BreakEdgeRight","Spark","Spark2","Sparks",
"Sparks2","Fireball","HomingProj1","HorzProj1","VertProj1","DirProj1",
"DirProj2","DropMine","Scratch","Icon","RaptorBot","SniperBot","SpiderBot",
"WaspBot","Xanatos","PlasmaBot","RabidHH","MorningStar","Archer","Arrow",
"Valkyrie","Axe","WeaponExp","Couldron","SpittingCouldron","FireballHead",
"FireballTrail","BigFireballHead","BigFireballTrail","Oil","OilGenerator",
"Claw","Stump","StumpBubble","StumpFire","ClawStump","StumpFireGen","Vent",
"VentSparks","Chain","FlameLick","Floor","MutVikBody","MutVikHead",
"MutVikHammer","EyeOfOdin","EyeOfOdinTrail","L1BreakWall","Catapult",
"L1BreakFloor","Gate","GateCrusher","Weight","WeightCrusher","WallFire",
"Balista","BalistaLog","PasteWall","FlameBoulder","CastlePiece",
"MutantSpiderBot","MutSpiLegs","MutSpiHead","MutSpiHeadFlame","MutSpiProj",
"MutSpiElecV","MutSpiElecH","PlasmaBall","PlasmaBallTail","PlasmaDeadHead",
"VertFlame","WallFlame","FloorFlame","OPPlatform","OPLink","OPOrb",
"Furnace","RobotGenerator","RockGenerator","BigRock","MediumRock",
"SmallRock","BigCouldronGen","BigCouldron","Trough","TroughGen","Energizer",
"Demona","TrajectoryProj","WallPaste","EdgePaste","Tentacle","Infuser",
"BigGuns","BigGunsProj","HighSignPole","HighSign","LowLight","L5Skylight",
"L5Wall","ElecGenerator","Electricity","WaspGenerator","TunnelEdge",
"ForegroundPost","Sorcerer","LightningTop","LightningBot","MDemonaWallFire",
"MDemonaFloorFire","EyeRooftopUp","EyeRooftopDn","EyeRaptor"
}
local function RoomTime()
local start11 = 894--767
local start12 = 2294
local start13 = 5468 -- 4254 -- 4101
local startl4 = 5506
local startl5 = 7117
local startl6 = 8412
local startl7 = 17117
local timer = emu.framecount()
if timer < start11 then room = timer
elseif timer < start12 then room = timer - start11
elseif timer < start13 then room = timer - start12
elseif timer < startl4 then room = timer - start13
elseif timer < startl5 then room = timer - startl4
elseif timer < startl6 then room = timer - startl5
elseif timer < startl7 then room = timer - startl6
end
text(2, 2, string.format("cx:%5d\ncy:%5d\nroom:%d", camx, camy, room), "white", "bottomright")
end
local function HUD()
--if working > 0 then return end
local rndcol = "white"
if rndlast ~= rnd1 then rndcol = "red" end
text(0, 2, string.format("RNG:%08X %04X", rnd1, rnd2), rndcol, "bottomleft")
text(2, 0, string.format(
"x: %4d\ny: %4d\ndx: %3d\ndy: %3d\nhp: %3d\nrun:%3d\ninv:%3d",
Xpos, Ypos, Xspd, Yspd, health, run, inv),
"white", "topright")
end
local function CamhackHUD()
if working == 0 then
-- screen edge
box((backx-camx- 1)/div,
(backy-camy- 1)/div,
(backx-camx+320)/div,
(backy-camy+224)/div,
0xff0000ff, 0)
-- map edge
box( 0-camx/div+size,
0-camy/div+size,
mapw/div-camx/div,
maph/div-camy/div,
0xff0000ff, 0)
end
if camhack or div > 1 then
text(0, 0, string.format("div:%d", div), "white", "topleft")
end
end
local function PosToIndex(x, y)
return (x // 16)+(y // 16)*xblocks
end
local function IndexToPos(i)
return { x=(i%xblocks)*16, y=(i // xblocks)*16 }
end
local function InBounds(x, minimum, maximum)
if x >= minimum and x <= maximum
then return true
else return false
end
end
local function GetBlock(x, y)
if working > 0 then return nil end
local final = { contour={}, block=0 }
if x > 0 and x < mapw
and y > 0 and y < maph then
local pixels = 0
local x1 = x/div-camx/div
local x2 = x1+size-1
local y1 = y/div-camy/div
local y2 = y1+size-1
local d4 = rw(mapline_tab+(y >> 4)*2)
local a1 = r24(LevelFlr+1)
local d1 = rw(MapA_Buff+d4+(x >> 4)*2) >> 1
final.block = rb(a1+d1+2)
d1 = rw(a1+d1)
a1 = r24(LevelCon+1)+d1
if rb(a1) > 0 or rb(a1+8) > 0 then
for pixel=0, 15 do
final.contour[pixel] = rb(a1+pixel)
end
else
final.contour = nil
end
else
return nil
end
return final
end
local DrawBlock = {
[0x80] = function(x1, y1, x2, y2) -- WALL
col = 0x00ffffff -- white
line(x1, y1, x1, y2, col+op) -- left
line(x2, y1, x2, y2, col+op) -- right
end,
[0x81] = function(x1, y1, x2, y2) -- CEILING
col = 0x00ffffff -- white
line(x1, y2, x2, y2, col+op) -- bottom
end,
[0x82] = function(x1, y1, x2, y2) -- CLIMB_U
col = 0x0000ffff -- cyan
line(x1, y2, x2, y2, col+op) -- bottom
end,
[0x83] = function(x1, y1, x2, y2) -- CLIMB_R
col = 0x0000ffff -- cyan
line(x1, y1, x1, y2, col+op) -- left
end,
[0x84] = function(x1, y1, x2, y2) -- CLIMB_L
col = 0x0000ffff -- cyan
line(x2, y1, x2, y2, col+op) -- right
end,
[0x85] = function(x1, y1, x2, y2) -- CLIMB_LR
col = 0x0000ffff -- cyan
line(x1, y1, x1, y2, col+op) -- left
line(x2, y1, x2, y2, col+op) -- right
end,
[0x86] = function(x1, y1, x2, y2) -- CLIMB_R_STAND_R
col = 0x00ffffff -- white
line(x1, y1, x2, y1, col+op) -- top
col = 0x0000ffff -- cyan
line(x1, y1, x1, y2, col+op) -- left
end,
[0x87] = function(x1, y1, x2, y2) -- CLIMB_L_STAND_L
col = 0x00ffffff -- white
line(x1, y1, x2, y1, col+op) -- top
col = 0x0000ffff -- cyan
line(x2, y1, x2, y2, col+op) -- right
end,
[0x88] = function(x1, y1, x2, y2) -- CLIMB_LR_STAND_LR
col = 0x00ffffff -- white
line(x1, y1, x2, y1, col+op) -- top
col = 0x00ff00ff -- cyan
line(x1, y1, x1, y2, col+op) -- left
col = 0x0000ffff -- cyan
line(x2, y1, x2, y2, col+op) -- right
end,
[0x70] = function(x1, y1, x2, y2) -- GRAB_SWING
col = 0x0000ff00 -- green
box(x1, y1, x2, y2, col, col+opout)
end,
[0x7f] = function(x1, y1, x2, y2) -- EXIT
col = 0x00ffff00 -- yellow
end,
[0xd0] = function(x1, y1, x2, y2) -- SPIKES
col = 0x00ff0000 -- red
box(x1, y1, x2, y2, col, col+opout)
end,
[0xd1] = function(x1, y1, x2, y2) -- SPIKES
col = 0x00ff0000 -- red
box(x1, y1, x2, y2, col, col+opout)
end
}
local function DrawBlockDefault(x1, y1, x2, y2) -- LEVEL_SPECIFIC
col = 0x00ff8800 -- orange
box(x1, y1, x2, y2, col+opin, col+opout)
end
local function DrawBG(unit, x, y)
local val= 0
local x1 = x/div-camx/div-(camx%16)/div
local x2 = x1+size-1
local y1 = y/div-camy/div-(camy%16)/div
local y2 = y1+size-1
if unit.contour ~= nil then
box(x1, y1, x2, y2, 0x5500ff00, 0x5500ff00)
for pixel=0, 15 do
val = unit.contour[pixel]
--[ [--
if val > 0 then
gui.drawPixel(
x1+pixel/div,
y1+val/div-1/div,
0xffffff00)
end
--]]--
end
end
if unit.block > 0 then
local Fn = DrawBlock[unit.block] or DrawBlockDefault
Fn(x1, y1, x2, y2)
box(x1, y1, x2, y2, col+opin, col+opout)
end
end
local function Background()
if working > 0 then
cache = {}
return
end
if camhack then
camx = Xpos-320/2*div
camy = Ypos-224/2*div
box(0, 0, 320, 240, 0, 0x66000000)
end
local border = 0
local offset = 32
local basex = camx+border
local basey = camy+border
local basei = PosToIndex(basex-offset, basey-offset)
local boundx = 320*div-border
local boundy = 224*div-border
local xblockstockeck = ((camx+boundx+offset)-(basex-offset))/size/div
local yblockstockeck = ((camy+boundy+offset)-(basey-offset))/size/div
for yblock = 0, yblockstockeck do
for xblock = 0, xblockstockeck do
local i = yblock*xblocks+xblock+basei
local x = basex+xblock*size*div
local y = basey+yblock*size*div
if InBounds(x, basex-offset, camx+boundx+offset) then
local unit = cache[i]
if unit == nil or workinglast > 0 then
if InBounds(x, basex, camx+boundx)
and InBounds(y, basey, camy+boundy)
then cache[i] = GetBlock(x, y)
end
else
if not InBounds(x, basex, camx+boundx)
and not InBounds(y, basey, camy+boundy)
then cache[i] = nil
end
end
if unit ~= nil then
DrawBG(unit, x, y)
end
elseif cache[i] ~= nil
then cache[i] = nil
end
end
end
CamhackHUD()
end
local function Clamp(v, vmin, vmax)
if v < vmin then v = vmin end
if v > vmax then v = vmax end
return v
end
local function Objects()
if working > 0 then return end
for i=0, 63 do
local base = GlobalBase+i*128
local flag2 = rb(base+0x49) & 0x10 -- active
if flag2 == 0x10 then
local xpos = rw (base+0x00)
local ypos = rw (base+0x02)
local state = rw (base+0x0c)
local dmg = rb (base+0x10)
local id = rw (base+0x40)
local hp = rw (base+0x50)
local cRAM = r24(base+0x75) -- pointer to 4 collision boxes per object
local xscr = (xpos-camx)/div
local yscr = (ypos-camy)/div
local num = id/6
local name = types[num]
local col = 0 -- collision color
for boxx=0, 4 do
local x0 = rw (cRAM+boxx*8)
local x1 = (rws(cRAM+boxx*8+0)-camx)/div
local y1 = (rws(cRAM+boxx*8+2)-camy)/div
local x2 = (rws(cRAM+boxx*8+4)-camx)/div
local y2 = (rws(cRAM+boxx*8+6)-camy)/div
if boxx == 0 then
col = 0xff00ff00 -- body
-- archer hp doesn't matter
if id == 282 or id == 258 then hp = 1 end
if hp > 0 and id > 0 and x0 ~= 0x8888 then
local xx = Clamp(xscr, 0, 318-string.len(name)*4)
local yy = Clamp(yscr, 0, 214)
ptext(xx, yy+2, string.format("%d", hp), col)
end
elseif boxx == 1 then
col = 0xffffff00 -- floor
elseif boxx == 2 then
if dmg > 0
then col = 0xffff0000 -- projectile
else col = 0xff8800ff -- item
end
if dmg > 0 then
text(x1*wSize+2, y2*wSize+1,
string.format("%d", dmg), col, 0x88000000)
end
else
col = 0xffffffff -- other
end
if x1 ~= 0x8888
and x1 <= 320 and x2 >= 0
and y1 <= 224 and y2 >= 0 then
box(x1, y1, x2, y2, col, 0)
end
end
end
end
end
local function PostRndRoll()
for i = 1,#MsgTable do
if MsgTable[i] and MsgTable[i].index == i then
local base = MsgTable[i].base
local xpos = rw(base+0x00)
local ypos = rw(base+0x02)
local id = rw(base+0x40)
local x = (xpos-camx)/div
local y = (ypos-camy)/div
local num = id/6
local ymsg = 0
local yoffs = ((i-1) // MsgCutoff)*14
local name = types[num]
local color = 0xffffff00
if base == GolBase then
name = "Goliath"
elseif not name then
name = string.format("%X", base)
color = 0xff00ffff
end
if y < 224/2 then
yoffs = -yoffs
ymsg = 210
end
x = Clamp(x, 2, 320-string.len(name)*4)
y = Clamp(y, 20, 214)
line ((i-1)%MsgCutoff*MsgStep+3 +MsgOffs, ymsg+yoffs+4, x, y, color-0x88000000)
ptext((i-1)%MsgCutoff*MsgStep*wSize+MsgOffs, ymsg+yoffs, i, color)
MsgTable[i].timer = MsgTable[i].timer-1
if MsgTable[i].timer <= 0 then
MsgTable[i] = nil
end
end
end
end
local function PlayerBoxes()
if working > 0 then return end
local xx = (Xpos-camx)/div
local yy = (Ypos-camy)/div
local col = 0xff00ffff
local swcol = col -- usual detection
if Yspd > 0 then -- gimme swings to grab!
swcol = 0xff00ff00
elseif Yspd == 0 then -- can tell that too
swcol = 0xffffffff
end
if facing == 2
then box(xx-0xf /div-2, yy-0x2c/div-1, xx-0xf/div+0, yy-0x2c/div+1, swcol, 0) -- lefttop
else box(xx+0xf /div , yy-0x2c/div-1, xx+0xf/div+2, yy-0x2c/div+1, swcol, 0) -- rightttop
end
box(xx -1, yy-0x2c/div-1, xx +1, yy-0x2c/div+1, col, 0) -- top
box(xx-0xf /div-2, yy-0x1f/div-1, xx-0xf /div+0, yy-0x1f/div+1, col, 0) -- left
box(xx+0x10/div-1, yy-0x1f/div-1, xx+0x10/div+1, yy-0x1f/div+1, col, 0) -- right
-- box(xx -1, yy-0x1f/div-1, xx +1, yy-0x1f/div+1, col, 0) -- center
box(xx -1, yy-0x0f/div-1, xx +1, yy-0x0f/div+1, col, 0) -- bottom
box(xx -1, yy -1, xx +1, yy +1,0xffffff00, 0) -- feet
-- box(xx -1, yy+0x10/div-1, xx +1, yy+0x10/div+1, col, 0) -- ground
end
local function Input()
local i, u, d, l, r, a, b, c, s
if movie.isloaded()
then i = movie.getinput(emu.framecount()-1)
else i = joypad.getimmediate()
end
if i["P1 Up" ] then u = "U" else u = " " end
if i["P1 Down" ] then d = "D" else d = " " end
if i["P1 Left" ] then l = "L" else l = " " end
if i["P1 Right"] then r = "R" else r = " " end
if i["P1 A" ] then a = "A" else a = " " end
if i["P1 B" ] then b = "B" else b = " " end
if i["P1 C" ] then c = "C" else c = " " end
if i["P1 Start"] then s = "S" else s = " " end
text(1, 10, u..d..l..r..a..b..c..s, "yellow")
end
event.onframeend(function()
emu.setislagged(rb(0xfff6d4) == 0)
if rb(0xfff6d4) == 0 then
lagcount = lagcount+1
framecol = "red"
else
framecol = "white"
end
emu.setlagcount(lagcount)
wSize = client.getwindowsize()
rndlast = rnd1
workinglast = working
XposLast = Xpos
YposLast = Ypos
end)
event.onmemoryexecute(function()
local a0 = emu.getregister("M68K A0") & 0xffffff
if a0 ~= 0xff4044 then
for i = 1, 200 do
if MsgTable[i] == nil then
MsgTable[i] = { index = i, timer = MsgTime, base = a0 }
break
end
end
end
end, 0x257A, "RNGseed")
local function main()
rnd1 = rl (0xff001c)
rnd2 = rw (0xff0020)
working = rb (0xff0073)
xblocks = rw (0xff00d4)
mapw = rw (0xff00d4)*8
maph = rw (0xff00d6)*8
Xpos = rws(0xff0106)
Ypos = rws(0xff0108)
camx = rws(0xff010c)+16
camy = rws(0xff010e)+16
run = rb (0xff1699)
inv = rw (0xff16d2)
health = rws(0xff2cc6)
backx = camx
backy = camy
Xspd = Xpos-XposLast
Yspd = Ypos-YposLast
facing = rb(GolBase+0x48) & 2 -- object flag 1
if working > 0 then MsgTable = {} end
Background()
PlayerBoxes()
Objects()
PostRndRoll()
HUD()
RoomTime()
end
while true do
main()
emu.frameadvance()
gui.clearGraphics()
-- Gargoyles, Genesis (BizHawk)
-- feos, 2015-2016
--== Shortcuts ==--
rb = memory.read_u8
rw = memory.read_u16_be
rws = memory.read_s16_be
r24 = memory.read_u24_be
rl = memory.read_u32_be
box = gui.drawBox
text = gui.pixelText
line = gui.drawLine
AND = bit.band
SHIFT = bit.rshift
--== RAM addresses ==--
levnum = 0xff00ba
LevelFlr = 0xff00c0
LevelCon = 0xff00c4
mapline_tab = 0xff0244
GlobalBase = 0xff1c76
GolBase = 0xff2c76
MapA_Buff = 0xff4af0
--== Camera Hack ==--
camhack = false
div = 1 -- scale
size = 16/div -- block size
--== Block cache ==--
col = 0 -- block color
opout = 0x33000000 -- outer opacity
opin = 0x66000000 -- inner opacity
op = 0xff000000
cache = {}
--== Other stuff ==--
XposLast = 0
YposLast = 0
room = 0
workinglast = 0
lagcount = emu.lagcount()
gui.defaultPixelFont("fceux")
function main()
rnd1 = rl (0xff001c)
rnd2 = rw (0xff0020)
working = rb (0xff0073)
xblocks = rw (0xff00d4)
mapw = rw (0xff00d4)*8
maph = rw (0xff00d6)*8
Xpos = rws(0xff0106)
Ypos = rws(0xff0108)
camx = rws(0xff010c)+16
camy = rws(0xff010e)+16
run = rb (0xff1699)
inv = rw (0xff16d2)
health = rws(0xff2cc6)
backx = camx
backy = camy
Xspd = Xpos-XposLast
Yspd = Ypos-YposLast
facing = AND(rb(GolBase+0x48),2) -- object flag 1
Background()
CamhackHUD()
Objects()
PlayerBoxes()
HUD()
RoomTime()
Input()
end
function RoomTime()
local start11 = 894--767
local start12 = 2294
local start13 = 4101
local startl4 = 6000
timer = emu.framecount()
if timer < start11 then room = timer
elseif timer < start12 then room = timer - start11
elseif timer < start13 then room = timer - start12
elseif timer < startl4 then room = timer - start13
end
text(160,214,"room cnt: "..room, "white")
end
function HUD()
text(1, 0,emu.framecount(), framecol)
text(1,20,emu.lagcount(), "red")
text(1,30,movie.rerecordcount(),"orange")
if working>0 then return end
if rndlast ~= rnd1 then rndcol = "red" else rndcol = "white" end
text( 0,214,"rnd: ","yellow")
text( 26,214,string.format("%08X %04X",rnd1,rnd2),rndcol)
text(277, 0,string.format(
"x: %4d\ny: %4d\ndx: %3d\ndy: %3d\nhp: %3d\nrun:%3d\ninv:%3d",
Xpos,Ypos,Xspd,Yspd,health,run,inv)
)
end
function CamhackHUD()
if working==0 then
-- screen edge
box((backx-camx- 1)/div,
(backy-camy- 1)/div,
(backx-camx+320)/div,
(backy-camy+224)/div,
0xff0000ff)
-- map edge
box( 0-camx/div+size,
0-camy/div+size,
mapw/div-camx/div,
maph/div-camy/div,
0xff0000ff)
end
text(260,206,string.format("cHack: %s\nscale: %d",ch,div))
end
function Background()
if working>0 then
cache = {}
return
end
if camhack then
camx = Xpos-320/2*div
camy = Ypos-224/2*div
box(0,0,320,240,0,0x66000000)
ch = "on"
else
ch = "off"
end
local border = 0
local offset = 32
local basex = camx+border
local basey = camy+border
local basei = PosToIndex(basex-offset,basey-offset)
local boundx = 320*div-border
local boundy = 224*div-border
local xblockstockeck = ((camx+boundx+offset)-(basex-offset))/size/div
local yblockstockeck = ((camy+boundy+offset)-(basey-offset))/size/div
for yblock = 0,yblockstockeck do
for xblock = 0,xblockstockeck do
local i = yblock*xblocks+xblock+basei
local x = basex+xblock*size*div
local y = basey+yblock*size*div
if InBounds(x,basex-offset,camx+boundx+offset) then
local unit = cache[i]
if unit == nil or workinglast>0 then
if InBounds(x,basex,camx+boundx)
and InBounds(y,basey,camy+boundy)
then cache[i] = GetBlock(x,y)
end
else
if not InBounds(x,basex,camx+boundx)
and not InBounds(y,basey,camy+boundy)
then cache[i] = nil
end
end
if unit ~= nil then
DrawBG(unit,x,y)
end
elseif cache[i] ~= nil
then cache[i] = nil
end
end
end
end
function DrawBG(unit, x, y)
local val= 0
local x1 = x/div-camx/div-(camx%16)/div
local x2 = x1+size-1
local y1 = y/div-camy/div-(camy%16)/div
local y2 = y1+size-1
if unit.contour ~= nil then
box(x1,y1,x2,y2,0x5500ff00,0x5500ff00)
for pixel=0,15 do
val = unit.contour[pixel]
if val>0 then
gui.drawPixel(
x1+pixel/div,
y1+val/div-1/div,
0xffffff00)
end
end
end
if unit.block>0 then
local Fn = DrawBlock[unit.block] or DrawBlockDefault
Fn(x1,y1,x2,y2)
box(x1,y1,x2,y2,col+opin,col+opout)
end
end
function GetBlock(x,y)
if working>0 then return nil end
local final = { contour={}, block=0 }
if x>0 and x<mapw
and y>0 and y<maph then
local pixels = 0
local x1 = x/div-camx/div
local x2 = x1+size-1
local y1 = y/div-camy/div
local y2 = y1+size-1
local d4 = rw(mapline_tab+SHIFT(y,4)*2)
local a1 = r24(LevelFlr+1)
local d1 = SHIFT(rw(MapA_Buff+d4+SHIFT(x,4)*2),1)
final.block = rb(a1+d1+2)
d1 = rw(a1+d1)
a1 = r24(LevelCon+1)+d1
if rb(a1)>0 or rb(a1+8)>0 then
for pixel=0,15 do
final.contour[pixel] = rb(a1+pixel)
end
else
final.contour = nil
end
else
return nil
end
return final
end
function PosToIndex(x,y)
return math.floor(x/16)+math.floor(y/16)*xblocks
end
function IndexToPos(i)
return { x=(i%xblocks)*16, y=math.floor(i/xblocks)*16 }
end
function InBounds(x,minimum,maximum)
if x>=minimum and x<=maximum
then return true
else return false
end
end
DrawBlock = {
[0x80] = function(x1,y1,x2,y2) -- WALL
col = 0x00ffffff -- white
line(x1,y1,x1,y2,col+op) -- left
line(x2,y1,x2,y2,col+op) -- right
end,
[0x81] = function(x1,y1,x2,y2) -- CEILING
col = 0x00ffffff -- white
line(x1,y2,x2,y2,col+op) -- bottom
end,
[0x82] = function(x1,y1,x2,y2) -- CLIMB_U
col = 0x0000ffff -- cyan
line(x1,y2,x2,y2,col+op) -- bottom
end,
[0x83] = function(x1,y1,x2,y2) -- CLIMB_R
col = 0x0000ffff -- cyan
line(x1,y1,x1,y2,col+op) -- left
end,
[0x84] = function(x1,y1,x2,y2) -- CLIMB_L
col = 0x0000ffff -- cyan
line(x2,y1,x2,y2,col+op) -- right
end,
[0x85] = function(x1,y1,x2,y2) -- CLIMB_LR
col = 0x0000ffff -- cyan
line(x1,y1,x1,y2,col+op) -- left
line(x2,y1,x2,y2,col+op) -- right
end,
[0x86] = function(x1,y1,x2,y2) -- CLIMB_R_STAND_R
col = 0x00ffffff -- white
line(x1,y1,x2,y1,col+op) -- top
col = 0x0000ffff -- cyan
line(x1,y1,x1,y2,col+op) -- left
end,
[0x87] = function(x1,y1,x2,y2) -- CLIMB_L_STAND_L
col = 0x00ffffff -- white
line(x1,y1,x2,y1,col+op) -- top
col = 0x0000ffff -- cyan
line(x2,y1,x2,y2,col+op) -- right
end,
[0x88] = function(x1,y1,x2,y2) -- CLIMB_LR_STAND_LR
col = 0x00ffffff -- white
line(x1,y1,x2,y1,col+op) -- top
col = 0x00ff00ff -- cyan
line(x1,y1,x1,y2,col+op) -- left
col = 0x0000ffff -- cyan
line(x2,y1,x2,y2,col+op) -- right
end,
[0x70] = function(x1,y1,x2,y2) -- GRAB_SWING
col = 0x0000ff00 -- green
box(x1,y1,x2,y2,col,col+opout)
end,
[0x7f] = function(x1,y1,x2,y2) -- EXIT
col = 0x00ffff00 -- yellow
end,
[0xd0] = function(x1,y1,x2,y2) -- SPIKES
col = 0x00ff0000 -- red
box(x1,y1,x2,y2,col,col+opout)
end,
[0xd1] = function(x1,y1,x2,y2) -- SPIKES
col = 0x00ff0000 -- red
box(x1,y1,x2,y2,col,col+opout)
end
}
function DrawBlockDefault(x1,y1,x2,y2)-- LEVEL_SPECIFIC
col = 0x00ff8800 -- orange
box(x1,y1,x2,y2,col+opin,col+opout)
end
function Objects()
if working>0 then return end
for i=0,63 do
local base = GlobalBase+i*128
local flag2 = AND(rb(base+0x49),0x10) -- active
if flag2==0x10 then
local xpos = rw (base+0x00)
local ypos = rw (base+0x02)
local dmg = rb (base+0x10)
local type = rw (base+0x40)
local hp = rw (base+0x50)
local cRAM = r24(base+0x75) -- pointer to 4 collision boxes per object
local col = 0 -- collision color
local xscr = (xpos-camx)/div
local yscr = (ypos-camy)/div
for boxx=0,4 do
local x1 = (rws(cRAM+boxx*8+0)-camx)/div
local y1 = (rws(cRAM+boxx*8+2)-camy)/div
local x2 = (rws(cRAM+boxx*8+4)-camx)/div
local y2 = (rws(cRAM+boxx*8+6)-camy)/div
if boxx==0 then
col = 0xff00ff00 -- body
if type==282 or type==258 then hp = 1 end -- archer hp doesn't matter
if hp>0 and type>0 then
text(x1+2,y1+1,string.format("%d",hp),col,0x88000000,"gens")
end
elseif boxx==1 then
col = 0xffffff00 -- floor
elseif boxx==2 then
if dmg>0
then col = 0xffff0000 -- projectile
else col = 0xff8800ff -- item
end
if dmg>0 then
text(x1+2,y2+1,string.format("%d",dmg),col,0x88000000,"gens")
end
else
col = 0xffffffff -- other
end
if x1~=0x8888 and x2<320 and x1>0 and y2<224 and y1>0 then
box(x1,y1,x2,y2,col)
end
end
end
end
end
function PlayerBoxes()
if working>0 then return end
local xx = (Xpos-camx)/div
local yy = (Ypos-camy)/div
local col = 0xff00ffff
local swcol = col -- usual detection
if Yspd>0 then -- gimme swings to grab!
swcol = 0xff00ff00
elseif Yspd==0 then -- can tell that too
swcol = 0xffffffff
end
if facing==2 then
box(xx-0xf /div-2,yy-0x2c/div-1,xx-0xf /div+0,yy-0x2c/div+1,swcol) -- lefttop
else
box(xx+0xf /div-1,yy-0x2c/div-1,xx+0xf /div+1,yy-0x2c/div+1,swcol) -- rightttop
end
box(xx -1,yy-0x2c/div-1,xx +1,yy-0x2c/div+1,col) -- top
box(xx-0xf /div-2,yy-0x1f/div-1,xx-0xf /div+0,yy-0x1f/div+1,col) -- left
box(xx+0x10/div-1,yy-0x1f/div-1,xx+0x10/div+1,yy-0x1f/div+1,col) -- right
-- box(xx -1,yy-0x1f/div-1,xx +1,yy-0x1f/div+1,col) -- center
box(xx -1,yy-0x0f/div-1,xx +1,yy-0x0f/div+1,col) -- bottom
box(xx -1,yy -1,xx +1,yy +1,0xffffff00) -- feet
-- box(xx -1,yy+0x10/div-1,xx +1,yy+0x10/div+1,col) -- ground
end
function Input()
local i,u,d,l,r,a,b,c,s
if movie.isloaded() then
i = movie.getinput(emu.framecount()-1)
else
i = joypad.getimmediate()
end
if i["P1 Up" ] then u = "U" else u = " " end
if i["P1 Down" ] then d = "D" else d = " " end
if i["P1 Left" ] then l = "L" else l = " " end
if i["P1 Right"] then r = "R" else r = " " end
if i["P1 A" ] then a = "A" else a = " " end
if i["P1 B" ] then b = "B" else b = " " end
if i["P1 C" ] then c = "C" else c = " " end
if i["P1 Start"] then s = "S" else s = " " end
text(1,10,u..d..l..r..a..b..c..s,"yellow")
end
event.onframeend(function()
emu.setislagged(rb(0xfff6d4)==0)
if rb(0xfff6d4)==0 then
lagcount = lagcount+1
framecol = "red"
else
framecol = "white"
end
emu.setlagcount(lagcount)
rndlast = rnd1
workinglast = working
XposLast = Xpos
YposLast = Ypos
end)
while true do
main()
emu.frameadvance()
end

View File

@ -1,485 +0,0 @@
-- The Adventures of Batman and Robin
-- 2013-2024, feos and r57shell
-- GLOBALS --
MsgTable = {}
MsgTime = 16
MsgOffs = 24
MsgCutoff = 60
RNGcount = 0
SpawnCount = 0
SpawnDelay = 0
SpawnX = 0
SpawnY = 0
Enemies = 0
Items = 0
Hearts = 0
-- SHORTCUTS --
rb = memory.read_u8
rbs = memory.read_s8
rw = memory.read_u16_be
rws = memory.read_s16_be
rl = memory.read_u32_be
rls = memory.read_s32_be
rex = event.onmemoryexecute
getr= emu.getregister
box = gui.drawBox
text= gui.pixelText
line= gui.drawLine
memory.usememorydomain("M68K BUS")
userdata.set("SpawnCount", 0)
userdata.set("SpawnOpac", 192)
function ToSigned16(num)
if num > 32768 then
num = num - (2 * 32768)
return num
else return num
end
end
function FitX(x, text)
local length = 0
if text ~= nil then length = string.len(text)*5 end
if x < 0 then x = 0
elseif x+length > 319 then x = 319-length end
return x
end
function FitY(y)
if y < 0 then y = 0
elseif y > 210 then y = 210 end
return y
end
function GetCam()
xcam = rws(0xFFDFC4)
if rb(0xFFFFF6) == 50 then
ycam = rws(0xFFDFE0)-20
else
ycam = 0
end
end
function EnemyPos(Base)
GetCam()
x1 = rws(Base + 0x12) - xcam
y1 = rws(Base + 0x14) - ycam
x2 = rws(Base + 0x16) - xcam
y2 = rws(Base + 0x18) - ycam
hp = rws(Base + 0x1E)
end
function PlayerPos()
local sbase1 = rw(0xFFAD5C) + 0xFF0000
local sbase2 = rw(0xFFADB6) + 0xFF0000
p1speedx = rls(sbase1 + 0x18) / 0x10000
p1speedy = rls(sbase1 + 0x1C) / 0x10000
p2speedx = rls(sbase2 + 0x18) / 0x10000
p2speedy = rls(sbase2 + 0x1C) / 0x10000
LIFT = rw(0xFF9024)
end
function HandleMsgTable(clear)
for i = 1, #MsgTable do
if clear then
MsgTable[i] = nil
end
if MsgTable[i] then
GetCam()
if MsgTable[i].y_ > MsgCutoff then
MsgY1 = 0
MsgY2 = 6
else
MsgY1 = 203
MsgY2 = 203
end
line(i * MsgOffs + 3, MsgY2,
MsgTable[i].x_ - xcam, MsgTable[i].y_,
0xFF0000 + (MsgTable[i].timer_ << 28))
text(i * MsgOffs , MsgY1, MsgTable[i].damage_, "red")
MsgTable[i].timer_ = MsgTable[i].timer_ - 1
if MsgTable[i].timer_ <= 0 then
MsgTable[i] = nil
end
end
end
end
function HandleDamage()
local damage = getr("M68K D0") & 0xFFFF
local base = getr("M68K A2") & 0xFFFFFF
-- print(string.format("%X", getr("M68K PC")))
EnemyPos(base)
unit = {
timer_ = MsgTime,
damage_ = damage,
x_ = x1 + xcam,
y_ = y1
}
for i = 1, 200 do
if MsgTable[i] == nil then
MsgTable[i] = unit
break
end
end
end
function Collision()
GetCam()
local a0 = getr("M68K A0") & 0xFFFFFF
local a6 = getr("M68K A6") & 0xFFFFFF
local wx1 = ToSigned16(getr("M68K D4") & 0xFFFF) - xcam
local wy1 = ToSigned16(getr("M68K D5") & 0xFFFF) - ycam
local wx2 = ToSigned16(getr("M68K D6") & 0xFFFF) - xcam
local wy2 = ToSigned16(getr("M68K D7") & 0xFFFF) - ycam
local id = rw(a6 + 2)
local damage = rw(a6 + 0x12)
-- text(wx2 + 2, wy1 + 1, string.format("%X",a6))
if damage == 0 then
damage = rw(a0 + 0x34)
end
if DamageHitbox then
box(wx1, wy1, wx2, wy2, 0xFFFF0000)
text(wx1 + 2, wy1 + 1, damage)
else
box(wx1, wy1, wx2, wy2, 0xFFFFFF00)
if id == 0x53B4 then Hearts = Hearts + 1 end
end
end
function InRange(var, num1, num2)
if var >= num1 and var <= num2
then return true
end
end
function Item()
GetCam()
local a6 = getr("M68K A6") & 0xFFFFFF
local x = rw(a6 + 0x3E) - xcam
local y = rw(a6 + 0x42)
local code = rb(a6 + 0x19)
if InRange(code, 0, 1) then return
elseif InRange(code, 7, 19) then item = "Amo" -- ammo
elseif InRange(code, 21, 23) then item = "Cha" -- fast charge
elseif InRange(code, 24, 26) then item = "Bom" -- bomb
elseif InRange(code, 27, 29) then item = "Lif" -- life
elseif InRange(code, 30, 47) then item = "HiP" -- hearts
else item = tostring(code)
end
text(x-7, y, string.format("%s" , item ), "yellow")
-- text(x-7, y, string.format("\n%X", a6+0x19), "yellow")
end
function Hitbox(address)
local i = 0
local base = rw(address)
while (base ~= 0) do
base = base + 0xFF0000
if rw(base + 2) == 0 then break end
EnemyPos(base)
if address == 0xFFDEB2 then
box(x1, y1, x2, y2, 0xFF00FF00)
elseif address == 0xFFDEBA then
box(x1, y1, x2, y2, 0xFF00FFFF)
text(FitX(x1, hp) + 2, FitY(y1) + 1, hp, 0xFFFF00FF)
-- if x2 < 0 then text(x1 + 2, y2 - 7, "x:" .. x1 ) end
-- if x1 >= 320 then text(x1 + 2, y2 - 7, "x:" .. x1 - 320) end
-- if y2 < 0 then text(x2 + 2, y2 - 7, "y:" .. y2 ) end
local offtext = ""
if x2 < 0 then offtext = offtext .. "x:" .. x1 end
if x1 >= 320 then offtext = offtext .. "x:" .. x1 - 320 end
if y2 < 0 then offtext = offtext .. "y:" .. y2 end
if y2 >= 224 then offtext = offtext .. "y:" .. y2 - 224 end
if offtext ~= "" then
text(FitX(x1, offtext), FitY(y1) - 7, offtext)
end
end
base = rw(base + 2)
i = i + 1
if i > 400 then break end
end
end
function Objects()
local level = rw(0xFFFFF5)
if level ~= 818 and level ~= 1026 then return end
Enemies = 0
Items = 0
GetCam()
local base = 0xFFAD54
for i=0,100 do
local id = rl (base)
local link = rw (base+ 6)
local ptr1 = rw (base+0x0A) + 0xFF0000
local delay = rl (base+0x2E) >> 8
local x = rws(base+0x3E)
local xsub = rb (base+0x40)
local y = rws(base+0x42)
local ysub = rb (base+0x44)
local hp = rw (base+0x52)
local ptr2 = 0
if id == 0x53B3 then ptr2 = rl(ptr1+0x2A) end
-- local code = rw (ptr2)
if base > 0 then
if ptr2 == 0x27DEE -- helicopter black
or ptr2 == 0x27F9C -- helicopter red
or ptr2 == 0x2804E -- plane black
or ptr2 == 0x28134 -- helicopter green
or ptr2 == 0x282B8 -- plane red
or ptr2 == 0x2860A -- missile
or ptr2 == 0x28DD2 -- helicopter red phase 1
or ptr2 == 0x28E08 -- helicopter red phase 2
then
Enemies = Enemies + 1
elseif ptr2 == 0x13326
or ptr2 == 0x13BDE
then
Items = Items + 1
else
text(x - xcam, y - ycam, string.format("%d", delay))
end
if delay > 0 and delay < 1000 then
SpawnDelay = delay
-- print(string.format("%d delay = %d", i, delay))
local xscr = 100
local yscr = 30 + i*10
text(xscr, yscr, string.format("delay %d: %d", i, delay))
end
end
base = link + 0xFF0000
local a5 = rl(base)
if a5 == 0x88BE then return end
end
end
function Spawns()
local level = rw(0xFFFFF5)
if level ~= 818 and level ~= 1026 then return end
local base = getr("M68K A6") & 0xFFFFFF
local ptr1 = rw(base+0x0A) + 0xFF0000
local ptr2 = rl(ptr1+0x2A)
local code = rw(ptr2)
local text = ""
SpawnX = rws(base+0x3E) - xcam
SpawnY = rws(base+0x42) - ycam
if ptr2 == 0x3A6E2 then text = "HOMING"
elseif ptr2 == 0x3A5C6 then text = "SCROLLING"
elseif ptr2 == 0x3A81E then text = "LONG 1"
elseif ptr2 == 0x3A778 then text = "LONG 2"
else text = "UNKNOWN"
end
if code ~= 0xAE6 -- drone
and code ~= 0xAF2 -- mini-missile
and code ~= 0x2384 -- item
then
userdata.set("SpawnOpac", 192)
userdata.set("SpawnCount", userdata.get("SpawnCount") + 1)
-- print(string.format("%02d - %X - %s", userdata.get("SpawnCount"), ptr2, text))
end
end
function Waves()
local level = rw(0xFFFFF5)
if level ~= 1142 then return end
GetCam()
local waveCount = rw(0xffdfb0)
text(120, 8, "Waves: " .. waveCount)
local base = 0xFFAD54
for i=0,100 do
local id = rl (base)
local link = rw (base+ 6)
local x0A = rw (base+0x0A)
local x12 = rw (base+0x12)
local x14 = rw (base+0x14)
local code = rl (base+0x1E) & 0xffffff
local delay = rl (base+0x2E) >> 8
local x = rws(base+0x3E)
local y = rws(base+0x42)
local hp = rws(base+0x52)
local nextop = rw (code)
local wait = ""
local color = 0xffffffff
if base > 0
and id ~= 0x53b4 -- projectile
and x0A ~= 0xaf16 -- batman
and not (hp <= 0 and id == 0x7D2) -- item
then
local xscr = 120
local yscr = 0 + i*7 + 14
if base == 0xFFAE62 then color = "yellow" end
if code == 0x411FC then color = 0xff00ff00 end
if code == 0x41206 or code == 0x4130E then color = "red" end
if nextop == 0x6ED2 then
wait = ":: wait enemies == 0"
elseif nextop >= 0x6EB2 and nextop <= 0x6ED2 then
wait = string.format(":: wait enemies <= %d", (0x6ED2 - nextop) / 4)
end
if x ~= 0 or y ~= 0 then
line(x - xcam, y - ycam, xscr, yscr+3, 0xAAFFFFFF)
end
text(xscr, yscr, string.format(
"%2d:%4X %4X %4X Timer:%3d %s",
i, x0A, x12, x14, delay, wait), color)
text(x - xcam - 10, y - ycam, i, 0xFF00FF00)
end
base = link + 0xFF0000
if rl(base) == 0x88BE then return end
end
end
function CalculateDelay()
local d0 = getr("M68K D0") >> 8
local d1 = getr("M68K D1") >> 8
print(string.format("Random spawn delay: %d + %d", d1, d0))
end
function PredictItem(rng)
rng = rng & 0xFFFF
local a2 = 0x29B78
local d0 = 0
local carry = rw(a2) > rng
a2 = a2 + 2
if carry then
a2 = a2 + 2
while rw(a2) > rng do
a2 = a2 + 4
end
a2 = a2 + 2
end
a2 = a2 + rw(a2) + 2
if a2 == 0x29BBA then a2 = 0 end
return rw(a2) & 0xFF
end
function RNGroll(seed1, seed2) -- subroutine $995C
local d0 = seed1
local d1 = seed2
d1 = (d1 << 1) | (d1 >> 31) -- ROL.L #1,D1
d1 = ((d1 & 0xFFFF) ~ d0) | (d1 & 0xFFFF0000) -- EOR.W D0,D1
d1 = ((d1 & 0xFFFF) << 16) | (d1 >> 16) -- SWAP.W D1
d0 = (d1 ~ d0) & 0xFFFF -- EOR.W D1,D0
d0 = ((d0 << 1) & 0xFFFF) | ((d0 << 1) >> 16) -- ROL.W #1,D0
d1 = ((d1 & 0xFFFF) ~ d0) | (d1 & 0xFFFF0000) -- EOR.W D0,D1
d1 = ((d1 & 0xFFFF) << 16) | (d1 >> 16) -- SWAP.W D1
d0 = ((d1 & 0xFFFF) ~ d0) -- EOR.W D1,D0
return {(d0 & 0xFFFF), d1}
end
function ItemPrediction()
local RNG1 = rw (0xFFF5FC)
local RNG2 = rl (0xFFF5FE)
local RNG = RNGroll(RNG1, RNG2)
local RNG = RNGroll(RNG[1], RNG[2])
local item = PredictItem(RNG[1])
gui.text(0, 170, string.format("%2X", item),"yellow")
end
function Main()
local color0 = "yellow"
local color1 = "yellow"
local color2 = "yellow"
local base1 = 0xFFAD54
local base2 = 0xFFADAE
-- local hp1 = rw (0xFFF654)
-- local life1 = rw (0xFFF644)
local level = rw (0xFFFFF5)
local X1 = rw (base1 + 0x3E)
local X1sub = rb (base1 + 0x40)
local Y1 = rws(base1 + 0x42)
local Y1sub = rb (base1 + 0x44)
local X2 = rw (base2 + 0x3E)
local X2sub = rb (base2 + 0x40)
local Y2 = rws(base2 + 0x42)
local Y2sub = rb (base2 + 0x44)
local RNG1 = rw (0xFFF5FC)
-- local RNG2 = rl (0xFFF5FE)
local Weapon1 = rb (0xFFF67B)
local Weapon2 = rb (0xFFF6BB)
local Charge1 = (rw(0xFFF658) - 0x2800) / -0x80
local Charge2 = (rw(0xFFF698) - 0x2800) / -0x80
local ScreenLock = rw (0xFFDFC0)
if Charge1 <= 0 then Charge1 = 0 color1 = "red" end
if Charge2 <= 0 then Charge2 = 0 color2 = "red" end
if RNGcount > 1 then color0 = "red" end
HandleMsgTable()
PlayerPos()
Objects()
Waves()
if level == 818 or level == 1026 then
line(30, 42, SpawnX, SpawnY, 0x00FF00 + (userdata.get("SpawnOpac") << 24))
text( 0, 35, string.format("Obj: %d", userdata.get("SpawnCount")), 0xFF00FF00)
text( 0, 49, string.format("%d %d %s", Enemies, Items, Hearts/2))
if SpawnDelay > 0 and SpawnDelay < 1000 then
text(0, 42, string.format("Del: %d", SpawnDelay), "yellow")
end
end
text( 1, 217, string.format("RNG:%X" , RNG1))
text( 40, 217, string.format("Lock:%d" , ScreenLock))
text( 81, 210, string.format("Pos: %d.%d\nSpd: %.5f", X1, X1sub, p1speedx))
text(137, 210, string.format("/ %d.%d\n/ %.5f" , Y1, Y1sub, p1speedy))
text( 80, 22, string.format("%2.0f" , Charge1), color1)
-- text(235, 20, string.format("%2.0f" , Charge2), color2)
text( 34, 217, string.format("%d" , RNGcount), color0)
text(180, 217, string.format("%2d" , Weapon1+1), "yellow")
-- text(300, 217, string.format("%2d" , Weapon2+1), "yellow")
-- text(203, 210, string.format("Pos: %d.%d\nSpd: %.5f", X2, X2sub, p2speedx), 0xFF00FF00)
-- text(260, 210, string.format("/ %d.%d\n/ %.5f" , Y2, Y2sub, p2speedy), 0xFF00FF00)
Hitbox(0xFFDEB2)
Hitbox(0xFFDEBA)
RNGcount = 0
if rb(0xFF4633) == 5 then
-- text(143,3,string.format(" %2d", LIFT), 0xFFFF00FF, clear)
end
DER = rw(0xFFAEA0)
-- text(135,3,string.format(" %2d", DER), 0xFFFF00FF, clear)
-- emu.frameadvance()
-- gui.clearGraphics()
end
event.onframeend(function()
local spawnOpac = userdata.get("SpawnOpac") - 4
if spawnOpac < 0 then spawnOpac = 0 end
userdata.set("SpawnOpac", spawnOpac)
Main()
end)
event.onframestart(function()
SpawnDelay1 = 0
SpawnDelay2 = 0
Hearts = 0
ItemPrediction()
end)
event.onloadstate(function()
Enemies = 0
Items = 0
Hearts = 0
SpawnCount = 0
return HandleMsgTable(1)
end)
rex(function() DamageHitbox = false end , 0x375A, "DamageHitbox-")
rex(function() DamageHitbox = true end , 0x375E, "DamageHitbox+")
rex(function() DamageHitbox = false end , 0x3768, "DamageHitbox-")
rex(function() DamageHitbox = true end , 0x376C, "DamageHitbox+")
rex(function() DamageHitbox = false end , 0x65C4, "DamageHitbox-")
rex(function() DamageHitbox = true end , 0x65C8, "DamageHitbox+")
rex(CalculateDelay , 0x6ADE, "Delay")
rex(function() RNGcount = RNGcount + 1 end, 0x995C, "RNGcount++")
rex(Item , 0x4738, "Item")
rex(Item , 0x4534, "Item")
rex(Spawns , 0x8DE6, "Spawns")
rex(Spawns , 0x8DCE, "Spawns")
rex(Collision , 0x8C9A, "Collision")
rex(HandleDamage , 0x1085A, "MeeleeDamage")
rex(HandleDamage , 0x10CBA, "WeaponDamage")
rex(HandleDamage , 0x10CC4, "WeaponDamage")

File diff suppressed because it is too large Load Diff

View File

@ -1,57 +0,0 @@
---------------------------------------------------------
-- Small script for only allowing input on P1 controller
-- if both P1 and P2 holds down a specific input
--
-- Note that this script only works on systems which
-- has two or more joypads (such as NES) and not on
-- systems with just one joypad (such as Gameboy)
--
-- Author: Gikkman
---------------------------------------------------------
-- Pre-made array for resetting the P1 joypad
local reset = joypad.get(1)
for k,v in pairs(reset) do
reset[k] = ''
end
event.onframestart( function()
local p1 = joypad.get(1)
local p2 = joypad.get(2)
local consolidated = intersection(p1, p2)
gui.drawText(0,10, 'P1: ' .. dump(p1))
gui.drawText(0,25, 'P2: ' .. dump(p2))
joypad.set(consolidated, 1)
end )
event.onframeend( function()
joypad.set(reset, 1)
end )
-- Get intersection of P1 and P2 joypads
function intersection(p1, p2)
local ret = {}
for k,v in pairs(p1) do
ret[k] = p1[k] and p2[k]
end
return ret
end
-- Print all pressed buttons
function dump(o)
local s = ''
for k,v in pairs(o) do
if v then s = s .. tostring(k) .. ' ' end
end
return s
end
--------------------------------------
-- Main loop --
--------------------------------------
while true do
emu.frameadvance()
end

View File

@ -1,28 +1,12 @@
local START_FRAME = 0;
local CORNER = "topright";
local OFFSET_X = 0;
local OFFSET_Y = 0;
while true do
if (movie.isloaded()) then
if movie.getheader()["Core"] == "Gambatte" then
clockrate = 2 ^ 21;
cycles = emu.totalexecutedcycles();
tseconds = (cycles / clockrate);
elseif movie.getheader()["Core"] == "SubGBHawk" then
clockrate = 2 ^ 22;
cycles = emu.totalexecutedcycles();
tseconds = (cycles / clockrate);
else
fps = movie.getfps();
frames = emu.framecount();
frames = frames < START_FRAME and 0 or (frames - START_FRAME);
tseconds = (frames / fps);
end
fps = movie.getfps();
frames = movie.length();
tseconds = (frames / fps)
secondsraw = tseconds % 60;
shift = 10 ^ 2;
seconds = math.floor((secondsraw * shift) + 0.5) / shift;
secondsstr = string.format("%.2f", seconds);
secondsstr = string.format("%.2f", seconds)
if (seconds < 10) then
secondsstr = "0" .. secondsstr;
end
@ -39,7 +23,7 @@ while true do
if (hours > 0) then
time = "0" .. hours .. ":" .. time;
end
gui.text(OFFSET_X, OFFSET_Y, time, nil, CORNER);
gui.text(0, 0, time, null, null, 1);
end
emu.frameadvance();
end
end

View File

@ -1,56 +0,0 @@
-- Gives a cross hair UI for the stylus for DS games
local upColor = 'lime'
local downColor = 'red'
local dotColor = 'blue'
function Draw(x, y, maxX, maxY, isDown)
color = upColor
if isDown then
color = downColor
end
gui.drawLine(0, y - 1, maxX, y - 1, color, "client")
gui.drawLine(0, y, maxX, y, color, "client")
gui.drawLine(0, y + 1, maxX, y + 1, color, "client")
gui.drawLine(x - 1, 0, x - 1, maxY, color, "client")
gui.drawLine(x, 0, x, maxY, color, "client")
gui.drawLine(x + 1, 0, x + 1, maxY, color, "client")
if isDown then
gui.drawPixel(x - 1, y - 1, dotColor, "client")
gui.drawPixel(x, y - 1, dotColor, "client")
gui.drawPixel(x + 1, y - 1, dotColor, "client")
gui.drawPixel(x - 1, y, dotColor, "client")
gui.drawPixel(x, y, dotColor, "client")
gui.drawPixel(x + 1, y, dotColor, "client")
gui.drawPixel(x - 1, y + 1, dotColor, "client")
gui.drawPixel(x, y + 1, dotColor, "client")
gui.drawPixel(x + 1, y + 1, dotColor, "client")
end
end
while true do
if emu.getsystemid() ~= "NDS" then
console.log('This script is for Nintendo DS only')
break
end
local btns = joypad.get()
if movie.mode() == "PLAY" and emu.framecount() > 0 then
btns = movie.getinput(emu.framecount() - 1)
end
local x = btns['Touch X']
local y = btns['Touch Y']
local isDown = btns['Touch']
local pts = client.transformPoint(x, y)
local tx = pts["x"];
local ty = pts["y"];
Draw(tx, ty, 10000, 10000, isDown)
emu.yield()
end

View File

@ -61,10 +61,10 @@ end
while true do
--*****************************************************************************
EnemyHP = mainmemory.read_u8(EHP)
gui.text(0,0,"Opponent: " .. EnemyHP, nil, nil, "topright")
gui.text(0,0,"Opponent: " .. EnemyHP, null, null, "topright")
MacHP = mainmemory.read_u8(MHP)
gui.text(0,12,"Mac: " .. MacHP, nil, nil, "topright")
gui.text(0,12,"Mac: " .. MacHP, null, null, "topright")
if IsOppDown() then
OppWillGet = mainmemory.read_u8(OppWillGetUpWith)
@ -72,8 +72,8 @@ while true do
if OppGetUpCount == -153 then
OppGetUpCount = "never!"
end
gui.text(0, 12, "Next health: " .. OppWillGet, nil, nil, "bottomright")
gui.text(OppGetUpX, OppGetUpY, "Will get up on: " .. OppGetUpCount, nil, nil, "bottomright")
gui.text(0, 12, "Next health: " .. OppWillGet, null, null, "bottomright")
gui.text(OppGetUpX, OppGetUpY, "Will get up on: " .. OppGetUpCount, null, null, "bottomright")
end
if OppIsHit() then
@ -83,7 +83,7 @@ while true do
end
if OppHitTimer > 0 then
gui.text(0, 0, "Damage: " .. OppHitToDisplay, nil, nil, "bottomright")
gui.text(0, 0, "Damage: " .. OppHitToDisplay, null, null, "bottomright")
end

View File

@ -177,49 +177,49 @@ pitchtype = mainmemory.read_u8(pitchtypeAddr);
--What the pitcher will pitch
if (pitchtype == 0) then
gui.text(0,0,"Sinker!!", nil, nil, "bottomright");
gui.text(0,0,"Sinker!!", null, null, "bottomright");
end
if (pitchtype == 2) then
gui.text(0,0, "Fast Ball", nil, nil, "bottomright")
gui.text(0,0, "Fast Ball", null, null, "bottomright")
end
if (pitchtype == 1) then
gui.text(0,0,"Regular Pitch", nil, nil, "bottomright")
gui.text(0,0,"Regular Pitch", null, null, "bottomright")
end
--Top of Inning
if (inningtb == 0) then
gui.text(0,0, "Health " .. mainmemory.read_u8(0x061D), nil, nil, "topright")
gui.text(0,12,"Drop " .. mainmemory.read_u8(0x0617) % 16, nil, nil, "topright")
gui.text(0,24,"CurveL " .. mainmemory.read_u8(0x061C) / 16, nil, nil, "topright")
gui.text(0,36,"CurveR " .. mainmemory.read_u8(0x061C) % 16, nil, nil, "topright")
gui.text(0,48,"Fast SP " .. mainmemory.read_u8(0x061B), nil, nil, "topright")
gui.text(0,60,"Reg SP " .. mainmemory.read_u8(0x061A), nil, nil, "topright")
gui.text(0,72,"Sink SP " .. mainmemory.read_u8(0x0619), nil, nil, "topright")
gui.text(0,0, "Health " .. mainmemory.read_u8(0x061D), null, null, "topright")
gui.text(0,12,"Drop " .. mainmemory.read_u8(0x0617) % 16, null, null, "topright")
gui.text(0,24,"CurveL " .. mainmemory.read_u8(0x061C) / 16, null, null, "topright")
gui.text(0,36,"CurveR " .. mainmemory.read_u8(0x061C) % 16, null, null, "topright")
gui.text(0,48,"Fast SP " .. mainmemory.read_u8(0x061B), null, null, "topright")
gui.text(0,60,"Reg SP " .. mainmemory.read_u8(0x061A), null, null, "topright")
gui.text(0,72,"Sink SP " .. mainmemory.read_u8(0x0619), null, null, "topright")
P1currPower = mainmemory.read_u8(P1currHitterPowerAddr) + (mainmemory.read_u8(P1currHitterPowerAddr+1) * 256);
gui.text(0,108, "Power: " .. P1currPower, nil, nil, "topright");
gui.text(0,108, "Power: " .. P1currPower, null, null, "topright");
P1currSpeed = mainmemory.read_u8(P1currSpeedAddr);
gui.text(0,120, "Speed: " .. P1currSpeed, nil, nil, "topright");
gui.text(0,120, "Speed: " .. P1currSpeed, null, null, "topright");
P1currCt = mainmemory.read_u8(P1currContactAddr);
gui.text(0,132, "Contact: " .. P1currCt, nil, nil, "topright");
gui.text(0,132, "Contact: " .. P1currCt, null, null, "topright");
end
--Bottom of Inning
if (inningtb == 0x10) then
gui.text(0,0,"Health " .. mainmemory.read_u8(0x060D), nil, nil, "topright")
gui.text(0,12,"Drop " .. mainmemory.read_u8(0x0607) % 16, nil, nil, "topright")
gui.text(0,24,"CurveL " .. mainmemory.read_u8(0x060C) / 16, nil, nil, "topright")
gui.text(0,36,"CurveR " .. mainmemory.read_u8(0x060C) % 16, nil, nil, "topright")
gui.text(0,48,"Fast SP " .. mainmemory.read_u8(0x060B), nil, nil, "topright")
gui.text(0,60,"Reg SP " .. mainmemory.read_u8(0x060A), nil, nil, "topright")
gui.text(0,72,"Sink SP " .. mainmemory.read_u8(0x0609), nil, nil, "topright")
gui.text(0,0,"Health " .. mainmemory.read_u8(0x060D), null, null, "topright")
gui.text(0,12,"Drop " .. mainmemory.read_u8(0x0607) % 16, null, null, "topright")
gui.text(0,24,"CurveL " .. mainmemory.read_u8(0x060C) / 16, null, null, "topright")
gui.text(0,36,"CurveR " .. mainmemory.read_u8(0x060C) % 16, null, null, "topright")
gui.text(0,48,"Fast SP " .. mainmemory.read_u8(0x060B), null, null, "topright")
gui.text(0,60,"Reg SP " .. mainmemory.read_u8(0x060A), null, null, "topright")
gui.text(0,72,"Sink SP " .. mainmemory.read_u8(0x0609), null, null, "topright")
P2currPower = mainmemory.read_u8(P2currHitterPowerAddr) + (mainmemory.read_u8(P2currHitterPowerAddr+1) * 256);
gui.text(0,108, "Power: " .. P2currPower, nil, nil, "topright");
gui.text(0,108, "Power: " .. P2currPower, null, null, "topright");
P2currSpeed = mainmemory.read_u8(P2currSpeedAddr);
gui.text(0,120, "Speed: " .. P2currSpeed, nil, nil, "topright");
gui.text(0,120, "Speed: " .. P2currSpeed, null, null, "topright");
P2currCt = mainmemory.read_u8(P2currContactAddr);
gui.text(0,132, "Contact: " .. P2currCt, nil, nil, "topright");
gui.text(0,132, "Contact: " .. P2currCt, null, null, "topright");
end
end
@ -228,7 +228,7 @@ end
if (PitchingScreen == 0x0036) then
p1Outs = mainmemory.read_u8(p1OutsAddr);
gui.text(0,0, "Outs " .. p1Outs, nil, nil, "topright");
gui.text(0,0, "Outs " .. p1Outs, null, null, "topright");
end
-------------------------------------------------------

View File

@ -6,8 +6,6 @@
-- Git repository: https://github.com/rodamaral/smw-tas
---------------------------------------------------------------------------
bit = (require "migration_helpers").EmuHawk_pre_2_9_bit();
--#############################################################################
-- CONFIG:
@ -950,11 +948,9 @@ local Nextframe, Starting_subframe_next_frame, Starting_subframe_next_frame, Fin
local function bizhawk_status()
Movie_active = movie.isloaded() -- BizHawk
Readonly = movie.getreadonly() -- BizHawk
if Movie_active then
Framecount = movie.length() -- BizHawk
Rerecords = movie.getrerecordcount() -- BizHawk
end
Framecount = movie.length() -- BizHawk
Lagcount = emu.lagcount() -- BizHawk
Rerecords = movie.getrerecordcount() -- BizHawk
Is_lagged = emu.islagged() -- BizHawk
Game_region = emu.getdisplaytype() -- BizHawk
@ -2620,7 +2616,7 @@ local function yoshi()
if eat_id == SMW.null_sprite_id and tongue_len == 0 and tongue_timer == 0 and tongue_wait == 0 then
Text_opacity = 0.2
end
draw_text(x_text, y_text + h, fmt("(%s, %s) %02d, %d, %d",
draw_text(x_text, y_text + h, fmt("(%0s, %0s) %02d, %d, %d",
eat_id_str, eat_type_str, tongue_len, tongue_wait, tongue_timer), COLOUR.yoshi)
;

View File

@ -13,7 +13,7 @@ buttons = { };
buttons["Up"] = false;
buttons["Down"] = true;
buttons["Left"] = "invert";
buttons["Right"] = nil;
buttons["Right"] = null;
joypad.set(buttons, 1);
pushThings = true;
@ -24,17 +24,17 @@ while true do
buttons["A"] = false;
buttons["B"] = true;
buttons["Select"] = "invert";
buttons["Start"] = nil;
buttons["Start"] = null;
joypad.set(buttons, 1);
end
if (emu.framecount() == 600) then
pushThings = false;
turnoff = { };
turnoff["A"] = nil;
turnoff["B"] = nil;
turnoff["Select"] = nil;
turnoff["Start"] = nil;
turnoff["A"] = null;
turnoff["B"] = null;
turnoff["Select"] = null;
turnoff["Start"] = null;
joypad.set(turnoff, 1);
console.writeline("cleared")

View File

@ -13,7 +13,7 @@ buttons = { };
buttons["Up"] = false;
buttons["Down"] = true;
buttons["Left"] = "invert";
buttons["Right"] = nil;
buttons["Right"] = null;
joypad.set(buttons, 1);
pushThings = true;
@ -24,17 +24,17 @@ while true do
buttons["A"] = false;
buttons["B"] = true;
buttons["Select"] = "invert";
buttons["Start"] = nil;
buttons["Start"] = null;
joypad.set(buttons, 1);
end
if (emu.framecount() == 600) then
pushThings = false;
turnoff = { };
turnoff["A"] = nil;
turnoff["B"] = nil;
turnoff["Select"] = nil;
turnoff["Start"] = nil;
turnoff["A"] = null;
turnoff["B"] = null;
turnoff["Select"] = null;
turnoff["Start"] = null;
joypad.set(turnoff, 1);
console.writeline("cleared")

View File

@ -1,149 +0,0 @@
function round(num, numDecimalPlaces)
local mult = 10^(numDecimalPlaces or 0)
return math.floor(num * mult + 0.5) / mult
end
function get_baseline()
i = 100
client.reboot_core()
t = os.clock()
while i > 0 do
emu.frameadvance()
i = i - 1
end
baseline = os.clock() - t
print('Baseline: ' .. round(baseline, 3) .. " secs")
return baseline
end
function test_mmf()
i = 100
client.reboot_core()
t = os.clock()
while i > 0 do
emu.frameadvance()
comm.mmfScreenshot()
i = i - 1
end
print('Memory mapped files: ' .. round((os.clock() - t - baseline), 3) .. " secs")
end
function test_http()
print("Testing HTTP server")
client.reboot_core()
i = 100
t = os.clock()
while i > 0 do
emu.frameadvance()
comm.httpTestGet()
i = i - 1
end
print('HTTP get: ' .. round((os.clock() - t - baseline), 3) .. " secs")
client.reboot_core()
i = 100
t = os.clock()
while i > 0 do
emu.frameadvance()
comm.httpPostScreenshot()
i = i - 1
end
print('HTTP post: ' .. round((os.clock() - t - baseline), 3) .. " secs")
end
function test_socket()
i = 100
client.reboot_core()
t = os.clock()
while i > 0 do
emu.frameadvance()
comm.socketServerScreenShot()
i = i - 1
end
print('Socket server: ' .. round((os.clock() - t - baseline), 3) .. " secs")
end
function test_socketresponse()
best_time = -100
timeouts = {1, 2, 3, 4, 5, 10, 20, 25, 50, 100, 250, 500, 1000}
comm.socketServerSetTimeout(1000)
resp = comm.socketServerScreenShotResponse()
for t, timeout in ipairs(timeouts) do
comm.socketServerSetTimeout(timeout)
client.reboot_core()
print("Trying to find minimal timeout for Socket server")
i = 100
t = os.clock()
while i > 0 do
emu.frameadvance()
resp = comm.socketServerScreenShotResponse()
if resp ~= 'ack' then
i = -100
print(resp)
print("Failed to a get a proper response")
end
i = i - 1
end
if i > -100 then
print("Best timeout: " .. timeout .. " msecs")
print("Best time: " .. round((os.clock() - t - baseline), 3) .. " secs")
break
end
end
end
function test_http_response()
err = false
print("Testing HTTP server response")
client.reboot_core()
i = 100
while i > 0 do
emu.frameadvance()
resp = comm.httpTestGet()
if resp ~= "<html><body><h1>hi!</h1></body></html>" then
print("Failed to get correct HTTP get response")
print(resp)
i = 0
err = true
end
i = i - 1
end
if not err then
print("HTTP GET looks fine: No errors occurred")
end
client.reboot_core()
i = 100
err = false
while i > 0 do
emu.frameadvance()
resp = comm.httpPostScreenshot()
if resp ~= "<html><body>OK</body></html>" then
print("Failed to get correct HTTP post response")
print(resp)
i = 0
err = true
end
i = i - 1
end
if not err then
print("HTTP POST looks fine: No errors occurred")
end
end
baseline = get_baseline()
test_socket()
test_mmf()
test_http()
print("#####################")
test_http_response()
test_socketresponse()
print()

View File

@ -1,91 +0,0 @@
print("##########################################################")
getUrl = comm.httpGetGetUrl()
print("GET URL: " .. getUrl)
postUrl = comm.httpGetPostUrl()
print("POST URL: " .. postUrl)
print("\nChecking GET URL change")
error = false
comm.httpSetGetUrl('a')
if (getUrl ~= comm.httpGetGetUrl()) then
comm.httpSetGetUrl(getUrl)
error = (getUrl ~= comm.httpGetGetUrl())
else
error = true
end
if error == false then
print("Get URL was successfully changed")
else
print("Error while changing Get URL")
end
print("\nChecking POST URL change")
error = false
comm.httpSetPostUrl('a')
if (postUrl ~= comm.httpGetPostUrl()) then
comm.httpSetPostUrl(postUrl)
error = (postUrl ~= comm.httpGetPostUrl())
else
error = true
end
if error == false then
print("Post URL was successfully changed")
else
print("Error while changing Post URL")
end
print("\nChecking GET request")
getResponse = comm.httpGet("http://tasvideos.org/BizHawk.html")
if string.find(getResponse, "Bizhawk") then
print("GET seems to work")
else
print("Either the Bizhawk site is down or the GET does not work")
end
print("\nChecking memory mapped filed")
size = comm.mmfScreenshot()
if size > 0 then
print("Memory mapped file was successfully written")
else
print("Failed to write memory mapped file")
end
mmf_filename = comm.mmfGetFilename()
print("MMF filename: " .. mmf_filename)
comm.mmfSetFilename("deleteme.tmp")
error = false
if (mmf_filename ~= comm.mmfGetFilename()) then
comm.mmfSetFilename(mmf_filename)
error = (mmf_filename ~= comm.mmfGetFilename())
else
error = true
end
if error == false then
print("MMF filename successfully changed")
else
print("MMF filename change failed")
end
print("Writing to MMF")
message = "ABC"
resp_n = tonumber(comm.mmfWrite(mmf_filename, message))
if (resp_n ~= string.len(message)) then
print("Failed to write to MMF")
else
resp = comm.mmfRead(mmf_filename, string.len(message))
if (resp ~= message) then
print("Failed to read from MMF")
else
print("MMF read and read OK")
end
end
print("\nTests finished")
print("Please run TestCommunication_All.lua with the supplied Python server for a more comprehensive test")

View File

@ -1,22 +0,0 @@
local helpers = {};
helpers.EmuHawk_pre_2_9_bit = function()
local wrapped_bit = {
band = function(val, amt) return val & amt; end,
bnot = function(val) return ~val; end,
bor = function(val, amt) return val | amt; end,
bxor = function(val, amt) return val ~ amt; end, -- not a typo
lshift = function(val, amt) return val << amt; end,
rol = bit.rol,
ror = bit.ror,
rshift = function(val, amt) return val >> amt; end,
arshift = bit.arshift,
check = bit.check,
set = bit.set,
clear = bit.clear,
byteswap_16 = bit.byteswap_16,
byteswap_32 = bit.byteswap_32,
byteswap_64 = bit.byteswap_64,
};
return wrapped_bit;
end;
return helpers;

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,32 @@
struct input
{
float2 video_size;
float2 texture_size;
float2 output_size;
};
void main_vertex
(
float4 position : POSITION,
out float4 oPosition : POSITION,
uniform float4x4 modelViewProj,
float2 tex : TEXCOORD,
uniform input IN,
out float2 oTexcoord : TEXCOORD
)
{
oPosition = mul(modelViewProj, position);
oTexcoord = tex;
}
uniform float uIntensity;
float4 main_fragment (in float2 texcoord : TEXCOORD, in float2 wpos : WPOS, uniform sampler2D s_p : TEXUNIT0) : COLOR
{
float4 temp = tex2D(s_p,texcoord);
if(floor(wpos.y/2) != floor(wpos.y)/2) temp.rgb *= uIntensity;
return temp;
}

View File

@ -1,34 +0,0 @@
#ifdef VERTEX
uniform mat4 MVPMatrix;
in vec4 VertexCoord;
in vec2 TexCoord;
out vec2 vTex;
void main()
{
gl_Position = MVPMatrix * VertexCoord;
vTex = TexCoord;
}
#endif
#ifdef FRAGMENT
uniform float uIntensity;
uniform sampler2D s_p;
in vec2 vTex;
out vec4 FragColor;
void main()
{
vec4 temp = texture(s_p,vTex);
vec2 wpos = gl_FragCoord.xy;
if(floor(wpos.y/2.0) != floor(wpos.y)/2.0) temp.rgb *= uIntensity;
FragColor = temp;
}
#endif

View File

@ -1,25 +0,0 @@
void main_vertex
(
float4 position : POSITION,
float2 tex : TEXCOORD0,
uniform float4x4 modelViewProj,
out float4 oPosition : POSITION,
out float2 oTex0 : TEXCOORD0,
out float oTex1 : TEXCOORD1
)
{
oPosition = mul(modelViewProj, position);
oTex0 = tex;
oTex1 = position.y;
}
uniform float uIntensity;
float4 main_fragment (in float4 vpos : POSITION, in float2 tex0 : TEXCOORD0, in float tex1 : TEXCOORD1, uniform sampler2D s_p : TEXUNIT0) : COLOR
{
float4 temp = tex2D(s_p, tex0);
if (floor(tex1 / 2) != floor(tex1) / 2) temp.rgb *= uIntensity;
return temp;
}

View File

@ -0,0 +1,152 @@
/* COMPATIBILITY
- HLSL compilers
- Cg compilers
*/
/*
bicubic-fast Shader
Copyright (C) 2011-2015 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
const static float4x4 invX = float4x4(-1.0/6.0, 0.5, -1.0/3.0, 0.0,
0.5, -1.0, -0.5, 1.0,
-0.5, 0.5, 1.0, 0.0,
1.0/6.0, 0.0, -1.0/6.0, 0.0);
// Can't init statically from variable, even though it's const ...
//const static float4x4 invY = transpose(invX);
const static float4x4 invY = float4x4(-1.0/6.0, 0.5, -0.5, 1.0/6.0,
0.5, -1.0, 0.5, 0.0,
-1.0/3.0, -0.5, 1.0, -1.0/6.0,
0.0, 1.0, 0.0, 0.0);
struct input
{
float2 video_size;
float2 texture_size;
float2 output_size;
float frame_count;
float frame_direction;
float frame_rotation;
};
struct out_vertex {
float2 texCoord : TEXCOORD0;
float4 t1 : TEXCOORD1;
float4 t2 : TEXCOORD2;
float4 t3 : TEXCOORD3;
float4 t4 : TEXCOORD4;
float4 t5 : TEXCOORD5;
float4 t6 : TEXCOORD6;
float4 t7 : TEXCOORD7;
float2 t8 : COLOR0;
};
/* VERTEX_SHADER */
out_vertex main_vertex
(
float4 position : POSITION,
out float4 oPosition : POSITION,
float2 texCoord1 : TEXCOORD0,
uniform float4x4 modelViewProj,
uniform input IN
)
{
float2 ps = float2(1.0/IN.texture_size.x, 1.0/IN.texture_size.y);
float dx = ps.x;
float dy = ps.y;
oPosition = mul(modelViewProj, position);
// This line fix a bug in ATI cards.
float2 tex = texCoord1 + float2(0.0000001, 0.0000001);
out_vertex OUT = {
tex,
float4(tex,tex) + float4( -dx, -dy, 0.0, -dy),
float4(tex,tex) + float4( dx, -dy, 2.0*dx, -dy),
float4(tex,tex) + float4( -dx, 0.0, dx, 0.0),
float4(tex,tex) + float4(2.0*dx, 0.0, -dx, dy),
float4(tex,tex) + float4( 0.0, dy, dx, dy),
float4(tex,tex) + float4(2.0*dx, dy, -dx, 2.0*dy),
float4(tex,tex) + float4( 0.0, 2.0*dy, dx, 2.0*dy),
tex + float2(2.0*dx, 2.0*dy)
};
return OUT;
}
float4 main_fragment(in out_vertex VAR, uniform sampler2D s_p : TEXUNIT0, uniform input IN) : COLOR
{
float2 fp = frac(VAR.texCoord*IN.texture_size);
float3 c00 = tex2D(s_p, VAR.t1.xy).xyz;
float3 c01 = tex2D(s_p, VAR.t1.zw).xyz;
float3 c02 = tex2D(s_p, VAR.t2.xy).xyz;
float3 c03 = tex2D(s_p, VAR.t2.zw).xyz;
float3 c10 = tex2D(s_p, VAR.t3.xy).xyz;
float3 c11 = tex2D(s_p, VAR.texCoord).xyz;
float3 c12 = tex2D(s_p, VAR.t3.zw).xyz;
float3 c13 = tex2D(s_p, VAR.t4.xy).xyz;
float3 c20 = tex2D(s_p, VAR.t4.zw).xyz;
float3 c21 = tex2D(s_p, VAR.t5.xy).xyz;
float3 c22 = tex2D(s_p, VAR.t5.zw).xyz;
float3 c23 = tex2D(s_p, VAR.t6.xy).xyz;
float3 c30 = tex2D(s_p, VAR.t6.zw).xyz;
float3 c31 = tex2D(s_p, VAR.t7.xy).xyz;
float3 c32 = tex2D(s_p, VAR.t7.zw).xyz;
float3 c33 = tex2D(s_p, VAR.t8.xy).xyz;
float4x4 red_matrix = float4x4(c00.x, c01.x, c02.x, c03.x,
c10.x, c11.x, c12.x, c13.x,
c20.x, c21.x, c22.x, c23.x,
c30.x, c31.x, c32.x, c33.x);
float4x4 green_matrix = float4x4(c00.y, c01.y, c02.y, c03.y,
c10.y, c11.y, c12.y, c13.y,
c20.y, c21.y, c22.y, c23.y,
c30.y, c31.y, c32.y, c33.y);
float4x4 blue_matrix = float4x4(c00.z, c01.z, c02.z, c03.z,
c10.z, c11.z, c12.z, c13.z,
c20.z, c21.z, c22.z, c23.z,
c30.z, c31.z, c32.z, c33.z);
float4x1 invX_Px = mul(invX, float4x1(fp.x*fp.x*fp.x, fp.x*fp.x, fp.x, 1.0));
float1x4 Py_invY = mul(float1x4(fp.y*fp.y*fp.y, fp.y*fp.y, fp.y, 1.0), invY);
float red = mul(Py_invY, mul( red_matrix, invX_Px));
float green = mul(Py_invY, mul(green_matrix, invX_Px));
float blue = mul(Py_invY, mul( blue_matrix, invX_Px));
return float4(red, green, blue, 1.0);
}

View File

@ -1,153 +0,0 @@
/* COMPATIBILITY
- HLSL compilers
- Cg compilers
*/
/*
bicubic-fast Shader
Copyright (C) 2011-2015 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
const static float4x4 invX = float4x4(-1.0/6.0, 0.5, -1.0/3.0, 0.0,
0.5, -1.0, -0.5, 1.0,
-0.5, 0.5, 1.0, 0.0,
1.0/6.0, 0.0, -1.0/6.0, 0.0);
// Can't init statically from variable, even though it's const ...
//const static float4x4 invY = transpose(invX);
const static float4x4 invY = float4x4(-1.0/6.0, 0.5, -0.5, 1.0/6.0,
0.5, -1.0, 0.5, 0.0,
-1.0/3.0, -0.5, 1.0, -1.0/6.0,
0.0, 1.0, 0.0, 0.0);
struct input
{
float2 video_size;
float2 texture_size;
float2 output_size;
float frame_count;
float frame_direction;
float frame_rotation;
};
struct out_vertex
{
float2 texCoord : TEXCOORD0;
float4 t1 : TEXCOORD1;
float4 t2 : TEXCOORD2;
float4 t3 : TEXCOORD3;
float4 t4 : TEXCOORD4;
float4 t5 : TEXCOORD5;
float4 t6 : TEXCOORD6;
float4 t7 : TEXCOORD7;
float2 t8 : COLOR0;
};
/* VERTEX_SHADER */
void main_vertex
(
float4 position : POSITION,
float2 texCoord1 : TEXCOORD0,
uniform float4x4 modelViewProj,
uniform input IN,
out float4 oPosition : POSITION,
out out_vertex oVAR
)
{
float2 ps = float2(1.0/IN.texture_size.x, 1.0/IN.texture_size.y);
float dx = ps.x;
float dy = ps.y;
oPosition = mul(modelViewProj, position);
// This line fix a bug in ATI cards.
float2 tex = texCoord1 + float2(0.0000001, 0.0000001);
out_vertex OUT =
{
tex,
float4(tex,tex) + float4( -dx, -dy, 0.0, -dy),
float4(tex,tex) + float4( dx, -dy, 2.0*dx, -dy),
float4(tex,tex) + float4( -dx, 0.0, dx, 0.0),
float4(tex,tex) + float4(2.0*dx, 0.0, -dx, dy),
float4(tex,tex) + float4( 0.0, dy, dx, dy),
float4(tex,tex) + float4(2.0*dx, dy, -dx, 2.0*dy),
float4(tex,tex) + float4( 0.0, 2.0*dy, dx, 2.0*dy),
tex + float2(2.0*dx, 2.0*dy)
};
oVAR = OUT;
}
float4 main_fragment(in float4 vpos : POSITION, in out_vertex VAR, uniform sampler2D s_p : TEXUNIT0, uniform input IN) : COLOR
{
float2 fp = frac(VAR.texCoord*IN.texture_size);
float3 c00 = tex2D(s_p, VAR.t1.xy).xyz;
float3 c01 = tex2D(s_p, VAR.t1.zw).xyz;
float3 c02 = tex2D(s_p, VAR.t2.xy).xyz;
float3 c03 = tex2D(s_p, VAR.t2.zw).xyz;
float3 c10 = tex2D(s_p, VAR.t3.xy).xyz;
float3 c11 = tex2D(s_p, VAR.texCoord).xyz;
float3 c12 = tex2D(s_p, VAR.t3.zw).xyz;
float3 c13 = tex2D(s_p, VAR.t4.xy).xyz;
float3 c20 = tex2D(s_p, VAR.t4.zw).xyz;
float3 c21 = tex2D(s_p, VAR.t5.xy).xyz;
float3 c22 = tex2D(s_p, VAR.t5.zw).xyz;
float3 c23 = tex2D(s_p, VAR.t6.xy).xyz;
float3 c30 = tex2D(s_p, VAR.t6.zw).xyz;
float3 c31 = tex2D(s_p, VAR.t7.xy).xyz;
float3 c32 = tex2D(s_p, VAR.t7.zw).xyz;
float3 c33 = tex2D(s_p, VAR.t8.xy).xyz;
float4x4 red_matrix = float4x4(c00.x, c01.x, c02.x, c03.x,
c10.x, c11.x, c12.x, c13.x,
c20.x, c21.x, c22.x, c23.x,
c30.x, c31.x, c32.x, c33.x);
float4x4 green_matrix = float4x4(c00.y, c01.y, c02.y, c03.y,
c10.y, c11.y, c12.y, c13.y,
c20.y, c21.y, c22.y, c23.y,
c30.y, c31.y, c32.y, c33.y);
float4x4 blue_matrix = float4x4(c00.z, c01.z, c02.z, c03.z,
c10.z, c11.z, c12.z, c13.z,
c20.z, c21.z, c22.z, c23.z,
c30.z, c31.z, c32.z, c33.z);
float4x1 invX_Px = mul(invX, float4x1(fp.x*fp.x*fp.x, fp.x*fp.x, fp.x, 1.0));
float1x4 Py_invY = mul(float1x4(fp.y*fp.y*fp.y, fp.y*fp.y, fp.y, 1.0), invY);
float red = mul(Py_invY, mul( red_matrix, invX_Px));
float green = mul(Py_invY, mul(green_matrix, invX_Px));
float blue = mul(Py_invY, mul( blue_matrix, invX_Px));
return float4(red, green, blue, 1.0);
}

View File

@ -0,0 +1,151 @@
/* COMPATIBILITY
- HLSL compilers
- Cg compilers
*/
/*
Copyright (C) 2010 Team XBMC
http://www.xbmc.org
Copyright (C) 2011 Stefanos A.
http://www.opentk.com
This Program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This Program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with XBMC; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
http://www.gnu.org/copyleft/gpl.html
From this forum post:
http://board.byuu.org/viewtopic.php?p=33488#p33488
*/
/* Default Vertex shader */
void main_vertex
(
float4 position : POSITION,
//float4 color : COLOR,
float2 texCoord1 : TEXCOORD0,
uniform float4x4 modelViewProj,
out float4 oPosition : POSITION,
//out float4 oColor : COLOR,
out float2 otexCoord : TEXCOORD
)
{
oPosition = mul(modelViewProj, position);
//oColor = color;
otexCoord = texCoord1;
}
struct output
{
float4 color : COLOR;
};
struct input
{
float2 video_size;
float2 texture_size;
float2 output_size;
float frame_count;
float frame_direction;
float frame_rotation;
};
float weight(float x)
{
float ax = abs(x);
// Mitchel-Netravali coefficients.
// Best psychovisual result.
const float B = 1.0 / 3.0;
const float C = 1.0 / 3.0;
// Sharper version.
// May look better in some cases.
//const float B = 0.0;
//const float C = 0.75;
if (ax < 1.0)
{
return
(
pow(x, 2.0) * ((12.0 - 9.0 * B - 6.0 * C) * ax + (-18.0 + 12.0 * B + 6.0 * C)) +
(6.0 - 2.0 * B)
) / 6.0;
}
else if ((ax >= 1.0) && (ax < 2.0))
{
return
(
pow(x, 2.0) * ((-B - 6.0 * C) * ax + (6.0 * B + 30.0 * C)) +
(-12.0 * B - 48.0 * C) * ax + (8.0 * B + 24.0 * C)
) / 6.0;
}
else
{
return 0.0;
}
}
float4 weight4(float x)
{
return float4(
weight(x - 2.0),
weight(x - 1.0),
weight(x),
weight(x + 1.0));
}
float3 pixel(float xpos, float ypos, uniform sampler2D s_p)
{
return tex2D(s_p, float2(xpos, ypos)).rgb;
}
float3 line_run(float ypos, float4 xpos, float4 linetaps, uniform sampler2D s_p)
{
return
pixel(xpos.r, ypos, s_p) * linetaps.r +
pixel(xpos.g, ypos, s_p) * linetaps.g +
pixel(xpos.b, ypos, s_p) * linetaps.b +
pixel(xpos.a, ypos, s_p) * linetaps.a;
}
output main_fragment (float2 tex : TEXCOORD0, uniform input IN, uniform sampler2D s_p : TEXUNIT0)
{
float2 stepxy = float2(1.0/IN.texture_size.x, 1.0/IN.texture_size.y);
float2 pos = tex.xy + stepxy * 0.5;
float2 f = frac(pos / stepxy);
float4 linetaps = weight4(1.0 - f.x);
float4 columntaps = weight4(1.0 - f.y);
//make sure all taps added together is exactly 1.0, otherwise some (very small) distortion can occur
linetaps /= linetaps.r + linetaps.g + linetaps.b + linetaps.a;
columntaps /= columntaps.r + columntaps.g + columntaps.b + columntaps.a;
float2 xystart = (-1.5 - f) * stepxy + pos;
float4 xpos = float4(xystart.x, xystart.x + stepxy.x, xystart.x + stepxy.x * 2.0, xystart.x + stepxy.x * 3.0);
// final sum and weight normalization
output OUT;
OUT.color = float4(line_run(xystart.y , xpos, linetaps, s_p) * columntaps.r +
line_run(xystart.y + stepxy.y , xpos, linetaps, s_p) * columntaps.g +
line_run(xystart.y + stepxy.y * 2.0, xpos, linetaps, s_p) * columntaps.b +
line_run(xystart.y + stepxy.y * 3.0, xpos, linetaps, s_p) * columntaps.a,1);
return OUT;
}

View File

@ -1,147 +0,0 @@
/* COMPATIBILITY
- HLSL compilers
- Cg compilers
*/
/*
Copyright (C) 2010 Team XBMC
http://www.xbmc.org
Copyright (C) 2011 Stefanos A.
http://www.opentk.com
This Program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This Program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with XBMC; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
http://www.gnu.org/copyleft/gpl.html
From this forum post:
http://board.byuu.org/viewtopic.php?p=33488#p33488
*/
/* Default Vertex shader */
void main_vertex
(
float4 position : POSITION,
float2 texCoord1 : TEXCOORD0,
uniform float4x4 modelViewProj,
out float4 oPosition : POSITION,
out float2 otexCoord : TEXCOORD
)
{
oPosition = mul(modelViewProj, position);
otexCoord = texCoord1;
}
struct output
{
float4 color : COLOR;
};
struct input
{
float2 video_size;
float2 texture_size;
float2 output_size;
float frame_count;
float frame_direction;
float frame_rotation;
};
float weight(float x)
{
float ax = abs(x);
// Mitchel-Netravali coefficients.
// Best psychovisual result.
const float B = 1.0 / 3.0;
const float C = 1.0 / 3.0;
// Sharper version.
// May look better in some cases.
//const float B = 0.0;
//const float C = 0.75;
if (ax < 1.0)
{
return
(
pow(x, 2.0) * ((12.0 - 9.0 * B - 6.0 * C) * ax + (-18.0 + 12.0 * B + 6.0 * C)) +
(6.0 - 2.0 * B)
) / 6.0;
}
else if ((ax >= 1.0) && (ax < 2.0))
{
return
(
pow(x, 2.0) * ((-B - 6.0 * C) * ax + (6.0 * B + 30.0 * C)) +
(-12.0 * B - 48.0 * C) * ax + (8.0 * B + 24.0 * C)
) / 6.0;
}
else
{
return 0.0;
}
}
float4 weight4(float x)
{
return float4(
weight(x - 2.0),
weight(x - 1.0),
weight(x),
weight(x + 1.0));
}
float3 pixel(float xpos, float ypos, uniform sampler2D s_p)
{
return tex2D(s_p, float2(xpos, ypos)).rgb;
}
float3 line_run(float ypos, float4 xpos, float4 linetaps, uniform sampler2D s_p)
{
return
pixel(xpos.r, ypos, s_p) * linetaps.r +
pixel(xpos.g, ypos, s_p) * linetaps.g +
pixel(xpos.b, ypos, s_p) * linetaps.b +
pixel(xpos.a, ypos, s_p) * linetaps.a;
}
output main_fragment (in float4 vpos : POSITION, float2 tex : TEXCOORD0, uniform input IN, uniform sampler2D s_p : TEXUNIT0)
{
float2 stepxy = float2(1.0/IN.texture_size.x, 1.0/IN.texture_size.y);
float2 pos = tex.xy + stepxy * 0.5;
float2 f = frac(pos / stepxy);
float4 linetaps = weight4(1.0 - f.x);
float4 columntaps = weight4(1.0 - f.y);
//make sure all taps added together is exactly 1.0, otherwise some (very small) distortion can occur
linetaps /= linetaps.r + linetaps.g + linetaps.b + linetaps.a;
columntaps /= columntaps.r + columntaps.g + columntaps.b + columntaps.a;
float2 xystart = (-1.5 - f) * stepxy + pos;
float4 xpos = float4(xystart.x, xystart.x + stepxy.x, xystart.x + stepxy.x * 2.0, xystart.x + stepxy.x * 3.0);
// final sum and weight normalization
output OUT;
OUT.color = float4(line_run(xystart.y , xpos, linetaps, s_p) * columntaps.r +
line_run(xystart.y + stepxy.y , xpos, linetaps, s_p) * columntaps.g +
line_run(xystart.y + stepxy.y * 2.0, xpos, linetaps, s_p) * columntaps.b +
line_run(xystart.y + stepxy.y * 3.0, xpos, linetaps, s_p) * columntaps.a,1);
return OUT;
}

View File

@ -1,4 +0,0 @@
shaders = 1
shader0 = bsnes-gamma.cg
scale0 = 1

View File

@ -1,56 +0,0 @@
//https://raw.githubusercontent.com/Themaister/Emulator-Shader-Pack/master/Cg/TV/gamma.cg
/*
Author: Themaister
License: Public domain
*/
// Shader that replicates gamma-ramp of bSNES/Higan.
#ifdef VERTEX
uniform mat4 MVPMatrix;
in vec4 VertexCoord;
in vec2 TexCoord;
out vec2 vTex;
void main()
{
gl_Position = MVPMatrix * VertexCoord;
vTex = TexCoord;
}
#endif
#ifdef FRAGMENT
uniform sampler2D s_p;
in vec2 vTex;
out vec4 FragColor;
// Tweakables.
#define saturation 1.0
#define gamma 1.5
#define luminance 1.0
vec3 grayscale(vec3 col)
{
// Non-conventional way to do grayscale,
// but bSNES uses this as grayscale value.
float v = dot(col, vec3(0.3333,0.3333,0.3333));
return vec3(v,v,v);
}
void main()
{
vec3 res = texture(s_p,vTex).xyz;
res = mix(grayscale(res), res, saturation); // Apply saturation
res = pow(res, vec3(gamma,gamma,gamma)); // Apply gamma
FragColor = vec4(clamp(res * luminance,0.0,1.0), 1.0);
}
#endif

View File

@ -1,45 +0,0 @@
//https://raw.githubusercontent.com/Themaister/Emulator-Shader-Pack/master/Cg/TV/gamma.cg
/*
Author: Themaister
License: Public domain
*/
// Shader that replicates gamma-ramp of bSNES/Higan.
void main_vertex
(
float4 position : POSITION,
float2 tex : TEXCOORD,
uniform float4x4 modelViewProj,
out float4 oPosition : POSITION,
out float2 oTex : TEXCOORD
)
{
oPosition = mul(modelViewProj, position);
oTex = tex;
}
// Tweakables.
#define saturation 1.0
#define gamma 1.5
#define luminance 1.0
float3 grayscale(float3 col)
{
// Non-conventional way to do grayscale,
// but bSNES uses this as grayscale value.
float v = dot(col, float3(0.3333,0.3333,0.3333));
return float3(v,v,v);
}
float4 main_fragment(in float4 vpos : POSITION, in float2 tex : TEXCOORD, uniform sampler2D s0 : TEXUNIT0) : COLOR
{
float3 res = tex2D(s0, tex).xyz;
res = lerp(grayscale(res), res, saturation); // Apply saturation
res = pow(res, float3(gamma,gamma,gamma)); // Apply gamma
return float4(saturate(res * luminance), 1.0);
}

View File

@ -0,0 +1,95 @@
struct tex_coords
{
float2 c00 : TEXCOORD0;
float2 c01 : TEXCOORD1;
float2 c02 : TEXCOORD2;
float2 c10 : TEXCOORD3;
float2 c11 : TEXCOORD4;
float2 c12 : TEXCOORD5;
float2 c20 : TEXCOORD6;
float2 c21 : TEXCOORD7;
float2 c22 : COLOR0;
};
struct input
{
float2 video_size;
float2 texture_size;
float2 output_size;
};
void main_vertex
(
float4 position : POSITION,
out float4 oPosition : POSITION,
uniform float4x4 modelViewProj,
float2 tex : TEXCOORD,
uniform input IN,
out tex_coords coords
)
{
oPosition = mul(modelViewProj, position);
float2 texsize = IN.texture_size;
float2 delta = 0.5 / texsize;
float dx = delta.x;
float dy = delta.y;
coords = tex_coords (
tex + float2(-dx, -dy),
tex + float2(-dx, 0),
tex + float2(-dx, dy),
tex + float2(0, -dy),
tex + float2(0, 0),
tex + float2(0, dy),
tex + float2(dx, -dy),
tex + float2(dx, 0),
tex + float2(dx, dy)
);
}
const float mx = 0.325; // start smoothing wt.
const float k = -0.250; // wt. decrease factor
const float max_w = 0.25; // max filter weigth
const float min_w = -0.05; // min filter weigth
const float lum_add = 0.25; // effects smoothing
float4 main_fragment (in tex_coords co, uniform sampler2D s_p : TEXUNIT0) : COLOR
{
float3 c00 = tex2D(s_p, co.c00).xyz;
float3 c01 = tex2D(s_p, co.c01).xyz;
float3 c02 = tex2D(s_p, co.c02).xyz;
float3 c10 = tex2D(s_p, co.c10).xyz;
float3 c11 = tex2D(s_p, co.c11).xyz;
float3 c12 = tex2D(s_p, co.c12).xyz;
float3 c20 = tex2D(s_p, co.c20).xyz;
float3 c21 = tex2D(s_p, co.c21).xyz;
float3 c22 = tex2D(s_p, co.c22).xyz;
float3 dt = float3(1.0);
float md1 = dot(abs(c00 - c22), dt);
float md2 = dot(abs(c02 - c20), dt);
float w1 = dot(abs(c22 - c11), dt) * md2;
float w2 = dot(abs(c02 - c11), dt) * md1;
float w3 = dot(abs(c00 - c11), dt) * md2;
float w4 = dot(abs(c20 - c11), dt) * md1;
float t1 = w1 + w3;
float t2 = w2 + w4;
float ww = max(t1, t2) + 0.0001;
c11 = (w1 * c00 + w2 * c20 + w3 * c22 + w4 * c02 + ww * c11) / (t1 + t2 + ww);
float lc1 = k / (0.12 * dot(c10 + c12 + c11, dt) + lum_add);
float lc2 = k / (0.12 * dot(c01 + c21 + c11, dt) + lum_add);
w1 = clamp(lc1 * dot(abs(c11 - c10), dt) + mx, min_w, max_w);
w2 = clamp(lc2 * dot(abs(c11 - c21), dt) + mx, min_w, max_w);
w3 = clamp(lc1 * dot(abs(c11 - c12), dt) + mx, min_w, max_w);
w4 = clamp(lc2 * dot(abs(c11 - c01), dt) + mx, min_w, max_w);
return float4(w1 * c10 + w2 * c21 + w3 * c12 + w4 * c01 + (1.0 - w1 - w2 - w3 - w4) * c11, 1.0);
}

View File

@ -1,90 +0,0 @@
uniform struct
{
vec2 video_size;
vec2 texture_size;
vec2 output_size;
} IN;
#ifdef VERTEX
uniform mat4 MVPMatrix;
in vec4 VertexCoord;
in vec2 TexCoord;
out vec2 coords[9];
void main()
{
gl_Position = MVPMatrix * VertexCoord;
vec2 texsize = IN.texture_size;
vec2 delta = 0.5 / texsize;
float dx = delta.x;
float dy = delta.y;
coords[0] = TexCoord + vec2(-dx, -dy);
coords[1] = TexCoord + vec2(-dx, 0.0);
coords[2] = TexCoord + vec2(-dx, dy);
coords[3] = TexCoord + vec2(0.0, -dy);
coords[4] = TexCoord + vec2(0.0, 0.0);
coords[5] = TexCoord + vec2(0.0, dy);
coords[6] = TexCoord + vec2(dx, -dy);
coords[7] = TexCoord + vec2(dx, 0);
coords[8] = TexCoord + vec2(dx, dy);
}
#endif
#ifdef FRAGMENT
uniform sampler2D s_p;
in vec2 coords[9];
out vec4 FragColor;
const float mx = 0.325; // start smoothing wt.
const float k = -0.250; // wt. decrease factor
const float max_w = 0.25; // max filter weigth
const float min_w = -0.05; // min filter weigth
const float lum_add = 0.25; // effects smoothing
void main()
{
vec3 c00 = texture(s_p, coords[0]).xyz;
vec3 c01 = texture(s_p, coords[1]).xyz;
vec3 c02 = texture(s_p, coords[2]).xyz;
vec3 c10 = texture(s_p, coords[3]).xyz;
vec3 c11 = texture(s_p, coords[4]).xyz;
vec3 c12 = texture(s_p, coords[5]).xyz;
vec3 c20 = texture(s_p, coords[6]).xyz;
vec3 c21 = texture(s_p, coords[7]).xyz;
vec3 c22 = texture(s_p, coords[8]).xyz;
vec3 dt = vec3(1.0,1.0,1.0);
float md1 = dot(abs(c00 - c22), dt);
float md2 = dot(abs(c02 - c20), dt);
float w1 = dot(abs(c22 - c11), dt) * md2;
float w2 = dot(abs(c02 - c11), dt) * md1;
float w3 = dot(abs(c00 - c11), dt) * md2;
float w4 = dot(abs(c20 - c11), dt) * md1;
float t1 = w1 + w3;
float t2 = w2 + w4;
float ww = max(t1, t2) + 0.0001;
c11 = (w1 * c00 + w2 * c20 + w3 * c22 + w4 * c02 + ww * c11) / (t1 + t2 + ww);
float lc1 = k / (0.12 * dot(c10 + c12 + c11, dt) + lum_add);
float lc2 = k / (0.12 * dot(c01 + c21 + c11, dt) + lum_add);
w1 = clamp(lc1 * dot(abs(c11 - c10), dt) + mx, min_w, max_w);
w2 = clamp(lc2 * dot(abs(c11 - c21), dt) + mx, min_w, max_w);
w3 = clamp(lc1 * dot(abs(c11 - c12), dt) + mx, min_w, max_w);
w4 = clamp(lc2 * dot(abs(c11 - c01), dt) + mx, min_w, max_w);
FragColor = vec4(w1 * c10 + w2 * c21 + w3 * c12 + w4 * c01 + (1.0 - w1 - w2 - w3 - w4) * c11, 1.0);
}
#endif

View File

@ -1,93 +0,0 @@
struct tex_coords
{
float2 c00 : TEXCOORD0;
float2 c01 : TEXCOORD1;
float2 c02 : TEXCOORD2;
float2 c10 : TEXCOORD3;
float2 c11 : TEXCOORD4;
float2 c12 : TEXCOORD5;
float2 c20 : TEXCOORD6;
float2 c21 : TEXCOORD7;
float2 c22 : COLOR0;
};
struct input
{
float2 video_size;
float2 texture_size;
float2 output_size;
};
void main_vertex
(
float4 position : POSITION,
float2 tex : TEXCOORD0,
uniform float4x4 modelViewProj,
uniform input IN,
out float4 oPosition : POSITION,
out tex_coords coords
)
{
oPosition = mul(modelViewProj, position);
float2 texsize = IN.texture_size;
float2 delta = 0.5 / texsize;
float dx = delta.x;
float dy = delta.y;
coords.c00 = tex + float2(-dx, -dy);
coords.c01 = tex + float2(-dx, 0.0);
coords.c02 = tex + float2(-dx, dy);
coords.c10 = tex + float2(0.0, -dy);
coords.c11 = tex + float2(0.0, 0.0);
coords.c12 = tex + float2(0.0, dy);
coords.c20 = tex + float2(dx, -dy);
coords.c21 = tex + float2(dx, 0);
coords.c22 = tex + float2(dx, dy);
}
static const float mx = 0.325; // start smoothing wt.
static const float k = -0.250; // wt. decrease factor
static const float max_w = 0.25; // max filter weigth
static const float min_w = -0.05; // min filter weigth
static const float lum_add = 0.25; // effects smoothing
float4 main_fragment (in float4 vpos : POSITION, in tex_coords co, uniform sampler2D s_p : TEXUNIT0) : COLOR
{
float3 c00 = tex2D(s_p, co.c00).xyz;
float3 c01 = tex2D(s_p, co.c01).xyz;
float3 c02 = tex2D(s_p, co.c02).xyz;
float3 c10 = tex2D(s_p, co.c10).xyz;
float3 c11 = tex2D(s_p, co.c11).xyz;
float3 c12 = tex2D(s_p, co.c12).xyz;
float3 c20 = tex2D(s_p, co.c20).xyz;
float3 c21 = tex2D(s_p, co.c21).xyz;
float3 c22 = tex2D(s_p, co.c22).xyz;
float3 dt = float3(1.0,1.0,1.0);
float md1 = dot(abs(c00 - c22), dt);
float md2 = dot(abs(c02 - c20), dt);
float w1 = dot(abs(c22 - c11), dt) * md2;
float w2 = dot(abs(c02 - c11), dt) * md1;
float w3 = dot(abs(c00 - c11), dt) * md2;
float w4 = dot(abs(c20 - c11), dt) * md1;
float t1 = w1 + w3;
float t2 = w2 + w4;
float ww = max(t1, t2) + 0.0001;
c11 = (w1 * c00 + w2 * c20 + w3 * c22 + w4 * c02 + ww * c11) / (t1 + t2 + ww);
float lc1 = k / (0.12 * dot(c10 + c12 + c11, dt) + lum_add);
float lc2 = k / (0.12 * dot(c01 + c21 + c11, dt) + lum_add);
w1 = clamp(lc1 * dot(abs(c11 - c10), dt) + mx, min_w, max_w);
w2 = clamp(lc2 * dot(abs(c11 - c21), dt) + mx, min_w, max_w);
w3 = clamp(lc1 * dot(abs(c11 - c12), dt) + mx, min_w, max_w);
w4 = clamp(lc2 * dot(abs(c11 - c01), dt) + mx, min_w, max_w);
return float4(w1 * c10 + w2 * c21 + w3 * c12 + w4 * c01 + (1.0 - w1 - w2 - w3 - w4) * c11, 1.0);
}

View File

@ -1,4 +0,0 @@
shaders = 1
shader0 = retroizer.cg
scale0 = 6

View File

@ -1,224 +0,0 @@
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
////
//// VERTEX SHADER : STOLEN FROM NEIGHBOURING SHADERS
////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
#ifdef VERTEX
uniform mat4 MVPMatrix;
in vec4 VertexCoord;
in vec2 TexCoord;
out vec2 vTexcoord;
void main()
{
gl_Position = MVPMatrix * VertexCoord;
vTexcoord = TexCoord;
}
#endif //VERTEX
#ifdef FRAGMENT
uniform struct
{
vec2 video_size;
vec2 texture_size;
vec2 output_size;
} IN;
uniform float Time;
uniform sampler2D s_p;
in vec2 vTexcoord;
out vec4 FragColor;
float saturate(float x)
{
return max(0, min(1, x));
}
vec2 saturate(vec2 x)
{
return max(vec2(0.0,0.0), min(vec2(1.0,1.0), x));
}
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
//// EFFECT CONSTANTS : TWEAK THEM!
////
// Size of the border effect
const vec2 OverscanMaskHardness = vec2(12.0f ,12.0f );
// Attenuation of the border effect
const float OverscanMaskPower = 4.0f;
// Intensity of the border effect
const float OverscanIntensity = 0.96f;
// Intensity of the TV Corners (round-ness) deformation
const float TVDeformInstensity = 0.02f;
// How much R, G and B are offset : default is -0.333 pixels in fake-pixel-space
const float ColorFringeIntensity = -0.666;
// How much luminosity is output by a fake-pixel
const float FakePixelMaskGain = 0.75f;
// How much luminosity is output between fake-pixels (adds to the fake-pixel value)
const float FakePixelMaskOffset = 0.55f;
// How sharp will appear the pixels (Horizontal Sharpness, Vertical Sharpness A.K.A Scanlines)
const vec2 FakePixelMaskPower = vec2(0.150f ,2.0f );
// Scanline Off Sync (Slides one line out of two)
const float ScanlineOffSync = 0.25;
// Base Brightness
const float BaseBrightness = 0.55f;
// How much the Fake-Pixel effect is Active (0.0 = normal image, 1.0 = full FakePixel Effect)
const float FakePixelEffectBlend = 0.95f;
// Ghost Sampling : enable define to activate
#define GHOST_SAMPLING;
const float GhostLatencyIntensity = 0.03f;
// Number of samples (higer is slower)
const int GhostNumSamples = 32;
// Latency of the RGB Signal (per-signal, in screen width percentage)
const vec3 SignalLatencyRGB = vec3(0.184f,0.08f,0.0624f);
// Attenuation of the ghosting latency
const float SignalLatencyAttenuation = 1.0f;
// Bloom : enable define to activate
#define BLOOM;
const float BloomIntensity = 0.75f;
const float BloomExponent = 1.00f;
const float BloomWeights[25] = float[] (
0.003765, 0.015019, 0.023792, 0.015019, 0.003765,
0.015019, 0.059912, 0.094907, 0.059912, 0.015019,
0.023792, 0.094907, 0.150342, 0.094907, 0.023792,
0.015019, 0.059912, 0.094907, 0.059912, 0.015019,
0.003765, 0.015019, 0.023792, 0.015019, 0.003765
);
const float BloomPositions[5] = float[] ( -2, -1, 0 , 1 , 2 );
////
////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
float expow(float value, float exponent) {
return mix(1.0f,pow(value,max(exponent,1.0f)),saturate(exponent));
}
//the code that calls expow() carefully builds vec2 for some reason and calls this only to have it implicitly thrown away (which is a warning)
//so this was added to get rid of the warning
float expow(vec2 value, vec2 exponent) {
return mix(1.0f,pow(value.x,max(exponent.x,1.0f)),saturate(exponent.x));
}
float expow(vec2 value, float exponent) {
return mix(1.0f,pow(value.x,max(exponent,1.0f)),saturate(exponent));
}
// MultiSampling for ghosting effect
vec3 GhostSample(vec2 t, float latency) {
vec3 Out = texture(s_p,t).rgb;
float Weight = 1.0f;
vec2 Direction = vec2(-latency,0.0f);
for(int i=1; i < GhostNumSamples; i++) {
float curweight = pow(1.0f-(float(i)/GhostNumSamples),1.0f/SignalLatencyAttenuation);
Out += GhostLatencyIntensity * curweight * texture(s_p,saturate(t+(1.0f-curweight)*Direction)).xyz;
Weight += GhostLatencyIntensity * curweight;
}
return Out/Weight;
}
// MultiSampling for ghosting effect
vec3 Bloom(vec2 t, vec2 r) {
vec3 Out = vec3(0,0,0);
for(int j = 0; j < 5; j++)
for(int i = 0; i < 5; i++)
{
vec2 offset = vec2(BloomPositions[i],BloomPositions[j]) / r;
Out += texture(s_p, t + offset).rgb * BloomWeights[i*5+j];
}
return pow(Out, vec3(BloomExponent,BloomExponent,BloomExponent)) * BloomIntensity;
}
// Compositing of the TV Emulation
vec3 TVEffect(vec2 in_Position, vec2 FakeResolution, float Time) {
// TV Deformation
vec2 ScreenPos = in_Position + dot(in_Position-0.5f,in_Position-0.5f)*(in_Position-0.5f)* TVDeformInstensity;
// Apply Off-Sync
ScreenPos += (ScanlineOffSync/FakeResolution.x) * vec2(sin((Time*30*3.1415926)+(ScreenPos.y*3.1415926*FakeResolution.y)),0);
// Sampling 3 Images biased to simulate TV RGB Offset
#ifdef GHOST_SAMPLING
vec3 latencyweight = vec3(0.0f,0.0f,0.0f);
for(int i=1; i < GhostNumSamples; i++) {
latencyweight += texture(s_p, ScreenPos + vec2(1.0f/FakeResolution.x,0.0f)).xyz;
}
vec3 LatencyRGB = SignalLatencyRGB * (1.0-(latencyweight/GhostNumSamples));
vec3 SMP_Red = GhostSample((ScreenPos),LatencyRGB.x).xyz;
vec3 SMP_Green = GhostSample((ScreenPos) + ((vec2(ColorFringeIntensity,0.0f))/FakeResolution),LatencyRGB.y).xyz;
vec3 SMP_Blue = GhostSample((ScreenPos) + ((vec2(ColorFringeIntensity*2.0f,0.0f))/FakeResolution),LatencyRGB.z).xyz;
#else
vec3 SMP_Red = texture(s_p, (ScreenPos)).xyz;
vec3 SMP_Green = texture(s_p, (ScreenPos) + ((vec2(ColorFringeIntensity,0.0f))/FakeResolution)).xyz;
vec3 SMP_Blue = texture(s_p, (ScreenPos) + ((vec2(ColorFringeIntensity*2.0f,0.0f))/FakeResolution)).xyz;
#endif
#ifdef BLOOM
vec3 bloom = Bloom(ScreenPos, FakeResolution);
SMP_Red += bloom.r;
SMP_Green += bloom.g;
SMP_Blue += bloom.b;
#endif
// Apply base Brightness
SMP_Red *= BaseBrightness;
SMP_Green *= BaseBrightness;
SMP_Blue *= BaseBrightness;
// Overscan Darkening Mask
float ScreenMaskPower = 1.0f/OverscanMaskPower;
vec2 ScreenMask = pow(saturate(ScreenPos*(1.0f-ScreenPos)*OverscanMaskHardness),vec2(ScreenMaskPower,ScreenMaskPower));
float mask = mix(1.0, ScreenMask.x * ScreenMask.y, OverscanIntensity);
// CRT Cell Masks (HorizontalRGB+Scanline)
float PixelMaskR = expow(saturate(4*fract(ScreenPos.x*FakeResolution.x)*(1.0f-fract(ScreenPos.x*FakeResolution.x))),FakePixelMaskPower.x);
float PixelMaskG = expow(saturate(4*fract(ScreenPos.x*FakeResolution.x+vec2(ColorFringeIntensity,0.0f))*(1.0f-fract(ScreenPos.x*FakeResolution.x+vec2(ColorFringeIntensity,0.0f)))),FakePixelMaskPower.x);
float PixelMaskB = expow(saturate(4*fract(ScreenPos.x*FakeResolution.x+vec2(ColorFringeIntensity*2.0f,0.0f))*(1.0f-fract(ScreenPos.x*FakeResolution.x+vec2(ColorFringeIntensity*2.0f,0.0f)))),FakePixelMaskPower.x);
float PixelMaskScanline = pow(saturate(4*fract(ScreenPos.y*FakeResolution.y)*(1.0f-fract(ScreenPos.y*FakeResolution.y))),FakePixelMaskPower.y);
vec3 PixelRGB = vec3 (
((PixelMaskR*PixelMaskScanline * FakePixelMaskGain)+FakePixelMaskOffset) * SMP_Red.x ,
((PixelMaskG*PixelMaskScanline * FakePixelMaskGain)+FakePixelMaskOffset) * SMP_Green.y ,
((PixelMaskB*PixelMaskScanline * FakePixelMaskGain)+FakePixelMaskOffset) * SMP_Blue.z
);
// Non-Pixelated Image
vec3 ImageRGB = texture(s_p, ScreenPos).xyz;
return mix(ImageRGB, PixelRGB, FakePixelEffectBlend) * mask;
}
void main()
{
vec4 color = vec4(1.0f,1.0f,1.0f,1.0f);
color.xyz = TVEffect(vTexcoord, IN.texture_size, Time);
FragColor = color;
}
#endif

View File

@ -1,216 +0,0 @@
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
////
//// VERTEX SHADER : STOLEN FROM NEIGHBOURING SHADERS
////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
struct input
{
float2 video_size;
float2 texture_size;
float2 output_size;
};
void main_vertex
(
float4 position : POSITION,
float2 tex : TEXCOORD0,
uniform float4x4 modelViewProj,
uniform input IN,
out float4 oPosition : POSITION,
out float2 oTexcoord : TEXCOORD0,
out float2 oFakeResolution : TEXCOORD1
)
{
oPosition = mul(modelViewProj, position);
oTexcoord = tex;
oFakeResolution = IN.texture_size;
}
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
//// EFFECT CONSTANTS : TWEAK THEM!
////
// Size of the border effect
static const float2 OverscanMaskHardness = {12.0f ,12.0f };
// Attenuation of the border effect
static const float OverscanMaskPower = 4.0f;
// Intensity of the border effect
static const float OverscanIntensity = 0.96f;
// Intensity of the TV Corners (round-ness) deformation
static const float TVDeformInstensity = 0.02f;
// How much R, G and B are offset : default is -0.333 pixels in fake-pixel-space
static const float ColorFringeIntensity = -0.666;
// How much luminosity is output by a fake-pixel
static const float FakePixelMaskGain = 0.75f;
// How much luminosity is output between fake-pixels (adds to the fake-pixel value)
static const float FakePixelMaskOffset = 0.55f;
// How sharp will appear the pixels (Horizontal Sharpness, Vertical Sharpness A.K.A Scanlines)
static const float2 FakePixelMaskPower = {0.150f ,2.0f };
// Scanline Off Sync (Slides one line out of two)
static const float ScanlineOffSync = 0.25;
// Base Brightness
static const float BaseBrightness = 0.55f;
// How much the Fake-Pixel effect is Active (0.0 = normal image, 1.0 = full FakePixel Effect)
static const float FakePixelEffectBlend = 0.95f;
// Ghost Sampling : enable define to activate
#define GHOST_SAMPLING;
static const float GhostLatencyIntensity = 0.03f;
// Number of samples (higer is slower)
static const int GhostNumSamples = 32;
// Latency of the RGB Signal (per-signal, in screen width percentage)
static const float3 SignalLatencyRGB = {0.184f,0.08f,0.0624f};
// Attenuation of the ghosting latency
static const float SignalLatencyAttenuation = 1.0f;
// Bloom : enable define to activate
#define BLOOM;
static const float BloomIntensity = 0.75f;
static const float BloomExponent = 1.00f;
static const float BloomWeights[5][5] =
{
{0.003765, 0.015019, 0.023792, 0.015019, 0.003765},
{0.015019, 0.059912, 0.094907, 0.059912, 0.015019},
{0.023792, 0.094907, 0.150342, 0.094907, 0.023792},
{0.015019, 0.059912, 0.094907, 0.059912, 0.015019},
{0.003765, 0.015019, 0.023792, 0.015019, 0.003765}
};
static const float BloomPositions[5] = { -2, -1, 0 , 1 , 2};
////
////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
float expow(float value, float exponent)
{
return lerp(1.0f,pow(value,max(exponent,1.0f)),saturate(exponent));
}
//the code that calls expow() carefully builds float2 for some reason and calls this only to have it implicitly thrown away (which is a warning)
//so this was added to get rid of the warning
float expow(float2 value, float2 exponent)
{
return lerp(1.0f,pow(value,max(exponent,1.0f)),saturate(exponent)).x;
}
// MultiSampling for ghosting effect
float3 GhostSample(sampler2D s, float2 t, float latency)
{
float3 Out = tex2D(s,t);
float Weight = 1.0f;
float2 Direction = float2(-latency,0.0f);
for(int i=1; i < GhostNumSamples; i++)
{
float curweight = pow(1.0f-((float)i/GhostNumSamples),1.0f/SignalLatencyAttenuation);
Out += GhostLatencyIntensity * curweight * tex2D(s,saturate(t+(1.0f-curweight)*Direction)).xyz;
Weight += GhostLatencyIntensity * curweight;
}
return Out/Weight;
}
// MultiSampling for ghosting effect
float3 Bloom(sampler2D s, float2 t, float2 r)
{
float3 Out = float3(0,0,0);
for(int j = 0; j < 5; j++)
{
for(int i = 0; i < 5; i++)
{
float2 offset = float2(BloomPositions[i],BloomPositions[j]) / r;
Out += tex2D(s, t + offset).rgb * BloomWeights[i][j];
}
}
return pow(Out, BloomExponent) * BloomIntensity;
}
// Compositing of the TV Emulation
float3 TVEffect(float2 in_Position, float2 FakeResolution, sampler2D Texture, float Time)
{
// TV Deformation
float2 ScreenPos = in_Position + dot(in_Position-0.5f,in_Position-0.5f)*(in_Position-0.5f)* TVDeformInstensity;
// Apply Off-Sync
ScreenPos += (ScanlineOffSync/FakeResolution.x) * float2(sin((Time*30*3.1415926)+(ScreenPos.y*3.1415926*FakeResolution.y)),0);
// Sampling 3 Images biased to simulate TV RGB Offset
#ifdef GHOST_SAMPLING
float3 latencyweight = float3(0.0f,0.0f,0.0f);
for(int i=1; i < GhostNumSamples; i++)
{
latencyweight += tex2D(Texture, ScreenPos + float2(1.0f/FakeResolution.x,0.0f)).xyz;
}
float3 LatencyRGB = SignalLatencyRGB * (1.0-(latencyweight/GhostNumSamples));
float3 SMP_Red = GhostSample(Texture, (ScreenPos),LatencyRGB.x).xyz;
float3 SMP_Green = GhostSample(Texture, (ScreenPos) + ((float2(ColorFringeIntensity,0.0f))/FakeResolution),LatencyRGB.y).xyz;
float3 SMP_Blue = GhostSample(Texture, (ScreenPos) + ((float2(ColorFringeIntensity*2.0f,0.0f))/FakeResolution),LatencyRGB.z).xyz;
#else
float3 SMP_Red = tex2D(Texture, (ScreenPos)).xyz;
float3 SMP_Green = tex2D(Texture, (ScreenPos) + ((float2(ColorFringeIntensity,0.0f))/FakeResolution)).xyz;
float3 SMP_Blue = tex2D(Texture, (ScreenPos) + ((float2(ColorFringeIntensity*2.0f,0.0f))/FakeResolution)).xyz;
#endif
#ifdef BLOOM
float3 bloom = Bloom(Texture, ScreenPos, FakeResolution);
SMP_Red += bloom.r;
SMP_Green += bloom.g;
SMP_Blue += bloom.b;
#endif
// Apply base Brightness
SMP_Red *= BaseBrightness;
SMP_Green *= BaseBrightness;
SMP_Blue *= BaseBrightness;
// Overscan Darkening Mask
float2 ScreenMask = pow(saturate(ScreenPos*(1.0f-ScreenPos)*OverscanMaskHardness),1.0f/OverscanMaskPower);
float mask = lerp(1.0, ScreenMask.x * ScreenMask.y, OverscanIntensity);
// CRT Cell Masks (HorizontalRGB+Scanline)
float PixelMaskR = expow(saturate(4*frac(ScreenPos.x*FakeResolution.x)*(1.0f-frac(ScreenPos.x*FakeResolution.x))),FakePixelMaskPower.x);
float PixelMaskG = expow(saturate(4*frac(ScreenPos.x*FakeResolution.x+float2(ColorFringeIntensity,0.0f))*(1.0f-frac(ScreenPos.x*FakeResolution.x+float2(ColorFringeIntensity,0.0f)))),FakePixelMaskPower.x);
float PixelMaskB = expow(saturate(4*frac(ScreenPos.x*FakeResolution.x+float2(ColorFringeIntensity*2.0f,0.0f))*(1.0f-frac(ScreenPos.x*FakeResolution.x+float2(ColorFringeIntensity*2.0f,0.0f)))),FakePixelMaskPower.x);
float PixelMaskScanline = pow(saturate(4*frac(ScreenPos.y*FakeResolution.y)*(1.0f-frac(ScreenPos.y*FakeResolution.y))),FakePixelMaskPower.y);
float3 PixelRGB = float3(((PixelMaskR*PixelMaskScanline * FakePixelMaskGain)+FakePixelMaskOffset) * SMP_Red.x,
((PixelMaskG*PixelMaskScanline * FakePixelMaskGain)+FakePixelMaskOffset) * SMP_Green.y,
((PixelMaskB*PixelMaskScanline * FakePixelMaskGain)+FakePixelMaskOffset) * SMP_Blue.z);
// Non-Pixelated Image
float3 ImageRGB = tex2D(Texture, ScreenPos).xyz;
return lerp(ImageRGB, PixelRGB, FakePixelEffectBlend) * mask;
//return float3(PixelMaskR*PixelMaskScanline,PixelMaskG*PixelMaskScanline,PixelMaskB*PixelMaskScanline);
}
float4 main_fragment
(
in float4 vpos : POSITION,
in float2 TexCoord : TEXCOORD0,
in float2 FakeResolution : TEXCOORD1,
uniform sampler2D s_p : TEXUNIT0,
uniform float Time
) : COLOR
{
float4 color = float4(1.0f,1.0f,1.0f,1.0f);
color.xyz = TVEffect(TexCoord,FakeResolution, s_p, Time);
return color;
}

View File

@ -1,16 +0,0 @@
Despite using the "cgp" derived "retro shader" approach, we're doing things a bit different than retroarch.
A single .cgp file is used for any graphics backend. The shader references inside it can be written extensionless, or with .cg (or with .hlsl or .glsl for reasons, read on)
In case you have shaders that work only GLSL or HLSL -- well, they simply won't work in the wrong mode.
In that case, try something like bizhawkdir/Shaders/myshaders/glsl/mybadshader.cgp
In this case, the .cgp can reference .glsl shaders internally.
An important point, which you will perceive by checking out the bizhawk shaders, is that a .cgp is now portable due to the extension-ignorant behaviour AND the separate .glsl and .hlsl extensions.
(For instance, BizScanlines.cgp+BizScanlines.hlsl+BizScanlines.glsl).
The separate extensions let there be separate shaders for each backend, each referenced by the same cgp which references .cg (arbitrarily; it could be blank)
However if the .cgp referenced a .glsl, it wouldn't work on D3D.
In case you haven't pieced it together yet, this means there is no automatic mechanism for transpiling shaders. It isn't reliable and created an unmaintainable, slow, mess.
Porting shaders from retroarch will require touching them extensively, probably.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
Assets/dll/cgc.exe Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More