Beispiel #1
0
static void VBlankIntr(void)
{
	// Reflect virtual screen to VRAM
	DC_FlushRange( gTopScreen , sizeof( gTopScreen ) );
	DC_FlushRange( gBottomScreen , sizeof( gBottomScreen ) );
	GX_LoadBG0Scr( gTopScreen , 0 , sizeof( gTopScreen ) );
	GXS_LoadBG0Scr( gBottomScreen , 0 , sizeof( gBottomScreen ) );

	// Set IRQ check flag
	OS_SetIrqCheckFlag( OS_IE_V_BLANK );
}
Beispiel #2
0
void TextButton::init_vram( const void* source, u16*& vram_dest )
{
	vram_dest = oamAllocateGfx( this->get_oam(), this->sprite_size, SpriteColorFormat_Bmp );
	DC_FlushRange( source, SPRITE_SIZE_PIXELS(this->sprite_size)*2 );
	dmaCopy( source, vram_dest, SPRITE_SIZE_PIXELS(this->sprite_size)*2 );
	set_16bpp_sprite_opague( vram_dest, SPRITE_SIZE_PIXELS(this->sprite_size)*2 );
}
// Returns index of passed paletteAsset in video memory. DMA copies it if needed
uint8 assets::getPalette(paletteAsset *pal)
{
	// Don't do anything if passed NULL
	if (!pal) return 0;

	// Return its index if it's already loaded
	if (pal->vmLoaded)
		return pal->index;

	// If it's not in main memory for some reason, load it
	if (!pal->mmLoaded)
		loadPalette(pal);

	// Keep track of which index a palette can be loaded into
	static int curIndex = 0;

	// TODO: add support for 256 color palettes
	static const int numColors = 16;

	DC_FlushRange(pal->data, pal->length);
	dmaCopyHalfWordsAsynch(3, pal->data, &SPRITE_PALETTE[curIndex * numColors], pal->length);

	// Update the paletteAsset's information
	pal->vmLoaded = true;
	pal->index = curIndex;
	//iprintf("pal vmLoaded -> %d\n", curIndex);

	// Update the index for the next call
	curIndex++;

	// return index
	return curIndex - 1;
}
// returns the offset for the gfxAsset in video memory. DMA copies if needed
uint16 *assets::getGfx(gfxAsset *gfx)
{
	// Don't do anything if passed a NULL pointer
	if (!gfx)
		return 0;

	// If it's already loaded, just return its offset
	if (gfx->vmLoaded)
		return gfx->offset;

	// If the gfx isn't in main memory (which it should be), run loadGfx()
	if (!gfx->mmLoaded)
		loadGfx(gfx);

	// It would appear that the gfx is in main memory, but video memory.
	// So load it up!

	// Allocate video memory for the gfx
	uint16 *mem = oamAllocateGfx(oam, gfx->size, SpriteColorFormat_16Color);
	gfx->offset = mem;
	gfx->vmLoaded = true;

	// Start copying asynchronously
	uint16 length = gfx->length;
	DC_FlushRange(gfx->data, length);
	dmaCopyHalfWordsAsynch(3, gfx->data, mem, length);

	//iprintf("gfx vmLoaded -> %x\n", (unsigned int) gfx->offset);

	return mem;
}
void CGbaLoader::LoadBorder(void)
{
  videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE);
  videoSetModeSub(MODE_5_2D | DISPLAY_BG3_ACTIVE);
  vramSetMainBanks(VRAM_A_MAIN_BG_0x06000000, VRAM_B_MAIN_BG_0x06020000, VRAM_C_SUB_BG_0x06200000, VRAM_D_LCD);

  // for the main screen
  REG_BG3CNT = BG_BMP16_256x256 | BG_BMP_BASE(0) | BG_WRAP_OFF;
  REG_BG3PA = 1 << 8; //scale x
  REG_BG3PB = 0; //rotation x
  REG_BG3PC = 0; //rotation y
  REG_BG3PD = 1 << 8; //scale y
  REG_BG3X = 0; //translation x
  REG_BG3Y = 0; //translation y

  memset((void*)BG_BMP_RAM(0),0,0x18000);
  memset((void*)BG_BMP_RAM(8),0,0x18000);

  cBMP15 frameBMP=createBMP15FromFile(SFN_GBAFRAME);
  if(frameBMP.valid()&&frameBMP.width()==SCREEN_WIDTH&&frameBMP.height()==SCREEN_HEIGHT)
  {
    DC_FlushRange(frameBMP.buffer(),SCREEN_WIDTH*SCREEN_HEIGHT*2);
    dmaCopy(frameBMP.buffer(),(void*)BG_BMP_RAM(0),SCREEN_WIDTH*SCREEN_HEIGHT*2);
    dmaCopy(frameBMP.buffer(),(void*)BG_BMP_RAM(8),SCREEN_WIDTH*SCREEN_HEIGHT*2);
  }
}
Beispiel #6
0
void gamestate::initLandscape() {
    // Sets up the palette
    landscape1.Palette[BLACK]      =   BLACK_15BIT;
    landscape1.Palette[RED]        =   RED_15BIT;
    landscape1.Palette[GREEN]      =   GREEN_15BIT;
    landscape1.Palette[BLUE]       =   BLUE_15BIT;
    landscape1.Palette[YELLOW]     =   YELLOW_15BIT;
    landscape1.Palette[TURQUIS]    =   TURQUIS_15BIT;
    landscape1.Palette[PURPLE]     =   PURPLE_15BIT;
    landscape1.Palette[WHITE]      =   WHITE_15BIT;
    landscape1.Palette[ORANGE]     =   ORANGE_15BIT;
    landscape1.Palette[MAGENTA]    =   MAGENTA_15BIT;
    landscape1.Palette[SALMON]     =   SALMON_15BIT;
    landscape1.Palette[DIRT]       =   DIRT_15BIT;
    landscape1.Palette[DARKBG]     =   DARKBG_15BIT;
    // Gets the DS ready to write to VRAM
    DC_FlushRange(landscape1.Palette, BG_PAL_LEN);
    // Writes Palette to VRAM
    dmaCopy(landscape1.Palette, BG_PALETTE, BG_PAL_LEN);
    landscape1.colorI = DIRT;
    landscape1.backgroundColorI = DARKBG;
    // makes all pixels of the background blue
    landscape1.fill(landscape1.backgroundColorI);
    landscape1.initCosLandscape(); //Calculates heights for a Landscape
    landscape1.fillLandscape(); // Sets the landscape based on heights

    object::landscape1 = &landscape1;
}
Beispiel #7
0
static inline bool decompress(memchunk_t* pChunk, FILE* f, size_t compSize)
{
	word_t compType = read32(f);
	word_t decompSize = compType >> 8;
	compType &= 0xF0;

	// Alloc first the uncompressed buffer in order to avoid heap fragmentation
	memchunk_t chunk = MemChunk_Alloc(decompSize);
	if (!chunk) return false;

	if (compType == 0) // Shortcut for uncompressed
	{
		if (decompSize != (compSize - 4))
		{
			MemChunk_Free(chunk);
			return false;
		}
		fread(chunk, 1, decompSize, f);
		DC_FlushRange(chunk, decompSize);
		*pChunk = chunk;
		return true;
	}

	void* compBuf = malloc(compSize);
	if (!compBuf)
	{
		MemChunk_Free(chunk);
		return false;
	}

	bool bSuccess = true;
	fseek(f, -4, SEEK_CUR);
	fread(compBuf, 1, compSize, f);

	decompressAuto(compBuf, chunk, false);

	free(compBuf);
	if (bSuccess)
	{
		DC_FlushRange(chunk, decompSize);
		*pChunk = chunk;
		return true;
	}

	MemChunk_Free(chunk);
	return false;
}
Beispiel #8
0
static bool LoadNDS(data_t* pData, const char* fname, const u32 Offset, const u32 Size)
{
	FILE* f = fopen(fname, "rb");
	if (!f) return false;
	fseek(f, Offset, SEEK_SET);
	pData->size = Size;
	pData->data = malloc(Size);
	fread(pData->data, 1, Size, f);
	fclose(f);
	DC_FlushRange(pData->data, Size);
	return true;
}
Beispiel #9
0
static bool LoadFile(data_t* pData, const char* fname)
{
	FILE* f = fopen(fname, "rb");
	if (!f) return false;
	fseek(f, 0, SEEK_END);
	pData->size = ftell(f);
	rewind(f);
	pData->data = malloc(pData->size);
	fread(pData->data, 1, pData->size, f);
	fclose(f);
	DC_FlushRange(pData->data, pData->size);
	return true;
}
Beispiel #10
0
static int NDS_UpdateWindowFramebuffer(_THIS, SDL_Window * window,
									   SDL_Rect * rects, int numrects)
{
	struct NDS_WindowData *wdata = window->driverdata;

	/* Copy everything. TODO: use rects/numrects. */
	DC_FlushRange(wdata->pixels, wdata->pixels_length);

	swiWaitForVBlank();

	dmaCopy(wdata->main.pixels, wdata->main.vram_pixels, wdata->main.length);
	dmaCopy(wdata->sub.pixels, wdata->sub.vram_pixels, wdata->sub.length);

    return 0;
}
Beispiel #11
0
static void flush_frame(void) {
	uint8_t *fill_to = frame_base + FRAME_SIZE;
	while (wrptr < fill_to)
		*(wrptr++) = lastsample;
	DC_FlushRange(frame_base, FRAME_SIZE);
	frame_cycle_base += FRAME_CYCLES;
	frame_cycle = 0;
	flush_event->at_cycle = frame_cycle_base + FRAME_CYCLES;
	event_queue(&MACHINE_EVENT_LIST, flush_event);
	writing_buf ^= 1;
	frame_base = buf + (writing_buf * FRAME_SIZE);
	wrptr = frame_base;
	/* wait here */
	if ((REG_IPC_SYNC & 1) == writing_buf) {
		swiIntrWait(1, IRQ_IPC_SYNC);
	}
}
Beispiel #12
0
static void NDS_HW_Update()
{
	/* TODO should be called md_bpm/2.5 times per second? */
	md_player();
	int i;
	DC_FlushRange(ipc, sizeof(*ipc));
	for(i = 0; i < NDS_HW_MAXVOICES; i++) {
		NDS_HW_VOICE* v = ipc->voices + i;
		if(v->changes != 0) {
			MikMod9_SendCommand(
				(NDS_HW_CMD_VOICE_UPDATE << 28) |
				(v->changes << 8) |
				i);
			v->changes = 0;
		}
	}
}
Beispiel #13
0
void gamestate::battleAction() {
    // applies Gravity to all objects (moves them)
    for(u8 i = 0; i < players_count; i += 1) {
        players[i].applyGravity();
    }
    bombs[0].applyGravity();
    //landscape1.dropLandscape();
    swiWaitForVBlank(); // Wait for a good time to put stuff in OAM
    // Put objects in OAM
    for(u8 i = 0; i < players_count; i += 1) {
        players[i].updateOAM();
    }
    bombs[0].updateOAM();
    oamUpdate(&oamMain);
    // Updates the Landscape and Background
    DC_FlushRange(landscape1.Bitmap, BG_BITMAP_LEN);
    dmaCopy(landscape1.Bitmap, bgGetGfxPtr(bg[2]), BG_BITMAP_LEN);
}
Beispiel #14
0
//---------------------------------------------------------------------------------
bool sdio_WriteSectors(sec_t sector, sec_t numSectors,const void* buffer) {
//---------------------------------------------------------------------------------
	FifoMessage msg;

	DC_FlushRange(buffer,numSectors * 512);

	msg.type = SDMMC_SD_WRITE_SECTORS;
	msg.sdParams.startsector = sector;
	msg.sdParams.numsectors = numSectors;
	msg.sdParams.buffer = (void*)buffer;
	
	fifoSendDatamsg(FIFO_SDMMC, sizeof(msg), (u8*)&msg);

	fifoWaitValue32(FIFO_SDMMC);

	int result = fifoGetValue32(FIFO_SDMMC);
	
	return result == 0;
}
Beispiel #15
0
void Util_SetupStrideFixAffine(BG23AffineInfo* pAffineInfo, int srcStride, int dstStride, int xOffset, int yOffset, int xScale, int yScale)
{
	int startoffset = -yOffset * srcStride;
	int x = startoffset & 0xFF;
	int y = startoffset >> 8;
	int realy = 128;//0;
	//setup affine shit
	for(int i = 0; i < 192; i++)
	{
		pAffineInfo[i].BG2PA = xScale;
		pAffineInfo[i].BG2PB = 0;
		pAffineInfo[i].BG2PC = 0;
		pAffineInfo[i].BG2PD = 256;
		pAffineInfo[i].BG3PA = xScale;
		pAffineInfo[i].BG3PB = 0;
		pAffineInfo[i].BG3PC = 0;
		pAffineInfo[i].BG3PD = 256;
		pAffineInfo[i].BG2X = x * 256 - xOffset * 256 + 128;
		pAffineInfo[i].BG2Y = y * 256;
		if(dstStride - x < srcStride)
		{
			pAffineInfo[i].BG3X = (x - dstStride) * 256 - xOffset * 256 + 128;
			pAffineInfo[i].BG3Y = (y + 1) * 256;
		}
		else
		{
			pAffineInfo[i].BG3X = x * 256 - xOffset * 256 + 128;
			pAffineInfo[i].BG3Y = y * 256;
		}
		//some lines need to be repeated
		if((realy & 0xFF) + yScale >= dstStride)
		{
			x += srcStride;
			if(x >= dstStride)
			{
				x -= dstStride;
				y++;
			}
		}
		realy += yScale;
	}
	DC_FlushRange(pAffineInfo, sizeof(BG23AffineInfo) * 192);
}
Beispiel #16
0
void * bufferFile(const char * file, int * sz)
{
	if (!hArc) return NULL;

	farfile_t hFile = FAR_GetFile(hArc, file);
	if (!hFile) return NULL;
	size_t size;
	if(sz)
		*sz = FAR_FileGetSize(hFile);
	void* mem = malloc(size = FAR_FileGetSize(hFile));
	if (!mem) {
		FAR_FileClose(hFile);
		return NULL;
	}
	FAR_FileRead(hFile, mem, size);
	FAR_FileClose(hFile);
	DC_FlushRange(mem, size);
	return mem;
}
Beispiel #17
0
static BOOL NDS_SW_PlayStart(void)
{
	if(VC_PlayStart())
		return 1;
	
	Player_SetPosition(0);
	
	ipc->prevTimer = 0;
	ipc->writeCursor = 0;
	ipc->readCursor = 0;

	int written = VC_WriteBytes(ipc->buffer, ipc->bufferSize);
	unsignedtosigned(ipc->buffer, written);

	DC_FlushRange(ipc, sizeof(*ipc));
	MikMod9_SendCommand(NDS_SW_CMD_START << 28);
	
	return 0;
}
Beispiel #18
0
static SWORD NDS_HW_SampleLoad(struct SAMPLOAD* sload, int type)
{
	ASSERT(sload != NULL);

	SAMPLE *s = sload->sample;
	int handle;

	/* Find empty slot to put sample address in */
	for(handle = 0; handle < NDS_HW_MAXSAMPLES; handle++) {
		if(ipc->samples[handle] == 0) {
			break;
		}
	}

	if(handle == MAXSAMPLEHANDLES) {
		_mm_errno = MMERR_OUT_OF_HANDLES;
		return -1;
	}
	
	/* Reality check for loop settings */
	if (s->loopend > s->length)
		s->loopend = s->length;
	if (s->loopstart >= s->loopend)
		s->flags &= ~SF_LOOP;

	/* TODO difference between 8 and 16 bits? */
	SL_SampleSigned(sload);

	ipc->samples[handle] = _mm_malloc(s->length * ((s->flags & SF_16BITS) ? 2 : 1));
	if(ipc->samples[handle] == NULL) {
		_mm_errno = MMERR_SAMPLE_TOO_BIG;
		return -1;
	}

	/* read sample into buffer */
	if (SL_Load(ipc->samples[handle], sload, s->length))
		return -1;

	DC_FlushRange(ipc->samples[handle], s->length * ((s->flags & SF_16BITS) ? 2 : 1));

	return handle;
}
Beispiel #19
0
//---------------------------------------------------------------------------------
bool sdio_ReadSectors(sec_t sector, sec_t numSectors,void* buffer) {
//---------------------------------------------------------------------------------
	if (!REG_DSIMODE) return false;
	FifoMessage msg;

	DC_FlushRange(buffer,numSectors * 512);

	msg.type = SDMMC_SD_READ_SECTORS;
	msg.sdParams.startsector = sector;
	msg.sdParams.numsectors = numSectors;
	msg.sdParams.buffer = buffer;
	
	fifoSendDatamsg(FIFO_SDMMC, sizeof(msg), (u8*)&msg);

	while(!fifoCheckValue32(FIFO_SDMMC));

	int result = fifoGetValue32(FIFO_SDMMC);
	
	return result == 0;
}
Beispiel #20
0
//---------------------------------------------------------------------------------
void oamInit(OamState *oam, SpriteMapping mapping, bool extPalette) {
//---------------------------------------------------------------------------------
	int i;
	int extPaletteFlag = extPalette ? DISPLAY_SPR_EXT_PALETTE : 0;

	oam->gfxOffsetStep = (mapping & 3) + 5;

	oam->spriteMapping = mapping;

	dmaFillWords(0, oam->oamMemory, sizeof(OamMemory));

	for(i = 0; i < 128; i++) {
		oam->oamMemory[i].isHidden = true;
	}

	for(i = 0; i < 32; i++) {
		oam->oamRotationMemory[i].hdx = (1<<8);
		oam->oamRotationMemory[i].vdy = (1<<8);
	}

	swiWaitForVBlank();

	DC_FlushRange(oam->oamMemory, sizeof(OamMemory));

	if(oam == &oamMain) {
		dmaCopy(oam->oamMemory, OAM, sizeof(OamMemory));

		REG_DISPCNT &= ~DISPLAY_SPRITE_ATTR_MASK;
		REG_DISPCNT |= DISPLAY_SPR_ACTIVE | (mapping & 0xffffff0) | extPaletteFlag;
	} else {
		dmaCopy(oam->oamMemory, OAM_SUB, sizeof(OamMemory));

		REG_DISPCNT_SUB &= ~DISPLAY_SPRITE_ATTR_MASK;
		REG_DISPCNT_SUB |= DISPLAY_SPR_ACTIVE | (mapping & 0xffffff0) | extPaletteFlag;
	}

	oamAllocReset(oam);
}
Beispiel #21
0
static void NDS_SW_Update(void)
{
	DC_InvalidateRange(&ipc->readCursor, sizeof(ipc->readCursor));
	while(ipc->readCursor != ipc->writeCursor)
	{
		int todo = ipc->readCursor - ipc->writeCursor;
		if(todo < 0)
			todo = ipc->bufferSize - ipc->writeCursor;

		int written = VC_WriteBytes(ipc->buffer + ipc->writeCursor, todo);
		unsignedtosigned(ipc->buffer + ipc->writeCursor, written);
		
		int newCursor = ipc->writeCursor + written;
		if(ipc->writeCursor >= ipc->bufferSize)
			newCursor -= ipc->bufferSize;
		ipc->writeCursor = newCursor;
	}
	DC_FlushRange(&ipc->writeCursor, sizeof(ipc->writeCursor));
	
	// we send this afterwards to give arm7 as much time as possible
	// to update
	MikMod9_SendCommand(NDS_SW_CMD_UPDATE << 28);
}
Beispiel #22
0
//---------------------------------------------------------------------------------
static void playSoundBlock(TransferSound *snd) {
//---------------------------------------------------------------------------------
	DC_FlushRange( snd, sizeof(TransferSound) );

	IPC->soundData = snd;
}
Beispiel #23
0
void TextButton::update_vram(const void* source, u16* vram_dest)
{
	DC_FlushRange( source, SPRITE_SIZE_PIXELS(this->sprite_size)*2 );
	dmaCopy( source, vram_dest, SPRITE_SIZE_PIXELS(this->sprite_size)*2 );
	set_16bpp_sprite_opague( vram_dest, SPRITE_SIZE_PIXELS(this->sprite_size)*2 );
}
Beispiel #24
0
//copy our sprite to object attribute memory
void updateOAM(void) {

	DC_FlushRange(sprites,128*sizeof(SpriteEntry));
	dmaCopy(sprites, OAM, 128 * sizeof(SpriteEntry));
}
Beispiel #25
0
void mode__intro__credits___init(void) {

  // initialize main screen
  videoSetMode(MODE_5_2D);

  // map main screen background fourth (128k) region to vram bank A
  vramSetBankA(VRAM_A_MAIN_BG_0x06060000);
  
  // set the secondary/sub screen for text and a background
  videoSetModeSub(MODE_5_2D);

  // map sub screen background (only? 1/4?) to vram bank C
  vramSetBankC(VRAM_C_SUB_BG);

  // FRAK, may need to reimplement this with mcp_bg_init...
  // XXX: time will tell if this flickers
  consoleInit(&bottom_screen, 
	      0, 
	      BgType_Text4bpp, 
	      BgSize_T_256x256, 
	      31, 
	      0, 
	      false,
	      true);

  // set printf sink
  consoleSelect(&bottom_screen);

  // set console background layer to top priority
  bgSetPriority(bottom_screen.bgId, 0);

  // note: this must be done _after_ consoleInit (as that resets it)
  //       and _after_ loading our 8bit indexed bitmap reloads it
  // set to black to allow renderer to really control
  BG_PALETTE_SUB[255] = RGB15(0, 0, 0);

  // unfaded
  mcp_set_blend(MCP_MAIN_SCREEN,
		MCP_MAX_BLEND_LEVEL);
  mcp_set_blend(MCP_SUB_SCREEN,
		MCP_MAX_BLEND_LEVEL);

  // fade the mainscreen background to/from black, layer 3
  REG_BLDCNT = BLEND_FADE_BLACK | BLEND_SRC_BG3;
  // fade the lava background to/from black, layer 3
  REG_BLDCNT_SUB = BLEND_FADE_BLACK | BLEND_SRC_BG3;

  // init subscreen layer/background 3 
  // the mapbase offset of 24 here means 24*16k which means utilizing
  // the 4th of the possible main background memory regions that vram
  // bank A can be mapped to.  I.e. above we mapped to the 4th.  Had
  // we mapped to the 1st, we would have used offset 0.  
  // note: vram bank A is 128k, i.e. 8 * 16k.
  // note: *16k is because of bitmap type, else would be *2k
  //  bg3 = bgInit(3, BgType_Bmp16, BgSize_B16_256x256, 24, 0);
  bg3 = mcp_bg_init(MCP_MAIN_SCREEN,
		    3, 
		    MCP_BG_HIDE,
		    BgType_Bmp16, 
		    BgSize_B16_256x256, 
		    24, 
		    0);

  // its initial priority, lowest (to emphasize lack of other enabled layers)
  // priorities 0..3, 0 highest priority
  bgSetPriority(bg3, 3);

  //  bgHide(bg3);

  // load main splash screen into screen/background memory (bgs3)
  // note: if I wanted to do this quickly/perfectly/doublebufferred somehow
  //       I'm not sure if I'd need to tweak the bgInitSub offset or pointer
  //       here or some such.  As it is, the fade to black ensures no tear
  //       as this new image gets loaded into display memory.
  decompress(guitar_zyx_splash_creditsBitmap, 
	     (u16*)bgGetGfxPtr(bg3),  
	     LZ77Vram);
  
  bgShow(bg3);

  // note: using offset=4, because 4 will be 64k offset, where 31 above is 62k
  // (thus above using only 2k? seems plausible with tiles for console text chars
  // NOTE: if this flickers, could try 2 instead of 3
  bgs3 = mcp_bg_init(MCP_SUB_SCREEN,
		     3,
		     MCP_BG_HIDE,
		     BgType_Bmp8, 
		     BgSize_B8_256x256, 
		     4, 
		     0);
  // its initial priority, lowest (to emphasize lack of other enabled layers)
  // priorities 0..3, 0 highest priority
  bgSetPriority(bgs3, 2);

  //  bgHide(bgs3);

  // as per libnds doc on dma
  DC_FlushRange(dlavaBitmap, 256*256);
  dmaCopy(dlavaBitmap, bgGetGfxPtr(bgs3), 256*256);
  DC_FlushRange(dlavaPal, 256*2);
  dmaCopy(dlavaPal, BG_PALETTE_SUB, 256*2);
  
  bgShow(bgs3);

  BG_PALETTE_SUB[255] = RGB15(0, 0, 0);
}
Beispiel #26
0
void updateOAM(void)
{
	DC_FlushRange(d3dSprites, 128 * sizeof(SpriteEntry));
	memcpy(OAM_SUB, d3dSprites, 128 * sizeof(SpriteEntry));
}
Beispiel #27
0
void mode__intro__main___init(void) {

  // ooh, ahh, earcandy
  mmEffectEx(&sounds[SFX_STARTUP]);

  // initialize main screen 
  // edunote: had tried MODE_5_3D here, but after 3D was actually used,
  //          it would interfere with the bitmap showing.  I think I'm
  //          effectively bghiding all layers in intermode init, but
  //          maybe I'm not, or maybe there is another way to hide the 3D
  //          layer.  Probably I should figure out how to render 3D on 
  //          top of a bitmap successfully.  Then the rest might follow.
  videoSetMode(MODE_5_2D);

  // map main screen background fourth (128k) region to vram bank A
  vramSetBankA(VRAM_A_MAIN_BG_0x06060000);
  
  // NOTE: current half educated assumption is that or-ing together
  //       bg enabled layers here is nothing but effectively an
  //       advanced call to bgShow, which is also a part of bgInit
  // NOTE2: after some time, I'm convinced of the above, and about
  //        to write a function bg_init_hidden()
  videoSetModeSub(MODE_5_2D);

  // map sub screen background (only? 1/4?) to vram bank C
  vramSetBankC(VRAM_C_SUB_BG);

  mcp_console_init(&bottom_screen, 
		   MCP_SUB_SCREEN,
		   0, 
		   1,
		   1,
		   BgType_Text4bpp, 
		   BgSize_T_256x256, 
		   31, 
		   0);

  // set printf sink
  consoleSelect(&bottom_screen);

  // set console background layer to top priority
  bgSetPriority(bottom_screen.bgId, 0);

  // note: this must be done _after_ consoleInit (as that resets it)
  //       and _after_ loading our 8bit indexed bitmap reloads it
  // set to black to allow renderer to really control
  BG_PALETTE_SUB[255] = RGB15(0, 0, 0);

  // show the console layer
  mcp_bg_show(MCP_SUB_SCREEN, 0);

  // default to fully faded (to black)
  mcp_set_blend(MCP_MAIN_SCREEN, 
		MCP_MAX_BLEND_LEVEL);
  mcp_set_blend(MCP_SUB_SCREEN, 
		MCP_MAX_BLEND_LEVEL);

  // fade the mainscreen background to/from black, layer 3
  REG_BLDCNT = BLEND_FADE_BLACK | BLEND_SRC_BG3;
  // fade the lava background to/from black, layer 3
  REG_BLDCNT_SUB = BLEND_FADE_BLACK | BLEND_SRC_BG2;

  // init subscreen layer/background 3 
  // the mapbase offset of 24 here means 24*16k which means utilizing
  // the 4th of the possible main background memory regions that vram
  // bank A can be mapped to.  I.e. above we mapped to the 4th.  Had
  // we mapped to the 1st, we would have used offset 0.  
  // note: vram bank A is 128k, i.e. 8 * 16k.
  // note: *16k is because of bitmap type, else would be *2k
  //  bg3 = bgInit(3, BgType_Bmp16, BgSize_B16_256x256, 24, 0);
  bg3 = mcp_bg_init(MCP_MAIN_SCREEN,
		    3, 
		    MCP_BG_HIDE,
		    BgType_Bmp16, 
		    BgSize_B16_256x256, 
		    24, 
		    0);
  // its initial priority, lowest (to emphasize lack of other enabled layers)
  // note: priorities 0..3, 0 highest priority
  bgSetPriority(bg3, 3);

  // mcp_bg_init covers this
  // maybe this prevents flicker during decompress
  //  bgHide(bg3);

  // load main splash screen into screen/background memory (bgs3)
  decompress(guitar_zyx_splash_mainBitmap, 
	     (u16*)bgGetGfxPtr(bg3),  
	     LZ77Vram);
  // maybe this prevents flicker during decompress
  mcp_bg_show(MCP_MAIN_SCREEN, 3);

  // note: using offset=4, because 4 will be 64k offset, where 31 above is 62k
  // (thus above using only 2k? seems plausible with tiles for console text chars
  //  bgs2 = bgInitSub(2, BgType_Bmp8, BgSize_B8_256x256, 4, 0);
  bgs2 = mcp_bg_init(MCP_SUB_SCREEN,
		     2,
		     MCP_BG_HIDE,
		     BgType_Bmp8, 
		     BgSize_B8_256x256, 
		     4, 
		     0);
  // its initial priority, lowest (to emphasize lack of other enabled layers)
  // priorities 0..3, 0 highest priority
  bgSetPriority(bgs2, 2);

  // mcp_bg_init covers this
  //  bgHide(bgs2);

  // note: as per libnds doc on dma, do the flush first
  DC_FlushRange(dlavaBitmap, 256*256);
  dmaCopy(dlavaBitmap, bgGetGfxPtr(bgs2), 256*256);
  DC_FlushRange(dlavaPal, 256*2);
  dmaCopy(dlavaPal, BG_PALETTE_SUB, 256*2);
  
  bgShow(bgs2);

  // reinitialize the text color
  BG_PALETTE_SUB[255] = RGB15(0, 0, 0);

  /* bad experiment, but probably will use later anyway)
  consoleInit(&bottom_screen_x, 
	      3, 
	      BgType_ExRotation,
	      BgSize_ER_256x256,
	      31, 
	      1, 
	      false,
	      false);

  // custom 8bpp font
  mcpfont.asciiOffset = 32;
  mcpfont.bpp = 8;
  mcpfont.convertSingleColor = false;
  mcpfont.gfx = (u16*)mcpfontTiles;
  mcpfont.numChars = 95;
  mcpfont.numColors =  mcpfontPalLen / 2;
  mcpfont.pal = (u16*)mcpfontPal;
  consoleSetFont(&bottom_screen, &mcpfont);

  // set console background layer to top priority
  bgSetPriority(bottom_screen_x.bgId, 0);
  bgShow(bottom_screen_x.bgId);
  */


}