Omnimaga

Calculator Community => TI Calculators => Calculator C => Topic started by: Spenceboy98 on June 17, 2013, 04:08:44 pm

Title: [Ndless] Tunnel
Post by: Spenceboy98 on June 17, 2013, 04:08:44 pm
Hello all. I saw this (http://lodev.org/cgtutor/tunnel.html) tutorial on how to make a tunnel and I decided to port it to Nspire. I'm having problems though. It only displays half of the tunnel correctly(the right side).

Could you guys help(I directly ported the code from the tutorial)?

Gif is attached(faster on calc).
Title: Re: [Ndless] Tunnel
Post by: lkj on June 17, 2013, 05:24:58 pm
Well, most likely you made a mistake while porting, so we'd need to look at your code to help?
Title: Re: [Ndless] Tunnel
Post by: DJ Omnimaga on June 17, 2013, 05:26:48 pm
You might have to post the code so C users can help you easier. By the way this looks kinda nice so far. How will obstacles be drawn? Also are the vertical lines due to some compression to save speed? Not that it looks bad, but just curious.
Title: Re: [Ndless] Tunnel
Post by: Spenceboy98 on June 17, 2013, 06:05:05 pm
I don't know why the lines are there. :P

Here is my code:
Spoiler For Code:
Code: [Select]
#include <os.h>
#include "utils.c"
#include "graphics3.c"
#include "touchpad.c"

#define texWidth 256
#define texHeight 256
#define screenWidth 240
#define screenHeight 240

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

int texture[texWidth][texHeight];

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

void masksprite(void *buffer, int *data, int x, int y, int width, int height, int mask){
int i, j;
for(i = 0; i < height; i++){
for(j = 0; j < width; j++){
if(data[i*width+j] != mask && x+j < 320 && x+j > 0 && y+i < 240 && y+i > 0){
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);
}

int main(void) {
char *screen;
screen = (char*)malloc(SCREEN_BYTES_SIZE * sizeof(char));     // just a buffer
if(!screen)
{
exit(0);
}
initTP();
lcd_ingray();
for(x = 0; x < texWidth; x++)
    for(y = 0; y < texHeight; y++)
    {
uint8_t c = x ^ y;
        texture[x][y] = RGBColor(c, c, c);
    }
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 = (unsigned int)(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 = (int)(texHeight * 0.25);
    //begin the loop
    while(!isKeyPressed(KEY_NSPIRE_ESC))
    {
        animation = animation+0.01;
readTP();
int TZ = getTouchedZone4();
        //calculate the shift values out of the animation value
        int shiftX = (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)(distanceTable[x][y] + shiftX)  % texWidth][(unsigned int)(angleTable[x][y] + shiftY) % texHeight];
            buffer[x][y] = color;
        }
        masksprite(screen, buffer[0], 0, 0, 240, 240, 0xf800);
refresh(screen);
clearBuf(screen);
    } 
free(screen);
endTP();
return 0;
}

Title: Re: [Ndless] Tunnel
Post by: Spenceboy98 on June 18, 2013, 02:04:51 pm
*BUMP*
Could someone please help? I have no idea why it's doing this. :/
Title: Re: [Ndless] Tunnel
Post by: Matrefeytontias on June 18, 2013, 02:35:06 pm
I can't see your code since my phone is real shit, but seeing at the result it seems that somehow your implementation of the algorithm doesn't work with negative numbers. I'd recommend casting the angle and depth to unsigned int before using the modulo when you get the texels.
Title: Re: [Ndless] Tunnel
Post by: Spenceboy98 on June 18, 2013, 02:51:37 pm
It has
Code: [Select]
(unsigned int)(distanceTable[x][y] + shiftX) already, but I made it
Code: [Select]
(unsigned int)((unsigned int)distanceTable[x][y] + shiftX) and there's no change. Any other ideas?
Title: Re: [Ndless] Tunnel
Post by: Matrefeytontias on June 18, 2013, 03:16:42 pm
No, I didn't mean that ; how do you calculate x and y from the code you posted ? Those are the ones you need to cast to unsigned int before moduling them.
Title: Re: [Ndless] Tunnel
Post by: Spenceboy98 on June 18, 2013, 03:26:29 pm
x and y are just from a for loop:
Code: [Select]
for(x = 0; x < w; x++)
for(y = 0; y < h; y++){
    color=texture[blah][blah];
    buffer[x][y]=color;
}
Title: Re: [Ndless] Tunnel
Post by: Augs on June 18, 2013, 03:47:48 pm
I'm not an expert(In fact I have no idea how this works) but it looks to me that you are stretching the bottom of the texture across half the tunnel. Make sure that your variable(One of the texture drawing ones) isn't saying constant. 
Title: Re: [Ndless] Tunnel
Post by: Matrefeytontias on June 18, 2013, 04:02:10 pm
^ that, but also I was actually asking for the calculations you replaced by "blah" ;D
Title: Re: [Ndless] Tunnel
Post by: Spenceboy98 on June 18, 2013, 04:12:41 pm
Here are the values:
Code: [Select]
texture[((unsigned int)(distanceTable[x][y] + shiftX)  % texWidth)][((unsigned int)(angleTable[x][y] + shiftY) % texHeight)];
Title: Re: [Ndless] Tunnel
Post by: Matrefeytontias on June 18, 2013, 04:21:18 pm
And that doesn't work ? Weird .__.

Try replacing the cast with abs(), just to be sure.
Title: Re: [Ndless] Tunnel
Post by: Spenceboy98 on June 18, 2013, 04:25:27 pm
And that doesn't work ? Weird .__.

Try replacing the cast with abs(), just to be sure.

Nope. Still doesn't work.
Title: Re: [Ndless] Tunnel
Post by: Matrefeytontias on June 19, 2013, 01:02:01 am
Then be sure that you don't cast to unsigned too early in the calculations.

Can you post the code on pastebin or whatever, that I could look at it ?
Title: Re: [Ndless] Tunnel
Post by: Spenceboy98 on June 19, 2013, 01:04:46 am
Here you go: http://pastebin.com/dx8a30x6

Edit: Sorry for using your BMP loading code without permission. I was just testing things. :P
Title: Re: [Ndless] Tunnel
Post by: Matrefeytontias on June 19, 2013, 04:40:23 am
Oh you're using it. So I know why there are those vertical lines on the texture : you're trying to use 3-bytes bitmaps but my function only loads correctly 16-bits non-paletted bitmaps.

EDIT : error spotted. You must not cast to unsigned when calculating distance and angle, because pixels at the left of te center have negative angles.
Title: Re: [Ndless] Tunnel
Post by: Spenceboy98 on June 19, 2013, 03:14:14 pm
Oh you're using it. So I know why there are those vertical lines on the texture : you're trying to use 3-bytes bitmaps but my function only loads correctly 16-bits non-paletted bitmaps.

EDIT : error spotted. You must not cast to unsigned when calculating distance and angle, because pixels at the left of te center have negative angles.

The old screenshot didn't use your bmp loading routine. The one attached does. Thank you for your help! :D
Title: Re: [Ndless] Tunnel
Post by: Spenceboy98 on June 19, 2013, 04:28:04 pm
*BUMP*

There are downloads attached. I have one for CX and one for regular. If your Nspire has a touchpad, it will work for left and right. There is no BMP texture loading for now. I'm not sure how I'm going to do obstacles. I'm not sure if the CX one works, but if you can test it, please post screenies. :D
Title: Re: [Ndless] Tunnel
Post by: Sorunome on June 20, 2013, 03:16:18 am
wow,
just wow,
that's looking faaar to amazing!
Title: Re: [Ndless] Tunnel
Post by: Matrefeytontias on June 20, 2013, 04:11:39 am
Nice :) now try to look around and to bend the tunnel ;D
Title: Re: [Ndless] Tunnel
Post by: DJ Omnimaga on June 20, 2013, 04:22:49 am
Looks really great!
Title: Re: [Ndless] Tunnel
Post by: lkj on June 20, 2013, 04:50:21 am
The screenshot looks cool, but the CX one isn't working. It only shows four black squares at the top of the screen.

Edit: Oh, and you should probably clear the screen at the start of your program, the garbage it displays before starting is a bit ugly :P
Title: Re: [Ndless] Tunnel
Post by: Spenceboy98 on June 20, 2013, 09:39:43 am
The screenshot looks cool, but the CX one isn't working. It only shows four black squares at the top of the screen.

Edit: Oh, and you should probably clear the screen at the start of your program, the garbage it displays before starting is a bit ugly :P

I don't know how to program for CX. :P Also, what garbage? I don't see any.
Title: Re: [Ndless] Tunnel
Post by: lkj on June 20, 2013, 10:05:57 am
Now I don't see it anymore, either.
If you have lcd_ingray() at the start of your program, it should work without any changes (unless you directly use the timers or other hardware).
Title: Re: [Ndless] Tunnel
Post by: Spenceboy98 on June 20, 2013, 10:28:01 am
Now I don't see it anymore, either.
If you have lcd_ingray() at the start of your program, it should work without any changes (unless you directly use the timers or other hardware).

That means that the not-CX version should work on the CX. The CX version I put lcd_incolor(); :P
Title: Re: [Ndless] Tunnel
Post by: DJ Omnimaga on June 26, 2013, 07:49:35 pm
Yep I had the same issue with the CX version. It just glithces up the screen then  four black squares appears. Exiting works fine, though (no reboot).
Title: Re: [Ndless] Tunnel
Post by: Spenceboy98 on July 25, 2013, 06:27:13 pm
Here's a version with loaded BMP textures using Matre's BMP loading routine(attached).

Screenies attached as well.

Edit: Supports relative file paths and the texture has to be 64*64.
Title: Re: [Ndless] Tunnel
Post by: Sorunome on July 25, 2013, 07:02:02 pm
that just looks so awesome, gret job!
Title: Re: Re: [Ndless] Tunnel
Post by: DJ Omnimaga on July 25, 2013, 09:35:05 pm
Nice indeed. I am really curious about how this would look like with color support in game.
Title: Re: [Ndless] Tunnel
Post by: Spenceboy98 on July 26, 2013, 01:31:08 am
Thanks!

Nice indeed. I am really curious about how this would look like with color support in game.

I'm not really sure how to do color support. Whenever I try putting lcd_incolor(), it doesn't work(also, I don't have a CX to test it on).
Title: Re: [Ndless] Tunnel
Post by: Spenceboy98 on August 26, 2013, 06:10:03 pm
Tried color support again(attached). Don't know if it works because I have no CX. This time I'm trying RGBlib (btw, do I need to put the lcd_incolor() for RGBlib?). Use a texture from other post.
Title: Re: [Ndless] Tunnel
Post by: lkj on August 26, 2013, 08:46:47 pm
You normally don't need lcd_incolor() if you don't have a lcd_ingray() earlier in your program.
It still doesn't work, it only shows a black screen. Or do I need something else than texture.bmp.tns and Tunnel.tns in the same directory?
Could you post the code?
Title: Re: [Ndless] Tunnel
Post by: Spenceboy98 on August 26, 2013, 09:14:41 pm
You normally don't need lcd_incolor() if you don't have a lcd_ingray() earlier in your program.
It still doesn't work, it only shows a black screen. Or do I need something else than texture.bmp.tns and Tunnel.tns in the same directory?
Could you post the code?

Here is my code:
Code: [Select]
#include <os.h>
#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){
setPixel(x+j, y+i, data[i*width+j], buffer);
}
}
}
}

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);
}
clearScreen(RGBColor(0,0,0), screen);

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();
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);
    //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);
