Refactor codebase and complete implementation

- Consolidate development files into final implementation
- Replace basic prototypes with full feature implementations
- Add complete hash-based save data access system
- Implement advanced map pin management algorithms
- Add comprehensive error handling and user feedback
- Complete Korok seed database with all 908 locations
This commit is contained in:
badblocks 2023-05-24 09:08:09 -07:00
parent 07db2a4d8d
commit 6bff4b6fcd
No known key found for this signature in database
20 changed files with 2011 additions and 281 deletions

21
.vscode/c_cpp_properties.json vendored Normal file
View file

@ -0,0 +1,21 @@
{
"configurations": [
{
"name": "Linux",
"includePath": [
"/opt/devkitpro/libnx/include",
"/opt/devkitpro/devkitA64/aarch64-none-elf/include",
"/home/rob/Code/botw-completer/build",
"/home/rob/Code/botw-completer/include"
],
"defines": [
"__SWITCH__"
],
"intelliSenseMode": "gcc-arm64",
"compilerPath": "/opt/devkitpro/devkitA64/bin/aarch64-none-elf-gcc",
"cStandard": "c11",
"cppStandard": "c++17"
}
],
"version": 4
}

21
.vscode/c_cpp_properties.json.backup vendored Normal file
View file

@ -0,0 +1,21 @@
{
"configurations": [
{
"name": "Linux",
"includePath": [
"/opt/devkitpro/libnx/include",
"/opt/devkitpro/devkitA64/aarch64-none-elf/include",
"/home/rob/Code/botw-completer/build",
"/home/rob/Code/botw-completer/include"
],
"defines": [
"__SWITCH__"
],
"intelliSenseMode": "gcc-arm64",
"compilerPath": "/opt/devkitpro/devkitA64/bin/aarch64-none-elf-gcc",
"cStandard": "c11",
"cppStandard": "c++17"
}
],
"version": 4
}

6
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,6 @@
{
"files.associations": {
"dirent.h": "c",
"cstdlib": "c"
}
}

23
.vscode/tasks.json vendored Normal file
View file

@ -0,0 +1,23 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "make: all",
"type": "shell",
"command": "make all",
"problemMatcher": [],
"group": {
"kind": "build",
"isDefault": true
}
},
{
"label": "nxlink: net_launch",
"type": "shell",
"command": "nxlink botw-completer.nro",
"problemMatcher": []
}
]
}

183
Makefile
View file

@ -9,12 +9,43 @@ endif
TOPDIR ?= $(CURDIR)
include $(DEVKITPRO)/libnx/switch_rules
#---------------------------------------------------------------------------------
# TARGET is the name of the output
# BUILD is the directory where object files & intermediate files will be placed
# SOURCES is a list of directories containing source code
# DATA is a list of directories containing data files
# INCLUDES is a list of directories containing header files
# ROMFS is the directory containing data to be added to RomFS, relative to the Makefile (Optional)
#
# NO_ICON: if set to anything, do not use icon.
# NO_NACP: if set to anything, no .nacp file is generated.
# APP_TITLE is the name of the app stored in the .nacp file (Optional)
# APP_AUTHOR is the author of the app stored in the .nacp file (Optional)
# APP_VERSION is the version of the app stored in the .nacp file (Optional)
# APP_TITLEID is the titleID of the app stored in the .nacp file (Optional)
# ICON is the filename of the icon (.jpg), relative to the project folder.
# If not set, it attempts to use one of the following (in this order):
# - <Project name>.jpg
# - icon.jpg
# - <libnx folder>/default_icon.jpg
#
# CONFIG_JSON is the filename of the NPDM config file (.json), relative to the project folder.
# If not set, it attempts to use one of the following (in this order):
# - <Project name>.json
# - config.json
# If a JSON file is provided or autodetected, an ExeFS PFS0 (.nsp) is built instead
# of a homebrew executable (.nro). This is intended to be used for sysmodules.
# NACP building is skipped as well.
#---------------------------------------------------------------------------------
TARGET := $(notdir $(CURDIR))
BUILD := build
SOURCES := source
DATA := data
INCLUDES := include
#ROMFS := romfs
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
ARCH := -march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -fPIE
@ -23,19 +54,169 @@ CFLAGS := -g -Wall -O2 -ffunction-sections \
CFLAGS += $(INCLUDE) -D__SWITCH__
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
LIBS := -lnx -lm
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS := $(PORTLIBS) $(LIBNX)
#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
# rules for different file extensions
#---------------------------------------------------------------------------------
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------
export OUTPUT := $(CURDIR)/$(TARGET)
export TOPDIR := $(CURDIR)
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
export DEPSDIR := $(CURDIR)/$(BUILD)
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
#---------------------------------------------------------------------------------
export LD := $(CC)
#---------------------------------------------------------------------------------
else
#---------------------------------------------------------------------------------
export LD := $(CXX)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------
export OFILES_BIN := $(addsuffix .o,$(BINFILES))
export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
export OFILES := $(OFILES_BIN) $(OFILES_SRC)
export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES)))
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
-I$(CURDIR)/$(BUILD)
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
ifeq ($(strip $(CONFIG_JSON)),)
jsons := $(wildcard *.json)
ifneq (,$(findstring $(TARGET).json,$(jsons)))
export APP_JSON := $(TOPDIR)/$(TARGET).json
else
ifneq (,$(findstring config.json,$(jsons)))
export APP_JSON := $(TOPDIR)/config.json
endif
endif
else
export APP_JSON := $(TOPDIR)/$(CONFIG_JSON)
endif
ifeq ($(strip $(ICON)),)
icons := $(wildcard *.jpg)
ifneq (,$(findstring $(TARGET).jpg,$(icons)))
export APP_ICON := $(TOPDIR)/$(TARGET).jpg
else
ifneq (,$(findstring icon.jpg,$(icons)))
export APP_ICON := $(TOPDIR)/icon.jpg
endif
endif
else
export APP_ICON := $(TOPDIR)/$(ICON)
endif
ifeq ($(strip $(NO_ICON)),)
export NROFLAGS += --icon=$(APP_ICON)
endif
ifeq ($(strip $(NO_NACP)),)
export NROFLAGS += --nacp=$(CURDIR)/$(TARGET).nacp
endif
ifneq ($(APP_TITLEID),)
export NACPFLAGS += --titleid=$(APP_TITLEID)
endif
ifneq ($(ROMFS),)
export NROFLAGS += --romfsdir=$(CURDIR)/$(ROMFS)
endif
.PHONY: $(BUILD) clean all
#---------------------------------------------------------------------------------
all: $(BUILD)
$(BUILD):
@[ -d $@ ] || mkdir -p $@
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
#---------------------------------------------------------------------------------
clean:
@echo clean ...
@rm -fr $(BUILD) $(TARGET).nro $(TARGET).nacp $(TARGET).elf
ifeq ($(strip $(APP_JSON)),)
@rm -fr $(BUILD) $(TARGET).nro $(TARGET).nacp $(TARGET).elf
else
@rm -fr $(BUILD) $(TARGET).nsp $(TARGET).nso $(TARGET).npdm $(TARGET).elf
endif
#---------------------------------------------------------------------------------
else
.PHONY: all
DEPENDS := $(OFILES:.o=.d)
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
ifeq ($(strip $(APP_JSON)),)
all : $(OUTPUT).nro
ifeq ($(strip $(NO_NACP)),)
$(OUTPUT).nro : $(OUTPUT).elf $(OUTPUT).nacp
else
$(OUTPUT).nro : $(OUTPUT).elf
endif
else
all : $(OUTPUT).nsp
$(OUTPUT).nsp : $(OUTPUT).nso $(OUTPUT).npdm
$(OUTPUT).nso : $(OUTPUT).elf
endif
$(OUTPUT).elf : $(OFILES)
$(OFILES_SRC) : $(HFILES_BIN)
#---------------------------------------------------------------------------------
# you need a rule like this for each extension you use as binary data
#---------------------------------------------------------------------------------
%.bin.o %_bin.h : %.bin
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(bin2o)
-include $(DEPENDS)
#---------------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------------

910
source/data.h Normal file
View file

