Compare commits

..

56 Commits

Author SHA1 Message Date
6bbe7a7970 Update haloo3d 2024-09-24 23:12:37 -04:00
e72d10925c Working on ps2 for real (terrain) 2024-09-23 23:39:34 -04:00
0bc14e3ea8 Moved clouds back up 2024-09-23 13:53:11 -04:00
d636d35f38 More color diffs 2024-09-23 02:25:46 -04:00
cb75c48a80 Sand 2024-09-23 02:00:55 -04:00
2c0c4c485d Gradient sky 2024-09-22 20:41:05 -04:00
8284f29be2 Small cleanup 2024-09-22 17:38:19 -04:00
c52bf93daf Less frequent towers 2024-09-22 17:27:36 -04:00
51addcae02 Colored terrain 1 2024-09-22 17:00:11 -04:00
7b03cd0aa6 Tower constants 2024-09-22 14:20:36 -04:00
e4789d6156 Towers with lights 2024-09-21 23:32:37 -04:00
ee8d4635fa Generate tower 2024-09-21 21:19:43 -04:00
29e73a36b8 sky color tweak 2024-09-21 14:27:50 -04:00
cf228eee94 Fixed flower colors 2024-09-21 14:21:42 -04:00
5966782b90 More sane flower spawning? 2024-09-21 09:41:19 -04:00
8a1534004c Crazy flowers 2024-09-21 09:26:52 -04:00
20a8c65266 Setting up flower generation 2024-09-21 08:54:58 -04:00
dcca92ee43 Normalized some stuff 2024-09-21 02:54:24 -04:00
2cef922233 Render more in terrain 2024-09-21 01:28:59 -04:00
3ef1233ee5 Finally fixed makefile not rebuilding haloo3d 2024-09-21 00:55:27 -04:00
8457fdbe39 Move old unused projects 2024-09-21 00:42:59 -04:00
5b437adf8e Cleanup 2024-09-21 00:38:46 -04:00
29358c9258 Limited printing option 2024-09-21 00:15:10 -04:00
31ccf3c218 Ps2 (so slow) 2024-09-20 23:54:40 -04:00
1db028c814 Clouds! 2024-09-20 23:37:58 -04:00
a1182995ae Better tree spawning (getting mem error) 2024-09-20 19:33:53 -04:00
1f3b6a973d Lots of trees (ugly) 2024-09-20 03:05:45 -04:00
a2d38044f0 Tree model test 2024-09-20 02:22:27 -04:00
ccc017c647 Clear water 2024-09-19 22:33:53 -04:00
300bdb3e31 A working flyover (fast) 2024-09-19 21:34:05 -04:00
96cc0a246c Trying to make terrain work with ocean 2024-09-19 20:27:49 -04:00
a009fd3749 Face down 2024-09-19 05:33:21 -04:00
787786bfa4 Sea that follows you 2024-09-19 04:13:39 -04:00
ff826b1806 Fixed realloc causing segfault (it wasn't realloc) 2024-09-18 23:11:15 -04:00
c0f1685cbb Fixed everything? Time for terrain! 2024-09-14 04:34:19 -04:00
082a084971 CHUNKS BEFORE SEGFAULT 2024-09-14 03:42:59 -04:00
9511c07f3e There's SOME output! 2024-09-14 03:30:53 -04:00
a17ef2d379 Terrain ecs is taking a lot 2024-09-14 01:00:20 -04:00
dd68a9115e Fixed for new unigi 2024-09-12 23:41:54 -04:00
0ff396757b Merge branch 'master' into terrain 2024-09-12 23:37:48 -04:00
8ffad9e6b9 Fully working maze on ps2 thank you unigi 2024-09-12 13:58:08 -04:00
aa65ae8142 FINALLY WORKING 2024-09-12 05:00:19 -04:00
1de3a60aef It runs on the ps2, barely (broken) 2024-09-12 04:46:47 -04:00
93d9113451 Setting up more ps2 (but it doesn't work) 2024-09-12 03:50:38 -04:00
7b530a67f1 Submodules might be ok 2024-09-12 03:28:43 -04:00
2a8cb45651 Having trouble with submodules again 2024-09-12 03:13:52 -04:00
4bba0346dd Not sure what I was doing here 2024-09-12 02:59:28 -04:00
1d17372d8e Unified ps2 build 2024-09-12 02:58:48 -04:00
dfa6176182 Unigi updates 2024-09-11 18:42:08 -04:00
b2963910d9 Build unigi yeah 2024-09-11 03:17:57 -04:00
e1847d5d67 Setting up changes for new unigi 2024-09-11 01:15:19 -04:00
a38bcd51dd Put more in ecs 2024-09-09 02:32:02 -04:00
4d00379ace Terrain ecs system going well 2024-09-09 02:13:24 -04:00
8b227bf993 Setting up basic components and systems 2024-09-08 23:04:57 -04:00
1fddf39939 Initial terrain stuff 2024-09-08 18:42:50 -04:00
8bfe2301a7 No more zips 2024-09-08 15:17:08 -04:00
31 changed files with 1556 additions and 121 deletions

2
.clangd Normal file
View File

@ -0,0 +1,2 @@
CompileFlags: # Tweak the parse settings
Add: [-Iunigi/]

1
.gitignore vendored
View File

@ -5,6 +5,7 @@ ignore/
*.obj *.obj
*.cam *.cam
*.tar.gz *.tar.gz
*.zip
*.Identifier *.Identifier
callgrind.* callgrind.*

19
.gitmodules vendored
View File

@ -1,15 +1,12 @@
[submodule "haloo3d"] [submodule "haloo3d"]
path = haloo3d path = haloo3d
url = https://github.com/randomouscrap98/haloo3d.git url = https://github.com/randomouscrap98/haloo3d.git
[submodule "unigi/unigi"] [submodule "unigi.platform.sdl2"]
path = unigi/unigi path = unigi.platform.sdl2
url = https://git.lumen.sh/Fierelier/unigi.git url = https://git.lumen.sh/Fierelier/unigi.platform.sdl2.git
[submodule "unigi/unigi.headers"] [submodule "unigi.platform.sdl1"]
path = unigi/unigi.headers path = unigi.platform.sdl1
url = https://git.lumen.sh/Fierelier/unigi.headers.git
[submodule "unigi/unigi.ext"]
path = unigi/unigi.ext
url = https://git.lumen.sh/Fierelier/unigi.ext
[submodule "unigi/unigi.platform.sdl1"]
path = unigi/unigi.platform.sdl1
url = https://git.lumen.sh/Fierelier/unigi.platform.sdl1.git url = https://git.lumen.sh/Fierelier/unigi.platform.sdl1.git
[submodule "unigi"]
path = unigi
url = https://git.lumen.sh/Fierelier/unigi.git

View File

@ -21,28 +21,39 @@ else
endif endif
HALOOLIB = haloo3d/build/haloo3d_full.a HALOOLIB = haloo3d/build/haloo3d_full.a
UNIGIPLAT = $(BUILDD)/unigi.platform.sdl2.o
UNIGILIB = $(BUILDD)/unigi.a
ALLH3DFILES = haloo3d/*.c haloo3d/*.h
.PHONY: clean .PHONY: clean
.PHONY: full .PHONY: libs
full: libs: $(UNIGILIB) $(HALOOLIB)
echo "Please specify a sample to build (ends with .exe)" @echo "Built libs!"
$(HALOOLIB): $(HALOOLIB): $(ALLH3DFILES)
cd haloo3d && $(MAKE) full cd haloo3d && $(MAKE) full
$(UNIGIPLAT): unigi.platform.sdl2/main.c
mkdir -p $(BUILDD)
$(CC) $(CFLAGS) -I. -c $< -o $@
$(UNIGILIB): $(UNIGIPLAT)
ar -vr $@ $^
# Rule to build .o files in main folder # Rule to build .o files in main folder
$(BUILDD)/%.o: %.c %.h $(BUILDD)/%.o: %.c %.h
mkdir -p $(BUILDD) mkdir -p $(BUILDD)
$(CC) $(CFLAGS) -c $< -o $@ $(CC) $(CFLAGS) -c $< -o $@
# Rule to build any sample. We ALWAYS need math so... link it # Rule to build any sample. We ALWAYS need math so... link it
%.exe: %.o $(HALOOLIB) %.exe: %.o $(UNIGILIB) $(HALOOLIB)
$(CC) $(CFLAGS) $< $(HALOOLIB) -o $@ -lm -lSDL $(CC) $(CFLAGS) $^ -o $@ -lm -lSDL2
# Rule to clean the build files # Rule to clean the build files
clean: clean:
rm -rf $(BUILDD) rm -rf $(BUILDD)
rm -f *.o *.elf
find . -name "*.exe" -type f -delete find . -name "*.exe" -type f -delete
cd haloo3d && $(MAKE) clean cd haloo3d && $(MAKE) clean

45
Makefile_PS2 Normal file
View File

@ -0,0 +1,45 @@
# _____ ___ ____ ___ ____
# ____| | ____| | | |____|
# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
#-----------------------------------------------------------------------
# Copyright 2001-2022, ps2dev - http://www.ps2dev.org
# Licenced under Academic Free License version 2.0
# Review ps2sdk README & LICENSE files for further details.
EE_BIN = $(PROGRAM_PS2).elf
# KERNEL_NOPATCH = 1
# NEWLIB_NANO = 1
# NOTE: CANNOT USE JUST 'PS2' AS A DEFINE, IT BREAKS EVERYTHING!
EE_OBJS = $(PROGRAM_PS2).o
EE_CFLAGS += -fdata-sections -ffunction-sections -I$(PS2SDK)/ports/include -Wformat=0
EE_LDFLAGS += -L$(PS2SDK)/ports/lib -L$(GSKIT)/lib -lSDL2 -lgskit -ldmakit -lps2_drivers -lm -Wl,--gc-sections
ifeq ($(DUMMY_TIMEZONE), 1)
EE_CFLAGS += -DDUMMY_TIMEZONE
endif
ifeq ($(DUMMY_LIBC_INIT), 1)
EE_CFLAGS += -DDUMMY_LIBC_INIT
endif
ifeq ($(KERNEL_NOPATCH), 1)
EE_CFLAGS += -DKERNEL_NOPATCH
endif
ifeq ($(DEBUG), 1)
EE_CFLAGS += -DDEBUG -O0 -g
else
EE_CFLAGS += -Os
EE_LDFLAGS += -s
endif
all: $(EE_BIN)
clean:
rm -rf $(EE_OBJS) $(EE_BIN)
# Include makefiles
include $(PS2SDK)/samples/Makefile.pref
include $(PS2SDK)/samples/Makefile.eeglobal

View File

@ -3,7 +3,7 @@
Everything in here is a little sample program or otherwise which Everything in here is a little sample program or otherwise which
uses [haloo3d](https://github.com/randomouscrap98/haloo3d) and uses [haloo3d](https://github.com/randomouscrap98/haloo3d) and
[unigi](https://git.lumen.sh/Fierelier/unigi). It's all software [unigi](https://git.lumen.sh/Fierelier/unigi). It's all software
rendered, but you'll need to get sdl1 so it can render to screen. rendered, but you'll need to get sdl2 so it can render to screen.
The libraries required are set as submodules, so you can pull them The libraries required are set as submodules, so you can pull them
when cloning with: when cloning with:
@ -33,14 +33,13 @@ make FORCE=1 maze.exe
## Unigi ## Unigi
For the time being, unigi is designed such that it expects you to Unigi is a small library and is built manually using the 3dtoys makefile.
compile your entire program as a single unit. This means you must You can tinker around with Unigi if you like; it has its own make system,
include all your .c files into the main file, in the right order. but I'm not sure what is required. The parts that are required for 3dtoys
are handled with the 3dtoys makefile.
This may change in the future.
Unigi expects some kind of graphics backend to run. In this case, Unigi expects some kind of graphics backend to run. In this case,
our samples use SDL1, so you'll need to get that. our samples use SDL2, so you'll need to get that.
## Haloo3d ## Haloo3d

137
commonobj.c Normal file
View File

@ -0,0 +1,137 @@
#include "haloo3d/haloo3d.h"
#include "haloo3d/haloo3dex_gen.h"
#include "haloo3d/haloo3dex_obj.h"
#ifndef TREECOL
#define TREECOL 0xF070
#endif
#ifndef TREETRUNKCOL
#define TREETRUNKCOL 0xF950
#endif
#ifndef TREEBOTTOM
#define TREEBOTTOM -0.333
#endif
#ifndef TREETOPWIDTH
#define TREETOPWIDTH 1.0
#endif
#ifndef TREETRUNKWIDTH
#define TREETRUNKWIDTH 0.2
#endif
#define TOWERTHICK 0.65
#define COMVERT(m, _x, _y, _z) \
haloo3d_obj_addvertex(m, (struct vec4){.x = _x, .y = _y, .z = _z, .w = 1})
#define COMCOL(m, col) haloo3d_obj_addvtexture(m, haloo3d_gen_paletteuv(col))
// Fill a face with a solid color given by the tex
void fastface(haloo3d_facei face, uint16_t tex, uint16_t v0, uint16_t v1,
uint16_t v2) {
face[0].texi = tex;
face[1].texi = tex;
face[2].texi = tex;
face[0].posi = v0;
face[1].posi = v1;
face[2].posi = v2;
}
static inline uint16_t fastface2(haloo3d_obj *model, uint16_t tex, uint16_t v0,
uint16_t v1, uint16_t v2) {
haloo3d_facei face;
fastface(face, tex, v0, v1, v2);
return haloo3d_obj_addface(model, face);
}
// Generate a basic tree model
void gen_tree_model(haloo3d_obj *tree) {
haloo3d_obj_resetfixed(tree, 12, 24);
int treeuv = COMCOL(tree, TREECOL);
int trunkuv = COMCOL(tree, TREETRUNKCOL);
uint16_t top = COMVERT(tree, 0, 1, 0);
uint16_t tree1 = COMVERT(tree, -TREETOPWIDTH, TREEBOTTOM, -TREETOPWIDTH);
uint16_t tree2 = COMVERT(tree, TREETOPWIDTH, TREEBOTTOM, -TREETOPWIDTH);
uint16_t tree3 = COMVERT(tree, 0, TREEBOTTOM, TREETOPWIDTH);
uint16_t trunk1 = COMVERT(tree, -TREETRUNKWIDTH, -1, -TREETRUNKWIDTH);
uint16_t trunk2 = COMVERT(tree, TREETRUNKWIDTH, -1, -TREETRUNKWIDTH);
uint16_t trunk3 = COMVERT(tree, 0, -1, TREETRUNKWIDTH);
fastface2(tree, treeuv, top, tree1, tree3);
fastface2(tree, treeuv, top, tree3, tree2);
fastface2(tree, treeuv, top, tree2, tree1);
fastface2(tree, trunkuv, top, trunk1, trunk3);
fastface2(tree, trunkuv, top, trunk3, trunk2);
fastface2(tree, trunkuv, top, trunk2, trunk1);
haloo3d_obj_shrinktofit(tree);
}
void gen_circle_model(haloo3d_obj *model, uint16_t color, int vertices) {
haloo3d_obj_resetfixed(model, vertices, vertices + 1);
int circleuv = COMCOL(model, color);
// Add the center
uint16_t middle = COMVERT(model, 0, 0, 0);
// Go in a circle of course
float angle = 0;
float angle_inc = MPI * 2 / vertices;
uint16_t lastv = 0;
uint16_t firstv = 0;
for (int i = 0; i < vertices; i++) {
uint16_t thisv = COMVERT(model, cos(angle), sin(angle), 0);
if (i == 0) {
firstv = thisv;
} else {
fastface2(model, circleuv, middle, lastv, thisv);
}
angle += angle_inc;
lastv = thisv;
}
fastface2(model, circleuv, middle, lastv, firstv);
}
void gen_flower_model(haloo3d_obj *model, uint16_t color) {
haloo3d_obj_resetfixed(model, 2, 5);
uint16_t vs[5];
uint16_t col = COMCOL(model, color);
vs[0] = COMVERT(model, 0, -1, 0); // The shared middle
vs[1] = COMVERT(model, 1, 1, 0);
vs[2] = COMVERT(model, -1, 1, 0);
vs[3] = COMVERT(model, 0, 1, 1);
vs[4] = COMVERT(model, 0, 1, -1);
fastface2(model, col, vs[0], vs[1], vs[2]);
fastface2(model, col, vs[0], vs[3], vs[4]);
}
void gen_horibox(haloo3d_obj *model, uint16_t col, mfloat_t wid, mfloat_t bot,
mfloat_t hei) {
uint16_t box[8];
box[0] = COMVERT(model, -wid, bot, wid);
box[1] = COMVERT(model, -wid, bot + hei, wid);
box[2] = COMVERT(model, wid, bot, wid);
box[3] = COMVERT(model, wid, bot + hei, wid);
box[4] = COMVERT(model, wid, bot, -wid);
box[5] = COMVERT(model, wid, bot + hei, -wid);
box[6] = COMVERT(model, -wid, bot, -wid);
box[7] = COMVERT(model, -wid, bot + hei, -wid);
for (int i = 0; i < 8; i += 2) {
fastface2(model, col, box[i], box[(i + 3) & 7], box[(i + 1) & 7]);
fastface2(model, col, box[i], box[(i + 2) & 7], box[(i + 3) & 7]);
}
}
void gen_tower_model(haloo3d_obj *model, uint16_t color) {
haloo3d_obj_resetfixed(model, 100, 100);
uint16_t col = COMCOL(model, color);
uint16_t top = COMVERT(model, 0, 1, 0);
fastface2(model, col, top, COMVERT(model, -1, -1, 1),
COMVERT(model, -TOWERTHICK, -1, TOWERTHICK));
fastface2(model, col, top, COMVERT(model, 1, -1, 1),
COMVERT(model, TOWERTHICK, -1, TOWERTHICK));
fastface2(model, col, top, COMVERT(model, -1, -1, -1),
COMVERT(model, -TOWERTHICK, -1, -TOWERTHICK));
fastface2(model, col, top, COMVERT(model, 1, -1, -1),
COMVERT(model, TOWERTHICK, -1, -TOWERTHICK));
gen_horibox(model, col, 0.2, 0.8, 0.03);
gen_horibox(model, col, 0.8, -0.4, 0.05);
for (mfloat_t f = 0.7; f >= -0.4; f -= 0.2) {
gen_horibox(model, col, (1 - f) * 0.5, f, 0.01);
}
haloo3d_obj_shrinktofit(model);
}

155
ecs2.h
View File

@ -13,6 +13,10 @@
#define ECS_MAXENTITIES 1024 #define ECS_MAXENTITIES 1024
#endif #endif
#ifndef ECS_FNTYPE
#define ECS_FNTYPE
#endif
// We reserve one slot to automatically point back to the ecs system. // We reserve one slot to automatically point back to the ecs system.
// This is the unusable 64th ID = 63 (your ids should start from 0) // This is the unusable 64th ID = 63 (your ids should start from 0)
#define ECS_MAXCTYPES 63 #define ECS_MAXCTYPES 63
@ -24,6 +28,8 @@
typedef unsigned long long ecs_cid; typedef unsigned long long ecs_cid;
typedef int ecs_eid; typedef int ecs_eid;
// -------------- ECS BUILDERS -----------------------
#define ECS_START(name) \ #define ECS_START(name) \
typedef struct name name; \ typedef struct name name; \
struct name { \ struct name { \
@ -34,10 +40,30 @@ typedef int ecs_eid;
#define ECS_END(name) \ #define ECS_END(name) \
} \ } \
; \ ; \
const ecs_cid name##_fl = ECS_SELFFLAG;
// Create an ECS component within an ECS struct
#define ECS_COMPONENT(type) type c_##type[ECS_MAXENTITIES];
// Define the CIDs necessary to access a component (each component MUST
// have a unique id and I can't do that inside a macro without requiring
// extensions). Note: can't use enum, because we need the flag value too.
// (unless you have a compiler that supports iterating over macro varargs)
#define ECS_CID(type, id) \
const int type##_id = id; \
const ecs_cid type##_fl = (1ULL << id);
// -------------- ECS EXTRA FUNCTIONS -----------------------
// NOTE: these generate functions individually because some systems might
// not allow unused functions and you may not need them all
#define ECS_FN_INIT(name) \
/* Always initialize the ecs system when you create a new one! */ \ /* Always initialize the ecs system when you create a new one! */ \
static void name##_init(name *_ecs) { memset(_ecs, 0, sizeof(name)); } \ ECS_FNTYPE void name##_init(name *_ecs) { memset(_ecs, 0, sizeof(name)); }
#define ECS_FN_NEWENTITY(name) \
/* Create an entity with the given base components (usually 0) */ \ /* Create an entity with the given base components (usually 0) */ \
static ecs_eid name##_newentity(name *_ecs, ecs_cid basecomponents) { \ ECS_FNTYPE ecs_eid name##_newentity(name *_ecs, ecs_cid basecomponents) { \
for (int i = 0; i < ECS_MAXENTITIES; i++) { \ for (int i = 0; i < ECS_MAXENTITIES; i++) { \
ecs_eid id = _ecs->entitytop; \ ecs_eid id = _ecs->entitytop; \
_ecs->entitytop = (_ecs->entitytop + 1) % ECS_MAXENTITIES; \ _ecs->entitytop = (_ecs->entitytop + 1) % ECS_MAXENTITIES; \
@ -48,19 +74,23 @@ typedef int ecs_eid;
} \ } \
} \ } \
return -1; \ return -1; \
} \ }
#define ECS_FN_DELETEENTITY(name) \
/* Delete an entity by eid from the given ecs sys */ \ /* Delete an entity by eid from the given ecs sys */ \
static void name##_deleteentity(name *_ecs, ecs_eid eid) { \ ECS_FNTYPE void name##_deleteentity(name *_ecs, ecs_eid eid) { \
if (eid >= 0 && eid < ECS_MAXENTITIES) \ if (eid >= 0 && eid < ECS_MAXENTITIES) \
_ecs->entities[eid] = 0; \ _ecs->entities[eid] = 0; \
} \ }
#define ECS_FN_QUERY(name) \
/* Whether an entity matches a given list of components by flag */ \ /* Whether an entity matches a given list of components by flag */ \
static int name##_match(name *_ecs, ecs_eid _eid, ecs_cid _comps) { \ ECS_FNTYPE int name##_match(name *_ecs, ecs_eid _eid, ecs_cid _comps) { \
ecs_cid _realcomps = ECS_SELFFLAG | _comps; \ ecs_cid _realcomps = ECS_SELFFLAG | _comps; \
return (_ecs->entities[_eid] & _realcomps) == _realcomps; \ return (_ecs->entities[_eid] & _realcomps) == _realcomps; \
} \ } \
/* fill given list with eids of entities that match. careful with size */ \ /* fill given list with eids of entities that match. careful with size */ \
static int name##_query(name *_ecs, ecs_cid _comps, ecs_eid *out) { \ ECS_FNTYPE int name##_query(name *_ecs, ecs_cid _comps, ecs_eid *out) { \
int count = 0; \ int count = 0; \
for (int i = 0; i < ECS_MAXENTITIES; i++) { \ for (int i = 0; i < ECS_MAXENTITIES; i++) { \
if (name##_match(_ecs, i, _comps)) { \ if (name##_match(_ecs, i, _comps)) { \
@ -68,36 +98,105 @@ typedef int ecs_eid;
} \ } \
} \ } \
return count; \ return count; \
} \ }
/* Calculate the eid from a double ecs pointer. Useful to get eid in sys */ \
static ecs_eid name##_eid(name **_ecs) { \
return (ecs_eid)(_ecs - (*_ecs)->c_##name); \
} \
const ecs_cid name##_fl = ECS_SELFFLAG;
// Create an ECS component within an ECS struct #define ECS_FN_EID(name) \
#define ECS_COMPONENT(type) type c_##type[ECS_MAXENTITIES]; /* Calculate the eid from a double ecs pointer. Useful to get eid in sys */ \
ECS_FNTYPE ecs_eid name##_eid(name **_ecs) { \
return (ecs_eid)(_ecs - (*_ecs)->c_##name); \
}
// ------------------ ECS GENERAL MACROS ----------------------------
#define ECS_COMPONENTS(_ecs, eid) (_ecs->entities[eid])
#define ECS_HASCOMPONENT(_ecs, eid, type) \
((_ecs->entities[eid] & type##_fl) != 0)
#define ECS_GETCOMPONENT(_ecs, eid, type) (_ecs)->c_##type[eid] #define ECS_GETCOMPONENT(_ecs, eid, type) (_ecs)->c_##type[eid]
// Define the CIDs necessary to access a component (each component MUST
// have a unique id and I can't do that inside a macro without requiring
// extensions)
#define ECS_CID(type, id) \
const int type##_id = id; \
const ecs_cid type##_fl = (1ULL << id);
// Set the given entity to have the given component (by type). Follow this // Set the given entity to have the given component (by type). Follow this
// macro immediately with the struct initializer // macro immediately with the struct initializer
#define ECS_SETCOMPONENT(_ecs, eid, type) \ #define ECS_SETCOMPONENT(_ecs, eid, type) \
(_ecs)->entities[eid] |= type##_fl; \ (_ecs)->entities[eid] |= type##_fl; \
(_ecs)->c_##type[eid] = (type) (_ecs)->c_##type[eid] = (type)
// Internal-use loop for ECS_RUNSYSTEM
#define _ECS_RSLOOP(_i, _ecs, _comps) \
for (int _i = 0; _i < ECS_MAXENTITIES; _i++) \
if (((_ecs)->entities[_i] & _comps) == _comps)
// A shortcut to run a system against all matching components. You could also
// define systems using ECS_SYSTEM1 etc. and call them per entity.
// Make sure you pass int the name of YOUR system, not the "run" function (you
// don't need the run function when using these macros)
#define ECS_RUNSYSTEM1(_ecs, _system, type1) \
{ \
ecs_cid _ecsflags = ECS_SELFFLAG | type1##_fl; \
_ECS_RSLOOP(eid, _ecs, _ecsflags) { _system((_ecs)->c_##type1 + eid); } \
}
// A shortcut to run a system against all matching components. You could also
// define systems using ECS_SYSTEM2 etc. and call them per entity.
// Make sure you pass int the name of YOUR system, not the "run" function (you
// don't need the run function when using these macros)
#define ECS_RUNSYSTEM2(_ecs, _system, t1, t2) \
{ \
ecs_cid _ecsflags = ECS_SELFFLAG | t1##_fl | t2##_fl; \
_ECS_RSLOOP(eid, _ecs, _ecsflags) { \
_system((_ecs)->c_##t1 + eid, (_ecs)->c_##t2 + eid); \
} \
}
// A shortcut to run a system against all matching components. You could also
// define systems using ECS_SYSTEM3 etc. and call them per entity.
// Make sure you pass int the name of YOUR system, not the "run" function (you
// don't need the run function when using these macros)
#define ECS_RUNSYSTEM3(_ecs, _system, t1, t2, t3) \
{ \
ecs_cid _ecsflags = ECS_SELFFLAG | t1##_fl | t2##_fl | t3##_fl; \
_ECS_RSLOOP(eid, _ecs, _ecsflags) { \
_system((_ecs)->c_##t1 + eid, (_ecs)->c_##t2 + eid, \
(_ecs)->c_##t3 + eid); \
} \
}
// A shortcut to run a system against all matching components. You could also
// define systems using ECS_SYSTEM4 etc. and call them per entity.
// Make sure you pass int the name of YOUR system, not the "run" function (you
// don't need the run function when using these macros)
#define ECS_RUNSYSTEM4(_ecs, _system, t1, t2, t3, t4) \
{ \
ecs_cid _ecsflags = ECS_SELFFLAG | t1##_fl | t2##_fl | t3##_fl | t4##_fl; \
_ECS_RSLOOP(eid, _ecs, _ecsflags) { \
_system((_ecs)->c_##t1 + eid, (_ecs)->c_##t2 + eid, \
(_ecs)->c_##t3 + eid, (_ecs)->c_##t4 + eid); \
} \
}
// A shortcut to run a system against all matching components. You could also
// define systems using ECS_SYSTEM5 etc. and call them per entity.
// Make sure you pass int the name of YOUR system, not the "run" function (you
// don't need the run function when using these macros)
#define ECS_RUNSYSTEM5(_ecs, _system, t1, t2, t3, t4, t5) \
{ \
ecs_cid _ecsflags = \
ECS_SELFFLAG | t1##_fl | t2##_fl | t3##_fl | t4##_fl | t5##_fl; \
_ECS_RSLOOP(eid, _ecs, _ecsflags) { \
_system(_ecs->c_##t1 + eid, _ecs->c_##t2 + eid, _ecs->c_##t3 + eid, \
_ecs->c_##t4 + eid, _ecs->c_##t5 + eid); \
} \
}
// ---------------------------------------------------------
// YOU DON'T NEED THIS STUFF IF YOU USE ECS_RUNSYSTEM
// ---------------------------------------------------------
// Add a system function which automatically calls your given function with // Add a system function which automatically calls your given function with
// pre-pulled items from the entity component arrays. The new function is // pre-pulled items from the entity component arrays. The new function is
// named the same as the old one, just with _run appeneded // named the same as the old one, just with _run appeneded
#define ECS_SYSTEM1(ecsname, fname, type1) \ #define ECS_SYSTEM1(ecsname, fname, type1) \
void fname##_run(ecsname *_ecs, ecs_eid eid) { \ ECS_FNTYPE void fname##_run(ecsname *_ecs, ecs_eid eid) { \
ecs_cid _ecsflags = type1##_fl; \ ecs_cid _ecsflags = type1##_fl; \
if (ecsname##_match(_ecs, eid, _ecsflags)) { \ if (ecsname##_match(_ecs, eid, _ecsflags)) { \
fname(_ecs->c_##type1 + eid); \ fname(_ecs->c_##type1 + eid); \
@ -108,7 +207,7 @@ typedef int ecs_eid;
// pre-pulled items from the entity component arrays. The new function is // pre-pulled items from the entity component arrays. The new function is
// named the same as the old one, just with _run appeneded // named the same as the old one, just with _run appeneded
#define ECS_SYSTEM2(ecsname, fname, type1, type2) \ #define ECS_SYSTEM2(ecsname, fname, type1, type2) \
void fname##_run(ecsname *_ecs, ecs_eid eid) { \ ECS_FNTYPE void fname##_run(ecsname *_ecs, ecs_eid eid) { \
ecs_cid _ecsflags = type1##_fl | type2##_fl; \ ecs_cid _ecsflags = type1##_fl | type2##_fl; \
if (ecsname##_match(_ecs, eid, _ecsflags)) { \ if (ecsname##_match(_ecs, eid, _ecsflags)) { \
fname(_ecs->c_##type1 + eid, _ecs->c_##type2 + eid); \ fname(_ecs->c_##type1 + eid, _ecs->c_##type2 + eid); \
@ -119,7 +218,7 @@ typedef int ecs_eid;
// pre-pulled items from the entity component arrays. The new function is // pre-pulled items from the entity component arrays. The new function is
// named the same as the old one, just with _run appeneded // named the same as the old one, just with _run appeneded
#define ECS_SYSTEM3(ecsname, fname, type1, type2, type3) \ #define ECS_SYSTEM3(ecsname, fname, type1, type2, type3) \
void fname##_run(ecsname *_ecs, ecs_eid eid) { \ ECS_FNTYPE void fname##_run(ecsname *_ecs, ecs_eid eid) { \
ecs_cid _ecsflags = type1##_fl | type2##_fl | type3##_fl; \ ecs_cid _ecsflags = type1##_fl | type2##_fl | type3##_fl; \
if (ecsname##_match(_ecs, eid, _ecsflags)) { \ if (ecsname##_match(_ecs, eid, _ecsflags)) { \
fname(_ecs->c_##type1 + eid, _ecs->c_##type2 + eid, \ fname(_ecs->c_##type1 + eid, _ecs->c_##type2 + eid, \
@ -131,7 +230,7 @@ typedef int ecs_eid;
// pre-pulled items from the entity component arrays. The new function is // pre-pulled items from the entity component arrays. The new function is
// named the same as the old one, just with _run appeneded // named the same as the old one, just with _run appeneded
#define ECS_SYSTEM4(ecsname, fname, type1, type2, type3, type4) \ #define ECS_SYSTEM4(ecsname, fname, type1, type2, type3, type4) \
void fname##_run(ecsname *_ecs, ecs_eid eid) { \ ECS_FNTYPE void fname##_run(ecsname *_ecs, ecs_eid eid) { \
ecs_cid _ecsflags = type1##_fl | type2##_fl | type3##_fl | type4##_fl; \ ecs_cid _ecsflags = type1##_fl | type2##_fl | type3##_fl | type4##_fl; \
if (ecsname##_match(_ecs, eid, _ecsflags)) { \ if (ecsname##_match(_ecs, eid, _ecsflags)) { \
fname(_ecs->c_##type1 + eid, _ecs->c_##type2 + eid, \ fname(_ecs->c_##type1 + eid, _ecs->c_##type2 + eid, \
@ -143,7 +242,7 @@ typedef int ecs_eid;
// pre-pulled items from the entity component arrays. The new function is // pre-pulled items from the entity component arrays. The new function is
// named the same as the old one, just with _run appeneded // named the same as the old one, just with _run appeneded
#define ECS_SYSTEM5(ecsname, fname, type1, type2, type3, type4, type5) \ #define ECS_SYSTEM5(ecsname, fname, type1, type2, type3, type4, type5) \
void fname##_run(ecsname *_ecs, ecs_eid eid) { \ ECS_FNTYPE void fname##_run(ecsname *_ecs, ecs_eid eid) { \
ecs_cid _ecsflags = \ ecs_cid _ecsflags = \
type1##_fl | type2##_fl | type3##_fl | type4##_fl | type5##_fl; \ type1##_fl | type2##_fl | type3##_fl | type4##_fl | type5##_fl; \
if (ecsname##_match(_ecs, eid, _ecsflags)) { \ if (ecsname##_match(_ecs, eid, _ecsflags)) { \
@ -157,7 +256,7 @@ typedef int ecs_eid;
// pre-pulled items from the entity component arrays. The new function is // pre-pulled items from the entity component arrays. The new function is
// named the same as the old one, just with _run appeneded // named the same as the old one, just with _run appeneded
#define ECS_SYSTEM6(ecsname, fname, type1, type2, type3, type4, type5, type6) \ #define ECS_SYSTEM6(ecsname, fname, type1, type2, type3, type4, type5, type6) \
void fname##_run(ecsname *_ecs, ecs_eid eid) { \ ECS_FNTYPE void fname##_run(ecsname *_ecs, ecs_eid eid) { \
ecs_cid _ecsflags = type1##_fl | type2##_fl | type3##_fl | type4##_fl | \ ecs_cid _ecsflags = type1##_fl | type2##_fl | type3##_fl | type4##_fl | \
type5##_fl | type6##_fl; \ type5##_fl | type6##_fl; \
if (ecsname##_match(_ecs, eid, _ecsflags)) { \ if (ecsname##_match(_ecs, eid, _ecsflags)) { \

@ -1 +1 @@
Subproject commit 9fbc0948f182cd46c4aaff43b632f92f72fb4fb2 Subproject commit 1667617d89a80f7802aca9260b9e79dd63ac56f6

18
make_ps2.sh Executable file
View File

@ -0,0 +1,18 @@
#!/bin/bash
set -e
if [ "$#" -lt "1" ]; then
echo "ERROR: You must pass the program name! For instance, to build maze.elf,"
echo "pass in just 'maze'"
exit 1
fi
make -f Makefile_PS2 PROGRAM_PS2="$1"
if [ "$#" -gt "1" ]; then
echo "Running on $2"
ps2client -h "$2" reset
sleep 1
ps2client -h "$2" execee host:$1.elf
fi

86
maze.c
View File

@ -1,13 +1,33 @@
// NOTE: CANNOT USE JUST 'PS2' AS A DEFINE, IT BREAKS EVERYTHING
#ifdef _EE
#define DIRECTBUILD
#define H3D_VOLATILE_FLOATS
#endif
#ifdef DIRECTBUILD
// clang-format off
#define MATHC_USE_UNIONS
#define MATHC_NO_STRUCT_FUNCTIONS
#include "haloo3d/lib/mathc.c"
#define FNL_IMPL
#include "haloo3d/lib/FastNoiseLite.h"
#include "haloo3d/haloo3d.c"
#include "haloo3d/haloo3dex_console.c"
#include "haloo3d/haloo3dex_easy.c"
#include "haloo3d/haloo3dex_gen.c"
#include "haloo3d/haloo3dex_obj.c"
#include "haloo3d/haloo3dex_print.c"
#include "unigi.platform.sdl2/main.c"
// clang-format on
#else
#include "haloo3d/haloo3d.h" #include "haloo3d/haloo3d.h"
#include "haloo3d/haloo3dex_console.h" #include "haloo3d/haloo3dex_console.h"
#include "haloo3d/haloo3dex_easy.h" #include "haloo3d/haloo3dex_easy.h"
#include "haloo3d/haloo3dex_gen.h" #include "haloo3d/haloo3dex_gen.h"
// #include "haloo3d/haloo3dex_img.h"
#include "haloo3d/haloo3dex_obj.h" #include "haloo3d/haloo3dex_obj.h"
#include "haloo3d/haloo3dex_print.h" #include "haloo3d/haloo3dex_print.h"
#include "unigi/main.h"
#include "unigi/unigi.headers/src/main.h" #endif
#include "unigi/unigi.platform.sdl1/src/main.c"
#include "ecs2.h" #include "ecs2.h"
#include "keys.h" #include "keys.h"
@ -23,25 +43,34 @@
#include <stdlib.h> #include <stdlib.h>
// INteresting flags for debugging
#define FASTFILL #define FASTFILL
#define NUMMICE 1 #define NUMMICE 1
#define MOUSELOGGING
// #define NOWALLS // #define NOWALLS
#ifdef _EE
#define WIDTH 160
#define HEIGHT 120
#define SCREENSCALE 4
#define DITHERSTART 2.5
#define DITHEREND 3.5
int fps = 20;
#else
#define WIDTH 480 #define WIDTH 480
#define HEIGHT 300 #define HEIGHT 300
#define ASPECT ((float)WIDTH / HEIGHT)
#define SCREENSCALE 2 #define SCREENSCALE 2
#define MOUSELOGGING
#define DITHERSTART 10000
#define DITHEREND 10000
int fps = 30;
#endif
#define ASPECT ((float)WIDTH / HEIGHT)
#define SWIDTH (WIDTH * SCREENSCALE) #define SWIDTH (WIDTH * SCREENSCALE)
#define SHEIGHT (HEIGHT * SCREENSCALE) #define SHEIGHT (HEIGHT * SCREENSCALE)
#define NEARCLIP 0.01 #define NEARCLIP 0.01
#define FARCLIP 100.0 #define FARCLIP 100.0
#define LIGHTANG -MPI / 4.0 #define LIGHTANG -MPI / 4.0
#define AVGWEIGHT 0.85 #define AVGWEIGHT 0.85
// Try 0.5 and 3.5 or something
#define DITHERSTART 10000
#define DITHEREND 10000
// Game options // Game options
#define MAZESIZE 15 #define MAZESIZE 15
@ -97,8 +126,7 @@ const char POLYNAMES[NUMPOLYS][20] = {"tetrahedron"};
float fov = 90.0; float fov = 90.0;
float minlight = 0.15; float minlight = 0.15;
float speed = 1.0; float speed = 1.0;
int fps = 30; uint16_t sky = 0xF644;
uint16_t sky = 0xF000;
struct vec2i dirtovec(uint8_t dir) { struct vec2i dirtovec(uint8_t dir) {
struct vec2i result; struct vec2i result;
@ -969,10 +997,20 @@ void create_paintingobj(haloo3d_obj *obj) {
} }
} }
int main() { // int argc, char **argv) { int main() { // int argc, char *argv[]) {
srand(clock()); srand(clock());
// Init unigi system
unigi_type_event event;
unigi_type_resolution res;
res.width = SWIDTH;
res.height = SHEIGHT;
res.depth = 0;
unigi_graphics_init();
unigi_window_create(res, "maze.exe"); // render.printbuf);
haloo3d_easystore storage; haloo3d_easystore storage;
haloo3d_easystore_init(&storage); haloo3d_easystore_init(&storage);
@ -986,6 +1024,7 @@ int main() { // int argc, char **argv) {
render.autolightfix = 1; render.autolightfix = 1;
render.rendersettings.ditherclose = DITHERSTART; render.rendersettings.ditherclose = DITHERSTART;
render.rendersettings.ditherfar = DITHEREND; render.rendersettings.ditherfar = DITHEREND;
// render.rendersettings.flags &= ~H3DR_PCT;
// render.rendersettings.flags &= ~(H3DR_LIGHTING); // render.rendersettings.flags &= ~(H3DR_LIGHTING);
render.rendersettings.pctminsize = 100; render.rendersettings.pctminsize = 100;
eprintf("Initialized renderer\n"); eprintf("Initialized renderer\n");
@ -1071,25 +1110,11 @@ int main() { // int argc, char **argv) {
init_billboard(endi, 0.25); init_billboard(endi, 0.25);
eprintf("Setup all static object instances\n"); eprintf("Setup all static object instances\n");
unigi_type_event event;
unigi_type_resolution res;
res.width = SWIDTH;
res.height = SHEIGHT;
res.depth = 0;
int totaldrawn = 0; int totaldrawn = 0;
eprintf("Scene has %d tris, %d verts\n", render.totalfaces, eprintf("Scene has %d tris, %d verts\n", render.totalfaces,
render.totalverts); render.totalverts);
// Init unigi system
unigi_graphics_init();
unigi_window_create(res, "maze.exe"); // render.printbuf);
// render.camera.pos.y = 4; // 5;
// render.camera.pitch = MPI - 0.1; // 2.2;
// ceili->pos.y = -10;
haloo3d_debugconsole dc; haloo3d_debugconsole dc;
haloo3d_debugconsole_init(&dc); haloo3d_debugconsole_init(&dc);
@ -1191,17 +1216,10 @@ int main() { // int argc, char **argv) {
while (1) { while (1) {
haloo3d_easytimer_start(&frametimer); haloo3d_easytimer_start(&frametimer);
// render.camera.yaw += 0.008;
haloo3d_perspective(render.perspective, fov, ASPECT, NEARCLIP, FARCLIP); haloo3d_perspective(render.perspective, fov, ASPECT, NEARCLIP, FARCLIP);
haloo3d_easyrender_beginframe(&render); haloo3d_easyrender_beginframe(&render);
haloo3d_fb_clear(&render.window, sky); haloo3d_fb_clear(&render.window, sky);
// walli->scale.y = fabs(sin(3 * render.camera.yaw));
// render.camera.up.x = sin(render.camera.yaw);
// render.camera.up.y = cos(render.camera.yaw);
// walli->up.x = sin(3 * render.camera.yaw);
// walli->up.y = cos(4 * render.camera.yaw);
do { do {
unigi_event_get(&event); unigi_event_get(&event);
switch (event.type) { switch (event.type) {

View File

@ -126,6 +126,12 @@ ECS_COMPONENT(ecs_object);
ECS_COMPONENT(ecs_mazeentity); ECS_COMPONENT(ecs_mazeentity);
ECS_END(mecs) ECS_END(mecs)
ECS_FN_INIT(mecs)
ECS_FN_NEWENTITY(mecs)
ECS_FN_DELETEENTITY(mecs)
ECS_FN_EID(mecs)
ECS_FN_QUERY(mecs)
// And then a copy of the components here... that sucksssss // And then a copy of the components here... that sucksssss
ECS_CID(ecs_worldstate, 0); ECS_CID(ecs_worldstate, 0);
ECS_CID(ecs_world, 1); ECS_CID(ecs_world, 1);

3
modeleditor/go.mod Normal file
View File

@ -0,0 +1,3 @@
module gitlumen.sh/haloopdy/3dtoys/modeleditor
go 1.23.0

9
modeleditor/main.go Normal file
View File

@ -0,0 +1,9 @@
package main
import (
"fmt"
)
func main() {
fmt.Printf("Program starting\n")
}

BIN
modeleditor/modeleditor Executable file

Binary file not shown.

3
notes.txt Normal file
View File

@ -0,0 +1,3 @@
1) MAKE SURE DEFINES ARE ISOLATED!
Minxrod gave a very useful command to find them:
find . -name '*.[ch]' | xargs grep -n -d recurse '#define .* [-+*/] .*' | grep -v '[(].* [-+*/] .*[)]'

View File

@ -1,12 +1,11 @@
#include "haloo3d/haloo3d.h" #include "haloo3d/haloo3d.h"
#include "haloo3d/haloo3dex_easy.h" // #include "haloo3d/haloo3dex_easy.h"
#include "haloo3d/haloo3dex_gen.h" #include "haloo3d/haloo3dex_gen.h"
#include "haloo3d/haloo3dex_img.h" #include "haloo3d/haloo3dex_img.h"
#include "haloo3d/haloo3dex_obj.h" #include "haloo3d/haloo3dex_obj.h"
#include "haloo3d/haloo3dex_print.h" #include "haloo3d/haloo3dex_print.h"
#include "unigi/unigi.headers/src/main.h" #include "unigi/main.h"
#include "unigi/unigi.platform.sdl1/src/main.c"
// #include "unigi/unigi.ext/src/main.c" // #include "unigi/unigi.ext/src/main.c"
#include "camera.h" #include "camera.h"
@ -16,7 +15,7 @@
#include <time.h> #include <time.h>
#define DOLIGHTING #define DOLIGHTING
#define FASTTRIS // #define FASTTRIS
// IDK you probably have to change this based on your display. // IDK you probably have to change this based on your display.
// Maybe there's a way to fix this? // Maybe there's a way to fix this?
@ -25,6 +24,7 @@
#define DITHERSTART 100 #define DITHERSTART 100
#define DITHEREND 101 #define DITHEREND 101
#define PCTSTART 100
#define WIDTH 640 #define WIDTH 640
#define HEIGHT 480 #define HEIGHT 480
@ -45,13 +45,13 @@
#define NUMINSTANCES (NUMOBJECTS - 1 + NUMFLOWERS) #define NUMINSTANCES (NUMOBJECTS - 1 + NUMFLOWERS)
#define MAXCAM 1200 #define MAXCAM 1200
#ifdef FASTTRIS // #ifdef FASTTRIS
#define WBUFCLEAR FARCLIP // #define WBUFCLEAR FARCLIP
#define TRIFUNC haloo3d_texturedtriangle_fast // #define TRIFUNC haloo3d_texturedtriangle_fast
#else // #else
#define WBUFCLEAR 0 // #define WBUFCLEAR 0
#define TRIFUNC haloo3d_texturedtriangle // #define TRIFUNC haloo3d_texturedtriangle
#endif // #endif
#define CALCTIME(thistime, start, end, sum) \ #define CALCTIME(thistime, start, end, sum) \
thistime = 1000.0 * (float)(end - start) / CLOCKS_PER_SEC; \ thistime = 1000.0 * (float)(end - start) / CLOCKS_PER_SEC; \
@ -166,6 +166,9 @@ int main(int argc, char **argv) {
// present in this // present in this
haloo3d_trirender rendersettings; haloo3d_trirender rendersettings;
haloo3d_trirender_init(&rendersettings); haloo3d_trirender_init(&rendersettings);
rendersettings.ditherfar = DITHEREND;
rendersettings.ditherclose = DITHERSTART;
rendersettings.pctminsize = PCTSTART;
eprintf("Scene has %d tris, %d verts\n", totalfaces, totalverts); eprintf("Scene has %d tris, %d verts\n", totalfaces, totalverts);
@ -198,7 +201,7 @@ int main(int argc, char **argv) {
camera.pitch = cams[cami].pitch + MPI_2; camera.pitch = cams[cami].pitch + MPI_2;
// REMEMBER TO CLEAR DEPTH BUFFER // REMEMBER TO CLEAR DEPTH BUFFER
haloo3d_fb_cleardepth(&fb, WBUFCLEAR); haloo3d_fb_cleardepth(&fb);
// Screen matrix calc. We multiply the modelview matrix with this later // Screen matrix calc. We multiply the modelview matrix with this later
haloo3d_camera_calclook(&camera, matrixcam); haloo3d_camera_calclook(&camera, matrixcam);
@ -223,8 +226,9 @@ int main(int argc, char **argv) {
objects[i].model->vtexture, face); objects[i].model->vtexture, face);
int tris = haloo3d_facef_clip(face, outfaces); int tris = haloo3d_facef_clip(face, outfaces);
if (tris > 0) { if (tris > 0) {
haloo3d_easy_calcdither4x4(&rendersettings, face, DITHERSTART, // haloo3d_getdither4x4(float dither, uint8_t *buf)
DITHEREND); // haloo3d_easy_calcdither4x4(&rendersettings, face, DITHERSTART,
// DITHEREND);
rendersettings.intensity = 1.0; rendersettings.intensity = 1.0;
if (objects[i].lighting) { if (objects[i].lighting) {
haloo3d_obj_facef(objects[i].model, objects[i].model->faces[fi], haloo3d_obj_facef(objects[i].model, objects[i].model->faces[fi],
@ -242,7 +246,7 @@ int main(int argc, char **argv) {
// We still have to convert the points into the view // We still have to convert the points into the view
haloo3d_facef_viewport_into(outfaces[ti], WIDTH, HEIGHT); haloo3d_facef_viewport_into(outfaces[ti], WIDTH, HEIGHT);
// eprintf("RENDER TRI\n"); // eprintf("RENDER TRI\n");
TRIFUNC(&fb, &rendersettings, outfaces[ti]); haloo3d_triangle(&fb, &rendersettings, outfaces[ti]);
} }
} }
} }

View File

@ -4,9 +4,7 @@
#include "haloo3d/haloo3dex_obj.h" #include "haloo3d/haloo3dex_obj.h"
#include "haloo3d/haloo3dex_print.h" #include "haloo3d/haloo3dex_print.h"
#include "unigi/unigi.headers/src/main.h" #include "unigi/main.h"
#include "unigi/unigi.platform.sdl1/src/main.c"
// #include "unigi/unigi.ext/src/main.c"
#include "camera.h" #include "camera.h"
#include "keys.h" #include "keys.h"
@ -227,7 +225,7 @@ int main(int argc, char **argv) {
// camera.pitch = cams[cami].pitch + MPI_2; // camera.pitch = cams[cami].pitch + MPI_2;
// REMEMBER TO CLEAR DEPTH BUFFER // REMEMBER TO CLEAR DEPTH BUFFER
haloo3d_fb_cleardepth(&fb, WBUFCLEAR); haloo3d_fb_cleardepth(&fb);
// Screen matrix calc. We multiply the modelview matrix with this later // Screen matrix calc. We multiply the modelview matrix with this later
haloo3d_camera_calclook(&camera, matrixcam); haloo3d_camera_calclook(&camera, matrixcam);
@ -264,7 +262,7 @@ int main(int argc, char **argv) {
} }
// We still have to convert the points into the view // We still have to convert the points into the view
haloo3d_facef_viewport_into(outfaces[ti], WIDTH, HEIGHT); haloo3d_facef_viewport_into(outfaces[ti], WIDTH, HEIGHT);
TRIFUNC(&fb, &rendersettings, outfaces[ti]); haloo3d_triangle(&fb, &rendersettings, outfaces[ti]);
} }
} }
} }

922
terrain.c Normal file
View File

@ -0,0 +1,922 @@
#ifdef _EE
#define DIRECTBUILD
#define H3D_VOLATILE_FLOATS
#endif
#ifdef DIRECTBUILD
// clang-format off
#define MATHC_USE_UNIONS
#define MATHC_NO_STRUCT_FUNCTIONS
#include "haloo3d/lib/mathc.c"
#define FNL_IMPL
#include "haloo3d/lib/FastNoiseLite.h"
#include "haloo3d/haloo3d.c"
#include "haloo3d/haloo3dex_easy.c"
#include "haloo3d/haloo3dex_gen.c"
#include "haloo3d/haloo3dex_obj.c"
#include "haloo3d/haloo3dex_print.c"
#include "unigi.platform.sdl2/main.c"
// clang-format on
#else
#include "haloo3d/haloo3d.h"
#include "haloo3d/haloo3dex_easy.h"
#include "haloo3d/haloo3dex_gen.h"
#include "haloo3d/haloo3dex_obj.h"
#include "haloo3d/haloo3dex_print.h"
#include "haloo3d/lib/FastNoiseLite.h"
#include "haloo3d/lib/mathc.h"
#include "unigi/main.h"
#endif
// #include "keys.h"
// #define ECS_MAXENTITIES 30000
#include "terrain_ecstypes.h"
#include <stdlib.h>
#include <time.h>
// #define LIMITEDPRINT
// #define NOPRINT
#ifdef _EE
#define WIDTH 160
#define HEIGHT 120
#define SCREENSCALE 4
#define VIEWDISTANCE 2 // MAX IS AROUND 12
#define MAXTREEPERCELL 4
#define MAXTREEACROSS 2
#define CHUNKINITFACES (H3D_OBJ_MAXFACES / 2)
#define CHUNKINITVERTS (H3D_OBJ_MAXVERTICES / 2)
#define INIT_DITHEREND 999
#define INIT_DITHERSTART 999
#else
#define WIDTH 480
#define HEIGHT 300
#define SCREENSCALE 2
#define VIEWDISTANCE 10 // MAX IS AROUND 12
#define MAXTREEPERCELL 9
#define MAXTREEACROSS 3
#define CHUNKINITFACES H3D_OBJ_MAXFACES
#define CHUNKINITVERTS H3D_OBJ_MAXVERTICES
#define INIT_DITHEREND H3DVF(VIEWDISTANCE - 1.0)
#define INIT_DITHERSTART H3DVF(INIT_DITHEREND * 0.5)
#endif
#define SWIDTH (WIDTH * SCREENSCALE)
#define SHEIGHT (HEIGHT * SCREENSCALE)
#define AVGWEIGHT H3DVF(0.85)
#define DEFAULTUP \
{ .x = 0, .y = 1, .z = 0 }
// Lookvec for objects which all face forward along with the player
#define DEFAULTLOOK \
{ .x = 0, .y = 0, .z = -1 }
// How big each chunk is (x and y, square). MUST BE POWER OF 2 - 1
#define CHUNKSIZE 7 // This is the width in tiles
#define CHUNKSCALE H3DVF(1.0 / CHUNKSIZE)
// This is how many vertices across a chunk is
#define CHUNKVSIZE (CHUNKSIZE + 1)
#define PLBOXEDGE (VIEWDISTANCE * 2 + 1)
#define MAXCHUNKPERFRAME PLBOXEDGE
// Generation consts / things for looks
#define COLOREDTERRAIN // Some cost, not much
#define LANDHEIGHT H3DVF(4.0)
#define LANDCOL 0xF7C3 // 0xF4E1
#define FLANDCOL 0xF260 // 0xF3A0 // 0xF4E1
#define UWLANDCOL 0xF026
#define SEACOL 0xF28D // 0xF26C
#define SKYCOL 0xF96E // 0xF77F
#define SKYCOL2 0xFFAF // 0xF77F
#define CLOUDCOL 0xFFDE
#define TREECOL 0xF070
#define TREETRUNKCOL 0xF950
#define REDFLOWERCOL 0xFF46 // 0xFF9A
#define YELLOWFLOWERCOL 0xFEE0
#define TOWERCOL 0xF111
#define LIGHTCOL 0xFF00
#define SANDCOL 0xFDD8
#define TOWERLOW H3DVF(0.755) // small changes to this make a huge difference
#define TOWERLIGHTMINSIZE H3DVF(CHUNKSCALE * 0.1)
#define TOWERLIGHTMAXSIZE H3DVF(CHUNKSCALE * 0.3)
#define TOWERLIGHTMINTRANS H3DVF(0)
#define TOWERLIGHTMAXTRANS H3DVF(0.4)
#define TOWERLIGHTRATE H3DVF(1.5)
#define SANDSTART H3DVF(0.085)
#define TREEBOTTOM H3DVF(-0.333)
#define TREETRUNKWIDTH H3DVF(0.20)
#define SEATRANS H3DVF(0.5)
#define CLOUDTRANSMIN H3DVF(0.1)
#define CLOUDTRANSMAX H3DVF(0.2)
#define CLOUDHEIGHT H3DVF(1 + VIEWDISTANCE * 0.1)
#define CLOUDSTRETCH H3DVF(2)
#define CLOUDCHANCE H3DVF(0.1)
#define INIT_LIGHTPITCH H3DVF(MPI_2 * 1.65)
#define INIT_LIGHTYAW H3DVF(MPI_2 * 0.65)
#define INIT_MINLIGHT H3DVF(0.2)
#define MAXTREECLOSENESS H3DVF(0.2)
// Player things
#define INIT_FOV H3DVF(90.0)
#define INIT_CAMPITCH H3DVF(MPI_2 * 1.3) // MPI_2 * 1.6 // 1.575
#define INIT_PLAYERHEIGHT H3DVF(0.65)
#define INIT_NEARCLIP H3DVF(0.010)
#define INIT_FARCLIP H3DVF(100.0)
#define INIT_PLAYERSPEED \
{ .x = 0, .y = 0, .z = -1.5 }
#define RANDF() ((float)rand() / H3DVF(RAND_MAX))
#define OFLOOR(v) (floor(fabs(v)) * ((v) < 0 ? -1 : 1))
// Some globals you can mess around with potentially
int fps = 60;
#define PALETTEKEY "palette"
#define TREEKEY "tree"
#define CLOUDKEY "cloud"
#define LIGHTKEY "light"
#define REDFLOWERKEY "redflower"
#define YELLOWFLOWERKEY "yellowflower"
#define TOWERKEY "tower"
#include "commonobj.c"
static int gen_terrain_seed = 0;
static inline mfloat_t calc_barycentric(mfloat_t *point, mfloat_t *values,
struct vec2 *triedge, int count) {
mfloat_t we[3];
for (int i = 0; i < count; i++) {
int ofs = i * 3;
we[0] = haloo3d_edgefunc(triedge[ofs + 1].v, triedge[ofs + 2].v, point);
we[1] = haloo3d_edgefunc(triedge[ofs + 2].v, triedge[ofs + 0].v, point);
we[2] = haloo3d_edgefunc(triedge[ofs + 0].v, triedge[ofs + 1].v, point);
if (we[0] < 0 || we[1] < 0 || we[2] < 0) {
continue;
}
return we[0] * values[ofs] + we[1] * values[ofs + 1] +
we[2] * values[ofs + 2];
}
return 0;
}
void gen_tower(haloo3d_obj *model, haloo3d_obj *tower, tecs *ecs,
render_context *ctx, struct vec3i chunk, struct vec3 pos) {
const float scale = 0.5;
pos.x += H3DVF(0.5);
pos.y += scale;
pos.z -= H3DVF(0.5);
haloo3d_obj_addobj(model, tower, pos, (struct vec3)DEFAULTLOOK,
(struct vec3)DEFAULTUP,
(struct vec3){.x = scale, .y = scale, .z = scale});
// Put a nice little light on top
pos.y += scale;
haloo3d_obj *light = haloo3d_easystore_getobj(&ecs->storage, LIGHTKEY);
ecs_eid lightid = tecs_newentity(ecs, 0);
eprintf("LIGHTING SPAWN: %d (%d,%d)\n", lightid, chunk.x, chunk.z);
ECS_SETCOMPONENT(ecs, lightid, ecs_playergarbage){};
ECS_SETCOMPONENT(ecs, lightid, ecs_towerlight){.timer = 0};
ECS_SETCOMPONENT(ecs, lightid, ecs_placement){
.up = DEFAULTUP,
.lookvec = DEFAULTLOOK,
.pos = (struct vec3){.x = chunk.x + pos.x * CHUNKSCALE,
.y = pos.y * CHUNKSCALE * LANDHEIGHT,
.z = chunk.z + pos.z * CHUNKSCALE}};
ECS_SETCOMPONENT(ecs, lightid, ecs_object){
.flatdither = 0.2,
.texture = haloo3d_easystore_gettex(&ecs->storage, PALETTEKEY),
.scale = {.x = CHUNKSCALE, .y = CHUNKSCALE, .z = CHUNKSCALE},
.lighting = NULL,
.stoplighting = 0,
.model = light,
.cullbackface = 0,
.context = {ctx},
.contextcount = 1};
}
void gen_cloud(render_context *ctx, tecs *ecs, struct vec3i pos) {
haloo3d_obj *cloud = haloo3d_easystore_getobj(&ecs->storage, CLOUDKEY);
ecs_eid cloudid = tecs_newentity(ecs, 0);
ECS_SETCOMPONENT(ecs, cloudid, ecs_playergarbage){};
ECS_SETCOMPONENT(ecs, cloudid, ecs_placement){
.up = DEFAULTUP,
.lookvec = DEFAULTLOOK,
.pos = {.x = pos.x + RANDF(),
.y = CLOUDHEIGHT + H3DVF(0.5) * RANDF(),
.z = pos.z - 0.9}};
ECS_SETCOMPONENT(ecs, cloudid, ecs_object){
.flatdither = CLOUDTRANSMIN + (CLOUDTRANSMAX - CLOUDTRANSMIN) * RANDF(),
.texture = haloo3d_easystore_gettex(&ecs->storage, PALETTEKEY),
.scale = {.x = H3DVF(1) + RANDF(),
.y = H3DVF(1.0 / CLOUDSTRETCH),
.z = 1},
.lighting = NULL,
.stoplighting = 0,
.model = cloud,
.cullbackface = 0,
.context = {ctx},
.contextcount = 1};
}
uint16_t gen_terrain(struct vec3i pos, haloo3d_obj *model, tecs *ecs,
render_context *ctx) {
haloo3d_easystore *storage = &ecs->storage;
eprintf("Generating terrain at %d,%d\n", pos.x, pos.z);
haloo3d_obj *tree = haloo3d_easystore_getobj(storage, TREEKEY);
haloo3d_obj *tower = haloo3d_easystore_getobj(storage, TOWERKEY);
haloo3d_obj *flowers[2];
flowers[0] = haloo3d_easystore_getobj(storage, REDFLOWERKEY);
flowers[1] = haloo3d_easystore_getobj(storage, YELLOWFLOWERKEY);
// Don't allow the model to have more than some amount of faces/vertices.
haloo3d_obj_resetfixed(model, CHUNKINITFACES, CHUNKINITVERTS);
#define LCOLSTEP 8
// uint16_t sandcol = COMCOL(model, 0xFFF7);
uint16_t landcols[(LCOLSTEP + 1) * 2];
for (int i = 0; i <= LCOLSTEP; i++) {
landcols[i] = COMCOL(
model, haloo3d_col_lerp(LANDCOL, FLANDCOL, (float)i / H3DVF(LCOLSTEP)));
landcols[i + LCOLSTEP + 1] =
// 0xFDE6
COMCOL(model, haloo3d_col_lerp(SANDCOL, UWLANDCOL,
(float)i / H3DVF(LCOLSTEP)));
}
fnl_state ns = fnlCreateState();
ns.noise_type = FNL_NOISE_OPENSIMPLEX2;
ns.seed = gen_terrain_seed;
ns.frequency = H3DVF(0.025);
ns.fractal_type = FNL_FRACTAL_RIDGED;
float noisex = pos.x * CHUNKSIZE;
float noisey = -pos.z * CHUNKSIZE;
for (int z = 0; z < CHUNKVSIZE; z++) {
for (int x = 0; x < CHUNKVSIZE; x++) {
// clang-format off
haloo3d_obj_addvertex(model, (struct vec4){
.x = x, .y = fnlGetNoise2D(&ns, noisex + x, noisey + z), .z = -z, .w = 1 });
// clang-format on
}
}
struct vec2 triedge[6];
mfloat_t heights[6];
uint16_t faces[2];
uint8_t gentower = 0;
// A funny little thing... we're going to add flowers to this alternative
// model, then add them to the end of the real model with a pointer saying
// "don't do lighting past this point"
haloo3d_obj nl_model;
haloo3d_obj_resetfixed(&nl_model, H3D_OBJ_MAXFACES, H3D_OBJ_MAXVERTICES);
for (int i = 0; i < CHUNKVSIZE * (CHUNKVSIZE - 1); i++) {
if ((i & CHUNKSIZE) == CHUNKSIZE) {
continue;
}
// Change frequency for subthings
// ns.seed = 0;
ns.frequency = 0.01; // 0.02;
ns.fractal_type = FNL_FRACTAL_NONE;
uint16_t bl = i;
uint16_t br = i + 1;
uint16_t tl = i + CHUNKVSIZE;
uint16_t tr = i + CHUNKVSIZE + 1;
faces[0] = fastface2(model, landcols[0], bl, br, tl);
faces[1] = fastface2(model, landcols[0], br, tr, tl);
float lowys[2];
float highys[2];
for (int t = 0; t < 2; t++) {
lowys[t] = H3DVF(999);
highys[t] = H3DVF(-999);
for (int v = 0; v < 3; v++) {
int ofs = t * 3;
// NOTE: WE SWTICH Y AND Z TO MAKE THE EDGE FUNCTION WORK
triedge[ofs + v].x = model->vertices[model->faces[faces[t]][v].posi].x;
triedge[ofs + v].y = model->vertices[model->faces[faces[t]][v].posi].z;
heights[ofs + v] = model->vertices[model->faces[faces[t]][v].posi].y;
if (heights[ofs + v] < lowys[t])
lowys[t] = heights[ofs + v];
if (heights[ofs + v] > highys[t])
highys[t] = heights[ofs + v];
}
#ifdef COLOREDTERRAIN
uint16_t tfvi = model->faces[faces[t]][0].posi;
float nlayer = fnlGetNoise2D(&ns, noisex + model->vertices[tfvi].x,
noisey + model->vertices[tfvi].z);
int landcol;
if (highys[t] < SANDSTART) {
landcol = LCOLSTEP + 1 + LCOLSTEP * fabs(highys[t]);
} else {
landcol = LCOLSTEP * fabs(lowys[t]) * (H3DVF(1) + nlayer) * H3DVF(0.5);
}
for (int v = 0; v < 3; v++) {
model->faces[faces[t]][v].texi = landcols[landcol];
}
#endif
}
float lowy = MIN(lowys[0], lowys[1]);
int treecount = 0;
for (int t = 0; t < MAXTREEPERCELL; t++) {
// We know that the first vec in the first triangle is bl, which is our
// base to start generating trees
struct vec2 treepos = {
.x = triedge[0].x + H3DVF(1.0 / MAXTREEACROSS) *
((t % MAXTREEACROSS) +
(H3DVF(1.0) - MAXTREECLOSENESS) * RANDF()),
.y = triedge[0].y - (H3DVF(1.0 / MAXTREEACROSS) *
((int)(t / MAXTREEACROSS) +
(H3DVF(1.0) - MAXTREECLOSENESS) * RANDF()))};
float y = calc_barycentric(treepos.v, heights, triedge, 2);
float pick = RANDF(); // pow(RANDF(), 2);
float nlayer = fnlGetNoise2D(&ns, noisex + treepos.x, noisey + treepos.y);
if (pick < y * (H3DVF(1) + nlayer) * H3DVF(0.5)) {
// Generate tree
float scale = H3DVF(0.1) + RANDF() * H3DVF(0.05);
float height = H3DVF(0.5) + RANDF() * H3DVF(0.5);
haloo3d_obj_addobj(
model, tree,
(struct vec3){
.x = treepos.x, .y = y + scale * height, .z = treepos.y},
(struct vec3)DEFAULTLOOK, (struct vec3)DEFAULTUP,
(struct vec3){.x = scale, .y = scale * height, .z = scale});
treecount++;
} else if ((rand() & 3) == 0 && y < H3DVF(0.4) && y > H3DVF(0) &&
RANDF() < -nlayer) {
// Generate flower of random-ish color
float scale = H3DVF(0.04);
float vertscale = scale * (H3DVF(1) - H3DVF(0.5) * RANDF());
haloo3d_obj_addobj(
&nl_model, flowers[nlayer > H3DVF(-0.9)],
(struct vec3){.x = treepos.x,
.y = y + vertscale * H3DVF(0.5),
.z = treepos.y},
(struct vec3)DEFAULTLOOK, (struct vec3)DEFAULTUP,
(struct vec3){.x = scale, .y = vertscale, .z = scale});
}
}
// You can put towers in cells with no trees that are high enough, as long
// as this chunk doesn't already have one
if (treecount == 0 && lowy > TOWERLOW && !gentower) {
gentower = 1;
gen_tower(&nl_model, tower, ecs, ctx, pos,
(struct vec3){.x = triedge[0].x, .y = lowy, .z = triedge[0].y});
}
}
// A silly hack to get a single model to render in multiple ways. Not good!
uint16_t stoplighting = model->numfaces;
haloo3d_obj_addobj(model, &nl_model, (struct vec3){.x = 0, .y = 0, .z = 0},
(struct vec3)DEFAULTLOOK, (struct vec3)DEFAULTUP,
(struct vec3){.x = 1, .y = 1, .z = 1});
haloo3d_obj_free(&nl_model);
// Generate a cloud maybe
if (RANDF() < CLOUDCHANCE)
gen_cloud(ctx, ecs, pos);
return stoplighting;
}
// Generate the entity/components/terrain for the chunk at the given
// coordinates.
// NOTE: chunks are per x/y tile (terrain inside is just scaled
// down to fit inside the 1x1 box)
void gen_chunk(render_context *ctx, tecs *ecs, struct vec3i pos) {
// eprintf("Generating chunk at %d,%d\n", pos.x, pos.y);
ecs_eid id = tecs_newentity(ecs, 0);
ecs_playergarbage garbage;
sprintf(garbage.dynmodel, "e%d", id);
haloo3d_obj *model =
haloo3d_easystore_addobj(&ecs->storage, garbage.dynmodel);
uint16_t stoplighting = gen_terrain(pos, model, ecs, ctx);
ECS_SETCOMPONENT(ecs, id, ecs_playergarbage) garbage;
ECS_SETCOMPONENT(ecs, id, ecs_chunk){.pos = pos};
ECS_SETCOMPONENT(ecs, id,
ecs_placement){.up = DEFAULTUP,
.lookvec = DEFAULTLOOK,
.pos = {.x = pos.x, .y = pos.y, .z = pos.z}};
// TODO: an easy place for optimization (if it's even needed)
// eprintf("TEX: %p\n", haloo3d_easystore_gettex(&ecs->storage, PALETTEKEY));
ECS_SETCOMPONENT(ecs, id, ecs_object){
.flatdither = 0,
.texture = haloo3d_easystore_gettex(&ecs->storage, PALETTEKEY),
.scale = {.x = CHUNKSCALE, .y = CHUNKSCALE * LANDHEIGHT, .z = CHUNKSCALE},
.lighting = &ecs->chunklight,
.stoplighting = stoplighting,
.model = model,
.cullbackface = 1,
.context = {ctx},
.contextcount = 1};
}
void player_chunkload(ecs_placement *ppos, render_context *ctx, tecs *ecs) {
struct vec3i pchunk = {.x = OFLOOR(ppos->pos.x),
.y = OFLOOR(ppos->pos.y),
.z = OFLOOR(ppos->pos.z)};
// This is our little array of "filled chunks" around the player. We
// use this to figure out what to generate
ecs_eid surround[PLBOXEDGE][PLBOXEDGE] = {0};
// Need to pull all existing objects that are killable
ecs_eid matches[ECS_MAXENTITIES];
// Find + iterate over killable objects placed in world
int mcount = tecs_query(
ecs, ecs_playergarbage_fl | ecs_placement_fl | ecs_object_fl, matches);
int lostobjects = 0;
for (int i = 0; i < mcount; i++) {
ecs_placement *placement =
&ECS_GETCOMPONENT(ecs, matches[i], ecs_placement);
ecs_object *obj = &ECS_GETCOMPONENT(ecs, matches[i], ecs_object);
// If this object is outside the view distance, we no longer have access to
// it
if (fabs(OFLOOR(placement->pos.x) - pchunk.x) > VIEWDISTANCE ||
fabs(OFLOOR(placement->pos.z) - pchunk.z) > VIEWDISTANCE) {
// OK, reduce the item refcount, since we're no longer close to it
obj->contextcount--;
lostobjects++;
}
// This is specifically a chunk, it might be within our view radius.
if (ECS_HASCOMPONENT(ecs, matches[i], ecs_chunk)) {
ecs_chunk *chunk = &ECS_GETCOMPONENT(ecs, matches[i], ecs_chunk);
int surx = chunk->pos.x - pchunk.x + VIEWDISTANCE;
int surz = chunk->pos.z - pchunk.z + VIEWDISTANCE;
if (surx >= 0 && surz >= 0 && surx < PLBOXEDGE && surz < PLBOXEDGE) {
// eprintf("SUR: %d %d\n", surx, sury);
surround[surz][surx] = 1; // matches[i];
}
}
}
if (lostobjects) {
eprintf("KILLABLE OBJS: %d PCHUNK: %d,%d\n", mcount, pchunk.x, pchunk.y);
}
int chunkgen = 0;
// We now have our view radius box and which chunks are not loaded. Up to
// some amount, let's load them
for (int z = pchunk.z - VIEWDISTANCE; z <= pchunk.z + VIEWDISTANCE; z++) {
for (int x = pchunk.x - VIEWDISTANCE; x <= pchunk.x + VIEWDISTANCE; x++) {
int surx = x - pchunk.x + VIEWDISTANCE;
int surz = z - pchunk.z + VIEWDISTANCE;
if (!surround[surz][surx]) {
gen_chunk(ctx, ecs, (struct vec3i){.x = x, .y = 0, .z = z});
if (++chunkgen >= MAXCHUNKPERFRAME) {
break;
}
}
}
}
}
// ---------------------------------------------------
// The terrain ecs systems
// ---------------------------------------------------
// All initialization for a specific render context
void sys_rendercontext(ecs_rendercontext *erc, ecs_placement *p, tecs **ecs) {
render_context *rc = *erc;
struct vec3 lookat;
mfloat_t cammatrix[MAT4_SIZE];
mfloat_t perspective[MAT4_SIZE];
// Some initial clearing
haloo3d_fb_cleardepth(&rc->window);
if (rc->windowclear & 0xF000) {
haloo3d_fb_clear(&rc->window, rc->windowclear);
}
if (rc->backtex) {
haloo3d_fb_fill_raw(&rc->window, rc->backtex, 0);
}
// Precalc stuff for later object rendering
rc->precalc_halfwidth = rc->window.width * H3DVF(0.5);
rc->precalc_halfheight = rc->window.height * H3DVF(0.5);
haloo3d_perspective(perspective, rc->fov,
(mfloat_t)rc->window.width / rc->window.height,
rc->nearclip, rc->farclip);
vec3_add(lookat.v, p->pos.v, p->lookvec.v);
haloo3d_my_lookat(cammatrix, p->pos.v, lookat.v, p->up.v);
mat4_inverse(cammatrix, cammatrix);
mat4_multiply(rc->precalc_screen, perspective, cammatrix);
// Well, since we're here... might as well do the player-related stuff.
// After all, we can be sure this is a player... right?
player_chunkload(p, rc, *ecs);
}
void sys_towerlight(ecs_towerlight *tl, tecs **ecs, ecs_object *o) {
tl->timer += (*ecs)->delta_s;
float ang = fabs(sin(tl->timer * TOWERLIGHTRATE));
o->flatdither =
TOWERLIGHTMINTRANS + (TOWERLIGHTMAXTRANS - TOWERLIGHTMINTRANS) * ang;
for (int i = 0; i < 3; i++) {
o->scale.v[i] =
TOWERLIGHTMINSIZE + (TOWERLIGHTMAXSIZE - TOWERLIGHTMINSIZE) * ang;
}
}
// Apply rotation to lookvec of placement, overrides lookvec
void sys_rotation(ecs_placement *p, ecs_rotation *r) {
YAWP2VEC(r->yaw, r->pitch, p->lookvec.v);
}
void sys_movement(ecs_placement *p, ecs_movement *m, tecs **ecs) {
mfloat_t temp[VEC3_SIZE];
vec3_multiply_f(temp, m->lookvec.v, (*ecs)->delta_s);
vec3_add(p->lookvec.v, p->lookvec.v, temp);
vec3_multiply_f(temp, m->up.v, (*ecs)->delta_s);
vec3_add(p->up.v, p->up.v, temp);
vec3_multiply_f(temp, m->pos.v, (*ecs)->delta_s);
vec3_add(p->pos.v, p->pos.v, temp);
// vec3_multiply(p->pos.v, p->pos.v, p->pos.v);
}
// Perform the entire rendering of an object
void sys_renderobject(ecs_placement *p, ecs_object *o, tecs **ecs) {
// --**-- First, precalc all the vertices in the object --**--
mfloat_t tmp[VEC4_SIZE];
mfloat_t modelm[MAT4_SIZE];
mfloat_t finalmatrix[MAT4_SIZE];
struct vec4 precalc_verts[H3D_OBJ_MAXVERTICES];
vec3_add(tmp, p->pos.v, p->lookvec.v);
haloo3d_my_lookat(modelm, p->pos.v, tmp, p->up.v);
// Apply scale such that it looks like it was applied first (this prevents
// scaling applying skew to a rotated object)
haloo3d_mat4_prescalev(modelm, o->scale.v);
haloo3d_trirender rsettings;
// We might be rendering into multiple contexts in a multiplayer game (or
// just different angles or something)
for (int ctx = 0; ctx < o->contextcount; ctx++) {
memcpy(&rsettings, &o->context[ctx]->rendersettings,
sizeof(haloo3d_trirender));
rsettings.texture = o->texture;
if (o->flatdither > 0) {
rsettings.ditherflat = o->flatdither;
}
mat4_multiply(finalmatrix, o->context[ctx]->precalc_screen, modelm);
haloo3d_precalc_verts(o->model, finalmatrix, precalc_verts);
// --**-- Next, setup some rendering invariants --**--
struct vec3 lighting;
// The compiler is complaining about lighting being used unitialized, even
// though it's not. Just shut it up
vec3(lighting.v, 0, 0, 0);
if (o->lighting) {
if (o->lighting->autolightfix) {
// Lighting doesn't rotate with the model unless you do it yourself.
// In the easy system, you can request the renderer to do it for you
struct vec4 ltmp, lout;
// Lighting is centered at 0
vec4(ltmp.v, 0, 0, 0, 1);
// Calc the same lookat just without translation. THis should be the
// same rotation matrix used on the model
haloo3d_my_lookat(modelm, ltmp.v, p->lookvec.v, p->up.v);
// We actually want the inverse. Apparently to speed things up, the
// transpose works for rotation matrices(?) but I don't trust that
// this lookat does that mat4_inverse(modelm, modelm);
mat4_transpose(modelm, modelm);
// We HAVE to have a vec4 (oof)
vec4(ltmp.v, o->lighting->dir.x, o->lighting->dir.y, o->lighting->dir.z,
1);
haloo3d_vec4_multmat_into(&ltmp, modelm, &lout);
// No need to fix W, should all be good (no perspective divide). But
// we DO need to pull out that result
vec3(lighting.v, lout.x, lout.y, lout.z);
vec3_normalize(lighting.v, lighting.v);
} else {
vec3_assign(lighting.v, o->lighting->dir.v);
}
}
// --**-- Finally, actually render faces --**--
haloo3d_facef face, baseface;
haloo3d_facef outfaces[H3D_FACEF_MAXCLIP];
for (int facei = 0; facei < o->model->numfaces; facei++) {
// Copy face values out of precalc array and clip them
haloo3d_make_facef(o->model->faces[facei], precalc_verts,
o->model->vtexture, face);
int tris = haloo3d_facef_clip(face, outfaces);
if (tris > 0) {
uint8_t oflags = rsettings.flags;
if (o->lighting && facei < o->stoplighting) {
haloo3d_obj_facef(o->model, o->model->faces[facei], baseface);
rsettings.intensity =
haloo3d_calc_light(lighting.v, o->lighting->minlight, baseface);
} else {
rsettings.intensity = H3DVF(1.0);
}
// if ((r->_objstate[object - r->objects] & H3D_EASYOBJSTATE_NOTRANS))
// {
// r->rendersettings.flags &= ~H3DR_TRANSPARENCY;
// }
for (int ti = 0; ti < tris; ti++) {
int backface = !haloo3d_facef_finalize(outfaces[ti]);
if (o->cullbackface && facei < o->stoplighting && backface) {
continue;
}
(*ecs)->totaldrawn++;
// We still have to convert the points into the view
haloo3d_facef_viewport_into_fast(outfaces[ti],
o->context[ctx]->precalc_halfwidth,
o->context[ctx]->precalc_halfheight);
haloo3d_triangle(&o->context[ctx]->window, &rsettings, outfaces[ti]);
}
rsettings.flags = oflags;
}
}
}
}
void sys_playerinput(ecs_input *in) {
in->numevents = 0;
unigi_type_event event;
do {
unigi_event_get(&event);
switch (event.type) {
case unigi_enum_event_input_keyboard:
if (event.data.input_keyboard.down) {
switch (event.data.input_keyboard.button) {
// case KEY_SPACE:
// haloo3d_debugconsole_beginprompt(&dc);
// break;
default:
exit(0);
}
}
break;
}
in->numevents++;
} while (event.type != unigi_enum_event_none);
}
void sys_playergarbage(ecs_playergarbage *pg, ecs_object *ob, tecs **ecs) {
ecs_eid id = tecs_eid(ecs);
if (ob->contextcount <= 0) {
eprintf("Deleting object %d\n", id);
if (pg->dynmodel[0]) {
haloo3d_easystore_deleteobj(&(*ecs)->storage, pg->dynmodel,
haloo3d_obj_free);
}
tecs_deleteentity(*ecs, id);
}
}
void sys_placement_lock(ecs_placement_lock *lock, ecs_placement *pl) {
if (lock->options & TECS_PLOCK_LOCKUP) {
pl->up = lock->link->up;
}
if (lock->options & TECS_PLOCK_LOCKPOSX) {
pl->pos.x = lock->link->pos.x;
}
if (lock->options & TECS_PLOCK_LOCKPOSY) {
pl->pos.y = lock->link->pos.y;
}
if (lock->options & TECS_PLOCK_LOCKPOSZ) {
pl->pos.z = lock->link->pos.z;
}
if (lock->options & TECS_PLOCK_LOCKLOOKX) {
pl->lookvec.x = lock->link->lookvec.x;
}
if (lock->options & TECS_PLOCK_LOCKLOOKY) {
pl->lookvec.y = lock->link->lookvec.y;
}
if (lock->options & TECS_PLOCK_LOCKLOOKZ) {
pl->lookvec.z = lock->link->lookvec.z;
}
}
// ---------------------------------------------------
// Setup functions
// ---------------------------------------------------
ecs_eid setup_player(tecs *ecs, render_context *context) {
ecs_eid playerid = tecs_newentity(ecs, 0);
ECS_SETCOMPONENT(ecs, playerid, ecs_placement){
.pos = {.x = 0, .y = INIT_PLAYERHEIGHT, .z = 0}, .up = DEFAULTUP};
ECS_SETCOMPONENT(ecs, playerid, ecs_movement){.pos = INIT_PLAYERSPEED};
ECS_SETCOMPONENT(ecs, playerid, ecs_rotation){.yaw = 0,
.pitch = INIT_CAMPITCH};
ECS_SETCOMPONENT(ecs, playerid, ecs_rendercontext) context;
ECS_SETCOMPONENT(ecs, playerid, ecs_input){};
return playerid;
}
ecs_eid setup_sea(tecs *ecs, render_context *ctx, ecs_placement *playerpos,
haloo3d_easystore *storage) {
ecs_eid seaid = tecs_newentity(ecs, 0);
ECS_SETCOMPONENT(ecs, seaid, ecs_placement){
.pos = {.x = 0, .y = 0, .z = 0}, .lookvec = DEFAULTLOOK, .up = DEFAULTUP};
ECS_SETCOMPONENT(ecs, seaid, ecs_placement_lock){
.options = TECS_PLOCK_LOCKPOSX | TECS_PLOCK_LOCKPOSZ | TECS_PLOCK_LOCKUP,
.link = playerpos,
};
haloo3d_obj *model = haloo3d_easystore_addobj(storage, "sea");
haloo3d_obj_resetfixed(model, 2, 4);
struct vec3 seacol = haloo3d_gen_paletteuv(SEACOL); // 0xF26F);
int seauv = haloo3d_obj_addvtexture(model, seacol);
// clang-format off
// REMEMBER: NEGATIVE Z IS FORWARD
int tl = haloo3d_obj_addvertex(model, (struct vec4){.x = -1, .y = 0, .z = -1, .w = 1});
int tr = haloo3d_obj_addvertex(model, (struct vec4){.x = 1, .y = 0, .z = -1, .w = 1});
int bl = haloo3d_obj_addvertex(model, (struct vec4){.x = -1, .y = 0, .z = 1, .w = 1});
int br = haloo3d_obj_addvertex(model, (struct vec4){.x = 1, .y = 0, .z = 1, .w = 1});
// clang-format on
haloo3d_facei face;
fastface(face, seauv, bl, br, tl);
haloo3d_obj_addface(model, face);
fastface(face, seauv, br, tr, tl);
haloo3d_obj_addface(model, face);
ECS_SETCOMPONENT(ecs, seaid, ecs_object){
.flatdither = SEATRANS,
.texture = haloo3d_easystore_gettex(&ecs->storage, PALETTEKEY),
.scale = {.x = VIEWDISTANCE * 1.5,
.y = VIEWDISTANCE * 1.5,
.z = VIEWDISTANCE * 1.5},
.lighting = NULL,
.model = model,
.cullbackface = 1,
.context = {ctx},
.contextcount = 1};
return seaid;
}
void draw_gradient(haloo3d_fb *buf, uint16_t topcol, uint16_t botcol,
int height) {
// Precalc an array indicating the bands of color.
int row[64]; // not sure how many bands there can be but...
uint16_t col[64];
int bandscount = 1;
row[0] = 0;
col[0] = topcol;
uint8_t dither[4];
for (int y = 1; y < height; y++) {
uint16_t thiscol =
haloo3d_col_lerp(topcol, botcol, (float)y / (height - 1));
if (thiscol != col[bandscount - 1]) {
row[bandscount] = y;
col[bandscount] = thiscol;
bandscount++;
}
}
for (int band = 0; band < bandscount - 1; band++) {
for (int r = row[band]; r < row[band + 1]; r++) {
haloo3d_getdither4x4((float)(r - row[band]) / (row[band + 1] - row[band]),
dither);
uint8_t df = dither[r & 3];
for (int b = 0; b < 8; b++) {
haloo3d_fb_set(buf, b, r, (df & 1) ? col[band + 1] : col[band]);
df >>= 1;
}
uint16_t *bufstart = buf->buffer + r * buf->width;
// Then, a repeated growing copy to minimize copies? IDK
for (int size = 8; size < buf->width; size <<= 1) {
memcpy(bufstart + size, bufstart,
sizeof(uint16_t) * MIN(size, buf->width - size));
}
}
}
}
// ---------------------------------------------------
// MAIN FUNCTION
// ---------------------------------------------------
int main() { // int argc, char **argv) {
srand(clock());
gen_terrain_seed = rand();
// Init unigi system. Can use anything here that can render to screen
unigi_type_resolution res;
res.width = SWIDTH;
res.height = SHEIGHT;
res.depth = 0;
unigi_graphics_init();
unigi_window_create(res, "terrain.exe"); // render.printbuf);
eprintf("Initialized unigi system\n");
haloo3d_fb screen;
haloo3d_fb_init(&screen, SWIDTH, SHEIGHT);
haloo3d_print_tracker pt;
char printbuf[8192];
haloo3d_print_initdefault(&pt, printbuf, sizeof(printbuf));
pt.fb = &screen;
pt.scale = 1;
haloo3d_easytimer frametimer, drawtimer, sdltimer;
haloo3d_easytimer_init(&frametimer, AVGWEIGHT);
haloo3d_easytimer_init(&drawtimer, AVGWEIGHT);
haloo3d_easytimer_init(&sdltimer, AVGWEIGHT);
haloo3d_fb skygrad;
haloo3d_fb_init_tex(&skygrad, 1 << (int)ceil(log2(WIDTH)),
1 << (int)ceil(log2(HEIGHT)));
haloo3d_fb_clear(&skygrad, SKYCOL2);
draw_gradient(&skygrad, SKYCOL, SKYCOL2, HEIGHT / 2);
eprintf("Sky texture size: %dx%d\n", skygrad.width, skygrad.height);
render_context context;
context.backtex = &skygrad;
context.windowclear = 0; // SKYCOL;
context.nearclip = INIT_NEARCLIP;
context.farclip = INIT_FARCLIP;
context.fov = INIT_FOV;
haloo3d_trirender_init(&context.rendersettings);
// context.rendersettings.flags &= ~H3DR_PCT;
// context.rendersettings.flags &= ~H3DR_DITHERPIX;
// context.rendersettings.flags |= H3DR_DITHERTRI;
context.rendersettings.ditherclose = INIT_DITHERSTART;
context.rendersettings.ditherfar = INIT_DITHEREND;
// context.rendersettings.pctminsize = 500;
haloo3d_fb_init(&context.window, WIDTH, HEIGHT);
eprintf("Initialized screen buffers, context, and timers\n");
tecs ecs;
ecs.delta_s = 0;
tecs_init(&ecs);
int tecs_size = sizeof(tecs);
YAWP2VEC(INIT_LIGHTYAW, INIT_LIGHTPITCH, ecs.globallighting.v);
// An issue? Not a pointer? Eeehhh....
ecs.chunklight.dir = ecs.globallighting;
ecs.chunklight.minlight = INIT_MINLIGHT;
ecs.chunklight.autolightfix = 0;
haloo3d_easystore_init(&ecs.storage);
haloo3d_fb *palettetex = haloo3d_easystore_addtex(&ecs.storage, PALETTEKEY);
haloo3d_gen_palettetex(palettetex);
haloo3d_obj *treemodel = haloo3d_easystore_addobj(&ecs.storage, TREEKEY);
gen_tree_model(treemodel);
haloo3d_obj *cloudmodel = haloo3d_easystore_addobj(&ecs.storage, CLOUDKEY);
gen_circle_model(cloudmodel, CLOUDCOL, 32);
haloo3d_obj *lightmodel = haloo3d_easystore_addobj(&ecs.storage, LIGHTKEY);
gen_circle_model(lightmodel, LIGHTCOL, 16);
haloo3d_obj *redflower = haloo3d_easystore_addobj(&ecs.storage, REDFLOWERKEY);
gen_flower_model(redflower, REDFLOWERCOL);
haloo3d_obj *yellowflower =
haloo3d_easystore_addobj(&ecs.storage, YELLOWFLOWERKEY);
gen_flower_model(yellowflower, YELLOWFLOWERCOL);
haloo3d_obj *tower = haloo3d_easystore_addobj(&ecs.storage, TOWERKEY);
gen_tower_model(tower, TOWERCOL);
eprintf("Setup ECS system + obj/tex storage (%d bytes)\n", tecs_size);
ecs_eid playerid = setup_player(&ecs, &context);
ecs_placement *playerpos = &ECS_GETCOMPONENT(&ecs, playerid, ecs_placement);
ecs_eid seaid = setup_sea(&ecs, &context, playerpos, &ecs.storage);
eprintf("Setup player(%d) + sea(%d)\n", playerid, seaid);
// MAIN LOOP
while (1) {
haloo3d_easytimer_start(&frametimer);
haloo3d_print_refresh(&pt);
ecs.totaldrawn = 0;
// ECS logic (which includes rendering)
if (ecs.delta_s) {
ECS_RUNSYSTEM1(&ecs, sys_playerinput, ecs_input);
ECS_RUNSYSTEM2(&ecs, sys_rotation, ecs_placement, ecs_rotation);
ECS_RUNSYSTEM3(&ecs, sys_movement, ecs_placement, ecs_movement, tecs);
ECS_RUNSYSTEM2(&ecs, sys_placement_lock, ecs_placement_lock,
ecs_placement);
ECS_RUNSYSTEM3(&ecs, sys_rendercontext, ecs_rendercontext, ecs_placement,
tecs);
ECS_RUNSYSTEM3(&ecs, sys_playergarbage, ecs_playergarbage, ecs_object,
tecs);
ECS_RUNSYSTEM3(&ecs, sys_towerlight, ecs_towerlight, tecs, ecs_object);
haloo3d_easytimer_start(&drawtimer);
ECS_RUNSYSTEM3(&ecs, sys_renderobject, ecs_placement, ecs_object, tecs);
haloo3d_easytimer_end(&drawtimer);
}
// Scale 3D into final buffer
haloo3d_fb_fill(&screen, &context.window);
#ifndef NOPRINT
// clang-format off
haloo3d_print(&pt,
"Pframe: %05.2f (%05.2f) DT: %0.3f\n"
#ifndef LIMITEDPRINT
"PSDLFl: %05.2f (%05.2f)\n"
"Render: %05.2f (%05.2f)\n"
"PlPos: %05.2f (%05.2f)\n"
#endif
"Tris: %d\n",
frametimer.last * 1000, frametimer.sum * 1000, ecs.delta_s,
#ifndef LIMITEDPRINT
sdltimer.last * 1000, sdltimer.sum * 1000,
drawtimer.last * 1000, drawtimer.sum * 1000,
playerpos->pos.x, playerpos->pos.z,
#endif
ecs.totaldrawn);
// clang-format on
#endif
// Finally, actually put buffer onto screen
haloo3d_easytimer_start(&sdltimer);
unigi_graphics_blit(0, (unigi_type_color *)screen.buffer,
res.width * res.height);
unigi_graphics_flush();
haloo3d_easytimer_end(&sdltimer);
haloo3d_easytimer_end(&frametimer);
// Wait for next frame based on fps
float waittime = (1.0 / fps) - frametimer.last;
if (waittime > 0) {
unigi_time_sleep(waittime * unigi_time_clocks_per_s);
}
ecs.delta_s = frametimer.last + MAX(waittime, 0);
}
haloo3d_fb_free(&screen);
haloo3d_fb_free(&context.window);
haloo3d_easystore_deleteallobj(&ecs.storage, haloo3d_obj_free);
haloo3d_easystore_deletealltex(&ecs.storage, haloo3d_fb_free);
}

174
terrain_ecstypes.h Normal file
View File

@ -0,0 +1,174 @@
#ifndef __TERRAIN_ECSTYPES
#define __TERRAIN_ECSTYPES
#define ECS_FNTYPE static
#include "ecs2.h"
#include "haloo3d/haloo3d.h"
#include "haloo3d/haloo3dex_easy.h"
#define TERRAIN_MAXPLAYERS 4
// Baseline render context. When a pointer to this is attached as a component,
// it becomes a render target, and that entity will perform the precalcs
// necessary for later object rendering.
typedef struct {
mfloat_t precalc_screen[MAT4_SIZE];
mfloat_t precalc_halfwidth; // Optimization for reducing calcs per tri
mfloat_t precalc_halfheight; // Optimization for reducing calcs per tri
mfloat_t fov;
mfloat_t nearclip;
mfloat_t farclip;
// NOTE: aspect ratio calculated from window
haloo3d_fb window;
haloo3d_fb *backtex;
// Baseline render settings. Some of these settings will be applied to
// each object associated with this context
haloo3d_trirender rendersettings;
// If alpha is 0, screen is not cleared
uint16_t windowclear;
} render_context;
// Associate this to some entity along with a placement and it will be the
// main "renderer" for a viewpoint
typedef render_context *ecs_rendercontext;
// Associate lighting with some object. Since this is part of the renderer,
// this isn't a component you can assign (it also doesn't mean anything on its
// own)
typedef struct {
struct vec3 dir;
mfloat_t minlight;
// Whether to automatically move lighting when models have a
// lookvec. This also normalizes the light
uint8_t autolightfix;
} object_lighting;
// All values which allow rendering of a 3d object
typedef struct {
// haloo3d_trirender rendersettings; // baseline settings for THIS object.
render_context *context[TERRAIN_MAXPLAYERS]; // What to render into
struct vec3 scale; // how big the thing should be in world
object_lighting *lighting; // a pointer to lighting, null for none
haloo3d_obj *model;
haloo3d_fb *texture;
uint16_t stoplighting;
uint8_t cullbackface; // Whether to cull backfaces (you probably should)
uint8_t contextcount; // How many contexts we render into
float flatdither; // A flat dither amount. Set to -1 to disable
} ecs_object;
// Some placement within the world. Doesn't imply anything other than a
// position and a facing direction
typedef struct {
struct vec3 pos;
struct vec3 up;
struct vec3 lookvec;
} ecs_placement;
// If set, locks the placement of one entity to another
typedef struct {
ecs_placement *link;
// struct vec3 posofs; // The offset from linked pos
uint8_t options; // Which things to lock
} ecs_placement_lock;
#define TECS_PLOCK_LOCKLOOKX 1
#define TECS_PLOCK_LOCKLOOKY 2
#define TECS_PLOCK_LOCKLOOKZ 4
#define TECS_PLOCK_LOCKPOSX 8
#define TECS_PLOCK_LOCKPOSY 16
#define TECS_PLOCK_LOCKPOSZ 32
#define TECS_PLOCK_LOCKUP 64
// typedef ecs_placement *ecs_placement_lock;
typedef struct {
// The data required to animate the tower light
float timer;
} ecs_towerlight;
// Movement is applied to placement and may also be used to check for
// collisions and whatever
typedef struct {
struct vec3 pos;
struct vec3 up;
struct vec3 lookvec;
} ecs_movement;
// Use rotation to override the lookvec of an ecs_placement
typedef struct {
mfloat_t yaw;
mfloat_t pitch;
} ecs_rotation;
// Type to track and mark some entity as receiving input events.
typedef struct {
int numevents;
} ecs_input;
// Simple component for some entity that should clean itself up
// when there are no more "references" to it. Whatever that means...
// some fields are for special cleanup
typedef struct {
char dynmodel[8]; // A model we may have to cleanup
} ecs_playergarbage;
// Represents the singular object that is the entire stationary
// object of terrain. The position is the "chunk position", which
// should be integer aligned. Not necessarily 1:1 with world
// coordinates?
typedef struct {
struct vec3i pos;
// uint8_t generation; // The type(?) of generation (idk honestly)
} ecs_chunk;
// // A billboard for OUR system, which does not look up or down at the target.
// As
// // such, no matter what the lookat is set to, y is always going to be equal
// to
// // the y of the instance, so it appears to be looking "straight"
// typedef struct {
// haloo3d_obj_instance *obj;
// struct vec3 *lookat;
// } ecs_billboard;
// Setup ECS system for our game
ECS_START(tecs)
float delta_s; // Store delta time in ecs
int totaldrawn; // A place to store total drawn tris
struct vec3 globallighting; // the global lighting to apply to terrain
object_lighting chunklight; // lighting to assign to a chunk
// Everyone needs to be able to get and set obj/texture
haloo3d_easystore storage;
ECS_COMPONENT(ecs_rendercontext)
ECS_COMPONENT(ecs_object)
ECS_COMPONENT(ecs_placement)
ECS_COMPONENT(ecs_rotation)
ECS_COMPONENT(ecs_movement)
ECS_COMPONENT(ecs_input)
ECS_COMPONENT(ecs_playergarbage)
ECS_COMPONENT(ecs_chunk)
ECS_COMPONENT(ecs_placement_lock)
ECS_COMPONENT(ecs_towerlight)
ECS_END(tecs)
ECS_FN_INIT(tecs)
ECS_FN_NEWENTITY(tecs)
ECS_FN_DELETEENTITY(tecs)
ECS_FN_EID(tecs)
ECS_FN_QUERY(tecs)
// And then a copy of the components here... that sucksssss
ECS_CID(ecs_rendercontext, 0)
ECS_CID(ecs_object, 1)
ECS_CID(ecs_placement, 2)
ECS_CID(ecs_rotation, 3)
ECS_CID(ecs_movement, 4)
ECS_CID(ecs_input, 5)
ECS_CID(ecs_playergarbage, 6)
ECS_CID(ecs_chunk, 7)
ECS_CID(ecs_placement_lock, 8)
ECS_CID(ecs_towerlight, 9)
#endif

1
unigi Submodule

@ -0,0 +1 @@
Subproject commit 8767a3dd8538c6650ab06f36c15d926d12a4b081

1
unigi.platform.sdl1 Submodule

@ -0,0 +1 @@
Subproject commit c2bb042dcb29e55879f9b0b415c2989afed56132

1
unigi.platform.sdl2 Submodule

@ -0,0 +1 @@
Subproject commit 7761a397a86b0e94bf5d7280b3c2c65e3713fae8

View File

@ -1,10 +0,0 @@
#!/bin/sh
set -e
cd unigi
git pull
cd ../unigi.headers
git pull
cd ../unigi.ext
git pull
cd ../unigi.platform.sdl1
git pull

@ -1 +0,0 @@
Subproject commit 34aa7f0a1cd24939c2de879b5dcce03daa0c7de2

@ -1 +0,0 @@
Subproject commit cf21dd85c6d49509c946ab9f462edc2e8a73327c

@ -1 +0,0 @@
Subproject commit ab07d46aac8d7043399437b83f81ce8ce3bf1233

@ -1 +0,0 @@
Subproject commit e407020c2118d7ad2f4d43eca5214b6360a0b7cc