aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2012-04-18 03:47:31 +0000
committerDimitri Sokolyuk <demon@dim13.org>2012-04-18 03:47:31 +0000
commitce38b43357c573f4a68d24a10f847473ff77b305 (patch)
tree460172d3071b95854d354661a0352c910aa003f3
parentb7fd152aa1f40ca89da321040e8e86a48e19d1e0 (diff)
Graphic display, no scalling, no input ... jet
-rw-r--r--Makefile5
-rw-r--r--dcpu16.h3
-rw-r--r--font.h137
-rw-r--r--gui.c187
-rw-r--r--main.c17
-rw-r--r--tui.c7
6 files changed, 343 insertions, 13 deletions
diff --git a/Makefile b/Makefile
index edc7262..12c59f8 100644
--- a/Makefile
+++ b/Makefile
@@ -1,9 +1,10 @@
# $Id$
PROG= dcpu
-SRCS= gramar.y lexer.l emu.c main.c tui.c y.tab.h
+SRCS= gramar.y lexer.l emu.c main.c tui.c gui.c y.tab.h
NOMAN=
-LDADD+= -lcurses
+CFLAGS+=`sdl-config --cflags`
+LDADD+= `sdl-config --libs` -lcurses
DEBUG+= -Wall
#DEBUG+= -ggdb -pg
#YFLAGS= -dtv
diff --git a/dcpu16.h b/dcpu16.h
index 9ede832..0f11c77 100644
--- a/dcpu16.h
+++ b/dcpu16.h
@@ -44,6 +44,7 @@ enum { Res, JSR, BRK, nExt };
unsigned short *compile(FILE *, size_t);
int step(unsigned short *, unsigned short *);
void tuiemu(unsigned short *, unsigned short *);
-
+void guiemu(unsigned short *, unsigned short *);
+void dumpcode(unsigned short *, unsigned short *);
#endif
diff --git a/font.h b/font.h
new file mode 100644
index 0000000..dd0ad7c
--- /dev/null
+++ b/font.h
@@ -0,0 +1,137 @@
+/* $Id$ */
+
+#ifndef _FONT_H
+#define _FONT_H
+
+unsigned short atari_small[0x80][2] = {
+ { 0x0000, 0x0000 },
+ { 0x081c, 0x3e1c },
+ { 0x0055, 0xaa55 },
+ { 0x001f, 0x24ff },
+ { 0x1f05, 0xf928 },
+ { 0x0205, 0xf550 },
+ { 0x0f08, 0xf850 },
+ { 0x001e, 0x121e },
+ { 0x0024, 0x2e24 },
+ { 0x0f02, 0xf48f },
+ { 0x0708, 0x17f0 },
+ { 0x0808, 0x0f00 },
+ { 0x0808, 0xf800 },
+ { 0x0000, 0xf808 },
+ { 0x0000, 0x0f08 },
+ { 0x0808, 0xff08 },
+ { 0x0002, 0x0202 },
+ { 0x0004, 0x0404 },
+ { 0x0008, 0x0808 },
+ { 0x0010, 0x1010 },
+ { 0x0020, 0x2020 },
+ { 0x0000, 0xff08 },
+ { 0x0808, 0xff00 },
+ { 0x1010, 0x1f10 },
+ { 0x1010, 0xf010 },
+ { 0x0000, 0xff00 },
+ { 0x0048, 0x5462 },
+ { 0x0062, 0x5448 },
+ { 0x023e, 0x023e },
+ { 0x1434, 0x1c16 },
+ { 0x247e, 0x1531 },
+ { 0x0000, 0x0800 },
+ { 0x0000, 0x0000 },
+ { 0x005e, 0x0000 },
+ { 0x0600, 0x0600 },
+ { 0x7e24, 0x7e00 },
+ { 0x24cb, 0x3400 },
+ { 0x6218, 0x4600 },
+ { 0x3a65, 0x5a00 },
+ { 0x0006, 0x0000 },
+ { 0x003c, 0x4200 },
+ { 0x423c, 0x0000 },
+ { 0x2a1c, 0x2a00 },
+ { 0x083e, 0x0800 },
+ { 0x8060, 0x0000 },
+ { 0x0808, 0x0800 },
+ { 0x0060, 0x0000 },
+ { 0x6018, 0x0600 },
+ { 0x3c4a, 0x3c00 },
+ { 0x447e, 0x4000 },
+ { 0x6452, 0x4c00 },
+ { 0x224a, 0x3600 },
+ { 0x1814, 0x7e00 },
+ { 0x2e4a, 0x3200 },
+ { 0x3c4a, 0x3200 },
+ { 0x0272, 0x0e00 },
+ { 0x344a, 0x3400 },
+ { 0x4c52, 0x3c00 },
+ { 0x0024, 0x0000 },
+ { 0x4024, 0x0000 },
+ { 0x1028, 0x4400 },
+ { 0x1414, 0x1400 },
+ { 0x4428, 0x1000 },
+ { 0x0452, 0x0c00 },
+ { 0x3c42, 0x4c00 },
+ { 0x7c12, 0x7c00 },
+ { 0x7e4a, 0x3400 },
+ { 0x3c42, 0x2400 },
+ { 0x7e42, 0x3c00 },
+ { 0x7e4a, 0x4a00 },
+ { 0x7e0a, 0x0a00 },
+ { 0x3c42, 0x3400 },
+ { 0x7e08, 0x7e00 },
+ { 0x427e, 0x4200 },
+ { 0x2040, 0x3e00 },
+ { 0x7e08, 0x7600 },
+ { 0x7e40, 0x4000 },
+ { 0x7e04, 0x7e00 },
+ { 0x7c18, 0x3e00 },
+ { 0x3c42, 0x3c00 },
+ { 0x7e12, 0x0c00 },
+ { 0x3c62, 0x5c00 },
+ { 0x7e12, 0x6c00 },
+ { 0x244a, 0x3400 },
+ { 0x027e, 0x0200 },
+ { 0x7e40, 0x7e00 },
+ { 0x3e40, 0x3e00 },
+ { 0x7e20, 0x7e00 },
+ { 0x7608, 0x7600 },
+ { 0x0678, 0x0600 },
+ { 0x625a, 0x4600 },
+ { 0x007e, 0x4200 },
+ { 0x0618, 0x6000 },
+ { 0x427e, 0x0000 },
+ { 0x0402, 0x0400 },
+ { 0x8080, 0x8080 },
+ { 0x0204, 0x0000 },
+ { 0x2454, 0x7800 },
+ { 0x7e48, 0x3000 },
+ { 0x3844, 0x4400 },
+ { 0x3048, 0x7e00 },
+ { 0x3854, 0x5800 },
+ { 0x087c, 0x0a00 },
+ { 0x98a4, 0x7c00 },
+ { 0x7e08, 0x7000 },
+ { 0x487a, 0x4000 },
+ { 0x8088, 0x7a00 },
+ { 0x7e10, 0x6800 },
+ { 0x007e, 0x0000 },
+ { 0x7c08, 0x7c00 },
+ { 0x7c04, 0x7800 },
+ { 0x3844, 0x3800 },
+ { 0xfc24, 0x1800 },
+ { 0x1824, 0xfc00 },
+ { 0x7804, 0x0400 },
+ { 0x4854, 0x2400 },
+ { 0x087e, 0x0800 },
+ { 0x7c40, 0x7c00 },
+ { 0x3c40, 0x3c00 },
+ { 0x7c20, 0x7c00 },
+ { 0x6c10, 0x6c00 },
+ { 0x9ca0, 0x7c00 },
+ { 0x6454, 0x4c00 },
+ { 0x0836, 0x4100 },
+ { 0x0077, 0x0000 },
+ { 0x4136, 0x0800 },
+ { 0x040c, 0x0800 },
+ { 0x0000, 0x0000 },
+};
+
+#endif
diff --git a/gui.c b/gui.c
new file mode 100644
index 0000000..90cb7a0
--- /dev/null
+++ b/gui.c
@@ -0,0 +1,187 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2012 Dimitri Sokolyuk <demon@dim13.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, dATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <SDL.h>
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "dcpu16.h"
+#include "font.h"
+
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+Uint32 rmask = 0xff000000;
+Uint32 gmask = 0x00ff0000;
+Uint32 bmask = 0x0000ff00;
+Uint32 amask = 0x000000ff;
+#else
+Uint32 rmask = 0x000000ff;
+Uint32 gmask = 0x0000ff00;
+Uint32 bmask = 0x00ff0000;
+Uint32 amask = 0xff000000;
+#endif
+
+SDL_Surface *screen;
+
+SDL_Rect disp = { 0, 0, 640, 480 };
+SDL_Rect out = { 64, 48, 640, 480 };
+
+SDL_Rect draw = { 16, 12, 128, 96 };
+SDL_Rect scr = { 0, 0, 160, 120 };
+SDL_Rect gl = { 0, 0, 4, 8 };
+SDL_Color black = { 0x00, 0x00, 0x00 };
+SDL_Color white = { 0xff, 0xff, 0xff };
+
+SDL_Color color[0x10] = {
+ { 0x00, 0x00, 0x00 },
+ { 0x00, 0x00, 0xaa },
+ { 0x00, 0xaa, 0x00 },
+ { 0x00, 0xaa, 0xaa },
+ { 0xaa, 0x00, 0x00 },
+ { 0xaa, 0x00, 0xaa },
+ { 0xaa, 0x55, 0x00 },
+ { 0xaa, 0xaa, 0xaa },
+ { 0x55, 0x55, 0x55 },
+ { 0x55, 0x55, 0xff },
+ { 0x55, 0xff, 0x55 },
+ { 0x55, 0xff, 0xff },
+ { 0xff, 0x55, 0x55 },
+ { 0xff, 0x55, 0xff },
+ { 0xff, 0xff, 0x55 },
+ { 0xff, 0xff, 0xff },
+};
+
+void
+decodecolor(unsigned short u, SDL_Color **fg, SDL_Color **bg)
+{
+ *bg = &color[(u >> 8) & 0x0f];
+ *fg = &color[(u >> 12) & 0x0f];
+}
+
+void
+setpixel(SDL_Surface *s, int x, int y, SDL_Color *c)
+{
+ Uint32 *buf = (Uint32 *)s->pixels + y * (s->pitch >> 2) + x;
+ Uint32 pixel = SDL_MapRGB(s->format, c->r, c->g, c->b);
+ *buf = pixel;
+}
+
+void
+fillrect(SDL_Surface *s, SDL_Rect *r, SDL_Color *c)
+{
+ SDL_FillRect(s, r, SDL_MapRGB(s->format, c->r, c->g, c->b));
+}
+
+SDL_Surface *
+mkglyph(unsigned char ch, SDL_Color *fg, SDL_Color *bg, unsigned short *m)
+{
+ SDL_Surface *g;
+ SDL_Color *c;
+ int i;
+
+ g = SDL_CreateRGBSurface(SDL_SWSURFACE, gl.w, gl.h, 32,
+ rmask, gmask, bmask, amask);
+
+ ch &= 0x7f;
+ ch <<= 1;
+
+ for (i = 0; i < 8; i++) {
+ c = m[CHARS + ch] & (0x0100 << i) ? fg : bg;
+ setpixel(g, 0, i, c);
+
+ c = m[CHARS + ch] & (0x0001 << i) ? fg : bg;
+ setpixel(g, 1, i, c);
+
+ c = m[CHARS + ch + 1] & (0x0100 << i) ? fg : bg;
+ setpixel(g, 2, i, c);
+
+ c = m[CHARS + ch + 1] & (0x0001 << i) ? fg : bg;
+ setpixel(g, 3, i, c);
+ }
+
+ return g;
+}
+
+void
+setfont(unsigned short *m)
+{
+ int i;
+
+ for (i = 0; i < 0x80; i++) {
+ m[CHARS + 2 * i] = atari_small[i][0];
+ m[CHARS + 2 * i + 1] = atari_small[i][1];
+ }
+
+ m[MISC] = 0x8000; /* set default fg/bg */
+}
+
+void
+guiemu(unsigned short *m, unsigned short *r)
+{
+ SDL_Surface *glyph;
+ SDL_Rect to;
+ SDL_Color *fg, *bg;
+ SDL_Event event;
+ int ch, x, y, k = 0, n = 0;
+
+ screen = SDL_SetVideoMode(scr.w, scr.h, 32, SDL_SWSURFACE);
+ setfont(m);
+
+ to.w = gl.w;
+ to.h = gl.h;
+
+ while (step(m, r) != -1) {
+ if (++n % 100)
+ continue;
+
+ decodecolor(m[MISC], &fg, &bg);
+
+ fillrect(screen, &scr, bg);
+
+ for (x = 0; x < 32; x++) {
+ for (y = 0; y < 12; y++) {
+ to.x = draw.x + x * to.w;
+ to.y = draw.y + y * to.h;
+
+ ch = m[DISP + y * 32 + x];
+
+ decodecolor(ch, &fg, &bg);
+ glyph = mkglyph(ch, fg, bg, m);
+
+ SDL_BlitSurface(glyph, &gl, screen, &to);
+ SDL_FreeSurface(glyph);
+ }
+ }
+
+ SDL_Flip(screen);
+
+ while (SDL_PollEvent(&event)) {
+ switch (event.type) {
+ case SDL_QUIT:
+ goto leave;
+ case SDL_KEYDOWN:
+ m[KEYB + k] = event.key.keysym.sym;
+ printf("%x\n", m[KEYB + k]);
+ k = (k + 1) % 0x10;
+ break;
+ }
+ }
+ }
+
+leave:
+ SDL_FreeSurface(screen);
+}
diff --git a/main.c b/main.c
index 02a4f8f..70634d1 100644
--- a/main.c
+++ b/main.c
@@ -21,8 +21,10 @@
#include <unistd.h>
#include "dcpu16.h"
+void (*emu)(unsigned short *, unsigned short *);
+
void
-dumpcode(unsigned short *m)
+dumpcode(unsigned short *m, unsigned short *r)
{
int i, k, sum;
@@ -54,17 +56,17 @@ main(int argc, char **argv)
unsigned short *m;
unsigned short r[nReg] = { 0 };
FILE *fd;
- int e_flag = 0;
- int g_flag = 0;
int ch;
+ emu = dumpcode;
+
while ((ch = getopt(argc, argv, "eg")) != -1)
switch (ch) {
case 'e':
- e_flag = 1;
+ emu = tuiemu;
break;
case 'g':
- g_flag = 1;
+ emu = guiemu;
break;
default:
usage();
@@ -84,10 +86,7 @@ main(int argc, char **argv)
m = compile(fd, MEMSZ);
fclose(fd);
- if (e_flag)
- tuiemu(m, r);
- else
- dumpcode(m);
+ emu(m, r);
return 0;
}
diff --git a/tui.c b/tui.c
index 5bbbfdc..297f2ce 100644
--- a/tui.c
+++ b/tui.c
@@ -127,7 +127,7 @@ init_colors()
void
tuiemu(unsigned short *m, unsigned short *r)
{
- int ch;
+ int ch, n = 0;
initscr();
@@ -152,13 +152,18 @@ tuiemu(unsigned short *m, unsigned short *r)
m[KEYP] = KEYB;
while (step(m, r) != -1) {
+ if (n % 100)
+ continue;
+
dumpmem(m);
dumpdisp(m);
dumpreg(m, r);
+
if ((ch = wgetch(stdscr)) != ERR) {
m[m[KEYP]] = ch;
m[KEYP] = KEYB + (m[KEYP] + 1) % 0x10;
}
+
doupdate();
}