maug
Quick and dirty C mini-augmentation library.
Loading...
Searching...
No Matches
retrowin.h
Go to the documentation of this file.
1
2#ifndef RETROW3D_H
3#define RETROW3D_H
4
48
49#ifndef RETROWIN_TRACE_LVL
50# define RETROWIN_TRACE_LVL 0
51#endif /* !RETROWIN_TRACE_LVL */
52
58#define RETROWIN_FLAG_INIT_GUI 0x10
59
60#define RETROWIN_FLAG_INIT_BMP 0x20
61
62#define RETROWIN_FLAG_GUI_LOCKED 0x04
63
64#define RETROWIN_FLAG_BORDER_NONE 0x00
65#define RETROWIN_FLAG_BORDER_GRAY 0x01
66#define RETROWIN_FLAG_BORDER_BLUE 0x02
67
68#define retrowin_win_is_active( win ) \
69 (RETROWIN_FLAG_INIT_BMP == (RETROWIN_FLAG_INIT_BMP & (win)->flags))
70
71#define RETROWIN_FLAG_BORDER_MASK 0x03
72
73#define retrowin_lock_gui( win ) \
74 if( \
75 RETROWIN_FLAG_INIT_GUI == (RETROWIN_FLAG_INIT_GUI & (win)->flags) && \
76 RETROWIN_FLAG_GUI_LOCKED != (RETROWIN_FLAG_GUI_LOCKED & (win)->flags) \
77 ) { \
78 maug_mlock( (win)->gui_h, (win)->gui_p ); \
79 maug_cleanup_if_null_lock( struct RETROGUI*, (win)->gui_p ); \
80 (win)->flags |= RETROWIN_FLAG_GUI_LOCKED; \
81 }
82
83#define retrowin_unlock_gui( win ) \
84 if( \
85 RETROWIN_FLAG_INIT_GUI == (RETROWIN_FLAG_INIT_GUI & (win)->flags) && \
86 RETROWIN_FLAG_GUI_LOCKED == (RETROWIN_FLAG_GUI_LOCKED & (win)->flags) \
87 ) { \
88 maug_munlock( (win)->gui_h, (win)->gui_p ); \
89 (win)->flags &= ~RETROWIN_FLAG_GUI_LOCKED; \
90 }
91
92#define retrowin_gui_is_locked( win ) \
93 (RETROWIN_FLAG_INIT_GUI == (RETROWIN_FLAG_INIT_GUI & (win)->flags) && \
94 RETROWIN_FLAG_GUI_LOCKED == (RETROWIN_FLAG_GUI_LOCKED & (win)->flags))
95
96struct RETROWIN {
97 uint8_t flags;
101 MAUG_MHANDLE gui_h;
102 struct RETROGUI* gui_p;
103#ifndef RETROWIN_NO_BITMAP
104 retroflat_blit_t gui_bmp;
105#endif /* !RETROWIN_NO_BITMAP */
106};
107
108MERROR_RETVAL retrowin_redraw_win_stack( struct MDATA_VECTOR* win_stack );
109
114
130 struct MDATA_VECTOR* win_stack, retrogui_idc_t idc_active,
131 RETROFLAT_IN_KEY* p_input, struct RETROFLAT_INPUT* input_evt );
132
138 struct MDATA_VECTOR* win_stack,
139 retrogui_idc_t idc_win, retrogui_idc_t idc_ctl );
140
141void retrowin_free_win( struct RETROWIN* win );
142
143MERROR_RETVAL retrowin_free_all_win( struct MDATA_VECTOR* win_stack );
144
145ssize_t retrowin_get_by_idc(
146 retrogui_idc_t idc, struct MDATA_VECTOR* win_stack );
147
159 struct RETROGUI* gui, struct MDATA_VECTOR* win_stack,
160 retrogui_idc_t idc, const maug_path font_filename,
162 retroflat_pxxy_t w, retroflat_pxxy_t h, uint8_t flags );
163
170 struct MDATA_VECTOR* win_stack, retrogui_idc_t idc );
171
172#ifdef RETROW3D_C
173
174static MERROR_RETVAL _retrowin_draw_border( struct RETROWIN* win ) {
175 MERROR_RETVAL retval = MERROR_OK;
176 uint8_t autolock_gui = 0;
177
178#if RETROWIN_TRACE_LVL > 0
179 debug_printf( RETROWIN_TRACE_LVL, "drawing window border..." );
180#endif /* RETROWIN_TRACE_LVL */
181
182 if( !retrowin_gui_is_locked( win ) ) {
183 retrowin_lock_gui( win );
184 autolock_gui = 1;
185 }
186
187 switch( RETROWIN_FLAG_BORDER_MASK & win->flags ) {
188 case RETROWIN_FLAG_BORDER_NONE:
189 retroflat_2d_rect(
190 win->gui_p->draw_bmp, RETROFLAT_COLOR_BLACK,
191 win->gui_p->x,
192 win->gui_p->y,
193 win->gui_p->w,
194 win->gui_p->h,
196 break;
197
198 case RETROWIN_FLAG_BORDER_GRAY:
199 retroflat_2d_rect(
200 win->gui_p->draw_bmp,
201 2 < retroflat_screen_colors() ?
202 RETROFLAT_COLOR_GRAY : RETROFLAT_COLOR_WHITE,
203 win->gui_p->x,
204 win->gui_p->y,
205 win->gui_p->w,
206 win->gui_p->h,
208
209 /* Draw the border. */
210 retroflat_2d_rect(
211 win->gui_p->draw_bmp,
212 2 < retroflat_screen_colors() ?
213 RETROGUI_COLOR_BORDER : RETROFLAT_COLOR_BLACK,
214 win->gui_p->x,
215 win->gui_p->y,
216 win->gui_p->w,
217 win->gui_p->h,
218 0 );
219 if( 2 < retroflat_screen_colors() ) {
220 /* Draw highlight lines only visible in >2-color mode. */
221 retroflat_2d_line(
222 win->gui_p->draw_bmp, RETROFLAT_COLOR_WHITE,
223 win->gui_p->x + 1,
224 win->gui_p->y + 1,
225 win->gui_p->x + win->gui_p->w - 2,
226 win->gui_p-> y + 1,
227 0 );
228 retroflat_2d_line(
229 win->gui_p->draw_bmp, RETROFLAT_COLOR_WHITE,
230 win->gui_p->x + 1,
231 win->gui_p->y + 2,
232 win->gui_p->x + 1,
233 win->gui_p->y + win->gui_p->h - 3,
234 0 );
235 }
236 break;
237
238 case RETROWIN_FLAG_BORDER_BLUE:
239 retroflat_2d_rect(
240 win->gui_p->draw_bmp,
241 2 < retroflat_screen_colors() ?
242 RETROFLAT_COLOR_BLUE : RETROFLAT_COLOR_BLACK,
243 win->gui_p->x,
244 win->gui_p->y,
245 win->gui_p->w,
246 win->gui_p->h,
248
249 /* Draw the border. */
250 retroflat_2d_rect(
251 win->gui_p->draw_bmp,
252 2 < retroflat_screen_colors() ?
253 RETROGUI_COLOR_BORDER : RETROFLAT_COLOR_BLACK,
254 win->gui_p->x + 2,
255 win->gui_p->y + 2,
256 win->gui_p->w - 4,
257 win->gui_p->h - 4,
258 0 );
259 retroflat_2d_rect(
260 win->gui_p->draw_bmp, RETROFLAT_COLOR_WHITE,
261 win->gui_p->x + 1,
262 win->gui_p->y + 1,
263 win->gui_p->w - 2,
264 win->gui_p->h - 2,
265 0 );
266 retroflat_2d_rect(
267 win->gui_p->draw_bmp,
268 2 < retroflat_screen_colors() ?
269 RETROGUI_COLOR_BORDER : RETROFLAT_COLOR_BLACK,
270 win->gui_p->x,
271 win->gui_p->y,
272 win->gui_p->w,
273 win->gui_p->h,
274 0 );
275 break;
276 }
277
278#if RETROWIN_TRACE_LVL > 0
279 debug_printf( RETROWIN_TRACE_LVL, "drawing window border complete!" );
280#endif /* RETROWIN_TRACE_LVL */
281
282cleanup:
283
284 if( autolock_gui ) {
285 retrowin_unlock_gui( win );
286 }
287
288 return retval;
289}
290
291/* === */
292
293static MERROR_RETVAL _retrowin_redraw_win( struct RETROWIN* win ) {
294 MERROR_RETVAL retval = MERROR_OK;
295 uint8_t autolock_gui = 0;
296
297 if( !retrowin_gui_is_locked( win ) ) {
298 retrowin_lock_gui( win );
299 autolock_gui = 1;
300 }
301
302 /* Dirty detection is in retrogui_redraw_ctls(). */
303
304#ifdef RETROWIN_NO_BITMAP
305 win->gui_p->draw_bmp = NULL;
306#else
307 retroflat_2d_lock_bitmap( &(win->gui_bmp) );
308 win->gui_p->draw_bmp = &(win->gui_bmp);
309#endif /* RETROWIN_NO_BITMAP */
310
311#if RETROWIN_TRACE_LVL > 0
312 debug_printf( RETROWIN_TRACE_LVL,
313 "redrawing window IDC " RETROGUI_IDC_FMT " at "
314 PXXY_FMT ", " PXXY_FMT "...",
315 win->idc, win->gui_p->x, win->gui_p->y );
316#endif /* RETROWIN_TRACE_LVL */
317
318#ifndef RETROWIN_NO_BITMAP
319 /* This is a bit of a hack... Set X/Y to 0 so that we draw at the top
320 * of the bitmap that will be used as a texture. Reset it below so input
321 * detection works!
322 */
323 win->gui_p->x = 0;
324 win->gui_p->y = 0;
325#endif /* !RETROWIN_NO_BITMAP */
326 retval = _retrowin_draw_border( win );
327 if( MERROR_OK == retval ) {
328 retval = retrogui_redraw_ctls( win->gui_p );
329 }
330#ifndef RETROWIN_NO_BITMAP
331 win->gui_p->x = win->x;
332 win->gui_p->y = win->y;
333
334 retroflat_2d_release_bitmap( &(win->gui_bmp) );
335#endif /* !RETROWIN_NO_BITMAP */
336
337 maug_cleanup_if_not_ok();
338
339#if RETROWIN_TRACE_LVL > 0
340 debug_printf( RETROWIN_TRACE_LVL,
341 "redraw of window IDC " RETROGUI_IDC_FMT " at "
342 PXXY_FMT ", " PXXY_FMT " complete!",
343 win->idc, win->gui_p->x, win->gui_p->y );
344#endif /* RETROWIN_TRACE_LVL */
345
346cleanup:
347
348 if( autolock_gui ) {
349 retrowin_unlock_gui( win );
350 }
351
352 return retval;
353}
354
355/* === */
356
357MERROR_RETVAL retrowin_redraw_win_stack( struct MDATA_VECTOR* win_stack ) {
358 MERROR_RETVAL retval = MERROR_OK;
359 size_t i = 0;
360 struct RETROWIN* win = NULL;
361 uint8_t autolock_stack = 0;
362
363 if( 0 == mdata_vector_ct( win_stack ) ) {
364 goto cleanup;
365 }
366
367 if( !mdata_vector_is_locked( win_stack ) ) {
368 mdata_vector_lock( win_stack );
369 autolock_stack = 1;
370 }
371
372 for( i = 0 ; mdata_vector_ct( win_stack ) > i ; i++ ) {
373 win = mdata_vector_get( win_stack, i, struct RETROWIN );
374 assert( NULL != win );
375
376 if( !retrowin_win_is_active( win ) ) {
377 continue;
378 }
379
380 retrowin_lock_gui( win );
381
382#ifndef RETROWIN_NO_BITMAP
383 if(
384 RETROGUI_FLAGS_DIRTY == (RETROGUI_FLAGS_DIRTY & win->gui_p->flags)
385 ) {
386#endif /* !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,
390 i, win->idc );
391#endif /* RETROWIN_TRACE_LVL */
392
393 /* Redraw the window bitmap, including controls. */
394 retval = _retrowin_redraw_win( win );
395 maug_cleanup_if_not_ok();
396#ifndef RETROWIN_NO_BITMAP
397 }
398#endif /* !RETROWIN_NO_BITMAP */
399
400#ifndef RETROWIN_NO_BITMAP
401 /* Always blit the finished window to the screen, to compensate for e.g.
402 * the implicit screen-clearing of the engine loop.
403 */
404 retval = retroflat_2d_blit_win(
405 &(win->gui_bmp), win->gui_p->x, win->gui_p->y );
406#endif /* !RETROWIN_NO_BITMAP */
407
408 retrowin_unlock_gui( win );
409
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
413 " complete!",
414 i, win->idc );
415#endif /* RETROWIN_TRACE_LVL */
416 }
417
418#if RETROWIN_TRACE_LVL > 0
419 debug_printf( RETROWIN_TRACE_LVL, "redraw of all windows complete!" );
420#endif /* RETROWIN_TRACE_LVL */
421
422cleanup:
423
424 if( autolock_stack ) {
425 mdata_vector_unlock( win_stack );
426 }
427
428 return retval;
429}
430
431/* === */
432
434 MERROR_RETVAL retval = MERROR_OK;
435 size_t i = 0;
436 struct RETROWIN* win = NULL;
437 uint8_t autolock_stack = 0;
438
439 if( 0 == mdata_vector_ct( win_stack ) ) {
440 goto cleanup;
441 }
442
443 if( !mdata_vector_is_locked( win_stack ) ) {
444 mdata_vector_lock( win_stack );
445 autolock_stack = 1;
446 }
447
448 for( i = 0 ; mdata_vector_ct( win_stack ) > i ; i++ ) {
449 win = mdata_vector_get( win_stack, i, struct RETROWIN );
450 assert( NULL != win );
451
452 if( !retrowin_win_is_active( win ) ) {
453 continue;
454 }
455
456 retrowin_lock_gui( win );
457
458#if RETROWIN_TRACE_LVL > 0
459 debug_printf( RETROWIN_TRACE_LVL,
460 "refreshing window idx " SIZE_T_FMT " with IDC " RETROGUI_IDC_FMT,
461 i, win->idc );
462#endif /* RETROWIN_TRACE_LVL */
463
464 win->gui_p->flags |= RETROGUI_FLAGS_DIRTY;
465
466 retrowin_unlock_gui( win );
467 }
468
469cleanup:
470
471 if( autolock_stack ) {
472 mdata_vector_unlock( win_stack );
473 }
474
475 return retval;
476}
477
478/* === */
479
481 struct MDATA_VECTOR* win_stack, retrogui_idc_t idc_active,
482 RETROFLAT_IN_KEY* p_input, struct RETROFLAT_INPUT* input_evt
483) {
484 retrogui_idc_t idc_out = RETROGUI_IDC_NONE;
485 MERROR_RETVAL retval = MERROR_OK;
486 struct RETROWIN* win = NULL;
487 int autolock = 0;
488 ssize_t win_idx = -1;
489
490 if( !mdata_vector_is_locked( win_stack ) ) {
491 mdata_vector_lock( win_stack );
492 autolock = 1;
493 }
494
495 win_idx = retrowin_get_by_idc( idc_active, win_stack );
496 if( 0 > win_idx ) {
497 /* No window found! */
498 error_printf( "polling missing window!" );
499 retval = MERROR_GUI;
500 goto cleanup;
501 }
502
503 win = mdata_vector_get( win_stack, win_idx, struct RETROWIN );
504 assert( NULL != win );
505 assert( idc_active == win->idc );
506 if( !retrowin_win_is_active( win ) ) {
507 /* Window not initialized! */
508 error_printf( "polling uninitialized window!" );
509 retval = MERROR_GUI;
510 goto cleanup;
511 }
512
513 retrowin_lock_gui( win );
514 if( 0 != *p_input ) {
515#if RETROWIN_TRACE_LVL > 0
516 debug_printf( RETROWIN_TRACE_LVL,
517 "polling window idx " SIZE_T_FMT " with IDC " RETROGUI_IDC_FMT,
518 win_idx, win->idc );
519#endif /* RETROWIN_TRACE_LVL */
520 }
521 idc_out = retrogui_poll_ctls( win->gui_p, p_input, input_evt );
522 retrowin_unlock_gui( win );
523
524cleanup:
525
526 if( MERROR_OK != retval ) {
527 error_printf( "error polling windows!" );
528 idc_out = merror_retval_to_sz( retval );
529 }
530
531 if( autolock ) {
532 mdata_vector_unlock( win_stack );
533 }
534
535 return idc_out;
536}
537
538/* === */
539
541 struct MDATA_VECTOR* win_stack,
542 retrogui_idc_t idc_win, retrogui_idc_t idc_ctl
543) {
544 ssize_t idx_out = -1;
545 MERROR_RETVAL retval = MERROR_OK;
546 struct RETROWIN* win = NULL;
547 int autolock = 0;
548 ssize_t win_idx = -1;
549
550 if( !mdata_vector_is_locked( win_stack ) ) {
551 mdata_vector_lock( win_stack );
552 autolock = 1;
553 }
554
555 win_idx = retrowin_get_by_idc( idc_win, win_stack );
556 if( 0 > win_idx ) {
557 /* No window found! */
558 error_printf( "polling invalid window!" );
559 goto cleanup;
560 }
561
562 win = mdata_vector_get( win_stack, win_idx, struct RETROWIN );
563 assert( NULL != win );
564 assert( idc_win == win->idc );
565 if( !retrowin_win_is_active( win ) ) {
566 /* Window not active! */
567 error_printf( "polling inactive window!" );
568 goto cleanup;
569 }
570
571 retrowin_lock_gui( win );
572 idx_out = retrogui_get_ctl_sel_idx( win->gui_p, idc_ctl );
573 retrowin_unlock_gui( win );
574
575cleanup:
576
577 if( MERROR_OK != retval ) {
578 error_printf( "error getting window control selection index!" );
579 idx_out = merror_retval_to_sz( retval );
580 }
581
582 if( autolock ) {
583 mdata_vector_unlock( win_stack );
584 }
585
586 return idx_out;
587}
588
589/* === */
590
591void retrowin_free_win( struct RETROWIN* win ) {
592 MERROR_RETVAL retval = MERROR_OK;
593
594 if( RETROWIN_FLAG_INIT_BMP == (RETROWIN_FLAG_INIT_BMP & win->flags) ) {
595#ifndef RETROWIN_NO_BITMAP
596 retroflat_2d_destroy_bitmap( &(win->gui_bmp) );
597#endif /* !RETROWIN_NO_BITMAP */
598 retrowin_lock_gui( win );
599 win->gui_p->draw_bmp = NULL;
600 retrowin_unlock_gui( win );
601 }
602
603 if( RETROWIN_FLAG_INIT_GUI == (RETROWIN_FLAG_INIT_GUI & win->flags) ) {
604 /* This GUI was created by a NULL to push_win(). */
605 retrowin_lock_gui( win )
606 retrogui_destroy( win->gui_p );
607 retrowin_unlock_gui( win )
608 maug_mfree( win->gui_h );
609 }
610
611cleanup:
612
613 if( MERROR_OK != retval ) {
614 error_printf( "error while locking self-managed GUI! not freed!" );
615 }
616
617 maug_mzero( win, sizeof( struct RETROWIN ) );
618}
619
620/* === */
621
622MERROR_RETVAL retrowin_free_all_win( struct MDATA_VECTOR* win_stack ) {
623 MERROR_RETVAL retval = MERROR_OK;
624 struct RETROWIN* win = NULL;
625
626 if( 0 < mdata_vector_ct( win_stack ) ) {
627 mdata_vector_lock( win_stack );
628 while( 0 < mdata_vector_ct( win_stack ) ) {
629 win = mdata_vector_get( win_stack, 0, struct RETROWIN );
630 assert( NULL != win );
631 retrowin_free_win( win );
632 mdata_vector_unlock( win_stack );
633 mdata_vector_remove( win_stack, 0 );
634 mdata_vector_lock( win_stack );
635 }
636 mdata_vector_unlock( win_stack );
637 }
638 mdata_vector_free( win_stack );
639
640cleanup:
641
642 return retval;
643}
644
645/* === */
646
647ssize_t retrowin_get_by_idc(
648 retrogui_idc_t idc, struct MDATA_VECTOR* win_stack
649) {
650 ssize_t idx_out = -1;
651 int autolock = 0;
652 size_t i = 0;
653 struct RETROWIN const* win = NULL;
654 MERROR_RETVAL retval = MERROR_OK;
655
656 if( 0 == mdata_vector_ct( win_stack ) ) {
657 goto cleanup;
658 }
659
660 if( !mdata_vector_is_locked( win_stack ) ) {
661 mdata_vector_lock( win_stack );
662 autolock = 1;
663 }
664
665 for( i = 0 ; mdata_vector_ct( win_stack ) > i ; i++ ) {
666 win = mdata_vector_get( win_stack, i, struct RETROWIN );
667 if( idc == win->idc ) {
668 idx_out = i;
669 goto cleanup;
670 }
671 }
672
673cleanup:
674
675 if( autolock ) {
676 mdata_vector_unlock( win_stack );
677 }
678
679 if( MERROR_OK != retval ) {
680 idx_out = merror_retval_to_sz( retval );
681 }
682
683 return idx_out;
684}
685
686/* === */
687
688ssize_t retrowin_push_win(
689 struct RETROGUI* gui, struct MDATA_VECTOR* win_stack,
690 retrogui_idc_t idc, const maug_path font_filename,
692 retroflat_pxxy_t w, retroflat_pxxy_t h, uint8_t flags
693) {
694 MERROR_RETVAL retval = MERROR_OK;
695 struct RETROWIN win;
696 ssize_t idx_out = -1;
697
698 if( RETROGUI_IDC_NONE >= idc ) {
699 error_printf( "invalid IDC: %d", idc );
700 retval = MERROR_GUI;
701 goto cleanup;
702 }
703
704 if(
705 0 > x || 0 > y ||
706 retroflat_screen_w() < x + w || retroflat_screen_h() < y + h
707 ) {
708 error_printf( "attempting to create window with IDC " RETROGUI_IDC_FMT
709 " offscreen at %d, %d (%d x %d)", idc, x, y, w, h );
710 retval = MERROR_GUI;
711 goto cleanup;
712 }
713
714 idx_out = retrowin_get_by_idc( idc, win_stack );
715 if( 0 <= idx_out ) {
716 error_printf(
717 "window with IDC " RETROGUI_IDC_FMT " already exists!", idc );
718 retval = MERROR_GUI;
719 goto cleanup;
720 }
721
722 maug_mzero( &win, sizeof( struct RETROWIN ) );
723
724 win.flags = 0;
725
726 if( NULL != gui ) {
727 win.gui_p = gui;
728 } else {
729#if RETROWIN_TRACE_LVL > 0
730 debug_printf( RETROWIN_TRACE_LVL,
731 "creating self-owned GUI for window with IDC " RETROGUI_IDC_FMT ": "
732 PXXY_FMT "x" PXXY_FMT " @ " PXXY_FMT ", " PXXY_FMT,
733 idc, w, h, x, y );
734#endif /* RETROWIN_TRACE_LVL */
735
736 win.gui_p = NULL;
737 maug_malloc_test( win.gui_h, 1, sizeof( struct RETROGUI ) );
738
739 win.flags |= RETROWIN_FLAG_INIT_GUI;
740
741 debug_printf( RETROWIN_TRACE_LVL, "x0" );
742
743 /* Prepare gui_p for use as if it had just been assigned. */
744 retrowin_lock_gui( &win );
745
746 debug_printf( RETROWIN_TRACE_LVL, "x1" );
747
748 retval = retrogui_init( win.gui_p );
749 maug_cleanup_if_not_ok();
750
751 debug_printf( RETROWIN_TRACE_LVL, "x2" );
752
753 retval = retrogui_set_font( win.gui_p, font_filename );
754 maug_cleanup_if_not_ok();
755
756 debug_printf( RETROWIN_TRACE_LVL, "x3" );
757 }
758
759#ifndef RETROWIN_NO_BITMAP
760 retval = retroflat_2d_create_bitmap(
761 w, h, &(win.gui_bmp),
763 maug_cleanup_if_not_ok_msg( "error creating window bitmap!" );
764#endif /* !RETROWIN_NO_BITMAP */
765
766 win.flags |= RETROWIN_FLAG_INIT_BMP;
767
768 win.gui_p->w = w;
769 win.gui_p->h = h;
770 /* These might seem redundant, but check out retrowin_redraw_win()
771 * to see how they're used.
772 */
773 win.x = x;
774 win.y = y;
775 win.gui_p->x = x;
776 win.gui_p->y = y;
777 win.idc = idc;
778 win.flags |= flags;
779
780#if RETROWIN_TRACE_LVL > 0
781 debug_printf( RETROWIN_TRACE_LVL,
782 "pushing window with IDC " RETROGUI_IDC_FMT ": "
783 PXXY_FMT "x" PXXY_FMT " @ " PXXY_FMT ", " PXXY_FMT,
784 win.idc, win.gui_p->w, win.gui_p->h, win.gui_p->x, win.gui_p->y );
785#endif /* RETROWIN_TRACE_LVL */
786
787 retrowin_unlock_gui( &win );
788
789 idx_out = mdata_vector_append( win_stack, &win, sizeof( struct RETROWIN ) );
790 if( 0 > idx_out ) {
791 goto cleanup;
792 }
793
794 if( w != h ) {
795 /* TODO: Update to detect proportional windows. */
796 error_printf(
797 "non-square window created; some systems may have trouble!" );
798 }
799
800 retrowin_refresh_win_stack( win_stack );
801
802cleanup:
803
804 /* Unlock if unlock above was skipped due to error. */
805 retrowin_unlock_gui( &win );
806
807 return idx_out;
808}
809
810/* === */
811
813 struct MDATA_VECTOR* win_stack, retrogui_idc_t idc
814) {
815 size_t i = 0;
816 MERROR_RETVAL retval = MERROR_OK;
817 struct RETROWIN* win = NULL;
818 ssize_t i_free = -1;
819 int autolock = 0;
820
821#if RETROWIN_TRACE_LVL > 0
822 debug_printf( RETROWIN_TRACE_LVL,
823 "attempting to destroy window with IDC " RETROGUI_IDC_FMT, idc );
824#endif /* RETROWIN_TRACE_LVL */
825
826 if( !mdata_vector_is_locked( win_stack ) ) {
827 mdata_vector_lock( win_stack );
828 autolock = 1;
829 }
830
831 for( i = 0 ; mdata_vector_ct( win_stack ) > i ; i++ ) {
832 win = mdata_vector_get( win_stack, i, struct RETROWIN );
833 assert( NULL != win );
834 if( idc != win->idc ) {
835 continue;
836 }
837
838 if( !retrowin_win_is_active( win ) ) {
839#if RETROWIN_TRACE_LVL > 0
840 debug_printf( RETROWIN_TRACE_LVL,
841 "window with IDC " RETROGUI_IDC_FMT
842 " found, but not active! (flags: 0x%02x)",
843 idc, win->flags );
844#endif /* RETROWIN_TRACE_LVL */
845 continue;
846 }
847
848#if RETROWIN_TRACE_LVL > 0
849 debug_printf( RETROWIN_TRACE_LVL,
850 "freeing window with IDC " RETROGUI_IDC_FMT, win->idc );
851#endif /* RETROWIN_TRACE_LVL */
852
853 retrowin_free_win( win );
854
855 i_free = i;
856
857 break;
858 }
859
860 /* Remove the window from the vector if asked to. */
861 if( 0 <= i_free ) {
862 if( autolock ) {
863 mdata_vector_unlock( win_stack );
864 }
865 mdata_vector_remove( win_stack, i_free );
866 if( autolock ) {
867 mdata_vector_lock( win_stack );
868 }
869 }
870
871cleanup:
872
873 if( autolock ) {
874 mdata_vector_unlock( win_stack );
875 }
876
877 return retval;
878}
879
880#endif /* RETROW3D_C */
881 /* maug_retrowin */
883 /* maug_retroflt */
885
886#endif /* !RETROW3D_H */
887
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:138
#define RETROFLAT_BITMAP_FLAG_OPAQUE
Flag for retroflat_create_bitmap() or retroflat_load_bitmap() to create or load a bitmap without tran...
Definition retroflt.h:575
#define RETROFLAT_DRAW_FLAG_FILL
Flag for retroflat_rect() or retroflat_ellipse(), indicating drawn shape should be filled.
Definition retroflt.h:376
int16_t retroflat_pxxy_t
Type used for surface pixel coordinates.
Definition retroflt.h:925
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...
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.
#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
A vector of uniformly-sized objects, stored contiguously.
Definition mdata.h:108
Struct passed to retroflat_poll_input() to hold return data.
Definition retroflt.h:865
Definition retrogui.h:468
Definition retrowin.h:96