Buddha - a new 'Game'

Use this forum to share and discuss Uzebox games and demos.
Post Reply
User avatar
PitfallJones
Posts: 39
Joined: Mon Aug 16, 2010 12:01 am

Buddha - a new 'Game'

Post by PitfallJones » Sat Sep 06, 2014 10:40 pm

Hi All,

Here's a little program that should give hours of enlightenment!
buddha640.jpg
buddha640.jpg (84.13 KiB) Viewed 4004 times
Enjoy!

- PJ
Attachments
buddha.zip
(58.65 KiB) Downloaded 529 times

User avatar
D3thAdd3r
Posts: 2430
Joined: Wed Apr 29, 2009 10:00 am
Location: Minneapolis, United States

Re: Buddha - a new 'Game'

Post by D3thAdd3r » Sun Sep 07, 2014 1:55 am

Well, this is by far the most tranquil program that has graced the Uzebox. It wouldn't be a bad "screen saver" if you felt like adding some enlightenment to your evening. Good graphics and very good flute sound BTW...for some reason, I feel like lighting a candle, yes I think I'll do that now :)

User avatar
Gosma
Posts: 67
Joined: Thu Oct 24, 2013 7:31 pm
Location: Santos, Brazil

Re: Buddha - a new 'Game'

Post by Gosma » Sun Sep 07, 2014 2:28 pm

Liked the graphic and the phrases.

User avatar
uze6666
Site Admin
Posts: 4487
Joined: Tue Aug 12, 2008 9:13 pm
Location: Montreal, Canada
Contact:

Re: Buddha - a new 'Game'

Post by uze6666 » Mon Sep 08, 2014 2:20 am

Clever idea and very well done..and soo soothing... 8-) How many proverbs were you able to pack in?

User avatar
PitfallJones
Posts: 39
Joined: Mon Aug 16, 2010 12:01 am

Re: Buddha - a new 'Game'

Post by PitfallJones » Tue Sep 09, 2014 3:19 pm

Hi Guys,

Thanks for the feedback.

There are 35 phrases in there and I compress them with huffman encoding.

The program is 56276 bytes long so there would be room for lots more but that felt about right.

It uses the 6x8 tiled mode which gives a more compact font than 8x8 would. I would have liked to stagger the message at 1/2 character spacing which I did on a BBC Micro version of Buddha but that wasn't tile based.

The tileset uses a lot of tiles, especially with the graduated sky.

The 'c' compiler actually fails to compile the tileset with a 'warning excess elements in array initializer' error.

Code: Select all

const unsigned char ts_data_0[48*826] PROGMEM ={...}
which is untrue.

Anyway I got round that problem by putting the tileset in a '.s' file like:

Code: Select all

.section .progmem.data
.align 8
ts_data_0:
#include "ts.s"
I had a lot of fun making the envelopes for the tune - I always think the Uzebox has a nice warm sound.

The graphics are actually re-colored from the ZX Spectrum 8-bit game of 'Way of the Exploding Fist' - the Uzebox has a much better palette!

There is a hidden 'feature' but it might not be easy to find - waiting a long time once a message is displayed might give a clue :-)

- PJ

User avatar
Artcfox
Posts: 1029
Joined: Thu Jun 04, 2015 5:35 pm
Contact:

Re: Buddha - a new 'Game'

Post by Artcfox » Wed Jun 17, 2020 11:45 pm

Necroposting on a really old thread, because ever since I've gotten my Uzebox, I've been fascinated by the music in this "game."

It sounds very different from the music on any other Uzebox game, and I always wanted to know why, but the source code was never posted.

I've spent the past few days looking at the raw hexdump of BUDDHA.uze, and found where the custom wave table was stored, and where the MIDI was, and then decoded the PatchStruct, and each of the patches. Then I realized that when playing the song, it doesn't actually use any patches that are defined with the custom wave table, it just uses really nice envelopes to get that perfect sound.

For some reason I wanted an actual MIDI, so I used the hexdump along with Rosegarden to transcribe each note. In the process I found a few "bugs" in the song that's included in the Buddha game. The Uzebox can only play one note per track, and in a few places there were multiple notes defined on a single track at the same time, so I either moved them to another track that had the same patch defined for its instrument, or deleted that note because I realized it was already being played at the same exact time on another track.

If anyone knows the name of the song, please let me know.

Here it is in sheet music form:
BUDDHA.png
BUDDHA.png (387.23 KiB) Viewed 944 times
And here is the above sheet music (sped up 2x) in MIDI form:
buddha-midi.zip
(908 Bytes) Downloaded 29 times

