I have a nice isometric map drawn and the scrolling is working fine BUT I''m having trouble clipping off the tiles when they reach the boundaries of the screen. Can anyone help?
Well here''s what I use so that no matter where I blit a sprite it will show up. I''m assuming your using Fullscreen mode so you can''t attach a cliplist? Well this is in assembler but you can figure it out... Or ask!
;########################################################################
; BltFastClipper
;########################################################################
BltFastClipper proc surface :DWORD,
RECTvar :RECT,
X :DWORD,
Y :DWORD
LOCAL ScreenLeft :SDWORD
LOCAL ScreenTop :SDWORD
LOCAL ScreenBottom :SDWORD
LOCAL ScreenRight :SDWORD
LOCAL OldX :SDWORD
LOCAL OldY :SDWORD
LOCAL NewX :DWORD
LOCAL NewY :DWORD
m2m OldX, X
m2m OldY, Y
;Set up screen rect for clipping
m2m ScreenLeft, X
m2m ScreenTop, Y
;Calculate ScreenBottom
mov eax, Y
add eax, RECTvar.bottom
sub eax, RECTvar.top
mov ScreenBottom, eax
;Calculate ScreenRight
mov eax, X
add eax, RECTvar.right
sub eax, RECTvar.left
mov ScreenRight, eax
;Temporary source rect
m2m SrcRect.top, RECTvar.top
m2m SrcRect.left, RECTvar.left
m2m SrcRect.right, RECTvar.right
m2m SrcRect.bottom, RECTvar.bottom
;We''re going straight for 800x600 now.
.if ScreenBottom > 600
mov eax, ScreenBottom
sub eax, 600
sub SrcRect.bottom, eax
mov ScreenBottom, 600
.endif
.if ScreenLeft < 0
mov eax, ScreenLeft
sub SrcRect.left, eax
mov OldX, 0
.endif
.if ScreenRight > 800
mov eax, ScreenRight
sub eax, 800
sub SrcRect.right, eax
mov ScreenRight, 0
.endif
.if ScreenTop < 0
mov eax, ScreenTop
sub SrcRect.top, eax
mov OldY, 0
.endif
m2m NewX, OldX
m2m NewY, OldY
;Do the blit
;Note there is a SRCCOLORKEY on here for transparency, you may want
;to remove this..
DDS4INVOKE BltFast, lpddssysback, NewX, NewY, surface, ADDR SrcRect, DDBLTFAST_SRCCOLORKEY or DDBLTFAST_WAIT
done:
;===================
; We completed
;===================
return TRUE
err:
;===================
; We didn''t make it
;===================
return FALSE
BltFastClipper ENDP
;########################################################################
; END BltFastClipper
;########################################################################
You may also want to add error checking after the BLTFast for Surface lost or other spontaneous problems...
Ask any questions, but basically convert this to C or C++ and your rocking!
A few notes, the first argument is the source surface, it always blits to the backbuffer which you could change in the BltFast line of code. the rect passed in next is the source rectanle of where it''s blitting out of the surface (passed in first) and x and y are the dest co-ords which can be negative, it''ll equalise them out and chop down the source rect if it''s out of the screen, rather than your whole blit not appearing!
Have fun!
See ya,
Ben
P.S. Oh yah you''ll notice the 800 and 600 in the right and bottom side checking, well that can be changed to whatever you want.
;########################################################################
; BltFastClipper
;########################################################################
BltFastClipper proc surface :DWORD,
RECTvar :RECT,
X :DWORD,
Y :DWORD
LOCAL ScreenLeft :SDWORD
LOCAL ScreenTop :SDWORD
LOCAL ScreenBottom :SDWORD
LOCAL ScreenRight :SDWORD
LOCAL OldX :SDWORD
LOCAL OldY :SDWORD
LOCAL NewX :DWORD
LOCAL NewY :DWORD
m2m OldX, X
m2m OldY, Y
;Set up screen rect for clipping
m2m ScreenLeft, X
m2m ScreenTop, Y
;Calculate ScreenBottom
mov eax, Y
add eax, RECTvar.bottom
sub eax, RECTvar.top
mov ScreenBottom, eax
;Calculate ScreenRight
mov eax, X
add eax, RECTvar.right
sub eax, RECTvar.left
mov ScreenRight, eax
;Temporary source rect
m2m SrcRect.top, RECTvar.top
m2m SrcRect.left, RECTvar.left
m2m SrcRect.right, RECTvar.right
m2m SrcRect.bottom, RECTvar.bottom
;We''re going straight for 800x600 now.
.if ScreenBottom > 600
mov eax, ScreenBottom
sub eax, 600
sub SrcRect.bottom, eax
mov ScreenBottom, 600
.endif
.if ScreenLeft < 0
mov eax, ScreenLeft
sub SrcRect.left, eax
mov OldX, 0
.endif
.if ScreenRight > 800
mov eax, ScreenRight
sub eax, 800
sub SrcRect.right, eax
mov ScreenRight, 0
.endif
.if ScreenTop < 0
mov eax, ScreenTop
sub SrcRect.top, eax
mov OldY, 0
.endif
m2m NewX, OldX
m2m NewY, OldY
;Do the blit
;Note there is a SRCCOLORKEY on here for transparency, you may want
;to remove this..
DDS4INVOKE BltFast, lpddssysback, NewX, NewY, surface, ADDR SrcRect, DDBLTFAST_SRCCOLORKEY or DDBLTFAST_WAIT
done:
;===================
; We completed
;===================
return TRUE
err:
;===================
; We didn''t make it
;===================
return FALSE
BltFastClipper ENDP
;########################################################################
; END BltFastClipper
;########################################################################
You may also want to add error checking after the BLTFast for Surface lost or other spontaneous problems...
Ask any questions, but basically convert this to C or C++ and your rocking!
A few notes, the first argument is the source surface, it always blits to the backbuffer which you could change in the BltFast line of code. the rect passed in next is the source rectanle of where it''s blitting out of the surface (passed in first) and x and y are the dest co-ords which can be negative, it''ll equalise them out and chop down the source rect if it''s out of the screen, rather than your whole blit not appearing!
Have fun!
See ya,
Ben
P.S. Oh yah you''ll notice the 800 and 600 in the right and bottom side checking, well that can be changed to whatever you want.
__________________________Mencken's Law:"For every human problem, there is a neat, simple solution; and it's always wrong."
"Computers in the future may weigh no more than 1.5 tons."- Popular Mechanics, forecasting the relentless march of science in 1949
"Computers in the future may weigh no more than 1.5 tons."- Popular Mechanics, forecasting the relentless march of science in 1949
Well it''s peculiar but you CAN USE a CLIPPER in fullscreen mode.
You may not able to specify a clip list but you can
use the IDirectDrawClipper::SetHWnd method(in c++) to use a clipper to your fullscreen window.
For more information check the SDK or ask someone else cause i''m not very familiar in C++.
But i have to tell it works in Visual Basic 6.
Voodoo4
You may not able to specify a clip list but you can
use the IDirectDrawClipper::SetHWnd method(in c++) to use a clipper to your fullscreen window.
For more information check the SDK or ask someone else cause i''m not very familiar in C++.
But i have to tell it works in Visual Basic 6.
Voodoo4
Here these words vilifiers and pretenders, please let me die in solitude...
Yah I could be wrong. I found that on a site for using DirectX in VB, before it had native support for DX, you had to use some funny Library or something... I just converted the function to assembler and it worked great. But now that you mention it I may just go with setting a Clipper!
Thanks,
Ben
Thanks,
Ben
__________________________Mencken's Law:"For every human problem, there is a neat, simple solution; and it's always wrong."
"Computers in the future may weigh no more than 1.5 tons."- Popular Mechanics, forecasting the relentless march of science in 1949
"Computers in the future may weigh no more than 1.5 tons."- Popular Mechanics, forecasting the relentless march of science in 1949
But beware!
Clippers slow down performance dramatically sometimes.
Use them only when user routines can not help you.
Voodoo4
Clippers slow down performance dramatically sometimes.
Use them only when user routines can not help you.
Voodoo4
Here these words vilifiers and pretenders, please let me die in solitude...
void CMap::DrawMap(int x, int y){ RECT rect; HRESULT hRet; unsigned short int Tile, TileHeight; int posx, posy, xoff, yoff; CString mapForm; for(int layer = 0; layer<MapLayers; layer++) { for(int wid = 0; wid<MapWidth; wid++) { for (int hgh = 0; hgh<MapHeight; hgh++) { // Get tile identifier and height Tile = Map[layer][wid][hgh].TileID; TileHeight = Map[layer][wid][hgh].Height; // Get the tile to draw rect.left = (Tile - 1) * TILEWIDTH; rect.top = 0; rect.right = Tile * TILEWIDTH; rect.bottom = TileHeight; // If the tile height or ident is invalid quit if(Tile<=0 || TileHeight<=0) { dbError.ShowMessage("Error drawing map"); dbError.Quit(); } // Calculate where the tile will be drawn posy = y + wid*16 + hgh*16; posx = x + hgh*32 - wid*32; // Check if the current tile is exceeding the screen boundaries xoff = posx + TILEWIDTH; yoff = posy + TILEHEIGHT; // Clip tile if(xoff > scrSize.g_scrX) continue; if(yoff > scrSize.g_scrY) continue; if(posy < 0) continue; if(posx < 0) continue; // Draw the tile hRet = m_pDDraw->m_pDDSBack->BltFast(posx, posy, m_pDDraw->m_pDDSTiles, ▭, DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT); if(hRet != DD_OK) { dbError.ReportError(hRet); dbError.Quit(); } } } }
Where it says continue; is there it skips the tile that is offscreen. I need a method of finding how many pixels the tile is off the screen so I can change the RECT to the size of to draw.
Oh and it's not fullscreen so I have a clipper set.
Edited by - Rial on August 14, 2000 3:39:01 AM
Edited by - RiAL on August 14, 2000 3:40:32 AM
I read somewhere that you cant use a clipper on BltFast() sprites? Is that true?
Diemonex Games
Yeah, that''s what I read too. But I think it was a poster, and I have no idea how valid that posters info was... but the above method works with BltFast (And other MMX routines of mine..) and it ain''t that slow... actually the reason I wrote that as well was because I could choose wheather or not to use the clipper function, so if something (Like UI) was for sure not out of the screen I''d just use BltFast, if it was something like a tile or unit, I''d use my BltFastClipper Function.
But somewhere I heard that in Fullscreen mode with BltFast there was limitations as to what you could do. And I remember someone telling me I couldn''t use a clipper on my game. So I didn''t!
See ya,
Ben
But somewhere I heard that in Fullscreen mode with BltFast there was limitations as to what you could do. And I remember someone telling me I couldn''t use a clipper on my game. So I didn''t!
See ya,
Ben
__________________________Mencken's Law:"For every human problem, there is a neat, simple solution; and it's always wrong."
"Computers in the future may weigh no more than 1.5 tons."- Popular Mechanics, forecasting the relentless march of science in 1949
"Computers in the future may weigh no more than 1.5 tons."- Popular Mechanics, forecasting the relentless march of science in 1949
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement