Я сделал нечто похожее еще в 90-х, используя два разных подхода.
Первый связан с «оконным режимом», который поддерживается стандартом VESA SVGA. Некоторые карты реализовали это правильно. По сути, если бы у вас был кадровый буфер / видеопамять больше, чем отображаемая область, вы могли бы нарисовать большое растровое изображение и дать системные координаты для окна в той области, которую вы хотите отобразить. Изменяя эти координаты, вы можете прокручивать без необходимости заново заполнять буфер кадра.
Другой метод основывался на манипулировании методом BLT, используемым для получения завершенного кадра в буфер кадров. Перетаскивание страницы в буфер кадров, который был того же размера, что и экран, является простым и эффективным.
Я нашел этот старый код ассемблера 286 (на работающей 17-летней дискете!), Который копировал экран размером 64000 байт (320x200) со страницы вне экрана в видеобуфер:
Procedure flip; assembler;
{ This copies the entire screen at "source" to destination }
asm
push ds
mov ax, [Dest]
mov es, ax
mov ax, [Source]
mov ds, ax
xor si, si
xor di, di
mov cx, 32000
rep movsw
pop ds
end;
rep movsw
перемещенные слова CX (где слово в данном случае составляет два байта). Это было очень эффективно, так как это в основном единственная инструкция, которая указывает процессору перемещать все как можно быстрее.
Однако, если бы у вас был больший буфер (скажем, 1024 * 200 для боковой скроллера), вы могли бы так же легко использовать вложенный цикл и копировать одну строку пикселей на цикл. Например, в буфере шириной 1024 пикселя можно скопировать байты:
start count
0+left 320
1024+left 320
...
255*1024+left 320
, где left
- это координата x в большом фоновом изображении, с которого вы хотите начать (с левой стороны экрана).
Конечно, в 16-битном режиме требовалось некоторое волшебство и манипулирование указателями сегментов (ES, DS), чтобы получить буфер размером более 64 КБ (в действительности это несколько смежных буферов по 64 КБ), но это работало довольно хорошо.
Вероятно, были и более эффективные решения этой проблемы (и определенно более подходящие для использования сегодня), но это помогло мне.