Allegro.cc - Online Community

Allegro.cc Forums » Off-Topic Ordeals » [RetroHack] Start of competition

This thread is locked; no one can reply to it. rss feed Print
[RetroHack] Start of competition
Jakub Wasilewski
Member #3,653
June 2003
avatar

Quote:

I ran it, but it crashed part way through the tune (about 6 seconds into the piece)

Well the test only had one pattern, which lasts about 6 seconds :).

I'm reconsidering the whole idea of sharing this code... It's became a rather convoluted mess of things. It's all became rather idiosyncratic with a lot of work-arounds and hoops you have to jump through - documenting all of it would be a rather lengthy process. I also don't want to spend a lot of time making it easily reusable outside my audio framework, to which module playback is heavily bound...

Well, I've promised to share it, so here goes - if you figure it out, good for you :). Attached what I have to this post. It's not entirely finished, but it's working.

How to make it play something:
1) Prepare a .src file using mod2.src as a template, along with all the needed .wav's in the same directory
2) Compile it with modconvert.py (requires Python)
3) Play it back (AYTest.cpp is an example program that does that, and one we will be using to write the music).

The whole thing is in C++, and the text->binary format converter is in Python. The archive contains all needed source-files, just link all *.cpp files in both directories with Allegro.

Oh, not commented at all. And there be dragons in that code :).

EDIT: Remember, it only works properly with RH 1.0 under Windows.

---------------------------
[ ChristmasHack! | My games ] :::: One CSS to style them all, One Javascript to script them, / One HTML to bring them all and in the browser bind them / In the Land of Fantasy where Standards mean something.

Jeff Bernard
Member #6,698
December 2005
avatar

Question- Can I modify the RetroHack library to do a scanlines effect? It looks a lot better (tweaking the library a bit), rather than using the RetroHack's blit function because I can get thinner lines.

--
I thought I was wrong once, but I was mistaken.

Thomas Harte
Member #33
April 2000
avatar

Quote:

Question- Can I modify the RetroHack library to do a scanlines effect? It looks a lot better (tweaking the library a bit), rather than using the RetroHack's blit function because I can get thinner lines.

As currently drafted, that'd be against the rules. But if you send me the code, I'll try to incorporate it as an option in the coming v1.1 of the library.

Re: all that:

  • I'm not making very good progress with the AY file format. The format itself is a horrid mess, but the problem seems to be my z80 code — I think I've stripped it from its previous project quite poorly and probably broken something. But I'll keep trying.

  • I've pretty much decided I'm going to give up on the sound fixes. As the only affected platform seems to be Linux, I'll just make buffer size a compile time option. Especially as I want to get the RT_MIX palette and C++ #include fixes 'out there'

EDIT: partial update. I have fixed my AY file format music player, and uploaded it to the website. Here's a direct file link. Some documentation and a demo program are included in that archive.

Jeff Bernard
Member #6,698
December 2005
avatar

The scanlines modification I wrote is pretty basic (and probably not what actual scanlines are). Basically, it stretch_blits the buffer to a BITMAP* that is the same size as the screen, instead of blitting to the screen. Then it draws horizontal lines of color makcol(0,0,128) (because I think that looks good overlayed onto my game) at certain intervals. I don't have the code in front of me now, but the loop that draws the horizontal lines is (I'm pretty sure): for (i = 0; i < SCREEN_H; i+=3).

--
I thought I was wrong once, but I was mistaken.

Elias
Member #358
May 2000

