@@ -0,0 +1,84 @@
#include "Managers.h"

#include "Managers.h"
#include "ImageLibrary.h"
#include "Entities\Entities.h"

#include "CoreComponents.h"
#include "WorldView.h"
#include "segashared\CheckedMemory.h"
#include "segalib\EGA.h"
#include "segautils\Rect.h"
#include "segautils\Defs.h"

#include <stdio.h>

typedef struct{
byte flag;
}TCursorComponent;

#define TComponentT TCursorComponent
#include "Entities\ComponentDeclTransient.h"

struct CursorManager_t{
Manager m;
WorldView *view;
Entity *e;

Int2 dragStart;

byte boxColor;

vec(Int2) *dragBox;
};

ImplManagerVTable(CursorManager)

CursorManager *createCursorManager(WorldView *view){
CursorManager *out = checkedCalloc(1, sizeof(CursorManager));
out->view = view;
out->m.vTable = CreateManagerVTable(CursorManager);

out->boxColor = 15;

return out;
}

void _destroy(CursorManager *self){
checkedFree(self);
}
void _onDestroy(CursorManager *self, Entity *e){}
void _onUpdate(CursorManager *self, Entity *e){}

static void _updateDragBox(CursorManager *self, int x, int y){

if (self->dragBox){
*vecAt(Int2)(self->dragBox, 0) = (Int2){ self->dragStart.x, self->dragStart.y };
*vecAt(Int2)(self->dragBox, 1) = (Int2){ x, self->dragStart.y };
*vecAt(Int2)(self->dragBox, 2) = (Int2){ x, y };
*vecAt(Int2)(self->dragBox, 3) = (Int2){ self->dragStart.x, y };
}



}

void cursorManagerCreateCursor(CursorManager *self){
self->e = entityCreate(self->view->entitySystem);

COMPONENT_ADD(self->e, PositionComponent, 0, 0);
COMPONENT_ADD(self->e, ImageComponent, stringIntern("assets/img/cursor.ega"));
COMPONENT_ADD(self->e, TCursorComponent, 0);
COMPONENT_ADD(self->e, LayerComponent, LayerCursor);
entityUpdate(self->e);
}

void cursorManagerUpdate(CursorManager *self, int x, int y){
PositionComponent *pc = entityGet(PositionComponent)(self->e);
if (pc){
pc->x = x;
pc->y = y;
}

_updateDragBox(self, x, y);
}
@@ -0,0 +1,45 @@
#include "GameClock.h"
#include "segautils\Defs.h"
#include "segashared\CheckedMemory.h"
#include "SEGA\App.h"

struct GameClock_t {
long time, appTime;
bool paused;
};

GameClock *gameClockCreate(){
GameClock *out = checkedCalloc(1, sizeof(GameClock));
return out;
}
void gameClockDestroy(GameClock *self){
checkedFree(self);
}

static void _updateTime(GameClock *self){
long newTime = (long)appGetTime(appGet());
long elapsed = newTime - self->appTime;

self->time += elapsed;
self->appTime = newTime;
}

long gameClockGetTime(GameClock *self){
if (!self->paused){
_updateTime(self);
}

return self->time;
}
void gameClockPause(GameClock *self){
if (!self->paused){
_updateTime(self);
self->paused = true;
}
}
void gameClockResume(GameClock *self){
if (self->paused){
self->appTime = (long)appGetTime(appGet());
self->paused = false;
}
}
@@ -0,0 +1,10 @@
#pragma once

typedef struct GameClock_t GameClock;

GameClock *gameClockCreate();
void gameClockDestroy(GameClock *self);

long gameClockGetTime(GameClock *self);
void gameClockPause(GameClock *self);
void gameClockResume(GameClock *self);
@@ -0,0 +1,8 @@
#include "GameState.h"

ImpleStateMessage(GameStateUpdate)
ImpleStateMessage(GameStateHandleInput)
ImpleStateMessage(GameStateRender)



@@ -0,0 +1,12 @@
#pragma once

#include "segautils\FSM.h"

typedef struct WorldView_t WorldView;
typedef struct Frame_t Frame;

DeclStateMessage(GameStateUpdate);
DeclStateMessage(GameStateHandleInput);
DeclStateMessageWithData(GameStateRender, { Frame *frame; });

