#141424 - Ruben - Tue Sep 25, 2007 9:13 am
OK. This is just freaky! When I started doing my 'big map' scrolling system, my logic's run out!!
Code: |
void Draw2NewRows() {
int iX;
int SXO = (CameraX/8);
int SYO = ((CameraY/8)+30)*32;
int MXO = (CameraX/8);
int MYO = ((CameraY/8)+30)*MapSize;
for(iX=0;iX<32;iX++) {
ScreenBaseBlock[SYO+SXO+iX] = baronMap[MYO+MXO+iX];
ScreenBaseBlock[SYO+SXO+iX+1] = baronMap[MYO+MXO+iX+1];
ScreenBaseBlock[SYO+SXO+iX+32] = baronMap[MYO+MXO+iX+MapSize];
ScreenBaseBlock[SYO+SXO+iX+32+1] = baronMap[MYO+MXO+iX+MapSize+1];
}
}
|
I'm pretty sure the logic behind that is fine but I can't figure out the rest! ARGH!! ...ahem... umm... CameraX and Y are 'int's that hold the scrolling information.. umm...'ScreenBaseBlock' is a pointer to the screen base block.. umm.... and 'baronMap' is a 'const u16' array of data. I'm REALLY stuck now!
#141427 - f33ldead - Tue Sep 25, 2007 10:20 am
Have you seen this thread?
_________________
It's real, spooky action at distance!
#141432 - Ruben - Tue Sep 25, 2007 12:13 pm
Yeah, I've read that topic from top to bottom but still... I don't really get what's wrong with my program... hmm...
#141434 - f33ldead - Tue Sep 25, 2007 12:59 pm
Note the +30 you gave to SY0. It's probably not what you want.
_________________
It's real, spooky action at distance!
#141484 - Ruben - Wed Sep 26, 2007 4:11 am
Hmm... probably... but even if I try +20 it still doesn't work on the Map Y Offset... hmm...
#141500 - f33ldead - Wed Sep 26, 2007 9:44 am
I'm not sure what you intend to do, but if you add camera coordinates to the SBB index, you'll eventually go off bg.
If you just want to load two bottom strips for the map, this should do it:
Code: |
#define SCREEN_HEIGHT 20
#define BG_WIDTH 32
#define MAP_WIDTH whatever
for(iy=SCREEN_HEIGHT; iy<SCREEN_HEIGHT+2; iy++) {
for(ix=0; ix<BG_WIDTH; ix++) {
sbb[iy*BG_WIDTH + ix] = map[(iy+camy)*MAP_WIDTH + (ix+camx)];
}
} |
where camy, camx, iy, ix are tile coordinates.
However, when you scroll the map down, say using BGxVOFF, you'll eventually reach the bottom strip, i.e. then end of map. A way around this suggested to me way to load the relevant 32x20 portion of the map every time you scroll the map. To avoid some "missing tile effects" you'll need to load somewhat larger than 32x20, you have to load one extra strip from the direction you're scrolling -if that strip is available of course, ie you haven't reached the edge of the map.
It doesn't look like much of a burden to me. For now.
_________________
It's real, spooky action at distance!
#141502 - Ruben - Wed Sep 26, 2007 10:23 am
OK. I'll try that.
BTW: I am actually using mode 0 for this which is why I went with the 'greater than allowed' scrolling offsets which pretty much work well when scrolling horizontally.
#141503 - Ruben - Wed Sep 26, 2007 10:51 am
OK. I ended up with this code:
Code: |
int iX, iY;
int MXO = (CameraX/8);
int MYO = (CameraY/8)+20;
int SXO = (CameraX/8);
int SYO = (CameraY/8)+20;
MXO %= MapSize;
MYO %= MapSize;
SXO %= 32;
SYO %= 32;
for(iX=0;iX<32;iX++) {
for(iY=0;iY<2;iY++) {
ScreenBaseBlock[(iY+SYO)*32+SXO+iX] = baronMap[(iY+MYO)*MapSize+MXO+iX];
}
} |
But that is STILL incorrect! It tends to mess up every now and then and usually data is a bit off by 32 tiles... I don't know what that could be... hmm...
#141509 - Cearn - Wed Sep 26, 2007 2:37 pm
it's the screenblock coordinates that need to stay within the [0,31] range, not the screenblock origins. The modulo goes inside the loop:
Code: |
u32 ix, iy;
u32 sx0, sy0, mx0, my0; // Camera positions in tile units
u32 srcPitch;
u16 *src= MapData, u16 *dst= Screenblock;
for(iy=0; iy<2; iy++)
for(ix=0; ix<32; ix++)
dst[(sy0+iy)%32*32 + (sx0+ix)%32] = src[(my0+iy)*srcPitch + mx0+ix];
|
In testing, it also helps to use data with which you can actually see what happens. For example, with a fairly open map, you wouldn't be able to see what parts would actually be updated by the routine. Tiles with different numbers would work well with that. Also fun: instead of copying from a map, just start with all 1's or something end then increment when the boundaries are refreshed. It'll look awful, but you can tell exactly what screen entries the routine is working on.
#141574 - Ruben - Thu Sep 27, 2007 4:24 am
YAY!!!!!!!!!!! Thanks man!! I FINALLY got my test project running so now I can actually implement it in my 'real' game!! YAY!!!!!!!!!!!!!! ...ahem.... err.... thanks Cearn..... lol........
#141578 - Ruben - Thu Sep 27, 2007 4:52 am
BTW: Just to tell people what I ended up doing, I'll post my full 'big map' code here:
Code: |
void DrawNewColumn() {
int iX, iY;
int MXO = (CameraX/8)+30;
int MYO = (CameraY/8)-CameraOY;
int SXO = (CameraX/8)+30;
int SYO = (CameraY/8)-CameraOY;
for(iX=0;iX<2;iX++) {
for(iY=0;iY<32;iY++) {
ScreenBaseBlock[(iY+SYO)%32*32+(SXO+iX)%32] = baronMap[(iY+MYO)%MapSize*MapSize+(MXO+iX)%MapSize];
}
}
}
void DelNewColumn() {
int iX, iY;
int MXO = (CameraX/8)-2;
int MYO = (CameraY/8)-CameraOY;
int SXO = (CameraX/8)-2;
int SYO = (CameraY/8)-CameraOY;
for(iX=0;iX<2;iX++) {
for(iY=0;iY<32;iY++) {
ScreenBaseBlock[(iY+SYO)%32*32+(SXO+iX)%32] = baronMap[(iY+MYO)%MapSize*MapSize+(MXO+iX)%MapSize];
}
}
}
void DrawNewRow() {
int iX, iY;
int MXO = (CameraX/8);
int MYO = (CameraY/8)+20-CameraOY;
int SXO = (CameraX/8);
int SYO = (CameraY/8)+20-CameraOY;
for(iX=0;iX<32;iX++) {
for(iY=0;iY<2;iY++) {
ScreenBaseBlock[(iY+SYO)%32*32+(SXO+iX)%32] = baronMap[(iY+MYO)%MapSize*MapSize+(MXO+iX)%MapSize];
}
}
}
void DelNewRow() {
int iX, iY;
int MXO = (CameraX/8);
int MYO = (CameraY/8)-2-CameraOY;
int SXO = (CameraX/8);
int SYO = (CameraY/8)-2-CameraOY;
for(iX=0;iX<32;iX++) {
for(iY=0;iY<2;iY++) {
ScreenBaseBlock[(iY+SYO)%32*32+(SXO+iX)%32] = baronMap[(iY+MYO)%MapSize*MapSize+(MXO+iX)%MapSize];
}
}
} |
Where 'CameraX' and Y is your scrolling offsets, 'CameraOY' is incase you start off say at an offset of 8 pixels from the original Y offset which I am using right now, which is then divided by 8. The rest is pretty much self-explanatory. These functions should be called IMMEDIATLY after a keystroke. Eg:
Code: |
if(KEY_PRESSED(KEY_RIGHT)) {
DrawNewColumn();
//the rest of your code
} |
Etc, etc...