diff --git a/CMakeLists.txt b/CMakeLists.txt index 739ec39..9f4ef2f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,6 +61,7 @@ add_shader(basic_pixel_shader) add_executable(mikemon src/log.cpp src/load_entire_file.cpp + src/smol-atlas.cpp src/main.cpp ) target_link_libraries(mikemon diff --git a/assets/map/map.sv b/assets/map/map.sv index eb79907..80eaa19 100644 Binary files a/assets/map/map.sv and b/assets/map/map.sv differ diff --git a/assets/shader/basic_pixel_shader.h b/assets/shader/basic_pixel_shader.h index f2efcf0..2fd556d 100644 --- a/assets/shader/basic_pixel_shader.h +++ b/assets/shader/basic_pixel_shader.h @@ -1,253 +1,229 @@ const unsigned char SPIRV_basic_pixel_shader[] = { - 0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0b, 0x00, 0x08, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0b, 0x00, 0x08, 0x00, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x53, 0x50, 0x56, 0x5f, 0x4b, 0x48, 0x52, 0x5f, 0x6e, 0x6f, 0x6e, 0x5f, 0x73, 0x65, 0x6d, 0x61, 0x6e, 0x74, 0x69, 0x63, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x01, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x53, 0x65, 0x6d, 0x61, 0x6e, 0x74, 0x69, 0x63, 0x2e, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x44, 0x65, 0x62, 0x75, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x31, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x03, 0x00, 0x00, 0x00, 0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, - 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, - 0x00, 0x10, 0x00, 0x03, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x03, 0x00, 0x02, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x75, 0x69, 0x6e, 0x74, 0x00, - 0x00, 0x00, 0x00, 0x07, 0x00, 0x13, 0x00, 0x10, 0x00, 0x00, 0x00, 0x2f, 0x68, 0x6f, 0x6d, 0x65, 0x2f, 0x73, 0x76, - 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x6d, 0x69, 0x6b, 0x65, 0x6d, 0x6f, 0x6e, - 0x2f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x73, 0x2f, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x2f, 0x62, 0x61, 0x73, 0x69, - 0x63, 0x5f, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x5f, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x73, 0x6c, 0x61, 0x6e, - 0x67, 0x00, 0x00, 0x07, 0x00, 0x04, 0x00, 0x11, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x08, 0x01, 0x19, 0x00, 0x00, 0x00, 0x2f, 0x2f, 0x20, 0x4f, 0x70, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, - 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x76, 0x75, - 0x6c, 0x6b, 0x61, 0x6e, 0x31, 0x30, 0x30, 0x0a, 0x2f, 0x2f, 0x20, 0x4f, 0x70, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, - 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x2d, 0x65, 0x6e, - 0x76, 0x20, 0x76, 0x75, 0x6c, 0x6b, 0x61, 0x6e, 0x31, 0x2e, 0x30, 0x0a, 0x2f, 0x2f, 0x20, 0x4f, 0x70, 0x4d, 0x6f, - 0x64, 0x75, 0x6c, 0x65, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x65, 0x6e, 0x74, 0x72, 0x79, - 0x2d, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x0a, 0x23, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x31, - 0x0a, 0x23, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x34, 0x35, 0x30, 0x0a, 0x6c, 0x61, 0x79, 0x6f, 0x75, - 0x74, 0x28, 0x72, 0x6f, 0x77, 0x5f, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x29, 0x20, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, - 0x6d, 0x3b, 0x0a, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x28, 0x72, 0x6f, 0x77, 0x5f, 0x6d, 0x61, 0x6a, 0x6f, 0x72, - 0x29, 0x20, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x3b, 0x0a, 0x0a, 0x23, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x31, 0x32, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x10, 0x00, 0x03, + 0x00, 0x0e, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x07, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x75, 0x69, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x07, + 0x00, 0x13, 0x00, 0x10, 0x00, 0x00, 0x00, 0x2f, 0x68, 0x6f, 0x6d, 0x65, 0x2f, 0x73, 0x76, 0x65, 0x6e, 0x2f, 0x70, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x6d, 0x69, 0x6b, 0x65, 0x6d, 0x6f, 0x6e, 0x2f, 0x61, 0x73, 0x73, + 0x65, 0x74, 0x73, 0x2f, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x2f, 0x62, 0x61, 0x73, 0x69, 0x63, 0x5f, 0x70, 0x69, + 0x78, 0x65, 0x6c, 0x5f, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x73, 0x6c, 0x61, 0x6e, 0x67, 0x00, 0x00, 0x07, + 0x00, 0x04, 0x00, 0x11, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xed, 0x00, + 0x19, 0x00, 0x00, 0x00, 0x2f, 0x2f, 0x20, 0x4f, 0x70, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x50, 0x72, 0x6f, 0x63, + 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x76, 0x75, 0x6c, 0x6b, 0x61, 0x6e, + 0x31, 0x30, 0x30, 0x0a, 0x2f, 0x2f, 0x20, 0x4f, 0x70, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x50, 0x72, 0x6f, 0x63, + 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x2d, 0x65, 0x6e, 0x76, 0x20, 0x76, 0x75, + 0x6c, 0x6b, 0x61, 0x6e, 0x31, 0x2e, 0x30, 0x0a, 0x2f, 0x2f, 0x20, 0x4f, 0x70, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, + 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2d, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x0a, 0x23, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x31, 0x0a, 0x23, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x34, 0x35, 0x30, 0x0a, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x28, 0x72, 0x6f, + 0x77, 0x5f, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x29, 0x20, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x3b, 0x0a, 0x6c, + 0x61, 0x79, 0x6f, 0x75, 0x74, 0x28, 0x72, 0x6f, 0x77, 0x5f, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x29, 0x20, 0x62, 0x75, + 0x66, 0x66, 0x65, 0x72, 0x3b, 0x0a, 0x0a, 0x23, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x31, 0x32, 0x20, 0x22, 0x2f, 0x68, + 0x6f, 0x6d, 0x65, 0x2f, 0x73, 0x76, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x6d, + 0x69, 0x6b, 0x65, 0x6d, 0x6f, 0x6e, 0x2f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x73, 0x2f, 0x73, 0x68, 0x61, 0x64, 0x65, + 0x72, 0x2f, 0x62, 0x61, 0x73, 0x69, 0x63, 0x5f, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x5f, 0x73, 0x68, 0x61, 0x64, 0x65, + 0x72, 0x2e, 0x73, 0x6c, 0x61, 0x6e, 0x67, 0x22, 0x0a, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x28, 0x62, 0x69, 0x6e, + 0x64, 0x69, 0x6e, 0x67, 0x20, 0x3d, 0x20, 0x30, 0x2c, 0x20, 0x73, 0x65, 0x74, 0x20, 0x3d, 0x20, 0x32, 0x29, 0x0a, + 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x32, 0x44, 0x20, 0x74, + 0x65, 0x78, 0x31, 0x5f, 0x30, 0x3b, 0x0a, 0x0a, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x28, 0x62, 0x69, 0x6e, 0x64, + 0x69, 0x6e, 0x67, 0x20, 0x3d, 0x20, 0x30, 0x2c, 0x20, 0x73, 0x65, 0x74, 0x20, 0x3d, 0x20, 0x32, 0x29, 0x0a, 0x75, + 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x20, 0x74, 0x65, 0x78, 0x74, + 0x75, 0x72, 0x65, 0x5f, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x5f, 0x30, 0x3b, 0x0a, 0x0a, 0x0a, 0x23, 0x6c, + 0x69, 0x6e, 0x65, 0x20, 0x31, 0x37, 0x38, 0x30, 0x20, 0x22, 0x68, 0x6c, 0x73, 0x6c, 0x2e, 0x6d, 0x65, 0x74, 0x61, + 0x2e, 0x73, 0x6c, 0x61, 0x6e, 0x67, 0x22, 0x0a, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x28, 0x6c, 0x6f, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x30, 0x29, 0x0a, 0x6f, 0x75, 0x74, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, + 0x65, 0x6e, 0x74, 0x72, 0x79, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x5f, 0x6d, 0x61, 0x69, + 0x6e, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x30, 0x3b, 0x0a, 0x0a, 0x0a, 0x23, 0x6c, 0x69, 0x6e, 0x65, 0x20, + 0x31, 0x37, 0x38, 0x30, 0x0a, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x28, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x3d, 0x20, 0x30, 0x29, 0x0a, 0x69, 0x6e, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x69, 0x6e, 0x70, 0x75, + 0x74, 0x5f, 0x75, 0x76, 0x73, 0x74, 0x5f, 0x30, 0x3b, 0x0a, 0x0a, 0x0a, 0x23, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x37, 0x20, 0x22, 0x2f, 0x68, 0x6f, 0x6d, 0x65, 0x2f, 0x73, 0x76, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x6d, 0x69, 0x6b, 0x65, 0x6d, 0x6f, 0x6e, 0x2f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x73, 0x2f, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x2f, 0x62, 0x61, 0x73, 0x69, 0x63, 0x5f, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x5f, 0x73, - 0x68, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x73, 0x6c, 0x61, 0x6e, 0x67, 0x22, 0x0a, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, - 0x28, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x3d, 0x20, 0x30, 0x2c, 0x20, 0x73, 0x65, 0x74, 0x20, 0x3d, - 0x20, 0x32, 0x29, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, - 0x32, 0x44, 0x41, 0x72, 0x72, 0x61, 0x79, 0x20, 0x74, 0x65, 0x78, 0x31, 0x5f, 0x30, 0x3b, 0x0a, 0x0a, 0x6c, 0x61, - 0x79, 0x6f, 0x75, 0x74, 0x28, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x3d, 0x20, 0x30, 0x2c, 0x20, 0x73, - 0x65, 0x74, 0x20, 0x3d, 0x20, 0x32, 0x29, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, 0x61, 0x6d, - 0x70, 0x6c, 0x65, 0x72, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, - 0x72, 0x5f, 0x30, 0x3b, 0x0a, 0x0a, 0x0a, 0x23, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x31, 0x37, 0x38, 0x30, 0x20, 0x22, - 0x68, 0x6c, 0x73, 0x6c, 0x2e, 0x6d, 0x65, 0x74, 0x61, 0x2e, 0x73, 0x6c, 0x61, 0x6e, 0x67, 0x22, 0x0a, 0x6c, 0x61, - 0x79, 0x6f, 0x75, 0x74, 0x28, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x30, 0x29, 0x0a, - 0x6f, 0x75, 0x74, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x50, 0x6f, 0x69, 0x6e, 0x74, - 0x50, 0x61, 0x72, 0x61, 0x6d, 0x5f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x30, 0x3b, - 0x0a, 0x0a, 0x0a, 0x23, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x31, 0x37, 0x38, 0x30, 0x0a, 0x6c, 0x61, 0x79, 0x6f, 0x75, - 0x74, 0x28, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x30, 0x29, 0x0a, 0x69, 0x6e, 0x20, - 0x76, 0x65, 0x63, 0x34, 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x75, 0x76, 0x73, 0x74, 0x5f, 0x30, 0x3b, 0x0a, - 0x0a, 0x0a, 0x23, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x31, 0x37, 0x38, 0x30, 0x0a, 0x66, 0x6c, 0x61, 0x74, 0x20, 0x6c, - 0x61, 0x79, 0x6f, 0x75, 0x74, 0x28, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x31, 0x29, - 0x0a, 0x69, 0x6e, 0x20, 0x75, 0x69, 0x6e, 0x74, 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x74, 0x69, 0x6c, 0x65, - 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x30, 0x3b, 0x0a, 0x0a, 0x0a, 0x23, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x37, 0x20, - 0x22, 0x2f, 0x68, 0x6f, 0x6d, 0x65, 0x2f, 0x73, 0x76, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, - 0x73, 0x2f, 0x6d, 0x69, 0x6b, 0x65, 0x6d, 0x6f, 0x6e, 0x2f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x73, 0x2f, 0x73, 0x68, - 0x61, 0x64, 0x65, 0x72, 0x2f, 0x62, 0x61, 0x73, 0x69, 0x63, 0x5f, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x5f, 0x73, 0x68, - 0x61, 0x64, 0x65, 0x72, 0x2e, 0x73, 0x6c, 0x61, 0x6e, 0x67, 0x22, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, + 0x68, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x73, 0x6c, 0x61, 0x6e, 0x67, 0x22, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x20, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, + 0x30, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, + 0x30, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x0a, 0x0a, 0x23, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x31, 0x38, 0x0a, 0x76, 0x6f, + 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29, 0x0a, 0x7b, 0x0a, 0x0a, 0x23, 0x6c, 0x69, 0x6e, 0x65, 0x20, + 0x31, 0x39, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x30, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x30, 0x3b, 0x0a, 0x0a, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x5f, 0x53, 0x31, 0x20, 0x3d, 0x20, 0x28, 0x74, 0x65, + 0x78, 0x74, 0x75, 0x72, 0x65, 0x28, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x32, 0x44, 0x28, 0x74, 0x65, 0x78, + 0x31, 0x5f, 0x30, 0x2c, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, + 0x5f, 0x30, 0x29, 0x2c, 0x20, 0x28, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x75, 0x76, 0x73, 0x74, 0x5f, 0x30, 0x2e, + 0x78, 0x79, 0x29, 0x29, 0x29, 0x3b, 0x0a, 0x0a, 0x23, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x32, 0x32, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x30, 0x2e, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x30, 0x20, + 0x3d, 0x20, 0x5f, 0x53, 0x31, 0x3b, 0x0a, 0x0a, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x74, 0x72, 0x79, + 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x5f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x5f, 0x30, 0x20, 0x3d, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x30, 0x2e, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x5f, 0x30, 0x3b, 0x0a, 0x0a, 0x23, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x32, 0x36, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x00, 0x07, 0x00, 0x04, 0x00, 0x1f, 0x00, + 0x00, 0x00, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x00, 0x00, 0x00, 0x07, 0x00, 0x03, 0x00, 0x28, 0x00, 0x00, 0x00, 0x5f, + 0x53, 0x31, 0x00, 0x07, 0x00, 0x06, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x32, 0x64, 0x2e, + 0x69, 0x6d, 0x61, 0x67, 0x65, 0x00, 0x00, 0x00, 0x07, 0x00, 0x06, 0x00, 0x30, 0x00, 0x00, 0x00, 0x40, 0x74, 0x79, + 0x70, 0x65, 0x2e, 0x32, 0x64, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x00, 0x00, 0x07, 0x00, 0x04, 0x00, 0x36, 0x00, + 0x00, 0x00, 0x74, 0x65, 0x78, 0x31, 0x5f, 0x30, 0x00, 0x00, 0x07, 0x00, 0x06, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x74, + 0x79, 0x70, 0x65, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x06, 0x00, + 0x3c, 0x00, 0x00, 0x00, 0x40, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x00, 0x00, + 0x00, 0x07, 0x00, 0x07, 0x00, 0x41, 0x00, 0x00, 0x00, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x73, 0x61, + 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x5f, 0x30, 0x00, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, 0x45, 0x00, 0x00, 0x00, 0x74, + 0x79, 0x70, 0x65, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x64, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x00, 0x00, + 0x07, 0x00, 0x07, 0x00, 0x46, 0x00, 0x00, 0x00, 0x40, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, + 0x65, 0x64, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x00, 0x07, 0x00, 0x06, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x69, 0x6e, + 0x70, 0x75, 0x74, 0x5f, 0x75, 0x76, 0x73, 0x74, 0x5f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x04, 0x00, 0x54, + 0x00, 0x00, 0x00, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x30, 0x00, 0x07, 0x00, 0x07, 0x00, 0x58, 0x00, 0x00, 0x00, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x30, - 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x30, - 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x0a, 0x0a, 0x23, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x31, 0x38, 0x0a, 0x76, 0x6f, 0x69, - 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29, 0x0a, 0x7b, 0x0a, 0x0a, 0x23, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x31, - 0x39, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, - 0x74, 0x70, 0x75, 0x74, 0x5f, 0x30, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x30, 0x3b, 0x0a, 0x0a, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x5f, 0x53, 0x31, 0x20, 0x3d, 0x20, 0x28, 0x74, 0x65, 0x78, - 0x74, 0x75, 0x72, 0x65, 0x28, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x32, 0x44, 0x41, 0x72, 0x72, 0x61, 0x79, - 0x28, 0x74, 0x65, 0x78, 0x31, 0x5f, 0x30, 0x2c, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x73, 0x61, 0x6d, - 0x70, 0x6c, 0x65, 0x72, 0x5f, 0x30, 0x29, 0x2c, 0x20, 0x28, 0x76, 0x65, 0x63, 0x33, 0x28, 0x69, 0x6e, 0x70, 0x75, - 0x74, 0x5f, 0x75, 0x76, 0x73, 0x74, 0x5f, 0x30, 0x2e, 0x78, 0x79, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x28, - 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x74, 0x69, 0x6c, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x30, 0x29, 0x29, - 0x29, 0x29, 0x29, 0x3b, 0x0a, 0x0a, 0x23, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x32, 0x32, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x30, 0x2e, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x30, 0x20, 0x3d, 0x20, - 0x5f, 0x53, 0x31, 0x3b, 0x0a, 0x0a, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x50, 0x6f, - 0x69, 0x6e, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x5f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, - 0x5f, 0x30, 0x20, 0x3d, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x30, 0x2e, 0x63, 0x6f, 0x6c, 0x6f, 0x72, - 0x5f, 0x30, 0x3b, 0x0a, 0x0a, 0x23, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x32, 0x36, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, - 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x00, 0x07, 0x00, 0x04, 0x00, 0x1f, 0x00, 0x00, 0x00, - 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x00, 0x00, 0x00, 0x07, 0x00, 0x03, 0x00, 0x28, 0x00, 0x00, 0x00, 0x5f, 0x53, 0x31, - 0x00, 0x07, 0x00, 0x06, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x32, 0x64, 0x2e, 0x69, 0x6d, - 0x61, 0x67, 0x65, 0x00, 0x00, 0x00, 0x07, 0x00, 0x06, 0x00, 0x30, 0x00, 0x00, 0x00, 0x40, 0x74, 0x79, 0x70, 0x65, - 0x2e, 0x32, 0x64, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x00, 0x00, 0x07, 0x00, 0x04, 0x00, 0x36, 0x00, 0x00, 0x00, - 0x74, 0x65, 0x78, 0x31, 0x5f, 0x30, 0x00, 0x00, 0x07, 0x00, 0x06, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x74, 0x79, 0x70, - 0x65, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x06, 0x00, 0x3c, 0x00, - 0x00, 0x00, 0x40, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x00, 0x00, 0x00, 0x07, - 0x00, 0x07, 0x00, 0x41, 0x00, 0x00, 0x00, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x73, 0x61, 0x6d, 0x70, - 0x6c, 0x65, 0x72, 0x5f, 0x30, 0x00, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, 0x45, 0x00, 0x00, 0x00, 0x74, 0x79, 0x70, - 0x65, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x64, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x00, 0x00, 0x07, 0x00, - 0x07, 0x00, 0x46, 0x00, 0x00, 0x00, 0x40, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x64, - 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x00, 0x07, 0x00, 0x06, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x69, 0x6e, 0x70, 0x75, - 0x74, 0x5f, 0x75, 0x76, 0x73, 0x74, 0x5f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, 0x55, 0x00, 0x00, - 0x00, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x74, 0x69, 0x6c, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x30, 0x00, - 0x00, 0x00, 0x07, 0x00, 0x04, 0x00, 0x60, 0x00, 0x00, 0x00, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x30, 0x00, 0x07, - 0x00, 0x07, 0x00, 0x64, 0x00, 0x00, 0x00, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, - 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x30, 0x00, 0x07, 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x6f, 0x75, 0x74, - 0x70, 0x75, 0x74, 0x5f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x03, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x69, 0x6e, - 0x74, 0x00, 0x07, 0x00, 0x0a, 0x00, 0x75, 0x00, 0x00, 0x00, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x50, 0x6f, 0x69, 0x6e, - 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x5f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x30, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x47, 0x4c, 0x5f, 0x47, 0x4f, 0x4f, 0x47, 0x4c, 0x45, 0x5f, 0x63, - 0x70, 0x70, 0x5f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, - 0x74, 0x69, 0x76, 0x65, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, - 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x26, 0x00, 0x00, 0x00, 0x5f, 0x53, 0x31, 0x00, 0x05, 0x00, 0x04, 0x00, - 0x34, 0x00, 0x00, 0x00, 0x74, 0x65, 0x78, 0x31, 0x5f, 0x30, 0x00, 0x00, 0x05, 0x00, 0x07, 0x00, 0x3f, 0x00, 0x00, - 0x00, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x5f, 0x30, 0x00, - 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x75, 0x76, 0x73, - 0x74, 0x5f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x07, 0x00, 0x53, 0x00, 0x00, 0x00, 0x69, 0x6e, 0x70, 0x75, - 0x74, 0x5f, 0x74, 0x69, 0x6c, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x30, 0x00, 0x00, 0x00, 0x05, 0x00, 0x07, - 0x00, 0x5e, 0x00, 0x00, 0x00, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, - 0x70, 0x75, 0x74, 0x5f, 0x30, 0x00, 0x06, 0x00, 0x05, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, - 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x30, 0x00, 0x05, 0x00, 0x05, 0x00, 0x67, 0x00, 0x00, 0x00, 0x6f, 0x75, 0x74, 0x70, - 0x75, 0x74, 0x5f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x0a, 0x00, 0x73, 0x00, 0x00, 0x00, 0x65, 0x6e, 0x74, - 0x72, 0x79, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x5f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x63, - 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x34, 0x00, 0x00, 0x00, 0x21, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x34, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x47, 0x00, 0x04, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x47, 0x00, - 0x04, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x53, - 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x53, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x73, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x13, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, - 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, - 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, - 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x09, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, - 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x08, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x04, 0x00, - 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x2b, - 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, - 0x00, 0x17, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, 0x18, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x2b, - 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x09, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, - 0x00, 0x17, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x0e, 0x00, 0x04, 0x00, - 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x06, - 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, - 0x11, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00, 0x1e, 0x00, 0x00, - 0x00, 0x20, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x09, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0c, - 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x21, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x0c, 0x00, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, - 0x00, 0x20, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x23, 0x00, 0x00, 0x00, 0x07, 0x00, - 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x07, - 0x00, 0x00, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, - 0x00, 0x07, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x04, 0x00, - 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x22, - 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x17, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x05, 0x00, 0x04, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x1f, 0x00, 0x00, 0x00, 0x19, 0x00, 0x09, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0c, 0x00, 0x05, 0x00, 0x04, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x0e, 0x00, 0x04, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x0a, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x29, 0x00, - 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x0d, - 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, - 0x0c, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, - 0x00, 0x2e, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x32, 0x00, - 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x37, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x0e, 0x00, 0x04, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, - 0x00, 0x29, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x34, 0x00, - 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x02, 0x00, 0x39, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x0e, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, - 0x16, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, - 0x00, 0x3c, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x3d, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x3e, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, - 0x0c, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x0c, 0x00, 0x0e, 0x00, 0x04, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x12, 0x00, - 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x0c, - 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, - 0x1b, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x0e, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x0c, 0x00, - 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x46, - 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x48, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x0c, 0x00, - 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x48, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c, - 0x00, 0x0e, 0x00, 0x04, 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x4c, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, - 0x00, 0x15, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x17, 0x00, - 0x04, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x07, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x1a, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x51, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, - 0x00, 0x0c, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, - 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x51, - 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x0e, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x54, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, - 0x00, 0x13, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x55, 0x00, - 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x58, 0x00, 0x00, 0x00, 0x1e, - 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x03, - 0x00, 0x5e, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x61, 0x00, - 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x0a, - 0x00, 0x00, 0x00, 0x0c, 0x00, 0x0d, 0x00, 0x04, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x0b, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, - 0x00, 0x62, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0c, 0x00, - 0x0f, 0x00, 0x04, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x64, - 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, - 0x15, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, - 0x00, 0x20, 0x00, 0x04, 0x00, 0x65, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x0c, 0x00, - 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x63, - 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x68, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, - 0x00, 0x13, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x17, 0x00, - 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c, - 0x00, 0x09, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x6c, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, - 0x00, 0x6b, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x71, 0x00, - 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x72, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, - 0x0c, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x71, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, - 0x00, 0x2b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x0c, 0x00, - 0x0e, 0x00, 0x04, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x75, - 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, - 0x15, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, - 0x00, 0x07, 0x00, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00, 0x04, 0x00, - 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x0f, - 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x23, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x3b, 0x00, 0x04, 0x00, 0x65, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x06, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x12, 0x00, - 0x00, 0x00, 0x0c, 0x00, 0x0a, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x67, - 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, - 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x65, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x0a, 0x00, 0x04, 0x00, - 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x29, - 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x08, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, - 0x00, 0x26, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x38, 0x00, - 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x39, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x3f, - 0x00, 0x00, 0x00, 0x56, 0x00, 0x05, 0x00, 0x43, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, - 0x42, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x21, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, - 0x00, 0x4f, 0x00, 0x07, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x4f, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x56, - 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x70, 0x00, 0x04, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, - 0x56, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x50, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x06, 0x00, 0x58, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x5a, - 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x57, 0x00, 0x05, 0x00, 0x21, 0x00, 0x00, 0x00, - 0x5d, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x26, 0x00, 0x00, - 0x00, 0x5d, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x3d, - 0x00, 0x04, 0x00, 0x21, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, - 0x23, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, - 0x00, 0x70, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x0a, 0x00, 0x04, 0x00, 0x00, 0x00, 0x78, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x76, + 0x00, 0x07, 0x00, 0x05, 0x00, 0x5d, 0x00, 0x00, 0x00, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x07, 0x00, 0x03, 0x00, 0x60, 0x00, 0x00, 0x00, 0x69, 0x6e, 0x74, 0x00, 0x07, 0x00, 0x0a, 0x00, 0x69, + 0x00, 0x00, 0x00, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x5f, + 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0a, + 0x00, 0x47, 0x4c, 0x5f, 0x47, 0x4f, 0x4f, 0x47, 0x4c, 0x45, 0x5f, 0x63, 0x70, 0x70, 0x5f, 0x73, 0x74, 0x79, 0x6c, + 0x65, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x00, 0x00, 0x05, + 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, + 0x26, 0x00, 0x00, 0x00, 0x5f, 0x53, 0x31, 0x00, 0x05, 0x00, 0x04, 0x00, 0x34, 0x00, 0x00, 0x00, 0x74, 0x65, 0x78, + 0x31, 0x5f, 0x30, 0x00, 0x00, 0x05, 0x00, 0x07, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, + 0x65, 0x5f, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x5f, 0x30, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x4a, + 0x00, 0x00, 0x00, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x75, 0x76, 0x73, 0x74, 0x5f, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x07, 0x00, 0x52, 0x00, 0x00, 0x00, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, + 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x30, 0x00, 0x06, 0x00, 0x05, 0x00, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x30, 0x00, 0x05, 0x00, 0x05, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x0a, 0x00, 0x67, 0x00, 0x00, 0x00, + 0x65, 0x6e, 0x74, 0x72, 0x79, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x5f, 0x6d, 0x61, 0x69, + 0x6e, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x34, 0x00, + 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x34, 0x00, 0x00, 0x00, 0x22, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x47, 0x00, 0x04, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, + 0x04, 0x00, 0x67, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, + 0x00, 0x0a, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0b, 0x00, + 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0x00, 0x09, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, + 0x00, 0x2b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0c, 0x00, + 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0d, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x04, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, + 0x00, 0x14, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x16, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0c, 0x00, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x23, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, + 0x00, 0x1a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x09, 0x00, 0x04, 0x00, 0x00, 0x00, 0x15, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x18, + 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x0e, 0x00, 0x04, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, + 0x00, 0x14, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0d, 0x00, + 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0c, + 0x00, 0x09, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x1f, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, + 0x00, 0x21, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x07, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x17, + 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x23, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, + 0x2b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x08, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x22, 0x00, + 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x29, + 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x04, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, + 0x00, 0x29, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x0c, 0x00, + 0x05, 0x00, 0x04, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x19, + 0x00, 0x09, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x05, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, + 0x0e, 0x00, 0x04, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x2f, + 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x15, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, + 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x0c, + 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x32, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x0c, 0x00, 0x0e, 0x00, 0x04, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x0c, + 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, + 0x1a, 0x00, 0x02, 0x00, 0x39, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x0e, 0x00, 0x04, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x13, 0x00, + 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x39, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x3b, 0x00, + 0x04, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x0e, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, + 0x3a, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, + 0x00, 0x41, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x03, 0x00, 0x43, 0x00, + 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x0e, 0x00, 0x04, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x29, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, + 0x00, 0x0d, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x21, 0x00, + 0x00, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, + 0x48, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x0e, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x4b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x22, 0x00, + 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x4c, + 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x4d, 0x00, 0x00, 0x00, + 0x1e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x1e, 0x00, + 0x03, 0x00, 0x52, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x55, + 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x0d, 0x00, 0x04, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x0b, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x55, 0x00, + 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0c, + 0x00, 0x0f, 0x00, 0x04, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x58, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, + 0x00, 0x15, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x53, 0x00, + 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x59, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x0c, + 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x57, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x5c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x5d, 0x00, 0x00, 0x00, 0x57, 0x00, + 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x17, + 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x09, 0x00, 0x04, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x2b, 0x00, + 0x04, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x65, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x66, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, + 0x00, 0x0c, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x65, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x03, 0x00, + 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x0c, + 0x00, 0x0e, 0x00, 0x04, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x69, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, + 0x00, 0x15, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x2b, 0x00, + 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x23, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, + 0x00, 0x3b, 0x00, 0x04, 0x00, 0x59, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0c, 0x00, + 0x06, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x12, + 0x00, 0x00, 0x00, 0x0c, 0x00, 0x0a, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x67, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, + 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x0a, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x29, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x08, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x27, 0x00, + 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x38, + 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x39, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, + 0x3f, 0x00, 0x00, 0x00, 0x56, 0x00, 0x05, 0x00, 0x43, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, + 0x00, 0x42, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x21, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x4a, 0x00, + 0x00, 0x00, 0x4f, 0x00, 0x07, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x4f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x57, 0x00, 0x05, 0x00, 0x21, 0x00, 0x00, 0x00, + 0x51, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x26, 0x00, 0x00, + 0x00, 0x51, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x3d, + 0x00, 0x04, 0x00, 0x21, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, + 0x23, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, + 0x00, 0x64, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x0a, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6c, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x23, 0x00, 0x00, 0x00, - 0x77, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x21, 0x00, 0x00, - 0x00, 0x79, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x73, 0x00, 0x00, 0x00, 0x79, 0x00, + 0x6b, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x21, 0x00, 0x00, + 0x00, 0x6d, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x67, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00, }; -const size_t SPIRV_basic_pixel_shader_sizeInBytes = 4684; +const size_t SPIRV_basic_pixel_shader_sizeInBytes = 4228; diff --git a/assets/shader/basic_pixel_shader.slang b/assets/shader/basic_pixel_shader.slang index 2e618bf..957e86b 100644 --- a/assets/shader/basic_pixel_shader.slang +++ b/assets/shader/basic_pixel_shader.slang @@ -9,7 +9,7 @@ struct PixelShaderOutput { }; [[vk::binding(0, 2)]] -Texture2DArray tex1 : register(t0, space2); +Texture2D tex1 : register(t0, space2); [[vk::binding(0, 2)]] SamplerState texture_sampler : register(s0, space2); @@ -19,7 +19,7 @@ PixelShaderOutput main(PixelShaderInput input) { PixelShaderOutput output; #if 1 - output.color = tex1.Sample(texture_sampler, float3(input.uvst.xy, input.tile_type)); + output.color = tex1.Sample(texture_sampler, float2(input.uvst.xy)); #else output.color = float4(1, 0, 1, 1); #endif diff --git a/src/main.cpp b/src/main.cpp index fcc8a09..c284bfe 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,6 +6,7 @@ #include #include +#include "smol-atlas.h" #include "defer.h" #include "log.h" #include "m_string.h" @@ -31,8 +32,8 @@ SDL_GPUBuffer *index_buffer; SDL_GPUBuffer *tiles_instance_buffer; SDL_GPUBuffer *player_instance_buffer; -Sint16 window_width; -Sint16 window_height; +Sint32 window_width; +Sint32 window_height; bool Running = true; @@ -68,14 +69,10 @@ Instance tiles_instances[view_width * view_height] = { Instance player_instance = { { 0.5f + 0.5f / view_width, 0.5f, 1.0f / view_width, 1.0f / view_height}, 0, {0, 0, 1, 1}}; -struct Tile { - Uint32 type; -}; - Uint32 map_width = view_width; Uint32 map_height = view_height; -Tile* map_tiles; +Uint32* map_tiles; struct Player { Sint64 pos_x; @@ -94,6 +91,24 @@ struct PerFrame { PerFrame per_frame = {1}; +typedef struct { + Uint32 type; + const char *asset_path; + + smol_atlas_item_t *atlas_item; +} TileInfo; + +TileInfo tile_infos[] = { + { 0x0001, "../assets/tiles/error.png" }, + { 0x0000, "../assets/tiles/empty.png" }, + { 0x0100, "../assets/tiles/grass_1.png" }, + { 0x0200, "../assets/tiles/ground_1.png" }, + { 0x0300, "../assets/tiles/water_1.png" }, +}; + +int tile_atlas_size = 256; +smol_atlas_t *tile_atlas; + void save_map() { log("Save file is under construction."); FILE* file = fopen("../assets/map/map.sv", "wb"); @@ -115,7 +130,8 @@ void save_map() { } for (int i = 0; i < map_width * map_height; i++) { - if (fwrite(&map_tiles[i], sizeof(Tile), 1, file) != 1) { + Uint32 type = tile_infos[map_tiles[i]].type; + if (fwrite(&type, sizeof(Uint32), 1, file) != 1) { log_error("fwrite for tile_type at tile number %d has failed.", i); return; } @@ -142,17 +158,26 @@ void load_map() { if (map_tiles) free(map_tiles); - map_tiles = (Tile*)malloc(map_width * map_height * sizeof(Tile)); + map_tiles = (Uint32*)malloc(map_width * map_height * sizeof(Uint32)); for (int i = 0; i < map_width * map_height; i++) { - map_tiles[i] = read(file); + Uint32 type = read(file); + Uint32 kind = 0; + for (int i = 0; i < SDL_arraysize(tile_infos); i++) { + if (tile_infos[i].type == type) { + kind = i; + break; + } + } + + map_tiles[i] = kind; } log("Loading map was successful."); } void change_map_size(char direction, int amount) { - Tile* old_map = map_tiles; + Uint32* old_map = map_tiles; auto old_map_width = map_width; auto old_map_height = map_height; @@ -200,7 +225,7 @@ void change_map_size(char direction, int amount) { to_fill_y_offset = old_map_height; } - map_tiles = (Tile*)malloc(map_width * map_height * sizeof(Tile)); + map_tiles = (Uint32*)malloc(map_width * map_height * sizeof(Uint32)); for (int y = 0; y < min(old_map_height, map_height); y++) { for (int x = 0; x < min(old_map_width, map_width); x++) { @@ -210,7 +235,7 @@ void change_map_size(char direction, int amount) { for (int y = 0; y < to_fill_height; y++) { for (int x = 0; x < to_fill_width; x++) { - map_tiles[(y + to_fill_y_offset) * map_width + (x + to_fill_x_offset)].type = 0; + map_tiles[(y + to_fill_y_offset) * map_width + (x + to_fill_x_offset)] = 0; } } @@ -406,27 +431,27 @@ SDL_GPUTexture *create_shader_texture(const char *path) { return texture; } -SDL_GPUTexture* create_shader_texture_array(Uint32 num_textures, const char **texture_paths, const char *debug_name) { - if (!num_textures) return NULL; - - int width = 0, height = 0, channels = 0; - stbi_uc *data = stbi_load(texture_paths[0], &width, &height, &channels, 4); - if (!data) { - log_error("Failed to load texture (\"%s\").", texture_paths[0]); +SDL_GPUTexture *create_shader_texture(const char *name, const char *data, int width, int height, int channels) { + SDL_GPUTextureFormat format = SDL_GPU_TEXTUREFORMAT_INVALID; + if (channels == 1) format = SDL_GPU_TEXTUREFORMAT_A8_UNORM; + if (channels == 4) format = SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM; + + if (format == SDL_GPU_TEXTUREFORMAT_INVALID) { + log_error("Failed to find texture format for texture."); return NULL; } SDL_PropertiesID properties = SDL_CreateProperties(); - if (properties) SDL_SetStringProperty(properties, SDL_PROP_GPU_TEXTURE_CREATE_NAME_STRING, debug_name); + if (properties) SDL_SetStringProperty(properties, SDL_PROP_GPU_TEXTURE_CREATE_NAME_STRING, name); SDL_GPUTextureCreateInfo texture_info = { - .type = SDL_GPU_TEXTURETYPE_2D_ARRAY, - .format = SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM, + .type = SDL_GPU_TEXTURETYPE_2D, + .format = format, .usage = SDL_GPU_TEXTUREUSAGE_SAMPLER, .width = (Uint32)width, .height = (Uint32)height, - .layer_count_or_depth = (Uint32)num_textures, + .layer_count_or_depth = 1, .num_levels = 1, .props = properties, @@ -435,23 +460,20 @@ SDL_GPUTexture* create_shader_texture_array(Uint32 num_textures, const char **te SDL_GPUTexture *texture = SDL_CreateGPUTexture(device, &texture_info); if (!texture) { log_error("Failed to create gpu texture (%s).", SDL_GetError()); - stbi_image_free(data); return NULL; } if (properties) SDL_DestroyProperties(properties); - Uint32 upload_size = width * height * 4; - Uint32 total_upload_size = upload_size * num_textures; + Uint32 upload_size = width * height * channels; SDL_GPUTransferBufferCreateInfo transfer_buffer_info = { .usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD, - .size = total_upload_size, + .size = upload_size, }; SDL_GPUTransferBuffer *transfer_buffer = SDL_CreateGPUTransferBuffer(device, &transfer_buffer_info); if (!transfer_buffer) { log_error("Failed to create gpu transfer buffer (%s).", SDL_GetError()); SDL_ReleaseGPUTexture(device, texture); - stbi_image_free(data); return NULL; } @@ -460,30 +482,23 @@ SDL_GPUTexture* create_shader_texture_array(Uint32 num_textures, const char **te log_error("Failed to map gpu transfer buffer (%s).", SDL_GetError()); SDL_ReleaseGPUTransferBuffer(device, transfer_buffer); SDL_ReleaseGPUTexture(device, texture); - stbi_image_free(data); return NULL; } - memcpy(transfer_data, data, upload_size); - stbi_image_free(data); - - for (int i = 1; i < num_textures; i++) { - int width2 = 0, height2 = 0; - stbi_uc *data = stbi_load(texture_paths[i], &width2, &height2, &channels, 4); - if (!data || width != width2 || height != height2) { - log_error("Failed to load texture (\"%s\").", texture_paths[i]); - SDL_UnmapGPUTransferBuffer(device, transfer_buffer); - SDL_ReleaseGPUTransferBuffer(device, transfer_buffer); - SDL_ReleaseGPUTexture(device, texture); - return NULL; - } - - memcpy((void *)((char *)transfer_data + i * upload_size), data, upload_size); - stbi_image_free(data); - } - SDL_UnmapGPUTransferBuffer(device, transfer_buffer); + SDL_GPUTextureTransferInfo transfer_info = { + .transfer_buffer = transfer_buffer, + .pixels_per_row = (Uint32)width, + }; + + SDL_GPUTextureRegion tetxure_region = { + .texture = texture, + .w = (Uint32)width, + .h = (Uint32)height, + .d = 1, + }; + SDL_GPUCommandBuffer *command_buffer = SDL_AcquireGPUCommandBuffer(device); if (!command_buffer) { log_error("Failed to acquire gpu command buffer (%s).", SDL_GetError()); @@ -493,26 +508,7 @@ SDL_GPUTexture* create_shader_texture_array(Uint32 num_textures, const char **te } SDL_GPUCopyPass *copy_pass = SDL_BeginGPUCopyPass(command_buffer); - - for (int i = 0; i < num_textures; i++) { - SDL_GPUTextureTransferInfo transfer_info = { - .transfer_buffer = transfer_buffer, - .offset = i * upload_size, - .pixels_per_row = (Uint32)width, - .rows_per_layer = (Uint32)height, - }; - - SDL_GPUTextureRegion tetxure_region = { - .texture = texture, - .layer = (Uint32)i, - .w = (Uint32)width, - .h = (Uint32)height, - .d = 1, - }; - - SDL_UploadToGPUTexture(copy_pass, &transfer_info, &tetxure_region, false); - } - + SDL_UploadToGPUTexture(copy_pass, &transfer_info, &tetxure_region, false); SDL_EndGPUCopyPass(copy_pass); if (!SDL_SubmitGPUCommandBuffer(command_buffer)) { @@ -527,6 +523,11 @@ SDL_GPUTexture* create_shader_texture_array(Uint32 num_textures, const char **te return texture; } +void blit(char *dst, Sint32 dst_width, Sint32 dst_x, Sint32 dst_y, char *src, Sint32 width, Sint32 height, int components = 4) { + for (Sint32 y = 0; y < height; y++) + memmove(&dst[((dst_y + y) * dst_width + dst_x) * components], &src[y * width * components], width * components); +} + int main(int argc, char **argv) { if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS)) { log_error("Failed to initialize SDL (%s). Exiting.", SDL_GetError()); @@ -684,17 +685,35 @@ int main(int argc, char **argv) { } } - const char *player_texture_array[] = { "../assets/decorations/strawberry.png" }; - SDL_GPUTexture *player_texture = create_shader_texture_array(SDL_arraysize(player_texture_array), player_texture_array, "player_textures"); + SDL_GPUTexture *player_texture = create_shader_texture("../assets/decorations/strawberry.png"); if (!player_texture) { log_error("Failed to create shader texture. Exiting."); return 1; } - const char *tile_texture_array[] = { "../assets/tiles/empty.png", "../assets/tiles/grass_1.png" , "../assets/tiles/ground_1.png" , "../assets/tiles/water_1.png", "../assets/tiles/error.png" }; - SDL_GPUTexture *tile_texture = create_shader_texture_array(SDL_arraysize(tile_texture_array), tile_texture_array, "tile_textures"); - if (!player_texture) { - log_error("Failed to create shader texture array. Exiting."); + tile_atlas = sma_atlas_create(tile_atlas_size, tile_atlas_size); + char *tile_atlas_texture_cpu = (char *)calloc(1, tile_atlas_size * tile_atlas_size * 4); + for (int i = 0; i < SDL_arraysize(tile_infos); i++) { + int width = 0, height = 0; + stbi_uc *data = stbi_load(tile_infos[i].asset_path, &width, &height, NULL, 4); + if (!data) { + log_error("Failed to load texture (\"%s\"). Exiting.", tile_infos[i].asset_path); + return 1; + } + + tile_infos[i].atlas_item = sma_item_add(tile_atlas, width, height); + if (!tile_infos[i].atlas_item) { + log_error("Failed to add tile texture to atlas. Exiting."); + return 1; + } + + blit(tile_atlas_texture_cpu, tile_atlas_size, sma_item_x(tile_infos[i].atlas_item), sma_item_y(tile_infos[i].atlas_item), (char *)data, width, height); + stbi_image_free(data); + } + SDL_GPUTexture *tile_atlas_texture = create_shader_texture("tile_atlas", tile_atlas_texture_cpu, tile_atlas_size, tile_atlas_size, 4); + free(tile_atlas_texture_cpu); + if (!tile_atlas_texture) { + log_error("Failed to create tile atlas texture. Exiting."); return 1; } @@ -755,6 +774,9 @@ int main(int argc, char **argv) { bool show_demo_window = true; bool first_frame = true; + + SDL_GetWindowSizeInPixels(window, &window_width, &window_height); + // MSG Message; while (Running) { ImGui_ImplSDLGPU3_NewFrame(); @@ -861,7 +883,7 @@ int main(int argc, char **argv) { if(0 <= tile_x && tile_x < map_width && 0 <= tile_y && tile_y < map_height) - map_tiles[tile_x + map_width * tile_y].type = (map_tiles[tile_x + map_width * tile_y].type + 1) % 4; + map_tiles[tile_x + map_width * tile_y] = (map_tiles[tile_x + map_width * tile_y] + 1) % 4; SDL_Keymod modifiers = SDL_GetModState(); if (modifiers & SDL_KMOD_SHIFT && tile_x == -1) { @@ -900,10 +922,19 @@ int main(int argc, char **argv) { for (int x = 0; x < view_width; x++) { if (x + player.pos_x - view_width / 2 >= 0 && x + player.pos_x - view_width / 2 < map_width && y + player.pos_y - view_height / 2 >= 0 && y + player.pos_y - view_height / 2 < map_height) { - tiles_instances[x + y * view_width].tile_type = map_tiles[(x + player.pos_x - view_width / 2) + (y + player.pos_y - view_height / 2) * map_width].type; + tiles_instances[x + y * view_width].tile_type = map_tiles[(x + player.pos_x - view_width / 2) + (y + player.pos_y - view_height / 2) * map_width]; } else { - tiles_instances[x + y * view_width].tile_type = 4; + tiles_instances[x + y * view_width].tile_type = 0; } + + Uint32 type = tiles_instances[x + y * view_width].tile_type; + + float x0 = sma_item_x(tile_infos[type].atlas_item); + float y0 = sma_item_y(tile_infos[type].atlas_item); + float x1 = x0 + sma_item_width(tile_infos[type].atlas_item); + float y1 = y0 + sma_item_height(tile_infos[type].atlas_item); + + tiles_instances[x + y * view_width].uv0uv1 = { x0 / tile_atlas_size, y0 / tile_atlas_size, x1 / tile_atlas_size, y1 / tile_atlas_size }; } } @@ -942,7 +973,7 @@ int main(int argc, char **argv) { { .buffer = tiles_instance_buffer, .offset = 0 }, }; SDL_GPUTextureSamplerBinding texture_bindings[] = { - { .texture = tile_texture, .sampler = point_sampler }, + { .texture = tile_atlas_texture, .sampler = point_sampler }, }; SDL_BindGPUGraphicsPipeline(render_pass, basic_graphics_pipeline); @@ -987,4 +1018,4 @@ int main(int argc, char **argv) { } } return 0; -} \ No newline at end of file +} diff --git a/src/smol-atlas.cpp b/src/smol-atlas.cpp new file mode 100644 index 0000000..274de85 --- /dev/null +++ b/src/smol-atlas.cpp @@ -0,0 +1,403 @@ +// SPDX-License-Identifier: MIT OR Unlicense +// smol-atlas: https://github.com/aras-p/smol-atlas + +#include "smol-atlas.h" + +#include +#include +#include +#include + +// "memory pool" that allocates chunks of same size items, +// and maintains a freelist of items for O(1) alloc and free. +template +struct smol_pool_t +{ + static_assert(std::is_trivially_destructible_v, "smol_pool_t type must be trivially destructible"); + + union item_t + { + item_t* next; + alignas(alignof(T)) char data[sizeof(T)]; + }; + + struct chunk_t + { + item_t* storage = nullptr; + chunk_t* next = nullptr; + size_t m_size_in_items; + chunk_t(size_t size_in_items) : storage(new item_t[size_in_items]), m_size_in_items(size_in_items) + { + link_all_items(nullptr); + } + ~chunk_t() { delete[] storage; } + + void link_all_items(item_t* last_item_next_ptr) + { + for (size_t i = 1; i < m_size_in_items; ++i) + storage[i - 1].next = &storage[i]; + storage[m_size_in_items - 1].next = last_item_next_ptr; + } + }; + + size_t m_chunk_size_in_items; + chunk_t* m_cur_chunk = nullptr; + item_t* m_free_list = nullptr; + + smol_pool_t(size_t size_in_items) + : m_chunk_size_in_items(size_in_items) + , m_cur_chunk(new chunk_t(size_in_items)) + , m_free_list(m_cur_chunk->storage) + { + } + ~smol_pool_t() + { + chunk_t* chunk = m_cur_chunk; + while (chunk) { + chunk_t* next = chunk->next; + delete chunk; + chunk = next; + } + } + + // makes all items "unused", but keeps the allocated space + void clear() + { + chunk_t* chunk = m_cur_chunk; + while (chunk) { + chunk_t* next = chunk->next; + chunk->link_all_items(next ? next->storage : nullptr); + chunk = next; + } + m_free_list = m_cur_chunk ? m_cur_chunk->storage : nullptr; + } + + template T* alloc(Args &&... args) + { + // create a new chunk if current one is full + if (m_free_list == nullptr) { + chunk_t* new_chunk = new chunk_t(m_chunk_size_in_items); + new_chunk->next = m_cur_chunk; + m_cur_chunk = new_chunk; + m_free_list = m_cur_chunk->storage; + } + + // grab item from free list + item_t* item = m_free_list; + m_free_list = item->next; + + // construct the object + T* res = reinterpret_cast(item->data); + new (res) T(std::forward(args)...); + return res; + } + + void free(T* ptr) + { + // add item to the free list + item_t* item = reinterpret_cast(ptr); + item->next = m_free_list; + m_free_list = item; + } +}; + +static inline int max_i(int a, int b) +{ + return a > b ? a : b; +} + +struct smol_atlas_item_t +{ + explicit smol_atlas_item_t(int x_, int y_, int w_, int h_, int shelf_) + : x(x_), y(y_), width(w_), height(h_), shelf_index(shelf_) + { + } + + int x; + int y; + int width; + int height; + int shelf_index; +}; + +struct smol_free_span_t +{ + explicit smol_free_span_t(int x_, int w_) : x(x_), width(w_), next(nullptr) {} + + int x; + int width; + smol_free_span_t* next; +}; + +template +struct smol_single_list_t +{ + smol_single_list_t(T* h) : m_head(h) { } + + void insert(T* prev, T* node) + { + if (prev == nullptr) { // this is first node + node->next = m_head; + m_head = node; + } + else { + node->next = prev->next; + prev->next = node; + } + } + + void remove(T* prev, T* node) + { + if (prev) + prev->next = node->next; + else + m_head = node->next; + } + + T* m_head = nullptr; +}; + +struct smol_shelf_t +{ + explicit smol_shelf_t(int y, int width, int height, int index, smol_pool_t& span_pool) + : m_y(y), m_height(height), m_index(index), m_free_spans(span_pool.alloc(0, width)) + { + } + + bool has_space_for(int width) const + { + smol_free_span_t* it = m_free_spans.m_head; + while (it != nullptr) { + if (width <= it->width) + return true; + it = it->next; + } + return false; + } + + smol_atlas_item_t* alloc_item(int w, int h, smol_pool_t& item_pool, smol_pool_t& span_pool) + { + if (h > m_height) + return nullptr; + + // find a suitable free span + smol_free_span_t* it = m_free_spans.m_head; + smol_free_span_t* prev = nullptr; + while (it != nullptr) { + if (it->width >= w) { + break; + } + prev = it; + it = it->next; + } + + // no space in this shelf + if (it == nullptr) + return nullptr; + + const int x = it->x; + const int rest = it->width - w; + if (rest > 0) { + // there will be still space left in this span, adjust + it->x += w; + it->width -= w; + } + else { + // whole span is taken, remove it + m_free_spans.remove(prev, it); + span_pool.free(it); + } + + return item_pool.alloc(x, m_y, w, h, m_index); + } + + void add_free_span(int x, int width, smol_pool_t& span_pool) + { + // insert into free spans list at the right position + smol_free_span_t* free_e = span_pool.alloc(x, width); + smol_free_span_t* it = m_free_spans.m_head; + smol_free_span_t* prev = nullptr; + bool added = false; + while (it != nullptr) { + if (free_e->x < it->x) { + // found right place, insert into the list + m_free_spans.insert(prev, free_e); + added = true; + break; + } + prev = it; + it = it->next; + } + if (!added) + m_free_spans.insert(prev, free_e); + + merge_free_spans(prev, free_e, span_pool); + } + + void free_item(smol_atlas_item_t* e, smol_pool_t& item_pool, smol_pool_t& span_pool) + { + assert(e); + assert(e->shelf_index == m_index); + assert(e->y == m_y); + add_free_span(e->x, e->width, span_pool); + item_pool.free(e); + } + + void merge_free_spans(smol_free_span_t* prev, smol_free_span_t* span, smol_pool_t& span_pool) + { + smol_free_span_t* next = span->next; + if (next != nullptr && span->x + span->width == next->x) { + // merge with next + span->width += next->width; + m_free_spans.remove(span, next); + span_pool.free(next); + } + if (prev != nullptr && prev->x + prev->width == span->x) { + // merge with prev + prev->width += span->width; + m_free_spans.remove(prev, span); + span_pool.free(span); + } + } + + smol_single_list_t m_free_spans; + const int m_y; + const int m_height; + const int m_index; +}; + +struct smol_atlas_t +{ + explicit smol_atlas_t(int w, int h) + : m_item_pool(1024), m_span_pool(1024) + { + m_shelves.reserve(8); + m_width = w > 0 ? w : 64; + m_height = h > 0 ? h : 64; + } + + ~smol_atlas_t() + { + clear(); + } + + smol_atlas_item_t* pack(int w, int h) + { + // find best shelf + smol_shelf_t* best_shelf = nullptr; + int best_score = 0x7fffffff; + + int top_y = 0; + for (auto& shelf : m_shelves) { + const int shelf_h = shelf.m_height; + top_y = max_i(top_y, shelf.m_y + shelf_h); + + if (shelf_h < h) + continue; // too short + + if (shelf_h == h) { // exact height fit, try to use it + smol_atlas_item_t* res = shelf.alloc_item(w, h, m_item_pool, m_span_pool); + if (res != nullptr) + return res; + } + + // otherwise the shelf is too tall, track best one + int score = shelf_h - h; + if (score < best_score && shelf.has_space_for(w)) { + best_score = score; + best_shelf = &shelf; + } + } + + if (best_shelf) { + smol_atlas_item_t* res = best_shelf->alloc_item(w, h, m_item_pool, m_span_pool); + if (res != nullptr) + return res; + } + + // no shelf with enough space: add a new shelf + if (w <= m_width && h <= m_height - top_y) { + int shelf_index = int(m_shelves.size()); + m_shelves.emplace_back(top_y, m_width, h, shelf_index, m_span_pool); + return m_shelves.back().alloc_item(w, h, m_item_pool, m_span_pool); + } + + // out of space + return nullptr; + } + + void free_item(smol_atlas_item_t* item) + { + if (item == nullptr) + return; + assert(item->shelf_index >= 0 && item->shelf_index < m_shelves.size()); + m_shelves[item->shelf_index].free_item(item, m_item_pool, m_span_pool); + } + + void clear() + { + m_item_pool.clear(); + m_span_pool.clear(); + m_shelves.clear(); + } + + smol_pool_t m_item_pool; + smol_pool_t m_span_pool; + std::vector m_shelves; + int m_width; + int m_height; +}; + +smol_atlas_t* sma_atlas_create(int width, int height) +{ + return new smol_atlas_t(width, height); +} + +void sma_atlas_destroy(smol_atlas_t* atlas) +{ + delete atlas; +} + +int sma_atlas_width(const smol_atlas_t* atlas) +{ + return atlas->m_width; +} + +int sma_atlas_height(const smol_atlas_t* atlas) +{ + return atlas->m_height; +} + +smol_atlas_item_t* sma_item_add(smol_atlas_t* atlas, int width, int height) +{ + return atlas->pack(width, height); +} + +void sma_item_remove(smol_atlas_t* atlas, smol_atlas_item_t* item) +{ + atlas->free_item(item); +} + +void sma_atlas_clear(smol_atlas_t* atlas, int new_width, int new_height) +{ + atlas->clear(); + if (new_width > 0) atlas->m_width = new_width; + if (new_height > 0) atlas->m_height = new_height; +} + +int sma_item_x(const smol_atlas_item_t* item) +{ + return item->x; +} +int sma_item_y(const smol_atlas_item_t* item) +{ + return item->y; +} +int sma_item_width(const smol_atlas_item_t* item) +{ + return item->width; +} +int sma_item_height(const smol_atlas_item_t* item) +{ + return item->height; +} diff --git a/src/smol-atlas.h b/src/smol-atlas.h new file mode 100644 index 0000000..e8cc793 --- /dev/null +++ b/src/smol-atlas.h @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: MIT OR Unlicense +// smol-atlas: https://github.com/aras-p/smol-atlas + +#pragma once + +// 2D rectangular bin packing utility that uses the Shelf Best Height Fit +// heuristic, and supports item removal. You could also call it a +// dynamic texture atlas allocator. +// +// The shelf packing algorithm works well when there is a high number of items +// with similar sizes, for example dynamic glyph or thumbnail atlases. +// +// - Incoming items are placed into horizontal "shelves" based on item heights. +// - Within each shelf, there is a sorted list of free spans. +// - When an item is added, needed portion of the first suitable free span +// is used. +// - When an item is removed, resulting free span is joined with any +// neighboring spans. +// - Shelves, once created, stay at their height and location. Even if they +// become empty, they are not removed nor joined with nearby shelves. +// +// Implementation uses STL , and some manual memory allocation +// with just regular `new` and `delete`. Custom allocators might be nice to +// do someday. +// +// At least C++11 is required. + +struct smol_atlas_t; +struct smol_atlas_item_t; + +/// Create atlas of given size. +smol_atlas_t* sma_atlas_create(int width, int height); + +/// Destroy the atlas. +void sma_atlas_destroy(smol_atlas_t* atlas); + +/// Get atlas width. +int sma_atlas_width(const smol_atlas_t* atlas); + +/// Get atlas height. +int sma_atlas_height(const smol_atlas_t* atlas); + +/// Add an item of (width x height) size into the atlas. +/// Use `sma_item_x` and `sma_item_y` to query the resulting item location. +/// Item can later be removed with `sma_item_remove`. +/// Returned pointer is valid until atlas is cleared or destroyed, or the item is removed. +/// Returns NULL if there is no more space left. +smol_atlas_item_t* sma_item_add(smol_atlas_t* atlas, int width, int height); + +/// Remove a previously added item from the atlas. +/// The item pointer becomes invalid and can no longer be used. +void sma_item_remove(smol_atlas_t* atlas, smol_atlas_item_t* item); + +/// Clear the atlas. This invalidates any previously returned item pointers. +/// If passed width and height are positive, the atlas size is also set +/// to the new values. +void sma_atlas_clear(smol_atlas_t* atlas, int new_width = 0, int new_height = 0); + +/// Get item X coordinate. +int sma_item_x(const smol_atlas_item_t* item); +/// Get item Y coordinate. +int sma_item_y(const smol_atlas_item_t* item); +/// Get item width. +int sma_item_width(const smol_atlas_item_t* item); +/// Get item height. +int sma_item_height(const smol_atlas_item_t* item);