StateClosure gameStateCreateWorld(WorldView *view);
@@ -0,0 +1,90 @@
#include "ImageLibrary.h"

#include "segalib\EGA.h"
#include "segautils\BitTwiddling.h"

typedef struct {
StringView key;
ManagedImage *value;
} iEntry;

#define HashTableT iEntry
#include "segautils\HashTable_Create.h"

typedef struct ManagedImage_t{
ht(iEntry) *map;
StringView path;
Image *image;
size_t useCount;
};

void managedImageDestroy(ManagedImage *self){
if (self->useCount > 1){
--self->useCount;
}
else {
iEntry entry = { self->path, self };
htErase(iEntry)(self->map, &entry);
}
}
Image *managedImageGetImage(ManagedImage *self){
return self->image;
}



static int _iEntryCompare(iEntry *e1, iEntry *e2){
return e1->key == e2->key;
}

static size_t _iEntryHash(iEntry *p){
return hashPtr((void*)p->key);
}

static void _iEntryDestroy(iEntry *p){
imageDestroy(p->value->image);
checkedFree(p->value);
}

typedef struct ImageLibrary_t{
ht(iEntry) *table;
};

ImageLibrary *imageLibraryCreate(){
ImageLibrary *out = checkedCalloc(1, sizeof(ImageLibrary));
out->table = htCreate(iEntry)(&_iEntryCompare, &_iEntryHash, &_iEntryDestroy);
return out;
}
void imageLibraryDestroy(ImageLibrary *self){
htDestroy(iEntry)(self->table);
checkedFree(self);
}
ManagedImage *imageLibraryGetImage(ImageLibrary *self, StringView path){
iEntry entry = { 0 };
iEntry *found = 0;
ManagedImage *out = 0;

entry.key = path;
found = htFind(iEntry)(self->table, &entry);

if (!found){
Image *newImage = imageDeserializeOptimized(path);

if (newImage){
out = checkedCalloc(1, sizeof(ManagedImage));
out->image = newImage;
out->map = self->table;
out->path = path;
out->useCount = 2;

entry.value = out;
htInsert(iEntry)(self->table, &entry);
}
}
else {
++found->value->useCount;
out = found->value;
}

return out;
}
@@ -0,0 +1,16 @@
#pragma once

#include "segashared\Strings.h"

typedef struct Image_t Image;

typedef struct ImageLibrary_t ImageLibrary;

typedef struct ManagedImage_t ManagedImage;

void managedImageDestroy(ManagedImage *self);
Image *managedImageGetImage(ManagedImage *self);

ImageLibrary *imageLibraryCreate();
void imageLibraryDestroy(ImageLibrary *self);
ManagedImage *imageLibraryGetImage(ImageLibrary *self, StringView path);
@@ -0,0 +1,23 @@
#pragma once

#include "segautils\Preprocessor.h"

typedef struct RenderManager_t RenderManager;
typedef struct CursorManager_t CursorManager;
typedef struct Frame_t Frame;
typedef struct WorldView_t WorldView;

typedef struct BTManagers_t {
RenderManager *renderManager;
CursorManager *cursorManager;
}BTManagers;

RenderManager *createRenderManager(WorldView *view, double *fps);
void renderManagerRender(RenderManager *self, Frame *frame);

CursorManager *createCursorManager(WorldView *view);
void cursorManagerCreateCursor(CursorManager *self);
void cursorManagerUpdate(CursorManager *self, int x, int y);



@@ -0,0 +1,109 @@
#include "MeshRendering.h"
#include "segalib\EGA.h"

#include "segalib\Rasterizer.h"
#include "segautils\BitTwiddling.h"
#include "segautils\Matrix.h"
#include "segautils\Quaternion.h"

#define VectorTPart Vertex
#include "segautils\Vector_Impl.h"
#include "SEGA\App.h"
#include <math.h>

static FlatImage g_flatImage = { 0 };

typedef struct{
FlatImage *img;
Frame *frame;
} RenderData;

typedef struct{
Int2 coords[3];
}TexCoords;

