diff --git a/platforms/amiga/pistorm-dev/pistorm-dev-enums.h b/platforms/amiga/pistorm-dev/pistorm-dev-enums.h index 15fb424..4cdbc72 100644 --- a/platforms/amiga/pistorm-dev/pistorm-dev-enums.h +++ b/platforms/amiga/pistorm-dev/pistorm-dev-enums.h @@ -5,6 +5,7 @@ // [R], [W] and [RW] indicate read, write or both access modes for register // Any failure or result code from a write command should be put in PI_CMDRESULT +// Try to make sure to align any new registers to word/longword offsets enum pistorm_dev_cmds { PI_CMD_RESET = 0x00, // [W] Reset the host system. PI_CMD_SWITCHCONFIG = 0x02, // [W] Switch config file to string at PI_STR1, if it exists. @@ -34,7 +35,10 @@ enum pistorm_dev_cmds { PI_CMD_SHOWFPS = 0x0118, // [W] Enable/disable RTG FPS display. PI_CMD_PALETTEDEBUG = 0x011A, // [W] Enable/disable RTG palette debug. PI_CMD_MEMCPY_Q = 0x0120, // [W] CopyMemQuick debug thing - PI_CMD_GET_TEMP = 0x0121, // [R] Get the CPU core temperature + PI_CMD_GET_TEMP = 0x0124, // [R] Get the CPU core temperature + + PI_CMD_RTG_SCALING = 0x0200, // [W] Set RTG scaling mode + PI_CMD_RTG_SCALE_FILTER = 0x0202, // [W] Set RTG scale filter PI_CMD_QBASIC = 0x0FFC, // QBasic PI_CMD_NIBBLES = 0x0FFE, // Nibbles @@ -92,6 +96,25 @@ enum pistorm_dev_cmds { PI_CMDRESULT = 0x2100, // [R] Check the result of any command that provides a "return value". }; +enum rtg_scaling_commands { + PIGFX_SCALE_NONE, // No scaling, display at 1:1 size even if it doesn't fit on screen + PIGFX_SCALE_INTEGER_MAX, // Scale to max integer multiple that fits on screen + PIGFX_SCALE_FULL_ASPECT, // Scale to full width and/or height of screen, preserve source aspect ratio + PIGFX_SCALE_FULL_43, // Scale to full width and/or height of screen at 4:3 aspect ratio + PIGFX_SCALE_FULL_169, // Scale to full width and/or height of screen at 16:9 aspect ratio + PIGFX_SCALE_FULL, // Scale to full width and height of screen, ignoring source aspect ratio + PIGFX_SCALE_CUSTOM, // Scale to custom position and size specified in PI_WORD1 through PI_WORD4 + PIGFX_SCALE_CUSTOM_RECT, // Scale to custom rectangle coordinates specified in PI_WORD1 through PI_WORD4 + PIGFX_SCALE_NUM, +}; + +enum rtg_scale_filter_commands { + PIGFX_FILTER_POINT, // Nearest neighbor scaling, sharp image, may cause uneven pixels + PIGFX_FILTER_SMOOTH, // Linear/bilinear texture scaling, blurry, may improve visibility or perceived "squareness" of pixels + PIGFX_FILTER_SHADER, // Load and use a pixel shader specified in PI_STR1 for scaling RTG output [NYI] + PIGFX_FILTER_NUM, +}; + enum pistorm_piscsi_commands { PISCSI_CTRL_NONE, PISCSI_CTRL_MAP, // For hard drives diff --git a/platforms/amiga/pistorm-dev/pistorm-dev.c b/platforms/amiga/pistorm-dev/pistorm-dev.c index a013909..d722577 100644 --- a/platforms/amiga/pistorm-dev/pistorm-dev.c +++ b/platforms/amiga/pistorm-dev/pistorm-dev.c @@ -369,6 +369,19 @@ void handle_pistorm_dev_write(uint32_t addr_, uint32_t val, uint8_t type) { } adjust_ranges_amiga(cfg); break; + case PI_CMD_RTG_SCALING: + DEBUG("[PISTORM-DEV] Write to RTG_SCALING: %d\n", val); + if (val == PIGFX_SCALE_CUSTOM || val == PIGFX_SCALE_CUSTOM_RECT) { + rtg_set_scale_rect(val, (int16_t)pi_word[0], (int16_t)pi_word[1], (int16_t)pi_word[2], (int16_t)pi_word[3]); + } else { + rtg_set_scale_mode(val); + } + break; + case PI_CMD_RTG_SCALE_FILTER: + DEBUG("[PISTORM-DEV] Write to RTG_SCALE_FILTER: %d\n", val); + rtg_set_scale_filter(val); + break; + case PI_CMD_NETSTATUS: DEBUG("[PISTORM-DEV] Write to NETSTATUS: %d\n", val); if (val == 1 && !pinet_enabled) { diff --git a/platforms/amiga/pistorm-dev/pistorm_dev_amiga/CopyMems b/platforms/amiga/pistorm-dev/pistorm_dev_amiga/CopyMems index 8c48396..85f9b5e 100755 Binary files a/platforms/amiga/pistorm-dev/pistorm_dev_amiga/CopyMems and b/platforms/amiga/pistorm-dev/pistorm_dev_amiga/CopyMems differ diff --git a/platforms/amiga/pistorm-dev/pistorm_dev_amiga/PiSimple b/platforms/amiga/pistorm-dev/pistorm_dev_amiga/PiSimple index 9c73f73..c626888 100755 Binary files a/platforms/amiga/pistorm-dev/pistorm_dev_amiga/PiSimple and b/platforms/amiga/pistorm-dev/pistorm_dev_amiga/PiSimple differ diff --git a/platforms/amiga/pistorm-dev/pistorm_dev_amiga/pistorm_dev.c b/platforms/amiga/pistorm-dev/pistorm_dev_amiga/pistorm_dev.c index 1c24320..ee9bf60 100644 --- a/platforms/amiga/pistorm-dev/pistorm_dev_amiga/pistorm_dev.c +++ b/platforms/amiga/pistorm-dev/pistorm_dev_amiga/pistorm_dev.c @@ -160,6 +160,25 @@ void pi_copyrect_ex(unsigned char *dst, unsigned char *src, WRITESHORT(PI_CMD_COPYRECT_EX, 1); } +// Set scale mode for the RTG, no additional arguments required +void pi_set_rtg_scale_mode(unsigned short scale_mode) { + WRITESHORT(PI_CMD_RTG_SCALING, scale_mode); +} + +// Set rect to scale RTG output to, argument values depend on rect mode +void pi_set_rtg_scale_rect(unsigned short scale_mode, signed short x1, signed short y1, signed short x2, signed short y2) { + WRITESHORT(PI_WORD1, x1); + WRITESHORT(PI_WORD2, y1); + WRITESHORT(PI_WORD3, x2); + WRITESHORT(PI_WORD4, y2); + WRITESHORT(PI_CMD_RTG_SCALING, scale_mode); +} + +// Set RTG scaling filter (sharp, smooth/blurry, shader [NYI]) +void pi_set_rtg_scale_filter(unsigned short scale_filter) { + WRITESHORT(PI_CMD_RTG_SCALE_FILTER, scale_filter); +} + // PiSCSI stuff // TODO: There's currently no way to read back what drives are mounted at which SCSI index. unsigned short pi_piscsi_map_drive(char *filename, unsigned char index) { diff --git a/platforms/amiga/pistorm-dev/pistorm_dev_amiga/pistorm_dev.h b/platforms/amiga/pistorm-dev/pistorm_dev_amiga/pistorm_dev.h index 4cef879..22614b3 100644 --- a/platforms/amiga/pistorm-dev/pistorm_dev_amiga/pistorm_dev.h +++ b/platforms/amiga/pistorm-dev/pistorm_dev_amiga/pistorm_dev.h @@ -31,6 +31,9 @@ unsigned short pi_memset(unsigned char *dst, unsigned char val, unsigned int siz void pi_copyrect(unsigned char *dst, unsigned char *src, unsigned short src_pitch, unsigned short dst_pitch, unsigned short w, unsigned short h); void pi_copyrect_ex(unsigned char *dst, unsigned char *src, unsigned short src_pitch, unsigned short dst_pitch, unsigned short src_x, unsigned short src_y, unsigned short dst_x, unsigned short dst_y, unsigned short w, unsigned short h); unsigned int pi_get_fb(void); +void pi_set_rtg_scale_mode(unsigned short scale_mode); +void pi_set_rtg_scale_rect(unsigned short scale_mode, signed short x1, signed short y1, signed short x2, signed short y2); +void pi_set_rtg_scale_filter(unsigned short scale_filter); unsigned short pi_load_config(char *filename); void pi_reload_config(void); diff --git a/platforms/amiga/pistorm-dev/pistorm_dev_amiga/simple_interact.c b/platforms/amiga/pistorm-dev/pistorm_dev_amiga/simple_interact.c index 3ff1268..01119a8 100644 --- a/platforms/amiga/pistorm-dev/pistorm_dev_amiga/simple_interact.c +++ b/platforms/amiga/pistorm-dev/pistorm_dev_amiga/simple_interact.c @@ -40,10 +40,13 @@ void print_usage(char *exe); int get_command(char *cmd); +unsigned short get_scale_mode(char *mode); +unsigned short get_scale_filter(char *mode); extern unsigned int pistorm_base_addr; unsigned short cmd_arg = 0; +unsigned short scale_rect = 0; int __stdargs main (int argc, char *argv[]) { if (argc < 2) { @@ -60,11 +63,11 @@ int __stdargs main (int argc, char *argv[]) { pistorm_base_addr = pi_find_pistorm(); if (pistorm_base_addr == 0xFFFFFFFF) { - printf ("Unable to find PiStorm autoconf device.\n"); + printf("Unable to find PiStorm autoconf device.\n"); return 1; } else { - printf ("PiStorm autoconf device found at $%.X\n", pistorm_base_addr); + printf("PiStorm autoconf device found at $%.X\n", pistorm_base_addr); } unsigned int tmpvalue = 0; @@ -79,64 +82,113 @@ int __stdargs main (int argc, char *argv[]) { pi_reset_amiga(tmpshort); break; case PI_CMD_SWREV: - printf ("PiStorm ----------------------------\n"); - printf ("Hardware revision: %d.%d\n", (pi_get_hw_rev() >> 8), (pi_get_hw_rev() & 0xFF)); - printf ("Software revision: %d.%d\n", (pi_get_sw_rev() >> 8), (pi_get_sw_rev() & 0xFF)); - printf ("RTG: %s - %s\n", (pi_get_rtg_status() & 0x01) ? "Enabled" : "Disabled", (pi_get_rtg_status() & 0x02) ? "In use" : "Not in use"); - printf ("NET: %s\n", pi_get_net_status() ? "Enabled" : "Disabled"); - printf ("PiSCSI: %s\n", pi_get_piscsi_status() ? "Enabled" : "Disabled"); + printf("PiStorm ----------------------------\n"); + printf("Hardware revision: %d.%d\n", (pi_get_hw_rev() >> 8), (pi_get_hw_rev() & 0xFF)); + printf("Software revision: %d.%d\n", (pi_get_sw_rev() >> 8), (pi_get_sw_rev() & 0xFF)); + printf("RTG: %s - %s\n", (pi_get_rtg_status() & 0x01) ? "Enabled" : "Disabled", (pi_get_rtg_status() & 0x02) ? "In use" : "Not in use"); + printf("NET: %s\n", pi_get_net_status() ? "Enabled" : "Disabled"); + printf("PiSCSI: %s\n", pi_get_piscsi_status() ? "Enabled" : "Disabled"); break; case PI_CMD_SWITCHCONFIG: if (cmd_arg == PICFG_LOAD) { if (argc < 3) { - printf ("User asked to load config, but no config filename specified.\n"); + printf("User asked to load config, but no config filename specified.\n"); } } pi_handle_config(cmd_arg, argv[2]); break; case PI_CMD_TRANSFERFILE: if (argc < 4) { - printf ("Please specify a source and destination filename in addition to the command.\n"); - printf ("Example: %s --transfer platforms/platform.h snakes.h\n", argv[0]); + printf("Please specify a source and destination filename in addition to the command.\n"); + printf("Example: %s --transfer platforms/platform.h snakes.h\n", argv[0]); } if (pi_get_filesize(argv[2], &tmpvalue) == PI_RES_FILENOTFOUND) { - printf ("File %s not found on the Pi side.\n", argv[2]); + printf("File %s not found on the Pi side.\n", argv[2]); } else { unsigned int filesize = tmpvalue; unsigned char *dest = malloc(filesize); if (dest == NULL) { - printf ("Failed to allocate memory buffer for file. Aborting file transfer.\n"); + printf("Failed to allocate memory buffer for file. Aborting file transfer.\n"); } else { - printf ("Found a %u byte file on the Pi side. Eating it.\n", filesize); + printf("Found a %u byte file on the Pi side. Eating it.\n", filesize); if (pi_transfer_file(argv[2], dest) != PI_RES_OK) { - printf ("Something went horribly wrong during the file transfer.\n"); + printf("Something went horribly wrong during the file transfer.\n"); } else { FILE *out = fopen(argv[3], "wb+"); if (out == NULL) { - printf ("Failed to open output file %s for writing.\n", argv[3]); + printf("Failed to open output file %s for writing.\n", argv[3]); } else { fwrite(dest, filesize, 1, out); fclose(out); - printf ("%u bytes transferred to file %s.\n", filesize, argv[3]); + printf("%u bytes transferred to file %s.\n", filesize, argv[3]); } } free(dest); } } break; - case PI_CMD_GET_TEMP: - { - unsigned short temp = pi_get_temperature(); - if (temp == 0) { - printf("Error getting temperature\n"); - } else { - printf("CPU temp: %u%cC\n", temp, 0xb0); - } + case PI_CMD_GET_TEMP: { + unsigned short temp = pi_get_temperature(); + if (temp == 0) { + printf("Error getting temperature\n"); + } else { + printf("CPU temp: %u%cC\n", temp, 0xb0); + } + break; + } + case PI_CMD_RTG_SCALE_FILTER: { + if (argc < 3) { + printf("Failed to set RTG scale filter: No scale filter specified.\n"); break; } + unsigned short scale_filter = get_scale_filter(argv[2]); + if (scale_filter != PIGFX_FILTER_NUM) { + pi_set_rtg_scale_filter(scale_filter); + } else { + printf("Failed to set RTG scale filter: Unknown scale filter %s.\n", argv[2]); + } + + break; + } + case PI_CMD_RTG_SCALING: + if (scale_rect != 0) { + if (argc < 6) { + printf("Missing command line arguments for RTG scale rect. Example:\n"); + if (scale_rect == 1) { + printf("%s --rtg-rect 16 16 640 480\n", argv[0]); + printf("Arguments being a rect: [X] [Y] [Width] [Height]\n"); + } + if (scale_rect == 2) { + printf("%s --rtg-rect 16 16 1264 705\n", argv[0]); + printf("Arguments being coordinates of rect corners: [X] [Y] [X2] [Y2]\n"); + } + break; + } else { + signed short x1, y1, x2, y2; + x1 = atoi(argv[2]); + y1 = atoi(argv[3]); + x2 = atoi(argv[4]); + y2 = atoi(argv[5]); + pi_set_rtg_scale_rect(scale_rect == 1 ? PIGFX_SCALE_CUSTOM_RECT : PIGFX_SCALE_CUSTOM, x1, y1, x2, y2); + break; + } + } else { + if (argc < 3) { + printf("Failed to set RTG scale mode: No scale mode type specified.\n"); + break; + } + unsigned short scale_mode = get_scale_mode(argv[2]); + if (scale_mode != PIGFX_SCALE_NUM) { + pi_set_rtg_scale_mode(scale_mode); + } else { + printf("Failed to set RTG scale mode: Unknown RTG scale mode %s.\n", argv[2]); + printf("Valid options are 4:3, 16:9, 1:1, full, aspect and integer\n"); + } + } + break; default: - printf ("Unhandled command %s.\n", argv[1]); + printf("Unhandled command %s.\n", argv[1]); return 1; break; } @@ -166,19 +218,57 @@ int get_command(char *cmd) { if (strcmp(cmd, "--transfer-file") == 0 || strcmp(cmd, "--transfer") == 0 || strcmp(cmd, "--getfile") == 0) { return PI_CMD_TRANSFERFILE; } - if (strcmp(cmd, "--get-temperature") == 0) { + if (strcmp(cmd, "--get-temperature") == 0 || strcmp(cmd, "--get-temp") == 0 || strcmp(cmd, "--temp") == 0) { return PI_CMD_GET_TEMP; } + if (strcmp(cmd, "--rtg-scaling") == 0 || strcmp(cmd, "--rtg-scale-mode") == 0 || strcmp(cmd, "--rtgscale") == 0) { + return PI_CMD_RTG_SCALING; + } + if (strcmp(cmd, "--rtg-rect") == 0 || strcmp(cmd, "--rtg-scale-rect") == 0 || strcmp(cmd, "--rtgrect") == 0) { + scale_rect = 1; + return PI_CMD_RTG_SCALING; + } + if (strcmp(cmd, "--rtg-custom") == 0 || strcmp(cmd, "--rtg-scale-custom") == 0 || strcmp(cmd, "--rtgcustom") == 0) { + scale_rect = 2; + return PI_CMD_RTG_SCALING; + } + if (strcmp(cmd, "--rtg-filter") == 0 || strcmp(cmd, "--rtg-scale-filter") == 0 || strcmp(cmd, "--rtgfilter") == 0) { + return PI_CMD_RTG_SCALE_FILTER; + } + return -1; } +unsigned short get_scale_mode(char *mode) { + if (strcmp(mode, "4:3") == 0) return PIGFX_SCALE_FULL_43; + if (strcmp(mode, "16:9") == 0) return PIGFX_SCALE_FULL_169; + if (strcmp(mode, "1:1") == 0) return PIGFX_SCALE_NONE; + if (strcmp(mode, "full") == 0) return PIGFX_SCALE_FULL; + if (strcmp(mode, "aspect") == 0) return PIGFX_SCALE_FULL_ASPECT; + if (strcmp(mode, "integer") == 0) return PIGFX_SCALE_INTEGER_MAX; + + return PIGFX_SCALE_NUM; +} + +unsigned short get_scale_filter(char *mode) { + if (strcmp(mode, "sharp") == 0) return PIGFX_FILTER_POINT; + if (strcmp(mode, "point") == 0) return PIGFX_FILTER_POINT; + if (strcmp(mode, "smooth") == 0) return PIGFX_FILTER_SMOOTH; + if (strcmp(mode, "blurry") == 0) return PIGFX_FILTER_SMOOTH; + if (strcmp(mode, "bilinear") == 0) return PIGFX_FILTER_SMOOTH; + if (strcmp(mode, "linear") == 0) return PIGFX_FILTER_SMOOTH; + if (strcmp(mode, "shader") == 0) return PIGFX_FILTER_SHADER; + + return PIGFX_FILTER_NUM; +} + void print_usage(char *exe) { - printf ("Usage: %s --[command] (arguments)\n", exe); - printf ("Example: %s --restart, --reboot or --reset\n", exe); - printf (" Restarts the Amiga.\n"); - printf (" %s --check, --find or --info\n", exe); - printf (" Finds the PiStorm device and prints some data.\n"); + printf("Usage: %s --[command] (arguments)\n", exe); + printf("Example: %s --restart, --reboot or --reset\n", exe); + printf(" Restarts the Amiga.\n"); + printf(" %s --check, --find or --info\n", exe); + printf(" Finds the PiStorm device and prints some data.\n"); return; } diff --git a/platforms/amiga/rtg/rtg-output-raylib.c b/platforms/amiga/rtg/rtg-output-raylib.c index 11da7d7..4934111 100644 --- a/platforms/amiga/rtg/rtg-output-raylib.c +++ b/platforms/amiga/rtg/rtg-output-raylib.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: MIT #include "config_file/config_file.h" +#include "platforms/amiga/pistorm-dev/pistorm-dev-enums.h" #include "emulator.h" #include "rtg.h" @@ -39,6 +40,7 @@ static pthread_t thread_id; static uint8_t mouse_cursor_enabled = 0, cursor_image_updated = 0, updating_screen = 0, debug_palette = 0, show_fps = 0; static uint8_t mouse_cursor_w = 16, mouse_cursor_h = 16; static int16_t mouse_cursor_x = 0, mouse_cursor_y = 0; +static int16_t mouse_cursor_x_adj = 0, mouse_cursor_y_adj = 0; struct rtg_shared_data { uint16_t *width, *height; @@ -49,6 +51,12 @@ struct rtg_shared_data { uint8_t *running; }; +float scale_x = 1.0f, scale_y = 1.0f; +static Rectangle srcrect, dstscale; +static Vector2 origin; +static uint8_t scale_mode = PIGFX_SCALE_FULL_ASPECT; +static uint8_t filter_mode = 0; + struct rtg_shared_data rtg_share_data; static uint32_t palette[256]; static uint32_t cursor_palette[256]; @@ -71,12 +79,119 @@ uint32_t rtg_pixel_size[RTGFMT_NUM] = { 2, }; +void rtg_scale_output(uint16_t width, uint16_t height) { + static uint8_t fit_to_screen = 1, center = 1; + srcrect.x = srcrect.y = 0; + srcrect.width = width; + srcrect.height = height; + if (scale_mode != PIGFX_SCALE_CUSTOM && scale_mode != PIGFX_SCALE_CUSTOM_RECT) { + dstscale.x = dstscale.y = 0; + dstscale.width = width; + dstscale.height = height; + mouse_cursor_x_adj = 0; + mouse_cursor_y_adj = 0; + } + + if (dstscale.width == 0.0f || dstscale.height == 0.0f) { + dstscale.width = 128.0f; + dstscale.height = 128.0f; + } + if (srcrect.width == 0.0f || srcrect.height == 0.0f) { + dstscale.width = 128.0f; + dstscale.height = 128.0f; + } + + switch (scale_mode) { + case PIGFX_SCALE_INTEGER_MAX: + default: + if (dstscale.height * 2 <= GetScreenHeight()) { + if (width == 320) { + if (GetScreenHeight() == 720) { + dstscale.width = 960; + dstscale.height = 720; + } else if (GetScreenHeight() == 1080) { + dstscale.width = 1440; + dstscale.height = 1080; + } else if (GetScreenHeight() == 1200) { + dstscale.width = 1600; + dstscale.height = 1200; + } + } + while (dstscale.height + height <= GetScreenHeight()) { + dstscale.height += height; + dstscale.width += width; + } + } + break; + case PIGFX_SCALE_FULL_ASPECT: + dstscale.height = (float)GetScreenHeight(); + dstscale.width = srcrect.width * (dstscale.height / srcrect.height); + break; + case PIGFX_SCALE_FULL_43: + dstscale.height = (float)GetScreenHeight(); + dstscale.width = ((float)GetScreenHeight() / 3.0f) * 4.0f; + break; + case PIGFX_SCALE_FULL_169: + dstscale.height = (float)GetScreenHeight(); + dstscale.width = ((float)GetScreenHeight() / 9.0f) * 16.0f; + break; + case PIGFX_SCALE_FULL: + dstscale.height = GetScreenHeight(); + dstscale.width = GetScreenWidth(); + break; + case PIGFX_SCALE_NONE: + dstscale.width = srcrect.width; + dstscale.height = srcrect.height; + fit_to_screen = 0; + break; + case PIGFX_SCALE_CUSTOM: + case PIGFX_SCALE_CUSTOM_RECT: + fit_to_screen = 0; + center = 0; + break; + } + + if (fit_to_screen) { + if (dstscale.width > GetScreenWidth() || dstscale.height > GetScreenHeight()) { + if (dstscale.height > GetScreenHeight()) { + DEBUG("[H > SH]\n"); + DEBUG("Adjusted width from %d to", (int)dstscale.width); + dstscale.width = dstscale.width * ((float)GetScreenHeight() / srcrect.height); + DEBUG("%d.\n", (int)dstscale.width); + DEBUG("Adjusted height from %d to", (int)dstscale.height); + dstscale.height = GetScreenHeight(); + DEBUG("%d.\n", (int)dstscale.height); + } + if (dstscale.width > GetScreenWidth()) { + // First scaling attempt failed, do not double adjust, re-adjust + dstscale.width = width; + dstscale.height = height; + DEBUG("[W > SW]\n"); + DEBUG("Adjusted height from %d to", (int)dstscale.height); + dstscale.height = dstscale.height * ((float)GetScreenWidth() / srcrect.width); + DEBUG("%d.\n", (int)dstscale.height); + DEBUG("Adjusted width from %d to", (int)dstscale.width); + dstscale.width = GetScreenWidth(); + DEBUG("%d.\n", (int)dstscale.width); + } + } + } + + scale_x = dstscale.width / srcrect.width; + scale_y = dstscale.height / srcrect.height; + + if (center) { + origin.x = (dstscale.width - GetScreenWidth()) * 0.5; + origin.y = (dstscale.height - GetScreenHeight()) * 0.5; + } +} + void *rtgThread(void *args) { printf("RTG thread running\n"); fflush(stdout); - int reinit = 0; + int reinit = 0, old_filter_mode = -1; rtg_on = 1; uint32_t *indexed_buf = NULL; @@ -106,7 +221,6 @@ void *rtgThread(void *args) { SetTargetFPS(60); Color bef = { 0, 64, 128, 255 }; - float scale_x = 1.0f, scale_y = 1.0f; Shader clut_shader = LoadShader(NULL, "platforms/amiga/rtg/clut.shader"); Shader swizzle_shader = LoadShader(NULL, "platforms/amiga/rtg/argbswizzle.shader"); @@ -127,9 +241,6 @@ void *rtgThread(void *args) { raylib_cursor.data = cursor_data; raylib_cursor_texture = LoadTextureFromImage(raylib_cursor); - Rectangle srcrect, dstscale; - Vector2 origin; - reinit_raylib:; if (reinit) { printf("Reinitializing raylib...\n"); @@ -168,62 +279,17 @@ reinit_raylib:; printf("Loaded framebuffer texture.\n"); - srcrect.x = srcrect.y = 0; - srcrect.width = width; - srcrect.height = height; - dstscale.x = dstscale.y = 0; - dstscale.width = width; - dstscale.height = height; - - if (dstscale.height * 2 <= GetScreenHeight()) { - if (width == 320) { - if (GetScreenHeight() == 720) { - dstscale.width = 960; - dstscale.height = 720; - } else if (GetScreenHeight() == 1080) { - dstscale.width = 1440; - dstscale.height = 1080; - } else if (GetScreenHeight() == 1200) { - dstscale.width = 1600; - dstscale.height = 1200; - } - } - while (dstscale.height + height <= GetScreenHeight()) { - dstscale.height += height; - dstscale.width += width; - } - } else if (dstscale.width > GetScreenWidth() || dstscale.height > GetScreenHeight()) { - if (dstscale.height > GetScreenHeight()) { - DEBUG("[H > SH]\n"); - DEBUG("Adjusted width from %d to", (int)dstscale.width); - dstscale.width = dstscale.width * ((float)GetScreenHeight() / (float)height); - DEBUG("%d.\n", (int)dstscale.width); - DEBUG("Adjusted height from %d to", (int)dstscale.height); - dstscale.height = GetScreenHeight(); - DEBUG("%d.\n", (int)dstscale.height); - } - if (dstscale.width > GetScreenWidth()) { - // First scaling attempt failed, do not double adjust, re-adjust - dstscale.width = width; - dstscale.height = height; - DEBUG("[W > SW]\n"); - DEBUG("Adjusted height from %d to", (int)dstscale.height); - dstscale.height = dstscale.height * ((float)GetScreenWidth() / (float)width); - DEBUG("%d.\n", (int)dstscale.height); - DEBUG("Adjusted width from %d to", (int)dstscale.width); - dstscale.width = GetScreenWidth(); - DEBUG("%d.\n", (int)dstscale.width); - } - } - - scale_x = dstscale.width / (float)width; - scale_y = dstscale.height / (float)height; - - origin.x = (dstscale.width - GetScreenWidth()) * 0.5; - origin.y = (dstscale.height - GetScreenHeight()) * 0.5; + rtg_scale_output(width, height); while (1) { if (rtg_on) { + if (old_filter_mode != filter_mode) { + old_filter_mode = filter_mode; + SetTextureFilter(raylib_clut_texture, filter_mode); + SetTextureFilter(raylib_texture, filter_mode); + SetTextureFilter(raylib_cursor_texture, filter_mode); + } + BeginDrawing(); rtg_output_in_vblank = 0; updating_screen = 1; @@ -249,8 +315,8 @@ reinit_raylib:; } if (mouse_cursor_enabled) { - float mc_x = mouse_cursor_x - rtg_offset_x; - float mc_y = mouse_cursor_y - rtg_offset_y; + float mc_x = mouse_cursor_x - rtg_offset_x + mouse_cursor_x_adj; + float mc_y = mouse_cursor_y - rtg_offset_y + mouse_cursor_y_adj; Rectangle cursor_srcrect = { 0, 0, mouse_cursor_w, mouse_cursor_h }; Rectangle dstrect = { mc_x * scale_x, mc_y * scale_y, (float)mouse_cursor_w * scale_x, (float)mouse_cursor_h * scale_y }; DrawTexturePro(raylib_cursor_texture, cursor_srcrect, dstrect, origin, 0.0f, RAYWHITE); @@ -442,3 +508,49 @@ void rtg_show_fps(uint8_t enable) { void rtg_palette_debug(uint8_t enable) { debug_palette = (enable != 0); } + +void rtg_set_scale_mode(uint16_t _scale_mode) { + switch (_scale_mode) { + case PIGFX_SCALE_INTEGER_MAX: + case PIGFX_SCALE_FULL_ASPECT: + case PIGFX_SCALE_FULL_43: + case PIGFX_SCALE_FULL_169: + case PIGFX_SCALE_FULL: + case PIGFX_SCALE_NONE: + scale_mode = _scale_mode; + rtg_scale_output(rtg_display_width, rtg_display_height); + break; + case PIGFX_SCALE_CUSTOM: + case PIGFX_SCALE_CUSTOM_RECT: + printf("[!!!RTG] Tried to set RTG scale mode to custom or custom rect using the wrong function. Ignored.\n"); + break; + } +} + +void rtg_set_scale_rect(uint16_t _scale_mode, int16_t x1, int16_t y1, int16_t x2, int16_t y2) { + scale_mode = _scale_mode; + + origin.x = 0.0f; + origin.y = 0.0f; + mouse_cursor_x_adj = x1; + mouse_cursor_y_adj = y1; + dstscale.x = (float)x1; + dstscale.y = (float)y1; + + switch (scale_mode) { + case PIGFX_SCALE_CUSTOM_RECT: + dstscale.width = (float)x2; + dstscale.height = (float)y2; + break; + case PIGFX_SCALE_CUSTOM: + dstscale.width = (float)x2 - (float)x1; + dstscale.height = (float)y2 - (float)y1; + break; + } + + rtg_scale_output(rtg_display_width, rtg_display_height); +} + +void rtg_set_scale_filter(uint16_t _filter_mode) { + filter_mode = _filter_mode; +} diff --git a/platforms/amiga/rtg/rtg.h b/platforms/amiga/rtg/rtg.h index 63decc7..7bbdb88 100644 --- a/platforms/amiga/rtg/rtg.h +++ b/platforms/amiga/rtg/rtg.h @@ -24,6 +24,9 @@ void rtg_set_cursor_clut_entry(uint8_t r, uint8_t g, uint8_t b, uint8_t idx); void rtg_set_mouse_cursor_image(uint8_t *src, uint8_t w, uint8_t h); void rtg_show_fps(uint8_t enable); +void rtg_set_scale_mode(uint16_t scale_mode); +void rtg_set_scale_rect(uint16_t scale_mode, int16_t x1, int16_t y1, int16_t x2, int16_t y2); +void rtg_set_scale_filter(uint16_t _filter_mode); void rtg_palette_debug(uint8_t enable); int init_rtg_data(struct emulator_config *cfg);