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 > 3D Engine - Nitro Engine V 0.6.0

#163069 - AntonioND - Sun Sep 21, 2008 1:20 pm

Hello!

This is a 3D engine, which aim is to make easier the procces of making a 3D game for the DS

Characteristics:
-Loader of models and textures from FAT.
-Dual 3D, as easy as normal 3D.
-Can load BMPs of 4,8, 16, and 24 bits and convert them into textures.
-Hardware-accelerated effects like fog and toon shading.
-You can take screenshots of both screens in dual 3D mode or the 3D screen in normal 3D mode.
-Animated model support, models are drawn using linear interpolation.
-2D over 3D system.
-Very basic physics engine.
-API functions.
-2D text in 3D mode, any character size allowed.
-More things...

TODO:
-Improve physics engine.
-You can ask me for the things you would like to see. :)

Download NitroEngine
Download NitroEngine Setup
(it) (en) (es) (fr) (gr)

Regards,

Antonio.


Last edited by AntonioND on Sun Sep 06, 2009 11:06 am; edited 13 times in total

#163070 - pas - Sun Sep 21, 2008 1:52 pm

Nice, let's hope lots of cool stuff emerges from this !
_________________
Starcraft DS ?

#163933 - AntonioND - Wed Oct 15, 2008 9:52 pm

Released version 0.4.0. Changes:

-Added MD2_2_NEA <converts an MD2 model into a NEA file that can used by Nitro Engine> and MD2_2_BIN <Converts the first frame of an MD2 model into a display list>. Display lists created are really optimized.
-Updated DisplayList_Fixed. Now it can remove normal commands too.
-Added a text system. It can use fonts of any size. ^^
-Added some simple API functions (buttons, check boxes, radio buttons and slide bars).
-Fixed 2D projection.
-Removed some internal unused functions to save space, and made 'inline' some of the rest.
-Functions that used float parameters modified so they use integers now. You can still use some wrappers if you want to use floats. This will let the compiler try to optimize the code.
-Animated and static models are now the same. You can move, rotate, etc them with the same functions.
-Now, you can 'clone' models so you can save a lot of RAM if they are repeated.
-Renamed lots of model functions. Take a look at new examples or documentation.
-NE_Color struct removed (I don't even know why I created it...).
-Examples updated to work with last version and added examples of clonning models, API and text system.
-libnds' console is not inited with Nitro Engine. You will have to init it yourself with NE_InitConsole or libnds' functions.

I'm sorry, you will have to make some changes in your game's source code for this version to work, but it is worth it! ^^

EDIT: I forgot to mention that cloning models will only save space if you have loaded them from fat using engine's functions.

EDIT 2: I've noticed a bug in the palette system. Download this file and replace the one you have with the new one. This bug has always been there, so if you have an older version and don't want to update, change the code of the old NE_PaletteLoad with the new one and recompile.
Here you are:
http://antoniond.drunkencoders.com/nitroengine/NEPalette.c

#164864 - dj-ceejay - Thu Nov 27, 2008 6:13 pm

How do you go about rendering 2D elements when using a 3D mode?
Do you just draw screen aligned quads?
Or can you switch modes and use sprites and BGs?
_________________
Fruit Machine Games:
http://www.fmsoftware.info/

#164867 - AntonioND - Thu Nov 27, 2008 8:00 pm

I set an orthogonal projection matrix and draw textured quads.

#164940 - josath - Wed Dec 03, 2008 6:46 pm

This looks very interesting. Do you have a website anywhere with real download links, docs, screenshots, etc or the only place to get it is those crappy file hosting sites you linked to?

#164945 - AntonioND - Wed Dec 03, 2008 9:44 pm

If you look carefully my profile, you'll see my webpage. :P There are some (two) screenshots, and 'real' download links. Documentation is included in the download.

#164946 - josath - Wed Dec 03, 2008 9:56 pm

yay, thanks, didn't think to look there :)

out of curiosity, did you make your 3d games (pong, tetris, blobb) using nitro engine?

and also, what tool do you use to make your 3d models?

#164947 - AntonioND - Wed Dec 03, 2008 10:15 pm

I make them with 3ds max/paint(omg! XD)/GIMP and I export them with the tools included in the downloads. The games you say were coded before Nitro Engine.

#165081 - nanou - Tue Dec 09, 2008 8:59 am

Pretty cool. I'll probably make use of this.... whenever I get MD2 export working.

Is NEA a custom format for Nitro Engine, or is it a preexisting format? If it's custom, can you tell me what kind of information it retains? I suppose I should just read the converter source.
_________________
- nanou

#165086 - AntonioND - Tue Dec 09, 2008 3:37 pm

NEA is just a pack of display lists with a header. If you convert the models with the other converter included in the rar (or any other converter), you can put them together with this:

http://antoniond.drunkencoders.com/files/bin2nea.rar

Rename your bin files to modelXXX.bin (XXX is a number from 0 to whatever).

Obviously, if you can convert them to md2 it would be better.

#165096 - nanou - Tue Dec 09, 2008 9:11 pm

Thanks. I've been using wavefront (.obj) because that's the most common/easily managed format I can export to without jumping through hoops... but I haven't found any obj->bin conversion tools that aren't also problematic.

Blender's MD2 export is trying to make me do things I don't want to do (but I'm bugging the blenderartists forums about that.)
_________________
- nanou

#165181 - freddan007 - Thu Dec 11, 2008 7:09 pm

I'm having some problems. When I run build.bat i get some errors. I could be because I have the new devkit arm.
error:
Quote:

NEFormats.c
arm-eabi-gcc -MMD -MP -MF /c/devkitPro/NitroEngine/build/NEFormats.d -g -Wall -O
2 -march=armv5te -mtune=arm946e-s -fomit-frame-pointer -ffast-math -mthumb -mthu
mb-interwork -I/c/devkitPro/NitroEngine/include -I/c/devkitPro/libnds/include -I
/c/devkitPro/NitroEngine/build -DARM9 -c /c/devkitPro/NitroEngine/source/NEForma
ts.c -o NEFormats.o
NEGeneral.c
arm-eabi-gcc -MMD -MP -MF /c/devkitPro/NitroEngine/build/NEGeneral.d -g -Wall -O
2 -march=armv5te -mtune=arm946e-s -fomit-frame-pointer -ffast-math -mthumb -mthu
mb-interwork -I/c/devkitPro/NitroEngine/include -I/c/devkitPro/libnds/include -I
/c/devkitPro/NitroEngine/build -DARM9 -c /c/devkitPro/NitroEngine/source/NEGener
al.c -o NEGeneral.o
c:/devkitPro/NitroEngine/source/NEGeneral.c: In function 'NE_UpdateInput':
c:/devkitPro/NitroEngine/source/NEGeneral.c:129: warning: 'touchReadXY' is depre
cated (declared at c:/devkitPro/libnds/include/nds/arm9/input.h:89)
c:/devkitPro/NitroEngine/source/NEGeneral.c: In function 'NE_Init3D':
c:/devkitPro/NitroEngine/source/NEGeneral.c:139: warning: implicit declaration o
f function 'powerON'
c:/devkitPro/NitroEngine/source/NEGeneral.c: In function 'NE_InitDual3D':
c:/devkitPro/NitroEngine/source/NEGeneral.c:163: error: 'SUB_BG2_CR' undeclared
(first use in this function)
c:/devkitPro/NitroEngine/source/NEGeneral.c:163: error: (Each undeclared identif
ier is reported only once
c:/devkitPro/NitroEngine/source/NEGeneral.c:163: error: for each function it app
ears in.)
c:/devkitPro/NitroEngine/source/NEGeneral.c:164: error: 'SUB_BG2_XDX' undeclared
(first use in this function)
c:/devkitPro/NitroEngine/source/NEGeneral.c:165: error: 'SUB_BG2_XDY' undeclared
(first use in this function)
c:/devkitPro/NitroEngine/source/NEGeneral.c:166: error: 'SUB_BG2_YDX' undeclared
(first use in this function)
c:/devkitPro/NitroEngine/source/NEGeneral.c:167: error: 'SUB_BG2_YDY' undeclared
(first use in this function)
c:/devkitPro/NitroEngine/source/NEGeneral.c:168: error: 'SUB_BG2_CY' undeclared
(first use in this function)
c:/devkitPro/NitroEngine/source/NEGeneral.c:169: error: 'SUB_BG2_CX' undeclared
(first use in this function)
c:/devkitPro/NitroEngine/source/NEGeneral.c: In function 'NE_InitConsole':
c:/devkitPro/NitroEngine/source/NEGeneral.c:207: error: 'BG1_CR' undeclared (fir
st use in this function)
c:/devkitPro/NitroEngine/source/NEGeneral.c:208: error: 'BG0_CR' undeclared (fir
st use in this function)
c:/devkitPro/NitroEngine/source/NEGeneral.c:210: warning: implicit declaration o
f function 'consoleInitDefault'
c:/devkitPro/NitroEngine/source/NEGeneral.c:210: error: 'CONSOLE_USE_COLOR255' u
ndeclared (first use in this function)
c:/devkitPro/NitroEngine/source/NEGeneral.c: In function 'NE_ProcessDual':
c:/devkitPro/NitroEngine/source/NEGeneral.c:240: error: 'BG1_CR' undeclared (fir
st use in this function)
c:/devkitPro/NitroEngine/source/NEGeneral.c:241: error: 'BG0_CR' undeclared (fir
st use in this function)
c:/devkitPro/NitroEngine/source/NEGeneral.c: In function 'NE_HBLFunc':
c:/devkitPro/NitroEngine/source/NEGeneral.c:356: error: 'SIN' undeclared (first
use in this function)
make[1]: *** [NEGeneral.o] Error 1
make: *** [build] Error 2

#165186 - AntonioND - Thu Dec 11, 2008 8:41 pm

This weekend I'll update my libnds and modify NitroEngine to work with latest version. I shouldn't take me much time...

EDIT: Actually, a lot of uv coordinates are swapped, so I'll try to fix them...

EDIT 2:
Everything fixed and ready to compile with latest libnds. I've also added a function to draw to RGBA textures. I've fixed MD2_2_NEA and M2D_2_BIN. You'll have to convert again your models if you have converted them with one of that programs.

If you want to use an older version of libnds, go to NEMain.h and uncomment "#define OLD_LIBNDS". Examples are prepared for latest version, so they might not work with older versions.

#165228 - freddan007 - Sat Dec 13, 2008 5:22 pm

AntonioND wrote:
This weekend I'll update my libnds and modify NitroEngine to work with latest version. I shouldn't take me much time...

EDIT: Actually, a lot of uv coordinates are swapped, so I'll try to fix them...

EDIT 2:
Everything fixed and ready to compile with latest libnds. I've also added a function to draw to RGBA textures. I've fixed MD2_2_NEA and M2D_2_BIN. You'll have to convert again your models if you have converted them with one of that programs.

If you want to use an older version of libnds, go to NEMain.h and uncomment "#define OLD_LIBNDS". Examples are prepared for latest version, so they might not work with older versions.
It works great with the new libnds, thank you! :D

#165240 - AntonioND - Sun Dec 14, 2008 11:10 am

Well, new version. Some bugfixes... Added a couple of examples... Added linux tools (thanks, nintendork32)...

I hope this is the last 0.4.X version...

#165264 - a128 - Mon Dec 15, 2008 5:38 pm

AntonioND wrote:
Well, new version. Some bugfixes... Added a couple of examples... Added linux tools (thanks, nintendork32)...

I hope this is the last 0.4.X version...




sometimes it's fine to test the software and after some weeks post an update.

#165266 - AntonioND - Mon Dec 15, 2008 6:02 pm

a128 wrote:
sometimes it's fine to test the software and after some weeks post an update.

I know, I usually do that but, as I wanted to make it compatible with latest libnds, I didn't test version 0.4.1 very much... I usually test Nitro Engine in the game I'm coding right now, in fact, the bugs fixed in 0.4.2 were reported by another guy right after the release.

#165344 - LOst? - Wed Dec 17, 2008 5:23 pm

AntonioND wrote:
I set an orthogonal projection matrix and draw textured quads.

Now how do you do this? Is this possible on the NDS? I have always wondered how to do just the thing you said but I thought it was not possible for the NDS, and that using 2D sprites were the only possible thing.
_________________
Exceptions are fun

#165351 - AntonioND - Wed Dec 17, 2008 8:09 pm

Take a look at "NE2D.c". NE_2DViewInit() sets the matrices, then you can draw with functions like NE_2DDrawQuad(), or just using libnds functions.

#165709 - AntonioND - Sun Jan 04, 2009 10:49 pm

-Text system and camera system optimized. New functions for the camera system.
-NE_TextPrintBox and NE_TextPrintBoxFree slightly changed. They can limit the text drawn to a number of characters set by the coder.
-Some functions made internal. Don't use them unless you know what you are doing.
-Fixed (?) at least the 2D projection.
-HBL effects fixed.
-Touch test functions.
-NE_UPDATE_INPUT removed.
-It now supports any BMP size, and BMP with 4 bits of depth.
-Arrays made pointers, so there is more memory free when you are not using Nitro Engine. You can also configure the number of objects of each systems you are going to use.
-NE_TextPalette replaced by NE_Palette.
-You can clone materials to use the same texture with different colors. This doesn't have the problems of cloning models.
-Added functions to remove all palettes and textures.
-Fixed NE_End().
-NE can free all memory used by it, and the coder can tell NE how much memory to use.
-Texture drawing system improved a bit.
-NE_PolyFormat simplified.
-Some bugfixes, code reorganized, define lists converted into enums.
-Clear bitmap supported, this is used to display an bitmap as rear plane. Each pixel can have different depth. This needs 2 VRAM banks to work.
-Solved some problems with 2D system and culling.
-Nomad NDS_Texture_Converter is no longer included, if you want it, look for it in google.
-Added Nitro Texture Converter, made by me. Open source, and it exports various levels of alpha in the textures that can handle it. It does only accept PNG files.
-NE now accepts any texture size. NE_SIZE_XXX defines removed as they are not needed now.
-Added a couple of examples.

#166118 - hacker013 - Thu Jan 29, 2009 5:08 pm

what are the diffrents between 0.5.0 and 0.5.1
_________________
Website / Blog

Let the nds be with you.

#166119 - AntonioND - Thu Jan 29, 2009 5:16 pm

hacker013 wrote:
what are the diffrents between 0.5.0 and 0.5.1

A bugfix to make it work with C++. I've only removed some definitions from headers.

And... I forgot 3 semicolons in old libnds compatibility mode. :P Yeah, that's the problem of copy/paste...

#166141 - hacker013 - Sat Jan 31, 2009 2:00 pm

I've made a little update wich included a updated version from libpicture from dragonminded so you can load gif,jpeg,png and bmp from fat. added some new functions and a error handler. If get permission, i will release this, i think.

EDIT:
Also added dsli support for plugins.
The error handeling doesn't work like it should be.

BUG-Found in version 0.5.1:

If i load 2 textures to memory the will displayed fine but when i wanna load and show a thirth texture it will be always shown white.
_________________
Website / Blog

Let the nds be with you.

#166142 - AntonioND - Sat Jan 31, 2009 3:18 pm

If you want, release it. ;)

hacker013 wrote:
If i load 2 textures to memory the will displayed fine but when i wanna load and show a thirth texture it will be always shown white.


What texture size/format?

#166144 - hacker013 - Sat Jan 31, 2009 4:49 pm

the format is .gif but i also tryed bmp. When i make the bmp's 256 color then it works as i should but i wanna have all colors.

size:
texture 1, 255*191
texture 2, 256*192
texture 3, 220*186

EDIT:
I think i will release tomorrow the updated engine. first i have to make the documentation. and the error check works now as it should be.
_________________
Website / Blog

Let the nds be with you.

#166145 - AntonioND - Sat Jan 31, 2009 5:04 pm

-RGB (2 bytes per pixel):

Texture 1 = 256(255) * 191 * 2 = 97792
Texture 2 = 256 * 192 * 2 = 98304
Texture 3 = 256(220) * 186 * 2 = 95232

Total = 291328 = 284,5 Kb.


-RGB256 (1 byte per pixel):

Texture 1 = 256(255) * 191 = 48896
Texture 2 = 256 * 192 = 49152
Texture 3 = 256(220) * 186 = 47616

Total = 145664 = 145,6 Kb.


Nitro Engine uses only VRAM_A and VRAM_B for textures, so you can use up to 256 KB. In first case, you try to use more memory than alowed. In second case you don't.

#166146 - a128 - Sat Jan 31, 2009 5:25 pm

dear AntonioND,

great to release a usefull 3d lib for the NDS....but I find it strange if a lib gets updated every 1-2 week....maybe you should just go from V 0.5.x to V 0.6 and release that . In my opinion this is better .

Anyway. Thanks for sharing your work....

#166148 - AntonioND - Sat Jan 31, 2009 5:37 pm

a128 wrote:
dear AntonioND,

great to release a usefull 3d lib for the NDS....but I find it strange if a lib gets updated every 1-2 week....maybe you should just go from V 0.5.x to V 0.6 and release that . In my opinion this is better .

Anyway. Thanks for sharing your work....


If you are talking about versions 0.4.X, I agree with you. I know I should have tested them more in order not to have to make bugfixes.

If you are talking about 0.5.1, I've only fixed some missing semicolons and removed some definitions from headers... a month after the previous release. Why I didn't notice that? Well, the semicolons bug was related to old-libnds compatibility mode (which I don't use, I think people shouldn't use, and will be deprecated next version). The other bug was reported by someone who was coding in C++ (I don't code in C++, so I just didn't know that could be a problem for its compiler).

If you are talking about hacker013's release... Well, that's not my update.

#166150 - hacker013 - Sat Jan 31, 2009 6:12 pm

AntonioND wrote:
-RGB (2 bytes per pixel):

Texture 1 = 256(255) * 191 * 2 = 97792
Texture 2 = 256 * 192 * 2 = 98304
Texture 3 = 256(220) * 186 * 2 = 95232

Total = 291328 = 284,5 Kb.


-RGB256 (1 byte per pixel):

Texture 1 = 256(255) * 191 = 48896
Texture 2 = 256 * 192 = 49152
Texture 3 = 256(220) * 186 = 47616

Total = 145664 = 145,6 Kb.


Nitro Engine uses only VRAM_A and VRAM_B for textures, so you can use up to 256 KB. In first case, you try to use more memory than alowed. In second case you don't.


in the first case your library says when i have loaded 3 textures that i have 25 procent free. O_O
_________________
Website / Blog

Let the nds be with you.

#166152 - AntonioND - Sat Jan 31, 2009 6:17 pm

hacker013 wrote:
in the first case your library says when i have loaded 3 textures that i have 25 procent free. O_O

Because when you load the third texture, the library checks if there is enough space for it. There isn't space, so the function just stops and returns 0.

#166153 - hacker013 - Sat Jan 31, 2009 6:30 pm

so i have only 256 kb for all my textures O_O?
_________________
Website / Blog

Let the nds be with you.

#166161 - AntonioND - Sat Jan 31, 2009 9:37 pm

hacker013 wrote:
so i have only 256 kb for all my textures O_O?


Yes. I only use vram A and B because I can use the same texture allocation system for normal 3D or dual 3D. I'm planning to change it. It should be easy. I just have to change a bit the allocation system to allow the user choose the vram banks to be used for texture memory.

#166178 - hacker013 - Sun Feb 01, 2009 3:04 pm

what can we expect in your next update?
_________________
Website / Blog

Let the nds be with you.

#166180 - AntonioND - Sun Feb 01, 2009 3:31 pm

Well, at the moment I'm quite busy with exams and I don't have time to work on Nitro Engine. When I have time I'll do the following changes:

-Change the animated model system so that it can use linear interpolation between frames. This means that old animated models won't work with new versions, and they will need more time to be displayed.
-I'll let the user choose which banks to use for texture memory.
-I'll remove GL_RGB support (if you want to load a RGB texture, you'll have to convert it to RGBA by yourself).

