format PE GUI 4.0
entry start
include 'win32a.inc'


section '.text' code readable executable
start:

   invoke  GetModuleHandle,0
   mov     [clsHInstance],eax
   invoke  LoadIcon,0,IDI_ASTERISK
   mov     [clsHIcon],eax
   invoke  LoadCursor,0,IDC_ARROW
   mov     [clsHCursor],eax
   invoke  RegisterClass,clsStyle

   invoke  CreateWindowEx,0,szClassName,szTitleName,WS_VISIBLE+WS_CAPTION+WS_SYSMENU+WS_MINIMIZEBOX,170,0,966,989,0,0,[clsHInstance],0
   mov     [hwindow],eax

   invoke  CreateWindowEx,0,stname,0,SS_BITMAP+WS_CHILD+WS_VISIBLE,0,0,960,960,[hwindow],5467,[clsHInstance],0
   mov     [hspl2],eax

   invoke  GetDC,[hwindow]
   mov     [MyDC],eax
   invoke  CreateDIBSection,[MyDC],bhead,DIB_RGB_COLORS,tut,0,0
   mov     [IBitmap],eax

   invoke  CreateEvent,0,0,0,0
   mov     [chndl],eax                  

   invoke  CreateThread,0,0,ThrProcV,0,0,ThVID
   mov     [thndl],eax

   invoke  GetCommandLine

waitsecondkav:
   inc     eax
   cmp     byte [eax],22h
jne waitsecondkav

waitnospace:
   inc     eax
   cmp     byte [eax],20h
je waitnospace

   cmp     byte [eax],0
je welcome

   mov     [comli],eax
   invoke  SetWindowText,[hwindow],[comli]
   invoke  CreateFile,[comli],GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,0,0
   cmp     eax,INVALID_HANDLE_VALUE
je welcome
   mov     [hsour],eax
   mov     al,20h
   mov     edi,splt
   mov     ecx,2400
   repe    stosb
   invoke  ReadFile,[hsour],splt,[proi],hows,0

welcome:
   invoke  SetEvent,[chndl]




msg_loop:
   invoke  GetMessage,msHWND,0,0,0
   cmp     eax,1
jb end_loop
jne msg_loop
   invoke  TranslateMessage,msHWND
   invoke  DispatchMessage,msHWND
jmp msg_loop
end_loop:
   invoke  CloseHandle,[hsour]
   invoke  CloseHandle,[thndl]
   invoke  CloseHandle,[chndl]
   invoke  ReleaseDC,[hwindow],[MyDC]
   invoke  DeleteObject,[IBitmap]
   invoke  ExitProcess,[msWPARAM]




proc ThrProcV, paramx
align 16
splagain:
   invoke  WaitForSingleObject,[chndl],-1
   xor     ecx,ecx
   mov     [tete],ecx
   mov ebx,[diwi]            ;How many letters are in a line on the screen.
again:                       ;The cycle of drawing one letter on the screen.
   mov esi,splt              ;Address of the beginning of the text - an array with letter codes.
   mov eax,[tete]            ;A variable containing the ordinal number of the letter in the text.
   add esi,eax               ;Already the address of a specific letter in the text.
   div bl                    ;Divide the letter number by the length of the string in letters.
   mov ecx,[dihe]            ;Number of lines on the screen.
   dec ecx                   ;The last (top) line (numbering starts from zero).
   sub cl,al                 ;We subtract and get the line number where to draw the letter.
   shr ax,8                  ;Now in ax is the column number where to draw the letter.
   mov dx,6                  ;Width of letter image in bytes.
   mul dx                    ;Multiply by the width to get the offset in bytes from the left edge.
   xchg ecx,eax              ;Now cx contains bytes from the left edge, and al contains the line number.
   mul ebx                   ;The line number is multiplied by the number of letters in the line.
   shl eax,5                 ;And then another 32 - the height of the letter image in bytes.
   mov edx,6                 ;Width of the letter image in bytes.
   mul edx                   ;And we also multiply by the width.
   mov edi,[tut]             ;Address of the beginning of the image in memory.
   add edi,eax               ;Add bytes in full lines.
   add edi,ecx               ;Add bytes from the left edge, got space for drawing.
   xor eax,eax               ;Write ZERO to the accumulator.
   lodsb                     ;Read the letter code.
   mov ecx,eax               ;For now, we'll save the code here.
   and al,0Fh                ;The remainder of division by 16 is the column number in the array of letter images.
   mov dl,6                  ;Letter width in bytes.
   mul dl                    ;We multiply, we get bytes from the left edge.
   xchg ecx,eax              ;Now in ecx there are bytes on the left, and in eax there is a letter code.
   shr al,4                  ;The quotient of division by 16 letters in a line is the line number.
   mov ah,15                 ;15 - the last (top) line (numbering from zero).
   sub ah,al                 ;We subtract and get the number of the line where the letter is drawn.
   xor al,al                 ;Clear the low byte.
   shl eax,1                 ;Multiply by 16 letters in a string and by 32 bytes of letter height.
   mov edx,6                 ;Width of the letter image in bytes.
   mul edx                   ;And we also multiply by the width.
   mov esi,[buu]             ;Address of the beginning of the array of letter images in memory.
   add esi,eax               ;Add bytes in full lines.
   add esi,ecx               ;Add bytes from the left edge, get the address of the letter image.
   mov ecx,32                ;32 bytes height of letter.
onebu:                       ;The cycle of drawing one letter.
   movsd                     ;4 bytes to move.
   movsw                     ;And move 2 more bytes.
   add esi,90                ;In the array of letter images, we skip 15 x 6 bytes.
   add edi,[dopa]            ;In the array of the finished image, we skip ((letters in the line) - 1) x 6 bytes.
loop onebu                   ;Next line of letters.
   inc [tete]                ;Increase the letter number in the text.
   mov eax,[tete]
   cmp eax,[proi]            ;Compare with last.
jb again                     ;If less, then draw another letter.
   invoke  SendMessage,[hspl2],STM_SETIMAGE,IMAGE_BITMAP,[IBitmap]

jmp splagain
endp




proc WndProc, hwnd,wmsg,wparam,lparam
        push    ebx esi edi
        cmp     [wmsg],WM_LBUTTONDOWN
je thef3
        cmp     [wmsg],WM_RBUTTONUP
je wmdestroy
        cmp     [wmsg],WM_DESTROY
je wmdestroy
        cmp     [wmsg],WM_KEYDOWN
je keypressed
        cmp     [wmsg],WM_MOUSEWHEEL
je wheel
        invoke  DefWindowProc,[hwnd],[wmsg],[wparam],[lparam]
jmp finish



wheel:
        mov     eax,[wparam]
        shr     eax,16
        test    ah,10000000b
jne wdown
        mov     [poineg],0FFFFFFFFh
        invoke  SetFilePointer,[hsour],-4800,poineg,FILE_CURRENT
        cmp     eax,INVALID_SET_FILE_POINTER
jne goodwup
        mov     [poipos],0
        invoke  SetFilePointer,[hsour],0,poipos,FILE_BEGIN
goodwup:
        invoke  ReadFile,[hsour],splt,[proi],hows,0
        invoke  SetEvent,[chndl]
jmp my
wdown:
        invoke  ReadFile,[hsour],splt,[proi],hows,0
        cmp     [hows],2400
je normwdown
        mov     [poineg],0FFFFFFFFh
        invoke  SetFilePointer,[hsour],-2400,poineg,FILE_END
        invoke  ReadFile,[hsour],splt,[proi],hows,0
normwdown:
        invoke  SetEvent,[chndl]
jmp my





keypressed:
        cmp     [wparam],VK_F3
jne nof3
thef3:
        invoke  GetOpenFileName,ofn
        cmp     eax,0
je my
        invoke  CloseHandle,[hsour]
        invoke  SetWindowText,[hwindow],snam
        invoke  CreateFile,snam,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,0,0
        mov     [hsour],eax
        mov     al,20h
        mov     edi,splt
        mov     ecx,2400
        repe    stosb
        invoke  ReadFile,[hsour],splt,[proi],hows,0
        invoke  SetEvent,[chndl]
jmp my



