gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

DS development > How can I load Sprites from SD?

#104850 - jandujar - Tue Oct 03, 2006 8:09 am

I want to make a program that uses sprites, but I want that this sprites must be loaded from a SD with old chrism FAT library.

I thing I must use 16bit sprites (because I don't know the palette of the SD sprites)

But I don't know how to load/show 16bit sprites in mode 5.

Could somebody help me?

I make this and the sprite is show:

Code:

//Preparo el espacio en memoria de los sprites.
   //sprite attribute memory
   SpriteEntry * spritesMain = new SpriteEntry[128];
   //rotation attributes overlap so assign then to the same location
   SpriteRotation * spriteRotationsMain = (SpriteRotation *)spritesMain;
      
   initOAM(spritesMain, spriteRotationsMain);
   updateOAM(spritesMain);
      
   
    spritesMain[0].attribute[0] = ATTR0_BMP | ATTR0_ROTSCALE_DOUBLE | 0;
   spritesMain[0].attribute[1] = ATTR1_SIZE_64 | 0;
   spritesMain[0].attribute[2] = ATTR2_ALPHA(1)| 0;

   // red 64*64 square for 1d bitmap mode
   for(int i=0;i<64*64*2;i++)
      SPRITE_GFX[i]=RGB15(31,0,0)|(1<<15); //dont forget alpha bit
      
   updateOAM(spritesMain);
   while(1){
   swiWaitForVBlank();
   }


Is this correct? If I put for(int i=0;i<64*64;i++) instead of for(int i=0;i<64*64*2;i++) I only see the half of the cube.

-How can I load a jpeg to this gfx? using libjpeg from libnds.

*What is the sprite limit using 64x64 16bit sprites?
I think sprite space is 256KB = 256 * 1024 bytes = 262144 bytes

And I 64x64 16bit sprite uses 64*64*2 = 8192 bytes

Could I use up to 262144/8192 = 32 64x64 sprites ?
_________________
http://jandujar.homelinux.com
http://www.dsrobot.com

#104858 - PypeBros - Tue Oct 03, 2006 12:32 pm

wow, that makes plenty of "how do i ..." in a row.

1. you can indeed use chishm's FAT library to load content from a file (say, stuff.spr) into some memory region (just using FAT_read, FAT_open, etc, which basically behave almost like standard fopen/fread/etc.), and that indeed includes loading tiles data straight into VRAM. E.g. in my sprite editor, i have
Code:

bool SpriteSet::Load(char *filename) {
   if (!checkFileLibrary()) return false;
   FAT_FILE* file=FAT_fopen(filename,"rb");
   struct SprFileCmap pal_hdr={};
   struct SprFileTile tile_hdr={};
   struct SprFileUnknown hdr={};
   
   iprintf("reading '%s' ...\n",filename);
   while (!pal_hdr.magic || !tile_hdr.magic) {
     if (FAT_feof(file) || FAT_fread(&hdr, sizeof(hdr),1,file)!=sizeof(hdr)) {
       FAT_fclose(file);
       iprintf("unexpected EOF\n");
       return false;
     }
     iprintf("section '%c%c%c%c' ...", hdr.magic&255,
        (hdr.magic>>8)&255,(hdr.magic>>16)&255,(hdr.magic>>24)&255);
     switch(hdr.magic) {
     case SPR_FILE_CMAP_MAGIC:
       pal_hdr.magic=hdr.magic;
       if (FAT_fread(&(pal_hdr.ncols),sizeof(u32),1,file)==sizeof(u32)) {
    uint nb=FAT_fread(palette_target,sizeof(u16),pal_hdr.ncols,file);
    iprintf("%i/%i colors loaded\n",nb/sizeof(u16),pal_hdr.ncols);
       }
       break;
     case SPR_FILE_TILE_MAGIC:
         tile_hdr.magic=hdr.magic;
         if (FAT_fread(&(tile_hdr.ntiles),sizeof(u32),1,file)==sizeof(u32) &&
             FAT_fread(tiles_target,64,tile_hdr.ntiles,file)==64*tile_hdr.ntiles)
            iprintf("%i tiles loaded\n",tile_hdr.ntiles);
    nbtiles=tile_hdr.ntiles;
         break;
      default:
   iprintf("unknown. skipping %u bytes\n",hdr.skipsize);
   FAT_fseek(file, hdr.skipsize, SEEK_CUR);
         break;
      }
   }
   FAT_fclose(file);
   return true;
}

where palette_target and tiles_target were initialized with (SPRITE_GFX_SUB,SPRITE_PALETTE_SUB) respectively.

2. if you're using some mode initialization of your own, make sure you defined things like DISPLAY_SPR_1D, DISPLAY_SPR_1D_BMP and DISPLAY_SPR_1D_BMP_SIZE_128. The actual values might depend on your setup, but what it all means is that depending on those values, the DS hardware will pick different tiles number to form the "next row".

3. once you've mastered VRAM filling and the FAT library, you're quite free to use any library available to decode any format you read from SD into RAM. That includes JPEG too even if that'd be the last thing I would consider (rather picking PNG)
_________________
SEDS: Sprite Edition on DS :: modplayer

#104859 - chishm - Tue Oct 03, 2006 12:40 pm

PypeBros wrote:
you can indeed use chishm's FAT library to load content from a file (say, stuff.spr) into some memory region (just using FAT_read, FAT_open, etc, which basically behave almost like standard fopen/fread/etc.), and that indeed includes loading tiles data straight into VRAM.

That's true, with many conditions. It's a lot like memcpy (in fact, it uses memcpy for some cases) in that it will into memory 2 or 4 bytes at a time when certain conditions are met. Unfortunately, it is not possible to be certain that it will all occur correctly, so you are better off reading into another section of RAM then copy it across.
_________________
http://chishm.drunkencoders.com
http://dldi.drunkencoders.com

#104964 - Mollusk - Wed Oct 04, 2006 7:41 pm

i would go with using gif files, as they're already paletted, and using 256 color sprites that way
_________________
PAlib official forum : http://www.palib.info
PAlib official tutorials: http://www.palib.info/wiki
Updates, help, code examples, tutorials, etc...

#104968 - HyperHacker - Wed Oct 04, 2006 7:56 pm

Isn't GIF copyrighted or something? Anyway PNG is essentially just GIF but better, except without animations. (An animated MNG format exists but few people use it.)
_________________
I'm a PSP hacker now, but I still <3 DS.

#104975 - josath - Wed Oct 04, 2006 9:33 pm

yes, 256 color png is better than 256 color gif.
But either way, using a compressed image format, with anything more complex than RLE, will complicate the loading. For simple sprites, which are generally pretty small anyway, the easiest is to just use PCX files. They contain RLE compression, and libnds has a very basic PCX decompression function.

#105038 - jandujar - Thu Oct 05, 2006 12:26 pm

first of all, thank's to all the people who answer me.

I have made a program that load a jpg icon (two sprites with same gfx) and show this icon on the sub screen. (the jpg icon is bin2o). I not use any palette for the sprites.

But I'm getting something strange, the icon seems to have been scaled 50% height.
What I'm doing wrong?

Code:

#include <nds.h>
#include <stdlib.h>  //malloc
#include <stdio.h> //iprintf
#include "Sprites.h"
#include "Video.h"
#include "arriba_bin.h"
#include "IconoMac.h"
#include "gba-jpeg.h"
#include "gba-jpeg-decode.h"
#include "lupa_jpg.h"



int main(int a, char **b){
   //////////////////////////// INIT ////////////////////////////////////////
   //turn on the 2D core
    powerON(POWER_ALL_2D);
   
    //set up a VBlank handler
   irqInit();
   irqSet(IRQ_VBLANK, 0);
   
    initVideo();
   initBackgrounds();
   initConsole();
   
   //Cargo los backgrounds
   copyBackground(arriba_bin, arriba_bin_size);
   copyBackgroundSub(arriba_bin, arriba_bin_size);
   
   //Preparo el espacio en memoria de los sprites.
   //sprite attribute memory
   SpriteEntry * spritesMain = new SpriteEntry[128];
   //rotation attributes overlap so assign then to the same location
   SpriteRotation * spriteRotationsMain = (SpriteRotation *)spritesMain;
      
   initOAM(spritesMain, spriteRotationsMain);
   updateOAM(spritesMain);
      
   
    spritesMain[0].attribute[0] = ATTR0_BMP | ATTR0_ROTSCALE_DOUBLE | 0; //Y
   spritesMain[0].attribute[1] = ATTR1_SIZE_64 | 64;
   spritesMain[0].attribute[2] = ATTR2_ALPHA(1)| 0;

   spritesMain[1].attribute[0] = ATTR0_BMP | ATTR0_ROTSCALE_DOUBLE |0;
   spritesMain[1].attribute[1] = ATTR1_SIZE_64 | 0;
   spritesMain[1].attribute[2] = ATTR2_ALPHA(1)| 0;

   //Cargo la lupa
   u16* imagen;
   imagen=(u16*)malloc(64*64*2);
   
   REG_IME = 0x00;
   JPEG_DecompressImage(lupa_jpg, imagen, 64, 64);
   REG_IME = 0x01;
   
   spriteRotationsMain[0].hdx=256;
   spriteRotationsMain[0].hdy=0;
   spriteRotationsMain[0].vdx=0;
   spriteRotationsMain[0].vdy=256;
 

   // red 64*64 square for 1d bitmap mode  copio el primer icono
   int i;
   iprintf("paso%d",imagen[0]);
   for(i=0;i<64*64*2;i++){
      SPRITE_GFX[i]=imagen[i]; //dont forget alpha bit   
   }
   int suma=64*64*2;
   //copio el segundo
   for(i=0;i<64*64*2;i++){
      SPRITE_GFX[suma+i]=imagen[i]; //dont forget alpha bit      
   }
   
   iprintf("paso%d",imagen[0]);   
   updateOAM(spritesMain);
   while(1){
   swiWaitForVBlank();
   }
   
   
   //displaySplash();
   
      
   return 0;   
}


How can I draw a jpg image with a color like a alpha bit? (transparent)
SPRITE_GFX[suma+i]=0; ? <- will be transparent?

[Images not permitted - Click here to view it]
_________________
http://jandujar.homelinux.com
http://www.dsrobot.com

#105043 - PypeBros - Thu Oct 05, 2006 1:08 pm

Whatever color you use with an alpha bit cleared will not show up. Note that it's truly a bit: either you see the pixel, or you don't. If you want "translucent" sprite (e.g. seeing through your magnifying glass, but still with a pale blue tint), what you need is alpha-blending (which applies uniformly to all pixels of the sprite).

About the sprite being "squeezed" vertically to 1/2 of his height, are you using 1D or 2D bmp mode (see tonc tutorial if the question seems meaningless to you)
_________________
SEDS: Sprite Edition on DS :: modplayer

#105050 - jandujar - Thu Oct 05, 2006 1:59 pm

Quote:
About the sprite being "squeezed" vertically to 1/2 of his height, are you using 1D or 2D bmp mode (see tonc tutorial if the question seems meaningless to you)

1D or 2D bmp mode? I don't know


where is this tutorial?

this?
http://user.chem.tue.nl/jakvijn/tonc/affine.htm
_________________
http://jandujar.homelinux.com
http://www.dsrobot.com

#105051 - PypeBros - Thu Oct 05, 2006 2:00 pm

that's rather "regular sprite". see "2.1. The sprite mapping mode"
_________________
SEDS: Sprite Edition on DS :: modplayer

#105054 - jandujar - Thu Oct 05, 2006 2:31 pm

I use this function to initialize the video.

Code:

void initVideo() {
   //enable vram and map it to the right places
    vramSetMainBanks(   VRAM_A_MAIN_BG_0x6000000,      //map A and B to main background memory
                        VRAM_B_MAIN_BG_0x6020000,      //this gives us 256KB which is a healthy amount for 16-bit gfx
                        VRAM_C_SUB_BG_0x6200000,      //map C to sub background memory
                        VRAM_D_LCD                  //map D to LCD free space
                  //allows adjacent banks to overflow into D if a bug like that was ever to occur
                        );
   
   //map a bank for use with sprites
   vramSetBankE(VRAM_E_MAIN_SPRITE); //mapping E to main sprites gives us 64k for sprites
   //(64k is the max space that 1024 tiles take up in 256 color mode)
   
   //set the video mode
    videoSetMode(  MODE_5_2D |
                   DISPLAY_SPR_ACTIVE |    //turn on sprites
                   DISPLAY_BG3_ACTIVE |    //turn on background 3
                   DISPLAY_SPR_1D          //this is used when in tile mode
               );
   
   videoSetModeSub(MODE_5_2D | DISPLAY_BG3_ACTIVE);
}


If I change DISPLAY_SPR_1D for DISPLAY_SPR_2D it's show me 4 sprites (with the same problem of scale)


[EDIT]
LOL

I change video mode, like in the sprite example of libnds
DISPLAY_SPR_1D |
DISPLAY_SPR_1D_BMP
And it does not work too.

The problem is Desmume!!!! With dualis works great.

Another time I have an problem with the emulator, not the program itselft.
_________________
http://jandujar.homelinux.com
http://www.dsrobot.com

#105060 - PypeBros - Thu Oct 05, 2006 3:52 pm

1D sprite is the preferred way to go for most of us ... and now that you mention it, there's indeed a bug with that in desmume ... as well as it cannot rotate sprites (maybe it cannot scale them either) and it doesn't understand the "double scale/rotate" or any alpha-blending stuff ...

So the only use i've found to desmume is the fact it's my only option on Linux systems ...
_________________
SEDS: Sprite Edition on DS :: modplayer