[Windows x64] mpix256 a tiny - 8 bit, 256 color example gfx lib

Bare metal programming in PureBasic, for experienced users
User avatar
Mijikai
Addict
Addict
Posts: 1359
Joined: Sun Sep 11, 2016 2:17 pm

[Windows x64] mpix256 a tiny - 8 bit, 256 color example gfx lib

Post by Mijikai »

mpix256 is a tiny example gfx library that shows (one way) how to realize 8 bit 256 color palette gfx on windows.

It uses good old StretchDIBits() for the color translation and drawing.
I originally wrote this as exercise, maybe its useful for someone :)

Note: In PB Import "mpix256.obj" or Import "mpix256.lib"

Updated 25.01.2023
Updated 14.08.2023 - bug fix (drawing with the c backend)

Commented source (fasm v.1.73.30):

Alpha 2:

Code: Select all

;mpix256 - 256 colors @ 256 x 256 pixels

;basic example on 8 bit - 256 color palette gfx
;author: mijikai

;version alpha 02

;changes/improvements:

;- fixed a bug in mpixDevice() & mpixBuffer() / hwnd & buffersize was not returned
;- removed the need to link to msvcrt / LocalAlloc() LocalFree() are perfectly fine and cooler :)
;- mpixPixelDraw() now uses a struct instead of several variables
;- replaced the locals with the local macro (no need to zero the variable if it is not needed)
;- the frame macro is now used to improve the stack reservation

format MS64 COFF;<- 64 bit!
include 'win64w.inc';<- use the win x64 wchar macros provided by fasm

extrn GetDC;<- all the win api functions used
extrn ReleaseDC
extrn StretchDIBits
extrn LocalAlloc
extrn LocalFree

public mpixCreate;<- all the exported functions
public mpixDevice
public mpixBuffer
public mpixPalette
public mpixPaletteSet
public mpixPaletteGet
public mpixPixelClear
public mpixPixelSet
public mpixPixelGet
public mpixPixelDraw
public mpixRelease
public mpixVersion

