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 > Stuck on graphic mode requirements for lisp parser

#139217 - Ollie - Mon Sep 03, 2007 5:31 pm

Hi, not long ago I made a quick little lisp-like parser/enterpretter on the PC which was an interesting little toy. Out of interest I decided to quickly port it to the DS today and it worked fine. However, I thought it would be cool if you could make little graphical applications with it...

Here is where I run into my problem. I'm a pc programmer and my knowledge of console programming is mind-bogglingly poor. I do not know what to do with all these VRAM settings and the such, so here is where I request some assistance.

When the user presses the right shoulder button it enables "game mode", which basically tells my lisp enterpretter to execute the line:

(main "placeholder\n")

- in an infinate loop until the start key is pressed. This will act as a main game loop, as main can be defined by the user.

However, the DS is currently running console on the top screen and a keyboard on the bottom screen. What I would like to do is to set the bottom screen to enable per-pixel drawing so I can make a double-buffer system. I have no idea how to mess with the drawing modes like this...

So, would anyone mind helping me out? I will paste my main.cpp below, it is not too long and hopefully should be fairly simple to understand:

Code:

#include <nds.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <string>

#include <nds/arm9/console.h> //basic print funcionality
#include "keyboard.h"
#include "lisp_parse.h"

#define ECHO_ON    0
#define ECHO_OFF 1

#define MAX_TEXT 256

bool game_mode;

void waitForVBlank(void)
{
   while(!(REG_DISPSTAT & DISP_IN_VBLANK));
   while((REG_DISPSTAT & DISP_IN_VBLANK));
}

int main(void)
{
   game_mode = false;

   videoSetMode(MODE_0_2D | DISPLAY_BG0_ACTIVE);   // bg 0 will be used to print text
   videoSetModeSub(MODE_0_2D | DISPLAY_BG0_ACTIVE);
   vramSetBankA(VRAM_A_MAIN_BG);
   vramSetBankC(VRAM_C_SUB_BG);

   BG0_CR = BG_MAP_BASE(31);

   BG_PALETTE[255] = RGB15(31,31,31);   //by default font will be rendered with color 255

   //consoleInit() is a lot more flexible but this gets you up and running quick
   consoleInitDefault((u16*)SCREEN_BASE_BLOCK(31), (u16*)CHAR_BASE_BLOCK(0), 16);
   
   initKeyboard();
   
   iprintf("> ");
   
   char str[MAX_TEXT] = "";
   std::string input;
   lispToken ret;             //This is just me setting up the lisp stuff.
   lispProgram prog("");
   lispLoadDefault(prog);
   lispEnableVars(prog);
   lispEnableString(prog);

   while(input != "quit")
   {
      scanKeys();
      
      if((keysHeld() & KEY_R) && !game_mode)   // for enabling game mode
      {
         printf("\nGame mode:\n");
         game_mode = true;
      }
      
      if(game_mode)                 // game mode, will clear the screen
      {                             // then it will set the lower screen to be able to use double-buffering
         for(int i = 0; i < 256*192; ++i)
         {
            VRAM_C[i] = RGB15(0,0,0) | 0x8000;   //clear the bottom screen? :S Beyond me.
         }
         
         while(!(keysHeld() & KEY_START))        // infinately executes "(main "placeholder\n")" until start is pressed
         {
            scanKeys();
            prog.do_line("(main \"placeholder\")");
         }
         
         printf("Programming mode:\n> ");
         game_mode = false;
      }
      
      if(processKeyboard(&str[0], MAX_TEXT, ECHO_ON)=='\n')     //this is just the command-line enterpretting stuff
      {
         input = str;
         strcpy(str,"");
         
         if(input != "quit")
         {
            ret = prog.do_line(input);
            std::cout << ret.text;
            
            if(ret.text[ret.text.size()-1] != '\n') std::cout << std::endl;
            
            printf("> ");
         }
      }

      waitForVBlank();
   }
   
   printf("Exited!");

   return 0;
}


Thank you for reading this :)

#139226 - DragonMinded - Mon Sep 03, 2007 6:55 pm

If you simply wanted double buffered mode, you could set up the sub screen to use a dual ex-rot mode. Each has a simple 256x256 drawing surface, and you can set the priority on one or the other, instantly "flipping" the buffer. All you would have to do is keep a buffer cursor so that you knew which was in the back and flip when done drawing. The added benefit of an ex-rot buffer is that you can rotate and scale them as well.

I put together a demo of how this would work years ago when I was learning the stuff myself. The link is http://www.dragonminded.com/ndsdev/dualBG.rar and it incudes a .nds to play with as well as the source. It requires libfb to compile, but since the majority of the console code uses the sub screen to display anyhow, you could easily rip it out and replace it with a subscreen console.
_________________
Enter the mind of the dragon.

http://dragonminded.blogspot.com

Seriously guys, how hard is it to simply TRY something yourself?