nof3:
        cmp     [wparam],VK_F8
jne nof8
        cmp     [buu],buk2+64
        mov     [buu],buk2+64
jne nobuk2
        mov     [buu],buk1+64
nobuk2:
        invoke  SetEvent,[chndl]
jmp my



nof8:
        cmp     [wparam],VK_UP
jne noup
        mov     [poineg],0FFFFFFFFh
        invoke  SetFilePointer,[hsour],-2480,poineg,FILE_CURRENT
        cmp     eax,INVALID_SET_FILE_POINTER
jne goodup
        mov     [poipos],0
        invoke  SetFilePointer,[hsour],0,poipos,FILE_BEGIN
goodup:
        invoke  ReadFile,[hsour],splt,[proi],hows,0
        invoke  SetEvent,[chndl]
jmp my



noup:
        cmp     [wparam],VK_DOWN
jne nodown
        mov     [poineg],0FFFFFFFFh
        invoke  SetFilePointer,[hsour],-2320,poineg,FILE_CURRENT
        invoke  ReadFile,[hsour],splt,[proi],hows,0
        cmp     [hows],2400
je normdown
        mov     [poineg],0FFFFFFFFh
        invoke  SetFilePointer,[hsour],-2400,poineg,FILE_END
        invoke  ReadFile,[hsour],splt,[proi],hows,0
normdown:
        invoke  SetEvent,[chndl]
jmp my



nodown:
        cmp     [wparam],VK_PGUP
jne nopgup
        mov     [poineg],0FFFFFFFFh
        invoke  SetFilePointer,[hsour],-4800,poineg,FILE_CURRENT
        cmp     eax,INVALID_SET_FILE_POINTER
jne goodpgup
        mov     [poipos],0
        invoke  SetFilePointer,[hsour],0,poipos,FILE_BEGIN
goodpgup:
        invoke  ReadFile,[hsour],splt,[proi],hows,0
        invoke  SetEvent,[chndl]
jmp my



nopgup:
        cmp     [wparam],VK_LEFT
jne noleft
        mov     [poineg],0FFFFFFFFh
        invoke  SetFilePointer,[hsour],-4800,poineg,FILE_CURRENT
        cmp     eax,INVALID_SET_FILE_POINTER
jne goodleft
        mov     [poipos],0
        invoke  SetFilePointer,[hsour],0,poipos,FILE_BEGIN
goodleft:
        invoke  ReadFile,[hsour],splt,[proi],hows,0
        invoke  SetEvent,[chndl]
jmp my



noleft:
        cmp     [wparam],VK_RIGHT
jne noright
        invoke  ReadFile,[hsour],splt,[proi],hows,0
        cmp     [hows],2400
je normright
        mov     [poineg],0FFFFFFFFh
        invoke  SetFilePointer,[hsour],-2400,poineg,FILE_END
        invoke  ReadFile,[hsour],splt,[proi],hows,0
normright:
        invoke  SetEvent,[chndl]
jmp my



noright:
        cmp     [wparam],VK_PGDN
jne nopgdn
        invoke  ReadFile,[hsour],splt,[proi],hows,0
        cmp     [hows],2400
je normpgdn
        mov     [poineg],0FFFFFFFFh
        invoke  SetFilePointer,[hsour],-2400,poineg,FILE_END
        invoke  ReadFile,[hsour],splt,[proi],hows,0
normpgdn:
        invoke  SetEvent,[chndl]
jmp my



nopgdn:
        cmp     [wparam],VK_HOME
jne nohome
        mov     [poipos],0
        invoke  SetFilePointer,[hsour],0,poipos,FILE_BEGIN
        invoke  ReadFile,[hsour],splt,[proi],hows,0
        invoke  SetEvent,[chndl]
jmp my



nohome:
        cmp     [wparam],VK_END
jne noend
        mov     [poineg],0FFFFFFFFh
        invoke  SetFilePointer,[hsour],-2400,poineg,FILE_END
        invoke  ReadFile,[hsour],splt,[proi],hows,0
        invoke  SetEvent,[chndl]
jmp my



noend:
        cmp     [wparam],VK_ESCAPE
jne my



