ThinkC [Study Group 2] - Events & Menu Management

Relating to ThinkC Development

Crutch

Tinkerer
Jul 10, 2022
293
228
43
Chicago
I’m a little confused by what you are looking for Eric. To my reading, if working correctly, and you are running your app while you shut down the computer or quit the app, it will printf(“got hle”) then immediately quit.

Are you sure you are letting it run long enough post-shutdown to visually confirm that the printf is executing? What if you replace your DoQuitApp() code with {long d; SysBeep(0); Delay(60, &d);}?
 

eric

Administrator
Staff member
Sep 2, 2021
939
1,535
93
MN
scsi.blue
Expected behavior:
run the app
goto special -> restart in Finder
app comes to front and quits

Actual behavior:
Run the app
goto special -> restart in Finder
App comes to font, no event shown besides the mouse down/up events from clicking on the menus
app does not quit. No logs are printed. computer does not restart
 
Last edited:

Crutch

Tinkerer
Jul 10, 2022
293
228
43
Chicago
Got it. Theory: the THINK C console runtime is eating your AppleEvent. What happens if you instead build a test app that doesn’t use
stdio?
 

Crutch

Tinkerer
Jul 10, 2022
293
228
43
Chicago
This works for me in THINK C 6 under 7.5.5 — I see the menu bar flash, then the stdio runtime does make me press Return before quitting.

Don’t forget to set ”Accepts High-Level Events” in Set Project Type —> Flags.

1665538657484.png
 

eric

Administrator
Staff member
Sep 2, 2021
939
1,535
93
MN
scsi.blue
Don’t forget to set ”Accepts High-Level Events” in Set Project Type —> Flags.
You read something 9 times, and the 10th time you see it :D Yes it did tell me to do that, but I didnt! All working now, thanks!

As far as I can tell these are only in System 7 - is there the same for MultiFinder in System 6? Or should I just not worry about that :)
 

Crutch

Tinkerer
Jul 10, 2022
293
228
43
Chicago
No AppleEvent in System 6. MultiFinder makes applications quit by trickily faking a mouse click in the menubar, then a MenuSelect patch that tricks the application into thinking “Quit” was chosen. So under MultiFinder your normal “Quit” code should get triggered when the system is trying to restart and quit your app. This is described (briefly) in Tech Note #205.

(Technically MultiFinder fakes a mouse click in any menu item whose name matches the single string in your ‘mstr’ resource #100, or any string in your ‘mst#’ resource #100. If no such resources are present — as usually they are not — it just looks for “Quit”, I think.)
 
Last edited:
  • Like
Reactions: Patrick and eric

pretzelFTW

New Tinkerer
Sep 5, 2022
26
8
3
With EventTracker, I'm never seeing the keyUp event. I've tried on both 6.0.8 and 7.1.

Is that working for anyone else?
 

Crutch

Tinkerer
Jul 10, 2022
293
228
43
Chicago
keyUp events are masked by the system by default. If you ever want to see a keyUp event, you need

C:
SetEventMask(everyEvent);

first. On older Macs (pre-MultiFinder, I think) this is a systemwide global, so you should always put it back when you’re done.
 
  • Like
Reactions: pretzelFTW and eric

KennyPowers

Active Tinkerer
Jun 27, 2022
278
315
63
keyUp events are masked by the system by default. If you ever want to see a keyUp event, you need

C:
SetEventMask(everyEvent);

first. On older Macs (pre-MultiFinder, I think) this is a systemwide global, so you should always put it back when you’re done.
Ya, that's what I had to do to see keyUp events. I stored the current value of SysEvtMask in EventInit(), called SetEventMask(everyEvent), then set it back to the original when my program exits. What would be the recommended place to restore the original event mask if my program exited abnormally? The kAEQuitApplication handler?
 
  • Like
Reactions: pretzelFTW

Crutch

Tinkerer
Jul 10, 2022
293
228
43
Chicago
I would expect your kAEQuitApplication handler to call a common CleanUp() function that you would always call when preparing to exit the application, which function should reset the system event mask.
 

KennyPowers

Active Tinkerer
Jun 27, 2022
278
315
63
I would expect your kAEQuitApplication handler to call a common CleanUp() function that you would always call when preparing to exit the application, which function should reset the system event mask.
Ya, that's how I would actually implement it. Just wanted to confirm that the kAEQuitApplication handler was the correct place to respond to that scenario (seems like it obviously would be, but my classic mac programming experience is currently limited to the first 5 chapters of this book :) ). So kAEQuitApplication is analagous to SIGTERM in the UNIX world. I guess if your app was force-quit, then you can't handle that to do any clean-up tasks (kind of like SIGKILL).
 

pretzelFTW

New Tinkerer
Sep 5, 2022
26
8
3
keyUp events are masked by the system by default. If you ever want to see a keyUp event, you need

C:
SetEventMask(everyEvent);

first. On older Macs (pre-MultiFinder, I think) this is a systemwide global, so you should always put it back when you’re done.
That worked. Thank you!
I guess that detail was missing from the book.
 

Crutch

Tinkerer
Jul 10, 2022
293
228
43
Chicago
Ya, that's how I would actually implement it. Just wanted to confirm that the kAEQuitApplication handler was the correct place to respond to that scenario (seems like it obviously would be, but my classic mac programming experience is currently limited to the first 5 chapters of this book :) ). So kAEQuitApplication is analagous to SIGTERM in the UNIX world. I guess if your app was force-quit, then you can't handle that to do any clean-up tasks (kind of like SIGKILL).
If you’re really paranoid you can patch _ExitToShell. I am pretty sure the OS forced quit handler calls it for you!
 
  • Like
Reactions: KennyPowers

KennyPowers

Active Tinkerer
Jun 27, 2022
278
315
63
So my "project" after chapters 4 & 5 was a simple ray tracer that allows configuring rendering options via menus. It currently only supports spheres (cause they're easy), and supports diffuse and specular shading, as well as reflections, basic shadows, and basic refraction/transparency. Refraction/transparency doesn't look quite right, so I've probably got a bug in there somewhere, but it's honestly too slow to be practical anyways :) Also, it exclusively uses fixed-point numbers (as opposed to floating-point). I kind of just did that for grins...I don't know if it's any faster than it would have been with floating-point math (obviously the floating-point capabilities of the machine would play into that), especially since several of the fixed-point math functions I'm currently using are very very sub-optimal. I also haven't put much effort into optimizing the rendering code. Still, it's a neat toy project that I can augment as I work my way through the rest of the book by adding things like file I/O, etc (the PICT-related menu options don't currently do anything for example). Also, the scene with the four spheres is currently hard-coded, so the ability to specify or import scene definitions would be another thing I could add.

