Omnimaga

Calculator Community => Other Calc-Related Projects and Ideas => TI-Nspire => Topic started by: Matrefeytontias on September 30, 2012, 07:09:50 am

Title: Mode 7 with Ndless !
Post by: Matrefeytontias on September 30, 2012, 07:09:50 am
Hi guys !

I programmed a simple but cool effect of Mode 7 (like the firsts F-Zero or Super Mario Kart) with C and nSDL, and I thank that I should share it :)

(http://mattias.refeyton.fr/espace-ti/mode7.gif)

On the gif the program is laggy, but it's because of my bad PC ; on-calc it's way smoother.

Spoiler For "Source code":
Code: [Select]
#include <os.h>
#include <SDL/SDL.h>

#define WIDTH 320
#define HALF_WIDTH 160 // WIDTH / 2
#define HEIGHT 240
#define HALF_HEIGHT 120 // HEIGHT / 2
#define SCALE_FACTOR 6
#define FACTOR 128 //(2<<(SCALE_FACTOR+1))
#define SPEED 4

int main(void) {
SDL_Surface *screen;
SDL_Rect pixelRect, clearRect;

int Xib;
short X0 = 0, Y0 = 0;

clearRect.x = 0;
clearRect.y = HALF_HEIGHT;
clearRect.w = WIDTH;
clearRect.h = 1;

pixelRect.h = (pixelRect.w = 2);

SDL_Init(SDL_INIT_VIDEO);

screen = SDL_SetVideoMode(WIDTH, HEIGHT, is_cx?16:8, SDL_SWSURFACE);

while(!isKeyPressed(KEY_NSPIRE_ESC))
{
for(pixelRect.x = 0; pixelRect.x < WIDTH; pixelRect.x += 2)
{
Xib = (pixelRect.x - HALF_WIDTH) * HEIGHT;
for(pixelRect.y = HALF_HEIGHT; pixelRect.y < HEIGHT; pixelRect.y += 2)
{
if( ( (( (WIDTH - (Xib / pixelRect.y) + X0) >> SCALE_FACTOR) & 1) + (( (2 * (HEIGHT - pixelRect.y) + Y0) >> SCALE_FACTOR) & 1 ) ) & 1)
{
SDL_FillRect(screen, &pixelRect, (Uint32)0);
}
}
}

SDL_FillRect(screen, &clearRect, (Uint32)0);

SDL_Flip(screen);
SDL_FillRect(screen, NULL, (Uint32)0xffffffff);


if(isKeyPressed(KEY_NSPIRE_LEFT))
{
X0 = (FACTOR + X0 - SPEED) % FACTOR;
}

if(isKeyPressed(KEY_NSPIRE_RIGHT))
{
X0 = (FACTOR + X0 + SPEED) % FACTOR;
}

if(isKeyPressed(KEY_NSPIRE_UP))
{
Y0 = (FACTOR + Y0 - SPEED) % FACTOR;
}

if(isKeyPressed(KEY_NSPIRE_DOWN))
{
Y0 = (FACTOR + Y0 + SPEED) % FACTOR;
}
}

SDL_FreeSurface(screen);
SDL_Quit();
return 0;
}

Share comments :)
Title: Re: Mode 7 with Ndless !
Post by: Alex on September 30, 2012, 08:02:30 am
C'est sympas matref. Continue :)
Title: Re: Mode 7 with Ndless !
Post by: Lionel Debroux on September 30, 2012, 11:13:11 am
Je suis tout à fait d'accord, mais english spoken here ;)
Title: Re: Mode 7 with Ndless !
Post by: annoyingcalc on September 30, 2012, 12:04:52 pm
NICE!
Title: Re: Mode 7 with Ndless !
Post by: cyanophycean314 on September 30, 2012, 09:08:25 pm
Looks really nice!  :)
Title: Re: Mode 7 with Ndless !
Post by: Juju on September 30, 2012, 11:11:45 pm
Hey that looks pretty cool :D
Title: Re: Mode 7 with Ndless !
Post by: Sorunome on September 30, 2012, 11:43:32 pm
That's looking awesome! :D
Title: Re: Mode 7 with Ndless !
Post by: tr1p1ea on October 01, 2012, 03:33:42 am
Looking good, have you put any thought into rotations?
Title: Re: Mode 7 with Ndless !
Post by: DJ Omnimaga on October 01, 2012, 03:36:07 am
O.O looks really sweet! I wonder how it will look like with actual sprites?
Title: Re: Mode 7 with Ndless !
Post by: aeTIos on October 01, 2012, 03:48:05 am
code in spoiler <_<
Looks nice :D
Title: Re: Mode 7 with Ndless !
Post by: Hayleia on October 01, 2012, 06:58:52 am
That looks nice Matref :D
Also, you have +83 ratings :P

