Рипнуть картинку с С64

 


ААА выпустил новое демо - простой запил со сменой картинок, который просто умоляет сделать красивый эффект со сменой монохромных картинок. Меня заинтересовало изображение котика, я поинтересовался источником. Оказалось, что использовался Blowback / Sulevi.

Запустил C64 Debugger, выгрузил память и стал изучать. Определить расположение картинки оказалось легким - в дизассемблере отображается запись значения в $D018 - значит адрес bitmap mode расположен в $2000.  Режим я уже изучал раньше, поэтому знал, как расположены данные: в $2000-$2007 хранятся данные линий для знакоместа, $2008 - следующее знакоместо, и так далее.

Написал программу на PureBasic:


Это всего лишь черновик, поэтому программу надо усовершенствовать, но у меня не было данных RGB для 16 цветов.Поэтому я написал код на ужасме, дополнив обработку атрибутов:

device zxspectrum128
        ORG #6000
begin
ld hl,bincat
ld de,$4000
xlp:
push de
ld b,8
chlp:
ld a,(hl),(de),a
inc hl,d
djnz chlp
pop de
inc e
ld a,e
and 31
jr nz,xlp
ld bc,64
add hl,bc
inc e
dec e
jr nz,nodn
ld a,d
add a,8
ld d,a
nodn
ld a,d
cp $58
jr nz,xlp

ld hl,catc
ld de,$5800
alp:
ld bc,32
ldir
ld bc,8
add hl,bc
ld a,d
cp $5b
jr nz,alp
;check colors
ld hl,$5800
chelp:
ld bc,0
ld a,(hl)
and $F0
cp $30
jr nz,bra1
ld b,5
bra1
cp $E0
jr nz,bra2
ld b,0
bra2
ld a,(hl)
and $0F
cp $3
jr nz,bra3
ld b,5*8
bra3
cp $E
jr nz,bra4
ld b,0
bra4
ld a,b
or c
ld (hl),a
inc hl
ld a,h
cp $5B
jr nz,chelp
jr $
bincat:incbin "2000.bin"
catc:incbin "400.bin"
end
display /d,end-begin
savesna "!void.sna",begin


Здесь 2000.bin, 400.bin это отдельно выдранные данные из дампа.


Ой, как мило! Я полез за следующими картинками, но тут меня ждал облом - куча цветов. Поэтому я немного изменил программу, которая только выгружает картинку:

*m=AllocateMemory(65536)
Dim co64.l(15)
co64(0)= 0
co64(1) = $FFFFFF
co64(2) = RGB(137,64,54);$924A40
co64(3) = RGB(112,164,178);$68d0a8
co64(4) = RGB(141,71,179);$9351B6
co64(5) = RGB(104,169,65);$72B14B
co64(6) = RGB(62,49,162);$483AAA
co64(7) = RGB(208,220,113);$D5DF7C
co64(8) = RGB(144,95,37);$675200
co64(9) = RGB(92,71,0);$C33D00
co64(10) = RGB(240,143,166);$C18178
co64(11) = RGB(68,68,68);$606060
co64(12) = RGB(128,128,128);$8A8A8A
co64(13) = RGB(154,210,132);$B3EC91
co64(14) = $003f00;$867ADE
co64(15) = $B3B3B3

CreateImage(0,320,200)
If OpenWindow(0, 0, 0, 640, 480, "CanvasGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  CanvasGadget(0, 0, 0, 640, 480)
  
  f$="amza"
  ReadFile(0,f$+".bin")
  ReadData(0,*m,65536)
  CloseFile(0)
  StartDrawing(ImageOutput(0))
  ;Box(0,0,640,480,$ffffff)
  ofs=$2000
  
  For y=0 To 24
    For x=0 To 39
      For j=0 To 7
        a.a=PeekA(*m+ofs)
        ca.a=PeekA(*m+1024+x+y*40)
        coff=co64(ca&15)
        con=co64((ca>>4)&15)
        ofs+1
        b.a=128
        For i=0 To 7
          If a&b
            col=con
          Else
            col=coff
          EndIf
          Box((i+x*8),(j+y*8),1,1,col)
          b>>1
        Next i
      Next j
    Next x
  Next y
  ;Debug Hex(ofs-$2000)
  StopDrawing()
  StartDrawing(CanvasOutput(0))
  DrawImage(ImageID(0),0,0,640,400)
  StopDrawing()
  SaveImage(0,f$+".bmp")
  Repeat
    Event = WaitWindowEvent()
    
  Until Event = #PB_Event_CloseWindow
EndIf

Здесь f$ - имя переменной для загрузки бинаря и сохранения картинки с таким именем. Значение переменной ofs может изменяться - это зависит от кода. Атрибуты тоже хранились вразнобой, поэтому адрес пришлось менять для каждой картинки.

С цветами вышла полная засада - мне так и не удалось задать все 16 значений для цветов. Кроме того, при показе цветов картинка выглядит по-другому. Я пока оставлю эту заготовку на будущее.

Комментарии