Get JBit at SourceForge.net. Fast, secure and Free Open Source software downloads

[ Home | Documentation | Gallery | Download | Demo | GameKit ]
[ Info | MIDlet | Sheets | SDK ]

Demo (SDK)

Programs
Assembly: bgcol1 bgcol2 charset ciao fill1 fill2 gamekeys idummy iload ipnggen1 ipnggen2 irawrgba keypad loop1 loop2 loop3 maze resize setpal sprites stdpal tiles vintage C: bounce cciao clock cpubm dpyinfo fps gperf hello mandelbrot newline pngtest rand time

Support Files
c64jb.c cgetc.s chline.s clock.s clrscr.s color.s cputc.s crt0.s ctype.s cvline.s gotox.s gotoxy.s gotoy.s header.s jbit.cfg jbit.h jbit.inc kbhit.s mainargs.s randomize.s vsync.s wherex.s wherey.s _scrsize.s _systime.s

+----------+
|          |
|  JBitRT  |
|  MIDlet  |
| Emulator |
|          |
|  1 2 3   |
|  4 5 6   |
|  7 8 9   |
|  * 0 #   |
|          |
+----------+

mandelbrot.jb

/*****************************************************************************
 * mandelbrot sample program for cc65.                                       *
 *                                                                           *
 * (w)2002 by groepaz/hitmen, TGI support by Stefan Haubenthal               *
 * JBit port by Emanuele Fornara                                             *
 *****************************************************************************/

/*

  JBit is very slow here.

  The IO chip might get a math (int/float/double) subsystem in the future;
  on one hand it would be easy to implement, on the other hand I don't
  consider it a priority and it would force the split of the MIDP2
  distribution in two versions (CLDC 1.0/1.1).

  This demo allows us to:

  - Have a reference for future CPU/VM optimizations.
  - Test the stability of JBit and the accuracy of the 6502 emulation.
  - Test the PNG generator with multiple deflate blocks.
  - Post a nice screenshot.

*/

#include <stdlib.h>
#include <time.h>
#include <conio.h>

#include <jbit.h>
#define CLK_TCK 100


/* Graphics definitions */
signed short SCREEN_X;
signed short SCREEN_Y;
unsigned char MAXCOL;

/*

  Poor Man's TGI
  ==============

  TGI is not supported in JBit; the gfx model of the MIDP platform is too
  different from the one you can find in most real 8-bit machines.
  In MIDP you create an immutable image and then render it to the display.
  Screens in games are usually drawn by composing parts of immutable images.

  In other words, in JBit there is no framebuffer that can be updated in
  real-time; what we do here is to stream the pixels one by one to the IO chip
  to generate an immutable image. At the end the image is shown.

  JBit will eventually get some drawing primitives (e.g. lines, rectangles,
  arcs, etc...) of its own; that's what IEMPTY and IMKIMMUT are for.

*/

// #define USE_RGBA

#define IMAGE_ID 1

static unsigned char palette[] = {
	0x00, 0x40, 0x80, 0xA0, 0xA8, 0xB0, 0xB8, 0xC0,
	0xC8, 0xD0, 0xD8, 0xE0, 0xE8, 0xF0, 0xF8, 0xFF
};

static unsigned char is_color;

#ifdef USE_RGBA

#define tgi_setcolor(color) ( \
	is_color ? \
	( \
		req_put(0), \
		req_put(0), \
		req_put(palette[color]), \
		req_put(255) \
	) : ( \
		req_put(palette[color]), \
		req_put(palette[color]), \
		req_put(palette[color]), \
		req_put(255) \
	) \
)

#else

#define tgi_setcolor(color) req_put(color)

#endif

#define tgi_setpixel(x, y)

static void tgi_init()
{
	req_put(REQ_DPYINFO);
	req_end();
	SCREEN_X = *(unsigned*)&IODAT[DPYINFO_WIDTH];
	SCREEN_Y = *(unsigned*)&IODAT[DPYINFO_HEIGHT];
	is_color = IODAT[DPYINFO_FLAGS] & DPYINFO_FLAGS_ISCOLOR;
	MAXCOL = 16;
	// SCREEN_X = 24; SCREEN_Y = 24;
}

static void tgi_done()
{
	IO[ENABLE] = ENABLE_BGCOL | ENABLE_CONSOLE;
}

