• 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

joevt

Well-known member
Never used it before.
I just found it inside THINK Pascal v3 (folder named THINK Pascal 4 - as in disk 4) and moved it into BasiliskII and ran it.
Seems straight forward.
Looks like it converted the resource fork items into hex data?
I updated my GitHub with this file. Shows up fine in Raw format.
I can only presume that for someone to download it and to convert it back into a proper Resource file you have to use "SARez"?
You should use the .r files from RIncludes of Universal Interfaces with DeRez and Rez so that not everything is hex data.

For GitHub, maybe you should add a couple unix scripts - one to convert from GitHub to Think Pascal, and another for the reverse. The conversion will produce resource files for ThinkPascal, and .r files for GitHub. If you can't find a way for GitHub to produce carriage returns for Think Pascal, or to have GitHub accept carriage returns for the repository, then I suppose the scripts can do that conversion as well. There probably should be a way, since GitHub probably works Windows line endings (CRLF)?
 

LelandLong

Active member
You should use the .r files from RIncludes of Universal Interfaces with DeRez and Rez so that not everything is hex data.

For GitHub, maybe you should add a couple unix scripts - one to convert from GitHub to Think Pascal, and another for the reverse. The conversion will produce resource files for ThinkPascal, and .r files for GitHub. If you can't find a way for GitHub to produce carriage returns for Think Pascal, or to have GitHub accept carriage returns for the repository, then I suppose the scripts can do that conversion as well. There probably should be a way, since GitHub probably works Windows line endings (CRLF)?
Welp!
All of this sounds like fantastic advice.
Only problem being I’ve never done any of the offered suggestions before and don’t even know where to begin.

If anyone is willing and able to guide, the quoted post above contains to very different suggestions so we would need to separate them in following posts.

1) use .r files to prevent hex-only results

2) create unix scripts to use with github
 

LelandLong

Active member
Next update ready.
We have a backdrop picture now instead of a blank screen.
Tricky to get a png converted to 2-bit PICT file and into Resource file!!
Will just attach a zipped folder of all the source and compiled App for your easy viewing.
 

Attachments

  • PacMan_v2 ƒ.zip
    1 MB · Views: 1

LelandLong