static void textureShader(RenderData *r, TexCoords *data, TrianglePoint *p){
int i = 0;
float texX = 0.0f, texY = 0.0f;
int x, y;
SuperScanLine *buff = NULL;

if (p->pos.x < 0 || p->pos.x >= EGA_RES_WIDTH ||
p->pos.y < 0 || p->pos.y >= EGA_RES_HEIGHT){
return;
}

for (i = 0; i < 3; ++i){
texX += data->coords[i].x * p->b[i];
texY += data->coords[i].y * p->b[i];
}

x = abs((int)texX) % r->img->width;
y = abs((int)texY) % r->img->height;

buff = r->img->planes[0].lines + y;
if (!getBitFromArray(buff->pixels, x)){
for (i = 0; i < EGA_PLANES; ++i){
buff = r->img->planes[i + 1].lines + y;

setBitInArray(r->frame->planes[i].lines[p->pos.y].pixels, p->pos.x, getBitFromArray(buff->pixels, x));
}
}
}

static void pixelShader(RenderData *r, TexCoords *data, TrianglePoint *p){
if (p->pos.x < 0 || p->pos.x >= EGA_RES_WIDTH ||
p->pos.y < 0 || p->pos.y >= EGA_RES_HEIGHT){
return;
}

frameRenderPoint(r->frame, p->pos.x, p->pos.y, 0);
}

static void buildTransform(Matrix *m, Transform t){
Matrix m2 = quaternionToMatrix(&t.rotation);

matrixIdentity(m);
//matrixOrtho(m, 0.0f, EGA_RES_WIDTH, EGA_RES_HEIGHT, 0.0f, 1.0f, -1.0f);

matrixTranslate(m, (Float3){ (float)t.offset.x, (float)t.offset.y, (float)t.offset.z });

*m = matrixMultiply(m, &m2);

matrixScale(m, (Float3){ (float)t.size.x, (float)t.size.y, (float)t.size.z });
}

void renderMesh(vec(Vertex) *vbo, vec(size_t) *ibo, Image *tex, Transform t, Frame *frame){
RenderData r = { .img = &g_flatImage, .frame = frame };
size_t iCount = vecSize(size_t)(ibo);
size_t i = 0, j = 0;
PixelShader shader = { 0 };
Vertex *v[3] = { 0 };
Float3 vPos[3] = { 0 };
Matrix m;

imageRenderToFlat(tex, r.img);

buildTransform(&m, t);
closureInit(PixelShader)(&shader, &r, (PixelShaderFunc)&textureShader, NULL);

for (i = 0; i < iCount / 3; ++i){
Float3 n = { 0 };
//fill out 3 vertices
for (j = 0; j < 3; ++j){
v[j] = vecAt(Vertex)(vbo, *vecAt(size_t)(ibo, i * 3 + j));
vPos[j] = matrixMultiplyV(&m, v[j]->coords);
}

//determine if vertex is facing away from the screen
n = vCross(vSubtract(vPos[1], vPos[0]), vSubtract(vPos[2], vPos[0]));

if (n.z < 0.0f){
//render
TexCoords data = { .coords = { v[0]->texCoords, v[1]->texCoords, v[2]->texCoords } };
drawTriangle(shader, &data, (Int2){ (int)vPos[0].x, (int)vPos[0].y },
(Int2){ (int)vPos[1].x, (int)vPos[1].y },
(Int2){ (int)vPos[2].x, (int)vPos[2].y });
}
}
}
@@ -0,0 +1,23 @@
#pragma once

#include "segautils\Vector.h"
#include "segautils\StandardVectors.h"
#include "segautils\Quaternion.h"

typedef struct{
Float3 coords;
Int2 texCoords;
}Vertex;

#define VectorTPart Vertex
#include "segautils\Vector_Decl.h"

typedef struct{
Int3 size, offset;
Quaternion rotation;
} Transform;

typedef struct Image_t Image;
typedef struct Frame_t Frame;

void renderMesh(vec(Vertex) *vbo, vec(size_t) *ibo, Image *tex, Transform t, Frame *frame);
@@ -0,0 +1,298 @@
#include "Managers.h"
#include "ImageLibrary.h"

#include "Entities\Entities.h"

#include "CoreComponents.h"
#include "segashared\CheckedMemory.h"
#include "segalib\EGA.h"
#include "MeshRendering.h"
#include "WorldView.h"

#include <stdio.h>

struct RenderManager_t{
Manager m;
WorldView *view;
FontFactory *fontFactory;
double *fps;

vec(EntityPtr) *layers[LayerCount];
};

