Author Topic: [Ndless] Tunnel  (Read 28087 times)

0 Members and 1 Guest are viewing this topic.

Offline Spenceboy98

  • LV7 Elite (Next: 700)
  • *******
  • Posts: 547
  • Rating: +59/-2
    • View Profile
Re: [Ndless] Tunnel
« Reply #45 on: August 27, 2013, 07:51:14 pm »
Here, try the one attached to this post. I think it should work this time.
I like milk.

Offline lkj

  • LV6 Super Member (Next: 500)
  • ******
  • Posts: 485
  • Rating: +58/-1
    • View Profile
Re: [Ndless] Tunnel
« Reply #46 on: August 27, 2013, 10:45:09 pm »
Yeah, now it works. It's much slower than before, though.

Offline Levak

  • LV9 Veteran (Next: 1337)
  • *********
  • Posts: 1002
  • Rating: +208/-39
    • View Profile
    • My website
Re: [Ndless] Tunnel
« Reply #47 on: August 28, 2013, 02:08:33 am »
Have you made a conditional branch/jump or something smarter ?
Remember that using an if inside a setPixel is most likely time cretical. You may want to use faster designs like function pointers.
I do not get mad at people, I just want them to learn the way I learnt.
My website - TI-Planet - iNspired-Lua

Offline Spenceboy98

  • LV7 Elite (Next: 700)
  • *******
  • Posts: 547
  • Rating: +59/-2
    • View Profile
Re: [Ndless] Tunnel
« Reply #48 on: August 28, 2013, 06:43:14 am »
Yeah, now it works. It's much slower than before, though.

Yeah, I figured(slower on the gray too).

Have you made a conditional branch/jump or something smarter ?
Remember that using an if inside a setPixel is most likely time cretical. You may want to use faster designs like function pointers.

Branch/jump? By "if inside a setPixel", do you mean like this?:
Code: [Select]
if(has_colors)
    setPixel(x,y,color,buffer);

What could be a faster way to do it?

Edit: I'll try a switch statement when I get home from school today.
« Last Edit: August 28, 2013, 06:48:49 am by Spenceboy98 »
I like milk.

Offline Levak

  • LV9 Veteran (Next: 1337)
  • *********
  • Posts: 1002
  • Rating: +208/-39
    • View Profile
    • My website
Re: [Ndless] Tunnel
« Reply #49 on: August 28, 2013, 07:12:57 am »
I suggest you this reading while you're getting your math class ;)
« Last Edit: August 28, 2013, 07:14:48 am by Levak »
I do not get mad at people, I just want them to learn the way I learnt.
My website - TI-Planet - iNspired-Lua

Offline Spenceboy98

  • LV7 Elite (Next: 700)
  • *******
  • Posts: 547
  • Rating: +59/-2
    • View Profile
Re: [Ndless] Tunnel
« Reply #50 on: August 28, 2013, 04:41:14 pm »
Switch case doesn't really help the speed much. How would I use the info on that link to help(I can't seem to wrap my mind around it)? :/
I like milk.

Offline Spenceboy98

  • LV7 Elite (Next: 700)
  • *******
  • Posts: 547
  • Rating: +59/-2
    • View Profile
Re: [Ndless] Tunnel
« Reply #51 on: August 29, 2013, 06:42:41 am »
*BUMP*
Could one of you help make this faster? What exactly should I do instead of my if statement?
I like milk.

Offline Levak

  • LV9 Veteran (Next: 1337)
  • *********
  • Posts: 1002
  • Rating: +208/-39
    • View Profile
    • My website
Re: [Ndless] Tunnel
« Reply #52 on: August 29, 2013, 07:07:44 am »
*BUMP*
Could one of you help make this faster? What exactly should I do instead of my if statement?
Without the last source updated source code ? Does anything has changed since the last one ?
I do not get mad at people, I just want them to learn the way I learnt.
My website - TI-Planet - iNspired-Lua

Offline Spenceboy98

  • LV7 Elite (Next: 700)
  • *******
  • Posts: 547
  • Rating: +59/-2
    • View Profile
Re: [Ndless] Tunnel
« Reply #53 on: August 29, 2013, 07:09:26 pm »
*BUMP*
Could one of you help make this faster? What exactly should I do instead of my if statement?
Without the last source updated source code ? Does anything has changed since the last one ?

Here is my code now(with the switch case):
Code: [Select]
#include <os.h>
#include "utils.c"
#include "graphics3.c"
#include "math.h"
#include "nCOMMON.h"
#include "touchpad.c"

#define R5G6B5(r,g,b) (is_cx ? (((r) << 11) | ((g) << 5) | (b)) : ((int)( 0.229 * (r) + 0.587 * ((g) / 2) + 0.114 * (b)) / 2))