Active member
Apr 14 update.
Have tried 2 new things I've never attempted before: Gestalt & ColorQuickdraw !!
Had some hurdles but seem to have gotten over them successfully.
I now have a small, black/white (2-bit) window & backdrop picture, along with a new 16-bit color picture inside a larger window (13" rgb size).
My plan is to have 3 sizes for windows and b/w & color options.
Wow, sure makes the file size and memory requirements significantly higher 😊
I'm thrilled with progress thus far.
Any comments? Anyone checking out the code? Are y'all waiting for more significant progress?
 

Attachments

  • PacMan_v2 ƒ.zip
    1.6 MB · Views: 0

LelandLong

Active member
Apr 15 update.
We have a proper yellow PacMan and his 9 different animation frames.
In 3 sizes, for the 3 windows.
Available now in a Window menu. Swap live between them. No animation yet, but got all the pngs resized, converted to PICTs, opened in SuperPaint, converted to Drawing layer, copied, pasted into ResEdit in PICT resource. For 27 images. Whew.
1713227414036.png
 

Attachments

  • PacMan_v2 ƒ.zip
    2.7 MB · Views: 0

LelandLong

Active member
Got a question that hopefully someone can answer.
Memory Management related.

Apple appears to use handles every time they have a RECORD type variable.
i.e.
Code:
PicHandle    =    ^PicPtr;
PicPtr        =    ^Picture;
Picture        =    RECORD
                    picSize:    INTEGER;
                    picFrame:    Rect;
                    [picture definition data]
                END;

From my little understanding this allows a picture to have the Relocatable Block of memory gain the ability to be moved around the Heap by the OS when needed. The content disappears and has to be reloaded if this happens, but the handle remains.

That appears to be great when you want something temporarily, like say a Dialog. Or a picture that you can draw on the screen and then be done with it.

But what if you want it to stay around? I understand you can Lock the Handle to keep it around. Ok, great.

So now my questions:
I have several of my own RECORD type variables, but currently no Pointers or Handles to them. Just VARs of that type, hanging around in the Stack for the duration of the App.

Is there a reason to keep them this way?
Is there a reason to assign Handles to them, Lock them, and keep them in the Heap instead?
 

joevt

Well-known member
A Picture is usually a resource from a file. Resources are loaded as Handles. There's a resource map for the resource file that keeps track of all the resources/handles. This allows resources to be loaded and unloaded (to save memory space). For resources, read about the Resource Manager.

The reason for Handles in classic macOS is because classic macOS didn't have virtual memory to allow for memory allocations to use discontiguous physical memory ranges or to use the entire virtual memory address range. A Handle points to a Pointer. The Pointer points to a memory range which can move around if the Handle is not locked.

For specific types of resources (Icons, Pictures, etc.) read about those separately. To use a picture, maybe you want to leave it as a handle if the API that uses it expects it to be a handle (the API might do stuff like HLock, GetHandleSize, etc. and those won't work if it's not a Handle).

For your own data structures that are not resources, you can use stack space or global space or pointers or handles. You have to consider the sizes of each data structure and the amount of stack or global space they'll take (they are limited). Global space is fine for limited amounts of data. You would not use global space for a text document since a text document can be many thousands of pages. Pointers are fine for things that will stick around.

I think ThinkPascal shows how much space each code resource takes when you compile? I forget if it shows how much global space each takes.
 

LelandLong

Active member
Apr 17 update.
Nothing but frustration for days. Many, many hours of failures and almost successes.
The issue: CGrafPtrs and CopyBits !!
My new nemesis, uugh.
Let me summarize my failures to hopefully illuminate for you something(s) I have missed so that you can aid me in resolution.

Goal: I already successfully load a PICT resource and draw it to the game Window. What I am trying to do is to change this to drawing the PICT over to an offScreen PixMap, do this for several PICTS is various positions, then use CopyBits to transfer the entire offScreen PixMap to the game Window.

1) tried creating & using GWorlds. Tried code sample on page 21-7 of InsideMac VI. Difficult turned to nightmare with all of the dependancies, that once added ended up causing previously working code to generate compilation errors (for Toolbox functions like GetDItem & Alert) claiming to be type discrepancies. Again previously compiling and running fine, add dependacies to the uses section, and suddenly broken.

2) tried creating a CGrafPtr using "OpenCPort". It immediately crashed until I followed it with SetPort(newCGrafPtr) then it seemed to work better. Seemed like no matter how many variations I tried at this point to use CopyBits, using this OpenCPort as my offScreen PixMap it either crashed or gave my compile errors as I was attempting type coercion and other tricks to code something I didn't understand much at all about.

3) tried creating new PixMaps, point them to loaded PICT resources, and use CopyBits to draw them onto the offscreenPixMap. No luck. Evidently strong-typed Pascal is making it impossible for me to do what the Inside Mac docs state (InsideMac V-66): "Most routines that accept bitMaps as parameters also accept pixMaps (not PixMapHandles)." I tried type coercion BitMap(myPixMapHandle^^) to no avail. And the QuickDraw.p file only includes:
Code:
procedure CopyBits ({CONST}
       var srcBits: BitMap; {CONST}
       var dstBits: BitMap; {CONST}
       var srcRect: Rect; {CONST}
       var dstRect: Rect; mode: INTEGER; maskRgn: RgnHandle);

4) what I have tried most recently that is sorta working but still has some issues I cannot work out: loading a 2nd WIND resource and using it as my "offScreen" PixMap. I have 2 windows loading now, drawing PICTs onto the "offScreen" one (that is still on the screen), then using CopyBits to copy that PixMap over to the main "game" window. Works great, mostly, but then when I try moving the window to the right, even mostly off the screen, the CopyBits starts buggering up the resulting image. I believe this is due to the WindowMgr handling the "invisible/hidden" visRgn & updateRgns. I have never dealt with those Regions, only just let the WindowMgr to it all for me, so I'm not sure if/how to manually adjust those so that my offScreen window can truly be well off the sides of the screen, allow me to draw onto them, then use CopyBits to get a complete render on the game window.

So I am stuck.
Hours of failed attempts.
So little sample code found when searching for it.
Sure would love StackOverflow for THINK Pascal lol.
So ahow about it 68kmla peeps? Got some guidance for me?
If I cannot get this to work I guess I'll be left with old-fashioned animation by erasing old position and drawing in new position animation in the game window, with some obvious flickering probably.
 

