render_Bundles loading
This commit is contained in:
		
							
								
								
									
										3
									
								
								app.c
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								app.c
									
									
									
									
									
								
							| @@ -7,11 +7,14 @@ | ||||
| #include "physics.h" | ||||
| #include "player.h" | ||||
| #include "types.h" | ||||
| #include "render_bundle.h" | ||||
| #include <stdlib.h> | ||||
| #include <stdio.h> | ||||
|  | ||||
|  | ||||
| App *app_NewApp() { | ||||
| 	render_LoadBundle("bundles.txt"); | ||||
|  | ||||
| 	App *app = malloc(sizeof(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(); | ||||
| 	app_DeleteApp(app); | ||||
| 	printf("%.6lf seconds has elapsed\n", duration_Seconds(time_Since(startup))); | ||||
| 	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_HEIGHT 720 | ||||
|  | ||||
| #define WARN(fmt, ...) fprintf(stderr, "[WARN][%s] " fmt "\n", __func__, __VA_ARGS__) | ||||
|  | ||||
|  | ||||
| static inline void *zero_malloc(size_t size) { | ||||
| 	void *d = malloc(size); | ||||
| @@ -21,6 +23,13 @@ static inline void *zero_malloc(size_t size) { | ||||
| 	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. | ||||
| typedef struct { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user