[Add] Implement system boot sequence screen.
This commit is contained in:
		
							parent
							
								
									e72cc987ff
								
							
						
					
					
						commit
						6876cbff95
					
				
							
								
								
									
										24
									
								
								assets/boot_messages.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								assets/boot_messages.txt
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,24 @@
 | 
			
		||||
[  0.000000] Bettola version 6.1.0-bettola (dev@bettola)
 | 
			
		||||
[  0.000000] Command line: BOOT_IMAGE=/vmbettola-6.1.0 ro quiet
 | 
			
		||||
[  0.134589] ACPI: PM-Timer IO Port: 0x808
 | 
			
		||||
[  0.345821] pci 0000:00:02.0: vgaarb: setting as boot VGA device
 | 
			
		||||
[  0.345911] pci 0000:00:03.0: enp0s3: identified as [B77A:1337]
 | 
			
		||||
[  0.582190] systemd[1]: Starting systemd-journald.service...
 | 
			
		||||
[  0.621337] systemd-journald[218]: Journal started.
 | 
			
		||||
[  1.123456] EXT4-fs (sda1): mounted filesystem with ordered data mode.
 | 
			
		||||
[  1.567890] systemd[1]: Reached target Local File Systems.
 | 
			
		||||
[  1.890123] systemd[1]: Starting systemd-logind.service...
 | 
			
		||||
[  2.101122] systemd[1]: Starting NetworkManager.service...
 | 
			
		||||
[  2.334455] NetworkManager[310]: <info>  [1678886400.123] NetworkManager (version 1.40.0) is
 | 
			
		||||
starting...
 | 
			
		||||
[  2.800100] enp0s3: Link is up at 1000 Mbps, full duplex.
 | 
			
		||||
[  3.123456] systemd[1]: Reached target Network.
 | 
			
		||||
[  3.500000] systemd[1]: Starting Bettola Daemon...
 | 
			
		||||
[  3.600000] bettolad[420]: Initializing VFS...
 | 
			
		||||
[  3.700000] bettolad[420]: Generating world...
 | 
			
		||||
[  4.100000] bettolad[420]: World generation complete. Seed: 0xDEADBEEF
 | 
			
		||||
[  4.200000] bettolad[420]: Listening on 0.0.0.0:1337
 | 
			
		||||
[  4.500000] systemd[1]: Started Bettola Daemon.
 | 
			
		||||
[  4.800000] systemd[1]: Reached target Multi-User System.
 | 
			
		||||
[  5.000000] systemd[1]: Starting Graphical Interface.
 | 
			
		||||
[  5.500000] bettolac-greeter: Starting display manager...
 | 
			
		||||
@ -12,6 +12,7 @@
 | 
			
		||||
#include "ui/desktop.h"
 | 
			
		||||
#include "ui/ui_window.h"
 | 
			
		||||
#include <ui/main_menu.h>
 | 
			
		||||
#include <ui/boot_sequence.h>
 | 
			
		||||
 | 
			
		||||
