Вобщем 2 экрана планирую добавить так (и даже больше чем это) - вывод графики (а также опрос кнопок клавы и мыши) у меня идёт через C++ класс
UniGraf (который внутри имеет реализации для SDL, svgalib и DOS переключаемые условной компиляцией), который поддерживает абстрактные пикселы, которые могут быть больше реальных пикселов экрана и даже могут быть совсем неквадратные - поэтому у меня получается выводить спринтеровский экран 640x256 в графическое окно 800x600 и вообще окно (или экран) любого размера (причём размер может быть даже меньше эмулируемого). Копирование в окно (на экран) идёт через периодически вызываемый метод
Update, в котором например в случае SDL просто стоит вызов
SDL_UpdateRect(PRIV->screen,0,0,dx,dy); копирующий копию экрана из системной памяти в видеопамять. Так вот мне надо добавить новый закадровый экран как отдельный объект
SDL_Surface размером БОЛЬШЕ видимой области и блиттить его часть по вызову метода
Update - левую часть закадрового буфера (страница 0), либо правую часть закадрового буфера (страница 1). Можно даже дальше пойти и сымитировать полную видеопамять 512КБ (хоть она и не поддержана в реальной железяке), добавив ещё одну такую же пару экранов ниже первой пары (т.е. закадровый буфер получит размер в 1024 полупикселей (512 байт) на 512 строк (причём с увеличением пропорционально целевому окну). Более того - пользуясь тем фактом, что у нас уже будет буфер больше видимого экрана, можно относительно просто реализовать горизонтальный и вертикальный СКРОЛЛИНГ причём с заворачиванием в кольцо (точнее в тор)! Для эмуляции Спринтера скроллинг само собой ненужен, но для будущего компьютера Zpring он очень даже не помешает

Одно НО (точнее два) - это будет работать только в SDL, т.к. в реализации через svgalib для Linux и через ваткомовский graph.h для DOS никаких сурфейсов в
UniGraf нету и весь вывод идёт прямо на экран путём вывода пикселей в нужные места согласно коэффициенту увеличения для каждого абстрактного пиксела. Скажем реализацию для svgalib я выкину - с некоторых пор этой графической библиотекой для консольного линуха на ПЦ стало не так то просто пользоваться (она лет 10 назад стала требовать подгрузки специального модуля ядра из под рута) и я даже не в курсе будет ли она работать с современными дистрами линукса (из дебияна её похоже выкинули ещё в 2013) - как говориться фиг с ней, а вот DOS мне хотелось бы сохранить - возможно в ваткомовском graph.h есть поддержка закадровых буферов и мне надо просто ей правильно воспользоваться - буду смотреть...
P.S. Почитал про ваткомовскую графику - там можно только сохранять экран в image и восстанавливать его потом обратно, т.е. придётся научиться рисовать в такую сохранённую картинку и при переключении экранов просто копировать правильную картинку в экран - выходит полноценного плавного скроллинга не получится т.к. картинка копируется только целиком, хоть и в произвольные координаты. Можно попробовать программно скроллировать, но это будет наверное несколько тормозно. Вот как WATCOM рассчитывает размер буфера под картинку:
 |  |  |
 | Code: long _WCI86FAR _CGRAPH _imagesize( short x1, short y1, short x2, short y2 ) /*==================================================================== This routine returns the size of buffer needed to store the picture in the rectangle defined by ( x1, y1 ) and ( x2, y2 ), in viewport coordinates. */ { if( _GraphMode() ) { return( _L2imagesize( _VtoPhysX( x1 ), _VtoPhysY( y1 ), _VtoPhysX( x2 ), _VtoPhysY( y2 ) ) ); } else { return( 0 ); } } Entry( _IMAGESIZE, _imagesize ) // alternate entry-point long _WCI86FAR _L2imagesize( short x1, short y1, short x2, short y2 ) /*============================================================== This routine returns the size of buffer needed to store the picture in the rectangle defined by ( x1, y1 ) and ( x2, y2 ), in physical coordinates. */ { #if defined( _DEFAULT_WINDOWS ) // For Windows and OS/2, the size is only the size of the record x1 = x1; x2 = x2; y1 = y1; y2 = y2; return( sizeof( struct picture ) ); #else short xwid; short ywid; long size; /* size of image */ xwid = abs( x2 - x1 ) + 1; ywid = abs( y2 - y1 ) + 1; size = (long)ywid * _RowLen( xwid ); return( size + 6L ); #endif } short _RowLen( short pixels ) /*=========================== This routine calculates the number of bytes needed to store one row of pixels. */ { short size; if( _CurrState->misc_info & PLANAR ) { size = ( ( pixels + 7 ) / 8 ) * _CurrState->vc.bitsperpixel; } else { size = ( ( pixels * _CurrState->vc.bitsperpixel + 7 ) / 8 ); } return( size ); }
|  |
 |  |  |
что при палитровом режиме 8 бит на пиксел должно просто стать dx*dy+6 (если я всё правильно понял) и при имитации скрола надо просто копировать эти 6 лишних байтов в правильное место.
P.P.S. В этих 6 байтах запоминаются значения picwidth, picheight и bpp (это если я нагуглил правильные сырцы)...