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
5#ifdef RETROFLAT_OPENGL
6# define RETROFLAT_BMP_TEX
7#endif /* RETROFLAT_OPENGL */
8
13
19typedef int16_t retroflat_tile_t;
20
22
42
163
276
277/* === Generic Includes and Defines === */
278
279#ifndef RETROFLAT_BITMAP_TRACE_LVL
280# define RETROFLAT_BITMAP_TRACE_LVL 0
281#endif /* !RETROFLAT_BITMAP_TRACE_LVL */
282
283#ifndef RETROFLAT_KB_TRACE_LVL
284# define RETROFLAT_KB_TRACE_LVL 0
285#endif /* !RETROFLAT_KB_TRACE_LVL */
286
287#include <stdarg.h>
288
289#include <marge.h>
290
295
306#define RETROFLAT_COLOR_TABLE( f ) \
307 f( 0, black, BLACK, 0, 0, 0, BLACK, BLACK ) \
308 f( 1, darkblue, DARKBLUE, 0, 0, 170, CYAN, BLACK ) \
309 f( 2, darkgreen, DARKGREEN, 0, 170, 0, CYAN, BLACK ) \
310 f( 3, teal, TEAL, 0, 170, 170, CYAN, CYAN ) \
311 f( 4, darkred, DARKRED, 170, 0, 0, MAGENTA, BLACK ) \
312 f( 5, violet, VIOLET, 170, 0, 170, MAGENTA, BLACK ) \
313 f( 6, brown, BROWN, 170, 85, 0, CYAN, MAGENTA ) \
314 f( 7, gray, GRAY, 170, 170, 170, WHITE, BLACK ) \
315 f( 8, darkgray, DARKGRAY, 85, 85, 85, WHITE, BLACK ) \
316 f( 9, blue, BLUE, 85, 85, 255, CYAN, WHITE ) \
317 f( 10, green, GREEN, 85, 255, 85, CYAN, CYAN ) \
318 f( 11, cyan, CYAN, 85, 255, 255, CYAN, CYAN ) \
319 f( 12, red, RED, 255, 85, 85, MAGENTA, WHITE ) \
320 f( 13, magenta, MAGENTA, 255, 85, 255, MAGENTA, MAGENTA ) \
321 f( 14, yellow, YELLOW, 255, 255, 85, CYAN, MAGENTA ) \
322 f( 15, white, WHITE, 255, 255, 255, WHITE, WHITE )
323
325typedef int8_t RETROFLAT_COLOR;
326
327# define RETROFLAT_COLOR_NULL (-1)
328
329# define RETROFLAT_COLORS_SZ 16
330
332
333/* TODO: Mouse is broken under DOS/Allegro. */
334#if defined( RETROFLAT_OS_UNIX ) || defined( RETROFLAT_OS_WIN )
335#define RETROFLAT_MOUSE
336#endif /* RETROFLAT_OS_WIN || RETROFLAT_OS_WIN */
337
343
345#define RETROFLAT_OK 0x00
346#define RETROFLAT_ERROR_ENGINE 0x01
347#define RETROFLAT_ERROR_GRAPHICS 0x02
348#define RETROFLAT_ERROR_MOUSE 0x04
349
354#define RETROFLAT_ERROR_BITMAP 0x08
355#define RETROFLAT_ERROR_TIMER 0x0f
356 /* maug_retroflt_retval */
358
368
373#define RETROFLAT_FLAGS_FILL 0x01
374
379#define RETROFLAT_FLAGS_OPAQUE 0x01
380
387#define RETROFLAT_FLAGS_ALL_CAPS 0x02
388
392#define RETROFLAT_FLAGS_LITERAL_PATH 0x02
393
400#define RETROFLAT_FLAGS_SCREEN_BUFFER 0x80
401 /* maug_retroflt_drawing */
403
409
415#define RETROFLAT_FLAGS_RUNNING 0x01
416
421#define RETROFLAT_FLAGS_UNLOCK_FPS 0x02
422
427#define RETROFLAT_FLAGS_KEY_REPEAT 0x04
428
433#define RETROFLAT_FLAGS_SCREENSAVER 0x08
434
438#define RETROFLAT_FLAGS_WAIT_FOR_FPS 0x20
439 /* maug_retroflt_flags */
441
448
450#define RETROFLAT_MSG_FLAG_TYPE_MASK 0x07
451
456#define RETROFLAT_MSG_FLAG_ERROR 0x01
457
463#define RETROFLAT_MSG_FLAG_INFO 0x02
464
470#define RETROFLAT_MSG_FLAG_WARNING 0x04
471 /* maug_retroflt_msg_flags */
473
474struct RETROFLAT_STATE;
475
487
495#define RETROFLAT_VDP_FLAG_PXLOCK 0x01
496
509 /* maug_retroflt_vdp */
511
512typedef MERROR_RETVAL (*retroflat_proc_resize_t)(
513 uint16_t new_w, uint16_t new_h, void* data );
514
519
520#define RETROSND_ARGS_FLAG_LIST_DEVS 0x01
521
523
549
553#define RETROFLAT_FLAGS_LOCK 0x01
554
555#define RETROFLAT_FLAGS_SCREEN_LOCK 0x02
556
557#define RETROFLAT_FLAGS_BITMAP_RO 0x04
558
564#define RETROFLAT_INSTANCE_NULL (0)
565
570#define retroflat_instance_tile( instance ) \
571 (instance * -1)
572
577#ifndef RETROFLAT_BITMAP_EXT
578# define RETROFLAT_BITMAP_EXT "bmp"
579#endif /* !RETROFLAT_BITMAP_EXT */
580
581#ifndef RETROFLAT_OPENGL_BPP
582# define RETROFLAT_OPENGL_BPP 32
583#endif /* !RETROFLAT_OPENGL_BPP */
584
585#ifndef RETROFLAT_TILE_W
586# define RETROFLAT_TILE_W 16
587#endif /* !RETROFLAT_TILE_W */
588
589#ifndef RETROFLAT_TILE_W_BITS
590# define RETROFLAT_TILE_W_BITS 4
591#endif /* !RETROFLAT_TILE_W_BITS */
592
593#ifndef RETROFLAT_TILE_H
594# define RETROFLAT_TILE_H 16
595#endif /* !RETROFLAT_TILE_H */
596
597#ifndef RETROFLAT_TILE_H_BITS
598# define RETROFLAT_TILE_H_BITS 4
599#endif /* !RETROFLAT_TILE_H_BITS */
600
601/* Transparency background color: black by default, to match Allegro. */
602#ifndef RETROFLAT_TXP_R
608# define RETROFLAT_TXP_R 0x00
609#endif /* !RETROFLAT_TXP_R */
610
611#ifndef RETROFLAT_TXP_G
617# define RETROFLAT_TXP_G 0x00
618#endif /* !RETROFLAT_TXP_G */
619
620#ifndef RETROFLAT_TXP_B
626# define RETROFLAT_TXP_B 0x00
627#endif /* !RETROFLAT_TXP_B */
628
629#ifndef RETROFLAT_TXP_PAL_IDX
630# define RETROFLAT_TXP_PAL_IDX 0
631#endif /* !RETROFLAT_TXP_PAL_IDX */
632 /* maug_retroflt_bitmap */
634
635#ifndef RETROFLAT_DEFAULT_SCREEN_W
636# define RETROFLAT_DEFAULT_SCREEN_W 320
637#endif /* RETROFLAT_DEFAULT_SCREEN_W */
638
639#ifndef RETROFLAT_DEFAULT_SCREEN_H
640# define RETROFLAT_DEFAULT_SCREEN_H 200
641#endif /* RETROFLAT_DEFAULT_SCREEN_H */
642
643#define retroflat_on_resize( w, h ) \
644 g_retroflat_state->screen_w = w; \
645 g_retroflat_state->screen_h = h;
646
651
652#ifndef RETROFLAT_LINE_THICKNESS
657# define RETROFLAT_LINE_THICKNESS 1
658#endif /* !RETROFLAT_LINE_THICKNESS */
659
660#define RETROFLAT_PI 3.14159
661 /* maug_retroflt_drawing */
663
668
669#ifndef RETROFLAT_FPS
674# define RETROFLAT_FPS 30
675#endif /* !RETROFLAT_FPS */
676
677#define retroflat_fps_next() (1000 / RETROFLAT_FPS)
678
679#ifndef RETROFLAT_WINDOW_CLASS
684# define RETROFLAT_WINDOW_CLASS "RetroFlatWindowClass"
685#endif /* !RETROFLAT_WINDOW_CLASS */
686
687#ifndef RETROFLAT_WIN_FRAME_TIMER_ID
692# define RETROFLAT_WIN_FRAME_TIMER_ID 6001
693#endif /* !RETROFLAT_WIN_FRAME_TIMER_ID */
694
695#ifndef RETROFLAT_WIN_LOOP_TIMER_ID
700# define RETROFLAT_WIN_LOOP_TIMER_ID 6002
701#endif /* !RETROFLAT_WIN_LOOP_TIMER_ID */
702
703#ifndef RETROFLAT_MSG_MAX
708# define RETROFLAT_MSG_MAX 4096
709#endif /* !RETROFLAT_MSG_MAX */
710
711#define RETROFLAT_PATH_MAX MAUG_PATH_MAX
712
713#ifndef RETROFLAT_TITLE_MAX
714# define RETROFLAT_TITLE_MAX 255
715#endif /* !RETROFLAT_TITLE_MAX */
716
717#ifndef RETROFLAT_VDP_ARGS_SZ_MAX
721# define RETROFLAT_VDP_ARGS_SZ_MAX 255
722#endif /* !RETROFLAT_VDP_ARGS_SZ_MAX */
723
724#if defined( RETROFLAT_API_SDL2 )
725# if !defined( NO_RETROFLAT_RESIZABLE )
726# define RETROFLAT_WIN_FLAGS SDL_WINDOW_RESIZABLE
727# else
728# define RETROFLAT_WIN_FLAGS 0
729# endif /* !NO_RETROFLAT_RESIZABLE */
730#endif /* RETROFLAT_API_SDL2 */
731
732#if defined( RETROFLAT_API_SDL1 )
733# define RETROFLAT_SDL_CC_FLAGS (SDL_RLEACCEL | SDL_SRCCOLORKEY)
734#elif defined( RETROFLAT_API_SDL2 )
735# define RETROFLAT_SDL_CC_FLAGS (SDL_TRUE)
736#endif /* RETROFLAT_API_SDL1 || RETROFLAT_API_SDL2 */
737
738#ifdef RETROFLAT_OS_DOS
739# define RETROFLAT_PATH_SEP '\\'
740#else
742# define RETROFLAT_PATH_SEP '/'
743#endif /* RETROFLAT_OS_DOS */
744
746#define RETROFLAT_ASSETS_PATH_MAX (RETROFLAT_PATH_MAX >> 1)
747
748#ifndef RETROFLAT_BMP_COLORS_SZ_MAX
749# define RETROFLAT_BMP_COLORS_SZ_MAX 256
750#endif /* !RETROFLAT_BMP_COLORS_SZ_MAX */
751 /* maug_retroflt_compiling */
753
754#define retroflat_wait_for_frame() \
755 (g_retroflat_state->retroflat_flags |= RETROFLAT_FLAGS_WAIT_FOR_FPS)
756
757#define retroflat_is_waiting_for_frame() \
758 (RETROFLAT_FLAGS_WAIT_FOR_FPS == \
759 (g_retroflat_state->retroflat_flags & RETROFLAT_FLAGS_WAIT_FOR_FPS))
760
767
771typedef char retroflat_asset_path[RETROFLAT_PATH_MAX + 1];
772
776#define retroflat_cmp_asset_path( a, b ) strncmp( a, b, RETROFLAT_PATH_MAX )
777
778#define retroflat_assign_asset_path( tgt, src ) \
779 maug_strncpy( tgt, src, RETROFLAT_PATH_MAX )
780
781#define retroflat_assign_asset_trim_ext( tgt, src ) \
782 maug_snprintf( tgt, RETROFLAT_PATH_MAX, "%s", src ); \
783 if( NULL != strrchr( tgt, '.' ) ) { \
784 *(strrchr( tgt, '.' )) = '\0'; \
785 }
786 /* maug_retroflt_assets */
788
792typedef void (*retroflat_loop_iter)(void* data);
793
799
803#define retroflat_buffer_bksp( buffer, buffer_cur, buffer_sz ) \
804 if( 0 < buffer_cur ) { \
805 if( buffer_cur < buffer_sz ) { \
806 memmove( \
807 &(buffer[(buffer_cur) - 1]), \
808 &(buffer[buffer_cur]), \
809 (buffer_sz) - (buffer_cur) ); \
810 } \
811 buffer_cur--; \
812 buffer_sz--; \
813 buffer[buffer_sz] = '\0'; \
814 }
815
819#define retroflat_buffer_insert( c, buffer, buffer_cur, buffer_sz, buffer_mx ) \
820 if( buffer_sz + 1 < buffer_mx ) { \
821 if( buffer_cur < buffer_sz ) { \
822 memmove( \
823 &(buffer[(buffer_cur) + 1]), \
824 &(buffer[buffer_cur]), \
825 (buffer_sz) - (buffer_cur) ); \
826 } \
827 buffer[buffer_cur] = c; \
828 buffer_cur++; \
829 buffer_sz++; \
830 buffer[buffer_sz] = '\0'; \
831 }
832
833#define RETROFLAT_INPUT_MOD_SHIFT 0x01
834
835#define RETROFLAT_INPUT_MOD_ALT 0x02
836
837#define RETROFLAT_INPUT_MOD_CTRL 0x04
838
839#define RETROFLAT_INPUT_FORCE_UPPER 0x08
840
853 uint8_t key_flags;
854};
855 /* maug_retroflt_input */
857
864
865typedef int8_t retroflat_dir4_t;
866
867typedef int8_t retroflat_dir8_t;
868
869#define RETROFLAT_DIR4_NONE (-1)
870#define RETROFLAT_DIR4_NORTH 0
871#define RETROFLAT_DIR4_EAST 1
872#define RETROFLAT_DIR4_SOUTH 2
873#define RETROFLAT_DIR4_WEST 3
874
875#define RETROFLAT_DIR8_NONE (-1)
876#define RETROFLAT_DIR8_NORTH 0
877#define RETROFLAT_DIR8_EAST 2
878#define RETROFLAT_DIR8_SOUTH 4
879#define RETROFLAT_DIR8_WEST 6
880
881#define retroflat_dir8_reverse( dir ) \
882 ((dir + 4) % 8)
883
884#define retroflat_dir8_bounce( dir ) \
885 ((dir + 2) % 8)
886 /* maug_retroflt_dir */
888
895typedef size_t retroflat_pxxy_t;
896
897struct RETROFLAT_ARGS;
898
899#ifndef RETRO2D_TRACE_LVL
900# define RETRO2D_TRACE_LVL 0
901#endif /* !RETRO2D_TRACE_LVL */
902
903#ifndef RETROFLAT_NO_SOUND
904
932
933#ifndef RETROSND_TRACE_LVL
934# define RETROSND_TRACE_LVL 0
935#endif /* !RETROSND_TRACE_LVL */
936
937#ifndef RETROSND_REG_TRACE_LVL
938# define RETROSND_REG_TRACE_LVL 0
939#endif /* !RETROSND_REG_TRACE_LVL */
940
946
951#define RETROSND_FLAG_INIT 0x01
952 /* maug_retrosnd_flags */
954
955#define RETROSND_VOICE_BREATH 122
956
957#define RETROSND_VOICE_SEASHORE 123
958
959#define RETROSND_VOICE_BIRD_TWEET 124
960
961#define RETROSND_VOICE_PHONE_RING 125
962
963#define RETROSND_VOICE_HELICOPTER 126
964
965#define RETROSND_VOICE_APPLAUSE 127
966
971#define RETROSND_VOICE_GUNSHOT 128
972
973#define RETROSND_CHANNEL_CT 8
974
984
988void retrosnd_set_sf_bank( const char* filename_in );
989
990void retrosnd_midi_set_voice( uint8_t channel, uint8_t voice );
991
992void retrosnd_midi_set_control( uint8_t channel, uint8_t key, uint8_t val );
993
994void retrosnd_midi_note_on( uint8_t channel, uint8_t pitch, uint8_t vel );
995
996void retrosnd_midi_note_off( uint8_t channel, uint8_t pitch, uint8_t vel );
997
998MERROR_RETVAL retrosnd_midi_play_smf( const char* filename );
999
1000uint8_t retrosnd_midi_is_playing_smf();
1001
1002void retrosnd_shutdown();
1003 /* maug_retrosnd */
1005
1006#endif /* !RETROFLAT_NO_SOUND */
1007
1008/* === Platform-specific APIs === */
1009
1010/* The first call to these headers should just establish definitions (macros, defines, prototypes,
1011 * typedefs, etc). The later call below should then define function bodies.
1012 */
1013#ifndef RETROFLAT_NO_SOUND
1014# include <retapis.h>
1015#endif /* !RETROFLAT_NO_SOUND */
1016#include <retapii.h>
1017
1018/* === End platform-specific APIs === */
1019
1020
1021
1022/* === OS-Specific Includes and Defines === */
1023
1024#if defined( RETROFLAT_OS_WIN ) && !defined( MAUG_WINDOWS_H )
1025# include <windows.h>
1026# define MAUG_WINDOWS_H
1027#endif /* !MAUG_WINDOWS_H */
1028
1029#if defined( RETROFLAT_BMP_TEX ) || defined( DOCUMENTATION )
1030
1035
1037 uint8_t flags;
1038 MAUG_MHANDLE bytes_h;
1039 uint8_t* bytes;
1040 uint32_t bpp;
1041 uint32_t sz;
1042 uint8_t* px;
1043 uint32_t id;
1044 size_t w;
1045 size_t h;
1046};
1047
1048#endif /* RETROFLAT_BMP_TEX */
1049
1050/* TODO: Migrate all platform-specific parts below to retapid.h. */
1051#include <retapid.h>
1052
1053typedef maug_ms_t retroflat_ms_t;
1054
1055#include "retrom2d.h"
1056
1057/* === Structures === */
1058
1059/* TODO: Break the args into API-specific headers. */
1060
1063 uint8_t flags;
1068 char* title;
1073# if !defined( RETROFLAT_NO_CLI_SZ )
1074 int screen_w;
1081# endif /* RETROFLAT_NO_CLI_SZ */
1082 struct RETROFLAT_PLATFORM_ARGS platform;
1083# ifndef RETROFLAT_NO_SOUND
1084 struct RETROFLAT_SOUND_ARGS sound;
1085# endif /* !RETROFLAT_NO_SOUND */
1086};
1087
1098
1111 int16_t screen_x;
1117 int16_t screen_y;
1123 int16_t world_x;
1129 int16_t world_y;
1135 int16_t world_w;
1141 int16_t world_h;
1147 uint16_t screen_w;
1153 uint16_t screen_h;
1182 int16_t world_tile_x;
1183 int16_t world_tile_y;
1184#ifndef RETROFLAT_NO_VIEWPORT_REFRESH
1185 MAUG_MHANDLE refresh_grid_h;
1197#endif /* !RETROFLAT_NO_VIEWPORT_REFRESH */
1198};
1199
1200# define retroflat_screen_colors() (g_retroflat_state->screen_colors)
1201
1202#ifndef DOCUMENTATION
1203
1204# define retroflat_viewport_world_x_generic() \
1205 (g_retroflat_state->viewport.world_x)
1206
1207# define retroflat_viewport_world_y_generic() \
1208 (g_retroflat_state->viewport.world_y)
1209
1210# define retroflat_viewport_world_tile_x_generic() \
1211 (g_retroflat_state->viewport.world_tile_x)
1212
1213# define retroflat_viewport_world_tile_y_generic() \
1214 (g_retroflat_state->viewport.world_tile_y)
1215
1216# define retroflat_viewport_world_w_generic() \
1217 (g_retroflat_state->viewport.world_w)
1218
1219# define retroflat_viewport_world_h_generic() \
1220 (g_retroflat_state->viewport.world_h)
1221
1222# define retroflat_viewport_screen_tile_w_generic() \
1223 (g_retroflat_state->viewport.screen_tile_w)
1224
1225# define retroflat_viewport_screen_tile_h_generic() \
1226 (g_retroflat_state->viewport.screen_tile_h)
1227
1228# define retroflat_viewport_screen_w_generic() \
1229 (g_retroflat_state->viewport.screen_w)
1230
1231# define retroflat_viewport_screen_h_generic() \
1232 (g_retroflat_state->viewport.screen_h)
1233
1234# define retroflat_viewport_screen_w_remainder_generic() \
1235 (g_retroflat_state->viewport.screen_w_remainder)
1236
1237# define retroflat_viewport_screen_h_remainder_generic() \
1238 (g_retroflat_state->viewport.screen_h_remainder)
1239
1240# define retroflat_viewport_set_world_generic( w, h ) \
1241 debug_printf( 1, "setting viewport size to %d x %d...", \
1242 (int16_t)(w), (int16_t)(h) ); \
1243 (g_retroflat_state->viewport.world_w) = w; \
1244 (g_retroflat_state->viewport.world_h) = h;
1245
1246# define retroflat_viewport_set_world_pos_generic( x, y ) \
1247 debug_printf( 1, "setting viewport world pos to %d, %d...", x, y ); \
1248 (g_retroflat_state->viewport.world_x) = x; \
1249 (g_retroflat_state->viewport.world_y) = y; \
1250 (g_retroflat_state->viewport.world_tile_x) = (x) >> RETROFLAT_TILE_W_BITS; \
1251 (g_retroflat_state->viewport.world_tile_y) = (y) >> RETROFLAT_TILE_H_BITS;
1252
1253# define retroflat_viewport_set_pos_size_generic( x_px, y_px, w_px, h_px ) \
1254 g_retroflat_state->viewport.screen_x = (x_px); \
1255 g_retroflat_state->viewport.screen_y = (y_px); \
1256 g_retroflat_state->viewport.screen_tile_w = \
1257 ((w_px) / RETROFLAT_TILE_W); \
1258 g_retroflat_state->viewport.screen_tile_h = \
1259 ((h_px) / RETROFLAT_TILE_H); \
1260 /* We're not adding the extra room here since this won't be used for
1261 * indexing or allocation but rather pixel detection.
1262 */ \
1263 g_retroflat_state->viewport.screen_w = \
1264 ((w_px) / RETROFLAT_TILE_W) * RETROFLAT_TILE_W; \
1265 g_retroflat_state->viewport.screen_h = \
1266 ((h_px) / RETROFLAT_TILE_H) * RETROFLAT_TILE_H; \
1267 g_retroflat_state->viewport.screen_w_remainder = \
1268 (x_px) + (w_px) - g_retroflat_state->viewport.screen_w; \
1269 g_retroflat_state->viewport.screen_h_remainder = \
1270 (y_px) + (h_px) - g_retroflat_state->viewport.screen_h;
1271
1272#ifndef RETROFLAT_NO_VIEWPORT_REFRESH
1273
1274# define retroflat_viewport_lock_refresh_generic() \
1275 if( NULL == g_retroflat_state->viewport.refresh_grid ) { \
1276 maug_mlock( \
1277 g_retroflat_state->viewport.refresh_grid_h, \
1278 g_retroflat_state->viewport.refresh_grid ); \
1279 maug_cleanup_if_null_lock( retroflat_tile_t*, \
1280 g_retroflat_state->viewport.refresh_grid ); \
1281 }
1282
1283# define retroflat_viewport_unlock_refresh_generic() \
1284 if( NULL != g_retroflat_state->viewport.refresh_grid ) { \
1285 maug_munlock( \
1286 g_retroflat_state->viewport.refresh_grid_h, \
1287 g_retroflat_state->viewport.refresh_grid ); \
1288 }
1289
1290# define _retroflat_viewport_refresh_tile_x( x_px ) \
1291 (((x_px) + RETROFLAT_TILE_W) >> RETROFLAT_TILE_W_BITS)
1292
1293# define _retroflat_viewport_refresh_tile_y( y_px ) \
1294 (((y_px) + RETROFLAT_TILE_H) >> RETROFLAT_TILE_H_BITS)
1295
1296# define retroflat_viewport_set_refresh_generic( x_px, y_px, tid ) \
1297 assert( NULL != g_retroflat_state->viewport.refresh_grid ); \
1298 if( \
1299 /* Expand the range by -1 to account for just off-screen tile. */ \
1300 -(RETROFLAT_TILE_W) <= x_px && -(RETROFLAT_TILE_H) <= y_px && \
1301 retroflat_screen_w() > x_px && \
1302 retroflat_screen_h() > y_px \
1303 ) { \
1304 assert( 0 < g_retroflat_state->viewport.screen_tile_w ); \
1305 assert( 0 <= (((y_px) + RETROFLAT_TILE_H) >> RETROFLAT_TILE_H_BITS) ); \
1306 assert( 0 <= (((x_px) + RETROFLAT_TILE_W) >> RETROFLAT_TILE_W_BITS) ); \
1307 g_retroflat_state->viewport.refresh_grid[ \
1308 /* Add +1 tile to make off-screen "-1" tile positive. */ \
1309 ((_retroflat_viewport_refresh_tile_y( y_px ) + 1) * \
1310 (g_retroflat_state->viewport.screen_tile_w + 2)) + \
1311 (_retroflat_viewport_refresh_tile_x( x_px ) + 1)] = tid; \
1312 }
1313
1314# define retroflat_viewport_tile_is_stale( x_px, y_px, tile_id ) \
1315 ((tile_id) != \
1316 g_retroflat_state->viewport.refresh_grid[ \
1317 ((_retroflat_viewport_refresh_tile_y( y_px ) + 1) * \
1318 (g_retroflat_state->viewport.screen_tile_w + 2)) + \
1319 (_retroflat_viewport_refresh_tile_x( x_px ) + 1)])
1320
1321#endif /* !RETROFLAT_NO_VIEWPORT_REFRESH */
1322
1323uint8_t retroflat_viewport_move_x_generic( int16_t x );
1324
1325uint8_t retroflat_viewport_move_y_generic( int16_t y );
1326
1327uint8_t retroflat_viewport_focus_generic(
1328 size_t x1, size_t y1, size_t range, size_t speed );
1329
1330# define retroflat_viewport_screen_x_generic( world_x ) \
1331 (g_retroflat_state->viewport.screen_x + \
1332 ((world_x) - retroflat_viewport_world_x()))
1333
1334# define retroflat_viewport_screen_y_generic( world_y ) \
1335 (g_retroflat_state->viewport.screen_y + \
1336 ((world_y) - retroflat_viewport_world_y()))
1337
1338#endif /* !DOCUMENTATION */
1339
1340#if defined( RETROFLAT_SOFT_VIEWPORT ) || defined( DOCUMENTATION )
1341
1342# ifndef RETROFLAT_NO_VIEWPORT_REFRESH
1343 /* These clamp world coordinates to tile borders to allow refresh grid to
1344 * function properly (smooth-scrolling tiles will always be in motion).
1345 */
1346
1351# define retroflat_viewport_world_x() \
1352 ((retroflat_viewport_world_x_generic() \
1353 >> RETROFLAT_TILE_W_BITS) << RETROFLAT_TILE_W_BITS)
1354
1359# define retroflat_viewport_world_y() \
1360 ((retroflat_viewport_world_y_generic() \
1361 >> RETROFLAT_TILE_H_BITS) << RETROFLAT_TILE_H_BITS)
1362# else
1363# define retroflat_viewport_world_x() retroflat_viewport_world_x_generic()
1364# define retroflat_viewport_world_y() retroflat_viewport_world_y_generic()
1365#endif /* !RETROFLAT_NO_VIEWPORT_REFRESH */
1366
1367# define retroflat_viewport_world_tile_x() \
1368 retroflat_viewport_world_tile_x_generic()
1369# define retroflat_viewport_world_tile_y() \
1370 retroflat_viewport_world_tile_y_generic()
1371
1376# define retroflat_viewport_world_w() \
1377 retroflat_viewport_world_w_generic()
1378
1383# define retroflat_viewport_world_h() \
1384 retroflat_viewport_world_h_generic()
1385
1390# define retroflat_viewport_screen_tile_w() \
1391 retroflat_viewport_screen_tile_w_generic()
1392
1397# define retroflat_viewport_screen_tile_h() \
1398 retroflat_viewport_screen_tile_h_generic()
1399
1404# define retroflat_viewport_screen_w() \
1405 retroflat_viewport_screen_w_generic()
1406
1411# define retroflat_viewport_screen_h() \
1412 retroflat_viewport_screen_h_generic()
1413
1419# define retroflat_viewport_screen_w_remainder() \
1420 retroflat_viewport_screen_w_remainder_generic()
1421
1427# define retroflat_viewport_screen_h_remainder() \
1428 retroflat_viewport_screen_h_remainder_generic()
1429
1437# define retroflat_viewport_set_world( w, h ) \
1438 retroflat_viewport_set_world_generic( w, h )
1439
1444# define retroflat_viewport_set_world_pos( x, y ) \
1445 retroflat_viewport_set_world_pos_generic( x, y )
1446
1452# define retroflat_viewport_set_pos_size( x_px, y_px, w_px, h_px ) \
1453 retroflat_viewport_set_pos_size_generic( x_px, y_px, w_px, h_px )
1454
1455#ifndef RETROFLAT_NO_VIEWPORT_REFRESH
1456
1464# define retroflat_viewport_lock_refresh() \
1465 retroflat_viewport_lock_refresh_generic()
1466
1474# define retroflat_viewport_unlock_refresh() \
1475 retroflat_viewport_unlock_refresh_generic()
1476
1488# define retroflat_viewport_set_refresh( x, y, tid ) \
1489 retroflat_viewport_set_refresh_generic( x, y, tid )
1490
1491#endif /* !RETROFLAT_NO_VIEWPORT_REFRESH */
1492
1505# define retroflat_viewport_focus( x1, y1, range, speed ) \
1506 retroflat_viewport_focus_generic( x1, y1, range, speed )
1507
1512# define retroflat_viewport_screen_x( world_x ) \
1513 retroflat_viewport_screen_x_generic( world_x )
1514
1519# define retroflat_viewport_screen_y( world_y ) \
1520 retroflat_viewport_screen_y_generic( world_y )
1521
1522# ifndef RETROFLAT_VIEWPORT_OVERRIDE_MOVE
1523# define retroflat_viewport_move_x( x ) \
1524 retroflat_viewport_move_x_generic( x )
1525
1526# define retroflat_viewport_move_y( y ) \
1527 retroflat_viewport_move_y_generic( y )
1528# endif /* !RETROFLAT_VIEWPORT_OVERRIDE_MOVE */
1529
1530#endif /* RETROFLAT_SOFT_VIEWPORT || DOCUMENTATION */
1531
1533
1540#define retroflat_heartbeat_set( len, max ) \
1541 g_retroflat_state->heartbeat_max = max; \
1542 g_retroflat_state->heartbeat_len = len;
1543
1548#define retroflat_heartbeat() (g_retroflat_state->heartbeat_frame)
1549
1556#define retroflat_heartbeat_update() \
1557 /* Update the heartbeat animation frame. */ \
1558 if( g_retroflat_state->heartbeat_next <= retroflat_get_ms() ) { \
1559 g_retroflat_state->heartbeat_frame++; \
1560 if( \
1561 g_retroflat_state->heartbeat_frame >= \
1562 g_retroflat_state->heartbeat_max \
1563 ) { \
1564 g_retroflat_state->heartbeat_frame = 0; \
1565 } \
1566 g_retroflat_state->heartbeat_next = \
1567 retroflat_get_ms() + g_retroflat_state->heartbeat_len; \
1568 }
1569
1577 /* TODO: Set this up in the initialization function! */
1578 /* TODO: We probably need more of these. */
1579 size_t sz;
1580 size_t offset_pal;
1581 size_t offset_tex_pal;
1582
1583 void* loop_data;
1584 MERROR_RETVAL retval;
1587 char config_path[RETROFLAT_PATH_MAX + 1];
1588 char assets_path[RETROFLAT_ASSETS_PATH_MAX + 1];
1590 struct RETROFLAT_BITMAP buffer;
1591 int scale;
1592
1593# if defined( RETROFLAT_VDP ) || defined( DOCUMENTATION ) || \
1594defined( RETROVDP_C )
1599 struct RETROFLAT_BITMAP* vdp_buffer;
1600# ifdef RETROFLAT_OS_WIN
1601 HMODULE vdp_exe;
1602# else
1604 void* vdp_exe;
1605# endif /* RETROFLAT_OS_WIN */
1614 uint8_t vdp_flags;
1615# endif /* RETROFLAT_VDP || DOCUMENTATION || RETROVDP_C */
1616
1617 /* These are used by VDP so should be standardized/not put in plat-spec! */
1618
1619 struct RETROFLAT_VIEWPORT viewport;
1620
1636 size_t screen_w;
1638 size_t screen_h;
1641
1642 /* WARNING: The VDP requires the state specifier to be the same size
1643 * as the one it was compiled for! Do not modify above here!
1644 */
1645
1646 /* TODO: Put these in a platform-specific struct of some kind to maintain
1647 * consistent state struct size for VDP?
1648 */
1649
1650 retroflat_ms_t heartbeat_next;
1668
1669 retroflat_proc_resize_t on_resize;
1670 void* on_resize_data;
1671
1672#ifndef RETROFLAT_OPENGL
1674 RETROFLAT_COLOR_DEF palette[RETROFLAT_COLORS_SZ];
1675#endif /* !RETROFLAT_OPENGL */
1676
1677 retroflat_loop_iter loop_iter;
1678 retroflat_loop_iter frame_iter;
1679
1680 struct RETROFLAT_PLATFORM platform;
1681
1682# if defined( RETROFLAT_3D )
1683 /* This allows native colors to be used for things like glColor3fv while
1684 * these colors are used to manipulate textures passed through
1685 * retroflat_bitmap_*()
1686 */
1687 uint8_t tex_palette[RETROFLAT_COLORS_SZ][3];
1688# endif /* RETROFLAT_OPENGL */
1689
1690 struct RETROFLAT_INPUT_STATE input;
1691
1692# ifndef RETROFLAT_NO_SOUND
1693 struct RETROFLAT_SOUND_STATE sound;
1694# endif /* !RETROFLAT_NO_SOUND */
1695};
1696
1697/* === Translation Module === */
1698
1699/* Declare the prototypes so that internal functions can call each other. */
1700
1701# ifdef retroflat_loop
1702MERROR_RETVAL retroflat_loop_generic(
1703 retroflat_loop_iter frame_iter, retroflat_loop_iter loop_iter, void* data );
1704# else
1711 retroflat_loop_iter frame_iter, retroflat_loop_iter loop_iter, void* data );
1712# endif /* retroflat_loop */
1713
1721 uint8_t flags, const char* title, const char* format, ... );
1722
1730MERROR_RETVAL retroflat_init( int argc, char* argv[], struct RETROFLAT_ARGS* args );
1731
1738void retroflat_shutdown( int retval );
1739
1740# if defined( RETROFLAT_VDP ) || defined( DOCUMENTATION )
1745
1749MERROR_RETVAL retroflat_vdp_call( const char* proc_name );
1750 /* maug_retroflt_vdp */
1752# endif /* RETROFLAT_VDP || DOCUMENTATION */
1753
1754void retroflat_set_title( const char* format, ... );
1755
1756retroflat_ms_t retroflat_get_ms();
1757
1758uint32_t retroflat_get_rand();
1759
1760# if !defined( RETROFLAT_NO_KEYBOARD )
1761char retroflat_vk_to_ascii( RETROFLAT_IN_KEY k, uint8_t flags );
1762# endif /* !RETROFLAT_NO_KEYBOARD */
1763
1768
1780 const char* filename, struct RETROFLAT_BITMAP* bmp_out, uint8_t flags );
1781
1782MERROR_RETVAL retroflat_create_bitmap(
1783 size_t w, size_t h, struct RETROFLAT_BITMAP* bmp_out, uint8_t flags );
1784
1790void retroflat_destroy_bitmap( struct RETROFLAT_BITMAP* bitmap );
1791
1808 struct RETROFLAT_BITMAP* target, struct RETROFLAT_BITMAP* src,
1809 size_t s_x, size_t s_y, int16_t d_x, int16_t d_y, size_t w, size_t h,
1810 int16_t instance );
1811
1819#define retroflat_constrain_px( x, y, bmp, retact ) \
1820 if( \
1821 x >= retroflat_bitmap_w( bmp ) || y >= retroflat_bitmap_h( bmp ) \
1822 ) { retact; }
1823 /* maug_retroflt_bitmap */
1825
1830
1840MERROR_RETVAL retroflat_draw_lock( struct RETROFLAT_BITMAP* bmp );
1841
1842MERROR_RETVAL retroflat_draw_release( struct RETROFLAT_BITMAP* bmp );
1843
1844void retroflat_px(
1845 struct RETROFLAT_BITMAP* target, const RETROFLAT_COLOR color,
1846 size_t x, size_t y, uint8_t flags );
1847
1848#ifdef RETROFLAT_SOFT_SHAPES
1849# ifdef RETROFLAT_OPENGL
1850/* Make sure we're not passing NULL to openGL texture drawers... they can't
1851 * handle that!
1852 */
1853# define retroflat_rect( t, c, x, y, w, h, f ) \
1854 assert( NULL != t ); \
1855 retrosoft_rect( t, c, x, y, w, h, f );
1856# define retroflat_ellipse( t, c, x, y, w, h, f ) \
1857 assert( NULL != t ); \
1858 retrosoft_ellipse( t, c, x, y, w, h, f )
1859# else
1860# define retroflat_rect( t, c, x, y, w, h, f ) \
1861 retrosoft_rect( t, c, x, y, w, h, f )
1862# define retroflat_ellipse( t, c, x, y, w, h, f ) \
1863 retrosoft_ellipse( t, c, x, y, w, h, f )
1864# endif /* RETROFLAT_3D */
1865#else
1866
1878 struct RETROFLAT_BITMAP* target, const RETROFLAT_COLOR color,
1879 int16_t x, int16_t y, int16_t w, int16_t h, uint8_t flags );
1880
1892 struct RETROFLAT_BITMAP* target, const RETROFLAT_COLOR color,
1893 int16_t x, int16_t y, int16_t w, int16_t h, uint8_t flags );
1894
1895#endif /* RETROFLAT_SOFT_SHAPES */
1896
1897#ifdef RETROFLAT_SOFT_LINES
1898# define retroflat_line( t, c, x1, y1, x2, y2, f ) \
1899 retrosoft_line( t, c, x1, y1, x2, y2, f )
1900#else
1901
1914 struct RETROFLAT_BITMAP* target, const RETROFLAT_COLOR color,
1915 int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint8_t flags );
1916
1917#endif /* RETROFLAT_SOFT_LINES */
1918
1919void retroflat_cursor( struct RETROFLAT_BITMAP* target, uint8_t flags );
1920
1934 struct RETROFLAT_BITMAP* target, const char* str, size_t str_sz,
1935 const char* font_str, size_t* w_out, size_t* h_out, uint8_t flags );
1936
1955 struct RETROFLAT_BITMAP* target, const RETROFLAT_COLOR color,
1956 const char* str, int str_sz, const char* font_str, int16_t x_orig, int16_t y_orig,
1957 uint8_t flags );
1958
1959/* TODO: Documentation! */
1960void retroflat_get_palette( uint8_t idx, uint32_t* rgb );
1961
1962MERROR_RETVAL retroflat_set_palette( uint8_t idx, uint32_t rgb );
1963 /* maug_retroflt_bitmap */
1965
1976 retroflat_proc_resize_t on_resize_in, void* data_in );
1977
1983
1988
1994RETROFLAT_IN_KEY retroflat_poll_input( struct RETROFLAT_INPUT* input );
1995 /* maug_retroflt_input */
1997
1998#ifdef RETROFLT_C
1999
2000MAUG_CONST int16_t SEG_MCONST gc_retroflat_offsets8_x[8] =
2001 { 0, 1, 1, 1, 0, -1, -1, -1 };
2002MAUG_CONST int16_t SEG_MCONST gc_retroflat_offsets8_y[8] =
2003 { -1, -1, 0, 1, 1, 1, 0, -1 };
2004
2005MAUG_CONST int16_t SEG_MCONST gc_retroflat_offsets4_x[4] =
2006 { 0, 1, 0, -1 };
2007MAUG_CONST int16_t SEG_MCONST gc_retroflat_offsets4_y[4] =
2008 { -1, 0, 1, 0 };
2009
2010MAUG_MHANDLE g_retroflat_state_h = (MAUG_MHANDLE)NULL;
2011struct RETROFLAT_STATE* g_retroflat_state = NULL;
2012
2013# define RETROFLAT_COLOR_TABLE_CONSTS( idx, name_l, name_u, r, g, b, cgac, cgad ) \
2014 MAUG_CONST RETROFLAT_COLOR RETROFLAT_COLOR_ ## name_u = idx;
2015
2016RETROFLAT_COLOR_TABLE( RETROFLAT_COLOR_TABLE_CONSTS )
2017
2018# define RETROFLAT_COLOR_TABLE_NAMES( idx, name_l, name_u, r, g, b, cgac, cgad ) \
2019 #name_u,
2020
2021MAUG_CONST char* SEG_MCONST gc_retroflat_color_names[] = {
2022 RETROFLAT_COLOR_TABLE( RETROFLAT_COLOR_TABLE_NAMES )
2023};
2024
2025/* Callback table is down below, after the statically-defined callbacks. */
2026
2027/* === Function Definitions === */
2028
2029MERROR_RETVAL retroflat_build_filename_path(
2030 const char* filename_in,
2031 char* buffer_out, size_t buffer_out_sz, uint8_t flags
2032) {
2033 MERROR_RETVAL retval = MERROR_OK;
2034
2035 assert( 1 < buffer_out_sz );
2036
2037 /* Build the path to the bitmap. */
2038 memset( buffer_out, '\0', buffer_out_sz );
2039 if(
2042 ) {
2043 /* TODO: Error checking. */
2044 maug_snprintf( buffer_out, buffer_out_sz - 1, "%s", filename_in );
2045 } else {
2046 /* TODO: Error checking. */
2047 maug_snprintf( buffer_out, buffer_out_sz - 1, "%s%c%s.%s",
2048 g_retroflat_state->assets_path, RETROFLAT_PATH_SEP,
2049 filename_in, RETROFLAT_BITMAP_EXT );
2050 }
2051
2052 return retval;
2053}
2054
2055/* === */
2056
2057# if (defined( RETROFLAT_SOFT_SHAPES ) || defined( RETROFLAT_SOFT_LINES ) || \
2058 defined( RETROFLAT_3D ))
2059/* RETROSOFT_PRESENT is different from RETROFLAT_SOFT_SHAPES in that it only
2060 * indicates that the retrosoft library is loaded, not that it is the default
2061 * for drawing primatives!
2062 */
2063# define RETROSOFT_PRESENT
2064# endif
2065
2066# if defined( RETROFLAT_3D )
2067# if !defined( MAUG_NO_AUTO_C )
2068# define RETRO3D_C
2069# define RETRO3DP_C
2070# define RETROFP_C
2071# endif /* MAUG_NO_AUTO_C */
2072# include <retro3dp.h>
2073# include <retro3d.h>
2074# include <retro3du.h>
2075# include <retapi3.h>
2076# endif /* RETROFLAT_3D */
2077
2078# ifdef RETROSOFT_PRESENT
2079# if !defined( MAUG_NO_AUTO_C )
2080# define RETROSFT_C
2081# endif /* !MAUG_NO_AUTO_C */
2082# define RETROSOFT_PRESENT
2083# include <retrosft.h>
2084# endif /* RETROFLAT_SOFT_SHAPES */
2085
2086# ifndef RETROFLAT_NO_SOUND
2087# include <retapis.h>
2088# endif /* !RETROFLAT_NO_SOUND */
2089
2090# include <retapii.h>
2091
2092# if defined( RETROFLAT_VDP ) && defined( RETROFLAT_OS_UNIX )
2093# include <dlfcn.h>
2094# endif
2095
2096/* Still inside RETROFLT_C! */
2097
2098/* === */
2099
2100#ifndef RETROFLAT_NO_GENERIC_LOOP
2101
2102MERROR_RETVAL retroflat_loop_generic(
2103 retroflat_loop_iter frame_iter, retroflat_loop_iter loop_iter, void* data
2104) {
2105 MERROR_RETVAL retval = MERROR_OK;
2106 retroflat_ms_t next = 0,
2107 now = 0;
2108
2109 g_retroflat_state->loop_iter = (retroflat_loop_iter)loop_iter;
2110 g_retroflat_state->loop_data = (void*)data;
2111 g_retroflat_state->frame_iter = (retroflat_loop_iter)frame_iter;
2112
2113 if(
2115 (g_retroflat_state->retroflat_flags & RETROFLAT_FLAGS_RUNNING)
2116 ) {
2117 /* Main loop is already running, so we're just changing the iter call
2118 * and leaving!
2119 */
2120 debug_printf( 1, "main loop already running!" );
2121 goto cleanup;
2122 }
2123
2124 g_retroflat_state->retroflat_flags |= RETROFLAT_FLAGS_RUNNING;
2125 do {
2126 if(
2127 /* Not waiting for the next frame? */
2129 (RETROFLAT_FLAGS_WAIT_FOR_FPS & g_retroflat_state->retroflat_flags) &&
2130 /* Inter-frame loop present? */
2131 NULL != g_retroflat_state->loop_iter
2132 ) {
2133 /* Run the loop iter as many times as possible. */
2134 g_retroflat_state->loop_iter( g_retroflat_state->loop_data );
2135 }
2136 if(
2138 (RETROFLAT_FLAGS_UNLOCK_FPS & g_retroflat_state->retroflat_flags) &&
2139 retroflat_get_ms() < next
2140 ) {
2141 /* Sleep/low power for a bit. */
2142 continue;
2143 }
2144
2146
2147 if( NULL != g_retroflat_state->frame_iter ) {
2148 /* Run the frame iterator once per FPS tick. */
2149 g_retroflat_state->frame_iter( g_retroflat_state->loop_data );
2150 }
2151 /* Reset wait-for-frame flag AFTER frame callback. */
2152 g_retroflat_state->retroflat_flags &= ~RETROFLAT_FLAGS_WAIT_FOR_FPS;
2153 now = retroflat_get_ms();
2154 if( now + retroflat_fps_next() > now ) {
2155 next = now + retroflat_fps_next();
2156 } else {
2157 /* Rollover protection. */
2158 /* TODO: Add difference from now/next to 0 here. */
2159 next = 0;
2160 }
2161 } while(
2163 (RETROFLAT_FLAGS_RUNNING & g_retroflat_state->retroflat_flags)
2164 );
2165 retval = g_retroflat_state->retval;
2166
2167cleanup:
2168
2169 /* This should be set by retroflat_quit(). */
2170 return retval;
2171}
2172
2173#endif /* !RETROFLAT_NO_GENERIC_LOOP */
2174
2175/* === */
2176
2177# if !defined( RETROFLAT_NO_KEYBOARD )
2178
2179char retroflat_vk_to_ascii( RETROFLAT_IN_KEY k, uint8_t flags ) {
2180 char c = 0;
2181 char offset_lower = 0;
2182
2183 if( RETROFLAT_INPUT_MOD_SHIFT != (RETROFLAT_INPUT_MOD_SHIFT & flags) ) {
2184 /* Shift is *not* being held down. */
2185
2186 if( RETROFLAT_KEY_A <= k && RETROFLAT_KEY_Z >= k ) {
2187 if(
2188 RETROFLAT_INPUT_FORCE_UPPER !=
2189 (RETROFLAT_INPUT_FORCE_UPPER & flags)
2190 ) {
2191 /* Key is alphabetical and we're not forcing uppercase. */
2192 offset_lower = 0x20;
2193 }
2194 } else {
2195 offset_lower = 1;
2196 }
2197 }
2198
2199 switch( k ) {
2200 case RETROFLAT_KEY_A: c = 0x41 + offset_lower; break;
2201 case RETROFLAT_KEY_B: c = 0x42 + offset_lower; break;
2202 case RETROFLAT_KEY_C: c = 0x43 + offset_lower; break;
2203 case RETROFLAT_KEY_D: c = 0x44 + offset_lower; break;
2204 case RETROFLAT_KEY_E: c = 0x45 + offset_lower; break;
2205 case RETROFLAT_KEY_F: c = 0x46 + offset_lower; break;
2206 case RETROFLAT_KEY_G: c = 0x47 + offset_lower; break;
2207 case RETROFLAT_KEY_H: c = 0x48 + offset_lower; break;
2208 case RETROFLAT_KEY_I: c = 0x49 + offset_lower; break;
2209 case RETROFLAT_KEY_J: c = 0x4a + offset_lower; break;
2210 case RETROFLAT_KEY_K: c = 0x4b + offset_lower; break;
2211 case RETROFLAT_KEY_L: c = 0x4c + offset_lower; break;
2212 case RETROFLAT_KEY_M: c = 0x4d + offset_lower; break;
2213 case RETROFLAT_KEY_N: c = 0x4e + offset_lower; break;
2214 case RETROFLAT_KEY_O: c = 0x4f + offset_lower; break;
2215 case RETROFLAT_KEY_P: c = 0x50 + offset_lower; break;
2216 case RETROFLAT_KEY_Q: c = 0x51 + offset_lower; break;
2217 case RETROFLAT_KEY_R: c = 0x52 + offset_lower; break;
2218 case RETROFLAT_KEY_S: c = 0x53 + offset_lower; break;
2219 case RETROFLAT_KEY_T: c = 0x54 + offset_lower; break;
2220 case RETROFLAT_KEY_U: c = 0x55 + offset_lower; break;
2221 case RETROFLAT_KEY_V: c = 0x56 + offset_lower; break;
2222 case RETROFLAT_KEY_W: c = 0x57 + offset_lower; break;
2223 case RETROFLAT_KEY_X: c = 0x58 + offset_lower; break;
2224 case RETROFLAT_KEY_Y: c = 0x59 + offset_lower; break;
2225 case RETROFLAT_KEY_Z: c = 0x60 + offset_lower; break;
2226 case RETROFLAT_KEY_0: c = offset_lower ? 0x30 : ')'; break;
2227 case RETROFLAT_KEY_1: c = offset_lower ? 0x31 : '!'; break;
2228 case RETROFLAT_KEY_2: c = offset_lower ? 0x32 : '@'; break;
2229 case RETROFLAT_KEY_3: c = offset_lower ? 0x33 : '#'; break;
2230 case RETROFLAT_KEY_4: c = offset_lower ? 0x34 : '$'; break;
2231 case RETROFLAT_KEY_5: c = offset_lower ? 0x35 : '%'; break;
2232 case RETROFLAT_KEY_6: c = offset_lower ? 0x36 : '^'; break;
2233 case RETROFLAT_KEY_7: c = offset_lower ? 0x37 : '&'; break;
2234 case RETROFLAT_KEY_8: c = offset_lower ? 0x38 : '*'; break;
2235 case RETROFLAT_KEY_9: c = offset_lower ? 0x39 : '('; break;
2236 case RETROFLAT_KEY_SPACE: c = ' '; break;
2237 case RETROFLAT_KEY_BKSP: c = 0x08; break;
2238 case RETROFLAT_KEY_ENTER: c = '\n'; break;
2239 case RETROFLAT_KEY_SEMICOLON: c = offset_lower ? ';' : ':'; break;
2240 case RETROFLAT_KEY_DASH: c = offset_lower ? '-' : '_'; break;
2241 case RETROFLAT_KEY_SLASH: c = offset_lower ? '/' : '?'; break;
2242 case RETROFLAT_KEY_PERIOD: c = offset_lower ? '.' : '>'; break;
2243 case RETROFLAT_KEY_COMMA: c = offset_lower ? ',' : '<'; break;
2244 case RETROFLAT_KEY_QUOTE: c = offset_lower ? '\'' : '"'; break;
2245 case RETROFLAT_KEY_EQUALS: c = offset_lower ? '=' : '+'; break;
2246 case RETROFLAT_KEY_BACKSLASH: c = offset_lower ? '\\' : '|'; break;
2247 case RETROFLAT_KEY_BRACKETL: c = offset_lower ? '[' : '{'; break;
2248 case RETROFLAT_KEY_BRACKETR: c = offset_lower ? ']' : '}'; break;
2249#ifndef RETROFLAT_API_PC_BIOS
2250 /* TODO: FIXME in DOS! */
2251 case RETROFLAT_KEY_GRAVE: c = offset_lower ? '`' : '~'; break;
2252#endif /* !RETROFLAT_API_PC_BIOS */
2253 }
2254
2255 debug_printf( RETROFLAT_KB_TRACE_LVL, "0x%02x", c );
2256
2257 return c;
2258}
2259
2260#endif /* !RETROFLAT_NO_KEYBOARD */
2261
2262/* === */
2263
2264/* TODO: Migrate all platform-specific parts below to retapif.h. */
2265#include <retapif.h>
2266
2267/* === */
2268
2269# ifndef RETROFLAT_NO_CLI
2270
2271# if !defined( RETROFLAT_NO_SOUND ) && defined( RETROSND_ARGS )
2272
2273static MERROR_RETVAL retrosnd_cli_rsl(
2274 const char* arg, ssize_t arg_c, struct RETROFLAT_ARGS* args
2275) {
2276 if(
2277 0 <= arg_c &&
2278 0 == strncmp( MAUG_CLI_SIGIL "rsl", arg, MAUG_CLI_SIGIL_SZ + 4 )
2279 ) {
2280 args->sound.flags |= RETROSND_ARGS_FLAG_LIST_DEVS;
2281 }
2282 return MERROR_OK;
2283}
2284
2285# endif /* !RETROFLAT_NO_SOUND && RETROSND_ARGS */
2286
2287# if !defined( RETROFLAT_API_PC_BIOS ) && !defined( RETROFLAT_NO_CLI_SZ )
2288
2289static MERROR_RETVAL retroflat_cli_rfs(
2290 const char* arg, ssize_t arg_c, struct RETROFLAT_ARGS* args
2291) {
2292 if( 0 < arg_c ) {
2293 g_retroflat_state->scale = atoi( arg );
2294 debug_printf( 3, "screen scale set to: %d",
2295 g_retroflat_state->scale );
2296 }
2297 return MERROR_OK;
2298}
2299
2300static MERROR_RETVAL retroflat_cli_rfx(
2301 const char* arg, ssize_t arg_c, struct RETROFLAT_ARGS* args
2302) {
2303 if( 0 > arg_c ) {
2304 if( 0 == args->screen_w ) {
2305 args->screen_x = 0;
2306 }
2307 } else if(
2308 0 == strncmp( MAUG_CLI_SIGIL "rfx", arg, MAUG_CLI_SIGIL_SZ + 4 )
2309 ) {
2310 /* The next arg must be the new var. */
2311 } else {
2312 args->screen_x = atoi( arg );
2313 }
2314 return MERROR_OK;
2315}
2316
2317static MERROR_RETVAL retroflat_cli_rfy(
2318 const char* arg, ssize_t arg_c, struct RETROFLAT_ARGS* args
2319) {
2320 if( 0 > arg_c ) {
2321 if( 0 == args->screen_h ) {
2322 args->screen_y = 0;
2323 }
2324 } else if(
2325 0 == strncmp( MAUG_CLI_SIGIL "rfy", arg, MAUG_CLI_SIGIL_SZ + 4 )
2326 ) {
2327 /* The next arg must be the new var. */
2328 } else {
2329 args->screen_y = atoi( arg );
2330 }
2331 return MERROR_OK;
2332}
2333
2334static MERROR_RETVAL retroflat_cli_rfw(
2335 const char* arg, ssize_t arg_c, struct RETROFLAT_ARGS* args
2336) {
2337 if( 0 > arg_c ) {
2338 if( 0 == args->screen_w ) {
2339 args->screen_w = RETROFLAT_DEFAULT_SCREEN_W;
2340 }
2341 } else if(
2342 0 == strncmp( MAUG_CLI_SIGIL "rfw", arg, MAUG_CLI_SIGIL_SZ + 4 )
2343 ) {
2344 /* The next arg must be the new var. */
2345 } else {
2346 args->screen_w = atoi( arg );
2347 }
2348 return MERROR_OK;
2349}
2350
2351static MERROR_RETVAL retroflat_cli_rfh(
2352 const char* arg, ssize_t arg_c, struct RETROFLAT_ARGS* args
2353) {
2354 if( 0 > arg_c ) {
2355 if( 0 == args->screen_h ) {
2356 args->screen_h = RETROFLAT_DEFAULT_SCREEN_H;
2357 }
2358 } else if(
2359 0 == strncmp( MAUG_CLI_SIGIL "rfh", arg, MAUG_CLI_SIGIL_SZ + 4 )
2360 ) {
2361 /* The next arg must be the new var. */
2362 } else {
2363 args->screen_h = atoi( arg );
2364 }
2365 return MERROR_OK;
2366}
2367
2368# endif /* !RETROFLAT_API_PC_BIOS && !RETROFLAT_NO_CLI_SZ */
2369
2370# ifdef RETROFLAT_VDP
2371static MERROR_RETVAL retroflat_cli_vdp(
2372 const char* arg, ssize_t arg_c, struct RETROFLAT_ARGS* args
2373) {
2374 if( 0 == strncmp( MAUG_CLI_SIGIL "vdp", arg, MAUG_CLI_SIGIL_SZ + 4 ) ) {
2375 /* Next arg is VDP args str. */
2376 } else {
2377 maug_strncpy( g_retroflat_state->vdp_args, arg, RETROFLAT_VDP_ARGS_SZ_MAX );
2378 debug_printf( 1, "VDP args: %s", g_retroflat_state->vdp_args );
2379 }
2380 return MERROR_OK;
2381}
2382# endif /* RETROFLAT_VDP */
2383
2384static MERROR_RETVAL retroflat_cli_u(
2385 const char* arg, ssize_t arg_c, struct RETROFLAT_ARGS* args
2386) {
2387 if( 0 > arg_c ) {
2388 args->flags &= ~RETROFLAT_FLAGS_UNLOCK_FPS;
2389 } else if(
2390 0 == strncmp( MAUG_CLI_SIGIL "rfu", arg, MAUG_CLI_SIGIL_SZ + 4 )
2391 ) {
2392 debug_printf( 1, "unlocking FPS..." );
2393 args->flags |= RETROFLAT_FLAGS_UNLOCK_FPS;
2394 }
2395 return MERROR_OK;
2396}
2397
2398#endif /* !RETROFLAT_NO_CLI */
2399
2400/* === */
2401
2402/* Still inside RETROFLT_C! */
2403
2404int retroflat_init( int argc, char* argv[], struct RETROFLAT_ARGS* args ) {
2405
2406 /* = Declare Init Vars = */
2407
2408 int retval = 0;
2409
2410 /* = Begin Init Procedure = */
2411
2412# ifdef RETROFLAT_COMMIT_HASH
2413 debug_printf( 1, "retroflat commit: " RETROFLAT_COMMIT_HASH );
2414# endif /* RETROFLAT_COMMIT_HASH */
2415
2416 debug_printf( 1, "retroflat: initializing..." );
2417
2418 /* System sanity checks. */
2419 assert( 2 <= sizeof( MERROR_RETVAL ) );
2420 assert( 4 == sizeof( uint32_t ) );
2421 assert( 4 == sizeof( int32_t ) );
2422 assert( 2 == sizeof( uint16_t ) );
2423 assert( 2 == sizeof( int16_t ) );
2424 assert( 1 == sizeof( uint8_t ) );
2425 assert( 1 == sizeof( int8_t ) );
2426 assert( NULL != args );
2427 assert( 1 << RETROFLAT_TILE_W_BITS == RETROFLAT_TILE_W );
2428 assert( 1 << RETROFLAT_TILE_H_BITS == RETROFLAT_TILE_H );
2429
2430 /* Initialize 2D callbacks depending on if we're in 2D or 3D mode.
2431 * Please see retrom2d.h for more information.
2432 */
2433# if defined( RETROFLAT_BMP_TEX )
2434 retroflat_2d_px = (retroflat_px_cb)retro3d_texture_px;
2435 retroflat_2d_line = (retroflat_line_cb)retrosoft_line;
2436 retroflat_2d_rect = (retroflat_rect_cb)retrosoft_rect;
2437 retroflat_2d_blit_bitmap = (retroflat_blit_bitmap_cb)retro3d_texture_blit;
2438 retroflat_2d_load_bitmap =
2439 (retroflat_load_bitmap_cb)retro3d_texture_load_bitmap;
2440 retroflat_2d_create_bitmap =
2441 (retroflat_create_bitmap_cb)retro3d_texture_create;
2442# else
2443 retroflat_2d_px = (retroflat_px_cb)retroflat_px;
2444# ifdef RETROFLAT_SOFT_SHAPES
2445 /* TODO: Work retrosoft routines to use retroflat_blit_t */
2446 retroflat_2d_line = (retroflat_line_cb)retrosoft_line;
2447 retroflat_2d_rect = (retroflat_rect_cb)retrosoft_rect;
2448# else
2449 retroflat_2d_line = (retroflat_line_cb)retroflat_line;
2450 retroflat_2d_rect = (retroflat_rect_cb)retroflat_rect;
2451# endif /* RETROFLAT_SOFT_SHAPES */
2452 retroflat_2d_blit_bitmap = (retroflat_blit_bitmap_cb)retroflat_blit_bitmap;
2453 retroflat_2d_load_bitmap = (retroflat_load_bitmap_cb)retroflat_load_bitmap;
2454 retroflat_2d_create_bitmap =
2455 (retroflat_create_bitmap_cb)retroflat_create_bitmap;
2456# endif /* RETROFLAT_BMP_TEX */
2457
2458 debug_printf( 1, "retroflat: MFIX_PRECISION: %f", MFIX_PRECISION );
2459
2460 debug_printf( 1, "retroflat: allocating state (" SIZE_T_FMT " bytes)...",
2461 sizeof( struct RETROFLAT_STATE ) );
2462
2463 debug_printf( 1, "retroflat: size_t is (" SIZE_T_FMT " bytes)...",
2464 sizeof( size_t ) );
2465
2466 debug_printf( 1, "retroflat: ssize_t is (" SIZE_T_FMT " bytes)...",
2467 sizeof( ssize_t ) );
2468
2469 debug_printf( 1, "retroflat: off_t is (" SIZE_T_FMT " bytes)...",
2470 sizeof( off_t ) );
2471
2472 g_retroflat_state_h = maug_malloc( 1, sizeof( struct RETROFLAT_STATE ) );
2473 if( (MAUG_MHANDLE)NULL == g_retroflat_state_h ) {
2475 "Error", "Could not allocate global state!" );
2476 retval = MERROR_ALLOC;
2477 goto cleanup;
2478 }
2479
2480 maug_mlock( g_retroflat_state_h, g_retroflat_state );
2481 if( (MAUG_MHANDLE)NULL == g_retroflat_state ) {
2483 "Error", "Could not lock global state!" );
2484 retval = MERROR_ALLOC;
2485 goto cleanup;
2486 }
2487 maug_mzero( g_retroflat_state, sizeof( struct RETROFLAT_STATE ) );
2488
2489 retroflat_heartbeat_set( 1000, 2 );
2490
2491 /* Set default, so that this is never zero, to avoid division by zero. */
2492 g_retroflat_state->scale = 1;
2493
2494# ifndef RETROFLAT_NO_CLI
2495
2496 debug_printf( 1, "retroflat: parsing args..." );
2497
2498 /* All platforms: add command-line args based on compile definitons. */
2499
2500# if !defined( RETROFLAT_NO_SOUND ) && defined( RETROSND_ARGS )
2501 retval = maug_add_arg( MAUG_CLI_SIGIL "rsd", MAUG_CLI_SIGIL_SZ + 4,
2502 "Select MIDI device", 0, (maug_cli_cb)retrosnd_cli_rsd, args );
2503 maug_cleanup_if_not_ok();
2504 retval = maug_add_arg( MAUG_CLI_SIGIL "rsl", MAUG_CLI_SIGIL_SZ + 4,
2505 "List MIDI devices", 0, (maug_cli_cb)retrosnd_cli_rsl, args );
2506 maug_cleanup_if_not_ok();
2507# endif /* !RETROFLAT_NO_SOUND && RETROSND_ARGS */
2508
2509# ifdef RETROFLAT_SCREENSAVER
2510 retval = maug_add_arg( MAUG_CLI_SIGIL "p", MAUG_CLI_SIGIL_SZ + 2,
2511 "Preview screensaver", 0, (maug_cli_cb)retroflat_cli_p, args );
2512 maug_cleanup_if_not_ok();
2513 retval = maug_add_arg( MAUG_CLI_SIGIL "s", MAUG_CLI_SIGIL_SZ + 2,
2514 "Launch screensaver", 0, (maug_cli_cb)retroflat_cli_s, args );
2515 maug_cleanup_if_not_ok();
2516# endif /* RETROFLAT_SCREENSAVER */
2517
2518# ifdef RETROFLAT_API_PC_BIOS
2519 retval = maug_add_arg( MAUG_CLI_SIGIL "rfm", MAUG_CLI_SIGIL_SZ + 4,
2520 "Set the screen mode.", 0,
2521 (maug_cli_cb)retroflat_cli_rfm, args );
2522 maug_cleanup_if_not_ok();
2523# elif !defined( RETROFLAT_NO_CLI_SZ )
2524 retval = maug_add_arg( MAUG_CLI_SIGIL "rfs", MAUG_CLI_SIGIL_SZ + 4,
2525 "Set screen scale factor.", 0,
2526 (maug_cli_cb)retroflat_cli_rfs, args );
2527 maug_cleanup_if_not_ok();
2528 retval = maug_add_arg( MAUG_CLI_SIGIL "rfx", MAUG_CLI_SIGIL_SZ + 4,
2529 "Set the screen X position.", 0,
2530 (maug_cli_cb)retroflat_cli_rfx, args );
2531 maug_cleanup_if_not_ok();
2532 retval = maug_add_arg( MAUG_CLI_SIGIL "rfy", MAUG_CLI_SIGIL_SZ + 4,
2533 "Set the screen Y position.", 0,
2534 (maug_cli_cb)retroflat_cli_rfy, args );
2535 maug_cleanup_if_not_ok();
2536 retval = maug_add_arg( MAUG_CLI_SIGIL "rfw", MAUG_CLI_SIGIL_SZ + 4,
2537 "Set the screen width.", 0,
2538 (maug_cli_cb)retroflat_cli_rfw, args );
2539 maug_cleanup_if_not_ok();
2540 retval = maug_add_arg( MAUG_CLI_SIGIL "rfh", MAUG_CLI_SIGIL_SZ + 4,
2541 "Set the screen height.", 0,
2542 (maug_cli_cb)retroflat_cli_rfh, args );
2543 maug_cleanup_if_not_ok();
2544# endif /* !RETROFLAT_NO_CLI_SZ */
2545
2546# ifdef RETROFLAT_VDP
2547 retval = maug_add_arg( MAUG_CLI_SIGIL "vdp", MAUG_CLI_SIGIL_SZ + 4,
2548 "Pass a string of args to the VDP.", 0,
2549 (maug_cli_cb)retroflat_cli_vdp, args );
2550 maug_cleanup_if_not_ok();
2551# endif /* RETROFLAT_VDP */
2552
2553 retval = maug_add_arg( MAUG_CLI_SIGIL "rfu", MAUG_CLI_SIGIL_SZ + 4,
2554 "Unlock FPS.", 0,
2555 (maug_cli_cb)retroflat_cli_u, args );
2556 maug_cleanup_if_not_ok();
2557
2558 /* Parse command line args. */
2559 retval = maug_parse_args( argc, argv );
2560 maug_cleanup_if_not_ok();
2561
2562# else
2563
2564 args->screen_w = RETROFLAT_DEFAULT_SCREEN_W;
2565 args->screen_h = RETROFLAT_DEFAULT_SCREEN_H;
2566
2567# endif /* !RETROFLAT_NO_CLI */
2568
2569 if(
2571 ) {
2572 g_retroflat_state->retroflat_flags |= RETROFLAT_FLAGS_UNLOCK_FPS;
2573 }
2574
2575 debug_printf( 1, "retroflat: setting config..." );
2576
2577 /* Set the assets path. */
2578 memset( g_retroflat_state->assets_path, '\0', RETROFLAT_ASSETS_PATH_MAX );
2579 if( NULL != args->assets_path ) {
2580 maug_strncpy( g_retroflat_state->assets_path,
2582 }
2583
2584# if defined( RETROFLAT_SCREENSAVER )
2585 if(
2587 (RETROFLAT_FLAGS_SCREENSAVER & args->flags)
2588 ) {
2589 g_retroflat_state->retroflat_flags |= RETROFLAT_FLAGS_SCREENSAVER;
2590 }
2591# endif /* RETROFLAT_SCREENSAVER */
2592
2593# if !defined( RETROFLAT_NO_CLI_SZ )
2594 /* Setup intended screen size. */
2595 g_retroflat_state->screen_v_w = args->screen_w;
2596 g_retroflat_state->screen_v_h = args->screen_h;
2597 g_retroflat_state->screen_w = args->screen_w;
2598 g_retroflat_state->screen_h = args->screen_h;
2599# endif /* RETROFLAT_NO_CLI_SZ */
2600
2601 /* == Platform-Specific Init == */
2602
2603 retval = retroflat_init_platform( argc, argv, args );
2604 maug_cleanup_if_not_ok();
2605
2606 debug_printf( 3, "screen initialized with: " SIZE_T_FMT "x" SIZE_T_FMT
2607 " pixels with " SIZE_T_FMT " colors",
2608 retroflat_screen_w(), retroflat_screen_h(), retroflat_screen_colors() );
2609
2610 /* Setup the refresh grid, if requested, only after screen space has been
2611 * determined by the platform!
2612 */
2613 maug_cleanup_if_eq(
2614 (size_t)0, retroflat_screen_w(), SIZE_T_FMT, MERROR_GUI );
2615 maug_cleanup_if_eq(
2616 (size_t)0, retroflat_screen_h(), SIZE_T_FMT, MERROR_GUI );
2617 maug_cleanup_if_eq(
2618 (size_t)0, retroflat_screen_colors(), SIZE_T_FMT, MERROR_GUI );
2619
2620 /* This is intended as a default and can be modified by calling this macro
2621 * again later.
2622 */
2623 retroflat_viewport_set_pos_size(
2624 0, 0, retroflat_screen_w(), retroflat_screen_h() );
2625
2626#ifndef RETROFLAT_NO_VIEWPORT_REFRESH
2627 debug_printf( 1, "allocating refresh grid (%d tiles...)",
2628 g_retroflat_state->viewport.screen_tile_w *
2629 g_retroflat_state->viewport.screen_tile_h );
2630 g_retroflat_state->viewport.refresh_grid_h = maug_malloc(
2631 (g_retroflat_state->viewport.screen_tile_w + 2) *
2632 (g_retroflat_state->viewport.screen_tile_h + 2),
2633 sizeof( retroflat_tile_t ) );
2634 maug_cleanup_if_null_alloc( MAUG_MHANDLE,
2635 g_retroflat_state->viewport.refresh_grid_h );
2636#endif /* !RETROFLAT_NO_VIEWPORT_REFRESH */
2637
2638# ifdef RETROFLAT_VDP
2639# if defined( RETROFLAT_OS_UNIX )
2640 g_retroflat_state->vdp_exe = dlopen(
2641 "./" RETROFLAT_VDP_LIB_NAME ".so", RTLD_LAZY );
2642# elif defined( RETROFLAT_OS_WIN )
2643 g_retroflat_state->vdp_exe = LoadLibrary(
2644 "./" RETROFLAT_VDP_LIB_NAME ".dll" );
2645# else
2646# error "dlopen undefined!"
2647# endif /* RETROFLAT_OS_UNIX */
2648
2649 if( !(g_retroflat_state->vdp_exe) ) {
2650 error_printf( "not loading VDP" );
2651 /* Skip creating the buffer or trying to run the init proc. */
2652 goto skip_vdp;
2653 }
2654
2655 /* Create intermediary screen buffer. */
2656 debug_printf( 1, "creating VDP buffer, " SIZE_T_FMT " x " SIZE_T_FMT,
2657 g_retroflat_state->screen_v_w, g_retroflat_state->screen_v_h );
2658 g_retroflat_state->vdp_buffer =
2659 calloc( 1, sizeof( struct RETROFLAT_BITMAP ) );
2660 maug_cleanup_if_null_alloc(
2661 struct RETROFLAT_BITMAP*, g_retroflat_state->vdp_buffer );
2662 retval = retroflat_create_bitmap(
2663 g_retroflat_state->screen_v_w, g_retroflat_state->screen_v_h,
2664 g_retroflat_state->vdp_buffer, RETROFLAT_FLAGS_OPAQUE );
2665 maug_cleanup_if_not_ok();
2666
2667 debug_printf( 1, "initializing VDP..." );
2668 retval = retroflat_vdp_call( "retroflat_vdp_init" );
2669
2670skip_vdp:
2671
2672# endif /* RETROFLAT_VDP */
2673
2674# ifdef RETROFLAT_3D
2675 retro3d_platform_init();
2676# endif /* RETROFLAT_3D */
2677
2678# if !defined( RETROFLAT_NO_BLANK_INIT ) && !defined( RETROFLAT_3D )
2679 retroflat_draw_lock( NULL );
2681 NULL, RETROFLAT_COLOR_BLACK, 0, 0,
2682 retroflat_screen_w(), retroflat_screen_h(),
2684 retroflat_draw_release( NULL );
2685# endif /* !RETROFLAT_NO_BLANK_INIT */
2686
2687cleanup:
2688
2689 return retval;
2690}
2691
2692/* === */
2693
2694void retroflat_shutdown( int retval ) {
2695
2696 debug_printf( 1, "retroflat shutdown called..." );
2697
2698#ifndef RETROFLAT_NO_VIEWPORT_REFRESH
2699 if( (MAUG_MHANDLE)NULL != g_retroflat_state->viewport.refresh_grid_h ) {
2700 maug_mfree( g_retroflat_state->viewport.refresh_grid_h );
2701 }
2702#endif /* !RETROFLAT_NO_VIEWPORT_REFRESH */
2703
2704# if defined( RETROFLAT_VDP )
2705 if( NULL != g_retroflat_state->vdp_exe ) {
2706 retroflat_vdp_call( "retroflat_vdp_shutdown" );
2707# ifdef RETROFLAT_OS_UNIX
2708 dlclose( g_retroflat_state->vdp_exe );
2709# elif defined( RETROFLAT_OS_WIN )
2710 FreeLibrary( g_retroflat_state->vdp_exe );
2711# else
2712# error "dlclose undefined!"
2713# endif /* RETROFLAT_OS_UNIX || RETROFLAT_OS_WIN */
2714 }
2715
2716 if( NULL != g_retroflat_state->vdp_buffer ) {
2717 debug_printf( 1, "destroying VPD buffer..." );
2718 retroflat_destroy_bitmap( g_retroflat_state->vdp_buffer );
2719 free( g_retroflat_state->vdp_buffer );
2720 }
2721# endif /* RETROFLAT_VDP */
2722
2723 /* === Platform-Specific Shutdown === */
2724
2725#ifdef RETROFLAT_3D
2726 retro3d_platform_shutdown();
2727#endif /* RETROFLAT_3D */
2728
2729 retroflat_shutdown_platform( retval );
2730
2731 maug_munlock( g_retroflat_state_h, g_retroflat_state );
2732 maug_mfree( g_retroflat_state );
2733
2734}
2735
2736/* === */
2737
2738# ifdef RETROFLAT_VDP
2739
2740MERROR_RETVAL retroflat_vdp_call( const char* proc_name ) {
2741 MERROR_RETVAL retval = MERROR_OK;
2743# ifdef RETROFLAT_OS_WIN
2744 char proc_name_ex[256];
2745# endif /* RETROFLAT_OS_WIN */
2746
2747 if( NULL == g_retroflat_state->vdp_exe ) {
2748 goto cleanup;
2749 }
2750
2751# ifdef RETROFLAT_OS_UNIX
2752 vdp_proc = dlsym( g_retroflat_state->vdp_exe, proc_name );
2753# elif defined( RETROFLAT_OS_WIN )
2754 /* Append a _ to the proc_name because Watcom? Windows? */
2755 maug_snprintf( proc_name_ex, 255, "%s_", proc_name );
2756 vdp_proc = (retroflat_vdp_proc_t)GetProcAddress(
2757 g_retroflat_state->vdp_exe, proc_name_ex );
2758# else
2759# error "dlsym undefined!"
2760# endif
2761 if( (retroflat_vdp_proc_t)NULL == vdp_proc ) {
2762 goto cleanup;
2763 }
2764
2765# ifdef RETROFLAT_OS_WIN
2766 retroflat_draw_lock( g_retroflat_state->vdp_buffer );
2767# endif /* RETROFLAT_OS_WIN */
2768
2769 if(
2770 /* Don't pxlock before init can set the flag! */
2771 0 == strcmp( "retroflat_vdp_flip", proc_name ) &&
2773 (RETROFLAT_VDP_FLAG_PXLOCK & g_retroflat_state->vdp_flags)
2774 ) {
2775 retroflat_vdp_lock( &(g_retroflat_state->buffer) );
2776 retroflat_vdp_lock( g_retroflat_state->vdp_buffer );
2777 }
2778
2779 retval = vdp_proc( g_retroflat_state );
2780
2781 if(
2782 0 == strcmp( "retroflat_vdp_flip", proc_name ) &&
2784 (RETROFLAT_VDP_FLAG_PXLOCK & g_retroflat_state->vdp_flags)
2785 ) {
2786 retroflat_vdp_release( &(g_retroflat_state->buffer) );
2787 retroflat_vdp_release( g_retroflat_state->vdp_buffer );
2788 }
2789
2790# ifdef RETROFLAT_OS_WIN
2791 retroflat_draw_release( g_retroflat_state->vdp_buffer );
2792# endif /* RETROFLAT_OS_WIN */
2793
2794cleanup:
2795 return retval;
2796}
2797
2798# endif /* RETROFLAT_VDP */
2799
2800/* === */
2801
2802#if 0
2803
2804void retroflat_cursor( struct RETROFLAT_BITMAP* target, uint8_t flags ) {
2805#if 0
2806 char mouse_str[11] = "";
2807
2808 maug_snprintf(
2809 mouse_str, 10, "%02d, %02d", g_retroflat_state->last_mouse_x, g_retroflat_state->last_mouse_y );
2810
2812 target, RETROFLAT_COLOR_BLACK,
2813 mouse_str, 10, NULL, 0, 0, 0 );
2815 target, RETROFLAT_COLOR_BLACK,
2816 g_retroflat_state->last_mouse_x - 5, g_retroflat_state->last_mouse_y - 5, 10, 10, 0 );
2817#endif
2818}
2819
2820#endif
2821
2822/* === */
2823
2825 retroflat_proc_resize_t on_resize_in, void* data_in
2826) {
2827 g_retroflat_state->on_resize = on_resize_in;
2828 g_retroflat_state->on_resize_data = data_in;
2829}
2830
2831/* === */
2832
2833uint8_t retroflat_viewport_move_x_generic( int16_t x ) {
2834 int16_t new_world_x = g_retroflat_state->viewport.world_x + x;
2835
2836 /* Keep the viewport in the world arena. */
2837 if(
2838 0 <= new_world_x &&
2839 g_retroflat_state->viewport.world_w >= new_world_x +
2840 g_retroflat_state->viewport.screen_w
2841 ) {
2842 g_retroflat_state->viewport.world_x += x;
2843 g_retroflat_state->viewport.world_tile_x += x >> RETROFLAT_TILE_W_BITS;
2844 return 1;
2845 }
2846
2847 return 0;
2848}
2849
2850/* === */
2851
2852uint8_t retroflat_viewport_move_y_generic( int16_t y ) {
2853 int16_t new_world_y = g_retroflat_state->viewport.world_y + y;
2854
2855 /* Keep the viewport in the world arena. */
2856 if(
2857 0 <= new_world_y &&
2858 g_retroflat_state->viewport.world_h >= new_world_y +
2859 g_retroflat_state->viewport.screen_h
2860 ) {
2861 g_retroflat_state->viewport.world_y += y;
2862 g_retroflat_state->viewport.world_tile_y += y >> RETROFLAT_TILE_H_BITS;
2863 return 1;
2864 }
2865
2866 return 0;
2867}
2868
2869/* === */
2870
2871uint8_t retroflat_viewport_focus_generic(
2872 size_t x1, size_t y1, size_t range, size_t speed
2873) {
2874 uint8_t moved = 0,
2875 new_moved = 0;
2876 int16_t new_pt = 0;
2877
2878# define _retroflat_viewport_focus_dir( n, xy, wh, gl, pm, dir, range, speed ) \
2879 new_pt = n - retroflat_viewport_world_ ## xy(); \
2880 if( new_pt gl (retroflat_screen_ ## wh() >> 1) pm range ) { \
2881 new_moved = retroflat_viewport_move_ ## xy( \
2882 gc_retroflat_offsets8_ ## xy[RETROFLAT_DIR8_ ## dir] * speed ); \
2883 if( !moved && new_moved ) { \
2884 moved = new_moved; \
2885 } \
2886 }
2887
2888 _retroflat_viewport_focus_dir( x1, x, w, <, -, WEST, range, speed );
2889 _retroflat_viewport_focus_dir( x1, x, w, >, +, EAST, range, speed );
2890 _retroflat_viewport_focus_dir( y1, y, h, <, -, NORTH, range, speed );
2891 _retroflat_viewport_focus_dir( y1, y, h, >, +, SOUTH, range, speed );
2892
2893 return moved;
2894}
2895
2896/* === */
2897
2898#elif !defined( RETROVDP_C ) /* End of RETROFLT_C */
2899
2904
2905extern MAUG_CONST int16_t SEG_MCONST gc_retroflat_offsets8_x[8];
2906extern MAUG_CONST int16_t SEG_MCONST gc_retroflat_offsets8_y[8];
2907extern MAUG_CONST int16_t SEG_MCONST gc_retroflat_offsets4_x[4];
2908extern MAUG_CONST int16_t SEG_MCONST gc_retroflat_offsets4_y[4];
2909
2911
2912#define RETROFLAT_COLOR_TABLE_CONSTS( idx, name_l, name_u, r, g, b, cgac, cgad ) \
2913 extern MAUG_CONST RETROFLAT_COLOR RETROFLAT_COLOR_ ## name_u;
2914
2915RETROFLAT_COLOR_TABLE( RETROFLAT_COLOR_TABLE_CONSTS )
2916
2917extern MAUG_CONST char* SEG_MCONST gc_retroflat_color_names[];
2918
2919 extern struct RETROFLAT_STATE* g_retroflat_state;
2920# if defined( RETROFLAT_API_WIN16 ) || defined( RETROFLAT_API_WIN32 )
2921 extern HINSTANCE g_retroflat_instance;
2922 extern int g_retroflat_cmd_show;
2923# endif /* RETROFLAT_API_WIN16 || RETROFLAT_API_WIN32 */
2924
2925# if (defined( RETROFLAT_SOFT_SHAPES ) || defined( RETROFLAT_SOFT_LINES ) || \
2926 defined( RETROFLAT_3D ))
2927# define RETROSOFT_PRESENT
2928# endif
2929
2930# ifdef RETROFLAT_3D
2931# include <retro3dp.h>
2932# include <retro3d.h>
2933# include <retro3du.h>
2934# endif /* RETROFLAT_3D */
2935
2936# ifdef RETROSOFT_PRESENT
2937# include <retrosft.h>
2938# endif /* RETROFLAT_SOFT_SHAPES */
2939
2940/* Second retapis.h include for function bodies not needed. */
2941
2942/* Second retapii.h include for function bodies not needed. */
2943
2944#endif /* RETROFLT_C */
2945
2946#ifdef RETROFLAT_XPM
2947#include <retroxpm.h>
2948#endif /* RETROFLAT_XPM */
2949
2950#ifdef RETROVDP_C
2951
2952/* Declarations for VDP sources. */
2953
2954#endif /* RETROVDP_C */
2955 /* maug_retroflt */
2957
2958#endif /* RETROFLT_H */
2959
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:65
#define retroflat_heartbeat_update()
Check and update RETROFLAT_STATE::heartbeat_frame. This should be called in the API HAL on every iter...
Definition retroflt.h:1556
void retroflat_shutdown(int retval)
Deinitialize RetroFlat and its underlying layers. This should be called once at the end of the progra...
#define retroflat_heartbeat_set(len, max)
Set parameters for the RETROFLAT_STATE::heartbeat_frame.
Definition retroflt.h:1540
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).
char retroflat_asset_path[RETROFLAT_PATH_MAX+1]
Path/name used to load an asset from disk.
Definition retroflt.h:771
#define RETROFLAT_BITMAP_EXT
The filename suffix to be appended with a "." to filenames passed to retroflat_load_bitmap()....
Definition retroflt.h:578
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 ...
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 ...
int8_t RETROFLAT_COLOR
Defines an index in the platform-specific color-table.
Definition retroflt.h:325
#define RETROFLAT_COLOR_TABLE(f)
This macro defines all colors supported by RetroFlat for primative operations, particularly using ret...
Definition retroflt.h:306
#define RETROFLAT_VDP_ARGS_SZ_MAX
Definition retroflt.h:721
#define RETROFLAT_ASSETS_PATH_MAX
Maximum size of the assets path, to allow room for appending.
Definition retroflt.h:746
#define RETROFLAT_PATH_SEP
The valid path separator on the target platform.
Definition retroflt.h:742
#define RETROFLAT_FLAGS_LITERAL_PATH
Flag for retroflat_load_bitmap() to not use assets path.
Definition retroflt.h:392
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:379
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:373
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 ::RETROFLA...
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:433
#define RETROFLAT_FLAGS_UNLOCK_FPS
Flag indicating FPS should not be capped.
Definition retroflt.h:421
#define RETROFLAT_FLAGS_RUNNING
Flag indicating that retroflat_loop() should continue executing.
Definition retroflt.h:415
#define RETROFLAT_FLAGS_WAIT_FOR_FPS
Do not execute any more inter-frame loops until next frame.
Definition retroflt.h:438
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:456
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:508
#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:495
uint16_t screen_w_remainder
Difference between viewport width and screen width in pixels. Should only be retrieved through retrof...
Definition retroflt.h:1160
char vdp_args[RETROFLAT_VDP_ARGS_SZ_MAX]
CLI args passed with -vdp to the RetroFlat VDP API.
Definition retroflt.h:1612
char * config_path
Relative path of local config file (if not using registry).
Definition retroflt.h:1072
int16_t screen_x
X position of the viewport in real screen memory in pixels. Should only be retrieved through retrofla...
Definition retroflt.h:1111
size_t screen_h
The screen height as seen by the system, after scaling.
Definition retroflt.h:1638
char * assets_path
Relative path under which bitmap assets are stored.
Definition retroflt.h:1070
uint8_t vdp_flags
Flags set by the RetroFlat VDP API.
Definition retroflt.h:1614
uint16_t screen_h_remainder
Difference between viewport height and screen height in pixels. Should only be retrieved through retr...
Definition retroflt.h:1167
size_t screen_v_w
The screen width as seen by our program, before scaling.
Definition retroflt.h:1627
size_t screen_colors
The number of colors the screen is capable of displaying.
Definition retroflt.h:1640
int mouse_y
Y-coordinate of the mouse pointer in pixels if the returned event is a mouse click.
Definition retroflt.h:852
uint8_t retroflat_flags
Global Flags indicating current system status.
Definition retroflt.h:1586
uint8_t heartbeat_max
When RETROFLAT_STATE::heartbeat_frame reaches this value, it will reset to 0.
Definition retroflt.h:1667
retroflat_tile_t * refresh_grid
A grid of tile values representing the last-drawn values on-screen.
Definition retroflt.h:1196
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:1599
uint8_t heartbeat_frame
Simple iteration loop that can be used to time e.g. perpetual sprite animations. Modify parameters wi...
Definition retroflt.h:1662
size_t screen_w
The screen width as seen by the system, after scaling.
Definition retroflt.h:1636
uint16_t screen_h
Viewport height in pixels. Should only be retrieved through retroflat_viewport_screen_w() and set thr...
Definition retroflt.h:1153
int screen_h
Desired screen or window height in pixels.
Definition retroflt.h:1076
int16_t world_w
The width of the entire world tilemap in pixels. Should only be retrieved through retroflat_viewport_...
Definition retroflt.h:1135
int mouse_x
X-coordinate of the mouse pointer in pixels if the returned event is a mouse click.
Definition retroflt.h:847
void(* retroflat_loop_iter)(void *data)
Prototype for the main loop function passed to retroflat_loop().
Definition retroflt.h:792
int16_t screen_tile_w
The number of tiles across that fit in the viewport. Should only be retrieved through retroflat_viewp...
Definition retroflt.h:1174
size_t retroflat_pxxy_t
Type used for surface pixel coordinates.
Definition retroflt.h:895
struct RETROFLAT_BITMAP buffer
Off-screen buffer bitmap.
Definition retroflt.h:1590
void * vdp_exe
A handle for the loaded RetroFlat VDP API module.
Definition retroflt.h:1604
RETROFLAT_COLOR_DEF palette[RETROFLAT_COLORS_SZ]
Index of available colors, initialized on platform init.
Definition retroflt.h:1674
uint16_t heartbeat_len
Number of ms to stay on current value of RETROFLAT_STATE::heartbeat_frame before incrementing....
Definition retroflt.h:1656
void * vdp_data
Pointer to data defined by the RetroFlat VDP API for its use.
Definition retroflt.h:1610
int16_t screen_tile_h
The number of tiles high that fit in the viewport. Should only be retrieved through retroflat_viewpor...
Definition retroflt.h:1181
int16_t world_h
The height of the entire world tilemap in pixels. Should only be retrieved through retroflat_viewport...
Definition retroflt.h:1141
size_t screen_v_h
The screen height as seen by our program, before scaling.
Definition retroflt.h:1634
char * title
Title to set for the main program Window if applicable on the target platform.
Definition retroflt.h:1068
int screen_y
Desired window Y position in pixels.
Definition retroflt.h:1080
int16_t world_y
The Y offset, in pixels, of the viewport on the world tilemap. Should only be retrieved through retro...
Definition retroflt.h:1129
int16_t screen_y
Y position of the viewport in real screen memory in pixels. Should only be retrieved through retrofla...
Definition retroflt.h:1117
uint16_t screen_w
Viewport width in pixels. Should only be retrieved through retroflat_viewport_screen_w() and set thro...
Definition retroflt.h:1147
int screen_x
Desired window X position in pixels.
Definition retroflt.h:1078
int16_t world_x
The X offset, in pixels, of the viewport on the world tilemap. Should only be retrieved through retro...
Definition retroflt.h:1123
void retrosoft_rect(retroflat_blit_t *target, const RETROFLAT_COLOR color_idx, int x, int y, int w, int h, uint8_t flags)
Draw a rectangle at the given coordinates, with the given dimensions.
void retrosoft_line(retroflat_blit_t *target, RETROFLAT_COLOR color, int x1, int y1, int x2, int y2, uint8_t flags)
Draw a line from x1, y1 to x2, y2.
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.
int16_t retroflat_tile_t
Value for an individual tile in a RETROTILE_LAYER.
Definition retroflt.h:19
Tools for drawing shape primatives.
Definition retroflt.h:1036
Struct containing configuration values for a RetroFlat program.
Definition retroflt.h:1062
Struct passed to retroflat_poll_input() to hold return data.
Definition retroflt.h:842
Global singleton containing state for the current platform.
Definition retroflt.h:1576
The viewport data struct.
Definition retroflt.h:1105