@ -0,0 +1,910 @@
#ifndef DATA_H
#define DATA_H
#include "save.h"
//HASHES.MAP = 0x0bee9e46;
Hashes HASHES = {.PLAYER_POSITION = 0xa40ba103};
Point KOROKS[] = {
{0x2c5b5d,-163.2841,156.127,-784.6775},
{0x59aae8,1694.872,141.9548,-862.0854},
{0x66ded0,-3065.6,604.494,1287.267},
{0x753066,518.627,131.0005,1475.525},
{0x105ef12,-2393.37,233.0458,1047.341},
{0x1a77626,-763.77,156.0443,-606.28},
{0x22e0e12,4634.409,139.7075,-1840.946},
{0x2621e0d,-609.8074,95.24519,2390.653},
{0x30bd873,3721.263,108.243,617.6266},
{0x32d8700,-1382.269,249.2708,1858.037},
{0x3443957,4707.057,292.6219,-1355.02},
{0x37dfc51,265.6219,111.8148,3837.008},
{0x3924391,2181.727,414.9811,2534.696},
{0x3d6015e,-2383.528,211.8481,-1150.632},
{0x42c6214,3709.191,301.4515,1943.087},
{0x4774091,1725.349,607.0526,-2553.939},
{0x4b6719b,-666.9385,128.6065,-543.8143},
{0x4bcb461,1943.746,348.5898,3009.422},
{0x5388d71,806.5719,116.8914,24.09494},
{0x5828e12,-3751.844,157.3583,2531.624},
{0x5a246a2,-3286.434,169.881,3787.151},
{0x60b5dd9,3024.405,107.6149,3654.227},
{0x664971e,4702.884,297.2508,-1039.331},
{0x7518cd7,-2646.005,688.3249,1535.135},
{0x7975126,39.26459,140.7788,1034.492},
{0x7edf88b,-3847.195,471.2815,1467.019},
{0x7f53fae,-681.3192,122.3821,-860.6268},
{0x8546066,354.3845,114.5671,1997.546},
{0x93d1f93,-548.5,140.8805,-229.52},
{0x9533a19,1293.442,273.6983,1331.361},
{0x95d5540,-1992.891,291.315,161.3196},
{0x9af9809,4662.712,169.5986,2376.256},
{0xa467aec,3244.917,265.8715,-2000.31},
{0xaab98c9,-3799.649,128.1501,3428.887},
{0xb03cec2,3075.875,318.8392,-3684.381},
{0xb19b851,-4685.214,171.4609,1970.388},
{0xb358ef9,-135.8379,105.9709,3802.004},
{0xb727016,3148.72,277.1993,2402.78},
{0xbdebc55,4105.454,233.4027,-2836.7},
{0xbfa2096,2032.282,292.1425,3164.345},
{0xc1a9b21,1775.802,219.047,963.6041},
{0xc66c8aa,-4325.409,768.4449,698.2925},
{0xc91457e,-803.96,138.0739,-403.127},
{0xd62d541,-657.7655,187.6206,3851.838},
{0xd90eabf,2791.464,451.4998,-500.932},
{0xde05681,1647.232,521.0447,-2244.461},
{0xe1bab2b,1966.63,365.963,2634.479},
{0xe2d38d1,97.36087,145.4663,3821.548},
{0xe6aa63d,-122.0947,128.7947,594.0034},
{0xe6e49e6,1638.969,116.4747,1376.29},
{0xea24f4c,-1313.943,116.1744,622.8615},
{0xf42e520,-4396.838,183.404,-2049.885},
{0xf9242ec,3277.774,346.3461,1436.003},
{0x10ff5446,-1142.419,182.6268,-761.9467},
{0x11e0cf95,-1106.94,139.4218,905.2623},
{0x12915bc4,-2099.382,205.4608,1104.728},
{0x12a50513,2939.432,122.4304,3427.086},
{0x12c054b3,-4112.895,560.6601,1377.535},
{0x13025056,639.3911,219.0958,3710.839},
{0x1317a6a4,-4252.405,171.9353,-84.01248},
{0x134475fc,1736.363,129.0441,85.67816},
{0x138ac4c9,679.1974,244.7956,2499.422},
{0x139f0bdc,-1965.813,255.7401,600.9499},
{0x13fe59ca,2469.913,514.7255,-3174.503},
{0x140f447d,4508.734,106.4035,-2643.605},
{0x141b4dec,1434.736,117.5035,135.4037},
{0x144479ea,3326.963,309.8105,-3589.208},
{0x14a7d3b8,4533.438,111.2271,1022.985},
{0x1536edde,-2015.552,347.5501,-2456.002},
{0x15905a70,2951.341,246.5786,3005.962},
{0x15c3415d,-95.25006,144.6425,3128.957},
{0x17277806,206.7611,233.044,-3559.005},
{0x17558872,2473.889,231.4696,461.6964},
{0x17620397,4572.536,134.9927,647.8932},
{0x17997994,-2008.684,210.3142,-514.1512},
{0x181364a8,147.1042,128.3034,295.7684},
{0x18c5e539,3436.59,155.1925,-2533.653},
{0x1911ba9b,-872.8973,335.5025,-3316.106},
{0x19b169e1,312.6802,180.2717,1766.797},
{0x19e1da3a,-436.5749,117.5131,-932.8251},
{0x1a51b775,4211.834,106.3895,2270.373},
{0x1af5fbf1,2635.693,269.5276,370.9941},
{0x1b44308f,2427.764,301.4021,-412.1216},
{0x1b50b160,-3069.678,452.0268,910.7488},
{0x1b9c14c4,2170.738,547.0384,-2109.555},
{0x1be2b3ed,-2547.832,299.9424,-306.3023},
{0x1c2cebb5,-3071.388,197.7886,2044.733},
{0x1d26bfc6,-1599.497,307.1487,3099.939},
{0x1e37b9d3,3741.72,542.5132,1156.121},
{0x1e5870f3,715.111,166.3484,1327.026},
{0x1e92767b,-253.853,172.9086,-632.2283},
{0x1ed6d88c,-2290.108,564.2583,-3407.597},
{0x1f7e6066,225.3007,121.9902,1705.663},
{0x1f9d7be0,-2200.96,358.412,730.8455},
{0x1ffc5f3f,-3151.575,185.5,-1563.284},
{0x2067839b,-1969.749,205.3946,1087.833},
{0x21049e6d,-4001.078,324.3853,1566.552},
{0x2172b5da,610.3417,206.4002,2869.851},
{0x219f8191,4104.558,282.0802,-1350.665},
{0x21fa3907,609.2872,177.2309,2409.829},
{0x22008f4a,-601.9537,90.30075,2656.119},
{0x22374558,-1127.287,145.9699,414.3107},
{0x224c2d20,-3224.519,570.7603,1022.451},
{0x23166cb2,-4225.714,216.796,-1747.385},
{0x2435519f,-4340.229,301.8517,-2354.104},
{0x245527c7,-1405.51,162.602,459.7081},
{0x2482e3e2,1313.974,115.9051,503.0696},
{0x24d7197c,3796.614,106.2936,3618.895},
{0x26743533,-1855.986,395.4964,-1192.541},
{0x2685f3a7,-1414.648,228.5877,-2398.596},
{0x26acfebb,-1149.917,218.2874,1204.104},
{0x26bfbead,3893.508,549.9678,-704.2333},
{0x273b4962,-2698.419,414.599,-766.7476},
{0x2761df77,4008.603,195.2031,-2736.307},
{0x27729224,3572.843,205.911,-3046.931},
{0x2789911a,3303.744,393.3527,22.58359},
{0x279bcc46,-486.7185,231.9948,-3142.917},
{0x27d9e48f,-2492.704,310.4511,589.6708},
{0x27ee227b,3783.725,390.7211,2125.184},
{0x285be209,-3861.732,101.0103,-147.1551},
{0x286b87c1,-1314.297,139.1935,1257.335},
{0x28c6a403,-1092.084,129.0204,-497.5138},
{0x293f9601,-1410.552,1.018336,-2224.807},
{0x29531d38,2495.853,205.5029,1804.202},
{0x297ac38f,4038.21,329.6245,-1254.872},
{0x2a134c17,2149.357,262.5131,790.0027},
{0x2a685c1e,-1443.119,284.2529,2105.64},
{0x2a6e88c5,2103.915,422.5005,2726.099},
{0x2a7115b9,-941.4103,133.3554,-817.634},
{0x2a956d11,-1491.531,68.49856,1832.245},
{0x2ad0d275,-3350.53,621.953,-2994.895},
{0x2adc59a7,-1256.743,323.0287,3134.151},
{0x2b2674ca,-267.2103,139.8674,-610.1879},
{0x2b306b21,1625.494,143.747,3891.732},
{0x2b617218,-2850,678.3259,1229},
{0x2ba19d1e,-2550.179,190.0043,2038.102},
{0x2bb51da0,1040.555,121.3508,1318.153},
{0x2bcf5168,-4170.682,193.1844,1989.385},
{0x2bdafa92,-878.7282,245.8745,3567.743},
{0x2bf2bfa3,1799.42,224.8338,3157.655},
{0x2c016340,-230.6865,148.0112,-633.3799},
{0x2c596e0b,-266.3544,125.1503,3888.153},
{0x2c758cd9,-1142.671,116.4736,-284.3372},
{0x2c8c2594,-2259.542,357.4554,2224.756},
{0x2cc21c7d,-4230.893,284.8569,-3134.811},
{0x2d7d823c,-2936.534,471.2046,-2412.46},
{0x2da020a7,3407.366,442.7657,-1278.327},
{0x2e04bfa8,2836.32,126.6323,2120.507},
{0x2e2b3cc3,696.3098,217.9963,-824.385},
{0x2e36e82b,1265.178,116.4061,-707.2505},
{0x2e72c9b2,323.4945,118.2383,1927.427},
{0x2ef650ea,112.3135,116.6742,1709.782},
{0x2f3c2ea2,2728.917,342.0908,904.33},
{0x2fe77b9a,-248.9898,130.3179,3828.45},
{0x30abfb13,2441.137,257.407,-1241.73},
{0x31776e42,4499.122,123.2442,1015.01},
{0x31893753,-4075.584,298.8925,1595.132},
{0x31a00e68,-12.47214,119.7731,2586.321},
{0x31c92a64,1492.117,188.1291,3370.485},
{0x31ed5300,3604.77,334.4839,-1008.638},
{0x32441ef9,1632.926,119,-545.1971},
{0x325137af,-4876.908,153.2946,2469.674},
{0x32594185,-2853.363,210.4986,2320.153},
{0x32cd82e1,-1611.515,411.2915,3678.327},
{0x32db0e32,4071.793,483.7702,-459.0538},
{0x33d12189,-1110.798,438.0612,-3043.856},
{0x3432070d,1012.067,127.121,3258.183},
{0x349f93b4,-2298.86,462.7161,341.1622},
{0x34b9ea2d,-2715.905,269.5669,-429.8643},
{0x34e7350a,-2382.55,498.734,-2132.68},
{0x350236a8,-2483.315,328.1486,504.7361},
{0x35833d5f,-2476.617,307.2358,547.6678},
{0x35d2e144,-3212.859,235.0042,-574.0104},
{0x35d44e1e,3170.416,109.8854,3824.316},
{0x35da7e79,279.0251,184.6331,3503.79},
{0x35ddecf1,-516.9583,154.0469,97.79037},
{0x35ff3af3,-1551.966,167.382,815.4899},
{0x36919813,516.1042,127.0251,1167.103},
{0x3814a1ea,-3277.424,585.327,-2618.865},
{0x38f48417,2403.831,256.6015,2511.222},
{0x397c7666,4817.198,106.12,-3094.218},
{0x399ffe15,-868.5022,187.1793,219.1196},
{0x3a031153,4087.936,423.3066,1142.371},
{0x3a627ebc,3292.116,530.9024,-1428.613},
{0x3aaaf546,1857.431,176.8405,3351.672},
{0x3b1391d4,-1586.488,68.14883,-2133.002},
{0x3b3f009f,-4034.983,273.2282,-1748.402},
{0x3b48064c,-4330.523,160.93,-2052.857},
{0x3b7ce629,4144.261,406.6976,-595.9681},
{0x3b854d84,3896.64,416.6681,1556.54},
{0x3b8acb25,-769.8831,175.2213,1574.225},
{0x3bb376d3,4338.091,170.552,-2438.518},
{0x3c5e4ee6,1412.024,408.7473,-1759.805},
{0x3c716aa0,-4180.768,440.3622,1482.394},
{0x3cd4b5f0,2636.166,205.2848,1108.997},
{0x3dc85c5a,-1819.302,248.4935,973.5981},
{0x3e1546e4,-353.38,286.3675,-829.6086},
{0x3e4f52e6,4136.606,521.7107,-408.5667},
{0x3e7a2c72,-332.594,299.3984,-1747.388},
{0x3ed4373c,-2019.698,375.7961,2884.231},
{0x3ef6c241,1687.556,427.395,-1717.087},
{0x3efdd10b,-398.4,103.87,2559.24},
{0x3f8cebc3,-4011.171,205.6772,-1167.086},
{0x3fe2d9ba,2087.115,318.2577,-3573.556},
{0x40041a33,370.4178,92.51205,2567.043},
{0x4083454e,-4402.555,415.0383,-2866.692},
{0x40c903b6,1562.56,298.6208,2898.317},
{0x417748c0,-1970.932,420.7117,-3792.569},
{0x421ccbdc,-3327.45,3.924433,-336.9249},
{0x424fc160,1750.43,116.3929,1544.69},
{0x42baf164,-4307.612,132.1694,3459.745},
{0x42cf300d,-4409.103,618.9225,331.3417},
{0x437626cf,-2022.654,390.9383,-1300.632},
{0x44260d03,367.097,176.9335,3642.119},
{0x4437570a,4042.218,351.5685,-661.9659},
{0x44760b6f,3291.972,295.3834,-261.1206},
{0x44bae869,-2210.599,152.8292,-1621.4},
{0x44e4d73d,4239.353,409.8841,-998.2581},
{0x450b9f2b,-1996.6,301.5532,3619.667},
{0x450bc0fc,1188.64,323.4319,2476.71},
{0x458327c7,613.4128,183.5145,-743.3782},
{0x45c63ebb,4615.143,106.2173,1915.474},
{0x45cafb59,-3610.649,561.9243,-3491.99},
{0x45e64655,-2297.368,424.8451,-2293.149},
{0x45f2d306,1885.784,513.9319,-2749.106},
{0x467ee8b3,-308.7722,132.6444,-1166.005},
{0x46ef8e1d,-1590.039,210.7338,-229.1346},
{0x47079416,271.7195,222.3727,3289.589},
{0x470abbf6,416.7571,106.4126,3848.923},
{0x471abe01,-1512.017,177.0386,56.45966},
{0x475ded63,868.2729,142.6162,1902.033},
{0x4784fd6b,418.2094,128.0125,2873.406},
{0x478bf467,-4039.641,239.3008,-350.2388},
{0x47f4c0e2,3813.457,255.9981,-3419.22},
{0x485ae219,1055.116,167.1361,3254.771},
{0x48eb753e,-40.78424,306.5025,-2985.747},
{0x48faa931,-2836.955,348.8333,-1594.782},
{0x492c8b33,2811.316,239.6189,2391.926},
{0x49305266,2891.033,234.1595,517.871},
{0x4963817f,-1155.97,137.3342,245.1235},
{0x497b3aa1,-68.0202,91.39095,2332.616},
{0x49cb2b7f,34.27469,115.5547,2102.726},
{0x4a0d4d30,2991.393,118.1034,2272.146},
{0x4a1b0c3e,889.6107,180.8653,2395.303},
{0x4a278879,-2305.082,486.2545,2561.364},
{0x4a4be4b2,-512.7507,170.2696,550.6234},
{0x4a68f549,3726.792,127.2903,-2677.462},
{0x4a9fe113,-1057.312,167.5325,1327.525},
{0x4add63de,1074.55,182.0952,3620.945},
{0x4ae88291,-4195.749,165.6116,3091.554},
{0x4b1622c8,1374.621,107.2461,3751.464},
{0x4b225629,-2908.738,116.6645,796.266},
{0x4b864ab7,216.3226,199.1464,3488.015},
{0x4ba7a2f7,4697.84,335.7005,-547.03},
{0x4bf81bb3,517.5668,193.8545,3765.023},
{0x4c34123f,3171.941,293.8482,1490.935},
{0x4c435209,3350.103,175.0276,-3079.839},
{0x4c624fdd,160.0443,150.4367,1942.172},
{0x4c676609,1217.386,135.0406,3524.105},
{0x4c71cd7d,2684.855,218.5164,562.7817},
{0x4cbf31a5,2769.947,123.2163,348.8461},
{0x4cf9af7a,2504.476,312.2056,-1304.284},
{0x4d57c17f,551.5767,182.9,1903.507},
{0x4d7068c2,-2729.922,219.9338,761.3842},
{0x4dcf791e,-1047.625,139.6863,-2620.561},
{0x4ddac174,3206.764,312.2505,23.68088},
{0x4df49e60,-68.0647,261.281,-979.6238},
{0x4e05dfc4,-3441.073,357.3612,-664.8755},
{0x4e1bec8d,-792.036,201.3972,2257.223},
{0x4e86f173,-3971.633,213.6341,-920.5166},
{0x4ea8552b,-250.1414,432.8846,-1061.673},
{0x506472d9,4541.932,109.8,2405.64},
{0x50ab1278,-1728.585,144.3969,1478.864},
{0x5205d39d,-1224.69,299.7989,1358.416},
{0x520b5971,-190.9501,121.6845,1831.54},
{0x526ee929,-2175.129,407.0975,463.3505},
{0x52d18fa9,4452.651,164.2638,483.9736},
{0x52e200aa,-2817.465,578.2277,1652.721},
{0x52eabbf9,-599.9459,138.0255,1071.816},
{0x53449f3a,1101.693,224.2867,1889.54},
{0x535989d9,-3444.365,231.2116,-1328.69},
{0x53bf9a40,-74.38333,90.54819,2412.872},
{0x542ca5dd,2752.294,233.728,-1366.336},
{0x5498e0e8,1877.425,132.5337,2051.324},
{0x55d95f2b,2655.789,261.746,-971.1711},
{0x5603fd19,516.767,167.2447,1788.169},
{0x56323b35,-427.4001,317.6273,-1734.047},
{0x564f942b,-2638.9,410.0378,-2364.1},
{0x567c4331,3797.93,577.8524,1269.197},
{0x56a7b9b9,-2207.487,253.303,-1767.467},
{0x5700b68a,2511.433,120.0366,1571.525},
{0x578f3784,-2989.566,222.6,-2164.987},
{0x57ebd46f,-1962.841,314.6183,409.854},
{0x581282c5,69.30228,121.1721,1438},
{0x583a94ae,-2041.04,425.5532,296.3528},
{0x5848c075,2636.233,191.5871,3197.799},
{0x58932cbd,1676.101,324.6342,1157.939},
{0x5893c1cd,-4710.485,209.7189,2171.835},
{0x58ed79fc,3297.691,466.4747,-1583.792},
{0x5911354c,-253.8293,141.7269,-425.7258},
{0x5947fa66,2019.416,557.7247,-2172.899},
{0x595194e8,-4330.862,441.8892,-2600.161},
{0x59613b7f,891.1671,284.3683,3694.827},
{0x5987853d,4396.832,224.3599,-2721.584},
{0x59ab55bb,-3295.154,250.0965,-1362.929},
{0x59e0685e,-1805.357,31.56281,-1842.527},
{0x59e4f211,1088.531,164.7885,-215.8946},
{0x5a432e0e,-2448.412,134.736,3751.94},
{0x5a4a3917,-2602.175,508.3545,-3238.931},
{0x5ae18d84,-3831.341,248.413,-2106.709},
{0x5af84790,-2340.702,249.8667,1104.579},
{0x5b2750bd,3178.812,177.0007,1607.304},
{0x5b374fba,-4071.819,131.4124,-2545.949},
{0x5bc2358d,1739.307,413.3752,1186.675},
{0x5ced9ad3,2559.241,344.0077,3602.712},
{0x5d4170ff,3525.984,454.0448,1710.623},
{0x5d8f46c1,-2783.552,838.5354,-2895.525},
{0x5e2633fd,3271.144,105.9228,656.8208},
{0x5ec0d1ab,1323.723,194.4022,2453.452},
{0x5ef432e2,1387.279,135.2196,-112.9289},
{0x5f208f59,1886.184,147.4078,2418.735},
{0x5f622fdc,1008.131,270.2619,-1564.019},
{0x5fcdbd75,1377.204,322.4067,-1261.174},
{0x5fdb248a,1282.642,129.65,-1123.445},
{0x5ff70e36,-2521.762,457.0563,1318.59},
{0x6044b661,-653.6451,159.1371,1390.29},
{0x604688d4,1936.528,492.9896,2778.544},
{0x604e6f4c,-2842.696,333.9389,-3493.488},
{0x6071fa85,-1379.17,592.9069,3328.08},
{0x60c729d3,3779.707,275.4236,-3361.52},
{0x60ebf61e,1940.15,226.0126,-1217.732},
{0x610076d6,-1877.903,243.7032,-32.18372},
{0x6115ec62,-3476.202,154.9382,-69.05823},
{0x6134dc7d,4438.906,141.7224,1432.916},
{0x61895378,-26.89398,107.8101,3042.69},
{0x621d08df,-2946.503,686.9847,-3146.699},
{0x62939b45,2132.422,321.1151,678.8488},
{0x62cd12c3,-4862.196,129.3502,3260.965},
{0x62ef4882,2663.897,564.496,-2066.873},
{0x63643f49,-609.5657,119.0036,-682.3019},
{0x63a4612c,4199.456,107.1416,463.675},
{0x63fbbcc0,-567.7869,489.6004,-2599.203},
{0x64406b98,-3828.839,160.1595,-118.4242},
{0x645bf0a5,-38.98267,152.9507,2513.643},
{0x649e315a,-423.3546,125.2606,2022.457},
{0x655a0c0f,-1370.342,174.2264,1165.821},
{0x655ac3b3,-4183.675,491.7545,291.0669},
{0x655e5c8b,1537.85,505.3825,-2091.503},
{0x667c2c2c,2239.665,337.9715,726.3528},
{0x66a49116,-1336.888,122.5514,249.6623},
{0x670c85ff,-796.22,187.6677,-558.8558},
{0x6720557f,2330.776,133.963,1828.012},
{0x6789cfcd,-670.0859,119.1157,-932.6809},
{0x67e0b113,-1926.303,264.6315,3241.999},
{0x6801dca3,4332.92,406.9635,-696.6332},
{0x68de4eed,-3331.95,508.7438,-2297.167},
{0x69c59d49,4264.459,126.7609,628.2208},
{0x69c884cb,1803.734,202.6011,3221.996},
{0x6a047ec0,3112.552,426.0035,-1295.329},
{0x6b93ced0,-54.77505,128.9469,2492.44},
{0x6c199e80,-935.2057,167.8454,-641.2414},
{0x6c4af732,2303.51,281.3,2375.135},
{0x6c88172d,-3966.312,293.9241,-624.5618},
{0x6cd70d96,-1334.809,232.6704,1675.9},
{0x6ce27815,2517.501,182.504,-212.4814},
{0x6d337dd5,-2467.77,620.801,-2765.222},
{0x6d65fa2a,2884.092,160.9207,1765.027},
{0x6d9a328b,909.6229,183.5958,3837.292},
{0x6e05e450,-239.3844,139.7745,-112.5946},
{0x6e425edd,623.2406,123.537,-194.769},
{0x6e4b275d,5.321655,207.8237,1897.896},
{0x6e998846,-4192.807,288.3735,-2678.943},
{0x6e9bbc97,295.5803,135.2223,1204.796},
{0x6f884090,1381.904,288.3027,2277.448},
{0x6fc72def,-3673.786,550.7923,698.3047},
{0x7012ae43,4282.686,289.0398,1655.666},
{0x7017c7d1,-335.4028,256.5638,-1003.319},
{0x70665f74,-1809.821,162.5114,2459.625},
{0x707072d3,-3714.738,302.7229,-1040.965},
{0x70799bef,-354.8371,182.5916,3898.783},
{0x70b00c66,2665.531,205.7801,-1.298676},
{0x70b4b53c,-2247.72,446.0183,464.6729},
{0x70e63ec6,-3845.235,412.2645,1897.052},
{0x712b0ea5,-254.3532,146.8498,-264.4141},
{0x7166a639,-1512.686,117.3846,908.6653},
{0x7169f507,3166.324,193.831,1828.891},
{0x7186e8b8,-1132.606,238.2254,1917.723},
{0x71afefbb,-3757.127,375.4655,-3848.083},
{0x71d5d765,-423.0228,169.4002,1993.361},
{0x71e86829,1404.953,122.0926,-832.9891},
{0x71e8a107,-1176.851,344.9949,3578.054},
{0x71f54da2,3475.639,278.6932,1916.261},
{0x721f1852,790.6398,159.6066,2565.135},
{0x72d01780,668.647,135.4751,1468.298},
{0x731a1644,-2316.8,206.6814,-806.4525},
{0x7489ba85,200.8704,92.34924,2603.86},
{0x74d76fb9,1398.038,125.9827,-856.3475},
{0x74e51faa,54.9873,146.9078,1758.558},
{0x751e528f,-4266.573,226.0547,1691.536},
{0x754daf9f,-4058.83,208.5266,-773.8512},
{0x75910bc5,-1859.587,272.6248,334.3039},
{0x75e0dfc6,-853.2325,181.421,1671.219},
{0x76caf587,2484.83,119,2103.393},
{0x7733f2b8,1449.474,222.6956,3531.368},
{0x778f207d,-2012.6,127.1831,-1921.7},
{0x77efae60,232.2081,115.3543,1601.418},
{0x7815fb3a,3083.239,363.9244,-167.6896},
{0x782c2165,2508.15,157.6213,3825.909},
{0x787bd471,3639.774,326.9118,3258.224},
{0x789ebea5,-4314.106,219.0169,1629.409},
{0x78ca3e57,-2207.692,432.1688,2550.621},
{0x78fbe96b,2925.468,478.7521,1401.573},
{0x7901258d,-227.2847,176.7279,3342.734},
{0x79333e04,604.934,177.1582,2408.781},
{0x794f242d,-1935.345,452.7967,2673.502},
{0x79c7e150,-3688.848,740.4763,798.725},
{0x79fdfdf9,-2018.632,188.74,2186.643},
{0x7b10dfc2,-2636.621,444.7024,-2048.352},
{0x7b7ba39e,-1227.239,255.96,-1578.176},
{0x7bb7d834,-4552.238,623.3943,1353.159},
{0x7bfe2497,87.0126,164.5443,1585.099},
{0x7c0867ac,-2628.115,168.4946,2751.206},
{0x7ca4ffb4,625.1648,164.7659,2305.906},
{0x7d12a804,-2036.946,48.7074,-1622.946},
{0x7d787c89,-3677.899,426.2462,-2466.755},
{0x7dd35902,-2429.137,203.4877,1921.336},
{0x7dd43b3d,1867.815,511.0075,-2400.638},
{0x7de6bf97,788.8382,145.8729,1471.354},
{0x7e4d566b,2294.48,287.5065,3028.171},
{0x7f7d12eb,-3803.935,251.2842,-772.4634},
{0x7f8291b4,-1721.226,143.1919,2237.781},
{0x7fc87ad6,-115.4848,186.8435,2303.392},
{0x80826056,-2910.18,382.2979,-1639.037},
{0x80cfe359,644.1887,116.8154,1763.264},
{0x80d58d7e,4691.71,136.7105,-1777.33},
{0x80e46a95,-1280.393,284.6875,1384.899},
{0x80ec4d12,1865.555,533.9347,-2465.044},
{0x81f28000,-3115.97,496.3582,-2806.234},
{0x8292f970,4698.904,345.4613,-1003.025},
{0x82ac968e,400.8698,142.0619,2150.868},
{0x82ea3f2d,-1094.139,210.8778,-1731.894},
{0x82fad086,-1682.218,353.4708,-2184.838},
{0x830f1ec0,695.5233,119.4377,3071.41},
{0x836fa5ed,-2636.197,101.8104,3302.574},
{0x83bf0a9b,-1526.976,397.5132,3405.893},
{0x83dd4e76,2058.505,244.813,1208.554},
{0x847d126e,584.4322,217.5105,2678.335},
{0x8490d920,-1964.676,221.2041,-584.1647},
{0x84c082c4,-1799.607,114.8927,1625.901},
{0x853ee307,-3734.782,446.5874,-2964.398},
{0x8583858c,2315.027,293.5242,-1133.257},
{0x85fd0726,-2826.254,193.1497,-1580.078},
{0x86b9cf34,-2972.812,377.3,-1878.102},
{0x86ceb585,1049.239,115.8737,1783.277},
{0x86d7be5a,-3.030243,90.672,2614.667},
{0x86e964bc,-3207.551,5.917226,-333.9864},
{0x86f2438b,4518.497,219.7798,2316.516},
{0x879574c2,-4136.396,401.4471,1717.96},
{0x87c85b50,-2791.13,397.6961,-1945.598},
{0x881390d3,-822.6375,171.2339,1546.921},
{0x8818e264,704.9866,116.7559,1796.567},
{0x881a3647,-1062.994,226.9131,-1934.109},
{0x883875aa,-4224.869,154.6506,2738.074},
{0x88cc839d,2276.034,162.2581,1501.621},
{0x88e54d6b,-240.1111,106.0764,3882.502},
{0x89ca3c5d,850.5078,115.3998,1623.993},
{0x89e19447,-4424.155,497.1648,-3215.942},
{0x89facd12,824.9434,120.7363,3005.301},
{0x8a07fb55,4344.057,363.3881,-3178.368},
{0x8a1c1396,-2900.084,498.6471,-2508.787},
{0x8a3b5037,2085.788,129.7888,181.6626},
{0x8a4b420c,-4355.337,716.6,709.874},
{0x8a6c5698,-394.0272,204.58,-785.4035},
{0x8ac957d4,868.0159,209.8152,-1362.166},
{0x8ad9e8a7,-1336.357,117.1225,366.6163},
{0x8b14d443,-4160.327,133.1369,3826.202},
{0x8b47a5fb,-133.7057,143.3529,945.0361},
{0x8b8a196a,-3418.51,286.3803,-2066.815},
{0x8bfd9414,-2547.427,141.4355,3951.93},
{0x8c119354,4422.963,115.1583,-3340.219},
{0x8c2a33fa,2874.915,299.74,2683.368},
{0x8c323e3b,-2172.509,185.7276,3200.396},
{0x8c3a4e37,2409.547,269.6053,849.3189},
{0x8c5a8b69,1245.111,541.3436,1942.178},
{0x8c5bda77,318.1566,115.3873,1397.902},
{0x8c6caeff,-251.8438,517.1672,-1061.771},
{0x8c750182,1821.037,272.0274,3742.026},
{0x8cb6e831,-4607.906,161.6079,2338.845},
{0x8d17595f,2526.617,334.827,1257.579},
{0x8d908351,3736.669,147.3763,-2884.984},
{0x8dec90ea,322.0657,127.5006,525.0073},
{0x8df0c4a7,-753.6708,151.1773,-1086.794},
{0x8df41fab,4144.438,138.3371,195.9695},
{0x8e40d3ee,-4220.021,257.5498,1659.797},
{0x8e4adad4,153.9499,143.8689,2981.718},
{0x8e6ff49f,-886.65,129.2583,-274.04},
{0x8eb3216e,-420.7542,141.3747,3368.484},
{0x8ebae5b4,406.1136,139.9,3051.134},
{0x8ec92e81,2266.556,347.3776,-1565.486},
{0x8ee513d1,3122.881,185.6049,-17.39868},
{0x8ef728de,1980.929,174.2776,451.9176},
{0x8f03405e,-2053.485,258.4682,636.411},
{0x8f2a30e1,4080.406,421.4792,-216.7825},
{0x8f3ab788,4134.865,294.9371,60.32083},
{0x8f633554,-923.501,214.5819,3436.38},
{0x8f706bf5,3432.942,342.9529,1150.31},
{0x900525b6,-3414.794,542.0234,-3509.611},
{0x907adc44,-2523.397,364.8272,-1736.947},
{0x90931b5a,3420.944,340.3562,2390.287},
{0x909ff681,-1249.552,125.526,730.6769},
{0x90aea807,1552.487,182.8108,3529.241},
{0x90da6b48,3431.141,146.4093,523.7474},
{0x911bcd90,1185.502,164.2552,-67.4191},
{0x914e5c8b,396.0804,115.5029,-625.5601},
{0x919a1346,1406.713,255.4892,3198.755},
{0x91d09be7,1116.142,119.931,555.5753},
{0x921c662a,-1922.226,332.9751,3279.693},
{0x9295df6c,-1356.697,140.9515,1002.412},
{0x92ae480a,69.03473,127.14,3221.873},
{0x92ccabab,-1666.661,249.2757,1393.96},
{0x93269172,85.54697,138.1385,-634.9767},
{0x938cdf69,-1651.16,224.8122,-39.06839},
{0x93dbf4f8,2968.719,122.9329,3380.182},
{0x93ea4614,506.9064,141.8195,-882.6183},
{0x944bb152,13.95764,106.5948,3790.43},
{0x945bd1cd,686.0379,167.9348,-635.104},
{0x947bb87d,-368.9545,151.4308,-993.4459},
{0x94875ae7,1773.844,346.6876,2930.867},
{0x956be08e,-3461.163,176.1707,166.2989},
{0x9596e203,-168.3692,216.0174,-860.4059},
{0x95cdfa70,-4123.615,303.5288,-1935.337},
{0x9615d0d6,1373,220.294,2749.046},
{0x963411fc,-2358.595,385.0072,-1872.809},
{0x9696539d,-3715.859,570.3722,1558.073},
{0x96c02c14,755.6919,194.098,2347.605},
{0x975b52db,4428.835,352.2694,-3182.9},
{0x97b2deb4,3010.155,346.4312,-1204.248},
{0x97c9c11b,-1258.633,138.6124,-2360.096},
{0x97e79802,1840.689,135.0218,3595.827},
{0x9812135c,4083.595,109.3641,2973.261},
{0x98143e94,-3843.155,435.3878,-3348.182},
{0x985f3beb,-2918.603,118.2453,479.7349},
{0x98753d6c,-1066.794,208.4339,2910.011},
{0x98e17eee,-2918.655,141.7088,3061.014},
{0x992cf785,699.92,133.6721,3276.863},
{0x9966d589,-2338.221,369.2435,-1726.701},
{0x9969542a,3479.966,280.7756,-2077.341},
{0x99736b62,-265.7393,250.3626,-1138.757},
{0x9988d511,1517.272,400.2469,1850.083},
{0x99996f7e,685.1261,431.8878,-2758.458},
{0x999c8205,742.8929,134.0192,3243.08},
{0x9a2a7ab3,-1399.424,220.2027,2378.205},
{0x9ad72bfb,3288.675,511.2913,-1574.587},
{0x9b3310be,-1501.964,118.0242,156.2179},
{0x9b5dda92,-1134.464,143.8477,1030.472},
{0x9b7cd7b0,-663.3021,146.7741,-432.6016},
{0x9b7f8797,-1148.198,149.3743,-226.6854},
{0x9b88be59,-4065.467,316.0535,-1678.328},
{0x9bebaec0,1748.572,140.6938,1921.653},
{0x9c1bfb39,3144.467,163.4093,2229.855},
{0x9c75e5f8,-1077.38,238.5356,-1278.708},
{0x9c77f87c,3882.549,356.5327,-1340.015},
{0x9db69b95,-3627.384,453.5585,-1804.825},
{0x9ebdaa4c,1615.105,207.955,-3661.03},
{0x9f0488fe,-3107.278,135.387,2881.241},
{0x9f5bf5e7,-1503.422,297.2265,1920.174},
{0x9f8b8360,2366.56,221.7048,2303.499},
{0x9f8c6f32,3561.943,106.2442,626.3196},
{0x9fadacb6,-2217.829,321.1888,-1565.024},
{0x9fbac800,589.7725,121.4821,-1107.129},
{0x9ffb6db1,-3353.04,156.9178,2276.308},
{0x9ffc1594,3229.815,256.5484,2848.442},
{0xa0d80366,-1258.401,159.7504,-240.5181},
{0xa1300acf,-2645.98,300.1651,547.9241},
{0xa169ce01,2163.896,460.6209,1034.737},
{0xa1a2edef,-4340.954,767.3851,782.1329},
{0xa206700f,1513.742,136.271,3725.037},
{0xa2217391,2139.981,200.2839,3531.94},
{0xa26bf7c8,-1731.076,216.9656,375.1318},
{0xa2b4a213,3687.959,107.3202,2413.493},
{0xa394e375,833.7554,145.3382,2434.576},
{0xa3c26a27,-644.5822,146.2107,876.1129},
{0xa3cecb89,97.63947,181.0175,-429.8078},
{0xa44b516c,66.22549,94.00381,2310.65},
{0xa4e8182d,1793.9,258.8986,1052.825},
{0xa5235679,-2487.656,514.3344,-3021.601},
{0xa5b0ddd5,3662.784,273.6752,-2067.316},
{0xa5f5aed7,-1375.173,361.9268,-3640.943},
{0xa63ff4cc,1378.099,256.94,3503.561},
{0xa664790a,-66.24554,124.0046,2440.657},
{0xa6a81087,4356.779,284.9696,-1528.1},
{0xa6f93c08,3527.287,395.3051,-276.7639},
{0xa79e3be3,-4019.884,130.8091,-2350.359},
{0xa7cbccfa,-2417.311,191.1999,1923.725},
{0xa8810dca,-2167.784,336.4488,2082.042},
{0xa89818b7,2836.962,126.8794,3452.763},
{0xa91201aa,-4167.162,516.8201,-3615.937},
{0xa92b45ef,-425.2748,131,1189.346},
{0xa956dc79,292.1846,117.2136,-724.0883},
{0xa9bb8861,-1349.376,241.7028,-2734.519},
{0xaaf7b209,-925.2401,237.0128,2936.44},
{0xab116079,3347.619,209.942,2249.252},
{0xab4471a0,1733.161,168.0593,3450.589},
{0xab7ee389,4536.525,106.4408,2520.272},
{0xac952baa,-3496.125,474.2198,-3580.674},
{0xacfc460d,2195.503,613.2101,-3007.841},
{0xad58d3ce,2320.668,119.2743,1726.367},
{0xad635dca,3877.544,178.8445,-2371.863},
{0xae2177a0,-4029.339,464.8524,-3760.179},
{0xaeaa31fe,2233.992,338.4426,-3673.525},
{0xaed4da21,-150.92,143.3865,3067.3},
{0xaf068a5a,384.2617,154.1735,135.3624},
{0xaf1381a7,474.9577,115.2629,2149.122},
{0xaf46339e,-3109.259,34.17905,-909.2654},
{0xafd6ac26,-1675.992,96.53553,-2139.302},
{0xb092991a,1660.151,252.6535,3163.642},
{0xb0978dc0,-1658.59,159.12,2306.77},
{0xb0a896f6,-4507.235,226.3406,-2146.108},
{0xb0d722c0,-2594.755,284.7202,2539.869},
{0xb1ae7c07,-2836.292,501.8753,-2423.835},
{0xb2972d36,1632.017,585.5543,-2939.5},
{0xb29ba230,-4353.388,242.2131,1838.526},
{0xb29d5968,-1351.458,448.5679,3770.793},
{0xb2c7a150,-324.3851,185.6199,-798.1587},
{0xb30d16ad,-1095.986,413.9733,-3399.873},
{0xb38f3294,-3431.202,278.0103,-707.841},
{0xb3d00fa3,3029.036,114.8,2017.677},
{0xb3fa9939,224.1717,135.2091,2868.403},
{0xb42b2abb,-247.1635,211.8434,-739.613},
{0xb50397e3,2060.978,580.314,-2757.42},
{0xb50f57b1,-3780.539,368.6099,-1865.624},
{0xb52de9f9,2279.315,182.4268,1608.345},
{0xb539c88a,-1190.024,174.9518,1116.745},
{0xb5f30638,-100.9207,131.378,-979.7477},
{0xb6514b9c,2355.876,524.6516,-2067.376},
{0xb690acc0,-1372.536,115.847,-107.9869},
{0xb692e371,-2081.09,353.6358,1477.029},
{0xb6a4fe6e,-3999.216,632.9622,-3620.06},
{0xb6f62fe4,-2370.105,307.047,-345.3073},
{0xb77452ca,1143.403,209.9631,-3742.778},
{0xb88a8351,518.3896,211.5482,2492.625},
{0xb92bcf9a,-965.4801,187.2091,1625.697},
{0xb93698b0,3175.443,309.289,3204.03},
{0xb97c0a67,3732.84,139.5452,-2423.215},
{0xba2cee6a,2275.006,134.982,-720.1478},
{0xba424efe,-1230.517,207.6727,-999.8165},
{0xba58f3fc,2408.195,262.344,-1229.951},
{0xbaba4538,-254.0015,210.5489,-739.5409},
{0xbad8620b,-427.2841,135.8405,150.9248},
{0xbb03c92f,3152.594,170.1656,-3328.348},
{0xbb45ccb7,1785.537,344.3603,3011.07},
{0xbb4bfa62,-3078.344,207.994,-1120.356},
{0xbbb11045,3321.498,414.0922,-514.2532},
{0xbbba17c1,340.6279,94.2322,2830.629},
{0xbc7389bd,86.2337,138.8198,-412.086},
{0xbcbec70f,-2516.125,61.96953,-1436.305},
{0xbcf9ae6f,3537.012,313.5478,1376.113},
{0xbd828e2c,225.3818,173.6473,872.0403},
{0xbde42185,954.403,116.2789,942.4681},
{0xbde4dc1c,-1125.279,157.9102,-675.4301},
{0xbdf2209a,-953.0682,201.5502,1721.484},
{0xbe4a5e9b,-383.2059,347.4652,-993.6246},
{0xbe8daba7,178.5485,134.0422,-940.0205},
{0xbeceb922,-2867.818,518.5404,1124.927},
{0xbf572908,1104.015,210.7557,-444.2307},
{0xbf74ae6d,627.0391,130.941,182.307},
{0xbfbebf6e,-1357.034,479.6575,3671.94},
{0xc0514ef5,-3562.246,289.5035,-1761.346},
{0xc0547b5f,-1984.865,348.4926,362.9465},
{0xc0851403,2378.29,231.6163,373.1468},
{0xc0c5b569,-4155.937,350.4482,-3404.128},
{0xc0cd8a7f,-2060.66,259.4979,-775.7871},
{0xc12bdd2b,1757.802,253.7049,3685.978},
{0xc1d550bc,3323.916,301.6292,-519.5153},
{0xc22ceff6,-2434.115,319.8664,-491.0357},
{0xc232a5db,1685.603,129.8256,661.1248},
{0xc239ed48,-1115.559,151.9816,-528.5893},
{0xc2cb5826,-1019.516,222.8577,-2077.297},
{0xc2e1762c,3496.163,255.9283,-3374.297},
{0xc30ec0c8,1258.459,492.1165,1851.127},
{0xc31f0b04,-1403.117,101.0272,-2312.289},
{0xc32c01ee,-1125.951,315.8488,3624.428},
{0xc3ae20b1,-3574.575,494.2303,-3272.382},
{0xc3b32918,1936.541,134.2709,2564.501},
{0xc4a46604,2054.829,153.2433,2092.73},
{0xc4c62b2c,-466.4118,137.2151,1279.382},
{0xc5001ffb,-1379.586,215.0948,2742.734},
{0xc54c483d,671.092,180.8665,1638.379},
{0xc55a580a,-1204.356,329.348,2322.776},
{0xc57a665c,-2542.837,307.7846,639.8586},
{0xc5b90c80,603.3977,249.912,-3633.77},
{0xc5e9f609,-4148.758,216.3956,-2616.475},
{0xc61db84f,4098.317,232.8195,-1756.464},
{0xc6a34951,-1017.86,116.9594,-1066.078},
{0xc6fe441e,-2736.11,456.88,-2582.83},
{0xc74e2a27,3960.616,378.5291,-858.5881},
{0xc7b919e2,-4527.836,571.9739,1423.325},
{0xc826318a,3208.673,570.4832,-1011.226},
{0xc8679196,-703.6862,247.6578,-1443.785},
{0xc88964c5,3709.392,204.173,-1683.445},
{0xc88dcc27,-270.2613,255.1069,-879.1967},
{0xc8ba33c8,2288.527,250.7979,699.6213},
{0xc919c75f,-4482.926,266.7692,-1970.876},
{0xc996c2e9,1682.657,201.4698,2327.619},
{0xc9ef2e6c,1544.331,394.203,-1837.214},
{0xc9f260d3,-2636.284,300.5481,-1246.991},
{0xc9fb4ba8,-737.4062,125.8594,333.7565},
{0xca074b9f,2927.666,292.9401,332.8004},
{0xca1474b6,-1615.964,193.3715,2447.329},
{0xca31bdfa,169.7322,118.7293,2903.416},
{0xca4be8f1,-770.0294,135.0662,1380.977},
{0xca72f256,-147.5123,188.9713,-1159.794},
{0xcaa658ea,-1035.085,150.2215,-446.2222},
{0xcacc2df3,-1011.91,330.58,2638.47},
{0xcb09ff3f,4274.364,430.7932,1981.021},
{0xcb637a36,-3207.789,37.56471,-494.8928},
{0xcb8bdf6e,-809.2235,297.7529,1966.909},
{0xcbf505e2,581.2495,123.0391,3007.603},
{0xcc29f2e1,-130.5417,168.7775,-1379.279},
{0xcc2f05cf,-4859.178,172.696,3832.948},
{0xcc35335a,-2264.512,356.9891,2163.38},
{0xcc5c6d8c,1832.722,217.9547,-535.6974},
{0xcd93538a,3516.118,160.2076,2628.382},
{0xce90cbd2,-749.9227,132.9082,892.2105},
{0xced040d3,1593.879,543.9135,-2475.25},
{0xcef4746e,-3271.391,244.4316,-1868.258},
{0xcf43cc73,-2464.743,417.7118,1713.475},
{0xcf4a869e,-378.6588,163.6076,-1112.098},
{0xcf58e63d,3229.032,302.8331,1545.245},
{0xcf88b5d2,3367.108,109.9,3653.537},
{0xcf8c8a6b,-254,364.0167,-994.6138},
{0xcf9d7c89,3441.938,216.0831,3121.876},
{0xcfd54587,-4066.787,569.1418,437.8475},
{0xd00a5f8c,-4347.897,142.8856,3713.184},
{0xd022178b,-3696.666,211.106,-1684.11},
{0xd0cd4001,3237.797,479.9398,-1527.746},
{0xd0fd5dce,-2450.164,317.9307,373.4799},
{0xd122eec3,-2685.725,206.0558,2929.656},
{0xd186c389,337.1497,120.0506,1271.062},
{0xd1f96d16,56.69495,109.8976,3150.023},
{0xd24e7a25,4232.734,385.9994,-212.3339},
{0xd2ac12eb,-1436.289,231.0027,-1668.662},
{0xd2ba8c37,1593.187,115.9848,114.1612},
{0xd2fb91a3,-2984.896,559.2073,-2693.526},
{0xd3d6c91c,1549.113,533.4022,-3108.549},
{0xd3eb5666,-1439.601,125.505,846.6677},
{0xd4031665,-2830.556,669.6175,-2828.345},
{0xd40caa6e,-1583.931,68.69307,1579.691},
{0xd5210e5e,3296.232,459.8649,-1421.087},
{0xd5d14cc9,1957.253,248.0698,1062.054},
{0xd60dddfc,2171.211,198.8678,3276.907},
{0xd61e3051,3901.082,235.8,2096.729},
{0xd62e065c,2746.148,237.5875,-176.402},
{0xd652c264,237.4364,304.0661,-2943.386},
{0xd656293a,3565.886,530.6382,-915.9223},
{0xd6db8c19,908.2865,247.1734,2193.526},
{0xd6e38e1e,-2669.56,375.5663,-864.3912},
{0xd71066f2,1197.521,126.9715,-1152.63},
{0xd7a55949,4530.945,106.988,-2098.376},
{0xd7c86b91,3289.577,175.8,3338.793},
{0xd8927c64,-1538.743,278.4041,3070.083},
{0xd89c4741,-1884.491,23.98346,-1813.181},
{0xd8c72da7,1376.526,327.8504,1680.343},
{0xd910c140,4815.501,105.7348,-3300.246},
{0xd93aea04,1950.854,457.4908,-1832.657},
{0xd97128ce,1173.395,192.6689,2849.989},
{0xd9852d2a,1798.334,230.967,1078.175},
{0xd9957080,3140.857,220.7948,324.9673},
{0xd9d7b018,-2066.651,228.3253,1850.097},
{0xd9f18bf9,3322.944,379.4629,-2803.064},
{0xda11e11a,-3675.036,390.4904,-393.3223},
{0xdad9a49f,2703.711,225.5242,-1749.271},
{0xdae8ff9a,-3960.376,350.6725,-3723.258},
{0xdaea9644,-4210.025,609.7234,1133.509},
{0xdb42b09c,-3061.221,535.2148,-2813.686},
{0xdb4d9121,4181.042,220.8049,-2540.406},
{0xdc0848c2,-2030.122,206.4728,-547.6038},
{0xdc2dd997,-2751.337,459.4663,-2258.777},
{0xdcc8ba61,-162.0529,310.192,-878.053},
{0xdd4e2b38,-4026.708,145.2115,-232.4064},
{0xdd512e1b,3451.99,143.5695,550.7929},
{0xdd5a8ff0,1426.895,465.0379,-1544.07},
{0xdd777485,2705.439,203.1025,1164.945},
{0xdd836be1,-911.8,219.251,-1612.799},
{0xdd8e3d43,-2250.215,446.8035,-3092.183},
{0xdeb178e3,3726.305,331.2563,-1129.711},
{0xdec72884,-106.4598,153.33,1047.969},
{0xdf2a8fb0,-3841.713,218.4154,-803.9846},
{0xdf2fbf5f,2478.573,313.4195,-1391.592},
{0xdf664163,1305.289,191.349,2434.059},
{0xdfabfc2e,-1764,343.6976,-2350.704},
{0xdfbafa88,883.0738,133.6105,274.7977},
{0xdfbd654f,-3435.389,145.8999,2980.161},
{0xdfc6edc1,319.6543,137.195,-962.0651},
{0xdfc9ba84,-1020.383,201.0212,559.8116},
{0xdfda0f23,178.9613,116.6815,1719.983},
{0xe02da94d,-3014.163,174.9565,372.4369},
{0xe06124cb,-1309.765,209.0709,-1941.56},
{0xe0ec0587,286.8358,109.9,3899.422},
{0xe0ec0c23,1595.755,117.3918,807.6757},
{0xe1091dcc,-2059.885,306.7729,2420.099},
{0xe11fff55,-363.2491,131.7304,396.9416},
{0xe195562e,3951.867,106.3174,695.8884},
{0xe1edbaea,-2083.961,293.0881,-1558.725},
{0xe1f3f35a,214.5758,170.0761,2070.059},
{0xe23f09b9,1446.498,116.0391,558.3604},
{0xe27c26e0,-728.0692,154.6989,134.7785},
{0xe2810b71,1553.541,119,1297.187},
{0xe340e086,2863.861,140.2649,2182.903},
{0xe4dfc1c0,-4397.606,332.4454,-3773.917},
{0xe5293f22,4294.82,171.3062,78.50095},
{0xe73804b3,-2454.273,337.828,1157.305},
{0xe7538675,-1171.618,342.5077,2317.226},
{0xe7bd6e0d,-1363.466,335.7053,2215.195},
{0xe7d81530,-3129.014,614.0129,1467.155},
{0xe80a9eda,-1665.899,143.884,2338.163},
{0xe973a2c6,1462.677,336.7975,2370.849},
{0xea312f16,-1691.985,224.9699,-175.5285},
{0xeac72197,1807.032,220.4456,992.2015},
{0xeadbf30c,704.0372,120,2957.835},
{0xeafbc191,1933.256,376.7372,1220.964},
{0xeb323cb8,1325.561,296.6678,3008.678},
{0xebf2367a,3084.931,239.7771,2884.649},
{0xec46d3c7,3383.032,118.7868,982.824},
{0xec65fd0e,2424.331,253.6873,-1738.5},
{0xec69ed31,1939.514,269.1108,1110.931},
{0xec777d7c,-3524.551,373.7811,-449.6941},
{0xec9bb374,2207.285,192.5972,1373.48},
{0xece1fa6a,-1535.295,346.8846,-3475.819},
{0xece4af29,-1746.917,71,1831.097},
{0xed01da5f,2407.271,328.6665,-1613.596},
{0xed7f50ce,-2290.551,438.3871,468.2381},
{0xed80c7a5,3455.615,314.1401,-3581.874},
{0xee425e1d,-2883.833,521.3348,-2398.015},
{0xee48aa58,-1214.313,193.4733,2701.554},
{0xeed4a595,-2312.609,262.63,24.0163},
{0xef0a866a,815.2213,202.7296,2089.438},
{0xef6dfdb7,840.4058,236.2888,-692.4791},
{0xef9ceab3,-1154.359,132.8694,964.6355},
{0xf0274e1a,-2298.7,352.5616,2850.02},
{0xf036238f,-3792.613,283.47,-2320.191},
{0xf04e0c73,2856.583,113.7,3651.77},
{0xf0988858,-2358.78,476.1237,2554.533},
{0xf0b1e9b3,806.0729,124.5497,3112.856},
{0xf1888b2f,266.1024,276.4652,3668.951},
{0xf1aa8b46,-2210.06,498.6493,-2908.544},
{0xf22a43d9,-234.593,233.9734,-743.9327},
{0xf26db476,3520.64,326.7276,-383.5883},
{0xf29f26c9,-4690.488,704.1445,842.3635},
{0xf32bd5d4,3854.316,150.8158,352.2569},
{0xf349734f,-1781.002,347.3688,-2745.017},
{0xf3610321,-3041.119,430.4363,-2520.181},
{0xf366a0bd,-3125.194,263.008,-1366.506},
{0xf443fae0,-1009.463,130.1141,932.0392},
{0xf450426c,4503.659,379.2101,-3164.388},
{0xf5163503,-887.3224,208.1414,1891.407},
{0xf58b5c80,504.4539,123.3314,-493.469},
{0xf5b246cc,863.917,316.2801,-3358.529},
{0xf6099a1a,3372.048,271.9472,-2315.193},
{0xf6264d79,-1465.906,418.667,2952.556},
{0xf634a5b7,3995.799,292.524,-3147.581},
{0xf6853f20,-161.7531,147.4383,-262.0431},
{0xf691cf9e,-816.6761,224.4611,-1926.157},
{0xf7812399,-387.5938,152.9809,3151.553},
{0xf7bfdb93,1196.1,132.0342,3055.431},
{0xf7fb7294,1658.13,554.5893,-2564.875},
{0xf80d5e7e,2551.062,411.2377,-3592.677},
{0xf8497c57,963.303,173.4832,3371.103},
{0xf8d0c224,522.4664,166.3034,3680.958},
{0xf8d0d057,163.2763,90.2076,2783.299},
{0xf90a90fd,-3031.625,181.0055,3754.591},
{0xf9342a29,-2351.149,263.4041,846.18},
{0xf93afc9a,4616.441,366.4656,-638.0287},
{0xf9531c7b,-3886.142,229.4351,2965.82},
{0xf99b49af,-2815.311,160.7108,2247.913},
{0xf9d1d011,2751.067,293.7672,-1675.908},
{0xf9e10545,2179.551,226.3402,-1282.035},
{0xf9e81bfa,2099.721,363.6605,2625.572},
{0xf9eb79ab,-3661.365,257.3734,-828.8036},
{0xfa2ecee2,-2697.263,270.8433,2105.062},
{0xfa2f3eec,-710.2506,158.3555,99.93271},
{0xfa3e6133,3178.982,176.4081,-3073.667},
{0xfa5c61d9,25.66391,148.4707,147.481},
{0xfa7b263f,284.2921,146.7982,2253.376},
{0xfb1f386a,-468.6423,98.70972,2908.232},
{0xfb765fbc,-1631.543,210.4313,-515.1945},
{0xfbee67d4,645.7247,152.3,3615.123},
{0xfc5b8f9f,-2066.654,288.8196,2397.045},
{0xfca2f664,2714.133,225.5328,2345.553},
{0xfd72c546,-4373.898,165.1335,2587.057},
{0xfd840f72,280.4268,97.65099,2405.01},
{0xfdd548dc,-1819.094,206.1718,1532.648},
{0xfe3efb1d,2273.799,431.7688,-1823.225},
{0xfe508967,4095.783,220.0073,-1627.464},
{0xfe750c11,-3793.74,353.0625,-3032.967},
{0xfea08520,2284.273,287.5378,2659.972},
{0xff6a74af,2662.632,479.3359,-3471.585},
{0xff7758a0,-3728.542,166.4874,3610.083},
{0xffa754fa,-1045.92,54.66044,-2707.638},
{0xfffbdf04,4110.978,111.1552,2588.168}
};
#endif

