Codebase ported from old project

also added many new things
This commit is contained in:
xtreme8000 2022-11-11 19:00:55 +01:00
parent a51338735c
commit 97d6b8c041
69 changed files with 6295 additions and 0 deletions

38
.clang-format Executable file
View file

@ -0,0 +1,38 @@
---
BasedOnStyle: WebKit
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: 'false'
AlignConsecutiveDeclarations: 'false'
AlignTrailingComments: 'true'
AllowAllParametersOfDeclarationOnNextLine: 'true'
AllowShortBlocksOnASingleLine: 'true'
AllowShortCaseLabelsOnASingleLine: 'true'
AllowShortFunctionsOnASingleLine: Empty
AllowShortIfStatementsOnASingleLine: 'false'
AllowShortLoopsOnASingleLine: 'false'
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: 'false'
BreakBeforeBraces: Attach
BreakBeforeTernaryOperators: 'false'
Cpp11BracedListStyle: 'true'
ExperimentalAutoDetectBinPacking: 'false'
IndentCaseLabels: 'true'
KeepEmptyLinesAtTheStartOfBlocks: 'false'
Language: Cpp
PointerAlignment: Left
SortIncludes: 'true'
SpaceAfterCStyleCast: 'false'
SpaceBeforeAssignmentOperators: 'true'
SpaceBeforeParens: Never
SpaceInEmptyParentheses: 'false'
SpacesInCStyleCastParentheses: 'false'
SpacesInParentheses: 'false'
SpacesInSquareBrackets: 'false'
TabWidth: '4'
UseTab: Always
MaxEmptyLinesToKeep: 1
ReflowComments: 'true'
ColumnLimit: '80'
...

5
.editorconfig Executable file
View file

@ -0,0 +1,5 @@
[*]
indent_style = tab
indent_size = 4
end_of_line = lf
trim_trailing_whitespace = true

150
Makefile Normal file
View file

