render_Bundles loading
This commit is contained in:
parent
5698bca940
commit
203f54f76c
3
app.c
3
app.c
@ -7,11 +7,14 @@
|
|||||||
#include "physics.h"
|
#include "physics.h"
|
||||||
#include "player.h"
|
#include "player.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
#include "render_bundle.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
App *app_NewApp() {
|
App *app_NewApp() {
|
||||||
|
render_LoadBundle("bundles.txt");
|
||||||
|
|
||||||
App *app = malloc(sizeof(App));
|
App *app = malloc(sizeof(App));
|
||||||
|
|
||||||
app->input = input_NewSystem(app);
|
app->input = input_NewSystem(app);
|
||||||
|
21
bundles.txt
Normal file
21
bundles.txt
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
BUNDLE info_plate
|
||||||
|
PRIM LINES
|
||||||
|
FG ffffff
|
||||||
|
BG 000000
|
||||||
|
P 123 456
|
||||||
|
P 456 789
|
||||||
|
P 324 123
|
||||||
|
P 432 123
|
||||||
|
ENDPRIM
|
||||||
|
ENDBUNDLE
|
||||||
|
|
||||||
|
BUNDLE info_plate2
|
||||||
|
PRIM LINES
|
||||||
|
FG ffffff
|
||||||
|
BG 000000
|
||||||
|
P 123 456
|
||||||
|
P 456 789
|
||||||
|
P 324 123
|
||||||
|
P 432 123
|
||||||
|
ENDPRIM
|
||||||
|
ENDBUNDLE
|
1
main.cpp
1
main.cpp
@ -56,6 +56,7 @@ int main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
closegraph();
|
closegraph();
|
||||||
|
app_DeleteApp(app);
|
||||||
printf("%.6lf seconds has elapsed\n", duration_Seconds(time_Since(startup)));
|
printf("%.6lf seconds has elapsed\n", duration_Seconds(time_Since(startup)));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
46
render_bundle.c
Normal file
46
render_bundle.c
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
|
||||||
|
#include "render_bundle.h"
|
||||||
|
#include "types.h"
|
||||||
|
#include "util/vector.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
render_Primitive *render_NewPrimitive(render_PrimitiveType type) {
|
||||||
|
render_Primitive *p = malloc(sizeof(render_Primitive));
|
||||||
|
|
||||||
|
p->type = type;
|
||||||
|
p->points = vector_Create(sizeof(Vec2));
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void render_DeletePrimitive(render_Primitive *p) {
|
||||||
|
vector_Destroy(p->points);
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
void render_Push(render_Primitive *p, Vec2 point) {
|
||||||
|
vector_Push(p->points, &point);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
render_Bundle *render_NewBundle(const char *name) {
|
||||||
|
render_Bundle *b = malloc(sizeof(render_Bundle));
|
||||||
|
b->name = copy_malloc(name);
|
||||||
|
b->prims = vector_Create(sizeof(render_Primitive));
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
void render_DeleteBundle(render_Bundle *b) {
|
||||||
|
for (int i = 0; i < vector_Size(b->prims); i++) {
|
||||||
|
render_Primitive *p = vector_At(b->prims, i);
|
||||||
|
if (p->points)
|
||||||
|
vector_Destroy(p->points);
|
||||||
|
}
|
||||||
|
vector_Destroy(b->prims);
|
||||||
|
free(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void render_DrawBundleW(App *app, render_Bundle *b, Vec2 offset) {
|
||||||
|
for (int i = 0; i < vector_Size(b->prims); i++)
|
||||||
|
render_DrawPrimitiveW(app, vector_At(b->prims, i), offset);
|
||||||
|
}
|
65
render_bundle.h
Normal file
65
render_bundle.h
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "render_util.h"
|
||||||
|
#include "types.h"
|
||||||
|
#include "util/vector.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
render_Lines, // Individial lines
|
||||||
|
render_LineStrip, // Connected lines
|
||||||
|
render_Polygon // Filled polygon
|
||||||
|
} render_PrimitiveType;
|
||||||
|
|
||||||
|
|
||||||
|
// render_Primitive describes one render operation.
|
||||||
|
typedef struct {
|
||||||
|
FillMode mode; // fill mode
|
||||||
|
uint32_t fg, bg; // foreground & background colors
|
||||||
|
|
||||||
|
render_PrimitiveType type;
|
||||||
|
vector_Vector *points; // Vector of Vec2
|
||||||
|
} render_Primitive;
|
||||||
|
|
||||||
|
// render_Primitive *render_NewPrimitive(render_PrimitiveType type);
|
||||||
|
// void render_DeletePrimitive(render_Primitive *p);
|
||||||
|
|
||||||
|
void render_Push(render_Primitive *p, Vec2 point);
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _App App;
|
||||||
|
|
||||||
|
// Draws a primitive with the given offset in screen space.
|
||||||
|
void render_DrawPrimitiveW(App *app, render_Primitive *p, Vec2 offset);
|
||||||
|
|
||||||
|
|
||||||
|
// render_Bundle is a list of Primitives
|
||||||
|
typedef struct {
|
||||||
|
char *name; // Name, malloc & copied
|
||||||
|
vector_Vector *prims; // Vector of render_Primitive
|
||||||
|
} render_Bundle;
|
||||||
|
|
||||||
|
// Creates a new bundle. Name is copied into a malloc'ed string.
|
||||||
|
render_Bundle *render_NewBundle(const char *name);
|
||||||
|
void render_DeleteBundle(render_Bundle *b);
|
||||||
|
|
||||||
|
// Draws the bundle with the given offset in screen space.
|
||||||
|
void render_DrawBundleW(App *app, render_Bundle *b, Vec2 offset);
|
||||||
|
|
||||||
|
|
||||||
|
// Global bundles identified by name
|
||||||
|
extern vector_Vector *render_Bundles;
|
||||||
|
|
||||||
|
// Appends the global bundle list with this file.
|
||||||
|
void render_LoadBundle(const char *filename);
|
||||||
|
// Finds the first bundle with this name, or NULL otherwise.
|
||||||
|
render_Bundle *render_FindBundle(const char *name);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
63
render_bundle_draw.cpp
Normal file
63
render_bundle_draw.cpp
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
|
||||||
|
#include "camera.h"
|
||||||
|
#include "render_bundle.h"
|
||||||
|
#include "app.h"
|
||||||
|
#include "util/vector.h"
|
||||||
|
#include "util/assert.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <easyx.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
vector_Vector *buff;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" void render_DrawPrimitiveW(App *app, render_Primitive *p, Vec2 offset) {
|
||||||
|
if (buff == NULL)
|
||||||
|
buff = vector_Create(sizeof(POINT));
|
||||||
|
vector_Clear(buff);
|
||||||
|
|
||||||
|
// Construct the points in screen space
|
||||||
|
for (int i = 0; i < vector_Size(p->points); i++) {
|
||||||
|
Vec2 realpos = vec2_Add(*((Vec2 *)vector_At(p->points, i)), offset);
|
||||||
|
Vec2 screenpos;
|
||||||
|
if (!app->camera) {
|
||||||
|
// Really weird
|
||||||
|
fprintf(stderr, "[WARN][render_DrawPrimitiveW] called without a Camera system\n");
|
||||||
|
screenpos = realpos;
|
||||||
|
} else
|
||||||
|
screenpos = camera_TransformVec2(app->camera, realpos);
|
||||||
|
|
||||||
|
// Round the screen position to ints
|
||||||
|
POINT rounded;
|
||||||
|
rounded.x = (LONG)round(screenpos.x);
|
||||||
|
rounded.y = (LONG)round(screenpos.y);
|
||||||
|
vector_Push(buff, &rounded);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the colors
|
||||||
|
setlinecolor(p->fg);
|
||||||
|
setfillcolor(p->fg);
|
||||||
|
setbkcolor(p->bg);
|
||||||
|
|
||||||
|
// Draw the converted primitive
|
||||||
|
switch (p->type) {
|
||||||
|
case render_Lines:
|
||||||
|
if (vector_Size(buff) % 2 != 0)
|
||||||
|
fprintf(stderr, "[WARN][render_DrawPrimitiveW] render_Lines drawed odd numbers of points");
|
||||||
|
for (int i = 0; i < vector_Size(buff); i += 2) {
|
||||||
|
POINT p0 = *(POINT *)vector_At(buff, i);
|
||||||
|
POINT p1 = *(POINT *)vector_At(buff, i + 1);
|
||||||
|
line(p0.x, p0.y, p1.x, p1.y);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case render_LineStrip:
|
||||||
|
polyline((POINT *)vector_Data(buff), vector_Size(buff));
|
||||||
|
break;
|
||||||
|
case render_Polygon:
|
||||||
|
fillpolygon((POINT *)vector_Data(buff), vector_Size(buff));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
126
render_bundle_file.c
Normal file
126
render_bundle_file.c
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
|
||||||
|
#include "render_bundle.h"
|
||||||
|
#include "util/vector.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
|
||||||
|
vector_Vector *render_Bundles;
|
||||||
|
static render_Bundle *_tmpb;
|
||||||
|
static render_Primitive *_tmpp;
|
||||||
|
|
||||||
|
// Subsequent tokens can be read by strtok(NULL, " ")
|
||||||
|
static void _render_BundleCommand(char *cmd) {
|
||||||
|
// convert CMD to upper case
|
||||||
|
for (int i = 0; i < strlen(cmd); i++)
|
||||||
|
cmd[i] = toupper(cmd[i]);
|
||||||
|
|
||||||
|
#define CMD(str) (strcmp(cmd, str) == 0)
|
||||||
|
// Find the command
|
||||||
|
if (CMD("BUNDLE")) {
|
||||||
|
// Start a bundle
|
||||||
|
if (_tmpb != NULL) {
|
||||||
|
WARN("_tmpb!=0, you forgot to use ENDBUNDLE for the last bundle, discarding", 0);
|
||||||
|
free(_tmpb);
|
||||||
|
}
|
||||||
|
_tmpb = render_NewBundle(strtok(NULL, " "));
|
||||||
|
|
||||||
|
|
||||||
|
} else if (CMD("ENDBUNDLE")) {
|
||||||
|
// commit the bundle
|
||||||
|
if (_tmpb) {
|
||||||
|
fprintf(stderr, "[_render_BundleCommand] Commiting bundle %s with %d primitives\n", _tmpb->name, vector_Size(_tmpb->prims));
|
||||||
|
vector_Push(render_Bundles, &_tmpb);
|
||||||
|
_tmpb = NULL;
|
||||||
|
} else
|
||||||
|
WARN("_tmpb==0, ENDBUNDLE without BUNDLE first", 0);
|
||||||
|
|
||||||
|
|
||||||
|
} else if (CMD("PRIM")) {
|
||||||
|
// start a primitive
|
||||||
|
if (_tmpp != NULL) {
|
||||||
|
WARN("_tmpp!=0, you forgot to ENDPRIM for the last primitive, discarding", 0);
|
||||||
|
if (_tmpp->points)
|
||||||
|
vector_Destroy(_tmpp->points);
|
||||||
|
free(_tmpp);
|
||||||
|
}
|
||||||
|
_tmpp = malloc(sizeof(render_Primitive));
|
||||||
|
_tmpp->points = vector_Create(sizeof(Vec2));
|
||||||
|
_tmpp->fg = 0xffffff;
|
||||||
|
_tmpp->bg = 0;
|
||||||
|
|
||||||
|
// parse the type
|
||||||
|
char *type = strtok(NULL, " ");
|
||||||
|
if (strcmp(type, "LINES"))
|
||||||
|
_tmpp->type = render_Lines;
|
||||||
|
else if (strcmp(type, "LINESTRIP"))
|
||||||
|
_tmpp->type = render_LineStrip;
|
||||||
|
else if (strcmp(type, "POLY"))
|
||||||
|
_tmpp->type = render_Polygon;
|
||||||
|
|
||||||
|
|
||||||
|
} else if (CMD("ENDPRIM")) {
|
||||||
|
// commit the primitive
|
||||||
|
if (_tmpb && _tmpp) {
|
||||||
|
fprintf(stderr, "[_render_BundleCommand] Commiting primitive type %d with %d points\n", _tmpp->type, vector_Size(_tmpp->points));
|
||||||
|
vector_Push(_tmpb->prims, _tmpp);
|
||||||
|
free(_tmpp);
|
||||||
|
_tmpp = NULL;
|
||||||
|
} else
|
||||||
|
WARN("tmpb=%x, tmpp=%x, ENDPRIM when one of them is NULL", _tmpb, _tmpp);
|
||||||
|
|
||||||
|
|
||||||
|
} else if (CMD("P")) {
|
||||||
|
// Add a Vec2
|
||||||
|
if (_tmpp) {
|
||||||
|
Vec2 v = vec2(strtod(strtok(NULL, " "), NULL), strtod(strtok(NULL, " "), NULL));
|
||||||
|
vector_Push(_tmpp->points, &v);
|
||||||
|
} else
|
||||||
|
WARN("P without PRIM first", 0);
|
||||||
|
} else {
|
||||||
|
WARN("unknown command %s", cmd);
|
||||||
|
}
|
||||||
|
#undef CMD
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char linebuf[512];
|
||||||
|
|
||||||
|
void render_LoadBundle(const char *filename) {
|
||||||
|
if (!render_Bundles)
|
||||||
|
render_Bundles = vector_Create(sizeof(render_Bundle *));
|
||||||
|
|
||||||
|
FILE *f = fopen(filename, "r");
|
||||||
|
if (!f) {
|
||||||
|
WARN("failed to open file\"%s\"", filename);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!feof(f) && fgets(linebuf, sizeof(linebuf), f)) {
|
||||||
|
while (linebuf[strlen(linebuf) - 1] == '\n')
|
||||||
|
linebuf[strlen(linebuf) - 1] = '\0';
|
||||||
|
|
||||||
|
char *cmd = strtok(linebuf, " ");
|
||||||
|
if (cmd == NULL)
|
||||||
|
continue;
|
||||||
|
_render_BundleCommand(cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render_Bundle *render_FindBundle(const char *name) {
|
||||||
|
if (!render_Bundles) {
|
||||||
|
WARN("called with render_Bundles=NULL (name=%s)", name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// brute force search. could be slow
|
||||||
|
for (int i = 0; i < vector_Size(render_Bundles); i++) {
|
||||||
|
render_Bundle *b = *(render_Bundle **)vector_At(render_Bundles, i);
|
||||||
|
if (strcmp(name, b->name) == 0)
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
WARN("bundle \"%s\" not found", name);
|
||||||
|
return NULL;
|
||||||
|
}
|
9
types.h
9
types.h
@ -14,6 +14,8 @@ extern "C" {
|
|||||||
#define SCREEN_WIDTH 1280
|
#define SCREEN_WIDTH 1280
|
||||||
#define SCREEN_HEIGHT 720
|
#define SCREEN_HEIGHT 720
|
||||||
|
|
||||||
|
#define WARN(fmt, ...) fprintf(stderr, "[WARN][%s] " fmt "\n", __func__, __VA_ARGS__)
|
||||||
|
|
||||||
|
|
||||||
static inline void *zero_malloc(size_t size) {
|
static inline void *zero_malloc(size_t size) {
|
||||||
void *d = malloc(size);
|
void *d = malloc(size);
|
||||||
@ -21,6 +23,13 @@ static inline void *zero_malloc(size_t size) {
|
|||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline char *copy_malloc(const char *src) {
|
||||||
|
size_t len = strlen(src);
|
||||||
|
char *p = (char *)malloc(len + 1);
|
||||||
|
memcpy(p, src, len + 1);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// A 2d vector of double.
|
// A 2d vector of double.
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
Loading…
Reference in New Issue
Block a user