shithub: dporg

Download patch

ref: 8ca30e5e3fed97299bda16b4b366bbf6b3541ee9
parent: 17fa4c8f626d854f87e5272edc4697e6dd8c34e0
author: qwx <qwx@sciops.net>
date: Sun Oct 10 14:02:41 EDT 2021

fs: load raw bsp tree and lines

--- a/dat.h
+++ b/dat.h
@@ -1,6 +1,9 @@
 typedef struct Wall Wall;
 typedef struct Pic Pic;
 typedef struct Sprite Sprite;
+typedef struct Map Map;
+typedef struct Node Node;
+typedef struct Line Line;
 
 extern char *prefix;
 
@@ -88,6 +91,52 @@
 	DFace = 0xff323232,
 	DAmmo = 0xff828282,
 };
+
+struct Node{
+	int type;
+	Rectangle;
+	int split;
+	int left;
+	int right;
+};
+enum{
+	LFwall = 0<<0,
+	LFdoor = 1<<0 | 1<<2,
+	LFshiftS⋁E = 1<<3,
+	LFshiftN∨W = 1<<4,
+	LFsecret = 1<<5,
+	LFyshift = 1<<8,
+	LFxshift = 1<<9,
+	LFlock = 1<<10,
+	LFwallS = 1<<11,
+	LFwallN = 1<<12,
+	LFwallW = 1<<13,
+	LFwallE = 1<<14,
+	LFmirrored = 1<<15,
+
+	Fineshift = 3,
+};
+struct Line{
+	int flags;
+	int tex;
+	int unkn1;
+	Rectangle;
+	int minpshift;
+	int maxpshift;
+};
+struct Map{
+	int id;
+	int nnodes;
+	Node *nodes;
+	int nlines;
+	Line *lines;
+	u32int ceilc;
+	u32int floorc;
+	u32int backc;
+	int unkn1;
+	int unkn2;
+};
+extern Map map;
 
 extern void (*step)(void);
 extern void (*input)(Rune);
--- a/drw.c
+++ b/drw.c
@@ -14,6 +14,16 @@
 static Image *fbs, *bgcol;
 static u32int *fbsbuf;
 
+Image *
+eallocimage(Rectangle r, int repl, ulong col)
+{
+	Image *i;
+
+	if((i = allocimage(display, r, XRGB32, repl, col)) == nil)
+		sysfatal("allocimage: %r");
+	return i;
+}
+
 void
 scrollpic(Pic *pp, int Δx)
 {
@@ -183,9 +193,7 @@
 	fbsr = Rpt(subpt(o, p), addpt(o, p));
 	fbsz = Vw * Vfullh * scale * sizeof *fbsbuf;
 	freeimage(fbs);
-	if((fbs = allocimage(display, Rect(0,0,Vw*scale,scale==1? Vfullh : 1),
-		XRGB32, scale > 1, DBlack)) == nil)
-		sysfatal("allocimage: %r");
+	fbs = eallocimage(Rect(0,0,Vw*scale,scale==1? Vfullh : 1), scale > 1, DBlack);
 	free(fbsbuf);
 	fbsbuf = nil;
 	if(scale != 1)
@@ -203,7 +211,6 @@
 	if(initdraw(nil, nil, "dporg") < 0)
 		sysfatal("initdraw: %r");
 	loadpics();
-	if((bgcol = allocimage(display, Rect(0,0,1,1), XRGB32, 1, 0xccccccff)) == nil)
-		sysfatal("allocimage: %r");
+	bgcol = eallocimage(Rect(0,0,1,1), 1, 0xccccccff);
 	resetfb(0);
 }
--- a/fns.h
+++ b/fns.h
@@ -15,6 +15,7 @@
 void	loadimg(void);
 void	loadpics(void);
 void	initfs(void);
+Image*	eallocimage(Rectangle, int, ulong);
 int	max(int, int);
 int	min(int, int);
 void*	erealloc(void*, ulong, ulong);
--- a/fs.c
+++ b/fs.c
@@ -509,6 +509,103 @@
 }
 
 static void
