News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

need help restarting and now continuing :)

Started by raneti, October 29, 2006, 01:15:17 AM

Previous topic - Next topic

raneti

i've been slacking off and i have a little trouble restarting to program as well as solving some problems i had even before i slacked off

since i am learnign to program and more as i go i need some help

here is the source

attached below as .zip

problems:

1. the "star map" matrix first line gets generated on y coordinate pixel 0 for some reason (assemble to get the visual); on line 331 i fill the y values of the array of points

2. it seems main diagonal points are missing  (x1y1 x2y2 etc)

3. i'm getting stuck on managing how to get this right. Normally i want the star map to be drawn on the center child window device context and i want it to resize properly along with the whole window. Preferably i want this to be done as neat as possible, i suspect with a mapping mode set to mm_isotropic.

4. advice?

[attachment deleted by admin]

Tedd

1. The problem seems to come from when you draw the list of points - you're using both esi and edi to access the same array (at overlapping offsets).
The end result is that you get 0 for the y value of the last 9 points.

2. If the points are supposed to be random, then you may or may not get points on the diagonal - I wouldn't expect them to necessarily be there.

3. You have to regenerate the starmap whenever the window resizes, but use the same random seed (i.e. only set it once at startup). Although, depending on your formula, the starfield may not look the same after re-sizing. The other option is to generate the points for a 'huge' window, and then scale the co-ordinates when you redraw.

