ref: d720781005fff71800333afec5f574ccd770edea
parent: 006f3116af711aeea7331515f92384c9fe518368
author: qwx <qwx@sciops.net>
date: Mon Apr 26 13:04:52 EDT 2021
add basic drawing
--- a/dat.h
+++ b/dat.h
@@ -3,6 +3,14 @@
extern char *prefix;
enum{
+ Vwidth = 320,
+ Vheight = 210,
+};
+
+extern int npal;
+extern u32int *pal;
+
+enum{
PCfont,
PCarrow,
PCspace,
--- a/dporg.c
+++ b/dporg.c
@@ -9,6 +9,29 @@
char *prefix = "/sys/games/lib/dporg";
+enum{
+ Kfire = 'x',
+ K↑ = Kup,
+ K↓ = Kdown,
+ K← = Kleft,
+ K→ = Kright,
+};
+
+static Keyboardctl *kc;
+static Mousectl *mc;
+
+int
+max(int a, int b)
+{
+ return a > b ? a : b;
+}
+
+int
+min(int a, int b)
+{
+ return a < b ? a : b;
+}
+
void *
erealloc(void *p, ulong n, ulong oldn)
{
@@ -34,7 +57,7 @@
static void
usage(void)
{
- fprint(2, "usage: %s [-d datadir]\n", argv0);
+ fprint(2, "usage: %s [-m datadir]\n", argv0);
threadexits("usage");
}
@@ -41,12 +64,54 @@
void
threadmain(int argc, char **argv)
{
+ Rune r;
+ Mouse mo;
+
ARGBEGIN{
- case 'd': prefix = EARGF(usage()); break;
+ case 'm': prefix = EARGF(usage()); break;
default: usage();
}ARGEND
- if(initdraw(nil, nil, "dporg") < 0)
- sysfatal("initdraw: %r");
initfs();
- threadexits(nil);
+ initfb();
+ if((kc = initkeyboard(nil)) == nil)
+ sysfatal("initkeyboard: %r");
+ if((mc = initmouse(nil, screen)) == nil)
+ sysfatal("initmouse: %r");
+ initfsm();
+ enum{
+ Aresize,
+ Amouse,
+ Akbd,
+ };
+ Alt a[] = {
+ {mc->resizec, nil, CHANRCV},
+ {mc->c, &mc->Mouse, CHANRCV},
+ {kc->c, &r, CHANRCV},
+ {nil, nil, CHANEND}
+ };
+ for(;;){
+ switch(alt(a)){
+ case Aresize:
+ if(getwindow(display, Refnone) < 0)
+ sysfatal("resize failed: %r");
+ mo = mc->Mouse;
+ resetfb(1);
+ break;
+ case Amouse:
+ if(eqpt(mo.xy, ZP))
+ mo = mc->Mouse;
+ break;
+ case Akbd:
+ switch(r){
+ case Kdel:
+ case 'q': threadexitsall(nil);
+ case Kfire: break;
+ case K↑: break;
+ case K↓: break;
+ case K←: break;
+ case K→: break;
+ }
+ break;
+ }
+ }
}
--- /dev/null
+++ b/drw.c
@@ -1,0 +1,102 @@
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include "dat.h"
+#include "fns.h"
+
+static u32int fb[Vwidth * Vheight];
+
+int npal;
+u32int *pal;
+Pic pics[PCend];
+
+static int scale, fbsz;
+static Rectangle fbsr;
+static Image *fbs;
+static u32int *fbsbuf;
+
+static void
+drawscaled(void)
+{
+ u32int *s, *p, v;
+
+ s = fb;
+ p = fbsbuf;
+ while(s < fb + nelem(fb)){
+ v = *s++;
+ switch(scale){
+ case 12: *p++ = v;
+ case 11: *p++ = v;
+ case 10: *p++ = v;
+ case 9: *p++ = v;
+ case 8: *p++ = v;
+ case 7: *p++ = v;
+ case 6: *p++ = v;
+ case 5: *p++ = v;
+ case 4: *p++ = v;
+ case 3: *p++ = v;
+ case 2: *p++ = v; *p++ = v;
+ }
+ }
+}
+
+void
+drawfb(void)
+{
+ uchar *p;
+ Rectangle r;
+
+ if(scale == 1){
+ loadimage(fbs, fbs->r, (uchar*)fb, fbsz);
+ draw(screen, fbsr, fbs, nil, ZP);
+ }else{
+ drawscaled();
+ p = (uchar*)fbsbuf;
+ r = fbsr;
+ while(r.min.y < fbsr.max.y){
+ r.max.y = r.min.y + scale;
+ p += loadimage(fbs, fbs->r, p, fbsz / Vheight);
+ draw(screen, r, fbs, nil, ZP);
+ r.min.y = r.max.y;
+ }
+ }
+ flushimage(display, 1);
+}
+
+void
+resetfb(int paint)
+{
+ Point o, p;
+
+ scale = min(Dx(screen->r) / Vwidth, Dy(screen->r) / Vheight);
+ if(scale <= 0)
+ scale = 1;
+ else if(scale > 12)
+ scale = 12;
+ o = divpt(addpt(screen->r.min, screen->r.max), 2);
+ p = Pt(Vwidth / 2 * scale, Vheight / 2 * scale);
+ fbsr = Rpt(subpt(o, p), addpt(o, p));
+ fbsz = Vwidth * Vheight * scale * sizeof *fbsbuf;
+ freeimage(fbs);
+ if((fbs = allocimage(display, Rect(0,0,Vwidth*scale,scale==1? Vheight : 1),
+ XRGB32, scale > 1, DBlack)) == nil)
+ sysfatal("allocimage: %r");
+ free(fbsbuf);
+ fbsbuf = nil;
+ if(scale != 1)
+ fbsbuf = emalloc(fbsz);
+ draw(screen, screen->r, display->black, nil, ZP);
+ if(paint)
+ drawfb();
+ else
+ flushimage(display, 1);
+}
+
+void
+initfb(void)
+{
+ if(initdraw(nil, nil, "dporg") < 0)
+ sysfatal("initdraw: %r");
+ loadpics();
+ resetfb(0);
+}
--- a/fns.h
+++ b/fns.h
@@ -1,3 +1,11 @@
+void initfsm(void);
+void drawfb(void);
+void resetfb(int);
+void initfb(void);
+void loadimg(void);
+void loadpics(void);
void initfs(void);
+int max(int, int);
+int min(int, int);
void* erealloc(void*, ulong, ulong);
void* emalloc(ulong);
--- a/fs.c
+++ b/fs.c
@@ -6,9 +6,6 @@
#include "fns.h"
s32int sintab[256];
-int npal;
-u32int *pal;
-Pic pics[PCend];
static Biobuf *
eopen(char *s, int mode)
@@ -99,7 +96,7 @@
free(b);
}
-static void
+void
loadpics(void)
{
loadpic("a.bit", pics + PCfont);
@@ -162,7 +159,6 @@
fprint(2, "initfs: %r\n");
loadsintab();
loadpal();
- loadpics();
}
// grids: 32/256/2048
--- /dev/null
+++ b/fsm.c
@@ -1,0 +1,10 @@
+#include <u.h>
+#include <libc.h>
+#include "dat.h"
+#include "fns.h"
+
+void
+initfsm(void)
+{
+ srand(time(nil));
+}
--- a/mkfile
+++ b/mkfile
@@ -4,6 +4,8 @@
OFILES=\
fs.$O\
dporg.$O\
+ drw.$O\
+ fsm.$O\
HFILES= dat.h fns.h
</sys/src/cmd/mkone