+dumplines(Map *m)
+{
+	int fd;
+	Image *i;
+	Line *l;
+
+	assert(display != nil);
+	i = eallocimage(Rect(0,0,256<<3,256<<3), 0, DBlack);
+	for(l=m->lines; l<m->lines+m->nlines; l++)
+		line(i, l->min, l->max, 0, Endarrow, 0, display->white, ZP);
+	if((fd = create("lines.bit", OWRITE, 0664)) < 0)
+		sysfatal("create: %r");
+	if(writeimage(fd, i, 0) < 0)
+		sysfatal("writeimage: %r");
+	freeimage(i);
+	close(fd);
+}
+
+void
+debugmap(void)
+{
+	dumplines(&map);
+}
+
+static void
+loadbsp(Biobuf *bf, Map *m)
+{
+	Node *n;
+
+	m->nnodes = get16(bf);
+	m->nodes = emalloc(m->nnodes * sizeof *m->nodes);
+	for(n=m->nodes; n<m->nodes+m->nnodes; n++){
+		n->min.x = get8(bf) << Fineshift;
+		n->min.y = get8(bf) << Fineshift;
+		n->max.x = get8(bf) << Fineshift;
+		n->max.y = get8(bf) << Fineshift;
+		n->type = get8(bf);
+		n->split = get8(bf) << Fineshift;
+		n->left = get16(bf);
+		n->right = get16(bf);
+	}
+}
+
+static void
+loadlines(Biobuf *bf, Map *m)
+{
+	Line *l;
+
+	m->nlines = get16(bf);
+	m->lines = emalloc(m->nlines * sizeof *m->lines);
+	for(l=m->lines; l<m->lines+m->nlines; l++){
+		l->min.x = get8(bf) << Fineshift;
+		l->min.y = get8(bf) << Fineshift;
+		l->max.x = get8(bf) << Fineshift;
+		l->max.y = get8(bf) << Fineshift;
+		l->tex = get16(bf);	/* FIXME: actual Wall* */
+		l->flags = get16(bf);
+		if(l->flags & LFmirrored)
+			l->minpshift = max(Dx(l->Rectangle), Dy(l->Rectangle));
+		else
+			l->maxpshift = max(Dx(l->Rectangle), Dy(l->Rectangle));
+		if(l->flags & (LFxshift | LFshiftS⋁E))
+			l->Rectangle = rectaddpt(l->Rectangle, Pt(3,0));
+		else if(l->flags & (LFxshift | LFshiftN∨W))
+			l->Rectangle = rectsubpt(l->Rectangle, Pt(3,0));
+		else if(l->flags & (LFyshift | LFshiftS⋁E))
+			l->Rectangle = rectaddpt(l->Rectangle, Pt(0,3));
+		else if(l->flags & (LFyshift | LFshiftN∨W))
+			l->Rectangle = rectsubpt(l->Rectangle, Pt(0,3));
+		/* FIXME: no way to know why until we properly process walls to dump them */
+		if(l->tex == 7){ }	/* FIXME */
+	}
+}
+
+static void
+loadmap(char *name)
+{
+	Biobuf *bf;
+	Map *m;
+
+	bf = eopen(name, OREAD);
+	m = &map;
+	m->ceilc = 0xff << 24 | get24(bf);
+	m->floorc = 0xff << 24 | get24(bf);
+	m->backc = 0xff << 24 | get24(bf);
+	m->id = get8(bf);
+	m->unkn1 = get16(bf);
+	m->unkn2 = get8(bf);
+	loadbsp(bf, m);
+	loadlines(bf, m);
+
+	/* FIXME: things, events, commands */
+
+	Bterm(bf);
+}
+
+static void
 loadsintab(void)
 {
 	Biobuf *bf;
@@ -530,6 +627,8 @@
 	loadpal();
 	loadbasestr();
 	loadfontmap();
+	// FIXME: walls: same processing as sprites
 	loadwalls();
 	loadsprites();
+	loadmap("intro.bsp");
 }
--- /dev/null
+++ b/map.c
@@ -1,0 +1,7 @@
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include "dat.h"
+#include "fns.h"
+
+Map map;
--- a/mkfile
+++ b/mkfile
@@ -8,6 +8,7 @@
 	fsm.$O\
 	fsm.intro.$O\
 	fsm.map.$O\
+	map.$O\
 
 HFILES= dat.h fns.h
 </sys/src/cmd/mkone