Commit graph

204 commits

Author SHA1 Message Date
Daniel Prilik 8ae814d615
Update .gitattributes 2022-01-11 14:34:56 -08:00
Daniel Prilik cbc4160fe9
Merge pull request #15 from MrKOSMOS/master
Compiler warnings fix
2021-12-03 12:30:03 -10:00
MrKOSMOS 9f0c11c6e3
Update cpu.cc 2021-12-03 20:34:03 +00:00
MrKOSMOS f19d1d0304
Update emu.cc 2021-12-03 20:10:45 +00:00
MrKOSMOS 42d33b1e08
Update emu.h 2021-12-03 20:08:27 +00:00
MrKOSMOS 0995f9a86f
Update widenes.cc 2021-12-02 20:56:10 +00:00
MrKOSMOS 1d903e2615
Update mapper_009.cc 2021-12-02 20:46:53 +00:00
MrKOSMOS 99ae2a99fa
Update mapper_007.cc 2021-12-02 20:46:23 +00:00
MrKOSMOS 35290b5296
Update mapper_004.cc
Making the compiler happy
2021-12-02 20:42:38 +00:00
MrKOSMOS 8c23e981f0
Update mapper_001.cc 2021-12-02 20:30:21 +00:00
MrKOSMOS 6f27b38d83
Update apu.cc
Idk, compiler stuff
2021-12-02 20:29:04 +00:00
MrKOSMOS 9e16eb1d13
Update emu.cc 2021-12-02 19:05:10 +00:00
MrKOSMOS af086ebfa6
Update emu.cc 2021-12-02 18:37:47 +00:00
MrKOSMOS 772656ed71
Update emu.h 2021-12-02 18:30:18 +00:00
Daniel Prilik 050bb8b193
Merge pull request #12 from Margen67/actions
Add GitHub Actions CI
2020-08-31 21:22:03 -04:00
Margen67 88a571ac30 Add GitHub Actions CI 2020-08-22 17:36:36 -07:00
Daniel Prilik cd756d0a2d fix some gcc warnings, and maybe even a ppu bug?
first commit in a _long_ time, and it's just because I installed a
fresh linux distro and wanted to see if ANESE compiles on it.
It does, but I noticed a couple of warnings and bugs, so these are
some quick fixes.

looks like I had an unintended fallthrough in my bgr_fetch routine.
not sure how mission-critical this is, but maybe it fixes stuff?

other than that, g++ helpfuly noted some other silly errors and
unused vars, so I cleaned those up too.

lastly, I removed some code that skipped the first directory
returned by cute_files in the menu component. Not _super_ sure why
that was there in the first place, but directory traversal now
works on some more linux distros (such as the one I am running)
2018-12-03 14:04:27 -05:00
Daniel Prilik 0081371aa4
add links to wideNES writeup 2018-08-28 13:39:26 -04:00
Daniel Prilik 22d9de7434
Update README.md 2018-08-24 12:33:58 -07:00
Daniel Prilik 51457bc9e7
Update README.md 2018-08-24 12:32:06 -07:00
Daniel Prilik f5e13d1da2
Update _config.yml 2018-08-24 12:13:39 -07:00
Daniel Prilik 13618a768b updated metroid GIF 2018-07-31 16:03:03 -07:00
Daniel Prilik 1a5f555f6b fixed MMC1 bug - Metroid enemies move now 2018-07-31 14:22:18 -07:00
Daniel Prilik 51d6e27c26
Merge pull request #1 from daniel5151/wideNES
WideNES
2018-07-25 10:38:48 -07:00
Daniel Prilik 2093dc058d save / load scenes to/from disk
that's it then, the final piece.
You can play games, record scenes, and boot games back up with the
recorded map.

It's not perfect, _far from it_, but it works!

There is still a lot of work to do, improving heuristics and such,
but I think wideNES is at a point where it can be merged into
master and shown off a bit :)