In case anyone else is curious, here are the patches and PatchStruct from the original:

Code: Select all

const char a85e[] PROGMEM = {
0,PC_WAVE,0,
0,PC_ENV_VOL,24,
0,PC_ENV_SPEED,1,
16,PC_ENV_SPEED,-1,
0,PATCH_END
};

const char a86c[] PROGMEM = {
0,PC_WAVE,5,
0,PC_ENV_VOL,0,
0,PC_ENV_SPEED,12,
4,PC_ENV_SPEED,-2,
0,PATCH_END
};

const char a87a[] PROGMEM = {
0,PC_WAVE,5,
0,PC_ENV_VOL,0,
0,PC_ENV_SPEED,48,
1,PC_ENV_SPEED,-2,
8,PC_ENV_SPEED,-4,
0,PATCH_END
};

const char a88b[] PROGMEM = {
0,PC_WAVE,0,
0,PC_ENV_VOL,0,
0,PC_ENV_SPEED,2,
8,PC_ENV_SPEED,-2,
8,PATCH_END
};

const char a899[] PROGMEM = {
0,PC_WAVE,0,
0,PC_ENV_VOL,0,
0,PC_ENV_SPEED,2,
12,PC_ENV_SPEED,-2,
24,PATCH_END
};

const char a8a7[] PROGMEM = {
0,PC_NOISE_PARAMS,1,
0,PC_TREMOLO_LEVEL,100,
0,PC_TREMOLO_RATE,20,
0,PC_ENV_SPEED,1,
0,PC_ENV_VOL,0,
10,PC_ENV_SPEED,0,
200,PATCH_END
};

const char a8bb[] PROGMEM = {
0,PC_NOISE_PARAMS,1,
0,PC_TREMOLO_LEVEL,100,
0,PC_TREMOLO_RATE,20,
0,PC_ENV_SPEED,-1,
0,PC_ENV_VOL,10,
10,PATCH_END
};

const char a8cc[] PROGMEM = {
0,PC_NOISE_PARAMS,3,
0,PC_TREMOLO_LEVEL,100,
0,PC_TREMOLO_RATE,20,
0,PC_ENV_SPEED,1,
0,PC_ENV_VOL,0,
10,PC_ENV_SPEED,0,
200,PATCH_END
};

const char a8e0[] PROGMEM = {
0,PC_NOISE_PARAMS,3,
0,PC_TREMOLO_LEVEL,100,
0,PC_TREMOLO_RATE,20,
0,PC_ENV_SPEED,-1,
0,PC_ENV_VOL,10,
10,PATCH_END
};

const struct PatchStruct patches[] PROGMEM = {
{0,0,a85e,0,0},
{0,0,a899,0,0},
{0,0,a899,0,0},
{0,0,a85e,0,0},
{1,0,a8a7,0,0},
{1,0,a8cc,0,0},
{1,0,a8bb,0,0},
{1,0,a8e0,0,0},
};
And here is the original Uzebox-specific MIDI (with the polyphonic note bugs annotated):

Code: Select all

//*********************************//
// MIDI file: midisong.h
//*********************************//

// Likely generated using 1/4 notes at the default tempo of 120bpm
// with: midiconv -f 5.6 midisong.mid midisong.h

