Added game files
This commit is contained in:
parent
704637d45e
commit
340b9b6900
31 changed files with 5427 additions and 0 deletions
207
Makefile
Normal file
207
Makefile
Normal file
|
@ -0,0 +1,207 @@
|
|||
#---------------------------------------------------------------------------------
|
||||
.SUFFIXES:
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
ifeq ($(strip $(DEVKITARM)),)
|
||||
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
|
||||
endif
|
||||
|
||||
TOPDIR ?= $(CURDIR)
|
||||
include $(DEVKITARM)/3ds_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
|
||||
# DATA is a list of directories containing data files
|
||||
# INCLUDES is a list of directories containing header files
|
||||
#
|
||||
# NO_SMDH: if set to anything, no SMDH file is generated.
|
||||
# APP_TITLE is the name of the app stored in the SMDH file (Optional)
|
||||
# APP_DESCRIPTION is the description of the app stored in the SMDH file (Optional)
|
||||
# APP_AUTHOR is the author of the app stored in the SMDH file (Optional)
|
||||
# ICON is the filename of the icon (.png), relative to the project folder.
|
||||
# If not set, it attempts to use one of the following (in this order):
|
||||
# - <Project name>.png
|
||||
# - icon.png
|
||||
# - <libctru folder>/default_icon.png
|
||||
#---------------------------------------------------------------------------------
|
||||
TARGET := Minicraft3DS
|
||||
BUILD := build
|
||||
SOURCES := source
|
||||
DATA := data
|
||||
INCLUDES := include
|
||||
|
||||
APP_TITLE := Test
|
||||
APP_DESCRIPTION := ???
|
||||
APP_AUTHOR := Davideesk
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# options for code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard
|
||||
|
||||
CFLAGS := -g -Wall -O2 -mword-relocations \
|
||||
-fomit-frame-pointer -ffast-math \
|
||||
$(ARCH)
|
||||
|
||||
CFLAGS += $(INCLUDE) -DARM11 -D_3DS
|
||||
|
||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
|
||||
|
||||
ASFLAGS := -g $(ARCH)
|
||||
LDFLAGS = -specs=3dsx.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||
|
||||
LIBS := -lsfil -lpng -ljpeg -lz -lsf2d -lctru -lm
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
# include and lib
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBDIRS := $(CTRULIB) $(PORTLIBS)
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# 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 TOPDIR := $(CURDIR)
|
||||
|
||||
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
|
||||
|
||||
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||
|
||||
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
||||
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
||||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# 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)) \
|
||||
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
||||
|
||||
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
||||
-I$(CURDIR)/$(BUILD)
|
||||
|
||||
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
|
||||
|
||||
ifeq ($(strip $(ICON)),)
|
||||
icons := $(wildcard *.png)
|
||||
ifneq (,$(findstring $(TARGET).png,$(icons)))
|
||||
export APP_ICON := $(TOPDIR)/$(TARGET).png
|
||||
else
|
||||
ifneq (,$(findstring icon.png,$(icons)))
|
||||
export APP_ICON := $(TOPDIR)/icon.png
|
||||
endif
|
||||
endif
|
||||
else
|
||||
export APP_ICON := $(TOPDIR)/$(ICON)
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(NO_SMDH)),)
|
||||
export _3DSXFLAGS += --smdh=$(CURDIR)/$(TARGET).smdh
|
||||
endif
|
||||
|
||||
.PHONY: $(BUILD) clean all
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
all: $(BUILD)
|
||||
|
||||
$(BUILD):
|
||||
@[ -d $@ ] || mkdir -p $@
|
||||
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
clean:
|
||||
@echo clean ...
|
||||
@rm -fr $(BUILD) $(TARGET).3dsx $(OUTPUT).smdh $(TARGET).elf $(TARGET)-strip.elf $(TARGET).cia $(TARGET).3ds
|
||||
#---------------------------------------------------------------------------------
|
||||
$(TARGET)-strip.elf: $(BUILD)
|
||||
@$(STRIP) $(TARGET).elf -o $(TARGET)-strip.elf
|
||||
#---------------------------------------------------------------------------------
|
||||
cci: $(TARGET)-strip.elf
|
||||
@makerom -f cci -rsf resources/$(TARGET).rsf -target d -exefslogo -elf $(TARGET)-strip.elf -o $(TARGET).3ds
|
||||
@echo "built ... sfil_sample.3ds"
|
||||
#---------------------------------------------------------------------------------
|
||||
cia: $(TARGET)-strip.elf
|
||||
@makerom -f cia -o $(TARGET).cia -elf $(TARGET)-strip.elf -rsf resources/$(TARGET).rsf -exefslogo -target t
|
||||
@echo "built ... sfil_sample.cia"
|
||||
#---------------------------------------------------------------------------------
|
||||
send: $(BUILD)
|
||||
@3dslink $(TARGET).3dsx
|
||||
#---------------------------------------------------------------------------------
|
||||
run: $(BUILD)
|
||||
@citra $(TARGET).3dsx
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
|
||||
DEPENDS := $(OFILES:.o=.d)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# main targets
|
||||
#---------------------------------------------------------------------------------
|
||||
ifeq ($(strip $(NO_SMDH)),)
|
||||
$(OUTPUT).3dsx : $(OUTPUT).elf $(OUTPUT).smdh
|
||||
else
|
||||
$(OUTPUT).3dsx : $(OUTPUT).elf
|
||||
endif
|
||||
|
||||
$(OUTPUT).elf : $(OFILES)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# you need a rule like this for each extension you use as binary data
|
||||
#---------------------------------------------------------------------------------
|
||||
%.bin.o : %.bin
|
||||
#---------------------------------------------------------------------------------
|
||||
@echo $(notdir $<)
|
||||
@$(bin2o)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
%.jpeg.o: %.jpeg
|
||||
#---------------------------------------------------------------------------------
|
||||
@echo $(notdir $<)
|
||||
@$(bin2o)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
%.png.o : %.png
|
||||
#---------------------------------------------------------------------------------
|
||||
@echo $(notdir $<)
|
||||
@$(bin2o)
|
||||
|
||||
# WARNING: This is not the right way to do this! TODO: Do it right!
|
||||
#---------------------------------------------------------------------------------
|
||||
%.vsh.o : %.vsh
|
||||
#---------------------------------------------------------------------------------
|
||||
@echo $(notdir $<)
|
||||
@python $(AEMSTRO)/aemstro_as.py $< ../$(notdir $<).shbin
|
||||
@bin2s ../$(notdir $<).shbin | $(PREFIX)as -o $@
|
||||
@echo "extern const u8" `(echo $(notdir $<).shbin | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"_end[];" > `(echo $(notdir $<).shbin | tr . _)`.h
|
||||
@echo "extern const u8" `(echo $(notdir $<).shbin | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"[];" >> `(echo $(notdir $<).shbin | tr . _)`.h
|
||||
@echo "extern const u32" `(echo $(notdir $<).shbin | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(notdir $<).shbin | tr . _)`.h
|
||||
@rm ../$(notdir $<).shbin
|
||||
|
||||
-include $(DEPENDS)
|
||||
|
||||
#---------------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------------
|
BIN
data/Font.png
Normal file
BIN
data/Font.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.9 KiB |
BIN
data/icons2.png
Normal file
BIN
data/icons2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
BIN
resources/bossdeath.raw
Normal file
BIN
resources/bossdeath.raw
Normal file
Binary file not shown.
BIN
resources/craft.raw
Normal file
BIN
resources/craft.raw
Normal file
Binary file not shown.
BIN
resources/death.raw
Normal file
BIN
resources/death.raw
Normal file
Binary file not shown.
BIN
resources/monsterhurt.raw
Normal file
BIN
resources/monsterhurt.raw
Normal file
Binary file not shown.
BIN
resources/pickup.raw
Normal file
BIN
resources/pickup.raw
Normal file
Binary file not shown.
BIN
resources/playerhurt.raw
Normal file
BIN
resources/playerhurt.raw
Normal file
Binary file not shown.
BIN
resources/test.raw
Normal file
BIN
resources/test.raw
Normal file
Binary file not shown.
136
source/Crafting.c
Normal file
136
source/Crafting.c
Normal file
|
@ -0,0 +1,136 @@
|
|||
#include "Crafting.h"
|
||||
|
||||
void checkCanCraftRecipes(RecipeManager * rm, Inventory * inv){
|
||||
int i, j;
|
||||
for(i = 0; i < rm->size; i++){
|
||||
rm->recipes[i].canCraft = true;
|
||||
for(j = 0; j < rm->recipes[i].numOfCosts; j++){
|
||||
if(countItemInv(rm->recipes[i].costs[j].costItem,0,inv) < rm->recipes[i].costs[j].costAmount){
|
||||
rm->recipes[i].canCraft = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int compareCanCraft(const void * ra, const void * rb) {
|
||||
Recipe* r1 = (Recipe*)ra;
|
||||
Recipe* r2 = (Recipe*)rb;
|
||||
if (r1->canCraft && !r2->canCraft) return -1;
|
||||
if (!r1->canCraft && r2->canCraft) return 1;
|
||||
return r1->order - r2->order; // Needed for stable sorting.
|
||||
}
|
||||
|
||||
void sortRecipes(RecipeManager * rm){
|
||||
qsort(rm->recipes,rm->size,sizeof(Recipe),compareCanCraft);
|
||||
}
|
||||
|
||||
void deductCost(Cost c, Inventory * inv){
|
||||
Item* item = getItemFromInventory(c.costItem, inv);
|
||||
if(!item->onlyOne){
|
||||
item->countLevel -= c.costAmount;
|
||||
if(item->countLevel < 1) removeItemFromInventory(item->slotNum, inv);
|
||||
} else {
|
||||
removeItemFromInventory(item->slotNum, inv);
|
||||
}
|
||||
}
|
||||
|
||||
bool craftItem(RecipeManager * rm, Recipe* r, Inventory* inv){
|
||||
if(r->canCraft){
|
||||
int i;
|
||||
for(i=0;i<r->numOfCosts;++i) deductCost(r->costs[i], inv);
|
||||
Item item = newItem(r->itemResult,r->itemAmountLevel);
|
||||
|
||||
if(!item.onlyOne && countItemInv(item.id,item.countLevel,inv) > 0){
|
||||
getItemFromInventory(item.id, inv)->countLevel += r->itemAmountLevel;
|
||||
} else{
|
||||
pushItemToInventoryFront(item, inv);
|
||||
}
|
||||
checkCanCraftRecipes(rm, inv);
|
||||
sortRecipes(rm);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Cost newCost(int i, int c){
|
||||
Cost nc;
|
||||
nc.costItem = i;
|
||||
nc.costAmount = c;
|
||||
return nc;
|
||||
}
|
||||
|
||||
u8 curPlace = 0;
|
||||
Recipe defineRecipe(int item, int amountOrLevel, int numArgs, ...){
|
||||
Recipe r;
|
||||
r.itemResult = item;
|
||||
r.itemAmountLevel = amountOrLevel;
|
||||
r.numOfCosts = numArgs;
|
||||
int i;
|
||||
va_list al;
|
||||
numArgs <<= 1; // Did this to get rid of a warning.
|
||||
va_start(al,numArgs);
|
||||
for(i=0;i<r.numOfCosts;++i) r.costs[i] = newCost(va_arg(al,int), va_arg(al,int));
|
||||
va_end(al);
|
||||
r.order = curPlace;
|
||||
curPlace++;
|
||||
return r;
|
||||
}
|
||||
|
||||
void initRecipes(){
|
||||
|
||||
curPlace = 0;
|
||||
workbenchRecipes.size = 16;
|
||||
workbenchRecipes.recipes = (Recipe*)malloc(sizeof(Recipe) * (workbenchRecipes.size));
|
||||
workbenchRecipes.recipes[0] = defineRecipe(ITEM_WORKBENCH,1,1,ITEM_WOOD,20);
|
||||
workbenchRecipes.recipes[1] = defineRecipe(ITEM_FURNACE,1,1,ITEM_STONE,20);
|
||||
workbenchRecipes.recipes[2] = defineRecipe(ITEM_OVEN,1,1,ITEM_STONE,20);
|
||||
workbenchRecipes.recipes[3] = defineRecipe(ITEM_CHEST,1,1,ITEM_WOOD,20);
|
||||
workbenchRecipes.recipes[4] = defineRecipe(ITEM_ANVIL,1,1,ITEM_IRONINGOT,5);
|
||||
workbenchRecipes.recipes[5] = defineRecipe(ITEM_LANTERN,1,3,ITEM_WOOD,5,ITEM_SLIME,10,ITEM_GLASS,4);
|
||||
workbenchRecipes.recipes[6] = defineRecipe(TOOL_SWORD,0,1,ITEM_WOOD,5);
|
||||
workbenchRecipes.recipes[7] = defineRecipe(TOOL_AXE,0,1,ITEM_WOOD,5);
|
||||
workbenchRecipes.recipes[8] = defineRecipe(TOOL_HOE,0,1,ITEM_WOOD,5);
|
||||
workbenchRecipes.recipes[9] = defineRecipe(TOOL_PICKAXE,0,1,ITEM_WOOD,5);
|
||||
workbenchRecipes.recipes[10] = defineRecipe(TOOL_SHOVEL,0,1,ITEM_WOOD,5);
|
||||
workbenchRecipes.recipes[11] = defineRecipe(TOOL_SWORD,1,2,ITEM_WOOD,5,ITEM_STONE,5);
|
||||
workbenchRecipes.recipes[12] = defineRecipe(TOOL_AXE,1,2,ITEM_WOOD,5,ITEM_STONE,5);
|
||||
workbenchRecipes.recipes[13] = defineRecipe(TOOL_HOE,1,2,ITEM_WOOD,5,ITEM_STONE,5);
|
||||
workbenchRecipes.recipes[14] = defineRecipe(TOOL_PICKAXE,1,2,ITEM_WOOD,5,ITEM_STONE,5);
|
||||
workbenchRecipes.recipes[15] = defineRecipe(TOOL_SHOVEL,1,2,ITEM_WOOD,5,ITEM_STONE,5);
|
||||
|
||||
anvilRecipes.size = 15;
|
||||
anvilRecipes.recipes = (Recipe*)malloc(sizeof(Recipe) * (anvilRecipes.size));
|
||||
anvilRecipes.recipes[0] = defineRecipe(TOOL_SWORD,2,2,ITEM_WOOD,5,ITEM_IRONINGOT,5);
|
||||
anvilRecipes.recipes[1] = defineRecipe(TOOL_AXE,2,2,ITEM_WOOD,5,ITEM_IRONINGOT,5);
|
||||
anvilRecipes.recipes[2] = defineRecipe(TOOL_HOE,2,2,ITEM_WOOD,5,ITEM_IRONINGOT,5);
|
||||
anvilRecipes.recipes[3] = defineRecipe(TOOL_PICKAXE,2,2,ITEM_WOOD,5,ITEM_IRONINGOT,5);
|
||||
anvilRecipes.recipes[4] = defineRecipe(TOOL_SHOVEL,2,2,ITEM_WOOD,5,ITEM_IRONINGOT,5);
|
||||
anvilRecipes.recipes[5] = defineRecipe(TOOL_SWORD,3,2,ITEM_WOOD,5,ITEM_GOLDINGOT,5);
|
||||
anvilRecipes.recipes[6] = defineRecipe(TOOL_AXE,3,2,ITEM_WOOD,5,ITEM_GOLDINGOT,5);
|
||||
anvilRecipes.recipes[7] = defineRecipe(TOOL_HOE,3,2,ITEM_WOOD,5,ITEM_GOLDINGOT,5);
|
||||
anvilRecipes.recipes[8] = defineRecipe(TOOL_PICKAXE,3,2,ITEM_WOOD,5,ITEM_GOLDINGOT,5);
|
||||
anvilRecipes.recipes[9] = defineRecipe(TOOL_SHOVEL,3,2,ITEM_WOOD,5,ITEM_GOLDINGOT,5);
|
||||
anvilRecipes.recipes[10] = defineRecipe(TOOL_SWORD,4,2,ITEM_WOOD,5,ITEM_GEM,50);
|
||||
anvilRecipes.recipes[11] = defineRecipe(TOOL_AXE,4,2,ITEM_WOOD,5,ITEM_GEM,50);
|
||||
anvilRecipes.recipes[12] = defineRecipe(TOOL_HOE,4,2,ITEM_WOOD,5,ITEM_GEM,50);
|
||||
anvilRecipes.recipes[13] = defineRecipe(TOOL_PICKAXE,4,2,ITEM_WOOD,5,ITEM_GEM,50);
|
||||
anvilRecipes.recipes[14] = defineRecipe(TOOL_SHOVEL,4,2,ITEM_WOOD,5,ITEM_GEM,50);
|
||||
|
||||
furnaceRecipes.size = 3;
|
||||
furnaceRecipes.recipes = (Recipe*)malloc(sizeof(Recipe) * (furnaceRecipes.size));
|
||||
furnaceRecipes.recipes[0] = defineRecipe(ITEM_IRONINGOT,1,2,ITEM_IRONORE,4,ITEM_COAL,1);
|
||||
furnaceRecipes.recipes[1] = defineRecipe(ITEM_GOLDINGOT,1,2,ITEM_GOLDORE,4,ITEM_COAL,1);
|
||||
furnaceRecipes.recipes[2] = defineRecipe(ITEM_GLASS,1,2,ITEM_SAND,4,ITEM_COAL,1);
|
||||
|
||||
ovenRecipes.size = 1;
|
||||
ovenRecipes.recipes = (Recipe*)malloc(sizeof(Recipe) * (ovenRecipes.size));
|
||||
ovenRecipes.recipes[0] = defineRecipe(ITEM_BREAD,1,1,ITEM_WHEAT,4);
|
||||
}
|
||||
|
||||
/* Free up allocated memory */
|
||||
void freeRecipes(){
|
||||
free(workbenchRecipes.recipes);
|
||||
free(ovenRecipes.recipes);
|
||||
free(furnaceRecipes.recipes);
|
||||
free(anvilRecipes.recipes);
|
||||
}
|
35
source/Crafting.h
Normal file
35
source/Crafting.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
#pragma once
|
||||
#include <stdarg.h>
|
||||
#include "Item.h"
|
||||
|
||||
typedef struct {
|
||||
int costItem;
|
||||
int costAmount;
|
||||
} Cost;
|
||||
|
||||
typedef struct {
|
||||
bool canCraft;
|
||||
int itemResult;
|
||||
int itemAmountLevel;
|
||||
s8 numOfCosts;
|
||||
Cost costs[6]; // Up to 6 items for costs
|
||||
u8 order; // Used for stable sorting.
|
||||
} Recipe;
|
||||
|
||||
typedef struct {
|
||||
int size;
|
||||
Recipe * recipes;
|
||||
} RecipeManager;
|
||||
|
||||
|
||||
RecipeManager workbenchRecipes;
|
||||
RecipeManager furnaceRecipes;
|
||||
RecipeManager ovenRecipes;
|
||||
RecipeManager anvilRecipes;
|
||||
|
||||
void checkCanCraftRecipes(RecipeManager * rm, Inventory * inv);
|
||||
void sortRecipes(RecipeManager * rm);
|
||||
bool craftItem(RecipeManager * rm, Recipe* r, Inventory* inv);
|
||||
|
||||
void initRecipes();
|
||||
void freeRecipes();
|
204
source/Entity.c
Normal file
204
source/Entity.c
Normal file
|
@ -0,0 +1,204 @@
|
|||
#include "Entity.h"
|
||||
|
||||
#define PI 3.141592654
|
||||
double gaussrand()
|
||||
{
|
||||
static double U, V;
|
||||
static int phase = 0;
|
||||
double Z;
|
||||
|
||||
if(phase == 0) {
|
||||
U = (rand() + 1.) / (RAND_MAX + 2.);
|
||||
V = rand() / (RAND_MAX + 1.);
|
||||
Z = sqrt(-2 * log(U)) * sin(2 * PI * V);
|
||||
} else
|
||||
Z = sqrt(-2 * log(U)) * cos(2 * PI * V);
|
||||
|
||||
phase = 1 - phase;
|
||||
|
||||
return Z;
|
||||
}
|
||||
|
||||
Entity newItemEntity(Item item, int x, int y, int level){
|
||||
Entity e;
|
||||
e.type = ENTITY_ITEM;
|
||||
e.level = level;
|
||||
e.entityItem.age = 0;
|
||||
e.entityItem.item = item;
|
||||
e.x = x;
|
||||
e.y = y;
|
||||
e.xr = 3;
|
||||
e.yr = 3;
|
||||
e.canPass = false;
|
||||
|
||||
e.entityItem.xx = x;
|
||||
e.entityItem.yy = y;
|
||||
e.entityItem.zz = 2;
|
||||
e.entityItem.xa = gaussrand() * 0.1;
|
||||
e.entityItem.ya = gaussrand() * 0.1;
|
||||
e.entityItem.za = ((float)rand() / RAND_MAX) * 0.45 + 1;
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
void assignInventory(Entity* e){
|
||||
if(eManager.nextInv > 300) return;
|
||||
e->entityFurniture.inv = &eManager.invs[eManager.nextInv];
|
||||
eManager.nextInv++;
|
||||
}
|
||||
|
||||
Entity newFurnitureEntity(int itemID,Inventory * invPtr, int x, int y, int level){
|
||||
Entity e;
|
||||
e.type = ENTITY_FURNITURE;
|
||||
e.level = level;
|
||||
e.x = x;
|
||||
e.y = y;
|
||||
e.xr = 3;
|
||||
e.yr = 3;
|
||||
e.entityFurniture.itemID = itemID;
|
||||
e.canPass = false;
|
||||
if(itemID == ITEM_LANTERN) e.entityFurniture.r = 8;
|
||||
else if(itemID == ITEM_CHEST){
|
||||
if(invPtr == NULL)assignInventory(&e);
|
||||
else e.entityFurniture.inv = invPtr;
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
|
||||
Entity newZombieEntity(int lvl, int x, int y, int level){
|
||||
Entity e;
|
||||
e.type = ENTITY_ZOMBIE;
|
||||
e.level = level;
|
||||
e.x = x;
|
||||
e.y = y;
|
||||
e.hurtTime = 0;
|
||||
e.xKnockback = 0;
|
||||
e.yKnockback = 0;
|
||||
e.zombie.lvl = lvl;
|
||||
e.zombie.health = lvl * lvl * 10;
|
||||
e.zombie.dir = 0;
|
||||
e.xr = 4;
|
||||
e.yr = 3;
|
||||
e.canPass = false;
|
||||
switch(lvl){
|
||||
case 2: e.zombie.color = 0xCC8282FF; break;
|
||||
case 3: e.zombie.color = 0xEFEFEFFF; break;
|
||||
case 4: e.zombie.color = 0x6262AAFF; break;
|
||||
default: e.zombie.color = 0x95DB95FF; break;
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
Entity newSlimeEntity(int lvl, int x, int y, int level){
|
||||
Entity e;
|
||||
e.type = ENTITY_SLIME;
|
||||
e.level = level;
|
||||
e.x = x;
|
||||
e.y = y;
|
||||
e.hurtTime = 0;
|
||||
e.xKnockback = 0;
|
||||
e.yKnockback = 0;
|
||||
e.slime.lvl = lvl;
|
||||
e.slime.xa = 0;
|
||||
e.slime.ya = 0;
|
||||
e.slime.dir = 0;
|
||||
e.slime.health = lvl * lvl * 5;
|
||||
e.xr = 4;
|
||||
e.yr = 3;
|
||||
e.canPass = false;
|
||||
switch(lvl){
|
||||
case 2: e.slime.color = 0xCC8282FF; break;
|
||||
case 3: e.slime.color = 0xEFEFEFFF; break;
|
||||
case 4: e.slime.color = 0x6262AAFF; break;
|
||||
default: e.slime.color = 0x95DB95FF; break;
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
Entity newAirWizardEntity(int x, int y, int level){
|
||||
Entity e;
|
||||
e.type = ENTITY_AIRWIZARD;
|
||||
e.level = level;
|
||||
e.x = x;
|
||||
e.y = y;
|
||||
e.hurtTime = 0;
|
||||
e.xKnockback = 0;
|
||||
e.yKnockback = 0;
|
||||
e.wizard.dir = 0;
|
||||
e.wizard.health = 2000;
|
||||
e.wizard.attackDelay = 0;
|
||||
e.wizard.attackTime = 0;
|
||||
e.wizard.attackType = 0;
|
||||
e.wizard.xa = 0;
|
||||
e.wizard.ya = 0;
|
||||
e.xr = 4;
|
||||
e.yr = 3;
|
||||
e.canPass = true;
|
||||
return e;
|
||||
}
|
||||
|
||||
Entity newSparkEntity(Entity* parent, float xa, float ya){
|
||||
Entity e;
|
||||
e.type = ENTITY_SPARK;
|
||||
e.spark.age = 0;
|
||||
e.spark.parent = parent;
|
||||
e.spark.xa = xa;
|
||||
e.spark.ya = ya;
|
||||
e.spark.xx = parent->x;
|
||||
e.spark.yy = parent->y;
|
||||
e.xr = 3;
|
||||
e.yr = 3;
|
||||
e.canPass = true;
|
||||
return e;
|
||||
}
|
||||
|
||||
Entity newTextParticleEntity(char * str, u32 color, int x, int y, int level){
|
||||
Entity e;
|
||||
e.type = ENTITY_TEXTPARTICLE;
|
||||
e.level = level;
|
||||
e.textParticle.color = color;
|
||||
e.textParticle.age = 0;
|
||||
e.textParticle.text = (char*)calloc(strlen(str),sizeof(char));
|
||||
strncpy(e.textParticle.text,str,strlen(str));
|
||||
e.x = x;
|
||||
e.y = y;
|
||||
e.canPass = true;
|
||||
e.textParticle.xx = x;
|
||||
e.textParticle.yy = y;
|
||||
e.textParticle.zz = 2;
|
||||
e.textParticle.xa = gaussrand() * 0.3;
|
||||
e.textParticle.ya = gaussrand() * 0.2;
|
||||
e.textParticle.za = ((float)rand() / RAND_MAX) * 0.7 + 2;
|
||||
|
||||
return e;
|
||||
}
|
||||
Entity newSmashParticleEntity(int x, int y, int level){
|
||||
Entity e;
|
||||
e.type = ENTITY_SMASHPARTICLE;
|
||||
e.level = level;
|
||||
e.smashParticle.age = 0;
|
||||
e.x = x;
|
||||
e.y = y;
|
||||
e.canPass = true;
|
||||
playSound(snd_monsterHurt);
|
||||
return e;
|
||||
}
|
||||
|
||||
void addEntityToList(Entity e, EntityManager* em){
|
||||
e.slotNum = em->lastSlot[e.level];
|
||||
em->entities[e.level][em->lastSlot[e.level]] = e;
|
||||
++em->lastSlot[e.level];
|
||||
}
|
||||
|
||||
Entity nullEntity;
|
||||
void removeEntityFromList(Entity * e,int level,EntityManager* em){
|
||||
int i;
|
||||
if(em->entities[level][e->slotNum].type == ENTITY_TEXTPARTICLE) free(em->entities[level][e->slotNum].textParticle.text);
|
||||
for(i = e->slotNum; i < em->lastSlot[level];++i){
|
||||
em->entities[level][i] = em->entities[level][i + 1]; // Move the items down.
|
||||
em->entities[level][i].slotNum = i;
|
||||
}
|
||||
em->lastSlot[level]--;
|
||||
em->entities[level][em->lastSlot[level]] = nullEntity; // Make the last slot null.
|
||||
}
|
170
source/Entity.h
Normal file
170
source/Entity.h
Normal file
|
@ -0,0 +1,170 @@
|
|||
#pragma once
|
||||
#include "Crafting.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
// Entity types
|
||||
#define ENTITY_NULL 0
|
||||
#define ENTITY_ITEM 1
|
||||
#define ENTITY_FURNITURE 2
|
||||
#define ENTITY_ZOMBIE 3
|
||||
#define ENTITY_SLIME 4
|
||||
#define ENTITY_AIRWIZARD 5
|
||||
#define ENTITY_SPARK 6
|
||||
#define ENTITY_TEXTPARTICLE 7
|
||||
#define ENTITY_SMASHPARTICLE 8
|
||||
#define ENTITY_PLAYER 9
|
||||
|
||||
typedef struct Entity Entity;
|
||||
|
||||
typedef struct {
|
||||
s8 ax;
|
||||
s8 ay;
|
||||
u8 dir;
|
||||
s8 health;
|
||||
s8 stamina;
|
||||
s8 staminaRecharge;
|
||||
s8 staminaRechargeDelay;
|
||||
s8 attackTimer;
|
||||
u8 spawnTrigger;
|
||||
bool isDead;
|
||||
bool hasWon;
|
||||
bool hasWonSaved;
|
||||
s8 endTimer;
|
||||
s16 walkDist;
|
||||
bool isCarrying;
|
||||
bool isSwimming;
|
||||
int swimTimer;
|
||||
int score;
|
||||
Inventory* inv;
|
||||
Item* activeItem;
|
||||
} Player;
|
||||
|
||||
|
||||
typedef struct {
|
||||
float xa;
|
||||
float ya;
|
||||
float za;
|
||||
float xx;
|
||||
float yy;
|
||||
float zz;
|
||||
s16 age;
|
||||
Item item;
|
||||
} EntityItem;
|
||||
|
||||
typedef struct {
|
||||
s16 itemID;
|
||||
bool active;
|
||||
s8 r; // light radius for lantern. window select for chests.
|
||||
Inventory* inv; // Points to chest inventory.
|
||||
s16 oSel; // other selection inside the chest inv.
|
||||
} EntityFurniture;
|
||||
|
||||
typedef struct {
|
||||
s8 xa;
|
||||
s8 ya;
|
||||
s16 health;
|
||||
s8 dir;
|
||||
s8 lvl;
|
||||
s8 randWalkTime;
|
||||
s8 walkDist;
|
||||
u32 color;
|
||||
} Zombie;
|
||||
|
||||
typedef struct {
|
||||
s8 xa;
|
||||
s8 ya;
|
||||
s16 health;
|
||||
s8 lvl;
|
||||
s8 dir;
|
||||
s8 jumpTime;
|
||||
u32 color;
|
||||
} Slime;
|
||||
|
||||
typedef struct {
|
||||
s8 xa;
|
||||
s8 ya;
|
||||
s16 health;
|
||||
s8 randWalkTime;
|
||||
s8 walkDist;
|
||||
s8 dir;
|
||||
int attackDelay;
|
||||
int attackTime;
|
||||
int attackType;
|
||||
s8 spriteAdjust;
|
||||
} AirWizard;
|
||||
|
||||
typedef struct {
|
||||
Entity* parent;
|
||||
s16 age;
|
||||
float xa;
|
||||
float ya;
|
||||
float xx;
|
||||
float yy;
|
||||
} Spark;
|
||||
|
||||
typedef struct {
|
||||
float xa;
|
||||
float ya;
|
||||
float za;
|
||||
float xx;
|
||||
float yy;
|
||||
float zz;
|
||||
s16 age;
|
||||
char* text;
|
||||
int color;
|
||||
} TextParticleEntity;
|
||||
|
||||
typedef struct {
|
||||
s16 age;
|
||||
} SmashParticleEntity;
|
||||
|
||||
struct Entity {
|
||||
s16 x;
|
||||
s16 y;
|
||||
s8 xKnockback,yKnockback;
|
||||
u8 xr,yr;
|
||||
u8 type;
|
||||
u8 level;
|
||||
s8 hurtTime;
|
||||
s16 slotNum; // Read-only. Do not mess with this.
|
||||
bool canPass;
|
||||
bool canSwim;
|
||||
union {
|
||||
Player p;
|
||||
EntityItem entityItem;
|
||||
EntityFurniture entityFurniture;
|
||||
Zombie zombie;
|
||||
Slime slime;
|
||||
AirWizard wizard;
|
||||
Spark spark;
|
||||
TextParticleEntity textParticle;
|
||||
SmashParticleEntity smashParticle;
|
||||
};
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
Entity entities[5][1000];
|
||||
Entity wizardSparks[120];
|
||||
s16 lastSlot[5];
|
||||
Inventory invs[301];//1 for the player, 300 for chests.
|
||||
s16 nextInv;
|
||||
} EntityManager;
|
||||
|
||||
EntityManager eManager;
|
||||
s8 currentLevel;
|
||||
|
||||
|
||||
double gaussrand();
|
||||
Entity newItemEntity(Item item, int x, int y, int level);
|
||||
Entity newFurnitureEntity(int itemID,Inventory * invPtr, int x, int y, int level);
|
||||
Entity newZombieEntity(int lvl, int x, int y, int level);
|
||||
Entity newSlimeEntity(int lvl, int x, int y, int level);
|
||||
Entity newAirWizardEntity(int x, int y, int level);
|
||||
Entity newSparkEntity(Entity* parent, float xa, float ya);
|
||||
Entity newTextParticleEntity(char * str, u32 color, int xa, int ya, int level);
|
||||
Entity newSmashParticleEntity(int xa, int ya, int level);
|
||||
void addEntityToList(Entity e, EntityManager* em);
|
||||
void removeEntityFromList(Entity * e,int level,EntityManager* em);
|
||||
|
||||
|
||||
|
1319
source/Globals.c
Normal file
1319
source/Globals.c
Normal file
File diff suppressed because it is too large
Load diff
100
source/Globals.h
Normal file
100
source/Globals.h
Normal file
|
@ -0,0 +1,100 @@
|
|||
#pragma once
|
||||
#include <3ds.h>
|
||||
#include "SaveLoad.h"
|
||||
#include "Input.h"
|
||||
|
||||
#define CIRCLEPAD 0xF0000000
|
||||
#define CSTICK 0x0F000000
|
||||
|
||||
#define MENU_NONE 0
|
||||
#define MENU_TITLE 1
|
||||
#define MENU_TUTORIAL 2
|
||||
#define MENU_ABOUT 3
|
||||
#define MENU_SETTINGS 4
|
||||
#define MENU_INVENTORY 5
|
||||
#define MENU_CRAFTING 6
|
||||
#define MENU_CONTAINER 7
|
||||
#define MENU_WIN 8
|
||||
#define MENU_LOSE 9
|
||||
#define MENU_PAUSED 10
|
||||
#define MENU_LOADGAME 11
|
||||
|
||||
#define TILE_NULL 255
|
||||
#define TILE_GRASS 0
|
||||
#define TILE_TREE 1
|
||||
#define TILE_ROCK 2
|
||||
#define TILE_DIRT 3
|
||||
#define TILE_SAND 4
|
||||
#define TILE_WATER 5
|
||||
#define TILE_LAVA 6
|
||||
#define TILE_CACTUS 7
|
||||
#define TILE_FLOWER 8
|
||||
#define TILE_IRONORE 9
|
||||
#define TILE_GOLDORE 10
|
||||
#define TILE_GEMORE 11
|
||||
#define TILE_FARM 12
|
||||
#define TILE_WHEAT 13
|
||||
#define TILE_SAPLING_TREE 14
|
||||
#define TILE_SAPLING_CACTUS 15
|
||||
#define TILE_STAIRS_DOWN 16
|
||||
#define TILE_STAIRS_UP 17
|
||||
#define TILE_CLOUD 18
|
||||
#define TILE_HARDROCK 19
|
||||
#define TILE_CLOUDCACTUS 20
|
||||
#define TILE_HOLE 21
|
||||
|
||||
bool screenShot;
|
||||
|
||||
extern char versionText[34];
|
||||
|
||||
Entity player;
|
||||
sf2d_texture * lightScreen;
|
||||
|
||||
sf2d_texture * minimap[5];
|
||||
u8 map[5][128*128];
|
||||
u8 data[5][128*128];
|
||||
u8 treeTable[256];
|
||||
u16 rockTable[256];
|
||||
u16 grassTable[16];
|
||||
char currentFileName[256];
|
||||
extern u8 currentMenu;
|
||||
extern char fpsstr[];
|
||||
u8 initGame;
|
||||
Item noItem;
|
||||
int airWizardHealthDisplay;
|
||||
u32 tickCount;
|
||||
RecipeManager* currentRecipes;
|
||||
Entity* curChestEntity;
|
||||
s16 curInvSel;
|
||||
bool quitGame;
|
||||
s8 currentSelection;
|
||||
|
||||
void tickTile(int x, int y);
|
||||
bool tileIsSolid(int tile, Entity * e);
|
||||
|
||||
s8 itemTileInteract(int tile, Item* item, int x, int y, int px, int py, int dir);
|
||||
|
||||
void tickEntity(Entity* e);
|
||||
|
||||
void trySpawn(int count, int level);
|
||||
|
||||
int getTile(int x, int y);
|
||||
u32 getTileColor(int tile);
|
||||
void setTile(int id, int x, int y);
|
||||
int getData(int x, int y);
|
||||
void setData(int id, int x, int y);
|
||||
|
||||
bool intersectsEntity(int x, int y, int r, Entity* e);
|
||||
|
||||
bool EntityBlocksEntity(Entity* e1, Entity* e2);
|
||||
void EntityVsEntity(Entity* e1, Entity* e2);
|
||||
void entityTileInteract(Entity* e, int tile,int x, int y);
|
||||
|
||||
void initPlayer();
|
||||
void tickPlayer();
|
||||
void playerAttack();
|
||||
bool isSwimming();
|
||||
bool playerUseEnergy(int amount);
|
||||
void playerHurtTile(int tile, int xt, int yt, int damage, int dir);
|
||||
bool playerIntersectsEntity(Entity* e);
|
||||
void playerEntityInteract(Entity* e);
|
20
source/Input.c
Normal file
20
source/Input.c
Normal file
|
@ -0,0 +1,20 @@
|
|||
#include "Input.h"
|
||||
|
||||
void toggleKey(Key* key, bool held, bool down){
|
||||
key->down = held;
|
||||
key->clicked = down;
|
||||
}
|
||||
|
||||
void tickKeys(u32 held, u32 down){
|
||||
toggleKey(&k_up, held & k_up.input, down & k_up.input);
|
||||
toggleKey(&k_down, held & k_down.input, down & k_down.input);
|
||||
toggleKey(&k_left, held & k_left.input, down & k_left.input);
|
||||
toggleKey(&k_right, held & k_right.input, down & k_right.input);
|
||||
toggleKey(&k_pause, held & k_pause.input, down & k_pause.input);
|
||||
toggleKey(&k_attack, held & k_attack.input, down & k_attack.input);
|
||||
toggleKey(&k_menu, held & k_menu.input, down & k_menu.input);
|
||||
toggleKey(&k_accept, held & k_accept.input, down & k_accept.input);
|
||||
toggleKey(&k_decline, held & k_decline.input, down & k_decline.input);
|
||||
toggleKey(&k_delete, held & k_delete.input, down & k_delete.input);
|
||||
}
|
||||
|
21
source/Input.h
Normal file
21
source/Input.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
#include <3ds.h>
|
||||
|
||||
typedef struct {
|
||||
bool down, clicked;
|
||||
int input;
|
||||
} Key;
|
||||
|
||||
Key k_null;
|
||||
Key k_up;
|
||||
Key k_down;
|
||||
Key k_left;
|
||||
Key k_right;
|
||||
Key k_attack;
|
||||
Key k_menu;
|
||||
Key k_pause;
|
||||
Key k_accept;
|
||||
Key k_decline;
|
||||
Key k_delete;
|
||||
|
||||
void tickKeys(u32 held,u32 down);
|
||||
bool clicked(Key key);
|
238
source/Item.c
Normal file
238
source/Item.c
Normal file
|
@ -0,0 +1,238 @@
|
|||
#include "Item.h"
|
||||
|
||||
char currentName[16];
|
||||
|
||||
bool isItemEmpty(Item* item){
|
||||
if(item->id < 6 || item->onlyOne == true) return false;
|
||||
if(item->countLevel < 1) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void pushItemToInventoryFront(Item item, Inventory * inv){
|
||||
if(inv->lastSlot < 300) ++inv->lastSlot;
|
||||
int i;
|
||||
for(i = inv->lastSlot;i > 0;--i){
|
||||
inv->items[i] = inv->items[i-1]; // Move the items up the list.
|
||||
inv->items[i].slotNum = i;
|
||||
}
|
||||
item.invPtr = (int*)inv;
|
||||
inv->items[0] = item;
|
||||
inv->items[0].slotNum = 0;
|
||||
|
||||
}
|
||||
|
||||
void addItemToInventory(Item item, Inventory * inv){
|
||||
if(!item.onlyOne){
|
||||
int i;
|
||||
for(i = 0;i < inv->lastSlot;++i){ //Search inventory if item already exists.
|
||||
if(inv->items[i].id == item.id){
|
||||
inv->items[i].countLevel+=item.countLevel;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
item.slotNum = inv->lastSlot;
|
||||
item.invPtr = (int*)inv;
|
||||
inv->items[inv->lastSlot] = item;
|
||||
++inv->lastSlot;
|
||||
}
|
||||
|
||||
void removeItemFromCurrentInv(Item* item){
|
||||
removeItemFromInventory(item->slotNum, (Inventory*)item->invPtr);
|
||||
}
|
||||
|
||||
Item nullItem;
|
||||
void removeItemFromInventory(int slot, Inventory * inv){
|
||||
int i;
|
||||
for(i = slot;i < inv->lastSlot - 1;++i){
|
||||
inv->items[i] = inv->items[i + 1]; // Move the items down.
|
||||
inv->items[i].slotNum--;
|
||||
}
|
||||
--inv->lastSlot;
|
||||
inv->items[inv->lastSlot] = nullItem; // Make the last slot null.
|
||||
}
|
||||
|
||||
Item newItem(int id, int cLevel){
|
||||
Item item;
|
||||
item.id = id;
|
||||
if(id != ITEM_NULL){
|
||||
if(cLevel > 999) cLevel = 999;
|
||||
item.countLevel = cLevel;
|
||||
if(id < 7 || id > 27) item.onlyOne = true; // Tools + Furniture.
|
||||
else item.onlyOne = false;
|
||||
}
|
||||
item.chestPtr = NULL;
|
||||
return item;
|
||||
}
|
||||
|
||||
Item* getItemFromInventory(int itemID, Inventory * inv){
|
||||
int i;
|
||||
for(i = 0;i < inv->lastSlot;++i){
|
||||
if(inv->items[i].id == itemID){
|
||||
return &inv->items[i];
|
||||
}
|
||||
}
|
||||
return (Item*)NULL;
|
||||
}
|
||||
|
||||
int countItemInv(int itemID, int level, Inventory* inv){
|
||||
int i, count = 0;
|
||||
for(i = 0;i < inv->lastSlot;++i){
|
||||
if(inv->items[i].id == itemID){
|
||||
if(inv->items[i].onlyOne){
|
||||
if(level == inv->items[i].countLevel) count++;
|
||||
} else count += inv->items[i].countLevel;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
char* getItemName(int itemID, int countLevel){
|
||||
switch(itemID){
|
||||
case TOOL_SHOVEL:
|
||||
switch(countLevel){
|
||||
case 1: return "Rock Shovel";
|
||||
case 2: return "Iron Shovel";
|
||||
case 3: return "Gold Shovel";
|
||||
case 4: return "Gem Shovel";
|
||||
default: return "Wood Shovel";
|
||||
}
|
||||
case TOOL_HOE:
|
||||
switch(countLevel){
|
||||
case 1: return "Rock Hoe";
|
||||
case 2: return "Iron Hoe";
|
||||
case 3: return "Gold Hoe";
|
||||
case 4: return "Gem Hoe";
|
||||
default: return "Wood Hoe";
|
||||
}
|
||||
case TOOL_SWORD:
|
||||
switch(countLevel){
|
||||
case 1: return "Rock Sword";
|
||||
case 2: return "Iron Sword";
|
||||
case 3: return "Gold Sword";
|
||||
case 4: return "Gem Sword";
|
||||
default: return "Wood Sword";
|
||||
}
|
||||
case TOOL_PICKAXE:
|
||||
switch(countLevel){
|
||||
case 1: return "Rock Pickaxe";
|
||||
case 2: return "Iron Pickaxe";
|
||||
case 3: return "Gold Pickaxe";
|
||||
case 4: return "Gem Pickaxe";
|
||||
default: return "Wood Pickaxe";
|
||||
}
|
||||
case TOOL_AXE:
|
||||
switch(countLevel){
|
||||
case 1: return "Rock Axe";
|
||||
case 2: return "Iron Axe";
|
||||
case 3: return "Gold Axe";
|
||||
case 4: return "Gem Axe";
|
||||
default: return "Wood Axe";
|
||||
}
|
||||
case ITEM_ANVIL: return "Anvil";
|
||||
case ITEM_CHEST: return "Chest";
|
||||
case ITEM_OVEN: return "Oven";
|
||||
case ITEM_FURNACE: return "Furnace";
|
||||
case ITEM_WORKBENCH: return "Workbench";
|
||||
case ITEM_LANTERN: return "Lantern";
|
||||
case ITEM_POWGLOVE: return "Power Glove";
|
||||
case ITEM_FLOWER: sprintf(currentName,"%d Flower", countLevel); return currentName;
|
||||
case ITEM_WOOD: sprintf(currentName,"%d Wood", countLevel); return currentName;
|
||||
case ITEM_STONE: sprintf(currentName,"%d Stone", countLevel); return currentName;
|
||||
case ITEM_SAND: sprintf(currentName,"%d Sand", countLevel); return currentName;
|
||||
case ITEM_DIRT: sprintf(currentName,"%d Dirt", countLevel); return currentName;
|
||||
case ITEM_CLOUD: sprintf(currentName,"%d Cloud", countLevel); return currentName;
|
||||
case ITEM_ACORN: sprintf(currentName,"%d Acorn", countLevel); return currentName;
|
||||
case ITEM_CACTUS: sprintf(currentName,"%d Cactus", countLevel); return currentName;
|
||||
case ITEM_SEEDS: sprintf(currentName,"%d Seeds", countLevel); return currentName;
|
||||
case ITEM_WHEAT: sprintf(currentName,"%d Wheat", countLevel); return currentName;
|
||||
case ITEM_FLESH: sprintf(currentName,"%d Flesh", countLevel); return currentName;
|
||||
case ITEM_BREAD: sprintf(currentName,"%d Bread", countLevel); return currentName;
|
||||
case ITEM_APPLE: sprintf(currentName,"%d Apple", countLevel); return currentName;
|
||||
case ITEM_COAL: sprintf(currentName,"%d Coal", countLevel); return currentName;
|
||||
case ITEM_IRONORE: sprintf(currentName,"%d Iron ore", countLevel); return currentName;
|
||||
case ITEM_GOLDORE: sprintf(currentName,"%d Gold ore", countLevel); return currentName;
|
||||
case ITEM_IRONINGOT: sprintf(currentName,"%d Iron ingot", countLevel); return currentName;
|
||||
case ITEM_GOLDINGOT: sprintf(currentName,"%d Gold ingot", countLevel); return currentName;
|
||||
case ITEM_GLASS: sprintf(currentName,"%d Glass", countLevel); return currentName;
|
||||
case ITEM_GEM: sprintf(currentName,"%d Gem", countLevel); return currentName;
|
||||
case ITEM_SLIME: sprintf(currentName,"%d Slime", countLevel); return currentName;
|
||||
default: return ""; // null
|
||||
}
|
||||
}
|
||||
|
||||
char* getBasicItemName(int itemID, int countLevel){
|
||||
switch(itemID){
|
||||
case TOOL_SHOVEL:
|
||||
switch(countLevel){
|
||||
case 1: return "Rock Shovel";
|
||||
case 2: return "Iron Shovel";
|
||||
case 3: return "Gold Shovel";
|
||||
case 4: return "Gem Shovel";
|
||||
default: return "Wood Shovel";
|
||||
}
|
||||
case TOOL_HOE:
|
||||
switch(countLevel){
|
||||
case 1: return "Rock Hoe";
|
||||
case 2: return "Iron Hoe";
|
||||
case 3: return "Gold Hoe";
|
||||
case 4: return "Gem Hoe";
|
||||
default: return "Wood Hoe";
|
||||
}
|
||||
case TOOL_SWORD:
|
||||
switch(countLevel){
|
||||
case 1: return "Rock Sword";
|
||||
case 2: return "Iron Sword";
|
||||
case 3: return "Gold Sword";
|
||||
case 4: return "Gem Sword";
|
||||
default: return "Wood Sword";
|
||||
}
|
||||
case TOOL_PICKAXE:
|
||||
switch(countLevel){
|
||||
case 1: return "Rock Pickaxe";
|
||||
case 2: return "Iron Pickaxe";
|
||||
case 3: return "Gold Pickaxe";
|
||||
case 4: return "Gem Pickaxe";
|
||||
default: return "Wood Pickaxe";
|
||||
}
|
||||
case TOOL_AXE:
|
||||
switch(countLevel){
|
||||
case 1: return "Rock Axe";
|
||||
case 2: return "Iron Axe";
|
||||
case 3: return "Gold Axe";
|
||||
case 4: return "Gem Axe";
|
||||
default: return "Wood Axe";
|
||||
}
|
||||
case ITEM_ANVIL: return "Anvil";
|
||||
case ITEM_CHEST: return "Chest";
|
||||
case ITEM_OVEN: return "Oven";
|
||||
case ITEM_FURNACE: return "Furnace";
|
||||
case ITEM_WORKBENCH: return "Workbench";
|
||||
case ITEM_LANTERN: return "Lantern";
|
||||
case ITEM_POWGLOVE: return "Power Glove";
|
||||
case ITEM_FLOWER: return "Flower";
|
||||
case ITEM_WOOD: return "Wood";
|
||||
case ITEM_STONE: return "Stone";
|
||||
case ITEM_SAND: return "Sand";
|
||||
case ITEM_DIRT: return "Dirt";
|
||||
case ITEM_CLOUD: return "Cloud";
|
||||
case ITEM_ACORN: return "Acorn";
|
||||
case ITEM_CACTUS: return "Cactus";
|
||||
case ITEM_SEEDS: return "Seeds";
|
||||
case ITEM_WHEAT: return "Wheat";
|
||||
case ITEM_FLESH: return "Flesh";
|
||||
case ITEM_BREAD: return "Bread";
|
||||
case ITEM_APPLE: return "Apple";
|
||||
case ITEM_COAL: return "Coal";
|
||||
case ITEM_IRONORE: return "Iron ore";
|
||||
case ITEM_GOLDORE: return "Gold ore";
|
||||
case ITEM_IRONINGOT: return "Iron ingot";
|
||||
case ITEM_GOLDINGOT: return "Gold ingot";
|
||||
case ITEM_GLASS: return "Glass";
|
||||
case ITEM_GEM: return "Gem";
|
||||
case ITEM_SLIME: return "Slime";
|
||||
default: return ""; // null
|
||||
}
|
||||
|
||||
}
|
70
source/Item.h
Normal file
70
source/Item.h
Normal file
|
@ -0,0 +1,70 @@
|
|||
#pragma once
|
||||
#include <3ds.h>
|
||||
#include <sf2d.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "Sound.h"
|
||||
|
||||
#define ITEM_NULL 0
|
||||
#define TOOL_SHOVEL 1
|
||||
#define TOOL_HOE 2
|
||||
#define TOOL_SWORD 3
|
||||
#define TOOL_PICKAXE 4
|
||||
#define TOOL_AXE 5
|
||||
#define ITEM_POWGLOVE 6
|
||||
#define ITEM_FLOWER 7
|
||||
#define ITEM_WOOD 8
|
||||
#define ITEM_STONE 9
|
||||
#define ITEM_SAND 10
|
||||
#define ITEM_DIRT 11
|
||||
#define ITEM_CLOUD 12
|
||||
#define ITEM_ACORN 13
|
||||
#define ITEM_CACTUS 14
|
||||
#define ITEM_SEEDS 15
|
||||
#define ITEM_WHEAT 16
|
||||
#define ITEM_FLESH 17
|
||||
#define ITEM_BREAD 18
|
||||
#define ITEM_APPLE 19
|
||||
#define ITEM_SLIME 20
|
||||
#define ITEM_COAL 21
|
||||
#define ITEM_IRONORE 22
|
||||
#define ITEM_GOLDORE 23
|
||||
#define ITEM_IRONINGOT 24
|
||||
#define ITEM_GOLDINGOT 25
|
||||
#define ITEM_GLASS 26
|
||||
#define ITEM_GEM 27
|
||||
#define ITEM_ANVIL 28
|
||||
#define ITEM_CHEST 29
|
||||
#define ITEM_OVEN 30
|
||||
#define ITEM_FURNACE 31
|
||||
#define ITEM_WORKBENCH 32
|
||||
#define ITEM_LANTERN 33
|
||||
|
||||
typedef struct Inventory Inventory;
|
||||
|
||||
typedef struct {
|
||||
s16 id;
|
||||
s16 countLevel; // Count for items, Level for tools.
|
||||
s16 slotNum; // Read-only. Do not mess with this.
|
||||
bool onlyOne;
|
||||
int* invPtr; // pointer to current inventory.
|
||||
Inventory * chestPtr; // pointer to chest inventory for chest item.
|
||||
} Item;
|
||||
|
||||
struct Inventory {
|
||||
Item items[300]; // Maximum of 300 slots in every inventory.
|
||||
s16 lastSlot; // lastSlot can also be used to read the size of the inventory.
|
||||
};
|
||||
|
||||
bool isItemEmpty(Item* item);
|
||||
Item newItem(int id, int cLevel);
|
||||
char* getItemName(int itemID, int countLevel);
|
||||
char* getBasicItemName(int itemID, int countLevel);
|
||||
void pushItemToInventoryFront(Item item, Inventory * inv);
|
||||
void addItemToInventory(Item item, Inventory * inv);
|
||||
void removeItemFromCurrentInv(Item* item);
|
||||
void removeItemFromInventory(int slot, Inventory * inv);
|
||||
Item* getItemFromInventory(int itemID, Inventory * inv);
|
||||
int countItemInv(int itemID,int level, Inventory* inv);
|
403
source/MapGen.c
Normal file
403
source/MapGen.c
Normal file
|
@ -0,0 +1,403 @@
|
|||
#include "MapGen.h"
|
||||
|
||||
int w = 0;
|
||||
int h = 0;
|
||||
|
||||
float nextFloat(){
|
||||
return (float)rand()/RAND_MAX;
|
||||
}
|
||||
|
||||
double sample(double * values, int x, int y) {
|
||||
return values[(x & (w - 1)) + (y & (h - 1)) * w];
|
||||
}
|
||||
|
||||
double * Noise(int width, int height, int featureSize) {
|
||||
w = width;
|
||||
h = height;
|
||||
double * values = malloc(sizeof(double) * w * h);
|
||||
int x, y;
|
||||
for(x = 0; x < w; x+=featureSize){
|
||||
for(y = 0; y < w; y+=featureSize){
|
||||
values[(x & (w - 1)) + (y & (h - 1)) * w] = nextFloat() * 2 - 1;
|
||||
}
|
||||
}
|
||||
|
||||
int stepSize = featureSize;
|
||||
double scale = 1.0 / w;
|
||||
double scaleMod = 1;
|
||||
do {
|
||||
int halfStep = stepSize / 2;
|
||||
for(x = 0; x < w; x+=stepSize){
|
||||
for(y = 0; y < w; y+=stepSize){
|
||||
double a = sample(values,x, y);
|
||||
double b = sample(values,x + stepSize, y);
|
||||
double c = sample(values,x, y + stepSize);
|
||||
double d = sample(values,x + stepSize, y + stepSize);
|
||||
|
||||
double e = (a + b + c + d) / 4.0 + (nextFloat() * 2 - 1) * stepSize * scale;
|
||||
values[((x + halfStep) & (w - 1)) + ((y + halfStep) & (h - 1)) * w] = e;
|
||||
}
|
||||
}
|
||||
for(x = 0; x < w; x+=stepSize){
|
||||
for(y = 0; y < w; y+=stepSize){
|
||||
double a = sample(values,x, y);
|
||||
double b = sample(values,x + stepSize, y);
|
||||
double c = sample(values,x, y + stepSize);
|
||||
double d = sample(values,x + halfStep, y + halfStep);
|
||||
double e = sample(values,x + halfStep, y - halfStep);
|
||||
double f = sample(values,x - halfStep, y + halfStep);
|
||||
double H = (a + b + d + e) / 4.0 + (nextFloat() * 2 - 1) * stepSize * scale * 0.5;
|
||||
double g = (a + c + d + f) / 4.0 + (nextFloat() * 2 - 1) * stepSize * scale * 0.5;
|
||||
values[((x + halfStep) & (w - 1)) + (y & (h - 1)) * w] = H;
|
||||
values[(x & (w - 1)) + ((y + halfStep) & (h - 1)) * w] = g;
|
||||
}
|
||||
}
|
||||
|
||||
stepSize /= 2;
|
||||
scale *= (scaleMod + 0.8);
|
||||
scaleMod *= 0.3;
|
||||
} while (stepSize > 1);
|
||||
return values;
|
||||
}
|
||||
|
||||
void newSeed(){
|
||||
srand(time(NULL));
|
||||
}
|
||||
|
||||
void createAndValidateTopMap(int w, int h, u8 * map, u8 * data) {
|
||||
do {
|
||||
createTopMap(w, h, map, data);
|
||||
|
||||
int count[256]={[0 ... 255] = 0};
|
||||
int i;
|
||||
for (i = 0; i < w * h; ++i) count[map[i] & 0xff]++;
|
||||
if (count[TILE_ROCK & 0xff] < 100) continue;
|
||||
if (count[TILE_SAND & 0xff] < 100) continue;
|
||||
if (count[TILE_GRASS & 0xff] < 100) continue;
|
||||
if (count[TILE_TREE & 0xff] < 100) continue;
|
||||
if (count[TILE_STAIRS_DOWN & 0xff] < 2) continue;
|
||||
|
||||
return;
|
||||
} while (true);
|
||||
}
|
||||
|
||||
void createAndValidateUndergroundMap(int w, int h,int depthLevel, u8 * map, u8 * data) {
|
||||
do {
|
||||
createUndergroundMap(w, h, depthLevel, map, data);
|
||||
|
||||
int count[256]={[0 ... 255] = 0};
|
||||
int i = 0;
|
||||
for (i = 0; i < w * h; ++i)count[map[i] & 0xff]++;
|
||||
if (count[TILE_ROCK & 0xff] < 100) continue;
|
||||
if (count[TILE_DIRT & 0xff] < 100) continue;
|
||||
switch(depthLevel){
|
||||
case 1: if (count[TILE_IRONORE & 0xff] < 20) continue; break;
|
||||
case 2: if (count[TILE_GOLDORE & 0xff] < 20) continue; break;
|
||||
case 3: if (count[TILE_GEMORE & 0xff] < 20) continue; break;
|
||||
}
|
||||
if (depthLevel < 3) if (count[TILE_STAIRS_DOWN & 0xff] < 2) continue;
|
||||
|
||||
return;
|
||||
} while (true);
|
||||
}
|
||||
void createAndValidateSkyMap(int w, int h, u8 * map, u8 * data) {
|
||||
do {
|
||||
createSkyMap(w, h, map, data);
|
||||
|
||||
int count[256]={[0 ... 255] = 0};
|
||||
int i = 0;
|
||||
for (i = 0; i < w * h; ++i)count[map[i] & 0xff]++;
|
||||
if (count[TILE_CLOUD & 0xff] < 1600) continue;
|
||||
if (count[TILE_STAIRS_DOWN & 0xff] < 2) continue;
|
||||
|
||||
return;
|
||||
} while (true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void createTopMap(int w, int h, u8 * map, u8 * data) {
|
||||
double* mnoise1 = Noise(w, h, 16);
|
||||
double* mnoise2 = Noise(w, h, 16);
|
||||
double* mnoise3 = Noise(w, h, 16);
|
||||
double* noise1 = Noise(w, h, 32);
|
||||
double* noise2 = Noise(w, h, 32);
|
||||
|
||||
int x,y,i,j,k,xx,yy;
|
||||
|
||||
for(x = 0; x < w; ++x){
|
||||
for(y = 0; y < w; ++y){
|
||||
int i = x + y * w;
|
||||
|
||||
double val = fabs(noise1[i] - noise2[i]) * 3 - 2;
|
||||
double mval = fabs(mnoise1[i] - mnoise2[i]);
|
||||
mval = fabs(mval - mnoise3[i]) * 3 - 2;
|
||||
|
||||
double xd = x / (w - 1.0) * 2 - 1;
|
||||
double yd = y / (h - 1.0) * 2 - 1;
|
||||
if (xd < 0) xd = -xd;
|
||||
if (yd < 0) yd = -yd;
|
||||
double dist = xd >= yd ? xd : yd;
|
||||
dist = dist * dist * dist * dist;
|
||||
dist = dist * dist * dist * dist;
|
||||
val = val + 1 - dist * 20; //-2 before to -21.0 after
|
||||
|
||||
if (val < -0.5) {
|
||||
map[i] = TILE_WATER;
|
||||
} else if (val > 0.5 && mval < -1) {
|
||||
map[i] = TILE_ROCK;
|
||||
} else {
|
||||
map[i] = TILE_GRASS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < w * h / 2800; ++i) {
|
||||
int xs = rand()%w;
|
||||
int ys = rand()%h;
|
||||
for (k = 0; k < 10; ++k) {
|
||||
x = xs + (rand()%21) - 10;
|
||||
y = ys + (rand()%21) - 10;
|
||||
for (j = 0; j < 100; ++j) {
|
||||
int xo = x + (rand()%5) - (rand()%5);
|
||||
int yo = y + (rand()%5) - (rand()%5);
|
||||
for (yy = yo - 1;yy <= yo + 1; ++yy){
|
||||
for(xx = xo - 1; xx <= xo + 1; ++xx){
|
||||
if (xx >= 0 && yy >= 0 && xx < w && yy < h) if (map[xx + yy * w] == TILE_GRASS) map[xx + yy * w] = TILE_SAND;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < w * h / 400; ++i) {
|
||||
x = rand()%w;
|
||||
y = rand()%h;
|
||||
for (j = 0; j < 200; ++j) {
|
||||
xx = x + (rand()%15) - (rand()%15);
|
||||
yy = y + (rand()%15) - (rand()%15);
|
||||
if (xx >= 0 && yy >= 0 && xx < w && yy < h) {
|
||||
if (map[xx + yy * w] == TILE_GRASS) {
|
||||
map[xx + yy * w] = TILE_TREE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < w * h / 800; ++i) {
|
||||
x = rand()%w;
|
||||
y = rand()%h;
|
||||
for (j = 0; j < 30;++j) {
|
||||
xx = x + (rand()%5) - (rand()%5);
|
||||
yy = y + (rand()%5) - (rand()%5);
|
||||
if (xx >= 0 && yy >= 0 && xx < w && yy < h) {
|
||||
if (map[xx + yy * w] == TILE_GRASS) {
|
||||
map[xx + yy * w] = TILE_FLOWER;
|
||||
data[xx + yy * w] = rand()%4; // determines mirroring.
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < w * h / 100; ++i) {
|
||||
xx = rand()%w;
|
||||
yy = rand()%h;
|
||||
if (xx >= 0 && yy >= 0 && xx < w && yy < h) {
|
||||
if (map[xx + yy * w] == TILE_SAND) {
|
||||
map[xx + yy * w] = TILE_CACTUS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int sCount, attempts = 0;
|
||||
for (sCount = 0; sCount < 4;) {
|
||||
xx = rand()%w;
|
||||
yy = rand()%h;
|
||||
if (xx >= 0 && yy >= 0 && xx < w && yy < h) {
|
||||
if (map[xx + yy * w] == TILE_ROCK)
|
||||
{
|
||||
map[xx + yy * w] = TILE_STAIRS_DOWN;
|
||||
map[xx + (yy+1) * w] = TILE_ROCK;
|
||||
map[(xx+1) + yy * w] = TILE_ROCK;
|
||||
map[xx + (yy-1) * w] = TILE_ROCK;
|
||||
map[(xx-1) + yy * w] = TILE_ROCK;
|
||||
map[(xx-1) + (yy-1) * w] = TILE_ROCK;
|
||||
map[(xx+1) + (yy+1) * w] = TILE_ROCK;
|
||||
map[(xx+1) + (yy-1) * w] = TILE_ROCK;
|
||||
map[(xx-1) + (yy+1) * w] = TILE_ROCK;
|
||||
++sCount;
|
||||
}
|
||||
}
|
||||
if(attempts < (w*h/100)) ++attempts; else break;
|
||||
}
|
||||
free(mnoise1);
|
||||
free(mnoise2);
|
||||
free(mnoise3);
|
||||
free(noise1);
|
||||
free(noise2);
|
||||
return;
|
||||
}
|
||||
|
||||
void createUndergroundMap(int w, int h,int depthLevel, u8 * map, u8 * data) {
|
||||
double* mnoise1 = Noise(w, h, 16);
|
||||
double* mnoise2 = Noise(w, h, 16);
|
||||
double* mnoise3 = Noise(w, h, 16);
|
||||
|
||||
double* nnoise1 = Noise(w, h, 16);
|
||||
double* nnoise2 = Noise(w, h, 16);
|
||||
double* nnoise3 = Noise(w, h, 16);
|
||||
|
||||
double* wnoise1 = Noise(w, h, 16);
|
||||
double* wnoise2 = Noise(w, h, 16);
|
||||
double* wnoise3 = Noise(w, h, 16);
|
||||
|
||||
double* noise1 = Noise(w, h, 32);
|
||||
double* noise2 = Noise(w, h, 32);
|
||||
|
||||
int x, y;
|
||||
for(x = 0; x < w; ++x){
|
||||
for(y = 0; y < w; ++y){
|
||||
int i = x + y * w;
|
||||
|
||||
double val = fabs(noise1[i] - noise2[i]) * 3 - 2;
|
||||
|
||||
double mval = fabs(mnoise1[i] - mnoise2[i]);
|
||||
mval = fabs(mval - mnoise3[i]) * 3 - 2;
|
||||
|
||||
double nval = fabs(nnoise1[i] - nnoise2[i]);
|
||||
nval = fabs(nval - nnoise3[i]) * 3 - 2;
|
||||
|
||||
double wval = fabs(wnoise1[i] - wnoise2[i]);
|
||||
wval = fabs(nval - wnoise3[i]) * 3 - 2;
|
||||
|
||||
double xd = x / (w - 1.0) * 2 - 1;
|
||||
double yd = y / (h - 1.0) * 2 - 1;
|
||||
if (xd < 0) xd = -xd;
|
||||
if (yd < 0) yd = -yd;
|
||||
double dist = xd >= yd ? xd : yd;
|
||||
dist = dist * dist * dist * dist;
|
||||
dist = dist * dist * dist * dist;
|
||||
val = val + 1 - dist * 20;
|
||||
|
||||
if (val > -2 && wval < -2.0 + (depthLevel) / 2 * 3) {
|
||||
if (depthLevel > 2)
|
||||
map[i] = TILE_LAVA;
|
||||
else
|
||||
map[i] = TILE_WATER;
|
||||
} else if (val > -2 && (mval < -1.7 || nval < -1.4)) {
|
||||
map[i] = TILE_DIRT;
|
||||
} else {
|
||||
map[i] = TILE_ROCK;
|
||||
}
|
||||
}
|
||||
}
|
||||
int i,j;
|
||||
for (i = 0; i < w * h / 400; ++i) {
|
||||
int x = rand()%w;
|
||||
int y = rand()%h;
|
||||
for(j = 0; j < 30; ++j) {
|
||||
int xx = x + (rand()%5) - (rand()%5);
|
||||
int yy = y + (rand()%5) - (rand()%5);
|
||||
if (xx >= 2 && yy >= 2 && xx < w-2 && yy < h-2) {
|
||||
if (map[xx + yy * w] == TILE_ROCK) {
|
||||
map[xx + yy * w] = TILE_IRONORE+depthLevel-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (depthLevel < 3){
|
||||
int sCount, attempts = 0;
|
||||
for (sCount = 0; sCount < 4;) {
|
||||
int xx = rand()%w;
|
||||
int yy = rand()%h;
|
||||
if (xx >= 0 && yy >= 0 && xx < w && yy < h) {
|
||||
if (map[xx + yy * w] == TILE_ROCK){
|
||||
map[xx + yy * w] = TILE_STAIRS_DOWN;
|
||||
map[xx + (yy+1) * w] = TILE_ROCK;
|
||||
map[(xx+1) + yy * w] = TILE_ROCK;
|
||||
map[xx + (yy-1) * w] = TILE_ROCK;
|
||||
map[(xx-1) + yy * w] = TILE_ROCK;
|
||||
map[(xx-1) + (yy-1) * w] = TILE_ROCK;
|
||||
map[(xx+1) + (yy+1) * w] = TILE_ROCK;
|
||||
map[(xx+1) + (yy-1) * w] = TILE_ROCK;
|
||||
map[(xx-1) + (yy+1) * w] = TILE_ROCK;
|
||||
++sCount;
|
||||
}
|
||||
}
|
||||
if(attempts < (w*h/100)) ++attempts; else break;
|
||||
}
|
||||
}
|
||||
free(mnoise1);
|
||||
free(mnoise2);
|
||||
free(mnoise3);
|
||||
free(nnoise1);
|
||||
free(nnoise2);
|
||||
free(nnoise3);
|
||||
free(wnoise1);
|
||||
free(wnoise2);
|
||||
free(wnoise3);
|
||||
free(noise1);
|
||||
free(noise2);
|
||||
|
||||
}
|
||||
void createSkyMap(int w, int h, u8 * map, u8 * data) {
|
||||
double* noise1 = Noise(w, h, 8);
|
||||
double* noise2 = Noise(w, h, 8);
|
||||
int x, y;
|
||||
for(x = 0; x < w; ++x){
|
||||
for(y = 0; y < w; ++y){
|
||||
int i = x + y * w;
|
||||
|
||||
double val = fabs(noise1[i] - noise2[i]) * 3 - 2;
|
||||
|
||||
double xd = x / (w - 1.0) * 2 - 1;
|
||||
double yd = y / (h - 1.0) * 2 - 1;
|
||||
if (xd < 0) xd = -xd;
|
||||
if (yd < 0) yd = -yd;
|
||||
double dist = xd >= yd ? xd : yd;
|
||||
dist = dist * dist * dist * dist;
|
||||
dist = dist * dist * dist * dist;
|
||||
val = -val * 1 - 2.2;
|
||||
val = val + 1 - dist * 20;
|
||||
|
||||
if (val < -0.25) {
|
||||
map[i] = -1; // render nothing
|
||||
} else {
|
||||
map[i] = TILE_CLOUD;
|
||||
}
|
||||
}
|
||||
}
|
||||
int i;
|
||||
for (i = 0; i < w * h / 50; ++i) {
|
||||
int xx = rand()%w;
|
||||
int yy = rand()%h;
|
||||
if (xx >= 0 && yy >= 0 && xx < w && yy < h) {
|
||||
if (map[xx + yy * w] == TILE_CLOUD) map[xx + yy * w] = TILE_CLOUDCACTUS;
|
||||
}
|
||||
}
|
||||
int sCount, attempts = 0;
|
||||
for (sCount = 0; sCount < 2;) {
|
||||
int xx = rand()%w;
|
||||
int yy = rand()%h;
|
||||
if (xx >= 0 && yy >= 0 && xx < w && yy < h) {
|
||||
if (map[xx + yy * w] == TILE_CLOUD)
|
||||
{
|
||||
map[xx + yy * w] = TILE_STAIRS_DOWN;
|
||||
map[xx + (yy+1) * w] = TILE_CLOUD;
|
||||
map[(xx+1) + yy * w] = TILE_CLOUD;
|
||||
map[xx + (yy-1) * w] = TILE_CLOUD;
|
||||
map[(xx-1) + yy * w] = TILE_CLOUD;
|
||||
map[(xx-1) + (yy-1) * w] = TILE_CLOUD;
|
||||
map[(xx+1) + (yy+1) * w] = TILE_CLOUD;
|
||||
map[(xx+1) + (yy-1) * w] = TILE_CLOUD;
|
||||
map[(xx-1) + (yy+1) * w] = TILE_CLOUD;
|
||||
++sCount;
|
||||
}
|
||||
}
|
||||
if(attempts < w*h) ++attempts; else break;
|
||||
}
|
||||
free(noise1);
|
||||
free(noise2);
|
||||
}
|
||||
|
19
source/MapGen.h
Normal file
19
source/MapGen.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
#pragma once
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <3ds.h>
|
||||
|
||||
#include "Globals.h"
|
||||
|
||||
float nextFloat();
|
||||
double sample(double * values, int x, int y);
|
||||
double * Noise(int w, int h, int featureSize);
|
||||
void newSeed();
|
||||
void createAndValidateTopMap(int w, int h, u8 * map, u8 * data);
|
||||
void createTopMap(int w, int h, u8 * map, u8 * data);
|
||||
void createAndValidateUndergroundMap(int w, int h,int depthLevel, u8 * map, u8 * data);
|
||||
void createUndergroundMap(int w, int h,int depthLevel, u8 * map, u8 * data);
|
||||
void createAndValidateSkyMap(int w, int h, u8 * map, u8 * data);
|
||||
void createSkyMap(int w, int h, u8 * map, u8 * data);
|
1006
source/Menu.c
Normal file
1006
source/Menu.c
Normal file
File diff suppressed because it is too large
Load diff
12
source/Menu.h
Normal file
12
source/Menu.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
#include <3ds.h>
|
||||
#include <string.h>
|
||||
#include <sf2d.h>
|
||||
#include <dirent.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "Render.h"
|
||||
|
||||
void renderMenu(int menu,int xscr,int yscr);
|
||||
void tickMenu(int menu);
|
826
source/Render.c
Normal file
826
source/Render.c
Normal file
|
@ -0,0 +1,826 @@
|
|||
#include "Render.h"
|
||||
|
||||
void render(s32 xp, s32 yp, u32 xTile, u32 yTile, u8 bits){
|
||||
xp-=offsetX;
|
||||
yp-=offsetY;
|
||||
int scaleX = 2, scaleY = 2;
|
||||
if((bits & 1) > 0){scaleX=-2;xp+=8;}
|
||||
if((bits & 2) > 0){scaleY=-2;yp+=8;}
|
||||
sf2d_draw_texture_part_scale(icons,xp<<1,yp<<1,xTile,yTile,8,8,scaleX,scaleY);
|
||||
}
|
||||
void renderb(s32 xp, s32 yp, u32 xTile, u32 yTile, u8 bits, u32 color){
|
||||
xp-=offsetX;
|
||||
yp-=offsetY;
|
||||
int scaleX = 2, scaleY = 2;
|
||||
if((bits & 1) > 0){scaleX=-2;xp+=8;}
|
||||
if((bits & 2) > 0){scaleY=-2;yp+=8;}
|
||||
sf2d_draw_texture_part_scale_blend(icons,xp<<1,yp<<1,xTile,yTile,8,8,scaleX,scaleY,color);
|
||||
}
|
||||
void renderr(s32 xp, s32 yp, u32 xTile, u32 yTile, u8 bits, float rotate){
|
||||
xp-=offsetX;
|
||||
yp-=offsetY;
|
||||
int scaleX = 2, scaleY = 2;
|
||||
if((bits & 1) > 0){scaleX=-2;xp+=8;}
|
||||
if((bits & 2) > 0){scaleY=-2;yp+=8;}
|
||||
sf2d_draw_texture_part_rotate_scale(icons,xp<<1,yp<<1,rotate,xTile,yTile,8,8,scaleX,scaleY);
|
||||
}
|
||||
void renderc(s32 xp, s32 yp, u32 xTile, u32 yTile,int sizeX, int sizeY, u8 bits){
|
||||
xp-=offsetX;
|
||||
yp-=offsetY;
|
||||
int scaleX = 2, scaleY = 2;
|
||||
if((bits & 1) > 0){scaleX=-2;xp+=sizeX;}
|
||||
if((bits & 2) > 0){scaleY=-2;yp+=sizeY;}
|
||||
sf2d_draw_texture_part_scale(icons,xp<<1,yp<<1,xTile,yTile,sizeX,sizeY,scaleX,scaleY);
|
||||
}
|
||||
void renderbc(s32 xp, s32 yp, u32 xTile, u32 yTile,int sizeX, int sizeY, u8 bits, u32 color){
|
||||
xp-=offsetX;
|
||||
yp-=offsetY;
|
||||
int scaleX = 2, scaleY = 2;
|
||||
if((bits & 1) > 0){scaleX=-2;xp+=sizeX;}
|
||||
if((bits & 2) > 0){scaleY=-2;yp+=sizeY;}
|
||||
sf2d_draw_texture_part_scale_blend(icons,xp<<1,yp<<1,xTile,yTile,sizeX,sizeY,scaleX,scaleY,color);
|
||||
}
|
||||
void render16(s32 xp, s32 yp, u32 xTile, u32 yTile, u8 bits){
|
||||
xp-=offsetX;
|
||||
yp-=offsetY;
|
||||
int scaleX = 2, scaleY = 2;
|
||||
if((bits & 1) > 0){scaleX=-2;xp+=16;}
|
||||
if((bits & 2) > 0){scaleY=-2;yp+=16;}
|
||||
sf2d_draw_texture_part_scale(icons,xp<<1,yp<<1,xTile,yTile,16,16,scaleX,scaleY);
|
||||
}
|
||||
|
||||
|
||||
void render16c(s32 xp, s32 yp, u32 xTile, u32 yTile, u8 bits,float scaleX, float scaleY){
|
||||
xp-=offsetX;
|
||||
yp-=offsetY;
|
||||
if((bits & 1) > 0){scaleX=-scaleX;xp+=16;}
|
||||
if((bits & 2) > 0){scaleY=-scaleY;yp+=16;}
|
||||
sf2d_draw_texture_part_scale(icons,xp*scaleX,yp*scaleY,xTile,yTile,16,16,scaleX,scaleY);
|
||||
}
|
||||
|
||||
void render16b(s32 xp, s32 yp, u32 xTile, u32 yTile, u8 bits,u32 color){
|
||||
xp-=offsetX;
|
||||
yp-=offsetY;
|
||||
int scaleX = 2, scaleY = 2;
|
||||
if((bits & 1) > 0){scaleX=-2;xp+=16;}
|
||||
if((bits & 2) > 0){scaleY=-2;yp+=16;}
|
||||
sf2d_draw_texture_part_scale_blend(icons,xp<<1,yp<<1,xTile,yTile,16,16,scaleX,scaleY,color);
|
||||
}
|
||||
void render16s(s32 xp, s32 yp, u32 tile, u8 bits,u32 color){
|
||||
xp-=offsetX;
|
||||
yp-=offsetY;
|
||||
int xTile = tile & 255;
|
||||
int yTile = tile >> 8;
|
||||
int scaleX = 2, scaleY = 2;
|
||||
if((bits & 1) > 0){scaleX=-2;xp+=16;}
|
||||
if((bits & 2) > 0){scaleY=-2;yp+=16;}
|
||||
sf2d_draw_texture_part_scale_blend(icons,xp<<1,yp<<1,xTile,yTile,16,16,scaleX,scaleY,color);
|
||||
}
|
||||
|
||||
void renderTitle(int x, int y){
|
||||
sf2d_draw_texture_part_scale(icons,(x-26)<<1,y<<1,0,240,104,16,2.0,2.0); // MINICRAFT
|
||||
sf2d_draw_texture_part(icons,x+48,y+52,104,240,152,16); // 3DS HOMEBREW EDITION
|
||||
}
|
||||
|
||||
void renderButtonIcon(u32 keyIcon, int x, int y, float scale){
|
||||
switch(keyIcon){
|
||||
case CIRCLEPAD: render16c(x,y,96,208,0,scale,scale); break;
|
||||
case KEY_CPAD_UP: render16c(x,y,112,208,0,scale,scale); break;
|
||||
case KEY_CPAD_LEFT: render16c(x,y,128,208,0,scale,scale); break;
|
||||
case KEY_CPAD_DOWN: render16c(x,y,144,208,0,scale,scale); break;
|
||||
case KEY_CPAD_RIGHT: render16c(x,y,160,208,0,scale,scale); break;
|
||||
|
||||
/* New 3DS only */
|
||||
case CSTICK: render16c(x,y,176,208,0,scale,scale); break;
|
||||
case KEY_CSTICK_UP: render16c(x,y,192,208,0,scale,scale); break;
|
||||
case KEY_CSTICK_LEFT: render16c(x,y,208,208,0,scale,scale); break;
|
||||
case KEY_CSTICK_DOWN: render16c(x,y,224,208,0,scale,scale); break;
|
||||
case KEY_CSTICK_RIGHT: render16c(x,y,240,208,0,scale,scale); break;
|
||||
|
||||
case KEY_A: render16c(x,y,0,224,0,scale,scale); break;
|
||||
case KEY_B: render16c(x,y,16,224,0,scale,scale); break;
|
||||
case KEY_X: render16c(x,y,32,224,0,scale,scale); break;
|
||||
case KEY_Y: render16c(x,y,48,224,0,scale,scale); break;
|
||||
case KEY_DUP: render16c(x,y,64,224,0,scale,scale); break;
|
||||
case KEY_DLEFT: render16c(x,y,80,224,0,scale,scale); break;
|
||||
case KEY_DDOWN: render16c(x,y,96,224,0,scale,scale); break;
|
||||
case KEY_DRIGHT: render16c(x,y,112,224,0,scale,scale); break;
|
||||
case KEY_START:
|
||||
render16c(x-8,y,128,224,0,scale,scale);
|
||||
render16c(x+8,y,144,224,0,scale,scale);
|
||||
break;
|
||||
case KEY_SELECT:
|
||||
render16c(x-8,y,160,224,0,scale,scale);
|
||||
render16c(x+8,y,176,224,0,scale,scale);
|
||||
break;
|
||||
case KEY_L: render16c(x,y,192,224,0,scale,scale); break;
|
||||
case KEY_R: render16c(x,y,208,224,0,scale,scale); break;
|
||||
|
||||
/* New 3DS only */
|
||||
case KEY_ZL: render16c(x,y,224,224,0,scale,scale); break;
|
||||
case KEY_ZR: render16c(x,y,240,224,0,scale,scale); break;
|
||||
}
|
||||
}
|
||||
|
||||
int getFrame(int a, int b, int s){
|
||||
return (a == s) ? 0 : ((a < b-1) ? 8 : 16);
|
||||
}
|
||||
|
||||
void renderFrame(int x1, int y1, int x2, int y2, u32 bgColor){
|
||||
int startX = x1;
|
||||
int startY = y1;
|
||||
sf2d_draw_rectangle((x1<<4)+4-(offsetX<<1),(y1<<4)+4-(offsetY<<1),((x2-x1)<<4)-8,((y2-y1)<<4)-8, bgColor);
|
||||
while(x1 < x2){
|
||||
y1 = startY;
|
||||
while(y1 < y2){
|
||||
int xp=(x1<<4)-(offsetX<<1);
|
||||
int yp=(y1<<4)-(offsetY<<1);
|
||||
sf2d_draw_texture_part_scale(icons,xp,yp,getFrame(x1,x2,startX),200+getFrame(y1,y2,startY),8,8,2.0,2.0);
|
||||
++y1;
|
||||
}
|
||||
++x1;
|
||||
}
|
||||
}
|
||||
|
||||
void renderDotsWithColor(int val, int x, int y,u8 bits, u32 color){
|
||||
switch(val){
|
||||
case 3: renderb(x,y,0,0,bits,color); return;
|
||||
case 5: renderb(x+8,y,8,0,bits,color); return;
|
||||
case 7: renderbc(x,y,0,0,16,8,bits,color); return;
|
||||
case 10: renderb(x,y+8,0,8,bits,color); return;
|
||||
case 11: renderbc(x,y,0,0,8,16,bits,color); return;
|
||||
case 12: renderb(x+8,y+8,8,8,bits,color); return;
|
||||
case 13: renderbc(x+8,y,8,0,8,16,bits,color); return;
|
||||
case 14: renderbc(x,y+8,0,8,16,8,bits,color); return;
|
||||
case 15: render16b(x,y,0,0,bits,color); return;
|
||||
}
|
||||
}
|
||||
|
||||
void renderRockDotsWithColor(int val, int x, int y, u32 color){
|
||||
switch(val){
|
||||
case 208: render16b(x,y,0,0,0,color); return;
|
||||
case 16: renderb(x+8,y+8,8,8,0,color); return;
|
||||
case 32: renderb(x,y+8,0,8,0,color); return;
|
||||
case 48: renderb(x,y+8,0,8,0,color); return;
|
||||
case 64: renderb(x,y,0,0,0,color); return;
|
||||
case 80: renderbc(x,y,0,0,8,16,0,color);return;
|
||||
case 96: renderbc(x+8,y,8,0,8,16,0,color);return;
|
||||
case 112: renderbc(x,y+8,0,8,16,8,0,color);return;
|
||||
case 128: renderbc(x,y,0,0,16,8,0,color);return;
|
||||
case 144: renderb(x,y+8,0,8,0,color);renderbc(x+8,y,8,0,8,16,0,color); return;
|
||||
case 160: renderb(x,y,0,0,0,color);renderbc(x+8,y,8,0,8,16,0,color); return;
|
||||
case 176: renderb(x+8,y,8,0,0,color);renderbc(x,y,0,0,8,16,0,color); return;
|
||||
case 192: renderb(x+8,y+8,8,8,0,color);renderbc(x,y,0,0,8,16,0,color); return;
|
||||
case 4112: renderbc(x,y,0,0,8,16,0,color);return;
|
||||
case 4128: renderbc(x,y+8,0,8,8,16,0,color);return;
|
||||
case 4192: renderb(x,y,0,0,0,color); return;
|
||||
case 8192: renderb(x,y+8,0,8,0,color); return;
|
||||
case 8208: renderb(x+8,y+8,8,8,0,color); return;
|
||||
case 8224: renderb(x+8,y+8,8,8,0,color); return;
|
||||
case 8240: renderb(x+8,y,8,0,0,color); return;
|
||||
case 8256: renderb(x,y+8,0,8,0,color); return;
|
||||
case 8272: renderb(x+8,y,8,0,0,color); return;
|
||||
case 8288: renderb(x,y,0,0,0,color); return;
|
||||
case 8304: renderb(x+8,y,8,0,0,color);renderb(x,y+8,0,8,0,color); return;
|
||||
case 8320: renderbc(x+8,y,8,0,8,16,0,color);return;
|
||||
case 8336: renderbc(x,y,0,0,8,16,0,color);return;
|
||||
case 8352: renderb(x,y,0,0,0,color); renderb(x+8,y+8,8,8,0,color); return;
|
||||
case 8368: renderb(x+8,y,8,0,0,color); return;
|
||||
case 8384: renderb(x,y+8,0,8,0,color); return;
|
||||
case 8400: renderb(x,y,0,0,0,color); return;
|
||||
case 8416: renderb(x+8,y+8,8,8,0,color); return;
|
||||
}
|
||||
}
|
||||
|
||||
void renderLights(){
|
||||
renderLight(player.x,player.y,4*8);
|
||||
int i;
|
||||
for(i = 0; i < eManager.lastSlot[currentLevel]; ++i){
|
||||
Entity e = eManager.entities[currentLevel][i];
|
||||
if(e.type != ENTITY_FURNITURE) continue;
|
||||
if(e.x > player.x-160 && e.y > player.y-125 && e.x<player.x+160 && e.y<player.y+125) renderLight(e.x,e.y,8*8);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/* The original software rendered version, it's bad for the framerate :( */
|
||||
void renderLight(int x, int y, int r){
|
||||
x-=offsetX;
|
||||
y-=offsetY;
|
||||
int x0 = x - r;
|
||||
int x1 = x + r;
|
||||
int y0 = y - r;
|
||||
int y1 = y + r;
|
||||
|
||||
// The game's resolution is actually 200x120, the textures are all scaled up by 2.
|
||||
if (x0 < 0) x0 = 0;
|
||||
if (y0 < 0) y0 = 0;
|
||||
if (x1 > 200) x1 = 200;
|
||||
if (y1 > 120) y1 = 120;
|
||||
|
||||
int xx, yy;
|
||||
for (yy = y0; yy < y1; yy++) {
|
||||
int yd = yy - y;
|
||||
yd = yd * yd;
|
||||
for (xx = x0; xx < x1; xx++) {
|
||||
int xd = xx - x;
|
||||
int dist = xd * xd + yd;
|
||||
if (dist <= r * r) sf2d_set_pixel(lightScreen, xx, yy, 0); // set transparent pixel
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void renderLightScreen(){
|
||||
sf2d_draw_texture_scale(lightScreen,0,0,2.0,2.0);
|
||||
}
|
||||
|
||||
u8 checkSurrTiles8(int xt, int yt, int id){
|
||||
u8 vt = 0;
|
||||
if(getTile(xt,yt-1) == id) vt |= 1;
|
||||
if(getTile(xt-1,yt) == id) vt |= 2;
|
||||
if(getTile(xt+1,yt) == id) vt |= 4;
|
||||
if(getTile(xt,yt+1) == id) vt |= 8;
|
||||
if(getTile(xt-1,yt-1) == id) vt |= 16;
|
||||
if(getTile(xt+1,yt-1) == id) vt |= 32;
|
||||
if(getTile(xt-1,yt+1) == id) vt |= 64;
|
||||
if(getTile(xt+1,yt+1) == id) vt |= 128;
|
||||
return vt;
|
||||
}
|
||||
u8 checkSurrTiles4(int xt, int yt, int id){
|
||||
u8 vt = 0;
|
||||
if(getTile(xt,yt-1) == id) vt |= 1;
|
||||
if(getTile(xt-1,yt) == id) vt |= 2;
|
||||
if(getTile(xt+1,yt) == id) vt |= 4;
|
||||
if(getTile(xt,yt+1) == id) vt |= 8;
|
||||
return vt;
|
||||
}
|
||||
|
||||
u8 v = 0;
|
||||
u8 tData = 0;
|
||||
void renderTile(int i, int x, int y){
|
||||
int age=0;
|
||||
switch(i){
|
||||
case TILE_GRASS:
|
||||
v = checkSurrTiles4(x >> 4,y >> 4, TILE_GRASS)
|
||||
| checkSurrTiles4(x >> 4,y >> 4, TILE_TREE)
|
||||
| checkSurrTiles4(x >> 4,y >> 4, TILE_FLOWER)
|
||||
| checkSurrTiles4(x >> 4,y >> 4, TILE_SAPLING_TREE);
|
||||
render16b(x,y,grassTable[v],80,0,0x69B569FF);
|
||||
renderDotsWithColor(v, x, y, 0, 0x8ED38EFF);
|
||||
break;
|
||||
case TILE_TREE:
|
||||
render16(x,y,treeTable[checkSurrTiles8(x >> 4,y >> 4, TILE_TREE)],16,0);
|
||||
break;
|
||||
case TILE_ROCK:
|
||||
v = checkSurrTiles8(x >> 4,y >> 4, TILE_ROCK);
|
||||
render16s(x,y,rockTable[v]+8192,0,0xFFFFFFFF);
|
||||
renderRockDotsWithColor(rockTable[v], x, y, 0x949494FF);
|
||||
break;
|
||||
case TILE_HARDROCK:
|
||||
v = checkSurrTiles8(x >> 4,y >> 4, TILE_HARDROCK);
|
||||
render16s(x,y,rockTable[v]+8192,0,0xCFCFFFFF);
|
||||
renderRockDotsWithColor(rockTable[v], x, y, 0x9494FFFF);
|
||||
break;
|
||||
case TILE_DIRT:
|
||||
if(currentLevel>1)render16b(x,y,0,0,0,0x383838FF);
|
||||
else render16b(x,y,0,0,0,0xA88F8FFF);
|
||||
break;
|
||||
case TILE_SAND:
|
||||
v = checkSurrTiles4(x >> 4,y >> 4, TILE_SAND)
|
||||
| checkSurrTiles4(x >> 4,y >> 4, TILE_CACTUS)
|
||||
| checkSurrTiles4(x >> 4,y >> 4, TILE_SAPLING_CACTUS);
|
||||
render16b(x,y,grassTable[v],80,0,0xF7F77BFF);
|
||||
renderDotsWithColor(v, x, y, 0, 0xB7B75BFF);
|
||||
break;
|
||||
case TILE_WATER:
|
||||
v = checkSurrTiles4(x >> 4,y >> 4, TILE_WATER)|checkSurrTiles4(x >> 4,y >> 4, TILE_HOLE);
|
||||
render16b(x,y,grassTable[v],96,0,0x001DC1FF);
|
||||
srand((tickCount + (x / 2 - y) * 4311)/10);
|
||||
renderDotsWithColor(v, x, y, rand()&3, 0x6B6BFFFF);
|
||||
break;
|
||||
case TILE_LAVA:
|
||||
v = checkSurrTiles4(x >> 4,y >> 4, TILE_LAVA)|checkSurrTiles4(x >> 4,y >> 4, TILE_HOLE);
|
||||
render16b(x,y,grassTable[v],96,0,0xC11D00FF);
|
||||
srand((tickCount + (x / 2 - y) * 4311)/10);
|
||||
renderDotsWithColor(v, x, y, rand()&3, 0xFF6B6BFF);
|
||||
break;
|
||||
case TILE_HOLE:
|
||||
render16b(x,y,grassTable[
|
||||
checkSurrTiles4(x >> 4,y >> 4, TILE_HOLE)|
|
||||
checkSurrTiles4(x >> 4,y >> 4, TILE_WATER)|
|
||||
checkSurrTiles4(x >> 4,y >> 4, TILE_LAVA)
|
||||
],96,0,0x383838FF);
|
||||
break;
|
||||
case TILE_CACTUS:
|
||||
render16(x,y,48,0,0);
|
||||
break;
|
||||
case TILE_FLOWER:
|
||||
render16(x,y,64,0,getData(x>>4,y>>4));
|
||||
break;
|
||||
case TILE_STAIRS_DOWN:
|
||||
if(currentLevel == 0) renderTile(TILE_CLOUD,x,y);
|
||||
render16(x,y,96,0,0);
|
||||
break;
|
||||
case TILE_STAIRS_UP:
|
||||
render16(x,y,112,0,0);
|
||||
break;
|
||||
case TILE_IRONORE:
|
||||
render16b(x,y,80,0,0,0xDFC8C8FF);
|
||||
break;
|
||||
case TILE_GOLDORE:
|
||||
render16b(x,y,80,0,0,0xE5E8B9FF);
|
||||
break;
|
||||
case TILE_GEMORE:
|
||||
render16b(x,y,80,0,0,0xDF98DEFF);
|
||||
break;
|
||||
case TILE_CLOUD:
|
||||
render16b(x,y,grassTable[checkSurrTiles4(x >> 4,y >> 4, TILE_CLOUD)
|
||||
| checkSurrTiles4(x >> 4,y >> 4, TILE_STAIRS_DOWN)
|
||||
| checkSurrTiles4(x >> 4,y >> 4, TILE_CLOUDCACTUS)],80,0,0xFFFFFFFF);
|
||||
break;
|
||||
case TILE_CLOUDCACTUS:
|
||||
renderTile(TILE_CLOUD,x,y);
|
||||
render16(x,y,80,0,0);
|
||||
break;
|
||||
case TILE_SAPLING_TREE:
|
||||
renderTile(TILE_GRASS,x,y);
|
||||
render16(x,y,32,0,0);
|
||||
break;
|
||||
case TILE_SAPLING_CACTUS:
|
||||
renderTile(TILE_SAND,x,y);
|
||||
render16(x,y,32,0,0);
|
||||
break;
|
||||
case TILE_FARM:
|
||||
render16(x,y,144,0,0);
|
||||
break;
|
||||
case TILE_WHEAT:
|
||||
age = getData(x>>4,y>>4)/20;
|
||||
if(age > 5) age = 5;
|
||||
render16(x,y,160+(age<<4),0,0);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void renderGui(){
|
||||
int i;
|
||||
for(i=0;i<10;++i){
|
||||
if(i < player.p.health) render(i*8+1,1,168,152,0); else render(i*8+1,1,176,152,0);
|
||||
if(i < player.p.stamina) render(i*8+1,10,184,152,0); else render(i*8+1,10,191,152,0);
|
||||
}
|
||||
}
|
||||
|
||||
void renderPlayer(){
|
||||
if(player.p.isDead) return;
|
||||
int xo = player.x - 8;
|
||||
int yo = player.y - 8;
|
||||
|
||||
if(player.p.attackTimer > 0 && player.p.dir == 1){
|
||||
renderc(xo,yo-4,16,160,16,8,0);
|
||||
renderItemIcon(player.p.activeItem->id,player.p.activeItem->countLevel,xo+4,yo-4);
|
||||
}
|
||||
u8 walk = (player.p.walkDist >> 4) & 1;
|
||||
bool swimming = isSwimming();
|
||||
switch(player.p.dir){
|
||||
case 0: // down
|
||||
if(swimming)renderc(xo,yo+4,48,160+(((player.p.swimTimer>>4)&1)<<3),16,8,0);
|
||||
else renderc(xo,yo+8,0,120+(player.p.isCarrying?16:0),16,8,walk==0?0:1);
|
||||
renderc(xo,yo,0,112+(player.p.isCarrying?16:0),16,8,walk==0?0:1);
|
||||
break;
|
||||
case 1: // up
|
||||
if(swimming)renderc(xo,yo+4,48,160+(((player.p.swimTimer>>4)&1)<<3),16,8,0);
|
||||
else renderc(xo,yo+8,16,120+(player.p.isCarrying?16:0),16,8,walk==0?0:1);
|
||||
renderc(xo,yo,16,112+(player.p.isCarrying?16:0),16,8,walk==0?0:1);
|
||||
break;
|
||||
case 2: // left
|
||||
if(swimming)renderc(xo,yo+4,48,160+(((player.p.swimTimer>>4)&1)<<3),16,8,0);
|
||||
else renderc(xo,yo+8,32+(walk<<4),120+(player.p.isCarrying?16:0),16,8,1);
|
||||
renderc(xo,yo,32+(walk<<4),112+(player.p.isCarrying?16:0),16,8,1);
|
||||
break;
|
||||
case 3: // right
|
||||
if(swimming)renderc(xo,yo+4,48,160+(((player.p.swimTimer>>4)&1)<<3),16,8,0);
|
||||
else renderc(xo,yo+8,32+(walk<<4),120+(player.p.isCarrying?16:0),16,8,0);
|
||||
renderc(xo,yo,32+(walk<<4),112+(player.p.isCarrying?16:0),16,8,0);
|
||||
break;
|
||||
}
|
||||
|
||||
if(player.p.isCarrying){
|
||||
renderFurniture(player.p.activeItem->id, xo, yo-12);
|
||||
}
|
||||
|
||||
if(player.p.attackTimer > 0){
|
||||
switch(player.p.dir){
|
||||
case 0:
|
||||
renderc(xo-player.p.ax,yo-player.p.ay+12,16,168,16,8,0);
|
||||
renderItemIcon(player.p.activeItem->id,player.p.activeItem->countLevel, xo+4,yo+12);
|
||||
break;
|
||||
case 2:
|
||||
renderc(xo-player.p.ax-4,yo-player.p.ay,32,160,8,16,0);
|
||||
renderItemIcon(player.p.activeItem->id,player.p.activeItem->countLevel, xo-4,yo+4);
|
||||
break;
|
||||
case 3:
|
||||
renderc(xo-player.p.ax+12,yo-player.p.ay,40,160,8,16,0);
|
||||
renderItemIcon(player.p.activeItem->id,player.p.activeItem->countLevel, xo+12,yo+4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void renderBackground(int xScroll, int yScroll){
|
||||
int xo = xScroll >> 4;
|
||||
int yo = yScroll >> 4;
|
||||
int x,y;
|
||||
for (x = xo;x <= 13 + xo; ++x) {
|
||||
for (y = yo;y <= 8 + yo; ++y)renderTile(getTile(x,y),x << 4,y << 4);
|
||||
}
|
||||
}
|
||||
|
||||
char * fontChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789.,!?'\"-+=/\\%()<>:; ";
|
||||
|
||||
void drawText(char * msg, u32 x, u32 y){
|
||||
int i = 0;
|
||||
x-=offsetX<<1;
|
||||
y-=offsetY<<1;
|
||||
for(i = 0; i<strlen(msg); ++i){
|
||||
int ix = strchr(fontChars, toupper((unsigned char)msg[i]))-fontChars;
|
||||
int iy = ix >> 5;
|
||||
if (ix >= 0) {
|
||||
sf2d_draw_texture_part(font,x + i * 12,y,(ix&31)*12,16+(iy*12),12,12);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void drawSizedText(char * msg, u32 x, u32 y, float size){
|
||||
int i = 0;
|
||||
for(i = 0; i<strlen(msg); ++i){
|
||||
int ix = strchr(fontChars, toupper((unsigned char)msg[i]))-fontChars;
|
||||
int iy = ix >> 5;
|
||||
if (ix >= 0) {
|
||||
sf2d_draw_texture_part_scale(font,(x + i * 8) * size,y,(ix&31)<<3,iy<<3,8,8,size,size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void drawTextColor(char * msg, u32 x, u32 y, u32 color){
|
||||
int i = 0;
|
||||
x-=offsetX<<1;
|
||||
y-=offsetY<<1;
|
||||
for(i = 0; i<strlen(msg); ++i){
|
||||
int ix = strchr(fontChars, toupper((unsigned char)msg[i]))-fontChars;
|
||||
int iy = ix >> 5;
|
||||
if (ix >= 0) {
|
||||
sf2d_draw_texture_part_blend(font,x + i * 12,y,(ix&31)*12,16+(iy*12),12,12, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Changes text color after the first space.
|
||||
void drawTextColorSpecial(char * msg, u32 x, u32 y, u32 color, u32 color2){
|
||||
int i = 0;
|
||||
x-=offsetX<<1;
|
||||
y-=offsetY<<1;
|
||||
bool sOver = false;
|
||||
for(i = 0; i<strlen(msg); ++i){
|
||||
int ix = strchr(fontChars, toupper((unsigned char)msg[i]))-fontChars;
|
||||
if(msg[i] == 32) sOver = true;
|
||||
int iy = ix >> 5;
|
||||
if (ix >= 0) {
|
||||
if(sOver)sf2d_draw_texture_part_blend(font,x + i * 12,y,(ix&31)*12,16+(iy*12),12,12, color2);
|
||||
else sf2d_draw_texture_part_blend(font,x + i * 12,y,(ix&31)*12,16+(iy*12),12,12, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void drawSizedTextColor(char * msg, int x, int y, float size, u32 color){
|
||||
int i;
|
||||
for(i = 0; i<strlen(msg); ++i){
|
||||
int ix = strchr(fontChars, toupper((unsigned char)msg[i]))-fontChars;
|
||||
int iy = ix >> 5;
|
||||
if (ix >= 0) sf2d_draw_texture_part_scale_blend(font,(x + i * 8) * size,y*size,(ix&31)<<3,iy<<3,8,8,size,size,color);
|
||||
}
|
||||
}
|
||||
|
||||
void renderFurniture(int itemID, int x, int y){
|
||||
switch(itemID){
|
||||
case ITEM_ANVIL: render16(x,y,64,128,0); break;
|
||||
case ITEM_CHEST: render16(x,y,80,128,0); break;
|
||||
case ITEM_OVEN: render16(x,y,96,128,0); break;
|
||||
case ITEM_FURNACE: render16(x,y,112,128,0); break;
|
||||
case ITEM_WORKBENCH: render16(x,y,128,128,0); break;
|
||||
case ITEM_LANTERN: render16(x,y,144,128,0); break;
|
||||
}
|
||||
}
|
||||
|
||||
char ertxt[20];
|
||||
void renderEntity(Entity* e, int x, int y){
|
||||
switch(e->type){
|
||||
case ENTITY_ITEM:
|
||||
if (e->entityItem.age >= 520) if (e->entityItem.age / 6 % 2 == 0) return;
|
||||
renderItemIcon2(e->entityItem.item.id,e->entityItem.item.countLevel, x-4, y-4, (int)e->entityItem.zz);
|
||||
break;
|
||||
case ENTITY_FURNITURE: renderFurniture(e->entityFurniture.itemID, x-8, y-8); break;
|
||||
case ENTITY_ZOMBIE:
|
||||
switch(e->zombie.dir){
|
||||
case 0: // down
|
||||
render16b(x-8,y-8,64,112,((e->zombie.walkDist>>4)&1)==0?0:1,e->zombie.color);
|
||||
break;
|
||||
case 1: // up
|
||||
render16b(x-8,y-8,80,112,((e->zombie.walkDist>>4)&1)==0?0:1,e->zombie.color);
|
||||
break;
|
||||
case 2: // left
|
||||
render16b(x-8,y-8,96+(((e->zombie.walkDist>>4)&1)<<4),112,1,e->zombie.color);
|
||||
break;
|
||||
case 3: // right
|
||||
render16b(x-8,y-8,96+(((e->zombie.walkDist>>4)&1)<<4),112,0,e->zombie.color);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ENTITY_SLIME:
|
||||
render16b(x-8,y-8-(e->slime.jumpTime>0?4:0),128+(e->slime.jumpTime>0?16:0),112,0,e->slime.color);
|
||||
break;
|
||||
case ENTITY_AIRWIZARD:
|
||||
e->wizard.spriteAdjust = 0;
|
||||
if(e->wizard.health < 200){ if (tickCount / 4 % 3 < 2) e->wizard.spriteAdjust = 16; }
|
||||
else if(e->wizard.health < 1000){ if (tickCount / 5 % 4 < 2) e->wizard.spriteAdjust = 16; }
|
||||
switch(e->wizard.dir){
|
||||
case 0: // down
|
||||
render16(x-8,y-8,160,112+e->wizard.spriteAdjust,((e->wizard.walkDist>>4)&1)==0?0:1);
|
||||
break;
|
||||
case 1: // up
|
||||
render16(x-8,y-8,176,112+e->wizard.spriteAdjust,((e->wizard.walkDist>>4)&1)==0?0:1);
|
||||
break;
|
||||
case 2: // left
|
||||
render16(x-8,y-8,192+(((e->wizard.walkDist>>4)&1)<<4),112+e->wizard.spriteAdjust,1);
|
||||
break;
|
||||
case 3: // right
|
||||
render16(x-8,y-8,192+(((e->wizard.walkDist>>4)&1)<<4),112+e->wizard.spriteAdjust,0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ENTITY_TEXTPARTICLE:
|
||||
x-=offsetX;
|
||||
y-=offsetY;
|
||||
drawSizedTextColor(e->textParticle.text,x+1,y-(int)e->textParticle.zz+1,2,0xFF);
|
||||
drawSizedTextColor(e->textParticle.text,x,y-(int)e->textParticle.zz,2,e->textParticle.color);
|
||||
break;
|
||||
case ENTITY_SMASHPARTICLE: render16(x,y,0,160,0); break;
|
||||
case ENTITY_SPARK:
|
||||
if (e->spark.age >= 200) if (e->spark.age / 6 % 2 == 0) return;
|
||||
renderr(x,y,200,152,0,e->spark.age*0.0349);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void renderEntities(int x, int y, EntityManager* em){
|
||||
int i;
|
||||
for(i = 0; i < em->lastSlot[currentLevel]; ++i){
|
||||
Entity e = em->entities[currentLevel][i];
|
||||
if(e.x > x-200 && e.y > y-125 && e.x<x+200 && e.y<y+125) renderEntity(&e, e.x, e.y);
|
||||
}
|
||||
}
|
||||
|
||||
void renderItemList(Inventory * inv,int xo, int yo, int x1, int y1, int selected){
|
||||
// If lastSlot is 0, then there are no items are in the inventory.
|
||||
bool drawCursor = true;
|
||||
if(selected < 0){
|
||||
drawCursor = false;
|
||||
selected = 0;
|
||||
}
|
||||
int w = x1 - xo;
|
||||
int h = y1 - yo - 2;
|
||||
int i1 = inv->lastSlot;
|
||||
if (i1 > h) i1 = h;
|
||||
int io = selected - h / 2;
|
||||
if (io > inv->lastSlot - h) io = inv->lastSlot - h;
|
||||
if (io < 0) io = 0;
|
||||
|
||||
int i;
|
||||
for(i = 0; i < i1; ++i) renderItemWithText(&inv->items[i+io], (1 + xo) << 4, (i + 1 + yo) << 4);
|
||||
|
||||
if(drawCursor){
|
||||
int yy = selected + 1 - io + yo;
|
||||
sf2d_draw_rectangle((xo<<4)-(offsetX<<1),(yy<<4)-(offsetY<<1),12,12,0xFF);
|
||||
drawText(">", (xo << 4), yy << 4);
|
||||
sf2d_draw_rectangle(((xo+w)<<4)-12-(offsetX<<1),(yy<<4)-(offsetY<<1),12,12,0xFF);
|
||||
drawText("<", ((xo+w)<<4)-12, yy<<4);
|
||||
}
|
||||
}
|
||||
|
||||
void renderRecipes(RecipeManager * r,int xo, int yo, int x1, int y1, int selected){
|
||||
int size = r->size;
|
||||
if(size < 1) return;
|
||||
if(selected < 0) selected = 0;
|
||||
int w = x1 - xo;
|
||||
int h = y1 - yo - 2;
|
||||
int i1 = size;
|
||||
if (i1 > h) i1 = h;
|
||||
int io = selected - h / 2;
|
||||
if (io > size - h) io = size - h;
|
||||
if (io < 0) io = 0;
|
||||
|
||||
int i, col;
|
||||
for(i = 0; i < i1; ++i){
|
||||
int x = (1 + xo) << 4, y = (i + 1 + yo) << 4;
|
||||
renderItemIcon(r->recipes[i+io].itemResult,r->recipes[i+io].itemAmountLevel,x>>1,y>>1);
|
||||
if(r->recipes[i+io].canCraft) col = 0xFFFFFFFF;
|
||||
else col = 0x7F7F7FFF;
|
||||
drawTextColor(getBasicItemName(r->recipes[i+io].itemResult,r->recipes[i+io].itemAmountLevel),x+18,y+2,col);
|
||||
}
|
||||
|
||||
int yy = selected + 1 - io + yo;
|
||||
sf2d_draw_rectangle(xo<<4,yy<<4,12,12,0xFF);
|
||||
drawText(">", xo << 4, yy << 4);
|
||||
sf2d_draw_rectangle(((xo+w)<<4)-12,yy<<4,12,12,0xFF);
|
||||
drawText("<", ((xo+w)<<4)-12, yy<<4);
|
||||
}
|
||||
|
||||
void renderItemWithText(Item* item, int x, int y){
|
||||
renderItemIcon(item->id,item->countLevel,x>>1,y>>1);
|
||||
if(item->onlyOne) drawText(getItemName(item->id,item->countLevel),x+18,y+2);
|
||||
else drawTextColorSpecial(getItemName(item->id,item->countLevel),x+18,y+2,0xD2D2D2FF,0xFFFFFFFF);
|
||||
}
|
||||
|
||||
void renderItemIcon2(int itemID, int countLevel, int x, int y, int z){
|
||||
switch(itemID){
|
||||
case ITEM_NULL: return;
|
||||
case TOOL_SHOVEL: renderb(x,y,countLevel*8,144,0,0xFF); break;
|
||||
case TOOL_HOE: renderb(x,y,40+countLevel*8,144,0,0xFF); break;
|
||||
case TOOL_SWORD: renderb(x,y,80+countLevel*8,144,0,0xFF); break;
|
||||
case TOOL_PICKAXE: renderb(x,y,120+countLevel*8,144,0,0xFF); break;
|
||||
case TOOL_AXE: renderb(x,y,160+countLevel*8,144,0,0xFF); break;
|
||||
case ITEM_ANVIL: renderb(x,y,120,152,0,0xFF); break;
|
||||
case ITEM_CHEST: renderb(x,y,128,152,0,0xFF); break;
|
||||
case ITEM_OVEN: renderb(x,y,136,152,0,0xFF); break;
|
||||
case ITEM_FURNACE: renderb(x,y,144,152,0,0xFF); break;
|
||||
case ITEM_WORKBENCH: renderb(x,y,152,152,0,0xFF); break;
|
||||
case ITEM_LANTERN: renderb(x,y,160,152,0,0xFF); break;
|
||||
case ITEM_POWGLOVE: renderb(x,y,56,152,0,0xFF); break;
|
||||
case ITEM_FLOWER: renderb(x,y,0,152,0,0xFF); break;
|
||||
case ITEM_WOOD: renderb(x,y,8,152,0,0xFF); break;
|
||||
case ITEM_STONE: renderb(x,y,16,152,0,0xFF); break;
|
||||
case ITEM_SAND: renderb(x,y,16,152,0,0xFF); break;
|
||||
case ITEM_DIRT: renderb(x,y,16,152,0,0xFF); break;
|
||||
case ITEM_CLOUD: renderb(x,y,16,152,0,0xFF); break;
|
||||
case ITEM_ACORN: renderb(x,y,24,152,0,0xFF); break;
|
||||
case ITEM_CACTUS: renderb(x,y,32,152,0,0xFF); break;
|
||||
case ITEM_SEEDS: renderb(x,y,40,152,0,0xFF); break;
|
||||
case ITEM_WHEAT: renderb(x,y,48,152,0,0xFF); break;
|
||||
case ITEM_FLESH: renderb(x,y,64,152,0,0xFF); break;
|
||||
case ITEM_BREAD: renderb(x,y,72,152,0,0xFF); break;
|
||||
case ITEM_APPLE: renderb(x,y,80,152,0,0xFF); break;
|
||||
case ITEM_SLIME: renderb(x,y,88,152,0,0xFF); break;
|
||||
case ITEM_COAL: renderb(x,y,88,152,0,0xFF); break;
|
||||
case ITEM_IRONORE: renderb(x,y,88,152,0,0xFF); break;
|
||||
case ITEM_GOLDORE: renderb(x,y,88,152,0,0xFF); break;
|
||||
case ITEM_IRONINGOT: renderb(x,y,96,152,0,0xFF); break;
|
||||
case ITEM_GOLDINGOT: renderb(x,y,96,152,0,0xFF); break;
|
||||
case ITEM_GLASS: renderb(x,y,104,152,0,0xFF); break;
|
||||
case ITEM_GEM: renderb(x,y,112,152,0,0xFF); break;
|
||||
}
|
||||
y-=z;
|
||||
renderItemIcon(itemID, countLevel, x, y);
|
||||
}
|
||||
|
||||
void renderItemIcon(int itemID,int countLevel, int x, int y){
|
||||
switch(itemID){
|
||||
case ITEM_NULL: return;
|
||||
case TOOL_SHOVEL: render(x,y,countLevel*8,144,0); break;
|
||||
case TOOL_HOE: render(x,y,40+countLevel*8,144,0); break;
|
||||
case TOOL_SWORD: render(x,y,80+countLevel*8,144,0); break;
|
||||
case TOOL_PICKAXE: render(x,y,120+countLevel*8,144,0); break;
|
||||
case TOOL_AXE: render(x,y,160+countLevel*8,144,0); break;
|
||||
case ITEM_ANVIL: render(x,y,120,152,0); break;
|
||||
case ITEM_CHEST: render(x,y,128,152,0); break;
|
||||
case ITEM_OVEN: render(x,y,136,152,0); break;
|
||||
case ITEM_FURNACE: render(x,y,144,152,0); break;
|
||||
case ITEM_WORKBENCH: render(x,y,152,152,0); break;
|
||||
case ITEM_LANTERN: render(x,y,160,152,0); break;
|
||||
case ITEM_POWGLOVE: render(x,y,56,152,0); break;
|
||||
case ITEM_FLOWER: render(x,y,0,152,0); break;
|
||||
case ITEM_WOOD: render(x,y,8,152,0); break;
|
||||
case ITEM_STONE: renderb(x,y,16,152,0,0xCFCFCFFF); break;
|
||||
case ITEM_SAND: renderb(x,y,16,152,0,0xF7F77BFF); break;
|
||||
case ITEM_DIRT: renderb(x,y,16,152,0,0xAF9781FF); break;
|
||||
case ITEM_CLOUD: renderb(x,y,16,152,0,0xFFFFFFFF); break;
|
||||
case ITEM_ACORN: render(x,y,24,152,0); break;
|
||||
case ITEM_CACTUS: render(x,y,32,152,0); break;
|
||||
case ITEM_SEEDS: render(x,y,40,152,0); break;
|
||||
case ITEM_WHEAT: render(x,y,48,152,0); break;
|
||||
case ITEM_FLESH: render(x,y,64,152,0); break;
|
||||
case ITEM_BREAD: render(x,y,72,152,0); break;
|
||||
case ITEM_APPLE: render(x,y,80,152,0); break;
|
||||
case ITEM_SLIME: renderb(x,y,88,152,0,0x4DC04DFF); break;
|
||||
case ITEM_COAL: renderb(x,y,88,152,0,0x383838FF); break;
|
||||
case ITEM_IRONORE: renderb(x,y,88,152,0,0xBC9999FF); break;
|
||||
case ITEM_GOLDORE: renderb(x,y,88,152,0,0xCECE77FF); break;
|
||||
case ITEM_IRONINGOT: renderb(x,y,96,152,0,0xDFC8C8FF); break;
|
||||
case ITEM_GOLDINGOT: renderb(x,y,96,152,0,0xEAEABCFF); break;
|
||||
case ITEM_GLASS: render(x,y,104,152,0); break;
|
||||
case ITEM_GEM: render(x,y,112,152,0); break;
|
||||
}
|
||||
}
|
||||
|
||||
void defineTables(){
|
||||
|
||||
int i = 0;
|
||||
for(i = 256;i > 0;--i){
|
||||
// Creates the lookup table for the tree tile.
|
||||
if((i&255)==255) treeTable[i] = 208;
|
||||
else if((i&239)==239) treeTable[i] = 144;
|
||||
else if((i&191)==191) treeTable[i] = 160;
|
||||
else if((i&127)==127) treeTable[i] = 176;
|
||||
else if((i&223)==223) treeTable[i] = 192;
|
||||
else if((i&206)==206) treeTable[i] = 112;
|
||||
else if((i&55)==55) treeTable[i] = 128;
|
||||
else if((i&173)==173) treeTable[i] = 96;
|
||||
else if((i&91)==91) treeTable[i] = 80;
|
||||
|
||||
else if((i&159)==159) treeTable[i] = 224;
|
||||
else if((i&111)==111) treeTable[i] = 240;
|
||||
|
||||
else if((i&19)==19) treeTable[i] = 64;
|
||||
else if((i&37)==37) treeTable[i] = 48;
|
||||
else if((i&74)==74) treeTable[i] = 32;
|
||||
else if((i&140)==140) treeTable[i] = 16;
|
||||
}
|
||||
|
||||
/*
|
||||
boolean up = i & 1
|
||||
boolean left = i & 2
|
||||
boolean right = i & 4
|
||||
boolean down = i & 8
|
||||
boolean up-left = i & 16
|
||||
boolean up-right = i & 32
|
||||
boolean down-left = i & 64
|
||||
boolean down-right = i & 128
|
||||
*/
|
||||
|
||||
for(i = 256;i > 0;--i){
|
||||
// Creates the lookup table for the rock tile.
|
||||
if((i&255)==255) rockTable[i] = 208;
|
||||
else if((i&239)==239) rockTable[i] = 144;
|
||||
else if((i&191)==191) rockTable[i] = 160;
|
||||
else if((i&127)==127) rockTable[i] = 176;
|
||||
else if((i&223)==223) rockTable[i] = 192;
|
||||
else if((i&207)==207) rockTable[i] = 256*16+32;
|
||||
else if((i&63)==63) rockTable[i] = 256*16+16;
|
||||
else if((i&206)==206) rockTable[i] = 112;
|
||||
else if((i&95)==95) rockTable[i] = 256*32+144;
|
||||
else if((i&159)==159) rockTable[i] = 256*32+160;
|
||||
else if((i&31)==31) rockTable[i] = 256*32+208;
|
||||
else if((i&55)==55) rockTable[i] = 128;
|
||||
else if((i&175)==175) rockTable[i] = 256*32+128;
|
||||
else if((i&143)==143) rockTable[i] = 256*32+224;
|
||||
else if((i&173)==173) rockTable[i] = 96;
|
||||
else if((i&111)==111) rockTable[i] = 256*32+112;
|
||||
else if((i&47)==47) rockTable[i] = 256*32+48;
|
||||
else if((i&45)==45) rockTable[i] = 256*32+176;
|
||||
else if((i&79)==79) rockTable[i] = 256*32+192;
|
||||
else if((i&23)==23) rockTable[i] = 256*32+96;
|
||||
else if((i&91)==91) rockTable[i] = 80;
|
||||
else if((i&27)==27) rockTable[i] = 256*16+96;
|
||||
else if((i&19)==19) rockTable[i] = 64;
|
||||
else if((i&75)==75) rockTable[i] = 256*32;
|
||||
else if((i&141)==141) rockTable[i] = 256*32+16;
|
||||
else if((i&142)==142) rockTable[i] = 256*32+32;
|
||||
else if((i&78)==78) rockTable[i] = 256*32+64;
|
||||
else if((i&39)==39) rockTable[i] = 256*32+80;
|
||||
else if((i&37)==37) rockTable[i] = 48;
|
||||
else if((i&74)==74) rockTable[i] = 32;
|
||||
else if((i&140)==140) rockTable[i] = 16;
|
||||
else if((i&15)==15) rockTable[i] = 256*16+112;
|
||||
else if((i&11)==11) rockTable[i] = 256*16+192;
|
||||
else if((i&13)==13) rockTable[i] = 256*16+208;
|
||||
else if((i&14)==14) rockTable[i] = 256*16+224;
|
||||
else if((i&7)==7) rockTable[i] = 256*16+240;
|
||||
else if((i&12)==12) rockTable[i] = 256*16+128;
|
||||
else if((i&10)==10) rockTable[i] = 256*16+144;
|
||||
else if((i&5)==5) rockTable[i] = 256*16+160;
|
||||
else if((i&3)==3) rockTable[i] = 256*16+176;
|
||||
else if((i&9)==9) rockTable[i] = 256*16;
|
||||
else if((i&6)==6) rockTable[i] = 256*16+48;
|
||||
else if((i&8)==8) rockTable[i] = 224;
|
||||
else if((i&4)==4) rockTable[i] = 256*16+64;
|
||||
else if((i&2)==2) rockTable[i] = 256*16+80;
|
||||
else if((i&1)==1) rockTable[i] = 240;
|
||||
|
||||
}
|
||||
|
||||
// Lookup table for the grass/sand tile.
|
||||
grassTable[1] = 192;
|
||||
grassTable[2] = 160;
|
||||
grassTable[3] = 64;
|
||||
grassTable[4] = 144;
|
||||
grassTable[5] = 48;
|
||||
grassTable[6] = 224;
|
||||
grassTable[7] = 128;
|
||||
grassTable[8] = 176;
|
||||
grassTable[9] = 240;
|
||||
grassTable[10] = 32;
|
||||
grassTable[11] = 80;
|
||||
grassTable[12] = 16;
|
||||
grassTable[13] = 96;
|
||||
grassTable[14] = 112;
|
||||
grassTable[15] = 208;
|
||||
|
||||
}
|
54
source/Render.h
Normal file
54
source/Render.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
#pragma once
|
||||
#include <3ds.h>
|
||||
#include <sf2d.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include "Globals.h"
|
||||
#include "MapGen.h"
|
||||
|
||||
sf2d_texture *icons;
|
||||
sf2d_texture *font;
|
||||
sf2d_texture *lightScreen;
|
||||
int offsetX, offsetY;
|
||||
|
||||
void render(s32 xp, s32 yp, u32 xTile, u32 yTile, u8 bits);
|
||||
void renderb(s32 xp, s32 yp, u32 xTile, u32 yTile, u8 bits, u32 color);
|
||||
void renderr(s32 xp, s32 yp, u32 xTile, u32 yTile, u8 bits,float rotate);
|
||||
void renderc(s32 xp, s32 yp, u32 xTile, u32 yTile,int sizeX, int sizeY, u8 bits);
|
||||
void renderbc(s32 xp, s32 yp, u32 xTile, u32 yTile,int sizeX, int sizeY, u8 bits, u32 color);
|
||||
void render16(s32 xp, s32 yp, u32 xTile, u32 yTile, u8 bits);
|
||||
void render16c(s32 xp, s32 yp, u32 xTile, u32 yTile, u8 bits,float scaleX,float scaleY);
|
||||
void render16b(s32 xp, s32 yp, u32 xTile, u32 yTile, u8 bits,u32 color);
|
||||
void render16s(s32 xp, s32 yp, u32 tile, u8 bits,u32 color);
|
||||
|
||||
void renderTitle(int x, int y);
|
||||
void renderFrame(int x1, int y1, int x2, int y2, u32 bgColor);
|
||||
void renderTile(int i, int x, int y);
|
||||
void renderBackground(int xScroll, int yScroll);
|
||||
void renderButtonIcon(u32 icon, int x, int y, float scale);
|
||||
|
||||
void renderLights();
|
||||
void renderLight(int x, int y, int r);
|
||||
void renderLightScreen();
|
||||
|
||||
void renderGui();
|
||||
void renderPlayer();
|
||||
|
||||
void drawText(char * msg, u32 x, u32 y);
|
||||
void drawSizedText(char * msg, u32 x, u32 y, float size);
|
||||
void drawTextColor(char * msg, u32 x, u32 y, u32 color);
|
||||
void drawTextColorSpecial(char * msg, u32 x, u32 y, u32 color, u32 color2);
|
||||
void drawSizedTextColor(char * msg, int x, int y, float size, u32 color);
|
||||
|
||||
void renderFurniture(int itemID, int x, int y);
|
||||
void renderEntity(Entity* e, int x, int y);
|
||||
void renderEntities(int x, int y, EntityManager* em);
|
||||
|
||||
void renderRecipes(RecipeManager * r,int xo, int yo, int x1, int y1, int selected);
|
||||
void renderItemList(Inventory * inv,int xo, int yo, int x1, int y1, int selected);
|
||||
void renderItemWithText(Item* item, int x, int y);
|
||||
void renderItemIcon(int itemID, int countLevel, int x, int y);
|
||||
void renderItemIcon2(int itemID, int countLevel, int x, int y, int z);
|
||||
|
||||
void defineTables();
|
251
source/SaveLoad.c
Normal file
251
source/SaveLoad.c
Normal file
|
@ -0,0 +1,251 @@
|
|||
#include "SaveLoad.h"
|
||||
|
||||
s16 calculateImportantEntites(EntityManager * eManager, int level){
|
||||
int i;
|
||||
s16 count = 0;
|
||||
for(i = 0; i < eManager->lastSlot[level]; ++i){
|
||||
switch(eManager->entities[level][i].type){
|
||||
case ENTITY_AIRWIZARD:
|
||||
case ENTITY_SLIME:
|
||||
case ENTITY_ZOMBIE:
|
||||
case ENTITY_ITEM:
|
||||
case ENTITY_FURNITURE:
|
||||
count++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
bool entityIsImportant(Entity * e){
|
||||
switch(e->type){
|
||||
case ENTITY_AIRWIZARD:
|
||||
case ENTITY_SLIME:
|
||||
case ENTITY_ZOMBIE:
|
||||
case ENTITY_ITEM:
|
||||
case ENTITY_FURNITURE:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void saveCurrentWorld(char * filename, EntityManager * eManager, Entity * player, u8 * map, u8 * mapData){
|
||||
FILE * file = fopen(filename, "wb");
|
||||
int i,j;
|
||||
|
||||
// Player Data
|
||||
fwrite(&player->p.score, sizeof(int), 1, file);
|
||||
fwrite(&player->p.hasWonSaved, sizeof(bool), 1, file);
|
||||
fwrite(&player->p.health, sizeof(s16), 1, file);
|
||||
fwrite(&player->x, sizeof(s16), 1, file);
|
||||
fwrite(&player->y, sizeof(s16), 1, file);
|
||||
fwrite(¤tLevel, sizeof(s8), 1, file);
|
||||
|
||||
// Inventory Data
|
||||
fwrite(&eManager->nextInv, sizeof(s16), 1, file); // write amount of inventories.
|
||||
for(i = 0; i < eManager->nextInv; ++i) {
|
||||
fwrite(&eManager->invs[i].lastSlot, sizeof(s16), 1, file); // write amount of items in inventory;
|
||||
for(j = 0; j < eManager->invs[i].lastSlot; ++j) {
|
||||
fwrite(&eManager->invs[i].items[j].id, sizeof(s16), 1, file); // write ID of item
|
||||
fwrite(&eManager->invs[i].items[j].countLevel, sizeof(s16), 1, file); // write count/level of item
|
||||
fwrite(&eManager->invs[i].items[j].onlyOne, sizeof(bool), 1, file);
|
||||
if(eManager->invs[i].items[j].id == ITEM_CHEST){
|
||||
int invIndex = eManager->invs[i].items[j].chestPtr - eManager->invs;
|
||||
fwrite(&invIndex, sizeof(int), 1, file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Entity Data
|
||||
for(i = 0; i < 5; ++i){
|
||||
int amount = calculateImportantEntites(eManager,i);
|
||||
fwrite(&amount, sizeof(s16), 1, file); // read amount of entities in level.
|
||||
for(j = 0; j < eManager->lastSlot[i]; ++j){
|
||||
if(!entityIsImportant(&eManager->entities[i][j])) continue;
|
||||
fwrite(&eManager->entities[i][j].type, sizeof(s16), 1, file); // write entity's type ID
|
||||
fwrite(&eManager->entities[i][j].x, sizeof(s16), 1, file); // write entity's x coordinate
|
||||
fwrite(&eManager->entities[i][j].y, sizeof(s16), 1, file); // write entity's y coordinate
|
||||
switch(eManager->entities[i][j].type){
|
||||
case ENTITY_AIRWIZARD:
|
||||
fwrite(&eManager->entities[i][j].wizard.health, sizeof(s16), 1, file);
|
||||
break;
|
||||
case ENTITY_SLIME:
|
||||
fwrite(&eManager->entities[i][j].slime.health, sizeof(s16), 1, file);
|
||||
fwrite(&eManager->entities[i][j].slime.lvl, sizeof(s8), 1, file);
|
||||
break;
|
||||
case ENTITY_ZOMBIE:
|
||||
fwrite(&eManager->entities[i][j].zombie.health, sizeof(s16), 1, file);
|
||||
fwrite(&eManager->entities[i][j].zombie.lvl, sizeof(s8), 1, file);
|
||||
break;
|
||||
case ENTITY_ITEM:
|
||||
fwrite(&eManager->entities[i][j].entityItem.item.id, sizeof(s16), 1, file);
|
||||
fwrite(&eManager->entities[i][j].entityItem.item.countLevel, sizeof(s16), 1, file);
|
||||
fwrite(&eManager->entities[i][j].entityItem.age, sizeof(s16), 1, file);
|
||||
break;
|
||||
case ENTITY_FURNITURE:
|
||||
fwrite(&eManager->entities[i][j].entityFurniture.itemID, sizeof(s16), 1, file);
|
||||
int invIndex = eManager->entities[i][j].entityFurniture.inv - eManager->invs;
|
||||
fwrite(&invIndex, sizeof(int), 1, file);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Map Data
|
||||
fwrite(map, sizeof(u8), 128*128*5, file); // Map Tile IDs, 128*128*5 bytes = 80KB
|
||||
fwrite(mapData, sizeof(u8), 128*128*5, file); // Map Tile Data (Damage done to trees/rocks, age of wheat & saplings, etc). 80KB
|
||||
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
int loadWorld(char * filename, EntityManager * eManager, Entity * player, u8 * map, u8 * mapData){
|
||||
FILE * file;
|
||||
int i,j;
|
||||
|
||||
if ((file = fopen(filename, "rb"))){
|
||||
|
||||
fread(&player->p.score, sizeof(int), 1, file);
|
||||
fread(&player->p.hasWonSaved, sizeof(bool), 1, file);
|
||||
fread(&player->p.health, sizeof(s16), 1, file);
|
||||
fread(&player->x, sizeof(s16), 1, file);
|
||||
fread(&player->y, sizeof(s16), 1, file);
|
||||
fread(¤tLevel, sizeof(s8), 1, file);
|
||||
|
||||
fread(&eManager->nextInv, sizeof(s16), 1, file);
|
||||
for(i = 0; i < eManager->nextInv; ++i) {
|
||||
fread(&eManager->invs[i].lastSlot, sizeof(s16), 1, file); // read amount of items in inventory;
|
||||
for(j = 0; j < eManager->invs[i].lastSlot; ++j) {
|
||||
fread(&eManager->invs[i].items[j].id, sizeof(s16), 1, file); // write ID of item
|
||||
fread(&eManager->invs[i].items[j].countLevel, sizeof(s16), 1, file); // write count/level of item
|
||||
fread(&eManager->invs[i].items[j].onlyOne, sizeof(bool), 1, file);
|
||||
eManager->invs[i].items[j].invPtr = (int*)&eManager->invs[i]; // setup Inventory pointer
|
||||
eManager->invs[i].items[j].slotNum = j; // setup slot number
|
||||
if(eManager->invs[i].items[j].id == ITEM_CHEST){ // for chest item specifically.
|
||||
int invIndex;
|
||||
fread(&invIndex, sizeof(int), 1, file);
|
||||
eManager->invs[i].items[j].chestPtr = (Inventory*)&eManager->invs[invIndex]; // setup chest inventory pointer.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(i = 0; i < 5; ++i){
|
||||
fread(&eManager->lastSlot[i], sizeof(s16), 1, file); // read amount of entities in level.
|
||||
for(j = 0; j < eManager->lastSlot[i]; ++j){
|
||||
fread(&eManager->entities[i][j].type, sizeof(s16), 1, file); // read entity's type ID
|
||||
fread(&eManager->entities[i][j].x, sizeof(s16), 1, file); // read entity's x coordinate
|
||||
fread(&eManager->entities[i][j].y, sizeof(s16), 1, file); // read entity's y coordinate
|
||||
eManager->entities[i][j].slotNum = j;
|
||||
switch(eManager->entities[i][j].type){
|
||||
case ENTITY_SMASHPARTICLE:
|
||||
eManager->entities[i][j].level = i;
|
||||
eManager->entities[i][j].smashParticle.age = 300;
|
||||
eManager->entities[i][j].canPass = true;
|
||||
break;
|
||||
case ENTITY_TEXTPARTICLE:
|
||||
eManager->entities[i][j].level = i;
|
||||
eManager->entities[i][j].canPass = true;
|
||||
eManager->entities[i][j].textParticle.age = 59;
|
||||
eManager->entities[i][j].textParticle.text = NULL;
|
||||
eManager->entities[i][j].textParticle.xx = eManager->entities[i][j].x;
|
||||
eManager->entities[i][j].textParticle.yy = eManager->entities[i][j].y;
|
||||
eManager->entities[i][j].textParticle.zz = 2;
|
||||
eManager->entities[i][j].textParticle.xa = 0;
|
||||
eManager->entities[i][j].textParticle.ya = 0;
|
||||
eManager->entities[i][j].textParticle.za = 0;
|
||||
break;
|
||||
case ENTITY_SPARK:
|
||||
eManager->entities[i][j].level = i;
|
||||
eManager->entities[i][j].spark.age = 300;
|
||||
break;
|
||||
case ENTITY_AIRWIZARD:
|
||||
fread(&eManager->entities[i][j].wizard.health, sizeof(s16), 1, file);
|
||||
eManager->entities[i][j].level = i;
|
||||
eManager->entities[i][j].hurtTime = 0;
|
||||
eManager->entities[i][j].xKnockback = 0;
|
||||
eManager->entities[i][j].yKnockback = 0;
|
||||
eManager->entities[i][j].wizard.dir = 0;
|
||||
eManager->entities[i][j].wizard.attackDelay = 0;
|
||||
eManager->entities[i][j].wizard.attackTime = 0;
|
||||
eManager->entities[i][j].wizard.attackType = 0;
|
||||
eManager->entities[i][j].wizard.xa = 0;
|
||||
eManager->entities[i][j].wizard.ya = 0;
|
||||
eManager->entities[i][j].xr = 4;
|
||||
eManager->entities[i][j].yr = 3;
|
||||
eManager->entities[i][j].canPass = true;
|
||||
break;
|
||||
case ENTITY_SLIME:
|
||||
fread(&eManager->entities[i][j].slime.health, sizeof(s16), 1, file);
|
||||
fread(&eManager->entities[i][j].slime.lvl, sizeof(s8), 1, file);
|
||||
eManager->entities[i][j].level = i;
|
||||
eManager->entities[i][j].hurtTime = 0;
|
||||
eManager->entities[i][j].xKnockback = 0;
|
||||
eManager->entities[i][j].yKnockback = 0;
|
||||
eManager->entities[i][j].slime.xa = 0;
|
||||
eManager->entities[i][j].slime.ya = 0;
|
||||
eManager->entities[i][j].slime.dir = 0;
|
||||
eManager->entities[i][j].xr = 4;
|
||||
eManager->entities[i][j].yr = 3;
|
||||
eManager->entities[i][j].canPass = false;
|
||||
switch(eManager->entities[i][j].slime.lvl){
|
||||
case 2: eManager->entities[i][j].slime.color = 0xCC8282FF; break;
|
||||
case 3: eManager->entities[i][j].slime.color = 0xEFEFEFFF; break;
|
||||
case 4: eManager->entities[i][j].slime.color = 0x6262AAFF; break;
|
||||
default: eManager->entities[i][j].slime.color = 0x95DB95FF; break;
|
||||
}
|
||||
break;
|
||||
case ENTITY_ZOMBIE:
|
||||
fread(&eManager->entities[i][j].zombie.health, sizeof(s16), 1, file);
|
||||
fread(&eManager->entities[i][j].zombie.lvl, sizeof(s8), 1, file);
|
||||
eManager->entities[i][j].level = i;
|
||||
eManager->entities[i][j].hurtTime = 0;
|
||||
eManager->entities[i][j].xKnockback = 0;
|
||||
eManager->entities[i][j].yKnockback = 0;
|
||||
eManager->entities[i][j].zombie.dir = 0;
|
||||
eManager->entities[i][j].xr = 4;
|
||||
eManager->entities[i][j].yr = 3;
|
||||
eManager->entities[i][j].canPass = false;
|
||||
switch(eManager->entities[i][j].zombie.lvl){
|
||||
case 2: eManager->entities[i][j].zombie.color = 0xCC8282FF; break;
|
||||
case 3: eManager->entities[i][j].zombie.color = 0xEFEFEFFF; break;
|
||||
case 4: eManager->entities[i][j].zombie.color = 0x6262AAFF; break;
|
||||
default: eManager->entities[i][j].zombie.color = 0x95DB95FF; break;
|
||||
}
|
||||
break;
|
||||
case ENTITY_ITEM:
|
||||
//eManager->entities[i][j].entityItem.item = newItem(0,0);
|
||||
fread(&eManager->entities[i][j].entityItem.item.id, sizeof(s16), 1, file);
|
||||
fread(&eManager->entities[i][j].entityItem.item.countLevel, sizeof(s16), 1, file);
|
||||
fread(&eManager->entities[i][j].entityItem.age, sizeof(s16), 1, file);
|
||||
eManager->entities[i][j].level = i;
|
||||
eManager->entities[i][j].entityItem.age = 0;
|
||||
eManager->entities[i][j].xr = 3;
|
||||
eManager->entities[i][j].yr = 3;
|
||||
eManager->entities[i][j].canPass = false;
|
||||
eManager->entities[i][j].entityItem.xx = eManager->entities[i][j].x;
|
||||
eManager->entities[i][j].entityItem.yy = eManager->entities[i][j].y;
|
||||
eManager->entities[i][j].entityItem.zz = 2;
|
||||
eManager->entities[i][j].entityItem.xa = 0;
|
||||
eManager->entities[i][j].entityItem.ya = 0;
|
||||
eManager->entities[i][j].entityItem.za = 0;
|
||||
break;
|
||||
case ENTITY_FURNITURE:
|
||||
fread(&eManager->entities[i][j].entityFurniture.itemID, sizeof(s16), 1, file);
|
||||
int invIndex;
|
||||
fread(&invIndex, sizeof(int), 1, file);
|
||||
eManager->entities[i][j].entityFurniture.inv = &eManager->invs[invIndex];
|
||||
eManager->entities[i][j].xr = 3;
|
||||
eManager->entities[i][j].yr = 3;
|
||||
eManager->entities[i][j].canPass = false;
|
||||
if(eManager->entities[i][j].entityFurniture.itemID == ITEM_LANTERN) eManager->entities[i][j].entityFurniture.r = 8;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
fread(map, sizeof(u8), 128*128*5, file);
|
||||
fread(mapData, sizeof(u8), 128*128*5, file);
|
||||
fclose(file);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
7
source/SaveLoad.h
Normal file
7
source/SaveLoad.h
Normal file
|
@ -0,0 +1,7 @@
|
|||
#pragma once
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "Entity.h"
|
||||
|
||||
void saveCurrentWorld(char * filename, EntityManager * eManager, Entity * player, u8 * map, u8 * mapData);
|
||||
int loadWorld(char * filename, EntityManager * eManager, Entity * player, u8 * map, u8 * mapData);
|
27
source/Sound.c
Normal file
27
source/Sound.c
Normal file
|
@ -0,0 +1,27 @@
|
|||
#include "Sound.h"
|
||||
|
||||
void loadSound(Sound * snd, char * filename){
|
||||
FILE *file = fopen(filename, "rb");
|
||||
if(file != NULL){
|
||||
fseek(file, 0, SEEK_END);
|
||||
snd->size = ftell(file);
|
||||
fseek(file, 0, SEEK_SET);
|
||||
snd->buffer = linearAlloc(snd->size);
|
||||
fread(snd->buffer, 1, snd->size, file);
|
||||
}
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
void playSound(Sound snd){
|
||||
csndPlaySound(8, SOUND_FORMAT_16BIT | SOUND_ONE_SHOT, 44100, 1, 0, snd.buffer, snd.buffer, snd.size);
|
||||
}
|
||||
|
||||
void freeSounds(){
|
||||
linearFree(snd_playerHurt.buffer);
|
||||
linearFree(snd_playerDeath.buffer);
|
||||
linearFree(snd_monsterHurt.buffer);
|
||||
linearFree(snd_test.buffer);
|
||||
linearFree(snd_pickup.buffer);
|
||||
linearFree(snd_bossdeath.buffer);
|
||||
linearFree(snd_craft.buffer);
|
||||
}
|
23
source/Sound.h
Normal file
23
source/Sound.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
#pragma once
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <3ds.h>
|
||||
|
||||
|
||||
typedef struct {
|
||||
u32 size;
|
||||
u8 * buffer;
|
||||
} Sound;
|
||||
|
||||
void loadSound(Sound * snd, char * filename);
|
||||
void playSound(Sound snd);
|
||||
void freeSounds();
|
||||
|
||||
Sound snd_playerHurt;
|
||||
Sound snd_playerDeath;
|
||||
Sound snd_monsterHurt;
|
||||
Sound snd_test;
|
||||
Sound snd_pickup;
|
||||
Sound snd_bossdeath;
|
||||
Sound snd_craft;
|
279
source/main.c
Normal file
279
source/main.c
Normal file
|
@ -0,0 +1,279 @@
|
|||
#include <3ds.h>
|
||||
#include <sf2d.h>
|
||||
#include <sfil.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "icons2_png.h"
|
||||
#include "Font_png.h"
|
||||
|
||||
#include "Globals.h"
|
||||
#include "Render.h"
|
||||
#include "MapGen.h"
|
||||
#include "Menu.h"
|
||||
|
||||
|
||||
void initMiniMap(bool loadUpWorld){
|
||||
int i,x,y;
|
||||
for(i=0;i<5;++i){
|
||||
for(x=0;x < 128;++x){
|
||||
for(y=0;y < 128;++y){
|
||||
|
||||
if(!loadUpWorld){ // generate stairs up when making a new world.
|
||||
switch(map[i][x+y*128]){
|
||||
case TILE_STAIRS_DOWN:
|
||||
map[i+1][x+y*128] = TILE_STAIRS_UP;
|
||||
if(i == 0){
|
||||
map[i+1][(x+1)+y*128] = TILE_HARDROCK;
|
||||
map[i+1][x+(y+1)*128] = TILE_HARDROCK;
|
||||
map[i+1][(x-1)+y*128] = TILE_HARDROCK;
|
||||
map[i+1][x+(y-1)*128] = TILE_HARDROCK;
|
||||
map[i+1][(x+1)+(y+1)*128] = TILE_HARDROCK;
|
||||
map[i+1][(x-1)+(y-1)*128] = TILE_HARDROCK;
|
||||
map[i+1][(x-1)+(y+1)*128] = TILE_HARDROCK;
|
||||
map[i+1][(x+1)+(y-1)*128] = TILE_HARDROCK;
|
||||
} else {
|
||||
map[i+1][(x+1)+y*128] = TILE_DIRT;
|
||||
map[i+1][x+(y+1)*128] = TILE_DIRT;
|
||||
map[i+1][(x-1)+y*128] = TILE_DIRT;
|
||||
map[i+1][x+(y-1)*128] = TILE_DIRT;
|
||||
map[i+1][(x+1)+(y+1)*128] = TILE_DIRT;
|
||||
map[i+1][(x-1)+(y-1)*128] = TILE_DIRT;
|
||||
map[i+1][(x-1)+(y+1)*128] = TILE_DIRT;
|
||||
map[i+1][(x+1)+(y-1)*128] = TILE_DIRT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Minimaps */
|
||||
switch(map[i][x+y*128]){
|
||||
case TILE_WATER: sf2d_set_pixel (minimap[i], x, y, 0xFFFF0000); break;
|
||||
case TILE_LAVA: sf2d_set_pixel (minimap[i], x, y, 0xFF0000FF); break;
|
||||
case TILE_DIRT: sf2d_set_pixel (minimap[i], x, y, 0xFF6C6D82); break;
|
||||
case TILE_ROCK: sf2d_set_pixel (minimap[i], x, y, 0xFF7F7F7F); break;
|
||||
case TILE_HARDROCK: sf2d_set_pixel (minimap[i], x, y, 0xFF7F5F5F); break;
|
||||
case TILE_GRASS: sf2d_set_pixel (minimap[i], x, y, 0xFF00FF00); break;
|
||||
case TILE_TREE: sf2d_set_pixel (minimap[i], x, y, 0xFF007F00); break;
|
||||
case TILE_SAND: sf2d_set_pixel (minimap[i], x, y, 0xFF00FFFF); break;
|
||||
case TILE_CACTUS: sf2d_set_pixel (minimap[i], x, y, 0xFF009F00); break;
|
||||
case TILE_FLOWER: sf2d_set_pixel (minimap[i], x, y, 0xFF00FF3F); break;
|
||||
case TILE_IRONORE: sf2d_set_pixel (minimap[i], x, y, 0xFF9696DC); break;
|
||||
case TILE_GOLDORE: sf2d_set_pixel (minimap[i], x, y, 0xFF9AE8E5); break;
|
||||
case TILE_GEMORE: sf2d_set_pixel (minimap[i], x, y, 0xFFDE98DF); break;
|
||||
case TILE_CLOUD: sf2d_set_pixel (minimap[i], x, y, 0xFFFFFFFF); break;
|
||||
case TILE_CLOUDCACTUS: sf2d_set_pixel (minimap[i], x, y, 0xFFAFAFAF); break;
|
||||
case TILE_STAIRS_DOWN: sf2d_set_pixel (minimap[i], x, y, 0xFF9F9F9F); break;
|
||||
case TILE_STAIRS_UP: sf2d_set_pixel (minimap[i], x, y, 0xFF9F9F9F); break;
|
||||
default: sf2d_set_pixel (minimap[i], x, y, 0xFF111111); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void initNewMap(){
|
||||
newSeed();
|
||||
createAndValidateSkyMap(128,128,map[0],data[0]);
|
||||
createAndValidateTopMap(128,128,map[1],data[1]);
|
||||
createAndValidateUndergroundMap(128,128,1,map[2],data[2]);
|
||||
createAndValidateUndergroundMap(128,128,2,map[3],data[3]);
|
||||
createAndValidateUndergroundMap(128,128,3,map[4],data[4]);
|
||||
}
|
||||
|
||||
void setupGame(bool loadUpWorld){
|
||||
currentLevel = 1;
|
||||
|
||||
// Reset entity manager.
|
||||
memset(&eManager, 0, sizeof(eManager));
|
||||
sf2d_set_clear_color(RGBA8(0x82, 0x6D, 0x6C, 0xFF));
|
||||
|
||||
if(!loadUpWorld){
|
||||
initNewMap();
|
||||
initPlayer();
|
||||
airWizardHealthDisplay = 2000;
|
||||
int i;
|
||||
for(i=0;i<5;++i){
|
||||
trySpawn(500, i);
|
||||
}
|
||||
addEntityToList(newAirWizardEntity(630,820,0), &eManager);
|
||||
} else {
|
||||
initPlayer();
|
||||
loadWorld(currentFileName, &eManager, &player, (u8*)map, (u8*)data);
|
||||
}
|
||||
|
||||
initMiniMap(loadUpWorld);
|
||||
initGame = 0;
|
||||
}
|
||||
|
||||
|
||||
int xscr=0, yscr=0;
|
||||
void tick(){
|
||||
if(player.p.isDead){
|
||||
if(player.p.endTimer < 1){
|
||||
currentMenu = MENU_LOSE;
|
||||
}
|
||||
--player.p.endTimer;
|
||||
return;
|
||||
} else if(player.p.hasWon){
|
||||
if(player.p.endTimer < 1){
|
||||
currentMenu = MENU_WIN;
|
||||
}
|
||||
--player.p.endTimer;
|
||||
return;
|
||||
}
|
||||
|
||||
int i;
|
||||
for(i = 0;i < 324;++i){
|
||||
int xx = rand() & 127;
|
||||
int yy = rand() & 127;
|
||||
tickTile(xx,yy);
|
||||
}
|
||||
tickPlayer();
|
||||
xscr = player.x - 100;
|
||||
yscr = player.y - 56;
|
||||
if (xscr < 16) xscr = 16; else if (xscr > 1832) xscr = 1832;
|
||||
if (yscr < 16) yscr = 16; else if (yscr > 1912) yscr = 1912;
|
||||
|
||||
for(i = 0; i < eManager.lastSlot[currentLevel]; ++i){
|
||||
Entity * e = &eManager.entities[currentLevel][i];
|
||||
if((e->type != ENTITY_ZOMBIE && e->type != ENTITY_SLIME) || (e->x > player.x-160 && e->y > player.y-125 && e->x<player.x+160 && e->y<player.y+125)) tickEntity(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void clearScreen(int* data, u8 fill, int size){
|
||||
int i;
|
||||
for (i=0; i < size/4; ++i) data[i] = 0x000000FF;
|
||||
}
|
||||
|
||||
|
||||
char debugText[34];
|
||||
char bossHealthText[34];
|
||||
int main()
|
||||
{
|
||||
sf2d_init();
|
||||
csndInit();
|
||||
noItem = newItem(ITEM_NULL,0);
|
||||
|
||||
currentMenu = MENU_TITLE;
|
||||
currentSelection = 0;
|
||||
quitGame = false;
|
||||
|
||||
icons = sfil_load_PNG_buffer(icons2_png, SF2D_PLACE_RAM);
|
||||
font = sfil_load_PNG_buffer(Font_png, SF2D_PLACE_RAM);
|
||||
|
||||
//consoleInit(GFX_BOTTOM, NULL);
|
||||
// printf("Press 'Start' to exit.\n");
|
||||
|
||||
loadSound(&snd_playerHurt, "resources/playerhurt.raw");
|
||||
loadSound(&snd_playerDeath, "resources/playerdeath.raw");
|
||||
loadSound(&snd_monsterHurt, "resources/monsterhurt.raw");
|
||||
loadSound(&snd_test, "resources/test.raw");
|
||||
loadSound(&snd_pickup, "resources/pickup.raw");
|
||||
loadSound(&snd_bossdeath, "resources/bossdeath.raw");
|
||||
loadSound(&snd_craft, "resources/craft.raw");
|
||||
|
||||
int i;
|
||||
for(i = 0;i < 5;++i){
|
||||
minimap[i] = sf2d_create_texture(128,128,TEXFMT_RGBA8,SF2D_PLACE_RAM);
|
||||
sf2d_texture_tile32(minimap[i]);
|
||||
}
|
||||
|
||||
sf2d_set_vblank_wait(true);
|
||||
|
||||
sf2d_set_clear_color(0xFF);
|
||||
|
||||
/* Default inputs */
|
||||
k_up.input = KEY_DUP | KEY_CPAD_UP | KEY_CSTICK_UP;
|
||||
k_down.input = KEY_DDOWN | KEY_CPAD_DOWN | KEY_CSTICK_DOWN;
|
||||
k_left.input = KEY_DLEFT | KEY_CPAD_LEFT | KEY_CSTICK_LEFT;
|
||||
k_right.input = KEY_DRIGHT | KEY_CPAD_RIGHT | KEY_CSTICK_RIGHT;
|
||||
k_attack.input = KEY_A | KEY_B | KEY_L | KEY_ZR;
|
||||
k_menu.input = KEY_X | KEY_Y | KEY_R | KEY_ZL;
|
||||
k_pause.input = KEY_START;
|
||||
k_accept.input = KEY_A;
|
||||
k_decline.input = KEY_B;
|
||||
k_delete.input = KEY_X;
|
||||
FILE * file;
|
||||
|
||||
/* If btnSave exists, then use that. */
|
||||
if ((file = fopen("btnSave.bin", "rb"))){
|
||||
fread(&k_up.input, sizeof(int), 1, file);
|
||||
fread(&k_down.input, sizeof(int), 1, file);
|
||||
fread(&k_left.input, sizeof(int), 1, file);
|
||||
fread(&k_right.input, sizeof(int), 1, file);
|
||||
fread(&k_attack.input, sizeof(int), 1, file);
|
||||
fread(&k_menu.input, sizeof(int), 1, file);
|
||||
fread(&k_pause.input, sizeof(int), 1, file);
|
||||
fread(&k_accept.input, sizeof(int), 1, file);
|
||||
fread(&k_decline.input, sizeof(int), 1, file);
|
||||
fread(&k_delete.input, sizeof(int), 1, file);
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
//screenShot = false;
|
||||
|
||||
tickCount=0;
|
||||
initRecipes();
|
||||
defineTables();
|
||||
while (aptMainLoop()) {
|
||||
++tickCount;
|
||||
hidScanInput();
|
||||
tickKeys(hidKeysHeld(),hidKeysDown());
|
||||
|
||||
//if (quitGame || hidKeysHeld() & KEY_SELECT) break;
|
||||
if (quitGame) break;
|
||||
//if (hidKeysDown() & (KEY_L | KEY_R)) screenShot = true;
|
||||
// else screenShot = false;
|
||||
|
||||
if(initGame > 0) setupGame(initGame == 1 ? true : false);
|
||||
|
||||
if(currentMenu == 0){
|
||||
tick();
|
||||
sprintf(fpsstr, " FPS: %.0f, X:%d, Y:%d, E:%d", sf2d_get_fps(),player.x, player.y,eManager.lastSlot[currentLevel]);
|
||||
sf2d_start_frame(GFX_TOP, GFX_LEFT);
|
||||
if(currentLevel == 0){
|
||||
sf2d_draw_texture_part_scale(minimap[1],(-xscr/3)-256,(-yscr/3)-32,0,0,128,128,12.5,7.5);
|
||||
sf2d_draw_rectangle(0,0,400,240, 0xDFDFDFAF);
|
||||
}
|
||||
offsetX = xscr;offsetY = yscr;
|
||||
renderBackground(xscr,yscr);
|
||||
renderEntities(player.x, player.y, &eManager);
|
||||
renderPlayer();
|
||||
offsetX = 0;offsetY = 0;
|
||||
renderItemWithText(player.p.activeItem, 10, 205);
|
||||
// drawText(debugText,2,208);
|
||||
drawText(fpsstr,2,225);
|
||||
sf2d_end_frame();
|
||||
|
||||
sf2d_start_frame(GFX_BOTTOM, GFX_LEFT);
|
||||
if(currentLevel == 0 && airWizardHealthDisplay > 0){
|
||||
sprintf(bossHealthText, "BOSS: %.0f%%", ((float)airWizardHealthDisplay/2000.0)*100);
|
||||
drawText(bossHealthText,2,225);
|
||||
}
|
||||
renderGui();
|
||||
sf2d_draw_texture(minimap[currentLevel], 192, 112);//y:56
|
||||
sf2d_end_frame();
|
||||
} else{
|
||||
tickMenu(currentMenu);
|
||||
renderMenu(currentMenu,xscr,yscr);
|
||||
}
|
||||
|
||||
sf2d_swapbuffers();
|
||||
}
|
||||
|
||||
freeRecipes();
|
||||
sf2d_free_texture(icons);
|
||||
sf2d_free_texture(minimap[0]);
|
||||
sf2d_free_texture(minimap[1]);
|
||||
sf2d_free_texture(minimap[2]);
|
||||
sf2d_free_texture(minimap[3]);
|
||||
sf2d_free_texture(minimap[4]);
|
||||
freeSounds();
|
||||
csndExit();
|
||||
sf2d_fini();
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Reference in a new issue