{"name":"593618","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/7\/7\/777a600c4e59720821347fc11f93833b.png","w":640,"h":480,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/7\/7\/777a600c4e59720821347fc11f93833b"}593618
What am I doing wrong here? Both blits are drawn to 160/120 (the center). The one in the lower right corner works just as expected. But when I flip the y scaling - why do I get this shifted and enlarged blit above it? And in case that's the intended behavior, how would I get just a vertically flipped version?

(EDIT)
Ah, figured it out now by glancing at retrohack.c, you have a special case there for when the y scale is < 0.. still, it's weird - the Atari Lynx did not do any such position/size adjustments just because you used flipped drawing.

1#include "retrohack.h"
2 
3int main(void)
4{
5 rt_Init();
6 
7 unsigned char data[256 * 256];
8 int i, j;
9 for (i = 0; i < 256; i++)
10 for (j = 0; j < 256; j++)
11 data[i + j * 256] = ((i / 128) & 1) + ((j / 128) & 1) * 2;
12 void * g = rt_UploadGraphic(RT_MIX, data, 1, 256, 256, 15);
13
14 while (!rtSim_QuitWanted())
15 {
16 if ((rt_ReadKeyboard(0) & 2) == 0) break;
17 
18 // background
19 rt_Blit(g, 0, 0, 0, ftofix(320.0 / 256), ftofix(240.0 / 256), 0, 0);
20
21 // ???
22 rt_Blit(g, 15, ftofix(160), ftofix(120), ftofix(1) / 8, ftofix(-1) / 8,
23 ftofix(1 / 64.0), ftofix(-1 / 16.0 / 32.0));
24
25 // works as it should
26 rt_Blit(g, 15, ftofix(160), ftofix(120), ftofix(1) /8, ftofix(1) / 8,
27 ftofix(1 / 64.0), ftofix(-1 / 16.0 / 32.0));
28
29 rt_Flip();
30 }
31 rt_Exit();
32 return 0;
33}
34END_OF_MAIN()

--
"Either help out or stop whining" - Evert

Karies
Member #8,158
December 2006
avatar

Hello!
I have a problem when I try to make sprite rotation. I think the method I'm using is the problem then I want to know if somebody can tell me the good one for pixel rotation.

x2 and y2 are the transformed coordinates:

int x2 = (int)
( (cos((angle*PI)/180)*(i-xcenter))-(sin((angle*PI)/180)*(j-ycenter))+xcenter );

int y2 = (int)
( (sin((angle*PI)/180)*(i-xcenter))-(cos((angle*PI)/180)*(j-ycenter))+ycenter );
data[ (y2*desp) + x2] = byte;

Jakub Wasilewski
Member #3,653
June 2003
avatar

A cursory look would suggest you messed up the signs. Y2 should have sin+cos, not sin-cos. Oh, and I would suggest using the Programming Questions forum for general questions not related to RH, there is no need to clutter this thread.

Well, since I'm already making a post here, I might brag a little.

A few minutes ago, I finally managed to merge my blitter code with the tracker playback code without one farking up the other, and I'm really happy about it :). I ended up counting every single expended cycle, including peculiarities such as the AY bus having a different clock resulting in additional cycles for synchronization, and even the single cycle cost for reading the keyboard.

Well, at least now I have a cycle-perfect blitter + sound playback. It probably crashes if the amount of blits needed overloads the blitter for a given frame, but that's something to be solved tomorrow ;).

---------------------------
[ ChristmasHack! | My games ] :::: One CSS to style them all, One Javascript to script them, / One HTML to bring them all and in the browser bind them / In the Land of Fantasy where Standards mean something.

Karies
Member #8,158
December 2006
avatar

:-/ well... that was embarrassing, but... although the problem was easy to solve, it is related to retrohack. I didn't use rotate_sprite allegro method and bitmap struct because I'm beginning to make a retrohack game, and if I would ask in other thread then people could tell me other ways to do it and they couldn't give me the answer.

Thanks Jakub.. and yes, I'm a game programming newbie (trying to make a retrohack game :P)

Thomas Harte
Member #33
April 2000
avatar

Quote:

What am I doing wrong here?

Nothing, it's a RetroHack bug. It'll be fixed in V1.1 of the library, which I hope to release tonight. In the meantime, you can fix it yourself by going into retrohack.c, finding the segment that starts at like 449 and looks like this:

  else
  {
    srcy = (g->images[0]->h << 22) - 1; // start at the bottom, draw upward

    y += scaley*g->images[0]->h; // move up the required number of pixels
    x -= skew*g->images[0]->h;
    scalex -= scalechange*g->images[0]->h;
  }

And replacing it with:

  else
  {
    int yadd = scaley*g->images[0]->h;

    srcy = (g->images[0]->h << 22) - 1; /* start at the bottom, draw upward */

    y += yadd; /* move up the required number of pixels */
    x -= fixmul(yadd, skew); skew = -skew;
    scalex -= fixmul(yadd, scalechange); scalechange = -scalechange;
  }

Sorry about this!

EDIT: new screenshot:

http://www.allegro.cc/files/attachment/593636

Elias
Member #358
May 2000

That screenshot looks much more predictable, thanks :)

--
"Either help out or stop whining" - Evert

Thomas Harte
Member #33
April 2000
avatar

Grrr. Lost my first post to a login timeout. So, very briefly:

Version 1.1 of the library is now available, with fixes to RT_MIX palettes, vertically flipped sprites with non-zero ScaleChange and/or Skew and C++ #inclusion. Sound code is reverted to the version 1.0 version rather than the various realtime fixes that weren't working under Windows. BUFFER_SIZE may now be set on the compiler command line so that it can be chosen at build time. I think that's fine for now, as the only problems have been with the latency under Linux, where people will tend to build for themselves.

Also, to clarify — the competition ends on the 18th of November (as per the website and posts here), not the 11th as per the scroller in Tetrominoes. That text was sadly left in place from before the competition start was put back by a week.

Comments and feedback are welcome.

HardTranceFan
Member #7,317
June 2006
avatar

Heh, guess who didn't read the manual properly and realise there's only 64K of graphics memory? All my plans, dashed because I skimmed over the library docs. Time for some tricky dicky stuff...

[edit]
@Thomas: How can I determine the total space I'm using for sprites? At one point I had 36Kb of .raw files, yet it seemed like not all the sprites were being stored in memory. Are there overheads we should be aware of?

--
"Shame your mind don't shine like your possessions do" - Faithless (I want more part 1)

Elias
Member #358
May 2000

One pixel uses only half a byte. I do this here:

rt_UploadGraphic(mode, data, 1, w, h, 0);
mem_used += w * h;
printf("%d/64 KB used", mem_used / 2048);

--
"Either help out or stop whining" - Evert

HardTranceFan
Member #7,317
June 2006
avatar

Well, what do you know. I was allocating graphics space to fonts way too many times, and a simple 36 character 8x7 font was taking up 55Kb. I've since fixed it and now it's registering as less than 1K.

Thanks Elias, you've helped to spot a bug ;D

[edit]
I've had problems compiling with the latest library (my project is C++) - it keeps coming up with the message:

C:/Program Files/CodeBlocks/include/allegro/fix.h:92: error: declaration of C function `fix operator+(fix, int)' conflicts with
C:/Program Files/CodeBlocks/include/allegro/fix.h:91: error: previous declaration `fix operator+(fix, fix)' here
C:/Program Files/CodeBlocks/include/allegro/fix.h:92: warning: `fix operator+(fix, int)' is already a friend of class `fix'
C:/Program Files/CodeBlocks/include/allegro/fix.h:93: error: declaration of C function `fix operator+(int, fix)' conflicts with
C:/Program Files/CodeBlocks/include/allegro/fix.h:92: error: previous declaration `fix operator+(fix, int)' here
C:/Program Files/CodeBlocks/include/allegro/fix.h:93: warning: `fix operator+(int, fix)' is already a friend of class `fix'
...

However, I managed to get rid of it by putting the #include <allegro.h> before the [ty]#ifdef __cplusplus</tt> in the retrohack.h header file.

Should the library be updated, or am I missing something with my compiling?

--
"Shame your mind don't shine like your possessions do" - Faithless (I want more part 1)

Eric Love
Member #846
December 2000

Hi guys. I've been out of this scene entirely since I've been working full-time, and popped onto a.cc to show someone, and I see there's a RetroHack. I wished I'd found out earlier - the one week Back2Hack of 2002 was a good one even though only Elias & I made anything (or were there any others?)

In the Back2Hack I spent day one making the system play MIDI files, probably the best feature of my entry, and I'm thinking about trying to do the same thing here, for the benefit of anyone who wants to use such a feature. Would that be helpful to anyone? I haven't tried the code out yet, so I don't know how doable that would be. I'll look more at it tonight.

Elias
Member #358
May 2000

Ah, Back2Hack, that was fun. Our game this time is called "Tom the Tomato 2" - now guess what my Back2Hack game was called back then :)

I really wonder if there will be more entries this time - else we should get an easy win :) (Not that we're finished yet, but there's some gameplay emerging already, and still the whole final weekend, so should have something submittable.)

About music, in my case, I made a player which can play tunes given as an ASCII format already, so I'm more concerned with how to create sound effects now. For that need to first investigate why I seem to get sound buffer overruns all the time though - it can't be audiostreams, as in my own synth they work fine with a buffer size of 2048 and in retrohack.c I already upped that to 8192. Likely I'm misinterpreting the AY specs..