static void png_begin()
{
	unsigned char color;

	req_put(REQ_IPNGGEN); // Create a new image using the PNG generator
	req_put(IMAGE_ID);
	req_put(SCREEN_X & 0xFF); // Width (u16)
	req_put(SCREEN_X >> 8);
	req_put(SCREEN_Y & 0xFF); // Height (u16)
	req_put(SCREEN_Y >> 8);
	req_put(8); // Depth (8 bpp = 256 levels/colors)
#ifdef USE_RGBA
	req_put(IPNGGEN_CT_TRUECOLOR_ALPHA); // Color type
	req_put(0); // Flags
#else
	req_put(IPNGGEN_CT_INDEXED_COLOR); // Color type
	req_put(0); // Flags
	req_put(MAXCOL - 1);
	for (color = 0; color < MAXCOL; color++) {
		req_put(is_color ? 0 : palette[color]); // red
		req_put(is_color ? 0 : palette[color]); // green
		req_put(palette[color]); // blue
	}
#endif
}

static void png_end()
{
	req_end();
	if (IO[REQRES] != 0) {
		unsigned char i, c;
		req_put(REQ_IDUMMY);
		req_put(IMAGE_ID);
		req_put(IDUMMY_SIMPLE);
		req_put(SCREEN_X & 0xFF); // Width (u16)
		req_put(SCREEN_X >> 8);
		req_put(SCREEN_Y & 0xFF); // Height (u16)
		req_put(SCREEN_Y >> 8);
		req_put(COLOR_BLACK); // background
		req_put(COLOR_RED); // foreground
		for (i = 0; c = "PNGGEN Err"[i]; i++)
			req_put(c);
		req_end();
	}
	req_put(REQ_SETBGIMG);
	req_put(IMAGE_ID);
	req_end();
	IO[ENABLE] = ENABLE_BGCOL | ENABLE_BGIMG;
}


#define maxiterations   32
#define fpshift         (10)
#define tofp(_x)        ((_x)<<fpshift)
#define fromfp(_x)      ((_x)>>fpshift)
#define fpabs(_x)       (abs(_x))

#define mulfp(_a,_b)    ((((signed long)_a)*(_b))>>fpshift)
#define divfp(_a,_b)    ((((signed long)_a)<<fpshift)/(_b))

/* Use static local variables for speed */
#pragma staticlocals (1);



void mandelbrot (signed short x1, signed short y1, signed short x2,
		 signed short y2)
{
    register unsigned char count;
    register signed short r, r1, i;
    register signed short xs, ys, xx, yy;
    register signed short x, y;

    /* calc stepwidth */
    xs = ((x2 - x1) / (SCREEN_X));
    ys = ((y2 - y1) / (SCREEN_Y));

    yy = y1;
    for (y = 0; y < (SCREEN_Y); y++) {
	gotoxy(0, 0);
        cprintf("%03u", y + 1);
	vsync();
	yy += ys;
	xx = x1;
	for (x = 0; x < (SCREEN_X); x++) {
	    xx += xs;
	    /* do iterations */
	    r = 0;
	    i = 0;
	    for (count = 0; (count < maxiterations) &&
		 (fpabs (r) < tofp (2)) && (fpabs (i) < tofp (2));
		 ++count) {
		r1 = (mulfp (r, r) - mulfp (i, i)) + xx;
		/* i = (mulfp(mulfp(r,i),tofp(2)))+yy; */
		i = (((signed long) r * i) >> (fpshift - 1)) + yy;
		r = r1;
	    }
	    if (count == maxiterations) {
		tgi_setcolor (0);
	    } else {
		if (MAXCOL == 2)
		    tgi_setcolor (1);
		else
		    tgi_setcolor (count % MAXCOL);
	    }
	    /* set pixel */
	    tgi_setpixel (x, y);
	}
    }
}

int main (void)
{
    clock_t t;
    unsigned long sec;
    unsigned sec10;

    /* Initialize graphics */
    tgi_init ();

    IO[CONCOLS] = 7;
    IO[CONROWS] = 1;
    clrscr ();
    cprintf("---/%03u", SCREEN_Y);

    t = clock ();

    /* calc mandelbrot set */
    png_begin();
    mandelbrot (tofp (-2), tofp (-2), tofp (2), tofp (2));
    png_end();

    t = clock () - t;

    /* Fetch the character from the keyboard buffer and discard it */
    (void) cgetc ();

    /* shut down gfx mode and return to textmode */
    tgi_done ();

    /* Calculate stats */
    sec = (t * 10) / CLK_TCK;
    sec10 = sec % 10;
    sec /= 10;

    /* Output stats */
    clrscr ();
    cprintf ("%lu.%us", sec, sec10);

    /* Wait for a key, then end */
    (void) cgetc ();

    /* Done */
    return EXIT_SUCCESS;

}

mandelbrot.c