View file

@ -1,57 +0,0 @@
#include "data_basic.h"
// Expanded Korok seed locations (50 for better testing)
Point KOROKS[] = {
{0x2c5b5d, -163.2841, 156.127, -784.6775},
{0x59aae8, 1694.872, 141.9548, -862.0854},
{0x66ded0, -3065.6, 604.494, 1287.267},
{0x753066, 518.627, 131.0005, 1475.525},
{0x105ef12, -2393.37, 233.0458, 1047.341},
{0x1a77626, -763.77, 156.0443, -606.28},
{0x22e0e12, 4634.409, 139.7075, -1840.946},
{0x2621e0d, -609.8074, 95.24519, 2390.653},
{0x30bd873, 3721.263, 108.243, 617.6266},
{0x32d8700, -1382.269, 249.2708, 1858.037},
{0x3443957, 4707.057, 292.6219, -1355.02},
{0x37dfc51, 265.6219, 111.8148, 3837.008},
{0x3924391, 2181.727, 414.9811, 2534.696},
{0x3d6015e, -2383.528, 211.8481, -1150.632},
{0x42c6214, 3709.191, 301.4515, 1943.087},
{0x4774091, 1725.349, 607.0526, -2553.939},
{0x4b6719b, -666.9385, 128.6065, -543.8143},
{0x4bcb461, 1943.746, 348.5898, 3009.422},
{0x5388d71, 806.5719, 116.8914, 24.09494},
{0x5828e12, -3751.844, 157.3583, 2531.624},
{0x5a246a2, -3286.434, 169.881, 3787.151},
{0x60b5dd9, 3024.405, 107.6149, 3654.227},
{0x664971e, 4702.884, 297.2508, -1039.331},
{0x7518cd7, -2646.005, 688.3249, 1535.135},
{0x7975126, 39.26459, 140.7788, 1034.492},
{0x7edf88b, -3847.195, 471.2815, 1467.019},
{0x7f53fae, -681.3192, 122.3821, -860.6268},
{0x8546066, 354.3845, 114.5671, 1997.546},
{0x93d1f93, -548.5, 140.8805, -229.52},
{0x9533a19, 1293.442, 273.6983, 1331.361},
{0x95d5540, -1992.891, 291.315, 161.3196},
{0x9af9809, 4662.712, 169.5986, 2376.256},
{0xa467aec, 3244.917, 265.8715, -2000.31},
{0xaab98c9, -3799.649, 128.1501, 3428.887},
{0xb03cec2, 3075.875, 318.8392, -3684.381},
{0xb19b851, -4685.214, 171.4609, 1970.388},
{0xb358ef9, -135.8379, 105.9709, 3802.004},
{0xb727016, 3148.72, 277.1993, 2402.78},
{0xbdebc55, 4105.454, 233.4027, -2836.7},
{0xbfa2096, 2032.282, 292.1425, 3164.345},
{0xc1a9b21, 1775.802, 219.047, 963.6041},
{0xc66c8aa, -4325.409, 768.4449, 698.2925},
{0xc91457e, -803.96, 138.0739, -403.127},
{0xd62d541, -657.7655, 187.6206, 3851.838},
{0xd90eabf, 2791.464, 451.4998, -500.932},
{0xde05681, 1647.232, 521.0447, -2244.461},
{0xe1bab2b, 1966.63, 365.963, 2634.479},
{0xe2d38d1, 97.36087, 145.4663, 3821.548},
{0xe6aa63d, -122.0947, 128.7947, 594.0034},
{0xe6e49e6, 1638.969, 116.4747, 1376.29}
};
const int KOROK_COUNT = 50;