For example, can writing the same value to a register multiple times have any effect?

--
"Either help out or stop whining" - Evert

Thomas Harte
Member #33
April 2000
avatar

Quote:

One pixel uses only half a byte. I do this here: ...

Don't forget the caveat that pixel scan lines have to begin on byte boundaries, so if your sprite is an odd number of pixels wide then storage is allocated for a spare pixel at the end of every scanline, and then not used. So the correct formula to work out memory usage for a single sprite of size w × h is ((w + 1) >> 1) * h.

Quote:

I've had problems compiling with the latest library (my project is C++) - it keeps coming up with the message:
...
However, I managed to get rid of it by putting the #include <allegro.h> before the [ty]#ifdef __cplusplus in the retrohack.h header file.

Oh, good spot. In that case the compiler is effectively being told "here's some C++ code which you should expect to link to from a pure-C file" which obviously doesn't make any sense. I'll fix that and reupload version 1.1 tonight. I think it's acceptable in this case not to increment the library version because this is a mere linking problem and definitely either doesn't change the functionality of the library or makes it work.

Quote:

Hi guys. I've been out of this scene entirely since I've been working full-time, and popped onto a.cc to show someone, and I see there's a RetroHack. I wished I'd found out earlier - the one week Back2Hack of 2002 was a good one even though only Elias & I made anything (or were there any others?)

No, it was just you two. Which is partly why I've not exactly been pushing the Back2Hack angle.

EDIT:
I also think it's time to become certain about the categories that prizes will be considered part of. I'm going to come up with some specific proposals tonight. In the meantime, I've decided to clarify the rules concerning library modifications, for the benefit of Jeff Bernard. Entries with some modifications are acceptable, but in that case both a version with the modified library and a version without will be circulated in the judging pack to provide a means of verification that the modifications don't fundamentally subvert the purpose of the competition, e.g. by increasing the amount of drawing that's allowed to be done each frame.

Jeff Bernard
Member #6,698
December 2005
avatar

Woah, woah, woah. Prizes? I was planning on not being able to finish my entry since all I've got is an engine and I've been spending too much time learning NES Assembler when I should have been working on my RetroHack entry.

I may just need to switch into SpeedHack mode for this last week so that I can win some trinket.

--
I thought I was wrong once, but I was mistaken.

Elias
Member #358
May 2000

I tried displaying the sound output, and couldn't find the problem I get yet, but I'm wondering about something else now. This code

1#include "retrohack.h"
2#include <stdio.h>
3#include <math.h>
4 
5static void ay(unsigned char reg, unsigned char val)
6{
7 ay_Write(AY_REGSELECT, reg);
8 ay_Write(AY_REGVALUE, val);
9}
10 
11static void ay_frequency(int channel, int tp)
12{
13 ay(channel * 2 + 0, tp & 255);
14 ay(channel * 2 + 1, tp >> 8);
15}
16 
17static void ay_noise(int np)
18{
19 ay(6, np);
20}
21 
22static void ay_mixer(int a, int b, int c, int noise_a, int noise_b, int noise_c)
23{
24 ay(7, 0xff - a - 2 * b - 4 * c - 8 * noise_a - 16 * noise_b - 32 * noise_c);
25}
26 
27static void ay_volume(int channel, int v)
28{
29 ay(8 + channel, v);
30}
31 
32int main(int argc, const char *argv[])
33{
34 rt_Init();
35 rtSim_SetWindowTitle("AY");
36
37 ay_frequency(0, 200);
38 ay_frequency(1, 200);
39 ay_frequency(2, 200);
40 ay_volume(0, 15);
41 ay_volume(1, 15);
42 ay_volume(2, 15);
43 ay_mixer(1, 1, 1, 0, 0, 0);
44
45 while(!rtSim_QuitWanted())
46 {
47 int k[11], i, j;
48 for (i = 0; i < 11; i++)
49 k<i> = rt_ReadKeyboard(i);
50 
51 if ((k[0] & 2) == 0) break;
52 
53 rt_Flip();
54 }
55 
56 rt_Exit();
57 return 0;
58}
59END_OF_MAIN()

produces this when recording back from ALSA's output: {"name":"593678","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/5\/b\/5b5d47136d0d8cc13766169aee23918b.png","w":1234,"h":393,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/5\/b\/5b5d47136d0d8cc13766169aee23918b"}593678

