flat assembler
Message board for the users of flat assembler.

flat assembler > DOS > Simple sprite editor

Author
Thread Post new topic Reply to topic
lutetia



Joined: 21 Oct 2012
Posts: 5
This is my first dos program in fasm. Source might be useful to someone.
It's pixel editor in 320x200 video mode. You can make sprites from 3x3 to 40x40 in size and save it. Runs fine on all windows xp machines that I tried. More info in readme.txt


Description:
Download
Filename: sprite05.zip
Filesize: 19.89 KB
Downloaded: 165 Time(s)



Last edited by lutetia on 28 Jan 2013, 13:48; edited 3 times in total
Post 15 Dec 2012, 20:17
View user's profile Send private message Reply with quote
HaHaAnonymous



Joined: 02 Dec 2012
Posts: 1171
Location: Unknown
Stupid post removed.


Last edited by HaHaAnonymous on 28 Feb 2015, 22:11; edited 1 time in total
Post 15 Dec 2012, 20:19
View user's profile Send private message Reply with quote
DOS386



Joined: 08 Dec 2006
Posts: 1904
> This is my first dos program in fasm

Welcome and COOL, it does something (see shot) Smile

BUG's:

* filenames are too long
* doesn't restore screen at exit
* your graphics files should not have an extension ".TXT" as they are not text, maybe ".LSE" instead, and even better hold a Sigi like "!LSE!",0,$FF,$1A (why???)
* besides your private file format, you could support some of existing (bad) formats like (a subset of) BMP
* the binary is bloated - buffers should be outside
* absurdly high numbers (see shot) - uninitialized var's ?
* size is obscure/invisible - how is it supposed to work ?
* binary depends from some ".TXT" files and doesn't whine if they are not found - better include the data into the binary
* you call both BIOS and DOS to write onto the graphics screen - better parse the font yourself
* no way to exit by keypress (for example <ALT>-<X>)

EDIT : deleted obsolete bugshot

_________________
Bug Nr.: 12345

Title: Hello World program compiles to 100 KB !!!

Status: Closed: NOT a Bug


Last edited by DOS386 on 17 Dec 2012, 06:17; edited 1 time in total
Post 16 Dec 2012, 12:26
View user's profile Send private message Reply with quote
lutetia



Joined: 21 Oct 2012
Posts: 5
Thank you for your guidance.
*So does .asm and .inc file names have to be dos style not more than 8 symbols long?
*Those absurdly high numbers probably are from me assuming that eax register initially is zero. Since I deal with ax only and then output numbers on the screen that are in eax.
*"buffers should be outside". Do you mean instead of:
buffer1 db 1600d
i should do something different?
Post 17 Dec 2012, 00:51
View user's profile Send private message Reply with quote
DOS386



Joined: 08 Dec 2006
Posts: 1904
lutetia wrote:
.asm and .inc file names have to be dos style not more than 8 symbols long?


This would be cool in DOS stuff.

> absurdly high numbers probably are from me assuming that
> eax register initially is zero. Since I deal with ax only and then
> output numbers on the screen that are in eax

easy to fix

> "buffers should be outside". Do you mean instead of:
> buffer1 db 1600d
> i should do something different?

1. Use always "rb" and never "db" for buffers (writable locations), at program start, clear them all, and then set non-ZERO values (like the two "40")

2. Put all rb's at program end rather than in the middle, that way, they will not bloat the binary (see HEX dump of your COM binary)

seems you updated the attach (untested)
Post 17 Dec 2012, 03:58
View user's profile Send private message Reply with quote
lutetia



Joined: 21 Oct 2012
Posts: 5
I'll keep updating it.

Added program exit on escape key press.
Fixed program exit code.
Changed graphics file extensions to .lse
Added binary dependent files missing at loading time error message.
Hopefully those high numbers are fixed too.
Fixed names.

I didn't know that rb at the end of file won't bloat the binary, thank you.

So memory location defined as
Code:
xCoord DB 40d
is not meant to be overwritten? Lets say
Code:
MOV [xCoord], 39d
Post 17 Dec 2012, 04:56
View user's profile Send private message Reply with quote
DOS386



Joined: 08 Dec 2006
Posts: 1904
lutetia wrote:
I'll keep updating it.

...
...
...


COOL ... COOL ... COOL ... COOL ... COOL Smile

Quote:
So memory location defined as
Code:
xCoord DB 40d
is not meant to be overwritten? Lets say
Code:
MOV [xCoord], 39d


You can overwrite it and it will work ... and you will find much old (MASM) code doing that way ... but it's a bad habit for multiple reasons:

1. it (usually) doesn't work in protected mode
2. you risk corrupting your code rather than "only" corrupting your data - harder to debug
...

Code:
... ret ;---- xcoord: db 40 ycoord: db 40 procblah: push ax ... MOV al, 39 MOV [yCoord], al ; OK ... MOV [yCoord], ax ; !!! BUG !!!


> I didn't know that rb at the end of file won't bloat the binary, thank you

Make sure to "manually" clear all those buffers then (REP STOSW).

_________________
Bug Nr.: 12345

Title: Hello World program compiles to 100 KB !!!

Status: Closed: NOT a Bug
Post 17 Dec 2012, 05:22
View user's profile Send private message Reply with quote
DOS386



Joined: 08 Dec 2006
Posts: 1904
Image

Seems most BUG's are gone Smile
Post 17 Dec 2012, 06:26
View user's profile Send private message Reply with quote
Picnic



Joined: 05 May 2007
Posts: 1240
Location: Icarian Sea
My objection is about the file format, i mean i can't use the creations elsewhere outside the editor. BMP support would be useful.

Nevertheless is a fine program lutetia.
Post 18 Dec 2012, 10:34
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1388
Location: Toronto, Canada
I miss those sprite games from DOS...
Post 18 Dec 2012, 15:50
View user's profile Send private message Send e-mail Reply with quote
uart777



Joined: 17 Jan 2012
Posts: 369
Excellent work, lutetia!

Just one question: Why did you choose DOS? Do you not have good Windows code? Or are you an old-school 90s programmer? Wink

You can draw directly to linear memory VGA/buffer (vga[x]=COLOR) then copy it to primary display using BitBlt/StretchBlt. Something like this:

Code:
macro os.define.vga { if OS='w' HBITMAP vga.hbm BITMAPINFO vga.bmi RECT vga.rect end if } function os.create.vga, w, h if OS='w' try [vga.hbm]=CreateBitmap \ [screen.w], [screen.h], 32, 1, [vga] calla !memory.zero, vga.bmi.h, BITMAPINFOHEADER.$ let [vga.bmi.h.biSize]=BITMAPINFOHEADER.$,\ [vga.bmi.h.biWidth]=[os.w],\ eax=[os.h], neg eax,\ [vga.bmi.h.biHeight]=eax,\ [vga.bmi.h.biBitCount]=32,\ [vga.bmi.h.biPlanes]=1 ShowCursor 0 end if endf function os.show.vga if OS='w' SetDIBits [_dc], [vga.hbm], 0, [screen.h],\ [vga], vga.bmi, 0 draw.bitmap.w [vga.hbm], 0, 0, [os.w], [os.h] let [vga.rect.left]=0, [vga.rect.top]=0,\ [vga.rect.right]=[os.w], [vga.rect.bottom]=[os.h] InvalidateRect [_hwnd], vga.rect, 0 end if endf


I agree with Picnic, it should support a standard format (ie, .BMP) and that's very easy to do (ASM is easy, life is HARD!):

