From b0088adf036a53139f67ebf96f1bbb55abf199f4 Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Wed, 7 Jun 2023 22:46:35 +0300 Subject: [PATCH] integrating software renderer --- GNUmakefile | 5 +- src/app.c | 115 +++++++++++------- src/app.h | 6 + src/gaw/gaw.h | 3 +- src/gaw/gaw_gl.c | 7 +- src/gaw/gaw_glide.c | 2 +- src/gaw/gaw_glide.h | 2 +- src/gaw/gaw_sw.c | 2 +- src/gaw/gawswtnl.c | 10 +- src/gaw/gawswtnl.h | 2 +- src/gaw/polyclip.c | 17 +++ src/gaw/polyclip.h | 17 +++ src/gaw/polyfill.c | 17 +++ src/gaw/polyfill.h | 17 +++ src/gaw/polytmpl.h | 17 +++ src/logger.c | 320 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/logger.h | 42 +++++++ src/modern/main.c | 17 +++ src/rtk.c | 132 +++++++++++++++++++-- src/rtk.h | 14 ++- src/rtk_impl.h | 8 -- src/scr_mod.c | 129 ++++++++++++++++++++- 22 files changed, 828 insertions(+), 73 deletions(-) create mode 100644 src/logger.c create mode 100644 src/logger.h diff --git a/GNUmakefile b/GNUmakefile index fb746ac..d897cc1 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -9,6 +9,9 @@ build_dbg ?= true gawsrc_gl = src/gaw/gaw_gl.c gawsrc_sw = src/gaw/gaw_sw.c src/gaw/gawswtnl.c src/gaw/polyfill.c src/gaw/polyclip.c +gawdef_gl = -DGFX_GL +gawdef_sw = -DGFX_SW + src = $(wildcard src/*.c) $(wildcard src/modern/*.c) $(gawsrc_$(build_gfx)) obj = $(src:.c=.o) dep = $(src:.c=.d) @@ -17,7 +20,7 @@ bin = retroray warn = -pedantic -Wall dbg = -g #opt = -O3 -def = -DMINIGLUT_USE_LIBC +def = -DMINIGLUT_USE_LIBC $(gawdef_$(build_gfx)) inc = -Isrc -Isrc/modern -Ilibs -Ilibs/imago/src -Ilibs/treestor/include -Ilibs/drawtext libs = libs/unix/imago.a libs/unix/treestor.a libs/unix/drawtext.a diff --git a/src/app.c b/src/app.c index e3af5ab..fdcbe11 100644 --- a/src/app.c +++ b/src/app.c @@ -26,7 +26,16 @@ along with this program. If not, see . #include "options.h" #include "font.h" #include "util.h" +#include "rtk.h" +#ifdef GFX_SW +#include "gaw/gaw_sw.h" +#endif + +static void gui_fill(rtk_rect *rect, uint32_t color); +static void gui_blit(int x, int y, rtk_icon *icon); +static void gui_drawtext(int x, int y, const char *str); +static void gui_textrect(const char *str, rtk_rect *rect); static void txdraw(struct dtx_vertex *v, int vcount, struct dtx_pixmap *pixmap, void *cls); int mouse_x, mouse_y, mouse_state[3]; @@ -41,6 +50,9 @@ struct app_screen *cur_scr; struct font *uifont; +uint32_t *framebuf; + + /* available screens */ #define MAX_SCREENS 8 static struct app_screen *screens[MAX_SCREENS]; @@ -51,6 +63,9 @@ int app_init(void) { int i; char *start_scr_name; + static rtk_draw_ops guigfx = {gui_fill, gui_blit, gui_drawtext, gui_textrect}; + + init_logger(); #if !defined(NDEBUG) && defined(DBG_FPEXCEPT) printf("floating point exceptions enabled\n"); @@ -72,6 +87,8 @@ int app_init(void) return -1; } + rtk_setup(&guigfx); + /* initialize screens */ screens[num_screens++] = &scr_model; screens[num_screens++] = &scr_rend; @@ -115,6 +132,8 @@ void app_shutdown(void) destroy_font(uifont); free(uifont); + + cleanup_logger(); } void app_display(void) @@ -128,6 +147,21 @@ void app_display(void) void app_reshape(int x, int y) { + int numpix = x * y; + int prev_numpix = win_width * win_height; + + if(numpix > prev_numpix) { + void *tmp; + if(!(tmp = realloc(framebuf, numpix * sizeof *framebuf))) { + errormsg("failed to resize framebuffer to %dx%d\n", x, y); + return; + } + framebuf = tmp; + } +#ifdef GFX_SW + gaw_sw_framebuffer(x, y, framebuf); +#endif + win_width = x; win_height = y; win_aspect = (float)x / (float)y; @@ -226,57 +260,50 @@ void app_chscr(struct app_screen *scr) cur_scr = scr; } -static void txdraw(struct dtx_vertex *v, int vcount, struct dtx_pixmap *pixmap, void *cls) +static void gui_fill(rtk_rect *rect, uint32_t color) { - /* - int i, aref, npix; - unsigned char *src, *dest; - struct texture *tex = pixmap->udata; - - if(!tex) { - struct img_pixmap *img = img_create(); - img_set_pixels(img, pixmap->width, pixmap->height, IMG_FMT_RGBA32, 0); - - npix = pixmap->width * pixmap->height; - src = pixmap->pixels; - dest = img->pixels; - for(i=0; iy * win_width + rect->x; - if(!(tex = tex_image(img))) { - return; + for(i=0; iheight; i++) { + for(j=0; jwidth; j++) { + fb[j] = color; } - pixmap->udata = tex; + fb += win_width; } +} - gaw_save(); - if(dtx_get(DTX_GL_BLEND)) { - gaw_enable(GAW_BLEND); - gaw_blend_func(GAW_SRC_ALPHA, GAW_ONE_MINUS_SRC_ALPHA); - } else { - gaw_disable(GAW_BLEND); - } - if((aref = dtx_get(DTX_GL_ALPHATEST))) { - gaw_enable(GAW_ALPHA_TEST); - gaw_alpha_func(GAW_GREATER, aref); - } else { - gaw_disable(GAW_ALPHA_TEST); +static void gui_blit(int x, int y, rtk_icon *icon) +{ + int i, j; + uint32_t *dest, *src; + + dest = framebuf + y * win_width + x; + src = icon->pixels; + + for(i=0; iheight; i++) { + for(j=0; jwidth; j++) { + int r = src[j] & 0xff; + int g = (src[j] >> 8) & 0xff; + int b = (src[j] >> 16) & 0xff; + dest[j] = 0xff000000 | (r << 16) | (g << 8) | b; + } + dest += win_width; + src += icon->scanlen; } +} - gaw_set_tex2d(tex->texid); +static void gui_drawtext(int x, int y, const char *str) +{ +} - gaw_begin(GAW_TRIANGLES); - for(i=0; is, v->t); - gaw_vertex2f(v->x, v->y); - v++; - } - gaw_end(); +static void gui_textrect(const char *str, rtk_rect *rect) +{ + rect->x = rect->y = 0; + rect->width = 20; + rect->height = 10;/* TODO */ +} - gaw_restore(); - gaw_set_tex2d(0); - */ +static void txdraw(struct dtx_vertex *v, int vcount, struct dtx_pixmap *pixmap, void *cls) +{ } diff --git a/src/app.h b/src/app.h index c74bd02..96e6659 100644 --- a/src/app.h +++ b/src/app.h @@ -18,6 +18,9 @@ along with this program. If not, see . #ifndef APP_H_ #define APP_H_ +#include "sizeint.h" +#include "logger.h" + enum { KEY_ESC = 27, KEY_DEL = 127, @@ -67,6 +70,9 @@ extern struct app_screen scr_model, scr_rend; struct font; extern struct font *uifont; +extern uint32_t *framebuf; + + int app_init(void); void app_shutdown(void); diff --git a/src/gaw/gaw.h b/src/gaw/gaw.h index 37d5ca0..c43b648 100644 --- a/src/gaw/gaw.h +++ b/src/gaw/gaw.h @@ -1,5 +1,5 @@ /* -Deep Runner - 6dof shooter game for the SGI O2. +RetroRay - integrated standalone vintage modeller/renderer Copyright (C) 2023 John Tsiombikas This program is free software: you can redistribute it and/or modify @@ -144,6 +144,7 @@ void gaw_texcoord1f(float u); void gaw_texcoord2f(float u, float v); void gaw_vertex2f(float x, float y); void gaw_vertex3f(float x, float y, float z); +void gaw_vertex4f(float x, float y, float z, float w); void gaw_rect(float x1, float y1, float x2, float y2); diff --git a/src/gaw/gaw_gl.c b/src/gaw/gaw_gl.c index 7a58c1d..40f870c 100644 --- a/src/gaw/gaw_gl.c +++ b/src/gaw/gaw_gl.c @@ -1,5 +1,5 @@ /* -Deep Runner - 6dof shooter game for the SGI O2. +RetroRay - integrated standalone vintage modeller/renderer Copyright (C) 2023 John Tsiombikas This program is free software: you can redistribute it and/or modify @@ -389,6 +389,11 @@ void gaw_vertex3f(float x, float y, float z) glVertex3f(x, y, z); } +void gaw_vertex4f(float x, float y, float z, float w) +{ + glVertex4f(x, y, z, w); +} + void gaw_rect(float x1, float y1, float x2, float y2) { glRectf(x1, y1, x2, y2); diff --git a/src/gaw/gaw_glide.c b/src/gaw/gaw_glide.c index 516570c..6fe8ccc 100644 --- a/src/gaw/gaw_glide.c +++ b/src/gaw/gaw_glide.c @@ -1,5 +1,5 @@ /* -Deep Runner - 6dof shooter game for the SGI O2. +RetroRay - integrated standalone vintage modeller/renderer Copyright (C) 2023 John Tsiombikas This program is free software: you can redistribute it and/or modify diff --git a/src/gaw/gaw_glide.h b/src/gaw/gaw_glide.h index 0bb3d1f..66b1a62 100644 --- a/src/gaw/gaw_glide.h +++ b/src/gaw/gaw_glide.h @@ -1,5 +1,5 @@ /* -Deep Runner - 6dof shooter game for the SGI O2. +RetroRay - integrated standalone vintage modeller/renderer Copyright (C) 2023 John Tsiombikas This program is free software: you can redistribute it and/or modify diff --git a/src/gaw/gaw_sw.c b/src/gaw/gaw_sw.c index de96cab..3df97f3 100644 --- a/src/gaw/gaw_sw.c +++ b/src/gaw/gaw_sw.c @@ -1,5 +1,5 @@ /* -Deep Runner - 6dof shooter game for the SGI O2. +RetroRay - integrated standalone vintage modeller/renderer Copyright (C) 2023 John Tsiombikas This program is free software: you can redistribute it and/or modify diff --git a/src/gaw/gawswtnl.c b/src/gaw/gawswtnl.c index 2df3ed3..5278754 100644 --- a/src/gaw/gawswtnl.c +++ b/src/gaw/gawswtnl.c @@ -1,5 +1,5 @@ /* -Deep Runner - 6dof shooter game for the SGI O2. +RetroRay - integrated standalone vintage modeller/renderer Copyright (C) 2023 John Tsiombikas This program is free software: you can redistribute it and/or modify @@ -617,18 +617,22 @@ void gaw_texcoord2f(float u, float v) void gaw_vertex2f(float x, float y) { - gaw_vertex3f(x, y, 0); + gaw_vertex4f(x, y, 0, 1); } void gaw_vertex3f(float x, float y, float z) { + gaw_vertex4f(x, y, z, 1); + +void gaw_vertex4f(float x, float y, float z, float w) +{ float *cptr = st.imm_cbuf + st.imm_numv * 4; struct vertex *vptr = st.imm_vbuf + st.imm_numv++; *vptr = st.imm_curv; vptr->x = x; vptr->y = y; vptr->z = z; - vptr->w = 1.0f; + vptr->w = w; cptr[0] = st.imm_curcol[0]; cptr[1] = st.imm_curcol[1]; diff --git a/src/gaw/gawswtnl.h b/src/gaw/gawswtnl.h index 952f92c..7510f16 100644 --- a/src/gaw/gawswtnl.h +++ b/src/gaw/gawswtnl.h @@ -1,5 +1,5 @@ /* -Deep Runner - 6dof shooter game for the SGI O2. +RetroRay - integrated standalone vintage modeller/renderer Copyright (C) 2023 John Tsiombikas This program is free software: you can redistribute it and/or modify diff --git a/src/gaw/polyclip.c b/src/gaw/polyclip.c index 4a203a8..e21051c 100644 --- a/src/gaw/polyclip.c +++ b/src/gaw/polyclip.c @@ -1,3 +1,20 @@ +/* +RetroRay - integrated standalone vintage modeller/renderer +Copyright (C) 2023 John Tsiombikas + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ #include #include #include diff --git a/src/gaw/polyclip.h b/src/gaw/polyclip.h index e6c38fa..29e5ba2 100644 --- a/src/gaw/polyclip.h +++ b/src/gaw/polyclip.h @@ -1,3 +1,20 @@ +/* +RetroRay - integrated standalone vintage modeller/renderer +Copyright (C) 2023 John Tsiombikas + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ #ifndef POLYCLIP_H_ #define POLYCLIP_H_ diff --git a/src/gaw/polyfill.c b/src/gaw/polyfill.c index 250c152..efdee71 100644 --- a/src/gaw/polyfill.c +++ b/src/gaw/polyfill.c @@ -1,3 +1,20 @@ +/* +RetroRay - integrated standalone vintage modeller/renderer +Copyright (C) 2023 John Tsiombikas + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ #include #include #include diff --git a/src/gaw/polyfill.h b/src/gaw/polyfill.h index ad2d5b3..b9173bc 100644 --- a/src/gaw/polyfill.h +++ b/src/gaw/polyfill.h @@ -1,3 +1,20 @@ +/* +RetroRay - integrated standalone vintage modeller/renderer +Copyright (C) 2023 John Tsiombikas + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ #ifndef POLYFILL_H_ #define POLYFILL_H_ diff --git a/src/gaw/polytmpl.h b/src/gaw/polytmpl.h index 88be705..14e9b0f 100644 --- a/src/gaw/polytmpl.h +++ b/src/gaw/polytmpl.h @@ -1,3 +1,20 @@ +/* +RetroRay - integrated standalone vintage modeller/renderer +Copyright (C) 2023 John Tsiombikas + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ #ifdef _MSC_VER #pragma warning (disable: 4101) #endif diff --git a/src/logger.c b/src/logger.c new file mode 100644 index 0000000..00d88b4 --- /dev/null +++ b/src/logger.c @@ -0,0 +1,320 @@ +/* +RetroRay - integrated standalone vintage modeller/renderer +Copyright (C) 2023 John Tsiombikas + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include +#include +#include +#include "logger.h" + +#if defined(__MSDOS__) || defined(MSDOS) +static int setup_serial(int sdev); +#else +#define USE_STD +#endif + +enum { LOG_FILE, LOG_STREAM, LOG_CON, LOG_CB }; +enum { LOG_DBG, LOG_INFO, LOG_WARN, LOG_ERR }; + +struct log_callback { + void (*func)(const char*, void*); + void *cls; +}; + +struct log_output { + int type, level; + union { + FILE *fp; + int con; + struct log_callback cb; + } out; +}; + +#define MAX_OUTPUTS 8 +static struct log_output outputs[MAX_OUTPUTS]; +static int num_outputs; + +void init_logger(void) +{ + num_outputs = 0; +} + +void cleanup_logger(void) +{ + int i; + + for(i=0; i= MAX_OUTPUTS) { + return -1; + } + if(!(fp = fopen(fname, "w"))) { + return -1; + } + idx = num_outputs++; + + outputs[idx].type = LOG_FILE; + outputs[idx].out.fp = fp; + return 0; +} + +int add_log_stream(FILE *fp) +{ + int idx; + + if(num_outputs >= MAX_OUTPUTS) { + return -1; + } + idx = num_outputs++; + + outputs[idx].type = LOG_STREAM; + outputs[idx].out.fp = fp; + return 0; +} + +int add_log_console(const char *devname) +{ +#if defined(MSDOS) || defined(__MSDOS__) + int i, comport; + if(sscanf(devname, "COM%d", &comport) != 1 || comport < 1 || comport > 2) { + return -1; + } + comport--; + + if(num_outputs >= MAX_OUTPUTS) { + return -1; + } + for(i=0; i= MAX_OUTPUTS) { + return -1; + } + idx = num_outputs++; + + outputs[idx].type = LOG_CB; + outputs[idx].out.cb.func = cbfunc; + outputs[idx].out.cb.cls = cls; + return 0; +} + +#if defined(__WATCOMC__) +#ifndef vsnprintf +#define vsnprintf _vsnprintf +#endif +#endif + +static void logmsg(int type, const char *fmt, va_list ap) +{ + static char *buf; + static int bufsz; + int i, ret, newsz; + char *tmp; + + while((ret = vsnprintf(buf, bufsz, fmt, ap)) > bufsz || ret < 0) { + if(ret > bufsz) { + newsz = ret + 1; + } else { + newsz = bufsz ? bufsz * 2 : 256; + } + if(!(tmp = realloc(buf, newsz))) { + if(buf) { + buf[bufsz - 1] = 0; + } + break; + } + buf = tmp; + bufsz = newsz; + } + + if(!buf) return; + + for(i=0; i 1) { + return -1; + } + iobase = sdev == 0 ? UART1_BASE : UART2_BASE; + + /* set clock divisor */ + outp(iobase | UART_LCTL, LCTL_DLAB); + outp(iobase | UART_DIVLO, DIV_9600 & 0xff); + outp(iobase | UART_DIVHI, DIV_9600 >> 8); + /* set format 8n1 */ + outp(iobase | UART_LCTL, LCTL_8N1); + /* assert RTS and DTR */ + outp(iobase | UART_MCTL, MCTL_DTR_RTS_OUT2); + return 0; +} + +void ser_putchar(int c) +{ + if(c == '\n') { + ser_putchar('\r'); + } + + while((inp(iobase | UART_LSTAT) & LST_TRIG_EMPTY) == 0); + outp(iobase | UART_DATA, c); +} + +void ser_puts(const char *s) +{ + while(*s) { + ser_putchar(*s++); + } +} + +void ser_printf(const char *fmt, ...) +{ + va_list ap; + char buf[512]; + + va_start(ap, fmt); + vsprintf(buf, fmt, ap); + va_end(ap); + + ser_puts(buf); +} +#endif diff --git a/src/logger.h b/src/logger.h new file mode 100644 index 0000000..29522da --- /dev/null +++ b/src/logger.h @@ -0,0 +1,42 @@ +/* +RetroRay - integrated standalone vintage modeller/renderer +Copyright (C) 2023 John Tsiombikas + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef LOGGER_H_ +#define LOGGER_H_ + +#include +#include + +void init_logger(void); +void cleanup_logger(void); + +int add_log_file(const char *fname); +int add_log_stream(FILE *fp); +int add_log_console(const char *devname); +int add_log_callback(void (*cbfunc)(const char*, void*), void *cls); + +void errormsg(const char *fmt, ...); +void warnmsg(const char *fmt, ...); +void infomsg(const char *fmt, ...); +void dbgmsg(const char *fmt, ...); + +void verrormsg(const char *fmt, va_list ap); +void vwarnmsg(const char *fmt, va_list ap); +void vinfomsg(const char *fmt, va_list ap); +void vdbgmsg(const char *fmt, va_list ap); + +#endif /* LOGGER_H_ */ diff --git a/src/modern/main.c b/src/modern/main.c index e511b65..066c431 100644 --- a/src/modern/main.c +++ b/src/modern/main.c @@ -99,6 +99,23 @@ void app_redisplay(void) void app_swap_buffers(void) { + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glRasterPos2i(-1, 1); + glPixelZoom(1, -1); + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_GREATER, 0.5f); + glDrawPixels(win_width, win_height, GL_BGRA, GL_UNSIGNED_BYTE, framebuf); + glDisable(GL_ALPHA_TEST); + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glutSwapBuffers(); assert(glGetError() == GL_NO_ERROR); } diff --git a/src/rtk.c b/src/rtk.c index 43de80d..abd4244 100644 --- a/src/rtk.c +++ b/src/rtk.c @@ -6,6 +6,10 @@ static rtk_draw_ops gfx; static void calc_widget_rect(rtk_widget *w, rtk_rect *rect); +static void draw_window(rtk_widget *w); +static void draw_button(rtk_widget *w); +static void draw_checkbox(rtk_widget *w); +static void draw_separator(rtk_widget *w); void rtk_setup(rtk_draw_ops *drawop) { @@ -189,8 +193,13 @@ int rtk_win_has(rtk_widget *par, rtk_widget *child) void rtk_bn_set_icon(rtk_widget *w, rtk_icon *icon) { + rtk_rect rect; + RTK_ASSERT_TYPE(w, RTK_BUTTON); w->bn.icon = icon; + + calc_widget_rect(w, &rect); + rtk_resize(w, rect.width, rect.height); } rtk_icon *rtk_bn_get_icon(rtk_widget *w) @@ -208,6 +217,7 @@ rtk_widget *rtk_create_window(rtk_widget *par, const char *title, int x, int y, if(!(w = rtk_create_widget())) { return 0; } + w->type = RTK_WIN; if(par) rtk_win_add(par, w); rtk_set_text(w, title); rtk_move(w, x, y); @@ -222,6 +232,7 @@ rtk_widget *rtk_create_button(rtk_widget *par, const char *str, rtk_callback cbf if(!(w = rtk_create_widget())) { return 0; } + w->type = RTK_BUTTON; if(par) rtk_win_add(par, w); rtk_set_text(w, str); rtk_set_callback(w, cbfunc, 0); @@ -235,6 +246,7 @@ rtk_widget *rtk_create_iconbutton(rtk_widget *par, rtk_icon *icon, rtk_callback if(!(w = rtk_create_widget())) { return 0; } + w->type = RTK_BUTTON; if(par) rtk_win_add(par, w); rtk_bn_set_icon(w, icon); rtk_set_callback(w, cbfunc, 0); @@ -248,6 +260,7 @@ rtk_widget *rtk_create_label(rtk_widget *par, const char *text) if(!(w = rtk_create_widget())) { return 0; } + w->type = RTK_LABEL; if(par) rtk_win_add(par, w); rtk_set_text(w, text); return w; @@ -260,6 +273,7 @@ rtk_widget *rtk_create_checkbox(rtk_widget *par, const char *text, int chk, rtk_ if(!(w = rtk_create_widget())) { return 0; } + w->type = RTK_CHECKBOX; if(par) rtk_win_add(par, w); rtk_set_text(w, text); rtk_set_value(w, chk ? 1 : 0); @@ -267,6 +281,19 @@ rtk_widget *rtk_create_checkbox(rtk_widget *par, const char *text, int chk, rtk_ return w; } +rtk_widget *rtk_create_separator(rtk_widget *par) +{ + rtk_widget *w; + + if(!(w = rtk_create_widget())) { + return 0; + } + w->type = RTK_SEP; + if(par) rtk_win_add(par, w); + return w; +} + + /* --- icon functions --- */ rtk_iconsheet *rtk_load_iconsheet(const char *fname) { @@ -354,6 +381,18 @@ static void calc_widget_rect(rtk_widget *w, rtk_rect *rect) rect->height = txrect.height + PAD * 2; break; + case RTK_SEP: + if(w->any.par->win.layout == RTK_VBOX) { + rect->width = w->any.par->any.width - PAD * 2; + rect->height = (PAD + BEVELSZ) * 2; + } else if(w->any.par->win.layout == RTK_HBOX) { + rect->width = (PAD + BEVELSZ) * 2; + rect->height = w->any.par->any.height - PAD * 2; + } else { + rect->width = rect->height = 0; + } + break; + default: rect->width = rect->height = 0; } @@ -405,10 +444,6 @@ static void calc_layout(rtk_widget *w) w->any.flags = (w->any.flags & ~GEOMCHG) | DIRTY; } -static void draw_window(rtk_widget *w); -static void draw_button(rtk_widget *w); -static void draw_checkbox(rtk_widget *w); - void rtk_draw_widget(rtk_widget *w) { if(need_relayout(w)) { @@ -428,6 +463,10 @@ void rtk_draw_widget(rtk_widget *w) draw_checkbox(w); break; + case RTK_SEP: + draw_separator(w); + break; + default: break; } @@ -460,17 +499,72 @@ static void abs_pos(rtk_widget *w, int *xpos, int *ypos) *ypos = y; } -#define COL_BG 0xa0a0a0 -#define COL_LBEV 0xcccccc -#define COL_SBEV 0x202020 -#define COL_TEXT 0 +#define COL_BG 0xff666666 +#define COL_LBEV 0xffaaaaaa +#define COL_SBEV 0xff333333 +#define COL_TEXT 0xff000000 + +static void hline(int x, int y, int sz, uint32_t col) +{ + rtk_rect rect; + rect.x = x; + rect.y = y; + rect.width = sz; + rect.height = 1; + gfx.fill(&rect, col); +} + +static void vline(int x, int y, int sz, uint32_t col) +{ + rtk_rect rect; + rect.x = x; + rect.y = y; + rect.width = 1; + rect.height = sz; + gfx.fill(&rect, col); +} + +enum {FRM_SOLID, FRM_OUTSET, FRM_INSET}; + +static void draw_frame(rtk_rect *rect, int type) +{ + int tlcol, brcol; + + switch(type) { + case FRM_SOLID: + tlcol = brcol = 0xff000000; + break; + case FRM_OUTSET: + tlcol = COL_LBEV; + brcol = COL_SBEV; + break; + case FRM_INSET: + tlcol = COL_SBEV; + brcol = COL_LBEV; + break; + default: + break; + } + + hline(rect->x, rect->y, rect->width, tlcol); + vline(rect->x, rect->y + 1, rect->height - 2, tlcol); + hline(rect->x, rect->y + rect->height - 1, rect->width, brcol); + vline(rect->x + rect->width - 1, rect->y + 1, rect->height - 2, brcol); +} static void draw_window(rtk_widget *w) { rtk_rect rect; + rtk_widget *c; widget_rect(w, &rect); gfx.fill(&rect, COL_BG); + + c = w->win.clist; + while(c) { + rtk_draw_widget(c); + c = c->any.next; + } } static void draw_button(rtk_widget *w) @@ -480,14 +574,34 @@ static void draw_button(rtk_widget *w) widget_rect(w, &rect); abs_pos(w, &rect.x, &rect.y); + if(rect.width > 2 && rect.height > 2) { + draw_frame(&rect, FRM_OUTSET); + + rect.x++; + rect.y++; + rect.width -= 2; + rect.height -= 2; + } + gfx.fill(&rect, COL_BG); if(w->bn.icon) { gfx.blit(rect.x + OFFS, rect.y + OFFS, w->bn.icon); } else { - gfx.fill(&rect, 0x802020); + gfx.fill(&rect, 0xff802020); } } static void draw_checkbox(rtk_widget *w) { } + +static void draw_separator(rtk_widget *w) +{ + rtk_widget *win = w->any.par; + rtk_rect rect; + + widget_rect(w, &rect); + abs_pos(w, &rect.x, &rect.y); + + draw_frame(&rect, FRM_INSET); +} diff --git a/src/rtk.h b/src/rtk.h index 58cccad..15b6c79 100644 --- a/src/rtk.h +++ b/src/rtk.h @@ -2,7 +2,7 @@ #define RTK_H_ /* widget type */ -enum { RTK_ANY, RTK_WIN, RTK_BUTTON, RTK_LABEL, RTK_CHECKBOX, RTK_SLIDER }; +enum { RTK_ANY, RTK_WIN, RTK_BUTTON, RTK_LABEL, RTK_CHECKBOX, RTK_SLIDER, RTK_SEP }; /* window layout */ enum { RTK_NONE, RTK_VBOX, RTK_HBOX }; @@ -14,6 +14,15 @@ typedef struct rtk_rect { int x, y, width, height; } rtk_rect; +typedef struct rtk_icon { + char *name; + int width, height, scanlen; + uint32_t *pixels; + + struct rtk_icon *next; +} rtk_icon; + + typedef struct rtk_draw_ops { void (*fill)(rtk_rect *rect, uint32_t color); void (*blit)(int x, int y, rtk_icon *icon); @@ -32,6 +41,7 @@ rtk_widget *rtk_create_widget(void); void rtk_free_widget(rtk_widget *w); int rtk_type(rtk_widget *w); +rtk_widget *rtk_parent(rtk_widget *w); void rtk_move(rtk_widget *w, int x, int y); void rtk_pos(rtk_widget *w, int *xptr, int *yptr); @@ -62,12 +72,14 @@ rtk_widget *rtk_create_button(rtk_widget *par, const char *str, rtk_callback cbf rtk_widget *rtk_create_iconbutton(rtk_widget *par, rtk_icon *icon, rtk_callback cbfunc); rtk_widget *rtk_create_label(rtk_widget *par, const char *text); rtk_widget *rtk_create_checkbox(rtk_widget *par, const char *text, int chk, rtk_callback cbfunc); +rtk_widget *rtk_create_separator(rtk_widget *par); /* icon functions */ rtk_iconsheet *rtk_load_iconsheet(const char *fname); void rtk_free_iconsheet(rtk_iconsheet *is); rtk_icon *rtk_define_icon(rtk_iconsheet *is, const char *name, int x, int y, int w, int h); +rtk_icon *rtk_lookup_icon(rtk_iconsheet *is, const char *name); void rtk_draw_widget(rtk_widget *w); diff --git a/src/rtk_impl.h b/src/rtk_impl.h index d9ee120..9afa913 100644 --- a/src/rtk_impl.h +++ b/src/rtk_impl.h @@ -41,14 +41,6 @@ typedef union rtk_widget { rtk_button bn; } rtk_widget; -typedef struct rtk_icon { - char *name; - int width, height, scanlen; - uint32_t *pixels; - - struct rtk_icon *next; -} rtk_icon; - typedef struct rtk_iconsheet { int width, height; uint32_t *pixels; diff --git a/src/scr_mod.c b/src/scr_mod.c index 189e271..29ce348 100644 --- a/src/scr_mod.c +++ b/src/scr_mod.c @@ -17,6 +17,32 @@ along with this program. If not, see . */ #include "gaw/gaw.h" #include "app.h" +#include "rtk.h" + +enum { + TBN_NEW, TBN_OPEN, TBN_SAVE, TBN_SEP1, + TBN_SEL, TBN_MOVE, TBL_ROT, TBN_SCALE, TBN_SEP2, + TBL_ADD, TBL_RM, TBN_SEP3, + TBN_MTL, TBN_REND, TBL_VIEWREND, TBN_SEP4, TBL_CFG, + + NUM_TOOL_BUTTONS +}; +static const char *tbn_icon_name[] = { + "new", "open", "save", 0, + "sel", "move", "rot", "scale", 0, + "add", "remove", 0, + "mtl", "rend", "viewrend", 0, "cfg" +}; +static int tbn_icon_pos[][2] = { + {0,0}, {16,0}, {32,0}, {-1,-1}, + {48,0}, {64,0}, {80,0}, {96,0}, {-1,-1}, + {112,0}, {112,16}, {-1,-1}, + {48,16}, {64,16}, {80,16}, {-1,-1}, {96,16} +}; +static rtk_icon *tbn_icons[NUM_TOOL_BUTTONS]; + +#define TOOLBAR_HEIGHT 26 + static int mdl_init(void); static void mdl_destroy(void); @@ -28,6 +54,8 @@ static void mdl_keyb(int key, int press); static void mdl_mouse(int bn, int press, int x, int y); static void mdl_motion(int x, int y); +static void draw_grid(void); + struct app_screen scr_model = { "modeller", @@ -37,18 +65,53 @@ struct app_screen scr_model = { mdl_keyb, mdl_mouse, mdl_motion }; +static rtk_widget *toolbar; +static rtk_iconsheet *icons; + +static float cam_theta, cam_phi = 20, cam_dist = 8; + static int mdl_init(void) { + int i; + rtk_widget *w; + + if(!(icons = rtk_load_iconsheet("data/icons.png"))) { + errormsg("failed to load iconsheet\n"); + return -1; + } + for(i=0; i 90) cam_phi = 90; + app_redisplay(); + } + + if(mouse_state[2]) { + cam_dist += dy * 0.1f; + if(cam_dist < 0) cam_dist = 0; + app_redisplay(); + } } -- 1.7.10.4