Giter VIP home page Giter VIP logo

notorious_beeg's Introduction

gba emu

gb / gbc / gba emulator witten in c++23.

Img Img
Img Img
Img Img

Img

notable features:

  • reasonably accurate gba emulation, most games should just work.
  • waitloop detection. can remove most idle loops which improves performance.
  • very fast gb/gbc emulation.
  • reasonably accurate gb/gbc emulation.
  • complete ezflash emulation, this is the only emulator with this feature.
  • emulation of most fat devices used in dkp libfat. this means you can access files from a virtual sd card with homebrew. i believe this is the only emulator that supports this.

building

a c++23 compiler is needed (gcc12+ clang15+ msvc12+) and cmake.

sdl2 vcpkg (simple frontend)

cmake --preset sdl2-vcpkg
cmake --build --preset sdl2-vcpkg

imgui vcpkg (complex debugger frontend)

cmake --preset imgui-vcpkg
cmake --build --preset imgui-vcpkg

you can checkout the rest of the presets in

there are a number of presets to help with building


web builds

web builds are the easiest way to quickly test a game. builds are automatically built from master. please report any bugs you find, giving as much info as possible such as browser, os, game etc.

gh-pages version doesn't support threads / mutexs. may crash.

netlify version supports threads / mutexes, won't crash.


yet to implement

list of stuff that i haven't yet implemented. for the most part, everything is done!

ppu

  • mosaic bg
  • mosaic obj

apu

dma

  • dma3 special

misc

  • correct openbus behaviour
  • correct rom access timings
  • lots of optimisations. ppu rendering is not optimised at all. dma can be further optimised. mem access can be better optimised for vram and bios access

thanks

notorious_beeg's People

Contributors

itotaljustice avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

notorious_beeg's Issues

implement open bus

firstly i need to find a test rom / game (ideally test rom) that uses open bus behaviour

rewrite dma code

current code is too complicated for what it actually does, the control flow is hard to reason about and very easily bugs can creep in.

[minish cap] text missing from intro

the text is missing from the intro. haven't looked into it yet, but likely is a priority issue.

image

as can be seen, the text is rendered on layer 1, but bg2 seems to be layered on top. again, need to check what the priority is.

sample at freq higher than 32k

64k seems like a reasonable max sample rate as most games use either 32k or 64k.

games that use the gb apu will often set sample rate to 64k, pokemon emerald in particular does this

[Pokemon Emerald] player cannot move left / right when already moving in a up/down direction

if the player is walking forward, then right is pressed, on the gba the player would move right. after releasing right, the player continues to walk forward.

this doesnt happen in my emulator. my guess is that what actually happens on the gba is that the dpad is a rocker, so pressing a direction only presses that single direction.

this is easy to replicate the gba with any controller, but on pc with a keyboard, not so much.

not sure the best path to handle this. i guess having 2 copies of the keystate. when a direction is set, set it. when another direction is set whilst the current direction is set, save the current keystate to the copy, then unset that direction and set the new direction. upon releasing that new direction, load back the previous keystate.

optimise ppu rendering

in emerald, without rendering: 1k fps
with rendering: 450-460 fps

thats just over half of my fps gone just because of rendering 160 times a frame.

  1. only calculate window tables on window values changing
  2. template rendering to skip blending / windowing checks if disabled
  3. cache decoded screen entries (likely not worth it)
  4. cache decoded oam entries

1:
this should give a decent speed up, but still not by much.

2:
while this will speed up scenes that dont use windowing and blending, this still isn't ideal because many scenes
do use both windowing and blending. so those scenes will still be super slow.

3:
decoding is very fast already.

4:
this will be a decent speed up.

reduce template bloat of instruction handlers

from my readme:

reduce template bloat for arm/thumb instructions by creating dedicated functions for every possible version,
ie, data_proc_add_imm_s. this will GREATLY reduce bloat, which is nicer for icache and also compile times.

to achive this, still have normal template function, such as data_proc, so data_proc_add_imm_s will call that template func.
the template<> will have to be toggled by a macro so that debug builds can still be fast (instant) and not templated at all.

my cpu has 256KiB icache, which my final binary far exceeds (1.0 MiB (1,094,928)), this is with full optimisations and lto.
without lto, it's much bigger stil...

really there's not much code to the emulator, so i really think i can at the very least get it to ~512KiB, likely a LOT smaller.

without tables generated (-O3 -lto) and built as a single file (all hot functions inlined) the final binary is 123.6 KiB (126,520).


