From 1ed3af66eb7a3f868e62d6409061a8d83a9cceae Mon Sep 17 00:00:00 2001 From: Marcus Huderle Date: Sun, 10 Nov 2019 12:46:39 -0600 Subject: [PATCH] Document contest painting image processing effects --- common_syms/contest_painting.txt | 6 +- common_syms/contest_painting_effects.txt | 20 +- data/contest_painting_effects.s | 2 +- include/contest.h | 2 +- include/contest_painting.h | 11 +- include/contest_painting_effects.h | 65 +- src/contest.c | 14 +- src/contest_painting.c | 191 ++-- src/contest_painting_effects.c | 1083 +++++++++++----------- src/scrcmd.c | 6 +- 10 files changed, 717 insertions(+), 683 deletions(-) diff --git a/common_syms/contest_painting.txt b/common_syms/contest_painting.txt index 1fba37a59..d8dadccfa 100644 --- a/common_syms/contest_painting.txt +++ b/common_syms/contest_painting.txt @@ -1,4 +1,4 @@ -gUnknown_03006190 -gUnknown_030061A0 -gUnknown_030061C0 +gContestMonPixels +gContestPaintingContext +gContestPaintingWinner gContestPaintingMonPalette diff --git a/common_syms/contest_painting_effects.txt b/common_syms/contest_painting_effects.txt index 2f3d79219..134f7e88b 100644 --- a/common_syms/contest_painting_effects.txt +++ b/common_syms/contest_painting_effects.txt @@ -1,10 +1,10 @@ -gUnknown_03006164 -gUnknown_03006168 -gUnknown_0300616C -gUnknown_03006170 -gUnknown_03006174 -gUnknown_03006178 -gUnknown_0300617C -gUnknown_03006180 -gUnknown_03006184 -gUnknown_03006188 +gCanvasColumnStart +gCanvasPixels +gCanvasRowEnd +gCanvasHeight +gCanvasColumnEnd +gCanvasRowStart +gCanvasMonPersonality +gCanvasWidth +gCanvasPalette +gCanvasPaletteStart diff --git a/data/contest_painting_effects.s b/data/contest_painting_effects.s index d14b51a51..b319b4023 100644 --- a/data/contest_painting_effects.s +++ b/data/contest_painting_effects.s @@ -4,7 +4,7 @@ .section .rodata .align 2, 0 -gUnknown_085A1F94:: @ 85A1F94 +gPointillismPoints:: @ 85A1F94 .byte 0x00, 0x1d, 0x1c, 0x0e, 0x1e, 0x1b, 0x00, 0x01, 0x32, 0x2e, 0x1e, 0x37, 0x0a, 0x22, 0x1f, 0x05, 0x26, 0x2e, 0x12, 0x17, 0x1e, 0x1a, 0x03, 0x11, 0x05, 0x11, 0x18, 0x05, 0x27, 0x2f, 0x1a, 0x3f .byte 0x12, 0x22, 0x3f, 0x16, 0x2b, 0x2f, 0x2e, 0x11, 0x02, 0x2d, 0x23, 0x0d, 0x28, 0x17, 0x0c, 0x19, 0x2f, 0x0e, 0x13, 0x30, 0x18, 0x20, 0x2d, 0x28, 0x22, 0x01, 0x03, 0x19, 0x0e, 0x2a, 0x2b, 0x22 .byte 0x15, 0x25, 0x22, 0x0a, 0x26, 0x39, 0x06, 0x23, 0x16, 0x07, 0x2f, 0x22, 0x3a, 0x1b, 0x3b, 0x36, 0x35, 0x0a, 0x2b, 0x24, 0x36, 0x09, 0x12, 0x1c, 0x2f, 0x23, 0x2e, 0x38, 0x2c, 0x05, 0x2a, 0x20 diff --git a/include/contest.h b/include/contest.h index aeedc63b1..49e130b08 100644 --- a/include/contest.h +++ b/include/contest.h @@ -453,7 +453,7 @@ extern u8 gNumLinkContestPlayers; extern u8 gHighestRibbonRank; extern struct ContestResources *gContestResources; extern u8 sContestBgCopyFlags; -extern struct ContestWinner gUnknown_02039F3C; +extern struct ContestWinner gCurContestWinner; extern u8 gUnknown_02039F5C; extern u8 gUnknown_02039F5D; diff --git a/include/contest_painting.h b/include/contest_painting.h index c633c50cc..f16a0d2f3 100644 --- a/include/contest_painting.h +++ b/include/contest_painting.h @@ -1,16 +1,7 @@ #ifndef GUARD_CONTESTPAINTING_H #define GUARD_CONTESTPAINTING_H -enum -{ - CONTESTRESULT_COOL = 9, - CONTESTRESULT_BEAUTY = 13, - CONTESTRESULT_CUTE = 2, - CONTESTRESULT_SMART = 36, - CONTESTRESULT_TOUGH = 6, -}; - -void sub_812FDA8(int); +void SetContestWinnerForPainting(int); void CB2_ContestPainting(void); #endif diff --git a/include/contest_painting_effects.h b/include/contest_painting_effects.h index 3b6964666..599c38140 100755 --- a/include/contest_painting_effects.h +++ b/include/contest_painting_effects.h @@ -1,28 +1,53 @@ #ifndef GUARD_CONTEST_PAINTING_EFFECTS_H #define GUARD_CONTEST_PAINTING_EFFECTS_H -struct Unk030061A0 +enum { - u8 var_0; - u8 pad1[3]; - u16 (*var_4)[][32]; - u16 *var_8; - u8 pad0C[4]; - u32 var_10; - u16 var_14; - u16 var_16; - u8 var_18; - u8 var_19; - u8 var_1A; - u8 var_1B; - u8 var_1C; - u8 var_1D; - u8 var_1E; - u8 var_1F; + IMAGE_EFFECT_POINTILLISM = 2, + IMAGE_EFFECT_GRAYSCALE_LIGHT = 6, + IMAGE_EFFECT_BLUR = 8, + IMAGE_EFFECT_OUTLINE_COLORED = 9, + IMAGE_EFFECT_INVERT_BLACK_WHITE = 10, + IMAGE_EFFECT_THICK_BLACK_WHITE = 11, + IMAGE_EFFECT_SHIMMER = 13, + IMAGE_EFFECT_OUTLINE = 30, + IMAGE_EFFECT_INVERT = 31, + IMAGE_EFFECT_BLUR_RIGHT = 32, + IMAGE_EFFECT_BLUR_DOWN = 33, + IMAGE_EFFECT_CHARCOAL = 36, }; -void sub_8124F2C(struct Unk030061A0 *); -void sub_81261A4(struct Unk030061A0 *); -void sub_8126058(struct Unk030061A0 *); +enum +{ + QUANTIZE_EFFECT_STANDARD, + QUANTIZE_EFFECT_STANDARD_LIMITED_COLORS, + QUANTIZE_EFFECT_PRIMARY_COLORS, + QUANTIZE_EFFECT_GRAYSCALE, + QUANTIZE_EFFECT_GRAYSCALE_SMALL, + QUANTIZE_EFFECT_BLACK_WHITE, +}; + +struct ContestPaintingContext +{ + u8 effect; + void *canvasPixels; + u16 *canvasPalette; + u8 fillerC[0x4]; + u32 dest; + u16 quantizeEffect; + u16 var_16; + u8 paletteStart; + u8 columnStart; + u8 rowStart; + u8 columnEnd; + u8 rowEnd; + u8 canvasWidth; + u8 canvasHeight; + u8 personality; +}; + +void ApplyImageProcessingEffects(struct ContestPaintingContext *); +void ApplyImageProcessingQuantization(struct ContestPaintingContext *); +void ConvertImageProcessingToGBA(struct ContestPaintingContext *); #endif diff --git a/src/contest.c b/src/contest.c index 2ad189058..b202fe71e 100644 --- a/src/contest.c +++ b/src/contest.c @@ -238,7 +238,7 @@ EWRAM_DATA u8 gNumLinkContestPlayers = 0; EWRAM_DATA u8 gHighestRibbonRank = 0; EWRAM_DATA struct ContestResources *gContestResources = NULL; EWRAM_DATA u8 sContestBgCopyFlags = 0; -EWRAM_DATA struct ContestWinner gUnknown_02039F3C = {0}; +EWRAM_DATA struct ContestWinner gCurContestWinner = {0}; EWRAM_DATA u8 gUnknown_02039F5C = 0; EWRAM_DATA u8 gUnknown_02039F5D = 0; @@ -5353,12 +5353,12 @@ bool8 sub_80DEDA8(u8 a) } else { - gUnknown_02039F3C.personality = gContestMons[i].personality; - gUnknown_02039F3C.trainerId = gContestMons[i].otId; - gUnknown_02039F3C.species = gContestMons[i].species; - StringCopy(gUnknown_02039F3C.monName, gContestMons[i].nickname); - StringCopy(gUnknown_02039F3C.trainerName, gContestMons[i].trainerName); - gUnknown_02039F3C.contestCategory = r7; + gCurContestWinner.personality = gContestMons[i].personality; + gCurContestWinner.trainerId = gContestMons[i].otId; + gCurContestWinner.species = gContestMons[i].species; + StringCopy(gCurContestWinner.monName, gContestMons[i].nickname); + StringCopy(gCurContestWinner.trainerName, gContestMons[i].trainerName); + gCurContestWinner.contestCategory = r7; } return TRUE; } diff --git a/src/contest_painting.c b/src/contest_painting.c index 2b36d5e38..40931d7d1 100644 --- a/src/contest_painting.c +++ b/src/contest_painting.c @@ -22,9 +22,9 @@ #include "constants/rgb.h" // IWRAM common -u16 (*gUnknown_03006190)[][32]; -struct Unk030061A0 gUnknown_030061A0; -struct ContestWinner *gUnknown_030061C0; +u16 (*gContestMonPixels)[][32]; +struct ContestPaintingContext gContestPaintingContext; +struct ContestWinner *gContestPaintingWinner; u16 *gContestPaintingMonPalette; // IWRAM bss @@ -39,10 +39,10 @@ static void HoldContestPainting(void); static void InitContestPaintingWindow(void); static void InitContestPaintingBg(void); static void InitContestPaintingVars(bool8); -static void sub_8130884(u8, u8); +static void CreateContestPaintingPicture(u8, u8); static void PrintContestPaintingCaption(u8, u8); static void VBlankCB_ContestPainting(void); -static void sub_8130380(u8 *spritePixels, u16 *palette, u16 (*destColorBuffer)[64][64]); +static void _InitContestMonPixels(u8 *spriteGfx, u16 *palette, u16 (*destPixels)[64][64]); extern const u8 gUnknown_0827EA0C[]; extern const u8 gContestCoolness[]; @@ -85,7 +85,7 @@ const u8 gPictureFrameTilemap_3[] = INCBIN_U8("graphics/picture_frame/frame3_map const u8 gPictureFrameTilemap_4[] = INCBIN_U8("graphics/picture_frame/frame4_map.bin.rl"); const u8 gPictureFrameTilemap_5[] = INCBIN_U8("graphics/picture_frame/frame5_map.bin.rl"); -const u8 *const gUnknown_085B07C0[] = +static const u8 *const sContestCategoryNames_Unused[] = { gContestCoolness, gContestBeauty, @@ -94,7 +94,7 @@ const u8 *const gUnknown_085B07C0[] = gContestToughness, }; -const u8 *const gContestRankTextPointers[] = +static const u8 *const sContestRankNames[] = { gContestRankNormal, gContestRankSuper, @@ -103,7 +103,7 @@ const u8 *const gContestRankTextPointers[] = gContestLink, }; -const struct BgTemplate gUnknown_085B07E8[] = +static const struct BgTemplate sContestPaintingBgTemplates[] = { { .bg = 1, @@ -116,7 +116,7 @@ const struct BgTemplate gUnknown_085B07E8[] = }, }; -const struct WindowTemplate gUnknown_085B07EC = +static const struct WindowTemplate sContestPaintingWindowTemplate = { .bg = 1, .tilemapLeft = 2, @@ -127,7 +127,7 @@ const struct WindowTemplate gUnknown_085B07EC = .baseBlock = 1, }; -const u8 *const gContestPaintingDescriptionPointers[] = +static const u8 *const sContestPaintingDescriptionPointers[] = { gContestPaintingCool1, gContestPaintingCool2, @@ -146,7 +146,7 @@ const u8 *const gContestPaintingDescriptionPointers[] = gContestPaintingTough3, }; -const struct OamData gUnknown_085B0830 = +static const struct OamData sContestPaintingMonOamData = { .y = 0, .affineMode = ST_OAM_AFFINE_OFF, @@ -163,13 +163,13 @@ const struct OamData gUnknown_085B0830 = const u16 gUnknown_085B0838[] = {RGB(0, 0, 0), RGB(0, 0, 0)}; -void sub_812FDA8(int contestWinner) +void SetContestWinnerForPainting(int contestWinnerId) { // probably fakematching u8 *ptr1 = &gUnknown_02039F5D; u8 *ptr2 = &gUnknown_02039F5C; - gUnknown_02039F3C = gSaveBlock1Ptr->contestWinners[contestWinner - 1]; - *ptr1 = contestWinner - 1; + gCurContestWinner = gSaveBlock1Ptr->contestWinners[contestWinnerId - 1]; + *ptr1 = contestWinnerId - 1; *ptr2 = 0; } @@ -189,7 +189,7 @@ static void CB2_QuitContestPainting(void) { SetMainCallback2(gMain.savedCallback); FREE_AND_SET_NULL(gContestPaintingMonPalette); - FREE_AND_SET_NULL(gUnknown_03006190); + FREE_AND_SET_NULL(gContestMonPixels); RemoveWindow(gContestPaintingWindowId); Free(GetBgTilemapBuffer(1)); FreeMonSpritesGfx(); @@ -203,7 +203,7 @@ static void ShowContestPainting(void) ScanlineEffect_Stop(); SetVBlankCallback(NULL); AllocateMonSpritesGfx(); - gUnknown_030061C0 = &gUnknown_02039F3C; + gContestPaintingWinner = &gCurContestWinner; InitContestPaintingVars(1); InitContestPaintingBg(); gMain.state++; @@ -221,7 +221,7 @@ static void ShowContestPainting(void) gMain.state++; break; case 3: - sub_8130884(gUnknown_02039F5D, gUnknown_02039F5C); + CreateContestPaintingPicture(gUnknown_02039F5D, gUnknown_02039F5C); gMain.state++; break; case 4: @@ -269,11 +269,11 @@ static void HoldContestPainting(void) static void InitContestPaintingWindow(void) { ResetBgsAndClearDma3BusyFlags(0); - InitBgsFromTemplates(0, gUnknown_085B07E8, ARRAY_COUNT(gUnknown_085B07E8)); + InitBgsFromTemplates(0, sContestPaintingBgTemplates, ARRAY_COUNT(sContestPaintingBgTemplates)); ChangeBgX(1, 0, 0); ChangeBgY(1, 0, 0); SetBgTilemapBuffer(1, AllocZeroed(BG_SCREEN_SIZE)); - gContestPaintingWindowId = AddWindow(&gUnknown_085B07EC); + gContestPaintingWindowId = AddWindow(&sContestPaintingWindowTemplate); DeactivateAllTextPrinters(); FillWindowPixelBuffer(gContestPaintingWindowId, PIXEL_FILL(0)); PutWindowTilemap(gContestPaintingWindowId); @@ -289,21 +289,21 @@ static void PrintContestPaintingCaption(u8 contestType, u8 arg1) if (arg1 == TRUE) return; - category = gUnknown_030061C0->contestCategory; + category = gContestPaintingWinner->contestCategory; if (contestType < 8) { BufferContestName(gStringVar1, category); StringAppend(gStringVar1, gText_Space); - StringAppend(gStringVar1, gContestRankTextPointers[gUnknown_030061C0->contestRank]); - StringCopy(gStringVar2, gUnknown_030061C0->trainerName); + StringAppend(gStringVar1, sContestRankNames[gContestPaintingWinner->contestRank]); + StringCopy(gStringVar2, gContestPaintingWinner->trainerName); sub_81DB5AC(gStringVar2); - StringCopy(gStringVar3, gUnknown_030061C0->monName); + StringCopy(gStringVar3, gContestPaintingWinner->monName); StringExpandPlaceholders(gStringVar4, gUnknown_0827EA0C); } else { - StringCopy(gStringVar1, gUnknown_030061C0->monName); - StringExpandPlaceholders(gStringVar4, gContestPaintingDescriptionPointers[category]); + StringCopy(gStringVar1, gContestPaintingWinner->monName); + StringExpandPlaceholders(gStringVar4, sContestPaintingDescriptionPointers[category]); } x = GetStringCenterAlignXOffset(1, gStringVar4, 208); @@ -360,18 +360,18 @@ static void VBlankCB_ContestPainting(void) TransferPlttBuffer(); } -void sub_81302E8(u16 species, u8 arg1) +static void InitContestMonPixels(u16 species, u8 whichSprite) { - const void *pal = GetMonSpritePalFromSpeciesAndPersonality(species, gUnknown_030061C0->trainerId, gUnknown_030061C0->personality); + const void *pal = GetMonSpritePalFromSpeciesAndPersonality(species, gContestPaintingWinner->trainerId, gContestPaintingWinner->personality); LZDecompressVram(pal, gContestPaintingMonPalette); - if (!arg1) + if (whichSprite == 0) { HandleLoadSpecialPokePic_DontHandleDeoxys( &gMonFrontPicTable[species], gMonSpritesGfxPtr->sprites[1], species, - gUnknown_030061C0->personality); - sub_8130380(gMonSpritesGfxPtr->sprites[1], gContestPaintingMonPalette, (void *)gUnknown_03006190); + gContestPaintingWinner->personality); + _InitContestMonPixels(gMonSpritesGfxPtr->sprites[1], gContestPaintingMonPalette, (void *)gContestMonPixels); } else { @@ -379,14 +379,14 @@ void sub_81302E8(u16 species, u8 arg1) &gMonBackPicTable[species], gMonSpritesGfxPtr->sprites[0], species, - gUnknown_030061C0->personality); - sub_8130380(gMonSpritesGfxPtr->sprites[0], gContestPaintingMonPalette, (void *)gUnknown_03006190); + gContestPaintingWinner->personality); + _InitContestMonPixels(gMonSpritesGfxPtr->sprites[0], gContestPaintingMonPalette, (void *)gContestMonPixels); } } #ifdef NONMATCHING // functionally equivalent. -static void sub_8130380(u8 *spritePixels, u16 *palette, u16 (*destColorBuffer)[64][64]) +static void _InitContestMonPixels(u8 *spriteGfx, u16 *palette, u16 (*destPixels)[64][64]) { u16 tileY, tileX, pixelY, pixelX; u8 colorIndex; @@ -400,16 +400,16 @@ static void sub_8130380(u8 *spritePixels, u16 *palette, u16 (*destColorBuffer)[6 for (pixelX = 0; pixelX < 8; pixelX++) { int offset = 32 * (8 * tileY + tileX) + (pixelY * 4 + pixelX / 2); - colorIndex = spritePixels[offset]; + colorIndex = spriteGfx[offset]; if (pixelX & 1) colorIndex >>= 4; else colorIndex &= 0xF; if (colorIndex == 0) // transparent pixel - (*destColorBuffer)[8 * tileY + pixelY][tileX * 8 + pixelX] = 0x8000; + (*destPixels)[8 * tileY + pixelY][tileX * 8 + pixelX] = 0x8000; else - (*destColorBuffer)[8 * tileY + pixelY][tileX * 8 + pixelX] = palette[colorIndex]; + (*destPixels)[8 * tileY + pixelY][tileX * 8 + pixelX] = palette[colorIndex]; } } } @@ -417,7 +417,7 @@ static void sub_8130380(u8 *spritePixels, u16 *palette, u16 (*destColorBuffer)[6 } #else NAKED -static void sub_8130380(u8 *spritePixels, u16 *palette, u16 (*destColorBuffer)[64][64]) +static void _InitContestMonPixels(u8 *spriteGfx, u16 *palette, u16 (*destPixels)[64][64]) { asm_unified("\n\ push {r4-r7,lr}\n\ @@ -519,34 +519,34 @@ _081303F8:\n\ } #endif -static void sub_8130430(u8 arg0, u8 arg1) +static void LoadContestPaintingFrame(u8 contestWinnerId, u8 arg1) { u8 x, y; LoadPalette(gPictureFramePalettes, 0, 0x100); if (arg1 == 1) { - switch (gUnknown_030061C0->contestCategory / 3) + switch (gContestPaintingWinner->contestCategory / 3) { case CONTEST_CATEGORY_COOL: RLUnCompVram(gPictureFrameTiles_0, (void *)VRAM); - RLUnCompWram(gPictureFrameTilemap_0, gUnknown_03006190); + RLUnCompWram(gPictureFrameTilemap_0, gContestMonPixels); break; case CONTEST_CATEGORY_BEAUTY: RLUnCompVram(gPictureFrameTiles_1, (void *)VRAM); - RLUnCompWram(gPictureFrameTilemap_1, gUnknown_03006190); + RLUnCompWram(gPictureFrameTilemap_1, gContestMonPixels); break; case CONTEST_CATEGORY_CUTE: RLUnCompVram(gPictureFrameTiles_2, (void *)VRAM); - RLUnCompWram(gPictureFrameTilemap_2, gUnknown_03006190); + RLUnCompWram(gPictureFrameTilemap_2, gContestMonPixels); break; case CONTEST_CATEGORY_SMART: RLUnCompVram(gPictureFrameTiles_3, (void *)VRAM); - RLUnCompWram(gPictureFrameTilemap_3, gUnknown_03006190); + RLUnCompWram(gPictureFrameTilemap_3, gContestMonPixels); break; case CONTEST_CATEGORY_TOUGH: RLUnCompVram(gPictureFrameTiles_4, (void *)VRAM); - RLUnCompWram(gPictureFrameTilemap_4, gUnknown_03006190); + RLUnCompWram(gPictureFrameTilemap_4, gContestMonPixels); break; } @@ -563,23 +563,23 @@ static void sub_8130430(u8 arg0, u8 arg1) for (y = 0; y < 10; y++) { for (x = 0; x < 18; x++) - VRAM_PICTURE_DATA(x + 6, y + 2) = (*gUnknown_03006190)[y + 2][x + 6]; + VRAM_PICTURE_DATA(x + 6, y + 2) = (*gContestMonPixels)[y + 2][x + 6]; } // Re-set the entire top row to the first top frame part for (x = 0; x < 16; x++) - VRAM_PICTURE_DATA(x + 7, 2) = (*gUnknown_03006190)[2][7]; + VRAM_PICTURE_DATA(x + 7, 2) = (*gContestMonPixels)[2][7]; #undef VRAM_PICTURE_DATA } - else if (arg0 < 8) + else if (contestWinnerId < 8) { RLUnCompVram(gPictureFrameTiles_5, (void *)VRAM); RLUnCompVram(gPictureFrameTilemap_5, (void *)(BG_SCREEN_ADDR(12))); } else { - switch (gUnknown_030061C0->contestCategory / 3) + switch (gContestPaintingWinner->contestCategory / 3) { case CONTEST_CATEGORY_COOL: RLUnCompVram(gPictureFrameTiles_0, (void *)VRAM); @@ -605,100 +605,99 @@ static void sub_8130430(u8 arg0, u8 arg1) } } -static void sub_8130688(u8 arg0) +static void InitPaintingMonOamData(u8 contestWinnerId) { //Some hacks just to get the asm to match #ifndef NONMATCHING - asm(""::"r"(arg0)); + asm(""::"r"(contestWinnerId)); #endif - gMain.oamBuffer[0] = gUnknown_085B0830; + gMain.oamBuffer[0] = sContestPaintingMonOamData; gMain.oamBuffer[0].tileNum = 0; #ifndef NONMATCHING - if (arg0) arg0 = gMain.oamBuffer[0].tileNum; + if (contestWinnerId) contestWinnerId = gMain.oamBuffer[0].tileNum; #endif gMain.oamBuffer[0].x = 88; gMain.oamBuffer[0].y = 24; } -static u8 sub_81306CC(u8 arg0) +static u8 GetImageEffectForContestWinner(u8 contestWinnerId) { u8 contestCategory; - if (arg0 < 8) - contestCategory = gUnknown_030061C0->contestCategory; + if (contestWinnerId < 8) + contestCategory = gContestPaintingWinner->contestCategory; else - contestCategory = gUnknown_030061C0->contestCategory / 3; + contestCategory = gContestPaintingWinner->contestCategory / 3; switch (contestCategory) { case CONTEST_CATEGORY_COOL: - return CONTESTRESULT_COOL; + return IMAGE_EFFECT_OUTLINE_COLORED; case CONTEST_CATEGORY_BEAUTY: - return CONTESTRESULT_BEAUTY; + return IMAGE_EFFECT_SHIMMER; case CONTEST_CATEGORY_CUTE: - return CONTESTRESULT_CUTE; + return IMAGE_EFFECT_POINTILLISM; case CONTEST_CATEGORY_SMART: - return CONTESTRESULT_SMART; + return IMAGE_EFFECT_CHARCOAL; case CONTEST_CATEGORY_TOUGH: - return CONTESTRESULT_TOUGH; + return IMAGE_EFFECT_GRAYSCALE_LIGHT; } return contestCategory; } -static void sub_8130738(void) +static void AllocPaintingResources(void) { - gContestPaintingMonPalette = AllocZeroed(0x200); - gUnknown_03006190 = AllocZeroed(0x2000); + gContestPaintingMonPalette = AllocZeroed(OBJ_PLTT_SIZE); + gContestMonPixels = AllocZeroed(0x2000); } -static void sub_8130760(u8 contestResult) +static void DoContestPaintingImageProcessing(u8 imageEffect) { - gUnknown_030061A0.var_4 = gUnknown_03006190; - gUnknown_030061A0.var_8 = gContestPaintingMonPalette; - gUnknown_030061A0.var_18 = 0; - gUnknown_030061A0.var_1F = gUnknown_030061C0->personality % 256; - gUnknown_030061A0.var_19 = 0; - gUnknown_030061A0.var_1A = 0; - gUnknown_030061A0.var_1B = 64; - gUnknown_030061A0.var_1C = 64; - gUnknown_030061A0.var_1D = 64; - gUnknown_030061A0.var_1E = 64; + gContestPaintingContext.canvasPixels = gContestMonPixels; + gContestPaintingContext.canvasPalette = gContestPaintingMonPalette; + gContestPaintingContext.paletteStart = 0; + gContestPaintingContext.personality = gContestPaintingWinner->personality % 256; + gContestPaintingContext.columnStart = 0; + gContestPaintingContext.rowStart = 0; + gContestPaintingContext.columnEnd = 64; + gContestPaintingContext.rowEnd = 64; + gContestPaintingContext.canvasWidth = 64; + gContestPaintingContext.canvasHeight = 64; - switch (contestResult) + switch (imageEffect) { - case CONTESTRESULT_SMART: - case CONTESTRESULT_TOUGH: - gUnknown_030061A0.var_14 = 3; + case IMAGE_EFFECT_CHARCOAL: + case IMAGE_EFFECT_GRAYSCALE_LIGHT: + gContestPaintingContext.quantizeEffect = QUANTIZE_EFFECT_GRAYSCALE; break; - case CONTESTRESULT_COOL: - case CONTESTRESULT_BEAUTY: - case CONTESTRESULT_CUTE: + case IMAGE_EFFECT_OUTLINE_COLORED: + case IMAGE_EFFECT_SHIMMER: + case IMAGE_EFFECT_POINTILLISM: default: - gUnknown_030061A0.var_14 = 1; + gContestPaintingContext.quantizeEffect = QUANTIZE_EFFECT_STANDARD_LIMITED_COLORS; break; } - gUnknown_030061A0.var_16 = 2; - gUnknown_030061A0.var_0 = contestResult; - gUnknown_030061A0.var_10 = OBJ_VRAM0; - - sub_8124F2C(&gUnknown_030061A0); - sub_81261A4(&gUnknown_030061A0); - sub_8126058(&gUnknown_030061A0); + gContestPaintingContext.var_16 = 2; + gContestPaintingContext.effect = imageEffect; + gContestPaintingContext.dest = OBJ_VRAM0; + ApplyImageProcessingEffects(&gContestPaintingContext); + ApplyImageProcessingQuantization(&gContestPaintingContext); + ConvertImageProcessingToGBA(&gContestPaintingContext); LoadPalette(gContestPaintingMonPalette, 0x100, 0x200); } -static void sub_8130884(u8 arg0, u8 arg1) +static void CreateContestPaintingPicture(u8 contestWinnerId, u8 arg1) { - sub_8130738(); - sub_81302E8(gUnknown_030061C0->species, 0); - sub_8130760(sub_81306CC(arg0)); - sub_8130688(arg0); - sub_8130430(arg0, arg1); + AllocPaintingResources(); + InitContestMonPixels(gContestPaintingWinner->species, 0); + DoContestPaintingImageProcessing(GetImageEffectForContestWinner(contestWinnerId)); + InitPaintingMonOamData(contestWinnerId); + LoadContestPaintingFrame(contestWinnerId, arg1); } diff --git a/src/contest_painting_effects.c b/src/contest_painting_effects.c index a791df65c..f3354c900 100644 --- a/src/contest_painting_effects.c +++ b/src/contest_painting_effects.c @@ -3,498 +3,497 @@ #include "contest_painting.h" #include "constants/rgb.h" -struct Unk8125954 -{ - u8 unk0; - u8 unk1; - u16 unk2; -}; - // IWRAM common -u8 gUnknown_03006164; -u16 (*gUnknown_03006168)[][32]; -u8 gUnknown_0300616C; -u8 gUnknown_03006170; -u8 gUnknown_03006174; -u8 gUnknown_03006178; -u8 gUnknown_0300617C; -u8 gUnknown_03006180; -u16 *gUnknown_03006184; -u16 gUnknown_03006188; +u8 gCanvasColumnStart; +u16 (*gCanvasPixels)[][32]; +u8 gCanvasRowEnd; +u8 gCanvasHeight; +u8 gCanvasColumnEnd; +u8 gCanvasRowStart; +u8 gCanvasMonPersonality; +u8 gCanvasWidth; +u16 *gCanvasPalette; +u16 gCanvasPaletteStart; -static void sub_8125230(void); -static void sub_81252E8(void); -static void sub_81254E0(void); -static void sub_8125630(void); -static void sub_8125448(void); -static void sub_81257F8(void); -static void sub_81258A0(void); -static void sub_81256C8(void); -static void sub_8125250(void); -static void sub_81253A4(u8); -static void sub_81250B8(u8); -static void sub_8125170(u8); -static void sub_8125954(u16); +static void ApplyImageEffect_Pointillism(void); +static void ApplyImageEffect_Blur(void); +static void ApplyImageEffect_BlackOutline(void); +static void ApplyImageEffect_Invert(void); +static void ApplyImageEffect_BlackAndWhite(void); +static void ApplyImageEffect_BlurRight(void); +static void ApplyImageEffect_BlurDown(void); +static void ApplyImageEffect_Shimmer(void); +static void ApplyImageEffect_Grayscale(void); +static void ApplyImageEffect_PersonalityColor(u8); +static void ApplyImageEffect_RedChannelGrayscale(u8); +static void ApplyImageEffect_RedChannelGrayscaleHighlight(u8); +static void AddPointillismPoints(u16); static u16 ConvertColorToGrayscale(u16*); -static u16 sub_8125E18(u16*, u16*, u16*); -static u16 ConvertCoolColor(u16*, u8); -static u16 ConvertToBlackOrWhite(u16*); -static u16 sub_8125C98(u16*, u16*); -static u16 InvertColor(u16*); -static u16 sub_8125F38(u16*, u16*, u16*); -static u16 sub_8125CF4(u16*, u16*); -static u16 GetCoolColorFromPersonality(u8); -static void sub_81263A4(bool8); -static void sub_8126270(void); -static void sub_8126714(void); -static void sub_8126370(void); -static void sub_8126664(void); -static void sub_8126334(void); -static void sub_81265B4(void); -static void sub_8126318(void); -static void sub_81264FC(void); -static u16 sub_81267C4(u16*); -static u16 sub_8126908(u16*); -static u16 sub_812693C(u16*); -static u16 sub_8126838(u16*); +static u16 QuantizePixel_Blur(u16*, u16*, u16*); +static u16 QuantizePixel_PersonalityColor(u16*, u8); +static u16 QuantizePixel_BlackAndWhite(u16*); +static u16 QuantizePixel_BlackOutline(u16*, u16*); +static u16 QuantizePixel_Invert(u16*); +static u16 QuantizePixel_BlurHard(u16*, u16*, u16*); +static u16 QuantizePixel_MotionBlur(u16*, u16*); +static u16 GetColorFromPersonality(u8); +static void QuantizePalette_Standard(bool8); +static void SetPresetPalette_PrimaryColors(void); +static void QuantizePalette_PrimaryColors(void); +static void SetPresetPalette_Grayscale(void); +static void QuantizePalette_Grayscale(void); +static void SetPresetPalette_GrayscaleSmall(void); +static void QuantizePalette_GrayscaleSmall(void); +static void SetPresetPalette_BlackAndWhite(void); +static void QuantizePalette_BlackAndWhite(void); +static u16 QuantizePixel_Standard(u16*); +static u16 QuantizePixel_GrayscaleSmall(u16*); +static u16 QuantizePixel_Grayscale(u16*); +static u16 QuantizePixel_PrimaryColors(u16*); -extern const u8 gUnknown_085A1F94[][3]; +extern const u8 gPointillismPoints[][3]; -void sub_8124F2C(struct Unk030061A0 *info) +void ApplyImageProcessingEffects(struct ContestPaintingContext *context) { - gUnknown_03006168 = info->var_4; - gUnknown_0300617C = info->var_1F; - gUnknown_03006164 = info->var_19; - gUnknown_03006178 = info->var_1A; - gUnknown_03006174 = info->var_1B; - gUnknown_0300616C = info->var_1C; - gUnknown_03006180 = info->var_1D; - gUnknown_03006170 = info->var_1E; - switch (info->var_0) + gCanvasPixels = context->canvasPixels; + gCanvasMonPersonality = context->personality; + gCanvasColumnStart = context->columnStart; + gCanvasRowStart = context->rowStart; + gCanvasColumnEnd = context->columnEnd; + gCanvasRowEnd = context->rowEnd; + gCanvasWidth = context->canvasWidth; + gCanvasHeight = context->canvasHeight; + + switch (context->effect) { - case 2: - sub_8125230(); + case IMAGE_EFFECT_POINTILLISM: + ApplyImageEffect_Pointillism(); break; - case 8: - sub_81252E8(); + case IMAGE_EFFECT_BLUR: + ApplyImageEffect_Blur(); break; - case 9: - sub_81254E0(); - sub_81253A4(gUnknown_0300617C); + case IMAGE_EFFECT_OUTLINE_COLORED: + ApplyImageEffect_BlackOutline(); + ApplyImageEffect_PersonalityColor(gCanvasMonPersonality); break; - case 10: - sub_81254E0(); - sub_8125630(); - sub_8125448(); - case 31: - sub_8125630(); + case IMAGE_EFFECT_INVERT_BLACK_WHITE: + ApplyImageEffect_BlackOutline(); + ApplyImageEffect_Invert(); + ApplyImageEffect_BlackAndWhite(); + case IMAGE_EFFECT_INVERT: + ApplyImageEffect_Invert(); break; - case 11: - sub_81254E0(); - sub_81257F8(); - sub_81257F8(); - sub_81258A0(); - sub_8125448(); + case IMAGE_EFFECT_THICK_BLACK_WHITE: + ApplyImageEffect_BlackOutline(); + ApplyImageEffect_BlurRight(); + ApplyImageEffect_BlurRight(); + ApplyImageEffect_BlurDown(); + ApplyImageEffect_BlackAndWhite(); break; - case 13: - sub_81256C8(); + case IMAGE_EFFECT_SHIMMER: + ApplyImageEffect_Shimmer(); break; - case 30: - sub_81254E0(); + case IMAGE_EFFECT_OUTLINE: + ApplyImageEffect_BlackOutline(); break; - case 32: - sub_81257F8(); + case IMAGE_EFFECT_BLUR_RIGHT: + ApplyImageEffect_BlurRight(); break; - case 33: - sub_81258A0(); + case IMAGE_EFFECT_BLUR_DOWN: + ApplyImageEffect_BlurDown(); break; - case 6: - sub_8125250(); - sub_81250B8(3); + case IMAGE_EFFECT_GRAYSCALE_LIGHT: + ApplyImageEffect_Grayscale(); + ApplyImageEffect_RedChannelGrayscale(3); break; - case 36: - sub_81254E0(); - sub_81257F8(); - sub_81258A0(); - sub_8125448(); - sub_81252E8(); - sub_81252E8(); - sub_81250B8(2); - sub_8125170(4); + case IMAGE_EFFECT_CHARCOAL: + ApplyImageEffect_BlackOutline(); + ApplyImageEffect_BlurRight(); + ApplyImageEffect_BlurDown(); + ApplyImageEffect_BlackAndWhite(); + ApplyImageEffect_Blur(); + ApplyImageEffect_Blur(); + ApplyImageEffect_RedChannelGrayscale(2); + ApplyImageEffect_RedChannelGrayscaleHighlight(4); break; } } -static void sub_81250B8(u8 a0) // it changes palette someway somehow... .__. +static void ApplyImageEffect_RedChannelGrayscale(u8 delta) { u8 i, j; - for (i = 0; i < gUnknown_0300616C; i++) + for (j = 0; j < gCanvasRowEnd; j++) { - u16* var2 = &(*gUnknown_03006168)[0][(gUnknown_03006178 + i) * gUnknown_03006180]; - u16* pal = &var2[gUnknown_03006164]; - for (j = 0; j < gUnknown_03006174; j++, pal++) + u16 *pixelRow = &(*gCanvasPixels)[0][(gCanvasRowStart + j) * gCanvasWidth]; + u16 *pixel = &pixelRow[gCanvasColumnStart]; + for (i = 0; i < gCanvasColumnEnd; i++, pixel++) { - if (!(0x8000 & *pal)) + if (!(0x8000 & *pixel)) { - u8 val = (31 & *pal); - val += a0; - if (val > 31) - val = 31; + // Gets the grayscale value, based on the pixel's red channel. + // Also adds a delta to skew lighter or darker. + u8 grayValue = (31 & *pixel); + grayValue += delta; + if (grayValue > 31) + grayValue = 31; - *pal = RGB2(val, val, val); + *pixel = RGB2(grayValue, grayValue, grayValue); } } } } -static void sub_8125170(u8 a0) +static void ApplyImageEffect_RedChannelGrayscaleHighlight(u8 highlight) { u8 i, j; - for (i = 0; i < gUnknown_0300616C; i++) + for (j = 0; j < gCanvasRowEnd; j++) { - u16* var2 = &(*gUnknown_03006168)[0][(gUnknown_03006178 + i) * gUnknown_03006180]; - u16* pal = &var2[gUnknown_03006164]; - for (j = 0; j < gUnknown_03006174; j++, pal++) + u16 *pixelRow = &(*gCanvasPixels)[0][(gCanvasRowStart + j) * gCanvasWidth]; + u16 *pixel = &pixelRow[gCanvasColumnStart]; + for (i = 0; i < gCanvasColumnEnd; i++, pixel++) { - if (!(0x8000 & *pal)) + if (!(0x8000 & *pixel)) { - u8 val = (31 & *pal); - if (val > 31 - a0) - val = 31 - (a0 >> 1); + u8 grayValue = (31 & *pixel); + if (grayValue > 31 - highlight) + grayValue = 31 - (highlight >> 1); - *pal = RGB2(val, val, val); + *pixel = RGB2(grayValue, grayValue, grayValue); } } } } -static void sub_8125230(void) +static void ApplyImageEffect_Pointillism(void) { u32 i; for (i = 0; i < 3200; i++) - sub_8125954(i); + AddPointillismPoints(i); } -static void sub_8125250(void) +static void ApplyImageEffect_Grayscale(void) { u8 i, j; - for (i = 0; i < gUnknown_0300616C; i++) + for (j = 0; j < gCanvasRowEnd; j++) { - u16* var2 = &(*gUnknown_03006168)[0][(gUnknown_03006178 + i) * gUnknown_03006180]; - u16* color = &var2[gUnknown_03006164]; - for (j = 0; j < gUnknown_03006174; j++, color++) + u16 *pixelRow = &(*gCanvasPixels)[0][(gCanvasRowStart + j) * gCanvasWidth]; + u16 *pixel = &pixelRow[gCanvasColumnStart]; + for (i = 0; i < gCanvasColumnEnd; i++, pixel++) { - if (!(0x8000 & *color)) - { - *color = ConvertColorToGrayscale(color); - } + if (!(0x8000 & *pixel)) + *pixel = ConvertColorToGrayscale(pixel); } } } -static void sub_81252E8(void) +static void ApplyImageEffect_Blur(void) { u8 i, j; - for (i = 0; i < gUnknown_03006174; i++) + for (i = 0; i < gCanvasColumnEnd; i++) { - u16* var0 = &(*gUnknown_03006168)[0][gUnknown_03006178 * gUnknown_03006180]; - u16* palette = &var0[gUnknown_03006164 + i]; - u16 color = *palette; + u16 *pixelRow = &(*gCanvasPixels)[0][gCanvasRowStart * gCanvasWidth]; + u16 *pixel = &pixelRow[gCanvasColumnStart + i]; + u16 prevPixel = *pixel; j = 1; - palette += gUnknown_03006180; - while (j < gUnknown_0300616C - 1) + pixel += gCanvasWidth; + while (j < gCanvasRowEnd - 1) { - if (!(0x8000 & *palette)) + if (!(0x8000 & *pixel)) { - *palette = sub_8125E18(&color, palette, palette + gUnknown_03006180); - color = *palette; + *pixel = QuantizePixel_Blur(&prevPixel, pixel, pixel + gCanvasWidth); + prevPixel = *pixel; } j++; - palette += gUnknown_03006180; + pixel += gCanvasWidth; } } } -static void sub_81253A4(u8 arg0) +static void ApplyImageEffect_PersonalityColor(u8 personality) { u8 i, j; - for (i = 0; i < gUnknown_0300616C; i++) + for (j = 0; j < gCanvasRowEnd; j++) { - u16* var0 = &(*gUnknown_03006168)[0][(gUnknown_03006178 + i) * gUnknown_03006180]; - u16* color = &var0[gUnknown_03006164]; - for (j = 0; j < gUnknown_03006174; j++, color++) + u16 *pixelRow = &(*gCanvasPixels)[0][(gCanvasRowStart + j) * gCanvasWidth]; + u16 *pixel = &pixelRow[gCanvasColumnStart]; + for (i = 0; i < gCanvasColumnEnd; i++, pixel++) { - if (!(0x8000 & *color)) - { - *color = ConvertCoolColor(color, arg0); - } + if (!(0x8000 & *pixel)) + *pixel = QuantizePixel_PersonalityColor(pixel, personality); } } } -static void sub_8125448(void) +static void ApplyImageEffect_BlackAndWhite(void) { u8 i, j; - for (i = 0; i < gUnknown_0300616C; i++) + for (j = 0; j < gCanvasRowEnd; j++) { - u16* var0 = &(*gUnknown_03006168)[0][(gUnknown_03006178 + i) * gUnknown_03006180]; - u16* color = &var0[gUnknown_03006164]; - for (j = 0; j < gUnknown_03006174; j++, color++) + u16 *pixelRow = &(*gCanvasPixels)[0][(gCanvasRowStart + j) * gCanvasWidth]; + u16 *pixel = &pixelRow[gCanvasColumnStart]; + for (i = 0; i < gCanvasColumnEnd; i++, pixel++) { - if (!(0x8000 & *color)) - { - *color = ConvertToBlackOrWhite(color); - } + if (!(0x8000 & *pixel)) + *pixel = QuantizePixel_BlackAndWhite(pixel); } } } -static void sub_81254E0(void) +static void ApplyImageEffect_BlackOutline(void) { u8 i, j; - u16 *palette; + u16 *pixel; - for (i = 0; i < gUnknown_0300616C; i++) + // Handle top row of pixels first. + for (j = 0; j < gCanvasRowEnd; j++) { - u16 *var0 = &(*gUnknown_03006168)[0][(gUnknown_03006178 + i) * gUnknown_03006180]; - palette = &var0[gUnknown_03006164]; - *palette = sub_8125C98(palette, palette + 1); - for (j = 1, palette = palette + 1; j < gUnknown_03006174 - 1; j++, palette++) + u16 *pixelRow = &(*gCanvasPixels)[0][(gCanvasRowStart + j) * gCanvasWidth]; + pixel = &pixelRow[gCanvasColumnStart]; + *pixel = QuantizePixel_BlackOutline(pixel, pixel + 1); + for (i = 1, pixel++; i < gCanvasColumnEnd - 1; i++, pixel++) { - *palette = sub_8125C98(palette, palette + 1); - *palette = sub_8125C98(palette, palette - 1); + *pixel = QuantizePixel_BlackOutline(pixel, pixel + 1); + *pixel = QuantizePixel_BlackOutline(pixel, pixel - 1); } - *palette = sub_8125C98(palette, palette - 1); + *pixel = QuantizePixel_BlackOutline(pixel, pixel - 1); } - for (j = 0; j < gUnknown_03006174; j++) + // Handle each column from left to right. + for (i = 0; i < gCanvasColumnEnd; i++) { - u16 *var0 = &(*gUnknown_03006168)[0][gUnknown_03006178 * gUnknown_03006180]; - palette = &var0[gUnknown_03006164 + j]; - *palette = sub_8125C98(palette, palette + gUnknown_03006180); - for (i = 1, palette = palette + gUnknown_03006180; i < gUnknown_0300616C - 1; i++, palette += gUnknown_03006180) + u16 *pixelRow = &(*gCanvasPixels)[0][gCanvasRowStart * gCanvasWidth]; + pixel = &pixelRow[gCanvasColumnStart + i]; + *pixel = QuantizePixel_BlackOutline(pixel, pixel + gCanvasWidth); + for (j = 1, pixel += gCanvasWidth; j < gCanvasRowEnd - 1; j++, pixel += gCanvasWidth) { - *palette = sub_8125C98(palette, palette + gUnknown_03006180); - *palette = sub_8125C98(palette, palette - gUnknown_03006180); + *pixel = QuantizePixel_BlackOutline(pixel, pixel + gCanvasWidth); + *pixel = QuantizePixel_BlackOutline(pixel, pixel - gCanvasWidth); } - *palette = sub_8125C98(palette, palette - gUnknown_03006180); + *pixel = QuantizePixel_BlackOutline(pixel, pixel - gCanvasWidth); } } -static void sub_8125630(void) +static void ApplyImageEffect_Invert(void) { u8 i, j; - for (i = 0; i < gUnknown_0300616C; i++) + for (j = 0; j < gCanvasRowEnd; j++) { - u16 *var0 = &(*gUnknown_03006168)[0][(gUnknown_03006178 + i) * gUnknown_03006180]; - u16 *color = &var0[gUnknown_03006164]; - for (j = 0; j < gUnknown_03006174; j++, color++) + u16 *pixelRow = &(*gCanvasPixels)[0][(gCanvasRowStart + j) * gCanvasWidth]; + u16 *pixel = &pixelRow[gCanvasColumnStart]; + for (i = 0; i < gCanvasColumnEnd; i++, pixel++) { - if (!(0x8000 & *color)) - { - *color = InvertColor(color); - } + if (!(0x8000 & *pixel)) + *pixel = QuantizePixel_Invert(pixel); } } } -static void sub_81256C8(void) +static void ApplyImageEffect_Shimmer(void) { u8 i, j; - u16 *palette; - u16 color; + u16 *pixel; + u16 prevPixel; - palette = (*gUnknown_03006168)[0]; + // First, invert all of the colors. + pixel = (*gCanvasPixels)[0]; for (i = 0; i < 64; i++) { - for (j = 0; j < 64; j++, palette++) + for (j = 0; j < 64; j++, pixel++) { - if (!(0x8000 & *palette)) - { - *palette = InvertColor(palette); - } + if (!(0x8000 & *pixel)) + *pixel = QuantizePixel_Invert(pixel); } } + // Blur the pixels twice. for (j = 0; j < 64; j++) { - palette = &(*gUnknown_03006168)[0][j]; - color = *palette; - *palette = 0x8000; - for (i = 1, palette += 64; i < 63; i++, palette += 64) + pixel = &(*gCanvasPixels)[0][j]; + prevPixel = *pixel; + *pixel = 0x8000; + for (i = 1, pixel += 64; i < 63; i++, pixel += 64) { - if (!(0x8000 & *palette)) + if (!(0x8000 & *pixel)) { - *palette = sub_8125F38(&color, palette, palette + 64); - color = *palette; + *pixel = QuantizePixel_BlurHard(&prevPixel, pixel, pixel + 64); + prevPixel = *pixel; } } - *palette = 0x8000; - palette = &(*gUnknown_03006168)[0][j]; - color = *palette; - *palette = 0x8000; - for (i = 1, palette += 64; i < 63; i++, palette += 64) + *pixel = 0x8000; + pixel = &(*gCanvasPixels)[0][j]; + prevPixel = *pixel; + *pixel = 0x8000; + for (i = 1, pixel += 64; i < 63; i++, pixel += 64) { - if (!(0x8000 & *palette)) + if (!(0x8000 & *pixel)) { - *palette = sub_8125F38(&color, palette, palette + 64); - color = *palette; + *pixel = QuantizePixel_BlurHard(&prevPixel, pixel, pixel + 64); + prevPixel = *pixel; } } - *palette = 0x8000; + *pixel = 0x8000; } - palette = (*gUnknown_03006168)[0]; + // Finally, invert colors back to the original color space. + // The above blur causes the outline areas to darken, which makes + // this inversion give the effect of light outlines. + pixel = (*gCanvasPixels)[0]; for (i = 0; i < 64; i++) { - for (j = 0; j < 64; j++, palette++) + for (j = 0; j < 64; j++, pixel++) { - if (!(0x8000 & *palette)) - { - *palette = InvertColor(palette); - } + if (!(0x8000 & *pixel)) + *pixel = QuantizePixel_Invert(pixel); } } } -static void sub_81257F8(void) +static void ApplyImageEffect_BlurRight(void) { u8 i, j; - for (i = 0; i < gUnknown_0300616C; i++) + for (j = 0; j < gCanvasRowEnd; j++) { - u16 *var0 = &(*gUnknown_03006168)[0][(gUnknown_03006178 + i) * gUnknown_03006180]; - u16 *palette = &var0[gUnknown_03006164]; - u16 color = *palette; - for (j = 1, palette++; j < gUnknown_03006174 - 1; j++, palette++) + u16 *pixelRow = &(*gCanvasPixels)[0][(gCanvasRowStart + j) * gCanvasWidth]; + u16 *pixel = &pixelRow[gCanvasColumnStart]; + u16 prevPixel = *pixel; + for (i = 1, pixel++; i < gCanvasColumnEnd - 1; i++, pixel++) { - if (!(0x8000 & *palette)) + if (!(0x8000 & *pixel)) { - *palette = sub_8125CF4(&color, palette); - color = *palette; + *pixel = QuantizePixel_MotionBlur(&prevPixel, pixel); + prevPixel = *pixel; } } } } -static void sub_81258A0(void) +static void ApplyImageEffect_BlurDown(void) { u8 i, j; - for (i = 0; i < gUnknown_03006174; i++) + for (i = 0; i < gCanvasColumnEnd; i++) { - u16* var0 = &(*gUnknown_03006168)[0][gUnknown_03006178 * gUnknown_03006180]; - u16* palette = &var0[gUnknown_03006164 + i]; - u16 color = *palette; - for (j = 1, palette += gUnknown_03006180; j < gUnknown_0300616C - 1; j++, palette += gUnknown_03006180) + u16 *pixelRow = &(*gCanvasPixels)[0][gCanvasRowStart * gCanvasWidth]; + u16 *pixel = &pixelRow[gCanvasColumnStart + i]; + u16 prevPixel = *pixel; + for (j = 1, pixel += gCanvasWidth; j < gCanvasRowEnd - 1; j++, pixel += gCanvasWidth) { - if (!(0x8000 & *palette)) + if (!(0x8000 & *pixel)) { - *palette = sub_8125CF4(&color, palette); - color = *palette; + *pixel = QuantizePixel_MotionBlur(&prevPixel, pixel); + prevPixel = *pixel; } } } } -static void sub_8125954(u16 arg0) +struct PointillismPoint +{ + u8 column; + u8 row; + u16 delta; +}; + +static void AddPointillismPoints(u16 arg0) { u8 i; - u8 r5, r9; - struct Unk8125954 unkStruct[6]; + bool8 offsetDownLeft; + u8 colorType; + struct PointillismPoint points[6]; - unkStruct[0].unk0 = gUnknown_085A1F94[arg0][0]; - unkStruct[0].unk1 = gUnknown_085A1F94[arg0][1]; - unkStruct[0].unk2 = (gUnknown_085A1F94[arg0][2] >> 3) & 7; + points[0].column = gPointillismPoints[arg0][0]; + points[0].row = gPointillismPoints[arg0][1]; + points[0].delta = (gPointillismPoints[arg0][2] >> 3) & 7; - r9 = (gUnknown_085A1F94[arg0][2] >> 1) & 3; - r5 = gUnknown_085A1F94[arg0][2] & 1; - for (i = 1; i < unkStruct[0].unk2; i++) + colorType = (gPointillismPoints[arg0][2] >> 1) & 3; + offsetDownLeft = gPointillismPoints[arg0][2] & 1; + for (i = 1; i < points[0].delta; i++) { - if (!r5) + if (!offsetDownLeft) { - unkStruct[i].unk0 = unkStruct[0].unk0 - i; - unkStruct[i].unk1 = unkStruct[0].unk1 + i; + points[i].column = points[0].column - i; + points[i].row = points[0].row + i; } else { - unkStruct[i].unk0 = unkStruct[0].unk0 + 1; - unkStruct[i].unk1 = unkStruct[0].unk1 - 1; + points[i].column = points[0].column + 1; + points[i].row = points[0].row - 1; } - if (unkStruct[i].unk0 > 63 || unkStruct[i].unk1 > 63) + if (points[i].column > 63 || points[i].row > 63) { - unkStruct[0].unk2 = i - 1; + points[0].delta = i - 1; break; } - unkStruct[i].unk2 = unkStruct[0].unk2 - i; + points[i].delta = points[0].delta - i; } - for (i = 0; i < unkStruct[0].unk2; i++) + for (i = 0; i < points[0].delta; i++) { - u16 *pal = &(*gUnknown_03006168)[unkStruct[i].unk1 * 2][unkStruct[i].unk0]; + u16 *pixel = &(*gCanvasPixels)[points[i].row * 2][points[i].column]; - if (!(0x8000 & *pal)) + if (!(0x8000 & *pixel)) { - u16 r = (*pal) & 0x1F; - u16 g = (*pal >> 5) & 0x1F; - u16 b = (*pal >> 10) & 0x1F; + u16 red = (*pixel) & 0x1F; + u16 green = (*pixel >> 5) & 0x1F; + u16 blue = (*pixel >> 10) & 0x1F; - switch (r9) + switch (colorType) { case 0: case 1: - switch (((gUnknown_085A1F94[arg0][2] >> 3) & 7) % 3) + switch (((gPointillismPoints[arg0][2] >> 3) & 7) % 3) { case 0: - if (r >= unkStruct[i].unk2) - r -= unkStruct[i].unk2; + if (red >= points[i].delta) + red -= points[i].delta; else - r = 0; + red = 0; break; case 1: - if (g >= unkStruct[i].unk2) - g -= unkStruct[i].unk2; + if (green >= points[i].delta) + green -= points[i].delta; else - g = 0; + green = 0; break; case 2: - if (b >= unkStruct[i].unk2) - b -= unkStruct[i].unk2; + if (blue >= points[i].delta) + blue -= points[i].delta; else - b = 0; + blue = 0; break; } break; case 2: case 3: - r += unkStruct[i].unk2; - g += unkStruct[i].unk2; - b += unkStruct[i].unk2; - if (r > 31) - r = 31; - if (g > 31) - g = 31; - if (b > 31) - b = 31; + red += points[i].delta; + green += points[i].delta; + blue += points[i].delta; + if (red > 31) + red = 31; + if (green > 31) + green = 31; + if (blue > 31) + blue = 31; break; } - *pal = RGB2(r, g, b); + *pixel = RGB2(red, green, blue); } } } @@ -511,21 +510,21 @@ static u16 ConvertColorToGrayscale(u16 *color) // The dark colors are the colored edges of the Cool painting effect. // Everything else is white. -static u16 ConvertCoolColor(u16 *color, u8 personality) +static u16 QuantizePixel_PersonalityColor(u16 *color, u8 personality) { u16 red = *color & 0x1F; u16 green = (*color >> 5) & 0x1F; u16 blue = (*color >> 10) & 0x1F; if (red < 17 && green < 17 && blue < 17) - return GetCoolColorFromPersonality(personality); + return GetColorFromPersonality(personality); else return RGB_WHITE; } // Based on the given value, which comes from the first 8 bits of // the mon's personality value, return a color. -static u16 GetCoolColorFromPersonality(u8 personality) +static u16 GetColorFromPersonality(u8 personality) { u16 red = 0; u16 green = 0; @@ -576,7 +575,7 @@ static u16 GetCoolColorFromPersonality(u8 personality) return RGB2(red, green, blue); } -static u16 ConvertToBlackOrWhite(u16 *color) +static u16 QuantizePixel_BlackAndWhite(u16 *color) { u16 red = *color & 0x1F; u16 green = (*color >> 5) & 0x1F; @@ -588,22 +587,22 @@ static u16 ConvertToBlackOrWhite(u16 *color) return RGB_WHITE; } -static u16 sub_8125C98(u16 *colorA, u16 *colorB) +static u16 QuantizePixel_BlackOutline(u16 *pixelA, u16 *pixelB) { - if (*colorA) + if (*pixelA != RGB_BLACK) { - if (*colorA & 0x8000) + if (*pixelA & 0x8000) return 0x8000; - if (*colorB & 0x8000) + if (*pixelB & 0x8000) return RGB_BLACK; - return *colorA; + return *pixelA; } return RGB_BLACK; } -static u16 InvertColor(u16 *color) +static u16 QuantizePixel_Invert(u16 *color) { u16 red = *color & 0x1F; u16 green = (*color >> 5) & 0x1F; @@ -616,158 +615,160 @@ static u16 InvertColor(u16 *color) return RGB2(red, green, blue); } -static u16 sub_8125CF4(u16 *a0, u16 *a1) -{ - u16 sp0[2][3]; - u16 spC[3]; - u8 r4; - u16 r2; - u16 r, g, b; - - if (*a0 == *a1) - return *a1; - - sp0[0][0] = (*a0 >> 0) & 0x1F; - sp0[0][1] = (*a0 >> 5) & 0x1F; - sp0[0][2] = (*a0 >> 10) & 0x1F; - sp0[1][0] = (*a1 >> 0) & 0x1F; - sp0[1][1] = (*a1 >> 5) & 0x1F; - sp0[1][2] = (*a1 >> 10) & 0x1F; - - if (sp0[0][0] > 25 && sp0[0][1] > 25 && sp0[0][2] > 25) - return *a1; - if (sp0[1][0] > 25 && sp0[1][1] > 25 && sp0[1][2] > 25) - return *a1; - - for (r4 = 0; r4 < 3; r4++) - { - if (sp0[0][r4] > sp0[1][r4]) - spC[r4] = sp0[0][r4] - sp0[1][r4]; - else - spC[r4] = sp0[1][r4] - sp0[0][r4]; - } - - if (spC[0] >= spC[1]) - { - if (spC[0] >= spC[2]) - r2 = spC[0]; - else if (spC[1] >= spC[2]) - r2 = spC[1]; - else - r2 = spC[2]; - } - else - { - if (spC[1] >= spC[2]) - r2 = spC[1]; - else if (spC[2] >= spC[0]) - r2 = spC[2]; - else - r2 = spC[0]; - } - - r = (sp0[1][0] * (31 - r2 / 2)) / 31; - g = (sp0[1][1] * (31 - r2 / 2)) / 31; - b = (sp0[1][2] * (31 - r2 / 2)) / 31; - return RGB2(r, g, b); -} - -static u16 sub_8125E18(u16 * a0, u16 * a1, u16 * a2) +static u16 QuantizePixel_MotionBlur(u16 *prevPixel, u16 *curPixel) { + u16 pixelChannels[2][3]; + u16 diffs[3]; + u8 i; + u16 largestDiff; u16 red, green, blue; - u16 avg0, avg1, avg2; - u16 diff1, diff2; - u32 minimum; - u16 factor; - if (*a0 == *a1 && *a2 == *a1) - return *a1; + if (*prevPixel == *curPixel) + return *curPixel; - red = (*a1 >> 0) & 0x1F; - green = (*a1 >> 5) & 0x1F; - blue = (*a1 >> 10) & 0x1F; + pixelChannels[0][0] = (*prevPixel >> 0) & 0x1F; + pixelChannels[0][1] = (*prevPixel >> 5) & 0x1F; + pixelChannels[0][2] = (*prevPixel >> 10) & 0x1F; + pixelChannels[1][0] = (*curPixel >> 0) & 0x1F; + pixelChannels[1][1] = (*curPixel >> 5) & 0x1F; + pixelChannels[1][2] = (*curPixel >> 10) & 0x1F; - avg0 = (((*a0 >> 0) & 0x1F) + ((*a0 >> 5) & 0x1F) + ((*a0 >> 10) & 0x1F)) / 3; - avg1 = (((*a1 >> 0) & 0x1F) + ((*a1 >> 5) & 0x1F) + ((*a1 >> 10) & 0x1F)) / 3; - avg2 = (((*a2 >> 0) & 0x1F) + ((*a2 >> 5) & 0x1F) + ((*a2 >> 10) & 0x1F)) / 3; + // Don't blur light colors. + if (pixelChannels[0][0] > 25 && pixelChannels[0][1] > 25 && pixelChannels[0][2] > 25) + return *curPixel; + if (pixelChannels[1][0] > 25 && pixelChannels[1][1] > 25 && pixelChannels[1][2] > 25) + return *curPixel; - if (avg0 == avg1 && avg2 == avg1) - return *a1; + for (i = 0; i < 3; i++) + { + if (pixelChannels[0][i] > pixelChannels[1][i]) + diffs[i] = pixelChannels[0][i] - pixelChannels[1][i]; + else + diffs[i] = pixelChannels[1][i] - pixelChannels[0][i]; + } - if (avg0 > avg1) - diff1 = avg0 - avg1; + // Find the largest diff of any of the color channels. + if (diffs[0] >= diffs[1]) + { + if (diffs[0] >= diffs[2]) + largestDiff = diffs[0]; + else if (diffs[1] >= diffs[2]) + largestDiff = diffs[1]; + else + largestDiff = diffs[2]; + } else - diff1 = avg1 - avg0; + { + if (diffs[1] >= diffs[2]) + largestDiff = diffs[1]; + else if (diffs[2] >= diffs[0]) + largestDiff = diffs[2]; + else + largestDiff = diffs[0]; + } - if (avg2 > avg1) - diff2 = avg2 - avg1; - else - diff2 = avg1 - avg2; - - if (diff1 >= diff2) - minimum = diff1; - else - minimum = diff2; - - factor = 31 - minimum / 2; - red = red * factor / 31; - green = green * factor / 31; - blue = blue * factor / 31; + red = (pixelChannels[1][0] * (31 - largestDiff / 2)) / 31; + green = (pixelChannels[1][1] * (31 - largestDiff / 2)) / 31; + blue = (pixelChannels[1][2] * (31 - largestDiff / 2)) / 31; return RGB2(red, green, blue); } -static u16 sub_8125F38(u16 *a0, u16 *a1, u16 *a2) +static u16 QuantizePixel_Blur(u16 *prevPixel, u16 *curPixel, u16 *nextPixel) { u16 red, green, blue; - u16 avg0, avg1, avg2; - u16 diff1, diff2; - u32 minimum; + u16 prevAvg, curAvg, nextAvg; + u16 prevDiff, nextDiff; + u32 diff; u16 factor; - if (*a0 == *a1 && *a2 == *a1) - return *a1; + if (*prevPixel == *curPixel && *nextPixel == *curPixel) + return *curPixel; - red = (*a1 >> 0) & 0x1F; - green = (*a1 >> 5) & 0x1F; - blue = (*a1 >> 10) & 0x1F; + red = (*curPixel >> 0) & 0x1F; + green = (*curPixel >> 5) & 0x1F; + blue = (*curPixel >> 10) & 0x1F; - avg0 = (((*a0 >> 0) & 0x1F) + ((*a0 >> 5) & 0x1F) + ((*a0 >> 10) & 0x1F)) / 3; - avg1 = (((*a1 >> 0) & 0x1F) + ((*a1 >> 5) & 0x1F) + ((*a1 >> 10) & 0x1F)) / 3; - avg2 = (((*a2 >> 0) & 0x1F) + ((*a2 >> 5) & 0x1F) + ((*a2 >> 10) & 0x1F)) / 3; + prevAvg = (((*prevPixel >> 0) & 0x1F) + ((*prevPixel >> 5) & 0x1F) + ((*prevPixel >> 10) & 0x1F)) / 3; + curAvg = (((*curPixel >> 0) & 0x1F) + ((*curPixel >> 5) & 0x1F) + ((*curPixel >> 10) & 0x1F)) / 3; + nextAvg = (((*nextPixel >> 0) & 0x1F) + ((*nextPixel >> 5) & 0x1F) + ((*nextPixel >> 10) & 0x1F)) / 3; - if (avg0 == avg1 && avg2 == avg1) - return *a1; + if (prevAvg == curAvg && nextAvg == curAvg) + return *curPixel; - if (avg0 > avg1) - diff1 = avg0 - avg1; + if (prevAvg > curAvg) + prevDiff = prevAvg - curAvg; else - diff1 = avg1 - avg0; + prevDiff = curAvg - prevAvg; - if (avg2 > avg1) - diff2 = avg2 - avg1; + if (nextAvg > curAvg) + nextDiff = nextAvg - curAvg; else - diff2 = avg1 - avg2; + nextDiff = curAvg - nextAvg; - if (diff1 >= diff2) - minimum = diff1; + if (prevDiff >= nextDiff) + diff = prevDiff; else - minimum = diff2; + diff = nextDiff; - factor = 31 - minimum; - red = red * factor / 31; - green = green * factor / 31; - blue = blue * factor / 31; + factor = 31 - diff / 2; + red = (red * factor) / 31; + green = (green * factor) / 31; + blue = (blue * factor) / 31; + return RGB2(red, green, blue); +} + +static u16 QuantizePixel_BlurHard(u16 *prevPixel, u16 *curPixel, u16 *nextPixel) +{ + u16 red, green, blue; + u16 prevAvg, curAvg, nextAvg; + u16 prevDiff, nextDiff; + u32 diff; + u16 factor; + + if (*prevPixel == *curPixel && *nextPixel == *curPixel) + return *curPixel; + + red = (*curPixel >> 0) & 0x1F; + green = (*curPixel >> 5) & 0x1F; + blue = (*curPixel >> 10) & 0x1F; + + prevAvg = (((*prevPixel >> 0) & 0x1F) + ((*prevPixel >> 5) & 0x1F) + ((*prevPixel >> 10) & 0x1F)) / 3; + curAvg = (((*curPixel >> 0) & 0x1F) + ((*curPixel >> 5) & 0x1F) + ((*curPixel >> 10) & 0x1F)) / 3; + nextAvg = (((*nextPixel >> 0) & 0x1F) + ((*nextPixel >> 5) & 0x1F) + ((*nextPixel >> 10) & 0x1F)) / 3; + + if (prevAvg == curAvg && nextAvg == curAvg) + return *curPixel; + + if (prevAvg > curAvg) + prevDiff = prevAvg - curAvg; + else + prevDiff = curAvg - prevAvg; + + if (nextAvg > curAvg) + nextDiff = nextAvg - curAvg; + else + nextDiff = curAvg - nextAvg; + + if (prevDiff >= nextDiff) + diff = prevDiff; + else + diff = nextDiff; + + factor = 31 - diff; + red = (red * factor) / 31; + green = (green * factor) / 31; + blue = (blue * factor) / 31; return RGB2(red, green, blue); } /* -void sub_8126058(struct Unk030061A0 *arg0) +void ConvertImageProcessingToGBA(struct ContestPaintingContext *arg0) { u16 i, j, k; - u8 r5 = arg0->var_1D >> 3; - u8 var_24 = arg0->var_1E >> 3; - u16 (*var_2C)[][32] = arg0->var_4; - u32 var_28 = arg0->var_10; + u8 r5 = arg0->canvasWidth >> 3; + u8 var_24 = arg0->canvasHeight >> 3; + u16 (*var_2C)[][32] = arg0->canvasPixels; + u32 var_28 = arg0->dest; if (arg0->var_16 == 2) { @@ -786,7 +787,7 @@ void sub_8126058(struct Unk030061A0 *arg0) */ NAKED -void sub_8126058(struct Unk030061A0 *arg0) +void ConvertImageProcessingToGBA(struct ContestPaintingContext *arg0) { asm_unified("\n\ push {r4-r7,lr}\n\ @@ -967,139 +968,147 @@ _08126194:\n\ bx r0"); } -void sub_81261A4(struct Unk030061A0 *arg0) +void ApplyImageProcessingQuantization(struct ContestPaintingContext *context) { - gUnknown_03006188 = arg0->var_18 * 16; - gUnknown_03006184 = &arg0->var_8[gUnknown_03006188]; - gUnknown_03006168 = arg0->var_4; - gUnknown_03006164 = arg0->var_19; - gUnknown_03006178 = arg0->var_1A; - gUnknown_03006174 = arg0->var_1B; - gUnknown_0300616C = arg0->var_1C; - gUnknown_03006180 = arg0->var_1D; - gUnknown_03006170 = arg0->var_1E; + gCanvasPaletteStart = context->paletteStart * 16; + gCanvasPalette = &context->canvasPalette[gCanvasPaletteStart]; + gCanvasPixels = context->canvasPixels; + gCanvasColumnStart = context->columnStart; + gCanvasRowStart = context->rowStart; + gCanvasColumnEnd = context->columnEnd; + gCanvasRowEnd = context->rowEnd; + gCanvasWidth = context->canvasWidth; + gCanvasHeight = context->canvasHeight; - switch (arg0->var_14) + switch (context->quantizeEffect) { - case 0: - sub_81263A4(FALSE); + case QUANTIZE_EFFECT_STANDARD: + QuantizePalette_Standard(FALSE); break; - case 1: - sub_81263A4(TRUE); + case QUANTIZE_EFFECT_STANDARD_LIMITED_COLORS: + QuantizePalette_Standard(TRUE); break; - case 2: - sub_8126270(); - sub_8126714(); + case QUANTIZE_EFFECT_PRIMARY_COLORS: + SetPresetPalette_PrimaryColors(); + QuantizePalette_PrimaryColors(); break; - case 3: - sub_8126370(); - sub_8126664(); + case QUANTIZE_EFFECT_GRAYSCALE: + SetPresetPalette_Grayscale(); + QuantizePalette_Grayscale(); break; - case 4: - sub_8126334(); - sub_81265B4(); + case QUANTIZE_EFFECT_GRAYSCALE_SMALL: + SetPresetPalette_GrayscaleSmall(); + QuantizePalette_GrayscaleSmall(); break; - case 5: - sub_8126318(); - sub_81264FC(); + case QUANTIZE_EFFECT_BLACK_WHITE: + SetPresetPalette_BlackAndWhite(); + QuantizePalette_BlackAndWhite(); break; } } -static void sub_8126270(void) +static void SetPresetPalette_PrimaryColors(void) { - gUnknown_03006184[0] = RGB2(0, 0, 0); - gUnknown_03006184[1] = RGB2(6, 6, 6); - gUnknown_03006184[2] = RGB2(29, 29, 29); - gUnknown_03006184[3] = RGB2(11, 11, 11); - gUnknown_03006184[4] = RGB2(29, 6, 6); - gUnknown_03006184[5] = RGB2(6, 29, 6); - gUnknown_03006184[6] = RGB2(6, 6, 29); - gUnknown_03006184[7] = RGB2(29, 29, 6); - gUnknown_03006184[8] = RGB2(29, 6, 29); - gUnknown_03006184[9] = RGB2(6, 29, 29); - gUnknown_03006184[10] = RGB2(29, 11, 6); - gUnknown_03006184[11] = RGB2(11, 29, 6); - gUnknown_03006184[12] = RGB2(6, 11, 29); - gUnknown_03006184[13] = RGB2(29, 6, 11); - gUnknown_03006184[14] = RGB2(6, 29, 11); - gUnknown_03006184[15] = RGB2(11, 6, 29); + gCanvasPalette[0] = RGB2(0, 0, 0); + gCanvasPalette[1] = RGB2(6, 6, 6); + gCanvasPalette[2] = RGB2(29, 29, 29); + gCanvasPalette[3] = RGB2(11, 11, 11); + gCanvasPalette[4] = RGB2(29, 6, 6); + gCanvasPalette[5] = RGB2(6, 29, 6); + gCanvasPalette[6] = RGB2(6, 6, 29); + gCanvasPalette[7] = RGB2(29, 29, 6); + gCanvasPalette[8] = RGB2(29, 6, 29); + gCanvasPalette[9] = RGB2(6, 29, 29); + gCanvasPalette[10] = RGB2(29, 11, 6); + gCanvasPalette[11] = RGB2(11, 29, 6); + gCanvasPalette[12] = RGB2(6, 11, 29); + gCanvasPalette[13] = RGB2(29, 6, 11); + gCanvasPalette[14] = RGB2(6, 29, 11); + gCanvasPalette[15] = RGB2(11, 6, 29); } -static void sub_8126318(void) +static void SetPresetPalette_BlackAndWhite(void) { - gUnknown_03006184[0] = RGB2(0, 0, 0); - gUnknown_03006184[1] = RGB2(0, 0, 0); - gUnknown_03006184[2] = RGB2(31, 31, 31); + gCanvasPalette[0] = RGB2(0, 0, 0); + gCanvasPalette[1] = RGB2(0, 0, 0); + gCanvasPalette[2] = RGB2(31, 31, 31); } -static void sub_8126334(void) +static void SetPresetPalette_GrayscaleSmall(void) { u8 i; - gUnknown_03006184[0] = RGB2(0, 0, 0); - gUnknown_03006184[1] = RGB2(0, 0, 0); + gCanvasPalette[0] = RGB2(0, 0, 0); + gCanvasPalette[1] = RGB2(0, 0, 0); for (i = 0; i < 14; i++) - gUnknown_03006184[i + 2] = RGB2(2 * (i + 2), 2 * (i + 2), 2 * (i + 2)); + gCanvasPalette[i + 2] = RGB2(2 * (i + 2), 2 * (i + 2), 2 * (i + 2)); } -static void sub_8126370(void) +static void SetPresetPalette_Grayscale(void) { u8 i; - gUnknown_03006184[0] = RGB2(0, 0, 0); + gCanvasPalette[0] = RGB2(0, 0, 0); for (i = 0; i < 32; i++) - gUnknown_03006184[i + 1] = RGB2(i, i, i); + gCanvasPalette[i + 1] = RGB2(i, i, i); } -static void sub_81263A4(bool8 arg0) +static void QuantizePalette_Standard(bool8 useLimitedPalette) { u8 i, j; u16 maxIndex; maxIndex = 0xDF; - if (!arg0) + if (!useLimitedPalette) maxIndex = 0xFF; - for (j = 0; j < maxIndex; j++) - gUnknown_03006184[j] = 0; + for (i = 0; i < maxIndex; i++) + gCanvasPalette[i] = RGB_BLACK; - gUnknown_03006184[maxIndex] = RGB2(15, 15, 15); - for (i = 0; i < gUnknown_0300616C; i++) + gCanvasPalette[maxIndex] = RGB2(15, 15, 15); + for (j = 0; j < gCanvasRowEnd; j++) { - u16* var2 = &(*gUnknown_03006168)[0][(gUnknown_03006178 + i) * gUnknown_03006180]; - u16* pal = &var2[gUnknown_03006164]; - for (j = 0; j < gUnknown_03006174; j++, pal++) + u16 *pixelRow = &(*gCanvasPixels)[0][(gCanvasRowStart + j) * gCanvasWidth]; + u16 *pixel = &pixelRow[gCanvasColumnStart]; + for (i = 0; i < gCanvasColumnEnd; i++, pixel++) { - if (*pal & 0x8000) + if (*pixel & 0x8000) { - *pal = gUnknown_03006188; + *pixel = gCanvasPaletteStart; } else { - u16 color = sub_81267C4(pal); + u16 quantizedColor = QuantizePixel_Standard(pixel); u8 curIndex = 1; if (curIndex < maxIndex) { - if (gUnknown_03006184[curIndex] == RGB_BLACK) + if (gCanvasPalette[curIndex] == RGB_BLACK) { - gUnknown_03006184[curIndex] = color; - *pal = gUnknown_03006188 + curIndex; + // The quantized color does not match any existing color in the + // palette, so we add it to the palette. + // This if block seems pointless because the below while loop handles + // this same logic. + gCanvasPalette[curIndex] = quantizedColor; + *pixel = gCanvasPaletteStart + curIndex; } else { while (curIndex < maxIndex) { - if (gUnknown_03006184[curIndex] == RGB_BLACK) + if (gCanvasPalette[curIndex] == RGB_BLACK) { - gUnknown_03006184[curIndex] = color; - *pal = gUnknown_03006188 + curIndex; + // The quantized color does not match any existing color in the + // palette, so we add it to the palette. + gCanvasPalette[curIndex] = quantizedColor; + *pixel = gCanvasPaletteStart + curIndex; break; } - if (gUnknown_03006184[curIndex] == color) + if (gCanvasPalette[curIndex] == quantizedColor) { - *pal = gUnknown_03006188 + curIndex; + // The quantized color matches this existing color in the + // palette, so we use this existing color for the pixel. + *pixel = gCanvasPaletteStart + curIndex; break; } @@ -1110,99 +1119,110 @@ static void sub_81263A4(bool8 arg0) if (curIndex == maxIndex) { + // The entire palette's colors are already in use, which means + // the base image has too many colors to handle. This error is handled + // by marking such pixels as gray color. curIndex = maxIndex; - *pal = curIndex; + *pixel = curIndex; } } } } } -static void sub_81264FC(void) +static void QuantizePalette_BlackAndWhite(void) { u8 i, j; - for (i = 0; i < gUnknown_0300616C; i++) + for (j = 0; j < gCanvasRowEnd; j++) { - u16* var2 = &(*gUnknown_03006168)[0][(gUnknown_03006178 + i) * gUnknown_03006180]; - u16* pal = &var2[gUnknown_03006164]; - for (j = 0; j < gUnknown_03006174; j++, pal++) + u16 *pixelRow = &(*gCanvasPixels)[0][(gCanvasRowStart + j) * gCanvasWidth]; + u16 *pixel = &pixelRow[gCanvasColumnStart]; + for (i = 0; i < gCanvasColumnEnd; i++, pixel++) { - if (*pal & 0x8000) + if (*pixel & 0x8000) { - *pal = gUnknown_03006188; + *pixel = gCanvasPaletteStart; } else { - if (ConvertToBlackOrWhite(pal) == RGB_BLACK) - *pal = gUnknown_03006188 + 1; + if (QuantizePixel_BlackAndWhite(pixel) == RGB_BLACK) + { + // Black is the first color in the quantized palette. + *pixel = gCanvasPaletteStart + 1; + } else - *pal = gUnknown_03006188 + 2; + { + // White is the second color in the quantized palette. + *pixel = gCanvasPaletteStart + 2; + } } } } } -static void sub_81265B4(void) +static void QuantizePalette_GrayscaleSmall(void) { u8 i, j; - for (i = 0; i < gUnknown_0300616C; i++) + for (j = 0; j < gCanvasRowEnd; j++) { - u16* var2 = &(*gUnknown_03006168)[0][(gUnknown_03006178 + i) * gUnknown_03006180]; - u16* pal = &var2[gUnknown_03006164]; - for (j = 0; j < gUnknown_03006174; j++, pal++) + u16 *pixelRow = &(*gCanvasPixels)[0][(gCanvasRowStart + j) * gCanvasWidth]; + u16 *pixel = &pixelRow[gCanvasColumnStart]; + for (i = 0; i < gCanvasColumnEnd; i++, pixel++) { - if (*pal & 0x8000) - *pal = gUnknown_03006188; + if (*pixel & 0x8000) + *pixel = gCanvasPaletteStart; else - *pal = sub_8126908(pal) + gUnknown_03006188; + *pixel = QuantizePixel_GrayscaleSmall(pixel) + gCanvasPaletteStart; } } } -static void sub_8126664(void) +static void QuantizePalette_Grayscale(void) { u8 i, j; - for (i = 0; i < gUnknown_0300616C; i++) + for (j = 0; j < gCanvasRowEnd; j++) { - u16* var2 = &(*gUnknown_03006168)[0][(gUnknown_03006178 + i) * gUnknown_03006180]; - u16* pal = &var2[gUnknown_03006164]; - for (j = 0; j < gUnknown_03006174; j++, pal++) + u16 *pixelRow = &(*gCanvasPixels)[0][(gCanvasRowStart + j) * gCanvasWidth]; + u16 *pixel = &pixelRow[gCanvasColumnStart]; + for (i = 0; i < gCanvasColumnEnd; i++, pixel++) { - if (*pal & 0x8000) - *pal = gUnknown_03006188; + if (*pixel & 0x8000) + *pixel = gCanvasPaletteStart; else - *pal = sub_812693C(pal) + gUnknown_03006188; + *pixel = QuantizePixel_Grayscale(pixel) + gCanvasPaletteStart; } } } -static void sub_8126714(void) +static void QuantizePalette_PrimaryColors(void) { u8 i, j; - for (i = 0; i < gUnknown_0300616C; i++) + for (j = 0; j < gCanvasRowEnd; j++) { - u16* var2 = &(*gUnknown_03006168)[0][(gUnknown_03006178 + i) * gUnknown_03006180]; - u16* pal = &var2[gUnknown_03006164]; - for (j = 0; j < gUnknown_03006174; j++, pal++) + u16 *pixelRow = &(*gCanvasPixels)[0][(gCanvasRowStart + j) * gCanvasWidth]; + u16 *pixel = &pixelRow[gCanvasColumnStart]; + for (i = 0; i < gCanvasColumnEnd; i++, pixel++) { - if (*pal & 0x8000) - *pal = gUnknown_03006188; + if (*pixel & 0x8000) + *pixel = gCanvasPaletteStart; else - *pal = sub_8126838(pal) + gUnknown_03006188; + *pixel = QuantizePixel_PrimaryColors(pixel) + gCanvasPaletteStart; } } } -static u16 sub_81267C4(u16 *color) +// Quantizes the pixel's color channels to nearest multiple of 4, and clamps to [6, 30]. +static u16 QuantizePixel_Standard(u16 *pixel) { - u16 red = *color & 0x1F; - u16 green = (*color >> 5) & 0x1F; - u16 blue = (*color >> 10) & 0x1F; + u16 red = *pixel & 0x1F; + u16 green = (*pixel >> 5) & 0x1F; + u16 blue = (*pixel >> 10) & 0x1F; + // Quantize color channels to muliples of 4, rounding up. if (red & 3) red = (red & 0x1C) + 4; if (green & 3) @@ -1210,16 +1230,15 @@ static u16 sub_81267C4(u16 *color) if (blue & 3) blue = (blue & 0x1C) + 4; + // Clamp channels to [6, 30]. if (red < 6) red = 6; if (red > 30) red = 30; - if (green < 6) green = 6; if (green > 30) green = 30; - if (blue < 6) blue = 6; if (blue > 30) @@ -1228,7 +1247,7 @@ static u16 sub_81267C4(u16 *color) return RGB2(red, green, blue); } -static u16 sub_8126838(u16* color) +static u16 QuantizePixel_PrimaryColors(u16* color) { u16 red = *color & 0x1F; u16 green = (*color >> 5) & 0x1F; @@ -1343,7 +1362,7 @@ static u16 sub_8126838(u16* color) return 3; } -static u16 sub_8126908(u16 *color) +static u16 QuantizePixel_GrayscaleSmall(u16 *color) { u16 red = *color & 0x1F; u16 green = (*color >> 5) & 0x1F; @@ -1355,7 +1374,7 @@ static u16 sub_8126908(u16 *color) return average / 2; } -static u16 sub_812693C(u16 *color) +static u16 QuantizePixel_Grayscale(u16 *color) { u16 red = *color & 0x1F; u16 green = (*color >> 5) & 0x1F; diff --git a/src/scrcmd.c b/src/scrcmd.c index 610547dd8..02bc026d9 100644 --- a/src/scrcmd.c +++ b/src/scrcmd.c @@ -1467,10 +1467,10 @@ bool8 ScrCmd_hidemonpic(struct ScriptContext *ctx) bool8 ScrCmd_showcontestwinner(struct ScriptContext *ctx) { - u8 v1 = ScriptReadByte(ctx); + u8 contestWinnerId = ScriptReadByte(ctx); + if (contestWinnerId) + SetContestWinnerForPainting(contestWinnerId); - if (v1) - sub_812FDA8(v1); ShowContestWinner(); ScriptContext1_Stop(); return TRUE;