I've made a normal mapper based on a texture and heightmap:
load image "texture1.bmp",1,1
load image "texture2.bmp",2,1
make memblock from image 1,1
make memblock from image 2,2
width = memblock dword(1,0)
height = memblock dword(1,4)
depth = memblock dword(1,8)
make memblock 3,width*height*4+12
make memblock 4,width*height*4+12
write memblock dword 3,0,width
write memblock dword 3,4,height
write memblock dword 3,8,depth
write memblock dword 4,0,width
write memblock dword 4,4,height
write memblock dword 4,8,depth
lock pixels
for x = 0 to width-1
for y = 0 to height-1
location = (y * Width + x)*4 + 12
blue = memblock byte(1,location)
green = memblock byte(1,location+1)
red = memblock byte(1,location+2)
blue2 = memblock byte(2,location)
green2 = memblock byte(2,location+1)
red2 = memblock byte(2,location+2)
blue3 = (blue2*blue)
green3 = (green2*green)
red3 = (red2*red)
blue3 = sqrt(blue3)
green3 = sqrt(green3)
red3 = sqrt(red3)
x2 = (x + 1) mod width
x3 = (x + width - 1) mod width
y2 = (y + 1) mod height
y3 = (y + height - 1) mod height
location1 = (y2 * Width + x)*4 + 12
location2 = (y3 * Width + x)*4 + 12
location3 = (y * Width + x2)*4 + 12
location4 = (y * Width + x3)*4 + 12
xdiff = memblock byte(2,location4) - memblock byte(2,location3)
ydiff = memblock byte(2,location2) - memblock byte(2,location1)
zdiff = 131072 - xdiff*xdiff - ydiff*ydiff
zdiff = sqrt(zdiff)
red4 = (xdiff/2)+128
green4 = (ydiff/2)+128
blue4 = (zdiff/2)+128
If red4 > 255 then red4 = 255
If green4 > 255 then green4 = 255
If blue4 > 255 then blue4 = 255
If red4 < 0 then red4 = 0
If green4 < 0 then green4 = 0
If blue4 < 0 then blue4 = 0
`DOT x,y,RGB(red4,green4,blue4)
write memblock byte 3,location,blue3
write memblock byte 3,location+1,green3
write memblock byte 3,location+2,red3
write memblock byte 3,location+3,255
write memblock byte 4,location,blue4
write memblock byte 4,location+1,green4
write memblock byte 4,location+2,red4
write memblock byte 4,location+3,255
next y
next x
unlock pixels
delete image 1
make image from memblock 3,3
make image from memblock 4,4
If file exist("CombinedTexture.bmp") then delete file "CombinedTexture.bmp"
If file exist("NormalMap.bmp") then delete file "NormalMap.bmp"
save image "CombinedTexture.bmp",3
save image "NormalMap.bmp",4
delete memblock 1 : delete memblock 2 : delete memblock 3 : delete memblock 4
The optomist's right, The pessimist's right.