From c8c1a7638198d5de4bee1be8cf0ed0002aa52936 Mon Sep 17 00:00:00 2001 From: rakslice Date: Mon, 16 Nov 2020 21:34:24 -0800 Subject: [PATCH 1/2] prevent truncating unaligned rows in non-vosf mode with 16 colors or less (cherry picked from commit 9d6124871be79f5c3028ebe3f5d1068dbcea0c84) --- BasiliskII/src/SDL/video_sdl2.cpp | 16 +++++++++++----- SheepShaver/src/include/video.h | 6 +++--- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/BasiliskII/src/SDL/video_sdl2.cpp b/BasiliskII/src/SDL/video_sdl2.cpp index 1b62dd25..f5132ee1 100644 --- a/BasiliskII/src/SDL/video_sdl2.cpp +++ b/BasiliskII/src/SDL/video_sdl2.cpp @@ -2397,6 +2397,7 @@ static void update_display_static(driver_base *drv) const VIDEO_MODE &mode = drv->mode; int bytes_per_row = VIDEO_MODE_ROW_BYTES; uint8 *p, *p2; + uint32 x2_clipped, wide_clipped; // Check for first line from top and first line from bottom that have changed y1 = 0; @@ -2420,9 +2421,11 @@ static void update_display_static(driver_base *drv) if ((int)VIDEO_MODE_DEPTH < (int)VIDEO_DEPTH_8BIT) { const int src_bytes_per_row = bytes_per_row; const int dst_bytes_per_row = drv->s->pitch; - const int pixels_per_byte = VIDEO_MODE_X / src_bytes_per_row; + const int pixels_per_byte = 8/mac_depth_of_video_depth(VIDEO_MODE_DEPTH); - x1 = VIDEO_MODE_X / pixels_per_byte; + const uint32 line_len = TrivialBytesPerRow(VIDEO_MODE_X, VIDEO_MODE_DEPTH); + + x1 = line_len; for (uint32 j = y1; j <= y2; j++) { p = &the_buffer[j * bytes_per_row]; p2 = &the_buffer_copy[j * bytes_per_row]; @@ -2440,7 +2443,7 @@ static void update_display_static(driver_base *drv) p2 = &the_buffer_copy[j * bytes_per_row]; p += bytes_per_row; p2 += bytes_per_row; - for (uint32 i = (VIDEO_MODE_X / pixels_per_byte); i > x2; i--) { + for (uint32 i = line_len; i > x2; i--) { p--; p2--; if (*p != *p2) { x2 = i; @@ -2448,9 +2451,12 @@ static void update_display_static(driver_base *drv) } } } + x1 *= pixels_per_byte; x2 *= pixels_per_byte; - wide = (x2 - x1 + pixels_per_byte - 1) & -pixels_per_byte; + wide = x2 - x1; + x2_clipped = x2 > VIDEO_MODE_X? VIDEO_MODE_X : x2; + wide_clipped = x2_clipped - x1; // Update copy of the_buffer if (high && wide) { @@ -2474,7 +2480,7 @@ static void update_display_static(driver_base *drv) SDL_UnlockSurface(drv->s); // Refresh display - update_sdl_video(drv->s, x1, y1, wide, high); + update_sdl_video(drv->s, x1, y1, wide_clipped, high); } } else { diff --git a/SheepShaver/src/include/video.h b/SheepShaver/src/include/video.h index f3a30f04..53719dcd 100644 --- a/SheepShaver/src/include/video.h +++ b/SheepShaver/src/include/video.h @@ -70,9 +70,9 @@ inline int DepthModeForPixelDepth(int depth) inline uint32 TrivialBytesPerRow(uint32 width, int mode) { switch (mode) { - case APPLE_1_BIT: return width / 8; - case APPLE_2_BIT: return width / 4; - case APPLE_4_BIT: return width / 2; + case APPLE_1_BIT: return (width + 7)/8; + case APPLE_2_BIT: return (width + 3)/4; + case APPLE_4_BIT: return (width + 1)/2; case APPLE_8_BIT: return width; case APPLE_16_BIT: return width * 2; case APPLE_32_BIT: return width * 4; From 6b4cc38de62d4cf7f63be2401c4cec41bb99574b Mon Sep 17 00:00:00 2001 From: rakslice Date: Mon, 16 Nov 2020 22:21:46 -0800 Subject: [PATCH 2/2] Corresponding header change for BII; cleanup (cherry picked from commit 36ccf8a46a72b6c970df04bd6ecc60efd0363476) --- BasiliskII/src/include/video.h | 8 ++++---- SheepShaver/src/include/video.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/BasiliskII/src/include/video.h b/BasiliskII/src/include/video.h index fe4404ef..23bba5e8 100644 --- a/BasiliskII/src/include/video.h +++ b/BasiliskII/src/include/video.h @@ -79,13 +79,13 @@ inline video_depth DepthModeForPixelDepth(int depth) // Returns the name of a video_depth, or an empty string if the depth is unknown const char * NameOfDepth(video_depth depth); -// Return a bytes-per-row value (assuming no padding) for the specified depth and pixel width +// Return a bytes-per-row value (assuming enough bytes to fit the bits but no further padding) for the specified depth and pixel width inline uint32 TrivialBytesPerRow(uint32 width, video_depth depth) { switch (depth) { - case VDEPTH_1BIT: return width / 8; - case VDEPTH_2BIT: return width / 4; - case VDEPTH_4BIT: return width / 2; + case VDEPTH_1BIT: return (width + 7) / 8; + case VDEPTH_2BIT: return (width + 3) / 4; + case VDEPTH_4BIT: return (width + 1) / 2; case VDEPTH_8BIT: return width; case VDEPTH_16BIT: return width * 2; case VDEPTH_32BIT: return width * 4; diff --git a/SheepShaver/src/include/video.h b/SheepShaver/src/include/video.h index 53719dcd..790292ad 100644 --- a/SheepShaver/src/include/video.h +++ b/SheepShaver/src/include/video.h @@ -66,13 +66,13 @@ inline int DepthModeForPixelDepth(int depth) } } -// Return a bytes-per-row value (assuming no padding) for the specified depth and pixel width +// Return a bytes-per-row value (assuming enough bytes to fit the bits but no further padding) for the specified depth and pixel width inline uint32 TrivialBytesPerRow(uint32 width, int mode) { switch (mode) { - case APPLE_1_BIT: return (width + 7)/8; - case APPLE_2_BIT: return (width + 3)/4; - case APPLE_4_BIT: return (width + 1)/2; + case APPLE_1_BIT: return (width + 7) / 8; + case APPLE_2_BIT: return (width + 3) / 4; + case APPLE_4_BIT: return (width + 1) / 2; case APPLE_8_BIT: return width; case APPLE_16_BIT: return width * 2; case APPLE_32_BIT: return width * 4;