- video_set_palette() gets passed the number of used palette entries

- video_x.cpp supports 2- and 4-bit modes on truecolor screens
This commit is contained in:
cebix 2001-07-01 21:09:30 +00:00
parent f4243a191b
commit 5bd08dac88
8 changed files with 135 additions and 55 deletions

View File

@ -3,6 +3,8 @@ V1.0 (snapshot) - <date>
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

View File

@ -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<num; i++) {
table[i*3+1] = pal[i*3] * 0x01010101;
table[i*3+2] = pal[i*3+1] * 0x01010101;
table[i*3+3] = pal[i*3+2] * 0x01010101;

View File

@ -287,7 +287,7 @@ void VideoExit(void)
* Set palette
*/
void video_set_palette(uint8 *pal)
void video_set_palette(uint8 *pal, int num)
{
switch (display_type) {
case DISPLAY_WINDOW: {

View File

@ -262,9 +262,31 @@ static void Blit_Copy_Raw(uint8 * dest, const uint8 * source, uint32 length)
#include "video_blit.h"
/* -------------------------------------------------------------------------- */
/* --- 8-bit indexed to 16-bit mode color expansion --- */
/* --- 2/4/8-bit indexed to 16-bit mode color expansion --- */
/* -------------------------------------------------------------------------- */
static void Blit_Expand_2_To_16(uint8 * dest, const uint8 * p, uint32 length)
{
uint16 *q = (uint16 *)dest;
for (int i=0; i<length; i++) {
uint8 c = *p++;
*q++ = ExpandMap[c >> 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<length; i++) {
uint8 c = *p++;
*q++ = ExpandMap[c >> 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<length; i++) {
uint8 c = *p++;
*q++ = ExpandMap[c >> 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<length; i++) {
uint8 c = *p++;
*q++ = ExpandMap[c >> 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;
}
}
}

View File

@ -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 {

View File

@ -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;

View File

@ -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

View File

@ -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;
}