From ce38b43357c573f4a68d24a10f847473ff77b305 Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Wed, 18 Apr 2012 03:47:31 +0000 Subject: Graphic display, no scalling, no input ... jet --- Makefile | 5 +- dcpu16.h | 3 +- font.h | 137 ++++++++++++++++++++++++++++++++++++++++++++++ gui.c | 187 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ main.c | 17 +++--- tui.c | 7 ++- 6 files changed, 343 insertions(+), 13 deletions(-) create mode 100644 font.h create mode 100644 gui.c 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 + * + * 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 +#include +#include +#include +#include +#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 #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(); } -- cgit v1.2.3