From e763dfa3ddf5c499875a6e1e9ec91d7fc154c076 Mon Sep 17 00:00:00 2001 From: Alexey Yakovenko Date: Sun, 11 Apr 2010 15:01:21 +0200 Subject: moved DUMB to dynamic plugin --- plugins/dumb/dumb-kode54/studio/font0.bmp | Bin 0 -> 3782 bytes plugins/dumb/dumb-kode54/studio/font1.bmp | Bin 0 -> 5862 bytes plugins/dumb/dumb-kode54/studio/font2.bmp | Bin 0 -> 11786 bytes plugins/dumb/dumb-kode54/studio/include/dumbdesk.h | 44 ++++ plugins/dumb/dumb-kode54/studio/include/dumbgui.h | 82 +++++++ plugins/dumb/dumb-kode54/studio/include/dumbmenu.h | 44 ++++ plugins/dumb/dumb-kode54/studio/include/guiproc.h | 52 ++++ plugins/dumb/dumb-kode54/studio/include/guitop.h | 17 ++ plugins/dumb/dumb-kode54/studio/include/main.h | 10 + plugins/dumb/dumb-kode54/studio/include/options.h | 34 +++ plugins/dumb/dumb-kode54/studio/include/subclip.h | 8 + plugins/dumb/dumb-kode54/studio/makedat | 13 + plugins/dumb/dumb-kode54/studio/src/dumbdesk.c | 271 +++++++++++++++++++++ plugins/dumb/dumb-kode54/studio/src/dumbgui.c | 120 +++++++++ plugins/dumb/dumb-kode54/studio/src/dumbmenu.c | 191 +++++++++++++++ plugins/dumb/dumb-kode54/studio/src/guiproc.c | 16 ++ plugins/dumb/dumb-kode54/studio/src/guitop.c | 131 ++++++++++ plugins/dumb/dumb-kode54/studio/src/main.c | 118 +++++++++ plugins/dumb/dumb-kode54/studio/src/options.c | 31 +++ plugins/dumb/dumb-kode54/studio/src/subclip.c | 33 +++ 20 files changed, 1215 insertions(+) create mode 100644 plugins/dumb/dumb-kode54/studio/font0.bmp create mode 100644 plugins/dumb/dumb-kode54/studio/font1.bmp create mode 100644 plugins/dumb/dumb-kode54/studio/font2.bmp create mode 100644 plugins/dumb/dumb-kode54/studio/include/dumbdesk.h create mode 100644 plugins/dumb/dumb-kode54/studio/include/dumbgui.h create mode 100644 plugins/dumb/dumb-kode54/studio/include/dumbmenu.h create mode 100644 plugins/dumb/dumb-kode54/studio/include/guiproc.h create mode 100644 plugins/dumb/dumb-kode54/studio/include/guitop.h create mode 100644 plugins/dumb/dumb-kode54/studio/include/main.h create mode 100644 plugins/dumb/dumb-kode54/studio/include/options.h create mode 100644 plugins/dumb/dumb-kode54/studio/include/subclip.h create mode 100644 plugins/dumb/dumb-kode54/studio/makedat create mode 100644 plugins/dumb/dumb-kode54/studio/src/dumbdesk.c create mode 100644 plugins/dumb/dumb-kode54/studio/src/dumbgui.c create mode 100644 plugins/dumb/dumb-kode54/studio/src/dumbmenu.c create mode 100644 plugins/dumb/dumb-kode54/studio/src/guiproc.c create mode 100644 plugins/dumb/dumb-kode54/studio/src/guitop.c create mode 100644 plugins/dumb/dumb-kode54/studio/src/main.c create mode 100644 plugins/dumb/dumb-kode54/studio/src/options.c create mode 100644 plugins/dumb/dumb-kode54/studio/src/subclip.c (limited to 'plugins/dumb/dumb-kode54/studio') diff --git a/plugins/dumb/dumb-kode54/studio/font0.bmp b/plugins/dumb/dumb-kode54/studio/font0.bmp new file mode 100644 index 00000000..5aff7cbc Binary files /dev/null and b/plugins/dumb/dumb-kode54/studio/font0.bmp differ diff --git a/plugins/dumb/dumb-kode54/studio/font1.bmp b/plugins/dumb/dumb-kode54/studio/font1.bmp new file mode 100644 index 00000000..7336d42b Binary files /dev/null and b/plugins/dumb/dumb-kode54/studio/font1.bmp differ diff --git a/plugins/dumb/dumb-kode54/studio/font2.bmp b/plugins/dumb/dumb-kode54/studio/font2.bmp new file mode 100644 index 00000000..5c0906cc Binary files /dev/null and b/plugins/dumb/dumb-kode54/studio/font2.bmp differ diff --git a/plugins/dumb/dumb-kode54/studio/include/dumbdesk.h b/plugins/dumb/dumb-kode54/studio/include/dumbdesk.h new file mode 100644 index 00000000..f8320f1c --- /dev/null +++ b/plugins/dumb/dumb-kode54/studio/include/dumbdesk.h @@ -0,0 +1,44 @@ +#ifndef INCLUDED_DUMBDESK_H +#define INCLUDED_DUMBDESK_H + + +#include "dumbgui.h" +#include "dumbmenu.h" + + +typedef struct DESKGUI +{ + struct DESKGUI *next; + + GUI *gui; + + const char *name; +} +DESKGUI; + + +typedef struct GUI_DESKTOP_PARAM +{ + const char *title; + GUI_MENU_PARAM *menu_bar; +} +GUI_DESKTOP_PARAM; + + +#define DESKTOP_CHANGED_TITLE GUI_OTHER +#define DESKTOP_CHANGED_REST (GUI_OTHER << 1) +#define DESKTOP_CHANGED_ALL (DESKTOP_CHANGED_TITLE | DESKTOP_CHANGED_REST) + +typedef struct GUI_DESKTOP_DATA +{ + const char *title; + GUI_MENU_PARAM *menu_bar; + DESKGUI *deskgui; +} +GUI_DESKTOP_DATA; + + +extern GUI_COMMANDS gui_desktop_commands; + + +#endif /* INCLUDED_DUMBDESK_H */ diff --git a/plugins/dumb/dumb-kode54/studio/include/dumbgui.h b/plugins/dumb/dumb-kode54/studio/include/dumbgui.h new file mode 100644 index 00000000..f6cc2bc7 --- /dev/null +++ b/plugins/dumb/dumb-kode54/studio/include/dumbgui.h @@ -0,0 +1,82 @@ +#ifndef INCLUDED_DUMBGUI_H +#define INCLUDED_DUMBGUI_H + + +/* GUI_FINISHED_WITH: Set this in your update, key or mouse function when you + * don't need the object any more. It will be destroyed + * before redrawing or any subsequent updates take place. + * GUI_OTHER: Any powers of two greater than or equal to this are + * free for use by objects for specific purposes. + */ +#define GUI_FINISHED_WITH 1 +#define GUI_OTHER 2 + + +typedef struct GUI GUI; + + +/* GUI_CREATE: Create a GUI object. + * GUI_DESTROY: Destroy the GUI object. + * GUI_KEY: Respond to a key. + * GUI_UPDATE: Process any real-time activity. + * GUI_DRAW: Draw any parts of the GUI that have changed. This may be + * called more than once with different clipping rectangles, + * so don't clear any flags here. + * GUI_DRAWN: Clear any redraw flags. + * GUI_CHANGED_*: Set flags to redraw parts of the object as necessary for + * the change that has occurred. + */ +typedef void (*GUI_CREATE)(GUI *gui, void *param); +typedef void (*GUI_DESTROY)(GUI *gui); +typedef void (*GUI_KEY)(GUI *gui, int k); +typedef void (*GUI_UPDATE)(GUI *gui); +typedef void (*GUI_DRAW)(GUI *gui); +typedef void (*GUI_DRAWN)(GUI *gui); +typedef void (*GUI_CHANGED_ALL)(GUI *gui); +typedef void (*GUI_CHANGED_ACTIVE)(GUI *gui); + + +typedef struct GUI_COMMANDS +{ + GUI_CREATE create; + GUI_DESTROY destroy; + GUI_KEY key; + GUI_UPDATE update; + GUI_DRAW draw; + GUI_DRAWN drawn; + GUI_CHANGED_ALL changed_all; + GUI_CHANGED_ACTIVE changed_active; +} +GUI_COMMANDS; + + +struct GUI +{ + GUI_COMMANDS *com; + + GUI *parent; + + int x, y, w, h; + int flags; + + void *data; +}; + + +extern GUI *gui_active; + +void gui_set_active(GUI *gui); + +GUI *gui_create(GUI_COMMANDS *com, GUI *parent, int x, int y, int w, int h, void *param); +void gui_destroy(GUI *gui); +void gui_key(GUI *gui, int k); +void gui_update(GUI *gui); +void gui_draw(GUI *gui); +void gui_draw_void(void *gui); +void gui_drawn(GUI *gui); +void gui_changed_all(GUI *gui); +void gui_changed_active(GUI *gui); + + +#endif /* INCLUDED_DUMBGUI_H */ + diff --git a/plugins/dumb/dumb-kode54/studio/include/dumbmenu.h b/plugins/dumb/dumb-kode54/studio/include/dumbmenu.h new file mode 100644 index 00000000..c28dcda1 --- /dev/null +++ b/plugins/dumb/dumb-kode54/studio/include/dumbmenu.h @@ -0,0 +1,44 @@ +#ifndef INCLUDED_DUMBMENU_H +#define INCLUDED_DUMBMENU_H + + +#include "dumbgui.h" + + +typedef void (*GUI_MENU_ACTIVATOR)(void *param); + + +typedef struct GUI_MENU_ENTRY +{ + char *text; /* If the first char is '\t', draw an arrow on the right. */ + GUI_MENU_ACTIVATOR activator; + void *param; +} +GUI_MENU_ENTRY; + + +typedef struct GUI_MENU_PARAM +{ + int n_entries; + GUI_MENU_ENTRY *entry; +} +GUI_MENU_PARAM; + + +#define GUI_MENU_REDRAW_ALL GUI_OTHER + +typedef struct GUI_MENU_DATA +{ + GUI_MENU_PARAM *menu; + int sel; + int lastsel; /* When this is different from 'sel', rows 'lastsel' and 'sel' need redrawing. */ +} +GUI_MENU_DATA; + + +extern GUI_COMMANDS gui_menu_commands; + +void gui_menu_get_size(GUI_MENU_PARAM *menu, int *w, int *h); + + +#endif /* INCLUDED_DUMBMENU_H */ diff --git a/plugins/dumb/dumb-kode54/studio/include/guiproc.h b/plugins/dumb/dumb-kode54/studio/include/guiproc.h new file mode 100644 index 00000000..ab3d8d71 --- /dev/null +++ b/plugins/dumb/dumb-kode54/studio/include/guiproc.h @@ -0,0 +1,52 @@ +#ifndef INCLUDED_GUIPROC_H +#define INCLUDED_GUIPROC_H + + +#define THE_SIZE 2 + + +#if THE_SIZE == 2 + +#define BEVEL_SIZE 3 +#define BORDER_SIZE 3 +#define TITLE_HEIGHT 21 + +#define THE_FONT FONT2 + +#elif THE_SIZE == 1 + +#define BEVEL_SIZE 2 +#define BORDER_SIZE 2 +#define TITLE_HEIGHT 13 + +#define THE_FONT FONT1 + +#else + +#define BEVEL_SIZE 1 +#define BORDER_SIZE 1 +#define TITLE_HEIGHT 7 + +#define THE_FONT FONT0 + +#endif + + +#define HIGHLIGHT 15 +#define MIDTONE 7 +#define SHADOW 8 +#define TITLE_BG_FOCUS 9 +#define TITLE_FG_FOCUS 14 +#define TITLE_BG 8 +#define TITLE_FG 7 +#define MENU_BG_FOCUS 1 +#define MENU_FG_FOCUS 15 +#define MENU_BG MIDTONE +#define MENU_FG 0 +#define DESKTOP 4 + + +void draw_bevel(int l, int t, int r, int b, int tl, int m, int br); + + +#endif /* INCLUDED_GUIPROC_H */ diff --git a/plugins/dumb/dumb-kode54/studio/include/guitop.h b/plugins/dumb/dumb-kode54/studio/include/guitop.h new file mode 100644 index 00000000..25557122 --- /dev/null +++ b/plugins/dumb/dumb-kode54/studio/include/guitop.h @@ -0,0 +1,17 @@ +#ifndef INCLUDED_GUITOP_H +#define INCLUDED_GUITOP_H + + +#include "dumbdesk.h" + +extern int the_time; + +extern volatile int true_time; + + +void run_desktop(GUI_DESKTOP_PARAM *param); + +void initialise_guitop(void); + + +#endif /* INCLUDED_GUITOP_H */ diff --git a/plugins/dumb/dumb-kode54/studio/include/main.h b/plugins/dumb/dumb-kode54/studio/include/main.h new file mode 100644 index 00000000..968fe5d6 --- /dev/null +++ b/plugins/dumb/dumb-kode54/studio/include/main.h @@ -0,0 +1,10 @@ +#ifndef INCLUDED_MAIN_H +#define INCLUDED_MAIN_H + + +extern DATAFILE *dat; + +#include "datafile.h" + + +#endif /* INCLUDED_MAIN_H */ diff --git a/plugins/dumb/dumb-kode54/studio/include/options.h b/plugins/dumb/dumb-kode54/studio/include/options.h new file mode 100644 index 00000000..a62d48c5 --- /dev/null +++ b/plugins/dumb/dumb-kode54/studio/include/options.h @@ -0,0 +1,34 @@ +#ifndef INCLUDED_OPTIONS_H +#define INCLUDED_OPTIONS_H + + +typedef struct OPTIONS +{ + int gfx_w, gfx_h; +} +OPTIONS; + + +OPTIONS opt; + + +#ifdef ALLEGRO_DOS + +#define DEF_GFX_W 320 +#define DEF_GFX_H 200 +#define DEF_GFX_STR "320x200" + +#else + +#define DEF_GFX_W 640 +#define DEF_GFX_H 480 +#define DEF_GFX_STR "640x480" + +#endif + + +void load_options(void); +void save_options(void); + + +#endif /* INCLUDED_OPTIONS_H */ diff --git a/plugins/dumb/dumb-kode54/studio/include/subclip.h b/plugins/dumb/dumb-kode54/studio/include/subclip.h new file mode 100644 index 00000000..5a5f8210 --- /dev/null +++ b/plugins/dumb/dumb-kode54/studio/include/subclip.h @@ -0,0 +1,8 @@ +#ifndef INCLUDED_SUBCLIP_H +#define INCLUDED_SUBCLIP_H + + +void subclip(int l, int t, int r, int b, void (*proc)(void *data), void *data); + + +#endif /* INCLUDED_SUBCLIP_H */ diff --git a/plugins/dumb/dumb-kode54/studio/makedat b/plugins/dumb/dumb-kode54/studio/makedat new file mode 100644 index 00000000..7932ff91 --- /dev/null +++ b/plugins/dumb/dumb-kode54/studio/makedat @@ -0,0 +1,13 @@ +# Makefile for building the datafile +# NOT FOR RELEASE +# Usage: make -f makedat + +include/datafile.h: studio.dat + dat -h $@ $< + +studio.dat: font0.bmp font1.bmp font2.bmp + rm -f $@ + dat -t FONT -a $@ font0.bmp; dat $@ FONT0_BMP NAME=FONT0 + dat -t FONT -a $@ font1.bmp; dat $@ FONT1_BMP NAME=FONT1 + dat -t FONT -a $@ font2.bmp; dat $@ FONT2_BMP NAME=FONT2 + dat -c2 $@ diff --git a/plugins/dumb/dumb-kode54/studio/src/dumbdesk.c b/plugins/dumb/dumb-kode54/studio/src/dumbdesk.c new file mode 100644 index 00000000..61a3cd0e --- /dev/null +++ b/plugins/dumb/dumb-kode54/studio/src/dumbdesk.c @@ -0,0 +1,271 @@ +#include +#include + +#include "main.h" +#include "subclip.h" +#include "dumbgui.h" +#include "guiproc.h" +#include "dumbdesk.h" +#include "options.h" + + + +static void gui_desktop_create(GUI *gui, void *param) +{ + GUI_DESKTOP_PARAM *desktop = param; + + GUI_DESKTOP_DATA *data = gui->data = malloc(sizeof(*data)); + + if (!data) + return; + + data->title = desktop->title; + data->menu_bar = desktop->menu_bar; + data->deskgui = NULL; +} + + + +static void gui_desktop_destroy(GUI *gui) +{ + GUI_DESKTOP_DATA *data = gui->data; + + DESKGUI *deskgui = data->deskgui; + + while (deskgui) { + DESKGUI *next = deskgui->next; + gui_destroy(deskgui->gui); + free(deskgui); + deskgui = next; + } + + free(data); +} + + + +static void gui_desktop_key(GUI *gui, int k) +{ + switch (k >> 8) { + case KEY_N: + { + GUI_DESKTOP_PARAM param2 = {"well.duh", NULL}; + GUI_DESKTOP_DATA *data = gui->data; + DESKGUI *next = data->deskgui; + data->deskgui = malloc(sizeof(*data->deskgui)); + if (!data->deskgui) break; + data->deskgui->gui = gui_create( + &gui_desktop_commands, + gui, + 10 + rand() % 50, 30 + rand() % 50, 50 + rand() % 600, 50 + rand() % 350, + ¶m2 + ); + if (!data->deskgui->gui) { + free(data->deskgui); + break; + } + data->deskgui->name = param2.title; + data->deskgui->next = next; + gui_set_active(data->deskgui->gui); + } + } +} + + + +static void gui_desktop_update(GUI *gui) +{ + GUI_DESKTOP_DATA *data = gui->data; + + DESKGUI *deskgui = data->deskgui; + + while (deskgui) { + gui_update(deskgui->gui); + deskgui = deskgui->next; + } +} + + + +static void draw_desktop_itself(void *g) +{ + GUI *gui = g; + GUI_DESKTOP_DATA *data = gui->data; + + if (data->deskgui) { + + /* Unlink child GUI. */ + DESKGUI *deskgui = data->deskgui; + GUI *subgui = deskgui->gui; + + data->deskgui = deskgui->next; + + /* Child GUI outer bevel */ + draw_bevel( + subgui->x - BORDER_SIZE - BEVEL_SIZE, + subgui->y - BORDER_SIZE - BEVEL_SIZE, + subgui->x + subgui->w + BORDER_SIZE + BEVEL_SIZE - 1, + subgui->y + subgui->h + BORDER_SIZE + BEVEL_SIZE - 1, + HIGHLIGHT, MIDTONE, SHADOW + ); + + /* Child GUI border */ + rectfill(screen, subgui->x - BORDER_SIZE, subgui->y - BORDER_SIZE, subgui->x + subgui->w + BORDER_SIZE - 1, subgui->y - 1, MIDTONE); + rectfill(screen, subgui->x - BORDER_SIZE, subgui->y, subgui->x - 1, subgui->y + subgui->h - 1, MIDTONE); + rectfill(screen, subgui->x + subgui->w, subgui->y, subgui->x + subgui->w + BORDER_SIZE - 1, subgui->y + subgui->h - 1, MIDTONE); + rectfill(screen, subgui->x - BORDER_SIZE, subgui->y + subgui->h, subgui->x + subgui->w + BORDER_SIZE - 1, subgui->y + subgui->h + BORDER_SIZE - 1, MIDTONE); + + /* Child GUI */ + subclip(subgui->x, subgui->y, subgui->x + subgui->w, subgui->y + subgui->h, + &gui_draw_void, subgui); + + /* Draw self, and other child GUIs, around this child GUI. */ + subclip(0, 0, opt.gfx_w, subgui->y - BORDER_SIZE - BEVEL_SIZE, &draw_desktop_itself, gui); + subclip(0, subgui->y - BORDER_SIZE - BEVEL_SIZE, subgui->x - BORDER_SIZE - BEVEL_SIZE, subgui->y + subgui->h + BORDER_SIZE + BEVEL_SIZE, &draw_desktop_itself, gui); + subclip(subgui->x + subgui->w + BORDER_SIZE + BEVEL_SIZE, subgui->y - BORDER_SIZE - BEVEL_SIZE, opt.gfx_w, subgui->y + subgui->h + BORDER_SIZE + BEVEL_SIZE, &draw_desktop_itself, gui); + subclip(0, subgui->y + subgui->h + BORDER_SIZE + BEVEL_SIZE, opt.gfx_w, opt.gfx_h, &draw_desktop_itself, gui); + + /* Link child GUI back in. */ + data->deskgui = deskgui; + + return; + } + + if (gui->flags & DESKTOP_CHANGED_REST) + /* Desktop area */ + clear_to_color(screen, DESKTOP); +} + + + +static int desktop_x; +static int desktop_y; +static GUI *desktop_gui; + + + +static void draw_desktop_title_bar(void *t) +{ + const char *title = t; + clear_to_color(screen, desktop_gui == gui_active ? TITLE_BG_FOCUS : TITLE_BG); + textout(screen, dat[THE_FONT].dat, title, desktop_x, desktop_y, desktop_gui == gui_active ? TITLE_FG_FOCUS : TITLE_FG); +} + + + +static void draw_menu_bar(void *data) +{ + GUI_MENU_PARAM *menu_bar = data; + + clear_to_color(screen, MENU_BG); + + if (menu_bar) { + int i; + GUI_MENU_ENTRY *entry = menu_bar->entry; + for (i = 0; i < menu_bar->n_entries; i++) { + // If the first char is '\t', draw an arrow on the right. + textout(screen, dat[THE_FONT].dat, entry->text, + desktop_x + BORDER_SIZE, desktop_y + BORDER_SIZE, MENU_FG); + desktop_x += BORDER_SIZE + text_length(dat[THE_FONT].dat, entry->text) + BORDER_SIZE; + entry++; + } + } // else hide the damn thing? +} + + + +static void gui_desktop_draw(GUI *gui) +{ + GUI_DESKTOP_DATA *data = gui->data; + + subclip( + gui->x + BEVEL_SIZE, + gui->y + TITLE_HEIGHT + TITLE_HEIGHT + BEVEL_SIZE, + gui->x + gui->w - BEVEL_SIZE, + gui->y + gui->h - BEVEL_SIZE, + &draw_desktop_itself, gui + ); + + if (gui->flags & DESKTOP_CHANGED_TITLE) { + /* Title bar */ + desktop_x = gui->x + BORDER_SIZE; + desktop_y = gui->y + BORDER_SIZE; + desktop_gui = gui; + + subclip(gui->x, gui->y, gui->x + gui->w, gui->y + TITLE_HEIGHT, + &draw_desktop_title_bar, (void *)data->title); + } + + if (gui->flags & DESKTOP_CHANGED_REST) { + /* Separation between title bar and inner bevel */ + //rectfill(screen, gui->x, gui->y + TITLE_HEIGHT, gui->x + gui->w - 1, gui->y + TITLE_HEIGHT + BORDER_SIZE - 1, MIDTONE); + + /* Menu bar */ + desktop_x = gui->x; + desktop_y = gui->y + TITLE_HEIGHT; + + subclip( + gui->x, gui->y + TITLE_HEIGHT, + gui->x + gui->w, gui->y + TITLE_HEIGHT + TITLE_HEIGHT, + &draw_menu_bar, data->menu_bar + ); + + /* Inner bevel */ + draw_bevel(gui->x, gui->y + TITLE_HEIGHT + TITLE_HEIGHT, gui->x + gui->w - 1, gui->y + gui->h - 1, SHADOW, MIDTONE, HIGHLIGHT); + } +} + + + +static void gui_desktop_drawn(GUI *gui) +{ + GUI_DESKTOP_DATA *data = gui->data; + + if (data->deskgui) { + /* Mark child GUIs as drawn. */ + DESKGUI *deskgui = data->deskgui; + while (deskgui) { + gui_drawn(deskgui->gui); + deskgui = deskgui->next; + } + } + + /* Mark self as drawn. */ + gui->flags &= ~DESKTOP_CHANGED_ALL; +} + + + +static void gui_desktop_changed_all(GUI *gui) +{ + gui->flags |= DESKTOP_CHANGED_ALL; + + { + GUI_DESKTOP_DATA *data = gui->data; + DESKGUI *deskgui = data->deskgui; + while (deskgui) { + gui_changed_all(deskgui->gui); + deskgui = deskgui->next; + } + } +} + + + +static void gui_desktop_changed_active(GUI *gui) +{ + gui->flags |= DESKTOP_CHANGED_TITLE; +} + + + +GUI_COMMANDS gui_desktop_commands = { + &gui_desktop_create, + &gui_desktop_destroy, + &gui_desktop_key, + &gui_desktop_update, + &gui_desktop_draw, + &gui_desktop_drawn, + &gui_desktop_changed_all, + &gui_desktop_changed_active +}; diff --git a/plugins/dumb/dumb-kode54/studio/src/dumbgui.c b/plugins/dumb/dumb-kode54/studio/src/dumbgui.c new file mode 100644 index 00000000..4927a09c --- /dev/null +++ b/plugins/dumb/dumb-kode54/studio/src/dumbgui.c @@ -0,0 +1,120 @@ +#include + +#include "dumbgui.h" + + + +GUI *gui_active; + + + +void gui_set_active(GUI *gui) +{ + gui_changed_active(gui_active); + gui_active = gui; + gui_changed_active(gui_active); +} + + + +GUI *gui_create(GUI_COMMANDS *com, GUI *parent, int x, int y, int w, int h, void *param) +{ + GUI *gui = malloc(sizeof(*gui)); + + if (!gui) + return NULL; + + gui->com = com; + + gui->parent = parent; + + gui->x = x; + gui->y = y; + gui->w = w; + gui->h = h; + + gui->flags = 0; + + if (com->create) { + (*com->create)(gui, param); + + if (!gui->data) { + free(gui); + return NULL; + } + } else + gui->data = NULL; + + gui_changed_all(gui); + + return gui; +} + + + +void gui_destroy(GUI *gui) +{ + if (gui) { + if (gui->com->destroy) + (*gui->com->destroy)(gui); + + free(gui); + } +} + + + +void gui_key(GUI *gui, int k) +{ + if (gui && gui->com->key) + (*gui->com->key)(gui, k); +} + + + +void gui_update(GUI *gui) +{ + if (gui && gui->com->update) + (*gui->com->update)(gui); +} + + + +void gui_draw(GUI *gui) +{ + if (gui && gui->com->draw) + (*gui->com->draw)(gui); +} + + + +/* For use with subclip(). */ +void gui_draw_void(void *gui) +{ + gui_draw(gui); +} + + + +void gui_drawn(GUI *gui) +{ + if (gui && gui->com->drawn) + (*gui->com->drawn)(gui); +} + + + +void gui_changed_all(GUI *gui) +{ + if (gui && gui->com->changed_all) + (*gui->com->changed_all)(gui); +} + + + +void gui_changed_active(GUI *gui) +{ + if (gui && gui->com->changed_active) + (*gui->com->changed_active)(gui); +} + diff --git a/plugins/dumb/dumb-kode54/studio/src/dumbmenu.c b/plugins/dumb/dumb-kode54/studio/src/dumbmenu.c new file mode 100644 index 00000000..609c70e2 --- /dev/null +++ b/plugins/dumb/dumb-kode54/studio/src/dumbmenu.c @@ -0,0 +1,191 @@ +#include +#include + +#include "main.h" +#include "dumbgui.h" +#include "guiproc.h" +#include "subclip.h" +#include "dumbmenu.h" + + + +static void gui_menu_create(GUI *gui, void *param) +{ + GUI_MENU_PARAM *menu = param; + + GUI_MENU_DATA *data = gui->data = malloc(sizeof(*data)); + + if (!data) + return; + + data->menu = menu; + data->sel = -1; + /* data->lastsel will be initialised by gui_menu_drawn(). */ +} + + + +static void gui_menu_destroy(GUI *gui) +{ + free(gui->data); +} + + + +static void gui_menu_key(GUI *gui, int k) +{ + GUI_MENU_DATA *data = gui->data; + + switch (k >> 8) { + case KEY_UP: + case KEY_8_PAD: + if (data->sel <= 0) data->sel = data->menu->n_entries; + data->sel--; + break; + case KEY_DOWN: + case KEY_2_PAD: + data->sel++; + if (data->sel >= data->menu->n_entries) data->sel = 0; + break; + case KEY_RIGHT: + case KEY_6_PAD: + case KEY_ENTER: + if (data->sel >= 0) { + GUI_MENU_ENTRY *entry = &data->menu->entry[data->sel]; + if (k >> 8 != KEY_RIGHT || entry->text[0] == '\t') + (*entry->activator)(entry->param); + } + // To do: defer 'right' to parent menus, making sure it doesn't reopen the same submenu + break; + case KEY_ESC: + gui->flags |= GUI_FINISHED_WITH; + break; + } +} + + + +static void gui_menu_update(GUI *gui) +{ + // Remove this function? + (void)gui; +} + + + +typedef struct GUI_MENU_DRAW_ENTRY_DATA +{ + GUI *gui; + GUI_MENU_DATA *data; + int i, y; +} +GUI_MENU_DRAW_ENTRY_DATA; + + + +static void gui_menu_draw_entry_proc(void *data) +{ + GUI_MENU_DRAW_ENTRY_DATA *d = data; + char *text = d->data->menu->entry[d->i].text; + + clear_to_color(screen, d->i == d->data->sel ? MENU_BG_FOCUS : MENU_BG); + + if (text[0] == '\t') { + text++; + // Draw an arrow + } + + textout(screen, dat[THE_FONT].dat, text, d->gui->x + BORDER_SIZE, d->y + BORDER_SIZE, + d->i == d->data->sel ? MENU_FG_FOCUS : MENU_FG); +} + + + +static void gui_menu_draw(GUI *gui) +{ + GUI_MENU_DRAW_ENTRY_DATA d; + d.gui = gui; + d.data = gui->data; + + if (gui->flags & GUI_MENU_REDRAW_ALL) { + // Redraw the whole menu + d.y = gui->y; + for (d.i = 0; d.i < d.data->menu->n_entries; d.i++) { + subclip(gui->x, d.y, gui->x + gui->w, d.y + TITLE_HEIGHT, &gui_menu_draw_entry_proc, &d); + d.y += TITLE_HEIGHT; + } + } else if (d.data->sel != d.data->lastsel) { + if (d.data->lastsel >= 0) { + // Redraw the 'lastsel' row + d.i = d.data->lastsel; + d.y = gui->y + d.i * TITLE_HEIGHT; + subclip(gui->x, d.y, gui->x + gui->w, d.y + TITLE_HEIGHT, &gui_menu_draw_entry_proc, &d); + } + if (d.data->sel >= 0) { // Necessary? + // Redraw the 'sel' row + d.i = d.data->sel; + d.y = gui->y + d.i * TITLE_HEIGHT; + subclip(gui->x, d.y, gui->x + gui->w, d.y + TITLE_HEIGHT, &gui_menu_draw_entry_proc, &d); + } + } +} + + + +static void gui_menu_drawn(GUI *gui) +{ + GUI_MENU_DATA *data = gui->data; + + gui->flags &= ~GUI_MENU_REDRAW_ALL; + data->lastsel = data->sel; +} + + + +static void gui_menu_changed_all(GUI *gui) +{ + gui->flags |= GUI_MENU_REDRAW_ALL; +} + + + +static void gui_menu_changed_active(GUI *gui) +{ + // Remove this function? + (void)gui; +} + + + +GUI_COMMANDS gui_menu_commands = { + &gui_menu_create, + &gui_menu_destroy, + &gui_menu_key, + &gui_menu_update, + &gui_menu_draw, + &gui_menu_drawn, + &gui_menu_changed_all, + &gui_menu_changed_active +}; + + + +void gui_menu_get_size(GUI_MENU_PARAM *menu, int *w, int *h) +{ + int i; + + *w = 2*BORDER_SIZE + TITLE_HEIGHT; /* A reasonable minimum width */ + *h = 2*BORDER_SIZE; + + for (i = 0; i < menu->n_entries; i++) { + char *text = menu->entry[i].text; + int wi = 2*BORDER_SIZE; + if (text[0] == '\t') { + text++; + wi += 10; // Fix this later + } + wi += text_length(dat[THE_FONT].dat, text); + if (wi > *w) *w = wi; + *h += TITLE_HEIGHT; + } +} diff --git a/plugins/dumb/dumb-kode54/studio/src/guiproc.c b/plugins/dumb/dumb-kode54/studio/src/guiproc.c new file mode 100644 index 00000000..6e53b323 --- /dev/null +++ b/plugins/dumb/dumb-kode54/studio/src/guiproc.c @@ -0,0 +1,16 @@ +#include +#include "guiproc.h" + + +void draw_bevel(int l, int t, int r, int b, int tl, int m, int br) +{ + int n; + for (n = 0; n < BEVEL_SIZE; n++) { + hline(screen, l + n, t + n, r - 1 - n, tl); + putpixel(screen, r - n, t + n, m); + vline(screen, l + n, t + 1 + n, b - 1 - n, tl); + vline(screen, r - n, t + 1 + n, b - 1 - n, br); + putpixel(screen, l + n, b - n, m); + hline(screen, l + 1 + n, b - n, r - n, br); + } +} diff --git a/plugins/dumb/dumb-kode54/studio/src/guitop.c b/plugins/dumb/dumb-kode54/studio/src/guitop.c new file mode 100644 index 00000000..be5cddf9 --- /dev/null +++ b/plugins/dumb/dumb-kode54/studio/src/guitop.c @@ -0,0 +1,131 @@ +#include + +#include "options.h" +#include "guitop.h" +#include "guiproc.h" +#include "dumbdesk.h" + + + +int the_time; + +volatile int true_time; +static int max_time; + + + +static void timer_handler(void) +{ + if (true_time < max_time) + true_time++; +} +END_OF_STATIC_FUNCTION(timer_handler); + + + +#define MAX_SKIP 20 + + + +/* +Every GUI has a reference to its parent - except the top one. + +Main loop: + Test keyboard. + Esc makes parent GUI active. + Other keys go to active GUI, which can do as it pleases. + Test mouse. + Mouse clicks go to the top GUI. + The top GUI may pass them down recursively. + A GUI may be marked as mouse-active, for dragging. + Update top GUI. + Update functions are called recursively. + This can be used for animation for example. + If there's time, draw top GUI. + Draw functions only draw areas marked for redrawing. + Marked areas are unmarked once they have been drawn. + Draw functions are called recursively. + If a child has moved: + It will call its parent for the vacated areas.* + +The child will have been removed from the parent's list while +it was drawn, so recursive cycles cannot occur. +*/ + + + +void run_desktop(GUI_DESKTOP_PARAM *param) +{ + GUI *gui = gui_create( + &gui_desktop_commands, + NULL, + 0, 0, opt.gfx_w, opt.gfx_h, + param + ); + + if (!gui) + return; + + gui_active = gui; + + true_time = the_time = 0; + max_time = MAX_SKIP; + + install_int_ex(timer_handler, BPS_TO_TIMER(100)); + + for (;;) { + gui_draw(gui); + gui_drawn(gui); + + while (the_time >= true_time) + yield_timeslice(); + + while (the_time < true_time) { + the_time++; + + /* + Test keyboard. + Esc makes parent GUI active. + Other keys go to active GUI, which can do as it pleases. + */ + while (keypressed()) { + int k = readkey(); + if (k >> 8 == KEY_ESC) { + if (!gui_active->parent) { + remove_int(timer_handler); + return; + } + gui_set_active(gui_active->parent); + } else + gui_key(gui_active, k); + } + + /* + Test mouse. + Mouse clicks go to the top GUI. + The top GUI may pass them down recursively. + A GUI may be marked as mouse-active, for dragging. + */ + + /* + Update top GUI. + Update functions are called recursively. + This can be used for animation for example. + */ + gui_update(gui); + } + + max_time = the_time + MAX_SKIP; + } + + gui_destroy(gui); +} + + + +void initialise_guitop(void) +{ + LOCK_FUNCTION(timer_handler); + LOCK_VARIABLE(true_time); + LOCK_VARIABLE(max_time); +} diff --git a/plugins/dumb/dumb-kode54/studio/src/main.c b/plugins/dumb/dumb-kode54/studio/src/main.c new file mode 100644 index 00000000..577d40c6 --- /dev/null +++ b/plugins/dumb/dumb-kode54/studio/src/main.c @@ -0,0 +1,118 @@ +#include +#include +#include +#include "dumb.h" + +#include "options.h" +#include "guitop.h" +#include "dumbdesk.h" + + + +DATAFILE *dat; + + + +static int load_studio_datafile(void) +{ + char ef[256], df[256]; + + get_executable_name(ef, 256); + replace_filename(df, ef, "studio.dat", 256); + + dat = load_datafile(df); + + if (!dat) + return 1; + + return 0; +} + + + +static GUI_MENU_ENTRY main_menu_bar_entries[] = { + {"File", NULL, NULL}, + {"Edit", NULL, NULL}, + {"View", NULL, NULL} +}; + +static GUI_MENU_PARAM main_menu_bar = {3, main_menu_bar_entries}; + +static GUI_DESKTOP_PARAM desktop_param = {"DUMB Studio v0.001", &main_menu_bar}; + + + +int main(void)//(int argc, char *argv[]) +{ + int old_gfx_w, old_gfx_h; + char old_allegro_error[ALLEGRO_ERROR_SIZE]; + + if (allegro_init()) + return 1; + + if (install_timer()) { + allegro_message("Unable to initialise timer\n"); + return 1; + } + + if (install_keyboard()) { + allegro_message("Unable to initialise keyboard\n"); + return 1; + } + + /* + if (install_dumb(&errno, &atexit)) { + allegro_message("Unable to initialise the DUMB library\n"); + return 1; + } + + register_sigtype_sample(); + register_sigtype_combining(); + register_sigtype_stereopan(); + register_sigtype_sequence(); + */ + + initialise_guitop(); + + if (load_studio_datafile()) { + allegro_message("Unable to load studio.dat\n"); + return 1; + } + + load_options(); + + old_gfx_w = opt.gfx_w; + old_gfx_h = opt.gfx_h; + + while (set_gfx_mode(GFX_AUTODETECT, opt.gfx_w, opt.gfx_h, 0, 0)) { + if (opt.gfx_w == DEF_GFX_W && opt.gfx_h == DEF_GFX_H) { + if (opt.gfx_w == old_gfx_w && opt.gfx_h == old_gfx_h) { + allegro_message( + "Unable to set graphics mode "DEF_GFX_STR"\n%s\n", + allegro_error + ); + } else { + allegro_message( + "Unable to set graphics mode %dx%d\n%s\n" + "Unable to revert to graphics mode "DEF_GFX_STR"\n%s\n", + old_gfx_w, old_gfx_h, + old_allegro_error, + allegro_error + ); + } + return 1; + } + + opt.gfx_w = DEF_GFX_W; + opt.gfx_h = DEF_GFX_H; + ustrncpy(old_allegro_error, allegro_error, ALLEGRO_ERROR_SIZE); + } + + text_mode(-1); + + run_desktop(&desktop_param); + + return 0; +} +END_OF_MAIN(); + diff --git a/plugins/dumb/dumb-kode54/studio/src/options.c b/plugins/dumb/dumb-kode54/studio/src/options.c new file mode 100644 index 00000000..e387db13 --- /dev/null +++ b/plugins/dumb/dumb-kode54/studio/src/options.c @@ -0,0 +1,31 @@ +#include +#include +#include "options.h" + + + +void load_options(void) +{ + { + char ef[256], cf[256]; + + get_executable_name(ef, 256); + replace_filename(cf, ef, "studio.ini", 256); + + set_config_file(cf); + } + + opt.gfx_w = get_config_int("options", "gfx_w", DEF_GFX_W); + opt.gfx_h = get_config_int("options", "gfx_h", DEF_GFX_H); + + atexit(&save_options); +} + + + +void save_options(void) +{ + set_config_int("options", "gfx_w", opt.gfx_w); + set_config_int("options", "gfx_h", opt.gfx_h); +} + diff --git a/plugins/dumb/dumb-kode54/studio/src/subclip.c b/plugins/dumb/dumb-kode54/studio/src/subclip.c new file mode 100644 index 00000000..ef1a9137 --- /dev/null +++ b/plugins/dumb/dumb-kode54/studio/src/subclip.c @@ -0,0 +1,33 @@ +#include + +#include "subclip.h" + + + +void subclip(int l, int t, int r, int b, void (*proc)(void *data), void *data) +{ + int cl = screen->cl; + int ct = screen->ct; + int cr = screen->cr; + int cb = screen->cb; + + if (l < cl) l = cl; + if (t < ct) t = ct; + if (r > cr) r = cr; + if (b > cb) b = cb; + + if (r > l && b > t) { + screen->cl = l; + screen->ct = t; + screen->cr = r; + screen->cb = b; + + (*proc)(data); + + screen->cl = cl; + screen->ct = ct; + screen->cr = cr; + screen->cb = cb; + } +} + -- cgit v1.2.3