- 1995-style multimedia experience -

VGA strongly recommended!

(TELNET version comming soon)

[A link to the past...]


/home/śmigło .::.

31.08.2019

DREZYNA: cleanup. (Neverending story...)


07.07.2019

DREZYNA: added lens flare effect (sort of...). This is Z-buffer-based and typical high-level emulators will fail to render. CEN64 recommended, as always, or some real hardware maybe.


25.01.2019

DREZYNA: clean up.


23.06.2018

Just two small things. First, this:

resize_Vec( self, self->max_el + 16 );

was what made my metaballs so slow. Should be rather:

resize_Vec( self, self->max_el << 1 );

See the difference: DREZYNA

Second, still learning Rust, so I've made some cleanup in lwo2ultra code.


04.04.2018

Do you like 3D metaballs? Obviously you do! Download new DREZYNA and contemplate them. The implementation is SLOW, deliberately, to keep you safe from the modern 60 fps insanity... Far from! Moreover, some bugs were fixed and now it works without Expansion Pack. There was a small naming change in static mesh, so lwo2ultra 1.5.1 is provided as well. See you next time!


03.08.2017

lwo2ultra 1.5.0
Program's output now contains data useful for display list relocation. On the N64, only the first 1MB of ROM is copied to RAM during boot; having more than this requires transfering stuff from ROM to RAM manually. Destination address is unknown at compile time (I use malloc), so dynamic relocation is needed. Check out latest DREZYNA; note that it requires expansion pack and may not work on Project64. Runs on CEN64 and Nemu. Still don't know how it would behave on real hardware.


12.04.2017

lwo2ultra 1.4.0
The winter is over and some of you wake up to establish a 56k modem connection. What can be expected?
-added function for tiling large textures (the -t switch)
-fixed a bug in texture coordinate conversion
-replaced lodepng with imagefmt library (supports: BMP, JPEG, PNG, TGA)
-added option for object naming (-n)
-updated myheader.h

I've also updated DREZYNA to give an example of what that tiling feature can be used for.

Happy Easter!


08.01.2017

DREZYNA update; features less entropic code and some basic lighting.


23.12.2016

Dear Santa,

I'm 10 years old and interested in making games for oldschool hardware. I find lwo2ultra (...) a good aid in developing N64 programs and have a wish: to get a version that supports some reasonable texture format, like PNG.

Little Joe, America


Dear Santa Claus,

have you ever heard about lwo2ultra? Being so useful for Ninny coders, it's a shame that author forgot about converting data from Left-Handed System to RHS... (...)

Matti, 12-yo, Finland




Having received millions of letters like these from children, how could I resist? Hired some of my best staff and devoted thousands of elf-years to bring you an experimental reimplementation in Rust:

lwo2ultra-1.3-alpha

(supported by libraries: lodepng, getopts)

Merry Christmas!

BTW: This requires some not-so-old PC to run with an acceptable speed. I/O in Rust seem to be incredibly slow when taken with a naive, first-tought approach. Not being sarcastic: C version for Amiga 1200 would rather outperform this one running on a ~GHz CPU. Heh. The perceived lag doesn't seem so big for a typical N64 texture sizes, however.

Probably you don't care anyway...

Numbers show that children favor PSX over N64, actually.


22.07.2016

DREZYNA - first release.


15.07.2016

lwo2ultra 1.2 released.



DREZYNA
ROM images and sources:
31.08.2019
07.07.2019
25.01.2019
23.06.2018
04.04.2018
03.08.2017 (expansion pack required; may not work with Project64)
12.04.2017
08.01.2017
22.07.2016

A simple 3d engine for Nintendo 64, developed mostly with CEN64 and Project64 emulators. Didn't have an opportunity to check how it runs on real hardware, though.





lwo2ultra

sources & linux executable:
v1.5.2
v1.5.1
v1.5.0
v1.4.0
v1.3-alpha
v1.2
v1.1

This thing converts a Lightwave object (LWO2) into a Nintendo 64 display list (F3DEX GBI).

