src/dos/drv_s3.obj
appobj = src/app.obj src/cmesh.obj src/darray.obj src/font.obj src/logger.obj &
src/meshgen.obj src/meshload.obj src/options.obj src/rbtree.obj src/geom.obj &
- src/rend.obj src/rtk.obj src/scene.obj src/scr_mod.obj src/scr_rend.obj &
- src/texture.obj src/material.obj &
+ src/rend.obj src/rtk.obj src/scene.obj src/scr_mod.obj src/modui.obj &
+ src/scr_rend.obj src/texture.obj src/material.obj &
src/util.obj src/util_s.obj src/cpuid.obj src/cpuid_s.obj
gawobj = src/gaw/gaw_sw.obj src/gaw/gawswtnl.obj src/gaw/polyclip.obj src/gaw/polyfill.obj
src\dos\drv_s3.obj
appobj = src\app.obj src\cmesh.obj src\darray.obj src\font.obj src\logger.obj &
src\meshgen.obj src\meshload.obj src\options.obj src\rbtree.obj src\geom.obj &
- src\rend.obj src\rtk.obj src\scene.obj src\scr_mod.obj src\scr_rend.obj &
- src\texture.obj src\material.obj &
+ src\rend.obj src\rtk.obj src\scene.obj src\scr_mod.obj src\modui.obj &
+ src\scr_rend.obj src\texture.obj src\material.obj &
src\util.obj src\util_s.obj src\cpuid.obj src\cpuid_s.obj
gawobj = src\gaw\gaw_sw.obj src\gaw\gawswtnl.obj src\gaw\polyclip.obj src\gaw\polyfill.obj
--- /dev/null
+/*
+RetroRay - integrated standalone vintage modeller/renderer
+Copyright (C) 2023 John Tsiombikas <nuclear@mutantstargoat.com>
+
+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 <https://www.gnu.org/licenses/>.
+*/
+#include <assert.h>
+#include "modui.h"
+#include "app.h"
+#include "rtk.h"
+
+static const char *tbn_icon_name[] = {
+ "new", "open", "save", 0,
+ "sel", "move", "rot", "scale", 0,
+ "add", "remove", 0,
+ "union", "isect", "diff", 0,
+ "mtl", "rend", "rend-area", "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},
+ {0,16}, {16,16}, {32,16}, {-1,-1},
+ {48,16}, {64,16}, {64, 32}, {80,16}, {-1,-1}, {96,16}
+};
+static int tbn_istool[] = {
+ 0, 0, 0, 0,
+ 1, 1, 1, 1, 0,
+ 0, 0, 0,
+ 1, 1, 1, 0,
+ 0, 0, 1, 0, 0, 0
+};
+static rtk_icon *tbn_icons[NUM_TOOL_BUTTONS];
+static rtk_widget *tbn_buttons[NUM_TOOL_BUTTONS];
+static rtk_iconsheet *icons;
+
+rtk_widget *toolbar, *mtlwin;
+rtk_widget *tools[NUM_TOOLS];
+
+static int create_toolbar(void);
+static int create_mtlwin(void);
+
+int modui_init(void)
+{
+ if(!(icons = rtk_load_iconsheet("data/icons.png"))) {
+ errormsg("failed to load iconsheet\n");
+ return -1;
+ }
+
+ if(create_toolbar() == -1) {
+ return -1;
+ }
+ if(create_mtlwin() == -1) {
+ return -1;
+ }
+ return 0;
+}
+
+static int create_toolbar(void)
+{
+ int i, toolidx;
+ rtk_widget *w;
+
+ for(i=0; i<NUM_TOOL_BUTTONS; i++) {
+ if(tbn_icon_name[i]) {
+ tbn_icons[i] = rtk_define_icon(icons, tbn_icon_name[i],
+ tbn_icon_pos[i][0], tbn_icon_pos[i][1], 16, 16);
+ } else {
+ tbn_icons[i] = 0;
+ }
+ }
+
+ if(!(toolbar = rtk_create_window(0, "toolbar", 0, 0, win_width, TOOLBAR_HEIGHT, 0))) {
+ return -1;
+ }
+ rtk_win_layout(toolbar, RTK_HBOX);
+
+ toolidx = 0;
+ for(i=0; i<NUM_TOOL_BUTTONS; i++) {
+ if(!tbn_icons[i]) {
+ rtk_create_separator(toolbar);
+ } else {
+ if(!(w = rtk_create_iconbutton(toolbar, tbn_icons[i], 0))) {
+ return -1;
+ }
+ tbn_buttons[i] = w;
+ rtk_set_callback(w, tbn_callback, (void*)(intptr_t)i);
+ if(tbn_istool[i]) {
+ rtk_bn_mode(w, RTK_TOGGLEBN);
+ tools[toolidx++] = w;
+ }
+ if(i == TBN_SEL) {
+ rtk_set_value(w, 1);
+ }
+ }
+ }
+ assert(toolidx == NUM_TOOLS);
+
+ return 0;
+}
+
+static int create_mtlwin(void)
+{
+ if(!(mtlwin = rtk_create_window(0, "Materials", win_width / 2, 64, 256, 380,
+ RTK_WIN_FRAME | RTK_WIN_MOVABLE | RTK_WIN_RESIZABLE))) {
+ return -1;
+ }
+
+ return 0;
+}
+
+void modui_cleanup(void)
+{
+ rtk_free_widget(toolbar);
+ rtk_free_widget(mtlwin);
+ rtk_free_iconsheet(icons);
+}
--- /dev/null
+#ifndef MODUI_H_
+#define MODUI_H_
+
+#include "rtk.h"
+
+#define TOOLBAR_HEIGHT 26
+
+/* tools */
+enum {
+ TOOL_SEL, TOOL_MOVE, TOOL_ROT, TOOL_SCALE,
+ TOOL_UNION, TOOL_ISECT, TOOL_DIFF, TOOL_REND_AREA,
+ NUM_TOOLS
+};
+
+/* toolbar buttons */
+enum {
+ TBN_NEW, TBN_OPEN, TBN_SAVE, TBN_SEP1,
+ TBN_SEL, TBN_MOVE, TBN_ROT, TBN_SCALE, TBN_SEP2,
+ TBN_ADD, TBN_RM, TBN_SEP3,
+ TBN_UNION, TBN_ISECT, TBN_DIFF, TBN_SEP4,
+ TBN_MTL, TBN_REND, TBN_REND_AREA, TBN_VIEWREND, TBN_SEP5, TBN_CFG,
+
+ NUM_TOOL_BUTTONS
+};
+
+
+extern rtk_widget *toolbar, *mtlwin;
+extern rtk_widget *tools[NUM_TOOLS];
+
+int modui_init(void);
+void modui_cleanup(void);
+
+void tbn_callback(rtk_widget *w, void *cls);
+
+#endif /* MODUI_H_ */
w->any.cbcls = cls;
}
+void rtk_show(rtk_widget *w)
+{
+ w->any.flags |= VISIBLE;
+ rtk_invalidate(w);
+}
+
+void rtk_hide(rtk_widget *w)
+{
+ w->any.flags &= ~VISIBLE;
+ invalfb(w);
+}
+
+int rtk_visible(const rtk_widget *w)
+{
+ return w->any.flags & VISIBLE;
+}
+
void rtk_invalidate(rtk_widget *w)
{
w->any.flags |= DIRTY;
/* --- constructors --- */
-rtk_widget *rtk_create_window(rtk_widget *par, const char *title, int x, int y, int width, int height)
+rtk_widget *rtk_create_window(rtk_widget *par, const char *title, int x, int y,
+ int width, int height, unsigned int flags)
{
rtk_widget *w;
rtk_set_text(w, title);
rtk_move(w, x, y);
rtk_resize(w, width, height);
+
+ w->any.flags |= flags << 16;
return w;
}
{
int dirty;
+ if(!(w->any.flags & VISIBLE)) {
+ return;
+ }
+
if(need_relayout(w)) {
calc_layout(w);
}
#define COL_LBEV 0xffaaaaaa
#define COL_SBEV 0xff222222
#define COL_TEXT 0xff000000
+#define COL_WINFRM 0xff2244aa
+#define COL_WINFRM_LIT 0xff4466ff
+#define COL_WINFRM_SHAD 0xff051166
static void hline(int x, int y, int sz, uint32_t col)
{
enum {FRM_SOLID, FRM_OUTSET, FRM_INSET};
+enum {UICOL_BG, UICOL_LBEV, UICOL_SBEV};
+static uint32_t uicol[3];
+
+static void uicolor(uint32_t col, uint32_t lcol, uint32_t scol)
+{
+ uicol[UICOL_BG] = col;
+ uicol[UICOL_LBEV] = lcol;
+ uicol[UICOL_SBEV] = scol;
+}
+
static void draw_frame(rtk_rect *rect, int type)
{
int tlcol, brcol;
tlcol = brcol = 0xff000000;
break;
case FRM_OUTSET:
- tlcol = COL_LBEV;
- brcol = COL_SBEV;
+ tlcol = uicol[UICOL_LBEV];
+ brcol = uicol[UICOL_SBEV];
break;
case FRM_INSET:
- tlcol = COL_SBEV;
- brcol = COL_LBEV;
+ tlcol = uicol[UICOL_SBEV];
+ brcol = uicol[UICOL_LBEV];
break;
default:
break;
vline(rect->x + rect->width - 1, rect->y + 1, rect->height - 2, brcol);
}
+#define WINFRM_SZ 2
+#define WINFRM_TBAR 16
+
static void draw_window(rtk_widget *w)
{
- rtk_rect rect;
+ rtk_rect rect, frmrect, tbrect;
rtk_widget *c;
int win_dirty = w->any.flags & DIRTY;
if(win_dirty) {
widget_rect(w, &rect);
+
+ if(w->any.flags & FRAME) {
+ uicolor(COL_WINFRM, COL_WINFRM_LIT, COL_WINFRM_SHAD);
+
+ frmrect = rect;
+ frmrect.width += WINFRM_SZ * 2;
+ frmrect.height += WINFRM_SZ * 2 + WINFRM_TBAR;
+ frmrect.x -= WINFRM_SZ;
+ frmrect.y -= WINFRM_SZ + WINFRM_TBAR;
+
+ tbrect.x = rect.x;
+ tbrect.y = rect.y - WINFRM_TBAR;
+ tbrect.width = rect.width;
+ tbrect.height = WINFRM_TBAR;
+
+ draw_frame(&frmrect, FRM_OUTSET);
+ frmrect.x++;
+ frmrect.y++;
+ frmrect.width -= 2;
+ frmrect.height -= 2;
+ draw_frame(&frmrect, FRM_INSET);
+
+ draw_frame(&tbrect, FRM_OUTSET);
+ tbrect.x++;
+ tbrect.y++;
+ tbrect.width -= 2;
+ tbrect.height -= 2;
+ gfx.fill(&tbrect, COL_WINFRM);
+ }
+
gfx.fill(&rect, COL_BG);
}
pressed = w->any.flags & PRESS;
}
+ uicolor(COL_BG, COL_LBEV, COL_SBEV);
+
if(rect.width > 2 && rect.height > 2) {
draw_frame(&rect, pressed ? FRM_INSET : FRM_OUTSET);
if(!win) return;
+ uicolor(COL_BG, COL_LBEV, COL_SBEV);
+
widget_rect(w, &rect);
abs_pos(w, &rect.x, &rect.y);
#ifndef RTK_H_
#define RTK_H_
+#include "sizeint.h"
+
/* widget type */
enum {
RTK_ANY,
};
/* window layout */
enum { RTK_NONE, RTK_VBOX, RTK_HBOX };
+/* window flags */
+enum {
+ RTK_WIN_FRAME = 1,
+ RTK_WIN_MOVABLE = 2,
+ RTK_WIN_RESIZABLE = 4
+};
/* button mode */
enum { RTK_PUSHBN, RTK_TOGGLEBN };
void rtk_set_callback(rtk_widget *w, rtk_callback cbfunc, void *cls);
+void rtk_show(rtk_widget *w);
+void rtk_hide(rtk_widget *w);
+int rtk_visible(const rtk_widget *w);
+
void rtk_invalidate(rtk_widget *w);
void rtk_validate(rtk_widget *w);
void rtk_bn_set_icon(rtk_widget *w, rtk_icon *icon);
rtk_icon *rtk_bn_get_icon(rtk_widget *w);
-rtk_widget *rtk_create_window(rtk_widget *par, const char *title, int x, int y, int w, int h);
+rtk_widget *rtk_create_window(rtk_widget *par, const char *title, int x, int y,
+ int width, int height, unsigned int flags);
rtk_widget *rtk_create_button(rtk_widget *par, const char *str, rtk_callback cbfunc);
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);
HOVER = 0x010,
PRESS = 0x020,
GEOMCHG = 0x100,
- DIRTY = 0x200
+ DIRTY = 0x200,
+
+ /* window flags */
+ FRAME = RTK_WIN_FRAME << 16,
+ MOVABLE = RTK_WIN_MOVABLE << 16,
+ RESIZABLE = RTK_WIN_RESIZABLE << 16
};
typedef struct rtk_any {
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-#include <assert.h>
#include "gaw/gaw.h"
#include "app.h"
#include "rtk.h"
#include "meshgen.h"
#include "font.h"
#include "rend.h"
-
-enum {
- TBN_NEW, TBN_OPEN, TBN_SAVE, TBN_SEP1,
- TBN_SEL, TBN_MOVE, TBN_ROT, TBN_SCALE, TBN_SEP2,
- TBN_ADD, TBN_RM, TBN_SEP3,
- TBN_UNION, TBN_ISECT, TBN_DIFF, TBN_SEP4,
- TBN_MTL, TBN_REND, TBN_REND_AREA, TBN_VIEWREND, TBN_SEP5, TBN_CFG,
-
- NUM_TOOL_BUTTONS
-};
-static const char *tbn_icon_name[] = {
- "new", "open", "save", 0,
- "sel", "move", "rot", "scale", 0,
- "add", "remove", 0,
- "union", "isect", "diff", 0,
- "mtl", "rend", "rend-area", "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},
- {0,16}, {16,16}, {32,16}, {-1,-1},
- {48,16}, {64,16}, {64, 32}, {80,16}, {-1,-1}, {96,16}
-};
-static int tbn_istool[] = {
- 0, 0, 0, 0,
- 1, 1, 1, 1, 0,
- 0, 0, 0,
- 1, 1, 1, 0,
- 0, 0, 1, 0, 0, 0
-};
-static rtk_icon *tbn_icons[NUM_TOOL_BUTTONS];
-static rtk_widget *tbn_buttons[NUM_TOOL_BUTTONS];
-
-#define TOOLBAR_HEIGHT 26
-
-enum {
- TOOL_SEL, TOOL_MOVE, TOOL_ROT, TOOL_SCALE,
- TOOL_UNION, TOOL_ISECT, TOOL_DIFF, TOOL_REND_AREA,
- NUM_TOOLS
-};
-static rtk_widget *tools[NUM_TOOLS];
+#include "modui.h"
static int vpdirty;
static rtk_rect totalrend;
static void draw_object(struct object *obj);
static void setup_material(struct material *mtl);
static void draw_grid(void);
-static void tbn_callback(rtk_widget *w, void *cls);
static void act_settool(int tidx);
static void act_addobj(void);
mdl_keyb, mdl_mouse, mdl_motion
};
-static rtk_widget *toolbar;
-static rtk_iconsheet *icons;
static struct cmesh *mesh_sph;
static int mdl_init(void)
{
- int i, toolidx;
- rtk_widget *w;
-
- if(!(icons = rtk_load_iconsheet("data/icons.png"))) {
- errormsg("failed to load iconsheet\n");
+ if(modui_init() == -1) {
+ errormsg("failed to initialize modeller UI\n");
return -1;
}
- for(i=0; i<NUM_TOOL_BUTTONS; i++) {
- if(tbn_icon_name[i]) {
- tbn_icons[i] = rtk_define_icon(icons, tbn_icon_name[i],
- tbn_icon_pos[i][0], tbn_icon_pos[i][1], 16, 16);
- } else {
- tbn_icons[i] = 0;
- }
- }
-
- if(!(toolbar = rtk_create_window(0, "toolbar", 0, 0, win_width, TOOLBAR_HEIGHT))) {
- return -1;
- }
- rtk_win_layout(toolbar, RTK_HBOX);
-
- toolidx = 0;
- for(i=0; i<NUM_TOOL_BUTTONS; i++) {
- if(!tbn_icons[i]) {
- rtk_create_separator(toolbar);
- } else {
- if(!(w = rtk_create_iconbutton(toolbar, tbn_icons[i], 0))) {
- return -1;
- }
- tbn_buttons[i] = w;
- rtk_set_callback(w, tbn_callback, (void*)(intptr_t)i);
- if(tbn_istool[i]) {
- rtk_bn_mode(w, RTK_TOGGLEBN);
- tools[toolidx++] = w;
- }
- if(i == TBN_SEL) {
- rtk_set_value(w, 1);
- }
- }
- }
- assert(toolidx == NUM_TOOLS);
if(!(mesh_sph = cmesh_alloc())) {
errormsg("failed to allocate sphere vis mesh\n");
static void mdl_destroy(void)
{
cmesh_free(mesh_sph);
- rtk_free_iconsheet(icons);
+ modui_cleanup();
}
static int mdl_start(void)
/* dirty all GUI windows */
rtk_invalidate(toolbar);
+ rtk_invalidate(mtlwin);
}
/* render layer */
/* GUI */
rtk_draw_widget(toolbar);
+ rtk_draw_widget(mtlwin);
}
static void draw_object(struct object *obj)
scn_add_object(scn, obj);
}
-static void tbn_callback(rtk_widget *w, void *cls)
+void tbn_callback(rtk_widget *w, void *cls)
{
int id = (intptr_t)cls;
case TBN_DIFF:
act_settool(id - TBN_UNION + TOOL_UNION);
break;
+
+ case TBN_MTL:
+ if(rtk_visible(mtlwin)) {
+ rtk_hide(mtlwin);
+ inval_vport();
+ } else {
+ rtk_show(mtlwin);
+ }
+ break;
+
case TBN_REND_AREA:
act_settool(TOOL_REND_AREA);
break;