Page 1 of 2

Tapper remake

Posted: November 24th, 2013, 3:35 am
by jman
Hi retro-people,

As my PSX pet project I choose to try to remake the C64 classic Tapper game.
It will be a very slow project because my free time slots are scarce, but nobody is pushing for a deadline :)

Find attached a first build: CROSS to tap a beer, UP/DOWN to move the barman.

The sprites are really awful but I really suck at drawing pixels and had to rely on some ready-made free stuff available from another partial remake using the Scratch programming language. I'll find better graphic later, suggestions?

I have a question so far: if you are quick enough tapping beer you'll notice there's just one beer sprite and I'm just relocating that one. In theory I may need N beer sprites running over the tables. What's the suggested way to implement this without allocating static arrays? Should I allocate them at runtime and keep track of them in a dynamic list of beer GsSPRITE objects all initialized from the same GsIMAGE? Thanks for any hint.

Re: Tapper remake

Posted: December 2nd, 2013, 1:09 am
by jman
First update.

I've implemented the beer "generator".

Referring to the question in my previous post, I had to think of something flexible to manage any number of beers. The only thing that came to my mind is a linked list of Beer objects.

I don't know if it's the most performing solution: adding elements to a list and always iterate through it to look for a single element with defined properties or to remove it may have quite a hit on performance. Probably this isn't noticeable on a simple games like this one or on small lists with just a handful of elements.

Each "table" too is defined by a struct defining placement relative to the background sprite.
When a beer reaches the wall the games stops (I will implement a penalty for the player).

Re: Tapper remake

Posted: December 3rd, 2013, 2:16 am
by fplgenius
As you say, linked list with a lot of entries isn't the most efficient thing in the world.
Try implementing a hash table, google is your friend for that.
Cheers, and good luck with your project.

Re: Tapper remake

Posted: December 3rd, 2013, 7:25 am
by jman
fplgenius wrote:As you say, linked list with a lot of entries isn't the most efficient thing in the world.
Try implementing a hash table, google is your friend for that.
Thanks for the suggestion. I think the linked list isn't an option even for such a small application like mine!
I've implemented a test case (attached) where the "drunkards" generated are never freed, they just stop and sit there when they reach the other end of the table.

It is noticeable the terrible frame rate hit (see the cpu/gpu indicators on the upper right corner).

Re: Tapper remake

Posted: December 4th, 2013, 6:13 am
by fplgenius
I'm a beginner in game programming in general, but I was wondering when I opened your psxiso.bin I saw a file named "main.psx".
I'm confused, how do you open it and what is it at all? and with what do I open it?I can't see no psx exe.

Re: Tapper remake

Posted: December 4th, 2013, 7:05 am
by Yagotzirck
it's still a psx executable, I don't recall which differences are there from .EXEs(if there are any at all)
Anyway I don't get why you just don't run it as cd image, running the standalone exe doesn't make any sense since it relies on tims in DATA folder.

@jman: those values seem more like cpu and gpu % load, not framerate indicators(unless they're related in a way i'm unaware of)
which kind of condition did you implement to free the objects? polling until they reach the x coordinate corresponding to the end of the table?

Re: Tapper remake

Posted: December 5th, 2013, 12:00 am
by jman
fplgenius wrote:I'm a beginner in game programming in general, but I was wondering when I opened your psxiso.bin I saw a file named "main.psx".
I'm confused, how do you open it and what is it at all? and with what do I open it?I can't see no psx exe.
As Yagotzirck said it's a disc file image suitable to run on an emulator or be burned into a physical disc.
In order to run that disc file use your emulator of choice, example EPSXE:

Code: Select all

ePSXe.exe -nogui -loadbin psxiso.bin
or NO$PSX:

Code: Select all

NO$PSX.EXE "C:\full\path\to\psxiso.iso"

Re: Tapper remake

Posted: December 5th, 2013, 12:54 am
by jman
Yagotzirck wrote:@jman: those values seem more like cpu and gpu % load, not framerate indicators(unless they're related in a way i'm unaware of)
Those numbers are the VSync delays generated in a function of Orion_'s wrapper when drawing occurs, more or less this is what happens:

Code: Select all

*cpu = VSync(1);
DrawSync(0);
*gpu = VSync(0);
GsSwapDispBuff();
GsSortClear(ClearColor[0], ClearColor[1], ClearColor[2], ot);
GsDrawOt(ot);
Which kind of condition did you implement to free the objects? polling until they reach the x coordinate corresponding to the end of the table?
Correct. During the main while() loop of the application I check the whole list of objects, increment the X position of the sprites and remove the item which X coord equals the X coord of the table.

Re: Tapper remake

Posted: December 5th, 2013, 1:59 am
by Yagotzirck
Those numbers are the VSync delays generated in a function of Orion_'s wrapper when drawing occurs
Oh, my bad. Thought it was cpu/gpu % use, since it increases as time passes/more objects get generated.