So, is the distortion of the square wave over time supposed to happen? (I assume it simulates the AY..)

And also, why is the audio stream only played at half volume?

--
"Either help out or stop whining" - Evert

Thomas Harte
Member #33
April 2000
avatar

Quote:

I tried displaying the sound output, and couldn't find the problem I get yet

Apologies, I missed your last post.

Quote:

For example, can writing the same value to a register multiple times have any effect?

I don't think so.

Quote:

So, is the distortion of the square wave over time supposed to happen? (I assume it simulates the AY..)

I'm probably being a bit thick, but we're talking about the sudden change in wave shape just after 0.230, right? I can't really account for that right now. I'll play around. Does a similar thing happen if you set just one channel going?

For reference, there should be some aliasing because it's essentially just doing a point sample to down sample from 3,545,400 Hz to 44,100 Hz. But nothing like that.

EDIT:

Quote:

Woah, woah, woah. Prizes?

Yeah, I didn't really mean to say prizes, but maybe I can rustle something up. I'll think about it.

Elias
Member #358
May 2000

Quote:

I'm probably being a bit thick, but we're talking about the sudden change in wave shape just after 0.230, right? I can't really account for that right now. I'll play around. Does a similar thing happen if you set just one channel going?

Yes. I just tried again with only 1 channel now, and then, the effect is gone. I get a perfect square wave, just not centered.

--
"Either help out or stop whining" - Evert

HardTranceFan
Member #7,317
June 2006
avatar

Quote:

Yeah, I didn't really mean to say prizes, but maybe I can rustle something up. I'll think about it.

I can't speak for the others, but I'm just doing this for the challenge. And it's quite a bit of fun so far... :D

--
"Shame your mind don't shine like your possessions do" - Faithless (I want more part 1)

Paul Pridham
Member #250
April 2000
avatar

It seems that the sound effects (Win32) are playing a good 1/2 second later than when they are triggered. This kind of sucks for connecting actions to sounds!

Is there something I may be doing wrong to cause this?

Thomas Harte
Member #33
April 2000
avatar

Quote:

Is there something I may be doing wrong to cause this?

No, it seems to be a limitation in Allegro. See the code in this thread - under Windows, with a buffer size of 1024 bytes, Allegro sits there offering no audio buffers for a very long time then suddenly offers six at once. So you're inevitably going to be at least one seventh of a second behind. But then because Allegro's AUDIOSTREAMS are completely and unhelpfully opaque, there's no real way to know how many buffers may suddenly need filling at once. That creates further problems because of the way the sound system works. So that the changes you request in the AY aren't all grouped together and performed simultaneously with an unknown and arbitrary precision, the machine has to keep a buffer of sound change requests and then map them to changes in the sound wave as it is generated. So the question is: how far back do you store sound events? When do you say "well, I've obviously got too much stuff stored because my events go back too far?" The answer is that you have no idea because Allegro doesn't reveal those details to you. On my particular Windows system, empirical testing suggests that 6 × 1024 samples may need to be generated at any one time, so the correct oldest event keep would be (6 × 1024) / 44100ths of a second. But on OS X it's 2 buffers. And on your machine it could, per the Allegro developer comments (in contrast to the documentation), be any number. So there's nothing much I can do, and nothing much you can do.

The various attempts at automatic AUDIOSTREAM buffer sizing, etc, that were considered for version 1.1 of the RetroHack library were meant to deemphasise these problems. They didn't work correctly across a sufficiently broad range of machines.

I think the real solution is to dust off and finish the SDL implementation of the RetroHack libraries. It has a system that is like AUDIOSTREAMs, but actually works with you rather than trying to surround you in bubblewrap and obscuring all useful functionality. If I'd known that the sound functionality of Allegro had become this useless, I probably wouldn't have tried to organise this competition.

Thomas Fjellstrom
Member #476
June 2000
avatar

Quote:

under Windows, with a buffer size of 1024 bytes, Allegro sits there offering no audio buffers for a very long time then suddenly offers six at once

Has anyone see that under linux/OSX? If not, its deff a bug in the windows driver.

I don't remember having this problem last time I played with allegro's AUDIOSTREAMS.

edit: IF it is a problem in all platforms, I think its a bug, it should not wait till all buffers are empty. And I'm postive it didn't for me a couple years ago (in linux). So I'd be willing to help fix allegro in that case. even if its just for the compo.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730



Go to: