Shop OBEX P1 Docs P2 Docs Learn Events
Running games in C++ — Parallax Forums

Running games in C++

Dr_AculaDr_Acula Posts: 5,484
edited 2012-02-09 14:46 in Propeller 1
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
void Gr::setMode(int mode) {
	union REGS regs;
	regs.x.ax = mode;
	int86(0x10,&regs,&regs);
}

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

  • jazzedjazzed Posts: 11,803
    edited 2012-02-05 21:23
    Dr_Acula wrote: »
    I am wondering what it would take to run Pacman on the propeller?

    ...

    But there are some technical questions;
    1) Will this fit in hub memory? (probably no)
    2) Is there an XMM version of GCC?

    ...

    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)?

    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.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-02-05 22:56
    Thanks jazzed.
    XMMC puts all non-HUB code in the external memory and all data into HUB memory.

    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?
  • denominatordenominator Posts: 242
    edited 2012-02-06 00:07
    I just did a quick compile of the code, hacking out the I/O, and it's 0x3764 bytes after compiling/linking. You still need the maps, etc. (around 4K), you need a video buffer and the I/O code. It's tight, it would be a challenge, but perhaps it's not out of the question to run it in LMM mode?
  • jazzedjazzed Posts: 11,803
    edited 2012-02-06 00:35
    Dr_Acula wrote: »
    Thanks jazzed.

    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.

    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:
    1. Use the slower but more generic XMM
    2. 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.
    Dr_Acula wrote: »
    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?

    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.
    I just did a quick compile of the code, hacking out the I/O, and it's 0x3764 bytes after compiling/linking. You still need the maps, etc. (around 4K), you need a video buffer and the I/O code. It's tight, it would be a challenge, but perhaps it's not out of the question to run it in LMM mode?

    Wow! That's amazing.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-02-06 01:09
    Sounds intriguing. File size is very encouraging. For standard propeller VGA and TV drivers, yes you need video buffers, but for the ILI9325 display this has its own internal ram. So maybe this would all fit into hub?
  • Daniel HarrisDaniel Harris Posts: 207
    edited 2012-02-07 17:24
    Thanks for posting a link to the source Dr. Acula. Breezing through that is a good quick tutorial for me on C++ classes :). It has been a while since my C++ classes in college...
  • Dave HeinDave Hein Posts: 6,347
    edited 2012-02-08 13:40
    I'm not a C++ programmer, so I ran into some problems getting the C++ code to compile and link properly. I decided to convert it to C and use structs instead of classes. I got the code to work under cygwin. Instead of writing it to a dsplay buffer I wrote it out to BMP image files. One of the frames is attached below. I also built the program for the Prop, and the LMM binary image is 30720 bytes. That doesn't include drivers for the display, sound and file I/O. It should be doable as an XMMC program.
    640 x 480 - 22K
  • Dave HeinDave Hein Posts: 6,347
    edited 2012-02-09 08:57
    I got this to work with a 2-color 320x240 VGA driver on the Prop running in XMMC mode on a C3 card. I tried a 4-color driver, but it ran out of hub RAM. This would work well with a tile graphics driver since everything uses tiles. The basic tile size in this code is 12x12, so it would work better on the Prop to convert it to a 16x16 tile size.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-02-09 14:46
    Hey wow! This is fantastic.
Sign In or Register to comment.