int mouse_x, mouse_y, mouse_state[3];
unsigned int modkeys;
-int scr_width, scr_height;
int fullscr;
long time_msec;
char *start_scr_name;
static rtk_draw_ops guigfx = {gui_fill, 0, gui_drawtext, gui_textrect};
+ if(!(framebuf = malloc(SCR_WIDTH * SCR_HEIGHT))) {
+ errormsg("failed to allocate framebuffer (%dx%d)\n", SCR_WIDTH, SCR_HEIGHT);
+ return -1;
+ }
+
rtk_setup(&guigfx);
/* initialize screens */
}
cleanup_logger();
+ free(framebuf);
}
void app_display(void)
cur_scr->display();
}
-void app_reshape(int x, int y)
-{
- int numpix = x * y;
- int prev_numpix = scr_width * scr_height;
-
- if(!framebuf || 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;
- }
-
- scr_width = x;
- scr_height = y;
-
- if(cur_scr && cur_scr->reshape) {
- cur_scr->reshape(x, y);
- }
-
- app_invalidate(0, 0, 0, 0);
-}
-
void app_keyboard(int key, int press)
{
long msec;
return;
}
break;
-
- case '\n':
- case '\r':
- if(modkeys & KEY_MOD_ALT) {
- case KEY_F11:
- app_fullscreen(-1);
- return;
- }
- break;
}
}
if(scr->start && scr->start() == -1) {
return;
}
- if(scr->reshape) {
- scr->reshape(scr_width, scr_height);
- }
if(prev && prev->stop) {
prev->stop();
cur_scr = scr;
}
-void gui_fill(rtk_rect *rect, int color)
+void gui_fill(rtk_rect *rect, uint32_t color)
{
int i, j;
unsigned char *fb;
rect->height += rect->y;
rect->y = 0;
}
- if(rect->x + rect->width >= scr_width) {
- rect->width = scr_width - rect->x;
+ if(rect->x + rect->width >= SCR_WIDTH) {
+ rect->width = SCR_WIDTH - rect->x;
}
- if(rect->y + rect->height >= scr_height) {
- rect->height = scr_height - rect->y;
+ if(rect->y + rect->height >= SCR_HEIGHT) {
+ rect->height = SCR_HEIGHT - rect->y;
}
- fb = framebuf + rect->y * scr_width + rect->x;
+ fb = framebuf + rect->y * SCR_WIDTH + rect->x;
for(i=0; i<rect->height; i++) {
for(j=0; j<rect->width; j++) {
fb[j] = color;
}
- fb += scr_width;
+ fb += SCR_WIDTH;
}
}
#include "logger.h"
#include "rtk.h"
+#define SCR_WIDTH 640
+#define SCR_HEIGHT 480
+
enum {
KEY_BACKSP = 8,
KEY_ESC = 27,
int (*start)(void);
void (*stop)(void);
void (*display)(void);
- void (*reshape)(int, int);
void (*keyboard)(int, int);
void (*mouse)(int, int, int, int);
void (*motion)(int, int);
extern int mouse_x, mouse_y, mouse_state[3];
extern unsigned int modkeys;
-extern int scr_width, scr_height;
extern int fullscr;
extern long time_msec;
void app_chscr(struct app_screen *scr);
-void gui_fill(rtk_rect *rect, int color);
+void gui_fill(rtk_rect *rect, uint32_t color);
void gui_drawtext(int x, int y, const char *str);
void gui_textrect(const char *str, rtk_rect *rect);
void app_invalidate(int x, int y, int w, int h);
void app_swap_buffers(void);
void app_quit(void);
-void app_resize(int x, int y);
-void app_fullscreen(int fs);
+
+void app_setcolor(int idx, int r, int g, int b);
#endif /* APP_H_ */
int i, pixsz, spansz;
unsigned char *dest, *src;
- /*dbgmsg("blit: %d,%d (%dx%d)\n", x, y, w, h);*/
+ dbgmsg("blit: %d,%d (%dx%d)\n", x, y, w, h);
pixsz = (cur_mi->bpp + 7) >> 3;
spansz = w * pixsz;
pixsz = (cur_mi->bpp + 7) >> 3;
spansz = cur_mi->width * pixsz;
+ if(spansz == cur_mi->pitch) {
+ memcpy(vid_vmem, fb, spansz * cur_mi->height);
+ return;
+ }
+
dest = vid_vmem;
src = fb;
-
for(i=0; i<cur_mi->height; i++) {
memcpy(dest, src, spansz);
dest += cur_mi->pitch;
} else {
add_log_file(env);
}
+ } else {
+ add_log_file("menu.log");
}
if(!(use_mouse = have_mouse())) {
return 1;
}
- scr_width = 640;
- scr_height = 480;
- if((vmidx = vid_findmode(scr_width, scr_height, 8)) == -1) {
+ if((vmidx = vid_findmode(SCR_WIDTH, SCR_HEIGHT, 8)) == -1) {
return 1;
}
if(!(vmem = vid_setmode(vmidx))) {
}
app_invalidate(0, 0, 0, 0);
- app_reshape(scr_width, scr_height);
- mx = scr_width / 2;
- my = scr_height / 2;
+ mx = SCR_WIDTH / 2;
+ my = SCR_HEIGHT / 2;
prev_mx = prev_my = -1;
for(;;) {
read_mouse_rel(&mdx, &mdy);
mx += mdx;
if(mx < 0) mx = 0;
- if(mx >= scr_width) mx = scr_width - 1;
+ if(mx >= SCR_WIDTH) mx = SCR_WIDTH - 1;
my += mdy;
if(my < 0) my = 0;
- if(my >= scr_height) my = scr_height - 1;
+ if(my >= SCR_HEIGHT) my = SCR_HEIGHT - 1;
mdx = mx - prev_mx;
mdy = my - prev_my;
if((w | h) == 0) {
r.x = r.y = 0;
- r.width = scr_width;
- r.height = scr_height;
+ r.width = SCR_WIDTH;
+ r.height = SCR_HEIGHT;
} else {
r.x = x;
r.y = y;
vid_vsync();
if(dirty_valid) {
- if(dirty.width < scr_width || dirty.height < scr_height) {
- src = framebuf + dirty.y * scr_width + dirty.x;
- vid_blit8(dirty.x, dirty.y, dirty.width, dirty.height, src, 0);
+ if(dirty.width < SCR_WIDTH || dirty.height < SCR_HEIGHT) {
+ src = framebuf + dirty.y * SCR_WIDTH + dirty.x;
+ vid_blit(dirty.x, dirty.y, dirty.width, dirty.height, src, SCR_WIDTH);
} else {
- vid_blitfb8(framebuf, 0);
+ vid_blitfb(framebuf, SCR_WIDTH);
}
dirty_valid = 0;
}
quit = 1;
}
-void app_resize(int x, int y)
-{
-}
-
-void app_fullscreen(int fs)
-{
-}
-
-void app_vsync(int vsync)
+void app_setcolor(int idx, int r, int g, int b)
{
+ struct vid_color col;
+ col.r = r;
+ col.g = g;
+ col.b = b;
+ vid_setpal(idx, 1, &col);
}
void vid_blit(int x, int y, int w, int h, void *src, int pitch)
{
- if(pitch <= 0) {
- pitch = cur_mode->width << 2;
- }
cur_mode->ops.blit(x, y, w, h, src, pitch);
}
void vid_blitfb(void *fb, int pitch)
{
- if(pitch <= 0) {
- pitch = cur_mode->width << 2;
- }
cur_mode->ops.blitfb(fb, pitch);
}
return;
}
- if(pitch <= 0) {
- pitch = cur_mode->width << 2;
- }
/* XXX */
}
return;
}
- if(pitch <= 0) {
- pitch = cur_mode->width << 2;
- }
-
if(vid_islinear()) {
winleft = INT_MAX;
} else {
+#include <string.h>
#include "app.h"
+#include "rtk.h"
static int menu_init(void);
static void menu_destroy(void);
"menu",
menu_init, menu_destroy,
menu_start, menu_stop,
- menu_display, menu_reshape,
+ menu_display,
menu_keyb, menu_mouse, menu_motion
};
+static rtk_screen *gui;
+
static int menu_init(void)
{
+ rtk_widget *win, *w;
+
+ if(!(gui = rtk_create_screen())) {
+ return -1;
+ }
+ rtk_invalidate_screen(gui);
+
+ if(!(win = rtk_create_window(0, "CD menu", 100, 100, 400, 300, RTK_WIN_FRAME))) {
+ return -1;
+ }
+ rtk_win_layout(win, RTK_NONE);
+ rtk_add_window(gui, win);
+
+ w = rtk_create_button(win, "foo", 0);
+ rtk_autosize(w, RTK_AUTOSZ_NONE);
+ rtk_move(w, 160, 130);
+ rtk_resize(w, 60, 25);
+
return 0;
}
static void menu_destroy(void)
{
+ rtk_free_screen(gui);
}
static int menu_start(void)
{
+ memset(framebuf, 0, SCR_WIDTH * SCR_HEIGHT);
return 0;
}
static void menu_display(void)
{
-}
-
-static void menu_reshape(int x, int y)
-{
+ rtk_draw_screen(gui);
}
static void menu_keyb(int key, int press)
{
+ if(!press) return;
+
+ switch(key) {
+ case 27:
+ app_quit();
+ break;
+ }
}
static void menu_mouse(int bn, int press, int x, int y)
static void on_button_click(rtk_widget *w);
static void on_textbox_key(rtk_widget *w, int key, int press);
-void inval_vport(void); /* scr_mod.c */
-
void rtk_setup(rtk_draw_ops *drawop)
{
void rtk_move(rtk_widget *w, int x, int y)
{
if(!w->par) {
- rtk_clearfb(w);
rtk_invalfb(w);
}
w->x = x;
w->flags |= GEOMCHG | DIRTY;
if(!w->par) {
rtk_invalfb(w);
- inval_vport();
}
}
void rtk_resize(rtk_widget *w, int xsz, int ysz)
{
if(!w->par) {
- rtk_clearfb(w);
rtk_invalfb(w);
}
w->width = xsz;
w->flags |= GEOMCHG | DIRTY;
if(!w->par) {
rtk_invalfb(w);
- inval_vport();
}
}
if(w->scr && w->scr->modal == w) {
w->scr->modal = 0;
}
- rtk_clearfb(w);
rtk_invalfb(w);
- inval_vport();
}
int rtk_visible(const rtk_widget *w)
#include "app.h"
#include "rtk.h"
#include "rtk_impl.h"
+#include "util.h"
rtk_draw_ops rtk_gfx;
#define gfx rtk_gfx
static void widget_rect(rtk_widget *w, rtk_rect *rect);
static void abs_widget_rect(rtk_widget *w, rtk_rect *rect);
static void uicolor(uint32_t col, uint32_t lcol, uint32_t scol);
-static void draw_frame(rtk_rect *rect, int type, int sz);
+static void draw_frame(rtk_rect *rect, int type, int sz, uint32_t bgcol, uint32_t shad, uint32_t lit);
static void draw_window(rtk_widget *w);
static void draw_label(rtk_widget *w);
static void draw_drawbox(rtk_widget *w);
-#define BEVELSZ 1
+#define BEVELSZ 2
#define PAD (w->pad)
#define OFFS (BEVELSZ + PAD)
#define CHKBOXSZ (BEVELSZ * 2 + 8)
#define WINFRM_SZ 2
#define WINFRM_TBAR 16
+enum {
+ COL_BLACK = 240,
+ COL_BG,
+ COL_BGHL,
+ COL_SHAD,
+ COL_LIT,
+ COL_FRM_BG,
+ COL_FRM_SHAD,
+ COL_FRM_LIT,
+ COL_TEXT,
+ COL_FRM_TEXT,
+ COL_WHITE
+};
+
void rtk_init_drawing(void)
{
- const char *s = "QI|9g/";
- rtk_rect r;
-
- gfx.textrect(s, &r);
- fontheight = r.height;
+ app_setcolor(COL_BLACK, 0, 0, 0);
+ app_setcolor(COL_WHITE, 0xff, 0xff, 0xff);
+ app_setcolor(COL_TEXT, 0, 0, 0);
+ app_setcolor(COL_BG, 0x66, 0x66, 0x66);
+ app_setcolor(COL_BGHL, 0x80, 0x80, 0x80);
+ app_setcolor(COL_SHAD, 0x22, 0x22, 0x22);
+ app_setcolor(COL_LIT, 0xaa, 0xaa, 0xaa);
+ app_setcolor(COL_FRM_TEXT, 0xff, 0xff, 0xff);
+ app_setcolor(COL_FRM_BG, 0x6d, 0x2a, 0x83);
+ app_setcolor(COL_FRM_SHAD, 0x49, 0x26, 0x55);
+ app_setcolor(COL_FRM_LIT, 0xa1, 0x34, 0xc5);
}
app_invalidate(rect.x, rect.y, rect.width, rect.height);
}
-void rtk_clearfb(rtk_widget *w)
-{
- rtk_rect rect;
-
- rect.x = w->x;
- rect.y = w->y;
- rect.width = w->width;
- rect.height = w->height;
-
- rtk_abs_pos(w, &rect.x, &rect.y);
-
- if(w->type == RTK_WIN && (w->flags & FRAME)) {
- rect.x -= WINFRM_SZ;
- rect.y -= WINFRM_SZ + WINFRM_TBAR;
- rect.width += WINFRM_SZ * 2;
- rect.height += WINFRM_SZ * 2 + WINFRM_TBAR;
- }
-
- app_clear_rect(rect.x, rect.y, rect.width, rect.height);
-}
-
static int need_relayout(rtk_widget *w)
{
rtk_widget *c;
w->drawcb(w, w->drawcls);
}
- if(w->flags & DBGRECT) {
- rtk_rect r;
- abs_widget_rect(w, &r);
- uicolor(0xffff0000, 0xffff0000, 0xffff0000);
- draw_frame(&r, FRM_SOLID, 1);
- }
-
if(dirty) {
rtk_validate(w);
rtk_invalfb(w);
rect->height = w->height;
}
-#define COL_BG 0xff666666
-#define COL_BGHL 0xff808080
-#define COL_LBEV 0xffaaaaaa
-#define COL_SBEV 0xff222222
-#define COL_TEXT 0xff000000
-#define COL_WINFRM_FOCUS 0xff6688cc
-#define COL_WINFRM_LIT_FOCUS 0xff88aaff
-#define COL_WINFRM_SHAD_FOCUS 0xff224466
-#define COL_WINFRM 0xff667788
-#define COL_WINFRM_LIT 0xff8899aa
-#define COL_WINFRM_SHAD 0xff224455
-#define COL_TBOX 0xffeeccbb
-
static void hline(int x, int y, int sz, uint32_t col)
{
rtk_rect rect;
gfx.fill(&rect, col);
}
-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 sz)
+static void draw_frame(rtk_rect *rect, int type, int sz, uint32_t bgcol, uint32_t shad, uint32_t lit)
{
int i, tlcol, brcol, fillbg;
rtk_rect r = *rect;
switch(type) {
case FRM_OUTSET:
- tlcol = uicol[UICOL_LBEV];
- brcol = uicol[UICOL_SBEV];
+ tlcol = lit;
+ brcol = shad;
break;
case FRM_INSET:
- tlcol = uicol[UICOL_SBEV];
- brcol = uicol[UICOL_LBEV];
+ tlcol = shad;
+ brcol = lit;
break;
case FRM_SOLID:
default:
- tlcol = brcol = uicol[UICOL_BG];
+ tlcol = brcol = bgcol;
}
for(i=0; i<sz; i++) {
}
if(fillbg) {
- gfx.fill(&r, uicol[UICOL_BG]);
+ gfx.fill(&r, bgcol);
}
}
abs_widget_rect(w, &rect);
if(w->flags & FRAME) {
- if(w->flags & FOCUS) {
+ /*if(w->flags & FOCUS) {
uicolor(COL_WINFRM_FOCUS, COL_WINFRM_LIT_FOCUS, COL_WINFRM_SHAD_FOCUS);
} else {
uicolor(COL_WINFRM, COL_WINFRM_LIT, COL_WINFRM_SHAD);
- }
+ }*/
frmrect = rect;
frmrect.width += WINFRM_SZ * 2;
tbrect.width = rect.width;
tbrect.height = WINFRM_TBAR;
- draw_frame(&frmrect, FRM_OUTSET, 1);
+ draw_frame(&frmrect, FRM_OUTSET, BEVELSZ, COL_FRM_BG, COL_FRM_SHAD, COL_FRM_LIT);
frmrect.x++;
frmrect.y++;
frmrect.width -= 2;
frmrect.height -= 2;
- draw_frame(&frmrect, FRM_INSET, 1);
+ draw_frame(&frmrect, FRM_INSET, BEVELSZ, COL_FRM_BG, COL_FRM_SHAD, COL_FRM_LIT);
- draw_frame(&tbrect, FRM_OUTSET | FRM_FILLBG, 1);
+ draw_frame(&tbrect, FRM_OUTSET | FRM_FILLBG, BEVELSZ, COL_FRM_BG, COL_FRM_SHAD, COL_FRM_LIT);
tbrect.x++;
tbrect.y++;
tbrect.width -= 2;
static void draw_button(rtk_widget *w)
{
- int pressed;
+ int pressed, flags;
rtk_rect rect;
+ uint32_t col;
rtk_button *bn = (rtk_button*)w;
abs_widget_rect(w, &rect);
pressed = w->flags & PRESS;
}
- uicolor(w->flags & HOVER ? COL_BGHL : COL_BG, COL_LBEV, COL_SBEV);
+ col = w->flags & HOVER ? COL_BGHL : COL_BG;
+ flags = (pressed ? FRM_INSET : FRM_OUTSET) | FRM_FILLBG;
- draw_frame(&rect, (pressed ? FRM_INSET : FRM_OUTSET) | FRM_FILLBG, 1);
+ draw_frame(&rect, flags, BEVELSZ, col, COL_SHAD, COL_LIT);
rect.x++;
rect.y++;
rect.width -= 2;
abs_widget_rect(w, &rect);
- uicolor(COL_TBOX, COL_LBEV, COL_SBEV);
-
- draw_frame(&rect, FRM_INSET | FRM_FILLBG, w->flags & FOCUS ? 2 : 1);
+ draw_frame(&rect, FRM_INSET | FRM_FILLBG, BEVELSZ, COL_WHITE, COL_SHAD, COL_LIT);
rect.x++;
rect.y++;
if(w->flags & FOCUS) {
int x = rect.x + PAD + curx - 1;
int y = rect.y + rect.height - PAD - fontheight;
- vline(x, y, fontheight, 0xff000000);
+ vline(x, y, fontheight, COL_TEXT);
}
rtk_invalfb(w);
if(!win) return;
- uicolor(COL_BG, COL_LBEV, COL_SBEV);
-
abs_widget_rect(w, &rect);
switch(win->layout) {
break;
}
- draw_frame(&rect, FRM_INSET, 1);
+ draw_frame(&rect, FRM_INSET, BEVELSZ, COL_BG, COL_SHAD, COL_LIT);
}
static void draw_drawbox(rtk_widget *w)
--- /dev/null
+#ifndef UTIL_H_
+#define UTIL_H_
+
+#include <stdlib.h>
+#include "sizeint.h"
+
+#if defined(__WATCOMC__) || defined(_WIN32) || defined(__DJGPP__)
+#include <malloc.h>
+#else
+#include <alloca.h>
+#endif
+
+#ifdef __GNUC__
+#define PACKED __attribute__((packed))
+#else
+#define PACKED
+#endif
+
+
+/* Non-failing versions of malloc/calloc/realloc. They never return 0, they call
+ * demo_abort on failure. Use the macros, don't call the *_impl functions.
+ */
+#define malloc_nf(sz) malloc_nf_impl(sz, __FILE__, __LINE__)
+void *malloc_nf_impl(size_t sz, const char *file, int line);
+#define calloc_nf(n, sz) calloc_nf_impl(n, sz, __FILE__, __LINE__)
+void *calloc_nf_impl(size_t num, size_t sz, const char *file, int line);
+#define realloc_nf(p, sz) realloc_nf_impl(p, sz, __FILE__, __LINE__)
+void *realloc_nf_impl(void *p, size_t sz, const char *file, int line);
+#define strdup_nf(s) strdup_nf_impl(s, __FILE__, __LINE__)
+char *strdup_nf_impl(const char *s, const char *file, int line);
+
+int match_prefix(const char *str, const char *prefix);
+
+#ifndef INLINE
+#if (__STDC_VERSION__ >= 199901) || defined(__GNUC__)
+#define INLINE inline
+#else
+#define INLINE __inline
+#endif
+#endif
+
+#if defined(__i386__) || defined(__386__) || defined(MSDOS)
+
+/* fast conversion of double -> 32bit int
+ * for details see:
+ * - http://chrishecker.com/images/f/fb/Gdmfp.pdf
+ * - http://stereopsis.com/FPU.html#convert
+ */
+static INLINE int32_t cround64(double val)
+{
+ val += 6755399441055744.0;
+ return *(int32_t*)&val;
+}
+#else
+#define cround64(x) ((int32_t)(x))
+#endif
+
+#endif /* UTIL_H_ */