X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Finterface.cpp;h=a5dcc0e06a77b9a7caf6f90cd26cd7f02ebcb3e1;hb=e53a0e2e711a7d8bd9b0ddacd1360aa14370643f;hp=f20903bd0a2c5acec54f7d2bd5904c66e160c02f;hpb=c3c5045f06327db2a3c97eae77a072bc06677286;p=blank.git diff --git a/src/interface.cpp b/src/interface.cpp index f20903b..a5dcc0e 100644 --- a/src/interface.cpp +++ b/src/interface.cpp @@ -1,85 +1,217 @@ #include "interface.hpp" -#include "geometry.hpp" #include "world.hpp" -#include +#include #include +#include namespace blank { -Interface::Interface(World &world) +Interface::Interface(const Config &config, World &world) : world(world) , ctrl(world.Player()) -, hud() +, hud(world.BlockTypes()) +, aim{{ 0, 0, 0 }, { 0, 0, -1 }} , aim_chunk(nullptr) , aim_block(0) , aim_normal() , outline() , outline_transform(1.0f) -, move_velocity(0.005f) -, pitch_sensitivity(-0.0025f) -, yaw_sensitivity(-0.001f) +, config(config) +, place_timer(256) +, remove_timer(256) , remove(0) , selection(1) -, front(false) -, back(false) -, left(false) -, right(false) -, up(false) -, down(false) { +, fwd(0) +, rev(0) { hud.Viewport(960, 600); - hud.Display(*world.BlockTypes()[selection.type]); + hud.Display(selection); } -void Interface::Handle(const SDL_KeyboardEvent &event) { +void Interface::HandlePress(const SDL_KeyboardEvent &event) { + if (config.keyboard_disabled) return; + switch (event.keysym.sym) { case SDLK_w: - front = event.state == SDL_PRESSED; + rev.z = 1; break; case SDLK_s: - back = event.state == SDL_PRESSED; + fwd.z = 1; break; case SDLK_a: - left = event.state == SDL_PRESSED; + rev.x = 1; break; case SDLK_d: - right = event.state == SDL_PRESSED; + fwd.x = 1; break; - case SDLK_q: case SDLK_SPACE: - up = event.state == SDL_PRESSED; + fwd.y = 1; + break; + case SDLK_LSHIFT: + rev.y = 1; + break; + + case SDLK_q: + FaceBlock(); break; case SDLK_e: + TurnBlock(); + break; + + case SDLK_b: + PrintBlockInfo(); + break; + case SDLK_c: + PrintChunkInfo(); + break; + case SDLK_l: + PrintLightInfo(); + break; + case SDLK_p: + PrintSelectionInfo(); + break; + } +} + +void Interface::HandleRelease(const SDL_KeyboardEvent &event) { + if (config.keyboard_disabled) return; + + switch (event.keysym.sym) { + case SDLK_w: + rev.z = 0; + break; + case SDLK_s: + fwd.z = 0; + break; + case SDLK_a: + rev.x = 0; + break; + case SDLK_d: + fwd.x = 0; + break; + case SDLK_SPACE: + fwd.y = 0; + break; case SDLK_LSHIFT: - down = event.state == SDL_PRESSED; + rev.y = 0; break; } } +void Interface::FaceBlock() { + selection.SetFace(Block::Face((selection.GetFace() + 1) % Block::FACE_COUNT)); + hud.Display(selection); +} + +void Interface::TurnBlock() { + selection.SetTurn(Block::Turn((selection.GetTurn() + 1) % Block::TURN_COUNT)); + hud.Display(selection); +} + +void Interface::PrintBlockInfo() { + std::cout << std::endl; + if (!aim_chunk) { + std::cout << "not looking at any block" << std::endl; + Ray aim = ctrl.Aim(); + std::cout << "aim ray: " << aim.orig << ", " << aim.dir << std::endl; + return; + } + std::cout << "looking at block " << aim_block + << " " << Chunk::ToCoords(aim_block) + << " of chunk " << aim_chunk->Position() + << std::endl; + Print(aim_chunk->BlockAt(aim_block)); +} + +void Interface::PrintChunkInfo() { + std::cout << std::endl; + if (!aim_chunk) { + std::cout << "not looking at any block" << std::endl; + return; + } + std::cout << "looking at chunk " + << aim_chunk->Position() + << std::endl; + + std::cout << " neighbors:" << std::endl; + if (aim_chunk->HasNeighbor(Block::FACE_LEFT)) { + std::cout << " left " << aim_chunk->GetNeighbor(Block::FACE_LEFT).Position() << std::endl; + } + if (aim_chunk->HasNeighbor(Block::FACE_RIGHT)) { + std::cout << " right " << aim_chunk->GetNeighbor(Block::FACE_RIGHT).Position() << std::endl; + } + if (aim_chunk->HasNeighbor(Block::FACE_UP)) { + std::cout << " up " << aim_chunk->GetNeighbor(Block::FACE_UP).Position() << std::endl; + } + if (aim_chunk->HasNeighbor(Block::FACE_DOWN)) { + std::cout << " down " << aim_chunk->GetNeighbor(Block::FACE_DOWN).Position() << std::endl; + } + if (aim_chunk->HasNeighbor(Block::FACE_FRONT)) { + std::cout << " front " << aim_chunk->GetNeighbor(Block::FACE_FRONT).Position() << std::endl; + } + if (aim_chunk->HasNeighbor(Block::FACE_BACK)) { + std::cout << " back " << aim_chunk->GetNeighbor(Block::FACE_BACK).Position() << std::endl; + } + std::cout << std::endl; +} + +void Interface::PrintLightInfo() { + std::cout + << "light level " << world.PlayerChunk().GetLight(world.Player().Position()) + << " at position " << world.Player().Position() + << std::endl; +} + +void Interface::PrintSelectionInfo() { + std::cout << std::endl; + Print(selection); +} + +void Interface::Print(const Block &block) { + std::cout << "type: " << block.type + << ", face: " << block.GetFace() + << ", turn: " << block.GetTurn() + << std::endl; +} + + void Interface::Handle(const SDL_MouseMotionEvent &event) { - ctrl.RotateYaw(event.xrel * yaw_sensitivity); - ctrl.RotatePitch(event.yrel * pitch_sensitivity); + if (config.mouse_disabled) return; + ctrl.RotateYaw(event.xrel * config.yaw_sensitivity); + ctrl.RotatePitch(event.yrel * config.pitch_sensitivity); } -void Interface::Handle(const SDL_MouseButtonEvent &event) { - if (event.state != SDL_PRESSED) return; +void Interface::HandlePress(const SDL_MouseButtonEvent &event) { + if (config.mouse_disabled) return; if (event.button == 1) { RemoveBlock(); + remove_timer.Start(); } else if (event.button == 2) { PickBlock(); } else if (event.button == 3) { PlaceBlock(); + place_timer.Start(); + } +} + +void Interface::HandleRelease(const SDL_MouseButtonEvent &event) { + if (config.mouse_disabled) return; + + if (event.button == 1) { + remove_timer.Stop(); + } else if (event.button == 3) { + place_timer.Stop(); } } void Interface::PickBlock() { if (!aim_chunk) return; selection = aim_chunk->BlockAt(aim_block); - hud.Display(*world.BlockTypes()[selection.type]); + hud.Display(selection); } void Interface::PlaceBlock() { @@ -90,18 +222,20 @@ void Interface::PlaceBlock() { mod_chunk = &world.Next(*aim_chunk, aim_normal); next_pos -= aim_normal * glm::vec3(Chunk::Extent()); } - mod_chunk->BlockAt(next_pos) = selection; + mod_chunk->SetBlock(next_pos, selection); mod_chunk->Invalidate(); } -void Interface::RemoveBlock() { +void Interface::RemoveBlock() noexcept { if (!aim_chunk) return; - aim_chunk->BlockAt(aim_block) = remove; + aim_chunk->SetBlock(aim_block, remove); aim_chunk->Invalidate(); } void Interface::Handle(const SDL_MouseWheelEvent &event) { + if (config.mouse_disabled) return; + if (event.y < 0) { SelectNext(); } else if (event.y > 0) { @@ -114,7 +248,7 @@ void Interface::SelectNext() { if (size_t(selection.type) >= world.BlockTypes().Size()) { selection.type = 1; } - hud.Display(*world.BlockTypes()[selection.type]); + hud.Display(selection); } void Interface::SelectPrevious() { @@ -122,10 +256,10 @@ void Interface::SelectPrevious() { if (selection.type <= 0) { selection.type = world.BlockTypes().Size() - 1; } - hud.Display(*world.BlockTypes()[selection.type]); + hud.Display(selection); } -void Interface::Handle(const SDL_WindowEvent &event) { +void Interface::Handle(const SDL_WindowEvent &event) noexcept { if (event.event == SDL_WINDOWEVENT_RESIZED) { hud.Viewport(event.data1, event.data2); } @@ -133,41 +267,43 @@ void Interface::Handle(const SDL_WindowEvent &event) { void Interface::Update(int dt) { - glm::vec3 vel; - if (right && !left) { - vel.x = move_velocity; - } else if (left && !right) { - vel.x = -move_velocity; - } - if (up && !down) { - vel.y = move_velocity; - } else if (down && !up) { - vel.y = -move_velocity; - } - if (back && !front) { - vel.z = move_velocity; - } else if (front && !back) { - vel.z = -move_velocity; - } - ctrl.Velocity(vel); + ctrl.Velocity(glm::vec3(fwd - rev) * config.move_velocity); ctrl.Update(dt); - Ray aim = ctrl.Aim(); + place_timer.Update(dt); + remove_timer.Update(dt); + + aim = ctrl.Aim(); + CheckAim(); + + if (remove_timer.Hit()) { + RemoveBlock(); + CheckAim(); + } + + if (place_timer.Hit()) { + PlaceBlock(); + CheckAim(); + } +} + +void Interface::CheckAim() { float dist; if (world.Intersection(aim, glm::mat4(1.0f), &aim_chunk, &aim_block, &dist, &aim_normal)) { outline.Clear(); aim_chunk->Type(aim_chunk->BlockAt(aim_block)).FillOutlineModel(outline); - outline_transform = glm::scale(glm::mat4(1.0f), glm::vec3(1.0002f)); - outline_transform = aim_chunk->Transform(world.Player().ChunkCoords()); - outline_transform *= aim_chunk->ToTransform(aim_block); + outline_transform = glm::scale(glm::vec3(1.0002f)); + outline_transform *= aim_chunk->Transform(world.Player().ChunkCoords()); + outline_transform *= aim_chunk->ToTransform(Chunk::ToPos(aim_block), aim_block); } else { aim_chunk = nullptr; } - } -void Interface::Render(DirectionalLighting &program) { +void Interface::Render(DirectionalLighting &program) noexcept { + if (config.visual_disabled) return; + if (aim_chunk) { program.SetM(outline_transform); outline.Draw();