For years, Nintendo 64 emulation has been pretty bad and lagging significantly behind Nintendo Gamecube/Wii emulation. At least 90 to 95% of the remaining problems are at the RDP level, the N64’s video subcomponent chip. By moving away from High-Level Emulation of the RDP, we could solve most of the remaining problems. The problem has been that for a long time, it seemed impossible to do this at playable speeds. Software rendering is too slow for a GPU from this timeframe, and older versions of OpenGL have too many crippling limitations in order to allow for a 1:1 reprogramming and port of Angrylion to GL.
At last, this dire situation will change in the upcoming days and we can finally release to the public something that will revolutionize N64 emulation forever so that we can move away from all of the hacky HLE video plugins that have been released in recent years.
The world’s first-ever low-level N64 video plugin implemented using the Vulkan API!
And not just any video plugin either. This is a reimplementation/port of Angrylion to Vulkan. This will be the first time most will be able to get anywhere close to playable speeds with an accuracy-based N64 video renderer.
This hardware renderer is unique for the following reasons:
This is the first N64 emulator project ever so far to receive Vulkan support.
This is the first time ever that an emulator takes advantage of asynchronous compute (exclusive only to DirectD12/Vulkan) for hardware rasterization of an emulated GPU.
This is the first time ever that the Angrylion renderer has been ported to a graphics API. It is the first time an RDP LLE video renderer for N64 has been capable of running at fullspeed. It marks a shift away from decades of inaccurate high-level emulation of the N64’s RDP which made for buggy N64 emulation in general.
When combined with a 3D game engine, such as the Source engine, the libretro framework is able to run on any surface in the game.
Replacing the simple game texture shown on an in-game TV screen with a fully functional libretro instance can do anything ranging from playing a full-length video with the ffmpeg core, to running interactive homebrew software, all on the in-game screen.
Adding libretro support to a 3D frontend allows a wide range of media to be loaded using libretro’s ever growing collection of cores. Only a few key components need to be in place to get started. This article outlines what was required to add libretro support to the Source engine for the 3D-frontend Anarchy Arcade (www.anarchyarcade.com). The process for other popular game engines is also very similar.
The Source engine has three notable road bumps when implementing libretro.
First is that the Source engine is DirectX, while libretro requires OpenGL for 3D acceleration. Without OpenGL, only the cores that support software mode will be able to function. Generally, this means only 2D cores will work properly, but technically it will depend on what the core supports.
The second road bump is audio. Anarchy Arcade uses PortAudio (www.portaudio.com) to play the audio streams that libretro provides. However, the Source engine itself may be capable of playing such audio streams more optimally. What ever the sound solution, it is still simple enough to get the audio streams from libretro and send them where ever they need to go.
The third road bump is frame scaling. The resolution of the frame that libretro generates will not match the resolution of your texture. The frame data must be re-scaled in real time before it can be written to the texture.
After libretro is initialized, a core module must be loaded and its interface built so that it can communicate with your frontend. The libretro core will be asking your frontend for different variables and options that your frontend must provide answers to. The core will also be delivering the video buffer and the audio streams to your frontend.
All that your frontend needs to do is display what libretro gives it. Your frontend can also forward keyboard & gamepad input to the libretro core so the user can interact with it. This communication all takes place during the main loop.
Source Engine Main Loop
After libretro is initialized, its retro_run method needs be able to be called as often as possible, without interfering with normal engine operations. A good place to plug your code into the Source engine for this is in CAutoGameSystemPerFrame::Update.
With a core loaded and retro_run being called from your main loop, libretro is fully functioning. Now the frontend just needs to display what it is given, and forward user input to the libretro core.
Source Engine Texture Access
Cores that have software rendering (such as most 2D cores) will basically require a memcopy of the frame that libretro gives your frontend. The Source engine has a special kind of texture called a procedural texture that allows you to write directly to its pixels, or do memcopies onto it. It works by plugging into the logic of the ITextureRegenerator::RegenerateTextureBits method to do a memcopy of the libretro frame buffer. This effectively draws what ever libretro is rendering onto the in-game texture.
Source Engine Input Capture
Finally, your frontend needs to send button state info to the libretro core so that the user can interact with it. In the Source engine, button states can be determined whenever needed by using the vgui::input()->IsKeyDown method.
Libretro Frontend on Source Engine w/ VR Mode
After all of these components are implemented into your frontend, you can use your interactive texture on how ever many surfaces you want. There is no additional performance impact for using it on more than 1 surface. You can also optimize your implementation so that memcopies only occur when they need to by assigning a CEntityMaterialProxy to the material that references your procedural texture. With these 3 simple components, you are able to run many of the libretro cores available at www.libretro.com, or your own homebrew software on the in-game screens of your Source engine 3D frontend.
Parasite Eve with the experimental GL renderer. Note the screen residue glitches at the bottom.
Here is the first release of Mednafen/Beetle PSX HW. You can download this core right now for Windows, Linux, and OSX.
NOTE: THIS IS AN ALPHA VERSION AND IT IS NOT REPRESENTATIVE OF THE UPCOMING BETA VERSION. PERFORMANCE RIGHT NOW IS A LOT LOWER THAN WHAT IT WILL BE FOR THE BETA VERSION. EXPECT BUGS TOO.
Rage Racer using experimental GL rendererFinal Fantasy VII using experimental GL renderer
Go to RetroArch, go to Online Updater, go to ‘Update Cores’, and download ‘PlayStation (Mednafen PSX HW)’. You might need to update your core info files first before this will show up properly. To do this, go to ‘Online Updater’, and select Update Core Info Files’.
I will add OSX 32bit and PowerPC releases to this later on. PS3 will be back at some later undisclosed time, same with original Xbox and 360.
Regarding the releases from this point on: give us as much feedback as possible, and with each week we can try to address some of this feedback and make RetroArch better. A ‘Release early, release often’ approach instead of the drought of stable releases that was the norm before will hopefully result in more sustained progress.
Cookie Consent
We use cookies to improve your experience on our site. By using our site, you consent to cookies.
Websites store cookies to enhance functionality and personalise your experience. You can manage your preferences, but blocking some cookies may impact site performance and services.
Essential cookies enable basic functions and are necessary for the proper function of the website.
Name
Description
Duration
Cookie Preferences
This cookie is used to store the user's cookie consent preferences.
30 days
Statistics cookies collect information anonymously. This information helps us understand how visitors use our website.
Google Analytics is a powerful tool that tracks and analyzes website traffic for informed marketing decisions.
Contains information related to marketing campaigns of the user. These are shared with Google AdWords / Google Ads when the Google Ads and Google Analytics accounts are linked together.
90 days
__utma
ID used to identify users and sessions
2 years after last activity
__utmt
Used to monitor number of Google Analytics server requests
10 minutes
__utmb
Used to distinguish new sessions and visits. This cookie is set when the GA.js javascript library is loaded and there is no existing __utmb cookie. The cookie is updated every time data is sent to the Google Analytics server.
30 minutes after last activity
__utmc
Used only with old Urchin versions of Google Analytics and not with GA.js. Was used to distinguish between new sessions and visits at the end of a session.
End of session (browser)
__utmz
Contains information about the traffic source or campaign that directed user to the website. The cookie is set when the GA.js javascript is loaded and updated when data is sent to the Google Anaytics server
6 months after last activity
__utmv
Contains custom information set by the web developer via the _setCustomVar method in Google Analytics. This cookie is updated every time new data is sent to the Google Analytics server.
2 years after last activity
__utmx
Used to determine whether a user is included in an A / B or Multivariate test.
18 months
_ga
ID used to identify users
2 years
_gali
Used by Google Analytics to determine which links on a page are being clicked
30 seconds
_ga_
ID used to identify users
2 years
_gid
ID used to identify users for 24 hours after last activity
24 hours
_gat
Used to monitor number of Google Analytics server requests when using Google Tag Manager
1 minute
Marketing cookies are used to follow visitors to websites. The intention is to show ads that are relevant and engaging to the individual user.
A video-sharing platform for users to upload, view, and share videos across various genres and topics.
Registers a unique ID on mobile devices to enable tracking based on geographical GPS location.
1 day
VISITOR_INFO1_LIVE
Tries to estimate the users' bandwidth on pages with integrated YouTube videos. Also used for marketing
179 days
PREF
This cookie stores your preferences and other information, in particular preferred language, how many search results you wish to be shown on your page, and whether or not you wish to have Google’s SafeSearch filter turned on.
10 years from set/ update
YSC
Registers a unique ID to keep statistics of what videos from YouTube the user has seen.
Session
DEVICE_INFO
Used to detect if the visitor has accepted the marketing category in the cookie banner. This cookie is necessary for GDPR-compliance of the website.
179 days
LOGIN_INFO
This cookie is used to play YouTube videos embedded on the website.
2 years
VISITOR_PRIVACY_METADATA
Youtube visitor privacy metadata cookie
180 days
You can find more information in our Cookie Policy and .