@ -0,0 +1,150 @@
#---------------------------------------------------------------------------------
# Clear the implicit built in rules
#---------------------------------------------------------------------------------
.SUFFIXES:
.SECONDARY:
#---------------------------------------------------------------------------------
# prevent deletion of implicit targets
#---------------------------------------------------------------------------------
.SECONDARY:
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITPPC)),)
$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=<path to>devkitPPC")
endif
include $(DEVKITPPC)/wii_rules
#---------------------------------------------------------------------------------
# TARGET is the name of the output
# BUILD is the directory where object files & intermediate files will be placed
# SOURCES is a list of directories containing source code
# INCLUDES is a list of directories containing extra header files
#---------------------------------------------------------------------------------
TARGET := $(notdir $(CURDIR))
BUILD := build
SOURCES := source source/block
DATA :=
TEXTURES := textures
INCLUDES :=
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
CFLAGS = -std=c99 -pedantic -Wextra -Wno-unused-parameter -flto=auto -O3 -Wall $(MACHDEP) $(INCLUDE)
CXXFLAGS = $(CFLAGS)
LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map
#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project
#---------------------------------------------------------------------------------
LIBS := -lwiiuse -lfat -lbte -logc -lm
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS :=
#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
# rules for different file extensions
#---------------------------------------------------------------------------------
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------
export OUTPUT := $(CURDIR)/$(TARGET)
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir)) \
$(foreach dir,$(TEXTURES),$(CURDIR)/$(dir))
export DEPSDIR := $(CURDIR)/$(BUILD)
#---------------------------------------------------------------------------------
# automatically build a list of object files for our project
#---------------------------------------------------------------------------------
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S)))
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
SCFFILES := $(foreach dir,$(TEXTURES),$(notdir $(wildcard $(dir)/*.scf)))
TPLFILES := $(SCFFILES:.scf=.tpl)
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
export LD := $(CC)
else
export LD := $(CXX)
endif
export OFILES := $(addsuffix .o,$(BINFILES)) \
$(addsuffix .o,$(TPLFILES)) \
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \
$(sFILES:.s=.o) $(SFILES:.S=.o)
#---------------------------------------------------------------------------------
# build a list of include paths
#---------------------------------------------------------------------------------
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
-I$(CURDIR)/$(BUILD) \
-I$(LIBOGC_INC)
#---------------------------------------------------------------------------------
# build a list of library paths
#---------------------------------------------------------------------------------
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \
-L$(LIBOGC_LIB)
export OUTPUT := $(CURDIR)/$(TARGET)
.PHONY: $(BUILD) clean
#---------------------------------------------------------------------------------
$(BUILD):
@[ -d $@ ] || mkdir -p $@
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
#---------------------------------------------------------------------------------
clean:
@echo clean ...
@rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).dol
#---------------------------------------------------------------------------------
run:
wiiload $(OUTPUT).dol
#---------------------------------------------------------------------------------
else
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
$(OUTPUT).dol: $(OUTPUT).elf
$(OUTPUT).elf: $(OFILES)
#---------------------------------------------------------------------------------
# This rule links in binary data with the .bin extension
#---------------------------------------------------------------------------------
%.bin.o : %.bin
#---------------------------------------------------------------------------------
@echo $(notdir $<)
$(bin2o)
#---------------------------------------------------------------------------------
%.tpl.o : %.tpl
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(bin2o)
-include $(DEPSDIR)/*.d
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------

BIN
icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

10
meta.xml Normal file
View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<app version="1">
<name>CavEX</name>
<version>Alpha 0.1.0</version>
<release_date>20221110000000</release_date>
<coder>ByteBit/xtreme8000</coder>
<short_description></short_description>
<long_description>https://github.com/xtreme8000/CavEX</long_description>
<ahb_access/>
</app>

72
source/block/aabb.c Normal file
View file

@ -0,0 +1,72 @@
#include <assert.h>
#include <math.h>
#include "aabb.h"
void aabb_setsize(struct AABB* a, float sx, float sy, float sz) {
assert(a);
a->x1 = 0.5F - sx / 2.0F;
a->y1 = 0;
a->z1 = 0.5F - sz / 2.0F;
a->x2 = 0.5F + sx / 2.0F;
a->y2 = sy;
a->z2 = 0.5F + sz / 2.0F;
}
void aabb_translate(struct AABB* a, float x, float y, float z) {
assert(a);
a->x1 += x;
a->y1 += y;
a->z1 += z;
a->x2 += x;
a->y2 += y;
a->z2 += z;
}
// see: https://tavianator.com/2011/ray_box.html
bool aabb_intersection_ray(struct AABB* a, struct ray* r, enum side* s) {
assert(a && r);
float inv_x = 1.0F / r->dx;
float tx1 = (a->x1 - r->x) * inv_x;
float tx2 = (a->x2 - r->x) * inv_x;
float tmin = fminf(tx1, tx2);
float tmax = fmaxf(tx1, tx2);
float inv_y = 1.0F / r->dy;
float ty1 = (a->y1 - r->y) * inv_y;
float ty2 = (a->y2 - r->y) * inv_y;
tmin = fmaxf(tmin, fminf(fminf(ty1, ty2), tmax));
tmax = fminf(tmax, fmaxf(fmaxf(ty1, ty2), tmin));
float inv_z = 1.0F / r->dz;
float tz1 = (a->z1 - r->z) * inv_z;
float tz2 = (a->z2 - r->z) * inv_z;
tmin = fmaxf(tmin, fminf(fminf(tz1, tz2), tmax));
tmax = fminf(tmax, fmaxf(fmaxf(tz1, tz2), tmin));
// is fine since fmaxf and fminf return the same value as one of the inputs
if(s) {
if(tmin == tx1)
*s = SIDE_LEFT;
else if(tmin == tx2)
*s = SIDE_RIGHT;
else if(tmin == ty1)
*s = SIDE_BOTTOM;
else if(tmin == ty2)
*s = SIDE_TOP;
else if(tmin == tz1)
*s = SIDE_FRONT;
else if(tmin == tz2)
*s = SIDE_BACK;
}
return tmax > fmax(tmin, 0.0F);
}

22
source/block/aabb.h Normal file
View file

@ -0,0 +1,22 @@
#ifndef AABB_H
#define AABB_H
#include <stdbool.h>
struct AABB {
float x1, y1, z1;
float x2, y2, z2;
};
struct ray {
float x, y, z;
float dx, dy, dz;
};
#include "blocks.h"
void aabb_setsize(struct AABB* a, float sx, float sy, float sz);
void aabb_translate(struct AABB* a, float x, float y, float z);
bool aabb_intersection_ray(struct AABB* a, struct ray* r, enum side* s);
#endif

80
source/block/block_bed.c Normal file
View file

@ -0,0 +1,80 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_WOOD;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
aabb_setsize(x, 1.0F, 0.5625F, 1.0F);
return true;
}
// TODO: add missing bed legs to mask? (difficult, many states)
struct face_occlusion side_mask = {
.mask = {0x00000000, 0x00000000, 0x00000000, 0x0000FFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFF0000, 0x00000000},
};
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
switch(side) {
case SIDE_TOP:
case SIDE_BOTTOM: return face_occlusion_empty();
default: return &side_mask;
}
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_FULL;
}
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
if(this->block->metadata & 0x8) {
switch(side) {
case SIDE_TOP: return TEXTURE_INDEX(7, 8);
case SIDE_LEFT:
case SIDE_RIGHT:
return (this->block->metadata & 0x1) ? TEXTURE_INDEX(11, 8) :
TEXTURE_INDEX(10, 8);
case SIDE_FRONT:
case SIDE_BACK:
return (this->block->metadata & 0x1) ? TEXTURE_INDEX(10, 8) :
TEXTURE_INDEX(11, 8);
default: return TEXTURE_INDEX(4, 0);
}
} else {
switch(side) {
case SIDE_TOP: return TEXTURE_INDEX(6, 8);
case SIDE_LEFT:
case SIDE_RIGHT:
return (this->block->metadata & 0x1) ? TEXTURE_INDEX(8, 8) :
TEXTURE_INDEX(9, 8);
case SIDE_FRONT:
case SIDE_BACK:
return (this->block->metadata & 0x1) ? TEXTURE_INDEX(9, 8) :
TEXTURE_INDEX(8, 8);
default: return TEXTURE_INDEX(4, 0);
}
}
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return 0xFFFFFF;
}
struct block block_bed = {
.name = "Bed",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_bed,
.luminance = 0,
.double_sided = false,
.can_see_through = true,
.ignore_lighting = false,
};

44
source/block/block_bedrock.c Executable file
View file

@ -0,0 +1,44 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_STONE;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
aabb_setsize(x, 1.0F, 1.0F, 1.0F);
return true;
}
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
return face_occlusion_full();
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_FULL;
}
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
return TEXTURE_INDEX(1, 1);
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return 0xFFFFFF;
}
struct block block_bedrock = {
.name = "Bedrock",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_full,
.luminance = 0,
.double_sided = false,
.can_see_through = false,
.ignore_lighting = false,
};

View file

@ -0,0 +1,44 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_STONE;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
aabb_setsize(x, 1.0F, 1.0F, 1.0F);
return true;
}
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
return face_occlusion_full();
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_FULL;
}
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
return TEXTURE_INDEX(7, 0);
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return 0xFFFFFF;
}
struct block block_bricks = {
.name = "Bricks",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_full,
.luminance = 0,
.double_sided = false,
.can_see_through = false,
.ignore_lighting = false,
};

View file

@ -0,0 +1,45 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_ORGANIC;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
aabb_setsize(x, 0.375F, 0.375F, 0.375F);
return !entity;
}
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
return face_occlusion_empty();
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_CROSS;
}
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
return TEXTURE_INDEX(13, 1);
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return 0xFFFFFF;
}
struct block block_brown_mushroom = {
.name = "Brown mushroom",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_cross,
.luminance = 1,
.double_sided = true,
.can_see_through = true,
.render_block_data.cross_random_displacement = false,
.ignore_lighting = false,
};

View file

@ -0,0 +1,57 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_ORGANIC;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
aabb_setsize(x, 0.875F, 1.0F, 0.875F);
return true;
}
struct face_occlusion side_top_bottom = {
.mask = {0x00007FFE, 0x7FFE7FFE, 0x7FFE7FFE, 0x7FFE7FFE, 0x7FFE7FFE,
0x7FFE7FFE, 0x7FFE7FFE, 0x7FFE0000},
};
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
switch(side) {
case SIDE_TOP:
case SIDE_BOTTOM: return &side_top_bottom;
default: return face_occlusion_empty();
}
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_FULL;
}
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
switch(side) {
case SIDE_TOP: return TEXTURE_INDEX(5, 4);
case SIDE_BOTTOM: return TEXTURE_INDEX(7, 4);
default: return TEXTURE_INDEX(6, 4);
}
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return 0xFFFFFF;
}
struct block block_cactus = {
.name = "Cactus",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_cactus,
.luminance = 0,
.double_sided = false,
.can_see_through = true,
.ignore_lighting = false,
};

62
source/block/block_cake.c Normal file
View file

@ -0,0 +1,62 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_WOOL;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
// TODO: AABB hitbox for all states
aabb_setsize(x, 0.875F - 0.125F * this->block->metadata, 0.5F, 0.875F);
aabb_translate(x, 0.0625F * this->block->metadata, 0, 0);
return true;
}
// TODO: mask not correct for all states
struct face_occlusion bottom_mask = {
.mask = {0x00007FFE, 0x7FFE7FFE, 0x7FFE7FFE, 0x7FFE7FFE, 0x7FFE7FFE,
0x7FFE7FFE, 0x7FFE7FFE, 0x7FFE0000},
};
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
switch(side) {
case SIDE_BOTTOM: return &bottom_mask;
default: return face_occlusion_empty();
}
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_FULL;
}
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
switch(side) {
case SIDE_TOP: return TEXTURE_INDEX(9, 7);
case SIDE_BOTTOM: return TEXTURE_INDEX(12, 7);
case SIDE_LEFT:
return (this->block->metadata > 0) ? TEXTURE_INDEX(11, 7) :
TEXTURE_INDEX(10, 7);
default: return TEXTURE_INDEX(10, 7);
}
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return 0xFFFFFF;
}
struct block block_cake = {
.name = "Cake",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_cake,
.luminance = 0,
.double_sided = false,
.can_see_through = true,
.ignore_lighting = false,
};

View file

@ -0,0 +1,104 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_STONE;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
aabb_setsize(x, 1.0F, 1.0F, 1.0F);
return true;
}
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
return face_occlusion_full();
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_FULL;
}
static uint8_t getTextureIndex1(struct block_info* this, enum side side) {
return TEXTURE_INDEX(6, 1);
}
static uint8_t getTextureIndex2(struct block_info* this, enum side side) {
return TEXTURE_INDEX(7, 1);
}
static uint8_t getTextureIndex3(struct block_info* this, enum side side) {
return TEXTURE_INDEX(8, 1);
}
static uint8_t getTextureIndex4(struct block_info* this, enum side side) {
return TEXTURE_INDEX(0, 9);
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return 0xFFFFFF;
}
struct block block_iron = {
.name = "Block of Iron",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex1,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_full,
.luminance = 0,
.double_sided = false,
.can_see_through = false,
.ignore_lighting = false,
};
struct block block_gold = {
.name = "Block of Gold",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex2,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_full,
.luminance = 0,
.double_sided = false,
.can_see_through = false,
.ignore_lighting = false,
};
struct block block_diamond = {
.name = "Diamond Block",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex3,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_full,
.luminance = 0,
.double_sided = false,
.can_see_through = false,
.ignore_lighting = false,
};
struct block block_lapis = {
.name = "Lapis Block",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex4,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_full,
.luminance = 0,
.double_sided = false,
.can_see_through = false,
.ignore_lighting = false,
};

126
source/block/block_chest.c Normal file
View file

@ -0,0 +1,126 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_WOOD;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
aabb_setsize(x, 1.0F, 1.0F, 1.0F);
return true;
}
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
return face_occlusion_full();
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_FULL;
}
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
struct block_data right
= world_get_block(this->world, this->x + 1, this->y, this->z);
struct block_data left
= world_get_block(this->world, this->x - 1, this->y, this->z);
struct block_data back
= world_get_block(this->world, this->x, this->y, this->z + 1);
struct block_data front
= world_get_block(this->world, this->x, this->y, this->z - 1);
if(right.type == this->block->type) {
switch(side) {
case SIDE_TOP:
case SIDE_BOTTOM: return TEXTURE_INDEX(9, 1);
case SIDE_BACK: return TEXTURE_INDEX(9, 2);
case SIDE_FRONT: return TEXTURE_INDEX(10, 3);
default: return TEXTURE_INDEX(10, 1);
}
}
if(left.type == this->block->type) {
switch(side) {
case SIDE_TOP:
case SIDE_BOTTOM: return TEXTURE_INDEX(9, 1);
case SIDE_BACK: return TEXTURE_INDEX(10, 2);
case SIDE_FRONT: return TEXTURE_INDEX(9, 3);
default: return TEXTURE_INDEX(10, 1);
}
}
if(back.type == this->block->type) {
switch(side) {
case SIDE_TOP:
case SIDE_BOTTOM: return TEXTURE_INDEX(9, 1);
case SIDE_RIGHT: return TEXTURE_INDEX(10, 2);
case SIDE_LEFT: return TEXTURE_INDEX(9, 3);
default: return TEXTURE_INDEX(10, 1);
}
}
if(front.type == this->block->type) {
switch(side) {
case SIDE_TOP:
case SIDE_BOTTOM: return TEXTURE_INDEX(9, 1);
case SIDE_RIGHT: return TEXTURE_INDEX(9, 2);
case SIDE_LEFT: return TEXTURE_INDEX(10, 3);
default: return TEXTURE_INDEX(10, 1);
}
}
uint8_t tex[SIDE_MAX] = {
[SIDE_TOP] = TEXTURE_INDEX(9, 1), [SIDE_BOTTOM] = TEXTURE_INDEX(9, 1),
[SIDE_BACK] = TEXTURE_INDEX(10, 1), [SIDE_FRONT] = TEXTURE_INDEX(10, 1),
[SIDE_LEFT] = TEXTURE_INDEX(10, 1), [SIDE_RIGHT] = TEXTURE_INDEX(10, 1),
};
if(left.type && !right.type)
tex[SIDE_RIGHT] = TEXTURE_INDEX(11, 1);
else if(right.type && !left.type)
tex[SIDE_LEFT] = TEXTURE_INDEX(11, 1);
else if(front.type && !back.type)
tex[SIDE_BACK] = TEXTURE_INDEX(11, 1);
else if(back.type && !front.type)
tex[SIDE_FRONT] = TEXTURE_INDEX(11, 1);
else
tex[SIDE_BACK] = TEXTURE_INDEX(11, 1);
return tex[side];
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return 0xFFFFFF;
}
struct block block_chest = {
.name = "Chest",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_full,
.luminance = 0,
.double_sided = false,
.can_see_through = false,
.ignore_lighting = false,
};
struct block block_locked_chest = {
.name = "Chest",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_full,
.luminance = 15,
.double_sided = false,
.can_see_through = false,
.ignore_lighting = false,
};

44
source/block/block_clay.c Normal file
View file

@ -0,0 +1,44 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_SAND;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
aabb_setsize(x, 1.0F, 1.0F, 1.0F);
return true;
}
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
return face_occlusion_full();
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_FULL;
}
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
return TEXTURE_INDEX(8, 4);
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return 0xFFFFFF;
}
struct block block_clay = {
.name = "Clay",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_full,
.luminance = 0,
.double_sided = false,
.can_see_through = false,
.ignore_lighting = false,
};

View file

@ -0,0 +1,63 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_STONE;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
aabb_setsize(x, 1.0F, 1.0F, 1.0F);
return true;
}
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
return face_occlusion_full();
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_FULL;
}
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
switch(this->block->type) {
default: return TEXTURE_INDEX(0, 1);
case 48: return TEXTURE_INDEX(4, 2);
}
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return 0xFFFFFF;
}
struct block block_cobblestone = {
.name = "Cobblestone",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_full,
.luminance = 0,
.double_sided = false,
.can_see_through = false,
.ignore_lighting = false,
};
struct block block_mossstone = {
.name = "Moss Stone",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_full,
.luminance = 0,
.double_sided = false,
.can_see_through = false,
.ignore_lighting = false,
};

View file

@ -0,0 +1,44 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_ORGANIC;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
aabb_setsize(x, 1.0F, 0.25F, 1.0F);
return !entity;
}
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
return face_occlusion_empty();
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_CROSS;
}
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
return TEXTURE_INDEX(this->block->metadata + 6, 5);
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return 0xFFFFFF;
}
struct block block_crops = {
.name = "Crops",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_crops,
.luminance = 0,
.double_sided = true,
.can_see_through = true,
.ignore_lighting = false,
};

44
source/block/block_dirt.c Normal file
View file

@ -0,0 +1,44 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_ORGANIC;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
aabb_setsize(x, 1.0F, 1.0F, 1.0F);
return true;
}
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
return face_occlusion_full();
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_FULL;
}
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
return TEXTURE_INDEX(2, 0);
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return 0xFFFFFF;
}
struct block block_dirt = {
.name = "Dirt",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_full,
.luminance = 0,
.double_sided = false,
.can_see_through = false,
.ignore_lighting = false,
};

View file

@ -0,0 +1,57 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_STONE;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
aabb_setsize(x, 1.0F, 1.0F, 1.0F);
return true;
}
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
return face_occlusion_full();
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_FULL;
}
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
switch(this->block->metadata) {
default:
case 0:
return (side == SIDE_TOP || side == SIDE_BOTTOM) ?
TEXTURE_INDEX(6, 0) :
TEXTURE_INDEX(5, 0);
case 1:
return (side == SIDE_TOP) ?
TEXTURE_INDEX(0, 11) :
((side == SIDE_BOTTOM) ? TEXTURE_INDEX(0, 13) :
TEXTURE_INDEX(0, 12));
case 2: return TEXTURE_INDEX(4, 0);
case 3: return TEXTURE_INDEX(0, 1);
}
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return 0xFFFFFF;
}
struct block block_double_slab = {
.name = "Double Slab",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_full,
.luminance = 0,
.double_sided = false,
.can_see_through = false,
.ignore_lighting = false,
};

View file

@ -0,0 +1,53 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_ORGANIC;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
aabb_setsize(x, 1.0F, 0.9375F, 1.0F);
return true;
}
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
switch(side) {
case SIDE_TOP: return face_occlusion_empty();
case SIDE_BOTTOM: return face_occlusion_full();
default: return face_occlusion_rect(15);
}
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_FULL;
}
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
switch(side) {
case SIDE_TOP:
return (this->block->metadata < 7) ? TEXTURE_INDEX(5, 5) :
TEXTURE_INDEX(4, 5);
default: return TEXTURE_INDEX(2, 0);
}
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return 0xFFFFFF;
}
struct block block_farmland = {
.name = "Farmland",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_farmland,
.luminance = 0,
.double_sided = false,
.can_see_through = true,
.ignore_lighting = true,
};

44
source/block/block_fire.c Normal file
View file

@ -0,0 +1,44 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_STONE;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
aabb_setsize(x, 1.0F, 1.0F, 1.0F);
return !entity;
}
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
return face_occlusion_empty();
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_FULL;
}
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
return TEXTURE_INDEX(3, 0);
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return 0xFFFFFF;
}
struct block block_fire = {
.name = "Fire",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = true,
.getBaseColor = getBaseColor,
.renderBlock = render_block_full,
.luminance = 0,
.double_sided = false,
.can_see_through = true,
.ignore_lighting = false,
};

View file

@ -0,0 +1,45 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_ORGANIC;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
aabb_setsize(x, 0.375F, 0.625F, 0.375F);
return !entity;
}
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
return face_occlusion_empty();
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_CROSS;
}
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
return TEXTURE_INDEX(13, 0);
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return 0xFFFFFF;
}
struct block block_flower = {
.name = "Flower",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_cross,
.luminance = 0,
.double_sided = true,
.can_see_through = true,
.render_block_data.cross_random_displacement = false,
.ignore_lighting = false,
};

View file

@ -0,0 +1,82 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_STONE;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
aabb_setsize(x, 1.0F, 1.0F, 1.0F);
return true;
}
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
return face_occlusion_full();
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_FULL;
}
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
switch(side) {
case SIDE_FRONT:
if(this->block->metadata == 2)
return TEXTURE_INDEX(12, 2);
else
return TEXTURE_INDEX(13, 2);
case SIDE_BACK:
if(this->block->metadata == 3)
return TEXTURE_INDEX(12, 2);
else
return TEXTURE_INDEX(13, 2);
case SIDE_RIGHT:
if(this->block->metadata == 5)
return TEXTURE_INDEX(12, 2);
else
return TEXTURE_INDEX(13, 2);
case SIDE_LEFT:
if(this->block->metadata == 4)
return TEXTURE_INDEX(12, 2);
else
return TEXTURE_INDEX(13, 2);
default: return TEXTURE_INDEX(13, 4);
}
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return 0xFFFFFF;
}
struct block block_furnaceoff = {
.name = "Furnace",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_full,
.luminance = 0,
.double_sided = false,
.can_see_through = false,
.ignore_lighting = false,
};
struct block block_furnaceon = {
.name = "Furnace",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_full,
.luminance = 13,
.double_sided = false,
.can_see_through = false,
.ignore_lighting = false,
};

View file

@ -0,0 +1,45 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_GLASS;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
aabb_setsize(x, 1.0F, 1.0F, 1.0F);
return true;
}
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
return (it->block->type == this->block->type) ? face_occlusion_full() :
face_occlusion_empty();
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_FULL;
}
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
return TEXTURE_INDEX(1, 3);
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return 0xFFFFFF;
}
struct block block_glass = {
.name = "Glass",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_full,
.luminance = 0,
.double_sided = false,
.can_see_through = true,
.ignore_lighting = false,
};

View file

@ -0,0 +1,44 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_GLASS;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
aabb_setsize(x, 1.0F, 1.0F, 1.0F);
return true;
}
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
return face_occlusion_full();
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_FULL;
}
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
return TEXTURE_INDEX(9, 6);
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return 0xFFFFFF;
}
struct block block_glowstone = {
.name = "Glowstone",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_full,
.luminance = 15,
.double_sided = false,
.can_see_through = false,
.ignore_lighting = false,
};

57
source/block/block_grass.c Executable file
View file

@ -0,0 +1,57 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_ORGANIC;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
aabb_setsize(x, 1.0F, 1.0F, 1.0F);
return true;
}
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
return face_occlusion_full();
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_FULL;
}
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
switch(side) {
case SIDE_TOP: return TEXTURE_INDEX(5, 9);
case SIDE_BOTTOM: return TEXTURE_INDEX(2, 0);
default:
if(world_get_block(this->world, this->x, this->y + 1, this->z).type
== BLOCK_SNOW) {
return TEXTURE_INDEX(4, 4);
} else {
return TEXTURE_INDEX(5, 10);
}
}
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
switch(side) {
case SIDE_TOP: return 0x619961;
default: return 0xFFFFFF;
}
}
struct block block_grass = {
.name = "Grass",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_full,
.luminance = 0,
.double_sided = false,
.can_see_through = false,
.ignore_lighting = false,
};

View file

@ -0,0 +1,44 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_ORGANIC;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
aabb_setsize(x, 1.0F, 1.0F, 1.0F);
return true;
}
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
return face_occlusion_full();
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_FULL;
}
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
return TEXTURE_INDEX(3, 1);
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return 0xFFFFFF;
}
struct block block_gravel = {
.name = "Gravel",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_full,
.luminance = 0,
.double_sided = false,
.can_see_through = false,
.ignore_lighting = false,
};

45
source/block/block_ice.c Normal file
View file

@ -0,0 +1,45 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_STONE;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
aabb_setsize(x, 1.0F, 1.0F, 1.0F);
return true;
}
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
return (it->block->type == this->block->type) ? face_occlusion_full() :
face_occlusion_empty();
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_FULL;
}
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
return TEXTURE_INDEX(3, 4);
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return 0xFFFFFF;
}
struct block block_ice = {
.name = "Ice",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = true,
.getBaseColor = getBaseColor,
.renderBlock = render_block_full,
.luminance = 0,
.double_sided = false,
.can_see_through = true,
.ignore_lighting = false,
};

View file

@ -0,0 +1,61 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_STONE;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
switch(this->block->metadata) {
case 2:
aabb_setsize(x, 1.0F, 1.0F, 0.125F);
aabb_translate(x, 0, 0, 0.4375F);
return true;
case 3:
aabb_setsize(x, 1.0F, 1.0F, 0.125F);
aabb_translate(x, 0, 0, -0.4375F);
return true;
case 4:
aabb_setsize(x, 0.125F, 1.0F, 1.0F);
aabb_translate(x, 0.4375F, 0, 0);
return true;
case 5:
aabb_setsize(x, 0.125F, 1.0F, 1.0F);
aabb_translate(x, -0.4375F, 0, 0);
return true;
default: return false;
}
}
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
return face_occlusion_empty();
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_LADDER;
}
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
return TEXTURE_INDEX(3, 5);
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return 0xFFFFFF;
}
struct block block_ladder = {
.name = "Ladder",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_ladder,
.luminance = 0,
.double_sided = false,
.can_see_through = true,
.ignore_lighting = false,
};

62
source/block/block_lava.c Normal file
View file

@ -0,0 +1,62 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_STONE;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
int block_height = (this->block->metadata & 0x8) ?
16 :
(8 - this->block->metadata) * 2 * 7 / 8;
aabb_setsize(x, 1.0F, (float)block_height / 16.0F, 1.0F);
return false;
}
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
int block_height = (this->block->metadata & 0x8) ?
16 :
(8 - this->block->metadata) * 2 * 7 / 8;
switch(side) {
case SIDE_TOP:
return (it->block->type == this->block->type) ?
face_occlusion_full() :
face_occlusion_empty();
case SIDE_BOTTOM: return face_occlusion_full();
default:
return (world_get_block(this->world, this->x, this->y + 1, this->z)
.type
== this->block->type) ?
face_occlusion_full() :
face_occlusion_rect(block_height);
}
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_FLUID;
}
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
return TEXTURE_INDEX(2, 0);
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return 0xFFFFFF;
}
struct block block_lava = {
.name = "Lava",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = true,
.getBaseColor = getBaseColor,
.renderBlock = render_block_fluid,
.luminance = 15,
.double_sided = false,
.can_see_through = true,
.ignore_lighting = false,
};

View file

@ -0,0 +1,62 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_ORGANIC;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
aabb_setsize(x, 1.0F, 1.0F, 1.0F);
return true;
}
struct face_occlusion sides_mask = {
.mask = {0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA,
0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA},
};
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
return (it->block->type == this->block->type) ?
((side == SIDE_RIGHT || side == SIDE_BACK || side == SIDE_BOTTOM) ?
face_occlusion_full() :
&sides_mask) :
&sides_mask;
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_FULL;
}
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
switch(this->block->metadata & 0x3) {
case 1: return TEXTURE_INDEX(4, 8);
case 2: return TEXTURE_INDEX(4, 3);
default: return TEXTURE_INDEX(5, 11);
}
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
switch(this->block->metadata & 0x3) {
case 0: return 0x619961;
case 1: return 0x48B518;
case 2: return 0x80A755;
default: return 0xFFFFFF;
}
}
struct block block_leaves = {
.name = "Leaves",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_full,
.luminance = 0,
.double_sided = true,
.can_see_through = true,
.ignore_lighting = false,
};

67
source/block/block_log.c Normal file
View file

@ -0,0 +1,67 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_WOOD;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
aabb_setsize(x, 1.0F, 1.0F, 1.0F);
return true;
}
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
return face_occlusion_full();
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_FULL;
}
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
switch(this->block->metadata) {
default:
case 0:
switch(side) {
case SIDE_TOP:
case SIDE_BOTTOM: return TEXTURE_INDEX(5, 1);
default: return TEXTURE_INDEX(4, 1);
}
break;
case 1:
switch(side) {
case SIDE_TOP:
case SIDE_BOTTOM: return TEXTURE_INDEX(5, 1);
default: return TEXTURE_INDEX(4, 7);
}
break;
case 2:
switch(side) {
case SIDE_TOP:
case SIDE_BOTTOM: return TEXTURE_INDEX(5, 1);
default: return TEXTURE_INDEX(5, 7);
}
break;
}
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return 0xFFFFFF;
}
struct block block_log = {
.name = "Log",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_full,
.luminance = 0,
.double_sided = false,
.can_see_through = false,
.ignore_lighting = false,
};

View file

@ -0,0 +1,44 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_STONE;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
aabb_setsize(x, 1.0F, 1.0F, 1.0F);
return true;
}
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
return face_occlusion_full();
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_FULL;
}
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
return TEXTURE_INDEX(5, 2);
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return 0xFFFFFF;
}
struct block block_obsidian = {
.name = "Obsidian",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_full,
.luminance = 0,
.double_sided = false,
.can_see_through = false,
.ignore_lighting = false,
};

138
source/block/block_ore.c Normal file
View file

@ -0,0 +1,138 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_STONE;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
aabb_setsize(x, 1.0F, 1.0F, 1.0F);
return true;
}
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
return face_occlusion_full();
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_FULL;
}
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
switch(this->block->type) {
case 14: // gold
return TEXTURE_INDEX(0, 2);
case 15: // iron
return TEXTURE_INDEX(1, 2);
case 16: // coal
return TEXTURE_INDEX(2, 2);
case 21: // lapis
return TEXTURE_INDEX(0, 10);
case 56: // diamond
return TEXTURE_INDEX(2, 3);
case 73: // redstone
case 74: return TEXTURE_INDEX(3, 3);
default: return TEXTURE_INDEX(1, 0);
}
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return 0xFFFFFF;
}
struct block block_coalore = {
.name = "Coal ore",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_full,
.luminance = 0,
.double_sided = false,
.can_see_through = false,
.ignore_lighting = false,
};
struct block block_ironore = {
.name = "Iron ore",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_full,
.luminance = 0,
.double_sided = false,
.can_see_through = false,
.ignore_lighting = false,
};
struct block block_goldore = {
.name = "Gold ore",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_full,
.luminance = 0,
.double_sided = false,
.can_see_through = false,
.ignore_lighting = false,
};
struct block block_diamondore = {
.name = "Diamond ore",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_full,
.luminance = 0,
.double_sided = false,
.can_see_through = false,
.ignore_lighting = false,
};
struct block block_redstoneore = {
.name = "Redstone ore",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_full,
.luminance = 0,
.double_sided = false,
.can_see_through = false,
.ignore_lighting = false,
};
struct block block_lapisore = {
.name = "Lapis lazuli ore",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_full,
.luminance = 0,
.double_sided = false,
.can_see_through = false,
.ignore_lighting = false,
};

View file

@ -0,0 +1,44 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_WOOD;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
aabb_setsize(x, 1.0F, 1.0F, 1.0F);
return true;
}
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
return face_occlusion_full();
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_FULL;
}
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
return TEXTURE_INDEX(4, 0);
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return 0xFFFFFF;
}
struct block block_planks = {
.name = "Planks",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_full,
.luminance = 0,
.double_sided = false,
.can_see_through = false,
.ignore_lighting = false,
};

View file

@ -0,0 +1,43 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_STONE;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
return false;
}
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
return face_occlusion_empty();
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_FULL;
}
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
return TEXTURE_INDEX(0, 0);
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return 0xFFFFFF;
}
struct block block_portal = {
.name = "Portal",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = true,
.getBaseColor = getBaseColor,
.renderBlock = render_block_portal,
.luminance = 11,
.double_sided = false,
.can_see_through = true,
.ignore_lighting = false,
};

View file

@ -0,0 +1,82 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_WOOD;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
aabb_setsize(x, 1.0F, 1.0F, 1.0F);
return true;
}
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
return face_occlusion_full();
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_FULL;
}
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
switch(side) {
case SIDE_FRONT:
if(this->block->metadata == 2)
return TEXTURE_INDEX(7, 7);
else
return TEXTURE_INDEX(6, 7);
case SIDE_BACK:
if(this->block->metadata == 0)
return TEXTURE_INDEX(7, 7);
else
return TEXTURE_INDEX(6, 7);
case SIDE_RIGHT:
if(this->block->metadata == 3)
return TEXTURE_INDEX(7, 7);
else
return TEXTURE_INDEX(6, 7);
case SIDE_LEFT:
if(this->block->metadata == 1)
return TEXTURE_INDEX(7, 7);
else
return TEXTURE_INDEX(6, 7);
default: return TEXTURE_INDEX(6, 6);
}
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return 0xFFFFFF;
}
struct block block_pumpkin = {
.name = "Pumpkin",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_full,
.luminance = 0,
.double_sided = false,
.can_see_through = false,
.ignore_lighting = false,
};
struct block block_pumpkin_lit = {
.name = "Jack o'Lantern",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_full,
.luminance = 15,
.double_sided = false,
.can_see_through = false,
.ignore_lighting = false,
};

94
source/block/block_rail.c Normal file
View file

@ -0,0 +1,94 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_STONE;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
aabb_setsize(x, 1.0F,
((this->block->metadata & 0x7) > 1
&& (this->block->metadata & 0x7) < 6) ?
0.625F :
0.125F,
1.0F);
return !entity;
}
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
return face_occlusion_empty();
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_FLAT;
}
static uint8_t getTextureIndex1(struct block_info* this, enum side side) {
return (this->block->metadata < 6) ? TEXTURE_INDEX(0, 8) :
TEXTURE_INDEX(0, 7);
}
static uint8_t getTextureIndex2(struct block_info* this, enum side side) {
return (this->block->metadata & 0x8) ? TEXTURE_INDEX(3, 11) :
TEXTURE_INDEX(3, 10);
}
static uint8_t getTextureIndex3(struct block_info* this, enum side side) {
return TEXTURE_INDEX(3, 12);
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return 0xFFFFFF;
}
struct block block_rail = {
.name = "Rail",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex1,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_rail,
.luminance = 0,
.double_sided = true,
.can_see_through = true,
.render_block_data.rail_curved_possible = true,
.ignore_lighting = false,
};
struct block block_powered_rail = {
.name = "Powered rail",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex2,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_rail,
.luminance = 0,
.double_sided = true,
.can_see_through = true,
.render_block_data.rail_curved_possible = false,
.ignore_lighting = false,
};
struct block block_detector_rail = {
.name = "Detector rail",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex3,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_rail,
.luminance = 0,
.double_sided = true,
.can_see_through = true,
.render_block_data.rail_curved_possible = false,
.ignore_lighting = false,
};

View file

@ -0,0 +1,45 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_ORGANIC;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
aabb_setsize(x, 0.375F, 0.375F, 0.375F);
return !entity;
}
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
return face_occlusion_empty();
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_CROSS;
}
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
return TEXTURE_INDEX(12, 1);
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return 0xFFFFFF;
}
struct block block_red_mushroom = {
.name = "Red mushroom",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_cross,
.luminance = 0,
.double_sided = true,
.can_see_through = true,
.render_block_data.cross_random_displacement = false,
.ignore_lighting = false,
};

45
source/block/block_reed.c Normal file
View file

@ -0,0 +1,45 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_ORGANIC;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
aabb_setsize(x, 0.75F, 1.0F, 0.75F);
return !entity;
}
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
return face_occlusion_empty();
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_CROSS;
}
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
return TEXTURE_INDEX(9, 4);
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return 0xFFFFFF;
}
struct block block_reed = {
.name = "Reed",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_cross,
.luminance = 0,
.double_sided = true,
.can_see_through = true,
.render_block_data.cross_random_displacement = false,
.ignore_lighting = false,
};

45
source/block/block_rose.c Normal file
View file

@ -0,0 +1,45 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_ORGANIC;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
aabb_setsize(x, 0.375F, 0.625F, 0.375F);
return !entity;
}
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
return face_occlusion_empty();
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_CROSS;
}
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
return TEXTURE_INDEX(12, 0);
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return 0xFFFFFF;
}
struct block block_rose = {
.name = "Rose",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_cross,
.luminance = 0,
.double_sided = true,
.can_see_through = true,
.render_block_data.cross_random_displacement = false,
.ignore_lighting = false,
};

44
source/block/block_sand.c Normal file
View file

@ -0,0 +1,44 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_SAND;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
aabb_setsize(x, 1.0F, 1.0F, 1.0F);
return true;
}
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
return face_occlusion_full();
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_FULL;
}
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
return TEXTURE_INDEX(2, 1);
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return 0xFFFFFF;
}
struct block block_sand = {
.name = "Sand",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_full,
.luminance = 0,
.double_sided = false,
.can_see_through = false,
.ignore_lighting = false,
};

View file

@ -0,0 +1,48 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_STONE;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
aabb_setsize(x, 1.0F, 1.0F, 1.0F);
return true;
}
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
return face_occlusion_full();
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_FULL;
}
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
switch(side) {
case SIDE_TOP: return TEXTURE_INDEX(0, 11);
case SIDE_BOTTOM: return TEXTURE_INDEX(0, 13);
default: return TEXTURE_INDEX(0, 12);
}
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return 0xFFFFFF;
}
struct block block_sandstone = {
.name = "Sandstone",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_full,
.luminance = 0,
.double_sided = false,
.can_see_through = false,
.ignore_lighting = false,
};

View file

@ -0,0 +1,49 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_ORGANIC;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
aabb_setsize(x, 0.8125F, 0.8125F, 0.8125F);
return !entity;
}
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
return face_occlusion_empty();
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_CROSS;
}
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
switch(this->block->metadata) {
case 1: return TEXTURE_INDEX(7, 2);
case 2: return TEXTURE_INDEX(8, 2);
default: return TEXTURE_INDEX(6, 2);
}
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return 0xFFFFFF;
}
struct block block_sapling = {
.name = "Sapling",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_cross,
.luminance = 0,
.double_sided = true,
.can_see_through = true,
.render_block_data.cross_random_displacement = false,
.ignore_lighting = false,
};

61
source/block/block_slab.c Normal file
View file

@ -0,0 +1,61 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_STONE;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
aabb_setsize(x, 1.0F, 0.5F, 1.0F);
return true;
}
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
switch(side) {
case SIDE_TOP: return face_occlusion_empty();
case SIDE_BOTTOM: return face_occlusion_full();
default: return face_occlusion_rect(8);
}
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_HALF;
}
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
switch(this->block->metadata) {
default:
case 0:
return (side == SIDE_TOP || side == SIDE_BOTTOM) ?
TEXTURE_INDEX(6, 0) :
TEXTURE_INDEX(5, 0);
case 1:
return (side == SIDE_TOP) ?
TEXTURE_INDEX(0, 11) :
((side == SIDE_BOTTOM) ? TEXTURE_INDEX(0, 13) :
TEXTURE_INDEX(0, 12));
case 2: return TEXTURE_INDEX(4, 0);
case 3: return TEXTURE_INDEX(0, 1);
}
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return 0xFFFFFF;
}
struct block block_slab = {
.name = "Slab",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_slab,
.luminance = 0,
.double_sided = false,
.can_see_through = true,
.ignore_lighting = true,
};

48
source/block/block_snow.c Normal file
View file

@ -0,0 +1,48 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_WOOL;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
aabb_setsize(x, 1.0F, 0.125F * (this->block->metadata + 1), 1.0F);
return true;
}
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
switch(side) {
case SIDE_TOP: return face_occlusion_empty();
case SIDE_BOTTOM: return face_occlusion_full();
default: return face_occlusion_rect((this->block->metadata + 1) * 2);
}
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_LAYER;
}
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
return TEXTURE_INDEX(2, 4);
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return 0xFFFFFF;
}
struct block block_snow = {
.name = "Snow",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_full,
.luminance = 0,
.double_sided = false,
.can_see_through = true,
.ignore_lighting = false,
};

View file

@ -0,0 +1,44 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_STONE;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
aabb_setsize(x, 1.0F, 1.0F, 1.0F);
return true;
}
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
return face_occlusion_empty();
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_FULL;
}
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
return TEXTURE_INDEX(1, 4);
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return 0xFFFFFF;
}
struct block block_spawner = {
.name = "Monster Spawner",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_full,
.luminance = 0,
.double_sided = false,
.can_see_through = true,
.ignore_lighting = false,
};

View file

@ -0,0 +1,59 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_STONE;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
aabb_setsize(x, 1.0F, 1.0F, 1.0F);
return true;
}
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
return face_occlusion_empty();
}
/*static struct rectangle getSideMask(struct block_info* this, enum side side,
struct block_info* it) { switch(side) { case SIDE_TOP: return
rectangle_from(0,0,16,8); case SIDE_BOTTOM: return rectangle_full(); case
SIDE_LEFT: return rectangle_from(0,8,16,8); case SIDE_RIGHT: return
rectangle_full(); case SIDE_FRONT: case SIDE_BACK:
{
struct rectangle rect;
rect.length = 2;
rectangle_from2(&rect,0,0,8,16,8);
rectangle_from2(&rect,1,8,0,8,8);
return rect;
}
}
}*/
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_STAIRS;
}
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
return TEXTURE_INDEX(4, 0);
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return 0xFFFFFF;
}
struct block block_stairs = {
.name = "Stairs",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_full,
.luminance = 0,
.double_sided = false,
.can_see_through = true,
.ignore_lighting = true,
};

View file

@ -0,0 +1,44 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_STONE;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
aabb_setsize(x, 1.0F, 1.0F, 1.0F);
return true;
}
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
return face_occlusion_full();
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_FULL;
}
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
return TEXTURE_INDEX(1, 0);
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return 0xFFFFFF;
}
struct block block_stone = {
.name = "Stone",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_full,
.luminance = 0,
.double_sided = false,
.can_see_through = false,
.ignore_lighting = false,
};

