1DOLLY 72PACKAGE box3d3REQUIRES HOST runtime@045# Box3D 0.1.0 from upstream's source, unchanged, without SIMD, and with6# Dolly's platform file in place of its timer.c: monotonic ticks, and tasks7# that run serially in the calling thread. For programs the cc package builds.8FROM /v0.1.4/Dollyfile-system 915c71d4ce772989e3076060967824e48ccd6a1a6259624fe6213542df088dbc9REQUIRES HEADER libc10REQUIRES TOOL   ar11REQUIRES TOOL   cc12REQUIRES TOOL   make13REQUIRES TOOL   mkdir14REQUIRES TOOL   rm15REQUIRES TOOL   tar1617SOURCE /v0.1.4/dist/static/gamedev/box3d.tar 5a502138e8f7b47c5994bdd279e9dcddeae0b8e147e3b92ab79b723bd07e4377 /tmp/box3d.tar18FILE /usr/src/dolly/box3d/box3d.mk19    CC := cc20    AR := ar21    SOURCE := /usr/src/box3d/src22    BUILD := /usr/src/dolly/box3d/build23    SOURCES := $(filter-out $(SOURCE)/timer.c,$(wildcard $(SOURCE)/*.c))24    OBJECTS := $(patsubst $(SOURCE)/%.c,$(BUILD)/%.o,$(SOURCES)) $(BUILD)/platform.o25    FLAGS := -std=gnu17 -O2 -fno-builtin -U__SIZEOF_INT128__ -DBOX3D_DISABLE_SIMD -I /usr/src/box3d/include -I $(SOURCE)26    27    .PHONY: all28    29    all: /usr/lib/libbox3d.a30    31    $(BUILD)/%.o: $(SOURCE)/%.c32    	mkdir -p $(BUILD)33    	$(CC) $(FLAGS) -c $< -o $@34    35    $(BUILD)/platform.o: /usr/src/dolly/box3d/box3d-platform.c36    	mkdir -p $(BUILD)37    	$(CC) $(FLAGS) -c $< -o $@38    39    /usr/lib/libbox3d.a: $(OBJECTS)40    	$(AR) rcs $@ $^41    	mkdir -p /usr/include/box3d42    	cp /usr/src/box3d/include/box3d/*.h /usr/include/box3d43FILE /usr/src/dolly/box3d/box3d-platform.c44    #define _POSIX_C_SOURCE 200809L45    46    // Dolly's Box3D target adapter replaces upstream timer.c. Box3D's built-in47    // scheduler links pthread primitives even when the normal one-worker world48    // never creates a thread. Dolly deliberately executes tasks serially inside49    // one Wasm userspace, so synchronization objects carry no host capability and50    // worker handles are inert. The scheduler's calling thread still drains every51    // queued task in b3SchedulerFinishTask.52    53    #include "core.h"54    55    #include <stdint.h>56    #include <string.h>57    #include <time.h>58    59    uint64_t b3GetTicks(void) {60      struct timespec now = {0};61      if (clock_gettime(CLOCK_MONOTONIC, &now) != 0) return 0;62      return (uint64_t)now.tv_sec * UINT64_C(1000000000) +63             (uint64_t)now.tv_nsec;64    }65    66    float b3GetMilliseconds(uint64_t ticks) {67      return (float)((double)(b3GetTicks() - ticks) / 1000000.0);68    }69    70    float b3GetMillisecondsAndReset(uint64_t *ticks) {71      const uint64_t now = b3GetTicks();72      const float elapsed = (float)((double)(now - *ticks) / 1000000.0);73      *ticks = now;74      return elapsed;75    }76    77    void b3Yield(void) {}78    void b3Sleep(int milliseconds) { (void)milliseconds; }79    80    struct b3Mutex { unsigned unused; };81    struct b3Semaphore { int count; };82    struct b3Thread { unsigned unused; };83    84    b3Mutex *b3CreateMutex(void) {85      return b3AllocZeroed(sizeof(b3Mutex));86    }87    88    void b3DestroyMutex(b3Mutex *mutex) {89      b3Free(mutex, sizeof(b3Mutex));90    }91    92    void b3LockMutex(b3Mutex *mutex) { (void)mutex; }93    void b3UnlockMutex(b3Mutex *mutex) { (void)mutex; }94    95    b3Semaphore *b3CreateSemaphore(int initial_count) {96      b3Semaphore *semaphore = b3Alloc(sizeof(b3Semaphore));97      semaphore->count = initial_count;98      return semaphore;99    }100    101    void b3DestroySemaphore(b3Semaphore *semaphore) {102      b3Free(semaphore, sizeof(b3Semaphore));103    }104    105    void b3WaitSemaphore(b3Semaphore *semaphore) {106      if (semaphore->count > 0) semaphore->count--;107    }108    109    void b3SignalSemaphore(b3Semaphore *semaphore) {110      semaphore->count++;111    }112    113    b3Thread *b3CreateThread(b3ThreadFunction *function, void *context,114                             const char *name) {115      (void)function;116      (void)context;117      (void)name;118      return b3AllocZeroed(sizeof(b3Thread));119    }120    121    void b3JoinThread(b3Thread *thread) {122      b3Free(thread, sizeof(b3Thread));123    }124    125    // This deterministic djb2 variant is part of upstream timer.c rather than the126    // OS-independent core. Keep the exact algorithm when replacing that complete127    // translation unit so hull and mesh hashes stay compatible with upstream.128    uint32_t b3Hash(uint32_t hash, const uint8_t *data, int count) {129      uint32_t result = hash;130      int index = 0;131      while (index + 8 <= count) {132        uint64_t word;133        memcpy(&word, data + index, sizeof(word));134    #if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__135        word = ((word & UINT64_C(0x00000000000000ff)) << 56) |136               ((word & UINT64_C(0x000000000000ff00)) << 40) |137               ((word & UINT64_C(0x0000000000ff0000)) << 24) |138               ((word & UINT64_C(0x00000000ff000000)) << 8) |139               ((word & UINT64_C(0x000000ff00000000)) >> 8) |140               ((word & UINT64_C(0x0000ff0000000000)) >> 24) |141               ((word & UINT64_C(0x00ff000000000000)) >> 40) |142               ((word & UINT64_C(0xff00000000000000)) >> 56);143    #endif144        result = (result << 5) + result + (uint32_t)word;145        result = (result << 5) + result + (uint32_t)(word >> 32);146        index += 8;147      }148      while (index < count) {149        result = (result << 5) + result + data[index];150        index++;151      }152      return result;153    }154SLOP tar -xf /tmp/box3d.tar -C /155SLOP CWD /usr/src/dolly/box3d make -f /usr/src/dolly/box3d/box3d.mk156157EXPORTS LIB    box3d /usr/lib/libbox3d.a158EXPORTS HEADER box3d /usr/include/box3d159FILE /usr/share/licenses/box3d/LICENSE160SLOP rm -rf /tmp/box3d.tar /usr/src/box3d /usr/src/dolly/box3d161