int nRC_enableRelativePaths(char **argv)
{
char buf[256], *p;
strcpy(buf, argv[0]);
p = strrchr(buf, '/');
if (!p)
return -1;
*p = '\0';
return NU_Set_Current_Dir(buf) ? -1 : 0;
}

uint16_t* nRC_loadBMP(char *path)
{
int size, offset, i, x, bpp, r, g, b;
uint16_t *returnValue, color;
FILE *temp = fopen(path, "rb");

if(!temp)
{
printf("Could not open %s\n", path);
return NULL;
}

// Check if the file's 2 first char are BM (indicates bitmap)
if(!(fgetc(temp) == 0x42 && fgetc(temp) == 0x4d))
{
printf("Image is not a bitmap\n");
fclose(temp);
return NULL;
}

// Check the bits-per-pixel format of the bitmap and converts color accordingly
fseek(temp, 0x1c, SEEK_SET);
bpp = fgetc(temp);

// Gets the 4-bytes numbers of bytes representing pixels, situated at 0x22
// Note that a same size can represent a different number of pixels, depending on bpp
fseek(temp, 0x22, SEEK_SET);
size = fgetc(temp) | (fgetc(temp) << 8) | (fgetc(temp) << 16) | (fgetc(temp) << 24);

// Gets the 4-bytes offset to the start of the pixel table, situated at 0x0a
fseek(temp, 0x0a, SEEK_SET);
offset = fgetc(temp) | (fgetc(temp) << 8) | (fgetc(temp) << 16) | (fgetc(temp) << 24);

fseek(temp, offset, SEEK_SET);

switch(bpp)
{ // Monochrome bitmaps have 1 bit per pixel : 0 is full black, 1 is full white
case 1:
returnValue = malloc(size * 8 * sizeof(int));
if(!returnValue)
{
printf("Could not allocate memory");
fclose(temp);
return NULL;
}
for(i = size - 1; i >= 0; i--)
{
color = fgetc(temp);
for(x = 0; x < 8; x++)
{
returnValue[i * 8 + x] = (color & (1 << x)) ? (is_cx ? 65535 : 15) : 0;
}
}
break;

// 16-colours bitmaps have 4 bits per pixel, corresponding to a grayscale.
// Fortunately, the non-CX screen uses the same pixel format.
case 4:
returnValue = malloc(size * 2 * sizeof(int));
if(!returnValue)
{
printf("Could not allocate memory");
fclose(temp);
return NULL;
}
for(i = size - 1; i >= 0; i--)
{
x = fgetc(temp);
color = x & 0x0f;
returnValue[i * 2] = is_cx ? ((color * 2) << 11) | ((color * 4) << 5) | (color * 2) : color;
color = (x >> 4) & 0x0f;
returnValue[i * 2 + 1] = is_cx ? ((color * 2) << 11) | ((color * 4) << 5) | (color * 2) : color;
}
break;

// 256-colours bitmaps have 8 bits per pixel, corresponding to an index in a palette.
// So we must add the 8-bit value to the start of the palette to get the 32-bits colour of the pixel.
case 8:
printf("Paletted bitmaps not supported\n");
fclose(temp);
return NULL;
break;

// 65536-colours bitmaps have 16 bits per pixel, corresponding to the R5G6B5 colour format.
// Fortunately, the CX screen uses the same pixel format.
case 16:
size >>= 1;
returnValue = malloc(size * sizeof(int));
if(!returnValue)
{
printf("Could not allocate memory\n");
fclose(temp);
return NULL;
}
for(i = size - 1; i >= 0; i--)
{
color = (uint16_t)(fgetc(temp) | (fgetc(temp) << 8));
returnValue[i] = (is_cx ? color : ((int)( 0.229 * (color >> 11) + 0.587 * ((color >> 6) & 0x1f) + 0.114 * (color & 0x1f)) >> 1));
}
break;

// 16777216-colours bitmaps have 24 bits per pixel, being 8 bits for red, 8 for green and 8 for blue.
// Unfortunately, no TI-Nspire screen supports this format for now, so we have to scale it down to R5G6B5
// even if this means that we loose some quality.
case 24:
size /= 3;
returnValue = malloc(size * sizeof(int));
if(!returnValue)
{
printf("Could not allocate memory");
fclose(temp);
return NULL;
}
for(i = size - 1; i >= 0; i--)
{
b = fgetc(temp); g = fgetc(temp); r = fgetc(temp);
returnValue[i] = R5G6B5((int)(r / 8), (int)(g / 4), (int)(b / 8));
}
break;

// This format is the same than the previous one, except that it includes an alpha byte to determine the transparence
// degree of the pixel. I never planned to support transparency anyway.
case 32:
printf("32-bits bitmaps not supported\n");
fclose(temp);
return NULL;
break;

default:
printf("Format not supported\n");
fclose(temp);
return NULL;
break;
}

fclose(temp);
return returnValue;
}


