The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: ASMCoderD on January 05, 2010, 12:47:42 AM

Title: Help on Bresenham Line Algo
Post by: ASMCoderD on January 05, 2010, 12:47:42 AM
Hello everyone.

I am having trouble implementing a bresenham line algorithm. I have tried for a few days without success. This is for an external .DLL
Note that I do know how to plot a pixel to the screen. Could anyone give me an example.

Thanks in advance.
Title: Re: Help on Bresenham Line Algo
Post by: raymond on January 05, 2010, 04:24:10 AM
The easiest way to draw a strait line is to use Windows "LineTo" function (unless you are trying to do that under 16-bit DOS as homework :().
Title: Re: Help on Bresenham Line Algo
Post by: dedndave on January 05, 2010, 09:22:36 AM
i played with Bresenham line and circle routines - about 10 years ago - got them working ok - don't remember the code   :bg
post the code you have in a zip   :U
but, google is your friend - lol - there are a lot of examples online
Title: Re: Help on Bresenham Line Algo
Post by: Farabi on January 05, 2010, 10:55:54 AM
I dont know about bresenham algo, but if you are going to make a line function this would help.

1. Get the Hypotenusa (This is my term for the distance between 2 point)


dx=x2-x1
dy=y2-y1

dx=dx*dx
dy=dy*dy

hyp=sqrt(dx+dy)



Then make a loop for hyp times.

loop_start:
pos_x= loop_cnt/hyp *hyp
pos_y=loop_cnt/hyp*hyp
jmp loop_start


I dont remember it well since I created it 3 years ago.
But you can always check Donkey Graphics lib for this algo.
Title: Re: Help on Bresenham Line Algo
Post by: ASMCoderD on January 05, 2010, 05:23:18 PM
Hello Everone:

Actually, I got the Bresenham algorithm working but I ran into secondary problems. The algorithm works but I don't have enough variables (32 bit: DWORD) left. There's EBP and ESP but those don't work with the C or STDCALL conventions (There're reserved). I tried the BASIC Convention but my .def file gives errors. Could anyone tell me how to setup the BASIC calling convention?  I am on windows, so thanks for the LineTo function, still, I need to know how to use the BASIC convention.

Thanks all for the responses!
Title: Re: Help on Bresenham Line Algo
Post by: dedndave on January 05, 2010, 05:25:40 PM
i think it is similar to C, except the calling parameters are pushed in reverse order
Title: Re: Help on Bresenham Line Algo
Post by: ASMCoderD on January 05, 2010, 05:30:30 PM
I know that but when I make a procedure in my asm file:

ProcName Proc BASIC, Arg1:DWORD, Arg2:DWORD

;code here

endp

and then put in my .def file:

EXPORTS ProcName

I get an error about error an .def file. How do I fix this?

Title: Re: Help on Bresenham Line Algo
Post by: ASMCoderD on January 05, 2010, 05:45:20 PM
Sorry to double post here, but if it isn't possible to use the BASIC convention, can I link to another routine to finish without losing my current values in my routine?
Title: Re: Help on Bresenham Line Algo
Post by: jj2007 on January 05, 2010, 06:16:56 PM
It would be a lot easier to understand your problems if you posted your code, as everybody does.
Normally, you cannot run out of variables - out of registers, yes, but you need registers only for really speed-critical tasks. For all other purposes, local or global variables are just fine...
Title: Re: Help on Bresenham Line Algo
Post by: ASMCoderD on January 05, 2010, 06:33:08 PM
Therein could lie my problem. Excuse me for sounding silly here, but what are local and global variables? I am used to only using registers.

Thanks!
Title: Re: Help on Bresenham Line Algo
Post by: dedndave on January 05, 2010, 06:42:45 PM
they are essentially memory locations
local variables are more or less temporary with scope inside the procedure
generally speaking, local variables are assigned space on the stack and are accessed by [ebp-4*n]
global variables have scope outside the procedure
generally speaking, global variables are allocated a permanent memory location

QuoteI am having trouble implementing a bresenham line algorithm. I have tried for a few days without
success. This is for an external .DLL Note that I do know how to plot a pixel to the screen.