code in spoiler <_<
Did you mean "Chrome <_<" ? jk :P
Title: Re: Mode 7 with Ndless !
Post by: Alex on October 01, 2012, 02:08:11 pm
Je suis tout à fait d'accord, mais english spoken here ;)
Ok Hayleia, sorry ^^
Title: Re: Mode 7 with Ndless !
Post by: apcalc on October 01, 2012, 05:51:42 pm
Looks great!  Excellent work!
Title: Re: Mode 7 with Ndless !
Post by: Hayleia on October 02, 2012, 01:16:41 am
Je suis tout à fait d'accord, mais english spoken here ;)
Ok Hayleia, sorry ^^
??? That was not me :P
Title: Re: Mode 7 with Ndless !
Post by: DJ Omnimaga on October 02, 2012, 03:36:40 pm
code in spoiler <_<
Not his fault if Chrome manages to be worse than Internet Explorer in certain ways :P
Title: Re: Mode 7 with Ndless !
Post by: Eiyeron on October 02, 2012, 03:54:46 pm
The only problem I saw from chrome!
Oh and by the way, it should add a The_Game_filter
Title: Re: Mode 7 with Ndless !
Post by: Alex on October 03, 2012, 07:07:12 am
Je suis tout à fait d'accord, mais english spoken here ;)
Ok Hayleia, sorry ^^
??? That was not me :P
Sorry. ^^
Title: Re: Mode 7 with Ndless !
Post by: DJ Omnimaga on October 14, 2012, 07:01:20 pm
Oh and by the way, it should add a The_Game_filter

Wat

On topic note, have you managed to successfully add rotation without losing much speed?
Title: Re: Mode 7 with Ndless !
Post by: Matrefeytontias on October 15, 2012, 01:17:34 am
For now, I'm trying to display a fullscreen "mode 7" 'd image. Then I'll add rotations ;)
Title: Re: Mode 7 with Ndless !
Post by: Matrefeytontias on January 02, 2013, 01:23:25 pm
Heavy bump,

I'm back with Mode 7, and I planned to make a game using it :)

But for now, here's a screenie of an infinite textured and mode7'd ground, with full moves and rotations :

(http://mattias.refeyton.fr/espace-ti/mode7/nspire/mode7ground.gif)

The quality here is because of the gif, it's far better on-calc :P

Also, I have a question : in order to avoid converting the texture in 242 lines of data, I access texture.bmp.tns using the absolute path (SDL_LoadBMP("/documents/Examples/texture.bmp.tns");). Is there a way to load the file texture.bmp.tns which is in the same directory as the executable ? I tried SDL_LoadBMP("texture.bmp.tns"); it just doesn't work.

Spoiler For Source code:
Code: [Select]
#include <os.h>
#include <SDL/SDL.h>
#include <fdlibm.h>

#define SCREEN_W 320
#define SCREEN_H 240
#define IMG_W 256
#define IMG_H 256

#define fsin(x) sin(x * M_PI / 128)
#define fcos(x) cos(x * M_PI / 128)

void setPixel(SDL_Surface *surface, int x, int y, Uint32 pixel);
Uint32 getPixel(SDL_Surface *surface, int x, int y);

int main(void)
{
SDL_Surface *screen, *bitmap, *sky;
SDL_Event event;
SDL_Rect skyRect;
skyRect.x = (skyRect.y = 0);
skyRect.w = SCREEN_W;
skyRect.h = SCREEN_H >> 2;
Uint32 color = 0;

float sinLUT[256];
float cosLUT[256];

float distance, hScale, line_dx, line_dy, space_x, space_y, scaleX = 200.0, scaleY = 200.0, space_z = 96.0,
offsetX = 870, offsetY = 1515;
int screen_x, screen_y, horizon = 0, x;

unsigned char angle = 0, speedX = 4, speedY = 4, speedAngle = 4;

SDL_Init(SDL_INIT_VIDEO);

screen = SDL_SetVideoMode(SCREEN_W, SCREEN_H, is_cx?16:8, SDL_SWSURFACE);

bitmap = SDL_LoadBMP("/documents/Examples/texture.bmp.tns"); // TODO : make the load relative

for(x = 0; x < 256; x++)
{
sinLUT[x] = fsin(x);
cosLUT[x] = fcos(x);
}

if(!bitmap)
{
SDL_Quit();
exit(1);
}

while(1)
{
SDL_PollEvent(&event);

if(isKeyPressed(KEY_NSPIRE_ESC))
{
break;
}
if(isKeyPressed(KEY_NSPIRE_DOWN))
{
offsetX -= cosLUT[angle] * speedX;
offsetY -= sinLUT[angle] * speedY;
}
if(isKeyPressed(KEY_NSPIRE_LEFT))
{
angle = (angle - speedAngle) & 0xff;
}
if(isKeyPressed(KEY_NSPIRE_RIGHT))
{
angle = (angle + speedAngle) & 0xff;
}
if(isKeyPressed(KEY_NSPIRE_UP))
{
offsetX += cosLUT[angle] * speedX;
offsetY += sinLUT[angle] * speedY;
}

for(screen_y = SCREEN_H/4; screen_y < SCREEN_H; screen_y += 2)
{
distance = space_z * scaleY / (screen_y + horizon);
hScale = distance / scaleX;

line_dx = -sinLUT[angle] * hScale;
line_dy = cosLUT[angle] * hScale;

space_x = offsetX + distance * cosLUT[angle] - SCREEN_W/4 * line_dx;
space_y = offsetY + distance * sinLUT[angle] - SCREEN_W/4 * line_dy;

for(screen_x = 0; screen_x < SCREEN_W; screen_x += 2)
{
if(SDL_LockSurface(bitmap) != 0)
{
printf("Can't access bitmap");
exit(2);
}
if(SDL_LockSurface(screen) != 0)
{
printf("Can't access screen");
exit(2);
}
color = getPixel(bitmap, (unsigned int)space_x % IMG_W, (unsigned int)space_y % IMG_H);

setPixel(screen, screen_x, screen_y, color);
setPixel(screen, screen_x + 1, screen_y, color);
setPixel(screen, screen_x, screen_y + 1, color);
setPixel(screen, screen_x + 1, screen_y + 1, color);

SDL_UnlockSurface(screen);
SDL_UnlockSurface(bitmap);

space_x += line_dx;
space_y += line_dy;
}
}

SDL_FillRect(screen, &skyRect, SDL_MapRGB(screen->format, 255, 255, 255));
SDL_Flip(screen);
}

SDL_FreeSurface(bitmap);
SDL_Quit();

return 0;
}

void setPixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
{
    int bpp = surface->format->BytesPerPixel;

    Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;

    switch(bpp) {
    case 1:
        *p = pixel;
        break;

    case 2:
        *(Uint16 *)p = pixel;
        break;

    case 3:
        if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
            p[0] = (pixel >> 16) & 0xff;
            p[1] = (pixel >> 8) & 0xff;
            p[2] = pixel & 0xff;
        } else {
            p[0] = pixel & 0xff;
            p[1] = (pixel >> 8) & 0xff;
            p[2] = (pixel >> 16) & 0xff;
        }
        break;

    case 4:
        *(Uint32 *)p = pixel;
        break;
    }
}

