From c912e59b898fe1ac461a1468e4a2e1937de286d7 Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Fri, 20 Dec 2019 05:54:00 +0200 Subject: [PATCH] world's saddest console --- .gitignore | 2 +- GNUmakefile | 13 +-- Makefile.dj | 18 ++-- cspr/README | 3 + src/cfgopt.c | 21 ++++- src/cfgopt.h | 1 + src/console.c | 235 ++++++++++++++++++++++++++++++++++++++++++++++ src/console.h | 14 +++ src/demo.c | 106 +++++++++------------ src/demo.h | 31 +++++- src/dos/keyb.h | 20 +--- src/dos/main.c | 3 +- src/screen.c | 14 ++- src/screen.h | 3 + src/sdl/main.c | 19 +++- tools/csprite/src/main.c | 60 +++++++++--- tools/procdata | 23 +++++ 17 files changed, 465 insertions(+), 121 deletions(-) create mode 100644 cspr/README create mode 100644 src/console.c create mode 100644 src/console.h create mode 100755 tools/procdata diff --git a/.gitignore b/.gitignore index afb00f8..e5f03cc 100644 --- a/.gitignore +++ b/.gitignore @@ -39,4 +39,4 @@ data *.dja *.DJA tools/csprite/csprite -font.asm +cspr/ diff --git a/GNUmakefile b/GNUmakefile index d0eec53..511b0ad 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -3,7 +3,7 @@ obj = $(src:.c=.o) $(asmsrc:.asm=.o) dep = $(obj:.o=.d) bin = demo -asmsrc += font.asm +asmsrc += cspr/dbgfont.asm cspr/confont.asm inc = -I/usr/local/include -Isrc -Isrc/scr -Isrc/sdl -Ilibs -Ilibs/imago/src -Ilibs/mikmod/include warn = -pedantic -Wall -Wno-unused-variable -Wno-unused-function @@ -18,6 +18,9 @@ else sdl_ldflags = `sdl-config --libs` endif +.PHONY: all +all: data $(bin) + $(bin): $(obj) imago mikmod $(CC) -o $@ $(obj) $(LDFLAGS) @@ -51,8 +54,6 @@ clean: cleandep: rm -f $(dep) -tools/csprite/csprite: - $(MAKE) -C tools/csprite - -font.asm: data/legible.fnt tools/csprite/csprite - tools/csprite/csprite -n cs_font -s 8x16 -conv565 -nasm $< >$@ +.PHONY: data +data: + @tools/procdata diff --git a/Makefile.dj b/Makefile.dj index b5c42bb..af00af7 100644 --- a/Makefile.dj +++ b/Makefile.dj @@ -4,7 +4,7 @@ obj = $(src:.c=.cof) $(asmsrc:.asm=.cof) dep = $(obj:.cof=.dep) bin = demo.exe -asmsrc += font.asm +asmsrc += cspr/dbgfont.asm cspr/confont.asm ifeq ($(findstring COMMAND.COM, $(SHELL)), COMMAND.COM) hostsys = dos @@ -23,6 +23,11 @@ AR = $(TOOLPREFIX)ar CFLAGS = $(warn) -march=pentium $(dbg) $(opt) $(inc) LDFLAGS = libs/imago/imago.dja libs/anim/anim.dja libs/mikmod/dos/libmikmod.a +ifneq ($(hostsys), dos) +.PHONY: all +all: data $(bin) +endif + $(bin): $(obj) imago anim mikmod $(CC) -o $@ -Wl,-Map=ld.map $(obj) $(LDFLAGS) @@ -76,11 +81,8 @@ clean: cleandep: rm -f $(dep) -endif - -tools/csprite/csprite: - $(MAKE) -C tools/csprite - -font.asm: data/legible.fnt tools/csprite/csprite - tools/csprite/csprite -n cs_font -s 8x16 -conv565 -nasm $< >$@ +.PHONY: data +data: + @tools/procdata +endif diff --git a/cspr/README b/cspr/README new file mode 100644 index 0000000..6218818 --- /dev/null +++ b/cspr/README @@ -0,0 +1,3 @@ +This directory is for compile sprites generated by tools/csprite. The tool runs +on UNIX/windows, not DOS. So this directory need to be populated by running +tools/procdata or tools/procdata.bat, and copied over to any DOS dev-boxes. diff --git a/src/cfgopt.c b/src/cfgopt.c index ef16167..8f3759b 100644 --- a/src/cfgopt.c +++ b/src/cfgopt.c @@ -4,12 +4,25 @@ #include #include "cfgopt.h" +#ifdef NDEBUG +/* release build default options */ +struct options opt = { + 0, /* start_scr */ + 1, /* music */ + 0, /* sball */ + 1, /* vsync */ + 0 /* dbginfo */ +}; +#else +/* debug build default options */ struct options opt = { 0, /* start_scr */ 0, /* music */ 0, /* sball */ - 1 /* vsync */ + 1, /* vsync */ + 1 /* dbginfo */ }; +#endif int parse_args(int argc, char **argv) { @@ -30,6 +43,10 @@ int parse_args(int argc, char **argv) opt.vsync = 1; } else if(strcmp(argv[i], "-novsync") == 0) { opt.vsync = 0; + } else if(strcmp(argv[i], "-dbg") == 0) { + opt.dbginfo = 1; + } else if(strcmp(argv[i], "-nodbg") == 0) { + opt.dbginfo = 0; } else { fprintf(stderr, "invalid option: %s\n", argv[i]); return -1; @@ -116,6 +133,8 @@ int load_config(const char *fname) opt.sball = bool_value(value); } else if(strcmp(line, "vsync") == 0) { opt.vsync = bool_value(value); + } else if(strcmp(line, "debug") == 0) { + opt.dbginfo = bool_value(value); } else { fprintf(stderr, "%s:%d invalid option: %s\n", fname, nline, line); return -1; diff --git a/src/cfgopt.h b/src/cfgopt.h index 57c41f6..0c302a6 100644 --- a/src/cfgopt.h +++ b/src/cfgopt.h @@ -6,6 +6,7 @@ struct options { int music; int sball; int vsync; + int dbginfo; }; extern struct options opt; diff --git a/src/console.c b/src/console.c new file mode 100644 index 0000000..f1afac2 --- /dev/null +++ b/src/console.c @@ -0,0 +1,235 @@ +#include +#include +#include +#include +#include +#include "console.h" +#include "demo.h" +#include "screen.h" + +static int runcmd(void); +static int cmd_list(const char *args); +static int cmd_help(const char *args); + +#define CBUF_SIZE 64 +#define CBUF_MASK (CBUF_SIZE - 1) + +#define HIST_SIZE 32 +#define SBUF_SIZE 4 + +static char cbuf[CBUF_SIZE]; +static char inp[CBUF_SIZE + 1], *dptr; +static int rd, wr; + +static char hist[HIST_SIZE][CBUF_SIZE + 1]; +static int hist_head, hist_tail; + +static char sbuf[SBUF_SIZE][CBUF_SIZE + 1]; +static int sbuf_head, sbuf_tail; +static int sbuf_size; + + +int con_init(void) +{ + wr = rd = 0; + hist_head = hist_tail = 0; + sbuf_head = sbuf_tail = 0; + sbuf_size = 0; + return 0; +} + +void con_start(void) +{ + wr = rd = 0; +} + +void con_stop(void) +{ +} + +void con_draw(uint16_t *fb) +{ + int x, y, sidx, cidx; + + /* print output buffer */ + y = 1; + sidx = sbuf_head; + while(sidx != sbuf_tail) { + cs_cputs(fb, 1, y, sbuf[sidx]); + sidx = (sidx + 1) & (SBUF_SIZE - 1); + y += 8; + } + + memset(fb + y++ * 320, 0xff, 640); + + cs_confont(fb, 1, y, '>' - 32); + cidx = rd; + x = 10; + while(cidx != wr) { + cs_confont(fb, x, y, cbuf[cidx] - 32); + x += 6; + cidx = (cidx + 1) & CBUF_MASK; + } + memset(fb + (y + 8) * 320, 0xff, 640); +} + +int con_input(int key) +{ + switch(key) { + case '\b': + if(wr != rd) { + wr = (wr + CBUF_SIZE - 1) & CBUF_MASK; + } + break; + + case '\n': + case '\r': + dptr = inp; + while(rd != wr) { + *dptr++ = cbuf[rd]; + rd = (rd + 1) & CBUF_MASK; + } + *dptr = 0; + if(inp[0]) { + /* add to history */ + memcpy(hist[hist_tail], inp, dptr - inp + 1); + hist_tail = (hist_tail + 1) & (HIST_SIZE - 1); + if(hist_tail == hist_head) { /* ovf */ + hist_head = (hist_head + 1) & (HIST_SIZE - 1); + } + + return runcmd(); + } + break; + + case KB_UP: + if(hist_head == hist_tail) break; + hist_tail = (hist_tail + HIST_SIZE - 1) & (HIST_SIZE - 1); + strcpy(inp, hist[hist_tail]); + break; + + default: + if(key < 256 && isprint(key)) { + cbuf[wr] = key; + wr = (wr + 1) & CBUF_MASK; + if(wr == rd) { /* overflow */ + rd = (rd + 1) & CBUF_MASK; + } + } + break; + } + + return 1; +} + +void con_printf(const char *fmt, ...) +{ + int len; + va_list ap; + + va_start(ap, fmt); + len = vsprintf(sbuf[sbuf_tail], fmt, ap); + sbuf[sbuf_tail][len] = 0; + va_end(ap); + + sbuf_tail = (sbuf_tail + 1) & (SBUF_SIZE - 1); + if(sbuf_tail == sbuf_head) { /* ovf */ + sbuf_head = (sbuf_head + 1) & (SBUF_SIZE - 1); + } + + if(sbuf_size < SBUF_SIZE) sbuf_size++; +} + +static struct { + const char *name; + int (*func)(const char*); +} cmd[] = { + {"ls", cmd_list}, + {"help", cmd_help}, + {"?", cmd_help}, + {0, 0} +}; + +static int runcmd(void) +{ + int i, nscr; + char *endp, *args; + + switch(inp[0]) { + case '/': + nscr = scr_num_screens(); + for(i=0; iname, inp + 1)) { + change_screen(i); + return 0; + } + } + con_printf("no such screen: %s\n", inp + 1); + break; + + case '#': + i = strtol(inp + 1, &endp, 10); + if(endp == inp + 1) { + con_printf("usage: #\n"); + break; + } + nscr = scr_num_screens(); + if(i < 0 || i >= nscr) { + con_printf("no such screen: %d\n", i); + break; + } + change_screen(i); + return 0; + + default: + endp = inp; + while(*endp && isspace(*endp)) endp++; + while(*endp && !isspace(*endp)) endp++; + + args = *endp ? endp + 1 : 0; + *endp = 0; + + for(i=0; cmd[i].name; i++) { + if(strcmp(inp, cmd[i].name) == 0) { + cmd[i].func(args); + return 1; + } + } + + con_printf("?%s\n", inp); + } + + return 1; +} + +static int cmd_list(const char *args) +{ + int i, nscr, len; + char buf[512], *ptr = buf; + + nscr = scr_num_screens(); + for(i=0; iname; + len = strlen(sname); + + if(ptr - buf + len > 53) { + *ptr = 0; + con_printf("%s", buf); + ptr = buf; + } + + len = sprintf(ptr, "%s ", sname); + ptr += len; + } + if(ptr > buf) { + *ptr = 0; + con_printf("%s", buf); + } + return 0; +} + +static int cmd_help(const char *args) +{ + con_printf("cmds: /, #, ls, help, ?\n"); + return 0; +} diff --git a/src/console.h b/src/console.h new file mode 100644 index 0000000..ed2c337 --- /dev/null +++ b/src/console.h @@ -0,0 +1,14 @@ +#ifndef CONSOLE_H_ +#define CONSOLE_H_ + +#include "inttypes.h" + +int con_init(void); +void con_start(void); +void con_stop(void); +void con_draw(uint16_t *fb); +int con_input(int key); + +void con_printf(const char *fmt, ...); + +#endif /* CONSOLE_H_ */ diff --git a/src/demo.c b/src/demo.c index e2b8155..8ad984c 100644 --- a/src/demo.c +++ b/src/demo.c @@ -10,6 +10,7 @@ #include "3dgfx.h" #include "music.h" #include "cfgopt.h" +#include "console.h" #include "tinyfps.h" #include "util.h" @@ -27,7 +28,7 @@ unsigned int mouse_bmask; float sball_matrix[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; static unsigned long nframes; -static int console_active; +static int con_active; int demo_init(int argc, char **argv) { @@ -44,6 +45,7 @@ int demo_init(int argc, char **argv) return -1; } + con_init(); initFpsFonts(); if(g3d_init() == -1) { @@ -102,12 +104,25 @@ void demo_draw(void) scr_update(); scr_draw(); - draw_mouse_pointer(vmem); - ++nframes; } +/* called by swap_buffers just before the actual swap */ +void demo_post_draw(void *pixels) +{ + if(opt.dbginfo) { + drawFps(pixels); + if(dbg_curscr_name) { + cs_dputs(pixels, dbg_curscr_name_pos, 240 - 16, dbg_curscr_name); + } + } + + if(con_active) { + con_draw(pixels); + } + draw_mouse_pointer(pixels); +} #define DEST(x, y) dest[(y) * FB_WIDTH + (x)] void draw_mouse_pointer(uint16_t *fb) @@ -164,37 +179,37 @@ void draw_mouse_pointer(uint16_t *fb) } } -void cs_puts(void *fb, int x, int y, const char *str) +void cs_puts_font(cs_font_func csfont, int sz, void *fb, int x, int y, const char *str) { while(*str) { int c = *str++; if(c > ' ' && c < 128) { - cs_font(fb, x, y, c - ' '); + csfont(fb, x, y, c - ' '); } - x += 9; + x += sz; } } -static void change_screen(int idx) +void change_screen(int idx) { printf("change screen %d\n", idx); scr_change(scr_screen(idx), 4000); } -#define CBUF_SIZE 64 -#define CBUF_MASK (CBUF_SIZE - 1) void demo_keyboard(int key, int press) { - static char cbuf[CBUF_SIZE]; - static int rd, wr; - char inp[CBUF_SIZE + 1], *dptr; - int i, nscr; + int nscr; if(press) { switch(key) { case 27: - demo_quit(); + if(con_active) { + con_stop(); + con_active = 0; + } else { + demo_quit(); + } return; case 127: @@ -202,71 +217,34 @@ void demo_keyboard(int key, int press) return; case '`': - console_active = !console_active; - if(console_active) { - printf("> "); - fflush(stdout); + con_active = !con_active; + if(con_active) { + con_start(); } else { - putchar('\n'); + con_stop(); } return; - case '\b': - if(console_active) { - if(wr != rd) { - printf("\b \b"); - fflush(stdout); - wr = (wr + CBUF_SIZE - 1) & CBUF_MASK; - } + case '/': + if(!con_active) { + con_start(); + con_active = con_input('/'); return; } - break; - - case '\n': - case '\r': - if(console_active) { - dptr = inp; - while(rd != wr) { - *dptr++ = cbuf[rd]; - rd = (rd + 1) & CBUF_MASK; - } - *dptr = 0; - if(inp[0]) { - printf("\ntrying to match: %s\n", inp); - nscr = scr_num_screens(); - for(i=0; iname, inp)) { - change_screen(i); - break; - } - } - } - console_active = 0; + + default: + if(con_active) { + con_active = con_input(key); return; } - break; - default: if(key >= '1' && key <= '9' && key <= '1' + scr_num_screens()) { change_screen(key - '1'); + return; } else if(key == '0' && scr_num_screens() >= 10) { change_screen(9); - } - - if(console_active) { - if(key < 256 && isprint(key)) { - putchar(key); - fflush(stdout); - - cbuf[wr] = key; - wr = (wr + 1) & CBUF_MASK; - if(wr == rd) { /* overflow */ - rd = (rd + 1) & CBUF_MASK; - } - } return; } - break; } scr_keypress(key); diff --git a/src/demo.h b/src/demo.h index a3cc66a..ff58caa 100644 --- a/src/demo.h +++ b/src/demo.h @@ -17,12 +17,32 @@ enum { MOUSE_BN_MIDDLE = 4 }; +/* special keys */ +enum { + KB_ESC = 27, + KB_BACKSP = 127, + + KB_NUM_0, KB_NUM_1, KB_NUM_2, KB_NUM_3, KB_NUM_4, + KB_NUM_5, KB_NUM_6, KB_NUM_7, KB_NUM_8, KB_NUM_9, + KB_NUM_DOT, KB_NUM_DIV, KB_NUM_MUL, KB_NUM_MINUS, KB_NUM_PLUS, KB_NUM_ENTER, KB_NUM_EQUALS, + KB_UP, KB_DOWN, KB_RIGHT, KB_LEFT, + KB_INSERT, KB_HOME, KB_END, KB_PGUP, KB_PGDN, + KB_F1, KB_F2, KB_F3, KB_F4, KB_F5, KB_F6, + KB_F7, KB_F8, KB_F9, KB_F10, KB_F11, KB_F12, + KB_F13, KB_F14, KB_F15, + KB_NUMLK, KB_CAPSLK, KB_SCRLK, + KB_RSHIFT, KB_LSHIFT, KB_RCTRL, KB_LCTRL, KB_RALT, KB_LALT, + KB_RMETA, KB_LMETA, KB_LSUPER, KB_RSUPER, KB_MODE, KB_COMPOSE, + KB_HELP, KB_PRINT, KB_SYSRQ, KB_BREAK +}; + extern float sball_matrix[16]; int demo_init(int argc, char **argv); void demo_cleanup(void); void demo_draw(void); +void demo_post_draw(void *pixels); void demo_keyboard(int key, int press); @@ -35,15 +55,22 @@ void set_palette(int idx, int r, int g, int b); /* if pixels is 0, it defaults to fb_pixels */ void swap_buffers(void *pixels); +void change_screen(int idx); + /* call each frame to get 3D viewing spherical coordinates */ void mouse_orbit_update(float *theta, float *phi, float *dist); void draw_mouse_pointer(uint16_t *fb); /* compiled sprites available */ -void cs_font(void *fb, int x, int y, int idx); +typedef void (*cs_font_func)(void *, int, int, int); +void cs_dbgfont(void *fb, int x, int y, int idx); +void cs_confont(void *fb, int x, int y, int idx); /* helper to print text with cs_font */ -void cs_puts(void *fb, int x, int y, const char *str); +void cs_puts_font(cs_font_func csfont, int sz, void *fb, int x, int y, const char *str); + +#define cs_dputs(fb, x, y, idx) cs_puts_font(cs_dbgfont, 9, fb, x, y, idx) +#define cs_cputs(fb, x, y, idx) cs_puts_font(cs_confont, 6, fb, x, y, idx) #endif /* DEMO_H_ */ diff --git a/src/dos/keyb.h b/src/dos/keyb.h index 9be97db..537a679 100644 --- a/src/dos/keyb.h +++ b/src/dos/keyb.h @@ -18,29 +18,13 @@ along with the program. If not, see #ifndef KEYB_H_ #define KEYB_H_ +#include "demo.h" + #define KB_ANY (-1) #define KB_ALT (-2) #define KB_CTRL (-3) #define KB_SHIFT (-4) -/* special keys */ -enum { - KB_LALT, KB_RALT, - KB_LCTRL, KB_RCTRL, - KB_LSHIFT, KB_RSHIFT, - KB_F1, KB_F2, KB_F3, KB_F4, KB_F5, KB_F6, - KB_F7, KB_F8, KB_F9, KB_F10, KB_F11, KB_F12, - KB_CAPSLK, KB_NUMLK, KB_SCRLK, KB_SYSRQ, - KB_ESC = 27, - KB_INSERT, KB_DEL, KB_HOME, KB_END, KB_PGUP, KB_PGDN, - KB_LEFT, KB_RIGHT, KB_UP, KB_DOWN, - KB_NUM_DOT, KB_NUM_ENTER, KB_NUM_PLUS, KB_NUM_MINUS, KB_NUM_MUL, KB_NUM_DIV, - KB_NUM_0, KB_NUM_1, KB_NUM_2, KB_NUM_3, KB_NUM_4, - KB_NUM_5, KB_NUM_6, KB_NUM_7, KB_NUM_8, KB_NUM_9, - KB_BACKSP = 127 -}; - - #ifdef __cplusplus extern "C" { #endif diff --git a/src/dos/main.c b/src/dos/main.c index 70ea449..4dcca05 100644 --- a/src/dos/main.c +++ b/src/dos/main.c @@ -124,11 +124,12 @@ void swap_buffers(void *pixels) pixels = fb_pixels; } + demo_post_draw(pixels); + /* just memcpy to the front buffer */ if(opt.vsync) { wait_vsync(); } - drawFps(pixels); memcpy(vmem, pixels, fbsize); } diff --git a/src/screen.c b/src/screen.c index 68a8c7f..362a15c 100644 --- a/src/screen.c +++ b/src/screen.c @@ -5,6 +5,13 @@ #include "screen.h" #include "demo.h" +#define DBG_SCRCHG \ + do { \ + dbg_curscr_name = cur->name ? cur->name : ""; \ + dbg_curscr_name_len = strlen(dbg_curscr_name); \ + dbg_curscr_name_pos = 320 - dbg_curscr_name_len * 9; \ + } while(0) + struct screen *tunnel_screen(void); struct screen *fract_screen(void); struct screen *grise_screen(void); @@ -92,6 +99,8 @@ void scr_update(void) prev = 0; cur = next; next = 0; + + DBG_SCRCHG; } } } @@ -101,9 +110,6 @@ void scr_draw(void) { if(cur) { cur->draw(); - - /* print screen name */ - cs_puts(fb_pixels, 0, 0, cur->name); } } @@ -158,6 +164,8 @@ int scr_change(struct screen *s, long trans_time) cur = s; prev = 0; + + DBG_SCRCHG; } return 0; } diff --git a/src/screen.h b/src/screen.h index c2e4974..85a1f86 100644 --- a/src/screen.h +++ b/src/screen.h @@ -15,6 +15,9 @@ struct screen { void (*keypress)(int key); }; +const char *dbg_curscr_name; +int dbg_curscr_name_len, dbg_curscr_name_pos; + int scr_init(void); void scr_shutdown(void); diff --git a/src/sdl/main.c b/src/sdl/main.c index 6a52021..de27777 100644 --- a/src/sdl/main.c +++ b/src/sdl/main.c @@ -16,6 +16,8 @@ static void toggle_fullscreen(void); static int handle_sball_event(sball_event *ev); static void recalc_sball_matrix(float *xform); +static int sdlkey_to_demokey(int sdlkey); + static int quit; static SDL_Surface *fbsurf; @@ -91,7 +93,6 @@ int main(int argc, char **argv) time_msec = get_msec(); demo_draw(); - drawFps(fb_pixels); if(SDL_MUSTLOCK(fbsurf)) { SDL_LockSurface(fbsurf); @@ -140,6 +141,8 @@ void wait_vsync(void) void swap_buffers(void *pixels) { + demo_post_draw(pixels ? pixels : fb_pixels); + /* do nothing, all pointers point to the same buffer */ if(opt.vsync) { wait_vsync(); @@ -163,6 +166,8 @@ static int bnmask(int sdlbn) static void handle_event(SDL_Event *ev) { + int key; + switch(ev->type) { case SDL_QUIT: quit = 1; @@ -175,7 +180,8 @@ static void handle_event(SDL_Event *ev) toggle_fullscreen(); break; } - demo_keyboard(ev->key.keysym.sym, ev->key.state == SDL_PRESSED ? 1 : 0); + key = sdlkey_to_demokey(ev->key.keysym.sym); + demo_keyboard(key, ev->key.state == SDL_PRESSED ? 1 : 0); break; case SDL_MOUSEMOTION: @@ -252,10 +258,17 @@ static int handle_sball_event(sball_event *ev) return 0; } -void recalc_sball_matrix(float *xform) +static void recalc_sball_matrix(float *xform) { quat_to_mat(xform, rot); xform[12] = pos.x; xform[13] = pos.y; xform[14] = pos.z; } + +static int sdlkey_to_demokey(int sdlkey) +{ + if(sdlkey < 128) return sdlkey; + if(sdlkey < 256) return 0; + return sdlkey - 128; +} diff --git a/tools/csprite/src/main.c b/tools/csprite/src/main.c index 0192002..fab302b 100644 --- a/tools/csprite/src/main.c +++ b/tools/csprite/src/main.c @@ -24,6 +24,8 @@ int fbpitch, fbwidth = 320; const char *name = "sprite"; int asyntax = AS_GNU; int conv565; +int padding; +const char *wrop = "mov"; int main(int argc, char **argv) { @@ -46,6 +48,13 @@ int main(int argc, char **argv) return 1; } + } else if(strcmp(argv[i], "-p") == 0 || strcmp(argv[i], "-pad") == 0) { + padding = strtol(argv[++i], &endp, 10); + if(endp == argv[i] || padding < 0) { + fprintf(stderr, "%s must be followed by a positive number\n", argv[i - 1]); + return 1; + } + } else if(strcmp(argv[i], "-coffset") == 0) { cmap_offs = strtol(argv[++i], &endp, 10); if(endp == argv[i] || cmap_offs < 0 || cmap_offs >= 256) { @@ -84,6 +93,9 @@ int main(int argc, char **argv) } else if(strcmp(argv[i], "-conv565") == 0) { conv565 = 1; + } else if(strcmp(argv[i], "-x") == 0 || strcmp(argv[i], "-xor") == 0) { + wrop = "xor"; + } else if(strcmp(argv[i], "-gas") == 0) { asyntax = AS_GNU; @@ -155,7 +167,7 @@ const char *prefixfmt[] = { int proc_sheet(const char *fname) { - int i, j, num_xtiles, num_ytiles, xsz, ysz, tidx; + int i, j, x, y, num_xtiles, num_ytiles, xsz, ysz, tidx; struct image img; if(load_image(&img, fname) == -1) { @@ -182,11 +194,25 @@ int proc_sheet(const char *fname) if(tile_xsz <= 0) { num_xtiles = num_ytiles = 1; - xsz = rect.w; - ysz = rect.h; + xsz = rect.w - padding; + ysz = rect.h - padding; } else { - num_xtiles = rect.w / tile_xsz; - num_ytiles = rect.h / tile_ysz; + if(padding) { + num_xtiles = num_ytiles = 0; + i = 0; + while(i < rect.w) { + num_xtiles++; + i += tile_xsz + padding; + } + i = 0; + while(i < rect.h) { + num_ytiles++; + i += tile_ysz + padding; + } + } else { + num_xtiles = rect.w / tile_xsz; + num_ytiles = rect.h / tile_ysz; + } xsz = tile_xsz; ysz = tile_ysz; } @@ -202,11 +228,15 @@ int proc_sheet(const char *fname) putchar('\n'); tidx = 0; + y = rect.y; for(i=0; ilen * pixsz; for(j=0; j: tile size (default: whole image)\n"); printf(" -r,-rect : use rectangle of the input image (default: whole image)\n"); + printf(" -p,-pad : how many pixels to skip between tiles in source image (default: 0)\n"); printf(" -coffset : colormap offset [0, 255] (default: 0)\n"); printf(" -fbpitch : target framebuffer pitch (scanline size in bytes)\n"); printf(" -k,-key : color-key for transparency (default: 0)\n"); printf(" -conv565: convert image to 16bpp 565 before processing\n"); + printf(" -x,-xor: use XOR for writing pixels instead of MOV\n"); printf(" -gas: output GNU assembler code (default)\n"); printf(" -nasm: output NASM-compatible code\n"); printf(" -h: print usage and exit\n"); diff --git a/tools/procdata b/tools/procdata new file mode 100755 index 0000000..3cef48a --- /dev/null +++ b/tools/procdata @@ -0,0 +1,23 @@ +#!/bin/sh + +[ -f ./procdata ] && cd .. +if [ ! -f tools/procdata ]; then + echo 'run from the demo root directory' >&2 + exit 1 +fi + +if [ ! -f tools/csprite/csprite ]; then + make -C tools/csprite || exit 1 +fi + +alias csprite=tools/csprite/csprite + +mkdir -p cspr +if [ ! -f cspr/dbgfont.asm -o data/legible.fnt -nt cspr/dbgfont.asm ]; then + echo 'csprite: dbgfont' + csprite -n cs_dbgfont -s 8x16 -conv565 -nasm -xor data/legible.fnt >cspr/dbgfont.asm +fi +if [ ! -f cspr/confont.asm -o data/con.fnt -nt cspr/confont.asm ]; then + echo 'csprite: confont' + csprite -n cs_confont -s 6x7 -pad 1 -conv565 -nasm data/con.fnt >cspr/confont.asm +fi -- 1.7.10.4