This was developed entirely on an 040-accelerated IIci with a RasterOps PaintBoard Prism GT video card for 24-bit color support. The included code has only been built with ThinkC 6, and I'm not sure how portable the project file is. Still, you can always just make a new project file and link all the .c files and the MacTraps lib. Add some more spheres! Change material properties! Go nuts and make your mac melt! A built executable is also included. Note, by default, all of the optional render features are ON, and the number of recursive ray bounces is MAXED. I recommend turning everything off/down before hitting "Render" for the first time and then incrementally enabling things unless you want to sit there forever (it's pretty fast under Basilisk II though). Shrinking the window will also reduce the render time (fewer pixels = fewer rays). Don't drag anything over your rendered image either after waiting for it to complete...this currently draws directly to the window's graphics port, so there's no offscreen rendering available to repaint the window :) Resizing the window will also clear the current rendered image. Also, it'll obviously look best in "millions" of colors if your machine can do it, but "thousands" or 256 will just have the usual banding.

RayTracer.sit.hqx was created with Stuffit Deluxe 4.5.

1.png 2.png 3.png 4.png
 

Attachments

  • RayTracer.sit.hqx
    64.6 KB · Views: 73

Crutch

Tinkerer
Jul 10, 2022
293
228
43
Chicago
Very pretty! I believe the fixed point routines (which incur function call overhead) are typically slower than floating point if you have an FPU or an 040, though it probably depends on the use case.
 

KennyPowers

Active Tinkerer
Jun 27, 2022
278
315
63
I believe the fixed point routines (which incur function call overhead) are typically slower than floating point if you have an FPU or an 040, though it probably depends on the use case.
I assumed as much. Also, some of those routines can apparently be hand-optimized. And my implementations of things like sqrt(), pow(), and exp() are very simplistic and rely on some limitations (integer exponents only, etc). I remember using look-up-tables for some of those things, as well as trig functions, a long time ago when doing pre-iphone games on Symbian phones. This also made me miss C++'s operator overloading and inlining, as well as being able to templatize the number of fractional and integer bits. The maximum size of a sphere is also limited by using 16.16 fixed-point numbers. Since I store the squared radius of a sphere as an optimization, and the max value of a fixed-point number is 32767, weird visuals will happen with spheres having a radius larger than around 150 or 160 units :) The large red sphere only has a radius of 4.
 

pfuentes69