View file

@ -0,0 +1,70 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_ORGANIC;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
aabb_setsize(x, 0.8125F, 0.8125F, 0.8125F);
return !entity;
}
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
return face_occlusion_empty();
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_CROSS;
}
static uint8_t getTextureIndex1(struct block_info* this, enum side side) {
switch(this->block->metadata) {
case 1: return TEXTURE_INDEX(5, 12); // tallgrass
case 2: return TEXTURE_INDEX(5, 13); // fern
default: return TEXTURE_INDEX(6, 3); // deadbush
}
}
static uint8_t getTextureIndex2(struct block_info* this, enum side side) {
return TEXTURE_INDEX(6, 3); // deadbush
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return (this->block->metadata == 0) ? 0xFFFFFF : 0x619961;
}
struct block block_tallgrass = {
.name = "Tallgrass",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex1,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_cross,
.luminance = 0,
.double_sided = true,
.can_see_through = true,
.render_block_data.cross_random_displacement = true,
.ignore_lighting = false,
};
struct block block_deadbush = {
.name = "Deadbush",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex2,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_cross,
.luminance = 0,
.double_sided = true,
.can_see_through = true,
.render_block_data.cross_random_displacement = false,
.ignore_lighting = false,
};

View file

@ -0,0 +1,93 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_WOOD;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
aabb_setsize(x, 0.3125F, 0.625F, 0.3125F);
switch(this->block->metadata) {
case 1: aabb_translate(x, -0.34375F, 0.1875F, 0); break;
case 2: aabb_translate(x, 0.34375F, 0.1875F, 0); break;
case 3: aabb_translate(x, 0, 0.1875F, -0.34375F); break;
case 4: aabb_translate(x, 0, 0.1875F, 0.34375F); break;
default: aabb_setsize(x, 0.2F, 0.6F, 0.2F); break;
}
return !entity;
}
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
return face_occlusion_empty();
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_CROSS;
}
static uint8_t getTextureIndex1(struct block_info* this, enum side side) {
return TEXTURE_INDEX(0, 5);
}
static uint8_t getTextureIndex2(struct block_info* this, enum side side) {
return TEXTURE_INDEX(3, 7);
}
static uint8_t getTextureIndex3(struct block_info* this, enum side side) {
return TEXTURE_INDEX(3, 6);
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return 0xFFFFFF;
}
struct block block_torch = {
.name = "Torch",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex1,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_torch,
.luminance = 14,
.double_sided = false,
.can_see_through = true,
.ignore_lighting = false,
};
struct block block_redstone_torch = {
.name = "Redstone Torch",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex2,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_torch,
.luminance = 0,
.double_sided = false,
.can_see_through = true,
.ignore_lighting = false,
};
struct block block_redstone_torch_lit = {
.name = "Redstone Torch",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex3,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_torch,
.luminance = 7,
.double_sided = false,
.can_see_through = true,
.ignore_lighting = false,
};

