Drunken Coders

Breaking new ground in console homebrew development

Background control is provided via an API or Direct register access. Usually these methods can be mixed. However, scrolling, scaling, and rotation will have unexpected results if API and Direct Register access is mixed. Effort is being directed at ensuring the API can access all hardware features without limitation.

The DS contains two separate hardware 2D cores responsible for rendering 2D backgrounds. The definitions below outline the libnds api for utilizing these backgrounds.
The background engine provides basic initialization and management of the 8 2D backgrounds available on the DS. Other than initialization and hardware limitations background control is identical on both main and sub screens.

The following modes of operation are allowed:

Main 2D engine
______________________________
|Mode | BG0 | BG1 | BG2 |BG3 | T = Text
| 0 | T | T | T | T | R = Rotation
| 1 | T | T | T | R | E = Extended Rotation
| 2 | T | T | R | R | L = Large Bitmap background
| 3 | T | T | T | E |
| 4 | T | T | R | E |
| 5 | T | T | E | E |
| 6 | | L | | |
—————————–
Sub 2D engine
______________________________
|Mode | BG0 | BG1 | BG2 |BG3 |
| 0 | T | T | T | T |
| 1 | T | T | T | R |
| 2 | T | T | R | R |
| 3 | T | T | T | E |
| 4 | T | T | R | E |
| 5 | T | T | E | E |
—————————–
On the main engine BG0 can be used as a 3D rendering surface.

Posted by dovoto

Smealum has finally released his work in progress. A very functional, playable, and editable Portal clone. Watch the video and try out the rom!

scr1

Posted by dovoto

Here is a neat little project (with schematics and source code) to interface a GBA to a pic microcontroller and use it for a data acquisition system. GBA_meter

Its pretty cool and uses the Multiboot protocol so you can probably build the whole thing for a couple of dollars.

A link to the project!

Posted by dovoto

After a very long pause Martin has released an update to his powerful emulator NO$GBA. For a long time we wondered if he was subject to some foulplay but it turns out he is still alive and kicking. The paypal links seem to be working for the $15 homebrew debug version which, in the past, has been money very well spent.

In its day, NO$ was easily the most accurate DS emulator out there and I would say still gives the others a tight run for their money….not to mention its coded in that OCD fashion we all love allowing it to zip along on even modest hardware.

Here is a long list of changes: Changes

And a link to the homebrew debugger page: http://nocash.emubase.de/gba-dev.htm

Posted by dovoto

Been working on a back end to host coding competitions and could use some help testing it out. Come check out our first compo:

Pong

Current Entries

Posted by dovoto

Hello!

I’ve been messing around with electronics lately (after all, that’s what I’m studying :P), and this is the result! A 32×8 LED Matrix controlled by a PIC18F2550. You can click in the pictures for full size! At the end of the post there is a video of the screen running.

Everything together

(more…)

Posted by AntonioND

This wont help but if you find it fun to watch then you are probably on the right website!

Posted by dovoto

Finally, a bitcoin mining with a purpose!

Although a touch convoluted by using a Raspberry Pi to fetch bits of work and a webcam to read the result from the NES in the form of a screen color change its still pretty slick.

RetroMiner

Posted by dovoto

This may be one of the more ridiculous things I have ever seen…an 8 bit serial computer built ENTIRELY of NAND gates and wire routing…

Crazy attention to detail. If you don’t follow kevtris you should.

What is a NAND computer? Well a quick refresher on digital logic:

