added support for 8-bit windowed modes on 16 and 32-bit screens (for the

games, man, the games! :-)
This commit is contained in:
cebix 2001-07-01 19:57:55 +00:00
parent af35353cf0
commit f4243a191b
3 changed files with 97 additions and 20 deletions

View File

@ -35,6 +35,9 @@ struct VisualFormat {
};
static VisualFormat visualFormat;
// This holds the pixels values of the palette colors for 8->16/32-bit expansion
uint32 ExpandMap[256];
/* -------------------------------------------------------------------------- */
/* --- Raw Copy / No conversion required --- */
/* -------------------------------------------------------------------------- */
@ -258,6 +261,28 @@ static void Blit_Copy_Raw(uint8 * dest, const uint8 * source, uint32 length)
#define FB_DEPTH 24
#include "video_blit.h"
/* -------------------------------------------------------------------------- */
/* --- 8-bit indexed to 16-bit mode color expansion --- */
/* -------------------------------------------------------------------------- */
static void Blit_Expand_8_To_16(uint8 * dest, const uint8 * p, uint32 length)
{
uint16 *q = (uint16 *)dest;
for (int i=0; i<length; i++)
*q++ = ExpandMap[*p++];
}
/* -------------------------------------------------------------------------- */
/* --- 8-bit indexed to 32-bit mode color expansion --- */
/* -------------------------------------------------------------------------- */
static void Blit_Expand_8_To_32(uint8 * dest, const uint8 * p, uint32 length)
{
uint32 *q = (uint32 *)dest;
for (int i=0; i<length; i++)
*q++ = ExpandMap[*p++];
}
/* -------------------------------------------------------------------------- */
/* --- Blitters to the host frame buffer, or XImage buffer --- */
/* -------------------------------------------------------------------------- */
@ -319,7 +344,7 @@ bool Screen_blitter_init(XVisualInfo * visual_info, bool native_byte_order, vide
visualFormat.Rmask = visual_info->red_mask;
visualFormat.Gmask = visual_info->green_mask;
visualFormat.Bmask = visual_info->blue_mask;
// Compute RGB shift values
visualFormat.Rshift = 0;
for (uint32 Rmask = visualFormat.Rmask; Rmask && ((Rmask & 1) != 1); Rmask >>= 1)
@ -330,9 +355,21 @@ bool Screen_blitter_init(XVisualInfo * visual_info, bool native_byte_order, vide
visualFormat.Bshift = 0;
for (uint32 Bmask = visualFormat.Bmask; Bmask && ((Bmask & 1) != 1); Bmask >>= 1)
++visualFormat.Bshift;
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;
}
}
// Search for an adequate blit function
bool blitter_found = false;
const int blitters_count = sizeof(Screen_blitters)/sizeof(Screen_blitters[0]);
for (int i = 0; !blitter_found && (i < blitters_count); i++) {
if ( (visualFormat.depth == Screen_blitters[i].depth)

View File

@ -281,6 +281,7 @@ static bool screen_fault_handler(sigsegv_address_t fault_address, sigsegv_addres
// From video_blit.cpp
extern void (*Screen_blit)(uint8 * dest, const uint8 * source, uint32 length);
extern bool Screen_blitter_init(XVisualInfo * visual_info, bool native_byte_order, video_depth mac_depth);
extern uint32 ExpandMap[256];
/* How can we deal with array overrun conditions ?
@ -336,13 +337,11 @@ static inline void update_display_window_vosf(driver_window *drv)
const int y2 = mainBuffer.pageInfo[page - 1].bottom;
const int height = y2 - y1 + 1;
const int bytes_per_row = VideoMonitor.mode.bytes_per_row;
const int bytes_per_pixel = VideoMonitor.mode.bytes_per_row / VideoMonitor.mode.x;
int i = y1 * bytes_per_row, j;
if (VideoMonitor.mode.depth == VDEPTH_1BIT) {
// 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;
for (j = y1; j <= y2; j++) {
Screen_blit(the_host_buffer + i, the_buffer + i, VideoMonitor.mode.x >> 3);
i += bytes_per_row;
@ -351,9 +350,14 @@ static inline void update_display_window_vosf(driver_window *drv)
} else {
// Update the_host_buffer and copy of the_buffer
const int src_bytes_per_row = VideoMonitor.mode.bytes_per_row;
const int dst_bytes_per_row = drv->img->bytes_per_line;
const int bytes_per_pixel = src_bytes_per_row / VideoMonitor.mode.x;
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, bytes_per_pixel * VideoMonitor.mode.x);
i += bytes_per_row;
Screen_blit(the_host_buffer + i2, the_buffer + i1, bytes_per_pixel * VideoMonitor.mode.x);
i1 += src_bytes_per_row;
i2 += dst_bytes_per_row;
}
}

View File

@ -185,6 +185,12 @@ extern void SysMountFirstFloppy(void);
* Utility functions
*/
// Map RGB color to pixel value (this only works in TrueColor/DirectColor visuals)
static inline uint32 map_rgb(uint8 red, uint8 green, uint8 blue)
{
return ((red >> rloss) << rshift) | ((green >> gloss) << gshift) | ((blue >> bloss) << bshift);
}
// Add mode to list of supported modes
static void add_mode(uint32 width, uint32 height, uint32 resolution_id, uint32 bytes_per_row, video_depth depth)
{
@ -479,7 +485,7 @@ driver_window::driver_window(const video_mode &mode)
// Create normal X image if SHM doesn't work ("height + 2" for safety)
if (!have_shm) {
int bytes_per_row = TrivialBytesPerRow(aligned_width, mode.depth);
int bytes_per_row = (mode.depth == VDEPTH_1BIT ? aligned_width/8 : TrivialBytesPerRow(aligned_width, DepthModeForPixelDepth(xdepth)));
the_buffer_copy = (uint8 *)malloc((aligned_height + 2) * bytes_per_row);
img = XCreateImage(x_display, vis, mode.depth == VDEPTH_1BIT ? 1 : xdepth, mode.depth == VDEPTH_1BIT ? XYBitmap : ZPixmap, 0, (char *)the_buffer_copy, aligned_width, aligned_height, 32, bytes_per_row);
}
@ -1043,6 +1049,13 @@ static bool video_open(const video_mode &mode)
XStoreColors(x_display, cmap[1], palette, num);
}
#ifdef ENABLE_VOSF
// Load gray ramp to 8->16/32 expand map
if (!IsDirectMode(mode) && (vis->c_class == TrueColor || vis->c_class == DirectColor))
for (int i=0; i<256; i++)
ExpandMap[i] = map_rgb(i, i, i);
#endif
// Create display driver object of requested type
switch (display_type) {
case DISPLAY_WINDOW:
@ -1233,7 +1246,7 @@ bool VideoInit(bool classic)
int num = vis->map_entries;
for (int i=0; i<num; i++) {
int c = (i * 256) / num;
palette[i].pixel = ((c >> rloss) << rshift) | ((c >> gloss) << gshift) | ((c >> bloss) << bshift);
palette[i].pixel = map_rgb(c, c, c);
}
}
@ -1282,20 +1295,29 @@ bool VideoInit(bool classic)
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(832, 624, 0x83, TrivialBytesPerRow(832, VDEPTH_1BIT), VDEPTH_1BIT);
add_mode(1024, 768, 0x84, TrivialBytesPerRow(1024, VDEPTH_1BIT), VDEPTH_1BIT);
add_mode(1152, 870, 0x85, TrivialBytesPerRow(1152, VDEPTH_1BIT), VDEPTH_1BIT);
add_mode(1280, 1024, 0x86, TrivialBytesPerRow(1280, VDEPTH_1BIT), VDEPTH_1BIT);
add_mode(1600, 1200, 0x87, TrivialBytesPerRow(1600, 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);
}
#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);
}
#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(832, 624, 0x83, TrivialBytesPerRow(832, default_depth), default_depth);
add_mode(1024, 768, 0x84, TrivialBytesPerRow(1024, default_depth), default_depth);
add_mode(1152, 870, 0x85, TrivialBytesPerRow(1152, default_depth), default_depth);
add_mode(1280, 1024, 0x86, TrivialBytesPerRow(1280, default_depth), default_depth);
add_mode(1600, 1200, 0x87, TrivialBytesPerRow(1600, 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);
}
} else
add_mode(default_width, default_height, 0x80, TrivialBytesPerRow(default_width, default_depth), default_depth);
@ -1446,6 +1468,20 @@ void video_set_palette(uint8 *pal)
p++;
}
#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]);
// We have to redraw everything because the interpretation of pixel values changed
LOCK_VOSF;
PFLAG_SET_ALL;
UNLOCK_VOSF;
memset(the_buffer_copy, 0, VideoMonitor.mode.bytes_per_row * VideoMonitor.mode.y);
}
#endif
// Tell redraw thread to change palette
palette_changed = true;