Code:
; $$$$$$$$$$$$$$ Z77 ASM LIBRARY $$$$$$$$$$$$$$$$$ ; ************** SUNGOD SOFTWARE ***************** ; ?????????????????? BMP.INC ????????????????????? bmp.header db 54 dup(0) bmp.sign equ word [bmp.header] bmp.file.size equ dword [bmp.header+2] bmp.offset equ dword [bmp.header+10] bmp.fourty equ dword [bmp.header+14] ; 40 bmp.w equ dword [bmp.header+18] bmp.h equ dword [bmp.header+22] bmp.n.planes equ word [bmp.header+26] ; 1 bmp.bpp equ word [bmp.header+28] bmp.compress equ dword [bmp.header+30] bmp.image.size equ dword [bmp.header+34] bmp.n.colors equ dword [bmp.header+46] TEXT bmp.ext='.BMP' ; load 8*/24/32BPP .BMP to 32BPP image. ; if success, return allocated image address ; in eax and w/h in ecx/edx. return 0 if error. ; (* 8BPP has not been fully tested) function load.bmp, file locals image, p, x, y, w, h,\ bpp, n, size, row, a, wb,\ palette, n.colors, palette.size let [image]=0,\ [p]=[?t], [palette]=0 text.copy [p], [file] change.ext \ [p], bmp.ext open [p] ; open and read header fail .error read bmp.header, 54 cmp bmp.sign, 'BM' ; verify signature jne .error let ecx=bmp.w,\ ; dimensions edx=bmp.h,\ [w]=ecx, [h]=edx,\ ecx*edx, [n]=ecx,\ ; # pixels ecx<<2, [size]=ecx ; size in bytes in memory movsx ecx, bmp.bpp ; BPP let [bpp]=ecx, eax=[w] .if ecx=32 ; width in bytes in file let eax<<2 .else.if ecx=24 let eax*3 .else.if ecx=8 ; w=w .else ; not supported yet jmp .error .end .if eax&3 align.n eax, 4 let [a]=ecx .else let [a]=0 .end get [image]=\ allocate [size] ; allocate image pointer fail .error .if [bpp]<=8 ; create/load palette? let eax=1,\ ecx=[bpp], eax<<cl,\ [n.colors]=eax,\ eax<<2,\ [palette.size]=eax get [palette]=\ allocate [palette.size] let [p]=[palette] .loop [x]=0 to [n.colors] read [p], 4 add [p], 4 .endl .end .loop [y]=0 to [h] let ecx=[h],\ ; row=h-y-1 (upside down) ecx-[y], ecx-1,\ [row]=ecx, ecx*[w],\ ecx<<2,\ ; ecx=row*w*4 eax=[image],\ ; line address = eax+ecx, [p]=eax ; &(image+(h-y-1)*w*4) .loop [x]=0 to [w] .if [bpp]=32 ; 32BPP read [p], 4 .else.if [bpp]=24 ; 24BPP let eax=[p],\ dword [eax]=0 read [p], 3 ; read BGR24 as RGB24 .else.if [bpp]=8 ; 8BPP read.c ; read palette+index*4 let eax<<2,\ eax+[palette],\ edx=[p],\ ecx=[eax],\ [edx]=ecx .end add [p], 4 ; advance pointer .endl .if [a] ; skip alignment after seek.r [a], YES .end .endl destroy [palette] close let eax=[image],\ ; return image ecx=[w], edx=[h] ; and w/h in ecx/edx escape .error: close let eax=0 endf ; save .BMP. "image" is pixel array function save.bmp, file, image, w, h, bpp locals p, x, y, row, a, n, wb, size let [p]=[?t] text.copy [p], [file] change.ext [p], bmp.ext create [p] fail .error let ecx=[bpp], eax=[w] .if ecx=32 ; width in bytes in file let eax<<2 .else.if ecx=24 let eax*3 .else.if ecx=8 ; w=w .end .if eax&3 align.n eax, 4 let [a]=ecx .else let [a]=0 .end let [wb]=eax,\ eax*[h], [size]=eax memory.zero bmp.header, 54 let \ bmp.sign='BM',\ ecx=[w], bmp.w=ecx,\ ecx=[h], bmp.h=ecx,\ ecx=[bpp], bmp.bpp=cx,\ bmp.offset=54,\ bmp.fourty=40,\ bmp.n.planes=1,\ ecx=[size],\ bmp.image.size=ecx write bmp.header, 54 let eax=[image],\ [p]=eax ; write image pixels... .loop [y]=0 to [h] let ecx=[h],\ ecx-[y], ecx-1,\ ; row=h-y-1 (upside down) [row]=ecx,\ ecx*[w], ecx<<2,\ ; line address = eax=[image],\ ; &(image+(h-y-1)*w*4) eax+ecx, [p]=eax .loop [x]=0 to [w] ; write pixels .if [bpp]=24 write [p], 3 .else.if [bpp]=32 write [p], 4 .end add [p], 4 ; advance pointer .endl .loop [n]=0 to [a] ; skip alignment after write.c 0 .endl .endl close let eax=1 jmp @f .error: close let eax=0 @@: endf


