You've already forked flecs_tests
Compare commits
12 Commits
21476a3b95
...
rework
| Author | SHA1 | Date | |
|---|---|---|---|
| af0a39166c | |||
| 8ea6a0bf3e | |||
| dc708de354 | |||
| beea8a0281 | |||
| 936043340c | |||
| 9789e449c3 | |||
| 7e3da1c424 | |||
| c4d657043c | |||
| e71641c094 | |||
| 9ce6e4accd | |||
| 81616f8a5d | |||
| 5881a7dafc |
34
CLAUDE.md
34
CLAUDE.md
@@ -1,5 +1,39 @@
|
||||
# CLAUDE.md
|
||||
|
||||
## Project: Cartograph
|
||||
|
||||
A browser-based world map creation tool (like Wonderdraft/Inkarnate). C99 compiled to WebAssembly via Emscripten.
|
||||
|
||||
### Stack
|
||||
- **Graphics:** Sokol (WebGPU backend, `SOKOL_WGPU`) — `lib/sokol/`
|
||||
- **UI:** Dear ImGui via cimgui — `lib/imgui/`
|
||||
- **Math:** cglm (types are C arrays: `vec2` = `float[2]`, `mat4` = `float[4][4]` column-major) — `lib/cglm/`
|
||||
- **Shaders:** WGSL in `src/shaders/`, compiled to C headers via `xxd -i` into `src/generated/`
|
||||
- **Shapes:** Line-strip based vector shapes (circle, star) with procedural vertex generation
|
||||
|
||||
### Build
|
||||
- `make` (release) / `make debug` — outputs `app.html`
|
||||
- All includes go through `src/api.h` which defines `SOKOL_IMPL`, `SOKOL_WGPU`, and pulls in every library header
|
||||
- Include paths: `lib/sokol`, `lib/imgui`, `lib/imgui/imgui`, `lib/util`, `lib/cglm/include`
|
||||
|
||||
### Key files
|
||||
- `src/main.c` — entry point, sokol init, render loop, all input handling, overlay geometry, UI panels, and debug stats
|
||||
- `src/api.h` — central include hub, backend defines, ALLOC/FREE macros (wired to smemtrack)
|
||||
- `src/camera.h` — viewport state (zoom/pan), MVP matrix computation, screen↔world coordinate transforms
|
||||
- `src/render.h` — shape pipeline init/shutdown, per-shape draw calls (shader uniform binding)
|
||||
- `src/shape.h` — shape geometry types, procedural generation (circle/star), transform building, hit testing, buffer management
|
||||
- `src/spatial.h` — spatial hash grid for accelerating hit tests and rect-selection queries
|
||||
- `src/history.h` — undo/redo stack with property-level tracking (position/scale/rotation/color), edit session capture, batch operations
|
||||
- `src/util.h` — `vector_t` (dynamic array) and `mem_pool_t` (free-list pool), both stripe-based
|
||||
- `src/rand.h` — xorshift32 PRNG
|
||||
|
||||
### Conventions
|
||||
- No malloc/free directly — use `ALLOC`/`FREE` macros (wired to smemtrack in main.c)
|
||||
- Assert is encouraged for invariant checks
|
||||
- Data structures use stripe-based allocation (byte stride per element, not sizeof)
|
||||
|
||||
---
|
||||
|
||||
**Tradeoff:** These guidelines bias toward caution over speed. For trivial tasks, use judgment.
|
||||
|
||||
## 1. Think Before Coding
|
||||
|
||||
22
README.md
Normal file
22
README.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# Cartograph
|
||||
|
||||
A browser-based world map creation tool inspired by Wonderdraft and Inkarnate. Uses a hierarchical tile-based SDF rendering.
|
||||
|
||||
## Build
|
||||
|
||||
```sh
|
||||
# Install dependencies
|
||||
./fetch_libs.sh
|
||||
|
||||
# Release build
|
||||
make
|
||||
|
||||
# Debug build
|
||||
make debug
|
||||
```
|
||||
|
||||
Output is `app.html`, served by Emscripten's built-in web server or any static server.
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
@@ -5,11 +5,12 @@ LIB_DIR="lib"
|
||||
|
||||
echo "=== Fetching library dependencies ==="
|
||||
|
||||
# 1. Sokol (single-file headers)
|
||||
mkdir -p "$LIB_DIR/sokol"
|
||||
mkdir -p "$LIB_DIR/imgui"
|
||||
mkdir -p "$LIB_DIR/util"
|
||||
mkdir -p "$LIB_DIR/cglm"
|
||||
|
||||
# 1. Sokol (single-file headers)
|
||||
if [ ! -f "$LIB_DIR/sokol/sokol_gfx.h" ]; then
|
||||
echo " > Fetching sokol (pinned to emdawnwebgpu-compatible version)..."
|
||||
git clone --depth 500 https://github.com/floooh/sokol.git "$LIB_DIR/sokol_tmp"
|
||||
@@ -47,4 +48,25 @@ else
|
||||
echo " > cimgui already present"
|
||||
fi
|
||||
|
||||
# 4. cglm
|
||||
if [ ! -f "$LIB_DIR/cglm/include/cglm/cglm.h" ]; then
|
||||
echo " > Fetching cglm..."
|
||||
git clone --depth 1 --branch v0.9.6 https://github.com/recp/cglm.git "$LIB_DIR/cglm_tmp"
|
||||
cp -r "$LIB_DIR/cglm_tmp/include" "$LIB_DIR/cglm/"
|
||||
cp -r "$LIB_DIR/cglm_tmp/src" "$LIB_DIR/cglm/"
|
||||
rm -rf "$LIB_DIR/cglm_tmp"
|
||||
else
|
||||
echo " > cglm already present"
|
||||
fi
|
||||
|
||||
# 5. stb_ds.h
|
||||
if [ ! -f "$LIB_DIR/util/stb_ds.h" ]; then
|
||||
echo " > Fetching STB..."
|
||||
git clone --depth 1 https://github.com/nothings/stb.git "$LIB_DIR/stb_tmp"
|
||||
cp -r "$LIB_DIR/stb_tmp/stb_ds.h" "$LIB_DIR/util/stb_ds.h"
|
||||
rm -rf "$LIB_DIR/stb_tmp"
|
||||
else
|
||||
echo " > stb_ds.h already present"
|
||||
fi
|
||||
|
||||
echo "=== Done ==="
|
||||
|
||||
19
makefile
19
makefile
@@ -19,6 +19,7 @@ IMGUI_SOURCES = $(LIB_DIR)/imgui/imgui/imgui.cpp \
|
||||
$(LIB_DIR)/imgui/imgui/imgui_tables.cpp \
|
||||
$(LIB_DIR)/imgui/imgui/imgui_widgets.cpp \
|
||||
$(LIB_DIR)/imgui/cimgui.cpp
|
||||
CGLM_SOURCES = $(wildcard $(LIB_DIR)/cglm/src/*.c)
|
||||
|
||||
# Dynamic shader processing
|
||||
SHADER_FILES = $(wildcard $(SHADER_DIR)/*.wgsl)
|
||||
@@ -29,7 +30,9 @@ EMCC_FLAGS = --use-port=emdawnwebgpu \
|
||||
-sWASM_BIGINT \
|
||||
-sALLOW_MEMORY_GROWTH \
|
||||
-msimd128 \
|
||||
-sFILESYSTEM=0
|
||||
-sFILESYSTEM=0 \
|
||||
-sMALLOC=emmalloc \
|
||||
-flto
|
||||
|
||||
# Shell template
|
||||
SHELL_FILE = shell.html
|
||||
@@ -38,15 +41,17 @@ SHELL_FILE = shell.html
|
||||
all: $(FETCH) $(TARGET)
|
||||
|
||||
# Main build target
|
||||
$(TARGET): $(SHADER_HEADERS) $(C_SOURCES) $(IMGUI_SOURCES) $(SHELL_FILE)
|
||||
$(CC) $(C_SOURCES) $(IMGUI_SOURCES) \
|
||||
$(TARGET): $(SHADER_HEADERS) $(C_SOURCES) $(IMGUI_SOURCES) $(CGLM_SOURCES) $(SHELL_FILE)
|
||||
$(CC) $(C_SOURCES) $(IMGUI_SOURCES) $(CGLM_SOURCES) \
|
||||
-o $(TARGET) \
|
||||
$(EMCC_FLAGS) \
|
||||
-O3 \
|
||||
--closure 1 \
|
||||
-I$(LIB_DIR)/sokol \
|
||||
-I$(LIB_DIR)/imgui \
|
||||
-I$(LIB_DIR)/imgui/imgui \
|
||||
-I$(LIB_DIR)/util \
|
||||
-I$(LIB_DIR)/cglm/include \
|
||||
--shell-file=$(SHELL_FILE)
|
||||
|
||||
# Shader header generation
|
||||
@@ -58,15 +63,17 @@ $(GENERATED_DIR)/%.h: $(SHADER_DIR)/%.wgsl | $(GENERATED_DIR)
|
||||
$(GENERATED_DIR):
|
||||
mkdir -p $(GENERATED_DIR)
|
||||
|
||||
debug: $(FETCH) $(SHADER_HEADERS) $(C_SOURCES) $(IMGUI_SOURCES) $(SHELL_FILE)
|
||||
$(CC) $(C_SOURCES) $(IMGUI_SOURCES) \
|
||||
debug: $(FETCH) $(SHADER_HEADERS) $(C_SOURCES) $(IMGUI_SOURCES) $(CGLM_SOURCES) $(SHELL_FILE)
|
||||
$(CC) $(C_SOURCES) $(IMGUI_SOURCES) $(CGLM_SOURCES) \
|
||||
-o $(TARGET) \
|
||||
$(EMCC_FLAGS) \
|
||||
-g -gsource-map=inline \
|
||||
-g3 --profiling-funcs -gsource-map \
|
||||
-sASSERTIONS \
|
||||
-I$(LIB_DIR)/sokol \
|
||||
-I$(LIB_DIR)/imgui \
|
||||
-I$(LIB_DIR)/imgui/imgui \
|
||||
-I$(LIB_DIR)/util \
|
||||
-I$(LIB_DIR)/cglm/include \
|
||||
--shell-file=$(SHELL_FILE)
|
||||
|
||||
# Clean build artifacts
|
||||
|
||||
71
src/api.h
71
src/api.h
@@ -1,30 +1,59 @@
|
||||
#ifndef API_DEFINITION
|
||||
#define API_DEFINITION
|
||||
|
||||
#define CIMGUI_DEFINE_ENUMS_AND_STRUCTS
|
||||
|
||||
#define SOKOL_IMPL
|
||||
#define SOKOL_WGPU
|
||||
#define SOKOL_IMGUI_IMPL
|
||||
|
||||
#include "sokol_gfx.h"
|
||||
#include "sokol_app.h"
|
||||
#include "sokol_glue.h"
|
||||
#include "sokol_log.h"
|
||||
#include "cimgui.h"
|
||||
#include "sokol_imgui.h"
|
||||
#include "sokol_memtrack.h"
|
||||
|
||||
#include "math.h"
|
||||
#include "rand.h"
|
||||
#include "util.h"
|
||||
#include "sprite.h"
|
||||
|
||||
#include "generated/sprite.h"
|
||||
|
||||
#include <emscripten.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <emscripten/emmalloc.h>
|
||||
|
||||
#define CIMGUI_DEFINE_ENUMS_AND_STRUCTS
|
||||
|
||||
static void log_fn(const char* tag, uint32_t log_level, uint32_t log_item_id, const char* message_or_null, uint32_t line_nr, const char* filename_or_null, void* user_data)
|
||||
{
|
||||
fprintf(stderr, "[%s - %s]: (%d) %s \tat %s:%d\r\n", tag, log_level == 0 ? "FATAL" : log_level == 1 ? "ERROR" : log_level == 2 ? "WARNING" : "INFO", log_item_id, message_or_null, filename_or_null, line_nr);
|
||||
}
|
||||
|
||||
#define SOKOL_ASSERT(x) ((void)((x) || (log_fn("ASSERT", 1, 1, "Assertion failed", __LINE__, __FILE__, NULL),0)))
|
||||
|
||||
#define SOKOL_IMPL
|
||||
#define SOKOL_WGPU
|
||||
#define SOKOL_IMGUI_IMPL
|
||||
|
||||
#define STB_DS_IMPLEMENTATION
|
||||
#define STBDS_NO_SHORT_NAMES
|
||||
|
||||
#define STBDS_REALLOC(context,ptr,size) emmalloc_realloc(ptr, size)
|
||||
#define STBDS_FREE(context,ptr) emmalloc_free(ptr)
|
||||
|
||||
#define COMPUTE_VIEWIDX_segments 0
|
||||
#define COMPUTE_VIEWIDX_shapes 1
|
||||
#define COMPUTE_VIEWIDX_circles 2
|
||||
#define COMPUTE_VIEWIDX_tiles 3
|
||||
#define COMPUTE_VIEWIDX_indices 4
|
||||
#define COMPUTE_VIEWIDX_SDF 5
|
||||
|
||||
#define DISPLAY_VIEWIDX_SDF 0
|
||||
#define DISPLAY_VIEWIDX_Sampler 1
|
||||
|
||||
static float clampf(float x, float a, float b)
|
||||
{
|
||||
return x < a ? a : (x > b ? b : x);
|
||||
}
|
||||
|
||||
#include "sokol_gfx.h"
|
||||
#include "sokol_app.h"
|
||||
#include "sokol_glue.h"
|
||||
#include "cimgui.h"
|
||||
#include "sokol_imgui.h"
|
||||
#include "stb_ds.h"
|
||||
|
||||
#include "shape.h"
|
||||
//#include "cache.h"
|
||||
#include "pool.h"
|
||||
#include "generated/compute.h"
|
||||
#include "generated/display.h"
|
||||
|
||||
#endif
|
||||
107
src/cache.h
Normal file
107
src/cache.h
Normal file
@@ -0,0 +1,107 @@
|
||||
#include "api.h"
|
||||
|
||||
tile_slot_t* cache_evict(scene_t* s)
|
||||
{
|
||||
tile_slot_t* best = NULL;
|
||||
uint64_t oldest = UINT64_MAX;
|
||||
|
||||
for(uint32_t i = 0; i < TILE_LAYERS; i++)
|
||||
{
|
||||
tile_slot_t* slot = &s->cache.slots[i];
|
||||
if(slot->key.lod == UINT32_MAX) continue; // LOD == UINT32_MAX means the slot is free.
|
||||
|
||||
//Found a better candidate
|
||||
if(slot->last_used < oldest)
|
||||
{
|
||||
oldest = slot->last_used;
|
||||
best = slot;
|
||||
}
|
||||
}
|
||||
|
||||
if(best == NULL)
|
||||
return best;
|
||||
|
||||
stbds_hmdel(s->cache.map, best->key);
|
||||
|
||||
s->cache.free_layers[s->cache.free_count] = best->layer;
|
||||
s->cache.free_count++;
|
||||
s->cache.slots[best->layer].key.lod = UINT32_MAX; //Mark the slot as free for the evict scan using lod == UINT32_MAX
|
||||
|
||||
return best;
|
||||
}
|
||||
uint32_t cache_allocate(scene_t* s)
|
||||
{
|
||||
assert(s->cache.free_count > 0);
|
||||
s->cache.free_count--;
|
||||
uint32_t layer = s->cache.free_layers[s->cache.free_count];
|
||||
|
||||
return layer;
|
||||
}
|
||||
tile_slot_t* cache_search(scene_t* s, tile_key_t* key, uint64_t frame_count)
|
||||
{
|
||||
uint32_t index = stbds_hmgeti(s->cache.map, *key);
|
||||
|
||||
if(index >= 0)
|
||||
{
|
||||
uint32_t layer = s->cache.map[index].value;
|
||||
tile_slot_t* slot = &s->cache.slots[layer];
|
||||
slot->last_used = frame_count;
|
||||
return slot;
|
||||
}
|
||||
|
||||
// Evict the least recently used (LRU) slot
|
||||
if(stbds_hmlen(s->cache.map) >= TILE_LAYERS)
|
||||
{
|
||||
tile_slot_t* evict = cache_evict(s);
|
||||
}
|
||||
|
||||
// Allocate a free layer
|
||||
uint32_t layer = cache_allocate(s);
|
||||
tile_slot_t* slot = &s->cache.slots[layer];
|
||||
slot->key.lod = key->lod; slot->key.tx = key->tx; slot->key.ty = key->ty;
|
||||
slot->layer = layer;
|
||||
slot->state = TILE_STATE_DIRTY;
|
||||
slot->last_used = frame_count;
|
||||
|
||||
stbds_hmput(s->cache.map, *key, layer);
|
||||
return slot;
|
||||
}
|
||||
// Works in 3 steps, first we select every required tiles and store the mising one from the cache
|
||||
// Then we evict the LRU cache until we have enough space for the missing tiles
|
||||
// Finally we allocate the missing tiles
|
||||
static int cache_query(scene_t* s, uint32_t lod, box_t* box, tile_key_t** buffer)
|
||||
{
|
||||
uint64_t frame = sapp_frame_count();
|
||||
tile_key_t tile_key = { lod, 0, 0 };
|
||||
|
||||
for(uint32_t ty = box->min_y; ty < box->max_y; ty++)
|
||||
{
|
||||
tile_key.ty = ty;
|
||||
for(uint32_t tx = box->min_x; tx < box->max_x; tx++)
|
||||
{
|
||||
tile_key.tx = tx;
|
||||
stbds_hmget(s->cache.map, tile_key);
|
||||
}
|
||||
}
|
||||
}
|
||||
static int cache_cull(scene_t* s, uint32_t tile_count)
|
||||
{
|
||||
uint32_t count = 0;
|
||||
for(uint32_t i = 0; i < tile_count; i++)
|
||||
{
|
||||
tile_slot_t slot = s->cache.slots[i];
|
||||
tile_task_t* tile = &s->cache.tiles[i];
|
||||
tile->bounds.min_x = slot.key.tx * s->LODs[slot.key.lod].texel_size;
|
||||
tile->bounds.min_y = slot.key.ty * s->LODs[slot.key.lod].texel_size;
|
||||
tile->bounds.max_x = (slot.key.tx + 1) * s->LODs[slot.key.lod].texel_size;
|
||||
tile->bounds.max_y = (slot.key.ty + 1) * s->LODs[slot.key.lod].texel_size;
|
||||
tile->layer = slot.layer;
|
||||
|
||||
uint32_t start = count;
|
||||
for(uint32_t j = 0; j < s->num_shapes; j++)
|
||||
{
|
||||
if(BOX_INTERSECTS(tile->bounds, s->shapes[j].aabb)) s->cache.indices[count++] = j;
|
||||
}
|
||||
tile->offset = start; tile->count = count - start;
|
||||
}
|
||||
}
|
||||
686
src/generated/compute.h
Normal file
686
src/generated/compute.h
Normal file
@@ -0,0 +1,686 @@
|
||||
unsigned char src_shaders_compute_wgsl[] = {
|
||||
0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x53, 0x65, 0x67, 0x6d, 0x65,
|
||||
0x6e, 0x74, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x70, 0x30,
|
||||
0x3a, 0x20, 0x76, 0x65, 0x63, 0x32, 0x66, 0x2c, 0x0d, 0x0a, 0x20, 0x20,
|
||||
0x20, 0x20, 0x70, 0x31, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x32, 0x66, 0x2c,
|
||||
0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x70, 0x32, 0x3a, 0x20, 0x76, 0x65,
|
||||
0x63, 0x32, 0x66, 0x2c, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x70, 0x33,
|
||||
0x3a, 0x20, 0x76, 0x65, 0x63, 0x32, 0x66, 0x2c, 0x0d, 0x0a, 0x7d, 0x0d,
|
||||
0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x53, 0x68, 0x61, 0x70,
|
||||
0x65, 0x4d, 0x65, 0x74, 0x61, 0x20, 0x7b, 0x20, 0x0d, 0x0a, 0x20, 0x20,
|
||||
0x20, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x73, 0x65, 0x67, 0x6d,
|
||||
0x65, 0x6e, 0x74, 0x3a, 0x20, 0x75, 0x33, 0x32, 0x2c, 0x20, 0x2f, 0x2f,
|
||||
0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68,
|
||||
0x65, 0x20, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x62,
|
||||
0x75, 0x66, 0x66, 0x65, 0x72, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73,
|
||||
0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74,
|
||||
0x3a, 0x20, 0x75, 0x33, 0x32, 0x2c, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
|
||||
0x62, 0x62, 0x6f, 0x78, 0x5f, 0x6d, 0x69, 0x6e, 0x3a, 0x20, 0x76, 0x65,
|
||||
0x63, 0x32, 0x66, 0x2c, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x62, 0x62,
|
||||
0x6f, 0x78, 0x5f, 0x6d, 0x61, 0x78, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x32,
|
||||
0x66, 0x2c, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63,
|
||||
0x74, 0x20, 0x43, 0x69, 0x72, 0x63, 0x6c, 0x65, 0x20, 0x7b, 0x0d, 0x0a,
|
||||
0x20, 0x20, 0x20, 0x20, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3a, 0x20,
|
||||
0x76, 0x65, 0x63, 0x32, 0x66, 0x2c, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
|
||||
0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3a, 0x20, 0x66, 0x33, 0x32, 0x2c,
|
||||
0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20,
|
||||
0x54, 0x69, 0x6c, 0x65, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
|
||||
0x77, 0x6f, 0x72, 0x6c, 0x64, 0x5f, 0x6d, 0x69, 0x6e, 0x3a, 0x20, 0x76,
|
||||
0x65, 0x63, 0x32, 0x66, 0x2c, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x77,
|
||||
0x6f, 0x72, 0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x78, 0x3a, 0x20, 0x76, 0x65,
|
||||
0x63, 0x32, 0x66, 0x2c, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x66,
|
||||
0x66, 0x73, 0x65, 0x74, 0x3a, 0x20, 0x75, 0x33, 0x32, 0x2c, 0x0d, 0x0a,
|
||||
0x20, 0x20, 0x20, 0x20, 0x63, 0x69, 0x72, 0x63, 0x6c, 0x65, 0x5f, 0x63,
|
||||
0x6f, 0x75, 0x6e, 0x74, 0x3a, 0x20, 0x75, 0x33, 0x32, 0x2c, 0x0d, 0x0a,
|
||||
0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x3a, 0x20, 0x75,
|
||||
0x33, 0x32, 0x2c, 0x0d, 0x0a, 0x7d, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x40,
|
||||
0x67, 0x72, 0x6f, 0x75, 0x70, 0x28, 0x31, 0x29, 0x20, 0x40, 0x62, 0x69,
|
||||
0x6e, 0x64, 0x69, 0x6e, 0x67, 0x28, 0x30, 0x29, 0x20, 0x76, 0x61, 0x72,
|
||||
0x3c, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x3e, 0x20, 0x73, 0x65,
|
||||
0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x3a, 0x20, 0x61, 0x72, 0x72, 0x61,
|
||||
0x79, 0x3c, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x3e, 0x3b, 0x0d,
|
||||
0x0a, 0x40, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x28, 0x31, 0x29, 0x20, 0x40,
|
||||
0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x28, 0x31, 0x29, 0x20, 0x76,
|
||||
0x61, 0x72, 0x3c, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x3e, 0x20,
|
||||
0x73, 0x68, 0x61, 0x70, 0x65, 0x73, 0x3a, 0x20, 0x61, 0x72, 0x72, 0x61,
|
||||
0x79, 0x3c, 0x53, 0x68, 0x61, 0x70, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x3e,
|
||||
0x3b, 0x0d, 0x0a, 0x40, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x28, 0x31, 0x29,
|
||||
0x20, 0x40, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x28, 0x32, 0x29,
|
||||
0x20, 0x76, 0x61, 0x72, 0x3c, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65,
|
||||
0x3e, 0x20, 0x63, 0x69, 0x72, 0x63, 0x6c, 0x65, 0x73, 0x3a, 0x20, 0x61,
|
||||
0x72, 0x72, 0x61, 0x79, 0x3c, 0x43, 0x69, 0x72, 0x63, 0x6c, 0x65, 0x3e,
|
||||
0x3b, 0x0d, 0x0a, 0x40, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x28, 0x31, 0x29,
|
||||
0x20, 0x40, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x28, 0x33, 0x29,
|
||||
0x20, 0x76, 0x61, 0x72, 0x3c, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65,
|
||||
0x3e, 0x20, 0x74, 0x69, 0x6c, 0x65, 0x73, 0x3a, 0x20, 0x61, 0x72, 0x72,
|
||||
0x61, 0x79, 0x3c, 0x54, 0x69, 0x6c, 0x65, 0x3e, 0x3b, 0x0d, 0x0a, 0x40,
|
||||
0x67, 0x72, 0x6f, 0x75, 0x70, 0x28, 0x31, 0x29, 0x20, 0x40, 0x62, 0x69,
|
||||
0x6e, 0x64, 0x69, 0x6e, 0x67, 0x28, 0x34, 0x29, 0x20, 0x76, 0x61, 0x72,
|
||||
0x3c, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x3e, 0x20, 0x69, 0x6e,
|
||||
0x64, 0x69, 0x63, 0x65, 0x73, 0x3a, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79,
|
||||
0x3c, 0x75, 0x33, 0x32, 0x3e, 0x3b, 0x0d, 0x0a, 0x40, 0x67, 0x72, 0x6f,
|
||||
0x75, 0x70, 0x28, 0x31, 0x29, 0x20, 0x40, 0x62, 0x69, 0x6e, 0x64, 0x69,
|
||||
0x6e, 0x67, 0x28, 0x35, 0x29, 0x20, 0x76, 0x61, 0x72, 0x20, 0x73, 0x64,
|
||||
0x66, 0x5f, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x3a, 0x20, 0x74, 0x65,
|
||||
0x78, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67,
|
||||
0x65, 0x5f, 0x32, 0x64, 0x3c, 0x72, 0x31, 0x36, 0x66, 0x6c, 0x6f, 0x61,
|
||||
0x74, 0x2c, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, 0x3e, 0x3b, 0x0d, 0x0a,
|
||||
0x0d, 0x0a, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x20, 0x54,
|
||||
0x49, 0x4c, 0x45, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x3a, 0x20, 0x75, 0x33,
|
||||
0x32, 0x20, 0x3d, 0x20, 0x32, 0x35, 0x36, 0x75, 0x3b, 0x0d, 0x0a, 0x0d,
|
||||
0x0a, 0x2f, 0x2f, 0x20, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
||||
0x2d, 0x2d, 0x20, 0x43, 0x75, 0x62, 0x69, 0x63, 0x20, 0x42, 0xc3, 0xa9,
|
||||
0x7a, 0x69, 0x65, 0x72, 0x20, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73,
|
||||
0x20, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0d,
|
||||
0x0a, 0x66, 0x6e, 0x20, 0x65, 0x76, 0x61, 0x6c, 0x5f, 0x63, 0x75, 0x62,
|
||||
0x69, 0x63, 0x28, 0x74, 0x3a, 0x20, 0x66, 0x33, 0x32, 0x2c, 0x20, 0x70,
|
||||
0x30, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x32, 0x66, 0x2c, 0x20, 0x70, 0x31,
|
||||
0x3a, 0x20, 0x76, 0x65, 0x63, 0x32, 0x66, 0x2c, 0x20, 0x70, 0x32, 0x3a,
|
||||
0x20, 0x76, 0x65, 0x63, 0x32, 0x66, 0x2c, 0x20, 0x70, 0x33, 0x3a, 0x20,
|
||||
0x76, 0x65, 0x63, 0x32, 0x66, 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x76, 0x65,
|
||||
0x63, 0x32, 0x66, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c,
|
||||
0x65, 0x74, 0x20, 0x6d, 0x74, 0x20, 0x3d, 0x20, 0x31, 0x2e, 0x30, 0x20,
|
||||
0x2d, 0x20, 0x74, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65,
|
||||
0x74, 0x20, 0x6d, 0x74, 0x32, 0x20, 0x3d, 0x20, 0x6d, 0x74, 0x20, 0x2a,
|
||||
0x20, 0x6d, 0x74, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65,
|
||||
0x74, 0x20, 0x74, 0x32, 0x20, 0x3d, 0x20, 0x74, 0x20, 0x2a, 0x20, 0x74,
|
||||
0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72,
|
||||
0x6e, 0x20, 0x6d, 0x74, 0x32, 0x20, 0x2a, 0x20, 0x6d, 0x74, 0x20, 0x2a,
|
||||
0x20, 0x70, 0x30, 0x20, 0x2b, 0x20, 0x33, 0x2e, 0x30, 0x20, 0x2a, 0x20,
|
||||
0x6d, 0x74, 0x32, 0x20, 0x2a, 0x20, 0x74, 0x20, 0x2a, 0x20, 0x70, 0x31,
|
||||
0x20, 0x2b, 0x20, 0x33, 0x2e, 0x30, 0x20, 0x2a, 0x20, 0x6d, 0x74, 0x20,
|
||||
0x2a, 0x20, 0x74, 0x32, 0x20, 0x2a, 0x20, 0x70, 0x32, 0x20, 0x2b, 0x20,
|
||||
0x74, 0x32, 0x20, 0x2a, 0x20, 0x74, 0x20, 0x2a, 0x20, 0x70, 0x33, 0x3b,
|
||||
0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x66, 0x6e, 0x20, 0x65, 0x76,
|
||||
0x61, 0x6c, 0x5f, 0x63, 0x75, 0x62, 0x69, 0x63, 0x5f, 0x64, 0x65, 0x72,
|
||||
0x69, 0x76, 0x61, 0x74, 0x69, 0x76, 0x65, 0x28, 0x74, 0x3a, 0x20, 0x66,
|
||||
0x33, 0x32, 0x2c, 0x20, 0x70, 0x30, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x32,
|
||||
0x66, 0x2c, 0x20, 0x70, 0x31, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x32, 0x66,
|
||||
0x2c, 0x20, 0x70, 0x32, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x32, 0x66, 0x2c,
|
||||
0x20, 0x70, 0x33, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x32, 0x66, 0x29, 0x20,
|
||||
0x2d, 0x3e, 0x20, 0x76, 0x65, 0x63, 0x32, 0x66, 0x20, 0x7b, 0x0d, 0x0a,
|
||||
0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x6d, 0x74, 0x20, 0x3d,
|
||||
0x20, 0x31, 0x2e, 0x30, 0x20, 0x2d, 0x20, 0x74, 0x3b, 0x0d, 0x0a, 0x20,
|
||||
0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x33, 0x2e,
|
||||
0x30, 0x20, 0x2a, 0x20, 0x6d, 0x74, 0x20, 0x2a, 0x20, 0x6d, 0x74, 0x20,
|
||||
0x2a, 0x20, 0x28, 0x70, 0x31, 0x20, 0x2d, 0x20, 0x70, 0x30, 0x29, 0x20,
|
||||
0x2b, 0x20, 0x36, 0x2e, 0x30, 0x20, 0x2a, 0x20, 0x6d, 0x74, 0x20, 0x2a,
|
||||
0x20, 0x74, 0x20, 0x2a, 0x20, 0x28, 0x70, 0x32, 0x20, 0x2d, 0x20, 0x70,
|
||||
0x31, 0x29, 0x20, 0x2b, 0x20, 0x33, 0x2e, 0x30, 0x20, 0x2a, 0x20, 0x74,
|
||||
0x20, 0x2a, 0x20, 0x74, 0x20, 0x2a, 0x20, 0x28, 0x70, 0x33, 0x20, 0x2d,
|
||||
0x20, 0x70, 0x32, 0x29, 0x3b, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a,
|
||||
0x2f, 0x2f, 0x20, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
||||
0x2d, 0x20, 0x44, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x74,
|
||||
0x6f, 0x20, 0x61, 0x20, 0x63, 0x75, 0x62, 0x69, 0x63, 0x20, 0x42, 0xc3,
|
||||
0xa9, 0x7a, 0x69, 0x65, 0x72, 0x20, 0x28, 0x73, 0x61, 0x6d, 0x70, 0x6c,
|
||||
0x69, 0x6e, 0x67, 0x20, 0x2b, 0x20, 0x4e, 0x65, 0x77, 0x74, 0x6f, 0x6e,
|
||||
0x20, 0x72, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x29,
|
||||
0x20, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0d,
|
||||
0x0a, 0x66, 0x6e, 0x20, 0x64, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65,
|
||||
0x5f, 0x74, 0x6f, 0x5f, 0x63, 0x75, 0x62, 0x69, 0x63, 0x28, 0x70, 0x3a,
|
||||
0x20, 0x76, 0x65, 0x63, 0x32, 0x66, 0x2c, 0x20, 0x73, 0x65, 0x67, 0x3a,
|
||||
0x20, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x29, 0x20, 0x2d, 0x3e,
|
||||
0x20, 0x66, 0x33, 0x32, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
|
||||
0x6c, 0x65, 0x74, 0x20, 0x70, 0x30, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x67,
|
||||
0x2e, 0x70, 0x30, 0x3b, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x70, 0x31, 0x20,
|
||||
0x3d, 0x20, 0x73, 0x65, 0x67, 0x2e, 0x70, 0x31, 0x3b, 0x20, 0x6c, 0x65,
|
||||
0x74, 0x20, 0x70, 0x32, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x67, 0x2e, 0x70,
|
||||
0x32, 0x3b, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x70, 0x33, 0x20, 0x3d, 0x20,
|
||||
0x73, 0x65, 0x67, 0x2e, 0x70, 0x33, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x20,
|
||||
0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72,
|
||||
0x6d, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x74,
|
||||
0x6f, 0x20, 0x66, 0x69, 0x6e, 0x64, 0x20, 0x61, 0x20, 0x67, 0x6f, 0x6f,
|
||||
0x64, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x74,
|
||||
0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x73, 0x61,
|
||||
0x6d, 0x70, 0x6c, 0x65, 0x73, 0x20, 0x3d, 0x20, 0x31, 0x36, 0x75, 0x3b,
|
||||
0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x62, 0x65,
|
||||
0x73, 0x74, 0x5f, 0x74, 0x20, 0x3d, 0x20, 0x30, 0x2e, 0x30, 0x3b, 0x0d,
|
||||
0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x62, 0x65, 0x73,
|
||||
0x74, 0x5f, 0x64, 0x69, 0x73, 0x74, 0x20, 0x3d, 0x20, 0x31, 0x65, 0x32,
|
||||
0x30, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6f, 0x72, 0x20,
|
||||
0x28, 0x76, 0x61, 0x72, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x30, 0x75, 0x3b,
|
||||
0x20, 0x69, 0x20, 0x3c, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73,
|
||||
0x3b, 0x20, 0x69, 0x2b, 0x2b, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x74, 0x20,
|
||||
0x3d, 0x20, 0x66, 0x33, 0x32, 0x28, 0x69, 0x29, 0x20, 0x2f, 0x20, 0x66,
|
||||
0x33, 0x32, 0x28, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x20, 0x2d,
|
||||
0x20, 0x31, 0x75, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x71, 0x20, 0x3d, 0x20, 0x65,
|
||||
0x76, 0x61, 0x6c, 0x5f, 0x63, 0x75, 0x62, 0x69, 0x63, 0x28, 0x74, 0x2c,
|
||||
0x20, 0x70, 0x30, 0x2c, 0x20, 0x70, 0x31, 0x2c, 0x20, 0x70, 0x32, 0x2c,
|
||||
0x20, 0x70, 0x33, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x64, 0x20, 0x3d, 0x20, 0x64,
|
||||
0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x28, 0x70, 0x2c, 0x20, 0x71,
|
||||
0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x69, 0x66, 0x20, 0x64, 0x20, 0x3c, 0x20, 0x62, 0x65, 0x73, 0x74, 0x5f,
|
||||
0x64, 0x69, 0x73, 0x74, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x65, 0x73, 0x74,
|
||||
0x5f, 0x64, 0x69, 0x73, 0x74, 0x20, 0x3d, 0x20, 0x64, 0x3b, 0x0d, 0x0a,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x62, 0x65, 0x73, 0x74, 0x5f, 0x74, 0x20, 0x3d, 0x20, 0x74, 0x3b, 0x0d,
|
||||
0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0d, 0x0a,
|
||||
0x20, 0x20, 0x20, 0x20, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20,
|
||||
0x20, 0x2f, 0x2f, 0x20, 0x4e, 0x65, 0x77, 0x74, 0x6f, 0x6e, 0x20, 0x72,
|
||||
0x65, 0x66, 0x69, 0x6e, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6f, 0x6e,
|
||||
0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x71, 0x75, 0x61, 0x72, 0x65, 0x64,
|
||||
0x20, 0x64, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x28, 0x6d,
|
||||
0x61, 0x78, 0x20, 0x34, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x73, 0x29, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61,
|
||||
0x72, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x61, 0x6d, 0x70, 0x28,
|
||||
0x62, 0x65, 0x73, 0x74, 0x5f, 0x74, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x2c,
|
||||
0x20, 0x31, 0x2e, 0x30, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
|
||||
0x66, 0x6f, 0x72, 0x20, 0x28, 0x76, 0x61, 0x72, 0x20, 0x69, 0x74, 0x65,
|
||||
0x72, 0x20, 0x3d, 0x20, 0x30, 0x75, 0x3b, 0x20, 0x69, 0x74, 0x65, 0x72,
|
||||
0x20, 0x3c, 0x20, 0x34, 0x75, 0x3b, 0x20, 0x69, 0x74, 0x65, 0x72, 0x2b,
|
||||
0x2b, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x42, 0x20, 0x3d, 0x20, 0x65, 0x76,
|
||||
0x61, 0x6c, 0x5f, 0x63, 0x75, 0x62, 0x69, 0x63, 0x28, 0x74, 0x2c, 0x20,
|
||||
0x70, 0x30, 0x2c, 0x20, 0x70, 0x31, 0x2c, 0x20, 0x70, 0x32, 0x2c, 0x20,
|
||||
0x70, 0x33, 0x29, 0x20, 0x2d, 0x20, 0x70, 0x3b, 0x0d, 0x0a, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x42, 0x70,
|
||||
0x20, 0x3d, 0x20, 0x65, 0x76, 0x61, 0x6c, 0x5f, 0x63, 0x75, 0x62, 0x69,
|
||||
0x63, 0x5f, 0x64, 0x65, 0x72, 0x69, 0x76, 0x61, 0x74, 0x69, 0x76, 0x65,
|
||||
0x28, 0x74, 0x2c, 0x20, 0x70, 0x30, 0x2c, 0x20, 0x70, 0x31, 0x2c, 0x20,
|
||||
0x70, 0x32, 0x2c, 0x20, 0x70, 0x33, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x66, 0x20,
|
||||
0x3d, 0x20, 0x64, 0x6f, 0x74, 0x28, 0x42, 0x2c, 0x20, 0x42, 0x70, 0x29,
|
||||
0x3b, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0xc2, 0xbd, 0x20, 0x64, 0x65,
|
||||
0x72, 0x69, 0x76, 0x61, 0x74, 0x69, 0x76, 0x65, 0x20, 0x6f, 0x66, 0x20,
|
||||
0x7c, 0x42, 0x7c, 0xc2, 0xb2, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x64, 0x66, 0x20, 0x3d, 0x20,
|
||||
0x64, 0x6f, 0x74, 0x28, 0x42, 0x70, 0x2c, 0x20, 0x42, 0x70, 0x29, 0x20,
|
||||
0x2b, 0x20, 0x64, 0x6f, 0x74, 0x28, 0x42, 0x2c, 0x20, 0x33, 0x2e, 0x30,
|
||||
0x20, 0x2a, 0x20, 0x28, 0x70, 0x32, 0x20, 0x2d, 0x20, 0x70, 0x31, 0x20,
|
||||
0x2b, 0x20, 0x28, 0x70, 0x33, 0x20, 0x2d, 0x20, 0x70, 0x32, 0x20, 0x2d,
|
||||
0x20, 0x70, 0x32, 0x20, 0x2b, 0x20, 0x70, 0x31, 0x29, 0x20, 0x2a, 0x20,
|
||||
0x32, 0x2e, 0x30, 0x20, 0x2a, 0x20, 0x74, 0x29, 0x29, 0x3b, 0x20, 0x2f,
|
||||
0x2f, 0x20, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64,
|
||||
0x20, 0x32, 0x6e, 0x64, 0x20, 0x64, 0x65, 0x72, 0x69, 0x76, 0x0d, 0x0a,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x61,
|
||||
0x62, 0x73, 0x28, 0x64, 0x66, 0x29, 0x20, 0x3c, 0x20, 0x31, 0x65, 0x2d,
|
||||
0x31, 0x32, 0x20, 0x7b, 0x20, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x20,
|
||||
0x7d, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c,
|
||||
0x65, 0x74, 0x20, 0x73, 0x74, 0x65, 0x70, 0x20, 0x3d, 0x20, 0x66, 0x20,
|
||||
0x2f, 0x20, 0x64, 0x66, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x61, 0x6d, 0x70,
|
||||
0x28, 0x74, 0x20, 0x2d, 0x20, 0x73, 0x74, 0x65, 0x70, 0x2c, 0x20, 0x30,
|
||||
0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x3b, 0x0d, 0x0a, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x61, 0x62,
|
||||
0x73, 0x28, 0x73, 0x74, 0x65, 0x70, 0x29, 0x20, 0x3c, 0x20, 0x31, 0x65,
|
||||
0x2d, 0x36, 0x20, 0x7b, 0x20, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x20,
|
||||
0x7d, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0d, 0x0a, 0x20, 0x20,
|
||||
0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x71, 0x5f, 0x66, 0x69, 0x6e, 0x61,
|
||||
0x6c, 0x20, 0x3d, 0x20, 0x65, 0x76, 0x61, 0x6c, 0x5f, 0x63, 0x75, 0x62,
|
||||
0x69, 0x63, 0x28, 0x74, 0x2c, 0x20, 0x70, 0x30, 0x2c, 0x20, 0x70, 0x31,
|
||||
0x2c, 0x20, 0x70, 0x32, 0x2c, 0x20, 0x70, 0x33, 0x29, 0x3b, 0x0d, 0x0a,
|
||||
0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x64,
|
||||
0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x28, 0x70, 0x2c, 0x20, 0x71,
|
||||
0x5f, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x29, 0x3b, 0x0d, 0x0a, 0x7d, 0x0d,
|
||||
0x0a, 0x0d, 0x0a, 0x2f, 0x2f, 0x20, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
||||
0x2d, 0x2d, 0x2d, 0x2d, 0x20, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x74, 0x69,
|
||||
0x63, 0x61, 0x6c, 0x20, 0x63, 0x75, 0x62, 0x69, 0x63, 0x20, 0x72, 0x6f,
|
||||
0x6f, 0x74, 0x20, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x20, 0x28, 0x66,
|
||||
0x6f, 0x72, 0x20, 0x79, 0x2d, 0x63, 0x72, 0x6f, 0x73, 0x73, 0x69, 0x6e,
|
||||
0x67, 0x29, 0x20, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
||||
0x2d, 0x0d, 0x0a, 0x2f, 0x2f, 0x20, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e,
|
||||
0x73, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20,
|
||||
0x72, 0x65, 0x61, 0x6c, 0x20, 0x72, 0x6f, 0x6f, 0x74, 0x73, 0x20, 0x69,
|
||||
0x6e, 0x20, 0x5b, 0x30, 0x2c, 0x31, 0x5d, 0x2c, 0x20, 0x73, 0x74, 0x6f,
|
||||
0x72, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x72, 0x6f, 0x6f, 0x74, 0x73,
|
||||
0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x28, 0x75, 0x70, 0x20, 0x74,
|
||||
0x6f, 0x20, 0x33, 0x29, 0x2e, 0x0d, 0x0a, 0x66, 0x6e, 0x20, 0x73, 0x6f,
|
||||
0x6c, 0x76, 0x65, 0x5f, 0x63, 0x75, 0x62, 0x69, 0x63, 0x5f, 0x69, 0x6e,
|
||||
0x5f, 0x30, 0x31, 0x28, 0x63, 0x33, 0x3a, 0x20, 0x66, 0x33, 0x32, 0x2c,
|
||||
0x20, 0x63, 0x32, 0x3a, 0x20, 0x66, 0x33, 0x32, 0x2c, 0x20, 0x63, 0x31,
|
||||
0x3a, 0x20, 0x66, 0x33, 0x32, 0x2c, 0x20, 0x63, 0x30, 0x3a, 0x20, 0x66,
|
||||
0x33, 0x32, 0x2c, 0x20, 0x72, 0x6f, 0x6f, 0x74, 0x73, 0x3a, 0x20, 0x70,
|
||||
0x74, 0x72, 0x3c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2c,
|
||||
0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3c, 0x66, 0x33, 0x32, 0x2c, 0x20,
|
||||
0x33, 0x3e, 0x3e, 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x75, 0x33, 0x32, 0x20,
|
||||
0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x4e, 0x6f,
|
||||
0x72, 0x6d, 0x61, 0x6c, 0x69, 0x73, 0x65, 0x3a, 0x20, 0x63, 0x33, 0x20,
|
||||
0x2a, 0x20, 0x74, 0x5e, 0x33, 0x20, 0x2b, 0x20, 0x63, 0x32, 0x20, 0x2a,
|
||||
0x20, 0x74, 0x5e, 0x32, 0x20, 0x2b, 0x20, 0x63, 0x31, 0x20, 0x2a, 0x20,
|
||||
0x74, 0x20, 0x2b, 0x20, 0x63, 0x30, 0x20, 0x3d, 0x20, 0x30, 0x0d, 0x0a,
|
||||
0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x61, 0x62, 0x73, 0x28, 0x63,
|
||||
0x33, 0x29, 0x20, 0x3c, 0x20, 0x31, 0x65, 0x2d, 0x39, 0x20, 0x7b, 0x0d,
|
||||
0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20,
|
||||
0x51, 0x75, 0x61, 0x64, 0x72, 0x61, 0x74, 0x69, 0x63, 0x20, 0x66, 0x61,
|
||||
0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x61, 0x62, 0x73, 0x28, 0x63,
|
||||
0x32, 0x29, 0x20, 0x3c, 0x20, 0x31, 0x65, 0x2d, 0x39, 0x20, 0x7b, 0x0d,
|
||||
0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x69, 0x66, 0x20, 0x61, 0x62, 0x73, 0x28, 0x63, 0x31, 0x29, 0x20,
|
||||
0x3c, 0x20, 0x31, 0x65, 0x2d, 0x39, 0x20, 0x7b, 0x20, 0x72, 0x65, 0x74,
|
||||
0x75, 0x72, 0x6e, 0x20, 0x30, 0x75, 0x3b, 0x20, 0x7d, 0x0d, 0x0a, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c,
|
||||
0x65, 0x74, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x2d, 0x63, 0x30, 0x20, 0x2f,
|
||||
0x20, 0x63, 0x31, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x74, 0x20, 0x3e,
|
||||
0x3d, 0x20, 0x30, 0x2e, 0x30, 0x20, 0x26, 0x26, 0x20, 0x74, 0x20, 0x3c,
|
||||
0x3d, 0x20, 0x31, 0x2e, 0x30, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x28, 0x2a, 0x72, 0x6f, 0x6f, 0x74, 0x73, 0x29, 0x5b, 0x30, 0x5d,
|
||||
0x20, 0x3d, 0x20, 0x74, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72,
|
||||
0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x31, 0x75, 0x3b, 0x0d, 0x0a, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d,
|
||||
0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x30, 0x75, 0x3b,
|
||||
0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0d,
|
||||
0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74,
|
||||
0x20, 0x64, 0x69, 0x73, 0x63, 0x20, 0x3d, 0x20, 0x63, 0x31, 0x20, 0x2a,
|
||||
0x20, 0x63, 0x31, 0x20, 0x2d, 0x20, 0x34, 0x2e, 0x30, 0x20, 0x2a, 0x20,
|
||||
0x63, 0x32, 0x20, 0x2a, 0x20, 0x63, 0x30, 0x3b, 0x0d, 0x0a, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x64, 0x69, 0x73,
|
||||
0x63, 0x20, 0x3c, 0x20, 0x30, 0x2e, 0x30, 0x20, 0x7b, 0x20, 0x72, 0x65,
|
||||
0x74, 0x75, 0x72, 0x6e, 0x20, 0x30, 0x75, 0x3b, 0x20, 0x7d, 0x0d, 0x0a,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20,
|
||||
0x73, 0x64, 0x20, 0x3d, 0x20, 0x73, 0x71, 0x72, 0x74, 0x28, 0x64, 0x69,
|
||||
0x73, 0x63, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x74, 0x30, 0x20, 0x3d, 0x20, 0x28,
|
||||
0x2d, 0x63, 0x31, 0x20, 0x2b, 0x20, 0x73, 0x64, 0x29, 0x20, 0x2f, 0x20,
|
||||
0x28, 0x32, 0x2e, 0x30, 0x20, 0x2a, 0x20, 0x63, 0x32, 0x29, 0x3b, 0x0d,
|
||||
0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74,
|
||||
0x20, 0x74, 0x31, 0x20, 0x3d, 0x20, 0x28, 0x2d, 0x63, 0x31, 0x20, 0x2d,
|
||||
0x20, 0x73, 0x64, 0x29, 0x20, 0x2f, 0x20, 0x28, 0x32, 0x2e, 0x30, 0x20,
|
||||
0x2a, 0x20, 0x63, 0x32, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x63, 0x6f, 0x75, 0x6e,
|
||||
0x74, 0x20, 0x3d, 0x20, 0x30, 0x75, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x74, 0x30, 0x20, 0x3e,
|
||||
0x3d, 0x20, 0x30, 0x2e, 0x30, 0x20, 0x26, 0x26, 0x20, 0x74, 0x30, 0x20,
|
||||
0x3c, 0x3d, 0x20, 0x31, 0x2e, 0x30, 0x20, 0x7b, 0x20, 0x28, 0x2a, 0x72,
|
||||
0x6f, 0x6f, 0x74, 0x73, 0x29, 0x5b, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5d,
|
||||
0x20, 0x3d, 0x20, 0x74, 0x30, 0x3b, 0x20, 0x63, 0x6f, 0x75, 0x6e, 0x74,
|
||||
0x2b, 0x2b, 0x3b, 0x20, 0x7d, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x74, 0x31, 0x20, 0x3e, 0x3d, 0x20,
|
||||
0x30, 0x2e, 0x30, 0x20, 0x26, 0x26, 0x20, 0x74, 0x31, 0x20, 0x3c, 0x3d,
|
||||
0x20, 0x31, 0x2e, 0x30, 0x20, 0x7b, 0x20, 0x28, 0x2a, 0x72, 0x6f, 0x6f,
|
||||
0x74, 0x73, 0x29, 0x5b, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5d, 0x20, 0x3d,
|
||||
0x20, 0x74, 0x31, 0x3b, 0x20, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2b, 0x2b,
|
||||
0x3b, 0x20, 0x7d, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x63, 0x6f, 0x75, 0x6e,
|
||||
0x74, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0d, 0x0a, 0x0d,
|
||||
0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x44, 0x65, 0x70, 0x72,
|
||||
0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x63, 0x75, 0x62, 0x69, 0x63, 0x3a,
|
||||
0x20, 0x6c, 0x65, 0x74, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x78, 0x20, 0x2d,
|
||||
0x20, 0x63, 0x32, 0x2f, 0x28, 0x33, 0x2a, 0x63, 0x33, 0x29, 0x0d, 0x0a,
|
||||
0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x61, 0x20, 0x3d, 0x20,
|
||||
0x63, 0x32, 0x20, 0x2f, 0x20, 0x63, 0x33, 0x3b, 0x0d, 0x0a, 0x20, 0x20,
|
||||
0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x62, 0x20, 0x3d, 0x20, 0x63, 0x31,
|
||||
0x20, 0x2f, 0x20, 0x63, 0x33, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
|
||||
0x6c, 0x65, 0x74, 0x20, 0x63, 0x20, 0x3d, 0x20, 0x63, 0x30, 0x20, 0x2f,
|
||||
0x20, 0x63, 0x33, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65,
|
||||
0x74, 0x20, 0x70, 0x20, 0x3d, 0x20, 0x62, 0x20, 0x2d, 0x20, 0x61, 0x20,
|
||||
0x2a, 0x20, 0x61, 0x20, 0x2f, 0x20, 0x33, 0x2e, 0x30, 0x3b, 0x0d, 0x0a,
|
||||
0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x71, 0x20, 0x3d, 0x20,
|
||||
0x32, 0x2e, 0x30, 0x20, 0x2a, 0x20, 0x61, 0x20, 0x2a, 0x20, 0x61, 0x20,
|
||||
0x2a, 0x20, 0x61, 0x20, 0x2f, 0x20, 0x32, 0x37, 0x2e, 0x30, 0x20, 0x2d,
|
||||
0x20, 0x61, 0x20, 0x2a, 0x20, 0x62, 0x20, 0x2f, 0x20, 0x33, 0x2e, 0x30,
|
||||
0x20, 0x2b, 0x20, 0x63, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c,
|
||||
0x65, 0x74, 0x20, 0x64, 0x69, 0x73, 0x63, 0x20, 0x3d, 0x20, 0x71, 0x20,
|
||||
0x2a, 0x20, 0x71, 0x20, 0x2f, 0x20, 0x34, 0x2e, 0x30, 0x20, 0x2b, 0x20,
|
||||
0x70, 0x20, 0x2a, 0x20, 0x70, 0x20, 0x2a, 0x20, 0x70, 0x20, 0x2f, 0x20,
|
||||
0x32, 0x37, 0x2e, 0x30, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20,
|
||||
0x20, 0x76, 0x61, 0x72, 0x20, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x3d,
|
||||
0x20, 0x30, 0x75, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65,
|
||||
0x74, 0x20, 0x73, 0x68, 0x69, 0x66, 0x74, 0x20, 0x3d, 0x20, 0x61, 0x20,
|
||||
0x2f, 0x20, 0x33, 0x2e, 0x30, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20,
|
||||
0x20, 0x20, 0x69, 0x66, 0x20, 0x64, 0x69, 0x73, 0x63, 0x20, 0x3e, 0x20,
|
||||
0x30, 0x2e, 0x30, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x73, 0x64, 0x20, 0x3d, 0x20,
|
||||
0x73, 0x71, 0x72, 0x74, 0x28, 0x64, 0x69, 0x73, 0x63, 0x29, 0x3b, 0x0d,
|
||||
0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74,
|
||||
0x20, 0x75, 0x20, 0x3d, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x28, 0x2d, 0x71,
|
||||
0x2f, 0x32, 0x2e, 0x30, 0x20, 0x2b, 0x20, 0x73, 0x64, 0x29, 0x20, 0x2a,
|
||||
0x20, 0x70, 0x6f, 0x77, 0x28, 0x61, 0x62, 0x73, 0x28, 0x2d, 0x71, 0x2f,
|
||||
0x32, 0x2e, 0x30, 0x20, 0x2b, 0x20, 0x73, 0x64, 0x29, 0x2c, 0x20, 0x31,
|
||||
0x2e, 0x30, 0x2f, 0x33, 0x2e, 0x30, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x76, 0x20,
|
||||
0x3d, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x28, 0x2d, 0x71, 0x2f, 0x32, 0x2e,
|
||||
0x30, 0x20, 0x2d, 0x20, 0x73, 0x64, 0x29, 0x20, 0x2a, 0x20, 0x70, 0x6f,
|
||||
0x77, 0x28, 0x61, 0x62, 0x73, 0x28, 0x2d, 0x71, 0x2f, 0x32, 0x2e, 0x30,
|
||||
0x20, 0x2d, 0x20, 0x73, 0x64, 0x29, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x2f,
|
||||
0x33, 0x2e, 0x30, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x78, 0x31, 0x20, 0x3d, 0x20,
|
||||
0x75, 0x20, 0x2b, 0x20, 0x76, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x74, 0x20, 0x3d, 0x20,
|
||||
0x78, 0x31, 0x20, 0x2d, 0x20, 0x73, 0x68, 0x69, 0x66, 0x74, 0x3b, 0x0d,
|
||||
0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20,
|
||||
0x74, 0x20, 0x3e, 0x3d, 0x20, 0x30, 0x2e, 0x30, 0x20, 0x26, 0x26, 0x20,
|
||||
0x74, 0x20, 0x3c, 0x3d, 0x20, 0x31, 0x2e, 0x30, 0x20, 0x7b, 0x20, 0x28,
|
||||
0x2a, 0x72, 0x6f, 0x6f, 0x74, 0x73, 0x29, 0x5b, 0x63, 0x6f, 0x75, 0x6e,
|
||||
0x74, 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x3b, 0x20, 0x63, 0x6f, 0x75, 0x6e,
|
||||
0x74, 0x2b, 0x2b, 0x3b, 0x20, 0x7d, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
|
||||
0x7d, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x20, 0x64, 0x69,
|
||||
0x73, 0x63, 0x20, 0x3d, 0x3d, 0x20, 0x30, 0x2e, 0x30, 0x20, 0x7b, 0x0d,
|
||||
0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74,
|
||||
0x20, 0x75, 0x20, 0x3d, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x28, 0x2d, 0x71,
|
||||
0x2f, 0x32, 0x2e, 0x30, 0x29, 0x20, 0x2a, 0x20, 0x70, 0x6f, 0x77, 0x28,
|
||||
0x61, 0x62, 0x73, 0x28, 0x2d, 0x71, 0x2f, 0x32, 0x2e, 0x30, 0x29, 0x2c,
|
||||
0x20, 0x31, 0x2e, 0x30, 0x2f, 0x33, 0x2e, 0x30, 0x29, 0x3b, 0x0d, 0x0a,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20,
|
||||
0x78, 0x31, 0x20, 0x3d, 0x20, 0x32, 0x2e, 0x30, 0x20, 0x2a, 0x20, 0x75,
|
||||
0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c,
|
||||
0x65, 0x74, 0x20, 0x78, 0x32, 0x20, 0x3d, 0x20, 0x2d, 0x75, 0x3b, 0x0d,
|
||||
0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74,
|
||||
0x20, 0x74, 0x31, 0x20, 0x3d, 0x20, 0x78, 0x31, 0x20, 0x2d, 0x20, 0x73,
|
||||
0x68, 0x69, 0x66, 0x74, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x74, 0x32, 0x20, 0x3d, 0x20,
|
||||
0x78, 0x32, 0x20, 0x2d, 0x20, 0x73, 0x68, 0x69, 0x66, 0x74, 0x3b, 0x0d,
|
||||
0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20,
|
||||
0x74, 0x31, 0x20, 0x3e, 0x3d, 0x20, 0x30, 0x2e, 0x30, 0x20, 0x26, 0x26,
|
||||
0x20, 0x74, 0x31, 0x20, 0x3c, 0x3d, 0x20, 0x31, 0x2e, 0x30, 0x20, 0x7b,
|
||||
0x20, 0x28, 0x2a, 0x72, 0x6f, 0x6f, 0x74, 0x73, 0x29, 0x5b, 0x63, 0x6f,
|
||||
0x75, 0x6e, 0x74, 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x31, 0x3b, 0x20, 0x63,
|
||||
0x6f, 0x75, 0x6e, 0x74, 0x2b, 0x2b, 0x3b, 0x20, 0x7d, 0x0d, 0x0a, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x74, 0x32,
|
||||
0x20, 0x3e, 0x3d, 0x20, 0x30, 0x2e, 0x30, 0x20, 0x26, 0x26, 0x20, 0x74,
|
||||
0x32, 0x20, 0x3c, 0x3d, 0x20, 0x31, 0x2e, 0x30, 0x20, 0x7b, 0x20, 0x28,
|
||||
0x2a, 0x72, 0x6f, 0x6f, 0x74, 0x73, 0x29, 0x5b, 0x63, 0x6f, 0x75, 0x6e,
|
||||
0x74, 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x32, 0x3b, 0x20, 0x63, 0x6f, 0x75,
|
||||
0x6e, 0x74, 0x2b, 0x2b, 0x3b, 0x20, 0x7d, 0x0d, 0x0a, 0x20, 0x20, 0x20,
|
||||
0x20, 0x7d, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0x0d, 0x0a, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x70,
|
||||
0x68, 0x69, 0x20, 0x3d, 0x20, 0x61, 0x63, 0x6f, 0x73, 0x28, 0x20, 0x2d,
|
||||
0x71, 0x20, 0x2f, 0x20, 0x28, 0x32, 0x2e, 0x30, 0x20, 0x2a, 0x20, 0x73,
|
||||
0x71, 0x72, 0x74, 0x28, 0x2d, 0x70, 0x2a, 0x70, 0x2a, 0x70, 0x2f, 0x32,
|
||||
0x37, 0x2e, 0x30, 0x29, 0x29, 0x20, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x72, 0x20,
|
||||
0x3d, 0x20, 0x32, 0x2e, 0x30, 0x20, 0x2a, 0x20, 0x73, 0x71, 0x72, 0x74,
|
||||
0x28, 0x2d, 0x70, 0x2f, 0x33, 0x2e, 0x30, 0x29, 0x3b, 0x0d, 0x0a, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x28,
|
||||
0x76, 0x61, 0x72, 0x20, 0x6b, 0x20, 0x3d, 0x20, 0x30, 0x75, 0x3b, 0x20,
|
||||
0x6b, 0x20, 0x3c, 0x20, 0x33, 0x75, 0x3b, 0x20, 0x6b, 0x2b, 0x2b, 0x29,
|
||||
0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x78, 0x20, 0x3d, 0x20,
|
||||
0x72, 0x20, 0x2a, 0x20, 0x63, 0x6f, 0x73, 0x28, 0x28, 0x70, 0x68, 0x69,
|
||||
0x20, 0x2b, 0x20, 0x32, 0x2e, 0x30, 0x20, 0x2a, 0x20, 0x33, 0x2e, 0x31,
|
||||
0x34, 0x31, 0x35, 0x39, 0x32, 0x36, 0x35, 0x33, 0x35, 0x20, 0x2a, 0x20,
|
||||
0x66, 0x33, 0x32, 0x28, 0x6b, 0x29, 0x29, 0x20, 0x2f, 0x20, 0x33, 0x2e,
|
||||
0x30, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x74, 0x20, 0x3d,
|
||||
0x20, 0x78, 0x20, 0x2d, 0x20, 0x73, 0x68, 0x69, 0x66, 0x74, 0x3b, 0x0d,
|
||||
0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x69, 0x66, 0x20, 0x74, 0x20, 0x3e, 0x3d, 0x20, 0x30, 0x2e, 0x30,
|
||||
0x20, 0x26, 0x26, 0x20, 0x74, 0x20, 0x3c, 0x3d, 0x20, 0x31, 0x2e, 0x30,
|
||||
0x20, 0x7b, 0x20, 0x28, 0x2a, 0x72, 0x6f, 0x6f, 0x74, 0x73, 0x29, 0x5b,
|
||||
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x3b, 0x20,
|
||||
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2b, 0x2b, 0x3b, 0x20, 0x7d, 0x0d, 0x0a,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0d, 0x0a, 0x20,
|
||||
0x20, 0x20, 0x20, 0x7d, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65,
|
||||
0x74, 0x75, 0x72, 0x6e, 0x20, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x3b, 0x0d,
|
||||
0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x2f, 0x2f, 0x20, 0x2d, 0x2d, 0x2d,
|
||||
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x20, 0x57, 0x69, 0x6e, 0x64,
|
||||
0x69, 0x6e, 0x67, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x63,
|
||||
0x6f, 0x6e, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x20,
|
||||
0x66, 0x72, 0x6f, 0x6d, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x63, 0x75, 0x62,
|
||||
0x69, 0x63, 0x20, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x2d,
|
||||
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0d, 0x0a, 0x66,
|
||||
0x6e, 0x20, 0x72, 0x61, 0x79, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x73,
|
||||
0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x63, 0x75, 0x62, 0x69,
|
||||
0x63, 0x28, 0x70, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x32, 0x66, 0x2c, 0x20,
|
||||
0x73, 0x65, 0x67, 0x3a, 0x20, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74,
|
||||
0x29, 0x20, 0x2d, 0x3e, 0x20, 0x69, 0x33, 0x32, 0x20, 0x7b, 0x0d, 0x0a,
|
||||
0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x57, 0x65, 0x20, 0x63, 0x61,
|
||||
0x73, 0x74, 0x20, 0x61, 0x20, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x6f, 0x6e,
|
||||
0x74, 0x61, 0x6c, 0x20, 0x72, 0x61, 0x79, 0x20, 0x66, 0x72, 0x6f, 0x6d,
|
||||
0x20, 0x70, 0x20, 0x74, 0x6f, 0x20, 0x2b, 0x78, 0x3b, 0x20, 0x66, 0x69,
|
||||
0x6e, 0x64, 0x20, 0x74, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x20, 0x79,
|
||||
0x28, 0x74, 0x29, 0x20, 0x3d, 0x20, 0x70, 0x2e, 0x79, 0x0d, 0x0a, 0x20,
|
||||
0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x79, 0x30, 0x20, 0x3d, 0x20,
|
||||
0x73, 0x65, 0x67, 0x2e, 0x70, 0x30, 0x2e, 0x79, 0x20, 0x2d, 0x20, 0x70,
|
||||
0x2e, 0x79, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74,
|
||||
0x20, 0x79, 0x31, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x67, 0x2e, 0x70, 0x31,
|
||||
0x2e, 0x79, 0x20, 0x2d, 0x20, 0x70, 0x2e, 0x79, 0x3b, 0x0d, 0x0a, 0x20,
|
||||
0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x79, 0x32, 0x20, 0x3d, 0x20,
|
||||
0x73, 0x65, 0x67, 0x2e, 0x70, 0x32, 0x2e, 0x79, 0x20, 0x2d, 0x20, 0x70,
|
||||
0x2e, 0x79, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74,
|
||||
0x20, 0x79, 0x33, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x67, 0x2e, 0x70, 0x33,
|
||||
0x2e, 0x79, 0x20, 0x2d, 0x20, 0x70, 0x2e, 0x79, 0x3b, 0x0d, 0x0a, 0x0d,
|
||||
0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x79, 0x28, 0x74, 0x29,
|
||||
0x20, 0x3d, 0x20, 0x28, 0x31, 0x2d, 0x74, 0x29, 0x5e, 0x33, 0x2a, 0x79,
|
||||
0x30, 0x20, 0x2b, 0x20, 0x33, 0x28, 0x31, 0x2d, 0x74, 0x29, 0x5e, 0x32,
|
||||
0x20, 0x74, 0x20, 0x2a, 0x20, 0x79, 0x31, 0x20, 0x2b, 0x20, 0x33, 0x28,
|
||||
0x31, 0x2d, 0x74, 0x29, 0x20, 0x74, 0x5e, 0x32, 0x20, 0x2a, 0x20, 0x79,
|
||||
0x32, 0x20, 0x2b, 0x20, 0x74, 0x5e, 0x33, 0x20, 0x2a, 0x20, 0x79, 0x33,
|
||||
0x20, 0x3d, 0x20, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f,
|
||||
0x20, 0x45, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x20, 0x70, 0x6f, 0x6c, 0x79,
|
||||
0x6e, 0x6f, 0x6d, 0x69, 0x61, 0x6c, 0x3a, 0x20, 0x63, 0x33, 0x20, 0x74,
|
||||
0x5e, 0x33, 0x20, 0x2b, 0x20, 0x63, 0x32, 0x20, 0x74, 0x5e, 0x32, 0x20,
|
||||
0x2b, 0x20, 0x63, 0x31, 0x20, 0x74, 0x20, 0x2b, 0x20, 0x63, 0x30, 0x0d,
|
||||
0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x63, 0x30, 0x20,
|
||||
0x3d, 0x20, 0x79, 0x30, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c,
|
||||
0x65, 0x74, 0x20, 0x63, 0x31, 0x20, 0x3d, 0x20, 0x33, 0x2e, 0x30, 0x20,
|
||||
0x2a, 0x20, 0x28, 0x79, 0x31, 0x20, 0x2d, 0x20, 0x79, 0x30, 0x29, 0x3b,
|
||||
0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x63, 0x32,
|
||||
0x20, 0x3d, 0x20, 0x33, 0x2e, 0x30, 0x20, 0x2a, 0x20, 0x28, 0x79, 0x32,
|
||||
0x20, 0x2d, 0x20, 0x32, 0x2e, 0x30, 0x20, 0x2a, 0x20, 0x79, 0x31, 0x20,
|
||||
0x2b, 0x20, 0x79, 0x30, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
|
||||
0x6c, 0x65, 0x74, 0x20, 0x63, 0x33, 0x20, 0x3d, 0x20, 0x79, 0x33, 0x20,
|
||||
0x2d, 0x20, 0x33, 0x2e, 0x30, 0x20, 0x2a, 0x20, 0x79, 0x32, 0x20, 0x2b,
|
||||
0x20, 0x33, 0x2e, 0x30, 0x20, 0x2a, 0x20, 0x79, 0x31, 0x20, 0x2d, 0x20,
|
||||
0x79, 0x30, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76,
|
||||
0x61, 0x72, 0x20, 0x72, 0x6f, 0x6f, 0x74, 0x73, 0x3a, 0x20, 0x61, 0x72,
|
||||
0x72, 0x61, 0x79, 0x3c, 0x66, 0x33, 0x32, 0x2c, 0x20, 0x33, 0x3e, 0x3b,
|
||||
0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x6e, 0x75,
|
||||
0x6d, 0x20, 0x3d, 0x20, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x5f, 0x63, 0x75,
|
||||
0x62, 0x69, 0x63, 0x5f, 0x69, 0x6e, 0x5f, 0x30, 0x31, 0x28, 0x63, 0x33,
|
||||
0x2c, 0x20, 0x63, 0x32, 0x2c, 0x20, 0x63, 0x31, 0x2c, 0x20, 0x63, 0x30,
|
||||
0x2c, 0x20, 0x26, 0x72, 0x6f, 0x6f, 0x74, 0x73, 0x29, 0x3b, 0x0d, 0x0a,
|
||||
0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x77, 0x69, 0x6e, 0x64,
|
||||
0x20, 0x3d, 0x20, 0x30, 0x69, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
|
||||
0x66, 0x6f, 0x72, 0x20, 0x28, 0x76, 0x61, 0x72, 0x20, 0x69, 0x20, 0x3d,
|
||||
0x20, 0x30, 0x75, 0x3b, 0x20, 0x69, 0x20, 0x3c, 0x20, 0x6e, 0x75, 0x6d,
|
||||
0x3b, 0x20, 0x69, 0x2b, 0x2b, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x74, 0x20,
|
||||
0x3d, 0x20, 0x72, 0x6f, 0x6f, 0x74, 0x73, 0x5b, 0x69, 0x5d, 0x3b, 0x0d,
|
||||
0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74,
|
||||
0x20, 0x78, 0x20, 0x3d, 0x20, 0x65, 0x76, 0x61, 0x6c, 0x5f, 0x63, 0x75,
|
||||
0x62, 0x69, 0x63, 0x28, 0x74, 0x2c, 0x20, 0x73, 0x65, 0x67, 0x2e, 0x70,
|
||||
0x30, 0x2c, 0x20, 0x73, 0x65, 0x67, 0x2e, 0x70, 0x31, 0x2c, 0x20, 0x73,
|
||||
0x65, 0x67, 0x2e, 0x70, 0x32, 0x2c, 0x20, 0x73, 0x65, 0x67, 0x2e, 0x70,
|
||||
0x33, 0x29, 0x2e, 0x78, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x78, 0x20, 0x3e, 0x20, 0x70, 0x2e,
|
||||
0x78, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x64, 0x79, 0x20,
|
||||
0x3d, 0x20, 0x65, 0x76, 0x61, 0x6c, 0x5f, 0x63, 0x75, 0x62, 0x69, 0x63,
|
||||
0x5f, 0x64, 0x65, 0x72, 0x69, 0x76, 0x61, 0x74, 0x69, 0x76, 0x65, 0x28,
|
||||
0x74, 0x2c, 0x20, 0x73, 0x65, 0x67, 0x2e, 0x70, 0x30, 0x2c, 0x20, 0x73,
|
||||
0x65, 0x67, 0x2e, 0x70, 0x31, 0x2c, 0x20, 0x73, 0x65, 0x67, 0x2e, 0x70,
|
||||
0x32, 0x2c, 0x20, 0x73, 0x65, 0x67, 0x2e, 0x70, 0x33, 0x29, 0x2e, 0x79,
|
||||
0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x64, 0x79, 0x20, 0x3e, 0x20, 0x30,
|
||||
0x2e, 0x30, 0x20, 0x7b, 0x20, 0x77, 0x69, 0x6e, 0x64, 0x20, 0x2b, 0x3d,
|
||||
0x20, 0x31, 0x69, 0x3b, 0x20, 0x7d, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65,
|
||||
0x20, 0x69, 0x66, 0x20, 0x64, 0x79, 0x20, 0x3c, 0x20, 0x30, 0x2e, 0x30,
|
||||
0x20, 0x7b, 0x20, 0x77, 0x69, 0x6e, 0x64, 0x20, 0x2d, 0x3d, 0x20, 0x31,
|
||||
0x69, 0x3b, 0x20, 0x7d, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x7d, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0d, 0x0a,
|
||||
0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x77,
|
||||
0x69, 0x6e, 0x64, 0x3b, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x2f,
|
||||
0x2f, 0x20, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
||||
0x20, 0x4d, 0x61, 0x69, 0x6e, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74,
|
||||
0x65, 0x20, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x2d, 0x2d, 0x2d,
|
||||
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0d, 0x0a, 0x40, 0x63, 0x6f,
|
||||
0x6d, 0x70, 0x75, 0x74, 0x65, 0x20, 0x40, 0x77, 0x6f, 0x72, 0x6b, 0x67,
|
||||
0x72, 0x6f, 0x75, 0x70, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x28, 0x38, 0x2c,
|
||||
0x20, 0x38, 0x29, 0x0d, 0x0a, 0x66, 0x6e, 0x20, 0x6d, 0x61, 0x69, 0x6e,
|
||||
0x28, 0x40, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x28, 0x77, 0x6f,
|
||||
0x72, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x69, 0x64, 0x29, 0x20,
|
||||
0x77, 0x67, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x33, 0x3c, 0x75, 0x33, 0x32,
|
||||
0x3e, 0x2c, 0x20, 0x2f, 0x2f, 0x20, 0x65, 0x61, 0x63, 0x68, 0x20, 0x77,
|
||||
0x6f, 0x72, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x69, 0x73, 0x20,
|
||||
0x61, 0x20, 0x74, 0x69, 0x6c, 0x65, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x40, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e,
|
||||
0x28, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x69, 0x6e, 0x76, 0x6f, 0x63,
|
||||
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x29, 0x20, 0x6c, 0x6f,
|
||||
0x63, 0x61, 0x6c, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x33, 0x3c, 0x75, 0x33,
|
||||
0x32, 0x3e, 0x29, 0x20, 0x2f, 0x2f, 0x20, 0x65, 0x61, 0x63, 0x68, 0x20,
|
||||
0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x6e, 0x76, 0x6f, 0x63, 0x61,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x70, 0x69,
|
||||
0x78, 0x65, 0x6c, 0x0d, 0x0a, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
|
||||
0x6c, 0x65, 0x74, 0x20, 0x74, 0x69, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x78,
|
||||
0x20, 0x3d, 0x20, 0x77, 0x67, 0x2e, 0x78, 0x20, 0x2f, 0x20, 0x31, 0x36,
|
||||
0x75, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20,
|
||||
0x74, 0x69, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0x74, 0x69, 0x6c, 0x65, 0x73,
|
||||
0x5b, 0x74, 0x69, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x78, 0x5d, 0x3b, 0x0d,
|
||||
0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x70,
|
||||
0x78, 0x20, 0x3d, 0x20, 0x28, 0x77, 0x67, 0x2e, 0x78, 0x20, 0x25, 0x20,
|
||||
0x31, 0x36, 0x75, 0x29, 0x20, 0x2a, 0x20, 0x38, 0x75, 0x20, 0x2b, 0x20,
|
||||
0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2e, 0x78, 0x3b, 0x0d, 0x0a, 0x20, 0x20,
|
||||
0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x70, 0x79, 0x20, 0x3d, 0x20, 0x77,
|
||||
0x67, 0x2e, 0x79, 0x20, 0x2a, 0x20, 0x38, 0x75, 0x20, 0x2b, 0x20, 0x6c,
|
||||
0x6f, 0x63, 0x61, 0x6c, 0x2e, 0x79, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x20,
|
||||
0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x70, 0x78, 0x20, 0x3e, 0x3d,
|
||||
0x20, 0x54, 0x49, 0x4c, 0x45, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x20, 0x7c,
|
||||
0x7c, 0x20, 0x70, 0x79, 0x20, 0x3e, 0x3d, 0x20, 0x54, 0x49, 0x4c, 0x45,
|
||||
0x5f, 0x53, 0x49, 0x5a, 0x45, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
|
||||
0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a,
|
||||
0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x75, 0x76, 0x20, 0x3d,
|
||||
0x20, 0x28, 0x76, 0x65, 0x63, 0x32, 0x66, 0x28, 0x66, 0x33, 0x32, 0x28,
|
||||
0x70, 0x78, 0x29, 0x2c, 0x20, 0x66, 0x33, 0x32, 0x28, 0x70, 0x79, 0x29,
|
||||
0x29, 0x20, 0x2b, 0x20, 0x30, 0x2e, 0x35, 0x29, 0x20, 0x2f, 0x20, 0x66,
|
||||
0x33, 0x32, 0x28, 0x54, 0x49, 0x4c, 0x45, 0x5f, 0x53, 0x49, 0x5a, 0x45,
|
||||
0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20,
|
||||
0x77, 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x3d, 0x20, 0x6d, 0x69, 0x78, 0x28,
|
||||
0x74, 0x69, 0x6c, 0x65, 0x2e, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x5f, 0x6d,
|
||||
0x69, 0x6e, 0x2c, 0x20, 0x74, 0x69, 0x6c, 0x65, 0x2e, 0x77, 0x6f, 0x72,
|
||||
0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x78, 0x2c, 0x20, 0x75, 0x76, 0x29, 0x3b,
|
||||
0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20,
|
||||
0x6d, 0x69, 0x6e, 0x44, 0x69, 0x73, 0x74, 0x3a, 0x20, 0x66, 0x33, 0x32,
|
||||
0x20, 0x3d, 0x20, 0x31, 0x65, 0x32, 0x30, 0x3b, 0x0d, 0x0a, 0x20, 0x20,
|
||||
0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x73, 0x64, 0x66, 0x3a, 0x20, 0x66,
|
||||
0x33, 0x32, 0x20, 0x3d, 0x20, 0x31, 0x65, 0x32, 0x30, 0x3b, 0x0d, 0x0a,
|
||||
0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x77, 0x69, 0x6e, 0x64,
|
||||
0x69, 0x6e, 0x67, 0x3a, 0x20, 0x69, 0x33, 0x32, 0x20, 0x3d, 0x20, 0x30,
|
||||
0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6f, 0x72,
|
||||
0x20, 0x28, 0x76, 0x61, 0x72, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x30, 0x75,
|
||||
0x3b, 0x20, 0x73, 0x20, 0x3c, 0x20, 0x74, 0x69, 0x6c, 0x65, 0x2e, 0x63,
|
||||
0x6f, 0x75, 0x6e, 0x74, 0x3b, 0x20, 0x73, 0x2b, 0x2b, 0x29, 0x20, 0x7b,
|
||||
0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f,
|
||||
0x20, 0x55, 0x73, 0x65, 0x20, 0x61, 0x20, 0x70, 0x72, 0x65, 0x2d, 0x63,
|
||||
0x75, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x73, 0x68, 0x61, 0x70, 0x65, 0x20,
|
||||
0x72, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x70, 0x65, 0x72, 0x20, 0x74, 0x69,
|
||||
0x6c, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x72, 0x65, 0x64, 0x75, 0x63, 0x65,
|
||||
0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x65, 0x72, 0x2d, 0x70, 0x69, 0x78,
|
||||
0x65, 0x6c, 0x20, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, 0x6e,
|
||||
0x67, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x69, 0x6e, 0x64, 0x65,
|
||||
0x78, 0x20, 0x3d, 0x20, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x65, 0x73, 0x5b,
|
||||
0x74, 0x69, 0x6c, 0x65, 0x2e, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x20,
|
||||
0x2b, 0x20, 0x73, 0x5d, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x49, 0x66, 0x20, 0x74,
|
||||
0x68, 0x65, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x69, 0x73, 0x20,
|
||||
0x6c, 0x6f, 0x77, 0x65, 0x72, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x20, 0x74,
|
||||
0x68, 0x65, 0x20, 0x63, 0x69, 0x72, 0x63, 0x6c, 0x65, 0x20, 0x63, 0x6f,
|
||||
0x75, 0x6e, 0x74, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x6d, 0x65, 0x61, 0x6e,
|
||||
0x20, 0x77, 0x65, 0x20, 0x61, 0x72, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x63,
|
||||
0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x63, 0x69, 0x72, 0x63, 0x6c,
|
||||
0x65, 0x73, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x69, 0x66, 0x28, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x3c, 0x20, 0x74,
|
||||
0x69, 0x6c, 0x65, 0x2e, 0x63, 0x69, 0x72, 0x63, 0x6c, 0x65, 0x5f, 0x63,
|
||||
0x6f, 0x75, 0x6e, 0x74, 0x29, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x63, 0x20,
|
||||
0x3d, 0x20, 0x63, 0x69, 0x72, 0x63, 0x6c, 0x65, 0x73, 0x5b, 0x69, 0x6e,
|
||||
0x64, 0x65, 0x78, 0x5d, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x64, 0x66, 0x20, 0x3d,
|
||||
0x20, 0x6d, 0x69, 0x6e, 0x28, 0x73, 0x64, 0x66, 0x2c, 0x20, 0x6c, 0x65,
|
||||
0x6e, 0x67, 0x74, 0x68, 0x28, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x2d,
|
||||
0x20, 0x63, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x29, 0x20, 0x2d,
|
||||
0x20, 0x63, 0x2e, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x29, 0x3b, 0x0d,
|
||||
0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0d, 0x0a,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65,
|
||||
0x20, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7b,
|
||||
0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x73, 0x68, 0x61, 0x70, 0x65, 0x20,
|
||||
0x3d, 0x20, 0x73, 0x68, 0x61, 0x70, 0x65, 0x73, 0x5b, 0x69, 0x6e, 0x64,
|
||||
0x65, 0x78, 0x5d, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2a, 0x6c, 0x65,
|
||||
0x74, 0x20, 0x62, 0x62, 0x6f, 0x78, 0x5f, 0x6d, 0x69, 0x6e, 0x20, 0x3d,
|
||||
0x20, 0x73, 0x68, 0x61, 0x70, 0x65, 0x2e, 0x62, 0x62, 0x6f, 0x78, 0x5f,
|
||||
0x6d, 0x69, 0x6e, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x62, 0x62,
|
||||
0x6f, 0x78, 0x5f, 0x6d, 0x61, 0x78, 0x20, 0x3d, 0x20, 0x73, 0x68, 0x61,
|
||||
0x70, 0x65, 0x2e, 0x62, 0x62, 0x6f, 0x78, 0x5f, 0x6d, 0x61, 0x78, 0x3b,
|
||||
0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x64, 0x78, 0x20, 0x3d, 0x20, 0x6d,
|
||||
0x61, 0x78, 0x28, 0x62, 0x62, 0x6f, 0x78, 0x5f, 0x6d, 0x69, 0x6e, 0x2e,
|
||||
0x78, 0x20, 0x2d, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2e, 0x78, 0x2c,
|
||||
0x20, 0x6d, 0x61, 0x78, 0x28, 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x77, 0x6f,
|
||||
0x72, 0x6c, 0x64, 0x2e, 0x78, 0x20, 0x2d, 0x20, 0x62, 0x62, 0x6f, 0x78,
|
||||
0x5f, 0x6d, 0x61, 0x78, 0x2e, 0x78, 0x29, 0x29, 0x3b, 0x0d, 0x0a, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c,
|
||||
0x65, 0x74, 0x20, 0x64, 0x79, 0x20, 0x3d, 0x20, 0x6d, 0x61, 0x78, 0x28,
|
||||
0x62, 0x62, 0x6f, 0x78, 0x5f, 0x6d, 0x69, 0x6e, 0x2e, 0x79, 0x20, 0x2d,
|
||||
0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2e, 0x79, 0x2c, 0x20, 0x6d, 0x61,
|
||||
0x78, 0x28, 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64,
|
||||
0x2e, 0x79, 0x20, 0x2d, 0x20, 0x62, 0x62, 0x6f, 0x78, 0x5f, 0x6d, 0x61,
|
||||
0x78, 0x2e, 0x79, 0x29, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20,
|
||||
0x64, 0x69, 0x73, 0x74, 0x5f, 0x74, 0x6f, 0x5f, 0x62, 0x6f, 0x78, 0x20,
|
||||
0x3d, 0x20, 0x73, 0x71, 0x72, 0x74, 0x28, 0x64, 0x78, 0x20, 0x2a, 0x20,
|
||||
0x64, 0x78, 0x20, 0x2b, 0x20, 0x64, 0x79, 0x20, 0x2a, 0x20, 0x64, 0x79,
|
||||
0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x64, 0x69, 0x73, 0x74, 0x5f,
|
||||
0x74, 0x6f, 0x5f, 0x62, 0x6f, 0x78, 0x20, 0x3e, 0x3d, 0x20, 0x6d, 0x69,
|
||||
0x6e, 0x44, 0x69, 0x73, 0x74, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x3b, 0x0d, 0x0a,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x7d, 0x2a, 0x2f, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x50, 0x72,
|
||||
0x6f, 0x63, 0x65, 0x73, 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x73, 0x65,
|
||||
0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68,
|
||||
0x65, 0x20, 0x73, 0x68, 0x61, 0x70, 0x65, 0x0d, 0x0a, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6f, 0x72,
|
||||
0x20, 0x28, 0x76, 0x61, 0x72, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x73, 0x68,
|
||||
0x61, 0x70, 0x65, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x73, 0x65,
|
||||
0x67, 0x6d, 0x65, 0x6e, 0x74, 0x3b, 0x20, 0x69, 0x20, 0x3c, 0x20, 0x73,
|
||||
0x68, 0x61, 0x70, 0x65, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x73,
|
||||
0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x2b, 0x20, 0x73, 0x68, 0x61,
|
||||
0x70, 0x65, 0x2e, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x63,
|
||||
0x6f, 0x75, 0x6e, 0x74, 0x3b, 0x20, 0x69, 0x2b, 0x2b, 0x29, 0x20, 0x7b,
|
||||
0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x73, 0x65,
|
||||
0x67, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73,
|
||||
0x5b, 0x69, 0x5d, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65,
|
||||
0x74, 0x20, 0x64, 0x20, 0x3d, 0x20, 0x64, 0x69, 0x73, 0x74, 0x61, 0x6e,
|
||||
0x63, 0x65, 0x5f, 0x74, 0x6f, 0x5f, 0x63, 0x75, 0x62, 0x69, 0x63, 0x28,
|
||||
0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2c, 0x20, 0x73, 0x65, 0x67, 0x29, 0x3b,
|
||||
0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x69, 0x6e, 0x44, 0x69, 0x73,
|
||||
0x74, 0x20, 0x3d, 0x20, 0x6d, 0x69, 0x6e, 0x28, 0x6d, 0x69, 0x6e, 0x44,
|
||||
0x69, 0x73, 0x74, 0x2c, 0x20, 0x64, 0x29, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x77, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x20,
|
||||
0x2b, 0x3d, 0x20, 0x72, 0x61, 0x79, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72,
|
||||
0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x63, 0x75, 0x62,
|
||||
0x69, 0x63, 0x28, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2c, 0x20, 0x73, 0x65,
|
||||
0x67, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65,
|
||||
0x74, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c,
|
||||
0x65, 0x63, 0x74, 0x28, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e,
|
||||
0x30, 0x2c, 0x20, 0x77, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x21,
|
||||
0x3d, 0x20, 0x30, 0x69, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x64, 0x66, 0x20,
|
||||
0x3d, 0x20, 0x6d, 0x69, 0x6e, 0x28, 0x73, 0x64, 0x66, 0x2c, 0x20, 0x73,
|
||||
0x69, 0x67, 0x6e, 0x20, 0x2a, 0x20, 0x6d, 0x69, 0x6e, 0x44, 0x69, 0x73,
|
||||
0x74, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x7d, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0d, 0x0a, 0x0d,
|
||||
0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65,
|
||||
0x53, 0x74, 0x6f, 0x72, 0x65, 0x28, 0x73, 0x64, 0x66, 0x5f, 0x62, 0x75,
|
||||
0x66, 0x66, 0x65, 0x72, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x32, 0x28, 0x75,
|
||||
0x33, 0x32, 0x28, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2e, 0x78, 0x29, 0x2c,
|
||||
0x20, 0x75, 0x33, 0x32, 0x28, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2e, 0x79,
|
||||
0x29, 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x34, 0x66, 0x28, 0x73, 0x64,
|
||||
0x66, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x2c,
|
||||
0x20, 0x31, 0x2e, 0x30, 0x29, 0x29, 0x3b, 0x0d, 0x0a, 0x7d
|
||||
};
|
||||
unsigned int src_shaders_compute_wgsl_len = 8194;
|
||||
47
src/generated/display.h
Normal file
47
src/generated/display.h
Normal file
@@ -0,0 +1,47 @@
|
||||
unsigned char src_shaders_display_wgsl[] = {
|
||||
0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x55, 0x6e, 0x69, 0x66, 0x6f,
|
||||
0x72, 0x6d, 0x73, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74,
|
||||
0x69, 0x6d, 0x65, 0x3a, 0x20, 0x75, 0x33, 0x32, 0x2c, 0x0d, 0x0a, 0x20,
|
||||
0x20, 0x20, 0x20, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x75, 0x33,
|
||||
0x32, 0x2c, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x76, 0x70, 0x3a,
|
||||
0x20, 0x6d, 0x61, 0x74, 0x34, 0x78, 0x34, 0x66, 0x2c, 0x0d, 0x0a, 0x7d,
|
||||
0x0d, 0x0a, 0x0d, 0x0a, 0x40, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x28, 0x30,
|
||||
0x29, 0x20, 0x40, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x28, 0x30,
|
||||
0x29, 0x20, 0x76, 0x61, 0x72, 0x3c, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72,
|
||||
0x6d, 0x3e, 0x20, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x3a,
|
||||
0x20, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x3b, 0x0d, 0x0a,
|
||||
0x0d, 0x0a, 0x40, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x28, 0x31, 0x29, 0x20,
|
||||
0x40, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x28, 0x30, 0x29, 0x20,
|
||||
0x76, 0x61, 0x72, 0x20, 0x73, 0x64, 0x66, 0x20, 0x3a, 0x20, 0x74, 0x65,
|
||||
0x78, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x32, 0x64, 0x3c, 0x66, 0x33, 0x32,
|
||||
0x3e, 0x3b, 0x0d, 0x0a, 0x40, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x28, 0x31,
|
||||
0x29, 0x20, 0x40, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x28, 0x31,
|
||||
0x29, 0x20, 0x76, 0x61, 0x72, 0x20, 0x73, 0x64, 0x66, 0x5f, 0x73, 0x61,
|
||||
0x6d, 0x70, 0x6c, 0x65, 0x72, 0x20, 0x3a, 0x20, 0x73, 0x61, 0x6d, 0x70,
|
||||
0x6c, 0x65, 0x72, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x40, 0x76, 0x65, 0x72,
|
||||
0x74, 0x65, 0x78, 0x20, 0x66, 0x6e, 0x20, 0x76, 0x73, 0x5f, 0x6d, 0x61,
|
||||
0x69, 0x6e, 0x28, 0x40, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x28, 0x30, 0x29, 0x20, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x3a, 0x20, 0x76, 0x65, 0x63, 0x32, 0x66, 0x29, 0x20, 0x2d, 0x3e, 0x20,
|
||||
0x40, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x28, 0x70, 0x6f, 0x73,
|
||||
0x69, 0x74, 0x69, 0x6f, 0x6e, 0x29, 0x20, 0x76, 0x65, 0x63, 0x34, 0x66,
|
||||
0x0d, 0x0a, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74,
|
||||
0x75, 0x72, 0x6e, 0x20, 0x76, 0x65, 0x63, 0x34, 0x66, 0x28, 0x70, 0x6f,
|
||||
0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x2c,
|
||||
0x20, 0x31, 0x2e, 0x30, 0x29, 0x20, 0x2a, 0x20, 0x75, 0x6e, 0x69, 0x66,
|
||||
0x6f, 0x72, 0x6d, 0x73, 0x2e, 0x6d, 0x76, 0x70, 0x3b, 0x0d, 0x0a, 0x7d,
|
||||
0x0d, 0x0a, 0x0d, 0x0a, 0x40, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e,
|
||||
0x74, 0x20, 0x66, 0x6e, 0x20, 0x66, 0x73, 0x5f, 0x6d, 0x61, 0x69, 0x6e,
|
||||
0x28, 0x40, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x28, 0x70, 0x6f,
|
||||
0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x29, 0x20, 0x70, 0x6f, 0x73, 0x69,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x34, 0x66, 0x29,
|
||||
0x20, 0x2d, 0x3e, 0x20, 0x40, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x28, 0x30, 0x29, 0x20, 0x76, 0x65, 0x63, 0x34, 0x66, 0x0d, 0x0a,
|
||||
0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72,
|
||||
0x6e, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x53, 0x61, 0x6d,
|
||||
0x70, 0x6c, 0x65, 0x28, 0x73, 0x64, 0x66, 0x2c, 0x20, 0x73, 0x64, 0x66,
|
||||
0x5f, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x2c, 0x20, 0x70, 0x6f,
|
||||
0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x78, 0x79, 0x29, 0x3b, 0x0d,
|
||||
0x0a, 0x7d
|
||||
};
|
||||
unsigned int src_shaders_display_wgsl_len = 518;
|
||||
@@ -1,145 +0,0 @@
|
||||
unsigned char src_shaders_sprite_wgsl[] = {
|
||||
0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x53, 0x70, 0x72, 0x69, 0x74,
|
||||
0x65, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x61, 0x74,
|
||||
0x72, 0x69, 0x78, 0x3a, 0x20, 0x6d, 0x61, 0x74, 0x34, 0x78, 0x34, 0x66,
|
||||
0x2c, 0x0d, 0x0a, 0x7d, 0x3b, 0x0d, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63,
|
||||
0x74, 0x20, 0x56, 0x73, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20,
|
||||
0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x76, 0x70, 0x3a, 0x20,
|
||||
0x6d, 0x61, 0x74, 0x34, 0x78, 0x34, 0x66, 0x2c, 0x0d, 0x0a, 0x7d, 0x3b,
|
||||
0x0d, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x56, 0x73, 0x49,
|
||||
0x20, 0x7b, 0x20, 0x2f, 0x2f, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x20,
|
||||
0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74,
|
||||
0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x40, 0x62, 0x75, 0x69, 0x6c, 0x74,
|
||||
0x69, 0x6e, 0x28, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f,
|
||||
0x69, 0x6e, 0x64, 0x65, 0x78, 0x29, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61,
|
||||
0x6e, 0x63, 0x65, 0x3a, 0x20, 0x75, 0x33, 0x32, 0x2c, 0x0d, 0x0a, 0x20,
|
||||
0x20, 0x20, 0x20, 0x40, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x28, 0x30, 0x29, 0x20, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x3a, 0x20, 0x76, 0x65, 0x63, 0x32, 0x66, 0x2c, 0x0d, 0x0a, 0x20, 0x20,
|
||||
0x20, 0x20, 0x40, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28,
|
||||
0x31, 0x29, 0x20, 0x75, 0x76, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x32, 0x66,
|
||||
0x2c, 0x0d, 0x0a, 0x7d, 0x3b, 0x0d, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63,
|
||||
0x74, 0x20, 0x56, 0x73, 0x32, 0x46, 0x73, 0x20, 0x7b, 0x20, 0x2f, 0x2f,
|
||||
0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x20, 0x73, 0x68, 0x61, 0x64, 0x65,
|
||||
0x72, 0x20, 0x74, 0x6f, 0x20, 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e,
|
||||
0x74, 0x20, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x0d, 0x0a, 0x20, 0x20,
|
||||
0x20, 0x20, 0x40, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x28, 0x70,
|
||||
0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x29, 0x20, 0x70, 0x6f, 0x73,
|
||||
0x3a, 0x20, 0x76, 0x65, 0x63, 0x34, 0x66, 0x2c, 0x0d, 0x0a, 0x20, 0x20,
|
||||
0x20, 0x20, 0x40, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28,
|
||||
0x30, 0x29, 0x20, 0x40, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x6f, 0x6c,
|
||||
0x61, 0x74, 0x65, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x29, 0x20,
|
||||
0x75, 0x76, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x32, 0x66, 0x2c, 0x0d, 0x0a,
|
||||
0x7d, 0x3b, 0x0d, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x46,
|
||||
0x73, 0x4f, 0x20, 0x7b, 0x20, 0x2f, 0x2f, 0x46, 0x72, 0x61, 0x67, 0x6d,
|
||||
0x65, 0x6e, 0x74, 0x20, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x6f,
|
||||
0x75, 0x74, 0x70, 0x75, 0x74, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x40,
|
||||
0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x30, 0x29, 0x20,
|
||||
0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x34, 0x66,
|
||||
0x2c, 0x0d, 0x0a, 0x7d, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x40, 0x62, 0x69,
|
||||
0x6e, 0x64, 0x69, 0x6e, 0x67, 0x28, 0x30, 0x29, 0x20, 0x40, 0x67, 0x72,
|
||||
0x6f, 0x75, 0x70, 0x28, 0x30, 0x29, 0x20, 0x76, 0x61, 0x72, 0x3c, 0x75,
|
||||
0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x3e, 0x20, 0x76, 0x73, 0x5f, 0x75,
|
||||
0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x3a, 0x20, 0x56, 0x73, 0x55,
|
||||
0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x3b, 0x0d, 0x0a, 0x40, 0x62, 0x69,
|
||||
0x6e, 0x64, 0x69, 0x6e, 0x67, 0x28, 0x30, 0x29, 0x20, 0x40, 0x67, 0x72,
|
||||
0x6f, 0x75, 0x70, 0x28, 0x31, 0x29, 0x20, 0x76, 0x61, 0x72, 0x20, 0x74,
|
||||
0x65, 0x78, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x5f,
|
||||
0x32, 0x64, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x3b, 0x0d, 0x0a, 0x40, 0x62,
|
||||
0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x28, 0x31, 0x29, 0x20, 0x40, 0x67,
|
||||
0x72, 0x6f, 0x75, 0x70, 0x28, 0x31, 0x29, 0x20, 0x76, 0x61, 0x72, 0x20,
|
||||
0x73, 0x61, 0x6d, 0x70, 0x3a, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65,
|
||||
0x72, 0x3b, 0x0d, 0x0a, 0x40, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67,
|
||||
0x28, 0x32, 0x29, 0x20, 0x40, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x28, 0x31,
|
||||
0x29, 0x20, 0x76, 0x61, 0x72, 0x3c, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67,
|
||||
0x65, 0x3e, 0x20, 0x73, 0x70, 0x72, 0x69, 0x74, 0x65, 0x73, 0x3a, 0x20,
|
||||
0x61, 0x72, 0x72, 0x61, 0x79, 0x3c, 0x53, 0x70, 0x72, 0x69, 0x74, 0x65,
|
||||
0x3e, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x40, 0x76, 0x65, 0x72, 0x74, 0x65,
|
||||
0x78, 0x20, 0x66, 0x6e, 0x20, 0x76, 0x73, 0x5f, 0x6d, 0x61, 0x69, 0x6e,
|
||||
0x28, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x3a, 0x20, 0x56, 0x73, 0x49, 0x29,
|
||||
0x20, 0x2d, 0x3e, 0x20, 0x56, 0x73, 0x32, 0x46, 0x73, 0x20, 0x7b, 0x0d,
|
||||
0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x6f, 0x75, 0x74,
|
||||
0x70, 0x75, 0x74, 0x3a, 0x20, 0x56, 0x73, 0x32, 0x46, 0x73, 0x3b, 0x0d,
|
||||
0x0a, 0x20, 0x20, 0x20, 0x20, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f,
|
||||
0x75, 0x74, 0x70, 0x75, 0x74, 0x2e, 0x70, 0x6f, 0x73, 0x20, 0x3d, 0x20,
|
||||
0x76, 0x65, 0x63, 0x34, 0x66, 0x28, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x2e,
|
||||
0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x78, 0x2c, 0x20,
|
||||
0x69, 0x6e, 0x70, 0x75, 0x74, 0x2e, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x2e, 0x79, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x30, 0x29, 0x20,
|
||||
0x2a, 0x20, 0x73, 0x70, 0x72, 0x69, 0x74, 0x65, 0x73, 0x5b, 0x69, 0x6e,
|
||||
0x70, 0x75, 0x74, 0x2e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65,
|
||||
0x5d, 0x2e, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x2a, 0x20, 0x76,
|
||||
0x73, 0x5f, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x2e, 0x6d,
|
||||
0x76, 0x70, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74,
|
||||
0x70, 0x75, 0x74, 0x2e, 0x75, 0x76, 0x20, 0x3d, 0x20, 0x69, 0x6e, 0x70,
|
||||
0x75, 0x74, 0x2e, 0x75, 0x76, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20,
|
||||
0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x75, 0x74,
|
||||
0x70, 0x75, 0x74, 0x3b, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x2f,
|
||||
0x2f, 0x20, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x20, 0x61, 0x20,
|
||||
0x33, 0x32, 0x62, 0x69, 0x74, 0x20, 0x75, 0x69, 0x6e, 0x74, 0x20, 0x63,
|
||||
0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x28, 0x68, 0x65, 0x78, 0x20, 0x72, 0x65,
|
||||
0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x29, 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x20, 0x61, 0x20, 0x6e, 0x6f, 0x72,
|
||||
0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x76, 0x65, 0x63, 0x34,
|
||||
0x66, 0x0d, 0x0a, 0x2f, 0x2a, 0x66, 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x76,
|
||||
0x65, 0x72, 0x74, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x69, 0x6e, 0x70,
|
||||
0x75, 0x74, 0x3a, 0x20, 0x75, 0x33, 0x32, 0x29, 0x20, 0x2d, 0x3e, 0x20,
|
||||
0x76, 0x65, 0x63, 0x34, 0x66, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20,
|
||||
0x20, 0x6c, 0x65, 0x74, 0x20, 0x72, 0x3a, 0x20, 0x66, 0x33, 0x32, 0x20,
|
||||
0x3d, 0x20, 0x66, 0x33, 0x32, 0x28, 0x28, 0x28, 0x69, 0x6e, 0x70, 0x75,
|
||||
0x74, 0x20, 0x3e, 0x3e, 0x20, 0x20, 0x30, 0x29, 0x20, 0x26, 0x20, 0x30,
|
||||
0x78, 0x66, 0x66, 0x29, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
|
||||
0x6c, 0x65, 0x74, 0x20, 0x67, 0x3a, 0x20, 0x66, 0x33, 0x32, 0x20, 0x3d,
|
||||
0x20, 0x66, 0x33, 0x32, 0x28, 0x28, 0x28, 0x69, 0x6e, 0x70, 0x75, 0x74,
|
||||
0x20, 0x3e, 0x3e, 0x20, 0x20, 0x38, 0x29, 0x20, 0x26, 0x20, 0x30, 0x78,
|
||||
0x66, 0x66, 0x29, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c,
|
||||
0x65, 0x74, 0x20, 0x62, 0x3a, 0x20, 0x66, 0x33, 0x32, 0x20, 0x3d, 0x20,
|
||||
0x66, 0x33, 0x32, 0x28, 0x28, 0x28, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20,
|
||||
0x3e, 0x3e, 0x20, 0x31, 0x36, 0x29, 0x20, 0x26, 0x20, 0x30, 0x78, 0x66,
|
||||
0x66, 0x29, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65,
|
||||
0x74, 0x20, 0x61, 0x3a, 0x20, 0x66, 0x33, 0x32, 0x20, 0x3d, 0x20, 0x66,
|
||||
0x33, 0x32, 0x28, 0x28, 0x28, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x3e,
|
||||
0x3e, 0x20, 0x32, 0x34, 0x29, 0x20, 0x26, 0x20, 0x30, 0x78, 0x66, 0x66,
|
||||
0x29, 0x29, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72,
|
||||
0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, 0x65, 0x63, 0x34, 0x66, 0x28,
|
||||
0x72, 0x20, 0x2f, 0x20, 0x32, 0x35, 0x35, 0x2c, 0x20, 0x67, 0x20, 0x2f,
|
||||
0x20, 0x32, 0x35, 0x35, 0x2c, 0x20, 0x62, 0x20, 0x2f, 0x20, 0x32, 0x35,
|
||||
0x35, 0x2c, 0x20, 0x61, 0x20, 0x2f, 0x20, 0x32, 0x35, 0x35, 0x29, 0x3b,
|
||||
0x0d, 0x0a, 0x7d, 0x2a, 0x2f, 0x0d, 0x0a, 0x2f, 0x2f, 0x20, 0x47, 0x65,
|
||||
0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72,
|
||||
0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x69, 0x6e, 0x64, 0x65,
|
||||
0x78, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x55,
|
||||
0x56, 0x0d, 0x0a, 0x2f, 0x2a, 0x66, 0x6e, 0x20, 0x69, 0x6e, 0x64, 0x65,
|
||||
0x78, 0x46, 0x72, 0x6f, 0x6d, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x28, 0x75,
|
||||
0x76, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x32, 0x66, 0x2c, 0x20, 0x77, 0x69,
|
||||
0x64, 0x74, 0x68, 0x3a, 0x20, 0x75, 0x33, 0x32, 0x2c, 0x20, 0x68, 0x65,
|
||||
0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, 0x75, 0x33, 0x32, 0x29, 0x20, 0x2d,
|
||||
0x3e, 0x20, 0x75, 0x33, 0x32, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20,
|
||||
0x20, 0x6c, 0x65, 0x74, 0x20, 0x78, 0x3a, 0x20, 0x75, 0x33, 0x32, 0x20,
|
||||
0x3d, 0x20, 0x63, 0x6c, 0x61, 0x6d, 0x70, 0x28, 0x66, 0x6c, 0x6f, 0x6f,
|
||||
0x72, 0x28, 0x75, 0x76, 0x2e, 0x78, 0x20, 0x2a, 0x20, 0x66, 0x33, 0x32,
|
||||
0x28, 0x77, 0x69, 0x64, 0x74, 0x68, 0x29, 0x29, 0x2c, 0x20, 0x30, 0x2c,
|
||||
0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20,
|
||||
0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x79, 0x3a, 0x20, 0x75, 0x33, 0x32,
|
||||
0x20, 0x3d, 0x20, 0x63, 0x6c, 0x61, 0x6d, 0x70, 0x28, 0x66, 0x6c, 0x6f,
|
||||
0x6f, 0x72, 0x28, 0x75, 0x76, 0x2e, 0x79, 0x20, 0x2a, 0x20, 0x66, 0x33,
|
||||
0x32, 0x28, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x29, 0x29, 0x2c, 0x20,
|
||||
0x30, 0x2c, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x29, 0x3b, 0x0d,
|
||||
0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20,
|
||||
0x79, 0x20, 0x2a, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, 0x2b, 0x20,
|
||||
0x78, 0x3b, 0x0d, 0x0a, 0x7d, 0x2a, 0x2f, 0x0d, 0x0a, 0x0d, 0x0a, 0x40,
|
||||
0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x66, 0x6e, 0x20,
|
||||
0x66, 0x73, 0x5f, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x69, 0x6e, 0x70, 0x75,
|
||||
0x74, 0x3a, 0x20, 0x56, 0x73, 0x32, 0x46, 0x73, 0x29, 0x20, 0x2d, 0x3e,
|
||||
0x20, 0x46, 0x73, 0x4f, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
|
||||
0x76, 0x61, 0x72, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x3a, 0x20,
|
||||
0x46, 0x73, 0x4f, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
|
||||
0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x2e, 0x63, 0x6f, 0x6c, 0x6f, 0x72,
|
||||
0x20, 0x3d, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x53, 0x61,
|
||||
0x6d, 0x70, 0x6c, 0x65, 0x28, 0x74, 0x65, 0x78, 0x2c, 0x20, 0x73, 0x61,
|
||||
0x6d, 0x70, 0x2c, 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x2e, 0x75, 0x76,
|
||||
0x29, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65,
|
||||
0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x3b,
|
||||
0x0d, 0x0a, 0x7d
|
||||
};
|
||||
unsigned int src_shaders_sprite_wgsl_len = 1695;
|
||||
582
src/main.c
582
src/main.c
@@ -1,116 +1,322 @@
|
||||
#include "api.h"
|
||||
|
||||
#define ALLOC(arg) smemtrack_alloc(arg, NULL)
|
||||
#define FREE(arg) smemtrack_free(arg, NULL)
|
||||
typedef struct display_uniforms {
|
||||
uint32_t frame;
|
||||
uint32_t time;
|
||||
|
||||
#define GRID_X 1000
|
||||
#define GRID_Y 1000
|
||||
|
||||
typedef struct vs_uniform_t {
|
||||
mat4x4f mvp;
|
||||
} uniform_t;
|
||||
float mvp[16];
|
||||
} display_uniforms;
|
||||
|
||||
typedef struct renderer_t {
|
||||
sg_pipeline pipeline; //Configured sprite pipeline
|
||||
sg_pass_action clear_pass; //Render pass - Clear screen
|
||||
uniform_t uniform; //Uniform data
|
||||
sg_pipeline pipeline;
|
||||
sg_pass_action clear_pass;
|
||||
sg_bindings bindings;
|
||||
|
||||
display_uniforms uniforms;
|
||||
} renderer_t;
|
||||
|
||||
typedef struct dragger_t {
|
||||
bool dragging;
|
||||
float origin_x, origin_y;
|
||||
} dragger_t;
|
||||
typedef struct compute_t {
|
||||
sg_pipeline pipeline;
|
||||
sg_bindings bindings;
|
||||
sg_pass pass;
|
||||
} compute_t;
|
||||
|
||||
typedef struct userdata_t {
|
||||
int width, height;
|
||||
vec2f pan;
|
||||
float zoom;
|
||||
dragger_t dragger;
|
||||
scene_t scene;
|
||||
renderer_t renderer;
|
||||
manager_t manager;
|
||||
compute_t compute;
|
||||
|
||||
//Viewport related values
|
||||
float pan_x, pan_y;
|
||||
float zoom, rotation;
|
||||
} userdata_t;
|
||||
|
||||
const char* format(const char* format, ...)
|
||||
static void* _malloc(size_t size, void* userdata)
|
||||
{
|
||||
char buffer[_SLOG_LINE_LENGTH];
|
||||
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
|
||||
int size = vsnprintf(buffer, _SLOG_LINE_LENGTH, format, va);
|
||||
|
||||
va_end(va);
|
||||
|
||||
return buffer;
|
||||
(void) userdata;
|
||||
return emmalloc_malloc(size);
|
||||
}
|
||||
void compute_mvp(userdata_t *userdata)
|
||||
static void _free(void* ptr, void* userdata)
|
||||
{
|
||||
userdata->renderer.uniform.mvp.e[0][0] = (2.0f / userdata->width) * userdata->zoom;
|
||||
userdata->renderer.uniform.mvp.e[1][1] = (2.0f / userdata->height) * userdata->zoom;
|
||||
userdata->renderer.uniform.mvp.e[0][3] = (2.0f / userdata->width) * userdata->pan.x;
|
||||
userdata->renderer.uniform.mvp.e[1][3] = (2.0f / userdata->height) * userdata->pan.y;
|
||||
(void) userdata;
|
||||
emmalloc_free(ptr);
|
||||
}
|
||||
|
||||
static void refresh_SDF(userdata_t* ud)
|
||||
{
|
||||
//Get visible tiles
|
||||
float view_world_w = sapp_widthf() * ud->zoom;
|
||||
float view_world_h = sapp_heightf() * ud->zoom;
|
||||
box_t viewport = (box_t) {
|
||||
ud->pan_x - view_world_w * 0.5f,
|
||||
ud->pan_y - view_world_h * 0.5f,
|
||||
ud->pan_x + view_world_w * 0.5f,
|
||||
ud->pan_y + view_world_h * 0.5f,
|
||||
};
|
||||
|
||||
bool dirty = false;
|
||||
if(ud->scene.segment_dirty)
|
||||
{
|
||||
pool_view_grow(ud->compute.bindings.views[COMPUTE_VIEWIDX_segments], sizeof(segment_t), ud->scene.shapes.num_segments, ud->scene.shapes.segments);
|
||||
ud->scene.segment_dirty = false;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
if(ud->scene.shape_dirty)
|
||||
{
|
||||
pool_view_grow(ud->compute.bindings.views[COMPUTE_VIEWIDX_shapes], sizeof(shape_meta_t), ud->scene.shapes.num_shapes, ud->scene.shapes.shapes);
|
||||
ud->scene.shape_dirty = false;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
if(ud->scene.circle_dirty)
|
||||
{
|
||||
pool_view_grow(ud->compute.bindings.views[COMPUTE_VIEWIDX_circles], sizeof(circle_t), ud->scene.circles.num_circles, ud->scene.circles.circles);
|
||||
ud->scene.circle_dirty = false;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
if(dirty)
|
||||
{
|
||||
uint32_t tile_count = scene_process_tiles(&ud->scene, ud->pan_x, ud->pan_y, ud->zoom, &ud->compute.bindings);
|
||||
|
||||
if(tile_count > 0)
|
||||
{
|
||||
pool_view_grow(ud->compute.bindings.views[COMPUTE_VIEWIDX_tiles], sizeof(tile_task_t), tile_count, ud->scene.cache.tiles);
|
||||
pool_view_grow(ud->compute.bindings.views[COMPUTE_VIEWIDX_indices], sizeof(uint32_t), ud->scene.cache.num_indices, ud->scene.cache.indices);
|
||||
|
||||
sg_begin_pass(&ud->compute.pass);
|
||||
sg_apply_pipeline(ud->compute.pipeline);
|
||||
sg_apply_bindings(&ud->compute.bindings);
|
||||
|
||||
sg_dispatch(tile_count * 16, 16, 1);
|
||||
|
||||
sg_end_pass();
|
||||
}
|
||||
dirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
static sg_pass pass = (sg_pass){
|
||||
.label = "Render pass",
|
||||
};
|
||||
static simgui_frame_desc_t imgui_frame = {0};
|
||||
|
||||
static void compute_mvp(userdata_t *ud)
|
||||
{
|
||||
const float w = sapp_widthf();
|
||||
const float h = sapp_heightf();
|
||||
const float z = ud->zoom;
|
||||
const float px = ud->pan_x;
|
||||
const float py = ud->pan_y;
|
||||
float* mvp = ud->renderer.uniforms.mvp;
|
||||
|
||||
mvp[0] = (2.0f / w) * z;
|
||||
mvp[1] = 0.0f;
|
||||
mvp[2] = 0.0f;
|
||||
mvp[3] = (2.0f / w) * px;
|
||||
|
||||
mvp[4] = 0.0f;
|
||||
mvp[5] = (2.0f / h) * z;
|
||||
mvp[6] = 0.0f;
|
||||
mvp[7] = (2.0f / h) * py;
|
||||
|
||||
mvp[8] = 0.0f;
|
||||
mvp[9] = 0.0f;
|
||||
mvp[10] = 0.0f;
|
||||
mvp[11] = 0.0f;
|
||||
|
||||
mvp[12] = 0.0f;
|
||||
mvp[13] = 0.0f;
|
||||
mvp[14] = 0.0f;
|
||||
mvp[15] = 1.0f;
|
||||
}
|
||||
|
||||
static void frame(void* _userdata)
|
||||
{
|
||||
userdata_t* userdata = (userdata_t*) _userdata;
|
||||
userdata_t* ud = (userdata_t*) _userdata;
|
||||
|
||||
sg_begin_pass(&(sg_pass){
|
||||
.action = userdata->renderer.clear_pass,
|
||||
.swapchain = sglue_swapchain(),
|
||||
});
|
||||
ud->renderer.uniforms.frame = sapp_frame_count();
|
||||
ud->renderer.uniforms.time += (uint32_t) ceil(sapp_frame_duration_unfiltered() / 1000.0f);
|
||||
|
||||
const uint32_t length = vector_length(&userdata->manager.textures);
|
||||
if(length > 0)
|
||||
{
|
||||
sg_apply_pipeline(userdata->renderer.pipeline);
|
||||
refresh_SDF(ud);
|
||||
|
||||
for(uint32_t i = 0; i < length; i++)
|
||||
{
|
||||
texture_t* texture = (texture_t*) vector_get(&userdata->manager.textures, i);
|
||||
pass.swapchain = sglue_swapchain();
|
||||
sg_begin_pass(&pass);
|
||||
|
||||
if(texture->dirty)
|
||||
{
|
||||
const sg_range range = vector_range(&texture->sprites);
|
||||
sg_buffer buf = sg_query_view_buffer(texture->binding.views[1]);
|
||||
sg_update_buffer(buf, &range);
|
||||
texture->dirty = false;
|
||||
}
|
||||
imgui_frame.width = sapp_width(),
|
||||
imgui_frame.height = sapp_height(),
|
||||
imgui_frame.delta_time = sapp_frame_duration_unfiltered(),
|
||||
imgui_frame.dpi_scale = sapp_dpi_scale(),
|
||||
simgui_new_frame(&imgui_frame);
|
||||
|
||||
sg_apply_bindings(&texture->binding);
|
||||
sg_apply_uniforms(0, &SG_RANGE(userdata->renderer.uniform));
|
||||
igBegin("Framerate", (bool*) true, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar);
|
||||
igText("%.0f FPS", 1 / sapp_frame_duration_unfiltered());
|
||||
igText("%.3fms", sapp_frame_duration_unfiltered() * 1000);
|
||||
igEnd();
|
||||
|
||||
sg_draw(0, 6, vector_length(&texture->sprites));
|
||||
}
|
||||
}
|
||||
sg_apply_pipeline(ud->renderer.pipeline);
|
||||
sg_apply_uniforms(0, &SG_RANGE(ud->renderer.uniforms));
|
||||
sg_apply_bindings(&ud->renderer.bindings);
|
||||
sg_draw(0, 6, 1);
|
||||
|
||||
simgui_render();
|
||||
sg_end_pass();
|
||||
sg_commit();
|
||||
}
|
||||
|
||||
static void init(void* _userdata)
|
||||
{
|
||||
rand_seed(1);
|
||||
userdata_t* ud = (userdata_t*) _userdata;
|
||||
|
||||
userdata_t* userdata = (userdata_t*) _userdata;
|
||||
|
||||
sg_desc sgdesc = {
|
||||
sg_setup(&(sg_desc){
|
||||
.environment = sglue_environment(),
|
||||
.logger.func = slog_func,
|
||||
};
|
||||
sg_setup(&sgdesc);
|
||||
if (!sg_isvalid()) {
|
||||
fprintf(stderr, "Failed to create Sokol GFX context!\n");
|
||||
exit(-1);
|
||||
}
|
||||
.logger.func = log_fn,
|
||||
.allocator = {
|
||||
.alloc_fn = _malloc,
|
||||
.free_fn = _free,
|
||||
},
|
||||
});
|
||||
simgui_setup(&(simgui_desc_t){
|
||||
.allocator = {
|
||||
.alloc_fn = _malloc,
|
||||
.free_fn = _free,
|
||||
},
|
||||
});
|
||||
|
||||
const vec2f quad[4] = {
|
||||
{-2.0f, 2.0f}, // bottom left
|
||||
{2.0f, 2.0f}, // bottom right
|
||||
{2.0f, -2.0f}, // top right
|
||||
{-2.0f, -2.0f}, // top left
|
||||
ud->scene = (scene_t) {0};
|
||||
if(!scene_init(&ud->scene, (vec2) { 8192.0f, 8192.0f })) return;
|
||||
|
||||
ud->compute = (compute_t) {
|
||||
.pipeline = sg_make_pipeline(&(sg_pipeline_desc){
|
||||
.compute = true,
|
||||
.shader = sg_make_shader(&(sg_shader_desc) {
|
||||
.compute_func = {
|
||||
.source = (const char*) src_shaders_compute_wgsl,
|
||||
.entry = "main",
|
||||
},
|
||||
.views = {
|
||||
[COMPUTE_VIEWIDX_segments] = {
|
||||
.storage_buffer = {
|
||||
.stage = SG_SHADERSTAGE_COMPUTE,
|
||||
.wgsl_group1_binding_n = COMPUTE_VIEWIDX_segments,
|
||||
.readonly = true,
|
||||
}
|
||||
},
|
||||
[COMPUTE_VIEWIDX_shapes] = {
|
||||
.storage_buffer = {
|
||||
.stage = SG_SHADERSTAGE_COMPUTE,
|
||||
.wgsl_group1_binding_n = COMPUTE_VIEWIDX_shapes,
|
||||
.readonly = true,
|
||||
}
|
||||
},
|
||||
[COMPUTE_VIEWIDX_circles] = {
|
||||
.storage_buffer = {
|
||||
.stage = SG_SHADERSTAGE_COMPUTE,
|
||||
.wgsl_group1_binding_n = COMPUTE_VIEWIDX_circles,
|
||||
.readonly = true,
|
||||
}
|
||||
},
|
||||
[COMPUTE_VIEWIDX_tiles] = {
|
||||
.storage_buffer = {
|
||||
.stage = SG_SHADERSTAGE_COMPUTE,
|
||||
.wgsl_group1_binding_n = COMPUTE_VIEWIDX_tiles,
|
||||
.readonly = true,
|
||||
}
|
||||
},
|
||||
[COMPUTE_VIEWIDX_indices] = {
|
||||
.storage_buffer = {
|
||||
.stage = SG_SHADERSTAGE_COMPUTE,
|
||||
.wgsl_group1_binding_n = COMPUTE_VIEWIDX_indices,
|
||||
.readonly = true,
|
||||
}
|
||||
},
|
||||
[COMPUTE_VIEWIDX_SDF] = {
|
||||
.storage_image = {
|
||||
.stage = SG_SHADERSTAGE_COMPUTE,
|
||||
.wgsl_group1_binding_n = COMPUTE_VIEWIDX_SDF,
|
||||
.access_format = SG_PIXELFORMAT_R16F,
|
||||
.image_type = SG_IMAGETYPE_2D,
|
||||
.writeonly = true,
|
||||
}
|
||||
}
|
||||
},
|
||||
.label = "SDF Compute Shader",
|
||||
}),
|
||||
.label = "SDF Compute Pipeline",
|
||||
}),
|
||||
.bindings = (sg_bindings) {
|
||||
.views[COMPUTE_VIEWIDX_segments] = sg_make_view(&(sg_view_desc) {
|
||||
.label = "Segments view",
|
||||
.storage_buffer = {
|
||||
.buffer = sg_make_buffer(&(sg_buffer_desc) {
|
||||
.label = "Segment buffer",
|
||||
.usage = {
|
||||
.storage_buffer = true,
|
||||
.stream_update = true,
|
||||
},
|
||||
.size = sizeof(segment_t) * INITIAL_SEGMENTS_SIZE,
|
||||
}),
|
||||
},
|
||||
}),
|
||||
.views[COMPUTE_VIEWIDX_shapes] = sg_make_view(&(sg_view_desc) {
|
||||
.label = "Shapes metadata view",
|
||||
.storage_buffer = {
|
||||
.buffer = sg_make_buffer(&(sg_buffer_desc) {
|
||||
.label = "Shapes metadata buffer",
|
||||
.usage = {
|
||||
.storage_buffer = true,
|
||||
.stream_update = true,
|
||||
},
|
||||
.size = sizeof(shape_meta_t) * INITIAL_SHAPE_SIZE,
|
||||
}),
|
||||
},
|
||||
}),
|
||||
.views[COMPUTE_VIEWIDX_circles] = sg_make_view(&(sg_view_desc) {
|
||||
.label = "Circles view",
|
||||
.storage_buffer = {
|
||||
.buffer = sg_make_buffer(&(sg_buffer_desc) {
|
||||
.label = "Circles buffer",
|
||||
.usage = {
|
||||
.storage_buffer = true,
|
||||
.stream_update = true,
|
||||
},
|
||||
.size = sizeof(circle_t) * INITIAL_CIRCLE_SIZE,
|
||||
}),
|
||||
},
|
||||
}),
|
||||
.views[COMPUTE_VIEWIDX_tiles] = sg_make_view(&(sg_view_desc) {
|
||||
.label = "Tiles rebuild view",
|
||||
.storage_buffer = {
|
||||
.buffer = sg_make_buffer(&(sg_buffer_desc) {
|
||||
.label = "Tiles rebuild buffer",
|
||||
.usage = {
|
||||
.storage_buffer = true,
|
||||
.stream_update = true,
|
||||
},
|
||||
.size = sizeof(tile_task_t) * 256,
|
||||
}),
|
||||
},
|
||||
}),
|
||||
.views[COMPUTE_VIEWIDX_indices] = sg_make_view(&(sg_view_desc) {
|
||||
.label = "Culling indices view",
|
||||
.storage_buffer = {
|
||||
.buffer = sg_make_buffer(&(sg_buffer_desc) {
|
||||
.label = "Culling indices buffer",
|
||||
.usage = {
|
||||
.storage_buffer = true,
|
||||
.stream_update = true,
|
||||
},
|
||||
.size = sizeof(uint32_t) * INITIAL_INDICES_SIZE,
|
||||
}),
|
||||
},
|
||||
}),
|
||||
.views[COMPUTE_VIEWIDX_SDF] = ud->scene.texture,
|
||||
},
|
||||
.pass = { .compute = true, .label = "Compute Pass" }
|
||||
};
|
||||
const vec2f uv[4] = {
|
||||
|
||||
const vec2 quad[4] = {
|
||||
{ 0.0f, 1.0f }, // bottom left
|
||||
{ 1.0f, 1.0f }, // bottom right
|
||||
{ 1.0f, 0.0f }, // top right
|
||||
@@ -120,173 +326,137 @@ static void init(void* _userdata)
|
||||
0, 1, 2, 0, 2, 3,
|
||||
};
|
||||
|
||||
userdata->width = sapp_width();
|
||||
userdata->height = sapp_height();
|
||||
userdata->pan = (vec2f) { 0.0f, 0.0f };
|
||||
userdata->zoom = 2;
|
||||
|
||||
sg_shader sprite_shader = sg_make_shader(&(sg_shader_desc) {
|
||||
ud->renderer = (renderer_t) {
|
||||
.pipeline = sg_make_pipeline(&(sg_pipeline_desc) {
|
||||
.shader = sg_make_shader(&(sg_shader_desc) {
|
||||
.vertex_func = {
|
||||
.source = (const char*) src_shaders_sprite_wgsl,
|
||||
.source = (const char*) src_shaders_display_wgsl,
|
||||
.entry = "vs_main",
|
||||
},
|
||||
.fragment_func = {
|
||||
.source = (const char*) src_shaders_sprite_wgsl,
|
||||
.source = (const char*) src_shaders_display_wgsl,
|
||||
.entry = "fs_main",
|
||||
},
|
||||
.views = {
|
||||
[0] = {
|
||||
.texture = {
|
||||
.stage = SG_SHADERSTAGE_FRAGMENT,
|
||||
.image_type = SG_IMAGETYPE_2D,
|
||||
.wgsl_group1_binding_n = 0,
|
||||
.sample_type = SG_IMAGESAMPLETYPE_FLOAT,
|
||||
},
|
||||
},
|
||||
[1] = {
|
||||
.storage_buffer = {
|
||||
.stage = SG_SHADERSTAGE_VERTEX,
|
||||
.readonly = true,
|
||||
.wgsl_group1_binding_n = 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
.samplers = {
|
||||
[0] = {
|
||||
.stage = SG_SHADERSTAGE_FRAGMENT,
|
||||
.sampler_type = SG_SAMPLERTYPE_FILTERING,
|
||||
.wgsl_group1_binding_n = 1,
|
||||
}
|
||||
},
|
||||
.texture_sampler_pairs = {
|
||||
[0] = {
|
||||
.stage = SG_SHADERSTAGE_FRAGMENT,
|
||||
.view_slot = 0,
|
||||
.sampler_slot = 0,
|
||||
}
|
||||
},
|
||||
.uniform_blocks = {
|
||||
[0] = {
|
||||
.size = sizeof(uniform_t),
|
||||
.stage = SG_SHADERSTAGE_VERTEX,
|
||||
.wgsl_group0_binding_n = 0,
|
||||
},
|
||||
},
|
||||
.attrs[0] = {
|
||||
.base_type = SG_SHADERATTRBASETYPE_FLOAT,
|
||||
},
|
||||
.label = "Sprite shader",
|
||||
});
|
||||
|
||||
userdata->renderer = (renderer_t) {
|
||||
.clear_pass = (sg_pass_action) {
|
||||
.colors[0] = { .clear_value = { 0.0f, 0.0f, 0.0f, 1.0f }, .load_action = SG_LOADACTION_CLEAR }
|
||||
.views = {
|
||||
[DISPLAY_VIEWIDX_SDF] = {
|
||||
.texture = {
|
||||
.image_type = SG_IMAGETYPE_2D,
|
||||
.stage = SG_SHADERSTAGE_FRAGMENT,
|
||||
.wgsl_group1_binding_n = DISPLAY_VIEWIDX_SDF,
|
||||
.sample_type = SG_IMAGESAMPLETYPE_FLOAT,
|
||||
},
|
||||
.pipeline = sg_make_pipeline(&(sg_pipeline_desc) {
|
||||
.shader = sprite_shader,
|
||||
},
|
||||
},
|
||||
.uniform_blocks = {
|
||||
[0] = {
|
||||
.size = sizeof(display_uniforms),
|
||||
.stage = SG_SHADERSTAGE_VERTEX,
|
||||
.wgsl_group0_binding_n = 0,
|
||||
},
|
||||
},
|
||||
.label = "Display Shader",
|
||||
.samplers[DISPLAY_VIEWIDX_Sampler] = {
|
||||
.sampler_type = SG_SAMPLERTYPE_FILTERING,
|
||||
.stage = SG_SHADERSTAGE_FRAGMENT,
|
||||
.wgsl_group1_binding_n = DISPLAY_VIEWIDX_Sampler,
|
||||
},
|
||||
.texture_sampler_pairs[0] = {
|
||||
.sampler_slot = DISPLAY_VIEWIDX_Sampler,
|
||||
.view_slot = DISPLAY_VIEWIDX_SDF,
|
||||
.stage = SG_SHADERSTAGE_FRAGMENT,
|
||||
},
|
||||
}),
|
||||
.cull_mode = SG_CULLMODE_NONE,
|
||||
.index_type = SG_INDEXTYPE_UINT16,
|
||||
.layout.attrs = {
|
||||
[0].format = SG_VERTEXFORMAT_FLOAT2,
|
||||
[1].format = SG_VERTEXFORMAT_FLOAT2,
|
||||
},
|
||||
.label = "Sprite pipeline",
|
||||
.label = "Render pipeline",
|
||||
}),
|
||||
.uniform = (uniform_t) {
|
||||
.mvp = {
|
||||
1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
.bindings = {
|
||||
.index_buffer = sg_make_buffer(&(sg_buffer_desc) {
|
||||
.label = "Index buffer",
|
||||
.usage.index_buffer = true,
|
||||
.size = sizeof(indices),
|
||||
.data = SG_RANGE(indices),
|
||||
}),
|
||||
.vertex_buffers = {
|
||||
[0] = sg_make_buffer(&(sg_buffer_desc) {
|
||||
.label = "Vertex buffer",
|
||||
.usage.vertex_buffer = true,
|
||||
.size = sizeof(quad),
|
||||
.data = SG_RANGE(quad),
|
||||
})
|
||||
},
|
||||
.views = {
|
||||
[DISPLAY_VIEWIDX_SDF] = sg_make_view(&(sg_view_desc) {
|
||||
.texture.image = sg_query_view_image(ud->scene.texture),
|
||||
.label = "SDF texture view",
|
||||
}),
|
||||
},
|
||||
.samplers = {
|
||||
[DISPLAY_VIEWIDX_Sampler] = sg_make_sampler(&(sg_sampler_desc) {
|
||||
.label = "SDF sampler",
|
||||
}),
|
||||
}
|
||||
},
|
||||
.uniforms = {
|
||||
.frame = 0,
|
||||
.time = 0,
|
||||
.mvp = { 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0 },
|
||||
},
|
||||
};
|
||||
compute_mvp(ud);
|
||||
|
||||
pass.action = (sg_pass_action) {
|
||||
.colors[0] = { .clear_value = { 0.0f, 0.0f, 0.0f, 1.0f }, .load_action = SG_LOADACTION_CLEAR }
|
||||
};
|
||||
|
||||
gs_init(&userdata->manager);
|
||||
|
||||
compute_mvp(userdata);
|
||||
add_rectangle(&ud->scene, (vec2) { 200.0f, 100.0f }, (vec2) { 100.0f, 150.0f });
|
||||
add_circle(&ud->scene, (vec2) { 400.0f, 300.0f }, 125.0f);
|
||||
}
|
||||
|
||||
static void cleanup(void* _userdata)
|
||||
{
|
||||
userdata_t* userdata = (userdata_t*) _userdata;
|
||||
userdata_t* ud = (userdata_t*) _userdata;
|
||||
|
||||
vector_free(&userdata->manager.textures);
|
||||
|
||||
FREE(userdata);
|
||||
scene_shutdown(&ud->scene);
|
||||
emmalloc_free(ud);
|
||||
|
||||
simgui_shutdown();
|
||||
sg_shutdown();
|
||||
}
|
||||
|
||||
static void event(const sapp_event* event, void* _userdata)
|
||||
{
|
||||
userdata_t* userdata = (userdata_t*) _userdata;
|
||||
userdata_t* ud = (userdata_t*) _userdata;
|
||||
|
||||
switch(event->type)
|
||||
{
|
||||
case SAPP_EVENTTYPE_FILES_DROPPED:
|
||||
uint32_t files = sapp_get_num_dropped_files();
|
||||
|
||||
for(uint32_t i = 0; i < files; i++)
|
||||
{
|
||||
const uint32_t size = sapp_html5_get_dropped_file_size(i);
|
||||
|
||||
if(size > MAX_FILE_SIZE)
|
||||
{
|
||||
//Toast error
|
||||
continue;
|
||||
if (event->type == SAPP_EVENTTYPE_RESIZED) {
|
||||
//handle_resize(ud, event);
|
||||
}
|
||||
|
||||
void* buffer = malloc(size);
|
||||
|
||||
sapp_html5_fetch_dropped_file(&(sapp_html5_fetch_request) {
|
||||
.buffer = (sapp_range) { .ptr = buffer, .size = size },
|
||||
.dropped_file_index = i,
|
||||
.callback = gs_import_file,
|
||||
.user_data = userdata
|
||||
});
|
||||
if (event->type == SAPP_EVENTTYPE_KEY_DOWN) {
|
||||
//if (handle_key_down(ud, event)) return;
|
||||
}
|
||||
|
||||
break;
|
||||
case SAPP_EVENTTYPE_RESIZED:
|
||||
userdata->width = sapp_width();
|
||||
userdata->height = sapp_height();
|
||||
|
||||
compute_mvp(userdata);
|
||||
|
||||
break;
|
||||
case SAPP_EVENTTYPE_MOUSE_DOWN:
|
||||
if(event->modifiers & SAPP_MODIFIER_RMB)
|
||||
{
|
||||
userdata->dragger.dragging = true;
|
||||
userdata->dragger.origin_x = event->mouse_x;
|
||||
userdata->dragger.origin_y = event->mouse_y;
|
||||
}
|
||||
if (simgui_handle_event(event)) return;
|
||||
|
||||
switch (event->type) {
|
||||
/* case SAPP_EVENTTYPE_MOUSE_DOWN:
|
||||
handle_mouse_down(ud, event);
|
||||
break;
|
||||
case SAPP_EVENTTYPE_MOUSE_UP:
|
||||
userdata->dragger.dragging = false;
|
||||
|
||||
handle_mouse_up(ud, event);
|
||||
break;
|
||||
case SAPP_EVENTTYPE_MOUSE_MOVE:
|
||||
if(userdata->dragger.dragging)
|
||||
{
|
||||
userdata->pan.x += event->mouse_dx;
|
||||
userdata->pan.y -= event->mouse_dy;
|
||||
|
||||
compute_mvp(userdata);
|
||||
}
|
||||
|
||||
handle_mouse_move(ud, event);
|
||||
break;
|
||||
case SAPP_EVENTTYPE_MOUSE_SCROLL:
|
||||
if((userdata->zoom >= 6.0f && event->scroll_y > 0.0f) || (userdata->zoom <= 0.1f && event->scroll_y < 0.0f))
|
||||
return;
|
||||
|
||||
const float diff = expf(event->scroll_y * 0.01f);
|
||||
userdata->zoom = _sg_clamp(userdata->zoom * diff, 0.1f, 6.0f);
|
||||
|
||||
compute_mvp(userdata);
|
||||
|
||||
break;
|
||||
handle_scroll_zoom(ud, event);
|
||||
break; */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -294,7 +464,7 @@ static void event(const sapp_event* event, void* _userdata)
|
||||
|
||||
sapp_desc sokol_main(int argc, char* argv[])
|
||||
{
|
||||
userdata_t* userdata = (userdata_t*) ALLOC(sizeof(userdata_t));
|
||||
userdata_t* userdata = (userdata_t*) emmalloc_malloc(sizeof(userdata_t));
|
||||
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
@@ -305,10 +475,10 @@ sapp_desc sokol_main(int argc, char* argv[])
|
||||
.cleanup_userdata_cb = cleanup,
|
||||
.event_userdata_cb = event,
|
||||
.window_title = "Sokol",
|
||||
.logger.func = slog_func,
|
||||
.allocator = {
|
||||
.alloc_fn = smemtrack_alloc,
|
||||
.free_fn = smemtrack_free,
|
||||
.alloc_fn = _malloc,
|
||||
.free_fn = _free,
|
||||
},
|
||||
.logger.func = log_fn,
|
||||
};
|
||||
}
|
||||
49
src/math.h
49
src/math.h
@@ -1,49 +0,0 @@
|
||||
#ifndef MATH_IMPL_H
|
||||
#define MATH_IMPL_H
|
||||
|
||||
#include "api.h"
|
||||
|
||||
#define PI 3.14159265358979323846
|
||||
#define PI32 3.14159265359f
|
||||
|
||||
typedef struct vec2f {
|
||||
float x, y;
|
||||
} vec2f;
|
||||
typedef struct vec3f {
|
||||
float x, y, z;
|
||||
} vec3f;
|
||||
typedef struct vec4f {
|
||||
float x, y, z, w;
|
||||
} vec4f;
|
||||
|
||||
typedef struct vec2u {
|
||||
uint32_t x, y;
|
||||
} vec2u;
|
||||
typedef struct vec3u {
|
||||
uint32_t x, y, z;
|
||||
} vec3u;
|
||||
typedef struct vec4u {
|
||||
uint32_t x, y, z, w;
|
||||
} vec4u;
|
||||
|
||||
typedef struct vec2 {
|
||||
int32_t x, y;
|
||||
} vec2;
|
||||
typedef struct vec3 {
|
||||
int32_t x, y, z;
|
||||
} vec3;
|
||||
typedef struct vec4 {
|
||||
int32_t x, y, z, w;
|
||||
} vec4;
|
||||
|
||||
typedef struct mat4x4f {
|
||||
float e[4][4];
|
||||
} mat4x4f;
|
||||
typedef struct mat4x4u {
|
||||
uint32_t e[4][4];
|
||||
} mat4x4u;
|
||||
typedef union mat4x4 {
|
||||
int32_t e[4][4];
|
||||
} mat4x4;
|
||||
|
||||
#endif
|
||||
36
src/pool.h
Normal file
36
src/pool.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#include "api.h"
|
||||
|
||||
#define MAX_BUFFER_SIZE 1024 * 1024 * 1024 // 1GB
|
||||
|
||||
static void pool_buffer_grow(sg_buffer buffer, uint32_t stripe, uint32_t count, void* data)
|
||||
{
|
||||
size_t size = sg_query_buffer_size(buffer);
|
||||
if(size == MAX_BUFFER_SIZE) return sg_update_buffer(buffer, &(sg_range) { data, MAX_BUFFER_SIZE });
|
||||
if(size < stripe * count)
|
||||
{
|
||||
sg_buffer_desc desc = sg_query_buffer_desc(buffer);
|
||||
while(desc.size < stripe * count) desc.size = fmaxf(MAX_BUFFER_SIZE, size * 2);
|
||||
|
||||
sg_uninit_buffer(buffer);
|
||||
sg_init_buffer(buffer, &desc);
|
||||
}
|
||||
|
||||
sg_update_buffer(buffer, &(sg_range) { data, stripe * count });
|
||||
}
|
||||
static void pool_view_grow(sg_view view, uint32_t stripe, uint32_t count, void* data)
|
||||
{
|
||||
sg_buffer buffer = sg_query_view_buffer(view);
|
||||
|
||||
size_t size = sg_query_buffer_size(buffer);
|
||||
if(size == MAX_BUFFER_SIZE) return sg_update_buffer(buffer, &(sg_range) { data, MAX_BUFFER_SIZE });
|
||||
if(size < stripe * count)
|
||||
{
|
||||
sg_buffer_desc desc = sg_query_buffer_desc(buffer);
|
||||
while(desc.size < stripe * count) desc.size = fmaxf(MAX_BUFFER_SIZE, size * 2);
|
||||
|
||||
sg_uninit_buffer(buffer);
|
||||
sg_init_buffer(buffer, &desc);
|
||||
}
|
||||
|
||||
sg_update_buffer(buffer, &(sg_range) { data, stripe * count });
|
||||
}
|
||||
66
src/rand.h
66
src/rand.h
@@ -1,66 +0,0 @@
|
||||
#ifndef RAND_H
|
||||
#define RAND_H
|
||||
|
||||
#include "api.h"
|
||||
|
||||
static uint32_t seed;
|
||||
|
||||
static uint32_t xorshift32(void);
|
||||
static void rand_seed(uint32_t _seed);
|
||||
static uint32_t next_int(void);
|
||||
static uint32_t next_int_max(uint32_t max);
|
||||
static uint32_t next_int_minmax(uint32_t min, uint32_t max);
|
||||
static float next_float(void);
|
||||
static float next_float_max(float max);
|
||||
static float next_float_minmax(float min, float max);
|
||||
|
||||
static uint32_t xorshift32(void)
|
||||
{
|
||||
seed ^= seed<<13;
|
||||
seed ^= seed>>17;
|
||||
seed ^= seed<<5;
|
||||
return seed;
|
||||
}
|
||||
static void rand_seed(uint32_t _seed)
|
||||
{
|
||||
if(_seed == 0)
|
||||
return;
|
||||
|
||||
seed = _seed;
|
||||
xorshift32();
|
||||
}
|
||||
// PRNG [0-UINT32_MAX]
|
||||
static uint32_t next_int(void)
|
||||
{
|
||||
return xorshift32();
|
||||
}
|
||||
// PRNG [0-max]
|
||||
static uint32_t next_int_max(uint32_t max)
|
||||
{
|
||||
return (uint32_t) floorf(xorshift32() / (float) UINT32_MAX * max);
|
||||
}
|
||||
// PRNG [min-max]
|
||||
static uint32_t next_int_minmax(uint32_t min, uint32_t max)
|
||||
{
|
||||
const float x = (float) xorshift32() / UINT32_MAX;
|
||||
//(1.0f - Time) * A + Time * B
|
||||
return (1.0f - x) * min + x * max;
|
||||
}
|
||||
// PRNG [0-1]
|
||||
static float next_float(void)
|
||||
{
|
||||
return (float) xorshift32() / UINT32_MAX;
|
||||
}
|
||||
// PRNG [0-max]
|
||||
static float next_float_max(float max)
|
||||
{
|
||||
return (float) xorshift32() / UINT32_MAX * max;
|
||||
}
|
||||
// PRNG [min-max]
|
||||
static float next_float_minmax(float min, float max)
|
||||
{
|
||||
const float x = (float) xorshift32() / UINT32_MAX;
|
||||
return (1.0f - x) * min + x * max;
|
||||
}
|
||||
|
||||
#endif
|
||||
235
src/shaders/compute.wgsl
Normal file
235
src/shaders/compute.wgsl
Normal file
@@ -0,0 +1,235 @@
|
||||
struct Segment {
|
||||
p0: vec2f,
|
||||
p1: vec2f,
|
||||
p2: vec2f,
|
||||
p3: vec2f,
|
||||
}
|
||||
struct ShapeMeta {
|
||||
start_segment: u32, //Offset in the segments buffer
|
||||
segment_count: u32,
|
||||
bbox_min: vec2f,
|
||||
bbox_max: vec2f,
|
||||
}
|
||||
struct Circle {
|
||||
center: vec2f,
|
||||
radius: f32,
|
||||
}
|
||||
struct Tile {
|
||||
world_min: vec2f,
|
||||
world_max: vec2f,
|
||||
offset: u32,
|
||||
circle_count: u32,
|
||||
count: u32,
|
||||
};
|
||||
|
||||
@group(1) @binding(0) var<storage> segments: array<Segment>;
|
||||
@group(1) @binding(1) var<storage> shapes: array<ShapeMeta>;
|
||||
@group(1) @binding(2) var<storage> circles: array<Circle>;
|
||||
@group(1) @binding(3) var<storage> tiles: array<Tile>;
|
||||
@group(1) @binding(4) var<storage> indices: array<u32>;
|
||||
@group(1) @binding(5) var sdf_buffer: texture_storage_2d<r16float, write>;
|
||||
|
||||
override TILE_SIZE: u32 = 256u;
|
||||
|
||||
// ---------- Cubic Bézier helpers ----------
|
||||
fn eval_cubic(t: f32, p0: vec2f, p1: vec2f, p2: vec2f, p3: vec2f) -> vec2f {
|
||||
let mt = 1.0 - t;
|
||||
let mt2 = mt * mt;
|
||||
let t2 = t * t;
|
||||
return mt2 * mt * p0 + 3.0 * mt2 * t * p1 + 3.0 * mt * t2 * p2 + t2 * t * p3;
|
||||
}
|
||||
|
||||
fn eval_cubic_derivative(t: f32, p0: vec2f, p1: vec2f, p2: vec2f, p3: vec2f) -> vec2f {
|
||||
let mt = 1.0 - t;
|
||||
return 3.0 * mt * mt * (p1 - p0) + 6.0 * mt * t * (p2 - p1) + 3.0 * t * t * (p3 - p2);
|
||||
}
|
||||
|
||||
// ---------- Distance to a cubic Bézier (sampling + Newton refinement) ----------
|
||||
fn distance_to_cubic(p: vec2f, seg: Segment) -> f32 {
|
||||
let p0 = seg.p0; let p1 = seg.p1; let p2 = seg.p2; let p3 = seg.p3;
|
||||
|
||||
// Uniform sampling to find a good starting t
|
||||
let samples = 16u;
|
||||
var best_t = 0.0;
|
||||
var best_dist = 1e20;
|
||||
for (var i = 0u; i < samples; i++) {
|
||||
let t = f32(i) / f32(samples - 1u);
|
||||
let q = eval_cubic(t, p0, p1, p2, p3);
|
||||
let d = distance(p, q);
|
||||
if d < best_dist {
|
||||
best_dist = d;
|
||||
best_t = t;
|
||||
}
|
||||
}
|
||||
|
||||
// Newton refinement on the squared distance (max 4 iterations)
|
||||
var t = clamp(best_t, 0.0, 1.0);
|
||||
for (var iter = 0u; iter < 4u; iter++) {
|
||||
let B = eval_cubic(t, p0, p1, p2, p3) - p;
|
||||
let Bp = eval_cubic_derivative(t, p0, p1, p2, p3);
|
||||
let f = dot(B, Bp); // ½ derivative of |B|²
|
||||
let df = dot(Bp, Bp) + dot(B, 3.0 * (p2 - p1 + (p3 - p2 - p2 + p1) * 2.0 * t)); // simplified 2nd deriv
|
||||
if abs(df) < 1e-12 { break; }
|
||||
let step = f / df;
|
||||
t = clamp(t - step, 0.0, 1.0);
|
||||
if abs(step) < 1e-6 { break; }
|
||||
}
|
||||
let q_final = eval_cubic(t, p0, p1, p2, p3);
|
||||
return distance(p, q_final);
|
||||
}
|
||||
|
||||
// ---------- Analytical cubic root solver (for y-crossing) ----------
|
||||
// Returns number of real roots in [0,1], stored in roots array (up to 3).
|
||||
fn solve_cubic_in_01(c3: f32, c2: f32, c1: f32, c0: f32, roots: ptr<function, array<f32, 3>>) -> u32 {
|
||||
// Normalise: c3 * t^3 + c2 * t^2 + c1 * t + c0 = 0
|
||||
if abs(c3) < 1e-9 {
|
||||
// Quadratic fallback
|
||||
if abs(c2) < 1e-9 {
|
||||
if abs(c1) < 1e-9 { return 0u; }
|
||||
let t = -c0 / c1;
|
||||
if t >= 0.0 && t <= 1.0 {
|
||||
(*roots)[0] = t;
|
||||
return 1u;
|
||||
}
|
||||
return 0u;
|
||||
}
|
||||
let disc = c1 * c1 - 4.0 * c2 * c0;
|
||||
if disc < 0.0 { return 0u; }
|
||||
let sd = sqrt(disc);
|
||||
let t0 = (-c1 + sd) / (2.0 * c2);
|
||||
let t1 = (-c1 - sd) / (2.0 * c2);
|
||||
var count = 0u;
|
||||
if t0 >= 0.0 && t0 <= 1.0 { (*roots)[count] = t0; count++; }
|
||||
if t1 >= 0.0 && t1 <= 1.0 { (*roots)[count] = t1; count++; }
|
||||
return count;
|
||||
}
|
||||
|
||||
// Depressed cubic: let t = x - c2/(3*c3)
|
||||
let a = c2 / c3;
|
||||
let b = c1 / c3;
|
||||
let c = c0 / c3;
|
||||
let p = b - a * a / 3.0;
|
||||
let q = 2.0 * a * a * a / 27.0 - a * b / 3.0 + c;
|
||||
let disc = q * q / 4.0 + p * p * p / 27.0;
|
||||
|
||||
var count = 0u;
|
||||
let shift = a / 3.0;
|
||||
|
||||
if disc > 0.0 {
|
||||
let sd = sqrt(disc);
|
||||
let u = sign(-q/2.0 + sd) * pow(abs(-q/2.0 + sd), 1.0/3.0);
|
||||
let v = sign(-q/2.0 - sd) * pow(abs(-q/2.0 - sd), 1.0/3.0);
|
||||
let x1 = u + v;
|
||||
let t = x1 - shift;
|
||||
if t >= 0.0 && t <= 1.0 { (*roots)[count] = t; count++; }
|
||||
} else if disc == 0.0 {
|
||||
let u = sign(-q/2.0) * pow(abs(-q/2.0), 1.0/3.0);
|
||||
let x1 = 2.0 * u;
|
||||
let x2 = -u;
|
||||
let t1 = x1 - shift;
|
||||
let t2 = x2 - shift;
|
||||
if t1 >= 0.0 && t1 <= 1.0 { (*roots)[count] = t1; count++; }
|
||||
if t2 >= 0.0 && t2 <= 1.0 { (*roots)[count] = t2; count++; }
|
||||
} else {
|
||||
let phi = acos( -q / (2.0 * sqrt(-p*p*p/27.0)) );
|
||||
let r = 2.0 * sqrt(-p/3.0);
|
||||
for (var k = 0u; k < 3u; k++) {
|
||||
let x = r * cos((phi + 2.0 * 3.1415926535 * f32(k)) / 3.0);
|
||||
let t = x - shift;
|
||||
if t >= 0.0 && t <= 1.0 { (*roots)[count] = t; count++; }
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
// ---------- Winding number contribution from one cubic segment ----------
|
||||
fn ray_intersections_cubic(p: vec2f, seg: Segment) -> i32 {
|
||||
// We cast a horizontal ray from p to +x; find t where y(t) = p.y
|
||||
let y0 = seg.p0.y - p.y;
|
||||
let y1 = seg.p1.y - p.y;
|
||||
let y2 = seg.p2.y - p.y;
|
||||
let y3 = seg.p3.y - p.y;
|
||||
|
||||
// y(t) = (1-t)^3*y0 + 3(1-t)^2 t * y1 + 3(1-t) t^2 * y2 + t^3 * y3 = 0
|
||||
// Expand polynomial: c3 t^3 + c2 t^2 + c1 t + c0
|
||||
let c0 = y0;
|
||||
let c1 = 3.0 * (y1 - y0);
|
||||
let c2 = 3.0 * (y2 - 2.0 * y1 + y0);
|
||||
let c3 = y3 - 3.0 * y2 + 3.0 * y1 - y0;
|
||||
|
||||
var roots: array<f32, 3>;
|
||||
let num = solve_cubic_in_01(c3, c2, c1, c0, &roots);
|
||||
var wind = 0i;
|
||||
for (var i = 0u; i < num; i++) {
|
||||
let t = roots[i];
|
||||
let x = eval_cubic(t, seg.p0, seg.p1, seg.p2, seg.p3).x;
|
||||
if x > p.x {
|
||||
let dy = eval_cubic_derivative(t, seg.p0, seg.p1, seg.p2, seg.p3).y;
|
||||
if dy > 0.0 { wind += 1i; }
|
||||
else if dy < 0.0 { wind -= 1i; }
|
||||
}
|
||||
}
|
||||
return wind;
|
||||
}
|
||||
|
||||
// ---------- Main compute shader ----------
|
||||
@compute @workgroup_size(8, 8)
|
||||
fn main(@builtin(workgroup_id) wg: vec3<u32>, // each workgroup is a tile
|
||||
@builtin(local_invocation_id) local: vec3<u32>) // each local invocation is a pixel
|
||||
{
|
||||
let tile_idx = wg.x / 16u;
|
||||
let tile = tiles[tile_idx];
|
||||
|
||||
let px = (wg.x % 16u) * 8u + local.x;
|
||||
let py = wg.y * 8u + local.y;
|
||||
|
||||
if (px >= TILE_SIZE || py >= TILE_SIZE) {
|
||||
return;
|
||||
}
|
||||
|
||||
let uv = (vec2f(f32(px), f32(py)) + 0.5) / f32(TILE_SIZE);
|
||||
let world = mix(tile.world_min, tile.world_max, uv);
|
||||
|
||||
var minDist: f32 = 1e20;
|
||||
var sdf: f32 = 1e20;
|
||||
var winding: i32 = 0;
|
||||
|
||||
for (var s = 0u; s < tile.count; s++) {
|
||||
// Use a pre-culled shape range per tile to reduce the per-pixel processing time
|
||||
let index = indices[tile.offset + s];
|
||||
|
||||
// If the index is lower than the circle count, it mean we are processing circles
|
||||
if(index < tile.circle_count)
|
||||
{
|
||||
let c = circles[index];
|
||||
sdf = min(sdf, length(world - c.center) - c.radius);
|
||||
}
|
||||
else
|
||||
{
|
||||
let shape = shapes[index];
|
||||
|
||||
/*let bbox_min = shape.bbox_min;
|
||||
let bbox_max = shape.bbox_max;
|
||||
let dx = max(bbox_min.x - world.x, max(0.0, world.x - bbox_max.x));
|
||||
let dy = max(bbox_min.y - world.y, max(0.0, world.y - bbox_max.y));
|
||||
let dist_to_box = sqrt(dx * dx + dy * dy);
|
||||
if dist_to_box >= minDist {
|
||||
continue;
|
||||
}*/
|
||||
|
||||
// Process all segments of the shape
|
||||
for (var i = shape.start_segment; i < shape.start_segment + shape.segment_count; i++) {
|
||||
let seg = segments[i];
|
||||
let d = distance_to_cubic(world, seg);
|
||||
minDist = min(minDist, d);
|
||||
|
||||
winding += ray_intersections_cubic(world, seg);
|
||||
}
|
||||
|
||||
let sign = select(1.0, -1.0, winding != 0i);
|
||||
sdf = min(sdf, sign * minDist);
|
||||
}
|
||||
}
|
||||
|
||||
textureStore(sdf_buffer, vec2(u32(world.x), u32(world.y)), vec4f(sdf, 0.0, 0.0, 1.0));
|
||||
}
|
||||
20
src/shaders/display.wgsl
Normal file
20
src/shaders/display.wgsl
Normal file
@@ -0,0 +1,20 @@
|
||||
struct Uniforms {
|
||||
time: u32,
|
||||
frame: u32,
|
||||
mvp: mat4x4f,
|
||||
}
|
||||
|
||||
@group(0) @binding(0) var<uniform> uniforms: Uniforms;
|
||||
|
||||
@group(1) @binding(0) var sdf : texture_2d<f32>;
|
||||
@group(1) @binding(1) var sdf_sampler : sampler;
|
||||
|
||||
@vertex fn vs_main(@location(0) position: vec2f) -> @builtin(position) vec4f
|
||||
{
|
||||
return vec4f(position, 0.0, 1.0) * uniforms.mvp;
|
||||
}
|
||||
|
||||
@fragment fn fs_main(@builtin(position) position: vec4f) -> @location(0) vec4f
|
||||
{
|
||||
return textureSample(sdf, sdf_sampler, position.xy);
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
struct Sprite {
|
||||
matrix: mat4x4f,
|
||||
};
|
||||
struct VsUniform {
|
||||
mvp: mat4x4f,
|
||||
};
|
||||
struct VsI { //Vertex shader input
|
||||
@builtin(instance_index) instance: u32,
|
||||
@location(0) position: vec2f,
|
||||
@location(1) uv: vec2f,
|
||||
};
|
||||
struct Vs2Fs { //Vertex shader to Fragment shader
|
||||
@builtin(position) pos: vec4f,
|
||||
@location(0) @interpolate(linear) uv: vec2f,
|
||||
};
|
||||
struct FsO { //Fragment shader output
|
||||
@location(0) color: vec4f,
|
||||
};
|
||||
|
||||
@binding(0) @group(0) var<uniform> vs_uniforms: VsUniform;
|
||||
@binding(0) @group(1) var tex: texture_2d<f32>;
|
||||
@binding(1) @group(1) var samp: sampler;
|
||||
@binding(2) @group(1) var<storage> sprites: array<Sprite>;
|
||||
|
||||
@vertex fn vs_main(input: VsI) -> Vs2Fs {
|
||||
var output: Vs2Fs;
|
||||
|
||||
output.pos = vec4f(input.position.x, input.position.y, 0, 0) * sprites[input.instance].matrix * vs_uniforms.mvp;
|
||||
output.uv = input.uv;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
// Convert a 32bit uint color (hex representation) into a normalized vec4f
|
||||
/*fn convertColor(input: u32) -> vec4f {
|
||||
let r: f32 = f32(((input >> 0) & 0xff));
|
||||
let g: f32 = f32(((input >> 8) & 0xff));
|
||||
let b: f32 = f32(((input >> 16) & 0xff));
|
||||
let a: f32 = f32(((input >> 24) & 0xff));
|
||||
|
||||
return vec4f(r / 255, g / 255, b / 255, a / 255);
|
||||
}*/
|
||||
// Get the texture array index from the UV
|
||||
/*fn indexFromCoord(uv: vec2f, width: u32, height: u32) -> u32 {
|
||||
let x: u32 = clamp(floor(uv.x * f32(width)), 0, width);
|
||||
let y: u32 = clamp(floor(uv.y * f32(height)), 0, height);
|
||||
return y * width + x;
|
||||
}*/
|
||||
|
||||
@fragment fn fs_main(input: Vs2Fs) -> FsO {
|
||||
var output: FsO;
|
||||
|
||||
output.color = textureSample(tex, samp, input.uv);
|
||||
|
||||
return output;
|
||||
}
|
||||
363
src/shape.h
Normal file
363
src/shape.h
Normal file
@@ -0,0 +1,363 @@
|
||||
#include "api.h"
|
||||
|
||||
typedef struct uvec2 { uint32_t x, y; } uvec2;
|
||||
typedef struct vec2 { float x, y; } vec2;
|
||||
|
||||
typedef struct ubox_t {
|
||||
uint32_t min_x, min_y, max_x, max_y;
|
||||
} ubox_t;
|
||||
typedef struct box_t {
|
||||
float min_x, min_y, max_x, max_y;
|
||||
} box_t;
|
||||
|
||||
#define BOX_INTERSECTS(a, b) !(b.min_x > a.max_x \
|
||||
|| b.max_x < a.min_x \
|
||||
|| b.min_y > a.max_y \
|
||||
|| b.max_y < a.min_y)
|
||||
|
||||
#define CIRCLE_INTERSECTS(box, circle) !(circle.center.x - circle.radius > box.max_x \
|
||||
|| circle.center.x + circle.radius < box.min_x \
|
||||
|| circle.center.y - circle.radius > box.max_y \
|
||||
|| circle.center.y + circle.radius < box.min_y)
|
||||
|
||||
typedef struct segment_t {
|
||||
vec2 p0, p1, p2, p3; // cubic Bézier: start, control1, control2, end
|
||||
} segment_t;
|
||||
|
||||
typedef struct shape_meta_t {
|
||||
uint32_t start_segment; // index into global segments array
|
||||
uint32_t segment_count; // number of segments forming this closed loop
|
||||
box_t aabb;
|
||||
} shape_meta_t;
|
||||
|
||||
typedef struct circle_t {
|
||||
vec2 center;
|
||||
float radius;
|
||||
} circle_t;
|
||||
|
||||
#define TILE_SIZE 256 // texels per tile
|
||||
|
||||
#define TILE_COUNT(size) (uint32_t)ceilf(size.x / TILE_SIZE) * (uint32_t)ceilf(size.y / TILE_SIZE)
|
||||
|
||||
#define INITIAL_SHAPE_SIZE 256
|
||||
#define INITIAL_SEGMENTS_SIZE 8192
|
||||
#define INITIAL_CIRCLE_SIZE 1024
|
||||
#define INITIAL_INDICES_SIZE 16384
|
||||
|
||||
// Tile metadata for targetted updates
|
||||
typedef struct tile_task_t {
|
||||
box_t bounds;
|
||||
uint32_t offset;
|
||||
uint32_t circle_count;
|
||||
uint32_t count;
|
||||
} tile_task_t;
|
||||
|
||||
typedef struct scene_t {
|
||||
vec2 world_size;
|
||||
|
||||
struct {
|
||||
uint32_t num_shapes;
|
||||
uint32_t max_shapes;
|
||||
shape_meta_t* shapes;
|
||||
|
||||
uint32_t num_segments;
|
||||
uint32_t max_segments;
|
||||
segment_t* segments;
|
||||
} shapes;
|
||||
|
||||
struct {
|
||||
uint32_t num_circles;
|
||||
uint32_t max_circles;
|
||||
circle_t* circles;
|
||||
} circles;
|
||||
|
||||
struct {
|
||||
tile_task_t* tiles; // Array of tiles metadata for the compute buffer
|
||||
bool* tile_dirty; // Array of tiles state, since this info don't needs to be uploaded to the GPU, it is stored separately
|
||||
|
||||
uint32_t max_indices;
|
||||
uint32_t num_indices;
|
||||
uint32_t* indices; // Array of shapes/circles indices per tile, pre culled on the CPU side
|
||||
} cache;
|
||||
|
||||
sg_view texture; //Layer count depends on the world size so the texture has to be allocate on the scene side
|
||||
|
||||
bool shape_dirty, segment_dirty, circle_dirty;
|
||||
} scene_t;
|
||||
|
||||
// Initialise a scene_t with a given capacity for shapes and segments.
|
||||
static uint32_t scene_init(scene_t* s, vec2 world_size) {
|
||||
s->shapes.num_shapes = 0;
|
||||
s->shapes.max_shapes = INITIAL_SHAPE_SIZE;
|
||||
s->shapes.shapes = (shape_meta_t*) emmalloc_malloc(INITIAL_SHAPE_SIZE * sizeof(shape_meta_t));
|
||||
|
||||
s->shapes.num_segments = 0;
|
||||
s->shapes.max_segments = INITIAL_SEGMENTS_SIZE;
|
||||
s->shapes.segments = (segment_t*) emmalloc_malloc(INITIAL_SEGMENTS_SIZE * sizeof(segment_t));
|
||||
|
||||
s->circles.num_circles = 0;
|
||||
s->circles.max_circles = INITIAL_SEGMENTS_SIZE;
|
||||
s->circles.circles = (circle_t*) emmalloc_malloc(INITIAL_CIRCLE_SIZE * sizeof(circle_t));
|
||||
|
||||
const uint32_t tile_count_x = (uint32_t)ceilf(world_size.x / TILE_SIZE), tile_count_y = (uint32_t)ceilf(world_size.y / TILE_SIZE);
|
||||
const uint32_t tile_count = tile_count_x * tile_count_y;
|
||||
s->cache.tiles = (tile_task_t*) emmalloc_malloc(sizeof(tile_task_t) * tile_count);
|
||||
s->cache.tile_dirty = (bool*) emmalloc_malloc(sizeof(bool) * tile_count);
|
||||
|
||||
uint32_t idx = 0;
|
||||
for(uint32_t y = 0; y < tile_count_y; y++)
|
||||
{
|
||||
for(uint32_t x = 0; x < tile_count_x; x++)
|
||||
{
|
||||
s->cache.tile_dirty[idx] = true;
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
|
||||
s->cache.max_indices = INITIAL_INDICES_SIZE;
|
||||
s->cache.num_indices = 0;
|
||||
s->cache.indices = (uint32_t*) emmalloc_malloc(sizeof(uint32_t) * INITIAL_INDICES_SIZE);
|
||||
|
||||
s->world_size = world_size;
|
||||
s->texture = sg_make_view(&(sg_view_desc) {
|
||||
.label = "SDF tiles view",
|
||||
.storage_image = {
|
||||
.image = sg_make_image(&(sg_image_desc) {
|
||||
.width = (uint32_t) ceilf(world_size.x),
|
||||
.height = (uint32_t) ceilf(world_size.y),
|
||||
.label = "SDF tiles texture",
|
||||
.pixel_format = SG_PIXELFORMAT_R16F,
|
||||
.type = SG_IMAGETYPE_2D,
|
||||
.usage = { .storage_image = true },
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
if (!s->shapes.shapes || !s->shapes.segments || !s->circles.circles || !s->cache.indices || !s->cache.tiles || !s->cache.tile_dirty) return 0; // allocation failure
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define COORD_TO_INDEX(x, y, scene) y * ceilf(s->world_size.x / TILE_SIZE) + x
|
||||
|
||||
static void scene_compute_culling(scene_t* s, tile_task_t* task)
|
||||
{
|
||||
task->count = 0;
|
||||
for(uint32_t i = 0; i < s->circles.num_circles; i++)
|
||||
{
|
||||
if(CIRCLE_INTERSECTS(task->bounds, s->circles.circles[i]))
|
||||
{
|
||||
if(s->cache.num_indices >= s->cache.max_indices)
|
||||
{
|
||||
s->cache.max_indices *= 2;
|
||||
s->cache.indices = emmalloc_realloc(s->cache.indices, s->cache.max_indices * sizeof(uint32_t));
|
||||
}
|
||||
s->cache.indices[s->cache.num_indices++] = i;
|
||||
task->count++;
|
||||
}
|
||||
}
|
||||
task->circle_count = task->count;
|
||||
for(uint32_t i = 0; i < s->shapes.num_shapes; i++)
|
||||
{
|
||||
if(BOX_INTERSECTS(task->bounds, s->shapes.shapes[i].aabb))
|
||||
{
|
||||
if(s->cache.num_indices >= s->cache.max_indices)
|
||||
{
|
||||
s->cache.max_indices *= 2;
|
||||
s->cache.indices = emmalloc_realloc(s->cache.indices, s->cache.max_indices * sizeof(uint32_t));
|
||||
}
|
||||
s->cache.indices[s->cache.num_indices++] = i;
|
||||
task->count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Find the proper LOD, the relevant tiles then run the culling process for the dirty tiles and upload data to the GPU for SDF rendering
|
||||
static uint32_t scene_process_tiles(scene_t* s, float pan_x, float pan_y, float zoom, sg_bindings* bindings)
|
||||
{
|
||||
const float width = (float)sapp_width(), height = (float) sapp_height();
|
||||
const float wpp = fmaxf(s->world_size.y / zoom / height, s->world_size.x / zoom / width); //World point per pixel
|
||||
|
||||
float view_w = width * wpp, view_h = height * wpp;
|
||||
box_t frustum = {
|
||||
.min_x = ceilf((pan_x - view_w * 0.5) / TILE_SIZE),
|
||||
.min_y = ceilf((pan_y - view_h * 0.5) / TILE_SIZE),
|
||||
.max_x = ceilf((pan_x + view_w * 0.5) / TILE_SIZE),
|
||||
.max_y = ceilf((pan_y + view_h * 0.5) / TILE_SIZE)
|
||||
};
|
||||
|
||||
uint32_t dirty_tile_count = 0, offset = 0;
|
||||
for(uint32_t y = frustum.min_y; y < frustum.max_y; y++)
|
||||
{
|
||||
for(uint32_t x = frustum.min_x; x < frustum.max_x; x++)
|
||||
{
|
||||
uint32_t idx = COORD_TO_INDEX(x, y, s);
|
||||
if(s->cache.tile_dirty[idx])
|
||||
{
|
||||
tile_task_t* task = &s->cache.tiles[dirty_tile_count++];
|
||||
task->bounds.min_x = x * TILE_SIZE;
|
||||
task->bounds.min_y = y * TILE_SIZE;
|
||||
task->bounds.max_x = fminf((x + 1) * TILE_SIZE, s->world_size.x);
|
||||
task->bounds.max_y = fminf((y + 1) * TILE_SIZE, s->world_size.y);
|
||||
|
||||
task->offset = offset;
|
||||
scene_compute_culling(s, task);
|
||||
offset += task->count;
|
||||
|
||||
s->cache.tile_dirty[idx] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dirty_tile_count;
|
||||
}
|
||||
|
||||
// Append a segment, returns its index. (Reallocs if needed, simplified.)
|
||||
static uint32_t scene_add_segment(scene_t* s, segment_t seg) {
|
||||
if (s->shapes.num_segments >= s->shapes.max_segments) {
|
||||
int new_cap = s->shapes.max_segments * 2;
|
||||
segment_t* tmp = (segment_t*) realloc(s->shapes.segments, new_cap * sizeof(segment_t));
|
||||
if (!tmp) return -1;
|
||||
s->shapes.segments = tmp;
|
||||
s->shapes.max_segments = new_cap;
|
||||
}
|
||||
int idx = s->shapes.num_segments++;
|
||||
s->shapes.segments[idx] = seg;
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
// Append a shape (meta data) and return its index.
|
||||
static uint32_t scene_add_shape(scene_t* s, shape_meta_t meta) {
|
||||
if (s->shapes.num_shapes >= s->shapes.max_shapes) {
|
||||
int new_cap = s->shapes.max_shapes * 2;
|
||||
shape_meta_t* tmp = (shape_meta_t*) emmalloc_realloc(s->shapes.shapes, new_cap * sizeof(shape_meta_t));
|
||||
if (!tmp) return -1;
|
||||
s->shapes.shapes = tmp;
|
||||
s->shapes.max_shapes = new_cap;
|
||||
}
|
||||
int idx = s->shapes.num_shapes++;
|
||||
s->shapes.shapes[idx] = meta;
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
static uint32_t scene_shutdown(scene_t* s) {
|
||||
emmalloc_free(s->shapes.segments);
|
||||
emmalloc_free(s->shapes.shapes);
|
||||
emmalloc_free(s->circles.circles);
|
||||
|
||||
emmalloc_free(s->cache.indices);
|
||||
emmalloc_free(s->cache.tiles);
|
||||
emmalloc_free(s->cache.tile_dirty);
|
||||
|
||||
emmalloc_free(s);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Compute axis-aligned bounding box for a set of segments (used after adding a shape).
|
||||
static void compute_bbox(segment_t* segs, uint32_t start, uint32_t count, float* minx, float* miny, float* maxx, float* maxy) {
|
||||
float mx = 1e30f, my = 1e30f, Mx = -1e30f, My = -1e30f;
|
||||
for (int i = 0; i < count; i++) {
|
||||
segment_t s = segs[start + i];
|
||||
float xs[4] = {s.p0.x, s.p1.x, s.p2.x, s.p3.x};
|
||||
float ys[4] = {s.p0.y, s.p1.y, s.p2.y, s.p3.y};
|
||||
for (int j = 0; j < 4; j++) {
|
||||
if (xs[j] < mx) mx = xs[j];
|
||||
if (xs[j] > Mx) Mx = xs[j];
|
||||
if (ys[j] < my) my = ys[j];
|
||||
if (ys[j] > My) My = ys[j];
|
||||
}
|
||||
}
|
||||
*minx = mx; *miny = my; *maxx = Mx; *maxy = My;
|
||||
}
|
||||
|
||||
// Add an axis‑aligned rectangle centred at `center` with given width and height.
|
||||
// Returns the shape index, or -1 on error.
|
||||
uint32_t add_rectangle(scene_t* s, vec2 center, vec2 size) {
|
||||
float hw = size.x * 0.5f, hh = size.y * 0.5f;
|
||||
vec2 corners[4] = {
|
||||
{center.x - hw, center.y - hh}, // bottom‑left
|
||||
{center.x + hw, center.y - hh}, // bottom‑right
|
||||
{center.x + hw, center.y + hh}, // top‑right
|
||||
{center.x - hw, center.y + hh} // top‑left
|
||||
};
|
||||
|
||||
// Four straight segments, control points = the corners themselves.
|
||||
segment_t segs[4];
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
int next = (i + 1) % 4;
|
||||
segs[i].p0 = corners[i];
|
||||
segs[i].p1 = corners[i]; // start = control1 → straight line
|
||||
segs[i].p2 = corners[next]; // control2 = end
|
||||
segs[i].p3 = corners[next];
|
||||
}
|
||||
|
||||
int start = scene_add_segment(s, segs[0]);
|
||||
if (start < 0) return -1;
|
||||
for (int i = 1; i < 4; i++)
|
||||
if (scene_add_segment(s, segs[i]) < 0) return -1;
|
||||
|
||||
shape_meta_t meta;
|
||||
meta.start_segment = start;
|
||||
meta.segment_count = 4;
|
||||
meta.aabb = (box_t) { center.x - hw, center.y - hh, center.x + hw, center.y + hh };
|
||||
return scene_add_shape(s, meta);
|
||||
}
|
||||
|
||||
// Add a circle centred at `center` with given radius.
|
||||
// approximated by 4 cubic Bézier segments (one per quadrant).
|
||||
// Returns shape index or -1.
|
||||
uint32_t add_circle_as_shape(scene_t* s, vec2 center, float radius) {
|
||||
const float k = 0.552284749831f; // magic constant for 90° arc (4/3 * (sqrt(2)-1))
|
||||
float rk = radius * k;
|
||||
|
||||
// Start at rightmost point (0°), moving counter‑clockwise.
|
||||
vec2 p0 = {center.x + radius, center.y};
|
||||
|
||||
// Quadrant 1 (0° to 90°): from right to top
|
||||
segment_t seg1;
|
||||
seg1.p0 = p0;
|
||||
seg1.p1 = (vec2) {p0.x, p0.y + rk};
|
||||
seg1.p2 = (vec2) {center.x + rk, center.y + radius};
|
||||
seg1.p3 = (vec2) {center.x, center.y + radius};
|
||||
|
||||
// Quadrant 2 (90° to 180°): top to left
|
||||
segment_t seg2;
|
||||
seg2.p0 = seg1.p3;
|
||||
seg2.p1 = (vec2) {center.x - rk, center.y + radius};
|
||||
seg2.p2 = (vec2) {center.x - radius, center.y + rk};
|
||||
seg2.p3 = (vec2) {center.x - radius, center.y};
|
||||
|
||||
// Quadrant 3 (180° to 270°): left to bottom
|
||||
segment_t seg3;
|
||||
seg3.p0 = seg2.p3;
|
||||
seg3.p1 = (vec2) {center.x - radius, center.y - rk};
|
||||
seg3.p2 = (vec2) {center.x - rk, center.y - radius};
|
||||
seg3.p3 = (vec2) {center.x, center.y - radius};
|
||||
|
||||
// Quadrant 4 (270° to 360°): bottom to right
|
||||
segment_t seg4;
|
||||
seg4.p0 = seg3.p3;
|
||||
seg4.p1 = (vec2) {center.x + rk, center.y - radius};
|
||||
seg4.p2 = (vec2) {center.x + radius, center.y - rk};
|
||||
seg4.p3 = p0; // closes back to rightmost point
|
||||
|
||||
int start = scene_add_segment(s, seg1);
|
||||
if (start < 0) return -1;
|
||||
if (scene_add_segment(s, seg2) < 0) return -1;
|
||||
if (scene_add_segment(s, seg3) < 0) return -1;
|
||||
if (scene_add_segment(s, seg4) < 0) return -1;
|
||||
|
||||
shape_meta_t meta;
|
||||
meta.start_segment = start;
|
||||
meta.segment_count = 4;
|
||||
compute_bbox(s->shapes.segments, start, 4, &meta.aabb.min_x, &meta.aabb.min_y, &meta.aabb.max_x, &meta.aabb.max_y);
|
||||
return scene_add_shape(s, meta);
|
||||
}
|
||||
|
||||
uint32_t add_circle(scene_t* s, vec2 center, float radius) {
|
||||
s->circles.circles[s->circles.num_circles++] = (circle_t) { center, radius };
|
||||
|
||||
return s->circles.num_circles - 1;
|
||||
}
|
||||
79
src/sprite.h
79
src/sprite.h
@@ -1,79 +0,0 @@
|
||||
#ifndef SPRITE_H
|
||||
#define SPRITE_H
|
||||
|
||||
#include "api.h"
|
||||
|
||||
#define KB (1024u)
|
||||
#define MB (1024u * KB)
|
||||
#define GB (1024u * MB)
|
||||
#define MAX_FILE_SIZE (10u * MB)
|
||||
|
||||
typedef struct texture_t {
|
||||
uint32_t id; //Texture ID
|
||||
sg_bindings binding; //Texture bindings (texture, sampler and buffer)
|
||||
vector_t sprites;
|
||||
bool dirty;
|
||||
} texture_t;
|
||||
|
||||
typedef struct sprite_t {
|
||||
mat4x4f transform;
|
||||
} sprite_t;
|
||||
|
||||
typedef struct manager_t {
|
||||
vector_t textures;
|
||||
} manager_t;
|
||||
|
||||
typedef struct loader_t {
|
||||
uint8_t buffer[MAX_FILE_SIZE];
|
||||
} loader_t;
|
||||
|
||||
typedef void (*ForEachTexture)(texture_t *texture, void *userdata);
|
||||
typedef void (*ForEachSprite)(sprite_t *sprite, void *userdata);
|
||||
|
||||
void gs_init(manager_t *manager);
|
||||
void gs_shutdown(manager_t *manager);
|
||||
void gs_import_file(const sapp_html5_fetch_response *response);
|
||||
|
||||
void gs_each_textures(manager_t *manager, ForEachTexture callback, void *userdata);
|
||||
void gs_each_sprites(manager_t *manager, ForEachSprite callback, void *userdata);
|
||||
|
||||
void gs_init(manager_t *manager)
|
||||
{
|
||||
manager->textures = vector_create(sizeof(texture_t));
|
||||
}
|
||||
void gs_shutdown(manager_t *manager)
|
||||
{
|
||||
vector_free(&manager->textures);
|
||||
}
|
||||
|
||||
void gs_import_file(const sapp_html5_fetch_response *response)
|
||||
{
|
||||
const char* filename = sapp_get_dropped_file_path(response->file_index);
|
||||
|
||||
if(response->succeeded)
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//Toast error
|
||||
}
|
||||
}
|
||||
void gs_each_textures(manager_t *manager, ForEachTexture callback, void *userdata)
|
||||
{
|
||||
for(uint32_t i = 0; i < manager->textures.size; i++)
|
||||
callback((texture_t*) manager->textures.data[i], userdata);
|
||||
}
|
||||
void gs_each_sprites(manager_t *manager, ForEachSprite callback, void *userdata)
|
||||
{
|
||||
for(uint32_t i = 0; i < manager->textures.size; i++)
|
||||
{
|
||||
const texture_t* texture = (texture_t*) manager->textures.data[i];
|
||||
for(uint32_t j = 0; j < texture->sprites.size; j++)
|
||||
{
|
||||
callback((sprite_t*) texture->sprites.data[j], userdata);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
241
src/util.h
241
src/util.h
@@ -1,241 +0,0 @@
|
||||
#ifndef UTIL_H
|
||||
#define UTIL_H
|
||||
|
||||
#include "api.h"
|
||||
|
||||
/*typedef struct linked_list_t {
|
||||
linked_item_t *first, *last;
|
||||
uint16_t size;
|
||||
} linked_list_t;
|
||||
|
||||
typedef struct linked_item_t {
|
||||
linked_item_t *next, *prev;
|
||||
void *data;
|
||||
} linked_item_t;
|
||||
|
||||
typedef void (*linked_list_callback)(void *item);
|
||||
|
||||
//Currently, these are the only method required.
|
||||
//Many more could be implemented but this is unnecessary.
|
||||
static void l_list_push(linked_list_t *l_list, void *item);
|
||||
static void l_list_append(linked_list_t *l_list, void *item);
|
||||
static void* l_list_pop(linked_list_t *l_list);
|
||||
static void* l_list_unppend(linked_list_t *l_list);
|
||||
static void l_list_each(linked_list_t *l_list, linked_list_callback callback);
|
||||
|
||||
static inline void l_list_push(linked_list_t *l_list, void *item)
|
||||
{
|
||||
linked_item_t l_item = (linked_item_t) { .data = item, .prev = l_list->last, .next = nullptr };
|
||||
|
||||
if(l_list->first == nullptr)
|
||||
l_list->first = &l_item;
|
||||
|
||||
l_list->last->next = &l_item;
|
||||
l_list->last = &l_item;
|
||||
l_list->size++;
|
||||
}
|
||||
static inline void l_list_append(linked_list_t *l_list, void *item)
|
||||
{
|
||||
linked_item_t l_item = (linked_item_t) { .data = item, .prev = nullptr, .next = l_list->last };
|
||||
|
||||
if(l_list->last == nullptr)
|
||||
l_list->last = &l_item;
|
||||
|
||||
l_list->first->prev = &l_item;
|
||||
l_list->first = &l_item;
|
||||
l_list->size++;
|
||||
}
|
||||
static inline void* l_list_pop(linked_list_t *l_list)
|
||||
{
|
||||
if(l_list->last == nullptr)
|
||||
return;
|
||||
|
||||
if(l_list->first == l_list->last)
|
||||
l_list->first = nullptr;
|
||||
|
||||
linked_item_t *item = l_list->last->prev;
|
||||
l_list->last->prev = nullptr;
|
||||
l_list->last = item;
|
||||
l_list->size--;
|
||||
}
|
||||
static inline void* l_list_unppend(linked_list_t *l_list)
|
||||
{
|
||||
if(l_list->first == nullptr)
|
||||
return;
|
||||
|
||||
if(l_list->last == l_list->first)
|
||||
l_list->last = nullptr;
|
||||
|
||||
linked_item_t *item = l_list->first->next;
|
||||
l_list->first->next = nullptr;
|
||||
l_list->first = item;
|
||||
l_list->size--;
|
||||
}
|
||||
static inline void l_list_each(linked_list_t *l_list, linked_list_callback callback)
|
||||
{
|
||||
|
||||
}*/
|
||||
|
||||
typedef struct vector_t {
|
||||
void **data; //Memory pool
|
||||
uint16_t stripe; //Bit per item
|
||||
uint32_t size; //Current amount of items
|
||||
uint32_t capacity; //Max capacity
|
||||
} vector_t;
|
||||
|
||||
#define MAX_BUCKET_SIZE (0xffffffffu)
|
||||
#define MAX_STRIPE_SIZE (0xffffffu)
|
||||
#define FIXED_START (0xfffu)
|
||||
|
||||
static vector_t vector_create(uint32_t stripe); //Create a new vector with a default size
|
||||
static void vector_clear(vector_t *vector);
|
||||
static void vector_free(vector_t *vector);
|
||||
|
||||
static uint32_t vector_length(vector_t *vector);
|
||||
static void* vector_get(vector_t *vector, uint32_t index);
|
||||
static void vector_set(vector_t *vector, uint32_t index, void *data);
|
||||
static uint32_t vector_push(vector_t *vector, void *data);
|
||||
static sg_range vector_range(vector_t *vector);
|
||||
|
||||
static vector_t vector_create(uint32_t stripe)
|
||||
{
|
||||
assert(stripe >= sizeof(uint32_t));
|
||||
assert(stripe <= MAX_STRIPE_SIZE);
|
||||
assert(FIXED_START * stripe <= MAX_BUCKET_SIZE);
|
||||
|
||||
return (vector_t) {
|
||||
.capacity = FIXED_START,
|
||||
.size = 0,
|
||||
.stripe = stripe,
|
||||
.data = (void**) malloc(FIXED_START * stripe),
|
||||
};
|
||||
}
|
||||
static void vector_clear(vector_t *vector)
|
||||
{
|
||||
vector->size = 0;
|
||||
}
|
||||
static void vector_free(vector_t *vector)
|
||||
{
|
||||
free(vector->data);
|
||||
}
|
||||
|
||||
static uint32_t vector_length(vector_t *vector)
|
||||
{
|
||||
return vector->size;
|
||||
}
|
||||
static void* vector_get(vector_t *vector, uint32_t index)
|
||||
{
|
||||
assert(index > 0);
|
||||
assert(index < vector->size);
|
||||
|
||||
return vector->data[index * vector->stripe];
|
||||
}
|
||||
static void vector_set(vector_t *vector, uint32_t index, void *data)
|
||||
{
|
||||
assert(index > 0);
|
||||
assert(index < vector->size);
|
||||
|
||||
vector->data[index * vector->stripe] = data;
|
||||
}
|
||||
static uint32_t vector_push(vector_t *vector, void *data)
|
||||
{
|
||||
if(vector->size >= vector->capacity)
|
||||
{
|
||||
vector->capacity *= 2;
|
||||
|
||||
vector->data = (void**) realloc(vector->data, vector->capacity * vector->stripe);
|
||||
}
|
||||
|
||||
return vector->size++;
|
||||
}
|
||||
static sg_range vector_range(vector_t *vector)
|
||||
{
|
||||
return (sg_range) {
|
||||
.ptr = vector->data,
|
||||
.size = vector->size,
|
||||
};
|
||||
}
|
||||
|
||||
typedef struct mem_pool_t {
|
||||
void **data; //Memory pool
|
||||
uint32_t stripe; //Bit per item
|
||||
uint32_t size; //Current amount of items
|
||||
uint32_t capacity; //Max capacity
|
||||
uint32_t free; //Linked list of available indices
|
||||
} mem_pool_t;
|
||||
|
||||
static mem_pool_t pool_create_default(uint32_t stripe); //Create a new memory pool with a default size
|
||||
static mem_pool_t pool_create(uint32_t stripe, uint32_t size); //Create a new memory pool with a default size
|
||||
static void pool_clear(mem_pool_t *pool);
|
||||
static void pool_free(mem_pool_t *pool);
|
||||
|
||||
static const uint32_t pool_add(mem_pool_t *pool); //Request a new free index
|
||||
static const void* pool_get(mem_pool_t *pool, uint32_t index); //Get the pointer
|
||||
static void pool_remove(mem_pool_t *pool, uint32_t index); //Flag the given index as free
|
||||
|
||||
static mem_pool_t pool_create_default(uint32_t stripe)
|
||||
{
|
||||
return pool_create(stripe, FIXED_START);
|
||||
}
|
||||
static mem_pool_t pool_create(uint32_t stripe, uint32_t size)
|
||||
{
|
||||
assert(stripe >= sizeof(uint32_t));
|
||||
assert(stripe <= MAX_STRIPE_SIZE);
|
||||
assert(size * stripe <= MAX_BUCKET_SIZE);
|
||||
|
||||
return (mem_pool_t) {
|
||||
.capacity = size,
|
||||
.size = 0,
|
||||
.stripe = stripe,
|
||||
.free = UINT32_MAX,
|
||||
.data = (void**) malloc(size * stripe),
|
||||
};
|
||||
}
|
||||
static void pool_clear(mem_pool_t *pool)
|
||||
{
|
||||
pool->size = 0;
|
||||
pool->free = UINT32_MAX;
|
||||
}
|
||||
static void pool_free(mem_pool_t *pool)
|
||||
{
|
||||
free(pool->data);
|
||||
}
|
||||
|
||||
static const uint32_t pool_add(mem_pool_t *pool)
|
||||
{
|
||||
if(pool->free != UINT32_MAX)
|
||||
{
|
||||
const uint32_t index = pool->free;
|
||||
|
||||
pool->free = (uint32_t) pool->data[index * pool->stripe];
|
||||
|
||||
return index;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(pool->size >= pool->capacity)
|
||||
{
|
||||
pool->capacity *= 2;
|
||||
|
||||
pool->data = (void**) realloc(pool->data, pool->capacity * pool->stripe);
|
||||
}
|
||||
|
||||
return pool->size++;
|
||||
}
|
||||
}
|
||||
static const void* pool_get(mem_pool_t *pool, uint32_t index)
|
||||
{
|
||||
assert(index > 0);
|
||||
assert(index < pool->capacity);
|
||||
|
||||
return pool->data[index * pool->stripe];
|
||||
}
|
||||
static void pool_remove(mem_pool_t *pool, uint32_t index)
|
||||
{
|
||||
const uint32_t pos = index * pool->stripe;
|
||||
|
||||
pool->data[pos] = (void*) pool->free;
|
||||
pool->free = index;
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user