NASM - The Netwide Assembler
NASM Forum => Example Code => Topic started by: encryptor256 on October 10, 2013, 01:10:42 PM
-
Hello!
GLFW is an Open Source, multi-platform library for creating windows with OpenGL.
; ############################################################
; This is: GLFW HelloWorld NASM MinGW GCC
; Author: J.K. Encryptor256
; Date: October 10, 2013
; ############################################################
; Description:
; This program set's up GLFW window,
; Loads bitmap image "helloworld.bmp" via custom load function,
; Displays that image on screen via OpenGL.
; ############################################################
; Program code is organized into three sections:
; 1. At this section, i setup bitmap image structure offsets.
; 2. At this section, i define NASM macros. They are pretty easy.
; 3. At this section, is all the code.
; ############################################################
; How to compile:
; In the way i did, in two simple steps as follows:
; 1. NASM: "nasm.exe helloworld.asm -f win32 -o helloworld.o".
;
; 2. GCC: This is a bit larger, folded in two lines, you have to make in one, if compile. :D
;
; "gcc.exe helloworld.o -o helloworld.exe
; -L"C:/MinGW/lib" -L"K:/win32/glfw" -lglfw3 -lgdi32 -lopengl32 -mwindows".
;
; MinGW library files are here: "C:/MinGW/lib"
; GLFW library files are here: "K:/win32/glfw" there are files "glfw3.dll,glfw3dll.a,libglfw3.a"
; ############################################################
; Using:
; NASM: The Netwide Assembler.(http://nasm.us/).
; GLFW: Multi-platform library for creating windows with OpenGL.(http://www.glfw.org/).
; GCC: GNU Compiler Collection.(http://gcc.gnu.org/).
; MinGW: Minimalist GNU for Windows.(http://www.mingw.org/).
; ############################################################
; I consulted this site, to get an idea,
; on how images are thrown on the sreen via OpenGL. (http://lazyfoo.net)
; OpenGL and Bitmap Structure description i found on MSDN.
; ############################################################
Using GLFW functions:
1. glfwInit.
2. glfwTerminate.
3. glfwSetErrorCallback.
4. glfwCreateWindow.
5. glfwMakeContextCurrent.
6. glfwWindowShouldClose.
7. glfwSwapBuffers.
8. glfwPollEvents.
9. glfwSetWindowSizeCallback.
10. glfwGetFramebufferSize.
Using OpenGL functions:
1. glClear.
2. glClearColor.
3. glViewport.
4. glMatrixMode.
5. glLoadIdentity.
6. glOrtho.
7. glBegin.
8. glColor3f.
9. glVertex2f.
10. glEnd.
11. glEnable.
12. glDisable.
13. glTexCoord2f.
14. glBindTexture.
15. glTexImage2D.3
16. glGenTextures.
17. glTexParameteri.
18. glDeleteTextures.
19. glGetError.
.Full demonstration:
Full source code and runtime demonstration you can view at youtube.
Named: "GLFW HelloWorld NASM MinGW GCC"
Link: http://youtu.be/yu5M0RsbfQw (http://youtu.be/yu5M0RsbfQw)
.Attachment:
There is an attacment file "GLFW HelloWorld NASM MinGW GCC.zip" of this post, which includes:
1. Main compile file, full source, named: "helloworld.asm".
2. BMP image file, that is loaded and displayed at runtime, named: "helloworld.bmp".
3. Screen shot, there you can see the result of all this, named: "screenshot.bmp".
! There is a post limitation, so i will post other parts, these three sections, here, after.
And that's it!
Encryptor256!
-
This is section 1, the content of the main compile file, code was organized into three sections.
; ############################################################
; ############################################################
; 1. Section: BITMAP IMAGE STRUCTURE OFFSETS
; ############################################################
; ############################################################
; The BITMAPFILEHEADER structure contains information about the type,
; size, and layout of a file that contains a device-independent bitmap (DIB).
; Define offsets
BITMAPFILEHEADER.bfType equ 0
BITMAPFILEHEADER.bfSize equ 0+2
BITMAPFILEHEADER.bfReserved1 equ 0+2+4
BITMAPFILEHEADER.bfReserved2 equ 0+2+4+2
BITMAPFILEHEADER.bfOffBits equ 0+2+4+2+2
BITMAPFILEHEADER_SIZE equ 0+2+4+2+2+4
; The BITMAPINFOHEADER structure contains information about the dimensions
; and color format of a device-independent bitmap (DIB).
; Define offsets
BITMAPINFOHEADER.biSize equ 0
BITMAPINFOHEADER.biWidth equ 0+4
BITMAPINFOHEADER.biHeight equ 0+4+4
BITMAPINFOHEADER.biPlanes equ 0+4+4+4
BITMAPINFOHEADER.biBitCount equ 0+4+4+4+2
BITMAPINFOHEADER.biCompression equ 0+4+4+4+2+2
BITMAPINFOHEADER.biSizeImage equ 0+4+4+4+2+2+4
BITMAPINFOHEADER.biXPelsPerMeter equ 0+4+4+4+2+2+4+4
BITMAPINFOHEADER.biYPelsPerMeter equ 0+4+4+4+2+2+4+4+4
BITMAPINFOHEADER.biClrUsed equ 0+4+4+4+2+2+4+4+4+4
BITMAPINFOHEADER.biClrImportant equ 0+4+4+4+2+2+4+4+4+4+4
BITMAPINFOHEADER_SIZE equ 0+4+4+4+2+2+4+4+4+4+4+4
This is section 2, the content of the main compile file, code was organized into three sections.
; ############################################################
; ############################################################
; 2. Section: A BUNCH OF NASM MACROS
; ############################################################
; ############################################################
%macro cextern 1
extern _%1
%ifndef %1
%define %1 _%1
%endif
%endmacro
%macro cglobal 1
global _%1
%ifndef %1
%define %1 _%1
%endif
%endmacro
%macro cexternList 1-*
%rep %0
cextern %1
%rotate 1
%endrep
%endmacro
%macro invoke_cdecl 1-*
%assign max %0-1
%if %0 > 0
%rotate max
%rep max
push dword %1
%rotate -1
%endrep
%endif
call %1
add esp,dword max * 4
%endmacro
%macro invoke_stdcall 1-*
%assign max %0-1
%if %0 > 0
%rotate max
%rep max
push dword %1
%rotate -1
%endrep
%endif
call %1
%endmacro
%macro invoke_error 3
cmp eax,dword %2
%1 %3
%endmacro
%macro invoke_returns_at 1
mov dword %1, eax
%endmacro
%macro define_gl_func 2
extern _%1@%2
%define %1 _%1@%2
%endmacro
%macro float32.push 1
fld dword [%1]
%endmacro
%macro float32.pushi 1
fild dword [%1]
%endmacro
%macro float32.pushv 1
sub esp,dword 4
mov dword [esp],__float32__(%1)
float32.push esp
add esp,dword 4
%endmacro
%macro float32.pushvi 1
sub esp,dword 4
mov dword [esp],%1
float32.pushi esp
add esp,dword 4
%endmacro
%macro float32.pop 1
fstp dword [%1]
%endmacro
%macro float64.pop 1
fstp qword [%1]
%endmacro
%macro float32.pops 0
sub esp,dword 4
float32.pop esp
%endmacro
%macro float64.pops 0
sub esp,dword 8
float64.pop esp
%endmacro
%macro float32.args32 1-*
%rotate -1
%rep %0
float32.pushv %1
float32.pops
%rotate -1
%endrep
%endmacro
%macro float32.args32i 1-*
%rotate -1
%rep %0
float32.pushvi %1
float32.pops
%rotate -1
%endrep
%endmacro
%macro float32.args64 1-*
%rotate -1
%rep %0
float32.pushv %1
float64.pops
%rotate -1
%endrep
%endmacro
%macro float32.args64i 1-*
%rotate -1
%rep %0
float32.pushvi %1
float64.pops
%rotate -1
%endrep
%endmacro
-
This is section 3, the content of the main compile file, code was organized into three sections.
; ############################################################
; ############################################################
; 3. Section: MAIN CORE IN NASM
; ############################################################
; ############################################################
; Tell compiler what kind'a cpu type
cpu 386
; Tell compiler to generate 32bit code
bits 32
; # Define GLFW functions and constants:
; ----------------------------------------------------
cexternList glfwInit, \
glfwTerminate, \
glfwSetErrorCallback, \
glfwCreateWindow, \
glfwMakeContextCurrent, \
glfwWindowShouldClose, \
glfwSwapBuffers, \
glfwPollEvents, \
glfwSetWindowSizeCallback, \
glfwGetFramebufferSize
; # Define C functions and constants
; ----------------------------------------------------
cexternList atexit, \
printf, \
fopen, \
fread, \
fclose, \
malloc, \
free, \
fseek
cglobal main
SEEK_CUR equ 1
; # Define OpenGL functions and constants
; ----------------------------------------------------
; GL externs (These functions are imported from library)
define_gl_func glClear,4
define_gl_func glClearColor,16
define_gl_func glViewport,16
define_gl_func glMatrixMode,4
define_gl_func glLoadIdentity,0
define_gl_func glOrtho,48
define_gl_func glBegin,4
define_gl_func glColor3f,12
define_gl_func glVertex2f,8
define_gl_func glEnd,0
define_gl_func glEnable,4
define_gl_func glDisable,4
define_gl_func glTexCoord2f,8
define_gl_func glBindTexture,8
define_gl_func glTexImage2D,36
define_gl_func glGenTextures,8
define_gl_func glTexParameteri,12
define_gl_func glDeleteTextures,8
define_gl_func glGetError,0
; GL error constants
GL_NO_ERROR equ 0
GL_INVALID_ENUM equ 0x0500
GL_INVALID_VALUE equ 0x0501
GL_INVALID_OPERATION equ 0x0502
GL_STACK_OVERFLOW equ 0x0503
GL_STACK_UNDERFLOW equ 0x0504
GL_OUT_OF_MEMORY equ 0x0505
; GL graphical constants
GL_COLOR_BUFFER_BIT equ 0x00004000
GL_TRUE equ 1
GL_FALSE equ 0
GL_MODELVIEW equ 0x1700
GL_PROJECTION equ 0x1701
GL_TRIANGLES equ 0x0004
GL_TEXTURE_2D equ 0x0DE1
GL_QUADS equ 0x0007
GL_RGB equ 0x1907
GL_UNSIGNED_BYTE equ 0x1401
GL_TEXTURE_MAG_FILTER equ 0x2800
GL_TEXTURE_MIN_FILTER equ 0x2801
GL_LINEAR equ 0x2601
GL_BGR_EXT equ 0x80E0
; -------------------------------------------------------------------------------------
section .data use32 ; 32bit Data segment
; -------------------------------------------------------------------------------------
; Strings:
; -------------------------------------------------------------------------------
txt_bmp_info: db 10,"Bitmap '%s' info (Width: %d, Height: %d,"
db "Compression: %d, BitCount: %d, DataSize: %d).",0
txt_window_text: db "Hello world with GLFW, NASM and Encryptor256",0
txt_esp: db 10,"Stack check: %d is equal? %d",0
txt_bmpname: db "helloworld.bmp",0
txt_error: db 10,"~ Error: %s",0
txt_file_access_rb: db "rb",0
; Strings: glGetError:
; -------------------------------------------------------------------------------
txt_glGetError: db 10,"glGetError: 0x%X, %s.",0
txt_glErrorN: db "GL_NO_ERROR",0
txt_glError0: db "GL_INVALID_ENUM",0
txt_glError1: db "GL_INVALID_VALUE",0
txt_glError2: db "GL_INVALID_OPERATION",0
txt_glError3: db "GL_STACK_OVERFLOW",0
txt_glError4: db "GL_STACK_UNDERFLOW",0
txt_glError5: db "GL_OUT_OF_MEMORY",0
; Determine OpenGL error type by this jump table
glError_types: dd txt_glError0,txt_glError1,txt_glError2
dd txt_glError3,txt_glError4,txt_glError5
; Memory items:
; -------------------------------------------------------------------------------
hWindow: dd 0
bitmapW: dd 0
bitmapH: dd 0
hBitmapData: dd 0
textureID: dd 0
; One for the debug purposes
espBK: dd 0
; -------------------------------------------------------------------------------------
section .text use32 ; 32bit Code segment
; -------------------------------------------------------------------------------------
main:
push ebp
mov ebp,esp
; Save stack pointer, if error occurs, then compare, maybe stack error.
mov dword [espBK],esp
; glfwSetErrorCallback: (GLFW)
; -------------------------------------------------------------------------------
; This function sets the error callback.
; -------------------------------------------------------------------------------
invoke_cdecl glfwSetErrorCallback,GLFWErrorCallbackFunction
; glfwInit: (GLFW)
; -------------------------------------------------------------------------------
; This function initializes the GLFW library.
; -------------------------------------------------------------------------------
invoke_cdecl glfwInit
invoke_error je,GL_FALSE,main.quitError
; glfwTerminate: (GLFW)
; -------------------------------------------------------------------------------
; This function destroys all remaining windows,
; frees any allocated resources and sets the library to an uninitialized state.
; -------------------------------------------------------------------------------
invoke_cdecl atexit,glfwTerminate
; glfwCreateWindow: (GLFW)
; -------------------------------------------------------------------------------
; This function creates a window and its associated context.
; -------------------------------------------------------------------------------
invoke_cdecl glfwCreateWindow,1024,512,txt_window_text,0,0
invoke_error je,0,main.quitError
invoke_returns_at [hWindow]
; glfwSetWindowSizeCallback: (GLFW)
; -------------------------------------------------------------------------------
; This function sets the size callback of the specified window,
; which is called when the window is resized.
; -------------------------------------------------------------------------------
invoke_cdecl glfwSetWindowSizeCallback,[hWindow],GLFWWindowSizeCallback
; glfwMakeContextCurrent: (GLFW)
; -------------------------------------------------------------------------------
; TThis function makes the context of the specified window current on the calling thread
; -------------------------------------------------------------------------------
invoke_cdecl glfwMakeContextCurrent,[hWindow]
; * This early GL setup...
; glViewport: (OpenGL)
; -------------------------------------------------------------------------------
; The glViewport function sets the viewport.
; -------------------------------------------------------------------------------
invoke_stdcall glViewport,0,0,1024,512
; glMatrixMode: (OpenGL)
; -------------------------------------------------------------------------------
; The glMatrixMode function specifies which matrix is the current matrix.
; -------------------------------------------------------------------------------
invoke_stdcall glMatrixMode,GL_PROJECTION
; glLoadIdentity: (OpenGL)
; -------------------------------------------------------------------------------
; The glLoadIdentity function replaces the current matrix with the identity matrix.
; -------------------------------------------------------------------------------
invoke_stdcall glLoadIdentity
; glOrtho: (OpenGL)
; -------------------------------------------------------------------------------
; The glOrtho function multiplies the current matrix by an orthographic matrix.
; -------------------------------------------------------------------------------
float32.args64i 0,1024,512,0,0,1
invoke_stdcall glOrtho
; glMatrixMode: (OpenGL)
; -------------------------------------------------------------------------------
; The glMatrixMode function specifies which matrix is the current matrix.
; -------------------------------------------------------------------------------
invoke_stdcall glMatrixMode,GL_MODELVIEW
; glLoadIdentity: (OpenGL)
; -------------------------------------------------------------------------------
; The glLoadIdentity function replaces the current matrix with the identity matrix.
; -------------------------------------------------------------------------------
invoke_stdcall glLoadIdentity
; * This is where image loading and image setup begins...
; LoadBmpFile: (Custom)
; -------------------------------------------------------------------------------
; Load bitmap image and obtain data.
; -------------------------------------------------------------------------------
invoke_stdcall LoadBmpFile, \
txt_bmpname, \
txt_file_access_rb, \
bitmapW,bitmapH, hBitmapData
invoke_error jne,0,main.quitError
; glGenTextures: (OpenGL)
; -------------------------------------------------------------------------------
; The glGenTextures function generates texture names.
; -------------------------------------------------------------------------------
invoke_stdcall glGenTextures,1,textureID
invoke_error je,0,main.quitError
; glBindTexture: (OpenGL)
; -------------------------------------------------------------------------------
; The glBindTexture function enables the creation
; of a named texture that is bound to a texture target.
; -------------------------------------------------------------------------------
invoke_stdcall glBindTexture,GL_TEXTURE_2D,[textureID]
; glTexImage2D: (OpenGL)
; -------------------------------------------------------------------------------
; The glTexImage2D function specifies a two-dimensional texture image.
; -------------------------------------------------------------------------------
invoke_stdcall glTexImage2D,GL_TEXTURE_2D,0, \
GL_RGB,[bitmapW],[bitmapH],0, \
GL_BGR_EXT,GL_UNSIGNED_BYTE,[hBitmapData]
; glTexParameteri: (OpenGL)
; -------------------------------------------------------------------------------
; Sets texture parameters.
; -------------------------------------------------------------------------------
invoke_stdcall glTexParameteri,GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR
invoke_stdcall glTexParameteri,GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR
; glBindTexture: (OpenGL)
; -------------------------------------------------------------------------------
invoke_stdcall glBindTexture,GL_TEXTURE_2D,0
; Enter main loop:
; -------------------------------------------------------------------------------
main.messageLoop:
; glClearColor: (OpenGL)
; -------------------------------------------------------------------------------
; The glClearColor function specifies clear values for the color buffers.
; -------------------------------------------------------------------------------
float32.args32 0.84765625,0.875,0.9375,0.0
invoke_stdcall glClearColor
; glClear: (OpenGL)
; -------------------------------------------------------------------------------
; The glClear function clears buffers to preset values.
; -------------------------------------------------------------------------------
invoke_stdcall glClear,GL_COLOR_BUFFER_BIT
; Display image: BEGIN
; -------------------------------------------------------------------------------
float32.args32 1.0,1.0,1.0
invoke_stdcall glColor3f
invoke_stdcall glEnable,GL_TEXTURE_2D
invoke_stdcall glBindTexture,GL_TEXTURE_2D,[textureID]
invoke_stdcall glBegin,GL_QUADS
; Get window size
sub esp,dword 4
mov edx,esp
sub esp,dword 4
mov eax,esp
invoke_cdecl glfwGetFramebufferSize,[hWindow],eax,edx
pop dword eax ; W
pop dword edx ; H
; Push arguments
float32.args32i 0,edx ; 8. Arguments for glVertex2f
float32.args32i 0,1 ; 7. Arguments for glTexCoord2f
float32.args32i eax,edx ; 6. Arguments for glVertex2f
float32.args32i 1,1 ; 5. Arguments for glTexCoord2f
float32.args32i eax,0 ; 4. Arguments for glVertex2f
float32.args32i 1,0 ; 3. Arguments for glTexCoord2f
float32.args32i 0,0 ; 2. Arguments for glVertex2f
float32.args32i 0,0 ; 1. Arguments for glTexCoord2f
; Call functions, set texture and vertex coordinates
invoke_stdcall glTexCoord2f ; 1.
invoke_stdcall glVertex2f ; 2.
invoke_stdcall glTexCoord2f ; 3.
invoke_stdcall glVertex2f ; 4.
invoke_stdcall glTexCoord2f ; 5.
invoke_stdcall glVertex2f ; 6.
invoke_stdcall glTexCoord2f ; 7.
invoke_stdcall glVertex2f ; 8.
invoke_stdcall glEnd
invoke_stdcall glDisable,GL_TEXTURE_2D
; Display image: END
; -------------------------------------------------------------------------------
; glfwWindowShouldClose: (GLFW)
; -------------------------------------------------------------------------
; This function returns the value of the close flag of the specified window.
; -------------------------------------------------------------------------
invoke_cdecl glfwWindowShouldClose,[hWindow]
invoke_error jg,0,main.quitLoop
; glfwSwapBuffers: (GLFW)
; -------------------------------------------------------------------------
; This function swaps the front and back buffers of the specified window.
; -------------------------------------------------------------------------
invoke_cdecl glfwSwapBuffers,[hWindow]
; glfwPollEvents: (GLFW)
; -------------------------------------------------------------------------
; This function processes only those events that
; have already been received and then returns immediately.
; -------------------------------------------------------------------------
invoke_cdecl glfwPollEvents
jmp main.messageLoop
main.quitLoop:
; free: (C)
; -------------------------------------------------------------------------
; C function, release bitmap data, that were allocated by Load bitmap function
; -------------------------------------------------------------------------
invoke_cdecl free,[hBitmapData]
; glDeleteTextures: (OpenGL)
; -------------------------------------------------------------------------
; The glDeleteTextures function deletes named textures.
; -------------------------------------------------------------------------
invoke_stdcall glDeleteTextures,1,textureID
; Quit normal:
; -------------------------------------------------------------------------------
mov eax,dword 0
pop ebp
ret
; Quit error:
; -------------------------------------------------------------------------------
main.quitError:
; Check, print stack error:
mov eax,esp
mov edx,esp
mov edx,dword [espBK]
invoke_cdecl printf,txt_esp,edx,eax
; Check stack error:
call printGLError
mov eax,dword -1
pop ebp
ret
-
This is section 3, the content of the main compile file, code was organized into three sections.
This is rest of the section 3: "Procedures".
; ############################################################
; ############################################################
; PROCEDURES
; ############################################################
; ############################################################
; -------------------------------------------------------------------------------------
GLFWErrorCallbackFunction: ; This procedure is called when GLFW finds an error
; -------------------------------------------------------------------------------------
push ebp
mov ebp,esp
; -------------------------------
%define ebp_error_code ebp+8
%define ebp_error_text ebp+12
; -------------------------------
; Display error message
invoke_cdecl printf,txt_error,[ebp_error_text]
pop ebp
ret
; -------------------------------------------------------------------------------------
GLFWWindowSizeCallback: ; This procedure is called when GLFW resizes window
; -------------------------------------------------------------------------------------
push ebp
mov ebp,esp
; -------------------------------
%define ebp_wnd_handle ebp+8
%define ebp_width ebp+12
%define ebp_height ebp+16
; -------------------------------
; Reset opengl...
invoke_stdcall glViewport,0,0,[ebp_width],[ebp_height]
invoke_stdcall glMatrixMode,GL_PROJECTION
invoke_stdcall glLoadIdentity
mov eax,dword [ebp_width]
mov edx,dword [ebp_height]
float32.args64i 0,eax,edx,0,0,1
invoke_stdcall glOrtho
invoke_stdcall glMatrixMode,GL_MODELVIEW
invoke_stdcall glLoadIdentity
pop ebp
ret
; -------------------------------------------------------------------------------------
LoadBmpFile:
; Loads uncompressed RGB image, bits per pixel: 24
; Code description:
; 1. Open File.
; 2. Allocate structure of BITMAPFILEHEADER.
; 3. Allocate structure of BITMAPINFOHEADER.
; 4. Read both structures from file.
; 5. Collect data, print bitmap info, format specified in "txt_bmp_info".
; 6. Allocate bitmap data, the data for all bitmap image pixels.
; 7. Read bitmap data into allocated buffer address.
; 8. Set output w and h pointer params.
; 9. Right now loaded image is upside down, so flip image vertically.
; 10. Quit
; -------------------------------------------------------------------------------------
push ebp
mov ebp,esp
; -------------------------------
%define ebp_name ebp+8
%define ebp_access ebp+12
%define ebp_w_ptr ebp+16
%define ebp_h_ptr ebp+20
%define ebp_data_ptr ebp+24
; -------------------------------
%define ebp_handle ebp-4
%define ebp_w ebp-8
%define ebp_h ebp-12
%define ebp_hBMFileHeader ebp-16
%define ebp_hBMInfoHeader ebp-20
%define ebp_hData ebp-24
%define ebp_hDataLen ebp-28
; -------------------------------------------------------------------------------
sub esp,dword 28
; 1. -------------------------------------------------------------------------------
invoke_cdecl fopen,[ebp_name],[ebp_access]
invoke_error je,0,LoadBmpFile.quitError
invoke_returns_at [ebp_handle]
; 2. -------------------------------------------------------------------------------
invoke_cdecl malloc,BITMAPFILEHEADER_SIZE
invoke_error je,0,LoadBmpFile.quitError
invoke_returns_at [ebp_hBMFileHeader]
; 3. -------------------------------------------------------------------------------
invoke_cdecl malloc,BITMAPINFOHEADER_SIZE
invoke_error je,0,LoadBmpFile.quitError
invoke_returns_at [ebp_hBMInfoHeader]
; 4. -------------------------------------------------------------------------------
invoke_cdecl fread,[ebp_hBMFileHeader],1,BITMAPFILEHEADER_SIZE,[ebp_handle]
invoke_cdecl fread,[ebp_hBMInfoHeader],1,BITMAPINFOHEADER_SIZE,[ebp_handle]
; -------------------------------------------------------------------------------
; 5. Print info:
; -------------------------------------------------------------------------------
; -
; Calculate size w*h:
mov eax,dword [ebp_hBMInfoHeader]
mov ebx,dword [eax+BITMAPINFOHEADER.biWidth]
mov eax,dword [eax+BITMAPINFOHEADER.biHeight]
mov dword [ebp_w],ebx
mov dword [ebp_h],eax
mov edx,dword 0
mul ebx
; -
; Calculate size w*h*3:
mov ebx,eax
mov eax,3
mov edx,dword 0
mul ebx
mov ecx,eax
push ecx ; Save data size
; -
; Get bit count word:
mov eax,dword [ebp_hBMInfoHeader]
mov edx,dword 0
mov dx,word [eax+BITMAPINFOHEADER.biBitCount]
; Display:
invoke_cdecl printf, \
txt_bmp_info, \
[ebp_name], \
[eax+BITMAPINFOHEADER.biWidth], \
[eax+BITMAPINFOHEADER.biHeight], \
[eax+BITMAPINFOHEADER.biCompression], \
edx, \
ecx
; 6. -------------------------------------------------------------------------------
; Allocate memory
pop edx
push edx
mov dword [ebp_hDataLen],edx
invoke_cdecl malloc,edx
invoke_error je,0,LoadBmpFile.quitError
invoke_returns_at [ebp_hData]
mov edx,dword [ebp_data_ptr]
invoke_returns_at [edx]
; 7. -------------------------------------------------------------------------------
pop edx
invoke_cdecl fread,[ebp_hData],1,edx,[ebp_handle] ; Read data
; 8. -------------------------------------------------------------------------------
mov edx,dword [ebp_w]
mov eax,dword [ebp_w_ptr]
mov dword [eax],edx
mov edx,dword [ebp_h]
mov eax,dword [ebp_h_ptr]
mov dword [eax],edx
; 9. -------------------------------------------------------------------------------
; Flip output memory vertically:
; Get row size in bytes: w * 3
mov eax,dword [ebp_w]
mov edx,dword 0
mov ebx,dword 3
mul ebx
;Setup addresses
mov esi,dword [ebp_hData] ; Setup address on start
mov edi,dword [ebp_hData] ; Setup address on end
add edi,dword [ebp_hDataLen] ; Setup address on end
sub edi,eax ; edi - row size (eax)
;Save row size, source and dst addresses
push esi ;Stack +1 (1)
push edi ;Stack +2 (2)
push eax ;Stack +3 (3)
; Get column size in bytes: h / 2
mov eax,dword [ebp_h]
mov edx,dword 0
mov ebx,dword 2
div ebx
mov ecx,eax
LoadBmpFile.Reverser:
; ----------------
pop eax ;Stack -1 (2)
push eax ;Stack +1 (3)
; ----------------
push ecx ;Stack +1 (4)
; ----------------
mov ecx,eax
; ----------------
LoadBmpFile.Reverser.loopRow:
; Swap bytes esi, edi
mov al,byte [esi]
mov ah,byte [edi]
mov byte [edi],al
mov byte [esi],ah
; Inc addresses
add esi,dword 1
add edi,dword 1
; Dec loop counter
sub ecx,dword 1
cmp ecx,dword 0
jg LoadBmpFile.Reverser.loopRow
; ----------------
pop ecx ;Stack -1 (3)
; ----------------
pop eax ;Stack -1 (2)
pop edi ;Stack -1 (1)
pop esi ;Stack -1 (0)
; ----------------
add esi,eax ; esi + row size (eax)
sub edi,eax ; edi - row size (eax)
; ----------------
push esi ;Stack +1 (1)
push edi ;Stack +1 (2)
push eax ;Stack +1 (3)
; ----------------
sub ecx,dword 1
cmp ecx,dword 0
jg LoadBmpFile.Reverser
pop eax ;Stack -1 (2)
pop edi ;Stack -1 (1)
pop esi ;Stack -1 (0)
; 10. -------------------------------------------------------------------------------
; Quit Normal:
; -------------------------------------------------------------------------------
invoke_cdecl free,[ebp_hBMFileHeader]
invoke_cdecl free,[ebp_hBMInfoHeader]
invoke_cdecl fclose,[ebp_handle]
; -------------------------------------------------------------------------------
add esp,dword 28
; -------------------------------------------------------------------------------
mov eax,dword 0
pop ebp
ret 4*5
; Quit error:
; -------------------------------------------------------------------------------
LoadBmpFile.quitError:
; -------------------------------------------------------------------------------
add esp,dword 28
; -------------------------------------------------------------------------------
mov eax,dword -1
pop ebp
ret 4*5
; -------------------------------------------------------------------------------------
printGLError: ; This procedure prints OpenGL error
; -------------------------------------------------------------------------------------
push ebp
mov ebp,esp
pushad
invoke_stdcall glGetError
cmp eax,dword 0
jne printGLError.continue
;----------------------------------
invoke_cdecl printf,txt_glGetError,0,txt_glErrorN
;----------------------------------
popad
pop ebp
ret
;----------------------------------
printGLError.continue:
push eax
sub eax,dword 0x0500
mov edx,dword 0
mov ebx,dword 4
mul ebx
add eax,dword glError_types
pop edx
invoke_cdecl printf,txt_glGetError,edx,[eax]
popad
pop ebp
ret
; ---
; END ---
; ---
And that's it!
Byte!
Encryptor256!