exciting!
2018-07-25 10:31:26 -07:00
Daniel Prilik 67cfa183f8 re-enterant scenes!
wowie this was a trickyboi to figure out, but I think I managed to
get a decent-working solution.

The algorithm consists of 2 parts: 1) detecting scene transitions,
and 2) figuring out if the new scene is a duplicate.

Part 1) was solved using perceptual hashing, and watching the delta
of the frame hash between frames. When it spikes, odds are that's a
scene change.

Part 2) was a bit trickier, but boils down to hashing every frame
and associating it with a scene + scroll values. That way, when a
scene transition is detected, I can check the hash-maps to see if
the "new" frame is actually one I've seen before.
There is a bit of extra work that gets the technique working with
elaborate fade-in animations / animated backgrounds, but it's not
magic or anything.

What's left?

Well, 1) needs to be improved, since the current delta threshold
value i'm using has been pulled out of thin air, and while it gives
reasonable results on many games, ideally, it should be more robust

2) is pretty good though!

All that I need to do now to be super happy with it is serialize
the scene data and enable loading / saving it to disk! Once that's
done, the initial vision of being able to automatically map out a
game will have come true!

exciting!
2018-07-20 15:23:31 -07:00
Daniel Prilik 8c0cd894ea initial scene-detection algorithm + cleanup
Perceptual hashing... that's the cool shit.

I mean, my "advanced" perceptual hashing algorithm is really dumb
right-now, literally just taking a sum of all pixels in the frame,
and yet, it's good enough to detect when a _bunch_ of pixel-values
change from frame-to-frame. I bet that with a bit more tweaking,
like normalizing the frame wrt. the palette, I can get some even
better results.

I also have a "true" hashing implementation, where each frame gets
a unique hash. It seems to be realtively collision-free. That said,
there are times where there are collisions, namely in Metroid,
where the game likes to reuse screens. I'll have to figure out how
to deal with that...

So, what's the next step?

Whenever a scene changes, take the hash of the new screen, and see
if it matches up with anything we've seen before.
That way, we can have "re-enterant" scenes, which is a key to being
able to save/load tiles!
2018-07-19 11:19:32 -07:00
Daniel 4768bfaf75 fix windows build 2018-07-17 21:52:55 -07:00
Daniel Prilik cfdb31e6dc add zelda heuristic + cleanup
didn't think i'd be able to pull it off, but Zelda seems to scroll
fine now! All I needed to do was sniff the PPUADDR register, since
after all, PPUSCROLL and PPUADDR both point to PPU t/v anyways...

I also bunched-up the heauristics a bit better, hopefully making
the code a bit nicer.

before showing off my work, the big thing that needs to get done is
scene detection. Yeah, heuristics are cool, and fun to implement,
but I can do that later. What I _should_ focus on is getting scene-
detection working, and afterwards, saving and loading, since that's
the killer feature (imo)

It's going to be tricky, but i've been reading-up on perceptual
hashes, so that might be useful?
Alternatively, I could sniff what games tend to write to the PPU
during "scene transitions" and see if there is anything I can use
to fingerprint scenes...
2018-07-17 15:45:00 -07:00
Daniel Prilik fc350a64ad very minor edits 2018-07-16 17:39:03 -07:00
Daniel Prilik 3ee521700a improved tile-updates, added 16x16 block sampling
yeah... i'm not entirely sure of the thought process I had with my
old method... It worked, but it wasn't very clean, or intuitive.
This new method is a lot cleaner, and makes a lot more sense.
Moreover, it enables me to add the 16x16 block sampling
functionality, which is awesome, since animated blocks tend no to
get "banded" or "smeared."
2018-07-15 12:31:44 -07:00
Daniel Prilik 41b8137d10 minor tweak to getting framebuffers / audio samples
basically, instead of using a referance to a pointer, i'm just
using a double pointer. Aside from looking nice, it also gives my
NES class a more C-like interface, which will come in handy if I
ever want to export ANESE as a libretro core.
2018-07-13 17:18:01 -07:00
Daniel Prilik 86a048127d improved ppu instrumentation + cleaning up debug hooks
I think i've settled on how to expose the inner workings of ANESE.
1) callbacks at key points
2) direct-acess to member variables using _functions.