wmdestroy:
        invoke  PostQuitMessage,0
my:
        xor     eax,eax
finish:
        pop     edi esi ebx
        ret
endp


section '.rdata' data readable import

  library kernel,'KERNEL32.DLL',\
          gdi,'GDI32.DLL',\
          user,'USER32.DLL',\
          comdlg,'COMDLG32.DLL',\
          shell,'SHELL32.DLL'

  import kernel,\
         GetCommandLine,'GetCommandLineA',\
         CreateFile,'CreateFileA',\
         ReadFile,'ReadFile',\
         CloseHandle,'CloseHandle',\
         CreateThread,'CreateThread',\
         GetModuleHandle,'GetModuleHandleA',\
         SetFilePointer,'SetFilePointer',\
         CreateEvent,'CreateEventA',\
         SetEvent,'SetEvent',\
         WaitForSingleObject,'WaitForSingleObject',\
         ExitProcess,'ExitProcess'

  import user,\
         RegisterClass,'RegisterClassA',\
         CreateWindowEx,'CreateWindowExA',\
         DefWindowProc,'DefWindowProcA',\
         GetMessage,'GetMessageA',\
         TranslateMessage,'TranslateMessage',\
         DispatchMessage,'DispatchMessageA',\
         LoadCursor,'LoadCursorA',\
         LoadIcon,'LoadIconA',\
         GetDC,'GetDC',\
         ReleaseDC,'ReleaseDC',\
         PostQuitMessage,'PostQuitMessage',\
         SetWindowText,'SetWindowTextA',\
         SendMessage,'SendMessageA'

  import gdi,\
         CreateDIBSection,'CreateDIBSection',\
         DeleteObject,'DeleteObject'

  import comdlg,\
         GetOpenFileName,'GetOpenFileNameA'

  import shell,\
         ShellExecute,'ShellExecuteA'







section '.data' data readable writeable



clsStyle                dd     0
clsLpfnWndProc          dd     WndProc
clsCbClsExtra           dd     0
clsCbWndExtra           dd     0
clsHInstance            dd     ?
clsHIcon                dd     ?
clsHCursor              dd     ?
clsHbrBackground        dd     COLOR_3DDKSHADOW+1
clsLpszMenuName         dd     0
clsLpszClassName        dd     szClassName

szTitleName             db     'SplView',0
szClassName             db     'mnbvmbdfe',0
stname                  db     'STATIC',0
                             
bhead                   dd      40
wi                      dd      960
he                      dd      960
                        dw      1
cbits                   dw      4
                        dd      0
proizv                  dd      921600
                        dd      2834
                        dd      2834
coc                     dd      16
cov                     dd      16


buk2                    file    'OEM.bmp':54,49216
buk1                    file    'ANSI.bmp':54,49216
buu                     dd      buk2+64


ofn                     dd      76
hWndOwner               dd      0
hInstance               dd      0
lpstrFilter             dd      sfilter
lpstrCustomFilter       dd      0
nMaxCustFilter          dd      0
nFilterIndex            dd      0
lpstrFile               dd      snam
nMaxFile                dd      1024
lpstrFileTitle          dd      0
nMaxFileTitle           dd      0
lpstrInitialDir         dd      0
lpstrTitle              dd      0
Flags                   dd      OFN_LONGNAMES+OFN_HIDEREADONLY+OFN_OVERWRITEPROMPT+OFN_FILEMUSTEXIST+OFN_PATHMUSTEXIST
nFileOffset             dw      0
nFileExtension          dw      0
lpstrDefExt             dd      exte
lCustData               dd      0
lpfnHook                dd      0
lpTemplateName          dd      0

sfilter                 db      'All files',0,'*.*',0,0
exte                    db      '*' 




dihe                    dd      30
diwi                    dd      80
proi                    dd      2400
dopa                    dd      474
comli                   rd      1

