75 |
|
uint32 pageCount; // Number of pages allocated to the screen |
76 |
|
|
77 |
|
bool dirty; // Flag: set if the frame buffer was touched |
78 |
+ |
bool very_dirty; // Flag: set if the frame buffer was completely modified (e.g. colormap changes) |
79 |
|
char * dirtyPages; // Table of flags set if page was altered |
80 |
|
ScreenPageInfo * pageInfo; // Table of mappings page -> Mac scanlines |
81 |
|
}; |
121 |
|
#define PFLAG_CLEAR_ALL do { \ |
122 |
|
PFLAG_CLEAR_RANGE(0, mainBuffer.pageCount); \ |
123 |
|
mainBuffer.dirty = false; \ |
124 |
+ |
mainBuffer.very_dirty = false; \ |
125 |
+ |
} while (0) |
126 |
+ |
|
127 |
+ |
#define PFLAG_SET_VERY_DIRTY do { \ |
128 |
+ |
mainBuffer.very_dirty = true; \ |
129 |
|
} while (0) |
130 |
|
|
131 |
|
// Set the following macro definition to 1 if your system |
435 |
|
{ |
436 |
|
VIDEO_MODE_INIT; |
437 |
|
|
438 |
< |
int i, j; |
439 |
< |
int page = 0; |
438 |
> |
if (mainBuffer.very_dirty) { |
439 |
> |
PFLAG_CLEAR_ALL; |
440 |
> |
vm_protect((char *)mainBuffer.memStart, mainBuffer.memLength, VM_PAGE_READ); |
441 |
> |
VIDEO_DRV_LOCK_PIXELS; |
442 |
> |
memcpy(the_buffer_copy, the_buffer, VIDEO_MODE_ROW_BYTES * VIDEO_MODE_Y); |
443 |
> |
Screen_blit(the_host_buffer, the_buffer, VIDEO_MODE_ROW_BYTES * VIDEO_MODE_Y); |
444 |
> |
VIDEO_DRV_UNLOCK_PIXELS; |
445 |
> |
return; |
446 |
> |
} |
447 |
|
|
448 |
+ |
int page = 0; |
449 |
|
for (;;) { |
450 |
|
const unsigned first_page = find_next_page_set(page); |
451 |
|
if (first_page >= mainBuffer.pageCount) |
459 |
|
const uint32 length = (page - first_page) << mainBuffer.pageBits; |
460 |
|
vm_protect((char *)mainBuffer.memStart + offset, length, VM_PAGE_READ); |
461 |
|
|
462 |
< |
// I am sure that y2 >= y1 and depth != 1 |
462 |
> |
// There is at least one line to update |
463 |
|
const int y1 = mainBuffer.pageInfo[first_page].top; |
464 |
|
const int y2 = mainBuffer.pageInfo[page - 1].bottom; |
465 |
|
|
466 |
+ |
#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); |
476 |
+ |
int i1 = y1 * src_bytes_per_row; |
477 |
+ |
int i2 = y1 * dst_bytes_per_row; |
478 |
+ |
VIDEO_DRV_LOCK_PIXELS; |
479 |
+ |
for (int j = y1; j <= y2; j++) { |
480 |
+ |
for (int i = 0; i < n_chunks; i++) { |
481 |
+ |
if (memcmp(the_buffer_copy + i1, the_buffer + i1, src_chunk_size) != 0) { |
482 |
+ |
memcpy(the_buffer_copy + i1, the_buffer + i1, src_chunk_size); |
483 |
+ |
Screen_blit(the_host_buffer + i2, the_buffer + i1, src_chunk_size); |
484 |
+ |
} |
485 |
+ |
i1 += src_chunk_size; |
486 |
+ |
i2 += dst_chunk_size; |
487 |
+ |
} |
488 |
+ |
if (src_chunk_size_left && dst_chunk_size_left) { |
489 |
+ |
if (memcmp(the_buffer_copy + i1, the_buffer + i1, src_chunk_size_left) != 0) { |
490 |
+ |
memcpy(the_buffer_copy + i1, the_buffer + i1, src_chunk_size_left); |
491 |
+ |
Screen_blit(the_host_buffer + i2, the_buffer + i1, src_chunk_size_left); |
492 |
+ |
} |
493 |
+ |
i1 += src_chunk_size_left; |
494 |
+ |
i2 += dst_chunk_size_left; |
495 |
+ |
} |
496 |
+ |
} |
497 |
+ |
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; |
456 |
– |
assert((bytes_per_row % chunk_size) == 0); |
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)); |
513 |
|
break; |
514 |
|
} |
515 |
|
} |
516 |
< |
} |
517 |
< |
|
470 |
< |
int b2 = b1; |
471 |
< |
for (j = y2; j >= y1; j--) { |
472 |
< |
chunk_t * const p1 = (chunk_t *)(the_buffer + (j * bytes_per_row)); |
473 |
< |
chunk_t * const p2 = (chunk_t *)(the_buffer_copy + (j * bytes_per_row)); |
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; |
561 |
|
i2 += dst_bytes_per_row; |
562 |
|
} |
563 |
|
VIDEO_DRV_UNLOCK_PIXELS; |
564 |
+ |
#endif |
565 |
|
} |
566 |
|
mainBuffer.dirty = false; |
567 |
|
} |