View file

@ -0,0 +1,57 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_STONE;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
int block_height = (this->block->metadata & 0x8) ?
16 :
(8 - this->block->metadata) * 2 * 7 / 8;
aabb_setsize(x, 1.0F, (float)block_height / 16.0F, 1.0F);
return false;
}
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
int block_height = (this->block->metadata & 0x8) ?
16 :
(8 - this->block->metadata) * 2 * 7 / 8;
switch(side) {
case SIDE_TOP:
return (it->block->type == this->block->type) ?
face_occlusion_full() :
face_occlusion_empty();
case SIDE_BOTTOM: return face_occlusion_full();
default: return face_occlusion_rect(block_height);
}
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_FLUID;
}
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
return TEXTURE_INDEX(1, 0);
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return 0xFFFFFF;
}
struct block block_water = {
.name = "Water",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = true,
.getBaseColor = getBaseColor,
.renderBlock = render_block_fluid,
.luminance = 0,
.double_sided = false,
.can_see_through = true,
.ignore_lighting = false,
};

View file

@ -0,0 +1,52 @@
#include "blocks.h"
static enum block_material getMaterial(struct block_info* this) {
return MATERIAL_WOOD;
}
static bool getBoundingBox(struct block_info* this, bool entity,
struct AABB* x) {
aabb_setsize(x, 1.0F, 1.0F, 1.0F);
return true;
}
static struct face_occlusion*
getSideMask(struct block_info* this, enum side side, struct block_info* it) {
return face_occlusion_full();
}
static enum block_render_type getRenderType(struct block_info* this) {
return RENDERTYPE_FULL;
}
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
switch(side) {
case SIDE_FRONT:
case SIDE_LEFT: return TEXTURE_INDEX(12, 3);
case SIDE_RIGHT:
case SIDE_BACK: return TEXTURE_INDEX(11, 3);
case SIDE_TOP: return TEXTURE_INDEX(11, 2);
default:
case SIDE_BOTTOM: return TEXTURE_INDEX(4, 0);
}
}
static uint32_t getBaseColor(struct block_info* this, enum side side) {
return 0xFFFFFF;
}
struct block block_workbench = {
.name = "Workbench",
.getRenderType = getRenderType,
.getSideMask = getSideMask,
.getBoundingBox = getBoundingBox,
.getMaterial = getMaterial,
.getTextureIndex = getTextureIndex,
.transparent = false,
.getBaseColor = getBaseColor,
.renderBlock = render_block_full,
.luminance = 0,
.double_sided = false,
.can_see_through = false,
.ignore_lighting = false,
};

182
source/block/blocks.c Executable file
View file

@ -0,0 +1,182 @@
#include <assert.h>
#include <stdlib.h>
#include "blocks.h"
struct block* blocks[256];
void blocks_init() {
for(int k = 0; k < 256; k++)
blocks[k] = NULL;
blocks[1] = &block_stone;
blocks[2] = &block_grass;
blocks[3] = &block_dirt;
blocks[4] = &block_cobblestone;
blocks[5] = &block_planks;
blocks[6] = &block_sapling;
blocks[7] = &block_bedrock;
blocks[8] = &block_water;
blocks[9] = &block_water;
blocks[10] = &block_lava;
blocks[11] = &block_lava;
blocks[12] = &block_sand;
blocks[13] = &block_gravel;
blocks[14] = &block_goldore;
blocks[15] = &block_ironore;
blocks[16] = &block_coalore;
blocks[17] = &block_log;
blocks[18] = &block_leaves;
// sponge
blocks[20] = &block_glass;
blocks[21] = &block_lapisore;
blocks[22] = &block_lapis;
// dispenser
blocks[24] = &block_sandstone;
// note block
blocks[26] = &block_bed;
blocks[27] = &block_powered_rail;
blocks[28] = &block_detector_rail;
// sticky piston
// cobweb
blocks[31] = &block_tallgrass;
blocks[32] = &block_deadbush;
// piston
// piston head
// wool
// moving piston head
blocks[37] = &block_flower;
blocks[38] = &block_rose;
blocks[39] = &block_brown_mushroom;
blocks[40] = &block_red_mushroom;
blocks[41] = &block_gold;
blocks[42] = &block_iron;
blocks[43] = &block_double_slab;
blocks[44] = &block_slab;
blocks[45] = &block_bricks;
// tnt
// bookshelf
blocks[48] = &block_mossstone;
blocks[49] = &block_obsidian;
blocks[50] = &block_torch;
// TODO: blocks[51] = &block_fire;
blocks[52] = &block_spawner;
blocks[53] = &block_stairs;
blocks[54] = &block_chest;
// redstone wire
blocks[56] = &block_diamondore;
blocks[57] = &block_diamond;
blocks[58] = &block_workbench;
blocks[59] = &block_crops;
blocks[60] = &block_farmland;
blocks[61] = &block_furnaceoff;
blocks[62] = &block_furnaceon;
// sign standing
// wooden door
blocks[65] = &block_ladder;
blocks[66] = &block_rail;
// cobblestone stairs
// sign wall mounted
// lever
// stone pressure plate
// iron door
// wooden pressure plate
blocks[73] = &block_redstoneore;
blocks[74] = &block_redstoneore;
blocks[75] = &block_redstone_torch;
blocks[76] = &block_redstone_torch_lit;
// button
blocks[78] = &block_snow;
blocks[79] = &block_ice;
// snow block
blocks[81] = &block_cactus;
blocks[82] = &block_clay;
blocks[83] = &block_reed;
// jukebox
// fence
blocks[86] = &block_pumpkin;
// netherrack
// soul sand
blocks[89] = &block_glowstone;
blocks[90] = &block_portal;
blocks[91] = &block_pumpkin_lit;
blocks[92] = &block_cake;
// repeater
// repeater
blocks[95] = &block_locked_chest;
// trap door
for(int k = 0; k < 256; k++) {
if(blocks[k]) {
assert(blocks[k]->getRenderType);
assert(blocks[k]->getMaterial);
assert(blocks[k]->getTextureIndex);
assert(blocks[k]->getSideMask);
assert(blocks[k]->getBoundingBox);
assert(blocks[k]->getBaseColor);
assert(blocks[k]->renderBlock);
}
}
}
enum side blocks_side_opposite(enum side s) {
switch(s) {
default:
case SIDE_TOP: return SIDE_BOTTOM;
case SIDE_BOTTOM: return SIDE_TOP;
case SIDE_LEFT: return SIDE_RIGHT;
case SIDE_RIGHT: return SIDE_LEFT;
case SIDE_FRONT: return SIDE_BACK;
case SIDE_BACK: return SIDE_FRONT;
}
}
const char* block_side_name(enum side s) {
switch(s) {
case SIDE_TOP: return "top";
case SIDE_BOTTOM: return "bottom";
case SIDE_LEFT: return "left";
case SIDE_RIGHT: return "right";
case SIDE_FRONT: return "front";
case SIDE_BACK: return "back";
default: return "invalid";
}
}
void blocks_side_offset(enum side s, int* x, int* y, int* z) {
assert(x && y && z);
switch(s) {
default:
case SIDE_TOP:
*x = 0;
*y = 1;
*z = 0;
break;
case SIDE_BOTTOM:
*x = 0;
*y = -1;
*z = 0;
break;
case SIDE_LEFT:
*x = -1;
*y = 0;
*z = 0;
break;
case SIDE_RIGHT:
*x = 1;
*y = 0;
*z = 0;
break;
case SIDE_BACK:
*x = 0;
*y = 0;
*z = 1;
break;
case SIDE_FRONT:
*x = 0;
*y = 0;
*z = -1;
break;
}
}

169
source/block/blocks.h Executable file
View file

@ -0,0 +1,169 @@
#ifndef BLOCKS_H
#define BLOCKS_H
#include "face_occlusion.h"
#include <stdbool.h>
#include <stdint.h>
#include "../displaylist.h"
#include "../world.h"
#define TEXTURE_INDEX(x, y) (((y)*14) + (x))
#define TEXTURE_X(idx) ((idx) % 14)
#define TEXTURE_Y(idx) ((idx) / 14)
enum block_material {
MATERIAL_WOOD,
MATERIAL_STONE,
MATERIAL_WOOL,
MATERIAL_ORGANIC,
MATERIAL_SAND,
MATERIAL_GLASS,
};
enum side {
SIDE_TOP = 0,
SIDE_BOTTOM = 1,
SIDE_LEFT = 2,
SIDE_RIGHT = 3,
SIDE_FRONT = 4,
SIDE_BACK = 5,
SIDE_MAX
};
enum block_render_type {
RENDERTYPE_FULL,
RENDERTYPE_FULL_OVERLAY,
RENDERTYPE_HALF,
RENDERTYPE_STAIRS,
RENDERTYPE_CROSS,
RENDERTYPE_CAKE,
RENDERTYPE_FLAT,
RENDERTYPE_LADDER,
RENDERTYPE_CACTUS,
RENDERTYPE_DOOR,
RENDERTYPE_TRAPDOOR,
RENDERTYPE_FLUID,
RENDERTYPE_LAYER
};
enum block_type {
BLOCK_AIR = 0,
BLOCK_STONE = 1,
BLOCK_GRASS = 2,
BLOCK_DIRT = 3,
BLOCK_COBBLESTONE = 4,
BLOCK_WATER_FLOW = 8,
BLOCK_WATER_STILL = 9,
BLOCK_LAVA_FLOW = 10,
BLOCK_LAVA_STILL = 11,
BLOCK_SAND = 12,
BLOCK_GRAVEL = 13,
BLOCK_LOG = 17,
BLOCK_LEAVES = 18,
BLOCK_TALL_GRASS = 31,
BLOCK_MOSSY_COBBLE = 48,
BLOCK_OBSIDIAN = 49,
BLOCK_SNOW = 78,
BLOCK_ICE = 79,
BLOCK_PORTAL = 90,
};
#include "aabb.h"
struct block {
char name[32];
enum block_render_type (*getRenderType)(struct block_info*);
enum block_material (*getMaterial)(struct block_info*);
uint8_t (*getTextureIndex)(struct block_info*, enum side);
struct face_occlusion* (*getSideMask)(struct block_info*, enum side,
struct block_info*);
bool (*getBoundingBox)(struct block_info*, bool, struct AABB*);
uint32_t (*getBaseColor)(struct block_info*, enum side);
size_t (*renderBlock)(struct displaylist*, struct block_info*, enum side,
struct block_info*, uint8_t*, bool);
bool transparent;
int luminance;
bool double_sided;
bool can_see_through;
bool ignore_lighting;
union {
bool cross_random_displacement;
bool rail_curved_possible;
} render_block_data;
};
extern struct block block_bedrock;
extern struct block block_slab;
extern struct block block_dirt;
extern struct block block_log;
extern struct block block_stone;
extern struct block block_leaves;
extern struct block block_grass;
extern struct block block_water;
extern struct block block_lava;
extern struct block block_sand;
extern struct block block_sandstone;
extern struct block block_gravel;
extern struct block block_ice;
extern struct block block_snow;
extern struct block block_tallgrass;
extern struct block block_deadbush;
extern struct block block_flower;
extern struct block block_rose;
extern struct block block_furnaceoff;
extern struct block block_furnaceon;
extern struct block block_workbench;
extern struct block block_glass;
extern struct block block_clay;
extern struct block block_coalore;
extern struct block block_ironore;
extern struct block block_goldore;
extern struct block block_diamondore;
extern struct block block_redstoneore;
extern struct block block_lapisore;
extern struct block block_stairs;
extern struct block block_obsidian;
extern struct block block_spawner;
extern struct block block_cobblestone;
extern struct block block_mossstone;
extern struct block block_chest;
extern struct block block_locked_chest;
extern struct block block_cactus;
extern struct block block_pumpkin;
extern struct block block_pumpkin_lit;
extern struct block block_brown_mushroom;
extern struct block block_red_mushroom;
extern struct block block_reed;
extern struct block block_glowstone;
extern struct block block_torch;
extern struct block block_rail;
extern struct block block_powered_rail;
extern struct block block_detector_rail;
extern struct block block_redstone_torch;
extern struct block block_redstone_torch_lit;
extern struct block block_ladder;
extern struct block block_farmland;
extern struct block block_crops;
extern struct block block_planks;
extern struct block block_portal;
extern struct block block_iron;
extern struct block block_gold;
extern struct block block_diamond;
extern struct block block_lapis;
extern struct block block_cake;
extern struct block block_fire;
extern struct block block_double_slab;
extern struct block block_bed;
extern struct block block_sapling;
extern struct block block_bricks;
extern struct block* blocks[256];
#include "../render_block.h"
void blocks_init(void);
enum side blocks_side_opposite(enum side s);
void blocks_side_offset(enum side s, int* x, int* y, int* z);
const char* block_side_name(enum side s);
#endif

View file

