From 5bd08dac88c27b025a455b62ceb475c197e9300f Mon Sep 17 00:00:00 2001 From: cebix <> Date: Sun, 1 Jul 2001 21:09:30 +0000 Subject: [PATCH] - video_set_palette() gets passed the number of used palette entries - video_x.cpp supports 2- and 4-bit modes on truecolor screens --- BasiliskII/ChangeLog | 2 + BasiliskII/src/AmigaOS/video_amiga.cpp | 8 +-- BasiliskII/src/BeOS/video_beos.cpp | 2 +- BasiliskII/src/Unix/video_blit.cpp | 82 ++++++++++++++++++++++---- BasiliskII/src/Unix/video_vosf.h | 13 ++-- BasiliskII/src/Unix/video_x.cpp | 57 ++++++++---------- BasiliskII/src/include/video.h | 2 +- BasiliskII/src/video.cpp | 24 +++++++- 8 files changed, 135 insertions(+), 55 deletions(-) diff --git a/BasiliskII/ChangeLog b/BasiliskII/ChangeLog index b2cfaaf8..61afa6fe 100644 --- a/BasiliskII/ChangeLog +++ b/BasiliskII/ChangeLog @@ -3,6 +3,8 @@ V1.0 (snapshot) - and gamma tables - fsave/frestore emulation under AmigaOS and NetBSD/m68k always behaves like a 68882/68040 FPU, eliminating the need for 68060 FPU patches + - Unix: windowed display mode supports different resolutions and color + depth, which can be switched on-the-fly V0.9 (release 0.9-1) - 31.May 2001 - final adjustments for 0.9 release diff --git a/BasiliskII/src/AmigaOS/video_amiga.cpp b/BasiliskII/src/AmigaOS/video_amiga.cpp index 447faf3a..eaa9a24a 100644 --- a/BasiliskII/src/AmigaOS/video_amiga.cpp +++ b/BasiliskII/src/AmigaOS/video_amiga.cpp @@ -536,16 +536,16 @@ void VideoExit(void) * Set palette */ -void video_set_palette(uint8 *pal) +void video_set_palette(uint8 *pal, in num) { if ((display_type == DISPLAY_SCREEN_P96 || display_type == DISPLAY_SCREEN_CGFX) && !IsDirectMode(VideoMonitor.mode)) { // Convert palette to 32 bits ULONG table[2 + 256 * 3]; - table[0] = 256 << 16; - table[256 * 3 + 1] = 0; - for (int i=0; i<256; i++) { + table[0] = num << 16; + table[num * 3 + 1] = 0; + for (int i=0; i> 6]; + *q++ = ExpandMap[c >> 4]; + *q++ = ExpandMap[c >> 2]; + *q++ = ExpandMap[c]; + } +} + +static void Blit_Expand_4_To_16(uint8 * dest, const uint8 * p, uint32 length) +{ + uint16 *q = (uint16 *)dest; + for (int i=0; i> 4]; + *q++ = ExpandMap[c]; + } +} + static void Blit_Expand_8_To_16(uint8 * dest, const uint8 * p, uint32 length) { uint16 *q = (uint16 *)dest; @@ -273,9 +295,31 @@ static void Blit_Expand_8_To_16(uint8 * dest, const uint8 * p, uint32 length) } /* -------------------------------------------------------------------------- */ -/* --- 8-bit indexed to 32-bit mode color expansion --- */ +/* --- 2/4/8-bit indexed to 32-bit mode color expansion --- */ /* -------------------------------------------------------------------------- */ +static void Blit_Expand_2_To_32(uint8 * dest, const uint8 * p, uint32 length) +{ + uint32 *q = (uint32 *)dest; + for (int i=0; i> 6]; + *q++ = ExpandMap[c >> 4]; + *q++ = ExpandMap[c >> 2]; + *q++ = ExpandMap[c]; + } +} + +static void Blit_Expand_4_To_32(uint8 * dest, const uint8 * p, uint32 length) +{ + uint32 *q = (uint32 *)dest; + for (int i=0; i> 4]; + *q++ = ExpandMap[c]; + } +} + static void Blit_Expand_8_To_32(uint8 * dest, const uint8 * p, uint32 length) { uint32 *q = (uint32 *)dest; @@ -358,14 +402,32 @@ bool Screen_blitter_init(XVisualInfo * visual_info, bool native_byte_order, vide bool blitter_found = false; - // 8-bit mode on 16/32-bit screen? - if (mac_depth == VDEPTH_8BIT && visualFormat.depth > 8) { - if (visual_info->depth <= 16) { - Screen_blit = Blit_Expand_8_To_16; - blitter_found = true; - } else { - Screen_blit = Blit_Expand_8_To_32; - blitter_found = true; + // 2/4/8-bit mode on 16/32-bit screen? + if (visualFormat.depth > 8) { + if (mac_depth == VDEPTH_2BIT) { + if (visual_info->depth <= 16) { + Screen_blit = Blit_Expand_2_To_16; + blitter_found = true; + } else { + Screen_blit = Blit_Expand_2_To_32; + blitter_found = true; + } + } else if (mac_depth == VDEPTH_4BIT) { + if (visual_info->depth <= 16) { + Screen_blit = Blit_Expand_4_To_16; + blitter_found = true; + } else { + Screen_blit = Blit_Expand_4_To_32; + blitter_found = true; + } + } else if (mac_depth == VDEPTH_8BIT) { + if (visual_info->depth <= 16) { + Screen_blit = Blit_Expand_8_To_16; + blitter_found = true; + } else { + Screen_blit = Blit_Expand_8_To_32; + blitter_found = true; + } } } diff --git a/BasiliskII/src/Unix/video_vosf.h b/BasiliskII/src/Unix/video_vosf.h index f6f77c5a..04d2d144 100644 --- a/BasiliskII/src/Unix/video_vosf.h +++ b/BasiliskII/src/Unix/video_vosf.h @@ -337,14 +337,17 @@ static inline void update_display_window_vosf(driver_window *drv) const int y2 = mainBuffer.pageInfo[page - 1].bottom; const int height = y2 - y1 + 1; - if (VideoMonitor.mode.depth == VDEPTH_1BIT) { + if (VideoMonitor.mode.depth < VDEPTH_8BIT) { // Update the_host_buffer and copy of the_buffer - const int bytes_per_row = VideoMonitor.mode.bytes_per_row; - int i = y1 * bytes_per_row, j; + const int src_bytes_per_row = VideoMonitor.mode.bytes_per_row; + const int dst_bytes_per_row = drv->img->bytes_per_line; + const int pixels_per_byte = VideoMonitor.mode.x / src_bytes_per_row; + int i1 = y1 * src_bytes_per_row, i2 = y1 * dst_bytes_per_row, j; for (j = y1; j <= y2; j++) { - Screen_blit(the_host_buffer + i, the_buffer + i, VideoMonitor.mode.x >> 3); - i += bytes_per_row; + Screen_blit(the_host_buffer + i2, the_buffer + i1, VideoMonitor.mode.x / pixels_per_byte); + i1 += src_bytes_per_row; + i2 += dst_bytes_per_row; } } else { diff --git a/BasiliskII/src/Unix/video_x.cpp b/BasiliskII/src/Unix/video_x.cpp index 48d2ae61..e5b474ed 100644 --- a/BasiliskII/src/Unix/video_x.cpp +++ b/BasiliskII/src/Unix/video_x.cpp @@ -203,6 +203,18 @@ static void add_mode(uint32 width, uint32 height, uint32 resolution_id, uint32 b VideoModes.push_back(mode); } +// Add standard list of windowed modes for given color depth +static void add_window_modes(video_depth depth) +{ + add_mode(512, 384, 0x80, TrivialBytesPerRow(512, depth), depth); + add_mode(640, 480, 0x81, TrivialBytesPerRow(640, depth), depth); + add_mode(800, 600, 0x82, TrivialBytesPerRow(800, depth), depth); + add_mode(1024, 768, 0x83, TrivialBytesPerRow(1024, depth), depth); + add_mode(1152, 870, 0x84, TrivialBytesPerRow(1152, depth), depth); + add_mode(1280, 1024, 0x85, TrivialBytesPerRow(1280, depth), depth); + add_mode(1600, 1200, 0x86, TrivialBytesPerRow(1600, depth), depth); +} + // Set Mac frame layout and base address (uses the_buffer/MacFrameBaseMac) static void set_mac_frame_buffer(video_depth depth, bool native_byte_order) { @@ -1291,33 +1303,16 @@ bool VideoInit(bool classic) if (classic) add_mode(512, 342, 0x80, 64, VDEPTH_1BIT); else { - if (default_depth != VDEPTH_1BIT) { // 1-bit modes are always available - add_mode(512, 384, 0x80, TrivialBytesPerRow(512, VDEPTH_1BIT), VDEPTH_1BIT); - add_mode(640, 480, 0x81, TrivialBytesPerRow(640, VDEPTH_1BIT), VDEPTH_1BIT); - add_mode(800, 600, 0x82, TrivialBytesPerRow(800, VDEPTH_1BIT), VDEPTH_1BIT); - add_mode(1024, 768, 0x83, TrivialBytesPerRow(1024, VDEPTH_1BIT), VDEPTH_1BIT); - add_mode(1152, 870, 0x84, TrivialBytesPerRow(1152, VDEPTH_1BIT), VDEPTH_1BIT); - add_mode(1280, 1024, 0x85, TrivialBytesPerRow(1280, VDEPTH_1BIT), VDEPTH_1BIT); - add_mode(1600, 1200, 0x86, TrivialBytesPerRow(1600, VDEPTH_1BIT), VDEPTH_1BIT); - } + if (default_depth != VDEPTH_1BIT) + add_window_modes(VDEPTH_1BIT); // 1-bit modes are always available #ifdef ENABLE_VOSF - if (default_depth > VDEPTH_8BIT) { // 8-bit modes are also possible on 16/32-bit screens with VOSF blitters - add_mode(512, 384, 0x80, TrivialBytesPerRow(512, VDEPTH_8BIT), VDEPTH_8BIT); - add_mode(640, 480, 0x81, TrivialBytesPerRow(640, VDEPTH_8BIT), VDEPTH_8BIT); - add_mode(800, 600, 0x82, TrivialBytesPerRow(800, VDEPTH_8BIT), VDEPTH_8BIT); - add_mode(1024, 768, 0x83, TrivialBytesPerRow(1024, VDEPTH_8BIT), VDEPTH_8BIT); - add_mode(1152, 870, 0x84, TrivialBytesPerRow(1152, VDEPTH_8BIT), VDEPTH_8BIT); - add_mode(1280, 1024, 0x85, TrivialBytesPerRow(1280, VDEPTH_8BIT), VDEPTH_8BIT); - add_mode(1600, 1200, 0x86, TrivialBytesPerRow(1600, VDEPTH_8BIT), VDEPTH_8BIT); + if (default_depth > VDEPTH_8BIT) { + add_window_modes(VDEPTH_2BIT); // 2, 4 and 8-bit modes are also possible on 16/32-bit screens with VOSF blitters + add_window_modes(VDEPTH_4BIT); + add_window_modes(VDEPTH_8BIT); } #endif - add_mode(512, 384, 0x80, TrivialBytesPerRow(512, default_depth), default_depth); - add_mode(640, 480, 0x81, TrivialBytesPerRow(640, default_depth), default_depth); - add_mode(800, 600, 0x82, TrivialBytesPerRow(800, default_depth), default_depth); - add_mode(1024, 768, 0x83, TrivialBytesPerRow(1024, default_depth), default_depth); - add_mode(1152, 870, 0x84, TrivialBytesPerRow(1152, default_depth), default_depth); - add_mode(1280, 1024, 0x85, TrivialBytesPerRow(1280, default_depth), default_depth); - add_mode(1600, 1200, 0x86, TrivialBytesPerRow(1600, default_depth), default_depth); + add_window_modes(default_depth); } } else add_mode(default_width, default_height, 0x80, TrivialBytesPerRow(default_width, default_depth), default_depth); @@ -1444,16 +1439,14 @@ void VideoInterrupt(void) * Set palette */ -void video_set_palette(uint8 *pal) +void video_set_palette(uint8 *pal, int num_in) { LOCK_PALETTE; // Convert colors to XColor array - int num_in = 256, num_out = 256; - if (VideoMonitor.mode.depth == VDEPTH_16BIT) - num_in = 32; + int num_out = 256; if (IsDirectMode(VideoMonitor.mode)) { - // If X is in 565 mode we have to stretch the palette from 32 to 64 entries + // If X is in 565 mode we have to stretch the gamma table from 32 to 64 entries num_out = vis->map_entries; } XColor *p = palette; @@ -1471,8 +1464,10 @@ void video_set_palette(uint8 *pal) #ifdef ENABLE_VOSF // Recalculate pixel color expansion map if (!IsDirectMode(VideoMonitor.mode) && (vis->c_class == TrueColor || vis->c_class == DirectColor)) { - for (int i=0; i<256; i++) - ExpandMap[i] = map_rgb(pal[i*3+0], pal[i*3+1], pal[i*3+2]); + for (int i=0; i<256; i++) { + int c = i % num_in; // If there are less than 256 colors, we repeat the first entries (this makes color expansion easier) + ExpandMap[i] = map_rgb(pal[c*3+0], pal[c*3+1], pal[c*3+2]); + } // We have to redraw everything because the interpretation of pixel values changed LOCK_VOSF; diff --git a/BasiliskII/src/include/video.h b/BasiliskII/src/include/video.h index 119595ef..93cb5332 100644 --- a/BasiliskII/src/include/video.h +++ b/BasiliskII/src/include/video.h @@ -175,6 +175,6 @@ extern void video_switch_to_mode(const video_mode &mode); // Called by the video driver to set the color palette (in indexed modes) // or gamma table (in direct modes) -extern void video_set_palette(uint8 *pal); +extern void video_set_palette(uint8 *pal, int num); #endif diff --git a/BasiliskII/src/video.cpp b/BasiliskII/src/video.cpp index d946e7f6..999a8e9f 100644 --- a/BasiliskII/src/video.cpp +++ b/BasiliskII/src/video.cpp @@ -124,6 +124,24 @@ static void get_size_of_resolution(uint32 id, uint32 &x, uint32 &y) } +/* + * Find palette size for given color depth + */ + +static int palette_size(video_depth depth) +{ + switch (depth) { + case VDEPTH_1BIT: return 2; + case VDEPTH_2BIT: return 4; + case VDEPTH_4BIT: return 16; + case VDEPTH_8BIT: return 256; + case VDEPTH_16BIT: return 32; + case VDEPTH_32BIT: return 256; + default: return 0; + } +} + + /* * Set palette to 50% gray */ @@ -135,7 +153,7 @@ static void set_gray_palette(void) VidLocal.palette[i * 3 + 1] = 127; VidLocal.palette[i * 3 + 2] = 127; } - video_set_palette(VidLocal.palette); + video_set_palette(VidLocal.palette, 256); } @@ -178,7 +196,7 @@ static void load_ramp_palette(void) *p++ = blue; } - video_set_palette(VidLocal.palette); + video_set_palette(VidLocal.palette, num); } @@ -483,7 +501,7 @@ int16 VideoDriverControl(uint32 pb, uint32 dce) s_pal += 8; } } - video_set_palette(VidLocal.palette); + video_set_palette(VidLocal.palette, palette_size(VidLocal.desc->mode.depth)); return noErr; }