Anything in ANESE core that starts with an underscore is something
that is _not related to NES emulation_, and is purely there for
instrumentation / debugging.
2018-07-13 17:08:25 -07:00
Daniel Prilik 8b805372a2 add menu to wideNES window 2018-07-13 15:23:08 -07:00
Daniel Prilik d8a2be3504 tweak inter-module interaction 2018-07-13 15:10:15 -07:00
Daniel f3add19dc2 fix windows build 2018-07-12 21:03:21 -07:00
Daniel Prilik fcf791af49 cleanup + make menu a submodule
gui.cc is now _almost_ module agnostic, which is awesome!

The last thing to do is to figure out what's the best way to route
input from the wideNES window to the main window, as the current
solution of _always_ passing input to the emulator is jank af.

I also finally got a ROM loading / unloading solution i'm happy
about. essentially, load/unload have become utility methods on the
shared-state struct.
2018-07-12 18:53:05 -07:00
Daniel Prilik e0b5ceef39 made ppu_debug into a GUI module + cli toggle wideNES and ppu_debug
no more SDL in ANESE core!

Also, with this commit, I can merge back into master, since wideNES
is hidden behind a flag :)

Before I do that though, a bit of cleanup is in order :)
2018-07-12 17:40:00 -07:00
Daniel Prilik e983ad4016 fixed smearing + removed wideNES specifics from PPU
to fix the smearing in MMC3 games, I needed to change which scroll-
values to use depending on if the status bar is at the top / bottom
of the screen. If it's at the top of the screen, then I need to use
the scroll values recorded _after_ the IRQ is fired. If it's at the
bottom of the screen, then I need to use the scroll values recorded
_before_ the IRQ is fired.

Also, turns out with my newer, better sampling methods, I don't
need to use that janky "true 0" filter anymore, so that's gone!

Lastly, I removed all wideNES specific code from the PPU, instead
adding scroll callbacks (so I can register values on my end)
2018-07-12 13:11:09 -07:00
Daniel Prilik 871daf6aa1 tweaked callbacks + refactored SDL_inprint
I wanted to use SDL_inprint in multiple renderers, and that meant I
had to modify the library a little bit.

also, I just noticed that the smearing issue is back! Not as bad as
before, but MMC3 games seems to be affected when the screen scrolls
upwards...

wierd.
2018-07-12 11:28:54 -07:00
Daniel Prilik b085f094af made NES state a shared resource 2018-07-11 17:51:29 -07:00
Daniel Prilik afd2523452 fix menu not showing up 2018-07-11 16:51:34 -07:00
Daniel Prilik cba273aa08 automatic padding detection + sampling overhaul
If a human can figure out which parts of a screen to chop, why
can't wideNES do it automatically? Well, it can! sort of...

I implemented a couple of heuristics that use the state of the PPU
and the Mapper to "guess" what padding values make sense.

For now, I only have 2 implemented:

1) Check if the bgr-mask column is enbled on PPUMASK
  - if so, add 8px of padding to the left of the screen
  - many games that mask the left also have artifacting on the
  right, so mask off 8px on the right too.

2) Check what scanline the Mapper IRQs happened on
  - mask-off the rest of the screen
  - many games use the Mapper IRQ for status-bars (smb3, kirby)

Now, these are not perfect heuristics by any means, with exceptions
rampant. eg: Lode Runner doesn't have any graphical artifacting on
the right of the screen. eg2: MegaMan IV uses the IRQ for different
reasons, unrelated to status-bars.

Nevertheless, they do a decent job with many games, smb3 and MC Kids
work flawlessly. Moreover, Metroid and Super Mario Bros work great
too, automatically having the entire screen captured (no padding)

While implemeting this feature, I decided to cleanup how I was
reading the NES's state, and implemented a basic Callback system,
enabling arbitrary methods to hook into important parts of the NES
lifecycle. eg: I added callbacks whenever a mapper fires an IRQ,
and a mapper whenever a PPU frame finished drawing (scanline 240)

