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 = ↦
+ 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