typedef struct{
bool hasImage;
bool hasMesh;
bool hasRect;
bool hasPolygon;
bool hasText;

ManagedImage *img;
StringView filename;
}TRenderComponent;

static void _updateManagedImage(RenderManager *self, TRenderComponent *trc, ImageComponent *ic){
if (trc->img && trc->filename != ic->filename){
//image has changed
managedImageDestroy(trc->img);
trc->filename = ic->filename;
trc->img = imageLibraryGetImage(self->view->imageLibrary, trc->filename);
}
else {
//new image
trc->filename = ic->filename;
trc->img = imageLibraryGetImage(self->view->imageLibrary, trc->filename);
}
}

static bool _buildTRenderComponent(RenderManager *self, TRenderComponent *trc, Entity *e){
bool success = false;
ImageComponent *ic = entityGet(ImageComponent)(e);

trc->hasImage = ic != NULL;

if (ic){
_updateManagedImage(self, trc, ic);
success = true;
}

trc->hasRect = entityGet(RectangleComponent)(e) != NULL;
if (trc->hasRect){ success = true; }

trc->hasPolygon = entityGet(PolygonComponent)(e) != NULL;
if (trc->hasPolygon){ success = true; }

trc->hasText = entityGet(TextComponent)(e) != NULL;
if (trc->hasText){ success = true; }

trc->hasMesh = entityGet(MeshComponent)(e) != NULL;
if (trc->hasMesh){ success = true; }

return success;
}

static void TRenderComponentDestroy(TRenderComponent *self){
if (self->img){
managedImageDestroy(self->img);
}
}

#define COMP_DESTROY_FUNC TRenderComponentDestroy
#define TComponentT TRenderComponent
#include "Entities\ComponentDeclTransient.h"

void _initLayers(RenderManager *self){
vec(EntityPtr) **first = self->layers;
vec(EntityPtr) **last = first + LayerCount;

while (first != last){ (*first++) = vecCreate(EntityPtr)(NULL); }
}

void _destroyLayers(RenderManager *self){
vec(EntityPtr) **first = self->layers;
vec(EntityPtr) **last = first + LayerCount;

while (first != last){ vecDestroy(EntityPtr)(*first++); }
}

static void _imageComponentUpdate(RenderManager *self, Entity *e, ImageComponent *oldIC){
ImageComponent *ic = entityGet(ImageComponent)(e);
TRenderComponent *trc = entityGet(TRenderComponent)(e);
if (trc){
_updateManagedImage(self, trc, ic);
}
}

static void _registerUpdateDelegate(RenderManager *self, EntitySystem *system){
ComponentUpdate update;

closureInit(ComponentUpdate)(&update, self, (ComponentUpdateFunc)&_imageComponentUpdate, NULL);
compRegisterUpdateDelegate(ImageComponent)(system, update);
}

ImplManagerVTable(RenderManager)

RenderManager *createRenderManager(WorldView *view, double *fps){
RenderManager *out = checkedCalloc(1, sizeof(RenderManager));
Image *fontImage = imageDeserializeOptimized("assets/img/font.ega");
out->view = view;
out->m.vTable = CreateManagerVTable(RenderManager);
out->fontFactory = fontFactoryCreate(fontImage);
out->fps = fps;
_initLayers(out);

_registerUpdateDelegate(out, view->entitySystem);

imageDestroy(fontImage);
return out;
}

void _destroy(RenderManager *self){
fontFactoryDestroy(self->fontFactory);
_destroyLayers(self);
checkedFree(self);
}

void _onDestroy(RenderManager *self, Entity *e){}

void _onUpdate(RenderManager *self, Entity *e){
TRenderComponent *trc = entityGet(TRenderComponent)(e);
TRenderComponent newtrc = { 0 };

if (!trc){//no trc
if (_buildTRenderComponent(self, &newtrc, e)){//we were able to generate one
entityAdd(TRenderComponent)(e, &newtrc);//add it
}
}
else{//trc present
if (!_buildTRenderComponent(self, trc, e)){//on refresh, its no longer rendered
entityRemove(TRenderComponent)(e);//remove it
}
}
}

void _clearLayers(RenderManager *self){
vec(EntityPtr) **first = self->layers;
vec(EntityPtr) **last = first + LayerCount;

while (first != last){ vecClear(EntityPtr)(*first++); }
}

