TextOut y value

Discussion specific to NXT-G, NXC, NBC, RobotC, Lejos, and more.
mspall
Posts: 15
Joined: 31 Oct 2011, 19:29

Re: TextOut y value

Post by mspall »

This might be a better way to report this data, average ticks /TextOut()
.344 ticks/TextOut()
.430 ticks/TextOut()
1.08 ticks/TextOut()

How fast vs flexible do we want or need TextOut() to be?
mattallen37
Posts: 1818
Joined: 02 Oct 2010, 02:19
Location: Michigan USA
Contact:

Re: TextOut y value

Post by mattallen37 »

Well, I'm fine with half the speed it used to be. John said he used a crude method of setting the bits in the latest FW, that's probably why it's so slow. Now that he will be using bit-math on the whole 16 bits at once, it should be significantly faster than 1.08 ticks per draw.

I'm curious though, what if you set all the y values to LCD_LINE1-1, so to speak. Offset them all to some degree, and see if that effects the speed.
Matt
http://mattallen37.wordpress.com/

I'm all for gun control... that's why I use both hands when shooting ;)
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: TextOut y value

Post by HaWe »

...and BTW the speed when using ric fonts instead would be also interestring to see :)
afanofosc
Site Admin
Posts: 1256
Joined: 26 Sep 2010, 19:36
Location: Nashville, TN
Contact:

Re: TextOut y value

Post by afanofosc »

On my NXT with the not yet uploaded firmware image using Nicolas' code I get 5931. Latest compiler, optimization level 3. That seems pretty respectable.

John Hansen
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
afanofosc
Site Admin
Posts: 1256
Joined: 26 Sep 2010, 19:36
Location: Nashville, TN
Contact:

Re: TextOut y value

Post by afanofosc »

With this code I get 5931 followed much later by 63062:

Code: Select all

#download "tahoma8.ric"

task main()
{
  unsigned int i, s, f, diff;
  s = CurrentTick();
  for(int i=0; i<1000; i++) {
    TextOut(0,LCD_LINE1,"Cicero scripsit:");
    TextOut(0,LCD_LINE2,"Neque porro quisquam");
    TextOut(0,LCD_LINE3,"est, qui dolorem");
    TextOut(0,LCD_LINE4,"ipsum,quia dolor sit");
    TextOut(0,LCD_LINE5,"amet, consectetur,");
    TextOut(0,LCD_LINE6,"adipisci con velit-");
    TextOut(0,LCD_LINE7,"Sed Cicero");
    TextOut(0,LCD_LINE8,"erat iniuriam:");

    TextOut(0,LCD_LINE1,"Neque porro quisquam");
    TextOut(0,LCD_LINE2,"est, qui dolorem");
    TextOut(0,LCD_LINE3,"ipsum,quia dolor sit");
    TextOut(0,LCD_LINE4,"amet, consectetur,");
    TextOut(0,LCD_LINE5,"adipisci con velit-");
    TextOut(0,LCD_LINE6,"Sed Cicero");
    TextOut(0,LCD_LINE7,"erat iniuriam:");
    TextOut(0,LCD_LINE8,"Redundant est!");
  }
  f = CurrentTick();
  diff = f - s;
  ClearScreen();
  NumOut(0,LCD_LINE1,diff);
  Wait(SEC_5);
  s = CurrentTick();
  for(int i=0; i<1000; i++) {
    FontTextOut(0,LCD_LINE1,"tahoma8.ric", "Cicero scripsit:");
    FontTextOut(0,LCD_LINE2,"tahoma8.ric", "Neque porro quisquam");
    FontTextOut(0,LCD_LINE3,"tahoma8.ric", "est, qui dolorem");
    FontTextOut(0,LCD_LINE4,"tahoma8.ric", "ipsum,quia dolor sit");
    FontTextOut(0,LCD_LINE5,"tahoma8.ric", "amet, consectetur,");
    FontTextOut(0,LCD_LINE6,"tahoma8.ric", "adipisci con velit-");
    FontTextOut(0,LCD_LINE7,"tahoma8.ric", "Sed Cicero");
    FontTextOut(0,LCD_LINE8,"tahoma8.ric", "erat iniuriam:");

    FontTextOut(0,LCD_LINE1,"tahoma8.ric", "Neque porro quisquam");
    FontTextOut(0,LCD_LINE2,"tahoma8.ric", "est, qui dolorem");
    FontTextOut(0,LCD_LINE3,"tahoma8.ric", "ipsum,quia dolor sit");
    FontTextOut(0,LCD_LINE4,"tahoma8.ric", "amet, consectetur,");
    FontTextOut(0,LCD_LINE5,"tahoma8.ric", "adipisci con velit-");
    FontTextOut(0,LCD_LINE6,"tahoma8.ric", "Sed Cicero");
    FontTextOut(0,LCD_LINE7,"tahoma8.ric", "erat iniuriam:");
    FontTextOut(0,LCD_LINE8,"tahoma8.ric", "Redundant est!");
  }
  f = CurrentTick();
  diff = f - s;
  ClearScreen();
  NumOut(0,LCD_LINE1,diff);
  while(true);
}
FontTextOut is definitely much slower - but more flexible, for certain.

With offsets such as -1, -2, or -4 from the standard lines the TextOut result was around 6050.

John Hansen
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
schodet
Posts: 139
Joined: 29 Sep 2010, 11:21
Contact:

Re: TextOut y value

Post by schodet »

afanofosc wrote:If you have any ideas what I might be doing wrong with my JMPABSVAR opcode (and almost certainly the BRCMPABSVAR and BRTSTABSVAR opcodes) I'd be grateful for the assistance there as well. I'll check in the code later on tonight so you can have a look at it, if you are interested.
I think my compiler is generating the right value for the absolute address to jump to (which I am trying to convert into a relative jump offset) but I wind up getting a ERR_INSTR file abort.
This seems much more complicated than some bit logic :) but I can give it a try if I understand what it is supposed to do.
LEGO things http://ni.fr.eu.org/lego/ - NXT Improved Firmware (GCC) http://nxt-firmware.ni.fr.eu.org/ - Other robots http://apbteam.org
afanofosc
Site Admin
Posts: 1256
Joined: 26 Sep 2010, 19:36
Location: Nashville, TN
Contact:

Re: TextOut y value

Post by afanofosc »

I think it might be possible to speed up the copybits code for drawing RIC sprites. This is where I got the "iterate through each bit in the current font byte" logic from but the routine is structured in a way that makes it a little harder to switch to Nicolas' code inside the nested for loops. I think, though, that with a little thought we could improve this in a similar fashion. It may not need to use any masking across 2 lines like with the text drawing - except perhaps on the top row of the sprite data and the bottom row of the sprite data when that row is drawn at a Y value that is not a multiple of 8.

Code: Select all