Well... I don't know what else to do... Any idea?

#166184 - hacker013 - Sun Feb 01, 2009 3:52 pm

why should you remove GL_RGB support ?

Maybe you can add md2 support?
_________________
Website / Blog

Let the nds be with you.

#166185 - AntonioND - Sun Feb 01, 2009 4:04 pm

hacker013 wrote:
why should you remove GL_RGB support ?


Well, personally I don't like that format because is the same as RGBA and it needs more time to load. RGBA textures can be loaded into VRAM using dmaCopy, for example, while RGB textures need to be modified when they are loaded. If you just include the data, It's quite stupid to modify the texture every time the program runs, it's better to convert it to the apropiate format in your PC and include it.

Besides, if you want to load a image file and convert it into RGB, it's easier/faster to set bit 15 while you are converting the data than when it is converted.

hacker013 wrote:
Maybe you can add md2 support?


I was thinking about integrating payk's md2 loader into Nitro Engine, but I prefer to make a conversion tool to convert MD2 into a custom format to avoid using floats and just load what Nitro Engine will actually use.

#166188 - hacker013 - Sun Feb 01, 2009 4:37 pm

i'm making a little sprite engine, because the texture memory is so small.
And the sprites are loaded in to texture memory when they're needed so it uses not much texture memory only i get white screens, here's my code, maybe you can see the problem:

NESprite.c
Code:

#include "NESprite.h"
#include "NEMain.h"
#include "NEPicLib.h"
#include "NETexture.h"
#include <stdio.h>
#include <string.h>

int NE_MAX_SPRITES;
int ne_sprites_init = false;
NE_SPRITE_ENGINE * nes_engine;

void NE_SpriteSystemReset(bool max_sprites)
{
   if (ne_sprites_init == true)NE_SpriteSystemEnd();
   if (max_sprites == 0)NE_MAX_SPRITES = MAX_SPRITES;
   
   nes_engine = (NE_SPRITE_ENGINE*)malloc(sizeof(NE_SPRITE_ENGINE));
   nes_engine->count = 0;
   
   ne_sprites_init = true;
}

void NE_SpriteSystemEnd()
{
   if(ne_sprites_init == true)
   {
      if(nes_engine != NULL)
      {
         free(nes_engine);
      }
      ne_sprites_init = false;
   }
}

NE_SPRITE_STRUCT * NE_SpriteCreate()
{
   if(ne_sprites_init == false)return NULL;
   if(nes_engine->count>NE_MAX_SPRITES)return NULL;
   NE_SPRITE_STRUCT * sprite;
   sprite = (NE_SPRITE_STRUCT*)malloc(sizeof(NE_SPRITE_STRUCT));
   sprite->sizeX = 0;
   sprite->sizeY = 0;
   sprite->adress = NULL;
   nes_engine->count++;
   return sprite;
}

void NE_SpriteDelete(NE_SPRITE_STRUCT * spr)
{
   if(ne_sprites_init == false)return;
   if(spr == NULL)return;
   if(spr->adress != NULL)free(spr->adress);
   free(spr);
   nes_engine->count--;
}

int NE_Sprite2Material(NE_SPRITE_STRUCT * spr, NE_Material * mat)
{
   int a = NE_MaterialTexLoad(mat, GL_RGB, spr->sizeX, spr->sizeY, TEXGEN_TEXCOORD, (uint8*)spr->adress);

   return a;
}

int NE_FATSpriteLoadPICtoRGB(NE_SPRITE_STRUCT * spr, const char* filename)
{
   if(ne_sprites_init == false)return 0; // Sprite System Not Inited
   if(spr == NULL){   
       #ifdef NE_ERROR_HANDLING
      char string[128];
      sprintf(string,"No sprite id to save %s to",filename);
      NE_Error(NE_ERROR_NOSPRITEID,string);
      #endif
      return 0;
   }
   PICTURE_DATA iconData;
   /* Changes const char to char */
   char* fn = "";
   sprintf(fn,"%s",filename);
   /* Check if file_exists */
   if (FATFileExists(fn) == false)
   {
      #ifdef NE_ERROR_HANDLING
      char string[128];
      sprintf(string,"%s couldn't be opened",fn);
      NE_Error(NE_ERROR_CANTOPENFILE,string);
      #endif
      return 0;
   }
   memset(&iconData, 0, sizeof(PICTURE_DATA));
   disableGIFFileStreaming();
   loadImage(fn, &iconData, 0, 0);

   if (iconData.error == true)
   {
      #ifdef NE_ERROR_HANDLING
      char string[128];
      sprintf(string, "Error happend while loading file\n%s", fn);
      NE_Error(NE_ERROR_FILELOADINGFAILED,string);
      #endif
      return 0;
   }

   spr->sizeX = iconData.max_X;
   spr->sizeY = iconData.max_Y;

   uint16 *tmpData = (uint16 *)malloc((spr->sizeX * spr->sizeY * 2) + 4);
   if (tmpData == NULL)
   {
      #ifdef NE_ERROR_HANDLING
      char string[128];
      sprintf(string, "Not enought memory to load file\n%s!", fn);
      NE_Error(NE_ERROR_OUTOFMEM,string);
      #endif
      return 0;
   }
   memcpy(tmpData, iconData.picData, (spr->sizeX * spr->sizeY * 2) + 4);

   freeImage(&iconData);
   
   spr->adress = tmpData;
   
   return 1;
}


NE2D.c
Code:

/****************************************************************************
*****************************************************************************
****       _   _ _ _               ______             _                  ****
****      | \ | (_) |             |  ____|           (_)                 ****
****      |  \| |_| |_ _ __ ___   | |__   _ __   __ _ _ _ __   ___       ****
****      | . ` | | __| '__/ _ \  |  __| | '_ \ / _` | | '_ \ / _ \      ****
****      | |\  | | |_| | | (_) | | |____| | | | (_| | | | | |  __/      ****
****      |_| \_|_|\__|_|  \___/  |______|_| |_|\__, |_|_| |_|\___|      ****
****                                             __/ |                   ****
****                                            |___/      V 0.5.1       ****
****                                                                     ****
****                     Copyright (C) 2008 - 2009 Antonio Ni?o D?az     ****
****                                   All rights reserved.              ****
****                                                                     ****
*****************************************************************************
****************************************************************************/

/****************************************************************************
*                                                                           *
*  This file is part of Nitro Engine version 0.5.1.                         *
*                                                                           *
*  Nitro Engine V 0.5.1 is licensed under the terms of the included file    *
*  named <readme_license.txt>. If you can't find it, send me an email and   *
*  I'll send you a copy. My adress is <antonio_nd@hotmail.com>              *
*                                                                           *
****************************************************************************/

#include "NEMain.h"

/*! \file   NE2D.c */

NE_Window ** NE_windowpointers = NULL;

int NE_MAX_WINDOWS;

bool ne_window_system_inited = false;

NE_Window * NE_WindowCreate(void)
{
if(!ne_window_system_inited) return NULL;

NE_Window * window = (NE_Window*)malloc(sizeof(NE_Window));

int a = 0;
while(1)
   {
   if(a == NE_MAX_WINDOWS) return NULL;
   if(NE_windowpointers[a] == NULL)
      {
      NE_windowpointers[a] = window;
      break;
      }
   a++;
   }

window->x = window->y = window->sx = window->sy = window->priority = 0;
window->visible = true;
window->color = NE_White;
window->mat = NULL;
window->spr = NULL;
window->alpha = 31; window->id = 0;
return window;
}


inline void NE_WindowSetCoords(NE_Window * window, int x, int y, int x2, int y2)
{
if(window == NULL) return;
window->x = x; window->y = y;
window->sx = x2 - x; window->sy = y2 - y;
}


inline void NE_WindowSetPos(NE_Window * window, int x, int y)
{
if(window == NULL) return;
window->x = x; window->y = y;
}


inline void NE_WindowSetSize(NE_Window * window, int x, int y)
{
if(window == NULL) return;
window->sx = x; window->sy = y;
}


inline void NE_WindowSetColor(NE_Window * window, u32 color)
{
if(window == NULL) return;
window->color = color;
}


inline void NE_WindowSetMaterial(NE_Window * window, NE_Material * mat)
{
if(window == NULL) return;
window->mat = mat;
}

