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