Add ability to shoot and delete entities
This commit is contained in:
		
							parent
							
								
									6069ed8415
								
							
						
					
					
						commit
						42ba86f05a
					
				
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										259
									
								
								src/Asteroid.c
									
									
									
									
									
								
							
							
						
						
									
										259
									
								
								src/Asteroid.c
									
									
									
									
									
								
							| @ -183,6 +183,8 @@ v2 *createAsteroidVertexList(MemoryArena_ *arena, i32 iterations, | ||||
| 		result[i] = V2(((math_cosf(iterationAngle * i) + 1) * asteroidRadius), | ||||
| 		               ((math_sinf(iterationAngle * i) + 1) * asteroidRadius)); | ||||
| 
 | ||||
| 		ASSERT(result[i].x >= 0 && result[i].y >= 0); | ||||
| 
 | ||||
| #if 1 | ||||
| 		f32 displacementDist   = 0.50f * asteroidRadius; | ||||
| 		i32 vertexDisplacement = | ||||
| @ -284,8 +286,9 @@ b32 checkEdgeProjectionOverlap(v2 *vertexList, i32 listSize, | ||||
| 	return result; | ||||
| } | ||||
| 
 | ||||
| b32 moveEntity(GameState *state, Entity *entity, i32 entityIndex, v2 ddP, | ||||
|                f32 dt, f32 ddPSpeed) | ||||
| INTERNAL b32 moveEntity(World *world, MemoryArena_ *transientArena, | ||||
|                         Entity *entity, i32 entityIndex, v2 ddP, f32 dt, | ||||
|                         f32 ddPSpeed) | ||||
| { | ||||
| 	ASSERT(ABS(ddP.x) <= 1.0f && ABS(ddP.y) <= 1.0f); | ||||
| 	/*
 | ||||
| @ -295,7 +298,7 @@ b32 moveEntity(GameState *state, Entity *entity, i32 entityIndex, v2 ddP, | ||||
| 	    newPos = (a*t^2)/2 + oldVelocity*t + oldPos | ||||
| 	*/ | ||||
| 
 | ||||
| 	ddP           = v2_scale(ddP, state->pixelsPerMeter * ddPSpeed); | ||||
| 	ddP           = v2_scale(ddP, world->pixelsPerMeter * ddPSpeed); | ||||
| 	v2 oldDp      = entity->dP; | ||||
| 	v2 resistance = v2_scale(oldDp, 2.0f); | ||||
| 	ddP           = v2_sub(ddP, resistance); | ||||
| @ -313,59 +316,59 @@ b32 moveEntity(GameState *state, Entity *entity, i32 entityIndex, v2 ddP, | ||||
| 
 | ||||
| 	// TODO(doyle): Collision for rects, (need to create vertex list for it)
 | ||||
| #if 1 | ||||
| 	if (entity->renderMode == rendermode_polygon && entity->collides) | ||||
| 	for (i32 i = entityIndex + 1; i < world->entityIndex; i++) | ||||
| 	{ | ||||
| 		for (i32 i = entityIndex + 1; i < state->entityIndex; i++) | ||||
| 		Entity *checkEntity = &world->entityList[i]; | ||||
| 		ASSERT(checkEntity->id != entity->id); | ||||
| 
 | ||||
| 		if (world->collisionTable[entity->type][checkEntity->type]) | ||||
| 		{ | ||||
| 			Entity *checkEntity = &state->entityList[i]; | ||||
| 			ASSERT(checkEntity->id != entity->id); | ||||
| 			ASSERT(entity->vertexPoints); | ||||
| 			ASSERT(checkEntity->vertexPoints); | ||||
| 
 | ||||
| 			if (checkEntity->renderMode == rendermode_polygon && | ||||
| 			    checkEntity->collides) | ||||
| 			/* Create entity edge lists */ | ||||
| 			v2 *entityVertexListOffsetToP = entity_generateUpdatedVertexList( | ||||
| 			    transientArena, entity); | ||||
| 
 | ||||
| 			v2 *checkEntityVertexListOffsetToP = | ||||
| 			    entity_generateUpdatedVertexList(transientArena, | ||||
| 			                                     checkEntity); | ||||
| 
 | ||||
| 			v2 *entityEdgeList = createNormalEdgeList(transientArena, | ||||
| 			                                          entityVertexListOffsetToP, | ||||
| 			                                          entity->numVertexPoints); | ||||
| 
 | ||||
| 			v2 *checkEntityEdgeList = createNormalEdgeList( | ||||
| 			    transientArena, checkEntityVertexListOffsetToP, | ||||
| 			    checkEntity->numVertexPoints); | ||||
| 
 | ||||
| 			/* Combine both edge lists into one */ | ||||
| 			i32 totalNumEdges = | ||||
| 			    checkEntity->numVertexPoints + entity->numVertexPoints; | ||||
| 			v2 *edgeList = | ||||
| 			    memory_pushBytes(transientArena, totalNumEdges * sizeof(v2)); | ||||
| 			for (i32 i = 0; i < entity->numVertexPoints; i++) | ||||
| 			{ | ||||
| 				/* Create entity edge lists */ | ||||
| 				v2 *entityVertexListOffsetToP = | ||||
| 				    entity_createVertexList(&state->transientArena, entity); | ||||
| 
 | ||||
| 				v2 *checkEntityVertexListOffsetToP = entity_createVertexList( | ||||
| 				    &state->transientArena, checkEntity); | ||||
| 
 | ||||
| 				v2 *entityEdgeList = createNormalEdgeList( | ||||
| 				    &state->transientArena, entityVertexListOffsetToP, | ||||
| 				    entity->numVertexPoints); | ||||
| 
 | ||||
| 				v2 *checkEntityEdgeList = createNormalEdgeList( | ||||
| 				    &state->transientArena, checkEntityVertexListOffsetToP, | ||||
| 				    checkEntity->numVertexPoints); | ||||
| 
 | ||||
| 				/* Combine both edge lists into one */ | ||||
| 				i32 totalNumEdges = | ||||
| 				    checkEntity->numVertexPoints + entity->numVertexPoints; | ||||
| 				v2 *edgeList = memory_pushBytes(&state->transientArena, | ||||
| 				                                totalNumEdges * sizeof(v2)); | ||||
| 				for (i32 i = 0; i < entity->numVertexPoints; i++) | ||||
| 				{ | ||||
| 					edgeList[i] = entityEdgeList[i]; | ||||
| 				} | ||||
| 
 | ||||
| 				for (i32 i = 0; i < checkEntity->numVertexPoints; i++) | ||||
| 				{ | ||||
| 					edgeList[i + entity->numVertexPoints] = | ||||
| 					    checkEntityEdgeList[i]; | ||||
| 				} | ||||
| 
 | ||||
| 				if (checkEdgeProjectionOverlap( | ||||
| 				        entityVertexListOffsetToP, entity->numVertexPoints, | ||||
| 				        checkEntityVertexListOffsetToP, | ||||
| 				        checkEntity->numVertexPoints, edgeList, totalNumEdges)) | ||||
| 				{ | ||||
| 					willCollide = TRUE; | ||||
| 				} | ||||
| 				edgeList[i] = entityEdgeList[i]; | ||||
| 			} | ||||
| 
 | ||||
| 			if (willCollide) { | ||||
| 				break; | ||||
| 			for (i32 i = 0; i < checkEntity->numVertexPoints; i++) | ||||
| 			{ | ||||
| 				edgeList[i + entity->numVertexPoints] = checkEntityEdgeList[i]; | ||||
| 			} | ||||
| 
 | ||||
| 			if (checkEdgeProjectionOverlap( | ||||
| 			        entityVertexListOffsetToP, entity->numVertexPoints, | ||||
| 			        checkEntityVertexListOffsetToP, | ||||
| 			        checkEntity->numVertexPoints, edgeList, totalNumEdges)) | ||||
| 			{ | ||||
| 				willCollide = TRUE; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		if (willCollide) | ||||
| 		{ | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| #endif | ||||
| @ -389,68 +392,106 @@ b32 moveEntity(GameState *state, Entity *entity, i32 entityIndex, v2 ddP, | ||||
| 	return willCollide; | ||||
| } | ||||
| 
 | ||||
| INTERNAL void addAsteroid(GameState *state, v2 windowSize) | ||||
| INTERNAL void addAsteroid(World *world, v2 windowSize) | ||||
| { | ||||
| 	Entity *asteroid = &state->entityList[state->entityIndex]; | ||||
| 	asteroid->id     = state->entityIndex++; | ||||
| 	Entity *asteroid = &world->entityList[world->entityIndex++]; | ||||
| 	asteroid->id     = world->entityIdCounter++; | ||||
| 
 | ||||
| 	i32 randValue = rand(); | ||||
| 	i32 randX     = (randValue % (i32)windowSize.w); | ||||
| 	i32 randY     = (randValue % (i32)windowSize.h); | ||||
| 	asteroid->pos = V2i(randX, randY); | ||||
| 
 | ||||
| 	asteroid->size       = V2(75.0f, 75.0f); | ||||
| 	asteroid->size       = V2(100.0f, 100.0f); | ||||
| 	asteroid->hitbox     = asteroid->size; | ||||
| 	asteroid->offset     = V2(asteroid->size.w * -0.5f, 0); | ||||
| 	asteroid->scale      = 1; | ||||
| 	asteroid->rotation   = 45; | ||||
| 	asteroid->offset     = v2_scale(asteroid->size, -0.5f); | ||||
| 	asteroid->type       = entitytype_asteroid; | ||||
| 	asteroid->direction  = direction_null; | ||||
| 	asteroid->renderMode = rendermode_polygon; | ||||
| 
 | ||||
| 	asteroid->numVertexPoints = 10; | ||||
| 	asteroid->vertexPoints    = createAsteroidVertexList( | ||||
| 	    &state->persistentArena, asteroid->numVertexPoints, | ||||
| 	    (i32)(asteroid->size.x * 0.5f)); | ||||
| 	    &world->entityArena, asteroid->numVertexPoints, | ||||
| 	    (i32)(asteroid->size.w * 0.5f)); | ||||
| 
 | ||||
| 	asteroid->tex      = NULL; | ||||
| 	asteroid->collides = TRUE; | ||||
| 	asteroid->color = V4(0.0f, 0.5f, 0.5f, 1.0f); | ||||
| } | ||||
| 
 | ||||
| INTERNAL void addBullet(World *world, Entity *shooter) | ||||
| { | ||||
| 	Entity *bullet = &world->entityList[world->entityIndex++]; | ||||
| 	bullet->id     = world->entityIdCounter++; | ||||
| 
 | ||||
| 	bullet->offset     = v2_scale(bullet->size, -0.5f); | ||||
| 	bullet->pos        = v2_add(shooter->pos, bullet->offset); | ||||
| 	bullet->hitbox     = bullet->size; | ||||
| 	bullet->size       = V2(2.0f, 20.0f); | ||||
| 	bullet->rotation   = shooter->rotation; | ||||
| 	bullet->renderMode = rendermode_quad; | ||||
| 
 | ||||
| 	// TODO(doyle): Figure out how to free this memory on entity delete. A free list?
 | ||||
| 	bullet->vertexPoints = | ||||
| 	    memory_pushBytes(&world->entityArena, sizeof(v2) * 4); | ||||
| 	bullet->vertexPoints[0] = V2(0, bullet->size.h); | ||||
| 	bullet->vertexPoints[1] = V2(0, 0); | ||||
| 	bullet->vertexPoints[2] = V2(bullet->size.w, 0); | ||||
| 	bullet->vertexPoints[3] = bullet->size; | ||||
| 
 | ||||
| 	bullet->numVertexPoints = 4; | ||||
| 
 | ||||
| 	bullet->type  = entitytype_bullet; | ||||
| 	bullet->color = V4(1.0f, 1.0f, 0, 1.0f); | ||||
| } | ||||
| 
 | ||||
| INTERNAL void setCollisionRule(World *world, enum EntityType a, | ||||
|                                enum EntityType b, b32 rule) | ||||
| { | ||||
| 	ASSERT(a <= entitytype_count); | ||||
| 	ASSERT(b <= entitytype_count); | ||||
| 	world->collisionTable[a][b] = rule; | ||||
| 	world->collisionTable[b][a] = rule; | ||||
| } | ||||
| 
 | ||||
| void asteroid_gameUpdateAndRender(GameState *state, Memory *memory, | ||||
|                                   v2 windowSize, f32 dt) | ||||
| { | ||||
| 	MemoryIndex globalTransientArenaSize = | ||||
| 	    (MemoryIndex)((f32)memory->transientSize * 0.5f); | ||||
| 	memory_arenaInit(&state->transientArena, memory->transient, | ||||
| 	                 memory->transientSize); | ||||
| 	                 globalTransientArenaSize); | ||||
| 
 | ||||
| 	World *world = &state->world; | ||||
| 	if (!state->init) | ||||
| 	{ | ||||
| 		srand((u32)time(NULL)); | ||||
| 		memory_arenaInit(&state->persistentArena, memory->persistent, | ||||
| 		                 memory->persistentSize); | ||||
| 		initAssetManager(state); | ||||
| 		initRenderer(state, windowSize); | ||||
| 
 | ||||
| 		state->pixelsPerMeter = 70.0f; | ||||
| 		world->pixelsPerMeter = 70.0f; | ||||
| 
 | ||||
| 		MemoryIndex entityArenaSize = | ||||
| 		    (MemoryIndex)((f32)memory->transientSize * 0.5f); | ||||
| 
 | ||||
| 		u8 *arenaBase = state->transientArena.base + state->transientArena.size; | ||||
| 		memory_arenaInit(&world->entityArena, arenaBase, entityArenaSize); | ||||
| 
 | ||||
| 		{ // Init asteroid entities
 | ||||
| 			i32 numAsteroids = 15; | ||||
| 			for (i32 i = 0; i < numAsteroids; i++) | ||||
| 				addAsteroid(state, windowSize); | ||||
| 				addAsteroid(world, windowSize); | ||||
| 		} | ||||
| 
 | ||||
| #if 1 | ||||
| 		{ // Init ship entity
 | ||||
| 			Entity *ship     = &state->entityList[state->entityIndex]; | ||||
| 			ship->id         = state->entityIndex++; | ||||
| 			Entity *ship     = &world->entityList[world->entityIndex++]; | ||||
| 			ship->id         = world->entityIdCounter++; | ||||
| 			ship->pos        = V2(100, 100); | ||||
| 			ship->size       = V2(25.0f, 50.0f); | ||||
| 			ship->hitbox     = ship->size; | ||||
| 			ship->offset     = v2_scale(ship->size, 0.5f); | ||||
| 			ship->offset     = v2_scale(ship->size, -0.5f); | ||||
| 
 | ||||
| 			ship->numVertexPoints = 3; | ||||
| 			ship->vertexPoints    = memory_pushBytes( | ||||
| 			    &state->persistentArena, sizeof(v2) * ship->numVertexPoints); | ||||
| 			    &world->entityArena, sizeof(v2) * ship->numVertexPoints); | ||||
| 
 | ||||
| 			v2 triangleBaseP  = V2(0, 0); | ||||
| 			v2 triangleTopP   = V2(ship->size.w * 0.5f, ship->size.h); | ||||
| @ -464,19 +505,21 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory, | ||||
| 			ship->type       = entitytype_ship; | ||||
| 			ship->direction  = direction_null; | ||||
| 			ship->renderMode = rendermode_polygon; | ||||
| 			ship->tex        = NULL; | ||||
| 			ship->collides   = TRUE; | ||||
| 
 | ||||
| 			ship->color      = V4(1.0f, 0.5f, 0.5f, 1.0f); | ||||
| 		} | ||||
| #endif | ||||
| 
 | ||||
| 		{ // Global Collision Rules
 | ||||
| 			setCollisionRule(world, entitytype_ship, entitytype_asteroid, TRUE); | ||||
| 			setCollisionRule(world, entitytype_bullet, entitytype_asteroid, | ||||
| 			                 TRUE); | ||||
| 		} | ||||
| 
 | ||||
| 		world->camera.min = V2(0, 0); | ||||
| 		world->camera.max = state->renderer.size; | ||||
| 		world->worldSize  = windowSize; | ||||
| 
 | ||||
| 		state->camera.min = V2(0, 0); | ||||
| 		state->camera.max = state->renderer.size; | ||||
| 		state->init       = TRUE; | ||||
| 
 | ||||
| 		state->worldSize = windowSize; | ||||
| 
 | ||||
| 		debug_init(&state->persistentArena, windowSize, | ||||
| 		           state->assetManager.font); | ||||
| 	} | ||||
| @ -509,26 +552,26 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory, | ||||
| 	if (getKeyStatus(&state->input.keys[keycode_left_square_bracket], | ||||
| 	                 readkeytype_repeat, 0.2f, dt)) | ||||
| 	{ | ||||
| 		addAsteroid(state, windowSize); | ||||
| 		addAsteroid(world, windowSize); | ||||
| 	} | ||||
| 
 | ||||
| 	for (i32 i = 0; i < state->entityIndex; i++) | ||||
| 	for (i32 i = 0; i < world->entityIndex; i++) | ||||
| 	{ | ||||
| 		Entity *entity = &state->entityList[i]; | ||||
| 		Entity *entity = &world->entityList[i]; | ||||
| 		ASSERT(entity->type != entitytype_invalid); | ||||
| 
 | ||||
| 		v2 pivotPoint = {0}; | ||||
| 
 | ||||
| 		// Loop entity around world
 | ||||
| 		if (entity->pos.y >= state->worldSize.h) | ||||
| 		if (entity->pos.y >= world->worldSize.h) | ||||
| 			entity->pos.y = 0; | ||||
| 		else if (entity->pos.y < 0) | ||||
| 			entity->pos.y = state->worldSize.h; | ||||
| 			entity->pos.y = world->worldSize.h; | ||||
| 
 | ||||
| 		if (entity->pos.x >= state->worldSize.w) | ||||
| 		if (entity->pos.x >= world->worldSize.w) | ||||
| 			entity->pos.x = 0; | ||||
| 		else if (entity->pos.x < 0) | ||||
| 			entity->pos.x = state->worldSize.w; | ||||
| 			entity->pos.x = world->worldSize.w; | ||||
| 
 | ||||
| 		f32 ddPSpeedInMs = 0; | ||||
| 		v2 ddP           = {0}; | ||||
| @ -560,6 +603,12 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory, | ||||
| 				entity->rotation -= (rotationsPerSecond) * dt; | ||||
| 			} | ||||
| 
 | ||||
| 			if (getKeyStatus(&state->input.keys[keycode_space], | ||||
| 			                 readkeytype_delayedRepeat, 0.0f, dt)) | ||||
| 			{ | ||||
| 				addBullet(world, entity); | ||||
| 			} | ||||
| 
 | ||||
| 			if (ddP.x > 0.0f && ddP.y > 0.0f) | ||||
| 			{ | ||||
| 				// NOTE(doyle): Cheese it and pre-compute the vector for
 | ||||
| @ -572,6 +621,11 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory, | ||||
| 			DEBUG_PUSH_VAR("Pos: %5.2f, %5.2f", entity->pos, "v2"); | ||||
| 			DEBUG_PUSH_VAR("Velocity: %5.2f, %5.2f", entity->dP, "v2"); | ||||
| 			DEBUG_PUSH_VAR("Rotation: %5.2f", entity->rotation, "f32"); | ||||
| 
 | ||||
| 			renderer_rect(&state->renderer, world->camera, entity->pos, | ||||
| 			              V2(5, 5), V2(0, 0), | ||||
| 			              DEGREES_TO_RADIANS(entity->rotation), NULL, | ||||
| 			              V4(1.0f, 1.0f, 1.0f, 1.0f), renderflag_no_texture); | ||||
| 		} | ||||
| 		else if (entity->type == entitytype_asteroid) | ||||
| 		{ | ||||
| @ -648,26 +702,43 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory, | ||||
| 			f32 dirOffset = ((randValue % 10) + 1) / 100.0f; | ||||
| 			v2_scale(ddP, dirOffset); | ||||
| 
 | ||||
| 			// NOTE(doyle): Make asteroids start and move at constant speed
 | ||||
| 			// NOTE(doyle): Make asteroids start and move at constant speed by
 | ||||
| 			// ensuring that dP is "refreshed" with non-decaying acceleration
 | ||||
| 			ddPSpeedInMs = 1; | ||||
| 			entity->dP   = v2_scale(ddP, state->pixelsPerMeter * ddPSpeedInMs); | ||||
| 			entity->dP   = v2_scale(ddP, world->pixelsPerMeter * ddPSpeedInMs); | ||||
| 			entity->rotation += (60 * dt); | ||||
| #endif | ||||
| 		} | ||||
| 		else if (entity->type == entitytype_bullet) | ||||
| 		{ | ||||
| 			ddPSpeedInMs     = 5; | ||||
| 			Radians rotation = DEGREES_TO_RADIANS((entity->rotation + 90.0f)); | ||||
| 			ddP              = V2(math_cosf(rotation), math_sinf(rotation)); | ||||
| 			entity->dP = v2_scale(ddP, world->pixelsPerMeter * ddPSpeedInMs); | ||||
| 		} | ||||
| 
 | ||||
| 		b32 willCollide = moveEntity(state, entity, i, ddP, dt, ddPSpeedInMs); | ||||
| 		v4 entityColor  = V4(1.0f, 1.0f, 1.0f, 1.0f); | ||||
| #if 1 | ||||
| 		b32 willCollide = moveEntity(world, &state->transientArena, entity, i, | ||||
| 		                             ddP, dt, ddPSpeedInMs); | ||||
| 		v4 collideColor = {0}; | ||||
| 		if (willCollide) | ||||
| 		{ | ||||
| 			entityColor = V4(1.0f, 1.0f, 0, 1.0f); | ||||
| 			collideColor = V4(1.0f, 0, 0, 0.5f); | ||||
| 		} | ||||
| 
 | ||||
| 		if (entity->type == entitytype_bullet) | ||||
| 		{ | ||||
| 			if (!math_pointInRect(world->camera, entity->pos)) | ||||
| 			{ | ||||
| 				world->entityList[i] = world->entityList[--world->entityIndex]; | ||||
| 				i--; | ||||
| 				continue; | ||||
| 			} | ||||
| 		} | ||||
| #endif | ||||
| 
 | ||||
| 		RenderFlags flags = renderflag_wireframe | renderflag_no_texture; | ||||
| 		renderer_entity(&state->renderer, &state->transientArena, state->camera, | ||||
| 		renderer_entity(&state->renderer, &state->transientArena, world->camera, | ||||
| 		                entity, V2(0, 0), 0, | ||||
| 		                entityColor, flags); | ||||
| 		                collideColor, flags); | ||||
| 	} | ||||
| 
 | ||||
| #if 1 | ||||
|  | ||||
							
								
								
									
										32
									
								
								src/Debug.c
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								src/Debug.c
									
									
									
									
									
								
							| @ -273,19 +273,27 @@ void debug_drawUi(GameState *state, f32 dt) | ||||
| 	updateAndRenderDebugStack(&state->renderer, &state->transientArena, dt); | ||||
| 	renderConsole(&state->renderer, &state->transientArena); | ||||
| 
 | ||||
| 	MemoryArena_ *transient = &state->transientArena; | ||||
| 	i32 transientSizeInKbs  = transient->size / 1024; | ||||
| 	i32 transientUsedInKbs  = transient->used / 1024; | ||||
| 	v2 transientUsage       = V2i(transientUsedInKbs, transientSizeInKbs); | ||||
| 	DEBUG_PUSH_VAR("Transient Size: %.0f", transient->size, "f32"); | ||||
| 	DEBUG_PUSH_VAR("Transient Usage: %.0f/%.0f", transientUsage, "v2"); | ||||
| 	{ // Print Memory Arena Info
 | ||||
| 		DEBUG_PUSH_STRING("== MEMORY ARENAS =="); | ||||
| 		MemoryArena_ *transient = &state->transientArena; | ||||
| 		i32 transientSizeInKbs  = transient->size / 1024; | ||||
| 		i32 transientUsedInKbs  = transient->used / 1024; | ||||
| 		v2 transientUsage       = V2i(transientUsedInKbs, transientSizeInKbs); | ||||
| 		DEBUG_PUSH_VAR("Transient Usage: %.0f/%.0f", transientUsage, "v2"); | ||||
| 
 | ||||
| 	MemoryArena_ *persistent = &state->persistentArena; | ||||
| 	i32 persistentSizeInKbs  = persistent->size / 1024; | ||||
| 	i32 persistentUsedInKbs  = persistent->used / 1024; | ||||
| 	v2 persistentUsage       = V2i(persistentUsedInKbs, persistentSizeInKbs); | ||||
| 	DEBUG_PUSH_VAR("Permanent Size: %.0f", persistent->size, "f32"); | ||||
| 	DEBUG_PUSH_VAR("Permanent Usage: %.0f/%.0f", persistentUsage, "v2"); | ||||
| 		MemoryArena_ *persistent = &state->persistentArena; | ||||
| 		i32 persistentSizeInKbs  = persistent->size / 1024; | ||||
| 		i32 persistentUsedInKbs  = persistent->used / 1024; | ||||
| 		v2 persistentUsage = V2i(persistentUsedInKbs, persistentSizeInKbs); | ||||
| 		DEBUG_PUSH_VAR("Permanent Usage: %.0f/%.0f", persistentUsage, "v2"); | ||||
| 
 | ||||
| 		MemoryArena_ *entityArena = &state->world.entityArena; | ||||
| 		i32 entitySizeInKbs       = entityArena->size / 1024; | ||||
| 		i32 entityUsedInKbs       = entityArena->used / 1024; | ||||
| 		v2 entityUsage            = V2i(entityUsedInKbs, entitySizeInKbs); | ||||
| 		DEBUG_PUSH_VAR("Entity Usage: %.0f/%.0f", entityUsage, "v2"); | ||||
| 		DEBUG_PUSH_STRING("== =="); | ||||
| 	} | ||||
| 
 | ||||
| 	DEBUG_PUSH_VAR("Num Vertex: %d", | ||||
| 	               GLOBAL_debug.callCount[debugcount_numVertex], "i32"); | ||||
|  | ||||
| @ -89,8 +89,12 @@ void entity_addAnim(AssetManager *const assetManager, Entity *const entity, | ||||
| 	DEBUG_LOG("No more free entity animation slots"); | ||||
| } | ||||
| 
 | ||||
| v2 *entity_createVertexList(MemoryArena_ *transientArena, Entity *entity) | ||||
| v2 *entity_generateUpdatedVertexList(MemoryArena_ *transientArena, | ||||
|                                      Entity *entity) | ||||
| { | ||||
| 	ASSERT(entity->vertexPoints); | ||||
| 	ASSERT(entity->numVertexPoints >= 3); | ||||
| 
 | ||||
| 	v2 *result = | ||||
| 	    memory_pushBytes(transientArena, entity->numVertexPoints * sizeof(v2)); | ||||
| 
 | ||||
| @ -98,9 +102,10 @@ v2 *entity_createVertexList(MemoryArena_ *transientArena, Entity *entity) | ||||
| 	{ | ||||
| 		result[i] = v2_add(entity->vertexPoints[i], entity->offset); | ||||
| 		result[i] = v2_add(result[i], entity->pos); | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	math_applyRotationToVertexes(result[0], entity->offset, | ||||
| 	math_applyRotationToVertexes(entity->pos, V2(0 ,0), | ||||
| 	                             DEGREES_TO_RADIANS(entity->rotation), result, | ||||
| 	                             entity->numVertexPoints); | ||||
| 
 | ||||
|  | ||||
| @ -574,11 +574,15 @@ void renderer_entity(Renderer *renderer, MemoryArena_ *transientArena, | ||||
| 		renderTex.texRect = texRect; | ||||
| 	} | ||||
| 
 | ||||
| 	// TODO(doyle): Proper blending
 | ||||
| 	v4 renderColor = color; | ||||
| 	if (v4_equals(color, V4(0, 0, 0, 0))) renderColor = entity->color; | ||||
| 
 | ||||
| 	if (entity->renderMode == rendermode_quad) | ||||
| 	{ | ||||
| 		renderer_rect(renderer, camera, entity->pos, entity->size, | ||||
| 		              v2_add(entity->offset, pivotPoint), totalRotation, | ||||
| 		              &renderTex, color, flags); | ||||
| 		              &renderTex, entity->color, flags); | ||||
| 	} | ||||
| 	else if (entity->renderMode == rendermode_polygon) | ||||
| 	{ | ||||
| @ -586,12 +590,12 @@ void renderer_entity(Renderer *renderer, MemoryArena_ *transientArena, | ||||
| 		ASSERT(entity->vertexPoints); | ||||
| 
 | ||||
| 		v2 *offsetVertexPoints = | ||||
| 		    entity_createVertexList(transientArena, entity); | ||||
| 		    entity_generateUpdatedVertexList(transientArena, entity); | ||||
| 
 | ||||
| 		renderer_polygon(renderer, camera, offsetVertexPoints, | ||||
| 		                 entity->numVertexPoints, | ||||
| 		                 v2_add(entity->offset, pivotPoint), totalRotation, | ||||
| 		                 &renderTex, color, flags); | ||||
| 		                 &renderTex, renderColor, flags); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
|  | ||||
| @ -172,8 +172,13 @@ i32 main(void) | ||||
| 	memory.transientSize = transientSize; | ||||
| 	memory.transient     = PLATFORM_MEM_ALLOC_(NULL, transientSize, u8); | ||||
| 
 | ||||
| 	GameState gameState = {0}; | ||||
| 	glfwSetWindowUserPointer(window, CAST(void *)(&gameState)); | ||||
| 	MemoryArena_ gameArena = {0}; | ||||
| 	memory_arenaInit(&gameArena, memory.persistent, memory.persistentSize); | ||||
| 
 | ||||
| 	GameState *gameState = MEMORY_PUSH_STRUCT(&gameArena, GameState); | ||||
| 	gameState->persistentArena = gameArena; | ||||
| 
 | ||||
| 	glfwSetWindowUserPointer(window, CAST(void *)(gameState)); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 ******************* | ||||
| @ -203,7 +208,7 @@ i32 main(void) | ||||
| 		glClearColor(0.2f, 0.2f, 0.2f, 1.0f); | ||||
| 		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | ||||
| 
 | ||||
| 		asteroid_gameUpdateAndRender(&gameState, &memory, windowSize, | ||||
| 		asteroid_gameUpdateAndRender(gameState, &memory, windowSize, | ||||
| 		                             secondsElapsed); | ||||
| 		GL_CHECK_ERROR(); | ||||
| 
 | ||||
| @ -233,7 +238,7 @@ i32 main(void) | ||||
| 			char textBuffer[256]; | ||||
| 			snprintf(textBuffer, ARRAY_COUNT(textBuffer), | ||||
| 			         "Dengine | %f ms/f | %f fps | Entity Count: %d", | ||||
| 			         msPerFrame, framesPerSecond, gameState.entityIndex); | ||||
| 			         msPerFrame, framesPerSecond, gameState->world.entityIndex); | ||||
| 
 | ||||
| 			glfwSetWindowTitle(window, textBuffer); | ||||
| 			titleUpdateFrequencyInSeconds = 0.5f; | ||||
|  | ||||
| @ -8,23 +8,35 @@ | ||||
| #include "Dengine/Platform.h" | ||||
| #include "Dengine/Renderer.h" | ||||
| 
 | ||||
| typedef struct World | ||||
| { | ||||
| 	MemoryArena_ entityArena; | ||||
| 
 | ||||
| 	v2 *entityVertexListCache[entitytype_count]; | ||||
| 	Entity entityList[1024]; | ||||
| 	i32 entityIndex; | ||||
| 
 | ||||
| 	u32 entityIdCounter; | ||||
| 
 | ||||
| 	f32 pixelsPerMeter; | ||||
| 	v2 worldSize; | ||||
| 	Rect camera; | ||||
| 
 | ||||
| 	// TODO(doyle): Ensure we change this if it gets too big
 | ||||
| 	b32 collisionTable[entitytype_count][entitytype_count]; | ||||
| } World; | ||||
| 
 | ||||
| typedef struct GameState { | ||||
| 	b32 init; | ||||
| 
 | ||||
| 	Entity entityList[1024]; | ||||
| 	i32 entityIndex; | ||||
| 	f32 pixelsPerMeter; | ||||
| 
 | ||||
| 	v2 worldSize; | ||||
| 
 | ||||
| 	Rect camera; | ||||
| 
 | ||||
| 	World world; | ||||
| 	AssetManager assetManager; | ||||
| 	KeyInput input; | ||||
| 
 | ||||
| 	MemoryArena_ transientArena; | ||||
| 	MemoryArena_ persistentArena; | ||||
| 
 | ||||
| 
 | ||||
| 	Renderer renderer; | ||||
| } GameState; | ||||
| 
 | ||||
|  | ||||
| @ -28,6 +28,7 @@ enum EntityType | ||||
| 	entitytype_invalid, | ||||
| 	entitytype_ship, | ||||
| 	entitytype_asteroid, | ||||
| 	entitytype_bullet, | ||||
| 	entitytype_count, | ||||
| }; | ||||
| 
 | ||||
| @ -42,10 +43,7 @@ typedef struct EntityAnim | ||||
| 
 | ||||
| typedef struct Entity | ||||
| { | ||||
| 	i32 id; | ||||
| 
 | ||||
| 	i32 childIds[8]; | ||||
| 	i32 numChilds; | ||||
| 	u32 id; | ||||
| 
 | ||||
| 	v2 pos; | ||||
| 	v2 dP; | ||||
| @ -53,11 +51,11 @@ typedef struct Entity | ||||
| 	v2 hitbox; | ||||
| 	v2 size; | ||||
| 
 | ||||
| 	// NOTE(doyle): Offset from origin point to the entity's considered "center"
 | ||||
| 	// point, all operations work from this point, i.e. rotation, movement,
 | ||||
| 	// collision detection
 | ||||
| 	// If this is a polygon, the offset should be from the 1st vertex point
 | ||||
| 	// specified
 | ||||
| 	/*
 | ||||
| 	   NOTE(doyle): Offset is the vector to shift the polygons "origin" to the | ||||
| 	   world origin. In our case this should strictly be negative as we have | ||||
| 	   a requirement that all vertex points must be strictly positive. | ||||
|    */ | ||||
| 	v2 offset; | ||||
| 
 | ||||
| 	enum RenderMode renderMode; | ||||
| @ -70,17 +68,11 @@ typedef struct Entity | ||||
| 	enum EntityType type; | ||||
| 	enum Direction direction; | ||||
| 
 | ||||
| 	v4 color; | ||||
| 	Texture *tex; | ||||
| 	b32 flipX; | ||||
| 	b32 flipY; | ||||
| 
 | ||||
| 	// TODO(doyle): Two collision flags, we want certain entities to collide
 | ||||
| 	// with certain types of entities only (i.e. projectile from hero to enemy,
 | ||||
| 	// only collides with enemy). Having two flags is redundant, but! it does
 | ||||
| 	// allow for early-exit in collision check if the entity doesn't collide at
 | ||||
| 	// all
 | ||||
| 	b32 collides; | ||||
| 
 | ||||
| 	EntityAnim animList[16]; | ||||
| 	i32 animListIndex; | ||||
| 
 | ||||
| @ -95,5 +87,6 @@ void entity_updateAnim(Entity *const entity, const f32 dt); | ||||
| void entity_addAnim(AssetManager *const assetManager, Entity *const entity, | ||||
|                     const char *const animName); | ||||
| 
 | ||||
| v2 *entity_createVertexList(MemoryArena_ *transientArena, Entity *entity); | ||||
| v2 *entity_generateUpdatedVertexList(MemoryArena_ *transientArena, | ||||
|                                      Entity *entity); | ||||
| #endif | ||||
|  | ||||
| @ -410,5 +410,23 @@ INTERNAL inline void math_applyRotationToVertexes(v2 pos, v2 pivotPoint, | ||||
| 		vertexList[i] = newP; | ||||
| 	} | ||||
| } | ||||
| INTERNAL inline f32 math_lerp(f32 a, f32 t, f32 b) | ||||
| { | ||||
| 	/*
 | ||||
| 	    Linear blend between two values. We having a starting point "a", and | ||||
| 	    the distance to "b" is defined as (b - a). Then we can say | ||||
| 
 | ||||
| 	    a + t(b - a) | ||||
| 
 | ||||
| 	    As our linear blend fn. We start from "a" and choosing a t from 0->1 | ||||
| 	    will vary the value of (b - a) towards b. If we expand this, this | ||||
| 	    becomes | ||||
| 
 | ||||
| 	    a + (t * b) - (a * t) == (1 - t)a + t*b | ||||
| 	*/ | ||||
| 	f32 result = ((1 - t) * a) + (t * b); | ||||
| 
 | ||||
| 	return result; | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user