mirror of
https://github.com/Cubitect/cubiomes.git
synced 2025-09-23 03:33:50 -04:00
Made compatible with g++ and clang compilers + better docu for getting started.
This commit is contained in:
parent
8fa78be25b
commit
a9705edfb8
148
README.md
148
README.md
@ -4,20 +4,130 @@ Cubiomes is a standalone library, written in C, that mimics the Minecraft biome
|
|||||||
It is intended as a powerful tool to devise very fast, custom seed finding applications and large scale map viewers.
|
It is intended as a powerful tool to devise very fast, custom seed finding applications and large scale map viewers.
|
||||||
|
|
||||||
|
|
||||||
### Audience
|
#### Audience
|
||||||
|
|
||||||
You should be familiar with the C programming language, also a basic understanding of the Minecraft biome generation process would be helpful.
|
You should be familiar with the C programming language, also a basic understanding of the Minecraft biome generation process would be helpful.
|
||||||
A POSIX environment is required to compile the finders library and examples, but the core generator library may also work on other platforms.
|
|
||||||
|
|
||||||
|
|
||||||
### Documentation
|
## Getting Started
|
||||||
|
|
||||||
|
This section is meant to give you a quick starting point if you want to use this library to find your own biome dependent features.
|
||||||
|
|
||||||
|
### Biome Generator
|
||||||
|
|
||||||
|
Let's create a simple program called `find_jedge.c` which tests seeds for a Junge Edge biome at a predefined location.
|
||||||
|
|
||||||
|
```
|
||||||
|
#include "finders.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// First initialize the global biome table 'int biomes[256]'. This sets up
|
||||||
|
// properties such as the category and temperature of each biome.
|
||||||
|
initBiomes();
|
||||||
|
|
||||||
|
// Allocate and initialize a stack of biome layers that reflects the biome
|
||||||
|
// generation of Minecraft 1.14
|
||||||
|
LayerStack g = setupGenerator(MC_1_14);
|
||||||
|
|
||||||
|
int64_t seed;
|
||||||
|
Pos pos = {0,0}; // block position to be checked
|
||||||
|
|
||||||
|
for (seed = 0; ; seed++)
|
||||||
|
{
|
||||||
|
// Go through the layers in the layer stack and initialize the seed
|
||||||
|
// dependent aspects of the generator.
|
||||||
|
applySeed(&g, seed);
|
||||||
|
|
||||||
|
// To get the biome at single block position we can use getBiomeAtPos().
|
||||||
|
int biomeID = getBiomeAtPos(g, pos);
|
||||||
|
if (biomeID == jungle_edge)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Seed %" PRId64 " has a Junge Edge biome at block position "
|
||||||
|
"(%d, %d).\n", seed, pos.x, pos.z);
|
||||||
|
|
||||||
|
// Clean up.
|
||||||
|
freeGenerator(g);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
You can compile this code either by directly adding a target to the makefile, or you can compile and link to a cubiomes archive:
|
||||||
|
```
|
||||||
|
$ cd cubiomes
|
||||||
|
$ make libcubiomes
|
||||||
|
```
|
||||||
|
To compile, and link the cubiomes library you can use one of
|
||||||
|
```
|
||||||
|
$ cc find_jedge.c libcubiomes.a -lm # static
|
||||||
|
$ cc find_jedge.c -L. -lcubiomes -lm # dynamic
|
||||||
|
```
|
||||||
|
Both options assume that your source code is saved as `find_jedge.c` in the cubiomes working directory. If your makefile is configured to use pthreads you also may need to add the `-lpthread` option to the compiler. Running the program should output:
|
||||||
|
```
|
||||||
|
$ ./a.out
|
||||||
|
Seed 615 has a Junge Edge biome at block position (0, 0).
|
||||||
|
```
|
||||||
|
|
||||||
|
We can also generate the biomes for a rectangular region using `getArea()` which also offers control over the entry layer, see the layer documentation for more information.
|
||||||
|
|
||||||
|
```
|
||||||
|
#include "generator.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
unsigned char biomeColours[256][3];
|
||||||
|
|
||||||
|
// Initialize global biome table.
|
||||||
|
initBiomes();
|
||||||
|
// Initialize a colour map for biomes.
|
||||||
|
initBiomeColours(biomeColours);
|
||||||
|
|
||||||
|
// Allocate and initialize a stack of biome layers.
|
||||||
|
LayerStack g = setupGenerator(MC_1_14);
|
||||||
|
// Extract the desired layer.
|
||||||
|
Layer *layer = &g.layers[L_SHORE_16];
|
||||||
|
|
||||||
|
int64_t seed = 1661454332289;
|
||||||
|
int areaX = -60, areaZ = -60;
|
||||||
|
unsigned int areaWidth = 120, areaHeight = 120;
|
||||||
|
unsigned int scale = 4;
|
||||||
|
unsigned int imgWidth = areaWidth*scale, imgHeight = areaHeight*scale;
|
||||||
|
|
||||||
|
// Allocate a sufficient buffer for the biomes and for the image pixels.
|
||||||
|
int *biomes = allocCache(layer, areaWidth, areaHeight);
|
||||||
|
unsigned char *rgb = (unsigned char *) malloc(3*imgWidth*imgHeight);
|
||||||
|
|
||||||
|
// Apply the seed only for the required layers and generate the area.
|
||||||
|
setWorldSeed(layer, seed);
|
||||||
|
genArea(layer, biomes, areaX, areaZ, areaWidth, areaHeight);
|
||||||
|
|
||||||
|
// Map the biomes to a color buffer and save to an image.
|
||||||
|
biomesToImage(rgb, biomeColours, biomes, areaWidth, areaHeight, scale, 2);
|
||||||
|
savePPM("biomes_at_layer.ppm", rgb, imgWidth, imgHeight);
|
||||||
|
|
||||||
|
// Clean up.
|
||||||
|
freeGenerator(g);
|
||||||
|
free(biomes);
|
||||||
|
free(rgb);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Layer Documentation
|
||||||
|
|
||||||
There is a reference document for the generator layers which contains a summary for most generator layers and their function within the generation process.
|
There is a reference document for the generator layers which contains a summary for most generator layers and their function within the generation process.
|
||||||
|
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
There are two example programs in this repository which can be compiled using the makefile provided.
|
There are two example programs in this repository which can be compiled using the makefile.
|
||||||
|
|
||||||
|
|
||||||
#### Finding Quad-Witch-Huts at a Specific Location
|
#### Finding Quad-Witch-Huts at a Specific Location
|
||||||
@ -125,20 +235,20 @@ If you are looking to get the "Adventuring Time" achievment you might consider o
|
|||||||
|
|
||||||
| Seed | All biome radius |
|
| Seed | All biome radius |
|
||||||
|---------------|------------------|
|
|---------------|------------------|
|
||||||
| -880424771806 | 644 |
|
| -880424771806 | 644 |
|
||||||
| 48382691805 | 633 |
|
| 48382691805 | 633 |
|
||||||
| 480800992945 | 649 |
|
| 480800992945 | 649 |
|
||||||
| 1065757415811 | 612 |
|
| 1065757415811 | 612 |
|
||||||
| 1509124018794 | 645 |
|
| 1509124018794 | 645 |
|
||||||
| 1550633690354 | 616 |
|
| 1550633690354 | 616 |
|
||||||
| 1571479851306 | 631 |
|
| 1571479851306 | 631 |
|
||||||
| 1925837979058 | 621 |
|
| 1925837979058 | 621 |
|
||||||
| 2082386353360 | 649 |
|
| 2082386353360 | 649 |
|
||||||
| 2087339213306 | 632 |
|
| 2087339213306 | 632 |
|
||||||
| 2810140768300 | 637 |
|
| 2810140768300 | 637 |
|
||||||
| 3053313529066 | 648 |
|
| 3053313529066 | 648 |
|
||||||
| 3457626356584 | 649 |
|
| 3457626356584 | 649 |
|
||||||
| 3548624619264 | 646 |
|
| 3548624619264 | 646 |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,8 +61,8 @@ int main(int argc, char *argv[])
|
|||||||
" range search range (in blocks) [uint, default=1024]\n");
|
" range search range (in blocks) [uint, default=1024]\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
if (argc <= 1 || sscanf(argv[1], "%"PRId64, &seedStart) != 1) seedStart = 0;
|
if (argc <= 1 || sscanf(argv[1], "%" PRId64, &seedStart) != 1) seedStart = 0;
|
||||||
if (argc <= 2 || sscanf(argv[2], "%"PRId64, &seedEnd) != 1) seedEnd = 100000000LL;
|
if (argc <= 2 || sscanf(argv[2], "%" PRId64, &seedEnd) != 1) seedEnd = 100000000LL;
|
||||||
if (argc <= 3 || sscanf(argv[3], "%u", &threads) != 1) threads = 1;
|
if (argc <= 3 || sscanf(argv[3], "%u", &threads) != 1) threads = 1;
|
||||||
if (argc <= 4 || sscanf(argv[4], "%u", &range) != 1) range = 1024;
|
if (argc <= 4 || sscanf(argv[4], "%u", &range) != 1) range = 1024;
|
||||||
|
|
||||||
@ -70,7 +70,7 @@ int main(int argc, char *argv[])
|
|||||||
filter = setupBiomeFilter(BIOMES_L13_OCEAN_MIX_4,
|
filter = setupBiomeFilter(BIOMES_L13_OCEAN_MIX_4,
|
||||||
sizeof(BIOMES_L13_OCEAN_MIX_4)/sizeof(int));
|
sizeof(BIOMES_L13_OCEAN_MIX_4)/sizeof(int));
|
||||||
|
|
||||||
printf("Starting search through seeds %"PRId64 " to %"PRId64", using %u threads.\n"
|
printf("Starting search through seeds %" PRId64 " to %" PRId64", using %u threads.\n"
|
||||||
"Search radius = %u.\n", seedStart, seedEnd, threads, range);
|
"Search radius = %u.\n", seedStart, seedEnd, threads, range);
|
||||||
|
|
||||||
thread_id_t threadID[threads];
|
thread_id_t threadID[threads];
|
||||||
|
@ -28,14 +28,14 @@ int main(int argc, char *argv[])
|
|||||||
const char *seedFileName;
|
const char *seedFileName;
|
||||||
StructureConfig featureConfig;
|
StructureConfig featureConfig;
|
||||||
|
|
||||||
if(argc > 2)
|
if (argc > 2)
|
||||||
{
|
{
|
||||||
if(sscanf(argv[1], "%d", ®PosX) != 1) regPosX = 0;
|
if (sscanf(argv[1], "%d", ®PosX) != 1) regPosX = 0;
|
||||||
if(sscanf(argv[2], "%d", ®PosZ) != 1) regPosZ = 0;
|
if (sscanf(argv[2], "%d", ®PosZ) != 1) regPosZ = 0;
|
||||||
|
|
||||||
if(argc > 3)
|
if (argc > 3)
|
||||||
{
|
{
|
||||||
if(sscanf(argv[3], "%d", &mcversion) != 1) mcversion = 0;
|
if (sscanf(argv[3], "%d", &mcversion) != 1) mcversion = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -55,7 +55,7 @@ int main(int argc, char *argv[])
|
|||||||
regPosX -= 1;
|
regPosX -= 1;
|
||||||
regPosZ -= 1;
|
regPosZ -= 1;
|
||||||
|
|
||||||
if(mcversion == 113)
|
if (mcversion >= 113)
|
||||||
{
|
{
|
||||||
featureConfig = SWAMP_HUT_CONFIG;
|
featureConfig = SWAMP_HUT_CONFIG;
|
||||||
seedFileName = "./seeds/quadhutbases_1_13_Q1.txt";
|
seedFileName = "./seeds/quadhutbases_1_13_Q1.txt";
|
||||||
@ -73,7 +73,7 @@ int main(int argc, char *argv[])
|
|||||||
g = setupGenerator(MC_1_7);
|
g = setupGenerator(MC_1_7);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(access(seedFileName, F_OK))
|
if (access(seedFileName, F_OK))
|
||||||
{
|
{
|
||||||
printf("Seed base file does not exist: Creating new one.\n"
|
printf("Seed base file does not exist: Creating new one.\n"
|
||||||
"This may take a few minutes...\n");
|
"This may take a few minutes...\n");
|
||||||
@ -95,7 +95,7 @@ int main(int argc, char *argv[])
|
|||||||
// so we can test the biome at these positions.
|
// so we can test the biome at these positions.
|
||||||
Pos qhpos[4];
|
Pos qhpos[4];
|
||||||
|
|
||||||
// Setup a dummy layer for Layer 19: Biome.
|
// Setup a dummy layer for Layer 19: Biome, to make preliminary seed tests.
|
||||||
Layer layerBiomeDummy;
|
Layer layerBiomeDummy;
|
||||||
setupLayer(256, &layerBiomeDummy, NULL, 200, NULL);
|
setupLayer(256, &layerBiomeDummy, NULL, 200, NULL);
|
||||||
|
|
||||||
@ -105,7 +105,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
|
|
||||||
// Search for a swamp at the structure positions
|
// Search for a swamp at the structure positions
|
||||||
for(i = 0; i < qhcnt; i++)
|
for (i = 0; i < qhcnt; i++)
|
||||||
{
|
{
|
||||||
base = moveStructure(qhcandidates[i], regPosX, regPosZ);
|
base = moveStructure(qhcandidates[i], regPosX, regPosZ);
|
||||||
|
|
||||||
@ -115,7 +115,7 @@ int main(int argc, char *argv[])
|
|||||||
qhpos[3] = getStructurePos(featureConfig, base, 1+regPosX, 1+regPosZ);
|
qhpos[3] = getStructurePos(featureConfig, base, 1+regPosX, 1+regPosZ);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
for(j = 0; j < 4; j++)
|
for (j = 0; j < 4; j++)
|
||||||
{
|
{
|
||||||
printf("(%d,%d) ", qhpos[j].x, qhpos[j].z);
|
printf("(%d,%d) ", qhpos[j].x, qhpos[j].z);
|
||||||
}
|
}
|
||||||
@ -124,29 +124,31 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
// This little magic code checks if there is a meaningful chance for
|
// This little magic code checks if there is a meaningful chance for
|
||||||
// this seed base to generate swamps in the area.
|
// this seed base to generate swamps in the area.
|
||||||
// The idea is that the conversion from Lush temperature to swamp is
|
// The idea is, that the conversion from Lush temperature to swamp is
|
||||||
// independent of surroundings, so we can test the conversion
|
// independent of surroundings, so we can test for this conversion
|
||||||
// beforehand. Furthermore biomes tend to leak into the negative
|
// beforehand. Furthermore, biomes tend to leak into the negative
|
||||||
// coordinates because of the Zoom layers, so the majority of hits will
|
// coordinates because of the Zoom layers, so the majority of hits will
|
||||||
// occur when SouthEast corner (at a 1:256 scale) of the quad-hut has a
|
// occur when SouthEast corner (at a 1:256 scale) of the quad-hut has a
|
||||||
// swamp. (This assumption misses about 1 in 500 quad-hut seeds.)
|
// swamp. (This assumption misses about 1 in 500 quad-hut seeds.)
|
||||||
// Finally, here we also exploit that the minecraft random number
|
// Finally, here we also exploit that the minecraft random number
|
||||||
// generator is quite bad, such that for the "mcNextRand() mod 6" check
|
// generator is quite bad, the "mcNextRand() mod 6" check has a period
|
||||||
// it has a period pattern of ~3 on the high seed-bits.
|
// pattern of ~3 on the high seed-bits, which means we can avoid
|
||||||
for(j = 0; j < 5; j++)
|
// checking all 16 high-bit combinations.
|
||||||
|
for (j = 0; j < 5; j++)
|
||||||
{
|
{
|
||||||
seed = base + ((j+0x53) << 48);
|
seed = base + ((j+0x53) << 48);
|
||||||
setWorldSeed(&layerBiomeDummy, seed);
|
setWorldSeed(&layerBiomeDummy, seed);
|
||||||
setChunkSeed(&layerBiomeDummy, areaX+1, areaZ+1);
|
setChunkSeed(&layerBiomeDummy, areaX+1, areaZ+1);
|
||||||
if(mcNextInt(&layerBiomeDummy, 6) == 5)
|
if (mcNextInt(&layerBiomeDummy, 6) == 5)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(j >= 5) continue;
|
if (j >= 5)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
|
||||||
int64_t hits = 0, swpc;
|
int64_t hits = 0, swpc;
|
||||||
|
|
||||||
for(j = 0; j < 0x10000; j++)
|
for (j = 0; j < 0x10000; j++)
|
||||||
{
|
{
|
||||||
seed = base + (j << 48);
|
seed = base + (j << 48);
|
||||||
|
|
||||||
@ -156,13 +158,13 @@ int main(int argc, char *argv[])
|
|||||||
setWorldSeed(&layerBiomeDummy, seed);
|
setWorldSeed(&layerBiomeDummy, seed);
|
||||||
|
|
||||||
setChunkSeed(&layerBiomeDummy, areaX+1, areaZ+1);
|
setChunkSeed(&layerBiomeDummy, areaX+1, areaZ+1);
|
||||||
if(mcNextInt(&layerBiomeDummy, 6) != 5)
|
if (mcNextInt(&layerBiomeDummy, 6) != 5)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// This seed base does not seem to contain many quad huts, so make
|
// This seed base does not seem to contain many quad huts, so make
|
||||||
// a more detailed analysis of the surroundings and see if there is
|
// a more detailed analysis of the surroundings and see if there is
|
||||||
// enough potential for more swamps to justify searching further.
|
// enough potential for more swamps to justify searching further.
|
||||||
if(hits == 0 && (j & 0xfff) == 0xfff)
|
if (hits == 0 && (j & 0xfff) == 0xfff)
|
||||||
{
|
{
|
||||||
swpc = 0;
|
swpc = 0;
|
||||||
setChunkSeed(&layerBiomeDummy, areaX, areaZ+1);
|
setChunkSeed(&layerBiomeDummy, areaX, areaZ+1);
|
||||||
@ -172,23 +174,24 @@ int main(int argc, char *argv[])
|
|||||||
setChunkSeed(&layerBiomeDummy, areaX, areaZ);
|
setChunkSeed(&layerBiomeDummy, areaX, areaZ);
|
||||||
swpc += mcNextInt(&layerBiomeDummy, 6) == 5;
|
swpc += mcNextInt(&layerBiomeDummy, 6) == 5;
|
||||||
|
|
||||||
if(swpc < (j > 0x1000 ? 2 : 1)) break;
|
if (swpc < (j > 0x1000 ? 2 : 1))
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dismiss seeds that don't have a swamp near the quad temple.
|
// Dismiss seeds that don't have a swamp near the quad temple.
|
||||||
setWorldSeed(lFilterBiome, seed);
|
setWorldSeed(lFilterBiome, seed);
|
||||||
genArea(lFilterBiome, biomeCache, (regPosX<<1)+2, (regPosZ<<1)+2, 1, 1);
|
genArea(lFilterBiome, biomeCache, (regPosX<<1)+2, (regPosZ<<1)+2, 1, 1);
|
||||||
|
|
||||||
if(biomeCache[0] != swamp)
|
if (biomeCache[0] != swamp)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
applySeed(&g, seed);
|
applySeed(&g, seed);
|
||||||
if(getBiomeAtPos(g, qhpos[0]) != swamp) continue;
|
if (getBiomeAtPos(g, qhpos[0]) != swamp) continue;
|
||||||
if(getBiomeAtPos(g, qhpos[1]) != swamp) continue;
|
if (getBiomeAtPos(g, qhpos[1]) != swamp) continue;
|
||||||
if(getBiomeAtPos(g, qhpos[2]) != swamp) continue;
|
if (getBiomeAtPos(g, qhpos[2]) != swamp) continue;
|
||||||
if(getBiomeAtPos(g, qhpos[3]) != swamp) continue;
|
if (getBiomeAtPos(g, qhpos[3]) != swamp) continue;
|
||||||
|
|
||||||
printf("%"PRId64 "\n", seed);
|
printf("%" PRId64 "\n", seed);
|
||||||
hits++;
|
hits++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
84
finders.c
84
finders.c
@ -73,7 +73,7 @@ int64_t *loadSavedSeeds(const char *fnam, int64_t *scnt)
|
|||||||
|
|
||||||
while (!feof(fp))
|
while (!feof(fp))
|
||||||
{
|
{
|
||||||
if (fscanf(fp, "%"PRId64, &seed) == 1) (*scnt)++;
|
if (fscanf(fp, "%" PRId64, &seed) == 1) (*scnt)++;
|
||||||
else while (!feof(fp) && fgetc(fp) != '\n');
|
else while (!feof(fp) && fgetc(fp) != '\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +83,7 @@ int64_t *loadSavedSeeds(const char *fnam, int64_t *scnt)
|
|||||||
|
|
||||||
for (int64_t i = 0; i < *scnt && !feof(fp);)
|
for (int64_t i = 0; i < *scnt && !feof(fp);)
|
||||||
{
|
{
|
||||||
if (fscanf(fp, "%"PRId64, &baseSeeds[i]) == 1) i++;
|
if (fscanf(fp, "%" PRId64, &baseSeeds[i]) == 1) i++;
|
||||||
else while (!feof(fp) && fgetc(fp) != '\n');
|
else while (!feof(fp) && fgetc(fp) != '\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -563,14 +563,14 @@ static DWORD WINAPI search4QuadBasesThread(LPVOID data)
|
|||||||
|
|
||||||
if (i < 32 && !fseek(fp, 1-i, SEEK_END) && fread(buf, i-1, 1, fp) > 0)
|
if (i < 32 && !fseek(fp, 1-i, SEEK_END) && fread(buf, i-1, 1, fp) > 0)
|
||||||
{
|
{
|
||||||
if (sscanf(buf, "%"PRId64, &seed) == 1)
|
if (sscanf(buf, "%" PRId64, &seed) == 1)
|
||||||
{
|
{
|
||||||
while (lowerBits[lowerBitsIdx] <= (seed & 0xffff))
|
while (lowerBits[lowerBitsIdx] <= (seed & 0xffff))
|
||||||
lowerBitsIdx++;
|
lowerBitsIdx++;
|
||||||
|
|
||||||
seed = (seed & 0x0000ffffffff0000) + lowerBits[lowerBitsIdx];
|
seed = (seed & 0x0000ffffffff0000) + lowerBits[lowerBitsIdx];
|
||||||
|
|
||||||
printf("Thread %d starting from: %"PRId64"\n", info.threadID, seed);
|
printf("Thread %d starting from: %" PRId64"\n", info.threadID, seed);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -586,9 +586,9 @@ static DWORD WINAPI search4QuadBasesThread(LPVOID data)
|
|||||||
{
|
{
|
||||||
if (isQuadBase(info.sconf, seed, info.quality))
|
if (isQuadBase(info.sconf, seed, info.quality))
|
||||||
{
|
{
|
||||||
fprintf(fp, "%"PRId64"\n", seed);
|
fprintf(fp, "%" PRId64"\n", seed);
|
||||||
fflush(fp);
|
fflush(fp);
|
||||||
//printf("Thread %d: %"PRId64"\n", info.threadID, seed);
|
//printf("Thread %d: %" PRId64"\n", info.threadID, seed);
|
||||||
}
|
}
|
||||||
|
|
||||||
lowerBitsIdx++;
|
lowerBitsIdx++;
|
||||||
@ -851,7 +851,6 @@ int isTreasureChunk(int64_t seed, const int chunkX, const int chunkZ)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
// Checking Biomes & Biome Helper Functions
|
// Checking Biomes & Biome Helper Functions
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
@ -1134,31 +1133,50 @@ static double getGrassProbability(int64_t seed, int biome, int x, int z)
|
|||||||
// TODO: Try to determine the actual probabilities and build a statistic.
|
// TODO: Try to determine the actual probabilities and build a statistic.
|
||||||
switch (biome)
|
switch (biome)
|
||||||
{
|
{
|
||||||
case plains: return 1.0;
|
case plains: return 1.0;
|
||||||
case mountains: return 0.8; // height dependent
|
case mountains: return 0.8; // height dependent
|
||||||
case forest: return 1.0;
|
case forest: return 1.0;
|
||||||
case taiga: return 1.0;
|
case taiga: return 1.0;
|
||||||
case swamp: return 0.6; // height dependent
|
case swamp: return 0.6; // height dependent
|
||||||
case river: return 0.2;
|
case river: return 0.5;
|
||||||
case beach: return 0.1;
|
case beach: return 0.1;
|
||||||
case wooded_hills: return 1.0;
|
case wooded_hills: return 1.0;
|
||||||
case taiga_hills: return 1.0;
|
case taiga_hills: return 1.0;
|
||||||
case mountain_edge: return 1.0; // height dependent
|
case mountain_edge: return 1.0; // height dependent
|
||||||
case jungle: return 1.0;
|
case jungle: return 1.0;
|
||||||
case jungle_hills: return 1.0;
|
case jungle_hills: return 1.0;
|
||||||
case jungleEdge: return 1.0;
|
case jungle_edge: return 1.0;
|
||||||
case birch_forest: return 1.0;
|
case birch_forest: return 1.0;
|
||||||
case birch_forest_hills: return 1.0;
|
case birch_forest_hills: return 1.0;
|
||||||
case dark_forest: return 0.9;
|
case dark_forest: return 0.9;
|
||||||
case snowy_taiga: return 0.1; // below trees
|
case snowy_taiga: return 0.2; // below trees
|
||||||
case snowy_taiga_hills: return 0.1; // below trees
|
case snowy_taiga_hills: return 0.2; // below trees
|
||||||
case giant_tree_taiga: return 0.6;
|
case giant_tree_taiga: return 0.6;
|
||||||
case giant_tree_taiga_hills: return 0.6;
|
case giant_tree_taiga_hills: return 0.6;
|
||||||
case wooded_mountains: return 0.2; // height dependent
|
case wooded_mountains: return 0.2; // height dependent
|
||||||
case savanna: return 1.0;
|
case savanna: return 1.0;
|
||||||
case savanna_plateau: return 1.0;
|
case savanna_plateau: return 1.0;
|
||||||
case wooded_badlands_plateau: return 0.1; // height dependent
|
case wooded_badlands_plateau: return 0.1; // height dependent
|
||||||
case badlands_plateau: return 0.1; // height dependent
|
case badlands_plateau: return 0.1; // height dependent
|
||||||
|
|
||||||
|
case sunflower_plains: return 1.0;
|
||||||
|
case gravelly_mountains: return 0.2;
|
||||||
|
case flower_forest: return 1.0;
|
||||||
|
case taiga_mountains: return 1.0;
|
||||||
|
case swamp_hills: return 0.9;
|
||||||
|
case modified_jungle: return 1.0;
|
||||||
|
case modified_jungle_edge: return 1.0;
|
||||||
|
case tall_birch_forest: return 1.0;
|
||||||
|
case tall_birch_hills: return 1.0;
|
||||||
|
case dark_forest_hills: return 0.9;
|
||||||
|
case snowy_taiga_mountains: return 0.2;
|
||||||
|
case giant_spruce_taiga: return 0.6;
|
||||||
|
case giant_spruce_taiga_hills: return 0.6;
|
||||||
|
case modified_gravelly_mountains: return 0.2;
|
||||||
|
case shattered_savanna: return 1.0;
|
||||||
|
case shattered_savanna_plateau: return 1.0;
|
||||||
|
case bamboo_jungle: return 0.4;
|
||||||
|
case bamboo_jungle_hills: return 0.4;
|
||||||
// NOTE: in rare circumstances you can get also get grassy islands that are
|
// NOTE: in rare circumstances you can get also get grassy islands that are
|
||||||
// completely in ocean variants...
|
// completely in ocean variants...
|
||||||
default: return 0;
|
default: return 0;
|
||||||
@ -1750,7 +1768,7 @@ BiomeFilter setupBiomeFilter(const int *biomeList, int listLen)
|
|||||||
|
|
||||||
if (isShallowOcean(id))
|
if (isShallowOcean(id))
|
||||||
{
|
{
|
||||||
bf.oceansToFind |= (1ULL < id);
|
bf.oceansToFind |= (1ULL << id);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
15
finders.h
15
finders.h
@ -128,14 +128,10 @@ STRUCT(BiomeFilter)
|
|||||||
int doScale4Check;
|
int doScale4Check;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
//==============================================================================
|
extern "C"
|
||||||
// Globals
|
{
|
||||||
//==============================================================================
|
#endif
|
||||||
|
|
||||||
extern Biome biomes[256];
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/******************************** SEED FINDING *********************************
|
/******************************** SEED FINDING *********************************
|
||||||
*
|
*
|
||||||
@ -569,5 +565,8 @@ int64_t checkForBiomes(
|
|||||||
const BiomeFilter filter,
|
const BiomeFilter filter,
|
||||||
const int minscale);
|
const int minscale);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* FINDERS_H_ */
|
#endif /* FINDERS_H_ */
|
||||||
|
12
generator.h
12
generator.h
@ -6,7 +6,8 @@
|
|||||||
/* Minecraft versions */
|
/* Minecraft versions */
|
||||||
enum MCversion
|
enum MCversion
|
||||||
{
|
{
|
||||||
MC_1_7, MC_1_8, MC_1_9, MC_1_10, MC_1_11, MC_1_12, MC_1_13, MC_1_14,
|
MC_1_7, MC_1_8, MC_1_9, MC_1_10, MC_1_11, MC_1_12, MC_1_13, MC_1_14,
|
||||||
|
MC_1_15, MC_1_16,
|
||||||
MCBE = 256
|
MCBE = 256
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -188,6 +189,11 @@ STRUCT(LayerStack)
|
|||||||
int layerCnt;
|
int layerCnt;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Initialise an instance of a generator. */
|
/* Initialise an instance of a generator. */
|
||||||
LayerStack setupGenerator(const int mcversion);
|
LayerStack setupGenerator(const int mcversion);
|
||||||
|
|
||||||
@ -223,5 +229,9 @@ void applySeed(LayerStack *g, int64_t seed);
|
|||||||
void genArea(Layer *layer, int *out, int areaX, int areaZ, int areaWidth, int areaHeight);
|
void genArea(Layer *layer, int *out, int areaX, int areaZ, int areaWidth, int areaHeight);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* GENERATOR_H_ */
|
#endif /* GENERATOR_H_ */
|
||||||
|
|
||||||
|
18
layers.c
18
layers.c
@ -183,6 +183,7 @@ void mapIsland(Layer *l, int * __restrict out, int areaX, int areaZ, int areaWid
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: currently SIMD only works properly for certain sizes
|
||||||
#if defined USE_SIMD && defined __AVX2__
|
#if defined USE_SIMD && defined __AVX2__
|
||||||
|
|
||||||
void mapZoom(Layer *l, int* __restrict out, int areaX, int areaZ, int areaWidth, int areaHeight)
|
void mapZoom(Layer *l, int* __restrict out, int areaX, int areaZ, int areaWidth, int areaHeight)
|
||||||
@ -200,7 +201,7 @@ void mapZoom(Layer *l, int* __restrict out, int areaX, int areaZ, int areaWidth,
|
|||||||
int pX = areaX&0xFFFFFFFE;
|
int pX = areaX&0xFFFFFFFE;
|
||||||
__m256i xs = _mm256_set_epi32(pX+14, pX+12, pX+10, pX+8, pX+6, pX+4, pX+2, pX), zs;
|
__m256i xs = _mm256_set_epi32(pX+14, pX+12, pX+10, pX+8, pX+6, pX+4, pX+2, pX), zs;
|
||||||
__m256i v2 = _mm256_set1_epi32(2), v16 = _mm256_set1_epi32(16);
|
__m256i v2 = _mm256_set1_epi32(2), v16 = _mm256_set1_epi32(16);
|
||||||
int* buf = malloc((newWidth+1)*((areaHeight+2)|1)*sizeof(*buf));
|
int* buf = (int*) malloc((newWidth+1)*((areaHeight+2)|1)*sizeof(*buf));
|
||||||
int* idx = buf;
|
int* idx = buf;
|
||||||
int* outIdx = out;
|
int* outIdx = out;
|
||||||
//z first!
|
//z first!
|
||||||
@ -262,7 +263,7 @@ void mapZoom(Layer *l, int* __restrict out, int areaX, int areaZ, int areaWidth,
|
|||||||
int pX = areaX&0xFFFFFFFE;
|
int pX = areaX&0xFFFFFFFE;
|
||||||
__m128i xs = _mm_set_epi32(pX+6, pX+4, pX+2, pX), zs;
|
__m128i xs = _mm_set_epi32(pX+6, pX+4, pX+2, pX), zs;
|
||||||
__m128i v2 = _mm_set1_epi32(2), v8 = _mm_set1_epi32(8);
|
__m128i v2 = _mm_set1_epi32(2), v8 = _mm_set1_epi32(8);
|
||||||
int* buf = malloc((newWidth+1)*(areaHeight+2|1)*sizeof(*buf));
|
int* buf = (int*) malloc((newWidth+1)*(areaHeight+2|1)*sizeof(*buf));
|
||||||
int* idx = buf;
|
int* idx = buf;
|
||||||
int* outIdx = out;
|
int* outIdx = out;
|
||||||
//z first!
|
//z first!
|
||||||
@ -314,27 +315,28 @@ void mapZoom(Layer *l, int * __restrict out, int areaX, int areaZ, int areaWidth
|
|||||||
{
|
{
|
||||||
int pX = areaX >> 1;
|
int pX = areaX >> 1;
|
||||||
int pZ = areaZ >> 1;
|
int pZ = areaZ >> 1;
|
||||||
int pWidth = (areaWidth >> 1) + 2;
|
int pWidth = ((areaX + areaWidth ) >> 1) - pX + 1;
|
||||||
int pHeight = (areaHeight >> 1) + 2;
|
int pHeight = ((areaZ + areaHeight) >> 1) - pZ + 1;
|
||||||
int x, z;
|
int x, z;
|
||||||
|
|
||||||
|
//printf("[%d %d] [%d %d]\n", pX, pZ, pWidth, pHeight);
|
||||||
l->p->getMap(l->p, out, pX, pZ, pWidth, pHeight);
|
l->p->getMap(l->p, out, pX, pZ, pWidth, pHeight);
|
||||||
|
|
||||||
int newWidth = (pWidth-1) << 1;
|
int newWidth = (pWidth) << 1;
|
||||||
int newHeight = (pHeight-1) << 1;
|
int newHeight = (pHeight) << 1;
|
||||||
int idx, a, b;
|
int idx, a, b;
|
||||||
int *buf = (int *)malloc((newWidth+1)*(newHeight+1)*sizeof(*buf));
|
int *buf = (int *)malloc((newWidth+1)*(newHeight+1)*sizeof(*buf));
|
||||||
|
|
||||||
const int ws = (int)l->worldSeed;
|
const int ws = (int)l->worldSeed;
|
||||||
const int ss = ws * (ws * 1284865837 + 4150755663);
|
const int ss = ws * (ws * 1284865837 + 4150755663);
|
||||||
|
|
||||||
for (z = 0; z < pHeight - 1; z++)
|
for (z = 0; z < pHeight; z++)
|
||||||
{
|
{
|
||||||
idx = (z << 1) * newWidth;
|
idx = (z << 1) * newWidth;
|
||||||
a = out[(z+0)*pWidth];
|
a = out[(z+0)*pWidth];
|
||||||
b = out[(z+1)*pWidth];
|
b = out[(z+1)*pWidth];
|
||||||
|
|
||||||
for (x = 0; x < pWidth - 1; x++)
|
for (x = 0; x < pWidth; x++)
|
||||||
{
|
{
|
||||||
int a1 = out[x+1 + (z+0)*pWidth];
|
int a1 = out[x+1 + (z+0)*pWidth];
|
||||||
int b1 = out[x+1 + (z+1)*pWidth];
|
int b1 = out[x+1 + (z+1)*pWidth];
|
||||||
|
29
layers.h
29
layers.h
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include "javarnd.h"
|
#include "javarnd.h"
|
||||||
|
|
||||||
|
#define __STDC_FORMAT_MACROS 1
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
@ -11,15 +13,21 @@
|
|||||||
#define NULL ((void*)0)
|
#define NULL ((void*)0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define SIMD_NOTIFY 0
|
||||||
|
|
||||||
#if defined USE_SIMD && __AVX2__
|
#if defined USE_SIMD && __AVX2__
|
||||||
#include <emmintrin.h>
|
#include <emmintrin.h>
|
||||||
#include <smmintrin.h>
|
#include <smmintrin.h>
|
||||||
#include <immintrin.h>
|
#include <immintrin.h>
|
||||||
|
#if SIMD_NOTIFY
|
||||||
#warning "Using AVX2 extensions."
|
#warning "Using AVX2 extensions."
|
||||||
|
#endif
|
||||||
#elif defined USE_SIMD && defined __SSE4_2__
|
#elif defined USE_SIMD && defined __SSE4_2__
|
||||||
#include <emmintrin.h>
|
#include <emmintrin.h>
|
||||||
#include <smmintrin.h>
|
#include <smmintrin.h>
|
||||||
|
#if SIMD_NOTIFY
|
||||||
#warning "Using SSE4.2 extensions."
|
#warning "Using SSE4.2 extensions."
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
//#warning "Using no SIMD extensions."
|
//#warning "Using no SIMD extensions."
|
||||||
#endif
|
#endif
|
||||||
@ -164,6 +172,10 @@ STRUCT(Layer)
|
|||||||
Layer *p, *p2; // parent layers
|
Layer *p, *p2; // parent layers
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
// Essentials
|
// Essentials
|
||||||
@ -352,10 +364,10 @@ static inline __m256i set8ChunkSeeds(int ws, __m256i xs, __m256i zs)
|
|||||||
|
|
||||||
static inline __m256i mc8NextInt(__m256i* cs, int ws, int mask)
|
static inline __m256i mc8NextInt(__m256i* cs, int ws, int mask)
|
||||||
{
|
{
|
||||||
__m256i and = _mm256_set1_epi32(mask);
|
__m256i andm = _mm256_set1_epi32(mask);
|
||||||
__m256i ret = _mm256_and_si256(and, _mm256_srli_epi32(*cs, 24));
|
__m256i ret = _mm256_and_si256(andm, _mm256_srli_epi32(*cs, 24));
|
||||||
*cs = _mm256_add_epi32(_mm256_set1_epi32(ws), _mm256_mullo_epi32(*cs, _mm256_add_epi32(_mm256_set1_epi32(4150755663), _mm256_mullo_epi32(*cs, _mm256_set1_epi32(1284865837)))));
|
*cs = _mm256_add_epi32(_mm256_set1_epi32(ws), _mm256_mullo_epi32(*cs, _mm256_add_epi32(_mm256_set1_epi32(4150755663), _mm256_mullo_epi32(*cs, _mm256_set1_epi32(1284865837)))));
|
||||||
return _mm256_add_epi32(ret, _mm256_and_si256(and, _mm256_cmpgt_epi32(_mm256_set1_epi32(0), ret)));;
|
return _mm256_add_epi32(ret, _mm256_and_si256(andm, _mm256_cmpgt_epi32(_mm256_set1_epi32(0), ret)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline __m256i select8Random2(__m256i* cs, int ws, __m256i a1, __m256i a2)
|
static inline __m256i select8Random2(__m256i* cs, int ws, __m256i a1, __m256i a2)
|
||||||
@ -431,10 +443,10 @@ static inline __m128i set4ChunkSeeds(int ws, __m128i xs, __m128i zs)
|
|||||||
|
|
||||||
static inline __m128i mc4NextInt(__m128i* cs, int ws, int mask)
|
static inline __m128i mc4NextInt(__m128i* cs, int ws, int mask)
|
||||||
{
|
{
|
||||||
__m128i and = _mm_set1_epi32(mask);
|
__m128i andm = _mm_set1_epi32(mask);
|
||||||
__m128i ret = _mm_and_si128(and, _mm_srli_epi32(*cs, 24));
|
__m128i ret = _mm_and_si128(andm, _mm_srli_epi32(*cs, 24));
|
||||||
*cs = _mm_add_epi32( _mm_set1_epi32(ws), _mm_mullo_epi32(*cs, _mm_add_epi32(_mm_set1_epi32(4150755663), _mm_mullo_epi32(*cs, _mm_set1_epi32(1284865837)))));
|
*cs = _mm_add_epi32( _mm_set1_epi32(ws), _mm_mullo_epi32(*cs, _mm_add_epi32(_mm_set1_epi32(4150755663), _mm_mullo_epi32(*cs, _mm_set1_epi32(1284865837)))));
|
||||||
return _mm_add_epi32(ret, _mm_and_si128(and, _mm_cmplt_epi32(ret, _mm_set1_epi32(0))));;
|
return _mm_add_epi32(ret, _mm_and_si128(andm, _mm_cmplt_epi32(ret, _mm_set1_epi32(0))));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline __m128i select4Random2(__m128i* cs, int ws, __m128i a1, __m128i a2)
|
static inline __m128i select4Random2(__m128i* cs, int ws, __m128i a1, __m128i a2)
|
||||||
@ -568,4 +580,9 @@ void mapOceanMix(Layer *l, int * __restrict out, int areaX, int areaZ, int areaW
|
|||||||
|
|
||||||
void mapVoronoiZoom(Layer *l, int * __restrict out, int x, int z, int w, int h);
|
void mapVoronoiZoom(Layer *l, int * __restrict out, int x, int z, int w, int h);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* LAYER_H_ */
|
#endif /* LAYER_H_ */
|
||||||
|
19
makefile
19
makefile
@ -1,21 +1,30 @@
|
|||||||
CC = gcc
|
CC = gcc
|
||||||
|
AR = ar
|
||||||
|
ARFLAGS = cr
|
||||||
override LDFLAGS = -lm
|
override LDFLAGS = -lm
|
||||||
override CFLAGS += -Wall -fwrapv -march=native
|
override CFLAGS += -Wall -fwrapv -march=native
|
||||||
|
#override CFLAGS += -DUSE_SIMD
|
||||||
|
|
||||||
ifeq ($(OS),Windows_NT)
|
ifeq ($(OS),Windows_NT)
|
||||||
override CFLAGS += -D_WIN32
|
override CFLAGS += -D_WIN32
|
||||||
|
RM = del
|
||||||
else
|
else
|
||||||
override LDFLAGS += -lX11 -pthread
|
override LDFLAGS += -lX11 -pthread
|
||||||
|
#RM = rm
|
||||||
endif
|
endif
|
||||||
|
|
||||||
.PHONY : all debug clean
|
.PHONY : all debug libcubiomes clean
|
||||||
|
|
||||||
all: CFLAGS += -O3
|
all: CFLAGS += -O3 -march=native
|
||||||
all: find_quadhuts find_compactbiomes clean
|
all: find_quadhuts find_compactbiomes clean
|
||||||
|
|
||||||
debug: CFLAGS += -DDEBUG -O0 -g
|
debug: CFLAGS += -DDEBUG -O0 -ggdb3
|
||||||
debug: find_quadhuts find_compactbiomes clean
|
debug: find_quadhuts find_compactbiomes clean
|
||||||
|
|
||||||
|
libcubiomes: CFLAGS += -O3 -fPIC
|
||||||
|
libcubiomes: layers.o generator.o finders.o util.o
|
||||||
|
$(AR) $(ARFLAGS) libcubiomes.a $^
|
||||||
|
|
||||||
find_compactbiomes: find_compactbiomes.o layers.o generator.o finders.o
|
find_compactbiomes: find_compactbiomes.o layers.o generator.o finders.o
|
||||||
$(CC) -o $@ $^ $(LDFLAGS)
|
$(CC) -o $@ $^ $(LDFLAGS)
|
||||||
|
|
||||||
@ -41,7 +50,9 @@ generator.o: generator.c generator.h
|
|||||||
layers.o: layers.c layers.h
|
layers.o: layers.c layers.h
|
||||||
$(CC) -c $(CFLAGS) $<
|
$(CC) -c $(CFLAGS) $<
|
||||||
|
|
||||||
|
util.o: util.c util.h
|
||||||
|
$(CC) -c $(CFLAGS) $<
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm *.o
|
$(RM) *.o
|
||||||
|
|
||||||
|
188
xmapview.c
188
xmapview.c
@ -1,133 +1,10 @@
|
|||||||
#include "xmapview.h"
|
#include "xmapview.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
/* Global biome colour table. */
|
|
||||||
|
|
||||||
|
|
||||||
void setBiomeColour(unsigned char biomeColour[256][3], int biome,
|
|
||||||
unsigned char r, unsigned char g, unsigned char b)
|
|
||||||
{
|
|
||||||
biomeColour[biome][0] = r;
|
|
||||||
biomeColour[biome][1] = g;
|
|
||||||
biomeColour[biome][2] = b;
|
|
||||||
}
|
|
||||||
|
|
||||||
void initBiomeColours(unsigned char biomeColours[256][3])
|
|
||||||
{
|
|
||||||
// This colouring scheme is taken from the AMIDST program:
|
|
||||||
// https://github.com/toolbox4minecraft/amidst
|
|
||||||
// https://sourceforge.net/projects/amidst.mirror/
|
|
||||||
|
|
||||||
memset(biomeColours, 0, 256*3);
|
|
||||||
|
|
||||||
setBiomeColour(biomeColours, ocean, 0, 0, 112);
|
|
||||||
setBiomeColour(biomeColours, plains,141, 179, 96);
|
|
||||||
setBiomeColour(biomeColours, desert, 250, 148, 24);
|
|
||||||
setBiomeColour(biomeColours, mountains, 96, 96, 96);
|
|
||||||
setBiomeColour(biomeColours, forest, 5, 102, 33);
|
|
||||||
setBiomeColour(biomeColours, taiga, 11, 102, 89);
|
|
||||||
setBiomeColour(biomeColours, swamp, 7, 249, 178);
|
|
||||||
setBiomeColour(biomeColours, river, 0, 0, 255);
|
|
||||||
setBiomeColour(biomeColours, hell, 255, 0, 0);
|
|
||||||
setBiomeColour(biomeColours, sky, 128, 128, 255);
|
|
||||||
setBiomeColour(biomeColours, frozen_ocean, 112, 112, 214);
|
|
||||||
setBiomeColour(biomeColours, frozen_river, 160, 160, 255);
|
|
||||||
setBiomeColour(biomeColours, snowy_tundra, 255, 255, 255);
|
|
||||||
setBiomeColour(biomeColours, snowy_mountains, 160, 160, 160);
|
|
||||||
setBiomeColour(biomeColours, mushroom_fields, 255, 0, 255);
|
|
||||||
setBiomeColour(biomeColours, mushroom_field_shore, 160, 0, 255);
|
|
||||||
setBiomeColour(biomeColours, beach, 250, 222, 85);
|
|
||||||
setBiomeColour(biomeColours, desert_hills, 210, 95, 18);
|
|
||||||
setBiomeColour(biomeColours, wooded_hills, 34, 85, 28);
|
|
||||||
setBiomeColour(biomeColours, taiga_hills, 22, 57, 51);
|
|
||||||
setBiomeColour(biomeColours, mountain_edge, 114, 120, 154);
|
|
||||||
setBiomeColour(biomeColours, jungle, 83, 123, 9);
|
|
||||||
setBiomeColour(biomeColours, jungle_hills, 44, 66, 5);
|
|
||||||
setBiomeColour(biomeColours, jungleEdge, 98, 139, 23);
|
|
||||||
setBiomeColour(biomeColours, deep_ocean, 0, 0, 48);
|
|
||||||
setBiomeColour(biomeColours, stone_shore, 162, 162, 132);
|
|
||||||
setBiomeColour(biomeColours, snowy_beach, 250, 240, 192);
|
|
||||||
setBiomeColour(biomeColours, birch_forest, 48, 116, 68);
|
|
||||||
setBiomeColour(biomeColours, birch_forest_hills, 31, 95, 50);
|
|
||||||
setBiomeColour(biomeColours, dark_forest, 64, 81, 26);
|
|
||||||
setBiomeColour(biomeColours, snowy_taiga, 49, 85, 74);
|
|
||||||
setBiomeColour(biomeColours, snowy_taiga_hills, 36, 63, 54);
|
|
||||||
setBiomeColour(biomeColours, giant_tree_taiga, 89, 102, 81);
|
|
||||||
setBiomeColour(biomeColours, giant_tree_taiga_hills, 69, 79, 62);
|
|
||||||
setBiomeColour(biomeColours, wooded_mountains, 80, 112, 80);
|
|
||||||
setBiomeColour(biomeColours, savanna, 189, 178, 95);
|
|
||||||
setBiomeColour(biomeColours, savanna_plateau, 167, 157, 100);
|
|
||||||
setBiomeColour(biomeColours, badlands, 217, 69, 21);
|
|
||||||
setBiomeColour(biomeColours, wooded_badlands_plateau, 176, 151, 101);
|
|
||||||
setBiomeColour(biomeColours, badlands_plateau, 202, 140, 101);
|
|
||||||
|
|
||||||
setBiomeColour(biomeColours, warm_ocean, 0, 0, 172);
|
|
||||||
setBiomeColour(biomeColours, lukewarm_ocean, 0, 0, 144);
|
|
||||||
setBiomeColour(biomeColours, cold_ocean, 32, 32, 112);
|
|
||||||
setBiomeColour(biomeColours, deep_warm_ocean, 0, 0, 80);
|
|
||||||
setBiomeColour(biomeColours, deep_lukewarm_ocean, 0, 0, 64);
|
|
||||||
setBiomeColour(biomeColours, deep_cold_ocean, 32, 32, 56);
|
|
||||||
setBiomeColour(biomeColours, deep_frozen_ocean, 64, 64, 144);
|
|
||||||
|
|
||||||
setBiomeColour(biomeColours, ocean+128, 0, 0, 112);
|
|
||||||
setBiomeColour(biomeColours, plains+128, 141, 179, 96);
|
|
||||||
setBiomeColour(biomeColours, desert+128, 250, 148, 24);
|
|
||||||
setBiomeColour(biomeColours, mountains+128, 96, 96, 96);
|
|
||||||
setBiomeColour(biomeColours, forest+128, 5, 102, 33);
|
|
||||||
setBiomeColour(biomeColours, taiga+128, 11, 102, 89);
|
|
||||||
setBiomeColour(biomeColours, swamp+128, 7, 249, 178);
|
|
||||||
setBiomeColour(biomeColours, river+128, 0, 0, 255);
|
|
||||||
setBiomeColour(biomeColours, hell+128, 255, 0, 0);
|
|
||||||
setBiomeColour(biomeColours, sky+128, 128, 128, 255);
|
|
||||||
setBiomeColour(biomeColours, frozen_ocean+128, 144, 144, 160);
|
|
||||||
setBiomeColour(biomeColours, frozen_river+128, 160, 160, 255);
|
|
||||||
setBiomeColour(biomeColours, snowy_tundra+128, 140, 180, 180);
|
|
||||||
setBiomeColour(biomeColours, snowy_mountains+128, 160, 160, 160);
|
|
||||||
setBiomeColour(biomeColours, mushroom_fields+128, 255, 0, 255);
|
|
||||||
setBiomeColour(biomeColours, mushroom_field_shore+128, 160, 0, 255);
|
|
||||||
setBiomeColour(biomeColours, beach+128, 250, 222, 85);
|
|
||||||
setBiomeColour(biomeColours, desert_hills+128, 210, 95, 18);
|
|
||||||
setBiomeColour(biomeColours, wooded_hills+128, 34, 85, 28);
|
|
||||||
setBiomeColour(biomeColours, taiga_hills+128, 22, 57, 51);
|
|
||||||
setBiomeColour(biomeColours, mountain_edge+128, 114, 120, 154);
|
|
||||||
setBiomeColour(biomeColours, jungle+128, 83, 123, 9);
|
|
||||||
setBiomeColour(biomeColours, jungle_hills+128, 44, 66, 5);
|
|
||||||
setBiomeColour(biomeColours, jungleEdge+128, 98, 139, 23);
|
|
||||||
setBiomeColour(biomeColours, deep_ocean+128, 0, 0, 48);
|
|
||||||
setBiomeColour(biomeColours, stone_shore+128, 162, 162, 132);
|
|
||||||
setBiomeColour(biomeColours, snowy_beach+128, 250, 240, 192);
|
|
||||||
setBiomeColour(biomeColours, birch_forest+128, 48, 116, 68);
|
|
||||||
setBiomeColour(biomeColours, birch_forest_hills+128, 31, 95, 50);
|
|
||||||
setBiomeColour(biomeColours, dark_forest+128, 64, 81, 26);
|
|
||||||
setBiomeColour(biomeColours, snowy_taiga+128, 49, 85, 74);
|
|
||||||
setBiomeColour(biomeColours, snowy_taiga_hills+128, 36, 63, 54);
|
|
||||||
setBiomeColour(biomeColours, giant_tree_taiga+128, 89, 102, 81);
|
|
||||||
setBiomeColour(biomeColours, giant_tree_taiga_hills+128, 69, 79, 62);
|
|
||||||
setBiomeColour(biomeColours, wooded_mountains+128, 80, 112, 80);
|
|
||||||
setBiomeColour(biomeColours, savanna+128, 189, 178, 95);
|
|
||||||
setBiomeColour(biomeColours, savanna_plateau+128, 167, 157, 100);
|
|
||||||
setBiomeColour(biomeColours, badlands+128, 217, 69, 21);
|
|
||||||
setBiomeColour(biomeColours, wooded_badlands_plateau+128, 176, 151, 101);
|
|
||||||
setBiomeColour(biomeColours, badlands_plateau+128, 202, 140, 101);
|
|
||||||
|
|
||||||
setBiomeColour(biomeColours, bamboo_jungle, 118, 142, 20);
|
|
||||||
setBiomeColour(biomeColours, bamboo_jungle_hills, 59, 71, 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
void initBiomeTypeColours(unsigned char biomeColours[256][3])
|
|
||||||
{
|
|
||||||
memset(biomeColours, 0, 256*3);
|
|
||||||
|
|
||||||
setBiomeColour(biomeColours, Oceanic, 0x00, 0x00, 0xa0);
|
|
||||||
setBiomeColour(biomeColours, Warm, 0xff, 0xc0, 0x00);
|
|
||||||
setBiomeColour(biomeColours, Lush, 0x00, 0xa0, 0x00);
|
|
||||||
setBiomeColour(biomeColours, Cold, 0x60, 0x60, 0x60);
|
|
||||||
setBiomeColour(biomeColours, Freezing, 0xff, 0xff, 0xff);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
xwin_t init_x(uint sx, uint sy, const char *titel)
|
xwin_t init_x(uint sx, uint sy, const char *titel)
|
||||||
{
|
{
|
||||||
xwin_t w;
|
xwin_t w;
|
||||||
@ -167,57 +44,6 @@ void close_x(xwin_t w)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void getBiomeColourMap(uint *colbuf, const unsigned char biomeColour[256][3],
|
|
||||||
const int *ints, const uint sx, const uint sy, const uint pixscale)
|
|
||||||
{
|
|
||||||
uint i, j;
|
|
||||||
int containsInvalidBiomes = 0;
|
|
||||||
|
|
||||||
for(j = 0; j < sy; j++)
|
|
||||||
{
|
|
||||||
for(i = 0; i < sx; i++)
|
|
||||||
{
|
|
||||||
int id = ints[i*sx+j]; //if(id != swamp) id = 100;
|
|
||||||
uint r, g, b;
|
|
||||||
|
|
||||||
if(id < 0 || id >= 256)
|
|
||||||
{
|
|
||||||
// This may happen for some intermediate layers
|
|
||||||
containsInvalidBiomes = 1;
|
|
||||||
r = biomeColour[id&0x7f][0]-40; r = (r>0xff) ? 0x00 : r&0xff;
|
|
||||||
g = biomeColour[id&0x7f][1]-40; g = (g>0xff) ? 0x00 : g&0xff;
|
|
||||||
b = biomeColour[id&0x7f][2]-40; b = (b>0xff) ? 0x00 : b&0xff;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(id < 128) {
|
|
||||||
r = biomeColour[id][0];
|
|
||||||
g = biomeColour[id][1];
|
|
||||||
b = biomeColour[id][2];
|
|
||||||
} else {
|
|
||||||
r = biomeColour[id][0]+40; r = (r>0xff) ? 0xff : r&0xff;
|
|
||||||
g = biomeColour[id][1]+40; g = (g>0xff) ? 0xff : g&0xff;
|
|
||||||
b = biomeColour[id][2]+40; b = (b>0xff) ? 0xff : b&0xff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint m, n;
|
|
||||||
for(m = 0; m < pixscale; m++){
|
|
||||||
for(n = 0; n < pixscale; n++){
|
|
||||||
colbuf[(j*pixscale+n) + sy*pixscale*(i*pixscale+m)] =
|
|
||||||
((r&0xff) << 16) + ((g&0xff) << 8) + (b&0xff);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(containsInvalidBiomes)
|
|
||||||
{
|
|
||||||
printf("Warning: Ints contain invalid Biome IDs (Is this an intermediate layer?)\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void viewmap(Layer *layer, unsigned char biomeColour[256][3], int areaX, int areaZ, uint areaWidth, uint areaHeight, uint pixscale)
|
void viewmap(Layer *layer, unsigned char biomeColour[256][3], int areaX, int areaZ, uint areaWidth, uint areaHeight, uint pixscale)
|
||||||
{
|
{
|
||||||
int *ints = allocCache(layer, areaWidth, areaHeight);
|
int *ints = allocCache(layer, areaWidth, areaHeight);
|
||||||
@ -227,7 +53,7 @@ void viewmap(Layer *layer, unsigned char biomeColour[256][3], int areaX, int are
|
|||||||
|
|
||||||
// Calculate a hash for the area (useful to verify the accuracy of the map)
|
// Calculate a hash for the area (useful to verify the accuracy of the map)
|
||||||
uint i, hash = 0;
|
uint i, hash = 0;
|
||||||
for(i = 0; i < areaWidth*areaHeight; i++) hash = hash ^ (i*(ints[i]+1));
|
for (i = 0; i < areaWidth*areaHeight; i++) hash = hash ^ (i*(ints[i]+1));
|
||||||
printf("Hash:%3X\n", hash&0xfff);
|
printf("Hash:%3X\n", hash&0xfff);
|
||||||
|
|
||||||
// construct the X11 window
|
// construct the X11 window
|
||||||
@ -242,19 +68,19 @@ void viewmap(Layer *layer, unsigned char biomeColour[256][3], int areaX, int are
|
|||||||
uint *colbuf = (uint *) malloc(sizeof(uint) *
|
uint *colbuf = (uint *) malloc(sizeof(uint) *
|
||||||
areaWidth*areaHeight*pixscale*pixscale);
|
areaWidth*areaHeight*pixscale*pixscale);
|
||||||
|
|
||||||
getBiomeColourMap(colbuf, biomeColour, ints, areaWidth, areaHeight, pixscale);
|
biomesToImage(colbuf, biomeColour, ints, areaWidth, areaHeight, pixscale, 0);
|
||||||
|
|
||||||
XImage *ximg = XCreateImage(w.dis, DefaultVisual(w.dis,0), 24, ZPixmap, 0,
|
XImage *ximg = XCreateImage(w.dis, DefaultVisual(w.dis,0), 24, ZPixmap, 0,
|
||||||
(char*)colbuf, areaWidth*pixscale, areaHeight*pixscale, 32, 0);
|
(char*)colbuf, areaWidth*pixscale, areaHeight*pixscale, 24, 0);
|
||||||
|
|
||||||
XSetForeground(w.dis, w.gc, 0xf00020);
|
XSetForeground(w.dis, w.gc, 0xf00020);
|
||||||
|
|
||||||
// enter the event loop
|
// enter the event loop
|
||||||
while(1)
|
while (1)
|
||||||
{
|
{
|
||||||
XNextEvent(w.dis, &event);
|
XNextEvent(w.dis, &event);
|
||||||
|
|
||||||
if(event.type == ClientMessage)
|
if (event.type == ClientMessage)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -20,11 +20,6 @@ typedef struct xwin_t
|
|||||||
|
|
||||||
} xwin_t;
|
} xwin_t;
|
||||||
|
|
||||||
|
|
||||||
void initBiomeColours(unsigned char biomeColours[256][3]);
|
|
||||||
void initBiomeTypeColours(unsigned char biomeColours[256][3]);
|
|
||||||
|
|
||||||
|
|
||||||
xwin_t init_x(uint sx, uint sy, const char *titel);
|
xwin_t init_x(uint sx, uint sy, const char *titel);
|
||||||
void close_x(xwin_t w);
|
void close_x(xwin_t w);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user