View file

@ -1,10 +0,0 @@
#ifndef DATA_H
#define DATA_H
#include "save_basic.h"
#include "map_basic.h"
// Sample Korok seed locations (first 10 for testing)
extern Point KOROKS[];
extern const int KOROK_COUNT;
#endif

View file

@ -1,42 +1,82 @@
#include <string.h>
#include <stdio.h>
#include <dirent.h>
#include <stdlib.h>
#include <math.h>
#include <switch.h>
#include "save_basic.h"
#include "ui_basic.h"
#include "save.h"
#include "ui.h"
int main(int argc, char **argv)
{
setvbuf(stdout, NULL, _IONBF, BUFSIZ);
setvbuf(stdout, NULL, _IONBF, BUFSIZ); //do not line-buffer stdout
Result rc=0;
bool exit = false;
AccountUid uid={0};
u64 application_id=0x01007ef00011e000;//ApplicationId of the save to mount, in this case BOTW.
consoleInit(NULL);
// Configure input
// Configure our supported input layout: a single player with standard controller styles
padConfigureInput(1, HidNpadStyleSet_NpadStandard);
// Initialize the default gamepad (which reads handheld mode inputs as well as the first connected controller)
PadState pad;
padInitializeDefault(&pad);
//draw main screen and menu
initUI();
//Get the userID for save mounting. To mount common savedata, use an all-zero userID.
//Try to find savedata to use with the above hard-coded TID + the userID from accountGetPreselectedUser(). Note that you can use either method.
//See the account example for getting account info for an userID.
//See also the app_controldata example for getting info for an application_id.
rc = accountInitialize(AccountServiceType_Application);
if (R_FAILED(rc)) {
printMessage("accountInitialize() failed: 0x%x\n", rc);
exit = true;
}
rc = accountGetPreselectedUser(&uid);
accountExit();
if (R_FAILED(rc)) {
printMessage("accountGetPreselectedUser() failed: 0x%x\n", rc);
exit = true;
}
//You can use any device-name. If you want multiple saves mounted at the same time, you must use different device-names for each one.
rc = fsdevMountSaveData("save", application_id, uid);//See also libnx fs.h/fs_dev.h
if (R_FAILED(rc)) {
printMessage("fsdevMountSaveData() failed: 0x%x\n", rc);
exit = true;
}
//At this point you can use the mounted device with standard stdio.
//After modifying savedata, in order for the changes to take affect you must use: rc = fsdevCommitDevice("save");
//See also libnx fs_dev.h for fsdevCommitDevice.
// Initialize save system
openSave();
processSave();
// Initialize UI
initUI();
bool exit = false;
// Main loop
while(appletMainLoop() && !exit)
{
// Scan the gamepad. This should be done once for each frame
padUpdate(&pad);
// padGetButtonsDown returns the set of buttons that have been newly pressed in this frame compared to the previous one
u64 kDown = padGetButtonsDown(&pad);
exit = handleButtonPress(kDown);
consoleUpdate(NULL);
}
// Unmount save data before exit
fsdevUnmountDevice("save");
consoleExit(NULL);
return 0;
}
}