section '.code' code readable executable;<- where code lives

        proc mpixCreate;(hwnd)
             local .hwnd        :QWORD
             frame                                      ;<- reserve space on the stack once
             mov [.hwnd],rcx                            ;<- store the supplied window handle into [hwnd]
             fastcall mpixRelease                       ;<- reset and release the old device!
             fastcall LocalAlloc,LPTR,0x10000           ;<- allocate the pixel buffer (256 x 256)
             test rax,rax                               ;<- was the buffer allocated?
             jz mpixCreate_error                        ;<- if there was an error return
             mov [surface],rax                          ;<- store the pointer to the pixel buffer into [surface]
             fastcall GetDC,qword[.hwnd]                ;<- get a device handle from the window (note: better check the device capabilities!)
             test rax,rax                               ;<- check if the device handle was obtained
             jz mpixCreate_error                        ;<- return on error
             mov rcx,[.hwnd]                            ;<- load hwnd from [hwnd]
             mov [window],rcx                           ;<- store the window handle into [window]
             mov [device],rax                           ;<- store the device handle into [device]
             xor rcx,rcx                                ;<- set the clear color $0 = black
             fastcall mpixPixelClear,rcx                ;<- clear all pixels
             mov rax,0x1                                ;<- mov 1 = true into the return register
             jmp mpixCreate_return                      ;
             mpixCreate_error:                          ;<- something went wrong continue execution here
             fastcall mpixRelease                       ;<- clean up if anything went wrong
             mpixCreate_return:                         ;
             endf                                       ;
             ret                                        ;<- return
        endp

        proc mpixDevice;(*Hwnd)
             test rcx,rcx                               ;<- if the first parameter is set (pointer to a variable) return the window handle
             jz @f                                      ;<- no pointer just return the device handle
             mov rax,[window]                           ;<- grab the window handle
             mov [rcx],rax                              ;<- write the windo handle into the variable pointed to by *Hwnd
             @@:                                        ;<- only return the device handle
             mov rax,[device]                           ;<- mov the device handle into the return register
             ret                                        ;<- return
        endp

        proc mpixBuffer;(*Size)
             test rcx,rcx                               ;<- if the first parameter is set (pointer to a variable) return the pixel buffer size
             jz @f                                      ;<- no parameter just return a pointer to the pixel buffer
             mov qword[rcx],0x10000                     ;<- write the buffer size into the variable pointed to by *Size (hardcoded - it was just a exercise...)
             @@:                                        ;<- only return a pointer to the pixel buffer
             mov rax,[surface]                          ;<- move the buffer handle into the return register
             ret                                        ;<- return
        endp

        proc mpixPalette;(*Palette)
             test rcx,rcx                               ;<- if *Palette is true load it (copy it)
             jz @f                                      ;<- if *Palette is false use the default palette (reset to default)
             mov rsi,rcx                                ;<- pointer to the palette to be loaded
             mov rdi,palette                            ;<- pointer to the palette
             mov rcx,0x100                              ;<- how many colors (256)
             rep movsd                                  ;<- copy all colors
             xor rax,rax                                ;<- clear the return register
             ret                                        ;<- return
             @@:                                        ;<- create the default palette
             mov rcx,0xFF                               ;<- how many colors (0 - 255)
             mov rax,0x400                              ;<- palette size (1024)
             lea rdx,qword[palette]                     ;<- load the pointer to the palette
             @@:                                        ;<- color creation loop
             sub rax,0x4                                ;<- advance to the next palette color
             mov dword[rdx + rax],0x0                   ;<- clear the palette color
             mov byte[rdx + rax + 1],cl                 ;<- make a green color
             dec cl                                     ;<- next green color
             test rax,rax                               ;<- are all color there
             jnz @b                                     ;<- repeat until the whole palette is filled
             ret                                        ;<- return
        endp

        proc mpixPaletteSet;(Index.a,Color.a)
             lea rax,[palette]                          ;<- get a pointer to the palette
             lea rax,[rax + rcx * 0x4]                  ;<- where is the color
             mov dword[rax],edx                         ;<- set the color
             xor rax,rax                                ;<- clear the return register
             ret                                        ;<- return
        endp

        proc mpixPaletteGet;(Index.a,*Color.a)
             lea rax,[palette]                          ;<- get a pointer to the palette
             lea rax,[rax + rcx * 0x4]                  ;<- where is the color
             mov ecx,dword[rax]                         ;<- read the color
             mov dword[rdx],ecx                         ;<- store the color into the variable pointed to by *Color
             xor rax,rax                                ;<- clear the return register
             ret                                        ;<- return
        endp

        proc mpixPixelClear;(Index.a)
             mov rdi,qword[surface]                     ;<- get a pointer to the pixel buffer
             mov rax,rcx                                ;<- clear with color index
             mov rcx,0x10000                            ;<- how many bytes
             repe stosb                                 ;<- clear the buffer
             xor rax,rax                                ;<- clear the return register
             ret                                        ;<- return
        endp

       proc mpixPixelSet;(X.i,Y.i,Index.a)
             cmp rcx,0x0                                ;<- check if the pixel is inside the screen
             jl @f                                      ;
             cmp rdx,0x0                                ;
             jl @f                                      ;
             cmp rcx,0xFF                               ;
             jg @f                                      ;
             cmp rdx,0xFF                               ;
             jg @f                                      ;
             shl rdx,0x8                                ;<- calculate the y offset (y * span)
             mov rax,[surface]                          ;<- get a pointer to the pixel buffer
             lea rcx,[rcx + rdx]                        ;<- calculate the x + y offset
             mov byte[rax + rcx],r8b                    ;<- write the color index into the pixel buffer
             mov rax,0x1                                ;<- return 1 if all went well
             ret                                        ;
             @@:                                        ;
             xor rax,rax                                ;<- return 0 if something went wrong
             ret                                        ;<- return
        endp

        proc mpixPixelGet;(X.i,Y.i,*Index.Ascii)
             cmp rcx,0x0                                ;<- check if the pixel is inside the screen
             jl @f                                      ;
             cmp rdx,0x0                                ;
             jl @f                                      ;
             cmp rcx,0xFF                               ;
             jg @f                                      ;
             cmp rdx,0xFF                               ;
             jg @f                                      ;
             shl rdx,0x8                                ;<- calculate the y offset (y * span)
             mov rax,[surface]                          ;<- get a pointer to the pixel buffer
             lea rcx,[rcx + rdx]                        ;<- calculate the x + y offset
             mov dl,byte[rax + rcx]                     ;<- read the color index from the pixel buffer
             mov byte[r8],dl                            ;<- return the color index to the variable pointed to by *Index
             mov rax,0x1                                ;<- return 1 if all went well
             ret                                        ;
             @@:                                        ;
             xor rax,rax                                ;<- return 0 if something went wrong
             ret                                        ;<- return
        endp

        proc mpixPixelDraw;(X.i,X.i,W.i,H.i)
             local .rect        :RECT                   ;<- rect to draw to
             mov dword[.rect.left],ecx
             mov dword[.rect.top],edx
             mov dword[.rect.right],r8d
             mov dword[.rect.bottom],r9d
             fastcall StretchDIBits,qword[device],[.rect.left],[.rect.top],[.rect.right],[.rect.bottom],0x0,0x0,0x100,0x100,qword[surface],addr layout,0x0,0xCC0020
             ret
        endp

        proc mpixRelease;()
             frame
             cmp qword[surface],0x0
             je mpixRelease_surface
             fastcall LocalFree,qword[surface]                  ;<- clean up the surface (pixel buffer)
             mpixRelease_surface:
             cmp qword[device],0x0
             je mpixRelease_device
             fastcall ReleaseDC,qword[window],qword[device]     ;<- clean up the device handle
             mpixRelease_device:
             mov qword[surface],0x0                             ;<- set everthing to zero
             mov qword[device],0x0
             mov qword[window],0x0
             xor rcx,rcx
             fastcall mpixPalette,rcx                           ;<- clear the palette
             xor rax,rax
             endf
             ret
        endp

        proc mpixVersion;()
             mov eax,0x000002;<- return a hardcoded version number
             ret
        endp

section '.data' data readable writeable;<- where data lives

        window:
                dq 0x00;<- stores the window handle

        device:
                dq 0x00;<- stores the device handle

        layout:
                db 0x28,0x00,0x00,0x00,0x00,0x01,0x00,0x00;<- stores the pixel layout (note: a bitmap info header)
                db 0x00,0xFF,0xFF,0xFF,0x01,0x00,0x08,0x00;<- black magic (note: not really check out StretchDIBits on msdn) :>
                db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00;<- takes care of the 8 -> 32 bit color conversion!
                db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
                db 0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00

        palette:
                rb 0x400;<- palette buffer

        surface:
                dq 0x00;<- stores a pointer to the pixel buffer  
Alpha 1 (DONT USE!):

Code: Select all

;mpix256 - 256 colors @ 256 x 256 pixels

;basic example on 8 bit - 256 color palette gfx
;author: mijikai

format MS64 COFF;<- 64 bit!
include 'win64w.inc';<- use the win x64 wchar macros provided by fasm