void _addToLayers(RenderManager *self, Entity* e){
Layer layer = 0;
LayerComponent *lc = entityGet(LayerComponent)(e);

if (lc){
layer = lc->layer;
}

if (layer < LayerCount){
vecPushBack(EntityPtr)(self->layers[layer], &e);
}
}

void _renderMeshEntity(Entity *e, Frame *frame, MeshComponent *mc, short x, short y, Image *img){
Transform t = {
.size = (Int3){ mc->size, mc->size, mc->size },
.offset = (Int3){ x, y, 0 },
.rotation = quaternionFromAxisAngle(mc->rotNormal, mc->angle)
};
renderMesh(mc->vbo, mc->ibo, img, t, frame);
}

void _renderPolygon(Frame *frame, vec(Int2) *pList, byte color, bool open){
if (!vecIsEmpty(Int2)(pList)){
Int2 *begin = vecBegin(Int2)(pList);
Int2 *end = vecEnd(Int2)(pList);
while (begin != end - 1){
Int2 p0 = *begin++;
Int2 p1 = *begin;

frameRenderLine(frame, p0.x, p0.y, p1.x, p1.y, color);
}

if(!open && vecSize(Int2)(pList) >= 2) {
Int2 p0 = *vecBack(Int2)(pList);
Int2 p1 = *vecBegin(Int2)(pList);

frameRenderLine(frame, p0.x, p0.y, p1.x, p1.y, color);
}
}
}

void _renderEntity(RenderManager *self, Entity *e, Frame *frame){
TRenderComponent *trc = entityGet(TRenderComponent)(e);
PositionComponent *pc = entityGet(PositionComponent)(e);
VisibilityComponent *vc = entityGet(VisibilityComponent)(e);
int x = 0, y = 0;

if (vc && !vc->shown){
return;
}

if (pc){
x = pc->x;
y = pc->y;
}

//render rect
if (trc->hasRect){
RectangleComponent *rc = entityGet(RectangleComponent)(e);
SizeComponent *sc = entityGet(SizeComponent)(e);
if (rc && sc){
frameRenderRect(frame, x, y, x + sc->x, y + sc->y, rc->color);
}
}

//render image (or mesh)
if (trc->hasImage && trc->img){
Image *img = managedImageGetImage(trc->img);

if (trc->hasMesh){
MeshComponent *mc = entityGet(MeshComponent)(e);
if (mc){ _renderMeshEntity(e, frame, mc, x, y, img); }
}
else{
ImageComponent *ic = entityGet(ImageComponent)(e);
if (ic->partial){
frameRenderImagePartial(frame, x, y, img, ic->x, ic->y, ic->width, ic->height);
}
else{
frameRenderImage(frame, x, y, img);
}

}
}

//polygons
if (trc->hasPolygon){
PolygonComponent *pc = entityGet(PolygonComponent)(e);
_renderPolygon(frame, pc->pList, pc->color, pc->open);
}

//text
if (trc->hasText){
TextComponent *tc = entityGet(TextComponent)(e);
frameRenderText(frame, c_str(tc->text), tc->x, tc->y,
fontFactoryGetFont(self->fontFactory, tc->bg, tc->fg));
}
}

void _renderLayer(RenderManager *self, vec(EntityPtr) *layer, Frame *frame){
vecForEach(EntityPtr, e, layer, {
_renderEntity(self, *e, frame);
});
}

void _renderLayers(RenderManager *self, Frame *frame){
vec(EntityPtr) **first = self->layers;
vec(EntityPtr) **last = first + LayerCount;

while (first != last){ _renderLayer(self, *first++, frame); }
}


void _renderFramerate(Frame *frame, Font *font, double d){
static char buffer[256] = { 0 };
short y = 0;
short x;
sprintf(buffer, "FPS: %.2f", d);

x = EGA_TEXT_RES_WIDTH - strlen(buffer);
frameRenderText(frame, buffer, x, y, font);
}