About the freeing objects part it could be everything, you could try using printf in critical point(s) to see if the code related to freeing objects gets executed at all(possible error in testing loop condition), or if you're freeing them correctly(the whole part about getting node 1 pointing to node 3 and then freeing node 2)
I could be more helpful if I had the chance to see the code directly, but I assume you're doing this for codeblast and I don't want to sound like a code stealer :P

Re: Tapper remake

Posted: December 5th, 2013, 10:26 am
by jman
Yagotzirck wrote:About the freeing objects part it could be everything, you could try using printf in critical point(s) to see if the code related to freeing objects gets executed at all(possible error in testing loop condition), or if you're freeing them correctly(the whole part about getting node 1 pointing to node 3 and then freeing node 2)
I could be more helpful if I had the chance to see the code directly, but I assume you're doing this for codeblast and I don't want to sound like a code stealer :P
LOL! Don't worry this is no secret code. Nobody will win anything with this ;-)
I think the code is working well but I'll investigate why frame rate is getting slower and slower (that's the competition I'm looking for). I'll test the performance replacing with an hash table, as suggested.

Thanks for the suggestion!

Re: Tapper remake

Posted: December 6th, 2013, 9:35 pm
by jman
I was wondering how to detect collisions between two GsSPRITE objects (on Amiga this was done in hardware :D).

I've found this useful piece of code from a Yaroze breakout demo (y-break):
http://read.pudn.com/downloads178/sourc ... in.c__.htm

Create a RECT out of the GsSPRITE coordinates and then check boundaries.
I can simplify for my purposes because I only need to detect collisions over the X axis.

I think I can even directly compare the GsSPRITE coordinates instead of creating a RECT out of it: what's the advantage of having a RECT? Is it faster?

Re: Tapper remake

Posted: December 29th, 2013, 11:41 am
by jman
Another (long due) status update.

After having lost a week worth of code, twice (due to some careless laptop HDD repartion), I could finally go ahead another bit and understand how to properly animate a sprite (again thanks to Orion_ and this forum), implement all the rules for sprite movement, collisions and various reactions (e.g. when the drunkard meets a beer, when a beer or a drunkard reach the end of the table, ...). Nearly 1K lines of code for this only! Am I a bit verbose? :-)

Now that the core logic for playing is mostly done, I can focus on something else:
* Graphics
* Audio/Music
* Auxiliary screens (like "YOU WON!", "YOU LOSE!", ....)

Now, speaking of graphics, is there a volunteer willing to help me? I' need someone able to help me finding the arcade sprites ripped (no success until now) or:
* be able to draw some nice sprite sheets
* have a basic understanding of TIM files
Is there someone up to the task? :-)

Have a taste of the current status: [X] for serving beers, UP/DOWN to move the bartender.
You will notice that at the moment it's impossible to get rid of the drunkards. That's because I still have to calibrate all the game variables according to the difficulty levels available.

Also, I need someone for a test on real hardware. I see something different when running this thing on ePSXe or NO$PSX. On ePSXe the drunkards noticeably pause while advancing towards the bartender. This doesn't happen with NO$PSX. Also on ePSXe the speed of the game is slower.
It is likely something in my code, but I'd to be sure it is not ePSXe fault.
A quick movie filming the game running would be perfect. Thanks!

Re: Tapper remake

Posted: December 29th, 2013, 12:42 pm
by Shendo
I tested it on my PS2 slim because it can read RWs and it seems to work as it does in emulators-
However CPU and GPU debug info is around 28 instead of 10.

But the game seems to be on godlike difficulty.
Drunkards are moving too fast and when I serve them they only take a step back.
Edit: I see you explained that in your post.

About the speed, I'm assuming the game checks the region of the BIOS to set the PAL or NTSC video mode.
That's where the difference may come because PAL has 50 FPS while NTSC has 60.
NO$PSX with nocash BIOS clone seems to be NTSC.

1K for collision seems too extreme.
You should make drunkard and beer objects with x and y variables.
When beer gets to drunkard.x + drunkard.width and are on the same y then it should be consumed.