extrn GetDC;<- all the win api functions used
extrn ReleaseDC
extrn StretchDIBits
extrn malloc
extrn free

public mpixCreate;<- all the exported functions
public mpixDevice
public mpixBuffer
public mpixPalette
public mpixPaletteSet
public mpixPaletteGet
public mpixPixelClear
public mpixPixelSet
public mpixPixelGet
public mpixPixelDraw
public mpixRelease
public mpixVersion

section '.code' code readable executable;<- where code lives

        proc mpixCreate;(hwnd)
             locals
                hwnd    dq 0x0;<- local variable
             endl
             mov qword[hwnd],rcx;<- store the supplied window handle into [hwnd]
             fastcall mpixRelease;<- reset and release the old device!
             mov rcx,0x10000;<- pixel buffer size (256 x 256)
             fastcall malloc,rcx;<- allocate the pixel buffer
             test rax,rax;<- was the buffer allocated?
             jz @f;<- if there was an error return
             mov qword[surface],rax;<- store the pointer to the pixel buffer into [surface]
             fastcall GetDC,qword[hwnd];<- get a device handle from the window (note: better check the device capabilities!)
             test rax,rax;<- check if the device handle was obtained
             jz @f;<- return on error
             mov rcx,qword[hwnd];<- load hwnd from [hwnd]
             mov qword[window],rcx;<- store the window handle into [window]
             mov qword[device],rax;<- store the device handle into [device]
             xor rcx,rcx;<- set the clear color $0 = black
             fastcall mpixPixelClear,rcx;<- clear all pixels
             mov rax,0x1;<- mov 1 = true into the return register
             ret;<- return
             @@:;<- something went wrong continue execution here
             fastcall mpixRelease;<- clean up if anything went wrong
             ret;<- return
        endp

        proc mpixDevice;(*Hwnd)
             cmp rcx,rcx;<- if the first parameter is set (pointer to a variable) return the window handle
             jz @f;<- no pointer just return the device handle
             mov rax,[window];<- grab the window handle
             mov [rcx],rax;<- write the windo handle into the variable pointed to by *Hwnd
             @@:;<- only return the device handle
             mov rax,qword[device];<- mov the device handle into the return register
             ret;<- return
        endp

        proc mpixBuffer;(*Size)
             cmp rcx,rcx;<- if the first parameter is set (pointer to a variable) return the pixel buffer size
             jz @f;<- no parameter just return a pointer to the pixel buffer
             mov qword[rcx],0x10000;<- write the buffer size into the variable pointed to by *Size (hardcoded - it was just a exercise...)
             @@:;<- only return a pointer to the pixel buffer
             mov rax,qword[surface];<- move the buffer handle into the return register
             ret;<- return
        endp

        proc mpixPalette;(*Palette)
             test rcx,rcx;<- if *Palette is true load it (copy it)
             jz @f;<- if *Palette is false use the default palette (reset to default)
             mov rsi,rcx;<- pointer to the palette to be loaded
             mov rdi,palette;<- pointer to the palette
             mov rcx,0x100;<- how many colors (256)
             rep movsd;<- copy all colors
             xor rax,rax;<- clear the return register
             ret;<- return
             @@:;<- create the default palette
             mov rcx,0xFF;<- how many colors (0 - 255)
             mov rax,0x400;<- palette size (1024)
             lea rdx,qword[palette];<- load the pointer to the palette
             @@:;<- color creation loop
             sub rax,0x4;<- advance to the next palette color
             mov dword[rdx + rax],0x0;<- clear the palette color
             mov byte[rdx + rax + 1],cl;<- make a green color
             dec cl;<- next green color
             test rax,rax;<- are all color there
             jnz @b;<- repeat until the whole palette is filled
             ret;<- return
        endp

        proc mpixPaletteSet;(Index.a,Color.a)
             lea rax,[palette];<- get a pointer to the palette
             lea rax,[rax + rcx * 0x4];<- where is the color
             mov dword[rax],edx;<- set the color
             xor rax,rax;<- clear the return register
             ret;<- return
        endp

        proc mpixPaletteGet;(Index.a,*Color.a)
             lea rax,[palette];<- get a pointer to the palette
             lea rax,[rax + rcx * 0x4];<- where is the color
             mov ecx,dword[rax];<- read the color
             mov dword[rdx],ecx;<- store the color into the variable pointed to by *Color
             xor rax,rax;<- clear the return register
             ret;<- return
        endp

        proc mpixPixelClear;(Index.a)
             mov rdi,qword[surface];<- get a pointer to the pixel buffer
             mov rax,rcx;<- clear with color index
             mov rcx,0x10000;<- how many bytes
             repe stosb;<- clear the buffer
             xor rax,rax;<- clear the return register
             ret;<- return
        endp

       proc mpixPixelSet;(X.i,Y.i,Index.a)
             cmp rcx,0x0;<- check if the pixel is inside the screen
             jl @f
             cmp rdx,0x0
             jl @f
             cmp rcx,0xFF
             jg @f
             cmp rdx,0xFF
             jg @f
             shl rdx,0x8;<- calculate the y offset (y * span)
             mov rax,qword[surface];<- get a pointer to the pixel buffer
             lea rcx,[rcx + rdx];<- calculate the x + y offset
             mov byte[rax + rcx],r8b;<- write the color index into the pixel buffer
             mov rax,0x1;<- return 1 if all went well
             ret
             @@:
             xor rax,rax;<- return 0 if something went wrong
             ret
        endp

        proc mpixPixelGet;(X.i,Y.i,*Index.Ascii)
             cmp rcx,0x0;<- check if the pixel is inside the screen
             jl @f
             cmp rdx,0x0
             jl @f
             cmp rcx,0xFF
             jg @f
             cmp rdx,0xFF
             jg @f
             shl rdx,0x8;<- calculate the y offset (y * span)
             mov rax,qword[surface];<- get a pointer to the pixel buffer
             lea rcx,[rcx + rdx];<- calculate the x + y offset
             mov dl,byte[rax + rcx];<- read the color index from the pixel buffer
             mov byte[r8],dl;<- return the color index to the variable pointed to by *Index
             mov rax,0x1;<- return 1 if all went well
             ret
             @@:
             xor rax,rax;<- return 0 if something went wrong
             ret
        endp

        proc mpixPixelDraw;(X.i,X.i,W.i,H.i)
             locals
                x       dq 0x0;<- the function draws the pixel buffer (the palette is used to translate the colors)
                y       dq 0x0;(note: check out msdn for details)
                w       dq 0x0
                h       dq 0x0
             endl
             mov qword[x],rcx
             mov qword[y],rdx
             mov qword[w],r8
             mov qword[h],r9
             fastcall StretchDIBits,qword[device],qword[x],qword[y],qword[w],qword[h],0x0,0x0,0x100,0x100,qword[surface],addr layout,0x0,0xCC0020
             ret
        endp

        proc mpixRelease;()
             cmp qword[surface],0x0
             je @f
                fastcall free,qword[surface];<- clean up the surface (pixel buffer)
             @@:
             cmp qword[device],0x0
             je @f
                fastcall ReleaseDC,qword[window],qword[device];<- clean up the device handle
             @@:
             mov qword[surface],0x0;<- set everthing to zero
             mov qword[device],0x0
             mov qword[window],0x0
             xor rcx,rcx
             fastcall mpixPalette,rcx;<- clear the palette
             xor rax,rax
             ret
        endp

        proc mpixVersion;()
             mov eax,0x000001;<- return a hardcoded version number
             ret
        endp

