#include "game.h" #include "utils.h" void resetScreenScale(Game* game) { Texture texture = game->screen.render.texture; // Get screen size on window. float renderWidth = GetRenderWidth(); float renderHeight = GetRenderHeight(); float scale; if (renderWidth > renderHeight) { scale = (float)renderHeight / texture.height; } else { scale = (float)renderWidth / texture.width; } game->screen.scale = scale; float width = texture.width * scale; float height = texture.height * scale; game->screen.destination = (Rectangle){ renderWidth / 2.0 - width / 2.0, renderHeight / 2.0 - height / 2.0, width, height }; // Fuck ultra-wide. game->screen.ultraWideMode = renderWidth / renderHeight >= MAX_ASPECT; if (game->screen.ultraWideMode) { game->screen.destination = (Rectangle){ renderWidth / 2.0, renderHeight / 2.0, renderWidth, renderHeight }; } } void initGame(Game* game) { game->sceneId = GAME_SCENE; // Settings. game->settings = defaultSettings(); game->isCrossHairEnabled = game->settings.isCrossHairEnabledDefault; game->showFPS = game->settings.showFPSDefault; // Window. InitWindow(game->settings.windowWidth, game->settings.windowHeight, "Find Things"); SetWindowState(FLAG_WINDOW_RESIZABLE); if (game->settings.maxFPS != 0) { SetTargetFPS(game->settings.maxFPS); } // Screen. game->screen.render = LoadRenderTexture(game->settings.screenWidth, game->settings.screenHeight); resetScreenScale(game); game->screen.postprocesserShader = POSTPROCESSING_SHADER; // Assets. initAssets(&game->assets, &game->settings); // Skybox. game->skybox = LoadModelFromMesh(GenMeshCube(1.0, 1.0, 1.0)); game->skybox.materials[0].shader = game->assets.shaders[SKYBOX_SHADER]; game->skybox.materials[0].maps[MATERIAL_MAP_CUBEMAP].texture = LoadTextureCubemap(game->assets.images[SKYBOX_IMAGE], CUBEMAP_LAYOUT_AUTO_DETECT); // World. game->world = createWorld(345893, &game->assets); // Player. game->player = createPlayer(); game->player.camera.fovy = game->settings.fov; game->player.position = Vector3Scale(game->world.size, 0.5); // Map. initMap(&game->map, &game->world, &game->settings); // Interaction chat and menu. initInteractionChat(&game->interactionChat, &game->settings); initInteractionMenu(&game->interactionMenu, &game->settings); // Inventory. initInventory(&game->inventory, &game->settings); disableGameCursor(game); } void updateMainMenuScene(Game* game) { ClearBackground(BLACK); } void drawGameTexturedBackground(Texture texture) { int screenWidth = GetRenderWidth(); int screenHeight = GetRenderHeight(); for (int y = 0; y < screenHeight; y += texture.height) { for (int x = 0; x < screenWidth; x += texture.width) { DrawTexture(texture, x, y, WHITE); } } } void drawGameScreen(Game* game) { Texture texture = game->screen.render.texture; if (game->screen.ultraWideMode) { BeginShaderMode(game->assets.shaders[FUCK_SHADER]); DrawTexturePro( texture, (Rectangle){0.0, 0.0, texture.width, -texture.height}, game->screen.destination, (Vector2){GetRenderWidth() / 2.0, GetRenderHeight() / 2.0}, (int)(GetTime() * ULTRA_WIDE_SPIN_SPEED) % 360, WHITE); EndShaderMode(); DrawText("FUCK ULTRA WIDE FUCK ULTRA WIDE FUCK ULTRA WIDE FUCK ULTRA WIDE FUCK ULTRA WIDE FUCK ULTRA WIDE FUCK ULTRA WIDE FUCK ULTRA WIDE", 0.0, 0.0, 50, RED); } else { BeginShaderMode(game->assets.shaders[game->screen.postprocesserShader]); DrawTexturePro( texture, (Rectangle){0.0, 0.0, texture.width, -texture.height}, game->screen.destination, (Vector2){0.0, 0.0}, 0.0, WHITE); EndShaderMode(); } } void drawCrosshair(float crossHairSize, float crossHairThickness, Color color) { float screenHalfWidth = GetRenderWidth() / 2.0; float screenHalfHeight = GetRenderHeight() / 2.0; float halfThickness = crossHairThickness / 2.0; // Vertical. DrawLineEx( (Vector2){screenHalfWidth - crossHairSize, screenHalfHeight}, (Vector2){screenHalfWidth + crossHairSize, screenHalfHeight}, crossHairThickness, color); // Horizontal. DrawLineEx( (Vector2){screenHalfWidth, screenHalfHeight - crossHairSize}, (Vector2){screenHalfWidth, screenHalfHeight + crossHairSize}, crossHairThickness, color); } void updateGameEntityInfo(Game* game) { // Get size. float screenWidth = GetRenderWidth(); float screenHeight = GetRenderWidth(); float x = game->map.rect.x + (game->map.rect.width * 0.25); float y = game->map.rect.y + game->map.rect.height; int lines = 1; int fontSize = game->settings.entityInfoFontSize; if (!game->map.isEnabled) { y = 0.0; } WorldUID selected = game->player.selectedEntity; if (selected == ENTITY_NONE) { return; } Color backgroundColor = PINK; backgroundColor.a = game->settings.statusAndInfoAlpha; DrawRectangle(x, y, screenWidth - x, lines * fontSize, backgroundColor); // Draw name. Entity* selectedEntity = &game->world.entities[selected]; DrawText(getEntityName(selectedEntity->id), x, y, fontSize, BLACK); } void updateGameStatus(Game* game) { float x; float y; float width; float height; int fontSize = 20; int lineCount = 3; int maxColumns = 24; float maxWidth = maxColumns * fontSize / 2.0; bool topBarStyle = game->screen.destination.x < maxWidth / 2.0; const char* spacer = topBarStyle ? ", " : "\n"; // Format text. char placeAt[ENTITY_NAME_MAX] = "Back woods"; WorldUID place = game->player.place; if (place != ENTITY_NONE) { strncpy(placeAt, getEntityName(game->world.entities[place].id), ENTITY_NAME_MAX - 1); } const char* text = TextFormat( "At: %s%sSpeed %d%sPee level: 7", placeAt, spacer, (int)roundf(game->player.speed), spacer); // Handle bar style. if (topBarStyle) // Top bar style. { x = 110.0; y = 1.0; width = (getStringLength(text, 255) + 1) * fontSize / 2.0; height = fontSize; } else // Side bar style. { x = 1.0; y = game->showFPS ? 20.0 : 0.0; width = maxWidth; height = fontSize * lineCount; } // Draw text and background. Color backgroundColor = PINK; backgroundColor.a = game->settings.statusAndInfoAlpha; DrawRectangle(x, y, width, height, backgroundColor); DrawText(text, x, y, fontSize, BLACK); } void updateGameScene(Game* game) { // Handle toggle cursor. if (IsKeyPressed(game->settings.toggleCursorKey)) { if (game->isCursorEnabled) { disableGameCursor(game); } else { enableGameCursor(game); } } BeginTextureMode(game->screen.render); ClearBackground(PINK); BeginMode3D(game->player.camera); // Render skybox. rlDisableBackfaceCulling(); rlDisableDepthMask(); DrawModel(game->skybox, Vector3Zero(), 1.0, WHITE); rlEnableBackfaceCulling(); rlEnableDepthMask(); updatePlayer(&game->player, game); updateWorld(&game->world, game); EndMode3D(); EndTextureMode(); // Draw background texture or color. if (game->settings.useBackgroundTexture && !FloatEquals(game->screen.destination.x, 0.0)) { AssetId backgroundTextureId = BACKGROUND1_TEXTURE + game->settings.backgroundTextureNumber; drawGameTexturedBackground(game->assets.textures[backgroundTextureId]); } else { ClearBackground(game->settings.backgroundColor); } drawGameScreen(game); // Cross hair. if (IsKeyPressed(game->settings.toggleCrossHairKey)) { game->isCrossHairEnabled = !game->isCrossHairEnabled; } if (game->isCrossHairEnabled) { drawCrosshair(game->settings.crossHairSize, game->settings.crossHairThickness, game->settings.crossHairColor); } updateMap(&game->map, game); updateGameEntityInfo(game); updateGameStatus(game); updateInteractionChat(&game->interactionChat, game); updateInteractionMenu(&game->interactionMenu, game); updateInventory(&game->inventory, game); } void handleGameResize(Game* game) { resetScreenScale(game); } void updateGame(Game* game) { BeginDrawing(); if (IsWindowResized()) { handleGameResize(game); } switch (game->sceneId) { case MAIN_MENU_SCENE: updateMainMenuScene(game); break; case GAME_SCENE: updateGameScene(game); break; default: break; } // FPS stuff. if (IsKeyPressed(game->settings.toggleFPSKey)) { game->showFPS = !game->showFPS; } if (game->showFPS) { DrawFPS(0, 0); } EndDrawing(); } void closeGame(Game* game) { closeAssets(&game->assets); UnloadRenderTexture(game->screen.render); UnloadTexture(game->skybox.materials[0].maps[MATERIAL_MAP_CUBEMAP].texture); UnloadModel(game->skybox); freeWorld(game->world); closeMap(&game->map); CloseWindow(); } void enableGameCursor(Game* game) { game->isCursorEnabled = true; EnableCursor(); } void disableGameCursor(Game* game) { game->isCursorEnabled = false; DisableCursor(); }