I would really recommend a real hardware for development.
The cheapest solution would be to use a simple USB-TTL adapter to
upload your code with PSXSERIAL (the setup I'm using).
Downside to this is that you need to include all data in exe and upload is a tad slow at 115200 bps.
But you get the 100% accuracy so you can be confident that it will work on a real thing.

Also even on a simple project like Sokoban I'm running into issues with different setups (emulators).
Something which works on emulators is totally broken on the real thing or vice versa.
The last problem I had is that ePSXe and pSX would hang on SPU upload because
status flags weren't implemented properly.
Current issue I'm battling with is that pSX stops reading gamepads after checking memory cards,
and I'm using BIOS routines which are working everywhere else (other emulators and real hardware).

Here is a video of my test:
http://www.youtube.com/watch?v=vpPnS6V6 ... e=youtu.be

Re: Tapper remake

Posted: December 29th, 2013, 11:35 pm
by jman
@Shendo: thank you very much for testing!
Shendo wrote: But the game seems to be on godlike difficulty.
Drunkards are moving too fast and when I serve them they only take a step back.
Edit: I see you explained that in your post.
I couldn't help but laugh when in your video capture I hear you're furiously tapping on the gamepad :-))
Shendo wrote: About the speed, I'm assuming the game checks the region of the BIOS to set the PAL or NTSC video mode.
That's where the difference may come because PAL has 50 FPS while NTSC has 60.
NO$PSX with nocash BIOS clone seems to be NTSC.
I tried PAL/NTSC ROM switching on both emulators and I dind't see any noticeable difference (although I'm not sure how to check which ROM NO$PSX is using).
However, you're right, one cannot trust emulators too much and I don't want to waste time in this respect.
I'll investigate the quickest option to put my modded PSOne at work (I don't have a TV but I have this device).
Shendo wrote: 1K for collision seems too extreme.
I'm sorry, I meant 1K lines of code for the whole application so far :-) (excluded Orion_'s wrapper)
Shendo wrote: I would really recommend a real hardware for development.
The cheapest solution would be to use a simple USB-TTL adapter to
upload your code with PSXSERIAL (the setup I'm using).
Downside to this is that you need to include all data in exe and upload is a tad slow at 115200 bps.
But you get the 100% accuracy so you can be confident that it will work on a real thing.
I agree wholeheartedly, however refactoring my code in order to include .H files for images is a bit of a nuisance for me.
Do you think the only other option would be to burn a disc (ugh) everytime?
I'll check whether I have an option to quickly deploy into the console my BIN files, test, rinse and repeat.

Re: Tapper remake

Posted: December 30th, 2013, 3:53 am
by jman
Speaking of emulators reliability: does the embedded emulator on a PSP is better than those you can run on your PC?

I see that POPstation (the tool to convert PSX ISO to PSP format) has a database of commercial games: is it possible to create a PSP executable with POPstation starting from your PSX homebrew BIN/CUE?

Re: Tapper remake

Posted: December 30th, 2013, 8:16 am
by Shendo
Yes you can use your homebrew on a CFW PSP.
I don't know about the POPS accuracy however as I haven't done any tests.

I would suggest against CD burning every time you need to test something.
You will end up with a bunch of coasters very quickly, not to mention it will be costly.

But, using PSXSERIAL you could "cheat". If you are programming and testing logic but you
are always using same data from CD, you could burn a CD with required files for your game to load.
Even if you need to update some graphics you will end up with far less disc then without PSXSERIAL.

Re: Tapper remake

Posted: December 31st, 2013, 9:45 am
by jman
Shendo wrote: But, using PSXSERIAL you could "cheat". If you are programming and testing logic but you
are always using same data from CD, you could burn a CD with required files for your game to load.
Even if you need to update some graphics you will end up with far less disc then without PSXSERIAL.
I think you're right here but that's a bit of a nuisance for me. I have to check whether a) I can embed graphics in code with Orion_'s wrapper b) am I able to pick up my solder tool and buy the needed parts, prepare the cable, don't fry the PS...
I'll investigate more.

Re: Tapper remake

Posted: January 3rd, 2014, 10:04 am
by jman
I'm posting another question while looking around for an answer.
I'm building the application in the most modular way, separating source code for all the "screens" composing it, I will end up with something like this:

game.o
menu.o
highscores.o
memcard.o
....

each of them loads its set of TIM files. I load these TIM files with LoadImage().
I was wondering how to unload from VRAM the TIM files I don't need anymore.

These TIM files, in each modules, are all placed starting from [0,0] coordinates. Loaded separately, these modules work fine. However when I "hotswap" from one module to another (example: the player goes from the menu screen to the main game screen) the background is lost, likely because the position of the new background assigned in VRAM overlaps with the old background.

How do I solve?

Just out of curiosity, in the gears.pdf document (the analysis of FF7 game) there's a mention of game modules (menu module, world map and so on). I'm curious to understand whether those modules are conceptually what I'm implementing.

At first I thought that modules meant separated EXE files, but on a second thought I don't think it's the case since separate EXE files live in really separate worlds and you cannot share data among them.

Thanks

Re: Tapper remake

Posted: January 3rd, 2014, 11:27 am
by LameGuy64
You cannot unload a TIM on VRAM but you can draw a new TIM over an existing one if you no longer really need it. The entire VRAM is treated as a large framebuffer space of 1024x512 16-bit pixels. Parts of it can be addressed for rendering/displaying graphics or for storing textures and CLUTs.

As for the modular thing, I'm not entirely sure about it though.

Re: Tapper remake

Posted: January 3rd, 2014, 12:15 pm
by Shendo
You have two solutions:
1. Use different VRAM coordinates (texture pages) for each module, or
2. Re-upload textures from RAM to VRAM each time you load a new module.

I suggest you give some official game a spin on pSX, Xebra or no$psx with "full VRAM" overview to see
how they deal with textures between different screens.

If you are going for the original arcade look I'm certain that with careful planning you can
fit all your textures in VRAM at the same time. And if you use palletized textures (8 bit) you can cut VRAM usage to half.