-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbasic.c
More file actions
132 lines (120 loc) · 4.24 KB
/
Copy pathbasic.c
File metadata and controls
132 lines (120 loc) · 4.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/* SPDX-License-Identifier: AGPL-3.0-or-later
* Copyright (C) 2026 Cycl0o0
*
* Minimal headless liboot host: initialize from a user-provided ROM, create a
* floor, spawn Link, run one second of input, and inspect renderer-neutral
* geometry. A host performs oot_link_tick once per PAL 60 ms gameplay tick and uploads
* changed textures through oot_get_texture().
*/
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "liboot_engine.h" /* also exposes the public ROM-size limits */
static float sPosition[OOT_GEO_MAX_TRIANGLES * 9];
static float sNormal[OOT_GEO_MAX_TRIANGLES * 9];
static float sColor[OOT_GEO_MAX_TRIANGLES * 9];
static float sUv[OOT_GEO_MAX_TRIANGLES * 6];
static uint16_t sTexture[OOT_GEO_MAX_TRIANGLES];
static int read_file( const char *path, uint8_t **outData, size_t *outSize )
{
FILE *file = fopen( path, "rb" );
if( !file ) {
fprintf( stderr, "%s: %s\n", path, strerror( errno ));
return 0;
}
if( fseek( file, 0, SEEK_END ) != 0 ) {
fprintf( stderr, "%s: could not determine ROM size\n", path );
fclose( file );
return 0;
}
long length = ftell( file );
if( length < (long)OOT_ENGINE_MIN_ROM_SIZE ||
(uintmax_t)length > (uintmax_t)OOT_ENGINE_MAX_ROM_SIZE ) {
fprintf( stderr, "%s: ROM size must be %u..%u bytes\n", path,
(unsigned)OOT_ENGINE_MIN_ROM_SIZE,
(unsigned)OOT_ENGINE_MAX_ROM_SIZE );
fclose( file );
return 0;
}
if( fseek( file, 0, SEEK_SET ) != 0 ) {
fprintf( stderr, "%s: could not rewind ROM\n", path );
fclose( file );
return 0;
}
uint8_t *data = malloc((size_t)length );
if( !data ) {
fprintf( stderr, "%s: could not allocate %ld bytes\n", path, length );
fclose( file );
return 0;
}
if( fread( data, 1, (size_t)length, file ) != (size_t)length ) {
fprintf( stderr, "%s: could not read ROM\n", path );
free( data );
fclose( file );
return 0;
}
if( fgetc( file ) != EOF ) {
fprintf( stderr, "%s: ROM size changed while it was being read\n", path );
free( data );
fclose( file );
return 0;
}
if( ferror( file )) {
fprintf( stderr, "%s: could not finish reading ROM\n", path );
free( data );
fclose( file );
return 0;
}
fclose( file );
*outData = data;
*outSize = (size_t)length;
return 1;
}
int main( int argc, char **argv )
{
if( argc != 2 ) {
fprintf( stderr, "usage: %s <legally-obtained-oot-rom>\n", argv[0] );
return 2;
}
uint8_t *rom = NULL;
size_t romSize = 0;
if( !read_file( argv[1], &rom, &romSize )) return 1;
oot_global_init( rom, romSize, NULL );
free( rom ); /* initialization extracts everything it needs synchronously */
const struct OoTSurface floor[2] = {
{ 0, {{ -1000, 0, -1000 }, { -1000, 0, 1000 }, { 1000, 0, 1000 }} },
{ 0, {{ -1000, 0, -1000 }, { 1000, 0, 1000 }, { 1000, 0, -1000 }} },
};
oot_static_surfaces_load( floor, 2 );
int32_t link = oot_link_create( 0, 0, 0 );
if( link < 0 ) {
fprintf( stderr, "Link creation failed; verify that the ROM is compatible.\n" );
oot_global_terminate();
return 1;
}
oot_link_set_equipment( link, OOT_SWORD_MASTER, OOT_SHIELD_HYLIAN,
OOT_TUNIC_KOKIRI, OOT_BOOTS_KOKIRI );
struct OoTLinkInputs input = { .camLookZ = 1.0f };
struct OoTLinkState state = { 0 };
struct OoTLinkGeometryBuffers geometry = {
.position = sPosition,
.normal = sNormal,
.color = sColor,
.uv = sUv,
.triTexture = sTexture,
};
for( int tick = 0; tick < 20; ++tick ) {
input.stickY = tick < 12 ? 1.0f : 0.0f;
input.buttonA = tick == 14; /* one-tick A press */
oot_link_tick( link, &input, &state, &geometry );
}
printf( "Link position: %.2f %.2f %.2f\n", state.position[0],
state.position[1], state.position[2] );
printf( "Geometry: %u triangles, %d cached textures\n",
geometry.numTrianglesUsed, oot_get_texture_count());
oot_link_delete( link );
oot_global_terminate();
return 0;
}