splt:
db '                                                                                '
db '                                                                                '
db '   Welcome to SplView - a program for viewing any file as if it consisted       '
db '   of letters (while in reality, any file consists only of numbers).            '
db '                                                                                '
db '                                                                                '
db '   SplView interprets each number in a file as the index of a letter            '
db '   in the alphabet and displays the corresponding letter                        '
db '   on the screen instead of the number.                                         '
db '                                                                                '
db '   You can scroll through the resulting text using the mouse wheel,             '
db '   arrow keys, or the Page Up, Page Down, Home, and End keys.                   '
db '                                                                                '
db '   To exit the program, use the right mouse button or the Esc key.              '
db '                                                                                '
db '   To select a file for viewing, use the left mouse button or the F3 key.       '
db '                                                                                '
db '                                                                                '
db '                                                                                '
db '                                                                                '
db '   Note 1: The following alphabet is used, containing exactly 256 characters:   '
db '                                                                                '
db 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30
db 31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58
db 59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86
db 87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110
db 111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131
db 132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152
db 153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173
db 174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194
db 195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215
db 216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236
db 237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
db '                                                                                '
db '                                                                '
db '   Note 2: You can switch this alphabet to a different one (and back again) by  '
db '   pressing the F8 key. '



splend                  db      2400-splend+splt dup (32)


poipos                  dd      0
poineg                  dd      0FFFFFFFFh

hsour                   dd      0



snam                    rb      1024
ThVID                   rd      1
thndl                   rd      1
chndl                   rd      1


hwindow                 rd      1
hspl2                   rd      1
IBitmap                 rd      1
MyDC                    rd      1
tut                     rd      1
hows                    rd      1
tete                    rd      1
                               
                               
msHWND                  rd      1
msMESSAGE               rd      1
msWPARAM                rd      1
msLPARAM                rd      1
msTIME                  rd      1
msPT                    rd      2









DIB_RGB_COLORS = 0
INVALID_SET_FILE_POINTER = -1
KEY_ALL_ACCESS = STANDARD_RIGHTS_ALL or KEY_QUERY_VALUE or KEY_SET_VALUE or KEY_CREATE_SUB_KEY or KEY_ENUMERATE_SUB_KEYS or KEY_NOTIFY or KEY_CREATE_LINK and not SYNCHRONIZE
HKEY_CLASSES_ROOT = 80000000h
REG_SZ = 1
REG_EXPAND_SZ = 2
SW_HIDE = 0
IDI_ASTERISK = 32516
IDC_ARROW = 32512
WS_VISIBLE = 010000000h
WS_CAPTION = 000C00000h
WS_SYSMENU = 000080000h
WS_MINIMIZEBOX = 000020000h
SS_BITMAP = 000Eh
WS_CHILD = 040000000h
OPEN_EXISTING = 3
FILE_SHARE_READ = 00000001h
GENERIC_READ = 80000000h
INVALID_HANDLE_VALUE = -1
IMAGE_BITMAP = 0
STM_SETIMAGE = 0172h
WM_LBUTTONDOWN = 0201h
WM_RBUTTONUP = 0205h
WM_DESTROY = 0002h
WM_KEYDOWN = 0100h
WM_MOUSEWHEEL = 020Ah
FILE_BEGIN = 0
FILE_CURRENT = 1
FILE_END = 2
VK_F3 = 072h
VK_F8 = 077h
VK_ESCAPE = 01Bh
VK_LEFT = 025h
VK_UP = 026h
VK_RIGHT = 027h
VK_DOWN = 028h
VK_PGUP = 021h
VK_PGDN = 022h
VK_END = 023h
VK_HOME = 024h
COLOR_3DDKSHADOW = 21
OFN_LONGNAMES = 200000h
OFN_HIDEREADONLY = 000004h
OFN_OVERWRITEPROMPT = 000002h
OFN_FILEMUSTEXIST = 001000h
OFN_PATHMUSTEXIST = 000800h
RT_ICON = 3
RT_GROUP_ICON = 14
LANG_NEUTRAL = 00h
KEY_QUERY_VALUE = 1
KEY_SET_VALUE = 2
KEY_CREATE_SUB_KEY = 4
KEY_ENUMERATE_SUB_KEYS = 8
KEY_NOTIFY = 10h
KEY_CREATE_LINK = 20h
STANDARD_RIGHTS_ALL = 001F0000h
SYNCHRONIZE = 00100000h








