maug
Quick and dirty C mini-augmentation library.
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
19typedef int16_t retroflat_tile_t;
20
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 RETROINPUT_TRACE_LVL
284# define RETROINPUT_TRACE_LVL 0
285#endif /* !RETROINPUT_TRACE_LVL */
286
287#include <stdarg.h>
288
289#include <marge.h>
290
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
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
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
373#define RETROFLAT_FLAGS_FILL 0x01
374
379#define RETROFLAT_FLAGS_OPAQUE 0x01
380
384#define RETROFLAT_FLAGS_LITERAL_PATH 0x02
385
390#define RETROFLAT_FLAGS_BITMAP_SILENT 0x04
391
398#define RETROFLAT_FLAGS_ALL_CAPS 0x02
399
406#define RETROFLAT_FLAGS_SCREEN_BUFFER 0x80
407 /* maug_retroflt_drawing */
409
416#define RETROFLAT_FLAGS_RUNNING 0x01
417
423#define RETROFLAT_FLAGS_UNLOCK_FPS 0x02
424
430#define RETROFLAT_FLAGS_KEY_REPEAT 0x04
431
437#define RETROFLAT_FLAGS_SCREENSAVER 0x08
438
443#define RETROFLAT_FLAGS_WAIT_FOR_FPS 0x20
444
455#define RETROFLAT_MSG_FLAG_TYPE_MASK 0x07
456
461#define RETROFLAT_MSG_FLAG_ERROR 0x01
462
468#define RETROFLAT_MSG_FLAG_INFO 0x02
469
475#define RETROFLAT_MSG_FLAG_WARNING 0x04
476 /* maug_retroflt_msg_api */
478
479struct RETROFLAT_STATE;
480
500#define RETROFLAT_VDP_FLAG_PXLOCK 0x01
501
514 /* maug_retroflt_vdp */
516
517typedef MERROR_RETVAL (*retroflat_proc_resize_t)(
518 uint16_t new_w, uint16_t new_h, void* data );
519
525#define RETROSND_ARGS_FLAG_LIST_DEVS 0x01
526
558#define RETROFLAT_FLAGS_LOCK 0x08
559
560#define RETROFLAT_FLAGS_SCREEN_LOCK 0x02
561
562#define RETROFLAT_FLAGS_BITMAP_RO 0x04
563
569#define RETROFLAT_INSTANCE_NULL (0)
570
575#define retroflat_instance_tile( instance ) \
576 (instance * -1)
577
582#ifndef RETROFLAT_BITMAP_EXT
583# define RETROFLAT_BITMAP_EXT "bmp"
584#endif /* !RETROFLAT_BITMAP_EXT */
585
586#ifndef RETROFLAT_OPENGL_BPP
587# define RETROFLAT_OPENGL_BPP 32
588#endif /* !RETROFLAT_OPENGL_BPP */
589
590#ifndef RETROFLAT_TILE_W
591# define RETROFLAT_TILE_W 16
592#endif /* !RETROFLAT_TILE_W */
593
594#ifndef RETROFLAT_TILE_W_BITS
595# define RETROFLAT_TILE_W_BITS 4
596#endif /* !RETROFLAT_TILE_W_BITS */
597
598#ifndef RETROFLAT_TILE_H
599# define RETROFLAT_TILE_H 16
600#endif /* !RETROFLAT_TILE_H */
601
602#ifndef RETROFLAT_TILE_H_BITS
603# define RETROFLAT_TILE_H_BITS 4
604#endif /* !RETROFLAT_TILE_H_BITS */
605
606/* Transparency background color: black by default, to match Allegro. */
607#ifndef RETROFLAT_TXP_R
613# define RETROFLAT_TXP_R 0x00
614#endif /* !RETROFLAT_TXP_R */
615
616#ifndef RETROFLAT_TXP_G
622# define RETROFLAT_TXP_G 0x00
623#endif /* !RETROFLAT_TXP_G */
624
625#ifndef RETROFLAT_TXP_B
631# define RETROFLAT_TXP_B 0x00
632#endif /* !RETROFLAT_TXP_B */
633
634#ifndef RETROFLAT_TXP_PAL_IDX
635# define RETROFLAT_TXP_PAL_IDX 0
636#endif /* !RETROFLAT_TXP_PAL_IDX */
637 /* maug_retroflt_bitmap */
639
640#ifndef RETROFLAT_DEFAULT_SCREEN_W
641# define RETROFLAT_DEFAULT_SCREEN_W 320
642#endif /* RETROFLAT_DEFAULT_SCREEN_W */
643
644#ifndef RETROFLAT_DEFAULT_SCREEN_H
645# define RETROFLAT_DEFAULT_SCREEN_H 200
646#endif /* RETROFLAT_DEFAULT_SCREEN_H */
647
648#define retroflat_on_resize( w, h ) \
649 g_retroflat_state->screen_w = w; \
650 g_retroflat_state->screen_h = h;
651
657#ifndef RETROFLAT_LINE_THICKNESS
662# define RETROFLAT_LINE_THICKNESS 1
663#endif /* !RETROFLAT_LINE_THICKNESS */
664
665#define RETROFLAT_PI 3.14159
666 /* maug_retroflt_drawing */
668
674#ifndef RETROFLAT_FPS
679# define RETROFLAT_FPS 30
680#endif /* !RETROFLAT_FPS */
681
682#define retroflat_fps_next() (1000 / RETROFLAT_FPS)
683
684#ifndef RETROFLAT_WINDOW_CLASS
689# define RETROFLAT_WINDOW_CLASS "RetroFlatWindowClass"
690#endif /* !RETROFLAT_WINDOW_CLASS */
691
692#ifndef RETROFLAT_WIN_FRAME_TIMER_ID
697# define RETROFLAT_WIN_FRAME_TIMER_ID 6001
698#endif /* !RETROFLAT_WIN_FRAME_TIMER_ID */
699
700#ifndef RETROFLAT_WIN_LOOP_TIMER_ID
705# define RETROFLAT_WIN_LOOP_TIMER_ID 6002
706#endif /* !RETROFLAT_WIN_LOOP_TIMER_ID */
707
708#ifndef RETROFLAT_MSG_MAX
713# define RETROFLAT_MSG_MAX 4096
714#endif /* !RETROFLAT_MSG_MAX */
715
716#ifndef RETROFLAT_TITLE_MAX
717# define RETROFLAT_TITLE_MAX 255
718#endif /* !RETROFLAT_TITLE_MAX */
719
720#ifndef RETROFLAT_VDP_ARGS_SZ_MAX
724# define RETROFLAT_VDP_ARGS_SZ_MAX 255
725#endif /* !RETROFLAT_VDP_ARGS_SZ_MAX */
726
727#if defined( RETROFLAT_API_SDL2 )
728# if !defined( NO_RETROFLAT_RESIZABLE )
729# define RETROFLAT_WIN_FLAGS SDL_WINDOW_RESIZABLE
730# else
731# define RETROFLAT_WIN_FLAGS 0
732# endif /* !NO_RETROFLAT_RESIZABLE */
733#endif /* RETROFLAT_API_SDL2 */
734
735#if defined( RETROFLAT_API_SDL1 )
736# define RETROFLAT_SDL_CC_FLAGS (SDL_RLEACCEL | SDL_SRCCOLORKEY)
737#elif defined( RETROFLAT_API_SDL2 )
738# define RETROFLAT_SDL_CC_FLAGS (SDL_TRUE)
739#endif /* RETROFLAT_API_SDL1 || RETROFLAT_API_SDL2 */
740
741#ifdef RETROFLAT_OS_DOS
742# define RETROFLAT_PATH_SEP '\\'
743#else
745# define RETROFLAT_PATH_SEP '/'
746#endif /* RETROFLAT_OS_DOS */
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
764typedef void (*retroflat_loop_iter)(void* data);
765
775#define retroflat_buffer_bksp( buffer, buffer_cur, buffer_sz ) \
776 if( 0 < buffer_cur ) { \
777 if( buffer_cur < buffer_sz ) { \
778 memmove( \
779 &(buffer[(buffer_cur) - 1]), \
780 &(buffer[buffer_cur]), \
781 (buffer_sz) - (buffer_cur) ); \
782 } \
783 buffer_cur--; \
784 buffer_sz--; \
785 buffer[buffer_sz] = '\0'; \
786 }
787
791#define retroflat_buffer_insert( c, buffer, buffer_cur, buffer_sz, buffer_mx ) \
792 if( buffer_sz + 1 < buffer_mx ) { \
793 if( buffer_cur < buffer_sz ) { \
794 memmove( \
795 &(buffer[(buffer_cur) + 1]), \
796 &(buffer[buffer_cur]), \
797 (buffer_sz) - (buffer_cur) ); \
798 } \
799 buffer[buffer_cur] = c; \
800 buffer_cur++; \
801 buffer_sz++; \
802 buffer[buffer_sz] = '\0'; \
803 }
804
805#define RETROFLAT_INPUT_MOD_SHIFT 0x01
806
807#define RETROFLAT_INPUT_MOD_ALT 0x02
808
809#define RETROFLAT_INPUT_MOD_CTRL 0x04
810
811#define RETROFLAT_INPUT_FORCE_UPPER 0x08
812
825 uint8_t key_flags;
826};
827 /* maug_retroflt_input */
829
837typedef int8_t retroflat_dir4_t;
838
839typedef int8_t retroflat_dir8_t;
840
841#define RETROFLAT_DIR4_NONE (-1)
842#define RETROFLAT_DIR4_NORTH 0
843#define RETROFLAT_DIR4_EAST 1
844#define RETROFLAT_DIR4_SOUTH 2
845#define RETROFLAT_DIR4_WEST 3
846
847#define RETROFLAT_DIR8_NONE (-1)
848#define RETROFLAT_DIR8_NORTH 0
849#define RETROFLAT_DIR8_EAST 2
850#define RETROFLAT_DIR8_SOUTH 4
851#define RETROFLAT_DIR8_WEST 6
852
853#define retroflat_dir4_rotate_cw( dir ) \
854 ((dir + 1) % 4)
855
856#define retroflat_dir8_reverse( dir ) \
857 ((dir + 4) % 8)
858
859#define retroflat_dir8_bounce( dir ) \
860 ((dir + 2) % 8)
861 /* maug_retroflt_dir */
863
870typedef size_t retroflat_pxxy_t;
871
872#define PXXY_FMT SIZE_T_FMT
873
874struct RETROFLAT_ARGS;
875
876#ifndef RETRO2D_TRACE_LVL
877# define RETRO2D_TRACE_LVL 0
878#endif /* !RETRO2D_TRACE_LVL */
879
880#ifndef RETROFLAT_NO_SOUND
881
910#ifndef RETROSND_TRACE_LVL
911# define RETROSND_TRACE_LVL 0
912#endif /* !RETROSND_TRACE_LVL */
913
914#ifndef RETROSND_REG_TRACE_LVL
915# define RETROSND_REG_TRACE_LVL 0
916#endif /* !RETROSND_REG_TRACE_LVL */
917
928#define RETROSND_FLAG_INIT 0x01
929 /* maug_retrosnd_flags */
931
932#define RETROSND_VOICE_BREATH 122
933
934#define RETROSND_VOICE_SEASHORE 123
935
936#define RETROSND_VOICE_BIRD_TWEET 124
937
938#define RETROSND_VOICE_PHONE_RING 125
939
940#define RETROSND_VOICE_HELICOPTER 126
941
942#define RETROSND_VOICE_APPLAUSE 127
943
948#define RETROSND_VOICE_GUNSHOT 128
949
950#define RETROSND_CHANNEL_CT 8
951
961
965void retrosnd_set_sf_bank( const char* filename_in );
966
967void retrosnd_midi_set_voice( uint8_t channel, uint8_t voice );
968
969void retrosnd_midi_set_control( uint8_t channel, uint8_t key, uint8_t val );
970
971void retrosnd_midi_note_on( uint8_t channel, uint8_t pitch, uint8_t vel );
972
973void retrosnd_midi_note_off( uint8_t channel, uint8_t pitch, uint8_t vel );
974
975MERROR_RETVAL retrosnd_midi_play_smf( const char* filename );
976
977uint8_t retrosnd_midi_is_playing_smf();
978
979void retrosnd_shutdown();
980 /* maug_retrosnd */
982
983#endif /* !RETROFLAT_NO_SOUND */
984
985/* === Platform-specific APIs === */
986
987/* The first call to these headers should just establish definitions (macros, defines, prototypes,
988 * typedefs, etc). The later call below should then define function bodies.
989 */
990#ifndef RETROFLAT_NO_SOUND
991# include <retapis.h>
992#endif /* !RETROFLAT_NO_SOUND */
993#include <retapii.h>
994
995/* === End platform-specific APIs === */
996
1002# if defined( RETROFLAT_NO_KEYBOARD )
1003# define retroflat_case_key( key, pad ) case pad:
1004# define retroflat_or_key( input, key, pad ) ((input) == (pad))
1005# elif defined( RETROFLAT_NO_PAD )
1006# define retroflat_case_key( key, pad ) case key:
1007# define retroflat_or_key( input, key, pad ) ((input) == (key))
1008# else
1016# define retroflat_case_key( key, pad ) case pad: case key:
1017# define retroflat_or_key( input, key, pad ) \
1018 (((input) == (pad)) || ((input) == (key)))
1019# endif
1020 /* maug_retroflt_input */
1022
1023/* === OS-Specific Includes and Defines === */
1024
1025#if defined( RETROFLAT_OS_WIN ) && !defined( MAUG_WINDOWS_H )
1026# include <windows.h>
1027# define MAUG_WINDOWS_H
1028#endif /* !MAUG_WINDOWS_H */
1029
1030#if defined( RETROFLAT_BMP_TEX ) || defined( DOCUMENTATION )
1031
1033 uint8_t flags;
1034 MAUG_MHANDLE bytes_h;
1035 uint8_t* bytes;
1036 uint32_t bpp;
1037 uint32_t sz;
1038 uint8_t* px;
1039 uint32_t id;
1040 size_t w;
1041 size_t h;
1042};
1043
1044#endif /* RETROFLAT_BMP_TEX */
1045
1046/* TODO: Migrate all platform-specific parts below to retapid.h. */
1047#include <retapid.h>
1048
1049#ifndef retroflat_system_task
1055# define retroflat_system_task()
1056#endif /* !retroflat_system_task */
1057
1058typedef maug_ms_t retroflat_ms_t;
1059
1060#include "retrom2d.h"
1061
1062/* === Structures === */
1063
1064/* TODO: Break the args into API-specific headers. */
1065
1068 uint8_t flags;
1073 char* title;
1078# if !defined( RETROFLAT_NO_CLI_SZ )
1079 int screen_w;
1086 int screen_scale;
1087 int joystick_id;
1088# endif /* RETROFLAT_NO_CLI_SZ */
1089 struct RETROFLAT_PLATFORM_ARGS platform;
1090# ifndef RETROFLAT_NO_SOUND
1091 struct RETROFLAT_SOUND_ARGS sound;
1092# endif /* !RETROFLAT_NO_SOUND */
1093};
1094
1118 int16_t screen_x;
1124 int16_t screen_y;
1130 int16_t world_x;
1136 int16_t world_y;
1142 int16_t world_w;
1148 int16_t world_h;
1154 uint16_t screen_w;
1160 uint16_t screen_h;
1189 int16_t world_tile_x;
1190 int16_t world_tile_y;
1191#ifndef RETROFLAT_NO_VIEWPORT_REFRESH
1192 MAUG_MHANDLE refresh_grid_h;
1204#endif /* !RETROFLAT_NO_VIEWPORT_REFRESH */
1205};
1206
1207# define retroflat_screen_colors() (g_retroflat_state->screen_colors)
1208
1209#ifndef DOCUMENTATION
1210
1211# define retroflat_viewport_world_x_generic() \
1212 (g_retroflat_state->viewport.world_x)
1213
1214# define retroflat_viewport_world_y_generic() \
1215 (g_retroflat_state->viewport.world_y)
1216
1217# define retroflat_viewport_world_tile_x_generic() \
1218 (g_retroflat_state->viewport.world_tile_x)
1219
1220# define retroflat_viewport_world_tile_y_generic() \
1221 (g_retroflat_state->viewport.world_tile_y)
1222
1223# define retroflat_viewport_world_w_generic() \
1224 (g_retroflat_state->viewport.world_w)
1225
1226# define retroflat_viewport_world_h_generic() \
1227 (g_retroflat_state->viewport.world_h)
1228
1229# define retroflat_viewport_screen_tile_w_generic() \
1230 (g_retroflat_state->viewport.screen_tile_w)
1231
1232# define retroflat_viewport_screen_tile_h_generic() \
1233 (g_retroflat_state->viewport.screen_tile_h)
1234
1235# define retroflat_viewport_screen_w_generic() \
1236 (g_retroflat_state->viewport.screen_w)
1237
1238# define retroflat_viewport_screen_h_generic() \
1239 (g_retroflat_state->viewport.screen_h)
1240
1241# define retroflat_viewport_screen_w_remainder_generic() \
1242 (g_retroflat_state->viewport.screen_w_remainder)
1243
1244# define retroflat_viewport_screen_h_remainder_generic() \
1245 (g_retroflat_state->viewport.screen_h_remainder)
1246
1247# define retroflat_viewport_set_world_generic( w, h ) \
1248 debug_printf( 1, "setting viewport size to %d x %d...", \
1249 (int16_t)(w), (int16_t)(h) ); \
1250 (g_retroflat_state->viewport.world_w) = w; \
1251 (g_retroflat_state->viewport.world_h) = h;
1252
1253# define retroflat_viewport_set_world_pos_generic( x, y ) \
1254 debug_printf( 1, "setting viewport world pos to %d, %d...", x, y ); \
1255 (g_retroflat_state->viewport.world_x) = x; \
1256 (g_retroflat_state->viewport.world_y) = y; \
1257 (g_retroflat_state->viewport.world_tile_x) = (x) >> RETROFLAT_TILE_W_BITS; \
1258 (g_retroflat_state->viewport.world_tile_y) = (y) >> RETROFLAT_TILE_H_BITS;
1259
1260# define retroflat_viewport_set_pos_size_generic( x_px, y_px, w_px, h_px ) \
1261 g_retroflat_state->viewport.screen_x = (x_px); \
1262 g_retroflat_state->viewport.screen_y = (y_px); \
1263 g_retroflat_state->viewport.screen_tile_w = \
1264 ((w_px) / RETROFLAT_TILE_W); \
1265 g_retroflat_state->viewport.screen_tile_h = \
1266 ((h_px) / RETROFLAT_TILE_H); \
1267 /* We're not adding the extra room here since this won't be used for
1268 * indexing or allocation but rather pixel detection.
1269 */ \
1270 g_retroflat_state->viewport.screen_w = \
1271 ((w_px) / RETROFLAT_TILE_W) * RETROFLAT_TILE_W; \
1272 g_retroflat_state->viewport.screen_h = \
1273 ((h_px) / RETROFLAT_TILE_H) * RETROFLAT_TILE_H; \
1274 g_retroflat_state->viewport.screen_w_remainder = \
1275 (x_px) + (w_px) - g_retroflat_state->viewport.screen_w; \
1276 g_retroflat_state->viewport.screen_h_remainder = \
1277 (y_px) + (h_px) - g_retroflat_state->viewport.screen_h;
1278
1279#ifndef RETROFLAT_NO_VIEWPORT_REFRESH
1280
1281# define retroflat_viewport_lock_refresh_generic() \
1282 if( NULL == g_retroflat_state->viewport.refresh_grid ) { \
1283 maug_mlock( \
1284 g_retroflat_state->viewport.refresh_grid_h, \
1285 g_retroflat_state->viewport.refresh_grid ); \
1286 maug_cleanup_if_null_lock( retroflat_tile_t*, \
1287 g_retroflat_state->viewport.refresh_grid ); \
1288 }
1289
1290# define retroflat_viewport_unlock_refresh_generic() \
1291 if( NULL != g_retroflat_state->viewport.refresh_grid ) { \
1292 maug_munlock( \
1293 g_retroflat_state->viewport.refresh_grid_h, \
1294 g_retroflat_state->viewport.refresh_grid ); \
1295 }
1296
1297# define _retroflat_viewport_refresh_tile_x( x_px ) \
1298 (((x_px) + RETROFLAT_TILE_W) >> RETROFLAT_TILE_W_BITS)
1299
1300# define _retroflat_viewport_refresh_tile_y( y_px ) \
1301 (((y_px) + RETROFLAT_TILE_H) >> RETROFLAT_TILE_H_BITS)
1302
1303# define retroflat_viewport_set_refresh_generic( x_px, y_px, tid ) \
1304 assert( NULL != g_retroflat_state->viewport.refresh_grid ); \
1305 if( \
1306 /* Expand the range by -1 to account for just off-screen tile. */ \
1307 -(RETROFLAT_TILE_W) <= x_px && -(RETROFLAT_TILE_H) <= y_px && \
1308 retroflat_screen_w() > x_px && \
1309 retroflat_screen_h() > y_px \
1310 ) { \
1311 assert( 0 < g_retroflat_state->viewport.screen_tile_w ); \
1312 assert( 0 <= (((y_px) + RETROFLAT_TILE_H) >> RETROFLAT_TILE_H_BITS) ); \
1313 assert( 0 <= (((x_px) + RETROFLAT_TILE_W) >> RETROFLAT_TILE_W_BITS) ); \
1314 g_retroflat_state->viewport.refresh_grid[ \
1315 /* Add +1 tile to make off-screen "-1" tile positive. */ \
1316 ((_retroflat_viewport_refresh_tile_y( y_px ) + 1) * \
1317 (g_retroflat_state->viewport.screen_tile_w + 2)) + \
1318 (_retroflat_viewport_refresh_tile_x( x_px ) + 1)] = tid; \
1319 }
1320
1321# define retroflat_viewport_tile_is_stale( x_px, y_px, tile_id ) \
1322 ((tile_id) != \
1323 g_retroflat_state->viewport.refresh_grid[ \
1324 ((_retroflat_viewport_refresh_tile_y( y_px ) + 1) * \
1325 (g_retroflat_state->viewport.screen_tile_w + 2)) + \
1326 (_retroflat_viewport_refresh_tile_x( x_px ) + 1)])
1327
1328#endif /* !RETROFLAT_NO_VIEWPORT_REFRESH */
1329
1330uint8_t retroflat_viewport_move_x_generic( int16_t x );
1331
1332uint8_t retroflat_viewport_move_y_generic( int16_t y );
1333
1334uint8_t retroflat_viewport_focus_generic(
1335 size_t x1, size_t y1, size_t range, size_t speed );
1336
1337# define retroflat_viewport_screen_x_generic( world_x ) \
1338 (g_retroflat_state->viewport.screen_x + \
1339 ((world_x) - retroflat_viewport_world_x()))
1340
1341# define retroflat_viewport_screen_y_generic( world_y ) \
1342 (g_retroflat_state->viewport.screen_y + \
1343 ((world_y) - retroflat_viewport_world_y()))
1344
1345#endif /* !DOCUMENTATION */
1346
1347#if defined( RETROFLAT_SOFT_VIEWPORT ) || defined( DOCUMENTATION )
1348
1349# ifndef RETROFLAT_NO_VIEWPORT_REFRESH
1350 /* These clamp world coordinates to tile borders to allow refresh grid to
1351 * function properly (smooth-scrolling tiles will always be in motion).
1352 */
1353
1358# define retroflat_viewport_world_x() \
1359 ((retroflat_viewport_world_x_generic() \
1360 >> RETROFLAT_TILE_W_BITS) << RETROFLAT_TILE_W_BITS)
1361
1366# define retroflat_viewport_world_y() \
1367 ((retroflat_viewport_world_y_generic() \
1368 >> RETROFLAT_TILE_H_BITS) << RETROFLAT_TILE_H_BITS)
1369# else
1370# define retroflat_viewport_world_x() retroflat_viewport_world_x_generic()
1371# define retroflat_viewport_world_y() retroflat_viewport_world_y_generic()
1372#endif /* !RETROFLAT_NO_VIEWPORT_REFRESH */
1373
1374# define retroflat_viewport_world_tile_x() \
1375 retroflat_viewport_world_tile_x_generic()
1376# define retroflat_viewport_world_tile_y() \
1377 retroflat_viewport_world_tile_y_generic()
1378
1383# define retroflat_viewport_world_w() \
1384 retroflat_viewport_world_w_generic()
1385
1390# define retroflat_viewport_world_h() \
1391 retroflat_viewport_world_h_generic()
1392
1397# define retroflat_viewport_screen_tile_w() \
1398 retroflat_viewport_screen_tile_w_generic()
1399
1404# define retroflat_viewport_screen_tile_h() \
1405 retroflat_viewport_screen_tile_h_generic()
1406
1411# define retroflat_viewport_screen_w() \
1412 retroflat_viewport_screen_w_generic()
1413
1418# define retroflat_viewport_screen_h() \
1419 retroflat_viewport_screen_h_generic()
1420
1426# define retroflat_viewport_screen_w_remainder() \
1427 retroflat_viewport_screen_w_remainder_generic()
1428
1434# define retroflat_viewport_screen_h_remainder() \
1435 retroflat_viewport_screen_h_remainder_generic()
1436
1444# define retroflat_viewport_set_world( w, h ) \
1445 retroflat_viewport_set_world_generic( w, h )
1446
1451# define retroflat_viewport_set_world_pos( x, y ) \
1452 retroflat_viewport_set_world_pos_generic( x, y )
1453
1459# define retroflat_viewport_set_pos_size( x_px, y_px, w_px, h_px ) \
1460 retroflat_viewport_set_pos_size_generic( x_px, y_px, w_px, h_px )
1461
1462#ifndef RETROFLAT_NO_VIEWPORT_REFRESH
1463
1471# define retroflat_viewport_lock_refresh() \
1472 retroflat_viewport_lock_refresh_generic()
1473
1481# define retroflat_viewport_unlock_refresh() \
1482 retroflat_viewport_unlock_refresh_generic()
1483
1495# define retroflat_viewport_set_refresh( x, y, tid ) \
1496 retroflat_viewport_set_refresh_generic( x, y, tid )
1497
1498#endif /* !RETROFLAT_NO_VIEWPORT_REFRESH */
1499
1512# define retroflat_viewport_focus( x1, y1, range, speed ) \
1513 retroflat_viewport_focus_generic( x1, y1, range, speed )
1514
1519# define retroflat_viewport_screen_x( world_x ) \
1520 retroflat_viewport_screen_x_generic( world_x )
1521
1526# define retroflat_viewport_screen_y( world_y ) \
1527 retroflat_viewport_screen_y_generic( world_y )
1528
1529# ifndef RETROFLAT_VIEWPORT_OVERRIDE_MOVE
1530# define retroflat_viewport_move_x( x ) \
1531 retroflat_viewport_move_x_generic( x )
1532
1533# define retroflat_viewport_move_y( y ) \
1534 retroflat_viewport_move_y_generic( y )
1535# endif /* !RETROFLAT_VIEWPORT_OVERRIDE_MOVE */
1536
1537#endif /* RETROFLAT_SOFT_VIEWPORT || DOCUMENTATION */
1538
1547#define retroflat_heartbeat_set( len, max ) \
1548 g_retroflat_state->heartbeat_max = max; \
1549 g_retroflat_state->heartbeat_len = len;
1550
1555#define retroflat_heartbeat() (g_retroflat_state->heartbeat_frame)
1556
1563#define retroflat_heartbeat_update() \
1564 /* Update the heartbeat animation frame. */ \
1565 if( g_retroflat_state->heartbeat_next <= retroflat_get_ms() ) { \
1566 g_retroflat_state->heartbeat_frame++; \
1567 if( \
1568 g_retroflat_state->heartbeat_frame >= \
1569 g_retroflat_state->heartbeat_max \
1570 ) { \
1571 g_retroflat_state->heartbeat_frame = 0; \
1572 } \
1573 g_retroflat_state->heartbeat_next = \
1574 retroflat_get_ms() + g_retroflat_state->heartbeat_len; \
1575 }
1576
1584 /* TODO: Set this up in the initialization function! */
1585 /* TODO: We probably need more of these. */
1586 size_t sz;
1587 size_t offset_pal;
1588 size_t offset_tex_pal;
1589
1590 void* loop_data;
1591 MERROR_RETVAL retval;
1594 char config_path[MAUG_PATH_SZ_MAX + 1];
1595 char assets_path[MAUG_PATH_SZ_MAX + 1];
1597 struct RETROFLAT_BITMAP buffer;
1598 int scale;
1599
1600# if defined( RETROFLAT_VDP ) || defined( DOCUMENTATION ) || \
1601defined( RETROVDP_C )
1606 struct RETROFLAT_BITMAP* vdp_buffer;
1607# ifdef RETROFLAT_OS_WIN
1608 HMODULE vdp_exe;
1609# else
1611 void* vdp_exe;
1612# endif /* RETROFLAT_OS_WIN */
1621 uint8_t vdp_flags;
1622# endif /* RETROFLAT_VDP || DOCUMENTATION || RETROVDP_C */
1623
1624 /* These are used by VDP so should be standardized/not put in plat-spec! */
1625
1626 struct RETROFLAT_VIEWPORT viewport;
1627
1643 size_t screen_w;
1645 size_t screen_h;
1648
1649 /* WARNING: The VDP requires the state specifier to be the same size
1650 * as the one it was compiled for! Do not modify above here!
1651 */
1652
1653 /* TODO: Put these in a platform-specific struct of some kind to maintain
1654 * consistent state struct size for VDP?
1655 */
1656
1657 retroflat_ms_t heartbeat_next;
1675
1676 retroflat_proc_resize_t on_resize;
1677 void* on_resize_data;
1678
1679#ifndef RETROFLAT_BMP_TEX
1681 RETROFLAT_COLOR_DEF palette[RETROFLAT_COLORS_SZ];
1682#endif /* !RETROFLAT_BMP_TEX */
1683
1684 retroflat_loop_iter loop_iter;
1685 retroflat_loop_iter frame_iter;
1686
1687 struct RETROFLAT_PLATFORM platform;
1688
1689# if defined( RETROFLAT_BMP_TEX )
1690 /* This allows native colors to be used for things like glColor3fv while
1691 * these colors are used to manipulate textures passed through
1692 * retroflat_bitmap_*().
1693 */
1694 RETROFLAT_TEX_COLOR_DEF tex_palette[RETROFLAT_COLORS_SZ];
1695# endif /* RETROFLAT_BMP_TEX */
1696
1697 struct RETROFLAT_INPUT_STATE input;
1698
1699# ifndef RETROFLAT_NO_SOUND
1700 struct RETROFLAT_SOUND_STATE sound;
1701# endif /* !RETROFLAT_NO_SOUND */
1702};
1703
1704/* === Translation Module === */
1705
1706/* Declare the prototypes so that internal functions can call each other. */
1707
1708# ifdef retroflat_loop
1709MERROR_RETVAL retroflat_loop_generic(
1710 retroflat_loop_iter frame_iter, retroflat_loop_iter loop_iter, void* data );
1711# else
1718 retroflat_loop_iter frame_iter, retroflat_loop_iter loop_iter, void* data );
1719# endif /* retroflat_loop */
1720
1721MERROR_RETVAL retroflat_build_filename_path(
1722 const char* filename_in, const char* filename_ext,
1723 char* buffer_out, size_t buffer_out_sz, uint8_t flags );
1724
1737 uint8_t flags, const char* title, const char* format, ... );
1738 /* maug_retroflt_msg_api */
1740
1748MERROR_RETVAL retroflat_init( int argc, char* argv[], struct RETROFLAT_ARGS* args );
1749
1756void retroflat_shutdown( int retval );
1757
1758# if defined( RETROFLAT_VDP ) || defined( DOCUMENTATION )
1767MERROR_RETVAL retroflat_vdp_call( const char* proc_name );
1768 /* maug_retroflt_vdp */
1770# endif /* RETROFLAT_VDP || DOCUMENTATION */
1771
1772RETROFLAT_IN_KEY retroflat_repeat_input(
1773 RETROFLAT_IN_KEY key_out, struct RETROFLAT_INPUT* input,
1774 RETROFLAT_IN_KEY* prev_input, int* prev_delay );
1775
1776void retroflat_set_title( const char* format, ... );
1777
1778retroflat_ms_t retroflat_get_ms();
1779
1780uint32_t retroflat_get_rand();
1781
1782# if !defined( RETROFLAT_NO_KEYBOARD )
1783char retroflat_vk_to_ascii( RETROFLAT_IN_KEY k, uint8_t flags );
1784# endif /* !RETROFLAT_NO_KEYBOARD */
1785
1802 const char* filename, struct RETROFLAT_BITMAP* bmp_out, uint8_t flags );
1803
1804MERROR_RETVAL retroflat_create_bitmap(
1805 size_t w, size_t h, struct RETROFLAT_BITMAP* bmp_out, uint8_t flags );
1806
1812void retroflat_destroy_bitmap( struct RETROFLAT_BITMAP* bitmap );
1813
1830 struct RETROFLAT_BITMAP* target, struct RETROFLAT_BITMAP* src,
1831 size_t s_x, size_t s_y, int16_t d_x, int16_t d_y, size_t w, size_t h,
1832 int16_t instance );
1833
1841#define retroflat_constrain_px( x, y, bmp, retact ) \
1842 if( \
1843 x >= retroflat_bitmap_w( bmp ) || y >= retroflat_bitmap_h( bmp ) \
1844 ) { retact; }
1845 /* maug_retroflt_bitmap */
1847
1862MERROR_RETVAL retroflat_draw_lock( struct RETROFLAT_BITMAP* bmp );
1863
1864MERROR_RETVAL retroflat_draw_release( struct RETROFLAT_BITMAP* bmp );
1865
1866void retroflat_px(
1867 struct RETROFLAT_BITMAP* target, const RETROFLAT_COLOR color,
1868 size_t x, size_t y, uint8_t flags );
1869
1870#ifdef RETROFLAT_SOFT_SHAPES
1871# ifdef RETROFLAT_OPENGL
1872/* Make sure we're not passing NULL to openGL texture drawers... they can't
1873 * handle that!
1874 */
1875# define retroflat_rect( t, c, x, y, w, h, f ) \
1876 assert( NULL != t ); \
1877 retrosoft_rect( t, c, x, y, w, h, f );
1878# define retroflat_ellipse( t, c, x, y, w, h, f ) \
1879 assert( NULL != t ); \
1880 retrosoft_ellipse( t, c, x, y, w, h, f )
1881# else
1882# define retroflat_rect( t, c, x, y, w, h, f ) \
1883 retrosoft_rect( t, c, x, y, w, h, f )
1884# define retroflat_ellipse( t, c, x, y, w, h, f ) \
1885 retrosoft_ellipse( t, c, x, y, w, h, f )
1886# endif /* RETROFLAT_3D */
1887#else
1888
1900 struct RETROFLAT_BITMAP* target, const RETROFLAT_COLOR color,
1901 int16_t x, int16_t y, int16_t w, int16_t h, uint8_t flags );
1902
1914 struct RETROFLAT_BITMAP* target, const RETROFLAT_COLOR color,
1915 int16_t x, int16_t y, int16_t w, int16_t h, uint8_t flags );
1916
1917#endif /* RETROFLAT_SOFT_SHAPES */
1918
1919#ifdef RETROFLAT_SOFT_LINES
1920# define retroflat_line( t, c, x1, y1, x2, y2, f ) \
1921 retrosoft_line( t, c, x1, y1, x2, y2, f )
1922#else
1923
1936 struct RETROFLAT_BITMAP* target, const RETROFLAT_COLOR color,
1937 int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint8_t flags );
1938
1939#endif /* RETROFLAT_SOFT_LINES */
1940
1941void retroflat_cursor( struct RETROFLAT_BITMAP* target, uint8_t flags );
1942
1956 struct RETROFLAT_BITMAP* target, const char* str, size_t str_sz,
1957 const char* font_str, size_t* w_out, size_t* h_out, uint8_t flags );
1958
1977 struct RETROFLAT_BITMAP* target, const RETROFLAT_COLOR color,
1978 const char* str, int str_sz, const char* font_str, int16_t x_orig, int16_t y_orig,
1979 uint8_t flags );
1980
1981/* TODO: Documentation! */
1982void retroflat_get_palette( uint8_t idx, uint32_t* rgb );
1983
1984MERROR_RETVAL retroflat_set_palette( uint8_t idx, uint32_t rgb );
1985 /* maug_retroflt_bitmap */
1987
1998 retroflat_proc_resize_t on_resize_in, void* data_in );
1999
2005
2016RETROFLAT_IN_KEY retroflat_poll_input( struct RETROFLAT_INPUT* input );
2017 /* maug_retroflt_input */
2019
2020#ifdef RETROFLT_C
2021
2022MAUG_CONST int16_t SEG_MCONST gc_retroflat_offsets8_x[8] =
2023 { 0, 1, 1, 1, 0, -1, -1, -1 };
2024MAUG_CONST int16_t SEG_MCONST gc_retroflat_offsets8_y[8] =
2025 { -1, -1, 0, 1, 1, 1, 0, -1 };
2026
2027MAUG_CONST int16_t SEG_MCONST gc_retroflat_offsets4_x[4] =
2028 { 0, 1, 0, -1 };
2029MAUG_CONST int16_t SEG_MCONST gc_retroflat_offsets4_y[4] =
2030 { -1, 0, 1, 0 };
2031
2032MAUG_MHANDLE SEG_MGLOBAL g_retroflat_state_h = (MAUG_MHANDLE)NULL;
2033struct RETROFLAT_STATE* SEG_MGLOBAL g_retroflat_state = NULL;
2034
2035# define RETROFLAT_COLOR_TABLE_CONSTS( idx, name_l, name_u, r, g, b, cgac, cgad ) \
2036 MAUG_CONST RETROFLAT_COLOR SEG_MCONST RETROFLAT_COLOR_ ## name_u = idx;
2037
2038RETROFLAT_COLOR_TABLE( RETROFLAT_COLOR_TABLE_CONSTS )
2039
2040# define RETROFLAT_COLOR_TABLE_NAMES( idx, name_l, name_u, r, g, b, cgac, cgad ) \
2041 #name_u,
2042
2043MAUG_CONST char* SEG_MCONST gc_retroflat_color_names[] = {
2044 RETROFLAT_COLOR_TABLE( RETROFLAT_COLOR_TABLE_NAMES )
2045};
2046
2047/* Callback table is down below, after the statically-defined callbacks. */
2048
2049/* === Function Definitions === */
2050
2051MERROR_RETVAL retroflat_build_filename_path(
2052 const char* filename_in, const char* filename_ext,
2053 char* buffer_out, size_t buffer_out_sz, uint8_t flags
2054) {
2055 MERROR_RETVAL retval = MERROR_OK;
2056
2057 assert( 1 < buffer_out_sz );
2058
2059 /* Build the path to the bitmap. */
2060 maug_mzero( buffer_out, buffer_out_sz );
2061 if(
2064 ) {
2065 /* TODO: Error checking. */
2066 maug_snprintf( buffer_out, buffer_out_sz - 1, "%s", filename_in );
2067 } else {
2068 /* TODO: Error checking. */
2069 maug_snprintf( buffer_out, buffer_out_sz - 1, "%s%c%s.%s",
2070 g_retroflat_state->assets_path, RETROFLAT_PATH_SEP,
2071 filename_in, filename_ext );
2072 }
2073
2074 return retval;
2075}
2076
2077/* === */
2078
2079# if (defined( RETROFLAT_SOFT_SHAPES ) || defined( RETROFLAT_SOFT_LINES ) || \
2080 defined( RETROFLAT_3D ))
2081/* RETROSOFT_PRESENT is different from RETROFLAT_SOFT_SHAPES in that it only
2082 * indicates that the retrosoft library is loaded, not that it is the default
2083 * for drawing primatives!
2084 */
2085# define RETROSOFT_PRESENT
2086# endif
2087
2088# if defined( RETROFLAT_3D )
2089# if !defined( MAUG_NO_AUTO_C )
2090# define RETRO3D_C
2091# define RETRO3DP_C
2092# define RETROFP_C
2093# endif /* MAUG_NO_AUTO_C */
2094# include <retro3dp.h>
2095# include <retro3d.h>
2096# include <retro3du.h>
2097# include <retapi3.h>
2098# endif /* RETROFLAT_3D */
2099
2100# ifdef RETROSOFT_PRESENT
2101# if !defined( MAUG_NO_AUTO_C )
2102# define RETROSFT_C
2103# endif /* !MAUG_NO_AUTO_C */
2104# define RETROSOFT_PRESENT
2105# include <retrosft.h>
2106# endif /* RETROFLAT_SOFT_SHAPES */
2107
2108# ifndef RETROFLAT_NO_SOUND
2109# include <retapis.h>
2110# endif /* !RETROFLAT_NO_SOUND */
2111
2112# include <retapii.h>
2113
2114# if defined( RETROFLAT_VDP ) && defined( RETROFLAT_OS_UNIX )
2115# include <dlfcn.h>
2116# endif
2117
2118/* Still inside RETROFLT_C! */
2119
2120/* === */
2121
2122#ifndef RETROFLAT_NO_GENERIC_LOOP
2123
2124MERROR_RETVAL retroflat_loop_generic(
2125 retroflat_loop_iter frame_iter, retroflat_loop_iter loop_iter, void* data
2126) {
2127 MERROR_RETVAL retval = MERROR_OK;
2128 retroflat_ms_t next = 0,
2129 now = 0;
2130
2131 g_retroflat_state->loop_iter = (retroflat_loop_iter)loop_iter;
2132 g_retroflat_state->loop_data = (void*)data;
2133 g_retroflat_state->frame_iter = (retroflat_loop_iter)frame_iter;
2134
2135 if(
2137 (g_retroflat_state->retroflat_flags & RETROFLAT_FLAGS_RUNNING)
2138 ) {
2139 /* Main loop is already running, so we're just changing the iter call
2140 * and leaving!
2141 */
2142 debug_printf( 1, "main loop already running!" );
2143 goto cleanup;
2144 }
2145
2146 g_retroflat_state->retroflat_flags |= RETROFLAT_FLAGS_RUNNING;
2147 do {
2149
2150 if(
2151 /* Not waiting for the next frame? */
2153 (RETROFLAT_FLAGS_WAIT_FOR_FPS & g_retroflat_state->retroflat_flags) &&
2154 /* Inter-frame loop present? */
2155 NULL != g_retroflat_state->loop_iter
2156 ) {
2157 /* Run the loop iter as many times as possible. */
2158 g_retroflat_state->loop_iter( g_retroflat_state->loop_data );
2159 }
2160 if(
2162 (RETROFLAT_FLAGS_UNLOCK_FPS & g_retroflat_state->retroflat_flags) &&
2163 retroflat_get_ms() < next
2164 ) {
2165 /* Sleep/low power for a bit. */
2166 continue;
2167 }
2168
2170
2171 if( NULL != g_retroflat_state->frame_iter ) {
2172 /* Run the frame iterator once per FPS tick. */
2173 g_retroflat_state->frame_iter( g_retroflat_state->loop_data );
2174 }
2175 /* Reset wait-for-frame flag AFTER frame callback. */
2176 g_retroflat_state->retroflat_flags &= ~RETROFLAT_FLAGS_WAIT_FOR_FPS;
2177 now = retroflat_get_ms();
2178 if( now + retroflat_fps_next() > now ) {
2179 next = now + retroflat_fps_next();
2180 } else {
2181 /* Rollover protection. */
2182 /* TODO: Add difference from now/next to 0 here. */
2183 next = 0;
2184 }
2185 } while(
2187 (RETROFLAT_FLAGS_RUNNING & g_retroflat_state->retroflat_flags)
2188 );
2189 retval = g_retroflat_state->retval;
2190
2191cleanup:
2192
2193 /* This should be set by retroflat_quit(). */
2194 return retval;
2195}
2196
2197#endif /* !RETROFLAT_NO_GENERIC_LOOP */
2198
2199/* === */
2200
2201# if !defined( RETROFLAT_NO_KEYBOARD )
2202
2203char retroflat_vk_to_ascii( RETROFLAT_IN_KEY k, uint8_t flags ) {
2204 char c = 0;
2205 char offset_lower = 0;
2206
2207 if( RETROFLAT_INPUT_MOD_SHIFT != (RETROFLAT_INPUT_MOD_SHIFT & flags) ) {
2208 /* Shift is *not* being held down. */
2209
2210 if( RETROFLAT_KEY_A <= k && RETROFLAT_KEY_Z >= k ) {
2211 if(
2212 RETROFLAT_INPUT_FORCE_UPPER !=
2213 (RETROFLAT_INPUT_FORCE_UPPER & flags)
2214 ) {
2215 /* Key is alphabetical and we're not forcing uppercase. */
2216 offset_lower = 0x20;
2217 }
2218 } else {
2219 offset_lower = 1;
2220 }
2221 }
2222
2223 switch( k ) {
2224 case RETROFLAT_KEY_A: c = 0x41 + offset_lower; break;
2225 case RETROFLAT_KEY_B: c = 0x42 + offset_lower; break;
2226 case RETROFLAT_KEY_C: c = 0x43 + offset_lower; break;
2227 case RETROFLAT_KEY_D: c = 0x44 + offset_lower; break;
2228 case RETROFLAT_KEY_E: c = 0x45 + offset_lower; break;
2229 case RETROFLAT_KEY_F: c = 0x46 + offset_lower; break;
2230 case RETROFLAT_KEY_G: c = 0x47 + offset_lower; break;
2231 case RETROFLAT_KEY_H: c = 0x48 + offset_lower; break;
2232 case RETROFLAT_KEY_I: c = 0x49 + offset_lower; break;
2233 case RETROFLAT_KEY_J: c = 0x4a + offset_lower; break;
2234 case RETROFLAT_KEY_K: c = 0x4b + offset_lower; break;
2235 case RETROFLAT_KEY_L: c = 0x4c + offset_lower; break;
2236 case RETROFLAT_KEY_M: c = 0x4d + offset_lower; break;
2237 case RETROFLAT_KEY_N: c = 0x4e + offset_lower; break;
2238 case RETROFLAT_KEY_O: c = 0x4f + offset_lower; break;
2239 case RETROFLAT_KEY_P: c = 0x50 + offset_lower; break;
2240 case RETROFLAT_KEY_Q: c = 0x51 + offset_lower; break;
2241 case RETROFLAT_KEY_R: c = 0x52 + offset_lower; break;
2242 case RETROFLAT_KEY_S: c = 0x53 + offset_lower; break;
2243 case RETROFLAT_KEY_T: c = 0x54 + offset_lower; break;
2244 case RETROFLAT_KEY_U: c = 0x55 + offset_lower; break;
2245 case RETROFLAT_KEY_V: c = 0x56 + offset_lower; break;
2246 case RETROFLAT_KEY_W: c = 0x57 + offset_lower; break;
2247 case RETROFLAT_KEY_X: c = 0x58 + offset_lower; break;
2248 case RETROFLAT_KEY_Y: c = 0x59 + offset_lower; break;
2249 case RETROFLAT_KEY_Z: c = 0x60 + offset_lower; break;
2250 case RETROFLAT_KEY_0: c = offset_lower ? 0x30 : ')'; break;
2251 case RETROFLAT_KEY_1: c = offset_lower ? 0x31 : '!'; break;
2252 case RETROFLAT_KEY_2: c = offset_lower ? 0x32 : '@'; break;
2253 case RETROFLAT_KEY_3: c = offset_lower ? 0x33 : '#'; break;
2254 case RETROFLAT_KEY_4: c = offset_lower ? 0x34 : '$'; break;
2255 case RETROFLAT_KEY_5: c = offset_lower ? 0x35 : '%'; break;
2256 case RETROFLAT_KEY_6: c = offset_lower ? 0x36 : '^'; break;
2257 case RETROFLAT_KEY_7: c = offset_lower ? 0x37 : '&'; break;
2258 case RETROFLAT_KEY_8: c = offset_lower ? 0x38 : '*'; break;
2259 case RETROFLAT_KEY_9: c = offset_lower ? 0x39 : '('; break;
2260 case RETROFLAT_KEY_SPACE: c = ' '; break;
2261 case RETROFLAT_KEY_BKSP: c = 0x08; break;
2262 case RETROFLAT_KEY_ENTER: c = '\n'; break;
2263 case RETROFLAT_KEY_SEMICOLON: c = offset_lower ? ';' : ':'; break;
2264 case RETROFLAT_KEY_DASH: c = offset_lower ? '-' : '_'; break;
2265 case RETROFLAT_KEY_SLASH: c = offset_lower ? '/' : '?'; break;
2266 case RETROFLAT_KEY_PERIOD: c = offset_lower ? '.' : '>'; break;
2267 case RETROFLAT_KEY_COMMA: c = offset_lower ? ',' : '<'; break;
2268 case RETROFLAT_KEY_QUOTE: c = offset_lower ? '\'' : '"'; break;
2269 case RETROFLAT_KEY_EQUALS: c = offset_lower ? '=' : '+'; break;
2270 case RETROFLAT_KEY_BACKSLASH: c = offset_lower ? '\\' : '|'; break;
2271 case RETROFLAT_KEY_BRACKETL: c = offset_lower ? '[' : '{'; break;
2272 case RETROFLAT_KEY_BRACKETR: c = offset_lower ? ']' : '}'; break;
2273#ifndef RETROFLAT_API_PC_BIOS
2274 /* TODO: FIXME in DOS! */
2275 case RETROFLAT_KEY_GRAVE: c = offset_lower ? '`' : '~'; break;
2276#endif /* !RETROFLAT_API_PC_BIOS */
2277 }
2278
2279 debug_printf( RETROINPUT_TRACE_LVL, "0x%02x", c );
2280
2281 return c;
2282}
2283
2284#endif /* !RETROFLAT_NO_KEYBOARD */
2285
2286/* === */
2287
2288/* TODO: Migrate all platform-specific parts below to retapif.h. */
2289#include <retapif.h>
2290
2291/* === */
2292
2293# ifndef RETROFLAT_NO_CLI
2294
2295# if !defined( RETROFLAT_NO_SOUND ) && defined( RETROSND_ARGS )
2296
2297static MERROR_RETVAL retrosnd_cli_rsl(
2298 const char* arg, ssize_t arg_c, struct RETROFLAT_ARGS* args
2299) {
2300 if(
2301 0 <= arg_c &&
2302 0 == strncmp( MAUG_CLI_SIGIL "rsl", arg, MAUG_CLI_SIGIL_SZ + 4 )
2303 ) {
2304 args->sound.flags |= RETROSND_ARGS_FLAG_LIST_DEVS;
2305 }
2306 return MERROR_OK;
2307}
2308
2309# endif /* !RETROFLAT_NO_SOUND && RETROSND_ARGS */
2310
2311# if !defined( RETROFLAT_API_PC_BIOS ) && !defined( RETROFLAT_NO_CLI_SZ )
2312
2313static MERROR_RETVAL retroflat_cli_rfs(
2314 const char* arg, ssize_t arg_c, struct RETROFLAT_ARGS* args
2315) {
2316 if( 1 < arg_c ) {
2317 args->screen_scale = atoi( arg );
2318 debug_printf( 3, "screen scale arg set to: %d", args->screen_scale );
2319 }
2320 return MERROR_OK;
2321}
2322
2323static MERROR_RETVAL retroflat_cli_rfx(
2324 const char* arg, ssize_t arg_c, struct RETROFLAT_ARGS* args
2325) {
2326 if( 0 > arg_c ) {
2327 if( 0 == args->screen_w ) {
2328 args->screen_x = 0;
2329 }
2330 } else if(
2331 0 == strncmp( MAUG_CLI_SIGIL "rfx", arg, MAUG_CLI_SIGIL_SZ + 4 )
2332 ) {
2333 /* The next arg must be the new var. */
2334 } else {
2335 args->screen_x = atoi( arg );
2336 }
2337 return MERROR_OK;
2338}
2339
2340static MERROR_RETVAL retroflat_cli_rfy(
2341 const char* arg, ssize_t arg_c, struct RETROFLAT_ARGS* args
2342) {
2343 if( 0 > arg_c ) {
2344 if( 0 == args->screen_h ) {
2345 args->screen_y = 0;
2346 }
2347 } else if(
2348 0 == strncmp( MAUG_CLI_SIGIL "rfy", arg, MAUG_CLI_SIGIL_SZ + 4 )
2349 ) {
2350 /* The next arg must be the new var. */
2351 } else {
2352 args->screen_y = atoi( arg );
2353 }
2354 return MERROR_OK;
2355}
2356
2357static MERROR_RETVAL retroflat_cli_rfw(
2358 const char* arg, ssize_t arg_c, struct RETROFLAT_ARGS* args
2359) {
2360 if( 0 > arg_c ) {
2361 if( 0 == args->screen_w ) {
2362 args->screen_w = RETROFLAT_DEFAULT_SCREEN_W;
2363 debug_printf( 1, "setting arg screen_w to default %d:",
2364 args->screen_w );
2365 }
2366 } else if(
2367 0 == strncmp( MAUG_CLI_SIGIL "rfw", arg, MAUG_CLI_SIGIL_SZ + 4 )
2368 ) {
2369 /* The next arg must be the new var. */
2370 } else {
2371 args->screen_w = atoi( arg );
2372 debug_printf( 1, "setting arg screen_w to: %d",
2373 args->screen_w );
2374 }
2375 return MERROR_OK;
2376}
2377
2378static MERROR_RETVAL retroflat_cli_rfh(
2379 const char* arg, ssize_t arg_c, struct RETROFLAT_ARGS* args
2380) {
2381 if( 0 > arg_c ) {
2382 if( 0 == args->screen_h ) {
2383 args->screen_h = RETROFLAT_DEFAULT_SCREEN_H;
2384 debug_printf( 1, "setting arg screen_h to default: %d",
2385 args->screen_h );
2386 }
2387 } else if(
2388 0 == strncmp( MAUG_CLI_SIGIL "rfh", arg, MAUG_CLI_SIGIL_SZ + 4 )
2389 ) {
2390 /* The next arg must be the new var. */
2391 } else {
2392 args->screen_h = atoi( arg );
2393 debug_printf( 1, "setting arg screen_h to: %d",
2394 args->screen_h );
2395 }
2396 return MERROR_OK;
2397}
2398
2399# endif /* !RETROFLAT_API_PC_BIOS && !RETROFLAT_NO_CLI_SZ */
2400
2401# ifdef RETROFLAT_VDP
2402static MERROR_RETVAL retroflat_cli_vdp(
2403 const char* arg, ssize_t arg_c, struct RETROFLAT_ARGS* args
2404) {
2405 if( 0 == strncmp( MAUG_CLI_SIGIL "vdp", arg, MAUG_CLI_SIGIL_SZ + 4 ) ) {
2406 /* Next arg is VDP args str. */
2407 } else {
2408 maug_strncpy( g_retroflat_state->vdp_args, arg, RETROFLAT_VDP_ARGS_SZ_MAX );
2409 debug_printf( 1, "VDP args: %s", g_retroflat_state->vdp_args );
2410 }
2411 return MERROR_OK;
2412}
2413# endif /* RETROFLAT_VDP */
2414
2415static MERROR_RETVAL retroflat_cli_u(
2416 const char* arg, ssize_t arg_c, struct RETROFLAT_ARGS* args
2417) {
2418 if( 0 > arg_c ) {
2419 args->flags &= ~RETROFLAT_FLAGS_UNLOCK_FPS;
2420 } else if(
2421 0 == strncmp( MAUG_CLI_SIGIL "rfu", arg, MAUG_CLI_SIGIL_SZ + 4 )
2422 ) {
2423 debug_printf( 1, "unlocking FPS..." );
2424 args->flags |= RETROFLAT_FLAGS_UNLOCK_FPS;
2425 }
2426 return MERROR_OK;
2427}
2428
2429# ifndef RETROFLAT_NO_PAD
2430
2431static MERROR_RETVAL retroflat_cli_rfj(
2432 const char* arg, ssize_t arg_c, struct RETROFLAT_ARGS* args
2433) {
2434 if( 0 > arg_c ) {
2435 args->joystick_id = -1;
2436 debug_printf( 1, "setting arg joystick_id to default: %d",
2437 args->joystick_id );
2438 } else if(
2439 0 == strncmp( MAUG_CLI_SIGIL "rfj", arg, MAUG_CLI_SIGIL_SZ + 4 )
2440 ) {
2441 /* The next arg must be the new var. */
2442 } else {
2443 args->joystick_id = atoi( arg );
2444 debug_printf( 1, "setting arg joystick_id to: %d",
2445 args->joystick_id );
2446 }
2447 return MERROR_OK;
2448}
2449
2450# endif /* !RETROFLAT_NO_PAD */
2451
2452#endif /* !RETROFLAT_NO_CLI */
2453
2454/* === */
2455
2456/* Still inside RETROFLT_C! */
2457
2459 int argc, char* argv[], struct RETROFLAT_ARGS* args
2460) {
2461
2462 /* = Declare Init Vars = */
2463
2464 MERROR_RETVAL retval = 0;
2465
2466 /* = Begin Init Procedure = */
2467
2468# ifdef RETROFLAT_COMMIT_HASH
2469 debug_printf( 1, "retroflat commit: " RETROFLAT_COMMIT_HASH );
2470# endif /* RETROFLAT_COMMIT_HASH */
2471
2472 debug_printf( 1, "retroflat: initializing..." );
2473
2474 /* System sanity checks. */
2475 assert( 2 <= sizeof( MERROR_RETVAL ) );
2476 assert( 4 == sizeof( uint32_t ) );
2477 assert( 4 == sizeof( int32_t ) );
2478 assert( 2 == sizeof( uint16_t ) );
2479 assert( 2 == sizeof( int16_t ) );
2480 assert( 1 == sizeof( uint8_t ) );
2481 assert( 1 == sizeof( int8_t ) );
2482 assert( NULL != args );
2483 assert( 1 << RETROFLAT_TILE_W_BITS == RETROFLAT_TILE_W );
2484 assert( 1 << RETROFLAT_TILE_H_BITS == RETROFLAT_TILE_H );
2485
2486 debug_printf( 1, "initializing drawing routines..." );
2487
2488 /* Initialize 2D callbacks depending on if we're in 2D or 3D mode.
2489 * Please see retrom2d.h for more information.
2490 */
2491# if defined( RETROFLAT_BMP_TEX )
2492 retroflat_2d_px = (retroflat_px_cb)retro3d_texture_px;
2493 retroflat_2d_line = (retroflat_line_cb)retrosoft_line;
2494 retroflat_2d_rect = (retroflat_rect_cb)retrosoft_rect;
2495 retroflat_2d_blit_bitmap = (retroflat_blit_bitmap_cb)retro3d_texture_blit;
2496 retroflat_2d_load_bitmap =
2497 (retroflat_load_bitmap_cb)retro3d_texture_load_bitmap;
2498 retroflat_2d_create_bitmap =
2499 (retroflat_create_bitmap_cb)retro3d_texture_create;
2500# else
2501 retroflat_2d_px = (retroflat_px_cb)retroflat_px;
2502# ifdef RETROFLAT_SOFT_SHAPES
2503 /* TODO: Work retrosoft routines to use retroflat_blit_t */
2504 retroflat_2d_line = (retroflat_line_cb)retrosoft_line;
2505 retroflat_2d_rect = (retroflat_rect_cb)retrosoft_rect;
2506# else
2507 retroflat_2d_line = (retroflat_line_cb)retroflat_line;
2508 retroflat_2d_rect = (retroflat_rect_cb)retroflat_rect;
2509# endif /* RETROFLAT_SOFT_SHAPES */
2510 retroflat_2d_blit_bitmap = (retroflat_blit_bitmap_cb)retroflat_blit_bitmap;
2511 retroflat_2d_load_bitmap = (retroflat_load_bitmap_cb)retroflat_load_bitmap;
2512 retroflat_2d_create_bitmap =
2513 (retroflat_create_bitmap_cb)retroflat_create_bitmap;
2514# endif /* RETROFLAT_BMP_TEX */
2515
2516 debug_printf( 1, "retroflat: MFIX_PRECISION: %f", MFIX_PRECISION );
2517
2518 debug_printf( 1, "retroflat: allocating state (" SIZE_T_FMT " bytes)...",
2519 sizeof( struct RETROFLAT_STATE ) );
2520
2521 debug_printf( 1, "retroflat: size_t is (" SIZE_T_FMT " bytes)...",
2522 sizeof( size_t ) );
2523
2524 debug_printf( 1, "retroflat: ssize_t is (" SIZE_T_FMT " bytes)...",
2525 sizeof( ssize_t ) );
2526
2527 debug_printf( 1, "retroflat: off_t is (" SIZE_T_FMT " bytes)...",
2528 sizeof( off_t ) );
2529
2530 debug_printf( 1, "initializing global state..." );
2531
2532 g_retroflat_state_h = maug_malloc( 1, sizeof( struct RETROFLAT_STATE ) );
2533 if( (MAUG_MHANDLE)NULL == g_retroflat_state_h ) {
2535 "Error", "Could not allocate global state!" );
2536 retval = MERROR_ALLOC;
2537 goto cleanup;
2538 }
2539
2540 maug_mlock( g_retroflat_state_h, g_retroflat_state );
2541 if( NULL == g_retroflat_state ) {
2543 "Error", "Could not lock global state!" );
2544 retval = MERROR_ALLOC;
2545 goto cleanup;
2546 }
2547 maug_mzero( g_retroflat_state, sizeof( struct RETROFLAT_STATE ) );
2548
2549 retroflat_heartbeat_set( 1000, 2 );
2550
2551 debug_printf( 1, "initializing platform filesystem..." );
2552 retval = mfile_plt_init();
2553 maug_cleanup_if_not_ok();
2554
2555# ifndef RETROFLAT_NO_CLI
2556
2557 debug_printf( 1, "retroflat: parsing args..." );
2558
2559 /* All platforms: add command-line args based on compile definitons. */
2560
2561 retval = maug_add_arg(
2562 MAUG_CLI_SIGIL "h", MAUG_CLI_SIGIL_SZ + 2, "Display command-line help",
2563 26, maug_cli_h, NULL );
2564
2565# if !defined( RETROFLAT_NO_SOUND ) && defined( RETROSND_ARGS )
2566 retval = maug_add_arg( MAUG_CLI_SIGIL "rsd", MAUG_CLI_SIGIL_SZ + 4,
2567 "Select MIDI device", 0, (maug_cli_cb)retrosnd_cli_rsd, args );
2568 maug_cleanup_if_not_ok();
2569 retval = maug_add_arg( MAUG_CLI_SIGIL "rsl", MAUG_CLI_SIGIL_SZ + 4,
2570 "List MIDI devices", 0, (maug_cli_cb)retrosnd_cli_rsl, args );
2571 maug_cleanup_if_not_ok();
2572# endif /* !RETROFLAT_NO_SOUND && RETROSND_ARGS */
2573
2574# ifdef RETROFLAT_SCREENSAVER
2575 retval = maug_add_arg( MAUG_CLI_SIGIL "p", MAUG_CLI_SIGIL_SZ + 2,
2576 "Preview screensaver", 0, (maug_cli_cb)retroflat_cli_p, args );
2577 maug_cleanup_if_not_ok();
2578 retval = maug_add_arg( MAUG_CLI_SIGIL "s", MAUG_CLI_SIGIL_SZ + 2,
2579 "Launch screensaver", 0, (maug_cli_cb)retroflat_cli_s, args );
2580 maug_cleanup_if_not_ok();
2581# endif /* RETROFLAT_SCREENSAVER */
2582
2583# ifdef RETROFLAT_API_PC_BIOS
2584 retval = maug_add_arg( MAUG_CLI_SIGIL "rfm", MAUG_CLI_SIGIL_SZ + 4,
2585 "Set the screen mode.", 0,
2586 (maug_cli_cb)retroflat_cli_rfm, args );
2587 maug_cleanup_if_not_ok();
2588# elif !defined( RETROFLAT_NO_CLI_SZ )
2589 retval = maug_add_arg( MAUG_CLI_SIGIL "rfs", MAUG_CLI_SIGIL_SZ + 4,
2590 "Set screen scale factor.", 0,
2591 (maug_cli_cb)retroflat_cli_rfs, args );
2592 maug_cleanup_if_not_ok();
2593 retval = maug_add_arg( MAUG_CLI_SIGIL "rfx", MAUG_CLI_SIGIL_SZ + 4,
2594 "Set the screen X position.", 0,
2595 (maug_cli_cb)retroflat_cli_rfx, args );
2596 maug_cleanup_if_not_ok();
2597 retval = maug_add_arg( MAUG_CLI_SIGIL "rfy", MAUG_CLI_SIGIL_SZ + 4,
2598 "Set the screen Y position.", 0,
2599 (maug_cli_cb)retroflat_cli_rfy, args );
2600 maug_cleanup_if_not_ok();
2601 retval = maug_add_arg( MAUG_CLI_SIGIL "rfw", MAUG_CLI_SIGIL_SZ + 4,
2602 "Set the screen width.", 0,
2603 (maug_cli_cb)retroflat_cli_rfw, args );
2604 maug_cleanup_if_not_ok();
2605 retval = maug_add_arg( MAUG_CLI_SIGIL "rfh", MAUG_CLI_SIGIL_SZ + 4,
2606 "Set the screen height.", 0,
2607 (maug_cli_cb)retroflat_cli_rfh, args );
2608 maug_cleanup_if_not_ok();
2609# endif /* !RETROFLAT_NO_CLI_SZ */
2610
2611# ifdef RETROFLAT_VDP
2612 retval = maug_add_arg( MAUG_CLI_SIGIL "vdp", MAUG_CLI_SIGIL_SZ + 4,
2613 "Pass a string of args to the VDP.", 0,
2614 (maug_cli_cb)retroflat_cli_vdp, args );
2615 maug_cleanup_if_not_ok();
2616# endif /* RETROFLAT_VDP */
2617
2618 retval = maug_add_arg( MAUG_CLI_SIGIL "rfu", MAUG_CLI_SIGIL_SZ + 4,
2619 "Unlock FPS.", 0,
2620 (maug_cli_cb)retroflat_cli_u, args );
2621 maug_cleanup_if_not_ok();
2622
2623# ifndef RETROFLAT_NO_PAD
2624 retval = maug_add_arg( MAUG_CLI_SIGIL "rfj", MAUG_CLI_SIGIL_SZ + 4,
2625 "Specify joystick ID to use.", 0,
2626 (maug_cli_cb)retroflat_cli_rfj, args );
2627 maug_cleanup_if_not_ok();
2628# endif /* !RETROFLAT_NO_PAD */
2629
2630 /* Parse command line args. */
2631 retval = maug_parse_args( argc, argv );
2632 maug_cleanup_if_not_ok();
2633
2634# else
2635
2636 if( 0 == args->screen_w ) {
2637 args->screen_w = RETROFLAT_DEFAULT_SCREEN_W;
2638 debug_printf( 1, "setting arg screen_w to default: %d",
2639 args->screen_w );
2640 }
2641 if( 0 == args->screen_h ) {
2642 args->screen_h = RETROFLAT_DEFAULT_SCREEN_H;
2643 debug_printf( 1, "setting arg screen_h to default: %d",
2644 args->screen_h );
2645 }
2646 args->joystick_id = -1;
2647
2648# endif /* !RETROFLAT_NO_CLI */
2649
2650# if !defined( RETROFLAT_NO_CLI_SZ )
2651 /* Set default, so that this is never zero, to avoid division by zero. */
2652 if( 0 < args->screen_scale ) {
2653 debug_printf( 1, "setting screen scale to: %d", args->screen_scale );
2654 g_retroflat_state->scale = args->screen_scale;
2655 } else {
2656 debug_printf( 1, "setting screen scale to default: 1" );
2657 g_retroflat_state->scale = 1;
2658 }
2659# endif /* !RETROFLAT_NO_CLI_SZ */
2660
2661 if(
2663 ) {
2664 g_retroflat_state->retroflat_flags |= RETROFLAT_FLAGS_UNLOCK_FPS;
2665 }
2666
2667 debug_printf( 1, "retroflat: setting config..." );
2668
2669 /* Set the assets path. */
2670 maug_mzero( g_retroflat_state->assets_path, MAUG_PATH_SZ_MAX + 1 );
2671 if( NULL != args->assets_path ) {
2672 maug_strncpy( g_retroflat_state->assets_path,
2674 }
2675
2676# if defined( RETROFLAT_SCREENSAVER )
2677 if(
2679 (RETROFLAT_FLAGS_SCREENSAVER & args->flags)
2680 ) {
2681 g_retroflat_state->retroflat_flags |= RETROFLAT_FLAGS_SCREENSAVER;
2682 }
2683# endif /* RETROFLAT_SCREENSAVER */
2684
2685# if !defined( RETROFLAT_NO_CLI_SZ )
2686 /* Setup intended screen size. */
2687 g_retroflat_state->screen_v_w = args->screen_w;
2688 g_retroflat_state->screen_v_h = args->screen_h;
2689 g_retroflat_state->screen_w = args->screen_w *
2690 g_retroflat_state->scale;
2691 g_retroflat_state->screen_h = args->screen_h *
2692 g_retroflat_state->scale;
2693# endif /* RETROFLAT_NO_CLI_SZ */
2694
2695 /* == Platform-Specific Init == */
2696
2697 debug_printf( 3, "attempting to initialize platform with: "
2698 SIZE_T_FMT "x" SIZE_T_FMT " pixels (scaled to " SIZE_T_FMT "x" SIZE_T_FMT
2699 ")",
2700 g_retroflat_state->screen_v_w, g_retroflat_state->screen_v_h,
2701 g_retroflat_state->screen_w, g_retroflat_state->screen_h );
2702
2703 retval = retroflat_init_platform( argc, argv, args );
2704 maug_cleanup_if_not_ok();
2705
2706 retval = retroflat_init_input( args );
2707 maug_cleanup_if_not_ok();
2708
2709 debug_printf( 3, "screen initialized with: " SIZE_T_FMT "x" SIZE_T_FMT
2710 " pixels (scaled to " SIZE_T_FMT "x" SIZE_T_FMT
2711 ") with " SIZE_T_FMT " colors",
2712 g_retroflat_state->screen_v_w, g_retroflat_state->screen_v_h,
2713 g_retroflat_state->screen_w, g_retroflat_state->screen_h,
2714 retroflat_screen_colors() );
2715
2716 /* Setup the refresh grid, if requested, only after screen space has been
2717 * determined by the platform!
2718 */
2719 maug_cleanup_if_eq(
2720 (size_t)0, retroflat_screen_w(), SIZE_T_FMT, MERROR_GUI );
2721 maug_cleanup_if_eq(
2722 (size_t)0, retroflat_screen_h(), SIZE_T_FMT, MERROR_GUI );
2723 maug_cleanup_if_eq(
2724 (size_t)0, retroflat_screen_colors(), SIZE_T_FMT, MERROR_GUI );
2725
2726 /* This is intended as a default and can be modified by calling this macro
2727 * again later.
2728 */
2730 0, 0, retroflat_screen_w(), retroflat_screen_h() );
2731
2732#ifndef RETROFLAT_NO_VIEWPORT_REFRESH
2733 debug_printf( 1, "allocating refresh grid (%d tiles...)",
2734 g_retroflat_state->viewport.screen_tile_w *
2735 g_retroflat_state->viewport.screen_tile_h );
2736 g_retroflat_state->viewport.refresh_grid_h = maug_malloc(
2737 (g_retroflat_state->viewport.screen_tile_w + 2) *
2738 (g_retroflat_state->viewport.screen_tile_h + 2),
2739 sizeof( retroflat_tile_t ) );
2740 maug_cleanup_if_null_alloc( MAUG_MHANDLE,
2741 g_retroflat_state->viewport.refresh_grid_h );
2742#endif /* !RETROFLAT_NO_VIEWPORT_REFRESH */
2743
2744# ifdef RETROFLAT_VDP
2745# if defined( RETROFLAT_OS_UNIX )
2746 g_retroflat_state->vdp_exe = dlopen(
2747 "./" RETROFLAT_VDP_LIB_NAME ".so", RTLD_LAZY );
2748# elif defined( RETROFLAT_OS_WIN )
2749 g_retroflat_state->vdp_exe = LoadLibrary(
2750 "./" RETROFLAT_VDP_LIB_NAME ".dll" );
2751# else
2752# error "dlopen undefined!"
2753# endif /* RETROFLAT_OS_UNIX */
2754
2755 if( !(g_retroflat_state->vdp_exe) ) {
2756 error_printf( "not loading VDP" );
2757 /* Skip creating the buffer or trying to run the init proc. */
2758 goto skip_vdp;
2759 }
2760
2761 /* Create intermediary screen buffer. */
2762 debug_printf( 1, "creating VDP buffer, " SIZE_T_FMT " x " SIZE_T_FMT,
2763 g_retroflat_state->screen_v_w, g_retroflat_state->screen_v_h );
2764 g_retroflat_state->vdp_buffer =
2765 calloc( 1, sizeof( struct RETROFLAT_BITMAP ) );
2766 maug_cleanup_if_null_alloc(
2767 struct RETROFLAT_BITMAP*, g_retroflat_state->vdp_buffer );
2768 retval = retroflat_create_bitmap(
2769 g_retroflat_state->screen_v_w, g_retroflat_state->screen_v_h,
2770 g_retroflat_state->vdp_buffer, RETROFLAT_FLAGS_OPAQUE );
2771 maug_cleanup_if_not_ok();
2772
2773 debug_printf( 1, "initializing VDP..." );
2774 retval = retroflat_vdp_call( "retroflat_vdp_init" );
2775
2776skip_vdp:
2777
2778# endif /* RETROFLAT_VDP */
2779
2780# ifdef RETROFLAT_3D
2781 retro3d_platform_init();
2782# endif /* RETROFLAT_3D */
2783
2784# if !defined( RETROFLAT_NO_BLANK_INIT ) && !defined( RETROFLAT_3D )
2785 retroflat_draw_lock( NULL );
2787 NULL, RETROFLAT_COLOR_BLACK, 0, 0,
2788 retroflat_screen_w(), retroflat_screen_h(),
2790 retroflat_draw_release( NULL );
2791# endif /* !RETROFLAT_NO_BLANK_INIT */
2792
2793cleanup:
2794
2795 return retval;
2796}
2797
2798/* === */
2799
2800void retroflat_shutdown( int retval ) {
2801
2802 debug_printf( 1, "retroflat shutdown called..." );
2803
2804#ifndef RETROFLAT_NO_VIEWPORT_REFRESH
2805 if(
2806 NULL != g_retroflat_state &&
2807 (MAUG_MHANDLE)NULL != g_retroflat_state->viewport.refresh_grid_h
2808 ) {
2809 maug_mfree( g_retroflat_state->viewport.refresh_grid_h );
2810 }
2811#endif /* !RETROFLAT_NO_VIEWPORT_REFRESH */
2812
2813# if defined( RETROFLAT_VDP )
2814 if( NULL != g_retroflat_state->vdp_exe ) {
2815 retroflat_vdp_call( "retroflat_vdp_shutdown" );
2816# ifdef RETROFLAT_OS_UNIX
2817 dlclose( g_retroflat_state->vdp_exe );
2818# elif defined( RETROFLAT_OS_WIN )
2819 FreeLibrary( g_retroflat_state->vdp_exe );
2820# else
2821# error "dlclose undefined!"
2822# endif /* RETROFLAT_OS_UNIX || RETROFLAT_OS_WIN */
2823 }
2824
2825 if( NULL != g_retroflat_state->vdp_buffer ) {
2826 debug_printf( 1, "destroying VPD buffer..." );
2827 retroflat_destroy_bitmap( g_retroflat_state->vdp_buffer );
2828 free( g_retroflat_state->vdp_buffer );
2829 }
2830# endif /* RETROFLAT_VDP */
2831
2832 /* === Platform-Specific Shutdown === */
2833
2834#ifdef RETROFLAT_3D
2835 retro3d_platform_shutdown();
2836#endif /* RETROFLAT_3D */
2837
2838 retroflat_shutdown_platform( retval );
2839
2840 maug_munlock( g_retroflat_state_h, g_retroflat_state );
2841 maug_mfree( g_retroflat_state_h );
2842
2843}
2844
2845/* === */
2846
2847RETROFLAT_IN_KEY retroflat_repeat_input(
2848 RETROFLAT_IN_KEY key_out, struct RETROFLAT_INPUT* input,
2849 RETROFLAT_IN_KEY* prev_input, int* prev_delay
2850) {
2851
2852 /* Add a slight debounce for gamepad button repeat. */
2853 if( 0 < (*prev_delay) ) {
2854 debug_printf(
2855 RETROINPUT_TRACE_LVL,
2856 "repeat delay: %d", (*prev_delay) );
2857 (*prev_delay)--;
2858 }
2859
2860 /* If nothing else happened and repeat is enabled and a joypad button is
2861 * down, then emulate repeat for it.
2862 */
2863 if(
2864 0 == key_out &&
2866 (RETROFLAT_FLAGS_KEY_REPEAT & g_retroflat_state->retroflat_flags) &&
2867 /* There is an input to repeat. */
2868 0 != *prev_input &&
2869 /* Delay countdown reached. */
2870 0 == *prev_delay
2871 ) {
2872 key_out = *prev_input;
2873 *prev_delay = 1;
2874 debug_printf( RETROINPUT_TRACE_LVL, "repeat: %d", key_out );
2875 }
2876
2877 return key_out;
2878}
2879
2880/* === */
2881
2882# ifdef RETROFLAT_VDP
2883
2884MERROR_RETVAL retroflat_vdp_call( const char* proc_name ) {
2885 MERROR_RETVAL retval = MERROR_OK;
2887# ifdef RETROFLAT_OS_WIN
2888 char proc_name_ex[256];
2889# endif /* RETROFLAT_OS_WIN */
2890
2891 if( NULL == g_retroflat_state->vdp_exe ) {
2892 goto cleanup;
2893 }
2894
2895# ifdef RETROFLAT_OS_UNIX
2896 vdp_proc = dlsym( g_retroflat_state->vdp_exe, proc_name );
2897# elif defined( RETROFLAT_OS_WIN )
2898 /* Append a _ to the proc_name because Watcom? Windows? */
2899 maug_snprintf( proc_name_ex, 255, "%s_", proc_name );
2900 vdp_proc = (retroflat_vdp_proc_t)GetProcAddress(
2901 g_retroflat_state->vdp_exe, proc_name_ex );
2902# else
2903# error "dlsym undefined!"
2904# endif
2905 if( (retroflat_vdp_proc_t)NULL == vdp_proc ) {
2906 goto cleanup;
2907 }
2908
2909# ifdef RETROFLAT_OS_WIN
2910 retroflat_draw_lock( g_retroflat_state->vdp_buffer );
2911# endif /* RETROFLAT_OS_WIN */
2912
2913 if(
2914 /* Don't pxlock before init can set the flag! */
2915 0 == strcmp( "retroflat_vdp_flip", proc_name ) &&
2917 (RETROFLAT_VDP_FLAG_PXLOCK & g_retroflat_state->vdp_flags)
2918 ) {
2919 retroflat_vdp_lock( &(g_retroflat_state->buffer) );
2920 retroflat_vdp_lock( g_retroflat_state->vdp_buffer );
2921 }
2922
2923 retval = vdp_proc( g_retroflat_state );
2924
2925 if(
2926 0 == strcmp( "retroflat_vdp_flip", proc_name ) &&
2928 (RETROFLAT_VDP_FLAG_PXLOCK & g_retroflat_state->vdp_flags)
2929 ) {
2930 retroflat_vdp_release( &(g_retroflat_state->buffer) );
2931 retroflat_vdp_release( g_retroflat_state->vdp_buffer );
2932 }
2933
2934# ifdef RETROFLAT_OS_WIN
2935 retroflat_draw_release( g_retroflat_state->vdp_buffer );
2936# endif /* RETROFLAT_OS_WIN */
2937
2938cleanup:
2939 return retval;
2940}
2941
2942# endif /* RETROFLAT_VDP */
2943
2944/* === */
2945
2946#if 0
2947
2948void retroflat_cursor( struct RETROFLAT_BITMAP* target, uint8_t flags ) {
2949#if 0
2950 char mouse_str[11] = "";
2951
2952 maug_snprintf(
2953 mouse_str, 10, "%02d, %02d", g_retroflat_state->last_mouse_x, g_retroflat_state->last_mouse_y );
2954
2956 target, RETROFLAT_COLOR_BLACK,
2957 mouse_str, 10, NULL, 0, 0, 0 );
2959 target, RETROFLAT_COLOR_BLACK,
2960 g_retroflat_state->last_mouse_x - 5, g_retroflat_state->last_mouse_y - 5, 10, 10, 0 );
2961#endif
2962}
2963
2964#endif
2965
2966/* === */
2967
2969 retroflat_proc_resize_t on_resize_in, void* data_in
2970) {
2971 g_retroflat_state->on_resize = on_resize_in;
2972 g_retroflat_state->on_resize_data = data_in;
2973}
2974
2975/* === */
2976
2977uint8_t retroflat_viewport_move_x_generic( int16_t x ) {
2978 int16_t new_world_x = g_retroflat_state->viewport.world_x + x;
2979
2980 /* Keep the viewport in the world arena. */
2981 if(
2982 0 <= new_world_x &&
2983 g_retroflat_state->viewport.world_w >= new_world_x +
2984 g_retroflat_state->viewport.screen_w
2985 ) {
2986 g_retroflat_state->viewport.world_x += x;
2987 g_retroflat_state->viewport.world_tile_x += x >> RETROFLAT_TILE_W_BITS;
2988 return 1;
2989 }
2990
2991 return 0;
2992}
2993
2994/* === */
2995
2996uint8_t retroflat_viewport_move_y_generic( int16_t y ) {
2997 int16_t new_world_y = g_retroflat_state->viewport.world_y + y;
2998
2999 /* Keep the viewport in the world arena. */
3000 if(
3001 0 <= new_world_y &&
3002 g_retroflat_state->viewport.world_h >= new_world_y +
3003 g_retroflat_state->viewport.screen_h
3004 ) {
3005 g_retroflat_state->viewport.world_y += y;
3006 g_retroflat_state->viewport.world_tile_y += y >> RETROFLAT_TILE_H_BITS;
3007 return 1;
3008 }
3009
3010 return 0;
3011}
3012
3013/* === */
3014
3015uint8_t retroflat_viewport_focus_generic(
3016 size_t x1, size_t y1, size_t range, size_t speed
3017) {
3018 uint8_t moved = 0,
3019 new_moved = 0;
3020 int16_t new_pt = 0;
3021
3022# define _retroflat_viewport_focus_dir( n, xy, wh, gl, pm, dir, range, speed ) \
3023 new_pt = n - retroflat_viewport_world_ ## xy(); \
3024 if( new_pt gl (retroflat_screen_ ## wh() >> 1) pm range ) { \
3025 new_moved = retroflat_viewport_move_ ## xy( \
3026 gc_retroflat_offsets8_ ## xy[RETROFLAT_DIR8_ ## dir] * speed ); \
3027 if( !moved && new_moved ) { \
3028 moved = new_moved; \
3029 } \
3030 }
3031
3032 _retroflat_viewport_focus_dir( x1, x, w, <, -, WEST, range, speed );
3033 _retroflat_viewport_focus_dir( x1, x, w, >, +, EAST, range, speed );
3034 _retroflat_viewport_focus_dir( y1, y, h, <, -, NORTH, range, speed );
3035 _retroflat_viewport_focus_dir( y1, y, h, >, +, SOUTH, range, speed );
3036
3037 return moved;
3038}
3039
3040/* === */
3041
3042#ifdef RETROFLAT_LOAD_BITMAP_GENERIC
3043
3044/* This is a generic function that uses the callback
3045 * retroflat_load_bitmap_px_cb(), which should be defined by the
3046 * platform-specific API to draw the loaded bitmap onto a native canvas.
3047 */
3048
3050 const char* filename, struct RETROFLAT_BITMAP* bmp_out, uint8_t flags
3051) {
3052 char filename_path[MAUG_PATH_SZ_MAX + 1];
3053 MERROR_RETVAL retval = MERROR_OK;
3054 mfile_t bmp_file;
3055 struct MFMT_STRUCT_BMPFILE header_bmp;
3056 uint8_t bmp_flags = 0;
3057
3058 assert( NULL != bmp_out );
3059 maug_mzero( bmp_out, sizeof( struct RETROFLAT_BITMAP ) );
3060 retval = retroflat_build_filename_path(
3061 filename, RETROFLAT_BITMAP_EXT, filename_path,
3062 MAUG_PATH_SZ_MAX + 1, flags );
3063 maug_cleanup_if_not_ok();
3064 debug_printf( 1, "retroflat: loading bitmap: %s", filename_path );
3065
3066 bmp_out->flags = flags;
3067
3068 /* Open the bitmap file. */
3069 retval = mfile_open_read( filename_path, &bmp_file );
3070 maug_cleanup_if_not_ok();
3071
3072 /* mfmt file detection system. */
3073 maug_mzero( &header_bmp, sizeof( struct MFMT_STRUCT_BMPFILE ) );
3074 header_bmp.magic[0] = 'B';
3075 header_bmp.magic[1] = 'M';
3076 header_bmp.info.sz = 40;
3077
3078 retval = mfmt_read_bmp_header(
3079 (struct MFMT_STRUCT*)&header_bmp,
3080 &bmp_file, 0, mfile_get_sz( &bmp_file ), &bmp_flags );
3081 maug_cleanup_if_not_ok();
3082
3083 retval = retroflat_create_bitmap(
3084 header_bmp.info.width, header_bmp.info.height, bmp_out, flags );
3085 maug_cleanup_if_not_ok();
3086
3087 retroflat_draw_lock( bmp_out );
3088
3089 retval = mfmt_read_bmp_px_cb(
3090 (struct MFMT_STRUCT*)&header_bmp,
3091 &bmp_file,
3092 header_bmp.px_offset,
3093 mfile_get_sz( &bmp_file ) - header_bmp.px_offset,
3094 bmp_flags,
3095 retroflat_load_bitmap_px_cb,
3096 bmp_out );
3097 maug_cleanup_if_not_ok();
3098
3099 retroflat_draw_release( bmp_out );
3100
3101cleanup:
3102
3103 mfile_close( &bmp_file );
3104
3105 return retval;
3106}
3107
3108#endif /* RETROFLAT_LOAD_BITMAP_GENERIC */
3109
3110#elif !defined( RETROVDP_C ) /* End of RETROFLT_C */
3111
3117extern MAUG_CONST int16_t SEG_MCONST gc_retroflat_offsets8_x[8];
3118extern MAUG_CONST int16_t SEG_MCONST gc_retroflat_offsets8_y[8];
3119extern MAUG_CONST int16_t SEG_MCONST gc_retroflat_offsets4_x[4];
3120extern MAUG_CONST int16_t SEG_MCONST gc_retroflat_offsets4_y[4];
3121
3124#define RETROFLAT_COLOR_TABLE_CONSTS( idx, name_l, name_u, r, g, b, cgac, cgad ) \
3125 extern MAUG_CONST RETROFLAT_COLOR SEG_MCONST RETROFLAT_COLOR_ ## name_u;
3126
3127RETROFLAT_COLOR_TABLE( RETROFLAT_COLOR_TABLE_CONSTS )
3128
3129extern MAUG_CONST char* SEG_MCONST gc_retroflat_color_names[];
3130
3131extern struct RETROFLAT_STATE* SEG_MGLOBAL g_retroflat_state;
3132
3133# if (defined( RETROFLAT_SOFT_SHAPES ) || defined( RETROFLAT_SOFT_LINES ) || \
3134 defined( RETROFLAT_3D ))
3135# define RETROSOFT_PRESENT
3136# endif
3137
3138# ifdef RETROFLAT_3D
3139# include <retro3dp.h>
3140# include <retro3d.h>
3141# include <retro3du.h>
3142# endif /* RETROFLAT_3D */
3143
3144# ifdef RETROSOFT_PRESENT
3145# include <retrosft.h>
3146# endif /* RETROFLAT_SOFT_SHAPES */
3147
3148/* Second retapis.h include for function bodies not needed. */
3149
3150/* Second retapii.h include for function bodies not needed. */
3151
3152#endif /* RETROFLT_C */
3153
3154#ifdef RETROFLAT_XPM
3155#include <retroxpm.h>
3156#endif /* RETROFLAT_XPM */
3157
3158#ifdef RETROVDP_C
3159
3160/* Declarations for VDP sources. */
3161
3162#endif /* RETROVDP_C */
3163 /* maug_retroflt */
3165
3166#endif /* RETROFLT_H */
3167
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:19
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.
#define MAUG_PATH_SZ_MAX
Maximum size allocated for asset paths.
Definition: mfile.h:35
MERROR_RETVAL mfile_open_read(const char *filename, mfile_t *p_file)
Open a file and read it into memory or memory-map it.
void mfile_close(mfile_t *p_file)
Close a file opened with mfile_open_read().
#define RETROFLAT_BITMAP_EXT
The filename suffix to be appended with a "." to filenames passed to retroflat_load_bitmap()....
Definition: retroflt.h:583
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:724
#define RETROFLAT_PATH_SEP
The valid path separator on the target platform.
Definition: retroflt.h:745
#define RETROFLAT_FLAGS_LITERAL_PATH
Flag for retroflat_load_bitmap() to not use assets path.
Definition: retroflt.h:384
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: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.
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:461
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:513
#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:500
void retroflat_shutdown(int retval)
Deinitialize RetroFlat and its underlying layers. This should be called once at the end of the progra...
#define retroflat_system_task()
Platform-specific task that should be called on every iteration of the generic loop....
Definition: retroflt.h:1055
void(* retroflat_loop_iter)(void *data)
Prototype for the main loop function passed to retroflat_loop().
Definition: retroflt.h:764
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:870
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...
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).
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
Lower-level retargetable 3D engine wrapper.
Tools for drawing shape primatives.
Definition: mfile.h:194
Definition: mfmt.h:124
Generic image description struct.
Definition: mfmt.h:69
Definition: retroflt.h:1032
Struct containing configuration values for a RetroFlat program.
Definition: retroflt.h:1067
char * config_path
Relative path of local config file (if not using registry).
Definition: retroflt.h:1077
char * assets_path
Relative path under which bitmap assets are stored.
Definition: retroflt.h:1075
int screen_h
Desired screen or window height in pixels.
Definition: retroflt.h:1081
char * title
Title to set for the main program Window if applicable on the target platform.
Definition: retroflt.h:1073
int screen_y
Desired window Y position in pixels.
Definition: retroflt.h:1085
int screen_x
Desired window X position in pixels.
Definition: retroflt.h:1083
Struct passed to retroflat_poll_input() to hold return data.
Definition: retroflt.h:814
int mouse_y
Y-coordinate of the mouse pointer in pixels if the returned event is a mouse click.
Definition: retroflt.h:824
int mouse_x
X-coordinate of the mouse pointer in pixels if the returned event is a mouse click.
Definition: retroflt.h:819
Global singleton containing state for the current platform.
Definition: retroflt.h:1583
#define RETROFLAT_FLAGS_SCREENSAVER
Flag indicating the current application is running as a screensaver.
Definition: retroflt.h:437
char vdp_args[RETROFLAT_VDP_ARGS_SZ_MAX]
CLI args passed with -vdp to the RetroFlat VDP API.
Definition: retroflt.h:1619
size_t screen_h
The screen height as seen by the system, after scaling.
Definition: retroflt.h:1645
uint8_t vdp_flags
Flags set by the RetroFlat VDP API.
Definition: retroflt.h:1621
#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:1563
size_t screen_v_w
The screen width as seen by our program, before scaling.
Definition: retroflt.h:1634
size_t screen_colors
The number of colors the screen is capable of displaying.
Definition: retroflt.h:1647
uint8_t retroflat_flags
maug_retroflt_flags indicating current system status.
Definition: retroflt.h:1593
#define RETROFLAT_FLAGS_UNLOCK_FPS
Flag indicating FPS should not be capped.
Definition: retroflt.h:423
uint8_t heartbeat_max
When RETROFLAT_STATE::heartbeat_frame reaches this value, it will reset to 0.
Definition: retroflt.h:1674
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:1606
uint8_t heartbeat_frame
Simple iteration loop that can be used to time e.g. perpetual sprite animations. Modify parameters wi...
Definition: retroflt.h:1669
size_t screen_w
The screen width as seen by the system, after scaling.
Definition: retroflt.h:1643
#define retroflat_heartbeat_set(len, max)
Set parameters for the RETROFLAT_STATE::heartbeat_frame.
Definition: retroflt.h:1547
struct RETROFLAT_BITMAP buffer
Off-screen buffer bitmap.
Definition: retroflt.h:1597
void * vdp_exe
A handle for the loaded RetroFlat VDP API module.
Definition: retroflt.h:1611
RETROFLAT_COLOR_DEF palette[RETROFLAT_COLORS_SZ]
Index of available colors, initialized on platform init.
Definition: retroflt.h:1681
uint16_t heartbeat_len
Number of ms to stay on current value of RETROFLAT_STATE::heartbeat_frame before incrementing....
Definition: retroflt.h:1663
void * vdp_data
Pointer to data defined by the RetroFlat VDP API for its use.
Definition: retroflt.h:1617
size_t screen_v_h
The screen height as seen by our program, before scaling.
Definition: retroflt.h:1641
#define RETROFLAT_FLAGS_RUNNING
Flag indicating that retroflat_loop() should continue executing.
Definition: retroflt.h:416
#define RETROFLAT_FLAGS_WAIT_FOR_FPS
Do not execute any more inter-frame loops until next frame.
Definition: retroflt.h:443
#define RETROFLAT_FLAGS_KEY_REPEAT
Flag indicating keyboard repeat is enabled.
Definition: retroflt.h:430
The viewport data struct.
Definition: retroflt.h:1112
uint16_t screen_w_remainder
Difference between viewport width and screen width in pixels. Should only be retrieved through retrof...
Definition: retroflt.h:1167
int16_t screen_x
X position of the viewport in real screen memory in pixels. Should only be retrieved through retrofla...
Definition: retroflt.h:1118
uint16_t screen_h_remainder
Difference between viewport height and screen height in pixels. Should only be retrieved through retr...
Definition: retroflt.h:1174
retroflat_tile_t * refresh_grid
A grid of tile values representing the last-drawn values on-screen.
Definition: retroflt.h:1203
uint16_t screen_h
Viewport height in pixels. Should only be retrieved through retroflat_viewport_screen_w() and set thr...
Definition: retroflt.h:1160
int16_t world_w
The width of the entire world tilemap in pixels. Should only be retrieved through retroflat_viewport_...
Definition: retroflt.h:1142
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:1181
#define retroflat_viewport_set_pos_size(x_px, y_px, w_px, h_px)
Set the pixel width and height of the viewport, as well as some other dependent values frequently use...
Definition: retroflt.h:1459
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:1188
int16_t world_h
The height of the entire world tilemap in pixels. Should only be retrieved through retroflat_viewport...
Definition: retroflt.h:1148
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:1136
int16_t screen_y
Y position of the viewport in real screen memory in pixels. Should only be retrieved through retrofla...
Definition: retroflt.h:1124
uint16_t screen_w
Viewport width in pixels. Should only be retrieved through retroflat_viewport_screen_w() and set thro...
Definition: retroflt.h:1154
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:1130