display(screen);
clearScreen(RGBColor(255,255,255), screen);
    } 
free(screen);
endTP();
return 0;
}

It keeps giving me the black screen too. :/
Title: Re: [Ndless] Tunnel
Post by: lkj on August 26, 2013, 09:46:04 pm
Either one of the functions you didn't post is the problem, or something with your SDK or makefile is wrong. It works without a problem after I built it. I'm pretty sure it's a problem with your makefile or Ndless, since my (working) build is 13kb whereas your broken build is almost 700kb big.
Maybe all you have to do is replace "nspire-ld" by "nspire-ld-bflt" in the makefile. If it still doesn't work, could you post the makefile?
Title: Re: [Ndless] Tunnel
Post by: Spenceboy98 on August 26, 2013, 10:03:58 pm
Either one of the functions you didn't post is the problem, or something with your SDK or makefile is wrong. It works without a problem after I built it. I'm pretty sure it's a problem with your makefile or Ndless, since my (working) build is 13kb whereas your broken build is almost 700kb big.
Maybe all you have to do is replace "nspire-ld" by "nspire-ld-bflt" in the makefile. If it still doesn't work, could you post the makefile?

Here's my makefile:
Code: [Select]
GCC = nspire-gcc
LD = nspire-ld
GCCFLAGS = -O2 -Wall -W -marm
LDFLAGS =
OBJCOPY := "$(shell which arm-elf-objcopy 2>/dev/null)"
ifeq (${OBJCOPY},"")
OBJCOPY := arm-none-eabi-objcopy
endif
EXE = Tunnel.tns
OBJS = Tunnel.o
DISTDIR = ../
vpath %.tns $(DISTDIR)