joevt

Well-known member
PixMapHandle^^ is a PixMap RECORD which is a different size than BitMap RECORD. You can't typecast different sized types.
You can type cast pointers: BitMapPtr(PixMapHandle^)^

Since CopyBits doesn't require a PixMapHandle you could have a PixMap record and pass that like this:
Code:
VAR
	thePix: PixMap;
...
CopyBits(BitMapPtr(@thePix)^, ...);

CopyBits will be able to determine that the srcBits is a PixMap by looking at the most signifiant bits of the rowBytes.
https://68kmla.org/bb/index.php?thr...nager-and-quickdraw-manager.46379/post-518236

You can't use a 2nd WIND for offscreen. The only pixels it has are the bits of the screen. If it's not onscreen then it has no pixels. There probably is never a reason to copy from one window to another. I suppose you might copy from one window to the same window for improved scrolling speed - the update region would then be stuff that is scrolled into view. I forget how all that is done. There's a MiniEdit app with source code in Macintosh Revealed Volume Two and Three written by Stephen Chernicoff. It think it explains menus, windows, dialogs, events, regions, scrolling, etc. There exist PDF copies. The app is 1894 lines of pascal code.

Does Think Pascal's built-in interface files include GWorlds? How do you determine what is included in the interface files?

Since Think Pascal has built-in interface files, it's difficult to upgrade them to include the later APIs. I'm not sure how to do that. There might be an option to change it? The point of having built-in interfaces is to make it compile faster?

GetDItem may be renamed in newer APIs to GetDialogItem.

Actually, Think Pascal has a QDOffscreen.p interface file which should be sufficient. It has all the GWorld APIs. See the CampFire and CopyBitsBlend examples in the attached zip file. Before GWorlds, people had to make BitMap or PixMap or GrafPort or GDevice manually. See OffscreenU.p in the attached zip file.
 

Attachments

  • joevt Think Pascal offscreen examples.zip
    127.1 KB · Views: 1

LelandLong

Active member
You have provided me with some excellent possibilities to try out.
Hope is restored, thank you!

I have a basic understanding of handles and pointers. But I notice your use of the @ symbol in your code sample. I’ve seen a few examples in the docs but not many. What is it’s use and purpose?
 

joevt

Well-known member
You have provided me with some excellent possibilities to try out.
Hope is restored, thank you!

I have a basic understanding of handles and pointers. But I notice your use of the @ symbol in your code sample. I’ve seen a few examples in the docs but not many. What is it’s use and purpose?
@ returns a pointer to a variable or to a element of a record or array, similar to & in C and C++.

Code:
VAR
    theBitMap : BitMap;
    theBitMapPtr : BitMapPtr;
    myInt : Integer;
BEGIN
     theBitMapPtr = @theBitMap;
     WriteLn(@myInt);

@theBitMap returns a pointer to theBitMap, which has type ^BitMap or BitMapPtr.
@myInt returns a pointer to the Integer myInt. It has type ^Integer.
 

LelandLong

Active member
So is this:
theBitMapPtr := @theBitMap;

Equal to:
theBitMapPtr := NewPtr(sizeof(BitMap));
theBitMapPtr := ^theBitMap ;
 

LelandLong

Active member
So I guess where I am just plain stuck is how to turn a PICT resource into a PixMap so that I use CopyBits to "draw" the PICT resource PixMap onto the gameWindow PixMap.

Without CopyBits it works great just to use "DrawPicture".
But once I get around to animating 5 moving color PICTs on the screen, along with 4 blinking pellets, I should probably start wishing that I was using CopyBits to push an "offscreen" compilation of these objects onto the gameWindow PixMap to alleviate flashing and poor graphics quality.

I have done several programs in my distant past using ICON's, turned into BitMaps, then using CopyBits to "draw" the ICON resource onto a window.
But ICON's appear to share BitMap characteristics that makes this process simple.
And PICT resources just aren't bitmaps out of the gate, so I cannot just quickly turn them into PixMaps evidently.

And now that I am using much larger PICT's instead of small ICON's I have ran into this brick wall I cannot seem to get past.
Have spent days on this problem.
With the guidance thus far I feel like I've come so close.
Several things have worked, but this large goal of mine is still elusive.

