From e7470bdfacb15d6c94dde73b90aad499c20fb450 Mon Sep 17 00:00:00 2001 From: scawful Date: Sun, 1 Jan 2023 17:52:09 -0600 Subject: [PATCH] backend-infra-engineer: Pre-0.2.2 snapshot (2022) --- .github/workflows/cmake.yml | 41 + .gitignore | 19 + .gitmodules | 31 +- CMakeLists.txt | 81 + LICENSE | 15 + README.md | 38 + assets/asm/alttp-hacker-workspace | 1 + assets/asm/mosaic_change.asm | 32 + assets/asm/template_song.asm | 160 ++ assets/font/Cousine-Regular.ttf | Bin 0 -> 43912 bytes assets/font/DroidSans.ttf | Bin 0 -> 190044 bytes assets/font/Karla-Regular.ttf | Bin 0 -> 16848 bytes assets/font/MaterialIcons-Regular.ttf | Bin 0 -> 345516 bytes assets/font/Roboto-Medium.ttf | Bin 0 -> 162588 bytes cmake/absl.cmake | 19 + cmake/asar.cmake | 33 + cmake/imgui.cmake | 35 + cmake/openssl.cmake | 5 + docs/changelog.md | 26 + docs/dev-setup-windows.md | 17 + docs/manual/manual.pdf | Bin 0 -> 83447 bytes docs/manual/manual.tex | 40 + src/CMakeLists.txt | 183 +++ src/Library/imgui | 1 - src/app/core/common.cc | 63 + src/app/core/common.h | 21 + src/app/core/constants.h | 1604 ++++++++++++++++++ src/app/core/controller.cc | 229 +++ src/app/core/controller.h | 57 + src/app/delta/CMakeLists.txt | 32 + src/app/delta/client.cc | 54 + src/app/delta/client.h | 44 + src/app/delta/delta.cc | 32 + src/app/delta/delta.proto | 105 ++ src/app/delta/service.cc | 87 + src/app/delta/service.h | 48 + src/app/delta/viewer.cc | 229 +++ src/app/delta/viewer.h | 45 + src/app/editor/assembly_editor.cc | 115 ++ src/app/editor/assembly_editor.h | 38 + src/app/editor/dungeon_editor.cc | 61 + src/app/editor/dungeon_editor.h | 26 + src/app/editor/master_editor.cc | 322 ++++ src/app/editor/master_editor.h | 72 + src/app/editor/music_editor.cc | 292 ++++ src/app/editor/music_editor.h | 86 + src/app/editor/overworld_editor.cc | 352 ++++ src/app/editor/overworld_editor.h | 118 ++ src/app/editor/palette_editor.cc | 128 ++ src/app/editor/palette_editor.h | 42 + src/app/editor/screen_editor.cc | 201 +++ src/app/editor/screen_editor.h | 60 + src/app/gfx/bitmap.cc | 135 ++ src/app/gfx/bitmap.h | 87 + src/app/gfx/snes_palette.cc | 197 +++ src/app/gfx/snes_palette.h | 117 ++ src/app/gfx/snes_tile.cc | 29 + src/app/gfx/snes_tile.h | 94 ++ src/app/rom.cc | 851 ++++++++++ src/app/rom.h | 157 ++ src/app/spc700/spc700.def | 26 + src/app/yaze.cc | 31 + src/app/zelda3/inventory.cc | 89 + src/app/zelda3/inventory.h | 47 + src/app/zelda3/overworld.cc | 384 +++++ src/app/zelda3/overworld.h | 136 ++ src/app/zelda3/overworld_map.cc | 546 ++++++ src/app/zelda3/overworld_map.h | 81 + src/app/zelda3/sprite.cc | 921 +++++++++++ src/app/zelda3/sprite.h | 68 + src/app/zelda3/title_screen.cc | 129 ++ src/app/zelda3/title_screen.h | 81 + src/gui/canvas.cc | 199 +++ src/gui/canvas.h | 67 + src/gui/color.cc | 84 + src/gui/color.h | 20 + src/gui/icons.h | 2192 +++++++++++++++++++++++++ src/gui/input.cc | 70 + src/gui/input.h | 29 + src/gui/style.cc | 108 ++ src/gui/style.h | 15 + src/gui/widgets.cc | 68 + src/gui/widgets.h | 19 + src/lib/ImGuiColorTextEdit | 1 + src/lib/ImGuiFileDialog | 1 + src/lib/SDL | 1 + src/lib/SDL_mixer | 1 + src/lib/abseil-cpp | 1 + src/lib/asar | 1 + src/lib/imgui | 1 + src/lib/imgui_memory_editor.h | 742 +++++++++ src/lib/snes_spc | 1 + src/lib/sneshacking | 1 + src/yaze.ico | Bin 0 -> 318 bytes src/yaze.rc | 1 + src/yaze.res | Bin 0 -> 606 bytes test/CMakeLists.txt | 49 + test/asm_test.cc | 67 + test/delta_test.cc | 74 + test/rom_test.cc | 315 ++++ test/yaze_test.cc | 14 + 101 files changed, 13685 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/cmake.yml create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 LICENSE create mode 100644 README.md create mode 160000 assets/asm/alttp-hacker-workspace create mode 100644 assets/asm/mosaic_change.asm create mode 100644 assets/asm/template_song.asm create mode 100644 assets/font/Cousine-Regular.ttf create mode 100644 assets/font/DroidSans.ttf create mode 100644 assets/font/Karla-Regular.ttf create mode 100644 assets/font/MaterialIcons-Regular.ttf create mode 100644 assets/font/Roboto-Medium.ttf create mode 100644 cmake/absl.cmake create mode 100644 cmake/asar.cmake create mode 100644 cmake/imgui.cmake create mode 100644 cmake/openssl.cmake create mode 100644 docs/changelog.md create mode 100644 docs/dev-setup-windows.md create mode 100644 docs/manual/manual.pdf create mode 100644 docs/manual/manual.tex create mode 100644 src/CMakeLists.txt delete mode 160000 src/Library/imgui create mode 100644 src/app/core/common.cc create mode 100644 src/app/core/common.h create mode 100644 src/app/core/constants.h create mode 100644 src/app/core/controller.cc create mode 100644 src/app/core/controller.h create mode 100644 src/app/delta/CMakeLists.txt create mode 100644 src/app/delta/client.cc create mode 100644 src/app/delta/client.h create mode 100644 src/app/delta/delta.cc create mode 100644 src/app/delta/delta.proto create mode 100644 src/app/delta/service.cc create mode 100644 src/app/delta/service.h create mode 100644 src/app/delta/viewer.cc create mode 100644 src/app/delta/viewer.h create mode 100644 src/app/editor/assembly_editor.cc create mode 100644 src/app/editor/assembly_editor.h create mode 100644 src/app/editor/dungeon_editor.cc create mode 100644 src/app/editor/dungeon_editor.h create mode 100644 src/app/editor/master_editor.cc create mode 100644 src/app/editor/master_editor.h create mode 100644 src/app/editor/music_editor.cc create mode 100644 src/app/editor/music_editor.h create mode 100644 src/app/editor/overworld_editor.cc create mode 100644 src/app/editor/overworld_editor.h create mode 100644 src/app/editor/palette_editor.cc create mode 100644 src/app/editor/palette_editor.h create mode 100644 src/app/editor/screen_editor.cc create mode 100644 src/app/editor/screen_editor.h create mode 100644 src/app/gfx/bitmap.cc create mode 100644 src/app/gfx/bitmap.h create mode 100644 src/app/gfx/snes_palette.cc create mode 100644 src/app/gfx/snes_palette.h create mode 100644 src/app/gfx/snes_tile.cc create mode 100644 src/app/gfx/snes_tile.h create mode 100644 src/app/rom.cc create mode 100644 src/app/rom.h create mode 100644 src/app/spc700/spc700.def create mode 100644 src/app/yaze.cc create mode 100644 src/app/zelda3/inventory.cc create mode 100644 src/app/zelda3/inventory.h create mode 100644 src/app/zelda3/overworld.cc create mode 100644 src/app/zelda3/overworld.h create mode 100644 src/app/zelda3/overworld_map.cc create mode 100644 src/app/zelda3/overworld_map.h create mode 100644 src/app/zelda3/sprite.cc create mode 100644 src/app/zelda3/sprite.h create mode 100644 src/app/zelda3/title_screen.cc create mode 100644 src/app/zelda3/title_screen.h create mode 100644 src/gui/canvas.cc create mode 100644 src/gui/canvas.h create mode 100644 src/gui/color.cc create mode 100644 src/gui/color.h create mode 100644 src/gui/icons.h create mode 100644 src/gui/input.cc create mode 100644 src/gui/input.h create mode 100644 src/gui/style.cc create mode 100644 src/gui/style.h create mode 100644 src/gui/widgets.cc create mode 100644 src/gui/widgets.h create mode 160000 src/lib/ImGuiColorTextEdit create mode 160000 src/lib/ImGuiFileDialog create mode 160000 src/lib/SDL create mode 160000 src/lib/SDL_mixer create mode 160000 src/lib/abseil-cpp create mode 160000 src/lib/asar create mode 160000 src/lib/imgui create mode 100644 src/lib/imgui_memory_editor.h create mode 160000 src/lib/snes_spc create mode 160000 src/lib/sneshacking create mode 100644 src/yaze.ico create mode 100644 src/yaze.rc create mode 100644 src/yaze.res create mode 100644 test/CMakeLists.txt create mode 100644 test/asm_test.cc create mode 100644 test/delta_test.cc create mode 100644 test/rom_test.cc create mode 100644 test/yaze_test.cc diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml new file mode 100644 index 00000000..2d0431d7 --- /dev/null +++ b/.github/workflows/cmake.yml @@ -0,0 +1,41 @@ +name: CMake + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + +env: + # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) + BUILD_TYPE: Debug + +jobs: + build: + # The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac. + # You can convert this to a matrix build if you need cross-platform coverage. + # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + with: + submodules: recursive + + - name: Install Video Libs + run: sudo apt install libglew-dev + + - name: Configure CMake + # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. + # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type + run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} + + - name: Build + # Build your program with the given configuration + run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} + + - name: Test + working-directory: ${{github.workspace}}/build + # Execute tests defined by the CMake configuration. + # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail + run: ${{github.workspace}}/build/bin/yaze_test diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..a22892fc --- /dev/null +++ b/.gitignore @@ -0,0 +1,19 @@ +build/ +.cache/ +.vscode/ +src/lib/SDL2 +src/lib/cmake +src/lib/GL +src/lib/abseil-cpp +src/lib/libGLEW.2.2.0.dylib +src/lib/libGLEW.2.2.dylib +src/lib/libGLEW.a +src/lib/libGLEW.dylib +src/lib/libSDL2_test.a +src/lib/libSDL2-2.0.0.dylib +src/lib/libSDL2.a +src/lib/libSDL2.dylib +src/lib/libSDL2main.a +checks.json +assets/lib/libasar.dll +cmake/yaze.plist.in diff --git a/.gitmodules b/.gitmodules index 4299d8d3..f610c45d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,30 @@ -[submodule "src/Library/imgui"] - path = src/Library/imgui +[submodule "src/lib/imgui"] + path = src/lib/imgui url = https://github.com/ocornut/imgui.git +[submodule "src/lib/ImGuiFileDialog"] + path = src/lib/ImGuiFileDialog + url = https://github.com/aiekick/ImGuiFileDialog.git +[submodule "src/lib/ImGuiColorTextEdit"] + path = src/lib/ImGuiColorTextEdit + url = https://github.com/BalazsJako/ImGuiColorTextEdit.git +[submodule "src/lib/sneshacking"] + path = src/lib/sneshacking + url = https://github.com/Skarsnik/sneshacking.git +[submodule "assets/asm/alttp-hacker-workspace"] + path = assets/asm/alttp-hacker-workspace + url = https://github.com/scawful/alttp-hacker-workspace.git +[submodule "src/lib/abseil-cpp"] + path = src/lib/abseil-cpp + url = https://github.com/abseil/abseil-cpp.git +[submodule "src/lib/SDL"] + path = src/lib/SDL + url = https://github.com/libsdl-org/SDL.git +[submodule "src/lib/asar"] + path = src/lib/asar + url = https://github.com/RPGHacker/asar.git +[submodule "src/lib/snes_spc"] + path = src/lib/snes_spc + url = https://github.com/blarggs-audio-libraries/snes_spc.git +[submodule "src/lib/SDL_mixer"] + path = src/lib/SDL_mixer + url = https://github.com/libsdl-org/SDL_mixer.git diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..1d4fa03c --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,81 @@ +# CMake Specifications -------------------------------------------------------- +cmake_minimum_required(VERSION 3.10) + +# Yet Another Zelda3 Editor +# by scawful +project(yaze VERSION 0.01) + +# C++ Standard Specifications ------------------------------------------------- +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS ON) +set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) +set(CMAKE_POSITION_INDEPENDENT_CODE ON) +set(CMAKE_MODULE_LINKER_FLAGS \"-Wl,--no-undefined -Wl,--no-undefined\") +set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) +set(BUILD_SHARED_LIBS ON) + +# Abseil Standard Specifications ---------------------------------------------- +include(cmake/absl.cmake) +add_subdirectory(src/lib/abseil-cpp) + +include(cmake/openssl.cmake) +set(Protobuf_PROTOC_EXECUTABLE "/Users/scawful/code/protobuf/bin/protoc") +set(Protobuf_INCLUDE_DIRS "/Users/scawful/code/protobuf/include/") +set(PROTOBUF_INCLUDE_PATH ${CMAKE_CURRENT_BINARY_DIR} + CACHE INTERNAL "Path to generated protobuf files.") +include_directories(${PROTOBUF_INCLUDE_PATH}) + +# Video Libraries ------------------------------------------------------------- +find_package(PNG REQUIRED) +find_package(OpenGL REQUIRED) +find_package(GLEW REQUIRED) + +# SDL2 ------------------------------------------------------------------------ +if (UNIX) + add_subdirectory(src/lib/SDL) +else() + find_package(SDL2) +endif() +set(SDL2MIXER_OPUS OFF) +set(SDL2MIXER_FLAC OFF) +set(SDL2MIXER_MOD OFF) +set(SDL2MIXER_MIDI_FLUIDSYNTH OFF) +find_library(SDL_MIXER_LIBRARY + NAMES SDL_mixer + HINTS + ENV SDLMIXERDIR + ENV SDLDIR + PATH_SUFFIXES lib ${VC_LIB_PATH_SUFFIX} + ) +add_subdirectory(src/lib/SDL_mixer) + +# Asar ------------------------------------------------------------------------ +add_subdirectory(src/lib/asar/src) +include(cmake/asar.cmake) + +# snes-spc -------------------------------------------------------------------- +ADD_DEFINITIONS(-DSNES_SPC_EXPORTS) +set(SNES_SPC_SOURCES + "../src/lib/snes_spc/snes_spc/spc.cpp" + "../src/lib/snes_spc/snes_spc/SNES_SPC.cpp" + "../src/lib/snes_spc/snes_spc/SNES_SPC_misc.cpp" + "../src/lib/snes_spc/snes_spc/SNES_SPC_state.cpp" + "../src/lib/snes_spc/snes_spc/SPC_DSP.cpp" + "../src/lib/snes_spc/snes_spc/dsp.cpp" + "../src/lib/snes_spc/snes_spc/SPC_Filter.cpp" + "../src/lib/snes_spc/demo/wave_writer.c" + "../src/lib/snes_spc/demo/demo_util.c" +) +include_directories(src/lib/snes_spc/snes_spc) +ADD_LIBRARY(snes_spc STATIC ${SNES_SPC_SOURCES} src/app/spc700/spc700.def) + +# ImGui ----------------------------------------------------------------------- +include(cmake/imgui.cmake) + +# Project Files +add_subdirectory(src) +add_subdirectory(test) \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..9a09e586 --- /dev/null +++ b/LICENSE @@ -0,0 +1,15 @@ +Copyright (C) 2022 Justin Scofield + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + diff --git a/README.md b/README.md new file mode 100644 index 00000000..b0c941af --- /dev/null +++ b/README.md @@ -0,0 +1,38 @@ +# Yet Another Zelda3 Editor + +- Platform: Windows, macOS, GNU/Linux +- Dependencies: SDL2, ImGui + +## Description + +General purpose editor for The Legend of Zelda: A Link to the Past for the Super Nintendo. + +Takes heavy inspiration from ALTTP community efforts such as [Hyrule Magic](https://www.romhacking.net/utilities/200/) and [ZScream](https://github.com/Zarby89/ZScreamDungeon) + +Building and installation +------------------------- +[CMake](http://www.cmake.org "CMake") is required to build yaze + +1. Clone the repository + + git clone --recurse-submodules https://github.com/scawful/yaze.git + +2. Create the build directory and configuration + + cmake -S . -B build + +3. Build and run. + + cmake --build build + +License +-------- +YAZE is distributed under the [GNU GPLv3](https://www.gnu.org/licenses/gpl-3.0.txt) license. + +SDL2, ImGUI and Abseil are subject to respective licenses. + +Screenshots +-------- +![image](https://user-images.githubusercontent.com/47263509/194669806-2b0da68d-9d38-4f52-bcce-c60ee861092c.png) + + diff --git a/assets/asm/alttp-hacker-workspace b/assets/asm/alttp-hacker-workspace new file mode 160000 index 00000000..ea81eb34 --- /dev/null +++ b/assets/asm/alttp-hacker-workspace @@ -0,0 +1 @@ +Subproject commit ea81eb34251c4e77703791f710f5b60a8a063d21 diff --git a/assets/asm/mosaic_change.asm b/assets/asm/mosaic_change.asm new file mode 100644 index 00000000..d4b08b9f --- /dev/null +++ b/assets/asm/mosaic_change.asm @@ -0,0 +1,32 @@ + +org + JML AreaCheck + +org + +AreaCheck: + PHB : PHK : PLB + + TAX + LDA .pool, X + + BEQ .noMosaic1 + PLB + JML $02AAE5 + + .noMosaic1 + + LDX $8A + LDA .pool, X + + BEQ .noMosaic2 + PLB + JML $02AAE5 + + .noMosaic2 + + PLB + JML $02AAF4 + + NOP + .pool diff --git a/assets/asm/template_song.asm b/assets/asm/template_song.asm new file mode 100644 index 00000000..01c33d20 --- /dev/null +++ b/assets/asm/template_song.asm @@ -0,0 +1,160 @@ +; +; Credit to Zarby89 +; +lorom + +!End = $00 +!Rest = $C9 +!Tie = $C8 + +macro SetChannelVolume(v) +db $ED, +endmacro + +macro SetMasterVolume(v) +db $E5, +endmacro + +macro SetTempo(v) +db $E7, +endmacro + +macro SetInstrument(v) +db $E0, +endmacro + +macro CallSubroutine(addr, repeat) +db $EF +dw +db +endmacro + +;1/4 = $48 +;1/4 double = $6C +;1/4 triplet = $30 +;1/8 = $24 +;1/8 double = $36 +;1/8 triplet = $18 +;1/16 = $12 +;1/16 double = $1B +;1/32 = $09 +; To make a whole note you tie 4 1/4 so something like +;%SetDuration(48) +;db !C4, !Tie, !Tie, !Tie ; will play a whole note (1/1) +;db !C4, !Tie ; will play a half note (1/2) + +macro SetDuration(v) +db , $7F +endmacro + + +!C1 = $80 +!C1s = $81 +!D1 = $82 +!D1s = $83 +!E1 = $84 +!F1 = $85 +!F1s = $86 +!G1 = $87 +!G1s = $88 +!A1 = $89 +!A1s = $8A +!B1 = $8B + + +!C2 = $8C +!C2s = $8D +!D2 = $8E +!D2s = $8F +!E2 = $90 +!F2 = $91 +!F2s = $92 +!G2 = $93 +!G2s = $94 +!A2 = $95 +!A2s = $96 +!B2 = $97 + + +!C3 = $98 +!C3s = $99 +!D3 = $9A +!D3s = $9B +!E3 = $9C +!F3 = $9D +!F3s = $9E +!G3 = $9F +!G3s = $A0 +!A3 = $A1 +!A3s = $A2 +!B3 = $A3 + +!C4 = $A4 +!C4s = $A5 +!D4 = $A6 +!D4s = $A7 +!E4 = $A8 +!F4 = $A9 +!F4s = $AA +!G4 = $AB +!G4s = $AC +!A4 = $AD +!A4s = $AE +!B4 = $AF + +!C5 = $B0 +!C5s = $B1 +!D5 = $B2 +!D5s = $B3 +!E5 = $B4 +!F5 = $B5 +!F5s = $B6 +!G5 = $B7 +!G5s = $B8 +!A5 = $B9 +!A5s = $BA +!B5 = $BB + +!C6 = $BC +!C6s = $BD +!D6 = $BE +!D6s = $BF +!E6 = $C0 +!F6 = $C1 +!F6s = $C2 +!G6 = $C3 +!G6s = $C4 +!A6 = $C5 +!A6s = $C6 +!B6 = $C7 + +org $1A9FF8 ; Hyrule Castle (Song Header information) +Sections: +!ARAMAddr = $D0FF +!StartingAddr = Sections +dw !ARAMAddr+$0A +dw !ARAMAddr+$0A +dw $00FF +dw !ARAMAddr +dw $0000 + +Channels: +!ARAMC = !ARAMAddr-Sections +dw Channel0+!ARAMC +dw $0000 +dw $0000 +dw $0000 +dw $0000 +dw $0000 +dw $0000 +dw $0000 + + +Channel0: +SetMasterVolume($80) +SetTempo($40) +SetInstrument($17) + +db !Rest, !Rest, !Rest + +db !End \ No newline at end of file diff --git a/assets/font/Cousine-Regular.ttf b/assets/font/Cousine-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..70a0bf902e1482724d7706f7a0f40d94fe51f4c3 GIT binary patch literal 43912 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 VEBwqml;Z2NCo|~pwK literal 0 HcmV?d00001 diff --git a/assets/font/DroidSans.ttf b/assets/font/DroidSans.ttf new file mode 100644 index 0000000000000000000000000000000000000000..767c63ad000e3eea20f3cb7a43ba9f4154ed7a5d GIT binary patch literal 190044 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%0D=-PBu&{ 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

~iKf3UaBNr~`)8hO)GQ-C8x^C1U^Kxn! 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 I_VuJ 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 literal 0 HcmV?d00001 diff --git a/assets/font/Roboto-Medium.ttf b/assets/font/Roboto-Medium.ttf new file mode 100644 index 0000000000000000000000000000000000000000..39c63d7461796094c0b8889ee8fe2706d344a99a GIT binary patch literal 162588 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 cASb?` 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

  • 2a-ytx-(Y1%*Q`;e(V?9Smc22g?_xG~I&%zq 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≀A#j z3En4hd#s$US74J{FZyyB`#_Q2U1F?42f@E6Md#-|I@mu*ya#KDzKk`-xN#cnlecPJ z=0XO3hS!&*a3=GH5a_@Tqu$JAU9XHCh^X(ElK+_Gl*}E7i0uxQ^mE{Q#!frn6OD&H z=O&-c+-ZmO2Sk2)B;UyF1Czcawdc*NnS11ret_ho?Oum09q;KcWqyy5Xo>d_-|%cB zt%9{Vup6A=;1B_6`-`qs21W~{s)I-^xrp>sN$Fc7ReC15+$rh9B)uoxsucVaQd|j3 z`oZM$o#0=QNjN9mx!$N(mN6X1 zRa312l1eO=p6-`|Kg$`H+=4ZsjkKx*2P;;U5(>~OJ+4odlHM2m_X6!nUzAF}Gx-zg z+J<~8_={8NcM1M0tnIrm&=LG^8@l-v>HL#X@);xP#VPzl^N*7MSITu4%A;3_1@%r7{2$=Dk6ahabt|sVk?ZgEwKExO{lDx0 zAo=~*tB9bE^_gHp4dnAb?usBQXWx)DM?1mRntUj0j$CWy&Cr!~a#H{Aq(1fN_dnN% zHJ{e?LXRbqpXTRHQU>TRWk|0k^sH(pTC7~XiqSNrR#X4suV0cm6?&nWH!oM@TJryE zd3i(rr_L@v>&TBT&+W2eGAZSms=oY_by!}X4D346BDIm+U1|F>>A6<^ukxO5XG)XC z*Sl^6^?GwkS6{m7NE5#KX~|qGVozoj+j|Aw4nKlEuS_b?-5PJzs`MXZr&-;tA()hY zjblNup}hO8TRRC&bvvfus&4Gya!NNsm235nqknQpn|nvMhr6+>>?hq8cGDZpYP5y= zC%t)WL9;I1be~)H7cc1GX36%lnXedQVTN9c!S2_ocQ(pf1$ z__%HIRAX`5nNPkl?CcM$**1)0z5Ap9l;wR?(+aF+dcRz^!zB)yw=z+@9q&RG`*|x9 z>jb7{(+}PIY8ccDQy}f!PZ}<42q8{ss7a-NIAa4GeU`)7+&daR%)8ji387dRpGB+nE={X^!=^PiwsVqngjw8V|+(Sz_1+)HHr@Omg=VPu}}L z6XWr>*Bz7`WPH)Z=(J_XN6s^w7w6raeBtabKD##WPi$qwWdFc4`(5;$-j^Bw*j=5>W4|?T4Xii2Tx^8KN!f_J(*%RasyDkFFDY=I=w7wxR*U4Nb!HE}Ydo5o zJ#=}U*+cKD&)k{T$q{wtL%d6j*qsk?QJwh^?-~dowG;nLT4eeax<%Ih8D}|I6iXR4 zmP+pyl{z=nfn2%iCee#~Q|DGjx}9+zVBY%^DV!kb1*!8aH9&orI&YvFGy3o5*+?D0 zOltSMF|G1Zsq-dk1bc(J=}pxo#>c7iW~#Airp}vl-jwl-JJ_N8J~c+&tZq~{5o_$s zI>w%Ona6T=7XRKs`mJgdSA%#H>~-uS+gY7T%B>tP^6$D!u12Z5z#KyxG)i3$=0)6n zEpRu`nbjXU^=9^Qy^ViHk?&Y?xd!~9a@Sq_cL&eVB{-TgxTQFrs}m$mUmsT|&mQ&i z%zWC-l%+GdcjoD1I9|^)Zj-0oLfReb27WW^cXXYry8m1U{%z3eCZW?^5{rN z)OEg_=jqZ9=D+KB*6l)z>%kezxqkW>&hI7ivRzdBAP#Ub7y~6 zjUA)zk?+yulg{gC$}k4X9s^}F%W)SegW=%m%mq82`2}Y%hr^|ECXX^XWFf_ToY9p1 z&prktgV~HVILN*MLPO>O&Q$imGY4Oy4!rKZF}JGjH;x%~i|TXhHFw`mbOQYm4I*;G zdHTx0yGmb~L|M{T78;g)UEW=Js+ausli!o&ci=6f#@w#X`QtD78&VuXEKP`W~hz}g6j;9yj zm-V~3aN-1YBBQG(!_^zv#cQ^jgVuhk=3-ywsrl-2W*&U6iq(4c13NgCs15AZxQY4J zKd~q07M`_@v9>Z*uC}u?WF<3lBdoSL%IHb#t{=NVo@ktGoMN0|oM}94Ofa4?o;S}l z&oT#@=bD4f^UU+jA?5|q<}>DV<_qRa=0x*V^L5^RJIVZ~ImMi6{>yyN{J@-MPB&+oADeT` zPtDKF`Q{hqSLQe7LUWP1)Ld?UYpycCGuN2w%wqEgbECQ044GTaQnTEwFvDil+-b(l zxS24k%^I`Ty2!fNy2QHF8fp!*F0+PPS6Cygk=B*gRo2zkHP&_3_0}ls2J1%aChKPF zKIf}yNleFyXz+-KDZ&-C4x z)vy27{#*NX?El>HJN4NK&-5AEa7@F!{Z8)JvCn&b?#=CWg6eZbqbvK)>l5l5Z#1>> zs>VO$zMlJf-(UKK`m}Abs$Z9;N9Df6@0oo1@P+r!!pXnSVc!3Ums;NSxvJ#g+pz1mOfIJ|S){#y?||B%w$UR{sY&+oHO z|91VQ+r-?d-SZCbb$H)!J`jvT*Jf8Brdznb#g{fh^E+UhU7(%)3c^s&#qC#Zg1H0Sh} z=WovprOQvLf9bn1ca{EEOGf|a`s~y92yE+7SjJzmWBB(;?9$!a;P<4?f?e^2Ya9*cW67Iz!%Ul|tn5-e_<-J=tHuTiz? zXMB}k)o)nx{fgaO3=^Mkw9&w5pl&m?&vm=e#%QPRVASPcHO4s7=%MbyQukEj^jM3! z#~5S`Qui9SvWoCN;|}9ab-(c?@r{QV4fsYqY%DdFsYi@&i8wrJtYQb9$BZJP3lq%l zW_R_3d4zeSdQw|=^)&WY7rLvIkgxo z{(@S9C4WgR#hSmRmT3#F)?&k_sbcK-bhRE^K2!aGJ^xt!h)tiPO0esnstwro&(ucj z`+T(t8~=scjGg~V{e-PwsY2#zbG6#Rn}CbdPIE2uI(A{{H>()dKBRVI@wcitR=-qL zVfo8d0_$I)s%ZhjY7ebIRMpTD>{NSc4PvU67NJ`0qeZAuznZmXt@@3YVVL@z7U5>Y zv~IO-HCkACR-Vz)8e@$y4zR{q?fLv|cfev|h9F zjULt%>uuv$>mBPIhLqm5-ev#b_pNEh@zxA$wvlTUSOvx@);w#zF@P51YvVLpjTOe} z)+%eYah_FVtuuyL8?24S#a74)8JAjHtqNnPwZqzJjI`o*YvU@rt=-mm%0AHUW;|^l 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 XDz@2YO+x)8BOh4hv GL_GLEXT_PROTOTYPES=1) + +set(IMGUI_FILE_DLG_PATH ${CMAKE_SOURCE_DIR}/src/lib/ImGuiFileDialog) +file(GLOB IMGUI_FILE_DLG_SOURCES ${IMGUI_FILE_DLG_PATH}/*.cpp) +add_library("ImGuiFileDialog" STATIC ${IMGUI_FILE_DLG_SOURCES}) +target_include_directories(ImGuiFileDialog PUBLIC ${IMGUI_PATH}) +target_compile_definitions(ImGuiFileDialog PUBLIC + IMGUI_IMPL_OPENGL_LOADER_CUSTOM= GL_GLEXT_PROTOTYPES=1) + +set(IMGUI_COLOR_TEXT_EDIT_PATH ${CMAKE_SOURCE_DIR}/src/lib/ImGuiColorTextEdit) +file(GLOB IMGUI_COLOR_TEXT_EDIT_SOURCES ${IMGUI_COLOR_TEXT_EDIT_PATH}/*.cpp) +add_library("ImGuiColorTextEdit" STATIC ${IMGUI_COLOR_TEXT_EDIT_SOURCES}) +target_include_directories(ImGuiColorTextEdit PUBLIC ${IMGUI_PATH}) +target_compile_definitions(ImGuiColorTextEdit PUBLIC + IMGUI_IMPL_OPENGL_LOADER_CUSTOM= GL_GLEXT_PROTOTYPES=1) + +set( + IMGUI_SRC + ${IMGUI_PATH}/imgui.cpp + ${IMGUI_PATH}/imgui_demo.cpp + ${IMGUI_PATH}/imgui_draw.cpp + ${IMGUI_PATH}/imgui_widgets.cpp + ${IMGUI_PATH}/backends/imgui_impl_sdl.cpp + ${IMGUI_PATH}/backends/imgui_impl_sdlrenderer.cpp + ${IMGUI_PATH}/misc/cpp/imgui_stdlib.cpp + ${IMGUI_FILE_DLG_PATH}/ImGuiFileDialog.cpp + ${IMGUI_COLOR_TEXT_EDIT_PATH}/TextEditor.cpp +) \ No newline at end of file diff --git a/cmake/openssl.cmake b/cmake/openssl.cmake new file mode 100644 index 00000000..d2da52c0 --- /dev/null +++ b/cmake/openssl.cmake @@ -0,0 +1,5 @@ +if (UNIX) + set(OPENSSL_INCLUDE_DIR "/usr/local/Cellar/openssl@1.1/1.1.1q/include") + set(OPENSSL_CRYPTO_LIBRARY "/usr/local/Cellar/openssl@1.1/1.1.1q/lib/libcrypto.dylib") + set(OPENSSL_SSL_LIBRARY "/usr/local/Cellar/openssl@1.1/1.1.1q/lib/libssl.dylib") +endif() diff --git a/docs/changelog.md b/docs/changelog.md new file mode 100644 index 00000000..5e74e4a0 --- /dev/null +++ b/docs/changelog.md @@ -0,0 +1,26 @@ +## September 2022 + +- Drawing Overworld maps to the screen +- Drawing entrance data on the overworld +- Drawing 2bpp inventory graphics data +- Started the YazeDelta project for version control. + +## August 2022 + +- Added ValidateCompressionResults to ROM::Compress +- Improved Overworld systems in preparation for drawing maps. + +## July 2022 + +- Display current overworld map graphics tile sheets. +- Added CreateAllGraphicsData to the ROM class +- Added Google Abseil C++ library for error handling, string manipulation +- Refactor ROM class to use smart pointers and STL containers + +## June 2022 + +- Implemented LC_LZ2 Decompression +- Created Bitmap class for displaying SNES Graphics +- Added Overworld and OverworldMap class definitions +- Built user interface using ImGui and SDL2 +- Started YAZE \ No newline at end of file diff --git a/docs/dev-setup-windows.md b/docs/dev-setup-windows.md new file mode 100644 index 00000000..8688b3f9 --- /dev/null +++ b/docs/dev-setup-windows.md @@ -0,0 +1,17 @@ + +For VSCode users, use the following CMake extensions with MinGW-w64 + +https://marketplace.visualstudio.com/items?itemName=twxs.cmake +https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools + +https://www.msys2.org/ + +Add to environment variables `C:\msys64\mingw64\bin` + +Install the following packages using `pacman -S ` + +`mingw-w64-x86_64-gcc` +`mingw-w64-x86_64-gcc-libs` +`mingw-w64-x86_64-cmake` +`mingw-w64-x86_64-glew` +`mingw-w64-x86_64-lib-png` \ No newline at end of file diff --git a/docs/manual/manual.pdf b/docs/manual/manual.pdf new file mode 100644 index 0000000000000000000000000000000000000000..974fd6fcc0966e65598a5a9d35b738a94c489e99 GIT binary patch literal 83447 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 U{eCp8479Yg5JW_RQbG{_1Lx#F$^ZZW literal 0 HcmV?d00001 diff --git a/docs/manual/manual.tex b/docs/manual/manual.tex new file mode 100644 index 00000000..4574d023 --- /dev/null +++ b/docs/manual/manual.tex @@ -0,0 +1,40 @@ +\documentclass[12pt, oneside]{report} +\title{Yet Another Zelda3 Editor} +\author{Justin Scofield\thanks{Special thanks to JaredBrian, Zarby89}} +\date{June 2022 - October 2022} +\pagestyle{headings} + +\begin{document} +\maketitle + +\tableofcontents + +\chapter{Introduction} + +{\bf Yet Another Zelda3 Editor} is a multi-purpose editor for the retro video game title {\it {"The Legend of Zelda: A Link to the Past"}} for the Super Nintendo Entertainment System. The editor only supports the US version. + +\section{Getting Started} +\section{Loading from ROM} +\section{Saving to ROM} + +\chapter{Overworld} + + The editor provides an interface for the user to make various changes to the overworld maps. These changes include the manpulation of the maps tiles, palettes, entrances, exits, sprites, area music, and other properties. Here we will explain the basics of the tile system. + + \section{Tile System} + \section{Map Toolset} + \section{Map Canvas} + +\chapter{Dungeons} + +\chapter{Palettes} + +\chapter{Sprites} + +\chapter{Screens} + \section{Inventory} + \section{Heads-up Display} + +\chapter{Modules} + +\end{document} \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 00000000..e3b147ad --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,183 @@ +# yaze source files ----------------------------------------------------------- +set( + YAZE_APP_CORE_SRC + app/core/common.cc + app/core/controller.cc +) + +set( + YAZE_APP_EDITOR_SRC + app/editor/assembly_editor.cc + app/editor/dungeon_editor.cc + app/editor/master_editor.cc + app/editor/music_editor.cc + app/editor/overworld_editor.cc + app/editor/palette_editor.cc + app/editor/screen_editor.cc +) + +set( + YAZE_APP_GFX_SRC + app/gfx/bitmap.cc + app/gfx/snes_palette.cc + app/gfx/snes_tile.cc +) + +set( + YAZE_APP_ZELDA3_SRC + app/zelda3/inventory.cc + app/zelda3/overworld_map.cc + app/zelda3/overworld.cc + app/zelda3/title_screen.cc + app/zelda3/sprite.cc +) + +set( + YAZE_GUI_SRC + gui/canvas.cc + gui/input.cc + gui/style.cc + gui/widgets.cc + gui/color.cc +) + +# executable creation --------------------------------------------------------- + +add_executable( + yaze + app/yaze.cc + app/rom.cc + ${YAZE_APP_CORE_SRC} + ${YAZE_APP_EDITOR_SRC} + ${YAZE_APP_GFX_SRC} + ${YAZE_APP_ZELDA3_SRC} + ${YAZE_GUI_SRC} + ${ASAR_STATIC_SRC} + ${SNES_SPC_SOURCES} + ${IMGUI_SRC} +) + +# including libraries --------------------------------------------------------- + +target_include_directories( + yaze PUBLIC + lib/ + app/ + ${CMAKE_SOURCE_DIR}/src/ + ${PNG_INCLUDE_DIRS} + ${SDL2_INCLUDE_DIR} + lib/SDL_mixer/include/ + ${GLEW_INCLUDE_DIRS} + lib/asar/src/asar/ + lib/snes_spc/snes_spc/ +) + +set(SDL_TARGETS SDL2::SDL2) + +if(WIN32 OR MINGW) + list(PREPEND SDL_TARGETS SDL2::SDL2main) + add_definitions(-DSDL_MAIN_HANDLED) +endif() + +# linking libraries ----------------------------------------------------------- + +target_link_libraries( + yaze PUBLIC + ${ABSL_TARGETS} + ${SDL_TARGETS} + ${SDLMIXER_LIBRARY} + SDL2_mixer + ${PNG_LIBRARIES} + ${GLEW_LIBRARIES} + ${OPENGL_LIBRARIES} + ${CMAKE_DL_LIBS} + asar-static + snes_spc + ImGui +) + +if (UNIX) + target_compile_definitions(yaze PRIVATE "linux") + target_compile_definitions(yaze PRIVATE "stricmp=strcasecmp") +endif() + +if(MACOS) + set(MACOSX_BUNDLE_ICON_FILE ${CMAKE_SOURCE_DIR}/yaze.ico) + set_target_properties(yaze + PROPERTIES + BUNDLE True + ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib" + LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib" + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" + # MACOSX_BUNDLE_INFO_PLIST ${CMAKE_SOURCE_DIR}/cmake/yaze.plist.in + ) +elseif(UNIX) + set_target_properties(yaze + PROPERTIES + BUNDLE True + ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib" + LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib" + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" + ) +else() +set_target_properties(yaze + PROPERTIES + ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib" + LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib" + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" + LINK_FLAGS "${CMAKE_CURRENT_SOURCE_DIR}/yaze.res" +) +endif() + +# add_subdirectory(app/delta) + +# add_executable( +# yaze_delta +# app/delta/delta.cc +# app/delta/viewer.cc +# app/delta/service.cc +# app/delta/client.cc +# app/rom.cc +# ${YAZE_APP_ASM_SRC} +# ${YAZE_APP_CORE_SRC} +# ${YAZE_APP_EDITOR_SRC} +# ${YAZE_APP_GFX_SRC} +# ${YAZE_APP_ZELDA3_SRC} +# ${YAZE_GUI_SRC} +# ${IMGUI_SRC} +# ${ASAR_STATIC_SRC} +# ) + +# target_include_directories( +# yaze_delta PUBLIC +# lib/ +# app/ +# lib/asar/src/ +# ${ASAR_INCLUDE_DIR} +# ${CMAKE_SOURCE_DIR}/src/ +# ${PNG_INCLUDE_DIRS} +# ${SDL2_INCLUDE_DIR} +# ${GLEW_INCLUDE_DIRS} +# ) + +# target_link_libraries( +# yaze_delta PUBLIC +# ${ABSL_TARGETS} +# ${SDL_TARGETS} +# ${PNG_LIBRARIES} +# ${GLEW_LIBRARIES} +# ${OPENGL_LIBRARIES} +# ${CMAKE_DL_LIBS} +# delta-service +# asar-static +# ImGui +# ) +# target_compile_definitions(yaze_delta PRIVATE "linux") +# target_compile_definitions(yaze_delta PRIVATE "stricmp=strcasecmp") + +# set (source "${CMAKE_SOURCE_DIR}/assets") +# set (destination "${CMAKE_CURRENT_BINARY_DIR}/assets") +# add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD +# COMMAND ${CMAKE_COMMAND} -E create_symlink ${source} ${destination} +# DEPENDS ${destination} +# COMMENT "symbolic link resources folder from ${source} => ${destination}") \ No newline at end of file diff --git a/src/Library/imgui b/src/Library/imgui deleted file mode 160000 index 0b1bcfcc..00000000 --- a/src/Library/imgui +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 0b1bcfcc205077d31493ec851f87ca4b54b4eab5 diff --git a/src/app/core/common.cc b/src/app/core/common.cc new file mode 100644 index 00000000..a8d0ee85 --- /dev/null +++ b/src/app/core/common.cc @@ -0,0 +1,63 @@ +#include "common.h" + +#include +#include + +namespace yaze { +namespace app { +namespace core { + +unsigned int SnesToPc(unsigned int addr) { + if (addr >= 0x808000) { + addr -= 0x808000; + } + unsigned int temp = (addr & 0x7FFF) + ((addr / 2) & 0xFF8000); + return (temp + 0x0); +} + +int AddressFromBytes(uint8_t addr1, uint8_t addr2, uint8_t addr3) { + return (addr1 << 16) | (addr2 << 8) | addr3; +} + +// hextodec has been imported from SNESDisasm to parse hex numbers +int HexToDec(char *input, int length) { + int result = 0; + int value; + int ceiling = length - 1; + int power16 = 16; + + int j = ceiling; + + for (; j >= 0; j--) { + if (input[j] >= 'A' && input[j] <= 'F') { + value = input[j] - 'F'; + value += 15; + } else { + value = input[j] - '9'; + value += 9; + } + + if (j == ceiling) { + result += value; + continue; + } + + result += (value * power16); + power16 *= 16; + } + + return result; +} + +bool StringReplace(std::string &str, const std::string &from, + const std::string &to) { + size_t start = str.find(from); + if (start == std::string::npos) return false; + + str.replace(start, from.length(), to); + return true; +} + +} // namespace core +} // namespace app +} // namespace yaze diff --git a/src/app/core/common.h b/src/app/core/common.h new file mode 100644 index 00000000..4a6969a5 --- /dev/null +++ b/src/app/core/common.h @@ -0,0 +1,21 @@ +#ifndef YAZE_CORE_COMMON_H +#define YAZE_CORE_COMMON_H + +#include +#include + +namespace yaze { +namespace app { +namespace core { + +unsigned int SnesToPc(unsigned int addr); +int AddressFromBytes(uint8_t addr1, uint8_t addr2, uint8_t addr3); +int HexToDec(char *input, int length); +bool StringReplace(std::string &str, const std::string &from, + const std::string &to); + +} // namespace core +} // namespace app +} // namespace yaze + +#endif \ No newline at end of file diff --git a/src/app/core/constants.h b/src/app/core/constants.h new file mode 100644 index 00000000..94f957ba --- /dev/null +++ b/src/app/core/constants.h @@ -0,0 +1,1604 @@ +#ifndef YAZE_APP_CORE_CONSTANTS_H +#define YAZE_APP_CORE_CONSTANTS_H + +#include + +#include "absl/strings/string_view.h" + +#define BASIC_BUTTON(w) if (ImGui::Button(w)) + +#define TAB_BAR(w) if (ImGui::BeginTabBar(w)) { +#define END_TAB_BAR() \ + ImGui::EndTabBar(); \ + } + +#define TAB_ITEM(w) if (ImGui::BeginTabItem(w)) { +#define END_TAB_ITEM() \ + ImGui::EndTabItem(); \ + } + +#define MENU_BAR() if (ImGui::BeginMenuBar()) { +#define END_MENU_BAR() \ + ImGui::EndMenuBar(); \ + } + +#define MENU_ITEM(w) if (ImGui::MenuItem(w)) +#define MENU_ITEM2(w, v) if (ImGui::MenuItem(w, v)) + +#define BUTTON_COLUMN(w) \ + ImGui::TableNextColumn(); \ + ImGui::Button(w); + +#define TEXT_COLUMN(w) \ + ImGui::TableNextColumn(); \ + ImGui::Text(w); + +#define PRINT_IF_ERROR(expression) \ + { \ + auto error = expression; \ + if (!error.ok()) { \ + std::cout << error.ToString() << std::endl; \ + } \ + } + +#define RETURN_IF_ERROR(expression) \ + { \ + auto error = expression; \ + if (!error.ok()) { \ + return error; \ + } \ + } + +#define ASSIGN_OR_RETURN(type_variable_name, expression) \ + ASSIGN_OR_RETURN_IMPL(APPEND_NUMBER(error_or_value, __LINE__), \ + type_variable_name, expression) + +#define ASSIGN_OR_RETURN_IMPL(error_or_value, type_variable_name, expression) \ + auto error_or_value = expression; \ + if (!error_or_value.ok()) { \ + return error_or_value.status(); \ + } \ + type_variable_name = std::move(*error_or_value); + +#define APPEND_NUMBER(expression, number) \ + APPEND_NUMBER_INNER(expression, number) + +#define APPEND_NUMBER_INNER(expression, number) expression##number + +using ushort = unsigned short; +using uint = unsigned int; +using uchar = unsigned char; +using Bytes = std::vector; + +using OWBlockset = std::vector>; +struct OWMapTiles { + OWBlockset light_world; // 64 maps + OWBlockset dark_world; // 64 maps + OWBlockset special_world; // 32 maps +}; +using OWMapTiles = struct OWMapTiles; + +namespace yaze { +namespace app { +namespace core { + +// ============================================================================ +// Window Variables +// ============================================================================ + +constexpr int kScreenWidth = 1200; +constexpr int kScreenHeight = 800; + +// ============================================================================ +// 65816 LanguageDefinition +// ============================================================================ + +static const char *const kKeywords[] = { + "ADC", "AND", "ASL", "BCC", "BCS", "BEQ", "BIT", "BMI", "BNE", + "BPL", "BRA", "BRL", "BVC", "BVS", "CLC", "CLD", "CLI", "CLV", + "CMP", "CPX", "CPY", "DEC", "DEX", "DEY", "EOR", "INC", "INX", + "INY", "JMP", "JSR", "JSL", "LDA", "LDX", "LDY", "LSR", "MVN", + "NOP", "ORA", "PEA", "PER", "PHA", "PHB", "PHD", "PHP", "PHX", + "PHY", "PLA", "PLB", "PLD", "PLP", "PLX", "PLY", "REP", "ROL", + "ROR", "RTI", "RTL", "RTS", "SBC", "SEC", "SEI", "SEP", "STA", + "STP", "STX", "STY", "STZ", "TAX", "TAY", "TCD", "TCS", "TDC", + "TRB", "TSB", "TSC", "TSX", "TXA", "TXS", "TXY", "TYA", "TYX", + "WAI", "WDM", "XBA", "XCE", "ORG", "LOROM", "HIROM", "NAMESPACE", "DB"}; + +static const char *const kIdentifiers[] = { + "abort", "abs", "acos", "asin", "atan", "atexit", + "atof", "atoi", "atol", "ceil", "clock", "cosh", + "ctime", "div", "exit", "fabs", "floor", "fmod", + "getchar", "getenv", "isalnum", "isalpha", "isdigit", "isgraph", + "ispunct", "isspace", "isupper", "kbhit", "log10", "log2", + "log", "memcmp", "modf", "pow", "putchar", "putenv", + "puts", "rand", "remove", "rename", "sinh", "sqrt", + "srand", "strcat", "strcmp", "strerror", "time", "tolower", + "toupper"}; + +// ============================================================================ +// Magic numbers +// ============================================================================ + +/// Bit set for object priority +constexpr ushort TilePriorityBit = 0x2000; + +/// Bit set for object hflip +constexpr ushort TileHFlipBit = 0x4000; + +/// Bit set for object vflip +constexpr ushort TileVFlipBit = 0x8000; + +/// Bits used for tile name +constexpr ushort TileNameMask = 0x03FF; + +constexpr int Uncompressed3BPPSize = 0x0600; +constexpr int UncompressedSheetSize = 0x0800; + +constexpr int NumberOfSheets = 223; +constexpr int LimitOfMap32 = 8864; +constexpr int NumberOfRooms = 296; + +constexpr int kNumOverworldMaps = 160; +constexpr int Map32PerScreen = 256; +constexpr int NumberOfMap16 = 3752; // 4096 +constexpr int NumberOfMap32 = Map32PerScreen * kNumOverworldMaps; +constexpr int NumberOfOWSprites = 352; +constexpr int NumberOfColors = 3143; + +// ============================================================================ +// Game Graphics +// ============================================================================ + +constexpr int tile_address = 0x1B52; // JP = Same +constexpr int tile_address_floor = 0x1B5A; // JP = Same +constexpr int subtype1_tiles = 0x8000; // JP = Same +constexpr int subtype2_tiles = 0x83F0; // JP = Same +constexpr int subtype3_tiles = 0x84F0; // JP = Same +constexpr int gfx_animated_pointer = 0x10275; // JP 0x10624 //long pointer +constexpr int overworldgfxGroups2 = 0x6073; // 0x60B3 + +// 2 byte pointer bank 00 pc -> 0x4320 +constexpr int gfx_1_pointer = 0x6790; // CF80 ; 004F80 +constexpr int gfx_2_pointer = 0x6795; // D05F ; 00505F +constexpr int gfx_3_pointer = 0x679A; // D13E ; 00513E +constexpr int hud_palettes = 0xDD660; +constexpr int maxGfx = 0xC3FB5; + +constexpr int kTilesheetWidth = 128; +constexpr int kTilesheetHeight = 32; +constexpr int kTilesheetDepth = 8; + +// ============================================================================ +// Overworld Related Variables +// ============================================================================ + +constexpr int compressedAllMap32PointersHigh = 0x1794D; +constexpr int compressedAllMap32PointersLow = 0x17B2D; +constexpr int overworldgfxGroups = 0x05D97; +constexpr int map16Tiles = 0x78000; +constexpr int map32TilesTL = 0x18000; +constexpr int map32TilesTR = 0x1B400; +constexpr int map32TilesBL = 0x20000; +constexpr int map32TilesBR = 0x23400; +constexpr int overworldPalGroup1 = 0xDE6C8; +constexpr int overworldPalGroup2 = 0xDE86C; +constexpr int overworldPalGroup3 = 0xDE604; +constexpr int overworldMapPalette = 0x7D1C; +constexpr int overworldSpritePalette = 0x7B41; +constexpr int overworldMapPaletteGroup = 0x75504; +constexpr int overworldSpritePaletteGroup = 0x75580; +constexpr int overworldSpriteset = 0x7A41; +constexpr int overworldSpecialGFXGroup = 0x16821; +constexpr int overworldSpecialPALGroup = 0x16831; + +constexpr int overworldSpritesBegining = 0x4C881; +constexpr int overworldSpritesAgahnim = 0x4CA21; +constexpr int overworldSpritesZelda = 0x4C901; + +constexpr int overworldItemsPointers = 0xDC2F9; +constexpr int overworldItemsAddress = 0xDC8B9; // 1BC2F9 +constexpr int overworldItemsBank = 0xDC8BF; +constexpr int overworldItemsEndData = 0xDC89C; // 0DC89E + +constexpr int mapGfx = 0x7C9C; +constexpr int overlayPointers = 0x77664; +constexpr int overlayPointersBank = 0x0E; + +constexpr int overworldTilesType = 0x71459; +constexpr int overworldMessages = 0x3F51D; + +constexpr int overworldMusicBegining = 0x14303; +constexpr int overworldMusicZelda = 0x14303 + 0x40; +constexpr int overworldMusicMasterSword = 0x14303 + 0x80; +constexpr int overworldMusicAgahim = 0x14303 + 0xC0; +constexpr int overworldMusicDW = 0x14403; + +constexpr int overworldEntranceAllowedTilesLeft = 0xDB8C1; +constexpr int overworldEntranceAllowedTilesRight = 0xDB917; + +// 0x00 = small maps, 0x20 = large maps +constexpr int overworldMapSize = 0x12844; + +// 0x01 = small maps, 0x03 = large maps +constexpr int overworldMapSizeHighByte = 0x12884; + +// relative to the WORLD + 0x200 per map +// large map that are not == parent id = same position as their parent! +// eg for X position small maps : +// 0000, 0200, 0400, 0600, 0800, 0A00, 0C00, 0E00 +// all Large map would be : +// 0000, 0000, 0400, 0400, 0800, 0800, 0C00, 0C00 + +constexpr int overworldTransitionPositionY = 0x128C4; +constexpr int overworldTransitionPositionX = 0x12944; + +constexpr int overworldScreenSize = 0x1788D; + +// ============================================================================ +// Overworld Exits/Entrances Variables +// ============================================================================ +constexpr int OWExitRoomId = 0x15D8A; // 0x15E07 Credits sequences +// 105C2 Ending maps +// 105E2 Sprite Group Table for Ending +constexpr int OWExitMapId = 0x15E28; +constexpr int OWExitVram = 0x15E77; +constexpr int OWExitYScroll = 0x15F15; +constexpr int OWExitXScroll = 0x15FB3; +constexpr int OWExitYPlayer = 0x16051; +constexpr int OWExitXPlayer = 0x160EF; +constexpr int OWExitYCamera = 0x1618D; +constexpr int OWExitXCamera = 0x1622B; +constexpr int OWExitDoorPosition = 0x15724; +constexpr int OWExitUnk1 = 0x162C9; +constexpr int OWExitUnk2 = 0x16318; +constexpr int OWExitDoorType1 = 0x16367; +constexpr int OWExitDoorType2 = 0x16405; +constexpr int OWEntranceMap = 0xDB96F; +constexpr int OWEntrancePos = 0xDBA71; +constexpr int OWEntranceEntranceId = 0xDBB73; +constexpr int OWHolePos = 0xDB800; //(0x13 entries, 2 bytes each) modified(less + // 0x400) map16 coordinates for each hole +constexpr int OWHoleArea = + 0xDB826; //(0x13 entries, 2 bytes each) corresponding + // area numbers for each hole +constexpr int OWHoleEntrance = + 0xDB84C; //(0x13 entries, 1 byte each) corresponding entrance numbers + +constexpr int OWExitMapIdWhirlpool = 0x16AE5; // JP = ;016849 +constexpr int OWExitVramWhirlpool = 0x16B07; // JP = ;01686B +constexpr int OWExitYScrollWhirlpool = 0x16B29; // JP = ;01688D +constexpr int OWExitXScrollWhirlpool = 0x16B4B; // JP = ;016DE7 +constexpr int OWExitYPlayerWhirlpool = 0x16B6D; // JP = ;016E09 +constexpr int OWExitXPlayerWhirlpool = 0x16B8F; // JP = ;016E2B +constexpr int OWExitYCameraWhirlpool = 0x16BB1; // JP = ;016E4D +constexpr int OWExitXCameraWhirlpool = 0x16BD3; // JP = ;016E6F +constexpr int OWExitUnk1Whirlpool = 0x16BF5; // JP = ;016E91 +constexpr int OWExitUnk2Whirlpool = 0x16C17; // JP = ;016EB3 +constexpr int OWWhirlpoolPosition = 0x16CF8; // JP = ;016F94 + +// ============================================================================ +// Dungeon Related Variables +// ============================================================================ + +// That could be turned into a pointer : +constexpr int dungeons_palettes_groups = 0x75460; // JP 0x67DD0 +constexpr int dungeons_main_bg_palette_pointers = 0xDEC4B; // JP Same +constexpr int dungeons_palettes = + 0xDD734; // JP Same (where all dungeons palettes are) + +// That could be turned into a pointer : +constexpr int room_items_pointers = 0xDB69; // JP 0xDB67 + +constexpr int rooms_sprite_pointer = 0x4C298; // JP Same //2byte bank 09D62E +constexpr int room_header_pointer = 0xB5DD; // LONG +constexpr int room_header_pointers_bank = 0xB5E7; // JP Same + +constexpr int gfx_groups_pointer = 0x6237; +constexpr int room_object_layout_pointer = 0x882D; + +constexpr int room_object_pointer = 0x874C; // Long pointer + +constexpr int chests_length_pointer = 0xEBF6; +constexpr int chests_data_pointer1 = 0xEBFB; +// constexpr int chests_data_pointer2 = 0xEC0A; //Disabled for now could be used +// for expansion constexpr int chests_data_pointer3 = 0xEC10; //Disabled for now +// could be used for expansion + +constexpr int blocks_length = 0x8896; // word value +constexpr int blocks_pointer1 = 0x15AFA; +constexpr int blocks_pointer2 = 0x15B01; +constexpr int blocks_pointer3 = 0x15B08; +constexpr int blocks_pointer4 = 0x15B0F; + +constexpr int torch_data = 0x2736A; // JP 0x2704A +constexpr int torches_length_pointer = 0x88C1; + +constexpr int kSpriteBlocksetPointer = 0x5B57; +constexpr int sprites_data = + 0x4D8B0; // It use the unused pointers to have more space //Save purpose +constexpr int sprites_data_empty_room = 0x4D8AE; +constexpr int sprites_end_data = 0x4EC9E; + +constexpr int pit_pointer = 0x394AB; +constexpr int pit_count = 0x394A6; + +constexpr int doorPointers = 0xF83C0; + +// doors +constexpr int door_gfx_up = 0x4D9E; +constexpr int door_gfx_down = 0x4E06; +constexpr int door_gfx_cavexit_down = 0x4E06; +constexpr int door_gfx_left = 0x4E66; +constexpr int door_gfx_right = 0x4EC6; + +constexpr int door_pos_up = 0x197E; +constexpr int door_pos_down = 0x1996; +constexpr int door_pos_left = 0x19AE; +constexpr int door_pos_right = 0x19C6; + +// TEXT EDITOR RELATED CONSTANTS +constexpr int gfx_font = 0x70000; // 2bpp format +constexpr int text_data = 0xE0000; +constexpr int text_data2 = 0x75F40; +constexpr int pointers_dictionaries = 0x74703; +constexpr int characters_width = 0x74ADF; + +// ============================================================================ +// Dungeon Entrances Related Variables +// ============================================================================ + +// 0x14577 word value for each room +constexpr int entrance_room = 0x14813; + +// 8 bytes per room, HU, FU, HD, FD, HL, FL, HR, FR +constexpr int entrance_scrolledge = 0x1491D; // 0x14681 +constexpr int entrance_yscroll = 0x14D45; // 0x14AA9 2 bytes each room +constexpr int entrance_xscroll = 0x14E4F; // 0x14BB3 2 bytes +constexpr int entrance_yposition = 0x14F59; // 0x14CBD 2bytes +constexpr int entrance_xposition = 0x15063; // 0x14DC7 2bytes +constexpr int entrance_camerayposition = 0x1516D; // 0x14ED1 2bytes +constexpr int entrance_cameraxposition = 0x15277; // 0x14FDB 2bytes + +constexpr int entrance_gfx_group = 0x5D97; +constexpr int entrance_blockset = 0x15381; // 0x150E5 1byte +constexpr int entrance_floor = 0x15406; // 0x1516A 1byte +constexpr int entrance_dungeon = 0x1548B; // 0x151EF 1byte (dungeon id) +constexpr int entrance_door = 0x15510; // 0x15274 1byte + +// 1 byte, ---b ---a b = bg2, a = need to check +constexpr int entrance_ladderbg = 0x15595; // 0x152F9 +constexpr int entrance_scrolling = 0x1561A; // 0x1537E 1byte --h- --v- +constexpr int entrance_scrollquadrant = 0x1569F; // 0x15403 1byte +constexpr int entrance_exit = 0x15724; // 0x15488 2byte word +constexpr int entrance_music = 0x1582E; // 0x15592 + +// word value for each room +constexpr int startingentrance_room = 0x15B6E; // 0x158D2 + +// 8 bytes per room, HU, FU, HD, FD, HL, FL, HR, FR +constexpr int startingentrance_scrolledge = 0x15B7C; // 0x158E0 +constexpr int startingentrance_yscroll = 0x15BB4; // 0x14AA9 //2bytes each room +constexpr int startingentrance_xscroll = 0x15BC2; // 0x14BB3 //2bytes +constexpr int startingentrance_yposition = 0x15BD0; // 0x14CBD 2bytes +constexpr int startingentrance_xposition = 0x15BDE; // 0x14DC7 2bytes +constexpr int startingentrance_camerayposition = 0x15BEC; // 0x14ED1 2bytes +constexpr int startingentrance_cameraxposition = 0x15BFA; // 0x14FDB 2bytes + +constexpr int startingentrance_blockset = 0x15C08; // 0x150E5 1byte +constexpr int startingentrance_floor = 0x15C0F; // 0x1516A 1byte +constexpr int startingentrance_dungeon = 0x15C16; // 0x151EF 1byte (dungeon id) + +constexpr int startingentrance_door = 0x15C2B; // 0x15274 1byte + +// 1 byte, ---b ---a b = bg2, a = need to check +constexpr int startingentrance_ladderbg = 0x15C1D; // 0x152F9 +// 1byte --h- --v- +constexpr int startingentrance_scrolling = 0x15C24; // 0x1537E +constexpr int startingentrance_scrollquadrant = 0x15C2B; // 0x15403 1byte +constexpr int startingentrance_exit = 0x15C32; // 0x15488 //2byte word +constexpr int startingentrance_music = 0x15C4E; // 0x15592 +constexpr int startingentrance_entrance = 0x15C40; + +constexpr int items_data_start = 0xDDE9; // save purpose +constexpr int items_data_end = 0xE6B2; // save purpose +constexpr int initial_equipement = 0x271A6; +constexpr int messages_id_dungeon = 0x3F61D; + +// item id you get instead if you already have that item +constexpr int chests_backupitems = 0x3B528; +constexpr int chests_yoffset = 0x4836C; +constexpr int chests_xoffset = 0x4836C + (76 * 1); +constexpr int chests_itemsgfx = 0x4836C + (76 * 2); +constexpr int chests_itemswide = 0x4836C + (76 * 3); +constexpr int chests_itemsproperties = 0x4836C + (76 * 4); +constexpr int chests_sramaddress = 0x4836C + (76 * 5); +constexpr int chests_sramvalue = 0x4836C + (76 * 7); +constexpr int chests_msgid = 0x442DD; + +constexpr int dungeons_startrooms = 0x7939; +constexpr int dungeons_endrooms = 0x792D; +constexpr int dungeons_bossrooms = 0x10954; // short value + +// Bed Related Values (Starting location) +constexpr int bedPositionX = 0x039A37; // short value +constexpr int bedPositionY = 0x039A32; // short value + +// short value (on 2 different bytes) +constexpr int bedPositionResetXLow = 0x02DE53; +constexpr int bedPositionResetXHigh = 0x02DE58; + +// short value (on 2 different bytes) +constexpr int bedPositionResetYLow = 0x02DE5D; +constexpr int bedPositionResetYHigh = 0x02DE62; + +constexpr int bedSheetPositionX = 0x0480BD; // short value +constexpr int bedSheetPositionY = 0x0480B8; // short value + +// ============================================================================ +// Gravestones related variables +// ============================================================================ + +constexpr int GravesYTilePos = 0x49968; // short (0x0F entries) +constexpr int GravesXTilePos = 0x49986; // short (0x0F entries) +constexpr int GravesTilemapPos = 0x499A4; // short (0x0F entries) +constexpr int GravesGFX = 0x499C2; // short (0x0F entries) + +constexpr int GravesXPos = 0x4994A; // short (0x0F entries) +constexpr int GravesYLine = 0x4993A; // short (0x08 entries) +constexpr int GravesCountOnY = 0x499E0; // Byte 0x09 entries + +constexpr int GraveLinkSpecialHole = 0x46DD9; // short +constexpr int GraveLinkSpecialStairs = 0x46DE0; // short + +// ============================================================================ +// Palettes Related Variables - This contain all the palettes of the game +// ============================================================================ +constexpr int overworldPaletteMain = 0xDE6C8; +constexpr int overworldPaletteAuxialiary = 0xDE86C; +constexpr int overworldPaletteAnimated = 0xDE604; +constexpr int globalSpritePalettesLW = 0xDD218; +constexpr int globalSpritePalettesDW = 0xDD290; +// Green, Blue, Red, Bunny, Electrocuted (15 colors each) +constexpr int armorPalettes = 0xDD308; +constexpr int spritePalettesAux1 = 0xDD39E; // 7 colors each +constexpr int spritePalettesAux2 = 0xDD446; // 7 colors each +constexpr int spritePalettesAux3 = 0xDD4E0; // 7 colors each +constexpr int swordPalettes = 0xDD630; // 3 colors each - 4 entries +constexpr int shieldPalettes = 0xDD648; // 4 colors each - 3 entries +constexpr int hudPalettes = 0xDD660; +constexpr int dungeonMapPalettes = 0xDD70A; // 21 colors +constexpr int dungeonMainPalettes = 0xDD734; //(15*6) colors each - 20 entries +constexpr int dungeonMapBgPalettes = 0xDE544; // 16*6 +// Mirrored Value at 0x75645 : 0x75625 +constexpr int hardcodedGrassLW = 0x5FEA9; +constexpr int hardcodedGrassDW = 0x05FEB3; // 0x7564F +constexpr int hardcodedGrassSpecial = 0x75640; +constexpr int overworldMiniMapPalettes = 0x55B27; +constexpr int triforcePalette = 0x64425; +constexpr int crystalPalette = 0xF4CD3; +constexpr int customAreaSpecificBGPalette = + 0x140000; // 2 bytes for each overworld area (320) +constexpr int customAreaSpecificBGASM = 0x140150; +constexpr int customAreaSpecificBGEnabled = + 0x140140; // 1 byte, not 0 if enabled +constexpr int overworldCustomMosaicArray = 0x1301F0; +// ============================================================================ +// Dungeon Map Related Variables +// ============================================================================ + +constexpr int dungeonMap_rooms_ptr = 0x57605; // 14 pointers of map data +constexpr int dungeonMap_floors = 0x575D9; // 14 words values + +constexpr int dungeonMap_gfx_ptr = 0x57BE4; // 14 pointers of gfx data + +// data start for floors/gfx MUST skip 575D9 to 57621 (pointers) +constexpr int dungeonMap_datastart = 0x57039; + +// IF Byte = 0xB9 dungeon maps are not expanded +constexpr int dungeonMap_expCheck = 0x56652; +constexpr int dungeonMap_tile16 = 0x57009; +constexpr int dungeonMap_tile16Exp = 0x109010; + +// 14 words values 0x000F = no boss +constexpr int dungeonMap_bossrooms = 0x56807; +constexpr int triforceVertices = 0x04FFD2; // group of 3, X, Y ,Z +constexpr int TriforceFaces = 0x04FFE4; // group of 5 + +constexpr int crystalVertices = 0x04FF98; + +// ============================================================================ +// Names +// ============================================================================ + +static const absl::string_view RoomEffect[] = {"Nothing", + "Nothing", + "Moving Floor", + "Moving Water", + "Trinexx Shell", + "Red Flashes", + "Light Torch to See Floor", + "Ganon's Darkness"}; + +static const absl::string_view RoomTag[] = {"Nothing", + + "NW Kill Enemy to Open", + "NE Kill Enemy to Open", + "SW Kill Enemy to Open", + "SE Kill Enemy to Open", + "W Kill Enemy to Open", + "E Kill Enemy to Open", + "N Kill Enemy to Open", + "S Kill Enemy to Open", + "Clear Quadrant to Open", + "Clear Full Tile to Open", + + "NW Push Block to Open", + "NE Push Block to Open", + "SW Push Block to Open", + "SE Push Block to Open", + "W Push Block to Open", + "E Push Block to Open", + "N Push Block to Open", + "S Push Block to Open", + "Push Block to Open", + "Pull Lever to Open", + "Collect Prize to Open", + + "Hold Switch Open Door", + "Toggle Switch to Open Door", + "Turn off Water", + "Turn on Water", + "Water Gate", + "Water Twin", + "Moving Wall Right", + "Moving Wall Left", + "Crash", + "Crash", + "Push Switch Exploding Wall", + "Holes 0", + "Open Chest (Holes 0)", + "Holes 1", + "Holes 2", + "Defeat Boss for Dungeon Prize", + + "SE Kill Enemy to Push Block", + "Trigger Switch Chest", + "Pull Lever Exploding Wall", + "NW Kill Enemy for Chest", + "NE Kill Enemy for Chest", + "SW Kill Enemy for Chest", + "SE Kill Enemy for Chest", + "W Kill Enemy for Chest", + "E Kill Enemy for Chest", + "N Kill Enemy for Chest", + "S Kill Enemy for Chest", + "Clear Quadrant for Chest", + "Clear Full Tile for Chest", + + "Light Torches to Open", + "Holes 3", + "Holes 4", + "Holes 5", + "Holes 6", + "Agahnim Room", + "Holes 7", + "Holes 8", + "Open Chest for Holes 8", + "Push Block for Chest", + "Clear Room for Triforce Door", + "Light Torches for Chest", + "Kill Boss Again"}; + +static const absl::string_view SecretItemNames[] = { + "Nothing", "Green Rupee", "Rock hoarder", "Bee", "Health pack", + "Bomb", "Heart ", "Blue Rupee", + + "Key", "Arrow", "Bomb", "Heart", "Magic", + "Full Magic", "Cucco", "Green Soldier", "Bush Stal", "Blue Soldier", + + "Landmine", "Heart", "Fairy", "Heart", + "Nothing ", // 22 + + "Hole", "Warp", "Staircase", "Bombable", "Switch"}; + +static const absl::string_view Type1RoomObjectNames[] = { + "Ceiling ↔", + "Wall (top, north) ↔", + "Wall (top, south) ↔", + "Wall (bottom, north) ↔", + "Wall (bottom, south) ↔", + "Wall columns (north) ↔", + "Wall columns (south) ↔", + "Deep wall (north) ↔", + "Deep wall (south) ↔", + "Diagonal wall A ◤ (top) ↔", + "Diagonal wall A ◣ (top) ↔", + "Diagonal wall A ◥ (top) ↔", + "Diagonal wall A ◢ (top) ↔", + "Diagonal wall B ◤ (top) ↔", + "Diagonal wall B ◣ (top) ↔", + "Diagonal wall B ◥ (top) ↔", + "Diagonal wall B ◢ (top) ↔", + "Diagonal wall C ◤ (top) ↔", + "Diagonal wall C ◣ (top) ↔", + "Diagonal wall C ◥ (top) ↔", + "Diagonal wall C ◢ (top) ↔", + "Diagonal wall A ◤ (bottom) ↔", + "Diagonal wall A ◣ (bottom) ↔", + "Diagonal wall A ◥ (bottom) ↔", + "Diagonal wall A ◢ (bottom) ↔", + "Diagonal wall B ◤ (bottom) ↔", + "Diagonal wall B ◣ (bottom) ↔", + "Diagonal wall B ◥ (bottom) ↔", + "Diagonal wall B ◢ (bottom) ↔", + "Diagonal wall C ◤ (bottom) ↔", + "Diagonal wall C ◣ (bottom) ↔", + "Diagonal wall C ◥ (bottom) ↔", + "Diagonal wall C ◢ (bottom) ↔", + "Platform stairs ↔", + "Rail ↔", + "Pit edge ┏━┓ A (north) ↔", + "Pit edge ┏━┓ B (north) ↔", + "Pit edge ┏━┓ C (north) ↔", + "Pit edge ┏━┓ D (north) ↔", + "Pit edge ┏━┓ E (north) ↔", + "Pit edge ┗━┛ (south) ↔", + "Pit edge ━━━ (south) ↔", + "Pit edge ━━━ (north) ↔", + "Pit edge ━━┛ (south) ↔", + "Pit edge ┗━━ (south) ↔", + "Pit edge ━━┓ (north) ↔", + "Pit edge ┏━━ (north) ↔", + "Rail wall (north) ↔", + "Rail wall (south) ↔", + "Nothing", + "Nothing", + "Carpet ↔", + "Carpet trim ↔", + "Weird door", // TODO: WEIRD DOOR OBJECT NEEDS INVESTIGATION + "Drapes (north) ↔", + "Drapes (west, odd) ↔", + "Statues ↔", + "Columns ↔", + "Wall decors (north) ↔", + "Wall decors (south) ↔", + "Chairs in pairs ↔", + "Tall torches ↔", + "Supports (north) ↔", + "Water edge ┏━┓ (concave) ↔", + "Water edge ┗━┛ (concave) ↔", + "Water edge ┏━┓ (convex) ↔", + "Water edge ┗━┛ (convex) ↔", + "Water edge ┏━┛ (concave) ↔", + "Water edge ┗━┓ (concave) ↔", + "Water edge ┗━┓ (convex) ↔", + "Water edge ┏━┛ (convex) ↔", + "Unknown", // TODO: NEEDS IN GAME CHECKING + "Unknown", // TODO: NEEDS IN GAME CHECKING + "Unknown", // TODO: NEEDS IN GAME CHECKING + "Unknown", // TODO: NEEDS IN GAME CHECKING + "Supports (south) ↔", + "Bar ↔", + "Shelf A ↔", + "Shelf B ↔", + "Shelf C ↔", + "Somaria path ↔", + "Cannon hole A (north) ↔", + "Cannon hole A (south) ↔", + "Pipe path ↔", + "Nothing", + "Wall torches (north) ↔", + "Wall torches (south) ↔", + "Nothing", + "Nothing", + "Nothing", + "Nothing", + "Cannon hole B (north) ↔", + "Cannon hole B (south) ↔", + "Thick rail ↔", + "Blocks ↔", + "Long rail ↔", + "Ceiling ↕", + "Wall (top, west) ↕", + "Wall (top, east) ↕", + "Wall (bottom, west) ↕", + "Wall (bottom, east) ↕", + "Wall columns (west) ↕", + "Wall columns (east) ↕", + "Deep wall (west) ↕", + "Deep wall (east) ↕", + "Rail ↕", + "Pit edge (west) ↕", + "Pit edge (east) ↕", + "Rail wall (west) ↕", + "Rail wall (east) ↕", + "Nothing", + "Nothing", + "Carpet ↕", + "Carpet trim ↕", + "Nothing", + "Drapes (west) ↕", + "Drapes (east) ↕", + "Columns ↕", + "Wall decors (west) ↕", + "Wall decors (east) ↕", + "Supports (west) ↕", + "Water edge (west) ↕", + "Water edge (east) ↕", + "Supports (east) ↕", + "Somaria path ↕", + "Pipe path ↕", + "Nothing", + "Wall torches (west) ↕", + "Wall torches (east) ↕", + "Wall decors tight A (west) ↕", + "Wall decors tight A (east) ↕", + "Wall decors tight B (west) ↕", + "Wall decors tight B (east) ↕", + "Cannon hole (west) ↕", + "Cannon hole (east) ↕", + "Tall torches ↕", + "Thick rail ↕", + "Blocks ↕", + "Long rail ↕", + "Jump ledge (west) ↕", + "Jump ledge (east) ↕", + "Rug trim (west) ↕", + "Rug trim (east) ↕", + "Bar ↕", + "Wall flair (west) ↕", + "Wall flair (east) ↕", + "Blue pegs ↕", + "Orange pegs ↕", + "Invisible floor ↕", + "Fake pots ↕", + "Hammer pegs ↕", + "Nothing", + "Nothing", + "Nothing", + "Nothing", + "Nothing", + "Nothing", + "Nothing", + "Nothing", + "Nothing", + "Diagonal ceiling A ◤", + "Diagonal ceiling A ◣", + "Diagonal ceiling A ◥", + "Diagonal ceiling A ◢", + "Pit ⇲", + "Diagonal layer 2 mask A ◤", + "Diagonal layer 2 mask A ◣", + "Diagonal layer 2 mask A ◥", + "Diagonal layer 2 mask A ◢", + "Diagonal layer 2 mask B ◤", // TODO: VERIFY + "Diagonal layer 2 mask B ◣", // TODO: VERIFY + "Diagonal layer 2 mask B ◥", // TODO: VERIFY + "Diagonal layer 2 mask B ◢", // TODO: VERIFY + "Nothing", + "Nothing", + "Nothing", + "Jump ledge (north) ↔", + "Jump ledge (south) ↔", + "Rug ↔", + "Rug trim (north) ↔", + "Rug trim (south) ↔", + "Archery game curtains ↔", + "Wall flair (north) ↔", + "Wall flair (south) ↔", + "Blue pegs ↔", + "Orange pegs ↔", + "Invisible floor ↔", + "Fake pressure plates ↔", + "Fake pots ↔", + "Hammer pegs ↔", + "Nothing", + "Nothing", + "Ceiling (large) ⇲", + "Chest platform (tall) ⇲", + "Layer 2 pit mask (large) ⇲", + "Layer 2 pit mask (medium) ⇲", + "Floor 1 ⇲", + "Floor 3 ⇲", + "Layer 2 mask (large) ⇲", + "Floor 4 ⇲", + "Water floor ⇲ ", + "Flood water (medium) ⇲ ", + "Conveyor floor ⇲ ", + "Nothing", + "Nothing", + "Moving wall (west) ⇲", + "Moving wall (east) ⇲", + "Nothing", + "Nothing", + "Icy floor A ⇲", + "Icy floor B ⇲", + "Moving wall flag", // TODO: WTF IS THIS? + "Moving wall flag", // TODO: WTF IS THIS? + "Moving wall flag", // TODO: WTF IS THIS? + "Moving wall flag", // TODO: WTF IS THIS? + "Layer 2 mask (medium) ⇲", + "Flood water (large) ⇲", + "Layer 2 swim mask ⇲", + "Flood water B (large) ⇲", + "Floor 2 ⇲", + "Chest platform (short) ⇲", + "Table / rock ⇲", + "Spike blocks ⇲", + "Spiked floor ⇲", + "Floor 7 ⇲", + "Tiled floor ⇲", + "Rupee floor ⇲", + "Conveyor upwards ⇲", + "Conveyor downwards ⇲", + "Conveyor leftwards ⇲", + "Conveyor rightwards ⇲", + "Heavy current water ⇲", + "Floor 10 ⇲", + "Nothing", + "Nothing", + "Nothing", + "Nothing", + "Nothing", + "Nothing", + "Nothing", + "Nothing", + "Nothing", + "Nothing", + "Nothing", + "Nothing", + "Nothing", + "Nothing", + "Nothing", +}; + +static const absl::string_view Type2RoomObjectNames[] = { + "Corner (top, concave) ▛", + "Corner (top, concave) ▙", + "Corner (top, concave) ▜", + "Corner (top, concave) ▟", + "Corner (top, convex) ▟", + "Corner (top, convex) ▜", + "Corner (top, convex) ▙", + "Corner (top, convex) ▛", + "Corner (bottom, concave) ▛", + "Corner (bottom, concave) ▙", + "Corner (bottom, concave) ▜", + "Corner (bottom, concave) ▟", + "Corner (bottom, convex) ▟", + "Corner (bottom, convex) ▜", + "Corner (bottom, convex) ▙", + "Corner (bottom, convex) ▛", + "Kinked corner north (bottom) ▜", + "Kinked corner south (bottom) ▟", + "Kinked corner north (bottom) ▛", + "Kinked corner south (bottom) ▙", + "Kinked corner west (bottom) ▙", + "Kinked corner west (bottom) ▛", + "Kinked corner east (bottom) ▟", + "Kinked corner east (bottom) ▜", + "Deep corner (concave) ▛", + "Deep corner (concave) ▙", + "Deep corner (concave) ▜", + "Deep corner (concave) ▟", + "Large brazier", + "Statue", + "Star tile (disabled)", + "Star tile (enabled)", + "Small torch (lit)", + "Barrel", + "Unknown", // TODO: NEEDS IN GAME CHECKING + "Table", + "Fairy statue", + "Unknown", // TODO: NEEDS IN GAME CHECKING + "Unknown", // TODO: NEEDS IN GAME CHECKING + "Chair", + "Bed", + "Fireplace", + "Mario portrait", + "Unknown", // TODO: NEEDS IN GAME CHECKING + "Unknown", // TODO: NEEDS IN GAME CHECKING + "Interroom stairs (up)", + "Interroom stairs (down)", + "Interroom stairs B (down)", + "Intraroom stairs north B", // TODO: VERIFY LAYER HANDLING + "Intraroom stairs north (separate layers)", + "Intraroom stairs north (merged layers)", + "Intraroom stairs north (swim layer)", + "Block", + "Water ladder (north)", + "Water ladder (south)", // TODO: NEEDS IN GAME VERIFICATION + "Dam floodgate", + "Interroom spiral stairs up (top)", + "Interroom spiral stairs down (top)", + "Interroom spiral stairs up (bottom)", + "Interroom spiral stairs down (bottom)", + "Sanctuary wall (north)", + "Unknown", // TODO: NEEDS IN GAME CHECKING + "Pew", + "Magic bat altar", +}; + +static const absl::string_view Type3RoomObjectNames[] = { + "Waterfall face (empty)", + "Waterfall face (short)", + "Waterfall face (long)", + "Somaria path endpoint", + "Somaria path intersection ╋", + "Somaria path corner ┏", + "Somaria path corner ┗", + "Somaria path corner ┓", + "Somaria path corner ┛", + "Somaria path intersection ┳", + "Somaria path intersection ┻", + "Somaria path intersection ┣", + "Somaria path intersection ┫", + "Unknown", // TODO: NEEDS IN GAME CHECKING + "Somaria path 2-way endpoint", + "Somaria path crossover", + "Babasu hole (north)", + "Babasu hole (south)", + "9 blue rupees", + "Telepathy tile", + "Warp door", // TODO: NEEDS IN GAME VERIFICATION THAT THIS IS USELESS + "Kholdstare's shell", + "Hammer peg", + "Prison cell", + "Big key lock", + "Chest", + "Chest (open)", + "Intraroom stairs south", // TODO: VERIFY LAYER HANDLING + "Intraroom stairs south (separate layers)", + "Intraroom stairs south (merged layers)", + "Interroom straight stairs up (north, top)", + "Interroom straight stairs down (north, top)", + "Interroom straight stairs up (south, top)", + "Interroom straight stairs down (south, top)", + "Deep corner (convex) ▟", + "Deep corner (convex) ▜", + "Deep corner (convex) ▙", + "Deep corner (convex) ▛", + "Interroom straight stairs up (north, bottom)", + "Interroom straight stairs down (north, bottom)", + "Interroom straight stairs up (south, bottom)", + "Interroom straight stairs down (south, bottom)", + "Lamp cones", + "Unknown", // TODO: NEEDS IN GAME CHECKING + "Liftable large block", + "Agahnim's altar", + "Agahnim's boss room", + "Pot", + "Unknown", // TODO: NEEDS IN GAME CHECKING + "Big chest", + "Big chest (open)", + "Intraroom stairs south (swim layer)", + "Unknown", // TODO: NEEDS IN GAME CHECKING + "Unknown", // TODO: NEEDS IN GAME CHECKING + "Unknown", // TODO: NEEDS IN GAME CHECKING + "Unknown", // TODO: NEEDS IN GAME CHECKING + "Unknown", // TODO: NEEDS IN GAME CHECKING + "Unknown", // TODO: NEEDS IN GAME CHECKING + "Pipe end (south)", + "Pipe end (north)", + "Pipe end (east)", + "Pipe end (west)", + "Pipe corner ▛", + "Pipe corner ▙", + "Pipe corner ▜", + "Pipe corner ▟", + "Pipe-rock intersection ⯊", + "Pipe-rock intersection ⯋", + "Pipe-rock intersection ◖", + "Pipe-rock intersection ◗", + "Pipe crossover", + "Bombable floor", + "Fake bombable floor", + "Unknown", // TODO: NEEDS IN GAME CHECKING + "Warp tile", + "Tool rack", + "Furnace", + "Tub (wide)", + "Anvil", + "Warp tile (disabled)", + "Pressure plate", + "Unknown", // TODO: NEEDS IN GAME CHECKING + "Blue peg", + "Orange peg", + "Fortune teller room", + "Unknown", // TODO: NEEDS IN GAME CHECKING + "Bar corner ▛", + "Bar corner ▙", + "Bar corner ▜", + "Bar corner ▟", + "Decorative bowl", + "Tub (tall)", + "Bookcase", + "Range", + "Suitcase", + "Bar bottles", + "Arrow game hole (west)", + "Arrow game hole (east)", + "Vitreous goo gfx", + "Fake pressure plate", + "Medusa head", + "4-way shooter block", + "Pit", + "Wall crack (north)", + "Wall crack (south)", + "Wall crack (west)", + "Wall crack (east)", + "Large decor", + "Water grate (north)", + "Water grate (south)", + "Water grate (west)", + "Water grate (east)", + "Window sunlight", + "Floor sunlight", + "Trinexx's shell", + "Layer 2 mask (full)", + "Boss entrance", + "Minigame chest", + "Ganon door", + "Triforce wall ornament", + "Triforce floor tiles", + "Freezor hole", + "Pile of bones", + "Vitreous goo damage", + "Arrow tile ↑", + "Arrow tile ↓", + "Arrow tile →", + "Nothing", +}; + +static const absl::string_view TileTypeNames[] = { + "$00 Nothing (standard floor)", + "$01 Collision", + "$02 Collision", + "$03 Collision", + "$04 Collision", + "$05 Nothing (unused?)", + "$06 Nothing (unused?)", + "$07 Nothing (unused?)", + "$08 Deep water", + "$09 Shallow water", + "$0A Unknown? Possibly unused", + "$0B Collision (different in Overworld and unknown)", + "$0C Overlay mask", + "$0D Spike floor", + "$0E GT ice", + "$0F Ice palace ice", + "$10 Slope ◤", + "$11 Slope ◥", + "$12 Slope ◣", + "$13 Slope ◢", + "$14 Nothing (unused?)", + "$15 Nothing (unused?)", + "$16 Nothing (unused?)", + "$17 Nothing (unused?)", + "$18 Slope ◤", + "$19 Slope ◥", + "$1A Slope ◣", + "$1B Slope ◢", + "$1C Layer 2 overlay", + "$1D North single-layer auto stairs", + "$1E North layer-swap auto stairs", + "$1F North layer-swap auto stairs", + "$20 Pit", + "$21 Nothing (unused?)", + "$22 Manual stairs", + "$23 Pot switch", + "$24 Pressure switch", + "$25 Nothing (unused but referenced by somaria blocks)", + "$26 Collision (near stairs?)", + "$27 Brazier/Fence/Statue/Block/General hookable things", + "$28 North ledge", + "$29 South ledge", + "$2A East ledge", + "$2B West ledge", + "$2C ◤ ledge", + "$2D ◣ ledge", + "$2E ◥ ledge", + "$2F ◢ ledge", + "$30 Straight inter-room stairs south/up 0", + "$31 Straight inter-room stairs south/up 1", + "$32 Straight inter-room stairs south/up 2", + "$33 Straight inter-room stairs south/up 3", + "$34 Straight inter-room stairs north/down 0", + "$35 Straight inter-room stairs north/down 1", + "$36 Straight inter-room stairs north/down 2", + "$37 Straight inter-room stairs north/down 3", + "$38 Straight inter-room stairs north/down edge", + "$39 Straight inter-room stairs south/up edge", + "$3A Star tile (inactive on load)", + "$3B Star tile (active on load)", + "$3C Nothing (unused?)", + "$3D South single-layer auto stairs", + "$3E South layer-swap auto stairs", + "$3F South layer-swap auto stairs", + "$40 Thick grass", + "$41 Nothing (unused?)", + "$42 Gravestone / Tower of hera ledge shadows??", + "$43 Skull Woods entrance/Hera columns???", + "$44 Spike", + "$45 Nothing (unused?)", + "$46 Desert Tablet", + "$47 Nothing (unused?)", + "$48 Diggable ground", + "$49 Nothing (unused?)", + "$4A Diggable ground", + "$4B Warp tile", + "$4C Nothing (unused?) | Something unknown in overworld", + "$4D Nothing (unused?) | Something unknown in overworld", + "$4E Square corners in EP overworld", + "$4F Square corners in EP overworld", + "$50 Green bush", + "$51 Dark bush", + "$52 Gray rock", + "$53 Black rock", + "$54 Hint tile/Sign", + "$55 Big gray rock", + "$56 Big black rock", + "$57 Bonk rocks", + "$58 Chest 0", + "$59 Chest 1", + "$5A Chest 2", + "$5B Chest 3", + "$5C Chest 4", + "$5D Chest 5", + "$5E Spiral stairs", + "$5F Spiral stairs", + "$60 Rupee tile", + "$61 Nothing (unused?)", + "$62 Bombable floor", + "$63 Minigame chest", + "$64 Nothing (unused?)", + "$65 Nothing (unused?)", + "$66 Crystal peg down", + "$67 Crystal peg up", + "$68 Upwards conveyor", + "$69 Downwards conveyor", + "$6A Leftwards conveyor", + "$6B Rightwards conveyor", + "$6C North vines", + "$6D South vines", + "$6E West vines", + "$6F East vines", + "$70 Pot/Hammer peg/Push block 00", + "$71 Pot/Hammer peg/Push block 01", + "$72 Pot/Hammer peg/Push block 02", + "$73 Pot/Hammer peg/Push block 03", + "$74 Pot/Hammer peg/Push block 04", + "$75 Pot/Hammer peg/Push block 05", + "$76 Pot/Hammer peg/Push block 06", + "$77 Pot/Hammer peg/Push block 07", + "$78 Pot/Hammer peg/Push block 08", + "$79 Pot/Hammer peg/Push block 09", + "$7A Pot/Hammer peg/Push block 0A", + "$7B Pot/Hammer peg/Push block 0B", + "$7C Pot/Hammer peg/Push block 0C", + "$7D Pot/Hammer peg/Push block 0D", + "$7E Pot/Hammer peg/Push block 0E", + "$7F Pot/Hammer peg/Push block 0F", + "$80 North/South door", + "$81 East/West door", + "$82 North/South shutter door", + "$83 East/West shutter door", + "$84 North/South layer 2 door", + "$85 East/West layer 2 door", + "$86 North/South layer 2 shutter door", + "$87 East/West layer 2 shutter door", + "$88 Some type of door (?)", + "$89 East/West transport door", + "$8A Some type of door (?)", + "$8B Some type of door (?)", + "$8C Some type of door (?)", + "$8D Some type of door (?)", + "$8E Entrance door", + "$8F Entrance door", + "$90 Layer toggle shutter door (?)", + "$91 Layer toggle shutter door (?)", + "$92 Layer toggle shutter door (?)", + "$93 Layer toggle shutter door (?)", + "$94 Layer toggle shutter door (?)", + "$95 Layer toggle shutter door (?)", + "$96 Layer toggle shutter door (?)", + "$97 Layer toggle shutter door (?)", + "$98 Layer+Dungeon toggle shutter door (?)", + "$99 Layer+Dungeon toggle shutter door (?)", + "$9A Layer+Dungeon toggle shutter door (?)", + "$9B Layer+Dungeon toggle shutter door (?)", + "$9C Layer+Dungeon toggle shutter door (?)", + "$9D Layer+Dungeon toggle shutter door (?)", + "$9E Layer+Dungeon toggle shutter door (?)", + "$9F Layer+Dungeon toggle shutter door (?)", + "$A0 North/South Dungeon swap door", + "$A1 Dungeon toggle door (?)", + "$A2 Dungeon toggle door (?)", + "$A3 Dungeon toggle door (?)", + "$A4 Dungeon toggle door (?)", + "$A5 Dungeon toggle door (?)", + "$A6 Nothing (unused?)", + "$A7 Nothing (unused?)", + "$A8 Layer+Dungeon toggle shutter door (?)", + "$A9 Layer+Dungeon toggle shutter door (?)", + "$AA Layer+Dungeon toggle shutter door (?)", + "$AB Layer+Dungeon toggle shutter door (?)", + "$AC Layer+Dungeon toggle shutter door (?)", + "$AD Layer+Dungeon toggle shutter door (?)", + "$AE Layer+Dungeon toggle shutter door (?)", + "$AF Layer+Dungeon toggle shutter door (?)", + "$B0 Somaria ─", + "$B1 Somaria │", + "$B2 Somaria ┌", + "$B3 Somaria └", + "$B4 Somaria ┐", + "$B5 Somaria ┘", + "$B6 Somaria ⍰ 1 way", + "$B7 Somaria ┬", + "$B8 Somaria ┴", + "$B9 Somaria ├", + "$BA Somaria ┤", + "$BB Somaria ┼", + "$BC Somaria ⍰ 2 way", + "$BD Somaria ┼ crossover", + "$BE Pipe entrance", + "$BF Nothing (unused?)", + "$C0 Torch 00", + "$C1 Torch 01", + "$C2 Torch 02", + "$C3 Torch 03", + "$C4 Torch 04", + "$C5 Torch 05", + "$C6 Torch 06", + "$C7 Torch 07", + "$C8 Torch 08", + "$C9 Torch 09", + "$CA Torch 0A", + "$CB Torch 0B", + "$CC Torch 0C", + "$CD Torch 0D", + "$CE Torch 0E", + "$CF Torch 0F", + "$D0 Nothing (unused?)", + "$D1 Nothing (unused?)", + "$D2 Nothing (unused?)", + "$D3 Nothing (unused?)", + "$D4 Nothing (unused?)", + "$D5 Nothing (unused?)", + "$D6 Nothing (unused?)", + "$D7 Nothing (unused?)", + "$D8 Nothing (unused?)", + "$D9 Nothing (unused?)", + "$DA Nothing (unused?)", + "$DB Nothing (unused?)", + "$DC Nothing (unused?)", + "$DD Nothing (unused?)", + "$DE Nothing (unused?)", + "$DF Nothing (unused?)", + "$E0 Nothing (unused?)", + "$E1 Nothing (unused?)", + "$E2 Nothing (unused?)", + "$E3 Nothing (unused?)", + "$E4 Nothing (unused?)", + "$E5 Nothing (unused?)", + "$E6 Nothing (unused?)", + "$E7 Nothing (unused?)", + "$E8 Nothing (unused?)", + "$E9 Nothing (unused?)", + "$EA Nothing (unused?)", + "$EB Nothing (unused?)", + "$EC Nothing (unused?)", + "$ED Nothing (unused?)", + "$EE Nothing (unused?)", + "$EF Nothing (unused?)", + "$F0 Door 0 bottom", + "$F1 Door 1 bottom", + "$F2 Door 2 bottom", + "$F3 Door 3 bottom", + "$F4 Door X bottom? (unused?)", + "$F5 Door X bottom? (unused?)", + "$F6 Door X bottom? (unused?)", + "$F7 Door X bottom? (unused?)", + "$F8 Door 0 top", + "$F9 Door 1 top", + "$FA Door 2 top", + "$FB Door 3 top", + "$FC Door X top? (unused?)", + "$FD Door X top? (unused?)", + "$FE Door X top? (unused?)", + "$FF Door X top? (unused?)"}; + +static const absl::string_view kSpriteDefaultNames[]{ + "00 Raven", + "01 Vulture", + "02 Flying Stalfos Head", + "03 No Pointer (Empty", + "04 Pull Switch (good", + "05 Pull Switch (unused", + "06 Pull Switch (bad", + "07 Pull Switch (unused", + "08 Octorock (one way", + "09 Moldorm (Boss", + "0A Octorock (four way", + "0B Chicken", + "0C Octorock (?", + "0D Buzzblock", + "0E Snapdragon", + "0F Octoballoon", + "10 Octoballon Hatchlings", + "11 Hinox", + "12 Moblin", + "13 Mini Helmasaure", + "14 Gargoyle's Domain Gate", + "15 Antifairy", + "16 Sahasrahla / Aginah", + "17 Bush Hoarder", + "18 Mini Moldorm", + "19 Poe", + "1A Dwarves", + "1B Arrow in wall", + "1C Statue", + "1D Weathervane", + "1E Crystal Switch", + "1F Bug-Catching Kid", + "20 Sluggula", + "21 Push Switch", + "22 Ropa", + "23 Red Bari", + "24 Blue Bari", + "25 Talking Tree", + "26 Hardhat Beetle", + "27 Deadrock", + "28 Storytellers", + "29 Blind Hideout attendant", + "2A Sweeping Lady", + "2B Storytellers", + "2C Lumberjacks", + "2D Telepathic Stones", + "2E Multipurpose Sprite", + "2F Race Npc", + "30 Person?", + "31 Fortune Teller", + "32 Angry Brothers", + "33 Pull for items", + "34 Scared Girl", + "35 Innkeeper", + "36 Witch", + "37 Waterfall", + "38 Arrow Target", + "39 Average Middle", + "3A Half Magic Bat", + "3B Dash Item", + "3C Village Kid", + "3D Signs? Chicken lady also showed up / Scared ladies outside houses.", + "3E Rock Hoarder", + "3F Tutorial Soldier", + "40 Lightning Lock", + "41 Blue Sword Soldier / Used by guards to detect player", + "42 Green Sword Soldier", + "43 Red Spear Soldier", + "44 Assault Sword Soldier", + "45 Green Spear Soldier", + "46 Blue Archer", + "47 Green Archer", + "48 Red Javelin Soldier", + "49 Red Javelin Soldier 2", + "4A Red Bomb Soldiers", + "4B Green Soldier Recruits", + "4C Geldman", + "4D Rabbit", + "4E Popo", + "4F Popo 2", + "50 Cannon Balls", + "51 Armos", + "52 Giant Zora", + "53 Armos Knights (Boss", + "54 Lanmolas (Boss", + "55 Fireball Zora", + "56 Walking Zora", + "57 Desert Palace Barriers", + "58 Crab", + "59 Bird", + "5A Squirrel", + "5B Spark (Left to Right", + "5C Spark (Right to Left", + "5D Roller (vertical moving", + "5E Roller (vertical moving", + "5F Roller", + "60 Roller (horizontal moving", + "61 Beamos", + "62 Master Sword", + "63 Devalant (Non", + "64 Devalant (Shooter", + "65 Shooting Gallery Proprietor", + "66 Moving Cannon Ball Shooters (Right", + "67 Moving Cannon Ball Shooters (Left", + "68 Moving Cannon Ball Shooters (Down", + "69 Moving Cannon Ball Shooters (Up", + "6A Ball N' Chain Trooper", + "6B Cannon Soldier", + "6C Mirror Portal", + "6D Rat", + "6E Rope", + "6F Keese", + "70 Helmasaur King Fireball", + "71 Leever", + "72 Activator for the ponds (where you throw in items", + "73 Uncle / Priest", + "74 Running Man", + "75 Bottle Salesman", + "76 Princess Zelda", + "77 Antifairy (Alternate", + "78 Village Elder", + "79 Bee", + "7A Agahnim", + "7B Agahnim Energy Ball", + "7C Hyu", + "7D Big Spike Trap", + "7E Guruguru Bar (Clockwise", + "7F Guruguru Bar (Counter Clockwise", + "80 Winder", + "81 Water Tektite", + "82 Antifairy Circle", + "83 Green Eyegore", + "84 Red Eyegore", + "85 Yellow Stalfos", + "86 Kodongos", + "87 Flames", + "88 Mothula (Boss", + "89 Mothula's Beam", + "8A Spike Trap", + "8B Gibdo", + "8C Arrghus (Boss", + "8D Arrghus spawn", + "8E Terrorpin", + "8F Slime", + "90 Wallmaster", + "91 Stalfos Knight", + "92 Helmasaur King", + "93 Bumper", + "94 Swimmers", + "95 Eye Laser (Right", + "96 Eye Laser (Left", + "97 Eye Laser (Down", + "98 Eye Laser (Up", + "99 Pengator", + "9A Kyameron", + "9B Wizzrobe", + "9C Tadpoles", + "9D Tadpoles", + "9E Ostrich (Haunted Grove", + "9F Flute", + "A0 Birds (Haunted Grove", + "A1 Freezor", + "A2 Kholdstare (Boss", + "A3 Kholdstare's Shell", + "A4 Falling Ice", + "A5 Zazak Fireball", + "A6 Red Zazak", + "A7 Stalfos", + "A8 Bomber Flying Creatures from Darkworld", + "A9 Bomber Flying Creatures from Darkworld", + "AA Pikit", + "AB Maiden", + "AC Apple", + "AD Lost Old Man", + "AE Down Pipe", + "AF Up Pipe", + "B0 Right Pip", + "B1 Left Pipe", + "B2 Good bee again?", + "B3 Hylian Inscription", + "B4 Thief?s chest (not the one that follows you", + "B5 Bomb Salesman", + "B6 Kiki", + "B7 Maiden following you in Blind Dungeon", + "B8 Monologue Testing Sprite", + "B9 Feuding Friends on Death Mountain", + "BA Whirlpool", + "BB Salesman / chestgame guy / 300 rupee giver guy / Chest game thief", + "BC Drunk in the inn", + "BD Vitreous (Large Eyeball", + "BE Vitreous (Small Eyeball", + "BF Vitreous' Lightning", + "C0 Monster in Lake of Ill Omen / Quake Medallion", + "C1 Agahnim teleporting Zelda to dark world", + "C2 Boulders", + "C3 Gibo", + "C4 Thief", + "C5 Medusa", + "C6 Four Way Fireball Spitters (spit when you use your sword", + "C7 Hokku", + "C8 Big Fairy who heals you", + "C9 Tektite", + "CA Chain Chomp", + "CB Trinexx", + "CC Another part of trinexx", + "CD Yet another part of trinexx", + "CE Blind The Thief (Boss)", + "CF Swamola", + "D0 Lynel", + "D1 Bunny Beam", + "D2 Flopping fish", + "D3 Stal", + "D4 Landmine", + "D5 Digging Game Proprietor", + "D6 Ganon", + "D7 Copy of Ganon", + "D8 Heart", + "D9 Green Rupee", + "DA Blue Rupee", + "DB Red Rupee", + "DC Bomb Refill (1)", + "DD Bomb Refill (4)", + "DE Bomb Refill (8)", + "DF Small Magic Refill", + "E0 Full Magic Refill", + "E1 Arrow Refill (5)", + "E2 Arrow Refill (10)", + "E3 Fairy", + "E4 Key", + "E5 Big Key", + "E6 Shield", + "E7 Mushroom", + "E8 Fake Master Sword", + "E9 Magic Shop dude / His items", + "EA Heart Container", + "EB Heart Piece", + "EC Bushes", + "ED Cane Of Somaria Platform", + "EE Mantle", + "EF Cane of Somaria Platform (Unused)", + "F0 Cane of Somaria Platform (Unused)", + "F1 Cane of Somaria Platform (Unused)", + "F2 Medallion Tablet", + "F3", + "F4 Falling Rocks", + "F5", + "F6", + "F7", + "F8", + "F9", + "FA", + "FB", + "FC", + "FD", + "FE", + "FF", +}; + +static const absl::string_view overlordnames[] = { + "Overlord_SpritePositionTarget", + "Overlord_AllDirectionMetalBallFactory", + "Overlord_CascadeMetalBallFactory", + "Overlord_StalfosFactory", + "Overlord_StalfosTrap", + "Overlord_SnakeTrap", + "Overlord_MovingFloor", + "Overlord_ZolFactory", + "Overlord_WallMasterFactory", + "Overlord_CrumbleTilePath 1", + "Overlord_CrumbleTilePath 2", + "Overlord_CrumbleTilePath 3", + "Overlord_CrumbleTilePath 4", + "Overlord_CrumbleTilePath 5", + "Overlord_CrumbleTilePath 6", + "Overlord_PirogusuFactory 1", + "Overlord_PirogusuFactory 2", + "Overlord_PirogusuFactory 3", + "Overlord_PirogusuFactory 4", + "Overlord_FlyingTileFactory", + "Overlord_WizzrobeFactory", + "Overlord_ZoroFactory", + "Overlord_StalfosTrapTriggerWindow", + "Overlord_RedStalfosTrap", + "Overlord_ArmosCoordinator", + "Overlord_BombTrap", +}; + +} // namespace core +} // namespace app +} // namespace yaze + +#endif \ No newline at end of file diff --git a/src/app/core/controller.cc b/src/app/core/controller.cc new file mode 100644 index 00000000..65b66100 --- /dev/null +++ b/src/app/core/controller.cc @@ -0,0 +1,229 @@ +#include "controller.h" + +#include +#include +#include +#include +#include +#include + +#include + +#include "absl/status/status.h" +#include "absl/strings/str_format.h" +#include "app/editor/master_editor.h" +#include "gui/icons.h" +#include "gui/style.h" + +namespace yaze { +namespace app { +namespace core { + +namespace { + +void InitializeKeymap() { + ImGuiIO &io = ImGui::GetIO(); + io.KeyMap[ImGuiKey_Backspace] = SDL_GetScancodeFromKey(SDLK_BACKSPACE); + io.KeyMap[ImGuiKey_LeftShift] = SDL_GetScancodeFromKey(SDLK_LSHIFT); + io.KeyMap[ImGuiKey_Enter] = SDL_GetScancodeFromKey(SDLK_RETURN); + io.KeyMap[ImGuiKey_UpArrow] = SDL_GetScancodeFromKey(SDLK_UP); + io.KeyMap[ImGuiKey_DownArrow] = SDL_GetScancodeFromKey(SDLK_DOWN); + io.KeyMap[ImGuiKey_Tab] = SDL_GetScancodeFromKey(SDLK_TAB); + io.KeyMap[ImGuiKey_LeftCtrl] = SDL_GetScancodeFromKey(SDLK_LCTRL); +} + +void HandleKeyDown(SDL_Event &event) { + ImGuiIO &io = ImGui::GetIO(); + switch (event.key.keysym.sym) { + case SDLK_UP: + case SDLK_DOWN: + case SDLK_RETURN: + case SDLK_BACKSPACE: + case SDLK_LSHIFT: + case SDLK_LCTRL: + case SDLK_TAB: + io.KeysDown[event.key.keysym.scancode] = (event.type == SDL_KEYDOWN); + break; + default: + break; + } +} + +void HandleKeyUp(SDL_Event &event) { + ImGuiIO &io = ImGui::GetIO(); + int key = event.key.keysym.scancode; + IM_ASSERT(key >= 0 && key < IM_ARRAYSIZE(io.KeysDown)); + io.KeysDown[key] = (event.type == SDL_KEYDOWN); + io.KeyShift = ((SDL_GetModState() & KMOD_SHIFT) != 0); + io.KeyCtrl = ((SDL_GetModState() & KMOD_CTRL) != 0); + io.KeyAlt = ((SDL_GetModState() & KMOD_ALT) != 0); + io.KeySuper = ((SDL_GetModState() & KMOD_GUI) != 0); +} + +void ChangeWindowSizeEvent(SDL_Event &event) { + ImGuiIO &io = ImGui::GetIO(); + io.DisplaySize.x = static_cast(event.window.data1); + io.DisplaySize.y = static_cast(event.window.data2); +} + +void HandleMouseMovement(int &wheel) { + ImGuiIO &io = ImGui::GetIO(); + int mouseX; + int mouseY; + const int buttons = SDL_GetMouseState(&mouseX, &mouseY); + + io.DeltaTime = 1.0f / 60.0f; + io.MousePos = ImVec2(static_cast(mouseX), static_cast(mouseY)); + io.MouseDown[0] = buttons & SDL_BUTTON(SDL_BUTTON_LEFT); + io.MouseDown[1] = buttons & SDL_BUTTON(SDL_BUTTON_RIGHT); + io.MouseWheel = static_cast(wheel); +} + +} // namespace + +bool Controller::isActive() const { return active_; } + +absl::Status Controller::onEntry() { + RETURN_IF_ERROR(CreateWindow()) + RETURN_IF_ERROR(CreateRenderer()) + RETURN_IF_ERROR(CreateGuiContext()) + InitializeKeymap(); + master_editor_.SetupScreen(renderer_); + active_ = true; + return absl::OkStatus(); +} + +void Controller::onInput() { + int wheel = 0; + SDL_Event event; + ImGuiIO &io = ImGui::GetIO(); + + while (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_KEYDOWN: + HandleKeyDown(event); + break; + case SDL_KEYUP: + HandleKeyUp(event); + break; + case SDL_TEXTINPUT: + io.AddInputCharactersUTF8(event.text.text); + break; + case SDL_MOUSEWHEEL: + wheel = event.wheel.y; + break; + case SDL_WINDOWEVENT: + switch (event.window.event) { + case SDL_WINDOWEVENT_CLOSE: + CloseWindow(); + break; + case SDL_WINDOWEVENT_SIZE_CHANGED: + ChangeWindowSizeEvent(event); + break; + default: + break; + } + break; + + default: + break; + } + } + + HandleMouseMovement(wheel); +} + +void Controller::onLoad() { master_editor_.UpdateScreen(); } + +void Controller::doRender() const { + SDL_RenderClear(renderer_.get()); + ImGui::Render(); + ImGui_ImplSDLRenderer_RenderDrawData(ImGui::GetDrawData()); + SDL_RenderPresent(renderer_.get()); +} + +void Controller::onExit() const { + ImGui_ImplSDLRenderer_Shutdown(); + ImGui_ImplSDL2_Shutdown(); + ImGui::DestroyContext(); + SDL_Quit(); +} + +absl::Status Controller::CreateWindow() { + if (SDL_Init(SDL_INIT_EVERYTHING) != 0) { + return absl::InternalError( + absl::StrFormat("SDL_Init: %s\n", SDL_GetError())); + } else { + window_ = std::unique_ptr( + SDL_CreateWindow("Yet Another Zelda3 Editor", // window title + SDL_WINDOWPOS_UNDEFINED, // initial x position + SDL_WINDOWPOS_UNDEFINED, // initial y position + kScreenWidth, // width, in pixels + kScreenHeight, // height, in pixels + SDL_WINDOW_RESIZABLE), + sdl_deleter()); + if (window_ == nullptr) { + return absl::InternalError( + absl::StrFormat("SDL_CreateWindow: %s\n", SDL_GetError())); + } + // Initialize SDL_mixer + if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) < 0) { + printf("SDL_mixer could not initialize! SDL_mixer Error: %s\n", + Mix_GetError()); + } + } + return absl::OkStatus(); +} + +absl::Status Controller::CreateRenderer() { + renderer_ = std::unique_ptr( + SDL_CreateRenderer(window_.get(), -1, + SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC), + sdl_deleter()); + if (renderer_ == nullptr) { + return absl::InternalError( + absl::StrFormat("SDL_CreateRenderer: %s\n", SDL_GetError())); + } else { + SDL_SetRenderDrawBlendMode(renderer_.get(), SDL_BLENDMODE_BLEND); + SDL_SetRenderDrawColor(renderer_.get(), 0x00, 0x00, 0x00, 0x00); + } + return absl::OkStatus(); +} + +absl::Status Controller::CreateGuiContext() { + ImGui::CreateContext(); + + // Initialize ImGui for SDL + ImGui_ImplSDL2_InitForSDLRenderer(window_.get(), renderer_.get()); + ImGui_ImplSDLRenderer_Init(renderer_.get()); + + // Load available fonts + const ImGuiIO &io = ImGui::GetIO(); + io.Fonts->AddFontFromFileTTF("assets/font/Karla-Regular.ttf", 14.0f); + + // merge in icons from Google Material Design + static const ImWchar icons_ranges[] = {ICON_MIN_MD, 0xf900, 0}; + ImFontConfig icons_config; + icons_config.MergeMode = true; + icons_config.GlyphOffset.y = 5.0f; + icons_config.GlyphMinAdvanceX = 13.0f; + icons_config.PixelSnapH = true; + io.Fonts->AddFontFromFileTTF(FONT_ICON_FILE_NAME_MD, 18.0f, &icons_config, + icons_ranges); + io.Fonts->AddFontFromFileTTF("assets/font/Roboto-Medium.ttf", 14.0f); + io.Fonts->AddFontFromFileTTF("assets/font/Cousine-Regular.ttf", 14.0f); + io.Fonts->AddFontFromFileTTF("assets/font/DroidSans.ttf", 16.0f); + + // Set the default style + gui::ColorsYaze(); + + // Build a new ImGui frame + ImGui_ImplSDLRenderer_NewFrame(); + ImGui_ImplSDL2_NewFrame(window_.get()); + + return absl::OkStatus(); +} + +} // namespace core +} // namespace app +} // namespace yaze \ No newline at end of file diff --git a/src/app/core/controller.h b/src/app/core/controller.h new file mode 100644 index 00000000..ba5af3e4 --- /dev/null +++ b/src/app/core/controller.h @@ -0,0 +1,57 @@ +#ifndef YAZE_APP_CORE_CONTROLLER_H +#define YAZE_APP_CORE_CONTROLLER_H + +#include +#include +#include +#include +#include + +#include + +#include "absl/status/status.h" +#include "app/editor/master_editor.h" +#include "gui/icons.h" +#include "gui/style.h" + +int main(int argc, char **argv); + +namespace yaze { +namespace app { +namespace core { + +class Controller { + public: + bool isActive() const; + absl::Status onEntry(); + void onInput(); + void onLoad(); + void onLoadDelta(); + void doRender() const; + void onExit() const; + + private: + struct sdl_deleter { + void operator()(SDL_Window *p) const { SDL_DestroyWindow(p); } + void operator()(SDL_Renderer *p) const { SDL_DestroyRenderer(p); } + void operator()(SDL_Texture *p) const { SDL_DestroyTexture(p); } + }; + + absl::Status CreateWindow(); + absl::Status CreateRenderer(); + absl::Status CreateGuiContext(); + void CloseWindow() { active_ = false; } + + friend int ::main(int argc, char **argv); + + bool active_; + editor::MasterEditor master_editor_; + std::shared_ptr window_; + std::shared_ptr renderer_; +}; + +} // namespace core +} // namespace app +} // namespace yaze + +#endif // YAZE_APP_CORE_CONTROLLER_H \ No newline at end of file diff --git a/src/app/delta/CMakeLists.txt b/src/app/delta/CMakeLists.txt new file mode 100644 index 00000000..087dd9f7 --- /dev/null +++ b/src/app/delta/CMakeLists.txt @@ -0,0 +1,32 @@ + +add_library(delta-service delta.proto) +target_link_libraries(delta-service + PUBLIC + protobuf::libprotobuf + gRPC::grpc + gRPC::grpc++ +) + +target_include_directories(delta-service + PUBLIC + ${CMAKE_CURRENT_BINARY_DIR} + ${PROTOBUF_INCLUDE_PATH} +) + +get_target_property(grpc_cpp_plugin_location gRPC::grpc_cpp_plugin LOCATION) + +# compile the message types +protobuf_generate(TARGET delta-service LANGUAGE cpp) + +# compile the GRPC services +protobuf_generate( + TARGET + delta-service + LANGUAGE + grpc + GENERATE_EXTENSIONS + .grpc.pb.h + .grpc.pb.cc + PLUGIN + "protoc-gen-grpc=${grpc_cpp_plugin_location}" +) \ No newline at end of file diff --git a/src/app/delta/client.cc b/src/app/delta/client.cc new file mode 100644 index 00000000..4a24a78d --- /dev/null +++ b/src/app/delta/client.cc @@ -0,0 +1,54 @@ +#include "client.h" + +#include +#include +#include +#include +#include + +#include "absl/status/status.h" +#include "src/app/delta/delta.grpc.pb.h" +#include "src/app/delta/delta.pb.h" + +namespace yaze { +namespace app { +namespace delta { + +using grpc::Channel; +using grpc::ClientAsyncResponseReader; +using grpc::ClientContext; +using grpc::CompletionQueue; +using grpc::Server; +using grpc::ServerBuilder; +using grpc::Status; + +void Client::CreateChannel() { + auto channel = grpc::CreateChannel("localhost:50051", + grpc::InsecureChannelCredentials()); + stub_ = ::YazeDelta::NewStub(channel); +} + +absl::Status Client::InitRepo(std::string author_name, + std::string project_name) { + Repository new_repo; + new_repo.set_author_name(author_name); + new_repo.set_project_name(project_name); + new_repo.mutable_tree()->Add(); + + InitRequest request; + request.set_allocated_repo(&new_repo); + + InitResponse response; + Status status = stub_->Init(&rpc_context, request, &response); + + if (!status.ok()) { + std::cerr << status.error_code() << ": " << status.error_message() + << std::endl; + return absl::InternalError(status.error_message()); + } + return absl::OkStatus(); +} + +} // namespace delta +} // namespace app +} // namespace yaze diff --git a/src/app/delta/client.h b/src/app/delta/client.h new file mode 100644 index 00000000..6c3d7f74 --- /dev/null +++ b/src/app/delta/client.h @@ -0,0 +1,44 @@ +#ifndef YAZE_APP_DELTA_CLIENT_H +#define YAZE_APP_DELTA_CLIENT_H + +#include +#include +#include +#include +#include + +#include + +#include "absl/status/status.h" +#include "src/app/delta/delta.grpc.pb.h" +#include "src/app/delta/delta.pb.h" + +namespace yaze { +namespace app { +namespace delta { + +using grpc::Channel; +using grpc::ClientAsyncResponseReader; +using grpc::ClientContext; +using grpc::CompletionQueue; +using grpc::Server; +using grpc::ServerBuilder; +using grpc::Status; + +class Client { + public: + Client() = default; + void CreateChannel(); + absl::Status InitRepo(std::string author_name, std::string project_name); + + private: + ClientContext rpc_context; + std::vector repos_; + std::unique_ptr stub_; +}; + +} // namespace delta +} // namespace app +} // namespace yaze + +#endif \ No newline at end of file diff --git a/src/app/delta/delta.cc b/src/app/delta/delta.cc new file mode 100644 index 00000000..4a413d67 --- /dev/null +++ b/src/app/delta/delta.cc @@ -0,0 +1,32 @@ +#if defined(_WIN32) +#define main SDL_main +#endif + +#include "absl/debugging/failure_signal_handler.h" +#include "absl/debugging/symbolize.h" +#include "app/core/controller.h" +#include "app/delta/viewer.h" + +int main(int argc, char** argv) { + absl::InitializeSymbolizer(argv[0]); + + absl::FailureSignalHandlerOptions options; + absl::InstallFailureSignalHandler(options); + + yaze::app::core::Controller controller; + yaze::app::delta::Viewer viewer; + + auto entry_status = controller.onEntry(); + if (!entry_status.ok()) { + return EXIT_FAILURE; + } + + while (controller.isActive()) { + controller.onInput(); + viewer.Update(); + controller.doRender(); + } + controller.onExit(); + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/src/app/delta/delta.proto b/src/app/delta/delta.proto new file mode 100644 index 00000000..c15090b3 --- /dev/null +++ b/src/app/delta/delta.proto @@ -0,0 +1,105 @@ +syntax = "proto3"; +option cc_enable_arenas = true; + +service YazeDelta { + rpc Init(InitRequest) returns (InitResponse) {} + + rpc Clone(CloneRequest) returns (CloneResponse) {} + + rpc Push(PushRequest) returns (PushResponse) {} + rpc Pull(PullRequest) returns (PullResponse) {} + + rpc Sync(stream SyncRequest) returns (stream SyncResponse) {} + + rpc CreateBranch(CreateBranchRequest) returns (CreateBranchResponse) {} + rpc DeleteBranch(DeleteBranchRequest) returns (DeleteBranchResponse) {} + + rpc Merge(MergeRequest) returns (MergeResponse) {} + rpc UndoMerge(UndoMergeRequest) returns (UndoMergeResponse) {} +} + +enum ChangeType { + OVERWORLD_MAP = 0; + DUNGEON_MAP = 1; + MONOLOGUE = 2; + PALETTE = 3; + OBJECT = 4; + ASSEMBLY = 5; + MISC = 6; +} + +message Delta { + int64 offset = 1; + int64 length = 2; + bytes data = 3; + ChangeType type = 4; +} + +message Commit { + int64 commit_id = 1; + int64 parent_commit_id = 2; + string author_name = 3; + string message_header = 4; + optional string message_body = 5; + repeated Delta delta = 6; + int64 signature = 7; +} + +message Branch { + string branch_name = 1; + optional string parent_name = 2; + repeated Commit commits = 3; +} + +message Repository { + string project_name = 1; + string author_name = 2; + int64 signature = 3; + optional bool locked = 4; + optional string password = 5; + repeated Branch tree = 6; +} + +message InitRequest { + Repository repo = 1; +} + +message InitResponse { + int32 response = 1; +} + +message CloneRequest {} + +message CloneResponse {} + +message PushRequest { + string author_name = 1; + string repository_name= 2; + string branch_name = 3; + repeated Commit commits = 4; +} +message PushResponse {} + +message PullRequest { + string repository_name = 1; + string branch_name = 2; + repeated Commit commits = 3; +} + +message PullResponse {} + +message SyncRequest {} + +message SyncResponse {} + +message CreateBranchRequest {} +message CreateBranchResponse {} + +message DeleteBranchRequest {} +message DeleteBranchResponse {} + +message MergeRequest {} +message MergeResponse {} + +message UndoMergeRequest {} +message UndoMergeResponse {} \ No newline at end of file diff --git a/src/app/delta/service.cc b/src/app/delta/service.cc new file mode 100644 index 00000000..cdfb5504 --- /dev/null +++ b/src/app/delta/service.cc @@ -0,0 +1,87 @@ +#include "service.h" + +#include +#include +#include +#include +#include + +#include + +#include "absl/status/status.h" +#include "absl/status/statusor.h" +#include "src/app/delta/delta.grpc.pb.h" +#include "src/app/delta/delta.pb.h" + +namespace yaze { +namespace app { +namespace delta { + +using grpc::Channel; +using grpc::ClientAsyncResponseReader; +using grpc::ClientContext; +using grpc::CompletionQueue; +using grpc::Server; +using grpc::ServerBuilder; +using grpc::Status; + +namespace { +auto FindRepository(std::vector& repos, const std::string& name) { + for (auto& repo : repos) { + if (repo.project_name() == name) { + return repo.mutable_tree(); + } + } +} + +auto FindBranch(google::protobuf::RepeatedPtrField* repo, + const std::string& branch_name) { + for (auto it = repo->begin(); it != repo->end(); ++it) { + if (it->branch_name() == branch_name) { + return it->mutable_commits(); + } + } +} +} // namespace + +Status DeltaService::Init(grpc::ServerContext* context, + const InitRequest* request, InitResponse* reply) { + std::filesystem::create_directories("./.yaze"); + repos_.push_back(request->repo()); + // std::ofstream commit_stream("./.yaze/commits"); + // for (const auto& repo : repos_) { + // for (const auto& branch : repo.tree()) { + // for (const auto& commit : branch.commits()) { + // commit_stream << commit.DebugString(); + // } + // } + // } + return Status::OK; +} + +Status DeltaService::Push(grpc::ServerContext* context, + const PushRequest* request, PushResponse* reply) { + const auto& repository_name = request->repository_name(); + const auto& branch_name = request->branch_name(); + auto repo = FindRepository(repos_, repository_name); + auto mutable_commits = FindBranch(repo, branch_name); + auto size = request->commits().size(); + for (int i = 1; i < size; ++i) { + *mutable_commits->Add() = request->commits().at(i); + } + return Status::OK; +} + +Status DeltaService::Pull(grpc::ServerContext* context, + const PullRequest* request, PullResponse* reply) { + return Status::OK; +} + +Status DeltaService::Clone(grpc::ServerContext* context, + const CloneRequest* request, CloneResponse* reply) { + return Status::OK; +} + +} // namespace delta +} // namespace app +} // namespace yaze diff --git a/src/app/delta/service.h b/src/app/delta/service.h new file mode 100644 index 00000000..d986def7 --- /dev/null +++ b/src/app/delta/service.h @@ -0,0 +1,48 @@ +#ifndef YAZE_APP_DELTA_SERVICE_H +#define YAZE_APP_DELTA_SERVICE_H + +#include + +#include +#include +#include +#include +#include + +#include + +#include "absl/status/status.h" +#include "src/app/delta/delta.grpc.pb.h" +#include "src/app/delta/delta.pb.h" + +namespace yaze { +namespace app { +namespace delta { + +using grpc::Status; + +class DeltaService final : public ::YazeDelta::Service { + public: + Status Init(grpc::ServerContext* context, const InitRequest* request, + InitResponse* reply) override; + + Status Push(grpc::ServerContext* context, const PushRequest* request, + PushResponse* reply) override; + + Status Pull(grpc::ServerContext* context, const PullRequest* request, + PullResponse* reply) override; + + Status Clone(grpc::ServerContext* context, const CloneRequest* request, + CloneResponse* reply) override; + + auto Repos() const { return repos_; } + + private: + std::vector repos_; +}; + +} // namespace delta +} // namespace app +} // namespace yaze + +#endif \ No newline at end of file diff --git a/src/app/delta/viewer.cc b/src/app/delta/viewer.cc new file mode 100644 index 00000000..c3848ebe --- /dev/null +++ b/src/app/delta/viewer.cc @@ -0,0 +1,229 @@ +#include "viewer.h" + +#include +#include +#include +#include +#include + +#include "absl/status/status.h" +#include "app/core/constants.h" +#include "app/gfx/snes_palette.h" +#include "app/gfx/snes_tile.h" +#include "app/rom.h" +#include "gui/canvas.h" +#include "gui/icons.h" +#include "gui/input.h" + +namespace yaze { +namespace app { +namespace delta { +namespace { + +constexpr ImGuiWindowFlags kMainEditorFlags = + ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse | + ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_MenuBar | + ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoTitleBar; + +void NewMasterFrame() { + const ImGuiIO& io = ImGui::GetIO(); + ImGui::NewFrame(); + ImGui::SetNextWindowPos(ImVec2(0, 0)); + ImVec2 dimensions(io.DisplaySize.x, io.DisplaySize.y); + ImGui::SetNextWindowSize(dimensions, ImGuiCond_Always); + + if (!ImGui::Begin("##YazeMain", nullptr, kMainEditorFlags)) { + ImGui::End(); + return; + } +} + +} // namespace + +void Viewer::Update() { + NewMasterFrame(); + DrawYazeMenu(); + DrawFileDialog(); + + ImGui::Text(ICON_MD_CHANGE_HISTORY); + ImGui::SameLine(); + ImGui::Text("%s", rom_.GetTitle()); + + ImGui::Separator(); + + ImGui::Button(ICON_MD_SYNC); + ImGui::SameLine(); + ImGui::Button(ICON_MD_ARROW_UPWARD); + ImGui::SameLine(); + ImGui::Button(ICON_MD_ARROW_DOWNWARD); + ImGui::SameLine(); + ImGui::Button(ICON_MD_MERGE); + ImGui::SameLine(); + + ImGui::Button(ICON_MD_MANAGE_HISTORY); + ImGui::SameLine(); + ImGui::Button(ICON_MD_LAN); + ImGui::SameLine(); + ImGui::Button(ICON_MD_COMMIT); + ImGui::SameLine(); + ImGui::Button(ICON_MD_DIFFERENCE); + + ImGui::Separator(); + + ImGui::SetNextItemWidth(75.f); + ImGui::Button(ICON_MD_SEND); + ImGui::SameLine(); + ImGui::InputText("Server Address", &client_address_); + + ImGui::SetNextItemWidth(75.f); + ImGui::Button(ICON_MD_DOWNLOAD); + ImGui::SameLine(); + ImGui::InputText("Repository Source", &client_address_); + + ImGui::Separator(); + DrawBranchTree(); + ImGui::End(); +} + +void Viewer::DrawFileDialog() { + if (ImGuiFileDialog::Instance()->Display("ChooseFileDlgKey")) { + if (ImGuiFileDialog::Instance()->IsOk()) { + std::string filePathName = ImGuiFileDialog::Instance()->GetFilePathName(); + rom_.LoadFromFile(filePathName); + } + ImGuiFileDialog::Instance()->Close(); + } +} + +void Viewer::DrawYazeMenu() { + MENU_BAR() + DrawFileMenu(); + DrawViewMenu(); + END_MENU_BAR() +} + +void Viewer::DrawFileMenu() const { + if (ImGui::BeginMenu("File")) { + if (ImGui::MenuItem("Open", "Ctrl+O")) { + ImGuiFileDialog::Instance()->OpenDialog("ChooseFileDlgKey", "Open ROM", + ".sfc,.smc", "."); + } + + MENU_ITEM2("Save", "Ctrl+S") {} + + ImGui::EndMenu(); + } +} + +void Viewer::DrawViewMenu() { + static bool show_imgui_metrics = false; + static bool show_imgui_style_editor = false; + static bool show_memory_editor = false; + static bool show_imgui_demo = false; + + if (show_imgui_metrics) { + ImGui::ShowMetricsWindow(&show_imgui_metrics); + } + + if (show_memory_editor) { + static MemoryEditor mem_edit; + mem_edit.DrawWindow("Memory Editor", (void*)&rom_, rom_.size()); + } + + if (show_imgui_demo) { + ImGui::ShowDemoWindow(); + } + + if (show_imgui_style_editor) { + ImGui::Begin("Style Editor (ImGui)", &show_imgui_style_editor); + ImGui::ShowStyleEditor(); + ImGui::End(); + } + + if (ImGui::BeginMenu("View")) { + ImGui::MenuItem("HEX Editor", nullptr, &show_memory_editor); + ImGui::MenuItem("ImGui Demo", nullptr, &show_imgui_demo); + ImGui::Separator(); + if (ImGui::BeginMenu("GUI Tools")) { + ImGui::MenuItem("Metrics (ImGui)", nullptr, &show_imgui_metrics); + ImGui::MenuItem("Style Editor (ImGui)", nullptr, + &show_imgui_style_editor); + ImGui::EndMenu(); + } + ImGui::EndMenu(); + } +} + +void Viewer::DrawBranchTree() { + static ImGuiTableFlags flags = + ImGuiTableFlags_BordersV | ImGuiTableFlags_BordersOuterH | + ImGuiTableFlags_Resizable | ImGuiTableFlags_RowBg | + ImGuiTableFlags_NoBordersInBody; + + if (ImGui::BeginTable("3ways", 3, flags)) { + // The first column will use the default _WidthStretch when ScrollX is Off + // and _WidthFixed when ScrollX is On + ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_NoHide); + ImGui::TableSetupColumn("Size", ImGuiTableColumnFlags_WidthFixed, + 10 * 12.0f); + ImGui::TableSetupColumn("Type", ImGuiTableColumnFlags_WidthFixed, + 10 * 18.0f); + ImGui::TableHeadersRow(); + + // Simple storage to output a dummy file-system. + struct MyTreeNode { + const char* Name; + const char* Type; + int Size; + int ChildIdx; + int ChildCount; + static void DisplayNode(const MyTreeNode* node, + const MyTreeNode* all_nodes) { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + const bool is_folder = (node->ChildCount > 0); + if (is_folder) { + bool open = + ImGui::TreeNodeEx(node->Name, ImGuiTreeNodeFlags_SpanFullWidth); + ImGui::TableNextColumn(); + ImGui::TextDisabled("--"); + ImGui::TableNextColumn(); + ImGui::TextUnformatted(node->Type); + if (open) { + for (int child_n = 0; child_n < node->ChildCount; child_n++) + DisplayNode(&all_nodes[node->ChildIdx + child_n], all_nodes); + ImGui::TreePop(); + } + } else { + ImGui::TreeNodeEx( + node->Name, ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_Bullet | + ImGuiTreeNodeFlags_NoTreePushOnOpen | + ImGuiTreeNodeFlags_SpanFullWidth); + ImGui::TableNextColumn(); + ImGui::Text("%d", node->Size); + ImGui::TableNextColumn(); + ImGui::TextUnformatted(node->Type); + } + } + }; + static const MyTreeNode nodes[] = { + {"lttp-redux", "Repository", -1, 1, 3}, + {"main", "Branch", -1, 4, 2}, + {"hyrule-castle", "Branch", -1, 4, 2}, + {"lost-woods", "Branch", -1, 6, 3}, + {"Added some bushes", "Commit", 1024, -1, -1}, + {"Constructed a new house", "Commit", 123000, -1, -1}, + {"File1_b.wav", "Commit", 456000, -1, -1}, + {"Image001.png", "Commit", 203128, -1, -1}, + {"Copy of Image001.png", "Commit", 203256, -1, -1}, + {"Copy of Image001 (Final2).png", "Commit", 203512, -1, -1}, + }; + + MyTreeNode::DisplayNode(&nodes[0], nodes); + + ImGui::EndTable(); + } +} +} // namespace delta +} // namespace app +} // namespace yaze \ No newline at end of file diff --git a/src/app/delta/viewer.h b/src/app/delta/viewer.h new file mode 100644 index 00000000..edcc8d48 --- /dev/null +++ b/src/app/delta/viewer.h @@ -0,0 +1,45 @@ +#ifndef YAZE_APP_DELTA_VIEWER_H +#define YAZE_APP_DELTA_VIEWER_H + +#include +#include +#include +#include +#include + +#include "absl/status/status.h" +#include "app/core/constants.h" +#include "app/delta/client.h" +#include "app/gfx/snes_palette.h" +#include "app/gfx/snes_tile.h" +#include "app/rom.h" +#include "gui/canvas.h" +#include "gui/icons.h" +#include "gui/input.h" + +namespace yaze { +namespace app { +namespace delta { +class Viewer { + public: + void Update(); + + private: + void DrawFileDialog(); + + void DrawYazeMenu(); + void DrawFileMenu() const; + void DrawViewMenu(); + + void DrawBranchTree(); + + std::string client_address_; + + ROM rom_; + Client client_; +}; +} // namespace delta +} // namespace app +} // namespace yaze + +#endif \ No newline at end of file diff --git a/src/app/editor/assembly_editor.cc b/src/app/editor/assembly_editor.cc new file mode 100644 index 00000000..aacdcaaa --- /dev/null +++ b/src/app/editor/assembly_editor.cc @@ -0,0 +1,115 @@ +#include "assembly_editor.h" + +#include "core/constants.h" +#include "gui/widgets.h" + +namespace yaze { +namespace app { +namespace editor { + +AssemblyEditor::AssemblyEditor() { + text_editor_.SetLanguageDefinition(gui::widgets::GetAssemblyLanguageDef()); + text_editor_.SetPalette(TextEditor::GetDarkPalette()); +} + +void AssemblyEditor::Update() { + ImGui::Begin("Assembly Editor", &file_is_loaded_); + MENU_BAR() + DrawFileMenu(); + DrawEditMenu(); + END_MENU_BAR() + + auto cpos = text_editor_.GetCursorPosition(); + SetEditorText(); + ImGui::Text("%6d/%-6d %6d lines | %s | %s | %s | %s", cpos.mLine + 1, + cpos.mColumn + 1, text_editor_.GetTotalLines(), + text_editor_.IsOverwrite() ? "Ovr" : "Ins", + text_editor_.CanUndo() ? "*" : " ", + text_editor_.GetLanguageDefinition().mName.c_str(), + current_file_.c_str()); + + text_editor_.Render("##asm_editor"); + ImGui::End(); +} + + + +void AssemblyEditor::InlineUpdate() { + ChangeActiveFile("assets/asm/template_song.asm"); + auto cpos = text_editor_.GetCursorPosition(); + SetEditorText(); + ImGui::Text("%6d/%-6d %6d lines | %s | %s | %s | %s", cpos.mLine + 1, + cpos.mColumn + 1, text_editor_.GetTotalLines(), + text_editor_.IsOverwrite() ? "Ovr" : "Ins", + text_editor_.CanUndo() ? "*" : " ", + text_editor_.GetLanguageDefinition().mName.c_str(), + current_file_.c_str()); + + text_editor_.Render("##asm_editor", ImVec2(0, 0)); +} + +void AssemblyEditor::ChangeActiveFile(const std::string& filename) { + current_file_ = filename; +} + +void AssemblyEditor::DrawFileMenu() { + if (ImGui::BeginMenu("File")) { + if (ImGui::MenuItem("Open", "Ctrl+O")) { + ImGuiFileDialog::Instance()->OpenDialog( + "ChooseASMFileDlg", "Open ASM file", ".asm,.txt", "."); + } + if (ImGui::MenuItem("Save", "Ctrl+S")) { + // TODO: Implement this + } + ImGui::EndMenu(); + } + + if (ImGuiFileDialog::Instance()->Display("ChooseASMFileDlg")) { + if (ImGuiFileDialog::Instance()->IsOk()) { + ChangeActiveFile(ImGuiFileDialog::Instance()->GetFilePathName()); + } + ImGuiFileDialog::Instance()->Close(); + } +} + +void AssemblyEditor::DrawEditMenu() { + if (ImGui::BeginMenu("Edit")) { + if (ImGui::MenuItem("Undo", "Ctrl+Z")) { + text_editor_.Undo(); + } + if (ImGui::MenuItem("Redo", "Ctrl+Y")) { + text_editor_.Redo(); + } + ImGui::Separator(); + if (ImGui::MenuItem("Cut", "Ctrl+X")) { + text_editor_.Cut(); + } + if (ImGui::MenuItem("Copy", "Ctrl+C")) { + text_editor_.Copy(); + } + if (ImGui::MenuItem("Paste", "Ctrl+V")) { + text_editor_.Paste(); + } + ImGui::Separator(); + if (ImGui::MenuItem("Find", "Ctrl+F")) { + // TODO: Implement this. + } + ImGui::EndMenu(); + } +} + +void AssemblyEditor::SetEditorText() { + if (!file_is_loaded_) { + std::ifstream t(current_file_); + if (t.good()) { + std::string str((std::istreambuf_iterator(t)), + std::istreambuf_iterator()); + text_editor_.SetText(str); + file_is_loaded_ = true; + } + } +} + +} // namespace editor +} // namespace app +} // namespace yaze \ No newline at end of file diff --git a/src/app/editor/assembly_editor.h b/src/app/editor/assembly_editor.h new file mode 100644 index 00000000..63195aa8 --- /dev/null +++ b/src/app/editor/assembly_editor.h @@ -0,0 +1,38 @@ +#ifndef YAZE_APP_EDITOR_ASSEMBLY_EDITOR_H +#define YAZE_APP_EDITOR_ASSEMBLY_EDITOR_H + +#include +#include + +#include +#include +#include + +namespace yaze { +namespace app { +namespace editor { + +class AssemblyEditor { + public: + AssemblyEditor(); + + void Update(); + void InlineUpdate(); + void ChangeActiveFile(const std::string &); + + private: + void DrawFileMenu(); + void DrawEditMenu(); + void SetEditorText(); + + bool file_is_loaded_ = false; + + std::string current_file_; + TextEditor text_editor_; +}; + +} // namespace editor +} // namespace app +} // namespace yaze + +#endif \ No newline at end of file diff --git a/src/app/editor/dungeon_editor.cc b/src/app/editor/dungeon_editor.cc new file mode 100644 index 00000000..151c2736 --- /dev/null +++ b/src/app/editor/dungeon_editor.cc @@ -0,0 +1,61 @@ +#include "dungeon_editor.h" + +#include "gui/icons.h" + +namespace yaze { +namespace app { +namespace editor { + +void DungeonEditor::Update() { + DrawToolset(); + canvas_.DrawBackground(); + canvas_.DrawContextMenu(); + canvas_.DrawGrid(); + canvas_.DrawOverlay(); +} + +void DungeonEditor::DrawToolset() { + if (ImGui::BeginTable("DWToolset", 9, toolset_table_flags_, ImVec2(0, 0))) { + ImGui::TableSetupColumn("#undoTool"); + ImGui::TableSetupColumn("#redoTool"); + ImGui::TableSetupColumn("#history"); + ImGui::TableSetupColumn("#separator"); + ImGui::TableSetupColumn("#bg1Tool"); + ImGui::TableSetupColumn("#bg2Tool"); + ImGui::TableSetupColumn("#bg3Tool"); + ImGui::TableSetupColumn("#itemTool"); + ImGui::TableSetupColumn("#spriteTool"); + + ImGui::TableNextColumn(); + ImGui::Button(ICON_MD_UNDO); + + ImGui::TableNextColumn(); + ImGui::Button(ICON_MD_REDO); + + ImGui::TableNextColumn(); + ImGui::Button(ICON_MD_MANAGE_HISTORY); + + ImGui::TableNextColumn(); + ImGui::Text(ICON_MD_MORE_VERT); + + ImGui::TableNextColumn(); + ImGui::Button(ICON_MD_FILTER_1); + + ImGui::TableNextColumn(); + ImGui::Button(ICON_MD_FILTER_2); + + ImGui::TableNextColumn(); + ImGui::Button(ICON_MD_FILTER_3); + + ImGui::TableNextColumn(); + ImGui::Button(ICON_MD_GRASS); + + ImGui::TableNextColumn(); + ImGui::Button(ICON_MD_PEST_CONTROL_RODENT); + ImGui::EndTable(); + } +} + +} // namespace editor +} // namespace app +} // namespace yaze \ No newline at end of file diff --git a/src/app/editor/dungeon_editor.h b/src/app/editor/dungeon_editor.h new file mode 100644 index 00000000..5c000d2d --- /dev/null +++ b/src/app/editor/dungeon_editor.h @@ -0,0 +1,26 @@ +#ifndef YAZE_APP_EDITOR_DUNGEONEDITOR_H +#define YAZE_APP_EDITOR_DUNGEONEDITOR_H + +#include + +#include "gui/canvas.h" +#include "gui/icons.h" + +namespace yaze { +namespace app { +namespace editor { +class DungeonEditor { + public: + void Update(); + + private: + void DrawToolset(); + + gui::Canvas canvas_; + ImGuiTableFlags toolset_table_flags_ = ImGuiTableFlags_SizingFixedFit; +}; +} // namespace editor +} // namespace app +} // namespace yaze + +#endif diff --git a/src/app/editor/master_editor.cc b/src/app/editor/master_editor.cc new file mode 100644 index 00000000..16ae7243 --- /dev/null +++ b/src/app/editor/master_editor.cc @@ -0,0 +1,322 @@ +#include "master_editor.h" + +#include +#include +#include +#include +#include + +#include "absl/status/status.h" +#include "app/core/constants.h" +#include "app/editor/assembly_editor.h" +#include "app/editor/dungeon_editor.h" +#include "app/editor/music_editor.h" +#include "app/editor/overworld_editor.h" +#include "app/gfx/snes_palette.h" +#include "app/gfx/snes_tile.h" +#include "app/rom.h" +#include "gui/canvas.h" +#include "gui/icons.h" +#include "gui/input.h" +#include "gui/widgets.h" + +namespace yaze { +namespace app { +namespace editor { + +namespace { + +constexpr ImGuiWindowFlags kMainEditorFlags = + ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse | + ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_MenuBar | + ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoTitleBar; + +void NewMasterFrame() { + const ImGuiIO &io = ImGui::GetIO(); + ImGui::NewFrame(); + ImGui::SetNextWindowPos(ImVec2(0, 0)); + ImVec2 dimensions(io.DisplaySize.x, io.DisplaySize.y); + ImGui::SetNextWindowSize(dimensions, ImGuiCond_Always); + + if (!ImGui::Begin("##YazeMain", nullptr, kMainEditorFlags)) { + ImGui::End(); + return; + } +} + +bool BeginCentered(const char *name) { + ImGuiIO const &io = ImGui::GetIO(); + ImVec2 pos(io.DisplaySize.x * 0.5f, io.DisplaySize.y * 0.5f); + ImGui::SetNextWindowPos(pos, ImGuiCond_Always, ImVec2(0.5f, 0.5f)); + ImGuiWindowFlags flags = + ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDecoration | + ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings; + return ImGui::Begin(name, nullptr, flags); +} + +void DisplayStatus(absl::Status &status) { + if (BeginCentered("StatusWindow")) { + ImGui::Text("%s", status.ToString().c_str()); + ImGui::Spacing(); + ImGui::NextColumn(); + ImGui::Columns(1); + ImGui::Separator(); + ImGui::NewLine(); + ImGui::SameLine(270); + if (ImGui::Button("OK", ImVec2(200, 0))) { + status = absl::OkStatus(); + } + ImGui::End(); + } +} + +} // namespace + +void MasterEditor::SetupScreen(std::shared_ptr renderer) { + sdl_renderer_ = renderer; + rom_.SetupRenderer(renderer); +} + +void MasterEditor::UpdateScreen() { + NewMasterFrame(); + + DrawYazeMenu(); + DrawFileDialog(); + DrawStatusPopup(); + DrawAboutPopup(); + DrawInfoPopup(); + + TAB_BAR("##TabBar") + DrawOverworldEditor(); + DrawDungeonEditor(); + DrawMusicEditor(); + DrawSpriteEditor(); + DrawScreenEditor(); + DrawPaletteEditor(); + END_TAB_BAR() + + ImGui::End(); +} + +void MasterEditor::DrawFileDialog() { + if (ImGuiFileDialog::Instance()->Display("ChooseFileDlgKey")) { + if (ImGuiFileDialog::Instance()->IsOk()) { + std::string filePathName = ImGuiFileDialog::Instance()->GetFilePathName(); + status_ = rom_.LoadFromFile(filePathName); + overworld_editor_.SetupROM(rom_); + screen_editor_.SetupROM(rom_); + palette_editor_.SetupROM(rom_); + } + ImGuiFileDialog::Instance()->Close(); + } +} + +void MasterEditor::DrawStatusPopup() { + if (!status_.ok()) { + DisplayStatus(status_); + } +} + +void MasterEditor::DrawAboutPopup() { + if (about_) ImGui::OpenPopup("About"); + if (ImGui::BeginPopupModal("About", nullptr, + ImGuiWindowFlags_AlwaysAutoResize)) { + ImGui::Text("Yet Another Zelda3 Editor - v0.02"); + ImGui::Text("Written by: scawful"); + ImGui::Spacing(); + ImGui::Text("Special Thanks: Zarby89, JaredBrian"); + ImGui::Separator(); + + if (ImGui::Button("Close", ImVec2(200, 0))) { + about_ = false; + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } +} + +void MasterEditor::DrawInfoPopup() { + if (rom_info_) ImGui::OpenPopup("ROM Information"); + if (ImGui::BeginPopupModal("ROM Information", nullptr, + ImGuiWindowFlags_AlwaysAutoResize)) { + ImGui::Text("Title: %s", rom_.GetTitle()); + ImGui::Text("ROM Size: %ld", rom_.size()); + + if (ImGui::Button("Close", ImVec2(200, 0))) { + rom_info_ = false; + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } +} + +void MasterEditor::DrawYazeMenu() { + MENU_BAR() + DrawFileMenu(); + DrawEditMenu(); + DrawViewMenu(); + DrawHelpMenu(); + END_MENU_BAR() +} + +void MasterEditor::DrawFileMenu() const { + if (ImGui::BeginMenu("File")) { + if (ImGui::MenuItem("Open", "Ctrl+O")) { + ImGuiFileDialog::Instance()->OpenDialog("ChooseFileDlgKey", "Open ROM", + ".sfc,.smc", "."); + } + + MENU_ITEM2("Save", "Ctrl+S") {} + MENU_ITEM("Save As..") {} + + ImGui::Separator(); + + // TODO: Make these options matter + if (ImGui::BeginMenu("Options")) { + static bool enabled = true; + ImGui::MenuItem("Enabled", "", &enabled); + ImGui::BeginChild("child", ImVec2(0, 60), true); + for (int i = 0; i < 10; i++) ImGui::Text("Scrolling Text %d", i); + ImGui::EndChild(); + static float f = 0.5f; + static int n = 0; + ImGui::SliderFloat("Value", &f, 0.0f, 1.0f); + ImGui::InputFloat("Input", &f, 0.1f); + ImGui::Combo("Combo", &n, "Yes\0No\0Maybe\0\0"); + ImGui::EndMenu(); + } + ImGui::EndMenu(); + } +} + +void MasterEditor::DrawEditMenu() { + if (ImGui::BeginMenu("Edit")) { + MENU_ITEM2("Undo", "Ctrl+Z") { status_ = overworld_editor_.Undo(); } + MENU_ITEM2("Redo", "Ctrl+Y") { status_ = overworld_editor_.Redo(); } + ImGui::Separator(); + MENU_ITEM2("Cut", "Ctrl+X") { status_ = overworld_editor_.Cut(); } + MENU_ITEM2("Copy", "Ctrl+C") { status_ = overworld_editor_.Copy(); } + MENU_ITEM2("Paste", "Ctrl+V") { status_ = overworld_editor_.Paste(); } + ImGui::Separator(); + MENU_ITEM2("Find", "Ctrl+F") {} + ImGui::Separator(); + MENU_ITEM("ROM Information") rom_info_ = true; + ImGui::EndMenu(); + } +} + +void MasterEditor::DrawViewMenu() { + static bool show_imgui_metrics = false; + static bool show_imgui_style_editor = false; + static bool show_memory_editor = false; + static bool show_asm_editor = false; + static bool show_imgui_demo = false; + static bool show_memory_viewer = false; + + if (show_imgui_metrics) { + ImGui::ShowMetricsWindow(&show_imgui_metrics); + } + + if (show_memory_editor) { + static MemoryEditor mem_edit; + mem_edit.DrawWindow("Memory Editor", (void *)&rom_, rom_.size()); + } + + if (show_imgui_demo) { + ImGui::ShowDemoWindow(); + } + + if (show_asm_editor) { + assembly_editor_.Update(); + } + + if (show_imgui_style_editor) { + ImGui::Begin("Style Editor (ImGui)", &show_imgui_style_editor); + ImGui::ShowStyleEditor(); + ImGui::End(); + } + + if (show_memory_viewer) { + ImGui::Begin("Memory Viewer (ImGui)", &show_memory_viewer); + + const float TEXT_BASE_HEIGHT = ImGui::GetTextLineHeightWithSpacing(); + static ImGuiTableFlags flags = + ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | + ImGuiTableFlags_ContextMenuInBody | ImGuiTableFlags_RowBg | + ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_NoHostExtendX; + if (auto outer_size = ImVec2(0.0f, TEXT_BASE_HEIGHT * 5.5f); + ImGui::BeginTable("table1", 3, flags, outer_size)) { + for (int row = 0; row < 10; row++) { + ImGui::TableNextRow(); + for (int column = 0; column < 3; column++) { + ImGui::TableNextColumn(); + ImGui::Text("Cell %d,%d", column, row); + } + } + ImGui::EndTable(); + } + + ImGui::End(); + } + + if (ImGui::BeginMenu("View")) { + ImGui::MenuItem("HEX Editor", nullptr, &show_memory_editor); + ImGui::MenuItem("ASM Editor", nullptr, &show_asm_editor); + ImGui::MenuItem("Memory Viewer", nullptr, &show_memory_viewer); + ImGui::MenuItem("ImGui Demo", nullptr, &show_imgui_demo); + ImGui::Separator(); + if (ImGui::BeginMenu("GUI Tools")) { + ImGui::MenuItem("Metrics (ImGui)", nullptr, &show_imgui_metrics); + ImGui::MenuItem("Style Editor (ImGui)", nullptr, + &show_imgui_style_editor); + ImGui::EndMenu(); + } + ImGui::EndMenu(); + } +} + +void MasterEditor::DrawHelpMenu() { + if (ImGui::BeginMenu("Help")) { + if (ImGui::MenuItem("About")) about_ = true; + ImGui::EndMenu(); + } +} + +void MasterEditor::DrawOverworldEditor() { + TAB_ITEM("Overworld") + status_ = overworld_editor_.Update(); + END_TAB_ITEM() +} + +void MasterEditor::DrawDungeonEditor() { + TAB_ITEM("Dungeon") + dungeon_editor_.Update(); + END_TAB_ITEM() +} + +void MasterEditor::DrawPaletteEditor() { + TAB_ITEM("Palettes") + status_ = palette_editor_.Update(); + END_TAB_ITEM() +} + +void MasterEditor::DrawScreenEditor() { + TAB_ITEM("Screens") + screen_editor_.Update(); + END_TAB_ITEM() +} + +void MasterEditor::DrawMusicEditor() { + TAB_ITEM("Music") + music_editor_.Update(); + END_TAB_ITEM() +} + +void MasterEditor::DrawSpriteEditor() { + TAB_ITEM("Sprites") + END_TAB_ITEM() +} + +} // namespace editor +} // namespace app +} // namespace yaze \ No newline at end of file diff --git a/src/app/editor/master_editor.h b/src/app/editor/master_editor.h new file mode 100644 index 00000000..66712aee --- /dev/null +++ b/src/app/editor/master_editor.h @@ -0,0 +1,72 @@ +#ifndef YAZE_APP_EDITOR_MASTER_EDITOR_H +#define YAZE_APP_EDITOR_MASTER_EDITOR_H + +#include +#include +#include +#include +#include + +#include "absl/status/status.h" +#include "app/core/constants.h" +#include "app/editor/assembly_editor.h" +#include "app/editor/dungeon_editor.h" +#include "app/editor/music_editor.h" +#include "app/editor/overworld_editor.h" +#include "app/editor/palette_editor.h" +#include "app/editor/screen_editor.h" +#include "app/gfx/snes_palette.h" +#include "app/gfx/snes_tile.h" +#include "app/rom.h" +#include "gui/canvas.h" +#include "gui/icons.h" +#include "gui/input.h" + +namespace yaze { +namespace app { +namespace editor { + +class MasterEditor { + public: + void SetupScreen(std::shared_ptr renderer); + void UpdateScreen(); + + private: + void DrawFileDialog(); + void DrawStatusPopup(); + void DrawAboutPopup(); + void DrawInfoPopup(); + + void DrawYazeMenu(); + void DrawFileMenu() const; + void DrawEditMenu(); + void DrawViewMenu(); + void DrawHelpMenu(); + + void DrawOverworldEditor(); + void DrawDungeonEditor(); + void DrawPaletteEditor(); + void DrawMusicEditor(); + void DrawScreenEditor(); + void DrawSpriteEditor(); + + bool about_ = false; + bool rom_info_ = false; + + std::shared_ptr sdl_renderer_; + absl::Status status_; + + AssemblyEditor assembly_editor_; + DungeonEditor dungeon_editor_; + OverworldEditor overworld_editor_; + PaletteEditor palette_editor_; + ScreenEditor screen_editor_; + MusicEditor music_editor_; + ROM rom_; +}; + +} // namespace editor +} // namespace app +} // namespace yaze + +#endif // YAZE_APP_EDITOR_MASTER_EDITOR_H \ No newline at end of file diff --git a/src/app/editor/music_editor.cc b/src/app/editor/music_editor.cc new file mode 100644 index 00000000..a635f081 --- /dev/null +++ b/src/app/editor/music_editor.cc @@ -0,0 +1,292 @@ +#include "music_editor.h" + +#include +#include + +#include "absl/strings/str_format.h" +#include "app/editor/assembly_editor.h" +#include "gui/canvas.h" +#include "gui/icons.h" +#include "gui/input.h" +#include "snes_spc/demo/demo_util.h" +#include "snes_spc/demo/wave_writer.h" +#include "snes_spc/snes_spc/spc.h" + +namespace yaze { +namespace app { +namespace editor { + +namespace { + +#define BUF_SIZE 2048 + +void PlaySPC() { + /* Create emulator and filter */ + SNES_SPC* snes_spc = spc_new(); + SPC_Filter* filter = spc_filter_new(); + if (!snes_spc || !filter) error("Out of memory"); + + /* Load SPC */ + { + /* Load file into memory */ + long spc_size; + void* spc = load_file("assets/music/hyrule_field.spc", &spc_size); + + /* Load SPC data into emulator */ + error(spc_load_spc(snes_spc, spc, spc_size)); + free(spc); /* emulator makes copy of data */ + + /* Most SPC files have garbage data in the echo buffer, so clear that */ + spc_clear_echo(snes_spc); + + /* Clear filter before playing */ + spc_filter_clear(filter); + } + + /* Record 20 seconds to wave file */ + wave_open(spc_sample_rate, "out.wav"); + wave_enable_stereo(); + while (wave_sample_count() < 30 * spc_sample_rate * 2) { + /* Play into buffer */ + short buf[BUF_SIZE]; + error(spc_play(snes_spc, BUF_SIZE, buf)); + + /* Filter samples */ + spc_filter_run(filter, buf, BUF_SIZE); + + wave_write(buf, BUF_SIZE); + } + + /* Cleanup */ + spc_filter_delete(filter); + spc_delete(snes_spc); + wave_close(); +} + +} // namespace + +void MusicEditor::Update() { + if (ImGui::BeginTable("MusicEditorColumns", 2, music_editor_flags_, + ImVec2(0, 0))) { + ImGui::TableSetupColumn("Assembly"); + ImGui::TableSetupColumn("Composition"); + ImGui::TableHeadersRow(); + ImGui::TableNextRow(); + + ImGui::TableNextColumn(); + assembly_editor_.InlineUpdate(); + + ImGui::TableNextColumn(); + DrawToolset(); + DrawChannels(); + DrawPianoRoll(); + + ImGui::EndTable(); + } +} + +void MusicEditor::DrawChannels() { + if (ImGui::BeginTabBar("MyTabBar", ImGuiTabBarFlags_None)) { + for (int i = 1; i <= 8; ++i) { + if (ImGui::BeginTabItem(absl::StrFormat("%d", i).data())) { + DrawPianoStaff(); + ImGui::EndTabItem(); + } + } + ImGui::EndTabBar(); + } +} + +static const int NUM_KEYS = 25; +static bool keys[NUM_KEYS]; + +void MusicEditor::DrawPianoStaff() { + if (ImGuiID child_id = ImGui::GetID((void*)(intptr_t)9); + ImGui::BeginChild(child_id, ImVec2(0, 170), false)) { + const int NUM_LINES = 5; + const int LINE_THICKNESS = 2; + const int LINE_SPACING = 40; + + // Get the draw list for the current window + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + + // Draw the staff lines + ImVec2 canvas_p0 = + ImVec2(ImGui::GetCursorScreenPos().x, ImGui::GetCursorScreenPos().y); + ImVec2 canvas_p1 = ImVec2(canvas_p0.x + ImGui::GetContentRegionAvail().x, + canvas_p0.y + ImGui::GetContentRegionAvail().y); + draw_list->AddRectFilled(canvas_p0, canvas_p1, IM_COL32(32, 32, 32, 255)); + for (int i = 0; i < NUM_LINES; i++) { + auto line_start = ImVec2(canvas_p0.x, canvas_p0.y + i * LINE_SPACING); + auto line_end = ImVec2(canvas_p1.x + ImGui::GetContentRegionAvail().x, + canvas_p0.y + i * LINE_SPACING); + draw_list->AddLine(line_start, line_end, IM_COL32(200, 200, 200, 255), + LINE_THICKNESS); + } + + // Draw the ledger lines + const int NUM_LEDGER_LINES = 3; + for (int i = -NUM_LEDGER_LINES; i <= NUM_LINES + NUM_LEDGER_LINES; i++) { + if (i % 2 == 0) continue; // skip every other line + auto line_start = ImVec2(canvas_p0.x, canvas_p0.y + i * LINE_SPACING / 2); + auto line_end = ImVec2(canvas_p1.x + ImGui::GetContentRegionAvail().x, + canvas_p0.y + i * LINE_SPACING / 2); + draw_list->AddLine(line_start, line_end, IM_COL32(150, 150, 150, 255), + LINE_THICKNESS); + } + } + ImGui::EndChild(); +} + +void MusicEditor::DrawPianoRoll() { + // Render the piano roll + float key_width = ImGui::GetContentRegionAvail().x / NUM_KEYS; + float white_key_height = ImGui::GetContentRegionAvail().y * 0.8f; + float black_key_height = ImGui::GetContentRegionAvail().y * 0.5f; + ImGui::Text("Piano Roll"); + ImGui::Separator(); + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + + // Draw the staff lines + ImVec2 canvas_p0 = + ImVec2(ImGui::GetCursorScreenPos().x, ImGui::GetCursorScreenPos().y); + ImVec2 canvas_p1 = ImVec2(canvas_p0.x + ImGui::GetContentRegionAvail().x, + canvas_p0.y + ImGui::GetContentRegionAvail().y); + draw_list->AddRectFilled(canvas_p0, canvas_p1, IM_COL32(200, 200, 200, 255)); + + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(4.f, 0.f)); + ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 0.f); + for (int i = 0; i < NUM_KEYS; i++) { + // Calculate the position and size of the key + ImVec2 key_pos = ImVec2(i * key_width, 0.0f); + ImVec2 key_size; + ImVec4 key_color; + ImVec4 text_color; + if (i % 12 == 1 || i % 12 == 3 || i % 12 == 6 || i % 12 == 8 || + i % 12 == 10) { + // This is a black key + key_size = ImVec2(key_width * 0.6f, black_key_height); + key_color = ImVec4(0, 0, 0, 255); + text_color = ImVec4(255, 255, 255, 255); + } else { + // This is a white key + key_size = ImVec2(key_width, white_key_height); + key_color = ImVec4(255, 255, 255, 255); + text_color = ImVec4(0, 0, 0, 255); + } + + ImGui::PushID(i); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.f, 0.f)); + ImGui::PushStyleColor(ImGuiCol_Button, key_color); + ImGui::PushStyleColor(ImGuiCol_Text, text_color); + if (ImGui::Button(kSongNotes[i].data(), key_size)) { + keys[i] ^= 1; + } + ImGui::PopStyleColor(); + ImGui::PopStyleColor(); + ImGui::PopStyleVar(); + + ImVec2 button_pos = ImGui::GetItemRectMin(); + ImVec2 button_size = ImGui::GetItemRectSize(); + if (keys[i]) { + ImVec2 dest; + dest.x = button_pos.x + button_size.x; + dest.y = button_pos.y + button_size.y; + ImGui::GetWindowDrawList()->AddRectFilled(button_pos, dest, + IM_COL32(200, 200, 255, 200)); + } + ImGui::PopID(); + ImGui::SameLine(); + } + ImGui::PopStyleVar(); + ImGui::PopStyleVar(); +} + +void MusicEditor::DrawSongToolset() { + if (ImGui::BeginTable("DWToolset", 8, toolset_table_flags_, ImVec2(0, 0))) { + ImGui::TableSetupColumn("#1"); + ImGui::TableSetupColumn("#play"); + ImGui::TableSetupColumn("#rewind"); + ImGui::TableSetupColumn("#fastforward"); + ImGui::TableSetupColumn("volumeController"); + + ImGui::EndTable(); + } +} + +void MusicEditor::DrawToolset() { + static bool is_playing = false; + static int selected_option = 0; + static int current_volume = 0; + static bool has_loaded_song = false; + const int MAX_VOLUME = 100; + + if (is_playing) { + if (!has_loaded_song) { + PlaySPC(); + current_song_ = Mix_LoadMUS("out.wav"); + Mix_PlayMusic(current_song_, -1); + has_loaded_song = true; + } + + // // If there is no music playing + // if (Mix_PlayingMusic() == 0) { + // Mix_PlayMusic(current_song_, -1); + // } + // // If music is being played + // else { + // // If the music is paused + // if (Mix_PausedMusic() == 1) { + // // Resume the music + // Mix_ResumeMusic(); + // } + // // If the music is playing + // else { + // // Pause the music + // Mix_PauseMusic(); + // } + // } + } + + gui::ItemLabel("Select a song to edit: ", gui::ItemLabelFlags::Left); + ImGui::Combo("#songs_in_game", &selected_option, kGameSongs, 30); + + gui::ItemLabel("Controls: ", gui::ItemLabelFlags::Left); + if (ImGui::BeginTable("SongToolset", 5, toolset_table_flags_, ImVec2(0, 0))) { + ImGui::TableSetupColumn("#play"); + ImGui::TableSetupColumn("#rewind"); + ImGui::TableSetupColumn("#fastforward"); + ImGui::TableSetupColumn("#volume"); + ImGui::TableSetupColumn("#slider"); + + ImGui::TableNextColumn(); + if (ImGui::Button(is_playing ? ICON_MD_STOP : ICON_MD_PLAY_ARROW)) { + if (is_playing) { + Mix_HaltMusic(); + has_loaded_song = false; + } + is_playing = !is_playing; + } + + BUTTON_COLUMN(ICON_MD_FAST_REWIND) + BUTTON_COLUMN(ICON_MD_FAST_FORWARD) + BUTTON_COLUMN(ICON_MD_VOLUME_UP) + ImGui::TableNextColumn(); + ImGui::SliderInt("Volume", ¤t_volume, 0, 100); + ImGui::EndTable(); + } + + const int SONG_DURATION = 120; // duration of the song in seconds + static int current_time = 0; // current time in the song in seconds + + // Display the current time in the song + gui::ItemLabel("Current Time: ", gui::ItemLabelFlags::Left); + ImGui::Text("%d:%02d", current_time / 60, current_time % 60); + ImGui::SameLine(); + // Display the song duration/progress using a progress bar + ImGui::ProgressBar((float)current_time / SONG_DURATION); +} + +} // namespace editor +} // namespace app +} // namespace yaze diff --git a/src/app/editor/music_editor.h b/src/app/editor/music_editor.h new file mode 100644 index 00000000..929d36ae --- /dev/null +++ b/src/app/editor/music_editor.h @@ -0,0 +1,86 @@ +#ifndef YAZE_APP_EDITOR_MUSIC_EDITOR_H +#define YAZE_APP_EDITOR_MUSIC_EDITOR_H + +#include +#include + +#include "absl/strings/str_format.h" +#include "app/editor/assembly_editor.h" +#include "gui/canvas.h" +#include "gui/icons.h" +#include "gui/input.h" +#include "snes_spc/demo/demo_util.h" +#include "snes_spc/demo/wave_writer.h" +#include "snes_spc/snes_spc/spc.h" + +namespace yaze { +namespace app { +namespace editor { + +static const char* kGameSongs[] = {"Title", + "Light World", + "Beginning", + "Rabbit", + "Forest", + "Intro", + "Town", + "Warp", + "Dark world", + "Master sword", + "File select", + "Soldier", + "Mountain", + "Shop", + "Fanfare", + "Castle", + "Palace (Pendant)", + "Cave (Same as Secret Way)", + "Clear (Dungeon end)", + "Church", + "Boss", + "Dungeon (Crystal)", + "Psychic", + "Secret Way (Same as Cave)", + "Rescue", + "Crystal", + "Fountain", + "Pyramid", + "Kill Agahnim", + "Ganon Room", + "Last Boss"}; + +static constexpr absl::string_view kSongNotes[] = { + "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B", "C", + "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B", "C"}; +class MusicEditor { + public: + void Update(); + + private: + void DrawChannels(); + void DrawPianoStaff(); + void DrawPianoRoll(); + void DrawSongToolset(); + void DrawToolset(); + + Mix_Music* current_song_ = NULL; + + AssemblyEditor assembly_editor_; + ImGuiTableFlags toolset_table_flags_ = ImGuiTableFlags_SizingFixedFit; + ImGuiTableFlags music_editor_flags_ = ImGuiTableFlags_SizingFixedFit | + ImGuiTableFlags_Resizable | + ImGuiTableFlags_Reorderable; + + ImGuiTableFlags channel_table_flags_ = + ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | + ImGuiTableFlags_Hideable | ImGuiTableFlags_Sortable | + ImGuiTableFlags_SortMulti | ImGuiTableFlags_RowBg | + ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | + ImGuiTableFlags_NoBordersInBody | ImGuiTableFlags_ScrollY; +}; + +} // namespace editor +} // namespace app +} // namespace yaze + +#endif diff --git a/src/app/editor/overworld_editor.cc b/src/app/editor/overworld_editor.cc new file mode 100644 index 00000000..f37c78f7 --- /dev/null +++ b/src/app/editor/overworld_editor.cc @@ -0,0 +1,352 @@ +#include "overworld_editor.h" + +#include + +#include +#include + +#include "absl/container/flat_hash_map.h" +#include "absl/status/status.h" +#include "absl/status/statusor.h" +#include "absl/strings/str_format.h" +#include "app/editor/palette_editor.h" +#include "app/gfx/bitmap.h" +#include "app/gfx/snes_palette.h" +#include "app/gfx/snes_tile.h" +#include "app/rom.h" +#include "app/zelda3/overworld.h" +#include "gui/canvas.h" +#include "gui/icons.h" + +namespace yaze { +namespace app { +namespace editor { + +// ---------------------------------------------------------------------------- + +absl::Status OverworldEditor::Update() { + // Initialize overworld graphics, maps, and palettes + if (rom_.isLoaded() && !all_gfx_loaded_) { + RETURN_IF_ERROR(LoadGraphics()) + all_gfx_loaded_ = true; + } + + // Draws the toolset for editing the Overworld. + RETURN_IF_ERROR(DrawToolset()) + + ImGui::Separator(); + if (ImGui::BeginTable("#owEditTable", 2, ow_edit_flags, ImVec2(0, 0))) { + ImGui::TableSetupColumn("Canvas", ImGuiTableColumnFlags_WidthStretch, + ImGui::GetContentRegionAvail().x); + ImGui::TableSetupColumn("Tile Selector"); + ImGui::TableHeadersRow(); + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + DrawOverworldCanvas(); + ImGui::TableNextColumn(); + DrawTileSelector(); + ImGui::EndTable(); + } + + return absl::OkStatus(); +} + +// ---------------------------------------------------------------------------- + +absl::Status OverworldEditor::DrawToolset() { + if (ImGui::BeginTable("OWToolset", 17, toolset_table_flags, ImVec2(0, 0))) { + for (const auto &name : kToolsetColumnNames) + ImGui::TableSetupColumn(name.data()); + + BUTTON_COLUMN(ICON_MD_UNDO) // Undo + BUTTON_COLUMN(ICON_MD_REDO) // Redo + TEXT_COLUMN(ICON_MD_MORE_VERT) // Separator + BUTTON_COLUMN(ICON_MD_ZOOM_OUT) // Zoom Out + BUTTON_COLUMN(ICON_MD_ZOOM_IN) // Zoom In + TEXT_COLUMN(ICON_MD_MORE_VERT) // Separator + BUTTON_COLUMN(ICON_MD_DRAW) // Draw Tile + BUTTON_COLUMN(ICON_MD_DOOR_FRONT) // Entrances + BUTTON_COLUMN(ICON_MD_DOOR_BACK) // Exits + BUTTON_COLUMN(ICON_MD_GRASS) // Items + BUTTON_COLUMN(ICON_MD_PEST_CONTROL_RODENT) // Sprites + BUTTON_COLUMN(ICON_MD_ADD_LOCATION) // Transports + BUTTON_COLUMN(ICON_MD_MUSIC_NOTE) // Music + TEXT_COLUMN(ICON_MD_MORE_VERT) // Separator + ImGui::TableNextColumn(); // Palette + palette_editor_.DisplayPalette(palette_, overworld_.isLoaded()); + + ImGui::EndTable(); + } + return absl::OkStatus(); +} + +// ---------------------------------------------------------------------------- + +void OverworldEditor::DrawOverworldMapSettings() { + if (ImGui::BeginTable("#mapSettings", 8, ow_map_flags, ImVec2(0, 0), -1)) { + for (const auto &name : kOverworldSettingsColumnNames) + ImGui::TableSetupColumn(name.data()); + + ImGui::TableNextColumn(); + ImGui::SetNextItemWidth(50.f); + ImGui::InputInt("Current Map", ¤t_map_); + + ImGui::TableNextColumn(); + ImGui::SetNextItemWidth(100.f); + ImGui::Combo("##world", ¤t_world_, + "Light World\0Dark World\0Extra World\0"); + + ImGui::TableNextColumn(); + ImGui::Text("GFX"); + ImGui::SameLine(); + ImGui::SetNextItemWidth(kInputFieldSize); + ImGui::InputText("##mapGFX", map_gfx_, kByteSize); + + ImGui::TableNextColumn(); + ImGui::Text("Palette"); + ImGui::SameLine(); + ImGui::SetNextItemWidth(kInputFieldSize); + ImGui::InputText("##mapPal", map_palette_, kByteSize); + + ImGui::TableNextColumn(); + ImGui::Text("Spr GFX"); + ImGui::SameLine(); + ImGui::SetNextItemWidth(kInputFieldSize); + ImGui::InputText("##sprGFX", spr_gfx_, kByteSize); + + ImGui::TableNextColumn(); + ImGui::Text("Spr Palette"); + ImGui::SameLine(); + ImGui::SetNextItemWidth(kInputFieldSize); + ImGui::InputText("##sprPal", spr_palette_, kByteSize); + + ImGui::TableNextColumn(); + ImGui::Text("Msg ID"); + ImGui::SameLine(); + ImGui::SetNextItemWidth(50.f); + ImGui::InputText("##msgid", spr_palette_, kMessageIdSize); + + ImGui::TableNextColumn(); + ImGui::Checkbox("Show grid", &opt_enable_grid); // TODO + ImGui::EndTable(); + } +} + +// ---------------------------------------------------------------------------- + +void OverworldEditor::DrawOverworldEntrances() { + for (const auto &each : overworld_.Entrances()) { + if (each.map_id_ < 0x40 + (current_world_ * 0x40) && + each.map_id_ >= (current_world_ * 0x40)) { + ow_map_canvas_.DrawRect(each.x_, each.y_, 16, 16, + ImVec4(210, 24, 210, 150)); + std::string str = absl::StrFormat("%#x", each.entrance_id_); + ow_map_canvas_.DrawText(str, each.x_ - 4, each.y_ - 2); + } + } +} + +// ---------------------------------------------------------------------------- + +void OverworldEditor::DrawOverworldMaps() { + int xx = 0; + int yy = 0; + for (int i = 0; i < 0x40; i++) { + int world_index = i + (current_world_ * 0x40); + int map_x = (xx * 0x200); + int map_y = (yy * 0x200); + ow_map_canvas_.DrawBitmap(maps_bmp_[world_index], map_x, map_y); + xx++; + if (xx >= 8) { + yy++; + xx = 0; + } + DrawOverworldEntrances(); + } +} + +// ---------------------------------------------------------------------------- + +// Overworld Editor canvas +// Allows the user to make changes to the overworld map. +void OverworldEditor::DrawOverworldCanvas() { + DrawOverworldMapSettings(); + ImGui::Separator(); + if (ImGuiID child_id = ImGui::GetID((void *)(intptr_t)7); + ImGui::BeginChild(child_id, ImGui::GetContentRegionAvail(), true, + ImGuiWindowFlags_AlwaysVerticalScrollbar | + ImGuiWindowFlags_AlwaysHorizontalScrollbar)) { + ow_map_canvas_.DrawBackground(ImVec2(0x200 * 8, 0x200 * 8)); + ow_map_canvas_.DrawContextMenu(); + if (overworld_.isLoaded()) { + DrawOverworldMaps(); + // User has selected a tile they want to draw from the blockset. + if (!blockset_canvas_.Points().empty()) { + int x = blockset_canvas_.Points().front().x / 32; + int y = blockset_canvas_.Points().front().y / 32; + std::cout << x << " " << y << std::endl; + current_tile16_ = x + (y * 8); + std::cout << current_tile16_ << std::endl; + ow_map_canvas_.DrawTilePainter(tile16_individual_[current_tile16_], 16); + } + } + ow_map_canvas_.DrawGrid(64.0f); + ow_map_canvas_.DrawOverlay(); + } + ImGui::EndChild(); +} + +// ---------------------------------------------------------------------------- + +// Tile 16 Selector +// Displays all the tiles in the game. +void OverworldEditor::DrawTile16Selector() { + blockset_canvas_.DrawBackground(ImVec2(0x100 + 1, (8192 * 2) + 1)); + blockset_canvas_.DrawContextMenu(); + blockset_canvas_.DrawBitmap(tile16_blockset_bmp_, 2, map_blockset_loaded_); + blockset_canvas_.DrawTileSelector(32); + blockset_canvas_.DrawGrid(32.0f); + blockset_canvas_.DrawOverlay(); +} + +// ---------------------------------------------------------------------------- + +// Tile 8 Selector +// Displays all the individual tiles that make up a tile16. +void OverworldEditor::DrawTile8Selector() { + graphics_bin_canvas_.DrawBackground( + ImVec2(0x100 + 1, kNumSheetsToLoad * 0x40 + 1)); + graphics_bin_canvas_.DrawContextMenu(); + if (all_gfx_loaded_) { + for (const auto &[key, value] : graphics_bin_) { + int offset = 0x40 * (key + 1); + int top_left_y = graphics_bin_canvas_.GetZeroPoint().y + 2; + if (key >= 1) { + top_left_y = graphics_bin_canvas_.GetZeroPoint().y + 0x40 * key; + } + graphics_bin_canvas_.GetDrawList()->AddImage( + (void *)value.GetTexture(), + ImVec2(graphics_bin_canvas_.GetZeroPoint().x + 2, top_left_y), + ImVec2(graphics_bin_canvas_.GetZeroPoint().x + 0x100, + graphics_bin_canvas_.GetZeroPoint().y + offset)); + } + } + graphics_bin_canvas_.DrawGrid(16.0f); + graphics_bin_canvas_.DrawOverlay(); +} + +// ---------------------------------------------------------------------------- + +// Displays the graphics tilesheets that are available on the current selected +// overworld map. +void OverworldEditor::DrawAreaGraphics() { + current_gfx_canvas_.DrawBackground(ImVec2(256 + 1, 0x10 * 0x40 + 1)); + current_gfx_canvas_.DrawContextMenu(); + current_gfx_canvas_.DrawTileSelector(32); + current_gfx_canvas_.DrawBitmap(current_gfx_bmp_, 2, overworld_.isLoaded()); + current_gfx_canvas_.DrawGrid(32.0f); + current_gfx_canvas_.DrawOverlay(); +} + +// ---------------------------------------------------------------------------- + +void OverworldEditor::DrawTileSelector() { + if (ImGui::BeginTabBar("##TabBar", ImGuiTabBarFlags_FittingPolicyScroll)) { + if (ImGui::BeginTabItem("Tile16")) { + if (ImGuiID child_id = ImGui::GetID((void *)(intptr_t)2); + ImGui::BeginChild(child_id, ImGui::GetContentRegionAvail(), true, + ImGuiWindowFlags_AlwaysVerticalScrollbar)) { + DrawTile16Selector(); + } + ImGui::EndChild(); + ImGui::EndTabItem(); + } + if (ImGui::BeginTabItem("Tile8")) { + if (ImGuiID child_id = ImGui::GetID((void *)(intptr_t)1); + ImGui::BeginChild(child_id, ImGui::GetContentRegionAvail(), true, + ImGuiWindowFlags_AlwaysVerticalScrollbar)) { + DrawTile8Selector(); + } + ImGui::EndChild(); + ImGui::EndTabItem(); + } + if (ImGui::BeginTabItem("Area Graphics")) { + if (ImGuiID child_id = ImGui::GetID((void *)(intptr_t)3); + ImGui::BeginChild(child_id, ImGui::GetContentRegionAvail(), true, + ImGuiWindowFlags_AlwaysVerticalScrollbar)) { + DrawAreaGraphics(); + } + ImGui::EndChild(); + ImGui::EndTabItem(); + } + ImGui::EndTabBar(); + } +} + +// ---------------------------------------------------------------------------- + +absl::Status OverworldEditor::LoadGraphics() { + // Load all of the graphics data from the game. + PRINT_IF_ERROR(rom_.LoadAllGraphicsData()) + graphics_bin_ = rom_.GetGraphicsBin(); + + // Load the Link to the Past overworld. + RETURN_IF_ERROR(overworld_.Load(rom_)) + palette_ = overworld_.AreaPalette(); + current_gfx_bmp_.Create(0x80, 0x200, 0x40, overworld_.AreaGraphics()); + current_gfx_bmp_.ApplyPalette(palette_); + rom_.RenderBitmap(¤t_gfx_bmp_); + + // Create the tile16 blockset image + tile16_blockset_bmp_.Create(0x80, 8192, 0x80, overworld_.Tile16Blockset()); + tile16_blockset_bmp_.ApplyPalette(palette_); + rom_.RenderBitmap(&tile16_blockset_bmp_); + map_blockset_loaded_ = true; + + // Copy the tile16 data into individual tiles. + auto tile16_data = overworld_.Tile16Blockset(); + + // Loop through the tiles and copy their pixel data into separate vectors + for (int i = 0; i < 4096; i++) { + // Create a new vector for the pixel data of the current tile + Bytes tile_data; + for (int j = 0; j < 32 * 32; j++) tile_data.push_back(0x00); + + // Copy the pixel data for the current tile into the vector + for (int ty = 0; ty < 32; ty++) { + for (int tx = 0; tx < 32; tx++) { + int position = (tx + (ty * 0x20)); + uchar value = tile16_data[i + tx + (ty * 0x80)]; + tile_data[position] = value; + } + } + + // Add the vector for the current tile to the vector of tile pixel data + tile16_individual_data_.push_back(tile_data); + } + + // Render the bitmaps of each tile. + for (int id = 0; id < 4096; id++) { + gfx::Bitmap new_tile16; + tile16_individual_.emplace_back(new_tile16); + tile16_individual_[id].Create(0x10, 0x10, 0x80, + tile16_individual_data_[id]); + tile16_individual_[id].ApplyPalette(palette_); + rom_.RenderBitmap(&tile16_individual_[id]); + } + + // Render the overworld maps loaded from the ROM. + for (int i = 0; i < core::kNumOverworldMaps; ++i) { + overworld_.SetCurrentMap(i); + auto palette = overworld_.AreaPalette(); + maps_bmp_[i].Create(0x200, 0x200, 0x200, overworld_.BitmapData()); + maps_bmp_[i].ApplyPalette(palette); + rom_.RenderBitmap(&(maps_bmp_[i])); + } + + return absl::OkStatus(); +} + +} // namespace editor +} // namespace app +} // namespace yaze \ No newline at end of file diff --git a/src/app/editor/overworld_editor.h b/src/app/editor/overworld_editor.h new file mode 100644 index 00000000..4c664843 --- /dev/null +++ b/src/app/editor/overworld_editor.h @@ -0,0 +1,118 @@ +#ifndef YAZE_APP_EDITOR_OVERWORLDEDITOR_H +#define YAZE_APP_EDITOR_OVERWORLDEDITOR_H + +#include + +#include +#include + +#include "absl/container/flat_hash_map.h" +#include "absl/status/status.h" +#include "absl/status/statusor.h" +#include "absl/strings/str_format.h" +#include "app/editor/palette_editor.h" +#include "app/gfx/bitmap.h" +#include "app/gfx/snes_palette.h" +#include "app/gfx/snes_tile.h" +#include "app/rom.h" +#include "app/zelda3/overworld.h" +#include "gui/canvas.h" +#include "gui/icons.h" + +namespace yaze { +namespace app { +namespace editor { + +static constexpr uint k4BPP = 4; +static constexpr uint kByteSize = 3; +static constexpr uint kMessageIdSize = 5; +static constexpr uint kNumSheetsToLoad = 223; +static constexpr uint kTile8DisplayHeight = 64; +static constexpr float kInputFieldSize = 30.f; + +static constexpr absl::string_view kToolsetColumnNames[] = { + "#undoTool", "#redoTool", "#drawTool", "#separator2", + "#zoomOutTool", "#zoomInTool", "#separator", "#history", + "#entranceTool", "#exitTool", "#itemTool", "#spriteTool", + "#transportTool", "#musicTool"}; + +static constexpr absl::string_view kOverworldSettingsColumnNames[] = { + "##1stCol", "##gfxCol", "##palCol", "##sprgfxCol", + "##sprpalCol", "##msgidCol", "##2ndCol"}; + +class OverworldEditor { + public: + absl::Status Update(); + absl::Status Undo() const { return absl::UnimplementedError("Undo"); } + absl::Status Redo() const { return absl::UnimplementedError("Redo"); } + absl::Status Cut() const { return absl::UnimplementedError("Cut"); } + absl::Status Copy() const { return absl::UnimplementedError("Copy"); } + absl::Status Paste() const { return absl::UnimplementedError("Paste"); } + void SetupROM(ROM &rom) { rom_ = rom; } + + private: + absl::Status DrawToolset(); + void DrawOverworldMapSettings(); + + void DrawOverworldEntrances(); + void DrawOverworldMaps(); + void DrawOverworldCanvas(); + + void DrawTile16Selector(); + void DrawTile8Selector(); + void DrawAreaGraphics(); + void DrawTileSelector(); + absl::Status LoadGraphics(); + + int current_world_ = 0; + int current_map_ = 0; + int current_tile16_ = 0; + int selected_tile_ = 0; + char map_gfx_[3] = ""; + char map_palette_[3] = ""; + char spr_gfx_[3] = ""; + char spr_palette_[3] = ""; + char message_id_[5] = ""; + char staticgfx[16]; + + bool opt_enable_grid = true; + bool all_gfx_loaded_ = false; + bool map_blockset_loaded_ = false; + bool selected_tile_loaded_ = false; + bool update_selected_tile_ = true; + + ImGuiTableFlags toolset_table_flags = ImGuiTableFlags_SizingFixedFit; + ImGuiTableFlags ow_map_flags = ImGuiTableFlags_Borders; + ImGuiTableFlags ow_edit_flags = ImGuiTableFlags_Reorderable | + ImGuiTableFlags_Resizable | + ImGuiTableFlags_SizingStretchSame; + + Bytes selected_tile_data_; + std::unordered_map graphics_bin_; + std::unordered_map current_graphics_set_; + std::unordered_map maps_bmp_; + std::unordered_map sprite_previews_; + + std::vector tile16_individual_data_; + std::vector tile16_individual_; + + ROM rom_; + PaletteEditor palette_editor_; + zelda3::Overworld overworld_; + + gfx::SNESPalette palette_; + gfx::Bitmap selected_tile_bmp_; + gfx::Bitmap tile16_blockset_bmp_; + gfx::Bitmap current_gfx_bmp_; + gfx::Bitmap all_gfx_bmp; + + gui::Canvas ow_map_canvas_; + gui::Canvas current_gfx_canvas_; + gui::Canvas blockset_canvas_; + gui::Canvas graphics_bin_canvas_; +}; +} // namespace editor +} // namespace app +} // namespace yaze + +#endif \ No newline at end of file diff --git a/src/app/editor/palette_editor.cc b/src/app/editor/palette_editor.cc new file mode 100644 index 00000000..00e6c381 --- /dev/null +++ b/src/app/editor/palette_editor.cc @@ -0,0 +1,128 @@ +#include "palette_editor.h" + +#include + +#include "absl/status/status.h" +#include "app/gfx/snes_palette.h" +#include "gui/canvas.h" +#include "gui/icons.h" + +namespace yaze { +namespace app { +namespace editor { + +absl::Status PaletteEditor::Update() { + for (int i = 0; i < 11; ++i) { + if (ImGui::TreeNode(kPaletteCategoryNames[i].data())) { + auto size = rom_.GetPaletteGroup(kPaletteGroupNames[i].data()).size; + auto palettes = rom_.GetPaletteGroup(kPaletteGroupNames[i].data()); + for (int j = 0; j < size; j++) { + ImGui::Text("%d", j); + auto palette = palettes[j]; + for (int n = 0; n < size; n++) { + ImGui::PushID(n); + if ((n % 8) != 0) + ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y); + + ImGuiColorEditFlags palette_button_flags = + ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoPicker; + if (ImGui::ColorButton("##palette", palette[n].RGB(), + palette_button_flags, ImVec2(20, 20))) + current_color_ = + ImVec4(palette[n].rgb.x, palette[n].rgb.y, palette[n].rgb.z, + current_color_.w); // Preserve alpha! + + ImGui::PopID(); + } + } + ImGui::TreePop(); + } + } + return absl::OkStatus(); +} + +void PaletteEditor::DisplayPalette(gfx::SNESPalette& palette, bool loaded) { + static ImVec4 color = ImVec4(0, 0, 0, 255.f); + ImGuiColorEditFlags misc_flags = ImGuiColorEditFlags_AlphaPreview | + ImGuiColorEditFlags_NoDragDrop | + ImGuiColorEditFlags_NoOptions; + + // Generate a default palette. The palette will persist and can be edited. + static bool init = false; + static ImVec4 saved_palette[256] = {}; + if (loaded && !init) { + for (int n = 0; n < palette.size_; n++) { + saved_palette[n].x = palette.GetColor(n).rgb.x / 255; + saved_palette[n].y = palette.GetColor(n).rgb.y / 255; + saved_palette[n].z = palette.GetColor(n).rgb.z / 255; + saved_palette[n].w = 255; // Alpha + } + init = true; + } + + static ImVec4 backup_color; + bool open_popup = ImGui::ColorButton("MyColor##3b", color, misc_flags); + ImGui::SameLine(0, ImGui::GetStyle().ItemInnerSpacing.x); + open_popup |= ImGui::Button("Palette"); + if (open_popup) { + ImGui::OpenPopup("mypicker"); + backup_color = color; + } + if (ImGui::BeginPopup("mypicker")) { + ImGui::Text("Current Overworld Palette"); + ImGui::Separator(); + ImGui::ColorPicker4("##picker", (float*)&color, + misc_flags | ImGuiColorEditFlags_NoSidePreview | + ImGuiColorEditFlags_NoSmallPreview); + ImGui::SameLine(); + + ImGui::BeginGroup(); // Lock X position + ImGui::Text("Current ==>"); + ImGui::SameLine(); + ImGui::Text("Previous"); + + ImGui::ColorButton( + "##current", color, + ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_AlphaPreviewHalf, + ImVec2(60, 40)); + ImGui::SameLine(); + + if (ImGui::ColorButton( + "##previous", backup_color, + ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_AlphaPreviewHalf, + ImVec2(60, 40))) + color = backup_color; + ImGui::Separator(); + ImGui::Text("Palette"); + for (int n = 0; n < IM_ARRAYSIZE(saved_palette); n++) { + ImGui::PushID(n); + if ((n % 8) != 0) ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y); + + ImGuiColorEditFlags palette_button_flags = ImGuiColorEditFlags_NoAlpha | + ImGuiColorEditFlags_NoPicker | + ImGuiColorEditFlags_NoTooltip; + if (ImGui::ColorButton("##palette", saved_palette[n], + palette_button_flags, ImVec2(20, 20))) + color = ImVec4(saved_palette[n].x, saved_palette[n].y, + saved_palette[n].z, color.w); // Preserve alpha! + + if (ImGui::BeginDragDropTarget()) { + if (const ImGuiPayload* payload = + ImGui::AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_3F)) + memcpy((float*)&saved_palette[n], payload->Data, sizeof(float) * 3); + if (const ImGuiPayload* payload = + ImGui::AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_4F)) + memcpy((float*)&saved_palette[n], payload->Data, sizeof(float) * 4); + ImGui::EndDragDropTarget(); + } + + ImGui::PopID(); + } + ImGui::EndGroup(); + ImGui::EndPopup(); + } +} + +} // namespace editor +} // namespace app +} // namespace yaze \ No newline at end of file diff --git a/src/app/editor/palette_editor.h b/src/app/editor/palette_editor.h new file mode 100644 index 00000000..80ab485f --- /dev/null +++ b/src/app/editor/palette_editor.h @@ -0,0 +1,42 @@ +#ifndef YAZE_APP_EDITOR_PALETTE_EDITOR_H +#define YAZE_APP_EDITOR_PALETTE_EDITOR_H + +#include + +#include "absl/status/status.h" +#include "app/gfx/snes_palette.h" +#include "app/rom.h" +#include "gui/canvas.h" +#include "gui/icons.h" + +namespace yaze { +namespace app { +namespace editor { + +static constexpr absl::string_view kPaletteCategoryNames[] = { + "Sword", "Shield", "Clothes", "World Colors", + "Area Colors", "Enemies", "Dungeons", "World Map", + "Dungeon Map", "Triforce", "Crystal"}; + +static constexpr absl::string_view kPaletteGroupNames[] = { + "swords", "shields", "armors", "ow_main", + "ow_aux", "global_sprites", "dungeon_main", "ow_mini_map", + "ow_mini_map", "3d_object", "3d_object"}; + +class PaletteEditor { + public: + absl::Status Update(); + void DisplayPalette(gfx::SNESPalette& palette, bool loaded); + + auto SetupROM(ROM& rom) { rom_ = rom; } + + private: + ImVec4 current_color_; + ROM rom_; +}; + +} // namespace editor +} // namespace app +} // namespace yaze + +#endif \ No newline at end of file diff --git a/src/app/editor/screen_editor.cc b/src/app/editor/screen_editor.cc new file mode 100644 index 00000000..bcf19352 --- /dev/null +++ b/src/app/editor/screen_editor.cc @@ -0,0 +1,201 @@ +#include "app/editor/screen_editor.h" + +#include + +#include +#include +#include +#include +#include + +#include "absl/status/statusor.h" +#include "absl/strings/str_format.h" +#include "absl/strings/string_view.h" +#include "app/core/common.h" +#include "app/core/constants.h" +#include "app/gfx/bitmap.h" +#include "app/gfx/snes_tile.h" +#include "gui/canvas.h" +#include "gui/icons.h" +#include "gui/input.h" + +namespace yaze { +namespace app { +namespace editor { + +ScreenEditor::ScreenEditor() { screen_canvas_.SetCanvasSize(ImVec2(512, 512)); } + +void ScreenEditor::Update() { + TAB_BAR("##TabBar") + DrawInventoryMenuEditor(); + DrawTitleScreenEditor(); + DrawNamingScreenEditor(); + DrawOverworldMapEditor(); + DrawDungeonMapsEditor(); + DrawMosaicEditor(); + END_TAB_BAR() +} + +void ScreenEditor::DrawWorldGrid(int world, int h, int w) { + const float time = (float)ImGui::GetTime(); + + int i = 0; + if (world == 1) { + i = 64; + } else if (world == 2) { + i = 128; + } + for (int y = 0; y < h; y++) + for (int x = 0; x < w; x++) { + if (x > 0) ImGui::SameLine(); + ImGui::PushID(y * 4 + x); + std::string label = absl::StrCat(" #", absl::StrFormat("%x", i)); + if (ImGui::Selectable(label.c_str(), mosaic_tiles_[i] != 0, 0, + ImVec2(35, 25))) { + mosaic_tiles_[i] ^= 1; + } + ImGui::PopID(); + i++; + } +} + +void ScreenEditor::DrawInventoryMenuEditor() { + TAB_ITEM("Inventory Menu") + + static bool create = false; + if (!create && rom_.isLoaded()) { + inventory_.Create(); + palette_ = inventory_.Palette(); + create = true; + } + + DrawInventoryToolset(); + + if (ImGui::BeginTable("InventoryScreen", 3, ImGuiTableFlags_Resizable)) { + ImGui::TableSetupColumn("Canvas"); + ImGui::TableSetupColumn("Tiles"); + ImGui::TableSetupColumn("Palette"); + ImGui::TableHeadersRow(); + + ImGui::TableNextColumn(); + screen_canvas_.DrawBackground(); + screen_canvas_.DrawContextMenu(); + screen_canvas_.DrawBitmap(inventory_.Bitmap(), 2, create); + screen_canvas_.DrawGrid(32.0f); + screen_canvas_.DrawOverlay(); + + ImGui::TableNextColumn(); + tilesheet_canvas_.DrawBackground(ImVec2(128 * 2 + 2, (192 * 2) + 4)); + tilesheet_canvas_.DrawContextMenu(); + tilesheet_canvas_.DrawBitmap(inventory_.Tilesheet(), 2, create); + tilesheet_canvas_.DrawGrid(16.0f); + tilesheet_canvas_.DrawOverlay(); + + ImGui::TableNextColumn(); + gui::DisplayPalette(palette_, create); + + ImGui::EndTable(); + } + ImGui::Separator(); + END_TAB_ITEM() +} + +void ScreenEditor::DrawTitleScreenEditor() { + TAB_ITEM("Title Screen") + END_TAB_ITEM() +} +void ScreenEditor::DrawNamingScreenEditor() { + TAB_ITEM("Naming Screen") + END_TAB_ITEM() +} +void ScreenEditor::DrawOverworldMapEditor() { + TAB_ITEM("Overworld Map") + END_TAB_ITEM() +} +void ScreenEditor::DrawDungeonMapsEditor() { + TAB_ITEM("Dungeon Maps") + END_TAB_ITEM() +} + +void ScreenEditor::DrawMosaicEditor() { + TAB_ITEM("Mosaic Transitions") + + if (ImGui::BeginTable("Worlds", 3, ImGuiTableFlags_Borders)) { + ImGui::TableSetupColumn("Light World"); + ImGui::TableSetupColumn("Dark World"); + ImGui::TableSetupColumn("Special World"); + ImGui::TableHeadersRow(); + + ImGui::TableNextColumn(); + DrawWorldGrid(0); + + ImGui::TableNextColumn(); + DrawWorldGrid(1); + + ImGui::TableNextColumn(); + DrawWorldGrid(2, 4); + + ImGui::EndTable(); + } + + gui::InputHex("Routine Location", &overworldCustomMosaicASM); + + if (ImGui::Button("Generate Mosaic Assembly")) { + auto mosaic = + rom_.PatchOverworldMosaic(mosaic_tiles_, overworldCustomMosaicASM); + if (!mosaic.ok()) { + std::cout << mosaic; + } + } + + END_TAB_ITEM() +} + +void ScreenEditor::DrawToolset() { + static bool show_bg1 = true; + static bool show_bg2 = true; + static bool show_bg3 = true; + + static bool drawing_bg1 = true; + static bool drawing_bg2 = false; + static bool drawing_bg3 = false; + + ImGui::Checkbox("Show BG1", &show_bg1); + ImGui::SameLine(); + ImGui::Checkbox("Show BG2", &show_bg2); + + ImGui::Checkbox("Draw BG1", &drawing_bg1); + ImGui::SameLine(); + ImGui::Checkbox("Draw BG2", &drawing_bg2); + ImGui::SameLine(); + ImGui::Checkbox("Draw BG3", &drawing_bg3); +} + +void ScreenEditor::DrawInventoryToolset() { + if (ImGui::BeginTable("InventoryToolset", 8, ImGuiTableFlags_SizingFixedFit, + ImVec2(0, 0))) { + ImGui::TableSetupColumn("#drawTool"); + ImGui::TableSetupColumn("#sep1"); + ImGui::TableSetupColumn("#zoomOut"); + ImGui::TableSetupColumn("#zoomIN"); + ImGui::TableSetupColumn("#sep2"); + ImGui::TableSetupColumn("#bg2Tool"); + ImGui::TableSetupColumn("#bg3Tool"); + ImGui::TableSetupColumn("#itemTool"); + + BUTTON_COLUMN(ICON_MD_UNDO) + BUTTON_COLUMN(ICON_MD_REDO) + TEXT_COLUMN(ICON_MD_MORE_VERT) + BUTTON_COLUMN(ICON_MD_ZOOM_OUT) + BUTTON_COLUMN(ICON_MD_ZOOM_IN) + TEXT_COLUMN(ICON_MD_MORE_VERT) + BUTTON_COLUMN(ICON_MD_DRAW) + BUTTON_COLUMN(ICON_MD_BUILD) + + ImGui::EndTable(); + } +} + +} // namespace editor +} // namespace app +} // namespace yaze \ No newline at end of file diff --git a/src/app/editor/screen_editor.h b/src/app/editor/screen_editor.h new file mode 100644 index 00000000..6de72848 --- /dev/null +++ b/src/app/editor/screen_editor.h @@ -0,0 +1,60 @@ +#ifndef YAZE_APP_EDITOR_SCREEN_EDITOR_H +#define YAZE_APP_EDITOR_SCREEN_EDITOR_H + +#include + +#include + +#include "app/core/constants.h" +#include "app/gfx/bitmap.h" +#include "app/gfx/snes_palette.h" +#include "app/gfx/snes_tile.h" +#include "app/rom.h" +#include "app/zelda3/inventory.h" +#include "gui/canvas.h" +#include "gui/color.h" +#include "gui/icons.h" + +namespace yaze { +namespace app { +namespace editor { + +using MosaicArray = std::array; +static int overworldCustomMosaicASM = 0x1301D0; + +class ScreenEditor { + public: + ScreenEditor(); + void SetupROM(ROM &rom) { + rom_ = rom; + inventory_.SetupROM(rom_); + } + void Update(); + + private: + void DrawMosaicEditor(); + void DrawTitleScreenEditor(); + void DrawNamingScreenEditor(); + void DrawOverworldMapEditor(); + void DrawDungeonMapsEditor(); + void DrawInventoryMenuEditor(); + + void DrawToolset(); + void DrawInventoryToolset(); + void DrawWorldGrid(int world, int h = 8, int w = 8); + + char mosaic_tiles_[core::kNumOverworldMaps]; + + ROM rom_; + Bytes all_gfx_; + zelda3::Inventory inventory_; + gfx::SNESPalette palette_; + gui::Canvas screen_canvas_; + gui::Canvas tilesheet_canvas_; +}; + +} // namespace editor +} // namespace app +} // namespace yaze + +#endif \ No newline at end of file diff --git a/src/app/gfx/bitmap.cc b/src/app/gfx/bitmap.cc new file mode 100644 index 00000000..c4ab757b --- /dev/null +++ b/src/app/gfx/bitmap.cc @@ -0,0 +1,135 @@ +#include "bitmap.h" + +#include + +#include +#include + +#include "absl/status/status.h" +#include "absl/status/statusor.h" +#include "absl/strings/str_cat.h" +#include "app/core/constants.h" +#include "app/gfx/snes_palette.h" + +namespace yaze { +namespace app { +namespace gfx { + +namespace { +void GrayscalePalette(SDL_Palette *palette) { + for (int i = 0; i < 8; i++) { + palette->colors[i].r = i * 31; + palette->colors[i].g = i * 31; + palette->colors[i].b = i * 31; + } +} +} // namespace + +Bitmap::Bitmap(int width, int height, int depth, uchar *data) { + Create(width, height, depth, data); +} + +Bitmap::Bitmap(int width, int height, int depth, int data_size) { + Create(width, height, depth, data_size); +} + +Bitmap::Bitmap(int width, int height, int depth, uchar *data, int data_size) { + Create(width, height, depth, data, data_size); +} + +// Pass raw pixel data directly to the surface +void Bitmap::Create(int width, int height, int depth, uchar *data) { + active_ = true; + width_ = width; + height_ = height; + depth_ = depth; + pixel_data_ = data; + surface_ = std::unique_ptr( + SDL_CreateRGBSurfaceWithFormat(0, width_, height_, depth_, + SDL_PIXELFORMAT_INDEX8), + SDL_Surface_Deleter()); + surface_->pixels = pixel_data_; + GrayscalePalette(surface_->format->palette); +} + +// Reserves data to later draw to surface via pointer +void Bitmap::Create(int width, int height, int depth, int size) { + active_ = true; + width_ = width; + height_ = height; + depth_ = depth; + data_size_ = size; + data_.reserve(size); + pixel_data_ = data_.data(); + surface_ = std::unique_ptr( + SDL_CreateRGBSurfaceWithFormat(0, width, height, depth, + SDL_PIXELFORMAT_INDEX8), + SDL_Surface_Deleter()); + surface_->pixels = pixel_data_; + GrayscalePalette(surface_->format->palette); +} + +// Pass raw pixel data directly to the surface +void Bitmap::Create(int width, int height, int depth, uchar *data, int size) { + active_ = true; + width_ = width; + height_ = height; + depth_ = depth; + pixel_data_ = data; + data_size_ = size; + surface_ = std::unique_ptr( + SDL_CreateRGBSurfaceWithFormat(0, width_, height_, depth_, + SDL_PIXELFORMAT_INDEX8), + SDL_Surface_Deleter()); + surface_->pixels = pixel_data_; + GrayscalePalette(surface_->format->palette); +} + +void Bitmap::Create(int width, int height, int depth, Bytes data) { + active_ = true; + width_ = width; + height_ = height; + depth_ = depth; + data_ = data; + pixel_data_ = data_.data(); + surface_ = std::unique_ptr( + SDL_CreateRGBSurfaceWithFormat(0, width_, height_, depth_, + SDL_PIXELFORMAT_INDEX8), + SDL_Surface_Deleter()); + surface_->pixels = pixel_data_; + GrayscalePalette(surface_->format->palette); +} + +void Bitmap::Apply(Bytes data) { + pixel_data_ = data.data(); + data_ = data; +} + +// Creates the texture that will be displayed to the screen. +void Bitmap::CreateTexture(std::shared_ptr renderer) { + texture_ = std::shared_ptr{ + SDL_CreateTextureFromSurface(renderer.get(), surface_.get()), + SDL_Texture_Deleter{}}; +} + +// Convert SNESPalette to SDL_Palette for surface. +void Bitmap::ApplyPalette(const SNESPalette &palette) { + palette_ = palette; + for (int i = 0; i < palette.size_; ++i) { + if (palette.GetColor(i).transparent) { + surface_->format->palette->colors[i].r = 0; + surface_->format->palette->colors[i].g = 0; + surface_->format->palette->colors[i].b = 0; + surface_->format->palette->colors[i].a = 0; + } else { + surface_->format->palette->colors[i].r = palette.GetColor(i).rgb.x; + surface_->format->palette->colors[i].g = palette.GetColor(i).rgb.y; + surface_->format->palette->colors[i].b = palette.GetColor(i).rgb.z; + surface_->format->palette->colors[i].a = palette.GetColor(i).rgb.w; + } + } +} + +} // namespace gfx +} // namespace app +} // namespace yaze diff --git a/src/app/gfx/bitmap.h b/src/app/gfx/bitmap.h new file mode 100644 index 00000000..9ae90ee3 --- /dev/null +++ b/src/app/gfx/bitmap.h @@ -0,0 +1,87 @@ +#ifndef YAZE_APP_GFX_BITMAP_H +#define YAZE_APP_GFX_BITMAP_H + +#include + +#include +#include + +#include "absl/status/status.h" +#include "absl/status/statusor.h" +#include "absl/strings/str_cat.h" +#include "app/core/constants.h" +#include "app/gfx/snes_palette.h" + +namespace yaze { +namespace app { +namespace gfx { + +class Bitmap { + public: + Bitmap() = default; + Bitmap(int width, int height, int depth, uchar *data); + Bitmap(int width, int height, int depth, int data_size); + Bitmap(int width, int height, int depth, uchar *data, int data_size); + + void Create(int width, int height, int depth, uchar *data); + void Create(int width, int height, int depth, int data_size); + void Create(int width, int height, int depth, uchar *data, int data_size); + void Create(int width, int height, int depth, Bytes data); + + void Apply(Bytes data); + + void CreateTexture(std::shared_ptr renderer); + + void ApplyPalette(const SNESPalette &palette); + + void WriteToPixel(int position, uchar value) { + this->pixel_data_[position] = value; + } + + int GetWidth() const { return width_; } + int GetHeight() const { return height_; } + auto GetSize() const { return data_size_; } + auto GetData() const { return pixel_data_; } + auto GetByte(int i) const { return pixel_data_[i]; } + auto GetTexture() const { return texture_.get(); } + auto GetSurface() const { return surface_.get(); } + auto IsActive() const { return active_; } + + private: + struct SDL_Texture_Deleter { + void operator()(SDL_Texture *p) const { + if (p != nullptr) { + SDL_DestroyTexture(p); + p = nullptr; + } + } + }; + + struct SDL_Surface_Deleter { + void operator()(SDL_Surface *p) const { + if (p != nullptr) { + p->pixels = nullptr; + SDL_FreeSurface(p); + p = nullptr; + } + } + }; + + int width_ = 0; + int height_ = 0; + int depth_ = 0; + int data_size_ = 0; + bool freed_ = false; + bool active_ = false; + uchar *pixel_data_; + Bytes data_; + gfx::SNESPalette palette_; + std::shared_ptr texture_ = nullptr; + std::shared_ptr surface_ = nullptr; +}; + +} // namespace gfx +} // namespace app +} // namespace yaze + +#endif // YAZE_APP_GFX_BITMAP_H \ No newline at end of file diff --git a/src/app/gfx/snes_palette.cc b/src/app/gfx/snes_palette.cc new file mode 100644 index 00000000..5ff1c878 --- /dev/null +++ b/src/app/gfx/snes_palette.cc @@ -0,0 +1,197 @@ +#include "snes_palette.h" + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "app/core/constants.h" + +namespace yaze { +namespace app { +namespace gfx { + +ushort ConvertRGBtoSNES(const snes_color color) { + uchar red = color.red / 8; + uchar green = color.green / 8; + uchar blue = color.blue / 8; + return blue * 1024 + green * 32 + red; +} + +snes_color ConvertSNEStoRGB(const ushort color) { + snes_color toret; + + toret.red = ((color) % 32) * 8; + toret.green = ((color / 32) % 32) * 8; + toret.blue = ((color / 1024) % 32) * 8; + + toret.red = toret.red + toret.red / 32; + toret.green = toret.green + toret.green / 32; + toret.blue = toret.blue + toret.blue / 32; + return toret; +} + +snes_palette* Extract(const char* data, const unsigned int offset, + const unsigned int palette_size) { + snes_palette* toret = nullptr; // palette_create(palette_size, 0) + unsigned colnum = 0; + for (int i = 0; i < palette_size * 2; i += 2) { + unsigned short snes_color; + snes_color = ((uchar)data[offset + i + 1]) << 8; + snes_color = snes_color | ((uchar)data[offset + i]); + toret->colors[colnum] = ConvertSNEStoRGB(snes_color); + colnum++; + } + return toret; +} + +char* Convert(const snes_palette pal) { + char* toret = (char*)malloc(pal.size * 2); + for (unsigned int i = 0; i < pal.size; i++) { + unsigned short snes_data = ConvertRGBtoSNES(pal.colors[i]); + toret[i * 2] = snes_data & 0xFF; + toret[i * 2 + 1] = snes_data >> 8; + } + return toret; +} + +// ============================================================================ + +SNESColor::SNESColor() : rgb(ImVec4(0.f, 0.f, 0.f, 0.f)) {} + +SNESColor::SNESColor(snes_color val) { + rgb.x = val.red; + rgb.y = val.green; + rgb.z = val.blue; +} + +SNESColor::SNESColor(ImVec4 val) : rgb(val) { + snes_color col; + col.red = (uchar)val.x; + col.blue = (uchar)val.y; + col.green = (uchar)val.z; + snes = ConvertRGBtoSNES(col); +} + +void SNESColor::setRgb(ImVec4 val) { + rgb = val; + snes_color col; + col.red = val.x; + col.blue = val.y; + col.green = val.z; + snes = ConvertRGBtoSNES(col); +} + +void SNESColor::setSNES(snes_color val) { + rgb = ImVec4(val.red, val.green, val.blue, 255.f); +} + +void SNESColor::setSNES(uint16_t val) { + snes = val; + snes_color col = ConvertSNEStoRGB(val); + rgb = ImVec4(col.red, col.green, col.blue, 0.f); +} + +// ============================================================================ + +SNESPalette::SNESPalette(uint8_t mSize) : size_(mSize) { + for (unsigned int i = 0; i < mSize; i++) { + SNESColor col; + colors.push_back(col); + } +} + +SNESPalette::SNESPalette(char* data) : size_(sizeof(data) / 2) { + assert((sizeof(data) % 4 == 0) && (sizeof(data) <= 32)); + for (unsigned i = 0; i < sizeof(data); i += 2) { + SNESColor col; + col.snes = static_cast(data[i + 1]) << 8; + col.snes = col.snes | static_cast(data[i]); + snes_color mColor = ConvertSNEStoRGB(col.snes); + col.rgb = ImVec4(mColor.red, mColor.green, mColor.blue, 1.f); + colors.push_back(col); + } +} + +SNESPalette::SNESPalette(const unsigned char* snes_pal) + : size_(sizeof(snes_pal) / 2) { + assert((sizeof(snes_pal) % 4 == 0) && (sizeof(snes_pal) <= 32)); + for (unsigned i = 0; i < sizeof(snes_pal); i += 2) { + SNESColor col; + col.snes = snes_pal[i + 1] << (uint16_t)8; + col.snes = col.snes | snes_pal[i]; + snes_color mColor = ConvertSNEStoRGB(col.snes); + col.rgb = ImVec4(mColor.red, mColor.green, mColor.blue, 1.f); + colors.push_back(col); + } +} + +SNESPalette::SNESPalette(const std::vector& cols) { + for (const auto& each : cols) { + SNESColor scol; + scol.setRgb(each); + colors.push_back(scol); + } + size_ = cols.size(); +} + +SNESPalette::SNESPalette(const std::vector& cols) { + for (const auto& each : cols) { + SNESColor scol; + scol.setSNES(each); + colors.push_back(scol); + } + size_ = cols.size(); +} + +SNESPalette::SNESPalette(const std::vector& cols) { + for (const auto& each : cols) { + colors.push_back(each); + } + size_ = cols.size(); +} + +void SNESPalette::Create(const std::vector& cols) { + for (const auto each : cols) { + colors.push_back(each); + } + size_ = cols.size(); +} + +char* SNESPalette::encode() { + auto data = new char[size_ * 2]; + for (unsigned int i = 0; i < size_; i++) { + std::cout << colors[i].snes << std::endl; + data[i * 2] = (char)(colors[i].snes & 0xFF); + data[i * 2 + 1] = (char)(colors[i].snes >> 8); + } + return data; +} + +SDL_Palette* SNESPalette::GetSDL_Palette() { + auto sdl_palette = std::make_shared(); + sdl_palette->ncolors = size_; + + auto color = std::vector(size_); + for (int i = 0; i < size_; i++) { + color[i].r = (uint8_t)colors[i].rgb.x * 100; + color[i].g = (uint8_t)colors[i].rgb.y * 100; + color[i].b = (uint8_t)colors[i].rgb.z * 100; + color[i].a = 0; + std::cout << "Color " << i << " added (R:" << color[i].r + << " G:" << color[i].g << " B:" << color[i].b << ")" << std::endl; + } + sdl_palette->colors = color.data(); + return sdl_palette.get(); +} + +PaletteGroup::PaletteGroup(uint8_t mSize) : size(mSize) {} + +} // namespace gfx +} // namespace app +} // namespace yaze \ No newline at end of file diff --git a/src/app/gfx/snes_palette.h b/src/app/gfx/snes_palette.h new file mode 100644 index 00000000..1c0e4143 --- /dev/null +++ b/src/app/gfx/snes_palette.h @@ -0,0 +1,117 @@ +#ifndef YAZE_APP_GFX_PALETTE_H +#define YAZE_APP_GFX_PALETTE_H + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "app/core/constants.h" + +namespace yaze { +namespace app { +namespace gfx { + +struct snes_color { + uchar red; + uchar blue; + uchar green; +}; +using snes_color = struct snes_color; + +struct snes_palette { + uint id; + uint size; + snes_color* colors; +}; +using snes_palette = struct snes_palette; + +ushort ConvertRGBtoSNES(const snes_color color); +snes_color ConvertSNEStoRGB(const ushort snes_color); +snes_palette* Extract(const char* data, const unsigned int offset, + const unsigned int palette_size); +char* Convert(const snes_palette pal); + +struct SNESColor { + SNESColor(); + explicit SNESColor(ImVec4); + explicit SNESColor(snes_color); + + void setRgb(ImVec4); + void setSNES(snes_color); + void setSNES(uint16_t); + void setTransparent(bool t) { transparent = t; } + + auto RGB() { + return ImVec4(rgb.x / 255, rgb.y / 255, rgb.z / 255, rgb.w); + } + + bool transparent = false; + uint16_t snes = 0; + ImVec4 rgb; +}; + +class SNESPalette { + public: + SNESPalette() = default; + explicit SNESPalette(uint8_t mSize); + explicit SNESPalette(char* snesPal); + explicit SNESPalette(const unsigned char* snes_pal); + explicit SNESPalette(const std::vector&); + explicit SNESPalette(const std::vector&); + explicit SNESPalette(const std::vector&); + + void Create(const std::vector&); + void AddColor(SNESColor color) { colors.push_back(color); } + auto GetColor(int i) const { return colors[i]; } + + SNESColor operator[](int i) { + if (i > size_) { + std::cout << "SNESPalette: Index out of bounds" << std::endl; + return colors[0]; + } + return colors[i]; + } + + char* encode(); + SDL_Palette* GetSDL_Palette(); + + int size_ = 0; + std::vector colors; +}; + +struct PaletteGroup { + PaletteGroup() = default; + explicit PaletteGroup(uint8_t mSize); + void AddPalette(SNESPalette pal) { + palettes.emplace_back(pal); + size = palettes.size(); + } + void AddColor(SNESColor color) { + if (size == 0) { + SNESPalette empty_pal; + palettes.emplace_back(empty_pal); + } + palettes[0].AddColor(color); + } + SNESPalette operator[](int i) { + if (i > size) { + std::cout << "PaletteGroup: Index out of bounds" << std::endl; + return palettes[0]; + } + return palettes[i]; + } + int size = 0; + std::vector palettes; +}; + +} // namespace gfx +} // namespace app +} // namespace yaze + +#endif // YAZE_APP_GFX_PALETTE_H \ No newline at end of file diff --git a/src/app/gfx/snes_tile.cc b/src/app/gfx/snes_tile.cc new file mode 100644 index 00000000..3e02f34b --- /dev/null +++ b/src/app/gfx/snes_tile.cc @@ -0,0 +1,29 @@ +#include "snes_tile.h" + +#include +#include + +#include "app/core/constants.h" + +namespace yaze { +namespace app { +namespace gfx { + +TileInfo GetTilesInfo(ushort tile) { + // vhopppcc cccccccc + bool o = false; + bool v = false; + bool h = false; + auto tid = (ushort)(tile & core::TileNameMask); + auto p = (uchar)((tile >> 10) & 0x07); + + o = ((tile & core::TilePriorityBit) == core::TilePriorityBit); + h = ((tile & core::TileHFlipBit) == core::TileHFlipBit); + v = ((tile & core::TileVFlipBit) == core::TileVFlipBit); + + return TileInfo(tid, p, v, h, o); +} + +} // namespace gfx +} // namespace app +} // namespace yaze \ No newline at end of file diff --git a/src/app/gfx/snes_tile.h b/src/app/gfx/snes_tile.h new file mode 100644 index 00000000..72764333 --- /dev/null +++ b/src/app/gfx/snes_tile.h @@ -0,0 +1,94 @@ +#ifndef YAZE_APP_GFX_SNES_TILE_H +#define YAZE_APP_GFX_SNES_TILE_H + +#include +#include + +#include "app/core/constants.h" + +namespace yaze { +namespace app { +namespace gfx { + +struct tile8 { + unsigned int id; + char data[64]; + unsigned int palette_id; +}; +using tile8 = struct tile8; + +// vhopppcc cccccccc +// [0, 1] +// [2, 3] +class TileInfo { + public: + ushort id_; + bool over_; + bool vertical_mirror_; + bool horizontal_mirror_; + uchar palette_; + TileInfo() = default; + TileInfo(ushort id, uchar palette, bool v, bool h, bool o) + : id_(id), + over_(o), + vertical_mirror_(v), + horizontal_mirror_(h), + palette_(palette) {} +}; + +TileInfo GetTilesInfo(ushort tile); + +class Tile32 { + public: + ushort tile0_; + ushort tile1_; + ushort tile2_; + ushort tile3_; + + Tile32(ushort t0, ushort t1, ushort t2, ushort t3) + : tile0_(t0), tile1_(t1), tile2_(t2), tile3_(t3) {} +}; + +class Tile16 { + public: + TileInfo tile0_; + TileInfo tile1_; + TileInfo tile2_; + TileInfo tile3_; + std::vector tiles_info; + + Tile16() = default; + Tile16(TileInfo t0, TileInfo t1, TileInfo t2, TileInfo t3) + : tile0_(t0), tile1_(t1), tile2_(t2), tile3_(t3) { + tiles_info.push_back(tile0_); + tiles_info.push_back(tile1_); + tiles_info.push_back(tile2_); + tiles_info.push_back(tile3_); + } +}; + +class OAMTile { + public: + int x_; + int y_; + int mx_; + int my_; + int pal_; + ushort tile_; + OAMTile() = default; + OAMTile(int x, int y, ushort tile, int pal, bool upper = false, int mx = 0, + int my = 0) + : x_(x), y_(y), mx_(mx), my_(my), pal_(pal) { + if (upper) { + tile_ = (ushort)(tile + 512); + } else { + tile_ = (ushort)(tile + 256 + 512); + } + } +}; + +} // namespace gfx +} // namespace app +} // namespace yaze + +#endif // YAZE_APP_GFX_SNES_TILE_H \ No newline at end of file diff --git a/src/app/rom.cc b/src/app/rom.cc new file mode 100644 index 00000000..8c6f6310 --- /dev/null +++ b/src/app/rom.cc @@ -0,0 +1,851 @@ +#include "rom.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "absl/status/status.h" +#include "absl/status/statusor.h" +#include "absl/strings/str_cat.h" +#include "absl/strings/str_format.h" +#include "absl/strings/string_view.h" +#include "app/core/common.h" +#include "app/core/constants.h" +#include "app/gfx/bitmap.h" + +namespace yaze { +namespace app { + +namespace lc_lz2 { + +void PrintCompressionPiece(const std::shared_ptr& piece) { + printf("Command: %d\n", piece->command); + printf("Command kength: %d\n", piece->length); + printf("Argument:"); + auto arg_size = piece->argument.size(); + for (int i = 0; i < arg_size; ++i) { + printf("%02X ", piece->argument.at(i)); + } + printf("\nArgument length: %d\n", piece->argument_length); +} + +void PrintCompressionChain( + const std::shared_ptr& compressed_chain_start) { + auto compressed_chain = compressed_chain_start->next; + while (compressed_chain != nullptr) { + printf("- Compression Piece -\n"); + PrintCompressionPiece(compressed_chain); + compressed_chain = compressed_chain->next; + } +} + +void CheckByteRepeat(const uchar* rom_data, DataSizeArray& data_size_taken, + CommandArgumentArray& cmd_args, uint& src_data_pos, + const uint last_pos) { + uint pos = src_data_pos; + char byte_to_repeat = rom_data[pos]; + while (pos <= last_pos && rom_data[pos] == byte_to_repeat) { + data_size_taken[kCommandByteFill]++; + pos++; + } + cmd_args[kCommandByteFill][0] = byte_to_repeat; +} + +void CheckWordRepeat(const uchar* rom_data, DataSizeArray& data_size_taken, + CommandArgumentArray& cmd_args, uint& src_data_pos, + const uint last_pos) { + if (src_data_pos + 2 <= last_pos && + rom_data[src_data_pos] != rom_data[src_data_pos + 1]) { + uint pos = src_data_pos; + char byte1 = rom_data[pos]; + char byte2 = rom_data[pos + 1]; + pos += 2; + data_size_taken[kCommandWordFill] = 2; + while (pos + 1 <= last_pos) { + if (rom_data[pos] == byte1 && rom_data[pos + 1] == byte2) + data_size_taken[kCommandWordFill] += 2; + else + break; + pos += 2; + } + cmd_args[kCommandWordFill][0] = byte1; + cmd_args[kCommandWordFill][1] = byte2; + } +} + +void CheckIncByte(const uchar* rom_data, DataSizeArray& data_size_taken, + CommandArgumentArray& cmd_args, uint& src_data_pos, + const uint last_pos) { + uint pos = src_data_pos; + char byte = rom_data[pos]; + pos++; + data_size_taken[kCommandIncreasingFill] = 1; + byte++; + while (pos <= last_pos && byte == rom_data[pos]) { + data_size_taken[kCommandIncreasingFill]++; + byte++; + pos++; + } + cmd_args[kCommandIncreasingFill][0] = rom_data[src_data_pos]; +} + +void CheckIntraCopy(const uchar* rom_data, DataSizeArray& data_size_taken, + CommandArgumentArray& cmd_args, uint& src_data_pos, + const uint last_pos, uint start) { + if (src_data_pos != start) { + uint searching_pos = start; + uint current_pos_u = src_data_pos; + uint copied_size = 0; + uint search_start = start; + + while (searching_pos < src_data_pos && current_pos_u <= last_pos) { + while (rom_data[current_pos_u] != rom_data[searching_pos] && + searching_pos < src_data_pos) + searching_pos++; + search_start = searching_pos; + while (current_pos_u <= last_pos && + rom_data[current_pos_u] == rom_data[searching_pos] && + searching_pos < src_data_pos) { + copied_size++; + current_pos_u++; + searching_pos++; + } + if (copied_size > data_size_taken[kCommandRepeatingBytes]) { + search_start -= start; + printf("- Found repeat of %d at %d\n", copied_size, search_start); + data_size_taken[kCommandRepeatingBytes] = copied_size; + cmd_args[kCommandRepeatingBytes][0] = search_start & kSnesByteMax; + cmd_args[kCommandRepeatingBytes][1] = search_start >> 8; + } + current_pos_u = src_data_pos; + copied_size = 0; + } + } +} + +// Check if a command managed to pick up `max_win` or more bytes +// Avoids being even with copy command, since it's possible to merge copy +void ValidateForByteGain(const DataSizeArray& data_size_taken, + const CommandSizeArray& cmd_size, uint& max_win, + uint& cmd_with_max) { + for (uint cmd_i = 1; cmd_i < 5; cmd_i++) { + uint cmd_size_taken = data_size_taken[cmd_i]; + // TODO(@scawful): Replace conditional with table of command sizes + // "Table that is even with copy but all other cmd are 2" + auto table_check = + !(cmd_i == kCommandRepeatingBytes && cmd_size_taken == 3); + if (cmd_size_taken > max_win && cmd_size_taken > cmd_size[cmd_i] && + table_check) { + printf("==> C:%d / S:%d\n", cmd_i, cmd_size_taken); + cmd_with_max = cmd_i; + max_win = cmd_size_taken; + } + } +} + +void CompressionCommandAlternative( + const uchar* rom_data, std::shared_ptr& compressed_chain, + const CommandSizeArray& cmd_size, const CommandArgumentArray& cmd_args, + uint& src_data_pos, uint& comp_accumulator, uint& cmd_with_max, + uint& max_win) { + printf("- Ok we get a gain from %d\n", cmd_with_max); + std::string buffer; + buffer.push_back(cmd_args[cmd_with_max][0]); + if (cmd_size[cmd_with_max] == 2) { + buffer.push_back(cmd_args[cmd_with_max][1]); + } + + auto new_comp_piece = std::make_shared( + cmd_with_max, max_win, buffer, cmd_size[cmd_with_max]); + PrintCompressionPiece(new_comp_piece); + // If we let non compressed stuff, we need to add a copy chunk before + if (comp_accumulator != 0) { + std::string copy_buff; + copy_buff.resize(comp_accumulator); + for (int i = 0; i < comp_accumulator; ++i) { + copy_buff[i] = rom_data[i + src_data_pos - comp_accumulator]; + } + auto copy_chunk = std::make_shared( + kCommandDirectCopy, comp_accumulator, copy_buff, comp_accumulator); + compressed_chain->next = copy_chunk; + compressed_chain = copy_chunk; + } else { + compressed_chain->next = new_comp_piece; + compressed_chain = new_comp_piece; + } + src_data_pos += max_win; + comp_accumulator = 0; +} + +absl::StatusOr> SplitCompressionPiece( + std::shared_ptr& piece, int mode) { + std::shared_ptr new_piece; + uint length_left = piece->length - kMaxLengthCompression; + piece->length = kMaxLengthCompression; + + switch (piece->command) { + case kCommandByteFill: + case kCommandWordFill: + new_piece = std::make_shared( + piece->command, length_left, piece->argument, piece->argument_length); + break; + case kCommandIncreasingFill: + new_piece = std::make_shared( + piece->command, length_left, piece->argument, piece->argument_length); + new_piece->argument[0] = + (char)(piece->argument[0] + kMaxLengthCompression); + break; + case kCommandDirectCopy: + piece->argument_length = kMaxLengthCompression; + new_piece = std::make_shared( + piece->command, length_left, nullptr, length_left); + // MEMCPY + for (int i = 0; i < length_left; ++i) { + new_piece->argument[i] = piece->argument[i + kMaxLengthCompression]; + } + break; + case kCommandRepeatingBytes: { + piece->argument_length = kMaxLengthCompression; + uint offset = piece->argument[0] + (piece->argument[1] << 8); + new_piece = std::make_shared( + piece->command, length_left, piece->argument, piece->argument_length); + if (mode == kNintendoMode2) { + new_piece->argument[0] = + (offset + kMaxLengthCompression) & kSnesByteMax; + new_piece->argument[1] = (offset + kMaxLengthCompression) >> 8; + } + if (mode == kNintendoMode1) { + new_piece->argument[1] = + (offset + kMaxLengthCompression) & kSnesByteMax; + new_piece->argument[0] = (offset + kMaxLengthCompression) >> 8; + } + } break; + default: { + return absl::InvalidArgumentError( + "SplitCompressionCommand: Invalid Command"); + } + } + return new_piece; +} + +Bytes CreateCompressionString(std::shared_ptr& start, + int mode) { + uint pos = 0; + auto piece = start; + Bytes output; + + while (piece != nullptr) { + if (piece->length <= kMaxLengthNormalHeader) { // Normal header + output.push_back(BUILD_HEADER(piece->command, piece->length)); + pos++; + } else { + if (piece->length <= kMaxLengthCompression) { + output.push_back(kCompressionStringMod | ((uchar)piece->command << 2) | + (((piece->length - 1) & 0xFF00) >> 8)); + pos++; + printf("Building extended header : cmd: %d, length: %d - %02X\n", + piece->command, piece->length, output[pos - 1]); + output.push_back(((piece->length - 1) & 0x00FF)); // (char) + pos++; + } else { + // We need to split the command + auto new_piece = SplitCompressionPiece(piece, mode); + if (!new_piece.ok()) { + std::cout << new_piece.status().ToString() << std::endl; + } + printf("New added piece\n"); + auto piece_data = new_piece.value(); + PrintCompressionPiece(piece_data); + piece_data->next = piece->next; + piece->next = piece_data; + continue; + } + } + + if (piece->command == kCommandRepeatingBytes) { + char tmp[2]; + tmp[0] = piece->argument[0]; + tmp[1] = piece->argument[1]; + if (mode == kNintendoMode1) { + tmp[0] = piece->argument[1]; + tmp[1] = piece->argument[0]; + } + for (const auto& each : tmp) { + output.push_back(each); + pos++; + } + } else { + for (int i = 0; i < piece->argument_length; ++i) { + output.push_back(piece->argument[i]); + pos++; + } + } + pos += piece->argument_length; + piece = piece->next; + } + output.push_back(kSnesByteMax); + return output; +} + +absl::Status ValidateCompressionResult( + CompressionPiecePointer& compressed_chain_start, int mode, int start, + int src_data_pos) { + if (compressed_chain_start->next != nullptr) { + ROM temp_rom; + RETURN_IF_ERROR(temp_rom.LoadFromBytes( + CreateCompressionString(compressed_chain_start->next, mode))) + ASSIGN_OR_RETURN(auto decomp_data, temp_rom.Decompress(0, temp_rom.size())) + if (!std::equal(decomp_data.begin() + start, decomp_data.end(), + temp_rom.begin())) { + return absl::InternalError(absl::StrFormat( + "Compressed data does not match uncompressed data at %d\n", + (uint)(src_data_pos - start))); + } + } + return absl::OkStatus(); +} + +// Merge consecutive copy if possible +CompressionPiecePointer MergeCopy(CompressionPiecePointer& start) { + CompressionPiecePointer piece = start; + + while (piece != nullptr) { + if (piece->command == kCommandDirectCopy && piece->next != nullptr && + piece->next->command == kCommandDirectCopy && + piece->length + piece->next->length <= kMaxLengthCompression) { + uint previous_length = piece->length; + piece->length = piece->length + piece->next->length; + + for (int i = 0; i < piece->next->argument_length; ++i) { + piece->argument[i + previous_length] = piece->next->argument[i]; + } + piece->argument_length = piece->length; + PrintCompressionPiece(piece); + + auto p_next_next = piece->next->next; + piece->next = p_next_next; + continue; // Next could be another copy + } + piece = piece->next; + } + return start; +} + +} // namespace lc_lz2 + +namespace { + +int GetGraphicsAddress(const uchar* data, uint8_t offset) { + auto part_one = data[kOverworldGraphicsPos1 + offset] << 16; + auto part_two = data[kOverworldGraphicsPos2 + offset] << 8; + auto part_three = data[kOverworldGraphicsPos3 + offset]; + auto snes_addr = (part_one | part_two | part_three); + return core::SnesToPc(snes_addr); +} + +Bytes SnesTo8bppSheet(Bytes sheet, int bpp) { + int xx = 0; // positions where we are at on the sheet + int yy = 0; + int pos = 0; + int ypos = 0; + int num_tiles = 64; + int buffer_size = 0x1000; + if (bpp == 2) { + bpp = 16; + num_tiles = 128; + buffer_size = 0x2000; + } else if (bpp == 3) { + bpp = 24; + } + Bytes sheet_buffer_out(buffer_size); + + for (int i = 0; i < num_tiles; i++) { // for each tiles, 16 per line + for (int y = 0; y < 8; y++) { // for each line + for (int x = 0; x < 8; x++) { //[0] + [1] + [16] + auto b1 = (sheet[(y * 2) + (bpp * pos)] & (kGraphicsBitmap[x])); + auto b2 = (sheet[((y * 2) + (bpp * pos)) + 1] & (kGraphicsBitmap[x])); + auto b3 = (sheet[(16 + y) + (bpp * pos)] & (kGraphicsBitmap[x])); + unsigned char b = 0; + if (b1 != 0) { + b |= 1; + } + if (b2 != 0) { + b |= 2; + } + if (b3 != 0 && bpp != 16) { + b |= 4; + } + sheet_buffer_out[x + xx + (y * 128) + (yy * 1024)] = b; + } + } + pos++; + ypos++; + xx += 8; + if (ypos >= 16) { + yy++; + xx = 0; + ypos = 0; + } + } + return sheet_buffer_out; +} + +} // namespace + +// TODO TEST compressed data border for each cmd +absl::StatusOr ROM::Compress(const int start, const int length, int mode, + bool check) { + // Worse case should be a copy of the string with extended header + auto compressed_chain = std::make_shared(1, 1, "aaa", 2); + auto compressed_chain_start = compressed_chain; + + CommandArgumentArray cmd_args = {{}}; + DataSizeArray data_size_taken = {0, 0, 0, 0, 0}; + CommandSizeArray cmd_size = {0, 1, 2, 1, 2}; + + uint src_data_pos = start; + uint last_pos = start + length - 1; + uint comp_accumulator = 0; // Used when skipping using copy + + while (true) { + data_size_taken.fill({}); + cmd_args.fill({{}}); + + lc_lz2::CheckByteRepeat(rom_data_.data(), data_size_taken, cmd_args, + src_data_pos, last_pos); + lc_lz2::CheckWordRepeat(rom_data_.data(), data_size_taken, cmd_args, + src_data_pos, last_pos); + lc_lz2::CheckIncByte(rom_data_.data(), data_size_taken, cmd_args, + src_data_pos, last_pos); + lc_lz2::CheckIntraCopy(rom_data_.data(), data_size_taken, cmd_args, + src_data_pos, last_pos, start); + + uint max_win = 2; + uint cmd_with_max = kCommandDirectCopy; + lc_lz2::ValidateForByteGain(data_size_taken, cmd_size, max_win, + cmd_with_max); + + if (cmd_with_max == kCommandDirectCopy) { + // This is the worst case scenario + // Progress through the next byte, in case there's a different + // compression command we can implement before we hit 32 bytes. + src_data_pos++; + comp_accumulator++; + + // Arbitrary choice to do a 32 bytes grouping for copy. + if (comp_accumulator == 32 || src_data_pos > last_pos) { + std::string buffer; + for (int i = 0; i < comp_accumulator; ++i) { + buffer.push_back(rom_data_[i + src_data_pos - comp_accumulator]); + } + auto new_comp_piece = std::make_shared( + kCommandDirectCopy, comp_accumulator, buffer, comp_accumulator); + compressed_chain->next = new_comp_piece; + compressed_chain = new_comp_piece; + comp_accumulator = 0; + } + } else { + lc_lz2::CompressionCommandAlternative( + rom_data_.data(), compressed_chain, cmd_size, cmd_args, src_data_pos, + comp_accumulator, cmd_with_max, max_win); + } + + if (src_data_pos > last_pos) { + printf("Breaking compression loop\n"); + break; + } + + if (check) { + RETURN_IF_ERROR(lc_lz2::ValidateCompressionResult( + compressed_chain_start, mode, start, src_data_pos)) + } + } + + // Skipping compression chain header + lc_lz2::MergeCopy(compressed_chain_start->next); + lc_lz2::PrintCompressionChain(compressed_chain_start); + return lc_lz2::CreateCompressionString(compressed_chain_start->next, mode); +} + +absl::StatusOr ROM::CompressGraphics(const int pos, const int length) { + return Compress(pos, length, kNintendoMode2); +} + +absl::StatusOr ROM::CompressOverworld(const int pos, const int length) { + return Compress(pos, length, kNintendoMode1); +} + +absl::StatusOr ROM::Decompress(int offset, int size, int mode) { + Bytes buffer(size, 0); + uint length = 0; + uint buffer_pos = 0; + uchar command = 0; + uchar header = rom_data_[offset]; + + while (header != kSnesByteMax) { + if ((header & kExpandedMod) == kExpandedMod) { + // Expanded Command + command = ((header >> 2) & kCommandMod); + length = (((header << 8) | rom_data_[offset + 1]) & kExpandedLengthMod); + offset += 2; // Advance 2 bytes in ROM + } else { + // Normal Command + command = ((header >> 5) & kCommandMod); + length = (header & kNormalLengthMod); + offset += 1; // Advance 1 byte in ROM + } + length += 1; // each commands is at least of size 1 even if index 00 + + switch (command) { + case kCommandDirectCopy: // Does not advance in the ROM + memcpy(buffer.data() + buffer_pos, rom_data_.data() + offset, length); + buffer_pos += length; + offset += length; + break; + case kCommandByteFill: + memset(buffer.data() + buffer_pos, (int)(rom_data_[offset]), length); + buffer_pos += length; + offset += 1; // Advances 1 byte in the ROM + break; + case kCommandWordFill: { + auto a = rom_data_[offset]; + auto b = rom_data_[offset + 1]; + for (int i = 0; i < length; i = i + 2) { + buffer[buffer_pos + i] = a; + if ((i + 1) < length) buffer[buffer_pos + i + 1] = b; + } + buffer_pos += length; + offset += 2; // Advance 2 byte in the ROM + } break; + case kCommandIncreasingFill: { + auto inc_byte = rom_data_[offset]; + for (int i = 0; i < length; i++) { + buffer[buffer_pos] = inc_byte++; + buffer_pos++; + } + offset += 1; // Advance 1 byte in the ROM + } break; + case kCommandRepeatingBytes: { + ushort s1 = ((rom_data_[offset + 1] & kSnesByteMax) << 8); + ushort s2 = ((rom_data_[offset] & kSnesByteMax)); + int addr = (s1 | s2); + if (mode == kNintendoMode1) { // Reversed byte order for overworld maps + addr = (rom_data_[offset + 1] & kSnesByteMax) | + ((rom_data_[offset] & kSnesByteMax) << 8); + } + if (addr > offset) { + return absl::InternalError(absl::StrFormat( + "Decompress: Offset for command copy exceeds current position " + "(Offset : %#04x | Pos : %#06x)\n", + addr, offset)); + } + if (buffer_pos + length >= size) { + size *= 2; + buffer.resize(size); + } + memcpy(buffer.data() + buffer_pos, buffer.data() + addr, length); + buffer_pos += length; + offset += 2; + } break; + default: { + std::cout << absl::StrFormat( + "Decompress: Invalid header (Offset : %#06x, Command: %#04x)\n", + offset, command); + } break; + } + // check next byte + header = rom_data_[offset]; + } + + return buffer; +} + +absl::StatusOr ROM::DecompressGraphics(int pos, int size) { + return Decompress(pos, size, kNintendoMode2); +} + +absl::StatusOr ROM::DecompressOverworld(int pos, int size) { + return Decompress(pos, size, kNintendoMode1); +} + +absl::StatusOr ROM::Load2bppGraphics() { + Bytes sheet; + const uint8_t sheets[] = {113, 114, 218, 219, 220, 221}; + + for (const auto& sheet_id : sheets) { + auto offset = GetGraphicsAddress(rom_data_.data(), sheet_id); + ASSIGN_OR_RETURN(auto decomp_sheet, Decompress(offset)) + auto converted_sheet = SnesTo8bppSheet(decomp_sheet, 2); + for (const auto& each_pixel : converted_sheet) { + sheet.push_back(each_pixel); + } + } + return sheet; +} + +// 0-112 -> compressed 3bpp bgr -> (decompressed each) 0x600 chars +// 113-114 -> compressed 2bpp -> (decompressed each) 0x800 chars +// 115-126 -> uncompressed 3bpp sprites -> (each) 0x600 chars +// 127-217 -> compressed 3bpp sprites -> (decompressed each) 0x600 chars +// 218-222 -> compressed 2bpp -> (decompressed each) 0x800 chars +absl::Status ROM::LoadAllGraphicsData() { + Bytes sheet; + bool bpp3 = false; + + for (int i = 0; i < core::NumberOfSheets; i++) { + if (i >= 115 && i <= 126) { // uncompressed sheets + sheet.resize(core::Uncompressed3BPPSize); + auto offset = GetGraphicsAddress(rom_data_.data(), i); + for (int j = 0; j < core::Uncompressed3BPPSize; j++) { + sheet[j] = rom_data_[j + offset]; + } + bpp3 = true; + } else if (i == 113 || i == 114 || i >= 218) { + bpp3 = false; + } else { + auto offset = GetGraphicsAddress(rom_data_.data(), i); + ASSIGN_OR_RETURN(sheet, Decompress(offset)) + bpp3 = true; + } + + if (bpp3) { + auto converted_sheet = SnesTo8bppSheet(sheet, 3); + graphics_bin_[i] = + gfx::Bitmap(core::kTilesheetWidth, core::kTilesheetHeight, + core::kTilesheetDepth, converted_sheet.data(), 0x1000); + graphics_bin_.at(i).CreateTexture(renderer_); + + for (int j = 0; j < graphics_bin_.at(i).GetSize(); ++j) { + graphics_buffer_.push_back(graphics_bin_.at(i).GetByte(j)); + } + } else { + for (int j = 0; j < graphics_bin_.at(0).GetSize(); ++j) { + graphics_buffer_.push_back(0xFF); + } + } + } + return absl::OkStatus(); +} + +absl::Status ROM::LoadFromFile(const absl::string_view& filename) { + filename_ = filename; + std::ifstream file(filename.data(), std::ios::binary); + if (!file.is_open()) { + return absl::InternalError( + absl::StrCat("Could not open ROM file: ", filename)); + } + + size_ = std::filesystem::file_size(filename); + rom_data_.resize(size_); + for (auto i = 0; i < size_; ++i) { + char byte_to_read = ' '; + file.read(&byte_to_read, sizeof(char)); + rom_data_[i] = byte_to_read; + } + + // copy ROM title + memcpy(title, rom_data_.data() + kTitleStringOffset, kTitleStringLength); + + file.close(); + LoadAllPalettes(); + is_loaded_ = true; + return absl::OkStatus(); +} + +absl::Status ROM::LoadFromPointer(uchar* data, size_t length) { + if (!data) + return absl::InvalidArgumentError( + "Could not load ROM: parameter `data` is empty."); + + for (int i = 0; i < length; ++i) rom_data_.push_back(data[i]); + + return absl::OkStatus(); +} + +absl::Status ROM::LoadFromBytes(const Bytes& data) { + if (data.empty()) { + return absl::InvalidArgumentError( + "Could not load ROM: parameter `data` is empty."); + } + rom_data_ = data; + return absl::OkStatus(); +} + +absl::Status ROM::SaveToFile() { + std::fstream file(filename_.data(), std::ios::binary | std::ios::out); + if (!file.is_open()) { + return absl::InternalError( + absl::StrCat("Could not open ROM file: ", filename_)); + } + for (auto i = 0; i < size_; ++i) { + file << rom_data_[i]; + } + return absl::OkStatus(); +} + +void ROM::RenderBitmap(gfx::Bitmap* bitmap) const { + bitmap->CreateTexture(renderer_); +} + +gfx::SNESColor ROM::ReadColor(int offset) { + short color = toint16(offset); + gfx::snes_color new_color; + new_color.red = (color & 0x1F) * 8; + new_color.green = ((color >> 5) & 0x1F) * 8; + new_color.blue = ((color >> 10) & 0x1F) * 8; + gfx::SNESColor snes_color(new_color); + return snes_color; +} + +gfx::SNESPalette ROM::ReadPalette(int offset, int num_colors) { + int color_offset = 0; + std::vector colors(num_colors); + + while (color_offset < num_colors) { + short color = toint16(offset); + gfx::snes_color new_color; + new_color.red = (color & 0x1F) * 8; + new_color.green = ((color >> 5) & 0x1F) * 8; + new_color.blue = ((color >> 10) & 0x1F) * 8; + colors[color_offset].setSNES(new_color); + color_offset++; + offset += 2; + } + + gfx::SNESPalette palette(colors); + return palette; +} + +void ROM::LoadAllPalettes() { + // 35 colors each, 7x5 (0,2 on grid) + for (int i = 0; i < 6; i++) { + palette_groups_["ow_main"].AddPalette( + ReadPalette(core::overworldPaletteMain + (i * (35 * 2)), 35)); + } + // 21 colors each, 7x3 (8,2 and 8,5 on grid) + for (int i = 0; i < 20; i++) { + palette_groups_["ow_aux"].AddPalette( + ReadPalette(core::overworldPaletteAuxialiary + (i * (21 * 2)), 21)); + } + // 7 colors each 7x1 (0,7 on grid) + for (int i = 0; i < 14; i++) { + palette_groups_["ow_animated"].AddPalette( + ReadPalette(core::overworldPaletteAnimated + (i * (7 * 2)), 7)); + } + // 32 colors each 16x2 (0,0 on grid) + for (int i = 0; i < 2; i++) { + palette_groups_["hud"].AddPalette( + ReadPalette(core::hudPalettes + (i * 64), 32)); + } + + palette_groups_["global_sprites"].AddPalette( + ReadPalette(core::globalSpritePalettesLW, 60)); + palette_groups_["global_sprites"].AddPalette( + ReadPalette(core::globalSpritePalettesDW, 60)); + + for (int i = 0; i < 5; i++) { + palette_groups_["armors"].AddPalette( + ReadPalette(core::armorPalettes + (i * 30), 15)); + } + for (int i = 0; i < 4; i++) { + palette_groups_["swords"].AddPalette( + ReadPalette(core::swordPalettes + (i * 6), 3)); + } + for (int i = 0; i < 3; i++) { + palette_groups_["shields"].AddPalette( + ReadPalette(core::shieldPalettes + (i * 8), 4)); + } + for (int i = 0; i < 12; i++) { + palette_groups_["sprites_aux1"].AddPalette( + ReadPalette(core::spritePalettesAux1 + (i * 14), 7)); + } + for (int i = 0; i < 11; i++) { + palette_groups_["sprites_aux2"].AddPalette( + ReadPalette(core::spritePalettesAux2 + (i * 14), 7)); + } + for (int i = 0; i < 24; i++) { + palette_groups_["sprites_aux3"].AddPalette( + ReadPalette(core::spritePalettesAux3 + (i * 14), 7)); + } + for (int i = 0; i < 20; i++) { + palette_groups_["dungeon_main"].AddPalette( + ReadPalette(core::dungeonMainPalettes + (i * 180), 90)); + } + + palette_groups_["grass"].AddColor(ReadColor(core::hardcodedGrassLW)); + palette_groups_["grass"].AddColor(ReadColor(core::hardcodedGrassDW)); + palette_groups_["grass"].AddColor(ReadColor(core::hardcodedGrassSpecial)); + + palette_groups_["3d_object"].AddPalette( + ReadPalette(core::triforcePalette, 8)); + palette_groups_["3d_object"].AddPalette(ReadPalette(core::crystalPalette, 8)); + + for (int i = 0; i < 2; i++) { + palette_groups_["ow_mini_map"].AddPalette( + ReadPalette(core::overworldMiniMapPalettes + (i * 256), 128)); + } +} + +absl::Status ROM::ApplyAssembly(const absl::string_view& filename, + size_t patch_size) { + int count = 0; + auto patch = filename.data(); + auto data = (char*)rom_data_.data(); + if (int size = size_; !asar_patch(patch, data, patch_size, &size)) { + auto asar_error = asar_geterrors(&count); + auto full_error = asar_error->fullerrdata; + return absl::InternalError(absl::StrCat("ASAR Error: ", full_error)); + } + return absl::OkStatus(); +} + +// TODO(scawful): Test me! +absl::Status ROM::PatchOverworldMosaic( + char mosaic_tiles[core::kNumOverworldMaps], int routine_offset) { + // Write the data for the mosaic tile array used by the assembly code. + for (int i = 0; i < core::kNumOverworldMaps; i++) { + if (mosaic_tiles[i]) { + rom_data_[core::overworldCustomMosaicArray + i] = 0x01; + } else { + rom_data_[core::overworldCustomMosaicArray + i] = 0x00; + } + } + + std::string filename = "assets/asm/mosaic_change.asm"; + std::fstream file(filename, std::ios::out | std::ios::in); + if (!file.is_open()) { + return absl::InvalidArgumentError( + "Unable to open mosaic change assembly source"); + } + + std::stringstream assembly; + assembly << file.rdbuf(); + file.close(); + auto assembly_string = assembly.str(); + + if (!core::StringReplace(assembly_string, "", kMosaicChangeOffset)) { + return absl::InternalError( + "Mosaic template did not have proper `` to replace."); + } + + if (!core::StringReplace( + assembly_string, "", + absl::StrFormat("$%x", routine_offset + kSNESToPCOffset))) { + return absl::InternalError( + "Mosaic template did not have proper `` to replace."); + } + + return ApplyAssembly(filename, assembly_string.size()); +} + +} // namespace app +} // namespace yaze \ No newline at end of file diff --git a/src/app/rom.h b/src/app/rom.h new file mode 100644 index 00000000..5e2a59b6 --- /dev/null +++ b/src/app/rom.h @@ -0,0 +1,157 @@ +#ifndef YAZE_APP_ROM_H +#define YAZE_APP_ROM_H + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "absl/status/status.h" +#include "absl/status/statusor.h" +#include "absl/strings/str_cat.h" +#include "absl/strings/str_format.h" +#include "absl/strings/string_view.h" +#include "app/core/common.h" +#include "app/core/constants.h" +#include "app/gfx/bitmap.h" + +#define BUILD_HEADER(command, length) (command << 5) + (length - 1) + +namespace yaze { +namespace app { + +constexpr int kCommandDirectCopy = 0; +constexpr int kCommandByteFill = 1; +constexpr int kCommandWordFill = 2; +constexpr int kCommandIncreasingFill = 3; +constexpr int kCommandRepeatingBytes = 4; +constexpr int kCommandLongLength = 7; +constexpr int kMaxLengthNormalHeader = 32; +constexpr int kMaxLengthCompression = 1024; +constexpr int kNintendoMode1 = 0; +constexpr int kNintendoMode2 = 1; +constexpr int kTile32Num = 4432; +constexpr int kTitleStringOffset = 0x7FC0; +constexpr int kTitleStringLength = 20; +constexpr int kOverworldGraphicsPos1 = 0x4F80; +constexpr int kOverworldGraphicsPos2 = 0x505F; +constexpr int kOverworldGraphicsPos3 = 0x513E; +constexpr int kSnesByteMax = 0xFF; +constexpr int kCommandMod = 0x07; +constexpr int kExpandedMod = 0xE0; +constexpr int kExpandedLengthMod = 0x3FF; +constexpr int kNormalLengthMod = 0x1F; +constexpr int kCompressionStringMod = 7 << 5; +constexpr uchar kGraphicsBitmap[8] = {0x80, 0x40, 0x20, 0x10, + 0x08, 0x04, 0x02, 0x01}; + +const std::string kMosaicChangeOffset = "$02AADB"; +constexpr int kSNESToPCOffset = 0x138000; + +using CommandArgumentArray = std::array, 5>; +using CommandSizeArray = std::array; +using DataSizeArray = std::array; +struct CompressionPiece { + char command; + int length; + int argument_length; + std::string argument; + std::shared_ptr next = nullptr; + CompressionPiece() = default; + CompressionPiece(int cmd, int len, std::string args, int arg_len) + : command(cmd), length(len), argument_length(arg_len), argument(args) {} +}; +using CompressionPiece = struct CompressionPiece; +using CompressionPiecePointer = std::shared_ptr; + +class ROM { + public: + absl::StatusOr Compress(const int start, const int length, + int mode = 1, bool check = false); + absl::StatusOr CompressGraphics(const int pos, const int length); + absl::StatusOr CompressOverworld(const int pos, const int length); + + absl::StatusOr Decompress(int offset, int size = 0x800, int mode = 1); + absl::StatusOr DecompressGraphics(int pos, int size); + absl::StatusOr DecompressOverworld(int pos, int size); + + absl::StatusOr Load2bppGraphics(); + + absl::Status LoadAllGraphicsData(); + absl::Status LoadFromFile(const absl::string_view& filename); + absl::Status LoadFromPointer(uchar* data, size_t length); + absl::Status LoadFromBytes(const Bytes& data); + void LoadAllPalettes(); + + absl::Status SaveToFile(); + + gfx::SNESColor ReadColor(int offset); + gfx::SNESPalette ReadPalette(int offset, int num_colors); + + void RenderBitmap(gfx::Bitmap* bitmap) const; + + absl::Status ApplyAssembly(const absl::string_view& filename, + size_t patch_size); + absl::Status PatchOverworldMosaic(char mosaic_tiles[core::kNumOverworldMaps], + int routine_offset); + + auto GetTitle() const { return title; } + auto GetGraphicsBin() const { return graphics_bin_; } + auto GetGraphicsBuffer() const { return graphics_buffer_; } + auto GetPaletteGroup(std::string group) { return palette_groups_[group]; } + void SetupRenderer(std::shared_ptr renderer) { + renderer_ = renderer; + } + auto isLoaded() const { return is_loaded_; } + auto begin() { return rom_data_.begin(); } + auto end() { return rom_data_.end(); } + auto data() { return rom_data_.data(); } + auto char_data() { return reinterpret_cast(rom_data_.data()); } + auto size() const { return size_; } + + uchar& operator[](int i) { + if (i > size_) { + std::cout << "ROM: Index out of bounds" << std::endl; + return rom_data_[0]; + } + return rom_data_[i]; + } + uchar& operator+(int i) { + if (i > size_) { + std::cout << "ROM: Index out of bounds" << std::endl; + return rom_data_[0]; + } + return rom_data_[i]; + } + const uchar* operator&() { return rom_data_.data(); } + + ushort toint16(int offset) { + return (ushort)((rom_data_[offset + 1]) << 8) | rom_data_[offset]; + } + + private: + long size_ = 0; + uchar title[21] = "ROM Not Loaded"; + bool is_loaded_ = false; + bool isbpp3[223]; + std::string filename_; + + Bytes rom_data_; + Bytes graphics_buffer_; + std::shared_ptr renderer_; + std::unordered_map graphics_bin_; + std::unordered_map palette_groups_; +}; + +} // namespace app +} // namespace yaze + +#endif \ No newline at end of file diff --git a/src/app/spc700/spc700.def b/src/app/spc700/spc700.def new file mode 100644 index 00000000..4781c5ef --- /dev/null +++ b/src/app/spc700/spc700.def @@ -0,0 +1,26 @@ +LIBRARY snes_spc +DESCRIPTION "snes_spc 0.9.0" +EXPORTS + spc_new @1 + spc_delete @2 + spc_init_rom @3 + spc_set_output @4 + spc_sample_count @5 + spc_reset @6 + spc_soft_reset @7 + spc_read_port @8 + spc_write_port @9 + spc_end_frame @10 + spc_mute_voices @11 + spc_disable_surround @12 + spc_set_tempo @13 + spc_load_spc @14 + spc_clear_echo @15 + spc_play @16 + spc_skip @17 + spc_filter_new @18 + spc_filter_delete @19 + spc_filter_run @20 + spc_filter_clear @21 + spc_filter_set_gain @22 + spc_filter_set_bass @23 \ No newline at end of file diff --git a/src/app/yaze.cc b/src/app/yaze.cc new file mode 100644 index 00000000..a6b7e20b --- /dev/null +++ b/src/app/yaze.cc @@ -0,0 +1,31 @@ +#if defined(_WIN32) +#define main SDL_main +#endif + +#include "absl/debugging/failure_signal_handler.h" +#include "absl/debugging/symbolize.h" +#include "app/core/controller.h" + +int main(int argc, char** argv) { + absl::InitializeSymbolizer(argv[0]); + + absl::FailureSignalHandlerOptions options; + absl::InstallFailureSignalHandler(options); + + yaze::app::core::Controller controller; + + auto entry_status = controller.onEntry(); + if (!entry_status.ok()) { + // TODO(@scawful): log the specific error + return EXIT_FAILURE; + } + + while (controller.isActive()) { + controller.onInput(); + controller.onLoad(); + controller.doRender(); + } + controller.onExit(); + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/src/app/zelda3/inventory.cc b/src/app/zelda3/inventory.cc new file mode 100644 index 00000000..89198cc0 --- /dev/null +++ b/src/app/zelda3/inventory.cc @@ -0,0 +1,89 @@ +#include "inventory.h" + +#include "app/gfx/bitmap.h" +#include "app/gfx/snes_tile.h" +#include "app/rom.h" +#include "gui/canvas.h" + +namespace yaze { +namespace app { +namespace zelda3 { + +void Inventory::Create() { + data_.reserve(256 * 256); + for (int i = 0; i < 256 * 256; i++) { + data_.push_back(0xFF); + } + PRINT_IF_ERROR(BuildTileset()) + for (int i = 0; i < 0x500; i += 0x08) { + tiles_.push_back(gfx::GetTilesInfo(rom_.toint16(i + kBowItemPos))); + tiles_.push_back(gfx::GetTilesInfo(rom_.toint16(i + kBowItemPos + 0x02))); + tiles_.push_back(gfx::GetTilesInfo(rom_.toint16(i + kBowItemPos + 0x04))); + tiles_.push_back(gfx::GetTilesInfo(rom_.toint16(i + kBowItemPos + 0x08))); + } + const int offsets[] = {0x00, 0x08, 0x800, 0x808}; + auto xx = 0; + auto yy = 0; + + int i = 0; + for (const auto& tile : tiles_) { + int offset = offsets[i]; + for (auto y = 0; y < 0x08; ++y) { + for (auto x = 0; x < 0x08; ++x) { + int mx = x; + int my = y; + + if (tile.horizontal_mirror_ != 0) { + mx = 0x07 - x; + } + + if (tile.vertical_mirror_ != 0) { + my = 0x07 - y; + } + + int xpos = ((tile.id_ % 0x10) * 0x08); + int ypos = (((tile.id_ / 0x10)) * 0x400); + int source = ypos + xpos + (x + (y * 0x80)); + + auto destination = xx + yy + offset + (mx + (my * 0x100)); + data_[destination] = (test_[source] & 0x0F) + tile.palette_ * 0x08; + } + } + + if (i == 4) { + i = 0; + xx += 0x10; + if (xx >= 0x100) { + yy += 0x1000; + xx = 0; + } + } else { + i++; + } + } + bitmap_.Create(256, 256, 128, data_); + bitmap_.ApplyPalette(palette_); + rom_.RenderBitmap(&bitmap_); +} + +absl::Status Inventory::BuildTileset() { + tilesheets_.reserve(6 * 0x2000); + for (int i = 0; i < 6 * 0x2000; i++) tilesheets_.push_back(0xFF); + ASSIGN_OR_RETURN(tilesheets_, rom_.Load2bppGraphics()) + Bytes test; + for (int i = 0; i < 0x4000; i++) { + test_.push_back(tilesheets_[i]); + } + for (int i = 0x8000; i < +0x8000 + 0x2000; i++) { + test_.push_back(tilesheets_[i]); + } + tilesheets_bmp_.Create(128, 0x130, 64, test_); + palette_ = rom_.GetPaletteGroup("hud")[0]; + tilesheets_bmp_.ApplyPalette(palette_); + rom_.RenderBitmap(&tilesheets_bmp_); + return absl::OkStatus(); +} + +} // namespace zelda3 +} // namespace app +} // namespace yaze \ No newline at end of file diff --git a/src/app/zelda3/inventory.h b/src/app/zelda3/inventory.h new file mode 100644 index 00000000..4b714f8a --- /dev/null +++ b/src/app/zelda3/inventory.h @@ -0,0 +1,47 @@ +#ifndef YAZE_APP_ZELDA3_INVENTORY_H +#define YAZE_APP_ZELDA3_INVENTORY_H + +#include "app/gfx/bitmap.h" +#include "app/gfx/snes_tile.h" +#include "app/gfx/snes_palette.h" +#include "app/rom.h" +#include "gui/canvas.h" + +namespace yaze { +namespace app { +namespace zelda3 { + +constexpr int kInventoryStart = 0x6564A; +constexpr int kBowItemPos = 0x6F631; + +class Inventory { + public: + void SetupROM(ROM& rom) { rom_ = rom; } + auto Bitmap() const { return bitmap_; } + auto Tilesheet() const { return tilesheets_bmp_; } + auto Palette() const { return palette_; } + + void Create(); + + private: + absl::Status BuildTileset(); + + ROM rom_; + + Bytes data_; + gfx::Bitmap bitmap_; + + Bytes tilesheets_; + Bytes test_; + gfx::Bitmap tilesheets_bmp_; + gfx::SNESPalette palette_; + + gui::Canvas canvas_; + std::vector tiles_; +}; + +} // namespace zelda3 +} // namespace app +} // namespace yaze + +#endif \ No newline at end of file diff --git a/src/app/zelda3/overworld.cc b/src/app/zelda3/overworld.cc new file mode 100644 index 00000000..352e14c2 --- /dev/null +++ b/src/app/zelda3/overworld.cc @@ -0,0 +1,384 @@ +#include "overworld.h" + +#include "app/gfx/snes_tile.h" +#include "app/rom.h" + +namespace yaze { +namespace app { +namespace zelda3 { + +namespace { + +uint GetOwMapGfxHighPtr(const uchar *rom, int index) { + int map_high_ptr = core::compressedAllMap32PointersHigh; + int p1 = (rom[(map_high_ptr) + 2 + (3 * index)] << 16) + + (rom[(map_high_ptr) + 1 + (3 * index)] << 8) + + (rom[(map_high_ptr + (3 * index))]); + return core::SnesToPc(p1); +} + +uint GetOwMapGfxLowPtr(const uchar *rom, int index) { + int map_low_ptr = core::compressedAllMap32PointersLow; + int p2 = (rom[(map_low_ptr) + 2 + (3 * index)] << 16) + + (rom[(map_low_ptr) + 1 + (3 * index)] << 8) + + (rom[(map_low_ptr + (3 * index))]); + return core::SnesToPc(p2); +} + +} // namespace + +absl::Status Overworld::Load(ROM &rom) { + rom_ = rom; + + AssembleMap32Tiles(); + AssembleMap16Tiles(); + RETURN_IF_ERROR(DecompressAllMapTiles()) + + for (int map_index = 0; map_index < core::kNumOverworldMaps; ++map_index) + overworld_maps_.emplace_back(map_index, rom_, tiles16); + + FetchLargeMaps(); + LoadEntrances(); + LoadSprites(); + + auto size = tiles16.size(); + for (int i = 0; i < core::kNumOverworldMaps; ++i) { + if (i < 64) { + RETURN_IF_ERROR(overworld_maps_[i].BuildMap( + size, game_state_, 0, map_parent_, map_tiles_.light_world)) + } else if (i < 0x80 && i >= 0x40) { + RETURN_IF_ERROR(overworld_maps_[i].BuildMap( + size, game_state_, 1, map_parent_, map_tiles_.dark_world)) + } else { + RETURN_IF_ERROR(overworld_maps_[i].BuildMap( + size, game_state_, 2, map_parent_, map_tiles_.special_world)) + } + } + + is_loaded_ = true; + return absl::OkStatus(); +} + +ushort Overworld::GenerateTile32(int i, int k, int dimension) { + return (ushort)(rom_[map32address[dimension] + k + (i)] + + (((rom_[map32address[dimension] + (i) + (k <= 1 ? 4 : 5)] >> + (k % 2 == 0 ? 4 : 0)) & + 0x0F) * + 256)); +} + +void Overworld::AssembleMap32Tiles() { + for (int i = 0; i < 0x33F0; i += 6) { + for (int k = 0; k < 4; k++) { + tiles32.push_back(gfx::Tile32( + /*top-left=*/GenerateTile32(i, k, (int)Dimension::map32TilesTL), + /*top-right=*/GenerateTile32(i, k, (int)Dimension::map32TilesTR), + /*bottom-left=*/GenerateTile32(i, k, (int)Dimension::map32TilesBL), + /*bottom-right=*/GenerateTile32(i, k, (int)Dimension::map32TilesBR))); + } + } + map_tiles_.light_world.resize(kTile32Num); + map_tiles_.dark_world.resize(kTile32Num); + map_tiles_.special_world.resize(kTile32Num); + for (int i = 0; i < kTile32Num; i++) { + map_tiles_.light_world[i].resize(kTile32Num); + map_tiles_.dark_world[i].resize(kTile32Num); + map_tiles_.special_world[i].resize(kTile32Num); + } +} + +void Overworld::AssembleMap16Tiles() { + int tpos = core::map16Tiles; + for (int i = 0; i < 4096; i += 1) { + auto t0 = gfx::GetTilesInfo((rom_.toint16(tpos))); + tpos += 2; + auto t1 = gfx::GetTilesInfo((rom_.toint16(tpos))); + tpos += 2; + auto t2 = gfx::GetTilesInfo((rom_.toint16(tpos))); + tpos += 2; + auto t3 = gfx::GetTilesInfo((rom_.toint16(tpos))); + tpos += 2; + tiles16.emplace_back(t0, t1, t2, t3); + } +} + +void Overworld::AssignWorldTiles(int x, int y, int sx, int sy, int tpos, + OWBlockset &world) { + int position_x1 = (x * 2) + (sx * 32); + int position_y1 = (y * 2) + (sy * 32); + int position_x2 = (x * 2) + 1 + (sx * 32); + int position_y2 = (y * 2) + 1 + (sy * 32); + world[position_x1][position_y1] = tiles32[tpos].tile0_; + world[position_x2][position_y1] = tiles32[tpos].tile1_; + world[position_x1][position_y2] = tiles32[tpos].tile2_; + world[position_x2][position_y2] = tiles32[tpos].tile3_; +} + +void Overworld::OrganizeMapTiles(Bytes &bytes, Bytes &bytes2, int i, int sx, + int sy, int &ttpos) { + for (int y = 0; y < 16; y++) { + for (int x = 0; x < 16; x++) { + auto tidD = (ushort)((bytes2[ttpos] << 8) + bytes[ttpos]); + int tpos = tidD; + if (tpos < tiles32.size()) { + if (i < 64) { + AssignWorldTiles(x, y, sx, sy, tpos, map_tiles_.light_world); + } else if (i < 128 && i >= 64) { + AssignWorldTiles(x, y, sx, sy, tpos, map_tiles_.dark_world); + } else { + AssignWorldTiles(x, y, sx, sy, tpos, map_tiles_.special_world); + } + } + ttpos += 1; + } + } +} + +absl::Status Overworld::DecompressAllMapTiles() { + int lowest = 0x0FFFFF; + int highest = 0x0F8000; + int sx = 0; + int sy = 0; + int c = 0; + for (int i = 0; i < 160; i++) { + auto p1 = GetOwMapGfxHighPtr(rom_.data(), i); + auto p2 = GetOwMapGfxLowPtr(rom_.data(), i); + int ttpos = 0; + + if (p1 >= highest) { + highest = p1; + } + if (p2 >= highest) { + highest = p2; + } + + if (p1 <= lowest && p1 > 0x0F8000) { + lowest = p1; + } + if (p2 <= lowest && p2 > 0x0F8000) { + lowest = p2; + } + + ASSIGN_OR_RETURN(auto bytes, rom_.DecompressOverworld(p2, 1000)) + ASSIGN_OR_RETURN(auto bytes2, rom_.DecompressOverworld(p1, 1000)) + OrganizeMapTiles(bytes, bytes2, i, sx, sy, ttpos); + + sx++; + if (sx >= 8) { + sy++; + sx = 0; + } + + c++; + if (c >= 64) { + sx = 0; + sy = 0; + c = 0; + } + } + + std::cout << "MapPointers(lowest) : " << lowest << std::endl; + std::cout << "MapPointers(highest) : " << highest << std::endl; + return absl::OkStatus(); +} + +void Overworld::FetchLargeMaps() { + for (int i = 128; i < 145; i++) { + map_parent_[i] = 0; + } + + map_parent_[128] = 128; + map_parent_[129] = 129; + map_parent_[130] = 129; + map_parent_[137] = 129; + map_parent_[138] = 129; + map_parent_[136] = 136; + overworld_maps_[136].SetLargeMap(false); + + bool mapChecked[64]; + for (int i = 0; i < 64; i++) { + mapChecked[i] = false; + } + int xx = 0; + int yy = 0; + while (true) { + int i = xx + (yy * 8); + if (mapChecked[i] == false) { + if (overworld_maps_[i].IsLargeMap() == true) { + mapChecked[i] = true; + map_parent_[i] = (uchar)i; + map_parent_[i + 64] = (uchar)(i + 64); + + mapChecked[i + 1] = true; + map_parent_[i + 1] = (uchar)i; + map_parent_[i + 65] = (uchar)(i + 64); + + mapChecked[i + 8] = true; + map_parent_[i + 8] = (uchar)i; + map_parent_[i + 72] = (uchar)(i + 64); + + mapChecked[i + 9] = true; + map_parent_[i + 9] = (uchar)i; + map_parent_[i + 73] = (uchar)(i + 64); + xx++; + } else { + map_parent_[i] = (uchar)i; + map_parent_[i + 64] = (uchar)(i + 64); + mapChecked[i] = true; + } + } + + xx++; + if (xx >= 8) { + xx = 0; + yy += 1; + if (yy >= 8) { + break; + } + } + } +} + +void Overworld::LoadEntrances() { + for (int i = 0; i < 129; i++) { + short mapId = rom_.toint16(core::OWEntranceMap + (i * 2)); + ushort mapPos = rom_.toint16(core::OWEntrancePos + (i * 2)); + uchar entranceId = (rom_[core::OWEntranceEntranceId + i]); + int p = mapPos >> 1; + int x = (p % 64); + int y = (p >> 6); + bool deleted = false; + if (mapPos == 0xFFFF) { + deleted = true; + } + all_entrances_.emplace_back( + (x * 16) + (((mapId % 64) - (((mapId % 64) / 8) * 8)) * 512), + (y * 16) + (((mapId % 64) / 8) * 512), entranceId, mapId, mapPos, + deleted); + } + + for (int i = 0; i < 0x13; i++) { + auto mapId = (short)((rom_[core::OWHoleArea + (i * 2) + 1] << 8) + + (rom_[core::OWHoleArea + (i * 2)])); + auto mapPos = (short)((rom_[core::OWHolePos + (i * 2) + 1] << 8) + + (rom_[core::OWHolePos + (i * 2)])); + uchar entranceId = (rom_[core::OWHoleEntrance + i]); + int p = (mapPos + 0x400) >> 1; + int x = (p % 64); + int y = (p >> 6); + all_holes_.emplace_back( + (x * 16) + (((mapId % 64) - (((mapId % 64) / 8) * 8)) * 512), + (y * 16) + (((mapId % 64) / 8) * 512), entranceId, mapId, + (ushort)(mapPos + 0x400), true); + } +} + +void Overworld::LoadSprites() { + // LW[0] = RainState 0 to 63 there's no data for DW + // LW[1] = ZeldaState 0 to 128 ; Contains LW and DW <128 or 144 wtf + // LW[2] = AgahState 0 to ?? ;Contains data for LW and DW + + for (int i = 0; i < 3; i++) { + all_sprites_.emplace_back(std::vector()); + } + + for (int i = 0; i < 64; i++) { + if (map_parent_[i] == i) { + // Beginning Sprites + int ptrPos = core::overworldSpritesBegining + (i * 2); + int spriteAddress = core::SnesToPc((0x09 << 0x10) + rom_.toint16(ptrPos)); + while (true) { + uchar b1 = rom_[spriteAddress]; + uchar b2 = rom_[spriteAddress + 1]; + uchar b3 = rom_[spriteAddress + 2]; + if (b1 == 0xFF) { + break; + } + + int mapY = (i / 8); + int mapX = (i % 8); + + int realX = ((b2 & 0x3F) * 16) + mapX * 512; + int realY = ((b1 & 0x3F) * 16) + mapY * 512; + + all_sprites_[0].emplace_back(overworld_maps_[i].AreaGraphics(), + (uchar)i, b3, (uchar)(b2 & 0x3F), + (uchar)(b1 & 0x3F), realX, realY); + + spriteAddress += 3; + } + } + } + + for (int i = 0; i < 144; i++) { + if (map_parent_[i] == i) { + // Zelda Saved Sprites + int ptrPos = core::overworldSpritesZelda + (i * 2); + int spriteAddress = core::SnesToPc((0x09 << 0x10) + rom_.toint16(ptrPos)); + while (true) { + uchar b1 = rom_[spriteAddress]; + uchar b2 = rom_[spriteAddress + 1]; + uchar b3 = rom_[spriteAddress + 2]; + if (b1 == 0xFF) { + break; + } + + int editorMapIndex = i; + if (editorMapIndex >= 128) { + editorMapIndex = i - 128; + } else if (editorMapIndex >= 64) { + editorMapIndex = i - 64; + } + + int mapY = (editorMapIndex / 8); + int mapX = (editorMapIndex % 8); + + int realX = ((b2 & 0x3F) * 16) + mapX * 512; + int realY = ((b1 & 0x3F) * 16) + mapY * 512; + + all_sprites_[1].emplace_back(overworld_maps_[i].AreaGraphics(), + (uchar)i, b3, (uchar)(b2 & 0x3F), + (uchar)(b1 & 0x3F), realX, realY); + + spriteAddress += 3; + } + } + + // Agahnim Dead Sprites + if (map_parent_[i] == i) { + int ptrPos = core::overworldSpritesAgahnim + (i * 2); + int spriteAddress = core::SnesToPc((0x09 << 0x10) + rom_.toint16(ptrPos)); + while (true) { + uchar b1 = rom_[spriteAddress]; + uchar b2 = rom_[spriteAddress + 1]; + uchar b3 = rom_[spriteAddress + 2]; + if (b1 == 0xFF) { + break; + } + + int editorMapIndex = i; + if (editorMapIndex >= 128) { + editorMapIndex = i - 128; + } else if (editorMapIndex >= 64) { + editorMapIndex = i - 64; + } + + int mapY = (editorMapIndex / 8); + int mapX = (editorMapIndex % 8); + + int realX = ((b2 & 0x3F) * 16) + mapX * 512; + int realY = ((b1 & 0x3F) * 16) + mapY * 512; + + all_sprites_[2].emplace_back(overworld_maps_[i].AreaGraphics(), + (uchar)i, b3, (uchar)(b2 & 0x3F), + (uchar)(b1 & 0x3F), realX, realY); + + spriteAddress += 3; + } + } + } +} + +} // namespace zelda3 +} // namespace app +} // namespace yaze \ No newline at end of file diff --git a/src/app/zelda3/overworld.h b/src/app/zelda3/overworld.h new file mode 100644 index 00000000..0606378e --- /dev/null +++ b/src/app/zelda3/overworld.h @@ -0,0 +1,136 @@ +#ifndef YAZE_APP_DATA_OVERWORLD_H +#define YAZE_APP_DATA_OVERWORLD_H + +#include + +#include +#include + +#include "absl/status/status.h" +#include "app/core/constants.h" +#include "app/gfx/bitmap.h" +#include "app/gfx/snes_tile.h" +#include "app/rom.h" +#include "app/zelda3/overworld_map.h" +#include "app/zelda3/sprite.h" + +namespace yaze { +namespace app { +namespace zelda3 { + +class OverworldEntrance { + public: + int x_; + int y_; + ushort map_pos_; + uchar entrance_id_; + uchar area_x_; + uchar area_y_; + short map_id_; + bool is_hole_ = false; + bool deleted = false; + + OverworldEntrance(int x, int y, uchar entranceId, short mapId, ushort mapPos, + bool hole) + : x_(x), + y_(y), + map_pos_(mapPos), + entrance_id_(entranceId), + map_id_(mapId), + is_hole_(hole) { + int mapX = (map_id_ - ((map_id_ / 8) * 8)); + int mapY = (map_id_ / 8); + + area_x_ = (uchar)((std::abs(x - (mapX * 512)) / 16)); + area_y_ = (uchar)((std::abs(y - (mapY * 512)) / 16)); + } + + auto Copy() { + return new OverworldEntrance(x_, y_, entrance_id_, map_id_, map_pos_, + is_hole_); + } + + void updateMapStuff(short mapId) { + map_id_ = mapId; + + if (map_id_ >= 64) { + map_id_ -= 64; + } + + int mapX = (map_id_ - ((map_id_ / 8) * 8)); + int mapY = (map_id_ / 8); + + area_x_ = (uchar)((std::abs(x_ - (mapX * 512)) / 16)); + area_y_ = (uchar)((std::abs(y_ - (mapY * 512)) / 16)); + + map_pos_ = (ushort)((((area_y_) << 6) | (area_x_ & 0x3F)) << 1); + } +}; + +class Overworld { + public: + absl::Status Load(ROM &rom); + auto GetTiles16() const { return tiles16; } + auto GetOverworldMap(uint index) { return overworld_maps_[index]; } + auto GetOverworldMaps() const { return overworld_maps_; } + auto Sprites() const { return all_sprites_[game_state_]; } + auto AreaGraphics() const { + return overworld_maps_[current_map_].AreaGraphics(); + } + auto Entrances() const { return all_entrances_; } + auto AreaPalette() const { + return overworld_maps_[current_map_].AreaPalette(); + } + auto BitmapData() const { return overworld_maps_[current_map_].BitmapData(); } + auto Tile16Blockset() const { + return overworld_maps_[current_map_].Tile16Blockset(); + } + auto GameState() const { return game_state_; } + auto isLoaded() const { return is_loaded_; } + void SetCurrentMap(int i) { current_map_ = i; } + + private: + const int map32address[4] = {core::map32TilesTL, core::map32TilesTR, + core::map32TilesBL, core::map32TilesBR}; + enum Dimension { + map32TilesTL = 0, + map32TilesTR = 1, + map32TilesBL = 2, + map32TilesBR = 3 + }; + + ushort GenerateTile32(int i, int k, int dimension); + void AssembleMap32Tiles(); + void AssembleMap16Tiles(); + void AssignWorldTiles(int x, int y, int sx, int sy, int tpos, + OWBlockset &world); + void OrganizeMapTiles(Bytes &bytes, Bytes &bytes2, int i, int sx, int sy, + int &ttpos); + absl::Status DecompressAllMapTiles(); + void FetchLargeMaps(); + void LoadEntrances(); + void LoadSprites(); + + void LoadOverworldMap(); + + int game_state_ = 0; + int current_map_ = 0; + uchar map_parent_[160]; + bool is_loaded_ = false; + + ROM rom_; + OWMapTiles map_tiles_; + + std::vector tiles16; + std::vector tiles32; + std::vector overworld_maps_; + std::vector all_entrances_; + std::vector all_holes_; + std::vector> all_sprites_; +}; + +} // namespace zelda3 +} // namespace app +} // namespace yaze + +#endif \ No newline at end of file diff --git a/src/app/zelda3/overworld_map.cc b/src/app/zelda3/overworld_map.cc new file mode 100644 index 00000000..35ce1d22 --- /dev/null +++ b/src/app/zelda3/overworld_map.cc @@ -0,0 +1,546 @@ +#include "overworld_map.h" + +#include + +#include +#include +#include +#include +#include + +#include "app/core/common.h" +#include "app/gfx/bitmap.h" +#include "app/gfx/snes_tile.h" +#include "app/rom.h" + +namespace yaze { +namespace app { +namespace zelda3 { + +namespace { + +void CopyTile8bpp16(int x, int y, int tile, Bytes& bitmap, Bytes& blockset) { + int src_pos = + ((tile - ((tile / 0x08) * 0x08)) * 0x10) + ((tile / 0x08) * 2048); + int dest_pos = (x + (y * 0x200)); + for (int yy = 0; yy < 0x10; yy++) { + for (int xx = 0; xx < 0x10; xx++) { + bitmap[dest_pos + xx + (yy * 0x200)] = + blockset[src_pos + xx + (yy * 0x80)]; + } + } +} + +void SetColorsPalette(ROM& rom, int index, gfx::SNESPalette& current, + gfx::SNESPalette main, gfx::SNESPalette animated, + gfx::SNESPalette aux1, gfx::SNESPalette aux2, + gfx::SNESPalette hud, gfx::SNESColor bgrcolor, + gfx::SNESPalette spr, gfx::SNESPalette spr2) { + // Palettes infos, color 0 of a palette is always transparent (the arrays + // contains 7 colors width wide) There is 16 color per line so 16*Y + + // Left side of the palette - Main, Animated + std::vector new_palette(256); + + // Main Palette, Location 0,2 : 35 colors [7x5] + int k = 0; + for (int y = 2; y < 7; y++) { + for (int x = 1; x < 8; x++) { + new_palette[x + (16 * y)] = main[k]; + k++; + } + } + + // Animated Palette, Location 0,7 : 7colors + for (int x = 1; x < 8; x++) { + new_palette[(16 * 7) + (x)] = animated[(x - 1)]; + } + + // Right side of the palette - Aux1, Aux2 + + // Aux1 Palette, Location 8,2 : 21 colors [7x3] + k = 0; + for (int y = 2; y < 5; y++) { + for (int x = 9; x < 16; x++) { + new_palette[x + (16 * y)] = aux1[k]; + k++; + } + } + + // Aux2 Palette, Location 8,5 : 21 colors [7x3] + k = 0; + for (int y = 5; y < 8; y++) { + for (int x = 9; x < 16; x++) { + new_palette[x + (16 * y)] = aux2[k]; + k++; + } + } + + // Hud Palette, Location 0,0 : 32 colors [16x2] + for (int i = 0; i < 32; i++) { + new_palette[i] = hud[i]; + } + + // Hardcoded grass color (that might change to become invisible instead) + for (int i = 0; i < 8; i++) { + new_palette[(i * 16)] = bgrcolor; + new_palette[(i * 16) + 8] = bgrcolor; + } + + // Sprite Palettes + k = 0; + for (int y = 8; y < 9; y++) { + for (int x = 1; x < 8; x++) { + new_palette[x + (16 * y)] = rom.GetPaletteGroup("sprites_aux1")[1][k]; + k++; + } + } + + // Sprite Palettes + k = 0; + for (int y = 8; y < 9; y++) { + for (int x = 9; x < 16; x++) { + new_palette[x + (16 * y)] = rom.GetPaletteGroup("sprites_aux3")[0][k]; + k++; + } + } + + // Sprite Palettes + k = 0; + for (int y = 9; y < 13; y++) { + for (int x = 1; x < 16; x++) { + new_palette[x + (16 * y)] = rom.GetPaletteGroup("global_sprites")[0][k]; + k++; + } + } + + // Sprite Palettes + k = 0; + for (int y = 13; y < 14; y++) { + for (int x = 1; x < 8; x++) { + new_palette[x + (16 * y)] = spr[k]; + k++; + } + } + + // Sprite Palettes + k = 0; + for (int y = 14; y < 15; y++) { + for (int x = 1; x < 8; x++) { + new_palette[x + (16 * y)] = spr2[k]; + k++; + } + } + + // Sprite Palettes + k = 0; + for (int y = 15; y < 16; y++) { + for (int x = 1; x < 16; x++) { + new_palette[x + (16 * y)] = rom.GetPaletteGroup("armors")[0][k]; + k++; + } + } + + current.Create(new_palette); + for (int i = 0; i < 256; i++) { + current[(i / 16) * 16].setTransparent(true); + } +} + +} // namespace + +OverworldMap::OverworldMap(int index, ROM& rom, + std::vector& tiles16) + : parent_(index), index_(index), rom_(rom), tiles16_(tiles16) { + LoadAreaInfo(); +} + +absl::Status OverworldMap::BuildMap(int count, int game_state, int world, + uchar* map_parent, + OWBlockset& world_blockset) { + game_state_ = game_state; + world_ = world; + if (large_map_) { + parent_ = map_parent[index_]; + if (parent_ != index_ && !initialized_) { + if (index_ >= 0x80 && index_ <= 0x8A && index_ != 0x88) { + area_graphics_ = + rom_[core::overworldSpecialGFXGroup + (parent_ - 0x80)]; + area_palette_ = rom_[core::overworldSpecialPALGroup + 1]; + } else if (index_ == 0x88) { + area_graphics_ = 0x51; + area_palette_ = 0x00; + } else { + area_graphics_ = rom_[core::mapGfx + parent_]; + area_palette_ = rom_[core::overworldMapPalette + parent_]; + } + + initialized_ = true; + } + } + + LoadAreaGraphics(); + RETURN_IF_ERROR(BuildTileset()) + RETURN_IF_ERROR(BuildTiles16Gfx(count)) + LoadPalette(); + RETURN_IF_ERROR(BuildBitmap(world_blockset)) + built_ = true; + return absl::OkStatus(); +} + +void OverworldMap::LoadAreaInfo() { + if (index_ != 0x80 && index_ <= 150 && + rom_[core::overworldMapSize + (index_ & 0x3F)] != 0) { + large_map_ = true; + } + if (index_ < 64) { + area_graphics_ = rom_[core::mapGfx + parent_]; + area_palette_ = rom_[core::overworldMapPalette + parent_]; + + area_music_[0] = rom_[core::overworldMusicBegining + parent_]; + area_music_[1] = rom_[core::overworldMusicZelda + parent_]; + area_music_[2] = rom_[core::overworldMusicMasterSword + parent_]; + area_music_[3] = rom_[core::overworldMusicAgahim + parent_]; + + sprite_graphics_[0] = rom_[core::overworldSpriteset + parent_]; + sprite_graphics_[1] = rom_[core::overworldSpriteset + parent_ + 0x40]; + sprite_graphics_[2] = rom_[core::overworldSpriteset + parent_ + 0x80]; + + sprite_palette_[0] = rom_[core::overworldSpritePalette + parent_]; + sprite_palette_[1] = rom_[core::overworldSpritePalette + parent_ + 0x40]; + sprite_palette_[2] = rom_[core::overworldSpritePalette + parent_ + 0x80]; + } else if (index_ < 0x80) { + area_graphics_ = rom_[core::mapGfx + parent_]; + area_palette_ = rom_[core::overworldMapPalette + parent_]; + area_music_[0] = rom_[core::overworldMusicDW + (parent_ - 64)]; + + sprite_graphics_[0] = rom_[core::overworldSpriteset + parent_ + 0x80]; + sprite_graphics_[1] = rom_[core::overworldSpriteset + parent_ + 0x80]; + sprite_graphics_[2] = rom_[core::overworldSpriteset + parent_ + 0x80]; + + sprite_palette_[0] = rom_[core::overworldSpritePalette + parent_ + 0x80]; + sprite_palette_[1] = rom_[core::overworldSpritePalette + parent_ + 0x80]; + sprite_palette_[2] = rom_[core::overworldSpritePalette + parent_ + 0x80]; + } else { + if (index_ == 0x94) { + parent_ = 0x80; + } else if (index_ == 0x95) { + parent_ = 0x03; + } else if (index_ == 0x96) { + parent_ = 0x5B; // pyramid bg use 0x5B map + } else if (index_ == 0x97) { + parent_ = 0x00; // pyramid bg use 0x5B map + } else if (index_ == 0x9C) { + parent_ = 0x43; + } else if (index_ == 0x9D) { + parent_ = 0x00; + } else if (index_ == 0x9E) { + parent_ = 0x00; + } else if (index_ == 0x9F) { + parent_ = 0x2C; + } else if (index_ == 0x88) { + parent_ = 0x88; + } + + area_palette_ = rom_[core::overworldSpecialPALGroup + parent_ - 0x80]; + if (index_ >= 0x80 && index_ <= 0x8A && index_ != 0x88) { + area_graphics_ = rom_[core::overworldSpecialGFXGroup + (parent_ - 0x80)]; + area_palette_ = rom_[core::overworldSpecialPALGroup + 1]; + } else if (index_ == 0x88) { + area_graphics_ = 0x51; + area_palette_ = 0x00; + } else { + // pyramid bg use 0x5B map + area_graphics_ = rom_[core::mapGfx + parent_]; + area_palette_ = rom_[core::overworldMapPalette + parent_]; + } + + message_id_ = rom_[core::overworldMessages + parent_]; + + sprite_graphics_[0] = rom_[core::overworldSpriteset + parent_ + 0x80]; + sprite_graphics_[1] = rom_[core::overworldSpriteset + parent_ + 0x80]; + sprite_graphics_[2] = rom_[core::overworldSpriteset + parent_ + 0x80]; + + sprite_palette_[0] = rom_[core::overworldSpritePalette + parent_ + 0x80]; + sprite_palette_[1] = rom_[core::overworldSpritePalette + parent_ + 0x80]; + sprite_palette_[2] = rom_[core::overworldSpritePalette + parent_ + 0x80]; + } +} + +void OverworldMap::LoadAreaGraphics() { + int world_index = 0x20; + if (parent_ < 0x40) { + world_index = 0x20; + } else if (parent_ >= 0x40 && parent_ < 0x80) { + world_index = 0x21; + } else if (parent_ == 0x88) { + world_index = 0x24; + } + + // Sprites Blocksets + static_graphics_[8] = 0x73 + 0x00; + static_graphics_[9] = 0x73 + 0x01; + static_graphics_[10] = 0x73 + 0x06; + static_graphics_[11] = 0x73 + 0x07; + for (int i = 0; i < 4; i++) { + static_graphics_[12 + i] = (rom_[core::kSpriteBlocksetPointer + + (sprite_graphics_[game_state_] * 4) + i] + + 0x73); + } + + // Main Blocksets + for (int i = 0; i < 8; i++) { + static_graphics_[i] = + rom_[core::overworldgfxGroups2 + (world_index * 8) + i]; + } + + if (rom_[core::overworldgfxGroups + (area_graphics_ * 4)] != 0) { + static_graphics_[3] = rom_[core::overworldgfxGroups + (area_graphics_ * 4)]; + } + if (rom_[core::overworldgfxGroups + (area_graphics_ * 4) + 1] != 0) { + static_graphics_[4] = + rom_[core::overworldgfxGroups + (area_graphics_ * 4) + 1]; + } + if (rom_[core::overworldgfxGroups + (area_graphics_ * 4) + 2] != 0) { + static_graphics_[5] = + rom_[core::overworldgfxGroups + (area_graphics_ * 4) + 2]; + } + if (rom_[core::overworldgfxGroups + (area_graphics_ * 4) + 3] != 0) { + static_graphics_[6] = + rom_[core::overworldgfxGroups + (area_graphics_ * 4) + 3]; + } + + // Hardcoded overworld GFX Values, for death mountain + if ((parent_ >= 0x03 && parent_ <= 0x07) || + (parent_ >= 0x0B && parent_ <= 0x0E)) { + static_graphics_[7] = 0x59; + } else if ((parent_ >= 0x43 && parent_ <= 0x47) || + (parent_ >= 0x4B && parent_ <= 0x4E)) { + static_graphics_[7] = 0x59; + } else { + static_graphics_[7] = 0x5B; + } +} + +void OverworldMap::LoadPalette() { + int previousPalId = 0; + int previousSprPalId = 0; + if (index_ > 0) { + previousPalId = rom_[core::overworldMapPalette + parent_ - 1]; + previousSprPalId = rom_[core::overworldSpritePalette + parent_ - 1]; + } + + if (area_palette_ >= 0xA3) { + area_palette_ = 0xA3; + } + + uchar pal0 = 0; + + uchar pal1 = rom_[core::overworldMapPaletteGroup + (area_palette_ * 4)]; + uchar pal2 = + rom_[core::overworldMapPaletteGroup + (area_palette_ * 4) + 1]; // aux2 + uchar pal3 = rom_[core::overworldMapPaletteGroup + (area_palette_ * 4) + + 2]; // animated + + uchar pal4 = rom_[core::overworldSpritePaletteGroup + + (sprite_palette_[game_state_] * 2)]; // spr3 + uchar pal5 = rom_[core::overworldSpritePaletteGroup + + (sprite_palette_[game_state_] * 2) + 1]; // spr4 + + gfx::SNESPalette aux1; + gfx::SNESPalette aux2; + gfx::SNESPalette main; + gfx::SNESPalette animated; + gfx::SNESPalette hud; + gfx::SNESPalette spr; + gfx::SNESPalette spr2; + gfx::SNESColor bgr = rom_.GetPaletteGroup("grass")[0].GetColor(0); + + if (pal1 == 255) { + pal1 = rom_[core::overworldMapPaletteGroup + (previousPalId * 4)]; + } + if (pal1 != 255) { + if (pal1 >= 20) { + pal1 = 19; + } + + aux1 = rom_.GetPaletteGroup("ow_aux")[pal1]; + } else { + aux1 = rom_.GetPaletteGroup("ow_aux")[0]; + } + + if (pal2 == 255) { + pal2 = rom_[core::overworldMapPaletteGroup + (previousPalId * 4) + 1]; + } + if (pal2 != 255) { + if (pal2 >= 20) { + pal2 = 19; + } + + aux2 = rom_.GetPaletteGroup("ow_aux")[pal2]; + } else { + aux2 = rom_.GetPaletteGroup("ow_aux")[0]; + } + + if (pal3 == 255) { + pal3 = rom_[core::overworldMapPaletteGroup + (previousPalId * 4) + 2]; + } + + if (parent_ < 0x40) { + // Default LW Palette + pal0 = 0; + bgr = rom_.GetPaletteGroup("grass")[0].GetColor(0); + if (parent_ == 0x03 || parent_ == 0x05 || parent_ == 0x07) { + pal0 = 2; + } + } else if (parent_ >= 0x40 && parent_ < 0x80) { + // Default DW Palette + pal0 = 1; + bgr = rom_.GetPaletteGroup("grass")[0].GetColor(1); + if (parent_ == 0x43 || parent_ == 0x45 || parent_ == 0x47) { + pal0 = 3; + } + } else if (parent_ >= 128 && parent_ < core::kNumOverworldMaps) { + // Default SP Palette + pal0 = 0; + bgr = rom_.GetPaletteGroup("grass")[0].GetColor(2); + } + + if (parent_ == 0x88) { + pal0 = 4; + } + + if (pal0 != 255) { + main = rom_.GetPaletteGroup("ow_main")[pal0]; + } else { + main = rom_.GetPaletteGroup("ow_main")[0]; + } + + if (pal3 >= 14) { + pal3 = 13; + } + animated = rom_.GetPaletteGroup("ow_animated")[(pal3)]; + + hud = rom_.GetPaletteGroup("hud")[0]; + if (pal4 == 255) { + pal4 = rom_[core::overworldSpritePaletteGroup + + (previousSprPalId * 2)]; // spr3 + } + if (pal4 == 255) { + pal4 = 0; + } + if (pal4 >= 24) { + pal4 = 23; + } + spr = rom_.GetPaletteGroup("sprites_aux3")[pal4]; + + if (pal5 == 255) { + pal5 = rom_[core::overworldSpritePaletteGroup + (previousSprPalId * 2) + + 1]; // spr3 + } + if (pal5 == 255) { + pal5 = 0; + } + if (pal5 >= 24) { + pal5 = 23; + } + spr2 = rom_.GetPaletteGroup("sprites_aux3")[pal5]; + + SetColorsPalette(rom_, parent_, current_palette_, main, animated, aux1, aux2, + hud, bgr, spr, spr2); +} + +absl::Status OverworldMap::BuildTileset() { + all_gfx_ = rom_.GetGraphicsBuffer(); + current_gfx_.reserve(0x10000); + for (int i = 0; i < 0x10000; i++) { + current_gfx_.push_back(0x00); + } + + for (int i = 0; i < 0x10; i++) { + for (int j = 0; j < 0x1000; j++) { + auto byte = all_gfx_[j + (static_graphics_[i] * 0x1000)]; + switch (i) { + case 0: + case 3: + case 4: + case 5: + byte += 0x88; + break; + } + current_gfx_[(i * 0x1000) + j] = byte; + } + } + return absl::OkStatus(); +} + +absl::Status OverworldMap::BuildTiles16Gfx(int count) { + current_blockset_.reserve(0x100000); + for (int i = 0; i < 0x100000; i++) { + current_blockset_.push_back(0x00); + } + const int offsets[] = {0x00, 0x08, 0x400, 0x408}; + auto yy = 0; + auto xx = 0; + + for (auto i = 0; i < count; i++) { + for (auto tile = 0; tile < 0x04; tile++) { + gfx::TileInfo info = tiles16_[i].tiles_info[tile]; + int offset = offsets[tile]; + for (auto y = 0; y < 0x08; ++y) { + for (auto x = 0; x < 0x08; ++x) { + int mx = x; + int my = y; + + if (info.horizontal_mirror_ != 0) { + mx = 0x07 - x; + } + + if (info.vertical_mirror_ != 0) { + my = 0x07 - y; + } + + int xpos = ((info.id_ % 0x10) * 0x08); + int ypos = (((info.id_ / 0x10)) * 0x400); + int source = ypos + xpos + (x + (y * 0x80)); + + auto destination = xx + yy + offset + (mx + (my * 0x80)); + current_blockset_[destination] = + (current_gfx_[source] & 0x0F) + (info.palette_ * 0x10); + } + } + } + + xx += 0x10; + if (xx >= 0x80) { + yy += 0x800; + xx = 0; + } + } + + return absl::OkStatus(); +} + +absl::Status OverworldMap::BuildBitmap(OWBlockset& world_blockset) { + bitmap_data_.reserve(0x40000); + for (int i = 0; i < 0x40000; i++) { + bitmap_data_.push_back(0x00); + } + + int superY = ((index_ - (world_ * 0x40)) / 0x08); + int superX = index_ - (world_ * 0x40) - (superY * 0x08); + + for (int y = 0; y < 0x20; y++) { + for (int x = 0; x < 0x20; x++) { + auto xt = x + (superX * 0x20); + auto yt = y + (superY * 0x20); + CopyTile8bpp16((x * 0x10), (y * 0x10), world_blockset[xt][yt], + bitmap_data_, current_blockset_); + } + } + return absl::OkStatus(); +} + +} // namespace zelda3 +} // namespace app +} // namespace yaze \ No newline at end of file diff --git a/src/app/zelda3/overworld_map.h b/src/app/zelda3/overworld_map.h new file mode 100644 index 00000000..51d35902 --- /dev/null +++ b/src/app/zelda3/overworld_map.h @@ -0,0 +1,81 @@ +#ifndef YAZE_APP_ZELDA3_OVERWORLD_MAP_H +#define YAZE_APP_ZELDA3_OVERWORLD_MAP_H + +#include + +#include +#include +#include +#include +#include + +#include "absl/status/status.h" +#include "app/core/common.h" +#include "app/gfx/bitmap.h" +#include "app/gfx/snes_tile.h" +#include "app/rom.h" + +namespace yaze { +namespace app { +namespace zelda3 { + +static constexpr int kTileOffsets[] = {0, 8, 4096, 4104}; + +class OverworldMap { + public: + OverworldMap(int index, ROM& rom, std::vector& tiles16); + + absl::Status BuildMap(int count, int game_state, int world, uchar* map_parent, + OWBlockset& world_blockset); + + auto Tile16Blockset() const { return current_blockset_; } + auto AreaGraphics() const { return current_gfx_; } + auto AreaPalette() const { return current_palette_; } + auto BitmapData() const { return bitmap_data_; } + auto SetLargeMap(bool is_set) { large_map_ = is_set; } + auto IsLargeMap() const { return large_map_; } + auto IsInitialized() const { return initialized_; } + + private: + void LoadAreaInfo(); + void LoadAreaGraphics(); + void LoadPalette(); + + absl::Status BuildTileset(); + absl::Status BuildTiles16Gfx(int count); + absl::Status BuildBitmap(OWBlockset& world_blockset); + + int parent_ = 0; + int index_ = 0; + int world_ = 0; + int message_id_ = 0; + int area_graphics_ = 0; + int area_palette_ = 0; + int game_state_ = 0; + + uchar sprite_graphics_[3]; + uchar sprite_palette_[3]; + uchar area_music_[4]; + uchar static_graphics_[16]; + + bool initialized_ = false; + bool built_ = false; + bool large_map_ = false; + + ROM rom_; + Bytes all_gfx_; + Bytes current_blockset_; + Bytes current_gfx_; + Bytes bitmap_data_; + OWMapTiles map_tiles_; + + gfx::SNESPalette current_palette_; + + std::vector tiles16_; +}; + +} // namespace zelda3 +} // namespace app +} // namespace yaze + +#endif \ No newline at end of file diff --git a/src/app/zelda3/sprite.cc b/src/app/zelda3/sprite.cc new file mode 100644 index 00000000..52774d58 --- /dev/null +++ b/src/app/zelda3/sprite.cc @@ -0,0 +1,921 @@ +#include "sprite.h" + +namespace yaze { +namespace app { +namespace zelda3 { + +Sprite::Sprite(Bytes src, uchar mapid, uchar id, uchar x, uchar y, int map_x, + int map_y) { + current_gfx_ = src; + overworld_ = true; + map_id_ = mapid; + id_ = id; + x_ = x; + y_ = y; + nx_ = x; + ny_ = y; + name_ = core::kSpriteDefaultNames[id]; + map_x_ = map_x; + map_y_ = map_y; + preview_gfx_.reserve(64 * 64); + for (int i = 0; i < 64 * 64; i++) { + preview_gfx_.push_back(0xFF); + } +} + +void Sprite::updateBBox() { + lowerX_ = 1; + lowerY_ = 1; + higherX_ = 15; + higherY_ = 15; +} + +void Sprite::Draw(bool picker) { + uchar x = nx_; + uchar y = ny_; + picker_ = picker; + + if (overlord_ == 0x07) { + if (id_ == 0x1A) { + DrawSpriteTile((x * 16), (y * 16), 14, 6, 11); // bomb + } else if (id_ == 0x05) { + DrawSpriteTile((x * 16), (y * 16) - 12, 12, 16, 12, false, true); + DrawSpriteTile((x * 16), (y * 16), 0, 16, 12, false, true); + } else if (id_ == 0x06) { + DrawSpriteTile((x * 16), (y * 16), 10, 26, 14, true, true, 2, + 2); // snek + } else if (id_ == 0x09) { + DrawSpriteTile((x * 16), (y * 16), 6, 26, 14); + DrawSpriteTile((x * 16) + 8, (y * 16) + 8, 8, 26, 14); + DrawSpriteTile((x * 16), (y * 16) + 16, 10, 27, 14, false, false, 1, 1); + } else if (id_ == 0x14) { + DrawSpriteTile((x * 16), (y * 16) + 8, 12, 06, 12, false, false, 2, + 1); // shadow tile + DrawSpriteTile((x * 16), (y * 16) - 8, 3, 29, 8, false, false, 1, + 1); // tile + DrawSpriteTile((x * 16) + 8, (y * 16) - 8, 3, 29, 8, true, false, 1, + 1); // tile + DrawSpriteTile((x * 16), (y * 16), 3, 29, 8, false, true, 1, + 1); // tile + DrawSpriteTile((x * 16) + 8, (y * 16), 3, 29, 8, true, true, 1, + 1); // tile + } else { + DrawSpriteTile((x * 16), (y * 16), 4, 4, 5); + } + + if (nx_ != x || ny_ != y) { + bounding_box_.x = (lowerX_ + (nx_ * 16)); + bounding_box_.y = (lowerY_ + (ny_ * 16)); + bounding_box_.w = width_; + bounding_box_.h = height_; + } else { + bounding_box_.x = (lowerX_ + (x * 16)); + bounding_box_.y = (lowerY_ + (y * 16)); + bounding_box_.w = width_; + bounding_box_.h = height_; + } + + return; + } + + if (id_ == 0x00) { + DrawSpriteTile((x * 16), (y * 16), 4, 28, 10); + } else if (id_ == 0x01) { + DrawSpriteTile((x * 16) - 8, (y * 16), 6, 24, 12, false, false, 2, 2); + DrawSpriteTile((x * 16) + 8, (y * 16), 6, 24, 12, true, false, 2, 2); + } else if (id_ == 0x02) { + DrawSpriteTile((x * 16), (y * 16), 0, 16, 10); + } else if (id_ == 0x04) { + uchar p = 3; + + DrawSpriteTile((x * 16), (y * 16), 14, 28, p); + DrawSpriteTile((x * 16), (y * 16), 14, 30, p); + } else if (id_ == 0x05) { + uchar p = 3; + + DrawSpriteTile((x * 16), (y * 16), 14, 28, p); + DrawSpriteTile((x * 16), (y * 16), 14, 30, p); + } else if (id_ == 0x06) { + uchar p = 3; + + DrawSpriteTile((x * 16), (y * 16), 14, 28, p); + DrawSpriteTile((x * 16), (y * 16), 14, 30, p); + } else if (id_ == 0x07) { + uchar p = 3; + + DrawSpriteTile((x * 16), (y * 16), 14, 28, p); + DrawSpriteTile((x * 16), (y * 16), 14, 30, p); + } else if (id_ == 0x08) { + DrawSpriteTile((x * 16), (y * 16), 0, 24, 6); + DrawSpriteTile((x * 16) + 4, (y * 16) + 6, 0, 24, 6, false, false, 1, 1); + } else if (id_ == 0x09) { + DrawSpriteTile((x * 16) - 22, (y * 16) - 24, 12, 24, 12, false, false, 2, + 2); // Moldorm tail + DrawSpriteTile((x * 16) - 16, (y * 16) - 20, 8, 24, 12, false, false, 2, + 2); // Moldorm b2 + DrawSpriteTile((x * 16) - 12, (y * 16) - 16, 4, 24, 12, false, false, 4, + 4); // Moldorm b + DrawSpriteTile((x * 16), (y * 16), 0, 24, 12, false, false, 4, + 4); // Moldorm head + + DrawSpriteTile((x * 16) + 20, (y * 16) + 12, 8, 26, 14, false, false, 2, + 2); // Moldorm eye + DrawSpriteTile((x * 16) + 12, (y * 16) + 20, 8, 26, 14, false, false, 2, + 2); // Moldorm eye + } else if (id_ == 0x0A) { + DrawSpriteTile((x * 16), (y * 16), 0, 24, 8); + DrawSpriteTile((x * 16) + 4, (y * 16) + 6, 0, 24, 8, false, false, 1, 1); + } else if (id_ == 0x0B) { + DrawSpriteTile((x * 16), (y * 16), 10, 30, 10); + } else if (id_ == 0x0C) { + DrawSpriteTile((x * 16), (y * 16), 0, 24, 8); + DrawSpriteTile((x * 16) + 4, (y * 16) + 6, 0, 24, 8, false, false, 1, 1); + } else if (id_ == 0x0D) { + DrawSpriteTile((x * 16), (y * 16), 14, 28, 12); + } else if (id_ == 0x0E) { + DrawSpriteTile((x * 16), (y * 16), 8, 18, 10, false, false, 3, 2); + } else if (id_ == 0x0F) { + DrawSpriteTile((x * 16), (y * 16), 14, 24, 8, false, false, 2, 3); + DrawSpriteTile((x * 16) + 16, (y * 16), 30, 8, 8, true, false, 1, 3); + } else if (id_ == 0x10) { + DrawSpriteTile((x * 16), (y * 16), 12, 31, 8, false, false, 1, 1); + } else if (id_ == 0x11) { + DrawSpriteTile((x * 16), (y * 16) + 16, 6, 16, 8, false, false, 2, + 2); // Feet + DrawSpriteTile((x * 16) - 8, (y * 16) + 8, 4, 18, 8, false, false, 2, + 2); // Body1 + DrawSpriteTile((x * 16) + 8, (y * 16) + 8, 4, 18, 8, true, false, 2, + 2); // Body2 + DrawSpriteTile((x * 16), (y * 16), 0, 16, 8, false, false, 2, + 2); // Head + } else if (id_ == 0x12) { + DrawSpriteTile((x * 16), (y * 16) + 8, 8, 26, 8); + DrawSpriteTile((x * 16), (y * 16), 6, 24, 8); + } else if (id_ == 0x13) { + DrawSpriteTile((x * 16), (y * 16), 4, 22, 2); + } else if (id_ == 0x15) { + // Antifairy + DrawSpriteTile((x * 16) + 2, (y * 16) + 8, 3, 30, 5, false, false, 1, 1); + DrawSpriteTile((x * 16) + 8, (y * 16) + 2, 3, 30, 5, false, false, 1, 1); + DrawSpriteTile((x * 16) + 14, (y * 16) + 8, 3, 30, 5, false, false, 1, 1); + DrawSpriteTile((x * 16) + 8, (y * 16) + 14, 3, 30, 5, false, false, 1, 1); + DrawSpriteTile((x * 16) + 8, (y * 16) + 8, 1, 30, 5, false, false, 1, + 1); // Middle + } else if (id_ == 0x16) { + DrawSpriteTile((x * 16), (y * 16) + 8, 2, 26, 2); + DrawSpriteTile((x * 16), (y * 16), 0, 26, 2); + } else if (id_ == 0x17) // Bush hoarder + { + DrawSpriteTile((x * 16), (y * 16), 8, 30, 10); + } else if (id_ == 0x18) // Mini moldorm + { + DrawSpriteTile((x * 16) + 13, (y * 16) + 17, 13, 21, 8, false, false, 1, + 1); // Tail + DrawSpriteTile((x * 16) + 5, (y * 16) + 8, 2, 22, 8); // Body + DrawSpriteTile((x * 16), (y * 16), 0, 22, 8); // Head + DrawSpriteTile((x * 16), (y * 16) - 4, 13, 20, 8, false, false, 1, + 1); // Eyes + DrawSpriteTile((x * 16) - 4, (y * 16), 13, 20, 8, false, false, 1, + 1); // Eyes + } else if (id_ == 0x19) // Poe - ghost + { + DrawSpriteTile((x * 16), (y * 16), 6, 31, 2); // + } else if (id_ == 0x1A) // Smith + { + // DrawSpriteTile((x*16), (y *16), 2, 4, 10,true); // Smitty + // DrawSpriteTile((x*16)+12, (y *16) - 7, 0, 6, 10); // Hammer + DrawSpriteTile((x * 16), (y * 16), 4, 22, 10); + } else if (id_ == 0x1C) // Statue + { + DrawSpriteTile((x * 16), (y * 16) + 8, 0, 28, 15); + DrawSpriteTile((x * 16), (y * 16), 2, 28, 15, false, false, 1, 1); + DrawSpriteTile((x * 16) + 8, (y * 16), 2, 28, 15, true, false, 1, 1); + } else if (id_ == 0x1E) // Crystal switch + { + DrawSpriteTile((x * 16), (y * 16), 4, 30, 5); + } else if (id_ == 0x1F) // Sick kid + { + DrawSpriteTile((x * 16) - 8, (y * 16) + 8, 10, 16, 14); + DrawSpriteTile((x * 16) + 16 - 8, (y * 16) + 8, 10, 16, 14, true); + DrawSpriteTile((x * 16) - 8, (y * 16) + 16, 10, 16, 14, false, true, 2, 2); + DrawSpriteTile((x * 16) + 16 - 8, (y * 16) + 16, 10, 16, 14, true, true, 2, + 2); + DrawSpriteTile((x * 16), (y * 16) - 4, 14, 16, 10); + } else if (id_ == 0x20) { + DrawSpriteTile((x * 16), (y * 16), 2, 24, 7); + } else if (id_ == 0x21) // Push switch + { + DrawSpriteTile((x * 16) + 4, (y * 16) + 20, 13, 29, 3, false, false, 1, 1); + DrawSpriteTile((x * 16) + 4, (y * 16) + 28, 12, 29, 3, false, false, 1, 1); + DrawSpriteTile((x * 16), (y * 16) + 8, 10, 28, 3); + } else if (id_ == 0x22) // Rope + { + DrawSpriteTile((x * 16), (y * 16), 8, 26, 5); + } else if (id_ == 0x23) // Red bari + { + DrawSpriteTile((x * 16), (y * 16), 2, 18, 4, false, false, 1, 2); + DrawSpriteTile((x * 16) + 8, (y * 16), 2, 18, 4, true, false, 1, 2); + } else if (id_ == 0x24) // Blue bari + { + DrawSpriteTile((x * 16), (y * 16), 2, 18, 6, false, false, 1, 2); + DrawSpriteTile((x * 16) + 8, (y * 16), 2, 18, 6, true, false, 1, 2); + } else if (id_ == 0x25) // Talking tree? + { + // TODO: Add something here? + } else if (id_ == 0x26) // Hardhat beetle + { + if ((x & 0x01) == 0x00) { + DrawSpriteTile((x * 16), (y * 16), 4, 20, 8); + DrawSpriteTile((x * 16), (y * 16) - 6, 0, 20, 8); + } else { + DrawSpriteTile((x * 16), (y * 16), 4, 20, 10); + DrawSpriteTile((x * 16), (y * 16) - 6, 0, 20, 10); + } + } else if (id_ == 0x27) // Deadrock + { + DrawSpriteTile((x * 16), (y * 16), 2, 30, 10); + } else if (id_ == 0x28) // Npcs + { + DrawSpriteTile((x * 16), (y * 16), 14, 22, 10); + } else if (id_ == 0x29) // Npcs + { + DrawSpriteTile((x * 16), (y * 16), 14, 22, 10); + } else if (id_ == 0x2A) // Npcs + { + DrawSpriteTile((x * 16), (y * 16), 14, 22, 10); + } else if (id_ == 0x2B) // ??? + { + DrawSpriteTile((x * 16), (y * 16), 14, 22, 10); + } else if (id_ == 0x2C) // Lumberjack + { + DrawSpriteTile((x * 16) - 24, (y * 16) + 12, 6, 26, 12, true); // Body + DrawSpriteTile((x * 16) - 24, (y * 16), 8, 26, 12, true); // Head + + DrawSpriteTile((x * 16) - 14, (y * 16) + 12, 14, 27, 10, false, false, 1, + 1); // Saw left edge + DrawSpriteTile((x * 16) - 6, (y * 16) + 12, 15, 27, 10, false, false, 1, + 1); // Saw left edge + DrawSpriteTile((x * 16) + 2, (y * 16) + 12, 15, 27, 10, false, false, 1, + 1); // Saw left edge + DrawSpriteTile((x * 16) + 10, (y * 16) + 12, 15, 27, 10, false, false, 1, + 1); // Saw left edge + DrawSpriteTile((x * 16) + 18, (y * 16) + 12, 15, 27, 10, false, false, 1, + 1); // Saw left edge + DrawSpriteTile((x * 16) + 26, (y * 16) + 12, 15, 27, 10, false, false, 1, + 1); // Saw left edge + DrawSpriteTile((x * 16) + 34, (y * 16) + 12, 14, 27, 10, true, false, 1, + 1); // Saw left edge + + DrawSpriteTile((x * 16) + 40, (y * 16) + 12, 4, 26, 12); // Body + DrawSpriteTile((x * 16) + 40, (y * 16), 8, 26, 12); // Head + } else if (id_ == 0x2D) // Npcs + { + DrawSpriteTile((x * 16), (y * 16), 14, 22, 10); + } else if (id_ == 0x2E) // Npcs + { + DrawSpriteTile((x * 16), (y * 16), 14, 22, 10); + } else if (id_ == 0x2F) // Npcs + { + DrawSpriteTile((x * 16), (y * 16), 14, 22, 10); + } else if (id_ == 0x30) // Npcs + { + DrawSpriteTile((x * 16), (y * 16), 14, 22, 10); + } else if (id_ == 0x31) // Npcs + { + DrawSpriteTile((x * 16), (y * 16), 14, 22, 10); + } else if (id_ == 0x32) // Npcs + { + DrawSpriteTile((x * 16), (y * 16), 14, 22, 10); + } + /* +else if (id_== 0x33) // Pull for rupees +{ + +} +*/ + else if (id_ == 0x34) // Npcs + { + DrawSpriteTile((x * 16), (y * 16), 14, 22, 10); + } else if (id_ == 0x35) // Npcs + { + DrawSpriteTile((x * 16), (y * 16), 14, 22, 10); + } else if (id_ == 0x36) // Npcs + { + DrawSpriteTile((x * 16), (y * 16), 14, 22, 10); + } + /* +else if (id_== 0x37) // Waterfall +{ +DrawSpriteTile((x*16), (y *16), 14, 6, 10); +} +*/ + else if (id_ == 0x38) // Arrowtarget + { + DrawSpriteTile((x * 16), (y * 16), 14, 22, 10); + } else if (id_ == 0x39) // Npcs + { + DrawSpriteTile((x * 16), (y * 16), 14, 22, 10); + } else if (id_ == 0x3A) // Npcs + { + DrawSpriteTile((x * 16), (y * 16), 14, 22, 10); + } else if (id_ == 0x3B) // Dash item + { + } else if (id_ == 0x3C) // Npcs + { + DrawSpriteTile((x * 16), (y * 16), 14, 22, 10); + } else if (id_ == 0x3D) // Npcs + { + DrawSpriteTile((x * 16), (y * 16), 14, 22, 10); + } else if (id_ == 0x3E) // Npcs + { + DrawSpriteTile((x * 16), (y * 16), 14, 22, 10); + } else if (id_ == 0x3F) // Npcs + { + DrawSpriteTile((x * 16), (y * 16), 14, 22, 10); + } else if (id_ == 0x40) // Lightning lock (agah tower) + { + DrawSpriteTile((x * 16) - 24, (y * 16), 10, 28, 2, false, false, 1, 2); + DrawSpriteTile((x * 16) - 16, (y * 16), 6, 30, 2); + DrawSpriteTile((x * 16), (y * 16), 8, 30, 2); + DrawSpriteTile((x * 16) + 16, (y * 16), 6, 30, 2); + DrawSpriteTile((x * 16) + 24, (y * 16), 10, 28, 2, false, false, 1, 2); + } else if (id_ == 0x41) // Blue soldier + { + DrawSpriteTile((x * 16) - 4, (y * 16) + 8, 6, 20, 10); + DrawSpriteTile((x * 16) + 12, (y * 16) + 8, 6, 20, 10, true, false, 1, 2); + DrawSpriteTile((x * 16), (y * 16), 0, 20, 10); + DrawSpriteTile((x * 16) + 12, (y * 16) + 8, 13, 22, 10, false, false, 1, + 2); // Shield + DrawSpriteTile((x * 16) - 4, (y * 16) + 16, 14, 22, 10, false, true, 1, + 2); // Sword + } else if (id_ == 0x42) // Green soldier + { + DrawSpriteTile((x * 16) - 4, (y * 16) + 8, 6, 20, 12); + DrawSpriteTile((x * 16) + 12, (y * 16) + 8, 6, 20, 12, true, false, 1, 2); + DrawSpriteTile((x * 16), (y * 16), 0, 20, 12); + DrawSpriteTile((x * 16) + 12, (y * 16) + 8, 13, 22, 12, false, false, 1, + 2); // Shield + DrawSpriteTile((x * 16) - 4, (y * 16) + 16, 14, 22, 12, false, true, 1, + 2); // Sword + } else if (id_ == 0x43) // Red spear soldier + { + DrawSpriteTile((x * 16) - 4, (y * 16) + 8, 6, 20, 8); + DrawSpriteTile((x * 16) + 12, (y * 16) + 8, 6, 20, 8, true, false, 1, 2); + DrawSpriteTile((x * 16), (y * 16), 0, 20, 8); + DrawSpriteTile((x * 16) + 12, (y * 16) + 8, 13, 22, 8, false, false, 1, + 2); // Shield + DrawSpriteTile((x * 16) - 4, (y * 16) + 16, 11, 22, 8, false, true, 1, + 2); // Spear + } else if (id_ == 0x44) // Sword blue holding up + { + DrawSpriteTile((x * 16) + 4, (y * 16) + 8, 6, 16, 10); + DrawSpriteTile((x * 16) - 4, (y * 16) + 8, 6, 20, 10, false, false, 1, 2); + DrawSpriteTile((x * 16), (y * 16), 0, 16, 10); // Head + DrawSpriteTile((x * 16) + 12, (y * 16) + 8, 14, 22, 10, false, true, 1, + 2); // Sword + } else if (id_ == 0x45) // Green spear soldier + { + DrawSpriteTile((x * 16) - 4, (y * 16) + 8, 6, 20, 12); + DrawSpriteTile((x * 16) + 12, (y * 16) + 8, 6, 20, 12, true, false, 1, 2); + DrawSpriteTile((x * 16), (y * 16), 0, 20, 12); + DrawSpriteTile((x * 16) + 12, (y * 16) + 8, 13, 22, 12, false, false, 1, + 2); // Shield + DrawSpriteTile((x * 16) - 4, (y * 16) + 16, 11, 22, 12, false, true, 1, + 2); // Spear + } else if (id_ == 0x46) // Blue archer + { + DrawSpriteTile((x * 16) - 4, (y * 16) + 8, 6, 20, 10); + DrawSpriteTile((x * 16) + 12, (y * 16) + 8, 6, 20, 10, true, false, 1, 2); + DrawSpriteTile((x * 16), (y * 16), 0, 20, 10); // Head + DrawSpriteTile((x * 16), (y * 16) + 16, 10, 16, 10, false, false, 1, + 1); // Bow1 + DrawSpriteTile((x * 16) + 8, (y * 16) + 16, 10, 16, 10, true, false, 1, + 1); // Bow2 + } else if (id_ == 0x47) // Green archer + { + DrawSpriteTile((x * 16), (y * 16) + 8, 14, 16, 12); + DrawSpriteTile((x * 16), (y * 16), 0, 20, 12); + DrawSpriteTile((x * 16), (y * 16) + 16, 10, 16, 12, false, false, 1, + 1); // Bow1 + DrawSpriteTile((x * 16) + 8, (y * 16) + 16, 10, 16, 12, true, false, 1, + 1); // Bow2 + } else if (id_ == 0x48) // Javelin soldier red + { + DrawSpriteTile((x * 16) + 4, (y * 16) + 8, 6, 16, 8); + DrawSpriteTile((x * 16) - 4, (y * 16) + 8, 6, 20, 8, false, false, 1, 2); + DrawSpriteTile((x * 16), (y * 16), 0, 16, 8); // Head + DrawSpriteTile((x * 16) + 12, (y * 16) + 8, 11, 22, 8, false, true, 1, + 2); // Sword + } else if (id_ == 0x49) // Javelin soldier red from bush + { + DrawSpriteTile((x * 16) + 4, (y * 16) + 8, 6, 16, 8); + DrawSpriteTile((x * 16) - 4, (y * 16) + 8, 6, 20, 8, false, false, 1, 2); + DrawSpriteTile((x * 16), (y * 16), 0, 18, 8); // Head + DrawSpriteTile((x * 16), (y * 16) + 24, 0, 20, 2); + DrawSpriteTile((x * 16) + 12, (y * 16) + 8, 11, 22, 8, false, true, 1, + 2); // Sword + } else if (id_ == 0x4A) // Red bomb soldier + { + DrawSpriteTile((x * 16) + 4, (y * 16) + 8, 6, 16, 8); + DrawSpriteTile((x * 16) - 4, (y * 16) + 8, 6, 20, 8, false, false, 1, 2); + DrawSpriteTile((x * 16), (y * 16), 0, 16, 8); // Head + DrawSpriteTile((x * 16) + 8, (y * 16) - 8, 14, 22, 11); // Bomb + } else if (id_ == 0x4B) // Green soldier recruit + { + // 0,4 + DrawSpriteTile((x * 16), (y * 16), 6, 24, 12); + DrawSpriteTile((x * 16), (y * 16) - 10, 0, 20, 12); + } else if (id_ == 0x4C) // Jazzhand + { + DrawSpriteTile((x * 16), (y * 16), 0, 26, 14, false, false, 6, 2); + } else if (id_ == 0x4D) // Rabit?? + { + DrawSpriteTile((x * 16), (y * 16), 0, 26, 12, false, false, 6, 2); + } else if (id_ == 0x4E) // Popo1 + { + DrawSpriteTile((x * 16), (y * 16), 0, 20, 10); + } else if (id_ == 0x4F) // Popo2 + { + DrawSpriteTile((x * 16), (y * 16), 2, 20, 10); + } else if (id_ == 0x50) // Canon ball + { + DrawSpriteTile((x * 16), (y * 16), 0, 24, 10); + } else if (id_ == 0x51) // Armos + { + DrawSpriteTile((x * 16), (y * 16), 0, 28, 11, false, false, 2, 4); + } else if (id_ == 0x53) // Armos Knight + { + DrawSpriteTile((x * 16), (y * 16), 0, 28, 10, false, false, 4, 4); + } else if (id_ == 0x54) { + DrawSpriteTile((x * 16), (y * 16), 2, 28, 12); + DrawSpriteTile((x * 16) + 8, (y * 16) + 10, 6, 28, 12); + DrawSpriteTile((x * 16) + 16, (y * 16) + 18, 10, 28, 12); + } else if (id_ == 0x55) // Fireball Zora + { + DrawSpriteTile((x * 16), (y * 16), 4, 26, 11); + } else if (id_ == 0x56) // Zora + { + DrawSpriteTile((x * 16), (y * 16), 10, 20, 2); + DrawSpriteTile((x * 16), (y * 16) + 8, 8, 30, 2); + } else if (id_ == 0x57) // Desert Rocks + { + DrawSpriteTile((x * 16), (y * 16), 14, 24, 2, false, false, 2, 4); + DrawSpriteTile((x * 16) + 16, (y * 16), 14, 24, 2, true, false, 2, 4); + } else if (id_ == 0x58) // Crab + { + DrawSpriteTile((x * 16), (y * 16), 14, 24, 12); + DrawSpriteTile((x * 16) + 16, (y * 16), 14, 24, 12, true); + } else if (id_ == 0x5B) // Spark + { + DrawSpriteTile((x * 16), (y * 16), 8, 18, 4); + } else if (id_ == 0x5C) // Spark + { + DrawSpriteTile((x * 16), (y * 16), 8, 18, 4, true); + } else if (id_ == 0x5D) // Roller vertical1 + { + // Subset3 + if (((y * 16) & 0x10) == 0x10) { + DrawSpriteTile((x * 16), (y * 16), 8, 24, 11); + + for (int i = 0; i < 7; i++) { + DrawSpriteTile((x * 16) + 8 + (i * 16), (y * 16), 9, 24, 11); + } + + DrawSpriteTile((x * 16) + (16 * 7), (y * 16), 8, 24, 11, true); + } else { + DrawSpriteTile((x * 16), (y * 16), 8, 24, 11); + DrawSpriteTile((x * 16) + 16, (y * 16), 9, 24, 11); + DrawSpriteTile((x * 16) + 32, (y * 16), 9, 24, 11); + DrawSpriteTile((x * 16) + 48, (y * 16), 8, 24, 11, true); + } + + } else if (id_ == 0x5E) // Roller vertical2 + { + // Subset3 + if (((y * 16) & 0x10) == 0x10) { + DrawSpriteTile((x * 16), (y * 16), 8, 24, 11); + + for (int i = 0; i < 7; i++) { + DrawSpriteTile((x * 16) + 8 + (i * 16), (y * 16), 9, 24, 11); + } + + DrawSpriteTile((x * 16) + (16 * 7), (y * 16), 8, 24, 11, true); + } else { + DrawSpriteTile((x * 16), (y * 16), 8, 24, 11); + DrawSpriteTile((x * 16) + 16, (y * 16), 9, 24, 11); + DrawSpriteTile((x * 16) + 32, (y * 16), 9, 24, 11); + DrawSpriteTile((x * 16) + 48, (y * 16), 8, 24, 11, true); + } + } else if (id_ == 0x5F) // Roller horizontal + { + if (((x * 16) & 0x10) == 0x10) { + DrawSpriteTile((x * 16), (y * 16), 14, 24, 11); + DrawSpriteTile((x * 16), (y * 16) + 16, 14, 25, 11); + DrawSpriteTile((x * 16), (y * 16) + 32, 14, 25, 11); + DrawSpriteTile((x * 16), (y * 16) + 48, 14, 24, 11, false, true); + } else { + for (int i = 0; i < 7; i++) { + DrawSpriteTile((x * 16), (y * 16) + i * 16, 14, 25, 11); + } + + DrawSpriteTile((x * 16), (y * 16), 14, 24, 11); + DrawSpriteTile((x * 16), (y * 16) + (7 * 16), 14, 24, 11, false, true); + } + } else if (id_ == 0x60) // Roller horizontal2 (right to left) + { + // Subset3 + if (((x * 16) & 0x10) == 0x10) { + DrawSpriteTile((x * 16), (y * 16), 14, 24, 11); + DrawSpriteTile((x * 16), (y * 16) + 16, 14, 25, 11); + DrawSpriteTile((x * 16), (y * 16) + 32, 14, 25, 11); + DrawSpriteTile((x * 16), (y * 16) + 48, 14, 24, 11, false, true); + } else { + for (int i = 0; i < 7; i++) { + DrawSpriteTile((x * 16), (y * 16) + i * 16, 14, 25, 11); + } + + DrawSpriteTile((x * 16), (y * 16), 14, 24, 11); + DrawSpriteTile((x * 16), (y * 16) + (7 * 16), 14, 24, 11, false, true); + } + + } else if (id_ == 0x61) // Beamos + { + DrawSpriteTile((x * 16), (y * 16) - 16, 8, 20, 14, false, false, 2, 4); + DrawSpriteTile((x * 16) + 4, (y * 16) - 8, 10, 20, 14, false, false, 1, 1); + } else if (id_ == 0x63) // Devalant non-shooter + { + DrawSpriteTile((x * 16) - 8, (y * 16) - 8, 2, 16, 2); + DrawSpriteTile((x * 16) + 8, (y * 16) - 8, 2, 16, 2, true); + DrawSpriteTile((x * 16) - 8, (y * 16) + 8, 2, 16, 2, false, true); + DrawSpriteTile((x * 16) + 8, (y * 16) + 8, 2, 16, 2, true, true); + DrawSpriteTile((x * 16), (y * 16), 0, 16, 10); + } else if (id_ == 0x64) // Devalant non-shooter + { + DrawSpriteTile((x * 16) - 8, (y * 16) - 8, 2, 16, 2); + DrawSpriteTile((x * 16) + 8, (y * 16) - 8, 2, 16, 2, true); + DrawSpriteTile((x * 16) - 8, (y * 16) + 8, 2, 16, 2, false, true); + DrawSpriteTile((x * 16) + 8, (y * 16) + 8, 2, 16, 2, true, true); + DrawSpriteTile((x * 16), (y * 16), 0, 16, 8); + } else if (id_ == 0x66) // Moving wall canon right + { + DrawSpriteTile((x * 16), (y * 16), 14, 16, 14, true); + } else if (id_ == 0x67) // Moving wall canon right + { + DrawSpriteTile((x * 16), (y * 16), 14, 16, 14); + } else if (id_ == 0x68) // Moving wall canon right + { + DrawSpriteTile((x * 16), (y * 16), 12, 16, 14); + } else if (id_ == 0x69) // Moving wall canon right + { + DrawSpriteTile((x * 16), (y * 16), 12, 16, 14, false, true); + } else if (id_ == 0x6A) // Chainball soldier + { + DrawSpriteTile((x * 16) + 4, (y * 16) + 8, 6, 16, 14); + DrawSpriteTile((x * 16) - 4, (y * 16) + 8, 6, 20, 14, false, false, 1, 2); + DrawSpriteTile((x * 16), (y * 16), 0, 16, 14); // Head + DrawSpriteTile((x * 16) + 12, (y * 16) - 16, 10, 18, 14); // Ball + } else if (id_ == 0x6B) // Cannon soldier + { + DrawSpriteTile((x * 16) + 4, (y * 16) + 8, 6, 16, 14); + DrawSpriteTile((x * 16) - 4, (y * 16) + 8, 6, 20, 14, false, false, 1, 2); + DrawSpriteTile((x * 16), (y * 16), 0, 16, 14); // Head + DrawSpriteTile((x * 16) + 12, (y * 16) + 8, 4, 18, 14); // Cannon + } else if (id_ == 0x6C) // Mirror portal + { + // Useless + } else if (id_ == 0x6D) // Rat + { + DrawSpriteTile((x * 16), (y * 16), 14, 24, 5); + } else if (id_ == 0x6E) // Rope + { + DrawSpriteTile((x * 16), (y * 16), 10, 26, 5); + } else if (id_ == 0x6F) { + DrawSpriteTile((x * 16), (y * 16), 4, 24, 10); + } else if (id_ == 0x70) // Helma fireball + { + DrawSpriteTile((x * 16), (y * 16), 10, 28, 4); + } else if (id_ == 0x71) // Leever + { + DrawSpriteTile((x * 16), (y * 16), 6, 16, 4); + } else if (id_ == 0x73) // Uncle priest + { + } else if (id_ == 0x79) // Bee + { + DrawSpriteTile((x * 16), (y * 16), 4, 14, 11, false, false, 1, 1); + } else if (id_ == 0x7A) { + DrawSpriteTile((x * 16), (y * 16) - 16, 2, 24, 12, false, false, 2, 4); + DrawSpriteTile((x * 16) + 16, (y * 16) - 16, 2, 24, 12, true, false, 2, 4); + } else if (id_ == 0x7C) // Skull head + { + DrawSpriteTile((x * 16), (y * 16), 0, 16, 10); + } else if (id_ == 0x7D) // Big spike + { + DrawSpriteTile((x * 16), (y * 16), 4, 28, 11); + DrawSpriteTile((x * 16) + 16, (y * 16), 4, 28, 11, true); + DrawSpriteTile((x * 16), (y * 16) + 16, 4, 28, 11, false, true); + DrawSpriteTile((x * 16) + 16, (y * 16) + 16, 4, 28, 11, true, true); + } else if (id_ == 0x7E) // Guruguru clockwise + { + DrawSpriteTile((x * 16), (y * 16) - 14, 8, 18, 4); + DrawSpriteTile((x * 16), (y * 16) - 28, 8, 18, 4); + DrawSpriteTile((x * 16), (y * 16) - 42, 8, 18, 4); + DrawSpriteTile((x * 16), (y * 16) - 56, 8, 18, 4); + } else if (id_ == 0x7F) // Guruguru Counterclockwise + { + DrawSpriteTile((x * 16), (y * 16) - 14, 8, 18, 4); + DrawSpriteTile((x * 16), (y * 16) - 28, 8, 18, 4); + DrawSpriteTile((x * 16), (y * 16) - 42, 8, 18, 4); + DrawSpriteTile((x * 16), (y * 16) - 56, 8, 18, 4); + } else if (id_ == 0x80) // Winder (moving firebar) + { + DrawSpriteTile((x * 16), (y * 16), 8, 18, 4); + DrawSpriteTile((x * 16) - 14, (y * 16), 8, 18, 4); + DrawSpriteTile((x * 16) - 28, (y * 16), 8, 18, 4); + DrawSpriteTile((x * 16) - 42, (y * 16), 8, 18, 4); + DrawSpriteTile((x * 16) - 56, (y * 16), 8, 18, 4); + } else if (id_ == 0x81) // Water tektite + { + DrawSpriteTile((x * 16), (y * 16), 0, 24, 11); + } else if (id_ == 0x82) // circle antifairy + { + // Antifairy top + DrawSpriteTile((x * 16 + 2) - 4, (y * 16 + 8) - 16, 3, 30, 5, false, false, + 1, 1); + DrawSpriteTile((x * 16 + 8) - 4, (y * 16 + 2) - 16, 3, 30, 5, false, false, + 1, 1); + DrawSpriteTile((x * 16 + 14) - 4, (y * 16 + 8) - 16, 3, 30, 5, false, false, + 1, 1); + DrawSpriteTile((x * 16 + 8) - 4, (y * 16 + 14) - 16, 3, 30, 5, false, false, + 1, 1); + DrawSpriteTile((x * 16 + 8) - 4, (y * 16 + 8) - 16, 1, 30, 5, false, false, + 1, 1); // Middle + // Left + DrawSpriteTile((x * 16 + 2) - 16, (y * 16 + 8) - 4, 3, 30, 5, false, false, + 1, 1); + DrawSpriteTile((x * 16 + 8) - 16, (y * 16 + 2) - 4, 3, 30, 5, false, false, + 1, 1); + DrawSpriteTile((x * 16 + 14) - 16, (y * 16 + 8) - 4, 3, 30, 5, false, false, + 1, 1); + DrawSpriteTile((x * 16 + 8) - 16, (y * 16 + 14) - 4, 3, 30, 5, false, false, + 1, 1); + DrawSpriteTile((x * 16 + 8) - 16, (y * 16 + 8) - 4, 1, 30, 5, false, false, + 1, 1); // Middle + + DrawSpriteTile((x * 16 + 2) - 4, (y * 16 + 8) + 8, 3, 30, 5, false, false, + 1, 1); + DrawSpriteTile((x * 16 + 8) - 4, (y * 16 + 2) + 8, 3, 30, 5, false, false, + 1, 1); + DrawSpriteTile((x * 16 + 14) - 4, (y * 16 + 8) + 8, 3, 30, 5, false, false, + 1, 1); + DrawSpriteTile((x * 16 + 8) - 4, (y * 16 + 14) + 8, 3, 30, 5, false, false, + 1, 1); + DrawSpriteTile((x * 16 + 8) - 4, (y * 16 + 8) + 8, 1, 30, 5, false, false, + 1, 1); // Middle + // Left + DrawSpriteTile((x * 16 + 2) + 8, (y * 16 + 8) - 4, 3, 30, 5, false, false, + 1, 1); + DrawSpriteTile((x * 16 + 8) + 8, (y * 16 + 2) - 4, 3, 30, 5, false, false, + 1, 1); + DrawSpriteTile((x * 16 + 14) + 8, (y * 16 + 8) - 4, 3, 30, 5, false, false, + 1, 1); + DrawSpriteTile((x * 16 + 8) + 8, (y * 16 + 14) - 4, 3, 30, 5, false, false, + 1, 1); + DrawSpriteTile((x * 16 + 8) + 8, (y * 16 + 8) - 4, 1, 30, 5, false, false, + 1, 1); // Middle + } else if (id_ == 0x83) // Green eyegore + { + DrawSpriteTile((x * 16), (y * 16), 12, 24, 14, false, false, 2, 3); + DrawSpriteTile((x * 16) + 16, (y * 16), 12, 24, 14, true, false, 1, 3); + } else if (id_ == 0x84) // Red eyegore + { + DrawSpriteTile((x * 16), (y * 16), 12, 24, 8, false, false, 2, 3); + DrawSpriteTile((x * 16) + 16, (y * 16), 12, 24, 8, true, false, 1, 3); + } else if (id_ == 0x85) // Yellow stalfos + { + DrawSpriteTile((x * 16), (y * 16), 10, 16, 11); + DrawSpriteTile((x * 16), (y * 16) - 12, 0, 16, 11); // Head + } else if (id_ == 0x86) // Kodongo + { + DrawSpriteTile((x * 16), (y * 16), 4, 26, 14); + } else if (id_ == 0x88) // Mothula + { + DrawSpriteTile((x * 16), (y * 16), 8, 24, 14, false, false, 2, 4); + DrawSpriteTile((x * 16) + 16, (y * 16), 8, 24, 14, true, false, 2, 4); + } else if (id_ == 0x8A) // Spike + { + DrawSpriteTile((x * 16), (y * 16), 6, 30, 15); + } else if (id_ == 0x8B) // Gibdo + { + DrawSpriteTile((x * 16), (y * 16), 10, 24, 14); + DrawSpriteTile((x * 16), (y * 16) - 8, 0, 24, 14); + } else if (id_ == 0x8C) // Arrghus + { + DrawSpriteTile((x * 16), (y * 16), 0, 24, 14, false, false, 2, 4); + DrawSpriteTile((x * 16) + 16, (y * 16), 0, 24, 14, true, false, 2, 4); + } else if (id_ == 0x8D) // Arrghus spawn + { + DrawSpriteTile((x * 16), (y * 16), 6, 24, 14); + } else if (id_ == 0x8E) // Terrorpin + { + DrawSpriteTile((x * 16), (y * 16), 14, 24, 12); + } else if (id_ == 0x8F) // Slime + { + DrawSpriteTile((x * 16), (y * 16), 0, 20, 12); + } else if (id_ == 0x90) // Wall master + { + DrawSpriteTile((x * 16), (y * 16), 6, 26, 12); + DrawSpriteTile((x * 16) + 16, (y * 16), 15, 26, 12, false, false, 1, 1); + DrawSpriteTile((x * 16) + 16, (y * 16) + 8, 9, 26, 12, false, false, 1, 2); + DrawSpriteTile((x * 16), (y * 16) + 16, 10, 27, 12, false, false, 1, 1); + DrawSpriteTile((x * 16) + 8, (y * 16) + 16, 8, 27, 12, false, false, 1, 1); + } else if (id_ == 0x91) // Stalfos knight + { + DrawSpriteTile((x * 16) - 2, (y * 16) + 12, 4, 22, 12, false, false, 1, 2); + DrawSpriteTile((x * 16) + 10, (y * 16) + 12, 4, 22, 12, true, false, 1, 2); + DrawSpriteTile((x * 16) - 4, (y * 16) + 4, 1, 22, 12); + DrawSpriteTile((x * 16) + 12, (y * 16) + 4, 3, 22, 12, false, false, 1, 2); + DrawSpriteTile((x * 16), (y * 16) - 8, 6, 20, 12); + } else if (id_ == 0x92) // Helmaking + { + DrawSpriteTile((x * 16), (y * 16) + 32, 14, 26, 14); + DrawSpriteTile((x * 16) + 16, (y * 16) + 32, 0, 28, 14); + DrawSpriteTile((x * 16) + 32, (y * 16) + 32, 14, 26, 14, true); + + DrawSpriteTile((x * 16), (y * 16) + 16 + 32, 2, 28, 14); + DrawSpriteTile((x * 16) + 16, (y * 16) + 16 + 32, 4, 28, 14); + DrawSpriteTile((x * 16) + 32, (y * 16) + 16 + 32, 2, 28, 14, true); + + DrawSpriteTile((x * 16) + 8, (y * 16) + 32 + 32, 6, 28, 14); + DrawSpriteTile((x * 16) + 24, (y * 16) + 32 + 32, 6, 28, 14, true); + } else if (id_ == 0x93) // Bumper + { + DrawSpriteTile((x * 16), (y * 16), 12, 30, 7); + DrawSpriteTile((x * 16) + 16, (y * 16), 12, 30, 7, true); + DrawSpriteTile((x * 16) + 16, (y * 16) + 16, 12, 30, 7, true, true); + DrawSpriteTile((x * 16), (y * 16) + 16, 12, 30, 7, false, true); + } else if (id_ == 0x95) // Right laser eye + { + DrawSpriteTile((x * 16), (y * 16), 9, 28, 3, true, false, 1, 2); + DrawSpriteTile((x * 16), (y * 16) + 16, 9, 28, 3, true, true, 1, 1); + } else if (id_ == 0x96) // Left laser eye + { + DrawSpriteTile((x * 16) + 8, (y * 16) - 4, 9, 28, 3, false, false, 1, 2); + DrawSpriteTile((x * 16) + 8, (y * 16) + 12, 9, 28, 3, false, true, 1, 1); + } else if (id_ == 0x97) // Right laser eye + { + DrawSpriteTile((x * 16), (y * 16), 6, 28, 3, false, false, 2, 1); + DrawSpriteTile((x * 16) + 16, (y * 16), 6, 28, 3, true, false, 1, 1); + } else if (id_ == 0x98) // Right laser eye + { + DrawSpriteTile((x * 16), (y * 16), 6, 28, 3, false, true, 2, 1); + DrawSpriteTile((x * 16) + 16, (y * 16), 6, 28, 3, true, true, 1, 1); + } else if (id_ == 0x99) { + DrawSpriteTile((x * 16), (y * 16), 6, 24, 12); + DrawSpriteTile((x * 16), (y * 16) - 8, 0, 24, 12); + } else if (id_ == 0x9A) // Water bubble kyameron + { + DrawSpriteTile((x * 16), (y * 16), 10, 24, 6); + } else if (id_ == 0x9B) // Water bubble kyameron + { + DrawSpriteTile((x * 16), (y * 16), 6, 24, 11); + DrawSpriteTile((x * 16), (y * 16) - 8, 2, 27, 11, false, false, 2, 1); + } else if (id_ == 0x9C) // Water bubble kyameron + { + DrawSpriteTile((x * 16), (y * 16), 12, 22, 11); + DrawSpriteTile((x * 16) + 16, (y * 16), 13, 22, 11, false, false, 1, 2); + } else if (id_ == 0x9D) // Water bubble kyameron + { + DrawSpriteTile((x * 16), (y * 16), 14, 21, 11); + DrawSpriteTile((x * 16), (y * 16) - 16, 14, 20, 11, false, false, 2, 1); + } else if (id_ == 0xA1) { + DrawSpriteTile((x * 16) - 8, (y * 16) + 8, 6, 26, 14); + DrawSpriteTile((x * 16) + 8, (y * 16) + 8, 6, 26, 14, true); + } else if (id_ == 0xA2) { + DrawSpriteTile((x * 16), (y * 16) + 8, 0, 24, 14, false, false, 4, 4); + } else if (id_ == 0xA5) { + DrawSpriteTile((x * 16), (y * 16), 0, 26, 10, false, false, 3, 2); + DrawSpriteTile((x * 16) + 4, (y * 16) - 8, 0, 24, 10); + } else if (id_ == 0xA6) { + DrawSpriteTile((x * 16), (y * 16), 0, 26, 8, false, false, 3, 2); + DrawSpriteTile((x * 16) + 4, (y * 16) - 8, 0, 24, 8); + } else if (id_ == 0xA7) { + DrawSpriteTile((x * 16), (y * 16) + 12, 12, 16, 10); + DrawSpriteTile((x * 16), (y * 16), 0, 16, 10); + } else if (id_ == 0xAC) { + DrawSpriteTile((x * 16), (y * 16), 5, 14, 4); + } else if (id_ == 0xAD) { + DrawSpriteTile((x * 16), (y * 16) + 8, 14, 10, 10); + DrawSpriteTile((x * 16), (y * 16), 12, 10, 10); + } else if (id_ == 0xBA) { + DrawSpriteTile((x * 16), (y * 16), 14, 14, 6); + } else if (id_ == 0xC1) { + DrawSpriteTile((x * 16), (y * 16) - 16, 2, 24, 12, false, false, 2, 4); + DrawSpriteTile((x * 16) + 16, (y * 16) - 16, 2, 24, 12, true, false, 2, 4); + } else if (id_ == 0xC3) { + DrawSpriteTile((x * 16), (y * 16), 10, 14, 12); + } else if (id_ == 0xC4) { + DrawSpriteTile((x * 16), (y * 16), 0, 18, 14); + DrawSpriteTile((x * 16), (y * 16) - 8, 0, 16, 14); + } else if (id_ == 0xC5) { + } else if (id_ == 0xC6) { + DrawSpriteTile((x * 16) + 4, (y * 16) + 14, 3, 30, 14, false, false, 1, 1); + DrawSpriteTile((x * 16) + 14, (y * 16) + 4, 3, 30, 14, false, false, 1, 1); + DrawSpriteTile((x * 16) + 4, (y * 16) + 2, 1, 31, 14, false, false, 1, 1); + DrawSpriteTile((x * 16) - 6, (y * 16) + 4, 3, 30, 14, false, false, 1, 1); + DrawSpriteTile((x * 16) + 4, (y * 16) - 6, 3, 30, 14, false, false, 1, 1); + } else if (id_ == 0xC7) { + DrawSpriteTile((x * 16), (y * 16), 0, 26, 4); + DrawSpriteTile((x * 16), (y * 16) - 10, 0, 26, 4); + DrawSpriteTile((x * 16), (y * 16) - 20, 0, 26, 4); + DrawSpriteTile((x * 16), (y * 16) - 30, 2, 26, 4); + } else if (id_ == 0xC8) { + DrawSpriteTile((x * 16), (y * 16), 12, 24, 12, false, false, 2, 3); + DrawSpriteTile((x * 16) + 16, (y * 16), 12, 24, 12, true, false, 1, 3); + } else if (id_ == 0xC9) { + DrawSpriteTile((x * 16), (y * 16), 8, 28, 8, false); + DrawSpriteTile((x * 16) + 16, (y * 16), 8, 28, 8, true); + } else if (id_ == 0xCA) { + DrawSpriteTile((x * 16), (y * 16), 8, 10, 10); + } else if (id_ == 0xD0) { + DrawSpriteTile((x * 16), (y * 16), 7, 14, 11, false, false, 3, 2); + DrawSpriteTile((x * 16), (y * 16) - 10, 8, 12, 11); + } else if (id_ == 0xD1) { + DrawSpriteTile((x * 16) + 2, (y * 16) + 8, 7, 13, 11, true, true, 1, 1); + DrawSpriteTile((x * 16) + 8, (y * 16) + 2, 7, 13, 11, true, false, 1, 1); + DrawSpriteTile((x * 16) + 14, (y * 16) + 8, 7, 13, 11, true, true, 1, 1); + DrawSpriteTile((x * 16) + 8, (y * 16) + 14, 7, 13, 11, false, true, 1, 1); + DrawSpriteTile((x * 16) + 8, (y * 16) + 8, 7, 13, 11, false, false, 1, + 1); // Middle + // 6,7 / 13 + } else if (id_ == 0xD4) { + DrawSpriteTile((x * 16) - 4, (y * 16), 0, 7, 7, false, false, 1, 1); + DrawSpriteTile((x * 16) + 4, (y * 16), 0, 7, 7, true, false, 1, 1); + } else if (id_ == 0xE3) // Fairy + { + DrawSpriteTile((x * 16), (y * 16), 10, 14, 10); + } else if (id_ == 0xE4) // Key + { + DrawSpriteTile((x * 16), (y * 16), 11, 06, 11, false, false, 1, 2); + } else if (id_ == 0xE7) // Mushroom + { + DrawSpriteTile((x * 16), (y * 16), 14, 30, 16); + } else if (id_ == 0xE8) // Fake ms + { + DrawSpriteTile((x * 16) + 4, (y * 16), 4, 31, 10, false, false, 1, 1); + DrawSpriteTile((x * 16) + 4, (y * 16) + 8, 5, 31, 10, false, false, 1, 1); + } else if (id_ == 0xEB) { + DrawSpriteTile((x * 16), (y * 16), 0, 14, 5); + } else if (id_ == 0xF2) { + DrawSpriteTile((x * 16), (y * 16) - 16, 12, 24, 2, false, false, 2, 4); + DrawSpriteTile((x * 16) + 16, (y * 16) - 16, 12, 24, 2, true, false, 2, 4); + } else if (id_ == 0xF4) { + DrawSpriteTile((x * 16), (y * 16), 12, 28, 5, false, false, 4, 4); + } else { + // stringtodraw.Add(new SpriteName(x, (y *16), sprites_name.name[id])); + DrawSpriteTile((x * 16), (y * 16), 4, 4, 5); + } + + bounding_box_.x = (lowerX_ + (x * 16)); + bounding_box_.y = (lowerY_ + (y * 16)); + bounding_box_.w = width_; + bounding_box_.h = height_; +} + +void Sprite::DrawSpriteTile(int x, int y, int srcx, int srcy, int pal, + bool mirror_x, bool mirror_y, int sizex, int sizey, + bool iskey) { + x += 16; + y += 16; + int drawid_ = (srcx + (srcy * 16)) + 512; + for (auto yl = 0; yl < sizey * 8; yl++) { + for (auto xl = 0; xl < (sizex * 8) / 2; xl++) { + int mx = xl; + int my = yl; + + if (mirror_x) { + mx = (((sizex * 8) / 2) - 1) - xl; + } + if (mirror_y) { + my = (((sizey * 8)) - 1) - yl; + } + + // Formula information to get tile index position in the array + //((ID / nbrofXtiles) * (imgwidth/2) + (ID - ((ID/16)*16) )) + + int tx = ((drawid_ / 0x10) * 0x400) + + ((drawid_ - ((drawid_ / 0x10) * 0x10)) * 8); + auto pixel = current_gfx_[tx + (yl * 0x80) + xl]; + // nx,ny = object position, xx,yy = tile position, xl,yl = pixel + // position + int index = (x) + (y * 64) + (mx + (my * 0x80)); + + if (index >= 0 && index <= 4096) { + preview_gfx_[index] = (uchar)((pixel & 0x0F) + 112 + (pal * 8)); + } + } + } +} + +} // namespace zelda3 +} // namespace app +} // namespace yaze diff --git a/src/app/zelda3/sprite.h b/src/app/zelda3/sprite.h new file mode 100644 index 00000000..aeb3308e --- /dev/null +++ b/src/app/zelda3/sprite.h @@ -0,0 +1,68 @@ +#ifndef YAZE_APP_ZELDA3_SPRITE_H +#define YAZE_APP_ZELDA3_SPRITE_H + +#include + +#include +#include +#include +#include + +#include "absl/status/status.h" +#include "app/core/constants.h" +#include "app/gfx/bitmap.h" +#include "app/gfx/snes_tile.h" +#include "app/rom.h" + +namespace yaze { +namespace app { +namespace zelda3 { + +class Sprite { + public: + uchar x_, y_, id_; + uchar nx_, ny_; + uchar layer_ = 0; + uchar subtype_ = 0; + uchar overlord_ = 0; + std::string name_; + uchar keyDrop_ = 0; + int sizeMap_ = 512; + bool overworld_ = false; + bool preview_ = false; + uchar map_id_ = 0; + int map_x_ = 0; + int map_y_ = 0; + short room_id_ = 0; + bool picker_ = false; + bool selected_ = false; + SDL_Rect bounding_box_; + + Bytes current_gfx_; + Bytes preview_gfx_; + + int lowerX_ = 32; + int lowerY_ = 32; + int higherX_ = 0; + int higherY_ = 0; + int width_ = 16; + int height_ = 16; + + Sprite(Bytes src, uchar mapid, uchar id, uchar x, uchar y, int map_x, + int map_y); + void updateBBox(); + + void Draw(bool picker = false); + + void DrawSpriteTile(int x, int y, int srcx, int srcy, int pal, + bool mirror_x = false, bool mirror_y = false, + int sizex = 2, int sizey = 2, bool iskey = false); + + auto PreviewGraphics() { return preview_gfx_; } +}; + +} // namespace zelda3 +} // namespace app +} // namespace yaze + +#endif \ No newline at end of file diff --git a/src/app/zelda3/title_screen.cc b/src/app/zelda3/title_screen.cc new file mode 100644 index 00000000..7553ca77 --- /dev/null +++ b/src/app/zelda3/title_screen.cc @@ -0,0 +1,129 @@ +#include "title_screen.h" + +#include + +#include "app/core/common.h" +#include "app/gfx/bitmap.h" +#include "app/gfx/snes_tile.h" +#include "app/rom.h" + +namespace yaze { +namespace app { +namespace zelda3 { + +void TitleScreen::Create() { + tiles8Bitmap.Create(128, 512, 8, 0x20000); + tilesBG1Bitmap.Create(256, 256, 8, 0x80000); + tilesBG2Bitmap.Create(256, 256, 8, 0x80000); + oamBGBitmap.Create(256, 256, 8, 0x80000); + + BuildTileset(); + + LoadTitleScreen(); +} + +void TitleScreen::BuildTileset() { + uchar staticgfx[16]; + + // Main Blocksets + + // TODO: get the gfx from the GFX class rather than the rom. + // for (int i = 0; i < 8; i++) { + // staticgfx[i] = GfxGroups.mainGfx[titleScreenTilesGFX][i]; + // } + + staticgfx[8] = 115 + 0; + // staticgfx[9] = (GfxGroups.spriteGfx[titleScreenSpritesGFX][3] + 115); + staticgfx[10] = 115 + 6; + staticgfx[11] = 115 + 7; + // staticgfx[12] = (GfxGroups.spriteGfx[titleScreenSpritesGFX][0] + 115); + staticgfx[13] = 112; + staticgfx[14] = 112; + staticgfx[15] = 112; + + // Loaded gfx for the current screen (empty at this point) + uchar* currentmapgfx8Data = tiles8Bitmap.GetData(); + + // All gfx of the game pack of 2048 bytes (4bpp) + uchar* allgfxData = nullptr; // rom_.GetMasterGraphicsBin(); + for (int i = 0; i < 16; i++) { + for (int j = 0; j < 2048; j++) { + uchar mapByte = allgfxData[j + (staticgfx[i] * 2048)]; + switch (i) { + case 0: + case 3: + case 4: + case 5: + mapByte += 0x88; + break; + } + + currentmapgfx8Data[(i * 2048) + j] = mapByte; // Upload used gfx data + } + } +} + +void TitleScreen::LoadTitleScreen() { + int pos = + (rom_[0x138C + 3] << 16) + (rom_[0x1383 + 3] << 8) + rom_[0x137A + 3]; + + for (int i = 0; i < 1024; i++) { + tilesBG1Buffer[i] = 492; + tilesBG2Buffer[i] = 492; + } + + pos = core::SnesToPc(pos); + + while ((rom_[pos] & 0x80) != 0x80) { + int dest_addr = pos; // $03 and $04 + pos += 2; + short length = pos; + bool increment64 = (length & 0x8000) == 0x8000; + bool fixsource = (length & 0x4000) == 0x4000; + pos += 2; + + length = (short)((length & 0x07FF)); + + int j = 0; + int jj = 0; + int posB = pos; + while (j < (length / 2) + 1) { + ushort tiledata = (ushort)pos; + if (dest_addr >= 0x1000) { + // destAddr -= 0x1000; + if (dest_addr < 0x2000) { + tilesBG1Buffer[dest_addr - 0x1000] = tiledata; + } + } else { + if (dest_addr < 0x1000) { + tilesBG2Buffer[dest_addr] = tiledata; + } + } + + if (increment64) { + dest_addr += 32; + } else { + dest_addr++; + } + + if (!fixsource) { + pos += 2; + } + + jj += 2; + j++; + } + + if (fixsource) { + pos += 2; + } else { + pos = posB + jj; + } + } + + pal_selected_ = 2; +} + +} // namespace zelda3 +} // namespace app +} // namespace yaze \ No newline at end of file diff --git a/src/app/zelda3/title_screen.h b/src/app/zelda3/title_screen.h new file mode 100644 index 00000000..4cade272 --- /dev/null +++ b/src/app/zelda3/title_screen.h @@ -0,0 +1,81 @@ +#ifndef YAZE_APP_ZELDA3_SCREEN_H +#define YAZE_APP_ZELDA3_SCREEN_H + +#include + +#include "app/core/common.h" +#include "app/gfx/bitmap.h" +#include "app/gfx/snes_tile.h" +#include "app/rom.h" + +namespace yaze { +namespace app { +namespace zelda3 { + +class TitleScreen { + public: + void Create(); + + private: + void BuildTileset(); + void LoadTitleScreen(); + + int sword_x_ = 0; + int mx_click_ = 0; + int my_click_ = 0; + int mx_dist_ = 0; + int my_dist_ = 0; + int last_x_ = 0; + int last_y_ = 0; + int x_in_ = 0; + int y_in_ = 0; + int dungmap_selected_tile_ = 0; + int dungmap_selected_ = 0; + int selected_palette_ = 0; + int total_floors_ = 0; + int current_floor_ = 0; + int num_basement_ = 0; + int num_floor_ = 0; + int selected_map_tile = 0; + int current_floor_rooms; // [1][]; + int current_floor_gfx; // [1][]; + int copied_data_rooms; // 25 + int copied_data_gfx; // 25 + int pal_selected_; + int addresses[7] = {0x53de4, 0x53e2c, 0x53e08, 0x53e50, + 0x53e74, 0x53e98, 0x53ebc}; + int addressesgfx[7] = {0x53ee0, 0x53f04, 0x53ef2, 0x53f16, + 0x53f28, 0x53f3a, 0x53f4c}; + + ushort bossRoom = 0x000F; + ushort selected_tile = 0; + ushort tilesBG1Buffer[0x1000]; // 0x1000 + ushort tilesBG2Buffer[0x1000]; // 0x1000 + uchar mapdata; // 64 * 64 + uchar dwmapdata; // 64 * 64 + + bool mDown = false; + bool swordSelected = false; + bool darkWorld = false; + bool currentDungeonChanged = false; + bool editedFromEditor = false; + bool mouseDown = false; + bool mdown = false; + + ROM rom_; + + gfx::OAMTile oam_data[10]; + gfx::OAMTile selected_oam_tile; + gfx::OAMTile last_selected_oam_tile; + + gfx::Bitmap tilesBG1Bitmap; // 0x80000 + gfx::Bitmap tilesBG2Bitmap; // 0x80000 + gfx::Bitmap oamBGBitmap; // 0x80000 + gfx::Bitmap tiles8Bitmap; // 0x20000 +}; + +} // namespace zelda3 +} // namespace app +} // namespace yaze + +#endif \ No newline at end of file diff --git a/src/gui/canvas.cc b/src/gui/canvas.cc new file mode 100644 index 00000000..14b4ec86 --- /dev/null +++ b/src/gui/canvas.cc @@ -0,0 +1,199 @@ +#include "canvas.h" + +#include + +#include +#include + +#include "app/gfx/bitmap.h" +#include "app/rom.h" + +namespace yaze { +namespace gui { + +void Canvas::DrawBackground(ImVec2 canvas_size) { + canvas_p0_ = ImGui::GetCursorScreenPos(); + if (!custom_canvas_size_) canvas_sz_ = ImGui::GetContentRegionAvail(); + if (canvas_size.x != 0) canvas_sz_ = canvas_size; + + canvas_p1_ = ImVec2(canvas_p0_.x + canvas_sz_.x, canvas_p0_.y + canvas_sz_.y); + + // Draw border and background color + draw_list_ = ImGui::GetWindowDrawList(); + draw_list_->AddRectFilled(canvas_p0_, canvas_p1_, IM_COL32(32, 32, 32, 255)); + draw_list_->AddRect(canvas_p0_, canvas_p1_, IM_COL32(255, 255, 255, 255)); +} + +void Canvas::DrawContextMenu() { + // This will catch our interactions + const ImGuiIO &io = ImGui::GetIO(); + ImGui::InvisibleButton( + "canvas", canvas_sz_, + ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight); + const bool is_hovered = ImGui::IsItemHovered(); // Hovered + const bool is_active = ImGui::IsItemActive(); // Held + const ImVec2 origin(canvas_p0_.x + scrolling_.x, + canvas_p0_.y + scrolling_.y); // Lock scrolled origin + const ImVec2 mouse_pos_in_canvas(io.MousePos.x - origin.x, + io.MousePos.y - origin.y); + + // Pan (we use a zero mouse threshold when there's no context menu) + const float mouse_threshold_for_pan = enable_context_menu_ ? -1.0f : 0.0f; + if (is_active && + ImGui::IsMouseDragging(ImGuiMouseButton_Right, mouse_threshold_for_pan)) { + scrolling_.x += io.MouseDelta.x; + scrolling_.y += io.MouseDelta.y; + } + + // Context menu (under default mouse threshold) + ImVec2 drag_delta = ImGui::GetMouseDragDelta(ImGuiMouseButton_Right); + if (enable_context_menu_ && drag_delta.x == 0.0f && drag_delta.y == 0.0f) + ImGui::OpenPopupOnItemClick("context", ImGuiPopupFlags_MouseButtonRight); + + if (ImGui::BeginPopup("context")) { + ImGui::MenuItem("Show Grid", nullptr, &enable_grid_); + if (ImGui::MenuItem("Reset Position", nullptr, false)) { + scrolling_.x = 0; + scrolling_.y = 0; + } + if (ImGui::MenuItem("Remove all", nullptr, false, points_.Size > 0)) { + points_.clear(); + } + ImGui::EndPopup(); + } +} + +void Canvas::DrawTilePainter(const Bitmap &bitmap, int size) { + const ImGuiIO &io = ImGui::GetIO(); + const bool is_hovered = ImGui::IsItemHovered(); // Hovered + const ImVec2 origin(canvas_p0_.x + scrolling_.x, + canvas_p0_.y + scrolling_.y); // Lock scrolled origin + const ImVec2 mouse_pos_in_canvas(io.MousePos.x - origin.x, + io.MousePos.y - origin.y); + + if (is_hovered) { + if (!points_.empty()) { + points_.clear(); + } + ImVec2 draw_tile_outline_pos; + draw_tile_outline_pos.x = + std::floor((double)mouse_pos_in_canvas.x / size) * size; + draw_tile_outline_pos.y = + std::floor((double)mouse_pos_in_canvas.y / size) * size; + + points_.push_back(draw_tile_outline_pos); + points_.push_back( + ImVec2(draw_tile_outline_pos.x + size, draw_tile_outline_pos.y + size)); + + if (bitmap.IsActive()) { + draw_list_->AddImage( + (void *)bitmap.GetTexture(), + ImVec2(origin.x + draw_tile_outline_pos.x, + origin.y + draw_tile_outline_pos.y), + ImVec2(origin.x + draw_tile_outline_pos.x + bitmap.GetWidth(), + origin.y + draw_tile_outline_pos.y + bitmap.GetHeight())); + } + + } else { + points_.clear(); + } +} + +void Canvas::DrawTileSelector(int size) { + const ImGuiIO &io = ImGui::GetIO(); + const bool is_hovered = ImGui::IsItemHovered(); // Hovered + const ImVec2 origin(canvas_p0_.x + scrolling_.x, + canvas_p0_.y + scrolling_.y); // Lock scrolled origin + const ImVec2 mouse_pos_in_canvas(io.MousePos.x - origin.x, + io.MousePos.y - origin.y); + + if (is_hovered && ImGui::IsMouseClicked(ImGuiMouseButton_Left)) { + if (!points_.empty()) { + points_.clear(); + } + ImVec2 draw_tile_outline_pos; + draw_tile_outline_pos.x = + std::floor((double)mouse_pos_in_canvas.x / size) * size; + draw_tile_outline_pos.y = + std::floor((double)mouse_pos_in_canvas.y / size) * size; + + points_.push_back(draw_tile_outline_pos); + points_.push_back( + ImVec2(draw_tile_outline_pos.x + size, draw_tile_outline_pos.y + size)); + } +} + +void Canvas::DrawBitmap(const Bitmap &bitmap, int border_offset, bool ready) { + if (ready) { + draw_list_->AddImage( + (void *)bitmap.GetTexture(), + ImVec2(canvas_p0_.x + border_offset, canvas_p0_.y + border_offset), + ImVec2(canvas_p0_.x + (bitmap.GetWidth() * 2), + canvas_p0_.y + (bitmap.GetHeight() * 2))); + } +} + +void Canvas::DrawBitmap(const Bitmap &bitmap, int x_offset, int y_offset) { + draw_list_->AddImage( + (void *)bitmap.GetTexture(), + ImVec2(canvas_p0_.x + x_offset + scrolling_.x, + canvas_p0_.y + y_offset + scrolling_.y), + ImVec2(canvas_p0_.x + x_offset + scrolling_.x + (bitmap.GetWidth()), + canvas_p0_.y + y_offset + scrolling_.y + (bitmap.GetHeight()))); +} + +void Canvas::DrawOutline(int x, int y, int w, int h) { + ImVec2 origin(canvas_p0_.x + scrolling_.x + x, + canvas_p0_.y + scrolling_.y + y); + ImVec2 size(canvas_p0_.x + scrolling_.x + x + w, + canvas_p0_.y + scrolling_.y + y + h); + draw_list_->AddRect(origin, size, IM_COL32(255, 255, 255, 255)); +} + +void Canvas::DrawRect(int x, int y, int w, int h, ImVec4 color) { + ImVec2 origin(canvas_p0_.x + scrolling_.x + x, + canvas_p0_.y + scrolling_.y + y); + ImVec2 size(canvas_p0_.x + scrolling_.x + x + w, + canvas_p0_.y + scrolling_.y + y + h); + draw_list_->AddRectFilled(origin, size, + IM_COL32(color.x, color.y, color.z, color.w)); +} + +void Canvas::DrawText(std::string text, int x, int y) { + draw_list_->AddText( + ImVec2(canvas_p0_.x + scrolling_.x + x, canvas_p0_.y + scrolling_.y + y), + IM_COL32(255, 255, 255, 255), text.data()); +} + +void Canvas::DrawGrid(float grid_step) { + // Draw grid + all lines in the canvas + draw_list_->PushClipRect(canvas_p0_, canvas_p1_, true); + if (enable_grid_) { + for (float x = fmodf(scrolling_.x, grid_step); x < canvas_sz_.x; + x += grid_step) + draw_list_->AddLine(ImVec2(canvas_p0_.x + x, canvas_p0_.y), + ImVec2(canvas_p0_.x + x, canvas_p1_.y), + IM_COL32(200, 200, 200, 40)); + for (float y = fmodf(scrolling_.y, grid_step); y < canvas_sz_.y; + y += grid_step) + draw_list_->AddLine(ImVec2(canvas_p0_.x, canvas_p0_.y + y), + ImVec2(canvas_p1_.x, canvas_p0_.y + y), + IM_COL32(200, 200, 200, 40)); + } +} + +void Canvas::DrawOverlay() { + const ImVec2 origin(canvas_p0_.x + scrolling_.x, + canvas_p0_.y + scrolling_.y); // Lock scrolled origin + for (int n = 0; n < points_.Size; n += 2) { + draw_list_->AddRect( + ImVec2(origin.x + points_[n].x, origin.y + points_[n].y), + ImVec2(origin.x + points_[n + 1].x, origin.y + points_[n + 1].y), + IM_COL32(255, 255, 255, 255), 1.0f); + } + + draw_list_->PopClipRect(); +} + +} // namespace gui +} // namespace yaze \ No newline at end of file diff --git a/src/gui/canvas.h b/src/gui/canvas.h new file mode 100644 index 00000000..e0a6eb78 --- /dev/null +++ b/src/gui/canvas.h @@ -0,0 +1,67 @@ +#ifndef YAZE_GUI_CANVAS_H +#define YAZE_GUI_CANVAS_H + +#include + +#include +#include + +#include "app/gfx/bitmap.h" +#include "app/rom.h" + +namespace yaze { +namespace gui { + +using app::gfx::Bitmap; + +class Canvas { + public: + Canvas() = default; + explicit Canvas(ImVec2 canvas_size) + : custom_canvas_size_(true), canvas_sz_(canvas_size) {} + + void DrawBackground(ImVec2 canvas_size = ImVec2(0, 0)); + void DrawContextMenu(); + void DrawTilePainter(const Bitmap& bitmap, int size); + void DrawTileSelector(int size); + void DrawBitmap(const Bitmap& bitmap, int border_offset = 0, + bool ready = true); + void DrawBitmap(const Bitmap& bitmap, int x_offset, int y_offset); + void DrawOutline(int x, int y, int w, int h); + void DrawRect(int x, int y, int w, int h, ImVec4 color); + void DrawText(std::string text, int x, int y); + void DrawGrid(float grid_step = 64.0f); + void DrawOverlay(); // last + + auto Points() const { return points_; } + auto GetDrawList() const { return draw_list_; } + auto GetZeroPoint() const { return canvas_p0_; } + void SetCanvasSize(ImVec2 canvas_size) { + canvas_sz_ = canvas_size; + custom_canvas_size_ = true; + } + + private: + bool enable_grid_ = true; + bool enable_context_menu_ = true; + bool custom_canvas_size_ = false; + bool is_hovered_ = false; + + ImDrawList* draw_list_; + ImVector points_; + ImVec2 scrolling_; + ImVec2 canvas_sz_; + ImVec2 canvas_p0_; + ImVec2 canvas_p1_; + ImVec2 mouse_pos_in_canvas_; + + std::vector changed_tiles_; + app::gfx::Bitmap current_tile_; + + std::string title_; +}; + +} // namespace gui +} // namespace yaze + +#endif \ No newline at end of file diff --git a/src/gui/color.cc b/src/gui/color.cc new file mode 100644 index 00000000..22c836a1 --- /dev/null +++ b/src/gui/color.cc @@ -0,0 +1,84 @@ +#include "color.h" + +#include + +#include +#include + +#include "app/gfx/bitmap.h" +#include "app/gfx/snes_palette.h" + +namespace yaze { +namespace gui { +void DisplayPalette(app::gfx::SNESPalette& palette, bool loaded) { + static ImVec4 color = ImVec4(0, 0, 0, 255.f); + ImGuiColorEditFlags misc_flags = ImGuiColorEditFlags_AlphaPreview | + ImGuiColorEditFlags_NoDragDrop | + ImGuiColorEditFlags_NoOptions; + + // Generate a default palette. The palette will persist and can be edited. + static bool init = false; + static ImVec4 saved_palette[32] = {}; + if (loaded && !init) { + for (int n = 0; n < palette.size_; n++) { + saved_palette[n].x = palette.GetColor(n).rgb.x / 255; + saved_palette[n].y = palette.GetColor(n).rgb.y / 255; + saved_palette[n].z = palette.GetColor(n).rgb.z / 255; + saved_palette[n].w = 255; // Alpha + } + init = true; + } + + static ImVec4 backup_color; + ImGui::Text("Current ==>"); + ImGui::SameLine(); + ImGui::Text("Previous"); + + ImGui::ColorButton( + "##current", color, + ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_AlphaPreviewHalf, + ImVec2(60, 40)); + ImGui::SameLine(); + + if (ImGui::ColorButton( + "##previous", backup_color, + ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_AlphaPreviewHalf, + ImVec2(60, 40))) + color = backup_color; + ImGui::Separator(); + +ImGui::BeginGroup(); // Lock X position + ImGui::Text("Palette"); + for (int n = 0; n < IM_ARRAYSIZE(saved_palette); n++) { + ImGui::PushID(n); + if ((n % 4) != 0) ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y); + + ImGuiColorEditFlags palette_button_flags = ImGuiColorEditFlags_NoAlpha | + ImGuiColorEditFlags_NoPicker | + ImGuiColorEditFlags_NoTooltip; + if (ImGui::ColorButton("##palette", saved_palette[n], palette_button_flags, + ImVec2(20, 20))) + color = ImVec4(saved_palette[n].x, saved_palette[n].y, saved_palette[n].z, + color.w); // Preserve alpha! + + if (ImGui::BeginDragDropTarget()) { + if (const ImGuiPayload* payload = + ImGui::AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_3F)) + memcpy((float*)&saved_palette[n], payload->Data, sizeof(float) * 3); + if (const ImGuiPayload* payload = + ImGui::AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_4F)) + memcpy((float*)&saved_palette[n], payload->Data, sizeof(float) * 4); + ImGui::EndDragDropTarget(); + } + + ImGui::PopID(); + } + ImGui::EndGroup(); + ImGui::SameLine(); + + ImGui::ColorPicker4("##picker", (float*)&color, + misc_flags | ImGuiColorEditFlags_NoSidePreview | + ImGuiColorEditFlags_NoSmallPreview); +} +} // namespace gui +} // namespace yaze \ No newline at end of file diff --git a/src/gui/color.h b/src/gui/color.h new file mode 100644 index 00000000..fc9c5bc4 --- /dev/null +++ b/src/gui/color.h @@ -0,0 +1,20 @@ +#ifndef YAZE_GUI_COLOR_H +#define YAZE_GUI_COLOR_H + +#include + +#include +#include + +#include "app/gfx/bitmap.h" +#include "app/gfx/snes_palette.h" + +namespace yaze { +namespace gui { + +void DisplayPalette(app::gfx::SNESPalette& palette, bool loaded); + +} // namespace gui +} // namespace yaze + +#endif \ No newline at end of file diff --git a/src/gui/icons.h b/src/gui/icons.h new file mode 100644 index 00000000..11748e17 --- /dev/null +++ b/src/gui/icons.h @@ -0,0 +1,2192 @@ +// Generated by https://github.com/juliettef/IconFontCppHeaders script GenerateIconFontCppHeaders.py for languages C and C++ +// from https://github.com/google/material-design-icons/raw/master/font/MaterialIcons-Regular.codepoints +// for use with https://github.com/google/material-design-icons/blob/master/font/MaterialIcons-Regular.ttf +#pragma once + +#define FONT_ICON_FILE_NAME_MD "assets/font/MaterialIcons-Regular.ttf" + +#define ICON_MIN_MD 0xe000 +#define ICON_MAX_MD 0x10fffd +#define ICON_MD_10K "\xee\xa5\x91" // U+e951 +#define ICON_MD_10MP "\xee\xa5\x92" // U+e952 +#define ICON_MD_11MP "\xee\xa5\x93" // U+e953 +#define ICON_MD_123 "\xee\xae\x8d" // U+eb8d +#define ICON_MD_12MP "\xee\xa5\x94" // U+e954 +#define ICON_MD_13MP "\xee\xa5\x95" // U+e955 +#define ICON_MD_14MP "\xee\xa5\x96" // U+e956 +#define ICON_MD_15MP "\xee\xa5\x97" // U+e957 +#define ICON_MD_16MP "\xee\xa5\x98" // U+e958 +#define ICON_MD_17MP "\xee\xa5\x99" // U+e959 +#define ICON_MD_18_UP_RATING "\xef\xa3\xbd" // U+f8fd +#define ICON_MD_18MP "\xee\xa5\x9a" // U+e95a +#define ICON_MD_19MP "\xee\xa5\x9b" // U+e95b +#define ICON_MD_1K "\xee\xa5\x9c" // U+e95c +#define ICON_MD_1K_PLUS "\xee\xa5\x9d" // U+e95d +#define ICON_MD_1X_MOBILEDATA "\xee\xbf\x8d" // U+efcd +#define ICON_MD_20MP "\xee\xa5\x9e" // U+e95e +#define ICON_MD_21MP "\xee\xa5\x9f" // U+e95f +#define ICON_MD_22MP "\xee\xa5\xa0" // U+e960 +#define ICON_MD_23MP "\xee\xa5\xa1" // U+e961 +#define ICON_MD_24MP "\xee\xa5\xa2" // U+e962 +#define ICON_MD_2K "\xee\xa5\xa3" // U+e963 +#define ICON_MD_2K_PLUS "\xee\xa5\xa4" // U+e964 +#define ICON_MD_2MP "\xee\xa5\xa5" // U+e965 +#define ICON_MD_30FPS "\xee\xbf\x8e" // U+efce +#define ICON_MD_30FPS_SELECT "\xee\xbf\x8f" // U+efcf +#define ICON_MD_360 "\xee\x95\xb7" // U+e577 +#define ICON_MD_3D_ROTATION "\xee\xa1\x8d" // U+e84d +#define ICON_MD_3G_MOBILEDATA "\xee\xbf\x90" // U+efd0 +#define ICON_MD_3K "\xee\xa5\xa6" // U+e966 +#define ICON_MD_3K_PLUS "\xee\xa5\xa7" // U+e967 +#define ICON_MD_3MP "\xee\xa5\xa8" // U+e968 +#define ICON_MD_3P "\xee\xbf\x91" // U+efd1 +#define ICON_MD_4G_MOBILEDATA "\xee\xbf\x92" // U+efd2 +#define ICON_MD_4G_PLUS_MOBILEDATA "\xee\xbf\x93" // U+efd3 +#define ICON_MD_4K "\xee\x81\xb2" // U+e072 +#define ICON_MD_4K_PLUS "\xee\xa5\xa9" // U+e969 +#define ICON_MD_4MP "\xee\xa5\xaa" // U+e96a +#define ICON_MD_5G "\xee\xbc\xb8" // U+ef38 +#define ICON_MD_5K "\xee\xa5\xab" // U+e96b +#define ICON_MD_5K_PLUS "\xee\xa5\xac" // U+e96c +#define ICON_MD_5MP "\xee\xa5\xad" // U+e96d +#define ICON_MD_60FPS "\xee\xbf\x94" // U+efd4 +#define ICON_MD_60FPS_SELECT "\xee\xbf\x95" // U+efd5 +#define ICON_MD_6_FT_APART "\xef\x88\x9e" // U+f21e +#define ICON_MD_6K "\xee\xa5\xae" // U+e96e +#define ICON_MD_6K_PLUS "\xee\xa5\xaf" // U+e96f +#define ICON_MD_6MP "\xee\xa5\xb0" // U+e970 +#define ICON_MD_7K "\xee\xa5\xb1" // U+e971 +#define ICON_MD_7K_PLUS "\xee\xa5\xb2" // U+e972 +#define ICON_MD_7MP "\xee\xa5\xb3" // U+e973 +#define ICON_MD_8K "\xee\xa5\xb4" // U+e974 +#define ICON_MD_8K_PLUS "\xee\xa5\xb5" // U+e975 +#define ICON_MD_8MP "\xee\xa5\xb6" // U+e976 +#define ICON_MD_9K "\xee\xa5\xb7" // U+e977 +#define ICON_MD_9K_PLUS "\xee\xa5\xb8" // U+e978 +#define ICON_MD_9MP "\xee\xa5\xb9" // U+e979 +#define ICON_MD_ABC "\xee\xae\x94" // U+eb94 +#define ICON_MD_AC_UNIT "\xee\xac\xbb" // U+eb3b +#define ICON_MD_ACCESS_ALARM "\xee\x86\x90" // U+e190 +#define ICON_MD_ACCESS_ALARMS "\xee\x86\x91" // U+e191 +#define ICON_MD_ACCESS_TIME "\xee\x86\x92" // U+e192 +#define ICON_MD_ACCESS_TIME_FILLED "\xee\xbf\x96" // U+efd6 +#define ICON_MD_ACCESSIBILITY "\xee\xa1\x8e" // U+e84e +#define ICON_MD_ACCESSIBILITY_NEW "\xee\xa4\xac" // U+e92c +#define ICON_MD_ACCESSIBLE "\xee\xa4\x94" // U+e914 +#define ICON_MD_ACCESSIBLE_FORWARD "\xee\xa4\xb4" // U+e934 +#define ICON_MD_ACCOUNT_BALANCE "\xee\xa1\x8f" // U+e84f +#define ICON_MD_ACCOUNT_BALANCE_WALLET "\xee\xa1\x90" // U+e850 +#define ICON_MD_ACCOUNT_BOX "\xee\xa1\x91" // U+e851 +#define ICON_MD_ACCOUNT_CIRCLE "\xee\xa1\x93" // U+e853 +#define ICON_MD_ACCOUNT_TREE "\xee\xa5\xba" // U+e97a +#define ICON_MD_AD_UNITS "\xee\xbc\xb9" // U+ef39 +#define ICON_MD_ADB "\xee\x98\x8e" // U+e60e +#define ICON_MD_ADD "\xee\x85\x85" // U+e145 +#define ICON_MD_ADD_A_PHOTO "\xee\x90\xb9" // U+e439 +#define ICON_MD_ADD_ALARM "\xee\x86\x93" // U+e193 +#define ICON_MD_ADD_ALERT "\xee\x80\x83" // U+e003 +#define ICON_MD_ADD_BOX "\xee\x85\x86" // U+e146 +#define ICON_MD_ADD_BUSINESS "\xee\x9c\xa9" // U+e729 +#define ICON_MD_ADD_CALL "\xee\x83\xa8" // U+e0e8 +#define ICON_MD_ADD_CARD "\xee\xae\x86" // U+eb86 +#define ICON_MD_ADD_CHART "\xee\xa5\xbb" // U+e97b +#define ICON_MD_ADD_CIRCLE "\xee\x85\x87" // U+e147 +#define ICON_MD_ADD_CIRCLE_OUTLINE "\xee\x85\x88" // U+e148 +#define ICON_MD_ADD_COMMENT "\xee\x89\xa6" // U+e266 +#define ICON_MD_ADD_IC_CALL "\xee\xa5\xbc" // U+e97c +#define ICON_MD_ADD_LINK "\xee\x85\xb8" // U+e178 +#define ICON_MD_ADD_LOCATION "\xee\x95\xa7" // U+e567 +#define ICON_MD_ADD_LOCATION_ALT "\xee\xbc\xba" // U+ef3a +#define ICON_MD_ADD_MODERATOR "\xee\xa5\xbd" // U+e97d +#define ICON_MD_ADD_PHOTO_ALTERNATE "\xee\x90\xbe" // U+e43e +#define ICON_MD_ADD_REACTION "\xee\x87\x93" // U+e1d3 +#define ICON_MD_ADD_ROAD "\xee\xbc\xbb" // U+ef3b +#define ICON_MD_ADD_SHOPPING_CART "\xee\xa1\x94" // U+e854 +#define ICON_MD_ADD_TASK "\xef\x88\xba" // U+f23a +#define ICON_MD_ADD_TO_DRIVE "\xee\x99\x9c" // U+e65c +#define ICON_MD_ADD_TO_HOME_SCREEN "\xee\x87\xbe" // U+e1fe +#define ICON_MD_ADD_TO_PHOTOS "\xee\x8e\x9d" // U+e39d +#define ICON_MD_ADD_TO_QUEUE "\xee\x81\x9c" // U+e05c +#define ICON_MD_ADDCHART "\xee\xbc\xbc" // U+ef3c +#define ICON_MD_ADF_SCANNER "\xee\xab\x9a" // U+eada +#define ICON_MD_ADJUST "\xee\x8e\x9e" // U+e39e +#define ICON_MD_ADMIN_PANEL_SETTINGS "\xee\xbc\xbd" // U+ef3d +#define ICON_MD_ADOBE "\xee\xaa\x96" // U+ea96 +#define ICON_MD_ADS_CLICK "\xee\x9d\xa2" // U+e762 +#define ICON_MD_AGRICULTURE "\xee\xa9\xb9" // U+ea79 +#define ICON_MD_AIR "\xee\xbf\x98" // U+efd8 +#define ICON_MD_AIRLINE_SEAT_FLAT "\xee\x98\xb0" // U+e630 +#define ICON_MD_AIRLINE_SEAT_FLAT_ANGLED "\xee\x98\xb1" // U+e631 +#define ICON_MD_AIRLINE_SEAT_INDIVIDUAL_SUITE "\xee\x98\xb2" // U+e632 +#define ICON_MD_AIRLINE_SEAT_LEGROOM_EXTRA "\xee\x98\xb3" // U+e633 +#define ICON_MD_AIRLINE_SEAT_LEGROOM_NORMAL "\xee\x98\xb4" // U+e634 +#define ICON_MD_AIRLINE_SEAT_LEGROOM_REDUCED "\xee\x98\xb5" // U+e635 +#define ICON_MD_AIRLINE_SEAT_RECLINE_EXTRA "\xee\x98\xb6" // U+e636 +#define ICON_MD_AIRLINE_SEAT_RECLINE_NORMAL "\xee\x98\xb7" // U+e637 +#define ICON_MD_AIRLINE_STOPS "\xee\x9f\x90" // U+e7d0 +#define ICON_MD_AIRLINES "\xee\x9f\x8a" // U+e7ca +#define ICON_MD_AIRPLANE_TICKET "\xee\xbf\x99" // U+efd9 +#define ICON_MD_AIRPLANEMODE_ACTIVE "\xee\x86\x95" // U+e195 +#define ICON_MD_AIRPLANEMODE_INACTIVE "\xee\x86\x94" // U+e194 +#define ICON_MD_AIRPLANEMODE_OFF "\xee\x86\x94" // U+e194 +#define ICON_MD_AIRPLANEMODE_ON "\xee\x86\x95" // U+e195 +#define ICON_MD_AIRPLAY "\xee\x81\x95" // U+e055 +#define ICON_MD_AIRPORT_SHUTTLE "\xee\xac\xbc" // U+eb3c +#define ICON_MD_ALARM "\xee\xa1\x95" // U+e855 +#define ICON_MD_ALARM_ADD "\xee\xa1\x96" // U+e856 +#define ICON_MD_ALARM_OFF "\xee\xa1\x97" // U+e857 +#define ICON_MD_ALARM_ON "\xee\xa1\x98" // U+e858 +#define ICON_MD_ALBUM "\xee\x80\x99" // U+e019 +#define ICON_MD_ALIGN_HORIZONTAL_CENTER "\xee\x80\x8f" // U+e00f +#define ICON_MD_ALIGN_HORIZONTAL_LEFT "\xee\x80\x8d" // U+e00d +#define ICON_MD_ALIGN_HORIZONTAL_RIGHT "\xee\x80\x90" // U+e010 +#define ICON_MD_ALIGN_VERTICAL_BOTTOM "\xee\x80\x95" // U+e015 +#define ICON_MD_ALIGN_VERTICAL_CENTER "\xee\x80\x91" // U+e011 +#define ICON_MD_ALIGN_VERTICAL_TOP "\xee\x80\x8c" // U+e00c +#define ICON_MD_ALL_INBOX "\xee\xa5\xbf" // U+e97f +#define ICON_MD_ALL_INCLUSIVE "\xee\xac\xbd" // U+eb3d +#define ICON_MD_ALL_OUT "\xee\xa4\x8b" // U+e90b +#define ICON_MD_ALT_ROUTE "\xef\x86\x84" // U+f184 +#define ICON_MD_ALTERNATE_EMAIL "\xee\x83\xa6" // U+e0e6 +#define ICON_MD_AMP_STORIES "\xee\xa8\x93" // U+ea13 +#define ICON_MD_ANALYTICS "\xee\xbc\xbe" // U+ef3e +#define ICON_MD_ANCHOR "\xef\x87\x8d" // U+f1cd +#define ICON_MD_ANDROID "\xee\xa1\x99" // U+e859 +#define ICON_MD_ANIMATION "\xee\x9c\x9c" // U+e71c +#define ICON_MD_ANNOUNCEMENT "\xee\xa1\x9a" // U+e85a +#define ICON_MD_AOD "\xee\xbf\x9a" // U+efda +#define ICON_MD_APARTMENT "\xee\xa9\x80" // U+ea40 +#define ICON_MD_API "\xef\x86\xb7" // U+f1b7 +#define ICON_MD_APP_BLOCKING "\xee\xbc\xbf" // U+ef3f +#define ICON_MD_APP_REGISTRATION "\xee\xbd\x80" // U+ef40 +#define ICON_MD_APP_SETTINGS_ALT "\xee\xbd\x81" // U+ef41 +#define ICON_MD_APP_SHORTCUT "\xee\xab\xa4" // U+eae4 +#define ICON_MD_APPLE "\xee\xaa\x80" // U+ea80 +#define ICON_MD_APPROVAL "\xee\xa6\x82" // U+e982 +#define ICON_MD_APPS "\xee\x97\x83" // U+e5c3 +#define ICON_MD_APPS_OUTAGE "\xee\x9f\x8c" // U+e7cc +#define ICON_MD_ARCHITECTURE "\xee\xa8\xbb" // U+ea3b +#define ICON_MD_ARCHIVE "\xee\x85\x89" // U+e149 +#define ICON_MD_AREA_CHART "\xee\x9d\xb0" // U+e770 +#define ICON_MD_ARROW_BACK "\xee\x97\x84" // U+e5c4 +#define ICON_MD_ARROW_BACK_IOS "\xee\x97\xa0" // U+e5e0 +#define ICON_MD_ARROW_BACK_IOS_NEW "\xee\x8b\xaa" // U+e2ea +#define ICON_MD_ARROW_CIRCLE_DOWN "\xef\x86\x81" // U+f181 +#define ICON_MD_ARROW_CIRCLE_LEFT "\xee\xaa\xa7" // U+eaa7 +#define ICON_MD_ARROW_CIRCLE_RIGHT "\xee\xaa\xaa" // U+eaaa +#define ICON_MD_ARROW_CIRCLE_UP "\xef\x86\x82" // U+f182 +#define ICON_MD_ARROW_DOWNWARD "\xee\x97\x9b" // U+e5db +#define ICON_MD_ARROW_DROP_DOWN "\xee\x97\x85" // U+e5c5 +#define ICON_MD_ARROW_DROP_DOWN_CIRCLE "\xee\x97\x86" // U+e5c6 +#define ICON_MD_ARROW_DROP_UP "\xee\x97\x87" // U+e5c7 +#define ICON_MD_ARROW_FORWARD "\xee\x97\x88" // U+e5c8 +#define ICON_MD_ARROW_FORWARD_IOS "\xee\x97\xa1" // U+e5e1 +#define ICON_MD_ARROW_LEFT "\xee\x97\x9e" // U+e5de +#define ICON_MD_ARROW_RIGHT "\xee\x97\x9f" // U+e5df +#define ICON_MD_ARROW_RIGHT_ALT "\xee\xa5\x81" // U+e941 +#define ICON_MD_ARROW_UPWARD "\xee\x97\x98" // U+e5d8 +#define ICON_MD_ART_TRACK "\xee\x81\xa0" // U+e060 +#define ICON_MD_ARTICLE "\xee\xbd\x82" // U+ef42 +#define ICON_MD_ASPECT_RATIO "\xee\xa1\x9b" // U+e85b +#define ICON_MD_ASSESSMENT "\xee\xa1\x9c" // U+e85c +#define ICON_MD_ASSIGNMENT "\xee\xa1\x9d" // U+e85d +#define ICON_MD_ASSIGNMENT_IND "\xee\xa1\x9e" // U+e85e +#define ICON_MD_ASSIGNMENT_LATE "\xee\xa1\x9f" // U+e85f +#define ICON_MD_ASSIGNMENT_RETURN "\xee\xa1\xa0" // U+e860 +#define ICON_MD_ASSIGNMENT_RETURNED "\xee\xa1\xa1" // U+e861 +#define ICON_MD_ASSIGNMENT_TURNED_IN "\xee\xa1\xa2" // U+e862 +#define ICON_MD_ASSISTANT "\xee\x8e\x9f" // U+e39f +#define ICON_MD_ASSISTANT_DIRECTION "\xee\xa6\x88" // U+e988 +#define ICON_MD_ASSISTANT_NAVIGATION "\xee\xa6\x89" // U+e989 +#define ICON_MD_ASSISTANT_PHOTO "\xee\x8e\xa0" // U+e3a0 +#define ICON_MD_ASSURED_WORKLOAD "\xee\xad\xaf" // U+eb6f +#define ICON_MD_ATM "\xee\x95\xb3" // U+e573 +#define ICON_MD_ATTACH_EMAIL "\xee\xa9\x9e" // U+ea5e +#define ICON_MD_ATTACH_FILE "\xee\x88\xa6" // U+e226 +#define ICON_MD_ATTACH_MONEY "\xee\x88\xa7" // U+e227 +#define ICON_MD_ATTACHMENT "\xee\x8a\xbc" // U+e2bc +#define ICON_MD_ATTRACTIONS "\xee\xa9\x92" // U+ea52 +#define ICON_MD_ATTRIBUTION "\xee\xbf\x9b" // U+efdb +#define ICON_MD_AUDIO_FILE "\xee\xae\x82" // U+eb82 +#define ICON_MD_AUDIOTRACK "\xee\x8e\xa1" // U+e3a1 +#define ICON_MD_AUTO_AWESOME "\xee\x99\x9f" // U+e65f +#define ICON_MD_AUTO_AWESOME_MOSAIC "\xee\x99\xa0" // U+e660 +#define ICON_MD_AUTO_AWESOME_MOTION "\xee\x99\xa1" // U+e661 +#define ICON_MD_AUTO_DELETE "\xee\xa9\x8c" // U+ea4c +#define ICON_MD_AUTO_FIX_HIGH "\xee\x99\xa3" // U+e663 +#define ICON_MD_AUTO_FIX_NORMAL "\xee\x99\xa4" // U+e664 +#define ICON_MD_AUTO_FIX_OFF "\xee\x99\xa5" // U+e665 +#define ICON_MD_AUTO_GRAPH "\xee\x93\xbb" // U+e4fb +#define ICON_MD_AUTO_MODE "\xee\xb0\xa0" // U+ec20 +#define ICON_MD_AUTO_STORIES "\xee\x99\xa6" // U+e666 +#define ICON_MD_AUTOFPS_SELECT "\xee\xbf\x9c" // U+efdc +#define ICON_MD_AUTORENEW "\xee\xa1\xa3" // U+e863 +#define ICON_MD_AV_TIMER "\xee\x80\x9b" // U+e01b +#define ICON_MD_BABY_CHANGING_STATION "\xef\x86\x9b" // U+f19b +#define ICON_MD_BACK_HAND "\xee\x9d\xa4" // U+e764 +#define ICON_MD_BACKPACK "\xef\x86\x9c" // U+f19c +#define ICON_MD_BACKSPACE "\xee\x85\x8a" // U+e14a +#define ICON_MD_BACKUP "\xee\xa1\xa4" // U+e864 +#define ICON_MD_BACKUP_TABLE "\xee\xbd\x83" // U+ef43 +#define ICON_MD_BADGE "\xee\xa9\xa7" // U+ea67 +#define ICON_MD_BAKERY_DINING "\xee\xa9\x93" // U+ea53 +#define ICON_MD_BALANCE "\xee\xab\xb6" // U+eaf6 +#define ICON_MD_BALCONY "\xee\x96\x8f" // U+e58f +#define ICON_MD_BALLOT "\xee\x85\xb2" // U+e172 +#define ICON_MD_BAR_CHART "\xee\x89\xab" // U+e26b +#define ICON_MD_BATCH_PREDICTION "\xef\x83\xb5" // U+f0f5 +#define ICON_MD_BATHROOM "\xee\xbf\x9d" // U+efdd +#define ICON_MD_BATHTUB "\xee\xa9\x81" // U+ea41 +#define ICON_MD_BATTERY_0_BAR "\xee\xaf\x9c" // U+ebdc +#define ICON_MD_BATTERY_1_BAR "\xee\xaf\x99" // U+ebd9 +#define ICON_MD_BATTERY_2_BAR "\xee\xaf\xa0" // U+ebe0 +#define ICON_MD_BATTERY_3_BAR "\xee\xaf\x9d" // U+ebdd +#define ICON_MD_BATTERY_4_BAR "\xee\xaf\xa2" // U+ebe2 +#define ICON_MD_BATTERY_5_BAR "\xee\xaf\x94" // U+ebd4 +#define ICON_MD_BATTERY_6_BAR "\xee\xaf\x92" // U+ebd2 +#define ICON_MD_BATTERY_ALERT "\xee\x86\x9c" // U+e19c +#define ICON_MD_BATTERY_CHARGING_FULL "\xee\x86\xa3" // U+e1a3 +#define ICON_MD_BATTERY_FULL "\xee\x86\xa4" // U+e1a4 +#define ICON_MD_BATTERY_SAVER "\xee\xbf\x9e" // U+efde +#define ICON_MD_BATTERY_STD "\xee\x86\xa5" // U+e1a5 +#define ICON_MD_BATTERY_UNKNOWN "\xee\x86\xa6" // U+e1a6 +#define ICON_MD_BEACH_ACCESS "\xee\xac\xbe" // U+eb3e +#define ICON_MD_BED "\xee\xbf\x9f" // U+efdf +#define ICON_MD_BEDROOM_BABY "\xee\xbf\xa0" // U+efe0 +#define ICON_MD_BEDROOM_CHILD "\xee\xbf\xa1" // U+efe1 +#define ICON_MD_BEDROOM_PARENT "\xee\xbf\xa2" // U+efe2 +#define ICON_MD_BEDTIME "\xee\xbd\x84" // U+ef44 +#define ICON_MD_BEDTIME_OFF "\xee\xad\xb6" // U+eb76 +#define ICON_MD_BEENHERE "\xee\x94\xad" // U+e52d +#define ICON_MD_BENTO "\xef\x87\xb4" // U+f1f4 +#define ICON_MD_BIKE_SCOOTER "\xee\xbd\x85" // U+ef45 +#define ICON_MD_BIOTECH "\xee\xa8\xba" // U+ea3a +#define ICON_MD_BLENDER "\xee\xbf\xa3" // U+efe3 +#define ICON_MD_BLINDS "\xee\x8a\x86" // U+e286 +#define ICON_MD_BLINDS_CLOSED "\xee\xb0\x9f" // U+ec1f +#define ICON_MD_BLOCK "\xee\x85\x8b" // U+e14b +#define ICON_MD_BLOCK_FLIPPED "\xee\xbd\x86" // U+ef46 +#define ICON_MD_BLOODTYPE "\xee\xbf\xa4" // U+efe4 +#define ICON_MD_BLUETOOTH "\xee\x86\xa7" // U+e1a7 +#define ICON_MD_BLUETOOTH_AUDIO "\xee\x98\x8f" // U+e60f +#define ICON_MD_BLUETOOTH_CONNECTED "\xee\x86\xa8" // U+e1a8 +#define ICON_MD_BLUETOOTH_DISABLED "\xee\x86\xa9" // U+e1a9 +#define ICON_MD_BLUETOOTH_DRIVE "\xee\xbf\xa5" // U+efe5 +#define ICON_MD_BLUETOOTH_SEARCHING "\xee\x86\xaa" // U+e1aa +#define ICON_MD_BLUR_CIRCULAR "\xee\x8e\xa2" // U+e3a2 +#define ICON_MD_BLUR_LINEAR "\xee\x8e\xa3" // U+e3a3 +#define ICON_MD_BLUR_OFF "\xee\x8e\xa4" // U+e3a4 +#define ICON_MD_BLUR_ON "\xee\x8e\xa5" // U+e3a5 +#define ICON_MD_BOLT "\xee\xa8\x8b" // U+ea0b +#define ICON_MD_BOOK "\xee\xa1\xa5" // U+e865 +#define ICON_MD_BOOK_ONLINE "\xef\x88\x97" // U+f217 +#define ICON_MD_BOOKMARK "\xee\xa1\xa6" // U+e866 +#define ICON_MD_BOOKMARK_ADD "\xee\x96\x98" // U+e598 +#define ICON_MD_BOOKMARK_ADDED "\xee\x96\x99" // U+e599 +#define ICON_MD_BOOKMARK_BORDER "\xee\xa1\xa7" // U+e867 +#define ICON_MD_BOOKMARK_OUTLINE "\xee\xa1\xa7" // U+e867 +#define ICON_MD_BOOKMARK_REMOVE "\xee\x96\x9a" // U+e59a +#define ICON_MD_BOOKMARKS "\xee\xa6\x8b" // U+e98b +#define ICON_MD_BORDER_ALL "\xee\x88\xa8" // U+e228 +#define ICON_MD_BORDER_BOTTOM "\xee\x88\xa9" // U+e229 +#define ICON_MD_BORDER_CLEAR "\xee\x88\xaa" // U+e22a +#define ICON_MD_BORDER_COLOR "\xee\x88\xab" // U+e22b +#define ICON_MD_BORDER_HORIZONTAL "\xee\x88\xac" // U+e22c +#define ICON_MD_BORDER_INNER "\xee\x88\xad" // U+e22d +#define ICON_MD_BORDER_LEFT "\xee\x88\xae" // U+e22e +#define ICON_MD_BORDER_OUTER "\xee\x88\xaf" // U+e22f +#define ICON_MD_BORDER_RIGHT "\xee\x88\xb0" // U+e230 +#define ICON_MD_BORDER_STYLE "\xee\x88\xb1" // U+e231 +#define ICON_MD_BORDER_TOP "\xee\x88\xb2" // U+e232 +#define ICON_MD_BORDER_VERTICAL "\xee\x88\xb3" // U+e233 +#define ICON_MD_BOY "\xee\xad\xa7" // U+eb67 +#define ICON_MD_BRANDING_WATERMARK "\xee\x81\xab" // U+e06b +#define ICON_MD_BREAKFAST_DINING "\xee\xa9\x94" // U+ea54 +#define ICON_MD_BRIGHTNESS_1 "\xee\x8e\xa6" // U+e3a6 +#define ICON_MD_BRIGHTNESS_2 "\xee\x8e\xa7" // U+e3a7 +#define ICON_MD_BRIGHTNESS_3 "\xee\x8e\xa8" // U+e3a8 +#define ICON_MD_BRIGHTNESS_4 "\xee\x8e\xa9" // U+e3a9 +#define ICON_MD_BRIGHTNESS_5 "\xee\x8e\xaa" // U+e3aa +#define ICON_MD_BRIGHTNESS_6 "\xee\x8e\xab" // U+e3ab +#define ICON_MD_BRIGHTNESS_7 "\xee\x8e\xac" // U+e3ac +#define ICON_MD_BRIGHTNESS_AUTO "\xee\x86\xab" // U+e1ab +#define ICON_MD_BRIGHTNESS_HIGH "\xee\x86\xac" // U+e1ac +#define ICON_MD_BRIGHTNESS_LOW "\xee\x86\xad" // U+e1ad +#define ICON_MD_BRIGHTNESS_MEDIUM "\xee\x86\xae" // U+e1ae +#define ICON_MD_BROADCAST_ON_HOME "\xef\xa3\xb8" // U+f8f8 +#define ICON_MD_BROADCAST_ON_PERSONAL "\xef\xa3\xb9" // U+f8f9 +#define ICON_MD_BROKEN_IMAGE "\xee\x8e\xad" // U+e3ad +#define ICON_MD_BROWSE_GALLERY "\xee\xaf\x91" // U+ebd1 +#define ICON_MD_BROWSER_NOT_SUPPORTED "\xee\xbd\x87" // U+ef47 +#define ICON_MD_BROWSER_UPDATED "\xee\x9f\x8f" // U+e7cf +#define ICON_MD_BRUNCH_DINING "\xee\xa9\xb3" // U+ea73 +#define ICON_MD_BRUSH "\xee\x8e\xae" // U+e3ae +#define ICON_MD_BUBBLE_CHART "\xee\x9b\x9d" // U+e6dd +#define ICON_MD_BUG_REPORT "\xee\xa1\xa8" // U+e868 +#define ICON_MD_BUILD "\xee\xa1\xa9" // U+e869 +#define ICON_MD_BUILD_CIRCLE "\xee\xbd\x88" // U+ef48 +#define ICON_MD_BUNGALOW "\xee\x96\x91" // U+e591 +#define ICON_MD_BURST_MODE "\xee\x90\xbc" // U+e43c +#define ICON_MD_BUS_ALERT "\xee\xa6\x8f" // U+e98f +#define ICON_MD_BUSINESS "\xee\x82\xaf" // U+e0af +#define ICON_MD_BUSINESS_CENTER "\xee\xac\xbf" // U+eb3f +#define ICON_MD_CABIN "\xee\x96\x89" // U+e589 +#define ICON_MD_CABLE "\xee\xbf\xa6" // U+efe6 +#define ICON_MD_CACHED "\xee\xa1\xaa" // U+e86a +#define ICON_MD_CAKE "\xee\x9f\xa9" // U+e7e9 +#define ICON_MD_CALCULATE "\xee\xa9\x9f" // U+ea5f +#define ICON_MD_CALENDAR_MONTH "\xee\xaf\x8c" // U+ebcc +#define ICON_MD_CALENDAR_TODAY "\xee\xa4\xb5" // U+e935 +#define ICON_MD_CALENDAR_VIEW_DAY "\xee\xa4\xb6" // U+e936 +#define ICON_MD_CALENDAR_VIEW_MONTH "\xee\xbf\xa7" // U+efe7 +#define ICON_MD_CALENDAR_VIEW_WEEK "\xee\xbf\xa8" // U+efe8 +#define ICON_MD_CALL "\xee\x82\xb0" // U+e0b0 +#define ICON_MD_CALL_END "\xee\x82\xb1" // U+e0b1 +#define ICON_MD_CALL_MADE "\xee\x82\xb2" // U+e0b2 +#define ICON_MD_CALL_MERGE "\xee\x82\xb3" // U+e0b3 +#define ICON_MD_CALL_MISSED "\xee\x82\xb4" // U+e0b4 +#define ICON_MD_CALL_MISSED_OUTGOING "\xee\x83\xa4" // U+e0e4 +#define ICON_MD_CALL_RECEIVED "\xee\x82\xb5" // U+e0b5 +#define ICON_MD_CALL_SPLIT "\xee\x82\xb6" // U+e0b6 +#define ICON_MD_CALL_TO_ACTION "\xee\x81\xac" // U+e06c +#define ICON_MD_CAMERA "\xee\x8e\xaf" // U+e3af +#define ICON_MD_CAMERA_ALT "\xee\x8e\xb0" // U+e3b0 +#define ICON_MD_CAMERA_ENHANCE "\xee\xa3\xbc" // U+e8fc +#define ICON_MD_CAMERA_FRONT "\xee\x8e\xb1" // U+e3b1 +#define ICON_MD_CAMERA_INDOOR "\xee\xbf\xa9" // U+efe9 +#define ICON_MD_CAMERA_OUTDOOR "\xee\xbf\xaa" // U+efea +#define ICON_MD_CAMERA_REAR "\xee\x8e\xb2" // U+e3b2 +#define ICON_MD_CAMERA_ROLL "\xee\x8e\xb3" // U+e3b3 +#define ICON_MD_CAMERASWITCH "\xee\xbf\xab" // U+efeb +#define ICON_MD_CAMPAIGN "\xee\xbd\x89" // U+ef49 +#define ICON_MD_CANCEL "\xee\x97\x89" // U+e5c9 +#define ICON_MD_CANCEL_PRESENTATION "\xee\x83\xa9" // U+e0e9 +#define ICON_MD_CANCEL_SCHEDULE_SEND "\xee\xa8\xb9" // U+ea39 +#define ICON_MD_CANDLESTICK_CHART "\xee\xab\x94" // U+ead4 +#define ICON_MD_CAR_CRASH "\xee\xaf\xb2" // U+ebf2 +#define ICON_MD_CAR_RENTAL "\xee\xa9\x95" // U+ea55 +#define ICON_MD_CAR_REPAIR "\xee\xa9\x96" // U+ea56 +#define ICON_MD_CARD_GIFTCARD "\xee\xa3\xb6" // U+e8f6 +#define ICON_MD_CARD_MEMBERSHIP "\xee\xa3\xb7" // U+e8f7 +#define ICON_MD_CARD_TRAVEL "\xee\xa3\xb8" // U+e8f8 +#define ICON_MD_CARPENTER "\xef\x87\xb8" // U+f1f8 +#define ICON_MD_CASES "\xee\xa6\x92" // U+e992 +#define ICON_MD_CASINO "\xee\xad\x80" // U+eb40 +#define ICON_MD_CAST "\xee\x8c\x87" // U+e307 +#define ICON_MD_CAST_CONNECTED "\xee\x8c\x88" // U+e308 +#define ICON_MD_CAST_FOR_EDUCATION "\xee\xbf\xac" // U+efec +#define ICON_MD_CASTLE "\xee\xaa\xb1" // U+eab1 +#define ICON_MD_CATCHING_POKEMON "\xee\x94\x88" // U+e508 +#define ICON_MD_CATEGORY "\xee\x95\xb4" // U+e574 +#define ICON_MD_CELEBRATION "\xee\xa9\xa5" // U+ea65 +#define ICON_MD_CELL_TOWER "\xee\xae\xba" // U+ebba +#define ICON_MD_CELL_WIFI "\xee\x83\xac" // U+e0ec +#define ICON_MD_CENTER_FOCUS_STRONG "\xee\x8e\xb4" // U+e3b4 +#define ICON_MD_CENTER_FOCUS_WEAK "\xee\x8e\xb5" // U+e3b5 +#define ICON_MD_CHAIR "\xee\xbf\xad" // U+efed +#define ICON_MD_CHAIR_ALT "\xee\xbf\xae" // U+efee +#define ICON_MD_CHALET "\xee\x96\x85" // U+e585 +#define ICON_MD_CHANGE_CIRCLE "\xee\x8b\xa7" // U+e2e7 +#define ICON_MD_CHANGE_HISTORY "\xee\xa1\xab" // U+e86b +#define ICON_MD_CHARGING_STATION "\xef\x86\x9d" // U+f19d +#define ICON_MD_CHAT "\xee\x82\xb7" // U+e0b7 +#define ICON_MD_CHAT_BUBBLE "\xee\x83\x8a" // U+e0ca +#define ICON_MD_CHAT_BUBBLE_OUTLINE "\xee\x83\x8b" // U+e0cb +#define ICON_MD_CHECK "\xee\x97\x8a" // U+e5ca +#define ICON_MD_CHECK_BOX "\xee\xa0\xb4" // U+e834 +#define ICON_MD_CHECK_BOX_OUTLINE_BLANK "\xee\xa0\xb5" // U+e835 +#define ICON_MD_CHECK_CIRCLE "\xee\xa1\xac" // U+e86c +#define ICON_MD_CHECK_CIRCLE_OUTLINE "\xee\xa4\xad" // U+e92d +#define ICON_MD_CHECKLIST "\xee\x9a\xb1" // U+e6b1 +#define ICON_MD_CHECKLIST_RTL "\xee\x9a\xb3" // U+e6b3 +#define ICON_MD_CHECKROOM "\xef\x86\x9e" // U+f19e +#define ICON_MD_CHEVRON_LEFT "\xee\x97\x8b" // U+e5cb +#define ICON_MD_CHEVRON_RIGHT "\xee\x97\x8c" // U+e5cc +#define ICON_MD_CHILD_CARE "\xee\xad\x81" // U+eb41 +#define ICON_MD_CHILD_FRIENDLY "\xee\xad\x82" // U+eb42 +#define ICON_MD_CHROME_READER_MODE "\xee\xa1\xad" // U+e86d +#define ICON_MD_CHURCH "\xee\xaa\xae" // U+eaae +#define ICON_MD_CIRCLE "\xee\xbd\x8a" // U+ef4a +#define ICON_MD_CIRCLE_NOTIFICATIONS "\xee\xa6\x94" // U+e994 +#define ICON_MD_CLASS "\xee\xa1\xae" // U+e86e +#define ICON_MD_CLEAN_HANDS "\xef\x88\x9f" // U+f21f +#define ICON_MD_CLEANING_SERVICES "\xef\x83\xbf" // U+f0ff +#define ICON_MD_CLEAR "\xee\x85\x8c" // U+e14c +#define ICON_MD_CLEAR_ALL "\xee\x82\xb8" // U+e0b8 +#define ICON_MD_CLOSE "\xee\x97\x8d" // U+e5cd +#define ICON_MD_CLOSE_FULLSCREEN "\xef\x87\x8f" // U+f1cf +#define ICON_MD_CLOSED_CAPTION "\xee\x80\x9c" // U+e01c +#define ICON_MD_CLOSED_CAPTION_DISABLED "\xef\x87\x9c" // U+f1dc +#define ICON_MD_CLOSED_CAPTION_OFF "\xee\xa6\x96" // U+e996 +#define ICON_MD_CLOUD "\xee\x8a\xbd" // U+e2bd +#define ICON_MD_CLOUD_CIRCLE "\xee\x8a\xbe" // U+e2be +#define ICON_MD_CLOUD_DONE "\xee\x8a\xbf" // U+e2bf +#define ICON_MD_CLOUD_DOWNLOAD "\xee\x8b\x80" // U+e2c0 +#define ICON_MD_CLOUD_OFF "\xee\x8b\x81" // U+e2c1 +#define ICON_MD_CLOUD_QUEUE "\xee\x8b\x82" // U+e2c2 +#define ICON_MD_CLOUD_SYNC "\xee\xad\x9a" // U+eb5a +#define ICON_MD_CLOUD_UPLOAD "\xee\x8b\x83" // U+e2c3 +#define ICON_MD_CLOUDY_SNOWING "\xee\xa0\x90" // U+e810 +#define ICON_MD_CO2 "\xee\x9e\xb0" // U+e7b0 +#define ICON_MD_CO_PRESENT "\xee\xab\xb0" // U+eaf0 +#define ICON_MD_CODE "\xee\xa1\xaf" // U+e86f +#define ICON_MD_CODE_OFF "\xee\x93\xb3" // U+e4f3 +#define ICON_MD_COFFEE "\xee\xbf\xaf" // U+efef +#define ICON_MD_COFFEE_MAKER "\xee\xbf\xb0" // U+eff0 +#define ICON_MD_COLLECTIONS "\xee\x8e\xb6" // U+e3b6 +#define ICON_MD_COLLECTIONS_BOOKMARK "\xee\x90\xb1" // U+e431 +#define ICON_MD_COLOR_LENS "\xee\x8e\xb7" // U+e3b7 +#define ICON_MD_COLORIZE "\xee\x8e\xb8" // U+e3b8 +#define ICON_MD_COMMENT "\xee\x82\xb9" // U+e0b9 +#define ICON_MD_COMMENT_BANK "\xee\xa9\x8e" // U+ea4e +#define ICON_MD_COMMENTS_DISABLED "\xee\x9e\xa2" // U+e7a2 +#define ICON_MD_COMMIT "\xee\xab\xb5" // U+eaf5 +#define ICON_MD_COMMUTE "\xee\xa5\x80" // U+e940 +#define ICON_MD_COMPARE "\xee\x8e\xb9" // U+e3b9 +#define ICON_MD_COMPARE_ARROWS "\xee\xa4\x95" // U+e915 +#define ICON_MD_COMPASS_CALIBRATION "\xee\x95\xbc" // U+e57c +#define ICON_MD_COMPOST "\xee\x9d\xa1" // U+e761 +#define ICON_MD_COMPRESS "\xee\xa5\x8d" // U+e94d +#define ICON_MD_COMPUTER "\xee\x8c\x8a" // U+e30a +#define ICON_MD_CONFIRMATION_NUM "\xee\x98\xb8" // U+e638 +#define ICON_MD_CONFIRMATION_NUMBER "\xee\x98\xb8" // U+e638 +#define ICON_MD_CONNECT_WITHOUT_CONTACT "\xef\x88\xa3" // U+f223 +#define ICON_MD_CONNECTED_TV "\xee\xa6\x98" // U+e998 +#define ICON_MD_CONNECTING_AIRPORTS "\xee\x9f\x89" // U+e7c9 +#define ICON_MD_CONSTRUCTION "\xee\xa8\xbc" // U+ea3c +#define ICON_MD_CONTACT_MAIL "\xee\x83\x90" // U+e0d0 +#define ICON_MD_CONTACT_PAGE "\xef\x88\xae" // U+f22e +#define ICON_MD_CONTACT_PHONE "\xee\x83\x8f" // U+e0cf +#define ICON_MD_CONTACT_SUPPORT "\xee\xa5\x8c" // U+e94c +#define ICON_MD_CONTACTLESS "\xee\xa9\xb1" // U+ea71 +#define ICON_MD_CONTACTS "\xee\x82\xba" // U+e0ba +#define ICON_MD_CONTENT_COPY "\xee\x85\x8d" // U+e14d +#define ICON_MD_CONTENT_CUT "\xee\x85\x8e" // U+e14e +#define ICON_MD_CONTENT_PASTE "\xee\x85\x8f" // U+e14f +#define ICON_MD_CONTENT_PASTE_GO "\xee\xaa\x8e" // U+ea8e +#define ICON_MD_CONTENT_PASTE_OFF "\xee\x93\xb8" // U+e4f8 +#define ICON_MD_CONTENT_PASTE_SEARCH "\xee\xaa\x9b" // U+ea9b +#define ICON_MD_CONTRAST "\xee\xac\xb7" // U+eb37 +#define ICON_MD_CONTROL_CAMERA "\xee\x81\xb4" // U+e074 +#define ICON_MD_CONTROL_POINT "\xee\x8e\xba" // U+e3ba +#define ICON_MD_CONTROL_POINT_DUPLICATE "\xee\x8e\xbb" // U+e3bb +#define ICON_MD_COOKIE "\xee\xaa\xac" // U+eaac +#define ICON_MD_COPY_ALL "\xee\x8b\xac" // U+e2ec +#define ICON_MD_COPYRIGHT "\xee\xa4\x8c" // U+e90c +#define ICON_MD_CORONAVIRUS "\xef\x88\xa1" // U+f221 +#define ICON_MD_CORPORATE_FARE "\xef\x87\x90" // U+f1d0 +#define ICON_MD_COTTAGE "\xee\x96\x87" // U+e587 +#define ICON_MD_COUNTERTOPS "\xef\x87\xb7" // U+f1f7 +#define ICON_MD_CREATE "\xee\x85\x90" // U+e150 +#define ICON_MD_CREATE_NEW_FOLDER "\xee\x8b\x8c" // U+e2cc +#define ICON_MD_CREDIT_CARD "\xee\xa1\xb0" // U+e870 +#define ICON_MD_CREDIT_CARD_OFF "\xee\x93\xb4" // U+e4f4 +#define ICON_MD_CREDIT_SCORE "\xee\xbf\xb1" // U+eff1 +#define ICON_MD_CRIB "\xee\x96\x88" // U+e588 +#define ICON_MD_CRISIS_ALERT "\xee\xaf\xa9" // U+ebe9 +#define ICON_MD_CROP "\xee\x8e\xbe" // U+e3be +#define ICON_MD_CROP_16_9 "\xee\x8e\xbc" // U+e3bc +#define ICON_MD_CROP_3_2 "\xee\x8e\xbd" // U+e3bd +#define ICON_MD_CROP_5_4 "\xee\x8e\xbf" // U+e3bf +#define ICON_MD_CROP_7_5 "\xee\x8f\x80" // U+e3c0 +#define ICON_MD_CROP_DIN "\xee\x8f\x81" // U+e3c1 +#define ICON_MD_CROP_FREE "\xee\x8f\x82" // U+e3c2 +#define ICON_MD_CROP_LANDSCAPE "\xee\x8f\x83" // U+e3c3 +#define ICON_MD_CROP_ORIGINAL "\xee\x8f\x84" // U+e3c4 +#define ICON_MD_CROP_PORTRAIT "\xee\x8f\x85" // U+e3c5 +#define ICON_MD_CROP_ROTATE "\xee\x90\xb7" // U+e437 +#define ICON_MD_CROP_SQUARE "\xee\x8f\x86" // U+e3c6 +#define ICON_MD_CRUELTY_FREE "\xee\x9e\x99" // U+e799 +#define ICON_MD_CSS "\xee\xae\x93" // U+eb93 +#define ICON_MD_CURRENCY_BITCOIN "\xee\xaf\x85" // U+ebc5 +#define ICON_MD_CURRENCY_EXCHANGE "\xee\xad\xb0" // U+eb70 +#define ICON_MD_CURRENCY_FRANC "\xee\xab\xba" // U+eafa +#define ICON_MD_CURRENCY_LIRA "\xee\xab\xaf" // U+eaef +#define ICON_MD_CURRENCY_POUND "\xee\xab\xb1" // U+eaf1 +#define ICON_MD_CURRENCY_RUBLE "\xee\xab\xac" // U+eaec +#define ICON_MD_CURRENCY_RUPEE "\xee\xab\xb7" // U+eaf7 +#define ICON_MD_CURRENCY_YEN "\xee\xab\xbb" // U+eafb +#define ICON_MD_CURRENCY_YUAN "\xee\xab\xb9" // U+eaf9 +#define ICON_MD_CURTAINS "\xee\xb0\x9e" // U+ec1e +#define ICON_MD_CURTAINS_CLOSED "\xee\xb0\x9d" // U+ec1d +#define ICON_MD_CYCLONE "\xee\xaf\x95" // U+ebd5 +#define ICON_MD_DANGEROUS "\xee\xa6\x9a" // U+e99a +#define ICON_MD_DARK_MODE "\xee\x94\x9c" // U+e51c +#define ICON_MD_DASHBOARD "\xee\xa1\xb1" // U+e871 +#define ICON_MD_DASHBOARD_CUSTOMIZE "\xee\xa6\x9b" // U+e99b +#define ICON_MD_DATA_ARRAY "\xee\xab\x91" // U+ead1 +#define ICON_MD_DATA_EXPLORATION "\xee\x9d\xaf" // U+e76f +#define ICON_MD_DATA_OBJECT "\xee\xab\x93" // U+ead3 +#define ICON_MD_DATA_SAVER_OFF "\xee\xbf\xb2" // U+eff2 +#define ICON_MD_DATA_SAVER_ON "\xee\xbf\xb3" // U+eff3 +#define ICON_MD_DATA_THRESHOLDING "\xee\xae\x9f" // U+eb9f +#define ICON_MD_DATA_USAGE "\xee\x86\xaf" // U+e1af +#define ICON_MD_DATE_RANGE "\xee\xa4\x96" // U+e916 +#define ICON_MD_DEBLUR "\xee\xad\xb7" // U+eb77 +#define ICON_MD_DECK "\xee\xa9\x82" // U+ea42 +#define ICON_MD_DEHAZE "\xee\x8f\x87" // U+e3c7 +#define ICON_MD_DELETE "\xee\xa1\xb2" // U+e872 +#define ICON_MD_DELETE_FOREVER "\xee\xa4\xab" // U+e92b +#define ICON_MD_DELETE_OUTLINE "\xee\xa4\xae" // U+e92e +#define ICON_MD_DELETE_SWEEP "\xee\x85\xac" // U+e16c +#define ICON_MD_DELIVERY_DINING "\xee\xa9\xb2" // U+ea72 +#define ICON_MD_DENSITY_LARGE "\xee\xae\xa9" // U+eba9 +#define ICON_MD_DENSITY_MEDIUM "\xee\xae\x9e" // U+eb9e +#define ICON_MD_DENSITY_SMALL "\xee\xae\xa8" // U+eba8 +#define ICON_MD_DEPARTURE_BOARD "\xee\x95\xb6" // U+e576 +#define ICON_MD_DESCRIPTION "\xee\xa1\xb3" // U+e873 +#define ICON_MD_DESELECT "\xee\xae\xb6" // U+ebb6 +#define ICON_MD_DESIGN_SERVICES "\xef\x84\x8a" // U+f10a +#define ICON_MD_DESK "\xef\xa3\xb4" // U+f8f4 +#define ICON_MD_DESKTOP_ACCESS_DISABLED "\xee\xa6\x9d" // U+e99d +#define ICON_MD_DESKTOP_MAC "\xee\x8c\x8b" // U+e30b +#define ICON_MD_DESKTOP_WINDOWS "\xee\x8c\x8c" // U+e30c +#define ICON_MD_DETAILS "\xee\x8f\x88" // U+e3c8 +#define ICON_MD_DEVELOPER_BOARD "\xee\x8c\x8d" // U+e30d +#define ICON_MD_DEVELOPER_BOARD_OFF "\xee\x93\xbf" // U+e4ff +#define ICON_MD_DEVELOPER_MODE "\xee\x86\xb0" // U+e1b0 +#define ICON_MD_DEVICE_HUB "\xee\x8c\xb5" // U+e335 +#define ICON_MD_DEVICE_THERMOSTAT "\xee\x87\xbf" // U+e1ff +#define ICON_MD_DEVICE_UNKNOWN "\xee\x8c\xb9" // U+e339 +#define ICON_MD_DEVICES "\xee\x86\xb1" // U+e1b1 +#define ICON_MD_DEVICES_FOLD "\xee\xaf\x9e" // U+ebde +#define ICON_MD_DEVICES_OTHER "\xee\x8c\xb7" // U+e337 +#define ICON_MD_DIALER_SIP "\xee\x82\xbb" // U+e0bb +#define ICON_MD_DIALPAD "\xee\x82\xbc" // U+e0bc +#define ICON_MD_DIAMOND "\xee\xab\x95" // U+ead5 +#define ICON_MD_DIFFERENCE "\xee\xad\xbd" // U+eb7d +#define ICON_MD_DINING "\xee\xbf\xb4" // U+eff4 +#define ICON_MD_DINNER_DINING "\xee\xa9\x97" // U+ea57 +#define ICON_MD_DIRECTIONS "\xee\x94\xae" // U+e52e +#define ICON_MD_DIRECTIONS_BIKE "\xee\x94\xaf" // U+e52f +#define ICON_MD_DIRECTIONS_BOAT "\xee\x94\xb2" // U+e532 +#define ICON_MD_DIRECTIONS_BOAT_FILLED "\xee\xbf\xb5" // U+eff5 +#define ICON_MD_DIRECTIONS_BUS "\xee\x94\xb0" // U+e530 +#define ICON_MD_DIRECTIONS_BUS_FILLED "\xee\xbf\xb6" // U+eff6 +#define ICON_MD_DIRECTIONS_CAR "\xee\x94\xb1" // U+e531 +#define ICON_MD_DIRECTIONS_CAR_FILLED "\xee\xbf\xb7" // U+eff7 +#define ICON_MD_DIRECTIONS_FERRY "\xee\x94\xb2" // U+e532 +#define ICON_MD_DIRECTIONS_OFF "\xef\x84\x8f" // U+f10f +#define ICON_MD_DIRECTIONS_RAILWAY "\xee\x94\xb4" // U+e534 +#define ICON_MD_DIRECTIONS_RAILWAY_FILLED "\xee\xbf\xb8" // U+eff8 +#define ICON_MD_DIRECTIONS_RUN "\xee\x95\xa6" // U+e566 +#define ICON_MD_DIRECTIONS_SUBWAY "\xee\x94\xb3" // U+e533 +#define ICON_MD_DIRECTIONS_SUBWAY_FILLED "\xee\xbf\xb9" // U+eff9 +#define ICON_MD_DIRECTIONS_TRAIN "\xee\x94\xb4" // U+e534 +#define ICON_MD_DIRECTIONS_TRANSIT "\xee\x94\xb5" // U+e535 +#define ICON_MD_DIRECTIONS_TRANSIT_FILLED "\xee\xbf\xba" // U+effa +#define ICON_MD_DIRECTIONS_WALK "\xee\x94\xb6" // U+e536 +#define ICON_MD_DIRTY_LENS "\xee\xbd\x8b" // U+ef4b +#define ICON_MD_DISABLED_BY_DEFAULT "\xef\x88\xb0" // U+f230 +#define ICON_MD_DISABLED_VISIBLE "\xee\x9d\xae" // U+e76e +#define ICON_MD_DISC_FULL "\xee\x98\x90" // U+e610 +#define ICON_MD_DISCORD "\xee\xa9\xac" // U+ea6c +#define ICON_MD_DISCOUNT "\xee\xaf\x89" // U+ebc9 +#define ICON_MD_DISPLAY_SETTINGS "\xee\xae\x97" // U+eb97 +#define ICON_MD_DND_FORWARDSLASH "\xee\x98\x91" // U+e611 +#define ICON_MD_DNS "\xee\xa1\xb5" // U+e875 +#define ICON_MD_DO_DISTURB "\xef\x82\x8c" // U+f08c +#define ICON_MD_DO_DISTURB_ALT "\xef\x82\x8d" // U+f08d +#define ICON_MD_DO_DISTURB_OFF "\xef\x82\x8e" // U+f08e +#define ICON_MD_DO_DISTURB_ON "\xef\x82\x8f" // U+f08f +#define ICON_MD_DO_NOT_DISTURB "\xee\x98\x92" // U+e612 +#define ICON_MD_DO_NOT_DISTURB_ALT "\xee\x98\x91" // U+e611 +#define ICON_MD_DO_NOT_DISTURB_OFF "\xee\x99\x83" // U+e643 +#define ICON_MD_DO_NOT_DISTURB_ON "\xee\x99\x84" // U+e644 +#define ICON_MD_DO_NOT_DISTURB_ON_TOTAL_SILENCE "\xee\xbf\xbb" // U+effb +#define ICON_MD_DO_NOT_STEP "\xef\x86\x9f" // U+f19f +#define ICON_MD_DO_NOT_TOUCH "\xef\x86\xb0" // U+f1b0 +#define ICON_MD_DOCK "\xee\x8c\x8e" // U+e30e +#define ICON_MD_DOCUMENT_SCANNER "\xee\x97\xba" // U+e5fa +#define ICON_MD_DOMAIN "\xee\x9f\xae" // U+e7ee +#define ICON_MD_DOMAIN_ADD "\xee\xad\xa2" // U+eb62 +#define ICON_MD_DOMAIN_DISABLED "\xee\x83\xaf" // U+e0ef +#define ICON_MD_DOMAIN_VERIFICATION "\xee\xbd\x8c" // U+ef4c +#define ICON_MD_DONE "\xee\xa1\xb6" // U+e876 +#define ICON_MD_DONE_ALL "\xee\xa1\xb7" // U+e877 +#define ICON_MD_DONE_OUTLINE "\xee\xa4\xaf" // U+e92f +#define ICON_MD_DONUT_LARGE "\xee\xa4\x97" // U+e917 +#define ICON_MD_DONUT_SMALL "\xee\xa4\x98" // U+e918 +#define ICON_MD_DOOR_BACK "\xee\xbf\xbc" // U+effc +#define ICON_MD_DOOR_FRONT "\xee\xbf\xbd" // U+effd +#define ICON_MD_DOOR_SLIDING "\xee\xbf\xbe" // U+effe +#define ICON_MD_DOORBELL "\xee\xbf\xbf" // U+efff +#define ICON_MD_DOUBLE_ARROW "\xee\xa9\x90" // U+ea50 +#define ICON_MD_DOWNHILL_SKIING "\xee\x94\x89" // U+e509 +#define ICON_MD_DOWNLOAD "\xef\x82\x90" // U+f090 +#define ICON_MD_DOWNLOAD_DONE "\xef\x82\x91" // U+f091 +#define ICON_MD_DOWNLOAD_FOR_OFFLINE "\xef\x80\x80" // U+f000 +#define ICON_MD_DOWNLOADING "\xef\x80\x81" // U+f001 +#define ICON_MD_DRAFTS "\xee\x85\x91" // U+e151 +#define ICON_MD_DRAG_HANDLE "\xee\x89\x9d" // U+e25d +#define ICON_MD_DRAG_INDICATOR "\xee\xa5\x85" // U+e945 +#define ICON_MD_DRAW "\xee\x9d\x86" // U+e746 +#define ICON_MD_DRIVE_ETA "\xee\x98\x93" // U+e613 +#define ICON_MD_DRIVE_FILE_MOVE "\xee\x99\xb5" // U+e675 +#define ICON_MD_DRIVE_FILE_MOVE_OUTLINE "\xee\xa6\xa1" // U+e9a1 +#define ICON_MD_DRIVE_FILE_MOVE_RTL "\xee\x9d\xad" // U+e76d +#define ICON_MD_DRIVE_FILE_RENAME_OUTLINE "\xee\xa6\xa2" // U+e9a2 +#define ICON_MD_DRIVE_FOLDER_UPLOAD "\xee\xa6\xa3" // U+e9a3 +#define ICON_MD_DRY "\xef\x86\xb3" // U+f1b3 +#define ICON_MD_DRY_CLEANING "\xee\xa9\x98" // U+ea58 +#define ICON_MD_DUO "\xee\xa6\xa5" // U+e9a5 +#define ICON_MD_DVR "\xee\x86\xb2" // U+e1b2 +#define ICON_MD_DYNAMIC_FEED "\xee\xa8\x94" // U+ea14 +#define ICON_MD_DYNAMIC_FORM "\xef\x86\xbf" // U+f1bf +#define ICON_MD_E_MOBILEDATA "\xef\x80\x82" // U+f002 +#define ICON_MD_EARBUDS "\xef\x80\x83" // U+f003 +#define ICON_MD_EARBUDS_BATTERY "\xef\x80\x84" // U+f004 +#define ICON_MD_EAST "\xef\x87\x9f" // U+f1df +#define ICON_MD_ECO "\xee\xa8\xb5" // U+ea35 +#define ICON_MD_EDGESENSOR_HIGH "\xef\x80\x85" // U+f005 +#define ICON_MD_EDGESENSOR_LOW "\xef\x80\x86" // U+f006 +#define ICON_MD_EDIT "\xee\x8f\x89" // U+e3c9 +#define ICON_MD_EDIT_ATTRIBUTES "\xee\x95\xb8" // U+e578 +#define ICON_MD_EDIT_CALENDAR "\xee\x9d\x82" // U+e742 +#define ICON_MD_EDIT_LOCATION "\xee\x95\xa8" // U+e568 +#define ICON_MD_EDIT_LOCATION_ALT "\xee\x87\x85" // U+e1c5 +#define ICON_MD_EDIT_NOTE "\xee\x9d\x85" // U+e745 +#define ICON_MD_EDIT_NOTIFICATIONS "\xee\x94\xa5" // U+e525 +#define ICON_MD_EDIT_OFF "\xee\xa5\x90" // U+e950 +#define ICON_MD_EDIT_ROAD "\xee\xbd\x8d" // U+ef4d +#define ICON_MD_EGG "\xee\xab\x8c" // U+eacc +#define ICON_MD_EGG_ALT "\xee\xab\x88" // U+eac8 +#define ICON_MD_EJECT "\xee\xa3\xbb" // U+e8fb +#define ICON_MD_ELDERLY "\xef\x88\x9a" // U+f21a +#define ICON_MD_ELDERLY_WOMAN "\xee\xad\xa9" // U+eb69 +#define ICON_MD_ELECTRIC_BIKE "\xee\xac\x9b" // U+eb1b +#define ICON_MD_ELECTRIC_BOLT "\xee\xb0\x9c" // U+ec1c +#define ICON_MD_ELECTRIC_CAR "\xee\xac\x9c" // U+eb1c +#define ICON_MD_ELECTRIC_METER "\xee\xb0\x9b" // U+ec1b +#define ICON_MD_ELECTRIC_MOPED "\xee\xac\x9d" // U+eb1d +#define ICON_MD_ELECTRIC_RICKSHAW "\xee\xac\x9e" // U+eb1e +#define ICON_MD_ELECTRIC_SCOOTER "\xee\xac\x9f" // U+eb1f +#define ICON_MD_ELECTRICAL_SERVICES "\xef\x84\x82" // U+f102 +#define ICON_MD_ELEVATOR "\xef\x86\xa0" // U+f1a0 +#define ICON_MD_EMAIL "\xee\x82\xbe" // U+e0be +#define ICON_MD_EMERGENCY "\xee\x87\xab" // U+e1eb +#define ICON_MD_EMERGENCY_RECORDING "\xee\xaf\xb4" // U+ebf4 +#define ICON_MD_EMERGENCY_SHARE "\xee\xaf\xb6" // U+ebf6 +#define ICON_MD_EMOJI_EMOTIONS "\xee\xa8\xa2" // U+ea22 +#define ICON_MD_EMOJI_EVENTS "\xee\xa8\xa3" // U+ea23 +#define ICON_MD_EMOJI_FLAGS "\xee\xa8\x9a" // U+ea1a +#define ICON_MD_EMOJI_FOOD_BEVERAGE "\xee\xa8\x9b" // U+ea1b +#define ICON_MD_EMOJI_NATURE "\xee\xa8\x9c" // U+ea1c +#define ICON_MD_EMOJI_OBJECTS "\xee\xa8\xa4" // U+ea24 +#define ICON_MD_EMOJI_PEOPLE "\xee\xa8\x9d" // U+ea1d +#define ICON_MD_EMOJI_SYMBOLS "\xee\xa8\x9e" // U+ea1e +#define ICON_MD_EMOJI_TRANSPORTATION "\xee\xa8\x9f" // U+ea1f +#define ICON_MD_ENERGY_SAVINGS_LEAF "\xee\xb0\x9a" // U+ec1a +#define ICON_MD_ENGINEERING "\xee\xa8\xbd" // U+ea3d +#define ICON_MD_ENHANCE_PHOTO_TRANSLATE "\xee\xa3\xbc" // U+e8fc +#define ICON_MD_ENHANCED_ENCRYPTION "\xee\x98\xbf" // U+e63f +#define ICON_MD_EQUALIZER "\xee\x80\x9d" // U+e01d +#define ICON_MD_ERROR "\xee\x80\x80" // U+e000 +#define ICON_MD_ERROR_OUTLINE "\xee\x80\x81" // U+e001 +#define ICON_MD_ESCALATOR "\xef\x86\xa1" // U+f1a1 +#define ICON_MD_ESCALATOR_WARNING "\xef\x86\xac" // U+f1ac +#define ICON_MD_EURO "\xee\xa8\x95" // U+ea15 +#define ICON_MD_EURO_SYMBOL "\xee\xa4\xa6" // U+e926 +#define ICON_MD_EV_STATION "\xee\x95\xad" // U+e56d +#define ICON_MD_EVENT "\xee\xa1\xb8" // U+e878 +#define ICON_MD_EVENT_AVAILABLE "\xee\x98\x94" // U+e614 +#define ICON_MD_EVENT_BUSY "\xee\x98\x95" // U+e615 +#define ICON_MD_EVENT_NOTE "\xee\x98\x96" // U+e616 +#define ICON_MD_EVENT_REPEAT "\xee\xad\xbb" // U+eb7b +#define ICON_MD_EVENT_SEAT "\xee\xa4\x83" // U+e903 +#define ICON_MD_EXIT_TO_APP "\xee\xa1\xb9" // U+e879 +#define ICON_MD_EXPAND "\xee\xa5\x8f" // U+e94f +#define ICON_MD_EXPAND_CIRCLE_DOWN "\xee\x9f\x8d" // U+e7cd +#define ICON_MD_EXPAND_LESS "\xee\x97\x8e" // U+e5ce +#define ICON_MD_EXPAND_MORE "\xee\x97\x8f" // U+e5cf +#define ICON_MD_EXPLICIT "\xee\x80\x9e" // U+e01e +#define ICON_MD_EXPLORE "\xee\xa1\xba" // U+e87a +#define ICON_MD_EXPLORE_OFF "\xee\xa6\xa8" // U+e9a8 +#define ICON_MD_EXPOSURE "\xee\x8f\x8a" // U+e3ca +#define ICON_MD_EXPOSURE_MINUS_1 "\xee\x8f\x8b" // U+e3cb +#define ICON_MD_EXPOSURE_MINUS_2 "\xee\x8f\x8c" // U+e3cc +#define ICON_MD_EXPOSURE_NEG_1 "\xee\x8f\x8b" // U+e3cb +#define ICON_MD_EXPOSURE_NEG_2 "\xee\x8f\x8c" // U+e3cc +#define ICON_MD_EXPOSURE_PLUS_1 "\xee\x8f\x8d" // U+e3cd +#define ICON_MD_EXPOSURE_PLUS_2 "\xee\x8f\x8e" // U+e3ce +#define ICON_MD_EXPOSURE_ZERO "\xee\x8f\x8f" // U+e3cf +#define ICON_MD_EXTENSION "\xee\xa1\xbb" // U+e87b +#define ICON_MD_EXTENSION_OFF "\xee\x93\xb5" // U+e4f5 +#define ICON_MD_FACE "\xee\xa1\xbc" // U+e87c +#define ICON_MD_FACE_RETOUCHING_NATURAL "\xee\xbd\x8e" // U+ef4e +#define ICON_MD_FACE_RETOUCHING_OFF "\xef\x80\x87" // U+f007 +#define ICON_MD_FACEBOOK "\xef\x88\xb4" // U+f234 +#define ICON_MD_FACT_CHECK "\xef\x83\x85" // U+f0c5 +#define ICON_MD_FACTORY "\xee\xae\xbc" // U+ebbc +#define ICON_MD_FAMILY_RESTROOM "\xef\x86\xa2" // U+f1a2 +#define ICON_MD_FAST_FORWARD "\xee\x80\x9f" // U+e01f +#define ICON_MD_FAST_REWIND "\xee\x80\xa0" // U+e020 +#define ICON_MD_FASTFOOD "\xee\x95\xba" // U+e57a +#define ICON_MD_FAVORITE "\xee\xa1\xbd" // U+e87d +#define ICON_MD_FAVORITE_BORDER "\xee\xa1\xbe" // U+e87e +#define ICON_MD_FAVORITE_OUTLINE "\xee\xa1\xbe" // U+e87e +#define ICON_MD_FAX "\xee\xab\x98" // U+ead8 +#define ICON_MD_FEATURED_PLAY_LIST "\xee\x81\xad" // U+e06d +#define ICON_MD_FEATURED_VIDEO "\xee\x81\xae" // U+e06e +#define ICON_MD_FEED "\xef\x80\x89" // U+f009 +#define ICON_MD_FEEDBACK "\xee\xa1\xbf" // U+e87f +#define ICON_MD_FEMALE "\xee\x96\x90" // U+e590 +#define ICON_MD_FENCE "\xef\x87\xb6" // U+f1f6 +#define ICON_MD_FESTIVAL "\xee\xa9\xa8" // U+ea68 +#define ICON_MD_FIBER_DVR "\xee\x81\x9d" // U+e05d +#define ICON_MD_FIBER_MANUAL_RECORD "\xee\x81\xa1" // U+e061 +#define ICON_MD_FIBER_NEW "\xee\x81\x9e" // U+e05e +#define ICON_MD_FIBER_PIN "\xee\x81\xaa" // U+e06a +#define ICON_MD_FIBER_SMART_RECORD "\xee\x81\xa2" // U+e062 +#define ICON_MD_FILE_COPY "\xee\x85\xb3" // U+e173 +#define ICON_MD_FILE_DOWNLOAD "\xee\x8b\x84" // U+e2c4 +#define ICON_MD_FILE_DOWNLOAD_DONE "\xee\xa6\xaa" // U+e9aa +#define ICON_MD_FILE_DOWNLOAD_OFF "\xee\x93\xbe" // U+e4fe +#define ICON_MD_FILE_OPEN "\xee\xab\xb3" // U+eaf3 +#define ICON_MD_FILE_PRESENT "\xee\xa8\x8e" // U+ea0e +#define ICON_MD_FILE_UPLOAD "\xee\x8b\x86" // U+e2c6 +#define ICON_MD_FILTER "\xee\x8f\x93" // U+e3d3 +#define ICON_MD_FILTER_1 "\xee\x8f\x90" // U+e3d0 +#define ICON_MD_FILTER_2 "\xee\x8f\x91" // U+e3d1 +#define ICON_MD_FILTER_3 "\xee\x8f\x92" // U+e3d2 +#define ICON_MD_FILTER_4 "\xee\x8f\x94" // U+e3d4 +#define ICON_MD_FILTER_5 "\xee\x8f\x95" // U+e3d5 +#define ICON_MD_FILTER_6 "\xee\x8f\x96" // U+e3d6 +#define ICON_MD_FILTER_7 "\xee\x8f\x97" // U+e3d7 +#define ICON_MD_FILTER_8 "\xee\x8f\x98" // U+e3d8 +#define ICON_MD_FILTER_9 "\xee\x8f\x99" // U+e3d9 +#define ICON_MD_FILTER_9_PLUS "\xee\x8f\x9a" // U+e3da +#define ICON_MD_FILTER_ALT "\xee\xbd\x8f" // U+ef4f +#define ICON_MD_FILTER_ALT_OFF "\xee\xac\xb2" // U+eb32 +#define ICON_MD_FILTER_B_AND_W "\xee\x8f\x9b" // U+e3db +#define ICON_MD_FILTER_CENTER_FOCUS "\xee\x8f\x9c" // U+e3dc +#define ICON_MD_FILTER_DRAMA "\xee\x8f\x9d" // U+e3dd +#define ICON_MD_FILTER_FRAMES "\xee\x8f\x9e" // U+e3de +#define ICON_MD_FILTER_HDR "\xee\x8f\x9f" // U+e3df +#define ICON_MD_FILTER_LIST "\xee\x85\x92" // U+e152 +#define ICON_MD_FILTER_LIST_ALT "\xee\xa5\x8e" // U+e94e +#define ICON_MD_FILTER_LIST_OFF "\xee\xad\x97" // U+eb57 +#define ICON_MD_FILTER_NONE "\xee\x8f\xa0" // U+e3e0 +#define ICON_MD_FILTER_TILT_SHIFT "\xee\x8f\xa2" // U+e3e2 +#define ICON_MD_FILTER_VINTAGE "\xee\x8f\xa3" // U+e3e3 +#define ICON_MD_FIND_IN_PAGE "\xee\xa2\x80" // U+e880 +#define ICON_MD_FIND_REPLACE "\xee\xa2\x81" // U+e881 +#define ICON_MD_FINGERPRINT "\xee\xa4\x8d" // U+e90d +#define ICON_MD_FIRE_EXTINGUISHER "\xef\x87\x98" // U+f1d8 +#define ICON_MD_FIRE_HYDRANT "\xef\x86\xa3" // U+f1a3 +#define ICON_MD_FIREPLACE "\xee\xa9\x83" // U+ea43 +#define ICON_MD_FIRST_PAGE "\xee\x97\x9c" // U+e5dc +#define ICON_MD_FIT_SCREEN "\xee\xa8\x90" // U+ea10 +#define ICON_MD_FITBIT "\xee\xa0\xab" // U+e82b +#define ICON_MD_FITNESS_CENTER "\xee\xad\x83" // U+eb43 +#define ICON_MD_FLAG "\xee\x85\x93" // U+e153 +#define ICON_MD_FLAG_CIRCLE "\xee\xab\xb8" // U+eaf8 +#define ICON_MD_FLAKY "\xee\xbd\x90" // U+ef50 +#define ICON_MD_FLARE "\xee\x8f\xa4" // U+e3e4 +#define ICON_MD_FLASH_AUTO "\xee\x8f\xa5" // U+e3e5 +#define ICON_MD_FLASH_OFF "\xee\x8f\xa6" // U+e3e6 +#define ICON_MD_FLASH_ON "\xee\x8f\xa7" // U+e3e7 +#define ICON_MD_FLASHLIGHT_OFF "\xef\x80\x8a" // U+f00a +#define ICON_MD_FLASHLIGHT_ON "\xef\x80\x8b" // U+f00b +#define ICON_MD_FLATWARE "\xef\x80\x8c" // U+f00c +#define ICON_MD_FLIGHT "\xee\x94\xb9" // U+e539 +#define ICON_MD_FLIGHT_CLASS "\xee\x9f\x8b" // U+e7cb +#define ICON_MD_FLIGHT_LAND "\xee\xa4\x84" // U+e904 +#define ICON_MD_FLIGHT_TAKEOFF "\xee\xa4\x85" // U+e905 +#define ICON_MD_FLIP "\xee\x8f\xa8" // U+e3e8 +#define ICON_MD_FLIP_CAMERA_ANDROID "\xee\xa8\xb7" // U+ea37 +#define ICON_MD_FLIP_CAMERA_IOS "\xee\xa8\xb8" // U+ea38 +#define ICON_MD_FLIP_TO_BACK "\xee\xa2\x82" // U+e882 +#define ICON_MD_FLIP_TO_FRONT "\xee\xa2\x83" // U+e883 +#define ICON_MD_FLOOD "\xee\xaf\xa6" // U+ebe6 +#define ICON_MD_FLOURESCENT "\xef\x80\x8d" // U+f00d +#define ICON_MD_FLUTTER_DASH "\xee\x80\x8b" // U+e00b +#define ICON_MD_FMD_BAD "\xef\x80\x8e" // U+f00e +#define ICON_MD_FMD_GOOD "\xef\x80\x8f" // U+f00f +#define ICON_MD_FOGGY "\xee\xa0\x98" // U+e818 +#define ICON_MD_FOLDER "\xee\x8b\x87" // U+e2c7 +#define ICON_MD_FOLDER_COPY "\xee\xae\xbd" // U+ebbd +#define ICON_MD_FOLDER_DELETE "\xee\xac\xb4" // U+eb34 +#define ICON_MD_FOLDER_OFF "\xee\xae\x83" // U+eb83 +#define ICON_MD_FOLDER_OPEN "\xee\x8b\x88" // U+e2c8 +#define ICON_MD_FOLDER_SHARED "\xee\x8b\x89" // U+e2c9 +#define ICON_MD_FOLDER_SPECIAL "\xee\x98\x97" // U+e617 +#define ICON_MD_FOLDER_ZIP "\xee\xac\xac" // U+eb2c +#define ICON_MD_FOLLOW_THE_SIGNS "\xef\x88\xa2" // U+f222 +#define ICON_MD_FONT_DOWNLOAD "\xee\x85\xa7" // U+e167 +#define ICON_MD_FONT_DOWNLOAD_OFF "\xee\x93\xb9" // U+e4f9 +#define ICON_MD_FOOD_BANK "\xef\x87\xb2" // U+f1f2 +#define ICON_MD_FOREST "\xee\xaa\x99" // U+ea99 +#define ICON_MD_FORK_LEFT "\xee\xae\xa0" // U+eba0 +#define ICON_MD_FORK_RIGHT "\xee\xae\xac" // U+ebac +#define ICON_MD_FORMAT_ALIGN_CENTER "\xee\x88\xb4" // U+e234 +#define ICON_MD_FORMAT_ALIGN_JUSTIFY "\xee\x88\xb5" // U+e235 +#define ICON_MD_FORMAT_ALIGN_LEFT "\xee\x88\xb6" // U+e236 +#define ICON_MD_FORMAT_ALIGN_RIGHT "\xee\x88\xb7" // U+e237 +#define ICON_MD_FORMAT_BOLD "\xee\x88\xb8" // U+e238 +#define ICON_MD_FORMAT_CLEAR "\xee\x88\xb9" // U+e239 +#define ICON_MD_FORMAT_COLOR_FILL "\xee\x88\xba" // U+e23a +#define ICON_MD_FORMAT_COLOR_RESET "\xee\x88\xbb" // U+e23b +#define ICON_MD_FORMAT_COLOR_TEXT "\xee\x88\xbc" // U+e23c +#define ICON_MD_FORMAT_INDENT_DECREASE "\xee\x88\xbd" // U+e23d +#define ICON_MD_FORMAT_INDENT_INCREASE "\xee\x88\xbe" // U+e23e +#define ICON_MD_FORMAT_ITALIC "\xee\x88\xbf" // U+e23f +#define ICON_MD_FORMAT_LINE_SPACING "\xee\x89\x80" // U+e240 +#define ICON_MD_FORMAT_LIST_BULLETED "\xee\x89\x81" // U+e241 +#define ICON_MD_FORMAT_LIST_NUMBERED "\xee\x89\x82" // U+e242 +#define ICON_MD_FORMAT_LIST_NUMBERED_RTL "\xee\x89\xa7" // U+e267 +#define ICON_MD_FORMAT_OVERLINE "\xee\xad\xa5" // U+eb65 +#define ICON_MD_FORMAT_PAINT "\xee\x89\x83" // U+e243 +#define ICON_MD_FORMAT_QUOTE "\xee\x89\x84" // U+e244 +#define ICON_MD_FORMAT_SHAPES "\xee\x89\x9e" // U+e25e +#define ICON_MD_FORMAT_SIZE "\xee\x89\x85" // U+e245 +#define ICON_MD_FORMAT_STRIKETHROUGH "\xee\x89\x86" // U+e246 +#define ICON_MD_FORMAT_TEXTDIRECTION_L_TO_R "\xee\x89\x87" // U+e247 +#define ICON_MD_FORMAT_TEXTDIRECTION_R_TO_L "\xee\x89\x88" // U+e248 +#define ICON_MD_FORMAT_UNDERLINE "\xee\x89\x89" // U+e249 +#define ICON_MD_FORMAT_UNDERLINED "\xee\x89\x89" // U+e249 +#define ICON_MD_FORT "\xee\xaa\xad" // U+eaad +#define ICON_MD_FORUM "\xee\x82\xbf" // U+e0bf +#define ICON_MD_FORWARD "\xee\x85\x94" // U+e154 +#define ICON_MD_FORWARD_10 "\xee\x81\x96" // U+e056 +#define ICON_MD_FORWARD_30 "\xee\x81\x97" // U+e057 +#define ICON_MD_FORWARD_5 "\xee\x81\x98" // U+e058 +#define ICON_MD_FORWARD_TO_INBOX "\xef\x86\x87" // U+f187 +#define ICON_MD_FOUNDATION "\xef\x88\x80" // U+f200 +#define ICON_MD_FREE_BREAKFAST "\xee\xad\x84" // U+eb44 +#define ICON_MD_FREE_CANCELLATION "\xee\x9d\x88" // U+e748 +#define ICON_MD_FRONT_HAND "\xee\x9d\xa9" // U+e769 +#define ICON_MD_FULLSCREEN "\xee\x97\x90" // U+e5d0 +#define ICON_MD_FULLSCREEN_EXIT "\xee\x97\x91" // U+e5d1 +#define ICON_MD_FUNCTIONS "\xee\x89\x8a" // U+e24a +#define ICON_MD_G_MOBILEDATA "\xef\x80\x90" // U+f010 +#define ICON_MD_G_TRANSLATE "\xee\xa4\xa7" // U+e927 +#define ICON_MD_GAMEPAD "\xee\x8c\x8f" // U+e30f +#define ICON_MD_GAMES "\xee\x80\xa1" // U+e021 +#define ICON_MD_GARAGE "\xef\x80\x91" // U+f011 +#define ICON_MD_GAS_METER "\xee\xb0\x99" // U+ec19 +#define ICON_MD_GAVEL "\xee\xa4\x8e" // U+e90e +#define ICON_MD_GENERATING_TOKENS "\xee\x9d\x89" // U+e749 +#define ICON_MD_GESTURE "\xee\x85\x95" // U+e155 +#define ICON_MD_GET_APP "\xee\xa2\x84" // U+e884 +#define ICON_MD_GIF "\xee\xa4\x88" // U+e908 +#define ICON_MD_GIF_BOX "\xee\x9e\xa3" // U+e7a3 +#define ICON_MD_GIRL "\xee\xad\xa8" // U+eb68 +#define ICON_MD_GITE "\xee\x96\x8b" // U+e58b +// #define ICON_MD_GOAT "\xf4\x8f\xbf\xbd" // U+10fffd +#define ICON_MD_GOLF_COURSE "\xee\xad\x85" // U+eb45 +#define ICON_MD_GPP_BAD "\xef\x80\x92" // U+f012 +#define ICON_MD_GPP_GOOD "\xef\x80\x93" // U+f013 +#define ICON_MD_GPP_MAYBE "\xef\x80\x94" // U+f014 +#define ICON_MD_GPS_FIXED "\xee\x86\xb3" // U+e1b3 +#define ICON_MD_GPS_NOT_FIXED "\xee\x86\xb4" // U+e1b4 +#define ICON_MD_GPS_OFF "\xee\x86\xb5" // U+e1b5 +#define ICON_MD_GRADE "\xee\xa2\x85" // U+e885 +#define ICON_MD_GRADIENT "\xee\x8f\xa9" // U+e3e9 +#define ICON_MD_GRADING "\xee\xa9\x8f" // U+ea4f +#define ICON_MD_GRAIN "\xee\x8f\xaa" // U+e3ea +#define ICON_MD_GRAPHIC_EQ "\xee\x86\xb8" // U+e1b8 +#define ICON_MD_GRASS "\xef\x88\x85" // U+f205 +#define ICON_MD_GRID_3X3 "\xef\x80\x95" // U+f015 +#define ICON_MD_GRID_4X4 "\xef\x80\x96" // U+f016 +#define ICON_MD_GRID_GOLDENRATIO "\xef\x80\x97" // U+f017 +#define ICON_MD_GRID_OFF "\xee\x8f\xab" // U+e3eb +#define ICON_MD_GRID_ON "\xee\x8f\xac" // U+e3ec +#define ICON_MD_GRID_VIEW "\xee\xa6\xb0" // U+e9b0 +#define ICON_MD_GROUP "\xee\x9f\xaf" // U+e7ef +#define ICON_MD_GROUP_ADD "\xee\x9f\xb0" // U+e7f0 +#define ICON_MD_GROUP_OFF "\xee\x9d\x87" // U+e747 +#define ICON_MD_GROUP_REMOVE "\xee\x9e\xad" // U+e7ad +#define ICON_MD_GROUP_WORK "\xee\xa2\x86" // U+e886 +#define ICON_MD_GROUPS "\xef\x88\xb3" // U+f233 +#define ICON_MD_H_MOBILEDATA "\xef\x80\x98" // U+f018 +#define ICON_MD_H_PLUS_MOBILEDATA "\xef\x80\x99" // U+f019 +#define ICON_MD_HAIL "\xee\xa6\xb1" // U+e9b1 +#define ICON_MD_HANDSHAKE "\xee\xaf\x8b" // U+ebcb +#define ICON_MD_HANDYMAN "\xef\x84\x8b" // U+f10b +#define ICON_MD_HARDWARE "\xee\xa9\x99" // U+ea59 +#define ICON_MD_HD "\xee\x81\x92" // U+e052 +#define ICON_MD_HDR_AUTO "\xef\x80\x9a" // U+f01a +#define ICON_MD_HDR_AUTO_SELECT "\xef\x80\x9b" // U+f01b +#define ICON_MD_HDR_ENHANCED_SELECT "\xee\xbd\x91" // U+ef51 +#define ICON_MD_HDR_OFF "\xee\x8f\xad" // U+e3ed +#define ICON_MD_HDR_OFF_SELECT "\xef\x80\x9c" // U+f01c +#define ICON_MD_HDR_ON "\xee\x8f\xae" // U+e3ee +#define ICON_MD_HDR_ON_SELECT "\xef\x80\x9d" // U+f01d +#define ICON_MD_HDR_PLUS "\xef\x80\x9e" // U+f01e +#define ICON_MD_HDR_STRONG "\xee\x8f\xb1" // U+e3f1 +#define ICON_MD_HDR_WEAK "\xee\x8f\xb2" // U+e3f2 +#define ICON_MD_HEADPHONES "\xef\x80\x9f" // U+f01f +#define ICON_MD_HEADPHONES_BATTERY "\xef\x80\xa0" // U+f020 +#define ICON_MD_HEADSET "\xee\x8c\x90" // U+e310 +#define ICON_MD_HEADSET_MIC "\xee\x8c\x91" // U+e311 +#define ICON_MD_HEADSET_OFF "\xee\x8c\xba" // U+e33a +#define ICON_MD_HEALING "\xee\x8f\xb3" // U+e3f3 +#define ICON_MD_HEALTH_AND_SAFETY "\xee\x87\x95" // U+e1d5 +#define ICON_MD_HEARING "\xee\x80\xa3" // U+e023 +#define ICON_MD_HEARING_DISABLED "\xef\x84\x84" // U+f104 +#define ICON_MD_HEART_BROKEN "\xee\xab\x82" // U+eac2 +#define ICON_MD_HEAT_PUMP "\xee\xb0\x98" // U+ec18 +#define ICON_MD_HEIGHT "\xee\xa8\x96" // U+ea16 +#define ICON_MD_HELP "\xee\xa2\x87" // U+e887 +#define ICON_MD_HELP_CENTER "\xef\x87\x80" // U+f1c0 +#define ICON_MD_HELP_OUTLINE "\xee\xa3\xbd" // U+e8fd +#define ICON_MD_HEVC "\xef\x80\xa1" // U+f021 +#define ICON_MD_HEXAGON "\xee\xac\xb9" // U+eb39 +#define ICON_MD_HIDE_IMAGE "\xef\x80\xa2" // U+f022 +#define ICON_MD_HIDE_SOURCE "\xef\x80\xa3" // U+f023 +#define ICON_MD_HIGH_QUALITY "\xee\x80\xa4" // U+e024 +#define ICON_MD_HIGHLIGHT "\xee\x89\x9f" // U+e25f +#define ICON_MD_HIGHLIGHT_ALT "\xee\xbd\x92" // U+ef52 +#define ICON_MD_HIGHLIGHT_OFF "\xee\xa2\x88" // U+e888 +#define ICON_MD_HIGHLIGHT_REMOVE "\xee\xa2\x88" // U+e888 +#define ICON_MD_HIKING "\xee\x94\x8a" // U+e50a +#define ICON_MD_HISTORY "\xee\xa2\x89" // U+e889 +#define ICON_MD_HISTORY_EDU "\xee\xa8\xbe" // U+ea3e +#define ICON_MD_HISTORY_TOGGLE_OFF "\xef\x85\xbd" // U+f17d +#define ICON_MD_HIVE "\xee\xaa\xa6" // U+eaa6 +#define ICON_MD_HLS "\xee\xae\x8a" // U+eb8a +#define ICON_MD_HLS_OFF "\xee\xae\x8c" // U+eb8c +#define ICON_MD_HOLIDAY_VILLAGE "\xee\x96\x8a" // U+e58a +#define ICON_MD_HOME "\xee\xa2\x8a" // U+e88a +#define ICON_MD_HOME_FILLED "\xee\xa6\xb2" // U+e9b2 +#define ICON_MD_HOME_MAX "\xef\x80\xa4" // U+f024 +#define ICON_MD_HOME_MINI "\xef\x80\xa5" // U+f025 +#define ICON_MD_HOME_REPAIR_SERVICE "\xef\x84\x80" // U+f100 +#define ICON_MD_HOME_WORK "\xee\xa8\x89" // U+ea09 +#define ICON_MD_HORIZONTAL_DISTRIBUTE "\xee\x80\x94" // U+e014 +#define ICON_MD_HORIZONTAL_RULE "\xef\x84\x88" // U+f108 +#define ICON_MD_HORIZONTAL_SPLIT "\xee\xa5\x87" // U+e947 +#define ICON_MD_HOT_TUB "\xee\xad\x86" // U+eb46 +#define ICON_MD_HOTEL "\xee\x94\xba" // U+e53a +#define ICON_MD_HOTEL_CLASS "\xee\x9d\x83" // U+e743 +#define ICON_MD_HOURGLASS_BOTTOM "\xee\xa9\x9c" // U+ea5c +#define ICON_MD_HOURGLASS_DISABLED "\xee\xbd\x93" // U+ef53 +#define ICON_MD_HOURGLASS_EMPTY "\xee\xa2\x8b" // U+e88b +#define ICON_MD_HOURGLASS_FULL "\xee\xa2\x8c" // U+e88c +#define ICON_MD_HOURGLASS_TOP "\xee\xa9\x9b" // U+ea5b +#define ICON_MD_HOUSE "\xee\xa9\x84" // U+ea44 +#define ICON_MD_HOUSE_SIDING "\xef\x88\x82" // U+f202 +#define ICON_MD_HOUSEBOAT "\xee\x96\x84" // U+e584 +#define ICON_MD_HOW_TO_REG "\xee\x85\xb4" // U+e174 +#define ICON_MD_HOW_TO_VOTE "\xee\x85\xb5" // U+e175 +#define ICON_MD_HTML "\xee\xad\xbe" // U+eb7e +#define ICON_MD_HTTP "\xee\xa4\x82" // U+e902 +#define ICON_MD_HTTPS "\xee\xa2\x8d" // U+e88d +#define ICON_MD_HUB "\xee\xa7\xb4" // U+e9f4 +#define ICON_MD_HVAC "\xef\x84\x8e" // U+f10e +#define ICON_MD_ICE_SKATING "\xee\x94\x8b" // U+e50b +#define ICON_MD_ICECREAM "\xee\xa9\xa9" // U+ea69 +#define ICON_MD_IMAGE "\xee\x8f\xb4" // U+e3f4 +#define ICON_MD_IMAGE_ASPECT_RATIO "\xee\x8f\xb5" // U+e3f5 +#define ICON_MD_IMAGE_NOT_SUPPORTED "\xef\x84\x96" // U+f116 +#define ICON_MD_IMAGE_SEARCH "\xee\x90\xbf" // U+e43f +#define ICON_MD_IMAGESEARCH_ROLLER "\xee\xa6\xb4" // U+e9b4 +#define ICON_MD_IMPORT_CONTACTS "\xee\x83\xa0" // U+e0e0 +#define ICON_MD_IMPORT_EXPORT "\xee\x83\x83" // U+e0c3 +#define ICON_MD_IMPORTANT_DEVICES "\xee\xa4\x92" // U+e912 +#define ICON_MD_INBOX "\xee\x85\x96" // U+e156 +#define ICON_MD_INCOMPLETE_CIRCLE "\xee\x9e\x9b" // U+e79b +#define ICON_MD_INDETERMINATE_CHECK_BOX "\xee\xa4\x89" // U+e909 +#define ICON_MD_INFO "\xee\xa2\x8e" // U+e88e +#define ICON_MD_INFO_OUTLINE "\xee\xa2\x8f" // U+e88f +#define ICON_MD_INPUT "\xee\xa2\x90" // U+e890 +#define ICON_MD_INSERT_CHART "\xee\x89\x8b" // U+e24b +#define ICON_MD_INSERT_CHART_OUTLINED "\xee\x89\xaa" // U+e26a +#define ICON_MD_INSERT_COMMENT "\xee\x89\x8c" // U+e24c +#define ICON_MD_INSERT_DRIVE_FILE "\xee\x89\x8d" // U+e24d +#define ICON_MD_INSERT_EMOTICON "\xee\x89\x8e" // U+e24e +#define ICON_MD_INSERT_INVITATION "\xee\x89\x8f" // U+e24f +#define ICON_MD_INSERT_LINK "\xee\x89\x90" // U+e250 +#define ICON_MD_INSERT_PAGE_BREAK "\xee\xab\x8a" // U+eaca +#define ICON_MD_INSERT_PHOTO "\xee\x89\x91" // U+e251 +#define ICON_MD_INSIGHTS "\xef\x82\x92" // U+f092 +#define ICON_MD_INSTALL_DESKTOP "\xee\xad\xb1" // U+eb71 +#define ICON_MD_INSTALL_MOBILE "\xee\xad\xb2" // U+eb72 +#define ICON_MD_INTEGRATION_INSTRUCTIONS "\xee\xbd\x94" // U+ef54 +#define ICON_MD_INTERESTS "\xee\x9f\x88" // U+e7c8 +#define ICON_MD_INTERPRETER_MODE "\xee\xa0\xbb" // U+e83b +#define ICON_MD_INVENTORY "\xee\x85\xb9" // U+e179 +#define ICON_MD_INVENTORY_2 "\xee\x86\xa1" // U+e1a1 +#define ICON_MD_INVERT_COLORS "\xee\xa2\x91" // U+e891 +#define ICON_MD_INVERT_COLORS_OFF "\xee\x83\x84" // U+e0c4 +#define ICON_MD_INVERT_COLORS_ON "\xee\xa2\x91" // U+e891 +#define ICON_MD_IOS_SHARE "\xee\x9a\xb8" // U+e6b8 +#define ICON_MD_IRON "\xee\x96\x83" // U+e583 +#define ICON_MD_ISO "\xee\x8f\xb6" // U+e3f6 +#define ICON_MD_JAVASCRIPT "\xee\xad\xbc" // U+eb7c +#define ICON_MD_JOIN_FULL "\xee\xab\xab" // U+eaeb +#define ICON_MD_JOIN_INNER "\xee\xab\xb4" // U+eaf4 +#define ICON_MD_JOIN_LEFT "\xee\xab\xb2" // U+eaf2 +#define ICON_MD_JOIN_RIGHT "\xee\xab\xaa" // U+eaea +#define ICON_MD_KAYAKING "\xee\x94\x8c" // U+e50c +#define ICON_MD_KEBAB_DINING "\xee\xa1\x82" // U+e842 +#define ICON_MD_KEY "\xee\x9c\xbc" // U+e73c +#define ICON_MD_KEY_OFF "\xee\xae\x84" // U+eb84 +#define ICON_MD_KEYBOARD "\xee\x8c\x92" // U+e312 +#define ICON_MD_KEYBOARD_ALT "\xef\x80\xa8" // U+f028 +#define ICON_MD_KEYBOARD_ARROW_DOWN "\xee\x8c\x93" // U+e313 +#define ICON_MD_KEYBOARD_ARROW_LEFT "\xee\x8c\x94" // U+e314 +#define ICON_MD_KEYBOARD_ARROW_RIGHT "\xee\x8c\x95" // U+e315 +#define ICON_MD_KEYBOARD_ARROW_UP "\xee\x8c\x96" // U+e316 +#define ICON_MD_KEYBOARD_BACKSPACE "\xee\x8c\x97" // U+e317 +#define ICON_MD_KEYBOARD_CAPSLOCK "\xee\x8c\x98" // U+e318 +#define ICON_MD_KEYBOARD_COMMAND "\xee\xab\xa0" // U+eae0 +#define ICON_MD_KEYBOARD_COMMAND_KEY "\xee\xab\xa7" // U+eae7 +#define ICON_MD_KEYBOARD_CONTROL "\xee\x97\x93" // U+e5d3 +#define ICON_MD_KEYBOARD_CONTROL_KEY "\xee\xab\xa6" // U+eae6 +#define ICON_MD_KEYBOARD_DOUBLE_ARROW_DOWN "\xee\xab\x90" // U+ead0 +#define ICON_MD_KEYBOARD_DOUBLE_ARROW_LEFT "\xee\xab\x83" // U+eac3 +#define ICON_MD_KEYBOARD_DOUBLE_ARROW_RIGHT "\xee\xab\x89" // U+eac9 +#define ICON_MD_KEYBOARD_DOUBLE_ARROW_UP "\xee\xab\x8f" // U+eacf +#define ICON_MD_KEYBOARD_HIDE "\xee\x8c\x9a" // U+e31a +#define ICON_MD_KEYBOARD_OPTION "\xee\xab\x9f" // U+eadf +#define ICON_MD_KEYBOARD_OPTION_KEY "\xee\xab\xa8" // U+eae8 +#define ICON_MD_KEYBOARD_RETURN "\xee\x8c\x9b" // U+e31b +#define ICON_MD_KEYBOARD_TAB "\xee\x8c\x9c" // U+e31c +#define ICON_MD_KEYBOARD_VOICE "\xee\x8c\x9d" // U+e31d +#define ICON_MD_KING_BED "\xee\xa9\x85" // U+ea45 +#define ICON_MD_KITCHEN "\xee\xad\x87" // U+eb47 +#define ICON_MD_KITESURFING "\xee\x94\x8d" // U+e50d +#define ICON_MD_LABEL "\xee\xa2\x92" // U+e892 +#define ICON_MD_LABEL_IMPORTANT "\xee\xa4\xb7" // U+e937 +#define ICON_MD_LABEL_IMPORTANT_OUTLINE "\xee\xa5\x88" // U+e948 +#define ICON_MD_LABEL_OFF "\xee\xa6\xb6" // U+e9b6 +#define ICON_MD_LABEL_OUTLINE "\xee\xa2\x93" // U+e893 +#define ICON_MD_LAN "\xee\xac\xaf" // U+eb2f +#define ICON_MD_LANDSCAPE "\xee\x8f\xb7" // U+e3f7 +#define ICON_MD_LANDSLIDE "\xee\xaf\x97" // U+ebd7 +#define ICON_MD_LANGUAGE "\xee\xa2\x94" // U+e894 +#define ICON_MD_LAPTOP "\xee\x8c\x9e" // U+e31e +#define ICON_MD_LAPTOP_CHROMEBOOK "\xee\x8c\x9f" // U+e31f +#define ICON_MD_LAPTOP_MAC "\xee\x8c\xa0" // U+e320 +#define ICON_MD_LAPTOP_WINDOWS "\xee\x8c\xa1" // U+e321 +#define ICON_MD_LAST_PAGE "\xee\x97\x9d" // U+e5dd +#define ICON_MD_LAUNCH "\xee\xa2\x95" // U+e895 +#define ICON_MD_LAYERS "\xee\x94\xbb" // U+e53b +#define ICON_MD_LAYERS_CLEAR "\xee\x94\xbc" // U+e53c +#define ICON_MD_LEADERBOARD "\xef\x88\x8c" // U+f20c +#define ICON_MD_LEAK_ADD "\xee\x8f\xb8" // U+e3f8 +#define ICON_MD_LEAK_REMOVE "\xee\x8f\xb9" // U+e3f9 +#define ICON_MD_LEAVE_BAGS_AT_HOME "\xef\x88\x9b" // U+f21b +#define ICON_MD_LEGEND_TOGGLE "\xef\x84\x9b" // U+f11b +#define ICON_MD_LENS "\xee\x8f\xba" // U+e3fa +#define ICON_MD_LENS_BLUR "\xef\x80\xa9" // U+f029 +#define ICON_MD_LIBRARY_ADD "\xee\x80\xae" // U+e02e +#define ICON_MD_LIBRARY_ADD_CHECK "\xee\xa6\xb7" // U+e9b7 +#define ICON_MD_LIBRARY_BOOKS "\xee\x80\xaf" // U+e02f +#define ICON_MD_LIBRARY_MUSIC "\xee\x80\xb0" // U+e030 +#define ICON_MD_LIGHT "\xef\x80\xaa" // U+f02a +#define ICON_MD_LIGHT_MODE "\xee\x94\x98" // U+e518 +#define ICON_MD_LIGHTBULB "\xee\x83\xb0" // U+e0f0 +#define ICON_MD_LIGHTBULB_CIRCLE "\xee\xaf\xbe" // U+ebfe +#define ICON_MD_LIGHTBULB_OUTLINE "\xee\xa4\x8f" // U+e90f +#define ICON_MD_LINE_AXIS "\xee\xaa\x9a" // U+ea9a +#define ICON_MD_LINE_STYLE "\xee\xa4\x99" // U+e919 +#define ICON_MD_LINE_WEIGHT "\xee\xa4\x9a" // U+e91a +#define ICON_MD_LINEAR_SCALE "\xee\x89\xa0" // U+e260 +#define ICON_MD_LINK "\xee\x85\x97" // U+e157 +#define ICON_MD_LINK_OFF "\xee\x85\xaf" // U+e16f +#define ICON_MD_LINKED_CAMERA "\xee\x90\xb8" // U+e438 +#define ICON_MD_LIQUOR "\xee\xa9\xa0" // U+ea60 +#define ICON_MD_LIST "\xee\xa2\x96" // U+e896 +#define ICON_MD_LIST_ALT "\xee\x83\xae" // U+e0ee +#define ICON_MD_LIVE_HELP "\xee\x83\x86" // U+e0c6 +#define ICON_MD_LIVE_TV "\xee\x98\xb9" // U+e639 +#define ICON_MD_LIVING "\xef\x80\xab" // U+f02b +#define ICON_MD_LOCAL_ACTIVITY "\xee\x94\xbf" // U+e53f +#define ICON_MD_LOCAL_AIRPORT "\xee\x94\xbd" // U+e53d +#define ICON_MD_LOCAL_ATM "\xee\x94\xbe" // U+e53e +#define ICON_MD_LOCAL_ATTRACTION "\xee\x94\xbf" // U+e53f +#define ICON_MD_LOCAL_BAR "\xee\x95\x80" // U+e540 +#define ICON_MD_LOCAL_CAFE "\xee\x95\x81" // U+e541 +#define ICON_MD_LOCAL_CAR_WASH "\xee\x95\x82" // U+e542 +#define ICON_MD_LOCAL_CONVENIENCE_STORE "\xee\x95\x83" // U+e543 +#define ICON_MD_LOCAL_DINING "\xee\x95\x96" // U+e556 +#define ICON_MD_LOCAL_DRINK "\xee\x95\x84" // U+e544 +#define ICON_MD_LOCAL_FIRE_DEPARTMENT "\xee\xbd\x95" // U+ef55 +#define ICON_MD_LOCAL_FLORIST "\xee\x95\x85" // U+e545 +#define ICON_MD_LOCAL_GAS_STATION "\xee\x95\x86" // U+e546 +#define ICON_MD_LOCAL_GROCERY_STORE "\xee\x95\x87" // U+e547 +#define ICON_MD_LOCAL_HOSPITAL "\xee\x95\x88" // U+e548 +#define ICON_MD_LOCAL_HOTEL "\xee\x95\x89" // U+e549 +#define ICON_MD_LOCAL_LAUNDRY_SERVICE "\xee\x95\x8a" // U+e54a +#define ICON_MD_LOCAL_LIBRARY "\xee\x95\x8b" // U+e54b +#define ICON_MD_LOCAL_MALL "\xee\x95\x8c" // U+e54c +#define ICON_MD_LOCAL_MOVIES "\xee\x95\x8d" // U+e54d +#define ICON_MD_LOCAL_OFFER "\xee\x95\x8e" // U+e54e +#define ICON_MD_LOCAL_PARKING "\xee\x95\x8f" // U+e54f +#define ICON_MD_LOCAL_PHARMACY "\xee\x95\x90" // U+e550 +#define ICON_MD_LOCAL_PHONE "\xee\x95\x91" // U+e551 +#define ICON_MD_LOCAL_PIZZA "\xee\x95\x92" // U+e552 +#define ICON_MD_LOCAL_PLAY "\xee\x95\x93" // U+e553 +#define ICON_MD_LOCAL_POLICE "\xee\xbd\x96" // U+ef56 +#define ICON_MD_LOCAL_POST_OFFICE "\xee\x95\x94" // U+e554 +#define ICON_MD_LOCAL_PRINT_SHOP "\xee\x95\x95" // U+e555 +#define ICON_MD_LOCAL_PRINTSHOP "\xee\x95\x95" // U+e555 +#define ICON_MD_LOCAL_RESTAURANT "\xee\x95\x96" // U+e556 +#define ICON_MD_LOCAL_SEE "\xee\x95\x97" // U+e557 +#define ICON_MD_LOCAL_SHIPPING "\xee\x95\x98" // U+e558 +#define ICON_MD_LOCAL_TAXI "\xee\x95\x99" // U+e559 +#define ICON_MD_LOCATION_CITY "\xee\x9f\xb1" // U+e7f1 +#define ICON_MD_LOCATION_DISABLED "\xee\x86\xb6" // U+e1b6 +#define ICON_MD_LOCATION_HISTORY "\xee\x95\x9a" // U+e55a +#define ICON_MD_LOCATION_OFF "\xee\x83\x87" // U+e0c7 +#define ICON_MD_LOCATION_ON "\xee\x83\x88" // U+e0c8 +#define ICON_MD_LOCATION_PIN "\xef\x87\x9b" // U+f1db +#define ICON_MD_LOCATION_SEARCHING "\xee\x86\xb7" // U+e1b7 +#define ICON_MD_LOCK "\xee\xa2\x97" // U+e897 +#define ICON_MD_LOCK_CLOCK "\xee\xbd\x97" // U+ef57 +#define ICON_MD_LOCK_OPEN "\xee\xa2\x98" // U+e898 +#define ICON_MD_LOCK_OUTLINE "\xee\xa2\x99" // U+e899 +#define ICON_MD_LOCK_PERSON "\xef\xa3\xb3" // U+f8f3 +#define ICON_MD_LOCK_RESET "\xee\xab\x9e" // U+eade +#define ICON_MD_LOGIN "\xee\xa9\xb7" // U+ea77 +#define ICON_MD_LOGO_DEV "\xee\xab\x96" // U+ead6 +#define ICON_MD_LOGOUT "\xee\xa6\xba" // U+e9ba +#define ICON_MD_LOOKS "\xee\x8f\xbc" // U+e3fc +#define ICON_MD_LOOKS_3 "\xee\x8f\xbb" // U+e3fb +#define ICON_MD_LOOKS_4 "\xee\x8f\xbd" // U+e3fd +#define ICON_MD_LOOKS_5 "\xee\x8f\xbe" // U+e3fe +#define ICON_MD_LOOKS_6 "\xee\x8f\xbf" // U+e3ff +#define ICON_MD_LOOKS_ONE "\xee\x90\x80" // U+e400 +#define ICON_MD_LOOKS_TWO "\xee\x90\x81" // U+e401 +#define ICON_MD_LOOP "\xee\x80\xa8" // U+e028 +#define ICON_MD_LOUPE "\xee\x90\x82" // U+e402 +#define ICON_MD_LOW_PRIORITY "\xee\x85\xad" // U+e16d +#define ICON_MD_LOYALTY "\xee\xa2\x9a" // U+e89a +#define ICON_MD_LTE_MOBILEDATA "\xef\x80\xac" // U+f02c +#define ICON_MD_LTE_PLUS_MOBILEDATA "\xef\x80\xad" // U+f02d +#define ICON_MD_LUGGAGE "\xef\x88\xb5" // U+f235 +#define ICON_MD_LUNCH_DINING "\xee\xa9\xa1" // U+ea61 +#define ICON_MD_LYRICS "\xee\xb0\x8b" // U+ec0b +#define ICON_MD_MAIL "\xee\x85\x98" // U+e158 +#define ICON_MD_MAIL_LOCK "\xee\xb0\x8a" // U+ec0a +#define ICON_MD_MAIL_OUTLINE "\xee\x83\xa1" // U+e0e1 +#define ICON_MD_MALE "\xee\x96\x8e" // U+e58e +#define ICON_MD_MAN "\xee\x93\xab" // U+e4eb +#define ICON_MD_MANAGE_ACCOUNTS "\xef\x80\xae" // U+f02e +#define ICON_MD_MANAGE_HISTORY "\xee\xaf\xa7" // U+ebe7 +#define ICON_MD_MANAGE_SEARCH "\xef\x80\xaf" // U+f02f +#define ICON_MD_MAP "\xee\x95\x9b" // U+e55b +#define ICON_MD_MAPS_HOME_WORK "\xef\x80\xb0" // U+f030 +#define ICON_MD_MAPS_UGC "\xee\xbd\x98" // U+ef58 +#define ICON_MD_MARGIN "\xee\xa6\xbb" // U+e9bb +#define ICON_MD_MARK_AS_UNREAD "\xee\xa6\xbc" // U+e9bc +#define ICON_MD_MARK_CHAT_READ "\xef\x86\x8b" // U+f18b +#define ICON_MD_MARK_CHAT_UNREAD "\xef\x86\x89" // U+f189 +#define ICON_MD_MARK_EMAIL_READ "\xef\x86\x8c" // U+f18c +#define ICON_MD_MARK_EMAIL_UNREAD "\xef\x86\x8a" // U+f18a +#define ICON_MD_MARK_UNREAD_CHAT_ALT "\xee\xae\x9d" // U+eb9d +#define ICON_MD_MARKUNREAD "\xee\x85\x99" // U+e159 +#define ICON_MD_MARKUNREAD_MAILBOX "\xee\xa2\x9b" // U+e89b +#define ICON_MD_MASKS "\xef\x88\x98" // U+f218 +#define ICON_MD_MAXIMIZE "\xee\xa4\xb0" // U+e930 +#define ICON_MD_MEDIA_BLUETOOTH_OFF "\xef\x80\xb1" // U+f031 +#define ICON_MD_MEDIA_BLUETOOTH_ON "\xef\x80\xb2" // U+f032 +#define ICON_MD_MEDIATION "\xee\xbe\xa7" // U+efa7 +#define ICON_MD_MEDICAL_INFORMATION "\xee\xaf\xad" // U+ebed +#define ICON_MD_MEDICAL_SERVICES "\xef\x84\x89" // U+f109 +#define ICON_MD_MEDICATION "\xef\x80\xb3" // U+f033 +#define ICON_MD_MEDICATION_LIQUID "\xee\xaa\x87" // U+ea87 +#define ICON_MD_MEETING_ROOM "\xee\xad\x8f" // U+eb4f +#define ICON_MD_MEMORY "\xee\x8c\xa2" // U+e322 +#define ICON_MD_MENU "\xee\x97\x92" // U+e5d2 +#define ICON_MD_MENU_BOOK "\xee\xa8\x99" // U+ea19 +#define ICON_MD_MENU_OPEN "\xee\xa6\xbd" // U+e9bd +#define ICON_MD_MERGE "\xee\xae\x98" // U+eb98 +#define ICON_MD_MERGE_TYPE "\xee\x89\x92" // U+e252 +#define ICON_MD_MESSAGE "\xee\x83\x89" // U+e0c9 +#define ICON_MD_MESSENGER "\xee\x83\x8a" // U+e0ca +#define ICON_MD_MESSENGER_OUTLINE "\xee\x83\x8b" // U+e0cb +#define ICON_MD_MIC "\xee\x80\xa9" // U+e029 +#define ICON_MD_MIC_EXTERNAL_OFF "\xee\xbd\x99" // U+ef59 +#define ICON_MD_MIC_EXTERNAL_ON "\xee\xbd\x9a" // U+ef5a +#define ICON_MD_MIC_NONE "\xee\x80\xaa" // U+e02a +#define ICON_MD_MIC_OFF "\xee\x80\xab" // U+e02b +#define ICON_MD_MICROWAVE "\xef\x88\x84" // U+f204 +#define ICON_MD_MILITARY_TECH "\xee\xa8\xbf" // U+ea3f +#define ICON_MD_MINIMIZE "\xee\xa4\xb1" // U+e931 +#define ICON_MD_MINOR_CRASH "\xee\xaf\xb1" // U+ebf1 +#define ICON_MD_MISCELLANEOUS_SERVICES "\xef\x84\x8c" // U+f10c +#define ICON_MD_MISSED_VIDEO_CALL "\xee\x81\xb3" // U+e073 +#define ICON_MD_MMS "\xee\x98\x98" // U+e618 +#define ICON_MD_MOBILE_FRIENDLY "\xee\x88\x80" // U+e200 +#define ICON_MD_MOBILE_OFF "\xee\x88\x81" // U+e201 +#define ICON_MD_MOBILE_SCREEN_SHARE "\xee\x83\xa7" // U+e0e7 +#define ICON_MD_MOBILEDATA_OFF "\xef\x80\xb4" // U+f034 +#define ICON_MD_MODE "\xef\x82\x97" // U+f097 +#define ICON_MD_MODE_COMMENT "\xee\x89\x93" // U+e253 +#define ICON_MD_MODE_EDIT "\xee\x89\x94" // U+e254 +#define ICON_MD_MODE_EDIT_OUTLINE "\xef\x80\xb5" // U+f035 +#define ICON_MD_MODE_FAN_OFF "\xee\xb0\x97" // U+ec17 +#define ICON_MD_MODE_NIGHT "\xef\x80\xb6" // U+f036 +#define ICON_MD_MODE_OF_TRAVEL "\xee\x9f\x8e" // U+e7ce +#define ICON_MD_MODE_STANDBY "\xef\x80\xb7" // U+f037 +#define ICON_MD_MODEL_TRAINING "\xef\x83\x8f" // U+f0cf +#define ICON_MD_MONETIZATION_ON "\xee\x89\xa3" // U+e263 +#define ICON_MD_MONEY "\xee\x95\xbd" // U+e57d +#define ICON_MD_MONEY_OFF "\xee\x89\x9c" // U+e25c +#define ICON_MD_MONEY_OFF_CSRED "\xef\x80\xb8" // U+f038 +#define ICON_MD_MONITOR "\xee\xbd\x9b" // U+ef5b +#define ICON_MD_MONITOR_HEART "\xee\xaa\xa2" // U+eaa2 +#define ICON_MD_MONITOR_WEIGHT "\xef\x80\xb9" // U+f039 +#define ICON_MD_MONOCHROME_PHOTOS "\xee\x90\x83" // U+e403 +#define ICON_MD_MOOD "\xee\x9f\xb2" // U+e7f2 +#define ICON_MD_MOOD_BAD "\xee\x9f\xb3" // U+e7f3 +#define ICON_MD_MOPED "\xee\xac\xa8" // U+eb28 +#define ICON_MD_MORE "\xee\x98\x99" // U+e619 +#define ICON_MD_MORE_HORIZ "\xee\x97\x93" // U+e5d3 +#define ICON_MD_MORE_TIME "\xee\xa9\x9d" // U+ea5d +#define ICON_MD_MORE_VERT "\xee\x97\x94" // U+e5d4 +#define ICON_MD_MOSQUE "\xee\xaa\xb2" // U+eab2 +#define ICON_MD_MOTION_PHOTOS_AUTO "\xef\x80\xba" // U+f03a +#define ICON_MD_MOTION_PHOTOS_OFF "\xee\xa7\x80" // U+e9c0 +#define ICON_MD_MOTION_PHOTOS_ON "\xee\xa7\x81" // U+e9c1 +#define ICON_MD_MOTION_PHOTOS_PAUSE "\xef\x88\xa7" // U+f227 +#define ICON_MD_MOTION_PHOTOS_PAUSED "\xee\xa7\x82" // U+e9c2 +#define ICON_MD_MOTORCYCLE "\xee\xa4\x9b" // U+e91b +#define ICON_MD_MOUSE "\xee\x8c\xa3" // U+e323 +#define ICON_MD_MOVE_DOWN "\xee\xad\xa1" // U+eb61 +#define ICON_MD_MOVE_TO_INBOX "\xee\x85\xa8" // U+e168 +#define ICON_MD_MOVE_UP "\xee\xad\xa4" // U+eb64 +#define ICON_MD_MOVIE "\xee\x80\xac" // U+e02c +#define ICON_MD_MOVIE_CREATION "\xee\x90\x84" // U+e404 +#define ICON_MD_MOVIE_FILTER "\xee\x90\xba" // U+e43a +#define ICON_MD_MOVING "\xee\x94\x81" // U+e501 +#define ICON_MD_MP "\xee\xa7\x83" // U+e9c3 +#define ICON_MD_MULTILINE_CHART "\xee\x9b\x9f" // U+e6df +#define ICON_MD_MULTIPLE_STOP "\xef\x86\xb9" // U+f1b9 +#define ICON_MD_MULTITRACK_AUDIO "\xee\x86\xb8" // U+e1b8 +#define ICON_MD_MUSEUM "\xee\xa8\xb6" // U+ea36 +#define ICON_MD_MUSIC_NOTE "\xee\x90\x85" // U+e405 +#define ICON_MD_MUSIC_OFF "\xee\x91\x80" // U+e440 +#define ICON_MD_MUSIC_VIDEO "\xee\x81\xa3" // U+e063 +#define ICON_MD_MY_LIBRARY_ADD "\xee\x80\xae" // U+e02e +#define ICON_MD_MY_LIBRARY_BOOKS "\xee\x80\xaf" // U+e02f +#define ICON_MD_MY_LIBRARY_MUSIC "\xee\x80\xb0" // U+e030 +#define ICON_MD_MY_LOCATION "\xee\x95\x9c" // U+e55c +#define ICON_MD_NAT "\xee\xbd\x9c" // U+ef5c +#define ICON_MD_NATURE "\xee\x90\x86" // U+e406 +#define ICON_MD_NATURE_PEOPLE "\xee\x90\x87" // U+e407 +#define ICON_MD_NAVIGATE_BEFORE "\xee\x90\x88" // U+e408 +#define ICON_MD_NAVIGATE_NEXT "\xee\x90\x89" // U+e409 +#define ICON_MD_NAVIGATION "\xee\x95\x9d" // U+e55d +#define ICON_MD_NEAR_ME "\xee\x95\xa9" // U+e569 +#define ICON_MD_NEAR_ME_DISABLED "\xef\x87\xaf" // U+f1ef +#define ICON_MD_NEARBY_ERROR "\xef\x80\xbb" // U+f03b +#define ICON_MD_NEARBY_OFF "\xef\x80\xbc" // U+f03c +#define ICON_MD_NEST_CAM_WIRED_STAND "\xee\xb0\x96" // U+ec16 +#define ICON_MD_NETWORK_CELL "\xee\x86\xb9" // U+e1b9 +#define ICON_MD_NETWORK_CHECK "\xee\x99\x80" // U+e640 +#define ICON_MD_NETWORK_LOCKED "\xee\x98\x9a" // U+e61a +#define ICON_MD_NETWORK_PING "\xee\xaf\x8a" // U+ebca +#define ICON_MD_NETWORK_WIFI "\xee\x86\xba" // U+e1ba +#define ICON_MD_NETWORK_WIFI_1_BAR "\xee\xaf\xa4" // U+ebe4 +#define ICON_MD_NETWORK_WIFI_2_BAR "\xee\xaf\x96" // U+ebd6 +#define ICON_MD_NETWORK_WIFI_3_BAR "\xee\xaf\xa1" // U+ebe1 +#define ICON_MD_NEW_LABEL "\xee\x98\x89" // U+e609 +#define ICON_MD_NEW_RELEASES "\xee\x80\xb1" // U+e031 +#define ICON_MD_NEWSPAPER "\xee\xae\x81" // U+eb81 +#define ICON_MD_NEXT_PLAN "\xee\xbd\x9d" // U+ef5d +#define ICON_MD_NEXT_WEEK "\xee\x85\xaa" // U+e16a +#define ICON_MD_NFC "\xee\x86\xbb" // U+e1bb +#define ICON_MD_NIGHT_SHELTER "\xef\x87\xb1" // U+f1f1 +#define ICON_MD_NIGHTLIFE "\xee\xa9\xa2" // U+ea62 +#define ICON_MD_NIGHTLIGHT "\xef\x80\xbd" // U+f03d +#define ICON_MD_NIGHTLIGHT_ROUND "\xee\xbd\x9e" // U+ef5e +#define ICON_MD_NIGHTS_STAY "\xee\xa9\x86" // U+ea46 +#define ICON_MD_NO_ACCOUNTS "\xef\x80\xbe" // U+f03e +#define ICON_MD_NO_ADULT_CONTENT "\xef\xa3\xbe" // U+f8fe +#define ICON_MD_NO_BACKPACK "\xef\x88\xb7" // U+f237 +#define ICON_MD_NO_CELL "\xef\x86\xa4" // U+f1a4 +#define ICON_MD_NO_CRASH "\xee\xaf\xb0" // U+ebf0 +#define ICON_MD_NO_DRINKS "\xef\x86\xa5" // U+f1a5 +#define ICON_MD_NO_ENCRYPTION "\xee\x99\x81" // U+e641 +#define ICON_MD_NO_ENCRYPTION_GMAILERRORRED "\xef\x80\xbf" // U+f03f +#define ICON_MD_NO_FLASH "\xef\x86\xa6" // U+f1a6 +#define ICON_MD_NO_FOOD "\xef\x86\xa7" // U+f1a7 +#define ICON_MD_NO_LUGGAGE "\xef\x88\xbb" // U+f23b +#define ICON_MD_NO_MEALS "\xef\x87\x96" // U+f1d6 +#define ICON_MD_NO_MEALS_OULINE "\xef\x88\xa9" // U+f229 +#define ICON_MD_NO_MEETING_ROOM "\xee\xad\x8e" // U+eb4e +#define ICON_MD_NO_PHOTOGRAPHY "\xef\x86\xa8" // U+f1a8 +#define ICON_MD_NO_SIM "\xee\x83\x8c" // U+e0cc +#define ICON_MD_NO_STROLLER "\xef\x86\xaf" // U+f1af +#define ICON_MD_NO_TRANSFER "\xef\x87\x95" // U+f1d5 +#define ICON_MD_NOISE_AWARE "\xee\xaf\xac" // U+ebec +#define ICON_MD_NOISE_CONTROL_OFF "\xee\xaf\xb3" // U+ebf3 +#define ICON_MD_NORDIC_WALKING "\xee\x94\x8e" // U+e50e +#define ICON_MD_NORTH "\xef\x87\xa0" // U+f1e0 +#define ICON_MD_NORTH_EAST "\xef\x87\xa1" // U+f1e1 +#define ICON_MD_NORTH_WEST "\xef\x87\xa2" // U+f1e2 +#define ICON_MD_NOT_ACCESSIBLE "\xef\x83\xbe" // U+f0fe +#define ICON_MD_NOT_INTERESTED "\xee\x80\xb3" // U+e033 +#define ICON_MD_NOT_LISTED_LOCATION "\xee\x95\xb5" // U+e575 +#define ICON_MD_NOT_STARTED "\xef\x83\x91" // U+f0d1 +#define ICON_MD_NOTE "\xee\x81\xaf" // U+e06f +#define ICON_MD_NOTE_ADD "\xee\xa2\x9c" // U+e89c +#define ICON_MD_NOTE_ALT "\xef\x81\x80" // U+f040 +#define ICON_MD_NOTES "\xee\x89\xac" // U+e26c +#define ICON_MD_NOTIFICATION_ADD "\xee\x8e\x99" // U+e399 +#define ICON_MD_NOTIFICATION_IMPORTANT "\xee\x80\x84" // U+e004 +#define ICON_MD_NOTIFICATIONS "\xee\x9f\xb4" // U+e7f4 +#define ICON_MD_NOTIFICATIONS_ACTIVE "\xee\x9f\xb7" // U+e7f7 +#define ICON_MD_NOTIFICATIONS_NONE "\xee\x9f\xb5" // U+e7f5 +#define ICON_MD_NOTIFICATIONS_OFF "\xee\x9f\xb6" // U+e7f6 +#define ICON_MD_NOTIFICATIONS_ON "\xee\x9f\xb7" // U+e7f7 +#define ICON_MD_NOTIFICATIONS_PAUSED "\xee\x9f\xb8" // U+e7f8 +#define ICON_MD_NOW_WALLPAPER "\xee\x86\xbc" // U+e1bc +#define ICON_MD_NOW_WIDGETS "\xee\x86\xbd" // U+e1bd +#define ICON_MD_NUMBERS "\xee\xab\x87" // U+eac7 +#define ICON_MD_OFFLINE_BOLT "\xee\xa4\xb2" // U+e932 +#define ICON_MD_OFFLINE_PIN "\xee\xa4\x8a" // U+e90a +#define ICON_MD_OFFLINE_SHARE "\xee\xa7\x85" // U+e9c5 +#define ICON_MD_OIL_BARREL "\xee\xb0\x95" // U+ec15 +#define ICON_MD_ON_DEVICE_TRAINING "\xee\xaf\xbd" // U+ebfd +#define ICON_MD_ONDEMAND_VIDEO "\xee\x98\xba" // U+e63a +#define ICON_MD_ONLINE_PREDICTION "\xef\x83\xab" // U+f0eb +#define ICON_MD_OPACITY "\xee\xa4\x9c" // U+e91c +#define ICON_MD_OPEN_IN_BROWSER "\xee\xa2\x9d" // U+e89d +#define ICON_MD_OPEN_IN_FULL "\xef\x87\x8e" // U+f1ce +#define ICON_MD_OPEN_IN_NEW "\xee\xa2\x9e" // U+e89e +#define ICON_MD_OPEN_IN_NEW_OFF "\xee\x93\xb6" // U+e4f6 +#define ICON_MD_OPEN_WITH "\xee\xa2\x9f" // U+e89f +#define ICON_MD_OTHER_HOUSES "\xee\x96\x8c" // U+e58c +#define ICON_MD_OUTBOND "\xef\x88\xa8" // U+f228 +#define ICON_MD_OUTBOUND "\xee\x87\x8a" // U+e1ca +#define ICON_MD_OUTBOX "\xee\xbd\x9f" // U+ef5f +#define ICON_MD_OUTDOOR_GRILL "\xee\xa9\x87" // U+ea47 +#define ICON_MD_OUTGOING_MAIL "\xef\x83\x92" // U+f0d2 +#define ICON_MD_OUTLET "\xef\x87\x94" // U+f1d4 +#define ICON_MD_OUTLINED_FLAG "\xee\x85\xae" // U+e16e +#define ICON_MD_OUTPUT "\xee\xae\xbe" // U+ebbe +#define ICON_MD_PADDING "\xee\xa7\x88" // U+e9c8 +#define ICON_MD_PAGES "\xee\x9f\xb9" // U+e7f9 +#define ICON_MD_PAGEVIEW "\xee\xa2\xa0" // U+e8a0 +#define ICON_MD_PAID "\xef\x81\x81" // U+f041 +#define ICON_MD_PALETTE "\xee\x90\x8a" // U+e40a +#define ICON_MD_PAN_TOOL "\xee\xa4\xa5" // U+e925 +#define ICON_MD_PAN_TOOL_ALT "\xee\xae\xb9" // U+ebb9 +#define ICON_MD_PANORAMA "\xee\x90\x8b" // U+e40b +#define ICON_MD_PANORAMA_FISH_EYE "\xee\x90\x8c" // U+e40c +#define ICON_MD_PANORAMA_FISHEYE "\xee\x90\x8c" // U+e40c +#define ICON_MD_PANORAMA_HORIZONTAL "\xee\x90\x8d" // U+e40d +#define ICON_MD_PANORAMA_HORIZONTAL_SELECT "\xee\xbd\xa0" // U+ef60 +#define ICON_MD_PANORAMA_PHOTOSPHERE "\xee\xa7\x89" // U+e9c9 +#define ICON_MD_PANORAMA_PHOTOSPHERE_SELECT "\xee\xa7\x8a" // U+e9ca +#define ICON_MD_PANORAMA_VERTICAL "\xee\x90\x8e" // U+e40e +#define ICON_MD_PANORAMA_VERTICAL_SELECT "\xee\xbd\xa1" // U+ef61 +#define ICON_MD_PANORAMA_WIDE_ANGLE "\xee\x90\x8f" // U+e40f +#define ICON_MD_PANORAMA_WIDE_ANGLE_SELECT "\xee\xbd\xa2" // U+ef62 +#define ICON_MD_PARAGLIDING "\xee\x94\x8f" // U+e50f +#define ICON_MD_PARK "\xee\xa9\xa3" // U+ea63 +#define ICON_MD_PARTY_MODE "\xee\x9f\xba" // U+e7fa +#define ICON_MD_PASSWORD "\xef\x81\x82" // U+f042 +#define ICON_MD_PATTERN "\xef\x81\x83" // U+f043 +#define ICON_MD_PAUSE "\xee\x80\xb4" // U+e034 +#define ICON_MD_PAUSE_CIRCLE "\xee\x86\xa2" // U+e1a2 +#define ICON_MD_PAUSE_CIRCLE_FILLED "\xee\x80\xb5" // U+e035 +#define ICON_MD_PAUSE_CIRCLE_OUTLINE "\xee\x80\xb6" // U+e036 +#define ICON_MD_PAUSE_PRESENTATION "\xee\x83\xaa" // U+e0ea +#define ICON_MD_PAYMENT "\xee\xa2\xa1" // U+e8a1 +#define ICON_MD_PAYMENTS "\xee\xbd\xa3" // U+ef63 +#define ICON_MD_PAYPAL "\xee\xaa\x8d" // U+ea8d +#define ICON_MD_PEDAL_BIKE "\xee\xac\xa9" // U+eb29 +#define ICON_MD_PENDING "\xee\xbd\xa4" // U+ef64 +#define ICON_MD_PENDING_ACTIONS "\xef\x86\xbb" // U+f1bb +#define ICON_MD_PENTAGON "\xee\xad\x90" // U+eb50 +#define ICON_MD_PEOPLE "\xee\x9f\xbb" // U+e7fb +#define ICON_MD_PEOPLE_ALT "\xee\xa8\xa1" // U+ea21 +#define ICON_MD_PEOPLE_OUTLINE "\xee\x9f\xbc" // U+e7fc +#define ICON_MD_PERCENT "\xee\xad\x98" // U+eb58 +#define ICON_MD_PERM_CAMERA_MIC "\xee\xa2\xa2" // U+e8a2 +#define ICON_MD_PERM_CONTACT_CAL "\xee\xa2\xa3" // U+e8a3 +#define ICON_MD_PERM_CONTACT_CALENDAR "\xee\xa2\xa3" // U+e8a3 +#define ICON_MD_PERM_DATA_SETTING "\xee\xa2\xa4" // U+e8a4 +#define ICON_MD_PERM_DEVICE_INFO "\xee\xa2\xa5" // U+e8a5 +#define ICON_MD_PERM_DEVICE_INFORMATION "\xee\xa2\xa5" // U+e8a5 +#define ICON_MD_PERM_IDENTITY "\xee\xa2\xa6" // U+e8a6 +#define ICON_MD_PERM_MEDIA "\xee\xa2\xa7" // U+e8a7 +#define ICON_MD_PERM_PHONE_MSG "\xee\xa2\xa8" // U+e8a8 +#define ICON_MD_PERM_SCAN_WIFI "\xee\xa2\xa9" // U+e8a9 +#define ICON_MD_PERSON "\xee\x9f\xbd" // U+e7fd +#define ICON_MD_PERSON_ADD "\xee\x9f\xbe" // U+e7fe +#define ICON_MD_PERSON_ADD_ALT "\xee\xa9\x8d" // U+ea4d +#define ICON_MD_PERSON_ADD_ALT_1 "\xee\xbd\xa5" // U+ef65 +#define ICON_MD_PERSON_ADD_DISABLED "\xee\xa7\x8b" // U+e9cb +#define ICON_MD_PERSON_OFF "\xee\x94\x90" // U+e510 +#define ICON_MD_PERSON_OUTLINE "\xee\x9f\xbf" // U+e7ff +#define ICON_MD_PERSON_PIN "\xee\x95\x9a" // U+e55a +#define ICON_MD_PERSON_PIN_CIRCLE "\xee\x95\xaa" // U+e56a +#define ICON_MD_PERSON_REMOVE "\xee\xbd\xa6" // U+ef66 +#define ICON_MD_PERSON_REMOVE_ALT_1 "\xee\xbd\xa7" // U+ef67 +#define ICON_MD_PERSON_SEARCH "\xef\x84\x86" // U+f106 +#define ICON_MD_PERSONAL_INJURY "\xee\x9b\x9a" // U+e6da +#define ICON_MD_PERSONAL_VIDEO "\xee\x98\xbb" // U+e63b +#define ICON_MD_PEST_CONTROL "\xef\x83\xba" // U+f0fa +#define ICON_MD_PEST_CONTROL_RODENT "\xef\x83\xbd" // U+f0fd +#define ICON_MD_PETS "\xee\xa4\x9d" // U+e91d +#define ICON_MD_PHISHING "\xee\xab\x97" // U+ead7 +#define ICON_MD_PHONE "\xee\x83\x8d" // U+e0cd +#define ICON_MD_PHONE_ANDROID "\xee\x8c\xa4" // U+e324 +#define ICON_MD_PHONE_BLUETOOTH_SPEAKER "\xee\x98\x9b" // U+e61b +#define ICON_MD_PHONE_CALLBACK "\xee\x99\x89" // U+e649 +#define ICON_MD_PHONE_DISABLED "\xee\xa7\x8c" // U+e9cc +#define ICON_MD_PHONE_ENABLED "\xee\xa7\x8d" // U+e9cd +#define ICON_MD_PHONE_FORWARDED "\xee\x98\x9c" // U+e61c +#define ICON_MD_PHONE_IN_TALK "\xee\x98\x9d" // U+e61d +#define ICON_MD_PHONE_IPHONE "\xee\x8c\xa5" // U+e325 +#define ICON_MD_PHONE_LOCKED "\xee\x98\x9e" // U+e61e +#define ICON_MD_PHONE_MISSED "\xee\x98\x9f" // U+e61f +#define ICON_MD_PHONE_PAUSED "\xee\x98\xa0" // U+e620 +#define ICON_MD_PHONELINK "\xee\x8c\xa6" // U+e326 +#define ICON_MD_PHONELINK_ERASE "\xee\x83\x9b" // U+e0db +#define ICON_MD_PHONELINK_LOCK "\xee\x83\x9c" // U+e0dc +#define ICON_MD_PHONELINK_OFF "\xee\x8c\xa7" // U+e327 +#define ICON_MD_PHONELINK_RING "\xee\x83\x9d" // U+e0dd +#define ICON_MD_PHONELINK_SETUP "\xee\x83\x9e" // U+e0de +#define ICON_MD_PHOTO "\xee\x90\x90" // U+e410 +#define ICON_MD_PHOTO_ALBUM "\xee\x90\x91" // U+e411 +#define ICON_MD_PHOTO_CAMERA "\xee\x90\x92" // U+e412 +#define ICON_MD_PHOTO_CAMERA_BACK "\xee\xbd\xa8" // U+ef68 +#define ICON_MD_PHOTO_CAMERA_FRONT "\xee\xbd\xa9" // U+ef69 +#define ICON_MD_PHOTO_FILTER "\xee\x90\xbb" // U+e43b +#define ICON_MD_PHOTO_LIBRARY "\xee\x90\x93" // U+e413 +#define ICON_MD_PHOTO_SIZE_SELECT_ACTUAL "\xee\x90\xb2" // U+e432 +#define ICON_MD_PHOTO_SIZE_SELECT_LARGE "\xee\x90\xb3" // U+e433 +#define ICON_MD_PHOTO_SIZE_SELECT_SMALL "\xee\x90\xb4" // U+e434 +#define ICON_MD_PHP "\xee\xae\x8f" // U+eb8f +#define ICON_MD_PIANO "\xee\x94\xa1" // U+e521 +#define ICON_MD_PIANO_OFF "\xee\x94\xa0" // U+e520 +#define ICON_MD_PICTURE_AS_PDF "\xee\x90\x95" // U+e415 +#define ICON_MD_PICTURE_IN_PICTURE "\xee\xa2\xaa" // U+e8aa +#define ICON_MD_PICTURE_IN_PICTURE_ALT "\xee\xa4\x91" // U+e911 +#define ICON_MD_PIE_CHART "\xee\x9b\x84" // U+e6c4 +#define ICON_MD_PIE_CHART_OUTLINE "\xef\x81\x84" // U+f044 +#define ICON_MD_PIE_CHART_OUTLINED "\xee\x9b\x85" // U+e6c5 +#define ICON_MD_PIN "\xef\x81\x85" // U+f045 +#define ICON_MD_PIN_DROP "\xee\x95\x9e" // U+e55e +#define ICON_MD_PIN_END "\xee\x9d\xa7" // U+e767 +#define ICON_MD_PIN_INVOKE "\xee\x9d\xa3" // U+e763 +#define ICON_MD_PINCH "\xee\xac\xb8" // U+eb38 +#define ICON_MD_PIVOT_TABLE_CHART "\xee\xa7\x8e" // U+e9ce +#define ICON_MD_PIX "\xee\xaa\xa3" // U+eaa3 +#define ICON_MD_PLACE "\xee\x95\x9f" // U+e55f +#define ICON_MD_PLAGIARISM "\xee\xa9\x9a" // U+ea5a +#define ICON_MD_PLAY_ARROW "\xee\x80\xb7" // U+e037 +#define ICON_MD_PLAY_CIRCLE "\xee\x87\x84" // U+e1c4 +#define ICON_MD_PLAY_CIRCLE_FILL "\xee\x80\xb8" // U+e038 +#define ICON_MD_PLAY_CIRCLE_FILLED "\xee\x80\xb8" // U+e038 +#define ICON_MD_PLAY_CIRCLE_OUTLINE "\xee\x80\xb9" // U+e039 +#define ICON_MD_PLAY_DISABLED "\xee\xbd\xaa" // U+ef6a +#define ICON_MD_PLAY_FOR_WORK "\xee\xa4\x86" // U+e906 +#define ICON_MD_PLAY_LESSON "\xef\x81\x87" // U+f047 +#define ICON_MD_PLAYLIST_ADD "\xee\x80\xbb" // U+e03b +#define ICON_MD_PLAYLIST_ADD_CHECK "\xee\x81\xa5" // U+e065 +#define ICON_MD_PLAYLIST_ADD_CHECK_CIRCLE "\xee\x9f\xa6" // U+e7e6 +#define ICON_MD_PLAYLIST_ADD_CIRCLE "\xee\x9f\xa5" // U+e7e5 +#define ICON_MD_PLAYLIST_PLAY "\xee\x81\x9f" // U+e05f +#define ICON_MD_PLAYLIST_REMOVE "\xee\xae\x80" // U+eb80 +#define ICON_MD_PLUMBING "\xef\x84\x87" // U+f107 +#define ICON_MD_PLUS_ONE "\xee\xa0\x80" // U+e800 +#define ICON_MD_PODCASTS "\xef\x81\x88" // U+f048 +#define ICON_MD_POINT_OF_SALE "\xef\x85\xbe" // U+f17e +#define ICON_MD_POLICY "\xee\xa8\x97" // U+ea17 +#define ICON_MD_POLL "\xee\xa0\x81" // U+e801 +#define ICON_MD_POLYLINE "\xee\xae\xbb" // U+ebbb +#define ICON_MD_POLYMER "\xee\xa2\xab" // U+e8ab +#define ICON_MD_POOL "\xee\xad\x88" // U+eb48 +#define ICON_MD_PORTABLE_WIFI_OFF "\xee\x83\x8e" // U+e0ce +#define ICON_MD_PORTRAIT "\xee\x90\x96" // U+e416 +#define ICON_MD_POST_ADD "\xee\xa8\xa0" // U+ea20 +#define ICON_MD_POWER "\xee\x98\xbc" // U+e63c +#define ICON_MD_POWER_INPUT "\xee\x8c\xb6" // U+e336 +#define ICON_MD_POWER_OFF "\xee\x99\x86" // U+e646 +#define ICON_MD_POWER_SETTINGS_NEW "\xee\xa2\xac" // U+e8ac +#define ICON_MD_PRECISION_MANUFACTURING "\xef\x81\x89" // U+f049 +#define ICON_MD_PREGNANT_WOMAN "\xee\xa4\x9e" // U+e91e +#define ICON_MD_PRESENT_TO_ALL "\xee\x83\x9f" // U+e0df +#define ICON_MD_PREVIEW "\xef\x87\x85" // U+f1c5 +#define ICON_MD_PRICE_CHANGE "\xef\x81\x8a" // U+f04a +#define ICON_MD_PRICE_CHECK "\xef\x81\x8b" // U+f04b +#define ICON_MD_PRINT "\xee\xa2\xad" // U+e8ad +#define ICON_MD_PRINT_DISABLED "\xee\xa7\x8f" // U+e9cf +#define ICON_MD_PRIORITY_HIGH "\xee\x99\x85" // U+e645 +#define ICON_MD_PRIVACY_TIP "\xef\x83\x9c" // U+f0dc +#define ICON_MD_PRIVATE_CONNECTIVITY "\xee\x9d\x84" // U+e744 +#define ICON_MD_PRODUCTION_QUANTITY_LIMITS "\xee\x87\x91" // U+e1d1 +#define ICON_MD_PROPANE "\xee\xb0\x94" // U+ec14 +#define ICON_MD_PROPANE_TANK "\xee\xb0\x93" // U+ec13 +#define ICON_MD_PSYCHOLOGY "\xee\xa9\x8a" // U+ea4a +#define ICON_MD_PUBLIC "\xee\xa0\x8b" // U+e80b +#define ICON_MD_PUBLIC_OFF "\xef\x87\x8a" // U+f1ca +#define ICON_MD_PUBLISH "\xee\x89\x95" // U+e255 +#define ICON_MD_PUBLISHED_WITH_CHANGES "\xef\x88\xb2" // U+f232 +#define ICON_MD_PUNCH_CLOCK "\xee\xaa\xa8" // U+eaa8 +#define ICON_MD_PUSH_PIN "\xef\x84\x8d" // U+f10d +#define ICON_MD_QR_CODE "\xee\xbd\xab" // U+ef6b +#define ICON_MD_QR_CODE_2 "\xee\x80\x8a" // U+e00a +#define ICON_MD_QR_CODE_SCANNER "\xef\x88\x86" // U+f206 +#define ICON_MD_QUERY_BUILDER "\xee\xa2\xae" // U+e8ae +#define ICON_MD_QUERY_STATS "\xee\x93\xbc" // U+e4fc +#define ICON_MD_QUESTION_ANSWER "\xee\xa2\xaf" // U+e8af +#define ICON_MD_QUESTION_MARK "\xee\xae\x8b" // U+eb8b +#define ICON_MD_QUEUE "\xee\x80\xbc" // U+e03c +#define ICON_MD_QUEUE_MUSIC "\xee\x80\xbd" // U+e03d +#define ICON_MD_QUEUE_PLAY_NEXT "\xee\x81\xa6" // U+e066 +#define ICON_MD_QUICK_CONTACTS_DIALER "\xee\x83\x8f" // U+e0cf +#define ICON_MD_QUICK_CONTACTS_MAIL "\xee\x83\x90" // U+e0d0 +#define ICON_MD_QUICKREPLY "\xee\xbd\xac" // U+ef6c +#define ICON_MD_QUIZ "\xef\x81\x8c" // U+f04c +#define ICON_MD_QUORA "\xee\xaa\x98" // U+ea98 +#define ICON_MD_R_MOBILEDATA "\xef\x81\x8d" // U+f04d +#define ICON_MD_RADAR "\xef\x81\x8e" // U+f04e +#define ICON_MD_RADIO "\xee\x80\xbe" // U+e03e +#define ICON_MD_RADIO_BUTTON_CHECKED "\xee\xa0\xb7" // U+e837 +#define ICON_MD_RADIO_BUTTON_OFF "\xee\xa0\xb6" // U+e836 +#define ICON_MD_RADIO_BUTTON_ON "\xee\xa0\xb7" // U+e837 +#define ICON_MD_RADIO_BUTTON_UNCHECKED "\xee\xa0\xb6" // U+e836 +#define ICON_MD_RAILWAY_ALERT "\xee\xa7\x91" // U+e9d1 +#define ICON_MD_RAMEN_DINING "\xee\xa9\xa4" // U+ea64 +#define ICON_MD_RAMP_LEFT "\xee\xae\x9c" // U+eb9c +#define ICON_MD_RAMP_RIGHT "\xee\xae\x96" // U+eb96 +#define ICON_MD_RATE_REVIEW "\xee\x95\xa0" // U+e560 +#define ICON_MD_RAW_OFF "\xef\x81\x8f" // U+f04f +#define ICON_MD_RAW_ON "\xef\x81\x90" // U+f050 +#define ICON_MD_READ_MORE "\xee\xbd\xad" // U+ef6d +#define ICON_MD_REAL_ESTATE_AGENT "\xee\x9c\xba" // U+e73a +#define ICON_MD_RECEIPT "\xee\xa2\xb0" // U+e8b0 +#define ICON_MD_RECEIPT_LONG "\xee\xbd\xae" // U+ef6e +#define ICON_MD_RECENT_ACTORS "\xee\x80\xbf" // U+e03f +#define ICON_MD_RECOMMEND "\xee\xa7\x92" // U+e9d2 +#define ICON_MD_RECORD_VOICE_OVER "\xee\xa4\x9f" // U+e91f +#define ICON_MD_RECTANGLE "\xee\xad\x94" // U+eb54 +#define ICON_MD_RECYCLING "\xee\x9d\xa0" // U+e760 +#define ICON_MD_REDDIT "\xee\xaa\xa0" // U+eaa0 +#define ICON_MD_REDEEM "\xee\xa2\xb1" // U+e8b1 +#define ICON_MD_REDO "\xee\x85\x9a" // U+e15a +#define ICON_MD_REDUCE_CAPACITY "\xef\x88\x9c" // U+f21c +#define ICON_MD_REFRESH "\xee\x97\x95" // U+e5d5 +#define ICON_MD_REMEMBER_ME "\xef\x81\x91" // U+f051 +#define ICON_MD_REMOVE "\xee\x85\x9b" // U+e15b +#define ICON_MD_REMOVE_CIRCLE "\xee\x85\x9c" // U+e15c +#define ICON_MD_REMOVE_CIRCLE_OUTLINE "\xee\x85\x9d" // U+e15d +#define ICON_MD_REMOVE_DONE "\xee\xa7\x93" // U+e9d3 +#define ICON_MD_REMOVE_FROM_QUEUE "\xee\x81\xa7" // U+e067 +#define ICON_MD_REMOVE_MODERATOR "\xee\xa7\x94" // U+e9d4 +#define ICON_MD_REMOVE_RED_EYE "\xee\x90\x97" // U+e417 +#define ICON_MD_REMOVE_ROAD "\xee\xaf\xbc" // U+ebfc +#define ICON_MD_REMOVE_SHOPPING_CART "\xee\xa4\xa8" // U+e928 +#define ICON_MD_REORDER "\xee\xa3\xbe" // U+e8fe +#define ICON_MD_REPEAT "\xee\x81\x80" // U+e040 +#define ICON_MD_REPEAT_ON "\xee\xa7\x96" // U+e9d6 +#define ICON_MD_REPEAT_ONE "\xee\x81\x81" // U+e041 +#define ICON_MD_REPEAT_ONE_ON "\xee\xa7\x97" // U+e9d7 +#define ICON_MD_REPLAY "\xee\x81\x82" // U+e042 +#define ICON_MD_REPLAY_10 "\xee\x81\x99" // U+e059 +#define ICON_MD_REPLAY_30 "\xee\x81\x9a" // U+e05a +#define ICON_MD_REPLAY_5 "\xee\x81\x9b" // U+e05b +#define ICON_MD_REPLAY_CIRCLE_FILLED "\xee\xa7\x98" // U+e9d8 +#define ICON_MD_REPLY "\xee\x85\x9e" // U+e15e +#define ICON_MD_REPLY_ALL "\xee\x85\x9f" // U+e15f +#define ICON_MD_REPORT "\xee\x85\xa0" // U+e160 +#define ICON_MD_REPORT_GMAILERRORRED "\xef\x81\x92" // U+f052 +#define ICON_MD_REPORT_OFF "\xee\x85\xb0" // U+e170 +#define ICON_MD_REPORT_PROBLEM "\xee\xa2\xb2" // U+e8b2 +#define ICON_MD_REQUEST_PAGE "\xef\x88\xac" // U+f22c +#define ICON_MD_REQUEST_QUOTE "\xef\x86\xb6" // U+f1b6 +#define ICON_MD_RESET_TV "\xee\xa7\x99" // U+e9d9 +#define ICON_MD_RESTART_ALT "\xef\x81\x93" // U+f053 +#define ICON_MD_RESTAURANT "\xee\x95\xac" // U+e56c +#define ICON_MD_RESTAURANT_MENU "\xee\x95\xa1" // U+e561 +#define ICON_MD_RESTORE "\xee\xa2\xb3" // U+e8b3 +#define ICON_MD_RESTORE_FROM_TRASH "\xee\xa4\xb8" // U+e938 +#define ICON_MD_RESTORE_PAGE "\xee\xa4\xa9" // U+e929 +#define ICON_MD_REVIEWS "\xef\x81\x94" // U+f054 +#define ICON_MD_RICE_BOWL "\xef\x87\xb5" // U+f1f5 +#define ICON_MD_RING_VOLUME "\xee\x83\x91" // U+e0d1 +#define ICON_MD_ROCKET "\xee\xae\xa5" // U+eba5 +#define ICON_MD_ROCKET_LAUNCH "\xee\xae\x9b" // U+eb9b +#define ICON_MD_ROLLER_SHADES "\xee\xb0\x92" // U+ec12 +#define ICON_MD_ROLLER_SHADES_CLOSED "\xee\xb0\x91" // U+ec11 +#define ICON_MD_ROLLER_SKATING "\xee\xaf\x8d" // U+ebcd +#define ICON_MD_ROOFING "\xef\x88\x81" // U+f201 +#define ICON_MD_ROOM "\xee\xa2\xb4" // U+e8b4 +#define ICON_MD_ROOM_PREFERENCES "\xef\x86\xb8" // U+f1b8 +#define ICON_MD_ROOM_SERVICE "\xee\xad\x89" // U+eb49 +#define ICON_MD_ROTATE_90_DEGREES_CCW "\xee\x90\x98" // U+e418 +#define ICON_MD_ROTATE_90_DEGREES_CW "\xee\xaa\xab" // U+eaab +#define ICON_MD_ROTATE_LEFT "\xee\x90\x99" // U+e419 +#define ICON_MD_ROTATE_RIGHT "\xee\x90\x9a" // U+e41a +#define ICON_MD_ROUNDABOUT_LEFT "\xee\xae\x99" // U+eb99 +#define ICON_MD_ROUNDABOUT_RIGHT "\xee\xae\xa3" // U+eba3 +#define ICON_MD_ROUNDED_CORNER "\xee\xa4\xa0" // U+e920 +#define ICON_MD_ROUTE "\xee\xab\x8d" // U+eacd +#define ICON_MD_ROUTER "\xee\x8c\xa8" // U+e328 +#define ICON_MD_ROWING "\xee\xa4\xa1" // U+e921 +#define ICON_MD_RSS_FEED "\xee\x83\xa5" // U+e0e5 +#define ICON_MD_RSVP "\xef\x81\x95" // U+f055 +#define ICON_MD_RTT "\xee\xa6\xad" // U+e9ad +#define ICON_MD_RULE "\xef\x87\x82" // U+f1c2 +#define ICON_MD_RULE_FOLDER "\xef\x87\x89" // U+f1c9 +#define ICON_MD_RUN_CIRCLE "\xee\xbd\xaf" // U+ef6f +#define ICON_MD_RUNNING_WITH_ERRORS "\xee\x94\x9d" // U+e51d +#define ICON_MD_RV_HOOKUP "\xee\x99\x82" // U+e642 +#define ICON_MD_SAFETY_CHECK "\xee\xaf\xaf" // U+ebef +#define ICON_MD_SAFETY_DIVIDER "\xee\x87\x8c" // U+e1cc +#define ICON_MD_SAILING "\xee\x94\x82" // U+e502 +#define ICON_MD_SANITIZER "\xef\x88\x9d" // U+f21d +#define ICON_MD_SATELLITE "\xee\x95\xa2" // U+e562 +#define ICON_MD_SATELLITE_ALT "\xee\xac\xba" // U+eb3a +#define ICON_MD_SAVE "\xee\x85\xa1" // U+e161 +#define ICON_MD_SAVE_ALT "\xee\x85\xb1" // U+e171 +#define ICON_MD_SAVE_AS "\xee\xad\xa0" // U+eb60 +#define ICON_MD_SAVED_SEARCH "\xee\xa8\x91" // U+ea11 +#define ICON_MD_SAVINGS "\xee\x8b\xab" // U+e2eb +#define ICON_MD_SCALE "\xee\xad\x9f" // U+eb5f +#define ICON_MD_SCANNER "\xee\x8c\xa9" // U+e329 +#define ICON_MD_SCATTER_PLOT "\xee\x89\xa8" // U+e268 +#define ICON_MD_SCHEDULE "\xee\xa2\xb5" // U+e8b5 +#define ICON_MD_SCHEDULE_SEND "\xee\xa8\x8a" // U+ea0a +#define ICON_MD_SCHEMA "\xee\x93\xbd" // U+e4fd +#define ICON_MD_SCHOOL "\xee\xa0\x8c" // U+e80c +#define ICON_MD_SCIENCE "\xee\xa9\x8b" // U+ea4b +#define ICON_MD_SCORE "\xee\x89\xa9" // U+e269 +#define ICON_MD_SCOREBOARD "\xee\xaf\x90" // U+ebd0 +#define ICON_MD_SCREEN_LOCK_LANDSCAPE "\xee\x86\xbe" // U+e1be +#define ICON_MD_SCREEN_LOCK_PORTRAIT "\xee\x86\xbf" // U+e1bf +#define ICON_MD_SCREEN_LOCK_ROTATION "\xee\x87\x80" // U+e1c0 +#define ICON_MD_SCREEN_ROTATION "\xee\x87\x81" // U+e1c1 +#define ICON_MD_SCREEN_ROTATION_ALT "\xee\xaf\xae" // U+ebee +#define ICON_MD_SCREEN_SEARCH_DESKTOP "\xee\xbd\xb0" // U+ef70 +#define ICON_MD_SCREEN_SHARE "\xee\x83\xa2" // U+e0e2 +#define ICON_MD_SCREENSHOT "\xef\x81\x96" // U+f056 +#define ICON_MD_SCREENSHOT_MONITOR "\xee\xb0\x88" // U+ec08 +#define ICON_MD_SCUBA_DIVING "\xee\xaf\x8e" // U+ebce +#define ICON_MD_SD "\xee\xa7\x9d" // U+e9dd +#define ICON_MD_SD_CARD "\xee\x98\xa3" // U+e623 +#define ICON_MD_SD_CARD_ALERT "\xef\x81\x97" // U+f057 +#define ICON_MD_SD_STORAGE "\xee\x87\x82" // U+e1c2 +#define ICON_MD_SEARCH "\xee\xa2\xb6" // U+e8b6 +#define ICON_MD_SEARCH_OFF "\xee\xa9\xb6" // U+ea76 +#define ICON_MD_SECURITY "\xee\x8c\xaa" // U+e32a +#define ICON_MD_SECURITY_UPDATE "\xef\x81\x98" // U+f058 +#define ICON_MD_SECURITY_UPDATE_GOOD "\xef\x81\x99" // U+f059 +#define ICON_MD_SECURITY_UPDATE_WARNING "\xef\x81\x9a" // U+f05a +#define ICON_MD_SEGMENT "\xee\xa5\x8b" // U+e94b +#define ICON_MD_SELECT_ALL "\xee\x85\xa2" // U+e162 +#define ICON_MD_SELF_IMPROVEMENT "\xee\xa9\xb8" // U+ea78 +#define ICON_MD_SELL "\xef\x81\x9b" // U+f05b +#define ICON_MD_SEND "\xee\x85\xa3" // U+e163 +#define ICON_MD_SEND_AND_ARCHIVE "\xee\xa8\x8c" // U+ea0c +#define ICON_MD_SEND_TIME_EXTENSION "\xee\xab\x9b" // U+eadb +#define ICON_MD_SEND_TO_MOBILE "\xef\x81\x9c" // U+f05c +#define ICON_MD_SENSOR_DOOR "\xef\x86\xb5" // U+f1b5 +#define ICON_MD_SENSOR_OCCUPIED "\xee\xb0\x90" // U+ec10 +#define ICON_MD_SENSOR_WINDOW "\xef\x86\xb4" // U+f1b4 +#define ICON_MD_SENSORS "\xee\x94\x9e" // U+e51e +#define ICON_MD_SENSORS_OFF "\xee\x94\x9f" // U+e51f +#define ICON_MD_SENTIMENT_DISSATISFIED "\xee\xa0\x91" // U+e811 +#define ICON_MD_SENTIMENT_NEUTRAL "\xee\xa0\x92" // U+e812 +#define ICON_MD_SENTIMENT_SATISFIED "\xee\xa0\x93" // U+e813 +#define ICON_MD_SENTIMENT_SATISFIED_ALT "\xee\x83\xad" // U+e0ed +#define ICON_MD_SENTIMENT_VERY_DISSATISFIED "\xee\xa0\x94" // U+e814 +#define ICON_MD_SENTIMENT_VERY_SATISFIED "\xee\xa0\x95" // U+e815 +#define ICON_MD_SET_MEAL "\xef\x87\xaa" // U+f1ea +#define ICON_MD_SETTINGS "\xee\xa2\xb8" // U+e8b8 +#define ICON_MD_SETTINGS_ACCESSIBILITY "\xef\x81\x9d" // U+f05d +#define ICON_MD_SETTINGS_APPLICATIONS "\xee\xa2\xb9" // U+e8b9 +#define ICON_MD_SETTINGS_BACKUP_RESTORE "\xee\xa2\xba" // U+e8ba +#define ICON_MD_SETTINGS_BLUETOOTH "\xee\xa2\xbb" // U+e8bb +#define ICON_MD_SETTINGS_BRIGHTNESS "\xee\xa2\xbd" // U+e8bd +#define ICON_MD_SETTINGS_CELL "\xee\xa2\xbc" // U+e8bc +#define ICON_MD_SETTINGS_DISPLAY "\xee\xa2\xbd" // U+e8bd +#define ICON_MD_SETTINGS_ETHERNET "\xee\xa2\xbe" // U+e8be +#define ICON_MD_SETTINGS_INPUT_ANTENNA "\xee\xa2\xbf" // U+e8bf +#define ICON_MD_SETTINGS_INPUT_COMPONENT "\xee\xa3\x80" // U+e8c0 +#define ICON_MD_SETTINGS_INPUT_COMPOSITE "\xee\xa3\x81" // U+e8c1 +#define ICON_MD_SETTINGS_INPUT_HDMI "\xee\xa3\x82" // U+e8c2 +#define ICON_MD_SETTINGS_INPUT_SVIDEO "\xee\xa3\x83" // U+e8c3 +#define ICON_MD_SETTINGS_OVERSCAN "\xee\xa3\x84" // U+e8c4 +#define ICON_MD_SETTINGS_PHONE "\xee\xa3\x85" // U+e8c5 +#define ICON_MD_SETTINGS_POWER "\xee\xa3\x86" // U+e8c6 +#define ICON_MD_SETTINGS_REMOTE "\xee\xa3\x87" // U+e8c7 +#define ICON_MD_SETTINGS_SUGGEST "\xef\x81\x9e" // U+f05e +#define ICON_MD_SETTINGS_SYSTEM_DAYDREAM "\xee\x87\x83" // U+e1c3 +#define ICON_MD_SETTINGS_VOICE "\xee\xa3\x88" // U+e8c8 +#define ICON_MD_SEVERE_COLD "\xee\xaf\x93" // U+ebd3 +#define ICON_MD_SHARE "\xee\xa0\x8d" // U+e80d +#define ICON_MD_SHARE_ARRIVAL_TIME "\xee\x94\xa4" // U+e524 +#define ICON_MD_SHARE_LOCATION "\xef\x81\x9f" // U+f05f +#define ICON_MD_SHIELD "\xee\xa7\xa0" // U+e9e0 +#define ICON_MD_SHIELD_MOON "\xee\xaa\xa9" // U+eaa9 +#define ICON_MD_SHOP "\xee\xa3\x89" // U+e8c9 +#define ICON_MD_SHOP_2 "\xee\x86\x9e" // U+e19e +#define ICON_MD_SHOP_TWO "\xee\xa3\x8a" // U+e8ca +#define ICON_MD_SHOPIFY "\xee\xaa\x9d" // U+ea9d +#define ICON_MD_SHOPPING_BAG "\xef\x87\x8c" // U+f1cc +#define ICON_MD_SHOPPING_BASKET "\xee\xa3\x8b" // U+e8cb +#define ICON_MD_SHOPPING_CART "\xee\xa3\x8c" // U+e8cc +#define ICON_MD_SHOPPING_CART_CHECKOUT "\xee\xae\x88" // U+eb88 +#define ICON_MD_SHORT_TEXT "\xee\x89\xa1" // U+e261 +#define ICON_MD_SHORTCUT "\xef\x81\xa0" // U+f060 +#define ICON_MD_SHOW_CHART "\xee\x9b\xa1" // U+e6e1 +#define ICON_MD_SHOWER "\xef\x81\xa1" // U+f061 +#define ICON_MD_SHUFFLE "\xee\x81\x83" // U+e043 +#define ICON_MD_SHUFFLE_ON "\xee\xa7\xa1" // U+e9e1 +#define ICON_MD_SHUTTER_SPEED "\xee\x90\xbd" // U+e43d +#define ICON_MD_SICK "\xef\x88\xa0" // U+f220 +#define ICON_MD_SIGN_LANGUAGE "\xee\xaf\xa5" // U+ebe5 +#define ICON_MD_SIGNAL_CELLULAR_0_BAR "\xef\x82\xa8" // U+f0a8 +#define ICON_MD_SIGNAL_CELLULAR_4_BAR "\xee\x87\x88" // U+e1c8 +#define ICON_MD_SIGNAL_CELLULAR_ALT "\xee\x88\x82" // U+e202 +#define ICON_MD_SIGNAL_CELLULAR_ALT_1_BAR "\xee\xaf\x9f" // U+ebdf +#define ICON_MD_SIGNAL_CELLULAR_ALT_2_BAR "\xee\xaf\xa3" // U+ebe3 +#define ICON_MD_SIGNAL_CELLULAR_CONNECTED_NO_INTERNET_0_BAR "\xef\x82\xac" // U+f0ac +#define ICON_MD_SIGNAL_CELLULAR_CONNECTED_NO_INTERNET_4_BAR "\xee\x87\x8d" // U+e1cd +#define ICON_MD_SIGNAL_CELLULAR_NO_SIM "\xee\x87\x8e" // U+e1ce +#define ICON_MD_SIGNAL_CELLULAR_NODATA "\xef\x81\xa2" // U+f062 +#define ICON_MD_SIGNAL_CELLULAR_NULL "\xee\x87\x8f" // U+e1cf +#define ICON_MD_SIGNAL_CELLULAR_OFF "\xee\x87\x90" // U+e1d0 +#define ICON_MD_SIGNAL_WIFI_0_BAR "\xef\x82\xb0" // U+f0b0 +#define ICON_MD_SIGNAL_WIFI_4_BAR "\xee\x87\x98" // U+e1d8 +#define ICON_MD_SIGNAL_WIFI_4_BAR_LOCK "\xee\x87\x99" // U+e1d9 +#define ICON_MD_SIGNAL_WIFI_BAD "\xef\x81\xa3" // U+f063 +#define ICON_MD_SIGNAL_WIFI_CONNECTED_NO_INTERNET_4 "\xef\x81\xa4" // U+f064 +#define ICON_MD_SIGNAL_WIFI_OFF "\xee\x87\x9a" // U+e1da +#define ICON_MD_SIGNAL_WIFI_STATUSBAR_4_BAR "\xef\x81\xa5" // U+f065 +#define ICON_MD_SIGNAL_WIFI_STATUSBAR_CONNECTED_NO_INTERNET_4 "\xef\x81\xa6" // U+f066 +#define ICON_MD_SIGNAL_WIFI_STATUSBAR_NULL "\xef\x81\xa7" // U+f067 +#define ICON_MD_SIGNPOST "\xee\xae\x91" // U+eb91 +#define ICON_MD_SIM_CARD "\xee\x8c\xab" // U+e32b +#define ICON_MD_SIM_CARD_ALERT "\xee\x98\xa4" // U+e624 +#define ICON_MD_SIM_CARD_DOWNLOAD "\xef\x81\xa8" // U+f068 +#define ICON_MD_SINGLE_BED "\xee\xa9\x88" // U+ea48 +#define ICON_MD_SIP "\xef\x81\xa9" // U+f069 +#define ICON_MD_SKATEBOARDING "\xee\x94\x91" // U+e511 +#define ICON_MD_SKIP_NEXT "\xee\x81\x84" // U+e044 +#define ICON_MD_SKIP_PREVIOUS "\xee\x81\x85" // U+e045 +#define ICON_MD_SLEDDING "\xee\x94\x92" // U+e512 +#define ICON_MD_SLIDESHOW "\xee\x90\x9b" // U+e41b +#define ICON_MD_SLOW_MOTION_VIDEO "\xee\x81\xa8" // U+e068 +#define ICON_MD_SMART_BUTTON "\xef\x87\x81" // U+f1c1 +#define ICON_MD_SMART_DISPLAY "\xef\x81\xaa" // U+f06a +#define ICON_MD_SMART_SCREEN "\xef\x81\xab" // U+f06b +#define ICON_MD_SMART_TOY "\xef\x81\xac" // U+f06c +#define ICON_MD_SMARTPHONE "\xee\x8c\xac" // U+e32c +#define ICON_MD_SMOKE_FREE "\xee\xad\x8a" // U+eb4a +#define ICON_MD_SMOKING_ROOMS "\xee\xad\x8b" // U+eb4b +#define ICON_MD_SMS "\xee\x98\xa5" // U+e625 +#define ICON_MD_SMS_FAILED "\xee\x98\xa6" // U+e626 +#define ICON_MD_SNAPCHAT "\xee\xa9\xae" // U+ea6e +#define ICON_MD_SNIPPET_FOLDER "\xef\x87\x87" // U+f1c7 +#define ICON_MD_SNOOZE "\xee\x81\x86" // U+e046 +#define ICON_MD_SNOWBOARDING "\xee\x94\x93" // U+e513 +#define ICON_MD_SNOWING "\xee\xa0\x8f" // U+e80f +#define ICON_MD_SNOWMOBILE "\xee\x94\x83" // U+e503 +#define ICON_MD_SNOWSHOEING "\xee\x94\x94" // U+e514 +#define ICON_MD_SOAP "\xef\x86\xb2" // U+f1b2 +#define ICON_MD_SOCIAL_DISTANCE "\xee\x87\x8b" // U+e1cb +#define ICON_MD_SOLAR_POWER "\xee\xb0\x8f" // U+ec0f +#define ICON_MD_SORT "\xee\x85\xa4" // U+e164 +#define ICON_MD_SORT_BY_ALPHA "\xee\x81\x93" // U+e053 +#define ICON_MD_SOS "\xee\xaf\xb7" // U+ebf7 +#define ICON_MD_SOUP_KITCHEN "\xee\x9f\x93" // U+e7d3 +#define ICON_MD_SOURCE "\xef\x87\x84" // U+f1c4 +#define ICON_MD_SOUTH "\xef\x87\xa3" // U+f1e3 +#define ICON_MD_SOUTH_AMERICA "\xee\x9f\xa4" // U+e7e4 +#define ICON_MD_SOUTH_EAST "\xef\x87\xa4" // U+f1e4 +#define ICON_MD_SOUTH_WEST "\xef\x87\xa5" // U+f1e5 +#define ICON_MD_SPA "\xee\xad\x8c" // U+eb4c +#define ICON_MD_SPACE_BAR "\xee\x89\x96" // U+e256 +#define ICON_MD_SPACE_DASHBOARD "\xee\x99\xab" // U+e66b +#define ICON_MD_SPATIAL_AUDIO "\xee\xaf\xab" // U+ebeb +#define ICON_MD_SPATIAL_AUDIO_OFF "\xee\xaf\xa8" // U+ebe8 +#define ICON_MD_SPATIAL_TRACKING "\xee\xaf\xaa" // U+ebea +#define ICON_MD_SPEAKER "\xee\x8c\xad" // U+e32d +#define ICON_MD_SPEAKER_GROUP "\xee\x8c\xae" // U+e32e +#define ICON_MD_SPEAKER_NOTES "\xee\xa3\x8d" // U+e8cd +#define ICON_MD_SPEAKER_NOTES_OFF "\xee\xa4\xaa" // U+e92a +#define ICON_MD_SPEAKER_PHONE "\xee\x83\x92" // U+e0d2 +#define ICON_MD_SPEED "\xee\xa7\xa4" // U+e9e4 +#define ICON_MD_SPELLCHECK "\xee\xa3\x8e" // U+e8ce +#define ICON_MD_SPLITSCREEN "\xef\x81\xad" // U+f06d +#define ICON_MD_SPOKE "\xee\xa6\xa7" // U+e9a7 +#define ICON_MD_SPORTS "\xee\xa8\xb0" // U+ea30 +#define ICON_MD_SPORTS_BAR "\xef\x87\xb3" // U+f1f3 +#define ICON_MD_SPORTS_BASEBALL "\xee\xa9\x91" // U+ea51 +#define ICON_MD_SPORTS_BASKETBALL "\xee\xa8\xa6" // U+ea26 +#define ICON_MD_SPORTS_CRICKET "\xee\xa8\xa7" // U+ea27 +#define ICON_MD_SPORTS_ESPORTS "\xee\xa8\xa8" // U+ea28 +#define ICON_MD_SPORTS_FOOTBALL "\xee\xa8\xa9" // U+ea29 +#define ICON_MD_SPORTS_GOLF "\xee\xa8\xaa" // U+ea2a +#define ICON_MD_SPORTS_GYMNASTICS "\xee\xaf\x84" // U+ebc4 +#define ICON_MD_SPORTS_HANDBALL "\xee\xa8\xb3" // U+ea33 +#define ICON_MD_SPORTS_HOCKEY "\xee\xa8\xab" // U+ea2b +#define ICON_MD_SPORTS_KABADDI "\xee\xa8\xb4" // U+ea34 +#define ICON_MD_SPORTS_MARTIAL_ARTS "\xee\xab\xa9" // U+eae9 +#define ICON_MD_SPORTS_MMA "\xee\xa8\xac" // U+ea2c +#define ICON_MD_SPORTS_MOTORSPORTS "\xee\xa8\xad" // U+ea2d +#define ICON_MD_SPORTS_RUGBY "\xee\xa8\xae" // U+ea2e +#define ICON_MD_SPORTS_SCORE "\xef\x81\xae" // U+f06e +#define ICON_MD_SPORTS_SOCCER "\xee\xa8\xaf" // U+ea2f +#define ICON_MD_SPORTS_TENNIS "\xee\xa8\xb2" // U+ea32 +#define ICON_MD_SPORTS_VOLLEYBALL "\xee\xa8\xb1" // U+ea31 +#define ICON_MD_SQUARE "\xee\xac\xb6" // U+eb36 +#define ICON_MD_SQUARE_FOOT "\xee\xa9\x89" // U+ea49 +#define ICON_MD_SSID_CHART "\xee\xad\xa6" // U+eb66 +#define ICON_MD_STACKED_BAR_CHART "\xee\xa7\xa6" // U+e9e6 +#define ICON_MD_STACKED_LINE_CHART "\xef\x88\xab" // U+f22b +#define ICON_MD_STADIUM "\xee\xae\x90" // U+eb90 +#define ICON_MD_STAIRS "\xef\x86\xa9" // U+f1a9 +#define ICON_MD_STAR "\xee\xa0\xb8" // U+e838 +#define ICON_MD_STAR_BORDER "\xee\xa0\xba" // U+e83a +#define ICON_MD_STAR_BORDER_PURPLE500 "\xef\x82\x99" // U+f099 +#define ICON_MD_STAR_HALF "\xee\xa0\xb9" // U+e839 +#define ICON_MD_STAR_OUTLINE "\xef\x81\xaf" // U+f06f +#define ICON_MD_STAR_PURPLE500 "\xef\x82\x9a" // U+f09a +#define ICON_MD_STAR_RATE "\xef\x83\xac" // U+f0ec +#define ICON_MD_STARS "\xee\xa3\x90" // U+e8d0 +#define ICON_MD_START "\xee\x82\x89" // U+e089 +#define ICON_MD_STAY_CURRENT_LANDSCAPE "\xee\x83\x93" // U+e0d3 +#define ICON_MD_STAY_CURRENT_PORTRAIT "\xee\x83\x94" // U+e0d4 +#define ICON_MD_STAY_PRIMARY_LANDSCAPE "\xee\x83\x95" // U+e0d5 +#define ICON_MD_STAY_PRIMARY_PORTRAIT "\xee\x83\x96" // U+e0d6 +#define ICON_MD_STICKY_NOTE_2 "\xef\x87\xbc" // U+f1fc +#define ICON_MD_STOP "\xee\x81\x87" // U+e047 +#define ICON_MD_STOP_CIRCLE "\xee\xbd\xb1" // U+ef71 +#define ICON_MD_STOP_SCREEN_SHARE "\xee\x83\xa3" // U+e0e3 +#define ICON_MD_STORAGE "\xee\x87\x9b" // U+e1db +#define ICON_MD_STORE "\xee\xa3\x91" // U+e8d1 +#define ICON_MD_STORE_MALL_DIRECTORY "\xee\x95\xa3" // U+e563 +#define ICON_MD_STOREFRONT "\xee\xa8\x92" // U+ea12 +#define ICON_MD_STORM "\xef\x81\xb0" // U+f070 +#define ICON_MD_STRAIGHT "\xee\xae\x95" // U+eb95 +#define ICON_MD_STRAIGHTEN "\xee\x90\x9c" // U+e41c +#define ICON_MD_STREAM "\xee\xa7\xa9" // U+e9e9 +#define ICON_MD_STREETVIEW "\xee\x95\xae" // U+e56e +#define ICON_MD_STRIKETHROUGH_S "\xee\x89\x97" // U+e257 +#define ICON_MD_STROLLER "\xef\x86\xae" // U+f1ae +#define ICON_MD_STYLE "\xee\x90\x9d" // U+e41d +#define ICON_MD_SUBDIRECTORY_ARROW_LEFT "\xee\x97\x99" // U+e5d9 +#define ICON_MD_SUBDIRECTORY_ARROW_RIGHT "\xee\x97\x9a" // U+e5da +#define ICON_MD_SUBJECT "\xee\xa3\x92" // U+e8d2 +#define ICON_MD_SUBSCRIPT "\xef\x84\x91" // U+f111 +#define ICON_MD_SUBSCRIPTIONS "\xee\x81\xa4" // U+e064 +#define ICON_MD_SUBTITLES "\xee\x81\x88" // U+e048 +#define ICON_MD_SUBTITLES_OFF "\xee\xbd\xb2" // U+ef72 +#define ICON_MD_SUBWAY "\xee\x95\xaf" // U+e56f +#define ICON_MD_SUMMARIZE "\xef\x81\xb1" // U+f071 +#define ICON_MD_SUNNY "\xee\xa0\x9a" // U+e81a +#define ICON_MD_SUNNY_SNOWING "\xee\xa0\x99" // U+e819 +#define ICON_MD_SUPERSCRIPT "\xef\x84\x92" // U+f112 +#define ICON_MD_SUPERVISED_USER_CIRCLE "\xee\xa4\xb9" // U+e939 +#define ICON_MD_SUPERVISOR_ACCOUNT "\xee\xa3\x93" // U+e8d3 +#define ICON_MD_SUPPORT "\xee\xbd\xb3" // U+ef73 +#define ICON_MD_SUPPORT_AGENT "\xef\x83\xa2" // U+f0e2 +#define ICON_MD_SURFING "\xee\x94\x95" // U+e515 +#define ICON_MD_SURROUND_SOUND "\xee\x81\x89" // U+e049 +#define ICON_MD_SWAP_CALLS "\xee\x83\x97" // U+e0d7 +#define ICON_MD_SWAP_HORIZ "\xee\xa3\x94" // U+e8d4 +#define ICON_MD_SWAP_HORIZONTAL_CIRCLE "\xee\xa4\xb3" // U+e933 +#define ICON_MD_SWAP_VERT "\xee\xa3\x95" // U+e8d5 +#define ICON_MD_SWAP_VERT_CIRCLE "\xee\xa3\x96" // U+e8d6 +#define ICON_MD_SWAP_VERTICAL_CIRCLE "\xee\xa3\x96" // U+e8d6 +#define ICON_MD_SWIPE "\xee\xa7\xac" // U+e9ec +#define ICON_MD_SWIPE_DOWN "\xee\xad\x93" // U+eb53 +#define ICON_MD_SWIPE_DOWN_ALT "\xee\xac\xb0" // U+eb30 +#define ICON_MD_SWIPE_LEFT "\xee\xad\x99" // U+eb59 +#define ICON_MD_SWIPE_LEFT_ALT "\xee\xac\xb3" // U+eb33 +#define ICON_MD_SWIPE_RIGHT "\xee\xad\x92" // U+eb52 +#define ICON_MD_SWIPE_RIGHT_ALT "\xee\xad\x96" // U+eb56 +#define ICON_MD_SWIPE_UP "\xee\xac\xae" // U+eb2e +#define ICON_MD_SWIPE_UP_ALT "\xee\xac\xb5" // U+eb35 +#define ICON_MD_SWIPE_VERTICAL "\xee\xad\x91" // U+eb51 +#define ICON_MD_SWITCH_ACCESS_SHORTCUT "\xee\x9f\xa1" // U+e7e1 +#define ICON_MD_SWITCH_ACCESS_SHORTCUT_ADD "\xee\x9f\xa2" // U+e7e2 +#define ICON_MD_SWITCH_ACCOUNT "\xee\xa7\xad" // U+e9ed +#define ICON_MD_SWITCH_CAMERA "\xee\x90\x9e" // U+e41e +#define ICON_MD_SWITCH_LEFT "\xef\x87\x91" // U+f1d1 +#define ICON_MD_SWITCH_RIGHT "\xef\x87\x92" // U+f1d2 +#define ICON_MD_SWITCH_VIDEO "\xee\x90\x9f" // U+e41f +#define ICON_MD_SYNAGOGUE "\xee\xaa\xb0" // U+eab0 +#define ICON_MD_SYNC "\xee\x98\xa7" // U+e627 +#define ICON_MD_SYNC_ALT "\xee\xa8\x98" // U+ea18 +#define ICON_MD_SYNC_DISABLED "\xee\x98\xa8" // U+e628 +#define ICON_MD_SYNC_LOCK "\xee\xab\xae" // U+eaee +#define ICON_MD_SYNC_PROBLEM "\xee\x98\xa9" // U+e629 +#define ICON_MD_SYSTEM_SECURITY_UPDATE "\xef\x81\xb2" // U+f072 +#define ICON_MD_SYSTEM_SECURITY_UPDATE_GOOD "\xef\x81\xb3" // U+f073 +#define ICON_MD_SYSTEM_SECURITY_UPDATE_WARNING "\xef\x81\xb4" // U+f074 +#define ICON_MD_SYSTEM_UPDATE "\xee\x98\xaa" // U+e62a +#define ICON_MD_SYSTEM_UPDATE_ALT "\xee\xa3\x97" // U+e8d7 +#define ICON_MD_SYSTEM_UPDATE_TV "\xee\xa3\x97" // U+e8d7 +#define ICON_MD_TAB "\xee\xa3\x98" // U+e8d8 +#define ICON_MD_TAB_UNSELECTED "\xee\xa3\x99" // U+e8d9 +#define ICON_MD_TABLE_BAR "\xee\xab\x92" // U+ead2 +#define ICON_MD_TABLE_CHART "\xee\x89\xa5" // U+e265 +#define ICON_MD_TABLE_RESTAURANT "\xee\xab\x86" // U+eac6 +#define ICON_MD_TABLE_ROWS "\xef\x84\x81" // U+f101 +#define ICON_MD_TABLE_VIEW "\xef\x86\xbe" // U+f1be +#define ICON_MD_TABLET "\xee\x8c\xaf" // U+e32f +#define ICON_MD_TABLET_ANDROID "\xee\x8c\xb0" // U+e330 +#define ICON_MD_TABLET_MAC "\xee\x8c\xb1" // U+e331 +#define ICON_MD_TAG "\xee\xa7\xaf" // U+e9ef +#define ICON_MD_TAG_FACES "\xee\x90\xa0" // U+e420 +#define ICON_MD_TAKEOUT_DINING "\xee\xa9\xb4" // U+ea74 +#define ICON_MD_TAP_AND_PLAY "\xee\x98\xab" // U+e62b +#define ICON_MD_TAPAS "\xef\x87\xa9" // U+f1e9 +#define ICON_MD_TASK "\xef\x81\xb5" // U+f075 +#define ICON_MD_TASK_ALT "\xee\x8b\xa6" // U+e2e6 +#define ICON_MD_TAXI_ALERT "\xee\xbd\xb4" // U+ef74 +#define ICON_MD_TELEGRAM "\xee\xa9\xab" // U+ea6b +#define ICON_MD_TEMPLE_BUDDHIST "\xee\xaa\xb3" // U+eab3 +#define ICON_MD_TEMPLE_HINDU "\xee\xaa\xaf" // U+eaaf +#define ICON_MD_TERMINAL "\xee\xae\x8e" // U+eb8e +#define ICON_MD_TERRAIN "\xee\x95\xa4" // U+e564 +#define ICON_MD_TEXT_DECREASE "\xee\xab\x9d" // U+eadd +#define ICON_MD_TEXT_FIELDS "\xee\x89\xa2" // U+e262 +#define ICON_MD_TEXT_FORMAT "\xee\x85\xa5" // U+e165 +#define ICON_MD_TEXT_INCREASE "\xee\xab\xa2" // U+eae2 +#define ICON_MD_TEXT_ROTATE_UP "\xee\xa4\xba" // U+e93a +#define ICON_MD_TEXT_ROTATE_VERTICAL "\xee\xa4\xbb" // U+e93b +#define ICON_MD_TEXT_ROTATION_ANGLEDOWN "\xee\xa4\xbc" // U+e93c +#define ICON_MD_TEXT_ROTATION_ANGLEUP "\xee\xa4\xbd" // U+e93d +#define ICON_MD_TEXT_ROTATION_DOWN "\xee\xa4\xbe" // U+e93e +#define ICON_MD_TEXT_ROTATION_NONE "\xee\xa4\xbf" // U+e93f +#define ICON_MD_TEXT_SNIPPET "\xef\x87\x86" // U+f1c6 +#define ICON_MD_TEXTSMS "\xee\x83\x98" // U+e0d8 +#define ICON_MD_TEXTURE "\xee\x90\xa1" // U+e421 +#define ICON_MD_THEATER_COMEDY "\xee\xa9\xa6" // U+ea66 +#define ICON_MD_THEATERS "\xee\xa3\x9a" // U+e8da +#define ICON_MD_THERMOSTAT "\xef\x81\xb6" // U+f076 +#define ICON_MD_THERMOSTAT_AUTO "\xef\x81\xb7" // U+f077 +#define ICON_MD_THUMB_DOWN "\xee\xa3\x9b" // U+e8db +#define ICON_MD_THUMB_DOWN_ALT "\xee\xa0\x96" // U+e816 +#define ICON_MD_THUMB_DOWN_OFF_ALT "\xee\xa7\xb2" // U+e9f2 +#define ICON_MD_THUMB_UP "\xee\xa3\x9c" // U+e8dc +#define ICON_MD_THUMB_UP_ALT "\xee\xa0\x97" // U+e817 +#define ICON_MD_THUMB_UP_OFF_ALT "\xee\xa7\xb3" // U+e9f3 +#define ICON_MD_THUMBS_UP_DOWN "\xee\xa3\x9d" // U+e8dd +#define ICON_MD_THUNDERSTORM "\xee\xaf\x9b" // U+ebdb +#define ICON_MD_TIKTOK "\xee\xa9\xbe" // U+ea7e +#define ICON_MD_TIME_TO_LEAVE "\xee\x98\xac" // U+e62c +#define ICON_MD_TIMELAPSE "\xee\x90\xa2" // U+e422 +#define ICON_MD_TIMELINE "\xee\xa4\xa2" // U+e922 +#define ICON_MD_TIMER "\xee\x90\xa5" // U+e425 +#define ICON_MD_TIMER_10 "\xee\x90\xa3" // U+e423 +#define ICON_MD_TIMER_10_SELECT "\xef\x81\xba" // U+f07a +#define ICON_MD_TIMER_3 "\xee\x90\xa4" // U+e424 +#define ICON_MD_TIMER_3_SELECT "\xef\x81\xbb" // U+f07b +#define ICON_MD_TIMER_OFF "\xee\x90\xa6" // U+e426 +#define ICON_MD_TIPS_AND_UPDATES "\xee\x9e\x9a" // U+e79a +#define ICON_MD_TIRE_REPAIR "\xee\xaf\x88" // U+ebc8 +#define ICON_MD_TITLE "\xee\x89\xa4" // U+e264 +#define ICON_MD_TOC "\xee\xa3\x9e" // U+e8de +#define ICON_MD_TODAY "\xee\xa3\x9f" // U+e8df +#define ICON_MD_TOGGLE_OFF "\xee\xa7\xb5" // U+e9f5 +#define ICON_MD_TOGGLE_ON "\xee\xa7\xb6" // U+e9f6 +#define ICON_MD_TOKEN "\xee\xa8\xa5" // U+ea25 +#define ICON_MD_TOLL "\xee\xa3\xa0" // U+e8e0 +#define ICON_MD_TONALITY "\xee\x90\xa7" // U+e427 +#define ICON_MD_TOPIC "\xef\x87\x88" // U+f1c8 +#define ICON_MD_TORNADO "\xee\x86\x99" // U+e199 +#define ICON_MD_TOUCH_APP "\xee\xa4\x93" // U+e913 +#define ICON_MD_TOUR "\xee\xbd\xb5" // U+ef75 +#define ICON_MD_TOYS "\xee\x8c\xb2" // U+e332 +#define ICON_MD_TRACK_CHANGES "\xee\xa3\xa1" // U+e8e1 +#define ICON_MD_TRAFFIC "\xee\x95\xa5" // U+e565 +#define ICON_MD_TRAIN "\xee\x95\xb0" // U+e570 +#define ICON_MD_TRAM "\xee\x95\xb1" // U+e571 +#define ICON_MD_TRANSFER_WITHIN_A_STATION "\xee\x95\xb2" // U+e572 +#define ICON_MD_TRANSFORM "\xee\x90\xa8" // U+e428 +#define ICON_MD_TRANSGENDER "\xee\x96\x8d" // U+e58d +#define ICON_MD_TRANSIT_ENTEREXIT "\xee\x95\xb9" // U+e579 +#define ICON_MD_TRANSLATE "\xee\xa3\xa2" // U+e8e2 +#define ICON_MD_TRAVEL_EXPLORE "\xee\x8b\x9b" // U+e2db +#define ICON_MD_TRENDING_DOWN "\xee\xa3\xa3" // U+e8e3 +#define ICON_MD_TRENDING_FLAT "\xee\xa3\xa4" // U+e8e4 +#define ICON_MD_TRENDING_NEUTRAL "\xee\xa3\xa4" // U+e8e4 +#define ICON_MD_TRENDING_UP "\xee\xa3\xa5" // U+e8e5 +#define ICON_MD_TRIP_ORIGIN "\xee\x95\xbb" // U+e57b +#define ICON_MD_TROUBLESHOOT "\xee\x87\x92" // U+e1d2 +#define ICON_MD_TRY "\xef\x81\xbc" // U+f07c +#define ICON_MD_TSUNAMI "\xee\xaf\x98" // U+ebd8 +#define ICON_MD_TTY "\xef\x86\xaa" // U+f1aa +#define ICON_MD_TUNE "\xee\x90\xa9" // U+e429 +#define ICON_MD_TUNGSTEN "\xef\x81\xbd" // U+f07d +#define ICON_MD_TURN_LEFT "\xee\xae\xa6" // U+eba6 +#define ICON_MD_TURN_RIGHT "\xee\xae\xab" // U+ebab +#define ICON_MD_TURN_SHARP_LEFT "\xee\xae\xa7" // U+eba7 +#define ICON_MD_TURN_SHARP_RIGHT "\xee\xae\xaa" // U+ebaa +#define ICON_MD_TURN_SLIGHT_LEFT "\xee\xae\xa4" // U+eba4 +#define ICON_MD_TURN_SLIGHT_RIGHT "\xee\xae\x9a" // U+eb9a +#define ICON_MD_TURNED_IN "\xee\xa3\xa6" // U+e8e6 +#define ICON_MD_TURNED_IN_NOT "\xee\xa3\xa7" // U+e8e7 +#define ICON_MD_TV "\xee\x8c\xb3" // U+e333 +#define ICON_MD_TV_OFF "\xee\x99\x87" // U+e647 +#define ICON_MD_TWO_WHEELER "\xee\xa7\xb9" // U+e9f9 +#define ICON_MD_U_TURN_LEFT "\xee\xae\xa1" // U+eba1 +#define ICON_MD_U_TURN_RIGHT "\xee\xae\xa2" // U+eba2 +#define ICON_MD_UMBRELLA "\xef\x86\xad" // U+f1ad +#define ICON_MD_UNARCHIVE "\xee\x85\xa9" // U+e169 +#define ICON_MD_UNDO "\xee\x85\xa6" // U+e166 +#define ICON_MD_UNFOLD_LESS "\xee\x97\x96" // U+e5d6 +#define ICON_MD_UNFOLD_MORE "\xee\x97\x97" // U+e5d7 +#define ICON_MD_UNPUBLISHED "\xef\x88\xb6" // U+f236 +#define ICON_MD_UNSUBSCRIBE "\xee\x83\xab" // U+e0eb +#define ICON_MD_UPCOMING "\xef\x81\xbe" // U+f07e +#define ICON_MD_UPDATE "\xee\xa4\xa3" // U+e923 +#define ICON_MD_UPDATE_DISABLED "\xee\x81\xb5" // U+e075 +#define ICON_MD_UPGRADE "\xef\x83\xbb" // U+f0fb +#define ICON_MD_UPLOAD "\xef\x82\x9b" // U+f09b +#define ICON_MD_UPLOAD_FILE "\xee\xa7\xbc" // U+e9fc +#define ICON_MD_USB "\xee\x87\xa0" // U+e1e0 +#define ICON_MD_USB_OFF "\xee\x93\xba" // U+e4fa +#define ICON_MD_VACCINES "\xee\x84\xb8" // U+e138 +#define ICON_MD_VAPE_FREE "\xee\xaf\x86" // U+ebc6 +#define ICON_MD_VAPING_ROOMS "\xee\xaf\x8f" // U+ebcf +#define ICON_MD_VERIFIED "\xee\xbd\xb6" // U+ef76 +#define ICON_MD_VERIFIED_USER "\xee\xa3\xa8" // U+e8e8 +#define ICON_MD_VERTICAL_ALIGN_BOTTOM "\xee\x89\x98" // U+e258 +#define ICON_MD_VERTICAL_ALIGN_CENTER "\xee\x89\x99" // U+e259 +#define ICON_MD_VERTICAL_ALIGN_TOP "\xee\x89\x9a" // U+e25a +#define ICON_MD_VERTICAL_DISTRIBUTE "\xee\x81\xb6" // U+e076 +#define ICON_MD_VERTICAL_SHADES "\xee\xb0\x8e" // U+ec0e +#define ICON_MD_VERTICAL_SHADES_CLOSED "\xee\xb0\x8d" // U+ec0d +#define ICON_MD_VERTICAL_SPLIT "\xee\xa5\x89" // U+e949 +#define ICON_MD_VIBRATION "\xee\x98\xad" // U+e62d +#define ICON_MD_VIDEO_CALL "\xee\x81\xb0" // U+e070 +#define ICON_MD_VIDEO_CAMERA_BACK "\xef\x81\xbf" // U+f07f +#define ICON_MD_VIDEO_CAMERA_FRONT "\xef\x82\x80" // U+f080 +#define ICON_MD_VIDEO_COLLECTION "\xee\x81\x8a" // U+e04a +#define ICON_MD_VIDEO_FILE "\xee\xae\x87" // U+eb87 +#define ICON_MD_VIDEO_LABEL "\xee\x81\xb1" // U+e071 +#define ICON_MD_VIDEO_LIBRARY "\xee\x81\x8a" // U+e04a +#define ICON_MD_VIDEO_SETTINGS "\xee\xa9\xb5" // U+ea75 +#define ICON_MD_VIDEO_STABLE "\xef\x82\x81" // U+f081 +#define ICON_MD_VIDEOCAM "\xee\x81\x8b" // U+e04b +#define ICON_MD_VIDEOCAM_OFF "\xee\x81\x8c" // U+e04c +#define ICON_MD_VIDEOGAME_ASSET "\xee\x8c\xb8" // U+e338 +#define ICON_MD_VIDEOGAME_ASSET_OFF "\xee\x94\x80" // U+e500 +#define ICON_MD_VIEW_AGENDA "\xee\xa3\xa9" // U+e8e9 +#define ICON_MD_VIEW_ARRAY "\xee\xa3\xaa" // U+e8ea +#define ICON_MD_VIEW_CAROUSEL "\xee\xa3\xab" // U+e8eb +#define ICON_MD_VIEW_COLUMN "\xee\xa3\xac" // U+e8ec +#define ICON_MD_VIEW_COMFORTABLE "\xee\x90\xaa" // U+e42a +#define ICON_MD_VIEW_COMFY "\xee\x90\xaa" // U+e42a +#define ICON_MD_VIEW_COMFY_ALT "\xee\xad\xb3" // U+eb73 +#define ICON_MD_VIEW_COMPACT "\xee\x90\xab" // U+e42b +#define ICON_MD_VIEW_COMPACT_ALT "\xee\xad\xb4" // U+eb74 +#define ICON_MD_VIEW_COZY "\xee\xad\xb5" // U+eb75 +#define ICON_MD_VIEW_DAY "\xee\xa3\xad" // U+e8ed +#define ICON_MD_VIEW_HEADLINE "\xee\xa3\xae" // U+e8ee +#define ICON_MD_VIEW_IN_AR "\xee\xa7\xbe" // U+e9fe +#define ICON_MD_VIEW_KANBAN "\xee\xad\xbf" // U+eb7f +#define ICON_MD_VIEW_LIST "\xee\xa3\xaf" // U+e8ef +#define ICON_MD_VIEW_MODULE "\xee\xa3\xb0" // U+e8f0 +#define ICON_MD_VIEW_QUILT "\xee\xa3\xb1" // U+e8f1 +#define ICON_MD_VIEW_SIDEBAR "\xef\x84\x94" // U+f114 +#define ICON_MD_VIEW_STREAM "\xee\xa3\xb2" // U+e8f2 +#define ICON_MD_VIEW_TIMELINE "\xee\xae\x85" // U+eb85 +#define ICON_MD_VIEW_WEEK "\xee\xa3\xb3" // U+e8f3 +#define ICON_MD_VIGNETTE "\xee\x90\xb5" // U+e435 +#define ICON_MD_VILLA "\xee\x96\x86" // U+e586 +#define ICON_MD_VISIBILITY "\xee\xa3\xb4" // U+e8f4 +#define ICON_MD_VISIBILITY_OFF "\xee\xa3\xb5" // U+e8f5 +#define ICON_MD_VOICE_CHAT "\xee\x98\xae" // U+e62e +#define ICON_MD_VOICE_OVER_OFF "\xee\xa5\x8a" // U+e94a +#define ICON_MD_VOICEMAIL "\xee\x83\x99" // U+e0d9 +#define ICON_MD_VOLCANO "\xee\xaf\x9a" // U+ebda +#define ICON_MD_VOLUME_DOWN "\xee\x81\x8d" // U+e04d +#define ICON_MD_VOLUME_DOWN_ALT "\xee\x9e\x9c" // U+e79c +#define ICON_MD_VOLUME_MUTE "\xee\x81\x8e" // U+e04e +#define ICON_MD_VOLUME_OFF "\xee\x81\x8f" // U+e04f +#define ICON_MD_VOLUME_UP "\xee\x81\x90" // U+e050 +#define ICON_MD_VOLUNTEER_ACTIVISM "\xee\xa9\xb0" // U+ea70 +#define ICON_MD_VPN_KEY "\xee\x83\x9a" // U+e0da +#define ICON_MD_VPN_KEY_OFF "\xee\xad\xba" // U+eb7a +#define ICON_MD_VPN_LOCK "\xee\x98\xaf" // U+e62f +#define ICON_MD_VRPANO "\xef\x82\x82" // U+f082 +#define ICON_MD_WALLET "\xef\xa3\xbf" // U+f8ff +#define ICON_MD_WALLET_GIFTCARD "\xee\xa3\xb6" // U+e8f6 +#define ICON_MD_WALLET_MEMBERSHIP "\xee\xa3\xb7" // U+e8f7 +#define ICON_MD_WALLET_TRAVEL "\xee\xa3\xb8" // U+e8f8 +#define ICON_MD_WALLPAPER "\xee\x86\xbc" // U+e1bc +#define ICON_MD_WAREHOUSE "\xee\xae\xb8" // U+ebb8 +#define ICON_MD_WARNING "\xee\x80\x82" // U+e002 +#define ICON_MD_WARNING_AMBER "\xef\x82\x83" // U+f083 +#define ICON_MD_WASH "\xef\x86\xb1" // U+f1b1 +#define ICON_MD_WATCH "\xee\x8c\xb4" // U+e334 +#define ICON_MD_WATCH_LATER "\xee\xa4\xa4" // U+e924 +#define ICON_MD_WATCH_OFF "\xee\xab\xa3" // U+eae3 +#define ICON_MD_WATER "\xef\x82\x84" // U+f084 +#define ICON_MD_WATER_DAMAGE "\xef\x88\x83" // U+f203 +#define ICON_MD_WATER_DROP "\xee\x9e\x98" // U+e798 +#define ICON_MD_WATERFALL_CHART "\xee\xa8\x80" // U+ea00 +#define ICON_MD_WAVES "\xee\x85\xb6" // U+e176 +#define ICON_MD_WAVING_HAND "\xee\x9d\xa6" // U+e766 +#define ICON_MD_WB_AUTO "\xee\x90\xac" // U+e42c +#define ICON_MD_WB_CLOUDY "\xee\x90\xad" // U+e42d +#define ICON_MD_WB_INCANDESCENT "\xee\x90\xae" // U+e42e +#define ICON_MD_WB_IRIDESCENT "\xee\x90\xb6" // U+e436 +#define ICON_MD_WB_SHADE "\xee\xa8\x81" // U+ea01 +#define ICON_MD_WB_SUNNY "\xee\x90\xb0" // U+e430 +#define ICON_MD_WB_TWIGHLIGHT "\xee\xa8\x82" // U+ea02 +#define ICON_MD_WB_TWILIGHT "\xee\x87\x86" // U+e1c6 +#define ICON_MD_WC "\xee\x98\xbd" // U+e63d +#define ICON_MD_WEB "\xee\x81\x91" // U+e051 +#define ICON_MD_WEB_ASSET "\xee\x81\xa9" // U+e069 +#define ICON_MD_WEB_ASSET_OFF "\xee\x93\xb7" // U+e4f7 +#define ICON_MD_WEB_STORIES "\xee\x96\x95" // U+e595 +#define ICON_MD_WEBHOOK "\xee\xae\x92" // U+eb92 +#define ICON_MD_WECHAT "\xee\xaa\x81" // U+ea81 +#define ICON_MD_WEEKEND "\xee\x85\xab" // U+e16b +#define ICON_MD_WEST "\xef\x87\xa6" // U+f1e6 +#define ICON_MD_WHATSAPP "\xee\xaa\x9c" // U+ea9c +#define ICON_MD_WHATSHOT "\xee\xa0\x8e" // U+e80e +#define ICON_MD_WHEELCHAIR_PICKUP "\xef\x86\xab" // U+f1ab +#define ICON_MD_WHERE_TO_VOTE "\xee\x85\xb7" // U+e177 +#define ICON_MD_WIDGETS "\xee\x86\xbd" // U+e1bd +#define ICON_MD_WIDTH_FULL "\xef\xa3\xb5" // U+f8f5 +#define ICON_MD_WIDTH_NORMAL "\xef\xa3\xb6" // U+f8f6 +#define ICON_MD_WIDTH_WIDE "\xef\xa3\xb7" // U+f8f7 +#define ICON_MD_WIFI "\xee\x98\xbe" // U+e63e +#define ICON_MD_WIFI_1_BAR "\xee\x93\x8a" // U+e4ca +#define ICON_MD_WIFI_2_BAR "\xee\x93\x99" // U+e4d9 +#define ICON_MD_WIFI_CALLING "\xee\xbd\xb7" // U+ef77 +#define ICON_MD_WIFI_CALLING_3 "\xef\x82\x85" // U+f085 +#define ICON_MD_WIFI_CHANNEL "\xee\xad\xaa" // U+eb6a +#define ICON_MD_WIFI_FIND "\xee\xac\xb1" // U+eb31 +#define ICON_MD_WIFI_LOCK "\xee\x87\xa1" // U+e1e1 +#define ICON_MD_WIFI_OFF "\xee\x99\x88" // U+e648 +#define ICON_MD_WIFI_PASSWORD "\xee\xad\xab" // U+eb6b +#define ICON_MD_WIFI_PROTECTED_SETUP "\xef\x83\xbc" // U+f0fc +#define ICON_MD_WIFI_TETHERING "\xee\x87\xa2" // U+e1e2 +#define ICON_MD_WIFI_TETHERING_ERROR "\xee\xab\x99" // U+ead9 +#define ICON_MD_WIFI_TETHERING_ERROR_ROUNDED "\xef\x82\x86" // U+f086 +#define ICON_MD_WIFI_TETHERING_OFF "\xef\x82\x87" // U+f087 +#define ICON_MD_WIND_POWER "\xee\xb0\x8c" // U+ec0c +#define ICON_MD_WINDOW "\xef\x82\x88" // U+f088 +#define ICON_MD_WINE_BAR "\xef\x87\xa8" // U+f1e8 +#define ICON_MD_WOMAN "\xee\x84\xbe" // U+e13e +#define ICON_MD_WOO_COMMERCE "\xee\xa9\xad" // U+ea6d +#define ICON_MD_WORDPRESS "\xee\xaa\x9f" // U+ea9f +#define ICON_MD_WORK "\xee\xa3\xb9" // U+e8f9 +#define ICON_MD_WORK_HISTORY "\xee\xb0\x89" // U+ec09 +#define ICON_MD_WORK_OFF "\xee\xa5\x82" // U+e942 +#define ICON_MD_WORK_OUTLINE "\xee\xa5\x83" // U+e943 +#define ICON_MD_WORKSPACE_PREMIUM "\xee\x9e\xaf" // U+e7af +#define ICON_MD_WORKSPACES "\xee\x86\xa0" // U+e1a0 +#define ICON_MD_WORKSPACES_FILLED "\xee\xa8\x8d" // U+ea0d +#define ICON_MD_WORKSPACES_OUTLINE "\xee\xa8\x8f" // U+ea0f +#define ICON_MD_WRAP_TEXT "\xee\x89\x9b" // U+e25b +#define ICON_MD_WRONG_LOCATION "\xee\xbd\xb8" // U+ef78 +#define ICON_MD_WYSIWYG "\xef\x87\x83" // U+f1c3 +#define ICON_MD_YARD "\xef\x82\x89" // U+f089 +#define ICON_MD_YOUTUBE_SEARCHED_FOR "\xee\xa3\xba" // U+e8fa +#define ICON_MD_ZOOM_IN "\xee\xa3\xbf" // U+e8ff +#define ICON_MD_ZOOM_IN_MAP "\xee\xac\xad" // U+eb2d +#define ICON_MD_ZOOM_OUT "\xee\xa4\x80" // U+e900 +#define ICON_MD_ZOOM_OUT_MAP "\xee\x95\xab" // U+e56b diff --git a/src/gui/input.cc b/src/gui/input.cc new file mode 100644 index 00000000..add939c9 --- /dev/null +++ b/src/gui/input.cc @@ -0,0 +1,70 @@ +#include "input.h" + +#include +#include + +#include "absl/strings/string_view.h" + +namespace yaze { +namespace gui { + +const int kStepOneHex = 0x01; +const int kStepFastHex = 0x0F; + +bool InputHex(const char* label, int* data) { + return ImGui::InputScalar(label, ImGuiDataType_U64, data, &kStepOneHex, + &kStepFastHex, "%06X", + ImGuiInputTextFlags_CharsHexadecimal); +} + +bool InputHexShort(const char* label, int* data) { + return ImGui::InputScalar(label, ImGuiDataType_U32, data, &kStepOneHex, + &kStepFastHex, "%06X", + ImGuiInputTextFlags_CharsHexadecimal); +} + +void ItemLabel(absl::string_view title, ItemLabelFlags flags) { + ImGuiWindow* window = ImGui::GetCurrentWindow(); + const ImVec2 lineStart = ImGui::GetCursorScreenPos(); + const ImGuiStyle& style = ImGui::GetStyle(); + float fullWidth = ImGui::GetContentRegionAvail().x; + float itemWidth = ImGui::CalcItemWidth() + style.ItemSpacing.x; + ImVec2 textSize = ImGui::CalcTextSize(title.begin(), title.end()); + ImRect textRect; + textRect.Min = ImGui::GetCursorScreenPos(); + if (flags & ItemLabelFlag::Right) textRect.Min.x = textRect.Min.x + itemWidth; + textRect.Max = textRect.Min; + textRect.Max.x += fullWidth - itemWidth; + textRect.Max.y += textSize.y; + + ImGui::SetCursorScreenPos(textRect.Min); + + ImGui::AlignTextToFramePadding(); + // Adjust text rect manually because we render it directly into a drawlist + // instead of using public functions. + textRect.Min.y += window->DC.CurrLineTextBaseOffset; + textRect.Max.y += window->DC.CurrLineTextBaseOffset; + + ImGui::ItemSize(textRect); + if (ImGui::ItemAdd( + textRect, window->GetID(title.data(), title.data() + title.size()))) { + ImGui::RenderTextEllipsis( + ImGui::GetWindowDrawList(), textRect.Min, textRect.Max, textRect.Max.x, + textRect.Max.x, title.data(), title.data() + title.size(), &textSize); + + if (textRect.GetWidth() < textSize.x && ImGui::IsItemHovered()) + ImGui::SetTooltip("%.*s", (int)title.size(), title.data()); + } + if (flags & ItemLabelFlag::Left) { + ImVec2 result; + auto other = ImVec2{0, textSize.y + window->DC.CurrLineTextBaseOffset}; + result.x = textRect.Max.x - other.x; + result.y = textRect.Max.y - other.y; + ImGui::SetCursorScreenPos(result); + ImGui::SameLine(); + } else if (flags & ItemLabelFlag::Right) + ImGui::SetCursorScreenPos(lineStart); +} + +} // namespace gui +} // namespace yaze diff --git a/src/gui/input.h b/src/gui/input.h new file mode 100644 index 00000000..11be3f2f --- /dev/null +++ b/src/gui/input.h @@ -0,0 +1,29 @@ +#ifndef YAZE_APP_CORE_INPUT_H +#define YAZE_APP_CORE_INPUT_H + +#include +#include + +#include +#include + +#include "absl/strings/string_view.h" + +namespace yaze { +namespace gui { + +IMGUI_API bool InputHex(const char* label, int* data); +IMGUI_API bool InputHexShort(const char* label, int* data); + +using ItemLabelFlags = enum ItemLabelFlag { + Left = 1u << 0u, + Right = 1u << 1u, + Default = Left, +}; + +IMGUI_API void ItemLabel(absl::string_view title, ItemLabelFlags flags); + +} // namespace gui +} // namespace yaze + +#endif \ No newline at end of file diff --git a/src/gui/style.cc b/src/gui/style.cc new file mode 100644 index 00000000..2e22b55a --- /dev/null +++ b/src/gui/style.cc @@ -0,0 +1,108 @@ +#include "style.h" + +#include "imgui/imgui.h" +#include "imgui/imgui_internal.h" + +namespace yaze { +namespace gui { + +void ColorsYaze() { + ImGuiStyle *style = &ImGui::GetStyle(); + ImVec4 *colors = style->Colors; + + style->WindowPadding = ImVec2(10.f, 10.f); + style->FramePadding = ImVec2(10.f, 3.f); + style->CellPadding = ImVec2(4.f, 5.f); + style->ItemSpacing = ImVec2(10.f, 5.f); + style->ItemInnerSpacing = ImVec2(5.f, 5.f); + style->TouchExtraPadding = ImVec2(0.f, 0.f); + style->IndentSpacing = 20.f; + style->ScrollbarSize = 14.f; + style->GrabMinSize = 15.f; + + style->WindowBorderSize = 0.f; + style->ChildBorderSize = 1.f; + style->PopupBorderSize = 1.f; + style->FrameBorderSize = 0.f; + style->TabBorderSize = 0.f; + + style->WindowRounding = 0.f; + style->ChildRounding = 0.f; + style->FrameRounding = 5.f; + style->PopupRounding = 0.f; + style->ScrollbarRounding = 5.f; + + auto alttpDarkGreen = ImVec4(0.18f, 0.26f, 0.18f, 1.0f); + auto alttpMidGreen = ImVec4(0.28f, 0.36f, 0.28f, 1.0f); + auto allttpLightGreen = ImVec4(0.36f, 0.45f, 0.36f, 1.0f); + auto allttpLightestGreen = ImVec4(0.49f, 0.57f, 0.49f, 1.0f); + + colors[ImGuiCol_MenuBarBg] = alttpDarkGreen; + colors[ImGuiCol_TitleBg] = alttpMidGreen; + + colors[ImGuiCol_Header] = alttpDarkGreen; + colors[ImGuiCol_HeaderHovered] = allttpLightGreen; + colors[ImGuiCol_HeaderActive] = alttpMidGreen; + + colors[ImGuiCol_TitleBgActive] = alttpDarkGreen; + colors[ImGuiCol_TitleBgCollapsed] = alttpMidGreen; + + colors[ImGuiCol_Tab] = alttpDarkGreen; + colors[ImGuiCol_TabHovered] = alttpMidGreen; + colors[ImGuiCol_TabActive] = ImVec4(0.347f, 0.466f, 0.347f, 1.000f); + + colors[ImGuiCol_Button] = alttpMidGreen; + colors[ImGuiCol_ButtonHovered] = allttpLightestGreen; + colors[ImGuiCol_ButtonActive] = allttpLightGreen; + + colors[ImGuiCol_ScrollbarBg] = ImVec4(0.36f, 0.45f, 0.36f, 0.60f); + colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.36f, 0.45f, 0.36f, 0.30f); + colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.36f, 0.45f, 0.36f, 0.40f); + colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.36f, 0.45f, 0.36f, 0.60f); + + colors[ImGuiCol_Text] = ImVec4(0.90f, 0.90f, 0.90f, 1.00f); + colors[ImGuiCol_TextDisabled] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f); + colors[ImGuiCol_WindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.85f); + colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + colors[ImGuiCol_PopupBg] = ImVec4(0.11f, 0.11f, 0.14f, 0.92f); + colors[ImGuiCol_Border] = allttpLightGreen; + colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + + colors[ImGuiCol_FrameBg] = ImVec4(0.43f, 0.43f, 0.43f, 0.39f); + colors[ImGuiCol_FrameBgHovered] = ImVec4(0.28f, 0.36f, 0.28f, 0.40f); + colors[ImGuiCol_FrameBgActive] = ImVec4(0.28f, 0.36f, 0.28f, 0.69f); + + colors[ImGuiCol_CheckMark] = ImVec4(0.90f, 0.90f, 0.90f, 0.50f); + colors[ImGuiCol_SliderGrab] = ImVec4(1.00f, 1.00f, 1.00f, 0.30f); + colors[ImGuiCol_SliderGrabActive] = ImVec4(0.36f, 0.45f, 0.36f, 0.60f); + + colors[ImGuiCol_Separator] = ImVec4(0.50f, 0.50f, 0.50f, 0.60f); + colors[ImGuiCol_SeparatorHovered] = ImVec4(0.60f, 0.60f, 0.70f, 1.00f); + colors[ImGuiCol_SeparatorActive] = ImVec4(0.70f, 0.70f, 0.90f, 1.00f); + colors[ImGuiCol_ResizeGrip] = ImVec4(1.00f, 1.00f, 1.00f, 0.10f); + colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.78f, 0.82f, 1.00f, 0.60f); + colors[ImGuiCol_ResizeGripActive] = ImVec4(0.78f, 0.82f, 1.00f, 0.90f); + + colors[ImGuiCol_TabUnfocused] = + ImLerp(colors[ImGuiCol_Tab], colors[ImGuiCol_TitleBg], 0.80f); + colors[ImGuiCol_TabUnfocusedActive] = + ImLerp(colors[ImGuiCol_TabActive], colors[ImGuiCol_TitleBg], 0.40f); + colors[ImGuiCol_PlotLines] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); + colors[ImGuiCol_PlotLinesHovered] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); + colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); + colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f); + colors[ImGuiCol_TableHeaderBg] = alttpDarkGreen; + colors[ImGuiCol_TableBorderStrong] = alttpMidGreen; + colors[ImGuiCol_TableBorderLight] = + ImVec4(0.26f, 0.26f, 0.28f, 1.00f); // Prefer using Alpha=1.0 here + colors[ImGuiCol_TableRowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + colors[ImGuiCol_TableRowBgAlt] = ImVec4(1.00f, 1.00f, 1.00f, 0.07f); + colors[ImGuiCol_TextSelectedBg] = ImVec4(0.00f, 0.00f, 1.00f, 0.35f); + colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f); + colors[ImGuiCol_NavHighlight] = colors[ImGuiCol_HeaderHovered]; + colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f); + colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.20f); + colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.20f, 0.20f, 0.20f, 0.35f); +} +} // namespace gui +} // namespace yaze \ No newline at end of file diff --git a/src/gui/style.h b/src/gui/style.h new file mode 100644 index 00000000..7f64b582 --- /dev/null +++ b/src/gui/style.h @@ -0,0 +1,15 @@ +#ifndef YAZE_APP_CORE_STYLE_H +#define YAZE_APP_CORE_STYLE_H + +#include +#include + +namespace yaze { +namespace gui { + +void ColorsYaze(); + +} // namespace gui +} // namespace yaze + +#endif \ No newline at end of file diff --git a/src/gui/widgets.cc b/src/gui/widgets.cc new file mode 100644 index 00000000..a3b54e3f --- /dev/null +++ b/src/gui/widgets.cc @@ -0,0 +1,68 @@ +#include "widgets.h" + +#include + +#include "absl/status/status.h" +#include "app/core/constants.h" + +namespace yaze { +namespace gui { +namespace widgets { + +TextEditor::LanguageDefinition GetAssemblyLanguageDef() { + TextEditor::LanguageDefinition language_65816; + for (auto &k : app::core::kKeywords) language_65816.mKeywords.emplace(k); + + for (auto &k : app::core::kIdentifiers) { + TextEditor::Identifier id; + id.mDeclaration = "Built-in function"; + language_65816.mIdentifiers.insert(std::make_pair(std::string(k), id)); + } + + language_65816.mTokenRegexStrings.push_back( + std::make_pair( + "[ \\t]*#[ \\t]*[a-zA-Z_]+", TextEditor::PaletteIndex::Preprocessor)); + language_65816.mTokenRegexStrings.push_back( + std::make_pair( + "L?\\\"(\\\\.|[^\\\"])*\\\"", TextEditor::PaletteIndex::String)); + language_65816.mTokenRegexStrings.push_back( + std::make_pair( + "\\'\\\\?[^\\']\\'", TextEditor::PaletteIndex::CharLiteral)); + language_65816.mTokenRegexStrings.push_back( + std::make_pair( + "[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)([eE][+-]?[0-9]+)?[fF]?", + TextEditor::PaletteIndex::Number)); + language_65816.mTokenRegexStrings.push_back( + std::make_pair( + "[+-]?[0-9]+[Uu]?[lL]?[lL]?", TextEditor::PaletteIndex::Number)); + language_65816.mTokenRegexStrings.push_back( + std::make_pair( + "0[0-7]+[Uu]?[lL]?[lL]?", TextEditor::PaletteIndex::Number)); + language_65816.mTokenRegexStrings.push_back( + std::make_pair( + "0[xX][0-9a-fA-F]+[uU]?[lL]?[lL]?", + TextEditor::PaletteIndex::Number)); + language_65816.mTokenRegexStrings.push_back( + std::make_pair( + "[a-zA-Z_][a-zA-Z0-9_]*", TextEditor::PaletteIndex::Identifier)); + language_65816.mTokenRegexStrings.push_back( + std::make_pair( + "[\\[\\]\\{\\}\\!\\%\\^\\&\\*\\(\\)\\-\\+\\=\\~\\|\\<\\>\\?\\/" + "\\;\\,\\.]", + TextEditor::PaletteIndex::Punctuation)); + + language_65816.mCommentStart = "/*"; + language_65816.mCommentEnd = "*/"; + language_65816.mSingleLineComment = ";"; + + language_65816.mCaseSensitive = false; + language_65816.mAutoIndentation = true; + + language_65816.mName = "65816"; + + return language_65816; +} + +} // namespace widgets +} // namespace gui +} // namespace yaze diff --git a/src/gui/widgets.h b/src/gui/widgets.h new file mode 100644 index 00000000..69bf15b9 --- /dev/null +++ b/src/gui/widgets.h @@ -0,0 +1,19 @@ +#ifndef YAZE_GUI_WIDGETS_H +#define YAZE_GUI_WIDGETS_H + +#include + +#include "absl/status/status.h" +#include "app/core/constants.h" + +namespace yaze { +namespace gui { +namespace widgets { + +TextEditor::LanguageDefinition GetAssemblyLanguageDef(); + +} // namespace widgets +} // namespace gui +} // namespace yaze + +#endif \ No newline at end of file diff --git a/src/lib/ImGuiColorTextEdit b/src/lib/ImGuiColorTextEdit new file mode 160000 index 00000000..0a88824f --- /dev/null +++ b/src/lib/ImGuiColorTextEdit @@ -0,0 +1 @@ +Subproject commit 0a88824f7de8d0bd11d8419066caa7d3469395c4 diff --git a/src/lib/ImGuiFileDialog b/src/lib/ImGuiFileDialog new file mode 160000 index 00000000..af4800e8 --- /dev/null +++ b/src/lib/ImGuiFileDialog @@ -0,0 +1 @@ +Subproject commit af4800e85a79154c8c08cf28d4cfee82bdc0cd03 diff --git a/src/lib/SDL b/src/lib/SDL new file mode 160000 index 00000000..5b904a10 --- /dev/null +++ b/src/lib/SDL @@ -0,0 +1 @@ +Subproject commit 5b904a103ad3bd58c13c82b11e32e97a91bafcfb diff --git a/src/lib/SDL_mixer b/src/lib/SDL_mixer new file mode 160000 index 00000000..7f73f724 --- /dev/null +++ b/src/lib/SDL_mixer @@ -0,0 +1 @@ +Subproject commit 7f73f724f2097e457cd7cfe3323a876670e79daf diff --git a/src/lib/abseil-cpp b/src/lib/abseil-cpp new file mode 160000 index 00000000..8c0b94e7 --- /dev/null +++ b/src/lib/abseil-cpp @@ -0,0 +1 @@ +Subproject commit 8c0b94e793a66495e0b1f34a5eb26bd7dc672db0 diff --git a/src/lib/asar b/src/lib/asar new file mode 160000 index 00000000..634d6baf --- /dev/null +++ b/src/lib/asar @@ -0,0 +1 @@ +Subproject commit 634d6baf7ad073ef01055c9f0ce923636738d2a7 diff --git a/src/lib/imgui b/src/lib/imgui new file mode 160000 index 00000000..e57871bb --- /dev/null +++ b/src/lib/imgui @@ -0,0 +1 @@ +Subproject commit e57871bb95faec757e51214bc0e1ae29b13258ab diff --git a/src/lib/imgui_memory_editor.h b/src/lib/imgui_memory_editor.h new file mode 100644 index 00000000..ec770db8 --- /dev/null +++ b/src/lib/imgui_memory_editor.h @@ -0,0 +1,742 @@ +// Mini memory editor for Dear ImGui (to embed in your game/tools) +// Get latest version at http://www.github.com/ocornut/imgui_club +// +// Right-click anywhere to access the Options menu! +// You can adjust the keyboard repeat delay/rate in ImGuiIO. +// The code assume a mono-space font for simplicity! +// If you don't use the default font, use ImGui::PushFont()/PopFont() to switch to a mono-space font before calling this. +// +// Usage: +// // Create a window and draw memory editor inside it: +// static MemoryEditor mem_edit_1; +// static char data[0x10000]; +// size_t data_size = 0x10000; +// mem_edit_1.DrawWindow("Memory Editor", data, data_size); +// +// Usage: +// // If you already have a window, use DrawContents() instead: +// static MemoryEditor mem_edit_2; +// ImGui::Begin("MyWindow") +// mem_edit_2.DrawContents(this, sizeof(*this), (size_t)this); +// ImGui::End(); +// +// Changelog: +// - v0.10: initial version +// - v0.23 (2017/08/17): added to github. fixed right-arrow triggering a byte write. +// - v0.24 (2018/06/02): changed DragInt("Rows" to use a %d data format (which is desirable since imgui 1.61). +// - v0.25 (2018/07/11): fixed wording: all occurrences of "Rows" renamed to "Columns". +// - v0.26 (2018/08/02): fixed clicking on hex region +// - v0.30 (2018/08/02): added data preview for common data types +// - v0.31 (2018/10/10): added OptUpperCaseHex option to select lower/upper casing display [@samhocevar] +// - v0.32 (2018/10/10): changed signatures to use void* instead of unsigned char* +// - v0.33 (2018/10/10): added OptShowOptions option to hide all the interactive option setting. +// - v0.34 (2019/05/07): binary preview now applies endianness setting [@nicolasnoble] +// - v0.35 (2020/01/29): using ImGuiDataType available since Dear ImGui 1.69. +// - v0.36 (2020/05/05): minor tweaks, minor refactor. +// - v0.40 (2020/10/04): fix misuse of ImGuiListClipper API, broke with Dear ImGui 1.79. made cursor position appears on left-side of edit box. option popup appears on mouse release. fix MSVC warnings where _CRT_SECURE_NO_WARNINGS wasn't working in recent versions. +// - v0.41 (2020/10/05): fix when using with keyboard/gamepad navigation enabled. +// - v0.42 (2020/10/14): fix for . character in ASCII view always being greyed out. +// - v0.43 (2021/03/12): added OptFooterExtraHeight to allow for custom drawing at the bottom of the editor [@leiradel] +// - v0.44 (2021/03/12): use ImGuiInputTextFlags_AlwaysOverwrite in 1.82 + fix hardcoded width. +// - v0.50 (2021/11/12): various fixes for recent dear imgui versions (fixed misuse of clipper, relying on SetKeyboardFocusHere() handling scrolling from 1.85). added default size. +// +// Todo/Bugs: +// - This is generally old/crappy code, it should work but isn't very good.. to be rewritten some day. +// - PageUp/PageDown are supported because we use _NoNav. This is a good test scenario for working out idioms of how to mix natural nav and our own... +// - Arrows are being sent to the InputText() about to disappear which for LeftArrow makes the text cursor appear at position 1 for one frame. +// - Using InputText() is awkward and maybe overkill here, consider implementing something custom. + +#pragma once + +#include // sprintf, scanf +#include // uint8_t, etc. + +#ifdef _MSC_VER +#define _PRISizeT "I" +#define ImSnprintf _snprintf +#else +#define _PRISizeT "z" +#define ImSnprintf snprintf +#endif + +#ifdef _MSC_VER +#pragma warning (push) +#pragma warning (disable: 4996) // warning C4996: 'sprintf': This function or variable may be unsafe. +#endif + +struct MemoryEditor +{ + enum DataFormat + { + DataFormat_Bin = 0, + DataFormat_Dec = 1, + DataFormat_Hex = 2, + DataFormat_COUNT + }; + + // Settings + bool Open; // = true // set to false when DrawWindow() was closed. ignore if not using DrawWindow(). + bool ReadOnly; // = false // disable any editing. + int Cols; // = 16 // number of columns to display. + bool OptShowOptions; // = true // display options button/context menu. when disabled, options will be locked unless you provide your own UI for them. + bool OptShowDataPreview; // = false // display a footer previewing the decimal/binary/hex/float representation of the currently selected bytes. + bool OptShowHexII; // = false // display values in HexII representation instead of regular hexadecimal: hide null/zero bytes, ascii values as ".X". + bool OptShowAscii; // = true // display ASCII representation on the right side. + bool OptGreyOutZeroes; // = true // display null/zero bytes using the TextDisabled color. + bool OptUpperCaseHex; // = true // display hexadecimal values as "FF" instead of "ff". + int OptMidColsCount; // = 8 // set to 0 to disable extra spacing between every mid-cols. + int OptAddrDigitsCount; // = 0 // number of addr digits to display (default calculated based on maximum displayed addr). + float OptFooterExtraHeight; // = 0 // space to reserve at the bottom of the widget to add custom widgets + ImU32 HighlightColor; // // background color of highlighted bytes. + ImU8 (*ReadFn)(const ImU8* data, size_t off); // = 0 // optional handler to read bytes. + void (*WriteFn)(ImU8* data, size_t off, ImU8 d); // = 0 // optional handler to write bytes. + bool (*HighlightFn)(const ImU8* data, size_t off);//= 0 // optional handler to return Highlight property (to support non-contiguous highlighting). + + // [Internal State] + bool ContentsWidthChanged; + size_t DataPreviewAddr; + size_t DataEditingAddr; + bool DataEditingTakeFocus; + char DataInputBuf[32]; + char AddrInputBuf[32]; + size_t GotoAddr; + size_t HighlightMin, HighlightMax; + int PreviewEndianess; + ImGuiDataType PreviewDataType; + + MemoryEditor() + { + // Settings + Open = true; + ReadOnly = false; + Cols = 16; + OptShowOptions = true; + OptShowDataPreview = false; + OptShowHexII = false; + OptShowAscii = true; + OptGreyOutZeroes = true; + OptUpperCaseHex = true; + OptMidColsCount = 8; + OptAddrDigitsCount = 0; + OptFooterExtraHeight = 0.0f; + HighlightColor = IM_COL32(255, 255, 255, 50); + ReadFn = NULL; + WriteFn = NULL; + HighlightFn = NULL; + + // State/Internals + ContentsWidthChanged = false; + DataPreviewAddr = DataEditingAddr = (size_t)-1; + DataEditingTakeFocus = false; + memset(DataInputBuf, 0, sizeof(DataInputBuf)); + memset(AddrInputBuf, 0, sizeof(AddrInputBuf)); + GotoAddr = (size_t)-1; + HighlightMin = HighlightMax = (size_t)-1; + PreviewEndianess = 0; + PreviewDataType = ImGuiDataType_S32; + } + + void GotoAddrAndHighlight(size_t addr_min, size_t addr_max) + { + GotoAddr = addr_min; + HighlightMin = addr_min; + HighlightMax = addr_max; + } + + struct Sizes + { + int AddrDigitsCount; + float LineHeight; + float GlyphWidth; + float HexCellWidth; + float SpacingBetweenMidCols; + float PosHexStart; + float PosHexEnd; + float PosAsciiStart; + float PosAsciiEnd; + float WindowWidth; + + Sizes() { memset(this, 0, sizeof(*this)); } + }; + + void CalcSizes(Sizes& s, size_t mem_size, size_t base_display_addr) + { + ImGuiStyle& style = ImGui::GetStyle(); + s.AddrDigitsCount = OptAddrDigitsCount; + if (s.AddrDigitsCount == 0) + for (size_t n = base_display_addr + mem_size - 1; n > 0; n >>= 4) + s.AddrDigitsCount++; + s.LineHeight = ImGui::GetTextLineHeight(); + s.GlyphWidth = ImGui::CalcTextSize("F").x + 1; // We assume the font is mono-space + s.HexCellWidth = (float)(int)(s.GlyphWidth * 2.5f); // "FF " we include trailing space in the width to easily catch clicks everywhere + s.SpacingBetweenMidCols = (float)(int)(s.HexCellWidth * 0.25f); // Every OptMidColsCount columns we add a bit of extra spacing + s.PosHexStart = (s.AddrDigitsCount + 2) * s.GlyphWidth; + s.PosHexEnd = s.PosHexStart + (s.HexCellWidth * Cols); + s.PosAsciiStart = s.PosAsciiEnd = s.PosHexEnd; + if (OptShowAscii) + { + s.PosAsciiStart = s.PosHexEnd + s.GlyphWidth * 1; + if (OptMidColsCount > 0) + s.PosAsciiStart += (float)((Cols + OptMidColsCount - 1) / OptMidColsCount) * s.SpacingBetweenMidCols; + s.PosAsciiEnd = s.PosAsciiStart + Cols * s.GlyphWidth; + } + s.WindowWidth = s.PosAsciiEnd + style.ScrollbarSize + style.WindowPadding.x * 2 + s.GlyphWidth; + } + + // Standalone Memory Editor window + void DrawWindow(const char* title, void* mem_data, size_t mem_size, size_t base_display_addr = 0x0000) + { + Sizes s; + CalcSizes(s, mem_size, base_display_addr); + ImGui::SetNextWindowSize(ImVec2(s.WindowWidth, s.WindowWidth * 0.60f), ImGuiCond_FirstUseEver); + ImGui::SetNextWindowSizeConstraints(ImVec2(0.0f, 0.0f), ImVec2(s.WindowWidth, FLT_MAX)); + + Open = true; + if (ImGui::Begin(title, &Open, ImGuiWindowFlags_NoScrollbar)) + { + if (ImGui::IsWindowHovered(ImGuiHoveredFlags_RootAndChildWindows) && ImGui::IsMouseReleased(ImGuiMouseButton_Right)) + ImGui::OpenPopup("context"); + DrawContents(mem_data, mem_size, base_display_addr); + if (ContentsWidthChanged) + { + CalcSizes(s, mem_size, base_display_addr); + ImGui::SetWindowSize(ImVec2(s.WindowWidth, ImGui::GetWindowSize().y)); + } + } + ImGui::End(); + } + + // Memory Editor contents only + void DrawContents(void* mem_data_void, size_t mem_size, size_t base_display_addr = 0x0000) + { + if (Cols < 1) + Cols = 1; + + ImU8* mem_data = (ImU8*)mem_data_void; + Sizes s; + CalcSizes(s, mem_size, base_display_addr); + ImGuiStyle& style = ImGui::GetStyle(); + + // We begin into our scrolling region with the 'ImGuiWindowFlags_NoMove' in order to prevent click from moving the window. + // This is used as a facility since our main click detection code doesn't assign an ActiveId so the click would normally be caught as a window-move. + const float height_separator = style.ItemSpacing.y; + float footer_height = OptFooterExtraHeight; + if (OptShowOptions) + footer_height += height_separator + ImGui::GetFrameHeightWithSpacing() * 1; + if (OptShowDataPreview) + footer_height += height_separator + ImGui::GetFrameHeightWithSpacing() * 1 + ImGui::GetTextLineHeightWithSpacing() * 3; + ImGui::BeginChild("##scrolling", ImVec2(0, -footer_height), false, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoNav); + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0)); + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0)); + + // We are not really using the clipper API correctly here, because we rely on visible_start_addr/visible_end_addr for our scrolling function. + const int line_total_count = (int)((mem_size + Cols - 1) / Cols); + ImGuiListClipper clipper; + clipper.Begin(line_total_count, s.LineHeight); + + bool data_next = false; + + if (ReadOnly || DataEditingAddr >= mem_size) + DataEditingAddr = (size_t)-1; + if (DataPreviewAddr >= mem_size) + DataPreviewAddr = (size_t)-1; + + size_t preview_data_type_size = OptShowDataPreview ? DataTypeGetSize(PreviewDataType) : 0; + + size_t data_editing_addr_next = (size_t)-1; + if (DataEditingAddr != (size_t)-1) + { + // Move cursor but only apply on next frame so scrolling with be synchronized (because currently we can't change the scrolling while the window is being rendered) + if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_UpArrow)) && (ptrdiff_t)DataEditingAddr >= (ptrdiff_t)Cols) { data_editing_addr_next = DataEditingAddr - Cols; } + else if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_DownArrow)) && (ptrdiff_t)DataEditingAddr < (ptrdiff_t)mem_size - Cols) { data_editing_addr_next = DataEditingAddr + Cols; } + else if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_LeftArrow)) && (ptrdiff_t)DataEditingAddr > (ptrdiff_t)0) { data_editing_addr_next = DataEditingAddr - 1; } + else if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_RightArrow)) && (ptrdiff_t)DataEditingAddr < (ptrdiff_t)mem_size - 1) { data_editing_addr_next = DataEditingAddr + 1; } + } + + // Draw vertical separator + ImVec2 window_pos = ImGui::GetWindowPos(); + if (OptShowAscii) + draw_list->AddLine(ImVec2(window_pos.x + s.PosAsciiStart - s.GlyphWidth, window_pos.y), ImVec2(window_pos.x + s.PosAsciiStart - s.GlyphWidth, window_pos.y + 9999), ImGui::GetColorU32(ImGuiCol_Border)); + + const ImU32 color_text = ImGui::GetColorU32(ImGuiCol_Text); + const ImU32 color_disabled = OptGreyOutZeroes ? ImGui::GetColorU32(ImGuiCol_TextDisabled) : color_text; + + const char* format_address = OptUpperCaseHex ? "%0*" _PRISizeT "X: " : "%0*" _PRISizeT "x: "; + const char* format_data = OptUpperCaseHex ? "%0*" _PRISizeT "X" : "%0*" _PRISizeT "x"; + const char* format_byte = OptUpperCaseHex ? "%02X" : "%02x"; + const char* format_byte_space = OptUpperCaseHex ? "%02X " : "%02x "; + + while (clipper.Step()) + for (int line_i = clipper.DisplayStart; line_i < clipper.DisplayEnd; line_i++) // display only visible lines + { + size_t addr = (size_t)(line_i * Cols); + ImGui::Text(format_address, s.AddrDigitsCount, base_display_addr + addr); + + // Draw Hexadecimal + for (int n = 0; n < Cols && addr < mem_size; n++, addr++) + { + float byte_pos_x = s.PosHexStart + s.HexCellWidth * n; + if (OptMidColsCount > 0) + byte_pos_x += (float)(n / OptMidColsCount) * s.SpacingBetweenMidCols; + ImGui::SameLine(byte_pos_x); + + // Draw highlight + bool is_highlight_from_user_range = (addr >= HighlightMin && addr < HighlightMax); + bool is_highlight_from_user_func = (HighlightFn && HighlightFn(mem_data, addr)); + bool is_highlight_from_preview = (addr >= DataPreviewAddr && addr < DataPreviewAddr + preview_data_type_size); + if (is_highlight_from_user_range || is_highlight_from_user_func || is_highlight_from_preview) + { + ImVec2 pos = ImGui::GetCursorScreenPos(); + float highlight_width = s.GlyphWidth * 2; + bool is_next_byte_highlighted = (addr + 1 < mem_size) && ((HighlightMax != (size_t)-1 && addr + 1 < HighlightMax) || (HighlightFn && HighlightFn(mem_data, addr + 1))); + if (is_next_byte_highlighted || (n + 1 == Cols)) + { + highlight_width = s.HexCellWidth; + if (OptMidColsCount > 0 && n > 0 && (n + 1) < Cols && ((n + 1) % OptMidColsCount) == 0) + highlight_width += s.SpacingBetweenMidCols; + } + draw_list->AddRectFilled(pos, ImVec2(pos.x + highlight_width, pos.y + s.LineHeight), HighlightColor); + } + + if (DataEditingAddr == addr) + { + // Display text input on current byte + bool data_write = false; + ImGui::PushID((void*)addr); + if (DataEditingTakeFocus) + { + ImGui::SetKeyboardFocusHere(0); + sprintf(AddrInputBuf, format_data, s.AddrDigitsCount, base_display_addr + addr); + sprintf(DataInputBuf, format_byte, ReadFn ? ReadFn(mem_data, addr) : mem_data[addr]); + } + struct UserData + { + // FIXME: We should have a way to retrieve the text edit cursor position more easily in the API, this is rather tedious. This is such a ugly mess we may be better off not using InputText() at all here. + static int Callback(ImGuiInputTextCallbackData* data) + { + UserData* user_data = (UserData*)data->UserData; + if (!data->HasSelection()) + user_data->CursorPos = data->CursorPos; + if (data->SelectionStart == 0 && data->SelectionEnd == data->BufTextLen) + { + // When not editing a byte, always refresh its InputText content pulled from underlying memory data + // (this is a bit tricky, since InputText technically "owns" the master copy of the buffer we edit it in there) + data->DeleteChars(0, data->BufTextLen); + data->InsertChars(0, user_data->CurrentBufOverwrite); + data->SelectionStart = 0; + data->SelectionEnd = 2; + data->CursorPos = 0; + } + return 0; + } + char CurrentBufOverwrite[3]; // Input + int CursorPos; // Output + }; + UserData user_data; + user_data.CursorPos = -1; + sprintf(user_data.CurrentBufOverwrite, format_byte, ReadFn ? ReadFn(mem_data, addr) : mem_data[addr]); + ImGuiInputTextFlags flags = ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_NoHorizontalScroll | ImGuiInputTextFlags_CallbackAlways; +#if IMGUI_VERSION_NUM >= 18104 + flags |= ImGuiInputTextFlags_AlwaysOverwrite; +#else + flags |= ImGuiInputTextFlags_AlwaysInsertMode; +#endif + ImGui::SetNextItemWidth(s.GlyphWidth * 2); + if (ImGui::InputText("##data", DataInputBuf, IM_ARRAYSIZE(DataInputBuf), flags, UserData::Callback, &user_data)) + data_write = data_next = true; + else if (!DataEditingTakeFocus && !ImGui::IsItemActive()) + DataEditingAddr = data_editing_addr_next = (size_t)-1; + DataEditingTakeFocus = false; + if (user_data.CursorPos >= 2) + data_write = data_next = true; + if (data_editing_addr_next != (size_t)-1) + data_write = data_next = false; + unsigned int data_input_value = 0; + if (data_write && sscanf(DataInputBuf, "%X", &data_input_value) == 1) + { + if (WriteFn) + WriteFn(mem_data, addr, (ImU8)data_input_value); + else + mem_data[addr] = (ImU8)data_input_value; + } + ImGui::PopID(); + } + else + { + // NB: The trailing space is not visible but ensure there's no gap that the mouse cannot click on. + ImU8 b = ReadFn ? ReadFn(mem_data, addr) : mem_data[addr]; + + if (OptShowHexII) + { + if ((b >= 32 && b < 128)) + ImGui::Text(".%c ", b); + else if (b == 0xFF && OptGreyOutZeroes) + ImGui::TextDisabled("## "); + else if (b == 0x00) + ImGui::Text(" "); + else + ImGui::Text(format_byte_space, b); + } + else + { + if (b == 0 && OptGreyOutZeroes) + ImGui::TextDisabled("00 "); + else + ImGui::Text(format_byte_space, b); + } + if (!ReadOnly && ImGui::IsItemHovered() && ImGui::IsMouseClicked(0)) + { + DataEditingTakeFocus = true; + data_editing_addr_next = addr; + } + } + } + + if (OptShowAscii) + { + // Draw ASCII values + ImGui::SameLine(s.PosAsciiStart); + ImVec2 pos = ImGui::GetCursorScreenPos(); + addr = line_i * Cols; + ImGui::PushID(line_i); + if (ImGui::InvisibleButton("ascii", ImVec2(s.PosAsciiEnd - s.PosAsciiStart, s.LineHeight))) + { + DataEditingAddr = DataPreviewAddr = addr + (size_t)((ImGui::GetIO().MousePos.x - pos.x) / s.GlyphWidth); + DataEditingTakeFocus = true; + } + ImGui::PopID(); + for (int n = 0; n < Cols && addr < mem_size; n++, addr++) + { + if (addr == DataEditingAddr) + { + draw_list->AddRectFilled(pos, ImVec2(pos.x + s.GlyphWidth, pos.y + s.LineHeight), ImGui::GetColorU32(ImGuiCol_FrameBg)); + draw_list->AddRectFilled(pos, ImVec2(pos.x + s.GlyphWidth, pos.y + s.LineHeight), ImGui::GetColorU32(ImGuiCol_TextSelectedBg)); + } + unsigned char c = ReadFn ? ReadFn(mem_data, addr) : mem_data[addr]; + char display_c = (c < 32 || c >= 128) ? '.' : c; + draw_list->AddText(pos, (display_c == c) ? color_text : color_disabled, &display_c, &display_c + 1); + pos.x += s.GlyphWidth; + } + } + } + ImGui::PopStyleVar(2); + ImGui::EndChild(); + + // Notify the main window of our ideal child content size (FIXME: we are missing an API to get the contents size from the child) + ImGui::SetCursorPosX(s.WindowWidth); + + if (data_next && DataEditingAddr + 1 < mem_size) + { + DataEditingAddr = DataPreviewAddr = DataEditingAddr + 1; + DataEditingTakeFocus = true; + } + else if (data_editing_addr_next != (size_t)-1) + { + DataEditingAddr = DataPreviewAddr = data_editing_addr_next; + DataEditingTakeFocus = true; + } + + const bool lock_show_data_preview = OptShowDataPreview; + if (OptShowOptions) + { + ImGui::Separator(); + DrawOptionsLine(s, mem_data, mem_size, base_display_addr); + } + + if (lock_show_data_preview) + { + ImGui::Separator(); + DrawPreviewLine(s, mem_data, mem_size, base_display_addr); + } + } + + void DrawOptionsLine(const Sizes& s, void* mem_data, size_t mem_size, size_t base_display_addr) + { + IM_UNUSED(mem_data); + ImGuiStyle& style = ImGui::GetStyle(); + const char* format_range = OptUpperCaseHex ? "Range %0*" _PRISizeT "X..%0*" _PRISizeT "X" : "Range %0*" _PRISizeT "x..%0*" _PRISizeT "x"; + + // Options menu + if (ImGui::Button("Options")) + ImGui::OpenPopup("context"); + if (ImGui::BeginPopup("context")) + { + ImGui::SetNextItemWidth(s.GlyphWidth * 7 + style.FramePadding.x * 2.0f); + if (ImGui::DragInt("##cols", &Cols, 0.2f, 4, 32, "%d cols")) { ContentsWidthChanged = true; if (Cols < 1) Cols = 1; } + ImGui::Checkbox("Show Data Preview", &OptShowDataPreview); + ImGui::Checkbox("Show HexII", &OptShowHexII); + if (ImGui::Checkbox("Show Ascii", &OptShowAscii)) { ContentsWidthChanged = true; } + ImGui::Checkbox("Grey out zeroes", &OptGreyOutZeroes); + ImGui::Checkbox("Uppercase Hex", &OptUpperCaseHex); + + ImGui::EndPopup(); + } + + ImGui::SameLine(); + ImGui::Text(format_range, s.AddrDigitsCount, base_display_addr, s.AddrDigitsCount, base_display_addr + mem_size - 1); + ImGui::SameLine(); + ImGui::SetNextItemWidth((s.AddrDigitsCount + 1) * s.GlyphWidth + style.FramePadding.x * 2.0f); + if (ImGui::InputText("##addr", AddrInputBuf, IM_ARRAYSIZE(AddrInputBuf), ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_EnterReturnsTrue)) + { + size_t goto_addr; + if (sscanf(AddrInputBuf, "%" _PRISizeT "X", &goto_addr) == 1) + { + GotoAddr = goto_addr - base_display_addr; + HighlightMin = HighlightMax = (size_t)-1; + } + } + + if (GotoAddr != (size_t)-1) + { + if (GotoAddr < mem_size) + { + ImGui::BeginChild("##scrolling"); + ImGui::SetScrollFromPosY(ImGui::GetCursorStartPos().y + (GotoAddr / Cols) * ImGui::GetTextLineHeight()); + ImGui::EndChild(); + DataEditingAddr = DataPreviewAddr = GotoAddr; + DataEditingTakeFocus = true; + } + GotoAddr = (size_t)-1; + } + } + + void DrawPreviewLine(const Sizes& s, void* mem_data_void, size_t mem_size, size_t base_display_addr) + { + IM_UNUSED(base_display_addr); + ImU8* mem_data = (ImU8*)mem_data_void; + ImGuiStyle& style = ImGui::GetStyle(); + ImGui::AlignTextToFramePadding(); + ImGui::Text("Preview as:"); + ImGui::SameLine(); + ImGui::SetNextItemWidth((s.GlyphWidth * 10.0f) + style.FramePadding.x * 2.0f + style.ItemInnerSpacing.x); + if (ImGui::BeginCombo("##combo_type", DataTypeGetDesc(PreviewDataType), ImGuiComboFlags_HeightLargest)) + { + for (int n = 0; n < ImGuiDataType_COUNT; n++) + if (ImGui::Selectable(DataTypeGetDesc((ImGuiDataType)n), PreviewDataType == n)) + PreviewDataType = (ImGuiDataType)n; + ImGui::EndCombo(); + } + ImGui::SameLine(); + ImGui::SetNextItemWidth((s.GlyphWidth * 6.0f) + style.FramePadding.x * 2.0f + style.ItemInnerSpacing.x); + ImGui::Combo("##combo_endianess", &PreviewEndianess, "LE\0BE\0\0"); + + char buf[128] = ""; + float x = s.GlyphWidth * 6.0f; + bool has_value = DataPreviewAddr != (size_t)-1; + if (has_value) + DrawPreviewData(DataPreviewAddr, mem_data, mem_size, PreviewDataType, DataFormat_Dec, buf, (size_t)IM_ARRAYSIZE(buf)); + ImGui::Text("Dec"); ImGui::SameLine(x); ImGui::TextUnformatted(has_value ? buf : "N/A"); + if (has_value) + DrawPreviewData(DataPreviewAddr, mem_data, mem_size, PreviewDataType, DataFormat_Hex, buf, (size_t)IM_ARRAYSIZE(buf)); + ImGui::Text("Hex"); ImGui::SameLine(x); ImGui::TextUnformatted(has_value ? buf : "N/A"); + if (has_value) + DrawPreviewData(DataPreviewAddr, mem_data, mem_size, PreviewDataType, DataFormat_Bin, buf, (size_t)IM_ARRAYSIZE(buf)); + buf[IM_ARRAYSIZE(buf) - 1] = 0; + ImGui::Text("Bin"); ImGui::SameLine(x); ImGui::TextUnformatted(has_value ? buf : "N/A"); + } + + // Utilities for Data Preview + const char* DataTypeGetDesc(ImGuiDataType data_type) const + { + const char* descs[] = { "Int8", "Uint8", "Int16", "Uint16", "Int32", "Uint32", "Int64", "Uint64", "Float", "Double" }; + IM_ASSERT(data_type >= 0 && data_type < ImGuiDataType_COUNT); + return descs[data_type]; + } + + size_t DataTypeGetSize(ImGuiDataType data_type) const + { + const size_t sizes[] = { 1, 1, 2, 2, 4, 4, 8, 8, sizeof(float), sizeof(double) }; + IM_ASSERT(data_type >= 0 && data_type < ImGuiDataType_COUNT); + return sizes[data_type]; + } + + const char* DataFormatGetDesc(DataFormat data_format) const + { + const char* descs[] = { "Bin", "Dec", "Hex" }; + IM_ASSERT(data_format >= 0 && data_format < DataFormat_COUNT); + return descs[data_format]; + } + + bool IsBigEndian() const + { + uint16_t x = 1; + char c[2]; + memcpy(c, &x, 2); + return c[0] != 0; + } + + static void* EndianessCopyBigEndian(void* _dst, void* _src, size_t s, int is_little_endian) + { + if (is_little_endian) + { + uint8_t* dst = (uint8_t*)_dst; + uint8_t* src = (uint8_t*)_src + s - 1; + for (int i = 0, n = (int)s; i < n; ++i) + memcpy(dst++, src--, 1); + return _dst; + } + else + { + return memcpy(_dst, _src, s); + } + } + + static void* EndianessCopyLittleEndian(void* _dst, void* _src, size_t s, int is_little_endian) + { + if (is_little_endian) + { + return memcpy(_dst, _src, s); + } + else + { + uint8_t* dst = (uint8_t*)_dst; + uint8_t* src = (uint8_t*)_src + s - 1; + for (int i = 0, n = (int)s; i < n; ++i) + memcpy(dst++, src--, 1); + return _dst; + } + } + + void* EndianessCopy(void* dst, void* src, size_t size) const + { + static void* (*fp)(void*, void*, size_t, int) = NULL; + if (fp == NULL) + fp = IsBigEndian() ? EndianessCopyBigEndian : EndianessCopyLittleEndian; + return fp(dst, src, size, PreviewEndianess); + } + + const char* FormatBinary(const uint8_t* buf, int width) const + { + IM_ASSERT(width <= 64); + size_t out_n = 0; + static char out_buf[64 + 8 + 1]; + int n = width / 8; + for (int j = n - 1; j >= 0; --j) + { + for (int i = 0; i < 8; ++i) + out_buf[out_n++] = (buf[j] & (1 << (7 - i))) ? '1' : '0'; + out_buf[out_n++] = ' '; + } + IM_ASSERT(out_n < IM_ARRAYSIZE(out_buf)); + out_buf[out_n] = 0; + return out_buf; + } + + // [Internal] + void DrawPreviewData(size_t addr, const ImU8* mem_data, size_t mem_size, ImGuiDataType data_type, DataFormat data_format, char* out_buf, size_t out_buf_size) const + { + uint8_t buf[8]; + size_t elem_size = DataTypeGetSize(data_type); + size_t size = addr + elem_size > mem_size ? mem_size - addr : elem_size; + if (ReadFn) + for (int i = 0, n = (int)size; i < n; ++i) + buf[i] = ReadFn(mem_data, addr + i); + else + memcpy(buf, mem_data + addr, size); + + if (data_format == DataFormat_Bin) + { + uint8_t binbuf[8]; + EndianessCopy(binbuf, buf, size); + ImSnprintf(out_buf, out_buf_size, "%s", FormatBinary(binbuf, (int)size * 8)); + return; + } + + out_buf[0] = 0; + switch (data_type) + { + case ImGuiDataType_S8: + { + int8_t int8 = 0; + EndianessCopy(&int8, buf, size); + if (data_format == DataFormat_Dec) { ImSnprintf(out_buf, out_buf_size, "%hhd", int8); return; } + if (data_format == DataFormat_Hex) { ImSnprintf(out_buf, out_buf_size, "0x%02x", int8 & 0xFF); return; } + break; + } + case ImGuiDataType_U8: + { + uint8_t uint8 = 0; + EndianessCopy(&uint8, buf, size); + if (data_format == DataFormat_Dec) { ImSnprintf(out_buf, out_buf_size, "%hhu", uint8); return; } + if (data_format == DataFormat_Hex) { ImSnprintf(out_buf, out_buf_size, "0x%02x", uint8 & 0XFF); return; } + break; + } + case ImGuiDataType_S16: + { + int16_t int16 = 0; + EndianessCopy(&int16, buf, size); + if (data_format == DataFormat_Dec) { ImSnprintf(out_buf, out_buf_size, "%hd", int16); return; } + if (data_format == DataFormat_Hex) { ImSnprintf(out_buf, out_buf_size, "0x%04x", int16 & 0xFFFF); return; } + break; + } + case ImGuiDataType_U16: + { + uint16_t uint16 = 0; + EndianessCopy(&uint16, buf, size); + if (data_format == DataFormat_Dec) { ImSnprintf(out_buf, out_buf_size, "%hu", uint16); return; } + if (data_format == DataFormat_Hex) { ImSnprintf(out_buf, out_buf_size, "0x%04x", uint16 & 0xFFFF); return; } + break; + } + case ImGuiDataType_S32: + { + int32_t int32 = 0; + EndianessCopy(&int32, buf, size); + if (data_format == DataFormat_Dec) { ImSnprintf(out_buf, out_buf_size, "%d", int32); return; } + if (data_format == DataFormat_Hex) { ImSnprintf(out_buf, out_buf_size, "0x%08x", int32); return; } + break; + } + case ImGuiDataType_U32: + { + uint32_t uint32 = 0; + EndianessCopy(&uint32, buf, size); + if (data_format == DataFormat_Dec) { ImSnprintf(out_buf, out_buf_size, "%u", uint32); return; } + if (data_format == DataFormat_Hex) { ImSnprintf(out_buf, out_buf_size, "0x%08x", uint32); return; } + break; + } + case ImGuiDataType_S64: + { + int64_t int64 = 0; + EndianessCopy(&int64, buf, size); + if (data_format == DataFormat_Dec) { ImSnprintf(out_buf, out_buf_size, "%lld", (long long)int64); return; } + if (data_format == DataFormat_Hex) { ImSnprintf(out_buf, out_buf_size, "0x%016llx", (long long)int64); return; } + break; + } + case ImGuiDataType_U64: + { + uint64_t uint64 = 0; + EndianessCopy(&uint64, buf, size); + if (data_format == DataFormat_Dec) { ImSnprintf(out_buf, out_buf_size, "%llu", (long long)uint64); return; } + if (data_format == DataFormat_Hex) { ImSnprintf(out_buf, out_buf_size, "0x%016llx", (long long)uint64); return; } + break; + } + case ImGuiDataType_Float: + { + float float32 = 0.0f; + EndianessCopy(&float32, buf, size); + if (data_format == DataFormat_Dec) { ImSnprintf(out_buf, out_buf_size, "%f", float32); return; } + if (data_format == DataFormat_Hex) { ImSnprintf(out_buf, out_buf_size, "%a", float32); return; } + break; + } + case ImGuiDataType_Double: + { + double float64 = 0.0; + EndianessCopy(&float64, buf, size); + if (data_format == DataFormat_Dec) { ImSnprintf(out_buf, out_buf_size, "%f", float64); return; } + if (data_format == DataFormat_Hex) { ImSnprintf(out_buf, out_buf_size, "%a", float64); return; } + break; + } + case ImGuiDataType_COUNT: + break; + } // Switch + IM_ASSERT(0); // Shouldn't reach + } +}; + +#undef _PRISizeT +#undef ImSnprintf + +#ifdef _MSC_VER +#pragma warning (pop) +#endif diff --git a/src/lib/snes_spc b/src/lib/snes_spc new file mode 160000 index 00000000..ec8ee2bb --- /dev/null +++ b/src/lib/snes_spc @@ -0,0 +1 @@ +Subproject commit ec8ee2bbe30451614c1d02a83f7af1c97d497d45 diff --git a/src/lib/sneshacking b/src/lib/sneshacking new file mode 160000 index 00000000..3cf5ab86 --- /dev/null +++ b/src/lib/sneshacking @@ -0,0 +1 @@ +Subproject commit 3cf5ab8681839e37c0aa7b8209821b809f47e9c7 diff --git a/src/yaze.ico b/src/yaze.ico new file mode 100644 index 0000000000000000000000000000000000000000..16069a6d2a973ab6c5de750406f3da85726e07ac GIT binary patch literal 318 zcmah_yA8rH6ubZuC8kLWJQ3uYh#D!%1VPRQ$sCl7kr5cdB_mK~gp@A1_aYh^&bqtj zd;Z7%Np XThEO2xMadt%o$15$RLJr9Qd^yo*^g-qX?tMl&@0~-Mrg(ko@GpL z+LH4lsu&S#MMng+E^W#2q^>kSS*=w!v-RqF- + +#include +#include + +#include +#include +#include +#include +#include + +#include "absl/status/status.h" +#include "absl/status/statusor.h" +#include "absl/strings/str_cat.h" +#include "absl/strings/string_view.h" +#include "app/asm/script.h" +#include "app/core/constants.h" +#include "app/rom.h" + +namespace yaze_test { +namespace asm_test { + +using yaze::app::ROM; +using yaze::app::snes_asm::Script; + +using ::testing::_; +using ::testing::ElementsAreArray; +using ::testing::Eq; +using ::testing::Return; + +class MockScript : public Script { + public: + MOCK_METHOD(absl::Status, ApplyPatchToROM, (ROM & rom)); + MOCK_METHOD(absl::Status, PatchOverworldMosaic, + (ROM & rom, char mosaic_tiles[yaze::app::core::kNumOverworldMaps], + int routine_offset, int hook_offset)); +}; + +TEST(ASMTest, ApplyMosaicChangePatchOk) { + ROM rom; + MockScript script; + char mosaic_tiles[yaze::app::core::kNumOverworldMaps]; + + EXPECT_CALL(script, PatchOverworldMosaic(_, Eq(mosaic_tiles), + Eq(0x1301D0 + 0x138000), 0)) + .WillOnce(Return(absl::OkStatus())); + + EXPECT_CALL(script, ApplyPatchToROM(_)).WillOnce(Return(absl::OkStatus())); + + EXPECT_THAT( + script.PatchOverworldMosaic(rom, mosaic_tiles, 0x1301D0 + 0x138000, 0), + absl::OkStatus()); + EXPECT_THAT(script.ApplyPatchToROM(rom), absl::OkStatus()); +} + +TEST(ASMTest, NoPatchLoadedError) { + ROM rom; + MockScript script; + EXPECT_CALL(script, ApplyPatchToROM(_)) + .WillOnce(Return(absl::InvalidArgumentError("No patch loaded!"))); + + EXPECT_THAT(script.ApplyPatchToROM(rom), + absl::InvalidArgumentError("No patch loaded!")); +} + +} // namespace asm_test +} // namespace yaze_test \ No newline at end of file diff --git a/test/delta_test.cc b/test/delta_test.cc new file mode 100644 index 00000000..a4db2f78 --- /dev/null +++ b/test/delta_test.cc @@ -0,0 +1,74 @@ +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "absl/status/status.h" +#include "absl/status/statusor.h" +#include "absl/strings/str_cat.h" +#include "absl/strings/string_view.h" +#include "app/core/constants.h" +#include "app/delta/client.h" +#include "app/delta/service.h" +#include "app/rom.h" +#include "src/app/delta/delta.grpc.pb.h" +#include "src/app/delta/delta.pb.h" + +namespace yaze_test { +namespace delta_test { + +TEST(DeltaTest, InitRepoAndPushOk) { + yaze::app::delta::DeltaService service; + yaze::app::ROM rom; + Bytes test_bytes; + test_bytes.push_back(0x40); + EXPECT_TRUE(rom.LoadFromBytes(test_bytes).ok()); + grpc::ServerContext* context; + InitRequest init_request; + auto repo = init_request.mutable_repo(); + repo->set_project_name("test_repo"); + Branch branch; + branch.set_branch_name("test_branch"); + auto new_mutable_commits = branch.mutable_commits(); + new_mutable_commits->Reserve(5); + for (int i = 0; i < 5; ++i) { + auto new_commit = new Commit(); + new_commit->set_commit_id(i); + new_mutable_commits->Add(); + new_mutable_commits->at(i) = *new_commit; + } + auto mutable_tree = repo->mutable_tree(); + mutable_tree->Add(); + mutable_tree->at(0) = branch; + InitResponse init_response; + auto init_status = service.Init(context, &init_request, &init_response); + EXPECT_TRUE(init_status.ok()); + + PushRequest request; + request.set_branch_name("test_branch"); + request.set_repository_name("test_repo"); + auto mutable_commits = request.mutable_commits(); + mutable_commits->Reserve(5); + for (int i = 0; i < 5; ++i) { + auto new_commit = new Commit(); + new_commit->set_commit_id(i * 2); + mutable_commits->Add(); + mutable_commits->at(i) = *new_commit; + } + PushResponse reply; + auto status = service.Push(context, &request, &reply); + EXPECT_TRUE(status.ok()); + + auto repos = service.Repos(); + auto result_branch = repos.at(0).tree(); + std::cerr << result_branch.at(0).DebugString() << std::endl; +} + +} // namespace delta_test +} // namespace yaze_test \ No newline at end of file diff --git a/test/rom_test.cc b/test/rom_test.cc new file mode 100644 index 00000000..1f1af99c --- /dev/null +++ b/test/rom_test.cc @@ -0,0 +1,315 @@ +#include "app/rom.h" + +#include +#include + +#include + +#include "absl/status/statusor.h" + +#define BUILD_HEADER(command, length) (command << 5) + (length - 1) + +namespace yaze_test { +namespace rom_test { + +using yaze::app::CompressionPiece; +using yaze::app::ROM; + +using ::testing::ElementsAreArray; +using ::testing::TypedEq; + +namespace { + +Bytes ExpectCompressOk(ROM& rom, uchar* in, int in_size) { + auto load_status = rom.LoadFromPointer(in, in_size); + EXPECT_TRUE(load_status.ok()); + auto compression_status = rom.Compress(0, in_size); + EXPECT_TRUE(compression_status.ok()); + auto compressed_bytes = std::move(*compression_status); + return compressed_bytes; +} + +Bytes ExpectDecompressBytesOk(ROM& rom, Bytes& in) { + auto load_status = rom.LoadFromBytes(in); + EXPECT_TRUE(load_status.ok()); + auto decompression_status = rom.Decompress(0, in.size()); + EXPECT_TRUE(decompression_status.ok()); + auto decompressed_bytes = std::move(*decompression_status); + return decompressed_bytes; +} + +Bytes ExpectDecompressOk(ROM& rom, uchar* in, int in_size) { + auto load_status = rom.LoadFromPointer(in, in_size); + EXPECT_TRUE(load_status.ok()); + auto decompression_status = rom.Decompress(0, in_size); + EXPECT_TRUE(decompression_status.ok()); + auto decompressed_bytes = std::move(*decompression_status); + return decompressed_bytes; +} + +std::shared_ptr ExpectNewCompressionPieceOk( + const char command, const int length, const std::string args, + const int argument_length) { + auto new_piece = std::make_shared(command, length, args, + argument_length); + EXPECT_TRUE(new_piece != nullptr); + return new_piece; +} + +} // namespace + +TEST(ROMTest, NewDecompressionPieceOk) { + char command = 1; + int length = 1; + char args[] = "aaa"; + int argument_length = 0x02; + CompressionPiece old_piece; + old_piece.command = command; + old_piece.length = length; + old_piece.argument = args; + old_piece.argument_length = argument_length; + old_piece.next = nullptr; + + auto new_piece = ExpectNewCompressionPieceOk(0x01, 0x01, "aaa", 0x02); + + EXPECT_EQ(old_piece.command, new_piece->command); + EXPECT_EQ(old_piece.length, new_piece->length); + ASSERT_EQ(old_piece.argument_length, new_piece->argument_length); + for (int i = 0; i < old_piece.argument_length; ++i) { + EXPECT_EQ(old_piece.argument[i], new_piece->argument[i]); + } +} + +TEST(ROMTest, DecompressionValidCommand) { + ROM rom; + Bytes simple_copy_input = {BUILD_HEADER(0x00, 0x02), 0x2A, 0x45, 0xFF}; + uchar simple_copy_output[2] = {0x2A, 0x45}; + auto decomp_result = ExpectDecompressBytesOk(rom, simple_copy_input); + EXPECT_THAT(simple_copy_output, ElementsAreArray(decomp_result.data(), 2)); +} + +TEST(ROMTest, DecompressionMixingCommand) { + ROM rom; + uchar random1_i[11] = {BUILD_HEADER(0x01, 0x03), + 0x2A, + BUILD_HEADER(0x00, 0x04), + 0x01, + 0x02, + 0x03, + 0x04, + BUILD_HEADER(0x02, 0x02), + 0x0B, + 0x16, + 0xFF}; + uchar random1_o[9] = {42, 42, 42, 1, 2, 3, 4, 11, 22}; + auto decomp_result = ExpectDecompressOk(rom, random1_i, 11); + EXPECT_THAT(random1_o, ElementsAreArray(decomp_result.data(), 9)); +} + +TEST(ROMTest, CompressionSingleSet) { + ROM rom; + uchar single_set[5] = {0x2A, 0x2A, 0x2A, 0x2A, 0x2A}; + uchar single_set_expected[3] = {BUILD_HEADER(1, 5), 0x2A, 0xFF}; + + auto comp_result = ExpectCompressOk(rom, single_set, 5); + EXPECT_THAT(single_set_expected, ElementsAreArray(comp_result.data(), 3)); +} + +TEST(ROMTest, CompressionSingleWord) { + ROM rom; + uchar single_word[6] = {0x2A, 0x01, 0x2A, 0x01, 0x2A, 0x01}; + uchar single_word_expected[4] = {BUILD_HEADER(0x02, 0x06), 0x2A, 0x01, 0xFF}; + + auto comp_result = ExpectCompressOk(rom, single_word, 6); + EXPECT_THAT(single_word_expected, ElementsAreArray(comp_result.data(), 4)); +} + +TEST(ROMTest, CompressionSingleIncrement) { + ROM rom; + uchar single_inc[3] = {0x01, 0x02, 0x03}; + uchar single_inc_expected[3] = {BUILD_HEADER(0x03, 0x03), 0x01, 0xFF}; + auto comp_result = ExpectCompressOk(rom, single_inc, 3); + EXPECT_THAT(single_inc_expected, ElementsAreArray(comp_result.data(), 3)); +} + +TEST(ROMTest, CompressionSingleCopy) { + ROM rom; + uchar single_copy[4] = {0x03, 0x0A, 0x07, 0x14}; + uchar single_copy_expected[6] = { + BUILD_HEADER(0x00, 0x04), 0x03, 0x0A, 0x07, 0x14, 0xFF}; + auto comp_result = ExpectCompressOk(rom, single_copy, 4); + EXPECT_THAT(single_copy_expected, ElementsAreArray(comp_result.data(), 6)); +} + +/* Hiding tests until I figure out a better PR to address the bug +TEST(ROMTest, CompressionSingleCopyRepeat) { + ROM rom; + uchar single_copy_repeat[8] = {0x03, 0x0A, 0x07, 0x14, 0x03, 10, 0x07, 0x14}; + uchar single_copy_repeat_expected[9] = { + BUILD_HEADER(0x00, 0x04), 0x03, 0x0A, 0x07, 0x14, + BUILD_HEADER(0x04, 0x04), 0x00, 0x00, 0xFF}; + auto comp_result = ExpectCompressOk(rom, single_copy_repeat, 8); + EXPECT_THAT(single_copy_repeat_expected, + ElementsAreArray(comp_result.data(), 9)); +} + +TEST(ROMTest, CompressionSingleOverflowIncrement) { + ROM rom; + uchar overflow_inc[4] = {0xFE, 0xFF, 0x00, 0x01}; + uchar overflow_inc_expected[3] = {BUILD_HEADER(0x03, 0x04), 0xFE, 0xFF}; + + auto comp_result = ExpectCompressOk(rom, overflow_inc, 4); + EXPECT_THAT(overflow_inc_expected, ElementsAreArray(comp_result.data(), 3)); +} + +TEST(ROMTest, CompressionMixedRepeatIncrement) { + ROM rom; + uchar to_compress_string[28] = {0x05, 0x05, 0x05, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x05, 0x02, 0x05, 0x02, + 0x05, 0x02, 0x0A, 0x0B, 0x05, 0x02, 0x05, + 0x02, 0x05, 0x02, 0x08, 0x0A, 0x00, 0x05}; + uchar repeat_and_inc_copy_expected[7] = {BUILD_HEADER(0x01, 0x04), + 0x05, + BUILD_HEADER(0x03, 0x06), + 0x06, + BUILD_HEADER(0x00, 0x01), + 0x05, + 0xFF}; + // Mixing, repeat, inc, trailing copy + auto comp_result = ExpectCompressOk(rom, to_compress_string, 28); + EXPECT_THAT(repeat_and_inc_copy_expected, + ElementsAreArray(comp_result.data(), 7)); +} + */ + +TEST(ROMTest, CompressionMixedIncrementIntraCopyOffset) { + ROM rom; + uchar to_compress_string[] = {0x05, 0x05, 0x05, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x05, 0x02, 0x05, 0x02, + 0x05, 0x02, 0x0A, 0x0B, 0x05, 0x02, 0x05, + 0x02, 0x05, 0x02, 0x08, 0x0A, 0x00, 0x05}; + uchar inc_word_intra_copy_expected[] = {BUILD_HEADER(0x03, 0x07), + 0x05, + BUILD_HEADER(0x02, 0x06), + 0x05, + 0x02, + BUILD_HEADER(0x04, 0x08), + 0x05, + 0x00, + 0xFF}; + + // "Mixing, inc, alternate, intra copy" + // compress start: 3, length: 21 + // compressed length: 9 + auto comp_result = ExpectCompressOk(rom, to_compress_string + 3, 21); + EXPECT_THAT(inc_word_intra_copy_expected, + ElementsAreArray(comp_result.data(), 9)); +} + +TEST(ROMTest, CompressionMixedIncrementIntraCopySource) { + ROM rom; + uchar to_compress_string[] = {0x05, 0x05, 0x05, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x05, 0x02, 0x05, 0x02, + 0x05, 0x02, 0x0A, 0x0B, 0x05, 0x02, 0x05, + 0x02, 0x05, 0x02, 0x08, 0x0A, 0x00, 0x05}; + uchar all_expected[] = {BUILD_HEADER(0x01, 0x04), + 0x05, + BUILD_HEADER(0x03, 0x06), + 0x06, + BUILD_HEADER(0x02, 0x06), + 0x05, + 0x02, + BUILD_HEADER(0x04, 0x08), + 0x08, + 0x00, + BUILD_HEADER(0x00, 0x04), + 0x08, + 0x0A, + 0x00, + 0x05, + 0xFF}; + // "Mixing, inc, alternate, intra copy" + // 0, 28 + // 16 + auto comp_result = ExpectCompressOk(rom, to_compress_string, 28); + EXPECT_THAT(all_expected, ElementsAreArray(comp_result.data(), 16)); +} + +TEST(ROMTest, LengthBorderCompression) { + ROM rom; + uchar buffer[3000]; + + for (unsigned int i = 0; i < 3000; i++) buffer[i] = 0x05; + uchar extended_lenght_expected_42[] = {0b11100100, 0x29, 0x05, 0xFF}; + uchar extended_lenght_expected_400[] = {0b11100101, 0x8F, 0x05, 0xFF}; + uchar extended_lenght_expected_1050[] = { + 0b11100111, 0xFF, 0x05, BUILD_HEADER(0x01, 0x1A), 0x05, 0xFF}; + uchar extended_lenght_expected_2050[] = { + 0b11100111, 0xFF, 0x05, 0b11100111, 0xFF, 0x05, BUILD_HEADER(0x01, 0x02), + 0x05, 0xFF}; + + // "Extended lenght, 42 repeat of 5" + auto comp_result = ExpectCompressOk(rom, buffer, 42); + EXPECT_THAT(extended_lenght_expected_42, + ElementsAreArray(comp_result.data(), 4)); + + // "Extended lenght, 400 repeat of 5" + comp_result = ExpectCompressOk(rom, buffer, 400); + EXPECT_THAT(extended_lenght_expected_400, + ElementsAreArray(comp_result.data(), 4)); + + // "Extended lenght, 1050 repeat of 5" + comp_result = ExpectCompressOk(rom, buffer, 1050); + EXPECT_THAT(extended_lenght_expected_1050, + ElementsAreArray(comp_result.data(), 6)); + + // "Extended lenght, 2050 repeat of 5" + comp_result = ExpectCompressOk(rom, buffer, 2050); + EXPECT_THAT(extended_lenght_expected_2050, + ElementsAreArray(comp_result.data(), 9)); +} + +TEST(ROMTest, CompressionExtendedWordCopy) { + ROM rom; + uchar buffer[3000]; + for (unsigned int i = 0; i < 3000; i += 2) { + buffer[i] = 0x05; + buffer[i + 1] = 0x06; + } + uchar hightlenght_word_1050[] = { + 0b11101011, 0xFF, 0x05, 0x06, BUILD_HEADER(0x02, 0x1A), 0x05, 0x06, 0xFF}; + + // "Extended word copy" + auto comp_result = ExpectCompressOk(rom, buffer, 1050); + EXPECT_THAT(hightlenght_word_1050, ElementsAreArray(comp_result.data(), 8)); +} + +/* Extended Header Command is currently unimplemented +TEST(ROMTest, ExtendedHeaderDecompress) { + ROM rom; + Bytes extendedcmd_i = {0b11100100, 0x8F, 0x2A, 0xFF}; + uchar extendedcmd_o[50]; + for (int i = 0; i < 50; ++i) { + extendedcmd_o[i] = 0x2A; + } + + auto decomp_result = ExpectDecompressBytesOk(rom, extendedcmd_i); + ASSERT_THAT(extendedcmd_o, ElementsAreArray(decomp_result.data(), 50)); +} + +TEST(ROMTest, ExtendedHeaderDecompress2) { + ROM rom; + Bytes extendedcmd_i = {0b11100101, 0x8F, 0x2A, 0xFF}; + uchar extendedcmd_o[50]; + for (int i = 0; i < 50; i++) { + extendedcmd_o[i] = 0x2A; + } + + auto data = ExpectDecompressBytesOk(rom, extendedcmd_i); + for (int i = 0; i < 50; i++) { + ASSERT_EQ(extendedcmd_o[i], data[i]); + } +} +*/ +} // namespace rom_test +} // namespace yaze_test \ No newline at end of file diff --git a/test/yaze_test.cc b/test/yaze_test.cc new file mode 100644 index 00000000..b972ad10 --- /dev/null +++ b/test/yaze_test.cc @@ -0,0 +1,14 @@ +#define SDL_MAIN_HANDLED +#include + +#include "absl/debugging/failure_signal_handler.h" +#include "absl/debugging/symbolize.h" + +int main(int argc, char* argv[]) { + absl::InitializeSymbolizer(argv[0]); + + absl::FailureSignalHandlerOptions options; + absl::InstallFailureSignalHandler(options); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} \ No newline at end of file