Full Code of allkern/iris for AI

master 90dae6afaa05 cached
245 files
2.4 MB
632.9k tokens
4661 symbols
1 requests
Download .txt
Showing preview only (2,529K chars total). Download the full file or copy to clipboard to get everything.
Repository: allkern/iris
Branch: master
Commit: 90dae6afaa05
Files: 245
Total size: 2.4 MB

Directory structure:
gitextract_3bqhuqc4/

├── .github/
│   ├── FUNDING.yml
│   └── workflows/
│       ├── linux.yml
│       ├── macos.yml
│       ├── release.yml
│       └── windows.yml
├── .gitignore
├── .gitmodules
├── AppImage.cmake
├── CMakeLists.txt
├── Info.plist
├── LICENSE
├── MoltenVK_icd.json
├── README.md
├── compat.txt
├── frontend/
│   ├── arcade.hpp
│   ├── audio.cpp
│   ├── config.hpp
│   ├── elf.cpp
│   ├── emu.cpp
│   ├── handlers.cpp
│   ├── imgui.cpp
│   ├── input.cpp
│   ├── iris.cpp
│   ├── iris.hpp
│   ├── notifications.cpp
│   ├── platform/
│   │   ├── stub.cpp
│   │   └── windows.cpp
│   ├── render.cpp
│   ├── res/
│   │   └── IconsMaterialSymbols.h
│   ├── settings.cpp
│   ├── shaders.cpp
│   ├── ui/
│   │   ├── about.cpp
│   │   ├── bios_setting.cpp
│   │   ├── breakpoints.cpp
│   │   ├── control.cpp
│   │   ├── dma.cpp
│   │   ├── gs.cpp
│   │   ├── intc.cpp
│   │   ├── logs.cpp
│   │   ├── memory.cpp
│   │   ├── memory_card_tool.cpp
│   │   ├── memory_search.cpp
│   │   ├── memory_viewer.h
│   │   ├── menubar.cpp
│   │   ├── modules.cpp
│   │   ├── overlay.cpp
│   │   ├── pad.cpp
│   │   ├── settings.cpp
│   │   ├── spu2.cpp
│   │   ├── state.cpp
│   │   ├── statusbar.cpp
│   │   ├── symbols.cpp
│   │   ├── threads.cpp
│   │   └── vu_disassembly.cpp
│   └── vulkan.cpp
├── main.cpp
├── res/
│   ├── iris.icns
│   ├── iris.rc
│   └── iris.res
├── shaders/
│   ├── curvature.frag
│   ├── curvature.spv
│   ├── decoder.frag
│   ├── decoder.spv
│   ├── default.frag
│   ├── default.vert
│   ├── encoder.frag
│   ├── encoder.spv
│   ├── fragment.spv
│   ├── noise.frag
│   ├── noise.spv
│   ├── scanlines.frag
│   ├── scanlines.spv
│   ├── shader.spv
│   ├── shader.vert
│   └── vertex.spv
└── src/
    ├── dev/
    │   ├── ds.c
    │   ├── ds.h
    │   ├── guncon.c
    │   ├── guncon.h
    │   ├── mcd.c
    │   ├── mcd.h
    │   ├── mtap.c
    │   ├── mtap.h
    │   ├── ps1_mcd.c
    │   └── ps1_mcd.h
    ├── ee/
    │   ├── bus.c
    │   ├── bus.h
    │   ├── bus_decl.h
    │   ├── dmac.c
    │   ├── dmac.h
    │   ├── ee.h
    │   ├── ee_cached.cpp
    │   ├── ee_def.hpp
    │   ├── ee_dis.c
    │   ├── ee_dis.h
    │   ├── ee_uncached.c
    │   ├── ee_uncached.h
    │   ├── gif.c
    │   ├── gif.h
    │   ├── intc.c
    │   ├── intc.h
    │   ├── syscall.h
    │   ├── timers.c
    │   ├── timers.h
    │   ├── vif.c
    │   ├── vif.h
    │   ├── vu.h
    │   ├── vu_cached.cpp
    │   ├── vu_def.hpp
    │   ├── vu_dis.c
    │   ├── vu_dis.h
    │   └── vu_uncached.c
    ├── elf.h
    ├── gs/
    │   ├── gs.c
    │   ├── gs.h
    │   └── renderer/
    │       ├── config.hpp
    │       ├── hardware.cpp
    │       ├── hardware.hpp
    │       ├── null.cpp
    │       ├── null.hpp
    │       ├── renderer.cpp
    │       ├── renderer.hpp
    │       ├── software_thread.cpp
    │       └── software_thread.hpp
    ├── iop/
    │   ├── bus.c
    │   ├── bus.h
    │   ├── bus_decl.h
    │   ├── cdvd.c
    │   ├── cdvd.h
    │   ├── disc/
    │   │   ├── bin.c
    │   │   ├── bin.h
    │   │   ├── chd.c
    │   │   ├── chd.h
    │   │   ├── ciso.c
    │   │   ├── ciso.h
    │   │   ├── cue.c
    │   │   ├── cue.h
    │   │   ├── iso.c
    │   │   └── iso.h
    │   ├── disc.c
    │   ├── disc.h
    │   ├── dma.c
    │   ├── dma.h
    │   ├── fw.c
    │   ├── fw.h
    │   ├── hle/
    │   │   ├── ioman.cpp
    │   │   ├── ioman.h
    │   │   ├── loadcore.c
    │   │   ├── loadcore.h
    │   │   ├── sysmem.c
    │   │   └── sysmem.h
    │   ├── intc.c
    │   ├── intc.h
    │   ├── iop.c
    │   ├── iop.h
    │   ├── iop_dis.c
    │   ├── iop_dis.h
    │   ├── iop_export.c
    │   ├── iop_export.h
    │   ├── rpc.c
    │   ├── rpc.h
    │   ├── sio2.c
    │   ├── sio2.h
    │   ├── spu2.c
    │   ├── spu2.h
    │   ├── timers.c
    │   ├── timers.h
    │   ├── usb.c
    │   └── usb.h
    ├── ipu/
    │   ├── chromtable.cpp
    │   ├── chromtable.hpp
    │   ├── codedblockpattern.cpp
    │   ├── codedblockpattern.hpp
    │   ├── dct_coeff.cpp
    │   ├── dct_coeff.hpp
    │   ├── dct_coeff_table0.cpp
    │   ├── dct_coeff_table0.hpp
    │   ├── dct_coeff_table1.cpp
    │   ├── dct_coeff_table1.hpp
    │   ├── ipu.cpp
    │   ├── ipu.h
    │   ├── ipu.hpp
    │   ├── ipu_fifo.cpp
    │   ├── ipu_fifo.hpp
    │   ├── lumtable.cpp
    │   ├── lumtable.hpp
    │   ├── mac_addr_inc.cpp
    │   ├── mac_addr_inc.hpp
    │   ├── mac_b_pic.cpp
    │   ├── mac_b_pic.hpp
    │   ├── mac_i_pic.cpp
    │   ├── mac_i_pic.hpp
    │   ├── mac_p_pic.cpp
    │   ├── mac_p_pic.hpp
    │   ├── motioncode.cpp
    │   ├── motioncode.hpp
    │   ├── vlc_table.cpp
    │   └── vlc_table.hpp
    ├── list.c
    ├── list.h
    ├── md5.c
    ├── md5.h
    ├── ps2.c
    ├── ps2.h
    ├── ps2_elf.c
    ├── ps2_elf.h
    ├── ps2_iso9660.c
    ├── ps2_iso9660.h
    ├── queue.c
    ├── queue.h
    ├── rom.c
    ├── rom.h
    ├── s14x/
    │   ├── aiboard.c
    │   ├── aiboard.h
    │   ├── ioboard.c
    │   ├── ioboard.h
    │   ├── link.c
    │   ├── link.h
    │   ├── nand.c
    │   ├── nand.h
    │   ├── sram.c
    │   ├── sram.h
    │   ├── syscon.c
    │   └── syscon.h
    ├── scheduler.c
    ├── scheduler.h
    ├── shared/
    │   ├── bios.c
    │   ├── bios.h
    │   ├── dev9.c
    │   ├── dev9.h
    │   ├── ram.c
    │   ├── ram.h
    │   ├── sbus.c
    │   ├── sbus.h
    │   ├── sif.c
    │   ├── sif.h
    │   ├── speed/
    │   │   ├── ata.c
    │   │   ├── ata.h
    │   │   ├── eeprom.c
    │   │   ├── eeprom.h
    │   │   ├── flash.c
    │   │   └── flash.h
    │   ├── speed.c
    │   └── speed.h
    └── u128.h

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms

github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
polar: # Replace with a single Polar username
buy_me_a_coffee: allkern
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']


================================================
FILE: .github/workflows/linux.yml
================================================
name: Ubuntu CI

on:
  push:
    branches: [ "master" ]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v6
      with:
        submodules: 'recursive'
        fetch-depth: 0
    - name: Install deps
      run: |
        sudo add-apt-repository universe
        sudo apt-get install build-essential git make \
        pkg-config cmake ninja-build gnome-desktop-testing libasound2-dev libpulse-dev \
        libaudio-dev libjack-dev libsndio-dev libx11-dev libxext-dev \
        libxrandr-dev libxcursor-dev libxfixes-dev libxi-dev libxss-dev libxtst-dev \
        libxkbcommon-dev libdrm-dev libgbm-dev libgl1-mesa-dev libgles2-mesa-dev \
        libegl1-mesa-dev libdbus-1-dev libibus-1.0-dev libudev-dev libfuse2t64
    - name: Build and pack Iris
      run: |
        git fetch --all --tags
        cmake -S . -B build
        cmake --build build -j8
        sudo cmake --install build
        mkdir dist
        mv ./build/iris ./dist
        mkdir appimage
        mv ./build/*.AppImage ./appimage
    - uses: actions/upload-artifact@v7
      with:
        name: iris-latest-linux
        path: ./dist
    - uses: actions/upload-artifact@v7
      with:
        name: iris-latest-linux-appimage
        path: ./appimage





================================================
FILE: .github/workflows/macos.yml
================================================
name: macOS CI

on:
  push:
    branches: [ "master" ]

jobs:
  macos-universal-build:
    runs-on: macos-latest

    steps:
    - uses: actions/checkout@v6
      with:
        submodules: 'recursive'
        fetch-depth: 0
    - name: Install Vulkan SDK
      uses: jakoch/install-vulkan-sdk-action@v1
      with:
        optional_components: com.lunarg.vulkan.volk
        install_runtime: true
        cache: true
        stripdown: true
    - name: Build and pack Iris
      run: |
        git fetch --all --tags
        cmake -S . -B build -G "Unix Makefiles"
        cmake --build build -j8
        sudo cmake --install build
        mkdir -p ./build/dist
        cp -R ./build/iris.app ./build/dist
    - uses: actions/upload-artifact@v7
      with:
        name: iris-latest-macos-universal
        path: ./build/dist











================================================
FILE: .github/workflows/release.yml
================================================
name: Release CI

on:
  push:
    tags:
    - '0.*'

jobs:
  windows-build:
    runs-on: windows-latest

    steps:
    - uses: actions/checkout@v6
      with:
        submodules: 'recursive'
        fetch-depth: 0
    - name: Build and pack Iris
      run: |
        git fetch --all --tags
        cmake -S . -B build -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release
        cmake --build build -j8
        New-Item -Path "dist" -ItemType Directory
        Copy-Item -Path ".\build\iris.exe" "dist"
        Copy-Item ".\build\*.dll" "dist"
        Copy-Item "C:\mingw64\bin\*.dll" "dist"
    - name: Generate artifact name
      id: generate-name
      run: |
        echo "::set-output name=artifact::iris-${{ github.ref_name }}-windows"
    - name: Zip artifact
      run: |
        $artifactName = "${{ steps.generate-name.outputs.artifact }}"
        Compress-Archive -Path "dist\*" -DestinationPath "$artifactName.zip"
    - name: Upload to release
      uses: softprops/action-gh-release@v2.6.1
      with:
        files: |
          ${{ steps.generate-name.outputs.artifact }}.zip

  linux-build:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v6
      with:
        submodules: 'recursive'
        fetch-depth: 0
    - name: Install deps
      run: |
        sudo add-apt-repository universe
        sudo apt-get install build-essential git make \
        pkg-config cmake ninja-build gnome-desktop-testing libasound2-dev libpulse-dev \
        libaudio-dev libjack-dev libsndio-dev libx11-dev libxext-dev \
        libxrandr-dev libxcursor-dev libxfixes-dev libxi-dev libxss-dev libxtst-dev \
        libxkbcommon-dev libdrm-dev libgbm-dev libgl1-mesa-dev libgles2-mesa-dev \
        libegl1-mesa-dev libdbus-1-dev libibus-1.0-dev libudev-dev libfuse2t64
    - name: Build and pack Iris
      run: |
        git fetch --all --tags
        cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
        cmake --build build -j8
        sudo cmake --install build
        mkdir dist
        mv ./build/iris ./dist
        mkdir appimage
        mv ./build/*.AppImage ./appimage
    - name: Generate artifact name
      id: generate-name
      run: |
        echo "::set-output name=artifact::iris-${{ github.ref_name }}-linux"
    - name: Generate AppImage artifact name
      id: generate-name-appimage
      run: |
        echo "::set-output name=artifact::iris-${{ github.ref_name }}-linux-appimage"
    - name: Zip artifact
      run: |
        zip -rj ${{ steps.generate-name.outputs.artifact }}.zip dist
    - name: Zip AppImage
      run: |
        zip -rj ${{ steps.generate-name-appimage.outputs.artifact }}.zip appimage
    - name: Upload normal binary to release
      uses: softprops/action-gh-release@vv2.6.1
      with:
        files: |
          ${{ steps.generate-name.outputs.artifact }}.zip
    - name: Upload AppImage to release
      uses: softprops/action-gh-release@v2.6.1
      with:
        files: |
          ${{ steps.generate-name-appimage.outputs.artifact }}.zip

  macos-universal-build:
    runs-on: macos-latest

    steps:
    - uses: actions/checkout@v6
      with:
        submodules: 'recursive'
        fetch-depth: 0
    - name: Install Vulkan SDK
      uses: jakoch/install-vulkan-sdk-action@v1
      with:
        optional_components: com.lunarg.vulkan.volk
        install_runtime: true
        cache: true
        stripdown: true
    - name: Build and pack Iris
      run: |
        git fetch --all --tags
        cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
        cmake --build build -j8
        sudo cmake --install build
    - name: Generate artifact name
      id: generate-name
      run: |
        echo "::set-output name=artifact::iris-${{ github.ref_name }}-macos-universal"
    - name: Zip artifact
      run: |
        cd build; zip -r ../${{ steps.generate-name.outputs.artifact }}.zip ./iris.app; cd ..
    - name: Upload to release
      uses: softprops/action-gh-release@v2.6.1
      with:
        files: |
          ${{ steps.generate-name.outputs.artifact }}.zip


================================================
FILE: .github/workflows/windows.yml
================================================
name: Windows CI

on:
  push:
    branches: [ "master" ]

jobs:
  build:
    runs-on: windows-latest

    steps:
    - uses: actions/checkout@v6
      with:
        submodules: 'recursive'
        fetch-depth: 0
    - name: Build and pack Iris
      run: |
        git fetch --all --tags
        cmake -S . -B build -G "MinGW Makefiles"
        cmake --build build -j8
        New-Item -Path "dist" -ItemType Directory
        Copy-Item -Path ".\build\iris.exe" "dist"
        Copy-Item ".\build\*.dll" "dist"
        Copy-Item "C:\mingw64\bin\*.dll" "dist"
    - name: Upload artifact
      uses: actions/upload-artifact@v7
      with:
        name: iris-latest-windows
        path: dist/





================================================
FILE: .gitignore
================================================
SDL2-2.32.0/
.vscode/
build/
bin/
tools/
elf/
roms/
.vs/
ac/
screens/
main2.cpp
compare
compare.cpp
imgui.ini
*.AppImage
*.expected
*.dump
*.cue
*.bin
*.elf
*.exe
*.iso
*.mec
*.nvm
*.mcd
*.wav
*.irx
*.o
.DS_Store


================================================
FILE: .gitmodules
================================================
[submodule "imgui"]
	path = deps/imgui
	url = https://github.com/ocornut/imgui
	branch = docking
[submodule "tomlplusplus"]
	path = deps/tomlplusplus
	url = https://github.com/marzer/tomlplusplus
[submodule "SDL"]
	path = deps/SDL
	url = https://github.com/libsdl-org/SDL
	branch = release-3.2.24
[submodule "incbin"]
	path = deps/incbin
	url = https://github.com/graphitemaster/incbin
[submodule "implot"]
	path = deps/implot
	url = https://github.com/epezent/implot
[submodule "parallel-gs"]
	path = deps/parallel-gs
	url = https://github.com/Arntzen-software/parallel-gs
[submodule "libchdr"]
	path = deps/libchdr
	url = https://github.com/rtissera/libchdr
[submodule "stb"]
	path = deps/stb
	url = https://github.com/nothings/stb
[submodule "portable-file-dialogs"]
	path = deps/portable-file-dialogs
	url = https://github.com/samhocevar/portable-file-dialogs
[submodule "deps/libdeflate"]
	path = deps/libdeflate
	url = https://github.com/ebiggers/libdeflate
[submodule "deps/lz4"]
	path = deps/lz4
	url = https://github.com/lz4/lz4
[submodule "deps/SDL_GameControllerDB"]
	path = deps/SDL_GameControllerDB
	url = https://github.com/mdqinc/SDL_GameControllerDB
[submodule "deps/asmjit"]
	path = deps/asmjit
	url = https://github.com/asmjit/asmjit


================================================
FILE: AppImage.cmake
================================================
function(make_appimage)
	set(optional)
	set(args EXE NAME DIR_ICON ICON OUTPUT_NAME)
	set(list_args ASSETS)
	cmake_parse_arguments(
		PARSE_ARGV 0
		ARGS
		"${optional}"
		"${args}"
		"${list_args}"
	)

	if(${ARGS_UNPARSED_ARGUMENTS})
		message(WARNING "Unparsed arguments: ${ARGS_UNPARSED_ARGUMENTS}")
	endif()


    # download AppImageTool if needed (TODO: non-x86 build machine?)
    SET(AIT_PATH "${CMAKE_BINARY_DIR}/AppImageTool.AppImage" CACHE INTERNAL "")
    if (NOT EXISTS "${AIT_PATH}")
        file(DOWNLOAD https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage "${AIT_PATH}")
        execute_process(COMMAND chmod +x ${AIT_PATH})
    endif()

    # make the AppDir
    set(APPDIR "${CMAKE_BINARY_DIR}/AppDir")
    file(REMOVE_RECURSE "${APPDIR}")       # remove if leftover
    file(MAKE_DIRECTORY "${APPDIR}")

    # copy executable to appdir
    file(COPY "${ARGS_EXE}" DESTINATION "${APPDIR}" FOLLOW_SYMLINK_CHAIN)
    get_filename_component(EXE_NAME "${ARGS_EXE}" NAME)

    # create the script that will launch the AppImage
file(WRITE "${APPDIR}/AppRun" 
"#!/bin/sh
cd \"$(dirname \"$0\")\";
./${EXE_NAME} $@"
    )
    execute_process(COMMAND chmod +x "${APPDIR}/AppRun")
    
    # copy assets to appdir
    file(COPY ${ARGS_ASSETS} DESTINATION "${APPDIR}")

    # copy icon thumbnail
    file(COPY ${ARGS_DIR_ICON} DESTINATION "${APPDIR}")
    get_filename_component(THUMB_NAME "${ARGS_DIR_ICON}" NAME)
    file(RENAME "${APPDIR}/${THUMB_NAME}" "${APPDIR}/.DirIcon")

    # copy icon highres
    file(COPY ${ARGS_ICON} DESTINATION "${APPDIR}")
    get_filename_component(ICON_NAME "${ARGS_ICON}" NAME)
    get_filename_component(ICON_EXT "${ARGS_ICON}" EXT)
    file(RENAME "${APPDIR}/${ICON_NAME}" "${APPDIR}/${ARGS_NAME}${ICON_EXT}")

    # Create the .desktop file
    file(WRITE "${APPDIR}/${ARGS_NAME}.desktop" 
    "[Desktop Entry]
Type=Application
Name=${ARGS_NAME}
Icon=${ARGS_NAME}
Categories=X-None;"    
    )

    # Invoke AppImageTool
    execute_process(COMMAND ${AIT_PATH} ${APPDIR} ${ARGS_OUTPUT_NAME})
    
    file(REMOVE_RECURSE "${APPDIR}")
endfunction()


================================================
FILE: CMakeLists.txt
================================================
cmake_minimum_required(VERSION 3.21)
project(iris LANGUAGES C CXX)

set(WIN_ICON ${CMAKE_CURRENT_SOURCE_DIR}/res/iris.rc)
set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64")
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15")
set(OSX_ICON ${CMAKE_CURRENT_SOURCE_DIR}/res/iris.icns)

set_source_files_properties(${OSX_ICON} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")

# Statically link SDL3 for Linux targets
set(SDL_STATIC ON)
set(ASMJIT_STATIC ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

find_package(Git QUIET)

if (GIT_FOUND)
    execute_process(
        COMMAND ${GIT_EXECUTABLE} describe --tags --always --dirty --match "0.*"
        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
        OUTPUT_VARIABLE GIT_VERSION_STRING
        OUTPUT_STRIP_TRAILING_WHITESPACE
        ERROR_QUIET
    )
    if(NOT GIT_VERSION_STRING)
        # Fallback if git describe fails (e.g., no tags in the history)
        set(GIT_VERSION_STRING "unknown-version")
    endif()
else()
    set(GIT_VERSION_STRING "git-not-found")
endif()

message(STATUS "Project Version: ${GIT_VERSION_STRING}")

# You can then use GIT_VERSION_STRING in your project, e.g., to generate a header file:
# configure_file(
#     ${CMAKE_CURRENT_SOURCE_DIR}/version.h.in
#     ${CMAKE_CURRENT_BINARY_DIR}/version.h
#     @ONLY
# )

include(CheckIPOSupported)
check_ipo_supported(RESULT LTO_SUPPORTED OUTPUT LTO_ERROR)

set(BUILD_SHARED_LIBS OFF)

# And this part tells CMake where to find and install the file itself
add_executable(iris MACOSX_BUNDLE ${OSX_ICON} ${WIN_ICON})

target_compile_definitions(iris PUBLIC IMGUI_IMPL_VULKAN_NO_PROTOTYPES)
target_compile_definitions(iris PUBLIC IMGUI_IMPL_VULKAN_USE_VOLK)
target_compile_options(iris PUBLIC "-Wno-deprecated-declarations")
# target_compile_definitions(iris PUBLIC _DEBUG)

set(PARALLEL_GS_STANDALONE ON CACHE BOOL "" FORCE)
add_subdirectory(deps/asmjit EXCLUDE_FROM_ALL)
add_subdirectory(deps/tomlplusplus EXCLUDE_FROM_ALL)
add_subdirectory(deps/libdeflate EXCLUDE_FROM_ALL)
add_subdirectory(deps/parallel-gs EXCLUDE_FROM_ALL)
add_subdirectory(deps/libchdr EXCLUDE_FROM_ALL)
add_subdirectory(deps/SDL EXCLUDE_FROM_ALL)

if (CMAKE_SYSTEM_PROCESSOR MATCHES "AMD64")
    target_compile_options(iris PRIVATE -D_EE_USE_INTRINSICS -mssse3 -msse4.1)
endif()

if (X11_API)
    target_compile_definitions(granite-volk PUBLIC VK_USE_PLATFORM_XLIB_KHR)
endif()
if (WAYLAND_API)
    target_compile_definitions(granite-volk PUBLIC VK_USE_PLATFORM_WAYLAND_KHR)
endif()
if (WIN32)
    target_compile_definitions(granite-volk PUBLIC VK_USE_PLATFORM_WIN32_KHR)
endif()

if (NOT CMAKE_SYSTEM_NAME MATCHES "Windows")
    if (LTO_SUPPORTED)
        message(STATUS "IPO/LTO enabled")
        set_property(TARGET iris PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
    else()
        message(STATUS "IPO/LTO not supported: ${LTO_ERROR}")
    endif()
endif()

set_property(TARGET iris PROPERTY CXX_STANDARD 20)
add_definitions("-D_IRIS_VERSION=${GIT_VERSION_STRING}")

target_sources(iris PRIVATE
    main.cpp
    frontend/audio.cpp
    frontend/handlers.cpp
    frontend/vulkan.cpp
    frontend/imgui.cpp
    frontend/emu.cpp
    frontend/render.cpp
    frontend/shaders.cpp
    frontend/input.cpp
    frontend/iris.cpp
    frontend/elf.cpp
    frontend/notifications.cpp
    frontend/settings.cpp
    frontend/ui/about.cpp
    frontend/ui/bios_setting.cpp
    frontend/ui/breakpoints.cpp
    frontend/ui/control.cpp
    frontend/ui/dma.cpp
    frontend/ui/gs.cpp
    frontend/ui/intc.cpp
    frontend/ui/logs.cpp
    frontend/ui/memory.cpp
    frontend/ui/memory_card_tool.cpp
    frontend/ui/memory_search.cpp
    frontend/ui/menubar.cpp
    frontend/ui/modules.cpp
    frontend/ui/overlay.cpp
    frontend/ui/pad.cpp
    frontend/ui/settings.cpp
    frontend/ui/spu2.cpp
    frontend/ui/state.cpp
    frontend/ui/statusbar.cpp
    frontend/ui/symbols.cpp
    frontend/ui/threads.cpp
    frontend/ui/vu_disassembly.cpp
    src/ps2.c
    src/ps2_elf.c
    src/ps2_iso9660.c
    src/queue.c
    src/rom.c
    src/md5.c
    src/list.c
    src/scheduler.c
    src/dev/ds.c
    src/dev/guncon.c
    src/dev/mcd.c
    src/dev/mtap.c
    src/dev/ps1_mcd.c
    src/dev/ps1_mcd.c
    src/ee/ee_cached.cpp
    src/ee/bus.c
    src/ee/dmac.c
    src/ee/ee_dis.c
    src/ee/gif.c
    src/ee/intc.c
    src/ee/timers.c
    src/ee/vif.c
    src/ee/vu_cached.cpp
    src/ee/vu_dis.c
    src/gs/gs.c
    src/gs/renderer/null.cpp
    src/gs/renderer/renderer.cpp
    src/gs/renderer/hardware.cpp
    src/iop/bus.c
    src/iop/cdvd.c
    src/iop/disc.c
    src/iop/dma.c
    src/iop/fw.c
    src/iop/intc.c
    src/iop/iop.c
    src/iop/iop_dis.c
    src/iop/iop_export.c
    src/iop/rpc.c
    src/iop/sio2.c
    src/iop/spu2.c
    src/iop/timers.c
    src/iop/usb.c
    src/iop/disc/bin.c
    src/iop/disc/cue.c
    src/iop/disc/chd.c
    src/iop/disc/ciso.c
    src/iop/disc/iso.c
    src/iop/hle/ioman.cpp
    src/iop/hle/loadcore.c
    src/iop/hle/sysmem.c
    src/ipu/chromtable.cpp
    src/ipu/codedblockpattern.cpp
    src/ipu/dct_coeff.cpp
    src/ipu/dct_coeff_table0.cpp
    src/ipu/dct_coeff_table1.cpp
    src/ipu/ipu.cpp
    src/ipu/ipu_fifo.cpp
    src/ipu/lumtable.cpp
    src/ipu/mac_addr_inc.cpp
    src/ipu/mac_b_pic.cpp
    src/ipu/mac_i_pic.cpp
    src/ipu/mac_p_pic.cpp
    src/ipu/motioncode.cpp
    src/ipu/vlc_table.cpp
    src/shared/bios.c
    src/shared/dev9.c
    src/shared/ram.c
    src/shared/sbus.c
    src/shared/sif.c
    src/shared/speed.c
    src/shared/speed/ata.c
    src/shared/speed/eeprom.c
    src/shared/speed/flash.c
    src/s14x/nand.c
    src/s14x/syscon.c
    src/s14x/sram.c
    src/s14x/link.c
    src/s14x/ioboard.c
    src/s14x/aiboard.c
    deps/imgui/imgui.cpp
    deps/imgui/imgui_demo.cpp
    deps/imgui/imgui_draw.cpp
    deps/imgui/imgui_tables.cpp
    deps/imgui/imgui_widgets.cpp
    deps/imgui/backends/imgui_impl_sdl3.cpp
    deps/imgui/backends/imgui_impl_vulkan.cpp
    deps/implot/implot_demo.cpp
    deps/implot/implot_items.cpp
    deps/implot/implot.cpp
    deps/lz4/lib/lz4.c
)

target_include_directories(iris PRIVATE
    deps/asmjit
    deps/imgui
    deps/imgui/backends
    deps/implot
    deps/SDL/include
    deps/incbin
    deps/parallel-gs
    deps/libchdr/include
    deps/lz4/lib
    deps/stb
    deps/portable-file-dialogs
    frontend
    src
    res
)

target_link_libraries(iris PUBLIC
    asmjit::asmjit
    libdeflate::libdeflate_static
    tomlplusplus::tomlplusplus
    SDL3::SDL3-static
    parallel-gs
    chdr-static
)

if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
    find_package(Vulkan COMPONENTS MoltenVK)

    message(STATUS "VulkanSDK path: $ENV{VULKAN_SDK}")

    find_library(MOLTENVK_LIBRARY
        NAMES libMoltenVK.dylib
        PATHS ENV VULKAN_SDK
        PATH_SUFFIXES /lib
    )

    target_link_libraries(iris PUBLIC
        Vulkan::Vulkan
        ${MOLTENVK_LIBRARY}
    )
endif()

if (WIN32)
    target_link_libraries(iris PRIVATE dwmapi)
    target_sources(iris PRIVATE frontend/platform/windows.cpp)
else()
    target_sources(iris PRIVATE frontend/platform/stub.cpp)
endif()

set_target_properties(iris PROPERTIES 
    # On macOS, make a proper .app bundle instead of a bare executable
    MACOSX_BUNDLE TRUE
    # Set the Info.plist file for Apple Mobile platforms. Without this file, your app
    # will not launch. 
    MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Info.plist"
    MACOSX_BUNDLE_ICON_FILE iris.icns

    # in Xcode, create a Scheme in the schemes dropdown for the app.
    XCODE_GENERATE_SCHEME TRUE
    # Identification for Xcode
    XCODE_ATTRIBUTE_BUNDLE_IDENTIFIER "com.allkern.iris"
    XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "com.allkern.iris"
    XCODE_ATTRIBUTE_CURRENTYEAR "${CURRENTYEAR}"
    RESOURCE "${RESOURCE_FILES}"
)

# on Visual Studio, set our app as the default project
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT "${EXECUTABLE_NAME}")

# On macOS Platforms, ensure that the bundle is valid for distribution by calling fixup_bundle.
# note that fixup_bundle does not work on iOS, so you will want to use static libraries 
# or manually copy dylibs and set rpaths
message(STATUS "CMake System Name: ${CMAKE_SYSTEM_NAME}")

if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
    # tell Install about the target, otherwise fixup won't know about the transitive dependencies
    install(TARGETS iris
        BUNDLE DESTINATION ./install COMPONENT Runtime
           RUNTIME DESTINATION ./install/bin COMPONENT Runtime
    )
    
    set(BUNDLE_PATH "${CMAKE_BINARY_DIR}/iris.app") # where to look for dependencies when fixing up
    file(GLOB VULKAN_DYLIBS $ENV{VULKAN_SDK}/lib/libvulkan.*.dylib)
    set(VULKAN_DYLIBS ${VULKAN_DYLIBS} $ENV{VULKAN_SDK}/lib/libMoltenVK.dylib)
    install(CODE "
        execute_process(COMMAND echo \"Preparing to bundle iris...\")
        execute_process(COMMAND echo \"Bundle path: ${BUNDLE_PATH}\")
        execute_process(COMMAND echo \"Vulkan dylibs: ${VULKAN_DYLIBS}\")
        execute_process(COMMAND echo \"Adding local RPATH...\")
        execute_process(
            COMMAND install_name_tool -add_rpath
            \"@executable_path/../Frameworks\"
            \"${BUNDLE_PATH}/Contents/MacOS/iris\"
        )
        execute_process(COMMAND echo \"Creating ICD JSON directory...\")
        make_directory(${BUNDLE_PATH}/Contents/Resources/vulkan/icd.d)
        execute_process(COMMAND echo \"Creating Frameworks directory...\")
        make_directory(${BUNDLE_PATH}/Contents/Frameworks)
        execute_process(COMMAND echo \"Copying files...\")
        file(COPY
            ${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK_icd.json
            DESTINATION ${BUNDLE_PATH}/Contents/Resources/vulkan/icd.d/
        )
        file(COPY
            ${VULKAN_DYLIBS}
            DESTINATION ${BUNDLE_PATH}/Contents/Frameworks/
        )
        execute_process(COMMAND echo \"Signing app bundle...\")
        execute_process(COMMAND
            codesign --force --deep --sign - ${BUNDLE_PATH}
            RESULT_VARIABLE codesign_result
            OUTPUT_VARIABLE codesign_output
        )
        if (codesign_result)
            execute_process(COMMAND echo \"${codesign_output}\")
        endif()
    ")
    set(CPACK_GENERATOR "DragNDrop")
    include(CPack)
endif()

if (CMAKE_SYSTEM_NAME MATCHES "Linux")
    install(CODE
        "include(${CMAKE_CURRENT_SOURCE_DIR}/AppImage.cmake)
        make_appimage(
            EXE \"${CMAKE_CURRENT_SOURCE_DIR}/build/iris\"
            NAME \"Iris\"
            ICON \"${CMAKE_CURRENT_SOURCE_DIR}/res/iris.png\"
            DIR_ICON \"${CMAKE_CURRENT_SOURCE_DIR}/res/iris.png\"
            OUTPUT_NAME \"${CMAKE_CURRENT_SOURCE_DIR}/build/Iris-${GIT_VERSION_STRING}.AppImage\"
        )
        "
        COMPONENT Runtime
    )
endif()

================================================
FILE: Info.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
	<dict>
		<key>CFBundleDevelopmentRegion</key>
			<string>en</string>
		<key>CFBundleExecutable</key>
			<string>iris</string>
		<key>CFBundleIdentifier</key>
			<string>iris.app.0</string>
		<key>CFBundleInfoDictionaryVersion</key>
			<string>6.0</string>
		<key>CFBundleName</key>
			<string>Iris</string>
		<key>CFBundlePackageType</key>
			<string>APPL</string>
		<key>CFBundleShortVersionString</key>
			<string>0.10-alpha</string>
		<key>CFBundleSignature</key>
			<string>iris</string>
		<key>CFBundleVersion</key>
			<string>0.10-alpha</string>
		<key>LSApplicationCategoryType</key>
			<string>public.app-category.games</string>
		<key>LSMinimumSystemVersion</key>
			<string>10.15</string>
		<key>NSHighResolutionCapable</key>
			<true/>
		<key>NSPrincipalClass</key>
			<string>NSApplication</string>
		<key>CFBundleIconFile</key>
			<string>iris</string>
	</dict>
</plist>


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2025 Allkern/Lisandro Alarcon

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.


================================================
FILE: MoltenVK_icd.json
================================================
{
    "file_format_version" : "1.0.0",
    "ICD": {
        "library_path": "../../../Frameworks/libMoltenVK.dylib",
        "api_version" : "1.4.0",
        "is_portability_driver": true
    }
}


================================================
FILE: README.md
================================================
<div align="center" text-align="center" width="100%">
    <img width="55%" src="https://github.com/user-attachments/assets/d59e2d95-5791-4497-9985-442ca5115ac6">
</div>

# 🐣 Iris
Sony PlayStation 2 emulator for Windows, Linux and macOS 

## Screenshots
<div align="center" class="grid" markdown>
    <img width="47%" alt="Metal Gear Solid 3 - Snake Eater (Japan)" src="https://github.com/user-attachments/assets/9ffd0131-5fa0-4e2f-97ee-6d180f7dcdcc" />
    <img width="47%" alt="Resident Evil 4 (USA)" src="https://github.com/user-attachments/assets/d2f68c22-c6c9-4e00-9430-ecf609f9b269" />
    <img width="47%" alt="God of War II (USA)" src="https://github.com/user-attachments/assets/40747140-1b0c-4834-b3ab-e5439cc1272d" />
    <img width="47%" alt="Kingdom Hearts II (USA)" src="https://github.com/user-attachments/assets/53aa9486-958f-49c6-aa88-cd435260bb0a" />
    <img width="47%" alt="Ace Combat Zero - The Belkan War (USA)" src="https://github.com/user-attachments/assets/1adfaf21-305d-4d2c-a828-00cbbbfba920" />
    <img width="47%" alt="Virtua Fighter 4 (USA)" src="https://github.com/user-attachments/assets/1d1662ed-177d-48de-b21f-300a035da1b3" />
    <img width="47%" alt="Devil May Cry 3 - Dante's Awakening (USA)" src="https://github.com/user-attachments/assets/a7fc4654-cdb1-4a00-8187-a99ab5b4f7ea" />
    <img width="47%" alt="Ico (USA)" src="https://github.com/user-attachments/assets/419b76a4-5208-4e18-bebe-ab762c0e08ed" />
</div>

## Usage
> [!WARNING]  
> This emulator is under development, most games WILL run at very low/unplayable framerates.

### GUI
Navigate over to `Iris > Open...` and choose a disc image or ELF executable, drag-and-drop is also supported

### CLI
```
Usage: iris [OPTION]... <path-to-disc-image>

  -b, --bios               Specify a PlayStation 2 BIOS dump file
      --rom1               Specify a DVD player dump file
      --rom2               Specify a ROM2 dump file
  -d, --boot               Specify a direct kernel boot path
  -i, --disc               Specify a path to a disc image file
  -x, --executable         Specify a path to an ELF executable to be
                             loaded on system startup
      --slot1              Specify a path to a memory card file to
                             be inserted on slot 1
      --slot2              Specify a path to a memory card file to
                             be inserted on slot 2
  -h, --help               Display this help and exit
  -v, --version            Output version information and exit
```

## Features
- Support for ISO, BIN/CUE, CHD and CSO/ZSO disc image formats
- Hardware-accelerated Vulkan GS renderer with support for up to 16x SSAA
- Feature-packed debugger
- Easy to use graphical interface
- Game controller support with input remapping
- Support for post-processing shaders

## Building
> [!WARNING]  
> Building requires CMake and the Vulkan SDK on all supported platforms

### Linux
Building on Linux requires installing SDL3 dependencies and FUSE if you wish to generate AppImages.
```
sudo apt update
sudo apt upgrade
sudo add-apt-repository universe
sudo apt-get install build-essential git make \
    pkg-config cmake ninja-build gnome-desktop-testing libasound2-dev libpulse-dev \
    libaudio-dev libjack-dev libsndio-dev libx11-dev libxext-dev \
    libxrandr-dev libxcursor-dev libxfixes-dev libxi-dev libxss-dev libxtst-dev \
    libxkbcommon-dev libdrm-dev libgbm-dev libgl1-mesa-dev libgles2-mesa-dev \
    libegl1-mesa-dev libdbus-1-dev libibus-1.0-dev libudev-dev libfuse2t64
```
Then clone the repository and run CMake:
```
git clone https://github.com/allkern/iris --recursive
cd iris
cmake -S . -B build
cmake --build build -j8
```
Optionally run `cmake --install build` to generate an AppImage.

### Windows
We currently only support GCC as a compiler on Windows, this is because MSVC doesn't have an inline assembler, which we need to embed resources into the executable. This might eventually be fixed though!
```
git clone https://github.com/allkern/iris --recursive
cd iris
cmake -S . -B build -G "MinGW Makefiles"
cmake --build build -j8
```

### macOS

```
git clone https://github.com/allkern/iris --recursive
cd iris
cmake -S . -B build
cmake --build build -j8
```
Optionally run `sudo cmake --install build` to generate a macOS App Bundle

## Progress/Insights
Iris can boot/run a fairly large number of commercial games, playability may be all over the place though, some games run fairly smoothly, while others can't break the 1 digit FPS mark, this is due to the lack of EE/VU JITs which will be addressed soon.

The PlayStation 2 can have up to three processors running simultaneously at ~300 MHz, plus the IOP running at 33 MHz, not counting all the different peripherals/chips doing their own work, such as the GS rendering massive amounts of graphics, the IPU decoding MPEG-2 video, the SPU2 rendering up to 48 ADPCM audio channels at 48 KHz, and more. You can see how emulating this system can become a pretty complex task once you factor in all the processing that's done per-frame.

In order to alleviate the struggles of emulating the PS2, we have a number of optimization techniques at our disposal, some of which have already been implemented:
- Scheduling (done)
- Software fastmem (done)
- EE interpreter caching (done)
- Hardware-accelerated GS rendering (done)
- EE JIT/Dynarec (coming up)
- VU JIT/Dynarec (soon)
- Hardware fastmem (eventually)
- etc.

Integrating Parallel-GS was a big milestone for Iris, now we need to work on JITing the EE. Once that's done, I'd expect the emulator to start running a lot more games at playable speeds.

## Preservation
Iris aims to emulate not only the retail PlayStation 2, but also other systems based on the PS2, such as the PSX DESR (Japanese PS2/DVR hybrid) and all or most of the PS2-based arcade systems, work towards this goal is ongoing, in fact, Iris was the first PS2 emulator to boot [the PSX DESR BIOS/bootrom](https://www.youtube.com/watch?v=YtsoRjofYKA).

In order to emulate these systems, a pile of extra hardware needs to be implemented, such as the onboard flash memory on the PSX DESR, and the NAND storage on all of the Namco boards. This is not trivial and the lack of documentation makes it a pretty daunting task, but we're working on it.

It's worth to mention that PSX DESR support has been merged to the main branch, which means you (our beloved user) should be able to dump the BIOS out of your PSX DESR machine and run it on Iris. It won't boot past some error screens after running the boot animation but I'd say it's still pretty cool.

In addition to emulating other systems based on the PS2, Iris also aims to support **all** the features/capabilities of the retail system, this includes the often overlooked DVD player, PSBBN, Linux, and eventually all of the available external USB/SIO peripherals and input/output devices.

# Special thanks and acknowledgements
I would like to thank the emudev Discord server, Ziemas, Nelson (ncarrillo), cakehonolulu, PSI-rockin, noumi and the PCSX2 team for their kind support.

This project makes use of the following third-party libraries:
- [ImGui](https://github.com/ocornut/imgui)
- [ImPlot](https://github.com/epezent/implot)
- [SDL3](https://github.com/libsdl-org/SDL)
- [SDL_GameControllerDB](https://github.com/mdqinc/SDL_GameControllerDB)
- [incbin](https://github.com/graphitemaster/incbin)
- [Parallel-GS](https://github.com/Arntzen-software/parallel-gs)
- [libchdr](https://github.com/rtissera/libchdr)
- [libdeflate](https://github.com/ebiggers/libdeflate)
- [lz4](https://github.com/lz4/lz4)
- [toml++](https://marzer.github.io/tomlplusplus/)
- [Portable File Dialogs](https://github.com/samhocevar/portable-file-dialogs)
- [stb_image](https://github.com/nothings/stb)

Credit goes out to the developers of these libraries, Iris wouldn't have been possible without your outstanding work.

### Components
This console is significantly more complex compared to the PS1, here's a rough list of components:
```
🟡 EE (R5900) CPU
- 🟡 FPU
- 🟡 MMI (SIMD)
- 🟡 TLB
- 🟡 DMAC
- 🟢 INTC
- 🟡 Timers
- 🟢 GIF
- 🟡 GS
- 🟡 VU0
  = 🟡 Macro mode
  = 🟡 Micro mode
  = 🟡 VIF0
- 🟡 VU1 (always micro mode)
  = 🟡 VIF1
- 🟡 IPU
🟢 IOP (R3000) CPU
- 🟡 DMAC
- 🟢 INTC
- 🟡 Timers
- 🟢 CDVD
- 🟢 SIO2 (controllers and Memory Cards)
- 🟢 SPU2
- 🟡 DEV9
- 🟡 USB/FireWire?
- 🔴 Ethernet
- 🔴 PS1 backcompat (PS1 hardware)
🟢 SIF
```


================================================
FILE: compat.txt
================================================
".hack - Infection (USA)" - Boots to menus, runs very slow
"007 - Nightfire (USA)" - Hangs trying to play an FMV at the very beginning
"Arcana Heart (USA)" - REGRESSION! Seems to trash IOP memory with what looks like ADPCM data
"Babe (Australia)" - Boots, won't boot with FMV skipping enabled though
"Batman - Vengeance (USA)" - Requires MFIFO
"Big Mutha Truckers (USA)" - Prints "CD Error 0xfd, ditching this request", reads sectors 1eb02,1eb12,1eb22 repeatedly
"Buffy the Vampire Slayer - Chaos Bleeds (USA)" - Gets stuck waiting for GIF_STAT.8-9 to be non-zero
"Bully (USA)" - Boots in-game, runs incredibly slow, textures broken, image looks yellow tinted (similar to GoW)
"Dead or Alive 2 (Japan)" - Nothing, prints "Read Time Out 15000(msec)" to the terminal, possibly CDVD-related?
"Final Fantasy XII (USA)" - Enables MFIFO through an 8-bit write to CTRL, uses transfer "mode 3" (actually just chain mode)
"Gallop Racer 2006 (USA)" - Requires proper EE timings (at most 2x underclock)
"Klonoa 2 - Lunatea's Veil (USA)" - Doesn't work on Release builds (!), requires 16-bit DMAC writes
"Namco Museum 50th Anniversary (USA)" - Requires MFIFO
"R-Type Final (Japan)" - Requires MFIFO
"Sega Ages 2500 Series Vol. 23 - Sega Memorial Selection (Japan)" - GIF DMA read from NULL
"Sega Genesis Collection (USA)" - Works, "forgets" to change the videomode causing wrong graphics at startup (needs 24-bit 640x448 interlaced?)
"Simpsons, The - Hit & Run (USA)" - Needs MFIFO
"Tekken 4 (USA)" - Needs MFIFO
"Tekken Tag Tournament (USA) (v1.00)" - Needs MFIFO
"Thunder Force VI (Japan)" - Crashes on an invalid GIF DMA address when starting up (compare against Dobie)
"Virtua Fighter 4 - Evolution (USA)" - Works, uses filling mode
"Virtua Fighter - Cyber Generation - Judgment Six no Yabou (Japan)" - PMTHL unimplemented
"We Love Katamari (USA)" - Uses filling mode, gets stuck trying to play an FMV after the Namco logo?

================================================
FILE: frontend/arcade.hpp
================================================
#include <toml++/toml.hpp>

#include "ps2.h"

const toml::table g_arcade_definitions = toml::table {
    { "pacmanap", toml::table {
        { "system", PS2_SYSTEM_NAMCO_S147 },
        { "name", "Pac-Man's Arcade Party" },
        { "nand", "kp007a_k9k8g08u0b_pmaam12-na-c.ic26" },
        { "bios", "common_system147b_bootrom.ic1" },
        { "boot", "atfile0:PMAAC.elf" }
    }},
    { "pacmanbr", toml::table {
        { "system", PS2_SYSTEM_NAMCO_S147 },
        { "name", "Pac-Man: Battle Royale" },
        { "nand", "pbr102-2-na-mpro-a13_kp006b.ic26" },
        { "bios", "common_system147b_bootrom.ic1" },
        { "boot", "atfile0:pacmanBR.elf" }
    }},
    { "akaiser", toml::table {
        { "system", PS2_SYSTEM_NAMCO_S147 },
        { "name", "Animal Kaiser: The King of Animals" },
        { "nand", "kp005a_ana1004-na-b.ic26" },
        { "bios", "common_system147b_bootrom.ic1" },
        { "boot", "atfile0:main.elf" },
        { "ioboard_mode", 1 }
    }},
    { "akaievo", toml::table {
        { "system", PS2_SYSTEM_NAMCO_S147 },
        { "name", "Animal Kaiser Evolution" },
        { "nand", "kp012b_k9k8g08u0b.ic31" },
        { "bios", "common_system147b_bootrom.ic1" },
        { "boot", "atfile0:main.elf" },
        { "ioboard_mode", 1 }
    }},
    { "umilucky", toml::table {
        { "system", PS2_SYSTEM_NAMCO_S148 },
        { "name", "Umimonogatari Lucky Marine Theater" },
        { "nand", "uls100-1-na-mpro-b01_kp008a.ic31" },
        { "bios", "common_system148_bootrom.ic1" },
        { "boot", "atfile0:prog.elf" }
    }}
};

================================================
FILE: frontend/audio.cpp
================================================
#include <chrono>
#include <thread>

#include "iris.hpp"

namespace iris::audio {

void update(void* userdata, SDL_AudioStream* stream, int additional_amount, int total_amount) {
    iris::instance* iris = (iris::instance*)userdata;

    if (iris->pause)
        std::this_thread::sleep_for(std::chrono::milliseconds(1));

    if (iris->pause || !additional_amount)
        return;

    iris->audio_buf.resize(additional_amount);

    for (int i = 0; i < additional_amount; i++) {
        iris->audio_buf[i] = ps2_spu2_get_sample(iris->ps2->spu2, !iris->mute_adma);
        iris->audio_buf[i].s16[0] *= iris->mute ? 0.0f : iris->volume;
        iris->audio_buf[i].s16[1] *= iris->mute ? 0.0f : iris->volume;
    }

    SDL_PutAudioStreamData(stream, (void*)iris->audio_buf.data(), additional_amount * sizeof(spu2_sample));
}

bool init(iris::instance* iris) {
    SDL_AudioSpec spec;

    spec.channels = 2;
    spec.format = SDL_AUDIO_S16;
    spec.freq = 48000;

    iris->stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &spec, iris::audio::update, iris);

    if (!iris->stream) {
        fprintf(stderr, "audio: Failed to open audio device\n");

        return false;
    }

    /* SDL_OpenAudioDeviceStream starts the device paused. You have to tell it to start! */
    SDL_ResumeAudioStreamDevice(iris->stream);

    return true;
}

void close(iris::instance* iris) {
    if (!iris->stream) {
        return;
    }

    SDL_PauseAudioStreamDevice(iris->stream);
    SDL_DestroyAudioStream(iris->stream);

    iris->stream = nullptr;
}

bool mute(iris::instance* iris) {
    iris->prev_mute = iris->mute;

    iris->mute = true;

    return iris->prev_mute;
}

void unmute(iris::instance* iris) {
    iris->mute = iris->prev_mute;
}

}

================================================
FILE: frontend/config.hpp
================================================
#pragma once

#ifndef _IRIS_VERSION
#define _IRIS_VERSION latest
#endif

#ifndef _IRIS_COMMIT
#define _IRIS_COMMIT latest
#endif

#ifndef _IRIS_OSVERSION
#define _IRIS_OSVERSION unknown
#endif

#define STR1(m) #m
#define STR(m) STR1(m)

#define IRIS_TITLE "Iris (" STR(_IRIS_VERSION) ")"
#define IRIS_VULKAN_API_VERSION VK_API_VERSION_1_2

================================================
FILE: frontend/elf.cpp
================================================
#include <cstdlib>
#include <cstdint>
#include <cstdio>

#include "iris.hpp"

#ifdef __linux__
#include <elf.h>
#else
#include "elf.h"
#endif

namespace iris::elf {

void load_symbols_from_memory(iris::instance* iris, char* buf) {
    if (!buf)
        return;

    // Clear previous symbols
    iris->symbols.clear();
    iris->strtab.clear();

    Elf32_Ehdr* ehdr = (Elf32_Ehdr*)buf;

    // Parse ELF header
    if (strncmp((char*)ehdr->e_ident, "\x7f" "ELF", 4) != 0) {
        printf("elf: Invalid ELF magic number\n");

        return;
    }

    // Read symbol table header
    Elf32_Shdr* symtab = nullptr;

    for (int i = 0; i < ehdr->e_shnum; i++) {
        Elf32_Shdr* shdr = (Elf32_Shdr*)(buf + ehdr->e_shoff + (i * ehdr->e_shentsize));

        if ((shdr->sh_type == SHT_STRTAB) && (i != ehdr->e_shstrndx)) {
            printf("elf: Loading string table size=%x offset=%x\n", shdr->sh_size, shdr->sh_offset);

            // Get string table
            iris->strtab.resize(shdr->sh_size);

            memcpy(iris->strtab.data(), buf + shdr->sh_offset, shdr->sh_size);
        }

        if (shdr->sh_type == SHT_SYMTAB) {
            symtab = shdr;

            printf("elf: Found symbol table size=%x offset=%x\n", symtab->sh_size, symtab->sh_offset);
        }
    }

    // No symbol table present
    if (!symtab) {
        printf("elf: No symbol table found\n");

        return;
    }

    if (!symtab->sh_entsize) {
        printf("elf: Invalid symbol table entry size\n");

        return;
    }

    if (!symtab->sh_size) {
        printf("elf: Symbol table is empty\n");

        return;
    }

    size_t symbol_count = symtab->sh_size / symtab->sh_entsize;

    printf("elf: Found symbol table with %d symbols\n", symbol_count);

    // Read symbol table
    Elf32_Sym* sym;

    for (int i = 0; i < symbol_count; i++) {
        sym = (Elf32_Sym*)(buf + symtab->sh_offset + (i * symtab->sh_entsize));

        if (ELF32_ST_TYPE(sym->st_info) != STT_FUNC)
            continue;

        elf_symbol symbol;

        symbol.name = (char*)(iris->strtab.data() + sym->st_name);
        symbol.addr = sym->st_value;
        symbol.size = sym->st_size;

        // printf("symbol: %s at 0x%08x\n", symbol.name, symbol.addr);

        iris->symbols.push_back(symbol);
    }
}

bool load_symbols_from_disc(iris::instance* iris) {
    if (!iris->ps2 || !iris->ps2->cdvd || !iris->ps2->cdvd->disc) {
        printf("elf: No disc loaded\n");

        return false;
    }

    char* elf = disc_read_boot_elf(iris->ps2->cdvd->disc, 0);

    load_symbols_from_memory(iris, elf);

    free(elf);

    return true;
}

bool load_symbols_from_file(iris::instance* iris, std::string path) {
    if (path.empty()) {
        printf("elf: No file path provided\n");

        return false;
    }

    FILE* file = fopen(path.c_str(), "rb");

    if (!file) {
        printf("elf: Failed to open file %s\n", path.c_str());

        return false;
    }

    fseek(file, 0, SEEK_END);
    size_t size = ftell(file);
    fseek(file, 0, SEEK_SET);

    char* buf = new char[size];

    fread(buf, 1, size, file);
    fclose(file);

    load_symbols_from_memory(iris, buf);

    delete[] buf;

    return true;
}

}

================================================
FILE: frontend/emu.cpp
================================================
#include "iris.hpp"
#include "arcade.hpp"

#include <filesystem>
#include <optional>

namespace iris::emu {

bool init(iris::instance* iris) {
    // Initialize our emulator state
    iris->ps2 = ps2_create();

    ps2_init(iris->ps2);
    ps2_init_tty_handler(iris->ps2, PS2_TTY_EE, iris::handle_ee_tty_event, iris);
    ps2_init_tty_handler(iris->ps2, PS2_TTY_IOP, iris::handle_iop_tty_event, iris);
    ps2_init_tty_handler(iris->ps2, PS2_TTY_SYSMEM, iris::handle_sysmem_tty_event, iris);

    iris->ds[0] = ds_attach(iris->ps2->sio2, 0);

    return true;
}

void destroy(iris::instance* iris) {
    if (iris->ps2) ps2_destroy(iris->ps2);
}

const char* get_extension(const char* path) {
    const char* dot = strrchr(path, '.');

    if (!dot || dot == path)
        return nullptr;

    return dot + 1;
}

template <typename T> std::optional<T> query_arcade_value(std::string arcade_name, std::string key) {
    auto it = g_arcade_definitions.find(arcade_name);

    if (it == g_arcade_definitions.end())
        return {};

    auto arcade_table = it->second.as_table();

    auto key_it = arcade_table->find(key);

    if (key_it == arcade_table->end())
        return {};

    if constexpr (std::is_same_v<T, std::string>) {
        return key_it->second.as_string()->get();
    } else if constexpr (std::is_integral_v<T>) {
        return key_it->second.as_integer()->get();
    } else if constexpr (std::is_same_v<T, bool>) {
        return key_it->second.as_boolean()->get();
    } else if constexpr (std::is_floating_point_v<T>) {
        return key_it->second.as_floating_point()->get();
    } else if constexpr (std::is_array_v<T>) {
        return key_it->second.as_array();
    } else {
        return {};
    }

    return {};
}

bool load_arcade(iris::instance* iris, std::string path) {
    std::filesystem::path base_path(path);

    std::string id = base_path.stem().string();
    std::string name = query_arcade_value<std::string>(id, "name").value_or("");

    if (!name.size()) {
        return false;
    }

    printf("emu: Loading arcade game \"%s\"...\n", id.c_str(), name.c_str());

    int system = query_arcade_value<int>(id, "system").value_or(PS2_SYSTEM_AUTO);

    switch (system) {
        case PS2_SYSTEM_NAMCO_S147:
        case PS2_SYSTEM_NAMCO_S148: {
            std::string bios = query_arcade_value<std::string>(id, "bios").value_or("");
            std::string nand = query_arcade_value<std::string>(id, "nand").value_or("");

            int ioboard_mode = query_arcade_value<int>(id, "ioboard_mode").value_or(0);

            std::filesystem::path bios_path = base_path / bios;
            std::filesystem::path nand_path = base_path / nand;
            std::filesystem::path sram_path = base_path / "sram.bin";

            if (!std::filesystem::exists(bios_path)) {
                printf("emu: Couldn't find bootrom file \"%s\"\n", bios_path.string().c_str());

                push_info(iris, "Couldn't start arcade game (Missing bootrom)");

                return false;
            }

            if (!std::filesystem::exists(nand_path)) {
                printf("emu: Couldn't find NAND file \"%s\"\n", nand_path.string().c_str());

                push_info(iris, "Couldn't start arcade game (Missing NAND)");

                return false;
            }

            ps2_set_system(iris->ps2, system);
            ps2_load_bios(iris->ps2, bios_path.string().c_str());
            s14x_nand_load(iris->ps2->s14x_nand, nand_path.string().c_str());
            s14x_sram_load(iris->ps2->s14x_sram, sram_path.string().c_str());

            if (iris->ps2->s14x_ioboard) {
                iris->ps2->s14x_ioboard->mode = ioboard_mode;
            }

            ps2_reset(iris->ps2);

            iris->loaded = name + " (" + id + ")";

            if (iris->autostart) {
                iris->pause = false;
            }

            return true;
        } break;

        default: {
            const char* names[] = {
                "Auto",
                "Retail (Fat)",
                "Retail (Slim)",
                "PSX DESR",
                "TEST unit (DTL-H)",
                "TOOL unit (DTL-T)",
                "Konami Python",
                "Konami Python 2",
                "Namco System 147",
                "Namco System 148",
                "Namco System 246",
                "Namco System 256"
            };

            printf("emu: %s isn't supported yet\n", names[system]);
        } break;
    }

    return false;
}

int attach_memory_card(iris::instance* iris, int slot, const char* path) {
    detach_memory_card(iris, slot);

    FILE* file = fopen(path, "rb");

    if (!file) {
        return 0;
    }

    fseek(file, 0, SEEK_END);
    int size = ftell(file);
    fclose(file);

    if (size < 0x800000) {
        struct ps1_mcd_state* mcd = ps1_mcd_attach(iris->ps2->sio2, slot+2, path);

        std::string ext = get_extension(path);

        if (ext == "psm" || ext == "pocket") {
            ps1_mcd_set_type(mcd, 1);

            iris->mcd_slot_type[slot] = 3;
        } else {
            ps1_mcd_set_type(mcd, 0);

            iris->mcd_slot_type[slot] = 2;
        }

        return 1;
    }

    mcd_attach(iris->ps2->sio2, slot+2, path);

    iris->mcd_slot_type[slot] = 1;

    return 1;
}

void detach_memory_card(iris::instance* iris, int slot) {
    iris->mcd_slot_type[slot] = 0;

    ps2_sio2_detach_device(iris->ps2->sio2, slot+2);
}

const char* g_system_names[] = {
    "Auto",
    "PlayStation 2 (Fat)",
    "PlayStation 2 (Slim)",
    "PSX DESR",
    "TEST Unit",
    "TOOL Unit",
    "Konami Python",
    "Konami Python 2",
    "Namco System 147",
    "Namco System 148",
    "Namco System 246",
    "Namco System 256"
};

const char* get_system_name(iris::instance* iris, int system) {
    return g_system_names[system];
}

const char* get_current_system_name(iris::instance* iris) {
    switch (iris->system) {
        case PS2_SYSTEM_AUTO: return get_system_name(iris, iris->ps2->detected_system);
        case PS2_SYSTEM_RETAIL:
        case PS2_SYSTEM_RETAIL_DECKARD:
        case PS2_SYSTEM_DESR:
        case PS2_SYSTEM_TEST:
        case PS2_SYSTEM_TOOL:
        case PS2_SYSTEM_KONAMI_PYTHON:
        case PS2_SYSTEM_KONAMI_PYTHON2:
        case PS2_SYSTEM_NAMCO_S147:
        case PS2_SYSTEM_NAMCO_S148:
        case PS2_SYSTEM_NAMCO_S246:
        case PS2_SYSTEM_NAMCO_S256:
            return g_system_names[iris->system];
        default: return "Unknown";
    }
}

int get_system_count(iris::instance* iris) {
    return sizeof(g_system_names) / sizeof(const char*);
}

}

================================================
FILE: frontend/handlers.cpp
================================================
#include "iris.hpp"

namespace iris {

void handle_ee_tty_event(void* udata, char c) {
    iris::instance* iris = (iris::instance*)udata;

    if (c == '\r')
        return;

    if (c == '\n') {
        iris->ee_log.push_back("");
    } else {
        iris->ee_log.back().push_back(c);
    }
}

void handle_iop_tty_event(void* udata, char c) {
    iris::instance* iris = (iris::instance*)udata;

    if (c == '\r')
        return;

    if (c == '\n') {
        iris->iop_log.push_back("");
    } else {
        iris->iop_log.back().push_back(c);
    }
}

void handle_sysmem_tty_event(void* udata, char c) {
    iris::instance* iris = (iris::instance*)udata;

    if (c == '\r')
        return;

    if (c == '\n') {
        iris->sysmem_log.push_back("");
    } else {
        iris->sysmem_log.back().push_back(c);
    }
}

}

================================================
FILE: frontend/imgui.cpp
================================================
#include "iris.hpp"

#include "imgui.h"
#include "imgui_impl_sdl3.h"
#include "imgui_impl_vulkan.h"
#include "implot.h"

#include <SDL3/SDL.h>
#include <SDL3/SDL_vulkan.h>

#include <array>

// External includes
#include "res/IconsMaterialSymbols.h"

// INCBIN stuff
#define INCBIN_PREFIX g_
#define INCBIN_STYLE INCBIN_STYLE_SNAKE

#include "incbin.h"

INCBIN(roboto, "../res/Roboto-Regular.ttf");
INCBIN(roboto_black, "../res/Roboto-Black.ttf");
INCBIN(symbols, "../res/MaterialSymbolsRounded.ttf");
INCBIN(firacode, "../res/FiraCode-Regular.ttf");
INCBIN(ps1_memory_card_icon, "../res/ps1_mcd.png");
INCBIN(ps2_memory_card_icon, "../res/ps2_mcd.png");
INCBIN(dualshock2_icon, "../res/ds2.png");
INCBIN(pocketstation_icon, "../res/pocketstation.png");
INCBIN(iris_icon, "../res/iris.png");
INCBIN(vertex_shader, "../shaders/vertex.spv");
INCBIN(fragment_shader, "../shaders/fragment.spv");

#include "stb_image.h"

#define VOLK_IMPLEMENTATION
#include <volk.h>

namespace iris::imgui {

static constexpr uint32_t DESCRIPTOR_SET_RING_SIZE = 8;

static const ImWchar g_icon_range[] = { ICON_MIN_MS, ICON_MAX_16_MS, 0 };

static bool setup_vulkan_window(iris::instance* iris, ImGui_ImplVulkanH_Window* wd, int width, int height, bool vsync) {
    wd->Surface = iris->surface;

    VkAttachmentDescription attachment = {};
    attachment.format = wd->SurfaceFormat.format;
    attachment.samples = VK_SAMPLE_COUNT_1_BIT;
    attachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
    attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
    attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
    attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
    attachment.initialLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
    attachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;

    wd->AttachmentDesc = attachment;

    // Check for WSI support
    VkBool32 res;

    vkGetPhysicalDeviceSurfaceSupportKHR(iris->physical_device, iris->queue_family, wd->Surface, &res);

    if (!res) {
        fprintf(stderr, "imgui: No WSI support on physical device\n");
        
        return false;
    }

    // Select Surface Format
    const VkFormat requestSurfaceImageFormat[] = {
        VK_FORMAT_B8G8R8A8_UNORM,
        VK_FORMAT_R8G8B8A8_UNORM,
        VK_FORMAT_B8G8R8_UNORM,
        VK_FORMAT_R8G8B8_UNORM
    };

    const VkColorSpaceKHR requestSurfaceColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;

    wd->SurfaceFormat = ImGui_ImplVulkanH_SelectSurfaceFormat(
        iris->physical_device,
        wd->Surface,
        requestSurfaceImageFormat,
        (size_t)IM_ARRAYSIZE(requestSurfaceImageFormat),
        requestSurfaceColorSpace
    );

    // Select Present Mode
    std::vector <VkPresentModeKHR> present_modes;

    if (vsync) {
        present_modes.push_back(VK_PRESENT_MODE_FIFO_KHR);
    } else {
        present_modes.push_back(VK_PRESENT_MODE_MAILBOX_KHR);
        present_modes.push_back(VK_PRESENT_MODE_IMMEDIATE_KHR);
        present_modes.push_back(VK_PRESENT_MODE_FIFO_KHR);
    }
 
    wd->PresentMode = ImGui_ImplVulkanH_SelectPresentMode(
        iris->physical_device,
        wd->Surface,
        present_modes.data(),
        present_modes.size()
    );

    // Create SwapChain, RenderPass, Framebuffer, etc.
    IM_ASSERT(iris->min_image_count >= 2);

    ImGui_ImplVulkanH_CreateOrResizeWindow(
        iris->instance,
        iris->physical_device,
        iris->device,
        wd,
        iris->queue_family,
        VK_NULL_HANDLE,
        width, height,
        iris->min_image_count,
        0
    );

    return true;
}

void set_vsync(iris::instance* iris, bool vsync) {
    std::vector <VkPresentModeKHR> present_modes;

    if (vsync) {
        present_modes.push_back(VK_PRESENT_MODE_FIFO_KHR);
    } else {
        present_modes.push_back(VK_PRESENT_MODE_MAILBOX_KHR);
        present_modes.push_back(VK_PRESENT_MODE_IMMEDIATE_KHR);
        present_modes.push_back(VK_PRESENT_MODE_FIFO_KHR);
    }
 
    iris->main_window_data.PresentMode = ImGui_ImplVulkanH_SelectPresentMode(
        iris->physical_device,
        iris->main_window_data.Surface,
        present_modes.data(),
        present_modes.size()
    );

    render::refresh(iris);
}

bool setup_fonts(iris::instance* iris, ImGuiIO& io) {
    io.Fonts->AddFontDefault();

    ImFontConfig config;
    config.MergeMode = true;
    config.GlyphMinAdvanceX = 13.0f;
    config.GlyphOffset = ImVec2(0.0f, 4.0f);
    config.FontDataOwnedByAtlas = false;

    ImFontConfig config_no_own;
    config_no_own.FontDataOwnedByAtlas = false;

    iris->font_small_code = io.Fonts->AddFontFromMemoryTTF((void*)g_firacode_data, g_firacode_size, 12.0F, &config_no_own);
    iris->font_code       = io.Fonts->AddFontFromMemoryTTF((void*)g_firacode_data, g_firacode_size, 16.0F, &config_no_own);
    iris->font_small      = io.Fonts->AddFontFromMemoryTTF((void*)g_roboto_data, g_roboto_size, 12.0F, &config_no_own);
    iris->font_heading    = io.Fonts->AddFontFromMemoryTTF((void*)g_roboto_data, g_roboto_size, 20.0F, &config_no_own);
    iris->font_body       = io.Fonts->AddFontFromMemoryTTF((void*)g_roboto_data, g_roboto_size, 16.0F, &config_no_own);
    iris->font_icons      = io.Fonts->AddFontFromMemoryTTF((void*)g_symbols_data, g_symbols_size, 20.0F, &config, g_icon_range);
    iris->font_icons_big  = io.Fonts->AddFontFromMemoryTTF((void*)g_symbols_data, g_symbols_size, 50.0F, &config_no_own, g_icon_range);
    iris->font_black      = io.Fonts->AddFontFromMemoryTTF((void*)g_roboto_black_data, g_roboto_black_size, 30.0F, &config_no_own);

    if (!iris->font_small_code ||
        !iris->font_code ||
        !iris->font_small ||
        !iris->font_heading ||
        !iris->font_body ||
        !iris->font_icons ||
        !iris->font_icons_big ||
        !iris->font_black) {
        return false;
    }

    io.FontDefault = iris->font_icons;

    return true;
}

void set_theme(iris::instance* iris, int theme, bool set_bg_color) {
    // Init 'Granite' theme
    ImGuiStyle& style = ImGui::GetStyle();
    style.WindowPadding           = ImVec2(8.0, 8.0);
    style.FramePadding            = ImVec2(5.0, 5.0);
    style.ItemSpacing             = ImVec2(8.0, 6.0);
    style.WindowBorderSize        = 0;
    style.ChildBorderSize         = 0;
    style.FrameBorderSize         = 1;
    style.PopupBorderSize         = 0;
    style.TabBorderSize           = 0;
    style.TabBarBorderSize        = 0;
    style.WindowRounding          = 6;
    style.ChildRounding           = 4;
    style.FrameRounding           = 4;
    style.PopupRounding           = 4;
    style.ScrollbarRounding       = 9;
    style.GrabRounding            = 2;
    style.TabRounding             = 4;
    style.WindowTitleAlign        = ImVec2(0.5, 0.5);
    style.DockingSeparatorSize    = 0;
    style.SeparatorTextBorderSize = 1;
    style.SeparatorTextPadding    = ImVec2(20, 0);

    // Use ImGui's default dark style as a base for our own style
    ImGui::StyleColorsDark();

    switch (theme) {
        case IRIS_THEME_GRANITE: {
            ImVec4* colors = style.Colors;

            colors[ImGuiCol_Text]                   = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
            colors[ImGuiCol_TextDisabled]           = ImVec4(0.35f, 0.35f, 0.35f, 1.00f);
            colors[ImGuiCol_WindowBg]               = ImVec4(0.02f, 0.02f, 0.02f, 1.00f);
            colors[ImGuiCol_ChildBg]                = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
            colors[ImGuiCol_PopupBg]                = ImVec4(0.07f, 0.09f, 0.10f, 1.00f);
            colors[ImGuiCol_Border]                 = ImVec4(0.10f, 0.12f, 0.13f, 1.00f);
            colors[ImGuiCol_BorderShadow]           = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
            colors[ImGuiCol_FrameBg]                = ImVec4(0.10f, 0.12f, 0.13f, 0.50f);
            colors[ImGuiCol_FrameBgHovered]         = ImVec4(0.20f, 0.24f, 0.26f, 0.50f);
            colors[ImGuiCol_FrameBgActive]          = ImVec4(0.29f, 0.35f, 0.39f, 0.50f);
            colors[ImGuiCol_TitleBg]                = ImVec4(0.04f, 0.04f, 0.04f, 1.00f);
            colors[ImGuiCol_TitleBgActive]          = ImVec4(0.16f, 0.20f, 0.22f, 1.00f);
            colors[ImGuiCol_TitleBgCollapsed]       = ImVec4(0.00f, 0.00f, 0.00f, 0.51f);
            colors[ImGuiCol_MenuBarBg]              = ImVec4(0.14f, 0.14f, 0.14f, 1.00f);
            colors[ImGuiCol_ScrollbarBg]            = ImVec4(0.02f, 0.02f, 0.02f, 0.53f);
            colors[ImGuiCol_ScrollbarGrab]          = ImVec4(0.31f, 0.31f, 0.31f, 1.00f);
            colors[ImGuiCol_ScrollbarGrabHovered]   = ImVec4(0.41f, 0.41f, 0.41f, 1.00f);
            colors[ImGuiCol_ScrollbarGrabActive]    = ImVec4(0.51f, 0.51f, 0.51f, 1.00f);
            colors[ImGuiCol_CheckMark]              = ImVec4(0.88f, 0.88f, 0.88f, 1.00f);
            colors[ImGuiCol_SliderGrab]             = ImVec4(0.39f, 0.47f, 0.52f, 0.50f);
            colors[ImGuiCol_SliderGrabActive]       = ImVec4(0.49f, 0.59f, 0.65f, 0.50f);
            colors[ImGuiCol_Button]                 = ImVec4(0.13f, 0.16f, 0.17f, 0.25f);
            colors[ImGuiCol_ButtonHovered]          = ImVec4(0.20f, 0.24f, 0.26f, 0.50f);
            colors[ImGuiCol_ButtonActive]           = ImVec4(0.29f, 0.35f, 0.39f, 0.50f);
            colors[ImGuiCol_Header]                 = ImVec4(0.13f, 0.16f, 0.17f, 0.50f);
            colors[ImGuiCol_HeaderHovered]          = ImVec4(0.20f, 0.24f, 0.26f, 0.50f);
            colors[ImGuiCol_HeaderActive]           = ImVec4(0.29f, 0.35f, 0.39f, 0.50f);
            colors[ImGuiCol_Separator]              = ImVec4(0.23f, 0.28f, 0.30f, 1.00f);
            colors[ImGuiCol_SeparatorHovered]       = ImVec4(0.33f, 0.39f, 0.43f, 1.00f);
            colors[ImGuiCol_SeparatorActive]        = ImVec4(0.38f, 0.46f, 0.51f, 1.00f);
            colors[ImGuiCol_ResizeGrip]             = ImVec4(0.15f, 0.20f, 0.22f, 1.00f);
            colors[ImGuiCol_ResizeGripHovered]      = ImVec4(0.00f, 0.30f, 0.25f, 1.00f);
            colors[ImGuiCol_ResizeGripActive]       = ImVec4(0.00f, 0.39f, 0.32f, 1.00f);
            colors[ImGuiCol_InputTextCursor]        = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
            colors[ImGuiCol_TabHovered]             = ImVec4(0.23f, 0.28f, 0.30f, 0.59f);
            colors[ImGuiCol_Tab]                    = ImVec4(0.20f, 0.24f, 0.26f, 0.59f);
            colors[ImGuiCol_TabSelected]            = ImVec4(0.26f, 0.31f, 0.35f, 0.59f);
            colors[ImGuiCol_TabSelectedOverline]    = ImVec4(0.00f, 0.39f, 0.32f, 1.00f);
            colors[ImGuiCol_TabDimmed]              = ImVec4(0.07f, 0.10f, 0.15f, 0.97f);
            colors[ImGuiCol_TabDimmedSelected]      = ImVec4(0.10f, 0.12f, 0.13f, 1.00f);
            colors[ImGuiCol_TabDimmedSelectedOverline]  = ImVec4(0.50f, 0.50f, 0.50f, 0.00f);
            colors[ImGuiCol_DockingPreview]         = ImVec4(0.15f, 0.20f, 0.22f, 1.00f);
            colors[ImGuiCol_DockingEmptyBg]         = ImVec4(0.20f, 0.20f, 0.20f, 1.00f);
            colors[ImGuiCol_PlotLines]              = ImVec4(0.61f, 0.61f, 0.61f, 1.00f);
            colors[ImGuiCol_PlotLinesHovered]       = ImVec4(1.00f, 0.43f, 0.35f, 1.00f);
            colors[ImGuiCol_PlotHistogram]          = ImVec4(0.90f, 0.70f, 0.00f, 1.00f);
            colors[ImGuiCol_PlotHistogramHovered]   = ImVec4(1.00f, 0.60f, 0.00f, 1.00f);
            colors[ImGuiCol_TableHeaderBg]          = ImVec4(0.19f, 0.19f, 0.20f, 1.00f);
            colors[ImGuiCol_TableBorderStrong]      = ImVec4(0.31f, 0.31f, 0.35f, 1.00f);
            colors[ImGuiCol_TableBorderLight]       = ImVec4(0.23f, 0.23f, 0.25f, 1.00f);
            colors[ImGuiCol_TableRowBg]             = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
            colors[ImGuiCol_TableRowBgAlt]          = ImVec4(1.00f, 1.00f, 1.00f, 0.06f);
            colors[ImGuiCol_TextLink]               = ImVec4(0.26f, 0.59f, 0.98f, 1.00f);
            colors[ImGuiCol_TextSelectedBg]         = ImVec4(0.15f, 0.20f, 0.22f, 1.00f);
            colors[ImGuiCol_DragDropTarget]         = ImVec4(0.29f, 0.38f, 0.42f, 1.00f);
            colors[ImGuiCol_NavCursor]              = ImVec4(0.15f, 0.20f, 0.22f, 1.00f);
            colors[ImGuiCol_NavWindowingHighlight]  = ImVec4(1.00f, 1.00f, 1.00f, 0.70f);
            colors[ImGuiCol_NavWindowingDimBg]      = ImVec4(0.80f, 0.80f, 0.80f, 0.20f);
            colors[ImGuiCol_ModalWindowDimBg]       = ImVec4(0.00f, 0.00f, 0.00f, 0.35f);

            if (!set_bg_color) break;

            iris->clear_value.color.float32[0] = 0.11f;
            iris->clear_value.color.float32[1] = 0.11f;
            iris->clear_value.color.float32[2] = 0.11f;
            iris->clear_value.color.float32[3] = 1.00f;
        } break;

        case IRIS_THEME_IMGUI_DARK: {
            ImGui::StyleColorsDark();

            if (!set_bg_color) break;

            iris->clear_value.color.float32[0] = 0.11f;
            iris->clear_value.color.float32[1] = 0.11f;
            iris->clear_value.color.float32[2] = 0.11f;
            iris->clear_value.color.float32[3] = 1.00f;
        } break;

        case IRIS_THEME_IMGUI_LIGHT: {
            ImGui::StyleColorsLight();

            if (!set_bg_color) break;

            iris->clear_value.color.float32[0] = 0.89f;
            iris->clear_value.color.float32[1] = 0.89f;
            iris->clear_value.color.float32[2] = 0.89f;
            iris->clear_value.color.float32[3] = 1.00f;
        } break;

        case IRIS_THEME_IMGUI_CLASSIC: {
            ImGui::StyleColorsClassic();

            if (!set_bg_color) break;

            iris->clear_value.color.float32[0] = 0.11f;
            iris->clear_value.color.float32[1] = 0.11f;
            iris->clear_value.color.float32[2] = 0.11f;
            iris->clear_value.color.float32[3] = 1.00f;
        } break;

        case IRIS_THEME_CHERRY: {
            // cherry colors, 3 intensities
            #define HI(v)   ImVec4(0.502f, 0.075f, 0.256f, v)
            #define MED(v)  ImVec4(0.455f, 0.198f, 0.301f, v)
            #define LOW(v)  ImVec4(0.232f, 0.201f, 0.271f, v)
            // backgrounds
            #define BG(v)   ImVec4(0.200f, 0.220f, 0.270f, v)
            // text
            #define TEXT(v) ImVec4(0.860f, 0.930f, 0.890f, v)

            auto &style = ImGui::GetStyle();
            style.Colors[ImGuiCol_Text]                  = TEXT(0.78f);
            style.Colors[ImGuiCol_TextDisabled]          = TEXT(0.28f);
            style.Colors[ImGuiCol_WindowBg]              = ImVec4(0.13f, 0.14f, 0.17f, 1.00f);
            style.Colors[ImGuiCol_ChildBg]               = BG( 0.58f);
            style.Colors[ImGuiCol_PopupBg]               = BG( 0.9f);
            style.Colors[ImGuiCol_Border]                = ImVec4(0.31f, 0.31f, 1.00f, 0.00f);
            style.Colors[ImGuiCol_BorderShadow]          = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
            style.Colors[ImGuiCol_FrameBg]               = BG( 1.00f);
            style.Colors[ImGuiCol_FrameBgHovered]        = MED( 0.78f);
            style.Colors[ImGuiCol_FrameBgActive]         = MED( 1.00f);
            style.Colors[ImGuiCol_TitleBg]               = LOW( 1.00f);
            style.Colors[ImGuiCol_TitleBgActive]         = HI( 1.00f);
            style.Colors[ImGuiCol_TitleBgCollapsed]      = BG( 0.75f);
            style.Colors[ImGuiCol_MenuBarBg]             = BG( 0.47f);
            style.Colors[ImGuiCol_ScrollbarBg]           = BG( 1.00f);
            style.Colors[ImGuiCol_ScrollbarGrab]         = ImVec4(0.09f, 0.15f, 0.16f, 1.00f);
            style.Colors[ImGuiCol_ScrollbarGrabHovered]  = MED( 0.78f);
            style.Colors[ImGuiCol_ScrollbarGrabActive]   = MED( 1.00f);
            style.Colors[ImGuiCol_CheckMark]             = ImVec4(0.71f, 0.22f, 0.27f, 1.00f);
            style.Colors[ImGuiCol_SliderGrab]            = ImVec4(0.47f, 0.77f, 0.83f, 0.14f);
            style.Colors[ImGuiCol_SliderGrabActive]      = ImVec4(0.71f, 0.22f, 0.27f, 1.00f);
            style.Colors[ImGuiCol_Button]                = ImVec4(0.47f, 0.77f, 0.83f, 0.14f);
            style.Colors[ImGuiCol_ButtonHovered]         = MED( 0.86f);
            style.Colors[ImGuiCol_ButtonActive]          = MED( 1.00f);
            style.Colors[ImGuiCol_Header]                = MED( 0.76f);
            style.Colors[ImGuiCol_HeaderHovered]         = MED( 0.86f);
            style.Colors[ImGuiCol_HeaderActive]          = HI( 1.00f);
            style.Colors[ImGuiCol_ResizeGrip]            = ImVec4(0.47f, 0.77f, 0.83f, 0.04f);
            style.Colors[ImGuiCol_ResizeGripHovered]     = MED( 0.78f);
            style.Colors[ImGuiCol_ResizeGripActive]      = MED( 1.00f);
            style.Colors[ImGuiCol_PlotLines]             = TEXT(0.63f);
            style.Colors[ImGuiCol_PlotLinesHovered]      = MED( 1.00f);
            style.Colors[ImGuiCol_PlotHistogram]         = TEXT(0.63f);
            style.Colors[ImGuiCol_PlotHistogramHovered]  = MED( 1.00f);
            style.Colors[ImGuiCol_TextSelectedBg]        = MED( 0.43f);
            style.Colors[ImGuiCol_ModalWindowDimBg]      = BG( 0.73f);

            #undef HI
            #undef MED
            #undef LOW
            #undef BG
            #undef TEXT

            if (!set_bg_color) break;

            iris->clear_value.color.float32[0] = 0.20f * 0.5f;
            iris->clear_value.color.float32[1] = 0.22f * 0.5f;
            iris->clear_value.color.float32[2] = 0.27f * 0.5f;
            iris->clear_value.color.float32[3] = 1.00f;
        } break;

        case IRIS_THEME_SOURCE: {
            ImVec4* colors = ImGui::GetStyle().Colors;

            colors[ImGuiCol_Text]                  = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
            colors[ImGuiCol_TextDisabled]          = ImVec4(0.50f, 0.50f, 0.50f, 1.00f);
            colors[ImGuiCol_WindowBg]              = ImVec4(0.29f, 0.34f, 0.26f, 1.00f);
            colors[ImGuiCol_ChildBg]               = ImVec4(0.29f, 0.34f, 0.26f, 1.00f);
            colors[ImGuiCol_PopupBg]               = ImVec4(0.24f, 0.27f, 0.20f, 1.00f);
            colors[ImGuiCol_Border]                = ImVec4(0.54f, 0.57f, 0.51f, 0.50f);
            colors[ImGuiCol_BorderShadow]          = ImVec4(0.14f, 0.16f, 0.11f, 0.52f);
            colors[ImGuiCol_FrameBg]               = ImVec4(0.24f, 0.27f, 0.20f, 1.00f);
            colors[ImGuiCol_FrameBgHovered]        = ImVec4(0.27f, 0.30f, 0.23f, 1.00f);
            colors[ImGuiCol_FrameBgActive]         = ImVec4(0.30f, 0.34f, 0.26f, 1.00f);
            colors[ImGuiCol_TitleBg]               = ImVec4(0.24f, 0.27f, 0.20f, 1.00f);
            colors[ImGuiCol_TitleBgActive]         = ImVec4(0.29f, 0.34f, 0.26f, 1.00f);
            colors[ImGuiCol_TitleBgCollapsed]      = ImVec4(0.00f, 0.00f, 0.00f, 0.51f);
            colors[ImGuiCol_MenuBarBg]             = ImVec4(0.24f, 0.27f, 0.20f, 1.00f);
            colors[ImGuiCol_ScrollbarBg]           = ImVec4(0.35f, 0.42f, 0.31f, 1.00f);
            colors[ImGuiCol_ScrollbarGrab]         = ImVec4(0.28f, 0.32f, 0.24f, 1.00f);
            colors[ImGuiCol_ScrollbarGrabHovered]  = ImVec4(0.25f, 0.30f, 0.22f, 1.00f);
            colors[ImGuiCol_ScrollbarGrabActive]   = ImVec4(0.23f, 0.27f, 0.21f, 1.00f);
            colors[ImGuiCol_CheckMark]             = ImVec4(0.59f, 0.54f, 0.18f, 1.00f);
            colors[ImGuiCol_SliderGrab]            = ImVec4(0.35f, 0.42f, 0.31f, 1.00f);
            colors[ImGuiCol_SliderGrabActive]      = ImVec4(0.54f, 0.57f, 0.51f, 0.50f);
            colors[ImGuiCol_Button]                = ImVec4(0.29f, 0.34f, 0.26f, 0.40f);
            colors[ImGuiCol_ButtonHovered]         = ImVec4(0.35f, 0.42f, 0.31f, 1.00f);
            colors[ImGuiCol_ButtonActive]          = ImVec4(0.54f, 0.57f, 0.51f, 0.50f);
            colors[ImGuiCol_Header]                = ImVec4(0.35f, 0.42f, 0.31f, 1.00f);
            colors[ImGuiCol_HeaderHovered]         = ImVec4(0.35f, 0.42f, 0.31f, 0.60f);
            colors[ImGuiCol_HeaderActive]          = ImVec4(0.54f, 0.57f, 0.51f, 0.50f);
            colors[ImGuiCol_Separator]             = ImVec4(0.14f, 0.16f, 0.11f, 1.00f);
            colors[ImGuiCol_SeparatorHovered]      = ImVec4(0.54f, 0.57f, 0.51f, 1.00f);
            colors[ImGuiCol_SeparatorActive]       = ImVec4(0.59f, 0.54f, 0.18f, 1.00f);
            colors[ImGuiCol_ResizeGrip]            = ImVec4(0.19f, 0.23f, 0.18f, 0.00f);
            colors[ImGuiCol_ResizeGripHovered]     = ImVec4(0.54f, 0.57f, 0.51f, 1.00f);
            colors[ImGuiCol_ResizeGripActive]      = ImVec4(0.59f, 0.54f, 0.18f, 1.00f);
            colors[ImGuiCol_Tab]                   = ImVec4(0.35f, 0.42f, 0.31f, 1.00f);
            colors[ImGuiCol_TabHovered]            = ImVec4(0.54f, 0.57f, 0.51f, 0.78f);
            colors[ImGuiCol_TabActive]             = ImVec4(0.59f, 0.54f, 0.18f, 1.00f);
            colors[ImGuiCol_TabUnfocused]          = ImVec4(0.24f, 0.27f, 0.20f, 1.00f);
            colors[ImGuiCol_TabUnfocusedActive]    = ImVec4(0.35f, 0.42f, 0.31f, 1.00f);
            colors[ImGuiCol_DockingPreview]        = ImVec4(0.59f, 0.54f, 0.18f, 1.00f);
            colors[ImGuiCol_DockingEmptyBg]        = ImVec4(0.20f, 0.20f, 0.20f, 1.00f);
            colors[ImGuiCol_PlotLines]             = ImVec4(0.61f, 0.61f, 0.61f, 1.00f);
            colors[ImGuiCol_PlotLinesHovered]      = ImVec4(0.59f, 0.54f, 0.18f, 1.00f);
            colors[ImGuiCol_PlotHistogram]         = ImVec4(1.00f, 0.78f, 0.28f, 1.00f);
            colors[ImGuiCol_PlotHistogramHovered]  = ImVec4(1.00f, 0.60f, 0.00f, 1.00f);
            colors[ImGuiCol_TextSelectedBg]        = ImVec4(0.59f, 0.54f, 0.18f, 1.00f);
            colors[ImGuiCol_DragDropTarget]        = ImVec4(0.73f, 0.67f, 0.24f, 1.00f);
            colors[ImGuiCol_NavHighlight]          = ImVec4(0.59f, 0.54f, 0.18f, 1.00f);
            colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f);
            colors[ImGuiCol_NavWindowingDimBg]     = ImVec4(0.80f, 0.80f, 0.80f, 0.20f);
            colors[ImGuiCol_ModalWindowDimBg]      = ImVec4(0.80f, 0.80f, 0.80f, 0.35f);

            if (!set_bg_color) break;

            iris->clear_value.color.float32[0] = 0.13f;
            iris->clear_value.color.float32[1] = 0.15f;
            iris->clear_value.color.float32[2] = 0.11f;
            iris->clear_value.color.float32[3] = 1.00f;
        } break;
    }

    ImPlotStyle& pstyle = ImPlot::GetStyle();

    pstyle.MinorGridSize = ImVec2(0.0f, 0.0f);
    pstyle.MajorGridSize = ImVec2(0.0f, 0.0f);
    pstyle.MinorTickLen = ImVec2(0.0f, 0.0f);
    pstyle.MajorTickLen = ImVec2(0.0f, 0.0f);
    pstyle.PlotDefaultSize = ImVec2(250.0f, 150.0f);
    pstyle.PlotPadding = ImVec2(0.0f, 0.0f);
    pstyle.LegendPadding = ImVec2(0.0f, 0.0f);
    pstyle.LegendInnerPadding = ImVec2(0.0f, 0.0f);
    pstyle.LineWeight = 2.0f;

    pstyle.Colors[ImPlotCol_Line]       = ImVec4(0.0f, 1.0f, 0.2f, 1.0f);
    pstyle.Colors[ImPlotCol_FrameBg]    = ImVec4(0.0f, 0.0f, 0.0f, 0.0f);
    pstyle.Colors[ImPlotCol_PlotBg]     = ImVec4(0.0f, 0.0f, 0.0f, 0.0f);
}

void set_codeview_scheme(iris::instance* iris, int scheme) {
    switch (scheme) {
        default: case IRIS_CODEVIEW_COLOR_SCHEME_SOLARIZED_DARK: {
            iris->codeview_color_text = IM_COL32(131, 148, 150, 255);
            iris->codeview_color_comment = IM_COL32(88, 110, 117, 255);
            iris->codeview_color_mnemonic = IM_COL32(211, 167, 30, 255);
            iris->codeview_color_number = IM_COL32(138, 143, 226, 255);
            iris->codeview_color_register = IM_COL32(68, 169, 240, 255);
            iris->codeview_color_other = IM_COL32(89, 89, 89, 255);
            iris->codeview_color_background = IM_COL32(0, 43, 54, 255);
            iris->codeview_color_highlight = IM_COL32(7, 54, 66, 255);
        } break;

        case IRIS_CODEVIEW_COLOR_SCHEME_SOLARIZED_LIGHT: {
            iris->codeview_color_text = IM_COL32(101, 123, 131, 255);
            iris->codeview_color_comment = IM_COL32(147, 161, 161, 255);
            iris->codeview_color_mnemonic = IM_COL32(147, 101, 21, 255);
            iris->codeview_color_number = IM_COL32(101, 123, 179, 255);
            iris->codeview_color_register = IM_COL32(38, 139, 210, 255);
            iris->codeview_color_other = IM_COL32(88, 110, 117, 255);
            iris->codeview_color_background = IM_COL32(253, 246, 227, 255);
            iris->codeview_color_highlight = IM_COL32(238, 232, 213, 255);
        } break;

        case IRIS_CODEVIEW_COLOR_SCHEME_ONE_DARK_PRO: {
            iris->codeview_color_text = IM_COL32(171, 178, 191, 255);
            iris->codeview_color_comment = IM_COL32(92, 99, 112, 255);
            iris->codeview_color_mnemonic = IM_COL32(198, 120, 221, 255);
            iris->codeview_color_number = IM_COL32(209, 154, 102, 255);
            iris->codeview_color_register = IM_COL32(97, 175, 239, 255);
            iris->codeview_color_other = IM_COL32(171, 178, 191, 255);
            iris->codeview_color_background = IM_COL32(40, 44, 52, 255);
            iris->codeview_color_highlight = IM_COL32(60, 64, 72, 255);
        } break;

        case IRIS_CODEVIEW_COLOR_SCHEME_CATPPUCCIN_LATTE: {
            iris->codeview_color_text = IM_COL32(76, 79, 105, 255);
            iris->codeview_color_comment = IM_COL32(124, 127, 147, 255);
            iris->codeview_color_mnemonic = IM_COL32(136, 57, 239, 255);
            iris->codeview_color_number = IM_COL32(254, 100, 11, 255);
            iris->codeview_color_register = IM_COL32(4, 165, 229, 255);
            iris->codeview_color_other = IM_COL32(114, 135, 253, 255);
            iris->codeview_color_background = IM_COL32(239, 241, 245, 255);
            iris->codeview_color_highlight = IM_COL32(204, 208, 218, 255);
        } break;

        case IRIS_CODEVIEW_COLOR_SCHEME_CATPPUCCIN_FRAPPE: {
            iris->codeview_color_text = IM_COL32(198, 208, 245, 255);
            iris->codeview_color_comment = IM_COL32(148, 156, 187, 255);
            iris->codeview_color_mnemonic = IM_COL32(202, 158, 230, 255);
            iris->codeview_color_number = IM_COL32(239, 159, 118, 255);
            iris->codeview_color_register = IM_COL32(153, 209, 219, 255);
            iris->codeview_color_other = IM_COL32(186, 187, 241, 255);
            iris->codeview_color_background = IM_COL32(48, 52, 70, 255);
            iris->codeview_color_highlight = IM_COL32(81, 87, 109, 255);
        } break;

        case IRIS_CODEVIEW_COLOR_SCHEME_CATPPUCCIN_MACCHIATO: {
            iris->codeview_color_text = IM_COL32(174, 178, 208, 255);
            iris->codeview_color_comment = IM_COL32(134, 138, 162, 255);
            iris->codeview_color_mnemonic = IM_COL32(190, 132, 255, 255);
            iris->codeview_color_number = IM_COL32(245, 142, 110, 255);
            iris->codeview_color_register = IM_COL32(125, 182, 191, 255);
            iris->codeview_color_other = IM_COL32(166, 167, 222, 255);
            iris->codeview_color_background = IM_COL32(58, 60, 79, 255);
            iris->codeview_color_highlight = IM_COL32(97, 100, 120, 255);
        } break;

        case IRIS_CODEVIEW_COLOR_SCHEME_CATPPUCCIN_MOCHA: {
            iris->codeview_color_text = IM_COL32(205, 214, 244, 255);
            iris->codeview_color_comment = IM_COL32(145, 151, 181, 255);
            iris->codeview_color_mnemonic = IM_COL32(220, 162, 255, 255);
            iris->codeview_color_number = IM_COL32(248, 159, 128, 255);
            iris->codeview_color_register = IM_COL32(159, 226, 235, 255);
            iris->codeview_color_other = IM_COL32(189, 191, 248, 255);
            iris->codeview_color_background = IM_COL32(46, 49, 64, 255);
            iris->codeview_color_highlight = IM_COL32(76, 80, 100, 255);
        } break;
    }
}

VkShaderModule create_shader(iris::instance* iris, uint32_t* code, size_t size) {
    VkShaderModuleCreateInfo info = {};
    info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
    info.pCode = code;
    info.codeSize = size;

    VkShaderModule shader;

    if (vkCreateShaderModule(iris->device, &info, nullptr, &shader) != VK_SUCCESS) {
        return VK_NULL_HANDLE;
    }

    return shader;
}

VkPipeline create_pipeline(iris::instance* iris, VkShaderModule vert_shader, VkShaderModule frag_shader) {
    // Create pipeline layout
    VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;

    VkPipelineLayoutCreateInfo pipeline_layout_info = {};
    pipeline_layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
    pipeline_layout_info.setLayoutCount = 1;
    pipeline_layout_info.pSetLayouts = &iris->descriptor_set_layout;
    pipeline_layout_info.pushConstantRangeCount = 0;
    pipeline_layout_info.pPushConstantRanges = VK_NULL_HANDLE;

    if (vkCreatePipelineLayout(iris->device, &pipeline_layout_info, nullptr, &pipeline_layout) != VK_SUCCESS) {
        fprintf(stderr, "vulkan: Failed to create pipeline layout\n");

        return VK_NULL_HANDLE;
    }

    iris->pipeline_layout = pipeline_layout;

    VkRenderPass render_pass = iris->main_window_data.RenderPass;

    // Create graphics pipeline
    VkPipelineShaderStageCreateInfo shader_stages[2] = {};
    shader_stages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
    shader_stages[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
    shader_stages[0].module = vert_shader;
    shader_stages[0].pName = "main";
    shader_stages[0].pNext = VK_NULL_HANDLE;
    shader_stages[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
    shader_stages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT;
    shader_stages[1].module = frag_shader;
    shader_stages[1].pName = "main";
    shader_stages[1].pNext = VK_NULL_HANDLE;

    static const VkDynamicState dynamic_states[] = {
        VK_DYNAMIC_STATE_VIEWPORT,
        VK_DYNAMIC_STATE_SCISSOR
    };

    VkPipelineDynamicStateCreateInfo dynamic_state_info = {};
    dynamic_state_info.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
    dynamic_state_info.dynamicStateCount = 2;
    dynamic_state_info.pDynamicStates = dynamic_states;

    const auto binding_description = vertex::get_binding_description();
    const auto attribute_descriptions = vertex::get_attribute_descriptions();

    VkPipelineVertexInputStateCreateInfo vertex_input_info = {};
    vertex_input_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
    vertex_input_info.vertexBindingDescriptionCount = 1;
    vertex_input_info.pVertexBindingDescriptions = &binding_description;
    vertex_input_info.vertexAttributeDescriptionCount = 2;
    vertex_input_info.pVertexAttributeDescriptions = attribute_descriptions.data();

    VkPipelineInputAssemblyStateCreateInfo input_assembly_info = {};
    input_assembly_info.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
    input_assembly_info.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
    input_assembly_info.primitiveRestartEnable = VK_FALSE;

    VkViewport viewport = {};
    viewport.x = 0.0f;
    viewport.y = 0.0f;
    viewport.width = (float)iris->main_window_data.Width;
    viewport.height = (float)iris->main_window_data.Height;
    viewport.minDepth = 0.0f;
    viewport.maxDepth = 1.0f;

    VkExtent2D extent = {};
    extent.width = iris->main_window_data.Width;
    extent.height = iris->main_window_data.Height;

    VkRect2D scissor = {};
    scissor.offset = {0, 0};
    scissor.extent = extent;

    VkPipelineViewportStateCreateInfo viewport_state_info = {};
    viewport_state_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
    viewport_state_info.viewportCount = 1;
    viewport_state_info.pViewports = &viewport;
    viewport_state_info.scissorCount = 1;
    viewport_state_info.pScissors = &scissor;

    VkPipelineRasterizationStateCreateInfo rasterizer_info = {};
    rasterizer_info.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
    rasterizer_info.depthClampEnable = VK_FALSE;
    rasterizer_info.rasterizerDiscardEnable = VK_FALSE;
    rasterizer_info.polygonMode = VK_POLYGON_MODE_FILL;
    rasterizer_info.lineWidth = 1.0f;
    rasterizer_info.cullMode = VK_CULL_MODE_NONE;
    rasterizer_info.frontFace = VK_FRONT_FACE_CLOCKWISE;
    rasterizer_info.depthBiasEnable = VK_FALSE;

    VkPipelineColorBlendAttachmentState blend_attachment_state = {};
    blend_attachment_state.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
    blend_attachment_state.blendEnable = VK_FALSE;

    VkPipelineColorBlendStateCreateInfo blend_state_info{};
    blend_state_info.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
    blend_state_info.logicOpEnable = VK_FALSE;
    blend_state_info.attachmentCount = 1;
    blend_state_info.pAttachments = &blend_attachment_state;

    VkPipelineMultisampleStateCreateInfo multisampling_state_info = {};
    multisampling_state_info.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
    multisampling_state_info.sampleShadingEnable = VK_FALSE;
    multisampling_state_info.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;

    VkGraphicsPipelineCreateInfo pipeline_info = {};
    pipeline_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
    pipeline_info.stageCount = 2;
    pipeline_info.pStages = shader_stages;
    pipeline_info.pVertexInputState = &vertex_input_info;
    pipeline_info.pInputAssemblyState = &input_assembly_info;
    pipeline_info.pViewportState = &viewport_state_info;
    pipeline_info.pRasterizationState = &rasterizer_info;
    pipeline_info.pMultisampleState = &multisampling_state_info;
    pipeline_info.pDepthStencilState = nullptr; // Optional
    pipeline_info.pColorBlendState = &blend_state_info;
    pipeline_info.pDynamicState = &dynamic_state_info;
    pipeline_info.layout = pipeline_layout;
    pipeline_info.renderPass = render_pass;
    pipeline_info.subpass = 0;
    pipeline_info.pTessellationState = VK_NULL_HANDLE;
    pipeline_info.basePipelineHandle = VK_NULL_HANDLE; // Optional
    pipeline_info.basePipelineIndex = -1; // Optional

    VkPipeline pipeline = VK_NULL_HANDLE;

    if (vkCreateGraphicsPipelines(iris->device, VK_NULL_HANDLE, 1, &pipeline_info, nullptr, &pipeline) != VK_SUCCESS) {
        return VK_NULL_HANDLE;
    }

    vkDestroyShaderModule(iris->device, frag_shader, nullptr);
    vkDestroyShaderModule(iris->device, vert_shader, nullptr);

    return pipeline;
}

bool init(iris::instance* iris) {
    VkDescriptorSetLayoutBinding sampler_layout_binding = {};
    sampler_layout_binding.binding = 0;
    sampler_layout_binding.descriptorCount = 1;
    sampler_layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
    sampler_layout_binding.pImmutableSamplers = nullptr;
    sampler_layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;

    // VkDescriptorBindingFlags flags = {};
    // flags = VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT;

    // VkDescriptorSetLayoutBindingFlagsCreateInfo binding_flags = {};
    // binding_flags.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO;
    // binding_flags.pNext = nullptr;
    // binding_flags.pBindingFlags = &flags;
    // binding_flags.bindingCount = 1;

    VkDescriptorSetLayoutCreateInfo layout_info = {};
    layout_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
    layout_info.bindingCount = 1;
    layout_info.pBindings = &sampler_layout_binding;
    // layout_info.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT;
    // layout_info.pNext = &binding_flags;

    if (vkCreateDescriptorSetLayout(iris->device, &layout_info, nullptr, &iris->descriptor_set_layout) != VK_SUCCESS) {
        fprintf(stderr, "imgui: Failed to create descriptor set layout\n");

        return false;
    }

    std::vector <VkDescriptorSetLayout> layouts(DESCRIPTOR_SET_RING_SIZE, iris->descriptor_set_layout);

    iris->descriptor_sets.resize(DESCRIPTOR_SET_RING_SIZE, VK_NULL_HANDLE);

    VkDescriptorSetAllocateInfo alloc_info = {};
    alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
    alloc_info.descriptorPool = iris->descriptor_pool;
    alloc_info.descriptorSetCount = DESCRIPTOR_SET_RING_SIZE;
    alloc_info.pSetLayouts = layouts.data();

    if (vkAllocateDescriptorSets(iris->device, &alloc_info, iris->descriptor_sets.data()) != VK_SUCCESS) {
        fprintf(stderr, "imgui: Failed to allocate descriptor sets\n");

        return false;
    }

    iris->descriptor_set = iris->descriptor_sets[0];

    if (!SDL_Vulkan_CreateSurface(iris->window, iris->instance, VK_NULL_HANDLE, &iris->surface)) {
        printf("imgui: Failed to create Vulkan surface\n");

        return false;
    }

    if (!setup_vulkan_window(iris, &iris->main_window_data, iris->window_width, iris->window_height, iris->vsync)) {
        printf("imgui: Failed to setup Vulkan window\n");

        return false;
    }

    iris->ini_path = iris->pref_path + "imgui.ini";

    IMGUI_CHECKVERSION();
    ImGui::CreateContext();
    ImPlot::CreateContext();
    ImGuiIO& io = ImGui::GetIO(); (void)io;
    io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;     // Enable Keyboard Controls
    io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;         // Enable Docking

    if (iris->imgui_enable_viewports) {
        io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
        io.ConfigViewportsNoDecoration = false;
        io.ConfigViewportsNoAutoMerge = true;
    }

    io.IniFilename = iris->ini_path.c_str();

    // Setup scaling
    ImGuiStyle& style = ImGui::GetStyle();
    style.ScaleAllSizes(iris->main_scale);
    style.FontScaleDpi = iris->main_scale;
    style.FontScaleMain = iris->ui_scale;

    io.ConfigDpiScaleFonts = true;
    io.ConfigDpiScaleViewports = true;

    // Setup Platform/Renderer backends
    if (!ImGui_ImplSDL3_InitForVulkan(iris->window)) {
        fprintf(stderr, "imgui: Failed to initialize SDL3/Vulkan backend\n");

        return false;
    }

    ImGui_ImplVulkan_InitInfo init_info = {};
    init_info.ApiVersion = IRIS_VULKAN_API_VERSION;
    init_info.Instance = iris->instance;
    init_info.PhysicalDevice = iris->physical_device;
    init_info.Device = iris->device;
    init_info.QueueFamily = iris->queue_family;
    init_info.Queue = iris->queue;
    init_info.PipelineCache = VK_NULL_HANDLE;
    init_info.DescriptorPool = iris->descriptor_pool;
    init_info.MinImageCount = iris->min_image_count;
    init_info.ImageCount = iris->main_window_data.ImageCount;
    init_info.Allocator = VK_NULL_HANDLE;
    init_info.PipelineInfoMain.RenderPass = iris->main_window_data.RenderPass;
    init_info.PipelineInfoMain.Subpass = 0;
    init_info.PipelineInfoMain.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
    init_info.CheckVkResultFn = VK_NULL_HANDLE;

    if (!ImGui_ImplVulkan_Init(&init_info)) {
        fprintf(stderr, "imgui: Failed to initialize Vulkan backend\n");

        return false;
    }

    if (!setup_fonts(iris, io)) {
        fprintf(stderr, "imgui: Failed to setup fonts\n");

        return false;
    }

    set_theme(iris, iris->theme, false);
    set_codeview_scheme(iris, iris->codeview_color_scheme);

    // Initialize our pipeline
    VkShaderModule vert_shader = create_shader(iris, (uint32_t*)g_vertex_shader_data, g_vertex_shader_size);
    VkShaderModule frag_shader = create_shader(iris, (uint32_t*)g_fragment_shader_data, g_fragment_shader_size);

    if (!vert_shader || !frag_shader) {
        fprintf(stderr, "vulkan: Failed to create shader modules\n");

        return false;
    }

    iris->pipeline = create_pipeline(iris, vert_shader, frag_shader);

    if (!iris->pipeline) {
        fprintf(stderr, "imgui: Failed to create graphics pipeline\n");

        return false;
    }

    auto load_texture = [iris](const stbi_uc* data, size_t size) -> texture {
        int x, y, c;

        stbi_uc* buf = stbi_load_from_memory(data, size, &x, &y, &c, 4);

        auto tex = vulkan::upload_texture(iris, buf, x, y, c);

        stbi_image_free(buf);

        return tex;
    };

    iris->ps1_memory_card_icon = load_texture(g_ps1_memory_card_icon_data, g_ps1_memory_card_icon_size);
    iris->ps2_memory_card_icon = load_texture(g_ps2_memory_card_icon_data, g_ps2_memory_card_icon_size);
    iris->pocketstation_icon = load_texture(g_pocketstation_icon_data, g_pocketstation_icon_size);
    iris->dualshock2_icon = load_texture(g_dualshock2_icon_data, g_dualshock2_icon_size);
    iris->iris_icon = load_texture(g_iris_icon_data, g_iris_icon_size);

    return true;
}

void cleanup(iris::instance* iris) {
    vulkan::wait_idle(iris);

    vulkan::free_texture(iris, iris->ps1_memory_card_icon);
    vulkan::free_texture(iris, iris->ps2_memory_card_icon);
    vulkan::free_texture(iris, iris->pocketstation_icon);
    vulkan::free_texture(iris, iris->dualshock2_icon);
    vulkan::free_texture(iris, iris->iris_icon);

    ImGui_ImplVulkan_Shutdown();
    ImGui_ImplSDL3_Shutdown();
    ImPlot::DestroyContext();
    ImGui::DestroyContext();

    ImGui_ImplVulkanH_DestroyWindow(iris->instance, iris->device, &iris->main_window_data, VK_NULL_HANDLE);

    iris->instance = NULL;
}

bool render_frame(iris::instance* iris, ImDrawData* draw_data) {
    if (iris->swapchain_rebuild)
        return true;

    ImGui_ImplVulkanH_Window* wd = &iris->main_window_data;
    VkSemaphore acquire_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].ImageAcquiredSemaphore;

    uint32_t image_index;

    VkResult err;

    err = vkAcquireNextImageKHR(
        iris->device,
        wd->Swapchain,
        UINT64_MAX,
        acquire_semaphore,
        VK_NULL_HANDLE,
        &image_index
    );

    VkSemaphore submit_semaphore = wd->FrameSemaphores[image_index].RenderCompleteSemaphore;

    if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR) {
        iris->swapchain_rebuild = true;

        return true;
    } else if (err != VK_SUCCESS) {
        fprintf(stderr, "imgui: Failed to acquire next image\n");

        return false;
    }

    wd->FrameIndex = image_index;

    ImGui_ImplVulkanH_Frame* fd = &wd->Frames[wd->FrameIndex];

    if (vkWaitForFences(iris->device, 1, &fd->Fence, VK_TRUE, UINT64_MAX) != VK_SUCCESS) {
        fprintf(stderr, "imgui: Failed to wait for fence\n");

        return false;
    }

    if (vkResetFences(iris->device, 1, &fd->Fence) != VK_SUCCESS) {
        fprintf(stderr, "imgui: Failed to reset fence\n");

        return false;
    }

    if (vkResetCommandPool(iris->device, fd->CommandPool, 0) != VK_SUCCESS) {
        fprintf(stderr, "imgui: Failed to reset command pool\n");

        return false;
    }

    VkCommandBufferBeginInfo begin_info = {};
    begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
    begin_info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;

    if (vkBeginCommandBuffer(fd->CommandBuffer, &begin_info) != VK_SUCCESS) {
        fprintf(stderr, "imgui: Failed to begin command buffer\n");
        
        return false;
    }

    if (iris->instance) {
        render::render_frame(iris, fd->CommandBuffer, fd->Framebuffer);
    }

    {
        VkRenderPassBeginInfo render_pass_info = {};
        render_pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
        render_pass_info.renderPass = wd->RenderPass;
        render_pass_info.framebuffer = fd->Framebuffer;
        render_pass_info.renderArea.extent.width = wd->Width;
        render_pass_info.renderArea.extent.height = wd->Height;
        render_pass_info.clearValueCount = 1;
        render_pass_info.pClearValues = &iris->clear_value;

        vkCmdBeginRenderPass(fd->CommandBuffer, &render_pass_info, VK_SUBPASS_CONTENTS_INLINE);
    }

    // Record dear imgui primitives into command buffer
    ImGui_ImplVulkan_RenderDrawData(draw_data, fd->CommandBuffer);

    // Submit command buffer
    vkCmdEndRenderPass(fd->CommandBuffer);

    {
        VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
        VkSubmitInfo submit_info = {};
        submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
        submit_info.waitSemaphoreCount = 1;
        submit_info.pWaitSemaphores = &acquire_semaphore;
        submit_info.pWaitDstStageMask = &wait_stage;
        submit_info.commandBufferCount = 1;
        submit_info.pCommandBuffers = &fd->CommandBuffer;
        submit_info.signalSemaphoreCount = 1;
        submit_info.pSignalSemaphores = &submit_semaphore;

        if (vkEndCommandBuffer(fd->CommandBuffer) != VK_SUCCESS) {
            fprintf(stderr, "imgui: Failed to end command buffer\n");
        
            return false;
        }

        if (vkQueueSubmit(iris->queue, 1, &submit_info, fd->Fence) != VK_SUCCESS) {
            fprintf(stderr, "imgui: Failed to submit queue\n");
        
            return false;
        }
    }

    if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable) {
        ImGui::UpdatePlatformWindows();
        ImGui::RenderPlatformWindowsDefault();
    }

    VkPresentInfoKHR present_info = {};
    present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
    present_info.waitSemaphoreCount = 1;
    present_info.pWaitSemaphores = &submit_semaphore;
    present_info.swapchainCount = 1;
    present_info.pSwapchains = &wd->Swapchain;
    present_info.pImageIndices = &image_index;

    err = vkQueuePresentKHR(iris->queue, &present_info);

    if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR) {
        iris->swapchain_rebuild = true;

        return true;
    } else if (err != VK_SUCCESS) {
        fprintf(stderr, "imgui: Failed to acquire next image\n");

        return false;
    }

    wd->SemaphoreIndex = (wd->SemaphoreIndex + 1) % wd->SemaphoreCount;

    return true;
}

bool BeginEx(const char* name, bool* p_open, ImGuiWindowFlags flags) {
    ImGui::SetNextWindowSize(ImVec2(600.0, 600.0), ImGuiCond_FirstUseEver);
    ImGui::SetNextWindowPos(ImVec2(50.0, 50.0), ImGuiCond_FirstUseEver);

    if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable) {
        flags |= ImGuiWindowFlags_NoTitleBar;
    }

    return ImGui::Begin(name, p_open, flags);
}

}


================================================
FILE: frontend/input.cpp
================================================
#include <filesystem>
#include <string>

#include "iris.hpp"

#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h"

#define INCBIN_PREFIX g_
#define INCBIN_STYLE INCBIN_STYLE_SNAKE

#include "incbin.h"

INCBIN(gamecontrollerdb, "../deps/SDL_GameControllerDB/gamecontrollerdb.txt");

namespace iris {

void keyboard_device::handle_event(iris::instance* iris, SDL_Event* event) {
    auto ievent = input::sdl_event_to_input_event(event);
    auto action = input::get_input_action(iris, m_slot, ievent.u64);

    if (!action)
        return;

    input::execute_action(iris, *action, m_slot, event->type == SDL_EVENT_KEY_DOWN ? 1.0f : 0.0f);
}

void gamepad_device::handle_event(iris::instance* iris, SDL_Event* event) {
    auto ievent = input::sdl_event_to_input_event(event);
    auto action = input::get_input_action(iris, m_slot, ievent.u64);

    if (!action)
        return;

    if (event->type == SDL_EVENT_GAMEPAD_BUTTON_DOWN) {
        input::execute_action(iris, *action, m_slot, 1.0f);
    } else if (event->type == SDL_EVENT_GAMEPAD_BUTTON_UP) {
        input::execute_action(iris, *action, m_slot, 0.0f);
    } else if (event->type == SDL_EVENT_GAMEPAD_AXIS_MOTION) {
        // Convert from -32768->32767 to -1.0->1.0 and take absolute value
        float value = fabs(event->gaxis.value / 32767.0f);

        input::execute_action(iris, *action, m_slot, value);
    }
}

}

namespace iris::input {

void load_db_default(iris::instance* iris) {
    SDL_IOStream* ios = SDL_IOFromConstMem(g_gamecontrollerdb_data, g_gamecontrollerdb_size);

    SDL_AddGamepadMappingsFromIO(ios, true);
}

bool load_db_from_file(iris::instance* iris, const char* path) {
    if (SDL_AddGamepadMappingsFromFile(path) == -1)
        return false;

    return true;
}

#define IEVENT(event, id, mod) \
    (((uint64_t)event << 32) | (((id & 0xf0000fff) | ((mod & 0xffff) << 12)) & 0xffffffff))

void init_default_mapping(iris::instance* iris, int id) {
    mapping& map = iris->input_maps[id];

    if (id == 0) {
        map.name = "Keyboard (default)";

        map.map.clear();

        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_X     , SDL_KMOD_NONE), IRIS_DS_BT_CROSS);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_A     , SDL_KMOD_NONE), IRIS_DS_BT_SQUARE);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_W     , SDL_KMOD_NONE), IRIS_DS_BT_TRIANGLE);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_D     , SDL_KMOD_NONE), IRIS_DS_BT_CIRCLE);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_RETURN, SDL_KMOD_NONE), IRIS_DS_BT_START);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_S     , SDL_KMOD_NONE), IRIS_DS_BT_SELECT);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_UP    , SDL_KMOD_NONE), IRIS_DS_BT_UP);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_DOWN  , SDL_KMOD_NONE), IRIS_DS_BT_DOWN);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_LEFT  , SDL_KMOD_NONE), IRIS_DS_BT_LEFT);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_RIGHT , SDL_KMOD_NONE), IRIS_DS_BT_RIGHT);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_Q     , SDL_KMOD_NONE), IRIS_DS_BT_L1);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_E     , SDL_KMOD_NONE), IRIS_DS_BT_R1);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_1     , SDL_KMOD_NONE), IRIS_DS_BT_L2);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_3     , SDL_KMOD_NONE), IRIS_DS_BT_R2);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_Z     , SDL_KMOD_NONE), IRIS_DS_BT_L3);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_C     , SDL_KMOD_NONE), IRIS_DS_BT_R3);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_I     , SDL_KMOD_NONE), IRIS_DS_AX_LEFTV_POS);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_J     , SDL_KMOD_NONE), IRIS_DS_AX_LEFTH_NEG);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_K     , SDL_KMOD_NONE), IRIS_DS_AX_LEFTV_NEG);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_L     , SDL_KMOD_NONE), IRIS_DS_AX_LEFTH_POS);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_T     , SDL_KMOD_NONE), IRIS_DS_AX_RIGHTV_POS);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_F     , SDL_KMOD_NONE), IRIS_DS_AX_RIGHTH_NEG);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_G     , SDL_KMOD_NONE), IRIS_DS_AX_RIGHTV_NEG);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_H     , SDL_KMOD_NONE), IRIS_DS_AX_RIGHTH_POS);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_0     , SDL_KMOD_NONE), IRIS_S14X_SW_SERVICE);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_9     , SDL_KMOD_NONE), IRIS_S14X_SW_TEST);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_8     , SDL_KMOD_NONE), IRIS_S14X_SW_ENTER);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_7     , SDL_KMOD_NONE), IRIS_S14X_SW_UP);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_6     , SDL_KMOD_NONE), IRIS_S14X_SW_DOWN);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_1     , SDL_KMOD_LSHIFT), IRIS_S14X_SW_P1_START);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_2     , SDL_KMOD_LSHIFT), IRIS_S14X_SW_P2_START);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_3     , SDL_KMOD_LSHIFT), IRIS_S14X_SW_P3_START);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_4     , SDL_KMOD_LSHIFT), IRIS_S14X_SW_P4_START);
    } else {
        map.name = "Gamepad (default)";

        map.map.clear();

        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_BUTTON  , SDL_GAMEPAD_BUTTON_SOUTH         , SDL_KMOD_NONE), IRIS_DS_BT_CROSS);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_BUTTON  , SDL_GAMEPAD_BUTTON_WEST          , SDL_KMOD_NONE), IRIS_DS_BT_SQUARE);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_BUTTON  , SDL_GAMEPAD_BUTTON_NORTH         , SDL_KMOD_NONE), IRIS_DS_BT_TRIANGLE);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_BUTTON  , SDL_GAMEPAD_BUTTON_EAST          , SDL_KMOD_NONE), IRIS_DS_BT_CIRCLE);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_BUTTON  , SDL_GAMEPAD_BUTTON_START         , SDL_KMOD_NONE), IRIS_DS_BT_START);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_BUTTON  , SDL_GAMEPAD_BUTTON_BACK          , SDL_KMOD_NONE), IRIS_DS_BT_SELECT);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_BUTTON  , SDL_GAMEPAD_BUTTON_DPAD_UP       , SDL_KMOD_NONE), IRIS_DS_BT_UP);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_BUTTON  , SDL_GAMEPAD_BUTTON_DPAD_DOWN     , SDL_KMOD_NONE), IRIS_DS_BT_DOWN);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_BUTTON  , SDL_GAMEPAD_BUTTON_DPAD_LEFT     , SDL_KMOD_NONE), IRIS_DS_BT_LEFT);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_BUTTON  , SDL_GAMEPAD_BUTTON_DPAD_RIGHT    , SDL_KMOD_NONE), IRIS_DS_BT_RIGHT);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_BUTTON  , SDL_GAMEPAD_BUTTON_LEFT_SHOULDER , SDL_KMOD_NONE), IRIS_DS_BT_L1);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_BUTTON  , SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER, SDL_KMOD_NONE), IRIS_DS_BT_R1);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_BUTTON  , SDL_GAMEPAD_BUTTON_LEFT_STICK    , SDL_KMOD_NONE), IRIS_DS_BT_L3);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_BUTTON  , SDL_GAMEPAD_BUTTON_RIGHT_STICK   , SDL_KMOD_NONE), IRIS_DS_BT_R3);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_AXIS_POS, SDL_GAMEPAD_AXIS_LEFT_TRIGGER    , SDL_KMOD_NONE), IRIS_DS_BT_L2);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_AXIS_POS, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER   , SDL_KMOD_NONE), IRIS_DS_BT_R2);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_AXIS_POS, SDL_GAMEPAD_AXIS_LEFTY           , SDL_KMOD_NONE), IRIS_DS_AX_LEFTV_POS);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_AXIS_NEG, SDL_GAMEPAD_AXIS_LEFTY           , SDL_KMOD_NONE), IRIS_DS_AX_LEFTV_NEG);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_AXIS_POS, SDL_GAMEPAD_AXIS_LEFTX           , SDL_KMOD_NONE), IRIS_DS_AX_LEFTH_POS);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_AXIS_NEG, SDL_GAMEPAD_AXIS_LEFTX           , SDL_KMOD_NONE), IRIS_DS_AX_LEFTH_NEG);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_AXIS_POS, SDL_GAMEPAD_AXIS_RIGHTY          , SDL_KMOD_NONE), IRIS_DS_AX_RIGHTV_POS);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_AXIS_NEG, SDL_GAMEPAD_AXIS_RIGHTY          , SDL_KMOD_NONE), IRIS_DS_AX_RIGHTV_NEG);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_AXIS_POS, SDL_GAMEPAD_AXIS_RIGHTX          , SDL_KMOD_NONE), IRIS_DS_AX_RIGHTH_POS);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_AXIS_NEG, SDL_GAMEPAD_AXIS_RIGHTX          , SDL_KMOD_NONE), IRIS_DS_AX_RIGHTH_NEG);
    }
}

bool init(iris::instance* iris) {
    if (!iris->gcdb_path.size()) {
        fprintf(stdout, "input: Adding default database\n");

        load_db_default(iris);
    } else {
        fprintf(stdout, "input: Adding database from file \'%s\'\n", iris->gcdb_path.c_str());

        load_db_from_file(iris, iris->gcdb_path.c_str());
    }

    iris->input_devices[0] = new iris::keyboard_device();

    if (iris->input_maps.size() == 0) {
        mapping map;

        map.name = "Keyboard (default)";
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_X     , SDL_KMOD_NONE), IRIS_DS_BT_CROSS);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_A     , SDL_KMOD_NONE), IRIS_DS_BT_SQUARE);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_W     , SDL_KMOD_NONE), IRIS_DS_BT_TRIANGLE);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_D     , SDL_KMOD_NONE), IRIS_DS_BT_CIRCLE);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_RETURN, SDL_KMOD_NONE), IRIS_DS_BT_START);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_S     , SDL_KMOD_NONE), IRIS_DS_BT_SELECT);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_UP    , SDL_KMOD_NONE), IRIS_DS_BT_UP);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_DOWN  , SDL_KMOD_NONE), IRIS_DS_BT_DOWN);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_LEFT  , SDL_KMOD_NONE), IRIS_DS_BT_LEFT);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_RIGHT , SDL_KMOD_NONE), IRIS_DS_BT_RIGHT);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_Q     , SDL_KMOD_NONE), IRIS_DS_BT_L1);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_E     , SDL_KMOD_NONE), IRIS_DS_BT_R1);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_1     , SDL_KMOD_NONE), IRIS_DS_BT_L2);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_3     , SDL_KMOD_NONE), IRIS_DS_BT_R2);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_Z     , SDL_KMOD_NONE), IRIS_DS_BT_L3);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_C     , SDL_KMOD_NONE), IRIS_DS_BT_R3);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_I     , SDL_KMOD_NONE), IRIS_DS_AX_LEFTV_POS);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_J     , SDL_KMOD_NONE), IRIS_DS_AX_LEFTH_NEG);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_K     , SDL_KMOD_NONE), IRIS_DS_AX_LEFTV_NEG);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_L     , SDL_KMOD_NONE), IRIS_DS_AX_LEFTH_POS);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_T     , SDL_KMOD_NONE), IRIS_DS_AX_RIGHTV_POS);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_F     , SDL_KMOD_NONE), IRIS_DS_AX_RIGHTH_NEG);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_G     , SDL_KMOD_NONE), IRIS_DS_AX_RIGHTV_NEG);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_H     , SDL_KMOD_NONE), IRIS_DS_AX_RIGHTH_POS);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_0     , SDL_KMOD_NONE), IRIS_S14X_SW_SERVICE);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_9     , SDL_KMOD_NONE), IRIS_S14X_SW_TEST);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_8     , SDL_KMOD_NONE), IRIS_S14X_SW_ENTER);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_7     , SDL_KMOD_NONE), IRIS_S14X_SW_UP);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_6     , SDL_KMOD_NONE), IRIS_S14X_SW_DOWN);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_1     , SDL_KMOD_LSHIFT), IRIS_S14X_SW_P1_START);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_2     , SDL_KMOD_LSHIFT), IRIS_S14X_SW_P2_START);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_3     , SDL_KMOD_LSHIFT), IRIS_S14X_SW_P3_START);
        map.map.insert(IEVENT(IRIS_EVENT_KEYBOARD, SDLK_4     , SDL_KMOD_LSHIFT), IRIS_S14X_SW_P4_START);

        iris->input_maps.push_back(map);

        map.map.clear();
        map = {};

        map.name = "Gamepad (default)";
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_BUTTON  , SDL_GAMEPAD_BUTTON_SOUTH         , SDL_KMOD_NONE), IRIS_DS_BT_CROSS);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_BUTTON  , SDL_GAMEPAD_BUTTON_WEST          , SDL_KMOD_NONE), IRIS_DS_BT_SQUARE);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_BUTTON  , SDL_GAMEPAD_BUTTON_NORTH         , SDL_KMOD_NONE), IRIS_DS_BT_TRIANGLE);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_BUTTON  , SDL_GAMEPAD_BUTTON_EAST          , SDL_KMOD_NONE), IRIS_DS_BT_CIRCLE);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_BUTTON  , SDL_GAMEPAD_BUTTON_START         , SDL_KMOD_NONE), IRIS_DS_BT_START);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_BUTTON  , SDL_GAMEPAD_BUTTON_BACK          , SDL_KMOD_NONE), IRIS_DS_BT_SELECT);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_BUTTON  , SDL_GAMEPAD_BUTTON_DPAD_UP       , SDL_KMOD_NONE), IRIS_DS_BT_UP);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_BUTTON  , SDL_GAMEPAD_BUTTON_DPAD_DOWN     , SDL_KMOD_NONE), IRIS_DS_BT_DOWN);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_BUTTON  , SDL_GAMEPAD_BUTTON_DPAD_LEFT     , SDL_KMOD_NONE), IRIS_DS_BT_LEFT);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_BUTTON  , SDL_GAMEPAD_BUTTON_DPAD_RIGHT    , SDL_KMOD_NONE), IRIS_DS_BT_RIGHT);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_BUTTON  , SDL_GAMEPAD_BUTTON_LEFT_SHOULDER , SDL_KMOD_NONE), IRIS_DS_BT_L1);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_BUTTON  , SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER, SDL_KMOD_NONE), IRIS_DS_BT_R1);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_BUTTON  , SDL_GAMEPAD_BUTTON_LEFT_STICK    , SDL_KMOD_NONE), IRIS_DS_BT_L3);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_BUTTON  , SDL_GAMEPAD_BUTTON_RIGHT_STICK   , SDL_KMOD_NONE), IRIS_DS_BT_R3);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_AXIS_POS, SDL_GAMEPAD_AXIS_LEFT_TRIGGER    , SDL_KMOD_NONE), IRIS_DS_BT_L2);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_AXIS_POS, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER   , SDL_KMOD_NONE), IRIS_DS_BT_R2);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_AXIS_POS, SDL_GAMEPAD_AXIS_LEFTY           , SDL_KMOD_NONE), IRIS_DS_AX_LEFTV_POS);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_AXIS_NEG, SDL_GAMEPAD_AXIS_LEFTY           , SDL_KMOD_NONE), IRIS_DS_AX_LEFTV_NEG);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_AXIS_POS, SDL_GAMEPAD_AXIS_LEFTX           , SDL_KMOD_NONE), IRIS_DS_AX_LEFTH_POS);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_AXIS_NEG, SDL_GAMEPAD_AXIS_LEFTX           , SDL_KMOD_NONE), IRIS_DS_AX_LEFTH_NEG);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_AXIS_POS, SDL_GAMEPAD_AXIS_RIGHTY          , SDL_KMOD_NONE), IRIS_DS_AX_RIGHTV_POS);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_AXIS_NEG, SDL_GAMEPAD_AXIS_RIGHTY          , SDL_KMOD_NONE), IRIS_DS_AX_RIGHTV_NEG);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_AXIS_POS, SDL_GAMEPAD_AXIS_RIGHTX          , SDL_KMOD_NONE), IRIS_DS_AX_RIGHTH_POS);
        map.map.insert(IEVENT(IRIS_EVENT_GAMEPAD_AXIS_NEG, SDL_GAMEPAD_AXIS_RIGHTX          , SDL_KMOD_NONE), IRIS_DS_AX_RIGHTH_NEG);

        iris->input_maps.push_back(map);
    }

#undef IEVENT

    // Ensure default mappings are in the correct order
    if (iris->input_maps[0].name == "Gamepad (default)") {
        auto map = iris->input_maps[0];

        iris->input_maps[0] = iris->input_maps[1];
        iris->input_maps[1] = map;
    }

    // Use keyboard mapping for slot 0 and none for slot 1 by default
    if (iris->input_map[0] <= 1) {
        iris->input_map[0] = 0;
    }

    if (iris->input_map[1] <= 1) {
        iris->input_map[1] = -1;
    }

    return true;
}

input_action* get_input_action(iris::instance* iris, int slot, uint64_t input) {
    if (iris->input_map[slot] == -1)
        return nullptr;

    return iris->input_maps[iris->input_map[slot]].map.get_value(input);
}

static inline void change_button(iris::instance* iris, int slot, float value, uint32_t button) {
    if (!iris->ds[slot]) return;

    if (value > 0.5f) {
        ds_button_press(iris->ds[slot], button);
    } else {
        ds_button_release(iris->ds[slot], button);
    }
}

static inline void change_s14x_switch(iris::instance* iris, float value, uint32_t mask) {
    if (!iris->ps2->s14x_ioboard)
        return;

    if (value > 0.5) {
        s14x_ioboard_press_switch(iris->ps2->s14x_ioboard, mask);
    } else {
        s14x_ioboard_release_switch(iris->ps2->s14x_ioboard, mask);
    }
}

void execute_action(iris::instance* iris, input_action action, int slot, float value) {
    if (!iris->ds[slot])
        return;

    switch (action) {
        case IRIS_DS_BT_SELECT: change_button(iris, slot, value, DS_BT_SELECT); break;
        case IRIS_DS_BT_L3: change_button(iris, slot, value, DS_BT_L3); break;
        case IRIS_DS_BT_R3: change_button(iris, slot, value, DS_BT_R3); break;
        case IRIS_DS_BT_START: change_button(iris, slot, value, DS_BT_START); break;
        case IRIS_DS_BT_UP: change_button(iris, slot, value, DS_BT_UP); break;
        case IRIS_DS_BT_RIGHT: change_button(iris, slot, value, DS_BT_RIGHT); break;
        case IRIS_DS_BT_DOWN: change_button(iris, slot, value, DS_BT_DOWN); break;
        case IRIS_DS_BT_LEFT: change_button(iris, slot, value, DS_BT_LEFT); break;
        case IRIS_DS_BT_L2: change_button(iris, slot, value, DS_BT_L2); break;
        case IRIS_DS_BT_R2: change_button(iris, slot, value, DS_BT_R2); break;
        case IRIS_DS_BT_L1: change_button(iris, slot, value, DS_BT_L1); break;
        case IRIS_DS_BT_R1: change_button(iris, slot, value, DS_BT_R1); break;
        case IRIS_DS_BT_TRIANGLE: change_button(iris, slot, value, DS_BT_TRIANGLE); break;
        case IRIS_DS_BT_CIRCLE: change_button(iris, slot, value, DS_BT_CIRCLE); break;
        case IRIS_DS_BT_CROSS: change_button(iris, slot, value, DS_BT_CROSS); break;
        case IRIS_DS_BT_SQUARE: change_button(iris, slot, value, DS_BT_SQUARE); break;
        case IRIS_DS_BT_ANALOG: change_button(iris, slot, value, DS_BT_ANALOG); break;
        case IRIS_DS_AX_RIGHTV_POS: ds_analog_change(iris->ds[slot], DS_AX_RIGHT_V, 0x7f + (value * 0x80)); break;
        case IRIS_DS_AX_RIGHTV_NEG: ds_analog_change(iris->ds[slot], DS_AX_RIGHT_V, 0x7f - (value * 0x7f)); break;
        case IRIS_DS_AX_RIGHTH_POS: ds_analog_change(iris->ds[slot], DS_AX_RIGHT_H, 0x7f + (value * 0x80)); break;
        case IRIS_DS_AX_RIGHTH_NEG: ds_analog_change(iris->ds[slot], DS_AX_RIGHT_H, 0x7f - (value * 0x7f)); break;
        case IRIS_DS_AX_LEFTV_POS: ds_analog_change(iris->ds[slot], DS_AX_LEFT_V, 0x7f + (value * 0x80)); break;
        case IRIS_DS_AX_LEFTV_NEG: ds_analog_change(iris->ds[slot], DS_AX_LEFT_V, 0x7f - (value * 0x7f)); break;
        case IRIS_DS_AX_LEFTH_POS: ds_analog_change(iris->ds[slot], DS_AX_LEFT_H, 0x7f + (value * 0x80)); break;
        case IRIS_DS_AX_LEFTH_NEG: ds_analog_change(iris->ds[slot], DS_AX_LEFT_H, 0x7f - (value * 0x7f)); break;
        case IRIS_S14X_SW_SERVICE: change_s14x_switch(iris, value, S14X_IOBOARD_SW_SERVICE); break;
        case IRIS_S14X_SW_TEST: change_s14x_switch(iris, value, S14X_IOBOARD_SW_TEST); break;
        case IRIS_S14X_SW_ENTER: change_s14x_switch(iris, value, S14X_IOBOARD_SW_ENTER); break;
        case IRIS_S14X_SW_UP: change_s14x_switch(iris, value, S14X_IOBOARD_SW_UP); break;
        case IRIS_S14X_SW_DOWN: change_s14x_switch(iris, value, S14X_IOBOARD_SW_DOWN); break;
        case IRIS_S14X_SW_P1_START: change_s14x_switch(iris, value, S14X_IOBOARD_SW_P1_START); break;
        case IRIS_S14X_SW_P2_START: change_s14x_switch(iris, value, S14X_IOBOARD_SW_P2_START); break;
        case IRIS_S14X_SW_P3_START: change_s14x_switch(iris, value, S14X_IOBOARD_SW_P3_START); break;
        case IRIS_S14X_SW_P4_START: change_s14x_switch(iris, value, S14X_IOBOARD_SW_P4_START); break;
    }
}

input_event sdl_event_to_input_event(SDL_Event* event) {
    input_event ievent = {};

    switch (event->type) {
        case SDL_EVENT_KEY_DOWN:
        case SDL_EVENT_KEY_UP: {
            ievent.type = IRIS_EVENT_KEYBOARD;
            ievent.id = event->key.key;

            // Devious hack, we have enough spare bits in the 
            // SDL_Keycode so we can actually do this
            const uint16_t mask =
                SDL_KMOD_LSHIFT | SDL_KMOD_RSHIFT |
                SDL_KMOD_LCTRL  | SDL_KMOD_RCTRL  |
                SDL_KMOD_LALT   | SDL_KMOD_RALT;

            ievent.id |= (event->key.mod & mask) << 12;
        } break;

        case SDL_EVENT_GAMEPAD_BUTTON_DOWN:
        case SDL_EVENT_GAMEPAD_BUTTON_UP: {
            ievent.type = IRIS_EVENT_GAMEPAD_BUTTON;
            ievent.id = event->gbutton.button;
        } break;

        case SDL_EVENT_GAMEPAD_AXIS_MOTION: {
            if (event->gaxis.value > 0) {
                ievent.type = IRIS_EVENT_GAMEPAD_AXIS_POS;
            } else {
                ievent.type = IRIS_EVENT_GAMEPAD_AXIS_NEG;
            }

            ievent.id = event->gaxis.axis;
        } break;
    }

    return ievent;
}

std::string get_default_screenshot_filename(iris::instance* iris) {
    SDL_Time t;
    SDL_DateTime dt;

    SDL_GetCurrentTime(&t);
    SDL_TimeToDateTime(t, &dt, true);

    char buf[512];

    sprintf(buf, "Screenshot-%04d-%02d-%02d_%02d-%02d-%02d-%d",
            dt.year, dt.month, dt.day,
            dt.hour, dt.minute, dt.second,
            iris->screenshot_counter + 1
    );

    std::string str(buf);

    switch (iris->screenshot_format) {
        case IRIS_SCREENSHOT_FORMAT_PNG: str += ".png"; break;
        case IRIS_SCREENSHOT_FORMAT_BMP: str += ".bmp"; break;
        case IRIS_SCREENSHOT_FORMAT_JPG: str += ".jpg"; break;
        case IRIS_SCREENSHOT_FORMAT_TGA: str += ".tga"; break;
    }

    return str;
}

int get_screenshot_jpg_quality(iris::instance* iris) {
    switch (iris->screenshot_jpg_quality_mode) {
        case IRIS_SCREENSHOT_JPG_QUALITY_MINIMUM: return 1;
        case IRIS_SCREENSHOT_JPG_QUALITY_LOW:     return 25;
        case IRIS_SCREENSHOT_JPG_QUALITY_MEDIUM:  return 50;
        case IRIS_SCREENSHOT_JPG_QUALITY_HIGH:    return 90;
        case IRIS_SCREENSHOT_JPG_QUALITY_MAXIMUM: return 100;
        case IRIS_SCREENSHOT_JPG_QUALITY_CUSTOM: return iris->screenshot_jpg_quality;
    }

    return 90;
}

bool save_screenshot(iris::instance* iris, std::string path) {
    std::filesystem::path fn(path);

    std::string directory = iris->snap_path;
    
    if (iris->snap_path.empty()) {
        directory = "snap";
    }

    std::filesystem::path p(directory);
    std::string absolute_path;
    std::string filename;

    if (path.size()) {
        filename = path;
    } else {
        filename = get_default_screenshot_filename(iris);
    }

    if (p.is_absolute()) {
        absolute_path = p.string();
    } else {
        absolute_path = iris->pref_path + p.string();
    }

    absolute_path += "/" + filename;

    if (fn.is_absolute()) {
        absolute_path = fn.string();
    }

    void* ptr = nullptr;
    int width = 0, height = 0, offset = 0;

    if (iris->screenshot_mode == IRIS_SCREENSHOT_MODE_INTERNAL) {
        renderer_image* image = iris->screenshot_shader_processing ? &iris->output_image : &iris->image;

        ptr = vulkan::read_image(iris,
            image->image,
            image->format,
            image->width,
            image->height
        );

        width = image->width;
        height = image->height;
    } else {
        ptr = vulkan::read_image(iris,
            iris->main_window_data.Frames[0].Backbuffer,
            iris->main_window_data.SurfaceFormat.format,
            iris->main_window_data.Width,
            iris->main_window_data.Height
        );

        width = iris->main_window_data.Width;
        height = iris->main_window_data.Height;
        
        if (!iris->fullscreen) {
            offset = iris->menubar_height;
            height -= iris->menubar_height;
        }
    }

    if (!ptr) {
        push_info(iris, "Couldn't save screenshot");

        return false;
    }

    uint32_t* buf = (uint32_t*)malloc((width * 4) * height);

    memcpy(buf, ((uint32_t*)ptr) + offset * width, (width * 4) * height);

    for (int y = 0; y < height; y++) {
        for (int x = 0; x < width; x++) {
            buf[x + (y * width)] |= 0xff000000;
        }
    }

    int r = 0;

    switch (iris->screenshot_format) {
        case IRIS_SCREENSHOT_FORMAT_PNG:
            r = stbi_write_png(absolute_path.c_str(), width, height, 4, buf, width * 4);
            break;
        case IRIS_SCREENSHOT_FORMAT_BMP:
            r = stbi_write_bmp(absolute_path.c_str(), width, height, 4, buf);
            break;
        case IRIS_SCREENSHOT_FORMAT_JPG:
            r = stbi_write_jpg(absolute_path.c_str(), width, height, 4, buf, get_screenshot_jpg_quality(iris));
            break;
        case IRIS_SCREENSHOT_FORMAT_TGA:
            r = stbi_write_tga(absolute_path.c_str(), width, height, 4, buf);
            break;
    }

    printf("Saving screenshot to '%s' (%dx%d, %d bpp): %s\n",
           absolute_path.c_str(), width, height, 32, r ? "Success" : "Failure"
    );

    free(ptr);
    free(buf);

    if (!r) {
        push_info(iris, "Couldn't save screenshot");

        return false;
    }

    iris->screenshot_counter++;

    push_info(iris, "Screenshot saved as '" + filename + "'");

    return true;
}

void handle_keydown_event(iris::instance* iris, SDL_Event* event) {
    SDL_Keycode key = event->key.key;

    switch (key) {
        case SDLK_SPACE: {
            iris->pause = !iris->pause;

            // vulkan::wait_idle(iris);
        } break;
        case SDLK_F9: {
            vulkan::wait_idle(iris);

            bool saved = save_screenshot(iris);
        } break;
        case SDLK_F11: {
            iris->fullscreen = !iris->fullscreen;

            SDL_SetWindowFullscreen(iris->window, iris->fullscreen ? true : false);
        } break;
        case SDLK_F1: {
            printf("ps2: Sending poweroff signal\n");
            ps2_cdvd_power_off(iris->ps2->cdvd);
        } break;
    }

    iris->last_input_event_read = false;
    iris->last_input_event_value = 1.0f;
    iris->last_input_event = sdl_event_to_input_event(event);

    if (iris->input_devices[0]) iris->input_devices[0]->handle_event(iris, event);
    if (iris->input_devices[1]) iris->input_devices[1]->handle_event(iris, event);
}

void handle_keyup_event(iris::instance* iris, SDL_Event* event) {
    // Add special keyup handling here if needed

    if (iris->input_devices[0]) iris->input_devices[0]->handle_event(iris, event);
    if (iris->input_devices[1]) iris->input_devices[1]->handle_event(iris, event);
}

}

================================================
FILE: frontend/iris.cpp
================================================
// Standard includes
#include <filesystem>
#include <algorithm>
#include <cstdlib>
#include <cstdio>
#include <thread>
#include <cmath>

// Iris includes
#include "iris.hpp"
#include "config.hpp"
#include "ee/ee_def.hpp"
#include "ee/vu_def.hpp"

// SDL3 includes
#include <SDL3/SDL.h>

// External includes
#include "res/IconsMaterialSymbols.h"

namespace iris {

void add_recent(iris::instance* iris, std::string file, int type) {
    auto it = std::find_if(iris->recents.begin(), iris->recents.end(), [file, type](const recent& a) {
        return a.type == type && a.path == file;
    });

    if (it != iris->recents.end()) {
        iris->recents.erase(it);
        iris->recents.push_front({file, type});

        return;
    }

    iris->recents.push_front({file, type});

    if (iris->recents.size() == 11)
        iris->recents.pop_back();
}

int open_file(iris::instance* iris, std::string file) {
    std::filesystem::path path(file);
    std::string ext = path.extension().string();

    for (char& c : ext)
        c = tolower(c);

    // Load disc image
    if (ext == ".iso" || ext == ".bin" || ext == ".cue" ||
        ext == ".chd" || ext == ".cso" || ext == ".zso") {
        if (ps2_cdvd_open(iris->ps2->cdvd, file.c_str(), 0))
            return 1;

        char* boot_file = disc_get_boot_path(iris->ps2->cdvd->disc);

        if (!boot_file)
            return 2;

        elf::load_symbols_from_disc(iris);

        renderer_reset(iris->renderer);

        ps2_set_system(iris->ps2, iris->system);
        ps2_load_bios(iris->ps2, iris->bios_path.c_str());
        ps2_boot_file(iris->ps2, boot_file);

        iris->loaded = file;

        if (iris->autostart) {
            iris->pause = false;
        }

        return 0;
    }

    elf::load_symbols_from_file(iris, file);

    // Note: We need the trailing whitespaces here because of IOMAN HLE
    // Load executable
    file = "host:  " + file;

    renderer_reset(iris->renderer);

    ps2_set_system(iris->ps2, iris->system);
    ps2_load_bios(iris->ps2, iris->bios_path.c_str());
    ps2_boot_file(iris->ps2, file.c_str());

    iris->loaded = file;

    if (iris->autostart) {
        iris->pause = false;
    }

    return 0;
}

void update_title(iris::instance* iris) {
    char buf[512];

    std::string base = "";

    if (iris->loaded.size()) {
        base = std::filesystem::path(iris->loaded).filename().string();
    }

    sprintf(buf, base.size() ? IRIS_TITLE " | %s" : IRIS_TITLE,
        base.c_str()
    );

    SDL_SetWindowTitle(iris->window, buf);
}

void update_time(iris::instance* iris) {
    int t = SDL_GetTicks() - iris->ticks;

    if (t < 500)
        return;

    if (iris->fps == 0.0f) {
        iris->fps = (float)iris->frames;
    } else {
        iris->fps += (float)iris->frames;
        iris->fps /= 2.0f;
    }

    iris->ticks = SDL_GetTicks();
    iris->frames = 0;
}

void sleep_limiter(iris::instance* iris) {
    uint32_t ticks = (1.0f / iris->fps_cap) * 1000.0f;

    std::this_thread::sleep_for(std::chrono::milliseconds(ticks / 2));

    // uint32_t now = SDL_GetTicks();

    // while ((SDL_GetTicks() - now) < ticks) {
    //     std::this_thread::sleep_for(std::chrono::milliseconds(ticks / 4));
    // }
}

static inline void do_cycle(iris::instance* iris) {
    ps2_cycle(iris->ps2);

    if (iris->step_out) {
        // jr $ra
        if (iris->ps2->ee->opcode == 0x03e00008) {
            iris->step_out = false;
            iris->pause = true;

            // Consume the delay slot
            ps2_cycle(iris->ps2);
        }
    }

    if (iris->step_over) {
        if (iris->ps2->ee->pc == iris->step_over_addr) {
            iris->step_over = false;
            iris->pause = true;
        }
    }

    for (const iris::breakpoint& b : iris->breakpoints) {
        if (b.cpu == iris::BKPT_CPU_EE) {
            if (iris->ps2->ee->pc == b.addr) {
                iris->pause = true;
            }
        } else {
            if (iris->ps2->iop->pc == b.addr) {
                iris->pause = true;
            }
        }
    }
}

void update_window(iris::instance* iris) {
    using namespace ImGui;

    // Limit FPS to 60 only when paused
    if (iris->limit_fps && iris->pause)
        sleep_limiter(iris);

    update_title(iris);
    update_time(iris);

    ImGuiIO& io = ImGui::GetIO();

    // Start the Dear ImGui frame
    if (SDL_GetWindowFlags(iris->window) & SDL_WINDOW_MINIMIZED) {
        SDL_Delay(1);

        return;
    }

    // Resize swapchain?
    int width, height;

    SDL_GetWindowSize(iris->window, &width, &height);

    if (width > 0 && height > 0 && (iris->swapchain_rebuild || iris->main_window_data.Width != width || iris->main_window_data.Height != height)) {
        ImGui_ImplVulkan_SetMinImageCount(iris->min_image_count);
    
        ImGui_ImplVulkanH_CreateOrResizeWindow(
            iris->instance,
            iris->physical_device,
            iris->device,
            &iris->main_window_data,
            iris->queue_family,
            nullptr,
            width, height,
            iris->min_image_count,
            0
        );

        iris->main_window_data.FrameIndex = 0;
        iris->swapchain_rebuild = false;
    }

    // Start the Dear ImGui frame
    ImGui_ImplVulkan_NewFrame();
    ImGui_ImplSDL3_NewFrame();
    ImGui::NewFrame();

    if (!iris->fullscreen) {
        show_main_menubar(iris);
    }

    DockSpaceOverViewport(0, GetMainViewport(), ImGuiDockNodeFlags_PassthruCentralNode);

    // Drop file fade animation
    if (iris->drop_file_active) {
        iris->drop_file_alpha += iris->drop_file_alpha_delta;

        if (iris->drop_file_alpha_delta > 0.0f) {
            if (iris->drop_file_alpha >= 1.0f) {
                iris->drop_file_alpha = 1.0f;
                iris->drop_file_alpha_delta = 0.0f;
            }
        } else {
            if (iris->drop_file_alpha <= 0.0f) {
                iris->drop_file_alpha = 0.0f;
                iris->drop_file_alpha_delta = 0.0f;
                iris->drop_file_active = false;
            }
        }

        GetForegroundDrawList()->AddRectFilled(
            ImVec2(0, 0),
            ImVec2(width, height),
            ImColor(0.0f, 0.0f, 0.0f, iris->drop_file_alpha * 0.35f)
        );

        ImVec2 text_size = CalcTextSize("Drop file here to launch");

        PushFont(iris->font_icons_big);

        ImVec2 icon_size = CalcTextSize(ICON_MS_DOWNLOAD);

        ImVec2 total_size = ImVec2(
            std::max(icon_size.x, text_size.x),
            icon_size.y + text_size.y
        );

        GetForegroundDrawList()->AddText(
            ImVec2(width / 2 - icon_size.x / 2, height / 2 - icon_size.y),
            ImColor(1.0f, 1.0f, 1.0f, iris->drop_file_alpha),
            ICON_MS_DOWNLOAD
        );

        PopFont();

        GetForegroundDrawList()->AddText(
            ImVec2(width / 2 - text_size.x / 2, height / 2),
            ImColor(1.0f, 1.0f, 1.0f, iris->drop_file_alpha),
            "Drop file here to launch"
        );
    }

    if (iris->show_ee_control) show_ee_control(iris);
    if (iris->show_ee_state) show_ee_state(iris);
    if (iris->show_ee_logs) show_ee_logs(iris);
    if (iris->show_ee_interrupts) show_ee_interrupts(iris);
    if (iris->show_ee_dmac) show_ee_dmac(iris);
    if (iris->show_iop_control) show_iop_control(iris);
    if (iris->show_iop_state) show_iop_state(iris);
    if (iris->show_iop_logs) show_iop_logs(iris);
    if (iris->show_iop_interrupts) show_iop_interrupts(iris);
    if (iris->show_iop_modules) show_iop_modules(iris);
    if (iris->show_iop_dma) show_iop_dma(iris);
    if (iris->show_gs_debugger) show_gs_debugger(iris);
    if (iris->show_spu2_debugger) show_spu2_debugger(iris);
    if (iris->show_memory_viewer) show_memory_viewer(iris);
    if (iris->show_vu_disassembler) show_vu_disassembler(iris);
    if (iris->show_status_bar && !iris->fullscreen) show_status_bar(iris);
    if (iris->show_breakpoints) show_breakpoints(iris);
    if (iris->show_about_window) show_about_window(iris);
    if (iris->show_settings) show_settings(iris);
    if (iris->show_pad_debugger) show_pad_debugger(iris);
    if (iris->show_symbols) show_symbols(iris);
    if (iris->show_threads) show_threads(iris);
    if (iris->show_sysmem_logs) show_sysmem_logs(iris);
    if (iris->show_memory_card_tool) show_memory_card_tool(iris);
    if (iris->show_memory_search) show_memory_search(iris);
    // if (iris->show_gamelist) show_gamelist(iris);
    if (iris->show_imgui_demo) ShowDemoWindow(&iris->show_imgui_demo);
    if (iris->show_bios_setting_window) show_bios_setting_window(iris);
    if (iris->show_overlay) show_overlay(iris);

    // Display little pause icon in the top right corner
    if (iris->pause) {
        ImVec2 ts = CalcTextSize(ICON_MS_PAUSE);
        ImVec2 offset = ImVec2(10.0f, 10.0f);
        ImVec2 padding = ImVec2(0.0f, 0.0f);

        ts.x -= 1.0f;

        int menubar_offset = 0;

        if (!iris->fullscreen) {
            menubar_offset += iris->menubar_height;
        }

        // GetBackgroundDrawList()->AddRectFilled(
        //     ImVec2(width - ts.x - offset.x - padding.x, menubar_offset + offset.y - padding.y),
        //     ImVec2(width - offset.x + padding.x, menubar_offset + ts.y + offset.y + padding.y),
        //     GetColorU32(GetStyleColorVec4(ImGuiCol_WindowBg)), 8.0f
        // );

        GetBackgroundDrawList(GetMainViewport())->AddText(
            ImVec2(width - ts.x - offset.x, menubar_offset + offset.y),
            GetColorU32(GetStyleColorVec4(ImGuiCol_Text)),
            ICON_MS_PAUSE
        );
    }

    handle_animations(iris);

    // Rendering
    ImGui::Render();

    ImDrawData* draw_data = ImGui::GetDrawData();

    const bool main_is_minimized = (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f);

    iris->main_window_data.ClearValue.color.float32[0] = 0.0f;
    iris->main_window_data.ClearValue.color.float32[1] = 0.0f;
    iris->main_window_data.ClearValue.color.float32[2] = 0.0f;
    iris->main_window_data.ClearValue.color.float32[3] = 1.0f;

    if (!main_is_minimized) {
        if (!imgui::render_frame(iris, draw_data)) {
            printf("iris: Failed to render ImGui frame\n");
        }
    }

    iris->frames++;
}

iris::instance* create() {
    return new iris::instance();
}

bool init(iris::instance* iris, int argc, const char* argv[]) {
    if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_EVENTS | SDL_INIT_GAMEPAD)) {
        fprintf(stderr, "iris: Failed to init SDL \'%s\'\n", SDL_GetError());

        return false;
    }

    // Create and check window
    iris->main_scale = SDL_GetDisplayContentScale(SDL_GetPrimaryDisplay());

    // Init preferences path
    if (std::filesystem::exists("portable") || std::filesystem::exists("portable.txt")) {
        iris->pref_path = "./";
    } else {
        char* pref = SDL_GetPrefPath("Allkern", "Iris");

        iris->pref_path = std::string(pref);

        SDL_free(pref);
    }

    if (!iris::emu::init(iris)) {
        fprintf(stderr, "iris: Failed to initialize emulator state\n");

        return false;
    }

    if (!iris::settings::init(iris, argc, argv)) {
        fprintf(stderr, "iris: Failed to initialize settings\n");

        return false;
    }

    iris->window = SDL_CreateWindow(
        IRIS_TITLE,
        iris->window_width, iris->window_height,
        SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE |
        SDL_WINDOW_HIGH_PIXEL_DENSITY | SDL_WINDOW_HIDDEN
    );

    if (!iris->window) {
        printf("iris: Failed to create SDL window \'%s\'\n", SDL_GetError());

        return false;
    }

    if (!iris::vulkan::init(iris, iris->vulkan_enable_validation_layers)) {
        fprintf(stderr, "iris: Failed to initialize Vulkan\n");

        return false;
    }

    if (!iris::imgui::init(iris)) {
        fprintf(stderr, "iris: Failed to initialize ImGui\n");

        return false;
    }

    if (!iris::platform::init(iris)) {
        fprintf(stderr, "iris: Failed to initialize platform\n");

        return false;
    }

    if (!iris::audio::init(iris)) {
        fprintf(stderr, "iris: Failed to initialize audio\n");

        return false;
    }

    if (!iris::render::init(iris)) {
        fprintf(stderr, "iris: Failed to initialize render state\n");

        return false;
    }

    if (!iris::input::init(iris)) {
        fprintf(stderr, "iris: Failed to initialize input\n");

        return false;
    }

    for (const std::string& s : iris->shader_passes_pending)
        shaders::push(iris, s);

    iris->shader_passes_pending.clear();

    // Sadly we need to start a frame here to measure menubar height
    ImGui_ImplVulkan_NewFrame();
    ImGui_ImplSDL3_NewFrame();
    ImGui::NewFrame();

    iris->menubar_height = ImGui::GetFrameHeight();

    ImGui::EndFrame();

    if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable) {
        ImGui::UpdatePlatformWindows();
        ImGui::RenderPlatformWindowsDefault();
    }

    SDL_SetWindowSize(iris->window, iris->window_width, iris->window_height + get_menubar_height(iris));
    SDL_ShowWindow(iris->window);

    return true;
}

SDL_AppResult update(iris::instance* iris) {
    if (iris->double_click_counter) {
        iris->double_click_counter--;
    }

    if (iris->pause) {
        iris->step_out = false;
        iris->step_over = false;

        if (iris->step) {
            ps2_step_ee(iris->ps2);

            iris->step = false;
        }

        iris::update_window(iris);

        return SDL_APP_CONTINUE;
    }

    // Execute until VBlank
    while (!ps2_gs_is_vblank(iris->ps2->gs)) {
        do_cycle(iris);

        if (iris->pause) {
            iris::update_window(iris);

            return SDL_APP_CONTINUE;
        }
    }

    // Draw frame
    iris::update_window(iris);
    
    // Execute until vblank is over
    while (ps2_gs_is_vblank(iris->ps2->gs)) {
        do_cycle(iris);

        if (iris->pause) {
            iris::update_window(iris);

            return SDL_APP_CONTINUE;
        }
    }

    // float p = ((float)iris->ps2->ee->eenull_counter / (float)(4920115)) * 100.0f;

    // printf("ee: Time spent idling: %ld cycles (%.2f%%) INTC reads: %d CSR reads: %d (%.1f fps)\n", iris->ps2->ee->eenull_counter, p, iris->ps2->ee->intc_reads, iris->ps2->ee->csr_reads, 1.0f / ImGui::GetIO().DeltaTime);

    iris->ps2->ee->eenull_counter = 0;
    iris->ps2->ee->intc_reads = 0;
    iris->ps2->ee->csr_reads = 0;

    return SDL_APP_CONTINUE;
}

SDL_AppResult handle_events(iris::instance* iris, SDL_Event* event) {
    ImGui_ImplSDL3_ProcessEvent(event);

    switch (event->type) {
        case SDL_EVENT_QUIT: {
            return SDL_APP_SUCCESS;
        } break;

        case SDL_EVENT_MOUSE_BUTTON_DOWN: {
            if (ImGui::GetIO().WantCaptureMouse) {
                break;
            }

            if (event->button.button == SDL_BUTTON_LEFT && event->button.windowID == SDL_GetWindowID(iris->window)) {
                if (iris->double_click_counter) {
                    if ((SDL_GetTicks() - iris->double_click_counter) > iris->double_click_interval) {
                        iris->double_click_counter = SDL_GetTicks();
                    } else {
                        iris->fullscreen = !iris->fullscreen;

                        SDL_SetWindowFullscreen(iris->window, iris->fullscreen);
                    }
                } else {
                    iris->double_click_counter = SDL_GetTicks();
                }
            }
        } break;

        case SDL_EVENT_GAMEPAD_ADDED: {
            SDL_Gamepad* gamepad = SDL_OpenGamepad(event->gdevice.which);

            if (!gamepad) {
                SDL_Log("Failed to open gamepad ID %u: %s", (unsigned int) event->gdevice.which, SDL_GetError());
            }

            if (iris->ds[0] && ((iris->input_devices[0] == nullptr) || (iris->input_devices[0]->get_type() == 0))) {
                if (iris->input_devices[0]) delete iris->input_devices[0];

                iris->input_devices[0] = new iris::gamepad_device(event->gdevice.which);
                iris->input_devices[0]->set_slot(0);

                if (iris->input_map[0] <= 1) {
                    iris->input_map[0] = 1;
                }

                push_info(iris, "\'" + std::string(SDL_GetGamepadName(gamepad)) + "\' connected to slot 1");
            } else if (iris->ds[1] && ((iris->input_devices[1] == nullptr) || (iris->input_devices[1]->get_type() == 0))) {
                if (iris->input_devices[1]) delete iris->input_devices[1];

                iris->input_devices[1] = new iris::gamepad_device(event->gdevice.which);
                iris->input_devices[1]->set_slot(1);

                if (iris->input_map[1] <= 1) {
                    iris->input_map[1] = 1;
                }

                push_info(iris, "\'" + std::string(SDL_GetGamepadName(gamepad)) + "\' connected to slot 2");
            } else {
                push_info(iris, "\'" + std::string(SDL_GetGamepadName(gamepad)) + "\' connected");
            }

            iris->gamepads[event->gdevice.which] = gamepad;
        } break;

        case SDL_EVENT_GAMEPAD_REMOVED: {
            SDL_Gamepad* gamepad = iris->gamepads[event->gdevice.which];

            for (int i = 0; i < 2; i++) {
                if (iris->input_devices[i] && iris->input_devices[i]->get_type() == 1) {
                    iris::gamepad_device* gp = static_cast<iris::gamepad_device*>(iris->input_devices[i]);

                    if (gp->get_id() == event->gdevice.which) {
                        delete iris->input_devices[i];
                        iris->input_devices[i] = new iris::keyboard_device();

                        if (iris->input_map[i] <= 1) {
                            iris->input_map[i] = 0;
                        }

                        push_info(iris, "\'" + std::string(SDL_GetGamepadName(gamepad)) + "\' in slot " + std::to_string(i + 1) + " disconnected");
                    }
                }
            }

            if (gamepad) {
                SDL_CloseGamepad(gamepad);

                iris->gamepads.erase(event->gdevice.which);
            }
        } break;

        case SDL_EVENT_WINDOW_CLOSE_REQUESTED: {
            if (event->window.windowID == SDL_GetWindowID(iris->window)) {
                return SDL_APP_SUCCESS;
            }
        } break;

        case SDL_EVENT_GAMEPAD_BUTTON_DOWN:
        case SDL_EVENT_GAMEPAD_BUTTON_UP:
        case SDL_EVENT_GAMEPAD_AXIS_MOTION:
        case SDL_EVENT_KEY_UP: {
            iris->last_input_event_read = false;
            iris->last_input_event = input::sdl_event_to_input_event(event);

            if (event->type == SDL_EVENT_GAMEPAD_AXIS_MOTION) {
                iris->last_input_event_value = fabs(event->gaxis.value / 32767.0f);
            } else {
                iris->last_input_event_value = 1.0f;
            }

            if (iris->input_devices[0]) iris->input_devices[0]->handle_event(iris, event);
            if (iris->input_devices[1]) iris->input_devices[1]->handle_event(iris, event);
        } break;

        case SDL_EVENT_KEY_DOWN: {
            input::handle_keydown_event(iris, event);
        } break;

        case SDL_EVENT_DROP_BEGIN: {
            iris->drop_file_active = true;
            iris->drop_file_alpha = 0.0f;
            iris->drop_file_alpha_delta = 1.0f / 10.0f;
            iris->drop_file_alpha_target = 1.0f;
        } break;
        
        case SDL_EVENT_DROP_COMPLETE: {
            iris->drop_file_active = true;
            iris->drop_file_alpha = iris->drop_file_alpha_target;
            iris->drop_file_alpha_delta = -(1.0f / 10.0f);
            iris->drop_file_alpha_target = 0.0f;
        } break;

        case SDL_EVENT_DROP_FILE: {
            if (!event->drop.data)
                break;

            std::string path(event->drop.data);

            std::filesystem::path p(path);

            if (std::filesystem::is_regular_file(p)) {
                if (open_file(iris, path)) {
                    push_info(iris, "Failed to open file: " + path);
                } else {
                    add_recent(iris, path, RECENT_TYPE_PS2);
                }
            } else {
                if (emu::load_arcade(iris, path)) {
                    add_recent(iris, path, RECENT_TYPE_ARCADE);
                } else {
                    push_info(iris, "Failed to boot arcade: " + path);
                }
            }

            // Maybe not needed anymore?
            // SDL_free(event->drop.data);
        } break;
    }

    return SDL_APP_CONTINUE;
}

int get_menubar_height(iris::instance* iris) {
    if (iris->show_status_bar) {
        return iris->menubar_height * 2;
    }

    return iris->menubar_height;
}

void destroy(iris::instance* iris) {
    for (int i = 0; i < 2; i++) {
        if (iris->input_devices[i]) {
            delete iris->input_devices[i];
            iris->input_devices[i] = nullptr;
        }
    }

    if (iris->imgui_enable_viewports) {
        iris->show_ee_control = false;
        iris->show_ee_state = false;
        iris->show_ee_logs = false;
        iris->show_ee_interrupts = false;
        iris->show_ee_dmac = false;
        iris->show_iop_control = false;
        iris->show_iop_state = false;
        iris->show_iop_logs = false;
        iris->show_iop_interrupts = false;
        iris->show_iop_modules = false;
        iris->show_iop_dma = false;
        iris->show_gs_debugger = false;
        iris->show_spu2_debugger = false;
        iris->show_memory_viewer = false;
        iris->show_memory_search = false;
        iris->show_vu_disassembler = false;
        iris->show_breakpoints = false;
        iris->show_threads = false;
        iris->show_sysmem_logs = false;
        iris->show_imgui_demo = false;
        iris->show_overlay = false;
    }

    if (iris->window) SDL_HideWindow(iris->window);

    iris::imgui::cleanup(iris);
    iris::audio::close(iris);
    iris::settings::close(iris);
    iris::render::destroy(iris);
    iris::vulkan::cleanup(iris);
    iris::platform::destroy(iris);
    iris::emu::destroy(iris);

    if (iris->window) SDL_DestroyWindow(iris->window);

    SDL_Quit();

    delete iris;
}

}

================================================
FILE: frontend/iris.hpp
================================================
#pragma once

#include <unordered_map>
#include <cstdint>
#include <string>
#include <vector>
#include <chrono>
#include <array>
#include <deque>

#include "gs/renderer/renderer.hpp"
#include "gs/renderer/config.hpp"

#include <SDL3/SDL.h>
#include <volk.h>

#include "imgui.h"
#include "imgui_impl_sdl3.h"
#include "imgui_impl_vulkan.h"

#include "ps2.h"
#include "config.hpp"

namespace iris {

#define RENDER_ASPECT_NATIVE 0
#define RENDER_ASPECT_STRETCH 1
#define RENDER_ASPECT_STRETCH_KEEP 2
#define RENDER_ASPECT_4_3 3
#define RENDER_ASPECT_16_9 4
#define RENDER_ASPECT_5_4 5
#define RENDER_ASPECT_AUTO 6

#define IRIS_THEME_GRANITE 0
#define IRIS_THEME_IMGUI_DARK 1
#define IRIS_THEME_IMGUI_LIGHT 2
#define IRIS_THEME_IMGUI_CLASSIC 3
#define IRIS_THEME_CHERRY 4
#define IRIS_THEME_SOURCE 5

#define IRIS_SCREENSHOT_FORMAT_PNG 0
#define IRIS_SCREENSHOT_FORMAT_BMP 1
#define IRIS_SCREENSHOT_FORMAT_JPG 2
#define IRIS_SCREENSHOT_FORMAT_TGA 3

#define IRIS_SCREENSHOT_MODE_INTERNAL 0
#define IRIS_SCREENSHOT_MODE_DISPLAY 1

#define IRIS_SCREENSHOT_JPG_QUALITY_MINIMUM 0
#define IRIS_SCREENSHOT_JPG_QUALITY_LOW 1
#define IRIS_SCREENSHOT_JPG_QUALITY_MEDIUM 2
#define IRIS_SCREENSHOT_JPG_QUALITY_HIGH 3
#define IRIS_SCREENSHOT_JPG_QUALITY_MAXIMUM 4
#define IRIS_SCREENSHOT_JPG_QUALITY_CUSTOM 5 

#define IRIS_CODEVIEW_COLOR_SCHEME_SOLARIZED_DARK 0
#define IRIS_CODEVIEW_COLOR_SCHEME_SOLARIZED_LIGHT 1
#define IRIS_CODEVIEW_COLOR_SCHEME_ONE_DARK_PRO 2
#define IRIS_CODEVIEW_COLOR_SCHEME_CATPPUCCIN_LATTE 3
#define IRIS_CODEVIEW_COLOR_SCHEME_CATPPUCCIN_FRAPPE 4
#define IRIS_CODEVIEW_COLOR_SCHEME_CATPPUCCIN_MACCHIATO 5
#define IRIS_CODEVIEW_COLOR_SCHEME_CATPPUCCIN_MOCHA 6

#define IRIS_TITLEBAR_DEFAULT 0
#define IRIS_TITLEBAR_SEAMLESS 1

class instance;

// class widget {
// public:
//     virtual bool init(iris::instance* iris) = 0;
//     virtual void render(iris::instance* iris) = 0;
//     virtual ~widget() = default;
// };

enum : int {
    BKPT_CPU_EE,
    BKPT_CPU_IOP
};

struct breakpoint {
    uint32_t addr;
    const char* symbol = nullptr;
    int cpu;
    bool cond_r, cond_w, cond_x;
    int size;
    bool enabled;
};

struct move_animation {
    int frames;
    int frames_remaining;
    float source_x, source_y;
    float target_x, target_y;
    float x, y;
};

struct fade_animation {
    int frames;
    int frames_remaining;
    int source_alpha, target_alpha;
    int alpha;
};

struct notification {
    int type;
    int state;
    int frames;
    int frames_remaining;
    float width, height;
    float text_width, text_height;
    bool end;
    move_animation move;
    fade_animation fade;
    std::string text;
};

struct elf_symbol {
    char* name;
    uint32_t addr;
    uint32_t size;
};

enum {
    RECENT_TYPE_PS2,
    RECENT_TYPE_ARCADE
};

enum {
    INPUT_CONTROLLER_DUALSHOCK2

    // Large To-do list here, we're missing the Namco GunCon
    // controllers, JogCon, NegCon, Buzz! Buzzer, the Train
    // controllers, Taiko Drum Master controller, the Dance Dance
    // Revolution mat, Guitar Hero controllers, etc.
};

struct input_device {
    int m_slot;

    void set_slot(int slot) {
        this->m_slot = slot;
    }

    int get_slot() {
        return this->m_slot;
    }

    virtual int get_type() = 0;
    virtual void handle_event(iris::instance* iris, SDL_Event* event) = 0;
};

class keyboard_device : public input_device {
public:
    int get_type() override {
        return 0;
    }

    void handle_event(iris::instance* iris, SDL_Event* event) override;
};

class gamepad_device : public input_device {
    SDL_JoystickID id;

public:
    gamepad_device(SDL_JoystickID id) : id(id) {}

    int get_type() override {
        return 1;
    }

    SDL_JoystickID get_id() {
        return id;
    }

    void handle_event(iris::instance* iris, SDL_Event* event) override;
};

union input_event {
    struct {
        uint32_t id;
        uint32_t type;
    };

    uint64_t u64;
};

enum event {
    IRIS_EVENT_KEYBOARD,
    IRIS_EVENT_GAMEPAD_BUTTON,
    IRIS_EVENT_GAMEPAD_AXIS_POS,
    IRIS_EVENT_GAMEPAD_AXIS_NEG
};

enum input_action : uint32_t {
    IRIS_DS_BT_CROSS,
    IRIS_DS_BT_CIRCLE,
    IRIS_DS_BT_SQUARE,
    IRIS_DS_BT_TRIANGLE,
    IRIS_DS_BT_START,
    IRIS_DS_BT_SELECT,
    IRIS_DS_BT_ANALOG,
    IRIS_DS_BT_UP,
    IRIS_DS_BT_DOWN,
    IRIS_DS_BT_LEFT,
    IRIS_DS_BT_RIGHT,
    IRIS_DS_BT_L1,
    IRIS_DS_BT_R1,
    IRIS_DS_BT_L2,
    IRIS_DS_BT_R2,
    IRIS_DS_BT_L3,
    IRIS_DS_BT_R3,
    IRIS_DS_AX_RIGHTV_POS,
    IRIS_DS_AX_RIGHTV_NEG,
    IRIS_DS_AX_RIGHTH_POS,
    IRIS_DS_AX_RIGHTH_NEG,
    IRIS_DS_AX_LEFTV_POS,
    IRIS_DS_AX_LEFTV_NEG,
    IRIS_DS_AX_LEFTH_POS,
    IRIS_DS_AX_LEFTH_NEG,

    IRIS_S14X_SW_DOWN,
    IRIS_S14X_SW_UP,
    IRIS_S14X_SW_ENTER,
    IRIS_S14X_SW_TEST,
    IRIS_S14X_SW_SERVICE,
    IRIS_S14X_SW_P1_START,
    IRIS_S14X_SW_P2_START,
    IRIS_S14X_SW_P3_START,
    IRIS_S14X_SW_P4_START,
    IRIS_INPUT_ACTION_MAX
};

struct vertex {
    struct {
        float x, y;
    } pos, uv;

    static constexpr const VkVertexInputBindingDescription get_binding_description() {
        VkVertexInputBindingDescription binding_description = {};

        binding_description.binding = 0;
        binding_description.stride = sizeof(vertex);
        binding_description.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;

        return binding_description;
    }

    static constexpr const std::array<VkVertexInputAttributeDescription, 2> get_attribute_descriptions() {
        std::array<VkVertexInputAttributeDescription, 2> attribute_descriptions = {};

        attribute_descriptions[0].binding = 0;
        attribute_descriptions[0].location = 0;
        attribute_descriptions[0].format = VK_FORMAT_R32G32_SFLOAT;
        attribute_descriptions[0].offset = offsetof(vertex, pos);

        attribute_descriptions[1].binding = 0;
        attribute_descriptions[1].location = 1;
        attribute_descriptions[1].format = VK_FORMAT_R32G32_SFLOAT;
        attribute_descriptions[1].offset = offsetof(vertex, uv);

        return attribute_descriptions;
    }
};

struct texture {
    int width = 0, height = 0, stride = 0;
    VkDeviceSize image_size = 0;
    VkImage image = VK_NULL_HANDLE;
    VkImageView image_view = VK_NULL_HANDLE;
    VkSampler sampler = VK_NULL_HANDLE;
    VkDeviceMemory image_memory = VK_NULL_HANDLE;
    VkDescriptorSet descriptor_set = VK_NULL_HANDLE;
};

namespace shaders {
    class pass;
}

struct vulkan_gpu {
    VkPhysicalDeviceType type = VK_PHYSICAL_DEVICE_TYPE_OTHER;
    VkPhysicalDevice device = VK_NULL_HANDLE;
    std::string name = "";
    uint32_t api_version = 0;
};

template <typename Key, typename Value> class bidirectional_map {
    std::unordered_map <Key, Value> m_forward_map;
    std::unordered_map <Value, Key> m_reverse_map;

public:
    void insert(const Key& key, const Value& value) {
        m_forward_map[key] = value;
        m_reverse_map[value] = key;
    }

    std::unordered_map <Key, Value>& forward_map() {
        return m_forward_map;
    }

    std::unordered_map <Value, Key>& reverse_map() {
        return m_reverse_map;
    }

    bool erase_by_key(const Key& key) {
        auto it = m_forward_map.find(key);
        if (it != m_forward_map.end()) {
            Value value = it->second;
            m_forward_map.erase(it);
            m_reverse_map.erase(value);
            return true;
        }
        return false;
    }

    bool erase_by_value(const Value& value) {
        auto it = m_reverse_map.find(value);
        if (it != m_reverse_map.end()) {
            Key key = it->second;
            m_reverse_map.erase(it);
            m_forward_map.erase(key);
            return true;
        }
        return false;
    }

    void clear() {
        m_forward_map.clear();
        m_reverse_map.clear();
    }

    Value* get_value(const Key& key) {
        auto it = m_forward_map.find(key);
        if (it != m_forward_map.end()) {
            return &it->second;
        }
        return nullptr;
    }

    Key* get_key(const Value& value) {
        auto it = m_reverse_map.find(value);
        if (it != m_reverse_map.end()) {
            return &it->second;
        }
        return nullptr;
    }
};

struct mapping {
    std::string name;
    bidirectional_map <uint64_t, input_action> map;
};

struct recent {
    std::string path;
    int type;
};

struct instance {
    SDL_Window* window = nullptr;
    SDL_AudioStream* stream = nullptr;

    // Vulkan state
    std::vector <VkExtensionProperties> instance_extensions;
    std::vector <VkLayerProperties> instance_layers;
    std::vector <VkExtensionProperties> device_extensions;
    std::vector <VkLayerProperties> device_layers;
    std::vector <const char*> enabled_instance_extensions;
    std::vector <const char*> enabled_instance_layers;
    std::vector <const char*> enabled_device_extensions;
    std::vector <const char*> enabled_device_layers;
    std::vector <vulkan_gpu> vulkan_gpus;
    VkApplicationInfo app_info = {};
    VkInstanceCreateInfo instance_create_info = {};
    VkDeviceCreateInfo device_create_info = {};
    VkInstance instance = VK_NULL_HANDLE;
    VkPhysicalDevice physical_device = VK_NULL_HANDLE;
    VkPhysicalDeviceFeatures2 device_features = {};
    VkDeviceQueueCreateInfo queue_create_info = {};
    uint32_t queue_family = (uint32_t)-1;
    VkQueue queue = VK_NULL_HANDLE;
    VkDevice device = VK_NULL_HANDLE;
    VkDescriptorPool descriptor_pool = VK_NULL_HANDLE;
    ImGui_ImplVulkanH_Window main_window_data = {};
    uint32_t min_image_count = 2;
    bool swapchain_rebuild = false;
    VkSurfaceKHR surface = VK_NULL_HANDLE;
    float main_scale = 1;
    VkPhysicalDeviceVulkan11Features vulkan_11_features = {};
    VkPhysicalDeviceVulkan12Features vulkan_12_features = {};
    VkPhysicalDeviceSubgroupSizeControlFeatures subgroup_size_control_features = {};
    VkSampler sampler[3] = { VK_NULL_HANDLE };
    bool cubic_supported = false;
    VkDescriptorSetLayout descriptor_set_layout = VK_NULL_HANDLE;
    VkDescriptorSet descriptor_set = VK_NULL_HANDLE;
    std::vector <VkDescriptorSet> descriptor_sets = {};
    VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
    VkRenderPass render_pass = VK_NULL_HANDLE;
    VkPipeline pipeline = VK_NULL_HANDLE;
    VkClearValue clear_value = { 0.11, 0.11, 0.11, 1.0 };
    VkBuffer vertex_buffer = VK_NULL_HANDLE;
    VkDeviceMemory vertex_buffer_memory = VK_NULL_HANDLE;
    VkBuffer vertex_staging_buffer = VK_NULL_HANDLE;
    VkDeviceMemory vertex_staging_buffer_memory = VK_NULL_HANDLE;
    VkDeviceSize vertex_buffer_size = 0;
    VkBuffer index_buffer = VK_NULL_HANDLE;
    VkDeviceMemory index_buffer_memory = VK_NULL_HANDLE;
    std::array <vertex, 4> vertices = {};
    std::array <uint16_t, 6> indices = {};
    renderer_image image = {};
    renderer_image output_image = {};

    // Multipass shader stuff
    std::vector <std::string> shader_passes_pending;
    std::vector <shaders::pass*> shader_passes = {};
    VkDescriptorSetLayout shader_descriptor_set_layout = VK_NULL_HANDLE;
    VkDescriptorSet shader_descriptor_set = VK_NULL_HANDLE;
    std::vector <VkDescriptorSet> shader_descriptor_sets = {};
    VkShaderModule default_vert_shader = VK_NULL_HANDLE;

    struct {
        VkImage image = VK_NULL_HANDLE;
        VkDeviceMemory memory = VK_NULL_HANDLE;
        VkImageView view = VK_NULL_HANDLE;
    } shader_framebuffers[2];

    std::vector <std::array <VkFramebuffer, 2>> shader_pass_framebuffers = {};

    struct ps2_state* ps2 = nullptr;

    unsigned int window_width = 960;
    unsigned int window_height = 720;
    unsigned int render_width = 640;
    unsigned int render_height = 480;

    unsigned int renderer_backend = RENDERER_BACKEND_HARDWARE;
    renderer_state* renderer = nullptr;

    texture ps2_memory_card_icon = {};
    texture ps1_memory_card_icon = {};
    texture pocketstation_icon = {};
    texture dualshock2_icon = {};
    texture iris_icon = {};

    ImFont* font_small_code = nullptr;
    ImFont* font_code = nullptr;
    ImFont* font_small = nullptr;
    ImFont* font_heading = nullptr;
    ImFont* font_body = nullptr;
    ImFont* font_icons = nullptr;
    ImFont* font_icons_big = nullptr;
    ImFont* font_black = nullptr;

    std::string elf_path = "";
    std::string boot_path = "";
    std::string bios_path = "";
    std::string rom1_path = "";
    std::string rom2_path = "";
    std::string nvram_path = "";
    std::string disc_path = "";
    std::string pref_path = "";
    std::string mcd0_path = "";
    std::string mcd1_path = "";
    std::string snap_path = "";
    std::string flash_path = "";
    std::string ini_path = "";
    std::string gcdb_path = "";

    uint8_t mac_address[6] = { 0 };

    bool core0_mute[24] = { false };
    bool core1_mute[24] = { false };
    int core0_solo = -1;
    int core1_solo = -1;

    bool open = false;
    bool pause = true;
    bool step = false;
    bool step_over = false;
    bool step_out = false;
    uint32_t step_over_addr = 0;

    bool show_ee_control = false;
    bool show_ee_state = false;
    bool show_ee_logs = false;
    bool show_ee_interrupts = false;
    bool show_ee_dmac = false;
    bool show_iop_control = false;
    bool show_iop_state = false;
    bool show_iop_logs = false;
    bool show_iop_interrupts = false;
    bool show_iop_modules = false;
    bool show_iop_dma = false;
    bool show_sysmem_logs = false;
    bool show_gs_debugger = false;
    bool show_spu2_debugger = false;
    bool show_memory_viewer = false;
    bool show_status_bar = true;
    bool show_breakpoints = false;
    bool show_settings = false;
    bool show_pad_debugger = false;
    bool show_symbols = false;
    bool show_threads = false;
    bool show_memory_card_tool = false;
    bool show_imgui_demo = false;
    bool show_vu_disassembler = false;
    bool show_overlay = false;
    bool show_memory_search = false;

    // Special windows
    bool show_bios_setting_window = false;
    bool show_about_window = false;

    bool fullscreen = false;
    int aspect_mode = RENDER_ASPECT_AUTO;
    int filter = 1;
    bool integer_scaling = false;
    float scale = 1.5f;
    int window_mode = 0;
    bool ee_control_follow_pc = true;
    bool iop_control_follow_pc = true;
    uint32_t ee_control_address = 0;
    uint32_t iop_control_address = 0;
    bool skip_fmv = false;
    int system = PS2_SYSTEM_AUTO;
    int theme = IRIS_THEME_GRANITE;
    bool enable_shaders = false;
    int vulkan_physical_device = -1;
    int vulkan_selected_device_index = 0;
    bool vulkan_enable_validation_layers = false;
    bool imgui_enable_viewports = false;
    int codeview_color_scheme = 0;
    ImColor codeview_color_text = IM_COL32(131, 148, 150, 255);
    ImColor codeview_color_comment = IM_COL32(88, 110, 117, 255);
    ImColor codeview_color_mnemonic = IM_COL32(211, 167, 30, 255);
    ImColor codeview_color_number = IM_COL32(138, 143, 226, 255);
    ImColor codeview_color_register = IM_COL32(68, 169, 240, 255);
    ImColor codeview_color_other = IM_COL32(89, 89, 89, 255);
    ImColor codeview_color_background = IM_COL32(30, 30, 30, 255);
    ImColor codeview_color_highlight = IM_COL32(75, 75, 75, 255);
    float codeview_font_scale = 1.0f;
    bool codeview_use_theme_background = true;
    bool autostart = true;
    int angle = 0;
    bool flip_x = false;
    bool flip_y = false;
    uint64_t double_click_interval = 500;
    uint64_t double_click_counter = 0;

    std::deque <recent> recents;

    bool dump_to_file = true;
    std::string settings_path = "";
    std::string mappings_path = "";

    int frames = 0;
    float fps = 0.0f;
    unsigned int ticks = 0;
    int menubar_height = 0;
    bool mute = false;
    bool prev_mute = false;
    float volume = 1.0f;
    int timescale = 8;
    bool mute_adma = true;
    bool vsync = true;
    float ui_scale = 1.0f;
    int screenshot_format = IRIS_SCREENSHOT_FORMAT_PNG;
    int screenshot_jpg_quality_mode = IRIS_SCREENSHOT_JPG_QUALITY_MAXIMUM;
    int screenshot_jpg_quality = 50;
    int screenshot_mode = IRIS_SCREENSHOT_MODE_INTERNAL;
    int docking_mode = 0;
    bool screenshot_shader_processing = false;
    input_device* input_devices[2] = { nullptr };
    std::unordered_map <SDL_JoystickID, SDL_Gamepad*> gamepads;
    std::vector <mapping> input_maps = {};
    int input_map[2] = { -1, -1 };
    input_event last_input_event = {};
    bool last_input_event_read = true;
    float last_input_event_value = 0.0f;

    bool limit_fps = true;
    float fps_cap = 60.0f;

    std::string loaded = "";

    std::vector <std::string> ee_log = { "" };
    std::vector <std::string> iop_log = { "" };
    std::vector <std::string> sysmem_log = { "" };

    std::vector <iris::breakpoint> breakpoints = {};
    std::deque <iris::notification> notifications = {};

    struct ds_state* ds[2] = { nullptr };
    struct mcd_state* mcd[2] = { nullptr };
    int mcd_slot_type[2] = { 0 };

    // input_device* device[2];

    float drop_file_alpha = 0.0f;
    float drop_file_alpha_delta = 0.0f;
    float drop_file_alpha_target = 0.0f;
    bool drop_file_active = false;

    // Debug
    std::vector <elf_symbol> symbols;
    std::vector <uint8_t> strtab;

    std::vector <spu2_sample> audio_buf;

    float avg_fps;
    float avg_frames;
    int screenshot_counter = 0;

    // Renderer configs
    hardware_config hardware_backend_config;

    // Windows-specific settings
#ifdef _WIN32
    int windows_titlebar_style = IRIS_TITLEBAR_DEFAULT;
    bool windows_enable_borders = true;
    bool windows_dark_mode = true;
#endif
};

struct push_constants {
    float resolution[2];
    int frame;
};

namespace audio {
    bool init(iris::instance* iris);
    void close(iris::instance* iris);
    void update(void* udata, SDL_AudioStream* stream, int additional_amount, int total_amount);
    bool mute(iris::instance* iris);
    void unmute(iris::instance* iris);
}

namespace settings {
    bool init(iris::instance* iris, int argc, const char* argv[]);
    bool check_for_quick_exit(int argc, const char* argv[]);
    void close(iris::instance* iris);
}

namespace shaders {
    class pass {
        VkPipelineLayout m_pipeline_layout = VK_NULL_HANDLE;
        VkPipeline m_pipeline = VK_NULL_HANDLE;
        VkRenderPass m_render_pass = VK_NULL_HANDLE;
        VkImageView m_input = VK_NULL_HANDLE;
        VkShaderModule m_vert_shader = VK_NULL_HANDLE;
        VkShaderModule m_frag_shader = VK_NULL_HANDLE;
        iris::instance* m_iris = nullptr;
        std::string m_id;

    public:
        void destroy();
        bool init(iris::instance* iris, const void* data, size_t size, std::string id);

        void swap(pass& rhs) {
            VkPipelineLayout pipeline_layout = m_pipeline_layout;
            VkPipeline pipeline = m_pipeline;
            VkRenderPass render_pass = m_render_pass;
            VkImageView input = m_input;
            VkShaderModule vert_shader = m_vert_shader;
            VkShaderModule frag_shader = m_frag_shader;
            iris::instance* iris = m_iris;
            std::string id = m_id;

            m_pipeline_layout = rhs.m_pipeline_layout;
            m_pipeline = rhs.m_pipeline;
            m_render_pass = rhs.m_render_pass;
            m_input = rhs.m_input;
            m_vert_shader = rhs.m_vert_shader;
            m_frag_shader = rhs.m_frag_shader;
            m_iris = rhs.m_iris;
            m_id = rhs.m_id;

            rhs.m_pipeline_layout = pipeline_layout;
            rhs.m_pipeline = pipeline;
            rhs.m_render_pass = render_pass;
            rhs.m_input = input;
            rhs.m_vert_shader = vert_shader;
            rhs.m_frag_shader = frag_shader;
            rhs.m_iris = iris;
            rhs.m_id = id;
        }

        pass(iris::instance* iris, const void* data, size_t size, std::string id);
        pass(pass&& other);
        pass() = default;
        ~pass();

        pass& operator=(pass&& other);

        VkPipelineLayout& get_pipeline_layout();
        VkPipeline& get_pipeline();
        VkRenderPass& get_render_pass();
        VkImageView& get_input();
        VkShaderModule& get_vert_shader();
        VkShaderModule& get_frag_shader();
        std::string get_id() const;

        bool bypass = false;
        bool ready();
        bool rebuild();
    };

    void push(iris::instance* iris, void* data, size_t size, std::string id);
    void push(iris::instance* iris, std::string id);
    void pop(iris::instance* iris);
    void insert(iris::instance* iris, int i, void* data, size_t size, std::string id);
    void insert(iris::instance* iris, std::string id);
    void erase(iris::instance* iris, int i);
    pass* at(iris::instance* iris, int i);
    void swap(iris::instance* iris, int i1, int i2);
    pass* front(iris::instance* iris);
    pass* back(iris::instance* iris);
    size_t count(iris::instance* iris);
    void clear(iris::instance* iris);
    std::vector <shaders::pass*>& vector(iris::instance* iris);
}

namespace imgui {
    bool init(iris::instance* iris);
    void set_theme(iris::instance* iris, int theme, bool set_bg_color = true);
    void set_codeview_scheme(iris::instance* iris, int scheme);
    bool render_frame(iris::instance* iris, ImDrawData* draw_data);
    void cleanup(iris::instance* iris);
    void set_vsync(iris::instance* iris, bool vsync);

    // Wrapper for ImGui::Begin that sets a default size
    bool BeginEx(const char* name, bool* p_open, ImGuiWindowFlags flags = 0);
}

namespace vulkan {
    bool init(iris::instance* iris, bool enable_validation = false);
    void cleanup(iris::instance* iris);
    texture upload_texture(iris::instance* iris, void* pixels, int width, int height, int stride);
    void free_texture(iris::instance* iris, texture& tex);
    void* read_image(iris::instance* iris, VkImage image, VkFormat format, int width, int height);
    void wait_idle(iris::instance* iris);
}

namespace platform {
    bool init(iris::instance* iris);
    bool apply_settings(iris::instance* iris);
    void destroy(iris::instance* iris);
}

namespace elf {
    bool load_symbols_from_disc(iris::instance* iris);
    bool load_symbols_from_file(iris::instance* iris, std::string path);
}

namespace emu {
    bool init(iris::instance* iris);
    void destroy(iris::instance* iris);
    bool load_arcade(iris::instance* iris, std::string path);
    int attach_memory_card(iris::instance* iris, int slot, const char* path);
    void detach_memory_card(iris::instance* iris, int slot);
    const char* get_system_name(iris::instance* iris, int system);
    const char* get_current_system_name(iris::instance* iris);
    int get_system_count(iris::instance* iris);
}

namespace render {
    bool init(iris::instance* iris);
    void destroy(iris::instance* iris);
    bool render_frame(iris::instance* iris, VkCommandBuffer command_buffer, VkFramebuffer framebuffer);
    bool save_screenshot(iris::instance* iris, std::string path);
    void switch_backend(iris::instance* iris, int backend);
    void refresh(iris::instance* iris);
}

namespace input {
    bool init(iris::instance* iris);
    void init_default_mapping(iris::instance* iris, int id);
    void load_db_default(iris::instance* iris);
    bool load_db_from_file(iris::instance* iris, const char* path);
    input_action* get_input_action(iris::instance* iris, int slot, uint64_t input);
    input_event sdl_event_to_input_event(SDL_Event* event);
    std::string get_default_screenshot_filename(iris::instance* iris);
    void execute_action(iris::instance* iris, input_action action, int slot, float value);
    bool save_screenshot(iris::instance* iris, std::string path = "");
    void handle_keydown_event(iris::instance* iris, SDL_Event* event);
    void handle_keyup_event(iris::instance* iris, SDL_Event* event);
}

iris::instance* create();
bool init(iris::instance* iris, int argc, const char* argv[]);
void destroy(iris::instance* iris);
SDL_AppResult handle_events(iris::instance* iris, SDL_Event* event);
SDL_AppResult update(iris::instance* iris);
void update_window(iris::instance* iris);
int get_menubar_height(iris::instance* iris);

void show_main_menubar(iris::instance* iris);
void show_ee_control(iris::instance* iris);
void show_ee_state(iris::instance* iris);
void show_ee_logs(iris::instance* iris);
void show_ee_interrupts(iris::instance* iris);
void show_ee_dmac(iris::instance* iris);
void show_iop_control(iris::instance* iris);
void show_iop_state(iris::instance* iris);
void show_iop_logs(iris::instance* iris);
void show_iop_interrupts(iris::instance* iris);
void show_iop_modules(iris::instance* iris);
void show_iop_dma(iris::instance* iris);
void show_sysmem_logs(iris::instance* iris);
void show_gs_debugger(iris::instance* iris);
void show_spu2_debugger(iris::instance* iris);
void show_memory_viewer(iris::instance* iris);
void show_vu_disassembler(iris::instance* iris);
void show_status_bar(iris::instance* iris);
void show_breakpoints(iris::instance* iris);
void show_about_window(iris::instance* iris);
void show_settings(iris::instance* iris);
void show_pad_debugger(iris::instance* iris);
void show_symbols(iris::instance* iris);
void show_threads(iris::instance* iris);
void show_overlay(iris::instance* iris);
void show_memory_card_tool(iris::instance* iris);
void show_bios_setting_window(iris::instance* iris);
void show_memory_search(iris::instance* iris);
// void show_gamelist(iris::instance* iris);

void handle_keydown_event(iris::instance* iris, SDL_Event* event);
void handle_keyup_event(iris::instance* iris, SDL_Event* event);
void handle_scissor_event(void* udata);
void handle_drag_and_drop_event(void* udata, const char* path);
void handle_ee_tty_event(void* udata, char c);
void handle_iop_tty_event(void* udata, char c);
void handle_sysmem_tty_event(void* udata, char c);

void handle_animations(iris::instance* iris);

void push_info(iris::instance* iris, std::string text);

void add_recent(iris::instance* iris, std::string file, int type);
int open_file(iris::instance* iris, std::string file);

}

================================================
FILE: frontend/notifications.cpp
================================================
#include "iris.hpp"

#include "res/IconsMaterialSymbols.h"

namespace iris {

enum {
    STATE_IDLE,
    STATE_MOVING = 1,
    STATE_FADING = 2
};

enum {
    TYPE_INFO = 0,
};

static inline int seconds_to_frames(float s) {
    return s * 60.0f;
}

float ease_in_out(float t) {
    if (t <= 0.5f) return 2.0f * t * t;

    t -= 0.5f;

    return 2.0f * t * (1.0f - t) + 0.5f;
}

void handle_move(iris::notification* notif) {
    float f = (float)notif->move.frames_remaining / (float)notif->move.frames;

    f = ease_in_out(f);

    float fs = f;
    float ft = 1.0 - f;

    notif->move.x = notif->move.source_x * fs + notif->move.target_x * ft;
    notif->move.y = notif->move.source_y * fs + notif->move.target_y * ft;

    if (!notif->move.frames_remaining) {
        notif->state &= ~STATE_MOVING;
    } else {
        notif->move.frames_remaining--;
    }
}

void handle_fade(iris::notification* notif) {
    float f = (float)notif->fade.frames_remaining / (float)notif->fade.frames;

    f = ease_in_out(f);

    float fs = f;
    float ft = 1.0 - f;

    notif->fade.alpha = notif->fade.source_alpha * fs + notif->fade.target_alpha * ft;

    if (!notif->fade.frames_remaining) {
        notif->state &= ~STATE_FADING;
    } else {
        notif->fade.frames_remaining--;
    }
}

void render_notification(iris::instance* iris, iris::notification* notif) {
    using namespace ImGui;

    ImGuiStyle& style = ImGui::GetStyle();

    ImVec4 bg = style.Colors[ImGuiCol_MenuBarBg];
    ImVec4 tc = style.Colors[ImGuiCol_Text];
    ImVec4 td = style.Colors[ImGuiCol_TextDisabled];

    uint32_t alpha = (notif->fade.alpha) << 24;

    uint32_t bg_col =
        ((uint32_t)(bg.x * 255.0) << 0 ) |
        ((uint32_t)(bg.y * 255.0) << 8 ) |
        ((uint32_t)(bg.z * 255.0) << 16) |
        alpha;

    uint32_t text_col =
        ((uint32_t)(tc.x * 255.0) << 0 ) |
        ((uint32_t)(tc.y * 255.0) << 8 ) |
        ((uint32_t)(tc.z * 255.0) << 16) |
        alpha;

    uint32_t icon_col = 0x799fa7 | alpha;

    uint32_t bar_col =
        ((uint32_t)(td.x * 255.0) << 0 ) |
        ((uint32_t)(td.y * 255.0) << 8 ) |
        ((uint32_t)(td.z * 255.0) << 16) |
        alpha;

    float x = notif->move.x;
    float y = notif->move.y;
    float width = notif->width;
    float height = notif->height;

    GetForegroundDrawList()->AddRectFilled(
        ImVec2(x, y),
        ImVec2(x + width, y + height),
        bg_col, 10.0, ImDrawFlags_RoundCornersAll
    );

    GetForegroundDrawList()->AddText(
        ImVec2(x + 10, y + (height / 2) - (notif->text_height / 2)), icon_col, ICON_MS_INFO
    );

    GetForegroundDrawList()->AddText(
        ImVec2(x + 35, y + (height / 2) - (notif->text_height / 2)), text_col, notif->text.c_str()
    );

    int progress_width = width * (1.0 - ((float)notif->frames_remaining / (float)notif->frames));

    GetForegroundDrawList()->AddRectFilled(
        ImVec2(x, y + height - 2),
        ImVec2(x + progress_width, y + height),
        bar_col, 10.0, ImDrawFlags_RoundCornersBottom
    );
}

void remove_notification(iris::instance* iris, int i) {
    iris::notification& n = iris->notifications.at(i);

    for (unsigned int j = i + 1; j < iris->notifications.size(); j++) {
        iris::notification& n1 = iris->notifications.at(j);

        int target_x = n1.state & STATE_MOVING ? n1.move.target_x : n1.move.x;
        int target_y = n1.state & STATE_MOVING ? n1.move.target_y : n1.move.y;

        n1.move.source_x = n1.move.x;
        n1.move.source_y = n1.move.y;
        n1.move.target_x = target_x;
        n1.move.target_y = target_y + n.height + 10;
        n1.move.frames = seconds_to_frames(0.25);
        n1.move.frames_remaining = n.move.frames;
        n1.state |= STATE_MOVING;
    }

    iris->notifications.erase(std::begin(iris->notifications) + i);
}

void handle_animations(iris::instance* iris) {
    for (unsigned int i = 0; i < iris->notifications.size(); i++) {
        iris::notification& n = iris->notifications.at(i);

        render_notification(iris, &n);

        if (n.frames_remaining) {
            n.frames_remaining--;

            if (!n.frames_remaining) {
                n.fade.source_alpha = n.fade.alpha;
                n.fade.target_alpha = 0;
                n.fade.frames = seconds_to_frames(0.25);
                n.fade.frames_remaining = n.fade.frames;
                n.state |= STATE_FADING;
                n.end = true;
            }
        }

        if (n.state == STATE_IDLE) {
            if (n.end) {
                remove_notification(iris, i);
            }

            continue;
        }

        if (n.state & STATE_MOVING) handle_move(&n);
        if (n.state & STATE_FADING) handle_fade(&n);
    }
}

void push_notification(iris::instance* iris, iris::notification notif) {
    for (iris::notification& n : iris->notifications) {
        int target_x = n.state & STATE_MOVING ? n.move.target_x : n.move.x;
        int target_y = n.state & STATE_MOVING ? n.move.target_y : n.move.y;

        n.move.source_x = n.move.x;
        n.move.source_y = n.move.y;
        n.move.target_x = target_x;
        n.move.target_y = target_y - notif.height - 10;
        n.move.frames = seconds_to_frames(0.25);
        n.move.frames_remaining = n.move.frames;
        n.state |= STATE_MOVING;
    }

    iris->notifications.push_front(notif);
}

void push_info(iris::instance* iris, std::string text) {
    using namespace ImGui;

    iris::notification notif;

    int window_width, window_height;
    int statusbar_offset = iris->show_status_bar ? iris->menubar_height : 0;

    SDL_GetWindowSizeInPixels(iris->window, &window_width, &window_height);

    ImVec2 ts = CalcTextSize(text.c_str());

    notif.text = text;
    notif.text_width = ts.x;
    notif.text_height = ts.y;
    notif.width = notif.text_width + 50;
    notif.height = notif.text_height + 25;
    notif.frames = seconds_to_frames(5.0);
    notif.frames_remaining = notif.frames;
    notif.state = STATE_MOVING | STATE_FADING;
    notif.move.source_x = window_width + 5;
    notif.move.source_y = window_height - notif.height - 10 - statusbar_offset;
    notif.move.target_x = window_width - notif.width - 10;
    notif.move.target_y = notif.move.source_y;
    notif.move.frames = seconds_to_frames(0.25);
    notif.move.frames_remaining = notif.move.frames;
    notif.fade.source_alpha = 0;
    notif.fade.target_alpha = 255;
    notif.fade.frames = seconds_to_frames(0.25);
    notif.fade.frames_remaining = notif.fade.frames;
    notif.type = TYPE_INFO;
    notif.end = false;

    push_notification(iris, notif);
}

}

================================================
FILE: frontend/platform/stub.cpp
================================================
#include "iris.hpp"

// Note: This is a stub implementation for platforms that
//       do not need special initialization

namespace iris::platform {

bool init(iris::instance* iris) {
    return true;
}

bool apply_settings(iris::instance* iris) {
    return true;
}

void destroy(iris::instance* iris) {}

}

================================================
FILE: frontend/platform/windows.cpp
================================================
#include "iris.hpp"
#include "imgui.h"

#include <dwmapi.h>

namespace iris::platform {

bool init(iris::instance* iris) {
    apply_settings(iris);

    return true;
}

bool apply_settings(iris::instance* iris) {
    SDL_PropertiesID props = SDL_GetWindowProperties(iris->window);

    HWND hwnd = (HWND)SDL_GetPointerProperty(props, SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL);

    COLORREF border_color = iris->windows_enable_borders ? DWMWA_COLOR_DEFAULT : DWMWA_COLOR_NONE;

    if (!SUCCEEDED(DwmSetWindowAttribute(
        hwnd,
        DWMWINDOWATTRIBUTE::DWMWA_BORDER_COLOR,
        &border_color,
        sizeof(border_color)
    ))) {
        return false;
    }

    if (iris->windows_titlebar_style == IRIS_TITLEBAR_DEFAULT) {
        BOOL dark_mode = iris->windows_dark_mode;

        if (!SUCCEEDED(DwmSetWindowAttribute(
            hwnd,
            DWMWINDOWATTRIBUTE::DWMWA_USE_IMMERSIVE_DARK_MODE,
            &dark_mode,
            sizeof(BOOL)
        ))) {
            printf("iris: Failed to set immersive dark mode\n");

            return false;
        }
    }

    bool result = false;

    switch (iris->windows_titlebar_style) {
        case IRIS_TITLEBAR_DEFAULT: {
            COLORREF color = DWMWA_COLOR_DEFAULT;

            result = SUCCEEDED(DwmSetWindowAttribute(
                hwnd,
                DWMWINDOWATTRIBUTE::DWMWA_CAPTION_COLOR,
                &color,
                sizeof(color)
            ));
        } break;

        case IRIS_TITLEBAR_SEAMLESS: {
            COLORREF color = 0;

            ImVec4 menubar_color = ImGui::GetStyleColorVec4(ImGuiCol_MenuBarBg);

            color = (uint32_t)(menubar_color.x * 255) |
                    ((uint32_t)(menubar_color.y * 255) << 8) |
                    ((uint32_t)(menubar_color.z * 255) << 16);

            result = SUCCEEDED(DwmSetWindowAttribute(
                hwnd,
                DWMWINDOWATTRIBUTE::DWMWA_CAPTION_COLOR,
                &color,
                sizeof(color)
            ));
        } break;
    }

    // ShowWindow(hwnd, SW_MINIMIZE);
    // ShowWindow(hwnd, SW_RESTORE);

    return result;
}

void destroy(iris::instance* iris) {}

}

================================================
FILE: frontend/render.cpp
================================================
#include <cmath>

#include "iris.hpp"

#define RENDER_MAX_SHADER_PASSES 16

// INCBIN stuff
#define INCBIN_PREFIX g_
#define INCBIN_STYLE INCBIN_STYLE_SNAKE

#include "incbin.h"

INCBIN(default_vertex_shader, "../shaders/shader.spv");

namespace iris::render {

static int frame = 0;
static constexpr uint32_t DESCRIPTOR_SET_RING_SIZE = 8;

bool create_image(iris::instance* iris, uint32_t width, uint32_t height, VkFormat format, VkImageUsageFlags usage, VkImage& image, VkImageView& view, VkDeviceMemory& memory) {
    VkImageCreateInfo image_info = {};
    image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
    image_info.imageType = VK_IMAGE_TYPE_2D;
    image_info.extent.width = width;
    image_info.extent.height = height;
    image_info.extent.depth = 1;
    image_info.mipLevels = 1;
    image_info.arrayLayers = 1;
    image_info.format = format;
    image_info.tiling = VK_IMAGE_TILING_OPTIMAL;
    image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
    image_info.usage = usage;
    image_info.samples = VK_SAMPLE_COUNT_1_BIT;
    image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;

    if (vkCreateImage(iris->device, &image_info, nullptr, &image) != VK_SUCCESS) {
        return false;
    }

    VkMemoryRequirements memory_requirements;
    vkGetImageMemoryRequirements(iris->device, image, &memory_requirements);

    VkMemoryAllocateInfo alloc_info = {};
    alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
    alloc_info.allocationSize = memory_requirements.size;

    VkPhysicalDeviceMemoryProperties memory_properties;
    vkGetPhysicalDeviceMemoryProperties(iris->physical_device, &memory_properties);

    for (uint32_t i = 0; i < memory_properties.memoryTypeCount; i++) {
        if ((memory_requirements.memoryTypeBits & (1 << i)) &&
            (memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) == VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) {
            alloc_info.memoryTypeIndex = i;
            break;
        }
    }

    if (vkAllocateMemory(iris->device, &alloc_info, nullptr, &memory) != VK_SUCCESS) {
        fprintf(stderr, "render: Failed to allocate image memory\n");

        vkDestroyImage(iris->device, image, nullptr);

        return false;
    }

    vkBindImageMemory(iris->device, image, memory, 0);

    VkImageViewCreateInfo image_view_info = {};
    image_view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
    image_view_info.image = image;
    image_view_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
    image_view_info.format = format;
    image_view_info.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
    image_view_info.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
    image_view_info.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
    image_view_info.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
    image_view_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
    image_view_info.subresourceRange.baseMipLevel = 0;
    image_view_info.subresourceRange.levelCount = 1;
    image_view_info.subresourceRange.baseArrayLayer = 0;
    image_view_info.subresourceRange.layerCount = 1;

    if (vkCreateImageView(iris->device, &image_view_info, nullptr, &view) != VK_SUCCESS) {
        return false;
    }

    return true;
}

bool rebuild_framebuffers(iris::instance* iris) {
    if (!shaders::count(iris))
        return true;

    vulkan::wait_idle(iris);

    for (auto& pass_framebuffers : iris->shader_pass_framebuffers) {
        for (VkFramebuffer& framebuffer : pass_framebuffers) {
            if (framebuffer) {
                vkDestroyFramebuffer(iris->device, framebuffer, nullptr);
                framebuffer = VK_NULL_HANDLE;
            }
        }
    }

    iris->shader_pass_framebuffers.clear();

    for (auto& fb : iris->shader_framebuffers) {
        if (fb.view) vkDestroyImageView(iris->device, fb.view, nullptr);
        if (fb.image) vkDestroyImage(iris->device, fb.image, nullptr);
        if (fb.memory) vkFreeMemory(iris->device, fb.memory, nullptr);

        bool res = create_image(iris,
            iris->image.width,
            iris->image.height,
            iris->image.format,
            VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
            fb.image,
            fb.view,
            fb.memory
        );

        if (!res) {
            fprintf(stderr, "render: Failed to create shader pass framebuffer image\n");

            return false;
        }
    }

    const size_t pass_count = shaders::count(iris);

    iris->shader_pass_framebuffers.resize(pass_count);

    for (size_t pass_index = 0; pass_index < pass_count; pass_index++) {
        auto* pass = shaders::at(iris, (int)pass_index);

        if (!pass || !pass->ready()) {
            iris->shader_pass_framebuffers[pass_index] = { VK_NULL_HANDLE, VK_NULL_HANDLE };

            continue;
        }

        for (int framebuffer_index = 0; framebuffer_index < 2; framebuffer_index++) {
            VkFramebufferCreateInfo framebuffer_info = {};
            framebuffer_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
            framebuffer_info.renderPass = pass->get_render_pass();
            framebuffer_info.attachmentCount = 1;
            framebuffer_info.pAttachments = &iris->shader_framebuffers[framebuffer_index].view;
            framebuffer_info.width = iris->image.width;
            framebuffer_info.height = iris->image.height;
            framebuffer_info.layers = 1;

            if (vkCreateFramebuffer(iris->device, &framebuffer_info, nullptr, &iris->shader_pass_framebuffers[pass_index][framebuffer_index]) != VK_SUCCESS) {
                fprintf(stderr, "render: Failed to create shader pass framebuffer\n");

                return false;
            }
        }
    }

    return true;
}

bool init(iris::instance* iris) {
    // Initialize our renderer
    iris->renderer = renderer_create();

    renderer_create_info info = {};

    info.backend = iris->renderer_backend;
    info.gif = iris->ps2->gif;
    info.gs = iris->ps2->gs;
    info.instance = iris->instance;
    info.device = iris->device;
    info.physical_device = iris->physical_device;
    info.instance_create_info = iris->instance_create_info;
    info.device_create_info = iris->device_create_info;

    switch (info.backend) {
        case RENDERER_BACKEND_HARDWARE: {
            info.config = &iris->hardware_backend_config;
        } break;
    }

    if (!renderer_init(iris->renderer, info)) {
        fprintf(stderr, "render: Failed to initialize renderer backend\n");

        return false;
    }

    VkSamplerCreateInfo nearest_sampler_info = {};
    nearest_sampler_info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
    nearest_sampler_info.magFilter = VK_FILTER_NEAREST;
    nearest_sampler_info.minFilter = VK_FILTER_NEAREST;
    nearest_sampler_info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
    nearest_sampler_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
    nearest_sampler_info.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
    nearest_sampler_info.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
    nearest_sampler_info.minLod = -1000;
    nearest_sampler_info.maxLod = 1000;
    nearest_sampler_info.maxAnisotropy = 1.0f;

    if (vkCreateSampler(iris->device, &nearest_sampler_info, VK_NULL_HANDLE, &iris->sampler[0]) != VK_SUCCESS) {
        fprintf(stderr, "render: Failed to create nearest texture sampler\n");

        return false;
    }

    VkSamplerCreateInfo bilinear_sampler_info = {};
    bilinear_sampler_info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
    bilinear_sampler_info.magFilter = VK_FILTER_LINEAR;
    bilinear_sampler_info.minFilter = VK_FILTER_LINEAR;
    bilinear_sampler_info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
    bilinear_sampler_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
    bilinear_sampler_info.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
    bilinear_sampler_info.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
    bilinear_sampler_info.minLod = -1000;
    bilinear_sampler_info.maxLod = 1000;
    bilinear_sampler_info.maxAnisotropy = 1.0f;

    if (vkCreateSampler(iris->device, &bilinear_sampler_info, VK_NULL_HANDLE, &iris->sampler[1]) != VK_SUCCESS) {
        fprintf(stderr, "render: Failed to create bilinear texture sampler\n");

        return false;
    }

    if (iris->cubic_supported) {
        VkSamplerCreateInfo cubic_sampler_info = {};
        cubic_sampler_info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
        cubic_sampler_info.magFilter = VK_FILTER_LINEAR;
        cubic_sampler_info.minFilter = VK_FILTER_LINEAR;
        cubic_sampler_info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
        cubic_sampler_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
        cubic_sampler_info.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
        cubic_sampler_info.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
        cubic_sampler_info.minLod = -1000;
        cubic_sampler_info.maxLod = 1000;
        cubic_sampler_info.maxAnisotropy = 1.0f;

        if (vkCreateSampler(iris->device, &cubic_sampler_info, VK_NULL_HANDLE, &iris->sampler[2]) != VK_SUCCESS) {
            fprintf(stderr, "render: Failed to create cubic texture sampler\n");

            return false;
        }
    }

    VkShaderModuleCreateInfo vert_shader_create_info = {};
    vert_shader_create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
    vert_shader_create_info.pCode = (const uint32_t*)g_default_vertex_shader_data;
    vert_shader_create_info.codeSize = g_default_vertex_shader_size;

    if (vkCreateShaderModule(iris->device, &vert_shader_create_info, nullptr, &iris->default_vert_shader) != VK_SUCCESS) {
        fprintf(stderr, "render: Failed to create default vertex shader module\n");

        return false;
    }

    // Create descriptor set
    VkDescriptorSetLayoutBinding sampler_layout_binding = {};
    sampler_layout_binding.binding = 0;
    sampler_layout_binding.descriptorCount = 1;
    sampler_layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
    sampler_layout_binding.pImmutableSamplers = nullptr;
    sampler_layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;

    VkDescriptorSetLayoutCreateInfo layout_info = {};
    layout_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
    layout_info.bindingCount = 1;
    layout_info.pBindings = &sampler_layout_binding;

    if (vkCreateDescriptorSetLayout(iris->device, &layout_info, nullptr, &iris->shader_descriptor_set_layout) != VK_SUCCESS) {
        fprintf(stderr, "render: Failed to create descriptor set layout\n");

        return false;
    }

    const uint32_t shader_descriptor_set_count = DESCRIPTOR_SET_RING_SIZE * RENDER_MAX_SHADER_PASSES;

    std::vector <VkDescriptorSetLayout> shader_layouts(shader_descriptor_set_count, iris->shader_descriptor_set_layout);

    iris->shader_descriptor_sets.resize(shader_descriptor_set_count, VK_NULL_HANDLE);

    VkDescriptorSetAllocateInfo alloc_info = {};
    alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
    alloc_info.descriptorPool = iris->descriptor_pool;
    alloc_info.descriptorSetCount = shader_descriptor_set_count;
    alloc_info.pSetLayouts = shader_layouts.data();

    if (vkAllocateDescriptorSets(iris->device, &alloc_info, iris->shader_descriptor_sets.data()) != VK_SUCCESS) {
        fprintf(stderr, "render: Failed to allocate descriptor sets\n");

        return false;
    }

    iris->shader_descriptor_set = iris->shader_descriptor_sets[0];

    return true;
}

static inline VkDescriptorSet get_frame_descriptor_set(iris::instance* iris) {
    if (!iris->descriptor_sets.size()) {
        return iris->descriptor_set;
    }

    const uint32_t frame_index = iris->main_window_data.FrameIndex;

    return iris->descriptor_sets[frame_index % iris->descriptor_sets.size()];
}

static inline VkDescriptorSet get_frame_shader_descriptor_set(iris::instance* iris, uint32_t pass_index) {
    if (!iris->shader_descriptor_sets.size()) {
        return iris->shader_descriptor_set;
    }

    const uint32_t frame_index = iris->main_window_data.FrameIndex % DESCRIPTOR_SET_RING_SIZE;
    const uint32_t slot = (frame_index * RENDER_MAX_SHADER_PASSES) + (pass_index % RENDER_MAX_SHADER_PASSES);

    return iris->shader_descriptor_sets[slot % iris->shader_descriptor_sets.size()];
}

static inline void update_vertex_buffer(iris::instance* iris, VkCommandBuffer command_buffer) {
    SDL_Rect size, rect, display;

    const int normalized_angle = ((iris->angle % 360) + 360) % 360;
    const bool swap_axes = normalized_angle == 90 || normalized_angle == 270;

    float aspect_ratio = 4.0 / 3.0;

    if (swap_axes) {
        aspect_ratio = 3.0 / 4.0;
    }

    float aspect_ratio_inv = 1.0f / aspect_ratio;

    SDL_GetWindowSize(iris->window, &size.w, &size.h);

    display.w = size.w;
    display.h = size.h;
    display.x = 0;
    display.y = 0;
    
    if (!iris->fullscreen) {
        display.h -= iris->menubar_height;
        display.y += iris->menubar_height;

        if (iris->show_status_bar) {
            display.h -= iris->menubar_height;
        }
    }

    rect.w = iris->image.width;
    rect.h = iris->image.height;

    float scale = iris->integer_scaling ? floorf(iris->scale) : iris->scale;

    switch (iris->aspect_mode) {
        case RENDER_ASPECT_NATIVE: {
            rect.w *= scale;
            rect.h *= scale;
        } break;

        case RENDER_ASPECT_4_3: {
            rect.w *= scale;
            rect.h = (float)rect.w * (3.0f / 4.0f);
        } break;

        case RENDER_ASPECT_16_9: {
            rect.w *= scale;
            rect.h = (float)rect.w * (9.0f / 16.0f);
        } break;

        case RENDER_ASPECT_5_4: {
            rect.w *= scale;
            rect.h = (float)rect.w * (4.0f / 5.0f);
        } break;

        case RENDER_ASPECT_STRETCH: {
            rect.w = display.w;
            rect.h = display.h;
        } break;

        case RENDER_ASPECT_AUTO:
        case RENDER_ASPECT_STRETCH_KEEP: {
            if (swap_axes) {
                std::swap(rect.w, rect.h);
            }

            rect.h = display.h;
            rect.w = (float)rect.h * aspect_ratio;

            // Scale vertically if the rect ends up being bigger
            // than our display area
            if (rect.w > display.w) {
                rect.w = display.w;
                rect.h = (float)rect.w * aspect_ratio_inv;
            }
        } break;
    }

    if (iris->aspect_mode != RENDER_ASPECT_AUTO && iris->aspect_mode != RENDER_ASPECT_STRETCH_KEEP) {
        if (swap_axes) {
            std::swap(rect.w, rect.h);
        }
    }

    iris->render_width = rect.w;
    iris->render_height = rect.h;

    rect.x = display.x + ((display.w / 2) - (rect.w / 2));
    rect.y = display.y + ((display.h / 2) - (rect.h / 2));

    float x0 = (rect.x / ((float)size.w / 2.0f)) - 1.0f;
    float y0 = (rect.y / ((float)size.h / 2.0f)) - 1.0f;
    float x1 = ((rect.x + rect.w) / ((float)size.w / 2.0f)) - 1.0f;
    float y1 = ((rect.y + rect.h) / ((float)size.h / 2.0f)) - 1.0f;

    float uvs[4][2] = {
        {0.0f, 1.0f},
        {1.0f, 1.0f},
        {1.0f, 0.0f},
        {0.0f, 0.0f}
    };

    for (int i = 0; i < 4; i++) {
        float u = uvs[i][0];
        float v = uvs[i][1];

        if (iris->flip_x) {
            u = 1.0f - u;
        }

        if (iris->flip_y) {
            v = 1.0f - v;
        }

        switch (normalized_angle) {
            case 90: {
                // Rotate clockwise in UV space.
                const float prev_u = u;
                u = v;
                v = 1.0f - prev_u;
            } break;

            case 180: {
                u = 1.0f - u;
                v = 1.0f - v;
            } break;

            case 270: {
                // Rotate counter-clockwise in UV space.
                const float prev_u = u;
                u = 1.0f - v;
                v = prev_u;
            } break;
        }

        uvs[i][0] = u;
        uvs[i][1] = v;
    }

    iris->vertices[0] = vertex{ { x0, y0 }, {uvs[0][0], uvs[0][1]} };
    iris->vertices[1] = vertex{ { x1, y0 }, {uvs[1][0], uvs[1][1]} };
    iris->vertices[2] = vertex{ { x1, y1 }, {uvs[2][0], uvs[2][1]} };
    iris->vertices[3] = vertex{ { x0, y1 }, {uvs[3][0], uvs[3][1]} };

    void* ptr;

    vkMapMemory(iris->device, iris->vertex_staging_buffer_memory, 0, iris->vertex_buffer_size, 0, &ptr);
    memcpy(ptr, iris->vertices.data(), (size_t)iris->vertex_buffer_size);
    vkUnmapMemory(iris->device, iris->vertex_staging_buffer_memory);

    static VkBufferCopy region = {};
    region.srcOffset = 0;
    region
Download .txt
gitextract_3bqhuqc4/

├── .github/
│   ├── FUNDING.yml
│   └── workflows/
│       ├── linux.yml
│       ├── macos.yml
│       ├── release.yml
│       └── windows.yml
├── .gitignore
├── .gitmodules
├── AppImage.cmake
├── CMakeLists.txt
├── Info.plist
├── LICENSE
├── MoltenVK_icd.json
├── README.md
├── compat.txt
├── frontend/
│   ├── arcade.hpp
│   ├── audio.cpp
│   ├── config.hpp
│   ├── elf.cpp
│   ├── emu.cpp
│   ├── handlers.cpp
│   ├── imgui.cpp
│   ├── input.cpp
│   ├── iris.cpp
│   ├── iris.hpp
│   ├── notifications.cpp
│   ├── platform/
│   │   ├── stub.cpp
│   │   └── windows.cpp
│   ├── render.cpp
│   ├── res/
│   │   └── IconsMaterialSymbols.h
│   ├── settings.cpp
│   ├── shaders.cpp
│   ├── ui/
│   │   ├── about.cpp
│   │   ├── bios_setting.cpp
│   │   ├── breakpoints.cpp
│   │   ├── control.cpp
│   │   ├── dma.cpp
│   │   ├── gs.cpp
│   │   ├── intc.cpp
│   │   ├── logs.cpp
│   │   ├── memory.cpp
│   │   ├── memory_card_tool.cpp
│   │   ├── memory_search.cpp
│   │   ├── memory_viewer.h
│   │   ├── menubar.cpp
│   │   ├── modules.cpp
│   │   ├── overlay.cpp
│   │   ├── pad.cpp
│   │   ├── settings.cpp
│   │   ├── spu2.cpp
│   │   ├── state.cpp
│   │   ├── statusbar.cpp
│   │   ├── symbols.cpp
│   │   ├── threads.cpp
│   │   └── vu_disassembly.cpp
│   └── vulkan.cpp
├── main.cpp
├── res/
│   ├── iris.icns
│   ├── iris.rc
│   └── iris.res
├── shaders/
│   ├── curvature.frag
│   ├── curvature.spv
│   ├── decoder.frag
│   ├── decoder.spv
│   ├── default.frag
│   ├── default.vert
│   ├── encoder.frag
│   ├── encoder.spv
│   ├── fragment.spv
│   ├── noise.frag
│   ├── noise.spv
│   ├── scanlines.frag
│   ├── scanlines.spv
│   ├── shader.spv
│   ├── shader.vert
│   └── vertex.spv
└── src/
    ├── dev/
    │   ├── ds.c
    │   ├── ds.h
    │   ├── guncon.c
    │   ├── guncon.h
    │   ├── mcd.c
    │   ├── mcd.h
    │   ├── mtap.c
    │   ├── mtap.h
    │   ├── ps1_mcd.c
    │   └── ps1_mcd.h
    ├── ee/
    │   ├── bus.c
    │   ├── bus.h
    │   ├── bus_decl.h
    │   ├── dmac.c
    │   ├── dmac.h
    │   ├── ee.h
    │   ├── ee_cached.cpp
    │   ├── ee_def.hpp
    │   ├── ee_dis.c
    │   ├── ee_dis.h
    │   ├── ee_uncached.c
    │   ├── ee_uncached.h
    │   ├── gif.c
    │   ├── gif.h
    │   ├── intc.c
    │   ├── intc.h
    │   ├── syscall.h
    │   ├── timers.c
    │   ├── timers.h
    │   ├── vif.c
    │   ├── vif.h
    │   ├── vu.h
    │   ├── vu_cached.cpp
    │   ├── vu_def.hpp
    │   ├── vu_dis.c
    │   ├── vu_dis.h
    │   └── vu_uncached.c
    ├── elf.h
    ├── gs/
    │   ├── gs.c
    │   ├── gs.h
    │   └── renderer/
    │       ├── config.hpp
    │       ├── hardware.cpp
    │       ├── hardware.hpp
    │       ├── null.cpp
    │       ├── null.hpp
    │       ├── renderer.cpp
    │       ├── renderer.hpp
    │       ├── software_thread.cpp
    │       └── software_thread.hpp
    ├── iop/
    │   ├── bus.c
    │   ├── bus.h
    │   ├── bus_decl.h
    │   ├── cdvd.c
    │   ├── cdvd.h
    │   ├── disc/
    │   │   ├── bin.c
    │   │   ├── bin.h
    │   │   ├── chd.c
    │   │   ├── chd.h
    │   │   ├── ciso.c
    │   │   ├── ciso.h
    │   │   ├── cue.c
    │   │   ├── cue.h
    │   │   ├── iso.c
    │   │   └── iso.h
    │   ├── disc.c
    │   ├── disc.h
    │   ├── dma.c
    │   ├── dma.h
    │   ├── fw.c
    │   ├── fw.h
    │   ├── hle/
    │   │   ├── ioman.cpp
    │   │   ├── ioman.h
    │   │   ├── loadcore.c
    │   │   ├── loadcore.h
    │   │   ├── sysmem.c
    │   │   └── sysmem.h
    │   ├── intc.c
    │   ├── intc.h
    │   ├── iop.c
    │   ├── iop.h
    │   ├── iop_dis.c
    │   ├── iop_dis.h
    │   ├── iop_export.c
    │   ├── iop_export.h
    │   ├── rpc.c
    │   ├── rpc.h
    │   ├── sio2.c
    │   ├── sio2.h
    │   ├── spu2.c
    │   ├── spu2.h
    │   ├── timers.c
    │   ├── timers.h
    │   ├── usb.c
    │   └── usb.h
    ├── ipu/
    │   ├── chromtable.cpp
    │   ├── chromtable.hpp
    │   ├── codedblockpattern.cpp
    │   ├── codedblockpattern.hpp
    │   ├── dct_coeff.cpp
    │   ├── dct_coeff.hpp
    │   ├── dct_coeff_table0.cpp
    │   ├── dct_coeff_table0.hpp
    │   ├── dct_coeff_table1.cpp
    │   ├── dct_coeff_table1.hpp
    │   ├── ipu.cpp
    │   ├── ipu.h
    │   ├── ipu.hpp
    │   ├── ipu_fifo.cpp
    │   ├── ipu_fifo.hpp
    │   ├── lumtable.cpp
    │   ├── lumtable.hpp
    │   ├── mac_addr_inc.cpp
    │   ├── mac_addr_inc.hpp
    │   ├── mac_b_pic.cpp
    │   ├── mac_b_pic.hpp
    │   ├── mac_i_pic.cpp
    │   ├── mac_i_pic.hpp
    │   ├── mac_p_pic.cpp
    │   ├── mac_p_pic.hpp
    │   ├── motioncode.cpp
    │   ├── motioncode.hpp
    │   ├── vlc_table.cpp
    │   └── vlc_table.hpp
    ├── list.c
    ├── list.h
    ├── md5.c
    ├── md5.h
    ├── ps2.c
    ├── ps2.h
    ├── ps2_elf.c
    ├── ps2_elf.h
    ├── ps2_iso9660.c
    ├── ps2_iso9660.h
    ├── queue.c
    ├── queue.h
    ├── rom.c
    ├── rom.h
    ├── s14x/
    │   ├── aiboard.c
    │   ├── aiboard.h
    │   ├── ioboard.c
    │   ├── ioboard.h
    │   ├── link.c
    │   ├── link.h
    │   ├── nand.c
    │   ├── nand.h
    │   ├── sram.c
    │   ├── sram.h
    │   ├── syscon.c
    │   └── syscon.h
    ├── scheduler.c
    ├── scheduler.h
    ├── shared/
    │   ├── bios.c
    │   ├── bios.h
    │   ├── dev9.c
    │   ├── dev9.h
    │   ├── ram.c
    │   ├── ram.h
    │   ├── sbus.c
    │   ├── sbus.h
    │   ├── sif.c
    │   ├── sif.h
    │   ├── speed/
    │   │   ├── ata.c
    │   │   ├── ata.h
    │   │   ├── eeprom.c
    │   │   ├── eeprom.h
    │   │   ├── flash.c
    │   │   └── flash.h
    │   ├── speed.c
    │   └── speed.h
    └── u128.h
Download .txt
Showing preview only (479K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (4661 symbols across 194 files)

FILE: frontend/audio.cpp
  type iris::audio (line 6) | namespace iris::audio {
    function update (line 8) | void update(void* userdata, SDL_AudioStream* stream, int additional_am...
    function init (line 28) | bool init(iris::instance* iris) {
    function close (line 49) | void close(iris::instance* iris) {
    function mute (line 60) | bool mute(iris::instance* iris) {
    function unmute (line 68) | void unmute(iris::instance* iris) {

FILE: frontend/elf.cpp
  type iris::elf (line 13) | namespace iris::elf {
    function load_symbols_from_memory (line 15) | void load_symbols_from_memory(iris::instance* iris, char* buf) {
    function load_symbols_from_disc (line 98) | bool load_symbols_from_disc(iris::instance* iris) {
    function load_symbols_from_file (line 114) | bool load_symbols_from_file(iris::instance* iris, std::string path) {

FILE: frontend/emu.cpp
  type iris::emu (line 7) | namespace iris::emu {
    function init (line 9) | bool init(iris::instance* iris) {
    function destroy (line 23) | void destroy(iris::instance* iris) {
    function query_arcade_value (line 36) | std::optional<T> query_arcade_value(std::string arcade_name, std::stri...
    function load_arcade (line 66) | bool load_arcade(iris::instance* iris, std::string path) {
    function attach_memory_card (line 151) | int attach_memory_card(iris::instance* iris, int slot, const char* pat...
    function detach_memory_card (line 189) | void detach_memory_card(iris::instance* iris, int slot) {
    function get_system_count (line 233) | int get_system_count(iris::instance* iris) {

FILE: frontend/handlers.cpp
  type iris (line 3) | namespace iris {
    function handle_ee_tty_event (line 5) | void handle_ee_tty_event(void* udata, char c) {
    function handle_iop_tty_event (line 18) | void handle_iop_tty_event(void* udata, char c) {
    function handle_sysmem_tty_event (line 31) | void handle_sysmem_tty_event(void* udata, char c) {

FILE: frontend/imgui.cpp
  type iris::imgui (line 39) | namespace iris::imgui {
    function setup_vulkan_window (line 45) | static bool setup_vulkan_window(iris::instance* iris, ImGui_ImplVulkan...
    function set_vsync (line 125) | void set_vsync(iris::instance* iris, bool vsync) {
    function setup_fonts (line 146) | bool setup_fonts(iris::instance* iris, ImGuiIO& io) {
    function set_theme (line 183) | void set_theme(iris::instance* iris, int theme, bool set_bg_color) {
    function set_codeview_scheme (line 457) | void set_codeview_scheme(iris::instance* iris, int scheme) {
    function VkShaderModule (line 538) | VkShaderModule create_shader(iris::instance* iris, uint32_t* code, siz...
    function VkPipeline (line 553) | VkPipeline create_pipeline(iris::instance* iris, VkShaderModule vert_s...
    function init (line 691) | bool init(iris::instance* iris) {
    function cleanup (line 855) | void cleanup(iris::instance* iris) {
    function render_frame (line 874) | bool render_frame(iris::instance* iris, ImDrawData* draw_data) {
    function BeginEx (line 1016) | bool BeginEx(const char* name, bool* p_open, ImGuiWindowFlags flags) {

FILE: frontend/input.cpp
  type iris (line 16) | namespace iris {
  type iris::input (line 49) | namespace iris::input {
    function load_db_default (line 51) | void load_db_default(iris::instance* iris) {
    function load_db_from_file (line 57) | bool load_db_from_file(iris::instance* iris, const char* path) {
    function init_default_mapping (line 67) | void init_default_mapping(iris::instance* iris, int id) {
    function init (line 140) | bool init(iris::instance* iris) {
    function input_action (line 247) | input_action* get_input_action(iris::instance* iris, int slot, uint64_...
    function change_button (line 254) | static inline void change_button(iris::instance* iris, int slot, float...
    function change_s14x_switch (line 264) | static inline void change_s14x_switch(iris::instance* iris, float valu...
    function execute_action (line 275) | void execute_action(iris::instance* iris, input_action action, int slo...
    function input_event (line 317) | input_event sdl_event_to_input_event(SDL_Event* event) {
    function get_default_screenshot_filename (line 356) | std::string get_default_screenshot_filename(iris::instance* iris) {
    function get_screenshot_jpg_quality (line 383) | int get_screenshot_jpg_quality(iris::instance* iris) {
    function save_screenshot (line 396) | bool save_screenshot(iris::instance* iris, std::string path) {
    function handle_keydown_event (line 512) | void handle_keydown_event(iris::instance* iris, SDL_Event* event) {
    function handle_keyup_event (line 545) | void handle_keyup_event(iris::instance* iris, SDL_Event* event) {

FILE: frontend/iris.cpp
  type iris (line 21) | namespace iris {
    function add_recent (line 23) | void add_recent(iris::instance* iris, std::string file, int type) {
    function open_file (line 41) | int open_file(iris::instance* iris, std::string file) {
    function update_title (line 97) | void update_title(iris::instance* iris) {
    function update_time (line 113) | void update_time(iris::instance* iris) {
    function sleep_limiter (line 130) | void sleep_limiter(iris::instance* iris) {
    function do_cycle (line 142) | static inline void do_cycle(iris::instance* iris) {
    function update_window (line 176) | void update_window(iris::instance* iris) {
    function init (line 363) | bool init(iris::instance* iris, int argc, const char* argv[]) {
    function SDL_AppResult (line 470) | SDL_AppResult update(iris::instance* iris) {
    function SDL_AppResult (line 526) | SDL_AppResult handle_events(iris::instance* iris, SDL_Event* event) {
    function get_menubar_height (line 688) | int get_menubar_height(iris::instance* iris) {
    function destroy (line 696) | void destroy(iris::instance* iris) {

FILE: frontend/iris.hpp
  type iris (line 24) | namespace iris {
    class instance (line 67) | class instance
      type ps2_state (line 429) | struct ps2_state
      type ds_state (line 593) | struct ds_state
      type mcd_state (line 594) | struct mcd_state
    type breakpoint (line 81) | struct breakpoint {
    type move_animation (line 90) | struct move_animation {
    type fade_animation (line 98) | struct fade_animation {
    type notification (line 105) | struct notification {
    type elf_symbol (line 118) | struct elf_symbol {
    type input_device (line 138) | struct input_device {
      method set_slot (line 141) | void set_slot(int slot) {
      method get_slot (line 145) | int get_slot() {
    class keyboard_device (line 153) | class keyboard_device : public input_device {
      method get_type (line 155) | int get_type() override {
    class gamepad_device (line 162) | class gamepad_device : public input_device {
      method gamepad_device (line 166) | gamepad_device(SDL_JoystickID id) : id(id) {}
      method get_type (line 168) | int get_type() override {
      method SDL_JoystickID (line 172) | SDL_JoystickID get_id() {
    type event (line 188) | enum event {
    type input_action (line 195) | enum input_action : uint32_t {
    type vertex (line 234) | struct vertex {
      method VkVertexInputBindingDescription (line 239) | static constexpr const VkVertexInputBindingDescription get_binding_d...
      method get_attribute_descriptions (line 249) | static constexpr const std::array<VkVertexInputAttributeDescription,...
    type texture (line 266) | struct texture {
    type shaders (line 276) | namespace shaders {
      class pass (line 277) | class pass
        method swap (line 659) | void swap(pass& rhs) {
        method pass (line 690) | pass() = default;
      class pass (line 645) | class pass {
        method swap (line 659) | void swap(pass& rhs) {
        method pass (line 690) | pass() = default;
    type vulkan_gpu (line 280) | struct vulkan_gpu {
    class bidirectional_map (line 287) | class bidirectional_map {
      method insert (line 292) | void insert(const Key& key, const Value& value) {
      method erase_by_key (line 305) | bool erase_by_key(const Key& key) {
      method erase_by_value (line 316) | bool erase_by_value(const Value& value) {
      method clear (line 327) | void clear() {
      method Value (line 332) | Value* get_value(const Key& key) {
      method Key (line 340) | Key* get_key(const Value& value) {
    type mapping (line 349) | struct mapping {
    type recent (line 354) | struct recent {
    type instance (line 359) | struct instance {
      type ps2_state (line 429) | struct ps2_state
      type ds_state (line 593) | struct ds_state
      type mcd_state (line 594) | struct mcd_state
    type push_constants (line 625) | struct push_constants {
    type audio (line 630) | namespace audio {
    type settings (line 638) | namespace settings {
    type shaders (line 644) | namespace shaders {
      class pass (line 277) | class pass
        method swap (line 659) | void swap(pass& rhs) {
        method pass (line 690) | pass() = default;
      class pass (line 645) | class pass {
        method swap (line 659) | void swap(pass& rhs) {
        method pass (line 690) | pass() = default;
    type imgui (line 723) | namespace imgui {
    type vulkan (line 735) | namespace vulkan {
    type platform (line 744) | namespace platform {
    type elf (line 750) | namespace elf {
    type emu (line 755) | namespace emu {
    type render (line 766) | namespace render {
    type input (line 775) | namespace input {

FILE: frontend/notifications.cpp
  type iris (line 5) | namespace iris {
    function seconds_to_frames (line 17) | static inline int seconds_to_frames(float s) {
    function ease_in_out (line 21) | float ease_in_out(float t) {
    function handle_move (line 29) | void handle_move(iris::notification* notif) {
    function handle_fade (line 47) | void handle_fade(iris::notification* notif) {
    function render_notification (line 64) | void render_notification(iris::instance* iris, iris::notification* not...
    function remove_notification (line 123) | void remove_notification(iris::instance* iris, int i) {
    function handle_animations (line 144) | void handle_animations(iris::instance* iris) {
    function push_notification (line 176) | void push_notification(iris::instance* iris, iris::notification notif) {
    function push_info (line 193) | void push_info(iris::instance* iris, std::string text) {

FILE: frontend/platform/stub.cpp
  type iris::platform (line 6) | namespace iris::platform {
    function init (line 8) | bool init(iris::instance* iris) {
    function apply_settings (line 12) | bool apply_settings(iris::instance* iris) {
    function destroy (line 16) | void destroy(iris::instance* iris) {}

FILE: frontend/platform/windows.cpp
  type iris::platform (line 6) | namespace iris::platform {
    function init (line 8) | bool init(iris::instance* iris) {
    function apply_settings (line 14) | bool apply_settings(iris::instance* iris) {
    function destroy (line 83) | void destroy(iris::instance* iris) {}

FILE: frontend/render.cpp
  type iris::render (line 15) | namespace iris::render {
    function create_image (line 20) | bool create_image(iris::instance* iris, uint32_t width, uint32_t heigh...
    function rebuild_framebuffers (line 90) | bool rebuild_framebuffers(iris::instance* iris) {
    function init (line 163) | bool init(iris::instance* iris) {
    function VkDescriptorSet (line 299) | static inline VkDescriptorSet get_frame_descriptor_set(iris::instance*...
    function VkDescriptorSet (line 309) | static inline VkDescriptorSet get_frame_shader_descriptor_set(iris::in...
    function update_vertex_buffer (line 320) | static inline void update_vertex_buffer(iris::instance* iris, VkComman...
    function update_descriptor_set (line 485) | static inline void update_descriptor_set(iris::instance* iris, VkDescr...
    function render_shader_passes (line 503) | void render_shader_passes(iris::instance* iris, VkCommandBuffer comman...
    function render_frame (line 609) | bool render_frame(iris::instance* iris, VkCommandBuffer command_buffer...
    function switch_backend (line 717) | void switch_backend(iris::instance* iris, int backend) {
    function refresh (line 749) | void refresh(iris::instance* iris) {
    function destroy (line 773) | void destroy(iris::instance* iris) {

FILE: frontend/settings.cpp
  type iris::settings (line 10) | namespace iris::settings {
    function print_version (line 12) | void print_version() {
    function print_help (line 27) | void print_help() {
    function parse_mappings_file (line 48) | bool parse_mappings_file(iris::instance* iris) {
    function parse_toml_settings (line 91) | bool parse_toml_settings(iris::instance* iris) {
    function check_for_quick_exit (line 272) | bool check_for_quick_exit(int argc, const char* argv[]) {
    function parse_cli_settings (line 290) | void parse_cli_settings(iris::instance* iris, int argc, const char* ar...
    function init (line 410) | bool init(iris::instance* iris, int argc, const char* argv[]) {
    function close (line 436) | void close(iris::instance* iris) {

FILE: frontend/shaders.cpp
  type iris::shaders (line 19) | namespace iris::shaders {
    function pass (line 66) | pass& pass::operator=(pass&& other) {
    function VkPipelineLayout (line 307) | VkPipelineLayout& pass::get_pipeline_layout() {
    function VkPipeline (line 311) | VkPipeline& pass::get_pipeline() {
    function VkRenderPass (line 315) | VkRenderPass& pass::get_render_pass() {
    function VkImageView (line 319) | VkImageView& pass::get_input() {
    function VkShaderModule (line 323) | VkShaderModule& pass::get_vert_shader() {
    function VkShaderModule (line 327) | VkShaderModule& pass::get_frag_shader() {
    function push (line 343) | void push(iris::instance* iris, void* data, size_t size, std::string i...
    function push (line 347) | void push(iris::instance* iris, std::string id) {
    function pop (line 355) | void pop(iris::instance* iris) {
    function insert (line 361) | void insert(iris::instance* iris, int i, void* data, size_t size, std:...
    function erase (line 368) | void erase(iris::instance* iris, int i) {
    function pass (line 374) | pass* at(iris::instance* iris, int i) {
    function swap (line 378) | void swap(iris::instance* iris, int a, int b) {
    function pass (line 385) | pass* front(iris::instance* iris) {
    function pass (line 389) | pass* back(iris::instance* iris) {
    function count (line 393) | size_t count(iris::instance* iris) {
    function clear (line 397) | void clear(iris::instance* iris) {

FILE: frontend/ui/about.cpp
  type iris (line 10) | namespace iris {
    function show_about_window (line 12) | void show_about_window(iris::instance* iris) {

FILE: frontend/ui/bios_setting.cpp
  type iris (line 8) | namespace iris {
    function is_valid (line 15) | int is_valid(const char* path) {
    function show_memory_card_stage (line 40) | void show_memory_card_stage(iris::instance* iris) {
    function show_bios_stage (line 88) | void show_bios_stage(iris::instance* iris) {
    function show_bios_setting_window (line 176) | void show_bios_setting_window(iris::instance* iris) {

FILE: frontend/ui/breakpoints.cpp
  type iris (line 9) | namespace iris {
    function show_breakpoints_table (line 19) | void show_breakpoints_table(iris::instance* iris) {
    function parse_address (line 100) | uint32_t parse_address(iris::instance* iris, const char* buf, const ch...
    function show_breakpoint_editor (line 121) | void show_breakpoint_editor(iris::instance* iris) {
    function show_breakpoints (line 170) | void show_breakpoints(iris::instance* iris) {

FILE: frontend/ui/control.cpp
  type iris (line 17) | namespace iris {
    type ee_dis_state (line 19) | struct ee_dis_state
    type iop_dis_state (line 20) | struct iop_dis_state
    function print_highlighted (line 22) | void print_highlighted(iris::instance* iris, const char* buf) {
    function show_ee_disassembly_view (line 118) | static void show_ee_disassembly_view(iris::instance* iris) {
    function show_iop_disassembly_view (line 321) | static void show_iop_disassembly_view(iris::instance* iris) {
    function show_ee_control (line 506) | void show_ee_control(iris::instance* iris) {
    function show_iop_control (line 566) | void show_iop_control(iris::instance* iris) {

FILE: frontend/ui/dma.cpp
  type iris (line 9) | namespace iris {
    function show_ee_dmac (line 11) | void show_ee_dmac(iris::instance* iris) {
    function show_iop_dma (line 19) | void show_iop_dma(iris::instance* iris) {

FILE: frontend/ui/gs.cpp
  type iris (line 9) | namespace iris {
    function show_privileged_registers (line 115) | void show_privileged_registers(iris::instance* iris) {
    function show_context_registers (line 149) | void show_context_registers(iris::instance* iris, int ctx) {
    function show_internal_registers (line 183) | void show_internal_registers(iris::instance* iris) {
    function show_gs_vertex_xy (line 217) | static inline void show_gs_vertex_xy(iris::instance* iris, const gs_ve...
    function show_gs_vertex_z (line 239) | static inline void show_gs_vertex_z(iris::instance* iris, const gs_ver...
    function show_gs_vertex_stq (line 261) | static inline void show_gs_vertex_stq(iris::instance* iris, const gs_v...
    function show_gs_vertex_uv (line 283) | static inline void show_gs_vertex_uv(iris::instance* iris, const gs_ve...
    function show_gs_vertex_rgba (line 311) | static inline void show_gs_vertex_rgba(iris::instance* iris, const gs_...
    function show_gs_vertex (line 352) | void show_gs_vertex(iris::instance* iris, const gs_vertex* vtx) {
    function show_gs_queue (line 375) | void show_gs_queue(iris::instance* iris) {
    function show_gs_registers (line 405) | void show_gs_registers(iris::instance* iris) {
    function show_gs_memory (line 455) | void show_gs_memory(iris::instance* iris) {
    function show_gs_debugger (line 621) | void show_gs_debugger(iris::instance* iris) {

FILE: frontend/ui/intc.cpp
  type iris (line 9) | namespace iris {
    function show_ee_intc_interrupts (line 58) | void show_ee_intc_interrupts(iris::instance* iris) {
    function show_ee_interrupts (line 104) | void show_ee_interrupts(iris::instance* iris) {
    function show_iop_intc_interrupts (line 132) | void show_iop_intc_interrupts(iris::instance* iris) {
    function show_iop_interrupts (line 178) | void show_iop_interrupts(iris::instance* iris) {

FILE: frontend/ui/logs.cpp
  type iris (line 9) | namespace iris {
    function show_logs (line 15) | void show_logs(iris::instance* iris, const std::vector <std::string>& ...
    function show_ee_logs (line 49) | void show_ee_logs(iris::instance* iris) {
    function show_iop_logs (line 74) | void show_iop_logs(iris::instance* iris) {
    function show_sysmem_logs (line 111) | void show_sysmem_logs(iris::instance* iris) {

FILE: frontend/ui/memory.cpp
  type iris (line 12) | namespace iris {
    function show_memory_viewer (line 16) | void show_memory_viewer(iris::instance* iris) {

FILE: frontend/ui/memory_card_tool.cpp
  type iris (line 11) | namespace iris {
    function show_memory_card_tool (line 30) | void show_memory_card_tool(iris::instance* iris) {

FILE: frontend/ui/memory_search.cpp
  type iris (line 14) | namespace iris {
    type match (line 83) | struct match {
    function compare_values (line 100) | bool compare_values(int cmp, T a, T b) {
    function search_memory (line 119) | void search_memory(struct ps2_state* ps2, int cpu, int type, int cmp, ...
    function filter_results (line 221) | void filter_results(int type, int cmp, const char* value_str) {
    function write_match_value (line 306) | void write_match_value(struct ps2_state* ps2, int cpu, match& m, int t...
    function sprintf_match (line 331) | void sprintf_match(const value& v, char* buf, size_t size, int type, i...
    function show_match_change_dialog (line 366) | void show_match_change_dialog(iris::instance* iris, match& m, char* la...
    function show_description_change_dialog (line 439) | void show_description_change_dialog(iris::instance* iris, match& m) {
    function show_search_table (line 492) | void show_search_table(iris::instance* iris, struct ps2_state* ps2, in...
    function show_address_list (line 623) | void show_address_list(iris::instance* iris) {
    function show_search_options (line 757) | void show_search_options(iris::instance* iris) {
    function update_search_matches (line 825) | void update_search_matches(struct ps2_state* ps2, int cpu) {
    function serialize_address_list (line 848) | std::string serialize_address_list() {
    function import_address_list_from_stream (line 858) | void import_address_list_from_stream(std::istream& stream) {
    function show_memory_search (line 894) | void show_memory_search(iris::instance* iris) {

FILE: frontend/ui/memory_viewer.h
  type DataFormat (line 79) | enum DataFormat
  function GotoAddrAndHighlight (line 163) | void GotoAddrAndHighlight(size_t addr_min, size_t addr_max)
  type Sizes (line 170) | struct Sizes
  function CalcSizes (line 186) | void CalcSizes(Sizes& s, size_t mem_size, size_t base_display_addr)
  type InputTextUserData (line 355) | struct InputTextUserData
  function DrawOptionsLine (line 553) | void DrawOptionsLine(const Sizes& s, void* mem_data, size_t mem_size, si...
  function DrawPreviewLine (line 601) | void DrawPreviewLine(const Sizes& s, void* mem_data_void, size_t mem_siz...
  function DataTypeGetSize (line 652) | size_t DataTypeGetSize(ImGuiDataType data_type) const
  function IsBigEndian (line 666) | bool IsBigEndian() const
  function DrawPreviewData (line 732) | void DrawPreviewData(size_t addr, const ImU8* mem_data, size_t mem_size,...

FILE: frontend/ui/menubar.cpp
  type iris (line 11) | namespace iris {
    function show_main_menubar (line 46) | void show_main_menubar(iris::instance* iris) {

FILE: frontend/ui/modules.cpp
  type iris (line 7) | namespace iris {
    function show_modules_table (line 26) | static inline void show_modules_table(iris::instance* iris) {
    type iop_module (line 73) | struct iop_module
    type iop_state (line 74) | struct iop_state
    type iop_module (line 77) | struct iop_module
    function show_iop_modules (line 86) | void show_iop_modules(iris::instance* iris) {

FILE: frontend/ui/overlay.cpp
  type iris (line 12) | namespace iris {
    function update_overlay (line 24) | void update_overlay(iris::instance* iris) {
    function show_overlay (line 54) | void show_overlay(iris::instance* iris) {

FILE: frontend/ui/pad.cpp
  type iris (line 9) | namespace iris {
    function show_pad_debugger (line 11) | void show_pad_debugger(iris::instance* iris) {

FILE: frontend/ui/settings.cpp
  type iris (line 11) | namespace iris {
    function mapping (line 18) | mapping* get_input_mapping(iris::instance* iris, int slot) {
    function get_event_name (line 67) | std::string get_event_name(const input_event& event) {
    function show_system_settings (line 180) | void show_system_settings(iris::instance* iris) {
    function show_hardware_renderer_settings (line 298) | void show_hardware_renderer_settings(iris::instance* iris) {
    function show_graphics_settings (line 356) | void show_graphics_settings(iris::instance* iris) {
    function show_controller_slot (line 536) | void show_controller_slot(iris::instance* iris, int slot) {
    function event_is_mod_key (line 691) | bool event_is_mod_key(const input_event& event) {
    function show_mappings_editor (line 710) | void show_mappings_editor(iris::instance* iris) {
    function show_input_settings (line 878) | void show_input_settings(iris::instance* iris) {
    function show_paths_settings (line 904) | void show_paths_settings(iris::instance* iris) {
    function show_memory_card (line 1153) | void show_memory_card(iris::instance* iris, int slot) {
    function show_memory_card_settings (line 1258) | void show_memory_card_settings(iris::instance* iris) {
    function show_misc_settings (line 1298) | void show_misc_settings(iris::instance* iris) {
    function show_shader_settings (line 1494) | void show_shader_settings(iris::instance* iris) {
    function show_settings (line 1586) | void show_settings(iris::instance* iris) {

FILE: frontend/ui/spu2.cpp
  type iris (line 9) | namespace iris {
    function show_spu2_core (line 29) | void show_spu2_core(iris::instance* iris, int c) {
    function show_spu2_tab (line 100) | void show_spu2_tab(iris::instance* iris, int c) {
    function show_spu2_debugger (line 129) | void show_spu2_debugger(iris::instance* iris) {

FILE: frontend/ui/state.cpp
  type iris (line 16) | namespace iris {
    type vu_reg128 (line 103) | struct vu_reg128
    function show_ee_main_registers (line 113) | static inline void show_ee_main_registers(iris::instance* iris) {
    function show_ee_cop0_registers (line 214) | static inline void show_ee_cop0_registers(iris::instance* iris) {
    function show_ee_fpu_registers (line 310) | static inline void show_ee_fpu_registers(iris::instance* iris) {
    function show_vu0_float (line 462) | static inline void show_vu0_float(iris::instance* iris) {
    function show_vu0_integer (line 580) | static inline void show_vu0_integer(iris::instance* iris) {
    function show_iop_main_registers (line 684) | static inline void show_iop_main_registers(iris::instance* iris) {
    function show_work_in_progress (line 773) | static inline void show_work_in_progress(iris::instance* iris) {
    function show_ee_state (line 806) | void show_ee_state(iris::instance* iris) {
    function show_iop_state (line 892) | void show_iop_state(iris::instance* iris) {

FILE: frontend/ui/statusbar.cpp
  type ImGui (line 7) | namespace ImGui {
    function BeginMainStatusBar (line 9) | bool BeginMainStatusBar()
    function EndMainStatusBar (line 34) | void EndMainStatusBar()
  type iris (line 49) | namespace iris {
    function get_format_bpp (line 51) | int get_format_bpp(VkFormat fmt) {
    function show_status_bar (line 62) | void show_status_bar(iris::instance* iris) {

FILE: frontend/ui/symbols.cpp
  type iris (line 11) | namespace iris {
    function filter_symbols (line 36) | void filter_symbols(iris::instance* iris, const char* filter, bool reg...
    function edit_callback (line 71) | int edit_callback(ImGuiInputTextCallbackData* data) {
    function show_symbols (line 79) | void show_symbols(iris::instance* iris) {

FILE: frontend/ui/threads.cpp
  type iris (line 12) | namespace iris {
    function show_thread_list (line 40) | void show_thread_list(iris::instance* iris) {
    function show_threads (line 96) | void show_threads(iris::instance* iris) {

FILE: frontend/ui/vu_disassembly.cpp
  function ltrim_impl (line 19) | inline void ltrim_impl(std::string &s) {
  function rtrim_impl (line 26) | inline void rtrim_impl(std::string &s) {
  function trim_impl (line 33) | inline void trim_impl(std::string &s) {
  function ltrim (line 39) | inline std::string ltrim(std::string s) {
  function rtrim (line 45) | inline std::string rtrim(std::string s) {
  function trim (line 51) | inline std::string trim(std::string s) {
  type iris (line 58) | namespace iris {
    type vu_dis_state (line 60) | struct vu_dis_state
    function print_highlighted_vu1 (line 69) | void print_highlighted_vu1(iris::instance* iris, const char* buf) {
    function show_vu_disassembly_view (line 179) | static void show_vu_disassembly_view(iris::instance* iris, uint64_t* m...
    function save_disassembly (line 289) | void save_disassembly(FILE* file, uint64_t* mem, size_t size) {
    function show_vu_disassembler (line 328) | void show_vu_disassembler(iris::instance* iris) {

FILE: frontend/vulkan.cpp
  type iris::vulkan (line 10) | namespace iris::vulkan {
    function get_instance_extensions (line 12) | std::vector <VkExtensionProperties> get_instance_extensions() {
    function get_instance_layers (line 30) | std::vector <VkLayerProperties> get_instance_layers() {
    function is_instance_extension_supported (line 48) | bool is_instance_extension_supported(iris::instance* iris, const char*...
    function is_instance_layer_supported (line 58) | bool is_instance_layer_supported(iris::instance* iris, const char* nam...
    function is_device_extension_supported (line 68) | bool is_device_extension_supported(iris::instance* iris, const char* n...
    function is_device_layer_supported (line 78) | bool is_device_layer_supported(iris::instance* iris, const char* name) {
    function get_device_extensions (line 88) | std::vector <VkExtensionProperties> get_device_extensions(iris::instan...
    function get_device_layers (line 106) | std::vector <VkLayerProperties> get_device_layers(iris::instance* iris) {
    type instance_create_info (line 124) | struct instance_create_info {
    function VkInstance (line 130) | VkInstance create_instance(iris::instance* iris, const instance_create...
    function find_memory_type (line 177) | static inline uint32_t find_memory_type(iris::instance* iris, uint32_t...
    type device_create_info (line 190) | struct device_create_info {
    function VkDevice (line 197) | VkDevice create_device(iris::instance* iris, const device_create_info&...
    function enumerate_physical_devices (line 317) | void enumerate_physical_devices(iris::instance* iris) {
    function VkPhysicalDevice (line 348) | VkPhysicalDevice find_suitable_physical_device(iris::instance* iris) {
    function find_graphics_queue_family_index (line 368) | int find_graphics_queue_family_index(iris::instance* iris) {
    function VkBuffer (line 392) | VkBuffer create_buffer(iris::instance* iris, VkDeviceSize size, VkBuff...
    function load_buffer (line 438) | void load_buffer(iris::instance* iris, VkDeviceMemory buffer_memory, v...
    function copy_buffer (line 446) | bool copy_buffer(iris::instance* iris, VkBuffer src, VkBuffer dst, VkD...
    function create_descriptor_pool (line 495) | bool create_descriptor_pool(iris::instance* iris) {
    function texture (line 520) | texture upload_texture(iris::instance* iris, void* pixels, int width, ...
    function free_texture (line 771) | void free_texture(iris::instance* iris, texture& tex) {
    function init (line 781) | bool init(iris::instance* iris, bool enable_validation) {
    function cleanup (line 1022) | void cleanup(iris::instance* iris) {
    function insert_image_memory_barrier (line 1046) | void insert_image_memory_barrier(
    function wait_idle (line 1338) | void wait_idle(iris::instance* iris) {

FILE: main.cpp
  function SDL_AppResult (line 29) | SDL_AppResult SDL_AppInit(void** appstate, int argc, char** argv) {
  function SDL_AppResult (line 52) | SDL_AppResult SDL_AppIterate(void* appstate) {
  function SDL_AppResult (line 58) | SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event) {
  function SDL_AppQuit (line 64) | void SDL_AppQuit(void* appstate, SDL_AppResult result) {

FILE: src/dev/ds.c
  function ds_get_model_byte (line 8) | static inline uint8_t ds_get_model_byte(struct ds_state* ds) {
  function ds_cmd_set_vref_param (line 15) | static inline void ds_cmd_set_vref_param(struct ps2_sio2* sio2, struct d...
  function ds_cmd_query_masked (line 28) | static inline void ds_cmd_query_masked(struct ps2_sio2* sio2, struct ds_...
  function ds_cmd_read_data (line 51) | static inline void ds_cmd_read_data(struct ps2_sio2* sio2, struct ds_sta...
  function ds_cmd_config_mode (line 86) | static inline void ds_cmd_config_mode(struct ps2_sio2* sio2, struct ds_s...
  function ds_cmd_set_mode (line 121) | static inline void ds_cmd_set_mode(struct ps2_sio2* sio2, struct ds_stat...
  function ds_cmd_query_model (line 143) | static inline void ds_cmd_query_model(struct ps2_sio2* sio2, struct ds_s...
  function ds_cmd_query_act (line 156) | static inline void ds_cmd_query_act(struct ps2_sio2* sio2, struct ds_sta...
  function ds_cmd_query_comb (line 183) | static inline void ds_cmd_query_comb(struct ps2_sio2* sio2, struct ds_st...
  function ds_cmd_query_mode (line 196) | static inline void ds_cmd_query_mode(struct ps2_sio2* sio2, struct ds_st...
  function ds_cmd_vibration_toggle (line 211) | static inline void ds_cmd_vibration_toggle(struct ps2_sio2* sio2, struct...
  function ds_cmd_set_native_mode (line 227) | static inline void ds_cmd_set_native_mode(struct ps2_sio2* sio2, struct ...
  function ds_handle_command (line 262) | void ds_handle_command(struct ps2_sio2* sio2, void* udata, int cmd) {
  type ds_state (line 284) | struct ds_state
  type ps2_sio2 (line 284) | struct ps2_sio2
  type ds_state (line 285) | struct ds_state
  type ds_state (line 285) | struct ds_state
  type sio2_device (line 286) | struct sio2_device
  type ds_state (line 292) | struct ds_state
  function ds_button_press (line 314) | void ds_button_press(struct ds_state* ds, uint32_t mask) {
  function ds_button_release (line 325) | void ds_button_release(struct ds_state* ds, uint32_t mask) {
  function ds_analog_change (line 329) | void ds_analog_change(struct ds_state* ds, int axis, uint8_t value) {
  function ds_detach (line 338) | void ds_detach(void* udata) {

FILE: src/dev/ds.h
  type ds_state (line 36) | struct ds_state {
  type ds_state (line 52) | struct ds_state
  type ps2_sio2 (line 52) | struct ps2_sio2
  type ds_state (line 53) | struct ds_state
  type ds_state (line 54) | struct ds_state
  type ds_state (line 55) | struct ds_state

FILE: src/dev/guncon.c
  function guncon_get_model_byte (line 8) | static inline uint8_t guncon_get_model_byte(struct guncon_state* guncon) {
  function guncon_cmd_set_vref_param (line 11) | static inline void guncon_cmd_set_vref_param(struct ps2_sio2* sio2, stru...
  function guncon_cmd_query_masked (line 24) | static inline void guncon_cmd_query_masked(struct ps2_sio2* sio2, struct...
  function guncon_cmd_read_data (line 37) | static inline void guncon_cmd_read_data(struct ps2_sio2* sio2, struct gu...
  function guncon_cmd_config_mode (line 50) | static inline void guncon_cmd_config_mode(struct ps2_sio2* sio2, struct ...
  function guncon_cmd_set_mode (line 82) | static inline void guncon_cmd_set_mode(struct ps2_sio2* sio2, struct gun...
  function guncon_cmd_query_model (line 95) | static inline void guncon_cmd_query_model(struct ps2_sio2* sio2, struct ...
  function guncon_cmd_query_act (line 108) | static inline void guncon_cmd_query_act(struct ps2_sio2* sio2, struct gu...
  function guncon_cmd_query_comb (line 135) | static inline void guncon_cmd_query_comb(struct ps2_sio2* sio2, struct g...
  function guncon_cmd_query_mode (line 148) | static inline void guncon_cmd_query_mode(struct ps2_sio2* sio2, struct g...
  function guncon_cmd_vibration_toggle (line 163) | static inline void guncon_cmd_vibration_toggle(struct ps2_sio2* sio2, st...
  function guncon_cmd_set_native_mode (line 176) | static inline void guncon_cmd_set_native_mode(struct ps2_sio2* sio2, str...
  function guncon_handle_command (line 195) | void guncon_handle_command(struct ps2_sio2* sio2, void* udata, int cmd) {
  type guncon_state (line 217) | struct guncon_state
  type ps2_sio2 (line 217) | struct ps2_sio2
  type guncon_state (line 218) | struct guncon_state
  type guncon_state (line 218) | struct guncon_state
  type sio2_device (line 219) | struct sio2_device
  type guncon_state (line 225) | struct guncon_state
  function guncon_button_press (line 238) | void guncon_button_press(struct guncon_state* guncon, uint16_t mask) {
  function guncon_button_release (line 242) | void guncon_button_release(struct guncon_state* guncon, uint16_t mask) {
  function guncon_analog_change (line 246) | void guncon_analog_change(struct guncon_state* guncon, int axis, uint8_t...
  function guncon_detach (line 253) | void guncon_detach(void* udata) {

FILE: src/dev/guncon.h
  type guncon_state (line 20) | struct guncon_state {
  type guncon_state (line 28) | struct guncon_state
  type ps2_sio2 (line 28) | struct ps2_sio2
  type guncon_state (line 29) | struct guncon_state
  type guncon_state (line 30) | struct guncon_state
  type guncon_state (line 31) | struct guncon_state

FILE: src/dev/mcd.c
  function mcd_flush_block (line 9) | void mcd_flush_block(struct mcd_state* mcd, int addr, int size) {
  function mcd_cmd_probe (line 14) | void mcd_cmd_probe(struct ps2_sio2* sio2, struct mcd_state* mcd) {
  function mcd_cmd_unk_12 (line 22) | void mcd_cmd_unk_12(struct ps2_sio2* sio2, struct mcd_state* mcd) {
  function mcd_cmd_start_erase (line 30) | void mcd_cmd_start_erase(struct ps2_sio2* sio2, struct mcd_state* mcd) {
  function mcd_cmd_start_write (line 52) | void mcd_cmd_start_write(struct ps2_sio2* sio2, struct mcd_state* mcd) {
  function mcd_cmd_start_read (line 74) | void mcd_cmd_start_read(struct ps2_sio2* sio2, struct mcd_state* mcd) {
  function mcd_cmd_get_specs (line 96) | void mcd_cmd_get_specs(struct ps2_sio2* sio2, struct mcd_state* mcd) {
  function mcd_cmd_set_terminator (line 114) | void mcd_cmd_set_terminator(struct ps2_sio2* sio2, struct mcd_state* mcd) {
  function mcd_cmd_get_terminator (line 125) | void mcd_cmd_get_terminator(struct ps2_sio2* sio2, struct mcd_state* mcd) {
  function mcd_cmd_write_data (line 134) | void mcd_cmd_write_data(struct ps2_sio2* sio2, struct mcd_state* mcd) {
  function mcd_cmd_read_data (line 158) | void mcd_cmd_read_data(struct ps2_sio2* sio2, struct mcd_state* mcd) {
  function mcd_cmd_rw_end (line 182) | void mcd_cmd_rw_end(struct ps2_sio2* sio2, struct mcd_state* mcd) {
  function mcd_cmd_erase_block (line 190) | void mcd_cmd_erase_block(struct ps2_sio2* sio2, struct mcd_state* mcd) {
  function mcd_cmd_auth_f0 (line 206) | void mcd_cmd_auth_f0(struct ps2_sio2* sio2, struct mcd_state* mcd) {
  function mcd_cmd_auth_f1 (line 267) | void mcd_cmd_auth_f1(struct ps2_sio2* sio2, struct mcd_state* mcd) {
  function mcd_cmd_auth_f3 (line 285) | void mcd_cmd_auth_f3(struct ps2_sio2* sio2, struct mcd_state* mcd) {
  function mcd_cmd_auth_f7 (line 294) | void mcd_cmd_auth_f7(struct ps2_sio2* sio2, struct mcd_state* mcd) {
  function mcd_cmd_unk_bf (line 303) | void mcd_cmd_unk_bf(struct ps2_sio2* sio2, struct mcd_state* mcd) {
  function mcd_handle_command (line 313) | void mcd_handle_command(struct ps2_sio2* sio2, void* udata, int cmd) {
  type mcd_state (line 342) | struct mcd_state
  type ps2_sio2 (line 342) | struct ps2_sio2
  type mcd_state (line 348) | struct mcd_state
  type mcd_state (line 348) | struct mcd_state
  type sio2_device (line 349) | struct sio2_device
  type mcd_state (line 351) | struct mcd_state
  function mcd_detach (line 389) | void mcd_detach(void* udata) {

FILE: src/dev/mcd.h
  type mcd_state (line 21) | struct mcd_state {
  type mcd_state (line 41) | struct mcd_state
  type ps2_sio2 (line 41) | struct ps2_sio2

FILE: src/dev/mtap.c
  function mtap_cmd_probe (line 8) | void mtap_cmd_probe(struct ps2_sio2* sio2, struct mtap_state* mtap) {
  function mtap_handle_command (line 19) | void mtap_handle_command(struct ps2_sio2* sio2, void* udata, int cmd) {
  type mtap_state (line 31) | struct mtap_state
  type ps2_sio2 (line 31) | struct ps2_sio2
  type mtap_state (line 32) | struct mtap_state
  type mtap_state (line 32) | struct mtap_state
  type sio2_device (line 33) | struct sio2_device
  type mtap_state (line 39) | struct mtap_state
  function mtap_detach (line 46) | void mtap_detach(void* udata) {

FILE: src/dev/mtap.h
  type mtap_state (line 13) | struct mtap_state {
  type mtap_state (line 17) | struct mtap_state
  type ps2_sio2 (line 17) | struct ps2_sio2

FILE: src/dev/ps1_mcd.c
  function ps1_mcd_flush_block (line 9) | void ps1_mcd_flush_block(struct ps1_mcd_state* mcd, int addr) {
  function ps1_mcd_cmd_read (line 30) | void ps1_mcd_cmd_read(struct ps2_sio2* sio2, struct ps1_mcd_state* mcd) {
  function ps1_mcd_cmd_write (line 75) | void ps1_mcd_cmd_write(struct ps2_sio2* sio2, struct ps1_mcd_state* mcd) {
  function ps1_mcd_cmd_get_id (line 106) | void ps1_mcd_cmd_get_id(struct ps2_sio2* sio2, struct ps1_mcd_state* mcd) {
  function ps1_mcd_cmd_invalid (line 111) | void ps1_mcd_cmd_invalid(struct ps2_sio2* sio2, struct ps1_mcd_state* mc...
  function ps1_mcd_cmd_detect_pocketstation (line 120) | void ps1_mcd_cmd_detect_pocketstation(struct ps2_sio2* sio2, struct ps1_...
  function ps1_mcd_handle_command (line 131) | void ps1_mcd_handle_command(struct ps2_sio2* sio2, void* udata, int cmd) {
  function ps1_mcd_set_type (line 151) | void ps1_mcd_set_type(struct ps1_mcd_state* mcd, int type) {
  type ps1_mcd_state (line 155) | struct ps1_mcd_state
  type ps2_sio2 (line 155) | struct ps2_sio2
  type ps1_mcd_state (line 161) | struct ps1_mcd_state
  type ps1_mcd_state (line 161) | struct ps1_mcd_state
  type sio2_device (line 162) | struct sio2_device
  type ps1_mcd_state (line 164) | struct ps1_mcd_state
  function ps1_mcd_detach (line 184) | void ps1_mcd_detach(void* udata) {

FILE: src/dev/ps1_mcd.h
  type ps1_mcd_state (line 17) | struct ps1_mcd_state {
  type ps1_mcd_state (line 26) | struct ps1_mcd_state
  type ps2_sio2 (line 26) | struct ps2_sio2
  type ps1_mcd_state (line 27) | struct ps1_mcd_state

FILE: src/ee/bus.c
  type ee_bus (line 8) | struct ee_bus
  type ee_bus (line 9) | struct ee_bus
  function ee_bus_init (line 15) | void ee_bus_init(struct ee_bus* bus, const char* bios_path) {
  function ee_bus_init_fastmem (line 24) | void ee_bus_init_fastmem(struct ee_bus* bus, int ee_ram_size, int iop_ra...
  function ee_bus_init_bios (line 46) | void ee_bus_init_bios(struct ee_bus* bus, struct ps2_bios* bios) {
  function ee_bus_init_rom1 (line 50) | void ee_bus_init_rom1(struct ee_bus* bus, struct ps2_bios* rom1) {
  function ee_bus_init_rom2 (line 54) | void ee_bus_init_rom2(struct ee_bus* bus, struct ps2_bios* rom2) {
  function ee_bus_init_iop_ram (line 58) | void ee_bus_init_iop_ram(struct ee_bus* bus, struct ps2_ram* iop_ram) {
  function ee_bus_init_sif (line 62) | void ee_bus_init_sif(struct ee_bus* bus, struct ps2_sif* sif) {
  function ee_bus_init_ram (line 66) | void ee_bus_init_ram(struct ee_bus* bus, struct ps2_ram* ram) {
  function ee_bus_init_dmac (line 70) | void ee_bus_init_dmac(struct ee_bus* bus, struct ps2_dmac* dmac) {
  function ee_bus_init_intc (line 74) | void ee_bus_init_intc(struct ee_bus* bus, struct ps2_intc* intc) {
  function ee_bus_init_gif (line 78) | void ee_bus_init_gif(struct ee_bus* bus, struct ps2_gif* gif) {
  function ee_bus_init_vif0 (line 82) | void ee_bus_init_vif0(struct ee_bus* bus, struct ps2_vif* vif0) {
  function ee_bus_init_vif1 (line 86) | void ee_bus_init_vif1(struct ee_bus* bus, struct ps2_vif* vif1) {
  function ee_bus_init_gs (line 90) | void ee_bus_init_gs(struct ee_bus* bus, struct ps2_gs* gs) {
  function ee_bus_init_ipu (line 94) | void ee_bus_init_ipu(struct ee_bus* bus, struct ps2_ipu* ipu) {
  function ee_bus_init_timers (line 98) | void ee_bus_init_timers(struct ee_bus* bus, struct ps2_ee_timers* timers) {
  function ee_bus_init_cdvd (line 102) | void ee_bus_init_cdvd(struct ee_bus* bus, struct ps2_cdvd* cdvd) {
  function ee_bus_init_usb (line 106) | void ee_bus_init_usb(struct ee_bus* bus, struct ps2_usb* usb) {
  function ee_bus_init_sbus (line 110) | void ee_bus_init_sbus(struct ee_bus* bus, struct ps2_sbus* sbus) {
  function ee_bus_init_dev9 (line 114) | void ee_bus_init_dev9(struct ee_bus* bus, struct ps2_dev9* dev9) {
  function ee_bus_init_speed (line 118) | void ee_bus_init_speed(struct ee_bus* bus, struct ps2_speed* speed) {
  function ee_bus_init_vu0 (line 122) | void ee_bus_init_vu0(struct ee_bus* bus, struct vu_state* vu) {
  function ee_bus_init_vu1 (line 126) | void ee_bus_init_vu1(struct ee_bus* bus, struct vu_state* vu) {
  function ee_bus_init_kputchar (line 130) | void ee_bus_init_kputchar(struct ee_bus* bus, void (*kputchar)(void*, ch...
  function ee_bus_destroy (line 135) | void ee_bus_destroy(struct ee_bus* bus) {
  function ee_bus_read8 (line 157) | uint64_t ee_bus_read8(void* udata, uint32_t addr) {
  function ee_bus_read16 (line 187) | uint64_t ee_bus_read16(void* udata, uint32_t addr) {
  function ee_bus_read32 (line 223) | uint64_t ee_bus_read32(void* udata, uint32_t addr) {
  function ee_bus_read64 (line 321) | uint64_t ee_bus_read64(void* udata, uint32_t addr) {
  function uint128_t (line 349) | uint128_t ee_bus_read128(void* udata, uint32_t addr) {
  function ee_bus_write8 (line 376) | void ee_bus_write8(void* udata, uint32_t addr, uint64_t data) {
  function ee_bus_write16 (line 406) | void ee_bus_write16(void* udata, uint32_t addr, uint64_t data) {
  function ee_bus_write32 (line 440) | void ee_bus_write32(void* udata, uint32_t addr, uint64_t data) {
  function ee_bus_write64 (line 507) | void ee_bus_write64(void* udata, uint32_t addr, uint64_t data) {
  function ee_bus_write128 (line 536) | void ee_bus_write128(void* udata, uint32_t addr, uint128_t data) {

FILE: src/ee/bus.h
  type ee_bus (line 26) | struct ee_bus {
  type ee_bus (line 63) | struct ee_bus
  type ps2_ram (line 63) | struct ps2_ram
  type ee_bus (line 64) | struct ee_bus
  type ps2_dmac (line 64) | struct ps2_dmac
  type ee_bus (line 65) | struct ee_bus
  type ps2_intc (line 65) | struct ps2_intc
  type ee_bus (line 66) | struct ee_bus
  type ps2_gif (line 66) | struct ps2_gif
  type ee_bus (line 67) | struct ee_bus
  type ps2_vif (line 67) | struct ps2_vif
  type ee_bus (line 68) | struct ee_bus
  type ps2_vif (line 68) | struct ps2_vif
  type ee_bus (line 69) | struct ee_bus
  type ps2_gs (line 69) | struct ps2_gs
  type ee_bus (line 70) | struct ee_bus
  type ps2_ipu (line 70) | struct ps2_ipu
  type ee_bus (line 71) | struct ee_bus
  type ps2_ee_timers (line 71) | struct ps2_ee_timers
  type ee_bus (line 72) | struct ee_bus
  type ps2_bios (line 72) | struct ps2_bios
  type ee_bus (line 73) | struct ee_bus
  type ps2_bios (line 73) | struct ps2_bios
  type ee_bus (line 74) | struct ee_bus
  type ps2_bios (line 74) | struct ps2_bios
  type ee_bus (line 75) | struct ee_bus
  type ps2_ram (line 75) | struct ps2_ram
  type ee_bus (line 76) | struct ee_bus
  type ps2_sif (line 76) | struct ps2_sif
  type ee_bus (line 77) | struct ee_bus
  type ps2_cdvd (line 77) | struct ps2_cdvd
  type ee_bus (line 78) | struct ee_bus
  type ps2_usb (line 78) | struct ps2_usb
  type ee_bus (line 79) | struct ee_bus
  type ps2_sbus (line 79) | struct ps2_sbus
  type ee_bus (line 80) | struct ee_bus
  type ps2_dev9 (line 80) | struct ps2_dev9
  type ee_bus (line 81) | struct ee_bus
  type ps2_speed (line 81) | struct ps2_speed
  type ee_bus (line 82) | struct ee_bus
  type vu_state (line 82) | struct vu_state
  type ee_bus (line 83) | struct ee_bus
  type vu_state (line 83) | struct vu_state
  type ee_bus (line 84) | struct ee_bus
  type ee_bus (line 85) | struct ee_bus

FILE: src/ee/bus_decl.h
  type ee_bus (line 10) | struct ee_bus
  type ee_bus (line 12) | struct ee_bus
  type ee_bus (line 13) | struct ee_bus
  type ee_bus (line 14) | struct ee_bus

FILE: src/ee/dmac.c
  function uint128_t (line 10) | static inline uint128_t dmac_read_qword(struct ps2_dmac* dmac, uint32_t ...
  function dmac_write_qword (line 19) | static inline void dmac_write_qword(struct ps2_dmac* dmac, uint32_t addr...
  type ps2_dmac (line 31) | struct ps2_dmac
  type ps2_dmac (line 32) | struct ps2_dmac
  function ps2_dmac_init (line 35) | void ps2_dmac_init(struct ps2_dmac* dmac, struct ps2_sif* sif, struct ps...
  function ps2_dmac_destroy (line 49) | void ps2_dmac_destroy(struct ps2_dmac* dmac) {
  type dmac_channel (line 53) | struct dmac_channel
  type ps2_dmac (line 53) | struct ps2_dmac
  type ps2_dmac (line 70) | struct ps2_dmac
  function channel_is_done (line 87) | static inline int channel_is_done(struct dmac_channel* ch) {
  function ps2_dmac_read32 (line 91) | uint64_t ps2_dmac_read32(struct ps2_dmac* dmac, uint32_t addr) {
  function dmac_process_source_tag (line 124) | static inline void dmac_process_source_tag(struct ps2_dmac* dmac, struct...
  function dmac_process_dest_tag (line 219) | static inline void dmac_process_dest_tag(struct ps2_dmac* dmac, struct d...
  function dmac_test_cpcond0 (line 244) | static inline void dmac_test_cpcond0(struct ps2_dmac* dmac) {
  function dmac_test_irq (line 248) | static inline void dmac_test_irq(struct ps2_dmac* dmac) {
  function dmac_set_irq (line 257) | static inline void dmac_set_irq(struct ps2_dmac* dmac, int ch) {
  function dmac_handle_vif0_transfer (line 265) | void dmac_handle_vif0_transfer(struct ps2_dmac* dmac) {
  function dmac_send_vif1_irq (line 340) | void dmac_send_vif1_irq(void* udata, int overshoot) {
  function mfifo_handle_ref_tag (line 351) | void mfifo_handle_ref_tag(struct ps2_dmac* dmac) {
  function mfifo_write_qword (line 383) | void mfifo_write_qword(struct ps2_dmac* dmac, uint128_t q) {
  function dmac_handle_vif1_transfer (line 471) | void dmac_handle_vif1_transfer(struct ps2_dmac* dmac) {
  function dmac_send_gif_irq (line 580) | void dmac_send_gif_irq(void* udata, int overshoot) {
  function dmac_handle_gif_transfer (line 589) | void dmac_handle_gif_transfer(struct ps2_dmac* dmac) {
  function dmac_handle_ipu_from_transfer (line 682) | void dmac_handle_ipu_from_transfer(struct ps2_dmac* dmac) {
  function dmac_transfer_ipu_to_qword (line 727) | int dmac_transfer_ipu_to_qword(struct ps2_dmac* dmac) {
  function dmac_handle_ipu_to_transfer (line 784) | void dmac_handle_ipu_to_transfer(struct ps2_dmac* dmac) {
  function dmac_handle_sif0_transfer (line 805) | void dmac_handle_sif0_transfer(struct ps2_dmac* dmac) {
  function dmac_handle_sif1_transfer (line 901) | void dmac_handle_sif1_transfer(struct ps2_dmac* dmac) {
  function dmac_handle_sif2_transfer (line 965) | void dmac_handle_sif2_transfer(struct ps2_dmac* dmac) {
  function dmac_spr_from_interleave (line 969) | void dmac_spr_from_interleave(struct ps2_dmac* dmac) {
  function dmac_handle_spr_from_transfer (line 992) | void dmac_handle_spr_from_transfer(struct ps2_dmac* dmac) {
  function dmac_spr_to_interleave (line 1097) | void dmac_spr_to_interleave(struct ps2_dmac* dmac) {
  function dmac_handle_spr_to_transfer (line 1120) | void dmac_handle_spr_to_transfer(struct ps2_dmac* dmac) {
  function dmac_handle_channel_start (line 1198) | static inline void dmac_handle_channel_start(struct ps2_dmac* dmac, uint...
  function dmac_write_stat (line 1262) | void dmac_write_stat(struct ps2_dmac* dmac, uint32_t data) {
  function ps2_dmac_write32 (line 1274) | void ps2_dmac_write32(struct ps2_dmac* dmac, uint32_t addr, uint64_t dat...
  function ps2_dmac_read8 (line 1344) | uint64_t ps2_dmac_read8(struct ps2_dmac* dmac, uint32_t addr) {
  function ps2_dmac_write8 (line 1390) | void ps2_dmac_write8(struct ps2_dmac* dmac, uint32_t addr, uint64_t data) {
  function ps2_dmac_read16 (line 1455) | uint64_t ps2_dmac_read16(struct ps2_dmac* dmac, uint32_t addr) {
  function ps2_dmac_write16 (line 1462) | void ps2_dmac_write16(struct ps2_dmac* dmac, uint32_t addr, uint64_t dat...

FILE: src/ee/dmac.h
  type ps2_dmac (line 1) | struct ps2_dmac
  type dmac_tag (line 40) | struct dmac_tag {
  type dmac_channel (line 50) | struct dmac_channel {
  type ps2_dmac (line 64) | struct ps2_dmac {
  type ps2_dmac (line 94) | struct ps2_dmac
  type ps2_dmac (line 95) | struct ps2_dmac
  type ps2_sif (line 95) | struct ps2_sif
  type ps2_iop_dma (line 95) | struct ps2_iop_dma
  type ps2_ram (line 95) | struct ps2_ram
  type ee_state (line 95) | struct ee_state
  type sched_state (line 95) | struct sched_state
  type ee_bus (line 95) | struct ee_bus
  type ps2_dmac (line 96) | struct ps2_dmac
  type ps2_dmac (line 97) | struct ps2_dmac
  type ps2_dmac (line 98) | struct ps2_dmac
  type ps2_dmac (line 99) | struct ps2_dmac
  type ps2_dmac (line 100) | struct ps2_dmac
  type ps2_dmac (line 101) | struct ps2_dmac
  type ps2_dmac (line 102) | struct ps2_dmac
  type ps2_dmac (line 104) | struct ps2_dmac
  type ps2_dmac (line 105) | struct ps2_dmac
  type ps2_dmac (line 106) | struct ps2_dmac
  type ps2_dmac (line 107) | struct ps2_dmac
  type ps2_dmac (line 108) | struct ps2_dmac
  type ps2_dmac (line 109) | struct ps2_dmac
  type ps2_dmac (line 110) | struct ps2_dmac
  type ps2_dmac (line 111) | struct ps2_dmac
  type ps2_dmac (line 112) | struct ps2_dmac
  type ps2_dmac (line 113) | struct ps2_dmac

FILE: src/ee/ee.h
  type ee_bus_s (line 16) | struct ee_bus_s {
  type ee_vtlb_entry (line 113) | struct ee_vtlb_entry {
  type ee_osd_config (line 130) | struct ee_osd_config {
  type ee_state (line 156) | struct ee_state
  type ee_state (line 158) | struct ee_state
  type ee_state (line 159) | struct ee_state
  type vu_state (line 159) | struct vu_state
  type vu_state (line 159) | struct vu_state
  type ee_bus_s (line 159) | struct ee_bus_s
  type ee_state (line 160) | struct ee_state
  type ee_state (line 161) | struct ee_state
  type ee_state (line 162) | struct ee_state
  type ee_state (line 163) | struct ee_state
  type ee_state (line 164) | struct ee_state
  type ee_state (line 165) | struct ee_state
  type ps2_ram (line 166) | struct ps2_ram
  type ee_state (line 166) | struct ee_state
  type ee_state (line 167) | struct ee_state
  type ee_state (line 168) | struct ee_state
  type ee_state (line 169) | struct ee_state
  type ee_state (line 170) | struct ee_state
  type ee_state (line 171) | struct ee_state
  type ee_state (line 172) | struct ee_state
  type ee_state (line 173) | struct ee_state
  type ee_state (line 174) | struct ee_state
  type ee_osd_config (line 174) | struct ee_osd_config
  type ee_osd_config (line 175) | struct ee_osd_config
  type ee_state (line 175) | struct ee_state

FILE: src/ee/ee_cached.cpp
  function fast_abs32 (line 90) | static inline int fast_abs32(int a) {
  function fast_abs16 (line 96) | static inline int16_t fast_abs16(int16_t a) {
  function saturate16 (line 102) | static inline int16_t saturate16(int32_t word) {
  function saturate32 (line 112) | static inline int32_t saturate32(int64_t word) {
  function __m128i (line 123) | static inline __m128i _mm_adds_epi32(__m128i a, __m128i b) {
  function __m128i (line 137) | static inline __m128i _mm_adds_epu32(__m128i a, __m128i b) {
  function unpack_5551_8888 (line 147) | static inline uint32_t unpack_5551_8888(uint32_t v) {
  function ee_print_disassembly (line 213) | static inline void ee_print_disassembly(struct ee_state* ee, const ee_in...
  function ee_get_segment (line 224) | static inline int ee_get_segment(uint32_t virt) {
  function fpu_cvtf (line 244) | static inline float fpu_cvtf(float f) {
  function fpu_cvtsw (line 264) | static inline float fpu_cvtsw(union ee_fpu_reg* reg) {
  function fpu_cvtws (line 278) | static inline void fpu_cvtws(union ee_fpu_reg* d, union ee_fpu_reg* s) {
  function fpu_check_overflow (line 287) | static inline int fpu_check_overflow(struct ee_state* ee, union ee_fpu_r...
  function fpu_check_underflow (line 300) | static inline int fpu_check_underflow(struct ee_state* ee, union ee_fpu_...
  function fpu_check_overflow_no_flags (line 313) | static inline int fpu_check_overflow_no_flags(struct ee_state* ee, union...
  function fpu_check_underflow_no_flags (line 323) | static inline int fpu_check_underflow_no_flags(struct ee_state* ee, unio...
  function fpu_max (line 333) | static inline int fpu_max(int32_t a, int32_t b) {
  function fpu_min (line 337) | static inline int fpu_min(int32_t a, int32_t b) {
  type ee_state (line 341) | struct ee_state
  type ee_vtlb_entry (line 344) | struct ee_vtlb_entry
  type ee_state (line 344) | struct ee_state
  type ee_vtlb_entry (line 346) | struct ee_vtlb_entry
  function ee_translate_virt (line 373) | static inline int ee_translate_virt(struct ee_state* ee, uint32_t virt, ...
  function uint128_t (line 456) | static inline uint128_t bus_read128(struct ee_state* ee, uint32_t addr) {
  function bus_write128 (line 470) | static inline void bus_write128(struct ee_state* ee, uint32_t addr, uint...
  function ee_translate_virt (line 479) | static inline int ee_translate_virt(struct ee_state* ee, uint32_t virt, ...
  function uint128_t (line 573) | static inline uint128_t bus_read128(struct ee_state* ee, uint32_t addr) {
  function bus_write128 (line 589) | static inline void bus_write128(struct ee_state* ee, uint32_t addr, uint...
  function ee_skip_fmv (line 609) | static inline int ee_skip_fmv(struct ee_state* ee, uint32_t addr) {
  function ee_set_pc (line 630) | static inline void ee_set_pc(struct ee_state* ee, uint32_t addr) {
  function ee_set_pc_delayed (line 639) | static inline void ee_set_pc_delayed(struct ee_state* ee, uint32_t addr) {
  function ee_exception_level1 (line 648) | void ee_exception_level1(struct ee_state* ee, uint32_t cause) {
  function ee_exception_level2 (line 688) | static inline void ee_exception_level2(struct ee_state* ee, uint32_t cau...
  function ee_check_irq (line 720) | static inline int ee_check_irq(struct ee_state* ee) {
  function ee_set_int0 (line 747) | void ee_set_int0(struct ee_state* ee, int v) {
  function ee_set_int1 (line 755) | void ee_set_int1(struct ee_state* ee, int v) {
  function ee_set_cpcond0 (line 763) | void ee_set_cpcond0(struct ee_state* ee, int v) {
  function ee_i_abss (line 767) | static inline void ee_i_abss(struct ee_state* ee, const ee_instruction& ...
  function ee_i_add (line 771) | static inline void ee_i_add(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_addas (line 784) | static inline void ee_i_addas(struct ee_state* ee, const ee_instruction&...
  function ee_i_addi (line 792) | static inline void ee_i_addi(struct ee_state* ee, const ee_instruction& ...
  function ee_i_addiu (line 803) | static inline void ee_i_addiu(struct ee_state* ee, const ee_instruction&...
  function ee_i_adds (line 806) | static inline void ee_i_adds(struct ee_state* ee, const ee_instruction& ...
  function ee_i_addu (line 816) | static inline void ee_i_addu(struct ee_state* ee, const ee_instruction& ...
  function ee_i_and (line 819) | static inline void ee_i_and(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_andi (line 822) | static inline void ee_i_andi(struct ee_state* ee, const ee_instruction& ...
  function ee_i_bc0f (line 825) | static inline void ee_i_bc0f(struct ee_state* ee, const ee_instruction& ...
  function ee_i_bc0fl (line 828) | static inline void ee_i_bc0fl(struct ee_state* ee, const ee_instruction&...
  function ee_i_bc0t (line 831) | static inline void ee_i_bc0t(struct ee_state* ee, const ee_instruction& ...
  function ee_i_bc0tl (line 834) | static inline void ee_i_bc0tl(struct ee_state* ee, const ee_instruction&...
  function ee_i_bc1f (line 837) | static inline void ee_i_bc1f(struct ee_state* ee, const ee_instruction& ...
  function ee_i_bc1fl (line 840) | static inline void ee_i_bc1fl(struct ee_state* ee, const ee_instruction&...
  function ee_i_bc1t (line 843) | static inline void ee_i_bc1t(struct ee_state* ee, const ee_instruction& ...
  function ee_i_bc1tl (line 846) | static inline void ee_i_bc1tl(struct ee_state* ee, const ee_instruction&...
  function ee_i_bc2f (line 849) | static inline void ee_i_bc2f(struct ee_state* ee, const ee_instruction& ...
  function ee_i_bc2fl (line 850) | static inline void ee_i_bc2fl(struct ee_state* ee, const ee_instruction&...
  function ee_i_bc2t (line 851) | static inline void ee_i_bc2t(struct ee_state* ee, const ee_instruction& ...
  function ee_i_bc2tl (line 852) | static inline void ee_i_bc2tl(struct ee_state* ee, const ee_instruction&...
  function ee_i_beq (line 853) | static inline void ee_i_beq(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_beql (line 856) | static inline void ee_i_beql(struct ee_state* ee, const ee_instruction& ...
  function ee_i_bgez (line 859) | static inline void ee_i_bgez(struct ee_state* ee, const ee_instruction& ...
  function ee_i_bgezal (line 862) | static inline void ee_i_bgezal(struct ee_state* ee, const ee_instruction...
  function ee_i_bgezall (line 867) | static inline void ee_i_bgezall(struct ee_state* ee, const ee_instructio...
  function ee_i_bgezl (line 872) | static inline void ee_i_bgezl(struct ee_state* ee, const ee_instruction&...
  function ee_i_bgtz (line 875) | static inline void ee_i_bgtz(struct ee_state* ee, const ee_instruction& ...
  function ee_i_bgtzl (line 878) | static inline void ee_i_bgtzl(struct ee_state* ee, const ee_instruction&...
  function ee_i_blez (line 881) | static inline void ee_i_blez(struct ee_state* ee, const ee_instruction& ...
  function ee_i_blezl (line 884) | static inline void ee_i_blezl(struct ee_state* ee, const ee_instruction&...
  function ee_i_bltz (line 887) | static inline void ee_i_bltz(struct ee_state* ee, const ee_instruction& ...
  function ee_i_bltzal (line 890) | static inline void ee_i_bltzal(struct ee_state* ee, const ee_instruction...
  function ee_i_bltzall (line 895) | static inline void ee_i_bltzall(struct ee_state* ee, const ee_instructio...
  function ee_i_bltzl (line 900) | static inline void ee_i_bltzl(struct ee_state* ee, const ee_instruction&...
  function ee_i_bne (line 903) | static inline void ee_i_bne(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_bnel (line 906) | static inline void ee_i_bnel(struct ee_state* ee, const ee_instruction& ...
  function ee_i_break (line 909) | static inline void ee_i_break(struct ee_state* ee, const ee_instruction&...
  function ee_i_cache (line 912) | static inline void ee_i_cache(struct ee_state* ee, const ee_instruction&...
  function ee_i_ceq (line 921) | static inline void ee_i_ceq(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_cf (line 928) | static inline void ee_i_cf(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_cfc1 (line 931) | static inline void ee_i_cfc1(struct ee_state* ee, const ee_instruction& ...
  function ee_i_cfc2 (line 934) | static inline void ee_i_cfc2(struct ee_state* ee, const ee_instruction& ...
  function ee_i_cle (line 937) | static inline void ee_i_cle(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_clt (line 944) | static inline void ee_i_clt(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_ctc1 (line 951) | static inline void ee_i_ctc1(struct ee_state* ee, const ee_instruction& ...
  function ee_i_ctc2 (line 957) | static inline void ee_i_ctc2(struct ee_state* ee, const ee_instruction& ...
  function ee_i_cvts (line 982) | static inline void ee_i_cvts(struct ee_state* ee, const ee_instruction& ...
  function ee_i_cvtw (line 986) | static inline void ee_i_cvtw(struct ee_state* ee, const ee_instruction& ...
  function ee_i_dadd (line 989) | static inline void ee_i_dadd(struct ee_state* ee, const ee_instruction& ...
  function ee_i_daddi (line 998) | static inline void ee_i_daddi(struct ee_state* ee, const ee_instruction&...
  function ee_i_daddiu (line 1007) | static inline void ee_i_daddiu(struct ee_state* ee, const ee_instruction...
  function ee_i_daddu (line 1010) | static inline void ee_i_daddu(struct ee_state* ee, const ee_instruction&...
  function ee_i_di (line 1013) | static inline void ee_i_di(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_div (line 1022) | static inline void ee_i_div(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_div1 (line 1037) | static inline void ee_i_div1(struct ee_state* ee, const ee_instruction& ...
  function ee_i_divs (line 1052) | static inline void ee_i_divs(struct ee_state* ee, const ee_instruction& ...
  function ee_i_divu (line 1080) | static inline void ee_i_divu(struct ee_state* ee, const ee_instruction& ...
  function ee_i_divu1 (line 1094) | static inline void ee_i_divu1(struct ee_state* ee, const ee_instruction&...
  function ee_i_dsll (line 1108) | static inline void ee_i_dsll(struct ee_state* ee, const ee_instruction& ...
  function ee_i_dsll32 (line 1111) | static inline void ee_i_dsll32(struct ee_state* ee, const ee_instruction...
  function ee_i_dsllv (line 1114) | static inline void ee_i_dsllv(struct ee_state* ee, const ee_instruction&...
  function ee_i_dsra (line 1117) | static inline void ee_i_dsra(struct ee_state* ee, const ee_instruction& ...
  function ee_i_dsra32 (line 1120) | static inline void ee_i_dsra32(struct ee_state* ee, const ee_instruction...
  function ee_i_dsrav (line 1123) | static inline void ee_i_dsrav(struct ee_state* ee, const ee_instruction&...
  function ee_i_dsrl (line 1126) | static inline void ee_i_dsrl(struct ee_state* ee, const ee_instruction& ...
  function ee_i_dsrl32 (line 1129) | static inline void ee_i_dsrl32(struct ee_state* ee, const ee_instruction...
  function ee_i_dsrlv (line 1132) | static inline void ee_i_dsrlv(struct ee_state* ee, const ee_instruction&...
  function ee_i_dsub (line 1135) | static inline void ee_i_dsub(struct ee_state* ee, const ee_instruction& ...
  function ee_i_dsubu (line 1144) | static inline void ee_i_dsubu(struct ee_state* ee, const ee_instruction&...
  function ee_i_ei (line 1147) | static inline void ee_i_ei(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_eret (line 1156) | static inline void ee_i_eret(struct ee_state* ee, const ee_instruction& ...
  function ee_i_j (line 1167) | static inline void ee_i_j(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_jal (line 1170) | static inline void ee_i_jal(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_jalr (line 1175) | static inline void ee_i_jalr(struct ee_state* ee, const ee_instruction& ...
  function ee_i_jr (line 1182) | static inline void ee_i_jr(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_lb (line 1185) | static inline void ee_i_lb(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_lbu (line 1188) | static inline void ee_i_lbu(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_ld (line 1191) | static inline void ee_i_ld(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_ldl (line 1194) | static inline void ee_i_ldl(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_ldr (line 1207) | static inline void ee_i_ldr(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_lh (line 1220) | static inline void ee_i_lh(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_lhu (line 1223) | static inline void ee_i_lhu(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_lq (line 1226) | static inline void ee_i_lq(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_lqc2 (line 1229) | static inline void ee_i_lqc2(struct ee_state* ee, const ee_instruction& ...
  function ee_i_lui (line 1236) | static inline void ee_i_lui(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_lw (line 1239) | static inline void ee_i_lw(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_lwc1 (line 1242) | static inline void ee_i_lwc1(struct ee_state* ee, const ee_instruction& ...
  function ee_i_lwl (line 1251) | static inline void ee_i_lwl(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_lwr (line 1260) | static inline void ee_i_lwr(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_lwu (line 1279) | static inline void ee_i_lwu(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_madd (line 1282) | static inline void ee_i_madd(struct ee_state* ee, const ee_instruction& ...
  function ee_i_madd1 (line 1293) | static inline void ee_i_madd1(struct ee_state* ee, const ee_instruction&...
  function ee_i_maddas (line 1304) | static inline void ee_i_maddas(struct ee_state* ee, const ee_instruction...
  function ee_i_madds (line 1312) | static inline void ee_i_madds(struct ee_state* ee, const ee_instruction&...
  function ee_i_maddu (line 1326) | static inline void ee_i_maddu(struct ee_state* ee, const ee_instruction&...
  function ee_i_maddu1 (line 1337) | static inline void ee_i_maddu1(struct ee_state* ee, const ee_instruction...
  function ee_i_maxs (line 1348) | static inline void ee_i_maxs(struct ee_state* ee, const ee_instruction& ...
  function ee_i_mfc0 (line 1353) | static inline void ee_i_mfc0(struct ee_state* ee, const ee_instruction& ...
  function ee_i_mfc1 (line 1356) | static inline void ee_i_mfc1(struct ee_state* ee, const ee_instruction& ...
  function ee_i_mfhi (line 1359) | static inline void ee_i_mfhi(struct ee_state* ee, const ee_instruction& ...
  function ee_i_mfhi1 (line 1362) | static inline void ee_i_mfhi1(struct ee_state* ee, const ee_instruction&...
  function ee_i_mflo (line 1365) | static inline void ee_i_mflo(struct ee_state* ee, const ee_instruction& ...
  function ee_i_mflo1 (line 1368) | static inline void ee_i_mflo1(struct ee_state* ee, const ee_instruction&...
  function ee_i_mfsa (line 1371) | static inline void ee_i_mfsa(struct ee_state* ee, const ee_instruction& ...
  function ee_i_mins (line 1374) | static inline void ee_i_mins(struct ee_state* ee, const ee_instruction& ...
  function ee_i_movn (line 1379) | static inline void ee_i_movn(struct ee_state* ee, const ee_instruction& ...
  function ee_i_movs (line 1382) | static inline void ee_i_movs(struct ee_state* ee, const ee_instruction& ...
  function ee_i_movz (line 1385) | static inline void ee_i_movz(struct ee_state* ee, const ee_instruction& ...
  function ee_i_msubas (line 1388) | static inline void ee_i_msubas(struct ee_state* ee, const ee_instruction...
  function ee_i_msubs (line 1396) | static inline void ee_i_msubs(struct ee_state* ee, const ee_instruction&...
  function ee_i_mtc0 (line 1410) | static inline void ee_i_mtc0(struct ee_state* ee, const ee_instruction& ...
  function ee_i_mtc1 (line 1420) | static inline void ee_i_mtc1(struct ee_state* ee, const ee_instruction& ...
  function ee_i_mthi (line 1423) | static inline void ee_i_mthi(struct ee_state* ee, const ee_instruction& ...
  function ee_i_mthi1 (line 1426) | static inline void ee_i_mthi1(struct ee_state* ee, const ee_instruction&...
  function ee_i_mtlo (line 1429) | static inline void ee_i_mtlo(struct ee_state* ee, const ee_instruction& ...
  function ee_i_mtlo1 (line 1432) | static inline void ee_i_mtlo1(struct ee_state* ee, const ee_instruction&...
  function ee_i_mtsa (line 1435) | static inline void ee_i_mtsa(struct ee_state* ee, const ee_instruction& ...
  function ee_i_mtsab (line 1438) | static inline void ee_i_mtsab(struct ee_state* ee, const ee_instruction&...
  function ee_i_mtsah (line 1441) | static inline void ee_i_mtsah(struct ee_state* ee, const ee_instruction&...
  function ee_i_mulas (line 1444) | static inline void ee_i_mulas(struct ee_state* ee, const ee_instruction&...
  function ee_i_muls (line 1452) | static inline void ee_i_muls(struct ee_state* ee, const ee_instruction& ...
  function ee_i_mult (line 1462) | static inline void ee_i_mult(struct ee_state* ee, const ee_instruction& ...
  function ee_i_mult1 (line 1470) | static inline void ee_i_mult1(struct ee_state* ee, const ee_instruction&...
  function ee_i_multu (line 1478) | static inline void ee_i_multu(struct ee_state* ee, const ee_instruction&...
  function ee_i_multu1 (line 1486) | static inline void ee_i_multu1(struct ee_state* ee, const ee_instruction...
  function ee_i_negs (line 1494) | static inline void ee_i_negs(struct ee_state* ee, const ee_instruction& ...
  function ee_i_nor (line 1499) | static inline void ee_i_nor(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_or (line 1502) | static inline void ee_i_or(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_ori (line 1505) | static inline void ee_i_ori(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_pabsh (line 1508) | static inline void ee_i_pabsh(struct ee_state* ee, const ee_instruction&...
  function ee_i_pabsw (line 1525) | static inline void ee_i_pabsw(struct ee_state* ee, const ee_instruction&...
  function ee_i_paddb (line 1542) | static inline void ee_i_paddb(struct ee_state* ee, const ee_instruction&...
  function ee_i_paddh (line 1559) | static inline void ee_i_paddh(struct ee_state* ee, const ee_instruction&...
  function ee_i_paddsb (line 1576) | static inline void ee_i_paddsb(struct ee_state* ee, const ee_instruction...
  function ee_i_paddsh (line 1594) | static inline void ee_i_paddsh(struct ee_state* ee, const ee_instruction...
  function ee_i_paddsw (line 1612) | static inline void ee_i_paddsw(struct ee_state* ee, const ee_instruction...
  function ee_i_paddub (line 1630) | static inline void ee_i_paddub(struct ee_state* ee, const ee_instruction...
  function ee_i_padduh (line 1648) | static inline void ee_i_padduh(struct ee_state* ee, const ee_instruction...
  function ee_i_padduw (line 1666) | static inline void ee_i_padduw(struct ee_state* ee, const ee_instruction...
  function ee_i_paddw (line 1684) | static inline void ee_i_paddw(struct ee_state* ee, const ee_instruction&...
  function ee_i_padsbh (line 1701) | static inline void ee_i_padsbh(struct ee_state* ee, const ee_instruction...
  function ee_i_pand (line 1725) | static inline void ee_i_pand(struct ee_state* ee, const ee_instruction& ...
  function ee_i_pceqb (line 1741) | static inline void ee_i_pceqb(struct ee_state* ee, const ee_instruction&...
  function ee_i_pceqh (line 1758) | static inline void ee_i_pceqh(struct ee_state* ee, const ee_instruction&...
  function ee_i_pceqw (line 1775) | static inline void ee_i_pceqw(struct ee_state* ee, const ee_instruction&...
  function ee_i_pcgtb (line 1792) | static inline void ee_i_pcgtb(struct ee_state* ee, const ee_instruction&...
  function ee_i_pcgth (line 1809) | static inline void ee_i_pcgth(struct ee_state* ee, const ee_instruction&...
  function ee_i_pcgtw (line 1826) | static inline void ee_i_pcgtw(struct ee_state* ee, const ee_instruction&...
  function ee_i_pcpyh (line 1843) | static inline void ee_i_pcpyh(struct ee_state* ee, const ee_instruction&...
  function ee_i_pcpyld (line 1871) | static inline void ee_i_pcpyld(struct ee_state* ee, const ee_instruction...
  function ee_i_pcpyud (line 1887) | static inline void ee_i_pcpyud(struct ee_state* ee, const ee_instruction...
  function ee_i_pdivbw (line 1895) | static inline void ee_i_pdivbw(struct ee_state* ee, const ee_instruction...
  function ee_i_pdivuw (line 1926) | static inline void ee_i_pdivuw(struct ee_state* ee, const ee_instruction...
  function ee_i_pdivw (line 1940) | static inline void ee_i_pdivw(struct ee_state* ee, const ee_instruction&...
  function ee_i_pexch (line 1967) | static inline void ee_i_pexch(struct ee_state* ee, const ee_instruction&...
  function ee_i_pexcw (line 1980) | static inline void ee_i_pexcw(struct ee_state* ee, const ee_instruction&...
  function ee_i_pexeh (line 1989) | static inline void ee_i_pexeh(struct ee_state* ee, const ee_instruction&...
  function ee_i_pexew (line 2002) | static inline void ee_i_pexew(struct ee_state* ee, const ee_instruction&...
  function ee_i_pext5 (line 2011) | static inline void ee_i_pext5(struct ee_state* ee, const ee_instruction&...
  function ee_i_pextlb (line 2020) | static inline void ee_i_pextlb(struct ee_state* ee, const ee_instruction...
  function ee_i_pextlh (line 2042) | static inline void ee_i_pextlh(struct ee_state* ee, const ee_instruction...
  function ee_i_pextlw (line 2056) | static inline void ee_i_pextlw(struct ee_state* ee, const ee_instruction...
  function ee_i_pextub (line 2066) | static inline void ee_i_pextub(struct ee_state* ee, const ee_instruction...
  function ee_i_pextuh (line 2088) | static inline void ee_i_pextuh(struct ee_state* ee, const ee_instruction...
  function ee_i_pextuw (line 2102) | static inline void ee_i_pextuw(struct ee_state* ee, const ee_instruction...
  function ee_i_phmadh (line 2112) | static inline void ee_i_phmadh(struct ee_state* ee, const ee_instruction...
  function ee_i_phmsbh (line 2135) | static inline void ee_i_phmsbh(struct ee_state* ee, const ee_instruction...
  function ee_i_pinteh (line 2158) | static inline void ee_i_pinteh(struct ee_state* ee, const ee_instruction...
  function ee_i_pinth (line 2172) | static inline void ee_i_pinth(struct ee_state* ee, const ee_instruction&...
  function ee_i_plzcw (line 2186) | static inline void ee_i_plzcw(struct ee_state* ee, const ee_instruction&...
  function ee_i_pmaddh (line 2197) | static inline void ee_i_pmaddh(struct ee_state* ee, const ee_instruction...
  function ee_i_pmadduw (line 2233) | static inline void ee_i_pmadduw(struct ee_state* ee, const ee_instructio...
  function ee_i_pmaddw (line 2248) | static inline void ee_i_pmaddw(struct ee_state* ee, const ee_instruction...
  function ee_i_pmaxh (line 2263) | static inline void ee_i_pmaxh(struct ee_state* ee, const ee_instruction&...
  function ee_i_pmaxw (line 2277) | static inline void ee_i_pmaxw(struct ee_state* ee, const ee_instruction&...
  function ee_i_pmfhi (line 2287) | static inline void ee_i_pmfhi(struct ee_state* ee, const ee_instruction&...
  function ee_i_pmfhllw (line 2290) | static inline void ee_i_pmfhllw(struct ee_state* ee, const ee_instructio...
  function ee_i_pmfhluw (line 2298) | static inline void ee_i_pmfhluw(struct ee_state* ee, const ee_instructio...
  function ee_i_pmfhlslw (line 2306) | static inline void ee_i_pmfhlslw(struct ee_state* ee, const ee_instructi...
  function ee_i_pmfhllh (line 2312) | static inline void ee_i_pmfhllh(struct ee_state* ee, const ee_instructio...
  function ee_i_pmfhlsh (line 2325) | static inline void ee_i_pmfhlsh(struct ee_state* ee, const ee_instructio...
  function ee_i_pmflo (line 2337) | static inline void ee_i_pmflo(struct ee_state* ee, const ee_instruction&...
  function ee_i_pminh (line 2340) | static inline void ee_i_pminh(struct ee_state* ee, const ee_instruction&...
  function ee_i_pminw (line 2354) | static inline void ee_i_pminw(struct ee_state* ee, const ee_instruction&...
  function ee_i_pmsubh (line 2364) | static inline void ee_i_pmsubh(struct ee_state* ee, const ee_instruction...
  function ee_i_pmsubw (line 2392) | static inline void ee_i_pmsubw(struct ee_state* ee, const ee_instruction...
  function ee_i_pmthi (line 2433) | static inline void ee_i_pmthi(struct ee_state* ee, const ee_instruction&...
  function ee_i_pmthl (line 2436) | static inline void ee_i_pmthl(struct ee_state* ee, const ee_instruction&...
  function ee_i_pmtlo (line 2444) | static inline void ee_i_pmtlo(struct ee_state* ee, const ee_instruction&...
  function ee_i_pmulth (line 2447) | static inline void ee_i_pmulth(struct ee_state* ee, const ee_instruction...
  function ee_i_pmultuw (line 2465) | static inline void ee_i_pmultuw(struct ee_state* ee, const ee_instructio...
  function ee_i_pmultw (line 2478) | static inline void ee_i_pmultw(struct ee_state* ee, const ee_instruction...
  function ee_i_pnor (line 2491) | static inline void ee_i_pnor(struct ee_state* ee, const ee_instruction& ...
  function ee_i_por (line 2499) | static inline void ee_i_por(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_ppac5 (line 2507) | static inline void ee_i_ppac5(struct ee_state* ee, const ee_instruction&...
  function ee_i_ppacb (line 2528) | static inline void ee_i_ppacb(struct ee_state* ee, const ee_instruction&...
  function ee_i_ppach (line 2550) | static inline void ee_i_ppach(struct ee_state* ee, const ee_instruction&...
  function ee_i_ppacw (line 2564) | static inline void ee_i_ppacw(struct ee_state* ee, const ee_instruction&...
  function ee_i_pref (line 2574) | static inline void ee_i_pref(struct ee_state* ee, const ee_instruction& ...
  function ee_i_prevh (line 2577) | static inline void ee_i_prevh(struct ee_state* ee, const ee_instruction&...
  function ee_i_prot3w (line 2590) | static inline void ee_i_prot3w(struct ee_state* ee, const ee_instruction...
  function ee_i_psllh (line 2599) | static inline void ee_i_psllh(struct ee_state* ee, const ee_instruction&...
  function ee_i_psllvw (line 2613) | static inline void ee_i_psllvw(struct ee_state* ee, const ee_instruction...
  function ee_i_psllw (line 2621) | static inline void ee_i_psllw(struct ee_state* ee, const ee_instruction&...
  function ee_i_psrah (line 2631) | static inline void ee_i_psrah(struct ee_state* ee, const ee_instruction&...
  function ee_i_psravw (line 2645) | static inline void ee_i_psravw(struct ee_state* ee, const ee_instruction...
  function ee_i_psraw (line 2653) | static inline void ee_i_psraw(struct ee_state* ee, const ee_instruction&...
  function ee_i_psrlh (line 2663) | static inline void ee_i_psrlh(struct ee_state* ee, const ee_instruction&...
  function ee_i_psrlvw (line 2677) | static inline void ee_i_psrlvw(struct ee_state* ee, const ee_instruction...
  function ee_i_psrlw (line 2685) | static inline void ee_i_psrlw(struct ee_state* ee, const ee_instruction&...
  function ee_i_psubb (line 2695) | static inline void ee_i_psubb(struct ee_state* ee, const ee_instruction&...
  function ee_i_psubh (line 2717) | static inline void ee_i_psubh(struct ee_state* ee, const ee_instruction&...
  function ee_i_psubsb (line 2731) | static inline void ee_i_psubsb(struct ee_state* ee, const ee_instruction...
  function ee_i_psubsh (line 2770) | static inline void ee_i_psubsh(struct ee_state* ee, const ee_instruction...
  function ee_i_psubsw (line 2793) | static inline void ee_i_psubsw(struct ee_state* ee, const ee_instruction...
  function ee_i_psubub (line 2808) | static inline void ee_i_psubub(struct ee_state* ee, const ee_instruction...
  function ee_i_psubuh (line 2847) | static inline void ee_i_psubuh(struct ee_state* ee, const ee_instruction...
  function ee_i_psubuw (line 2870) | static inline void ee_i_psubuw(struct ee_state* ee, const ee_instruction...
  function ee_i_psubw (line 2885) | static inline void ee_i_psubw(struct ee_state* ee, const ee_instruction&...
  function ee_i_pxor (line 2895) | static inline void ee_i_pxor(struct ee_state* ee, const ee_instruction& ...
  function ee_i_qfsrv (line 2903) | static inline void ee_i_qfsrv(struct ee_state* ee, const ee_instruction&...
  function ee_i_qmfc2 (line 2933) | static inline void ee_i_qmfc2(struct ee_state* ee, const ee_instruction&...
  function ee_i_qmtc2 (line 2940) | static inline void ee_i_qmtc2(struct ee_state* ee, const ee_instruction&...
  function ee_i_rsqrts (line 2948) | static inline void ee_i_rsqrts(struct ee_state* ee, const ee_instruction...
  function ee_i_sb (line 2972) | static inline void ee_i_sb(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_sd (line 2975) | static inline void ee_i_sd(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_sdl (line 2978) | static inline void ee_i_sdl(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_sdr (line 2991) | static inline void ee_i_sdr(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_sh (line 3004) | static inline void ee_i_sh(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_sll (line 3007) | static inline void ee_i_sll(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_sllv (line 3010) | static inline void ee_i_sllv(struct ee_state* ee, const ee_instruction& ...
  function ee_i_slt (line 3013) | static inline void ee_i_slt(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_slti (line 3016) | static inline void ee_i_slti(struct ee_state* ee, const ee_instruction& ...
  function ee_i_sltiu (line 3019) | static inline void ee_i_sltiu(struct ee_state* ee, const ee_instruction&...
  function ee_i_sltu (line 3022) | static inline void ee_i_sltu(struct ee_state* ee, const ee_instruction& ...
  function ee_i_sq (line 3025) | static inline void ee_i_sq(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_sqc2 (line 3028) | static inline void ee_i_sqc2(struct ee_state* ee, const ee_instruction& ...
  function ee_i_sqrts (line 3031) | static inline void ee_i_sqrts(struct ee_state* ee, const ee_instruction&...
  function ee_i_sra (line 3047) | static inline void ee_i_sra(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_srav (line 3050) | static inline void ee_i_srav(struct ee_state* ee, const ee_instruction& ...
  function ee_i_srl (line 3053) | static inline void ee_i_srl(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_srlv (line 3056) | static inline void ee_i_srlv(struct ee_state* ee, const ee_instruction& ...
  function ee_i_sub (line 3059) | static inline void ee_i_sub(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_subas (line 3070) | static inline void ee_i_subas(struct ee_state* ee, const ee_instruction&...
  function ee_i_subs (line 3078) | static inline void ee_i_subs(struct ee_state* ee, const ee_instruction& ...
  function ee_i_subu (line 3088) | static inline void ee_i_subu(struct ee_state* ee, const ee_instruction& ...
  function ee_i_sw (line 3091) | static inline void ee_i_sw(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_swc1 (line 3094) | static inline void ee_i_swc1(struct ee_state* ee, const ee_instruction& ...
  function ee_i_swl (line 3097) | static inline void ee_i_swl(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_swr (line 3110) | static inline void ee_i_swr(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_sync (line 3123) | static inline void ee_i_sync(struct ee_state* ee, const ee_instruction& ...
  function ee_get_thread_list (line 3129) | static inline void ee_get_thread_list(struct ee_state* ee) {
  function ee_i_syscall (line 3156) | static inline void ee_i_syscall(struct ee_state* ee, const ee_instructio...
  function ee_i_teq (line 3203) | static inline void ee_i_teq(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_teqi (line 3206) | static inline void ee_i_teqi(struct ee_state* ee, const ee_instruction& ...
  function ee_i_tge (line 3209) | static inline void ee_i_tge(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_tgei (line 3212) | static inline void ee_i_tgei(struct ee_state* ee, const ee_instruction& ...
  function ee_i_tgeiu (line 3213) | static inline void ee_i_tgeiu(struct ee_state* ee, const ee_instruction&...
  function ee_i_tgeu (line 3214) | static inline void ee_i_tgeu(struct ee_state* ee, const ee_instruction& ...
  function ee_i_tlbp (line 3215) | static inline void ee_i_tlbp(struct ee_state* ee, const ee_instruction& ...
  function ee_i_tlbr (line 3216) | static inline void ee_i_tlbr(struct ee_state* ee, const ee_instruction& ...
  function ee_i_tlbwi (line 3217) | static inline void ee_i_tlbwi(struct ee_state* ee, const ee_instruction&...
  function ee_i_tlbwr (line 3248) | static inline void ee_i_tlbwr(struct ee_state* ee, const ee_instruction&...
  function ee_i_tlt (line 3281) | static inline void ee_i_tlt(struct ee_state* ee, const ee_instruction& i...
  function ee_i_tlti (line 3282) | static inline void ee_i_tlti(struct ee_state* ee, const ee_instruction& ...
  function ee_i_tltiu (line 3283) | static inline void ee_i_tltiu(struct ee_state* ee, const ee_instruction&...
  function ee_i_tltu (line 3284) | static inline void ee_i_tltu(struct ee_state* ee, const ee_instruction& ...
  function ee_i_tne (line 3285) | static inline void ee_i_tne(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_tnei (line 3288) | static inline void ee_i_tnei(struct ee_state* ee, const ee_instruction& ...
  type ee_state (line 3289) | struct ee_state
  type ee_state (line 3290) | struct ee_state
  type ee_state (line 3291) | struct ee_state
  type ee_state (line 3292) | struct ee_state
  type ee_state (line 3293) | struct ee_state
  type ee_state (line 3294) | struct ee_state
  type ee_state (line 3295) | struct ee_state
  type ee_state (line 3296) | struct ee_state
  type ee_state (line 3297) | struct ee_state
  type ee_state (line 3298) | struct ee_state
  type ee_state (line 3299) | struct ee_state
  type ee_state (line 3300) | struct ee_state
  type ee_state (line 3301) | struct ee_state
  type ee_state (line 3302) | struct ee_state
  type ee_state (line 3303) | struct ee_state
  function ee_i_vcallms (line 3304) | static inline void ee_i_vcallms(struct ee_state* ee, const ee_instructio...
  function ee_i_vcallmsr (line 3307) | static inline void ee_i_vcallmsr(struct ee_state* ee, const ee_instructi...
  type ee_state (line 3310) | struct ee_state
  type ee_state (line 3311) | struct ee_state
  type ee_state (line 3312) | struct ee_state
  type ee_state (line 3313) | struct ee_state
  type ee_state (line 3314) | struct ee_state
  type ee_state (line 3315) | struct ee_state
  type ee_state (line 3316) | struct ee_state
  type ee_state (line 3317) | struct ee_state
  type ee_state (line 3318) | struct ee_state
  type ee_state (line 3319) | struct ee_state
  type ee_state (line 3320) | struct ee_state
  type ee_state (line 3321) | struct ee_state
  type ee_state (line 3322) | struct ee_state
  type ee_state (line 3323) | struct ee_state
  type ee_state (line 3324) | struct ee_state
  type ee_state (line 3325) | struct ee_state
  type ee_state (line 3326) | struct ee_state
  type ee_state (line 3327) | struct ee_state
  type ee_state (line 3328) | struct ee_state
  type ee_state (line 3329) | struct ee_state
  type ee_state (line 3330) | struct ee_state
  type ee_state (line 3331) | struct ee_state
  type ee_state (line 3332) | struct ee_state
  type ee_state (line 3333) | struct ee_state
  type ee_state (line 3334) | struct ee_state
  type ee_state (line 3335) | struct ee_state
  type ee_state (line 3336) | struct ee_state
  type ee_state (line 3337) | struct ee_state
  type ee_state (line 3338) | struct ee_state
  type ee_state (line 3339) | struct ee_state
  type ee_state (line 3340) | struct ee_state
  type ee_state (line 3341) | struct ee_state
  type ee_state (line 3342) | struct ee_state
  type ee_state (line 3343) | struct ee_state
  type ee_state (line 3344) | struct ee_state
  type ee_state (line 3345) | struct ee_state
  type ee_state (line 3346) | struct ee_state
  type ee_state (line 3347) | struct ee_state
  type ee_state (line 3348) | struct ee_state
  type ee_state (line 3349) | struct ee_state
  type ee_state (line 3350) | struct ee_state
  type ee_state (line 3351) | struct ee_state
  type ee_state (line 3352) | struct ee_state
  type ee_state (line 3353) | struct ee_state
  type ee_state (line 3354) | struct ee_state
  type ee_state (line 3355) | struct ee_state
  type ee_state (line 3356) | struct ee_state
  type ee_state (line 3357) | struct ee_state
  type ee_state (line 3358) | struct ee_state
  type ee_state (line 3359) | struct ee_state
  type ee_state (line 3360) | struct ee_state
  type ee_state (line 3361) | struct ee_state
  type ee_state (line 3362) | struct ee_state
  type ee_state (line 3363) | struct ee_state
  type ee_state (line 3364) | struct ee_state
  type ee_state (line 3365) | struct ee_state
  type ee_state (line 3366) | struct ee_state
  type ee_state (line 3367) | struct ee_state
  type ee_state (line 3368) | struct ee_state
  type ee_state (line 3369) | struct ee_state
  type ee_state (line 3370) | struct ee_state
  type ee_state (line 3371) | struct ee_state
  type ee_state (line 3372) | struct ee_state
  type ee_state (line 3373) | struct ee_state
  type ee_state (line 3374) | struct ee_state
  type ee_state (line 3375) | struct ee_state
  type ee_state (line 3376) | struct ee_state
  type ee_state (line 3377) | struct ee_state
  type ee_state (line 3378) | struct ee_state
  type ee_state (line 3379) | struct ee_state
  type ee_state (line 3380) | struct ee_state
  type ee_state (line 3381) | struct ee_state
  type ee_state (line 3382) | struct ee_state
  type ee_state (line 3383) | struct ee_state
  type ee_state (line 3384) | struct ee_state
  type ee_state (line 3385) | struct ee_state
  type ee_state (line 3386) | struct ee_state
  type ee_state (line 3387) | struct ee_state
  type ee_state (line 3388) | struct ee_state
  type ee_state (line 3389) | struct ee_state
  type ee_state (line 3390) | struct ee_state
  type ee_state (line 3391) | struct ee_state
  type ee_state (line 3392) | struct ee_state
  type ee_state (line 3393) | struct ee_state
  type ee_state (line 3394) | struct ee_state
  type ee_state (line 3395) | struct ee_state
  type ee_state (line 3396) | struct ee_state
  type ee_state (line 3397) | struct ee_state
  type ee_state (line 3398) | struct ee_state
  type ee_state (line 3399) | struct ee_state
  type ee_state (line 3400) | struct ee_state
  type ee_state (line 3401) | struct ee_state
  type ee_state (line 3402) | struct ee_state
  type ee_state (line 3403) | struct ee_state
  type ee_state (line 3404) | struct ee_state
  type ee_state (line 3405) | struct ee_state
  type ee_state (line 3406) | struct ee_state
  type ee_state (line 3407) | struct ee_state
  type ee_state (line 3408) | struct ee_state
  type ee_state (line 3409) | struct ee_state
  type ee_state (line 3410) | struct ee_state
  type ee_state (line 3411) | struct ee_state
  type ee_state (line 3412) | struct ee_state
  function ee_i_xor (line 3413) | static inline void ee_i_xor(struct ee_state* ee, const ee_instruction& i) {
  function ee_i_xori (line 3416) | static inline void ee_i_xori(struct ee_state* ee, const ee_instruction& ...
  function ee_i_invalid (line 3419) | static inline void ee_i_invalid(struct ee_state* ee, const ee_instructio...
  function ee_i_nop (line 3424) | static inline void ee_i_nop(struct ee_state* ee, const ee_instruction& i) {
  type ee_state (line 3427) | struct ee_state
  function ee_init (line 3431) | void ee_init(struct ee_state* ee, struct vu_state* vu0, struct vu_state*...
  function ee_reset (line 3467) | void ee_reset(struct ee_state* ee) {
  function ee_destroy (line 3508) | void ee_destroy(struct ee_state* ee) {
  function ee_instruction (line 3519) | ee_instruction ee_decode(uint32_t opcode) {
  type ee_block (line 4029) | struct ee_block
  type ee_state (line 4029) | struct ee_state
  type ee_block (line 4034) | struct ee_block
  type ee_block (line 4037) | struct ee_block
  type ee_block (line 4085) | struct ee_block
  type ee_state (line 4085) | struct ee_state
  type ee_block (line 4099) | struct ee_block
  function ee_run_block (line 4112) | int ee_run_block(struct ee_state* ee, int max_cycles) {
  function ee_step (line 4177) | int ee_step(struct ee_state* ee) {
  function ee_flush_cache (line 4205) | void ee_flush_cache(struct ee_state* ee) {
  function ee_get_pc (line 4216) | uint32_t ee_get_pc(struct ee_state* ee) {
  type ps2_ram (line 4220) | struct ps2_ram
  type ee_state (line 4220) | struct ee_state
  function ee_set_fmv_skip (line 4224) | void ee_set_fmv_skip(struct ee_state* ee, int v) {
  function ee_reset_intc_reads (line 4228) | void ee_reset_intc_reads(struct ee_state* ee) {
  function ee_reset_csr_reads (line 4232) | void ee_reset_csr_reads(struct ee_state* ee) {
  function ee_set_ram_size (line 4236) | void ee_set_ram_size(struct ee_state* ee, int ram_size) {
  function ee_set_osd_config (line 4240) | void ee_set_osd_config(struct ee_state* ee, struct ee_osd_config config) {
  function ee_get_osd_config (line 4244) | struct ee_osd_config ee_get_osd_config(struct ee_state* ee) {

FILE: src/ee/ee_def.hpp
  type ee_instruction (line 38) | struct ee_instruction {
    type ee_state (line 56) | struct ee_state
  type ee_block (line 59) | struct ee_block {
  type ee_state (line 64) | struct ee_state {
    type ee_bus_s (line 65) | struct ee_bus_s
    type ee_block (line 74) | struct ee_block
    type ps2_ram (line 92) | struct ps2_ram
    type vu_state (line 143) | struct vu_state
    type vu_state (line 144) | struct vu_state
    type ee_vtlb_entry (line 146) | struct ee_vtlb_entry
    type ee_osd_config (line 147) | struct ee_osd_config
  type ee_thread (line 167) | struct ee_thread {

FILE: src/ee/ee_dis.c
  type ee_dis_state (line 8) | struct ee_dis_state
  function ee_d_abss (line 61) | static inline void ee_d_abss(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_add (line 62) | static inline void ee_d_add(uint32_t opcode) { ptr += sprintf(ptr, "%-8s...
  function ee_d_addas (line 63) | static inline void ee_d_addas(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_addi (line 64) | static inline void ee_d_addi(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_addiu (line 65) | static inline void ee_d_addiu(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_adds (line 66) | static inline void ee_d_adds(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_addu (line 67) | static inline void ee_d_addu(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_and (line 68) | static inline void ee_d_and(uint32_t opcode) { ptr += sprintf(ptr, "%-8s...
  function ee_d_andi (line 69) | static inline void ee_d_andi(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_bc0f (line 70) | static inline void ee_d_bc0f(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_bc0fl (line 71) | static inline void ee_d_bc0fl(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_bc0t (line 72) | static inline void ee_d_bc0t(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_bc0tl (line 73) | static inline void ee_d_bc0tl(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_bc1f (line 74) | static inline void ee_d_bc1f(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_bc1fl (line 75) | static inline void ee_d_bc1fl(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_bc1t (line 76) | static inline void ee_d_bc1t(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_bc1tl (line 77) | static inline void ee_d_bc1tl(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_bc2f (line 78) | static inline void ee_d_bc2f(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_bc2fl (line 79) | static inline void ee_d_bc2fl(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_bc2t (line 80) | static inline void ee_d_bc2t(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_bc2tl (line 81) | static inline void ee_d_bc2tl(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_beq (line 82) | static inline void ee_d_beq(uint32_t opcode) { ptr += sprintf(ptr, "%-8s...
  function ee_d_beql (line 83) | static inline void ee_d_beql(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_bgez (line 84) | static inline void ee_d_bgez(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_bgezal (line 85) | static inline void ee_d_bgezal(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_bgezall (line 86) | static inline void ee_d_bgezall(uint32_t opcode) { ptr += sprintf(ptr, "...
  function ee_d_bgezl (line 87) | static inline void ee_d_bgezl(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_bgtz (line 88) | static inline void ee_d_bgtz(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_bgtzl (line 89) | static inline void ee_d_bgtzl(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_blez (line 90) | static inline void ee_d_blez(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_blezl (line 91) | static inline void ee_d_blezl(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_bltz (line 92) | static inline void ee_d_bltz(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_bltzal (line 93) | static inline void ee_d_bltzal(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_bltzall (line 94) | static inline void ee_d_bltzall(uint32_t opcode) { ptr += sprintf(ptr, "...
  function ee_d_bltzl (line 95) | static inline void ee_d_bltzl(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_bne (line 96) | static inline void ee_d_bne(uint32_t opcode) { ptr += sprintf(ptr, "%-8s...
  function ee_d_bnel (line 97) | static inline void ee_d_bnel(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_break (line 98) | static inline void ee_d_break(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_cache (line 99) | static inline void ee_d_cache(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_callmsr (line 100) | static inline void ee_d_callmsr(uint32_t opcode) { ptr += sprintf(ptr, "...
  function ee_d_ceq (line 101) | static inline void ee_d_ceq(uint32_t opcode) { ptr += sprintf(ptr, "%-8s...
  function ee_d_cfc1 (line 102) | static inline void ee_d_cfc1(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_cfc2 (line 103) | static inline void ee_d_cfc2(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_cf (line 104) | static inline void ee_d_cf(uint32_t opcode) { ptr += sprintf(ptr, "%-8s ...
  function ee_d_cle (line 105) | static inline void ee_d_cle(uint32_t opcode) { ptr += sprintf(ptr, "%-8s...
  function ee_d_clt (line 106) | static inline void ee_d_clt(uint32_t opcode) { ptr += sprintf(ptr, "%-8s...
  function ee_d_ctc1 (line 107) | static inline void ee_d_ctc1(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_ctc2 (line 108) | static inline void ee_d_ctc2(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_cvts (line 109) | static inline void ee_d_cvts(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_cvtw (line 110) | static inline void ee_d_cvtw(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_dadd (line 111) | static inline void ee_d_dadd(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_daddi (line 112) | static inline void ee_d_daddi(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_daddiu (line 113) | static inline void ee_d_daddiu(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_daddu (line 114) | static inline void ee_d_daddu(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_di (line 115) | static inline void ee_d_di(uint32_t opcode) { ptr += sprintf(ptr, "%-8s"...
  function ee_d_div (line 116) | static inline void ee_d_div(uint32_t opcode) { ptr += sprintf(ptr, "%-8s...
  function ee_d_div1 (line 117) | static inline void ee_d_div1(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_divs (line 118) | static inline void ee_d_divs(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_divu (line 119) | static inline void ee_d_divu(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_divu1 (line 120) | static inline void ee_d_divu1(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_dsll (line 121) | static inline void ee_d_dsll(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_dsll32 (line 122) | static inline void ee_d_dsll32(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_dsllv (line 123) | static inline void ee_d_dsllv(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_dsra (line 124) | static inline void ee_d_dsra(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_dsra32 (line 125) | static inline void ee_d_dsra32(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_dsrav (line 126) | static inline void ee_d_dsrav(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_dsrl (line 127) | static inline void ee_d_dsrl(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_dsrl32 (line 128) | static inline void ee_d_dsrl32(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_dsrlv (line 129) | static inline void ee_d_dsrlv(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_dsub (line 130) | static inline void ee_d_dsub(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_dsubu (line 131) | static inline void ee_d_dsubu(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_ei (line 132) | static inline void ee_d_ei(uint32_t opcode) { ptr += sprintf(ptr, "%-8s"...
  function ee_d_eret (line 133) | static inline void ee_d_eret(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_j (line 134) | static inline void ee_d_j(uint32_t opcode) { ptr += sprintf(ptr, "%-8s 0...
  function ee_d_jal (line 135) | static inline void ee_d_jal(uint32_t opcode) { ptr += sprintf(ptr, "%-8s...
  function ee_d_jalr (line 136) | static inline void ee_d_jalr(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_jr (line 137) | static inline void ee_d_jr(uint32_t opcode) { ptr += sprintf(ptr, "%-8s ...
  function ee_d_lb (line 138) | static inline void ee_d_lb(uint32_t opcode) { ptr += sprintf(ptr, "%-8s ...
  function ee_d_lbu (line 139) | static inline void ee_d_lbu(uint32_t opcode) { ptr += sprintf(ptr, "%-8s...
  function ee_d_ld (line 140) | static inline void ee_d_ld(uint32_t opcode) { ptr += sprintf(ptr, "%-8s ...
  function ee_d_ldl (line 141) | static inline void ee_d_ldl(uint32_t opcode) { ptr += sprintf(ptr, "%-8s...
  function ee_d_ldr (line 142) | static inline void ee_d_ldr(uint32_t opcode) { ptr += sprintf(ptr, "%-8s...
  function ee_d_lh (line 143) | static inline void ee_d_lh(uint32_t opcode) { ptr += sprintf(ptr, "%-8s ...
  function ee_d_lhu (line 144) | static inline void ee_d_lhu(uint32_t opcode) { ptr += sprintf(ptr, "%-8s...
  function ee_d_lq (line 145) | static inline void ee_d_lq(uint32_t opcode) { ptr += sprintf(ptr, "%-8s ...
  function ee_d_lqc2 (line 146) | static inline void ee_d_lqc2(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_lui (line 147) | static inline void ee_d_lui(uint32_t opcode) { ptr += sprintf(ptr, "%-8s...
  function ee_d_lw (line 148) | static inline void ee_d_lw(uint32_t opcode) { ptr += sprintf(ptr, "%-8s ...
  function ee_d_lwc1 (line 149) | static inline void ee_d_lwc1(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_lwl (line 150) | static inline void ee_d_lwl(uint32_t opcode) { ptr += sprintf(ptr, "%-8s...
  function ee_d_lwr (line 151) | static inline void ee_d_lwr(uint32_t opcode) { ptr += sprintf(ptr, "%-8s...
  function ee_d_lwu (line 152) | static inline void ee_d_lwu(uint32_t opcode) { ptr += sprintf(ptr, "%-8s...
  function ee_d_madd (line 153) | static inline void ee_d_madd(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_madd1 (line 154) | static inline void ee_d_madd1(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_maddas (line 155) | static inline void ee_d_maddas(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_madds (line 156) | static inline void ee_d_madds(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_maddu (line 157) | static inline void ee_d_maddu(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_maddu1 (line 158) | static inline void ee_d_maddu1(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_maxs (line 159) | static inline void ee_d_maxs(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_mfc0 (line 160) | static inline void ee_d_mfc0(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_mfc1 (line 161) | static inline void ee_d_mfc1(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_mfhi (line 162) | static inline void ee_d_mfhi(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_mfhi1 (line 163) | static inline void ee_d_mfhi1(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_mflo (line 164) | static inline void ee_d_mflo(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_mflo1 (line 165) | static inline void ee_d_mflo1(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_mfsa (line 166) | static inline void ee_d_mfsa(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_mins (line 167) | static inline void ee_d_mins(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_movn (line 168) | static inline void ee_d_movn(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_movs (line 169) | static inline void ee_d_movs(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_movz (line 170) | static inline void ee_d_movz(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_msubas (line 171) | static inline void ee_d_msubas(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_msubs (line 172) | static inline void ee_d_msubs(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_mtc0 (line 173) | static inline void ee_d_mtc0(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_mtc1 (line 174) | static inline void ee_d_mtc1(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_mthi (line 175) | static inline void ee_d_mthi(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_mthi1 (line 176) | static inline void ee_d_mthi1(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_mtlo (line 177) | static inline void ee_d_mtlo(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_mtlo1 (line 178) | static inline void ee_d_mtlo1(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_mtsa (line 179) | static inline void ee_d_mtsa(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_mtsab (line 180) | static inline void ee_d_mtsab(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_mtsah (line 181) | static inline void ee_d_mtsah(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_mulas (line 182) | static inline void ee_d_mulas(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_muls (line 183) | static inline void ee_d_muls(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_mult (line 184) | static inline void ee_d_mult(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_mult1 (line 185) | static inline void ee_d_mult1(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_multu (line 186) | static inline void ee_d_multu(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_multu1 (line 187) | static inline void ee_d_multu1(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_negs (line 188) | static inline void ee_d_negs(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_nor (line 189) | static inline void ee_d_nor(uint32_t opcode) { ptr += sprintf(ptr, "%-8s...
  function ee_d_or (line 190) | static inline void ee_d_or(uint32_t opcode) { ptr += sprintf(ptr, "%-8s ...
  function ee_d_ori (line 191) | static inline void ee_d_ori(uint32_t opcode) { ptr += sprintf(ptr, "%-8s...
  function ee_d_pabsh (line 192) | static inline void ee_d_pabsh(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_pabsw (line 193) | static inline void ee_d_pabsw(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_paddb (line 194) | static inline void ee_d_paddb(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_paddh (line 195) | static inline void ee_d_paddh(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_paddsb (line 196) | static inline void ee_d_paddsb(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_paddsh (line 197) | static inline void ee_d_paddsh(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_paddsw (line 198) | static inline void ee_d_paddsw(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_paddub (line 199) | static inline void ee_d_paddub(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_padduh (line 200) | static inline void ee_d_padduh(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_padduw (line 201) | static inline void ee_d_padduw(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_paddw (line 202) | static inline void ee_d_paddw(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_padsbh (line 203) | static inline void ee_d_padsbh(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_pand (line 204) | static inline void ee_d_pand(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_pceqb (line 205) | static inline void ee_d_pceqb(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_pceqh (line 206) | static inline void ee_d_pceqh(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_pceqw (line 207) | static inline void ee_d_pceqw(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_pcgtb (line 208) | static inline void ee_d_pcgtb(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_pcgth (line 209) | static inline void ee_d_pcgth(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_pcgtw (line 210) | static inline void ee_d_pcgtw(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_pcpyh (line 211) | static inline void ee_d_pcpyh(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_pcpyld (line 212) | static inline void ee_d_pcpyld(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_pcpyud (line 213) | static inline void ee_d_pcpyud(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_pdivbw (line 214) | static inline void ee_d_pdivbw(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_pdivuw (line 215) | static inline void ee_d_pdivuw(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_pdivw (line 216) | static inline void ee_d_pdivw(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_pexch (line 217) | static inline void ee_d_pexch(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_pexcw (line 218) | static inline void ee_d_pexcw(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_pexeh (line 219) | static inline void ee_d_pexeh(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_pexew (line 220) | static inline void ee_d_pexew(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_pext5 (line 221) | static inline void ee_d_pext5(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_pextlb (line 222) | static inline void ee_d_pextlb(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_pextlh (line 223) | static inline void ee_d_pextlh(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_pextlw (line 224) | static inline void ee_d_pextlw(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_pextub (line 225) | static inline void ee_d_pextub(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_pextuh (line 226) | static inline void ee_d_pextuh(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_pextuw (line 227) | static inline void ee_d_pextuw(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_phmadh (line 228) | static inline void ee_d_phmadh(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_phmsbh (line 229) | static inline void ee_d_phmsbh(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_pinteh (line 230) | static inline void ee_d_pinteh(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_pinth (line 231) | static inline void ee_d_pinth(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_plzcw (line 232) | static inline void ee_d_plzcw(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_pmaddh (line 233) | static inline void ee_d_pmaddh(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_pmadduw (line 234) | static inline void ee_d_pmadduw(uint32_t opcode) { ptr += sprintf(ptr, "...
  function ee_d_pmaddw (line 235) | static inline void ee_d_pmaddw(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_pmaxh (line 236) | static inline void ee_d_pmaxh(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_pmaxw (line 237) | static inline void ee_d_pmaxw(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_pmfhi (line 238) | static inline void ee_d_pmfhi(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_pmfhllw (line 239) | static inline void ee_d_pmfhllw(uint32_t opcode) { ptr += sprintf(ptr, "...
  function ee_d_pmfhluw (line 240) | static inline void ee_d_pmfhluw(uint32_t opcode) { ptr += sprintf(ptr, "...
  function ee_d_pmfhlslw (line 241) | static inline void ee_d_pmfhlslw(uint32_t opcode) { ptr += sprintf(ptr, ...
  function ee_d_pmfhllh (line 242) | static inline void ee_d_pmfhllh(uint32_t opcode) { ptr += sprintf(ptr, "...
  function ee_d_pmfhlsh (line 243) | static inline void ee_d_pmfhlsh(uint32_t opcode) { ptr += sprintf(ptr, "...
  function ee_d_pmflo (line 244) | static inline void ee_d_pmflo(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_pminh (line 245) | static inline void ee_d_pminh(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_pminw (line 246) | static inline void ee_d_pminw(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_pmsubh (line 247) | static inline void ee_d_pmsubh(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_pmsubw (line 248) | static inline void ee_d_pmsubw(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_pmthi (line 249) | static inline void ee_d_pmthi(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_pmthl (line 250) | static inline void ee_d_pmthl(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_pmtlo (line 251) | static inline void ee_d_pmtlo(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_pmulth (line 252) | static inline void ee_d_pmulth(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_pmultuw (line 253) | static inline void ee_d_pmultuw(uint32_t opcode) { ptr += sprintf(ptr, "...
  function ee_d_pmultw (line 254) | static inline void ee_d_pmultw(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_pnor (line 255) | static inline void ee_d_pnor(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_por (line 256) | static inline void ee_d_por(uint32_t opcode) { ptr += sprintf(ptr, "%-8s...
  function ee_d_ppac5 (line 257) | static inline void ee_d_ppac5(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_ppacb (line 258) | static inline void ee_d_ppacb(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_ppach (line 259) | static inline void ee_d_ppach(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_ppacw (line 260) | static inline void ee_d_ppacw(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_pref (line 261) | static inline void ee_d_pref(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_prevh (line 262) | static inline void ee_d_prevh(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_prot3w (line 263) | static inline void ee_d_prot3w(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_psllh (line 264) | static inline void ee_d_psllh(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_psllvw (line 265) | static inline void ee_d_psllvw(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_psllw (line 266) | static inline void ee_d_psllw(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_psrah (line 267) | static inline void ee_d_psrah(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_psravw (line 268) | static inline void ee_d_psravw(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_psraw (line 269) | static inline void ee_d_psraw(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_psrlh (line 270) | static inline void ee_d_psrlh(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_psrlvw (line 271) | static inline void ee_d_psrlvw(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_psrlw (line 272) | static inline void ee_d_psrlw(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_psubb (line 273) | static inline void ee_d_psubb(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_psubh (line 274) | static inline void ee_d_psubh(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_psubsb (line 275) | static inline void ee_d_psubsb(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_psubsh (line 276) | static inline void ee_d_psubsh(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_psubsw (line 277) | static inline void ee_d_psubsw(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_psubub (line 278) | static inline void ee_d_psubub(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_psubuh (line 279) | static inline void ee_d_psubuh(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_psubuw (line 280) | static inline void ee_d_psubuw(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_psubw (line 281) | static inline void ee_d_psubw(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_pxor (line 282) | static inline void ee_d_pxor(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_qfsrv (line 283) | static inline void ee_d_qfsrv(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_qmfc2 (line 284) | static inline void ee_d_qmfc2(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_qmtc2 (line 285) | static inline void ee_d_qmtc2(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_rsqrts (line 286) | static inline void ee_d_rsqrts(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_sb (line 287) | static inline void ee_d_sb(uint32_t opcode) { ptr += sprintf(ptr, "%-8s ...
  function ee_d_sd (line 288) | static inline void ee_d_sd(uint32_t opcode) { ptr += sprintf(ptr, "%-8s ...
  function ee_d_sdl (line 289) | static inline void ee_d_sdl(uint32_t opcode) { ptr += sprintf(ptr, "%-8s...
  function ee_d_sdr (line 290) | static inline void ee_d_sdr(uint32_t opcode) { ptr += sprintf(ptr, "%-8s...
  function ee_d_sh (line 291) | static inline void ee_d_sh(uint32_t opcode) { ptr += sprintf(ptr, "%-8s ...
  function ee_d_sll (line 292) | static inline void ee_d_sll(uint32_t opcode) { ptr += sprintf(ptr, "%-8s...
  function ee_d_sllv (line 293) | static inline void ee_d_sllv(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_slt (line 294) | static inline void ee_d_slt(uint32_t opcode) { ptr += sprintf(ptr, "%-8s...
  function ee_d_slti (line 295) | static inline void ee_d_slti(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_sltiu (line 296) | static inline void ee_d_sltiu(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_sltu (line 297) | static inline void ee_d_sltu(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_sq (line 298) | static inline void ee_d_sq(uint32_t opcode) { ptr += sprintf(ptr, "%-8s ...
  function ee_d_sqc2 (line 299) | static inline void ee_d_sqc2(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_sqrts (line 300) | static inline void ee_d_sqrts(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_sra (line 301) | static inline void ee_d_sra(uint32_t opcode) { ptr += sprintf(ptr, "%-8s...
  function ee_d_srav (line 302) | static inline void ee_d_srav(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_srl (line 303) | static inline void ee_d_srl(uint32_t opcode) { ptr += sprintf(ptr, "%-8s...
  function ee_d_srlv (line 304) | static inline void ee_d_srlv(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_sub (line 305) | static inline void ee_d_sub(uint32_t opcode) { ptr += sprintf(ptr, "%-8s...
  function ee_d_subas (line 306) | static inline void ee_d_subas(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_subs (line 307) | static inline void ee_d_subs(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_subu (line 308) | static inline void ee_d_subu(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_sw (line 309) | static inline void ee_d_sw(uint32_t opcode) { ptr += sprintf(ptr, "%-8s ...
  function ee_d_swc1 (line 310) | static inline void ee_d_swc1(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_swl (line 311) | static inline void ee_d_swl(uint32_t opcode) { ptr += sprintf(ptr, "%-8s...
  function ee_d_swr (line 312) | static inline void ee_d_swr(uint32_t opcode) { ptr += sprintf(ptr, "%-8s...
  function ee_d_sync (line 313) | static inline void ee_d_sync(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_syscall (line 314) | static inline void ee_d_syscall(uint32_t opcode) { ptr += sprintf(ptr, "...
  function ee_d_teq (line 315) | static inline void ee_d_teq(uint32_t opcode) { ptr += sprintf(ptr, "%-8s...
  function ee_d_teqi (line 316) | static inline void ee_d_teqi(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_tge (line 317) | static inline void ee_d_tge(uint32_t opcode) { ptr += sprintf(ptr, "%-8s...
  function ee_d_tgei (line 318) | static inline void ee_d_tgei(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_tgeiu (line 319) | static inline void ee_d_tgeiu(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_tgeu (line 320) | static inline void ee_d_tgeu(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_tlbp (line 321) | static inline void ee_d_tlbp(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_tlbr (line 322) | static inline void ee_d_tlbr(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_tlbwi (line 323) | static inline void ee_d_tlbwi(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_tlbwr (line 324) | static inline void ee_d_tlbwr(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_tlt (line 325) | static inline void ee_d_tlt(uint32_t opcode) { ptr += sprintf(ptr, "%-8s...
  function ee_d_tlti (line 326) | static inline void ee_d_tlti(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_tltiu (line 327) | static inline void ee_d_tltiu(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_tltu (line 328) | static inline void ee_d_tltu(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_tne (line 329) | static inline void ee_d_tne(uint32_t opcode) { ptr += sprintf(ptr, "%-8s...
  function ee_d_tnei (line 330) | static inline void ee_d_tnei(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_vabs (line 331) | static inline void ee_d_vabs(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_vadd (line 332) | static inline void ee_d_vadd(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_vadda (line 333) | static inline void ee_d_vadda(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_vaddai (line 334) | static inline void ee_d_vaddai(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_vaddaq (line 335) | static inline void ee_d_vaddaq(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_vaddaw (line 336) | static inline void ee_d_vaddaw(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_vaddax (line 337) | static inline void ee_d_vaddax(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_vadday (line 338) | static inline void ee_d_vadday(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_vaddaz (line 339) | static inline void ee_d_vaddaz(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_vaddi (line 340) | static inline void ee_d_vaddi(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_vaddq (line 341) | static inline void ee_d_vaddq(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_vaddw (line 342) | static inline void ee_d_vaddw(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_vaddx (line 343) | static inline void ee_d_vaddx(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_vaddy (line 344) | static inline void ee_d_vaddy(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_vaddz (line 345) | static inline void ee_d_vaddz(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_vcallms (line 346) | static inline void ee_d_vcallms(uint32_t opcode) { ptr += sprintf(ptr, "...
  function ee_d_vclipw (line 347) | static inline void ee_d_vclipw(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_vdiv (line 348) | static inline void ee_d_vdiv(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_vftoi0 (line 349) | static inline void ee_d_vftoi0(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_vftoi12 (line 350) | static inline void ee_d_vftoi12(uint32_t opcode) { ptr += sprintf(ptr, "...
  function ee_d_vftoi15 (line 351) | static inline void ee_d_vftoi15(uint32_t opcode) { ptr += sprintf(ptr, "...
  function ee_d_vftoi4 (line 352) | static inline void ee_d_vftoi4(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_viadd (line 353) | static inline void ee_d_viadd(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_viaddi (line 354) | static inline void ee_d_viaddi(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_viand (line 355) | static inline void ee_d_viand(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_vilwr (line 356) | static inline void ee_d_vilwr(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_vior (line 357) | static inline void ee_d_vior(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_visub (line 358) | static inline void ee_d_visub(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_viswr (line 359) | static inline void ee_d_viswr(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_vitof0 (line 360) | static inline void ee_d_vitof0(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_vitof12 (line 361) | static inline void ee_d_vitof12(uint32_t opcode) { ptr += sprintf(ptr, "...
  function ee_d_vitof15 (line 362) | static inline void ee_d_vitof15(uint32_t opcode) { ptr += sprintf(ptr, "...
  function ee_d_vitof4 (line 363) | static inline void ee_d_vitof4(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_vlqd (line 364) | static inline void ee_d_vlqd(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_vlqi (line 365) | static inline void ee_d_vlqi(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_vmadd (line 366) | static inline void ee_d_vmadd(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_vmadda (line 367) | static inline void ee_d_vmadda(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_vmaddai (line 368) | static inline void ee_d_vmaddai(uint32_t opcode) { ptr += sprintf(ptr, "...
  function ee_d_vmaddaq (line 369) | static inline void ee_d_vmaddaq(uint32_t opcode) { ptr += sprintf(ptr, "...
  function ee_d_vmaddaw (line 370) | static inline void ee_d_vmaddaw(uint32_t opcode) { ptr += sprintf(ptr, "...
  function ee_d_vmaddax (line 371) | static inline void ee_d_vmaddax(uint32_t opcode) { ptr += sprintf(ptr, "...
  function ee_d_vmadday (line 372) | static inline void ee_d_vmadday(uint32_t opcode) { ptr += sprintf(ptr, "...
  function ee_d_vmaddaz (line 373) | static inline void ee_d_vmaddaz(uint32_t opcode) { ptr += sprintf(ptr, "...
  function ee_d_vmaddi (line 374) | static inline void ee_d_vmaddi(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_vmaddq (line 375) | static inline void ee_d_vmaddq(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_vmaddw (line 376) | static inline void ee_d_vmaddw(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_vmaddx (line 377) | static inline void ee_d_vmaddx(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_vmaddy (line 378) | static inline void ee_d_vmaddy(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_vmaddz (line 379) | static inline void ee_d_vmaddz(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_vmax (line 380) | static inline void ee_d_vmax(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_vmaxi (line 381) | static inline void ee_d_vmaxi(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_vmaxw (line 382) | static inline void ee_d_vmaxw(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_vmaxx (line 383) | static inline void ee_d_vmaxx(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_vmaxy (line 384) | static inline void ee_d_vmaxy(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_vmaxz (line 385) | static inline void ee_d_vmaxz(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_vmfir (line 386) | static inline void ee_d_vmfir(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_vmini (line 387) | static inline void ee_d_vmini(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_vminii (line 388) | static inline void ee_d_vminii(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_vminiw (line 389) | static inline void ee_d_vminiw(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_vminix (line 390) | static inline void ee_d_vminix(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_vminiy (line 391) | static inline void ee_d_vminiy(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_vminiz (line 392) | static inline void ee_d_vminiz(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_vmove (line 393) | static inline void ee_d_vmove(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_vmr32 (line 394) | static inline void ee_d_vmr32(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_vmsub (line 395) | static inline void ee_d_vmsub(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_vmsuba (line 396) | static inline void ee_d_vmsuba(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_vmsubai (line 397) | static inline void ee_d_vmsubai(uint32_t opcode) { ptr += sprintf(ptr, "...
  function ee_d_vmsubaq (line 398) | static inline void ee_d_vmsubaq(uint32_t opcode) { ptr += sprintf(ptr, "...
  function ee_d_vmsubaw (line 399) | static inline void ee_d_vmsubaw(uint32_t opcode) { ptr += sprintf(ptr, "...
  function ee_d_vmsubax (line 400) | static inline void ee_d_vmsubax(uint32_t opcode) { ptr += sprintf(ptr, "...
  function ee_d_vmsubay (line 401) | static inline void ee_d_vmsubay(uint32_t opcode) { ptr += sprintf(ptr, "...
  function ee_d_vmsubaz (line 402) | static inline void ee_d_vmsubaz(uint32_t opcode) { ptr += sprintf(ptr, "...
  function ee_d_vmsubi (line 403) | static inline void ee_d_vmsubi(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_vmsubq (line 404) | static inline void ee_d_vmsubq(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_vmsubw (line 405) | static inline void ee_d_vmsubw(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_vmsubx (line 406) | static inline void ee_d_vmsubx(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_vmsuby (line 407) | static inline void ee_d_vmsuby(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_vmsubz (line 408) | static inline void ee_d_vmsubz(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_vmtir (line 409) | static inline void ee_d_vmtir(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_vmul (line 410) | static inline void ee_d_vmul(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_vmula (line 411) | static inline void ee_d_vmula(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_vmulai (line 412) | static inline void ee_d_vmulai(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_vmulaq (line 413) | static inline void ee_d_vmulaq(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_vmulaw (line 414) | static inline void ee_d_vmulaw(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_vmulax (line 415) | static inline void ee_d_vmulax(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_vmulay (line 416) | static inline void ee_d_vmulay(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_vmulaz (line 417) | static inline void ee_d_vmulaz(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_vmuli (line 418) | static inline void ee_d_vmuli(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_vmulq (line 419) | static inline void ee_d_vmulq(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_vmulw (line 420) | static inline void ee_d_vmulw(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_vmulx (line 421) | static inline void ee_d_vmulx(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_vmuly (line 422) | static inline void ee_d_vmuly(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_vmulz (line 423) | static inline void ee_d_vmulz(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_vnop (line 424) | static inline void ee_d_vnop(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_vopmsub (line 425) | static inline void ee_d_vopmsub(uint32_t opcode) { ptr += sprintf(ptr, "...
  function ee_d_vopmula (line 426) | static inline void ee_d_vopmula(uint32_t opcode) { ptr += sprintf(ptr, "...
  function ee_d_vrget (line 427) | static inline void ee_d_vrget(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_vrinit (line 428) | static inline void ee_d_vrinit(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_vrnext (line 429) | static inline void ee_d_vrnext(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_vrsqrt (line 430) | static inline void ee_d_vrsqrt(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_vrxor (line 431) | static inline void ee_d_vrxor(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_vsqd (line 432) | static inline void ee_d_vsqd(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_vsqi (line 433) | static inline void ee_d_vsqi(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_vsqrt (line 434) | static inline void ee_d_vsqrt(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_vsub (line 435) | static inline void ee_d_vsub(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_vsuba (line 436) | static inline void ee_d_vsuba(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_vsubai (line 437) | static inline void ee_d_vsubai(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_vsubaq (line 438) | static inline void ee_d_vsubaq(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_vsubaw (line 439) | static inline void ee_d_vsubaw(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_vsubax (line 440) | static inline void ee_d_vsubax(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_vsubay (line 441) | static inline void ee_d_vsubay(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_vsubaz (line 442) | static inline void ee_d_vsubaz(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_vsubi (line 443) | static inline void ee_d_vsubi(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_vsubq (line 444) | static inline void ee_d_vsubq(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_vsubw (line 445) | static inline void ee_d_vsubw(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_vsubx (line 446) | static inline void ee_d_vsubx(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_vsuby (line 447) | static inline void ee_d_vsuby(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_vsubz (line 448) | static inline void ee_d_vsubz(uint32_t opcode) { ptr += sprintf(ptr, "%-...
  function ee_d_vwaitq (line 449) | static inline void ee_d_vwaitq(uint32_t opcode) { ptr += sprintf(ptr, "%...
  function ee_d_xor (line 450) | static inline void ee_d_xor(uint32_t opcode) { ptr += sprintf(ptr, "%-8s...
  function ee_d_xori (line 451) | static inline void ee_d_xori(uint32_t opcode) { ptr += sprintf(ptr, "%-8...
  function ee_d_invalid (line 452) | static inline void ee_d_invalid(uint32_t opcode) { ptr += sprintf(ptr, "...
  type ee_dis_state (line 454) | struct ee_dis_state

FILE: src/ee/ee_dis.h
  type ee_dis_state (line 10) | struct ee_dis_state {
  type ee_dis_state (line 16) | struct ee_dis_state

FILE: src/ee/ee_uncached.c
  function fast_abs32 (line 37) | static inline int fast_abs32(int a) {
  function fast_abs16 (line 43) | static inline int16_t fast_abs16(int16_t a) {
  function saturate16 (line 49) | static inline int16_t saturate16(int32_t word) {
  function __m128i (line 60) | static inline __m128i _mm_adds_epi32(__m128i a, __m128i b) {
  function __m128i (line 74) | static inline __m128i _mm_adds_epu32(__m128i a, __m128i b) {
  function unpack_5551_8888 (line 84) | static inline uint32_t unpack_5551_8888(uint32_t v) {
  function ee_print_disassembly (line 141) | static inline void ee_print_disassembly(struct ee_state* ee) {
  function ee_get_segment (line 152) | static inline int ee_get_segment(uint32_t virt) {
  function fpu_cvtf (line 172) | static inline float fpu_cvtf(float f) {
  function fpu_cvtsw (line 192) | static inline float fpu_cvtsw(union ee_fpu_reg* reg) {
  function fpu_cvtws (line 206) | static inline void fpu_cvtws(union ee_fpu_reg* d, union ee_fpu_reg* s) {
  function fpu_check_overflow (line 215) | static inline int fpu_check_overflow(struct ee_state* ee, union ee_fpu_r...
  function fpu_check_underflow (line 228) | static inline int fpu_check_underflow(struct ee_state* ee, union ee_fpu_...
  function fpu_check_overflow_no_flags (line 241) | static inline int fpu_check_overflow_no_flags(struct ee_state* ee, union...
  function fpu_check_underflow_no_flags (line 251) | static inline int fpu_check_underflow_no_flags(struct ee_state* ee, unio...
  function fpu_max (line 261) | static inline int fpu_max(int32_t a, int32_t b) {
  function fpu_min (line 265) | static inline int fpu_min(int32_t a, int32_t b) {
  type ee_vtlb_entry (line 269) | struct ee_vtlb_entry
  type ee_state (line 269) | struct ee_state
  type ee_vtlb_entry (line 270) | struct ee_vtlb_entry
  function ee_translate_virt (line 277) | static inline int ee_translate_virt(struct ee_state* ee, uint32_t virt, ...
  function uint128_t (line 363) | static inline uint128_t bus_read128(struct ee_state* ee, uint32_t addr) {
  function bus_write128 (line 385) | static inline void bus_write128(struct ee_state* ee, uint32_t addr, uint...
  function ee_skip_fmv (line 406) | static inline int ee_skip_fmv(struct ee_state* ee, uint32_t addr) {
  function ee_set_pc (line 427) | static inline void ee_set_pc(struct ee_state* ee, uint32_t addr) {
  function ee_set_pc_delayed (line 435) | static inline void ee_set_pc_delayed(struct ee_state* ee, uint32_t addr) {
  function ee_exception_level1 (line 443) | void ee_exception_level1(struct ee_state* ee, uint32_t cause) {
  function ee_exception_level2 (line 470) | static inline void ee_exception_level2(struct ee_state* ee, uint32_t cau...
  function ee_check_irq (line 502) | static inline void ee_check_irq(struct ee_state* ee) {
  function ee_set_int0 (line 523) | void ee_set_int0(struct ee_state* ee, int v) {
  function ee_set_int1 (line 531) | void ee_set_int1(struct ee_state* ee, int v) {
  function ee_set_cpcond0 (line 539) | void ee_set_cpcond0(struct ee_state* ee, int v) {
  function ee_i_abss (line 543) | static inline void ee_i_abss(struct ee_state* ee) {
  function ee_i_add (line 547) | static inline void ee_i_add(struct ee_state* ee) {
  function ee_i_addas (line 560) | static inline void ee_i_addas(struct ee_state* ee) {
  function ee_i_addi (line 568) | static inline void ee_i_addi(struct ee_state* ee) {
  function ee_i_addiu (line 579) | static inline void ee_i_addiu(struct ee_state* ee) {
  function ee_i_adds (line 582) | static inline void ee_i_adds(struct ee_state* ee) {
  function ee_i_addu (line 592) | static inline void ee_i_addu(struct ee_state* ee) {
  function ee_i_and (line 595) | static inline void ee_i_and(struct ee_state* ee) {
  function ee_i_andi (line 598) | static inline void ee_i_andi(struct ee_state* ee) {
  function ee_i_bc0f (line 601) | static inline void ee_i_bc0f(struct ee_state* ee) {
  function ee_i_bc0fl (line 604) | static inline void ee_i_bc0fl(struct ee_state* ee) {
  function ee_i_bc0t (line 607) | static inline void ee_i_bc0t(struct ee_state* ee) {
  function ee_i_bc0tl (line 610) | static inline void ee_i_bc0tl(struct ee_state* ee) {
  function ee_i_bc1f (line 613) | static inline void ee_i_bc1f(struct ee_state* ee) {
  function ee_i_bc1fl (line 616) | static inline void ee_i_bc1fl(struct ee_state* ee) {
  function ee_i_bc1t (line 619) | static inline void ee_i_bc1t(struct ee_state* ee) {
  function ee_i_bc1tl (line 622) | static inline void ee_i_bc1tl(struct ee_state* ee) {
  function ee_i_bc2f (line 625) | static inline void ee_i_bc2f(struct ee_state* ee) { BRANCH(1, EE_D_SI16); }
  function ee_i_bc2fl (line 626) | static inline void ee_i_bc2fl(struct ee_state* ee) { BRANCH_LIKELY(1, EE...
  function ee_i_bc2t (line 627) | static inline void ee_i_bc2t(struct ee_state* ee) { BRANCH(0, EE_D_SI16); }
  function ee_i_bc2tl (line 628) | static inline void ee_i_bc2tl(struct ee_state* ee) { BRANCH_LIKELY(0, EE...
  function ee_i_beq (line 629) | static inline void ee_i_beq(struct ee_state* ee) {
  function ee_i_beql (line 632) | static inline void ee_i_beql(struct ee_state* ee) {
  function ee_i_bgez (line 635) | static inline void ee_i_bgez(struct ee_state* ee) {
  function ee_i_bgezal (line 638) | static inline void ee_i_bgezal(struct ee_state* ee) {
  function ee_i_bgezall (line 643) | static inline void ee_i_bgezall(struct ee_state* ee) {
  function ee_i_bgezl (line 648) | static inline void ee_i_bgezl(struct ee_state* ee) {
  function ee_i_bgtz (line 651) | static inline void ee_i_bgtz(struct ee_state* ee) {
  function ee_i_bgtzl (line 654) | static inline void ee_i_bgtzl(struct ee_state* ee) {
  function ee_i_blez (line 657) | static inline void ee_i_blez(struct ee_state* ee) {
  function ee_i_blezl (line 660) | static inline void ee_i_blezl(struct ee_state* ee) {
  function ee_i_bltz (line 663) | static inline void ee_i_bltz(struct ee_state* ee) {
  function ee_i_bltzal (line 666) | static inline void ee_i_bltzal(struct ee_state* ee) {
  function ee_i_bltzall (line 671) | static inline void ee_i_bltzall(struct ee_state* ee) {
  function ee_i_bltzl (line 676) | static inline void ee_i_bltzl(struct ee_state* ee) {
  function ee_i_bne (line 679) | static inline void ee_i_bne(struct ee_state* ee) {
  function ee_i_bnel (line 682) | static inline void ee_i_bnel(struct ee_state* ee) {
  function ee_i_break (line 685) | static inline void ee_i_break(struct ee_state* ee) {
  function ee_i_cache (line 688) | static inline void ee_i_cache(struct ee_state* ee) {
  function ee_i_ceq (line 691) | static inline void ee_i_ceq(struct ee_state* ee) {
  function ee_i_cf (line 698) | static inline void ee_i_cf(struct ee_state* ee) {
  function ee_i_cfc1 (line 701) | static inline void ee_i_cfc1(struct ee_state* ee) {
  function ee_i_cfc2 (line 704) | static inline void ee_i_cfc2(struct ee_state* ee) {
  function ee_i_cle (line 707) | static inline void ee_i_cle(struct ee_state* ee) {
  function ee_i_clt (line 714) | static inline void ee_i_clt(struct ee_state* ee) {
  function ee_i_ctc1 (line 721) | static inline void ee_i_ctc1(struct ee_state* ee) {
  function ee_i_ctc2 (line 727) | static inline void ee_i_ctc2(struct ee_state* ee) {
  function ee_i_cvts (line 752) | static inline void ee_i_cvts(struct ee_state* ee) {
  function ee_i_cvtw (line 756) | static inline void ee_i_cvtw(struct ee_state* ee) {
  function ee_i_dadd (line 759) | static inline void ee_i_dadd(struct ee_state* ee) {
  function ee_i_daddi (line 768) | static inline void ee_i_daddi(struct ee_state* ee) {
  function ee_i_daddiu (line 777) | static inline void ee_i_daddiu(struct ee_state* ee) {
  function ee_i_daddu (line 780) | static inline void ee_i_daddu(struct ee_state* ee) {
  function ee_i_di (line 783) | static inline void ee_i_di(struct ee_state* ee) {
  function ee_i_div (line 792) | static inline void ee_i_div(struct ee_state* ee) {
  function ee_i_div1 (line 807) | static inline void ee_i_div1(struct ee_state* ee) {
  function ee_i_divs (line 822) | static inline void ee_i_divs(struct ee_state* ee) {
  function ee_i_divu (line 850) | static inline void ee_i_divu(struct ee_state* ee) {
  function ee_i_divu1 (line 864) | static inline void ee_i_divu1(struct ee_state* ee) {
  function ee_i_dsll (line 878) | static inline void ee_i_dsll(struct ee_state* ee) {
  function ee_i_dsll32 (line 881) | static inline void ee_i_dsll32(struct ee_state* ee) {
  function ee_i_dsllv (line 884) | static inline void ee_i_dsllv(struct ee_state* ee) {
  function ee_i_dsra (line 887) | static inline void ee_i_dsra(struct ee_state* ee) {
  function ee_i_dsra32 (line 890) | static inline void ee_i_dsra32(struct ee_state* ee) {
  function ee_i_dsrav (line 893) | static inline void ee_i_dsrav(struct ee_state* ee) {
  function ee_i_dsrl (line 896) | static inline void ee_i_dsrl(struct ee_state* ee) {
  function ee_i_dsrl32 (line 899) | static inline void ee_i_dsrl32(struct ee_state* ee) {
  function ee_i_dsrlv (line 902) | static inline void ee_i_dsrlv(struct ee_state* ee) {
  function ee_i_dsub (line 905) | static inline void ee_i_dsub(struct ee_state* ee) {
  function ee_i_dsubu (line 914) | static inline void ee_i_dsubu(struct ee_state* ee) {
  function ee_i_ei (line 917) | static inline void ee_i_ei(struct ee_state* ee) {
  function ee_i_eret (line 926) | static inline void ee_i_eret(struct ee_state* ee) {
  function ee_i_j (line 937) | static inline void ee_i_j(struct ee_state* ee) {
  function ee_i_jal (line 940) | static inline void ee_i_jal(struct ee_state* ee) {
  function ee_i_jalr (line 945) | static inline void ee_i_jalr(struct ee_state* ee) {
  function ee_i_jr (line 952) | static inline void ee_i_jr(struct ee_state* ee) {
  function ee_i_lb (line 955) | static inline void ee_i_lb(struct ee_state* ee) {
  function ee_i_lbu (line 958) | static inline void ee_i_lbu(struct ee_state* ee) {
  function ee_i_ld (line 961) | static inline void ee_i_ld(struct ee_state* ee) {
  function ee_i_ldl (line 964) | static inline void ee_i_ldl(struct ee_state* ee) {
  function ee_i_ldr (line 977) | static inline void ee_i_ldr(struct ee_state* ee) {
  function ee_i_lh (line 990) | static inline void ee_i_lh(struct ee_state* ee) {
  function ee_i_lhu (line 993) | static inline void ee_i_lhu(struct ee_state* ee) {
  function ee_i_lq (line 996) | static inline void ee_i_lq(struct ee_state* ee) {
  function ee_i_lqc2 (line 999) | static inline void ee_i_lqc2(struct ee_state* ee) {
  function ee_i_lui (line 1006) | static inline void ee_i_lui(struct ee_state* ee) {
  function ee_i_lw (line 1009) | static inline void ee_i_lw(struct ee_state* ee) {
  function ee_i_lwc1 (line 1012) | static inline void ee_i_lwc1(struct ee_state* ee) {
  function ee_i_lwl (line 1021) | static inline void ee_i_lwl(struct ee_state* ee) {
  function ee_i_lwr (line 1030) | static inline void ee_i_lwr(struct ee_state* ee) {
  function ee_i_lwu (line 1049) | static inline void ee_i_lwu(struct ee_state* ee) {
  function ee_i_madd (line 1052) | static inline void ee_i_madd(struct ee_state* ee) {
  function ee_i_madd1 (line 1063) | static inline void ee_i_madd1(struct ee_state* ee) {
  function ee_i_maddas (line 1074) | static inline void ee_i_maddas(struct ee_state* ee) {
  function ee_i_madds (line 1082) | static inline void ee_i_madds(struct ee_state* ee) {
  function ee_i_maddu (line 1096) | static inline void ee_i_maddu(struct ee_state* ee) {
  function ee_i_maddu1 (line 1107) | static inline void ee_i_maddu1(struct ee_state* ee) {
  function ee_i_maxs (line 1118) | static inline void ee_i_maxs(struct ee_state* ee) {
  function ee_i_mfc0 (line 1123) | static inline void ee_i_mfc0(struct ee_state* ee) {
  function ee_i_mfc1 (line 1126) | static inline void ee_i_mfc1(struct ee_state* ee) {
  function ee_i_mfhi (line 1129) | static inline void ee_i_mfhi(struct ee_state* ee) {
  function ee_i_mfhi1 (line 1132) | static inline void ee_i_mfhi1(struct ee_state* ee) {
  function ee_i_mflo (line 1135) | static inline void ee_i_mflo(struct ee_state* ee) {
  function ee_i_mflo1 (line 1138) | static inline void ee_i_mflo1(struct ee_state* ee) {
  function ee_i_mfsa (line 1141) | static inline void ee_i_mfsa(struct ee_state* ee) {
  function ee_i_mins (line 1144) | static inline void ee_i_mins(struct ee_state* ee) {
  function ee_i_movn (line 1149) | static inline void ee_i_movn(struct ee_state* ee) {
  function ee_i_movs (line 1152) | static inline void ee_i_movs(struct ee_state* ee) {
  function ee_i_movz (line 1155) | static inline void ee_i_movz(struct ee_state* ee) {
  function ee_i_msubas (line 1158) | static inline void ee_i_msubas(struct ee_state* ee) {
  function ee_i_msubs (line 1166) | static inline void ee_i_msubs(struct ee_state* ee) {
  function ee_i_mtc0 (line 1180) | static inline void ee_i_mtc0(struct ee_state* ee) {
  function ee_i_mtc1 (line 1183) | static inline void ee_i_mtc1(struct ee_state* ee) {
  function ee_i_mthi (line 1186) | static inline void ee_i_mthi(struct ee_state* ee) {
  function ee_i_mthi1 (line 1189) | static inline void ee_i_mthi1(struct ee_state* ee) {
  function ee_i_mtlo (line 1192) | static inline void ee_i_mtlo(struct ee_state* ee) {
  function ee_i_mtlo1 (line 1195) | static inline void ee_i_mtlo1(struct ee_state* ee) {
  function ee_i_mtsa (line 1198) | static inline void ee_i_mtsa(struct ee_state* ee) {
  function ee_i_mtsab (line 1201) | static inline void ee_i_mtsab(struct ee_state* ee) {
  function ee_i_mtsah (line 1204) | static inline void ee_i_mtsah(struct ee_state* ee) {
  function ee_i_mulas (line 1207) | static inline void ee_i_mulas(struct ee_state* ee) {
  function ee_i_muls (line 1215) | static inline void ee_i_muls(struct ee_state* ee) {
  function ee_i_mult (line 1225) | static inline void ee_i_mult(struct ee_state* ee) {
  function ee_i_mult1 (line 1233) | static inline void ee_i_mult1(struct ee_state* ee) {
  function ee_i_multu (line 1241) | static inline void ee_i_multu(struct ee_state* ee) {
  function ee_i_multu1 (line 1249) | static inline void ee_i_multu1(struct ee_state* ee) {
  function ee_i_negs (line 1257) | static inline void ee_i_negs(struct ee_state* ee) {
  function ee_i_nor (line 1262) | static inline void ee_i_nor(struct ee_state* ee) {
  function ee_i_or (line 1265) | static inline void ee_i_or(struct ee_state* ee) {
  function ee_i_ori (line 1268) | static inline void ee_i_ori(struct ee_state* ee) {
  function ee_i_pabsh (line 1271) | static inline void ee_i_pabsh(struct ee_state* ee) {
  function ee_i_pabsw (line 1288) | static inline void ee_i_pabsw(struct ee_state* ee) {
  function ee_i_paddb (line 1305) | static inline void ee_i_paddb(struct ee_state* ee) {
  function ee_i_paddh (line 1322) | static inline void ee_i_paddh(struct ee_state* ee) {
  function ee_i_paddsb (line 1339) | static inline void ee_i_paddsb(struct ee_state* ee) {
  function ee_i_paddsh (line 1357) | static inline void ee_i_paddsh(struct ee_state* ee) {
  function ee_i_paddsw (line 1375) | static inline void ee_i_paddsw(struct ee_state* ee) {
  function ee_i_paddub (line 1393) | static inline void ee_i_paddub(struct ee_state* ee) {
  function ee_i_padduh (line 1411) | static inline void ee_i_padduh(struct ee_state* ee) {
  function ee_i_padduw (line 1429) | static inline void ee_i_padduw(struct ee_state* ee) {
  function ee_i_paddw (line 1447) | static inline void ee_i_paddw(struct ee_state* ee) {
  function ee_i_padsbh (line 1464) | static inline void ee_i_padsbh(struct ee_state* ee) {
  function ee_i_pand (line 1488) | static inline void ee_i_pand(struct ee_state* ee) {
  function ee_i_pceqb (line 1504) | static inline void ee_i_pceqb(struct ee_state* ee) {
  function ee_i_pceqh (line 1521) | static inline void ee_i_pceqh(struct ee_state* ee) {
  function ee_i_pceqw (line 1538) | static inline void ee_i_pceqw(struct ee_state* ee) {
  function ee_i_pcgtb (line 1555) | static inline void ee_i_pcgtb(struct ee_state* ee) {
  function ee_i_pcgth (line 1572) | static inline void ee_i_pcgth(struct ee_state* ee) {
  function ee_i_pcgtw (line 1589) | static inline void ee_i_pcgtw(struct ee_state* ee) {
  function ee_i_pcpyh (line 1606) | static inline void ee_i_pcpyh(struct ee_state* ee) {
  function ee_i_pcpyld (line 1634) | static inline void ee_i_pcpyld(struct ee_state* ee) {
  function ee_i_pcpyud (line 1650) | static inline void ee_i_pcpyud(struct ee_state* ee) {
  function ee_i_pdivbw (line 1658) | static inline void ee_i_pdivbw(struct ee_state* ee) { printf("ee: pdivbw...
  function ee_i_pdivuw (line 1659) | static inline void ee_i_pdivuw(struct ee_state* ee) { printf("ee: pdivuw...
  function ee_i_pdivw (line 1660) | static inline void ee_i_pdivw(struct ee_state* ee) { printf("ee: pdivw u...
  function ee_i_pexch (line 1661) | static inline void ee_i_pexch(struct ee_state* ee) {
  function ee_i_pexcw (line 1674) | static inline void ee_i_pexcw(struct ee_state* ee) {
  function ee_i_pexeh (line 1683) | static inline void ee_i_pexeh(struct ee_state* ee) {
  function ee_i_pexew (line 1696) | static inline void ee_i_pexew(struct ee_state* ee) {
  function ee_i_pext5 (line 1705) | static inline void ee_i_pext5(struct ee_state* ee) {
  function ee_i_pextlb (line 1714) | static inline void ee_i_pextlb(struct ee_state* ee) {
  function ee_i_pextlh (line 1736) | static inline void ee_i_pextlh(struct ee_state* ee) {
  function ee_i_pextlw (line 1750) | static inline void ee_i_pextlw(struct ee_state* ee) {
  function ee_i_pextub (line 1760) | static inline void ee_i_pextub(struct ee_state* ee) {
  function ee_i_pextuh (line 1782) | static inline void ee_i_pextuh(struct ee_state* ee) {
  function ee_i_pextuw (line 1796) | static inline void ee_i_pextuw(struct ee_state* ee) {
  function ee_i_phmadh (line 1806) | static inline void ee_i_phmadh(struct ee_state* ee) { printf("ee: phmadh...
  function ee_i_phmsbh (line 1807) | static inline void ee_i_phmsbh(struct ee_state* ee) { printf("ee: phmsbh...
  function ee_i_pinteh (line 1808) | static inline void ee_i_pinteh(struct ee_state* ee) {
  function ee_i_pinth (line 1822) | static inline void ee_i_pinth(struct ee_state* ee) {
  function ee_i_plzcw (line 1836) | static inline void ee_i_plzcw(struct ee_state* ee) {
  function ee_i_pmaddh (line 1847) | static inline void ee_i_pmaddh(struct ee_state* ee) {
  function ee_i_pmadduw (line 1883) | static inline void ee_i_pmadduw(struct ee_state* ee) { printf("ee: pmadd...
  function ee_i_pmaddw (line 1884) | static inline void ee_i_pmaddw(struct ee_state* ee) { printf("ee: pmaddw...
  function ee_i_pmaxh (line 1885) | static inline void ee_i_pmaxh(struct ee_state* ee) {
  function ee_i_pmaxw (line 1899) | static inline void ee_i_pmaxw(struct ee_state* ee) {
  function ee_i_pmfhi (line 1909) | static inline void ee_i_pmfhi(struct ee_state* ee) {
  function ee_i_pmfhllw (line 1912) | static inline void ee_i_pmfhllw(struct ee_state* ee) {
  function ee_i_pmfhluw (line 1920) | static inline void ee_i_pmfhluw(struct ee_state* ee) {
  function ee_i_pmfhlslw (line 1928) | static inline void ee_i_pmfhlslw(struct ee_state* ee) { printf("ee: pmfh...
  function ee_i_pmfhllh (line 1929) | static inline void ee_i_pmfhllh(struct ee_state* ee) {
  function ee_i_pmfhlsh (line 1942) | static inline void ee_i_pmfhlsh(struct ee_state* ee) {
  function ee_i_pmflo (line 1954) | static inline void ee_i_pmflo(struct ee_state* ee) {
  function ee_i_pminh (line 1957) | static inline void ee_i_pminh(struct ee_state* ee) {
  function ee_i_pminw (line 1971) | static inline void ee_i_pminw(struct ee_state* ee) {
  function ee_i_pmsubh (line 1981) | static inline void ee_i_pmsubh(struct ee_state* ee) { printf("ee: pmsubh...
  function ee_i_pmsubw (line 1982) | static inline void ee_i_pmsubw(struct ee_state* ee) { printf("ee: pmsubw...
  function ee_i_pmthi (line 1983) | static inline void ee_i_pmthi(struct ee_state* ee) {
  function ee_i_pmthl (line 1986) | static inline void ee_i_pmthl(struct ee_state* ee) { printf("ee: pmthl u...
  function ee_i_pmtlo (line 1987) | static inline void ee_i_pmtlo(struct ee_state* ee) {
  function ee_i_pmulth (line 1990) | static inline void ee_i_pmulth(struct ee_state* ee) {
  function ee_i_pmultuw (line 2008) | static inline void ee_i_pmultuw(struct ee_state* ee) {
  function ee_i_pmultw (line 2021) | static inline void ee_i_pmultw(struct ee_state* ee) {
  function ee_i_pnor (line 2034) | static inline void ee_i_pnor(struct ee_state* ee) {
  function ee_i_por (line 2042) | static inline void ee_i_por(struct ee_state* ee) {
  function ee_i_ppac5 (line 2050) | static inline void ee_i_ppac5(struct ee_state* ee) {
  function ee_i_ppacb (line 2071) | static inline void ee_i_ppacb(struct ee_state* ee) {
  function ee_i_ppach (line 2093) | static inline void ee_i_ppach(struct ee_state* ee) {
  function ee_i_ppacw (line 2107) | static inline void ee_i_ppacw(struct ee_state* ee) {
  function ee_i_pref (line 2117) | static inline void ee_i_pref(struct ee_state* ee) {
  function ee_i_prevh (line 2120) | static inline void ee_i_prevh(struct ee_state* ee) {
  function ee_i_prot3w (line 2133) | static inline void ee_i_prot3w(struct ee_state* ee) {
  function ee_i_psllh (line 2142) | static inline void ee_i_psllh(struct ee_state* ee) {
  function ee_i_psllvw (line 2156) | static inline void ee_i_psllvw(struct ee_state* ee) { printf("ee: psllvw...
  function ee_i_psllw (line 2157) | static inline void ee_i_psllw(struct ee_state* ee) {
  function ee_i_psrah (line 2167) | static inline void ee_i_psrah(struct ee_state* ee) {
  function ee_i_psravw (line 2181) | static inline void ee_i_psravw(struct ee_state* ee) { printf("ee: psravw...
  function ee_i_psraw (line 2182) | static inline void ee_i_psraw(struct ee_state* ee) {
  function ee_i_psrlh (line 2192) | static inline void ee_i_psrlh(struct ee_state* ee) {
  function ee_i_psrlvw (line 2206) | static inline void ee_i_psrlvw(struct ee_state* ee) {
  function ee_i_psrlw (line 2214) | static inline void ee_i_psrlw(struct ee_state* ee) {
  function ee_i_psubb (line 2224) | static inline void ee_i_psubb(struct ee_state* ee) {
  function ee_i_psubh (line 2246) | static inline void ee_i_psubh(struct ee_state* ee) {
  function ee_i_psubsb (line 2260) | static inline void ee_i_psubsb(struct ee_state* ee) {
  function ee_i_psubsh (line 2299) | static inline void ee_i_psubsh(struct ee_state* ee) {
  function ee_i_psubsw (line 2322) | static inline void ee_i_psubsw(struct ee_state* ee) {
  function ee_i_psubub (line 2337) | static inline void ee_i_psubub(struct ee_state* ee) {
  function ee_i_psubuh (line 2376) | static inline void ee_i_psubuh(struct ee_state* ee) {
  function ee_i_psubuw (line 2399) | static inline void ee_i_psubuw(struct ee_state* ee) {
  function ee_i_psubw (line 2414) | static inline void ee_i_psubw(struct ee_state* ee) {
  function ee_i_pxor (line 2424) | static inline void ee_i_pxor(struct ee_state* ee) {
  function ee_i_qfsrv (line 2432) | static inline void ee_i_qfsrv(struct ee_state* ee) {
  function ee_i_qmfc2 (line 2462) | static inline void ee_i_qmfc2(struct ee_state* ee) {
  function ee_i_qmtc2 (line 2469) | static inline void ee_i_qmtc2(struct ee_state* ee) {
  function ee_i_rsqrts (line 2477) | static inline void ee_i_rsqrts(struct ee_state* ee) {
  function ee_i_sb (line 2501) | static inline void ee_i_sb(struct ee_state* ee) {
  function ee_i_sd (line 2504) | static inline void ee_i_sd(struct ee_state* ee) {
  function ee_i_sdl (line 2507) | static inline void ee_i_sdl(struct ee_state* ee) {
  function ee_i_sdr (line 2520) | static inline void ee_i_sdr(struct ee_state* ee) {
  function ee_i_sh (line 2533) | static inline void ee_i_sh(struct ee_state* ee) {
  function ee_i_sll (line 2536) | static inline void ee_i_sll(struct ee_state* ee) {
  function ee_i_sllv (line 2539) | static inline void ee_i_sllv(struct ee_state* ee) {
  function ee_i_slt (line 2542) | static inline void ee_i_slt(struct ee_state* ee) {
  function ee_i_slti (line 2545) | static inline void ee_i_slti(struct ee_state* ee) {
  function ee_i_sltiu (line 2548) | static inline void ee_i_sltiu(struct ee_state* ee) {
  function ee_i_sltu (line 2551) | static inline void ee_i_sltu(struct ee_state* ee) {
  function ee_i_sq (line 2554) | static inline void ee_i_sq(struct ee_state* ee) {
  function ee_i_sqc2 (line 2557) | static inline void ee_i_sqc2(struct ee_state* ee) {
  function ee_i_sqrts (line 2560) | static inline void ee_i_sqrts(struct ee_state* ee) {
  function ee_i_sra (line 2576) | static inline void ee_i_sra(struct ee_state* ee) {
  function ee_i_srav (line 2579) | static inline void ee_i_srav(struct ee_state* ee) {
  function ee_i_srl (line 2582) | static inline void ee_i_srl(struct ee_state* ee) {
  function ee_i_srlv (line 2585) | static inline void ee_i_srlv(struct ee_state* ee) {
  function ee_i_sub (line 2588) | static inline void ee_i_sub(struct ee_state* ee) {
  function ee_i_subas (line 2599) | static inline void ee_i_subas(struct ee_state* ee) {
  function ee_i_subs (line 2607) | static inline void ee_i_subs(struct ee_state* ee) {
  function ee_i_subu (line 2617) | static inline void ee_i_subu(struct ee_state* ee) {
  function ee_i_sw (line 2620) | static inline void ee_i_sw(struct ee_state* ee) {
  function ee_i_swc1 (line 2623) | static inline void ee_i_swc1(struct ee_state* ee) {
  function ee_i_swl (line 2626) | static inline void ee_i_swl(struct ee_state* ee) {
  function ee_i_swr (line 2639) | static inline void ee_i_swr(struct ee_state* ee) {
  function ee_i_sync (line 2652) | static inline void ee_i_sync(struct ee_state* ee) {
  function ee_i_syscall (line 2658) | static inline void ee_i_syscall(struct ee_state* ee) {
  function ee_i_teq (line 2669) | static inline void ee_i_teq(struct ee_state* ee) {
  function ee_i_teqi (line 2672) | static inline void ee_i_teqi(struct ee_state* ee) {
  function ee_i_tge (line 2675) | static inline void ee_i_tge(struct ee_state* ee) { printf("ee: tge unimp...
  function ee_i_tgei (line 2676) | static inline void ee_i_tgei(struct ee_state* ee) { printf("ee: tgei uni...
  function ee_i_tgeiu (line 2677) | static inline void ee_i_tgeiu(struct ee_state* ee) { printf("ee: tgeiu u...
  function ee_i_tgeu (line 2678) | static inline void ee_i_tgeu(struct ee_state* ee) { printf("ee: tgeu uni...
  function ee_i_tlbp (line 2679) | static inline void ee_i_tlbp(struct ee_state* ee) { printf("ee: tlbp uni...
  function ee_i_tlbr (line 2680) | static inline void ee_i_tlbr(struct ee_state* ee) { printf("ee: tlbr uni...
  function ee_i_tlbwi (line 2681) | static inline void ee_i_tlbwi(struct ee_state* ee) {
  function ee_i_tlbwr (line 2691) | static inline void ee_i_tlbwr(struct ee_state* ee) { return; printf("ee:...
  function ee_i_tlt (line 2692) | static inline void ee_i_tlt(struct ee_state* ee) { printf("ee: tlt unimp...
  function ee_i_tlti (line 2693) | static inline void ee_i_tlti(struct ee_state* ee) { printf("ee: tlti uni...
  function ee_i_tltiu (line 2694) | static inline void ee_i_tltiu(struct ee_state* ee) { printf("ee: tltiu u...
  function ee_i_tltu (line 2695) | static inline void ee_i_tltu(struct ee_state* ee) { printf("ee: tltu uni...
  function ee_i_tne (line 2696) | static inline void ee_i_tne(struct ee_state* ee) {
  function ee_i_tnei (line 2699) | static inline void ee_i_tnei(struct ee_state* ee) { printf("ee: tnei uni...
  function ee_i_vabs (line 2700) | static inline void ee_i_vabs(struct ee_state* ee) { VU_UPPER(abs) }
  function ee_i_vadd (line 2701) | static inline void ee_i_vadd(struct ee_state* ee) { VU_UPPER(add) }
  function ee_i_vadda (line 2702) | static inline void ee_i_vadda(struct ee_state* ee) { VU_UPPER(adda) }
  function ee_i_vaddai (line 2703) | static inline void ee_i_vaddai(struct ee_state* ee) { VU_UPPER(addai) }
  function ee_i_vaddaq (line 2704) | static inline void ee_i_vaddaq(struct ee_state* ee) { VU_UPPER(addaq) }
  function ee_i_vaddaw (line 2705) | static inline void ee_i_vaddaw(struct ee_state* ee) { VU_UPPER(addaw) }
  function ee_i_vaddax (line 2706) | static inline void ee_i_vaddax(struct ee_state* ee) { VU_UPPER(addax) }
  function ee_i_vadday (line 2707) | static inline void ee_i_vadday(struct ee_state* ee) { VU_UPPER(adday) }
  function ee_i_vaddaz (line 2708) | static inline void ee_i_vaddaz(struct ee_state* ee) { VU_UPPER(addaz) }
  function ee_i_vaddi (line 2709) | static inline void ee_i_vaddi(struct ee_state* ee) { VU_UPPER(addi) }
  function ee_i_vaddq (line 2710) | static inline void ee_i_vaddq(struct ee_state* ee) { VU_UPPER(addq) }
  function ee_i_vaddw (line 2711) | static inline void ee_i_vaddw(struct ee_state* ee) { VU_UPPER(addw) }
  function ee_i_vaddx (line 2712) | static inline void ee_i_vaddx(struct ee_state* ee) { VU_UPPER(addx) }
  function ee_i_vaddy (line 2713) | static inline void ee_i_vaddy(struct ee_state* ee) { VU_UPPER(addy) }
  function ee_i_vaddz (line 2714) | static inline void ee_i_vaddz(struct ee_state* ee) { VU_UPPER(addz) }
  function ee_i_vcallms (line 2715) | static inline void ee_i_vcallms(struct ee_state* ee) {
  function ee_i_vcallmsr (line 2718) | static inline void ee_i_vcallmsr(struct ee_state* ee) {
  function ee_i_vclipw (line 2721) | static inline void ee_i_vclipw(struct ee_state* ee) { VU_UPPER(clip) }
  function ee_i_vdiv (line 2722) | static inline void ee_i_vdiv(struct ee_state* ee) { VU_LOWER(div) }
  function ee_i_vftoi0 (line 2723) | static inline void ee_i_vftoi0(struct ee_state* ee) { VU_UPPER(ftoi0) }
  function ee_i_vftoi12 (line 2724) | static inline void ee_i_vftoi12(struct ee_state* ee) { VU_UPPER(ftoi12) }
  function ee_i_vftoi15 (line 2725) | static inline void ee_i_vftoi15(struct ee_state* ee) { VU_UPPER(ftoi15) }
  function ee_i_vftoi4 (line 2726) | static inline void ee_i_vftoi4(struct ee_state* ee) { VU_UPPER(ftoi4) }
  function ee_i_viadd (line 2727) | static inline void ee_i_viadd(struct ee_state* ee) { VU_LOWER(iadd) }
  function ee_i_viaddi (line 2728) | static inline void ee_i_viaddi(struct ee_state* ee) { VU_LOWER(iaddi) }
  function ee_i_viand (line 2729) | static inline void ee_i_viand(struct ee_state* ee) { VU_LOWER(iand) }
  function ee_i_vilwr (line 2730) | static inline void ee_i_vilwr(struct ee_state* ee) { VU_LOWER(ilwr) }
  function ee_i_vior (line 2731) | static inline void ee_i_vior(struct ee_state* ee) { VU_LOWER(ior) }
  function ee_i_visub (line 2732) | static inline void ee_i_visub(struct ee_state* ee) { VU_LOWER(isub) }
  function ee_i_viswr (line 2733) | static inline void ee_i_viswr(struct ee_state* ee) { VU_LOWER(iswr) }
  function ee_i_vitof0 (line 2734) | static inline void ee_i_vitof0(struct ee_state* ee) { VU_UPPER(itof0) }
  function ee_i_vitof12 (line 2735) | static inline void ee_i_vitof12(struct ee_state* ee) { VU_UPPER(itof12) }
  function ee_i_vitof15 (line 2736) | static inline void ee_i_vitof15(struct ee_state* ee) { VU_UPPER(itof15) }
  function ee_i_vitof4 (line 2737) | static inline void ee_i_vitof4(struct ee_state* ee) { VU_UPPER(itof4) }
  function ee_i_vlqd (line 2738) | static inline void ee_i_vlqd(struct ee_state* ee) { VU_LOWER(lqd) }
  function ee_i_vlqi (line 2739) | static inline void ee_i_vlqi(struct ee_state* ee) { VU_LOWER(lqi) }
  function ee_i_vmadd (line 2740) | static inline void ee_i_vmadd(struct ee_state* ee) { VU_UPPER(madd) }
  function ee_i_vmadda (line 2741) | static inline void ee_i_vmadda(struct ee_state* ee) { VU_UPPER(madda) }
  function ee_i_vmaddai (line 2742) | static inline void ee_i_vmaddai(struct ee_state* ee) { VU_UPPER(maddai) }
  function ee_i_vmaddaq (line 2743) | static inline void ee_i_vmaddaq(struct ee_state* ee) { VU_UPPER(maddaq) }
  function ee_i_vmaddaw (line 2744) | static inline void ee_i_vmaddaw(struct ee_state* ee) { VU_UPPER(maddaw) }
  function ee_i_vmaddax (line 2745) | static inline void ee_i_vmaddax(struct ee_state* ee) { VU_UPPER(maddax) }
  function ee_i_vmadday (line 2746) | static inline void ee_i_vmadday(struct ee_state* ee) { VU_UPPER(madday) }
  function ee_i_vmaddaz (line 2747) | static inline void ee_i_vmaddaz(struct ee_state* ee) { VU_UPPER(maddaz) }
  function ee_i_vmaddi (line 2748) | static inline void ee_i_vmaddi(struct ee_state* ee) { VU_UPPER(maddi) }
  function ee_i_vmaddq (line 2749) | static inline void ee_i_vmaddq(struct ee_state* ee) { VU_UPPER(maddq) }
  function ee_i_vmaddw (line 2750) | static inline void ee_i_vmaddw(struct ee_state* ee) { VU_UPPER(maddw) }
  function ee_i_vmaddx (line 2751) | static inline void ee_i_vmaddx(struct ee_state* ee) { VU_UPPER(maddx) }
  function ee_i_vmaddy (line 2752) | static inline void ee_i_vmaddy(struct ee_state* ee) { VU_UPPER(maddy) }
  function ee_i_vmaddz (line 2753) | static inline void ee_i_vmaddz(struct ee_state* ee) { VU_UPPER(maddz) }
  function ee_i_vmax (line 2754) | static inline void ee_i_vmax(struct ee_state* ee) { VU_UPPER(max) }
  function ee_i_vmaxi (line 2755) | static inline void ee_i_vmaxi(struct ee_state* ee) { VU_UPPER(maxi) }
  function ee_i_vmaxw (line 2756) | static inline void ee_i_vmaxw(struct ee_state* ee) { VU_UPPER(maxw) }
  function ee_i_vmaxx (line 2757) | static inline void ee_i_vmaxx(struct ee_state* ee) { VU_UPPER(maxx) }
  function ee_i_vmaxy (line 2758) | static inline void ee_i_vmaxy(struct ee_state* ee) { VU_UPPER(maxy) }
  function ee_i_vmaxz (line 2759) | static inline void ee_i_vmaxz(struct ee_state* ee) { VU_UPPER(maxz) }
  function ee_i_vmfir (line 2760) | static inline void ee_i_vmfir(struct ee_state* ee) { VU_UPPER(mfir) }
  function ee_i_vmini (line 2761) | static inline void ee_i_vmini(struct ee_state* ee) { VU_UPPER(mini) }
  function ee_i_vminii (line 2762) | static inline void ee_i_vminii(struct ee_state* ee) { VU_UPPER(minii) }
  function ee_i_vminiw (line 2763) | static inline void ee_i_vminiw(struct ee_state* ee) { VU_UPPER(miniw) }
  function ee_i_vminix (line 2764) | static inline void ee_i_vminix(struct ee_state* ee) { VU_UPPER(minix) }
  function ee_i_vminiy (line 2765) | static inline void ee_i_vminiy(struct ee_state* ee) { VU_UPPER(miniy) }
  function ee_i_vminiz (line 2766) | static inline void ee_i_vminiz(struct ee_state* ee) { VU_UPPER(miniz) }
  function ee_i_vmove (line 2767) | static inline void ee_i_vmove(struct ee_state* ee) { VU_LOWER(move) }
  function ee_i_vmr32 (line 2768) | static inline void ee_i_vmr32(struct ee_state* ee) { VU_LOWER(mr32) }
  function ee_i_vmsub (line 2769) | static inline void ee_i_vmsub(struct ee_state* ee) { VU_UPPER(msub) }
  function ee_i_vmsuba (line 2770) | static inline void ee_i_vmsuba(struct ee_state* ee) { VU_UPPER(msuba) }
  function ee_i_vmsubai (line 2771) | static inline void ee_i_vmsubai(struct ee_state* ee) { VU_UPPER(msubai) }
  function ee_i_vmsubaq (line 2772) | static inline void ee_i_vmsubaq(struct ee_state* ee) { VU_UPPER(msubaq) }
  function ee_i_vmsubaw (line 2773) | static inline void ee_i_vmsubaw(struct ee_state* ee) { VU_UPPER(msubaw) }
  function ee_i_vmsubax (line 2774) | static inline void ee_i_vmsubax(struct ee_state* ee) { VU_UPPER(msubax) }
  function ee_i_vmsubay (line 2775) | static inline void ee_i_vmsubay(struct ee_state* ee) { VU_UPPER(msubay) }
  function ee_i_vmsubaz (line 2776) | static inline void ee_i_vmsubaz(struct ee_state* ee) { VU_UPPER(msubaz) }
  function ee_i_vmsubi (line 2777) | static inline void ee_i_vmsubi(struct ee_state* ee) { VU_UPPER(msubi) }
  function ee_i_vmsubq (line 2778) | static inline void ee_i_vmsubq(struct ee_state* ee) { VU_UPPER(msubq) }
  function ee_i_vmsubw (line 2779) | static inline void ee_i_vmsubw(struct ee_state* ee) { VU_UPPER(msubw) }
  function ee_i_vmsubx (line 2780) | static inline void ee_i_vmsubx(struct ee_state* ee) { VU_UPPER(msubx) }
  function ee_i_vmsuby (line 2781) | static inline void ee_i_vmsuby(struct ee_state* ee) { VU_UPPER(msuby) }
  function ee_i_vmsubz (line 2782) | static inline void ee_i_vmsubz(struct ee_state* ee) { VU_UPPER(msubz) }
  function ee_i_vmtir (line 2783) | static inline void ee_i_vmtir(struct ee_state* ee) { VU_LOWER(mtir) }
  function ee_i_vmul (line 2784) | static inline void ee_i_vmul(struct ee_state* ee) { VU_UPPER(mul) }
  function ee_i_vmula (line 2785) | static inline void ee_i_vmula(struct ee_state* ee) { VU_UPPER(mula) }
  function ee_i_vmulai (line 2786) | static inline void ee_i_vmulai(struct ee_state* ee) { VU_UPPER(mulai) }
  function ee_i_vmulaq (line 2787) | static inline void ee_i_vmulaq(struct ee_state* ee) { VU_UPPER(mulaq) }
  function ee_i_vmulaw (line 2788) | static inline void ee_i_vmulaw(struct ee_state* ee) { VU_UPPER(mulaw) }
  function ee_i_vmulax (line 2789) | static inline void ee_i_vmulax(struct ee_state* ee) { VU_UPPER(mulax) }
  function ee_i_vmulay (line 2790) | static inline void ee_i_vmulay(struct ee_state* ee) { VU_UPPER(mulay) }
  function ee_i_vmulaz (line 2791) | static inline void ee_i_vmulaz(struct ee_state* ee) { VU_UPPER(mulaz) }
  function ee_i_vmuli (line 2792) | static inline void ee_i_vmuli(struct ee_state* ee) { VU_UPPER(muli) }
  function ee_i_vmulq (line 2793) | static inline void ee_i_vmulq(struct ee_state* ee) { VU_UPPER(mulq) }
  function ee_i_vmulw (line 2794) | static inline void ee_i_vmulw(struct ee_state* ee) { VU_UPPER(mulw) }
  function ee_i_vmulx (line 2795) | static inline void ee_i_vmulx(struct ee_state* ee) { VU_UPPER(mulx) }
  function ee_i_vmuly (line 2796) | static inline void ee_i_vmuly(struct ee_state* ee) { VU_UPPER(muly) }
  function ee_i_vmulz (line 2797) | static inline void ee_i_vmulz(struct ee_state* ee) { VU_UPPER(mulz) }
  function ee_i_vnop (line 2798) | static inline void ee_i_vnop(struct ee_state* ee) { VU_UPPER(nop) }
  function ee_i_vopmsub (line 2799) | static inline void ee_i_vopmsub(struct ee_state* ee) { VU_UPPER(opmsub) }
  function ee_i_vopmula (line 2800) | static inline void ee_i_vopmula(struct ee_state* ee) { VU_UPPER(opmula) }
  function ee_i_vrget (line 2801) | static inline void ee_i_vrget(struct ee_state* ee) { VU_LOWER(rget) }
  function ee_i_vrinit (line 2802) | static inline void ee_i_vrinit(struct ee_state* ee) { VU_LOWER(rinit) }
  function ee_i_vrnext (line 2803) | static inline void ee_i_vrnext(struct ee_state* ee) { VU_LOWER(rnext) }
  function ee_i_vrsqrt (line 2804) | static inline void ee_i_vrsqrt(struct ee_state* ee) { VU_LOWER(rsqrt) }
  function ee_i_vrxor (line 2805) | static inline void ee_i_vrxor(struct ee_state* ee) { VU_LOWER(rxor) }
  function ee_i_vsqd (line 2806) | static inline void ee_i_vsqd(struct ee_state* ee) { VU_LOWER(sqd) }
  function ee_i_vsqi (line 2807) | static inline void ee_i_vsqi(struct ee_state* ee) { VU_LOWER(sqi) }
  function ee_i_vsqrt (line 2808) | static inline void ee_i_vsqrt(struct ee_state* ee) { VU_LOWER(sqrt) }
  function ee_i_vsub (line 2809) | static inline void ee_i_vsub(struct ee_state* ee) { VU_UPPER(sub) }
  function ee_i_vsuba (line 2810) | static inline void ee_i_vsuba(struct ee_state* ee) { VU_UPPER(suba) }
  function ee_i_vsubai (line 2811) | static inline void ee_i_vsubai(struct ee_state* ee) { VU_UPPER(subai) }
  function ee_i_vsubaq (line 2812) | static inline void ee_i_vsubaq(struct ee_state* ee) { VU_UPPER(subaq) }
  function ee_i_vsubaw (line 2813) | static inline void ee_i_vsubaw(struct ee_state* ee) { VU_UPPER(subaw) }
  function ee_i_vsubax (line 2814) | static inline void ee_i_vsubax(struct ee_state* ee) { VU_UPPER(subax) }
  function ee_i_vsubay (line 2815) | static inline void ee_i_vsubay(struct ee_state* ee) { VU_UPPER(subay) }
  function ee_i_vsubaz (line 2816) | static inline void ee_i_vsubaz(struct ee_state* ee) { VU_UPPER(subaz) }
  function ee_i_vsubi (line 2817) | static inline void ee_i_vsubi(struct ee_state* ee) { VU_UPPER(subi) }
  function ee_i_vsubq (line 2818) | static inline void ee_i_vsubq(struct ee_state* ee) { VU_UPPER(subq) }
  function ee_i_vsubw (line 2819) | static inline void ee_i_vsubw(struct ee_state* ee) { VU_UPPER(subw) }
  function ee_i_vsubx (line 2820) | static inline void ee_i_vsubx(struct ee_state* ee) { VU_UPPER(subx) }
  function ee_i_vsuby (line 2821) | static inline void ee_i_vsuby(struct ee_state* ee) { VU_UPPER(suby) }
  function ee_i_vsubz (line 2822) | static inline void ee_i_vsubz(struct ee_state* ee) { VU_UPPER(subz) }
  function ee_i_vwaitq (line 2823) | static inline void ee_i_vwaitq(struct ee_state* ee) { VU_LOWER(waitq) }
  function ee_i_xor (line 2824) | static inline void ee_i_xor(struct ee_state* ee) {
  function ee_i_xori (line 2827) | static inline void ee_i_xori(struct ee_state* ee) {
  type ee_state (line 2831) | struct ee_state
  type ee_state (line 2832) | struct ee_state
  function ee_init (line 2835) | void ee_init(struct ee_state* ee, struct vu_state* vu0, struct vu_state*...
  function ee_execute (line 2856) | static inline void ee_execute(struct ee_state* ee) {
  function ee_cycle (line 3354) | void ee_cycle(struct ee_state* ee) {
  function ee_reset (line 3482) | void ee_reset(struct ee_state* ee) {
  function ee_destroy (line 3512) | void ee_destroy(struct ee_state* ee) {
  function ee_run_block (line 3518) | void ee_run_block(struct ee_state* ee, int cycles) {

FILE: src/ee/ee_uncached.h
  type ee_bus_s (line 16) | struct ee_bus_s {
  type ee_vtlb_entry (line 111) | struct ee_vtlb_entry {
  type ee_state (line 143) | struct ee_state {
  type ee_state (line 214) | struct ee_state
  type ee_state (line 215) | struct ee_state
  type vu_state (line 215) | struct vu_state
  type vu_state (line 215) | struct vu_state
  type ee_bus_s (line 215) | struct ee_bus_s
  type ee_state (line 216) | struct ee_state
  type ee_state (line 217) | struct ee_state
  type ee_state (line 218) | struct ee_state
  type ee_state (line 219) | struct ee_state
  type ee_state (line 220) | struct ee_state
  type ee_state (line 221) | struct ee_state

FILE: src/ee/gif.c
  type ps2_gif (line 74) | struct ps2_gif
  type ps2_gif (line 75) | struct ps2_gif
  function ps2_gif_init (line 78) | void ps2_gif_init(struct ps2_gif* gif, struct vu_state* vu1, struct ps2_...
  function ps2_gif_reset (line 92) | void ps2_gif_reset(struct ps2_gif* gif) {
  function ps2_gif_destroy (line 112) | void ps2_gif_destroy(struct ps2_gif* gif) {
  function ps2_gif_read32 (line 119) | uint64_t ps2_gif_read32(struct ps2_gif* gif, uint32_t addr) {
  function ps2_gif_write32 (line 141) | void ps2_gif_write32(struct ps2_gif* gif, uint32_t addr, uint64_t data) {
  function gif_handle_tag (line 199) | void gif_handle_tag(struct ps2_gif* gif, uint128_t data) {
  function ps2_gif_write128 (line 337) | void ps2_gif_write128(struct ps2_gif* gif, uint32_t addr, uint128_t data) {
  function ps2_gif_fifo_write (line 341) | void ps2_gif_fifo_write(struct ps2_gif* gif, uint128_t data, int path) {
  function ps2_gif_set_backend (line 373) | void ps2_gif_set_backend(struct ps2_gif* gif, void* udata, void (*func)(...

FILE: src/ee/gif.h
  type gif_tag (line 22) | struct gif_tag {
  type ps2_gif (line 36) | struct ps2_gif {
  type ps2_gif (line 63) | struct ps2_gif
  type ps2_gif (line 64) | struct ps2_gif
  type vu_state (line 64) | struct vu_state
  type ps2_gs (line 64) | struct ps2_gs
  type ps2_gif (line 65) | struct ps2_gif
  type ps2_gif (line 66) | struct ps2_gif
  type ps2_gif (line 67) | struct ps2_gif
  type ps2_gif (line 68) | struct ps2_gif
  type ps2_gif (line 69) | struct ps2_gif
  type ps2_gif (line 70) | struct ps2_gif
  type ps2_gif (line 71) | struct ps2_gif

FILE: src/ee/intc.c
  function intc_check_irq (line 8) | static inline void intc_check_irq(struct ps2_intc* intc) {
  type ps2_intc (line 12) | struct ps2_intc
  type ps2_intc (line 13) | struct ps2_intc
  function ps2_intc_init (line 16) | void ps2_intc_init(struct ps2_intc* intc, struct ee_state* ee, struct sc...
  function ps2_intc_destroy (line 23) | void ps2_intc_destroy(struct ps2_intc* intc) {
  function ps2_intc_read32 (line 27) | uint64_t ps2_intc_read32(struct ps2_intc* intc, uint32_t addr) {
  function ps2_intc_write8 (line 38) | void ps2_intc_write8(struct ps2_intc* intc, uint32_t addr, uint64_t data) {
  function ps2_intc_write16 (line 51) | void ps2_intc_write16(struct ps2_intc* intc, uint32_t addr, uint64_t dat...
  function intc_check_irq_event (line 64) | void intc_check_irq_event(void* udata, int overshoot) {
  function ps2_intc_write32 (line 70) | void ps2_intc_write32(struct ps2_intc* intc, uint32_t addr, uint64_t dat...
  function ps2_intc_write64 (line 88) | void ps2_intc_write64(struct ps2_intc* intc, uint32_t addr, uint64_t dat...
  function ps2_intc_irq (line 101) | void ps2_intc_irq(struct ps2_intc* intc, int dev) {

FILE: src/ee/intc.h
  type ps2_intc (line 1) | struct ps2_intc
  type ps2_intc (line 32) | struct ps2_intc {
  type ps2_intc (line 40) | struct ps2_intc
  type ps2_intc (line 41) | struct ps2_intc
  type ee_state (line 41) | struct ee_state
  type sched_state (line 41) | struct sched_state
  type ps2_intc (line 42) | struct ps2_intc
  type ps2_intc (line 43) | struct ps2_intc
  type ps2_intc (line 44) | struct ps2_intc
  type ps2_intc (line 45) | struct ps2_intc
  type ps2_intc (line 46) | struct ps2_intc
  type ps2_intc (line 47) | struct ps2_intc
  type ps2_intc (line 48) | struct ps2_intc

FILE: src/ee/timers.c
  type ps2_ee_timers (line 9) | struct ps2_ee_timers
  type ps2_ee_timers (line 11) | struct ps2_ee_timers
  type ps2_ee_timers (line 12) | struct ps2_ee_timers
  function ee_timers_update_active_mask (line 15) | static inline void ee_timers_update_active_mask(struct ps2_ee_timers* ti...
  function ps2_ee_timers_init (line 25) | void ps2_ee_timers_init(struct ps2_ee_timers* timers, struct ps2_intc* i...
  function ee_timers_update_event (line 40) | static inline void ee_timers_update_event(struct ee_timer* t) {
  function ee_timers_cycles_until_check (line 65) | static inline uint32_t ee_timers_cycles_until_check(struct ee_timer* t) {
  function ee_timers_advance_counter (line 89) | static inline void ee_timers_advance_counter(struct ps2_ee_timers* timer...
  function ee_timers_sync_timer (line 159) | static inline void ee_timers_sync_timer(struct ps2_ee_timers* timers, st...
  function ee_timers_irq_event_cb (line 197) | static void ee_timers_irq_event_cb(void* udata, int overshoot) {
  function ee_timers_schedule_next_irq_event (line 221) | static void ee_timers_schedule_next_irq_event(struct ps2_ee_timers* time...
  function ee_timers_write_counter (line 257) | void ee_timers_write_counter(struct ps2_ee_timers* timers, int t, uint32...
  function ee_timers_write_compare (line 275) | void ee_timers_write_compare(struct ps2_ee_timers* timers, int t, uint32...
  function ps2_ee_timers_destroy (line 303) | void ps2_ee_timers_destroy(struct ps2_ee_timers* timers) {
  function ee_timers_write_mode (line 307) | static inline void ee_timers_write_mode(struct ps2_ee_timers* timers, in...
  function ps2_ee_timers_tick (line 371) | void ps2_ee_timers_tick(struct ps2_ee_timers* timers) {
  function ps2_ee_timers_tick_cycles (line 375) | void ps2_ee_timers_tick_cycles(struct ps2_ee_timers* timers, uint32_t cy...
  function ps2_ee_timers_write16 (line 395) | void ps2_ee_timers_write16(struct ps2_ee_timers* timers, uint32_t addr, ...
  function ps2_ee_timers_write32 (line 410) | void ps2_ee_timers_write32(struct ps2_ee_timers* timers, uint32_t addr, ...
  function ps2_ee_timers_read16 (line 423) | uint64_t ps2_ee_timers_read16(struct ps2_ee_timers* timers, uint32_t add...
  function ps2_ee_timers_read32 (line 445) | uint64_t ps2_ee_timers_read32(struct ps2_ee_timers* timers, uint32_t add...

FILE: src/ee/timers.h
  type ee_timer (line 13) | struct ee_timer {
  type ps2_ee_timers (line 44) | struct ps2_ee_timers {
  type ps2_ee_timers (line 57) | struct ps2_ee_timers
  type ps2_ee_timers (line 58) | struct ps2_ee_timers
  type ps2_intc (line 58) | struct ps2_intc
  type sched_state (line 58) | struct sched_state
  type ps2_ee_timers (line 59) | struct ps2_ee_timers
  type ps2_ee_timers (line 60) | struct ps2_ee_timers
  type ps2_ee_timers (line 61) | struct ps2_ee_timers
  type ps2_ee_timers (line 62) | struct ps2_ee_timers
  type ps2_ee_timers (line 63) | struct ps2_ee_timers
  type ps2_ee_timers (line 64) | struct ps2_ee_timers
  type ps2_ee_timers (line 65) | struct ps2_ee_timers
  type ps2_ee_timers (line 66) | struct ps2_ee_timers
  type ps2_ee_timers (line 67) | struct ps2_ee_timers
  type ps2_ee_timers (line 68) | struct ps2_ee_timers

FILE: src/ee/vif.c
  type ps2_vif (line 11) | struct ps2_vif
  type ps2_vif (line 12) | struct ps2_vif
  function ps2_vif_init (line 15) | void ps2_vif_init(struct ps2_vif* vif, int id, struct vu_state* vu, stru...
  function ps2_vif_destroy (line 26) | void ps2_vif_destroy(struct ps2_vif* vif) {
  function vif_write_vu_mem (line 30) | static inline void vif_write_vu_mem(struct ps2_vif* vif, uint128_t data) {
  function vif0_send_irq (line 106) | void vif0_send_irq(void* udata, int overshoot) {
  function vif1_send_irq (line 112) | void vif1_send_irq(void* udata, int overshoot) {
  function vif_handle_fifo_write (line 118) | static inline void vif_handle_fifo_write(struct ps2_vif* vif, uint32_t d...
  function ps2_vif_read32 (line 803) | uint64_t ps2_vif_read32(struct ps2_vif* vif, uint32_t addr) {
  function ps2_vif_write32 (line 869) | void ps2_vif_write32(struct ps2_vif* vif, uint32_t addr, uint64_t data) {
  function uint128_t (line 909) | uint128_t ps2_vif_read128(struct ps2_vif* vif, uint32_t addr) {
  function ps2_vif_write128 (line 924) | void ps2_vif_write128(struct ps2_vif* vif, uint32_t addr, uint128_t data) {

FILE: src/ee/vif.h
  type ps2_vif (line 58) | struct ps2_vif {
  type ps2_vif (line 106) | struct ps2_vif
  type ps2_vif (line 107) | struct ps2_vif
  type vu_state (line 107) | struct vu_state
  type ps2_gif (line 107) | struct ps2_gif
  type ps2_intc (line 107) | struct ps2_intc
  type sched_state (line 107) | struct sched_state
  type ee_bus (line 107) | struct ee_bus
  type ps2_vif (line 108) | struct ps2_vif
  type ps2_vif (line 109) | struct ps2_vif
  type ps2_vif (line 110) | struct ps2_vif
  type ps2_vif (line 111) | struct ps2_vif
  type ps2_vif (line 112) | struct ps2_vif

FILE: src/ee/vu.h
  type vu_state (line 1) | struct vu_state
  type vu_reg128 (line 16) | struct vu_reg128 {
  type vu_reg32 (line 34) | struct vu_reg32 {
  type vu_instruction (line 51) | struct vu_instruction {
  type vu_state (line 81) | struct vu_state
  type vu_state (line 83) | struct vu_state
  type vu_state (line 84) | struct vu_state
  type ps2_gif (line 84) | struct ps2_gif
  type ps2_vif (line 84) | struct ps2_vif
  type vu_state (line 84) | struct vu_state
  type vu_state (line 85) | struct vu_state
  type vu_state (line 88) | struct vu_state
  type vu_state (line 89) | struct vu_state
  type vu_state (line 90) | struct vu_state
  type vu_state (line 91) | struct vu_state
  type vu_state (line 92) | struct vu_state
  type vu_state (line 93) | struct vu_state
  type vu_state (line 94) | struct vu_state
  type vu_state (line 95) | struct vu_state
  type vu_state (line 96) | struct vu_state
  type vu_state (line 97) | struct vu_state
  type vu_state (line 98) | struct vu_state
  type vu_state (line 99) | struct vu_state
  type vu_state (line 100) | struct vu_state
  type vu_state (line 101) | struct vu_state
  type vu_state (line 102) | struct vu_state
  type vu_state (line 103) | struct vu_state
  type vu_state (line 104) | struct vu_state
  type vu_state (line 106) | struct vu_state
  type vu_state (line 107) | struct vu_state
  type vu_state (line 108) | struct vu_state
  type vu_state (line 109) | struct vu_state
  type vu_state (line 110) | struct vu_state
  type vu_state (line 111) | struct vu_state
  type vu_state (line 112) | struct vu_state
  type vu_state (line 113) | struct vu_state

FILE: src/ee/vu_cached.cpp
  function unreachable (line 38) | [[noreturn]] inline void unreachable() {
  type vu_state (line 49) | struct vu_state
  type vu_state (line 50) | struct vu_state
  function vu_init (line 53) | void vu_init(struct vu_state* vu, int id, struct ps2_gif* gif, struct ps...
  function vu_destroy (line 82) | void vu_destroy(struct vu_state* vu) {
  function vu_max (line 89) | static inline uint32_t vu_max(int32_t a, int32_t b) {
  function vu_min (line 93) | static inline uint32_t vu_min(int32_t a, int32_t b) {
  function vu_atan (line 97) | static inline float vu_atan(float t) {
  function vu_update_status (line 115) | static inline void vu_update_status(struct vu_state* vu) {
  function vu_set_q (line 126) | static inline void vu_set_q(struct vu_state* vu, float value, int delay) {
  function vu_get_q (line 135) | static inline struct vu_reg32 vu_get_q(struct vu_state* vu) {
  function vu_update_flags (line 143) | static inline float vu_update_flags(struct vu_state* vu, float value, in...
  function vu_clear_flags (line 184) | static inline void vu_clear_flags(struct vu_state* vu, int index) {
  function vu_cvtf (line 188) | static inline float vu_cvtf(uint32_t value) {
  function vu_cvti (line 206) | int32_t vu_cvti(float value) {
  function vu_set_vf (line 216) | static inline void vu_set_vf(struct vu_state* vu, int r, int f, float v) {
  function vu_set_vfu (line 220) | static inline void vu_set_vfu(struct vu_state* vu, int r, int f, int32_t...
  function vu_set_vf_x (line 224) | static inline void vu_set_vf_x(struct vu_state* vu, int r, float v) {
  function vu_set_vf_y (line 228) | static inline void vu_set_vf_y(struct vu_state* vu, int r, float v) {
  function vu_set_vf_z (line 232) | static inline void vu_set_vf_z(struct vu_state* vu, int r, float v) {
  function vu_set_vf_w (line 236) | static inline void vu_set_vf_w(struct vu_state* vu, int r, float v) {
  function vu_set_vi (line 240) | static inline void vu_set_vi(struct vu_state* vu, int r, uint16_t v) {
  function vu_vf_i (line 244) | static inline float vu_vf_i(struct vu_state* vu, int r, int i) {
  function vu_vf_x (line 248) | static inline float vu_vf_x(struct vu_state* vu, int r) {
  function vu_vf_y (line 252) | static inline float vu_vf_y(struct vu_state* vu, int r) {
  function vu_vf_z (line 256) | static inline float vu_vf_z(struct vu_state* vu, int r) {
  function vu_vf_w (line 260) | static inline float vu_vf_w(struct vu_state* vu, int r) {
  function vu_acc_i (line 264) | static inline float vu_acc_i(struct vu_state* vu, int i) {
  function vu_mem_write (line 268) | static inline void vu_mem_write(struct vu_state* vu, uint16_t addr, uint...
  function uint128_t (line 306) | static inline uint128_t vu_mem_read(struct vu_state* vu, uint32_t addr) {
  function vu_write_branch_pipeline (line 347) | static inline void vu_write_branch_pipeline(struct vu_state* vu, int dst) {
  function vu_get_branch_register (line 368) | static inline uint16_t vu_get_branch_register(struct vu_state* vu, int r...
  function vu_xgkick (line 376) | void vu_xgkick(struct vu_state* vu) {
  function seq (line 456) | void seq(F f, std::index_sequence<Is...>) {
  function template_seq (line 462) | void template_seq(F f) {
  function vu_i_abs (line 468) | void vu_i_abs(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_add (line 479) | void vu_i_add(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_addi (line 497) | void vu_i_addi(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_addq (line 514) | void vu_i_addq(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_addx (line 532) | void vu_i_addx(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_addy (line 552) | void vu_i_addy(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_addz (line 572) | void vu_i_addz(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_addw (line 592) | void vu_i_addw(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_adda (line 612) | void vu_i_adda(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_addai (line 629) | void vu_i_addai(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_addaq (line 645) | void vu_i_addaq(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_addax (line 662) | void vu_i_addax(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_adday (line 681) | void vu_i_adday(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_addaz (line 700) | void vu_i_addaz(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_addaw (line 719) | void vu_i_addaw(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_sub (line 738) | void vu_i_sub(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_subi (line 756) | void vu_i_subi(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_subq (line 773) | void vu_i_subq(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_subx (line 791) | void vu_i_subx(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_suby (line 811) | void vu_i_suby(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_subz (line 831) | void vu_i_subz(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_subw (line 851) | void vu_i_subw(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_suba (line 871) | void vu_i_suba(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_subai (line 888) | void vu_i_subai(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_subaq (line 904) | void vu_i_subaq(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_subax (line 921) | void vu_i_subax(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_subay (line 940) | void vu_i_subay(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_subaz (line 959) | void vu_i_subaz(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_subaw (line 978) | void vu_i_subaw(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_mul (line 997) | void vu_i_mul(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_muli (line 1015) | void vu_i_muli(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_mulq (line 1032) | void vu_i_mulq(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_mulx (line 1050) | void vu_i_mulx(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_muly (line 1070) | void vu_i_muly(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_mulz (line 1090) | void vu_i_mulz(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_mulw (line 1110) | void vu_i_mulw(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_mula (line 1130) | void vu_i_mula(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_mulai (line 1147) | void vu_i_mulai(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_mulaq (line 1163) | void vu_i_mulaq(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_mulax (line 1180) | void vu_i_mulax(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_mulay (line 1199) | void vu_i_mulay(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_mulaz (line 1218) | void vu_i_mulaz(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_mulaw (line 1237) | void vu_i_mulaw(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_madd (line 1256) | void vu_i_madd(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_maddi (line 1274) | void vu_i_maddi(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_maddq (line 1291) | void vu_i_maddq(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_maddx (line 1309) | void vu_i_maddx(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_maddy (line 1329) | void vu_i_maddy(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_maddz (line 1349) | void vu_i_maddz(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_maddw (line 1369) | void vu_i_maddw(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_madda (line 1389) | void vu_i_madda(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_maddai (line 1406) | void vu_i_maddai(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_maddaq (line 1422) | void vu_i_maddaq(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_maddax (line 1439) | void vu_i_maddax(struct vu_state* vu, const struct vu_instruction* ins) {
  function vu_i_madday (line 1
Condensed preview — 245 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (2,620K chars).
[
  {
    "path": ".github/FUNDING.yml",
    "chars": 824,
    "preview": "# These are supported funding model platforms\n\ngithub: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [u"
  },
  {
    "path": ".github/workflows/linux.yml",
    "chars": 1307,
    "preview": "name: Ubuntu CI\r\n\r\non:\r\n  push:\r\n    branches: [ \"master\" ]\r\n\r\njobs:\r\n  build:\r\n    runs-on: ubuntu-latest\r\n\r\n    steps:"
  },
  {
    "path": ".github/workflows/macos.yml",
    "chars": 878,
    "preview": "name: macOS CI\r\n\r\non:\r\n  push:\r\n    branches: [ \"master\" ]\r\n\r\njobs:\r\n  macos-universal-build:\r\n    runs-on: macos-latest"
  },
  {
    "path": ".github/workflows/release.yml",
    "chars": 4043,
    "preview": "name: Release CI\n\non:\n  push:\n    tags:\n    - '0.*'\n\njobs:\n  windows-build:\n    runs-on: windows-latest\n\n    steps:\n    "
  },
  {
    "path": ".github/workflows/windows.yml",
    "chars": 726,
    "preview": "name: Windows CI\r\n\r\non:\r\n  push:\r\n    branches: [ \"master\" ]\r\n\r\njobs:\r\n  build:\r\n    runs-on: windows-latest\r\n\r\n    step"
  },
  {
    "path": ".gitignore",
    "chars": 213,
    "preview": "SDL2-2.32.0/\n.vscode/\nbuild/\nbin/\ntools/\nelf/\nroms/\n.vs/\nac/\nscreens/\nmain2.cpp\ncompare\ncompare.cpp\nimgui.ini\n*.AppImage"
  },
  {
    "path": ".gitmodules",
    "chars": 1252,
    "preview": "[submodule \"imgui\"]\n\tpath = deps/imgui\n\turl = https://github.com/ocornut/imgui\n\tbranch = docking\n[submodule \"tomlplusplu"
  },
  {
    "path": "AppImage.cmake",
    "chars": 2139,
    "preview": "function(make_appimage)\n\tset(optional)\n\tset(args EXE NAME DIR_ICON ICON OUTPUT_NAME)\n\tset(list_args ASSETS)\n\tcmake_parse"
  },
  {
    "path": "CMakeLists.txt",
    "chars": 10755,
    "preview": "cmake_minimum_required(VERSION 3.21)\nproject(iris LANGUAGES C CXX)\n\nset(WIN_ICON ${CMAKE_CURRENT_SOURCE_DIR}/res/iris.rc"
  },
  {
    "path": "Info.plist",
    "chars": 1049,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
  },
  {
    "path": "LICENSE",
    "chars": 1081,
    "preview": "MIT License\n\nCopyright (c) 2025 Allkern/Lisandro Alarcon\n\nPermission is hereby granted, free of charge, to any person ob"
  },
  {
    "path": "MoltenVK_icd.json",
    "chars": 196,
    "preview": "{\n    \"file_format_version\" : \"1.0.0\",\n    \"ICD\": {\n        \"library_path\": \"../../../Frameworks/libMoltenVK.dylib\",\n   "
  },
  {
    "path": "README.md",
    "chars": 8408,
    "preview": "<div align=\"center\" text-align=\"center\" width=\"100%\">\n    <img width=\"55%\" src=\"https://github.com/user-attachments/asse"
  },
  {
    "path": "compat.txt",
    "chars": 1915,
    "preview": "\".hack - Infection (USA)\" - Boots to menus, runs very slow\n\"007 - Nightfire (USA)\" - Hangs trying to play an FMV at the "
  },
  {
    "path": "frontend/arcade.hpp",
    "chars": 1571,
    "preview": "#include <toml++/toml.hpp>\n\n#include \"ps2.h\"\n\nconst toml::table g_arcade_definitions = toml::table {\n    { \"pacmanap\", t"
  },
  {
    "path": "frontend/audio.cpp",
    "chars": 1762,
    "preview": "#include <chrono>\n#include <thread>\n\n#include \"iris.hpp\"\n\nnamespace iris::audio {\n\nvoid update(void* userdata, SDL_Audio"
  },
  {
    "path": "frontend/config.hpp",
    "chars": 338,
    "preview": "#pragma once\n\n#ifndef _IRIS_VERSION\n#define _IRIS_VERSION latest\n#endif\n\n#ifndef _IRIS_COMMIT\n#define _IRIS_COMMIT lates"
  },
  {
    "path": "frontend/elf.cpp",
    "chars": 3216,
    "preview": "#include <cstdlib>\n#include <cstdint>\n#include <cstdio>\n\n#include \"iris.hpp\"\n\n#ifdef __linux__\n#include <elf.h>\n#else\n#i"
  },
  {
    "path": "frontend/emu.cpp",
    "chars": 6601,
    "preview": "#include \"iris.hpp\"\n#include \"arcade.hpp\"\n\n#include <filesystem>\n#include <optional>\n\nnamespace iris::emu {\n\nbool init(i"
  },
  {
    "path": "frontend/handlers.cpp",
    "chars": 826,
    "preview": "#include \"iris.hpp\"\n\nnamespace iris {\n\nvoid handle_ee_tty_event(void* udata, char c) {\n    iris::instance* iris = (iris:"
  },
  {
    "path": "frontend/imgui.cpp",
    "chars": 46043,
    "preview": "#include \"iris.hpp\"\n\n#include \"imgui.h\"\n#include \"imgui_impl_sdl3.h\"\n#include \"imgui_impl_vulkan.h\"\n#include \"implot.h\"\n"
  },
  {
    "path": "frontend/input.cpp",
    "chars": 27240,
    "preview": "#include <filesystem>\n#include <string>\n\n#include \"iris.hpp\"\n\n#define STB_IMAGE_WRITE_IMPLEMENTATION\n#include \"stb_image"
  },
  {
    "path": "frontend/iris.cpp",
    "chars": 22269,
    "preview": "// Standard includes\n#include <filesystem>\n#include <algorithm>\n#include <cstdlib>\n#include <cstdio>\n#include <thread>\n#"
  },
  {
    "path": "frontend/iris.hpp",
    "chars": 26042,
    "preview": "#pragma once\n\n#include <unordered_map>\n#include <cstdint>\n#include <string>\n#include <vector>\n#include <chrono>\n#include"
  },
  {
    "path": "frontend/notifications.cpp",
    "chars": 6600,
    "preview": "#include \"iris.hpp\"\n\n#include \"res/IconsMaterialSymbols.h\"\n\nnamespace iris {\n\nenum {\n    STATE_IDLE,\n    STATE_MOVING = "
  },
  {
    "path": "frontend/platform/stub.cpp",
    "chars": 310,
    "preview": "#include \"iris.hpp\"\n\n// Note: This is a stub implementation for platforms that\n//       do not need special initializati"
  },
  {
    "path": "frontend/platform/windows.cpp",
    "chars": 2171,
    "preview": "#include \"iris.hpp\"\n#include \"imgui.h\"\n\n#include <dwmapi.h>\n\nnamespace iris::platform {\n\nbool init(iris::instance* iris)"
  },
  {
    "path": "frontend/render.cpp",
    "chars": 28147,
    "preview": "#include <cmath>\n\n#include \"iris.hpp\"\n\n#define RENDER_MAX_SHADER_PASSES 16\n\n// INCBIN stuff\n#define INCBIN_PREFIX g_\n#de"
  },
  {
    "path": "frontend/res/IconsMaterialSymbols.h",
    "chars": 193207,
    "preview": "// Generated by https://github.com/juliettef/IconFontCppHeaders script GenerateIconFontCppHeaders.py\n// for C and C++\n//"
  },
  {
    "path": "frontend/settings.cpp",
    "chars": 23672,
    "preview": "#include \"iris.hpp\"\n#include \"config.hpp\"\n\n#include \"ps2_elf.h\"\n#include \"ps2_iso9660.h\"\n\n#define TOML_EXCEPTIONS 0\n#inc"
  },
  {
    "path": "frontend/shaders.cpp",
    "chars": 14371,
    "preview": "#include <unordered_map>\n#include <algorithm>\n\n#include \"config.hpp\"\n#include \"iris.hpp\"\n\n// INCBIN stuff\n#define INCBIN"
  },
  {
    "path": "frontend/ui/about.cpp",
    "chars": 1807,
    "preview": "#include <vector>\n#include <string>\n#include <cctype>\n\n#include \"iris.hpp\"\n#include \"config.hpp\"\n\n#include \"res/IconsMat"
  },
  {
    "path": "frontend/ui/bios_setting.cpp",
    "chars": 4892,
    "preview": "#include \"iris.hpp\"\n\n#include \"res/IconsMaterialSymbols.h\"\n#include \"portable-file-dialogs.h\"\n\n#include \"rom.h\"\n\nnamespa"
  },
  {
    "path": "frontend/ui/breakpoints.cpp",
    "chars": 5467,
    "preview": "#include <vector>\n#include <string>\n#include <cctype>\n\n#include \"iris.hpp\"\n\n#include \"res/IconsMaterialSymbols.h\"\n\nnames"
  },
  {
    "path": "frontend/ui/control.cpp",
    "chars": 19558,
    "preview": "#include <algorithm>\n#include <vector>\n#include <string>\n#include <cctype>\n\n#include \"iris.hpp\"\n\n#include \"res/IconsMate"
  },
  {
    "path": "frontend/ui/dma.cpp",
    "chars": 424,
    "preview": "#include <vector>\n#include <string>\n#include <cctype>\n\n#include \"iris.hpp\"\n\n#include \"res/IconsMaterialSymbols.h\"\n\nnames"
  },
  {
    "path": "frontend/ui/gs.cpp",
    "chars": 15711,
    "preview": "#include <vector>\n#include <string>\n#include <cctype>\n\n#include \"iris.hpp\"\n\n#include \"res/IconsMaterialSymbols.h\"\n\nnames"
  },
  {
    "path": "frontend/ui/intc.cpp",
    "chars": 4546,
    "preview": "#include <vector>\n#include <string>\n#include <cctype>\n\n#include \"iris.hpp\"\n\n#include \"res/IconsMaterialSymbols.h\"\n\nnames"
  },
  {
    "path": "frontend/ui/logs.cpp",
    "chars": 3728,
    "preview": "#include <vector>\n#include <string>\n#include <cctype>\n\n#include \"iris.hpp\"\n\n#include \"res/IconsMaterialSymbols.h\"\n\nnames"
  },
  {
    "path": "frontend/ui/memory.cpp",
    "chars": 3460,
    "preview": "#include <vector>\n#include <string>\n#include <cctype>\n\n#include \"iris.hpp\"\n#include \"ee/ee_def.hpp\"\n#include \"ee/vu_def."
  },
  {
    "path": "frontend/ui/memory_card_tool.cpp",
    "chars": 5450,
    "preview": "#include <vector>\n#include <string>\n#include <cctype>\n#include <cstdlib>\n\n#include \"iris.hpp\"\n\n#include \"res/IconsMateri"
  },
  {
    "path": "frontend/ui/memory_search.cpp",
    "chars": 29858,
    "preview": "#include <sstream>\n#include <fstream>\n#include <vector>\n#include <string>\n#include <cctype>\n\n#include \"iris.hpp\"\n#includ"
  },
  {
    "path": "frontend/ui/memory_viewer.h",
    "chars": 41932,
    "preview": "// Mini memory editor for Dear ImGui (to embed in your game/tools)\n// Get latest version at http://www.github.com/ocornu"
  },
  {
    "path": "frontend/ui/menubar.cpp",
    "chars": 21015,
    "preview": "#include <filesystem>\n\n#include \"iris.hpp\"\n\n#include \"res/IconsMaterialSymbols.h\"\n#include \"portable-file-dialogs.h\"\n\n#i"
  },
  {
    "path": "frontend/ui/modules.cpp",
    "chars": 3578,
    "preview": "#include \"iris.hpp\"\n\n#include \"iop/hle/loadcore.h\"\n\n#include \"res/IconsMaterialSymbols.h\"\n\nnamespace iris {\n\nstatic cons"
  },
  {
    "path": "frontend/ui/overlay.cpp",
    "chars": 3135,
    "preview": "#include <vector>\n#include <cmath>\n\n#include \"iris.hpp\"\n\n#include \"res/IconsMaterialSymbols.h\"\n\n#include \"implot.h\"\n\n#de"
  },
  {
    "path": "frontend/ui/pad.cpp",
    "chars": 2563,
    "preview": "#include <vector>\n#include <string>\n#include <cctype>\n\n#include \"iris.hpp\"\n\n#include \"res/IconsMaterialSymbols.h\"\n\nnames"
  },
  {
    "path": "frontend/ui/settings.cpp",
    "chars": 47770,
    "preview": "#include <algorithm>\n#include <vector>\n#include <string>\n#include <cctype>\n\n#include \"iris.hpp\"\n\n#include \"res/IconsMate"
  },
  {
    "path": "frontend/ui/spu2.cpp",
    "chars": 3597,
    "preview": "#include <vector>\n#include <string>\n#include <cctype>\n\n#include \"iris.hpp\"\n\n#include \"res/IconsMaterialSymbols.h\"\n\nnames"
  },
  {
    "path": "frontend/ui/state.cpp",
    "chars": 26459,
    "preview": "#include <vector>\n#include <string>\n#include <cctype>\n\n#include \"iris.hpp\"\n\n#include \"res/IconsMaterialSymbols.h\"\n\n#incl"
  },
  {
    "path": "frontend/ui/statusbar.cpp",
    "chars": 4723,
    "preview": "#include \"imgui_internal.h\"\n\n#include \"iris.hpp\"\n\n#include \"res/IconsMaterialSymbols.h\"\n\nnamespace ImGui {\n\nbool BeginMa"
  },
  {
    "path": "frontend/ui/symbols.cpp",
    "chars": 8777,
    "preview": "#include <vector>\n#include <string>\n#include <cctype>\n#include <algorithm>\n#include <regex>\n\n#include \"iris.hpp\"\n\n#inclu"
  },
  {
    "path": "frontend/ui/threads.cpp",
    "chars": 3304,
    "preview": "#include <vector>\n#include <string>\n#include <cctype>\n#include <algorithm>\n#include <regex>\n\n#include \"iris.hpp\"\n#includ"
  },
  {
    "path": "frontend/ui/vu_disassembly.cpp",
    "chars": 14813,
    "preview": "#include <algorithm>\n#include <vector>\n#include <string>\n#include <cctype>\n\n#include \"iris.hpp\"\n\n#include \"portable-file"
  },
  {
    "path": "frontend/vulkan.cpp",
    "chars": 49170,
    "preview": "#include <algorithm>\n\n#include \"config.hpp\"\n#include \"iris.hpp\"\n\n#include <SDL3/SDL_vulkan.h>\n\n#include <volk.h>\n\nnamesp"
  },
  {
    "path": "main.cpp",
    "chars": 1591,
    "preview": "// Standard includes\n#include <filesystem>\n#include <algorithm>\n#include <cstdlib>\n#include <cstdio>\n\n// Iris includes\n#"
  },
  {
    "path": "res/iris.rc",
    "chars": 382,
    "preview": "id ICON \"iris.ico\"\n1 VERSIONINFO\nFILEVERSION     1,0,0,0\nPRODUCTVERSION  1,0,0,0\nBEGIN\n  BLOCK \"StringFileInfo\"\n  BEGIN\n"
  },
  {
    "path": "shaders/curvature.frag",
    "chars": 1293,
    "preview": "#version 460\n\nlayout (location = 0) in vec2 TexCoord;\nlayout (location = 0) out vec4 FragColor;\nlayout (binding = 0) uni"
  },
  {
    "path": "shaders/decoder.frag",
    "chars": 2788,
    "preview": "#version 460\n\nlayout (location = 0) in vec2 TexCoord;\nlayout (location = 0) out vec4 FragColor;\nlayout (binding = 0) uni"
  },
  {
    "path": "shaders/default.frag",
    "chars": 223,
    "preview": "#version 460\n\nlayout (location = 0) in vec2 TexCoord;\nlayout (location = 0) out vec4 FragColor;\nlayout (binding = 0) uni"
  },
  {
    "path": "shaders/default.vert",
    "chars": 235,
    "preview": "#version 460\n\nlayout (location = 0) in vec2 position;\nlayout (location = 1) in vec2 in_uv;\nlayout (location = 0) out vec"
  },
  {
    "path": "shaders/encoder.frag",
    "chars": 1935,
    "preview": "#version 460\n\nlayout (location = 0) in vec2 TexCoord;\nlayout (location = 0) out vec4 FragColor;\nlayout (binding = 0) uni"
  },
  {
    "path": "shaders/noise.frag",
    "chars": 968,
    "preview": "#version 460\n\nlayout (location = 0) in vec2 TexCoord;\nlayout (location = 0) out vec4 FragColor;\nlayout (binding = 0) uni"
  },
  {
    "path": "shaders/scanlines.frag",
    "chars": 2136,
    "preview": "#version 460\n\nlayout (location = 0) in vec2 TexCoord;\nlayout (location = 0) out vec4 FragColor;\nlayout (binding = 0) uni"
  },
  {
    "path": "shaders/shader.vert",
    "chars": 432,
    "preview": "#version 460\n\nlayout (location = 0) out vec2 out_uv;\n\nconst vec2 vertices[4] = vec2[](\n    vec2(-1.0, -1.0),\n    vec2( 1"
  },
  {
    "path": "src/dev/ds.c",
    "chars": 10714,
    "preview": "#include \"ds.h\"\n\n#include <stdlib.h>\n#include <string.h>\n\n#define printf(fmt, ...)(0)\n\nstatic inline uint8_t ds_get_mode"
  },
  {
    "path": "src/dev/ds.h",
    "chars": 1330,
    "preview": "#ifndef DS_H\n#define DS_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n#include <stdlib.h>\n\n#include \"io"
  },
  {
    "path": "src/dev/guncon.c",
    "chars": 8870,
    "preview": "#include \"guncon.h\"\n\n#include <stdlib.h>\n#include <string.h>\n\n// #define printf(fmt, ...)(0)\n\nstatic inline uint8_t gunc"
  },
  {
    "path": "src/dev/guncon.h",
    "chars": 757,
    "preview": "#ifndef GUNCON_H\n#define GUNCON_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n#include <stdlib.h>\n\n#inc"
  },
  {
    "path": "src/dev/mcd.c",
    "chars": 11779,
    "preview": "#include \"mcd.h\"\n\n#include <stdlib.h>\n#include <string.h>\n#include <assert.h>\n\n#define printf(fmt,...)(0)\n\nvoid mcd_flus"
  },
  {
    "path": "src/dev/mcd.h",
    "chars": 814,
    "preview": "#ifndef MCD_H\n#define MCD_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n#include <stdlib.h>\n\n#include \""
  },
  {
    "path": "src/dev/mtap.c",
    "chars": 1158,
    "preview": "#include <stdlib.h>\n#include <string.h>\n\n#include \"mtap.h\"\n\n#define printf(fmt,...)(0)\n\nvoid mtap_cmd_probe(struct ps2_s"
  },
  {
    "path": "src/dev/mtap.h",
    "chars": 323,
    "preview": "#ifndef MTAP_H\n#define MTAP_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n#include <stdlib.h>\n\n#include"
  },
  {
    "path": "src/dev/ps1_mcd.c",
    "chars": 5623,
    "preview": "#include \"ps1_mcd.h\"\n\n#include <stdlib.h>\n#include <string.h>\n#include <assert.h>\n\n#define printf(fmt,...)(0)\n\nvoid ps1_"
  },
  {
    "path": "src/dev/ps1_mcd.h",
    "chars": 564,
    "preview": "#ifndef PS1_MCD_H\n#define PS1_MCD_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n#include <stdlib.h>\n\n#i"
  },
  {
    "path": "src/ee/bus.c",
    "chars": 20219,
    "preview": "#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n\n#include \"bus.h\"\n#include \"bus_decl.h\"\n\nstruct ee_bus* ee_bu"
  },
  {
    "path": "src/ee/bus.h",
    "chars": 2812,
    "preview": "#ifndef EE_BUS_H\n#define EE_BUS_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include \"u128.h\"\n\n#include \"dmac.h\"\n#include"
  },
  {
    "path": "src/ee/bus_decl.h",
    "chars": 877,
    "preview": "#ifndef EE_BUS_DECL_H\n#define EE_BUS_DECL_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include \"u128.h\"\n\nstruct ee_bus;\n\n"
  },
  {
    "path": "src/ee/dmac.c",
    "chars": 42580,
    "preview": "#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <assert.h>\n\n#include \"dmac.h\"\n\n#define printf(fmt, ."
  },
  {
    "path": "src/ee/dmac.h",
    "chars": 2994,
    "preview": "struct ps2_dmac;\n\n#ifndef DMAC_H\n#define DMAC_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n\n#include \""
  },
  {
    "path": "src/ee/ee.h",
    "chars": 5491,
    "preview": "#ifndef EE_H\n#define EE_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n\n#include \"shared/ram.h\"\n\n#includ"
  },
  {
    "path": "src/ee/ee_cached.cpp",
    "chars": 177719,
    "preview": "#include <stdio.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <string.h>\n#include <signal.h>\n#include <assert.h>\n#"
  },
  {
    "path": "src/ee/ee_def.hpp",
    "chars": 4087,
    "preview": "#pragma once\n\n#include <cstdint>\n\n#include \"shared/ram.h\"\n\n#include \"u128.h\"\n\n#include \"vu.h\"\n#include \"vu_def.hpp\"\n\n#in"
  },
  {
    "path": "src/ee/ee_dis.c",
    "chars": 80376,
    "preview": "#include <stdio.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <string.h>\n\n#include \"ee_dis.h\"\n\nstatic struct ee_di"
  },
  {
    "path": "src/ee/ee_dis.h",
    "chars": 302,
    "preview": "#ifndef EE_DIS_H\n#define EE_DIS_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n\nstruct ee_dis_state {\n  "
  },
  {
    "path": "src/ee/ee_uncached.c",
    "chars": 129571,
    "preview": "#include <stdio.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <string.h>\n#include <math.h>\n#include <signal.h>\n#in"
  },
  {
    "path": "src/ee/ee_uncached.h",
    "chars": 5870,
    "preview": "#ifndef EE_UNCACHED_H\n#define EE_UNCACHED_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n\n#include \"shar"
  },
  {
    "path": "src/ee/gif.c",
    "chars": 12905,
    "preview": "#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n\n#include \"gif.h\"\n\n// Burnout games need the FQC field on GIF"
  },
  {
    "path": "src/ee/gif.h",
    "chars": 1574,
    "preview": "#ifndef GIF_H\n#define GIF_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n\n#include \"gs/gs.h\"\n#include \"u"
  },
  {
    "path": "src/ee/intc.c",
    "chars": 3273,
    "preview": "#include <stdlib.h>\n#include <stdint.h>\n#include <string.h>\n#include <stdio.h>\n\n#include \"intc.h\"\n\nstatic inline void in"
  },
  {
    "path": "src/ee/intc.h",
    "chars": 1357,
    "preview": "struct ps2_intc;\n\n#ifndef INTC_H\n#define INTC_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n\n#include \""
  },
  {
    "path": "src/ee/syscall.h",
    "chars": 4214,
    "preview": "static const char* ee_get_syscall(int n) {\n    switch (n) {\n        case 0x01: return \"void ResetEE(int reset_flag)\";\n  "
  },
  {
    "path": "src/ee/timers.c",
    "chars": 12966,
    "preview": "#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n\n#include \"timers.h\"\n\n#define EE_TIMER_SCHED_QUANTUM 64\n\nstat"
  },
  {
    "path": "src/ee/timers.h",
    "chars": 1889,
    "preview": "#ifndef EE_TIMERS_H\n#define EE_TIMERS_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n\n#include \"schedule"
  },
  {
    "path": "src/ee/vif.c",
    "chars": 33396,
    "preview": "#include <assert.h>\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <math.h>\n\n#include \"vif.h\"\n\n#def"
  },
  {
    "path": "src/ee/vif.h",
    "chars": 2558,
    "preview": "#ifndef VIF_H\n#define VIF_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n\n#include \"u128.h\"\n#include \"bu"
  },
  {
    "path": "src/ee/vu.h",
    "chars": 3080,
    "preview": "struct vu_state;\n\n#ifndef VU_H\n#define VU_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n\n#include \"u128"
  },
  {
    "path": "src/ee/vu_cached.cpp",
    "chars": 116117,
    "preview": "#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <math.h>\n#include <fenv.h>\n#include <utility>\n\n#incl"
  },
  {
    "path": "src/ee/vu_def.hpp",
    "chars": 16260,
    "preview": "#pragma once\n\n#include <cstdint>\n#include <unordered_map>\n#include <vector>\n\n#include \"vu.h\"\n\nstruct vu_block_entry {\n  "
  },
  {
    "path": "src/ee/vu_dis.c",
    "chars": 45470,
    "preview": "#include <stdio.h>\n\n#include \"vu_dis.h\"\n\n#define VU_LD_DEST ((o >> 21) & 0xf)\n#define VU_LD_DI(i) (o & (1 << (24 - i)))\n"
  },
  {
    "path": "src/ee/vu_dis.h",
    "chars": 382,
    "preview": "#ifndef VU_DIS_H\n#define VU_DIS_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n\nstruct vu_dis_state {\n  "
  },
  {
    "path": "src/ee/vu_uncached.c",
    "chars": 103862,
    "preview": "#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <math.h>\n#include <fenv.h>\n\n#include \"vu.h\"\n#include"
  },
  {
    "path": "src/elf.h",
    "chars": 118243,
    "preview": "/* This is the original elf.h file from the GNU C Library; I only removed\n   the inclusion of feature.h and added defini"
  },
  {
    "path": "src/gs/gs.c",
    "chars": 35634,
    "preview": "#include <stdint.h>\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n\n#include \"gs.h\"\n#include \"ee/intc.h\"\n#in"
  },
  {
    "path": "src/gs/gs.h",
    "chars": 8700,
    "preview": "#ifndef GS_H\n#define GS_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n\n#include \"u128.h\"\n#include \"sche"
  },
  {
    "path": "src/gs/renderer/config.hpp",
    "chars": 310,
    "preview": "#pragma once\n\nstruct hardware_config {\n    int super_sampling = 0;\n    bool force_progressive = false;\n    bool overscan"
  },
  {
    "path": "src/gs/renderer/hardware.cpp",
    "chars": 7125,
    "preview": "#include \"hardware.hpp\"\n\nvoid* hardware_create() {\n    return new hardware_state();\n}\n\nbool hardware_init(void* udata, c"
  },
  {
    "path": "src/gs/renderer/hardware.hpp",
    "chars": 3173,
    "preview": "#pragma once\n\n#include <vector>\n#include <cstdio>\n\n#include <SDL3/SDL.h>\n\n#include \"renderer.hpp\"\n\n#include \"Granite/vul"
  },
  {
    "path": "src/gs/renderer/null.cpp",
    "chars": 620,
    "preview": "#include \"renderer.hpp\"\n\n#include \"null.hpp\"\n\nvoid* null_create() {\n    return nullptr;\n}\n\nbool null_init(void* udata, c"
  },
  {
    "path": "src/gs/renderer/null.hpp",
    "chars": 427,
    "preview": "#pragma once\n\n#include <vector>\n#include <cstdio>\n\n#include <SDL3/SDL.h>\n\n#include \"renderer.hpp\"\n\nvoid* null_create();\n"
  },
  {
    "path": "src/gs/renderer/renderer.cpp",
    "chars": 2433,
    "preview": "#include \"renderer.hpp\"\n\n#include \"null.hpp\"\n#include \"hardware.hpp\"\n\nrenderer_state* renderer_create(void) {\n    return"
  },
  {
    "path": "src/gs/renderer/renderer.hpp",
    "chars": 2657,
    "preview": "#pragma once\n\n#include \"Granite/vulkan/vulkan_headers.hpp\"\n\n#include <volk.h>\n\n#include \"gs/gs.h\"\n\n#include \"config.hpp\""
  },
  {
    "path": "src/gs/renderer/software_thread.cpp",
    "chars": 103698,
    "preview": "#include <cstdlib>\n#include <cstring>\n#include <cstdio>\n#include <cmath>\n\n#include \"gs/gs.h\"\n#include \"software_thread.h"
  },
  {
    "path": "src/gs/renderer/software_thread.hpp",
    "chars": 3657,
    "preview": "#pragma once\n\n#include <vector>\n#include <cstdio>\n#include <thread>\n#include <chrono>\n#include <atomic>\n#include <queue>"
  },
  {
    "path": "src/iop/bus.c",
    "chars": 14018,
    "preview": "#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n\n#include \"bus.h\"\n#include \"bus_decl.h\"\n\n#define printf(fmt, "
  },
  {
    "path": "src/iop/bus.h",
    "chars": 2935,
    "preview": "#ifndef IOP_BUS_H\n#define IOP_BUS_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include \"u128.h\"\n\n// Shared IOP/EE hardwar"
  },
  {
    "path": "src/iop/bus_decl.h",
    "chars": 589,
    "preview": "#ifndef IOP_BUS_DECL_H\n#define IOP_BUS_DECL_H\n\n#include <stdint.h>\n\nstruct iop_bus;\n\nstruct iop_bus* iop_bus_create(void"
  },
  {
    "path": "src/iop/cdvd.c",
    "chars": 42167,
    "preview": "#include <stdint.h>\n#include <stdlib.h>\n#include <string.h>\n#include <assert.h>\n#include <stdio.h>\n#include <ctype.h>\n#i"
  },
  {
    "path": "src/iop/cdvd.h",
    "chars": 4605,
    "preview": "#ifndef CDVD_H\n#define CDVD_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n\n#include \"scheduler.h\"\n#incl"
  },
  {
    "path": "src/iop/disc/bin.c",
    "chars": 1306,
    "preview": "#include <stdlib.h>\n\n#include \"../disc.h\"\n#include \"bin.h\"\n\nstruct disc_bin* bin_create(void) {\n    return malloc(sizeof"
  },
  {
    "path": "src/iop/disc/bin.h",
    "chars": 662,
    "preview": "#ifndef BIN_H\n#define BIN_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdio.h>\n#include <stdint.h>\n\n#include \"."
  },
  {
    "path": "src/iop/disc/chd.c",
    "chars": 3488,
    "preview": "#include <stdlib.h>\n#include <string.h>\n#include <ctype.h>\n\n#include \"chd.h\"\n\nint get_sector_type_size(const char* type)"
  },
  {
    "path": "src/iop/disc/chd.h",
    "chars": 790,
    "preview": "#ifndef CHD_H\n#define CHD_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include \"../disc.h\"\n\n#include <libchdr/chd.h>\n#inc"
  },
  {
    "path": "src/iop/disc/ciso.c",
    "chars": 4693,
    "preview": "#include <stdlib.h>\n#include <string.h>\n#include <ctype.h>\n\n#include \"ciso.h\"\n\n#define CISO_DEFLATE 0\n#define CISO_LZ4 1"
  },
  {
    "path": "src/iop/disc/ciso.h",
    "chars": 1124,
    "preview": "#ifndef CISO_H\n#define CISO_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include \"../disc.h\"\n\n#include <stdio.h>\n#include"
  },
  {
    "path": "src/iop/disc/cue.c",
    "chars": 14468,
    "preview": "#include <stdlib.h>\n#include <stdint.h>\n#include <string.h>\n#include <stdio.h>\n#include <ctype.h>\n\n#include \"cue.h\"\n#inc"
  },
  {
    "path": "src/iop/disc/cue.h",
    "chars": 2032,
    "preview": "#ifndef CUE_H\n#define CUE_H\n\n#include \"list.h\"\n#include \"../disc.h\"\n\n#include <stdint.h>\n#include <stddef.h>\n#include <s"
  },
  {
    "path": "src/iop/disc/iso.c",
    "chars": 1121,
    "preview": "#include <stdlib.h>\n\n#include \"iso.h\"\n\nstruct disc_iso* iso_create(void) {\n    return malloc(sizeof(struct disc_iso));\n}"
  },
  {
    "path": "src/iop/disc/iso.h",
    "chars": 662,
    "preview": "#ifndef ISO_H\n#define ISO_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include \"../disc.h\"\n\n#include <stdio.h>\n#include <"
  },
  {
    "path": "src/iop/disc.c",
    "chars": 18942,
    "preview": "#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <ctype.h>\n\n#include \"disc.h\"\n#include \"disc/iso.h\"\n#"
  },
  {
    "path": "src/iop/disc.h",
    "chars": 3104,
    "preview": "#ifndef DISC_H\n#define DISC_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n\n#ifdef _MSC_VER\n#define fsee"
  },
  {
    "path": "src/iop/dma.c",
    "chars": 29849,
    "preview": "#include <stdint.h>\n#include <stdlib.h>\n#include <string.h>\n#include <assert.h>\n#include <stdio.h>\n#include <ctype.h>\n#i"
  },
  {
    "path": "src/iop/dma.h",
    "chars": 3469,
    "preview": "#ifndef IOP_DMA_H\n#define IOP_DMA_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n\n#include \"u128.h\"\n\n#in"
  },
  {
    "path": "src/iop/fw.c",
    "chars": 2960,
    "preview": "#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n\n#include \"fw.h\"\n\nstruct ps2_fw* ps2_fw_create(void) {\n    re"
  },
  {
    "path": "src/iop/fw.h",
    "chars": 757,
    "preview": "#ifndef FW_H\n#define FW_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n\n#include \"intc.h\"\n\nstruct ps2_fw"
  },
  {
    "path": "src/iop/hle/ioman.cpp",
    "chars": 12821,
    "preview": "#include <filesystem>\n#include <cstdlib>\n#include <cstdio>\n#include <string>\n\n#include \"ioman.h\"\n\n#include \"../iop.h\"\n#i"
  },
  {
    "path": "src/iop/hle/ioman.h",
    "chars": 1983,
    "preview": "#ifndef IOMAN_H\n#define IOMAN_H\n\n#include \"../iop.h\"\n#include \"../iop_export.h\"\n\n#define IOMAN_DEV_UNKNOWN 0\n\n// BIOS RO"
  },
  {
    "path": "src/iop/hle/loadcore.c",
    "chars": 2504,
    "preview": "#include \"loadcore.h\"\n\n#include \"../iop.h\"\n\n#include <stdlib.h>\n#include <string.h>\n\nstatic unsigned get_module_list(str"
  },
  {
    "path": "src/iop/hle/loadcore.h",
    "chars": 449,
    "preview": "#ifndef LOADCORE_H_\n#define LOADCORE_H_\n\n#include \"../iop.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nstruct iop_module "
  },
  {
    "path": "src/iop/hle/sysmem.c",
    "chars": 2961,
    "preview": "#include \"sysmem.h\"\n\n#define SM_PUTCHAR(c) \\\n    iop->sm_putchar(iop->sm_putchar_udata, c);\n\nint reg_index = 0;\n\nuint32_"
  },
  {
    "path": "src/iop/hle/sysmem.h",
    "chars": 202,
    "preview": "#ifndef SYSMEM_H\n#define SYSMEM_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include \"../iop.h\"\n#include \"../iop_export.h"
  },
  {
    "path": "src/iop/intc.c",
    "chars": 2256,
    "preview": "#include <stdint.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#include \"intc.h\"\n\nstruct ps2_iop_intc* "
  },
  {
    "path": "src/iop/intc.h",
    "chars": 2789,
    "preview": "#ifndef IOP_INTC_H\n#define IOP_INTC_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n\n#include \"iop.h\"\n\n/*"
  },
  {
    "path": "src/iop/iop.c",
    "chars": 29034,
    "preview": "#include <stdlib.h>\r\n#include <string.h>\r\n\r\n#include \"iop.h\"\r\n#include \"iop_dis.h\"\r\n\r\n#include \"iop_export.h\"\r\n\r\n// stat"
  },
  {
    "path": "src/iop/iop.h",
    "chars": 7744,
    "preview": "#ifndef IOP_H\r\n#define IOP_H\r\n\r\n#ifdef __cplusplus\r\nextern \"C\" {\r\n#endif\r\n\r\n#include <stdint.h>\r\n#include <stdio.h>\r\n\r\n#"
  },
  {
    "path": "src/iop/iop_dis.c",
    "chars": 10253,
    "preview": "// license:MIT\n// copyright-holders:Lisandro Alarcon (Allkern)\n\n/**\n * @file r3000d.c\n * @brief Disassembler for MIPS R3"
  },
  {
    "path": "src/iop/iop_dis.h",
    "chars": 890,
    "preview": "// license:MIT\n// copyright-holders:Lisandro Alarcon (Allkern)\n\n/**\n * @file iop_dis.h\n * @brief Disassembler for MIPS R"
  },
  {
    "path": "src/iop/iop_export.c",
    "chars": 3783,
    "preview": "#include \"iop_export.h\"\n\nstatic inline uint32_t irx_import_table_addr(struct iop_state* iop, int entry) {\n    uint32_t i"
  },
  {
    "path": "src/iop/iop_export.h",
    "chars": 1246,
    "preview": "#ifndef IOP_EXPORT_H\n#define IOP_EXPORT_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <string.h>\n\n#include \"iop.h\""
  },
  {
    "path": "src/iop/rpc.c",
    "chars": 5160,
    "preview": "#include <stdlib.h>\n#include <stdint.h>\n#include <stdio.h>\n\n#include \"rpc.h\"\n\n#define printf(fmt, ...)(0)\n\nconst char* r"
  },
  {
    "path": "src/iop/rpc.h",
    "chars": 2852,
    "preview": "#ifndef RPC_H\n#define RPC_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n\n#include \"iop.h\"\n\nstruct __att"
  },
  {
    "path": "src/iop/sio2.c",
    "chars": 9760,
    "preview": "#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n\n#include \"sio2.h\"\n\nstatic inline void sio2_reset(struct ps2_"
  },
  {
    "path": "src/iop/sio2.h",
    "chars": 1567,
    "preview": "#ifndef SIO2_H\n#define SIO2_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n\n#include \"queue.h\"\n#include "
  },
  {
    "path": "src/iop/spu2.c",
    "chars": 41757,
    "preview": "#include <stdint.h>\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n\n#include \"spu2.h\"\n\nFILE* output = NULL;\n"
  },
  {
    "path": "src/iop/spu2.h",
    "chars": 6816,
    "preview": "#ifndef SPU2_H\n#define SPU2_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n\n#include \"scheduler.h\"\n#incl"
  },
  {
    "path": "src/iop/timers.c",
    "chars": 8514,
    "preview": "#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n\n#include \"timers.h\"\n#include \"intc.h\"\n#include \"scheduler.h\""
  },
  {
    "path": "src/iop/timers.h",
    "chars": 1461,
    "preview": "#ifndef IOP_TIMER_H\n#define IOP_TIMER_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n\nstruct iop_timer {"
  },
  {
    "path": "src/iop/usb.c",
    "chars": 4300,
    "preview": "#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n\n#include \"usb.h\"\n\nstruct ps2_usb* ps2_usb_create(void) {\n   "
  },
  {
    "path": "src/iop/usb.h",
    "chars": 1251,
    "preview": "#ifndef USB_H\n#define USB_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n\n#define OHCI_BASE 0x1f801600\n#"
  },
  {
    "path": "src/ipu/chromtable.cpp",
    "chars": 474,
    "preview": "#include \"chromtable.hpp\"\n\nVLC_Entry ChromTable::table[] =\n{\n    {0x0, 0, 2},\n    {0x1, 1, 2},\n    {0x2, 2, 2},\n    {0x6"
  },
  {
    "path": "src/ipu/chromtable.hpp",
    "chars": 304,
    "preview": "#ifndef CHROMTABLE_HPP\n#define CHROMTABLE_HPP\n#include \"vlc_table.hpp\"\n\nclass ChromTable : public VLC_Table\n{\n    privat"
  },
  {
    "path": "src/ipu/codedblockpattern.cpp",
    "chars": 1587,
    "preview": "#include \"codedblockpattern.hpp\"\n\nVLC_Entry CodedBlockPattern::table[] =\n{\n    {0x7, 60, 3},\n    {0xD, 4, 4},\n    {0xC, "
  },
  {
    "path": "src/ipu/codedblockpattern.hpp",
    "chars": 339,
    "preview": "#ifndef CODEDBLOCKPATTERN_HPP\n#define CODEDBLOCKPATTERN_HPP\n#include \"vlc_table.hpp\"\n\nclass CodedBlockPattern : public V"
  },
  {
    "path": "src/ipu/dct_coeff.cpp",
    "chars": 507,
    "preview": "#include <cstdio>\n#include <cstdlib>\n#include \"dct_coeff.hpp\"\n\nDCT_Coeff::DCT_Coeff(VLC_Entry* table, int table_size, in"
  },
  {
    "path": "src/ipu/dct_coeff.hpp",
    "chars": 757,
    "preview": "#ifndef DCT_COEFF_HPP\n#define DCT_COEFF_HPP\n#include \"vlc_table.hpp\"\n\nstruct RunLevelPair\n{\n    int run, level;\n};\n\nclas"
  },
  {
    "path": "src/ipu/dct_coeff_table0.cpp",
    "chars": 7401,
    "preview": "#include <cstdio>\n#include <cstdlib>\n#include \"dct_coeff_table0.hpp\"\n\n#define printf(fmt, ...)(0)\n\nVLC_Entry DCT_Coeff_T"
  },
  {
    "path": "src/ipu/dct_coeff_table0.hpp",
    "chars": 655,
    "preview": "#ifndef DCT_COEFF_TABLE0_HPP\n#define DCT_COEFF_TABLE0_HPP\n#include \"dct_coeff.hpp\"\n\nclass DCT_Coeff_Table0 : public DCT_"
  },
  {
    "path": "src/ipu/dct_coeff_table1.cpp",
    "chars": 7153,
    "preview": "#include <cstdio>\n#include <cstdlib>\n#include \"dct_coeff_table1.hpp\"\n\n#define printf(fmt, ...)(0)\n\nVLC_Entry DCT_Coeff_T"
  },
  {
    "path": "src/ipu/dct_coeff_table1.hpp",
    "chars": 655,
    "preview": "#ifndef DCT_COEFF_TABLE1_HPP\n#define DCT_COEFF_TABLE1_HPP\n#include \"dct_coeff.hpp\"\n\nclass DCT_Coeff_Table1 : public DCT_"
  },
  {
    "path": "src/ipu/ipu.cpp",
    "chars": 49345,
    "preview": "#include <cmath>\n#include <cstdio>\n#include <cstdlib>\n#include <cstring>\n#include <limits>\n#include \"ipu.hpp\"\n#include \""
  },
  {
    "path": "src/ipu/ipu.h",
    "chars": 1145,
    "preview": "#ifndef IPU_H\n#define IPU_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include \"ee/dmac.h\"\n#include \"ee/intc.h\"\n#include "
  },
  {
    "path": "src/ipu/ipu.hpp",
    "chars": 4976,
    "preview": "#ifndef IPU_HPP\n#define IPU_HPP\n#include <cstdint>\n#include <queue>\n\n#include \"u128.h\"\n#include \"chromtable.hpp\"\n#includ"
  },
  {
    "path": "src/ipu/ipu_fifo.cpp",
    "chars": 1787,
    "preview": "#include <cstdlib>\n#include <cstdio>\n#include \"ipu_fifo.hpp\"\n\nbool IPU_FIFO::get_bits(uint32_t &data, int bits)\n{\n    in"
  },
  {
    "path": "src/ipu/ipu_fifo.hpp",
    "chars": 373,
    "preview": "#ifndef IPU_FIFO_HPP\n#define IPU_FIFO_HPP\n#include <cstdint>\n#include <queue>\n\n#include \"u128.h\"\n\nstruct IPU_FIFO\n{\n    "
  },
  {
    "path": "src/ipu/lumtable.cpp",
    "chars": 479,
    "preview": "#include \"lumtable.hpp\"\n\nVLC_Entry LumTable::table[] =\n{\n    {0x0000, 1, 2},\n    {0x0001, 2, 2},\n    {0x0004, 0, 3},\n   "
  },
  {
    "path": "src/ipu/lumtable.hpp",
    "chars": 294,
    "preview": "#ifndef LUMTABLE_HPP\n#define LUMTABLE_HPP\n#include \"vlc_table.hpp\"\n\nclass LumTable : public VLC_Table\n{\n    private:\n   "
  },
  {
    "path": "src/ipu/mac_addr_inc.cpp",
    "chars": 1181,
    "preview": "#include \"mac_addr_inc.hpp\"\n\nVLC_Entry MacroblockAddrInc::table[] =\n{\n    {0x1, 0x10001, 1},\n    {0x3, 0x30002, 3},\n    "
  },
  {
    "path": "src/ipu/mac_addr_inc.hpp",
    "chars": 318,
    "preview": "#ifndef MAC_ADDR_INC_H\n#define MAC_ADDR_INC_H\n#include \"vlc_table.hpp\"\n\nclass MacroblockAddrInc : public VLC_Table\n{\n   "
  },
  {
    "path": "src/ipu/mac_b_pic.cpp",
    "chars": 499,
    "preview": "#include \"mac_b_pic.hpp\"\n\nVLC_Entry Macroblock_BPic::table[] =\n{\n    {0x2, 0x2000C, 2},\n    {0x3, 0x2000E, 2},\n    {0x2,"
  },
  {
    "path": "src/ipu/mac_b_pic.hpp",
    "chars": 311,
    "preview": "#ifndef MAC_B_PIC_HPP\n#define MAC_B_PIC_HPP\n#include \"vlc_table.hpp\"\n\nclass Macroblock_BPic : public VLC_Table\n{\n    pri"
  },
  {
    "path": "src/ipu/mac_i_pic.cpp",
    "chars": 262,
    "preview": "#include \"mac_i_pic.hpp\"\n\nVLC_Entry Macroblock_IPic::table[] =\n{\n    {0x1, 0x10001, 1},\n    {0x1, 0x20011, 2}\n};\n\nunsign"
  },
  {
    "path": "src/ipu/mac_i_pic.hpp",
    "chars": 310,
    "preview": "#ifndef MAC_I_PIC_HPP\n#define MAC_I_PIC_HPP\n#include \"vlc_table.hpp\"\n\nclass Macroblock_IPic : public VLC_Table\n{\n    pri"
  },
  {
    "path": "src/ipu/mac_p_pic.cpp",
    "chars": 409,
    "preview": "#include \"mac_p_pic.hpp\"\n\nVLC_Entry Macroblock_PPic::table[] =\n{\n    {0x1, 0x1000A, 1},\n    {0x1, 0x20002, 2},\n    {0x1,"
  },
  {
    "path": "src/ipu/mac_p_pic.hpp",
    "chars": 310,
    "preview": "#ifndef MAC_P_PIC_HPP\n#define MAC_P_PIC_HPP\n#include \"vlc_table.hpp\"\n\nclass Macroblock_PPic : public VLC_Table\n{\n    pri"
  },
  {
    "path": "src/ipu/motioncode.cpp",
    "chars": 1072,
    "preview": "#include \"motioncode.hpp\"\n\nVLC_Entry MotionCode::table[] =\n{\n    {0x1, 0x10000, 1},\n    {0x2, 0x30001, 3},\n    {0x3, 0x3"
  },
  {
    "path": "src/ipu/motioncode.hpp",
    "chars": 304,
    "preview": "#ifndef MOTIONCODE_HPP\n#define MOTIONCODE_HPP\n#include \"vlc_table.hpp\"\n\nclass MotionCode : public VLC_Table\n{\n    privat"
  },
  {
    "path": "src/ipu/vlc_table.cpp",
    "chars": 1037,
    "preview": "#include <cstdlib>\n#include <cstdio>\n#include \"vlc_table.hpp\"\n\nVLC_Table::VLC_Table(VLC_Entry* table, int table_size, in"
  },
  {
    "path": "src/ipu/vlc_table.hpp",
    "chars": 694,
    "preview": "#ifndef VLC_TABLE_HPP\n#define VLC_TABLE_HPP\n#include <stdexcept>\n#include <cstdint>\n#include <queue>\n#include \"ipu_fifo."
  },
  {
    "path": "src/list.c",
    "chars": 1964,
    "preview": "#include \"list.h\"\n\n#include <stdlib.h>\n#include <string.h>\n\nlist_t* list_create(void) {\n    list_t* list = malloc(sizeof"
  },
  {
    "path": "src/list.h",
    "chars": 658,
    "preview": "#ifndef LIST_H\n#define LIST_H\n\n#include <stddef.h>\n\ntypedef struct node_t node_t;\n\ntypedef struct node_t {\n    node_t* n"
  },
  {
    "path": "src/md5.c",
    "chars": 7884,
    "preview": "/*\n * Derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm\n * and modified slightly to be functionally "
  },
  {
    "path": "src/md5.h",
    "chars": 676,
    "preview": "#ifndef MD5_H\n#define MD5_H\n\n#include <stdio.h>\n#include <stdint.h>\n#include <string.h>\n#include <stdlib.h>\n\nstruct md5_"
  },
  {
    "path": "src/ps2.c",
    "chars": 19830,
    "preview": "#include <stdint.h>\n#include <stdlib.h>\n#include <stddef.h>\n#include <string.h>\n\n#include \"ps2.h\"\n#include \"rom.h\"\n\nstru"
  },
  {
    "path": "src/ps2.h",
    "chars": 3979,
    "preview": "#ifndef PS2_H\n#define PS2_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include \"ee/bus.h\"\n#include \"ee/ee.h\"\n#include \"ee"
  },
  {
    "path": "src/ps2_elf.c",
    "chars": 4119,
    "preview": "#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n\n#include \"ps2_elf.h\"\n\nint ps2_elf_load(struct ps2_state* ps2"
  },
  {
    "path": "src/ps2_elf.h",
    "chars": 255,
    "preview": "#ifndef PS2_ELF_H\n#define PS2_ELF_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#ifdef __linux__\n#include <elf.h>\n#else\n#in"
  },
  {
    "path": "src/ps2_iso9660.c",
    "chars": 3813,
    "preview": "#include <stdlib.h>\n#include <string.h>\n#include <stdint.h>\n#include <stdio.h>\n#include <ctype.h>\n\n#include \"ps2_iso9660"
  },
  {
    "path": "src/ps2_iso9660.h",
    "chars": 1680,
    "preview": "#ifndef PS2_ISO9660_H\n#define PS2_ISO9660_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n#include <stdio"
  },
  {
    "path": "src/queue.c",
    "chars": 1495,
    "preview": "#include <stdlib.h>\n#include <string.h>\n#include <stddef.h>\n#include <stdio.h>\n\n#include \"queue.h\"\n\nstruct queue_state* "
  },
  {
    "path": "src/queue.h",
    "chars": 720,
    "preview": "#ifndef QUEUE_H\n#define QUEUE_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n\nstruct queue_state {\n    u"
  }
]

// ... and 45 more files (download for full content)

About this extraction

This page contains the full source code of the allkern/iris GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 245 files (2.4 MB), approximately 632.9k tokens, and a symbol index with 4661 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!