#define texWidth 64
#define texHeight 64
#define screenWidth 240
#define screenHeight 240

int w = 240, h = 240, x, y;

uint16_t *texture;

int distanceTable[screenWidth][screenHeight];
int angleTable[screenWidth][screenHeight];
int buffer[screenWidth][screenHeight];

void sprite1(void *buffer, int *data, int x, int y, int width, int height){
int i, j;
for(i = 0; i < height; i++){
for(j = 0; j < width; j++){
if(x+j < 320 && x+j > 0 && y+i < 240 && y+i > 0){
if(has_colors)
setPixel(x+j, y+i, data[i*width+j], buffer);
else
setPixelBuf(buffer, x+j, y+i, data[i*width+j]);
}
}
}
}

uint16_t RGBColor(uint8_t r, uint8_t g, uint8_t b)
{
  return ((r / 8) << 11) | ((g / 4) << 5) | (b / 8);
}

uint16_t HSLtoRGB(int h, float s, float l) {
   float r = 0.0f; float g = 0.0f; float b = 0.0f;
   float c = (1-fabs(2*l-1))*s;
   float tc = c*(1-abs(h%2-1));
   switch(h/60) {
      case 0: r = c; g = tc; break;
      case 1: g = c; r = tc; break;
      case 2: g = c; b = tc; break;
      case 3: b = c; g = tc; break;
      case 4: b = c; r = tc; break;
      case 5: r = c; b = tc; break;
      default: break;
   }
   float m = l-c/2;
   r += m; g += m; b += m;
   return (uint16_t)(((int)(r*32)<<11)|((int)(g*64)<<5)|((int)(b*32)));
}

int main(int argc, char *argv[]) {
char *screen;
screen = (char*)malloc(SCREEN_BYTES_SIZE * sizeof(char));     // just a buffer
if(!screen)
{
exit(0);
}

if(nRC_enableRelativePaths(argv))
{
printf("Couldn't change directory\n");
exit(0);
}
texture = nRC_loadBMP("texture.bmp.tns");
if(!texture){
free(screen);
exit(0);
}
initTP();
if(!has_colors)
lcd_ingray();
for(x = 0; x < w; x++)
    for(y = 0; y < h; y++)
    {
        int angle, distance;
        float ratio = 32.0;
        distance = (int)(ratio * texHeight / sqrt((x - w / 2.0) * (x - w / 2.0) + (y - h / 2.0) * (y - h / 2.0))) % texHeight;
        angle = (0.5 * texWidth * atan2(y - h / 2.0, x - w / 2.0) / M_PI);
        distanceTable[x][y] = distance;
        angleTable[x][y] = angle;
    }
float animation = 0;
int shiftY = (unsigned int)(texHeight * 0.25);
if(has_colors)
clearScreen(RGBColor(255,255,255), screen);
else
clearBuf(screen);
    //begin the loop
    while(!isKeyPressed(KEY_NSPIRE_ESC))
    {
        animation = animation+0.04;
readTP();
int TZ = getTouchedZone4();
        //calculate the shift values out of the animation value
        int shiftX = (unsigned int)(texWidth * 1.0 * animation);
if(isKeyPressed(KEY_NSPIRE_RIGHT) || TZ==6)
shiftY++;
if(isKeyPressed(KEY_NSPIRE_LEFT) || TZ==4)
shiftY--;
        for(x = 0; x < w; x++)
        for(y = 0; y < h; y++)
        {
            //get the texel from the texture by using the tables, shifted with the animation values
            int color = texture[((unsigned int)(angleTable[x][y] + shiftY) % texHeight)*texWidth+((unsigned int)(distanceTable[x][y] + shiftX)  % texWidth)];
            buffer[x][y] = color;
        }
        sprite1(screen, buffer[0], 40, 0, 240, 240);
switch(has_colors){
    case 1:
                display(screen);
                //clearScreen(RGBColor(255,255,255), screen);
                break;
            case 0:
                refresh(screen);
                clearBuf(screen);
                break;
default:
                refresh(screen);
                clearBuf(screen);
                break;
}
    }
free(screen);
endTP();
return 0;
}
I like milk.

Offline Levak

  • LV9 Veteran (Next: 1337)
  • *********
  • Posts: 1002
  • Rating: +208/-39
    • View Profile
    • My website
Re: [Ndless] Tunnel
« Reply #54 on: August 30, 2013, 04:57:29 am »
I can't see anywhere in your topic theses includes
Code: [Select]
#include "utils.c"     
#include "graphics3.c" 
#include "math.h"       
#include "nCOMMON.h"   
#include "touchpad.c"   

But the problem is not here.
You said you put a switch/case but you didn't, at least where you pointed it (arround setPixel).

