#34211 - identitycrisisuk - Sat Jan 15, 2005 6:11 pm
I made a new little demo last night (click nuproj.zip), I was quite impressed with it for a few hours work but there's some things that aren't quite right, which I think are because I don't fully understand what's going on when you allow HBlank interrupts. In that demo the top line always scrolls at the maximum speed, no matter what it should do given how far down the background is scrolled. Here's my interrupt enabling code:
And here's my IrqHandler function (in a separate file):
BGy is how much scrolled down my background is so by adding REG_VCOUNT to it I should get the true position a horizontal line relates to and how much the scroll register should be set to to give the right paralax effect (which is chosen in the following if statements). I'm thinking my problem might be that REG_VCOUNT does not necessarily hold the number of the horizontal blank that you are on at that exact point and that on the first HBlank it's some big number left over from the last time round maybe? What's the 'official' or best way to find out exactly what horizontal line you are drawing when you come to a HBlank interrupt?
I'm also getting funny little black artifacts when I run this on a GBA but not through VBA strangely enough. I don't know if that's because I'm doing too much work, the code's in C not ASM and it only really needs to change the horizontal scroll every 32 HBlanks (or thereabouts) not every single line.
Off topic, I'd also like to know how best to scale one number to another using just ints. I've seen a few threads talking about getting a constant value in fixed point and then multiplying, how would I do that practically? I want to take the ships y position (between 0 and 159<<8) and scale it to a number between 0 and 96, which is the maximum I can scroll a 256x256 background before the top of it will appear at the bottom if you get me. At the moment I'm just dividing the screen position of the ship by 2, which avoids artefacts but is missing a bit of the bottom, I really need to multiply by 0.6 or some equivalent technique.
_________________
Code: |
REG_IRQ_HANDLER = IrqHandler;
REG_DISPSTAT = (1<<4); REG_IE = (1<<1); REG_IME = 1; |
And here's my IrqHandler function (in a separate file):
Code: |
void IrqHandler(void)
{ int vpos = BGy+REG_VCOUNT; if((vpos < 32) || (vpos >= 224)) { REG_BG0HOFS = BGx; } else { if((vpos < 64) || (vpos >= 192)) { REG_BG0HOFS = BGx>>1; } else { if((vpos < 96) || (vpos >= 160)) { REG_BG0HOFS = BGx>>2; } else { REG_BG0HOFS = BGx>>3; } } } REG_IF = REG_IF; } |
BGy is how much scrolled down my background is so by adding REG_VCOUNT to it I should get the true position a horizontal line relates to and how much the scroll register should be set to to give the right paralax effect (which is chosen in the following if statements). I'm thinking my problem might be that REG_VCOUNT does not necessarily hold the number of the horizontal blank that you are on at that exact point and that on the first HBlank it's some big number left over from the last time round maybe? What's the 'official' or best way to find out exactly what horizontal line you are drawing when you come to a HBlank interrupt?
I'm also getting funny little black artifacts when I run this on a GBA but not through VBA strangely enough. I don't know if that's because I'm doing too much work, the code's in C not ASM and it only really needs to change the horizontal scroll every 32 HBlanks (or thereabouts) not every single line.
Off topic, I'd also like to know how best to scale one number to another using just ints. I've seen a few threads talking about getting a constant value in fixed point and then multiplying, how would I do that practically? I want to take the ships y position (between 0 and 159<<8) and scale it to a number between 0 and 96, which is the maximum I can scroll a 256x256 background before the top of it will appear at the bottom if you get me. At the moment I'm just dividing the screen position of the ship by 2, which avoids artefacts but is missing a bit of the bottom, I really need to multiply by 0.6 or some equivalent technique.
_________________
Code: |
CanIKickIt(YES_YOU_CAN); |