282
source/map.c Normal file
View file

@ -0,0 +1,282 @@
#include <stdlib.h>
#include <switch.h>
#include <math.h>
#include "map.h"
#include "save.h"
#include "ui.h"
#include "data.h"
u32 mapPinIconCount = 0;
u32 mapPinLocCount = 0;
u32 map_pin_count = 0;
Point PlayerLocation;
//2d seems to work better than 3d
int compDistance (const void* elem1, const void* elem2)
{
Point f = *((Point*)elem1);
Point s = *((Point*)elem2);
double f_distance = sqrt(pow(f.x-PlayerLocation.x,2)+pow(f.z-PlayerLocation.z,2));
double s_distance = sqrt(pow(s.x-PlayerLocation.x,2)+pow(s.z-PlayerLocation.z,2));
if (f_distance > s_distance) return 1;
if (f_distance < s_distance) return -1;
return 0;
}
/*void addMapPin(u32 icon, Point location) {
u32 pin_hash = 0x9383490e;
u32 pin_offset = _searchHash(pin_hash) - 4;
u32 pin_maxlength = ((GAMEDATASAV.length - pin_offset) / 8);
u32 pin_total = 0;
for ( u32 i = 0; i < pin_maxlength; i++) {
u32 pin_base = pin_offset + (8*i);
u32 pin_header = readU32FromAddr(pin_base);
u32 pin_value = readU32FromAddr(pin_base + 4);
//printMessage2("%d: hash %x offset %x base %x header %x value: %x", i, pin_hash, pin_offset, pin_base, pin_header, pin_value);
if (pin_header != pin_hash) { break; }
if (pin_value == 0xffffffff) {
//printMessage2("%d: hash %x offset %x base %x header %x value: %x", i, pin_hash, pin_offset, pin_base, pin_header, pin_value);
writeU32ToAddr(pin_base + 4, icon);
pin_counter++;
break;
}
if (++pin_total >= 100) { break; }
}
u32 pinloc_hash = 0xea9def3f;
u32 pinloc_offset = _searchHash(pinloc_hash) - 4;
u32 pinloc_maxlength = ((GAMEDATASAV.length - pinloc_offset) / 8);
u32 pinloc_total = 0;
for ( u32 i = 0; i < pinloc_maxlength; i++) {
if (i%3 != 0) { continue; }
u32 pinloc_base = pinloc_offset + (8*i);
u32 pinloc_header = readU32FromAddr(pinloc_base);
//printMessage2("hash 0x%x offset 0x%x base 0x%x header 0x%x x: %f y: %f z:%f\n", pinloc_hash, pinloc_offset, pinloc_base, pinloc_header, pinloc_value_x, pinloc_value_y, pinloc_value_z);
if (pinloc_header != pinloc_hash) { break; }
float pinloc_value = readF32FromAddr(pinloc_base + 4);
if (pinloc_value == -100000) {
//printMessage2("hash 0x%x offset 0x%x base 0x%x header 0x%x x: %f y: %f z:%f\n", pinloc_hash, pinloc_offset, pinloc_base, pinloc_header, pinloc_value_x, pinloc_value_y, pinloc_value_z);
writeF32ToAddr(pinloc_base + 4, location.x);
writeF32ToAddr(pinloc_base + 12, location.y);
writeF32ToAddr(pinloc_base + 20, location.z);
pinloc_counter++;
break;
}
if (++pinloc_total >= 100) { break; }
}
}*/
void iterateMapPinIcons(func_t_0 iterFunc, u32 icon) {
mapPinIconCount = 0;
u32 pin_hash = 0x9383490e;
u32 pin_offset = _searchHash(pin_hash) - 4;
u32 pin_maxlength = ((getSaveSize() - pin_offset) / 8);
for ( u32 i = 0; i < pin_maxlength; i++) {
u32 pin_base = pin_offset + (8*i);
u32 pin_header = readU32FromAddr(pin_base);
u32 pin_value = readU32FromAddr(pin_base + 4);
if (pin_header != pin_hash) { break; }
if (!iterFunc(pin_base+4, pin_value, icon)) {
break;
}
}
}
void iterateMapPinLocs(func_t_1 iterFunc, Point location) {
mapPinLocCount = 0;
u32 pinloc_hash = 0xea9def3f;
u32 pinloc_offset = _searchHash(pinloc_hash) - 4;
u32 pinloc_maxlength = ((getSaveSize() - pinloc_offset) / 24);
for ( u32 i = 0; i < pinloc_maxlength; i++) {
u32 pinloc_base = pinloc_offset + (24*i);
u32 pinloc_header = readU32FromAddr(pinloc_base);
float pinloc_value_x = readF32FromAddr(pinloc_base + 4);
float pinloc_value_y = readF32FromAddr(pinloc_base + 12);
float pinloc_value_z = readF32FromAddr(pinloc_base + 20);
if (pinloc_header != pinloc_hash) { break; }
if (!iterFunc(pinloc_base+4, pinloc_value_x, pinloc_value_y, pinloc_value_z, location)) {
break;
}
}
}
void sortKoroksByDistance()
{
/*Point korokLocations[900];
for (int i = 0 ;i < 900; i++) {
korokLocations[i] = KOROKS[i];
}*/
qsort(KOROKS, 900, sizeof(Point), compDistance);
u32 added_pins = 0;
u32 max_pins_to_add = 100 - map_pin_count;
for (int i = 0; i < 900 && added_pins < max_pins_to_add; i++) {
if (isKorokCompletedOrMarked(KOROKS[i])) { continue; }
if (!addPinToMap(MAP_PIN_LEAF, KOROKS[i])) { break; }
added_pins++;
/*printMessage("%d (0x%x): %f, %f ,%f (dist: %f)\n", added_pins, korokLocations[i].hash,
korokLocations[i].x, korokLocations[i].y, korokLocations[i].z,
sqrt(pow(korokLocations[i].x-PlayerLocation.x,2)+pow(korokLocations[i].y-PlayerLocation.y,2)+pow(korokLocations[i].z-PlayerLocation.z,2)));*/
}
printMessage("%d pins added to map.", added_pins);
}
bool isKorokCompletedOrMarked(Point korok) {
//check if korok is marked on map already
if (isLocationInPinLoc(korok)) { return true; }
//check if korok is marked completed in game save
return (readU32FromHash(korok.hash) == 1);
}
void eraseCompletedKorokPins() {
}
bool addPinToMap(u32 pin_icon, Point location) {
iterateMapPinIcons(&_addMapPinIcon, pin_icon);
iterateMapPinLocs(&_addMapPinLoc, location);
if (mapPinIconCount != mapPinLocCount) {
printMessage("Mismatch: Added %d map icons, but %d map locations.", mapPinIconCount, mapPinLocCount);
return false;
}
map_pin_count = map_pin_count + mapPinIconCount;
return (mapPinIconCount == 1);
}
bool _addMapPinIcon(u32 offset, u32 value, u32 icon) {
if (value == MAP_PIN_EMPTY) {
writeU32ToAddr(offset, icon);
mapPinIconCount++;
return false;
}
return true;
}
bool _addMapPinLoc(u32 offset, float value_x, float value_y, float value_z, Point location) {
if (value_x == -100000 && value_y == 0 && value_z == 0) {
writeF32ToAddr(offset, location.x);
writeF32ToAddr(offset+8, location.y);
writeF32ToAddr(offset+16, location.z);
mapPinLocCount++;
return false;
}
return true;
}
bool isLocationInPinLoc(Point location) {
iterateMapPinLocs(&_isLocationInPinLoc, location);
return mapPinLocCount == 1;
}
bool _isLocationInPinLoc(u32 offset, float value_x, float value_y, float value_z, Point location) {
if (value_x == -100000 && value_y == 0 && value_z == 0) {
return false;
}
if (value_x == location.x && value_y == location.y && value_z == location.z) {
mapPinLocCount++;
return false;
}
return true;
}
void loadPlayerLocation() {
PlayerLocation = (Point){.hash = 0,
.x = readF32FromHash(HASHES.PLAYER_POSITION, 0),
.y = readF32FromHash(HASHES.PLAYER_POSITION, 8),
.z = readF32FromHash(HASHES.PLAYER_POSITION, 16)};
printMessage("player loc is x: %f, y: %f, z: %f.", PlayerLocation.x, PlayerLocation.y, PlayerLocation.z);
}
void countMapPins() {
map_pin_count = 0;
iterateMapPinIcons(&_loadMapPinIcons, 0);
iterateMapPinLocs(&_loadMapPinLocs, (Point){});
if (mapPinIconCount != mapPinLocCount) {
printMessage("Mismatch: Counted %d map icons, but have %d map locations.", mapPinIconCount, mapPinLocCount);
}
printMessage("number of map pins: %d.", map_pin_count);
}
bool _loadMapPinIcons(u32 offset, u32 value, u32 icon) {
if (value == MAP_PIN_EMPTY) {
return false;
}
if (value <= 0x23 && value >= 0x1b) {
mapPinIconCount++;
map_pin_count++;
} else {
printMessage("Invalid map pin icon 0x%x @ offset 0x%x", value, offset);
}
return true;
}
bool _loadMapPinLocs(u32 offset, float value_x, float value_y, float value_z, Point location) {
if (value_x == -100000 && value_y == 0 && value_z == 0) {
return false;
}
mapPinLocCount++;
return true;
}
void eraseMapPins() {
iterateMapPinIcons(&_eraseMapPinIcons, 0);
iterateMapPinLocs(&_eraseMapPinLocs, (Point){.hash=0});
map_pin_count = 0;
printMessage("%d pin icons erased, %d pin locations erased.", mapPinIconCount, mapPinLocCount);
}
bool _eraseMapPinIcons(u32 offset, u32 value, u32 icon) {
if (value != MAP_PIN_EMPTY) {
//if we have a hash set, we're looking for a specific icon to erase. if this isn't it, return true to iterator to continue
if (icon != 0 && icon != value) { return true; }
writeU32ToAddr(offset, MAP_PIN_EMPTY);
mapPinIconCount++;
}
return true;
}
bool _eraseMapPinLocs(u32 offset, float value_x, float value_y, float value_z, Point location) {
if (value_x != -100000 && value_y != 0 && value_z != 0) {
//if we have a hash set, we're looking for a specific location to erase. if this isn't it, return true to iterator to continue
if (location.hash != 0 && (location.x != value_x || location.y != value_y || location.z != value_z)) { return true; }
writeF32ToAddr(offset, -100000);
writeF32ToAddr(offset+8, 0);
writeF32ToAddr(offset+16, 0);
mapPinLocCount++;
}
return true;
}
void convertInvalidMapPinIcons() {
iterateMapPinIcons(&_convertInvalidMapPinIcons, 0x1b);
map_pin_count = map_pin_count + mapPinIconCount;
printMessage("%d invalid map pin icons converted.", mapPinIconCount);
countMapPins();
}
bool _convertInvalidMapPinIcons(u32 offset, u32 value, u32 icon) {
if (value == MAP_PIN_EMPTY) {
return false;
}
if (value > 0x23 || value < 0x1b) {
writeU32ToAddr(offset, icon);
mapPinIconCount++;
}
return true;
}