4. Start again - use this version only as reference; don't copy and paste from it!
First just do a single window with the starfield in, you can add the other windows later.
Also, try to do it without using the fpu (I recognise the example you've modfied to get to this, so I know why you have been using it.) You only need to use MUL and DIV (or possibly IMUL and IDIV): a*(3/4) is the same as (a*3)/4 -- you should use the second form to keep accuracy.
Get it right for 10 stars first, then change the numbers to make 100 :wink
No snowflake in an avalanche feels responsible.

raneti

#2
On a preliminary look i think i got one of the problems:
The filling system for the matrix was: 1st_step{x0y0 x1y1 ... x9y9} 2nd_step{x0y1...x9y0} 3rd_step{x0y2...x9y1} ... and so on.
In my code 1st_step is missing so the main matrix diagonal doesn't get drawn. I have to go over the logic again to be sure of what i was doing, i only noted the big ideea down like formulas.


For the first line of the matrix i think its because the range of y is [0...5/7cyClient] not [1/7cyClient...6/7cyClient] as it should, but, the last line of the matrix gets drawn correctly(hmm). The first line gets drawn seemingly on 0 line of the child window because its coordinates are beyond that but cannot draw there instead since the hdc refers to a limited drawing area? I'll come back after i recheck all that again. * and / are comutative operations i don't see a reason to use one over the other. I'll pick the one that produces less clocks over least memory if posible as i try to minimize the code using non-fpu instructions. Using the FPU tought me to use it tough, and i think its faster than using only the CPU.


Think i should comment my code more? Since its my code i know mostly what it does but i suppose its hard to read its logic at a glance.
I use both esi and edi like this because i need two separate values cycling, and if i did it right and i remember also right, indexing through the array of points where x and y are double words is by indexing the bits between the values, 4 for the x value plus 4 for the y value i jump over is add esi, 8; same for edi. The rest of the logic i use is the one i stated earlier, dont' ask me why is it that twisted :), i ran into some problems when initializing the matrix the way i wanted and this is the first viable solution i found. The second one was doing {x0y0, x10,y10...} {x1y1, x11y11...}. This is because i "preplaced" the coordinates so they can't be laid but in these orders w/o anymore calculations.

hutch--

raneti,

To address your original topic, the method that works for me most of the time is having two seperate approaches to writing code, the "bits" brain and the "app" brain. The "bits" brain is essentially that of making components, procedures, libraries etc ... where the "app" brain concentrates on writing applications, often out of some of the previously written bits.

This saves you from endlessly having to dream up new apps to keep yourself amused if that is the problem. Instead you make what you see as useful components which in turn make writing apps easier, faster and something like fun.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

Tedd

Quote from: raneti on October 30, 2006, 07:31:16 PM
For the first line of the matrix i think its because the range of y is [0...5/7cyClient] not [1/7cyClient...6/7cyClient] as it should, but, the last line of the matrix gets drawn correctly(hmm). The first line gets drawn seemingly on 0 line of the child window because its coordinates are beyond that but cannot draw there instead since the hdc refers to a limited drawing area? I'll come back after i recheck all that again.
No. If the co-ordinates are out of range, then you won't see the point drawn; they don't wrap. (I told you, some of the y co-ordinates are used as zero.) How about drawing each of the 'lines' in a different colour to help with debugging? :wink

Quote
* and / are comutative operations i don't see a reason to use one over the other. I'll pick the one that produces less clocks over least memory if posible as i try to minimize the code using non-fpu instructions. Using the FPU tought me to use it tough, and i think its faster than using only the CPU.
They are commutative 'mathematically.' However, integer operations don't keep arbitrary precission. As a result, (3*4)/5 does not give the same result as 3*(4/5). The answer should be 2.4, but it will be 2 or 0 depending which way you do it.
It is good to know how to use the fpu, for those times when integer arithmetic isn't appropriate, but it's definitely not faster in any way. (There are some tricks to do * and / faster than the mul and div instructions, but these are for limited cases, if you want to get into that.)

Quote
Think i should comment my code more? Since its my code i know mostly what it does but i suppose its hard to read its logic at a glance.
It always helps :wink (In particular for yourself when you come back to it a few months later and wonder what on earth is going on :lol)

If you want to write what you intend to do, in steps, in english (for one, what is the steps of the points -- {(0,1),...,(9,0)} could go anywhere in between) then we can take a proper look :U
No snowflake in an avalanche feels responsible.

raneti

I started getting a resistance to pure theoretical learning so this is my way of practical learning, learning as i do it and do it as i learn.
My plan on this is simple, getting this thing to be the framework in wich i work myself around a copy of Master of Orion 2(improving it i hope). I plan to include in this project of mine every aspect of programming i must learn and since in a game you can do it all it would work. The points are actually starting points where i would put icons(bitmaps) of stars and i'll make them interactive. I will do this all within windows api if possible(to aquire GDI and overall API competence) then perhaps make a little real-time battle engine in opengl or directx(to aquire further competence). Assembly is the real nuts and bolts language of choice for me. For example the OOP data hiding is really hiding data from me, i don't like loose ends in my code and methaphisical learning(as in knowing intuitively why a thing would behave the way it does, in the way OOP is handled and meant to work - it is RAD but for professionals i think). To get back to the point, this is the main event for now, getting the darn starmap to work(i think i'll call it galactic sector because there are no square galaxies  :toothy). The formula i put in there looks like that because its meant to provide this rule for the star map: no star is meant to be too close to another star(and i wouldn't want Einstein twiching in his grave because i generate stars that would collide); so, i created a grid in wich squares stars are randomly generated, the squares beeing a certain distance from each other thus serving the purpose of separating each star in its own sector(in a 2Dish look at least) also beeing the horizontal and vertical range in wich the star is generated. From this formula came the way i had to draw them, because their position in the grid is predetermined, any other placement would have okward results. I'm having a hard time determining how i would make the whole thing dynamic so it would move and resize corectly with the window but still be interactive so i'm gonna make it a static window(1024x768 meant) and eliminate the top child windows and use a normal windows menu instead(i'll give it more tought after i fix the star generation glitches). In this game i mean to copy one researches technology so in the future i will have to do two things, copy the tech math or make one of my own, learn to work with files, implement the whole thing and link it to the rest of the game. My greatest unknown thing about all this implementing the whole TBS system and a save-game system so this whole thing can move past the 0 turn :)

In this journey i plan using all the tehniques and things i can gather like using all i learned in Iczelions tutorials and all i will learn reading about making a TBS game. It doesn't have to be extra flashy at first just a solid framework i can keep working on. I know making a game sounds like a job on wich C++ would be used and Python etc. but on the other hand i looked at some free souce projects(including FreeOrion wich i believe it would take a huge amount of time for me just to get aquinted to and also is moving too slowly and including work in too many programming environments) and i also find people who actually know stuff but even they can't read the code easely. Anyway this is meant to be a learnign trip at first.

A question: would the code work the same way if i take all the star map generation code and make it a function(w/o parameters at first, i mean will the code be using the stack more thus be slower or still work as the inline way it is now?) I want for example to generate different star densities like having a scarce, medium and dense predefined star sector with a certain number of stars or even allowing any number of stars(within possiblity limits). I mean of putting it in a .dll and making threads of everything of course for practice and good programming practice as well :)

The only way of making the bitmapped areas wich will represent stars be interactive is creating a new class of child areas who would receive the mouse input(i know no other way at the moment). Is there another way?

Where to learn tehniques of working with files and managing quite a large database of items? I think its easy to use the functions that work with files but the tehniques have to be learned(Perhaps use an existing interface? Learnign XML and the way to handle it in my programs?)

Tedd

Quote from: raneti on November 02, 2006, 06:05:54 AM
A question: would the code work the same way if i take all the star map generation code and make it a function(w/o parameters at first, i mean will the code be using the stack more thus be slower or still work as the inline way it is now?) I want for example to generate different star densities like having a scarce, medium and dense predefined star sector with a certain number of stars or even allowing any number of stars(within possiblity limits). I mean of putting it in a .dll and making threads of everything of course for practice and good programming practice as well :)
Would it work the same? Well I'd hope so - assuming you write it correctly :P Would it be slower? That depends on how you use it. There is obviously a little overhead from having to push the parameters on the stack, then call, then get them at the other end, etc.. But in some cases, if you call a function regularly within a short space of time then it can turn out to be faster then a long set of inlines. Anyway, it's not going to slow it down by any noticeable amount. I would advise making it into a function for the flexibility, and readability. Dont spend too much time worrying about speed. Make it work first, then you can fix the bits that need speeding up (if there are any.)