summary: (all -O3 -lto, single file (force inlined r/w funcs)

  • THUMB[OFF] ARM[OFF] = 123.6 KiB (126,520)
  • THUMB[ON] ARM[OFF] = 303.5 KiB (310,800) + 179.9 KiB
  • THUMB[OFF] ARM[ON] = 893.2 KiB (914,616) + 769.6 KiB
  • THUMB[ON] ARM[ON] = 1.0 MiB (1,094,928) + 945.7 KiB

[phoenix wight 1] text missing on the second line

this happens when i treat the sprite_y as s8. the text simply isn't rendered. if i treat sprite_y as unsigned, it rendered. its likely an issue with this line here

if (REG_VCOUNT >= obj.attr0.Y && REG_VCOUNT < obj.attr0.Y + ySize)

y=s8
image

y=u8
image

treating y=u8 doesnt seem to be correct either. because then the top half of sprites will never be rendered.

std::span might be a performance hit

std::span is a container that's 16-bytes (ptr + std::size_t).

currently, it is used for all reads / writes here

STATIC_INLINE constexpr auto read_array(std::span<const u8> array, auto mask, u32 addr) -> T

STATIC_INLINE constexpr auto write_array(std::span<u8> array, auto mask, u32 addr, T v) -> void

now, the size is not needed for these functions, so passing a struct around is very uneeded. this of course does not matter when the function is inlined, which it is (in release mode). However, i am not so sure about its effects with msvc.

the emulator performance with msvc is shocking. a game which achieves 1.3k fps on linux (both gcc and clang) only reaches 600 fps with msvc. with clang-cl (windows) performance is 1k fps, which is about what i expected.

there are numerous posts online about the performance hit of std::span with msvc, however they state that it wont be an issue if the function is inlined, which i assume it is.

NOTE:
i tested using std::array instead of C-arrays for my memory struct. on linux, i did notice a very small performance hit. i am not sure if this is due to the constructor of std::span happening on every r/w, or it's within margin of error. i don't think there should be any hit at all. from 1300 to ~1250.

[CI] implement CI

auto builds / uploads for windows and linux (maybe mac if i find a tester).

what would be neat is having CI that builds and runs the emulator through several tests and takes a screen shot of the result. though maybe that's a bit too much to ask of CI.

[Minish Cap] missing "Roll" obj text

what should happen is the "Roll" text is 2 objects. obj0 and obj1. when link is moving, those obj attributes are written to oam[0] and oam[8] and shifts the other attributes down by 16 bytes (so the "R" button which was at oam[0] and oam[8] is now at oam[16] and oam[24]).

this is likely a dma issue.

this is how it currently looks
image

this is how it should look
image

[flash] implement flash

flash is currently stubbed which is enough to get pokemon games to boot. of course, proper flash is needed to save the game.

square channels are too loud

for square channels, if the duty=0, then i output a -volume, if duty=1 then i output a +volume.
this however makes the channels too loud, most notable in emerald intro.

the same happens if i apply this to the noise channel. when the bit=0, output -volume, otherwise +volume. this makes the channel too loud.

i am not really sure what to do here because having the dmg channels only output 4bit samples between 0-15 seems wrong when i want to output signed sound. however if i always treat it as duty=0, vol=0, then it sounds identical to gba hw (in terms of loudness).

maybe output -+vol is the correct thing to do, but i am missing an important step in between.

i guess one possible issue is that sound cannot go from say, -15 to +15 instantly, it's gradual, being a constant signal meaning theres no sharp edges. so maybe i need to emulate the gradual change in volume?

add dmg emulation support

since writing this gba emulator (in c++), it's inspired me to re-write my gameboy emulator https://github.com/ITotalJustice/TotalGB in modern c++, using a few of the optimisation techniques that i learned doing this project.

the initial goal is to have both emulators behave separate from each other. the only thing shared is some of the memory in mem struct (vram, pram, io, rom, wram). even then however, only rom mem will be used, just to simplify things.

the run loop will add an if (system == dmg) run_dmg();

the apu in gba can easily be re-purposed as well.

the final goal is to have the dmg/gbc emulation behave as it would on an actual gba. this means that gb games that dont work
on the gba should also not work in this emu. any bugs / sounds glitches that are present on the gba should also be present in this emu.

NOTE: certain gbc games have a gba mode, by detecting that its running on a gba, it changes the colour palette (and thats about it iirc). for now, i'll stub this so all games (namely shantae) believe its running on a gba.

[frontend] write imgui filebrowser

goal is to write a imgui filebrowser that uses std::filesystem. i'll (maybe) split this off into a separate repo, probably call it ImFs.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.