' data_terrain.pb — Terrain heightmap generation (Diamond-Square)
#COMPILE EXE
#DIM ALL

FUNCTION PBMAIN() AS LONG
    LOCAL heightMap(300) AS LONG
    LOCAL mapSize AS LONG
    LOCAL i AS LONG
    LOCAL j AS LONG
    LOCAL x AS LONG
    LOCAL y AS LONG
    LOCAL stepSize AS LONG
    LOCAL halfStep AS LONG
    LOCAL topLeft AS LONG
    LOCAL topRight AS LONG
    LOCAL botLeft AS LONG
    LOCAL botRight AS LONG
    LOCAL avgHeight AS LONG
    LOCAL offsetVal AS LONG
    LOCAL roughness AS LONG
    LOCAL maxHeight AS LONG
    LOCAL minHeight AS LONG
    LOCAL totalHeight AS LONG
    LOCAL avgVal AS LONG
    LOCAL iter AS LONG
    LOCAL col AS LONG
    LOCAL row AS LONG

    mapSize = 8
    roughness = 20

    PRINT "=== Terrain Generation (Diamond-Square) ==="
    PRINT "Map size: " + STR$(mapSize) + "x" + STR$(mapSize)

    heightMap(0) = 100
    heightMap(mapSize - 1) = 100
    heightMap((mapSize - 1) * mapSize) = 100
    heightMap((mapSize - 1) * mapSize + mapSize - 1) = 100

    stepSize = mapSize - 1

    WHILE 1
        IF stepSize <= 1 THEN EXIT LOOP
        halfStep = stepSize / 2

        FOR y = halfStep TO mapSize - 1 STEP stepSize
            FOR x = halfStep TO mapSize - 1 STEP stepSize
                topLeft = heightMap((y - halfStep) * mapSize + (x - halfStep))
                topRight = heightMap((y - halfStep) * mapSize + (x + halfStep))
                botLeft = heightMap((y + halfStep) * mapSize + (x - halfStep))
                botRight = heightMap((y + halfStep) * mapSize + (x + halfStep))
                avgHeight = (topLeft + topRight + botLeft + botRight) / 4
                offsetVal = (roughness)
                IF offsetVal / 2 * 2 = offsetVal THEN
                    offsetVal = offsetVal / 2
                ELSE
                    offsetVal = offsetVal / 2 + 1
                END IF
                avgHeight = avgHeight + offsetVal
                heightMap(y * mapSize + x) = avgHeight
            NEXT x
        NEXT y

        FOR y = 0 TO mapSize - 1 STEP halfStep
            FOR x = 0 TO mapSize - 1 STEP halfStep
                IF (y / halfStep + x / halfStep) / 2 * 2 <> (y / halfStep + x / halfStep) THEN
                    avgHeight = 0
                    IF y > 0 THEN avgHeight = avgHeight + heightMap((y - halfStep) * mapSize + x)
                    IF y < mapSize - 1 THEN avgHeight = avgHeight + heightMap((y + halfStep) * mapSize + x)
                    IF x > 0 THEN avgHeight = avgHeight + heightMap(y * mapSize + (x - halfStep))
                    IF x < mapSize - 1 THEN avgHeight = avgHeight + heightMap(y * mapSize + (x + halfStep))
                    heightMap(y * mapSize + x) = avgHeight / 4 + roughness
                END IF
            NEXT x
        NEXT y

        stepSize = halfStep
        IF roughness > 1 THEN roughness = roughness / 2
    WEND

    maxHeight = heightMap(0)
    minHeight = heightMap(0)
    totalHeight = 0
    FOR y = 0 TO mapSize - 1
        FOR x = 0 TO mapSize - 1
            totalHeight = totalHeight + heightMap(y * mapSize + x)
            IF heightMap(y * mapSize + x) > maxHeight THEN maxHeight = heightMap(y * mapSize + x)
            IF heightMap(y * mapSize + x) < minHeight THEN minHeight = heightMap(y * mapSize + x)
        NEXT x
    NEXT y
    avgVal = totalHeight / (mapSize * mapSize)

    PRINT "Max: " + STR$(maxHeight) + " Min: " + STR$(minHeight) + " Avg: " + STR$(avgVal)
    PRINT "=== End Terrain ==="
    FUNCTION = 0
END FUNCTION