48
source/map.h Normal file
View file

@ -0,0 +1,48 @@
#ifndef MAP_H
#define MAP_H
#include <stdlib.h>
#include <switch.h>
#define MAP_PIN_SWORD 0x1B
#define MAP_PIN_BOW 0x1C
#define MAP_PIN_SHIELD 0x1D
#define MAP_PIN_POT 0x1E
#define MAP_PIN_STAR 0x1F
#define MAP_PIN_CHEST 0x20
#define MAP_PIN_SKULL 0x21
#define MAP_PIN_LEAF 0x22
#define MAP_PIN_TOWER 0x23
#define MAP_PIN_EMPTY 0xFFFFFFFF
typedef struct {
u32 hash;
float x;
float y;
float z;
} Point;
void sortKoroksByDistance();
void loadPlayerLocation();
void eraseCompletedKorokPins();
int compDistance (const void* elem1, const void* elem2);
typedef bool (*func_t_0)(u32 offset, u32 value, u32 icon);
typedef bool (*func_t_1)(u32 offset, float value_x, float value_y, float value_z, Point location);
bool _loadMapPinIcons(u32 offset, u32 value, u32 icon);
bool _eraseMapPinIcons(u32 offset, u32 value, u32 icon);
bool _eraseMapPinLocs(u32 offset, float value_x, float value_y, float value_z, Point location);
bool _convertInvalidMapPinIcons(u32 offset, u32 value, u32 icon);
bool isKorokCompletedOrMarked(Point korok);
void addMapPin(u32 icon, Point location);
void eraseMapPins();
void convertInvalidMapPinIcons();
void countMapPins();
bool addPinToMap(u32 pin_icon, Point location);
bool _addMapPinLoc(u32 offset, float value_x, float value_y, float value_z, Point location);
bool _addMapPinIcon(u32 offset, u32 value, u32 icon);
bool isLocationInPinLoc(Point location);
bool _isLocationInPinLoc(u32 offset, float value_x, float value_y, float value_z, Point location);
bool _loadMapPinLocs(u32 offset, float value_x, float value_y, float value_z, Point location);
void iterateMapPinIcons(func_t_0 iterFunc, u32 icon);
void iterateMapPinLocs(func_t_1 iterFunc, Point location);
#endif