inline void NE_WindowSetSprite(NE_Window * window, NE_SPRITE_STRUCT * spr)
{
if(window == NULL) return;
window->spr = spr;
}


inline void NE_WindowSetPriority(NE_Window * window, int priority)
{
if(window == NULL) return;
window->priority = priority;
}


inline void NE_WindowVisible(NE_Window * window, bool visible)
{
if(window == NULL) return;
window->visible = visible;
}


void NE_WindowDelete(NE_Window * window)
{
if(!ne_window_system_inited) return;
if(window == NULL) return;

int a = 0;
while(1)
   {
   if(a == NE_MAX_WINDOWS) return;
   if(NE_windowpointers[a] == window)
      {
      NE_windowpointers[a] = NULL;
      free((void*)window);
      return;
      }
   a++;
   }
return;
}


void NE_WindowDeleteAll(void)
{
if(!ne_window_system_inited) return;

int a;
for(a = 0; a < NE_MAX_WINDOWS; a++) NE_WindowDelete(NE_windowpointers[a]);
return;
}

void NE_WindowSystemReset(int number_of_windows)
{
if(ne_window_system_inited) NE_WindowSystemEnd();

if(number_of_windows < 1) NE_MAX_WINDOWS = NE_DEFAULT_WINDOWS;
else NE_MAX_WINDOWS = number_of_windows;

NE_windowpointers = malloc(NE_MAX_WINDOWS * sizeof(NE_windowpointers));

int a;
for(a = 0; a < NE_MAX_WINDOWS; a++) NE_windowpointers[a] = NULL;

ne_window_system_inited = true;
}

void NE_WindowSystemEnd(void)
{
if(!ne_window_system_inited) return;

NE_WindowDeleteAll();

free(NE_windowpointers);

ne_window_system_inited = false;
}


inline void NE_WindowSetParams(NE_Window * window, u8 alpha, u8 id)
{
if(window == NULL) return;
window->alpha = alpha; window->id = id;
}


void NE_WindowDraw(NE_Window * window)
{
if(window == NULL) return;

if(!window->visible) return;

GFX_POLY_FORMAT = POLY_ALPHA(window->alpha) | POLY_ID(window->id) | NE_CULL_NONE;

if(window->spr != NULL)
   {
   if(window->mat != NULL)
      {
      NE_MaterialDelete(window->mat);
      }
   window->mat = NE_MaterialCreate();
   int b = NE_Sprite2Material(window->spr,window->mat);
   if (b == 0)
      {
      #ifdef NE_ERROR_HANDLING
      char string[128];
      sprintf(string,"Sprite data couldn't be converted to a texture");
      NE_Error(NE_ERROR_MEMLOADINGFAILED,string);
      #endif
      window->mat = NULL;
      }
   }
if(window->mat == NULL)
   {
   NE_2DDrawQuad(window->x, window->y, window->x + window->sx,
            window->y + window->sy, window->priority, window->color);
   }
else
   {
   NE_2DDrawTexturedQuadColor(window->x, window->y, window->x + window->sx,
            window->y + window->sy, window->priority, window->mat, window->color);
   }
if(window->spr != NULL)
   {
      NE_MaterialDelete(window->mat);
      window->mat = NULL;
   }
}


void NE_WindowDrawAll(void)
{
if(!ne_window_system_inited) return;

int a;
for(a = 0; a < NE_MAX_WINDOWS; a++) if(NE_windowpointers[a] !=NULL)
   {
   NE_Window * window = NE_windowpointers[a];
   
   if(window->visible)
      {
      GFX_POLY_FORMAT = POLY_ALPHA(window->alpha) | POLY_ID(window->id) | NE_CULL_NONE;
      if(window->spr != NULL)
         {
         if(window->mat != NULL)
            {
            NE_MaterialDelete(window->mat);
            }
         window->mat = NE_MaterialCreate();
         int b = NE_Sprite2Material(window->spr,window->mat);
         if (b == 0)
            {
            #ifdef NE_ERROR_HANDLING
            char string[128];
            sprintf(string,"Sprite data couldn't be converted to a texture");
            NE_Error(NE_ERROR_MEMLOADINGFAILED,string);
            #endif
            window->mat = NULL;
            }
         }
      if(window->mat == NULL)
         {
         NE_2DDrawQuad(window->x, window->y, window->x + window->sx,
                  window->y + window->sy, window->priority, window->color);
         }
      else
         {
         NE_2DDrawTexturedQuad(window->x, window->y, window->x + window->sx,
                  window->y + window->sy, window->priority, window->mat);
         }
      if(window->spr != NULL)
         {
            NE_MaterialDelete(window->mat);
            window->mat = NULL;
         }
      }
   }
   NE_TextureDefragMem();
}


//----------------------------------------------------------

//              Functions to draw in 2D.

//----------------------------------------------------------

//--------------------------------------------
//INTERNAL USE -- See "NETexture.c"
int __NE_TextureGetRawX(NE_Material * tex);
int __NE_TextureGetRawY(NE_Material * tex);
//--------------------------------------------

void NE_2DViewInit(void)
{
glViewport(0,0,255,191);

MATRIX_CONTROL = GL_PROJECTION;  ///FIXED!!!!
MATRIX_IDENTITY = 0;
glOrthof32 (0,256,  192,0, inttof32(1),inttof32(-1));

MATRIX_CONTROL = GL_MODELVIEW;
MATRIX_IDENTITY = 0;

NE_PolyFormat(31, 0, 0, NE_CULL_NONE, 0);
}


inline void NE_2DViewRotateByPosition(int x, int y, int rotz)
{
NE_ViewMoveI( x, y,0);
#ifdef NE_OLD_LIBNDS
glRotateZi(rotz);
#else
glRotateZi(rotz<<6);
#endif
NE_ViewMoveI(-x,-y,0);
}

void NE_2DDrawQuad(s16 x1, s16 y1, s16 x2, s16 y2, s16 z, u32 color)
{
GFX_BEGIN = GL_QUADS;

GFX_TEX_FORMAT = 0;

GFX_COLOR = color;

GFX_VERTEX16 = (y1 << 16) | (x1 & 0xFFFF); //Up-left
GFX_VERTEX16 = z;

GFX_VERTEX_XY = (y2 << 16) | (x1 & 0xFFFF); //Down-left

GFX_VERTEX_XY = (y2 << 16) | (x2 & 0xFFFF); //Down-right

GFX_VERTEX_XY = (y1 << 16) | (x2 & 0xFFFF); //Up-right
}

void NE_2DDrawQuadGradient(s16 x1, s16 y1, s16 x2, s16 y2, s16 z, u32 color1,
               u32 color2, u32 color3, u32 color4)
{
GFX_BEGIN = GL_QUADS;

GFX_TEX_FORMAT = 0;

GFX_COLOR = color1;
GFX_VERTEX16 = (y1 << 16) | (x1 & 0xFFFF); //Up-left
GFX_VERTEX16 = z;

GFX_COLOR = color4;
GFX_VERTEX_XY = (y2 << 16) | (x1 & 0xFFFF); //Down-left

GFX_COLOR = color3;
GFX_VERTEX_XY = (y2 << 16) | (x2 & 0xFFFF); //Down-right

GFX_COLOR = color2;
GFX_VERTEX_XY = (y1 << 16) | (x2 & 0xFFFF); //Up-right
}


void NE_2DDrawTexturedQuad(s16 x1, s16 y1, s16 x2, s16 y2, s16 z, NE_Material * mat)
{
if(mat == NULL) return;
if(mat->texindex == NE_NO_TEXTURE) return;

int rx = __NE_TextureGetRawX(mat), ry = __NE_TextureGetRawY(mat);
int x = NE_TextureGetSizeX(mat), y = NE_TextureGetSizeY(mat);

NE_MaterialUse(mat);

GFX_BEGIN = GL_QUADS;

GFX_TEX_COORD = TEXTURE_PACK(0,0);
GFX_VERTEX16 = (y1 << 16) | (x1 & 0xFFFF); //Up-left
GFX_VERTEX16 = z;

GFX_TEX_COORD = TEXTURE_PACK(0,(inttot16(y)+ry));
GFX_VERTEX_XY = (y2 << 16) | (x1 & 0xFFFF); //Down-left

GFX_TEX_COORD = TEXTURE_PACK((inttot16(x)+rx),(inttot16(y)+ry));
GFX_VERTEX_XY = (y2 << 16) | (x2 & 0xFFFF); //Down-right

GFX_TEX_COORD = TEXTURE_PACK((inttot16(x)+rx),0);
GFX_VERTEX_XY = (y1 << 16) | (x2 & 0xFFFF); //Up-right
}


void NE_2DDrawTexturedQuadColor(s16 x1, s16 y1, s16 x2, s16 y2, s16 z, NE_Material * mat,
               u32 color)
{
if(mat == NULL) return;
if(mat->texindex == NE_NO_TEXTURE) return;

int rx = __NE_TextureGetRawX(mat), ry = __NE_TextureGetRawY(mat);
int x = NE_TextureGetSizeX(mat), y = NE_TextureGetSizeY(mat);

NE_MaterialUse(mat);

GFX_COLOR = color;

GFX_BEGIN = GL_QUADS;

GFX_TEX_COORD = TEXTURE_PACK(0,0);
GFX_VERTEX16 = (y1 << 16) | (x1 & 0xFFFF); //Up-left
GFX_VERTEX16 = z;

GFX_TEX_COORD = TEXTURE_PACK(0,(inttot16(y)+ry));
GFX_VERTEX_XY = (y2 << 16) | (x1 & 0xFFFF); //Down-left

GFX_TEX_COORD = TEXTURE_PACK((inttot16(x)+rx),(inttot16(y)+ry));
GFX_VERTEX_XY = (y2 << 16) | (x2 & 0xFFFF); //Down-right

GFX_TEX_COORD = TEXTURE_PACK((inttot16(x)+rx),0);
GFX_VERTEX_XY = (y1 << 16) | (x2 & 0xFFFF); //Up-right
}

void NE_2DDrawTexturedQuadGradient(s16 x1, s16 y1, s16 x2, s16 y2, s16 z, NE_Material * mat,
            u32 color1, u32 color2, u32 color3, u32 color4)
{
if(mat == NULL) return;
if(mat->texindex == NE_NO_TEXTURE) return;

int rx = __NE_TextureGetRawX(mat), ry = __NE_TextureGetRawY(mat);
int x = NE_TextureGetSizeX(mat), y = NE_TextureGetSizeY(mat);

NE_MaterialUse(mat);

GFX_BEGIN = GL_QUADS;

GFX_COLOR = color1;
GFX_TEX_COORD = TEXTURE_PACK(0,0);
GFX_VERTEX16 = (y1 << 16) | (x1 & 0xFFFF); //Up-left
GFX_VERTEX16 = z;

GFX_COLOR = color4;
GFX_TEX_COORD = TEXTURE_PACK(0,(inttot16(y)+ry));
GFX_VERTEX_XY = (y2 << 16) | (x1 & 0xFFFF); //Down-left

GFX_COLOR = color3;
GFX_TEX_COORD = TEXTURE_PACK((inttot16(x)+rx),(inttot16(y)+ry));
GFX_VERTEX_XY = (y2 << 16) | (x2 & 0xFFFF); //Down-right

GFX_COLOR = color2;
GFX_TEX_COORD = TEXTURE_PACK((inttot16(x)+rx),0);
GFX_VERTEX_XY = (y1 << 16) | (x2 & 0xFFFF); //Up-right
}

void NE_2DDrawTexturedQuadAlpha(s16 x1, s16 y1, s16 x2, s16 y2, s16 z, NE_Material * mat, double alpha)
{
if(mat == NULL) return;
if(mat->texindex == NE_NO_TEXTURE) return;

int rx = __NE_TextureGetRawX(mat), ry = __NE_TextureGetRawY(mat);
int x = NE_TextureGetSizeX(mat), y = NE_TextureGetSizeY(mat);

NE_MaterialUse(mat);

GFX_POLY_FORMAT = POLY_ALPHA(alpha) | POLY_ID(NE_API_POLY_ID) | NE_CULL_NONE;

GFX_BEGIN = GL_QUADS;

GFX_TEX_COORD = TEXTURE_PACK(0,0);
GFX_VERTEX16 = (y1 << 16) | (x1 & 0xFFFF); //Up-left
GFX_VERTEX16 = z;

GFX_TEX_COORD = TEXTURE_PACK(0,(inttot16(y)+ry));
GFX_VERTEX_XY = (y2 << 16) | (x1 & 0xFFFF); //Down-left

GFX_TEX_COORD = TEXTURE_PACK((inttot16(x)+rx),(inttot16(y)+ry));
GFX_VERTEX_XY = (y2 << 16) | (x2 & 0xFFFF); //Down-right

GFX_TEX_COORD = TEXTURE_PACK((inttot16(x)+rx),0);
GFX_VERTEX_XY = (y1 << 16) | (x2 & 0xFFFF); //Up-right
}


because libpicture loads the pictures in RGB format i also use RGB format.
_________________
Website / Blog

Let the nds be with you.

#166192 - AntonioND - Sun Feb 01, 2009 6:14 pm

You shouldn't mix your sprite functions with the window system... In fact, I think it is quite useless right now, I will probably modify/remove it in the future.

Anyway...

Code:
if(window->spr != NULL)
   {
   if(window->mat != NULL)
      {
      NE_MaterialDelete(window->mat);
      }
   window->mat = NE_MaterialCreate();
   int b = NE_Sprite2Material(window->spr,window->mat);
   }

Well... This could work with only a few sprites, but I wouldn't load the textures in the same function I use them...

Code:
   char* fn = "";
   sprintf(fn,"%s",filename);

What?? Fix that, fn should be pointing somewhere to hold the filename.

Code:
   memcpy(tmpData, iconData.picData, (spr->sizeX * spr->sizeY * 2) + 4);

Why do you put "+4"?

#166193 - hacker013 - Sun Feb 01, 2009 7:03 pm

AntonioND wrote:
You shouldn't mix your sprite functions with the window system... In fact, I think it is quite useless right now, I will probably modify/remove it in the future.

Anyway...

