maug
Quick and dirty C mini-augmentation library.
Loading...
Searching...
No Matches
retroflt.h
Go to the documentation of this file.
1
2#ifndef RETROFLT_H
3#define RETROFLT_H
4
24
145
258
259/* === Generic Includes and Defines === */
260
261#ifndef RETROFLAT_BITMAP_TRACE_LVL
262# define RETROFLAT_BITMAP_TRACE_LVL 0
263#endif /* !RETROFLAT_BITMAP_TRACE_LVL */
264
265#ifndef RETROFLAT_KB_TRACE_LVL
266# define RETROFLAT_KB_TRACE_LVL 0
267#endif /* !RETROFLAT_KB_TRACE_LVL */
268
269#include <stdarg.h>
270
271#include <marge.h>
272
277
288#define RETROFLAT_COLOR_TABLE( f ) \
289 f( 0, black, BLACK, 0, 0, 0, BLACK, BLACK ) \
290 f( 1, darkblue, DARKBLUE, 0, 0, 170, CYAN, BLACK ) \
291 f( 2, darkgreen, DARKGREEN, 0, 170, 0, CYAN, BLACK ) \
292 f( 3, teal, TEAL, 0, 170, 170, CYAN, CYAN ) \
293 f( 4, darkred, DARKRED, 170, 0, 0, MAGENTA, BLACK ) \
294 f( 5, violet, VIOLET, 170, 0, 170, MAGENTA, BLACK ) \
295 f( 6, brown, BROWN, 170, 85, 0, CYAN, MAGENTA ) \
296 f( 7, gray, GRAY, 170, 170, 170, WHITE, BLACK ) \
297 f( 8, darkgray, DARKGRAY, 85, 85, 85, WHITE, BLACK ) \
298 f( 9, blue, BLUE, 85, 85, 255, CYAN, WHITE ) \
299 f( 10, green, GREEN, 85, 255, 85, CYAN, CYAN ) \
300 f( 11, cyan, CYAN, 85, 255, 255, CYAN, CYAN ) \
301 f( 12, red, RED, 255, 85, 85, MAGENTA, WHITE ) \
302 f( 13, magenta, MAGENTA, 255, 85, 255, MAGENTA, MAGENTA ) \
303 f( 14, yellow, YELLOW, 255, 255, 85, CYAN, MAGENTA ) \
304 f( 15, white, WHITE, 255, 255, 255, WHITE, WHITE )
305
307typedef int8_t RETROFLAT_COLOR;
308
309# define RETROFLAT_COLOR_NULL (-1)
310
311# define RETROFLAT_COLORS_SZ 16
312
314
315/* TODO: Mouse is broken under DOS/Allegro. */
316#if defined( RETROFLAT_OS_UNIX ) || defined( RETROFLAT_OS_WIN )
317#define RETROFLAT_MOUSE
318#endif /* RETROFLAT_OS_WIN || RETROFLAT_OS_WIN */
319
325
327#define RETROFLAT_OK 0x00
328#define RETROFLAT_ERROR_ENGINE 0x01
329#define RETROFLAT_ERROR_GRAPHICS 0x02
330#define RETROFLAT_ERROR_MOUSE 0x04
331
336#define RETROFLAT_ERROR_BITMAP 0x08
337#define RETROFLAT_ERROR_TIMER 0x0f
338 /* maug_retroflt_retval */
340
350
355#define RETROFLAT_FLAGS_FILL 0x01
356
361#define RETROFLAT_FLAGS_OPAQUE 0x01
362
369#define RETROFLAT_FLAGS_ALL_CAPS 0x02
370
374#define RETROFLAT_FLAGS_LITERAL_PATH 0x02
375
376#ifndef RETROFLAT_NO_STRING
383#define RETROFLAT_FLAGS_OUTLINE 0x04
384#endif /* !RETROFLAT_NO_STRING */
385
392#define RETROFLAT_FLAGS_SCREEN_BUFFER 0x80
393
398#define RETROFLAT_FLAGS_VIEWPORT_REFRESH 0x20
399 /* maug_retroflt_drawing */
401
407
413#define RETROFLAT_FLAGS_RUNNING 0x01
414
419#define RETROFLAT_FLAGS_UNLOCK_FPS 0x02
420
425#define RETROFLAT_FLAGS_KEY_REPEAT 0x04
426
431#define RETROFLAT_FLAGS_SCREENSAVER 0x08
432
436#define RETROFLAT_FLAGS_SCALE2X 0x10
437
441#define RETROFLAT_FLAGS_WAIT_FOR_FPS 0x20
442 /* maug_retroflt_flags */
444
451
453#define RETROFLAT_MSG_FLAG_TYPE_MASK 0x07
454
459#define RETROFLAT_MSG_FLAG_ERROR 0x01
460
466#define RETROFLAT_MSG_FLAG_INFO 0x02
467
473#define RETROFLAT_MSG_FLAG_WARNING 0x04
474 /* maug_retroflt_msg_flags */
476
477struct RETROFLAT_STATE;
478
490
498#define RETROFLAT_VDP_FLAG_PXLOCK 0x01
499
512 /* maug_retroflt_vdp */
514
515typedef MERROR_RETVAL (*retroflat_proc_resize_t)(
516 uint16_t new_w, uint16_t new_h, void* data );
517
522
523#define RETROSND_ARGS_FLAG_LIST_DEVS 0x01
524
526
552
556#define RETROFLAT_FLAGS_LOCK 0x01
557
558#define RETROFLAT_FLAGS_SCREEN_LOCK 0x02
559
560#define RETROFLAT_FLAGS_BITMAP_RO 0x04
561
567#define RETROFLAT_INSTANCE_NULL (0)
568
573#define retroflat_instance_tile( instance ) \
574 (instance * -1)
575
580#ifndef RETROFLAT_BITMAP_EXT
581# define RETROFLAT_BITMAP_EXT "bmp"
582#endif /* !RETROFLAT_BITMAP_EXT */
583
584#ifndef RETROFLAT_OPENGL_BPP
585# define RETROFLAT_OPENGL_BPP 32
586#endif /* !RETROFLAT_OPENGL_BPP */
587
588#ifndef RETROFLAT_TILE_W
589# define RETROFLAT_TILE_W 16
590#endif /* !RETROFLAT_TILE_W */
591
592#ifndef RETROFLAT_TILE_W_BITS
593# define RETROFLAT_TILE_W_BITS 4
594#endif /* !RETROFLAT_TILE_W_BITS */
595
596#ifndef RETROFLAT_TILE_H
597# define RETROFLAT_TILE_H 16
598#endif /* !RETROFLAT_TILE_H */
599
600#ifndef RETROFLAT_TILE_H_BITS
601# define RETROFLAT_TILE_H_BITS 4
602#endif /* !RETROFLAT_TILE_H_BITS */
603
604/* Transparency background color: black by default, to match Allegro. */
605#ifndef RETROFLAT_TXP_R
611# define RETROFLAT_TXP_R 0x00
612#endif /* !RETROFLAT_TXP_R */
613
614#ifndef RETROFLAT_TXP_G
620# define RETROFLAT_TXP_G 0x00
621#endif /* !RETROFLAT_TXP_G */
622
623#ifndef RETROFLAT_TXP_B
629# define RETROFLAT_TXP_B 0x00
630#endif /* !RETROFLAT_TXP_B */
631
632#ifndef RETROFLAT_TXP_PAL_IDX
633# define RETROFLAT_TXP_PAL_IDX 0
634#endif /* !RETROFLAT_TXP_PAL_IDX */
635 /* maug_retroflt_bitmap */
637
638#ifndef RETROFLAT_DEFAULT_SCREEN_W
639# define RETROFLAT_DEFAULT_SCREEN_W 320
640#endif /* RETROFLAT_DEFAULT_SCREEN_W */
641
642#ifndef RETROFLAT_DEFAULT_SCREEN_H
643# define RETROFLAT_DEFAULT_SCREEN_H 200
644#endif /* RETROFLAT_DEFAULT_SCREEN_H */
645
646#ifndef RETROFLAT_GL_Z
647# define RETROFLAT_GL_Z -0.001
648#endif /* !RETROFLAT_GL_Z */
649
650#define retroflat_on_resize( w, h ) \
651 g_retroflat_state->screen_w = w; \
652 g_retroflat_state->screen_h = h;
653
658
659#ifndef RETROFLAT_LINE_THICKNESS
664# define RETROFLAT_LINE_THICKNESS 1
665#endif /* !RETROFLAT_LINE_THICKNESS */
666
667#define RETROFLAT_PI 3.14159
668 /* maug_retroflt_drawing */
670
675
676#ifndef RETROFLAT_FPS
681# define RETROFLAT_FPS 30
682#endif /* !RETROFLAT_FPS */
683
684#define retroflat_fps_next() (1000 / RETROFLAT_FPS)
685
686#ifndef RETROFLAT_WINDOW_CLASS
691# define RETROFLAT_WINDOW_CLASS "RetroFlatWindowClass"
692#endif /* !RETROFLAT_WINDOW_CLASS */
693
694#ifndef RETROFLAT_WIN_FRAME_TIMER_ID
699# define RETROFLAT_WIN_FRAME_TIMER_ID 6001
700#endif /* !RETROFLAT_WIN_FRAME_TIMER_ID */
701
702#ifndef RETROFLAT_WIN_LOOP_TIMER_ID
707# define RETROFLAT_WIN_LOOP_TIMER_ID 6002
708#endif /* !RETROFLAT_WIN_LOOP_TIMER_ID */
709
710#ifndef RETROFLAT_MSG_MAX
715# define RETROFLAT_MSG_MAX 4096
716#endif /* !RETROFLAT_MSG_MAX */
717
718#define RETROFLAT_PATH_MAX MAUG_PATH_MAX
719
720#ifndef RETROFLAT_TITLE_MAX
721# define RETROFLAT_TITLE_MAX 255
722#endif /* !RETROFLAT_TITLE_MAX */
723
724#ifndef RETROFLAT_VDP_ARGS_SZ_MAX
728# define RETROFLAT_VDP_ARGS_SZ_MAX 255
729#endif /* !RETROFLAT_VDP_ARGS_SZ_MAX */
730
731#if defined( RETROFLAT_API_SDL2 )
732# if !defined( NO_RETROFLAT_RESIZABLE )
733# define RETROFLAT_WIN_FLAGS SDL_WINDOW_RESIZABLE
734# else
735# define RETROFLAT_WIN_FLAGS 0
736# endif /* !NO_RETROFLAT_RESIZABLE */
737#endif /* RETROFLAT_API_SDL2 */
738
739#if defined( RETROFLAT_API_SDL1 )
740# define RETROFLAT_SDL_CC_FLAGS (SDL_RLEACCEL | SDL_SRCCOLORKEY)
741#elif defined( RETROFLAT_API_SDL2 )
742# define RETROFLAT_SDL_CC_FLAGS (SDL_TRUE)
743#endif /* RETROFLAT_API_SDL1 || RETROFLAT_API_SDL2 */
744
745#ifdef RETROFLAT_OS_DOS
746# define RETROFLAT_PATH_SEP '\\'
747#else
749# define RETROFLAT_PATH_SEP '/'
750#endif /* RETROFLAT_OS_DOS */
751
753#define RETROFLAT_ASSETS_PATH_MAX (RETROFLAT_PATH_MAX >> 1)
754
755#ifndef RETROFLAT_BMP_COLORS_SZ_MAX
756# define RETROFLAT_BMP_COLORS_SZ_MAX 256
757#endif /* !RETROFLAT_BMP_COLORS_SZ_MAX */
758 /* maug_retroflt_compiling */
760
761#define retroflat_wait_for_frame() \
762 (g_retroflat_state->retroflat_flags |= RETROFLAT_FLAGS_WAIT_FOR_FPS)
763
764#define retroflat_is_waiting_for_frame() \
765 (RETROFLAT_FLAGS_WAIT_FOR_FPS == \
766 (g_retroflat_state->retroflat_flags & RETROFLAT_FLAGS_WAIT_FOR_FPS))
767
774
778typedef char retroflat_asset_path[RETROFLAT_PATH_MAX];
779
783#define retroflat_cmp_asset_path( a, b ) strncmp( a, b, RETROFLAT_PATH_MAX )
784 /* maug_retroflt_assets */
786
790typedef void (*retroflat_loop_iter)(void* data);
791
797
801#define retroflat_buffer_bksp( buffer, buffer_cur, buffer_sz ) \
802 if( 0 < buffer_cur ) { \
803 if( buffer_cur < buffer_sz ) { \
804 memmove( \
805 &(buffer[(buffer_cur) - 1]), \
806 &(buffer[buffer_cur]), \
807 (buffer_sz) - (buffer_cur) ); \
808 } \
809 buffer_cur--; \
810 buffer_sz--; \
811 buffer[buffer_sz] = '\0'; \
812 }
813
817#define retroflat_buffer_insert( c, buffer, buffer_cur, buffer_sz, buffer_mx ) \
818 if( buffer_sz + 1 < buffer_mx ) { \
819 if( buffer_cur < buffer_sz ) { \
820 memmove( \
821 &(buffer[(buffer_cur) + 1]), \
822 &(buffer[buffer_cur]), \
823 (buffer_sz) - (buffer_cur) ); \
824 } \
825 buffer[buffer_cur] = c; \
826 buffer_cur++; \
827 buffer_sz++; \
828 buffer[buffer_sz] = '\0'; \
829 }
830
831#define RETROFLAT_INPUT_MOD_SHIFT 0x01
832
833#define RETROFLAT_INPUT_MOD_ALT 0x02
834
835#define RETROFLAT_INPUT_MOD_CTRL 0x04
836
837#define RETROFLAT_INPUT_FORCE_UPPER 0x08
838
851 uint8_t key_flags;
852};
853 /* maug_retroflt_input */
855
862
863#define RETROFLAT_DIR4_NORTH 0
864#define RETROFLAT_DIR4_EAST 1
865#define RETROFLAT_DIR4_SOUTH 2
866#define RETROFLAT_DIR4_WEST 3
867
868#define RETROFLAT_DIR8_NORTH 0
869#define RETROFLAT_DIR8_EAST 2
870#define RETROFLAT_DIR8_SOUTH 4
871#define RETROFLAT_DIR8_WEST 6
872
873#define retroflat_dir8_reverse( dir ) \
874 ((dir + 4) % 8)
875
876#define retroflat_dir8_bounce( dir ) \
877 ((dir + 2) % 8)
878 /* maug_retroflt_dir */
880
881#ifdef RETROFLAT_OPENGL
882struct RETROFLAT_GLTEX {
883 MAUG_MHANDLE bytes_h;
884 uint8_t* bytes;
885 uint32_t bpp;
886 uint32_t sz;
887 uint8_t* px;
888 uint32_t id;
889 size_t w;
890 size_t h;
891};
892#endif /* RETROFLAT_OPENGL */
893
894struct RETROFLAT_ARGS;
895
896#ifndef NO_RETROSND
897
925
926#ifndef RETROSND_TRACE_LVL
927# define RETROSND_TRACE_LVL 0
928#endif /* !RETROSND_TRACE_LVL */
929
930#ifndef RETROSND_REG_TRACE_LVL
931# define RETROSND_REG_TRACE_LVL 0
932#endif /* !RETROSND_REG_TRACE_LVL */
933
939
944#define RETROSND_FLAG_INIT 0x01
945 /* maug_retrosnd_flags */
947
948#define RETROSND_VOICE_BREATH 122
949
950#define RETROSND_VOICE_SEASHORE 123
951
952#define RETROSND_VOICE_BIRD_TWEET 124
953
954#define RETROSND_VOICE_PHONE_RING 125
955
956#define RETROSND_VOICE_HELICOPTER 126
957
958#define RETROSND_VOICE_APPLAUSE 127
959
964#define RETROSND_VOICE_GUNSHOT 128
965
966#define RETROSND_CHANNEL_CT 8
967
977
981void retrosnd_set_sf_bank( const char* filename_in );
982
983void retrosnd_midi_set_voice( uint8_t channel, uint8_t voice );
984
985void retrosnd_midi_set_control( uint8_t channel, uint8_t key, uint8_t val );
986
987void retrosnd_midi_note_on( uint8_t channel, uint8_t pitch, uint8_t vel );
988
989void retrosnd_midi_note_off( uint8_t channel, uint8_t pitch, uint8_t vel );
990
991MERROR_RETVAL retrosnd_midi_play_smf( const char* filename );
992
993uint8_t retrosnd_midi_is_playing_smf();
994
995void retrosnd_shutdown();
996 /* maug_retrosnd */
998
999#endif /* !NO_RETROSND */
1000
1001/* === OS-Specific Includes and Defines === */
1002
1003#if defined( RETROFLAT_OS_WIN ) && !defined( MAUG_WINDOWS_H )
1004# include <windows.h>
1005# define MAUG_WINDOWS_H
1006#endif /* !MAUG_WINDOWS_H */
1007
1008/* TODO: Migrate all platform-specific parts below to retapid.h. */
1009#include <retapid.h>
1010
1011typedef maug_ms_t retroflat_ms_t;
1012
1013/* === Structures === */
1014
1021 char* title;
1024 uint8_t flags;
1027# ifdef RETROFLAT_API_PC_BIOS
1029 uint8_t screen_mode;
1030# elif !defined( RETROFLAT_NO_CLI_SZ )
1031 int screen_w;
1038# endif /* RETROFLAT_API_PC_BIOS */
1039 uint8_t snd_flags;
1040# if defined( RETROSND_API_SDL1 ) || defined( RETROSND_API_SDL2 )
1041# elif defined( RETROSND_API_WINMM )
1042 UINT snd_dev_id;
1043# elif defined( RETROSND_API_PC_BIOS )
1044 uint16_t snd_io_base;
1045 uint8_t snd_driver;
1046# elif defined( RETROSND_API_ALSA )
1047 uint8_t snd_client;
1048 uint8_t snd_port;
1049# else
1050# pragma message( "warning: sound args not specified" )
1051# endif /* RETROSND_API_WINMM */
1052};
1053
1060
1061typedef int16_t retroflat_tile_t;
1062
1065 int16_t screen_x;
1067 int16_t screen_y;
1068 int16_t world_x;
1069 int16_t world_y;
1070 int16_t world_w;
1071 int16_t world_h;
1072 int16_t screen_tile_w;
1073 int16_t screen_tile_h;
1074 MAUG_MHANDLE refresh_grid_h;
1075 retroflat_tile_t* refresh_grid;
1076};
1077
1078#ifndef DOCUMENTATION
1079
1080# define retroflat_viewport_world_x_generic() \
1081 (g_retroflat_state->viewport.world_x)
1082
1083# define retroflat_viewport_world_y_generic() \
1084 (g_retroflat_state->viewport.world_y)
1085
1086# define retroflat_viewport_world_w_generic() \
1087 (g_retroflat_state->viewport.world_w)
1088
1089# define retroflat_viewport_world_h_generic() \
1090 (g_retroflat_state->viewport.world_h)
1091
1092# define retroflat_viewport_screen_tile_w_generic() \
1093 (g_retroflat_state->viewport.screen_tile_w)
1094
1095# define retroflat_viewport_screen_tile_h_generic() \
1096 (g_retroflat_state->viewport.screen_tile_h)
1097
1098# define retroflat_viewport_set_world_generic( w, h ) \
1099 (g_retroflat_state->viewport.world_w) = w; \
1100 (g_retroflat_state->viewport.world_h) = h;
1101
1102# define retroflat_viewport_set_world_pos_generic( x, y ) \
1103 (g_retroflat_state->viewport.world_x) = x; \
1104 (g_retroflat_state->viewport.world_y) = y;
1105
1106# define retroflat_viewport_lock_refresh_generic() \
1107 if( NULL == g_retroflat_state->viewport.refresh_grid ) { \
1108 maug_mlock( \
1109 g_retroflat_state->viewport.refresh_grid_h, \
1110 g_retroflat_state->viewport.refresh_grid ); \
1111 maug_cleanup_if_null_lock( retroflat_tile_t*, \
1112 g_retroflat_state->viewport.refresh_grid ); \
1113 }
1114
1115# define retroflat_viewport_unlock_refresh_generic() \
1116 if( NULL != g_retroflat_state->viewport.refresh_grid ) { \
1117 maug_munlock( \
1118 g_retroflat_state->viewport.refresh_grid_h, \
1119 g_retroflat_state->viewport.refresh_grid ); \
1120 }
1121
1122# define _retroflat_viewport_refresh_tile_x( x_px ) \
1123 (((x_px) + RETROFLAT_TILE_W) >> RETROFLAT_TILE_W_BITS)
1124
1125# define _retroflat_viewport_refresh_tile_y( y_px ) \
1126 (((y_px) + RETROFLAT_TILE_H) >> RETROFLAT_TILE_H_BITS)
1127
1128# define retroflat_viewport_set_refresh_generic( x_px, y_px, tid ) \
1129 assert( NULL != g_retroflat_state->viewport.refresh_grid ); \
1130 if( \
1131 /* Expand the range by -1 to account for just off-screen tile. */ \
1132 -(RETROFLAT_TILE_W) <= x_px && -(RETROFLAT_TILE_H) <= y_px && \
1133 retroflat_screen_w() > x_px && \
1134 retroflat_screen_h() > y_px \
1135 ) { \
1136 assert( 0 < g_retroflat_state->viewport.screen_tile_w ); \
1137 assert( 0 <= (((y_px) + RETROFLAT_TILE_H) >> RETROFLAT_TILE_H_BITS) ); \
1138 assert( 0 <= (((x_px) + RETROFLAT_TILE_W) >> RETROFLAT_TILE_W_BITS) ); \
1139 g_retroflat_state->viewport.refresh_grid[ \
1140 /* Add +1 tile to make off-screen "-1" tile positive. */ \
1141 (_retroflat_viewport_refresh_tile_y( y_px ) * \
1142 g_retroflat_state->viewport.screen_tile_w) + \
1143 _retroflat_viewport_refresh_tile_x( x_px )] = tid; \
1144 }
1145
1146# define retroflat_viewport_tile_is_stale( x_px, y_px, tile_id ) \
1147 ((tile_id) != \
1148 g_retroflat_state->viewport.refresh_grid[ \
1149 (_retroflat_viewport_refresh_tile_y( y_px ) * \
1150 g_retroflat_state->viewport.screen_tile_w) + \
1151 _retroflat_viewport_refresh_tile_x( x_px )])
1152
1153uint8_t retroflat_viewport_move_x_generic( int16_t x );
1154
1155uint8_t retroflat_viewport_move_y_generic( int16_t y );
1156
1157uint8_t retroflat_viewport_focus_generic(
1158 size_t x1, size_t y1, size_t range, size_t speed );
1159
1160# define retroflat_viewport_screen_x_generic( world_x ) \
1161 ((world_x) - retroflat_viewport_world_x())
1162
1163# define retroflat_viewport_screen_y_generic( world_y ) \
1164 ((world_y) - retroflat_viewport_world_y())
1165
1166#endif /* !DOCUMENTATION */
1167
1168#if defined( RETROFLAT_SOFT_VIEWPORT ) || defined( DOCUMENTATION )
1169
1170# ifdef RETROFLAT_VIEWPORT_ADAPT
1171 /* Clamp world coordinates to tile borders to allow refresh grid to
1172 * function properly.
1173 */
1174# define retroflat_viewport_world_x() \
1175 ((retroflat_viewport_world_x_generic() \
1176 >> RETROFLAT_TILE_W_BITS) << RETROFLAT_TILE_W_BITS)
1177# define retroflat_viewport_world_y() \
1178 ((retroflat_viewport_world_y_generic() \
1179 >> RETROFLAT_TILE_H_BITS) << RETROFLAT_TILE_H_BITS)
1180# else
1182# define retroflat_viewport_world_x() retroflat_viewport_world_x_generic()
1183
1185# define retroflat_viewport_world_y() retroflat_viewport_world_y_generic()
1186#endif /* RETROFLAT_VIEWPORT_ADAPT */
1187
1189# define retroflat_viewport_world_w() \
1190 retroflat_viewport_world_w_generic()
1191
1193# define retroflat_viewport_world_h() \
1194 retroflat_viewport_world_h_generic()
1195
1196# define retroflat_viewport_screen_tile_w() \
1197 retroflat_viewport_screen_tile_w_generic()
1198
1199# define retroflat_viewport_screen_tile_h() \
1200 retroflat_viewport_screen_tile_h_generic()
1201
1208# define retroflat_viewport_set_world( w, h ) \
1209 retroflat_viewport_set_world_generic( w, h )
1210
1211# define retroflat_viewport_set_world_pos( x, y ) \
1212 retroflat_viewport_set_world_pos_generic( x, y )
1213
1214# define retroflat_viewport_lock_refresh() \
1215 retroflat_viewport_lock_refresh_generic()
1216
1217# define retroflat_viewport_unlock_refresh() \
1218 retroflat_viewport_unlock_refresh_generic()
1219
1220# define retroflat_viewport_set_refresh( x, y, tid ) \
1221 retroflat_viewport_set_refresh_generic( x, y, tid )
1222
1235# define retroflat_viewport_focus( x1, y1, range, speed ) \
1236 retroflat_viewport_focus_generic( x1, y1, range, speed )
1237
1242# define retroflat_viewport_screen_x( world_x ) \
1243 retroflat_viewport_screen_x_generic( world_x )
1244
1249# define retroflat_viewport_screen_y( world_y ) \
1250 retroflat_viewport_screen_y_generic( world_y )
1251
1252# ifndef RETROFLAT_VIEWPORT_OVERRIDE_MOVE
1253# define retroflat_viewport_move_x( x ) \
1254 retroflat_viewport_move_x_generic( x )
1255
1256# define retroflat_viewport_move_y( y ) \
1257 retroflat_viewport_move_y_generic( y )
1258# endif /* !RETROFLAT_VIEWPORT_OVERRIDE_MOVE */
1259
1260#endif /* RETROFLAT_SOFT_VIEWPORT || DOCUMENTATION */
1261
1263
1266 void* loop_data;
1267 MERROR_RETVAL retval;
1270 char config_path[RETROFLAT_PATH_MAX + 1];
1271 char assets_path[RETROFLAT_ASSETS_PATH_MAX + 1];
1272 /* TODO: Make indirect palette optional per-platform. */
1274 RETROFLAT_COLOR_DEF palette[RETROFLAT_COLORS_SZ];
1277
1278# if defined( RETROFLAT_VDP ) || defined( DOCUMENTATION ) || \
1279defined( RETROVDP_C )
1285# ifdef RETROFLAT_OS_WIN
1286 HMODULE vdp_exe;
1287# else
1289 void* vdp_exe;
1290# endif /* RETROFLAT_OS_WIN */
1299 uint8_t vdp_flags;
1300# endif /* RETROFLAT_VDP || DOCUMENTATION || RETROVDP_C */
1301
1302 /* These are used by VDP so should be standardized/not put in plat-spec! */
1303
1304 struct RETROFLAT_VIEWPORT viewport;
1305
1321 size_t screen_w;
1323 size_t screen_h;
1324
1325 /* WARNING: The VDP requires the state specifier to be the same size
1326 * as the one it was compiled for! Do not modify above here!
1327 */
1328
1329 /* TODO: Put these in a platform-specific struct of some kind to maintain
1330 * consistent state struct size for VDP?
1331 */
1332
1333 retroflat_loop_iter loop_iter;
1334 retroflat_loop_iter frame_iter;
1335
1336 retroflat_proc_resize_t on_resize;
1337 void* on_resize_data;
1338
1339# if defined( RETROFLAT_OPENGL )
1340 uint8_t tex_palette[RETROFLAT_COLORS_SZ][3];
1341# endif /* RETROFLAT_OPENGL */
1342
1343 struct RETROFLAT_PLATFORM platform;
1344
1345#ifndef NO_RETROSND
1346 struct RETROFLAT_SOUND sound;
1347#endif /* !NO_RETROSND */
1348};
1349
1350/* === Translation Module === */
1351
1352/* Declare the prototypes so that internal functions can call each other. */
1353
1354# ifdef retroflat_loop
1355MERROR_RETVAL retroflat_loop_generic(
1356 retroflat_loop_iter frame_iter, retroflat_loop_iter loop_iter, void* data );
1357# else
1364 retroflat_loop_iter frame_iter, retroflat_loop_iter loop_iter, void* data );
1365# endif /* retroflat_loop */
1366
1374 uint8_t flags, const char* title, const char* format, ... );
1375
1383MERROR_RETVAL retroflat_init( int argc, char* argv[], struct RETROFLAT_ARGS* args );
1384
1391void retroflat_shutdown( int retval );
1392
1393# if defined( RETROFLAT_VDP ) || defined( DOCUMENTATION )
1398
1402MERROR_RETVAL retroflat_vdp_call( const char* proc_name );
1403 /* maug_retroflt_vdp */
1405# endif /* RETROFLAT_VDP || DOCUMENTATION */
1406
1407void retroflat_set_title( const char* format, ... );
1408
1409retroflat_ms_t retroflat_get_ms();
1410
1411uint32_t retroflat_get_rand();
1412
1413# if !defined( RETROFLAT_NO_KEYBOARD )
1414char retroflat_vk_to_ascii( RETROFLAT_IN_KEY k, uint8_t flags );
1415# endif /* !RETROFLAT_NO_KEYBOARD */
1416
1421
1433 const char* filename, struct RETROFLAT_BITMAP* bmp_out, uint8_t flags );
1434
1435MERROR_RETVAL retroflat_create_bitmap(
1436 size_t w, size_t h, struct RETROFLAT_BITMAP* bmp_out, uint8_t flags );
1437
1444
1459 struct RETROFLAT_BITMAP* target, struct RETROFLAT_BITMAP* src,
1460 size_t s_x, size_t s_y, int16_t d_x, int16_t d_y, size_t w, size_t h,
1461 int16_t instance );
1462
1470#define retroflat_constrain_px( x, y, bmp, retact ) \
1471 if( \
1472 x >= retroflat_bitmap_w( bmp ) || y >= retroflat_bitmap_h( bmp ) \
1473 ) { retact; }
1474 /* maug_retroflt_bitmap */
1476
1481
1492
1493MERROR_RETVAL retroflat_draw_release( struct RETROFLAT_BITMAP* bmp );
1494
1495void retroflat_px(
1496 struct RETROFLAT_BITMAP* target, const RETROFLAT_COLOR color,
1497 size_t x, size_t y, uint8_t flags );
1498
1499#ifdef RETROFLAT_SOFT_SHAPES
1500# ifdef RETROFLAT_OPENGL
1501/* Make sure we're not passing NULL to openGL texture drawers... they can't
1502 * handle that!
1503 */
1504# define retroflat_rect( t, c, x, y, w, h, f ) \
1505 assert( NULL != t ); \
1506 retrosoft_rect( t, c, x, y, w, h, f );
1507# define retroflat_ellipse( t, c, x, y, w, h, f ) \
1508 assert( NULL != t ); \
1509 retrosoft_ellipse( t, c, x, y, w, h, f )
1510# else
1511# define retroflat_rect( t, c, x, y, w, h, f ) \
1512 retrosoft_rect( t, c, x, y, w, h, f )
1513# define retroflat_ellipse( t, c, x, y, w, h, f ) \
1514 retrosoft_ellipse( t, c, x, y, w, h, f )
1515# endif /* RETROFLAT_OPENGL */
1516#else
1517
1529 struct RETROFLAT_BITMAP* target, const RETROFLAT_COLOR color,
1530 int16_t x, int16_t y, int16_t w, int16_t h, uint8_t flags );
1531
1543 struct RETROFLAT_BITMAP* target, const RETROFLAT_COLOR color,
1544 int16_t x, int16_t y, int16_t w, int16_t h, uint8_t flags );
1545
1546#endif /* RETROFLAT_SOFT_SHAPES */
1547
1548#ifdef RETROFLAT_SOFT_LINES
1549# define retroflat_line( t, c, x1, y1, x2, y2, f ) \
1550 retrosoft_line( t, c, x1, y1, x2, y2, f )
1551#else
1552
1565 struct RETROFLAT_BITMAP* target, const RETROFLAT_COLOR color,
1566 int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint8_t flags );
1567
1568#endif /* RETROFLAT_SOFT_LINES */
1569
1570void retroflat_cursor( struct RETROFLAT_BITMAP* target, uint8_t flags );
1571
1585 struct RETROFLAT_BITMAP* target, const char* str, size_t str_sz,
1586 const char* font_str, size_t* w_out, size_t* h_out, uint8_t flags );
1587
1606 struct RETROFLAT_BITMAP* target, const RETROFLAT_COLOR color,
1607 const char* str, int str_sz, const char* font_str, int16_t x_orig, int16_t y_orig,
1608 uint8_t flags );
1609
1610/* TODO: Documentation! */
1611void retroflat_get_palette( uint8_t idx, uint32_t* rgb );
1612
1613MERROR_RETVAL retroflat_set_palette( uint8_t idx, uint32_t rgb );
1614 /* maug_retroflt_bitmap */
1616
1627 retroflat_proc_resize_t on_resize_in, void* data_in );
1628
1634
1639
1645RETROFLAT_IN_KEY retroflat_poll_input( struct RETROFLAT_INPUT* input );
1646 /* maug_retroflt_input */
1648
1649#ifdef RETROFLT_C
1650
1651MAUG_CONST int16_t SEG_MCONST gc_retroflat_offsets8_x[8] =
1652 { 0, 1, 1, 1, 0, -1, -1, -1 };
1653MAUG_CONST int16_t SEG_MCONST gc_retroflat_offsets8_y[8] =
1654 { -1, -1, 0, 1, 1, 1, 0, -1 };
1655
1656MAUG_CONST int16_t SEG_MCONST gc_retroflat_offsets4_x[4] =
1657 { 0, 1, 0, -1 };
1658MAUG_CONST int16_t SEG_MCONST gc_retroflat_offsets4_y[4] =
1659 { -1, 0, 1, 0 };
1660
1661MAUG_MHANDLE g_retroflat_state_h = (MAUG_MHANDLE)NULL;
1662struct RETROFLAT_STATE* g_retroflat_state = NULL;
1663
1664# define RETROFLAT_COLOR_TABLE_CONSTS( idx, name_l, name_u, r, g, b, cgac, cgad ) \
1665 MAUG_CONST RETROFLAT_COLOR RETROFLAT_COLOR_ ## name_u = idx;
1666
1667RETROFLAT_COLOR_TABLE( RETROFLAT_COLOR_TABLE_CONSTS )
1668
1669# define RETROFLAT_COLOR_TABLE_NAMES( idx, name_l, name_u, r, g, b, cgac, cgad ) \
1670 #name_u,
1671
1672MAUG_CONST char* SEG_MCONST gc_retroflat_color_names[] = {
1673 RETROFLAT_COLOR_TABLE( RETROFLAT_COLOR_TABLE_NAMES )
1674};
1675
1676/* Callback table is down below, after the statically-defined callbacks. */
1677
1678/* === Function Definitions === */
1679
1680MERROR_RETVAL retroflat_build_filename_path(
1681 const char* filename_in,
1682 char* buffer_out, size_t buffer_out_sz, uint8_t flags
1683) {
1684 MERROR_RETVAL retval = MERROR_OK;
1685
1686 assert( 1 < buffer_out_sz );
1687
1688 /* Build the path to the bitmap. */
1689 memset( buffer_out, '\0', buffer_out_sz );
1690 if(
1693 ) {
1694 /* TODO: Error checking. */
1695 maug_snprintf( buffer_out, buffer_out_sz - 1, "%s", filename_in );
1696 } else {
1697 /* TODO: Error checking. */
1698 maug_snprintf( buffer_out, buffer_out_sz - 1, "%s%c%s.%s",
1699 g_retroflat_state->assets_path, RETROFLAT_PATH_SEP,
1700 filename_in, RETROFLAT_BITMAP_EXT );
1701 }
1702
1703 return retval;
1704}
1705
1706/* === */
1707
1708# if (defined( RETROFLAT_SOFT_SHAPES ) || defined( RETROFLAT_SOFT_LINES )) \
1709 && !defined( MAUG_NO_AUTO_C )
1710# define RETROFP_C
1711# include <retrofp.h>
1712# define RETROSFT_C
1713# include <retrosft.h>
1714# endif /* RETROFLAT_SOFT_SHAPES */
1715
1716# if defined( RETROFLAT_OPENGL ) && !defined( MAUG_NO_AUTO_C )
1717# define RETROGLU_C
1718# include <retroglu.h>
1719# define RETROFP_C
1720# include <retrofp.h>
1721# define RETROSFT_C
1722# include <retrosft.h>
1723# endif /* RETROFLAT_OPENGL */
1724
1725# if defined( RETROFLAT_VDP ) && defined( RETROFLAT_OS_UNIX )
1726# include <dlfcn.h>
1727# endif
1728
1729/* Still inside RETROFLT_C! */
1730
1731/* === */
1732
1733#ifndef RETROFLAT_NO_GENERIC_LOOP
1734
1735MERROR_RETVAL retroflat_loop_generic(
1736 retroflat_loop_iter frame_iter, retroflat_loop_iter loop_iter, void* data
1737) {
1738 MERROR_RETVAL retval = MERROR_OK;
1739 retroflat_ms_t next = 0,
1740 now = 0;
1741
1742 g_retroflat_state->loop_iter = (retroflat_loop_iter)loop_iter;
1743 g_retroflat_state->loop_data = (void*)data;
1744 g_retroflat_state->frame_iter = (retroflat_loop_iter)frame_iter;
1745
1746 if(
1748 (g_retroflat_state->retroflat_flags & RETROFLAT_FLAGS_RUNNING)
1749 ) {
1750 /* Main loop is already running, so we're just changing the iter call
1751 * and leaving!
1752 */
1753 debug_printf( 1, "main loop already running!" );
1754 goto cleanup;
1755 }
1756
1757 g_retroflat_state->retroflat_flags |= RETROFLAT_FLAGS_RUNNING;
1758 do {
1759 if(
1760 /* Not waiting for the next frame? */
1762 (RETROFLAT_FLAGS_WAIT_FOR_FPS & g_retroflat_state->retroflat_flags) &&
1763 /* Inter-frame loop present? */
1764 NULL != g_retroflat_state->loop_iter
1765 ) {
1766 /* Run the loop iter as many times as possible. */
1767 g_retroflat_state->loop_iter( g_retroflat_state->loop_data );
1768 }
1769 if(
1771 (RETROFLAT_FLAGS_UNLOCK_FPS & g_retroflat_state->retroflat_flags) &&
1772 retroflat_get_ms() < next
1773 ) {
1774 /* Sleep/low power for a bit. */
1775 continue;
1776 }
1777 if( NULL != g_retroflat_state->frame_iter ) {
1778 /* Run the frame iterator once per FPS tick. */
1779 g_retroflat_state->frame_iter( g_retroflat_state->loop_data );
1780 }
1781 /* Reset wait-for-frame flag AFTER frame callback. */
1782 g_retroflat_state->retroflat_flags &= ~RETROFLAT_FLAGS_WAIT_FOR_FPS;
1783 now = retroflat_get_ms();
1784 if( now + retroflat_fps_next() > now ) {
1785 next = now + retroflat_fps_next();
1786 } else {
1787 /* Rollover protection. */
1788 /* TODO: Add difference from now/next to 0 here. */
1789 next = 0;
1790 }
1791 } while(
1793 (RETROFLAT_FLAGS_RUNNING & g_retroflat_state->retroflat_flags)
1794 );
1795 retval = g_retroflat_state->retval;
1796
1797cleanup:
1798
1799 /* This should be set by retroflat_quit(). */
1800 return retval;
1801}
1802
1803#endif /* !RETROFLAT_NO_GENERIC_LOOP */
1804
1805/* === */
1806
1807# if !defined( RETROFLAT_NO_KEYBOARD )
1808
1809char retroflat_vk_to_ascii( RETROFLAT_IN_KEY k, uint8_t flags ) {
1810 char c = 0;
1811 char offset_lower = 0;
1812
1813 if( RETROFLAT_INPUT_MOD_SHIFT != (RETROFLAT_INPUT_MOD_SHIFT & flags) ) {
1814 /* Shift is *not* being held down. */
1815
1816 if( RETROFLAT_KEY_A <= k && RETROFLAT_KEY_Z >= k ) {
1817 if(
1818 RETROFLAT_INPUT_FORCE_UPPER !=
1819 (RETROFLAT_INPUT_FORCE_UPPER & flags)
1820 ) {
1821 /* Key is alphabetical and we're not forcing uppercase. */
1822 offset_lower = 0x20;
1823 }
1824 } else {
1825 offset_lower = 1;
1826 }
1827 }
1828
1829 switch( k ) {
1830 case RETROFLAT_KEY_A: c = 0x41 + offset_lower; break;
1831 case RETROFLAT_KEY_B: c = 0x42 + offset_lower; break;
1832 case RETROFLAT_KEY_C: c = 0x43 + offset_lower; break;
1833 case RETROFLAT_KEY_D: c = 0x44 + offset_lower; break;
1834 case RETROFLAT_KEY_E: c = 0x45 + offset_lower; break;
1835 case RETROFLAT_KEY_F: c = 0x46 + offset_lower; break;
1836 case RETROFLAT_KEY_G: c = 0x47 + offset_lower; break;
1837 case RETROFLAT_KEY_H: c = 0x48 + offset_lower; break;
1838 case RETROFLAT_KEY_I: c = 0x49 + offset_lower; break;
1839 case RETROFLAT_KEY_J: c = 0x4a + offset_lower; break;
1840 case RETROFLAT_KEY_K: c = 0x4b + offset_lower; break;
1841 case RETROFLAT_KEY_L: c = 0x4c + offset_lower; break;
1842 case RETROFLAT_KEY_M: c = 0x4d + offset_lower; break;
1843 case RETROFLAT_KEY_N: c = 0x4e + offset_lower; break;
1844 case RETROFLAT_KEY_O: c = 0x4f + offset_lower; break;
1845 case RETROFLAT_KEY_P: c = 0x50 + offset_lower; break;
1846 case RETROFLAT_KEY_Q: c = 0x51 + offset_lower; break;
1847 case RETROFLAT_KEY_R: c = 0x52 + offset_lower; break;
1848 case RETROFLAT_KEY_S: c = 0x53 + offset_lower; break;
1849 case RETROFLAT_KEY_T: c = 0x54 + offset_lower; break;
1850 case RETROFLAT_KEY_U: c = 0x55 + offset_lower; break;
1851 case RETROFLAT_KEY_V: c = 0x56 + offset_lower; break;
1852 case RETROFLAT_KEY_W: c = 0x57 + offset_lower; break;
1853 case RETROFLAT_KEY_X: c = 0x58 + offset_lower; break;
1854 case RETROFLAT_KEY_Y: c = 0x59 + offset_lower; break;
1855 case RETROFLAT_KEY_Z: c = 0x60 + offset_lower; break;
1856 case RETROFLAT_KEY_0: c = offset_lower ? 0x30 : ')'; break;
1857 case RETROFLAT_KEY_1: c = offset_lower ? 0x31 : '!'; break;
1858 case RETROFLAT_KEY_2: c = offset_lower ? 0x32 : '@'; break;
1859 case RETROFLAT_KEY_3: c = offset_lower ? 0x33 : '#'; break;
1860 case RETROFLAT_KEY_4: c = offset_lower ? 0x34 : '$'; break;
1861 case RETROFLAT_KEY_5: c = offset_lower ? 0x35 : '%'; break;
1862 case RETROFLAT_KEY_6: c = offset_lower ? 0x36 : '^'; break;
1863 case RETROFLAT_KEY_7: c = offset_lower ? 0x37 : '&'; break;
1864 case RETROFLAT_KEY_8: c = offset_lower ? 0x38 : '*'; break;
1865 case RETROFLAT_KEY_9: c = offset_lower ? 0x39 : '('; break;
1866 case RETROFLAT_KEY_SPACE: c = ' '; break;
1867 case RETROFLAT_KEY_BKSP: c = 0x08; break;
1868 case RETROFLAT_KEY_ENTER: c = '\n'; break;
1869 case RETROFLAT_KEY_SEMICOLON: c = offset_lower ? ';' : ':'; break;
1870 case RETROFLAT_KEY_DASH: c = offset_lower ? '-' : '_'; break;
1871 case RETROFLAT_KEY_SLASH: c = offset_lower ? '/' : '?'; break;
1872 case RETROFLAT_KEY_PERIOD: c = offset_lower ? '.' : '>'; break;
1873 case RETROFLAT_KEY_COMMA: c = offset_lower ? ',' : '<'; break;
1874 case RETROFLAT_KEY_QUOTE: c = offset_lower ? '\'' : '"'; break;
1875 case RETROFLAT_KEY_EQUALS: c = offset_lower ? '=' : '+'; break;
1876 case RETROFLAT_KEY_BACKSLASH: c = offset_lower ? '\\' : '|'; break;
1877 case RETROFLAT_KEY_BRACKETL: c = offset_lower ? '[' : '{'; break;
1878 case RETROFLAT_KEY_BRACKETR: c = offset_lower ? ']' : '}'; break;
1879#ifndef RETROFLAT_API_PC_BIOS
1880 /* TODO: FIXME in DOS! */
1881 case RETROFLAT_KEY_GRAVE: c = offset_lower ? '`' : '~'; break;
1882#endif /* !RETROFLAT_API_PC_BIOS */
1883 }
1884
1885 debug_printf( RETROFLAT_KB_TRACE_LVL, "0x%02x", c );
1886
1887 return c;
1888}
1889
1890#endif /* !RETROFLAT_NO_KEYBOARD */
1891
1892/* === */
1893
1894/* TODO: Migrate all platform-specific parts below to retapif.h. */
1895#include <retapif.h>
1896
1897/* === */
1898
1899# ifndef RETROFLAT_NO_CLI
1900
1901# ifdef RETROSND_ARGS
1902
1903static MERROR_RETVAL retrosnd_cli_rsl(
1904 const char* arg, ssize_t arg_c, struct RETROFLAT_ARGS* args
1905) {
1906 if(
1907 0 <= arg_c &&
1908 0 == strncmp( MAUG_CLI_SIGIL "rsl", arg, MAUG_CLI_SIGIL_SZ + 4 )
1909 ) {
1910 args->snd_flags |= RETROSND_ARGS_FLAG_LIST_DEVS;
1911 }
1912 return MERROR_OK;
1913}
1914
1915static MERROR_RETVAL retrosnd_cli_rsd(
1916 const char* arg, ssize_t arg_c, struct RETROFLAT_ARGS* args
1917) {
1918 MERROR_RETVAL retval = MERROR_OK;
1919# if defined( RETROSND_API_PC_BIOS ) || defined( RETROSND_API_ALSA )
1920 char* env_var = NULL;
1921 size_t i = 0;
1922# elif defined( RETROSND_API_ALSA )
1923 char* env_var = NULL;
1924# elif defined( RETROSND_API_WINMM )
1925 char* env_var = NULL;
1926# endif /* RETROSND_API_PC_BIOS || RETROSND_API_ALSA */
1927
1928 if( 0 > arg_c ) {
1929# ifdef RETROSND_API_PC_BIOS
1930 if( NULL != env_var ) {
1931 env_var = getenv( "MAUG_MIDI_DOS" );
1932
1933 /* Return MERROR_OK since this isn't fatal and will just cause sound
1934 * init to fail later.
1935 */
1936 maug_cleanup_if_null_msg(
1937 char*, env_var, MERROR_OK, "MAUG_MIDI_DOS variable not found!" );
1938
1939 debug_printf( 2, "env: MAUG_MIDI_DOS: %s", env_var );
1940
1941 /* Turn comma separator into NULL split. */
1942 for( i = 0 ; maug_strlen( env_var ) > i ; i++ ) {
1943 if( ',' == env_var[i] ) {
1944 /* Split into two null-terminated strings. */
1945 env_var[i] = '\0';
1946 }
1947 }
1948
1949 if( 0 == strcmp( env_var, "mpu" ) ) {
1950 debug_printf( 3, "selecting MIDI driver: mpu" );
1951 args->snd_driver = 2;
1952 } else if( 0 == strcmp( env_var, "gus" ) ) {
1953 debug_printf( 3, "selecting MIDI driver: gus" );
1954 args->snd_driver = 4;
1955 } else if( 0 == strcmp( env_var, "adlib" ) ) {
1956 debug_printf( 3, "selecting MIDI driver: adlib" );
1957 args->snd_driver = 8;
1958 }
1959 /* TODO: Maug replacement for C99 crutch. */
1960 args->snd_io_base = strtoul( &(env_var[i]), NULL, 16 );
1961 debug_printf( 3, "setting MIDI I/O base: %u", args->snd_io_base );
1962 } else {
1963 /* default */
1964 debug_printf( 3, "default MIDI driver: adlib" );
1965 args->snd_driver = 8;
1966 args->snd_io_base = 0x388;
1967 }
1968
1969# elif defined( RETROSND_API_ALSA )
1970 if( 0 == args->snd_client ) {
1971 env_var = getenv( "MAUG_MIDI_ALSA" );
1972
1973 /* Return MERROR_OK since this isn't fatal and will just cause sound
1974 * init to fail later.
1975 */
1976 maug_cleanup_if_null_msg(
1977 char*, env_var, MERROR_OK, "MAUG_MIDI_ALSA variable not found!" );
1978
1979 debug_printf( 2, "env: MAUG_MIDI_ALSA: %s", env_var );
1980
1981 for( i = 0 ; maug_strlen( env_var ) > i ; i++ ) {
1982 if( ':' == env_var[i] ) {
1983 /* Split into two null-terminated strings. */
1984 env_var[i] = '\0';
1985 }
1986 }
1987
1988 args->snd_client = atoi( env_var );
1989 args->snd_port = atoi( &(env_var[i]) );
1990 debug_printf( 3, "setting MIDI device to: %u:%u",
1991 args->snd_client, args->snd_port );
1992 }
1993
1994# elif defined( RETROSND_API_WINMM )
1995 env_var = getenv( "MAUG_MIDI_WIN" );
1996
1997 /* Return MERROR_OK since this isn't fatal and will just cause sound
1998 * init to fail later.
1999 */
2000 maug_cleanup_if_null_msg(
2001 char*, env_var, MERROR_OK, "MAUG_MIDI_WIN variable not found!" );
2002
2003 debug_printf( 2, "env: MAUG_MIDI_WIN: %s", env_var );
2004
2005 if( NULL != env_var ) {
2006 args->snd_dev_id = atoi( env_var );
2007 } else {
2008 args->snd_dev_id = 0;
2009 }
2010 debug_printf( 3, "setting MIDI device to: %u", args->snd_dev_id );
2011
2012# endif /* RETROSND_API_PC_BIOS || RETROSND_API_ALSA || RETROSND_API_WINMM */
2013 } else if(
2014 0 == strncmp( MAUG_CLI_SIGIL "rsd", arg, MAUG_CLI_SIGIL_SZ + 4 )
2015 ) {
2016 /* The next arg must be the new var. */
2017 } else {
2018# ifdef RETROSND_API_PC_BIOS
2019 /* TODO: Parse device. */
2020# elif defined( RETROSND_API_ALSA )
2021 /* TODO: Parse device. */
2022# elif defined( RETROSND_API_WINMM )
2023 debug_printf( 3, "setting MIDI device to rsd arg: %s", arg );
2024 args->snd_dev_id = atoi( arg );
2025# endif /* RETROSND_API_PC_BIOS || RETROSND_API_ALSA || RETROSND_API_WINMM */
2026 }
2027
2028# if defined( RETROSND_API_PC_BIOS ) || defined( RETROSND_API_ALSA )
2029cleanup:
2030# elif defined( RETROSND_API_ALSA )
2031cleanup:
2032# elif defined( RETROSND_API_WINMM )
2033cleanup:
2034# endif /* RETROSND_API_PC_BIOS || RETROSND_API_ALSA */
2035
2036 return retval;
2037}
2038
2039# endif /* RETROSND_ARGS */
2040
2041# if !defined( RETROFLAT_API_PC_BIOS ) && !defined( RETROFLAT_NO_CLI_SZ )
2042
2043static MERROR_RETVAL retroflat_cli_rfx(
2044 const char* arg, ssize_t arg_c, struct RETROFLAT_ARGS* args
2045) {
2046 if( 0 > arg_c ) {
2047 if( 0 == args->screen_w ) {
2048 args->screen_x = 0;
2049 }
2050 } else if(
2051 0 == strncmp( MAUG_CLI_SIGIL "rfx", arg, MAUG_CLI_SIGIL_SZ + 4 )
2052 ) {
2053 /* The next arg must be the new var. */
2054 } else {
2055 args->screen_x = atoi( arg );
2056 }
2057 return MERROR_OK;
2058}
2059
2060static MERROR_RETVAL retroflat_cli_rfy(
2061 const char* arg, ssize_t arg_c, struct RETROFLAT_ARGS* args
2062) {
2063 if( 0 > arg_c ) {
2064 if( 0 == args->screen_h ) {
2065 args->screen_y = 0;
2066 }
2067 } else if(
2068 0 == strncmp( MAUG_CLI_SIGIL "rfy", arg, MAUG_CLI_SIGIL_SZ + 4 )
2069 ) {
2070 /* The next arg must be the new var. */
2071 } else {
2072 args->screen_y = atoi( arg );
2073 }
2074 return MERROR_OK;
2075}
2076
2077static MERROR_RETVAL retroflat_cli_rfw(
2078 const char* arg, ssize_t arg_c, struct RETROFLAT_ARGS* args
2079) {
2080 if( 0 > arg_c ) {
2081 if( 0 == args->screen_w ) {
2082 args->screen_w = RETROFLAT_DEFAULT_SCREEN_W;
2083 }
2084 } else if(
2085 0 == strncmp( MAUG_CLI_SIGIL "rfw", arg, MAUG_CLI_SIGIL_SZ + 4 )
2086 ) {
2087 /* The next arg must be the new var. */
2088 } else {
2089 args->screen_w = atoi( arg );
2090 }
2091 return MERROR_OK;
2092}
2093
2094static MERROR_RETVAL retroflat_cli_rfh(
2095 const char* arg, ssize_t arg_c, struct RETROFLAT_ARGS* args
2096) {
2097 if( 0 > arg_c ) {
2098 if( 0 == args->screen_h ) {
2099 args->screen_h = RETROFLAT_DEFAULT_SCREEN_H;
2100 }
2101 } else if(
2102 0 == strncmp( MAUG_CLI_SIGIL "rfh", arg, MAUG_CLI_SIGIL_SZ + 4 )
2103 ) {
2104 /* The next arg must be the new var. */
2105 } else {
2106 args->screen_h = atoi( arg );
2107 }
2108 return MERROR_OK;
2109}
2110
2111# endif /* !RETROFLAT_API_PC_BIOS && !RETROFLAT_NO_CLI_SZ */
2112
2113# ifdef RETROFLAT_VDP
2114static MERROR_RETVAL retroflat_cli_vdp(
2115 const char* arg, ssize_t arg_c, struct RETROFLAT_ARGS* args
2116) {
2117 if( 0 == strncmp( MAUG_CLI_SIGIL "vdp", arg, MAUG_CLI_SIGIL_SZ + 4 ) ) {
2118 /* Next arg is VDP args str. */
2119 } else {
2120 maug_strncpy( g_retroflat_state->vdp_args, arg, RETROFLAT_VDP_ARGS_SZ_MAX );
2121 debug_printf( 1, "VDP args: %s", g_retroflat_state->vdp_args );
2122 }
2123 return MERROR_OK;
2124}
2125# endif /* RETROFLAT_VDP */
2126
2127static MERROR_RETVAL retroflat_cli_u(
2128 const char* arg, ssize_t arg_c, struct RETROFLAT_ARGS* args
2129) {
2130 if( 0 > arg_c ) {
2131 args->flags &= ~RETROFLAT_FLAGS_UNLOCK_FPS;
2132 } else if(
2133 0 == strncmp( MAUG_CLI_SIGIL "rfu", arg, MAUG_CLI_SIGIL_SZ + 4 )
2134 ) {
2135 debug_printf( 1, "unlocking FPS..." );
2136 args->flags |= RETROFLAT_FLAGS_UNLOCK_FPS;
2137 }
2138 return MERROR_OK;
2139}
2140
2141#endif /* !RETROFLAT_NO_CLI */
2142
2143/* === */
2144
2145/* Still inside RETROFLT_C! */
2146
2147int retroflat_init( int argc, char* argv[], struct RETROFLAT_ARGS* args ) {
2148
2149 /* = Declare Init Vars = */
2150
2151 int retval = 0;
2152
2153 /* = Begin Init Procedure = */
2154
2155# ifdef RETROFLAT_COMMIT_HASH
2156 debug_printf( 1, "retroflat commit: " RETROFLAT_COMMIT_HASH );
2157# endif /* RETROFLAT_COMMIT_HASH */
2158
2159 debug_printf( 1, "retroflat: initializing..." );
2160
2161 /* System sanity checks. */
2162 assert( 4 == sizeof( uint32_t ) );
2163 assert( 4 == sizeof( int32_t ) );
2164 assert( 2 == sizeof( uint16_t ) );
2165 assert( 2 == sizeof( int16_t ) );
2166 assert( 1 == sizeof( uint8_t ) );
2167 assert( 1 == sizeof( int8_t ) );
2168 assert( NULL != args );
2169 assert( 1 << RETROFLAT_TILE_W_BITS == RETROFLAT_TILE_W );
2170 assert( 1 << RETROFLAT_TILE_H_BITS == RETROFLAT_TILE_H );
2171
2172 debug_printf( 1, "retroflat: allocating state (" SIZE_T_FMT " bytes)...",
2173 sizeof( struct RETROFLAT_STATE ) );
2174
2175 debug_printf( 1, "retroflat: size_t is (" SIZE_T_FMT " bytes)...",
2176 sizeof( size_t ) );
2177
2178 debug_printf( 1, "retroflat: ssize_t is (" SIZE_T_FMT " bytes)...",
2179 sizeof( ssize_t ) );
2180
2181 debug_printf( 1, "retroflat: off_t is (" SIZE_T_FMT " bytes)...",
2182 sizeof( off_t ) );
2183
2184 g_retroflat_state_h = maug_malloc( 1, sizeof( struct RETROFLAT_STATE ) );
2185 if( (MAUG_MHANDLE)NULL == g_retroflat_state_h ) {
2187 "Error", "Could not allocate global state!" );
2188 retval = MERROR_ALLOC;
2189 goto cleanup;
2190 }
2191
2192 maug_mlock( g_retroflat_state_h, g_retroflat_state );
2193 if( (MAUG_MHANDLE)NULL == g_retroflat_state ) {
2195 "Error", "Could not lock global state!" );
2196 retval = MERROR_ALLOC;
2197 goto cleanup;
2198 }
2199 maug_mzero( g_retroflat_state, sizeof( struct RETROFLAT_STATE ) );
2200
2201# ifndef RETROFLAT_NO_CLI
2202
2203 debug_printf( 1, "retroflat: parsing args..." );
2204
2205 /* All platforms: add command-line args based on compile definitons. */
2206
2207# ifdef RETROSND_ARGS
2208 retval = maug_add_arg( MAUG_CLI_SIGIL "rsd", MAUG_CLI_SIGIL_SZ + 4,
2209 "Select MIDI device", 0, (maug_cli_cb)retrosnd_cli_rsd, args );
2210 maug_cleanup_if_not_ok();
2211 retval = maug_add_arg( MAUG_CLI_SIGIL "rsl", MAUG_CLI_SIGIL_SZ + 4,
2212 "List MIDI devices", 0, (maug_cli_cb)retrosnd_cli_rsl, args );
2213 maug_cleanup_if_not_ok();
2214# endif /* RETROSND_ARGS */
2215
2216# ifdef RETROFLAT_SCREENSAVER
2217 retval = maug_add_arg( MAUG_CLI_SIGIL "p", MAUG_CLI_SIGIL_SZ + 2,
2218 "Preview screensaver", 0, (maug_cli_cb)retroflat_cli_p, args );
2219 maug_cleanup_if_not_ok();
2220 retval = maug_add_arg( MAUG_CLI_SIGIL "s", MAUG_CLI_SIGIL_SZ + 2,
2221 "Launch screensaver", 0, (maug_cli_cb)retroflat_cli_s, args );
2222 maug_cleanup_if_not_ok();
2223# endif /* RETROFLAT_SCREENSAVER */
2224
2225# ifdef RETROFLAT_API_PC_BIOS
2226 retval = maug_add_arg( MAUG_CLI_SIGIL "rfm", MAUG_CLI_SIGIL_SZ + 4,
2227 "Set the screen mode.", 0,
2228 (maug_cli_cb)retroflat_cli_rfm, args );
2229 maug_cleanup_if_not_ok();
2230# elif !defined( RETROFLAT_NO_CLI_SZ )
2231 retval = maug_add_arg( MAUG_CLI_SIGIL "rfx", MAUG_CLI_SIGIL_SZ + 4,
2232 "Set the screen X position.", 0,
2233 (maug_cli_cb)retroflat_cli_rfx, args );
2234 maug_cleanup_if_not_ok();
2235 retval = maug_add_arg( MAUG_CLI_SIGIL "rfy", MAUG_CLI_SIGIL_SZ + 4,
2236 "Set the screen Y position.", 0,
2237 (maug_cli_cb)retroflat_cli_rfy, args );
2238 maug_cleanup_if_not_ok();
2239 retval = maug_add_arg( MAUG_CLI_SIGIL "rfw", MAUG_CLI_SIGIL_SZ + 4,
2240 "Set the screen width.", 0,
2241 (maug_cli_cb)retroflat_cli_rfw, args );
2242 maug_cleanup_if_not_ok();
2243 retval = maug_add_arg( MAUG_CLI_SIGIL "rfh", MAUG_CLI_SIGIL_SZ + 4,
2244 "Set the screen height.", 0,
2245 (maug_cli_cb)retroflat_cli_rfh, args );
2246 maug_cleanup_if_not_ok();
2247# endif /* !RETROFLAT_NO_CLI_SZ */
2248
2249# ifdef RETROFLAT_VDP
2250 retval = maug_add_arg( MAUG_CLI_SIGIL "vdp", MAUG_CLI_SIGIL_SZ + 4,
2251 "Pass a string of args to the VDP.", 0,
2252 (maug_cli_cb)retroflat_cli_vdp, args );
2253 maug_cleanup_if_not_ok();
2254# endif /* RETROFLAT_VDP */
2255
2256 retval = maug_add_arg( MAUG_CLI_SIGIL "rfu", MAUG_CLI_SIGIL_SZ + 4,
2257 "Unlock FPS.", 0,
2258 (maug_cli_cb)retroflat_cli_u, args );
2259 maug_cleanup_if_not_ok();
2260
2261 /* Parse command line args. */
2262 retval = maug_parse_args( argc, argv );
2263 maug_cleanup_if_not_ok();
2264
2265# else
2266
2267 args->screen_w = RETROFLAT_DEFAULT_SCREEN_W;
2268 args->screen_h = RETROFLAT_DEFAULT_SCREEN_H;
2269
2270# endif /* !RETROFLAT_NO_CLI */
2271
2272 if(
2274 ) {
2275 g_retroflat_state->retroflat_flags |= RETROFLAT_FLAGS_UNLOCK_FPS;
2276 }
2277
2278 debug_printf( 1, "retroflat: setting config..." );
2279
2280 /* Set the assets path. */
2281 memset( g_retroflat_state->assets_path, '\0', RETROFLAT_ASSETS_PATH_MAX );
2282 if( NULL != args->assets_path ) {
2283 maug_strncpy( g_retroflat_state->assets_path,
2285 }
2286
2287# if defined( RETROFLAT_SCREENSAVER )
2288 if(
2290 (RETROFLAT_FLAGS_SCREENSAVER & args->flags)
2291 ) {
2292 g_retroflat_state->retroflat_flags |= RETROFLAT_FLAGS_SCREENSAVER;
2293 }
2294# endif /* RETROFLAT_SCREENSAVER */
2295
2296# if !defined( RETROFLAT_NO_CLI_SZ )
2297 /* Setup intended screen size. */
2298 /* TODO: Handle window resizing someday! */
2299 g_retroflat_state->screen_v_w = args->screen_w;
2300 g_retroflat_state->screen_v_h = args->screen_h;
2301 if(
2303 ) {
2304 debug_printf( 1, "setting window scale to 2x..." );
2305 g_retroflat_state->screen_w = args->screen_w * 2;
2306 g_retroflat_state->screen_h = args->screen_h * 2;
2307 } else {
2308 g_retroflat_state->screen_w = args->screen_w;
2309 g_retroflat_state->screen_h = args->screen_h;
2310 }
2311# endif /* RETROFLAT_NO_CLI_SZ */
2312
2313# ifdef RETROFLAT_OPENGL
2314 debug_printf( 1, "setting up texture palette..." );
2315# define RETROFLAT_COLOR_TABLE_TEX( idx, name_l, name_u, r, g, b, cgac, cgad ) \
2316 g_retroflat_state->tex_palette[idx][0] = r; \
2317 g_retroflat_state->tex_palette[idx][1] = g; \
2318 g_retroflat_state->tex_palette[idx][2] = b;
2319 RETROFLAT_COLOR_TABLE( RETROFLAT_COLOR_TABLE_TEX )
2320# endif /* RETROFLAT_OPENGL */
2321
2322 /* == Platform-Specific Init == */
2323
2324 retval = retroflat_init_platform( argc, argv, args );
2325 maug_cleanup_if_not_ok();
2326
2327 /* Setup the refresh grid, if requested, only after screen space has been
2328 * determined by the platform!
2329 */
2330 assert( 0 < retroflat_screen_w() );
2331 assert( 0 < retroflat_screen_h() );
2332 if(
2334 (RETROFLAT_FLAGS_VIEWPORT_REFRESH & args->flags)
2335 ) {
2336 g_retroflat_state->retroflat_flags |= RETROFLAT_FLAGS_VIEWPORT_REFRESH;
2337
2338 g_retroflat_state->viewport.screen_tile_w =
2339 /* Allocate 1 extra tile on each side for smooth scrolling. */
2340 ((retroflat_screen_w() / RETROFLAT_TILE_W) + 2);
2341 g_retroflat_state->viewport.screen_tile_h =
2342 ((retroflat_screen_h() / RETROFLAT_TILE_H) + 2);
2343
2344 debug_printf( 1, "allocating refresh grid (%d tiles...)",
2345 g_retroflat_state->viewport.screen_tile_w *
2346 g_retroflat_state->viewport.screen_tile_h );
2347 g_retroflat_state->viewport.refresh_grid_h = maug_malloc(
2348 g_retroflat_state->viewport.screen_tile_w *
2349 g_retroflat_state->viewport.screen_tile_h,
2350 sizeof( retroflat_tile_t ) );
2351 maug_cleanup_if_null_alloc( MAUG_MHANDLE,
2352 g_retroflat_state->viewport.refresh_grid_h );
2353 }
2354
2355# if defined( RETROFLAT_SOFT_SHAPES ) || defined( RETROFLAT_SOFT_LINES )
2356 retval = retrosoft_init();
2357 maug_cleanup_if_not_ok();
2358# endif /* RETROFLAT_SOFT_SHAPES || RETROFLAT_SOFT_LINES */
2359
2360# if defined( RETROFLAT_OPENGL )
2361 retval = retrosoft_init();
2362 maug_cleanup_if_not_ok();
2363# ifndef RETROFLAT_NO_STRING
2364 retval = retroglu_init_glyph_tex();
2365 maug_cleanup_if_not_ok();
2366# endif /* !RETROFLAT_NO_STRING */
2367# endif /* RETROFLAT_OPENGL */
2368
2369# ifdef RETROFLAT_VDP
2370# if defined( RETROFLAT_OS_UNIX )
2371 g_retroflat_state->vdp_exe = dlopen(
2372 "./" RETROFLAT_VDP_LIB_NAME ".so", RTLD_LAZY );
2373# elif defined( RETROFLAT_OS_WIN )
2374 g_retroflat_state->vdp_exe = LoadLibrary(
2375 "./" RETROFLAT_VDP_LIB_NAME ".dll" );
2376# else
2377# error "dlopen undefined!"
2378# endif /* RETROFLAT_OS_UNIX */
2379
2380 if( !(g_retroflat_state->vdp_exe) ) {
2381 error_printf( "not loading VDP" );
2382 /* Skip creating the buffer or trying to run the init proc. */
2383 goto skip_vdp;
2384 }
2385
2386 /* Create intermediary screen buffer. */
2387 debug_printf( 1, "creating VDP buffer, " SIZE_T_FMT " x " SIZE_T_FMT,
2388 g_retroflat_state->screen_v_w, g_retroflat_state->screen_v_h );
2389 g_retroflat_state->vdp_buffer =
2390 calloc( 1, sizeof( struct RETROFLAT_BITMAP ) );
2391 maug_cleanup_if_null_alloc(
2392 struct RETROFLAT_BITMAP*, g_retroflat_state->vdp_buffer );
2393 retval = retroflat_create_bitmap(
2394 g_retroflat_state->screen_v_w, g_retroflat_state->screen_v_h,
2395 g_retroflat_state->vdp_buffer, RETROFLAT_FLAGS_OPAQUE );
2396 maug_cleanup_if_not_ok();
2397
2398 debug_printf( 1, "initializing VDP..." );
2399 retval = retroflat_vdp_call( "retroflat_vdp_init" );
2400
2401skip_vdp:
2402
2403# endif /* RETROFLAT_VDP */
2404
2405# if !defined( RETROFLAT_NO_BLANK_INIT ) && !defined( RETROFLAT_OPENGL )
2406 retroflat_draw_lock( NULL );
2408 NULL, RETROFLAT_COLOR_BLACK, 0, 0,
2411 retroflat_draw_release( NULL );
2412# endif /* !RETROFLAT_NO_BLANK_INIT */
2413
2414cleanup:
2415
2416 return retval;
2417}
2418
2419/* === */
2420
2421void retroflat_shutdown( int retval ) {
2422
2423 debug_printf( 1, "retroflat shutdown called..." );
2424
2425 if( (MAUG_MHANDLE)NULL != g_retroflat_state->viewport.refresh_grid_h ) {
2426 maug_mfree( g_retroflat_state->viewport.refresh_grid_h );
2427 }
2428
2429# if defined( RETROFLAT_VDP )
2430 if( NULL != g_retroflat_state->vdp_exe ) {
2431 retroflat_vdp_call( "retroflat_vdp_shutdown" );
2432# ifdef RETROFLAT_OS_UNIX
2433 dlclose( g_retroflat_state->vdp_exe );
2434# elif defined( RETROFLAT_OS_WIN )
2435 FreeLibrary( g_retroflat_state->vdp_exe );
2436# else
2437# error "dlclose undefined!"
2438# endif /* RETROFLAT_OS_UNIX || RETROFLAT_OS_WIN */
2439 }
2440
2441 if( NULL != g_retroflat_state->vdp_buffer ) {
2442 debug_printf( 1, "destroying VPD buffer..." );
2443 retroflat_destroy_bitmap( g_retroflat_state->vdp_buffer );
2444 free( g_retroflat_state->vdp_buffer );
2445 }
2446# endif /* RETROFLAT_VDP */
2447
2448# if defined( RETROFLAT_SOFT_SHAPES ) || defined( RETROFLAT_SOFT_LINES ) || \
2449defined( RETROFLAT_OPENGL )
2450 debug_printf( 1, "calling retrosoft shutdown..." );
2451 retrosoft_shutdown();
2452# endif /* RETROFLAT_SOFT_SHAPES */
2453
2454# if defined( RETROFLAT_OPENGL ) && !defined( RETROFLAT_NO_STRING )
2455 debug_printf( 1, "destroying GL glyphs..." );
2456 retroglu_destroy_glyph_tex();
2457# endif /* RETROFLAT_OPENGL */
2458
2459 /* === Platform-Specific Shutdown === */
2460
2461 retroflat_shutdown_platform( retval );
2462
2463 maug_munlock( g_retroflat_state_h, g_retroflat_state );
2464 maug_mfree( g_retroflat_state );
2465
2466}
2467
2468/* === */
2469
2470# ifdef RETROFLAT_VDP
2471
2472MERROR_RETVAL retroflat_vdp_call( const char* proc_name ) {
2473 MERROR_RETVAL retval = MERROR_OK;
2475# ifdef RETROFLAT_OS_WIN
2476 char proc_name_ex[256];
2477# endif /* RETROFLAT_OS_WIN */
2478
2479 if( NULL == g_retroflat_state->vdp_exe ) {
2480 goto cleanup;
2481 }
2482
2483# ifdef RETROFLAT_OS_UNIX
2484 vdp_proc = dlsym( g_retroflat_state->vdp_exe, proc_name );
2485# elif defined( RETROFLAT_OS_WIN )
2486 /* Append a _ to the proc_name because Watcom? Windows? */
2487 maug_snprintf( proc_name_ex, 255, "%s_", proc_name );
2488 vdp_proc = (retroflat_vdp_proc_t)GetProcAddress(
2489 g_retroflat_state->vdp_exe, proc_name_ex );
2490# else
2491# error "dlsym undefined!"
2492# endif
2493 if( (retroflat_vdp_proc_t)NULL == vdp_proc ) {
2494 goto cleanup;
2495 }
2496
2497# ifdef RETROFLAT_OS_WIN
2498 retroflat_draw_lock( g_retroflat_state->vdp_buffer );
2499# endif /* RETROFLAT_OS_WIN */
2500
2501 if(
2502 /* Don't pxlock before init can set the flag! */
2503 0 == strcmp( "retroflat_vdp_flip", proc_name ) &&
2505 (RETROFLAT_VDP_FLAG_PXLOCK & g_retroflat_state->vdp_flags)
2506 ) {
2507 retroflat_vdp_lock( &(g_retroflat_state->buffer) );
2508 retroflat_vdp_lock( g_retroflat_state->vdp_buffer );
2509 }
2510
2511 retval = vdp_proc( g_retroflat_state );
2512
2513 if(
2514 0 == strcmp( "retroflat_vdp_flip", proc_name ) &&
2516 (RETROFLAT_VDP_FLAG_PXLOCK & g_retroflat_state->vdp_flags)
2517 ) {
2518 retroflat_vdp_release( &(g_retroflat_state->buffer) );
2519 retroflat_vdp_release( g_retroflat_state->vdp_buffer );
2520 }
2521
2522# ifdef RETROFLAT_OS_WIN
2523 retroflat_draw_release( g_retroflat_state->vdp_buffer );
2524# endif /* RETROFLAT_OS_WIN */
2525
2526cleanup:
2527 return retval;
2528}
2529
2530# endif /* RETROFLAT_VDP */
2531
2532/* === */
2533
2534#if 0
2535
2536void retroflat_cursor( struct RETROFLAT_BITMAP* target, uint8_t flags ) {
2537#if 0
2538 char mouse_str[11] = "";
2539
2540 maug_snprintf(
2541 mouse_str, 10, "%02d, %02d", g_retroflat_state->last_mouse_x, g_retroflat_state->last_mouse_y );
2542
2544 target, RETROFLAT_COLOR_BLACK,
2545 mouse_str, 10, NULL, 0, 0, 0 );
2547 target, RETROFLAT_COLOR_BLACK,
2548 g_retroflat_state->last_mouse_x - 5, g_retroflat_state->last_mouse_y - 5, 10, 10, 0 );
2549#endif
2550}
2551
2552#endif
2553
2554/* === */
2555
2556#ifndef RETROFLAT_NO_STRING
2557
2558# if defined( RETROFLAT_API_WIN16 ) || defined( RETROFLAT_API_WIN32 )
2559
2560# define retroflat_win_create_font( flags, font_str ) \
2561 CreateFont( 10, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, \
2562 DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, \
2563 DEFAULT_QUALITY, DEFAULT_PITCH, \
2564 (NULL == font_str || '\0' == font_str[0] ? "Arial" : font_str) );
2565
2566# endif /* RETROFLAT_API_WIN16 || RETROFLAT_API_WIN32 */
2567
2569 struct RETROFLAT_BITMAP* target, const char* str, size_t str_sz,
2570 const char* font_str, size_t* w_out, size_t* h_out, uint8_t flags
2571) {
2572# if defined( RETROFLAT_OPENGL )
2573# elif defined( RETROFLAT_SOFT_SHAPES )
2574# elif defined( RETROFLAT_API_ALLEGRO )
2575 FONT* font_data = NULL;
2576 int font_loaded = 0;
2577# elif defined( RETROFLAT_API_WIN16 ) || defined( RETROFLAT_API_WIN32 )
2578 SIZE sz;
2579 HFONT font;
2580 HFONT old_font;
2581# endif /* RETROFLAT_API_ALLEGRO || RETROFLAT_API_SDL2 || RETROFLAT_API_WIN16 || RETROFLAT_API_WIN32 */
2582
2583 if( NULL == target ) {
2584 target = retroflat_screen_buffer();
2585 }
2586
2587# if defined( RETROFLAT_OPENGL )
2588
2589 retrosoft_string_sz( target, str, str_sz, font_str, w_out, h_out, flags );
2590
2591# elif defined( RETROFLAT_SOFT_SHAPES )
2592
2593 retrosoft_string_sz( target, str, str_sz, font_str, w_out, h_out, flags );
2594
2595# elif defined( RETROFLAT_API_ALLEGRO )
2596
2597 /* == Allegro == */
2598
2599 if( NULL == font_str || '\0' == font_str[0] ) {
2600 font_data = font;
2601 } else {
2602 /* TODO: Cache loaded fonts for later use. */
2603 font_data = load_font( font_str, NULL, NULL );
2604 }
2605 if( NULL == font_data ) {
2607 "Error", "Unable to load font: %s", font_str );
2608 goto cleanup;
2609 }
2610
2611 *w_out = text_length( font_data, str );
2612 *h_out = text_height( font_data );
2613
2614cleanup:
2615
2616 if( font_loaded && NULL != font_data ) {
2617 destroy_font( font_data );
2618 }
2619
2620# elif defined( RETROFLAT_API_WIN16 ) || defined( RETROFLAT_API_WIN32 )
2621
2622 /* == Win16/Win32 == */
2623
2624 assert( (HBITMAP)NULL != target->b );
2625 assert( retroflat_bitmap_locked( target ) );
2626
2627 font = retroflat_win_create_font( flags, font_str );
2628 old_font = SelectObject( target->hdc_b, font );
2629
2630 GetTextExtentPoint( target->hdc_b, str, str_sz, &sz );
2631 *w_out = sz.cx;
2632 *h_out = sz.cy;
2633
2634/* cleanup: */
2635
2636 SelectObject( target->hdc_b, old_font );
2637
2638# else
2639# pragma message( "warning: string sz not implemented" )
2640# endif /* RETROFLAT_API_ALLEGRO || RETROFLAT_API_SDL2 || RETROFLAT_API_WIN16 || RETROFLAT_API_WIN32 */
2641}
2642
2643/* === */
2644
2645void retroflat_string(
2646 struct RETROFLAT_BITMAP* target, const RETROFLAT_COLOR color,
2647 const char* str, int str_sz, const char* font_str, int16_t x_orig, int16_t y_orig,
2648 uint8_t flags
2649) {
2650# if defined( RETROFLAT_OPENGL )
2651 float aspect_ratio = 0,
2652 screen_x = 0,
2653 screen_y = 0;
2654# elif defined( RETROFLAT_SOFT_SHAPES )
2655# elif defined( RETROFLAT_API_ALLEGRO )
2656 FONT* font_data = NULL;
2657 int font_loaded = 0;
2658# elif defined( RETROFLAT_API_WIN16 ) || defined( RETROFLAT_API_WIN32 )
2659 RECT rect;
2660 SIZE sz;
2661 HFONT font;
2662 HFONT old_font;
2663# endif /* RETROFLAT_API_ALLEGRO || RETROFLAT_API_SDL2 || RETROFLAT_API_WIN16 || RETROFLAT_API_WIN32 */
2664
2665 if( RETROFLAT_COLOR_NULL == color ) {
2666 return;
2667 }
2668
2669# if !defined( RETROFLAT_OPENGL )
2670 if( NULL == target ) {
2671 target = retroflat_screen_buffer();
2672 }
2673# endif /* !RETROFLAT_OPENGL */
2674
2675 if( 0 == str_sz ) {
2676 str_sz = maug_strlen( str );
2677 }
2678
2679# if defined( RETROFLAT_OPENGL )
2680
2681 if( NULL == target || retroflat_screen_buffer() == target ) {
2682 /* Push new overlay projection parms before we create a new overlay. */
2683 retroglu_push_overlay( x_orig, y_orig, screen_x, screen_y, aspect_ratio );
2684
2685 retroglu_string(
2686 screen_x, screen_y, 0,
2687 g_retroflat_state->palette[color], str, str_sz, font_str, flags );
2688
2690 } else {
2691 /* Assume drawing surface is already configured inside a push_overlay()
2692 * call and draw to its texture. */
2693 retrosoft_string(
2694 target, color, str, str_sz, font_str, x_orig, y_orig, flags );
2695 }
2696
2697# elif defined( RETROFLAT_SOFT_SHAPES )
2698
2699 retrosoft_string(
2700 target, color, str, str_sz, font_str, x_orig, y_orig, flags );
2701
2702# elif defined( RETROFLAT_API_ALLEGRO )
2703
2704 /* == Allegro == */
2705
2706 if( NULL == font_str || '\0' == font_str[0] ) {
2707 font_data = font;
2708 } else {
2709 /* TODO: Cache loaded fonts for later use. */
2710 font_data = load_font( font_str, NULL, NULL );
2711 }
2712 if( NULL == font_data ) {
2714 "Error", "Unable to load font: %s", font_str );
2715 goto cleanup;
2716 }
2717
2718 textout_ex( target->b, font_data, str, x_orig, y_orig, color, -1 );
2719
2720cleanup:
2721 if( font_loaded && NULL != font_data ) {
2722 destroy_font( font_data );
2723 }
2724
2725# elif defined( RETROFLAT_API_WIN16 ) || defined( RETROFLAT_API_WIN32 )
2726
2727 /* == Win16/Win32 == */
2728
2729 assert( (HBITMAP)NULL != target->b );
2730
2731 assert( retroflat_bitmap_locked( target ) );
2732
2733 /* DrawText will draw gibberish even if the string is null-terminated! */
2734 str_sz = maug_strlen( str );
2735
2736 memset( &sz, '\0', sizeof( SIZE ) );
2737
2738 font = retroflat_win_create_font( flags, font_str );
2739 old_font = SelectObject( target->hdc_b, font );
2740
2741 GetTextExtentPoint( target->hdc_b, str, str_sz, &sz );
2742 rect.left = x_orig;
2743 rect.top = y_orig;
2744 rect.right = (x_orig + sz.cx);
2745 rect.bottom = (y_orig + sz.cy);
2746
2747 SetTextColor( target->hdc_b, g_retroflat_state->palette[color] );
2748 SetBkMode( target->hdc_b, TRANSPARENT );
2749
2750 DrawText( target->hdc_b, str, str_sz, &rect, 0 );
2751
2752/* cleanup: */
2753
2754 SelectObject( target->hdc_b, old_font );
2755
2756 SetBkMode( target->hdc_b, OPAQUE );
2757 SetTextColor( target->hdc_b,
2758 g_retroflat_state->palette[RETROFLAT_COLOR_BLACK] );
2759
2760# else
2761# pragma message( "warning: string not implemented" )
2762# endif /* RETROFLAT_API_ALLEGRO || RETROFLAT_API_SDL2 || RETROFLAT_API_WIN16 || RETROFLAT_API_WIN32 */
2763}
2764
2765#endif /* !RETROFLAT_NO_STRING */
2766
2767/* === */
2768
2770 retroflat_proc_resize_t on_resize_in, void* data_in
2771) {
2772 g_retroflat_state->on_resize = on_resize_in;
2773 g_retroflat_state->on_resize_data = data_in;
2774}
2775
2776/* === */
2777
2778uint8_t retroflat_viewport_move_x_generic( int16_t x ) {
2779 int16_t new_world_x = g_retroflat_state->viewport.world_x + x;
2780
2781 g_retroflat_state->viewport.screen_x += x;
2782
2783 /* Keep the viewport in the world arena. */
2784 if(
2785 0 < new_world_x &&
2786 g_retroflat_state->viewport.world_w > new_world_x + retroflat_screen_w()
2787 ) {
2788 g_retroflat_state->viewport.world_x += x;
2789 return 1;
2790 }
2791
2792 return 0;
2793}
2794
2795/* === */
2796
2797uint8_t retroflat_viewport_move_y_generic( int16_t y ) {
2798 int16_t new_world_y = g_retroflat_state->viewport.world_y + y;
2799
2800 g_retroflat_state->viewport.screen_y += y;
2801
2802 /* Keep the viewport in the world arena. */
2803 if(
2804 0 < new_world_y &&
2805 g_retroflat_state->viewport.world_h > new_world_y + retroflat_screen_h()
2806 ) {
2807 g_retroflat_state->viewport.world_y += y;
2808 return 1;
2809 }
2810
2811 return 0;
2812}
2813
2814/* === */
2815
2816uint8_t retroflat_viewport_focus_generic(
2817 size_t x1, size_t y1, size_t range, size_t speed
2818) {
2819 uint8_t moved = 0,
2820 new_moved = 0;
2821 int16_t new_pt = 0;
2822
2823# define _retroflat_viewport_focus_dir( n, xy, wh, gl, pm, dir, range, speed ) \
2824 new_pt = n - retroflat_viewport_world_ ## xy(); \
2825 if( new_pt gl (retroflat_screen_ ## wh() >> 1) pm range ) { \
2826 new_moved = retroflat_viewport_move_ ## xy( \
2827 gc_retroflat_offsets8_ ## xy[RETROFLAT_DIR8_ ## dir] * speed ); \
2828 if( !moved && new_moved ) { \
2829 moved = new_moved; \
2830 } \
2831 }
2832
2833 _retroflat_viewport_focus_dir( x1, x, w, <, -, WEST, range, speed );
2834 _retroflat_viewport_focus_dir( x1, x, w, >, +, EAST, range, speed );
2835 _retroflat_viewport_focus_dir( y1, y, h, <, -, NORTH, range, speed );
2836 _retroflat_viewport_focus_dir( y1, y, h, >, +, SOUTH, range, speed );
2837
2838 return moved;
2839}
2840
2841/* === */
2842
2843#elif !defined( RETROVDP_C ) /* End of RETROFLT_C */
2844
2849
2850extern MAUG_CONST int16_t SEG_MCONST gc_retroflat_offsets8_x[8];
2851extern MAUG_CONST int16_t SEG_MCONST gc_retroflat_offsets8_y[8];
2852extern MAUG_CONST int16_t SEG_MCONST gc_retroflat_offsets4_x[4];
2853extern MAUG_CONST int16_t SEG_MCONST gc_retroflat_offsets4_y[4];
2854
2856
2857#define RETROFLAT_COLOR_TABLE_CONSTS( idx, name_l, name_u, r, g, b, cgac, cgad ) \
2858 extern MAUG_CONST RETROFLAT_COLOR RETROFLAT_COLOR_ ## name_u;
2859
2860RETROFLAT_COLOR_TABLE( RETROFLAT_COLOR_TABLE_CONSTS )
2861
2862extern MAUG_CONST char* SEG_MCONST gc_retroflat_color_names[];
2863
2864 extern struct RETROFLAT_STATE* g_retroflat_state;
2865# if defined( RETROFLAT_API_WIN16 ) || defined( RETROFLAT_API_WIN32 )
2866 extern HINSTANCE g_retroflat_instance;
2867 extern int g_retroflat_cmd_show;
2868# endif /* RETROFLAT_API_WIN16 || RETROFLAT_API_WIN32 */
2869
2870# include <uprintf.h>
2871
2872# if (defined( RETROFLAT_SOFT_SHAPES ) || defined( RETROFLAT_SOFT_LINES)) \
2873 && !defined( MAUG_NO_AUTO_C )
2874# include <retrofp.h>
2875# include <retrosft.h>
2876# endif /* RETROFLAT_SOFT_SHAPES || RETROFLAT_SOFT_LINES */
2877
2878# if defined( RETROFLAT_OPENGL ) && !defined( MAUG_NO_AUTO_C )
2879# include <retroglu.h>
2880# include <retrofp.h>
2881# include <retrosft.h>
2882# endif /* RETROFLAT_OPENGL */
2883
2884#endif /* RETROFLT_C */
2885
2886#ifdef RETROFLAT_XPM
2887#include <retroxpm.h>
2888#endif /* RETROFLAT_XPM */
2889
2890#ifdef RETROVDP_C
2891
2892/* Declarations for VDP sources. */
2893
2894#endif /* RETROVDP_C */
2895 /* maug_retroflt */
2897
2898#endif /* RETROFLT_H */
2899
MERROR_RETVAL maug_add_arg(const char *arg, int arg_sz, const char *help, int help_sz, maug_cli_cb arg_cb, void *data)
Add a command-line argument to the built-in parser.
#define MAUG_CLI_SIGIL
Default flag to prepend to CLI arguments. Is "/" on Windows/DOS and "-" on other platforms....
Definition marge.h:39
int MERROR_RETVAL
Return type indicating function returns a value from this list.
Definition merror.h:19
#define maug_mzero(ptr, sz)
Zero the block of memory pointed to by ptr.
Definition mmem.h:62
char retroflat_asset_path[RETROFLAT_PATH_MAX]
Path/name used to load an asset from disk.
Definition retroflt.h:778
#define RETROFLAT_BITMAP_EXT
The filename suffix to be appended with a "." to filenames passed to retroflat_load_bitmap()....
Definition retroflt.h:581
MERROR_RETVAL retroflat_blit_bitmap(struct RETROFLAT_BITMAP *target, struct RETROFLAT_BITMAP *src, size_t s_x, size_t s_y, int16_t d_x, int16_t d_y, size_t w, size_t h, int16_t instance)
Blit the contents of a RETROFLAT_BITMAP onto another RETROFLAT_BITMAP.
void retroflat_destroy_bitmap(struct RETROFLAT_BITMAP *bitmap)
Unload a bitmap from a RETROFLAT_BITMAP struct. The struct, itself, is not freed (in case it is on th...
MERROR_RETVAL retroflat_load_bitmap(const char *filename, struct RETROFLAT_BITMAP *bmp_out, uint8_t flags)
Load a bitmap into the given RETROFLAT_BITMAP structure if it is available. Bitmaps are subject to th...
int8_t RETROFLAT_COLOR
Defines an index in the platform-specific color-table.
Definition retroflt.h:307
#define RETROFLAT_COLOR_TABLE(f)
This macro defines all colors supported by RetroFlat for primative operations, particularly using ret...
Definition retroflt.h:288
#define RETROFLAT_VDP_ARGS_SZ_MAX
Definition retroflt.h:728
#define RETROFLAT_ASSETS_PATH_MAX
Maximum size of the assets path, to allow room for appending.
Definition retroflt.h:753
#define RETROFLAT_PATH_SEP
The valid path separator on the target platform.
Definition retroflt.h:749
#define RETROFLAT_FLAGS_LITERAL_PATH
Flag for retroflat_load_bitmap() to not use assets path.
Definition retroflt.h:374
void retroflat_ellipse(struct RETROFLAT_BITMAP *target, const RETROFLAT_COLOR color, int16_t x, int16_t y, int16_t w, int16_t h, uint8_t flags)
Draw an ellipse onto the target RETROFLAT_BITMAP.
#define RETROFLAT_FLAGS_OPAQUE
Flag for retroflat_create_bitmap() to create a bitmap without transparency.
Definition retroflt.h:361
#define RETROFLAT_FLAGS_VIEWPORT_REFRESH
Flag for args->flags, indicating that a viewport tile refresh grid should be allocated and used.
Definition retroflt.h:398
MERROR_RETVAL retroflat_draw_lock(struct RETROFLAT_BITMAP *bmp)
Lock a bitmap for drawing. This will be done automatically if necessary and not called explicitly,...
void retroflat_string_sz(struct RETROFLAT_BITMAP *target, const char *str, size_t str_sz, const char *font_str, size_t *w_out, size_t *h_out, uint8_t flags)
Get the size in pixels of a text string when drawn with a given font by retroflat_string().
void retroflat_rect(struct RETROFLAT_BITMAP *target, const RETROFLAT_COLOR color, int16_t x, int16_t y, int16_t w, int16_t h, uint8_t flags)
Draw a rectangle onto the target RETROFLAT_BITMAP.
#define RETROFLAT_FLAGS_FILL
Flag for retroflat_rect() or retroflat_ellipse(), indicating drawn shape should be filled.
Definition retroflt.h:355
void retroflat_string(struct RETROFLAT_BITMAP *target, const RETROFLAT_COLOR color, const char *str, int str_sz, const char *font_str, int16_t x_orig, int16_t y_orig, uint8_t flags)
Draw a text string at the specified location in the specified font and color on the target RETROFLAT_...
void retroflat_line(struct RETROFLAT_BITMAP *target, const RETROFLAT_COLOR color, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint8_t flags)
Draw a straight line onto the target RETROFLAT_BITMAP.
#define RETROFLAT_FLAGS_SCREENSAVER
Flag indicating the current application is running as a screensaver.
Definition retroflt.h:431
#define RETROFLAT_FLAGS_UNLOCK_FPS
Flag indicating FPS should not be capped.
Definition retroflt.h:419
#define RETROFLAT_FLAGS_SCALE2X
Only supported on some platforms: Attempt to scale screen by 2X.
Definition retroflt.h:436
#define RETROFLAT_FLAGS_RUNNING
Flag indicating that retroflat_loop() should continue executing.
Definition retroflt.h:413
#define RETROFLAT_FLAGS_WAIT_FOR_FPS
Do not execute any more inter-frame loops until next frame.
Definition retroflt.h:441
RETROFLAT_IN_KEY retroflat_poll_input(struct RETROFLAT_INPUT *input)
Poll input devices (keyboard/mouse) and return the latest event.
#define RETROFLAT_MSG_FLAG_ERROR
This icon/type flag indicates an error. It will try to display messages in an urgent way with a red i...
Definition retroflt.h:459
MERROR_RETVAL retroflat_vdp_call(const char *proc_name)
Call a function from the retroflat VDP.
MERROR_RETVAL(* retroflat_vdp_proc_t)(struct RETROFLAT_STATE *)
VDP function called from the VDP library.
Definition retroflt.h:511
#define RETROFLAT_VDP_FLAG_PXLOCK
Flag for RETROFLAT_STATE::vdp_flags indicating the VDP requires RetroFlat to pixel-lock the frame bef...
Definition retroflt.h:498
void retroflat_shutdown(int retval)
Deinitialize RetroFlat and its underlying layers. This should be called once at the end of the progra...
void(* retroflat_loop_iter)(void *data)
Prototype for the main loop function passed to retroflat_loop().
Definition retroflt.h:790
void retroflat_resize_v()
Platform-specific function to resize virtual screen to match physical window size.
MERROR_RETVAL retroflat_loop(retroflat_loop_iter frame_iter, retroflat_loop_iter loop_iter, void *data)
This should be called once in the main body of the program in order to enter the main loop....
void retroflat_message(uint8_t flags, const char *title, const char *format,...)
Display a message in a dialog box and/or on stderr.
MERROR_RETVAL retroflat_init(int argc, char *argv[], struct RETROFLAT_ARGS *args)
Initialize RetroFlat and its underlying layers. This should be called once at the beginning of the pr...
void retroflat_set_proc_resize(retroflat_proc_resize_t on_resize_in, void *data_in)
Set the procedure to call when the window is resized (on platforms that support resizing).
#define retroglu_push_overlay(x, y, x_f, y_f, aspect_f)
Push current projection modelview and prepare useful parameters for drawing a textured overlay.
Definition retroglu.h:241
#define retroglu_pop_overlay()
Restore projection modelview previously pushed using retroglu_push().
Definition retroglu.h:274
void retrosnd_set_sf_bank(const char *filename_in)
Set the name of the voice bank filename to use.
MERROR_RETVAL retrosnd_init(struct RETROFLAT_ARGS *args)
Initialize retrosnd engine.
#define retroflat_screen_h()
Get the current screen height in pixels.
Definition retpltd.h:38
#define retroflat_screen_buffer()
Get the direct screen buffer or the VDP buffer if a VDP is loaded.
Definition retpltd.h:41
#define retroflat_screen_w()
Get the current screen width in pixels.
Definition retpltd.h:35
Contains functions and macros for working with fixed-point numbers.
Library of tools for working with RetroFlat and OpenGL.
Struct containing configuration values for a RetroFlat program.
Definition retroflt.h:1016
char * config_path
Relative path of local config file (if not using registry).
Definition retroflt.h:1026
char * assets_path
Relative path under which bitmap assets are stored.
Definition retroflt.h:1023
int screen_h
Desired screen or window height in pixels.
Definition retroflt.h:1033
char * title
Title to set for the main program Window if applicable on the target platform.
Definition retroflt.h:1021
int screen_y
Desired window Y position in pixels.
Definition retroflt.h:1037
int screen_x
Desired window X position in pixels.
Definition retroflt.h:1035
Platform-specific bitmap structure. retroflat_bitmap_ok() can be used on a pointer to it to determine...
Definition retpltd.h:21
Struct passed to retroflat_poll_input() to hold return data.
Definition retroflt.h:840
int mouse_y
Y-coordinate of the mouse pointer in pixels if the returned event is a mouse click.
Definition retroflt.h:850
int mouse_x
X-coordinate of the mouse pointer in pixels if the returned event is a mouse click.
Definition retroflt.h:845
Global singleton containing state for the current platform.
Definition retroflt.h:1265
char vdp_args[RETROFLAT_VDP_ARGS_SZ_MAX]
CLI args passed with -vdp to the RetroFlat VDP API.
Definition retroflt.h:1297
size_t screen_h
The screen height as seen by the system, after scaling.
Definition retroflt.h:1323
uint8_t vdp_flags
Flags set by the RetroFlat VDP API.
Definition retroflt.h:1299
size_t screen_v_w
The screen width as seen by our program, before scaling.
Definition retroflt.h:1312
uint8_t retroflat_flags
Global Flags indicating current system status.
Definition retroflt.h:1269
struct RETROFLAT_BITMAP * vdp_buffer
A buffer assembled and passed to the RetroFlat VDP API for it to modify, or NULL if no VDP is loaded.
Definition retroflt.h:1284
size_t screen_w
The screen width as seen by the system, after scaling.
Definition retroflt.h:1321
struct RETROFLAT_BITMAP buffer
Off-screen buffer bitmap.
Definition retroflt.h:1276
void * vdp_exe
A handle for the loaded RetroFlat VDP API module.
Definition retroflt.h:1289
RETROFLAT_COLOR_DEF palette[RETROFLAT_COLORS_SZ]
Index of available colors, initialized on platform init.
Definition retroflt.h:1274
void * vdp_data
Pointer to data defined by the RetroFlat VDP API for its use.
Definition retroflt.h:1295
size_t screen_v_h
The screen height as seen by our program, before scaling.
Definition retroflt.h:1319
Definition retroflt.h:1063
int16_t screen_x
X position of the viewport in real screen memory in pixels.
Definition retroflt.h:1065
int16_t screen_y
Y position of the viewport in real screen memory in pixels.
Definition retroflt.h:1067