Running games in C++
Dr_Acula
Posts: 5,484
I am wondering what it would take to run Pacman on the propeller?
Pacman source code here http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=2935&lngWId=3
and the 320x240 graphics display here http://forums.parallax.com/showthread.php?137266-Propeller-GUI-touchscreen-and-full-color-display&p=1065935#post1065935
This pacman code looks relatively self contained - it has its own internal fonts and so the interface to the program is a keyboard input, and a display output. The display works down at the pixel level and getting inside to the part where it draws a pixel, this is in GRAPHIC.HPP
There is this code which I think is machine dependent so it can be replaced with something else
and there is the pixel driver code
Which looks pretty straightforward - it is single dimensional array and you just change the pixel color. The screen size looks like it is 320x200 which will fit on a 320x240 display.
But there are some technical questions;
1) Will this fit in hub memory? (probably no)
2) Is there an XMM version of GCC?
If there is an XMM version, then this raises another question. If you dedicate enough pins to control the display as fast as possible you end up using about 20 propeller pins, and for fast memory access, those pins also are shared with the memory chips.
There are currently a number of low level pasm routines that do things like;
move 256 bytes from hub to external ram
move 256 bytes from external ram to hub
move 256 bytes from hub to the display
move 256 bytes from external ram to the display
These naturally lead to interfacing with caching.
However, XMM and the display can't be running at the same time. So if a line in C code calls a routine that is passed to a cog to do something like move a block of data out to the display, the XMM program itself needs to be paused until the cog sets a flag (a long in hub ram) to say it is finished.
Is there a way of calling a routine in C++ that sends a command to a cog (write a value to a long in hub) to run a particular pasm routine and also effectively pauses C++ until a particular value in hub changes (when the cog has finished)?
Pacman source code here http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=2935&lngWId=3
and the 320x240 graphics display here http://forums.parallax.com/showthread.php?137266-Propeller-GUI-touchscreen-and-full-color-display&p=1065935#post1065935
This pacman code looks relatively self contained - it has its own internal fonts and so the interface to the program is a keyboard input, and a display output. The display works down at the pixel level and getting inside to the part where it draws a pixel, this is in GRAPHIC.HPP
There is this code which I think is machine dependent so it can be replaced with something else
void Gr::setMode(int mode) { union REGS regs; regs.x.ax = mode; int86(0x10,®s,®s); }
and there is the pixel driver code
vga[i+offset] = color;
Which looks pretty straightforward - it is single dimensional array and you just change the pixel color. The screen size looks like it is 320x200 which will fit on a 320x240 display.
But there are some technical questions;
1) Will this fit in hub memory? (probably no)
2) Is there an XMM version of GCC?
If there is an XMM version, then this raises another question. If you dedicate enough pins to control the display as fast as possible you end up using about 20 propeller pins, and for fast memory access, those pins also are shared with the memory chips.
There are currently a number of low level pasm routines that do things like;
move 256 bytes from hub to external ram
move 256 bytes from external ram to hub
move 256 bytes from hub to the display
move 256 bytes from external ram to the display
These naturally lead to interfacing with caching.
However, XMM and the display can't be running at the same time. So if a line in C code calls a routine that is passed to a cog to do something like move a block of data out to the display, the XMM program itself needs to be paused until the cog sets a flag (a long in hub ram) to say it is finished.
Is there a way of calling a routine in C++ that sends a command to a cog (write a value to a long in hub) to run a particular pasm routine and also effectively pauses C++ until a particular value in hub changes (when the cog has finished)?
Comments
Interesting idea.
As you observe, most likely the program will not fit into HUB memory.
Propeller-GCC has 2 XMM modes XMM and XMMC.
XMMC puts all non-HUB code in the external memory and all data into HUB memory.
XMM puts all non-HUB code and data into external memory except for stack.
XMMC is significantly faster than XMM.
You can tell GCC to put code into HUB memory.
By keeping the "PASM poll until complete loop" in HUB memory, there should not be any conflict accessing your shared device and running the program.
Studying that code and your suggestions I can see some interesting ideas. Things like fonts and graphics can go off to external memory. XMMC then.
Can you tell GCC where to put various bits of code? I'm thinking some code is not used very often, like loading up a new level or initialising the display. So could that go off to external memory too, and the core of the program could be in hub?
Unfortunately "non-HUB code" does not include graphics data and fonts.
So XMMC may not be the most suitable mode. It's fast because we don't have to make decisions about where the data is kept.
In those cases where there is lots of graphics data, there are 2 choices:
- Use the slower but more generic XMM
- Use XMMC with a part of the external memory as a "block device"
Interesting that this all comes up because I have a small LCD for displaying a picture and text.I hope to store pictures and user data in the extra part of the XMMC Flash.
Currently all code goes into external memory for XMM/XMMC modes unless you tag the program functions as HUBTEXT.
You can use attributes and enhance the linker script if you need new sections.
Wow! That's amazing.