View file

@ -1,28 +0,0 @@
#include <stdio.h>
#include <math.h>
#include <switch.h>
#include "map_basic.h"
static Point player_location = {0};
void loadPlayerLocation() {
printf("Loading player location...\n");
// TODO: Read player position from save data
player_location.x = 0.0f;
player_location.y = 0.0f;
player_location.z = 0.0f;
printf("Player at: (%.1f, %.1f, %.1f)\n",
player_location.x, player_location.y, player_location.z);
}
void addMapPin(u32 icon, Point location) {
printf("Adding map pin at (%.1f, %.1f, %.1f)\n",
location.x, location.y, location.z);
// TODO: Implement map pin addition to save data
}
void countMapPins() {
printf("Counting map pins...\n");
// TODO: Count existing pins in save data
printf("Found 0 map pins\n");
}

View file

@ -1,22 +0,0 @@
#ifndef MAP_H
#define MAP_H
#include <stdlib.h>
#include <switch.h>
#define MAP_PIN_STAR 0x1F
#define MAP_PIN_LEAF 0x22
#define MAP_PIN_EMPTY 0xFFFFFFFF
typedef struct {
u32 hash;
float x;
float y;
float z;
} Point;
void loadPlayerLocation();
void addMapPin(u32 icon, Point location);
void countMapPins();
#endif

136
source/save.c Normal file
View file

@ -0,0 +1,136 @@
#include <string.h>
#include <stdio.h>
#include <dirent.h>
#include <stdlib.h>
#include <math.h>
#include <switch.h>
#include "save.h"
#include "ui.h"
#include "map.h"
gameDataSav GAMEDATASAV;
const u32 KOROK_COUNTER_HASH = 0x8a94e07a;
void openSave() {
GAMEDATASAV.saveFile = NULL;
FILE *fp = fopen("save:/5/game_data.sav", "rb"); //TODO: Dont hardcode save slot
if (fp != NULL) {
/* Go to the end of the file. */
if (fseek(fp, 0L, SEEK_END) == 0) {
/* Get the size of the file. */
long bufsize = ftell(fp);
if (bufsize == -1) { /* Error */ }
/* Allocate our buffer to that size. */
GAMEDATASAV.saveFile = malloc(sizeof(char) * (bufsize));
/* Go back to the start of the file. */
if (fseek(fp, 0L, SEEK_SET) != 0) { /* Error */ }
/* Read the entire file into memory. */
GAMEDATASAV.length = fread(GAMEDATASAV.saveFile, sizeof(char), bufsize, fp);
if (ferror( fp ) != 0) {
printMessage("Error reading file.");
} else {
printMessage("Read %.2f kbytes successfully.", GAMEDATASAV.length/1024.0);
}
}
fclose(fp);
} else {
printMessage("Error opening file.");
}
}
void processSave() {
countMapPins();
printMessage("number of korok seeds: %d.", readU32FromHash(KOROK_COUNTER_HASH));
loadPlayerLocation();
}
u32 getSaveSize() {
return GAMEDATASAV.length;
}
void writeSave() {
FILE *fp = fopen("save:/5/game_data.sav", "wb"); //TODO: dont hardcode save slot
if (fp != NULL) {
size_t bytes_writen = fwrite(GAMEDATASAV.saveFile, sizeof(char), GAMEDATASAV.length, fp);
if (ferror( fp ) != 0) {
printMessage("Error writing file.");
} else {
printMessage("Wrote %f.2 kbytes successfully.", bytes_writen/1024.0);
}
fclose(fp);
} else {
printMessage("Error opening file for writing.");
}
}
u32 _searchHash(u32 hash) {
for(u32 i=0x0c; i<GAMEDATASAV.length; i+=8) {
u32 val = GAMEDATASAV.saveFile[i] | ( (u32)GAMEDATASAV.saveFile[i+1] << 8 ) | ( (u32)GAMEDATASAV.saveFile[i+2] << 16 ) | ( (u32)GAMEDATASAV.saveFile[i+3] << 24 );
if(hash == val) {
return i;
}
}
return 0;
}
u32 readU32FromHash(u32 hash) {
return readU32FromAddr(_searchHash(hash));
}
u32 readU32FromAddr(u32 addr) {
if(addr != 0) {
u32 val = ((u32)GAMEDATASAV.saveFile[addr+4]) | ( (u32)GAMEDATASAV.saveFile[addr+5] << 8 ) | ( (u32)GAMEDATASAV.saveFile[addr+6] << 16 ) | ( (u32)GAMEDATASAV.saveFile[addr+7] << 24 );
return val;
}
return 0;
}
float readF32FromHash(u32 hash, u32 offset) {
return readF32FromAddr(_searchHash(hash) + offset);
}
float readF32FromAddr(u32 addr) {
if(addr != 0) {
Float val;
val.m_bytes[0] = GAMEDATASAV.saveFile[addr+4];
val.m_bytes[1] = GAMEDATASAV.saveFile[addr+5];
val.m_bytes[2] = GAMEDATASAV.saveFile[addr+6];
val.m_bytes[3] = GAMEDATASAV.saveFile[addr+7];
return val.m_float;
}
return 0;
}
void writeF32ToAddr(u32 addr, float value) {
if(addr != 0) {
Float val;
val.m_float = value;
GAMEDATASAV.saveFile[addr+4] = val.m_bytes[0];
GAMEDATASAV.saveFile[addr+5] = val.m_bytes[1];
GAMEDATASAV.saveFile[addr+6] = val.m_bytes[2];
GAMEDATASAV.saveFile[addr+7] = val.m_bytes[3];
//printMessage("wrote f32 %f to 0x%x, read check: %f\n", value, addr, readF32FromAddr(addr));
}
}
void writeU32ToAddr(u32 addr, u32 value) {
if (addr != 0) {
GAMEDATASAV.saveFile[addr+4] = value & 0x00000ff;
GAMEDATASAV.saveFile[addr+5] = (value & 0x0000ff00) >> 8;
GAMEDATASAV.saveFile[addr+6] = (value & 0x00ff0000) >> 16;
GAMEDATASAV.saveFile[addr+7] = (value & 0xff000000) >> 24;
//printMessage("wrote u32 0x%x to 0x%x, read check: 0x%x", value, addr, readU32FromAddr(addr));
}
}
void closeAndCommitSave() {
writeSave();
if (R_FAILED(fsdevCommitDevice("save"))) {
printMessage("Committing failed.");
}
free(GAMEDATASAV.saveFile);
}

View file

