// Copyright (c) 2023 Alex Diener. All rights reserved. #include "PROJECT_NAME/Globals.h" #include "PROJECT_NAME/RoomVisual.h" RoomVisual * RoomVisual_create(RoomState * roomState) { RoomVisual * self = malloc(sizeof(*self)); self->layers = malloc(roomState->roomData->layerCount * sizeof(*self->layers)); self->layerCount = 0; for (unsigned int layerIndex = 0; layerIndex < roomState->roomData->layerCount; layerIndex++) { if (roomState->roomData->layers[layerIndex].type == ROOM_LAYER_TYPE_GROUND || roomState->roomData->layers[layerIndex].type == ROOM_LAYER_TYPE_OBSTACLE) { self->layers[self->layerCount].type = roomState->roomData->layers[layerIndex].type; self->layers[self->layerCount].visual = TileMapVisual_create(g_tileset, g_imageCollection); TileMapVisual_addTileInstanceGrid(self->layers[self->layerCount].visual, &roomState->roomData->layers[layerIndex].tileGrid, roomState->roomData->layers[layerIndex].offset); self->layerCount++; } } return self; } void RoomVisual_dispose(RoomVisual * self) { for (unsigned int layerIndex = 0; layerIndex < self->layerCount; layerIndex++) { TileMapVisual_dispose(self->layers[layerIndex].visual); } free(self->layers); free(self); } RoomVisual * RoomVisual_copy(RoomVisual * self) { RoomVisual * copy = malloc(sizeof(*copy)); copy->layerCount = self->layerCount; copy->layers = malloc(self->layerCount * sizeof(*self->layers)); for (unsigned int layerIndex = 0; layerIndex < self->layerCount; layerIndex++) { copy->layers[layerIndex].type = self->layers[layerIndex].type; copy->layers[layerIndex].visual = TileMapVisual_copy(self->layers[layerIndex].visual); } return copy; } void RoomVisual_draw(RoomVisual * self, Vector2f offset, VertexIO * vertexIO) { float drawnTileWidth = g_tileset->tileSize.x; float drawnTileHeight = g_tileset->tileSize.y; struct vertex_p2f_t2f_c4f vertices[4], vertex = {.position = {0.0f, 0.0f}, .color = {1.0f, 1.0f, 1.0f, 1.0f}}; uint32_t indexes[6] = {0, 1, 2, 2, 3, 0}; for (unsigned int layerIndex = 0; layerIndex < self->layerCount; layerIndex++) { TileMapVisual * visual = self->layers[layerIndex].visual; for (unsigned int drawnTileIndex = 0; drawnTileIndex < visual->drawnTileCount; drawnTileIndex++) { TileMapVisual_drawnTile drawnTile = visual->drawnTiles[drawnTileIndex]; Vector2f tilePosition = VECTOR2f(offset.x + drawnTile.tilePosition.x * drawnTileWidth + drawnTile.offset.x, offset.y + TILE_MAP_HEIGHT * TILE_HEIGHT - (drawnTile.tilePosition.y * drawnTileHeight + drawnTile.offset.y)); Rect4f tileBounds = Rect4f_fromPositionSizeOrigin(tilePosition, VECTOR2f(drawnTile.size.x, drawnTile.size.y), VECTOR2f(0.0f, 1.0f)); vertex.position[0] = tileBounds.xMin; vertex.position[1] = tileBounds.yMax; vertex.texCoords[0] = drawnTile.textureBounds.xMin; vertex.texCoords[1] = drawnTile.textureBounds.yMax; vertices[0] = vertex; vertex.position[1] = tileBounds.yMin; vertex.texCoords[1] = drawnTile.textureBounds.yMin; vertices[1] = vertex; vertex.position[0] = tileBounds.xMax; vertex.texCoords[0] = drawnTile.textureBounds.xMax; vertices[2] = vertex; vertex.position[1] = tileBounds.yMax; vertex.texCoords[1] = drawnTile.textureBounds.yMax; vertices[3] = vertex; unsigned int vertexCount = 4, indexCount = 6; switch (drawnTile.shape) { case TILE_SHAPE_QUAD: break; case TILE_SHAPE_TRIANGLE_UPPER_LEFT: vertexCount = indexCount = 3; vertices[2] = vertices[3]; break; case TILE_SHAPE_TRIANGLE_UPPER_RIGHT: vertexCount = indexCount = 3; vertices[1] = vertices[2]; vertices[2] = vertices[3]; break; case TILE_SHAPE_TRIANGLE_LOWER_LEFT: vertexCount = indexCount = 3; break; case TILE_SHAPE_TRIANGLE_LOWER_RIGHT: vertexCount = indexCount = 3; vertices[0] = vertices[1]; vertices[1] = vertices[2]; vertices[2] = vertices[3]; break; } VertexIO_writeIndexedVertices(vertexIO, vertexCount, vertices, indexCount, indexes); } } }