void GameState::_init_desktop(void) {
 | 
			
		||||
  _desktop = std::make_unique<Desktop>();
 | 
			
		||||
@ -92,6 +93,15 @@ void GameState::update(void) {
 | 
			
		||||
      _main_menu.reset(); /* Free mem. */
 | 
			
		||||
 | 
			
		||||
      if(_current_screen == Screen::BOOTING) {
 | 
			
		||||
        _boot_sequence = std::make_unique<BootSequence>();
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    break;
 | 
			
		||||
  }
 | 
			
		||||
  case Screen::BOOTING: {
 | 
			
		||||
    if(!_boot_sequence) break; /* Shouldn't happen. */
 | 
			
		||||
    if(_boot_sequence->is_finished()) {
 | 
			
		||||
      /* Connect to server. */
 | 
			
		||||
      fprintf(stdout, "Starting in single-player mode...\n");
 | 
			
		||||
      std::thread server_thread(&GameState::_run_server, this);
 | 
			
		||||
      server_thread.detach();
 | 
			
		||||
@ -100,16 +110,12 @@ void GameState::update(void) {
 | 
			
		||||
      if(!_network->connect("127.0.0.1", 1337)) {
 | 
			
		||||
        /* TODO: Handle connection failure. */
 | 
			
		||||
      }
 | 
			
		||||
        /* TODO: transition to book screen. */
 | 
			
		||||
      _current_screen = Screen::DESKTOP;
 | 
			
		||||
      _init_desktop();
 | 
			
		||||
      }
 | 
			
		||||
      _boot_sequence.reset(); /* Free mem. */
 | 
			
		||||
    }
 | 
			
		||||
    break;
 | 
			
		||||
  }
 | 
			
		||||
  case Screen::BOOTING:
 | 
			
		||||
    /* TODO: */
 | 
			
		||||
    break;
 | 
			
		||||
  case Screen::DESKTOP: {
 | 
			
		||||
    std::string server_msg;
 | 
			
		||||
      while(_network->poll_message(server_msg)) {
 | 
			
		||||
@ -157,7 +163,9 @@ void GameState::render(ShapeRenderer* shape_renderer, TextRenderer* txt_renderer
 | 
			
		||||
    }
 | 
			
		||||
    break;
 | 
			
		||||
  case Screen::BOOTING:
 | 
			
		||||
    /* TODO: */
 | 
			
		||||
    if(_boot_sequence) {
 | 
			
		||||
      _boot_sequence->render(txt_renderer, screen_height);
 | 
			
		||||
    }
 | 
			
		||||
    break;
 | 
			
		||||
  case Screen::DESKTOP:
 | 
			
		||||
    if(_desktop) {
 | 
			
		||||
 | 
			
		||||
@ -4,6 +4,7 @@
 | 
			
		||||
 | 
			
		||||
class ClientNetwork;
 | 
			
		||||
class Desktop;
 | 
			
		||||
class BootSequence;
 | 
			
		||||
class MainMenu;
 | 
			
		||||
class ShapeRenderer;
 | 
			
		||||
class TextRenderer;
 | 
			
		||||
@ -30,6 +31,7 @@ public:
 | 
			
		||||
private:
 | 
			
		||||
  std::unique_ptr<ClientNetwork> _network;
 | 
			
		||||
  std::unique_ptr<Desktop>       _desktop;
 | 
			
		||||
  std::unique_ptr<BootSequence>  _boot_sequence;
 | 
			
		||||
  std::unique_ptr<MainMenu>      _main_menu;
 | 
			
		||||
  Screen                         _current_screen;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										54
									
								
								client/src/ui/boot_sequence.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								client/src/ui/boot_sequence.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,54 @@
 | 
			
		||||
#include <fstream>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <cstdio>
 | 
			
		||||
#include "gfx/txt_renderer.h"
 | 
			
		||||
 | 
			
		||||
#include "boot_sequence.h"
 | 
			
		||||
#include <SDL3/SDL_timer.h>
 | 
			
		||||
 | 
			
		||||
BootSequence::BootSequence(void) {
 | 
			
		||||
  /* Load boot messages. */
 | 
			
		||||
  std::ifstream boot_file("assets/boot_messages.txt");
 | 
			
		||||
  if(!boot_file.is_open()) {
 | 
			
		||||
    printf("ERROR: Failed to open assets/boot_messages.txt\n");
 | 
			
		||||
    _messages.push_back("ERROR: boot_messages.txt not found.");
 | 
			
		||||
  } else {
 | 
			
		||||
    std::string line;
 | 
			
		||||
    while(std::getline(boot_file, line)) {
 | 
			
		||||
      if(!line.empty()) {
 | 
			
		||||
        _messages.push_back(line);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* Init timings. */
 | 
			
		||||
  _start_time = SDL_GetTicks();
 | 
			
		||||
  _line_interval_ms = 150; /* 150ms between each line. */
 | 
			
		||||
  /* Total duration is time for all lines plus a 2-second pause at the end. */
 | 
			
		||||
  _total_duration_ms = (_messages.size() * _line_interval_ms) + 2000;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BootSequence::~BootSequence(void) {}
 | 
			
		||||
 | 
			
		||||
bool BootSequence::is_finished(void) {
 | 
			
		||||
  return (SDL_GetTicks() - _start_time) >= _total_duration_ms;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BootSequence::render(TextRenderer* txt_renderer, int screen_height) {
 | 
			
		||||
  const Color text_color  = { 0.9f, 0.9f, 0.9f }; /* grey/white */
 | 
			
		||||
  const float line_height = 18.0f;
 | 
			
		||||
  const float padding     = 15.0f;
 | 
			
		||||
 | 
			
		||||
  Uint32 elapsed_time = SDL_GetTicks() - _start_time;
 | 
			
		||||
  int lines_to_show = elapsed_time / _line_interval_ms;
 | 
			
		||||
 | 
			
		||||
  if(lines_to_show > _messages.size()) {
 | 
			
		||||
    lines_to_show = _messages.size();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for(int i = 0; i < lines_to_show; ++i) {
 | 
			
		||||
    float y_pos = (screen_height - padding) - (i * line_height);
 | 
			
		||||
    txt_renderer->render_text(_messages[i].c_str(), padding, y_pos, 1.0f, text_color);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										21
									
								
								client/src/ui/boot_sequence.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								client/src/ui/boot_sequence.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,21 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <SDL3/SDL.h>
 | 
			
		||||
 | 
			
		||||
#include "gfx/txt_renderer.h"
 | 
			
		||||
 | 
			
		||||
class BootSequence {
 | 
			
		||||
public:
 | 
			
		||||
  BootSequence(void);
 | 
			
		||||
  ~BootSequence(void);
 | 
			
		||||
 | 
			
		||||
  bool is_finished(void);
 | 
			
		||||
  void render(TextRenderer* txt_renderer, int screen_height);
 | 
			
		||||
private:
 | 
			
		||||
  std::vector<std::string> _messages;
 | 
			
		||||
  Uint32 _start_time;
 | 
			
		||||
  Uint32 _line_interval_ms;   /* Time for each line to appear. */
 | 
			
		||||
  Uint32 _total_duration_ms;  /* Total time for the whole sequence. */
 | 
			
		||||
};
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user