Look at this :
Code: [Select]
void sprite1(void *buffer, int *data, int x, int y, int width, int height){
    int i, j;
    for(i = 0; i < height; i++){
        for(j = 0; j < width; j++){
            if(x+j < 320 && x+j > 0 && y+i < 240 && y+i > 0){
                if(has_colors)   
                    setPixel(x+j, y+i, data[i*width+j], buffer);
                else
                    setPixelBuf(buffer, x+j, y+i, data[i*width+j]);
            }
        }
    }
}

You're asking, for each damn pixel if the screen has colors.
I will do the same, when you'll write an essay, for each letter you put on your paper, if you want a new sheet.

Look at this now :
Code: [Select]
void sprite1(void *buffer, int *data, int x, int y, int width, int height){
    int i, j;
    switch (has_colors)
    {
      case 1:
          for(i = 0; i < height; i++){
              for(j = 0; j < width; j++){
                  if(x+j < 320 && x+j > 0 && y+i < 240 && y+i > 0)
                      setPixel(x+j, y+i, data[i*width+j], buffer);
              }
          }
          break;
      default:
          for(i = 0; i < height; i++){
              for(j = 0; j < width; j++){
                  if(x+j < 320 && x+j > 0 && y+i < 240 && y+i > 0)
                      setPixelBuf(buffer, x+j, y+i, data[i*width+j]);
             }
         }
     }
}

There is still a condition that is being asked for each damn pixel that can be put outside of the loops and translated in a mathematical way.

Code: [Select]
void sprite1(void *buffer, int *data, int x, int y, int width, int height){

    if(x > SCREEN_WIDTH || y > SCREEN_HEIGHT || x+w < 0 || y+h < 0)
        return;

    if(x < 0)
    {
        w += x;
        x = 0;
    }

    if(y < 0)
    {
        h += y;
        y = 0;
    }

    if(x + w > SCREEN_WIDTH)
        w = SCREEN_WIDTH - x;
    if(y + h > SCREEN_HEIGHT)
        h = SCREEN_HEIGHT - y;

    if(w <= 0 || h <= 0)
        return;

    int i, j;
    switch (has_colors)
    {
      case 1:
          for(i = 0; i < height; i++){
              for(j = 0; j < width; j++)
                  setPixel(x+j, y+i, data[i*width+j], buffer);
          }
          break;
      default:
          for(i = 0; i < height; i++){
              for(j = 0; j < width; j++)
                  setPixelBuf(buffer, x+j, y+i, data[i*width+j]);
         }
     }
}

Untested, but should be fine.
« Last Edit: August 30, 2013, 05:00:09 am by Levak »
I do not get mad at people, I just want them to learn the way I learnt.
My website - TI-Planet - iNspired-Lua

Offline Spenceboy98

  • LV7 Elite (Next: 700)
  • *******
  • Posts: 547
  • Rating: +59/-2
    • View Profile
Re: [Ndless] Tunnel
« Reply #55 on: August 30, 2013, 06:54:39 am »
Oh my gosh, I feel so stupid.  O.O Sorry for any frustration I may have caused you. Here is an updated one attached.

Btw, could someone post more color screenies with different textures?
« Last Edit: August 30, 2013, 07:13:14 am by Spenceboy98 »
I like milk.

Offline Levak

  • LV9 Veteran (Next: 1337)
  • *********
  • Posts: 1002
  • Rating: +208/-39
    • View Profile
    • My website
Re: [Ndless] Tunnel
« Reply #56 on: August 30, 2013, 07:49:45 am »
Here we go
I do not get mad at people, I just want them to learn the way I learnt.
My website - TI-Planet - iNspired-Lua

Offline Eiyeron

  • Urist McEiyolobster
  • LV10 31337 u53r (Next: 2000)
  • **********
  • Posts: 1430
  • Rating: +130/-10
  • (-_(//));
    • View Profile
    • Rétro-Actif : Rétro/Prog/Blog
Re: [Ndless] Tunnel
« Reply #57 on: August 30, 2013, 07:51:26 am »
YOu should use a seamless texture, that'll avoid the seam at the end junction.

Offline Spenceboy98

  • LV7 Elite (Next: 700)
  • *******
  • Posts: 547
  • Rating: +59/-2
    • View Profile
Re: [Ndless] Tunnel
« Reply #58 on: August 31, 2013, 02:04:10 pm »
Does anyone have an idea for how to add another texture(so there's two)?
I like milk.

Offline Spenceboy98

  • LV7 Elite (Next: 700)
  • *******
  • Posts: 547
  • Rating: +59/-2
    • View Profile
Re: [Ndless] Tunnel
« Reply #59 on: September 01, 2013, 08:16:33 am »
*BUMP*

Does anyone have an idea for how to add another texture(so there's two)?

Any ideas?
I like milk.