Code:
if(window->spr != NULL)
   {
   if(window->mat != NULL)
      {
      NE_MaterialDelete(window->mat);
      }
   window->mat = NE_MaterialCreate();
   int b = NE_Sprite2Material(window->spr,window->mat);
   }

Well... This could work with only a few sprites, but I wouldn't load the textures in the same function I use them...

Why should this only work with a few sprites?

Quote:

Code:
   char* fn = "";
   sprintf(fn,"%s",filename);

What?? Fix that, fn should be pointing somewhere to hold the filename.

How do you mean?

Quote:

Code:
   memcpy(tmpData, iconData.picData, (spr->sizeX * spr->sizeY * 2) + 4);

Why do you put "+4"?

I don't know, I ripped the load code for pictures from DSOrganize. Because i added libpicture to it so i also added the basic load code from DSO.
_________________
Website / Blog

Let the nds be with you.

#166200 - AntonioND - Sun Feb 01, 2009 8:55 pm

hacker013 wrote:

Why should this only work with a few sprites?

If you use a lot of sprites, it will need too much time to load the textures. You are doing that while the sprites are being drawn, so it could happen that some sprites aren't drawn.

hacker013 wrote:

How do you mean?

I don't know exactly where is pointing fn to, but I think:
1) It is pointing to the part of the ram where the rest of text is located. If fn is pointing to a string with no lenght, when you use sprintf you will overwrite some data.
2)It is pointing anywhere/NULL. In that case, you could cause a code dump.

For example, you can use:

Code:
 char* fn = (char*)malloc(MAXPATHLEN);
   sprintf(fn,"%s",filename);

//blablabla...

free(fn);

#166207 - silent_code - Sun Feb 01, 2009 10:46 pm

Or use a temporary buffer (local array of fixed size) instead. There are a few ways to solve this task.
Maybe a refresher on C/C++ programming could come in handy?
_________________
July 5th 08: "Volumetric Shadow Demo" 1.6.0 (final) source released
June 5th 08: "Zombie NDS" WIP released!
It's all on my page, just click WWW below.

#166267 - hacker013 - Tue Feb 03, 2009 6:01 pm

thx guys, and AntonioND when can we expect and new release?
_________________
Website / Blog

Let the nds be with you.

#166313 - AntonioND - Wed Feb 04, 2009 5:27 pm

In a few weeks I'll have more free time to work on Nitro Engine. Don't expect anything new before March...

#166355 - hacker013 - Thu Feb 05, 2009 8:08 pm

can you add the function to add alpha from an another texture. so every pixel can have its own alpha.
_________________
Website / Blog

Let the nds be with you.

#166357 - AntonioND - Thu Feb 05, 2009 8:48 pm

hacker013 wrote:
can you add the function to add alpha from an another texture. so every pixel can have its own alpha.

What do you want that for? To modify the alpha of a texture previously loaded from fat?

#166372 - hacker013 - Fri Feb 06, 2009 4:21 pm

for alpha masks
_________________
Website / Blog

Let the nds be with you.

#166375 - elhobbs - Fri Feb 06, 2009 4:40 pm

the ds does not have full opengl alpha support. you can do 1 bit transparancy with GL_RGBA textures or you can do per triangle/quad transparacy with alpha using glPolyFmt. There are also some low color texture formats that have alpha channels as well.
Code:

//from videoGL.h in libnds
typedef enum {
   GL_RGB32_A3   = 1, /*!< 32 color palette, 3 bits of alpha */
   GL_RGB4       = 2, /*!< 4 color palette */
   GL_RGB16      = 3, /*!< 16 color palette */
   GL_RGB256     = 4, /*!< 256 color palette */
   GL_COMPRESSED = 5, /*!< compressed texture */
   GL_RGB8_A5    = 6, /*!< 8 color palette, 5 bits of alpha */
   GL_RGBA       = 7, /*!< 15 bit direct color, 1 bit of alpha */
   GL_RGB        = 8  /*!< 15 bit direct color, manually sets alpha bit to 1 */
} GL_TEXTURE_TYPE_ENUM;

/*! \fn  uint32 POLY_ALPHA(int n)
\brief used in glPolyFmt() to set the alpha level for the following polygons, set to 0 for wireframe mode
\param n the level of alpha (0-31) */
 uint32 POLY_ALPHA(int n) { return (uint32)((n) << 16); };

#166378 - hacker013 - Fri Feb 06, 2009 6:03 pm

in RGBA mode i thought that every pixel has its own alpha value, correct me if i'm wrong.
_________________
Website / Blog

Let the nds be with you.

#166381 - josath - Fri Feb 06, 2009 6:22 pm

hacker013 wrote:
in RGBA mode i thought that every pixel has its own alpha value, correct me if i'm wrong.


Yes, every pixel has its own alpha value....but the only possible values are 0 or 1.

#166382 - hacker013 - Fri Feb 06, 2009 7:23 pm

so i asked for support of loading alpha from a file: a black/white/grey bmp to set the alpha from every pixel aka alpha masks.

EDIT:

Can you also add scrolling background in 2d mode?
_________________
Website / Blog

Let the nds be with you.

#166402 - silent_code - Sat Feb 07, 2009 1:19 pm

I think he is requestin a separate alpha image with black and white entries, that is supposed to set the alpha bit in a corresponding color image.
_________________
July 5th 08: "Volumetric Shadow Demo" 1.6.0 (final) source released
June 5th 08: "Zombie NDS" WIP released!
It's all on my page, just click WWW below.

#166405 - hacker013 - Sat Feb 07, 2009 2:03 pm

silent_code wrote:
I think he is requestin a separate alpha image with black and white entries, that is supposed to set the alpha bit in a corresponding color image.


that is right
_________________
Website / Blog

Let the nds be with you.

#166469 - hacker013 - Sun Feb 08, 2009 5:51 pm

little request again:
can you add alpha support by every 2d function. and release some documentation about how to make a bitmap font for NE.
_________________
Website / Blog

Let the nds be with you.

#166490 - AntonioND - Sun Feb 08, 2009 8:43 pm

If you want to change alpha of 2D drawings, just change the polygon format between quads. It's not as easy as changing the alpha value, you have to take care of the poly ID. Try to draw a translucent polygon over another with the same ID to see what I mean.

And... about the font... Have you tried to open it with... Paint, for example? The fonts I use in the examples are just a BMP files, take a look at them.

#166619 - silent_code - Thu Feb 12, 2009 12:09 am

Usenti is a great tool for that purpose. :^)
_________________
July 5th 08: "Volumetric Shadow Demo" 1.6.0 (final) source released
June 5th 08: "Zombie NDS" WIP released!
It's all on my page, just click WWW below.

#166669 - hacker013 - Fri Feb 13, 2009 5:19 pm

we i use:
Code:

NE_ProcessDual(NE_2DViewInit,NE_2DViewInit);
NE_ProcessDual(Drawing2DTop,Drawing2DDown);

is then the second processdual still in 2d mode?

EDIT:
can i init dual 3d and ne console?
_________________
Website / Blog

Let the nds be with you.

#166673 - AntonioND - Fri Feb 13, 2009 8:02 pm

hacker013 wrote:
we i use:
Code:

NE_ProcessDual(NE_2DViewInit,NE_2DViewInit);
NE_ProcessDual(Drawing2DTop,Drawing2DDown);

is then the second processdual still in 2d mode?

EDIT:
can i init dual 3d and ne console?

That won't work... That function just calls the correct function to render to screen, you have to draw 2D + 3D in that function.

Yes, you can use the console, but i'd only use it for debugging purposes (it does only work in one screen). If you want to display text, use the text functions of NE.

#166700 - hacker013 - Sun Feb 15, 2009 10:41 am

i've some problems with materials, i've 1 material what is correctly loaded like the rest but isn't show. i use a window to show it and it hasn't a white rectangle, it just draws nothing.
_________________
Website / Blog

Let the nds be with you.

#166707 - AntonioND - Sun Feb 15, 2009 3:23 pm

hacker013 wrote:
i've some problems with materials, i've 1 material what is correctly loaded like the rest but isn't show. i use a window to show it and it hasn't a white rectangle, it just draws nothing.

If you try to draw a textured quad whose texture isn't pointing to a valid texture slot, the quad won't be displayed.

#166714 - renatobs - Sun Feb 15, 2009 7:28 pm

Hi. I?m remaking for NDS a game of console SEGA Genesis game called "Shining Force 2" and in the battle scene I?d like to put a 3D animation. I?m totally new in 3D engines ( I?m learning about Blender 3D, it?s very good! ) and seem to me that your 3D engine is so friendly, correct !!? But, I have some doubts: my 2D engine is made and I?d like to mix your engine, to create this animations, and show only in the up-screen, while the 2D scene keep under. Here you can see some information about "how looks like" the game:

http://forums.shiningforcecentral.com/index.php?showtopic=12564
http://br.youtube.com/watch?v=oHwqK46bE50

Ok, maybe you are asking "what are trying to do?". See this:

http://www.youtube.com/watch?v=E1MCLMRKklQ&feature=related

There you can see how was the battle scene in the first version of the game, Genesis 2D game. And here:

http://www.youtube.com/watch?v=NvogOLSYdhs

...you can see the 3D version of the game in the Sega Saturn console, but it?s not the same, it?s Shining Force 3.

Well, I?d like to put only the 3D battle scene in my game, when the character are fighting. One screen with the 2D scene, the touchscreen, and in the other the 3D animation fighting scene. What do you think ? Is it possible with your engine ?? If I was do all the game in 3D way, like you saw in the video, could I ??

Thanks for your atention and sorry fo my "poor english language! "

#166715 - hacker013 - Sun Feb 15, 2009 7:36 pm

if your game is totaly 2d but the cutscenes are 3d you maybe beter can implent swf and then make your 3d scenes in blender. make the movie. convert it to a .swf and play it on your nds-screen.
_________________
Website / Blog

Let the nds be with you.

#166723 - renatobs - Mon Feb 16, 2009 12:05 am

Ok... but no, cuz I?d like to do this in "real time", cuz I need to get the scene in a lot of views... and if the engime alow me to do all things in 3D, it?s very good !!!

#166741 - hacker013 - Mon Feb 16, 2009 9:39 am

i think i can but you have to reinit your 2d engine after using nitro engine or you could bease your 2d engine on the 2d functions from nitro engine.
_________________
Website / Blog

Let the nds be with you.

#166748 - AntonioND - Mon Feb 16, 2009 2:34 pm

The animation system is quite bad at the moment. If you want to display 3D scenes with many animated models, you'll have to use another system.

#166754 - hacker013 - Mon Feb 16, 2009 4:55 pm

i think you maybe should try out the yeti 3d engine
_________________
Website / Blog

Let the nds be with you.

#166807 - renatobs - Wed Feb 18, 2009 7:18 pm

No, no... I?d like to have only 2 characters on one texturized floor,only it... in the background I?ll put a 2D picture... in the link above you can see exactly what i?d like to do... when 2 characters of the battle come so close, a scene is show, with these chars fighting, one of them attacking and the other defensing or not... This scene is what I?d like to do in up-screen !!! Only this scene in 3D and with a simple and easy animation... I?d like to do one test with it. But I?d like to do if there is a chance that I can use your engine to do this, and could I use the Blender models to do it ?!?!

#166809 - AntonioND - Wed Feb 18, 2009 9:18 pm

renatobs wrote:
No, no... I?d like to have only 2 characters on one texturized floor,only it... in the background I?ll put a 2D picture... in the link above you can see exactly what i?d like to do... when 2 characters of the battle come so close, a scene is show, with these chars fighting, one of them attacking and the other defensing or not... This scene is what I?d like to do in up-screen !!! Only this scene in 3D and with a simple and easy animation... I?d like to do one test with it. But I?d like to do if there is a chance that I can use your engine to do this, and could I use the Blender models to do it ?!?!

You would have to export your models in MD2 format. Anyway, the animation system is really bad, there is no way to display "frames between frames", so even a short animation needs a lot of space... You can try to convert a model and see if that is what you are looking for.

#166818 - hacker013 - Thu Feb 19, 2009 4:31 pm

wth, is then using all that space?
_________________
Website / Blog

Let the nds be with you.

#167564 - hacker013 - Wed Mar 18, 2009 6:16 pm

Nitro Engine doesn't init correctly anymore with the newest libnds 1.3.2 and devkitARM r25. The screen is totaly messed up in Dual 3D mode. Do you have already made a new version or a fix?
_________________
Website / Blog

Let the nds be with you.

#167576 - AntonioND - Wed Mar 18, 2009 8:26 pm

hacker013 wrote:
Nitro Engine doesn't init correctly anymore with the newest libnds 1.3.2 and devkitARM r25. The screen is totaly messed up in Dual 3D mode. Do you have already made a new version or a fix?

Are you using the touch test functions? I know they don't work well with latest version of libnds. If you aren't using that, explain a little more what happens.

#167604 - hacker013 - Thu Mar 19, 2009 7:37 pm

No, I'm not using them. I found that is was a problem with the wifi init function. I placed it some where else in the program and now is any working right again oO.
_________________
Website / Blog

Let the nds be with you.

#167655 - hacker013 - Sat Mar 21, 2009 11:54 am

I found a bug. The text priority functions does't work. You have to open NEText.c and replace this:
Code:

static inline void _ne_texturecuadprint(int xcrd1, int ycrd1, int xcrd2, int ycrd2, int xtx1, int ytx1, int xtx2, int ytx2)
{
//------------ INTERNAL USE  ----------------------------
GFX_TEX_COORD = TEXTURE_PACK(inttot16(xtx1), inttot16(ytx1));
GFX_VERTEX16 = (ycrd1 << 16) | (xcrd1 & 0xFFFF);
GFX_VERTEX16 = 0;

GFX_TEX_COORD = TEXTURE_PACK(inttot16(xtx1), inttot16(ytx2));
GFX_VERTEX_XY = (ycrd2 << 16) | (xcrd1 & 0xFFFF);

GFX_TEX_COORD = TEXTURE_PACK(inttot16(xtx2), inttot16(ytx2));
GFX_VERTEX_XY = (ycrd2 << 16) | (xcrd2 & 0xFFFF);

GFX_TEX_COORD = TEXTURE_PACK(inttot16(xtx2), inttot16(ytx1));
GFX_VERTEX_XY = (ycrd1 << 16) | (xcrd2 & 0xFFFF);
}