Also, don't go out of your way trying to fit in every single 'technique' you can think of. Do what's necessary/appropriate for the task in hand - you'll pick up different things as you need them. (If you don't learn everything, that's because you don't need to :P)

Quote
The only way of making the bitmapped areas wich will represent stars be interactive is creating a new class of child areas who would receive the mouse input(i know no other way at the moment). Is there another way?
That is one way. Another is to check the point of each mouse-click against a list of squares representing the bitmapped areas - if it's in one of those squares then that bitmap was clicked. This would give you a lot more control (but require a little more work) and there are various ways to speed up this process so you don't need to check every single square each time (but first get it working. :bdg) And it avoids creating 200 child windows, which I wouldn't generally recommend.

Quote
Where to learn tehniques of working with files and managing quite a large database of items? I think its easy to use the functions that work with files but the tehniques have to be learned(Perhaps use an existing interface? Learnign XML and the way to handle it in my programs?)
Ask P1, he'll tell you (..to search! :lol)
You're going to have to do a little research on your own for this one - there are so many ways to handle these things, but they have been studied in detail by many people, so you shouldn't have any problem finding information.

No snowflake in an avalanche feels responsible.

raneti

Why don't i need to proto the winprok? Because of the OFFSET in this line :
mov wcex.lpfnWndProc, OFFSET WndProc?

PBrennick

raneti,
Something like that. It is because it is not being called using the invoke macro. The invoke macro is what requires proto-typing. There is a work-around for making it not necessary for invoke, either, but it is more trouble than it is worth.

Paul
The GeneSys Project is available from:
The Repository or My crappy website

raneti

#9
Ok i detected the logical bug but my fix doesn't work:
My code drawing the stars makes use of y-values index 100th through 109th wich don't exist(they happend to be 0 so they show this way when drawn) and doesn't use these y-values:
0, 11, 22, 33, 44, 55, 66, 77, 88, 99 wich also explains why theres no main diagonal in my drawn matrix.

mov counter, -1

label11::
dec ecx
push ecx
mov ecx, 10
add edi, 8 ; x0y1, x1y2...x10y12, x11y13
add counter, 10
mov eax, counter
mov edx, 8
mul edx
mov temp6, eax

label10::
mov temp7, edi
.if edi > temp6
mov eax, edi
sub eax, 80
mov temp7, eax
.endif

mov eax, apt[esi].x
mov edx, apt[temp7].y
add eax, 5
add edx, 5

push ecx
invoke Ellipse, hdc, apt[esi].x, apt[temp7].y, eax, edx
pop ecx

add esi, 8
add edi, 8

loop label10


*this whole thing works in multiples of 8
I am using a counter wich increments once every inner loop completion(total 10 times), adjusted to a multiple of 8 to properly index the array. This logically separates the points by the way they are picked from the array into "ranges"(y-values index) 0-9, 10-19 etc. Because in each inner loop the y-values go into the next "range" i check for it helped by the counter wich determines in wich range i am currently and i adjust the y-value apropriately.