const char midisong[] PROGMEM ={

0x00,0xff,0x06,0x01,0x53,

0x00,0xc0,0x00,
0x00,0xc1,0x00,
0x00,0xc2,0x00,

0x2d,0x90,0x40,0x7f,
0x00,0x91,0x54,0x7f,
0x2d,0x90,0x40,0x7f,
0x00,0x91,0x54,0x7f,
0x2d,0x90,0x40,0x7f,
0x00,0x91,0x54,0x7f,

0x00,0xc1,0x01,
0x00,0xc2,0x02,

0x2d,0x91,0x45,0x7f,
0x2d,0x91,0x40,0x7f,
0x16,0x91,0x45,0x7f,
0x17,0x91,0x47,0x7f,
0x16,0x91,0x4c,0x7f,
0x17,0x91,0x48,0x7f,
0x16,0x91,0x47,0x7f,
0x17,0x91,0x45,0x7f,
0x2d,0x91,0x40,0x7f,
0x16,0x91,0x45,0x7f,
0x17,0x91,0x47,0x7f,
0x16,0x91,0x4c,0x7f,
0x17,0x91,0x48,0x7f,
0x16,0x91,0x47,0x7f,
0x17,0x91,0x45,0x7f,
0x16,0x91,0x40,0x7f,
0x17,0x91,0x47,0x7f,
0x16,0x91,0x40,0x7f,
0x17,0x91,0x48,0x7f,
0x16,0x91,0x40,0x7f,
0x17,0x91,0x47,0x7f,
0x16,0x91,0x40,0x7f,
0x17,0x91,0x45,0x7f,
0x16,0x91,0x40,0x7f,
0x17,0x91,0x47,0x7f,
0x16,0x91,0x45,0x7f,
0x17,0x91,0x41,0x7f,
0x16,0x91,0x3e,0x7f,
0x17,0x91,0x40,0x7f,
0x16,0x91,0x41,0x7f,
0x17,0x91,0x40,0x7f,
0x16,0x91,0x39,0x7f,
0x17,0x91,0x3c,0x7f,
0x16,0x91,0x39,0x7f,
0x17,0x91,0x40,0x7f,
0x16,0x91,0x39,0x7f,
0x17,0x91,0x41,0x7f,
0x16,0x91,0x39,0x7f,
0x17,0x91,0x40,0x7f,
0x16,0x91,0x39,0x7f,
0x17,0x91,0x3c,0x7f,
0x16,0x91,0x40,0x7f,
0x17,0x91,0x3b,0x7f,
0x16,0x91,0x40,0x7f,
0x17,0x91,0x3c,0x7f,
0x16,0x91,0x3b,0x7f,
0x17,0x91,0x39,0x7f,
0x16,0x91,0x45,0x7f,
0x17,0x91,0x3b,0x7f,
0x16,0x91,0x47,0x7f,
0x17,0x91,0x3c,0x7f,
0x16,0x91,0x48,0x7f,
0x17,0x91,0x3b,0x7f,
0x16,0x91,0x47,0x7f,
0x17,0x91,0x39,0x7f,
0x16,0x91,0x45,0x7f,
0x17,0x91,0x47,0x7f,
0x16,0x91,0x45,0x7f,
0x17,0x91,0x41,0x7f,
0x16,0x91,0x3e,0x7f,
0x17,0x91,0x40,0x7f,
0x16,0x91,0x41,0x7f,
0x17,0x91,0x40,0x7f,
0x16,0x91,0x39,0x7f,
0x17,0x91,0x3c,0x7f,
0x16,0x91,0x39,0x7f,
0x17,0x91,0x40,0x7f,
0x16,0x91,0x39,0x7f,
0x17,0x91,0x41,0x7f,
0x16,0x91,0x39,0x7f,
0x17,0x91,0x40,0x7f,
0x16,0x91,0x39,0x7f,
0x17,0x91,0x3c,0x7f,
0x16,0x91,0x40,0x7f,
0x17,0x91,0x3b,0x7f,
0x16,0x91,0x40,0x7f,
0x17,0x91,0x45,0x7f,
0x16,0x91,0x47,0x7f,
0x17,0x91,0x45,0x7f,
0x16,0x91,0x40,0x7f,
0x17,0x91,0x45,0x7f,
0x16,0x91,0x48,0x7f,
0x17,0x91,0x47,0x7f,
0x16,0x91,0x4c,0x7f,
0x17,0x91,0x48,0x7f,
0x16,0x91,0x47,0x7f,
0x17,0x91,0x45,0x7f,
0x16,0x91,0x3c,0x7f,
0x17,0x91,0x40,0x7f,
0x16,0x91,0x45,0x7f,
0x17,0x91,0x47,0x7f,
0x16,0x91,0x4c,0x7f,
0x17,0x91,0x48,0x7f,
0x16,0x91,0x47,0x7f,
0x17,0x91,0x4c,0x7f,
0x00,0x91,0x40,0x7f, /* < should be 0x92 */
0x2d,0x91,0x41,0x7f,
0x00,0x91,0x4d,0x7f, /* < should be 0x92 */
0x2d,0x91,0x47,0x7f,
0x00,0x91,0x53,0x7f, /* < should be 0x92 */
0x16,0x91,0x45,0x7f,
0x00,0x91,0x51,0x7f, /* < should be 0x92 */
0x17,0x91,0x41,0x7f,
0x00,0x91,0x4d,0x7f, /* < should be 0x92 */
0x2d,0x91,0x40,0x7f,
0x00,0x91,0x4c,0x7f, /* < should be 0x92 */
0x16,0x91,0x45,0x7f,
0x17,0x91,0x47,0x7f,
0x16,0x91,0x4a,0x7f,
0x17,0x91,0x4c,0x7f,
0x42,0x91,0x51,0x7f,
0x00,0x92,0x45,0x7f,
0x2d,0x91,0x51,0x7f,
0x00,0x92,0x40,0x7f,
0x16,0x92,0x45,0x7f,
0x17,0x91,0x53,0x7f,
0x00,0x92,0x47,0x7f,
0x16,0x92,0x4c,0x7f,
0x17,0x92,0x48,0x7f,
0x16,0x92,0x47,0x7f,
0x17,0x91,0x51,0x7f,
0x00,0x92,0x45,0x7f,
0x2d,0x91,0x51,0x7f,
0x00,0x92,0x40,0x7f,
0x16,0x92,0x45,0x7f,
0x17,0x91,0x53,0x7f,
0x00,0x92,0x47,0x7f,
0x16,0x92,0x4c,0x7f,
0x17,0x92,0x48,0x7f,
0x16,0x92,0x47,0x7f,
0x17,0x91,0x51,0x7f,
0x00,0x92,0x45,0x7f,
0x16,0x92,0x40,0x7f,
0x17,0x91,0x53,0x7f,
0x00,0x92,0x47,0x7f,
0x16,0x92,0x40,0x7f,
0x17,0x91,0x54,0x7f,
0x00,0x92,0x48,0x7f,
0x16,0x92,0x40,0x7f,
0x17,0x91,0x53,0x7f,
0x00,0x92,0x47,0x7f,
0x16,0x92,0x40,0x7f,
0x17,0x91,0x51,0x7f,
0x00,0x92,0x45,0x7f,
0x16,0x92,0x40,0x7f,
0x17,0x91,0x53,0x7f,
0x00,0x92,0x47,0x7f,
0x16,0x91,0x51,0x7f,
0x00,0x92,0x45,0x7f,
0x17,0x91,0x4d,0x7f,
0x00,0x92,0x41,0x7f,
0x16,0x92,0x3e,0x7f,
0x17,0x92,0x40,0x7f,
0x16,0x92,0x41,0x7f,
0x17,0x91,0x4c,0x7f,
0x00,0x92,0x40,0x7f,
0x16,0x92,0x39,0x7f,
0x17,0x91,0x48,0x7f,
0x00,0x92,0x3c,0x7f,
0x16,0x92,0x39,0x7f,
0x17,0x91,0x4c,0x7f,
0x00,0x92,0x40,0x7f,
0x16,0x92,0x39,0x7f,
0x17,0x91,0x4d,0x7f,
0x00,0x92,0x41,0x7f,
0x16,0x92,0x39,0x7f,
0x17,0x91,0x4c,0x7f,
0x00,0x92,0x40,0x7f,
0x16,0x92,0x39,0x7f,
0x17,0x91,0x4c,0x7f,
0x00,0x92,0x3c,0x7f,
0x16,0x91,0x48,0x7f,
0x00,0x92,0x40,0x7f,
0x17,0x91,0x47,0x7f,
0x00,0x92,0x3b,0x7f,
0x16,0x92,0x40,0x7f,
0x17,0x92,0x3c,0x7f,
0x16,0x92,0x3b,0x7f,
0x17,0x91,0x51,0x7f,
0x00,0x92,0x39,0x7f,
0x16,0x92,0x45,0x7f,
0x17,0x91,0x53,0x7f,
0x00,0x92,0x3b,0x7f,
0x16,0x92,0x47,0x7f,
0x17,0x91,0x54,0x7f,
0x00,0x92,0x3c,0x7f,
0x16,0x92,0x48,0x7f,
0x17,0x91,0x53,0x7f,
0x00,0x92,0x3b,0x7f,
0x16,0x92,0x47,0x7f,
0x17,0x91,0x51,0x7f,
0x00,0x92,0x39,0x7f,
0x16,0x92,0x45,0x7f,
0x17,0x91,0x53,0x7f,
0x00,0x92,0x47,0x7f,
0x16,0x91,0x51,0x7f,
0x00,0x92,0x45,0x7f,
0x17,0x91,0x4d,0x7f,
0x00,0x92,0x41,0x7f,
0x16,0x92,0x3e,0x7f,
0x17,0x92,0x40,0x7f,
0x16,0x92,0x41,0x7f,
0x17,0x91,0x4c,0x7f,
0x00,0x92,0x40,0x7f,
0x16,0x92,0x39,0x7f,
0x17,0x91,0x48,0x7f,
0x00,0x92,0x3c,0x7f,
0x16,0x92,0x39,0x7f,
0x17,0x91,0x4c,0x7f,
0x00,0x92,0x40,0x7f,
0x16,0x92,0x39,0x7f,
0x17,0x91,0x4d,0x7f,
0x00,0x92,0x41,0x7f,
0x16,0x92,0x39,0x7f,
0x17,0x91,0x4c,0x7f,
0x00,0x92,0x40,0x7f,
0x16,0x92,0x39,0x7f,
0x17,0x91,0x4c,0x7f,
0x00,0x92,0x3c,0x7f,
0x16,0x91,0x48,0x7f,
0x00,0x92,0x40,0x7f,
0x17,0x91,0x47,0x7f,
0x00,0x92,0x3b,0x7f,
0x16,0x92,0x40,0x7f,
0x17,0x92,0x45,0x7f,
0x16,0x92,0x47,0x7f,
0x17,0x91,0x51,0x7f,
0x00,0x92,0x45,0x7f,
0x16,0x92,0x40,0x7f,
0x17,0x91,0x51,0x7f,
0x00,0x92,0x45,0x7f,
0x16,0x92,0x48,0x7f,
0x17,0x91,0x53,0x7f,
0x00,0x92,0x47,0x7f,
0x16,0x92,0x4c,0x7f,
0x17,0x92,0x48,0x7f,
0x16,0x92,0x47,0x7f,
0x17,0x91,0x51,0x7f,
0x00,0x92,0x45,0x7f,
0x16,0x92,0x3c,0x7f,
0x17,0x91,0x51,0x7f,
0x00,0x92,0x40,0x7f,
0x16,0x92,0x45,0x7f,
0x17,0x91,0x53,0x7f,
0x00,0x92,0x47,0x7f,
0x16,0x92,0x4c,0x7f,
0x17,0x92,0x48,0x7f,
0x16,0x92,0x47,0x7f,
0x17,0x91,0x4c,0x7f,
0x00,0x92,0x4c,0x7f, /* < should be removed */
0x00,0x92,0x40,0x7f,
0x2d,0x91,0x4d,0x7f,
0x00,0x92,0x41,0x7f,
0x00,0x92,0x4d,0x7f, /* < should be removed */
0x2d,0x91,0x53,0x7f,
0x00,0x92,0x47,0x7f,
0x00,0x92,0x53,0x7f, /* < should be removed */
0x16,0x91,0x51,0x7f,
0x00,0x92,0x45,0x7f,
0x00,0x92,0x51,0x7f, /* < should be removed */
0x17,0x91,0x4d,0x7f,
0x00,0x92,0x41,0x7f,
0x00,0x92,0x4d,0x7f, /* < should be removed */
0x2d,0x91,0x4c,0x7f,
0x00,0x92,0x40,0x7f,
0x00,0x92,0x4c,0x7f, /* < should be removed */
0x16,0x92,0x45,0x7f,
0x17,0x92,0x47,0x7f,
0x16,0x92,0x4a,0x7f,
0x17,0x92,0x4c,0x7f,

0x2d,0xff,0x06,0x01,0x45,

0x00,0xff,0x2f,0x00,

0x00,0x90,0x10,0x00,
0x00,0x91,0x10,0x00,
0x00,0x92,0x10,0x00,
0x00,0x93,0x10,0x00,
0x00,0xff,0x2f,0x00

};

And finally, here is the source code (and rosegard.hex and rosegard.uze file) for a demo that plays the "reverse-engineered" lightly-patched version of the song that I sequenced with Rosegarden if you want to compare it to the original:
rosegarden_tutorial-buddha.zip
(729.42 KiB) Downloaded 26 times

I haven't figured out how to do program changes in Rosegarden, so after sequencing it all with the default instruments, I hand-edited the top of the midisong.h file to include the proper program changes to select the proper instruments.

It was really fun unlocking the secrets to the amazing music in this "game".

Great work on this PitfallJones!

User avatar
D3thAdd3r
Posts: 2430
Joined: Wed Apr 29, 2009 10:00 am
Location: Minneapolis, United States

Re: Buddha - a new 'Game'

Post by D3thAdd3r » Sun Jun 21, 2020 5:51 am

Interesting, that is impressive reverse engineering.

User avatar
Jubatian
Posts: 1471
Joined: Thu Oct 01, 2015 9:44 pm
Location: Hungary
Contact:

Re: Buddha - a new 'Game'

Post by Jubatian » Sun Jun 21, 2020 12:46 pm

Nice! Guys, that's why you are supposed to post the source somewhere accessible, eh, to play fair, we are GPL, so you should do anyway! ;) But guess it was some fun adventure to get it back from the binary! :D

Post Reply

Who is online

Users browsing this forum: Artcfox and 3 guests