void cCmdCopyBitMapBits(
  SLONG dst_x,  // left pixel on LCD
  SLONG dst_y,  // bottom pixel on LCD
  SLONG src_x,  // starting pixel x coordinate from source map
  SLONG src_y,  // starting pixel y coordinate from source map
  SLONG src_width, // width in pixels to the right (negative implies to the left)
  SLONG src_height, // height in pixels down (negative implies down)
  IMG_OP_SPRITE * pSprite, UBYTE InvertMode, UBYTE LogicalMode, UBYTE FillMode)
{
  SLONG dy;  // Location in the destination pixmap , the screen that is
  SLONG sx;
  SLONG sy;  // Location in the source pixmap.
  SLONG trim, last_x, last_y, rowbytes;
  UBYTE *pSrcByte;
  UBYTE srcByte;      //JJR
  UBYTE *pDstBytes;
  UBYTE *pDstByte, *pFirstDstByte;
  UBYTE *pLastDstByte;
  UBYTE bit_y;                //JJR
  UBYTE masks[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};

  // Data in the image file is row major 8 pixels per byte. top row first.
  // src and dst coordinates treat the bottom left most pixel as (0,0)

  if (!pSprite || pSprite->OpCode!=IMG_SPRITE_ID)
    return;

  pDstBytes = DISP_BUFFER_P;

  // Clip the edges. Modify the source and width as well.
  if (dst_x < 0) {        // bounds check start of x
    trim = (0 - dst_x);
    dst_x = 0;
    src_x += trim;
    src_width -= trim;
    }

  last_x = dst_x + src_width;
  if (last_x > DISPLAY_WIDTH)   // bound check end of x
    last_x = DISPLAY_WIDTH;

  if (dst_y < 0) {        // bound check start of y
    trim  = (0 - dst_y);
    dst_y = 0;
    src_y += trim;  // fix up source as well since we are clipping the start of the loop
    src_height -= trim;
    }

  last_y = dst_y + src_height;
  if (last_y > DISPLAY_HEIGHT)  // bound check end of y
    last_y = DISPLAY_HEIGHT;

  // Convert the 0,0 bottom left origin to the top left 0,0 used by the actual
  // buffer
  last_y = TRANSLATE_Y(last_y);
  dst_y = TRANSLATE_Y(dst_y);

  // The last row is the top most scan line in the LCD Buffer
  // so limit if the copy would copy into memory before the buffer.
  // The first row copied will be the one closest to the bottom of the LCD
  // If that is off screen then limit as well and adjust the start point on the start

  // Copy bits top to top moving down.
  sy = src_y;
  rowbytes = pSprite->RowBytes;

  pSrcByte = pSprite->Bytes + ((pSprite->Rows - 1 - sy) * rowbytes);
  pFirstDstByte =  pDstBytes + ((dst_y >> 3) * DISPLAY_REALWIDTH) + dst_x;
  for (dy = dst_y;  dy > last_y; dy--)
  {
    sx = src_x;
    bit_y = masks[7 - (dy & 0x07)];
    // not_bit_y = ~ bit_y;          //JJR
    pDstByte = pFirstDstByte;
    pLastDstByte = pDstByte + (last_x - dst_x);
    for (; pDstByte < pLastDstByte; pDstByte++)
    {
      //Read source byte:
      //If fill mode is on, pretend the source bitmap is solid:
      if (FillMode==DRAW_SHAPE_FILLED)
        srcByte = 0xff;
      else
        srcByte =  *(pSrcByte + (sx >> 3));                     //JJR
      
      //If invert mode is on, invert the source byte:
      if (InvertMode==DRAW_BITMAP_INVERT) srcByte = ~srcByte;   //JJR

      //Test the pixel in the source byte:
      if ( srcByte & masks[sx & 0x07] )                         //JJR
      {
        //If pixel is set in source image:
        switch (LogicalMode)
        {
          case DRAW_LOGICAL_AND:
            break;
          case DRAW_LOGICAL_XOR:
            *pDstByte ^= bit_y;
            break;
          case DRAW_LOGICAL_OR:
          case DRAW_LOGICAL_COPY:
          default:
            *pDstByte |= bit_y;
            break;
        }
      }
      else
      {
        //If pixel is clear in source image:
        switch (LogicalMode)
        {
          case DRAW_LOGICAL_OR:
          case DRAW_LOGICAL_XOR:
            break;
          case DRAW_LOGICAL_AND:
          case DRAW_LOGICAL_COPY:
          default:
            *pDstByte &= ~bit_y;
            break;
        }
      }
//JJR
      sx ++;
    }
    pSrcByte -= rowbytes;
    sy ++;
    if ((dy & 0x07) == 0) // bump back the scan line start point at rollover
      pFirstDstByte -= DISPLAY_REALWIDTH;
  }

}
I will get the code checked in tonight and upload a new firmware image to the test_releases folder.

John Hansen
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
schodet
Posts: 139
Joined: 29 Sep 2010, 11:21
Contact:

Re: TextOut y value

Post by schodet »

afanofosc wrote:I think it might be possible to speed up the copybits code for drawing RIC sprites.[...]
This should be possible improve this code, but things are much more complicated because bytes are in lines in sprites, but columns on the screen! May be with a lot of scratch registers...
LEGO things http://ni.fr.eu.org/lego/ - NXT Improved Firmware (GCC) http://nxt-firmware.ni.fr.eu.org/ - Other robots http://apbteam.org
afanofosc
Site Admin
Posts: 1256
Joined: 26 Sep 2010, 19:36
Location: Nashville, TN
Contact:

Re: TextOut y value

Post by afanofosc »

Ah, yes. I see that now. I was getting confused by all the sx and sy, etc.. Thanks for looking at it, anyway. I still need to upload a new image, which I keep forgetting to do.

John Hansen
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: TextOut y value

Post by HaWe »

when taking all the efforts for printing buitl-in fonts at any x,y,
what about having also 4-5 different font sizes like in RobotC ?
(there you can print several font sizes of built-in fonts at any x,y)
Post Reply

Who is online

Users browsing this forum: No registered users and 4 guests