with this:
Code:

static inline void _ne_texturecuadprint(int xcrd1, int ycrd1, int xcrd2, int ycrd2, int xtx1, int ytx1, int xtx2, int ytx2)
{
//------------ INTERNAL USE  ----------------------------
GFX_TEX_COORD = TEXTURE_PACK(inttot16(xtx1), inttot16(ytx1));
GFX_VERTEX16 = (ycrd1 << 16) | (xcrd1 & 0xFFFF);
GFX_VERTEX16 = NE_TEXT_PRIORITY;

GFX_TEX_COORD = TEXTURE_PACK(inttot16(xtx1), inttot16(ytx2));
GFX_VERTEX_XY = (ycrd2 << 16) | (xcrd1 & 0xFFFF);

GFX_TEX_COORD = TEXTURE_PACK(inttot16(xtx2), inttot16(ytx2));
GFX_VERTEX_XY = (ycrd2 << 16) | (xcrd2 & 0xFFFF);

GFX_TEX_COORD = TEXTURE_PACK(inttot16(xtx2), inttot16(ytx1));
GFX_VERTEX_XY = (ycrd1 << 16) | (xcrd2 & 0xFFFF);
}


And replace this in NEGeneral.c:
Code:
static void NE_Init__(void)
{
//Power all 3D and 2D. Hide 3D screen during init
#ifdef NE_OLD_LIBNDS
powerON(POWER_ALL);
#else
powerOn(POWER_ALL);
#endif

videoSetMode(0);

vramSetBankA(VRAM_A_TEXTURE_SLOT0);
vramSetBankB(VRAM_B_TEXTURE_SLOT1);
vramSetBankE(VRAM_E_TEX_PALETTE);

while (GFX_STATUS & (1<<27));

// Clear the FIFO
GFX_STATUS |= (1<<29);

glFlush(0);
glFlush(0);

lcdMainOnTop();

glResetMatrixStack();

GFX_CONTROL = GL_TEXTURE_2D | GL_ANTIALIAS | GL_BLEND;

glAlphaFunc(BLEND_ALPHA);

NE_ClearColorSet(NE_Black,31,63);
NE_FogEnableBackground(false);
glClearDepth(GL_MAX_DEPTH);

NE_Viewport(0,0,255,191);

//Default number of objects for everyting
NE_TextureSystemReset(0,0);
NE_CameraSystemReset(0);
NE_PhysicsSystemReset(0);
NE_WindowSystemReset(0);
NE_APISystemReset(0);
NE_ModelSystemReset(0);

glMatrixMode(GL_TEXTURE);
glLoadIdentity();

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspectivef32(70 * LUT_SIZE / 360.0, floattof32(256.0 / 192.0), floattof32(0.1F), inttof32(40));

//ds uses a table for shinyness..this generates a half-ass one
glMaterialShinyness();

// setup other material properties
glMaterialf(GL_AMBIENT, RGB15(16,16,16));
glMaterialf(GL_DIFFUSE, RGB15(20,20,20));
glMaterialf(GL_SPECULAR, BIT(15) | RGB15(8,8,8));
glMaterialf(GL_EMISSION, RGB15(5,5,5));

//Turn off some things...
int a = 4;
while(a--) NE_LightOff(a);

GFX_COLOR = 0;
GFX_POLY_FORMAT = 0;

a = 8;
while(a--) NE_OutliningSetColor(a,0);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

//Ready!!

videoSetMode(MODE_0_3D);
}
with this:
Code:
static void NE_Init__(void)
{
//Power all 3D and 2D. Hide 3D screen during init
#ifdef NE_OLD_LIBNDS
powerON(POWER_ALL);
#else
powerOn(POWER_ALL);
#endif

videoSetMode(0);

vramSetBankA(VRAM_A_TEXTURE_SLOT0);
vramSetBankB(VRAM_B_TEXTURE_SLOT1);
vramSetBankE(VRAM_E_TEX_PALETTE);

while (GFX_STATUS & (1<<27));

// Clear the FIFO
GFX_STATUS |= (1<<29);

glFlush(0);
glFlush(0);

lcdMainOnTop();

glResetMatrixStack();

GFX_CONTROL = GL_TEXTURE_2D | GL_ANTIALIAS | GL_BLEND;

glAlphaFunc(BLEND_ALPHA);

NE_ClearColorSet(NE_Black,31,63);
NE_FogEnableBackground(false);
glClearDepth(GL_MAX_DEPTH);

NE_Viewport(0,0,255,191);

//Default number of objects for everyting
NE_TextureSystemReset(0,0);
NE_CameraSystemReset(0);
NE_PhysicsSystemReset(0);
NE_WindowSystemReset(0);
NE_APISystemReset(0);
NE_ModelSystemReset(0);
NE_TextPriorityReset();

glMatrixMode(GL_TEXTURE);
glLoadIdentity();

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspectivef32(70 * LUT_SIZE / 360.0, floattof32(256.0 / 192.0), floattof32(0.1F), inttof32(40));

//ds uses a table for shinyness..this generates a half-ass one
glMaterialShinyness();

// setup other material properties
glMaterialf(GL_AMBIENT, RGB15(16,16,16));
glMaterialf(GL_DIFFUSE, RGB15(20,20,20));
glMaterialf(GL_SPECULAR, BIT(15) | RGB15(8,8,8));
glMaterialf(GL_EMISSION, RGB15(5,5,5));

//Turn off some things...
int a = 4;
while(a--) NE_LightOff(a);

GFX_COLOR = 0;
GFX_POLY_FORMAT = 0;

a = 8;
while(a--) NE_OutliningSetColor(a,0);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

//Ready!!

videoSetMode(MODE_0_3D);
}

So that it work again.

This are 2 2d draw quad functions with alpha support:
Code:
void NE_2DDrawTexturedQuadAlpha(s16 x1, s16 y1, s16 x2, s16 y2, s16 z, NE_Material * mat, int alpha, int id)
{
if(mat == NULL) return;
if(mat->texindex == NE_NO_TEXTURE) return;

int rx = __NE_TextureGetRawX(mat), ry = __NE_TextureGetRawY(mat);
int x = NE_TextureGetSizeX(mat), y = NE_TextureGetSizeY(mat);

NE_MaterialUse(mat);

GFX_POLY_FORMAT = POLY_ALPHA(alpha) | POLY_ID(id) | NE_CULL_NONE;

GFX_BEGIN = GL_QUADS;

GFX_TEX_COORD = TEXTURE_PACK(0,0);
GFX_VERTEX16 = (y1 << 16) | (x1 & 0xFFFF); //Up-left
GFX_VERTEX16 = z;

GFX_TEX_COORD = TEXTURE_PACK(0,(inttot16(y)+ry));
GFX_VERTEX_XY = (y2 << 16) | (x1 & 0xFFFF); //Down-left

GFX_TEX_COORD = TEXTURE_PACK((inttot16(x)+rx),(inttot16(y)+ry));
GFX_VERTEX_XY = (y2 << 16) | (x2 & 0xFFFF); //Down-right

GFX_TEX_COORD = TEXTURE_PACK((inttot16(x)+rx),0);
GFX_VERTEX_XY = (y1 << 16) | (x2 & 0xFFFF); //Up-right
}

void NE_2DDrawQuadGradientAlpha(s16 x1, s16 y1, s16 x2, s16 y2, s16 z, u32 color1,
               u32 color2, u32 color3, u32 color4, int alpha, int id)
{
GFX_POLY_FORMAT = POLY_ALPHA(alpha) | POLY_ID(id) | NE_CULL_NONE;

GFX_BEGIN = GL_QUADS;

GFX_TEX_FORMAT = 0;

GFX_COLOR = color1;
GFX_VERTEX16 = (y1 << 16) | (x1 & 0xFFFF); //Up-left
GFX_VERTEX16 = z;

GFX_COLOR = color4;
GFX_VERTEX_XY = (y2 << 16) | (x1 & 0xFFFF); //Down-left

GFX_COLOR = color3;
GFX_VERTEX_XY = (y2 << 16) | (x2 & 0xFFFF); //Down-right

GFX_COLOR = color2;
GFX_VERTEX_XY = (y1 << 16) | (x2 & 0xFFFF); //Up-right
}


Here a fix for NE_WaitForVBL() so it work also without errors in c++
Replace this struct in NEGeneral.h:
Code:

/*! \enum  NE_UPDATE_FLAGS
 *  \brief Arguments for NE_WaitForVBL(). */
typedef enum
   {
   NE_UPDATE_API        =    1, /*!< Updates NE_API. */
   NE_UPDATE_ANIMATIONS = 1<<1, /*!< Updates animated models. */
   NE_UPDATE_PHYSICS    = 1<<2, /*!< Updates the physics engine. */
   NE_CAN_SKIP_VBL      = 1<<3  /*!< Allows Nitro Engine skip the VBL wait if CPU load is greater than 100. */
   } NE_UPDATE_FLAGS;

with this:
Code:
/*! \enum  NE_UPDATE_FLAGS
 *  \brief Arguments for NE_WaitForVBL(). */
typedef enum
   {
   NE_UPDATE_API        =    1, /*!< Updates NE_API. */
   NE_UPDATE_ANIMATIONS = 1<<1, /*!< Updates animated models. */
   NE_UPDATE_PHYSICS    = 1<<2, /*!< Updates the physics engine. */
   NE_CAN_SKIP_VBL      = 1<<3, /*!< Allows Nitro Engine skip the VBL wait if CPU load is greater than 100. */
   NE_UPDATE_BASIC    = 1<<4  /*<! Update Basic */
   } NE_UPDATE_FLAGS;


If you want gif/bmp/jpeg/png loading support from fat in this engine go to http://urazelda.webs.com/downloads.htm and download the update version from libpicture from my site and add this to NEFormats.c
Code:

/*--------------------------------------------------------------------
Internal Use
---------------------------------------------------------------------*/
// --
// FileExists
// --
bool FileExists(char* filename)
{
FILE *fp = fopen(filename,"r");
if(fp)
   {
      fclose(fp);
      return true;
   } else {
      return false;
   }
}
//-------------------------------------------------------------------------------
int UZ_FATMaterialTexLoadPICtoRGB(NE_Material * tex, const char * filename)
{
if (tex == NULL) return 0;

int lastx = 0, lasty = 0;
PICTURE_DATA iconData;
char* fn = malloc(MAXPATHLEN);
sprintf(fn,"%s",filename);

if(FileExists(fn)==false) // couldn't open
{
   char string[128];
   sprintf(string, "%s could't be opened!", fn);
   NE_FATAL_ERROR(string);
}
memset(&iconData, 0, sizeof(PICTURE_DATA));
disableGIFFileStreaming();
loadImage(fn, &iconData, 0, 0);

if (iconData.error == true)
{
   char string[128];
   sprintf(string, "Error happend while loading file\n%s", fn);
   NE_FATAL_ERROR(string);
}

lastx = iconData.max_X;
lasty = iconData.max_Y;

uint16 *tmpData = (uint16 *)malloc((lastx * lasty * 2) + 4);
if (tmpData == NULL)
{
   char string[128];
   sprintf(string, "Not enought memory to load file\n%s!", fn);
   NE_FATAL_ERROR(string);
}
memcpy(tmpData, iconData.picData, (lastx * lasty * 2) + 4);

freeImage(&iconData);

int a = NE_MaterialTexLoad(tex, GL_RGB, lastx, lasty, TEXGEN_TEXCOORD, (u8*)tmpData);

return a;
}

It loads the pictures from fat in RGB format.

Note: you have to update the header files by yourself. I hope that it don't gives to much work to do that.

This are bug fixes and updates for AntonioND's Nitro Engine. Your choise to use it or not. I hope he will intergrate them.
_________________
Website / Blog

Let the nds be with you.

#167666 - a128 - Sat Mar 21, 2009 5:32 pm

hacker013 wrote:
I found a bug. The text priority functions does't work. You have to open NEText.c and replace this:.....




please post your source code as a download link....that would be better I guess then posting tons tons of text

#167669 - hacker013 - Sat Mar 21, 2009 5:41 pm

I only post the changes because when I post only a zip with the source I had to post also the changes -_-
_________________
Website / Blog

Let the nds be with you.

#167673 - AntonioND - Sat Mar 21, 2009 8:39 pm

Thanks for the bug report, hacker013.

hacker013 wrote:
I only post the changes because when I post only a zip with the source I had to post also the changes -_-

But you could have posted only the modified functions and tell where the modification is, for example.

By the way, I've modified a bit the texture allocation system and it now lets you choose the vram banks Nitro Engine can use for textures. In dual 3D mode you can only choose banks A and B, of course.

#168059 - hacker013 - Wed Apr 08, 2009 4:55 pm

Any updates O_O?

And why doesn't do this anything?
Code:
   //Graphics
   NE_2DDrawTexturedQuad(44, 135, 44+256, 135+16, 5, MaterialCheckBrightness);
   NE_2DDrawTexturedQuad(44, 153, 44+256, 153+4, 5, MaterialOptionsLine);
   NE_2DDrawTexturedQuad(44, 56, 44+256, 56+4, 5, MaterialOptionsLine);
   NE_2DDrawTexturedQuad(44, 113, 44+256, 113+4, 5, MaterialOptionsLine);
   //Text
   NE_TextPrintFree(0, 31, 15, NE_White, "Options");
   NE_TextPrintFree(0, 44, 135, NE_White, "CHECK BRIGHTNESS");
   NE_TextPrintFree(0, 44, 38, NE_White, "SOUND");
   NE_TextPrintFree(0, 44, 59, NE_White, "Music\nEffects");
   if(game_music)
   {
      NE_TextPrintFree(0, 149, 59, NE_White, "On\nOff");
   } else {
      NE_TextPrintFree(0, 149, 59, NE_White, "Off\nOff");
   }
   NE_TextPrintFree(0, 44, 95, NE_White, "Z TARGETING");
   NE_TextPrintFree(0, 44, 126, NE_White, "Switch     Hold");