as Jochen has suggested, this doesn't tell us very much   :P
we have no idea what your problem really is
to help you make better posts, pretend you were trying to answer the question(s) you are asking
then ask yourself, "is there enough information there for us to provide help ?"
Title: Re: Help on Bresenham Line Algo
Post by: jj2007 on January 05, 2010, 07:05:19 PM
Quote from: ASMCoderD on January 05, 2010, 06:33:08 PM
what are local and global variables?

Have a look at the snippet posted here (http://www.masm32.com/board/index.php?topic=13062.0). Global variables are defined in .data (initialised with any value you like) or .data? (zero). They are marginally slower than LOCAL variables but have the advantage to be permanent.

Note also that you can use eax, ebx, ecx, edx, esi, edi but are supposed to preserve ebx esi edi by pushing them at the start of a procedure and popping them in reversed order before the ret statement. Sorry if that is too obvious :wink
Title: Re: Help on Bresenham Line Algo
Post by: dedndave on January 05, 2010, 07:13:37 PM
Jochen - i thought the fastest addressing mode was immed direct - no ?

        mov     eax,SomeLabel

faster than

        mov     eax,[ebp-4]

am i wrong (again  :P )
Title: Re: Help on Bresenham Line Algo
Post by: jj2007 on January 05, 2010, 07:34:31 PM
Quote from: dedndave on January 05, 2010, 07:13:37 PM
Jochen - i thought the fastest addressing mode was immed direct - no ?

        mov     eax,SomeLabel

faster than

        mov     eax,[ebp-4]

am i wrong (again  :P )

No idea :bg

530     cycles for [ebp]
529     cycles for [MyDword]


Quote.nolist
include \masm32\include\masm32rt.inc
.686
include \masm32\macros\timers.asm         ; get them from the Masm32 Laboratory (http://www.masm32.com/board/index.php?topic=770.0)
LOOP_COUNT   = 100000

.data?
MyDword   dd ?

.code
start:
   sub ebp, 4
   counter_begin LOOP_COUNT, HIGH_PRIORITY_CLASS
      REPEAT 100
      mov ecx, [ebp]
      mov eax, [ebp]
      mov [ebp], ecx
      mov [ebp], eax
      ENDM
   counter_end
   add ebp, 4
   print str$(eax), 9, "cycles for [ebp]", 13, 10

   counter_begin LOOP_COUNT, HIGH_PRIORITY_CLASS
      REPEAT 100
      mov ecx, MyDword
      mov eax, MyDword
      mov MyDword, ecx
      mov MyDword, eax
      ENDM
   counter_end
   print str$(eax), 9, "cycles for [MyDword]", 13, 10

   inkey chr$(13, 10, "--- ok ---", 13)
   exit
end start

Title: Re: Help on Bresenham Line Algo
Post by: ASMCoderD on January 05, 2010, 07:58:28 PM
Here is my code:

MyLine proc C, Layer:DWORD, Xpos:DWORD, Ypos:DWORD, Xpos2:DWORD, Ypos2:DWORD, Col:DWORD
    local ek:DWORD
    local y:DWORD
    local x:DWORD

    mov eax, Xpos
    mov ebx, Xpos2
    .if eax > ebx
        xchg eax, ebx
    .endif

    mov ecx, Ypos
    mov edx, Ypos2
    .if ecx > edx
        xchg ecx, edx
    .endif


    mov edi, ebx
    sub edi, eax ; dx
   
    mov esi, edx
    sub esi, ecx ; dy
   
    mov edx, esi
    shl edx, 1
    sub edx, edi
    mov ek, edx ; ek

    mov esi, ek
    add esi, edi ; dn
   
    mov edx, ek
    sub edx, edi
    mov edi, edx ; dp
   
    mov x, ebx ; x   
   
    draw:
    inc eax

    .if ek < 0
        add ek, esi
    .else
        add ek, edi
        inc ecx
    .endif

    mov edx, ecx
    mov y, edx
    shl y, 6
    shl edx, 8
    add edx, y
    add edx, eax
    add edx, dword ptr [Layer]
    add edx, 4
    mov ebx, dword ptr [Col]
    mov dword ptr [edx], ebx
   
    .if eax <= x
        jmp draw
    .endif

    ret
   
MyLine endp


I figured out very quickly how to use local integers and that solved one problem. However, the new problem seems to be here:

    .if ek < 0
        add ek, esi
    .else
        add ek, edi
        inc ecx
    .endif


I am not sure if it exits right. It seems to draw an even diagonal line. It may be a problem with the algo. I'm not sure however, I could be looking at the wrong area.

Thanks for all the help so far, I really appreciate it.
Title: Re: Help on Bresenham Line Algo
Post by: ASMCoderD on January 05, 2010, 10:20:47 PM
    .if ek < 0
        add ek, esi
    .else
        add ek, edi
        inc ecx
    .endif


Does the previous code do the following: (Pseudo code)

if ek < 0 then
ek = ek + esi
else
ek = ek + edi
ecx = ecx + 1
endif


Or does it do something else?
Title: Re: Help on Bresenham Line Algo
Post by: dedndave on January 05, 2010, 10:37:29 PM
it may - lol
i think "<" is for signed comparison, i.e. signed numbers
try ".lt" for less than - unsigned
you may want to check the masm manual - i am not good with these   :P
Title: Re: Help on Bresenham Line Algo
Post by: jj2007 on January 05, 2010, 10:49:57 PM
    .if ek < 0
        add ek, esi
    .else
        add ek, edi
        inc ecx
    .endif


Sure, it should do what it seems to do. But there is a pitfall in Masm that should be displayed in fat letters on top of this forum: .if eax < 0 is never true. Try this complete little Windows application:
include \masm32\include\masm32rt.inc

signed equ sdword ptr

.code
start: mov eax, -123
.if eax<0
MsgBox 0, "Great, it's below zero", "Hi", MB_OK
.else
MsgBox 0, "You are cheating!!", "Hi", MB_OK
.endif
exit
end start


The reason is that Masm does by default unsigned comparisons:
mov eax, -123 means eax= 4294967173 - a number that is definitely above zero!!

The same happens to other DWORD variables. Fortunately, it is easy to solve this problem. Put this equate near the top of your code: signed equ sdword ptr (as shown above).

Then use .if signed ek<0, and the code will work correctly...
:thumbu
Title: Re: Help on Bresenham Line Algo
Post by: ASMCoderD on January 05, 2010, 11:28:04 PM
Thanks so much jj2007, that's it! Since ek < 0 was never true it wouldn't access that part of the code. I don't think I could have figured that out for a while.

Thanks!
Title: Re: Help on Bresenham Line Algo
Post by: dedndave on January 06, 2010, 12:22:22 AM
QuoteThanks so much jj2007, that's it!

Dave <----- chopped liver   :'(
Title: Re: Help on Bresenham Line Algo
Post by: ASMCoderD on January 06, 2010, 12:46:27 AM
Actually, I have one more question:

Suppose I decide to make a routine to draw a filled rectangle. Could I make it dependent on my Line routine? Would I use the invoke command? Or do I have to rewrite the whole routine?

Thanks!
Title: Re: Help on Bresenham Line Algo
Post by: jj2007 on January 06, 2010, 01:09:42 AM
Quote from: dedndave on January 06, 2010, 12:22:22 AM
Dave <----- chopped liver   :'(
Keep cool, my friend :8)

@ASMCoderD:
You would use invoke MyLine, arg1, arg2 or whatever, similar to a call in C or Basic or Fortran. Below a simple example.

include \masm32\include\masm32rt.inc

MyTest PROTO: DWORD, :DWORD

.code
AppName db "Masm32 is great!", 0
Hello db "A message:", 0

start:
invoke MyTest, offset AppName, addr Hello
exit

MyTest proc arg1:DWORD, arg2:DWORD
; LOCAL lv1, lv2, locbuf[260]:BYTE
  MsgBox 0, arg1, arg2, MB_OK
  ret
MyTest endp

end start
Title: Re: Help on Bresenham Line Algo
Post by: ASMCoderD on January 06, 2010, 01:13:13 AM
Thanks. I thought it was something similar. I got all my code working now. Thanks everyone!
Title: Re: Help on Bresenham Line Algo
Post by: dedndave on January 06, 2010, 01:42:42 AM
lol - i am fine, Jochen   :bg
actually, i was going to refer him to you for if/while/switch/macro stuff
it's just that.................