• Updated 2023-07-12: Hello, Guest! Welcome back, and be sure to check out this follow-up post about our outage a week or so ago.

Would like to development a new THINK Pascal App for 68K

LelandLong

Active member
Okay, we have the beginnings of animation.
But I have some questions for this group.

Right now I am drawing a new animation frame every 2 ticks (TickCount = 1/60th of a second).
I am incrementing the PacDude rect.left by an increment value of +/- 5.
If its below window.left=200 or higher than 400 I reverse course.
I obscure the cursor if the mouse is inside the game window.

I am inefficiently re-drawing everything every frame (black fill, game image (blue walls, etc), & PacMan image). On the small & medium windows this looks fine thus far, but the large window is starting to show some lag, at least on my Basilisk emulator of a Mac Quadra900 (68040 w/256M RAM). I can only imagine a slower Mac being even slower.

Okay, all well and good.

Questions for this group:
1) do you think I should be using TickCount as the framerate
2) I think my drawing of the entire window is overkill and not completely necessary. If the moving objects don't overlap any of the blue walls of the backdrop image, then I should be able to just "erase" the current object with a black fill of a small rect, then draw the new object in the new location. This should speed things up dramatically across the board. Plus we will soon have 5 moving objects and 4 flashing objects and an occasional addition object (Fruit bonus)
 

Attachments

  • PacMan_v2 ƒ.zip
    2.8 MB · Views: 0

joevt

Well-known member
Where did you get your QDOffscreen.p from?

The one I have in the Think Pascal Interfaces file says this:

Code:
{	This file has been processed by The THINK Pascal Source Converter, v1.1.	}

{}
{Created: Sunday, January 6, 1991 at 10:59 PM}
{    QDOffscreen.p}
{    Pascal Interface to the Macintosh Libraries}
{}
{        Copyright Apple Computer, Inc.    1985-1990}
{        All rights reserved}
{}

My Think Pascal has date Oct 8, 1997.
PasLibIntf.p is from Nov 3, 1988. (LightSpeed Pascal?)
ObjIntf.p is from Aug, 20, 1990.
Half the interface files are from May 17, 1991.
QDOffscreen.p is from June 19, 1991.
Another half of the interface files are from July 15, 1991.
Sane.p is Oct 29, 1991.
SoundInput.p is July 27, 1995.

The only $IFC I have in the Interface files is for checking OPTION(MC68881)

I suppose the following addition is ok
Code:
{$IFC UNDEFINED GENERATINGCFM}
{$SETC GENERATINGCFM := 0}

as long as the tests below that use this:
{$IFC NOT GENERATINGCFM}
or this:
{$IFC GENERATINGCFM}

It would be a problem if there were any tests like this:
{$IFC DEFINED GENERATINGCFM}

CopyBits performance is complicated. Do the GWorld and main display use the same or different Graphics Devices? Different Graphics Devices may have different bit depths or color tables.
 

LelandLong

Active member
Where did you get your QDOffscreen.p from?
THINK Pascal 4.5d4

The one I have in the Think Pascal Interfaces file says this:

Code:
{    This file has been processed by The THINK Pascal Source Converter, v1.1.    }

{}
{Created: Sunday, January 6, 1991 at 10:59 PM}
{    QDOffscreen.p}
{    Pascal Interface to the Macintosh Libraries}
{}
{        Copyright Apple Computer, Inc.    1985-1990}
{        All rights reserved}
{}
{ Converted with MPW2TPas Tuesday, September 12, 1995 8:55:44 PM }
{}
{ File: QDOffscreen.p}
{ }
{ Contains: QuickDraw Offscreen GWorld Interfaces.}
{ }
{ Version: Technology: System 7.5}
{ Package: Universal Interfaces 2.1 in “MPW Latest” on ETO #18}
{ }
{ Copyright: © 1984-1995 by Apple Computer, Inc.}
{ All rights reserved.}
My Think Pascal has date Oct 8, 1997.
THINK Pascal App info: Feb 23, 1996
PasLibIntf.p is from Nov 3, 1988. (LightSpeed Pascal?)
ObjIntf.p is from Aug, 20, 1990.
Half the interface files are from May 17, 1991.
QDOffscreen.p is from June 19, 1991.
Another half of the interface files are from July 15, 1991.
Sane.p is Oct 29, 1991.
SoundInput.p is July 27, 1995.

The only $IFC I have in the Interface files is for checking OPTION(MC68881)

I suppose the following addition is ok
Code:
{$IFC UNDEFINED GENERATINGCFM}
{$SETC GENERATINGCFM := 0}

as long as the tests below that use this:
{$IFC NOT GENERATINGCFM}
or this:
{$IFC GENERATINGCFM}
function NewGWorld (var offscreenGWorld: GWorldPtr; PixelDepth: INTEGER; {CONST}
var boundsRect: Rect; cTable: CTabHandle; aGDevice: GDHandle; flags: GWorldFlags): QDErr;
{$IFC NOT GENERATINGCFM}
inline
$203C, $0016, $0000, $AB1D;
{$ENDC}
It would be a problem if there were any tests like this:
{$IFC DEFINED GENERATINGCFM}

CopyBits performance is complicated. Do the GWorld and main display use the same or different Graphics Devices? Different Graphics Devices may have different bit depths or color tables.
I'm just using a single screen set to Colors:Millions
 

LelandLong

Active member
Apr 22 update
1) new Window menu item: DeveloperView toggle
2) no longer redrawing entire screen for every frame. Now in the offscreen PixMap we draw the entire frame once (startup, window size switching, & updates) and then only draw moving rects (previous location and new location) in subsequent frames. Then we transfer the whole image over to the gameWindow using CopyBits
3) we have the first row and column of pellets so that I can start to figure out spacing, collisions with, and variable storage of all the pellets
4) we have Pacman movement and animation frames. Current keys are: W,A,S,D and/or I,J,K,L
5) no walls or paths yet. He continuously moves but bounces off game borders.
6) we have pellet collision testing and erasure