Hoping to continue getting great advice and help from this group to overcome and make it happen.
Thank you to everyone who has contributed on this thread!
Appreciate your time and attention.
 

olePigeon

Well-known member
@LelandLong I'm sure you're aware of this, but just in case, the ghost patterns are very well-documented. So when you get to that part of the game, I bet you could do an arcade-accurate interpretation in regards to how the ghosts behave.
 

LelandLong

Active member
@olePigeon yes, thank you. The last time I rewrote PacMan for FileMaker/JavaScript I found those documents online and totally mimicked the enemy AI patterns. Mostly lol. I matched the pays they followed, along with the 2-3 modes, but ignored the slight speed differences.

But thank you for the suggestions! Keep them coming.
 

olePigeon

Well-known member
Make it so at random levels the ghost patterns are slightly different. That'll catch "pro" players off guard who've already memorized the patterns. But don't tell anyone. :D
 

LelandLong

Active member
Based on advice from @joevt I am attempting once again to try to get me a working GWorld.
Why attempting? Again?
Well, because just like my last 2 hours of attempting this, in order to create/use a GWorld you have to Add a bunch of dependancies:
ConditionalMacros.p
Types.p
MixedMode.p
Errors.p
QuickdrawText.p
Quickdraw.p
QDOffscreen.p

Aaaaand as soon as I add all of those I begin getting a boatload of Build errors.
Code that once worked, such as:
Code:
GetDialogItem(alertDialog, staticTextID, dTextType, dTextHandle, dTextDisplayRect);
Code:
windowPtr := GetNewWindow(smallWindowID, @windowRecord, pointer(-1));

Which suddenly gives you Assignment and Type incompatibility errors galore.

WHICH I SOLVED by removing the ['USES' Extensions] checkbox in the Compile Options dialog!!
Never thought to do this, nor thought it would aid my endeavors ! But it sure did.

Of course then I had to add a bunch more unit names to all of my uses declarations, but that was fairly simple but exhaustive.

- - -

I did have 1 final error I had to get past, and even being "green" at this sort of thing I managed to guess correctly (from what I can tell anyways).
The final error to get past was a Build error "Compiler variable is not defined.", pointing to my code:
Code:
uses QDOffscreen;

So I opened up QDOffscreen.p and took a look around.
Now I am barely aware of compiler variables. Barely! I could not explain to anyone else what they are or how to use them.
But I did see some apparent Compiler variable(s) being used in this file:
Code:
{$IFC UNDEFINED __QDOFFSCREEN__}
{$SETC __QDOFFSCREEN__ := 1}

and

Code:
    {$IFC NOT GENERATINGCFM}
 inline
  $203C, $0016, $0003, $AB1D;
    {$ENDC}

So what I did to resolve this error was, at the top, to add this code:
Code:
{$IFC UNDEFINED GENERATINGCFM}
{$SETC GENERATINGCFM := 0}

Error went away!!

Now I ask this group of experts: did I really bugger things up and just don't know it yet but pain will be forthcoming!
Or do you agree that yup, indeedy-do, the youngster done figured it out I do believe!

I have NO idea what generatingCFM is doing, nor have I any idea what that acronym stands for, but seeing how the inline code in that file was only added if this value was false, I thought maybe it might be important for it to be false. So I gambled.
 

LelandLong

Active member
WE HAVE GWORLD, COPYBITS, OFFCREEN.PIXMAP !!!!!
Thank you, thank you @joevt . You are my hero. Please find your nearest cape, don it, wear it proudly, and proclaim that you are the THINK Pascal guru of the known Universe.
🦸🏻‍♂️⚡🎉🔥

Thank you everyone for your patience and understanding of my very exasperating week filled with way too many Build failures to handle.

What an exhausting journey this has turned out to be.
But I've never done this before so it feels rewarding to finally pass the last hurdle and use CopyBits to move an offscreen World PixMap over to the gameWindow in a single function call, after rendering all the game color PICT graphics onto the offscreen PixMap using DrawPicture. Whew!!

I am dancing.
 

Attachments

  • PacMan_v2 ƒ.zip
    2.8 MB · Views: 1
Top