Active Tinkerer
Oct 27, 2021
380
293
63
Switzerland
So my "project" after chapters 4 & 5 was a simple ray tracer that allows configuring rendering options via menus. It currently only supports spheres (cause they're easy), and supports diffuse and specular shading, as well as reflections, basic shadows, and basic refraction/transparency. Refraction/transparency doesn't look quite right, so I've probably got a bug in there somewhere, but it's honestly too slow to be practical anyways :) Also, it exclusively uses fixed-point numbers (as opposed to floating-point). I kind of just did that for grins...I don't know if it's any faster than it would have been with floating-point math (obviously the floating-point capabilities of the machine would play into that), especially since several of the fixed-point math functions I'm currently using are very very sub-optimal. I also haven't put much effort into optimizing the rendering code. Still, it's a neat toy project that I can augment as I work my way through the rest of the book by adding things like file I/O, etc (the PICT-related menu options don't currently do anything for example). Also, the scene with the four spheres is currently hard-coded, so the ability to specify or import scene definitions would be another thing I could add.

This was developed entirely on an 040-accelerated IIci with a RasterOps PaintBoard Prism GT video card for 24-bit color support. The included code has only been built with ThinkC 6, and I'm not sure how portable the project file is. Still, you can always just make a new project file and link all the .c files and the MacTraps lib. Add some more spheres! Change material properties! Go nuts and make your mac melt! A built executable is also included. Note, by default, all of the optional render features are ON, and the number of recursive ray bounces is MAXED. I recommend turning everything off/down before hitting "Render" for the first time and then incrementally enabling things unless you want to sit there forever (it's pretty fast under Basilisk II though). Shrinking the window will also reduce the render time (fewer pixels = fewer rays). Don't drag anything over your rendered image either after waiting for it to complete...this currently draws directly to the window's graphics port, so there's no offscreen rendering available to repaint the window :) Resizing the window will also clear the current rendered image. Also, it'll obviously look best in "millions" of colors if your machine can do it, but "thousands" or 256 will just have the usual banding.

RayTracer.sit.hqx was created with Stuffit Deluxe 4.5.

View attachment 9368 View attachment 9369 View attachment 9370 View attachment 9371
This is a very nice project!
I'm also making something related to 3D graphics, and definitely I'd like to check your code. In fact, once I finish it (long way to go!) I was planning to get into raytracing, but I was guessing it would be painfully slow.
 

KennyPowers

Active Tinkerer
Jun 27, 2022
278
315
63

Ya, I've been following that...looks really cool! I haven't looked at the code at all, but I had some questions (that would probably be quickly answered if I did look at the code :) ):

- Are you using QuickDraw primitives for rasterization? Like, basically transforming a scene-space triangle into screen-space with the usual transformation matrices and then drawing the screen-space triangle as a QuickDraw region (PolyAddPt(), PaintPoly(), etc)?
- Do your rotation controls (camera and/or object) suffer from gimbal-lock, or do you internally represent orientations/rotations using something like quaternions to avoid it?
 

pfuentes69

Active Tinkerer
Oct 27, 2021
380
293
63
Switzerland
Ya, I've been following that...looks really cool! I haven't looked at the code at all, but I had some questions (that would probably be quickly answered if I did look at the code :) ):

- Are you using QuickDraw primitives for rasterization? Like, basically transforming a scene-space triangle into screen-space with the usual transformation matrices and then drawing the screen-space triangle as a QuickDraw region (PolyAddPt(), PaintPoly(), etc)?
- Do your rotation controls (camera and/or object) suffer from gimbal-lock, or do you internally represent orientations/rotations using something like quaternions to avoid it?
Hey, cool having more people interested in this stuff. I just downloaded your project and tried it on Basilisk... very nice!

Yes, I'm using QuickDraw primitives after all the 3D space is transformed and projected, but basically only painting filled or hollow polygons (triangles only, in fact). My plan is to implement Gouraud and/or Phong shading, and then I'd be just painting pixels, but for now I'm painting the triangles in flat shades.

Both the camera and the objects use transformation 4x4 matrices. In the case of the objects the transformations are the typical (translation, scaling, rotation), and the camera allows pitch, yaw and roll.

How long it takes you to render one of these three-balls sample images in that upgraded IIci?
 

KennyPowers

Active Tinkerer
Jun 27, 2022
278
315
63
How long it takes you to render one of these three-balls sample images in that upgraded IIci?

Depends on the settings and window size :) Let's assume the default window size for consistency. Then, with the following settings:

- Reflection = ON
- Refraction = OFF
- Shadows = ON
- Specular = ON
- Max Recursive Depth = 10

it takes ~47 seconds to render on the 040 IIci. Turning reflection off drops that to ~40 seconds. Turning refraction on?...well, go take a nap :) That makes sense since the ray will be bouncing around several times inside the red translucent sphere and generating additional reflective and refractive bounces. Lowering the max recursive depth therefore speeds up rendering with refraction on, but refraction is currently ugly anyways, sooo :) I'm sure there are some additional performance gains to be had, but I haven't focused too much on that. It's too bad parallelism isn't trivial on this platform, as this is an embarrassingly parallel problem. Running a similar algorithm using 32 threads on my 5950X renders the same scene in the blink of an eye :)