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 > some questions and strange if statement behavior?

#41133 - rize - Mon Apr 25, 2005 8:56 pm

I was playing with the hello world demo (using dualis) and trying out a few things.

First let me ask a few basic questions. I thought I read somewhere that only the ARM7 can retrieve touch input, yet there is no ARM7 code in this demo and it is getting touch input via IPC->touchX etc. Am I misunderstanding something?

Second, the first line sets the video mode and is commented "not using the main screen". However, I thought video mode was set independantly of screen. I enabled the main screen as well without changing the video mode and there seems to be no problems.

Third, is there a trunc or round function somewhere? If not, is there a better method than what I used below (aside from putting that mess into a macro of course).

[edit: the problem below is solved... go ahead and laugh, I should have known better]

Anyway, onto the strange if behavior. I'm taking the uncalibrated touch input storing it in integers tx and ty and using the following:

Code:
tx = tx/14;
ty = f32toint(floatof32((float)(IPC->touchY)/(float)17.508))-14;


... to recalibrate the touch input for dualis. It apparently works great giving me X values from 1 to 256 and Y values from 1 to 192. However the minus 14 caused the Y value to default to -14 instead of 0. So I threw an if statement in... just to make it look nice.

Code:
if (ty = -14) ty = 0;


For some reason the branch is never taken and ty is set to 0 no matter where I touch the (emulated) screen. I even checked the hex value and tried:

Code:
if (ty = 0xFFFFFFF2) ty = 0;


That doesn't work either. However, the following three if statements work fine:

Code:
if (ty != -14); else ty = 0;

if (ty > 0); else ty = 0;

if (ty < 1) ty = 0; //I should have used this one to begin with


To verify that the touch input is what I think it should be, I'm printing the results out in dec and hex and also modifying the screen colors depending on the values of tx and ty. Everything works perfectly except the original two if statements. The problem occurs on dualis and ideas.

I figure its either some subtle syntax or type problem or else some kind of compiler error.

Here's the complete modified helloworld code I'm using:

Code:

//////////////////////////////////////////////////////////////////////
// Simple consol print demo
// -- dovoto (modified by rize)
//////////////////////////////////////////////////////////////////////

#include <NDS/NDS.h>

#include <NDS/ARM9/console.h> //basic print funcionality

int main(void)
{
   videoSetMode(0); //not using the main screen
   //\\rize: afiak, video mode has nothing to do with a particular screen
   
      //sub bg 0 will be used to print text   
   videoSetModeSub(MODE_0_2D | DISPLAY_BG0_ACTIVE);
   vramSetBankC(VRAM_C_SUB_BG);
   SUB_BG0_CR = BG_MAP_BASE(31);   
   
     //main screen initialized as well
   videoSetMode(MODE_0_2D | DISPLAY_BG0_ACTIVE);        
   vramSetBankC(VRAM_C_MAIN_BG);
   BG0_CR = BG_MAP_BASE(31);      

     //set up the SUB palette just once (i0 for BG i255 for text color)
   BG_PALETTE_SUB[0] = RGB15(31,31,31);    
   BG_PALETTE_SUB[255] = RGB15(0,0,0);   

       while(1)
   {
      int tx, ty;   
   
      consoleInitDefault((u16*)SCREEN_BASE_BLOCK_SUB(31),
                     (u16*)CHAR_BASE_BLOCK_SUB(0), 16);         
      consolePrintSet(0,0);      
      consolePrintf("\n   Hello World - Hijacked\n");
      
      tx = IPC->touchX/14;
      ty = f32toint(floatof32((float)(IPC->touchY)/(float)17.508))-14;
//      if (ty = -14) ty = 0;
//      if (ty = 0xFFFFFFF2) ty = 0;
//      if (ty != -14); else ty = 0;
//      if (ty >= 1); else ty = 0;
      if (ty < 1) ty = 0;
      
      consolePrintSet(0,10);      
      consolePrintf(" DEC Touch x =  %d      \n", tx);
      consolePrintf(" DEC Touch y =  %d      \n\n", ty);      
      consolePrintf(" HEX Touch x =  %X      \n", tx);
      consolePrintf(" HEX Touch y =  %X      \n\n", ty);            

          //BG based on touch input; text inverse of BG
      BG_PALETTE[0] = RGB15(tx/9, (tx+ty)/15, ty/7);
      BG_PALETTE[255] = ~BG_PALETTE[0] & (0xFFFF >> 1);
      
      consoleInitDefault((u16*)SCREEN_BASE_BLOCK(31),
                           (u16*)CHAR_BASE_BLOCK(0), 16);               
      consolePrintSet(0,22);
      consolePrintf(" BG COLOR = %04X\n", BG_PALETTE[0]);      
   }
   return 0;
}


Last edited by rize on Mon Apr 25, 2005 11:55 pm; edited 3 times in total

#41134 - Cleon I - Mon Apr 25, 2005 9:14 pm

= is assignment in C, ty = -14 stores 14 into ty. It always returns the value of ty. You want equality, ==, which returns a boolean (actually an integer that's either 1 or 0, but it's the same difference).

#41136 - rize - Mon Apr 25, 2005 9:38 pm

Well, at least I made over 30 people laugh their asses off! I can't believe I missed that, thanks.

If anyone would be so kind as to answer my first three questions I would appreciate it.

