support texture rotation; better interaction of mouse centering & VC6 debugger; fix in-place conversion when mca blocks are written in different order

This commit is contained in:
Sean Barrett
2015-03-12 19:03:49 -07:00
parent 3d4f545fd7
commit efcd76c9ab
5 changed files with 160 additions and 61 deletions

View File

@ -11,11 +11,13 @@ Not very. Many Minecraft blocks are not handled correctly:
* Only one wood type
* Colored glass becomes regular glass
* Glass panes become glass blocks
* Water is opaque
* Water level is incorrect
* No biome coloration
* Cactus is not shrunk, shows holes
* Chests are not shrunk
* Chests, pumpkins, etc. are not rotated properly
* Double-chests draw as two chests
* Pumpkins etc. are not rotated properly
* Torches are drawn hackily, do not attach to walls
* Incorrect textures for blocks that postdate terrain.png
* Transparent textures have black fringes due to non-premultiplied-alpha
@ -47,9 +49,11 @@ things that way wouldn't be so bad.
Rails, ladders, and redstone lines could be implemented by
using tex2 to overlay those effects, but you can't rotate
tex1 and tex2 independently, so you'd have to have a
separate texture for each orientation of rail, etc, and
you'd need special rendering for rail up/down sections.
tex1 and tex2 independently, so there may be cases where
the underlying texture needs a different rotation from the
overlaid texture, which would require separate rendering.
Handling redstone's brightness being different from underlying
block's brightness would require separate rendering.
You can use the face-color effect to do biome coloration,
but the change won't be smooth the way it is in Minecraft.
@ -60,8 +64,7 @@ but the change won't be smooth the way it is in Minecraft.
Partly because converting from minecraft data is expensive.
Here is the approximate breakdown of an older version
of this executable and lib that did the building single-threaded,
and was a bit slower at building mesh data.
of this executable and lib that did the building single-threaded.
* 25% loading & parsing minecraft files (4/5ths of this is my zlib)
* 18% converting from minecraft blockids & lighting to stb blockids & lighting

View File

@ -66,7 +66,7 @@ static void print(char *text, ...)
pos_y += 10;
}
float camang[3], camloc[3] = { 0,0,75 };
float camang[3], camloc[3] = { 60,22,77 };
float player_zoom = 1.0;
float rotate_view = 0.0;
@ -551,8 +551,12 @@ int SDL_main(int argc, char **argv)
SDL_GL_MakeCurrent(window, context); // is this true by default?
// if (!IsDebuggerPresent())
SDL_SetRelativeMouseMode(SDL_TRUE);
#if defined(_MSC_VER) && _MSC_VER < 1300
// work around broken behavior in VC6 debugging
if (IsDebuggerPresent())
SDL_SetHint(SDL_HINT_MOUSE_RELATIVE_MODE_WARP, "1");
#endif
stbgl_initExtensions();

View File

