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
277
278/* === Generic Includes and Defines === */
279
280#ifndef RETROFLAT_BITMAP_TRACE_LVL
281# define RETROFLAT_BITMAP_TRACE_LVL 0
282#endif /* !RETROFLAT_BITMAP_TRACE_LVL */
283
284#ifndef RETROINPUT_TRACE_LVL
285# define RETROINPUT_TRACE_LVL 0
286#endif /* !RETROINPUT_TRACE_LVL */
287
288#include <stdarg.h>
289
290#include <marge.h>
291
296
307#define RETROFLAT_COLOR_TABLE( f ) \
308 f( 0, black, BLACK, 0, 0, 0, BLACK, BLACK ) \
309 f( 1, darkblue, DARKBLUE, 0, 0, 170, CYAN, BLACK ) \
310 f( 2, darkgreen, DARKGREEN, 0, 170, 0, CYAN, BLACK ) \
311 f( 3, teal, TEAL, 0, 170, 170, CYAN, CYAN ) \
312 f( 4, darkred, DARKRED, 170, 0, 0, MAGENTA, BLACK ) \
313 f( 5, violet, VIOLET, 170, 0, 170, MAGENTA, BLACK ) \
314 f( 6, brown, BROWN, 170, 85, 0, CYAN, MAGENTA ) \
315 f( 7, gray, GRAY, 170, 170, 170, WHITE, BLACK ) \
316 f( 8, darkgray, DARKGRAY, 85, 85, 85, WHITE, BLACK ) \
317 f( 9, blue, BLUE, 85, 85, 255, CYAN, WHITE ) \
318 f( 10, green, GREEN, 85, 255, 85, CYAN, CYAN ) \
319 f( 11, cyan, CYAN, 85, 255, 255, CYAN, CYAN ) \
320 f( 12, red, RED, 255, 85, 85, MAGENTA, WHITE ) \
321 f( 13, magenta, MAGENTA, 255, 85, 255, MAGENTA, MAGENTA ) \
322 f( 14, yellow, YELLOW, 255, 255, 85, CYAN, MAGENTA ) \
323 f( 15, white, WHITE, 255, 255, 255, WHITE, WHITE )
324
326typedef int8_t RETROFLAT_COLOR;
327
328# define RETROFLAT_COLOR_NULL (-1)
329
330# define RETROFLAT_COLORS_SZ 16
331
333
334/* TODO: Mouse is broken under DOS/Allegro. */
335#if defined( RETROFLAT_OS_UNIX ) || defined( RETROFLAT_OS_WIN )
336#define RETROFLAT_MOUSE
337#endif /* RETROFLAT_OS_WIN || RETROFLAT_OS_WIN */
338
344
346#define RETROFLAT_OK 0x00
347#define RETROFLAT_ERROR_ENGINE 0x01
348#define RETROFLAT_ERROR_GRAPHICS 0x02
349#define RETROFLAT_ERROR_MOUSE 0x04
350
355#define RETROFLAT_ERROR_BITMAP 0x08
356#define RETROFLAT_ERROR_TIMER 0x0f
357 /* maug_retroflt_retval */
359
369
374#define RETROFLAT_FLAGS_FILL 0x01
375
380#define RETROFLAT_FLAGS_OPAQUE 0x01
381
385#define RETROFLAT_FLAGS_LITERAL_PATH 0x02
386
391#define RETROFLAT_FLAGS_BITMAP_SILENT 0x04
392
399#define RETROFLAT_FLAGS_ALL_CAPS 0x02
400
407#define RETROFLAT_FLAGS_SCREEN_BUFFER 0x80
408 /* maug_retroflt_drawing */
410
417#define RETROFLAT_FLAGS_RUNNING 0x01
418
424#define RETROFLAT_FLAGS_UNLOCK_FPS 0x02
425
431#define RETROFLAT_FLAGS_KEY_REPEAT 0x04
432
438#define RETROFLAT_FLAGS_SCREENSAVER 0x08
439
444#define RETROFLAT_FLAGS_WAIT_FOR_FPS 0x20
445
452
456#define RETROFLAT_MSG_FLAG_TYPE_MASK 0x07
457
462#define RETROFLAT_MSG_FLAG_ERROR 0x01
463
469#define RETROFLAT_MSG_FLAG_INFO 0x02
470
476#define RETROFLAT_MSG_FLAG_WARNING 0x04
477 /* maug_retroflt_msg_api */
479
480struct RETROFLAT_STATE;
481
493
501#define RETROFLAT_VDP_FLAG_PXLOCK 0x01
502
515 /* maug_retroflt_vdp */
517
518typedef MERROR_RETVAL (*retroflat_proc_resize_t)(
519 uint16_t new_w, uint16_t new_h, void* data );
520
525
526#define RETROSND_ARGS_FLAG_LIST_DEVS 0x01
527
529
555
559#define RETROFLAT_FLAGS_LOCK 0x08
560
561#define RETROFLAT_FLAGS_SCREEN_LOCK 0x02
562
563#define RETROFLAT_FLAGS_BITMAP_RO 0x04
564
570#define RETROFLAT_INSTANCE_NULL (0)
571
576#define retroflat_instance_tile( instance ) \
577 (instance * -1)
578
583#ifndef RETROFLAT_BITMAP_EXT
584# define RETROFLAT_BITMAP_EXT "bmp"
585#endif /* !RETROFLAT_BITMAP_EXT */
586
587#ifndef RETROFLAT_OPENGL_BPP
588# define RETROFLAT_OPENGL_BPP 32
589#endif /* !RETROFLAT_OPENGL_BPP */
590
591#ifndef RETROFLAT_TILE_W
592# define RETROFLAT_TILE_W 16
593#endif /* !RETROFLAT_TILE_W */
594
595#ifndef RETROFLAT_TILE_W_BITS
596# define RETROFLAT_TILE_W_BITS 4
597#endif /* !RETROFLAT_TILE_W_BITS */
598
599#ifndef RETROFLAT_TILE_H
600# define RETROFLAT_TILE_H 16
601#endif /* !RETROFLAT_TILE_H */
602
603#ifndef RETROFLAT_TILE_H_BITS
604# define RETROFLAT_TILE_H_BITS 4
605#endif /* !RETROFLAT_TILE_H_BITS */
606
607/* Transparency background color: black by default, to match Allegro. */
608#ifndef RETROFLAT_TXP_R
614# define RETROFLAT_TXP_R 0x00
615#endif /* !RETROFLAT_TXP_R */
616
617#ifndef RETROFLAT_TXP_G
623# define RETROFLAT_TXP_G 0x00
624#endif /* !RETROFLAT_TXP_G */
625
626#ifndef RETROFLAT_TXP_B
632# define RETROFLAT_TXP_B 0x00
633#endif /* !RETROFLAT_TXP_B */
634
635#ifndef RETROFLAT_TXP_PAL_IDX
636# define RETROFLAT_TXP_PAL_IDX 0
637#endif /* !RETROFLAT_TXP_PAL_IDX */
638 /* maug_retroflt_bitmap */
640
641#ifndef RETROFLAT_DEFAULT_SCREEN_W
642# define RETROFLAT_DEFAULT_SCREEN_W 320
643#endif /* RETROFLAT_DEFAULT_SCREEN_W */
644
645#ifndef RETROFLAT_DEFAULT_SCREEN_H
646# define RETROFLAT_DEFAULT_SCREEN_H 200
647#endif /* RETROFLAT_DEFAULT_SCREEN_H */
648
649#define retroflat_on_resize( w, h ) \
650 g_retroflat_state->screen_w = w; \
651 g_retroflat_state->screen_h = h;
652
657
658#ifndef RETROFLAT_LINE_THICKNESS
663# define RETROFLAT_LINE_THICKNESS 1
664#endif /* !RETROFLAT_LINE_THICKNESS */
665
666#define RETROFLAT_PI 3.14159
667 /* maug_retroflt_drawing */
669
674
675#ifndef RETROFLAT_FPS
680# define RETROFLAT_FPS 30
681#endif /* !RETROFLAT_FPS */
682
683#define retroflat_fps_next() (1000 / RETROFLAT_FPS)
684
685#ifndef RETROFLAT_WINDOW_CLASS
690# define RETROFLAT_WINDOW_CLASS "RetroFlatWindowClass"
691#endif /* !RETROFLAT_WINDOW_CLASS */
692
693#ifndef RETROFLAT_WIN_FRAME_TIMER_ID
698# define RETROFLAT_WIN_FRAME_TIMER_ID 6001
699#endif /* !RETROFLAT_WIN_FRAME_TIMER_ID */
700
701#ifndef RETROFLAT_WIN_LOOP_TIMER_ID
706# define RETROFLAT_WIN_LOOP_TIMER_ID 6002
707#endif /* !RETROFLAT_WIN_LOOP_TIMER_ID */
708
709#ifndef RETROFLAT_MSG_MAX
714# define RETROFLAT_MSG_MAX 4096
715#endif /* !RETROFLAT_MSG_MAX */
716
717#ifndef RETROFLAT_TITLE_MAX
718# define RETROFLAT_TITLE_MAX 255
719#endif /* !RETROFLAT_TITLE_MAX */
720
721#ifndef RETROFLAT_VDP_ARGS_SZ_MAX
725# define RETROFLAT_VDP_ARGS_SZ_MAX 255
726#endif /* !RETROFLAT_VDP_ARGS_SZ_MAX */
727
728#if defined( RETROFLAT_API_SDL2 )
729# if !defined( NO_RETROFLAT_RESIZABLE )
730# define RETROFLAT_WIN_FLAGS SDL_WINDOW_RESIZABLE
731# else
732# define RETROFLAT_WIN_FLAGS 0
733# endif /* !NO_RETROFLAT_RESIZABLE */
734#endif /* RETROFLAT_API_SDL2 */
735
736#if defined( RETROFLAT_API_SDL1 )
737# define RETROFLAT_SDL_CC_FLAGS (SDL_RLEACCEL | SDL_SRCCOLORKEY)
738#elif defined( RETROFLAT_API_SDL2 )
739# define RETROFLAT_SDL_CC_FLAGS (SDL_TRUE)
740#endif /* RETROFLAT_API_SDL1 || RETROFLAT_API_SDL2 */
741
742#ifdef RETROFLAT_OS_DOS
743# define RETROFLAT_PATH_SEP '\\'
744#else
746# define RETROFLAT_PATH_SEP '/'
747#endif /* RETROFLAT_OS_DOS */
748
749#ifndef RETROFLAT_BMP_COLORS_SZ_MAX
750# define RETROFLAT_BMP_COLORS_SZ_MAX 256
751#endif /* !RETROFLAT_BMP_COLORS_SZ_MAX */
752 /* maug_retroflt_compiling */
754
755#define retroflat_wait_for_frame() \
756 (g_retroflat_state->retroflat_flags |= RETROFLAT_FLAGS_WAIT_FOR_FPS)
757
758#define retroflat_is_waiting_for_frame() \
759 (RETROFLAT_FLAGS_WAIT_FOR_FPS == \
760 (g_retroflat_state->retroflat_flags & RETROFLAT_FLAGS_WAIT_FOR_FPS))
761
765typedef void (*retroflat_loop_iter)(void* data);
766
772
776#define retroflat_buffer_bksp( buffer, buffer_cur, buffer_sz ) \
777 if( 0 < buffer_cur ) { \
778 if( buffer_cur < buffer_sz ) { \
779 memmove( \
780 &(buffer[(buffer_cur) - 1]), \
781 &(buffer[buffer_cur]), \
782 (buffer_sz) - (buffer_cur) ); \
783 } \
784 buffer_cur--; \
785 buffer_sz--; \
786 buffer[buffer_sz] = '\0'; \
787 }
788
792#define retroflat_buffer_insert( c, buffer, buffer_cur, buffer_sz, buffer_mx ) \
793 if( buffer_sz + 1 < buffer_mx ) { \
794 if( buffer_cur < buffer_sz ) { \
795 memmove( \
796 &(buffer[(buffer_cur) + 1]), \
797 &(buffer[buffer_cur]), \
798 (buffer_sz) - (buffer_cur) ); \
799 } \
800 buffer[buffer_cur] = c; \
801 buffer_cur++; \
802 buffer_sz++; \
803 buffer[buffer_sz] = '\0'; \
804 }
805
806#define RETROFLAT_INPUT_MOD_SHIFT 0x01
807
808#define RETROFLAT_INPUT_MOD_ALT 0x02
809
810#define RETROFLAT_INPUT_MOD_CTRL 0x04
811
812#define RETROFLAT_INPUT_FORCE_UPPER 0x08
813
826 uint8_t key_flags;
827};
828 /* maug_retroflt_input */
830
837
838typedef int8_t retroflat_dir4_t;
839
840typedef int8_t retroflat_dir8_t;
841
842#define RETROFLAT_DIR4_NONE (-1)
843#define RETROFLAT_DIR4_NORTH 0
844#define RETROFLAT_DIR4_EAST 1
845#define RETROFLAT_DIR4_SOUTH 2
846#define RETROFLAT_DIR4_WEST 3
847
848#define RETROFLAT_DIR8_NONE (-1)
849#define RETROFLAT_DIR8_NORTH 0
850#define RETROFLAT_DIR8_EAST 2
851#define RETROFLAT_DIR8_SOUTH 4
852#define RETROFLAT_DIR8_WEST 6
853
854#define retroflat_dir4_rotate_cw( dir ) \
855 ((dir + 1) % 4)
856
857#define retroflat_dir8_reverse( dir ) \
858 ((dir + 4) % 8)
859
860#define retroflat_dir8_bounce( dir ) \
861 ((dir + 2) % 8)
862 /* maug_retroflt_dir */
864
871typedef size_t retroflat_pxxy_t;
872
873#define PXXY_FMT SIZE_T_FMT
874
875#define PXXY_MAX SIZE_MAX
876
877struct RETROFLAT_ARGS;
878
879#ifndef RETRO2D_TRACE_LVL
880# define RETRO2D_TRACE_LVL 0
881#endif /* !RETRO2D_TRACE_LVL */
882
883#ifndef RETROFLAT_NO_SOUND
884
912
913#ifndef RETROSND_TRACE_LVL
914# define RETROSND_TRACE_LVL 0
915#endif /* !RETROSND_TRACE_LVL */
916
917#ifndef RETROSND_REG_TRACE_LVL
918# define RETROSND_REG_TRACE_LVL 0
919#endif /* !RETROSND_REG_TRACE_LVL */
920
926
931#define RETROSND_FLAG_INIT 0x01
932 /* maug_retrosnd_flags */
934
935#define RETROSND_VOICE_BREATH 122
936
937#define RETROSND_VOICE_SEASHORE 123
938
939#define RETROSND_VOICE_BIRD_TWEET 124
940
941#define RETROSND_VOICE_PHONE_RING 125
942
943#define RETROSND_VOICE_HELICOPTER 126
944
945#define RETROSND_VOICE_APPLAUSE 127
946
951#define RETROSND_VOICE_GUNSHOT 128
952
953#define RETROSND_CHANNEL_CT 8
954
964
968void retrosnd_set_sf_bank( const char* filename_in );
969
970void retrosnd_midi_set_voice( uint8_t channel, uint8_t voice );
971
972void retrosnd_midi_set_control( uint8_t channel, uint8_t key, uint8_t val );
973
974void retrosnd_midi_note_on( uint8_t channel, uint8_t pitch, uint8_t vel );
975
976void retrosnd_midi_note_off( uint8_t channel, uint8_t pitch, uint8_t vel );
977
978MERROR_RETVAL retrosnd_midi_play_smf( const char* filename );
979
980uint8_t retrosnd_midi_is_playing_smf();
981
982void retrosnd_shutdown();
983 /* maug_retrosnd */
985
986#endif /* !RETROFLAT_NO_SOUND */
987
988/* === Platform-specific APIs === */
989
990/* The first call to these headers should just establish definitions (macros, defines, prototypes,
991 * typedefs, etc). The later call below should then define function bodies.
992 */
993#ifndef RETROFLAT_NO_SOUND
994# include <retapis.h>
995#endif /* !RETROFLAT_NO_SOUND */
996#include <retapii.h>
997
998/* === End platform-specific APIs === */
999
1004
1005# if defined( RETROFLAT_NO_KEYBOARD )
1006# define retroflat_case_key( key, pad ) case pad:
1007# define retroflat_or_key( input, key, pad ) ((input) == (pad))
1008# elif defined( RETROFLAT_NO_PAD )
1009# define retroflat_case_key( key, pad ) case key:
1010# define retroflat_or_key( input, key, pad ) ((input) == (key))
1011# else
1019# define retroflat_case_key( key, pad ) case pad: case key:
1020# define retroflat_or_key( input, key, pad ) \
1021 (((input) == (pad)) || ((input) == (key)))
1022# endif
1023 /* maug_retroflt_input */
1025
1026/* === OS-Specific Includes and Defines === */
1027
1028#if defined( RETROFLAT_OS_WIN ) && !defined( MAUG_WINDOWS_H )
1029# include <windows.h>
1030# define MAUG_WINDOWS_H
1031#endif /* !MAUG_WINDOWS_H */
1032
1033#if defined( RETROFLAT_BMP_TEX ) || defined( DOCUMENTATION )
1034
1036 uint8_t flags;
1037 MAUG_MHANDLE bytes_h;
1038 uint8_t* bytes;
1039 uint32_t bpp;
1040 uint32_t sz;
1041 uint8_t* px;
1042 uint32_t id;
1043 size_t w;
1044 size_t h;
1045};
1046
1047#endif /* RETROFLAT_BMP_TEX */
1048
1049/* TODO: Migrate all platform-specific parts below to retapid.h. */
1050#include <retapid.h>
1051
1052#ifndef retroflat_system_task
1058# define retroflat_system_task()
1059#endif /* !retroflat_system_task */
1060
1061typedef maug_ms_t retroflat_ms_t;
1062
1063#include "retrom2d.h"
1064
1065/* === Structures === */
1066
1067/* TODO: Break the args into API-specific headers. */
1068
1071 uint8_t flags;
1076 char* title;
1099 int screen_scale;
1107 int joystick_id;
1108 struct RETROFLAT_PLATFORM_ARGS platform;
1109# ifndef RETROFLAT_NO_SOUND
1110 struct RETROFLAT_SOUND_ARGS sound;
1111# endif /* !RETROFLAT_NO_SOUND */
1112};
1113
1124
1137 int16_t screen_x;
1143 int16_t screen_y;
1149 int16_t world_x;
1155 int16_t world_y;
1161 int16_t world_w;
1167 int16_t world_h;
1173 uint16_t screen_w;
1179 uint16_t screen_h;
1208 int16_t world_tile_x;
1209 int16_t world_tile_y;
1210#ifndef RETROFLAT_NO_VIEWPORT_REFRESH
1211 MAUG_MHANDLE refresh_grid_h;
1223#endif /* !RETROFLAT_NO_VIEWPORT_REFRESH */
1224};
1225
1226# define retroflat_screen_colors() (g_retroflat_state->screen_colors)
1227
1228#ifndef DOCUMENTATION
1229
1230# define retroflat_viewport_world_x_generic() \
1231 (g_retroflat_state->viewport.world_x)
1232
1233# define retroflat_viewport_world_y_generic() \
1234 (g_retroflat_state->viewport.world_y)
1235
1236# define retroflat_viewport_world_tile_x_generic() \
1237 (g_retroflat_state->viewport.world_tile_x)
1238
1239# define retroflat_viewport_world_tile_y_generic() \
1240 (g_retroflat_state->viewport.world_tile_y)
1241
1242# define retroflat_viewport_world_w_generic() \
1243 (g_retroflat_state->viewport.world_w)
1244
1245# define retroflat_viewport_world_h_generic() \
1246 (g_retroflat_state->viewport.world_h)
1247
1248# define retroflat_viewport_screen_tile_w_generic() \
1249 (g_retroflat_state->viewport.screen_tile_w)
1250
1251# define retroflat_viewport_screen_tile_h_generic() \
1252 (g_retroflat_state->viewport.screen_tile_h)
1253
1254# define retroflat_viewport_screen_w_generic() \
1255 (g_retroflat_state->viewport.screen_w)
1256
1257# define retroflat_viewport_screen_h_generic() \
1258 (g_retroflat_state->viewport.screen_h)
1259
1260# define retroflat_viewport_screen_w_remainder_generic() \
1261 (g_retroflat_state->viewport.screen_w_remainder)
1262
1263# define retroflat_viewport_screen_h_remainder_generic() \
1264 (g_retroflat_state->viewport.screen_h_remainder)
1265
1266# define retroflat_viewport_set_world_generic( w, h ) \
1267 debug_printf( 1, "setting viewport size to %d x %d...", \
1268 (int16_t)(w), (int16_t)(h) ); \
1269 (g_retroflat_state->viewport.world_w) = w; \
1270 (g_retroflat_state->viewport.world_h) = h;
1271
1272# define retroflat_viewport_set_world_pos_generic( x, y ) \
1273 debug_printf( 1, "setting viewport world pos to %d, %d...", x, y ); \
1274 (g_retroflat_state->viewport.world_x) = x; \
1275 (g_retroflat_state->viewport.world_y) = y; \
1276 (g_retroflat_state->viewport.world_tile_x) = (x) >> RETROFLAT_TILE_W_BITS; \
1277 (g_retroflat_state->viewport.world_tile_y) = (y) >> RETROFLAT_TILE_H_BITS;
1278
1279# define retroflat_viewport_set_pos_size_generic( x_px, y_px, w_px, h_px ) \
1280 g_retroflat_state->viewport.screen_x = (x_px); \
1281 g_retroflat_state->viewport.screen_y = (y_px); \
1282 g_retroflat_state->viewport.screen_tile_w = \
1283 ((w_px) / RETROFLAT_TILE_W); \
1284 g_retroflat_state->viewport.screen_tile_h = \
1285 ((h_px) / RETROFLAT_TILE_H); \
1286 /* We're not adding the extra room here since this won't be used for
1287 * indexing or allocation but rather pixel detection.
1288 */ \
1289 g_retroflat_state->viewport.screen_w = \
1290 ((w_px) / RETROFLAT_TILE_W) * RETROFLAT_TILE_W; \
1291 g_retroflat_state->viewport.screen_h = \
1292 ((h_px) / RETROFLAT_TILE_H) * RETROFLAT_TILE_H; \
1293 g_retroflat_state->viewport.screen_w_remainder = \
1294 (x_px) + (w_px) - g_retroflat_state->viewport.screen_w; \
1295 g_retroflat_state->viewport.screen_h_remainder = \
1296 (y_px) + (h_px) - g_retroflat_state->viewport.screen_h;
1297
1298#ifndef RETROFLAT_NO_VIEWPORT_REFRESH
1299
1300# define retroflat_viewport_lock_refresh_generic() \
1301 if( NULL == g_retroflat_state->viewport.refresh_grid ) { \
1302 maug_mlock( \
1303 g_retroflat_state->viewport.refresh_grid_h, \
1304 g_retroflat_state->viewport.refresh_grid ); \
1305 maug_cleanup_if_null_lock( retroflat_tile_t*, \
1306 g_retroflat_state->viewport.refresh_grid ); \
1307 }
1308
1309# define retroflat_viewport_unlock_refresh_generic() \
1310 if( NULL != g_retroflat_state->viewport.refresh_grid ) { \
1311 maug_munlock( \
1312 g_retroflat_state->viewport.refresh_grid_h, \
1313 g_retroflat_state->viewport.refresh_grid ); \
1314 }
1315
1316# define _retroflat_viewport_refresh_tile_x( x_px ) \
1317 (((x_px) + RETROFLAT_TILE_W) >> RETROFLAT_TILE_W_BITS)
1318
1319# define _retroflat_viewport_refresh_tile_y( y_px ) \
1320 (((y_px) + RETROFLAT_TILE_H) >> RETROFLAT_TILE_H_BITS)
1321
1322# define retroflat_viewport_set_refresh_generic( x_px, y_px, tid ) \
1323 assert( NULL != g_retroflat_state->viewport.refresh_grid ); \
1324 if( \
1325 /* Expand the range by -1 to account for just off-screen tile. */ \
1326 -(RETROFLAT_TILE_W) <= x_px && -(RETROFLAT_TILE_H) <= y_px && \
1327 retroflat_screen_w() > x_px && \
1328 retroflat_screen_h() > y_px \
1329 ) { \
1330 assert( 0 < g_retroflat_state->viewport.screen_tile_w ); \
1331 assert( 0 <= (((y_px) + RETROFLAT_TILE_H) >> RETROFLAT_TILE_H_BITS) ); \
1332 assert( 0 <= (((x_px) + RETROFLAT_TILE_W) >> RETROFLAT_TILE_W_BITS) ); \
1333 g_retroflat_state->viewport.refresh_grid[ \
1334 /* Add +1 tile to make off-screen "-1" tile positive. */ \
1335 ((_retroflat_viewport_refresh_tile_y( y_px ) + 1) * \
1336 (g_retroflat_state->viewport.screen_tile_w + 2)) + \
1337 (_retroflat_viewport_refresh_tile_x( x_px ) + 1)] = tid; \
1338 }
1339
1340# define retroflat_viewport_tile_is_stale( x_px, y_px, tile_id ) \
1341 ((tile_id) != \
1342 g_retroflat_state->viewport.refresh_grid[ \
1343 ((_retroflat_viewport_refresh_tile_y( y_px ) + 1) * \
1344 (g_retroflat_state->viewport.screen_tile_w + 2)) + \
1345 (_retroflat_viewport_refresh_tile_x( x_px ) + 1)])
1346
1347#endif /* !RETROFLAT_NO_VIEWPORT_REFRESH */
1348
1349uint8_t retroflat_viewport_move_x_generic( int16_t x );
1350
1351uint8_t retroflat_viewport_move_y_generic( int16_t y );
1352
1353uint8_t retroflat_viewport_focus_generic(
1354 size_t x1, size_t y1, size_t range, size_t speed );
1355
1356# define retroflat_viewport_screen_x_generic( world_x ) \
1357 (g_retroflat_state->viewport.screen_x + \
1358 ((world_x) - retroflat_viewport_world_x()))
1359
1360# define retroflat_viewport_screen_y_generic( world_y ) \
1361 (g_retroflat_state->viewport.screen_y + \
1362 ((world_y) - retroflat_viewport_world_y()))
1363
1364#endif /* !DOCUMENTATION */
1365
1366#if defined( RETROFLAT_SOFT_VIEWPORT ) || defined( DOCUMENTATION )
1367
1368# ifndef RETROFLAT_NO_VIEWPORT_REFRESH
1369 /* These clamp world coordinates to tile borders to allow refresh grid to
1370 * function properly (smooth-scrolling tiles will always be in motion).
1371 */
1372
1377# define retroflat_viewport_world_x() \
1378 ((retroflat_viewport_world_x_generic() \
1379 >> RETROFLAT_TILE_W_BITS) << RETROFLAT_TILE_W_BITS)
1380
1385# define retroflat_viewport_world_y() \
1386 ((retroflat_viewport_world_y_generic() \
1387 >> RETROFLAT_TILE_H_BITS) << RETROFLAT_TILE_H_BITS)
1388# else
1389# define retroflat_viewport_world_x() retroflat_viewport_world_x_generic()
1390# define retroflat_viewport_world_y() retroflat_viewport_world_y_generic()
1391#endif /* !RETROFLAT_NO_VIEWPORT_REFRESH */
1392
1393# define retroflat_viewport_world_tile_x() \
1394 retroflat_viewport_world_tile_x_generic()
1395# define retroflat_viewport_world_tile_y() \
1396 retroflat_viewport_world_tile_y_generic()
1397
1402# define retroflat_viewport_world_w() \
1403 retroflat_viewport_world_w_generic()
1404
1409# define retroflat_viewport_world_h() \
1410 retroflat_viewport_world_h_generic()
1411
1416# define retroflat_viewport_screen_tile_w() \
1417 retroflat_viewport_screen_tile_w_generic()
1418
1423# define retroflat_viewport_screen_tile_h() \
1424 retroflat_viewport_screen_tile_h_generic()
1425
1430# define retroflat_viewport_screen_w() \
1431 retroflat_viewport_screen_w_generic()
1432
1437# define retroflat_viewport_screen_h() \
1438 retroflat_viewport_screen_h_generic()
1439
1445# define retroflat_viewport_screen_w_remainder() \
1446 retroflat_viewport_screen_w_remainder_generic()
1447
1453# define retroflat_viewport_screen_h_remainder() \
1454 retroflat_viewport_screen_h_remainder_generic()
1455
1463# define retroflat_viewport_set_world( w, h ) \
1464 retroflat_viewport_set_world_generic( w, h )
1465
1470# define retroflat_viewport_set_world_pos( x, y ) \
1471 retroflat_viewport_set_world_pos_generic( x, y )
1472
1478# define retroflat_viewport_set_pos_size( x_px, y_px, w_px, h_px ) \
1479 retroflat_viewport_set_pos_size_generic( x_px, y_px, w_px, h_px )
1480
1481#ifndef RETROFLAT_NO_VIEWPORT_REFRESH
1482
1490# define retroflat_viewport_lock_refresh() \
1491 retroflat_viewport_lock_refresh_generic()
1492
1500# define retroflat_viewport_unlock_refresh() \
1501 retroflat_viewport_unlock_refresh_generic()
1502
1514# define retroflat_viewport_set_refresh( x, y, tid ) \
1515 retroflat_viewport_set_refresh_generic( x, y, tid )
1516
1517#endif /* !RETROFLAT_NO_VIEWPORT_REFRESH */
1518
1531# define retroflat_viewport_focus( x1, y1, range, speed ) \
1532 retroflat_viewport_focus_generic( x1, y1, range, speed )
1533
1538# define retroflat_viewport_screen_x( world_x ) \
1539 retroflat_viewport_screen_x_generic( world_x )
1540
1545# define retroflat_viewport_screen_y( world_y ) \
1546 retroflat_viewport_screen_y_generic( world_y )
1547
1548# ifndef RETROFLAT_VIEWPORT_OVERRIDE_MOVE
1549# define retroflat_viewport_move_x( x ) \
1550 retroflat_viewport_move_x_generic( x )
1551
1552# define retroflat_viewport_move_y( y ) \
1553 retroflat_viewport_move_y_generic( y )
1554# endif /* !RETROFLAT_VIEWPORT_OVERRIDE_MOVE */
1555
1556#endif /* RETROFLAT_SOFT_VIEWPORT || DOCUMENTATION */
1557
1559
1566#define retroflat_heartbeat_set( len, max ) \
1567 g_retroflat_state->heartbeat_max = max; \
1568 g_retroflat_state->heartbeat_len = len;
1569
1574#define retroflat_heartbeat() (g_retroflat_state->heartbeat_frame)
1575
1582#define retroflat_heartbeat_update() \
1583 /* Update the heartbeat animation frame. */ \
1584 if( g_retroflat_state->heartbeat_next <= retroflat_get_ms() ) { \
1585 g_retroflat_state->heartbeat_frame++; \
1586 if( \
1587 g_retroflat_state->heartbeat_frame >= \
1588 g_retroflat_state->heartbeat_max \
1589 ) { \
1590 g_retroflat_state->heartbeat_frame = 0; \
1591 } \
1592 g_retroflat_state->heartbeat_next = \
1593 retroflat_get_ms() + g_retroflat_state->heartbeat_len; \
1594 }
1595
1603 /* TODO: Set this up in the initialization function! */
1604 /* TODO: We probably need more of these. */
1605 size_t sz;
1606 size_t offset_pal;
1607 size_t offset_tex_pal;
1608
1609 void* loop_data;
1610 MERROR_RETVAL retval;
1613 maug_path config_path;
1614 maug_path assets_path;
1615 maug_path saves_path;
1616
1618 /* struct RETROFLAT_BITMAP buffer; */
1620
1621# if defined( RETROFLAT_VDP ) || defined( DOCUMENTATION ) || \
1622defined( RETROVDP_C )
1627 struct RETROFLAT_BITMAP* vdp_buffer;
1628# ifdef RETROFLAT_OS_WIN
1629 HMODULE vdp_exe;
1630# else
1632 void* vdp_exe;
1633# endif /* RETROFLAT_OS_WIN */
1642 uint8_t vdp_flags;
1643# endif /* RETROFLAT_VDP || DOCUMENTATION || RETROVDP_C */
1644
1645 /* These are used by VDP so should be standardized/not put in plat-spec! */
1646
1647 struct RETROFLAT_VIEWPORT viewport;
1648
1664 size_t screen_w;
1666 size_t screen_h;
1669
1670 /* WARNING: The VDP requires the state specifier to be the same size
1671 * as the one it was compiled for! Do not modify above here!
1672 */
1673
1674 /* TODO: Put these in a platform-specific struct of some kind to maintain
1675 * consistent state struct size for VDP?
1676 */
1677
1678 retroflat_ms_t heartbeat_next;
1696
1697 retroflat_proc_resize_t on_resize;
1698 void* on_resize_data;
1699
1700#ifndef RETROFLAT_BMP_TEX
1702 RETROFLAT_COLOR_DEF palette[RETROFLAT_COLORS_SZ];
1703#endif /* !RETROFLAT_BMP_TEX */
1704
1705 retroflat_loop_iter loop_iter;
1706 retroflat_loop_iter frame_iter;
1707
1708 struct RETROFLAT_PLATFORM platform;
1709
1710# if defined( RETROFLAT_BMP_TEX )
1711 /* This allows native colors to be used for things like glColor3fv while
1712 * these colors are used to manipulate textures passed through
1713 * retroflat_bitmap_*().
1714 */
1715 RETROFLAT_TEX_COLOR_DEF tex_palette[RETROFLAT_COLORS_SZ];
1716# endif /* RETROFLAT_BMP_TEX */
1717
1718 struct RETROFLAT_INPUT_STATE input;
1719
1720# ifndef RETROFLAT_NO_SOUND
1721 struct RETROFLAT_SOUND_STATE sound;
1722# endif /* !RETROFLAT_NO_SOUND */
1723};
1724
1725/* === Translation Module === */
1726
1727/* Declare the prototypes so that internal functions can call each other. */
1728
1729# ifdef retroflat_loop
1730MERROR_RETVAL retroflat_loop_generic(
1731 retroflat_loop_iter frame_iter, retroflat_loop_iter loop_iter, void* data );
1732# else
1739 retroflat_loop_iter frame_iter, retroflat_loop_iter loop_iter, void* data );
1740# endif /* retroflat_loop */
1741
1742#define retroflat_get_assets_path() (g_retroflat_state->assets_path)
1743
1744MERROR_RETVAL retroflat_build_filename_path(
1745 const maug_path filename_in, const char* filename_ext,
1746 char* buffer_out, size_t buffer_out_sz, uint8_t flags );
1747
1752
1760 uint8_t flags, const char* title, const char* format, ... );
1761 /* maug_retroflt_msg_api */
1763
1771MERROR_RETVAL retroflat_init( int argc, char* argv[], struct RETROFLAT_ARGS* args );
1772
1779void retroflat_shutdown( int retval );
1780
1781# if defined( RETROFLAT_VDP ) || defined( DOCUMENTATION )
1786
1790MERROR_RETVAL retroflat_vdp_call( const char* proc_name );
1791 /* maug_retroflt_vdp */
1793# endif /* RETROFLAT_VDP || DOCUMENTATION */
1794
1795RETROFLAT_IN_KEY retroflat_repeat_input(
1796 RETROFLAT_IN_KEY key_out, struct RETROFLAT_INPUT* input,
1797 RETROFLAT_IN_KEY* prev_input, int* prev_delay );
1798
1799void retroflat_set_title( const char* format, ... );
1800
1801retroflat_ms_t retroflat_get_ms();
1802
1803uint32_t retroflat_get_rand();
1804
1805# if !defined( RETROFLAT_NO_KEYBOARD )
1806char retroflat_vk_to_ascii( RETROFLAT_IN_KEY k, uint8_t flags );
1807# endif /* !RETROFLAT_NO_KEYBOARD */
1808
1813
1825 const char* filename, struct RETROFLAT_BITMAP* bmp_out, uint8_t flags );
1826
1827MERROR_RETVAL retroflat_create_bitmap(
1828 size_t w, size_t h, struct RETROFLAT_BITMAP* bmp_out, uint8_t flags );
1829
1835void retroflat_destroy_bitmap( struct RETROFLAT_BITMAP* bitmap );
1836
1853 struct RETROFLAT_BITMAP* target, struct RETROFLAT_BITMAP* src,
1854 size_t s_x, size_t s_y, int16_t d_x, int16_t d_y, size_t w, size_t h,
1855 int16_t instance );
1856
1857#ifdef RETROFLAT_TRACE_CONSTRAIN
1858# define retroflat_constrain_px( x, y, bmp, retact ) \
1859 if( \
1860 x >= retroflat_bitmap_w( bmp ) || y >= retroflat_bitmap_h( bmp ) || \
1861 0 > x || 0 > y \
1862 ) { \
1863 error_printf( "attempted offscreen draw: %d, %d", x, y ); \
1864 retact; \
1865 }
1866#else
1874# define retroflat_constrain_px( x, y, bmp, retact ) \
1875 if( \
1876 x >= retroflat_bitmap_w( bmp ) || y >= retroflat_bitmap_h( bmp ) || \
1877 0 > x || 0 > y \
1878 ) { \
1879 retact; \
1880 }
1881#endif /* RETROFLAT_TRACE_CONSTRAIN */
1882 /* maug_retroflt_bitmap */
1884
1889
1899MERROR_RETVAL retroflat_draw_lock( struct RETROFLAT_BITMAP* bmp );
1900
1901MERROR_RETVAL retroflat_draw_release( struct RETROFLAT_BITMAP* bmp );
1902
1903void retroflat_px(
1904 struct RETROFLAT_BITMAP* target, const RETROFLAT_COLOR color,
1905 size_t x, size_t y, uint8_t flags );
1906
1907#ifdef RETROFLAT_SOFT_SHAPES
1908# ifdef RETROFLAT_OPENGL
1909/* Make sure we're not passing NULL to openGL texture drawers... they can't
1910 * handle that!
1911 */
1912# define retroflat_rect( t, c, x, y, w, h, f ) \
1913 assert( NULL != t ); \
1914 retrosoft_rect( t, c, x, y, w, h, f );
1915# define retroflat_ellipse( t, c, x, y, w, h, f ) \
1916 assert( NULL != t ); \
1917 retrosoft_ellipse( t, c, x, y, w, h, f )
1918# else
1919# define retroflat_rect( t, c, x, y, w, h, f ) \
1920 retrosoft_rect( t, c, x, y, w, h, f )
1921# define retroflat_ellipse( t, c, x, y, w, h, f ) \
1922 retrosoft_ellipse( t, c, x, y, w, h, f )
1923# endif /* RETROFLAT_3D */
1924#else
1925
1937 struct RETROFLAT_BITMAP* target, const RETROFLAT_COLOR color,
1938 int16_t x, int16_t y, int16_t w, int16_t h, uint8_t flags );
1939
1951 struct RETROFLAT_BITMAP* target, const RETROFLAT_COLOR color,
1952 int16_t x, int16_t y, int16_t w, int16_t h, uint8_t flags );
1953
1954#endif /* RETROFLAT_SOFT_SHAPES */
1955
1956#ifdef RETROFLAT_SOFT_LINES
1957# define retroflat_line( t, c, x1, y1, x2, y2, f ) \
1958 retrosoft_line( t, c, x1, y1, x2, y2, f )
1959#else
1960
1973 struct RETROFLAT_BITMAP* target, const RETROFLAT_COLOR color,
1974 int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint8_t flags );
1975
1976#endif /* RETROFLAT_SOFT_LINES */
1977
1978void retroflat_cursor( struct RETROFLAT_BITMAP* target, uint8_t flags );
1979
1993 struct RETROFLAT_BITMAP* target, const char* str, size_t str_sz,
1994 const char* font_str, size_t* w_out, size_t* h_out, uint8_t flags );
1995
2014 struct RETROFLAT_BITMAP* target, const RETROFLAT_COLOR color,
2015 const char* str, int str_sz, const char* font_str, int16_t x_orig, int16_t y_orig,
2016 uint8_t flags );
2017
2018/* TODO: Documentation! */
2019void retroflat_get_palette( uint8_t idx, uint32_t* rgb );
2020
2021MERROR_RETVAL retroflat_set_palette( uint8_t idx, uint32_t rgb );
2022 /* maug_retroflt_bitmap */
2024
2035 retroflat_proc_resize_t on_resize_in, void* data_in );
2036
2042
2047
2053RETROFLAT_IN_KEY retroflat_poll_input( struct RETROFLAT_INPUT* input );
2054 /* maug_retroflt_input */
2056
2057#ifdef RETROFLT_C
2058
2059MAUG_CONST int16_t SEG_MCONST gc_retroflat_offsets8_x[8] =
2060 { 0, 1, 1, 1, 0, -1, -1, -1 };
2061MAUG_CONST int16_t SEG_MCONST gc_retroflat_offsets8_y[8] =
2062 { -1, -1, 0, 1, 1, 1, 0, -1 };
2063
2064MAUG_CONST int16_t SEG_MCONST gc_retroflat_offsets4_x[4] =
2065 { 0, 1, 0, -1 };
2066MAUG_CONST int16_t SEG_MCONST gc_retroflat_offsets4_y[4] =
2067 { -1, 0, 1, 0 };
2068
2069# ifdef RETROFLAT_STATE_ON_STACK
2070struct RETROFLAT_STATE SEG_MGLOBAL g_retroflat_state_stack;
2071# else
2072MAUG_MHANDLE SEG_MGLOBAL g_retroflat_state_h = (MAUG_MHANDLE)NULL;
2073# endif /* RETROFLAT_STATE_ON_STACK */
2074struct RETROFLAT_STATE* SEG_MGLOBAL g_retroflat_state = NULL;
2075
2076# define RETROFLAT_COLOR_TABLE_CONSTS( idx, name_l, name_u, r, g, b, cgac, cgad ) \
2077 MAUG_CONST RETROFLAT_COLOR SEG_MCONST RETROFLAT_COLOR_ ## name_u = idx;
2078
2079RETROFLAT_COLOR_TABLE( RETROFLAT_COLOR_TABLE_CONSTS )
2080
2081# define RETROFLAT_COLOR_TABLE_NAMES( idx, name_l, name_u, r, g, b, cgac, cgad ) \
2082 #name_u,
2083
2084MAUG_CONST char* SEG_MCONST gc_retroflat_color_names[] = {
2085 RETROFLAT_COLOR_TABLE( RETROFLAT_COLOR_TABLE_NAMES )
2086};
2087
2088/* Callback table is down below, after the statically-defined callbacks. */
2089
2090/* === Function Definitions === */
2091
2092MERROR_RETVAL retroflat_build_filename_path(
2093 const maug_path filename_in, const char* filename_ext,
2094 char* buffer_out, size_t buffer_out_sz, uint8_t flags
2095) {
2096 MERROR_RETVAL retval = MERROR_OK;
2097
2098 assert( 1 < buffer_out_sz );
2099
2100 /* Build the path to the bitmap. */
2101 maug_mzero( buffer_out, buffer_out_sz );
2102 if(
2105 ) {
2106 /* TODO: Error checking. */
2107 maug_snprintf( buffer_out, buffer_out_sz - 1, "%s", filename_in );
2108 } else if( NULL != filename_ext ) {
2109 /* TODO: Error checking. */
2110 maug_snprintf( buffer_out, buffer_out_sz - 1, "%s%c%s.%s",
2111 g_retroflat_state->assets_path, RETROFLAT_PATH_SEP,
2112 filename_in, filename_ext );
2113 } else {
2114 maug_snprintf( buffer_out, buffer_out_sz - 1, "%s%c%s",
2115 g_retroflat_state->assets_path, RETROFLAT_PATH_SEP,
2116 filename_in );
2117 }
2118
2119 return retval;
2120}
2121
2122/* === */
2123
2124# if (defined( RETROFLAT_SOFT_SHAPES ) || defined( RETROFLAT_SOFT_LINES ) || \
2125 defined( RETROFLAT_3D ))
2126/* RETROSOFT_PRESENT is different from RETROFLAT_SOFT_SHAPES in that it only
2127 * indicates that the retrosoft library is loaded, not that it is the default
2128 * for drawing primatives!
2129 */
2130# define RETROSOFT_PRESENT
2131# endif
2132
2133# if defined( RETROFLAT_3D )
2134# if !defined( MAUG_NO_AUTO_C )
2135# define RETRO3D_C
2136# define RETRO3DP_C
2137# define RETROFP_C
2138# endif /* MAUG_NO_AUTO_C */
2139# include <retro3dp.h>
2140# include <retro3d.h>
2141# include <retro3du.h>
2142# include <retapi3.h>
2143# endif /* RETROFLAT_3D */
2144
2145# ifdef RETROSOFT_PRESENT
2146# if !defined( MAUG_NO_AUTO_C )
2147# define RETROSFT_C
2148# endif /* !MAUG_NO_AUTO_C */
2149# define RETROSOFT_PRESENT
2150# include <retrosft.h>
2151# endif /* RETROFLAT_SOFT_SHAPES */
2152
2153# ifndef RETROFLAT_NO_SOUND
2154# include <retapis.h>
2155# endif /* !RETROFLAT_NO_SOUND */
2156
2157# include <retapii.h>
2158
2159# if defined( RETROFLAT_VDP ) && defined( RETROFLAT_OS_UNIX )
2160# include <dlfcn.h>
2161# endif
2162
2163/* Still inside RETROFLT_C! */
2164
2165/* === */
2166
2167#ifndef RETROFLAT_NO_GENERIC_LOOP
2168
2169MERROR_RETVAL retroflat_loop_generic(
2170 retroflat_loop_iter frame_iter, retroflat_loop_iter loop_iter, void* data
2171) {
2172 MERROR_RETVAL retval = MERROR_OK;
2173 retroflat_ms_t next = 0,
2174 now = 0;
2175
2176 g_retroflat_state->loop_iter = (retroflat_loop_iter)loop_iter;
2177 g_retroflat_state->loop_data = (void*)data;
2178 g_retroflat_state->frame_iter = (retroflat_loop_iter)frame_iter;
2179
2180 if(
2182 (g_retroflat_state->retroflat_flags & RETROFLAT_FLAGS_RUNNING)
2183 ) {
2184 /* Main loop is already running, so we're just changing the iter call
2185 * and leaving!
2186 */
2187 debug_printf( 1, "main loop already running!" );
2188 goto cleanup;
2189 }
2190
2191 g_retroflat_state->retroflat_flags |= RETROFLAT_FLAGS_RUNNING;
2192 do {
2194
2195 if(
2196 /* Not waiting for the next frame? */
2198 (RETROFLAT_FLAGS_WAIT_FOR_FPS & g_retroflat_state->retroflat_flags) &&
2199 /* Inter-frame loop present? */
2200 NULL != g_retroflat_state->loop_iter
2201 ) {
2202 /* Run the loop iter as many times as possible. */
2203 g_retroflat_state->loop_iter( g_retroflat_state->loop_data );
2204 }
2205 if(
2207 (RETROFLAT_FLAGS_UNLOCK_FPS & g_retroflat_state->retroflat_flags) &&
2208 retroflat_get_ms() < next
2209 ) {
2210 /* Sleep/low power for a bit. */
2211 continue;
2212 }
2213
2215
2216 if( NULL != g_retroflat_state->frame_iter ) {
2217 /* Run the frame iterator once per FPS tick. */
2218 g_retroflat_state->frame_iter( g_retroflat_state->loop_data );
2219 }
2220 /* Reset wait-for-frame flag AFTER frame callback. */
2221 g_retroflat_state->retroflat_flags &= ~RETROFLAT_FLAGS_WAIT_FOR_FPS;
2222 now = retroflat_get_ms();
2223 if( now + retroflat_fps_next() > now ) {
2224 next = now + retroflat_fps_next();
2225 } else {
2226 /* Rollover protection. */
2227 /* TODO: Add difference from now/next to 0 here. */
2228 next = 0;
2229 }
2230 } while(
2232 (RETROFLAT_FLAGS_RUNNING & g_retroflat_state->retroflat_flags)
2233 );
2234 retval = g_retroflat_state->retval;
2235
2236cleanup:
2237
2238 /* This should be set by retroflat_quit(). */
2239 return retval;
2240}
2241
2242#endif /* !RETROFLAT_NO_GENERIC_LOOP */
2243
2244/* === */
2245
2246# if !defined( RETROFLAT_NO_KEYBOARD )
2247
2248char retroflat_vk_to_ascii( RETROFLAT_IN_KEY k, uint8_t flags ) {
2249 char c = 0;
2250 char offset_lower = 0;
2251
2252 if( RETROFLAT_INPUT_MOD_SHIFT != (RETROFLAT_INPUT_MOD_SHIFT & flags) ) {
2253 /* Shift is *not* being held down. */
2254
2255 if( RETROFLAT_KEY_A <= k && RETROFLAT_KEY_Z >= k ) {
2256 if(
2257 RETROFLAT_INPUT_FORCE_UPPER !=
2258 (RETROFLAT_INPUT_FORCE_UPPER & flags)
2259 ) {
2260 /* Key is alphabetical and we're not forcing uppercase. */
2261 offset_lower = 0x20;
2262 }
2263 } else {
2264 offset_lower = 1;
2265 }
2266 }
2267
2268 switch( k ) {
2269 case RETROFLAT_KEY_A: c = 0x41 + offset_lower; break;
2270 case RETROFLAT_KEY_B: c = 0x42 + offset_lower; break;
2271 case RETROFLAT_KEY_C: c = 0x43 + offset_lower; break;
2272 case RETROFLAT_KEY_D: c = 0x44 + offset_lower; break;
2273 case RETROFLAT_KEY_E: c = 0x45 + offset_lower; break;
2274 case RETROFLAT_KEY_F: c = 0x46 + offset_lower; break;
2275 case RETROFLAT_KEY_G: c = 0x47 + offset_lower; break;
2276 case RETROFLAT_KEY_H: c = 0x48 + offset_lower; break;
2277 case RETROFLAT_KEY_I: c = 0x49 + offset_lower; break;
2278 case RETROFLAT_KEY_J: c = 0x4a + offset_lower; break;
2279 case RETROFLAT_KEY_K: c = 0x4b + offset_lower; break;
2280 case RETROFLAT_KEY_L: c = 0x4c + offset_lower; break;
2281 case RETROFLAT_KEY_M: c = 0x4d + offset_lower; break;
2282 case RETROFLAT_KEY_N: c = 0x4e + offset_lower; break;
2283 case RETROFLAT_KEY_O: c = 0x4f + offset_lower; break;
2284 case RETROFLAT_KEY_P: c = 0x50 + offset_lower; break;
2285 case RETROFLAT_KEY_Q: c = 0x51 + offset_lower; break;
2286 case RETROFLAT_KEY_R: c = 0x52 + offset_lower; break;
2287 case RETROFLAT_KEY_S: c = 0x53 + offset_lower; break;
2288 case RETROFLAT_KEY_T: c = 0x54 + offset_lower; break;
2289 case RETROFLAT_KEY_U: c = 0x55 + offset_lower; break;
2290 case RETROFLAT_KEY_V: c = 0x56 + offset_lower; break;
2291 case RETROFLAT_KEY_W: c = 0x57 + offset_lower; break;
2292 case RETROFLAT_KEY_X: c = 0x58 + offset_lower; break;
2293 case RETROFLAT_KEY_Y: c = 0x59 + offset_lower; break;
2294 case RETROFLAT_KEY_Z: c = 0x60 + offset_lower; break;
2295 case RETROFLAT_KEY_0: c = offset_lower ? 0x30 : ')'; break;
2296 case RETROFLAT_KEY_1: c = offset_lower ? 0x31 : '!'; break;
2297 case RETROFLAT_KEY_2: c = offset_lower ? 0x32 : '@'; break;
2298 case RETROFLAT_KEY_3: c = offset_lower ? 0x33 : '#'; break;
2299 case RETROFLAT_KEY_4: c = offset_lower ? 0x34 : '$'; break;
2300 case RETROFLAT_KEY_5: c = offset_lower ? 0x35 : '%'; break;
2301 case RETROFLAT_KEY_6: c = offset_lower ? 0x36 : '^'; break;
2302 case RETROFLAT_KEY_7: c = offset_lower ? 0x37 : '&'; break;
2303 case RETROFLAT_KEY_8: c = offset_lower ? 0x38 : '*'; break;
2304 case RETROFLAT_KEY_9: c = offset_lower ? 0x39 : '('; break;
2305 case RETROFLAT_KEY_SPACE: c = ' '; break;
2306 case RETROFLAT_KEY_BKSP: c = 0x08; break;
2307 case RETROFLAT_KEY_ENTER: c = '\n'; break;
2308 case RETROFLAT_KEY_SEMICOLON: c = offset_lower ? ';' : ':'; break;
2309 case RETROFLAT_KEY_DASH: c = offset_lower ? '-' : '_'; break;
2310 case RETROFLAT_KEY_SLASH: c = offset_lower ? '/' : '?'; break;
2311 case RETROFLAT_KEY_PERIOD: c = offset_lower ? '.' : '>'; break;
2312 case RETROFLAT_KEY_COMMA: c = offset_lower ? ',' : '<'; break;
2313 case RETROFLAT_KEY_QUOTE: c = offset_lower ? '\'' : '"'; break;
2314 case RETROFLAT_KEY_EQUALS: c = offset_lower ? '=' : '+'; break;
2315 case RETROFLAT_KEY_BACKSLASH: c = offset_lower ? '\\' : '|'; break;
2316 case RETROFLAT_KEY_BRACKETL: c = offset_lower ? '[' : '{'; break;
2317 case RETROFLAT_KEY_BRACKETR: c = offset_lower ? ']' : '}'; break;
2318#ifndef RETROFLAT_API_PC_BIOS
2319 /* TODO: FIXME in DOS! */
2320 case RETROFLAT_KEY_GRAVE: c = offset_lower ? '`' : '~'; break;
2321#endif /* !RETROFLAT_API_PC_BIOS */
2322 }
2323
2324 debug_printf( RETROINPUT_TRACE_LVL, "0x%02x", c );
2325
2326 return c;
2327}
2328
2329#endif /* !RETROFLAT_NO_KEYBOARD */
2330
2331/* === */
2332
2333/* TODO: Migrate all platform-specific parts below to retapif.h. */
2334#include <retapif.h>
2335
2336/* === */
2337
2338# ifndef RETROFLAT_NO_CLI
2339
2340# if !defined( RETROFLAT_NO_SOUND ) && defined( RETROSND_ARGS )
2341
2342static MERROR_RETVAL retrosnd_cli_rsl(
2343 const char* arg, ssize_t arg_c, struct RETROFLAT_ARGS* args
2344) {
2345 if(
2346 0 <= arg_c &&
2347 0 == strncmp( MAUG_CLI_SIGIL "rsl", arg, MAUG_CLI_SIGIL_SZ + 4 )
2348 ) {
2349 args->sound.flags |= RETROSND_ARGS_FLAG_LIST_DEVS;
2350 }
2351 return MERROR_OK;
2352}
2353
2354# endif /* !RETROFLAT_NO_SOUND && RETROSND_ARGS */
2355
2356# if !defined( RETROFLAT_API_PC_BIOS ) && !defined( RETROFLAT_NO_CLI_SZ )
2357
2358static MERROR_RETVAL retroflat_cli_rfs(
2359 const char* arg, ssize_t arg_c, struct RETROFLAT_ARGS* args
2360) {
2361 if( 1 < arg_c ) {
2362 args->screen_scale = atoi( arg );
2363 debug_printf( 3, "screen scale arg set to: %d", args->screen_scale );
2364 }
2365 return MERROR_OK;
2366}
2367
2368static MERROR_RETVAL retroflat_cli_rfx(
2369 const char* arg, ssize_t arg_c, struct RETROFLAT_ARGS* args
2370) {
2371 if( 0 > arg_c ) {
2372 if( 0 == args->screen_w ) {
2373 args->screen_x = 0;
2374 }
2375 } else if(
2376 0 == strncmp( MAUG_CLI_SIGIL "rfx", arg, MAUG_CLI_SIGIL_SZ + 4 )
2377 ) {
2378 /* The next arg must be the new var. */
2379 } else {
2380 args->screen_x = atoi( arg );
2381 }
2382 return MERROR_OK;
2383}
2384
2385static MERROR_RETVAL retroflat_cli_rfy(
2386 const char* arg, ssize_t arg_c, struct RETROFLAT_ARGS* args
2387) {
2388 if( 0 > arg_c ) {
2389 if( 0 == args->screen_h ) {
2390 args->screen_y = 0;
2391 }
2392 } else if(
2393 0 == strncmp( MAUG_CLI_SIGIL "rfy", arg, MAUG_CLI_SIGIL_SZ + 4 )
2394 ) {
2395 /* The next arg must be the new var. */
2396 } else {
2397 args->screen_y = atoi( arg );
2398 }
2399 return MERROR_OK;
2400}
2401
2402static MERROR_RETVAL retroflat_cli_rfw(
2403 const char* arg, ssize_t arg_c, struct RETROFLAT_ARGS* args
2404) {
2405 if( 0 > arg_c ) {
2406 if( 0 == args->screen_w ) {
2407 args->screen_w = RETROFLAT_DEFAULT_SCREEN_W;
2408 debug_printf( 1, "setting arg screen_w to default %d:",
2409 args->screen_w );
2410 }
2411 } else if(
2412 0 == strncmp( MAUG_CLI_SIGIL "rfw", arg, MAUG_CLI_SIGIL_SZ + 4 )
2413 ) {
2414 /* The next arg must be the new var. */
2415 } else {
2416 args->screen_w = atoi( arg );
2417 debug_printf( 1, "setting arg screen_w to: %d",
2418 args->screen_w );
2419 }
2420 return MERROR_OK;
2421}
2422
2423static MERROR_RETVAL retroflat_cli_rfh(
2424 const char* arg, ssize_t arg_c, struct RETROFLAT_ARGS* args
2425) {
2426 if( 0 > arg_c ) {
2427 if( 0 == args->screen_h ) {
2428 args->screen_h = RETROFLAT_DEFAULT_SCREEN_H;
2429 debug_printf( 1, "setting arg screen_h to default: %d",
2430 args->screen_h );
2431 }
2432 } else if(
2433 0 == strncmp( MAUG_CLI_SIGIL "rfh", arg, MAUG_CLI_SIGIL_SZ + 4 )
2434 ) {
2435 /* The next arg must be the new var. */
2436 } else {
2437 args->screen_h = atoi( arg );
2438 debug_printf( 1, "setting arg screen_h to: %d",
2439 args->screen_h );
2440 }
2441 return MERROR_OK;
2442}
2443
2444# endif /* !RETROFLAT_API_PC_BIOS && !RETROFLAT_NO_CLI_SZ */
2445
2446# ifdef RETROFLAT_VDP
2447static MERROR_RETVAL retroflat_cli_vdp(
2448 const char* arg, ssize_t arg_c, struct RETROFLAT_ARGS* args
2449) {
2450 if( 0 == strncmp( MAUG_CLI_SIGIL "vdp", arg, MAUG_CLI_SIGIL_SZ + 4 ) ) {
2451 /* Next arg is VDP args str. */
2452 } else {
2453 maug_strncpy( g_retroflat_state->vdp_args, arg, RETROFLAT_VDP_ARGS_SZ_MAX );
2454 debug_printf( 1, "VDP args: %s", g_retroflat_state->vdp_args );
2455 }
2456 return MERROR_OK;
2457}
2458# endif /* RETROFLAT_VDP */
2459
2460static MERROR_RETVAL retroflat_cli_u(
2461 const char* arg, ssize_t arg_c, struct RETROFLAT_ARGS* args
2462) {
2463 if( 0 > arg_c ) {
2464 args->flags &= ~RETROFLAT_FLAGS_UNLOCK_FPS;
2465 } else if(
2466 0 == strncmp( MAUG_CLI_SIGIL "rfu", arg, MAUG_CLI_SIGIL_SZ + 4 )
2467 ) {
2468 debug_printf( 1, "unlocking FPS..." );
2469 args->flags |= RETROFLAT_FLAGS_UNLOCK_FPS;
2470 }
2471 return MERROR_OK;
2472}
2473
2474# ifndef RETROFLAT_NO_PAD
2475
2476static MERROR_RETVAL retroflat_cli_rfj(
2477 const char* arg, ssize_t arg_c, struct RETROFLAT_ARGS* args
2478) {
2479 if( 0 > arg_c ) {
2480 args->joystick_id = -1;
2481 debug_printf( 1, "setting arg joystick_id to default: %d",
2482 args->joystick_id );
2483 } else if(
2484 0 == strncmp( MAUG_CLI_SIGIL "rfj", arg, MAUG_CLI_SIGIL_SZ + 4 )
2485 ) {
2486 /* The next arg must be the new var. */
2487 } else {
2488 args->joystick_id = atoi( arg );
2489 debug_printf( 1, "setting arg joystick_id to: %d",
2490 args->joystick_id );
2491 }
2492 return MERROR_OK;
2493}
2494
2495# endif /* !RETROFLAT_NO_PAD */
2496
2497#endif /* !RETROFLAT_NO_CLI */
2498
2499/* === */
2500
2501/* Still inside RETROFLT_C! */
2502
2504 int argc, char* argv[], struct RETROFLAT_ARGS* args
2505) {
2506
2507 /* = Declare Init Vars = */
2508
2509 MERROR_RETVAL retval = 0;
2510
2511 /* = Begin Init Procedure = */
2512
2513# ifdef RETROFLAT_COMMIT_HASH
2514 debug_printf( 1, "retroflat commit: " RETROFLAT_COMMIT_HASH );
2515# endif /* RETROFLAT_COMMIT_HASH */
2516
2517 debug_printf( 1, "retroflat: initializing..." );
2518
2519 /* System sanity checks. */
2520 assert( 2 <= sizeof( MERROR_RETVAL ) );
2521 assert( 4 == sizeof( uint32_t ) );
2522 assert( 4 == sizeof( int32_t ) );
2523 assert( 2 == sizeof( uint16_t ) );
2524 assert( 2 == sizeof( int16_t ) );
2525 assert( 1 == sizeof( uint8_t ) );
2526 assert( 1 == sizeof( int8_t ) );
2527 assert( NULL != args );
2528 assert( 1 << RETROFLAT_TILE_W_BITS == RETROFLAT_TILE_W );
2529 assert( 1 << RETROFLAT_TILE_H_BITS == RETROFLAT_TILE_H );
2530
2531 debug_printf( 1, "initializing drawing routines..." );
2532
2533 /* Initialize 2D callbacks depending on if we're in 2D or 3D mode.
2534 * Please see retrom2d.h for more information.
2535 */
2536# if defined( RETROFLAT_BMP_TEX )
2537 retroflat_2d_px = (retroflat_px_cb)retro3d_texture_px;
2538 retroflat_2d_line = (retroflat_line_cb)retrosoft_line;
2539 retroflat_2d_rect = (retroflat_rect_cb)retrosoft_rect;
2540 retroflat_2d_ellipse = (retroflat_ellipse_cb)retrosoft_ellipse;
2541 retroflat_2d_blit_bitmap = (retroflat_blit_bitmap_cb)retro3d_texture_blit;
2542 retroflat_2d_load_bitmap =
2543 (retroflat_load_bitmap_cb)retro3d_texture_load_bitmap;
2544 retroflat_2d_create_bitmap =
2545 (retroflat_create_bitmap_cb)retro3d_texture_create;
2546# else
2547 retroflat_2d_px = (retroflat_px_cb)retroflat_px;
2548# ifdef RETROFLAT_SOFT_SHAPES
2549 /* TODO: Work retrosoft routines to use retroflat_blit_t */
2550 retroflat_2d_line = (retroflat_line_cb)retrosoft_line;
2551 retroflat_2d_rect = (retroflat_rect_cb)retrosoft_rect;
2552 retroflat_2d_ellipse = (retroflat_ellipse_cb)retrosoft_ellipse;
2553# else
2554 retroflat_2d_line = (retroflat_line_cb)retroflat_line;
2555 retroflat_2d_rect = (retroflat_rect_cb)retroflat_rect;
2556 retroflat_2d_ellipse = (retroflat_ellipse_cb)retroflat_ellipse;
2557# endif /* RETROFLAT_SOFT_SHAPES */
2558 retroflat_2d_blit_bitmap = (retroflat_blit_bitmap_cb)retroflat_blit_bitmap;
2559 retroflat_2d_load_bitmap = (retroflat_load_bitmap_cb)retroflat_load_bitmap;
2560 retroflat_2d_create_bitmap =
2561 (retroflat_create_bitmap_cb)retroflat_create_bitmap;
2562# endif /* RETROFLAT_BMP_TEX */
2563
2564 debug_printf( 1, "retroflat: MFIX_PRECISION: %f", MFIX_PRECISION );
2565
2566 debug_printf( 1, "retroflat: allocating state (" SIZE_T_FMT " bytes)...",
2567 sizeof( struct RETROFLAT_STATE ) );
2568
2569 debug_printf( 1, "retroflat: size_t is (" SIZE_T_FMT " bytes)...",
2570 sizeof( size_t ) );
2571
2572 debug_printf( 1, "retroflat: ssize_t is (" SIZE_T_FMT " bytes)...",
2573 sizeof( ssize_t ) );
2574
2575 debug_printf( 1, "retroflat: off_t is (" SIZE_T_FMT " bytes)...",
2576 sizeof( off_t ) );
2577
2578 debug_printf( 1, "initializing global state..." );
2579
2580# ifdef RETROFLAT_STATE_ON_STACK
2581 g_retroflat_state = &g_retroflat_state_stack;
2582# else
2583 maug_malloc_test( g_retroflat_state_h, 1, sizeof( struct RETROFLAT_STATE ) );
2584
2585 maug_mlock( g_retroflat_state_h, g_retroflat_state );
2586 if( NULL == g_retroflat_state ) {
2588 "Error", "Could not lock global state!" );
2589 retval = MERROR_ALLOC;
2590 goto cleanup;
2591 }
2592# endif /* RETROFLAT_STATE_ON_STACK */
2593
2594 maug_mzero( g_retroflat_state, sizeof( struct RETROFLAT_STATE ) );
2595
2596 retroflat_heartbeat_set( 1000, 2 );
2597
2598 debug_printf( 1, "initializing platform filesystem..." );
2599 retval = mfile_plt_init();
2600 maug_cleanup_if_not_ok();
2601
2602# ifndef RETROFLAT_NO_CLI
2603
2604 debug_printf( 1, "retroflat: parsing args..." );
2605
2606 /* All platforms: add command-line args based on compile definitons. */
2607
2608 retval = maug_add_arg(
2609 MAUG_CLI_SIGIL "h", MAUG_CLI_SIGIL_SZ + 2, "Display command-line help",
2610 26, maug_cli_h, NULL );
2611
2612# if !defined( RETROFLAT_NO_SOUND ) && defined( RETROSND_ARGS )
2613 retval = maug_add_arg( MAUG_CLI_SIGIL "rsd", MAUG_CLI_SIGIL_SZ + 4,
2614 "Select MIDI device", 0, (maug_cli_cb)retrosnd_cli_rsd, args );
2615 maug_cleanup_if_not_ok();
2616 retval = maug_add_arg( MAUG_CLI_SIGIL "rsl", MAUG_CLI_SIGIL_SZ + 4,
2617 "List MIDI devices", 0, (maug_cli_cb)retrosnd_cli_rsl, args );
2618 maug_cleanup_if_not_ok();
2619# endif /* !RETROFLAT_NO_SOUND && RETROSND_ARGS */
2620
2621# ifdef RETROFLAT_SCREENSAVER
2622 retval = maug_add_arg( MAUG_CLI_SIGIL "p", MAUG_CLI_SIGIL_SZ + 2,
2623 "Preview screensaver", 0, (maug_cli_cb)retroflat_cli_p, args );
2624 maug_cleanup_if_not_ok();
2625 retval = maug_add_arg( MAUG_CLI_SIGIL "s", MAUG_CLI_SIGIL_SZ + 2,
2626 "Launch screensaver", 0, (maug_cli_cb)retroflat_cli_s, args );
2627 maug_cleanup_if_not_ok();
2628# endif /* RETROFLAT_SCREENSAVER */
2629
2630# ifdef RETROFLAT_API_PC_BIOS
2631 retval = maug_add_arg( MAUG_CLI_SIGIL "rfm", MAUG_CLI_SIGIL_SZ + 4,
2632 "Set the screen mode.", 0,
2633 (maug_cli_cb)retroflat_cli_rfm, args );
2634 maug_cleanup_if_not_ok();
2635# elif !defined( RETROFLAT_NO_CLI_SZ )
2636 retval = maug_add_arg( MAUG_CLI_SIGIL "rfs", MAUG_CLI_SIGIL_SZ + 4,
2637 "Set screen scale factor.", 0,
2638 (maug_cli_cb)retroflat_cli_rfs, args );
2639 maug_cleanup_if_not_ok();
2640 retval = maug_add_arg( MAUG_CLI_SIGIL "rfx", MAUG_CLI_SIGIL_SZ + 4,
2641 "Set the screen X position.", 0,
2642 (maug_cli_cb)retroflat_cli_rfx, args );
2643 maug_cleanup_if_not_ok();
2644 retval = maug_add_arg( MAUG_CLI_SIGIL "rfy", MAUG_CLI_SIGIL_SZ + 4,
2645 "Set the screen Y position.", 0,
2646 (maug_cli_cb)retroflat_cli_rfy, args );
2647 maug_cleanup_if_not_ok();
2648 retval = maug_add_arg( MAUG_CLI_SIGIL "rfw", MAUG_CLI_SIGIL_SZ + 4,
2649 "Set the screen width.", 0,
2650 (maug_cli_cb)retroflat_cli_rfw, args );
2651 maug_cleanup_if_not_ok();
2652 retval = maug_add_arg( MAUG_CLI_SIGIL "rfh", MAUG_CLI_SIGIL_SZ + 4,
2653 "Set the screen height.", 0,
2654 (maug_cli_cb)retroflat_cli_rfh, args );
2655 maug_cleanup_if_not_ok();
2656# endif /* !RETROFLAT_NO_CLI_SZ */
2657
2658# ifdef RETROFLAT_VDP
2659 retval = maug_add_arg( MAUG_CLI_SIGIL "vdp", MAUG_CLI_SIGIL_SZ + 4,
2660 "Pass a string of args to the VDP.", 0,
2661 (maug_cli_cb)retroflat_cli_vdp, args );
2662 maug_cleanup_if_not_ok();
2663# endif /* RETROFLAT_VDP */
2664
2665 retval = maug_add_arg( MAUG_CLI_SIGIL "rfu", MAUG_CLI_SIGIL_SZ + 4,
2666 "Unlock FPS.", 0,
2667 (maug_cli_cb)retroflat_cli_u, args );
2668 maug_cleanup_if_not_ok();
2669
2670# ifndef RETROFLAT_NO_PAD
2671 retval = maug_add_arg( MAUG_CLI_SIGIL "rfj", MAUG_CLI_SIGIL_SZ + 4,
2672 "Specify joystick ID to use.", 0,
2673 (maug_cli_cb)retroflat_cli_rfj, args );
2674 maug_cleanup_if_not_ok();
2675# endif /* !RETROFLAT_NO_PAD */
2676
2677 /* Parse command line args. */
2678 retval = maug_parse_args( argc, argv );
2679 maug_cleanup_if_not_ok();
2680
2681# endif /* !RETROFLAT_NO_CLI */
2682
2683 if( 0 == args->screen_w ) {
2684 args->screen_w = RETROFLAT_DEFAULT_SCREEN_W;
2685 debug_printf( 1, "setting arg screen_w to default: %d",
2686 args->screen_w );
2687 }
2688 if( 0 == args->screen_h ) {
2689 args->screen_h = RETROFLAT_DEFAULT_SCREEN_H;
2690 debug_printf( 1, "setting arg screen_h to default: %d",
2691 args->screen_h );
2692 }
2693 if( 0 == args->screen_scale ) {
2694 args->screen_scale = 1;
2695 debug_printf( 1, "setting arg screen_scale to default: %d",
2696 args->screen_scale );
2697 }
2698 if( 0 == args->screen_colors ) {
2699 args->screen_colors = 16;
2700 debug_printf( 1, "setting arg screen_colors to default: %d",
2701 args->screen_colors );
2702 }
2703 args->joystick_id = -1;
2704
2705 if(
2707 ) {
2708 g_retroflat_state->retroflat_flags |= RETROFLAT_FLAGS_UNLOCK_FPS;
2709 }
2710
2711 debug_printf( 1, "retroflat: setting config..." );
2712
2713 /* Set the assets path. */
2714 if( NULL != args->assets_path ) {
2715 maug_mzero( g_retroflat_state->assets_path, MAUG_PATH_SZ_MAX );
2716 maug_strncpy( g_retroflat_state->assets_path,
2717 args->assets_path, MAUG_PATH_SZ_MAX - 1 );
2718 }
2719
2720# if defined( RETROFLAT_SCREENSAVER )
2721 if(
2723 (RETROFLAT_FLAGS_SCREENSAVER & args->flags)
2724 ) {
2725 g_retroflat_state->retroflat_flags |= RETROFLAT_FLAGS_SCREENSAVER;
2726 }
2727# endif /* RETROFLAT_SCREENSAVER */
2728
2729# if !defined( RETROFLAT_NO_CLI_SZ )
2730 /* Setup intended screen size. */
2731 g_retroflat_state->screen_scale = args->screen_scale;
2732 g_retroflat_state->screen_v_w = args->screen_w;
2733 g_retroflat_state->screen_v_h = args->screen_h;
2734 g_retroflat_state->screen_w = args->screen_w *
2735 g_retroflat_state->screen_scale;
2736 g_retroflat_state->screen_h = args->screen_h *
2737 g_retroflat_state->screen_scale;
2738 g_retroflat_state->screen_colors = args->screen_colors;
2739
2740 debug_printf( 3, "attempting to initialize platform with: "
2741 SIZE_T_FMT "x" SIZE_T_FMT " pixels (scaled to " SIZE_T_FMT "x" SIZE_T_FMT
2742 ") and " SIZE_T_FMT " colors",
2743 g_retroflat_state->screen_v_w, g_retroflat_state->screen_v_h,
2744 g_retroflat_state->screen_w, g_retroflat_state->screen_h,
2745 g_retroflat_state->screen_colors );
2746# endif /* !RETROFLAT_NO_CLI_SZ */
2747
2748 /* == Platform-Specific Init == */
2749
2750 retval = retroflat_init_platform( argc, argv, args );
2751 maug_cleanup_if_not_ok();
2752
2753# if defined( RETROFLAT_NO_CLI_SZ )
2754 g_retroflat_state->screen_scale = args->screen_scale;
2755 g_retroflat_state->screen_v_w = args->screen_w;
2756 g_retroflat_state->screen_v_h = args->screen_h;
2757 g_retroflat_state->screen_w = args->screen_w *
2758 g_retroflat_state->screen_scale;
2759 g_retroflat_state->screen_h = args->screen_h *
2760 g_retroflat_state->screen_scale;
2761 g_retroflat_state->screen_colors = args->screen_colors;
2762
2763 debug_printf( 3, "initialized platform with: "
2764 SIZE_T_FMT "x" SIZE_T_FMT " pixels (scaled to " SIZE_T_FMT "x" SIZE_T_FMT
2765 ") and " SIZE_T_FMT " colors",
2766 g_retroflat_state->screen_v_w, g_retroflat_state->screen_v_h,
2767 g_retroflat_state->screen_w, g_retroflat_state->screen_h,
2768 g_retroflat_state->screen_colors );
2769# endif /* RETROFLAT_NO_CLI_SZ */
2770
2771 retval = retroflat_init_input( args );
2772 maug_cleanup_if_not_ok();
2773
2774 debug_printf( 3, "screen initialized with: " SIZE_T_FMT "x" SIZE_T_FMT
2775 " pixels (scaled to " SIZE_T_FMT "x" SIZE_T_FMT
2776 ") with " SIZE_T_FMT " colors",
2777 g_retroflat_state->screen_v_w, g_retroflat_state->screen_v_h,
2778 g_retroflat_state->screen_w, g_retroflat_state->screen_h,
2779 retroflat_screen_colors() );
2780
2781 /* Setup the refresh grid, if requested, only after screen space has been
2782 * determined by the platform!
2783 */
2784 maug_cleanup_if_eq(
2785 (size_t)0, retroflat_screen_w(), SIZE_T_FMT, MERROR_GUI );
2786 maug_cleanup_if_eq(
2787 (size_t)0, retroflat_screen_h(), SIZE_T_FMT, MERROR_GUI );
2788 maug_cleanup_if_eq(
2789 (size_t)0, retroflat_screen_colors(), SIZE_T_FMT, MERROR_GUI );
2790
2791 /* This is intended as a default and can be modified by calling this macro
2792 * again later.
2793 */
2794 retroflat_viewport_set_pos_size(
2795 0, 0, retroflat_screen_w(), retroflat_screen_h() );
2796
2797#ifndef RETROFLAT_NO_VIEWPORT_REFRESH
2798 debug_printf( 1, "allocating refresh grid (%d tiles...)",
2799 g_retroflat_state->viewport.screen_tile_w *
2800 g_retroflat_state->viewport.screen_tile_h );
2801 maug_malloc_test(
2802 g_retroflat_state->viewport.refresh_grid_h,
2803 (g_retroflat_state->viewport.screen_tile_w + 2) *
2804 (g_retroflat_state->viewport.screen_tile_h + 2),
2805 sizeof( retroflat_tile_t ) );
2806#endif /* !RETROFLAT_NO_VIEWPORT_REFRESH */
2807
2808# ifdef RETROFLAT_VDP
2809# if defined( RETROFLAT_OS_UNIX )
2810 g_retroflat_state->vdp_exe = dlopen(
2811 "./" RETROFLAT_VDP_LIB_NAME ".so", RTLD_LAZY );
2812# elif defined( RETROFLAT_OS_WIN )
2813 g_retroflat_state->vdp_exe = LoadLibrary(
2814 "./" RETROFLAT_VDP_LIB_NAME ".dll" );
2815# else
2816# error "dlopen undefined!"
2817# endif /* RETROFLAT_OS_UNIX */
2818
2819 if( !(g_retroflat_state->vdp_exe) ) {
2820 error_printf( "not loading VDP" );
2821 /* Skip creating the buffer or trying to run the init proc. */
2822 goto skip_vdp;
2823 }
2824
2825 /* Create intermediary screen buffer. */
2826 debug_printf( 1, "creating VDP buffer, " SIZE_T_FMT " x " SIZE_T_FMT,
2827 g_retroflat_state->screen_v_w, g_retroflat_state->screen_v_h );
2828 g_retroflat_state->vdp_buffer =
2829 calloc( 1, sizeof( struct RETROFLAT_BITMAP ) );
2830 maug_cleanup_if_null_alloc(
2831 struct RETROFLAT_BITMAP*, g_retroflat_state->vdp_buffer );
2832 retval = retroflat_create_bitmap(
2833 g_retroflat_state->screen_v_w, g_retroflat_state->screen_v_h,
2834 g_retroflat_state->vdp_buffer, RETROFLAT_FLAGS_OPAQUE );
2835 maug_cleanup_if_not_ok();
2836
2837 debug_printf( 1, "initializing VDP..." );
2838 retval = retroflat_vdp_call( "retroflat_vdp_init" );
2839
2840skip_vdp:
2841
2842# endif /* RETROFLAT_VDP */
2843
2844# ifdef RETROFLAT_3D
2845 retro3d_platform_init();
2846# endif /* RETROFLAT_3D */
2847
2848# if !defined( RETROFLAT_NO_BLANK_INIT ) && !defined( RETROFLAT_3D )
2849 retroflat_draw_lock( NULL );
2851 NULL, RETROFLAT_COLOR_BLACK, 0, 0,
2852 retroflat_screen_w(), retroflat_screen_h(),
2854 retroflat_draw_release( NULL );
2855# endif /* !RETROFLAT_NO_BLANK_INIT */
2856
2857cleanup:
2858
2859 return retval;
2860}
2861
2862/* === */
2863
2864void retroflat_shutdown( int retval ) {
2865
2866 debug_printf( 1, "retroflat shutdown called..." );
2867
2868#ifndef RETROFLAT_NO_VIEWPORT_REFRESH
2869 if(
2870 NULL != g_retroflat_state &&
2871 (MAUG_MHANDLE)NULL != g_retroflat_state->viewport.refresh_grid_h
2872 ) {
2873 maug_mfree( g_retroflat_state->viewport.refresh_grid_h );
2874 }
2875#endif /* !RETROFLAT_NO_VIEWPORT_REFRESH */
2876
2877# if defined( RETROFLAT_VDP )
2878 if( NULL != g_retroflat_state->vdp_exe ) {
2879 retroflat_vdp_call( "retroflat_vdp_shutdown" );
2880# ifdef RETROFLAT_OS_UNIX
2881 dlclose( g_retroflat_state->vdp_exe );
2882# elif defined( RETROFLAT_OS_WIN )
2883 FreeLibrary( g_retroflat_state->vdp_exe );
2884# else
2885# error "dlclose undefined!"
2886# endif /* RETROFLAT_OS_UNIX || RETROFLAT_OS_WIN */
2887 }
2888
2889 if( NULL != g_retroflat_state->vdp_buffer ) {
2890 debug_printf( 1, "destroying VPD buffer..." );
2891 retroflat_destroy_bitmap( g_retroflat_state->vdp_buffer );
2892 free( g_retroflat_state->vdp_buffer );
2893 }
2894# endif /* RETROFLAT_VDP */
2895
2896 /* === Platform-Specific Shutdown === */
2897
2898#ifdef RETROFLAT_3D
2899 retro3d_platform_shutdown();
2900#endif /* RETROFLAT_3D */
2901
2902 retroflat_shutdown_platform( retval );
2903
2904#ifndef RETROFLAT_STATE_ON_STACK
2905 maug_munlock( g_retroflat_state_h, g_retroflat_state );
2906 maug_mfree( g_retroflat_state_h );
2907#endif /* !RETROFLAT_STATE_ON_STACK */
2908
2909}
2910
2911/* === */
2912
2913RETROFLAT_IN_KEY retroflat_repeat_input(
2914 RETROFLAT_IN_KEY key_out, struct RETROFLAT_INPUT* input,
2915 RETROFLAT_IN_KEY* prev_input, int* prev_delay
2916) {
2917
2918 /* Add a slight debounce for gamepad button repeat. */
2919 if( 0 < (*prev_delay) ) {
2920 debug_printf(
2921 RETROINPUT_TRACE_LVL,
2922 "repeat delay: %d", (*prev_delay) );
2923 (*prev_delay)--;
2924 }
2925
2926 /* If nothing else happened and repeat is enabled and a joypad button is
2927 * down, then emulate repeat for it.
2928 */
2929 if(
2930 0 == key_out &&
2932 (RETROFLAT_FLAGS_KEY_REPEAT & g_retroflat_state->retroflat_flags) &&
2933 /* There is an input to repeat. */
2934 0 != *prev_input &&
2935 /* Delay countdown reached. */
2936 0 == *prev_delay
2937 ) {
2938 key_out = *prev_input;
2939 *prev_delay = 1;
2940 debug_printf( RETROINPUT_TRACE_LVL, "repeat: %d", key_out );
2941 }
2942
2943 return key_out;
2944}
2945
2946/* === */
2947
2948# ifdef RETROFLAT_VDP
2949
2950MERROR_RETVAL retroflat_vdp_call( const char* proc_name ) {
2951 MERROR_RETVAL retval = MERROR_OK;
2953# ifdef RETROFLAT_OS_WIN
2954 char proc_name_ex[256];
2955# endif /* RETROFLAT_OS_WIN */
2956
2957 if( NULL == g_retroflat_state->vdp_exe ) {
2958 goto cleanup;
2959 }
2960
2961# ifdef RETROFLAT_OS_UNIX
2962 vdp_proc = dlsym( g_retroflat_state->vdp_exe, proc_name );
2963# elif defined( RETROFLAT_OS_WIN )
2964 /* Append a _ to the proc_name because Watcom? Windows? */
2965 maug_snprintf( proc_name_ex, 255, "%s_", proc_name );
2966 vdp_proc = (retroflat_vdp_proc_t)GetProcAddress(
2967 g_retroflat_state->vdp_exe, proc_name_ex );
2968# else
2969# error "dlsym undefined!"
2970# endif
2971 if( (retroflat_vdp_proc_t)NULL == vdp_proc ) {
2972 goto cleanup;
2973 }
2974
2975# ifdef RETROFLAT_OS_WIN
2976 retroflat_draw_lock( g_retroflat_state->vdp_buffer );
2977# endif /* RETROFLAT_OS_WIN */
2978
2979 if(
2980 /* Don't pxlock before init can set the flag! */
2981 0 == strcmp( "retroflat_vdp_flip", proc_name ) &&
2983 (RETROFLAT_VDP_FLAG_PXLOCK & g_retroflat_state->vdp_flags)
2984 ) {
2985 retroflat_vdp_lock( &(g_retroflat_state->buffer) );
2986 retroflat_vdp_lock( g_retroflat_state->vdp_buffer );
2987 }
2988
2989 retval = vdp_proc( g_retroflat_state );
2990
2991 if(
2992 0 == strcmp( "retroflat_vdp_flip", proc_name ) &&
2994 (RETROFLAT_VDP_FLAG_PXLOCK & g_retroflat_state->vdp_flags)
2995 ) {
2996 retroflat_vdp_release( &(g_retroflat_state->buffer) );
2997 retroflat_vdp_release( g_retroflat_state->vdp_buffer );
2998 }
2999
3000# ifdef RETROFLAT_OS_WIN
3001 retroflat_draw_release( g_retroflat_state->vdp_buffer );
3002# endif /* RETROFLAT_OS_WIN */
3003
3004cleanup:
3005 return retval;
3006}
3007
3008# endif /* RETROFLAT_VDP */
3009
3010/* === */
3011
3012#if 0
3013
3014void retroflat_cursor( struct RETROFLAT_BITMAP* target, uint8_t flags ) {
3015#if 0
3016 char mouse_str[11] = "";
3017
3018 maug_snprintf(
3019 mouse_str, 10, "%02d, %02d", g_retroflat_state->last_mouse_x, g_retroflat_state->last_mouse_y );
3020
3022 target, RETROFLAT_COLOR_BLACK,
3023 mouse_str, 10, NULL, 0, 0, 0 );
3025 target, RETROFLAT_COLOR_BLACK,
3026 g_retroflat_state->last_mouse_x - 5, g_retroflat_state->last_mouse_y - 5, 10, 10, 0 );
3027#endif
3028}
3029
3030#endif
3031
3032/* === */
3033
3034void maug_critical_error( const char* msg ) {
3036}
3037
3038/* === */
3039
3041 retroflat_proc_resize_t on_resize_in, void* data_in
3042) {
3043 g_retroflat_state->on_resize = on_resize_in;
3044 g_retroflat_state->on_resize_data = data_in;
3045}
3046
3047/* === */
3048
3049uint8_t retroflat_viewport_move_x_generic( int16_t x ) {
3050 int16_t new_world_x = g_retroflat_state->viewport.world_x + x;
3051
3052 /* Keep the viewport in the world arena. */
3053 if(
3054 0 <= new_world_x &&
3055 g_retroflat_state->viewport.world_w >= new_world_x +
3056 g_retroflat_state->viewport.screen_w
3057 ) {
3058 g_retroflat_state->viewport.world_x += x;
3059 g_retroflat_state->viewport.world_tile_x += x >> RETROFLAT_TILE_W_BITS;
3060 return 1;
3061 }
3062
3063 return 0;
3064}
3065
3066/* === */
3067
3068uint8_t retroflat_viewport_move_y_generic( int16_t y ) {
3069 int16_t new_world_y = g_retroflat_state->viewport.world_y + y;
3070
3071 /* Keep the viewport in the world arena. */
3072 if(
3073 0 <= new_world_y &&
3074 g_retroflat_state->viewport.world_h >= new_world_y +
3075 g_retroflat_state->viewport.screen_h
3076 ) {
3077 g_retroflat_state->viewport.world_y += y;
3078 g_retroflat_state->viewport.world_tile_y += y >> RETROFLAT_TILE_H_BITS;
3079 return 1;
3080 }
3081
3082 return 0;
3083}
3084
3085/* === */
3086
3087uint8_t retroflat_viewport_focus_generic(
3088 size_t x1, size_t y1, size_t range, size_t speed
3089) {
3090 uint8_t moved = 0,
3091 new_moved = 0;
3092 int16_t new_pt = 0;
3093
3094# define _retroflat_viewport_focus_dir( n, xy, wh, gl, pm, dir, range, speed ) \
3095 new_pt = n - retroflat_viewport_world_ ## xy(); \
3096 if( new_pt gl (retroflat_screen_ ## wh() >> 1) pm range ) { \
3097 new_moved = retroflat_viewport_move_ ## xy( \
3098 gc_retroflat_offsets8_ ## xy[RETROFLAT_DIR8_ ## dir] * speed ); \
3099 if( !moved && new_moved ) { \
3100 moved = new_moved; \
3101 } \
3102 }
3103
3104 _retroflat_viewport_focus_dir( x1, x, w, <, -, WEST, range, speed );
3105 _retroflat_viewport_focus_dir( x1, x, w, >, +, EAST, range, speed );
3106 _retroflat_viewport_focus_dir( y1, y, h, <, -, NORTH, range, speed );
3107 _retroflat_viewport_focus_dir( y1, y, h, >, +, SOUTH, range, speed );
3108
3109 return moved;
3110}
3111
3112/* === */
3113
3114#ifdef RETROFLAT_LOAD_BITMAP_GENERIC
3115
3116/* This is a generic function that uses the callback
3117 * retroflat_load_bitmap_px_cb(), which should be defined by the
3118 * platform-specific API to draw the loaded bitmap onto a native canvas.
3119 */
3120
3122 const char* filename, struct RETROFLAT_BITMAP* bmp_out, uint8_t flags
3123) {
3124 maug_path filename_path;
3125 MERROR_RETVAL retval = MERROR_OK;
3126 mfile_t bmp_file;
3127 struct MFMT_STRUCT_BMPFILE header_bmp;
3128 uint8_t bmp_flags = 0;
3129
3130 assert( NULL != bmp_out );
3131 maug_mzero( bmp_out, sizeof( struct RETROFLAT_BITMAP ) );
3132 retval = retroflat_build_filename_path(
3133 filename, RETROFLAT_BITMAP_EXT, filename_path,
3134 MAUG_PATH_SZ_MAX, flags );
3135 maug_cleanup_if_not_ok();
3136 debug_printf( 1, "retroflat: loading bitmap: %s", filename_path );
3137
3138 bmp_out->flags = flags;
3139
3140 /* Open the bitmap file. */
3141 retval = mfile_open_read( filename_path, &bmp_file );
3142 maug_cleanup_if_not_ok();
3143
3144 /* mfmt file detection system. */
3145 maug_mzero( &header_bmp, sizeof( struct MFMT_STRUCT_BMPFILE ) );
3146 header_bmp.magic[0] = 'B';
3147 header_bmp.magic[1] = 'M';
3148 header_bmp.info.sz = 40;
3149
3150 retval = mfmt_read_bmp_header(
3151 (struct MFMT_STRUCT*)&header_bmp,
3152 &bmp_file, 0, mfile_get_sz( &bmp_file ), &bmp_flags );
3153 maug_cleanup_if_not_ok();
3154
3155 retval = retroflat_create_bitmap(
3156 header_bmp.info.width, header_bmp.info.height, bmp_out, flags );
3157 maug_cleanup_if_not_ok();
3158
3159 retroflat_draw_lock( bmp_out );
3160
3161 retval = mfmt_read_bmp_px_cb(
3162 (struct MFMT_STRUCT*)&header_bmp,
3163 &bmp_file,
3164 header_bmp.px_offset,
3165 mfile_get_sz( &bmp_file ) - header_bmp.px_offset,
3166 bmp_flags,
3167 retroflat_load_bitmap_px_cb,
3168 bmp_out );
3169 maug_cleanup_if_not_ok();
3170
3171 retroflat_draw_release( bmp_out );
3172
3173cleanup:
3174
3175 mfile_close( &bmp_file );
3176
3177 return retval;
3178}
3179
3180#endif /* RETROFLAT_LOAD_BITMAP_GENERIC */
3181
3182#elif !defined( RETROVDP_C ) /* End of RETROFLT_C */
3183
3188
3189extern MAUG_CONST int16_t SEG_MCONST gc_retroflat_offsets8_x[8];
3190extern MAUG_CONST int16_t SEG_MCONST gc_retroflat_offsets8_y[8];
3191extern MAUG_CONST int16_t SEG_MCONST gc_retroflat_offsets4_x[4];
3192extern MAUG_CONST int16_t SEG_MCONST gc_retroflat_offsets4_y[4];
3193
3195
3196#define RETROFLAT_COLOR_TABLE_CONSTS( idx, name_l, name_u, r, g, b, cgac, cgad ) \
3197 extern MAUG_CONST RETROFLAT_COLOR SEG_MCONST RETROFLAT_COLOR_ ## name_u;
3198
3199RETROFLAT_COLOR_TABLE( RETROFLAT_COLOR_TABLE_CONSTS )
3200
3201extern MAUG_CONST char* SEG_MCONST gc_retroflat_color_names[];
3202
3203extern struct RETROFLAT_STATE* SEG_MGLOBAL g_retroflat_state;
3204
3205# if (defined( RETROFLAT_SOFT_SHAPES ) || defined( RETROFLAT_SOFT_LINES ) || \
3206 defined( RETROFLAT_3D ))
3207# define RETROSOFT_PRESENT
3208# endif
3209
3210# ifdef RETROFLAT_3D
3211# include <retro3dp.h>
3212# include <retro3d.h>
3213# include <retro3du.h>
3214# endif /* RETROFLAT_3D */
3215
3216# ifdef RETROSOFT_PRESENT
3217# include <retrosft.h>
3218# endif /* RETROFLAT_SOFT_SHAPES */
3219
3220/* Second retapis.h include for function bodies not needed. */
3221
3222/* Second retapii.h include for function bodies not needed. */
3223
3224#endif /* RETROFLT_C */
3225
3226#ifdef RETROFLAT_XPM
3227#include <retroxpm.h>
3228#endif /* RETROFLAT_XPM */
3229
3230#ifdef RETROVDP_C
3231
3232/* Declarations for VDP sources. */
3233
3234#endif /* RETROVDP_C */
3235 /* maug_retroflt */
3237
3238#endif /* RETROFLT_H */
3239
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
uint16_t MERROR_RETVAL
Return type indicating function returns a value from this list.
Definition merror.h:28
void maug_critical_error(const char *msg)
Display an error dialog. This is a minimal function that can be called early on (e....
MERROR_RETVAL mfmt_read_bmp_px_cb(struct MFMT_STRUCT *header, mfile_t *p_file_in, uint32_t px_offset, off_t file_sz, uint8_t flags, mfmt_read_1px_cb px_cb, void *px_cb_data)
Read mfmt_bitmap pixels and process them using a callback.
MERROR_RETVAL mfile_open_read(const maug_path filename, mfile_t *p_file)
Open a file and read it into memory or memory-map it.
#define MAUG_PATH_SZ_MAX
Maximum size allocated for asset paths.
Definition mfile.h:36
void mfile_close(mfile_t *p_file)
Close a file opened with mfile_open_read().
char maug_path[MAUG_PATH_SZ_MAX]
Path/name used to load an asset from disk or access other files.
Definition mfile.h:136
#define RETROFLAT_BITMAP_EXT
The filename suffix to be appended with a "." to filenames passed to retroflat_load_bitmap()....
Definition retroflt.h:584
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:326
#define RETROFLAT_COLOR_TABLE(f)
This macro defines all colors supported by RetroFlat for primative operations, particularly using ret...
Definition retroflt.h:307
#define RETROFLAT_VDP_ARGS_SZ_MAX
Definition retroflt.h:725
#define RETROFLAT_PATH_SEP
The valid path separator on the target platform.
Definition retroflt.h:746
#define RETROFLAT_FLAGS_LITERAL_PATH
Flag for retroflat_load_bitmap() to not use assets path.
Definition retroflt.h:385
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() or retroflat_load_bitmap() to create or load a bitmap without tran...
Definition retroflt.h:380
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:374
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.
RETROFLAT_IN_KEY retroflat_poll_input(struct RETROFLAT_INPUT *input)
Poll input devices (keyboard/mouse) and return the latest event.
void retroflat_message(uint8_t flags, const char *title, const char *format,...)
Display a message in a dialog box and/or on stderr.
#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:462
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:514
#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:501
#define RETROFLAT_FLAGS_SCREENSAVER
Flag indicating the current application is running as a screensaver.
Definition retroflt.h:438
#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:1582
void retroflat_shutdown(int retval)
Deinitialize RetroFlat and its underlying layers. This should be called once at the end of the progra...
#define RETROFLAT_FLAGS_UNLOCK_FPS
Flag indicating FPS should not be capped.
Definition retroflt.h:424
#define retroflat_heartbeat_set(len, max)
Set parameters for the RETROFLAT_STATE::heartbeat_frame.
Definition retroflt.h:1566
#define retroflat_system_task()
Platform-specific task that should be called on every iteration of the generic loop....
Definition retroflt.h:1058
void(* retroflat_loop_iter)(void *data)
Prototype for the main loop function passed to retroflat_loop().
Definition retroflt.h:765
void retroflat_resize_v()
Platform-specific function to resize virtual screen to match physical window size.
size_t retroflat_pxxy_t
Type used for surface pixel coordinates.
Definition retroflt.h:871
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....
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...
#define RETROFLAT_FLAGS_RUNNING
Flag indicating that retroflat_loop() should continue executing.
Definition retroflt.h:417
#define RETROFLAT_FLAGS_WAIT_FOR_FPS
Do not execute any more inter-frame loops until next frame.
Definition retroflt.h:444
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 RETROFLAT_FLAGS_KEY_REPEAT
Flag indicating keyboard repeat is enabled.
Definition retroflt.h:431
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_ellipse(retroflat_blit_t *target, RETROFLAT_COLOR color, int x, int y, int w, int h, uint8_t flags)
Draw an ellipsoid 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
Lower-level retargetable 3D engine wrapper.
Tools for drawing shape primatives.
Definition mfmt.h:124
Generic image description struct.
Definition mfmt.h:69
Definition retroflt.h:1035
Struct containing configuration values for a RetroFlat program.
Definition retroflt.h:1070
char * config_path
Relative path of local config file (if not using registry).
Definition retroflt.h:1080
char * assets_path
Relative path under which bitmap assets are stored.
Definition retroflt.h:1078
int screen_w
Desired screen or window width in pixels.
Definition retroflt.h:1087
int screen_h
Desired screen or window height in pixels.
Definition retroflt.h:1094
int screen_colors
Desired colors (2, 4, or 16, for now). \TODO Implement command-line argument for this....
Definition retroflt.h:1106
char * title
Title to set for the main program Window if applicable on the target platform.
Definition retroflt.h:1076
int screen_y
Desired window Y position in pixels.
Definition retroflt.h:1098
int screen_x
Desired window X position in pixels.
Definition retroflt.h:1096
Struct passed to retroflat_poll_input() to hold return data.
Definition retroflt.h:815
int mouse_y
Y-coordinate of the mouse pointer in pixels if the returned event is a mouse click.
Definition retroflt.h:825
int mouse_x
X-coordinate of the mouse pointer in pixels if the returned event is a mouse click.
Definition retroflt.h:820
Global singleton containing state for the current platform.
Definition retroflt.h:1602
char vdp_args[RETROFLAT_VDP_ARGS_SZ_MAX]
CLI args passed with -vdp to the RetroFlat VDP API.
Definition retroflt.h:1640
size_t screen_h
The screen height as seen by the system, after scaling.
Definition retroflt.h:1666
uint8_t vdp_flags
Flags set by the RetroFlat VDP API.
Definition retroflt.h:1642
size_t screen_v_w
The screen width as seen by our program, before scaling.
Definition retroflt.h:1655
size_t screen_colors
The number of colors the screen is capable of displaying.
Definition retroflt.h:1668
uint8_t retroflat_flags
maug_retroflt_flags indicating current system status.
Definition retroflt.h:1612
uint8_t heartbeat_max
When RETROFLAT_STATE::heartbeat_frame reaches this value, it will reset to 0.
Definition retroflt.h:1695
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:1627
uint8_t heartbeat_frame
Simple iteration loop that can be used to time e.g. perpetual sprite animations. Modify parameters wi...
Definition retroflt.h:1690
size_t screen_w
The screen width as seen by the system, after scaling.
Definition retroflt.h:1664
void * vdp_exe
A handle for the loaded RetroFlat VDP API module.
Definition retroflt.h:1632
RETROFLAT_COLOR_DEF palette[RETROFLAT_COLORS_SZ]
Index of available colors, initialized on platform init.
Definition retroflt.h:1702
uint16_t heartbeat_len
Number of ms to stay on current value of RETROFLAT_STATE::heartbeat_frame before incrementing....
Definition retroflt.h:1684
void * vdp_data
Pointer to data defined by the RetroFlat VDP API for its use.
Definition retroflt.h:1638
size_t screen_v_h
The screen height as seen by our program, before scaling.
Definition retroflt.h:1662
int screen_scale
Off-screen buffer bitmap.
Definition retroflt.h:1619
The viewport data struct.
Definition retroflt.h:1131
uint16_t screen_w_remainder
Difference between viewport width and screen width in pixels. Should only be retrieved through retrof...
Definition retroflt.h:1186
int16_t screen_x
X position of the viewport in real screen memory in pixels. Should only be retrieved through retrofla...
Definition retroflt.h:1137
uint16_t screen_h_remainder
Difference between viewport height and screen height in pixels. Should only be retrieved through retr...
Definition retroflt.h:1193
retroflat_tile_t * refresh_grid
A grid of tile values representing the last-drawn values on-screen.
Definition retroflt.h:1222
uint16_t screen_h
Viewport height in pixels. Should only be retrieved through retroflat_viewport_screen_w() and set thr...
Definition retroflt.h:1179
int16_t world_w
The width of the entire world tilemap in pixels. Should only be retrieved through retroflat_viewport_...
Definition retroflt.h:1161
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:1200
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:1207
int16_t world_h
The height of the entire world tilemap in pixels. Should only be retrieved through retroflat_viewport...
Definition retroflt.h:1167
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:1155
int16_t screen_y
Y position of the viewport in real screen memory in pixels. Should only be retrieved through retrofla...
Definition retroflt.h:1143
uint16_t screen_w
Viewport width in pixels. Should only be retrieved through retroflat_viewport_screen_w() and set thro...
Definition retroflt.h:1173
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:1149