Guru: Me too Smile Love the old-school games, especially Commodore64 International Karate. Anyone remember this? Me and my dad - who was an electronics engineer who specialized in robotics - used to play the thinking games like 7th guest and 11th hour.

lutetia: Thanks for sharing Smile
Post 19 Dec 2012, 04:35
View user's profile Send private message Reply with quote
DOS386



Joined: 08 Dec 2006
Posts: 1904
Code:
; load 8*/24/32BPP .BMP to 32BPP image. ; if success, return allocated image address ; in eax and w/h in ecx/edx. return 0 if error. ; (* 8BPP has not been fully tested)


The code runs in 8 bpp mode so far: http://wiki.multimedia.cx/index.php?title=BMP

Note that BMP always (?) stores lines from bottom to the top.
Post 20 Dec 2012, 02:35
View user's profile Send private message Reply with quote
lutetia



Joined: 21 Oct 2012
Posts: 5
uart777 wrote:


Just one question: Why did you choose DOS? Do you not have good Windows code? Or are you an old-school 90s programmer? Wink

You can draw directly to linear memory VGA/buffer (vga[x]=COLOR) then copy it to primary display using BitBlt/StretchBlt. Something like this:

I agree with Picnic, it should support a standard format (ie, .BMP) and that's very easy to do (ASM is easy, life is HARD!):


