1#include <SDL2/SDL.h>
2#include <stdio.h>
3#include <stdlib.h>
4
5#include "SDL_keyboard.h"
6#include "SDL_timer.h"
7#include "config.h"
8#include "mcproto/mcproto.h"
9#include "util.h"
10#include "platform/platform.h"
11#include "renderer/renderer.h"
12#include "renderer/test_scene.h"
13
14static MGContext ctx = {
15 NULL, { NULL }, "Magnolia", 0, 0, 1024, 768,
16};
17
18static void input(void)
19{
20 static u32 last;
21
22 const u8* keys = SDL_GetKeyboardState(NULL);
23 MGVec3 move = MG_V3(0.0f, 0.0f, 0.0f);
24 u32 now = SDL_GetTicks();
25 float sensitivity = mg_config.input_sensitivity;
26 float dt;
27 i32 mx;
28 i32 my;
29
30 if (!last) {
31 last = now;
32 return;
33 }
34
35 dt = (float)(now - last) / 1000.0f;
36 last = now;
37
38 if (keys[SDL_SCANCODE_W])
39 move.z += 1.0f;
40 if (keys[SDL_SCANCODE_A])
41 move.x -= 1.0f;
42 if (keys[SDL_SCANCODE_S])
43 move.z -= 1.0f;
44 if (keys[SDL_SCANCODE_D])
45 move.x += 1.0f;
46 if (keys[SDL_SCANCODE_SPACE])
47 move.y += 1.0f;
48 if (keys[SDL_SCANCODE_LCTRL])
49 move.y -= 1.0f;
50
51 move = MG_MulV3F(move, mg_config.temp_movement_speed * dt);
52 camera_move(&cam, move);
53 SDL_GetRelativeMouseState(&mx, &my);
54 camera_rotate(&cam, mx * sensitivity, -my * sensitivity);
55}
56
57static int protocol_poc(const char* address, const char* username)
58{
59 MCAccount account;
60 MCClient* client;
61 char error[1024];
62
63 account.username = username;
64 account.profile_uuid = getenv("MANGOLIA_PROFILE_UUID");
65 account.access_token = getenv("MANGOLIA_ACCESS_TOKEN");
66 if (!mc_client_login(&client, address, &account, error, sizeof(error))) {
67 fprintf(stderr, "%s\n", error);
68 return MG_ERR_EXIT_FAILURE;
69 }
70 /* offline mode protocol test:
71 packet keep alive is play/clientbound 0x00 in protocol 47
72 https://prismarinejs.github.io/minecraft-data/protocol/pc/1.8/#play.toClient.types.packet_keep_alive */
73 puts("entered play state: printing packet ids and echoing keepalives");
74 for (;;) {
75 MCPacket packet;
76 if (!mc_client_read(client, &packet, error, sizeof(error))) {
77 fprintf(stderr, "%s\n", error);
78 mc_client_destroy(client);
79 return MG_ERR_EXIT_FAILURE;
80 }
81 printf("play packet 0x%02x size %lu\n", packet.id, (unsigned long)packet.size);
82 if (packet.id == 0x00) {
83 if (!mc_client_write(client, 0x00, packet.data, packet.size)) {
84 fprintf(stderr, "failed to echo keepalive\n");
85 mc_packet_free(&packet);
86 mc_client_destroy(client);
87 return MG_ERR_EXIT_FAILURE;
88 }
89 puts("echoed keepalive");
90 }
91 mc_packet_free(&packet);
92 }
93}
94
95int main(int argc, char** argv)
96{
97 if (argc != 1 && argc != 3) {
98 fprintf(stderr, "usage: %s [server[:port] username]\n", argv[0]);
99 return MG_ERR_EXIT_FAILURE;
100 }
101 if (argc == 3)
102 return protocol_poc(argv[1], argv[2]);
103
104 config_default();
105
106 ctx.width = mg_config.display_width;
107 ctx.height = mg_config.display_height;
108
109 platform_init(&ctx);
110 platform_window_create(&ctx);
111 renderer_create(&ctx);
112 test_scene_create();
113 SDL_SetRelativeMouseMode(SDL_TRUE);
114
115 while (platform_poll(&ctx)) {
116 input();
117 renderer_begin();
118
119 /* ... */
120 test_scene_draw(&ctx);
121
122 renderer_end();
123 platform_present(&ctx);
124 SDL_Delay(1); /* TODO: replace with target fps */
125 }
126
127 test_scene_destroy();
128 renderer_destroy();
129 platform_shutdown(&ctx);
130 return MG_ERR_EXIT_SUCCESS;
131}