void renderManagerRender(RenderManager *self, Frame *frame){
frameClear(frame, 0);

_clearLayers(self);

COMPONENT_QUERY(self->view->entitySystem, TRenderComponent, trc, {
Entity *e = componentGetParent(trc, self->view->entitySystem);
_addToLayers(self, e);
});

_renderLayers(self, frame);

_renderFramerate(frame, fontFactoryGetFont(self->fontFactory, 7, 0), *self->fps);
}
@@ -0,0 +1,77 @@
#include "WorldView.h"
#include "Managers.h"
#include "Entities\Entities.h"
#include "ImageLibrary.h"
#include "segalib\EGA.h"

#include "GameState.h"
#include "SEGA\Input.h"
#include "SEGA\App.h"
#include "segashared\CheckedMemory.h"

#include "CoreComponents.h"
#include "segashared\Strings.h"
#include "GameClock.h"

typedef struct {
WorldView *view;
}WorldState;

static void _boardStateDestroy(WorldState *self){
checkedFree(self);
}

static void _boardUpdate(WorldState*, GameStateUpdate*);
static void _boardHandleInput(WorldState*, GameStateHandleInput*);
static void _boardRender(WorldState*, GameStateRender*);

static void _board(WorldState *state, Type *t, Message m){
if (t == GetRTTI(GameStateUpdate)){ _boardUpdate(state, m); }
else if (t == GetRTTI(GameStateHandleInput)){ _boardHandleInput(state, m); }
else if (t == GetRTTI(GameStateRender)){ _boardRender(state, m); }
}


void _boardUpdate(WorldState *state, GameStateUpdate *m){
BTManagers *managers = state->view->managers;
Mouse *mouse = appGetMouse(appGet());
Int2 mousePos = mouseGetPosition(mouse);

cursorManagerUpdate(managers->cursorManager, mousePos.x, mousePos.y);
}

static void _handleKeyboard(WorldState *state){
BTManagers *managers = state->view->managers;
Keyboard *k = appGetKeyboard(appGet());
KeyboardEvent e = { 0 };
while (keyboardPopEvent(k, &e)){
}
}

static void _handleMouse(WorldState *state){
BTManagers *managers = state->view->managers;
Mouse *mouse = appGetMouse(appGet());
Keyboard *k = appGetKeyboard(appGet());
MouseEvent event = { 0 };
while (mousePopEvent(mouse, &event)){
}
}

void _boardHandleInput(WorldState *state, GameStateHandleInput *m){
_handleKeyboard(state);
_handleMouse(state);
}

void _boardRender(WorldState *state, GameStateRender *m){
renderManagerRender(state->view->managers->renderManager, m->frame);
}

StateClosure gameStateCreateWorld(WorldView *view){
StateClosure out;
WorldState *state = checkedCalloc(1, sizeof(WorldState));

state->view = view;
closureInit(StateClosure)(&out, state, (StateClosureFunc)&_board, &_boardStateDestroy);

return out;
}
@@ -0,0 +1,15 @@
#pragma once

typedef struct BTManagers_t BTManagers;
typedef struct EntitySystem_t EntitySystem;
typedef struct ImageLibrary_t ImageLibrary;
typedef struct FSM_t FSM;
typedef struct GameClock_t GameClock;

typedef struct WorldView_t {
BTManagers *managers;
EntitySystem *entitySystem;
ImageLibrary *imageLibrary;
FSM *gameState;
GameClock *gameClock;
}WorldView;
@@ -4,6 +4,8 @@
#include "segashared\RTTI.h"
#include <assert.h>

#define __FILE_EX__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)

DeclLocalRTTITag(COMPONENTS)

#define MAX_ENTITIES (1024 * 128)
@@ -82,7 +84,7 @@ EntitySystem *entitySystemCreateChecked(const char *file, int line);
EntitySystem *entitySystemCreateUnchecked();

#ifdef _DEBUG
#define entitySystemCreate() entitySystemCreateChecked(__FILE__, __LINE__)
#define entitySystemCreate() entitySystemCreateChecked(__FILE_EX__, __LINE__)
#else
#define entitySystemCreate() entitySystemCreateUnchecked()
#endif
@@ -109,7 +111,7 @@ Entity *entityCreateChecked(EntitySystem *system, const char *file, int line);
Entity *entityCreateUnchecked(EntitySystem *system);