_________________
Website / Blog

Let the nds be with you.

#168118 - AntonioND - Fri Apr 10, 2009 3:16 pm

Please, copy the whole function.

#168132 - hacker013 - Fri Apr 10, 2009 6:26 pm

oke, here is the whole function:

Code:
void DrawDownMenu(){
NE_2DViewInit();
// -- Draw moving clouds
NE_WindowDraw(WindowMenu[0]);
NE_WindowDraw(WindowMenu[1]);
NE_2DDrawQuadGradientAlpha(0, 0, 256, 192, 9, NE_Black, NE_Black, NE_Blue, NE_Blue, 15, 1);
NE_WindowDraw(WindowMenu[2]);
// -- Draw Text
NE_TextPrintFree(0,48,175,NE_LightBlue,"A-Decide  *  B-Cancel");
int i=0;
switch(menu_room)
{
// Main
case 0:
   // Draw Windows
   for(i=0;i<10;i++)
   {
      NE_WindowDraw(WindowMenu[3+i]);
   }
   // Draw Text
   NE_TextPrintFree(0,31,15,NE_White,"Please select a file.");
   NE_TextPrintFree(0,50,46,NE_White,"File 1");
   NE_TextPrintFree(0,50,66,NE_White,"File 2");
   NE_TextPrintFree(0,50,86,NE_White,"File 3");
   NE_TextPrintFree(0,50,110,NE_White,"Copy");
   NE_TextPrintFree(0,50,130,NE_White,"Erase");
   NE_TextPrintFree(0,50,154,NE_White,"Options");
   
   if(menu_current_button==3 && !Save[0]->exists && !Save[1]->exists && !Save[2]->exists)
   {
      NE_TextPrintFree(0,115,110,NE_White,"No file to copy.");
   }
   if(menu_current_button==3 && Save[0]->exists && Save[1]->exists && Save[2]->exists)
   {
      NE_TextPrintFree(0,115,110,NE_White,"There is no empty file.");
   }
   if(menu_current_button==4 && !Save[0]->exists && !Save[1]->exists && !Save[2]->exists)
   {
      NE_TextPrintFree(0,115,130,NE_White,"No file to erase.");
   }
   
   for(i=0;i<3;i++)
   {
      if(Save[i]->exists)
      {
         NE_TextPrintFree(0,124,46+20*i,NE_White,Save[i]->Player.name);
      }
   }
break;
// Load Game
case 1:
   NE_WindowDraw(WindowMenu[3]);
   NE_WindowDraw(WindowMenu[6]);
   NE_WindowDraw(WindowMenu[7]);
   NE_WindowDraw(WindowMenu[9]);
   // Draw Text
   NE_TextPrintFree(0,31,15,NE_White,"Open this file?");
   NE_TextPrintFree(0,50,46,NE_White,menu_current_fname);
   NE_TextPrintFree(0,60,110,NE_White,"Yes");
   NE_TextPrintFree(0,60,130,NE_White,"Quit");
   // Stats
   NE_TextPrintFree(0,124,46,NE_White,Save[menu_current_file]->Player.name); // Player Name
   NE_TextPrintFree(0,65,83,NE_White,menu_current_fdeaths); // Player Deaths

   if(Save[menu_current_file]->HeartContainers.amount<11)
   {
      i=125;
      do
      {
         if(Save[menu_current_file]->GreatFairies.fairy6)
         {
            NE_2DDrawTexturedQuad(i, 66, i+16, 66+16, 5, MaterialMenuHearts2[0]);
         } else {
            NE_2DDrawTexturedQuad(i, 66, i+16, 66+16, 5, MaterialMenuHearts1[0]);
         }
         i+=8;
      }
      while(i!=(125+(Save[menu_current_file]->HeartContainers.amount*8)));
   }
   else
   {
      i=125;
      do
      {
         if(Save[menu_current_file]->GreatFairies.fairy6)
         {
            NE_2DDrawTexturedQuad(i, 66, i+16, 66+16, 5, MaterialMenuHearts2[0]);
         } else {
            NE_2DDrawTexturedQuad(i, 66, i+16, 66+16, 5, MaterialMenuHearts1[0]);
         }
         i+=8;
      }
      while(i!=206);
      
      i=125;
      do
      {   
         if(Save[menu_current_file]->GreatFairies.fairy6)
         {
            NE_2DDrawTexturedQuad(i, 74, i+16, 74+16, 5, MaterialMenuHearts2[0]);
         } else {
            NE_2DDrawTexturedQuad(i, 74, i+16, 74+16, 5, MaterialMenuHearts1[0]);
         }
         i+=8;
      }
      while(i!=(125+((Save[menu_current_file]->HeartContainers.amount-10))*8));
   }
   if(Save[menu_current_file]->SpiritualStones.kokiriEmerald==1)
   {
      NE_2DDrawTexturedQuad(48, 85, 48+32, 85+32, 5, MaterialMenuKokiriEmerald);
   }
   if(Save[menu_current_file]->SpiritualStones.goronRuby==1)
   {
      NE_2DDrawTexturedQuad(64, 85, 64+32, 85+32, 5, MaterialMenuGoronRuby);
   }
   if(Save[menu_current_file]->SpiritualStones.zoraSapphire==1)
   {
      NE_2DDrawTexturedQuad(80, 85, 80+32, 85+32, 5, MaterialMenuZoraSapphire);
   }
   if(Save[menu_current_file]->Medallions.forest==1)
   {
      NE_2DDrawTexturedQuad(98, 84, 98+32, 84+32, 5, MaterialMedallions[1]);
   }
   if(Save[menu_current_file]->Medallions.fire==1)
   {
      NE_2DDrawTexturedQuad(116, 84, 116+32, 84+32, 5, MaterialMedallions[0]);
   }
   if(Save[menu_current_file]->Medallions.water==1)
   {
      NE_2DDrawTexturedQuad(134, 84, 134+32, 84+32, 5, MaterialMedallions[2]);
   }
   if(Save[menu_current_file]->Medallions.shadow==1)
   {
      NE_2DDrawTexturedQuad(152, 84, 152+32, 84+32, 5, MaterialMedallions[3]);
   }
   if(Save[menu_current_file]->Medallions.spirit==1)
   {
      NE_2DDrawTexturedQuad(170, 84, 170+32, 84+32, 5, MaterialMedallions[4]);
   }
   if(Save[menu_current_file]->Medallions.light==1)
   {
      NE_2DDrawTexturedQuad(188, 84, 188+32, 84+32, 5, MaterialMedallions[5]);
   }
break;
//copy
case 3:
   // Windows
   for(i=0;i<4;i++)
   {
      NE_WindowDraw(WindowMenu[3+i]);
   }
   for(i=0;i<3;i++)
   {
      NE_WindowDraw(WindowMenu[9+i]);
   }
   // Text
   NE_TextPrintFree(0,31,15,NE_White,"Copy which file?");
   NE_TextPrintFree(0,50,95,NE_White,"File 1");
   NE_TextPrintFree(0,50,115,NE_White,"File 2");
   NE_TextPrintFree(0,50,135,NE_White,"File 3");
   NE_TextPrintFree(0,50,155,NE_White,"Quit");
   if(Save[0]->exists)
   {
      NE_TextPrintFree(0, 124, 95, NE_White, Save[0]->Player.name);
   }
   if(Save[1]->exists)
   {
      NE_TextPrintFree(0, 124, 115, NE_White, Save[1]->Player.name);
   }
   if(Save[2]->exists)
   {
      NE_TextPrintFree(0, 124, 135, NE_White, Save[2]->Player.name);
   }
   if(menu_current_button==0&&!Save[0]->exists)
   {
      NE_TextPrintFree(0, 115, 92, NE_White, "This is an empty file.");
   }
   if(menu_current_button==1&&!Save[1]->exists)
   {
      NE_TextPrintFree(0, 115, 112, NE_White, "This is an empty file.");
   }
   if(menu_current_button==2&&!Save[2]->exists)
   {
      NE_TextPrintFree(0, 115, 132, NE_White, "This is an empty file.");
   }
break;
//erase
case 4:
   // Windows
   for(i=0;i<4;i++)
   {
      NE_WindowDraw(WindowMenu[3+i]);
   }
   for(i=0;i<3;i++)
   {
      NE_WindowDraw(WindowMenu[9+i]);
   }
   // Text
   NE_TextPrintFree(0,31,15, NE_White, "Erase which file?");
   NE_TextPrintFree(0,50,95, NE_White,"File 1");
   NE_TextPrintFree(0,50,115, NE_White,"File 2");
   NE_TextPrintFree(0,50,135, NE_White,"File 3");
   NE_TextPrintFree(0,50,155, NE_White,"Quit");
   if(Save[0]->exists)
   {
      NE_TextPrintFree(0, 124, 95, NE_White, Save[0]->Player.name);
   }
   if(Save[1]->exists)
   {
      NE_TextPrintFree(0, 124, 115, NE_White, Save[1]->Player.name);
   }
   if(Save[2]->exists)
   {
      NE_TextPrintFree(0, 124, 135, NE_White, Save[2]->Player.name);
   }
   if(menu_current_button==0&&!Save[0]->exists)
   {
      NE_TextPrintFree(0, 115, 92, NE_White, "This is an empty file.");
   }
   if(menu_current_button==1&&!Save[1]->exists)
   {
      NE_TextPrintFree(0, 115, 112, NE_White, "This is an empty file.");
   }
   if(menu_current_button==2&&!Save[2]->exists)
   {
      NE_TextPrintFree(0, 115, 132, NE_White, "This is an empty file.");
   }
break;
//options
case 5:
   //Graphics
   NE_2DDrawTexturedQuad(44, 135, 44+256, 135+16, 5, MaterialCheckBrightness);
   NE_2DDrawTexturedQuad(44, 153, 44+256, 153+4, 5, MaterialOptionsLine);
   NE_2DDrawTexturedQuad(44, 56, 44+256, 56+4, 5, MaterialOptionsLine);
   NE_2DDrawTexturedQuad(44, 113, 44+256, 113+4, 5, MaterialOptionsLine);
   //Text
   NE_TextPrintFree(0, 31, 15, NE_White, "Options");
   NE_TextPrintFree(0, 44, 135, NE_White, "CHECK BRIGHTNESS");
   NE_TextPrintFree(0, 44, 38, NE_White, "SOUND");
   NE_TextPrintFree(0, 44, 59, NE_White, "Music\nEffects");
   if(game_music)
   {
      NE_TextPrintFree(0, 149, 59, NE_White, "On\nOff");
   } else {
      NE_TextPrintFree(0, 149, 59, NE_White, "Off\nOff");
   }
   NE_TextPrintFree(0, 44, 95, NE_White, "Z TARGETING");
   NE_TextPrintFree(0, 44, 126, NE_White, "Switch     Hold");
   option_isdrawing = true;
break;
//View Erase
case 6:
   //Windows
   NE_WindowDraw(WindowMenu[3]);
   NE_WindowDraw(WindowMenu[6]);
   NE_WindowDraw(WindowMenu[7]);
   NE_WindowDraw(WindowMenu[9]);
   //Text
   NE_TextPrintFree(0, 31, 15, NE_White,"Are you sure?");
   NE_TextPrintFree(0,50,46,NE_White,menu_current_fname);
   NE_TextPrintFree(0,60,130,NE_White,"Yes");
   NE_TextPrintFree(0,60,154,NE_White,"Quit");
   // Stats
   NE_TextPrintFree(0,124,46,NE_White,Save[menu_current_file]->Player.name); // Player Name
   NE_TextPrintFree(0,65,83,NE_White,menu_current_fdeaths); // Player Deaths

   if(Save[menu_current_file]->HeartContainers.amount<11)
   {
      i=125;
      do
      {
         if(Save[menu_current_file]->GreatFairies.fairy6)
         {
            NE_2DDrawTexturedQuad(i, 66, i+16, 66+16, 5, MaterialMenuHearts2[0]);
         } else {
            NE_2DDrawTexturedQuad(i, 66, i+16, 66+16, 5, MaterialMenuHearts1[0]);
         }
         i+=8;
      }
      while(i!=(125+(Save[menu_current_file]->HeartContainers.amount*8)));
   }
   else
   {
      i=125;
      do
      {
         if(Save[menu_current_file]->GreatFairies.fairy6)
         {
            NE_2DDrawTexturedQuad(i, 66, i+16, 66+16, 5, MaterialMenuHearts2[0]);
         } else {
            NE_2DDrawTexturedQuad(i, 66, i+16, 66+16, 5, MaterialMenuHearts1[0]);
         }
         i+=8;
      }
      while(i!=206);
      
      i=125;
      do
      {   
         if(Save[menu_current_file]->GreatFairies.fairy6)
         {
            NE_2DDrawTexturedQuad(i, 74, i+16, 74+16, 5, MaterialMenuHearts2[0]);
         } else {
            NE_2DDrawTexturedQuad(i, 74, i+16, 74+16, 5, MaterialMenuHearts1[0]);
         }
         i+=8;
      }
      while(i!=(125+((Save[menu_current_file]->HeartContainers.amount-10))*8));
   }
   if(Save[menu_current_file]->SpiritualStones.kokiriEmerald==1)
   {
      NE_2DDrawTexturedQuad(48, 85, 48+32, 85+32, 5, MaterialMenuKokiriEmerald);
   }
   if(Save[menu_current_file]->SpiritualStones.goronRuby==1)
   {
      NE_2DDrawTexturedQuad(64, 85, 64+32, 85+32, 5, MaterialMenuGoronRuby);
   }
   if(Save[menu_current_file]->SpiritualStones.zoraSapphire==1)
   {
      NE_2DDrawTexturedQuad(80, 85, 80+32, 85+32, 5, MaterialMenuZoraSapphire);
   }
   if(Save[menu_current_file]->Medallions.forest==1)
   {
      NE_2DDrawTexturedQuad(98, 84, 98+32, 84+32, 5, MaterialMedallions[1]);
   }
   if(Save[menu_current_file]->Medallions.fire==1)
   {
      NE_2DDrawTexturedQuad(116, 84, 116+32, 84+32, 5, MaterialMedallions[0]);
   }
   if(Save[menu_current_file]->Medallions.water==1)
   {
      NE_2DDrawTexturedQuad(134, 84, 134+32, 84+32, 5, MaterialMedallions[2]);
   }
   if(Save[menu_current_file]->Medallions.shadow==1)
   {
      NE_2DDrawTexturedQuad(152, 84, 152+32, 84+32, 5, MaterialMedallions[3]);
   }
   if(Save[menu_current_file]->Medallions.spirit==1)
   {
      NE_2DDrawTexturedQuad(170, 84, 170+32, 84+32, 5, MaterialMedallions[4]);
   }
   if(Save[menu_current_file]->Medallions.light==1)
   {
      NE_2DDrawTexturedQuad(188, 84, 188+32, 84+32, 5, MaterialMedallions[5]);
   }
break;
//Erasew Succeed
case 7:
   //Windows
   NE_WindowDraw(WindowMenu[3]);
   NE_WindowDraw(WindowMenu[6]);
   NE_WindowDraw(WindowMenu[7]);
   NE_WindowDraw(WindowMenu[9]);
   //Text
   NE_TextPrintFree(0, 31, 15, NE_White,"File Erased");
   NE_TextPrintFree(0,50,46,NE_White,menu_current_fname);
   NE_TextPrintFree(0,60,130,NE_White,"Yes");
   NE_TextPrintFree(0,60,154,NE_White,"Quit");
break;
case 8:
   //Windows
   NE_WindowDraw(WindowMenu[3]);
   //Text
   NE_TextPrintFree(0, 31, 15, NE_White,"File Erased");
   NE_TextPrintFree(0,50,46,NE_White,menu_current_fname);
break;
case 9:
   //Windows
   for(i=0;i<4;i++)
   {
      NE_WindowDraw(WindowMenu[3+i]);
   }
   for(i=0;i<3;i++)
   {
      NE_WindowDraw(WindowMenu[9+i]);
   }
   //Text
   NE_TextPrintFree(0, 31, 15, NE_White, "Copy to which file?");
   NE_TextPrintFree(0, 50, 46, NE_White, menu_current_fname);
   NE_TextPrintFree(0, 50, 114, NE_White, menu_copy_sother1);
   NE_TextPrintFree(0, 50, 134, NE_White, menu_copy_sother2);
   NE_TextPrintFree(0, 50, 154, NE_White, "Quit");
   if(Save[menu_copy_other1]->exists)
   {
      NE_TextPrintFree(0, 124, 114, NE_White, Save[menu_copy_other1]->Player.name);
   }
   if(Save[menu_copy_other2]->exists)
   {
      NE_TextPrintFree(0, 124, 134, NE_White, Save[menu_copy_other2]->Player.name);
   }
   // Stats
   NE_TextPrintFree(0,124,46,NE_White,Save[menu_current_file]->Player.name); // Player Name
   NE_TextPrintFree(0,65,83,NE_White,menu_current_fdeaths); // Player Deaths

   if(Save[menu_current_file]->HeartContainers.amount<11)
   {
      i=125;
      do
      {
         if(Save[menu_current_file]->GreatFairies.fairy6)
         {
            NE_2DDrawTexturedQuad(i, 66, i+16, 66+16, 5, MaterialMenuHearts2[0]);
         } else {
            NE_2DDrawTexturedQuad(i, 66, i+16, 66+16, 5, MaterialMenuHearts1[0]);
         }
         i+=8;
      }
      while(i!=(125+(Save[menu_current_file]->HeartContainers.amount*8)));
   }
   else
   {
      i=125;
      do
      {
         if(Save[menu_current_file]->GreatFairies.fairy6)
         {
            NE_2DDrawTexturedQuad(i, 66, i+16, 66+16, 5, MaterialMenuHearts2[0]);
         } else {
            NE_2DDrawTexturedQuad(i, 66, i+16, 66+16, 5, MaterialMenuHearts1[0]);
         }
         i+=8;
      }
      while(i!=206);
      
      i=125;
      do
      {   
         if(Save[menu_current_file]->GreatFairies.fairy6)
         {
            NE_2DDrawTexturedQuad(i, 74, i+16, 74+16, 5, MaterialMenuHearts2[0]);
         } else {
            NE_2DDrawTexturedQuad(i, 74, i+16, 74+16, 5, MaterialMenuHearts1[0]);
         }
         i+=8;
      }
      while(i!=(125+((Save[menu_current_file]->HeartContainers.amount-10))*8));
   }
   if(Save[menu_current_file]->SpiritualStones.kokiriEmerald==1)
   {
      NE_2DDrawTexturedQuad(48, 85, 48+32, 85+32, 5, MaterialMenuKokiriEmerald);
   }
   if(Save[menu_current_file]->SpiritualStones.goronRuby==1)
   {
      NE_2DDrawTexturedQuad(64, 85, 64+32, 85+32, 5, MaterialMenuGoronRuby);
   }
   if(Save[menu_current_file]->SpiritualStones.zoraSapphire==1)
   {
      NE_2DDrawTexturedQuad(80, 85, 80+32, 85+32, 5, MaterialMenuZoraSapphire);
   }
   if(Save[menu_current_file]->Medallions.forest==1)
   {
      NE_2DDrawTexturedQuad(98, 84, 98+32, 84+32, 5, MaterialMedallions[1]);
   }
   if(Save[menu_current_file]->Medallions.fire==1)
   {
      NE_2DDrawTexturedQuad(116, 84, 116+32, 84+32, 5, MaterialMedallions[0]);
   }
   if(Save[menu_current_file]->Medallions.water==1)
   {
      NE_2DDrawTexturedQuad(134, 84, 134+32, 84+32, 5, MaterialMedallions[2]);
   }
   if(Save[menu_current_file]->Medallions.shadow==1)
   {
      NE_2DDrawTexturedQuad(152, 84, 152+32, 84+32, 5, MaterialMedallions[3]);
   }
   if(Save[menu_current_file]->Medallions.spirit==1)
   {
      NE_2DDrawTexturedQuad(170, 84, 170+32, 84+32, 5, MaterialMedallions[4]);
   }
   if(Save[menu_current_file]->Medallions.light==1)
   {
      NE_2DDrawTexturedQuad(188, 84, 188+32, 84+32, 5, MaterialMedallions[5]);
   }

   if(menu_current_button==0&&Save[menu_copy_other1]->exists)
   {
      NE_TextPrintFree(0, 115, 114, NE_White, "This file is in use.");
   }
   if(menu_current_button==1&&Save[menu_copy_other2]->exists)
   {
      NE_TextPrintFree(0, 115, 134, NE_White, "This file is in use.");
   }
break;
case 10:
   NE_WindowDraw(WindowMenu[3]);
   NE_WindowDraw(WindowMenu[4]);
   NE_WindowDraw(WindowMenu[6]);
   NE_WindowDraw(WindowMenu[7]);
   NE_WindowDraw(WindowMenu[9]);
   // Draw Text
   NE_TextPrintFree(0,31,15,NE_White,"Open this file?");
   NE_TextPrintFree(0,50,46,NE_White,menu_current_fname);
   NE_TextPrintFree(0,50,108,NE_White,menu_stocopy);
   NE_TextPrintFree(0,60,130,NE_White,"Yes");
   NE_TextPrintFree(0,60,154,NE_White,"Quit");
   // Stats
   NE_TextPrintFree(0,124,46,NE_White,Save[menu_current_file]->Player.name); // Player Name
   NE_TextPrintFree(0,65,83,NE_White,menu_current_fdeaths); // Player Deaths

   if(Save[menu_current_file]->HeartContainers.amount<11)
   {
      i=125;
      do
      {
         if(Save[menu_current_file]->GreatFairies.fairy6)
         {
            NE_2DDrawTexturedQuad(i, 66, i+16, 66+16, 5, MaterialMenuHearts2[0]);
         } else {
            NE_2DDrawTexturedQuad(i, 66, i+16, 66+16, 5, MaterialMenuHearts1[0]);
         }
         i+=8;
      }
      while(i!=(125+(Save[menu_current_file]->HeartContainers.amount*8)));
   }
   else
   {
      i=125;
      do
      {
         if(Save[menu_current_file]->GreatFairies.fairy6)
         {
            NE_2DDrawTexturedQuad(i, 66, i+16, 66+16, 5, MaterialMenuHearts2[0]);
         } else {
            NE_2DDrawTexturedQuad(i, 66, i+16, 66+16, 5, MaterialMenuHearts1[0]);
         }
         i+=8;
      }
      while(i!=206);
      
      i=125;
      do
      {   
         if(Save[menu_current_file]->GreatFairies.fairy6)
         {
            NE_2DDrawTexturedQuad(i, 74, i+16, 74+16, 5, MaterialMenuHearts2[0]);
         } else {
            NE_2DDrawTexturedQuad(i, 74, i+16, 74+16, 5, MaterialMenuHearts1[0]);
         }
         i+=8;
      }
      while(i!=(125+((Save[menu_current_file]->HeartContainers.amount-10))*8));
   }
   if(Save[menu_current_file]->SpiritualStones.kokiriEmerald==1)
   {
      NE_2DDrawTexturedQuad(48, 85, 48+32, 85+32, 5, MaterialMenuKokiriEmerald);
   }
   if(Save[menu_current_file]->SpiritualStones.goronRuby==1)
   {
      NE_2DDrawTexturedQuad(64, 85, 64+32, 85+32, 5, MaterialMenuGoronRuby);
   }
   if(Save[menu_current_file]->SpiritualStones.zoraSapphire==1)
   {
      NE_2DDrawTexturedQuad(80, 85, 80+32, 85+32, 5, MaterialMenuZoraSapphire);
   }
   if(Save[menu_current_file]->Medallions.forest==1)
   {
      NE_2DDrawTexturedQuad(98, 84, 98+32, 84+32, 5, MaterialMedallions[1]);
   }
   if(Save[menu_current_file]->Medallions.fire==1)
   {
      NE_2DDrawTexturedQuad(116, 84, 116+32, 84+32, 5, MaterialMedallions[0]);
   }
   if(Save[menu_current_file]->Medallions.water==1)
   {
      NE_2DDrawTexturedQuad(134, 84, 134+32, 84+32, 5, MaterialMedallions[2]);
   }
   if(Save[menu_current_file]->Medallions.shadow==1)
   {
      NE_2DDrawTexturedQuad(152, 84, 152+32, 84+32, 5, MaterialMedallions[3]);
   }
   if(Save[menu_current_file]->Medallions.spirit==1)
   {
      NE_2DDrawTexturedQuad(170, 84, 170+32, 84+32, 5, MaterialMedallions[4]);
   }
   if(Save[menu_current_file]->Medallions.light==1)
   {
      NE_2DDrawTexturedQuad(188, 84, 188+32, 84+32, 5, MaterialMedallions[5]);
   }
break;
case 11:
   NE_WindowDraw(WindowMenu[3]);
   NE_WindowDraw(WindowMenu[4]);
   NE_WindowDraw(WindowMenu[9]);
   NE_WindowDraw(WindowMenu[10]);
   // Draw Text
   NE_TextPrintFree(0,31,15,NE_White,"File copied.");
   NE_TextPrintFree(0,50,46,NE_White,menu_current_fname);
   // Stats
   NE_TextPrintFree(0,124,46,NE_White,Save[menu_current_file]->Player.name); // Player Name
   NE_TextPrintFree(0,65,83,NE_White,menu_current_fdeaths); // Player Deaths

   if(Save[menu_current_file]->HeartContainers.amount<11)
   {
      i=125;
      do
      {
         if(Save[menu_current_file]->GreatFairies.fairy6)
         {
            NE_2DDrawTexturedQuad(i, 66, i+16, 66+16, 5, MaterialMenuHearts2[0]);
         } else {
            NE_2DDrawTexturedQuad(i, 66, i+16, 66+16, 5, MaterialMenuHearts1[0]);
         }
         i+=8;
      }
      while(i!=(125+(Save[menu_current_file]->HeartContainers.amount*8)));
   }
   else
   {
      i=125;
      do
      {
         if(Save[menu_current_file]->GreatFairies.fairy6)
         {
            NE_2DDrawTexturedQuad(i, 66, i+16, 66+16, 5, MaterialMenuHearts2[0]);
         } else {
            NE_2DDrawTexturedQuad(i, 66, i+16, 66+16, 5, MaterialMenuHearts1[0]);
         }
         i+=8;
      }
      while(i!=206);
      
      i=125;
      do
      {   
         if(Save[menu_current_file]->GreatFairies.fairy6)
         {
            NE_2DDrawTexturedQuad(i, 74, i+16, 74+16, 5, MaterialMenuHearts2[0]);
         } else {
            NE_2DDrawTexturedQuad(i, 74, i+16, 74+16, 5, MaterialMenuHearts1[0]);
         }
         i+=8;
      }
      while(i!=(125+((Save[menu_current_file]->HeartContainers.amount-10))*8));
   }
   if(Save[menu_current_file]->SpiritualStones.kokiriEmerald==1)
   {
      NE_2DDrawTexturedQuad(48, 85, 48+32, 85+32, 5, MaterialMenuKokiriEmerald);
   }
   if(Save[menu_current_file]->SpiritualStones.goronRuby==1)
   {
      NE_2DDrawTexturedQuad(64, 85, 64+32, 85+32, 5, MaterialMenuGoronRuby);
   }
   if(Save[menu_current_file]->SpiritualStones.zoraSapphire==1)
   {
      NE_2DDrawTexturedQuad(80, 85, 80+32, 85+32, 5, MaterialMenuZoraSapphire);
   }
   if(Save[menu_current_file]->Medallions.forest==1)
   {
      NE_2DDrawTexturedQuad(98, 84, 98+32, 84+32, 5, MaterialMedallions[1]);
   }
   if(Save[menu_current_file]->Medallions.fire==1)
   {
      NE_2DDrawTexturedQuad(116, 84, 116+32, 84+32, 5, MaterialMedallions[0]);
   }
   if(Save[menu_current_file]->Medallions.water==1)
   {
      NE_2DDrawTexturedQuad(134, 84, 134+32, 84+32, 5, MaterialMedallions[2]);
   }
   if(Save[menu_current_file]->Medallions.shadow==1)
   {
      NE_2DDrawTexturedQuad(152, 84, 152+32, 84+32, 5, MaterialMedallions[3]);
   }
   if(Save[menu_current_file]->Medallions.spirit==1)
   {
      NE_2DDrawTexturedQuad(170, 84, 170+32, 84+32, 5, MaterialMedallions[4]);
   }
   if(Save[menu_current_file]->Medallions.light==1)
   {
      NE_2DDrawTexturedQuad(188, 84, 188+32, 84+32, 5, MaterialMedallions[5]);
   }
   //Draw Text
   NE_TextPrintFree(0,50,104,NE_White,menu_current_fname);
   // Stats
   NE_TextPrintFree(0,124,104,NE_White,Save[menu_current_file]->Player.name); // Player Name
   NE_TextPrintFree(0,65,126,NE_White,menu_current_fdeaths); // Player Deaths

   if(Save[menu_current_file]->HeartContainers.amount<11)
   {
      i=125;
      do
      {
         if(Save[menu_current_file]->GreatFairies.fairy6)
         {
            NE_2DDrawTexturedQuad(i, 126, i+16, 126+16, 5, MaterialMenuHearts2[0]);
         } else {
            NE_2DDrawTexturedQuad(i, 126, i+16, 126+16, 5, MaterialMenuHearts1[0]);
         }
         i+=8;
      }
      while(i!=(125+(Save[menu_current_file]->HeartContainers.amount*8)));
   }
   else
   {
      i=125;
      do
      {
         if(Save[menu_current_file]->GreatFairies.fairy6)
         {
            NE_2DDrawTexturedQuad(i, 126, i+16, 126+16, 5, MaterialMenuHearts2[0]);
         } else {
            NE_2DDrawTexturedQuad(i, 126, i+16, 126+16, 5, MaterialMenuHearts1[0]);
         }
         i+=8;
      }
      while(i!=206);
      
      i=125;
      do
      {   
         if(Save[menu_current_file]->GreatFairies.fairy6)
         {
            NE_2DDrawTexturedQuad(i, 134, i+16, 134+16, 5, MaterialMenuHearts2[0]);
         } else {
            NE_2DDrawTexturedQuad(i, 134, i+16, 134+16, 5, MaterialMenuHearts1[0]);
         }
         i+=8;
      }
      while(i!=(125+((Save[menu_current_file]->HeartContainers.amount-10))*8));
   }
   if(Save[menu_current_file]->SpiritualStones.kokiriEmerald==1)
   {
      NE_2DDrawTexturedQuad(48, 145, 48+32, 145+32, 5, MaterialMenuKokiriEmerald);
   }
   if(Save[menu_current_file]->SpiritualStones.goronRuby==1)
   {
      NE_2DDrawTexturedQuad(64, 145, 64+32, 145+32, 5, MaterialMenuGoronRuby);
   }
   if(Save[menu_current_file]->SpiritualStones.zoraSapphire==1)
   {
      NE_2DDrawTexturedQuad(80, 145, 80+32, 145+32, 5, MaterialMenuZoraSapphire);
   }
   if(Save[menu_current_file]->Medallions.forest==1)
   {
      NE_2DDrawTexturedQuad(98, 144, 98+32, 144+32, 5, MaterialMedallions[1]);
   }
   if(Save[menu_current_file]->Medallions.fire==1)
   {
      NE_2DDrawTexturedQuad(116, 144, 116+32, 144+32, 5, MaterialMedallions[0]);
   }
   if(Save[menu_current_file]->Medallions.water==1)
   {
      NE_2DDrawTexturedQuad(134, 144, 134+32, 144+32, 5, MaterialMedallions[2]);
   }
   if(Save[menu_current_file]->Medallions.shadow==1)
   {
      NE_2DDrawTexturedQuad(152, 144, 152+32, 144+32, 5, MaterialMedallions[3]);
   }
   if(Save[menu_current_file]->Medallions.spirit==1)
   {
      NE_2DDrawTexturedQuad(170, 144, 170+32, 144+32, 5, MaterialMedallions[4]);
   }
   if(Save[menu_current_file]->Medallions.light==1)
   {
      NE_2DDrawTexturedQuad(188, 144, 188+32, 144+32, 5, MaterialMedallions[5]);
   }
break;
}


case 5 doesn't draw anything and I check if it is called and yes it is called.
_________________
Website / Blog

Let the nds be with you.

#168139 - AntonioND - Fri Apr 10, 2009 8:45 pm

You could have attached it, or just copy the part with the problem. ^_^U

Try putting this after the case label:
Code:
NE_PolyFormat(31, 0,0,NE_CULL_NONE,0);

I think you are drawing the text with the same poly id than the background. With that you'll reset the alpha value to 31 and set poly id to 0. If you want to make it transparent, you'll have to change its poly id, anyway. The reason why the other cases are working ok is that the window drawing function changes the poly id and the alpha value.

#169015 - hacker013 - Tue Jun 09, 2009 6:15 pm

thx, it worked and how far are you with the new release ?
_________________
Website / Blog

Let the nds be with you.

#169022 - AntonioND - Tue Jun 09, 2009 7:34 pm

hacker013 wrote:
thx, it worked and how far are you with the new release ?

Well... I've implemented a new animated model system so as to use linear interpolation between frames. This needs some CPU time, but the result is a lot better than before and models need less space (but you'll have to convert them again). I've renamed the window system to sprite system and I'm going to add animations, maybe. I'm not sure about doing that... I've made some small changes and fixes, and I've added an option to compile NE with a lot of error checking so as to check if you are passing NULL pointers to functions or using too big values. Anyway, my holidays starts this thursday, so you can expect a new release soon. ^_^