section '.data' data readable writeable;<- where data lives

        window:
                dq 0x00;<- stores the window handle

        device:
                dq 0x00;<- stores the device handle

        layout:
                db 0x28,0x00,0x00,0x00,0x00,0x01,0x00,0x00;<- stores the pixel layout (note: a bitmap info header)
                db 0x00,0xFF,0xFF,0xFF,0x01,0x00,0x08,0x00;<- black magic (note: not really check out StretchDIBits on msdn) :>
                db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00;<- takes care of the 8 -> 32 bit color conversion!
                db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
                db 0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00

        palette:
                rb 0x400;<- palette buffer

        surface:
                dq 0x00;<- stores a pointer to the pixel buffer 
PureBasic example:

Code: Select all

EnableExplicit

Import "mpix256.lib"
  mpixCreate.i(WindowHandle.i = #Null)
  mpixDevice.i(*WindowHandle.Integer = #Null)
  mpixBuffer.i(*BufferSize.Integer = #Null)
  mpixPalette.i(*Palette = #Null)
  mpixPaletteSet.i(Index.a,Color.l)
  mpixPaletteGet.i(Index.a,*Color.Long)
  mpixPixelClear.i(Index.a)
  mpixPixelSet.i(X.i,Y.i,Index.a)
  mpixPixelGet.i(X.i,Y.i,*Index.Ascii)
  mpixPixelDraw.i(X.i,Y.i,Width.i,Height.i)
  mpixRelease.i()
  mpixVersion.i()
EndImport

#MPIX_VERSION = $000001

Procedure.i Main()
  Protected exit.i
  If OpenWindow(0,#Null,#Null,640,400,#Null$,#PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_MinimizeGadget)
    If mpixCreate(WindowID(0))
      mpixPaletteSet(250,$FF00FF)
      Repeat
        Repeat
          Select WindowEvent()
            Case #Null
              Break
            Case #PB_Event_CloseWindow
              exit = #True
          EndSelect
        ForEver
        mpixPixelClear(255)
        mpixPixelSet(100,100,250)     
        mpixPixelDraw(0,0,640,400)
      Until exit
      mpixRelease()
    EndIf
    CloseWindow(0)  
  EndIf
  ProcedureReturn #Null
EndProcedure

Main()

End
Have fun!
Last edited by Mijikai on Mon Aug 14, 2023 1:24 pm, edited 5 times in total.
User avatar
idle
Addict
Addict
Posts: 4984
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: [Windows x64] mpix256 a tiny - 8 bit, 256 color example gfx lib

Post by idle »

definitely useful as a practical means of using fasm.
User avatar
luis
Addict
Addict
Posts: 3876
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: [Windows x64] mpix256 a tiny - 8 bit, 256 color example gfx lib

Post by luis »

Interesting, thank you very much.
"Have you tried turning it off and on again ?"
A little PureBasic review
User avatar
Mijikai
Addict
Addict
Posts: 1359
Joined: Sun Sep 11, 2016 2:17 pm

Re: [Windows x64] mpix256 a tiny - 8 bit, 256 color example gfx lib

Post by Mijikai »

Thank you for the replies, i updated the first post with a new version.
User avatar
Mijikai
Addict
Addict
Posts: 1359
Joined: Sun Sep 11, 2016 2:17 pm

Re: [Windows x64] mpix256 a tiny - 8 bit, 256 color example gfx lib

Post by Mijikai »

Functions for Sprites :)

Demo:

Code: Select all


;FUNCTIONS TO PLAY AROUND WITH :)

;Basic (unoptimized) raster functions to:
;- draw a rect
;- draw a sprite 
;- draw a scaled sprite

;Note:
;Even thought the functions are unoptimized they should be ok for 256 x 256 ;)
;Sprites are represented as Index-Tables into the Palette.

EnableExplicit

Import "mpix256.obj"
  mpixCreate.i(WindowHandle.i = #Null)
  mpixDevice.i(*WindowHandle.Integer = #Null)
  mpixBuffer.i(*BufferSize.Integer = #Null)
  mpixPalette.i(*Palette = #Null)
  mpixPaletteSet.i(Index.a,Color.l)
  mpixPaletteGet.i(Index.a,*Color.Long)
  mpixPixelClear.i(Index.a = #Null)
  mpixPixelSet.i(X.i,Y.i,Index.a)
  mpixPixelGet.i(X.i,Y.i,*Index.Ascii)
  mpixPixelDraw.i(X.i,Y.i,Width.i,Height.i)
  mpixRelease.i()
  mpixVersion.i()
EndImport

#MPIX_VERSION = $000002

Procedure.i mpixDrawRect(X.i,Y.i,Width.i,Height.i,Color.i,Center.i = #False)
  Protected px.i
  Protected py.i
  If Center
    X - (Width >> 1)
    Y - (Height >> 1)
  EndIf
  Width - 1
  Height - 1
  For py = 0 To Height
    For px = 0 To Width
      mpixPixelSet(X + px,Y + py,Color);<- faster would be to draw entire spans (but for that we would need a clipper)
    Next
  Next
  ProcedureReturn #Null
EndProcedure

Procedure.i mpixDrawSprite(*Source.Ascii,X.i,Y.i,Width.i,Height.i,Center.i = #False)
  Protected px.i
  Protected py.i
  If Center
    X - (Width >> 1)
    Y - (Height >> 1)
  EndIf
  Width - 1
  Height - 1
  For py = 0 To Height
    For px = 0 To Width
      If *Source\a;<- color 0 aka. color-index 0 is transparent!
        mpixPixelSet(X + px,Y + py,*Source\a)
      EndIf
      *Source + 1
    Next
  Next
  ProcedureReturn #Null
EndProcedure

Procedure.i mpixDrawSpriteTint(*Source.Ascii,X.i,Y.i,Width.i,Height.i,Color.i,Center.i = #False)
  Protected px.i
  Protected py.i
  If Center
    X - (Width >> 1)
    Y - (Height >> 1)
  EndIf
  Width - 1
  Height - 1
  For py = 0 To Height
    For px = 0 To Width
      If *Source\a;<- color 0 aka. color-index 0 is transparent!
        mpixPixelSet(X + px,Y + py,Color)
      EndIf
      *Source + 1
    Next
  Next
  ProcedureReturn #Null
EndProcedure

Procedure.i mpixDrawSpriteEx(*Source.Ascii,X.i,Y.i,Width.i,Height.i,Scale.i,Center.i = #False)
  Protected px.i
  Protected py.i
  If Center
    X - ((Width * Scale) >> 1)
    Y - ((Height * Scale) >> 1)
  EndIf
  Width - 1
  Height - 1
  For py = 0 To Height
    For px = 0 To Width
      If *Source\a;<- color 0 aka. color-index 0 is transparent!
        mpixDrawRect(X + (px * Scale),Y + (py * Scale),Scale,Scale,*Source\a,#False)
      EndIf
      *Source + 1
    Next
  Next
  ProcedureReturn #Null
EndProcedure

Procedure.i mpixDrawSpriteExTint(*Source.Ascii,X.i,Y.i,Width.i,Height.i,Scale.i,Color.i,Center.i = #False)
  Protected px.i
  Protected py.i
  If Center
    X - ((Width * Scale) >> 1)
    Y - ((Height * Scale) >> 1)
  EndIf
  Width - 1
  Height - 1
  For py = 0 To Height
    For px = 0 To Width
      If *Source\a;<- color 0 aka. color-index 0 is transparent!
        mpixDrawRect(X + (px * Scale),Y + (py * Scale),Scale,Scale,Color,#False)
      EndIf
      *Source + 1
    Next
  Next
  ProcedureReturn #Null
EndProcedure

Procedure.i mpixMouse(*Rect.RECT,*X.Integer,*Y.Integer)
 Protected pos.POINT
 pos\x = WindowMouseX(0);<- get the mouse position
 pos\y = WindowMouseY(0)
 If PtInRect_(*Rect,PeekL(@pos));<- check if the mouse is inside the window
   *X\i = pos\x >> 1;<- translate the window coordinates into screen coordinates
   *Y\i = pos\y >> 1
   ProcedureReturn #True
 EndIf
 ProcedureReturn #False
EndProcedure

Procedure.i Main()
  Protected size.RECT
  Protected mx.i
  Protected my.i
  size\right = 512
  size\bottom = 512
  If OpenWindow(0,size\left,size\top,size\right,size\bottom,"Demo",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
    AddWindowTimer(0,0,10);<- very basic timing
    If mpixCreate(WindowID(0))
      mpixPaletteSet(1,$FF4242);<- put some colors into the palette (default is some greenscale - see source code)
      mpixPaletteSet(2,$FFFFFF)
      mpixPaletteSet(3,$42FFFF)
      Repeat
        Select WaitWindowEvent()
          Case #PB_Event_Timer
            mpixMouse(@size,@mx,@my)
            mpixPixelClear()
            mpixDrawRect(127,127,16,16,3,#True)
            mpixDrawSprite(?sprite,200,100,8,8)
            mpixDrawSpriteTint(?sprite,200,200,8,8,255)
            mpixDrawSpriteEx(?sprite,60,60,8,8,5,#True)
            mpixDrawSpriteExTint(?sprite,60,60,8,8,5,2,#False)
            mpixDrawSpriteEx(?sprite,mx,my,8,8,8,#True)
            mpixPixelDraw(size\left,size\top,size\right,size\bottom)
          Case #PB_Event_CloseWindow
            Break
        EndSelect 
      ForEver
      mpixRelease()
    EndIf
    CloseWindow(0)
  EndIf
  ProcedureReturn #Null
EndProcedure

Main()

End

DataSection
  sprite:;8x8
  Data.a 0,0,1,1,1,1,0,0
  Data.a 0,1,0,0,0,0,1,0
  Data.a 1,0,1,0,0,1,0,1
  Data.a 1,0,0,0,0,0,0,1
  Data.a 1,0,1,0,0,1,0,1
  Data.a 1,0,1,1,1,1,0,1
  Data.a 0,1,0,0,0,0,1,0
  Data.a 0,0,1,1,1,1,0,0  
EndDataSection

User avatar
Mijikai
Addict
Addict
Posts: 1359
Joined: Sun Sep 11, 2016 2:17 pm

Re: [Windows x64] mpix256 a tiny - 8 bit, 256 color example gfx lib

Post by Mijikai »

Functions for text rendering :)

Demo:

Code: Select all

EnableExplicit

Import "mpix256.obj"
  mpixCreate.i(WindowHandle.i = #Null)
  mpixDevice.i(*WindowHandle.Integer = #Null)
  mpixBuffer.i(*BufferSize.Integer = #Null)
  mpixPalette.i(*Palette = #Null)
  mpixPaletteSet.i(Index.a,Color.l)
  mpixPaletteGet.i(Index.a,*Color.Long)
  mpixPixelClear.i(Index.a = #Null)
  mpixPixelSet.i(X.i,Y.i,Index.a)
  mpixPixelGet.i(X.i,Y.i,*Index.Ascii)
  mpixPixelDraw.i(X.i,Y.i,Width.i,Height.i)
  mpixRelease.i()
  mpixVersion.i()
EndImport

#MPIX_VERSION = $000002

Procedure.i mpixDrawRect(X.i,Y.i,Width.i,Height.i,Color.i,Center.i = #False)
  Protected px.i
  Protected py.i
  If Center
    X - (Width >> 1)
    Y - (Height >> 1)
  EndIf
  Width - 1
  Height - 1
  For py = 0 To Height
    For px = 0 To Width
      mpixPixelSet(X + px,Y + py,Color);<- faster would be to draw entire spans (but for that we would need a clipper)
    Next
  Next
  ProcedureReturn #Null
EndProcedure

Procedure.i mpixDrawSprite(*Source.Ascii,X.i,Y.i,Width.i,Height.i,Center.i = #False)
  Protected px.i
  Protected py.i
  If Center
    X - (Width >> 1)
    Y - (Height >> 1)
  EndIf
  Width - 1
  Height - 1
  For py = 0 To Height
    For px = 0 To Width
      If *Source\a;<- color 0 aka. color-index 0 is transparent!
        mpixPixelSet(X + px,Y + py,*Source\a)
      EndIf
      *Source + 1
    Next
  Next
  ProcedureReturn #Null
EndProcedure

Procedure.i mpixDrawSpriteTint(*Source.Ascii,X.i,Y.i,Width.i,Height.i,Color.i,Center.i = #False)
  Protected px.i
  Protected py.i
  If Center
    X - (Width >> 1)
    Y - (Height >> 1)
  EndIf
  Width - 1
  Height - 1
  For py = 0 To Height
    For px = 0 To Width
      If *Source\a;<- color 0 aka. color-index 0 is transparent!
        mpixPixelSet(X + px,Y + py,Color)
      EndIf
      *Source + 1
    Next
  Next
  ProcedureReturn #Null
EndProcedure

Procedure.i mpixDrawSpriteEx(*Source.Ascii,X.i,Y.i,Width.i,Height.i,Scale.i,Center.i = #False)
  Protected px.i
  Protected py.i
  If Center
    X - ((Width * Scale) >> 1)
    Y - ((Height * Scale) >> 1)
  EndIf
  Width - 1
  Height - 1
  For py = 0 To Height
    For px = 0 To Width
      If *Source\a;<- color 0 aka. color-index 0 is transparent!
        mpixDrawRect(X + (px * Scale),Y + (py * Scale),Scale,Scale,*Source\a,#False)
      EndIf
      *Source + 1
    Next
  Next
  ProcedureReturn #Null
EndProcedure

Procedure.i mpixDrawSpriteExTint(*Source.Ascii,X.i,Y.i,Width.i,Height.i,Scale.i,Color.i,Center.i = #False)
  Protected px.i
  Protected py.i
  If Center
    X - ((Width * Scale) >> 1)
    Y - ((Height * Scale) >> 1)
  EndIf
  Width - 1
  Height - 1
  For py = 0 To Height
    For px = 0 To Width
      If *Source\a;<- color 0 aka. color-index 0 is transparent!
        mpixDrawRect(X + (px * Scale),Y + (py * Scale),Scale,Scale,Color,#False)
      EndIf
      *Source + 1
    Next
  Next
  ProcedureReturn #Null
EndProcedure
 
Procedure.i mpixDrawText(X.i,Y.i,Text.s,Color.i,Center.i = #False)
  Protected *a.Ascii
  Protected *r.Ascii
  Protected ox.i
  Protected oy.i
  Protected px.i
  Protected py.i
  If Center
    X - ((Len(Text) * 5) >> 1)
  EndIf
  *a = @Text
  Repeat
    oy = *a\a >> 4
    ox = *a\a - (oy << 4)
    ox * 5
    oy * 480
    oy + ox
    For py = 0 To 5
      For px = 0 To 4
        *r = ?font + px + oy
        If *r\a
          mpixPixelSet(X + px,Y + py,Color)
        EndIf
      Next
      oy + 80
    Next
    X + 5
    *a + 2
  Until *a\a = #Null
EndProcedure

Procedure.i mpixDrawTextEx(X.i,Y.i,Text.s,Scale.i,Color.i,Center.i = #False)
  Protected *a.Ascii
  Protected *r.Ascii
  Protected sz.i
  Protected ox.i
  Protected oy.i
  Protected px.i
  Protected py.i
  sz = Len(Text) * 5
  If Center
    X - ((sz * Scale) >> 1)
  EndIf
  sz = 5 * Scale
  *a = @Text
  Repeat
    oy = *a\a >> 4
    ox = *a\a - (oy << 4)
    ox * 5
    oy * 480
    oy + ox
    For py = 0 To 5
      For px = 0 To 4
        *r = ?font + px + oy
        If *r\a
          mpixDrawRect(X + (px * Scale),Y + (py * Scale),Scale,Scale,Color,#False)
        EndIf
      Next
      oy + 80
    Next
    X + sz
    *a + 2
  Until *a\a = #Null
EndProcedure

Procedure.i mpixMouse(*Rect.RECT,*X.Integer,*Y.Integer)
 Protected pos.POINT
 pos\x = WindowMouseX(0);<- get the mouse position
 pos\y = WindowMouseY(0)
 If PtInRect_(*Rect,PeekL(@pos));<- check if the mouse is inside the window
   *X\i = pos\x >> 1;<- translate the window coordinates into screen coordinates
   *Y\i = pos\y >> 1
   ProcedureReturn #True
 EndIf
 ProcedureReturn #False
EndProcedure

Procedure.i Main()
  Protected size.RECT
  Protected mx.i
  Protected my.i
  size\right = 512
  size\bottom = 512
  If OpenWindow(0,size\left,size\top,size\right,size\bottom,"Demo",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
    AddWindowTimer(0,0,10);<- very basic timing
    If mpixCreate(WindowID(0))
      mpixPaletteSet(1,$FF4242);<- put some colors into the palette (default is some greenscale - see source code)
      mpixPaletteSet(2,$FFFFFF)
      mpixPaletteSet(3,$42FFFF)
      Repeat
        Select WaitWindowEvent()
          Case #PB_Event_Timer
            mpixMouse(@size,@mx,@my)
            mpixPixelClear()
            mpixDrawTextEx(80,20,"Hello World!",2,1,0)
            mpixDrawTextEx(80,40,"Hello World!",2,2,1)
            mpixDrawText(100,60,"Hello World!",3,0)
            mpixDrawRect(127,127,16,16,3,#True)
            mpixDrawSprite(?sprite,200,100,8,8)
            mpixDrawSpriteTint(?sprite,200,200,8,8,255)
            mpixDrawSpriteEx(?sprite,60,60,8,8,5,#True)
            mpixDrawSpriteExTint(?sprite,60,60,8,8,5,2,#False)
            mpixDrawSpriteEx(?sprite,mx,my,8,8,8,#True)
            mpixPixelDraw(size\left,size\top,size\right,size\bottom)
          Case #PB_Event_CloseWindow
            Break
        EndSelect 
      ForEver
      mpixRelease()
    EndIf
    CloseWindow(0)
  EndIf
  ProcedureReturn #Null
EndProcedure

End Main()

DataSection
  font:
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,1,0,0,0,1,0,1,0,1,0,1,0,0,0,1,1,0,0,1,0,0,1,0,0,1,1,0,0,0,0,1,0,0,0,1,1,0,0,0,1,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0
  Data.a 0,0,0,0,0,0,0,1,0,0,0,1,0,1,0,1,1,1,1,0,1,0,1,1,0,0,0,1,1,0,1,0,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1,0,0,1,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0
  Data.a 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,1,0,0,1,1,0,1,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,1,1,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,1,1,1,1,0,1,1,0,0,0,1,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,1,0,0,1,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0
  Data.a 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,1,0,0,0,1,1,0,0,1,0,0,1,0,0,1,0,1,0,0,0,0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,1,1,0,0,0,1,1,0,0,0,1,1,0,0,1,1,1,0,0,0,0,0,1,0,0,1,1,0,0,0,1,1,0,0,1,1,1,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,1,1,0,0
  Data.a 1,0,0,1,0,1,0,1,0,0,1,0,0,1,0,0,0,0,1,0,0,0,1,1,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,1,0,0,1,0,1,0,0,1,0,0,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0,1,1,0,0,0,0,1,0,0,1,0,0,1,0
  Data.a 1,1,1,1,0,0,0,1,0,0,0,0,1,0,0,0,1,1,0,0,0,1,0,1,0,1,1,1,0,0,1,1,1,0,0,0,0,0,1,0,0,1,1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0
  Data.a 1,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,1,1,1,1,0,0,0,0,1,0,1,0,0,1,0,0,0,1,0,0,1,0,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0,1,1,0,0,0,0,1,0,0,0,0,0,0,0
  Data.a 0,1,1,0,0,0,0,1,0,0,1,1,1,1,0,1,1,1,0,0,0,0,0,1,0,1,1,1,0,0,0,1,1,0,0,0,0,1,0,0,0,1,1,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,1,1,0,0,0,1,1,0,0,1,1,1,0,0,0,1,1,1,0,1,1,1,0,0,0,1,1,1,0,0,1,1,1,0,0,1,1,0,0,1,0,0,1,0,0,1,1,1,0,1,1,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,1,0,1,0,0,1,0,0,1,1,0,0
  Data.a 1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,0,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,0,1,0,0,0,1,0,0,0,0,0,1,0,1,0,1,0,0,1,0,0,0,0,1,1,1,1,0,1,1,0,1,0,1,0,0,1,0
  Data.a 0,0,1,1,0,1,1,1,1,0,1,1,1,0,0,1,0,0,0,0,1,0,0,1,0,1,1,1,0,0,1,1,1,0,0,1,0,1,1,0,1,1,1,1,0,0,0,1,0,0,0,0,0,1,0,1,1,0,0,0,1,0,0,0,0,1,0,0,1,0,1,0,1,1,0,1,0,0,1,0
  Data.a 0,1,0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,0,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,0,0,1,0,0,1,0,1,0,0,1,0,0,0,1,0,0,1,0,0,1,0,1,0,1,0,0,1,0,0,0,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0
  Data.a 0,1,1,0,0,1,0,0,1,0,1,1,1,0,0,0,1,1,1,0,1,1,1,0,0,0,1,1,1,0,1,0,0,0,0,0,1,1,0,0,1,0,0,1,0,0,1,1,1,0,0,1,1,0,0,1,0,0,1,0,0,1,1,1,0,1,0,0,1,0,1,0,0,1,0,0,1,1,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 1,1,1,0,0,0,1,1,0,0,1,1,1,0,0,0,1,1,1,0,0,1,1,1,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,1,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0,0
  Data.a 1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,0,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,1,0,1,0,0,0,0,0,0
  Data.a 1,1,1,0,0,1,0,0,1,0,1,1,1,0,0,0,1,1,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,0,1,1,0,0,0,1,1,1,0,0,1,1,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0
  Data.a 1,0,0,0,0,1,0,1,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,1,0,0,1,0,1,0,1,1,1,1,0,1,0,0,1,0,0,0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0
  Data.a 1,0,0,0,0,0,1,0,1,0,1,0,0,1,0,1,1,1,0,0,0,0,1,0,0,0,1,1,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,1,0,0,0,0,1,0,0,1,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,1,1,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,1,0,0,0,0,1,1,0,0,1,1,1,0,0,0,1,1,1,0,1,1,1,0,0,0,1,1,1,0,0,1,1,1,0,0,1,1,0,0,1,0,0,1,0,0,1,1,1,0,1,1,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,1,0,1,0,0,1,0,0,1,1,0,0
  Data.a 0,0,1,0,0,1,0,0,1,0,1,0,0,1,0,1,0,0,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,0,1,0,0,0,1,0,0,0,0,0,1,0,1,0,1,0,0,1,0,0,0,0,1,1,1,1,0,1,1,0,1,0,1,0,0,1,0
  Data.a 0,0,0,0,0,1,1,1,1,0,1,1,1,0,0,1,0,0,0,0,1,0,0,1,0,1,1,1,0,0,1,1,1,0,0,1,0,1,1,0,1,1,1,1,0,0,0,1,0,0,0,0,0,1,0,1,1,0,0,0,1,0,0,0,0,1,0,0,1,0,1,0,1,1,0,1,0,0,1,0
  Data.a 0,0,0,0,0,1,0,0,1,0,1,0,0,1,0,1,0,0,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,0,0,1,0,0,1,0,1,0,0,1,0,0,0,1,0,0,1,0,0,1,0,1,0,1,0,0,1,0,0,0,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0
  Data.a 0,0,0,0,0,1,0,0,1,0,1,1,1,0,0,0,1,1,1,0,1,1,1,0,0,0,1,1,1,0,1,0,0,0,0,0,1,1,0,0,1,0,0,1,0,0,1,1,1,0,0,1,1,0,0,1,0,0,1,0,0,1,1,1,0,1,0,0,1,0,1,0,0,1,0,0,1,1,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 1,1,1,0,0,0,1,1,0,0,1,1,1,0,0,0,1,1,1,0,0,1,1,1,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,1,1,0,0,0,1,1,0,0,0,0,1,0,0,0,1,1,0,0,0,0,0,1,0,0,1,1,1,0
  Data.a 1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,0,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,1,0,0,0,1,0,1,0,0,1,0,1,0
  Data.a 1,1,1,0,0,1,0,0,1,0,1,1,1,0,0,0,1,1,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,0,1,1,0,0,0,1,1,1,0,0,1,1,0,0,1,1,0,0,0,0,0,1,0,0,0,0,1,1,0,1,0,1,0,0,0,1,0,1,0
  Data.a 1,0,0,0,0,1,0,1,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,1,0,0,1,0,1,0,1,1,1,1,0,1,0,0,1,0,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,1,0
  Data.a 1,0,0,0,0,0,1,0,1,0,1,0,0,1,0,1,1,1,0,0,0,0,1,0,0,0,1,1,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,1,0,0,0,0,1,0,0,1,1,1,0,0,1,1,0,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,1,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  sprite:;8x8
  Data.a 0,0,1,1,1,1,0,0
  Data.a 0,1,0,0,0,0,1,0
  Data.a 1,0,1,0,0,1,0,1
  Data.a 1,0,0,0,0,0,0,1
  Data.a 1,0,1,0,0,1,0,1
  Data.a 1,0,1,1,1,1,0,1
  Data.a 0,1,0,0,0,0,1,0
  Data.a 0,0,1,1,1,1,0,0  
EndDataSection

Post Reply