// Play a MOD file converted to HIT // MOD Wiki page : https://github.com/ABelliqueux/nolibgs_hello_worlds/wiki/MOD #include #include #include #include #include #include // Mod playback #include "src/mod.h" #define VMODE 0 // Video Mode : 0 : NTSC, 1: PAL #define SCREENXRES 320 // Screen width #define SCREENYRES 240 // Screen height : If VMODE is 0 = 240, if VMODE is 1 = 256 #define CENTERX SCREENXRES/2 // Center of screen on x #define CENTERY SCREENYRES/2 // Center of screen on y #define FONTX 960 #define FONTY 0 #define OTLEN 8 DISPENV disp[2]; // Double buffered DISPENV and DRAWENV DRAWENV draw[2]; short db = 1; // index of which buffer is used, values 0, 1 // Font color CVECTOR fntColor = { 128, 255, 0 }; CVECTOR fntColorBG = { 0, 0, 0 }; // MOD Playback #define MAXVOLUME 65536 #define INCVOLUME 256 // State enum PLAYBACK { STOP = 0, PLAY = 1, PAUSE = 2, }; // Music volume should range from 0 to 65536 u_int musicVolume = 2048; enum PLAYBACK state = PLAY; void init(void); void FntColor(CVECTOR fgcol, CVECTOR bgcol ); void display(void); void drawBG(void); void checkPad(void); void FntColor(CVECTOR fgcol, CVECTOR bgcol ) { // The debug font clut is at tx, ty + 128 // tx = bg color // tx + 1 = fg color // We can override the color by drawing a rect at these coordinates // RECT fg = { FONTX+1, FONTY + 128, 1, 1 }; RECT bg = { FONTX, FONTY + 128, 1, 1 }; ClearImage(&fg, fgcol.r, fgcol.g, fgcol.b); ClearImage(&bg, bgcol.r, bgcol.g, bgcol.b); } void init(void) { ResetCallback(); ResetGraph(0); // Initialize drawing engine with a complete reset (0) InitGeom(); SetGeomOffset(CENTERX,CENTERY); SetGeomScreen(CENTERX); SetDefDispEnv(&disp[0], 0, 0 , SCREENXRES, SCREENYRES); // Set display area for both &disp[0] and &disp[1] SetDefDispEnv(&disp[1], 0, SCREENYRES, SCREENXRES, SCREENYRES); // &disp[0] is on top of &disp[1] SetDefDrawEnv(&draw[0], 0, SCREENYRES, SCREENXRES, SCREENYRES); // Set draw for both &draw[0] and &draw[1] SetDefDrawEnv(&draw[1], 0, 0 , SCREENXRES, SCREENYRES); // &draw[0] is below &draw[1] // Set video mode #if VMODE SetVideoMode(MODE_PAL); disp[0].disp.y = 8; disp[1].disp.y = 8; #endif SetDispMask(1); // Display on screen setRGB0(&draw[0], 40, 40, 40); // set color for first draw area setRGB0(&draw[1], 40, 40, 40); // set color for second draw area draw[0].isbg = 1; // set mask for draw areas. 1 means repainting the area with the RGB color each frame draw[1].isbg = 1; PutDispEnv(&disp[db]); // set the disp and draw environnments PutDrawEnv(&draw[db]); FntLoad(FONTX, FONTY); // Load font to vram at 960,0(+128) FntOpen(16, 60, 288, 260, 0, 256 ); // FntOpen(x, y, width, height, black_bg, max. nbr. chars FntColor(fntColor, fntColorBG); } void display(void) { DrawSync(0); // Wait for all drawing to terminate VSync(0); // Wait for the next vertical blank PutDispEnv(&disp[db]); // set alternate disp and draw environnments PutDrawEnv(&draw[db]); db = !db; } void checkPad(void) { u_short pad = 0; static u_short oldPad; pad = PadRead(0); // Up if ( pad & PADLup && !(oldPad & PADLup) ) { MOD_PlaySoundEffect(11, 25, 15, 63); oldPad = pad; } if ( !(pad & PADLup) && oldPad & PADLup ) { oldPad = pad; } // Down if ( pad & PADLdown && !(oldPad & PADLdown) ) { MOD_PlaySoundEffect(12, 26, 15, 63); oldPad = pad; } if ( !(pad & PADLdown) && oldPad & PADLdown ) { oldPad = pad; } // Left if ( pad & PADLleft && !(oldPad & PADLleft) ) { MOD_PlaySoundEffect(13, 27, 15, 63); oldPad = pad; } if ( !(pad & PADLleft) && oldPad & PADLleft ) { oldPad = pad; } // Right if ( pad & PADLright && !(oldPad & PADLright) ) { // Channel 1 is transition anim, only take input when !transition MOD_PlaySoundEffect(6, 21, 15, 63); oldPad = pad; } if ( !(pad & PADLright) && oldPad & PADLright ) { oldPad = pad; } // Cross button if ( pad & PADRdown && !(oldPad & PADRdown) ) { // Select sound MOD_PlaySoundEffect(7, 22, 15, 63); oldPad = pad; } if ( !(pad & PADRdown) && oldPad & PADRdown ) { oldPad = pad; } // Square button if ( pad & PADRleft && !(oldPad & PADRleft) ) { // Select sound MOD_PlaySoundEffect(8, 23, 15, 63); oldPad = pad; } if ( !(pad & PADRleft) && oldPad & PADRleft ) { oldPad = pad; } // Circle button if ( pad & PADRright && !(oldPad & PADRright) ) { // Select sound MOD_PlaySoundEffect(9, 28, 15, 63); oldPad = pad; } if ( !(pad & PADRright) && oldPad & PADRright ) { oldPad = pad; } // Circle button if ( pad & PADRup && !(oldPad & PADRup) ) { // Select sound MOD_PlaySoundEffect(9, 24, 15, 63); oldPad = pad; } if ( !(pad & PADRup) && oldPad & PADRup ) { oldPad = pad; } // Select button : Stop mod / Play back from the start if ( pad & PADselect && !(oldPad & PADselect) ) { if ( state == PLAY ) { stopMusic(); state = STOP; } else if ( state == STOP ) { loadMod(); startMusic(); state = PLAY; } oldPad = pad; } if ( !(pad & PADselect) && oldPad & PADselect ) { oldPad = pad; } // Start button : Toggle playback pause if ( pad & PADstart && !(oldPad & PADstart) ) { if ( state == PLAY ) { pauseMusic(); state = PAUSE; } else if ( state == PAUSE ) { resumeMusic(); state = PLAY; } oldPad = pad; } if ( !(pad & PADstart) && oldPad & PADstart ) { oldPad = pad; } // R1/R2 : change music volume if ( pad & PADR1 && !(oldPad & PADR1) ) { if(musicVolume < MAXVOLUME) { musicVolume += INCVOLUME; } MOD_SetMusicVolume(musicVolume); oldPad = pad; } if ( !(pad & PADR1) && oldPad & PADR1 ) { oldPad = pad; } if ( pad & PADR2 && !(oldPad & PADR2) ) { if(musicVolume > 0) { musicVolume -= INCVOLUME; } MOD_SetMusicVolume(musicVolume); oldPad = pad; } if ( !(pad & PADR2) && oldPad & PADR2 ) { oldPad = pad; } } int main() { u_int t = 0; init(); PadInit(0); VSyncCallback(checkPad); // Mod Playback loadMod(); startMusic(); MOD_SetMusicVolume(musicVolume); // Main loop while (1) { // Timer t++; // Print stuff FntPrint("Hello mod ! %d\nUse the pad's buttons to\nplay sound effects.\n", t); FntPrint("State: %d, music volume : %d\n", state, musicVolume); FntPrint("Start : play/pause music.\n"); FntPrint("select : stop/play music.\n"); FntPrint("R1/R2 : Change music volume.\n"); FntFlush(-1); display(); } return 0; }