Making of "VBI gift"



Рассказ будет немного занудным

В качестве поздравления я хотел сделать что-то оригинальное, перепробовал несколько вариантов, но итоги показались неудовлетворительными, поэтому я вспомнил старое демо на Атари и стал искать известную гифку. На счастье мне попалась картинка без JPEG-артефактов.

Вышло немного-немало — всего лишь 288 кадров. Не стоит уповать на 256 сегментов памяти, которых хватит каждому, а нужно немного подумать.

Кадры состоят из 4х цветов, поэтому легко сгенерировать 256 тайлов в формате:

1|2
-+-
3|4


Мне было лень писать код и искать потенциально возникшие ошибки, с помощью PureBasic я сделал так:


*m=AllocateMemory(16384)

For t=0 To 255
  s.s=RSet( Bin(t),8,"0")
    t0=Val("%"+Mid(s,1,2) )*$11
    t1=Val("%"+Mid(s,3,2) )*$11
    t2=Val("%"+Mid(s,5,2) )*$11
    t3=Val("%"+Mid(s,7,2) )*$11
    
;    Debug (t&192)>>6
  For i=0 To 3
    ddi=(t&192)>>6
    PokeA(*m+i*256+8*256*ddi+(t&63)*4+0,t0)
    PokeA(*m+i*256+8*256*ddi+(t&63)*4+1,t0)
    PokeA(*m+i*256+8*256*ddi+(t&63)*4+2,t1)
    PokeA(*m+i*256+8*256*ddi+(t&63)*4+3,t1)
    
    PokeA(1024+*m+i*256+8*256*ddi+(t&63)*4+0,t2)
    PokeA(1024+*m+i*256+8*256*ddi+(t&63)*4+1,t2)
    PokeA(1024+*m+i*256+8*256*ddi+(t&63)*4+2,t3)
    PokeA(1024+*m+i*256+8*256*ddi+(t&63)*4+3,t3)

  Next i
    Debug Mid(s,5,2)+":"+Mid(s,7,2)+"-"+s
  
Next t

CreateFile(0,"tileset.dat")
WriteData(0,*m,16384)
CloseFile(0)

FreeMemory(*m)

На первый взгляд тайлы выглядят как задуманные, следующий шаг был в подготовке карты тайлов:


c0=RGB(000,000,000);черный
c1=RGB(255,255,255);белый
c2=RGB(040,000,184);синий
c3=RGB(216,064,096);розовый


Dim tm.a(256,64)


For i=0 To 287

;Debug "IMG00"+RSet(Str(i),3,"0")+".bmp"

LoadImage(0,"IMG00"+RSet(Str(i),3,"0")+".bmp")

;01
;23

;1234

StartDrawing( ImageOutput(0) )
For y=0 To 32
  For x=0 To 40-1
    
    cl=Point(x*8,y*8)
    t1.a=0
    If cl=c0:t1=0:EndIf
    If cl=c1:t1=1:EndIf
    If cl=c2:t1=2:EndIf
    If cl=c3:t1=3:EndIf
    
    cl=Point(x*8+4,y*8)
    t2.a=0
    If cl=c0:t2=0:EndIf
    If cl=c1:t2=1:EndIf
    If cl=c2:t2=2:EndIf
    If cl=c3:t2=3:EndIf
    
    cl=Point(x*8,y*8+4)
    t3.a=0
    If cl=c0:t3=0:EndIf
    If cl=c1:t3=1:EndIf
    If cl=c2:t3=2:EndIf
    If cl=c3:t3=3:EndIf
    
    cl=Point(x*8+4,y*8+4)
    t4.a=0
    If cl=c0:t4=0:EndIf
    If cl=c1:t4=1:EndIf
    If cl=c2:t4=2:EndIf
    If cl=c3:t4=3:EndIf
    
    tm(x,y)=(t4+( t3<<2 ) + ( t2<<4 ) + ( t1<<6) )
Next x
Next y

StopDrawing()

CreateFile(0,Str(i)+".bin")
For y=0 To 63
For x=0 To 127
  WriteAsciiCharacter( 0,tm(x,y) )
  WriteAsciiCharacter( 0,0 )
  tm(x,y)=0
Next x
Next y
CloseFile(0)

Next i

Еще одна порция индусского кода (:

Теперь картинка выглядит как кадр, но тайловая карта для страницы весит 16384 байта. Сжимаю zx7, получаю примерно 200 байт.

Дальнейшее — дело техники, нужно раскидать по папкам сжатые файлы так, чтобы они вместились в страницу.

Сделано, Все занудные incbin'ы с количеством цифр сгенерированы с помощью одной утилитки, которую я написал под такие нужды.
Несколько внесений в код и каратека пляшет. Не помешала бы надпись Happy Birthday! Спрайты мне в помощь.

Из анимированных шрифтов мне понравился этот вариант. На удачу у букв есть 8 фаз. Поэтому мне удобнее подготовить единый битмап срайта и переключать страничку для него в одно прерывание.
Делалось это просто — картинки масштабируются с помощью GIFresize, гифки разбиваются на кадры и пишется программа, которая создает анимацию:


CreateImage(0,512,640)

StartDrawing(ImageOutput(0))

Box(0,0,512,640,RGB(255,0,255)*0)

s.s="happy__birthday"

For n=0 To 7
For i=1 To Len(s)
  
  nn=(n+i)&7
  LoadImage(1,Mid(s,i,1)+"\IMG0000"+Str(nn)+".bmp")
  
  DrawImage(ImageID(1),i*32-32,n*64)
Next i

Next n


StopDrawing()

SaveImage(0,"hbs.bmp")


Вышла примерно такая картинка:


картинка сделана так, чтобы битмап спрайтов просто сконвертировался, жаль, что слово VBI никак не втиснулся:(

.ini для сборки .spg выглядел так:

; Blocks description: address (512 multiple, #C000-#FE00), page number, filename
Block = #E000,5,gift.bin

;song
Block = #C000,2,part2.bin

;tilemap
;Block = #C000,#11,frames\0.bin
Block = #C000,#10,frames\tileset.dat

;animation
Block = #C000,#20,anim0.bin
Block = #C000,#21,anim1.bin
Block = #C000,#22,anim2.bin
Block = #C000,#23,anim3.bin
Block = #C000,#24,anim4.bin

;sprites
Block = #C000,#28,_alpha\hbs0.bin
Block = #C000,#30,_alpha\hbs1.bin
Block = #C000,#38,_alpha\hbs2.bin
Block = #C000,#40,_alpha\hbs3.bin
Block = #C000,#48,_alpha\hbs4.bin
Block = #C000,#50,_alpha\hbs5.bin
Block = #C000,#58,_alpha\hbs6.bin
Block = #C000,#60,_alpha\hbs7.bin


Остальной код не буду приводит, он содержит простые установки нужных значений, воспроизведение музыки, распаковку данных для тайловой карты.

Сднем Рождения еще раз, Вова!

1 комментарий

avatar
Уважуха автору и повторные сердечные поздравления дяде Вове! )
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.