mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-12-21 06:29:55 +00:00
added support for 8-bit windowed modes on 16 and 32-bit screens (for the
games, man, the games! :-)
This commit is contained in:
parent
af35353cf0
commit
f4243a191b
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user