1: void __fastcall fastpixel(long* surface)
2: {
3: int iCount = 1152*864;
4: __asm
5: {
6: // Assign pointers to register
7: push edi;
8: push ecx;
9: push eax;
10: mov edi, [surface] ; //put dest addr to edi reg
11: mov ecx, [iCount] ;// put count to ecx reg
12:
13: codeloop:
14: mov eax, [edi] ; //mov a byte of src data to low
15: xor eax, 0x00ffffff ;
16: mov [edi], eax ;
17: add edi,4;
18: dec ecx ; //decrement count by 1
19: jnz codeloop ; //jump to codeloop if not 0
20: pop edi;
21: pop ecx;
22: pop eax;
23: }
24: }
Ok so I've got this lovely bit of code that I've constructed and I need a few clerifications:
in theory I should have been able to replace lines 14 to 16 with this:
first:
xor [edi], 0x00FFFFFF
how ever this just turns my screen blue :\
second:
I seem to need to use add edi,4 instead of just inc because inc only seems to move it 1 byte forward, is there a way to fix this?
third:
This is in the help docs for MASM32 but I have no clue what idex, scale, and displacement are reffering to.
[ Base Address + Index * Scale + Displacement ]
[ebx + ecx * 4 + 8]
ebx is the base address.
ecx is the index.
4 is the scale based on the data size.
8 is the displacement in BYTES.
In C, you merely shoot yourself in the foot.
In C++, you accidentally create a dozen instances of yourself and shoot them all in the foot. Providing emergency medical care is impossible, because you can't tell which are bitwise copies and which are just pointing at others and saying, "That's me, over there."
void fastpixel(long* surface)
{
int iCount = 1152*864;
__asm
{
// Assign pointers to register
push edi;
push ecx;
push eax;
mov edi, [surface] ; //put dest addr to edi reg
mov ecx, [iCount] ;// put count to ecx reg
codeloop:
//mov eax, [edi] ; //mov a byte of src data to low
//xor eax, 0x00ffffff ;
//mov [edi], eax ;
xor DWORD PTR [edi+ecx*4-4], 0x00ffffff;
//inc edi
//add edi,4;
dec ecx ; //decrement count by 1
jnz codeloop ; //jump to codeloop if not 0
pop edi;
pop ecx;
pop eax;
}
}
As you see, there is no need to modify EDI, although increasing it by 4 is not worse than increasing by 1, compilers create instructions like 'add reg data_type_size' when processing arrays. You also lack type specifier, thats why your 'xor [edi], long_num' did not work. And, in added line, you have example of addresing with index,scale and displacement.
Unfortunately, at this moment I have no time to explain these changes, but if you do not understand them, I will do it today evening (evening of CET+1h ).
Hope it helps
Hob
Last edited by Hobson; April 9th, 2005 at 07:52 AM.
hmm thanks that did help, I'm having another problem though, I have this asm code which for some reason does not work for writing 8bit video memory, instead the middle of my screen generates this image
(resolution is to big to post so you'lk need to use the link, and possibly paint ) http://img.photobucket.com/albums/v5...ul/ASMprob.png
all of those objectes are supposed to be a single thing in the middle not all spread out like that. (9 objects)
Code:
//index = (X-1+((Y-1)*1152));
__asm
{
mov eax, [X];//this ASM replaces the index calulation
sub eax, 1;
mov ecx, [Y];
sub ecx, 1;
imul ecx, 1152;
add ecx,eax;
//mov ecx, [index]; //index
mov edi, [surface]; //put dest addr to edi reg
mov al, [edi+ecx]; //mov a byte of src data to low
xor al, 0xF;
mov [edi+ecx], al;
Last edited by barrensoul; April 9th, 2005 at 04:40 PM.
In C, you merely shoot yourself in the foot.
In C++, you accidentally create a dozen instances of yourself and shoot them all in the foot. Providing emergency medical care is impossible, because you can't tell which are bitwise copies and which are just pointing at others and saying, "That's me, over there."
Those ideas are not tested, because I have no compiler here, let me know if it helped:
1. Always when you are reading or storing a value from memory, use size specifier. This does not affect the program, and you will be sure that everything is ok.
2. This code seems to be time-critical for you, or you just like to mess around with assembler. In both cases you could replace 'imul val, 1152' with
Rumours say that xMUL is slower than set of movs/shifts/adds, but i do not know hows that with modern procesors. Besides, IMUL is a bit tricky with it source/dest operands.
Instead 'sub reg,1' you could use 'dec reg'.
Thats all what I can help without compiler, Ill check it for more when i am back home.
I checked your code with compiler and it works in correct way (X and Y should be declared as DWORDS). Probably not index calculation code is your problem. I forgot to mention earlier:
Is 'surface' variable a pointer to memory of DirectX screen surface? If so, you should know that width of DirectX screen surface is NOT equal to its horizontal resolution. In your index calculationd you should use not 1152 (resolution value) but its pitch value.
If its not a DX screen buffer, then your problem is probably located not in index calculation routine. I would expect that X and Y variables are declared as WORD, and in assembly code they are used as DWORD. Just use size specifiers EVERYWHERE where possible. If your problem still persists, attach your project and I will check it (if its not too complicated for me).
it is a pointer to the screen memory (void pointer), I'm well aware of pitch (surface.lPitch) how ever I have specified a 8 bit screen thus making the pitch 1, on the other prog I use the *4 in the index cause that was 32bit mode, thus I should not need to specify an index multiplier.
Last edited by barrensoul; April 11th, 2005 at 12:19 PM.
In C, you merely shoot yourself in the foot.
In C++, you accidentally create a dozen instances of yourself and shoot them all in the foot. Providing emergency medical care is impossible, because you can't tell which are bitwise copies and which are just pointing at others and saying, "That's me, over there."
So if its not pitch, then I'd expect some size mismatch between declaration of coords and their usage in asm code.
By 'size specifier' I did not mean index multiplier. In this case it should be indeed set to 1. I just mean that your function prototype could look like
Code:
void setpixel(void* surf, WORD X, WORD Y)
while in asm snippet you use
Code:
mov eax, [X]
what moves into eax 32-bit value.
If it is also not a reason, then I think that trouble is not located at code posted by you.
If you attach your project, it does not need some specific libs and can be compiled under VC 6.0, I might to take look at it.
Hob
Last edited by Hobson; April 11th, 2005 at 02:35 PM.
well here it is, you'll need the directX SDK so you can link the directx libs n stuff (don't get the most recent one if your using VC++6.0 because it dosn't support VC++6.0 any more, you'll need to find last months)
link: user32.lib ddraw.lib gdi32.lib
In C, you merely shoot yourself in the foot.
In C++, you accidentally create a dozen instances of yourself and shoot them all in the foot. Providing emergency medical care is impossible, because you can't tell which are bitwise copies and which are just pointing at others and saying, "That's me, over there."
This is DDSurfaceDesc.lPitch value in your app. For some reason, it is NOT equal 1. You need to multiply all coords by this pitch, instead of 1152. If you have problem with changes, msg me.
Remember, that lPitch can vary depending on Graphic hardware driver, and it should be read every time it will be used.
Hob
Last edited by Hobson; April 12th, 2005 at 07:48 AM.
I will try pitch as soon as I get home, how ever it seems either you implimented my prog without the same rules or something went wrong because the straight line in your program should not exist, this link shows what you should see starting in the middle of my screen if it works correctly:
and I thank you for taking the time to help this stubourn noobie although I like ASM quite a bit, I'd have to say I love C++/ASM hybrid prorgamming alot.
Last edited by barrensoul; April 12th, 2005 at 10:40 AM.
In C, you merely shoot yourself in the foot.
In C++, you accidentally create a dozen instances of yourself and shoot them all in the foot. Providing emergency medical care is impossible, because you can't tell which are bitwise copies and which are just pointing at others and saying, "That's me, over there."
Straight line is made by me, for testing purposes. Your life of rabbits is working correctly, just now you need to change ALL occurences of 1152 to pitch, what will fix coords, because now pixels are spread around whole screen. And i'd suggest not hardcode pitch value, just read it each time when ddsdesc is obtained.
Always to help
heh heh yeah I made a cardinal sin in DirX I realised that after a computer at school was experiencing the same glitch in the 32bit working version
In C, you merely shoot yourself in the foot.
In C++, you accidentally create a dozen instances of yourself and shoot them all in the foot. Providing emergency medical care is impossible, because you can't tell which are bitwise copies and which are just pointing at others and saying, "That's me, over there."
* The Best Reasons to Target Windows 8
Learn some of the best reasons why you should seriously consider bringing your Android mobile development expertise to bear on the Windows 8 platform.