There are a few fundamental building blocks to constructing a digital circuit. These are gates, which perform the basic boolean logic operations (OR, AND, NOR, NAND, XOR, NOT) and latches/flipflops which preserve the value of a bit. It turns out that you can build any gate from a NAND gate and so can build flip flops and latches from NAND gates as well. (for more info see: http://en.wikipedia.org/wiki/NAND_logic )

The picture you see below is a whole bunch of NAND gates in discreet logic chips which are wired together to form an entire CPU. The better you understand it the more you will realize how ridiculous it is that someone thought to do it and furthermore how crazy they must have been to actually finish it.

http://blog.kevtris.org/

Posted by dovoto

Now this is just pretty slick. It seems these guys decap and photo old chips, then trace them out using some custom tools and convert the images to netlists for use in a javascript simulator. The result? A gate level simulation of the entire NES PPU you can interact with on a web page (at about 2Hz mind you) including the ability to trace signals and nodes. Its pretty crazy and worth checking out.

http://www.qmtpro.com/~nes/chipimages/visual2c02/

http://www.visual6502.org/faq.html

Posted by dovoto

sverx has posted some memory benchmarks in an attempt to answer that ever annoying question of which memory copy method is fastest on the DS.

Some of the more interesting results:

  • copying using DMA is both the slowest option (when copying to main RAM) and the fastest one (when copying to video RAM)
  • memcpy() gets overtaken by almost every other method, so I guess one should use it only when prototyping or when performance is not an issue
  • reading from an uncached address seems to give some % of boost when using ldmia/stmia; it just makes things worse when using memcpy()
  • Loop unrolling doesn’t give any advantage when copying to main RAM; on the contrary, it effectively speeds up a bit when copying to video RAM
  • reading from a cache unaligned source address can slow down things a bit, especially when reading from a cached address
  • using a DTCM temporary copy doesn’t help

Read the full post here: A DS Homebrewer’s Diary

Posted by dovoto

If you have ever been interested in Nintendo Entertainment System, Apple II, or Atari programming you have probably ran into the 6502 processor. Here is a great site introducing assembly on the somewhat dated CPU complete with an interactive assembly language interpreter. I think its pretty awesome.

http://skilldrick.github.com/easy6502/

Posted by dovoto

Smealum has released a new teaser for his upcoming Portal recreation on the DS. Its looking pretty impressive and worth checking out.

Posted by dovoto

For those of you doing some mobile cross platform dev, MonoGame 3.0 was just moments ago released. Some features:

What’s New?

3D (many thanks to Infinite Flight Studios for the code and Sickhead Games in taking the time to merge the code in)
New platforms: Windows 8, Windows Phone 8, OUYA, PlayStation Mobile (including Vita).
Custom Effects.
PVRTC support for iOS.
iOS supports compressed Songs.
Skinned Meshs
VS2012 templates.
New Windows Installer
New MonoDevelop Package/AddIn
A LOT of bug fixes
Closer XNA 4 compatibility

Check it out: MonoGame.net

Posted by dovoto

I made a bit of a change to the site to suppress some of the more annoying spam…but really…not sure who comes here anymore. If anyone is interested in helping out (or taking over) the admin for the site drop me a pm (email: jason @ this domain).

Posted by dovoto

For the battle scene, I have created 2 characters from Saint Seiya Anime : Pegasus seiya and Lion Aiolia.
I used GIMP to create the sprites, using gameboy advance characters as base and overwriting them.

Here are the sprites : 2 96×96 pixels lion and 3 96×96 pixels seiya. Knowing that DS will take 32×32 sprites, they have been split in 9 to fit the DS needs.

Background is coming directly from sega Megadrive’s Shining Force :

After that, some programings and here we go in the DS. 
You can download and rename the following file with .nds instead of .jpg and launch it on emulator or DS :

 http://ndssstactics.drunkencoders.com/files/2012/12/DS_SaintSeiya_092012.jpg

Posted by GuiguiPanda

I have been playing around with windows metro dev and since I have been a big fan of C# for quite a few years I thought it might be fun to put together a quick C# game for the app store….but it seems C# has been left out of the Direct X loop by MS this time around.

I found that rather dissapointing and went in search of options.

What I found was SharpDX and monogame.

Interestingly, these are rather easily cross platform. I did a windows, xbox, and android build with a hanfull of #ifdefs sprinkled about.

The result is my work in progress:

Feel free to post XNA or metro topics to the Questions thread.

Posted by dovoto

Here is a simple way using 16 random tiles and a random palette:

/*---------------------------------------------------------------------------------

	Faking static

---------------------------------------------------------------------------------*/
#include <nds.h>
//---------------------------------------------------------------------------------
int main(void) {
//---------------------------------------------------------------------------------
	int tileCount = 16;

	videoSetMode(MODE_0_2D);

	int bg = bgInit(0, BgType_Text8bpp, BgSize_B16_256x256, 0, 1);

	u16* tiles = bgGetGfxPtr(bg);
	u16* map = bgGetMapPtr(bg);

	//create 16 tiles filled with random colors
	for(int i = 0; i < tileCount * 32; i++)
		tiles[i] = rand();

	//create a map filled with those random tiles
	for(int i = 0; i < 32 * 32; i++)
		map[i] = rand() % tileCount;

	while(1) 
	{
		//create a random palette every frame
		for(int i = 0; i < 256; i++)
		{
			//a grey scaled palette...could have used colors but this looks better
			int shade = rand() % 32;
			BG_PALETTE[i] = RGB15(shade, shade, shade);
		}
		swiWaitForVBlank();
	}

}

Here is a slightly more complex way using a single 16 color tile and some hblank tricks:

/*---------------------------------------------------------------------------------

	Faking static

---------------------------------------------------------------------------------*/
#include 

void hblank(void)
{
	REG_BG0HOFS = rand() & 0xFF;
	REG_BG0VOFS = rand() & 0xFF;
}
//---------------------------------------------------------------------------------
int main(void) {
//---------------------------------------------------------------------------------
	videoSetMode(MODE_0_2D);

	int bg = bgInit(0, BgType_Text4bpp, BgSize_T_256x256, 0, 1);

	u16* tiles = bgGetGfxPtr(bg);
	u16* map = bgGetMapPtr(bg);

	irqEnable(IRQ_HBLANK);
	irqSet(IRQ_HBLANK, hblank);

	//create 1 tile filled with random colors
	for(int i = 0; i < 16; i++)
		tiles[i] = rand();

	//create a map filled with those random tiles (only bits we are setting are the 4 bits for palette and the two for h and v flip)
	for(int i = 0; i < 32 * 32; i++)
	{
		map[i] = rand() & (0x3F << 10);
	}
	while(1) 
	{
		//create a random palette every frame
		for(int i = 0; i < 256; i++)
		{
			//a grey scaled palette...could have used colors but this looks better
			int shade = rand() % 32;
			BG_PALETTE[i] = RGB15(shade, shade, shade);
		}
		swiWaitForVBlank();
	}

}
Posted by dovoto

Using the new windowing API to enable and display a window

First, as always, lets look at the full source for the demo. Notice that it sets up and displays our traditional drunkencoders logo, enables the window and finally lets us mess with its settings.

The DS has 3 hardware windows which can be used to mask parts of the screen. Two of them are simple rectangles, you give the DS the top, bottom, right, and left of the square and it creates a mask of that size. We can control what layers are rendered inside the window and which ones are rendered outside the window.

The other window is an Object Window and it uses a sprite object as the mask (basically any pixel in the sprite that is not zero becomes “in window”).

All that is required to use a window is first to turn it on, second to define if you want your layers or objects to appear inside the window or outside all windows, and finally define the top, left, bottom, and right positions of the window..

This brings us to our first bit of code to enable a window and set how that window effects our background.

If we did not set our background window options the background would neither show up inside nor outside the window and therefor would not be displayed. It is perfectly acceptable to have the bg show up inside multiple windows or outside all windows or both (just OR the window options together which you pass to bgWindowEnable).

We next set the starting x, y, and size of our window box:

Next is our main loop:

Inside this loop we alter the x and y with key presses so the window moves about, we adjust the size as well so we can shrink of grow it.

We also add a little feature that allows us to alter the window by pressing X and Y keys. Pressing Y tells the DS to display the part of the background that is outside all windows, pressing Y causes it to display only inside window 0. If you were to not call bgWindowDisable to turn off the unwanted option the background would simply end up being displayed both inside window 0 and outside all windows.

Finally, we set the bounds on our window based upon the settings we had altered above:

Posted by dovoto

What follows is a very detailed look at the sprite hardware on the DS including memory and register layout and a listing of basic libnds functions dealing with sprites. This post is a bit technical and does not need to be understood before moving on to the sprite examples (in fact, an argument can be made that it is best to skip all but the overview until you have gotten a sprite or two to display).

Overview

Keep in mind the DS has two distinct 2D graphics cores which each handle one screen. The main engine and the sub engine have few differences. We will focus on the main engine in this discussion and point out any differences we encounter along the way. Recall, that the engines do not imply a specific physical screen as either engine can be used to control either the top or bottom screen.

To begin, each core is capable of controlling 128 independent sprite objects which share a common graphics and palette memory.

Each object can have a rotation, blend, or mosaic applied (although not strictly independently as we shall see).

Each sprite can be one of 3 color formats: 256-color paletted, 16-color paletted, or 16-bit direct color bitmap.

Each sprite can be one of the following pixel sizes:

SizeSquareWideTall
08×816×88×16
116×1632×88×32
264×6464×3232×64

Sprites can contain transparent pixels allowing sprites of any size or shape to be represented as long as they can fit inside one of the above boxes. If you need even larger sprites we will learn a few tricks to stretch them and combine them to create sprites of any size.

Memory Layout

Main Engine:
OAM Attributes (1KB): 0x07000000
Palette Memory (1KB): 0x05000200
Graphics Memory (256KB): 0x6400000
Extended Palette Memory: (Memory mapped so varies)

Sub Display
OAM Attributes (1KB): 0x07000400
Palette Memory (1KB): 0x05000400
Graphics Memory (128KB): 0x6600000
Extended Palette Memory: (Memory mapped so varies)

Object Attribute Memory:
Each core has what is known as Object Attribute Memory which contains the state for our 128 sprites. This state is stored in a set of 3 16-bit attributes (one set for each sprite) which control nearly every aspect of the sprite.

Attribute 0:

BitsDescription
0-7The Y coordinate of the top of the sprite
8The rotation scaling flag which determines if a scale/rotation is to be applied. The setting of this flag controls how several of the bits below are interpreted.
9Size double / hide sprite flag: When the rotation and scaling flag is set this flag will allow the sprite to double in size when a scaling or rotation is applied. When the rotation scaling flag is not set this bit will hide the sprite if set (very useful).
10-11Display mode: 0 is a normal paletted sprite, 1 is a blended sprite, 2 means the sprite is acting as an window mask, and 3 is used to specify a bitmap sprite.
12Mosaic flag: when set the mosaic will be applied
13Color depth: 0 = 16 color 1 = 256 color
14-15Object shape: 0 = Square, 1= Wide, 2 = Tall

Attribute 1:

BitsDescription
0-8The X coordinate of the top of the sprite (one more bit than Y as the screen is wider)
9-13Bits 9-13 are used to store the 5 bit index into the 32 possible rotation/scaling attributes to apply to the sprite. When the rotation and scaling flag is not set bits 9-11 are unused and bits 12 and 13 can be used to flip the sprite.
12When the rotation and scalling flag is NOT set this bit sets the horizontal flip flag, when set the sprite will be flipped horizontally. When the rotation scaling flag is set this bit is used as part of the rotation attribute selection
13When the rotation and scalling flag is NOT set this bit sets the vertical flip flag, when set the sprite will be flipped vertically. When the rotation scaling flag is set this bit is used as part of the rotation attribute selection
14-15Selects the object size (see table above)

Attribute 2:

BitsDescription
0-9Selects the offset of the start of the sprites graphics
10-11The sprite priority (what order it is drawn with respect to other sprites and backgrounds, two sprites with the same priority will be drawn in order of OAM number)
12-15Palette number when in 16-color mode or when using extended palettes in 256-color mode. These bits control the alpha blend when in bitmap mode.

Rotation and Scaling Attributes:
Following each set of 3 OAM attributes is a single 16-bit rotation and scale attribute. These 16-bit values are what is used to control the rotation and scale of a sprite. It actually takes 4 rotation attributes to describe the rotation and scale which means there are only 32 available rotations which can be applied (128 sets of oam attributes, 4 sets per set of rotation attributes, 128/4 = 32).

The layout in memory is as follows:

AddressDescription
Sprite 00x07000000Attribute 0
0x07000002Attribute 1
0x07000004Attribute 2
0x07000006Rotation 0 PA
Sprite 10x07000008Attribute 0
0x0700000AAttribute 1
0x0700000CAttribute 2
0x0700000ERotation 0 PB
Sprite 20x07000010Attribute 0
0x07000012Attribute 1
0x07000014Attribute 2
0x07000016Rotation 0 PC
Sprite 30x07000018Attribute 0
0x0700001AAttribute 1
0x0700001CAttribute 2
0x0700001ERotation 0 PD
Sprite 1260x070003F0Attribute 0
0x070003F2Attribute 1
0x070003F4Attribute 2
0x070003F6Rotation 31 PC
Sprite 1270x070003F8Attribute 0
0x070003FAAttribute 1
0x070003FCAttribute 2
0x070003FERotation 31 PD

As you may notice, each rotation attribute contains 4 values named PA, PB, PC, PD which form an affine matrix. For a complete and rather detailed description of this matrix please read the link above. Don’t pay much attention to any code presented in it, we are not going to use it as we have our own code for such things (although its perfectly fine for consumption of you so chose).

Paletted Sprites:
By selecting the appropriate bits in the attributes described above you can select either 16 color or 256 color palettes. A 16 color sprite uses half the graphics memory of a 256 color sprite which uses half the memory of a direct color bitmap sprite. By trading the number of colors for memory consumption we can make some smart decisions about the usage of DS graphics resources.

As we alluded to above, the sprite palettes are shared and we can control per sprite what color format it is in (sort of).

To display a sprite we simply load some colors into our palette then load the bitmap into sprite memory…unfortunately there is one small item left to discus and that is how the pixel data is actually stored.

Sprite pixel graphics, much like background graphics are constructed of tiles. What that means is that if you have a 16×16 sprite it is actually stored internally as 4 8×8 tiles. To translate your sprite from your graphics program to something the DS can understand we will need a tool. That tool is grit.

The tiles themselves can be stored in memory either linearly for each sprite (known as 1D mapping) or they can be stored in a 2D grid of 32×32 tiles in 16-color mode or 16×32 tiles in 256-color mode (2D mapping). There are few uses for 2D mapping and it makes it rather challenging to organize your graphics so we are pretty much going to let it go at that and stick to 1D mapping.

The offset from attribute 2 is used to specify where in memory the first tile of the sprite graphics reside. How we calculate that depends on another setting in the main video display control register. This setting determines the stride between starting tiles for sprites and can be 32 bytes, 64, 128 or 256. This setting allows you to reach all of sprite graphics memory by a single 9 bit offset stored in attribute 2. Location will be: Start of graphics memory + offset * stride.

Extended Palettes
You can enable extended palette memory for both backgrounds and sprites globally (for each engine). Once this is done you will have access to 16 256-color palettes for your sprite. Normal sprite palette memory will be ignored in this case. Extended palettes take a bit more work to set up and manipulate but it is enough for now to know we have to allocate a VRAM bank to them and we can only load palette data into that bank when it is unmapped.

Bitmap Sprites:
The DS also allows for direct color bitmap sprites. These are very useful not only because they allow the full range of color in your sprite but also because they allow you to specify an alpha blend value in the unused bits that normally specify the palette index to use. In this mode each pixel is a 15 bit color value with the most significant bit an alpha flag. This alpha flag is how you specify a transparent pixel (0 means transparent, 1 means draw it).

There is no palette so the only issue is how to store the sprite graphics data in memory. In bitmap mode sprite graphics are not tiled but stored as a linear bitmap. When in 1D mapping mode each sprite graphic is stored sequentially and the offset is simply offset * stride (where stride is 128 or 256).

In 2D mode the sprite graphics memory is treated as a single large bitmap that is 128 or 256 pixels wide. The offset gets split into a 5 bit X and a 4 bit Y value (or 4 bit X and 5 bit Y depending on the chosen stride). You specify the x and y of the top left corner of your sprite in the large bitmap (divided by 16).

That is it for our sprite technical overview. For a more in-depth look at these features be sure to check out the examples.

Posted by dovoto
Featured Video