#169023 - hacker013 - Tue Jun 09, 2009 7:42 pm

thank you very much, but can add support for md2 files with multiple objects inside ?
_________________
Website / Blog

Let the nds be with you.

#169025 - AntonioND - Tue Jun 09, 2009 7:58 pm

An md2 file can't have different objects... Take a look at this:
http://tfc.duke.free.fr/coding/md2-specs-en.html
If you don't see some part of your models, it's because of the exporter. I just use the data inside of the md2 file.

#169032 - hacker013 - Wed Jun 10, 2009 7:32 am

I readed a other md2 spec and there was said that a md2 file could contain multiple animations ........ (source)
_________________
Website / Blog

Let the nds be with you.

#169036 - kusma - Wed Jun 10, 2009 11:35 am

hacker013 wrote:
I readed a other md2 spec and there was said that a md2 file could contain multiple animations ........ (source)

Animations != objects. And it's multiple animation FRAMES that is being discussed, as far as I can tell.

Notice that your source is an older document from the same author as the one AntonioND linked to. Also, I can't see anything suggesting that there can be multiple objects. There can be multiple skins (or textures), was this what you meant?

#169039 - hacker013 - Wed Jun 10, 2009 5:17 pm

no objects because the models build by my model maker are md2 containing multiple objects and multiple textures assigned to those objects (on a pc) but I don't see how I can do this with your engine (showing those because I see nowere support for objects)?
_________________
Website / Blog

