Skip to content

Commit

Permalink
Merge pull request #632 from MokhaLeee/bgaffin
Browse files Browse the repository at this point in the history
review on bg-affin rot/scale API
  • Loading branch information
RevoSucks authored Jun 18, 2024
2 parents 80499e7 + e88c4f8 commit 9e95abf
Show file tree
Hide file tree
Showing 10 changed files with 100 additions and 92 deletions.
15 changes: 2 additions & 13 deletions include/hardware.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,18 +122,8 @@ struct LCDControlBuffer {
/* 44 */ u8 blendCoeffA;
/* 45 */ u8 blendCoeffB;
/* 46 */ u8 blendY;
/* 48 */ u16 bg2pa;
/* 4A */ u16 bg2pb;
/* 4C */ u16 bg2pc;
/* 4E */ u16 bg2pd;
/* 50 */ u32 bg2x;
/* 54 */ u32 bg2y;
/* 58 */ u16 bg3pa;
/* 5A */ u16 bg3pb;
/* 5C */ u16 bg3pc;
/* 5E */ u16 bg3pd;
/* 60 */ u32 bg3x;
/* 64 */ u32 bg3y;
/* 48 */ struct BgAffineDstData bg2affin;
/* 58 */ struct BgAffineDstData bg3affin;
/* 68 */ s8 colorAddition;
};

Expand Down Expand Up @@ -202,7 +192,6 @@ extern void (*gMainCallback)(void);
extern struct KeyStatusBuffer * CONST_DATA gKeyStatusPtr;

extern struct LCDControlBuffer gLCDControlBuffer;
extern struct BgAffineDstData gOpAnimBgAffineDstData[2];

