diff --git a/CMakeLists.txt b/CMakeLists.txt index ec76553..a4c285c 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -102,12 +102,14 @@ add_executable(cavex source/graphics/gui_util.c source/graphics/render_block.c source/graphics/render_item.c + source/graphics/texture_atlas.c source/platform/displaylist.c source/platform/gfx.c source/platform/input.c source/platform/thread.c source/platform/time.c + source/platform/texture.c source/chunk_mesher.c source/chunk.c diff --git a/Makefile b/Makefile index ecdb66c..e442dc0 100644 --- a/Makefile +++ b/Makefile @@ -23,7 +23,7 @@ include $(DEVKITPPC)/wii_rules #--------------------------------------------------------------------------------- TARGET := $(notdir $(CURDIR)) BUILD := build -SOURCES := source source/block source/graphics source/network source/game source/game/gui source/platform source/item source/cNBT +SOURCES := source source/block source/graphics source/network source/game source/game/gui source/platform source/item source/cNBT source/lodepng DATA := TEXTURES := textures INCLUDES := diff --git a/source/block/block_bed.c b/source/block/block_bed.c index f3c7132..7cd5d60 100644 --- a/source/block/block_bed.c +++ b/source/block/block_bed.c @@ -47,29 +47,33 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { 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_TOP: return tex_atlas_lookup(TEXAT_BED_TOP_2); case SIDE_LEFT: case SIDE_RIGHT: - return (this->block->metadata & 0x1) ? TEXTURE_INDEX(11, 8) : - TEXTURE_INDEX(10, 8); + return (this->block->metadata & 0x1) ? + tex_atlas_lookup(TEXAT_BED_FRONT) : + tex_atlas_lookup(TEXAT_BED_SIDE_2); 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); + return (this->block->metadata & 0x1) ? + tex_atlas_lookup(TEXAT_BED_SIDE_2) : + tex_atlas_lookup(TEXAT_BED_FRONT); + default: return tex_atlas_lookup(TEXAT_PLANKS); } } else { switch(side) { - case SIDE_TOP: return TEXTURE_INDEX(6, 8); + case SIDE_TOP: return tex_atlas_lookup(TEXAT_BED_TOP_1); case SIDE_LEFT: case SIDE_RIGHT: - return (this->block->metadata & 0x1) ? TEXTURE_INDEX(8, 8) : - TEXTURE_INDEX(9, 8); + return (this->block->metadata & 0x1) ? + tex_atlas_lookup(TEXAT_BED_BACK) : + tex_atlas_lookup(TEXAT_BED_SIDE_1); 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); + return (this->block->metadata & 0x1) ? + tex_atlas_lookup(TEXAT_BED_SIDE_1) : + tex_atlas_lookup(TEXAT_BED_BACK); + default: return tex_atlas_lookup(TEXAT_PLANKS); } } } diff --git a/source/block/block_bedrock.c b/source/block/block_bedrock.c index 3e22c0d..d765a45 100755 --- a/source/block/block_bedrock.c +++ b/source/block/block_bedrock.c @@ -35,7 +35,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { } static uint8_t getTextureIndex(struct block_info* this, enum side side) { - return TEXTURE_INDEX(1, 1); + return tex_atlas_lookup(TEXAT_BEDROCK); } struct block block_bedrock = { diff --git a/source/block/block_bookshelf.c b/source/block/block_bookshelf.c index c54bad4..56fda5a 100644 --- a/source/block/block_bookshelf.c +++ b/source/block/block_bookshelf.c @@ -37,8 +37,8 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { static uint8_t getTextureIndex(struct block_info* this, enum side side) { switch(side) { case SIDE_TOP: - case SIDE_BOTTOM: return TEXTURE_INDEX(4, 0); - default: return TEXTURE_INDEX(3, 2); + case SIDE_BOTTOM: return tex_atlas_lookup(TEXAT_PLANKS); + default: return tex_atlas_lookup(TEXAT_BOOKSHELF); } } diff --git a/source/block/block_bricks.c b/source/block/block_bricks.c index 4270387..646126b 100644 --- a/source/block/block_bricks.c +++ b/source/block/block_bricks.c @@ -35,7 +35,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { } static uint8_t getTextureIndex(struct block_info* this, enum side side) { - return TEXTURE_INDEX(7, 0); + return tex_atlas_lookup(TEXAT_BRICKS); } struct block block_bricks = { diff --git a/source/block/block_brown_mushroom.c b/source/block/block_brown_mushroom.c index 2d810b8..5bfe2f7 100644 --- a/source/block/block_brown_mushroom.c +++ b/source/block/block_brown_mushroom.c @@ -35,7 +35,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { } static uint8_t getTextureIndex(struct block_info* this, enum side side) { - return TEXTURE_INDEX(13, 1); + return tex_atlas_lookup(TEXAT_MUSHROOM_BROWN); } struct block block_brown_mushroom = { diff --git a/source/block/block_cactus.c b/source/block/block_cactus.c index ff9994e..bfdf044 100644 --- a/source/block/block_cactus.c +++ b/source/block/block_cactus.c @@ -45,9 +45,9 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { 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); + case SIDE_TOP: return tex_atlas_lookup(TEXAT_CACTUS_TOP); + case SIDE_BOTTOM: return tex_atlas_lookup(TEXAT_CACTUS_BOTTOM); + default: return tex_atlas_lookup(TEXAT_CACTUS_SIDE); } } diff --git a/source/block/block_cake.c b/source/block/block_cake.c index 13cdf49..08e5c3d 100644 --- a/source/block/block_cake.c +++ b/source/block/block_cake.c @@ -46,12 +46,13 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { 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_TOP: return tex_atlas_lookup(TEXAT_CAKE_TOP); + case SIDE_BOTTOM: return tex_atlas_lookup(TEXAT_CAKE_BOTTOM); case SIDE_LEFT: - return (this->block->metadata > 0) ? TEXTURE_INDEX(11, 7) : - TEXTURE_INDEX(10, 7); - default: return TEXTURE_INDEX(10, 7); + return (this->block->metadata > 0) ? + tex_atlas_lookup(TEXAT_CAKE_SIDE_CUT) : + tex_atlas_lookup(TEXAT_CAKE_SIDE); + default: return tex_atlas_lookup(TEXAT_CAKE_SIDE); } } diff --git a/source/block/block_cast_block.c b/source/block/block_cast_block.c index 69d37dd..71d4919 100644 --- a/source/block/block_cast_block.c +++ b/source/block/block_cast_block.c @@ -35,19 +35,19 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { } static uint8_t getTextureIndex1(struct block_info* this, enum side side) { - return TEXTURE_INDEX(6, 1); + return tex_atlas_lookup(TEXAT_CAST_BLOCK_IRON); } static uint8_t getTextureIndex2(struct block_info* this, enum side side) { - return TEXTURE_INDEX(7, 1); + return tex_atlas_lookup(TEXAT_CAST_BLOCK_GOLD); } static uint8_t getTextureIndex3(struct block_info* this, enum side side) { - return TEXTURE_INDEX(8, 1); + return tex_atlas_lookup(TEXAT_CAST_BLOCK_DIAMOND); } static uint8_t getTextureIndex4(struct block_info* this, enum side side) { - return TEXTURE_INDEX(0, 9); + return tex_atlas_lookup(TEXAT_CAST_BLOCK_LAPIS); } struct block block_iron = { diff --git a/source/block/block_chest.c b/source/block/block_chest.c index 31082a8..f2e51ba 100644 --- a/source/block/block_chest.c +++ b/source/block/block_chest.c @@ -45,59 +45,62 @@ static uint8_t getTextureIndex(struct block_info* this, enum side side) { 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); + case SIDE_BOTTOM: return tex_atlas_lookup(TEXAT_CHEST_TOP); + case SIDE_BACK: return tex_atlas_lookup(TEXAT_CHEST_FRONT_1); + case SIDE_FRONT: return tex_atlas_lookup(TEXAT_CHEST_BACK_2); + default: return tex_atlas_lookup(TEXAT_CHEST_SIDE); } } 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); + case SIDE_BOTTOM: return tex_atlas_lookup(TEXAT_CHEST_TOP); + case SIDE_BACK: return tex_atlas_lookup(TEXAT_CHEST_FRONT_2); + case SIDE_FRONT: return tex_atlas_lookup(TEXAT_CHEST_BACK_1); + default: return tex_atlas_lookup(TEXAT_CHEST_SIDE); } } 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); + case SIDE_BOTTOM: return tex_atlas_lookup(TEXAT_CHEST_TOP); + case SIDE_RIGHT: return tex_atlas_lookup(TEXAT_CHEST_FRONT_2); + case SIDE_LEFT: return tex_atlas_lookup(TEXAT_CHEST_BACK_1); + default: return tex_atlas_lookup(TEXAT_CHEST_SIDE); } } 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); + case SIDE_BOTTOM: return tex_atlas_lookup(TEXAT_CHEST_TOP); + case SIDE_RIGHT: return tex_atlas_lookup(TEXAT_CHEST_FRONT_1); + case SIDE_LEFT: return tex_atlas_lookup(TEXAT_CHEST_BACK_2); + default: return tex_atlas_lookup(TEXAT_CHEST_SIDE); } } 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), + [SIDE_TOP] = tex_atlas_lookup(TEXAT_CHEST_TOP), + [SIDE_BOTTOM] = tex_atlas_lookup(TEXAT_CHEST_TOP), + [SIDE_BACK] = tex_atlas_lookup(TEXAT_CHEST_SIDE), + [SIDE_FRONT] = tex_atlas_lookup(TEXAT_CHEST_SIDE), + [SIDE_LEFT] = tex_atlas_lookup(TEXAT_CHEST_SIDE), + [SIDE_RIGHT] = tex_atlas_lookup(TEXAT_CHEST_SIDE), }; if(left->type && !right->type) - tex[SIDE_RIGHT] = TEXTURE_INDEX(11, 1); + tex[SIDE_RIGHT] = tex_atlas_lookup(TEXAT_CHEST_FRONT_SINGLE); else if(right->type && !left->type) - tex[SIDE_LEFT] = TEXTURE_INDEX(11, 1); + tex[SIDE_LEFT] = tex_atlas_lookup(TEXAT_CHEST_FRONT_SINGLE); else if(front->type && !back->type) - tex[SIDE_BACK] = TEXTURE_INDEX(11, 1); + tex[SIDE_BACK] = tex_atlas_lookup(TEXAT_CHEST_FRONT_SINGLE); else if(back->type && !front->type) - tex[SIDE_FRONT] = TEXTURE_INDEX(11, 1); + tex[SIDE_FRONT] = tex_atlas_lookup(TEXAT_CHEST_FRONT_SINGLE); else - tex[SIDE_BACK] = TEXTURE_INDEX(11, 1); + tex[SIDE_BACK] = tex_atlas_lookup(TEXAT_CHEST_FRONT_SINGLE); return tex[side]; } diff --git a/source/block/block_clay.c b/source/block/block_clay.c index e048bf4..bc64d42 100644 --- a/source/block/block_clay.c +++ b/source/block/block_clay.c @@ -35,7 +35,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { } static uint8_t getTextureIndex(struct block_info* this, enum side side) { - return TEXTURE_INDEX(8, 4); + return tex_atlas_lookup(TEXAT_CLAY); } struct block block_clay = { diff --git a/source/block/block_cobblestone.c b/source/block/block_cobblestone.c index 4d1bb7c..6566f0b 100755 --- a/source/block/block_cobblestone.c +++ b/source/block/block_cobblestone.c @@ -36,8 +36,8 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { 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); + default: return tex_atlas_lookup(TEXAT_COBBLESTONE); + case 48: return tex_atlas_lookup(TEXAT_COBBLESTONE_MOSSY); } } diff --git a/source/block/block_cobweb.c b/source/block/block_cobweb.c index 7e89596..3b23baa 100644 --- a/source/block/block_cobweb.c +++ b/source/block/block_cobweb.c @@ -35,7 +35,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { } static uint8_t getTextureIndex(struct block_info* this, enum side side) { - return TEXTURE_INDEX(11, 0); + return tex_atlas_lookup(TEXAT_COBWEB); } struct block block_cobweb = { diff --git a/source/block/block_crops.c b/source/block/block_crops.c index 99236ae..0b747ba 100644 --- a/source/block/block_crops.c +++ b/source/block/block_crops.c @@ -35,7 +35,17 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { } static uint8_t getTextureIndex(struct block_info* this, enum side side) { - return TEXTURE_INDEX(this->block->metadata + 6, 5); + switch(this->block->metadata) { + case 0: return tex_atlas_lookup(TEXAT_CROPS_0); + case 1: return tex_atlas_lookup(TEXAT_CROPS_1); + case 2: return tex_atlas_lookup(TEXAT_CROPS_2); + case 3: return tex_atlas_lookup(TEXAT_CROPS_3); + case 4: return tex_atlas_lookup(TEXAT_CROPS_4); + case 5: return tex_atlas_lookup(TEXAT_CROPS_5); + case 6: return tex_atlas_lookup(TEXAT_CROPS_6); + default: + case 7: return tex_atlas_lookup(TEXAT_CROPS_7); + } } struct block block_crops = { diff --git a/source/block/block_dirt.c b/source/block/block_dirt.c index 9c43343..feb1769 100644 --- a/source/block/block_dirt.c +++ b/source/block/block_dirt.c @@ -35,7 +35,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { } static uint8_t getTextureIndex(struct block_info* this, enum side side) { - return TEXTURE_INDEX(2, 0); + return tex_atlas_lookup(TEXAT_DIRT); } struct block block_dirt = { diff --git a/source/block/block_dispenser.c b/source/block/block_dispenser.c index d8d0488..4125550 100644 --- a/source/block/block_dispenser.c +++ b/source/block/block_dispenser.c @@ -38,25 +38,25 @@ 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, 4); + return tex_atlas_lookup(TEXAT_DISPENSER_FRONT); else - return TEXTURE_INDEX(13, 2); + return tex_atlas_lookup(TEXAT_FURNACE_SIDE); case SIDE_BACK: if(this->block->metadata == 3) - return TEXTURE_INDEX(12, 4); + return tex_atlas_lookup(TEXAT_DISPENSER_FRONT); else - return TEXTURE_INDEX(13, 2); + return tex_atlas_lookup(TEXAT_FURNACE_SIDE); case SIDE_RIGHT: if(this->block->metadata == 5) - return TEXTURE_INDEX(12, 4); + return tex_atlas_lookup(TEXAT_DISPENSER_FRONT); else - return TEXTURE_INDEX(13, 2); + return tex_atlas_lookup(TEXAT_FURNACE_SIDE); case SIDE_LEFT: if(this->block->metadata == 4) - return TEXTURE_INDEX(12, 4); + return tex_atlas_lookup(TEXAT_DISPENSER_FRONT); else - return TEXTURE_INDEX(13, 2); - default: return TEXTURE_INDEX(13, 4); + return tex_atlas_lookup(TEXAT_FURNACE_SIDE); + default: return tex_atlas_lookup(TEXAT_FURNACE_TOP); } } diff --git a/source/block/block_door.c b/source/block/block_door.c index 74d1b2c..ebf45ca 100644 --- a/source/block/block_door.c +++ b/source/block/block_door.c @@ -61,11 +61,15 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { } static uint8_t getTextureIndex1(struct block_info* this, enum side side) { - return TEXTURE_INDEX(1, (this->block->metadata & 0x08) ? 5 : 6); + return (this->block->metadata & 0x08) ? + tex_atlas_lookup(TEXAT_DOOR_WOOD_TOP) : + tex_atlas_lookup(TEXAT_DOOR_WOOD_BOTTOM); } static uint8_t getTextureIndex2(struct block_info* this, enum side side) { - return TEXTURE_INDEX(2, (this->block->metadata & 0x08) ? 5 : 6); + return (this->block->metadata & 0x08) ? + tex_atlas_lookup(TEXAT_DOOR_IRON_TOP) : + tex_atlas_lookup(TEXAT_DOOR_IRON_BOTTOM); } struct block block_wooden_door = { diff --git a/source/block/block_double_slab.c b/source/block/block_double_slab.c index 3459ec9..8fbb95d 100644 --- a/source/block/block_double_slab.c +++ b/source/block/block_double_slab.c @@ -39,15 +39,16 @@ static uint8_t getTextureIndex(struct block_info* this, enum side side) { default: case 0: return (side == SIDE_TOP || side == SIDE_BOTTOM) ? - TEXTURE_INDEX(6, 0) : - TEXTURE_INDEX(5, 0); + tex_atlas_lookup(TEXAT_SLAB_STONE_TOP) : + tex_atlas_lookup(TEXAT_SLAB_STONE_SIDE); 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); + tex_atlas_lookup(TEXAT_SANDSTONE_TOP) : + ((side == SIDE_BOTTOM) ? + tex_atlas_lookup(TEXAT_SANDSTONE_BOTTOM) : + tex_atlas_lookup(TEXAT_SANDSTONE_SIDE)); + case 2: return tex_atlas_lookup(TEXAT_PLANKS); + case 3: return tex_atlas_lookup(TEXAT_COBBLESTONE); } } diff --git a/source/block/block_farmland.c b/source/block/block_farmland.c index d37d8a4..8bb77f8 100644 --- a/source/block/block_farmland.c +++ b/source/block/block_farmland.c @@ -41,9 +41,10 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { 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); + return (this->block->metadata < 7) ? + tex_atlas_lookup(TEXAT_FARMLAND_DRY) : + tex_atlas_lookup(TEXAT_FARMLAND_WET); + default: return tex_atlas_lookup(TEXAT_DIRT); } } diff --git a/source/block/block_fence.c b/source/block/block_fence.c index 55e9fe2..9fac697 100644 --- a/source/block/block_fence.c +++ b/source/block/block_fence.c @@ -44,7 +44,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { } static uint8_t getTextureIndex(struct block_info* this, enum side side) { - return TEXTURE_INDEX(4, 0); + return tex_atlas_lookup(TEXAT_PLANKS); } struct block block_fence = { diff --git a/source/block/block_flower.c b/source/block/block_flower.c index 839b74b..5ffdd98 100644 --- a/source/block/block_flower.c +++ b/source/block/block_flower.c @@ -35,7 +35,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { } static uint8_t getTextureIndex(struct block_info* this, enum side side) { - return TEXTURE_INDEX(13, 0); + return tex_atlas_lookup(TEXAT_DANDELION); } struct block block_flower = { diff --git a/source/block/block_furnace.c b/source/block/block_furnace.c index e9e2dc4..d697a0b 100644 --- a/source/block/block_furnace.c +++ b/source/block/block_furnace.c @@ -34,29 +34,55 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { return face_occlusion_full(); } -static uint8_t getTextureIndex(struct block_info* this, enum side side) { +static uint8_t getTextureIndex1(struct block_info* this, enum side side) { switch(side) { case SIDE_FRONT: if(this->block->metadata == 2) - return TEXTURE_INDEX(12, 2); + return tex_atlas_lookup(TEXAT_FURNACE_FRONT); else - return TEXTURE_INDEX(13, 2); + return tex_atlas_lookup(TEXAT_FURNACE_SIDE); case SIDE_BACK: if(this->block->metadata == 3) - return TEXTURE_INDEX(12, 2); + return tex_atlas_lookup(TEXAT_FURNACE_FRONT); else - return TEXTURE_INDEX(13, 2); + return tex_atlas_lookup(TEXAT_FURNACE_SIDE); case SIDE_RIGHT: if(this->block->metadata == 5) - return TEXTURE_INDEX(12, 2); + return tex_atlas_lookup(TEXAT_FURNACE_FRONT); else - return TEXTURE_INDEX(13, 2); + return tex_atlas_lookup(TEXAT_FURNACE_SIDE); case SIDE_LEFT: if(this->block->metadata == 4) - return TEXTURE_INDEX(12, 2); + return tex_atlas_lookup(TEXAT_FURNACE_FRONT); else - return TEXTURE_INDEX(13, 2); - default: return TEXTURE_INDEX(13, 4); + return tex_atlas_lookup(TEXAT_FURNACE_SIDE); + default: return tex_atlas_lookup(TEXAT_FURNACE_TOP); + } +} + +static uint8_t getTextureIndex2(struct block_info* this, enum side side) { + switch(side) { + case SIDE_FRONT: + if(this->block->metadata == 2) + return tex_atlas_lookup(TEXAT_FURNACE_FRONT_LIT); + else + return tex_atlas_lookup(TEXAT_FURNACE_SIDE); + case SIDE_BACK: + if(this->block->metadata == 3) + return tex_atlas_lookup(TEXAT_FURNACE_FRONT_LIT); + else + return tex_atlas_lookup(TEXAT_FURNACE_SIDE); + case SIDE_RIGHT: + if(this->block->metadata == 5) + return tex_atlas_lookup(TEXAT_FURNACE_FRONT_LIT); + else + return tex_atlas_lookup(TEXAT_FURNACE_SIDE); + case SIDE_LEFT: + if(this->block->metadata == 4) + return tex_atlas_lookup(TEXAT_FURNACE_FRONT_LIT); + else + return tex_atlas_lookup(TEXAT_FURNACE_SIDE); + default: return tex_atlas_lookup(TEXAT_FURNACE_TOP); } } @@ -65,7 +91,7 @@ struct block block_furnaceoff = { .getSideMask = getSideMask, .getBoundingBox = getBoundingBox, .getMaterial = getMaterial, - .getTextureIndex = getTextureIndex, + .getTextureIndex = getTextureIndex1, .transparent = false, .renderBlock = render_block_full, .renderBlockAlways = NULL, @@ -89,7 +115,7 @@ struct block block_furnaceon = { .getSideMask = getSideMask, .getBoundingBox = getBoundingBox, .getMaterial = getMaterial, - .getTextureIndex = getTextureIndex, + .getTextureIndex = getTextureIndex2, .transparent = false, .renderBlock = render_block_full, .renderBlockAlways = NULL, diff --git a/source/block/block_glass.c b/source/block/block_glass.c index f51f6b7..76ab66e 100644 --- a/source/block/block_glass.c +++ b/source/block/block_glass.c @@ -36,7 +36,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { } static uint8_t getTextureIndex(struct block_info* this, enum side side) { - return TEXTURE_INDEX(1, 3); + return tex_atlas_lookup(TEXAT_GLASS); } struct block block_glass = { diff --git a/source/block/block_glowstone.c b/source/block/block_glowstone.c index ee9cb4f..01ef55c 100644 --- a/source/block/block_glowstone.c +++ b/source/block/block_glowstone.c @@ -35,7 +35,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { } static uint8_t getTextureIndex(struct block_info* this, enum side side) { - return TEXTURE_INDEX(9, 6); + return tex_atlas_lookup(TEXAT_GLOWSTONE); } struct block block_glowstone = { diff --git a/source/block/block_grass.c b/source/block/block_grass.c index b7fd70d..311412e 100755 --- a/source/block/block_grass.c +++ b/source/block/block_grass.c @@ -38,13 +38,13 @@ static uint8_t getTextureIndex(struct block_info* this, enum side side) { switch(side) { case SIDE_TOP: return (this->neighbours[SIDE_TOP].type == BLOCK_SNOW) ? - TEXTURE_INDEX(2, 4) : - TEXTURE_INDEX(5, 9); - case SIDE_BOTTOM: return TEXTURE_INDEX(2, 0); + tex_atlas_lookup(TEXAT_SNOW) : + tex_atlas_lookup(TEXAT_GRASS_TOP); + case SIDE_BOTTOM: return tex_atlas_lookup(TEXAT_DIRT); default: return (this->neighbours[SIDE_TOP].type == BLOCK_SNOW) ? - TEXTURE_INDEX(4, 4) : - TEXTURE_INDEX(5, 10); + tex_atlas_lookup(TEXAT_GRASS_SIDE_SNOW) : + tex_atlas_lookup(TEXAT_GRASS_SIDE); } } diff --git a/source/block/block_gravel.c b/source/block/block_gravel.c index 8b7659c..c77ea00 100644 --- a/source/block/block_gravel.c +++ b/source/block/block_gravel.c @@ -35,7 +35,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { } static uint8_t getTextureIndex(struct block_info* this, enum side side) { - return TEXTURE_INDEX(3, 1); + return tex_atlas_lookup(TEXAT_GRAVEL); } struct block block_gravel = { diff --git a/source/block/block_jukebox.c b/source/block/block_jukebox.c index f32e750..42c97d7 100644 --- a/source/block/block_jukebox.c +++ b/source/block/block_jukebox.c @@ -36,8 +36,8 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { static uint8_t getTextureIndex(struct block_info* this, enum side side) { switch(side) { - case SIDE_TOP: return TEXTURE_INDEX(11, 4); - default: return TEXTURE_INDEX(10, 4); + case SIDE_TOP: return tex_atlas_lookup(TEXAT_JUKBEBOX_TOP); + default: return tex_atlas_lookup(TEXAT_JUKBEBOX_SIDE); } } diff --git a/source/block/block_ladder.c b/source/block/block_ladder.c index 249fb3d..c808c1d 100644 --- a/source/block/block_ladder.c +++ b/source/block/block_ladder.c @@ -52,7 +52,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { } static uint8_t getTextureIndex(struct block_info* this, enum side side) { - return TEXTURE_INDEX(3, 5); + return tex_atlas_lookup(TEXAT_LADDER); } struct block block_ladder = { diff --git a/source/block/block_leaves.c b/source/block/block_leaves.c index 710d29b..9c65c2f 100644 --- a/source/block/block_leaves.c +++ b/source/block/block_leaves.c @@ -45,9 +45,9 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { 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); + case 1: return tex_atlas_lookup(TEXAT_LEAVES_SPRUCE); + case 2: return tex_atlas_lookup(TEXAT_LEAVES_BIRCH); + default: return tex_atlas_lookup(TEXAT_LEAVES_OAK); } } diff --git a/source/block/block_log.c b/source/block/block_log.c index 57689b4..7ea12f1 100644 --- a/source/block/block_log.c +++ b/source/block/block_log.c @@ -35,29 +35,14 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { } static uint8_t getTextureIndex(struct block_info* this, enum side side) { + if(side == SIDE_TOP || side == SIDE_BOTTOM) + return tex_atlas_lookup(TEXAT_LOG_OAK_TOP); + 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; + case 0: return tex_atlas_lookup(TEXAT_LOG_OAK_SIDE); + case 1: return tex_atlas_lookup(TEXAT_LOG_SPRUCE_SIDE); + case 2: return tex_atlas_lookup(TEXAT_LOG_BIRCH_SIDE); } } diff --git a/source/block/block_netherrack.c b/source/block/block_netherrack.c index ac2f975..422edef 100644 --- a/source/block/block_netherrack.c +++ b/source/block/block_netherrack.c @@ -35,7 +35,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { } static uint8_t getTextureIndex(struct block_info* this, enum side side) { - return TEXTURE_INDEX(7, 6); + return tex_atlas_lookup(TEXAT_NETHERRACK); } struct block block_netherrack = { diff --git a/source/block/block_noteblock.c b/source/block/block_noteblock.c index 9fc1dc9..2227402 100644 --- a/source/block/block_noteblock.c +++ b/source/block/block_noteblock.c @@ -35,7 +35,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { } static uint8_t getTextureIndex(struct block_info* this, enum side side) { - return TEXTURE_INDEX(10, 4); + return tex_atlas_lookup(TEXAT_JUKBEBOX_SIDE); } struct block block_noteblock = { diff --git a/source/block/block_obsidian.c b/source/block/block_obsidian.c index 5929367..ed842c2 100644 --- a/source/block/block_obsidian.c +++ b/source/block/block_obsidian.c @@ -35,7 +35,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { } static uint8_t getTextureIndex(struct block_info* this, enum side side) { - return TEXTURE_INDEX(5, 2); + return tex_atlas_lookup(TEXAT_OBSIDIAN); } struct block block_obsidian = { diff --git a/source/block/block_ore.c b/source/block/block_ore.c index 541b453..6bbd121 100644 --- a/source/block/block_ore.c +++ b/source/block/block_ore.c @@ -37,18 +37,18 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { static uint8_t getTextureIndex(struct block_info* this, enum side side) { switch(this->block->type) { case 14: // gold - return TEXTURE_INDEX(0, 2); + return tex_atlas_lookup(TEXAT_ORE_GOLD); case 15: // iron - return TEXTURE_INDEX(1, 2); + return tex_atlas_lookup(TEXAT_ORE_IRON); case 16: // coal - return TEXTURE_INDEX(2, 2); + return tex_atlas_lookup(TEXAT_ORE_COAL); case 21: // lapis - return TEXTURE_INDEX(0, 10); + return tex_atlas_lookup(TEXAT_ORE_LAPIS); case 56: // diamond - return TEXTURE_INDEX(2, 3); + return tex_atlas_lookup(TEXAT_ORE_DIAMOND); case 73: // redstone - case 74: return TEXTURE_INDEX(3, 3); - default: return TEXTURE_INDEX(1, 0); + case 74: return tex_atlas_lookup(TEXAT_ORE_REDSTONE); + default: return tex_atlas_lookup(TEXAT_STONE); } } diff --git a/source/block/block_planks.c b/source/block/block_planks.c index a9ef26d..4e861a2 100644 --- a/source/block/block_planks.c +++ b/source/block/block_planks.c @@ -35,7 +35,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { } static uint8_t getTextureIndex(struct block_info* this, enum side side) { - return TEXTURE_INDEX(4, 0); + return tex_atlas_lookup(TEXAT_PLANKS); } struct block block_planks = { diff --git a/source/block/block_pressure_plate.c b/source/block/block_pressure_plate.c index ec82213..d7e5e19 100644 --- a/source/block/block_pressure_plate.c +++ b/source/block/block_pressure_plate.c @@ -44,11 +44,11 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { } static uint8_t getTextureIndex1(struct block_info* this, enum side side) { - return TEXTURE_INDEX(1, 0); + return tex_atlas_lookup(TEXAT_STONE); } static uint8_t getTextureIndex2(struct block_info* this, enum side side) { - return TEXTURE_INDEX(4, 0); + return tex_atlas_lookup(TEXAT_PLANKS); } struct block block_stone_pressure_plate = { diff --git a/source/block/block_pumpkin.c b/source/block/block_pumpkin.c index c7b25a0..f5a77f5 100644 --- a/source/block/block_pumpkin.c +++ b/source/block/block_pumpkin.c @@ -34,29 +34,55 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { return face_occlusion_full(); } -static uint8_t getTextureIndex(struct block_info* this, enum side side) { +static uint8_t getTextureIndex1(struct block_info* this, enum side side) { switch(side) { case SIDE_FRONT: if(this->block->metadata == 2) - return TEXTURE_INDEX(7, 7); + return tex_atlas_lookup(TEXAT_PUMPKIN_FRONT); else - return TEXTURE_INDEX(6, 7); + return tex_atlas_lookup(TEXAT_PUMPKIN_SIDE); case SIDE_BACK: if(this->block->metadata == 0) - return TEXTURE_INDEX(7, 7); + return tex_atlas_lookup(TEXAT_PUMPKIN_FRONT); else - return TEXTURE_INDEX(6, 7); + return tex_atlas_lookup(TEXAT_PUMPKIN_SIDE); case SIDE_RIGHT: if(this->block->metadata == 3) - return TEXTURE_INDEX(7, 7); + return tex_atlas_lookup(TEXAT_PUMPKIN_FRONT); else - return TEXTURE_INDEX(6, 7); + return tex_atlas_lookup(TEXAT_PUMPKIN_SIDE); case SIDE_LEFT: if(this->block->metadata == 1) - return TEXTURE_INDEX(7, 7); + return tex_atlas_lookup(TEXAT_PUMPKIN_FRONT); else - return TEXTURE_INDEX(6, 7); - default: return TEXTURE_INDEX(6, 6); + return tex_atlas_lookup(TEXAT_PUMPKIN_SIDE); + default: return tex_atlas_lookup(TEXAT_PUMPKIN_TOP); + } +} + +static uint8_t getTextureIndex2(struct block_info* this, enum side side) { + switch(side) { + case SIDE_FRONT: + if(this->block->metadata == 2) + return tex_atlas_lookup(TEXAT_PUMPKIN_FRONT_LIT); + else + return tex_atlas_lookup(TEXAT_PUMPKIN_SIDE); + case SIDE_BACK: + if(this->block->metadata == 0) + return tex_atlas_lookup(TEXAT_PUMPKIN_FRONT_LIT); + else + return tex_atlas_lookup(TEXAT_PUMPKIN_SIDE); + case SIDE_RIGHT: + if(this->block->metadata == 3) + return tex_atlas_lookup(TEXAT_PUMPKIN_FRONT_LIT); + else + return tex_atlas_lookup(TEXAT_PUMPKIN_SIDE); + case SIDE_LEFT: + if(this->block->metadata == 1) + return tex_atlas_lookup(TEXAT_PUMPKIN_FRONT_LIT); + else + return tex_atlas_lookup(TEXAT_PUMPKIN_SIDE); + default: return tex_atlas_lookup(TEXAT_PUMPKIN_TOP); } } @@ -65,7 +91,7 @@ struct block block_pumpkin = { .getSideMask = getSideMask, .getBoundingBox = getBoundingBox, .getMaterial = getMaterial, - .getTextureIndex = getTextureIndex, + .getTextureIndex = getTextureIndex1, .transparent = false, .renderBlock = render_block_full, .renderBlockAlways = NULL, @@ -89,7 +115,7 @@ struct block block_pumpkin_lit = { .getSideMask = getSideMask, .getBoundingBox = getBoundingBox, .getMaterial = getMaterial, - .getTextureIndex = getTextureIndex, + .getTextureIndex = getTextureIndex2, .transparent = false, .renderBlock = render_block_full, .renderBlockAlways = NULL, diff --git a/source/block/block_rail.c b/source/block/block_rail.c index fc48a01..41bb71e 100644 --- a/source/block/block_rail.c +++ b/source/block/block_rail.c @@ -40,17 +40,18 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { } static uint8_t getTextureIndex1(struct block_info* this, enum side side) { - return (this->block->metadata < 6) ? TEXTURE_INDEX(0, 8) : - TEXTURE_INDEX(0, 7); + return (this->block->metadata < 6) ? tex_atlas_lookup(TEXAT_RAIL) : + tex_atlas_lookup(TEXAT_RAIL_CURVED); } static uint8_t getTextureIndex2(struct block_info* this, enum side side) { - return (this->block->metadata & 0x8) ? TEXTURE_INDEX(3, 11) : - TEXTURE_INDEX(3, 10); + return (this->block->metadata & 0x8) ? + tex_atlas_lookup(TEXAT_RAIL_POWERED_ON) : + tex_atlas_lookup(TEXAT_RAIL_POWERED_OFF); } static uint8_t getTextureIndex3(struct block_info* this, enum side side) { - return TEXTURE_INDEX(3, 12); + return tex_atlas_lookup(TEXAT_RAIL_DETECTOR); } struct block block_rail = { diff --git a/source/block/block_red_mushroom.c b/source/block/block_red_mushroom.c index 34be9b5..76f040a 100644 --- a/source/block/block_red_mushroom.c +++ b/source/block/block_red_mushroom.c @@ -35,7 +35,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { } static uint8_t getTextureIndex(struct block_info* this, enum side side) { - return TEXTURE_INDEX(12, 1); + return tex_atlas_lookup(TEXAT_MUSHROOM_RED); } struct block block_red_mushroom = { diff --git a/source/block/block_reed.c b/source/block/block_reed.c index 1344e6d..17f0ef8 100644 --- a/source/block/block_reed.c +++ b/source/block/block_reed.c @@ -35,7 +35,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { } static uint8_t getTextureIndex(struct block_info* this, enum side side) { - return TEXTURE_INDEX(9, 4); + return tex_atlas_lookup(TEXAT_REED); } struct block block_reed = { diff --git a/source/block/block_rose.c b/source/block/block_rose.c index ffb86a0..774b93d 100644 --- a/source/block/block_rose.c +++ b/source/block/block_rose.c @@ -35,7 +35,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { } static uint8_t getTextureIndex(struct block_info* this, enum side side) { - return TEXTURE_INDEX(12, 0); + return tex_atlas_lookup(TEXAT_ROSE); } struct block block_rose = { diff --git a/source/block/block_sand.c b/source/block/block_sand.c index 97091c1..b09fc89 100644 --- a/source/block/block_sand.c +++ b/source/block/block_sand.c @@ -35,11 +35,11 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { } static uint8_t getTextureIndex1(struct block_info* this, enum side side) { - return TEXTURE_INDEX(2, 1); + return tex_atlas_lookup(TEXAT_SAND); } static uint8_t getTextureIndex2(struct block_info* this, enum side side) { - return TEXTURE_INDEX(8, 6); + return tex_atlas_lookup(TEXAT_SOULSAND); } struct block block_sand = { diff --git a/source/block/block_sandstone.c b/source/block/block_sandstone.c index 9de0a19..1ed95d0 100644 --- a/source/block/block_sandstone.c +++ b/source/block/block_sandstone.c @@ -36,9 +36,9 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { 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); + case SIDE_TOP: return tex_atlas_lookup(TEXAT_SANDSTONE_TOP); + case SIDE_BOTTOM: return tex_atlas_lookup(TEXAT_SANDSTONE_BOTTOM); + default: return tex_atlas_lookup(TEXAT_SANDSTONE_SIDE); } } diff --git a/source/block/block_sapling.c b/source/block/block_sapling.c index e365b28..ce34493 100644 --- a/source/block/block_sapling.c +++ b/source/block/block_sapling.c @@ -36,9 +36,9 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { 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); + case 1: return tex_atlas_lookup(TEXAT_SAPLING_SPRUCE); + case 2: return tex_atlas_lookup(TEXAT_SAPLING_BIRCH); + default: return tex_atlas_lookup(TEXAT_SAPLING_OAK); } } diff --git a/source/block/block_slab.c b/source/block/block_slab.c index d20a6ef..4e8ee83 100644 --- a/source/block/block_slab.c +++ b/source/block/block_slab.c @@ -43,15 +43,16 @@ static uint8_t getTextureIndex(struct block_info* this, enum side side) { default: case 0: return (side == SIDE_TOP || side == SIDE_BOTTOM) ? - TEXTURE_INDEX(6, 0) : - TEXTURE_INDEX(5, 0); + tex_atlas_lookup(TEXAT_SLAB_STONE_TOP) : + tex_atlas_lookup(TEXAT_SLAB_STONE_SIDE); 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); + tex_atlas_lookup(TEXAT_SANDSTONE_TOP) : + ((side == SIDE_BOTTOM) ? + tex_atlas_lookup(TEXAT_SANDSTONE_BOTTOM) : + tex_atlas_lookup(TEXAT_SANDSTONE_SIDE)); + case 2: return tex_atlas_lookup(TEXAT_PLANKS); + case 3: return tex_atlas_lookup(TEXAT_COBBLESTONE); } } diff --git a/source/block/block_snow.c b/source/block/block_snow.c index eea7ea4..d224eae 100644 --- a/source/block/block_snow.c +++ b/source/block/block_snow.c @@ -50,7 +50,7 @@ getSideMask2(struct block_info* this, enum side side, struct block_info* it) { } static uint8_t getTextureIndex(struct block_info* this, enum side side) { - return TEXTURE_INDEX(2, 4); + return tex_atlas_lookup(TEXAT_SNOW); } struct block block_snow = { diff --git a/source/block/block_spawner.c b/source/block/block_spawner.c index 9dbf74d..420df5a 100644 --- a/source/block/block_spawner.c +++ b/source/block/block_spawner.c @@ -35,7 +35,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { } static uint8_t getTextureIndex(struct block_info* this, enum side side) { - return TEXTURE_INDEX(1, 4); + return tex_atlas_lookup(TEXAT_SPAWNER); } struct block block_spawner = { diff --git a/source/block/block_sponge.c b/source/block/block_sponge.c index 2d07dc1..c666567 100644 --- a/source/block/block_sponge.c +++ b/source/block/block_sponge.c @@ -35,7 +35,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { } static uint8_t getTextureIndex(struct block_info* this, enum side side) { - return TEXTURE_INDEX(0, 3); + return tex_atlas_lookup(TEXAT_SPONGE); } struct block block_sponge = { diff --git a/source/block/block_stairs.c b/source/block/block_stairs.c index 042f0fa..2d4eb37 100644 --- a/source/block/block_stairs.c +++ b/source/block/block_stairs.c @@ -98,11 +98,11 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { } static uint8_t getTextureIndex1(struct block_info* this, enum side side) { - return TEXTURE_INDEX(4, 0); + return tex_atlas_lookup(TEXAT_PLANKS); } static uint8_t getTextureIndex2(struct block_info* this, enum side side) { - return TEXTURE_INDEX(0, 1); + return tex_atlas_lookup(TEXAT_COBBLESTONE); } struct block block_wooden_stairs = { diff --git a/source/block/block_stone.c b/source/block/block_stone.c index 2495411..768d3bc 100644 --- a/source/block/block_stone.c +++ b/source/block/block_stone.c @@ -35,7 +35,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { } static uint8_t getTextureIndex(struct block_info* this, enum side side) { - return TEXTURE_INDEX(1, 0); + return tex_atlas_lookup(TEXAT_STONE); } struct block block_stone = { diff --git a/source/block/block_tallgrass.c b/source/block/block_tallgrass.c index 05e96c5..751c33c 100644 --- a/source/block/block_tallgrass.c +++ b/source/block/block_tallgrass.c @@ -36,14 +36,14 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { 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 + case 1: return tex_atlas_lookup(TEXAT_TALLGRASS); // tallgrass + case 2: return tex_atlas_lookup(TEXAT_FERN); // fern + default: return tex_atlas_lookup(TEXAT_DEADBUSH); // deadbush } } static uint8_t getTextureIndex2(struct block_info* this, enum side side) { - return TEXTURE_INDEX(6, 3); // deadbush + return tex_atlas_lookup(TEXAT_DEADBUSH); // deadbush } struct block block_tallgrass = { diff --git a/source/block/block_tnt.c b/source/block/block_tnt.c index d0bdbef..1be069c 100644 --- a/source/block/block_tnt.c +++ b/source/block/block_tnt.c @@ -36,9 +36,9 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { static uint8_t getTextureIndex(struct block_info* this, enum side side) { switch(side) { - case SIDE_TOP: return TEXTURE_INDEX(9, 0); - case SIDE_BOTTOM: return TEXTURE_INDEX(10, 0); - default: return TEXTURE_INDEX(8, 0); + case SIDE_TOP: return tex_atlas_lookup(TEXAT_TNT_TOP); + case SIDE_BOTTOM: return tex_atlas_lookup(TEXAT_TNT_BOTTOM); + default: return tex_atlas_lookup(TEXAT_TNT_SIDE); } } diff --git a/source/block/block_torch.c b/source/block/block_torch.c index f973c1a..b2b2123 100644 --- a/source/block/block_torch.c +++ b/source/block/block_torch.c @@ -44,15 +44,15 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { } static uint8_t getTextureIndex1(struct block_info* this, enum side side) { - return TEXTURE_INDEX(0, 5); + return tex_atlas_lookup(TEXAT_TORCH); } static uint8_t getTextureIndex2(struct block_info* this, enum side side) { - return TEXTURE_INDEX(3, 7); + return tex_atlas_lookup(TEXAT_REDSTONE_TORCH); } static uint8_t getTextureIndex3(struct block_info* this, enum side side) { - return TEXTURE_INDEX(3, 6); + return tex_atlas_lookup(TEXAT_REDSTONE_TORCH_LIT); } struct block block_torch = { diff --git a/source/block/block_trapdoor.c b/source/block/block_trapdoor.c index cbf8928..5d21bd3 100644 --- a/source/block/block_trapdoor.c +++ b/source/block/block_trapdoor.c @@ -69,7 +69,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { } static uint8_t getTextureIndex(struct block_info* this, enum side side) { - return TEXTURE_INDEX(8, 3); + return tex_atlas_lookup(TEXAT_TRAPDOOR); } struct block block_trapdoor = { diff --git a/source/block/block_wool.c b/source/block/block_wool.c index b2fd923..bd0f295 100644 --- a/source/block/block_wool.c +++ b/source/block/block_wool.c @@ -35,16 +35,24 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { } static uint8_t getTextureIndex(struct block_info* this, enum side side) { - if(this->block->metadata >= 9) - return TEXTURE_INDEX(1, 13 + 9 - this->block->metadata); - - if(this->block->metadata == 8) - return TEXTURE_INDEX(3, 13); - - if(this->block->metadata >= 1) - return TEXTURE_INDEX(2, 13 + 1 - this->block->metadata); - - return TEXTURE_INDEX(0, 4); + switch(this->block->metadata) { + case 0: return tex_atlas_lookup(TEXAT_WOOL_0); + case 1: return tex_atlas_lookup(TEXAT_WOOL_1); + case 2: return tex_atlas_lookup(TEXAT_WOOL_2); + case 3: return tex_atlas_lookup(TEXAT_WOOL_3); + case 4: return tex_atlas_lookup(TEXAT_WOOL_4); + case 5: return tex_atlas_lookup(TEXAT_WOOL_5); + case 6: return tex_atlas_lookup(TEXAT_WOOL_6); + case 7: return tex_atlas_lookup(TEXAT_WOOL_7); + case 8: return tex_atlas_lookup(TEXAT_WOOL_8); + case 9: return tex_atlas_lookup(TEXAT_WOOL_9); + case 10: return tex_atlas_lookup(TEXAT_WOOL_10); + case 11: return tex_atlas_lookup(TEXAT_WOOL_11); + case 12: return tex_atlas_lookup(TEXAT_WOOL_12); + case 13: return tex_atlas_lookup(TEXAT_WOOL_13); + case 14: return tex_atlas_lookup(TEXAT_WOOL_14); + case 15: return tex_atlas_lookup(TEXAT_WOOL_15); + } } struct block block_wool = { diff --git a/source/block/block_workbench.c b/source/block/block_workbench.c index 3b817b8..e0e1476 100644 --- a/source/block/block_workbench.c +++ b/source/block/block_workbench.c @@ -37,12 +37,12 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) { 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_LEFT: return tex_atlas_lookup(TEXAT_WORKBENCH_SIDE_2); case SIDE_RIGHT: - case SIDE_BACK: return TEXTURE_INDEX(11, 3); - case SIDE_TOP: return TEXTURE_INDEX(11, 2); + case SIDE_BACK: return tex_atlas_lookup(TEXAT_WORKBENCH_SIDE_1); + case SIDE_TOP: return tex_atlas_lookup(TEXAT_WORKBENCH_TOP); default: - case SIDE_BOTTOM: return TEXTURE_INDEX(4, 0); + case SIDE_BOTTOM: return tex_atlas_lookup(TEXAT_PLANKS); } } diff --git a/source/block/blocks.h b/source/block/blocks.h index 04965f7..296e163 100755 --- a/source/block/blocks.h +++ b/source/block/blocks.h @@ -23,13 +23,10 @@ #include #include +#include "../graphics/texture_atlas.h" #include "../item/items.h" #include "../platform/displaylist.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, diff --git a/source/graphics/gui_util.c b/source/graphics/gui_util.c index 8d171e2..bee1a27 100644 --- a/source/graphics/gui_util.c +++ b/source/graphics/gui_util.c @@ -21,6 +21,8 @@ #include "../platform/gfx.h" #include "gui_util.h" +#include "render_block.h" +#include "texture_atlas.h" int gutil_control_icon(int x, enum gutil_control_icon icon, char* str) { gfx_bind_texture(TEXTURE_GUI); @@ -69,9 +71,14 @@ void gutil_bg() { int cx = (gfx_width() + scale - 1) / scale; int cy = (gfx_height() + scale - 1) / scale; + uint8_t tex = tex_atlas_lookup(TEXAT_DIRT); + + uint8_t s = TEX_OFFSET(TEXTURE_X(tex)); + uint8_t t = TEX_OFFSET(TEXTURE_Y(tex)); + for(int y = 0; y < cy; y++) { for(int x = 0; x < cx; x++) { - gutil_texquad_col(x * scale, y * scale, 39, 3, 16, 16, scale, scale, + gutil_texquad_col(x * scale, y * scale, s, t, 16, 16, scale, scale, 0x40, 0x40, 0x40, 0xFF); } } diff --git a/source/graphics/texture_atlas.c b/source/graphics/texture_atlas.c new file mode 100644 index 0000000..d57fa68 --- /dev/null +++ b/source/graphics/texture_atlas.c @@ -0,0 +1,323 @@ +/* + Copyright (c) 2023 ByteBit/xtreme8000 + + This file is part of CavEX. + + CavEX is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + CavEX is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with CavEX. If not, see . +*/ + +#include + +#include "../platform/texture.h" +#include "texture_atlas.h" + +static uint8_t global_atlas[TEXAT_MAX]; + +static int clamp_n(int x, int n) { + if(x < 0) + return 0; + if(x > n - 1) + return n - 1; + return x; +} + +void tex_atlas_reg(dict_atlas_src_t atlas, enum tex_atlas_entry name, uint8_t x, + uint8_t y) { + dict_atlas_src_push_back(atlas, + (struct texture_entry) { + .name = name, + .x = x, + .y = y, + .bg.enable = false, + .colorize.enable = false, + }); +} + +void tex_atlas_reg_col(dict_atlas_src_t atlas, enum tex_atlas_entry name, + uint8_t x, uint8_t y, uint8_t r, uint8_t g, uint8_t b) { + dict_atlas_src_push_back(atlas, + (struct texture_entry) { + .name = name, + .x = x, + .y = y, + .bg.enable = false, + .colorize.enable = true, + .colorize.r = r, + .colorize.g = g, + .colorize.b = b, + }); +} + +void tex_atlas_reg_grass(dict_atlas_src_t atlas, enum tex_atlas_entry name, + uint8_t x, uint8_t y, uint8_t r, uint8_t g, uint8_t b, + uint8_t bg_x, uint8_t bg_y) { + dict_atlas_src_push_back(atlas, + (struct texture_entry) { + .name = name, + .x = x, + .y = y, + .bg.enable = true, + .bg.x = bg_x, + .bg.y = bg_y, + .colorize.enable = true, + .colorize.r = r, + .colorize.g = g, + .colorize.b = b, + }); +} + +void* tex_atlas_compute(dict_atlas_src_t atlas, uint8_t* atlas_dst, + uint8_t* image, size_t width, size_t height) { + assert(image && width >= 256 && width == height); + + int tile_size = width / 16; + int border_scale = width / 256; + + uint8_t* output = malloc(width * height * 4); + + if(!output) + return NULL; + + memset(output, 255, width * height * 4); + + dict_atlas_src_it_t it; + dict_atlas_src_it(it, atlas); + + int current = 0; + + while(!dict_atlas_src_end_p(it)) { + struct texture_entry* e = dict_atlas_src_ref(it); + + size_t current_x = (current % 14) * (tile_size + 2 * border_scale) + + 3 * border_scale; + size_t current_y = (current / 14) * (tile_size + 2 * border_scale) + + 3 * border_scale; + + for(int y = -border_scale; y < tile_size + border_scale; y++) { + for(int x = -border_scale; x < tile_size + border_scale; x++) { + uint8_t* src_col = image + + ((clamp_n(x, tile_size) + e->x * tile_size) + + (clamp_n(y, tile_size) + e->y * tile_size) * width) + * 4; + uint8_t* dst_col + = output + ((current_x + x) + (current_y + y) * width) * 4; + + if(e->colorize.enable) { + dst_col[0] = src_col[0] * e->colorize.r / 255; + dst_col[1] = src_col[1] * e->colorize.g / 255; + dst_col[2] = src_col[2] * e->colorize.b / 255; + dst_col[3] = src_col[3]; + } else { + for(size_t k = 0; k < 4; k++) + dst_col[k] = src_col[k]; + } + + if(e->bg.enable && dst_col[3] < 128) { + uint8_t* src_col2 = image + + ((clamp_n(x, tile_size) + e->bg.x * tile_size) + + (clamp_n(y, tile_size) + e->bg.y * tile_size) + * width) + * 4; + for(size_t k = 0; k < 4; k++) + dst_col[k] = src_col2[k]; + } + } + } + + atlas_dst[e->name] = TEXTURE_INDEX(current % 14, current / 14); + + current++; + dict_atlas_src_next(it); + } + + return output; +} + +uint8_t tex_atlas_lookup(enum tex_atlas_entry name) { + return global_atlas[name]; +} + +void* tex_atlas_block(const char* filename, size_t* width, size_t* height) { + dict_atlas_src_t atlas; + dict_atlas_src_init(atlas); + + tex_atlas_reg(atlas, TEXAT_STONE, 1, 0); + tex_atlas_reg(atlas, TEXAT_DIRT, 2, 0); + tex_atlas_reg(atlas, TEXAT_PLANKS, 4, 0); + tex_atlas_reg(atlas, TEXAT_SLAB_STONE_SIDE, 5, 0); + tex_atlas_reg(atlas, TEXAT_SLAB_STONE_TOP, 6, 0); + tex_atlas_reg(atlas, TEXAT_BRICKS, 7, 0); + tex_atlas_reg(atlas, TEXAT_TNT_SIDE, 8, 0); + tex_atlas_reg(atlas, TEXAT_TNT_TOP, 9, 0); + tex_atlas_reg(atlas, TEXAT_TNT_BOTTOM, 10, 0); + tex_atlas_reg(atlas, TEXAT_COBWEB, 11, 0); + tex_atlas_reg(atlas, TEXAT_ROSE, 12, 0); + tex_atlas_reg(atlas, TEXAT_DANDELION, 13, 0); + tex_atlas_reg(atlas, TEXAT_SAPLING_OAK, 15, 0); + + tex_atlas_reg(atlas, TEXAT_COBBLESTONE, 0, 1); + tex_atlas_reg(atlas, TEXAT_BEDROCK, 1, 1); + tex_atlas_reg(atlas, TEXAT_SAND, 2, 1); + tex_atlas_reg(atlas, TEXAT_GRAVEL, 3, 1); + tex_atlas_reg(atlas, TEXAT_LOG_OAK_SIDE, 4, 1); + tex_atlas_reg(atlas, TEXAT_LOG_OAK_TOP, 5, 1); + tex_atlas_reg(atlas, TEXAT_CAST_BLOCK_IRON, 6, 1); + tex_atlas_reg(atlas, TEXAT_CAST_BLOCK_GOLD, 7, 1); + tex_atlas_reg(atlas, TEXAT_CAST_BLOCK_DIAMOND, 8, 1); + tex_atlas_reg(atlas, TEXAT_CHEST_TOP, 9, 1); + tex_atlas_reg(atlas, TEXAT_CHEST_SIDE, 10, 1); + tex_atlas_reg(atlas, TEXAT_CHEST_FRONT_SINGLE, 11, 1); + tex_atlas_reg(atlas, TEXAT_MUSHROOM_RED, 12, 1); + tex_atlas_reg(atlas, TEXAT_MUSHROOM_BROWN, 13, 1); + + tex_atlas_reg(atlas, TEXAT_ORE_GOLD, 0, 2); + tex_atlas_reg(atlas, TEXAT_ORE_IRON, 1, 2); + tex_atlas_reg(atlas, TEXAT_ORE_COAL, 2, 2); + tex_atlas_reg(atlas, TEXAT_BOOKSHELF, 3, 2); + tex_atlas_reg(atlas, TEXAT_COBBLESTONE_MOSSY, 4, 2); + tex_atlas_reg(atlas, TEXAT_OBSIDIAN, 5, 2); + tex_atlas_reg(atlas, TEXAT_CHEST_FRONT_1, 9, 2); + tex_atlas_reg(atlas, TEXAT_CHEST_FRONT_2, 10, 2); + tex_atlas_reg(atlas, TEXAT_WORKBENCH_TOP, 11, 2); + tex_atlas_reg(atlas, TEXAT_FURNACE_FRONT, 12, 2); + tex_atlas_reg(atlas, TEXAT_FURNACE_SIDE, 13, 2); + tex_atlas_reg(atlas, TEXAT_DISPENSER_FRONT, 14, 2); + + tex_atlas_reg(atlas, TEXAT_SPONGE, 0, 3); + tex_atlas_reg(atlas, TEXAT_GLASS, 1, 3); + tex_atlas_reg(atlas, TEXAT_ORE_DIAMOND, 2, 3); + tex_atlas_reg(atlas, TEXAT_ORE_REDSTONE, 3, 3); + tex_atlas_reg_col(atlas, TEXAT_LEAVES_BIRCH, 4, 3, 128, 167, 85); + tex_atlas_reg(atlas, TEXAT_DEADBUSH, 7, 3); + tex_atlas_reg(atlas, TEXAT_CHEST_BACK_1, 9, 3); + tex_atlas_reg(atlas, TEXAT_CHEST_BACK_2, 10, 3); + tex_atlas_reg(atlas, TEXAT_WORKBENCH_SIDE_1, 11, 3); + tex_atlas_reg(atlas, TEXAT_WORKBENCH_SIDE_2, 12, 3); + tex_atlas_reg(atlas, TEXAT_FURNACE_FRONT_LIT, 13, 3); + tex_atlas_reg(atlas, TEXAT_FURNACE_TOP, 14, 3); + tex_atlas_reg(atlas, TEXAT_SAPLING_SPRUCE, 15, 3); + + tex_atlas_reg(atlas, TEXAT_SPAWNER, 1, 4); + tex_atlas_reg(atlas, TEXAT_SNOW, 2, 4); + tex_atlas_reg(atlas, TEXAT_GRASS_SIDE_SNOW, 4, 4); + tex_atlas_reg(atlas, TEXAT_CACTUS_TOP, 5, 4); + tex_atlas_reg(atlas, TEXAT_CACTUS_SIDE, 6, 4); + tex_atlas_reg(atlas, TEXAT_CACTUS_BOTTOM, 7, 4); + tex_atlas_reg(atlas, TEXAT_CLAY, 8, 4); + tex_atlas_reg(atlas, TEXAT_REED, 9, 4); + tex_atlas_reg(atlas, TEXAT_JUKBEBOX_SIDE, 10, 4); + tex_atlas_reg(atlas, TEXAT_JUKBEBOX_TOP, 11, 4); + tex_atlas_reg(atlas, TEXAT_SAPLING_BIRCH, 15, 4); + + tex_atlas_reg(atlas, TEXAT_TORCH, 0, 5); + tex_atlas_reg(atlas, TEXAT_DOOR_WOOD_TOP, 1, 5); + tex_atlas_reg(atlas, TEXAT_DOOR_IRON_TOP, 2, 5); + tex_atlas_reg(atlas, TEXAT_LADDER, 3, 5); + tex_atlas_reg(atlas, TEXAT_TRAPDOOR, 4, 5); + tex_atlas_reg(atlas, TEXAT_FARMLAND_WET, 6, 5); + tex_atlas_reg(atlas, TEXAT_FARMLAND_DRY, 7, 5); + tex_atlas_reg(atlas, TEXAT_CROPS_0, 8, 5); + tex_atlas_reg(atlas, TEXAT_CROPS_1, 9, 5); + tex_atlas_reg(atlas, TEXAT_CROPS_2, 10, 5); + tex_atlas_reg(atlas, TEXAT_CROPS_3, 11, 5); + tex_atlas_reg(atlas, TEXAT_CROPS_4, 12, 5); + tex_atlas_reg(atlas, TEXAT_CROPS_5, 13, 5); + tex_atlas_reg(atlas, TEXAT_CROPS_6, 14, 5); + tex_atlas_reg(atlas, TEXAT_CROPS_7, 15, 5); + + // tex_atlas_reg(atlas, "lever", 0, 6); + tex_atlas_reg(atlas, TEXAT_DOOR_WOOD_BOTTOM, 1, 6); + tex_atlas_reg(atlas, TEXAT_DOOR_IRON_BOTTOM, 2, 6); + tex_atlas_reg(atlas, TEXAT_REDSTONE_TORCH_LIT, 3, 6); + tex_atlas_reg(atlas, TEXAT_PUMPKIN_TOP, 6, 6); + tex_atlas_reg(atlas, TEXAT_NETHERRACK, 7, 6); + tex_atlas_reg(atlas, TEXAT_SOULSAND, 8, 6); + tex_atlas_reg(atlas, TEXAT_GLOWSTONE, 9, 6); + /*tex_atlas_reg(atlas, "piston_front_sticky", 10, 6); + tex_atlas_reg(atlas, "piston_front", 11, 6); + tex_atlas_reg(atlas, "piston_side", 12, 6); + tex_atlas_reg(atlas, "piston_back", 13, 6); + tex_atlas_reg(atlas, "piston_inner", 14, 6);*/ + + tex_atlas_reg(atlas, TEXAT_RAIL_CURVED, 0, 7); + tex_atlas_reg(atlas, TEXAT_REDSTONE_TORCH, 3, 7); + tex_atlas_reg(atlas, TEXAT_LOG_SPRUCE_SIDE, 4, 7); + tex_atlas_reg(atlas, TEXAT_LOG_BIRCH_SIDE, 5, 7); + tex_atlas_reg(atlas, TEXAT_PUMPKIN_SIDE, 6, 7); + tex_atlas_reg(atlas, TEXAT_PUMPKIN_FRONT, 7, 7); + tex_atlas_reg(atlas, TEXAT_PUMPKIN_FRONT_LIT, 8, 7); + tex_atlas_reg(atlas, TEXAT_CAKE_TOP, 9, 7); + tex_atlas_reg(atlas, TEXAT_CAKE_SIDE, 10, 7); + tex_atlas_reg(atlas, TEXAT_CAKE_SIDE_CUT, 11, 7); + tex_atlas_reg(atlas, TEXAT_CAKE_BOTTOM, 12, 7); + + tex_atlas_reg(atlas, TEXAT_RAIL, 0, 8); + // tex_atlas_reg(atlas, "repeater_off", 3, 8); + tex_atlas_reg_col(atlas, TEXAT_LEAVES_SPRUCE, 4, 8, 97, 153, 97); + tex_atlas_reg(atlas, TEXAT_BED_TOP_1, 6, 8); + tex_atlas_reg(atlas, TEXAT_BED_TOP_2, 7, 8); + + tex_atlas_reg(atlas, TEXAT_CAST_BLOCK_LAPIS, 0, 9); + // tex_atlas_reg(atlas, "repeater_on", 3, 9); + tex_atlas_reg(atlas, TEXAT_BED_BACK, 5, 9); + tex_atlas_reg(atlas, TEXAT_BED_SIDE_1, 6, 9); + tex_atlas_reg(atlas, TEXAT_BED_SIDE_2, 7, 9); + tex_atlas_reg(atlas, TEXAT_BED_FRONT, 8, 9); + + tex_atlas_reg(atlas, TEXAT_ORE_LAPIS, 0, 10); + tex_atlas_reg(atlas, TEXAT_RAIL_POWERED_OFF, 3, 10); + /*tex_atlas_reg_col(atlas, "redstone_intersect", 4, 10, 252, 49, 0); + tex_atlas_reg_col(atlas, "redstone_wire", 5, 10, 252, 49, 0);*/ + + tex_atlas_reg(atlas, TEXAT_SANDSTONE_TOP, 0, 11); + tex_atlas_reg(atlas, TEXAT_RAIL_POWERED_ON, 3, 11); + + tex_atlas_reg(atlas, TEXAT_SANDSTONE_SIDE, 0, 12); + tex_atlas_reg(atlas, TEXAT_RAIL_DETECTOR, 3, 12); + + tex_atlas_reg(atlas, TEXAT_SANDSTONE_BOTTOM, 0, 13); + + tex_atlas_reg(atlas, TEXAT_WOOL_0, 0, 4); + tex_atlas_reg(atlas, TEXAT_WOOL_1, 2, 13); + tex_atlas_reg(atlas, TEXAT_WOOL_2, 2, 12); + tex_atlas_reg(atlas, TEXAT_WOOL_3, 2, 11); + tex_atlas_reg(atlas, TEXAT_WOOL_4, 2, 10); + tex_atlas_reg(atlas, TEXAT_WOOL_5, 2, 9); + tex_atlas_reg(atlas, TEXAT_WOOL_6, 2, 8); + tex_atlas_reg(atlas, TEXAT_WOOL_7, 2, 7); + tex_atlas_reg(atlas, TEXAT_WOOL_8, 1, 14); + tex_atlas_reg(atlas, TEXAT_WOOL_9, 1, 13); + tex_atlas_reg(atlas, TEXAT_WOOL_10, 1, 12); + tex_atlas_reg(atlas, TEXAT_WOOL_11, 1, 11); + tex_atlas_reg(atlas, TEXAT_WOOL_12, 1, 10); + tex_atlas_reg(atlas, TEXAT_WOOL_13, 1, 9); + tex_atlas_reg(atlas, TEXAT_WOOL_14, 1, 8); + tex_atlas_reg(atlas, TEXAT_WOOL_15, 1, 7); + + tex_atlas_reg_col(atlas, TEXAT_GRASS_TOP, 0, 0, 110, 198, 63); + tex_atlas_reg_grass(atlas, TEXAT_GRASS_SIDE, 6, 2, 110, 198, 63, 3, 0); + tex_atlas_reg_col(atlas, TEXAT_TALLGRASS, 7, 2, 110, 198, 63); + tex_atlas_reg_col(atlas, TEXAT_LEAVES_OAK, 4, 3, 75, 182, 15); + tex_atlas_reg_col(atlas, TEXAT_FERN, 8, 3, 110, 198, 63); + + memset(global_atlas, 0, sizeof(global_atlas)); + + uint8_t* image = tex_read(filename, width, height); + void* output + = tex_atlas_compute(atlas, global_atlas, image, *width, *height); + dict_atlas_src_clear(atlas); + free(image); + + return output; +} diff --git a/source/graphics/texture_atlas.h b/source/graphics/texture_atlas.h new file mode 100644 index 0000000..a792e0f --- /dev/null +++ b/source/graphics/texture_atlas.h @@ -0,0 +1,197 @@ +/* + Copyright (c) 2023 ByteBit/xtreme8000 + + This file is part of CavEX. + + CavEX is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + CavEX is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with CavEX. If not, see . +*/ + +#ifndef TEXTURE_ATLAS_H +#define TEXTURE_ATLAS_H + +#include + +#include + +enum tex_atlas_entry { + TEXAT_STONE, + TEXAT_DIRT, + TEXAT_PLANKS, + TEXAT_SLAB_STONE_SIDE, + TEXAT_SLAB_STONE_TOP, + TEXAT_BRICKS, + TEXAT_TNT_SIDE, + TEXAT_TNT_TOP, + TEXAT_TNT_BOTTOM, + TEXAT_COBWEB, + TEXAT_ROSE, + TEXAT_DANDELION, + TEXAT_SAPLING_OAK, + TEXAT_COBBLESTONE, + TEXAT_BEDROCK, + TEXAT_SAND, + TEXAT_GRAVEL, + TEXAT_LOG_OAK_SIDE, + TEXAT_LOG_OAK_TOP, + TEXAT_CAST_BLOCK_IRON, + TEXAT_CAST_BLOCK_GOLD, + TEXAT_CAST_BLOCK_DIAMOND, + TEXAT_CHEST_TOP, + TEXAT_CHEST_SIDE, + TEXAT_CHEST_FRONT_SINGLE, + TEXAT_MUSHROOM_RED, + TEXAT_MUSHROOM_BROWN, + TEXAT_ORE_GOLD, + TEXAT_ORE_IRON, + TEXAT_ORE_COAL, + TEXAT_BOOKSHELF, + TEXAT_COBBLESTONE_MOSSY, + TEXAT_OBSIDIAN, + TEXAT_CHEST_FRONT_1, + TEXAT_CHEST_FRONT_2, + TEXAT_WORKBENCH_TOP, + TEXAT_FURNACE_FRONT, + TEXAT_FURNACE_SIDE, + TEXAT_DISPENSER_FRONT, + TEXAT_SPONGE, + TEXAT_GLASS, + TEXAT_ORE_DIAMOND, + TEXAT_ORE_REDSTONE, + TEXAT_LEAVES_BIRCH, + TEXAT_DEADBUSH, + TEXAT_CHEST_BACK_1, + TEXAT_CHEST_BACK_2, + TEXAT_WORKBENCH_SIDE_1, + TEXAT_WORKBENCH_SIDE_2, + TEXAT_FURNACE_FRONT_LIT, + TEXAT_FURNACE_TOP, + TEXAT_SAPLING_SPRUCE, + TEXAT_SPAWNER, + TEXAT_SNOW, + TEXAT_GRASS_SIDE_SNOW, + TEXAT_CACTUS_TOP, + TEXAT_CACTUS_SIDE, + TEXAT_CACTUS_BOTTOM, + TEXAT_CLAY, + TEXAT_REED, + TEXAT_JUKBEBOX_SIDE, + TEXAT_JUKBEBOX_TOP, + TEXAT_SAPLING_BIRCH, + TEXAT_TORCH, + TEXAT_DOOR_WOOD_TOP, + TEXAT_DOOR_IRON_TOP, + TEXAT_LADDER, + TEXAT_TRAPDOOR, + TEXAT_FARMLAND_WET, + TEXAT_FARMLAND_DRY, + TEXAT_CROPS_0, + TEXAT_CROPS_1, + TEXAT_CROPS_2, + TEXAT_CROPS_3, + TEXAT_CROPS_4, + TEXAT_CROPS_5, + TEXAT_CROPS_6, + TEXAT_CROPS_7, + TEXAT_DOOR_WOOD_BOTTOM, + TEXAT_DOOR_IRON_BOTTOM, + TEXAT_REDSTONE_TORCH_LIT, + TEXAT_PUMPKIN_TOP, + TEXAT_NETHERRACK, + TEXAT_SOULSAND, + TEXAT_GLOWSTONE, + TEXAT_RAIL_CURVED, + TEXAT_REDSTONE_TORCH, + TEXAT_LOG_SPRUCE_SIDE, + TEXAT_LOG_BIRCH_SIDE, + TEXAT_PUMPKIN_SIDE, + TEXAT_PUMPKIN_FRONT, + TEXAT_PUMPKIN_FRONT_LIT, + TEXAT_CAKE_TOP, + TEXAT_CAKE_SIDE, + TEXAT_CAKE_SIDE_CUT, + TEXAT_CAKE_BOTTOM, + TEXAT_RAIL, + TEXAT_LEAVES_SPRUCE, + TEXAT_BED_TOP_1, + TEXAT_BED_TOP_2, + TEXAT_CAST_BLOCK_LAPIS, + TEXAT_BED_BACK, + TEXAT_BED_SIDE_1, + TEXAT_BED_SIDE_2, + TEXAT_BED_FRONT, + TEXAT_ORE_LAPIS, + TEXAT_RAIL_POWERED_OFF, + TEXAT_SANDSTONE_TOP, + TEXAT_RAIL_POWERED_ON, + TEXAT_SANDSTONE_SIDE, + TEXAT_RAIL_DETECTOR, + TEXAT_SANDSTONE_BOTTOM, + TEXAT_WOOL_0, + TEXAT_WOOL_1, + TEXAT_WOOL_2, + TEXAT_WOOL_3, + TEXAT_WOOL_4, + TEXAT_WOOL_5, + TEXAT_WOOL_6, + TEXAT_WOOL_7, + TEXAT_WOOL_8, + TEXAT_WOOL_9, + TEXAT_WOOL_10, + TEXAT_WOOL_11, + TEXAT_WOOL_12, + TEXAT_WOOL_13, + TEXAT_WOOL_14, + TEXAT_WOOL_15, + TEXAT_GRASS_TOP, + TEXAT_GRASS_SIDE, + TEXAT_TALLGRASS, + TEXAT_LEAVES_OAK, + TEXAT_FERN, + + TEXAT_MAX, +}; + +struct texture_entry { + enum tex_atlas_entry name; + uint8_t x : 4, y : 4; + struct { + bool enable; + uint8_t r, g, b; + } colorize; + struct { + bool enable; + uint8_t x : 4, y : 4; + } bg; +}; + +ARRAY_DEF(dict_atlas_src, struct texture_entry, M_POD_OPLIST) + +#define TEXTURE_INDEX(x, y) (((y)*14) + (x)) +#define TEXTURE_X(idx) ((idx) % 14) +#define TEXTURE_Y(idx) ((idx) / 14) + +void tex_atlas_reg(dict_atlas_src_t atlas, enum tex_atlas_entry name, uint8_t x, + uint8_t y); +void tex_atlas_reg_col(dict_atlas_src_t atlas, enum tex_atlas_entry name, + uint8_t x, uint8_t y, uint8_t r, uint8_t g, uint8_t b); +void tex_atlas_reg_grass(dict_atlas_src_t atlas, enum tex_atlas_entry name, + uint8_t x, uint8_t y, uint8_t r, uint8_t g, uint8_t b, + uint8_t bg_x, uint8_t bg_y); +void* tex_atlas_compute(dict_atlas_src_t atlas, uint8_t* atlas_dst, + uint8_t* image, size_t width, size_t height); + +uint8_t tex_atlas_lookup(enum tex_atlas_entry name); +void* tex_atlas_block(const char* filename, size_t* width, size_t* height); + +#endif diff --git a/source/platform/pc/gfx.c b/source/platform/pc/gfx.c index 8b73e05..e5e2c1c 100644 --- a/source/platform/pc/gfx.c +++ b/source/platform/pc/gfx.c @@ -25,61 +25,45 @@ #include #include "../../game/game_state.h" +#include "../../graphics/texture_atlas.h" #include "../../lodepng/lodepng.h" #include "../../util.h" #include "../gfx.h" #include "../input.h" +#include "../texture.h" static GLuint textures[8]; -static GLuint load_tex(const char* filename, bool nearest) { - unsigned width, height; - unsigned char* img; - if(lodepng_decode32_file(&img, &width, &height, filename)) - printf("error loading texture %s\n", filename); - - GLuint tex; - glGenTextures(1, &tex); - glBindTexture(GL_TEXTURE_2D, tex); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, - GL_UNSIGNED_BYTE, img); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, - nearest ? GL_NEAREST : GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, - nearest ? GL_NEAREST : GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glBindTexture(GL_TEXTURE_2D, 0); - - free(img); - - return tex; -} - static void gfx_load_textures() { - textures[0] = load_tex("terrain.png", true); - textures[1] = load_tex("default.png", true); - textures[2] = load_tex("anim.png", true); - textures[3] = load_tex("gui.png", true); - textures[4] = load_tex("gui_2.png", true); - textures[5] = load_tex("items.png", true); + glGenTextures(6, textures); + + size_t w, h; + void* output = tex_atlas_block("assets/terrain.png", &w, &h); + if(output) { + tex_gfx_load(output, w, h, TEX_FMT_RGBA16, textures[0], false); + free(output); + } + + tex_gfx_load_file("assets/default.png", TEX_FMT_I8, textures[1], false); + tex_gfx_load_file("assets/anim.png", TEX_FMT_RGBA32, textures[2], false); + tex_gfx_load_file("assets/gui.png", TEX_FMT_IA4, textures[3], false); + tex_gfx_load_file("assets/gui_2.png", TEX_FMT_RGBA16, textures[4], false); + tex_gfx_load_file("assets/items.png", TEX_FMT_RGBA16, textures[5], false); } -static void testtest(GLuint shader) { - GLint isCompiled = 0; - glGetShaderiv(shader, GL_COMPILE_STATUS, &isCompiled); - if(isCompiled == GL_FALSE) { - GLint maxLength = 0; - glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &maxLength); +static void shader_error(GLuint shader) { + GLint is_compiled = 0; + glGetShaderiv(shader, GL_COMPILE_STATUS, &is_compiled); - // The maxLength includes the NULL character - char log[maxLength]; - glGetShaderInfoLog(shader, maxLength, &maxLength, log); + if(!is_compiled) { + GLint length = 0; + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length); + + char log[length]; + glGetShaderInfoLog(shader, length, &length, log); printf("%s\n", log); - // Provide the infolog in whatever manor you deem best. - // Exit with failure. - glDeleteShader(shader); // Don't leak the shader. + glDeleteShader(shader); } } @@ -87,12 +71,12 @@ static GLuint create_shader(const char* vertex, const char* fragment) { GLuint v = glCreateShader(GL_VERTEX_SHADER); glShaderSource(v, 1, (const GLchar* const*)&vertex, NULL); glCompileShader(v); - testtest(v); + shader_error(v); GLuint f = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(f, 1, (const GLchar* const*)&fragment, NULL); glCompileShader(f); - testtest(f); + shader_error(f); GLuint program = glCreateProgram(); glAttachShader(program, v); @@ -208,9 +192,9 @@ void gfx_setup() { printf("Renderer: %s\n", glGetString(GL_RENDERER)); printf("Version: %s\n", glGetString(GL_VERSION)); - void* vertex = file_read("vertex.shader"); + void* vertex = file_read("assets/vertex.shader"); assert(vertex); - void* fragment = file_read("fragment.shader"); + void* fragment = file_read("assets/fragment.shader"); assert(fragment); shader_prog = create_shader(vertex, fragment); diff --git a/source/platform/pc/texture.c b/source/platform/pc/texture.c new file mode 100644 index 0000000..5e5d820 --- /dev/null +++ b/source/platform/pc/texture.c @@ -0,0 +1,36 @@ +/* + Copyright (c) 2023 ByteBit/xtreme8000 + + This file is part of CavEX. + + CavEX is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + CavEX is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with CavEX. If not, see . +*/ + +#include + +void tex_gfx_load(void* img, size_t width, size_t height, enum tex_format type, + int slot, bool linear) { + assert(img && width > 0 && height > 0); + + glBindTexture(GL_TEXTURE_2D, slot); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, + GL_UNSIGNED_BYTE, img); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + linear ? GL_LINEAR : GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, + linear ? GL_LINEAR : GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glBindTexture(GL_TEXTURE_2D, 0); +} diff --git a/source/platform/texture.c b/source/platform/texture.c new file mode 100644 index 0000000..582946a --- /dev/null +++ b/source/platform/texture.c @@ -0,0 +1,61 @@ +/* + Copyright (c) 2023 ByteBit/xtreme8000 + + This file is part of CavEX. + + CavEX is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + CavEX is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with CavEX. If not, see . +*/ + +#include +#include + +#include "../lodepng/lodepng.h" +#include "texture.h" + +uint8_t* tex_read(const char* filename, size_t* width, size_t* height) { + assert(filename && width && height); + + uint8_t* img; + unsigned w, h; + if(lodepng_decode32_file(&img, &w, &h, filename)) + return NULL; + + *width = w; + *height = h; + + return img; +} + +void tex_gfx_load_file(const char* filename, enum tex_format type, int slot, + bool linear) { + assert(filename); + + size_t width, height; + void* img = tex_read(filename, &width, &height); + + if(!img) + return; + + tex_gfx_load(img, width, height, type, slot, linear); + + free(img); +} + +#ifdef PLATFORM_WII +#include "wii/texture.c" +#endif + +#ifdef PLATFORM_PC +#include "pc/texture.c" +#endif diff --git a/source/platform/texture.h b/source/platform/texture.h new file mode 100644 index 0000000..a730592 --- /dev/null +++ b/source/platform/texture.h @@ -0,0 +1,41 @@ +/* + Copyright (c) 2023 ByteBit/xtreme8000 + + This file is part of CavEX. + + CavEX is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + CavEX is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with CavEX. If not, see . +*/ + +#ifndef TEXTURE_H +#define TEXTURE_H + +#include +#include +#include + +enum tex_format { + TEX_FMT_RGBA16, + TEX_FMT_RGBA32, + TEX_FMT_I8, + TEX_FMT_IA4, +}; + +uint8_t* tex_read(const char* filename, size_t* width, size_t* height); + +void tex_gfx_load(void* img, size_t width, size_t height, enum tex_format type, + int slot, bool linear); +void tex_gfx_load_file(const char* filename, enum tex_format type, int slot, + bool linear); + +#endif diff --git a/source/platform/wii/gfx.c b/source/platform/wii/gfx.c index 466cee3..28db346 100644 --- a/source/platform/wii/gfx.c +++ b/source/platform/wii/gfx.c @@ -24,11 +24,10 @@ #include #include +#include "../../graphics/texture_atlas.h" #include "../../util.h" #include "../gfx.h" - -#include "textures.h" -#include "textures_tpl.h" +#include "../texture.h" #define FIFO_SIZE (256 * 1024) @@ -82,47 +81,44 @@ static void copy_buffers(u32 cnt) { } } +#define distance_2d(x1, y1, x2, y2) \ + (((x1) - (x2)) * ((x1) - (x2)) + ((y1) - (y2)) * ((y1) - (y2))) + +static void texture_fog(uint8_t* img, size_t size) { + for(size_t y = 0; y < size; y++) { + for(size_t x = 0; x < size; x++) { + float d = (sqrt(distance_2d(size / 2.0F, size / 2.0F, x + 0.5F, + y + 0.5F)) + - (size / 2.0F - 9.0F)) + / 8.0F; + + uint8_t* pixel = img + (x + y * size) * 4; + pixel[0] = pixel[1] = pixel[2] + = roundf(glm_clamp(d * 255.0F, 0.0F, 255.0F)); + pixel[3] = 255; + } + } +} + static void gfx_load_textures() { - GXTexObj terrain, font, anim, gui, gui2, items, fog; - TPLFile spriteTPL; - TPL_OpenTPLFromMemory(&spriteTPL, (void*)textures_tpl, textures_tpl_size); - TPL_GetTexture(&spriteTPL, texture_terrain, &terrain); - GX_InitTexObjFilterMode(&terrain, GX_NEAR, GX_NEAR); - GX_InitTexObjMaxAniso(&terrain, GX_ANISO_1); - GX_LoadTexObj(&terrain, GX_TEXMAP0); + size_t w, h; + void* output = tex_atlas_block("assets/terrain.png", &w, &h); + if(output) { + tex_gfx_load(output, w, h, TEX_FMT_RGBA16, GX_TEXMAP0, false); + free(output); + } - TPL_GetTexture(&spriteTPL, texture_font, &font); - GX_InitTexObjFilterMode(&font, GX_NEAR, GX_NEAR); - GX_InitTexObjMaxAniso(&font, GX_ANISO_1); - GX_LoadTexObj(&font, GX_TEXMAP1); + tex_gfx_load_file("assets/default.png", TEX_FMT_I8, GX_TEXMAP1, false); + tex_gfx_load_file("assets/anim.png", TEX_FMT_RGBA32, GX_TEXMAP2, false); + tex_gfx_load_file("assets/gui.png", TEX_FMT_IA4, GX_TEXMAP3, false); + tex_gfx_load_file("assets/gui_2.png", TEX_FMT_RGBA16, GX_TEXMAP4, false); + tex_gfx_load_file("assets/items.png", TEX_FMT_RGBA16, GX_TEXMAP5, false); - TPL_GetTexture(&spriteTPL, texture_anim, &anim); - GX_InitTexObjFilterMode(&anim, GX_NEAR, GX_NEAR); - GX_InitTexObjMaxAniso(&anim, GX_ANISO_1); - GX_LoadTexObj(&anim, GX_TEXMAP2); - - TPL_GetTexture(&spriteTPL, texture_gui, &gui); - GX_InitTexObjFilterMode(&gui, GX_NEAR, GX_NEAR); - GX_InitTexObjMaxAniso(&gui, GX_ANISO_1); - GX_LoadTexObj(&gui, GX_TEXMAP3); - - TPL_GetTexture(&spriteTPL, texture_gui2, &gui2); - GX_InitTexObjFilterMode(&gui2, GX_NEAR, GX_NEAR); - GX_InitTexObjMaxAniso(&gui2, GX_ANISO_1); - GX_LoadTexObj(&gui2, GX_TEXMAP4); - - TPL_GetTexture(&spriteTPL, texture_items, &items); - GX_InitTexObjFilterMode(&items, GX_NEAR, GX_NEAR); - GX_InitTexObjMaxAniso(&items, GX_ANISO_1); - GX_LoadTexObj(&items, GX_TEXMAP5); - - TPL_GetTexture(&spriteTPL, texture_fog, &fog); - GX_InitTexObjFilterMode(&fog, GX_LINEAR, GX_LINEAR); - GX_InitTexObjMaxAniso(&fog, GX_ANISO_1); - GX_InitTexObjWrapMode(&fog, GX_CLAMP, GX_CLAMP); - GX_LoadTexObj(&fog, GX_TEXMAP7); - - TPL_CloseTPLFile(&spriteTPL); + size_t fog_size = 128; + uint8_t* fog = malloc(fog_size * fog_size * 4); + texture_fog(fog, fog_size); + tex_gfx_load(fog, fog_size, fog_size, TEX_FMT_I8, GX_TEXMAP6, true); + free(fog); } int gfx_width() { @@ -389,7 +385,7 @@ void gfx_fog(bool enable) { if(enable) { GX_SetTevOp(GX_TEVSTAGE1, GX_DECAL); - GX_SetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD1, GX_TEXMAP7, GX_COLOR0A0); + GX_SetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD1, GX_TEXMAP6, GX_COLOR0A0); GX_SetTevColorIn(GX_TEVSTAGE1, GX_CC_CPREV, GX_CC_C0, GX_CC_TEXA, GX_CC_ZERO); } diff --git a/source/platform/wii/texture.c b/source/platform/wii/texture.c new file mode 100644 index 0000000..d678273 --- /dev/null +++ b/source/platform/wii/texture.c @@ -0,0 +1,187 @@ +/* + Copyright (c) 2023 ByteBit/xtreme8000 + + This file is part of CavEX. + + CavEX is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + CavEX is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with CavEX. If not, see . +*/ + +#include +#include +#include + +#define rgba16(r, g, b, a) \ + (((int)(a) << 12) | ((int)(r) << 8) | ((int)(g) << 4) | (int)(b)) +#define rgb16(r, g, b) (0x8000 | ((int)(r) << 10) | ((int)(g) << 5) | (int)(b)) +#define xy16(x, y) (((int)(x) << 8) | (int)(y)) +#define ia8(i, a) (((int)(a) << 4) | (int)(i)) + +static void* tex_conv_rgb32(uint8_t* image, size_t width, size_t height) { + assert(image && (width % 4) == 0 && (height % 4) == 0); + uint16_t* output = memalign(32, width * height * sizeof(uint16_t) * 2); + + if(!output) + return NULL; + + size_t output_idx = 0; + + for(size_t y = 0; y < height; y += 4) { + for(size_t x = 0; x < width; x += 4) { + for(size_t by = 0; by < 4; by++) { + for(size_t bx = 0; bx < 4; bx++) { + uint8_t* col = image + (x + bx + (y + by) * width) * 4; + output[output_idx++] = xy16(col[3], col[0]); + } + } + + for(size_t by = 0; by < 4; by++) { + for(size_t bx = 0; bx < 4; bx++) { + uint8_t* col = image + (x + bx + (y + by) * width) * 4; + output[output_idx++] = xy16(col[1], col[2]); + } + } + } + } + + DCFlushRange(output, width * height * sizeof(uint16_t) * 2); + + return output; +} + +static void* tex_conv_rgb16(uint8_t* image, size_t width, size_t height) { + assert(image && (width % 4) == 0 && (height % 4) == 0); + uint16_t* output = memalign(32, width * height * sizeof(uint16_t)); + + if(!output) + return NULL; + + size_t output_idx = 0; + + for(size_t y = 0; y < height; y += 4) { + for(size_t x = 0; x < width; x += 4) { + for(size_t by = 0; by < 4; by++) { + for(size_t bx = 0; bx < 4; bx++) { + uint8_t* col = image + (x + bx + (y + by) * width) * 4; + int alpha = col[3] >> 5; + + if(alpha < 7) { + output[output_idx++] = rgba16(col[0] >> 4, col[1] >> 4, + col[2] >> 4, alpha); + } else { + output[output_idx++] + = rgb16(col[0] >> 3, col[1] >> 3, col[2] >> 3); + } + } + } + } + } + + DCFlushRange(output, width * height * sizeof(uint16_t)); + + return output; +} + +static void* tex_conv_i8(uint8_t* image, size_t width, size_t height) { + assert(image && (width % 8) == 0 && (height % 4) == 0); + uint8_t* output = memalign(32, width * height * sizeof(uint8_t)); + + if(!output) + return NULL; + + size_t output_idx = 0; + + for(size_t y = 0; y < height; y += 4) { + for(size_t x = 0; x < width; x += 8) { + for(size_t by = 0; by < 4; by++) { + for(size_t bx = 0; bx < 8; bx++) { + uint8_t* col = image + (x + bx + (y + by) * width) * 4; + output[output_idx++] + = ((int)col[0] + (int)col[1] + (int)col[2]) / 3; + } + } + } + } + + DCFlushRange(output, width * height * sizeof(uint8_t)); + + return output; +} + +static void* tex_conv_ia4(uint8_t* image, size_t width, size_t height) { + assert(image && (width % 8) == 0 && (height % 4) == 0); + uint8_t* output = memalign(32, width * height * sizeof(uint8_t)); + + if(!output) + return NULL; + + size_t output_idx = 0; + + for(size_t y = 0; y < height; y += 4) { + for(size_t x = 0; x < width; x += 8) { + for(size_t by = 0; by < 4; by++) { + for(size_t bx = 0; bx < 8; bx++) { + uint8_t* col = image + (x + bx + (y + by) * width) * 4; + output[output_idx++] = ia8( + (((int)col[0] + (int)col[1] + (int)col[2]) / 3) >> 4, + col[3] >> 4); + } + } + } + } + + DCFlushRange(output, width * height * sizeof(uint8_t)); + + return output; +} + +void tex_gfx_load(void* img, size_t width, size_t height, enum tex_format type, + int slot, bool linear) { + assert(img && width > 0 && height > 0); + + void* output = NULL; + uint8_t fmt; + + switch(type) { + case TEX_FMT_RGBA32: + output = tex_conv_rgb32(img, width, height); + fmt = GX_TF_RGBA8; + break; + case TEX_FMT_RGBA16: + output = tex_conv_rgb16(img, width, height); + fmt = GX_TF_RGB5A3; + break; + case TEX_FMT_I8: + output = tex_conv_i8(img, width, height); + fmt = GX_TF_I8; + break; + case TEX_FMT_IA4: + output = tex_conv_ia4(img, width, height); + fmt = GX_TF_IA4; + break; + default: return; + } + + if(output) { + GXTexObj obj; + GX_InitTexObj(&obj, output, width, height, fmt, GX_CLAMP, GX_CLAMP, + GX_FALSE); + GX_InitTexObjMaxAniso(&obj, GX_ANISO_1); + GX_InitTexObjFilterMode(&obj, linear ? GX_LINEAR : GX_NEAR, + linear ? GX_LINEAR : GX_NEAR); + GX_LoadTexObj(&obj, slot); + + // TODO: data needed by gpu, must not free + // free(output); + } +}