This, ugly as it is, doesn't even work alltough the logic seems sound(you have to click once on the center child window to get the ugly visual).
EDIT: fixed redundant .if logic i made with no positive result.

raneti

The above code still doesn't work alltough i went through a full debug. There are no logic bugs i could find either but still it doesn't work. I'm aware of .if beeing replaced with jbe alltough i used > and should have been replaced with jb(a happy accident for me).

Tedd

Attach the whole project again and we'll take a look :wink
(It's unlikely the problem only comes from the short part you posted.)
No snowflake in an avalanche feels responsible.

raneti

It does come from that part somehow, reverting the code snip to its original makes it work like before.
Since my array contains the values and i'm just adjusting the indexing it should work, but it doesn't.
Nevertheless below is the new code:

[attachment deleted by admin]

Tedd

Okay, the offending line is:
mov edx, apt[temp7].y
which doesn't assemble like you'd expect it to (which has a lot to do with masm almost ignoring square brackets)  - what you actually get is mov edx,DWORD PTR [OFFSET apt + OFFSET temp7 + y] (I'm surprised it doesn't crash!)
You only get one level of indirection, so anything more (such as dereferencing a variable) requires an extra step to handle the extra indirection.
But, all you really need to do is use edi in the same way you've done with esi -- temp7 can easily be removed altogether..

    .IF (edi > temp6)
        sub edi,80
    .ENDIF

    mov eax, apt[esi].x
    mov edx, apt[edi].y

    ....



On another note, you can make your program endlessly more readable (and somewhat faster/more efficient) by employing the following function in place of your fpu code -- which is almost all of the form A*(B/C)

muldiv proc valA:DWORD,valB:DWORD,valC:DWORD
    ;return = A * B / C
    mov eax,valA
    mov edx,valB
    mov ecx,valC
    mul edx
    div ecx
    ret
muldiv endp

Doing so will allow you to see what's actually going on, and then give you chance to re-arrange the code so it's clear that it works, and so you can see how to remove a lot of the messing about with temp variables (which only make it even less easier to understand.)
{There is actually already a MulDiv function in kernel32, but the extra overhead of calling it isn't worth it, plus it has to do other checking; and you can see what's going on with this one, allowing the possibility for certain optimsations (see below..)}

If you're feeling really adventurous, you can turn that function into a macro (an opportunity to learn how to use macros :wink) which handles the special cases:
- multiply by 0 ==> 0
- multiply by 1 ==> no need to multiply
- multiply by 2 ==> add eax,eax
- multiply by 4 ==> shl eax,2
- divide by 0 ==> error!
- divide by 1 ==> no need to divide
- ...etc...
which means all of this checking is done at assemble time (rather than run-time), the code is inlined, and you get more optimised code, in addition to more readable code.
No snowflake in an avalanche feels responsible.

raneti

thanks, you're a life saver :U Not sure what to do now i'll let you know if i made it through editing this post, i use that stuff in the invoke Ellipse as well.
Quotemov edx,DWORD PTR [OFFSET apt + OFFSET temp7 + y] (I'm surprised it doesn't crash!)
this is almost funny, tricky error. This is because masm treats [] only as index and not dereferencing(not the case for registers wich seem to be dereferenced w/o problems in such cases) ? Lemme understand this case tough, if it were apt[edi].y (where edi == 8 for example) it would've been assembled as apt[8+y]? I don't understand the +y part. In olly it appears as 00401611  |. 8B95 F02F4000  ||MOV EDX,DWORD PTR SS:[EBP+402FF0]

If i remove temp7(from indexing i will anyway :) and use edi alone i will use y-values from indexing 0-9 because, it will sub 80 the first time around when it reaches apt[10].y wich instead turns into apt[0].y, after wich temp 6 get incremented and will always be ahead of edi. The result is i will use apt[0].y through apt[9].y twice then the code will resume doing it the old erroneous way.

I'll look into macros(hope they are covered in AoA). Do you know perhaps wich intel book handles memory arhitecture because i lost the chapters name. I need a good read on olly usage too i can't folow most of the interface.

EDIT: yep it works now, i got to figure how to make it work correctly(i ran out of registers and since i cannot dereference memory inside a index i see no solution yet).