all: $(EXE)

%.o: %.c
$(GCC) $(GCCFLAGS) -c $<

$(EXE): $(OBJS)
$(LD) $(LDFLAGS) $^ -o $(@:.tns=.elf) -lRGB
mkdir -p $(DISTDIR)
$(OBJCOPY) -O binary $(@:.tns=.elf) $(DISTDIR)/$@

clean:
rm -f *.o *.elf
rm -f $(DISTDIR)/$(EXE)

I tried changing what you said and it just gave me this error:
Code: [Select]
c:\Users\Kids\Downloads\ndless-v3.1-beta-r825-sdk\ndless-v3.1-beta-r825-sdk\yagarto\bin\arm-none-eabi-objcopy.exe:Tunnel.elf: File format not recognized
make: *** [Tunnel.tns] Error 1

Do you see anything wrong?
Title: Re: [Ndless] Tunnel
Post by: lkj on August 26, 2013, 10:23:25 pm
Ah, if you use nspire-ld-bflt you have to remove the lines about the objcopy, it isn't needed anymore. That's why it gave you an error.
Apart from that, there's nothing wrong with it.

Edit: This is the makefile the Ndless Editor automatically produces:
Spoiler For Makefile:
DEBUG = FALSE
GCC = nspire-gcc
AS = nspire-as
GXX=nspire-g++
LD = nspire-ld-bflt
GCCFLAGS = -Wall -W -marm
LDFLAGS =
ifeq ($(DEBUG),FALSE)
   GCCFLAGS += -Os