Let the nds be with you.

#169044 - AntonioND - Wed Jun 10, 2009 7:33 pm

If md2 format doesn't allow multiple objects, you just can't export multiple objects in an md2 file... Your exporter will just ignore them and only export one.

#169305 - hacker013 - Tue Jun 30, 2009 6:40 pm

Ok, and have you now a new version of Nitro Engine :) ?
_________________
Website / Blog

Let the nds be with you.

#169306 - AntonioND - Tue Jun 30, 2009 6:51 pm

Actually, I'm finishing the new version. I'm testing it to make sure the new changes don't break anything... So... In a few days I'll release it.


EDIT:

New release, version 0.6.0:

-The functions used to modify textures and palettes now return a pointer to the data so that you can modify them easily.
-Each material can have different propierties (amient, diffuse...). You can set the default ones, the propierties each new material will have, and then you can set each material's propierties individually.
-New texture and palette allocation system, it is faster and better. Defragmenting functions don't work now, but I'll fix them for the next version.
-Added a debug system. You can compile Nitro Engine in "debug mode" and it will send error messages to the function you want. Once you have finished debugging or whatever, just recompile Nitro Engine without debug mode.
-Window system renamed to Sprite system. You can set a rotation and a scale for each one.
-The most important thing... The animation system has been improved, and now animated models are drawn using linear interpolation (you can disable it, anyway).
-As a result, I've modified the converters, so you'll have to convert yout animated models again.

Well... That's it.

#169450 - hacker013 - Sat Jul 11, 2009 12:07 pm

Why has are the animation structs moved form the model.h to general.h ? This only causes errors in model.h >.>
_________________
Website / Blog

Let the nds be with you.

#169472 - AntonioND - Tue Jul 14, 2009 4:31 pm

hacker013 wrote:
Why has are the animation structs moved form the model.h to general.h ? This only causes errors in model.h >.>

Don't include that file in your source, include NEMain.h.

#169476 - hacker013 - Wed Jul 15, 2009 6:29 pm

I only include NEMain.h but because NEModel.h doesn't include anything it doesn't know that the animation structs are defined already, i moved them back to NEModel.h and everything is working again ...
_________________
Website / Blog

Let the nds be with you.

#169477 - AntonioND - Wed Jul 15, 2009 6:54 pm

Everything is working fine for me the way I uploaded it... I only removed them from that file because I'm going to use them for a (future) sprite animation system.

#169497 - Darkflame - Fri Jul 17, 2009 8:57 pm

nice work!
_________________
Darkflames Reviews --
Make your own at;
Rateoholic:Reviews for anything, by anyone.

#169802 - hacker013 - Tue Aug 04, 2009 1:06 pm

What can we expect on the next release ?
_________________
Website / Blog

Let the nds be with you.

#169946 - AntonioND - Mon Aug 17, 2009 3:53 pm

hacker013 wrote:
What can we expect on the next release ?

Any ideas to include to Nitro Engine, apart from the animated sprites system?

#169956 - hacker013 - Tue Aug 18, 2009 9:30 am

I have some ideas, a direct md2 loader instead of that converter thingy.
Also support for jpeg/gif/png files, i have made that but a native support from the author would be great. Make it an all around game engine with also sound, wifi, movie support :), maybe you can beat palib with it ;)
_________________
Website / Blog

Let the nds be with you.

#169970 - AntonioND - Wed Aug 19, 2009 7:50 pm

hacker013 wrote:
I have some ideas, a direct md2 loader instead of that converter thingy.
Also support for jpeg/gif/png files, i have made that but a native support from the author would be great. Make it an all around game engine with also sound, wifi, movie support :), maybe you can beat palib with it ;)

MD2 loader -> uhmmm... no... it uses floats all time, it is better to convert md2 files into display lists (md2_to_bin) or in another (and simpler) format (md2_to_nea). Doing that conversion would take some time and it would make NE need more space.
png/jpg/blah -> maybe... In fact, I was thinking about removing the bmp loader...

the rest -> just no.
For wifi, dswifi; sound, maxmod.. Movies... no idea. I don't want to add lots of things, I think it is better that the coder choose the right lib for these things.

#170036 - renatobs - Mon Aug 24, 2009 4:13 pm

Well, I?d like to learn about NE. How and where could I started ? Have some easy way to get the ideia of all ? I know to do some 3D things in Blender, but I don?t know what?s the better size of models, textures and other things that I can do there and transfer to NE.... I?d like to learn about everything of NE, how to do a model in Blender, for example, and convert to NE and after to use this in emulator and a real NDS... I?m developing a NDS game, but all things are in 2D, but I?d like to put some 3D things, like little scenes...
Could some one give me instructions about ....
Thanks.

#170098 - hacker013 - Sun Aug 30, 2009 4:19 pm

Please leave the bmp loader because it is now easy to use texture and people can edit the textures for you without to have converting everyting, why would you do that if that isn't nessesary O_o. Maybe you could make this engine plit up in module so you can download only the nessary modules. So you only have to use some defines to define which modules are just to spare more size and can add much more features to this engine without getting the engine to large.
_________________
Website / Blog

Let the nds be with you.

#170101 - kusma - Sun Aug 30, 2009 6:15 pm

hacker013 wrote:
Please <snip>

Since NitroEngine is open source, you can always do the changes yourself, and submit a patch. Getting patches usually helps motivating maintainers, and keeps development going :)

#170415 - tine622 - Tue Sep 22, 2009 6:38 am

Hello, I have been playing with this library a bit and for the life of me cannot figure out how to load one of my own textures and map it onto a quad. I tried to modify "TextureDrawing" example and all I am getting is the colored quad with no image.

Is there any place that outlines what to do? What texture converter to use from the tools lib, etc.

Thanks for your help.
Mark Carpenter

#170416 - hacker013 - Tue Sep 22, 2009 7:01 am

First of all you can just use bmp files as textures or even .png/.gif/.jpeg if you use my modificated libpicture for it.

The second dit you use NE_DrawQuadTextured O_o? Just look in de NE_2D.h :)
_________________
Website / Blog

Let the nds be with you.

#171183 - iainprice - Wed Nov 04, 2009 9:37 pm

Can you use this engine for an object rolling or sliding across a terrain.... have a set of polys that use the collision detection abd response rather than using bounding boxs or spheres?

#171184 - AntonioND - Wed Nov 04, 2009 10:09 pm

No, and don't even try to use the included "physics engine", it's really bad and it will be useless for you.

#171219 - tine622 - Sat Nov 07, 2009 4:03 am

Hello,
I made a post earlier about a texture issue that I still haven't been able to resolve. My issue is this. I have a md2 model and texture bmp(49kb) that load well in MilkShap3D. I run the MD2_2_BIN program on the md2 model (and have to scale it to .01) and include the bmp into the app (bin2o). I load the model using the SimpleModel tutorial. When I do not attach the texture the model shows up fine. When I try to NE_ModelSetMaterial(Model, Material); The screen only shows black. To load the texture im using: NE_MaterialTexLoadBMPtoRGBA(Material,(void*)crate_texture_bmp,0);
I tested this call in another tutorial and it worked well.

Could the texture mapping be messed up by the scaling that is done by the MD2_2_BIN program?

Thanks