33 |
|
// Glue for SDL and X11 support |
34 |
|
#ifdef USE_SDL_VIDEO |
35 |
|
#define MONITOR_INIT SDL_monitor_desc &monitor |
36 |
< |
#define VIDEO_DRV_INIT driver_window *drv |
37 |
< |
#define VIDEO_DRV_ROW_BYTES drv->s->pitch |
36 |
> |
#define VIDEO_DRV_WIN_INIT driver_window *drv |
37 |
|
#define VIDEO_DRV_LOCK_PIXELS if (SDL_MUSTLOCK(drv->s)) SDL_LockSurface(drv->s) |
38 |
|
#define VIDEO_DRV_UNLOCK_PIXELS if (SDL_MUSTLOCK(drv->s)) SDL_UnlockSurface(drv->s) |
39 |
+ |
#define VIDEO_DRV_DEPTH drv->s->format->BitsPerPixel |
40 |
+ |
#define VIDEO_DRV_WIDTH drv->s->w |
41 |
+ |
#define VIDEO_DRV_HEIGHT drv->s->h |
42 |
+ |
#define VIDEO_DRV_ROW_BYTES drv->s->pitch |
43 |
|
#else |
44 |
|
#ifdef SHEEPSHAVER |
45 |
|
#define MONITOR_INIT /* nothing */ |
46 |
< |
#define VIDEO_DRV_INIT /* nothing */ |
46 |
> |
#define VIDEO_DRV_WIN_INIT /* nothing */ |
47 |
> |
#define VIDEO_DRV_DGA_INIT /* nothing */ |
48 |
|
#define VIDEO_DRV_WINDOW the_win |
49 |
|
#define VIDEO_DRV_GC the_gc |
50 |
|
#define VIDEO_DRV_IMAGE img |
51 |
|
#define VIDEO_DRV_HAVE_SHM have_shm |
52 |
|
#else |
53 |
|
#define MONITOR_INIT X11_monitor_desc &monitor |
54 |
< |
#define VIDEO_DRV_INIT driver_window *drv |
54 |
> |
#define VIDEO_DRV_WIN_INIT driver_window *drv |
55 |
> |
#define VIDEO_DRV_DGA_INIT driver_dga *drv |
56 |
|
#define VIDEO_DRV_WINDOW drv->w |
57 |
|
#define VIDEO_DRV_GC drv->gc |
58 |
|
#define VIDEO_DRV_IMAGE drv->img |
60 |
|
#endif |
61 |
|
#define VIDEO_DRV_LOCK_PIXELS /* nothing */ |
62 |
|
#define VIDEO_DRV_UNLOCK_PIXELS /* nothing */ |
63 |
+ |
#define VIDEO_DRV_DEPTH VIDEO_DRV_IMAGE->depth |
64 |
+ |
#define VIDEO_DRV_WIDTH VIDEO_DRV_IMAGE->width |
65 |
+ |
#define VIDEO_DRV_HEIGHT VIDEO_DRV_IMAGE->height |
66 |
|
#define VIDEO_DRV_ROW_BYTES VIDEO_DRV_IMAGE->bytes_per_line |
67 |
|
#endif |
68 |
|
|
69 |
|
// Variables for Video on SEGV support |
70 |
|
static uint8 *the_host_buffer; // Host frame buffer in VOSF mode |
63 |
– |
static uint32 the_host_buffer_row_bytes; // Host frame buffer number of bytes per row |
71 |
|
|
72 |
|
struct ScreenPageInfo { |
73 |
|
int top, bottom; // Mapping between this virtual page and Mac scanlines |
384 |
|
than pageCount. |
385 |
|
*/ |
386 |
|
|
387 |
< |
static inline void update_display_window_vosf(VIDEO_DRV_INIT) |
387 |
> |
static inline void update_display_window_vosf(VIDEO_DRV_WIN_INIT) |
388 |
|
{ |
389 |
|
VIDEO_MODE_INIT; |
390 |
|
|
438 |
|
*/ |
439 |
|
|
440 |
|
#if REAL_ADDRESSING || DIRECT_ADDRESSING |
441 |
< |
static inline void update_display_dga_vosf(void) |
441 |
> |
static inline void update_display_dga_vosf(VIDEO_DRV_DGA_INIT) |
442 |
|
{ |
443 |
|
VIDEO_MODE_INIT; |
444 |
|
|
445 |
+ |
// Compute number of bytes per row, take care to virtual screens |
446 |
+ |
const int src_bytes_per_row = VIDEO_MODE_ROW_BYTES; |
447 |
+ |
const int dst_bytes_per_row = TrivialBytesPerRow(VIDEO_MODE_X, DepthModeForPixelDepth(VIDEO_DRV_DEPTH)); |
448 |
+ |
const int scr_bytes_per_row = VIDEO_DRV_ROW_BYTES; |
449 |
+ |
assert(dst_bytes_per_row <= scr_bytes_per_row); |
450 |
+ |
const int scr_bytes_left = scr_bytes_per_row - dst_bytes_per_row; |
451 |
+ |
|
452 |
+ |
// Full screen update requested? |
453 |
|
if (mainBuffer.very_dirty) { |
454 |
|
PFLAG_CLEAR_ALL; |
455 |
|
vm_protect((char *)mainBuffer.memStart, mainBuffer.memLength, VM_PAGE_READ); |
441 |
– |
VIDEO_DRV_LOCK_PIXELS; |
456 |
|
memcpy(the_buffer_copy, the_buffer, VIDEO_MODE_ROW_BYTES * VIDEO_MODE_Y); |
457 |
< |
Screen_blit(the_host_buffer, the_buffer, VIDEO_MODE_ROW_BYTES * VIDEO_MODE_Y); |
457 |
> |
VIDEO_DRV_LOCK_PIXELS; |
458 |
> |
int i1 = 0, i2 = 0; |
459 |
> |
for (int j = 0; j < VIDEO_MODE_Y; j++) { |
460 |
> |
Screen_blit(the_host_buffer + i2, the_buffer + i1, src_bytes_per_row); |
461 |
> |
i1 += src_bytes_per_row; |
462 |
> |
i2 += scr_bytes_per_row; |
463 |
> |
} |
464 |
> |
#ifdef USE_SDL_VIDEO |
465 |
> |
SDL_UpdateRect(drv->s, 0, 0, VIDEO_MODE_X, VIDEO_MODE_Y); |
466 |
> |
#endif |
467 |
|
VIDEO_DRV_UNLOCK_PIXELS; |
468 |
|
return; |
469 |
|
} |
470 |
|
|
471 |
+ |
// Setup partial blitter (use 64-pixel wide chunks) |
472 |
+ |
const int n_pixels = 64; |
473 |
+ |
const int n_chunks = VIDEO_MODE_X / n_pixels; |
474 |
+ |
const int src_chunk_size = src_bytes_per_row / n_chunks; |
475 |
+ |
const int dst_chunk_size = dst_bytes_per_row / n_chunks; |
476 |
+ |
const int src_chunk_size_left = src_bytes_per_row - (n_chunks * src_chunk_size); |
477 |
+ |
const int dst_chunk_size_left = dst_bytes_per_row - (n_chunks * dst_chunk_size); |
478 |
+ |
|
479 |
|
int page = 0; |
480 |
|
for (;;) { |
481 |
|
const unsigned first_page = find_next_page_set(page); |
494 |
|
const int y1 = mainBuffer.pageInfo[first_page].top; |
495 |
|
const int y2 = mainBuffer.pageInfo[page - 1].bottom; |
496 |
|
|
497 |
< |
#ifndef USE_SDL_VIDEO |
467 |
< |
// Update the_host_buffer and copy of the_buffer (use 64 bytes chunks) |
468 |
< |
const int src_bytes_per_row = VIDEO_MODE_ROW_BYTES; |
469 |
< |
const int dst_bytes_per_row = the_host_buffer_row_bytes; |
470 |
< |
const int n_pixels = 64; |
471 |
< |
const int n_chunks = VIDEO_MODE_X / n_pixels; |
472 |
< |
const int src_chunk_size = src_bytes_per_row / n_chunks; |
473 |
< |
const int dst_chunk_size = dst_bytes_per_row / n_chunks; |
474 |
< |
const int src_chunk_size_left = src_bytes_per_row - (n_chunks * src_chunk_size); |
475 |
< |
const int dst_chunk_size_left = dst_bytes_per_row - (n_chunks * dst_chunk_size); |
497 |
> |
// Update the_host_buffer and copy of the_buffer |
498 |
|
int i1 = y1 * src_bytes_per_row; |
499 |
< |
int i2 = y1 * dst_bytes_per_row; |
499 |
> |
int i2 = y1 * scr_bytes_per_row; |
500 |
|
VIDEO_DRV_LOCK_PIXELS; |
501 |
|
for (int j = y1; j <= y2; j++) { |
502 |
|
for (int i = 0; i < n_chunks; i++) { |
503 |
|
if (memcmp(the_buffer_copy + i1, the_buffer + i1, src_chunk_size) != 0) { |
504 |
|
memcpy(the_buffer_copy + i1, the_buffer + i1, src_chunk_size); |
505 |
|
Screen_blit(the_host_buffer + i2, the_buffer + i1, src_chunk_size); |
506 |
+ |
#ifdef USE_SDL_VIDEO |
507 |
+ |
SDL_UpdateRect(drv->s, i * n_pixels, j, n_pixels, 1); |
508 |
+ |
#endif |
509 |
|
} |
510 |
|
i1 += src_chunk_size; |
511 |
|
i2 += dst_chunk_size; |
518 |
|
i1 += src_chunk_size_left; |
519 |
|
i2 += dst_chunk_size_left; |
520 |
|
} |
521 |
+ |
i2 += scr_bytes_left; |
522 |
|
} |
523 |
|
VIDEO_DRV_UNLOCK_PIXELS; |
498 |
– |
#else |
499 |
– |
// Check for first chunk from left and first chunk from right that have changed |
500 |
– |
typedef uint64 chunk_t; |
501 |
– |
const int chunk_size = sizeof(chunk_t); |
502 |
– |
const int bytes_per_row = VIDEO_MODE_ROW_BYTES; |
503 |
– |
|
504 |
– |
int i, j; |
505 |
– |
int b1 = bytes_per_row / chunk_size; |
506 |
– |
int b2 = 0; |
507 |
– |
for (j = y1; j <= y2; j++) { |
508 |
– |
chunk_t * const p1 = (chunk_t *)(the_buffer + (j * bytes_per_row)); |
509 |
– |
chunk_t * const p2 = (chunk_t *)(the_buffer_copy + (j * bytes_per_row)); |
510 |
– |
for (i = 0; i < b1; i++) { |
511 |
– |
if (p1[i] != p2[i]) { |
512 |
– |
b1 = i; |
513 |
– |
break; |
514 |
– |
} |
515 |
– |
} |
516 |
– |
if (b1 > b2) |
517 |
– |
b2 = b1; |
518 |
– |
for (i = (bytes_per_row / chunk_size) - 1; i > b2; i--) { |
519 |
– |
if (p1[i] != p2[i]) { |
520 |
– |
b2 = i; |
521 |
– |
break; |
522 |
– |
} |
523 |
– |
} |
524 |
– |
} |
525 |
– |
b2++; |
526 |
– |
|
527 |
– |
// Convert to pixel information |
528 |
– |
int x1, x2; |
529 |
– |
switch (VIDEO_MODE_DEPTH) { |
530 |
– |
case VIDEO_DEPTH_1BIT: x1 = (b1 * chunk_size) << 3; x2 = (b2 * chunk_size) << 3; break; |
531 |
– |
case VIDEO_DEPTH_2BIT: x1 = (b1 * chunk_size) << 2; x2 = (b2 * chunk_size) << 2; break; |
532 |
– |
case VIDEO_DEPTH_4BIT: x1 = (b1 * chunk_size) << 1; x2 = (b2 * chunk_size) << 1; break; |
533 |
– |
case VIDEO_DEPTH_8BIT: x1 = b1 * chunk_size; x2 = b2 * chunk_size; break; |
534 |
– |
case VIDEO_DEPTH_16BIT: x1 = (b1 * chunk_size) >> 1; x2 = (b2 * chunk_size) >> 1; break; |
535 |
– |
case VIDEO_DEPTH_32BIT: x1 = (b1 * chunk_size) >> 2; x2 = (b2 * chunk_size) >> 2; break; |
536 |
– |
} |
537 |
– |
const int width = x2 - x1; |
538 |
– |
|
539 |
– |
// Normalize bounds for for the next blit |
540 |
– |
const int src_bytes_per_row = VIDEO_MODE_ROW_BYTES; |
541 |
– |
const int dst_bytes_per_row = the_host_buffer_row_bytes; |
542 |
– |
const int dst_bytes_per_pixel = dst_bytes_per_row / VIDEO_MODE_X; |
543 |
– |
int i2 = y1 * dst_bytes_per_row + x1 * dst_bytes_per_pixel; |
544 |
– |
int i1, n_bytes; |
545 |
– |
if ((int)VIDEO_MODE_DEPTH < VIDEO_DEPTH_8BIT) { |
546 |
– |
const int src_pixels_per_byte = VIDEO_MODE_X / src_bytes_per_row; |
547 |
– |
i1 = y1 * src_bytes_per_row + x1 / src_pixels_per_byte; |
548 |
– |
n_bytes = width / src_pixels_per_byte; |
549 |
– |
} else { |
550 |
– |
const int src_bytes_per_pixel = src_bytes_per_row / VIDEO_MODE_X; |
551 |
– |
i1 = y1 * src_bytes_per_row + x1 * src_bytes_per_pixel; |
552 |
– |
n_bytes = width * src_bytes_per_pixel; |
553 |
– |
} |
554 |
– |
|
555 |
– |
// Update the_host_buffer and copy of the_buffer |
556 |
– |
VIDEO_DRV_LOCK_PIXELS; |
557 |
– |
for (j = y1; j <= y2; j++) { |
558 |
– |
Screen_blit(the_host_buffer + i2, the_buffer + i1, n_bytes); |
559 |
– |
memcpy(the_buffer_copy + i1, the_buffer + i1, n_bytes); |
560 |
– |
i1 += src_bytes_per_row; |
561 |
– |
i2 += dst_bytes_per_row; |
562 |
– |
} |
563 |
– |
VIDEO_DRV_UNLOCK_PIXELS; |
564 |
– |
#endif |
524 |
|
} |
525 |
|
mainBuffer.dirty = false; |
526 |
|
} |