1713838821296.png
 

Attachments

  • PacMan_v2 ƒ.zip
    2.8 MB · Views: 0

LelandLong

Active member
THInK Pascal Names.
How long can they be?

According to what I found in the manual, if you turn on “Long Names” in the Compile Options then Procedure names can be longer than 8 chars. But what about const, type, and variable names?

I began using long Const variable names and started having odd results and think this was the reason why.

I think the odd results continued even after checking “Long Names”
 

LelandLong

Active member
Documentation

Page 258 states:

1.2 Identifiers
Identifiers serve to denote constants, types, variables, procedures, functions, programs, and fields in records. Identifiers can be up to 255 characters long. All characters are significant. Upper and lower case letters are equivalent in identifiers. No identifier can have the same spelling as a wordsymbol.

—-
So now I am confused.
Its seems that when I had made some const’s like the following I began seeing erratic behavior when attempting to use them later:
PELLET_MATRIX_01 = $3FFFFF;
PELLET_MATRIX_02 = $203ECC;
PELLET_MATRIX_COUNT_ROWS = 29;
PELLET_MATRIX_COUNT_COLUMNS = 26;
 

joevt

Well-known member
So now I am confused.
Its seems that when I had made some const’s like the following I began seeing erratic behavior when attempting to use them later:
PELLET_MATRIX_01 = $3FFFFF;
PELLET_MATRIX_02 = $203ECC;
PELLET_MATRIX_COUNT_ROWS = 29;
PELLET_MATRIX_COUNT_COLUMNS = 26;
What context are they used?

You need to be wary of type sizes of variables and expressions (2 byte integers or 4 byte integers).

For example, if you have an array of < 32K items then you might think it's ok to use a two byte integer for the index, and multiply that by the size of the element, but if the size of the element is not 1, then the size of the array might by > 32K and the compiler might use incorrect two byte size for the multiply result. This may vary with compiler versions.

You might have an unsized array type.
Code:
TYPE
    FSSpecArray = ARRAY [0..0] OF FSSpec;
    FSSpecArrayPtr = ^FSSpecArray;
VAR
    myfsspecarray : FSSpecArrayPtr;

An FSSpec is 70 bytes. You might think it's safe to do something like this:
Code:
VAR
    INTEGER myvref;
    INTEGER i;
BEGIN
    i = 500;
    myvref = myfsspecarray[i].vRefNum;

However, the compiler might try to use 2 byte math because the array size is defined as [0..0] which is only 70 bytes which is < 32K.

500 * 70 = 35000 which is greater than 32K. If the compiler used 2 byte math, then it might try to load vRefNum from a negative offset (if it doesn't use unsigned math).

if I is 1000, then 1000 * 70 = 70000 which would be offset 0x11170 but if it uses only two bytes then it would be offset 0x1170 which is in the middle of element 63.

A work-around would be to define the ARRAY as something larger than 32K.

FSSpecArray = ARRAY [0..32768 / SIZEOF(FSPec) + 1] OF FSSpec;


Here's a bug from Metrowerks CodeWarrior 7 Pascal:
Code:
PROGRAM Test;
TYPE
    EnumsType = ( enum00, enum01, enum02, enum03, enum04, enum05,=20
enum06, enum07, enum08, enum09, enum10, enum11 );
VAR
  strs : ARRAY [ EnumsType ] OF String[19];
    enum : EnumsType;
BEGIN
    strs[enum06] := 'Hello6';
    strs[enum07] := 'Hello7';
    WriteLn( strs[enum06] );
    WriteLn( strs[enum07] );

    enum := enum06;
    WriteLn( strs[enum] );
    enum := enum07;
    WriteLn( strs[enum] );                  { bad }
END.

enum07 * 20 = 140 is sign extended from byte = -116 which is wrong.
 

LelandLong

Active member
Apr 27 Major Update!
1) we have pellets. I decided to use a bitmap-style variable "matrix" to create where to draw pellets
2) we have walls. I copied the pellets "matrix" idea for the walls
3) we have collisions. I use the "matrix" to generate Rects and use these Rects inside SectRect() to test against the PacMan Rect
4) we have 30 new images, all for the custom scoring "digits", and the score is displayed using those instead of Text/Str255
5) the new Developer menu allows you to turn on/off behind the screens data that can be helpful and/or interesting
6) again, all of this is is implemented using 3 different screen sizes. A bit overkill but nice to have bigger & color when it's available

It feels like a lot of the hardest parts are implemented!

What is left?

Power pellets
Escape routes (vertically centered paths that wrap-around to the other side)
High Score
Custom controls
Sound
Monsters & their A.I. paths
Fruit / Levels
Cut scenes
Initial demo
Start/Abort game controls

Stretch goal: I have had this in mind for quite awhile now.
I would love to try and figure out how to connect 2 games together for a head-to-head 2 player game using AppleTalk.
I have never attempted AppleTalk programming and this should be a great place to start I think.
Maybe Program Linking?
Maybe AppleTalk Data Stream Protocol (ADSP)?
Just educated guesses.

But the game would be similar to the original Mario Bros. (not Super) and Joust and other games that allowed players to play both at the same time. But on 2 different networked Mac's, not using just 1 Mac, no no.
There would be 2 PacMan players, slightly different colors/shades to tell them apart. Competing over pellets and monsters and fruit to try and get them first.
Seems to me like a neat variation on a theme :)
1714267746815.png
 

Attachments

  • PacMan_v2 ƒ.zip
    2.9 MB · Views: 0
Top