├── .clang-format ├── .github ├── Alber.desktop ├── FUNDING.yml ├── gles.patch ├── linux-appimage-qt.sh ├── linux-appimage.sh ├── mac-bundle-qt.sh ├── mac-bundle.sh ├── mac-libs.rb └── workflows │ ├── Android_Build.yml │ ├── HTTP_Build.yml │ ├── Hydra_Build.yml │ ├── Linux_AppImage_Build.yml │ ├── Linux_Build.yml │ ├── MacOS_Build.yml │ ├── Qt_Build.yml │ ├── Windows_Build.yml │ └── iOS_Build.yml ├── .gitignore ├── .gitlab-ci.yml ├── .gitmodules ├── CMakeLists.txt ├── LICENSE.md ├── cmake └── FindRenderDoc.cmake ├── docs ├── 3ds │ ├── accelerometer_readings │ │ ├── readings_flat_1.png │ │ ├── readings_flat_2.png │ │ ├── readings_shaking_1.png │ │ └── readings_shaking_2.png │ └── lighting.md ├── img │ ├── Alber.png │ ├── KirbyAndroid.png │ ├── KirbyRobobot.png │ ├── MK7.png │ ├── OoT_Title.png │ ├── battery_icon.png │ ├── display_icon.png │ ├── mac_icon.ico │ ├── panda.jpg │ ├── pokegang.png │ ├── rcow_icon.png │ ├── rnap_icon.png │ ├── rpog_icon.png │ ├── rsob_icon.png │ ├── rstarstruck_icon.png │ ├── rsyn_icon.png │ ├── runpog_icon.png │ ├── sdcard_icon.png │ ├── settings_icon.png │ ├── skyemu_icon.png │ ├── sparkling_icon.png │ ├── speaker_icon.png │ ├── windows_alt_icon.ico │ ├── windows_icon.ico │ └── windows_icon.rc ├── libretro │ └── panda3ds_libretro.info └── translations │ ├── el.ts │ ├── en.ts │ ├── es.ts │ ├── nl.ts │ ├── pt_br.ts │ └── sv.ts ├── include ├── PICA │ ├── draw_acceleration.hpp │ ├── dynapica │ │ ├── pica_recs.hpp │ │ ├── shader_rec.hpp │ │ ├── shader_rec_emitter_arm64.hpp │ │ ├── shader_rec_emitter_x64.hpp │ │ ├── vertex_loader_rec.hpp │ │ └── x64_regs.hpp │ ├── float_types.hpp │ ├── gpu.hpp │ ├── pica_frag_config.hpp │ ├── pica_frag_uniforms.hpp │ ├── pica_hash.hpp │ ├── pica_simd.hpp │ ├── pica_vert_config.hpp │ ├── pica_vertex.hpp │ ├── regs.hpp │ ├── shader.hpp │ ├── shader_decompiler.hpp │ ├── shader_gen.hpp │ ├── shader_gen_types.hpp │ └── shader_unit.hpp ├── action_replay.hpp ├── align.hpp ├── android_utils.hpp ├── applets │ ├── applet.hpp │ ├── applet_manager.hpp │ ├── error_applet.hpp │ ├── mii_selector.hpp │ └── software_keyboard.hpp ├── arm_defs.hpp ├── audio │ ├── aac.hpp │ ├── aac_decoder.hpp │ ├── audio_device.hpp │ ├── audio_device_interface.hpp │ ├── audio_interpolation.hpp │ ├── dsp_core.hpp │ ├── dsp_shared_mem.hpp │ ├── dsp_simd.hpp │ ├── hle_core.hpp │ ├── hle_mixer.hpp │ ├── libretro_audio_device.hpp │ ├── miniaudio_device.hpp │ ├── null_core.hpp │ └── teakra_core.hpp ├── bitfield.hpp ├── capstone.hpp ├── cheats.hpp ├── colour.hpp ├── compiler_builtins.hpp ├── config.hpp ├── cpu.hpp ├── cpu_dynarmic.hpp ├── crypto │ └── aes_engine.hpp ├── discord_rpc.hpp ├── dynarmic_cp15.hpp ├── emulator.hpp ├── frontend_settings.hpp ├── fs │ ├── archive_base.hpp │ ├── archive_card_spi.hpp │ ├── archive_ext_save_data.hpp │ ├── archive_ncch.hpp │ ├── archive_save_data.hpp │ ├── archive_sdmc.hpp │ ├── archive_self_ncch.hpp │ ├── archive_system_save_data.hpp │ ├── archive_twl_photo.hpp │ ├── archive_twl_sound.hpp │ ├── archive_user_save_data.hpp │ ├── bad_word_list.hpp │ ├── country_list.hpp │ ├── ivfc.hpp │ ├── mii_data.hpp │ └── romfs.hpp ├── helpers.hpp ├── http_server.hpp ├── hydra_icon.hpp ├── input_mappings.hpp ├── io_file.hpp ├── ios_driver.h ├── ipc.hpp ├── kernel │ ├── config_mem.hpp │ ├── handles.hpp │ ├── kernel.hpp │ ├── kernel_types.hpp │ └── resource_limits.hpp ├── loader │ ├── 3dsx.hpp │ ├── lz77.hpp │ ├── ncch.hpp │ └── ncsd.hpp ├── logger.hpp ├── lua_manager.hpp ├── math_util.hpp ├── memory.hpp ├── memory_mapped_file.hpp ├── metaprogramming.hpp ├── panda_qt │ ├── about_window.hpp │ ├── cheats_window.hpp │ ├── config_window.hpp │ ├── elided_label.hpp │ ├── main_window.hpp │ ├── patch_window.hpp │ ├── screen.hpp │ ├── shader_editor.hpp │ └── text_editor.hpp ├── panda_sdl │ └── frontend_sdl.hpp ├── renderdoc.hpp ├── renderer.hpp ├── renderer_gl │ ├── gl_driver.hpp │ ├── gl_state.hpp │ ├── renderer_gl.hpp │ ├── surface_cache.hpp │ ├── surfaces.hpp │ └── textures.hpp ├── renderer_mtl │ ├── mtl_blit_pipeline_cache.hpp │ ├── mtl_command_encoder.hpp │ ├── mtl_common.hpp │ ├── mtl_depth_stencil_cache.hpp │ ├── mtl_draw_pipeline_cache.hpp │ ├── mtl_lut_texture.hpp │ ├── mtl_render_target.hpp │ ├── mtl_texture.hpp │ ├── mtl_vertex_buffer_cache.hpp │ ├── objc_helper.hpp │ ├── pica_to_mtl.hpp │ ├── renderer_mtl.hpp │ └── texture_decoder.hpp ├── renderer_null │ └── renderer_null.hpp ├── renderer_sw │ └── renderer_sw.hpp ├── renderer_vk │ ├── renderer_vk.hpp │ ├── vk_api.hpp │ ├── vk_debug.hpp │ ├── vk_descriptor_heap.hpp │ ├── vk_descriptor_update_batch.hpp │ ├── vk_memory.hpp │ ├── vk_pica.hpp │ └── vk_sampler_cache.hpp ├── result │ ├── result.hpp │ ├── result_cfg.hpp │ ├── result_common.hpp │ ├── result_fnd.hpp │ ├── result_fs.hpp │ ├── result_gsp.hpp │ ├── result_kernel.hpp │ └── result_os.hpp ├── ring_buffer.hpp ├── scheduler.hpp ├── sdl_sensors.hpp ├── services │ ├── ac.hpp │ ├── act.hpp │ ├── am.hpp │ ├── amiibo_device.hpp │ ├── apt.hpp │ ├── boss.hpp │ ├── cam.hpp │ ├── cecd.hpp │ ├── cfg.hpp │ ├── csnd.hpp │ ├── dlp_srvr.hpp │ ├── dsp.hpp │ ├── dsp_firmware_db.hpp │ ├── fonts.hpp │ ├── frd.hpp │ ├── fs.hpp │ ├── gsp_gpu.hpp │ ├── gsp_lcd.hpp │ ├── hid.hpp │ ├── http.hpp │ ├── ir_user.hpp │ ├── ldr_ro.hpp │ ├── mcu │ │ └── mcu_hwc.hpp │ ├── mic.hpp │ ├── ndm.hpp │ ├── news_u.hpp │ ├── nfc.hpp │ ├── nfc_types.hpp │ ├── nim.hpp │ ├── ns.hpp │ ├── nwm_uds.hpp │ ├── ptm.hpp │ ├── region_codes.hpp │ ├── service_manager.hpp │ ├── soc.hpp │ ├── ssl.hpp │ └── y2r.hpp ├── swap.hpp ├── system_models.hpp └── termcolor.hpp ├── readme.md ├── src ├── config.cpp ├── core │ ├── CPU │ │ ├── cpu_dynarmic.cpp │ │ └── dynarmic_cycles.cpp │ ├── PICA │ │ ├── draw_acceleration.cpp │ │ ├── dynapica │ │ │ ├── shader_rec.cpp │ │ │ ├── shader_rec_emitter_arm64.cpp │ │ │ └── shader_rec_emitter_x64.cpp │ │ ├── gpu.cpp │ │ ├── pica_hash.cpp │ │ ├── regs.cpp │ │ ├── shader_decompiler.cpp │ │ ├── shader_gen_glsl.cpp │ │ ├── shader_interpreter.cpp │ │ └── shader_unit.cpp │ ├── action_replay.cpp │ ├── applets │ │ ├── applet.cpp │ │ ├── applet_manager.cpp │ │ ├── error_applet.cpp │ │ ├── mii_selector.cpp │ │ └── software_keyboard.cpp │ ├── audio │ │ ├── aac_decoder.cpp │ │ ├── audio_interpolation.cpp │ │ ├── dsp_core.cpp │ │ ├── hle_core.cpp │ │ ├── miniaudio_device.cpp │ │ ├── null_core.cpp │ │ └── teakra_core.cpp │ ├── cheats.cpp │ ├── crypto │ │ └── aes_engine.cpp │ ├── fs │ │ ├── archive_card_spi.cpp │ │ ├── archive_ext_save_data.cpp │ │ ├── archive_ncch.cpp │ │ ├── archive_save_data.cpp │ │ ├── archive_sdmc.cpp │ │ ├── archive_self_ncch.cpp │ │ ├── archive_system_save_data.cpp │ │ ├── archive_twl_photo.cpp │ │ ├── archive_twl_sound.cpp │ │ ├── archive_user_save_data.cpp │ │ ├── ivfc.cpp │ │ └── romfs.cpp │ ├── kernel │ │ ├── address_arbiter.cpp │ │ ├── directory_operations.cpp │ │ ├── error.cpp │ │ ├── events.cpp │ │ ├── file_operations.cpp │ │ ├── idle_thread.cpp │ │ ├── kernel.cpp │ │ ├── memory_management.cpp │ │ ├── ports.cpp │ │ ├── resource_limits.cpp │ │ ├── threads.cpp │ │ └── timers.cpp │ ├── loader │ │ ├── 3dsx.cpp │ │ ├── elf.cpp │ │ ├── lz77.cpp │ │ ├── ncch.cpp │ │ └── ncsd.cpp │ ├── memory.cpp │ ├── renderer_gl │ │ ├── etc1.cpp │ │ ├── gl_state.cpp │ │ ├── renderer_gl.cpp │ │ └── textures.cpp │ ├── renderer_mtl │ │ ├── metal_cpp_impl.cpp │ │ ├── mtl_lut_texture.cpp │ │ ├── mtl_texture.cpp │ │ ├── objc_helper.mm │ │ ├── pica_to_mtl.cpp │ │ ├── renderer_mtl.cpp │ │ └── texture_decoder.cpp │ ├── renderer_null │ │ └── renderer_null.cpp │ ├── renderer_sw │ │ └── renderer_sw.cpp │ ├── renderer_vk │ │ ├── renderer_vk.cpp │ │ ├── vk_api.cpp │ │ ├── vk_debug.cpp │ │ ├── vk_descriptor_heap.cpp │ │ ├── vk_descriptor_update_batch.cpp │ │ ├── vk_memory.cpp │ │ ├── vk_pica.cpp │ │ └── vk_sampler_cache.cpp │ └── services │ │ ├── ac.cpp │ │ ├── act.cpp │ │ ├── am.cpp │ │ ├── amiibo_device.cpp │ │ ├── apt.cpp │ │ ├── boss.cpp │ │ ├── cam.cpp │ │ ├── cecd.cpp │ │ ├── cfg.cpp │ │ ├── csnd.cpp │ │ ├── dlp_srvr.cpp │ │ ├── dsp.cpp │ │ ├── fonts.cpp │ │ ├── fonts │ │ └── SharedFontReplacement.bin │ │ ├── frd.cpp │ │ ├── fs.cpp │ │ ├── gsp_gpu.cpp │ │ ├── gsp_lcd.cpp │ │ ├── hid.cpp │ │ ├── http.cpp │ │ ├── ir_user.cpp │ │ ├── ldr_ro.cpp │ │ ├── mcu │ │ └── mcu_hwc.cpp │ │ ├── mic.cpp │ │ ├── ndm.cpp │ │ ├── news_u.cpp │ │ ├── nfc.cpp │ │ ├── nim.cpp │ │ ├── ns.cpp │ │ ├── nwm_uds.cpp │ │ ├── ptm.cpp │ │ ├── service_manager.cpp │ │ ├── soc.cpp │ │ ├── ssl.cpp │ │ └── y2r.cpp ├── discord_rpc.cpp ├── emulator.cpp ├── frontend_settings.cpp ├── host_shaders │ ├── metal_blit.metal │ ├── metal_copy_to_lut_texture.metal │ ├── metal_shaders.metal │ ├── opengl_display.frag │ ├── opengl_display.vert │ ├── opengl_es_display.frag │ ├── opengl_es_display.vert │ ├── opengl_fragment_shader.frag │ ├── opengl_vertex_shader.vert │ ├── vulkan_display.frag │ └── vulkan_display.vert ├── http_server.cpp ├── hydra_core.cpp ├── io_file.cpp ├── ios_driver.mm ├── jni_driver.cpp ├── libretro_core.cpp ├── lua.cpp ├── memory_mapped_file.cpp ├── miniaudio │ ├── miniaudio.cpp │ └── miniaudio.m ├── panda_qt │ ├── about_window.cpp │ ├── cheats_window.cpp │ ├── config_window.cpp │ ├── elided_label.cpp │ ├── main.cpp │ ├── main_window.cpp │ ├── mappings.cpp │ ├── patch_window.cpp │ ├── screen.cpp │ ├── shader_editor.cpp │ ├── text_editor.cpp │ ├── translations.cpp │ └── zep.cpp ├── panda_sdl │ ├── frontend_sdl.cpp │ ├── main.cpp │ └── mappings.cpp ├── pandios │ ├── .gitignore │ ├── Alber │ │ ├── Headers │ │ │ └── ios_driver.h │ │ └── module.map │ ├── Pandios.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcuserdata │ │ │ │ └── giorgos.xcuserdatad │ │ │ │ └── UserInterfaceState.xcuserstate │ │ └── xcuserdata │ │ │ └── giorgos.xcuserdatad │ │ │ └── xcschemes │ │ │ └── xcschememanagement.plist │ ├── Pandios │ │ ├── Assets.xcassets │ │ │ ├── AccentColor.colorset │ │ │ │ └── Contents.json │ │ │ ├── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ │ └── Contents.json │ │ ├── ContentView.swift │ │ ├── DocumentPicker.swift │ │ ├── PandiosApp.swift │ │ └── Preview Content │ │ │ └── Preview Assets.xcassets │ │ │ └── Contents.json │ └── build.sh ├── pandroid │ ├── .gitignore │ ├── app │ │ ├── build.gradle.kts │ │ ├── proguard-rules.pro │ │ └── src │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── assets │ │ │ └── fonts │ │ │ │ └── comic_mono.ttf │ │ │ ├── ic_launcher-playstore.png │ │ │ ├── java │ │ │ └── com │ │ │ │ └── panda3ds │ │ │ │ └── pandroid │ │ │ │ ├── AlberDriver.java │ │ │ │ ├── app │ │ │ │ ├── BaseActivity.java │ │ │ │ ├── GameActivity.java │ │ │ │ ├── MainActivity.java │ │ │ │ ├── PandroidApplication.java │ │ │ │ ├── PreferenceActivity.java │ │ │ │ ├── base │ │ │ │ │ ├── BasePreferenceFragment.java │ │ │ │ │ ├── BaseSheetDialog.java │ │ │ │ │ ├── BottomAlertDialog.java │ │ │ │ │ ├── BottomDialogFragment.java │ │ │ │ │ ├── GameAboutDialog.java │ │ │ │ │ └── LoadingAlertDialog.java │ │ │ │ ├── editor │ │ │ │ │ └── CodeEditorActivity.java │ │ │ │ ├── game │ │ │ │ │ ├── AlberInputListener.java │ │ │ │ │ ├── DrawerFragment.java │ │ │ │ │ ├── EmulatorCallback.java │ │ │ │ │ ├── GameLauncher.java │ │ │ │ │ └── LuaDialogFragment.java │ │ │ │ ├── main │ │ │ │ │ ├── GamesFragment.java │ │ │ │ │ ├── SearchFragment.java │ │ │ │ │ └── SettingsFragment.java │ │ │ │ ├── preferences │ │ │ │ │ ├── AdvancedPreferences.java │ │ │ │ │ ├── ControllerMapperPreferences.java │ │ │ │ │ ├── GamesFoldersPreferences.java │ │ │ │ │ ├── GeneralPreferences.java │ │ │ │ │ ├── InputMapActivity.java │ │ │ │ │ ├── InputMapPreferences.java │ │ │ │ │ ├── InputPreferences.java │ │ │ │ │ ├── ThemeSelectorDialog.java │ │ │ │ │ └── screen_editor │ │ │ │ │ │ ├── ScreenEditorPreference.java │ │ │ │ │ │ └── ScreenLayoutsPreference.java │ │ │ │ ├── provider │ │ │ │ │ └── AppDataDocumentProvider.java │ │ │ │ └── services │ │ │ │ │ └── LoggerService.java │ │ │ │ ├── data │ │ │ │ ├── GsonConfigParser.java │ │ │ │ ├── SMDH.java │ │ │ │ ├── config │ │ │ │ │ └── GlobalConfig.java │ │ │ │ └── game │ │ │ │ │ ├── GameMetadata.java │ │ │ │ │ ├── GameRegion.java │ │ │ │ │ └── GamesFolder.java │ │ │ │ ├── input │ │ │ │ ├── InputEvent.java │ │ │ │ ├── InputHandler.java │ │ │ │ ├── InputMap.java │ │ │ │ └── KeyName.java │ │ │ │ ├── lang │ │ │ │ ├── Function.java │ │ │ │ ├── PipeStreamTask.java │ │ │ │ └── Task.java │ │ │ │ ├── math │ │ │ │ ├── Quaternion.java │ │ │ │ ├── Vector2.java │ │ │ │ └── Vector3.java │ │ │ │ ├── utils │ │ │ │ ├── CompatUtils.java │ │ │ │ ├── Constants.java │ │ │ │ ├── FileUtils.java │ │ │ │ ├── GameUtils.java │ │ │ │ ├── PerformanceMonitor.java │ │ │ │ └── SearchAgent.java │ │ │ │ └── view │ │ │ │ ├── PandaGlRenderer.java │ │ │ │ ├── PandaGlSurfaceView.java │ │ │ │ ├── PandaLayoutController.java │ │ │ │ ├── SimpleTextWatcher.java │ │ │ │ ├── code │ │ │ │ ├── BaseEditor.java │ │ │ │ ├── BasicTextEditor.java │ │ │ │ ├── CodeEditor.java │ │ │ │ ├── EditorColors.java │ │ │ │ └── syntax │ │ │ │ │ ├── CodeSyntax.java │ │ │ │ │ ├── LuaSyntax.java │ │ │ │ │ └── PatternUtils.java │ │ │ │ ├── controller │ │ │ │ ├── ControllerLayout.java │ │ │ │ ├── ControllerNode.java │ │ │ │ ├── TouchEvent.java │ │ │ │ ├── TouchType.java │ │ │ │ ├── listeners │ │ │ │ │ ├── ButtonStateListener.java │ │ │ │ │ └── JoystickListener.java │ │ │ │ ├── mapping │ │ │ │ │ ├── ControllerItem.java │ │ │ │ │ ├── ControllerMapper.java │ │ │ │ │ ├── ControllerProfileManager.java │ │ │ │ │ ├── Layout.java │ │ │ │ │ ├── Location.java │ │ │ │ │ └── Profile.java │ │ │ │ └── nodes │ │ │ │ │ ├── BasicControllerNode.java │ │ │ │ │ ├── Button.java │ │ │ │ │ ├── Joystick.java │ │ │ │ │ └── TouchScreenNodeImpl.java │ │ │ │ ├── ds │ │ │ │ ├── Bounds.java │ │ │ │ ├── DsEditorView.java │ │ │ │ ├── DsLayout.java │ │ │ │ ├── DsLayoutManager.java │ │ │ │ ├── Mode.java │ │ │ │ └── Model.java │ │ │ │ ├── gamesgrid │ │ │ │ ├── GameAdapter.java │ │ │ │ ├── GameIconView.java │ │ │ │ ├── GamesGridView.java │ │ │ │ └── ItemHolder.java │ │ │ │ ├── recycler │ │ │ │ ├── AutoFitGridLayout.java │ │ │ │ └── SimpleListAdapter.java │ │ │ │ ├── renderer │ │ │ │ ├── ConsoleRenderer.java │ │ │ │ └── layout │ │ │ │ │ └── ConsoleLayout.java │ │ │ │ └── utils │ │ │ │ └── PerformanceView.java │ │ │ ├── jniLibs │ │ │ ├── .gitignore │ │ │ ├── arm64-v8a │ │ │ │ └── .gitkeep │ │ │ └── x86_64 │ │ │ │ └── .gitkeep │ │ │ └── res │ │ │ ├── color │ │ │ ├── bottom_navigation_indicator_tint.xml │ │ │ ├── red_color.xml │ │ │ ├── text_secondary_dark.xml │ │ │ └── text_secondary_light.xml │ │ │ ├── drawable │ │ │ ├── alert_dialog_background.xml │ │ │ ├── analog_background.xml │ │ │ ├── analog_foreground.xml │ │ │ ├── button_a.xml │ │ │ ├── button_b.xml │ │ │ ├── button_l.xml │ │ │ ├── button_r.xml │ │ │ ├── button_select.xml │ │ │ ├── button_start.xml │ │ │ ├── button_x.xml │ │ │ ├── button_y.xml │ │ │ ├── color_surface.xml │ │ │ ├── dpad_down.xml │ │ │ ├── dpad_left.xml │ │ │ ├── dpad_right.xml │ │ │ ├── dpad_up.xml │ │ │ ├── ds_editor_popup_background.xml │ │ │ ├── ic_add.xml │ │ │ ├── ic_align_center.xml │ │ │ ├── ic_arrow_down.xml │ │ │ ├── ic_arrow_up.xml │ │ │ ├── ic_code.xml │ │ │ ├── ic_compare_arrow.xml │ │ │ ├── ic_delete.xml │ │ │ ├── ic_done.xml │ │ │ ├── ic_edit.xml │ │ │ ├── ic_exit.xml │ │ │ ├── ic_folder.xml │ │ │ ├── ic_key_a.xml │ │ │ ├── ic_keyboard_hide.xml │ │ │ ├── ic_launcher_background.xml │ │ │ ├── ic_launcher_foreground.xml │ │ │ ├── ic_play.xml │ │ │ ├── ic_rotate_screen.xml │ │ │ ├── ic_save.xml │ │ │ ├── ic_search.xml │ │ │ ├── ic_settings.xml │ │ │ ├── ic_shortcut.xml │ │ │ ├── ic_switch_screen.xml │ │ │ ├── ic_tab.xml │ │ │ ├── ic_theme.xml │ │ │ ├── ic_videogame.xml │ │ │ ├── ic_visibility.xml │ │ │ ├── medium_card_background.xml │ │ │ ├── rounded_selectable_item_background.xml │ │ │ ├── screen_gamepad_checkbox.xml │ │ │ ├── screen_gamepad_hide.xml │ │ │ ├── screen_gamepad_show.xml │ │ │ ├── search_bar_background.xml │ │ │ └── simple_card_background.xml │ │ │ ├── layout-land │ │ │ └── activity_main.xml │ │ │ ├── layout │ │ │ ├── activity_code_editor.xml │ │ │ ├── activity_input_map.xml │ │ │ ├── activity_main.xml │ │ │ ├── activity_preference.xml │ │ │ ├── controller_dpad.xml │ │ │ ├── controller_gamepad.xml │ │ │ ├── controller_joystick.xml │ │ │ ├── controller_l.xml │ │ │ ├── controller_r.xml │ │ │ ├── controller_select.xml │ │ │ ├── controller_start.xml │ │ │ ├── dialog_bottom_sheet.xml │ │ │ ├── dialog_game_about.xml │ │ │ ├── dialog_games_folder.xml │ │ │ ├── dialog_loading.xml │ │ │ ├── dialog_lua_scripts.xml │ │ │ ├── dialog_select_theme.xml │ │ │ ├── drawer_game_container.xml │ │ │ ├── ds_editor_gravity_anchor.xml │ │ │ ├── ds_editor_lock_aspect.xml │ │ │ ├── ds_editor_spinner.xml │ │ │ ├── ds_editor_spinner_label.xml │ │ │ ├── fragment_game_drawer.xml │ │ │ ├── fragment_games.xml │ │ │ ├── fragment_search.xml │ │ │ ├── game_activity.xml │ │ │ ├── hold_theme_preview.xml │ │ │ ├── hold_theme_preview_base.xml │ │ │ ├── holder_game.xml │ │ │ ├── holder_lua_script.xml │ │ │ ├── material_switch_widget.xml │ │ │ ├── preference_controller_mapper.xml │ │ │ ├── preference_simple_about.xml │ │ │ └── preference_start_item.xml │ │ │ ├── menu │ │ │ ├── game_drawer.xml │ │ │ └── main_activity_navigation.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.webp │ │ │ ├── ic_launcher_foreground.webp │ │ │ └── ic_launcher_round.webp │ │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.webp │ │ │ ├── ic_launcher_foreground.webp │ │ │ └── ic_launcher_round.webp │ │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.webp │ │ │ ├── ic_launcher_foreground.webp │ │ │ └── ic_launcher_round.webp │ │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.webp │ │ │ ├── ic_launcher_foreground.webp │ │ │ └── ic_launcher_round.webp │ │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.webp │ │ │ ├── ic_launcher_foreground.webp │ │ │ └── ic_launcher_round.webp │ │ │ ├── values-pt-rBR │ │ │ └── strings.xml │ │ │ ├── values-v27 │ │ │ └── themes.xml │ │ │ ├── values-v29 │ │ │ └── themes.xml │ │ │ ├── values │ │ │ ├── colors.xml │ │ │ ├── dimens.xml │ │ │ ├── ic_launcher_background.xml │ │ │ ├── strings.xml │ │ │ ├── styleable.xml │ │ │ ├── themes.xml │ │ │ └── values.xml │ │ │ └── xml │ │ │ ├── advanced_preferences.xml │ │ │ ├── backup_rules.xml │ │ │ ├── data_extraction_rules.xml │ │ │ ├── empty_preferences.xml │ │ │ ├── game_mode_config.xml │ │ │ ├── general_preference.xml │ │ │ ├── input_map_preferences.xml │ │ │ ├── input_preference.xml │ │ │ └── start_preferences.xml │ ├── build.gradle.kts │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ └── settings.gradle.kts ├── renderdoc.cpp ├── renderer.cpp └── stb_image_write.c ├── tests ├── AppCpuTimeLimit │ ├── Makefile │ ├── o3ds.png │ └── source │ │ └── main.c ├── DetectEmulator │ ├── Makefile │ └── source │ │ ├── main.c │ │ └── vshader.v.pica ├── HelloWorldSVC │ ├── Makefile │ └── source │ │ └── main.c ├── ImmediateModeTriangles │ ├── Makefile │ └── source │ │ ├── main.c │ │ └── vshader.v.pica ├── PICA_LITP │ ├── Makefile │ └── source │ │ ├── main.c │ │ └── vshader.v.pica ├── SimplerTri │ ├── Makefile │ └── source │ │ ├── main.c │ │ └── vshader.v.pica └── shader.cpp └── third_party ├── cityhash ├── cityhash.cpp └── include │ └── cityhash.hpp ├── cryptopp └── CMakeLists.txt ├── duckstation ├── duckstation_compat.h ├── duckstation_log.h ├── duckstation_scoped_guard.h ├── gl │ ├── context.cpp │ ├── context.h │ ├── context_agl.h │ ├── context_agl.mm │ ├── context_egl.cpp │ ├── context_egl.h │ ├── context_egl_wayland.cpp │ ├── context_egl_wayland.h │ ├── context_egl_x11.cpp │ ├── context_egl_x11.h │ ├── context_glx.cpp │ ├── context_glx.h │ ├── context_wgl.cpp │ ├── context_wgl.h │ ├── loader.h │ ├── stream_buffer.cpp │ ├── stream_buffer.h │ ├── x11_window.cpp │ └── x11_window.h ├── window_info.cpp ├── window_info.h └── windows_headers.h ├── glad ├── CMakeLists.txt ├── README.md ├── include │ ├── KHR │ │ └── khrplatform.h │ └── glad │ │ ├── eglplatform.h │ │ ├── gl.h │ │ ├── glad_egl.h │ │ ├── glad_glx.h │ │ └── glad_wgl.h └── src │ ├── gl.c │ ├── glad_egl.c │ ├── glad_glx.c │ └── glad_wgl.c ├── imgui ├── .editorconfig ├── .gitattributes ├── .github │ ├── FUNDING.yml │ ├── issue_template.md │ ├── pull_request_template.md │ └── workflows │ │ ├── build.yml │ │ ├── scheduled.yml │ │ └── static-analysis.yml ├── .gitignore ├── LICENSE.txt ├── backends │ ├── imgui_impl_allegro5.cpp │ ├── imgui_impl_allegro5.h │ ├── imgui_impl_android.cpp │ ├── imgui_impl_android.h │ ├── imgui_impl_dx10.cpp │ ├── imgui_impl_dx10.h │ ├── imgui_impl_dx11.cpp │ ├── imgui_impl_dx11.h │ ├── imgui_impl_dx12.cpp │ ├── imgui_impl_dx12.h │ ├── imgui_impl_dx9.cpp │ ├── imgui_impl_dx9.h │ ├── imgui_impl_glfw.cpp │ ├── imgui_impl_glfw.h │ ├── imgui_impl_glut.cpp │ ├── imgui_impl_glut.h │ ├── imgui_impl_marmalade.cpp │ ├── imgui_impl_marmalade.h │ ├── imgui_impl_metal.h │ ├── imgui_impl_metal.mm │ ├── imgui_impl_opengl2.cpp │ ├── imgui_impl_opengl2.h │ ├── imgui_impl_opengl3.cpp │ ├── imgui_impl_opengl3.h │ ├── imgui_impl_osx.h │ ├── imgui_impl_osx.mm │ ├── imgui_impl_sdl.cpp │ ├── imgui_impl_sdl.h │ ├── imgui_impl_vulkan.cpp │ ├── imgui_impl_vulkan.h │ ├── imgui_impl_wgpu.cpp │ ├── imgui_impl_wgpu.h │ ├── imgui_impl_win32.cpp │ ├── imgui_impl_win32.h │ └── vulkan │ │ ├── generate_spv.sh │ │ ├── glsl_shader.frag │ │ └── glsl_shader.vert ├── docs │ ├── BACKENDS.md │ ├── CHANGELOG.txt │ ├── EXAMPLES.md │ ├── FAQ.md │ ├── FONTS.md │ ├── README.md │ └── TODO.txt ├── examples │ ├── README.txt │ ├── example_allegro5 │ │ ├── README.md │ │ ├── example_allegro5.vcxproj │ │ ├── example_allegro5.vcxproj.filters │ │ ├── imconfig_allegro5.h │ │ └── main.cpp │ ├── example_android_opengl3 │ │ ├── CMakeLists.txt │ │ ├── android │ │ │ ├── .gitignore │ │ │ ├── app │ │ │ │ ├── build.gradle │ │ │ │ └── src │ │ │ │ │ └── main │ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ │ └── java │ │ │ │ │ └── MainActivity.kt │ │ │ ├── build.gradle │ │ │ └── settings.gradle │ │ └── main.cpp │ ├── example_apple_metal │ │ ├── README.md │ │ ├── example_apple_metal.xcodeproj │ │ │ └── project.pbxproj │ │ ├── iOS │ │ │ ├── Info-iOS.plist │ │ │ └── LaunchScreen.storyboard │ │ ├── macOS │ │ │ ├── Info-macOS.plist │ │ │ └── MainMenu.storyboard │ │ └── main.mm │ ├── example_apple_opengl2 │ │ ├── example_apple_opengl2.xcodeproj │ │ │ └── project.pbxproj │ │ └── main.mm │ ├── example_emscripten_opengl3 │ │ ├── Makefile │ │ ├── README.md │ │ ├── main.cpp │ │ └── shell_minimal.html │ ├── example_emscripten_wgpu │ │ ├── Makefile │ │ ├── README.md │ │ └── main.cpp │ ├── example_glfw_metal │ │ ├── Makefile │ │ └── main.mm │ ├── example_glfw_opengl2 │ │ ├── Makefile │ │ ├── build_win32.bat │ │ ├── example_glfw_opengl2.vcxproj │ │ ├── example_glfw_opengl2.vcxproj.filters │ │ └── main.cpp │ ├── example_glfw_opengl3 │ │ ├── Makefile │ │ ├── build_win32.bat │ │ ├── example_glfw_opengl3.vcxproj │ │ ├── example_glfw_opengl3.vcxproj.filters │ │ └── main.cpp │ ├── example_glfw_vulkan │ │ ├── CMakeLists.txt │ │ ├── build_win32.bat │ │ ├── build_win64.bat │ │ ├── example_glfw_vulkan.vcxproj │ │ ├── example_glfw_vulkan.vcxproj.filters │ │ └── main.cpp │ ├── example_glut_opengl2 │ │ ├── Makefile │ │ ├── example_glut_opengl2.vcxproj │ │ ├── example_glut_opengl2.vcxproj.filters │ │ └── main.cpp │ ├── example_marmalade │ │ ├── data │ │ │ └── app.icf │ │ ├── main.cpp │ │ └── marmalade_example.mkb │ ├── example_null │ │ ├── Makefile │ │ ├── build_win32.bat │ │ └── main.cpp │ ├── example_sdl_directx11 │ │ ├── build_win32.bat │ │ ├── example_sdl_directx11.vcxproj │ │ ├── example_sdl_directx11.vcxproj.filters │ │ └── main.cpp │ ├── example_sdl_metal │ │ ├── Makefile │ │ └── main.mm │ ├── example_sdl_opengl2 │ │ ├── Makefile │ │ ├── README.md │ │ ├── build_win32.bat │ │ ├── example_sdl_opengl2.vcxproj │ │ ├── example_sdl_opengl2.vcxproj.filters │ │ └── main.cpp │ ├── example_sdl_opengl3 │ │ ├── Makefile │ │ ├── README.md │ │ ├── build_win32.bat │ │ ├── example_sdl_opengl3.vcxproj │ │ ├── example_sdl_opengl3.vcxproj.filters │ │ └── main.cpp │ ├── example_sdl_vulkan │ │ ├── example_sdl_vulkan.vcxproj │ │ ├── example_sdl_vulkan.vcxproj.filters │ │ └── main.cpp │ ├── example_win32_directx10 │ │ ├── build_win32.bat │ │ ├── example_win32_directx10.vcxproj │ │ ├── example_win32_directx10.vcxproj.filters │ │ └── main.cpp │ ├── example_win32_directx11 │ │ ├── build_win32.bat │ │ ├── example_win32_directx11.vcxproj │ │ ├── example_win32_directx11.vcxproj.filters │ │ └── main.cpp │ ├── example_win32_directx12 │ │ ├── build_win32.bat │ │ ├── example_win32_directx12.vcxproj │ │ ├── example_win32_directx12.vcxproj.filters │ │ └── main.cpp │ ├── example_win32_directx9 │ │ ├── build_win32.bat │ │ ├── example_win32_directx9.vcxproj │ │ ├── example_win32_directx9.vcxproj.filters │ │ └── main.cpp │ ├── imgui_examples.sln │ └── libs │ │ ├── gl3w │ │ └── GL │ │ │ ├── gl3w.c │ │ │ ├── gl3w.h │ │ │ └── glcorearb.h │ │ ├── glfw │ │ ├── COPYING.txt │ │ ├── include │ │ │ └── GLFW │ │ │ │ ├── glfw3.h │ │ │ │ └── glfw3native.h │ │ ├── lib-vc2010-32 │ │ │ └── glfw3.lib │ │ └── lib-vc2010-64 │ │ │ └── glfw3.lib │ │ └── usynergy │ │ ├── README.txt │ │ ├── uSynergy.c │ │ └── uSynergy.h ├── imconfig.h ├── imgui.cpp ├── imgui.h ├── imgui_demo.cpp ├── imgui_draw.cpp ├── imgui_internal.h ├── imgui_tables.cpp ├── imgui_widgets.cpp ├── imstb_rectpack.h ├── imstb_textedit.h ├── imstb_truetype.h └── misc │ ├── README.txt │ ├── cpp │ ├── README.txt │ ├── imgui_stdlib.cpp │ └── imgui_stdlib.h │ ├── fonts │ ├── Cousine-Regular.ttf │ ├── DroidSans.ttf │ ├── Karla-Regular.ttf │ ├── ProggyClean.ttf │ ├── ProggyTiny.ttf │ ├── Roboto-Medium.ttf │ └── binary_to_compressed_c.cpp │ ├── freetype │ ├── README.md │ ├── imgui_freetype.cpp │ └── imgui_freetype.h │ ├── natvis │ ├── README.txt │ └── imgui.natvis │ └── single_file │ └── imgui_single_file.h ├── ios_toolchain └── ios.toolchain.cmake ├── libretro └── include │ └── libretro.h ├── opengl └── opengl.hpp ├── renderdoc └── renderdoc_app.h ├── result ├── LICENSE ├── README.md └── include │ └── result.hpp └── xxhash ├── .gitattributes ├── .github ├── dependabot.yml └── workflows │ └── ci.yml ├── .gitignore ├── .tipi ├── deps └── opts ├── .travis.yml ├── CHANGELOG ├── Doxyfile ├── LICENSE ├── Makefile ├── README.md ├── SECURITY.md ├── appveyor.yml ├── cli ├── .tipi │ ├── deps │ └── opts ├── COPYING ├── README.md ├── xsum_arch.h ├── xsum_bench.c ├── xsum_bench.h ├── xsum_config.h ├── xsum_os_specific.c ├── xsum_os_specific.h ├── xsum_output.c ├── xsum_output.h ├── xsum_sanity_check.c ├── xsum_sanity_check.h ├── xxhsum.1 ├── xxhsum.1.md └── xxhsum.c ├── cmake_unofficial ├── .gitignore ├── CMakeLists.txt ├── README.md └── xxHashConfig.cmake.in ├── doc ├── README.md ├── xxhash.cry └── xxhash_spec.md ├── include └── xxhash │ ├── xxh3.h │ ├── xxh_x86dispatch.h │ └── xxhash.h ├── libxxhash.pc.in ├── tests ├── Makefile ├── bench │ ├── .gitignore │ ├── LICENSE │ ├── Makefile │ ├── benchHash.c │ ├── benchHash.h │ ├── benchfn.c │ ├── benchfn.h │ ├── bhDisplay.c │ ├── bhDisplay.h │ ├── hashes.h │ ├── main.c │ ├── timefn.c │ └── timefn.h ├── collisions │ ├── .gitignore │ ├── LICENSE │ ├── Makefile │ ├── README.md │ ├── allcodecs │ │ ├── README.md │ │ ├── dummy.c │ │ └── dummy.h │ ├── hashes.h │ ├── main.c │ ├── pool.c │ ├── pool.h │ ├── sort.cc │ ├── sort.hh │ ├── threading.c │ └── threading.h ├── filename-escape.sh ├── generate_unicode_test.c ├── multiInclude.c ├── ppc_define.c ├── sanity_test.c ├── sanity_test_vectors.h ├── sanity_test_vectors_generator.c └── unicode_lint.sh ├── xxh_x86dispatch.c └── xxhash.c /.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: Google 2 | IndentWidth: 4 3 | ColumnLimit: 150 4 | AccessModifierOffset: -2 5 | TabWidth: 4 6 | NamespaceIndentation: All 7 | UseTab: ForContinuationAndIndentation 8 | AllowShortEnumsOnASingleLine: true 9 | AllowShortCaseLabelsOnASingleLine: true 10 | AllowShortFunctionsOnASingleLine: true 11 | AllowShortIfStatementsOnASingleLine: true 12 | Cpp11BracedListStyle: true 13 | PackConstructorInitializers: BinPack 14 | AlignAfterOpenBracket: BlockIndent 15 | -------------------------------------------------------------------------------- /.github/Alber.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Version=1.0 3 | Type=Application 4 | Name=Alber 5 | GenericName=3DS Emulator 6 | GenericName[fr]=Émulateur 3DS 7 | Comment=Nintendo 3DS video game console emulator 8 | Comment[fr]=Émulateur de console de jeu Nintendo 3DS 9 | Icon=Alber 10 | TryExec=Alber 11 | Exec=Alber %f 12 | Categories=Game;Emulator; 13 | MimeType=application/x-ctr-3dsx;application/x-ctr-cci;application/x-ctr-cia;application/x-ctr-cxi; 14 | Keywords=3DS;Nintendo; 15 | PrefersNonDefaultGPU=true 16 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | patreon: wheremyfoodat 2 | ko_fi: wheremyfoodat -------------------------------------------------------------------------------- /.github/linux-appimage-qt.sh: -------------------------------------------------------------------------------- 1 | # Prepare Tools for building the AppImage 2 | wget https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage 3 | wget https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-x86_64.AppImage 4 | 5 | chmod a+x linuxdeploy-x86_64.AppImage 6 | chmod a+x linuxdeploy-plugin-qt-x86_64.AppImage 7 | 8 | # Build AppImage 9 | QMAKE=/usr/lib/qt6/bin/qmake ./linuxdeploy-x86_64.AppImage --appdir AppDir -d ./.github/Alber.desktop -e ./build/Alber -i ./docs/img/Alber.png --plugin qt --output appimage 10 | -------------------------------------------------------------------------------- /.github/linux-appimage.sh: -------------------------------------------------------------------------------- 1 | # Prepare Tools for building the AppImage 2 | wget https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage 3 | chmod a+x linuxdeploy-x86_64.AppImage 4 | 5 | # Build AppImage 6 | ./linuxdeploy-x86_64.AppImage --appdir AppDir -d ./.github/Alber.desktop -e ./build/Alber -i ./docs/img/Alber.png --output appimage 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Visual Studio files 2 | *.rsuser 3 | *.suo 4 | *.user 5 | *.userosscache 6 | *.sln.docstates 7 | *.userprefs 8 | 9 | #Clion Files 10 | .idea/ 11 | cmake-build-*/ 12 | 13 | Debug/ 14 | Release/ 15 | ReleaseWithClangCL/ 16 | Enabled/ 17 | Disabled/ 18 | build/ 19 | 20 | .vs/ 21 | .vscode/*.log 22 | .cache/ 23 | ipch/ 24 | *.aps 25 | *.ncb 26 | *.opendb 27 | *.opensdf 28 | *.sdf 29 | *.cachefile 30 | *.VC.db 31 | *.VC.VC.opendb 32 | 33 | vsprojects/packages 34 | 35 | .Trash-1000/ 36 | 37 | # Linux files 38 | *.o 39 | *.dep 40 | *.mcd 41 | 42 | # FastBuild and msfastbuild stuff 43 | *.bff 44 | *.fdb 45 | fb.bat 46 | 47 | # macos files 48 | .DS_store 49 | 50 | # IDA database files 51 | *.id0 52 | *.id1 53 | *.nam 54 | *.til 55 | *.idb 56 | 57 | # 3DS files 58 | *.3ds 59 | *.3dsx 60 | *.app 61 | *.cia 62 | *.cci 63 | *.cxi 64 | *.elf 65 | *.smdh 66 | 67 | # Compiled Metal shader files 68 | *.ir 69 | *.metallib 70 | 71 | config.toml 72 | CMakeSettings.json 73 | -------------------------------------------------------------------------------- /cmake/FindRenderDoc.cmake: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project 2 | # SPDX-License-Identifier: GPL-2.0-or-later 3 | 4 | set(RENDERDOC_INCLUDE_DIR third_party/renderdoc) 5 | 6 | if (RENDERDOC_INCLUDE_DIR AND EXISTS "${RENDERDOC_INCLUDE_DIR}/renderdoc_app.h") 7 | file(STRINGS "${RENDERDOC_INCLUDE_DIR}/renderdoc_app.h" RENDERDOC_VERSION_LINE REGEX "typedef struct RENDERDOC_API") 8 | string(REGEX REPLACE ".*typedef struct RENDERDOC_API_([0-9]+)_([0-9]+)_([0-9]+).*" "\\1.\\2.\\3" RENDERDOC_VERSION "${RENDERDOC_VERSION_LINE}") 9 | unset(RENDERDOC_VERSION_LINE) 10 | endif() 11 | 12 | include(FindPackageHandleStandardArgs) 13 | find_package_handle_standard_args(RenderDoc 14 | REQUIRED_VARS RENDERDOC_INCLUDE_DIR 15 | VERSION_VAR RENDERDOC_VERSION 16 | ) 17 | 18 | if (RenderDoc_FOUND AND NOT TARGET RenderDoc::API) 19 | add_library(RenderDoc::API INTERFACE IMPORTED) 20 | set_target_properties(RenderDoc::API PROPERTIES 21 | INTERFACE_INCLUDE_DIRECTORIES "${RENDERDOC_INCLUDE_DIR}" 22 | ) 23 | endif() 24 | 25 | mark_as_advanced(RENDERDOC_INCLUDE_DIR) -------------------------------------------------------------------------------- /docs/3ds/accelerometer_readings/readings_flat_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/docs/3ds/accelerometer_readings/readings_flat_1.png -------------------------------------------------------------------------------- /docs/3ds/accelerometer_readings/readings_flat_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/docs/3ds/accelerometer_readings/readings_flat_2.png -------------------------------------------------------------------------------- /docs/3ds/accelerometer_readings/readings_shaking_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/docs/3ds/accelerometer_readings/readings_shaking_1.png -------------------------------------------------------------------------------- /docs/3ds/accelerometer_readings/readings_shaking_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/docs/3ds/accelerometer_readings/readings_shaking_2.png -------------------------------------------------------------------------------- /docs/img/Alber.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/docs/img/Alber.png -------------------------------------------------------------------------------- /docs/img/KirbyAndroid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/docs/img/KirbyAndroid.png -------------------------------------------------------------------------------- /docs/img/KirbyRobobot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/docs/img/KirbyRobobot.png -------------------------------------------------------------------------------- /docs/img/MK7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/docs/img/MK7.png -------------------------------------------------------------------------------- /docs/img/OoT_Title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/docs/img/OoT_Title.png -------------------------------------------------------------------------------- /docs/img/battery_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/docs/img/battery_icon.png -------------------------------------------------------------------------------- /docs/img/display_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/docs/img/display_icon.png -------------------------------------------------------------------------------- /docs/img/mac_icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/docs/img/mac_icon.ico -------------------------------------------------------------------------------- /docs/img/panda.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/docs/img/panda.jpg -------------------------------------------------------------------------------- /docs/img/pokegang.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/docs/img/pokegang.png -------------------------------------------------------------------------------- /docs/img/rcow_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/docs/img/rcow_icon.png -------------------------------------------------------------------------------- /docs/img/rnap_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/docs/img/rnap_icon.png -------------------------------------------------------------------------------- /docs/img/rpog_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/docs/img/rpog_icon.png -------------------------------------------------------------------------------- /docs/img/rsob_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/docs/img/rsob_icon.png -------------------------------------------------------------------------------- /docs/img/rstarstruck_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/docs/img/rstarstruck_icon.png -------------------------------------------------------------------------------- /docs/img/rsyn_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/docs/img/rsyn_icon.png -------------------------------------------------------------------------------- /docs/img/runpog_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/docs/img/runpog_icon.png -------------------------------------------------------------------------------- /docs/img/sdcard_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/docs/img/sdcard_icon.png -------------------------------------------------------------------------------- /docs/img/settings_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/docs/img/settings_icon.png -------------------------------------------------------------------------------- /docs/img/skyemu_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/docs/img/skyemu_icon.png -------------------------------------------------------------------------------- /docs/img/sparkling_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/docs/img/sparkling_icon.png -------------------------------------------------------------------------------- /docs/img/speaker_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/docs/img/speaker_icon.png -------------------------------------------------------------------------------- /docs/img/windows_alt_icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/docs/img/windows_alt_icon.ico -------------------------------------------------------------------------------- /docs/img/windows_icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/docs/img/windows_icon.ico -------------------------------------------------------------------------------- /docs/img/windows_icon.rc: -------------------------------------------------------------------------------- 1 | AlberIcon ICON "windows_icon.ico" -------------------------------------------------------------------------------- /docs/libretro/panda3ds_libretro.info: -------------------------------------------------------------------------------- 1 | # Software Information 2 | display_name = "Nintendo - 3DS (Panda3DS)" 3 | authors = "Panda3DS Authors (tm)" 4 | supported_extensions = "3ds|3dsx|elf|axf|cci|cxi|app|ncch" 5 | corename = "Panda3DS" 6 | categories = "Emulator" 7 | license = "GPLv3" 8 | permissions = "" 9 | display_version = "Git" 10 | 11 | # Hardware Information 12 | manufacturer = "Nintendo" 13 | systemname = "3DS" 14 | systemid = "3ds" 15 | 16 | # Libretro Information 17 | database = "Nintendo - Nintendo 3DS" 18 | supports_no_game = "false" 19 | savestate = "true" 20 | savestate_features = "basic" 21 | cheats = "false" 22 | input_descriptors = "true" 23 | memory_descriptors = "false" 24 | libretro_saves = "true" 25 | core_options = "true" 26 | core_options_version = "1.0" 27 | load_subsystem = "false" 28 | hw_render = "true" 29 | required_hw_api = "OpenGL Core >= 4.1" 30 | needs_fullpath = "true" 31 | disk_control = "false" 32 | is_experimental = "true" 33 | 34 | description = "Panda3DS !" 35 | -------------------------------------------------------------------------------- /include/PICA/draw_acceleration.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "helpers.hpp" 6 | 7 | namespace PICA { 8 | struct DrawAcceleration { 9 | static constexpr u32 maxAttribCount = 16; 10 | static constexpr u32 maxLoaderCount = 12; 11 | 12 | struct AttributeInfo { 13 | u32 offset; 14 | u32 stride; 15 | 16 | u8 type; 17 | u8 componentCount; 18 | 19 | std::array fixedValue; // For fixed attributes 20 | }; 21 | 22 | struct Loader { 23 | // Data to upload for this loader 24 | u8* data; 25 | usize size; 26 | }; 27 | 28 | u8* indexBuffer; 29 | 30 | // Minimum and maximum index in the index buffer for a draw call 31 | u16 minimumIndex, maximumIndex; 32 | u32 totalAttribCount; 33 | u32 totalLoaderCount; 34 | u32 enabledAttributeMask; 35 | u32 fixedAttributes; 36 | u32 vertexDataSize; 37 | 38 | std::array attributeInfo; 39 | std::array loaders; 40 | 41 | bool canBeAccelerated; 42 | bool indexed; 43 | bool useShortIndices; 44 | }; 45 | } // namespace PICA -------------------------------------------------------------------------------- /include/PICA/dynapica/pica_recs.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "helpers.hpp" 3 | #include "vertex_loader_rec.hpp" 4 | 5 | // Common file for our PICA JITs (From PICA shader -> CPU assembly) 6 | 7 | namespace Dynapica { 8 | #ifdef PANDA3DS_DYNAPICA_SUPPORTED 9 | static constexpr bool supported() { return true; } 10 | #else 11 | static constexpr bool supported() { return false; } 12 | #endif 13 | } -------------------------------------------------------------------------------- /include/PICA/pica_hash.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | // Defines to pick which hash algorithm to use for the PICA (For hashing shaders, etc) 6 | // Please only define one of them 7 | // Available algorithms: 8 | // xxh3: 64-bit non-cryptographic hash using SIMD, default. 9 | // Google CityHash64: 64-bit non-cryptographic hash, generated using regular 64-bit arithmetic 10 | 11 | //#define PANDA3DS_PICA_CITYHASH 12 | #define PANDA3DS_PICA_XXHASH3 13 | 14 | namespace PICAHash { 15 | #if defined(PANDA3DS_PICA_CITYHASH) || defined(PANDA3DS_PICA_XXHASH3) 16 | using HashType = std::uint64_t; 17 | #endif 18 | 19 | HashType computeHash(const char* buf, std::size_t len); 20 | } // namespace PICAHash -------------------------------------------------------------------------------- /include/PICA/shader_gen_types.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace PICA::ShaderGen { 4 | // Graphics API this shader is targetting 5 | enum class API { GL, GLES, Vulkan, Metal }; 6 | 7 | // Shading language to use 8 | enum class Language { GLSL, MSL }; 9 | } // namespace PICA::ShaderGen 10 | -------------------------------------------------------------------------------- /include/PICA/shader_unit.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "PICA/shader.hpp" 3 | 4 | class ShaderUnit { 5 | public: 6 | PICAShader vs; // Vertex shader 7 | PICAShader gs; // Geometry shader 8 | 9 | ShaderUnit() : vs(ShaderType::Vertex), gs(ShaderType::Geometry) {} 10 | void reset(); 11 | }; -------------------------------------------------------------------------------- /include/android_utils.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace AndroidUtils { 4 | int openDocument(const char* directory, const char* mode); 5 | } -------------------------------------------------------------------------------- /include/applets/applet_manager.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "applets/error_applet.hpp" 5 | #include "applets/mii_selector.hpp" 6 | #include "applets/software_keyboard.hpp" 7 | #include "helpers.hpp" 8 | #include "memory.hpp" 9 | #include "result/result.hpp" 10 | 11 | namespace Applets { 12 | class AppletManager { 13 | MiiSelectorApplet miiSelector; 14 | SoftwareKeyboardApplet swkbd; 15 | ErrorApplet error; 16 | std::optional nextParameter = std::nullopt; 17 | 18 | public: 19 | AppletManager(Memory& mem); 20 | void reset(); 21 | AppletBase* getApplet(u32 id); 22 | 23 | Applets::Parameter glanceParameter(); 24 | Applets::Parameter receiveParameter(); 25 | }; 26 | } // namespace Applets -------------------------------------------------------------------------------- /include/applets/error_applet.hpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "applets/applet.hpp" 4 | 5 | namespace Applets { 6 | class ErrorApplet final : public AppletBase { 7 | public: 8 | virtual const char* name() override { return "Error/EULA Agreement"; } 9 | virtual Result::HorizonResult start(const MemoryBlock* sharedMem, const std::vector& parameters, u32 appID) override; 10 | virtual Result::HorizonResult receiveParameter(const Applets::Parameter& parameter) override; 11 | virtual void reset() override; 12 | 13 | ErrorApplet(Memory& memory, std::optional& nextParam) : AppletBase(memory, nextParam) {} 14 | }; 15 | } // namespace Applets -------------------------------------------------------------------------------- /include/audio/aac_decoder.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "audio/aac.hpp" 5 | #include "helpers.hpp" 6 | 7 | struct AAC_DECODER_INSTANCE; 8 | 9 | namespace Audio::AAC { 10 | class Decoder { 11 | using DecoderHandle = AAC_DECODER_INSTANCE*; 12 | using PaddrCallback = std::function; 13 | 14 | DecoderHandle decoderHandle = nullptr; 15 | 16 | bool isInitialized() { return decoderHandle != nullptr; } 17 | void initialize(); 18 | 19 | public: 20 | // Decode function. Takes in a reference to the AAC response & request, and a callback for paddr -> pointer conversions 21 | // We also allow for optionally muting the AAC output (setting all of it to 0) instead of properly decoding it, for debug/research purposes 22 | void decode(AAC::Message& response, const AAC::Message& request, PaddrCallback paddrCallback, bool enableAudio = true); 23 | ~Decoder(); 24 | }; 25 | } // namespace Audio::AAC -------------------------------------------------------------------------------- /include/audio/audio_device.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #if defined(__LIBRETRO__) && defined(USE_LIBRETRO_AUDIO_DEVICE) 4 | #include "audio/libretro_audio_device.hpp" 5 | using AudioDevice = LibretroAudioDevice; 6 | #else 7 | #include "audio/miniaudio_device.hpp" 8 | using AudioDevice = MiniAudioDevice; 9 | #endif -------------------------------------------------------------------------------- /include/audio/miniaudio_device.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | #include "audio/audio_device_interface.hpp" 7 | #include "miniaudio.h" 8 | 9 | class MiniAudioDevice final : public AudioDeviceInterface { 10 | static constexpr ma_uint32 sampleRate = 32768; // 3DS sample rate 11 | static constexpr ma_uint32 channelCount = 2; // Audio output is stereo 12 | 13 | bool initialized = false; 14 | 15 | ma_device device; 16 | ma_context context; 17 | ma_device_config deviceConfig; 18 | 19 | // Store the last stereo sample we output. We play this when underruning to avoid pops. 20 | std::vector audioDevices; 21 | 22 | public: 23 | MiniAudioDevice(const AudioDeviceConfig& audioSettings); 24 | 25 | // If safe is on, we create a null audio device 26 | void init(Samples& samples, bool safe = false) override; 27 | void close() override; 28 | 29 | void start() override; 30 | void stop() override; 31 | 32 | bool isInitialized() const { return initialized; } 33 | }; -------------------------------------------------------------------------------- /include/colour.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "helpers.hpp" 3 | 4 | // Helpers functions for converting colour channels between bit depths 5 | namespace Colour { 6 | inline static constexpr u8 convert4To8Bit(u8 c) { 7 | return (c << 4) | c; 8 | } 9 | 10 | inline static constexpr u8 convert5To8Bit(u8 c) { 11 | return (c << 3) | (c >> 2); 12 | } 13 | 14 | inline static constexpr u8 convert6To8Bit(u8 c) { 15 | return (c << 2) | (c >> 4); 16 | } 17 | } -------------------------------------------------------------------------------- /include/compiler_builtins.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef _MSC_VER 4 | #define ALWAYS_INLINE __forceinline 5 | #else 6 | #define ALWAYS_INLINE __attribute__((always_inline)) 7 | #endif -------------------------------------------------------------------------------- /include/cpu.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef CPU_DYNARMIC 4 | #include "cpu_dynarmic.hpp" 5 | #elif defined(CPU_KVM) 6 | #error KVM CPU is not implemented yet 7 | #else 8 | #error No CPU core implemented :( 9 | #endif -------------------------------------------------------------------------------- /include/discord_rpc.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef PANDA3DS_ENABLE_DISCORD_RPC 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | namespace Discord { 10 | enum class RPCStatus { Idling, Playing }; 11 | 12 | class RPC { 13 | std::uint64_t startTimestamp; 14 | bool enabled = false; 15 | 16 | public: 17 | void init(); 18 | void update(RPCStatus status, const std::string& title); 19 | void stop(); 20 | 21 | bool running() const { return enabled; } 22 | }; 23 | } // namespace Discord 24 | 25 | #endif -------------------------------------------------------------------------------- /include/frontend_settings.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | // Some UI settings that aren't fully frontend-dependent. Note: Not all frontends will support the same settings. 5 | // Note: Any enums should ideally be ordered in the same order we want to show them in UI dropdown menus, so that we can cast indices to enums 6 | // directly. 7 | struct FrontendSettings { 8 | enum class Theme : int { 9 | System = 0, 10 | Light = 1, 11 | Dark = 2, 12 | GreetingsCat = 3, 13 | Cream = 4, 14 | Oled = 5, 15 | }; 16 | 17 | // Different panda-themed window icons 18 | enum class WindowIcon : int { 19 | Rpog = 0, 20 | Rsyn = 1, 21 | Rnap = 2, 22 | Rcow = 3, 23 | SkyEmu = 4, 24 | Runpog = 5, 25 | }; 26 | 27 | Theme theme = Theme::Dark; 28 | WindowIcon icon = WindowIcon::Rpog; 29 | std::string language = "en"; 30 | 31 | static Theme themeFromString(std::string inString); 32 | static const char* themeToString(Theme theme); 33 | 34 | static WindowIcon iconFromString(std::string inString); 35 | static const char* iconToString(WindowIcon icon); 36 | }; 37 | -------------------------------------------------------------------------------- /include/fs/archive_card_spi.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "archive_base.hpp" 3 | #include "result/result.hpp" 4 | 5 | using Result::HorizonResult; 6 | 7 | class CardSPIArchive : public ArchiveBase { 8 | public: 9 | CardSPIArchive(Memory& mem) : ArchiveBase(mem) {} 10 | std::string name() override { return "Card SPI"; } 11 | 12 | u64 getFreeBytes() override { 13 | Helpers::warn("Unimplemented GetFreeBytes for Card SPI archive"); 14 | return 0_MB; 15 | } 16 | 17 | HorizonResult createDirectory(const FSPath& path) override; 18 | HorizonResult createFile(const FSPath& path, u64 size) override; 19 | HorizonResult deleteFile(const FSPath& path) override; 20 | 21 | Rust::Result openArchive(const FSPath& path) override; 22 | Rust::Result openDirectory(const FSPath& path) override; 23 | 24 | FileDescriptor openFile(const FSPath& path, const FilePerms& perms) override; 25 | 26 | std::optional readFile(FileSession* file, u64 offset, u32 size, u32 dataPointer) override { 27 | Helpers::panic("Unimplemented ReadFile for Card SPI archive"); 28 | return {}; 29 | }; 30 | }; -------------------------------------------------------------------------------- /include/fs/archive_ncch.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "archive_base.hpp" 3 | 4 | class NCCHArchive : public ArchiveBase { 5 | public: 6 | NCCHArchive(Memory& mem) : ArchiveBase(mem) {} 7 | 8 | u64 getFreeBytes() override { Helpers::panic("NCCH::GetFreeBytes unimplemented"); return 0; } 9 | std::string name() override { return "NCCH"; } 10 | 11 | HorizonResult createFile(const FSPath& path, u64 size) override; 12 | HorizonResult deleteFile(const FSPath& path) override; 13 | 14 | Rust::Result openArchive(const FSPath& path) override; 15 | FileDescriptor openFile(const FSPath& path, const FilePerms& perms) override; 16 | std::optional readFile(FileSession* file, u64 offset, u32 size, u32 dataPointer) override; 17 | 18 | // Returns whether the cart has a RomFS 19 | bool hasRomFS() { 20 | auto cxi = mem.getCXI(); 21 | return (cxi != nullptr && cxi->hasRomFS()); 22 | } 23 | 24 | // Returns whether the cart has an ExeFS (All executable carts should have an ExeFS. This is just here to be safe) 25 | bool hasExeFS() { 26 | auto cxi = mem.getCXI(); 27 | return (cxi != nullptr && cxi->hasExeFS()); 28 | } 29 | }; -------------------------------------------------------------------------------- /include/fs/archive_sdmc.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "archive_base.hpp" 3 | #include "result/result.hpp" 4 | 5 | using Result::HorizonResult; 6 | 7 | class SDMCArchive : public ArchiveBase { 8 | bool isWriteOnly = false; // There's 2 variants of the SDMC archive: Regular one (Read/Write) and write-only 9 | 10 | public: 11 | SDMCArchive(Memory& mem, bool writeOnly = false) : ArchiveBase(mem), isWriteOnly(writeOnly) {} 12 | 13 | u64 getFreeBytes() override { return 1_GB; } 14 | std::string name() override { return "SDMC"; } 15 | 16 | HorizonResult createFile(const FSPath& path, u64 size) override; 17 | HorizonResult deleteFile(const FSPath& path) override; 18 | HorizonResult createDirectory(const FSPath& path) override; 19 | 20 | Rust::Result openArchive(const FSPath& path) override; 21 | Rust::Result openDirectory(const FSPath& path) override; 22 | 23 | FileDescriptor openFile(const FSPath& path, const FilePerms& perms) override; 24 | std::optional readFile(FileSession* file, u64 offset, u32 size, u32 dataPointer) override; 25 | }; -------------------------------------------------------------------------------- /include/fs/archive_self_ncch.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "archive_base.hpp" 3 | 4 | class SelfNCCHArchive : public ArchiveBase { 5 | public: 6 | SelfNCCHArchive(Memory& mem) : ArchiveBase(mem) {} 7 | 8 | u64 getFreeBytes() override { return 0; } 9 | std::string name() override { return "SelfNCCH"; } 10 | 11 | HorizonResult createFile(const FSPath& path, u64 size) override; 12 | HorizonResult deleteFile(const FSPath& path) override; 13 | 14 | Rust::Result openArchive(const FSPath& path) override; 15 | FileDescriptor openFile(const FSPath& path, const FilePerms& perms) override; 16 | std::optional readFile(FileSession* file, u64 offset, u32 size, u32 dataPointer) override; 17 | 18 | // Returns whether the cart has a RomFS 19 | bool hasRomFS() { 20 | auto cxi = mem.getCXI(); 21 | auto hb3dsx = mem.get3DSX(); 22 | return (cxi != nullptr && cxi->hasRomFS()) || (hb3dsx != nullptr && hb3dsx->hasRomFs()); 23 | } 24 | 25 | // Returns whether the cart has an ExeFS (All executable carts should have an ExeFS. This is just here to be safe) 26 | bool hasExeFS() { 27 | auto cxi = mem.getCXI(); 28 | return (cxi != nullptr && cxi->hasExeFS()); 29 | } 30 | }; -------------------------------------------------------------------------------- /include/fs/archive_system_save_data.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "archive_base.hpp" 3 | 4 | class SystemSaveDataArchive : public ArchiveBase { 5 | public: 6 | SystemSaveDataArchive(Memory& mem) : ArchiveBase(mem) {} 7 | 8 | u64 getFreeBytes() override { 9 | Helpers::warn("Unimplemented GetFreeBytes for SystemSaveData archive"); 10 | return 32_MB; 11 | } 12 | 13 | std::string name() override { return "SystemSaveData"; } 14 | 15 | HorizonResult createDirectory(const FSPath& path) override; 16 | HorizonResult createFile(const FSPath& path, u64 size) override; 17 | HorizonResult deleteFile(const FSPath& path) override; 18 | 19 | Rust::Result openArchive(const FSPath& path) override; 20 | Rust::Result openDirectory(const FSPath& path) override; 21 | 22 | FileDescriptor openFile(const FSPath& path, const FilePerms& perms) override; 23 | 24 | std::optional readFile(FileSession* file, u64 offset, u32 size, u32 dataPointer) override { 25 | Helpers::panic("Unimplemented ReadFile for SystemSaveData archive"); 26 | return {}; 27 | }; 28 | }; -------------------------------------------------------------------------------- /include/fs/archive_twl_photo.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "archive_base.hpp" 3 | #include "result/result.hpp" 4 | 5 | using Result::HorizonResult; 6 | 7 | class TWLPhotoArchive : public ArchiveBase { 8 | public: 9 | TWLPhotoArchive(Memory& mem) : ArchiveBase(mem) {} 10 | std::string name() override { return "TWL_PHOTO"; } 11 | 12 | u64 getFreeBytes() override { 13 | Helpers::warn("Unimplemented GetFreeBytes for TWLPhoto archive"); 14 | return 32_MB; 15 | } 16 | 17 | HorizonResult createDirectory(const FSPath& path) override; 18 | HorizonResult createFile(const FSPath& path, u64 size) override; 19 | HorizonResult deleteFile(const FSPath& path) override; 20 | 21 | Rust::Result openArchive(const FSPath& path) override; 22 | Rust::Result openDirectory(const FSPath& path) override; 23 | 24 | FileDescriptor openFile(const FSPath& path, const FilePerms& perms) override; 25 | 26 | std::optional readFile(FileSession* file, u64 offset, u32 size, u32 dataPointer) override { 27 | Helpers::panic("Unimplemented ReadFile for TWL_PHOTO archive"); 28 | return {}; 29 | }; 30 | }; -------------------------------------------------------------------------------- /include/fs/archive_twl_sound.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "archive_base.hpp" 3 | #include "result/result.hpp" 4 | 5 | using Result::HorizonResult; 6 | 7 | class TWLSoundArchive : public ArchiveBase { 8 | public: 9 | TWLSoundArchive(Memory& mem) : ArchiveBase(mem) {} 10 | std::string name() override { return "TWL_SOUND"; } 11 | 12 | u64 getFreeBytes() override { 13 | Helpers::warn("Unimplemented GetFreeBytes for TWLSound archive"); 14 | return 32_MB; 15 | } 16 | 17 | HorizonResult createDirectory(const FSPath& path) override; 18 | HorizonResult createFile(const FSPath& path, u64 size) override; 19 | HorizonResult deleteFile(const FSPath& path) override; 20 | 21 | Rust::Result openArchive(const FSPath& path) override; 22 | Rust::Result openDirectory(const FSPath& path) override; 23 | 24 | FileDescriptor openFile(const FSPath& path, const FilePerms& perms) override; 25 | 26 | std::optional readFile(FileSession* file, u64 offset, u32 size, u32 dataPointer) override { 27 | Helpers::panic("Unimplemented ReadFile for TWL_SOUND archive"); 28 | return {}; 29 | }; 30 | }; -------------------------------------------------------------------------------- /include/fs/ivfc.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "helpers.hpp" 6 | 7 | namespace IVFC { 8 | struct IVFCLevel { 9 | u64 logicalOffset; 10 | u64 size; 11 | u64 blockSize; 12 | }; 13 | 14 | struct IVFC { 15 | u64 masterHashSize; 16 | std::vector levels; 17 | }; 18 | 19 | size_t parseIVFC(uintptr_t ivfcStart, IVFC& ivfc); 20 | } // namespace IVFC -------------------------------------------------------------------------------- /include/fs/romfs.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | #include "helpers.hpp" 7 | 8 | namespace RomFS { 9 | struct RomFSNode { 10 | std::u16string name; 11 | // The file/directory offset relative to the start of the RomFS 12 | u64 metadataOffset = 0; 13 | u64 dataOffset = 0; 14 | u64 dataSize = 0; 15 | bool isDirectory = false; 16 | 17 | std::vector> directories; 18 | std::vector> files; 19 | }; 20 | 21 | // Result codes when dumping RomFS. These are used by the frontend to print appropriate error messages if RomFS dumping fails 22 | enum class DumpingResult { 23 | Success = 0, 24 | InvalidFormat = 1, // ROM is a format that doesn't support RomFS, such as ELF 25 | NoRomFS = 2 26 | }; 27 | 28 | std::unique_ptr parseRomFSTree(uintptr_t romFS, u64 romFSSize); 29 | } // namespace RomFS -------------------------------------------------------------------------------- /include/input_mappings.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "helpers.hpp" 6 | #include "services/hid.hpp" 7 | 8 | struct InputMappings { 9 | using Scancode = u32; 10 | using Container = std::unordered_map; 11 | 12 | u32 getMapping(Scancode scancode) const { 13 | auto it = container.find(scancode); 14 | return it != container.end() ? it->second : HID::Keys::Null; 15 | } 16 | 17 | void setMapping(Scancode scancode, u32 key) { container[scancode] = key; } 18 | static InputMappings defaultKeyboardMappings(); 19 | 20 | private: 21 | Container container; 22 | }; 23 | -------------------------------------------------------------------------------- /include/ios_driver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | void iosCreateEmulator(); 6 | void iosLoadROM(NSString* pathNS); 7 | void iosRunFrame(CAMetalLayer* layer); -------------------------------------------------------------------------------- /include/ipc.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace IPC { 5 | namespace BufferType { 6 | enum : std::uint32_t { 7 | Send = 1, 8 | Receive = 2, 9 | }; 10 | } 11 | 12 | constexpr std::uint32_t responseHeader(std::uint32_t commandID, std::uint32_t normalResponses, std::uint32_t translateResponses) { 13 | // TODO: Maybe validate the response count stuff fits in 6 bits 14 | return (commandID << 16) | (normalResponses << 6) | translateResponses; 15 | } 16 | 17 | constexpr std::uint32_t pointerHeader(std::uint32_t index, std::uint32_t size, std::uint32_t type) { 18 | return (size << 14) | (index << 10) | (type << 1); 19 | } 20 | } // namespace IPC -------------------------------------------------------------------------------- /include/kernel/config_mem.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "helpers.hpp" 3 | 4 | // Configuration memory addresses 5 | namespace ConfigMem { 6 | enum : u32 { 7 | KernelVersionMinor = 0x1FF80002, 8 | KernelVersionMajor = 0x1FF80003, 9 | SyscoreVer = 0x1FF80010, 10 | EnvInfo = 0x1FF80014, 11 | PrevFirm = 0x1FF80016, 12 | AppMemAlloc = 0x1FF80040, 13 | FirmUnknown = 0x1FF80060, 14 | FirmRevision = 0x1FF80061, 15 | FirmVersionMinor = 0x1FF80062, 16 | FirmVersionMajor = 0x1FF80063, 17 | FirmSyscoreVer = 0x1FF80064, 18 | FirmSdkVer = 0x1FF80068, 19 | 20 | HardwareType = 0x1FF81004, 21 | Datetime0 = 0x1FF81020, 22 | WifiMac = 0x1FF81060, 23 | WifiLevel = 0x1FF81066, 24 | NetworkState = 0x1FF81067, 25 | SliderState3D = 0x1FF81080, 26 | LedState3D = 0x1FF81084, 27 | BatteryState = 0x1FF81085, 28 | Unknown1086 = 0x1FF81086, 29 | HeadphonesConnectedMaybe = 0x1FF810C0 // TODO: What is actually stored here? 30 | }; 31 | 32 | // Shows what type of hardware we're running on 33 | namespace HardwareCodes { 34 | enum : u8 { 35 | Product = 1, 36 | Devboard = 2, 37 | Debugger = 3, 38 | Capture = 4, 39 | }; 40 | } 41 | } // namespace ConfigMem 42 | -------------------------------------------------------------------------------- /include/loader/lz77.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "helpers.hpp" 4 | 5 | // For parsing the LZ77 format used for compressing the .code file in the ExeFS 6 | namespace CartLZ77 { 7 | // Retrieves the uncompressed size of the compressed LZ77 data stored in buffer with a specific compressed size 8 | u32 decompressedSize(const u8* buffer, u32 compressedSize); 9 | 10 | template 11 | static u32 decompressedSize(const std::vector& buffer) { 12 | return decompressedSize((u8*)buffer.data(), u32(buffer.size() * sizeof(T))); 13 | } 14 | 15 | // Decompresses an LZ77-compressed buffer stored in input to output 16 | bool decompress(std::vector& output, const std::vector& input); 17 | } // End namespace CartLZ77 18 | -------------------------------------------------------------------------------- /include/loader/ncsd.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "helpers.hpp" 4 | #include "io_file.hpp" 5 | #include "loader/ncch.hpp" 6 | 7 | struct NCSD { 8 | static constexpr u64 mediaUnit = 0x200; 9 | 10 | struct Partition { 11 | u64 offset = 0; // Offset of partition converted to bytes 12 | u64 length = 0; // Length of partition converted to bytes 13 | NCCH ncch; 14 | }; 15 | 16 | IOFile file; 17 | u64 size = 0; // Image size according to the header converted to bytes 18 | std::array partitions; // NCCH partitions 19 | 20 | u32 entrypoint; // Initial ARM11 PC 21 | }; 22 | -------------------------------------------------------------------------------- /include/metaprogramming.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | namespace Helpers { 6 | /// Used to make the compiler evaluate beeg loops at compile time for things like generating compile-time tables 7 | template 8 | static constexpr void static_for_impl(Func&& f, std::integer_sequence) { 9 | (f(std::integral_constant{}), ...); 10 | } 11 | 12 | template 13 | static constexpr void static_for(Func&& f) { 14 | static_for_impl(std::forward(f), std::make_integer_sequence{}); 15 | } 16 | } -------------------------------------------------------------------------------- /include/panda_qt/about_window.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | class AboutWindow : public QDialog { 8 | Q_OBJECT 9 | 10 | public: 11 | AboutWindow(QWidget* parent = nullptr); 12 | }; -------------------------------------------------------------------------------- /include/panda_qt/elided_label.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | class ElidedLabel : public QLabel { 8 | Q_OBJECT 9 | public: 10 | explicit ElidedLabel(Qt::TextElideMode elideMode = Qt::ElideLeft, QWidget* parent = nullptr); 11 | explicit ElidedLabel(QString text, Qt::TextElideMode elideMode = Qt::ElideLeft, QWidget* parent = nullptr); 12 | void setText(QString text); 13 | 14 | protected: 15 | void resizeEvent(QResizeEvent* event); 16 | 17 | private: 18 | void updateText(); 19 | QString m_text; 20 | Qt::TextElideMode m_elideMode; 21 | }; -------------------------------------------------------------------------------- /include/panda_qt/patch_window.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "panda_qt/elided_label.hpp" 8 | 9 | class PatchWindow final : public QWidget { 10 | Q_OBJECT 11 | 12 | public: 13 | PatchWindow(QWidget* parent = nullptr); 14 | ~PatchWindow() = default; 15 | 16 | private: 17 | // Show a message box 18 | // Title: Title of the message box to display 19 | // Message: Message to display 20 | // Icon: The type of icon (error, warning, information, etc) to display 21 | // IconPath: If non-null, then a path to an icon in our assets to display on the OK button 22 | void displayMessage( 23 | const QString& title, const QString& message, QMessageBox::Icon icon = QMessageBox::Icon::Warning, const char* iconPath = nullptr 24 | ); 25 | 26 | std::filesystem::path inputPath = ""; 27 | std::filesystem::path patchPath = ""; 28 | 29 | ElidedLabel* inputPathLabel = nullptr; 30 | ElidedLabel* patchPathLabel = nullptr; 31 | }; 32 | -------------------------------------------------------------------------------- /include/panda_qt/shader_editor.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "zep.h" 9 | #include "zep/mode_repl.h" 10 | #include "zep/regress.h" 11 | 12 | class ShaderEditorWindow : public QDialog { 13 | Q_OBJECT 14 | 15 | private: 16 | Zep::ZepWidget_Qt zepWidget; 17 | Zep::IZepReplProvider replProvider; 18 | static constexpr float fontSize = 14.0f; 19 | 20 | public: 21 | // Whether this backend supports shader editor 22 | bool supported = true; 23 | 24 | ShaderEditorWindow(QWidget* parent, const std::string& filename, const std::string& initialText); 25 | void setText(const std::string& text) { zepWidget.GetEditor().GetMRUBuffer()->SetText(text); } 26 | void setEnable(bool enable); 27 | }; -------------------------------------------------------------------------------- /include/panda_qt/text_editor.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "zep.h" 9 | #include "zep/mode_repl.h" 10 | #include "zep/regress.h" 11 | 12 | class TextEditorWindow : public QDialog { 13 | Q_OBJECT 14 | 15 | private: 16 | Zep::ZepWidget_Qt zepWidget; 17 | Zep::IZepReplProvider replProvider; 18 | static constexpr float fontSize = 14.0f; 19 | 20 | public: 21 | TextEditorWindow(QWidget* parent, const std::string& filename, const std::string& initialText); 22 | void setText(const std::string& text) { zepWidget.GetEditor().GetMRUBuffer()->SetText(text); } 23 | }; -------------------------------------------------------------------------------- /include/renderer_gl/gl_driver.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Information about our OpenGL/OpenGL ES driver that we should keep track of 4 | // Stuff like whether specific extensions are supported, and potentially things like OpenGL context information 5 | namespace OpenGL { 6 | struct Driver { 7 | bool usingGLES = false; 8 | bool supportsExtFbFetch = false; 9 | bool supportsArmFbFetch = false; 10 | 11 | bool supportFbFetch() const { return supportsExtFbFetch || supportsArmFbFetch; } 12 | }; 13 | } // namespace OpenGL -------------------------------------------------------------------------------- /include/renderer_mtl/mtl_common.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #define GET_HELPER_TEXTURE_BINDING(binding) (30 - binding) 6 | #define GET_HELPER_SAMPLER_STATE_BINDING(binding) (15 - binding) 7 | -------------------------------------------------------------------------------- /include/renderer_mtl/mtl_lut_texture.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace Metal { 6 | 7 | class LutTexture { 8 | public: 9 | LutTexture(MTL::Device* device, MTL::TextureType type, MTL::PixelFormat pixelFormat, u32 width, u32 height, const char* name); 10 | ~LutTexture(); 11 | u32 getNextIndex(); 12 | 13 | MTL::Texture* getTexture() { return texture; } 14 | u32 getCurrentIndex() { return currentIndex; } 15 | private: 16 | MTL::Texture* texture; 17 | u32 currentIndex = 0; 18 | }; 19 | 20 | } // namespace Metal 21 | -------------------------------------------------------------------------------- /include/renderer_mtl/objc_helper.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "mtl_common.hpp" 6 | 7 | namespace Metal { 8 | dispatch_data_t createDispatchData(const void* data, size_t size); 9 | } // namespace Metal 10 | 11 | // Cast from std::string to NS::String* 12 | inline NS::String* toNSString(const std::string& str) { return NS::String::string(str.c_str(), NS::ASCIIStringEncoding); } -------------------------------------------------------------------------------- /include/renderer_sw/renderer_sw.hpp: -------------------------------------------------------------------------------- 1 | #include "renderer.hpp" 2 | 3 | class GPU; 4 | 5 | class RendererSw final : public Renderer { 6 | public: 7 | RendererSw(GPU& gpu, const std::array& internalRegs, const std::array& externalRegs); 8 | ~RendererSw() override; 9 | 10 | void reset() override; 11 | void display() override; 12 | void initGraphicsContext(SDL_Window* window) override; 13 | void clearBuffer(u32 startAddress, u32 endAddress, u32 value, u32 control) override; 14 | void displayTransfer(u32 inputAddr, u32 outputAddr, u32 inputSize, u32 outputSize, u32 flags) override; 15 | void textureCopy(u32 inputAddr, u32 outputAddr, u32 totalBytes, u32 inputSize, u32 outputSize, u32 flags) override; 16 | void drawVertices(PICA::PrimType primType, std::span vertices) override; 17 | void screenshot(const std::string& name) override; 18 | void deinitGraphicsContext() override; 19 | 20 | #ifdef PANDA3DS_FRONTEND_QT 21 | virtual void initGraphicsContext([[maybe_unused]] GL::Context* context) override {} 22 | #endif 23 | }; 24 | -------------------------------------------------------------------------------- /include/renderer_vk/vk_api.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define VK_NO_PROTOTYPES 4 | #include 5 | 6 | #define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1 7 | #define VULKAN_HPP_NO_EXCEPTIONS 8 | // Disable asserts on result-codes 9 | #define VULKAN_HPP_ASSERT_ON_RESULT 10 | #include 11 | #include 12 | #include -------------------------------------------------------------------------------- /include/renderer_vk/vk_pica.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "PICA/gpu.hpp" 4 | #include "helpers.hpp" 5 | #include "vk_api.hpp" 6 | 7 | namespace Vulkan { 8 | 9 | vk::Format colorFormatToVulkan(PICA::ColorFmt colorFormat); 10 | vk::Format depthFormatToVulkan(PICA::DepthFmt depthFormat); 11 | 12 | } // namespace Vulkan -------------------------------------------------------------------------------- /include/renderer_vk/vk_sampler_cache.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "helpers.hpp" 7 | #include "vk_api.hpp" 8 | 9 | namespace Vulkan { 10 | // Implements a simple pool of reusable sampler objects 11 | class SamplerCache { 12 | private: 13 | const vk::Device device; 14 | 15 | std::unordered_map samplerMap; 16 | 17 | explicit SamplerCache(vk::Device device); 18 | 19 | public: 20 | ~SamplerCache() = default; 21 | 22 | SamplerCache(SamplerCache&&) = default; 23 | 24 | const vk::Sampler& getSampler(const vk::SamplerCreateInfo& samplerInfo); 25 | 26 | static std::optional create(vk::Device device); 27 | }; 28 | } // namespace Vulkan -------------------------------------------------------------------------------- /include/result/result.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "result_cfg.hpp" 4 | #include "result_common.hpp" 5 | #include "result_kernel.hpp" 6 | #include "result_os.hpp" 7 | #include "result_fnd.hpp" 8 | #include "result_fs.hpp" 9 | #include "result_gsp.hpp" -------------------------------------------------------------------------------- /include/result/result_cfg.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "result_common.hpp" 3 | 4 | DEFINE_HORIZON_RESULT_MODULE(Result::CFG, Config); 5 | 6 | namespace Result::CFG { 7 | DEFINE_HORIZON_RESULT(NotFound, 1018, WrongArgument, Permanent); 8 | }; 9 | -------------------------------------------------------------------------------- /include/result/result_fnd.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "result_common.hpp" 3 | 4 | DEFINE_HORIZON_RESULT_MODULE(Result::FND, FND); 5 | 6 | namespace Result::FND { 7 | DEFINE_HORIZON_RESULT(InvalidEnumValue, 1005, InvalidArgument, Permanent); 8 | }; 9 | -------------------------------------------------------------------------------- /include/result/result_fs.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "result_common.hpp" 3 | 4 | DEFINE_HORIZON_RESULT_MODULE(Result::FS, FS); 5 | 6 | namespace Result::FS { 7 | // TODO: Verify this 8 | DEFINE_HORIZON_RESULT(FileNotFound, 100, NotFound, Status); 9 | // TODO: Verify this 10 | DEFINE_HORIZON_RESULT(FileNotFoundAlt, 112, NotFound, Status); 11 | // Also a not found error code used here and there in the FS module. 12 | DEFINE_HORIZON_RESULT(NotFoundInvalid, 120, InvalidState, Status); 13 | DEFINE_HORIZON_RESULT(AlreadyExists, 190, NothingHappened, Info); 14 | DEFINE_HORIZON_RESULT(FileTooLarge, 210, OutOfResource, Info); 15 | // Trying to access an archive that needs formatting and has not been formatted 16 | DEFINE_HORIZON_RESULT(NotFormatted, 340, InvalidState, Status); 17 | DEFINE_HORIZON_RESULT(UnexpectedFileOrDir, 770, NotSupported, Usage); 18 | 19 | // Trying to rename a file that doesn't exist or is a directory 20 | DEFINE_HORIZON_RESULT(RenameNonexistentFileOrDir, 120, NotFound, Status); 21 | 22 | // Trying to rename a file but the destination already exists 23 | DEFINE_HORIZON_RESULT(RenameFileDestExists, 190, NothingHappened, Status); 24 | }; // namespace Result::FS 25 | -------------------------------------------------------------------------------- /include/result/result_gsp.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "result_common.hpp" 3 | 4 | DEFINE_HORIZON_RESULT_MODULE(Result::GSP, GSP); 5 | 6 | namespace Result::GSP { 7 | DEFINE_HORIZON_RESULT(SuccessRegisterIRQ, 519, Success, Success); 8 | }; 9 | -------------------------------------------------------------------------------- /include/result/result_kernel.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "result_common.hpp" 3 | 4 | DEFINE_HORIZON_RESULT_MODULE(Result::Kernel, Kernel); 5 | 6 | namespace Result::Kernel { 7 | // Returned when a thread releases a mutex it does not own 8 | DEFINE_HORIZON_RESULT(InvalidMutexRelease, 31, InvalidArgument, Permanent); 9 | DEFINE_HORIZON_RESULT(NotFound, 1018, NotFound, Permanent); 10 | DEFINE_HORIZON_RESULT(InvalidEnumValue, 1005, InvalidArgument, Permanent); 11 | DEFINE_HORIZON_RESULT(InvalidHandle, 1015, InvalidArgument, Permanent); 12 | 13 | static_assert(InvalidHandle == 0xD8E007F7, "conversion broken"); 14 | }; // namespace Result::Kernel 15 | -------------------------------------------------------------------------------- /include/result/result_os.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "result_common.hpp" 3 | 4 | DEFINE_HORIZON_RESULT_MODULE(Result::OS, OS); 5 | 6 | namespace Result::OS { 7 | DEFINE_HORIZON_RESULT(PortNameTooLong, 30, InvalidArgument, Usage); 8 | DEFINE_HORIZON_RESULT(InvalidCombination, 1006, InvalidArgument, Usage); 9 | DEFINE_HORIZON_RESULT(MisalignedAddress, 1009, InvalidArgument, Usage); 10 | DEFINE_HORIZON_RESULT(MisalignedSize, 1010, InvalidArgument, Usage); 11 | DEFINE_HORIZON_RESULT(NotImplemented, 1012, InvalidArgument, Usage); 12 | DEFINE_HORIZON_RESULT(InvalidHandle, 1015, WrongArgument, Permanent); 13 | DEFINE_HORIZON_RESULT(OutOfRange, 1021, InvalidArgument, Usage); 14 | DEFINE_HORIZON_RESULT(Timeout, 1022, StatusChanged, Info); 15 | }; // namespace Result::OS 16 | -------------------------------------------------------------------------------- /include/services/ac.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "helpers.hpp" 5 | #include "kernel_types.hpp" 6 | #include "logger.hpp" 7 | #include "memory.hpp" 8 | #include "result/result.hpp" 9 | 10 | class ACService { 11 | using Handle = HorizonHandle; 12 | 13 | Handle handle = KernelHandles::AC; 14 | Memory& mem; 15 | MAKE_LOG_FUNCTION(log, acLogger) 16 | 17 | // Service commands 18 | void cancelConnectAsync(u32 messagePointer); 19 | void closeAsync(u32 messagePointer); 20 | void createDefaultConfig(u32 messagePointer); 21 | void getConnectingInfraPriority(u32 messagePointer); 22 | void getNZoneBeaconNotFoundEvent(u32 messagePointer); 23 | void getStatus(u32 messagePointer); 24 | void getLastErrorCode(u32 messagePointer); 25 | void getWifiStatus(u32 messagePointer); 26 | void isConnected(u32 messagePointer); 27 | void registerDisconnectEvent(u32 messagePointer); 28 | void setClientVersion(u32 messagePointer); 29 | 30 | bool connected = false; 31 | std::optional disconnectEvent = std::nullopt; 32 | 33 | public: 34 | ACService(Memory& mem) : mem(mem) {} 35 | void reset(); 36 | void handleSyncRequest(u32 messagePointer); 37 | }; -------------------------------------------------------------------------------- /include/services/act.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "helpers.hpp" 3 | #include "kernel_types.hpp" 4 | #include "logger.hpp" 5 | #include "memory.hpp" 6 | #include "result/result.hpp" 7 | 8 | class ACTService { 9 | using Handle = HorizonHandle; 10 | 11 | Handle handle = KernelHandles::ACT; 12 | Memory& mem; 13 | MAKE_LOG_FUNCTION(log, actLogger) 14 | 15 | // Service commands 16 | void initialize(u32 messagePointer); 17 | void generateUUID(u32 messagePointer); 18 | void getAccountDataBlock(u32 messagePointer); 19 | 20 | public: 21 | ACTService(Memory& mem) : mem(mem) {} 22 | void reset(); 23 | void handleSyncRequest(u32 messagePointer); 24 | }; -------------------------------------------------------------------------------- /include/services/am.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "helpers.hpp" 3 | #include "kernel_types.hpp" 4 | #include "logger.hpp" 5 | #include "memory.hpp" 6 | #include "result/result.hpp" 7 | 8 | class AMService { 9 | using Handle = HorizonHandle; 10 | 11 | Handle handle = KernelHandles::AM; 12 | Memory& mem; 13 | MAKE_LOG_FUNCTION(log, amLogger) 14 | 15 | // Service commands 16 | void getDLCTitleInfo(u32 messagePointer); 17 | void getPatchTitleInfo(u32 messagePointer); 18 | void listTitleInfo(u32 messagePointer); 19 | 20 | public: 21 | AMService(Memory& mem) : mem(mem) {} 22 | void reset(); 23 | void handleSyncRequest(u32 messagePointer); 24 | }; -------------------------------------------------------------------------------- /include/services/amiibo_device.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "helpers.hpp" 4 | #include "io_file.hpp" 5 | #include "nfc_types.hpp" 6 | 7 | class AmiiboDevice { 8 | bool loaded = false; 9 | bool encrypted = false; 10 | 11 | public: 12 | static constexpr size_t tagSize = 0x21C; 13 | std::array raw; 14 | 15 | void loadFromRaw(); 16 | void reset(); 17 | }; -------------------------------------------------------------------------------- /include/services/cecd.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "helpers.hpp" 5 | #include "kernel_types.hpp" 6 | #include "logger.hpp" 7 | #include "memory.hpp" 8 | #include "result/result.hpp" 9 | 10 | class Kernel; 11 | 12 | class CECDService { 13 | using Handle = HorizonHandle; 14 | 15 | Handle handle = KernelHandles::CECD; 16 | Memory& mem; 17 | Kernel& kernel; 18 | MAKE_LOG_FUNCTION(log, cecdLogger) 19 | 20 | std::optional infoEvent; 21 | 22 | // Service commands 23 | void getInfoEventHandle(u32 messagePointer); 24 | void openAndRead(u32 messagePointer); 25 | 26 | public: 27 | CECDService(Memory& mem, Kernel& kernel) : mem(mem), kernel(kernel) {} 28 | void reset(); 29 | void handleSyncRequest(u32 messagePointer); 30 | }; -------------------------------------------------------------------------------- /include/services/csnd.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "helpers.hpp" 5 | #include "kernel_types.hpp" 6 | #include "logger.hpp" 7 | #include "memory.hpp" 8 | 9 | // Circular dependencies ^-^ 10 | class Kernel; 11 | 12 | class CSNDService { 13 | using Handle = HorizonHandle; 14 | 15 | Handle handle = KernelHandles::CSND; 16 | Memory& mem; 17 | Kernel& kernel; 18 | MAKE_LOG_FUNCTION(log, csndLogger) 19 | 20 | u8* sharedMemory = nullptr; 21 | std::optional csndMutex = std::nullopt; 22 | size_t sharedMemSize = 0; 23 | bool initialized = false; 24 | 25 | // Service functions 26 | void acquireSoundChannels(u32 messagePointer); 27 | void executeCommands(u32 messagePointer); 28 | void initialize(u32 messagePointer); 29 | 30 | public: 31 | CSNDService(Memory& mem, Kernel& kernel) : mem(mem), kernel(kernel) {} 32 | void reset(); 33 | void handleSyncRequest(u32 messagePointer); 34 | 35 | void setSharedMemory(u8* ptr) { sharedMemory = ptr; } 36 | }; -------------------------------------------------------------------------------- /include/services/dlp_srvr.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "helpers.hpp" 3 | #include "kernel_types.hpp" 4 | #include "logger.hpp" 5 | #include "memory.hpp" 6 | #include "result/result.hpp" 7 | 8 | // Please forgive me for how everything in this file is named 9 | // "dlp:SRVR" is not a nice name to work with 10 | class DlpSrvrService { 11 | using Handle = HorizonHandle; 12 | 13 | Handle handle = KernelHandles::DLP_SRVR; 14 | Memory& mem; 15 | MAKE_LOG_FUNCTION(log, dlpSrvrLogger) 16 | 17 | // Service commands 18 | void isChild(u32 messagePointer); 19 | 20 | public: 21 | DlpSrvrService(Memory& mem) : mem(mem) {} 22 | void reset(); 23 | void handleSyncRequest(u32 messagePointer); 24 | }; -------------------------------------------------------------------------------- /include/services/gsp_lcd.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "helpers.hpp" 3 | #include "kernel_types.hpp" 4 | #include "logger.hpp" 5 | #include "memory.hpp" 6 | #include "result/result.hpp" 7 | 8 | class LCDService { 9 | Memory& mem; 10 | MAKE_LOG_FUNCTION(log, gspLCDLogger) 11 | 12 | // Service commands 13 | void setLedForceOff(u32 messagePointer); 14 | 15 | public: 16 | LCDService(Memory& mem) : mem(mem) {} 17 | void reset(); 18 | void handleSyncRequest(u32 messagePointer); 19 | }; -------------------------------------------------------------------------------- /include/services/http.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "helpers.hpp" 3 | #include "kernel_types.hpp" 4 | #include "logger.hpp" 5 | #include "memory.hpp" 6 | 7 | class HTTPService { 8 | using Handle = HorizonHandle; 9 | 10 | Handle handle = KernelHandles::HTTP; 11 | Memory& mem; 12 | MAKE_LOG_FUNCTION(log, httpLogger) 13 | 14 | bool initialized = false; 15 | 16 | // Service commands 17 | void createRootCertChain(u32 messagePointer); 18 | void initialize(u32 messagePointer); 19 | void rootCertChainAddDefaultCert(u32 messagePointer); 20 | 21 | public: 22 | HTTPService(Memory& mem) : mem(mem) {} 23 | void reset(); 24 | void handleSyncRequest(u32 messagePointer); 25 | }; -------------------------------------------------------------------------------- /include/services/ldr_ro.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "helpers.hpp" 3 | #include "kernel_types.hpp" 4 | #include "logger.hpp" 5 | #include "memory.hpp" 6 | #include "result/result.hpp" 7 | 8 | class Kernel; 9 | 10 | class LDRService { 11 | using Handle = HorizonHandle; 12 | 13 | Handle handle = KernelHandles::LDR_RO; 14 | Memory& mem; 15 | Kernel& kernel; 16 | MAKE_LOG_FUNCTION(log, ldrLogger) 17 | 18 | u32 loadedCRS; 19 | 20 | // Service commands 21 | void initialize(u32 messagePointer); 22 | void linkCRO(u32 messagePointer); 23 | void loadCRO(u32 messagePointer, bool isNew); 24 | void loadCRR(u32 messagePointer); 25 | void unloadCRO(u32 messagePointer); 26 | 27 | public: 28 | LDRService(Memory& mem, Kernel& kernel) : mem(mem), kernel(kernel) {} 29 | void reset(); 30 | void handleSyncRequest(u32 messagePointer); 31 | }; -------------------------------------------------------------------------------- /include/services/mcu/mcu_hwc.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "config.hpp" 3 | #include "helpers.hpp" 4 | #include "kernel_types.hpp" 5 | #include "logger.hpp" 6 | #include "memory.hpp" 7 | 8 | namespace MCU { 9 | class HWCService { 10 | using Handle = HorizonHandle; 11 | 12 | Handle handle = KernelHandles::MCU_HWC; 13 | Memory& mem; 14 | MAKE_LOG_FUNCTION(log, mcuLogger) 15 | 16 | const EmulatorConfig& config; 17 | 18 | // Service commands 19 | void getBatteryLevel(u32 messagePointer); 20 | void setInfoLEDPattern(u32 messagePointer); 21 | 22 | public: 23 | HWCService(Memory& mem, const EmulatorConfig& config) : mem(mem), config(config) {} 24 | void reset(); 25 | void handleSyncRequest(u32 messagePointer); 26 | }; 27 | } // namespace MCU -------------------------------------------------------------------------------- /include/services/ndm.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "helpers.hpp" 3 | #include "kernel_types.hpp" 4 | #include "logger.hpp" 5 | #include "memory.hpp" 6 | #include "result/result.hpp" 7 | 8 | class NDMService { 9 | using Handle = HorizonHandle; 10 | enum class ExclusiveState : u32 { 11 | None = 0, 12 | Infrastructure = 1, 13 | LocalComms = 2, 14 | StreetPass = 3, 15 | StreetPassData = 4, 16 | }; 17 | 18 | Handle handle = KernelHandles::NDM; 19 | Memory& mem; 20 | MAKE_LOG_FUNCTION(log, ndmLogger) 21 | 22 | // Service commands 23 | void clearHalfAwakeMacFilter(u32 messagePointer); 24 | void enterExclusiveState(u32 messagePointer); 25 | void exitExclusiveState(u32 messagePointer); 26 | void overrideDefaultDaemons(u32 messagePointer); 27 | void queryExclusiveState(u32 messagePointer); 28 | void resumeDaemons(u32 messagePointer); 29 | void resumeScheduler(u32 messagePointer); 30 | void suspendDaemons(u32 messagePointer); 31 | void suspendScheduler(u32 messagePointer); 32 | 33 | ExclusiveState exclusiveState = ExclusiveState::None; 34 | 35 | public: 36 | NDMService(Memory& mem) : mem(mem) {} 37 | void reset(); 38 | void handleSyncRequest(u32 messagePointer); 39 | }; -------------------------------------------------------------------------------- /include/services/news_u.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "helpers.hpp" 3 | #include "kernel_types.hpp" 4 | #include "logger.hpp" 5 | #include "memory.hpp" 6 | 7 | class NewsUService { 8 | using Handle = HorizonHandle; 9 | 10 | Handle handle = KernelHandles::NEWS_U; 11 | Memory& mem; 12 | MAKE_LOG_FUNCTION(log, newsLogger) 13 | 14 | // Service commands 15 | 16 | public: 17 | NewsUService(Memory& mem) : mem(mem) {} 18 | void reset(); 19 | void handleSyncRequest(u32 messagePointer); 20 | }; -------------------------------------------------------------------------------- /include/services/nim.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "helpers.hpp" 3 | #include "kernel_types.hpp" 4 | #include "logger.hpp" 5 | #include "memory.hpp" 6 | #include "result/result.hpp" 7 | 8 | class NIMService { 9 | using Handle = HorizonHandle; 10 | 11 | Handle handle = KernelHandles::NIM; 12 | Memory& mem; 13 | MAKE_LOG_FUNCTION(log, nimLogger) 14 | 15 | // Service commands 16 | void initialize(u32 messagePointer); 17 | 18 | public: 19 | NIMService(Memory& mem) : mem(mem) {} 20 | void reset(); 21 | void handleSyncRequest(u32 messagePointer); 22 | }; -------------------------------------------------------------------------------- /include/services/ns.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "helpers.hpp" 3 | #include "kernel_types.hpp" 4 | #include "logger.hpp" 5 | #include "memory.hpp" 6 | #include "result/result.hpp" 7 | 8 | class NSService { 9 | Memory& mem; 10 | MAKE_LOG_FUNCTION(log, nsLogger) 11 | 12 | // Service commands 13 | void launchTitle(u32 messagePointer); 14 | 15 | public: 16 | enum class Type { 17 | S, // ns:s 18 | P, // ns:p 19 | C, // ns:c 20 | }; 21 | 22 | NSService(Memory& mem) : mem(mem) {} 23 | void reset(); 24 | void handleSyncRequest(u32 messagePointer, Type type); 25 | }; 26 | -------------------------------------------------------------------------------- /include/services/nwm_uds.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "helpers.hpp" 5 | #include "kernel_types.hpp" 6 | #include "logger.hpp" 7 | #include "memory.hpp" 8 | 9 | // More circular dependencies 10 | class Kernel; 11 | 12 | class NwmUdsService { 13 | using Handle = HorizonHandle; 14 | 15 | Handle handle = KernelHandles::NWM_UDS; 16 | Memory& mem; 17 | Kernel& kernel; 18 | MAKE_LOG_FUNCTION(log, nwmUdsLogger) 19 | 20 | bool initialized = false; 21 | std::optional eventHandle = std::nullopt; 22 | 23 | // Service commands 24 | void initializeWithVersion(u32 messagePointer); 25 | 26 | public: 27 | NwmUdsService(Memory& mem, Kernel& kernel) : mem(mem), kernel(kernel) {} 28 | void reset(); 29 | void handleSyncRequest(u32 messagePointer); 30 | }; -------------------------------------------------------------------------------- /include/services/soc.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "helpers.hpp" 3 | #include "kernel_types.hpp" 4 | #include "logger.hpp" 5 | #include "memory.hpp" 6 | 7 | class SOCService { 8 | using Handle = HorizonHandle; 9 | 10 | Handle handle = KernelHandles::SOC; 11 | Memory& mem; 12 | MAKE_LOG_FUNCTION(log, socLogger) 13 | 14 | bool initialized = false; 15 | 16 | // Service commands 17 | void initializeSockets(u32 messagePointer); 18 | 19 | public: 20 | SOCService(Memory& mem) : mem(mem) {} 21 | void reset(); 22 | void handleSyncRequest(u32 messagePointer); 23 | }; -------------------------------------------------------------------------------- /include/services/ssl.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "helpers.hpp" 5 | #include "kernel_types.hpp" 6 | #include "logger.hpp" 7 | #include "memory.hpp" 8 | 9 | class SSLService { 10 | using Handle = HorizonHandle; 11 | 12 | Handle handle = KernelHandles::SSL; 13 | Memory& mem; 14 | MAKE_LOG_FUNCTION(log, sslLogger) 15 | 16 | std::mt19937 rng; // Use a Mersenne Twister for RNG since this service is supposed to have better rng than just rand() 17 | bool initialized; 18 | 19 | // Service commands 20 | void initialize(u32 messagePointer); 21 | void generateRandomData(u32 messagePointer); 22 | 23 | public: 24 | SSLService(Memory& mem) : mem(mem) {} 25 | void reset(); 26 | void handleSyncRequest(u32 messagePointer); 27 | }; -------------------------------------------------------------------------------- /include/system_models.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | // Codes for every 3DS system model 5 | // The 3-letter codes are codenames used by the ACT service, and can also be found on the hardware itself 6 | // This info can be retrieved in a variety of ways, usually through CFG::GetSystemModel 7 | namespace SystemModel { 8 | enum : std::uint32_t { 9 | Nintendo3DS = 0, 10 | Nintendo3DS_XL = 1, 11 | NewNintendo3DS = 2, 12 | Nintendo2DS = 3, 13 | NewNintendo3DS_XL = 4, 14 | NewNintendo2DS_XL = 5, 15 | 16 | CTR = Nintendo3DS, 17 | SPR = Nintendo3DS_XL, 18 | KTR = NewNintendo3DS, 19 | FTR = Nintendo2DS, 20 | RED = NewNintendo3DS_XL, 21 | JAN = NewNintendo2DS_XL 22 | }; 23 | } -------------------------------------------------------------------------------- /src/core/PICA/shader_unit.cpp: -------------------------------------------------------------------------------- 1 | #include "PICA/shader_unit.hpp" 2 | 3 | #include "cityhash.hpp" 4 | 5 | void ShaderUnit::reset() { 6 | vs.reset(); 7 | gs.reset(); 8 | } 9 | 10 | void PICAShader::reset() { 11 | loadedShader.fill(0); 12 | operandDescriptors.fill(0); 13 | 14 | boolUniform = 0; 15 | bufferIndex = 0; 16 | floatUniformIndex = 0; 17 | floatUniformWordCount = 0; 18 | opDescriptorIndex = 0; 19 | f32UniformTransfer = false; 20 | 21 | const vec4f zero = vec4f({f24::zero(), f24::zero(), f24::zero(), f24::zero()}); 22 | inputs.fill(zero); 23 | floatUniforms.fill(zero); 24 | outputs.fill(zero); 25 | tempRegisters.fill(zero); 26 | 27 | for (auto& e : intUniforms) { 28 | e[0] = e[1] = e[2] = e[3] = 0; 29 | } 30 | 31 | addrRegister[0] = 0; 32 | addrRegister[1] = 0; 33 | loopCounter = 0; 34 | 35 | codeHashDirty = true; 36 | opdescHashDirty = true; 37 | uniformsDirty = true; 38 | } -------------------------------------------------------------------------------- /src/core/applets/applet.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/src/core/applets/applet.cpp -------------------------------------------------------------------------------- /src/core/applets/error_applet.cpp: -------------------------------------------------------------------------------- 1 | #include "applets/error_applet.hpp" 2 | #include "kernel/handles.hpp" 3 | 4 | using namespace Applets; 5 | 6 | void ErrorApplet::reset() {} 7 | 8 | Result::HorizonResult ErrorApplet::start(const MemoryBlock* sharedMem, const std::vector& parameters, u32 appID) { 9 | Applets::Parameter param = Applets::Parameter{ 10 | .senderID = appID, 11 | .destID = AppletIDs::Application, 12 | .signal = static_cast(APTSignal::WakeupByExit), 13 | .object = 0, 14 | .data = parameters, // TODO: Figure out how the data format for this applet 15 | }; 16 | 17 | nextParameter = param; 18 | return Result::Success; 19 | } 20 | 21 | Result::HorizonResult ErrorApplet::receiveParameter(const Applets::Parameter& parameter) { 22 | Applets::Parameter param = Applets::Parameter{ 23 | .senderID = parameter.destID, 24 | .destID = AppletIDs::Application, 25 | .signal = static_cast(APTSignal::Response), 26 | .object = KernelHandles::APTCaptureSharedMemHandle, 27 | .data = {}, 28 | }; 29 | 30 | nextParameter = param; 31 | return Result::Success; 32 | } -------------------------------------------------------------------------------- /src/core/renderer_mtl/metal_cpp_impl.cpp: -------------------------------------------------------------------------------- 1 | #define NS_PRIVATE_IMPLEMENTATION 2 | #define CA_PRIVATE_IMPLEMENTATION 3 | #define MTL_PRIVATE_IMPLEMENTATION 4 | #include 5 | #include 6 | #include 7 | -------------------------------------------------------------------------------- /src/core/renderer_mtl/mtl_lut_texture.cpp: -------------------------------------------------------------------------------- 1 | #include "renderer_mtl/renderer_mtl.hpp" 2 | 3 | namespace Metal { 4 | static constexpr u32 LAYER_COUNT = 1024; 5 | 6 | LutTexture::LutTexture(MTL::Device* device, MTL::TextureType type, MTL::PixelFormat pixelFormat, u32 width, u32 height, const char* name) { 7 | MTL::TextureDescriptor* desc = MTL::TextureDescriptor::alloc()->init(); 8 | desc->setTextureType(type); 9 | desc->setPixelFormat(pixelFormat); 10 | desc->setWidth(width); 11 | desc->setHeight(height); 12 | desc->setArrayLength(LAYER_COUNT); 13 | desc->setUsage(MTL::TextureUsageShaderRead /* | MTL::TextureUsageShaderWrite*/); 14 | desc->setStorageMode(MTL::StorageModeShared); 15 | 16 | texture = device->newTexture(desc); 17 | texture->setLabel(toNSString(name)); 18 | desc->release(); 19 | } 20 | 21 | LutTexture::~LutTexture() { texture->release(); } 22 | 23 | u32 LutTexture::getNextIndex() { 24 | currentIndex = (currentIndex + 1) % LAYER_COUNT; 25 | return currentIndex; 26 | } 27 | } // namespace Metal 28 | -------------------------------------------------------------------------------- /src/core/renderer_mtl/objc_helper.mm: -------------------------------------------------------------------------------- 1 | #include "renderer_mtl/objc_helper.hpp" 2 | 3 | // TODO: change the include 4 | #import 5 | 6 | namespace Metal { 7 | 8 | dispatch_data_t createDispatchData(const void* data, size_t size) { 9 | return dispatch_data_create(data, size, dispatch_get_global_queue(0, 0), ^{}); 10 | } 11 | 12 | } // namespace Metal 13 | -------------------------------------------------------------------------------- /src/core/renderer_null/renderer_null.cpp: -------------------------------------------------------------------------------- 1 | #include "renderer_null/renderer_null.hpp" 2 | 3 | RendererNull::RendererNull(GPU& gpu, const std::array& internalRegs, const std::array& externalRegs) 4 | : Renderer(gpu, internalRegs, externalRegs) {} 5 | RendererNull::~RendererNull() {} 6 | 7 | void RendererNull::reset() {} 8 | void RendererNull::display() {} 9 | void RendererNull::initGraphicsContext(SDL_Window* window) {} 10 | void RendererNull::clearBuffer(u32 startAddress, u32 endAddress, u32 value, u32 control) {} 11 | void RendererNull::displayTransfer(u32 inputAddr, u32 outputAddr, u32 inputSize, u32 outputSize, u32 flags) {} 12 | void RendererNull::textureCopy(u32 inputAddr, u32 outputAddr, u32 totalBytes, u32 inputSize, u32 outputSize, u32 flags) {} 13 | void RendererNull::drawVertices(PICA::PrimType primType, std::span vertices) {} 14 | void RendererNull::screenshot(const std::string& name) {} 15 | void RendererNull::deinitGraphicsContext() {} -------------------------------------------------------------------------------- /src/core/renderer_vk/vk_api.cpp: -------------------------------------------------------------------------------- 1 | #include "renderer_vk/vk_api.hpp" 2 | 3 | VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE; -------------------------------------------------------------------------------- /src/core/renderer_vk/vk_sampler_cache.cpp: -------------------------------------------------------------------------------- 1 | #include "renderer_vk/vk_sampler_cache.hpp" 2 | 3 | #include 4 | 5 | #include "helpers.hpp" 6 | 7 | namespace Vulkan { 8 | 9 | SamplerCache::SamplerCache(vk::Device device) : device(device) {} 10 | 11 | const vk::Sampler& SamplerCache::getSampler(const vk::SamplerCreateInfo& samplerInfo) { 12 | const std::size_t samplerHash = std::hash()(samplerInfo); 13 | 14 | // Cache hit 15 | if (samplerMap.contains(samplerHash)) { 16 | return samplerMap.at(samplerHash).get(); 17 | } 18 | 19 | if (auto createResult = device.createSamplerUnique(samplerInfo); createResult.result == vk::Result::eSuccess) { 20 | return (samplerMap[samplerHash] = std::move(createResult.value)).get(); 21 | } else { 22 | Helpers::panic("Error creating sampler: %s\n", vk::to_string(createResult.result).c_str()); 23 | } 24 | } 25 | 26 | std::optional SamplerCache::create(vk::Device device) { 27 | SamplerCache newSamplerCache(device); 28 | 29 | return {std::move(newSamplerCache)}; 30 | } 31 | } // namespace Vulkan -------------------------------------------------------------------------------- /src/core/services/amiibo_device.cpp: -------------------------------------------------------------------------------- 1 | #include "services/amiibo_device.hpp" 2 | 3 | void AmiiboDevice::reset() { 4 | encrypted = false; 5 | loaded = false; 6 | } 7 | 8 | // Load amiibo information from our raw 540 byte array 9 | void AmiiboDevice::loadFromRaw() { 10 | 11 | } -------------------------------------------------------------------------------- /src/core/services/dlp_srvr.cpp: -------------------------------------------------------------------------------- 1 | #include "services/dlp_srvr.hpp" 2 | #include "ipc.hpp" 3 | 4 | namespace DlpSrvrCommands { 5 | enum : u32 { 6 | IsChild = 0x000E0040 7 | }; 8 | } 9 | 10 | void DlpSrvrService::reset() {} 11 | 12 | void DlpSrvrService::handleSyncRequest(u32 messagePointer) { 13 | const u32 command = mem.read32(messagePointer); 14 | switch (command) { 15 | case DlpSrvrCommands::IsChild: isChild(messagePointer); break; 16 | default: Helpers::panic("DLP::SRVR service requested. Command: %08X\n", command); 17 | } 18 | } 19 | 20 | void DlpSrvrService::isChild(u32 messagePointer) { 21 | log("DLP::SRVR: IsChild\n"); 22 | 23 | mem.write32(messagePointer, IPC::responseHeader(0x0E, 2, 0)); 24 | mem.write32(messagePointer + 4, Result::Success); 25 | mem.write32(messagePointer + 8, 0); // We are responsible adults 26 | } -------------------------------------------------------------------------------- /src/core/services/fonts/SharedFontReplacement.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/src/core/services/fonts/SharedFontReplacement.bin -------------------------------------------------------------------------------- /src/core/services/gsp_lcd.cpp: -------------------------------------------------------------------------------- 1 | #include "services/gsp_lcd.hpp" 2 | 3 | #include "ipc.hpp" 4 | 5 | namespace LCDCommands { 6 | enum : u32 { 7 | SetLedForceOff = 0x00130040, 8 | }; 9 | } 10 | 11 | void LCDService::reset() {} 12 | 13 | void LCDService::handleSyncRequest(u32 messagePointer) { 14 | const u32 command = mem.read32(messagePointer); 15 | switch (command) { 16 | case LCDCommands::SetLedForceOff: setLedForceOff(messagePointer); break; 17 | 18 | default: Helpers::panic("LCD service requested. Command: %08X\n", command); 19 | } 20 | } 21 | 22 | void LCDService::setLedForceOff(u32 messagePointer) { 23 | const u8 state = mem.read8(messagePointer + 4); 24 | log("LCD::SetLedForceOff (state = %X)\n", state); 25 | 26 | mem.write32(messagePointer, IPC::responseHeader(0x13, 1, 0)); 27 | mem.write32(messagePointer + 4, Result::Success); 28 | } -------------------------------------------------------------------------------- /src/core/services/news_u.cpp: -------------------------------------------------------------------------------- 1 | #include "ipc.hpp" 2 | #include "services/news_u.hpp" 3 | 4 | namespace NewsCommands { 5 | enum : u32 {}; 6 | } 7 | 8 | void NewsUService::reset() {} 9 | 10 | void NewsUService::handleSyncRequest(u32 messagePointer) { 11 | const u32 command = mem.read32(messagePointer); 12 | switch (command) { 13 | default: Helpers::panic("news:u service requested. Command: %08X\n", command); 14 | } 15 | } -------------------------------------------------------------------------------- /src/core/services/nim.cpp: -------------------------------------------------------------------------------- 1 | #include "services/nim.hpp" 2 | #include "ipc.hpp" 3 | 4 | namespace NIMCommands { 5 | enum : u32 { 6 | Initialize = 0x00210000 7 | }; 8 | } 9 | 10 | void NIMService::reset() {} 11 | 12 | void NIMService::handleSyncRequest(u32 messagePointer) { 13 | const u32 command = mem.read32(messagePointer); 14 | switch (command) { 15 | case NIMCommands::Initialize: initialize(messagePointer); break; 16 | default: Helpers::panic("NIM service requested. Command: %08X\n", command); 17 | } 18 | } 19 | 20 | void NIMService::initialize(u32 messagePointer) { 21 | log("NIM::Initialize\n"); 22 | mem.write32(messagePointer, IPC::responseHeader(0x21, 1, 0)); 23 | mem.write32(messagePointer + 4, Result::Success); 24 | } -------------------------------------------------------------------------------- /src/core/services/ns.cpp: -------------------------------------------------------------------------------- 1 | #include "services/ns.hpp" 2 | 3 | #include "ipc.hpp" 4 | 5 | namespace NSCommands { 6 | enum : u32 { 7 | LaunchTitle = 0x000200C0, 8 | }; 9 | } 10 | 11 | void NSService::reset() {} 12 | 13 | void NSService::handleSyncRequest(u32 messagePointer, Type type) { 14 | const u32 command = mem.read32(messagePointer); 15 | 16 | // ns:s commands 17 | switch (command) { 18 | case NSCommands::LaunchTitle: launchTitle(messagePointer); break; 19 | 20 | default: Helpers::panic("NS service requested. Command: %08X\n", command); 21 | } 22 | } 23 | 24 | void NSService::launchTitle(u32 messagePointer) { 25 | const u64 titleID = mem.read64(messagePointer + 4); 26 | const u32 launchFlags = mem.read32(messagePointer + 12); 27 | Helpers::warn("NS::LaunchTitle (title ID = %llX, launch flags = %X) (stubbed)", titleID, launchFlags); 28 | 29 | mem.write32(messagePointer, IPC::responseHeader(0x2, 2, 0)); 30 | mem.write32(messagePointer + 4, Result::Success); 31 | mem.write32(messagePointer + 8, 0); // Process ID 32 | } 33 | -------------------------------------------------------------------------------- /src/discord_rpc.cpp: -------------------------------------------------------------------------------- 1 | #ifdef PANDA3DS_ENABLE_DISCORD_RPC 2 | 3 | #include "discord_rpc.hpp" 4 | 5 | #include 6 | #include 7 | 8 | void Discord::RPC::init() { 9 | DiscordEventHandlers handlers{}; 10 | Discord_Initialize("1138176975865909360", &handlers, 1, nullptr); 11 | 12 | startTimestamp = time(nullptr); 13 | enabled = true; 14 | } 15 | 16 | void Discord::RPC::update(Discord::RPCStatus status, const std::string& game) { 17 | DiscordRichPresence rpc{}; 18 | 19 | if (status == Discord::RPCStatus::Playing) { 20 | rpc.details = "Playing a game"; 21 | rpc.state = game.c_str(); 22 | } else { 23 | rpc.details = "Idle"; 24 | } 25 | 26 | rpc.largeImageKey = "pand"; 27 | rpc.largeImageText = "Panda3DS is a 3DS emulator for Windows, MacOS and Linux"; 28 | rpc.startTimestamp = startTimestamp; 29 | 30 | Discord_UpdatePresence(&rpc); 31 | } 32 | 33 | void Discord::RPC::stop() { 34 | if (enabled) { 35 | enabled = false; 36 | Discord_ClearPresence(); 37 | Discord_Shutdown(); 38 | } 39 | } 40 | 41 | #endif -------------------------------------------------------------------------------- /src/host_shaders/metal_blit.metal: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace metal; 3 | 4 | #define GET_HELPER_TEXTURE_BINDING(binding) (30 - binding) 5 | #define GET_HELPER_SAMPLER_STATE_BINDING(binding) (15 - binding) 6 | 7 | struct BasicVertexOut { 8 | float4 position [[position]]; 9 | float2 uv; 10 | }; 11 | 12 | struct NDCViewport { 13 | float2 offset; 14 | float2 scale; 15 | }; 16 | 17 | vertex BasicVertexOut vertexBlit(uint vid [[vertex_id]], constant NDCViewport& viewport [[buffer(0)]]) { 18 | BasicVertexOut out; 19 | out.uv = float2((vid << 1) & 2, vid & 2); 20 | out.position = float4(out.uv * 2.0 - 1.0, 0.0, 1.0); 21 | out.position.y = -out.position.y; 22 | out.uv = out.uv * viewport.scale + viewport.offset; 23 | 24 | return out; 25 | } 26 | 27 | fragment float4 fragmentBlit(BasicVertexOut in [[stage_in]], texture2d tex [[texture(GET_HELPER_TEXTURE_BINDING(0))]], sampler samplr [[sampler(GET_HELPER_SAMPLER_STATE_BINDING(0))]]) { 28 | return tex.sample(samplr, in.uv); 29 | } 30 | -------------------------------------------------------------------------------- /src/host_shaders/metal_copy_to_lut_texture.metal: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace metal; 3 | 4 | constant ushort lutTextureWidth [[function_constant(0)]]; 5 | 6 | // The copy is done in a vertex shader instead of a compute kernel, since dispatching compute would require ending the render pass 7 | vertex void vertexCopyToLutTexture(uint vid [[vertex_id]], texture2d out [[texture(0)]], device float2* data [[buffer(0)]], constant uint& arrayOffset [[buffer(1)]]) { 8 | out.write(float4(data[vid], 0.0, 0.0), uint2(vid % lutTextureWidth, arrayOffset + vid / lutTextureWidth)); 9 | } 10 | -------------------------------------------------------------------------------- /src/host_shaders/opengl_display.frag: -------------------------------------------------------------------------------- 1 | #version 410 core 2 | in vec2 UV; 3 | out vec4 FragColor; 4 | 5 | uniform sampler2D u_texture; 6 | void main() { 7 | FragColor = texture(u_texture, UV); 8 | } -------------------------------------------------------------------------------- /src/host_shaders/opengl_display.vert: -------------------------------------------------------------------------------- 1 | #version 410 core 2 | out vec2 UV; 3 | 4 | void main() { 5 | const vec4 positions[4] = vec4[]( 6 | vec4(-1.0, 1.0, 1.0, 1.0), // Top-left 7 | vec4(1.0, 1.0, 1.0, 1.0), // Top-right 8 | vec4(-1.0, -1.0, 1.0, 1.0), // Bottom-left 9 | vec4(1.0, -1.0, 1.0, 1.0) // Bottom-right 10 | ); 11 | 12 | // The 3DS displays both screens' framebuffer rotated 90 deg counter clockwise 13 | // So we adjust our texcoords accordingly 14 | const vec2 texcoords[4] = vec2[]( 15 | vec2(1.0, 1.0), // Top-right 16 | vec2(1.0, 0.0), // Bottom-right 17 | vec2(0.0, 1.0), // Top-left 18 | vec2(0.0, 0.0) // Bottom-left 19 | ); 20 | 21 | gl_Position = positions[gl_VertexID]; 22 | UV = texcoords[gl_VertexID]; 23 | } -------------------------------------------------------------------------------- /src/host_shaders/opengl_es_display.frag: -------------------------------------------------------------------------------- 1 | #version 310 es 2 | precision mediump float; 3 | 4 | in vec2 UV; 5 | out vec4 FragColor; 6 | 7 | uniform sampler2D u_texture; 8 | void main() { 9 | FragColor = texture(u_texture, UV); 10 | } -------------------------------------------------------------------------------- /src/host_shaders/opengl_es_display.vert: -------------------------------------------------------------------------------- 1 | #version 310 es 2 | precision mediump float; 3 | 4 | out vec2 UV; 5 | 6 | void main() { 7 | const vec4 positions[4] = vec4[]( 8 | vec4(-1.0, 1.0, 1.0, 1.0), // Top-left 9 | vec4(1.0, 1.0, 1.0, 1.0), // Top-right 10 | vec4(-1.0, -1.0, 1.0, 1.0), // Bottom-left 11 | vec4(1.0, -1.0, 1.0, 1.0) // Bottom-right 12 | ); 13 | 14 | // The 3DS displays both screens' framebuffer rotated 90 deg counter clockwise 15 | // So we adjust our texcoords accordingly 16 | const vec2 texcoords[4] = vec2[]( 17 | vec2(1.0, 1.0), // Top-right 18 | vec2(1.0, 0.0), // Bottom-right 19 | vec2(0.0, 1.0), // Top-left 20 | vec2(0.0, 0.0) // Bottom-left 21 | ); 22 | 23 | gl_Position = positions[gl_VertexID]; 24 | UV = texcoords[gl_VertexID]; 25 | } -------------------------------------------------------------------------------- /src/host_shaders/vulkan_display.frag: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | layout(location = 0) in vec2 UV; 3 | layout(location = 0) out vec4 FragColor; 4 | 5 | layout(binding = 0) uniform sampler2D u_texture; 6 | 7 | void main() { FragColor = texture(u_texture, UV); } -------------------------------------------------------------------------------- /src/host_shaders/vulkan_display.vert: -------------------------------------------------------------------------------- 1 | #version 460 core 2 | layout(location = 0) out vec2 UV; 3 | 4 | void main() { 5 | UV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); 6 | gl_Position = vec4(UV * 2.0f + -1.0f, 0.0f, 1.0f); 7 | } -------------------------------------------------------------------------------- /src/memory_mapped_file.cpp: -------------------------------------------------------------------------------- 1 | #include "memory_mapped_file.hpp" 2 | 3 | MemoryMappedFile::MemoryMappedFile() : opened(false), filePath(""), pointer(nullptr) {} 4 | MemoryMappedFile::MemoryMappedFile(const std::filesystem::path& path) { open(path); } 5 | MemoryMappedFile::~MemoryMappedFile() { close(); } 6 | 7 | // TODO: This should probably also return the error one way or another eventually 8 | bool MemoryMappedFile::open(const std::filesystem::path& path) { 9 | std::error_code error; 10 | map = mio::make_mmap_sink(path.string(), 0, mio::map_entire_file, error); 11 | 12 | if (error) { 13 | opened = false; 14 | return false; 15 | } 16 | 17 | filePath = path; 18 | pointer = (u8*)map.data(); 19 | opened = true; 20 | return true; 21 | } 22 | 23 | void MemoryMappedFile::close() { 24 | if (opened) { 25 | opened = false; 26 | pointer = nullptr; // Set the pointer to nullptr to avoid errors related to lingering pointers 27 | 28 | map.unmap(); 29 | } 30 | } 31 | 32 | std::error_code MemoryMappedFile::flush() { 33 | std::error_code ret; 34 | map.sync(ret); 35 | 36 | return ret; 37 | } -------------------------------------------------------------------------------- /src/miniaudio/miniaudio.cpp: -------------------------------------------------------------------------------- 1 | // We do not need the ability to be able to encode or decode audio files for the time being 2 | // So we disable said functionality to make the executable smaller. 3 | #define MA_NO_DECODING 4 | #define MA_NO_ENCODING 5 | #define MINIAUDIO_IMPLEMENTATION 6 | 7 | #ifndef PANDA3DS_IOS 8 | #include "miniaudio.h" 9 | #endif -------------------------------------------------------------------------------- /src/miniaudio/miniaudio.m: -------------------------------------------------------------------------------- 1 | // We do not need the ability to be able to encode or decode audio files for the time being 2 | // So we disable said functionality to make the executable smaller. 3 | #define MA_NO_DECODING 4 | #define MA_NO_ENCODING 5 | #define MINIAUDIO_IMPLEMENTATION 6 | 7 | // On iOS we have to compile miniaudio as Obj-C 8 | #include "miniaudio.h" 9 | -------------------------------------------------------------------------------- /src/panda_qt/elided_label.cpp: -------------------------------------------------------------------------------- 1 | #include "panda_qt/elided_label.hpp" 2 | 3 | // Based on https://stackoverflow.com/questions/7381100/text-overflow-for-a-qlabel-s-text-rendering-in-qt 4 | ElidedLabel::ElidedLabel(Qt::TextElideMode elideMode, QWidget* parent) : ElidedLabel("", elideMode, parent) {} 5 | 6 | ElidedLabel::ElidedLabel(QString text, Qt::TextElideMode elideMode, QWidget* parent) : QLabel(parent) { 7 | m_elideMode = elideMode; 8 | setText(text); 9 | } 10 | 11 | void ElidedLabel::setText(QString text) { 12 | m_text = text; 13 | updateText(); 14 | } 15 | 16 | void ElidedLabel::resizeEvent(QResizeEvent* event) { 17 | QLabel::resizeEvent(event); 18 | updateText(); 19 | } 20 | 21 | void ElidedLabel::updateText() { 22 | QFontMetrics metrics(font()); 23 | QString elided = metrics.elidedText(m_text, m_elideMode, width()); 24 | QLabel::setText(elided); 25 | } -------------------------------------------------------------------------------- /src/panda_qt/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "panda_qt/main_window.hpp" 4 | #include "panda_qt/screen.hpp" 5 | 6 | int main(int argc, char *argv[]) { 7 | QApplication app(argc, argv); 8 | MainWindow window(&app); 9 | 10 | return app.exec(); 11 | } 12 | -------------------------------------------------------------------------------- /src/panda_qt/mappings.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "input_mappings.hpp" 4 | 5 | InputMappings InputMappings::defaultKeyboardMappings() { 6 | InputMappings mappings; 7 | mappings.setMapping(Qt::Key_L, HID::Keys::A); 8 | mappings.setMapping(Qt::Key_K, HID::Keys::B); 9 | mappings.setMapping(Qt::Key_O, HID::Keys::X); 10 | mappings.setMapping(Qt::Key_I, HID::Keys::Y); 11 | mappings.setMapping(Qt::Key_Q, HID::Keys::L); 12 | mappings.setMapping(Qt::Key_P, HID::Keys::R); 13 | mappings.setMapping(Qt::Key_Up, HID::Keys::Up); 14 | mappings.setMapping(Qt::Key_Down, HID::Keys::Down); 15 | mappings.setMapping(Qt::Key_Right, HID::Keys::Right); 16 | mappings.setMapping(Qt::Key_Left, HID::Keys::Left); 17 | mappings.setMapping(Qt::Key_Return, HID::Keys::Start); 18 | mappings.setMapping(Qt::Key_Backspace, HID::Keys::Select); 19 | mappings.setMapping(Qt::Key_W, HID::Keys::CirclePadUp); 20 | mappings.setMapping(Qt::Key_S, HID::Keys::CirclePadDown); 21 | mappings.setMapping(Qt::Key_D, HID::Keys::CirclePadRight); 22 | mappings.setMapping(Qt::Key_A, HID::Keys::CirclePadLeft); 23 | 24 | return mappings; 25 | } -------------------------------------------------------------------------------- /src/panda_qt/zep.cpp: -------------------------------------------------------------------------------- 1 | #define ZEP_SINGLE_HEADER_BUILD 2 | #include "zep.h" -------------------------------------------------------------------------------- /src/panda_sdl/main.cpp: -------------------------------------------------------------------------------- 1 | #include "panda_sdl/frontend_sdl.hpp" 2 | 3 | int main(int argc, char *argv[]) { 4 | FrontendSDL app; 5 | 6 | if (argc > 1) { 7 | auto romPath = std::filesystem::current_path() / argv[1]; 8 | if (!app.loadROM(romPath)) { 9 | // For some reason just .c_str() doesn't show the proper path 10 | Helpers::panic("Failed to load ROM file: %s", romPath.string().c_str()); 11 | } 12 | } else { 13 | printf("No ROM inserted! Load a ROM by dragging and dropping it into the emulator window!\n"); 14 | } 15 | 16 | app.run(); 17 | } 18 | -------------------------------------------------------------------------------- /src/panda_sdl/mappings.cpp: -------------------------------------------------------------------------------- 1 | #include "input_mappings.hpp" 2 | 3 | #include 4 | 5 | InputMappings InputMappings::defaultKeyboardMappings() { 6 | InputMappings mappings; 7 | mappings.setMapping(SDLK_l, HID::Keys::A); 8 | mappings.setMapping(SDLK_k, HID::Keys::B); 9 | mappings.setMapping(SDLK_o, HID::Keys::X); 10 | mappings.setMapping(SDLK_i, HID::Keys::Y); 11 | mappings.setMapping(SDLK_q, HID::Keys::L); 12 | mappings.setMapping(SDLK_p, HID::Keys::R); 13 | mappings.setMapping(SDLK_UP, HID::Keys::Up); 14 | mappings.setMapping(SDLK_DOWN, HID::Keys::Down); 15 | mappings.setMapping(SDLK_RIGHT, HID::Keys::Right); 16 | mappings.setMapping(SDLK_LEFT, HID::Keys::Left); 17 | mappings.setMapping(SDLK_RETURN, HID::Keys::Start); 18 | mappings.setMapping(SDLK_BACKSPACE, HID::Keys::Select); 19 | mappings.setMapping(SDLK_w, HID::Keys::CirclePadUp); 20 | mappings.setMapping(SDLK_s, HID::Keys::CirclePadDown); 21 | mappings.setMapping(SDLK_d, HID::Keys::CirclePadRight); 22 | mappings.setMapping(SDLK_a, HID::Keys::CirclePadLeft); 23 | 24 | return mappings; 25 | } -------------------------------------------------------------------------------- /src/pandios/.gitignore: -------------------------------------------------------------------------------- 1 | libAlber.dylib 2 | Alber/Headers/ios_driver.h -------------------------------------------------------------------------------- /src/pandios/Alber/Headers/ios_driver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | void iosCreateEmulator(); 6 | void iosLoadROM(NSString* pathNS); 7 | void iosRunFrame(CAMetalLayer* layer); -------------------------------------------------------------------------------- /src/pandios/Alber/module.map: -------------------------------------------------------------------------------- 1 | module AlberDriver { 2 | umbrella "Headers" // for multiple files 3 | link "libAlber" 4 | export * 5 | } -------------------------------------------------------------------------------- /src/pandios/Pandios.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/pandios/Pandios.xcodeproj/project.xcworkspace/xcuserdata/giorgos.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/src/pandios/Pandios.xcodeproj/project.xcworkspace/xcuserdata/giorgos.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /src/pandios/Pandios.xcodeproj/xcuserdata/giorgos.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Pandios.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/pandios/Pandios/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/pandios/Pandios/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "platform" : "ios", 6 | "size" : "1024x1024" 7 | }, 8 | { 9 | "appearances" : [ 10 | { 11 | "appearance" : "luminosity", 12 | "value" : "dark" 13 | } 14 | ], 15 | "idiom" : "universal", 16 | "platform" : "ios", 17 | "size" : "1024x1024" 18 | }, 19 | { 20 | "appearances" : [ 21 | { 22 | "appearance" : "luminosity", 23 | "value" : "tinted" 24 | } 25 | ], 26 | "idiom" : "universal", 27 | "platform" : "ios", 28 | "size" : "1024x1024" 29 | } 30 | ], 31 | "info" : { 32 | "author" : "xcode", 33 | "version" : 1 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/pandios/Pandios/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/pandios/Pandios/PandiosApp.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | @main 4 | struct PandiosApp: App { 5 | var body: some Scene { 6 | WindowGroup { 7 | ContentView() 8 | DocumentView() 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/pandios/Pandios/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/pandroid/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | .cxx 15 | local.properties 16 | -------------------------------------------------------------------------------- /src/pandroid/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Pandroid Proguard Rules 2 | # For more details, see 3 | # http://developer.android.com/guide/developing/tools/proguard.html 4 | 5 | # Keep all JNI and C++ related classes and methods 6 | -keepclasseswithmembernames class * { 7 | native ; 8 | } 9 | 10 | # Keep all native libraries and their methods 11 | -keep class * { 12 | native ; 13 | } 14 | 15 | # Keep all classes in the specified package and its subpackages 16 | -keep class com.panda3ds.pandroid.** {*;} 17 | 18 | # Uncomment this to preserve the line number information for 19 | # debugging stack traces. 20 | #-keepattributes SourceFile,LineNumberTable 21 | 22 | # If you keep the line number information, uncomment this to 23 | # hide the original source file name. 24 | #-renamesourcefileattribute SourceFile 25 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/assets/fonts/comic_mono.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/src/pandroid/app/src/main/assets/fonts/comic_mono.ttf -------------------------------------------------------------------------------- /src/pandroid/app/src/main/ic_launcher-playstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/src/pandroid/app/src/main/ic_launcher-playstore.png -------------------------------------------------------------------------------- /src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/BaseActivity.java: -------------------------------------------------------------------------------- 1 | package com.panda3ds.pandroid.app; 2 | 3 | import android.os.Bundle; 4 | 5 | import androidx.annotation.Nullable; 6 | import androidx.appcompat.app.AppCompatActivity; 7 | 8 | import com.google.android.material.color.DynamicColors; 9 | import com.panda3ds.pandroid.data.config.GlobalConfig; 10 | 11 | 12 | public class BaseActivity extends AppCompatActivity { 13 | private int currentTheme = PandroidApplication.getThemeId(); 14 | 15 | @Override 16 | protected void onCreate(@Nullable Bundle savedInstanceState) { 17 | applyTheme(); 18 | super.onCreate(savedInstanceState); 19 | } 20 | 21 | @Override 22 | protected void onResume() { 23 | super.onResume(); 24 | 25 | if (PandroidApplication.getThemeId() != currentTheme) { 26 | recreate(); 27 | } 28 | } 29 | 30 | private void applyTheme() { 31 | currentTheme = PandroidApplication.getThemeId(); 32 | setTheme(currentTheme); 33 | 34 | if (GlobalConfig.get(GlobalConfig.KEY_APP_THEME) == GlobalConfig.THEME_ANDROID) { 35 | DynamicColors.applyToActivityIfAvailable(this); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/base/BottomDialogFragment.java: -------------------------------------------------------------------------------- 1 | package com.panda3ds.pandroid.app.base; 2 | 3 | import android.app.Dialog; 4 | import android.os.Bundle; 5 | import android.view.Gravity; 6 | 7 | import androidx.annotation.NonNull; 8 | import androidx.annotation.Nullable; 9 | import androidx.fragment.app.DialogFragment; 10 | 11 | import com.panda3ds.pandroid.R; 12 | 13 | public class BottomDialogFragment extends DialogFragment { 14 | @Override 15 | public int getTheme() { 16 | return R.style.AlertDialog; 17 | } 18 | 19 | @NonNull 20 | @Override 21 | public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { 22 | Dialog dialog = super.onCreateDialog(savedInstanceState); 23 | dialog.getWindow().setGravity(Gravity.CENTER | Gravity.BOTTOM); 24 | dialog.getWindow().getAttributes().y = Math.round(getContext().getResources().getDisplayMetrics().density * 15); 25 | 26 | return dialog; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/base/LoadingAlertDialog.java: -------------------------------------------------------------------------------- 1 | package com.panda3ds.pandroid.app.base; 2 | 3 | import android.content.Context; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | 7 | import androidx.annotation.NonNull; 8 | import androidx.annotation.StringRes; 9 | import androidx.appcompat.widget.AppCompatTextView; 10 | 11 | import com.panda3ds.pandroid.R; 12 | 13 | public class LoadingAlertDialog extends BottomAlertDialog { 14 | public LoadingAlertDialog(@NonNull Context context, @StringRes int title) { 15 | super(context); 16 | View view = LayoutInflater.from(context).inflate(R.layout.dialog_loading, null, false); 17 | setView(view); 18 | setCancelable(false); 19 | ((AppCompatTextView)view.findViewById(R.id.title)) 20 | .setText(title); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/java/com/panda3ds/pandroid/app/game/EmulatorCallback.java: -------------------------------------------------------------------------------- 1 | package com.panda3ds.pandroid.app.game; 2 | 3 | import com.panda3ds.pandroid.data.config.GlobalConfig; 4 | 5 | public interface EmulatorCallback { 6 | void onBackPressed(); 7 | void swapScreens(int index); 8 | 9 | default void swapScreens() { 10 | swapScreens(GlobalConfig.get(GlobalConfig.KEY_CURRENT_DS_LAYOUT) + 1); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/java/com/panda3ds/pandroid/data/game/GameRegion.java: -------------------------------------------------------------------------------- 1 | package com.panda3ds.pandroid.data.game; 2 | 3 | import com.panda3ds.pandroid.R; 4 | 5 | public enum GameRegion { 6 | NorthAmerican, 7 | Japan, 8 | Europe, 9 | Australia, 10 | China, 11 | Korean, 12 | Taiwan, 13 | None; 14 | 15 | public int localizedName() { 16 | switch (this) { 17 | case NorthAmerican: 18 | return R.string.region_north_armerican; 19 | case Japan: 20 | return R.string.region_japan; 21 | case Europe: 22 | return R.string.region_europe; 23 | case Australia: 24 | return R.string.region_australia; 25 | case Korean: 26 | return R.string.region_korean; 27 | case Taiwan: 28 | return R.string.region_taiwan; 29 | } 30 | return R.string.unknown; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/java/com/panda3ds/pandroid/input/InputEvent.java: -------------------------------------------------------------------------------- 1 | package com.panda3ds.pandroid.input; 2 | 3 | public class InputEvent { 4 | private final String name; 5 | private final float value; 6 | 7 | public InputEvent(String name, float value) { 8 | this.name = name; 9 | this.value = Math.max(0.0f, Math.min(1.0f, value)); 10 | } 11 | 12 | public boolean isDown() { 13 | return value > 0.0f; 14 | } 15 | 16 | public String getName() { 17 | return name; 18 | } 19 | 20 | public float getValue() { 21 | return value; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/java/com/panda3ds/pandroid/input/KeyName.java: -------------------------------------------------------------------------------- 1 | package com.panda3ds.pandroid.input; 2 | 3 | import com.panda3ds.pandroid.utils.Constants; 4 | 5 | public enum KeyName { 6 | A(Constants.INPUT_KEY_A), 7 | B(Constants.INPUT_KEY_B), 8 | X(Constants.INPUT_KEY_X), 9 | Y(Constants.INPUT_KEY_Y), 10 | UP(Constants.INPUT_KEY_UP), 11 | DOWN(Constants.INPUT_KEY_DOWN), 12 | LEFT(Constants.INPUT_KEY_LEFT), 13 | RIGHT(Constants.INPUT_KEY_RIGHT), 14 | AXIS_LEFT, 15 | AXIS_RIGHT, 16 | AXIS_UP, 17 | AXIS_DOWN, 18 | START(Constants.INPUT_KEY_START), 19 | SELECT(Constants.INPUT_KEY_SELECT), 20 | L(Constants.INPUT_KEY_L), 21 | R(Constants.INPUT_KEY_R), 22 | NULL, 23 | CHANGE_DS_LAYOUT; 24 | 25 | private final int keyId; 26 | 27 | KeyName() { 28 | this(-1); 29 | } 30 | 31 | KeyName(int keyId) { 32 | this.keyId = keyId; 33 | } 34 | 35 | public int getKeyId() { 36 | return keyId; 37 | } 38 | 39 | } -------------------------------------------------------------------------------- /src/pandroid/app/src/main/java/com/panda3ds/pandroid/lang/Function.java: -------------------------------------------------------------------------------- 1 | package com.panda3ds.pandroid.lang; 2 | 3 | public interface Function { 4 | void run(T arg); 5 | } 6 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/java/com/panda3ds/pandroid/lang/PipeStreamTask.java: -------------------------------------------------------------------------------- 1 | package com.panda3ds.pandroid.lang; 2 | 3 | import java.io.InputStream; 4 | import java.io.OutputStream; 5 | 6 | public class PipeStreamTask extends Task { 7 | private final InputStream input; 8 | private final OutputStream output; 9 | private final long limit; 10 | private long size; 11 | 12 | public PipeStreamTask(InputStream input, OutputStream output, long limit) { 13 | this.input = input; 14 | this.output = output; 15 | this.limit = limit; 16 | } 17 | 18 | @Override 19 | public void run() { 20 | super.run(); 21 | int data; 22 | try { 23 | while ((data = input.read()) != -1) { 24 | output.write(data); 25 | if (++size > limit) { 26 | break; 27 | } 28 | } 29 | } catch (Exception e) {} 30 | close(); 31 | } 32 | 33 | public void close() { 34 | try { 35 | output.flush(); 36 | output.close(); 37 | input.close(); 38 | } catch (Exception e) {} 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/java/com/panda3ds/pandroid/lang/Task.java: -------------------------------------------------------------------------------- 1 | package com.panda3ds.pandroid.lang; 2 | 3 | public class Task extends Thread { 4 | public Task(Runnable runnable) { 5 | super(runnable); 6 | } 7 | 8 | protected Task() {} 9 | 10 | public void runSync() { 11 | start(); 12 | waitFinish(); 13 | } 14 | 15 | public void waitFinish() { 16 | try { 17 | join(); 18 | } catch (InterruptedException e) { 19 | throw new RuntimeException(e); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/java/com/panda3ds/pandroid/math/Quaternion.java: -------------------------------------------------------------------------------- 1 | package com.panda3ds.pandroid.math; 2 | 3 | public class Quaternion { 4 | public float x, y, z, w; 5 | public Quaternion(float x, float y, float z, float w) { 6 | this.x = x; 7 | this.y = y; 8 | this.z = z; 9 | this.w = w; 10 | } 11 | 12 | public Quaternion fromEuler(Vector3 euler) { 13 | float x = euler.x; 14 | float y = euler.y; 15 | float z = euler.z; 16 | 17 | double c1 = Math.cos(x / 2.0); 18 | double c2 = Math.cos(y / 2.0); 19 | double c3 = Math.cos(z / 2.0); 20 | 21 | double s1 = Math.sin(x / 2.0); 22 | double s2 = Math.sin(y / 2.0); 23 | double s3 = Math.sin(z / 2.0); 24 | 25 | this.x = (float) (s1 * c2 * c3 + c1 * s2 * s3); 26 | this.y = (float) (c1 * s2 * c3 - s1 * c2 * s3); 27 | this.z = (float) (c1 * c2 * s3 + s1 * s2 * c3); 28 | this.w = (float) (c1 * c2 * c3 - s1 * s2 * s3); 29 | return this; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/java/com/panda3ds/pandroid/math/Vector2.java: -------------------------------------------------------------------------------- 1 | package com.panda3ds.pandroid.math; 2 | 3 | public class Vector2 { 4 | public float x, y; 5 | public Vector2(float x, float y) { 6 | this.x = x; 7 | this.y = y; 8 | } 9 | 10 | public static float distance(float x, float y, float x2, float y2) { return (float) Math.sqrt((x - x2) * (x - x2) + (y - y2) * (y - y2)); } 11 | 12 | public void set(float x, float y) { 13 | this.x = x; 14 | this.y = y; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/java/com/panda3ds/pandroid/math/Vector3.java: -------------------------------------------------------------------------------- 1 | package com.panda3ds.pandroid.math; 2 | 3 | public class Vector3 { 4 | private final Quaternion quaternion = new Quaternion(0, 0, 0, 0); 5 | public float x, y, z; 6 | 7 | public Vector3(float x, float y, float z) { 8 | this.x = x; 9 | this.y = y; 10 | this.z = z; 11 | } 12 | 13 | public Vector3 rotateByEuler(Vector3 euler) { 14 | this.quaternion.fromEuler(euler); 15 | 16 | float x = this.x, y = this.y, z = this.z; 17 | float qx = this.quaternion.x; 18 | float qy = this.quaternion.y; 19 | float qz = this.quaternion.z; 20 | float qw = this.quaternion.w; 21 | 22 | float ix = qw * x + qy * z - qz * y; 23 | float iy = qw * y + qz * x - qx * z; 24 | float iz = qw * z + qx * y - qy * x; 25 | float iw = -qx * x - qy * qz * z; 26 | 27 | this.x = ix * qw + iw * -qx + iy * -qz - iz * -qy; 28 | this.y = iy * qw + iw * -qy + iz * -qx - ix * -qz; 29 | this.z = iz * qw + iw * -qz + ix * -qy - iy * -qx; 30 | return this; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/java/com/panda3ds/pandroid/view/SimpleTextWatcher.java: -------------------------------------------------------------------------------- 1 | package com.panda3ds.pandroid.view; 2 | 3 | import android.text.Editable; 4 | import android.text.TextWatcher; 5 | 6 | public interface SimpleTextWatcher extends TextWatcher { 7 | void onChange(String value); 8 | 9 | @Override 10 | default void onTextChanged(CharSequence s, int start, int before, int count) {} 11 | 12 | @Override 13 | default void beforeTextChanged(CharSequence s, int start, int count, int after) {} 14 | 15 | @Override 16 | default void afterTextChanged(Editable s) { 17 | onChange(s.toString()); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/java/com/panda3ds/pandroid/view/code/syntax/CodeSyntax.java: -------------------------------------------------------------------------------- 1 | package com.panda3ds.pandroid.view.code.syntax; 2 | 3 | public abstract class CodeSyntax { 4 | public abstract void apply(byte[] syntaxBuffer, final CharSequence text); 5 | 6 | // Get syntax highlighting data for a file based on its filename, by looking at the extension 7 | public static CodeSyntax getFromFilename(String name) { 8 | name = name.trim().toLowerCase(); 9 | String[] parts = name.split("\\."); 10 | if (parts.length == 0) 11 | return null; 12 | 13 | // Get syntax based on file extension 14 | switch (parts[parts.length - 1]) { 15 | case "lua": 16 | return new LuaSyntax(); 17 | default: 18 | return null; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/java/com/panda3ds/pandroid/view/code/syntax/PatternUtils.java: -------------------------------------------------------------------------------- 1 | package com.panda3ds.pandroid.view.code.syntax; 2 | 3 | import java.util.regex.Pattern; 4 | 5 | class PatternUtils { 6 | public static Pattern buildGenericKeywords(String... keywords) { 7 | StringBuilder builder = new StringBuilder(); 8 | builder.append("\\b("); 9 | for (int i = 0; i < keywords.length; i++) { 10 | builder.append(keywords[i]); 11 | if (i + 1 != keywords.length) { 12 | builder.append("|"); 13 | } 14 | } 15 | 16 | builder.append(")\\b"); 17 | return Pattern.compile(builder.toString()); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/java/com/panda3ds/pandroid/view/controller/ControllerNode.java: -------------------------------------------------------------------------------- 1 | package com.panda3ds.pandroid.view.controller; 2 | 3 | import android.view.View; 4 | import androidx.annotation.NonNull; 5 | import com.panda3ds.pandroid.math.Vector2; 6 | 7 | public interface ControllerNode { 8 | @NonNull 9 | default Vector2 getPosition() { 10 | View view = (View) this; 11 | 12 | int[] position = new int[2]; 13 | view.getLocationInWindow(position); 14 | return new Vector2(position[0], position[1]); 15 | } 16 | 17 | default boolean isVisible() { return ((View) this).isShown(); } 18 | 19 | @NonNull Vector2 getSize(); 20 | void onTouch(TouchEvent event); 21 | } 22 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/java/com/panda3ds/pandroid/view/controller/TouchEvent.java: -------------------------------------------------------------------------------- 1 | package com.panda3ds.pandroid.view.controller; 2 | 3 | public class TouchEvent { 4 | private final TouchType action; 5 | private final float x, y; 6 | 7 | public float getX() { return x; } 8 | public float getY() { return y; } 9 | public TouchType getAction() { return action; } 10 | 11 | public TouchEvent(float x, float y, TouchType action) { 12 | this.x = x; 13 | this.y = y; 14 | this.action = action; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/java/com/panda3ds/pandroid/view/controller/TouchType.java: -------------------------------------------------------------------------------- 1 | package com.panda3ds.pandroid.view.controller; 2 | 3 | public enum TouchType { 4 | ACTION_DOWN, 5 | ACTION_MOVE, 6 | ACTION_UP 7 | }; -------------------------------------------------------------------------------- /src/pandroid/app/src/main/java/com/panda3ds/pandroid/view/controller/listeners/ButtonStateListener.java: -------------------------------------------------------------------------------- 1 | package com.panda3ds.pandroid.view.controller.listeners; 2 | 3 | import com.panda3ds.pandroid.view.controller.nodes.Button; 4 | 5 | public interface ButtonStateListener { 6 | void onButtonPressedChange(Button button, boolean pressed); 7 | } 8 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/java/com/panda3ds/pandroid/view/controller/listeners/JoystickListener.java: -------------------------------------------------------------------------------- 1 | package com.panda3ds.pandroid.view.controller.listeners; 2 | 3 | import com.panda3ds.pandroid.view.controller.nodes.Joystick; 4 | 5 | public interface JoystickListener { 6 | void onJoystickAxisChange(Joystick joystick, float axisX, float axisY); 7 | } 8 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/java/com/panda3ds/pandroid/view/controller/mapping/ControllerItem.java: -------------------------------------------------------------------------------- 1 | package com.panda3ds.pandroid.view.controller.mapping; 2 | 3 | public enum ControllerItem { 4 | START, 5 | SELECT, 6 | L,R, 7 | GAMEPAD, 8 | DPAD, JOYSTICK 9 | } 10 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/java/com/panda3ds/pandroid/view/controller/mapping/Layout.java: -------------------------------------------------------------------------------- 1 | package com.panda3ds.pandroid.view.controller.mapping; 2 | 3 | 4 | import androidx.annotation.NonNull; 5 | 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | import java.util.Objects; 11 | 12 | public class Layout { 13 | private final Map mapLocations = new HashMap<>(); 14 | 15 | public void setLocation(ControllerItem item, Location location) { 16 | mapLocations.put(item, location); 17 | } 18 | 19 | @NotNull 20 | public Location getLocation(ControllerItem item) { 21 | if (!mapLocations.containsKey(item)) { 22 | setLocation(item, new Location()); 23 | } 24 | return Objects.requireNonNull(mapLocations.get(item)); 25 | } 26 | 27 | @NonNull 28 | @Override 29 | public Layout clone() { 30 | Layout cloned = new Layout(); 31 | for (ControllerItem key : mapLocations.keySet()) { 32 | cloned.setLocation(key, getLocation(key).clone()); 33 | } 34 | return cloned; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/java/com/panda3ds/pandroid/view/controller/nodes/BasicControllerNode.java: -------------------------------------------------------------------------------- 1 | package com.panda3ds.pandroid.view.controller.nodes; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import androidx.annotation.NonNull; 6 | import androidx.annotation.Nullable; 7 | import androidx.appcompat.widget.AppCompatTextView; 8 | import com.panda3ds.pandroid.view.controller.ControllerNode; 9 | 10 | public abstract class BasicControllerNode extends AppCompatTextView implements ControllerNode { 11 | public BasicControllerNode(@NonNull Context context) { super(context); } 12 | public BasicControllerNode(@NonNull Context context, @Nullable AttributeSet attrs) { super(context, attrs); } 13 | public BasicControllerNode(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } 14 | } 15 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/java/com/panda3ds/pandroid/view/ds/Mode.java: -------------------------------------------------------------------------------- 1 | package com.panda3ds.pandroid.view.ds; 2 | 3 | enum Mode { 4 | SINGLE, 5 | RELATIVE, 6 | ABSOLUTE 7 | } 8 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/java/com/panda3ds/pandroid/view/ds/Model.java: -------------------------------------------------------------------------------- 1 | package com.panda3ds.pandroid.view.ds; 2 | 3 | import android.util.Log; 4 | import android.view.Gravity; 5 | 6 | import androidx.annotation.NonNull; 7 | 8 | import com.panda3ds.pandroid.utils.Constants; 9 | 10 | class Model implements Cloneable { 11 | public Mode mode = Mode.RELATIVE; 12 | public final Bounds preferredTop = new Bounds(); 13 | public final Bounds preferredBottom = new Bounds(); 14 | public boolean reverse = false; 15 | public boolean onlyTop = true; 16 | public float space = 0.6f; 17 | public int gravity = Gravity.CENTER; 18 | public boolean lockAspect = true; 19 | 20 | @NonNull 21 | @Override 22 | public Model clone() { 23 | try { 24 | return (Model) super.clone(); 25 | } catch (Exception e) { 26 | Log.e(Constants.LOG_TAG, "Error on clone DsModel!", e); 27 | return new Model(); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/java/com/panda3ds/pandroid/view/gamesgrid/ItemHolder.java: -------------------------------------------------------------------------------- 1 | package com.panda3ds.pandroid.view.gamesgrid; 2 | 3 | import android.view.View; 4 | 5 | import androidx.annotation.NonNull; 6 | import androidx.appcompat.widget.AppCompatTextView; 7 | import androidx.recyclerview.widget.RecyclerView; 8 | import com.panda3ds.pandroid.R; 9 | import com.panda3ds.pandroid.data.game.GameMetadata; 10 | 11 | class ItemHolder extends RecyclerView.ViewHolder { 12 | public ItemHolder(@NonNull View itemView) { 13 | super(itemView); 14 | } 15 | 16 | public void apply(GameMetadata game) { 17 | ((AppCompatTextView) itemView.findViewById(R.id.title)) 18 | .setText(game.getTitle()); 19 | ((GameIconView) itemView.findViewById(R.id.icon)) 20 | .setImageBitmap(game.getIcon()); 21 | ((AppCompatTextView) itemView.findViewById(R.id.description)) 22 | .setText(game.getPublisher()); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/java/com/panda3ds/pandroid/view/renderer/ConsoleRenderer.java: -------------------------------------------------------------------------------- 1 | package com.panda3ds.pandroid.view.renderer; 2 | 3 | import com.panda3ds.pandroid.view.renderer.layout.ConsoleLayout; 4 | 5 | public interface ConsoleRenderer { 6 | void setLayout(ConsoleLayout layout); 7 | ConsoleLayout getLayout(); 8 | String getBackendName(); 9 | } 10 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/java/com/panda3ds/pandroid/view/renderer/layout/ConsoleLayout.java: -------------------------------------------------------------------------------- 1 | package com.panda3ds.pandroid.view.renderer.layout; 2 | 3 | import android.graphics.Rect; 4 | 5 | public interface ConsoleLayout { 6 | void update(int screenWidth, int screenHeight); 7 | 8 | void setBottomDisplaySourceSize(int width, int height); 9 | void setTopDisplaySourceSize(int width, int height); 10 | 11 | Rect getBottomDisplayBounds(); 12 | Rect getTopDisplayBounds(); 13 | } 14 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/jniLibs/.gitignore: -------------------------------------------------------------------------------- 1 | # Prebuilt Alber libraries will be placed in this directory, but we don't want to push them to the repo 2 | libAlber.so -------------------------------------------------------------------------------- /src/pandroid/app/src/main/jniLibs/arm64-v8a/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/src/pandroid/app/src/main/jniLibs/arm64-v8a/.gitkeep -------------------------------------------------------------------------------- /src/pandroid/app/src/main/jniLibs/x86_64/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/src/pandroid/app/src/main/jniLibs/x86_64/.gitkeep -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/color/bottom_navigation_indicator_tint.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/color/red_color.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/color/text_secondary_dark.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/color/text_secondary_light.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/drawable/alert_dialog_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/drawable/color_surface.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/drawable/ds_editor_popup_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/drawable/ic_add.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/drawable/ic_align_center.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/drawable/ic_arrow_down.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/drawable/ic_arrow_up.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/drawable/ic_code.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/drawable/ic_compare_arrow.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/drawable/ic_delete.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/drawable/ic_done.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/drawable/ic_edit.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/drawable/ic_exit.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/drawable/ic_folder.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/drawable/ic_key_a.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/drawable/ic_keyboard_hide.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/drawable/ic_play.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/drawable/ic_rotate_screen.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/drawable/ic_save.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/drawable/ic_search.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/drawable/ic_shortcut.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/drawable/ic_switch_screen.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/drawable/ic_tab.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/drawable/ic_theme.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/drawable/ic_videogame.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/drawable/ic_visibility.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/drawable/medium_card_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/drawable/rounded_selectable_item_background.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/drawable/screen_gamepad_checkbox.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/drawable/screen_gamepad_hide.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/drawable/screen_gamepad_show.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/drawable/search_bar_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/drawable/simple_card_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/layout/activity_input_map.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 15 | 16 | 23 | 24 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/layout/activity_preference.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 14 | 15 | 19 | 20 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/layout/controller_joystick.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/layout/controller_l.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/layout/controller_r.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/layout/controller_select.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/layout/controller_start.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/layout/dialog_select_theme.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 14 | 15 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/layout/drawer_game_container.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 11 | 12 | 16 | 17 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/layout/ds_editor_spinner_label.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/layout/fragment_games.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 13 | 14 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/layout/material_switch_widget.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/menu/main_activity_navigation.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 11 | 16 | 17 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/mipmap-hdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/src/pandroid/app/src/main/res/mipmap-hdpi/ic_launcher.webp -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/src/pandroid/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/src/pandroid/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/mipmap-mdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/src/pandroid/app/src/main/res/mipmap-mdpi/ic_launcher.webp -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/src/pandroid/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/src/pandroid/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/mipmap-xhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/src/pandroid/app/src/main/res/mipmap-xhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/src/pandroid/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/src/pandroid/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/src/pandroid/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/src/pandroid/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/src/pandroid/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/src/pandroid/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/src/pandroid/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheremyfoodat/Panda3DS/5591606177d7d595e19a18b3fdd33b8ffbbc1449/src/pandroid/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /src/pandroid/app/src/main/res/values-v27/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 15 | 6 |