Uint32 getPixel(SDL_Surface *surface, int x, int y)
{
    int bpp = surface->format->BytesPerPixel;
Uint32 value;
    Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;

    switch(bpp) {
    case 1:
        value = *p;
        break;

    case 2:
        value = *(Uint16 *)p;
        break;

    case 3:
        if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
            value = (p[0] & 0xff) | (p[1] << 8) | (p[2] << 16);
        } else {
            value = (p[2] & 0xff) | (p[1] << 8) | (p[0] << 16);
        }
        break;

    case 4:
        value = *(Uint32 *)p;
        break;
    }
return value;
}
Title: Re: Mode 7 with Ndless !
Post by: Nick on January 02, 2013, 01:26:22 pm
this is wonderful, vongratz! It looks really good :)

What game are you planning? or is it still a secret?
anyway, nice work, it might get used in future games too
Title: Re: Mode 7 with Ndless !
Post by: Lionel Debroux on January 02, 2013, 01:31:47 pm
Looks good, indeed :)
For some game types, the camera is at a lower altitude bove ground, and closer to horizontal position (lower angle value).
Title: Re: Mode 7 with Ndless !
Post by: Matrefeytontias on January 02, 2013, 01:32:00 pm
Thanks :)

I'll surely do an F-Zero game, I don't want to make something more difficult than that ;D

EDIT : ninja'd :ninja:

@ldebroux yeah I know, but I got problems with scaling (b/c the texture is too large), I didn't find any better way than growing the camera (I'll fix that later).

Someone has a solution for the file loading thing ?
Title: Re: Mode 7 with Ndless !
Post by: ElementCoder on January 02, 2013, 01:36:43 pm
This looks nice. But what exactly is Mode 7? I've seen it quite a few times by now.
Title: Re: Mode 7 with Ndless !
Post by: Lionel Debroux on January 02, 2013, 01:38:30 pm
https://en.wikipedia.org/wiki/Mode7 :)
Title: Re: Mode 7 with Ndless !
Post by: ElementCoder on January 02, 2013, 01:42:47 pm
I kinda knew someone would post that :P I guess Linear Algebra has its uses after all :P
I'll surely do an F-Zero game, I don't want to make something more difficult than that ;D
Even not knowing (before wikipedia) what Mode7 was, I immediately thought about this. Please do it :D
Title: Re: Mode 7 with Ndless !
Post by: Matrefeytontias on January 03, 2013, 05:43:57 am
Sprite ! ;D

I post with only this small update because it was such a pain to make the texture load relative and the masked sprite routine :P

(http://mattias.refeyton.fr/espace-ti/mode7/nspire/mode7groundSprite.gif)
Title: Re: Mode 7 with Ndless !
Post by: ElementCoder on January 03, 2013, 06:01:21 am
O_O Blue Falcon :D You're not supposed to go backwards :P This is looking great, keep it up you have my support :)
Title: Re: Mode 7 with Ndless !
Post by: Matrefeytontias on January 03, 2013, 06:09:40 am
I created another topic F-Zero : TrackSpire (http://ourl.ca/18072) because it's now the subject. So I lock this topic.