#41137 - Sebbo - Mon Apr 25, 2005 9:50 pm

the hello world example in your ndslib\examples folder does have arm7 code that sits there and monitors the touchpad among other things and sends the data to the arm9

Code:

//////////////////////////////////////////////////////////////////////
// Simple ARM7 stub (sends RTC, TSC, and X/Y data to the ARM 9)
// -- joat
//////////////////////////////////////////////////////////////////////

#include <NDS/NDS.h>

#include <NDS/ARM7/BIOS.h>
#include <NDS/ARM7/touch.h>
#include <NDS/ARM7/clock.h>

//////////////////////////////////////////////////////////////////////

void InterruptHandler(void) {
  int t1, t2;
  static int heartbeat = 0;

  if (IF & IRQ_VBLANK) {
    // Update the heartbeat
    heartbeat++;
    IPC->heartbeat = heartbeat;

    // Read the X/Y buttons and the /PENIRQ line
    IPC->buttons = XKEYS;

    // Read the touch screen
    IPC->touchX = touchRead(TSC_MEASURE_X);
    IPC->touchY = touchRead(TSC_MEASURE_Y);
    IPC->touchZ1 = touchRead(TSC_MEASURE_Z1);
    IPC->touchZ2 = touchRead(TSC_MEASURE_Z2);

    // Read the time
    rtcGetTime((uint8 *)IPC->curtime);
    BCDToInteger((uint8 *)&(IPC->curtime[1]), 7);
 
    // Read the temperature
    IPC->temperature = touchReadTemperature(t1, t2);
    IPC->tdiode1 = t1;
    IPC->tdiode2 = t2;
  }

  // Acknowledge interrupts
  IF = IF;
}

//////////////////////////////////////////////////////////////////////

int main(int argc, char ** argv) {
  // Reset the clock if needed
  rtcReset();

  // Set up the interrupt handler
  IME = 0;
  IRQ_HANDLER = &InterruptHandler;
  IE = IRQ_VBLANK;
  IF = ~0;
  DISP_SR = DISP_VBLANK_IRQ;
  IME = 1;

  // Keep the ARM7 out of main RAM
  while (1) swiWaitForVBlank();
  return 0;
}

//////////////////////////////////////////////////////////////////////


if your just using their example hello world code and modding that then that might be your answer, otherwise i'd guess that when you makefile it grabs an arm7 template that looks something like that *shrugs*

#41138 - rize - Mon Apr 25, 2005 10:05 pm

Ah, default arm7. Thank you I didn't notice that. It's probably included and linked in the makefile (or whatever). Thanks.

That just leaves the following two questions:

Devoto used this line in helloworld:

videoSetMode(0); //not using the main screen

I didn't think videoSetMode had anything to do with a particular screen though. And I didnt' set the mode again for the main screen which I have working in the modified demo.

Btw, don't worry about the trunc round thing. I'm going to start a new thread because I have a lot of questions about the DS fixed point formats.

#41140 - josath - Mon Apr 25, 2005 10:23 pm

there's:
videoSetMode(MODE) - sets the screen mode for the main screen
and
videoSetModeSub(MODE) - sets the screen mode for the sub screen.

the two screens are separate. also they can be swapped (so the top screen could be main and the bottom sub, or you could swap it with lcdSwap() and have the top be the sub and the bottom be the main)

#41142 - rize - Mon Apr 25, 2005 10:29 pm

in that case, the helloworld demo contains an error. It uses the sub screen (which appears as the top) but uses a call to videoSetMode which is for main.

I imagine it works becuase the mode defaults to 0 anyway.

#41150 - Cleon I - Mon Apr 25, 2005 11:48 pm

That sounds pretty similar to the issue of hardware/emulator differences discussed in this thread.

dovoto wrote:

what causes the LCD to 2D core mapping is somewhat missunderstood at the moment. By default (POWER_CR set to all on) the main is assigned to the bottom and sub to the top. Bit 15 of power control will cause them to swap...but other bits of power control also seem to cause this swapping as well as certain combinations of screenmodes. More specific details should surface in next few days. For now just check your power control setting and if it is correct:

#ifdef EMULATOR
lcdSwap();
#endif

ugly but works.


Maybe it's just an emulator problem? Do you have the ability to test on hardware to see if you get the same result?

#41152 - rize - Mon Apr 25, 2005 11:58 pm

Oh yeah; I understand that there are some issues about which screen is which and what the defaults are.

The error in dovoto's helloworld (unles I'm mistaken) is that he is setting up the screen marked as SUB but uses a call for the "MAIN" screen to set the video mode by accident.

Btw, I don't have the ability to use the DS itself yet (everyone's sold out of passthroughs!)

#41153 - josath - Tue Apr 26, 2005 12:05 am

i don't think you understand....he's calling:
Code:
        videoSetMode(0);

to turn off the main screen and then

Code:
        videoSetModeSub(MODE_0_2D | DISPLAY_BG0_ACTIVE);


to set the sub screen to 2D Mode, with BG0 active. He then draws on the sub screen, which is set up.

#41155 - rize - Tue Apr 26, 2005 12:17 am

Ah, I thought he was trying to set a mode FOR the sub screen. Thanks for clearing that up. The call to videoSetModeSub should have made that clear to me.

This is why I haven't moved beyond toying with Hello World yet... I didn't do any GBA dev so I'm still trying to master the basics.