@ -3,6 +3,8 @@
#include <stdlib.h>
typedef struct
{
size_t length;
@ -11,6 +13,7 @@ typedef struct
typedef struct {
u32 PLAYER_POSITION;
u32 MAP;
} Hashes;
typedef union Float {
@ -18,11 +21,17 @@ typedef union Float {
u8 m_bytes[sizeof(float)];
} Float;
u32 _searchHash(u32 hash);
u32 readU32FromHash(u32 hash);
u32 readU32FromAddr(u32 addr);
float readF32FromAddr(u32 addr);
void writeF32ToAddr(u32 addr, float value);
void writeU32ToAddr(u32 addr, u32 value);
float readF32FromHash(u32 hash, u32 offset);
void processSave();
void openSave();
void writeSave();
void closeAndCommitSave();
u32 getSaveSize();
#endif

View file

@ -1,63 +0,0 @@
#include <string.h>
#include <stdio.h>
#include <switch.h>
#include "save_basic.h"
static gameDataSav save_data = {0};
static Hashes HASHES = {.PLAYER_POSITION = 0xa40ba103};
void openSave() {
Result rc = 0;
AccountUid uid = {0};
u64 application_id = 0x01007ef00011e000; // BOTW Application ID
printf("Opening BOTW save data...\n");
// Get user account
rc = accountInitialize(AccountServiceType_Application);
if (R_FAILED(rc)) {
printf("accountInitialize() failed: 0x%x\n", rc);
return;
}
rc = accountGetPreselectedUser(&uid);
accountExit();
if (R_FAILED(rc)) {
printf("accountGetPreselectedUser() failed: 0x%x\n", rc);
return;
}
// Mount save data
rc = fsdevMountSaveData("save", application_id, uid);
if (R_FAILED(rc)) {
printf("fsdevMountSaveData() failed: 0x%x\n", rc);
return;
}
printf("Save data mounted successfully!\n");
}
u32 readU32FromAddr(u32 addr) {
// TODO: Implement reading u32 from save file address
return 0;
}
float readF32FromAddr(u32 addr) {
// TODO: Implement reading float from save file address
return 0.0f;
}
void writeF32ToAddr(u32 addr, float value) {
// TODO: Implement writing float to save file address
}
void processSave() {
printf("Processing save data...\n");
// TODO: Load save file into memory for processing
}
void writeSave() {
printf("Writing save data...\n");
// TODO: Write modified data back to save file
}

272
source/ui.c Normal file
View file

@ -0,0 +1,272 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <switch.h>
#include "ui.h"
#include "save.h"
#include "map.h"
#define FB_MAX_COLS 80
#define FB_MAX_LINES 45
#define MSG_MAX_LINE_LEN 45
#define MSG_START_COL (FB_MAX_COLS-MSG_MAX_LINE_LEN)
#define MSG_MAX_LEN (MSG_MAX_LINE_LEN*FB_MAX_LINES)
#define FB_MIDDLE_LINE (FB_MAX_LINES/2)
// this converts to string
#define STR_(X) #X
// this makes sure the argument is expanded before converting to string
#define STR(X) STR_(X)
MenuItem main_menu_items[6] = {
{"Add Missing Koroks to Map", &sortKoroksByDistance},
{"Erase Completed Korok Pins", &eraseCompletedKorokPins},
{"Erase All Map Pins", &eraseMapPins},
{"Convert Invalid Map Pins", &convertInvalidMapPinIcons},
{"Save and Exit", &saveAndExitApp},
{"Exit w/o Saving", &exitApp}
};
Menu main_menu = {
.HeaderStr = "BOTW KOROK COMPLETER",
.ItemCount = 6,
.Menu_Items = main_menu_items
};
MenuItem confirm_menu_items[2] = {
{"No, cancel!", NULL},
{"Yes, do it!", NULL}
};
Menu confirm_menu = {
.HeaderStr = "ARE YOU SURE??",
.ItemCount = 2,
.Menu_Items = confirm_menu_items
};
Menu *current_menu;
Menu *previous_menu;
char MSG_BUFFER[FB_MAX_LINES][MSG_MAX_LINE_LEN+1];
u32 msg_buf_write_line = 0;
u32 msg_buf_line_count = 0;
bool exit_state = false;
bool confirmed = false;
void _clearScreen() {
printf(CONSOLE_ESC(2J)); //clear screen and reset home cursor
}
void loadMenu(Menu* menu) {
current_menu = menu;
current_menu->StartLine = FB_MIDDLE_LINE - (current_menu->ItemCount / 2);
current_menu->SelectedIndex = 0;
_clearScreen();
_drawMenu();
_drawMessagePane();
}
void _drawMenu() {
//new code
printfAtCursor(2, current_menu->StartLine-2, current_menu->HeaderStr);
printfAtCursor(2, current_menu->StartLine, ">");
for (int i = 0; i < current_menu->ItemCount; i++) {
printfAtCursor(4, current_menu->StartLine+i, current_menu->Menu_Items[i].ItemStr);
}
//end new code
/*/old code
printfAtCursor(2, MENU_START_COL-2, "BOTW KOROK COMPLETER");
printfAtCursor(2, MENU_START_COL, "> Add Missing Koroks to Map");
printfAtCursor(2, MENU_START_COL+1, " Erase all map pins");
printfAtCursor(2, MENU_START_COL+2, " Convert invalid map pins");
printfAtCursor(2, MENU_START_COL+3, " Save and Exit");
printfAtCursor(2, MENU_START_COL+4, " Exit w/o Saving");
//end old code*/
//print vertical line between menu and messages panel
for (int i = 1; i <= FB_MAX_LINES; i++) {
printfAtCursor(FB_MAX_COLS - MSG_MAX_LINE_LEN - 2, i, "|");
}
}
void initUI() {
loadMenu(&main_menu);
}
void exitApp() {
exit_state = true;
}
void saveAndExitApp() {
closeAndCommitSave();
exitApp();
}
void handleMenuButtonPress(u64 button) {
//clear menu cursor
printfAtCursor(2, current_menu->StartLine+current_menu->SelectedIndex, " ");
switch (button) {
case HidNpadButton_Down:
if (current_menu->SelectedIndex == current_menu->ItemCount - 1) {
current_menu->SelectedIndex = 0;
} else {
current_menu->SelectedIndex++;
}
break;
case HidNpadButton_Up:
if (current_menu->SelectedIndex == 0) {
current_menu->SelectedIndex = current_menu->ItemCount-1;
} else {
current_menu->SelectedIndex--;
}
break;
case HidNpadButton_A: //run menu function, using menu item index: position - start_line
current_menu->Menu_Items[current_menu->SelectedIndex].ItemFunc();
break;
default:
break;
}
//print menu cursor
printfAtCursor(2, current_menu->StartLine+current_menu->SelectedIndex, ">");
}
bool handleButtonPress(u64 button) {
if (button & HidNpadButton_Plus) { return true; } // exit if + button pressed
handleMenuButtonPress(button);
return exit_state;
}
/*u32 handleMenuButtonPress(u64 button) {
switch (button) {
case HidNpadButton_Down:
printf(CONSOLE_ESC(%d;2H) " ", menu_pos);
if (menu_pos == MENU_END_LINE) { menu_pos = MENU_START_LINE; }
else { menu_pos++; }
printf(CONSOLE_ESC(%d;2H) ">", menu_pos);
break;
case HidNpadButton_Up:
printf(CONSOLE_ESC(%d;2H) " ", menu_pos);
if (menu_pos == MENU_START_LINE) { menu_pos = MENU_END_LINE; }
else { menu_pos--; }
printf(CONSOLE_ESC(%d;2H) ">", menu_pos);
break;
case HidNpadButton_A:
return menu_pos;
break;
default:
break;
}
return (enum menu_items)none;
}
bool handleButtonPress(u64 button) {
switch(handleMenuButtonPress(button)) {
case add_missing_koroks:
sortKoroksByDistance();
break;
case erase_all_map_pins:
eraseMapPins();
break;
case convert_invalid_map_pins:
convertInvalidMapPinIcons();
break;
case save_file:
writeSave();
closeAndCommitSave();
return true;
break;
case exit_app:
return true;
break;
default:
break;
}
return false;
}*/
void _confirm_no() {
loadMenu(previous_menu);
}
void confirmThenRunElse(func_t yes_func, func_t no_func) {
//save current menu
previous_menu = current_menu;
confirm_menu.Menu_Items[1].ItemFunc = yes_func;
confirm_menu.Menu_Items[0].ItemFunc = no_func;
loadMenu(&confirm_menu);
}
void confirmThenRun(func_t yes_func) {
confirmThenRunElse(yes_func, &_confirm_no);
}
void printfAtCursor(u32 x_pos, u32 y_pos, const char* format, ...) {
va_list args;
va_start(args, format);
_setCursorPos(x_pos, y_pos);
vprintf(format, args);
va_end(args);
}
void _setCursorPos(u32 x_pos, u32 y_pos) {
if (x_pos >= 1 && x_pos <= FB_MAX_COLS && y_pos >= 1 && y_pos <= FB_MAX_LINES) {
printf(CONSOLE_ESC(%d;%dH) , y_pos, x_pos);
}
}
void printMessage(const char* format, ...) {
//get variable args
va_list args;
va_start(args, format);
//process the format string
char message[MSG_MAX_LEN-FB_MAX_LINES];
vsnprintf(message, MSG_MAX_LEN-FB_MAX_LINES, format, args);
va_end(args);
//find out how many lines we are about to add to the buffer/print
size_t length = strlen(message);
u32 num_of_lines = length / MSG_MAX_LINE_LEN;
if (length%MSG_MAX_LINE_LEN != 0) {num_of_lines++;}
char *line;
for (int i = 0; i < num_of_lines; i++) {
//extract the next set of characters and store in line
line = strndup(message + (MSG_MAX_LINE_LEN*i), MSG_MAX_LINE_LEN);
//clear previous line
memset(MSG_BUFFER[msg_buf_write_line], 0, MSG_MAX_LINE_LEN+1);
//copy line to MSG_BUFFER at write_ptr
strncpy(MSG_BUFFER[msg_buf_write_line], line, MSG_MAX_LINE_LEN);
MSG_BUFFER[msg_buf_write_line][MSG_MAX_LINE_LEN] = '\0';
msg_buf_write_line++;
//free original line after we've copied it
free(line);
//if count is below max lines, then increase count
if (msg_buf_line_count < FB_MAX_LINES) { msg_buf_line_count++; }
// if the next write line is past the last index, set the next index to 0.
if (msg_buf_write_line == FB_MAX_LINES) { msg_buf_write_line = 0; }
_drawMessagePane();
}
}
void _drawMessagePane() {
//print all lines in buffer, from top to bottom, oldest to newest
if (msg_buf_line_count > 0) {
u32 start_line = 0;
if (msg_buf_line_count == FB_MAX_LINES) {
start_line = msg_buf_write_line;
}
for (int i = 0; i < msg_buf_line_count; i++) {
_setCursorPos(MSG_START_COL, i+1);
printf("%-" STR(MSG_MAX_LINE_LEN) "s", MSG_BUFFER[(start_line + i) % FB_MAX_LINES]);
}
}
}

44
source/ui.h Normal file
View file

@ -0,0 +1,44 @@
#ifndef UI_H
#define UI_H
typedef void (*func_t)();
typedef struct {
char ItemStr[30];
func_t ItemFunc;
} MenuItem;
typedef struct {
char HeaderStr[30];
u32 ItemCount;
u32 StartLine;
u32 SelectedIndex;
MenuItem *Menu_Items;
} Menu;
void _clearScreen();
void _drawMenu();
void loadMenu(Menu* menu);
void _confirm_no();
void confirmThenRunElse(func_t yes_func, func_t no_func);
void confirmThenRun(func_t yes_func);
void _setCursorPos(u32 x_pos, u32 y_pos);
void handleMenuButtonPress(u64 button);
bool handleButtonPress(u64 button);
void printMessage(const char* message, ...);
void printfAtCursor(u32 x_pos, u32 y_pos, const char* format, ...) ;
void _drawMessagePane();
void initUI();
void exitApp();
void saveAndExitApp();
/*#define MENU_START_LINEE 21
#define MENU_END_LINEE 25
enum menu_items {
none = MENU_START_LINEE-1,
add_missing_koroks,
erase_all_map_pins,
convert_invalid_map_pins,
save_file,
exit_app
};*/
#endif

View file

@ -1,60 +0,0 @@
#include <stdio.h>
#include <stdarg.h>
#include <switch.h>
#include "ui_basic.h"
#include "data_basic.h"
#include "map_basic.h"
static void addKorokPins() {
printMessage("Adding Korok seed pins...\n");
for (int i = 0; i < KOROK_COUNT; i++) {
addMapPin(MAP_PIN_LEAF, KOROKS[i]);
}
printMessage("Added %d Korok pins!\n", KOROK_COUNT);
}
static void testFunction() {
printMessage("Test function called!\n");
}
void initUI() {
printf("\x1b[2J"); // Clear screen
printf("\x1b[1;1H"); // Move cursor to top-left
printf("═══════════════════════════════════════\n");
printf(" BOTW Completer v0.4\n");
printf("═══════════════════════════════════════\n");
printf("\n");
printf("Menu:\n");
printf("A - Add Korok pins\n");
printf("B - Count map pins\n");
printf("Y - Test function\n");
printf("+ - Exit\n");
printf("\n");
}
void printMessage(const char* message, ...) {
va_list args;
va_start(args, message);
vprintf(message, args);
va_end(args);
}
bool handleButtonPress(u64 button) {
if (button & HidNpadButton_Plus) {
return true; // Exit requested
}
if (button & HidNpadButton_A) {
addKorokPins();
}
if (button & HidNpadButton_B) {
countMapPins();
}
if (button & HidNpadButton_Y) {
testFunction();
}
return false; // Continue running
}

View file

@ -1,23 +0,0 @@
#ifndef UI_H
#define UI_H
typedef void (*func_t)();
typedef struct {
char ItemStr[30];
func_t ItemFunc;
} MenuItem;
typedef struct {
char HeaderStr[30];
u32 ItemCount;
u32 StartLine;
u32 SelectedIndex;
MenuItem *Menu_Items;
} Menu;
void initUI();
void printMessage(const char* message, ...);
bool handleButtonPress(u64 button);
#endif