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.
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 :().
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
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.
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!
i think it is similar to C, except the calling parameters are pushed in reverse order
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?
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?
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...
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!
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 ?"
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
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 )
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
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.
.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?
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
.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
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!
QuoteThanks so much jj2007, that's it!
Dave <----- chopped liver :'(
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!
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
Thanks. I thought it was something similar. I got all my code working now. Thanks everyone!
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.................