#ifdef _DEBUG
#define entityCreate(SYSTEM) entityCreateChecked(SYSTEM, __FILE__, __LINE__)
#define entityCreate(SYSTEM) entityCreateChecked(SYSTEM, __FILE_EX__, __LINE__)
#else
#define entityCreate(SYSTEM) entityCreateUnchecked(SYSTEM)
#endif
@@ -42,7 +42,7 @@ static void _updateEntity(AIManager *self, Entity *e){
CommandComponent *cc = entityGet(CommandComponent)(e);
GridComponent *gc = entityGet(GridComponent)(e);
TeamComponent *tc = entityGet(TeamComponent)(e);
BTManagers *managers = self->view->managers;
ShiftManagers *managers = self->view->managers;
if (!gc || !tc || entityIsDead(e)){
return;
}
@@ -45,7 +45,7 @@ static void _createTestEntity(EntitySystem *system, int x, int y, bool AI);


static void _testSpawn(BoardState *state){
BTManagers *managers = state->view->managers;
ShiftManagers *managers = state->view->managers;
static long spawnTimer = 0;

if (spawnTimer == 0){
@@ -66,7 +66,7 @@ static void _testSpawn(BoardState *state){
}

void _boardUpdate(BoardState *state, GameStateUpdate *m){
BTManagers *managers = state->view->managers;
ShiftManagers *managers = state->view->managers;
Mouse *mouse = appGetMouse(appGet());
Int2 mousePos = mouseGetPosition(mouse);

@@ -92,7 +92,7 @@ void _boardUpdate(BoardState *state, GameStateUpdate *m){
static bool special = false;

static void _handleKeyboard(BoardState *state){
BTManagers *managers = state->view->managers;
ShiftManagers *managers = state->view->managers;
Keyboard *k = appGetKeyboard(appGet());
KeyboardEvent e = { 0 };
while (keyboardPopEvent(k, &e)){
@@ -127,7 +127,7 @@ static void _handleKeyboard(BoardState *state){
}

static void _handleMouse(BoardState *state){
BTManagers *managers = state->view->managers;
ShiftManagers *managers = state->view->managers;
Mouse *mouse = appGetMouse(appGet());
Keyboard *k = appGetKeyboard(appGet());
MouseEvent event = { 0 };
@@ -8,7 +8,7 @@

static Action *_buildMagicMissile(ClosureData d, WorldView *view, Entity *user){
float range = 6.0f;
BTManagers *managers = view->managers;
ShiftManagers *managers = view->managers;

Status *s = statusCreateByName(managers->statusManager, stringIntern("stun"));
s = statusSetDuration(s, 2.0f);
@@ -24,7 +24,7 @@ typedef struct AIManager_t AIManager;
typedef struct StatusManager_t StatusManager;
typedef struct DamageMarkerManager_t DamageMarkerManager;

typedef struct BTManagers_t {
typedef struct ShiftManagers_t {
RenderManager *renderManager;
CursorManager *cursorManager;
GridManager *gridManager;
@@ -38,7 +38,7 @@ typedef struct BTManagers_t {
AIManager *AIManager;
StatusManager *statusManager;
DamageMarkerManager *damageMarkerManager;
}BTManagers;
}ShiftManagers;

RenderManager *createRenderManager(WorldView *view, double *fps);
void renderManagerRender(RenderManager *self, Frame *frame);
@@ -8,7 +8,7 @@

static Action *_buildRangedAttack(ClosureData d, WorldView *view, Entity *user){
float range = 4.0f;
BTManagers *managers = view->managers;
ShiftManagers *managers = view->managers;

CombatAction *dmg = combatActionCreateCustom(managers->combatManager);
COMPONENT_ADD(dmg, CActionSourceComponent, .source = user);
@@ -22,7 +22,7 @@
typedef struct {
VirtualApp vApp;
AppData data;
BTManagers managers;
ShiftManagers managers;
EntitySystem *entitySystem;
ImageLibrary *imageLibrary;
FSM *gameState;
@@ -1,13 +1,13 @@
#pragma once

typedef struct BTManagers_t BTManagers;
typedef struct ShiftManagers_t ShiftManagers;
typedef struct EntitySystem_t EntitySystem;
typedef struct ImageLibrary_t ImageLibrary;
typedef struct FSM_t FSM;
typedef struct GameClock_t GameClock;

typedef struct WorldView_t {
BTManagers *managers;
ShiftManagers *managers;
EntitySystem *entitySystem;
ImageLibrary *imageLibrary;
FSM *gameState;
@@ -26,7 +26,7 @@ static void _AutoRoutineDestroy(AutoRoutineData *self){
}

static CoroutineStatus _AutoRoutine(AutoRoutineData *data, CoroutineRequest request){
BTManagers *managers = data->view->managers;
ShiftManagers *managers = data->view->managers;
ActionUserComponent *uc = entityGet(ActionUserComponent)(data->a);
ActionTargetEntityComponent *tec = entityGet(ActionTargetEntityComponent)(data->a);
float range = 0.0;
@@ -37,7 +37,7 @@ static void _meleeRoutineDestroy(MeleeRoutineData *self){


static CoroutineStatus _meleeRoutine(MeleeRoutineData *data, CoroutineRequest request){
BTManagers *managers = data->view->managers;
ShiftManagers *managers = data->view->managers;
ActionUserComponent *uc = entityGet(ActionUserComponent)(data->a);
ActionTargetEntityComponent *tec = entityGet(ActionTargetEntityComponent)(data->a);
ActionAbilityNameComponent *anc = entityGet(ActionAbilityNameComponent)(data->a);
@@ -26,7 +26,7 @@ static void _NEWCMDRoutineDestroy(NEWCMDRoutineData *self){
}

static CoroutineStatus _NEWCMDRoutine(NEWCMDRoutineData *data, CoroutineRequest request){
BTManagers *managers = data->view->managers;
ShiftManagers *managers = data->view->managers;
ActionUserComponent *uc = entityGet(ActionUserComponent)(data->a);
ActionTargetEntityComponent *tec = entityGet(ActionTargetEntityComponent)(data->a);
Entity *e, *target;
@@ -27,7 +27,7 @@ static void _projectileRoutineDestroy(ProjectileRoutineData *self){
}

static CoroutineStatus _projectileRoutine(ProjectileRoutineData *data, CoroutineRequest request){
BTManagers *managers = data->view->managers;
ShiftManagers *managers = data->view->managers;
ActionUserComponent *uc = entityGet(ActionUserComponent)(data->a);
ActionTargetEntityComponent *tec = entityGet(ActionTargetEntityComponent)(data->a);
Entity *e, *target;
@@ -30,7 +30,7 @@ static void _bowRoutineDestroy(BowRoutineData *self){
}

static CoroutineStatus _bowRoutine(BowRoutineData *data, CoroutineRequest request){
BTManagers *managers = data->view->managers;
ShiftManagers *managers = data->view->managers;
ActionUserComponent *uc = entityGet(ActionUserComponent)(data->a);
ActionTargetEntityComponent *tec = entityGet(ActionTargetEntityComponent)(data->a);
ActionAbilityNameComponent *anc = entityGet(ActionAbilityNameComponent)(data->a);
@@ -26,7 +26,7 @@ static void _StunRoutineDestroy(StunRoutineData *self){
}

static CoroutineStatus _StunRoutine(StunRoutineData *data, CoroutineRequest request){
BTManagers *managers = data->view->managers;
ShiftManagers *managers = data->view->managers;
ActionUserComponent *uc = entityGet(ActionUserComponent)(data->a);
Entity *e;

@@ -28,7 +28,7 @@ static void _SwapOtherRoutineDestroy(SwapOtherRoutineData *self){
}

static CoroutineStatus _SwapOtherRoutine(SwapOtherRoutineData *data, CoroutineRequest request){
BTManagers *managers = data->view->managers;
ShiftManagers *managers = data->view->managers;
ActionUserComponent *uc = entityGet(ActionUserComponent)(data->a);
ActionTargetEntityComponent *tec = entityGet(ActionTargetEntityComponent)(data->a);

@@ -39,7 +39,7 @@ static void _pushSwapOtherAction(CommandManager *manager, Entity *user, Entity *
}

static CoroutineStatus _SwapRoutine(SwapRoutineData *data, CoroutineRequest request){
BTManagers *managers = data->view->managers;
ShiftManagers *managers = data->view->managers;
ActionUserComponent *uc = entityGet(ActionUserComponent)(data->a);
ActionTargetEntityComponent *tec = entityGet(ActionTargetEntityComponent)(data->a);
ActionAbilityNameComponent *anc = entityGet(ActionAbilityNameComponent)(data->a);