今回はGBAで利用できる特殊効果のうち、モザイク機能を使います。選択したBGやスプライトに対して画像を縦×横の一定サイズで区切り、その部分を左上の色で塗りつぶすというものです。色を混ぜるわけではありません。
これからのチュートリアルはソースコードを分割して見通しをよくしています。前提知識についてはWikiのドキュメントに書かれているので疑問に思った場合はそちらを参照してください。
400004Ch - MOSAIC - Mosaic Size (W) The Mosaic function can be separately enabled/disabled for BG0-BG3 by BG0CNT-BG3CNT Registers, as well as for each OBJ0-127 by OBJ attributes in OAM memory. Also, setting all of the bits below to zero effectively disables the mosaic function. Bit Expl. 0-3 BG Mosaic H-Size (minus 1) 4-7 BG Mosaic V-Size (minus 1) 8-11 OBJ Mosaic H-Size (minus 1) 12-15 OBJ Mosaic V-Size (minus 1) 16-31 Not used Example: When setting H-Size to 5, then pixels 0-5 of each display row are colorized as pixel 0, pixels 6-11 as pixel 6, pixels 12-17 as pixel 12, and so on.
#define REG_MOSAIC *(volatile u32*)0x400004C #define MOSAIC_BG_H(x) ((x)<<0) #define MOSAIC_BG_V(x) ((x)<<4) #define MOSAIC_OBJ_H(x) ((x)<<8) #define MOSAIC_OBJ_V(x) ((x)<<12)
レジスタはREG_MOSAICです。そのほかのマクロは、横と縦のサイズをあらわしています。設定する値はそれぞれ0-15の範囲で、15がもっとも大きいモザイクで、0は通常の画像と変わりません。(数値+1)の範囲をモザイクの最小単位となります。事前準備としてBGはREG_BGxCNT(xはBG番号)のBG_MOZAIC_ON、スプライトはそれぞれのOAMのattribute0のSP_MOSAICを設定すると適用されるようになります。
#include "lib/gba.h" #include "res.h" #include "irq.arm.h" #include "key.h" //--------------------------------------------------------------------------- int main(void) { REG_WSCNT = 0x4317; IrqInit(); KeyInit(); SetMode(MODE_3 | BG2_ENABLE); REG_BG2CNT = BG_MOSAIC; REG_DMA3SAD = (u32)&imageBitmap; REG_DMA3DAD = (u32)VRAM; REG_DMA3CNT = (u32)(240*160) | (DMA_SRC_INC | DMA_DST_INC | DMA16 | DMA_ENABLE); s32 cx = 5; s32 cy = 5; u16 cnt; for(;;) { VBlankIntrWait(); REG_MOSAIC = MOSAIC_BG_H(cx) | MOSAIC_BG_V(cy); KeyExec(); cnt = KeyGetCnt(); if(cnt & KEY_UP ) cy--; if(cnt & KEY_DOWN ) cy++; if(cnt & KEY_LEFT ) cx--; if(cnt & KEY_RIGHT) cx++; if(cx < 0) cx = 0; if(cx > 15) cx = 15; if(cy < 0) cy = 0; if(cy > 15) cy = 15; } }