DOS looks easier. Eventually I'd like to graduate in windows.
Thank you for these examples.
Post 20 Dec 2012, 18:54
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
DOS386 wrote:
Note that BMP always (?) stores lines from bottom to the top.
BITMAPINFOHEADER.biHeight < 0 indicates top-down bitmap (OS/2 legacy IIRC). Some restrictions apply (it can't be compressed, e.g.)
Post 21 Dec 2012, 05:43
View user's profile Send private message Reply with quote
uart777



Joined: 17 Jan 2012
Posts: 369
Quote:
DOS looks easier. Eventually I'd like to graduate in windows.

Mode 13h is a good place to start. Ultimately, you may decide to move onto VESA for high color/resolution.

In art programs, 8BPP is not enough colors to represent the VGA and all images (unless all palette registers are grayscale or intensities of one color). High/true color (15/16/24) is required for image effects (example, adjust lightness, hue, saturation, etc) and artistic brush styles (example, airbrush, textures, smear).

All you need for drawing/animation is linear VGA, images and timer (in BIOS, A0000000h = VGA memory and 0000046Ch = 18.2 MHZ clock) and it's possible to simulate these in any OS. You can still write your own graphics and define portable custom controls - by drawing lines, rectangles, images and raster text - without using OS-specific code.

IMAGE SIZE, MIRROR, ROTATE

Code:
; size pixel array using "nearest neighbor" ; (accurate, interpolation is not) function size.image, image, w, h locals i, j, p, s, x1, y1, w1, h1, x2, y2 let eax=[image], [s]=[?image.p+eax],\ [w1]=[?image.w+eax], [h1]=[?image.h+eax] try [p]=scratch [w], [h] ; ratio=(size<<16)/size let eax=[w1], eax<<16, eax/[w], [x1]=eax,\ eax=[h1], eax<<16, eax/[h], [y1]=eax .loop [i]=0 to [h] .loop [j]=0 to [w] ; offset=(n*ratio)>>16 let eax=[j], eax*[x1], eax>>16, [x2]=eax,\ eax=[i], eax*[y1], eax>>16, [y2]=eax ; destiny[(i*w2)+j]=source[(y2*w1)+x2] let eax=[i], eax*[w], eax+[j], eax<<2,\ eax+[p], ecx=[y2], ecx*[w1], ecx+[x2],\ ecx<<2, ecx+[s], [eax]=[ecx] ; *p=*s .endl .endl end.scratch [image] endf ; size by percentage (integer) function size.image.p, image, p locals w, h, iw, ih let eax=[image],\ [iw]=[?image.w+eax], [ih]=[?image.h+eax],\ eax=[iw], eax*[p], ecx=100, eax/ecx, [w]=eax,\ eax=[ih], eax*[p], ecx=100, eax/ecx, [h]=eax size.image [image], [w], [h] endf ; mirror; flip 'h'orizontal, 'v'ertical ; or 'd'iagonal function mirror.image.h, image locals x, y, w, h, p, s let eax=[image], [s]=[?image.p+eax],\ [w]=[?image.w+eax], [h]=[?image.h+eax] try [p]=scratch [w], [h] .loop [y]=0 to [h] .loop [x]=0 to [w] ; p[x+(y*w)]=s[(w-x-1)+(y*w)] let edx=[w], edx-[x], edx--, ecx=[y],\ ecx*[w], edx+ecx, edx<<2, edx+[s],\ eax=[x], eax+ecx, eax<<2, eax+[p],\ [eax]=[edx] .endl .endl end.scratch [image] endf function mirror.image.v, image locals x, y, w, h, p, s let eax=[image], [s]=[?image.p+eax],\ [w]=[?image.w+eax], [h]=[?image.h+eax] try [p]=scratch [w], [h] .loop [y]=0 to [h] ; memory.copy &p[y*w], &s[(h-y-1)*w], w*4 let edx=[h], edx-[y], edx--, edx*[w],\ edx<<2, edx+[s], eax=[y], eax*[w],\ eax<<2, eax+[p], ecx=[w], ecx<<2 memory.copy eax, edx, ecx .endl end.scratch [image] endf function mirror.image, image, way .if [way]='h' mirror.image.h [image] .else.if [way]='v' mirror.image.v [image] .else.if [way]='d' mirror.image.h [image] mirror.image.v [image] .end endf ; rotate 'r'ight (90) or 'l'eft (270) function rotate.image, image, way locals x, y, w, h, p, s, col, row let eax=[image], [s]=[?image.p+eax],\ [w]=[?image.w+eax], [h]=[?image.h+eax] try [p]=scratch [h], [w] ; w/h reversed .if [way]='r' ; right, 90 let eax=[h], eax--, [col]=eax .loop [y]=0 to [h] .loop [x]=0 to [w] let eax=[x], eax*[h], eax+[col], eax<<2,\ eax+[p], edx=[y], edx*[w], edx+[x], edx<<2,\ edx+[s], [eax]=[edx] .endl let [col]-- .endl .else.if [way]='l' ; left, 270 let [col]=0 .loop [y]=0 to [h] let eax=[w], eax--, [row]=eax .loop [x]=0 to [w] let eax=[row], eax*[h], eax+[col], eax<<2,\ eax+[p], edx=[y], edx*[w], edx+[x], edx<<2,\ edx+[s], [eax]=[edx], [row]-- .endl let [col]++ .endl .end end.scratch [image] let eax=[image],\ ; adjust location edx=[?image.x+eax], ecx=[w], ecx>>1, edx+ecx,\ ecx=[h], ecx>>1, edx-ecx, [?image.x+eax]=edx,\ edx=[?image.y+eax], ecx=[h], ecx>>1, edx+ecx,\ ecx=[w], ecx>>1, edx-ecx, [?image.y+eax]=edx endf

Ultimate HL features: http://board.flatassembler.net/topic.php?t=14768

lutetia: Wish there was a site for modern ASM graphics programmers.
Post 27 Dec 2012, 00:16
View user's profile Send private message Reply with quote
lutetia



Joined: 21 Oct 2012
Posts: 5
Added BMP support finally.
Post 28 Jan 2013, 13:50
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >

Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 2004-2018, Tomasz Grysztar.

Powered by rwasa.