flat assembler
Message board for the users of flat assembler.
![]() Goto page Previous 1, 2, 3, 4, 5, 6, 7 Next |
Author |
|
AsmGuru62 12 Apr 2012, 20:03
I see... the console we looking at here right now is not a DOS console - it is a Win32 console application and the thread mentioned is not the way to go. If you planning a side scroller game, where your world scrolls around sideways and up and down -- you need Win32 application for that. Now, sidescrollers can be done in a couple of ways:
1. Tiled approach - in here you can have a 2D matrix of tiles. For example, you can have 256x256 tiles, each tile can be 16x16 pixels in size. Then, every time the worlds needs painting - you examine the scrollbars and figure out what tiles to start painting with. This way the wolds can be scrolled around following some action. Each tile has a type and image to be drawn: it can be anything you desire -- sea, ground, mountains, trees - i.e. nature based world. or it can be walls inside some building, like a castle or some base.... no limit, really. All you need is images for tiles and the map of the world -- where each tile is. 2. You can have polygon based world -- it will look better then tiles, because tiles will allow only square corners in your world. With polygons, you can have much better worlds -- better looking, I mean. More realistic. Here you should have a coordinate system for polygons, so you can paint each polygon. Also, the scroll bars will set up the point of origin for the window and you paint only polygons visible at this moment. Personally, I think #1 is easier for the beginner. |
|||
![]() |
|
AsmGuru62 12 Apr 2012, 20:06
Print the string like this one:
Code: NextLine db 0Dh,0Ah,0 And the console will print on next line. Or if you want to print multiple lines -- simply encode these bytes into text, like so: Code: Text2Lines db 'LINE #1',0Dh,0Ah,'LINE #2',0Dh,0Ah,0 |
|||
![]() |
|
Inagawa 12 Apr 2012, 20:29
I can print multiple lines. I know carriage return and line feed. But what if I want to make a call like this?
Code: invoke !Console.WriteLine, <'This is the first argument - %i', 0Dh, 0Ah>, eax ;<= EAX is the second argument That would be two arguments, but my !Console.WriteLine only supports one argument.. Win32 application.. I don't think I am ready for that. I will study console, since there is not much left to explore. And while creating some lame game I can at least focus on pure assembly in a console environment that I'll be already familiar with. I think that is what I must do. I want to learn it properly, so I don't have any gaps in knowledge later. Thanks for the info, though. Tiled approach would be my choice if I made the win32 app. Can I ask how complex do you consider OpenGL to be in assembly? Because that is my distant goal anyway, may as well break any dreams and hopes now. ![]() |
|||
![]() |
|
AsmGuru62 12 Apr 2012, 20:35
I think you can find a few OpenGL codes here on the FASM forum.
|
|||
![]() |
|
Inagawa 13 Apr 2012, 19:27
I have rewritten the code for the third time (took the whole day, gahh). This time using the trick I've learned by studying the easy part of huvaligen code to make the console screen bigger.
I have also created my own basic windowing system. All the windows are objects and if I had mouse input, it should be easy to move and resize them. But I do not understand huvaligen code, it's just too mashed together and I have no idea which part does what. It's a great piece of code, but certainly not for beginners. Guru, could you please explain the mouse input in some very easy fashion? Pretty please? ![]() Edit: Replaced the image |
|||
![]() |
|
AsmGuru62 13 Apr 2012, 20:09
This is the API you need for mouse in console:
http://msdn.microsoft.com/en-us/library/ms684961(v=vs.85).aspx You need to make a thread which will call this function and read just one record. Then you check if this record represents a MOUSE_EVENT and if it does - you Post a custom message to your main thread and then in response to that message you do whatever needed in your panels. That is a short explanation, but there is just too much there - read that link. You need a separate thread, because that function is a blocking call if no messages are detected in queue and you do not wish to block your main thread. Also, take a look at PeekConsoleInput -- maybe you need this function, if you want to preserve the non-mouse messages in queue. Otherwise, they will be lost. edit by revolution: Fixed URL |
|||
![]() |
|
Inagawa 14 Apr 2012, 00:03
Oh god, it's 2AM, I am half dead, but I finally made it. I have working mouse input on a separate thread.
Thanks a lot for sending me in the right direction with the link. I also absolutely took apart huvaligen code, this time documenting each line and finding out what it does. There are some things I don't understand - not from assembly perspective, but simply "why do this" kind of. I'll ask tomorrow. Ah, going to sleep with a feeling of victory. ![]() |
|||
![]() |
|
mindcooler 14 Apr 2012, 09:42
Ask away, there are probably a lot of strange things in it; it isn't exactly a finished program, just experimental. If you wonder about the midiInGetNumDevs, it's supposed to support MIDI input as well in the future.
|
|||
![]() |
|
Inagawa 14 Apr 2012, 11:09
Yes, what I basically did at first was to comment out as much as I could of the code that seemed to do nothing. Also I noticed this
Code: jmp .eventLoop ; ; Jump to the inputLoop - I don't think this code can be reached ; jmp .inputLoop Btw, thanks a lot for the code. |
|||
![]() |
|
mindcooler 14 Apr 2012, 21:27
Just leftovers from a do-while loop.
|
|||
![]() |
|
Inagawa 14 Apr 2012, 22:52
Can I ask where I've made a mistake?
Code: struct STR thing1 dd ? thing2 dw ? thing3 dw ? ends _s STR lea ebx, [_s] mov [ebx], DWORD 1 mov [ebx+4], WORD 1 mov [ebx+6], WORD 1 cinvoke printf, <'Thing 1 - %i', 10>, DWORD[ebx] cinvoke printf, <'Thing 2 - %i', 10>, DWORD[ebx+4] cinvoke printf, <'Thing 3 - %i', 10>, DWORD[ebx+6] Output is Code: Thing 1 - 1 Thing 2 - 65537 Thing 3 - 1 It's something obvious that I'm missing |
|||
![]() |
|
revolution 14 Apr 2012, 22:59
All invoke calls push a dword value onto the stack. The dword value at [ebx+4] is a combination of two word values forming a single dword value 0x00010001.
You can "fix" if like this: Code: cinvoke printf, <'Thing 1 - %i', 10>, DWORD[ebx] movzx eax, WORD[ebx+4] cinvoke printf, <'Thing 2 - %i', 10>, eax movzx eax, WORD[ebx+6] cinvoke printf, <'Thing 3 - %i', 10>, eax |
|||
![]() |
|
Inagawa 15 Apr 2012, 08:38
Because I have a piece of code that gets memory allocated by VirtualAlloc and I get a pointer.
I then need to initialize that structure just from that handle. You zero extend the argument and place it in EAX so there's no overlapping when you pass them. I do understand this. But How do I put this into a structure? Code: struct STR thing1 dd ? thing2 dw ? thing3 dw ? ends _s STR ;===================== lea ebx, [_s] mov [ebx], DWORD 1 ; ; _s STR: ; Offset 0 : DWORD 1 ; Offset 1 : DWORD 1 ; Offset 2 : DWORD 1 ; Offset 3 : DWORD 1 ; mov [ebx+4], WORD 2 movzx eax, WORD[ebx+4] ; ; _s STR: ; Offset 0 : DWORD 1 ; Offset 1 : DWORD 1 ; Offset 2 : DWORD 1 ; Offset 3 : DWORD 1 ; Offset 4 : WORD 2 ; Offset 5 : WORD 2 ; mov [ebx+6], WORD 3 movzx edx, WORD[ebx+6] ; ; _s STR: ; Offset 0 : DWORD 1 ; Offset 1 : DWORD 1 ; Offset 2 : DWORD 1 ; Offset 3 : DWORD 1 ; Offset 4 : WORD 2 ; Offset 5 : WORD 2 ; Offset 6 : WORD 3 ; Offset 7 : WORD 3 ; cinvoke printf, <'Thing 1 - %i', 10>, DWORD[ebx] cinvoke printf, <'Thing 2 - %i', 10>, eax cinvoke printf, <'Thing 3 - %i', 10>, edx Am I wrong about the offsets? MOV is not limited to DWORDs, why am I still getting an output of (1, 12, 582600)? Please please use this code to get the idea across. So I can better relate |
|||
![]() |
|
dancho 15 Apr 2012, 10:00
this coding style will help you with structs offsets, and
remember that printf trashing eax,ecx,edx ... registers and as Rev already said printf expect dword size value on the stack , that is why we used movzx for thing2 and thing3... Code: ; struct STR thing1 dd ? thing2 dw ? thing3 dw ? ends _s STR ; lea ebx,[_s] mov [ebx+STR.thing1],1 mov [ebx+STR.thing2],2 mov [ebx+STR.thing3],3 cinvoke printf,<'Thing 1 - %u',13,10>,[ebx+STR.thing1] movzx edx,[ebx+STR.thing2] cinvoke printf,<'Thing 2 - %u',13,10>,edx movzx edx,[ebx+STR.thing3] cinvoke printf,<'Thing 3 - %u',13,10>,edx and for the mem alloc: Code: ; ptr to memory ; pMem dd 0 ; ; need 5 STR structs ; MEM_SIZE = sizeof.STR*5 invoke VirtualAlloc,0,MEM_SIZE,MEM_COMMIT,PAGE_READWRITE ; ; remember to check eax ?! ; mov [pMem],eax mov ebx,eax ; ; fill struct 1 ; mov [ebx+STR.thing1],1 mov [ebx+STR.thing2],1 mov [ebx+STR.thing3],1 ; ; go to the next one add ebx,sizeof.STR ; ; fill struct 2 ; mov [ebx+STR.thing1],2 mov [ebx+STR.thing2],2 mov [ebx+STR.thing3],2 ; ; etc ; ; remember to free mem invoke VirtualFree,[pMem],0,MEM_RELEASE |
|||
![]() |
|
Inagawa 15 Apr 2012, 11:50
Yes, the register thrashing is one of my constant mistakes.. It's the price I pay for learning HLL first.
But an amazing piece of code! I knew I could use an offset, but it never occurred to me I can use a structure member offset! So easy compared to how I did it. Thanks a lot, now I need to go play with this ![]() |
|||
![]() |
|
Inagawa 15 Apr 2012, 13:44
I think I am going crazy. When I run this code:
Code: mov cx, WORD 5 cinvoke printf, <'%i',10>, ecx it outputs 5. When I run the exact same code in my application, it outputs a random number. No code is manipulating CX before the call to printf. It is just as you see it here. Is there any way to explain this? I can't figure out where I could've done an error. cinvoke translates to the code below, so how can CX be modified after it has been pushed on the stack? Code: PUSH ECX CCALL [PRINTF] I write a code like this: Code: push ecx cinvoke printf, <'X: %i', 10>, [ebx+Window.Location.X] cinvoke printf, <'Y: %i', 10>, [ebx+Window.Location.Y] cinvoke printf, <'W: %i', 10>, [ebx+Window.Width] cinvoke printf, <'H: %i', 10>, [ebx+Window.Height] pop ecx ECX is modified after this runs. I am baffled. I can already imagine it's something primitive and I'll be ashamed. ![]() Last edited by Inagawa on 15 Apr 2012, 13:55; edited 1 time in total |
|||
![]() |
|
revolution 15 Apr 2012, 13:46
CX != ECX
Code: mov ecx,5 cinvoke printf, <'%i',10>,ecx |
|||
![]() |
|
Inagawa 15 Apr 2012, 13:55
Edit: I'll rephrase the question. I am working with 16bit variables. How am I supposed to push and pop them, if push can only push a DWORD?
I have this code (I cut out the unimportant things in between): Code: mov cx, [PosX] ; PosX is a WORD argument ;Now I need to printf out debug info and preserve CX push ecx cinvoke printf, <'X: %i', 10>, [ebx+Window.Location.X] cinvoke printf, <'Y: %i', 10>, [ebx+Window.Location.Y] cinvoke printf, <'W: %i', 10>, [ebx+Window.Width] cinvoke printf, <'H: %i', 10>, [ebx+Window.Height] pop ecx cinvoke printf, <'%i', 10>, cx ; <==== THIS should still be equal to PosX but it's not Even though CX != ECX, pushing the 32bits on stack and then retrieving them should leave the low 16bits intact, no? |
|||
![]() |
|
Inagawa 15 Apr 2012, 14:11
And even using this code at the end, as dancho said:
Code: movzx edx, cx cinvoke printf,<'Original CX - %i',13,10>,edx It still outputs 0, not 5 (the original value) |
|||
![]() |
|
Goto page Previous 1, 2, 3, 4, 5, 6, 7 Next < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.