extern struct Struct02024CD4 gFrameTmRegisterConfig;
extern struct TileDataTransfer gFrameTmRegister[32];
Expand Down
15 changes: 8 additions & 7 deletions include/sysutil.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,13 +150,14 @@ void NewSysboxText(int vobj_offset, int pal, const char * str, int line, int del
void EndAllProcChildren(ProcPtr proc);
void nop_80ADDF8(void);

/* Some objects scalling routine */
void sub_80ADDFC(u8 layer, s16 angle, s16, s16, s16, s16);
void sub_80ADE90(u8, s16, s16);
void sub_80ADEE0(u8, s16, s16, s16, s16);
void sub_80ADF48(u8 layer, int angle, int a, int b, int c, int d);
void sub_80ADFBC(u8 layer, int a, int b);
void sub_80ADFFC(u8 layer, int a, int b, int c, int d);
/* Bg-affin rot/scale */
void BgAffinRotScaling(u8 bg, s16 angle, s16 x_center, s16 y_center, s16 sx, s16 sy);
void BgAffinScaling(u8 bg, s16 sy, s16 sx);
void BgAffinAnchoring(u8 bg, s16 q0_x, s16 q0_y, s16 p0_x, s16 p0_y);

void BgAffinRotScalingHighPrecision(u8 bg, int angle, int texX, int texY, int sx, int sy);
void BgAffinScalingHighPrecision(u8 bg, int sy, int sx);
void BgAffinAnchoringHighPrecision(u8 bg, int q0_x, int q0_y, int p0_x, int p0_y);

/* No idea, maybe some tile map or palette modication */
void sub_80AE044(int a, u16 * buf, int c, int d, int e, int f, int g, int h);
Expand Down
6 changes: 3 additions & 3 deletions src/chapterintrofx.c
Original file line number Diff line number Diff line change
Expand Up @@ -611,9 +611,9 @@ void ChapterIntro_LightBurst_Loop(struct ChapterIntroFXProc* proc) {
}

if (proc->unk_4C <= 0xFF) {
sub_80ADDFC(2, 0, 0, 0, 0x180, 0x180);
sub_80ADE90(2, (u16)proc->unk_4C + 0xF0, (u16)proc->unk_4C + 0xF0);
sub_80ADEE0(2, 0x70, 0x58, 0x4C, 0x4C);
BgAffinRotScaling(2, 0, 0, 0, 0x180, 0x180);
BgAffinScaling(2, (u16)proc->unk_4C + 0xF0, (u16)proc->unk_4C + 0xF0);
BgAffinAnchoring(2, 0x70, 0x58, 0x4C, 0x4C);
FlushLCDControl();

if (proc->unk_66 != 0) {
Expand Down
16 changes: 8 additions & 8 deletions src/hardware.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,18 +89,18 @@ void FlushLCDControl(void)
COPY_REG(u8, BLDY, &gLCDControlBuffer.blendY)

// set both BG2PA and BG2PB with a single 32-bit copy
COPY_REG(u32, BG2PA, &gLCDControlBuffer.bg2pa)
COPY_REG(u32, BG2PA, &gLCDControlBuffer.bg2affin.pa)
// set both BG2PC and BG2PD with a single 32-bit copy
COPY_REG(u32, BG2PC, &gLCDControlBuffer.bg2pc)
COPY_REG(u32, BG2X, &gLCDControlBuffer.bg2x)
COPY_REG(u32, BG2Y, &gLCDControlBuffer.bg2y)
COPY_REG(u32, BG2PC, &gLCDControlBuffer.bg2affin.pc)
COPY_REG(u32, BG2X, &gLCDControlBuffer.bg2affin.dx)
COPY_REG(u32, BG2Y, &gLCDControlBuffer.bg2affin.dy)

// set both BG3PA and BG3PB with a single 32-bit copy
COPY_REG(u32, BG3PA, &gLCDControlBuffer.bg3pa)
COPY_REG(u32, BG3PA, &gLCDControlBuffer.bg3affin.pa)
// set both BG3PC and BG3PD with a single 32-bit copy
COPY_REG(u32, BG3PC, &gLCDControlBuffer.bg3pc)
COPY_REG(u32, BG3X, &gLCDControlBuffer.bg3x)
COPY_REG(u32, BG3Y, &gLCDControlBuffer.bg3y)
COPY_REG(u32, BG3PC, &gLCDControlBuffer.bg3affin.pc)
COPY_REG(u32, BG3X, &gLCDControlBuffer.bg3affin.dx)
COPY_REG(u32, BG3Y, &gLCDControlBuffer.bg3affin.dy)

#undef COPY_REG
}
Expand Down
2 changes: 1 addition & 1 deletion src/opanim-main.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ void BgAffineSetOpAnim(int scaling_radio, int angle)
data.sy = scaling_radio;
data.alpha = angle << 8;

BgAffineSet(&data, gOpAnimBgAffineDstData, 1);
BgAffineSet(&data, &gLCDControlBuffer.bg2affin, 1);
}

void SetupOpAnimWorldMapfx(struct ProcOpAnim * proc)
Expand Down
6 changes: 3 additions & 3 deletions src/opinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -751,11 +751,11 @@ void ClassIntroFlare_Loop(struct OpInfoFlareProc* proc) {
unkC = Interpolate(0, 0, 0xD6, proc->unk_4c, 0x3C);
unkD = Interpolate(0, 0x10, 0x80, proc->unk_4c, 0x3C);

sub_80ADDFC(2, (s16)proc->unk_4e, 0, 0, (s16)(unkA * 5 + 0x80), (s16)(unkA * 5 + 0x80));
BgAffinRotScaling(2, (s16)proc->unk_4e, 0, 0, (s16)(unkA * 5 + 0x80), (s16)(unkA * 5 + 0x80));

sub_80ADE90(2, 0x100, 0x100);
BgAffinScaling(2, 0x100, 0x100);

sub_80ADEE0(2, unkC, unkD, 0x50, 0x48);
BgAffinAnchoring(2, unkC, unkD, 0x50, 0x48);

proc->unk_4e -= 0x40;

Expand Down
6 changes: 3 additions & 3 deletions src/opsubtitle.c
Original file line number Diff line number Diff line change
Expand Up @@ -238,9 +238,9 @@ void Subtitle_LightFlareFx_Loop(struct OpSubtitleProc* proc) {
c = Interpolate(0, 0, 214, proc->unk_4c, 60);
d = Interpolate(0, 16, 128, proc->unk_4c, 60);

sub_80ADDFC(2, proc->unk_4e, 0, 0, a * 5 + 0x80, a * 5 + 0x80);
sub_80ADE90(2, 0x100, 0x100);
sub_80ADEE0(2, c, d, 80, 72);
BgAffinRotScaling(2, proc->unk_4e, 0, 0, a * 5 + 0x80, a * 5 + 0x80);
BgAffinScaling(2, 0x100, 0x100);
BgAffinAnchoring(2, c, d, 80, 72);

proc->unk_4e -= 64;

Expand Down
123 changes: 71 additions & 52 deletions src/sysutil.c
Original file line number Diff line number Diff line change
Expand Up @@ -893,100 +893,119 @@ void nop_80ADDF8(void)
return;
}

void sub_80ADDFC(u8 layer, s16 angle, s16 c, s16 d, s16 e, s16 f)
void BgAffinRotScaling(u8 bg, s16 angle, s16 x_center, s16 y_center, s16 sx, s16 sy)
{
struct BgAffineSrcData data;
struct BgAffineDstData * dst;

if (e <= 4)
e = 4;
if (sx <= 4)
sx = 4;

if (f <= 4)
f = 4;
if (sy <= 4)
sy = 4;

data.texX = c * 0x100;
data.texY = d * 0x100;
data.texX = x_center * 0x100;
data.texY = y_center * 0x100;
data.scrX = 0;
data.scrY = 0;
data.sx = 0x10000 / e;
data.sy = 0x10000 / f;
data.sx = 0x10000 / sx;
data.sy = 0x10000 / sy;
data.alpha = angle * 0x10;

dst = &gOpAnimBgAffineDstData[1];
if (layer == 2)
dst = &gOpAnimBgAffineDstData[0];
dst = &gLCDControlBuffer.bg3affin;
if (bg == BG_2)
dst = &gLCDControlBuffer.bg2affin;

BgAffineSet(&data, dst, 1);
}

void sub_80ADE90(u8 layer, s16 a, s16 b)
void BgAffinScaling(u8 bg, s16 sy, s16 sx)
{
struct BgAffineDstData * affin = NULL;
if (layer == 2)
affin = gOpAnimBgAffineDstData;

affin->pb = (affin->pb * a) >> 8;
affin->pd = (affin->pd * a) >> 8;
affin->pa = (affin->pa * b) >> 8;
affin->pc = (affin->pc * b) >> 8;
}

void sub_80ADEE0(u8 layer, s16 a, s16 b, s16 c, s16 d)
{
if (bg == BG_2)
affin = &gLCDControlBuffer.bg2affin;

/**
* y = y * (1 / sy)
* x = x * (1 / sx)
*
* Both of which are 8.8 fixed point numbers:
* a halfword with 8 integer bits and 8 fractional bits.
*
* See tonc 10.4.1: https://www.coranac.com/tonc/text/affine.htm
*/

affin->pb = (affin->pb * sy) >> 8;
affin->pd = (affin->pd * sy) >> 8;
affin->pa = (affin->pa * sx) >> 8;
affin->pc = (affin->pc * sx) >> 8;
}

void BgAffinAnchoring(u8 bg, s16 q0_x, s16 q0_y, s16 p0_x, s16 p0_y)
{
/**
* vector q0: origin in screen space
* vector p0: origin in texture space
*
* See tonc 12.3: https://www.coranac.com/tonc/text/affbg.htm:
*
* bgaff->dx= asx->tex_x - (pa*asx->scr_x + pb*asx->scr_y);
* bgaff->dy= asx->tex_y - (pc*asx->scr_x + pd*asx->scr_y);
*/
struct BgAffineDstData * affin = NULL;
if (layer == 2)
affin = gOpAnimBgAffineDstData;
if (bg == BG_2)
affin = &gLCDControlBuffer.bg2affin;

affin->dx = affin->pa * (-a) + affin->pb * (-b) + c * 0x100;
affin->dy = affin->pc * (-a) + affin->pd * (-b) + d * 0x100;
affin->dx = affin->pa * (-q0_x) + affin->pb * (-q0_y) + p0_x * 0x100;
affin->dy = affin->pc * (-q0_x) + affin->pd * (-q0_y) + p0_y * 0x100;
}

void sub_80ADF48(u8 layer, int angle, int a, int b, int c, int d)
void BgAffinRotScalingHighPrecision(u8 bg, int angle, int texX, int texY, int sx, int sy)
{
struct BgAffineSrcData data;
struct BgAffineDstData * dst;

if (c <= 0x400)
c = 0x400;
if (sx <= 0x400)
sx = 0x400;

if (d <= 0x400)
d = 0x400;
if (sy <= 0x400)
sy = 0x400;

data.texX = a;
data.texY = b;
data.texX = texX;
data.texY = texY;
data.scrX = 0;
data.scrY = 0;
data.sx = 0x1000000 / c;
data.sy = 0x1000000 / d;
data.sx = 0x1000000 / sx;
data.sy = 0x1000000 / sy;
data.alpha = angle >> 4;

dst = &gOpAnimBgAffineDstData[1];
if (layer == 2)
dst = &gOpAnimBgAffineDstData[0];
dst = &gLCDControlBuffer.bg3affin;
if (bg == BG_2)
dst = &gLCDControlBuffer.bg2affin;

BgAffineSet(&data, dst, 1);
}

void sub_80ADFBC(u8 layer, int a, int b)
void BgAffinScalingHighPrecision(u8 bg, int sy, int sx)
{
struct BgAffineDstData * affin = NULL;
if (layer == 2)
affin = gOpAnimBgAffineDstData;
if (bg == BG_2)
affin = &gLCDControlBuffer.bg2affin;

affin->pb = (affin->pb * a) >> 0x10;
affin->pd = (affin->pd * a) >> 0x10;
affin->pa = (affin->pa * b) >> 0x10;
affin->pc = (affin->pc * b) >> 0x10;
affin->pb = (affin->pb * sy) >> 0x10;
affin->pd = (affin->pd * sy) >> 0x10;
affin->pa = (affin->pa * sx) >> 0x10;
affin->pc = (affin->pc * sx) >> 0x10;
}

void sub_80ADFFC(u8 layer, int a, int b, int c, int d)
void BgAffinAnchoringHighPrecision(u8 bg, int q0_x, int q0_y, int p0_x, int p0_y)
{
struct BgAffineDstData * affin = NULL;
if (layer == 2)
affin = gOpAnimBgAffineDstData;
if (bg == BG_2)
affin = &gLCDControlBuffer.bg2affin;

affin->dx = ((affin->pa * (-a) + affin->pb * (-b)) >> 8) + c;
affin->dy = ((affin->pc * (-a) + affin->pd * (-b)) >> 8) + d;
affin->dx = ((affin->pa * (-q0_x) + affin->pb * (-q0_y)) >> 8) + p0_x;
affin->dy = ((affin->pc * (-q0_x) + affin->pd * (-q0_y)) >> 8) + p0_y;
}

void sub_80AE044(int a, u16 * buf, int c, int d, int e, int f, int g, int h)
Expand Down
2 changes: 1 addition & 1 deletion src/titlescreen.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ void sub_80C5548(int arg) {

src.alpha = 0;

BgAffineSet(&src, gOpAnimBgAffineDstData, 1);
BgAffineSet(&src, &gLCDControlBuffer.bg2affin, 1);

return;
}
Expand Down
1 change: 0 additions & 1 deletion sym_iwram.txt
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@
. = 0x003070; gOamLoPutIt = .;
. = 0x003070; gOamLoPutIt = .;
. = 0x003080; gLCDControlBuffer = .;
. = 0x0030C8; gOpAnimBgAffineDstData = .;
. = 0x0030D8; gUnknown_030030D8 = .;
. = 0x0030F0; gIRQHandlers = .;
. = 0x003128; gUnknown_03003128 = .;
Expand Down

0 comments on commit 9e95abf

Please sign in to comment.