Я давно интересовался вопросом конверсии графики, и нашел подходящее время. Сначала я решил попробовать так, как делает ААА: преобразовать картинку в формат GIF и в редакторе поменять палитру на значения, схожие к ZX Spectrum. Не получилось:(, поэтому я решил попробовать обходной путь. Что такое режим HiRes? это экран разрешением 320х200 и с двумя цветами для блоков 8х8 - похоже на Спектрум. Я решил выгрузить данные из памяти и нарисовать на экране. Для выгрузки понадобится C64 Debugger - запустить программу, перетащить .prg или образ диска d64(понадобится загрузка программы с диска) и дождаться появления картинки. У отладчика есть одно удобство - экран можно сохранить на диск, нажав Ctrl+Shift+E. получится файл filename.art размером 9003 байт, формат которого уже известен:
адрес(2 байта) $2000
монохром 8000 байт
цвета 1000 байт.
Формат расположения точек мне уже известен, так как разбирался сам, поэтому опишу его:
Расположение адреса в памяти определяется значением регистра $D018. Первые 8 байт описывают блок справа слева:
Следующие 8 байт - блок справа, и так далее до блока номер 40. Нетрудно посчитать, что линия "знакомест" займет 40*8=320 байт. При рисовании на экране Спектрума нужно учесть, что надо уместить 40 "знакомест", к тому же надо пропустить несколько рядов:
xdisp=4
ld hl,pic+xdisp*8; пропустить 4 блока
ld de,$4000;начальный адрес
rowlp:
push hl; запомнить адрес памяти картинки, для перехода на 320 байт
linelp:
ld b,8;рисование знакомест
push de
chlp:
ld a,(hl)
ld (de),a
inc hl,d
djnz chlp
pop de
inc e
ld a,e
and 31
jr nz,linelp ; завершение цикла линии
ld hl,pic+xdisp*8; пропустить 4 блока
ld de,$4000;начальный адрес
rowlp:
push hl; запомнить адрес памяти картинки, для перехода на 320 байт
linelp:
ld b,8;рисование знакомест
push de
chlp:
ld a,(hl)
ld (de),a
inc hl,d
djnz chlp
pop de
inc e
ld a,e
and 31
jr nz,linelp ; завершение цикла линии
pop hl; перейти к данным следующей линии знакомест
ld bc,320
add hl,bc
inc e
dec e
jr nz,rowlp ; проверка на завершение 8 линий на экране
ld a,d ; переход к следующей части экрана
add a,8
ld d,a
cp $58
jr nz,rowlp
;...
pic:
incbin"fishyfishy.art",2 ; пропустить два байта в файле.
Теперь осталось самое сложное - цвета.Палитра C64 состоит из 16 значений:
цвет "знакоместа" описывается одним байтом: старший ниббл - цвет для точек, младший ниббл - для фона.Я решил использовать таблицу значений замены цветов на значения Спектрум, но получилось, что из-за совпадения цветов потерялась часть знакомест, поэтому я добавил к скрытым знакоместам аттрибут Flash - все равно придется править конверсию.
;fill colors
ld hl,pic+8000+xdisp
ld de,$5800
ld a,24
alpy:
exa
alpx:
;ink
ld a,(hl)
and $F0
srl a
srl a
srl a
srl a
ld c,a,b,0,ix,zxc
add ix,bc
ld c,(ix+0)
;paper
ld a,(hl)
and $0F
push bc
ld c,a,b,0,ix,zxc
add ix,bc
pop bc
ld a,(ix+0)
and 7
add a,a
add a,a
add a,a
or c
ld c,a
ld a,(ix+0)
and 192
or c
ld c,a
;equal colors?
ld a,c:and $3F:cp 0*9:jr nz,bra1
ld a,c:and 192:or 7:ld c,a
bra1:
ld a,c:and $3F:cp 1*9:jr nz,bra2
ld a,c:and 192:or 1:ld c,a
bra2:
ld a,c:and $3F:cp 2*9:jr nz,bra3
ld a,c:and 192:or 2:ld c,a
bra3:
ld a,c:and $3F:cp 3*9:jr nz,bra4
ld a,c:and 192:or 3:ld c,a
bra4:
ld a,c:and $3F:cp 4*9:jr nz,bra5
ld a,c:and 192:or 4:ld c,a
bra5:
ld a,c:and $3F:cp 5*9:jr nz,bra6
ld a,c:and 192:or 5:ld c,a
bra6:
ld a,c:and $3F:cp 6*9:jr nz,bra7
ld a,c:and 192:or 6:ld c,a
bra7:
ld a,c:and $3F:cp 7*9:jr nz,bra_
ld a,c:and 192:or 7:ld c,a
bra_:
ld a,c
ld (de),a
inc hl
inc de
ld a,e
and 31:jp nz,alpx
ld bc,8:add hl,bc
exa
dec a
jp nz,alpy
jr $
zxc:
db 0;0
db 7;1
db 2;2
db 5;3
db 3;4
db 4;5
db 1;6
db 6;7
db 6;8
db $6;9
db $42;10
db $C7;11
db $7;12
db $44;13
db $41;14
db $47;15
pic:
incbin"house.art",2
Не все так прошло гладко. Например, отладчик для картинки fishyfishy сохранил не привычный формат .art, а вывалил отдельно charset и rawtext. Поэтому я рискнул сделать другое: сохранил память(Ctrl+U) и вытащил отдельные данные
*m=AllocateMemory(65536) ;отведение памяти
ReadFile(0,"fishmem.bin");загрузка блока
ReadData(0,*m,65536)
CloseFile(0)
CreateFile(0,"fishyfishy.art");сохранение файла fishyfishy.art
WriteWord(0,$2000) ; адрес
WriteData(0,*m+$2000,8000) : запись пикселей
WriteData(0,*m+$400,1000) ; запись цветов
WriteAsciiCharacter(0,$0B) ; дополнительный байт - цвет рамки
CloseFile(0)
FreeMemory(*m)
ReadFile(0,"fishmem.bin");загрузка блока
ReadData(0,*m,65536)
CloseFile(0)
CreateFile(0,"fishyfishy.art");сохранение файла fishyfishy.art
WriteWord(0,$2000) ; адрес
WriteData(0,*m+$2000,8000) : запись пикселей
WriteData(0,*m+$400,1000) ; запись цветов
WriteAsciiCharacter(0,$0B) ; дополнительный байт - цвет рамки
CloseFile(0)
FreeMemory(*m)
Адреса $2000 и $400 могут быть другими, для поиска придется изучать саму программу.
Конечно, конверсия не всегда проходит гладко:
картинка Do not touch me
Но есть формат и похлеще:
Может быть, после правки цветов я научусь рисовать? (: Файлы тут.
Комментарии
Отправить комментарий