49#ifndef RETROWIN_TRACE_LVL
50# define RETROWIN_TRACE_LVL 0
58#define RETROWIN_FLAG_INIT_GUI 0x10
60#define RETROWIN_FLAG_INIT_BMP 0x20
62#define RETROWIN_FLAG_GUI_LOCKED 0x04
64#define RETROWIN_FLAG_BORDER_NONE 0x00
65#define RETROWIN_FLAG_BORDER_GRAY 0x01
66#define RETROWIN_FLAG_BORDER_BLUE 0x02
68#define retrowin_win_is_active( win ) \
69 (RETROWIN_FLAG_INIT_BMP == (RETROWIN_FLAG_INIT_BMP & (win)->flags))
71#define RETROWIN_FLAG_BORDER_MASK 0x03
73#define retrowin_lock_gui( win ) \
75 RETROWIN_FLAG_INIT_GUI == (RETROWIN_FLAG_INIT_GUI & (win)->flags) && \
76 RETROWIN_FLAG_GUI_LOCKED != (RETROWIN_FLAG_GUI_LOCKED & (win)->flags) \
80 maug_mlock( (win)->gui_h, (win)->gui_p ); \
81 maug_cleanup_if_null_lock( struct RETROGUI*, (win)->gui_p ); \
82 (win)->flags |= RETROWIN_FLAG_GUI_LOCKED; \
87#define retrowin_unlock_gui( win ) \
89 RETROWIN_FLAG_INIT_GUI == (RETROWIN_FLAG_INIT_GUI & (win)->flags) && \
90 RETROWIN_FLAG_GUI_LOCKED == (RETROWIN_FLAG_GUI_LOCKED & (win)->flags) \
94 maug_munlock( (win)->gui_h, (win)->gui_p ); \
95 (win)->flags &= ~RETROWIN_FLAG_GUI_LOCKED; \
98#define retrowin_gui_is_locked( win ) \
99 (RETROWIN_FLAG_INIT_GUI == (RETROWIN_FLAG_INIT_GUI & (win)->flags) && \
100 RETROWIN_FLAG_GUI_LOCKED == (RETROWIN_FLAG_GUI_LOCKED & (win)->flags))
109#ifndef RETROWIN_NO_BITMAP
110 retroflat_blit_t gui_bmp;
147void retrowin_free_win(
struct RETROWIN* win );
151ssize_t retrowin_get_by_idc(
180 uint8_t autolock_gui = 0;
182#if RETROWIN_TRACE_LVL > 0
183 debug_printf( RETROWIN_TRACE_LVL,
"drawing window border..." );
186 if( !retrowin_gui_is_locked( win ) ) {
187 retrowin_lock_gui( win );
191 switch( RETROWIN_FLAG_BORDER_MASK & win->flags ) {
192 case RETROWIN_FLAG_BORDER_NONE:
194 win->gui_p->draw_bmp, RETROFLAT_COLOR_BLACK,
202 case RETROWIN_FLAG_BORDER_GRAY:
204 win->gui_p->draw_bmp,
205 2 < retroflat_screen_colors() ?
206 RETROFLAT_COLOR_GRAY : RETROFLAT_COLOR_WHITE,
215 win->gui_p->draw_bmp,
216 2 < retroflat_screen_colors() ?
223 if( 2 < retroflat_screen_colors() ) {
226 win->gui_p->draw_bmp, RETROFLAT_COLOR_WHITE,
229 win->gui_p->x + win->gui_p->w - 2,
230 win->gui_p-> y + 1, 0 );
232 win->gui_p->draw_bmp, RETROFLAT_COLOR_WHITE,
236 win->gui_p->y + win->gui_p->h - 3, 0 );
240 case RETROWIN_FLAG_BORDER_BLUE:
242 win->gui_p->draw_bmp,
243 2 < retroflat_screen_colors() ?
244 RETROFLAT_COLOR_BLUE : RETROFLAT_COLOR_BLACK,
253 win->gui_p->draw_bmp,
254 2 < retroflat_screen_colors() ?
262 win->gui_p->draw_bmp, RETROFLAT_COLOR_WHITE,
269 win->gui_p->draw_bmp,
270 2 < retroflat_screen_colors() ?
280#if RETROWIN_TRACE_LVL > 0
281 debug_printf( RETROWIN_TRACE_LVL,
"drawing window border complete!" );
287 retrowin_unlock_gui( win );
297 uint8_t autolock_gui = 0;
299 if( !retrowin_gui_is_locked( win ) ) {
300 retrowin_lock_gui( win );
306#ifdef RETROWIN_NO_BITMAP
307 win->gui_p->draw_bmp = NULL;
309 retroflat_2d_lock_bitmap( &(win->gui_bmp) );
310 win->gui_p->draw_bmp = &(win->gui_bmp);
313#if RETROWIN_TRACE_LVL > 0
314 debug_printf( RETROWIN_TRACE_LVL,
315 "redrawing window IDC " RETROGUI_IDC_FMT
" at "
316 PXXY_FMT
", " PXXY_FMT
"...",
317 win->idc, win->gui_p->x, win->gui_p->y );
320#ifndef RETROWIN_NO_BITMAP
328 retval = _retrowin_draw_border( win );
329 if( MERROR_OK == retval ) {
330 retval = retrogui_redraw_ctls( win->gui_p );
332#ifndef RETROWIN_NO_BITMAP
333 win->gui_p->x = win->x;
334 win->gui_p->y = win->y;
336 retroflat_2d_release_bitmap( &(win->gui_bmp) );
339 maug_cleanup_if_not_ok();
341#if RETROWIN_TRACE_LVL > 0
342 debug_printf( RETROWIN_TRACE_LVL,
343 "redraw of window IDC " RETROGUI_IDC_FMT
" at "
344 PXXY_FMT
", " PXXY_FMT
" complete!",
345 win->idc, win->gui_p->x, win->gui_p->y );
351 retrowin_unlock_gui( win );
363 uint8_t autolock_stack = 0;
369 if( !mdata_vector_is_locked( win_stack ) ) {
375 win = mdata_vector_get( win_stack, i,
struct RETROWIN );
376 assert( NULL != win );
378 if( !retrowin_win_is_active( win ) ) {
382 retrowin_lock_gui( win );
384#ifndef RETROWIN_NO_BITMAP
387#if RETROWIN_TRACE_LVL > 0
388 debug_printf( RETROWIN_TRACE_LVL,
389 "redrawing window idx " SIZE_T_FMT
" with IDC " RETROGUI_IDC_FMT,
394 retval = _retrowin_redraw_win( win );
395 maug_cleanup_if_not_ok();
396#ifndef RETROWIN_NO_BITMAP
400#ifndef RETROWIN_NO_BITMAP
404 retval = retroflat_2d_blit_win(
405 &(win->gui_bmp), win->gui_p->x, win->gui_p->y );
408 retrowin_unlock_gui( win );
410#if RETROWIN_TRACE_LVL > 0
411 debug_printf( RETROWIN_TRACE_LVL,
412 "redraw of window idx " SIZE_T_FMT
" with IDC " RETROGUI_IDC_FMT
418#if RETROWIN_TRACE_LVL > 0
419 debug_printf( RETROWIN_TRACE_LVL,
"redraw of all windows complete!" );
424 if( autolock_stack ) {
437 uint8_t autolock_stack = 0;
443 if( !mdata_vector_is_locked( win_stack ) ) {
449 win = mdata_vector_get( win_stack, i,
struct RETROWIN );
450 assert( NULL != win );
452 if( !retrowin_win_is_active( win ) ) {
456 retrowin_lock_gui( win );
458#if RETROWIN_TRACE_LVL > 0
459 debug_printf( RETROWIN_TRACE_LVL,
460 "refreshing window idx " SIZE_T_FMT
" with IDC " RETROGUI_IDC_FMT,
466 retrowin_unlock_gui( win );
471 if( autolock_stack ) {
488 ssize_t win_idx = -1;
490 if( !mdata_vector_is_locked( win_stack ) ) {
495 win_idx = retrowin_get_by_idc( idc_active, win_stack );
498 error_printf(
"polling missing window!" );
502 win = mdata_vector_get( win_stack, win_idx,
struct RETROWIN );
503 assert( NULL != win );
504 assert( idc_active == win->idc );
505 if( !retrowin_win_is_active( win ) ) {
507 error_printf(
"polling uninitialized window!" );
511 retrowin_lock_gui( win );
512 if( 0 != *p_input ) {
513#if RETROWIN_TRACE_LVL > 0
514 debug_printf( RETROWIN_TRACE_LVL,
515 "polling window idx " SIZE_T_FMT
" with IDC " RETROGUI_IDC_FMT,
520 retrowin_unlock_gui( win );
524 if( MERROR_OK != retval ) {
525 error_printf(
"error polling windows!" );
526 idc_out = RETROGUI_IDC_NONE;
542 ssize_t idx_out = -1;
546 ssize_t win_idx = -1;
548 if( !mdata_vector_is_locked( win_stack ) ) {
553 win_idx = retrowin_get_by_idc( idc_win, win_stack );
556 error_printf(
"polling invalid window!" );
560 win = mdata_vector_get( win_stack, win_idx,
struct RETROWIN );
561 assert( NULL != win );
562 assert( idc_win == win->idc );
563 if( !retrowin_win_is_active( win ) ) {
565 error_printf(
"polling inactive window!" );
569 retrowin_lock_gui( win );
570 idx_out = retrogui_get_ctl_sel_idx( win->gui_p, idc_ctl );
571 retrowin_unlock_gui( win );
575 if( MERROR_OK != retval ) {
576 error_printf(
"error getting window control selection index!" );
577 idx_out = merror_retval_to_sz( retval );
589void retrowin_free_win(
struct RETROWIN* win ) {
592 if( RETROWIN_FLAG_INIT_BMP == (RETROWIN_FLAG_INIT_BMP & win->flags) ) {
593#ifndef RETROWIN_NO_BITMAP
594 retroflat_2d_destroy_bitmap( &(win->gui_bmp) );
596 retrowin_lock_gui( win );
597 win->gui_p->draw_bmp = NULL;
598 retrowin_unlock_gui( win );
603 retrowin_lock_gui( win )
605 retrowin_unlock_gui( win )
606 maug_mfree( win->gui_h );
611 if( MERROR_OK != retval ) {
612 error_printf(
"error while locking self-managed GUI! not freed!" );
615 maug_mzero( win,
sizeof(
struct RETROWIN ) );
627 win = mdata_vector_get( win_stack, 0,
struct RETROWIN );
628 assert( NULL != win );
629 retrowin_free_win( win );
636 mdata_vector_free( win_stack );
645ssize_t retrowin_get_by_idc(
648 ssize_t idx_out = -1;
658 if( !mdata_vector_is_locked( win_stack ) ) {
664 win = mdata_vector_get( win_stack, i,
struct RETROWIN );
665 if( idc == win->idc ) {
677 if( MERROR_OK != retval ) {
678 idx_out = merror_retval_to_sz( retval );
694 ssize_t idx_out = -1;
698 retroflat_screen_w() < x + w || retroflat_screen_h() < y + h
700 error_printf(
"attempting to create window with IDC " RETROGUI_IDC_FMT
701 " offscreen at %d, %d (%d x %d)", idc, x, y, w, h );
706 idx_out = retrowin_get_by_idc( idc, win_stack );
709 "window with IDC " RETROGUI_IDC_FMT
" already exists!", idc );
714 maug_mzero( &win,
sizeof(
struct RETROWIN ) );
721#if RETROWIN_TRACE_LVL > 0
722 debug_printf( RETROWIN_TRACE_LVL,
723 "creating self-owned GUI for window with IDC " RETROGUI_IDC_FMT
": "
724 PXXY_FMT
"x" PXXY_FMT
" @ " PXXY_FMT
", " PXXY_FMT,
729 maug_malloc_test( win.gui_h, 1,
sizeof(
struct RETROGUI ) );
733 debug_printf( RETROWIN_TRACE_LVL,
"x0" );
736 retrowin_lock_gui( &win );
738 debug_printf( RETROWIN_TRACE_LVL,
"x1" );
741 maug_cleanup_if_not_ok();
743 debug_printf( RETROWIN_TRACE_LVL,
"x2" );
746 maug_cleanup_if_not_ok();
748 debug_printf( RETROWIN_TRACE_LVL,
"x3" );
751#ifndef RETROWIN_NO_BITMAP
752 retval = retroflat_2d_create_bitmap( w, h, &(win.gui_bmp), 0 );
753 maug_cleanup_if_not_ok();
756 win.flags |= RETROWIN_FLAG_INIT_BMP;
770#if RETROWIN_TRACE_LVL > 0
771 debug_printf( RETROWIN_TRACE_LVL,
772 "pushing window with IDC " RETROGUI_IDC_FMT
": "
773 PXXY_FMT
"x" PXXY_FMT
" @ " PXXY_FMT
", " PXXY_FMT,
774 win.idc, win.gui_p->w, win.gui_p->h, win.gui_p->x, win.gui_p->y );
777 retrowin_unlock_gui( &win );
787 "non-square window created; some systems may have trouble!" );
795 retrowin_unlock_gui( &win );
811#if RETROWIN_TRACE_LVL > 0
812 debug_printf( RETROWIN_TRACE_LVL,
813 "attempting to destroy window with IDC " RETROGUI_IDC_FMT, idc );
816 if( !mdata_vector_is_locked( win_stack ) ) {
822 win = mdata_vector_get( win_stack, i,
struct RETROWIN );
823 assert( NULL != win );
824 if( idc != win->idc ) {
828 if( !retrowin_win_is_active( win ) ) {
829#if RETROWIN_TRACE_LVL > 0
830 debug_printf( RETROWIN_TRACE_LVL,
831 "window with IDC " RETROGUI_IDC_FMT
832 " found, but not active! (flags: 0x%02x)",
838#if RETROWIN_TRACE_LVL > 0
839 debug_printf( RETROWIN_TRACE_LVL,
840 "freeing window with IDC " RETROGUI_IDC_FMT, win->idc );
843 retrowin_free_win( win );
uint16_t MERROR_RETVAL
Return type indicating function returns a value from this list.
Definition: merror.h:28
char maug_path[MAUG_PATH_SZ_MAX]
Path/name used to load an asset from disk or access other files.
Definition: mfile.h:141
#define RETROFLAT_FLAGS_FILL
Flag for retroflat_rect() or retroflat_ellipse(), indicating drawn shape should be filled.
Definition: retroflt.h:374
int16_t retroflat_pxxy_t
Type used for surface pixel coordinates.
Definition: retroflt.h:879
retrogui_idc_t retrogui_poll_ctls(struct RETROGUI *gui, RETROFLAT_IN_KEY *p_input, struct RETROFLAT_INPUT *input_evt)
Poll for the last clicked control and maintain listboxes and menus.
MERROR_RETVAL retrogui_set_font(struct RETROGUI *gui, const maug_path font_path)
Load the RetroFont API for the given RETROGUI to draw its controls with. Use RetroGXCache API if avai...
MERROR_RETVAL retrogui_destroy(struct RETROGUI *gui)
Free memory held by a RETROGUI controller internally and clean up any subordinate controls.
MERROR_RETVAL retrogui_init(struct RETROGUI *gui)
Prepare a RETROGUI controller for use.
int16_t retrogui_idc_t
Unique identifying constant number for controls.
Definition: retrogui.h:330
#define RETROGUI_COLOR_BORDER
RetroGUI will try to use this color on non-monochrome systems instead of black to draw things like bo...
Definition: retrogui.h:93
retrogui_idc_t retrowin_poll_win_stack(struct MDATA_VECTOR *win_stack, retrogui_idc_t idc_active, RETROFLAT_IN_KEY *p_input, struct RETROFLAT_INPUT *input_evt)
Given the outputs of the input poller, check the controls on the active window to see if the inputs t...
MERROR_RETVAL retrowin_refresh_win_stack(struct MDATA_VECTOR *win_stack)
Force all windows on the stack to redraw.
MERROR_RETVAL retrowin_destroy_win(struct MDATA_VECTOR *win_stack, retrogui_idc_t idc)
Destroy the given window's resources and remove it from the window stack.
ssize_t retrowin_get_win_stack_sel_idx(struct MDATA_VECTOR *win_stack, retrogui_idc_t idc_win, retrogui_idc_t idc_ctl)
Get the selected index of the given control in the given window from the window stack.
ssize_t retrowin_push_win(struct RETROGUI *gui, struct MDATA_VECTOR *win_stack, retrogui_idc_t idc, const maug_path font_filename, retroflat_pxxy_t x, retroflat_pxxy_t y, retroflat_pxxy_t w, retroflat_pxxy_t h, uint8_t flags)
Create a new window on the given win_stack.
ssize_t mdata_vector_append(struct MDATA_VECTOR *v, const void *item, size_t item_sz)
Append an item to the specified vector.
MERROR_RETVAL mdata_vector_remove(struct MDATA_VECTOR *v, size_t idx)
Remove item at the given index, shifting subsequent items up by 1.
A vector of uniformly-sized objects, stored contiguously.
Definition: mdata.h:108
#define mdata_vector_lock(v)
Lock the vector. This should be done when items from the vector are actively being referenced,...
Definition: mdata.h:372
#define mdata_vector_unlock(v)
Unlock the vector so items may be added and removed.
Definition: mdata.h:405
#define mdata_vector_ct(v)
Number of items of MDATA_VECTOR::item_sz bytes actively stored in this vector.
Definition: mdata.h:448
Definition: retrogui.h:468
#define RETROGUI_FLAGS_DIRTY
RETROGUI::flags indicating controls should be redrawn.
Definition: retrogui.h:263
Definition: retrowin.h:99
#define RETROWIN_FLAG_INIT_GUI
Flag for RETROWIN::flags indicating RETROWIN::gui_p should be locked from RETROWIN::gui_h before use.
Definition: retrowin.h:58