Currently there's support for shading (per-vertex normals) and texture mapping (VMAP/VMAD chunks). Polygons in a single layer should refer to only one surface definition - if more than one surface is referenced, you get a yellow card. :) (in other words, all polygons in a layer share the same material). This will be fixed in the future (maybe).
Supported texture formats are: BMP, JPEG, PNG, TGA. Colors are counted and texture is 'downgraded' accordingly:
more than 16 colors -> RGBA 5:5:5:1 and you get a table of 16-bit texels.
no more than 16 colors -> a table of 16-bit (RGBA 5:5:5:1) values for the palette and a table of 4bit color indices packed into 8-bit values (high nibble refers to left pixel, as expected).


>Usage notes

Floating point values are converted to 16-bit integers - make sure that your input object is scaled properly (-s option).

Try to behave nicely:

lwo2ultra inputfile [-o outfile] [-s scalefactor] [-n name] [-t]

(inputfile must be first on the option list.)


>Tiling

Small texture memory in the RDP is a pain. To overcome this somehow, you may load parts of a large image into TMEM and render polygons in groups sharing these parts. The -t switch allows lwo2ultra to split object into such parts, each with a 'tile descriptor' giving information about which part of the image should be loaded. Note however, that the object must be properly subdivided. If you'd like to render a rectangle with a BIG 256x256 texture on it, you should subdivide it into smaller polygons (such that they are covered by - say - 32x32 texels). But you don't have to manually 'chop' the texture, create new layers and associate them with polys - as you would have to with previous versions. When subdividing, it might be a good idea to make polygons which aren't exactly covered by a largest TMEM-fittable tile. If rendering with bilinear filter, it's good to leave a bit of margin to be able to load texels surrounding right and bottom edges - this allows preventing 'seams' on polygon edges. Currently tiling gives unoptimized output - you get a new layer for EACH POLYGON.


File myheader.h provides structure declarations for use with the output code.

Output looks like this:

#include "myheader.h"

/* vertices for layer 0 */
static Vtx vts0[] = {
  ...
};

/* display list for layer 0 */
static Gfx drawmesh0[] = {
  ...
};

...

/* vertices for layer N */
static Vtx vtsN[] = {
  ...
};
/* diplay list for layer N */
static Gfx drawmeshN[] = {
  ...
};

/* texture 0 (RGBA 5:5:5:1) */
static u16 texture0[] = {
  ...
}

/* texture 1 palette */
static u16 palette1[] = {
  ...
}

/* texture 1 (4-bit indexes to palette, packed) */
static u8 texture1[] = {
  ...
}

...

/* texture M */
static u16 textureM[] = {
  ...
}

/* texture attributes */
static Texture textures[] = {
  TEXTURE_INIT(width0, height0, &texture0, NULL, format0),
  TEXTURE_INIT(width1, height1, &texture1, &palette1, format1),
  ...
  TEXTURE_INIT(widthM, heightM, &textureM, &paletteM, formatM),
}

/* materials */
static Material materials[] = {
  MATERIAL_INIT( VECTOR4F_SET( r, g, b, a ), TEXTUREMAPPING_TYPE, TEXTURE_ID ),
}

/* table of layers that build a mesh. */
static Layer layers[] = {
  LAYER_INIT( MATERIALS_INDEX_0, drawmesh0, sizeof(drawmesh_0), vts0, sizeof(vts0),  RECTANGLE_INIT(0, 0, 0, 0), LAYERATTRIBUTE_NONE )
  LAYER_INIT( MATERIALS_INDEX_1, drawmesh1, sizeof(drawmesh_1), vts1, sizeof(vts1),  RECTANGLE_INIT(0, 0, 0, 0), LAYERATTRIBUTE_NONE )
  ...
};

StaticMesh mesh = STATICMESH_INIT( layers, NUM_LAYERS, materials, NUM_MATERIALS, textures, NUM_TEXTURES );



Hello, mr 6502

Atari executable & sources

Atari 8-bit demo made by Dely (graphics), Miker (music) and me (code). Also, there's a music player written by Fox/Taquart.
First shown at Głuchołazy 2008 demo compo.



EPILOGUE

You can write to me: l p . a i r e t n i [t a] s o l t a m


HTML 2.0 compliant :)