Skip to content

[Discussion] Can SDLV1 handle BW 1 bpp source frame #35

@rickyzhang82

Description

@rickyzhang82

This is NOT an issue in your SDL2. But I can't find anyone who can discuss this topic with. Sorry to abuse your issue board.

Recently, I'm working on enabling 24 bit ROM in BII. Someone fixed broken frame buffer memory access. I fixed emulated hard drive. Now I want to make it work under SDL.

I traced the frame buffer drawing in the host down to the function in below.

Before I asked you questions, here is some background

  1. Screen size is 512x342
  2. Black and White -- 1 bit per pixel
  3. For Macintosh with 24bit ROM, it has 4MB memory limit. Buffer memory patch make it stays in the last page of memory, which is not hard coded address a0000000.
  4. The patch make drawing works in X11 but not SDL.

Here are my questions regarding to the function below:
1. I understood that it tries to find the minimum rectangle that contain different pixels between the current the_buffer and the previous the_buffer_copy, but what does variable wide and hide mean?
1. I have forced SDL use 1 bit per pixel, but the Destination bytes per row are still 512, which is one byte per pixel under 512 x 342.

-- I got the answers.

// Static display update (fixed frame rate, but incremental)
1842 static void update_display_static(driver_base *drv)
1843 {
1844     // Incremental update code
1845     int wide = 0, high = 0;
1846     uint32 x1, x2, y1, y2;
1847     const VIDEO_MODE &mode = drv->mode;
1848     int bytes_per_row = VIDEO_MODE_ROW_BYTES;
1849     uint8 *p, *p2;
1850 
1851     // Check for first line from top and first line from bottom that have changed
1852     y1 = 0;
1853     for (uint32 j = 0; j < VIDEO_MODE_Y; j++) {
1854         if (memcmp(&the_buffer[j * bytes_per_row], &the_buffer_copy[j * bytes_per_row], bytes_per_row)) {
1855             y1 = j;
1856             break;
1857         }
1858     }
1859     y2 = y1 - 1;
1860     for (uint32 j = VIDEO_MODE_Y; j-- > y1; ) {
1861         if (memcmp(&the_buffer[j * bytes_per_row], &the_buffer_copy[j * bytes_per_row], bytes_per_row)) {
1862             y2 = j;
1863             break;
1864         }
1865     }
1866     high = y2 - y1 + 1;
1867 
1868     // Check for first column from left and first column from right that have changed
1869     if (high) {
1870         if (VIDEO_MODE_DEPTH < VIDEO_DEPTH_8BIT) {
1871             const int src_bytes_per_row = bytes_per_row;
1872             const int dst_bytes_per_row = drv->s->pitch;
1873             const int pixels_per_byte = VIDEO_MODE_X / src_bytes_per_row;
1874 
1875             x1 = VIDEO_MODE_X / pixels_per_byte;
1876             for (uint32 j = y1; j <= y2; j++) {
1877                 p = &the_buffer[j * bytes_per_row];
1878                 p2 = &the_buffer_copy[j * bytes_per_row];
1879                 for (uint32 i = 0; i < x1; i++) {
1880                     if (*p != *p2) {
1881                         x1 = i;
1882                         break;
1883                     }
1884                     p++; p2++;
1885                 }
1886             }
1887             x2 = x1;
1888             for (uint32 j = y1; j <= y2; j++) {
1889                 p = &the_buffer[j * bytes_per_row];
1890                 p2 = &the_buffer_copy[j * bytes_per_row];
1891                 p += bytes_per_row;
1892                 p2 += bytes_per_row;
1893                 for (uint32 i = (VIDEO_MODE_X / pixels_per_byte); i > x2; i--) {
1894                     p--; p2--;
1895                     if (*p != *p2) {
1896                         x2 = i;
1897                         break;
1898                     }
1899                 }
1900             }
1901             x1 *= pixels_per_byte;
1902             x2 *= pixels_per_byte;
1903             wide = (x2 - x1 + pixels_per_byte - 1) & -pixels_per_byte;
1904 
1905             // Update copy of the_buffer
1906             if (high && wide) {
1907 
1908                 // Lock surface, if required
1909                 if (SDL_MUSTLOCK(drv->s))
1910                     SDL_LockSurface(drv->s);
1911 
1912                 // Blit to screen surface
1913                 int si = y1 * src_bytes_per_row + (x1 / pixels_per_byte);
1914                 int di = y1 * dst_bytes_per_row + x1;
1915                 for (uint32 j = y1; j <= y2; j++) {
1916                     memcpy(the_buffer_copy + si, the_buffer + si, wide / pixels_per_byte);
1917                     Screen_blit((uint8 *)drv->s->pixels + di, the_buffer + si, wide / pixels_per_byte);
1918                     si += src_bytes_per_row;
1919                     di += dst_bytes_per_row;
1920                 }
1921 
1922                 // Unlock surface, if required
1923                 if (SDL_MUSTLOCK(drv->s))
1924                     SDL_UnlockSurface(drv->s);
1925 
1926                 // Refresh display
1927                 SDL_UpdateRect(drv->s, x1, y1, wide, high);
1928             }
1929 
1930         } else {
1931             const int bytes_per_pixel = VIDEO_MODE_ROW_BYTES / VIDEO_MODE_X;
1932             const int dst_bytes_per_row = drv->s->pitch;
1933 
1934             x1 = VIDEO_MODE_X;
1935             for (uint32 j = y1; j <= y2; j++) {
1936                 p = &the_buffer[j * bytes_per_row];
1937                 p2 = &the_buffer_copy[j * bytes_per_row];
1938                 for (uint32 i = 0; i < x1 * bytes_per_pixel; i++) {
1939                     if (*p != *p2) {
1940                         x1 = i / bytes_per_pixel;
1941                         break;
1942                     }
1943                     p++; p2++;
1944                 }
1945             }
1946             x2 = x1;
1947             for (uint32 j = y1; j <= y2; j++) {
1948                 p = &the_buffer[j * bytes_per_row];
1949                 p2 = &the_buffer_copy[j * bytes_per_row];
1950                 p += bytes_per_row;
1951                 p2 += bytes_per_row;
1952                 for (uint32 i = VIDEO_MODE_X * bytes_per_pixel; i > x2 * bytes_per_pixel; i--) {
1953                     p--;
1954                     p2--;
1955                     if (*p != *p2) {
1956                         x2 = i / bytes_per_pixel;
1957                         break;
1958                     }
1959                 }
1960             }
1961             wide = x2 - x1;
1962 
1963             // Update copy of the_buffer
1964             if (high && wide) {
1965 
1966                 // Lock surface, if required
1967                 if (SDL_MUSTLOCK(drv->s))
1968                     SDL_LockSurface(drv->s);
1969 
1970                 // Blit to screen surface
1971                 for (uint32 j = y1; j <= y2; j++) {
1972                     uint32 i = j * bytes_per_row + x1 * bytes_per_pixel;
1973                     int dst_i = j * dst_bytes_per_row + x1 * bytes_per_pixel;
1974                     memcpy(the_buffer_copy + i, the_buffer + i, bytes_per_pixel * wide);
1975                     Screen_blit((uint8 *)drv->s->pixels + dst_i, the_buffer + i, bytes_per_pixel * wide);
1976                 }
1977 
1978                 // Unlock surface, if required
1979                 if (SDL_MUSTLOCK(drv->s))
1980                     SDL_UnlockSurface(drv->s);
1981 
1982                 // Refresh display
1983                 SDL_UpdateRect(drv->s, x1, y1, wide, high);
1984             }
1985         }
1986     }
1987 }
1988 

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions