Skip to content

Alban098/NEmuS

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

58 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NEmuS

An experimental NES Emulator written in Java

Super Mario BrosLegend of Zelda Super Mario Bros 3Mega Man


Table of Contents


Features

Core

  • 6502 CPU Emulation with basic decompiler
  • 2C02 PPU Emulation
  • 2A03 APU Emulation with 2 Pulse Channels, a Triangle Channel, a Noise Channel and a DMC (or PCM) Channel
  • Emulation of saves for games supporting it (every 30s)
  • iNES Mappers (Non-exhaustive Game list):
    • NROM (000) : Super Mario Bros, Donkey Kong, Duck Hunt, Ice Climbers, Excitebike
    • MMC1 (001) : Legend of Zelda, Zelda 2, Metroid, Mega Man 2,
    • UxROM (002) : Castlevania, DuckTales, Mega Man, Metal Gear
    • CNROM (003) : Track & Field
    • MMC3 (004) : Super Mario Bros 2, Super Mario Bros 3
    • MMC2 (009) : Mike Tyson's Punch Out!! (Glass Joe fight not starting, but others do ??)
    • GxROM (066) : Super Mario Bros + Duck Hunt, Dragon Ball

Controls

  • Fully customizable controllers inputs
  • Gamepads and Joystick support

User Interface

  • Main Game Window allowing you to :
    • Load a ROM
    • Pause / Resume emulation
    • Reset the emulator
  • Audio Settings Window allowing you to :
    • Select the Audio Output Peripheral (If a new device is plugged, it will not be detected until NEmuS is restarted)
    • Set the volume
    • Set the audio quality
    • Enable / Disable audio rendering
    • Switch to RAW audio
    • Enable / Disable specific audio channels
  • Graphics Settings Window allowing you to :
    • Add / Remove filters
    • Rearrange filters order
  • Controller Settings Window allowing you to customize controls scheme
  • CPU Viewer Window allowing you to :
    • See current CPU Status (Registers, Program Counter, Stack Pointer)
    • See currently executed assembly code
    • See the entire addressable range of the CPU in realtime
    • Step through the code line by line or frame by frame
  • PPU Viewer Window allowing you to :
    • See the palettes
    • See the pattern tables and apply a palette to them
    • See the nametables
    • See the OAM Memory (as a list and rendered)
  • APU Viewer Window showing you the waveform of each channel and the mixer in realtime

How to Use

Launch

To launch the Emulator set the Main Class to NEmuSUnified.java

Add custom Filters

To add a new Filter the following steps are needed :

  • Write the shaders
    • Write the vertex shader or reuse the default one : shaders/vertex.glsl
        //Example vertex shaders
        //this shader will flip the UVs
        #version 330
        
        layout(location = 0) in vec2 position;  //the vertex coords
        
        out vec2 pass_textureCoords;            //the UVs that are passed to the fragment
        
        void main() {
         pass_textureCoords = position * 0.5 + 0.5;           //the UVs are calculated from the vertex coords
         gl_Position = vec4(position.x, -position.y, 0, 1.0); //the position is set but the Y coords is flipped
        }
    • Write the fragment shader
        //Example fragment shaders
        //this shader will replace color that are brighter than a threshold with black
        #version 330
        
        in vec2 pass_textureCoords; //UVs
        out vec4 fragColor;         //pixel color
        
        uniform sampler2D tex;      //sampled texture (Name is important)
        uniform int demo_int; 
        uniform int demo_bool; 
        uniform float demo_float;   //threshold
        uniform vec3 demo_vec; 
        uniform mat3 demo_mat; 
        
        void main() {
          vec3 color = texture2D(tex, pass_textureCoords).rgb; //sample the texture at the passed UVs coords
          if (0.3 * color.r + 0.59 * color.g + 0.11 * color.b > demo_float)
              color = vec3(0);
          fragColor = vec4(color, 1.0);
        }
    • When your shaders are ready you can register the filter in filters.xml as follows
      <filters>
          <filter>
              <name>Demo Filter</name>
              <vertex>shader/myVertex.glsl</vertex>
              <fragment>shader/myFragment.glsl</fragment>
              <description>My Filter description</description>
              <uniforms>
                  <uniform type="int" name="demo_int" default="6"/>
                  <uniform type="float" name="demo_float" default="6"/>
                  <uniform type="bool" name="demo_bool" default="true"/>
                  <uniform type="vec3" name="demo_vec" default="0; 1; 2"/>
                  <uniform type="mat3" name="demo_mat" default="0; 1; 2; 3; 4; 5; 6; 7; 8"/>
              </uniforms>
          </filter>
      </filters>
    • That's it, your Filter will appear in the Graphics Settings along with a section that will let you edit the uniforms to tweak the filter at runtime

Screenshots

CPU ViewerPPU Viewer APU Viewer ControlsAudio Graphics

Libraries

  • LWJGL 3 Used to handle Rendering
  • LWJGUI Used for the Main window
  • JavaFX For all other windows
  • Beads Used to handle Audio

Thanks

  • OneLoneCoder (Github) For his amazing video series about the NES and its inner workings
  • NESDev Wiki For making available all of this information about the system in one place

License

This project is licensed under the MIT license