shithub: scoundrel

ref: 4da095780a50c2ee473afc4e8907e706d4150fb5
dir: /main.c/

View raw version
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <keyboard.h>
#include <event.h>
#include "dat.h"
#include "fns.h"

static void
usage(void)
{
	fprint(2, "usage: %s\n", argv0);
	exits("usage");
}

Image *background;

static void
initimg(void)
{
	background = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, 0x00BB22FF);
}

Point carddim;
Rectangle roomrects[4];
Rectangle weaponrect;
int panelstart;

static void
drawroom(int *cards)
{
	int i;
	Point p;
	Image *img;
	
	for (i = 0; i < 4; i++) {
		if (cards[i] <= 0)
			continue;
		img = getimage(cards[i]);
		if (!img)
			sysfatal("%r");
		p.x = panelstart + i * (Dx(img->r) + 5);
		p.y = 5;
		p = addpt(p, screen->r.min);
		roomrects[i] = rectaddpt(img->r, p);
		draw(screen, roomrects[i], img, nil, ZP);
	}
}

int useweapon = 0;

static void
drawweapon(int weapon, int killed)
{
	Point p;
	Image *img;
	
	if (weapon <= 0)
		return;
	
	img = getimage(weapon);
	if (!img)
		sysfatal("%r");
	
	p.x = panelstart;
	p.y = Dy(img->r) + 10;
	p = addpt(p, screen->r.min);
	weaponrect = rectaddpt(img->r, p);
	draw(screen, weaponrect, img, nil, ZP);
	
	if (useweapon) {
		p.x = panelstart + Dx(img->r) + 20;
		p.y = Dy(img->r) + 20;
		p = addpt(p, screen->r.min);
		line(screen, p, Pt(p.x, p.y + Dy(img->r) - 20),
			Enddisc, Enddisc, 4, display->black, ZP);
	}
	
	if (killed < 0)
		return;
	
	img = getimage(killed);
	if (!img)
		sysfatal("%r");
	
	p.x = panelstart + 5;
	p.y = Dy(img->r) + 10 + 45;
	p = addpt(p, screen->r.min);
	draw(screen, rectaddpt(img->r, p), img, nil, ZP);
}

static void
drawstats(State *state)
{
	Point p;
	char s[64];
	
	p.x = panelstart;
	p.x += carddim.x + 100;
	p.y = carddim.y + 40;
	p = addpt(p, screen->r.min);
	
	snprint(s, sizeof s, "Deck: %d", state->deckcards);
	string(screen, p, display->black, ZP, font, s);
	
	p.y += 50;
	snprint(s, sizeof s, "HP: %d", state->hp);
	string(screen, p, display->black, ZP, font, s);
}

static void
drawdialog(State *state)
{
	Point p, sp;
	char *message;
	if (state->status == Running)
		return;
	
	message = nil;
	switch (state->status) {
	case Notstarted:
		message = "Press 's' to start a new game";
		break;
	case Won:
		message = "You won! Press 's' to start a new game";
		break;
	case Lost:
		message = "You lost! Press 's' to start a new game";
		break;
	}
	
	if (!message)
		return;
	
	sp.x = Dx(screen->r);
	sp.y = Dy(screen->r);
	p = stringsize(font, message);
	p.x = (sp.x - p.x) / 2;
	p.y = (sp.y - p.y) / 2;
	
	stringbg(screen, addpt(p, screen->r.min), display->black, ZP, font, message, display->white, ZP);
}

static void
redraw(void)
{
	State *state;
	draw(screen, screen->r, background, nil, ZP);
	
	state = getstate();
	
	panelstart = (Dx(screen->r) - (carddim.x+5)*4)/2;
	drawroom(state->room);
	drawweapon(state->weapon, state->lastweaponkill);
	drawstats(state);
	drawdialog(state);
}

void
eresized(int new)
{
	if (new && getwindow(display, Refnone) < 0)
		sysfatal("resized: %r");
	
	redraw();
}

static void
handlekbd(int key)
{
	int i;
	switch (key) {
	case 'w':
		useweapon = !useweapon;
		redraw();
		break;
	case '1':
	case '2':
	case '3':
	case '4':
		i = key - '0';
		i = roomaction(i-1, useweapon);
		useweapon = 0;
		if (i) goto Redraw;
		break;
	case 's':
		if (startgame()) goto Redraw;
		break;
	case 'n':
		if (nextround()) goto Redraw;
		break;
	case 'r':
		initgame();
		if (startgame()) goto Redraw;
		break;
	}
	return;
Redraw:
	redraw();
}

int lastbutton = 0;
static void
handlemouse(Mouse m)
{
	int i;
	
	if (m.buttons != 1) {
		lastbutton = 0;
		return;
	}
	if (lastbutton == m.buttons)
		return;
	lastbutton = m.buttons;
	
	for (i = 0; i < 4; i++) {
		/* room cards */
		if (ptinrect(m.xy, roomrects[i])) {
			if (roomaction(i, useweapon))
				redraw();
			return;
		}
	}
	
	if (ptinrect(m.xy, weaponrect)) {
		/* weapon card */
		useweapon = !useweapon;
		redraw();
		return;
	}
}

void
main(int argc, char **argv)
{
	int e;
	Event ev;
	Image *img;
	
	ARGBEGIN{
	case 'h':
		usage();
		break;
	}ARGEND;
	
	if (initdraw(nil, nil, "scoundrel") < 0)
		sysfatal("initdraw: %r");
	
	initimg();
	
	einit(Emouse|Ekeyboard);
	srand(time(0));
	
	loadimages("img");
	initgame();
	
	/* 2 must be valid */
	img = getimage(2);
	carddim.x = Dx(img->r);
	carddim.y = Dy(img->r);
	
	redraw();
	
	for (;;) {
		e = event(&ev);
		switch (e) {
		case Emouse:
			handlemouse(ev.mouse);
			break;
		case Ekeyboard:
			if (ev.kbdc == Kesc || ev.kbdc == 'q')
				exits(nil);
			handlekbd(ev.kbdc);
		}
	}
}