else
   GCCFLAGS += -O0 -g
   LDFLAGS += --debug
endif
CPPOBJS = $(patsubst %.cpp,%.o,$(wildcard *.cpp))
OBJS = $(patsubst %.c,%.o,$(wildcard *.c)) $(patsubst %.S,%.o,$(wildcard *.S)) $(CPPOBJS)
ifneq ($(strip $(CPPOBJS)),)
   LDFLAGS += --cpp
endif
EXE = Tunnel.tns
DISTDIR = .
vpath %.tns $(DISTDIR)

all: $(EXE)

%.o: %.c
   $(GCC) $(GCCFLAGS) -c $<

%.o: %.cpp
   $(GXX) $(GCCFLAGS) -c $<

%.o: %.S
   $(AS) -c $<

$(EXE): $(OBJS)
   mkdir -p $(DISTDIR)
   $(LD) $^ -o $(DISTDIR)/$@ $(LDFLAGS)
ifeq ($(DEBUG),FALSE)
   @rm -f $(DISTDIR)/*.gdb
endif

clean:
   rm -f *.o *.elf $(DISTDIR)/*.gdb $(DISTDIR)/$(EXE)
Maybe try it with this one if it still doesn't work.
Title: Re: [Ndless] Tunnel
Post by: Spenceboy98 on August 26, 2013, 10:46:42 pm
With that makefile, it gives me the attached file. Can you confirm that it works(I can't tell with a non-cx)?
Title: Re: [Ndless] Tunnel
Post by: Spenceboy98 on August 26, 2013, 11:42:54 pm
*BUMP*
It definitely hasn't been 24 hours, but I felt I should update.

There are two files attached to this post. One in CX, and one is non-CX(though the gray should work just fine on CX). I'd like for tests and screenshots please(I hope it works). Also, if you test it, can you tell me how fast the CX one goes(if it works)?
Title: Re: [Ndless] Tunnel
Post by: DJ Omnimaga on August 26, 2013, 11:57:21 pm
Glad to see you're still working on this and especially that you added colors! :) By the way you should really add stuff on each sides of the screen or move the tunnel on one side then add stuff on the other side, such as an HUD with score and credits.

I probably won't try this now, though, unless this runs on any Ndless version released within the last 6 months (installing Ndless takes 5 hours because my battery is always depleted due to not using my calc often, and Ndless requires to charge it completely before being sent)
Title: Re: [Ndless] Tunnel
Post by: Spenceboy98 on August 26, 2013, 11:59:36 pm
Glad to see you're still working on this and especially that you added colors! :) By the way you should really add stuff on each sides of the screen or move the tunnel on one side then add stuff on the other side, such as an HUD with score and credits.

I probably won't try this now, though, unless this runs on any Ndless version released within the last 6 months (installing Ndless takes 5 hours because my battery is always depleted due to not using my calc often, and Ndless requires to charge it completely before being sent)

Compiled with ndless-v3.1-beta-r825-sdk. I think that's a newer version. ;)
Title: Re: [Ndless] Tunnel
Post by: Levak on August 27, 2013, 02:27:22 am
There are two files attached to this post. One in CX, and one is non-CX(though the gray should work just fine on CX).
Why are you giving separate builds ? You should checkout has_color (or similar others) (http://hackspire.unsads.com/wiki/index.php/Libndls#Hardware) in order to make only one build compatible with all models.

Quote
Compiled with ndless-v3.1-beta-r825-sdk. I think that's a newer version. Wink
If your using specific functionalities, you should always use assert_ndless_rev(rev) (http://hackspire.unsads.com/wiki/index.php/Libndls#Platform) according to the revision the feature you're using appeared in.
This guarantee your code doesn't crash if the user doesn't have the proper Ndless version.
I see you're using nspire-ld-bflt, your minimal Ndless version is at least r806 according to http://hackspire.unsads.com/wiki/index.php/Ndless_features_and_limitations#bFLT_loader


(installing Ndless takes 5 hours because my battery is always depleted due to not using my calc often, and Ndless requires to charge it completely before being sent)
Completely charged ? No.
Also, its not Ndless that requires this, but the operating system because Ndless installation is using OS upgrade routines in order to exploit. The OS itself requires that the battery is sufficiently charged in order to support the time to upgrade being offline. Since Ndless is a 12Ko upgrade it won't last really long.
Title: Re: [Ndless] Tunnel
Post by: lkj on August 27, 2013, 02:16:50 pm
*BUMP*
It definitely hasn't been 24 hours, but I felt I should update.

There are two files attached to this post. One in CX, and one is non-CX(though the gray should work just fine on CX). I'd like for tests and screenshots please(I hope it works). Also, if you test it, can you tell me how fast the CX one goes(if it works)?
This one finally works (the one a post before this one didn't, though) :)
It looks like the last color screenshot I posted, just with a white background. I don't know how fast it is on real hardware, though.
Title: Re: [Ndless] Tunnel
Post by: Spenceboy98 on August 27, 2013, 07:01:49 pm
Okay, thanks! I think I've made it cross compatible with both(attached). It works fine, but a little slower, on the gray Nspire. Hopefully it works for CX. :D
Title: Re: [Ndless] Tunnel
Post by: lkj on August 27, 2013, 07:45:06 pm
It only displays a white screen on the CX...
Title: Re: [Ndless] Tunnel
Post by: Spenceboy98 on August 27, 2013, 07:51:14 pm
Here, try the one attached to this post. I think it should work this time.
Title: Re: [Ndless] Tunnel
Post by: lkj on August 27, 2013, 10:45:09 pm
Yeah, now it works. It's much slower than before, though.
Title: Re: [Ndless] Tunnel
Post by: Levak 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.
Title: Re: [Ndless] Tunnel
Post by: Spenceboy98 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.
Title: Re: [Ndless] Tunnel
Post by: Levak on August 28, 2013, 07:12:57 am
I suggest you this reading (http://stackoverflow.com/questions/11227809/why-is-processing-a-sorted-array-faster-than-an-unsorted-array#answers) while you're getting your math class ;)
Title: Re: [Ndless] Tunnel
Post by: Spenceboy98 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)? :/
Title: Re: [Ndless] Tunnel
Post by: Spenceboy98 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?
Title: Re: [Ndless] Tunnel
Post by: Levak 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 ?
Title: Re: [Ndless] Tunnel
Post by: Spenceboy98 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;
}
Title: Re: [Ndless] Tunnel
Post by: Levak 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.
Title: Re: [Ndless] Tunnel
Post by: Spenceboy98 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?
Title: Re: [Ndless] Tunnel
Post by: Levak on August 30, 2013, 07:49:45 am
Here we go
Title: Re: [Ndless] Tunnel
Post by: Eiyeron on August 30, 2013, 07:51:26 am
YOu should use a seamless texture, that'll avoid the seam at the end junction.
Title: Re: [Ndless] Tunnel
Post by: Spenceboy98 on August 31, 2013, 02:04:10 pm
Does anyone have an idea for how to add another texture(so there's two)?
Title: Re: [Ndless] Tunnel
Post by: Spenceboy98 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?