This had the happy side-effect of fixing my smearing issues, as it
makes a lot more sense to sample the NES's state _before_ the NMI
handler happens, as that state the one that resulted in the current
frame! Just like that, every game I tested worked flawlessly, no
smearing to be found!

Also, this lays a much more solid groundwork for implementing a
proper debugger! It should be easy to take the nastyness that is
ppu_debug.cc and extract it into it's own GUI module! That way,
there will be _no_ state of SDL in ANESE core!
2018-07-11 16:17:08 -07:00
Daniel Prilik 28233ab5a5 add padding + update READMEs
I still haven't figured out the smearing issue, but I _did_ figure
out how to greatly-improve compatibility with many titles!

I added the ability to "pad" the screen, cutting-off any artifacts
at the edge. This means that with a bit of tweaking, games like
SMB3 and MC Kids work near flawlessly!

It _should_ be possible to guess "good" padding values for games by
using some heuristic that relies on current mirroring mode, scroll
direction, and if the PPUMASK is on...

I also updated the README some more, putting a "teaser" for wideNES
on the main page, but splitting off the details into it's own page.
2018-07-10 18:28:22 -07:00
Daniel Prilik a2e87f25bb make wideNES a standalone GUI module + smearing fix?
Yeah, it's about time I get wideNES out of the main NES module, it
was starting to make a mess. Instead, wideNES now has it's own
window, with it's own SDL rendering context.

I'd actually like to refactor the emu module some more, possibly
splitting it into sever different ones. eg: emu_core for the main
NES console + frameloop, emu_controls for handling input / movie
support, and take the file i/o and throw that into the menu module.

I'll get around to it eventually :)
Plus, if I can modularize things a bit more, I can merge this
branch into main, and put the entire wideNES module behind a flag!

-----

smearing.

I'm very confused.

I tried a bunch of stuff, and one thing I stumbled on was that if I
use the _last_ frame's scroll values, then I can fix smearing in
some games (smb2, metroid) at the expense of adding it to other
games (smb1)

I'm really not sure why that's happening, but i'll try investigate.

-----

Oh, and I added basic pan/zoom to WideNES, so you can scroll around
the viewport now :D
2018-07-10 14:15:03 -07:00
Daniel Prilik adb409b196 add Metroid GIF 2018-07-09 18:40:27 -07:00
Daniel Prilik 9982876c73 add seperate spr and bgr framebuffers
since i'll only be sampling from the bgr framebuffer, there should
not be any more nasty sprite artifacting at the edge of the screen.
2018-07-09 16:56:47 -07:00
Daniel Prilik fc6f6dd157 revamp tile system, much more robust
the last tile-based approach was a very jankyboi, with oversized
tiles that were clipped using SDL, with no memory of a framebuffer.
not great, not great at all.

I revamped the system so that each tile has it's own internal
framebuffer, and updates occur by copying chunks of the main nes
framebuffer into the 4 tiles the screen currently overlaps.

this works really well, and has major upsides like
1) no more black-strips
2) possiblity to save tiles (easy access to framebuffer)
3) easier to work with

I'm still running into some issues though, the biggest of which is
that most games that scroll end up "smearing" the background...

It's hard to explain in text, but if you load up SMB2 or Metroid
for example, whenever you scroll, the stuff you leave behind has
duplicate columns, resulting in a "smearing" effect.

I'm at a bit of a loss as to what might be causing it, as the
scroll-register values being sent to the PPU by those games seem
sensible...

I'll try to fix it somehow lol.
2018-07-09 15:53:09 -07:00
Daniel Prilik 96e2d1c7d6 Merge branch 'master' into wideNES 2018-07-09 11:27:14 -07:00
Daniel Prilik 00adfb44fd save savestates in .state files
it's kindof a jank file format, but hey, it works alright :)
2018-07-09 11:23:55 -07:00