@ -0,0 +1,96 @@
#include "face_occlusion.h"
struct face_occlusion face_occlusion_s[] = {
{
.mask = {0, 0, 0, 0, 0, 0, 0, 0},
},
{
.mask = {0, 0, 0, 0, 0, 0, 0, 0xFFFF},
},
{
.mask = {0, 0, 0, 0, 0, 0, 0, 0xFFFFFFFF},
},
{
.mask = {0, 0, 0, 0, 0, 0, 0xFFFF, 0xFFFFFFFF},
},
{
.mask = {0, 0, 0, 0, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF},
},
{
.mask = {0, 0, 0, 0, 0, 0xFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
},
{
.mask = {0, 0, 0, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
},
{
.mask = {0, 0, 0, 0, 0xFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
},
{
.mask = {0, 0, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
},
{
.mask
= {0, 0, 0, 0xFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
},
{
.mask
= {0, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
},
{
.mask = {0, 0, 0xFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF},
},
{
.mask = {0, 0, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF},
},
{
.mask = {0, 0xFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF},
},
{
.mask = {0, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF},
},
{
.mask = {0xFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
},
{
.mask = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
},
};
struct face_occlusion* face_occlusion_full() {
return face_occlusion_rect(16);
}
struct face_occlusion* face_occlusion_empty() {
return face_occlusion_rect(0);
}
struct face_occlusion* face_occlusion_rect(int size) {
return face_occlusion_s + size;
}
bool face_occlusion_test(struct face_occlusion* a, struct face_occlusion* b) {
bool is_empty_a = true;
for(size_t k = 0; k < FACE_OCCLUSION_ARR_LENGTH; k++) {
if(a->mask[k]) {
is_empty_a = false;
break;
}
}
if(is_empty_a)
return true;
for(size_t k = 0; k < FACE_OCCLUSION_ARR_LENGTH; k++) {
if(a->mask[k] != b->mask[k] && (a->mask[k] | b->mask[k]) == a->mask[k])
return true;
}
return false;
}

View file

@ -0,0 +1,23 @@
#ifndef FACE_OCCLUSION_H
#define FACE_OCCLUSION_H
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#define FACE_OCCLUSION_SIZE (16 * 16)
#define FACE_OCCLUSION_ARR_LENGTH \
((FACE_OCCLUSION_SIZE + (sizeof(uint32_t) * 8) - 1) \
/ (sizeof(uint32_t) * 8))
struct face_occlusion {
uint32_t mask[FACE_OCCLUSION_ARR_LENGTH];
};
struct face_occlusion* face_occlusion_full();
struct face_occlusion* face_occlusion_empty();
struct face_occlusion* face_occlusion_rect(int size);
bool face_occlusion_test(struct face_occlusion* a, struct face_occlusion* b);
#endif

574
source/chunk.c Normal file
View file

@ -0,0 +1,574 @@
#include <assert.h>
#include <gccore.h>
#include <malloc.h>
#include <math.h>
#include <stddef.h>
#include <string.h>
#include "block/blocks.h"
#include "chunk.h"
#include "stack.h"
#define CHUNK_INDEX(x, y, z) ((x) + ((z) + (y)*CHUNK_SIZE) * CHUNK_SIZE)
#define CHUNK_LIGHT_INDEX(x, y, z) \
((x) + ((z) + (y) * (CHUNK_SIZE + 2)) * (CHUNK_SIZE + 2))
extern void log_num(int x, int offset, bool flip);
void chunk_init(struct chunk* c, struct world* world, w_coord_t x, w_coord_t y,
w_coord_t z) {
assert(c && world);
c->blocks = malloc(CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE * 3);
assert(c->blocks);
memset(c->blocks, BLOCK_AIR, CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE * 3);
c->x = x;
c->y = y;
c->z = z;
for(int k = 0; k < 13; k++)
c->has_displist[k] = false;
c->rebuild_displist = false;
c->world = world;
}
void chunk_destroy(struct chunk* c) {
assert(c);
free(c->blocks);
for(int k = 0; k < 13; k++) {
if(c->has_displist[k])
displaylist_destroy(c->mesh + k);
}
}
struct block_data chunk_get_block(struct chunk* c, c_coord_t x, c_coord_t y,
c_coord_t z) {
assert(c && x < CHUNK_SIZE && y < CHUNK_SIZE && z < CHUNK_SIZE);
return (struct block_data) {
.type = c->blocks[CHUNK_INDEX(x, y, z) * 3 + 0],
.metadata = c->blocks[CHUNK_INDEX(x, y, z) * 3 + 1],
.sky_light = c->blocks[CHUNK_INDEX(x, y, z) * 3 + 2] & 0xF,
.torch_light = c->blocks[CHUNK_INDEX(x, y, z) * 3 + 2] >> 4,
};
}
static struct block_data chunk_lookup_block(struct chunk* c, w_coord_t x,
w_coord_t y, w_coord_t z) {
assert(c);
struct chunk* other = c;
if(x < c->x || y < c->y || z < c->z || x >= c->x + CHUNK_SIZE
|| y >= c->y + CHUNK_SIZE || z >= c->z + CHUNK_SIZE)
other = world_find_chunk(c->world, x, y, z);
return other ? chunk_get_block(other, x & CHUNK_SIZE_BITS,
y & CHUNK_SIZE_BITS, z & CHUNK_SIZE_BITS) :
(struct block_data) {
.type = (y < WORLD_HEIGHT) ? 1 : 0,
.metadata = 0,
.sky_light = 0,
.torch_light = 0,
};
}
void chunk_set_block(struct chunk* c, c_coord_t x, c_coord_t y, c_coord_t z,
struct block_data blk) {
assert(c && x < CHUNK_SIZE && y < CHUNK_SIZE && z < CHUNK_SIZE);
c->blocks[CHUNK_INDEX(x, y, z) * 3 + 0] = blk.type;
c->blocks[CHUNK_INDEX(x, y, z) * 3 + 1] = blk.metadata;
c->blocks[CHUNK_INDEX(x, y, z) * 3 + 2]
= (blk.torch_light << 4) | blk.sky_light;
c->rebuild_displist = true;
// TODO: diagonal chunks, just sharing edge or single point
if(x == 0) {
struct chunk* other = world_find_chunk(c->world, c->x - 1, c->y, c->z);
if(other)
other->rebuild_displist = true;
}
if(x == CHUNK_SIZE - 1) {
struct chunk* other
= world_find_chunk(c->world, c->x + CHUNK_SIZE, c->y, c->z);
if(other)
other->rebuild_displist = true;
}
if(y == 0) {
struct chunk* other = world_find_chunk(c->world, c->x, c->y - 1, c->z);
if(other)
other->rebuild_displist = true;
}
if(y == CHUNK_SIZE - 1) {
struct chunk* other
= world_find_chunk(c->world, c->x, c->y + CHUNK_SIZE, c->z);
if(other)
other->rebuild_displist = true;
}
if(z == 0) {
struct chunk* other = world_find_chunk(c->world, c->x, c->y, c->z - 1);
if(other)
other->rebuild_displist = true;
}
if(z == CHUNK_SIZE - 1) {
struct chunk* other
= world_find_chunk(c->world, c->x, c->y, c->z + CHUNK_SIZE);
if(other)
other->rebuild_displist = true;
}
}
static int chunk_test_side(enum side* on_sides, c_coord_t x, c_coord_t y,
c_coord_t z) {
assert(on_sides);
int count = 0;
if(x == 0)
on_sides[count++] = SIDE_LEFT;
if(x == CHUNK_SIZE - 1)
on_sides[count++] = SIDE_RIGHT;
if(y == 0)
on_sides[count++] = SIDE_BOTTOM;
if(y == CHUNK_SIZE - 1)
on_sides[count++] = SIDE_TOP;
if(z == 0)
on_sides[count++] = SIDE_FRONT;
if(z == CHUNK_SIZE - 1)
on_sides[count++] = SIDE_BACK;
return count;
}
static void chunk_test2(struct chunk* c, struct stack* queue, bool* visited,
uint8_t* reachable, c_coord_t x, c_coord_t y,
c_coord_t z) {
assert(queue && visited && reachable);
if(visited[CHUNK_INDEX(x, y, z)]
|| (blocks[c->blocks[CHUNK_INDEX(x, y, z) * 3 + 0]]
&& !blocks[c->blocks[CHUNK_INDEX(x, y, z) * 3 + 0]]
->can_see_through))
return;
stack_clear(queue);
stack_push(queue, (uint8_t[]) {x, y, z});
visited[CHUNK_INDEX(x, y, z)] = true;
uint8_t reached_sides = 0;
while(!stack_empty(queue)) {
uint8_t block[3];
stack_pop(queue, block);
enum side on_sides[3];
size_t on_sides_len
= chunk_test_side(on_sides, block[0], block[1], block[2]);
assert(on_sides_len <= 3);
for(size_t k = 0; k < on_sides_len; k++)
reached_sides |= (1 << on_sides[k]);
for(int s = 0; s < 6; s++) {
int nx, ny, nz;
blocks_side_offset(s, &nx, &ny, &nz);
nx += block[0];
ny += block[1];
nz += block[2];
if(nx >= 0 && ny >= 0 && nz >= 0 && nx < CHUNK_SIZE
&& ny < CHUNK_SIZE && nz < CHUNK_SIZE
&& !visited[CHUNK_INDEX(nx, ny, nz)]
&& (!blocks[c->blocks[CHUNK_INDEX(nx, ny, nz) * 3 + 0]]
|| blocks[c->blocks[CHUNK_INDEX(nx, ny, nz) * 3 + 0]]
->can_see_through)) {
stack_push(queue, (uint8_t[]) {nx, ny, nz});
visited[CHUNK_INDEX(nx, ny, nz)] = true;
}
}
}
for(int s = 0; s < 6; s++) {
if(reached_sides & (1 << s))
reachable[s] |= reached_sides;
}
}
void chunk_test(struct chunk* c) {
assert(c);
memset(c->reachable, 0, sizeof(c->reachable));
bool* visited = malloc(CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE);
assert(visited);
memset(visited, false, CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE);
struct stack queue;
stack_create(&queue, CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE / 4,
sizeof(uint8_t[3]));
for(int y = 0; y < CHUNK_SIZE; y++) {
for(int x = 0; x < CHUNK_SIZE; x++) {
chunk_test2(c, &queue, visited, c->reachable, x, y, 0);
chunk_test2(c, &queue, visited, c->reachable, x, 0, y);
chunk_test2(c, &queue, visited, c->reachable, 0, x, y);
chunk_test2(c, &queue, visited, c->reachable, x, y, CHUNK_SIZE - 1);
chunk_test2(c, &queue, visited, c->reachable, x, CHUNK_SIZE - 1, y);
chunk_test2(c, &queue, visited, c->reachable, CHUNK_SIZE - 1, x, y);
}
}
stack_destroy(&queue);
free(visited);
}
static void chunk_vertex_light(struct chunk* c, uint8_t* light_data) {
assert(c && light_data);
for(c_coord_t y = 0; y < CHUNK_SIZE + 2; y++) {
for(c_coord_t z = 0; z < CHUNK_SIZE + 2; z++) {
for(c_coord_t x = 0; x < CHUNK_SIZE + 2; x++) {
struct block_data b1[4] = {
chunk_lookup_block(c, c->x + x + 0, c->y + y - 1,
c->z + z + 0),
chunk_lookup_block(c, c->x + x - 1, c->y + y - 1,
c->z + z + 0),
chunk_lookup_block(c, c->x + x + 0, c->y + y - 1,
c->z + z - 1),
chunk_lookup_block(c, c->x + x - 1, c->y + y - 1,
c->z + z - 1),
};
struct block_data b2[4] = {
chunk_lookup_block(c, c->x + x - 1, c->y + y + 0,
c->z + z + 0),
chunk_lookup_block(c, c->x + x - 1, c->y + y - 1,
c->z + z + 0),
chunk_lookup_block(c, c->x + x - 1, c->y + y + 0,
c->z + z - 1),
chunk_lookup_block(c, c->x + x - 1, c->y + y - 1,
c->z + z - 1),
};
struct block_data b3[4] = {
chunk_lookup_block(c, c->x + x + 0, c->y + y + 0,
c->z + z - 1),
chunk_lookup_block(c, c->x + x - 1, c->y + y + 0,
c->z + z - 1),
chunk_lookup_block(c, c->x + x + 0, c->y + y - 1,
c->z + z - 1),
chunk_lookup_block(c, c->x + x - 1, c->y + y - 1,
c->z + z - 1),
};
int shade_table[5] = {0, 1, 3, 5, 0};
int sum_sky, sum_torch, count;
sum_sky = sum_torch = count = 0;
for(int k = 0; k < 4; k++) {
if(!blocks[b1[k].type]
|| (blocks[b1[k].type]->can_see_through
&& !blocks[b1[k].type]->ignore_lighting)) {
sum_sky += b1[k].sky_light;
sum_torch += b1[k].torch_light;
count++;
}
}
sum_torch = count > 0 ? (sum_torch + count - 1) / count : 0;
sum_sky = count > 0 ? (sum_sky + count - 1) / count : 0;
sum_torch = MAX(sum_torch - shade_table[4 - count], 0);
sum_sky = MAX(sum_sky - shade_table[4 - count], 0);
light_data[CHUNK_LIGHT_INDEX(x, y, z) * 3 + 0]
= (sum_torch << 4) | sum_sky;
sum_sky = sum_torch = count = 0;
for(int k = 0; k < 4; k++) {
if(!blocks[b2[k].type]
|| (blocks[b2[k].type]->can_see_through
&& !blocks[b2[k].type]->ignore_lighting)) {
sum_sky += b2[k].sky_light;
sum_torch += b2[k].torch_light;
count++;
}
}
sum_torch = count > 0 ? (sum_torch + count - 1) / count : 0;
sum_sky = count > 0 ? (sum_sky + count - 1) / count : 0;
sum_torch = MAX(sum_torch - shade_table[4 - count], 0);
sum_sky = MAX(sum_sky - shade_table[4 - count], 0);
light_data[CHUNK_LIGHT_INDEX(x, y, z) * 3 + 1]
= (sum_torch << 4) | sum_sky;
sum_sky = sum_torch = count = 0;
for(int k = 0; k < 4; k++) {
if(!blocks[b3[k].type]
|| (blocks[b3[k].type]->can_see_through
&& !blocks[b3[k].type]->ignore_lighting)) {
sum_sky += b3[k].sky_light;
sum_torch += b3[k].torch_light;
count++;
}
}
sum_torch = count > 0 ? (sum_torch + count - 1) / count : 0;
sum_sky = count > 0 ? (sum_sky + count - 1) / count : 0;
sum_torch = MAX(sum_torch - shade_table[4 - count], 0);
sum_sky = MAX(sum_sky - shade_table[4 - count], 0);
light_data[CHUNK_LIGHT_INDEX(x, y, z) * 3 + 2]
= (sum_torch << 4) | sum_sky;
}
}
}
}
static size_t chunk_rebuild(struct chunk* c, struct displaylist* d,
uint8_t* light_data, bool count_only,
bool transparent, enum side side_only,
bool double_sided_only) {
assert(c && d && light_data);
size_t visible_faces = 0;
for(c_coord_t y = 0; y < CHUNK_SIZE; y++) {
for(c_coord_t z = 0; z < CHUNK_SIZE; z++) {
for(c_coord_t x = 0; x < CHUNK_SIZE; x++) {
struct block_data local = chunk_get_block(c, x, y, z);
if(blocks[local.type]
&& transparent == blocks[local.type]->transparent
&& double_sided_only == blocks[local.type]->double_sided) {
struct block_info local_info = (struct block_info) {
.block = &local,
.world = c->world,
.x = c->x + x,
.y = c->y + y,
.z = c->z + z,
};
uint8_t vertex_light[24] = {
light_data[CHUNK_LIGHT_INDEX(x + 0, y + 0, z + 0) * 3
+ 0],
light_data[CHUNK_LIGHT_INDEX(x + 1, y + 0, z + 0) * 3
+ 0],
light_data[CHUNK_LIGHT_INDEX(x + 1, y + 0, z + 1) * 3
+ 0],
light_data[CHUNK_LIGHT_INDEX(x + 0, y + 0, z + 1) * 3
+ 0],
light_data[CHUNK_LIGHT_INDEX(x + 0, y + 2, z + 0) * 3
+ 0],
light_data[CHUNK_LIGHT_INDEX(x + 1, y + 2, z + 0) * 3
+ 0],
light_data[CHUNK_LIGHT_INDEX(x + 1, y + 2, z + 1) * 3
+ 0],
light_data[CHUNK_LIGHT_INDEX(x + 0, y + 2, z + 1) * 3
+ 0],
light_data[CHUNK_LIGHT_INDEX(x + 0, y + 0, z + 0) * 3
+ 1],
light_data[CHUNK_LIGHT_INDEX(x + 0, y + 1, z + 0) * 3
+ 1],
light_data[CHUNK_LIGHT_INDEX(x + 0, y + 1, z + 1) * 3
+ 1],
light_data[CHUNK_LIGHT_INDEX(x + 0, y + 0, z + 1) * 3
+ 1],
light_data[CHUNK_LIGHT_INDEX(x + 2, y + 0, z + 0) * 3
+ 1],
light_data[CHUNK_LIGHT_INDEX(x + 2, y + 1, z + 0) * 3
+ 1],
light_data[CHUNK_LIGHT_INDEX(x + 2, y + 1, z + 1) * 3
+ 1],
light_data[CHUNK_LIGHT_INDEX(x + 2, y + 0, z + 1) * 3
+ 1],
light_data[CHUNK_LIGHT_INDEX(x + 0, y + 0, z + 0) * 3
+ 2],
light_data[CHUNK_LIGHT_INDEX(x + 1, y + 0, z + 0) * 3
+ 2],
light_data[CHUNK_LIGHT_INDEX(x + 1, y + 1, z + 0) * 3
+ 2],
light_data[CHUNK_LIGHT_INDEX(x + 0, y + 1, z + 0) * 3
+ 2],
light_data[CHUNK_LIGHT_INDEX(x + 0, y + 0, z + 2) * 3
+ 2],
light_data[CHUNK_LIGHT_INDEX(x + 1, y + 0, z + 2) * 3
+ 2],
light_data[CHUNK_LIGHT_INDEX(x + 1, y + 1, z + 2) * 3
+ 2],
light_data[CHUNK_LIGHT_INDEX(x + 0, y + 1, z + 2) * 3
+ 2],
};
for(int k = 0; k < ((side_only == SIDE_MAX) ? 6 : 1); k++) {
enum side s = (side_only == SIDE_MAX) ? (enum side)k :
side_only;
int ox, oy, oz;
blocks_side_offset(s, &ox, &oy, &oz);
struct block_data neighbours = chunk_lookup_block(
c, c->x + x + ox, c->y + y + oy, c->z + z + oz);
struct block_info neighbours_info
= (struct block_info) {
.block = &neighbours,
.world = c->world,
.x = c->x + x + ox,
.y = c->y + y + oy,
.z = c->z + z + oz,
};
bool face_visible = true;
if(blocks[neighbours.type]
&& ((!transparent
&& !blocks[neighbours.type]->transparent)
|| transparent)) {
struct face_occlusion* a
= blocks[local.type]->getSideMask(
&local_info, s, &neighbours_info);
struct face_occlusion* b
= blocks[neighbours.type]->getSideMask(
&neighbours_info, blocks_side_opposite(s),
&local_info);
face_visible = face_occlusion_test(a, b);
}
if(face_visible)
visible_faces += blocks[local.type]->renderBlock(
d, &local_info, s, &neighbours_info,
vertex_light, count_only);
}
}
}
}
}
return visible_faces;
}
void chunk_check_built(struct chunk* c) {
assert(c);
if(c->rebuild_displist) {
uint8_t* light_data = malloc((CHUNK_SIZE + 2) * (CHUNK_SIZE + 2)
* (CHUNK_SIZE + 2) * 3);
assert(light_data);
chunk_vertex_light(c, light_data);
for(int k = 0; k < 13; k++) {
if(c->has_displist[k])
displaylist_destroy(c->mesh + k);
size_t vertices
= chunk_rebuild(c, c->mesh + k, light_data, true,
k >= 6 && k != 12,
(k == 12) ? SIDE_MAX : (k % 6), k == 12)
* 4;
if(vertices > 0 && vertices <= 0xFFFF * 4) {
displaylist_init(c->mesh + k, vertices, 3 * 2 + 2 * 1 + 1);
displaylist_begin(c->mesh + k);
GX_Begin(GX_QUADS, GX_VTXFMT0, vertices);
chunk_rebuild(c, c->mesh + k, light_data, false,
k >= 6 && k != 12, (k == 12) ? SIDE_MAX : (k % 6),
k == 12);
GX_End();
displaylist_end(c->mesh + k);
c->has_displist[k] = true;
} else {
c->has_displist[k] = false;
}
}
free(light_data);
chunk_test(c);
c->rebuild_displist = false;
}
}
void chunk_pre_render(struct chunk* c, Mtx view) {
assert(c && view);
Mtx model;
guMtxTrans(model, c->x, c->y, c->z);
guMtxConcat(view, model, c->model_view);
}
static void check_matrix_set(struct chunk* c, bool* needs_matrix) {
if(*needs_matrix) {
GX_LoadPosMtxImm(c->model_view, GX_PNMTX0);
*needs_matrix = false;
}
}
void chunk_render(struct chunk* c, bool pass, float x, float y, float z) {
assert(c);
chunk_check_built(c);
bool needs_matrix = true;
int offset = pass ? 6 : 0;
if(y < c->y + CHUNK_SIZE && c->has_displist[SIDE_BOTTOM + offset]) {
check_matrix_set(c, &needs_matrix);
displaylist_render(c->mesh + SIDE_BOTTOM + offset);
}
if(y > c->y && c->has_displist[SIDE_TOP + offset]) {
check_matrix_set(c, &needs_matrix);
displaylist_render(c->mesh + SIDE_TOP + offset);
}
if(x < c->x + CHUNK_SIZE && c->has_displist[SIDE_LEFT + offset]) {
check_matrix_set(c, &needs_matrix);
displaylist_render(c->mesh + SIDE_LEFT + offset);
}
if(x > c->x && c->has_displist[SIDE_RIGHT + offset]) {
check_matrix_set(c, &needs_matrix);
displaylist_render(c->mesh + SIDE_RIGHT + offset);
}
if(z < c->z + CHUNK_SIZE && c->has_displist[SIDE_FRONT + offset]) {
check_matrix_set(c, &needs_matrix);
displaylist_render(c->mesh + SIDE_FRONT + offset);
}
if(z > c->z && c->has_displist[SIDE_BACK + offset]) {
check_matrix_set(c, &needs_matrix);
displaylist_render(c->mesh + SIDE_BACK + offset);
}
if(!pass && c->has_displist[12]) {
check_matrix_set(c, &needs_matrix);
GX_SetCullMode(GX_CULL_NONE);
displaylist_render(c->mesh + 12);
GX_SetCullMode(GX_CULL_BACK);
}
}

52
source/chunk.h Normal file
View file

@ -0,0 +1,52 @@
#ifndef CHUNK_H
#define CHUNK_H
#include <gccore.h>
#include <m-lib/m-i-list.h>
#include <stdbool.h>
#include <stdint.h>
#include "block/blocks.h"
#include "displaylist.h"
#include "intrusive_list.h"
#include "world.h"
#define CHUNK_SIZE_BITS 0xF
#define CHUNK_SIZE 16
#define W2C_COORD(x) ((x)&CHUNK_SIZE_BITS)
typedef uint32_t c_coord_t;
struct chunk {
Mtx model_view;
w_coord_t x, y, z;
uint8_t* blocks;
bool has_faces;
struct displaylist mesh[13];
bool has_displist[13];
bool rebuild_displist;
struct world* world;
uint8_t reachable[6];
struct chunk_step {
bool visited;
enum side from;
uint8_t used_exit_sides;
int steps;
} tmp_data;
ILIST_INTERFACE(ilist_chunks, struct chunk);
};
void chunk_init(struct chunk* c, struct world* world, w_coord_t x, w_coord_t y,
w_coord_t z);
void chunk_destroy(struct chunk* c);
struct block_data chunk_get_block(struct chunk* c, c_coord_t x, c_coord_t y,
c_coord_t z);
void chunk_set_block(struct chunk* c, c_coord_t x, c_coord_t y, c_coord_t z,
struct block_data blk);
void chunk_check_built(struct chunk* c);
void chunk_render(struct chunk* c, bool pass, float x, float y, float z);
void chunk_pre_render(struct chunk* c, Mtx view);
void chunk_test(struct chunk* c);
#endif

44
source/displaylist.c Normal file
View file

@ -0,0 +1,44 @@
#include <assert.h>
#include <gccore.h>
#include <malloc.h>
#include "displaylist.h"
#define DISPLAYLIST_CLL 32
#define DISPLAYLIST_CACHE_LINES(v, s) \
(((v) * (s) + 3 + DISPLAYLIST_CLL - 1) / DISPLAYLIST_CLL * DISPLAYLIST_CLL)
void displaylist_init(struct displaylist* l, size_t vertices,
size_t vertex_size) {
assert(l && vertices > 0 && vertex_size > 0);
l->length = DISPLAYLIST_CACHE_LINES(vertices, vertex_size);
l->data = memalign(DISPLAYLIST_CLL, l->length);
DCInvalidateRange(l->data, l->length);
}
void displaylist_destroy(struct displaylist* l) {
assert(l);
free(l->data);
}
void displaylist_begin(struct displaylist* l) {
assert(l);
GX_BeginDispList(l->data, l->length);
}
void displaylist_end(struct displaylist* l) {
assert(l);
// has bug when exact size is given to GX_BeginDispList() (see docs), don't
// check result
GX_EndDispList();
}
void displaylist_render(struct displaylist* l) {
assert(l);
GX_CallDispList(l->data, l->length);
}

20
source/displaylist.h Normal file
View file

@ -0,0 +1,20 @@
#ifndef DISPLAYLIST_H
#define DISPLAYLIST_H
#include <stdbool.h>
#include <stddef.h>
struct displaylist {
void* data;
size_t length;
bool dirty;
};
void displaylist_init(struct displaylist* l, size_t vertices,
size_t vertex_size);
void displaylist_destroy(struct displaylist* l);
void displaylist_begin(struct displaylist* l);
void displaylist_end(struct displaylist* l);
void displaylist_render(struct displaylist* l);
#endif

736
source/render_block.c Normal file
View file

@ -0,0 +1,736 @@
#include <gccore.h>
#include <stdint.h>
#include "block/blocks.h"
#include "chunk.h"
#include "render_block.h"
#define BLK_LEN 256
#define TEX_OFFSET(x) ((x)*18 + 3)
static inline uint8_t MAX_LIGHT(uint8_t a, uint8_t b) {
return a > b ? a : b;
}
static uint8_t level_table_0[16] = {
0, 0, 0, 0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12,
};
static uint8_t level_table_1[16] = {
0, 0, 0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13,
};
static uint8_t level_table_2[16] = {
0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
};
static inline uint8_t DIM_LIGHT(uint8_t l, uint8_t* table, bool shade_sides,
uint8_t luminance) {
return shade_sides ?
(table[MAX_LIGHT(l >> 4, luminance)] << 4) | table[l & 0x0F] :
(MAX_LIGHT(l >> 4, luminance) << 4) | (l & 0x0F);
}
static inline void render_block_side_adv(struct displaylist* d, int16_t x,
int16_t y, int16_t z, uint16_t width,
uint16_t height, uint8_t tex_x,
uint8_t tex_y, bool tex_flip_h,
int tex_rotate, bool shade_sides,
enum side side, uint8_t* vertex_light,
uint8_t luminance) {
uint8_t tex_coords[2][4][2] = {
{
{tex_x, tex_y},
{tex_x + width / 16, tex_y},
{tex_x + width / 16, tex_y + height / 16},
{tex_x, tex_y + height / 16},
},
{
{tex_x + width / 16, tex_y},
{tex_x, tex_y},
{tex_x, tex_y + height / 16},
{tex_x + width / 16, tex_y + height / 16},
},
};
switch(side) {
case SIDE_LEFT: { // x minus
GX_Position3s16(x, y, z);
GX_Color1x8(DIM_LIGHT(vertex_light[8], level_table_1, shade_sides,
luminance));
GX_TexCoord2u8(tex_coords[tex_flip_h][(tex_rotate + 3) % 4][0],
tex_coords[tex_flip_h][(tex_rotate + 3) % 4][1]);
GX_Position3s16(x, y + height, z);
GX_Color1x8(DIM_LIGHT(vertex_light[9], level_table_1, shade_sides,
luminance));
GX_TexCoord2u8(tex_coords[tex_flip_h][(tex_rotate + 0) % 4][0],
tex_coords[tex_flip_h][(tex_rotate + 0) % 4][1]);
GX_Position3s16(x, y + height, z + width);
GX_Color1x8(DIM_LIGHT(vertex_light[10], level_table_1, shade_sides,
luminance));
GX_TexCoord2u8(tex_coords[tex_flip_h][(tex_rotate + 1) % 4][0],
tex_coords[tex_flip_h][(tex_rotate + 1) % 4][1]);
GX_Position3s16(x, y, z + width);
GX_Color1x8(DIM_LIGHT(vertex_light[11], level_table_1, shade_sides,
luminance));
GX_TexCoord2u8(tex_coords[tex_flip_h][(tex_rotate + 2) % 4][0],
tex_coords[tex_flip_h][(tex_rotate + 2) % 4][1]);
} break;
case SIDE_RIGHT: { // x positive
GX_Position3s16(x, y, z);
GX_Color1x8(DIM_LIGHT(vertex_light[12], level_table_1, shade_sides,
luminance));
GX_TexCoord2u8(tex_coords[tex_flip_h][(tex_rotate + 2) % 4][0],
tex_coords[tex_flip_h][(tex_rotate + 2) % 4][1]);
GX_Position3s16(x, y, z + width);
GX_Color1x8(DIM_LIGHT(vertex_light[15], level_table_1, shade_sides,
luminance));
GX_TexCoord2u8(tex_coords[tex_flip_h][(tex_rotate + 3) % 4][0],
tex_coords[tex_flip_h][(tex_rotate + 3) % 4][1]);
GX_Position3s16(x, y + height, z + width);
GX_Color1x8(DIM_LIGHT(vertex_light[14], level_table_1, shade_sides,
luminance));
GX_TexCoord2u8(tex_coords[tex_flip_h][(tex_rotate + 0) % 4][0],
tex_coords[tex_flip_h][(tex_rotate + 0) % 4][1]);
GX_Position3s16(x, y + height, z);
GX_Color1x8(DIM_LIGHT(vertex_light[13], level_table_1, shade_sides,
luminance));
GX_TexCoord2u8(tex_coords[tex_flip_h][(tex_rotate + 1) % 4][0],
tex_coords[tex_flip_h][(tex_rotate + 1) % 4][1]);
} break;
case SIDE_TOP: { // y positive
GX_Position3s16(x, y, z);
GX_Color1x8(DIM_LIGHT(vertex_light[4], NULL, false, luminance));
GX_TexCoord2u8(tex_coords[tex_flip_h][(tex_rotate + 0) % 4][0],
tex_coords[tex_flip_h][(tex_rotate + 0) % 4][1]);
GX_Position3s16(x + width, y, z);
GX_Color1x8(DIM_LIGHT(vertex_light[5], NULL, false, luminance));
GX_TexCoord2u8(tex_coords[tex_flip_h][(tex_rotate + 1) % 4][0],
tex_coords[tex_flip_h][(tex_rotate + 1) % 4][1]);
GX_Position3s16(x + width, y, z + height);
GX_Color1x8(DIM_LIGHT(vertex_light[6], NULL, false, luminance));
GX_TexCoord2u8(tex_coords[tex_flip_h][(tex_rotate + 2) % 4][0],
tex_coords[tex_flip_h][(tex_rotate + 2) % 4][1]);
GX_Position3s16(x, y, z + height);
GX_Color1x8(DIM_LIGHT(vertex_light[7], NULL, false, luminance));
GX_TexCoord2u8(tex_coords[tex_flip_h][(tex_rotate + 3) % 4][0],
tex_coords[tex_flip_h][(tex_rotate + 3) % 4][1]);
} break;
case SIDE_BOTTOM: { // y negative
GX_Position3s16(x, y, z);
GX_Color1x8(DIM_LIGHT(vertex_light[0], level_table_0, shade_sides,
luminance));
GX_TexCoord2u8(tex_coords[tex_flip_h][(tex_rotate + 3) % 4][0],
tex_coords[tex_flip_h][(tex_rotate + 3) % 4][1]);
GX_Position3s16(x, y, z + height);
GX_Color1x8(DIM_LIGHT(vertex_light[3], level_table_0, shade_sides,
luminance));
GX_TexCoord2u8(tex_coords[tex_flip_h][(tex_rotate + 0) % 4][0],
tex_coords[tex_flip_h][(tex_rotate + 0) % 4][1]);
GX_Position3s16(x + width, y, z + height);
GX_Color1x8(DIM_LIGHT(vertex_light[2], level_table_0, shade_sides,
luminance));
GX_TexCoord2u8(tex_coords[tex_flip_h][(tex_rotate + 1) % 4][0],
tex_coords[tex_flip_h][(tex_rotate + 1) % 4][1]);
GX_Position3s16(x + width, y, z);
GX_Color1x8(DIM_LIGHT(vertex_light[1], level_table_0, shade_sides,
luminance));
GX_TexCoord2u8(tex_coords[tex_flip_h][(tex_rotate + 2) % 4][0],
tex_coords[tex_flip_h][(tex_rotate + 2) % 4][1]);
} break;
case SIDE_FRONT: { // z minus
GX_Position3s16(x, y, z);
GX_Color1x8(DIM_LIGHT(vertex_light[16], level_table_2, shade_sides,
luminance));
GX_TexCoord2u8(tex_coords[tex_flip_h][(tex_rotate + 2) % 4][0],
tex_coords[tex_flip_h][(tex_rotate + 2) % 4][1]);
GX_Position3s16(x + width, y, z);
GX_Color1x8(DIM_LIGHT(vertex_light[17], level_table_2, shade_sides,
luminance));
GX_TexCoord2u8(tex_coords[tex_flip_h][(tex_rotate + 3) % 4][0],
tex_coords[tex_flip_h][(tex_rotate + 3) % 4][1]);
GX_Position3s16(x + width, y + height, z);
GX_Color1x8(DIM_LIGHT(vertex_light[18], level_table_2, shade_sides,
luminance));
GX_TexCoord2u8(tex_coords[tex_flip_h][(tex_rotate + 0) % 4][0],
tex_coords[tex_flip_h][(tex_rotate + 0) % 4][1]);
GX_Position3s16(x, y + height, z);
GX_Color1x8(DIM_LIGHT(vertex_light[19], level_table_2, shade_sides,
luminance));
GX_TexCoord2u8(tex_coords[tex_flip_h][(tex_rotate + 1) % 4][0],
tex_coords[tex_flip_h][(tex_rotate + 1) % 4][1]);
} break;
case SIDE_BACK: { // z positive
GX_Position3s16(x, y, z);
GX_Color1x8(DIM_LIGHT(vertex_light[20], level_table_2, shade_sides,
luminance));
GX_TexCoord2u8(tex_coords[tex_flip_h][(tex_rotate + 3) % 4][0],
tex_coords[tex_flip_h][(tex_rotate + 3) % 4][1]);
GX_Position3s16(x, y + height, z);
GX_Color1x8(DIM_LIGHT(vertex_light[23], level_table_2, shade_sides,
luminance));
GX_TexCoord2u8(tex_coords[tex_flip_h][(tex_rotate + 0) % 4][0],
tex_coords[tex_flip_h][(tex_rotate + 0) % 4][1]);
GX_Position3s16(x + width, y + height, z);
GX_Color1x8(DIM_LIGHT(vertex_light[22], level_table_2, shade_sides,
luminance));
GX_TexCoord2u8(tex_coords[tex_flip_h][(tex_rotate + 1) % 4][0],
tex_coords[tex_flip_h][(tex_rotate + 1) % 4][1]);
GX_Position3s16(x + width, y, z);
GX_Color1x8(DIM_LIGHT(vertex_light[21], level_table_2, shade_sides,
luminance));
GX_TexCoord2u8(tex_coords[tex_flip_h][(tex_rotate + 2) % 4][0],
tex_coords[tex_flip_h][(tex_rotate + 2) % 4][1]);
} break;
default: break;
}
}
static inline void render_block_side(struct displaylist* d, int16_t x,
int16_t y, int16_t z, int16_t yoffset,
uint16_t height, uint8_t tex,
uint8_t luminance, bool shade_sides,
uint16_t inset, bool tex_flip_h,
int tex_rotate, enum side side,
uint8_t* vertex_light) {
uint8_t tex_x = TEX_OFFSET(TEXTURE_X(tex));
uint8_t tex_y = TEX_OFFSET(TEXTURE_Y(tex));
switch(side) {
case SIDE_LEFT: // x minus
render_block_side_adv(
d, x * BLK_LEN + inset, y * BLK_LEN + yoffset, z * BLK_LEN,
BLK_LEN, height, tex_x, tex_y + (16 - height / 16), tex_flip_h,
tex_rotate, shade_sides, SIDE_LEFT, vertex_light, luminance);
break;
case SIDE_RIGHT: // x positive
render_block_side_adv(d, x * BLK_LEN + BLK_LEN - inset,
y * BLK_LEN + yoffset, z * BLK_LEN, BLK_LEN,
height, tex_x, tex_y + (16 - height / 16),
tex_flip_h, tex_rotate, shade_sides,
SIDE_RIGHT, vertex_light, luminance);
break;
case SIDE_BOTTOM: // y minus
render_block_side_adv(d, x * BLK_LEN, y * BLK_LEN + yoffset + inset,
z * BLK_LEN, BLK_LEN, BLK_LEN, tex_x, tex_y,
tex_flip_h, tex_rotate, shade_sides,
SIDE_BOTTOM, vertex_light, luminance);
break;
case SIDE_TOP: // y positive
render_block_side_adv(
d, x * BLK_LEN, y * BLK_LEN + yoffset + height - inset,
z * BLK_LEN, BLK_LEN, BLK_LEN, tex_x, tex_y, tex_flip_h,
tex_rotate, shade_sides, SIDE_TOP, vertex_light, luminance);
break;
case SIDE_FRONT: // z minus
render_block_side_adv(
d, x * BLK_LEN, y * BLK_LEN + yoffset, z * BLK_LEN + inset,
BLK_LEN, height, tex_x, tex_y + (16 - height / 16), tex_flip_h,
tex_rotate, shade_sides, SIDE_FRONT, vertex_light, luminance);
break;
case SIDE_BACK: // z positive
render_block_side_adv(d, x * BLK_LEN, y * BLK_LEN + yoffset,
z * BLK_LEN + BLK_LEN - inset, BLK_LEN,
height, tex_x, tex_y + (16 - height / 16),
tex_flip_h, tex_rotate, shade_sides,
SIDE_BACK, vertex_light, luminance);
break;
default: break;
}
}
size_t render_block_cross(struct displaylist* d, struct block_info* this,
enum side side, struct block_info* it,
uint8_t* vertex_light, bool count_only) {
if(side != SIDE_TOP)
return 0;
if(!count_only) {
int16_t x = W2C_COORD(this->x) * BLK_LEN;
int16_t y = W2C_COORD(this->y) * BLK_LEN;
int16_t z = W2C_COORD(this->z) * BLK_LEN;
if(blocks[this->block->type]
->render_block_data.cross_random_displacement) {
x += rand() % 129 - 64;
z += rand() % 129 - 64;
}
uint8_t tex
= blocks[this->block->type]->getTextureIndex(this, SIDE_TOP);
uint8_t tex_x = TEX_OFFSET(TEXTURE_X(tex));
uint8_t tex_y = TEX_OFFSET(TEXTURE_Y(tex));
uint8_t light = (MAX_LIGHT(this->block->torch_light,
blocks[this->block->type]->luminance)
<< 4)
| this->block->sky_light;
GX_Position3s16(x, y, z);
GX_Color1x8(light);
GX_TexCoord2u8(tex_x, tex_y + 16);
GX_Position3s16(x, y + BLK_LEN, z);
GX_Color1x8(light);
GX_TexCoord2u8(tex_x, tex_y);
GX_Position3s16(x + BLK_LEN, y + BLK_LEN, z + BLK_LEN);
GX_Color1x8(light);
GX_TexCoord2u8(tex_x + 16, tex_y);
GX_Position3s16(x + BLK_LEN, y, z + BLK_LEN);
GX_Color1x8(light);
GX_TexCoord2u8(tex_x + 16, tex_y + 16);
GX_Position3s16(x + BLK_LEN, y, z);
GX_Color1x8(light);
GX_TexCoord2u8(tex_x, tex_y + 16);
GX_Position3s16(x + BLK_LEN, y + BLK_LEN, z);
GX_Color1x8(light);
GX_TexCoord2u8(tex_x, tex_y);
GX_Position3s16(x, y + BLK_LEN, z + BLK_LEN);
GX_Color1x8(light);
GX_TexCoord2u8(tex_x + 16, tex_y);
GX_Position3s16(x, y, z + BLK_LEN);
GX_Color1x8(light);
GX_TexCoord2u8(tex_x + 16, tex_y + 16);
}
return 2;
}
size_t render_block_torch(struct displaylist* d, struct block_info* this,
enum side side, struct block_info* it,
uint8_t* vertex_light, bool count_only) {
if(side == SIDE_BOTTOM)
return 0;
if(!count_only) {
int16_t x = W2C_COORD(this->x);
int16_t y = W2C_COORD(this->y);
int16_t z = W2C_COORD(this->z);
uint8_t tex = blocks[this->block->type]->getTextureIndex(this, side);
uint8_t tex_x = TEX_OFFSET(TEXTURE_X(tex));
uint8_t tex_y = TEX_OFFSET(TEXTURE_Y(tex));
uint8_t light = (MAX_LIGHT(this->block->torch_light,
blocks[this->block->type]->luminance)
<< 4)
| this->block->sky_light;
int s1x, s1y; // wall offset
int s2x, s2y; // layer shift
int s3 = 48; // y offset
switch(this->block->metadata) {
case 1:
s1x = -128;
s1y = 0;
s2x = 104;
s2y = 0;
break;
case 2:
s1x = 128;
s1y = 0;
s2x = -104;
s2y = 0;
break;
case 3:
s1x = 0;
s1y = -128;
s2x = 0;
s2y = 104;
break;
case 4:
s1x = 0;
s1y = 128;
s2x = 0;
s2y = -104;
break;
default: s1x = s1y = s2x = s2y = s3 = 0; break;
}
switch(side) {
case SIDE_LEFT:
GX_Position3s16(x * BLK_LEN + 112 + s1x, y * BLK_LEN + s3,
z * BLK_LEN + s1y);
GX_Color1x8(DIM_LIGHT(light, level_table_1, true, 0));
GX_TexCoord2u8(tex_x, tex_y + 16);
GX_Position3s16(x * BLK_LEN + 112 + s1x + s2x,
y * BLK_LEN + BLK_LEN + s3,
z * BLK_LEN + s1y + s2y);
GX_Color1x8(DIM_LIGHT(light, level_table_1, true, 0));
GX_TexCoord2u8(tex_x, tex_y);
GX_Position3s16(x * BLK_LEN + 112 + s1x + s2x,
y * BLK_LEN + BLK_LEN + s3,
z * BLK_LEN + BLK_LEN + s1y + s2y);
GX_Color1x8(DIM_LIGHT(light, level_table_1, true, 0));
GX_TexCoord2u8(tex_x + 16, tex_y);
GX_Position3s16(x * BLK_LEN + 112 + s1x, y * BLK_LEN + s3,
z * BLK_LEN + BLK_LEN + s1y);
GX_Color1x8(DIM_LIGHT(light, level_table_1, true, 0));
GX_TexCoord2u8(tex_x + 16, tex_y + 16);
break;
case SIDE_RIGHT:
GX_Position3s16(x * BLK_LEN + 144 + s1x, y * BLK_LEN + s3,
z * BLK_LEN + s1y);
GX_Color1x8(DIM_LIGHT(light, level_table_1, true, 0));
GX_TexCoord2u8(tex_x + 16, tex_y + 16);
GX_Position3s16(x * BLK_LEN + 144 + s1x, y * BLK_LEN + s3,
z * BLK_LEN + BLK_LEN + s1y);
GX_Color1x8(DIM_LIGHT(light, level_table_1, true, 0));
GX_TexCoord2u8(tex_x, tex_y + 16);
GX_Position3s16(x * BLK_LEN + 144 + s1x + s2x,
y * BLK_LEN + BLK_LEN + s3,
z * BLK_LEN + BLK_LEN + s1y + s2y);
GX_Color1x8(DIM_LIGHT(light, level_table_1, true, 0));
GX_TexCoord2u8(tex_x, tex_y);
GX_Position3s16(x * BLK_LEN + 144 + s1x + s2x,
y * BLK_LEN + BLK_LEN + s3,
z * BLK_LEN + s1y + s2y);
GX_Color1x8(DIM_LIGHT(light, level_table_1, true, 0));
GX_TexCoord2u8(tex_x + 16, tex_y);
break;
case SIDE_BACK:
GX_Position3s16(x * BLK_LEN + s1x, y * BLK_LEN + s3,
z * BLK_LEN + 144 + s1y);
GX_Color1x8(DIM_LIGHT(light, level_table_2, true, 0));
GX_TexCoord2u8(tex_x, tex_y + 16);
GX_Position3s16(x * BLK_LEN + s1x + s2x,
y * BLK_LEN + BLK_LEN + s3,
z * BLK_LEN + 144 + s1y + s2y);
GX_Color1x8(DIM_LIGHT(light, level_table_2, true, 0));
GX_TexCoord2u8(tex_x, tex_y);
GX_Position3s16(x * BLK_LEN + BLK_LEN + s1x + s2x,
y * BLK_LEN + BLK_LEN + s3,
z * BLK_LEN + 144 + s1y + s2y);
GX_Color1x8(DIM_LIGHT(light, level_table_2, true, 0));
GX_TexCoord2u8(tex_x + 16, tex_y);
GX_Position3s16(x * BLK_LEN + BLK_LEN + s1x, y * BLK_LEN + s3,
z * BLK_LEN + 144 + s1y);
GX_Color1x8(DIM_LIGHT(light, level_table_2, true, 0));
GX_TexCoord2u8(tex_x + 16, tex_y + 16);
break;
case SIDE_FRONT:
GX_Position3s16(x * BLK_LEN + s1x, y * BLK_LEN + s3,
z * BLK_LEN + 112 + s1y);
GX_Color1x8(DIM_LIGHT(light, level_table_2, true, 0));
GX_TexCoord2u8(tex_x + 16, tex_y + 16);
GX_Position3s16(x * BLK_LEN + BLK_LEN + s1x, y * BLK_LEN + s3,
z * BLK_LEN + 112 + s1y);
GX_Color1x8(DIM_LIGHT(light, level_table_2, true, 0));
GX_TexCoord2u8(tex_x, tex_y + 16);
GX_Position3s16(x * BLK_LEN + BLK_LEN + s1x + s2x,
y * BLK_LEN + BLK_LEN + s3,
z * BLK_LEN + 112 + s1y + s2y);
GX_Color1x8(DIM_LIGHT(light, level_table_2, true, 0));
GX_TexCoord2u8(tex_x, tex_y);
GX_Position3s16(x * BLK_LEN + s1x + s2x,
y * BLK_LEN + BLK_LEN + s3,
z * BLK_LEN + 112 + s1y + s2y);
GX_Color1x8(DIM_LIGHT(light, level_table_2, true, 0));
GX_TexCoord2u8(tex_x + 16, tex_y);
break;
case SIDE_TOP:
GX_Position3s16(x * BLK_LEN + 112 + s1x + s2x * 10 / 16,
y * BLK_LEN + 160 + s3,
z * BLK_LEN + 112 + s1y + s2y * 10 / 16);
GX_Color1x8(light);
GX_TexCoord2u8(tex_x + 7, tex_y + 6);
GX_Position3s16(x * BLK_LEN + 144 + s1x + s2x * 10 / 16,
y * BLK_LEN + 160 + s3,
z * BLK_LEN + 112 + s1y + s2y * 10 / 16);
GX_Color1x8(light);
GX_TexCoord2u8(tex_x + 9, tex_y + 6);
GX_Position3s16(x * BLK_LEN + 144 + s1x + s2x * 10 / 16,
y * BLK_LEN + 160 + s3,
z * BLK_LEN + 144 + s1y + s2y * 10 / 16);
GX_Color1x8(light);
GX_TexCoord2u8(tex_x + 9, tex_y + 8);
GX_Position3s16(x * BLK_LEN + 112 + s1x + s2x * 10 / 16,
y * BLK_LEN + 160 + s3,
z * BLK_LEN + 144 + s1y + s2y * 10 / 16);
GX_Color1x8(light);
GX_TexCoord2u8(tex_x + 7, tex_y + 8);
break;
default: break;
}
}
return 1;
}
size_t render_block_cactus(struct displaylist* d, struct block_info* this,
enum side side, struct block_info* it,
uint8_t* vertex_light, bool count_only) {
if(!count_only)
render_block_side(
d, W2C_COORD(this->x), W2C_COORD(this->y), W2C_COORD(this->z), 0,
BLK_LEN, blocks[this->block->type]->getTextureIndex(this, side),
blocks[this->block->type]->luminance, true,
(side == SIDE_TOP || side == SIDE_BOTTOM) ? 0 : 16, false, 0, side,
vertex_light);
return 1;
}
size_t render_block_portal(struct displaylist* d, struct block_info* this,
enum side side, struct block_info* it,
uint8_t* vertex_light, bool count_only) {
// TODO: handle case with neighbour obsidian blocks correctly (low priority)
if(it->block->type == BLOCK_OBSIDIAN || it->block->type == BLOCK_PORTAL
|| side == SIDE_TOP || side == SIDE_BOTTOM)
return 0;
if(!count_only)
render_block_side(
d, W2C_COORD(this->x), W2C_COORD(this->y), W2C_COORD(this->z), 0,
BLK_LEN, blocks[this->block->type]->getTextureIndex(this, side),
blocks[this->block->type]->luminance, true, 96, false, 0, side,
vertex_light);
return 1;
}
size_t render_block_fluid(struct displaylist* d, struct block_info* this,
enum side side, struct block_info* it,
uint8_t* vertex_light, bool count_only) {
if(!count_only) {
uint16_t height = (this->block->metadata & 0x8) ?
BLK_LEN :
(8 - this->block->metadata) * 14 * 2;
render_block_side(
d, W2C_COORD(this->x), W2C_COORD(this->y), W2C_COORD(this->z), 0,
height, blocks[this->block->type]->getTextureIndex(this, side),
blocks[this->block->type]->luminance, true, 0, false, 0, side,
vertex_light);
}
return 1;
}
size_t render_block_rail(struct displaylist* d, struct block_info* this,
enum side side, struct block_info* it,
uint8_t* vertex_light, bool count_only) {
if(side != SIDE_TOP)
return 0;
if(!count_only) {
int16_t x = W2C_COORD(this->x);
int16_t y = W2C_COORD(this->y);
int16_t z = W2C_COORD(this->z);
uint8_t tex = blocks[this->block->type]->getTextureIndex(this, side);
uint8_t luminance = blocks[this->block->type]->luminance;
uint8_t tex_coords[4][2] = {
{TEX_OFFSET(TEXTURE_X(tex)), TEX_OFFSET(TEXTURE_Y(tex))},
{TEX_OFFSET(TEXTURE_X(tex)) + 16, TEX_OFFSET(TEXTURE_Y(tex))},
{TEX_OFFSET(TEXTURE_X(tex)) + 16, TEX_OFFSET(TEXTURE_Y(tex)) + 16},
{TEX_OFFSET(TEXTURE_X(tex)), TEX_OFFSET(TEXTURE_Y(tex)) + 16},
};
int tex_rotate = 0;
uint16_t a = 16, b = 16, c = 16, d = 16;
switch(this->block->metadata & 0x7) {
case 1: tex_rotate = 1; break;
case 2:
b = 272;
c = 272;
tex_rotate = 1;
break;
case 3:
a = 272;
d = 272;
tex_rotate = 1;
break;
case 4:
a = 272;
b = 272;
break;
case 5:
c = 272;
d = 272;
break;
}
if(blocks[this->block->type]->render_block_data.rail_curved_possible) {
switch(this->block->metadata) {
case 6: tex_rotate = 0; break;
case 7: tex_rotate = 3; break;
case 8: tex_rotate = 2; break;
}
}
GX_Position3s16(x * BLK_LEN, y * BLK_LEN + a, z * BLK_LEN);
GX_Color1x8(DIM_LIGHT(vertex_light[4], NULL, false, luminance));
GX_TexCoord2u8(tex_coords[(tex_rotate + 0) % 4][0],
tex_coords[(tex_rotate + 0) % 4][1]);
GX_Position3s16(x * BLK_LEN + BLK_LEN, y * BLK_LEN + b, z * BLK_LEN);
GX_Color1x8(DIM_LIGHT(vertex_light[5], NULL, false, luminance));
GX_TexCoord2u8(tex_coords[(tex_rotate + 1) % 4][0],
tex_coords[(tex_rotate + 1) % 4][1]);
GX_Position3s16(x * BLK_LEN + BLK_LEN, y * BLK_LEN + c,
z * BLK_LEN + BLK_LEN);
GX_Color1x8(DIM_LIGHT(vertex_light[6], NULL, false, luminance));
GX_TexCoord2u8(tex_coords[(tex_rotate + 2) % 4][0],
tex_coords[(tex_rotate + 2) % 4][1]);
GX_Position3s16(x * BLK_LEN, y * BLK_LEN + d, z * BLK_LEN + BLK_LEN);
GX_Color1x8(DIM_LIGHT(vertex_light[7], NULL, false, luminance));
GX_TexCoord2u8(tex_coords[(tex_rotate + 3) % 4][0],
tex_coords[(tex_rotate + 3) % 4][1]);
}
return 1;
}
size_t render_block_ladder(struct displaylist* d, struct block_info* this,
enum side side, struct block_info* it,
uint8_t* vertex_light, bool count_only) {
if((this->block->metadata == 2 && side != SIDE_FRONT)
|| (this->block->metadata == 3 && side != SIDE_BACK)
|| (this->block->metadata == 4 && side != SIDE_LEFT)
|| (this->block->metadata == 5 && side != SIDE_RIGHT))
return 0;
if(!count_only)
render_block_side(
d, W2C_COORD(this->x), W2C_COORD(this->y), W2C_COORD(this->z), 0,
BLK_LEN, blocks[this->block->type]->getTextureIndex(this, side),
blocks[this->block->type]->luminance, true, 240, false, 0, side,
vertex_light);
return 1;
}
size_t render_block_crops(struct displaylist* d, struct block_info* this,
enum side side, struct block_info* it,
uint8_t* vertex_light, bool count_only) {
if(side == SIDE_TOP || side == SIDE_BOTTOM)
return 0;
if(!count_only)
render_block_side(
d, W2C_COORD(this->x), W2C_COORD(this->y), W2C_COORD(this->z), -16,
BLK_LEN, blocks[this->block->type]->getTextureIndex(this, side),
blocks[this->block->type]->luminance, false, 64, false, 0, side,
vertex_light);
return 1;
}
size_t render_block_cake(struct displaylist* d, struct block_info* this,
enum side side, struct block_info* it,
uint8_t* vertex_light, bool count_only) {
if(!count_only) {
uint8_t tex = blocks[this->block->type]->getTextureIndex(this, side);
uint8_t luminance = blocks[this->block->type]->luminance;
switch(side) {
case SIDE_FRONT:
render_block_side_adv(d,
W2C_COORD(this->x) * BLK_LEN
+ this->block->metadata * 32 + 16,
W2C_COORD(this->y) * BLK_LEN,
W2C_COORD(this->z) * BLK_LEN + 16,
(7 - this->block->metadata) * 32, 128,
TEX_OFFSET(TEXTURE_X(tex)) + 1,
TEX_OFFSET(TEXTURE_Y(tex)) + 8, false, 0,
true, side, vertex_light, luminance);
break;
case SIDE_BACK:
render_block_side_adv(d,
W2C_COORD(this->x) * BLK_LEN
+ this->block->metadata * 32 + 16,
W2C_COORD(this->y) * BLK_LEN,
W2C_COORD(this->z) * BLK_LEN + 240,
(7 - this->block->metadata) * 32, 128,
TEX_OFFSET(TEXTURE_X(tex)) + 1
+ this->block->metadata * 2,
TEX_OFFSET(TEXTURE_Y(tex)) + 8, false, 0,
true, side, vertex_light, luminance);
break;
case SIDE_TOP:
render_block_side_adv(d,
W2C_COORD(this->x) * BLK_LEN
+ this->block->metadata * 32 + 16,
W2C_COORD(this->y) * BLK_LEN + 128,
W2C_COORD(this->z) * BLK_LEN + 16,
(7 - this->block->metadata) * 32, 224,
TEX_OFFSET(TEXTURE_X(tex)) + 1
+ this->block->metadata * 2,
TEX_OFFSET(TEXTURE_Y(tex)) + 1, false, 0,
true, side, vertex_light, luminance);
break;
case SIDE_BOTTOM:
render_block_side_adv(d,
W2C_COORD(this->x) * BLK_LEN
+ this->block->metadata * 32 + 16,
W2C_COORD(this->y) * BLK_LEN,
W2C_COORD(this->z) * BLK_LEN + 16,
(7 - this->block->metadata) * 32, 224,
TEX_OFFSET(TEXTURE_X(tex)) + 1
+ this->block->metadata * 2,
TEX_OFFSET(TEXTURE_Y(tex)) + 1, false, 0,
true, side, vertex_light, luminance);
break;
default:
render_block_side(
d, W2C_COORD(this->x), W2C_COORD(this->y),
W2C_COORD(this->z), 0, 128, tex, luminance, true,
(side == SIDE_LEFT) ? (16 + this->block->metadata * 32) :
16,
false, 0, side, vertex_light);
}
}
return 1;
}
size_t render_block_farmland(struct displaylist* d, struct block_info* this,
enum side side, struct block_info* it,
uint8_t* vertex_light, bool count_only) {
if(!count_only)
render_block_side(
d, W2C_COORD(this->x), W2C_COORD(this->y), W2C_COORD(this->z), 0,
240, blocks[this->block->type]->getTextureIndex(this, side),
blocks[this->block->type]->luminance, true, 0, false, 0, side,
vertex_light);
return 1;
}
size_t render_block_bed(struct displaylist* d, struct block_info* this,
enum side side, struct block_info* it,
uint8_t* vertex_light, bool count_only) {
if(!count_only)
render_block_side(
d, W2C_COORD(this->x), W2C_COORD(this->y), W2C_COORD(this->z), 0,
144, blocks[this->block->type]->getTextureIndex(this, side),
blocks[this->block->type]->luminance, true,
(side == SIDE_BOTTOM) ? 48 : 0,
(side == SIDE_RIGHT && (this->block->metadata & 0x3) == 0)
|| (side == SIDE_BACK && (this->block->metadata & 0x3) == 1)
|| (side == SIDE_LEFT && (this->block->metadata & 0x3) == 2)
|| (side == SIDE_FRONT && (this->block->metadata & 0x3) == 3),
(side == SIDE_TOP || side == SIDE_BOTTOM) ?
(3 - (this->block->metadata & 0x3)) :
0,
side, vertex_light);
return 1;
}
size_t render_block_slab(struct displaylist* d, struct block_info* this,
enum side side, struct block_info* it,
uint8_t* vertex_light, bool count_only) {
if(!count_only)
render_block_side(
d, W2C_COORD(this->x), W2C_COORD(this->y), W2C_COORD(this->z), 0,
128, blocks[this->block->type]->getTextureIndex(this, side),
blocks[this->block->type]->luminance, true, 0, false, 0, side,
vertex_light);
return 1;
}
size_t render_block_full(struct displaylist* d, struct block_info* this,
enum side side, struct block_info* it,
uint8_t* vertex_light, bool count_only) {
if(!count_only)
render_block_side(
d, W2C_COORD(this->x), W2C_COORD(this->y), W2C_COORD(this->z), 0,
BLK_LEN, blocks[this->block->type]->getTextureIndex(this, side),
blocks[this->block->type]->luminance, true, 0, false, 0, side,
vertex_light);
return 1;
}

63
source/render_block.h Normal file
View file

@ -0,0 +1,63 @@
#ifndef RENDER_BLOCK_H
#define RENDER_BLOCK_H
#include <stdbool.h>
#include <stddef.h>
#include "block/blocks.h"
#include "displaylist.h"
#include "world.h"
size_t render_block_cross(struct displaylist* d, struct block_info* this,
enum side side, struct block_info* it,
uint8_t* vertex_light, bool count_only);
size_t render_block_fluid(struct displaylist* d, struct block_info* this,
enum side side, struct block_info* it,
uint8_t* vertex_light, bool count_only);
size_t render_block_full(struct displaylist* d, struct block_info* this,
enum side side, struct block_info* it,
uint8_t* vertex_light, bool count_only);
size_t render_block_slab(struct displaylist* d, struct block_info* this,
enum side side, struct block_info* it,
uint8_t* vertex_light, bool count_only);
size_t render_block_bed(struct displaylist* d, struct block_info* this,
enum side side, struct block_info* it,
uint8_t* vertex_light, bool count_only);
size_t render_block_farmland(struct displaylist* d, struct block_info* this,
enum side side, struct block_info* it,
uint8_t* vertex_light, bool count_only);
size_t render_block_crops(struct displaylist* d, struct block_info* this,
enum side side, struct block_info* it,
uint8_t* vertex_light, bool count_only);
size_t render_block_torch(struct displaylist* d, struct block_info* this,
enum side side, struct block_info* it,
uint8_t* vertex_light, bool count_only);
size_t render_block_cactus(struct displaylist* d, struct block_info* this,
enum side side, struct block_info* it,
uint8_t* vertex_light, bool count_only);
size_t render_block_portal(struct displaylist* d, struct block_info* this,
enum side side, struct block_info* it,
uint8_t* vertex_light, bool count_only);
size_t render_block_rail(struct displaylist* d, struct block_info* this,
enum side side, struct block_info* it,
uint8_t* vertex_light, bool count_only);
size_t render_block_ladder(struct displaylist* d, struct block_info* this,
enum side side, struct block_info* it,
uint8_t* vertex_light, bool count_only);
size_t render_block_cake(struct displaylist* d, struct block_info* this,
enum side side, struct block_info* it,
uint8_t* vertex_light, bool count_only);
#endif

80
source/stack.c Executable file
View file

@ -0,0 +1,80 @@
#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "stack.h"
void stack_create(struct stack* stk, size_t inital_size, size_t element_size) {
assert(stk != NULL && inital_size > 0 && element_size > 0);
stk->element_size = element_size;
stk->index = 0;
stk->length = inital_size;
stk->data = malloc(stk->length * stk->element_size);
assert(stk->data);
}
void stack_push(struct stack* stk, void* obj) {
assert(stk != NULL && obj != NULL);
if(stk->index >= stk->length) {
stk->length *= 2;
stk->data = realloc(stk->data, stk->length * stk->element_size);
assert(stk->data);
}
memcpy((uint8_t*)stk->data + (stk->index++) * stk->element_size, obj,
stk->element_size);
}
bool stack_empty(struct stack* stk) {
assert(stk != NULL);
return stk->index == 0;
}
size_t stack_size(struct stack* stk) {
assert(stk != NULL);
return stk->index;
}
void stack_at(struct stack* stk, void* obj, size_t index) {
assert(stk != NULL && obj != NULL);
if(index < stk->index)
memcpy(obj, (uint8_t*)stk->data + index * stk->element_size,
stk->element_size);
}
bool stack_pop(struct stack* stk, void* obj) {
assert(stk != NULL && obj != NULL);
if(stack_empty(stk))
return false;
memcpy(obj, (uint8_t*)stk->data + (--stk->index) * stk->element_size,
stk->element_size);
/*if(stk->index * 4 <= stk->length) {
stk->length /= 2;
stk->data = realloc(stk->data, stk->length * stk->element_size);
assert(stk->data);
}*/
return true;
}
void stack_clear(struct stack* stk) {
assert(stk != NULL);
stk->index = 0;
}
void stack_destroy(struct stack* stk) {
assert(stk != NULL);
if(stk->data)
free(stk->data);
}

30
source/stack.h Executable file
View file

@ -0,0 +1,30 @@
#ifndef STACK_H
#define STACK_H
#include <stdbool.h>
#include <stddef.h>
struct stack {
size_t length;
size_t index;
size_t element_size;
void* data;
};
void stack_create(struct stack* stk, size_t inital_size, size_t element_size);
void stack_push(struct stack* stk, void* obj);
bool stack_empty(struct stack* stk);
size_t stack_size(struct stack* stk);
void stack_at(struct stack* stk, void* obj, size_t index);
bool stack_pop(struct stack* stk, void* obj);
void stack_clear(struct stack* stk);
void stack_destroy(struct stack* stk);
#endif

1094
source/triangle.c Normal file

File diff suppressed because it is too large Load diff

24
source/world.c Normal file
View file

@ -0,0 +1,24 @@
#include <assert.h>
#include "chunk.h"
#include "world.h"
struct block_data world_get_block(struct world* w, w_coord_t x, w_coord_t y,
w_coord_t z) {
assert(w);
struct chunk* c = world_find_chunk(w, x, y, z);
return c ? chunk_get_block(c, x & CHUNK_SIZE_BITS, y & CHUNK_SIZE_BITS,
z & CHUNK_SIZE_BITS) :
(struct block_data) {.type = (y < WORLD_HEIGHT) ? 1 : 0};
}
void world_set_block(struct world* w, w_coord_t x, w_coord_t y, w_coord_t z,
struct block_data blk) {
assert(w);
struct chunk* c = world_find_chunk(w, x, y, z);
if(c)
chunk_set_block(c, x & CHUNK_SIZE_BITS, y & CHUNK_SIZE_BITS,
z & CHUNK_SIZE_BITS, blk);
}

37
source/world.h Normal file
View file

@ -0,0 +1,37 @@
#ifndef WORLD_H
#define WORLD_H
#include <stddef.h>
#include <stdint.h>
#define WORLD_HEIGHT 128
typedef int32_t w_coord_t;
struct block_data {
uint8_t type;
uint8_t metadata : 4;
uint8_t sky_light : 4;
uint8_t torch_light : 4;
};
struct block_info {
struct block_data* block;
struct world* world;
w_coord_t x, y, z;
};
struct world {
int test;
};
void world_init(struct world* w, size_t chunks);
void world_destroy(struct world* w);
struct chunk* world_find_chunk(struct world* w, w_coord_t x, w_coord_t y,
w_coord_t z);
struct block_data world_get_block(struct world* w, w_coord_t x, w_coord_t y,
w_coord_t z);
void world_set_block(struct world* w, w_coord_t x, w_coord_t y, w_coord_t z,
struct block_data blk);
#endif