@ -121,7 +121,7 @@ unsigned char minecraft_info[256][7] =
{ C_empty }, // fire
{ C_trans, 65,65,65,65,65,65 },
{ C_stair, 4,4,4,4,4,4 },
{ C_solid, 27,26,26,26,25,25 },
{ C_solid, 26,26,26,27,25,25 },
{ C_empty }, // redstone
// 56
@ -237,7 +237,7 @@ unsigned char minecraft_info[256][7] =
// 144
{ C_empty }, // mob head
{ C_empty }, // anvil
{ C_solid, 27,26,26,26,25,25 }, // trapped chest
{ C_solid, 26,26,26,27,25,25 }, // trapped chest
{ C_empty }, // weighted pressure plate light
{ C_empty }, // weighted pressure plat eheavy
{ C_empty }, // comparator inactive
@ -315,11 +315,13 @@ void convert_fastchunk_inplace(fast_chunk *fc)
{
int i;
int num_blocks=0, step=0;
unsigned char rot[4096] = { 0 };
unsigned char rot[4096];
#ifndef IN_PLACE
unsigned char *storage;
#endif
memset(rot, 0, 4096);
for (i=0; i < 16; ++i)
num_blocks += fc->blockdata[i] != NULL;
@ -340,15 +342,12 @@ void convert_fastchunk_inplace(fast_chunk *fc)
sky = fc->skylight[i];
#ifdef IN_PLACE
assert(dd < sky && sky < lt && lt < bd);
out = bd;
outb = dd;
#else
out = storage + 16*16*16*2*step;
outb = out + 16*16*16;
++step;
#endif
// bd is written in place, but also reads from dd
for (o=0; o < 16*16*16/2; o += 1) {
unsigned char v1,v2;
unsigned char d = dd[o];
@ -359,7 +358,7 @@ void convert_fastchunk_inplace(fast_chunk *fc)
{
//unsigned char d = bd[o] & 15;
v1 = remap_data[remap[v1]][d&15];
rot[o] = rotate_data[d&3];
rot[o*2+0] = rotate_data[d&3];
} else
v1 = effective_blocktype[v1];
@ -367,7 +366,7 @@ void convert_fastchunk_inplace(fast_chunk *fc)
{
//unsigned char d = bd[o] >> 4;
v2 = remap_data[remap[v2]][d>>4];
rot[o+1] = rotate_data[(d>>4)&3];
rot[o*2+1] = rotate_data[(d>>4)&3];
} else
v2 = effective_blocktype[v2];
@ -375,18 +374,54 @@ void convert_fastchunk_inplace(fast_chunk *fc)
out[o*2+1] = v2;
}
// because this stores to data[], can't run at same time as above loop
for (o=0; o < 16*16*16/2; ++o) {
int bright;
bright = (lt[o]&15)*12 + 15 + (sky[o]&15)*16;
if (bright > 255) bright = 255;
if (bright < 32) bright = 32;
outb[o*2+0] = STBVOX_MAKE_LIGHTING((unsigned char) bright, rot[o]);
// this reads from lt & sky
#ifndef IN_PLACE
outb = out + 16*16*16;
++step;
#endif
bright = (lt[o]>>4)*12 + 15 + (sky[o]>>4)*16;
if (bright > 255) bright = 255;
if (bright < 32) bright = 32;
outb[o*2+1] = STBVOX_MAKE_LIGHTING((unsigned char) bright, rot[o+1]);
// MC used to write in this order and it makes it possible to compute in-place
if (dd < sky && sky < lt) {
// @TODO go this path always if !IN_PLACE
#ifdef IN_PLACE
outb = dd;
#endif
for (o=0; o < 16*16*16/2; ++o) {
int bright;
bright = (lt[o]&15)*12 + 15 + (sky[o]&15)*16;
if (bright > 255) bright = 255;
if (bright < 32) bright = 32;
outb[o*2+0] = STBVOX_MAKE_LIGHTING((unsigned char) bright, (rot[o*2+0]&3));
bright = (lt[o]>>4)*12 + 15 + (sky[o]>>4)*16;
if (bright > 255) bright = 255;
if (bright < 32) bright = 32;
outb[o*2+1] = STBVOX_MAKE_LIGHTING((unsigned char) bright, (rot[o*2+1]&3));
}
} else {
// @TODO: if blocktype is in between others, this breaks; need to find which side has two pointers, and use that
// overwrite rot[] array, then copy out
#ifdef IN_PLACE
outb = (dd < sky) ? dd : sky;
if (lt < outb) lt = outb;
#endif
for (o=0; o < 16*16*16/2; ++o) {
int bright;
bright = (lt[o]&15)*12 + 15 + (sky[o]&15)*16;
if (bright > 255) bright = 255;
if (bright < 32) bright = 32;
rot[o*2+0] = STBVOX_MAKE_LIGHTING((unsigned char) bright, (rot[o*2+0]&3));
bright = (lt[o]>>4)*12 + 15 + (sky[o]>>4)*16;
if (bright > 255) bright = 255;
if (bright < 32) bright = 32;
rot[o*2+1] = STBVOX_MAKE_LIGHTING((unsigned char) bright, (rot[o*2+1]&3));
}
memcpy(outb, rot, 4096);
fc->data[i] = outb;
}
#ifndef IN_PLACE
@ -653,10 +688,11 @@ void build_stair_rotations(int blocktype, unsigned char *map)
int i,j,k;
for (j=0; j < 2; ++j) {
int geom = j ? STBVOX_GEOM_ceil_slope_north_is_bottom : STBVOX_GEOM_floor_slope_north_is_top;
//int geom = STBVOX_GEOM_solid;
for (i=0; i < 4; ++i) {
if (i == 0 && j == 0) {
map[j*4+i+8] = map[j*4+i] = blocktype;
minecraft_geom_for_blocktype[blocktype] = (unsigned char) STBVOX_MAKE_GEOMETRY(geom, mc_rot[i], 0);
minecraft_geom_for_blocktype[blocktype] = (unsigned char) STBVOX_MAKE_GEOMETRY(geom, 0, 0);
} else {
map[j*4+i+8] = map[j*4+i] = next_blocktype;
@ -664,7 +700,7 @@ void build_stair_rotations(int blocktype, unsigned char *map)
minecraft_color_for_blocktype[next_blocktype][k] = minecraft_color_for_blocktype[blocktype][k];
minecraft_tex1_for_blocktype [next_blocktype][k] = minecraft_tex1_for_blocktype [blocktype][k];
}
minecraft_geom_for_blocktype[next_blocktype] = (unsigned char) STBVOX_MAKE_GEOMETRY(geom, mc_rot[i], 0);
minecraft_geom_for_blocktype[next_blocktype] = (unsigned char) STBVOX_MAKE_GEOMETRY(geom, 0, 0);
--next_blocktype;
}
}
@ -690,6 +726,15 @@ void build_wool_variations(int bt, unsigned char *map)
}
}
void remap_in_place(int bt, int rm)
{
int i;
remap[bt] = rm;
for (i=0; i < 16; ++i)
remap_data[rm][i] = bt;
}
void mesh_init(void)
{
int i;
@ -750,6 +795,10 @@ void mesh_init(void)
remap[35] = 8;
build_wool_variations(35, remap_data[remap[35]]);
// set the remap flags for these so they write the rotation values
remap_in_place(54, 9);
remap_in_place(146, 10);
for (i=0; i < 256; ++i) {
if (remap[i])
effective_block_add[i] = 0;

View File

@ -123,6 +123,10 @@ SOURCE=.\glext_list.h
# End Source File
# Begin Source File
SOURCE=.\README.md
# End Source File
# Begin Source File
SOURCE=.\win32\SDL_windows_main.c
# End Source File
# Begin Source File