mirror of
https://github.com/alfishe/amiga-bootcamp.git
synced 2026-06-12 16:16:28 +00:00
docs(amiga): fix README navigation indexes, add missing entries, and update Tier 3 statuses
This commit is contained in:
parent
7960cbdf25
commit
fa8ce16936
4 changed files with 413 additions and 9 deletions
|
|
@ -20,13 +20,13 @@ This section provides a systematic methodology for reverse engineering AmigaOS e
|
|||
| [ida_setup.md](ida_setup.md) | IDA Pro configuration for 68k/Amiga analysis |
|
||||
| [ghidra_setup.md](ghidra_setup.md) | Ghidra configuration for 68k/Amiga analysis & decompilation |
|
||||
| [compiler_fingerprints.md](compiler_fingerprints.md) | Compiler identification by code patterns |
|
||||
| [library_reconstruction.md](library_reconstruction.md) | Reconstructing unknown library JMP tables |
|
||||
| [static/library_jmp_table.md](static/library_jmp_table.md) | Reconstructing unknown library JMP tables and LVOs |
|
||||
| [static/code_vs_data_disambiguation.md](static/code_vs_data_disambiguation.md) | Distinguishing code bytes from data — IDA/Ghidra workflows |
|
||||
| [patching_techniques.md](patching_techniques.md) | Surgical binary patching methods |
|
||||
| [unpacking_and_decrunching.md](unpacking_and_decrunching.md) | Executable unpacking, decruncher architecture, and manual extraction |
|
||||
| [custom_loaders_and_drm.md](custom_loaders_and_drm.md) | Bypassing DOS, Trackloaders, and physical DRM tricks |
|
||||
| [anti_debugging.md](anti_debugging.md) | The Cracker vs. Developer arms race: Trace vector abuse, NMI defeat, CIA timers |
|
||||
| [whdload_architecture.md](whdload_architecture.md) | WHDLoad internals, slaves, resload_DiskLoad, and runtime memory patching |
|
||||
| [games/whdload_architecture.md](games/whdload_architecture.md) | WHDLoad internals, slaves, resload_DiskLoad, and runtime memory patching |
|
||||
| [case_studies/](case_studies/) | Real-world RE walkthroughs |
|
||||
| [case_studies/ramdrive_device.md](case_studies/ramdrive_device.md) | ramdrive.device RE walkthrough |
|
||||
|
||||
|
|
|
|||
|
|
@ -392,12 +392,413 @@ The `MaxChars` field includes the null terminator. If your buffer is 64 bytes, s
|
|||
6. **Set `PLACETEXT_LEFT/RIGHT/ABOVE`** for label placement — don't hardcode text positions
|
||||
7. **Handle `IDCMP_REFRESHWINDOW`** with `GT_BeginRefresh()`/`GT_EndRefresh()`
|
||||
8. **Give every gadget a unique `GadgetID`** — this is how you identify the source in `IDCMP_GADGETUP`
|
||||
9. **Always check `CreateGadget()` return** — a NULL return means the list is broken; you must free everything
|
||||
10. **Create GadTools gadgets in order** — the linked list must be contiguous; skipping one breaks the chain
|
||||
11. **Use `GTMN_NewLookMenus, TRUE`** when calling `CreateMenus()` — consistent 3D look
|
||||
12. **Use `GA_Immediate` / `GA_RelVerify`** on raw gadgets — without both, you miss press/release events
|
||||
|
||||
---
|
||||
|
||||
## Named Antipatterns
|
||||
|
||||
### "The Invisible Gadget" — Forgetting GT_RefreshWindow
|
||||
|
||||
```c
|
||||
/* BAD: GadTools gadgets need an explicit render pass after window open.
|
||||
Without it, the gadget structures exist but nothing is drawn. */
|
||||
struct Window *win = OpenWindowTags(NULL,
|
||||
WA_Gadgets, glist,
|
||||
TAG_DONE);
|
||||
/* User sees an empty window — gadgets are invisible! */
|
||||
```
|
||||
|
||||
```c
|
||||
/* CORRECT: Always call GT_RefreshWindow after opening */
|
||||
struct Window *win = OpenWindowTags(NULL,
|
||||
WA_Gadgets, glist,
|
||||
TAG_DONE);
|
||||
GT_RefreshWindow(win, NULL); /* renders all gadget borders and labels */
|
||||
```
|
||||
|
||||
### "The Message Mangler" — Mixing GetMsg with GadTools
|
||||
|
||||
```c
|
||||
/* BAD: Using exec.library GetMsg() instead of GT_GetIMsg().
|
||||
GadTools internally injects messages for sub-events (ListView scrolling,
|
||||
slider dragging). GetMsg() doesn't route through GadTools' filter,
|
||||
so internal state desynchronizes — gadgets stop responding. */
|
||||
struct IntuiMessage *msg;
|
||||
while ((msg = GetMsg(win->UserPort))) /* WRONG */
|
||||
{
|
||||
HandleMessage(msg);
|
||||
ReplyMsg(msg); /* ALSO WRONG — must use GT_ReplyIMsg */
|
||||
}
|
||||
```
|
||||
|
||||
```c
|
||||
/* CORRECT: Always use the GT_ pair */
|
||||
struct IntuiMessage *msg;
|
||||
while ((msg = GT_GetIMsg(win->UserPort)))
|
||||
{
|
||||
HandleMessage(msg);
|
||||
GT_ReplyIMsg(msg);
|
||||
}
|
||||
```
|
||||
|
||||
### "The Orphaned Chain" — Not Checking CreateGadget Return
|
||||
|
||||
```c
|
||||
/* BAD: If CreateGadget() returns NULL, the linked list is broken.
|
||||
Continuing to use 'gad' as context for subsequent calls creates
|
||||
a corrupted gadget list — crash or silent malfunction. */
|
||||
gad = CreateGadget(BUTTON_KIND, gad, &ng, TAG_DONE);
|
||||
/* No NULL check! If this failed, gad is NULL... */
|
||||
gad = CreateGadget(STRING_KIND, gad, &ng, TAG_DONE); /* undefined behavior */
|
||||
```
|
||||
|
||||
```c
|
||||
/* CORRECT: Check every CreateGadget return */
|
||||
gad = CreateGadget(BUTTON_KIND, gad, &ng, TAG_DONE);
|
||||
if (!gad) goto cleanup;
|
||||
|
||||
gad = CreateGadget(STRING_KIND, gad, &ng, TAG_DONE);
|
||||
if (!gad) goto cleanup;
|
||||
/* ... */
|
||||
cleanup:
|
||||
FreeGadgets(glist); /* frees everything created so far */
|
||||
```
|
||||
|
||||
### "The Hot-Swap Hazard" — Modifying Gadgets In-Place
|
||||
|
||||
```c
|
||||
/* BAD: Changing a raw gadget's position while it's attached.
|
||||
Intuition may be in the middle of rendering the gadget when
|
||||
you change its coordinates — screen corruption. */
|
||||
myGadget->LeftEdge = 50; /* LIVE MODIFICATION — DANGEROUS */
|
||||
myGadget->Width = 200;
|
||||
```
|
||||
|
||||
```c
|
||||
/* CORRECT: Remove → modify → re-add → refresh */
|
||||
UWORD pos = RemoveGadget(win, myGadget);
|
||||
myGadget->LeftEdge = 50;
|
||||
myGadget->Width = 200;
|
||||
AddGadget(win, myGadget, pos);
|
||||
RefreshGList(myGadget, win, NULL, 1);
|
||||
```
|
||||
|
||||
> [!TIP]
|
||||
> For GadTools gadgets, use `GT_SetGadgetAttrs()` instead — it handles the remove/modify/add/refresh cycle internally.
|
||||
|
||||
### "The Silent Button" — Missing GACT_RELVERIFY
|
||||
|
||||
```c
|
||||
/* BAD: Without GACT_RELVERIFY, Intuition never sends IDCMP_GADGETUP.
|
||||
The user clicks the button, sees it highlight, but nothing happens. */
|
||||
struct Gadget myButton = {
|
||||
.Flags = GFLG_GADGHCOMP,
|
||||
.Activation = GACT_IMMEDIATE, /* only sends GADGETDOWN, not GADGETUP */
|
||||
.GadgetType = GTYP_BOOLGADGET,
|
||||
};
|
||||
```
|
||||
|
||||
```c
|
||||
/* CORRECT: Set both IMMEDIATE and RELVERIFY */
|
||||
struct Gadget myButton = {
|
||||
.Flags = GFLG_GADGHCOMP,
|
||||
.Activation = GACT_IMMEDIATE | GACT_RELVERIFY,
|
||||
.GadgetType = GTYP_BOOLGADGET,
|
||||
};
|
||||
/* Now you get both IDCMP_GADGETDOWN (press) and IDCMP_GADGETUP (release) */
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## GadTools → BOOPSI Migration Guide
|
||||
|
||||
GadTools is built on top of raw `struct Gadget`. BOOPSI gadgets (`GTYP_CUSTOMGADGET`) are a different system. Here's when and how to migrate:
|
||||
|
||||
### When to Stick with GadTools
|
||||
|
||||
- Standard buttons, checkboxes, sliders, string fields
|
||||
- Application targets OS 2.0–3.1
|
||||
- No custom gadget rendering needed
|
||||
- Quick prototyping
|
||||
|
||||
### When to Move to BOOPSI
|
||||
|
||||
- Custom gadget appearance or behavior
|
||||
- Inter-gadget communication (slider auto-updates label)
|
||||
- Reusable components across projects
|
||||
- Need `layouthook`-based auto-positioning
|
||||
|
||||
### Quick-Reference: Same Gadget, Two APIs
|
||||
|
||||
| Task | GadTools | BOOPSI (ReAction/MUI) |
|
||||
|------|----------|-----------------------|
|
||||
| Create button | `CreateGadget(BUTTON_KIND, ...)` | `NewObject(NULL, "button.gadget", ...)` |
|
||||
| Set value | `GT_SetGadgetAttrs(gad, win, NULL, TAG_DONE)` | `SetAttrs(obj, TAG_DONE)` |
|
||||
| Get value | `GT_GetGadgetAttrs(gad, win, NULL, TAG_DONE)` | `GetAttr(attr, obj, &val)` |
|
||||
| Disable | `GT_SetGadgetAttrs(gad, win, NULL, GA_Disabled, TRUE, TAG_DONE)` | `SetAttrs(obj, GA_Disabled, TRUE, TAG_DONE)` |
|
||||
| Event | `IDCMP_GADGETUP`, check `GadgetID` | `IDCMP_GADGETUP`, check `GadgetID` or `GA_ID` |
|
||||
| Free | `FreeGadgets(glist)` | `DisposeObject(obj)` |
|
||||
|
||||
### Key Differences
|
||||
|
||||
```c
|
||||
/* GadTools: all gadgets share one linked list, created sequentially */
|
||||
gad = CreateContext(&glist);
|
||||
gad = CreateGadget(BUTTON_KIND, gad, &ng1, TAG_DONE);
|
||||
gad = CreateGadget(STRING_KIND, gad, &ng2, TAG_DONE);
|
||||
/* glist points to the head — contains all gadgets */
|
||||
|
||||
/* BOOPSI: each gadget is an independent object */
|
||||
Object *btn = NewObject(NULL, "button.gadget",
|
||||
GA_ID, 1,
|
||||
TAG_DONE);
|
||||
Object *str = NewObject(NULL, "strgadget",
|
||||
GA_ID, 2,
|
||||
TAG_DONE);
|
||||
/* Must manually build into a gadget list or use a group */
|
||||
```
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
subgraph "GadTools Approach"
|
||||
CTX[CreateContext] --> G1[Button]
|
||||
G1 --> G2[String]
|
||||
G2 --> G3[Slider]
|
||||
end
|
||||
|
||||
subgraph "BOOPSI Approach"
|
||||
B[NewObject button]
|
||||
S[NewObject strgadget]
|
||||
SL[NewObject propgadget]
|
||||
B -->|GA_Next| S
|
||||
S -->|GA_Next| SL
|
||||
end
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Practical Cookbook: Form with Mixed Gadgets
|
||||
|
||||
```c
|
||||
#include <proto/exec.h>
|
||||
#include <proto/intuition.h>
|
||||
#include <proto/gadtools.h>
|
||||
#include <libraries/gadtools.h>
|
||||
|
||||
enum {
|
||||
GAD_NAME = 1,
|
||||
GAD_AGE,
|
||||
GAD_COLOR,
|
||||
GAD_OK,
|
||||
GAD_CANCEL
|
||||
};
|
||||
|
||||
static const STRPTR colorLabels[] = { "Red", "Green", "Blue", NULL };
|
||||
|
||||
struct AppGadgets {
|
||||
struct Gadget *glist;
|
||||
struct Gadget *gadName;
|
||||
struct Gadget *gadAge;
|
||||
struct Gadget *gadColor;
|
||||
struct Gadget *gadOk;
|
||||
};
|
||||
|
||||
struct AppGadgets CreateFormGadgets(APTR vi, struct TextAttr *topaz8)
|
||||
{
|
||||
struct AppGadgets ag = {0};
|
||||
struct Gadget *gad;
|
||||
struct NewGadget ng = {0};
|
||||
|
||||
gad = CreateContext(&ag.glist);
|
||||
|
||||
/* --- Name string gadget --- */
|
||||
ng.ng_LeftEdge = 80;
|
||||
ng.ng_TopEdge = 20;
|
||||
ng.ng_Width = 200;
|
||||
ng.ng_Height = 16;
|
||||
ng.ng_GadgetText = "Name:";
|
||||
ng.ng_TextAttr = topaz8;
|
||||
ng.ng_VisualInfo = vi;
|
||||
ng.ng_Flags = PLACETEXT_LEFT;
|
||||
|
||||
ag.gadName = gad = CreateGadget(STRING_KIND, gad, &ng,
|
||||
GTST_MaxChars, 63,
|
||||
GTST_String, "",
|
||||
GA_ID, GAD_NAME,
|
||||
TAG_DONE);
|
||||
|
||||
/* --- Age integer gadget --- */
|
||||
ng.ng_TopEdge += 24;
|
||||
ng.ng_GadgetText = "Age:";
|
||||
ng.ng_GadgetID = GAD_AGE;
|
||||
|
||||
ag.gadAge = gad = CreateGadget(INTEGER_KIND, gad, &ng,
|
||||
GTIN_MaxChars, 4,
|
||||
GA_ID, GAD_AGE,
|
||||
TAG_DONE);
|
||||
|
||||
/* --- Color cycle gadget --- */
|
||||
ng.ng_TopEdge += 24;
|
||||
ng.ng_Width = 200;
|
||||
ng.ng_GadgetText = "Color:";
|
||||
ng.ng_GadgetID = GAD_COLOR;
|
||||
|
||||
ag.gadColor = gad = CreateGadget(CYCLE_KIND, gad, &ng,
|
||||
GTCY_Labels, colorLabels,
|
||||
GA_ID, GAD_COLOR,
|
||||
TAG_DONE);
|
||||
|
||||
/* --- OK / Cancel buttons --- */
|
||||
ng.ng_TopEdge += 30;
|
||||
ng.ng_LeftEdge = 120;
|
||||
ng.ng_Width = 80;
|
||||
ng.ng_Height = 20;
|
||||
ng.ng_GadgetText = "_OK";
|
||||
ng.ng_Flags = PLACETEXT_IN;
|
||||
|
||||
ag.gadOk = gad = CreateGadget(BUTTON_KIND, gad, &ng,
|
||||
GA_ID, GAD_OK,
|
||||
TAG_DONE);
|
||||
|
||||
ng.ng_LeftEdge += 90;
|
||||
ng.ng_GadgetText = "_Cancel";
|
||||
ng.ng_GadgetID = GAD_CANCEL;
|
||||
|
||||
gad = CreateGadget(BUTTON_KIND, gad, &ng,
|
||||
GA_ID, GAD_CANCEL,
|
||||
TAG_DONE);
|
||||
|
||||
return ag;
|
||||
}
|
||||
|
||||
void ReadFormValues(struct AppGadgets *ag, struct Window *win)
|
||||
{
|
||||
STRPTR name;
|
||||
LONG age;
|
||||
USHORT colorIdx;
|
||||
|
||||
GT_GetGadgetAttrs(ag->gadName, win, NULL,
|
||||
GTST_String, &name, TAG_DONE);
|
||||
|
||||
GT_GetGadgetAttrs(ag->gadAge, win, NULL,
|
||||
GTIN_Number, &age, TAG_DONE);
|
||||
|
||||
GT_GetGadgetAttrs(ag->gadColor, win, NULL,
|
||||
GTCY_Active, &colorIdx, TAG_DONE);
|
||||
|
||||
Printf("Name=%s Age=%ld Color=%s\n",
|
||||
name, age, colorLabels[colorIdx]);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Historical Context & Modern Analogies
|
||||
|
||||
### Competitive Landscape
|
||||
|
||||
| Platform | Gadget System | Custom Classes | Layout Engine | Inter-Gadget Communication |
|
||||
|----------|-------------|---------------|--------------|--------------------------|
|
||||
| **AmigaOS GadTools** | `CreateGadget()` + `NewGadget` | No — fixed gadget types | Manual coordinates | Via application event loop |
|
||||
| **AmigaOS BOOPSI** | `NewObject()` + dispatcher | Yes — subclass rootclass | Manual or layout hook | ICA interconnection (observer) |
|
||||
| **Amiga MUI** | `NewObject("mui.class")` | Yes — subclass MUI classes | Automatic (group/layout) | Notification hooks |
|
||||
| **Mac OS (Classic)** | Control Manager + CNTL resources | Yes (via CDEF) | Manual or dialog resources | Application event routing |
|
||||
| **Windows 3.x** | `CreateWindow()` + `WNDCLASS` | Yes (via WNDPROC) | Manual or dialog templates | `WM_COMMAND` / `SendDlgItemMessage()` |
|
||||
| **X11/Motif** | `XtCreateWidget()` + `XmCreate*` | Yes (via Xt class) | `XmForm` constraints | `XtAddCallback()` |
|
||||
|
||||
### Evolution of Amiga Gadget Systems
|
||||
|
||||
```mermaid
|
||||
timeline
|
||||
title Amiga Gadget API Timeline
|
||||
1985 : OS 1.0 — Raw struct Gadget\nManual Border/Image imagery
|
||||
1987 : OS 1.3 — No significant changes\nGadgets remained primitive
|
||||
1990 : OS 2.0 — GadTools.library\nCreateGadget() API\nBOOPSI introduced
|
||||
1992 : OS 2.1 — gadtools V39\nGT_GetGadgetAttrs added
|
||||
1993 : OS 3.0 — NewLook 3D gadgets\nGA_Disabled appearance
|
||||
1995 : OS 3.1 — No API changes\nBug fixes only
|
||||
1996 : MUI 3.x — Third-party\nAutomatic layout, skinning
|
||||
1999 : ReAction — AROS/OS 3.5+\nWindow.class, Layout.gadget
|
||||
```
|
||||
|
||||
### Modern Analogies
|
||||
|
||||
| Amiga Concept | Modern Equivalent | Notes |
|
||||
|--------------|-------------------|-------|
|
||||
| `struct Gadget` | `GtkWidget` / `QWidget` / `NSView` | Base widget type |
|
||||
| `GadgetID` | `gtk_buildable_get_name()` / Qt `objectName` | Widget identification |
|
||||
| `CreateGadget(KIND, ...)` | `gtk_button_new_with_label()` / Qt `QPushButton(tr("..."))` | Factory creation |
|
||||
| `GT_SetGadgetAttrs()` | `gtk_widget_set_property()` / Qt `setProperty()` | Runtime update |
|
||||
| `GT_GetGadgetAttrs()` | `gtk_widget_get_property()` / Qt `property()` | Runtime query |
|
||||
| `GA_Disabled` | `gtk_widget_set_sensitive()` / Qt `setEnabled()` | Gray out |
|
||||
| `GFLG_RELWIDTH/RELHEIGHT` | GTK `hexpand` / Qt `sizePolicy` | Responsive sizing |
|
||||
| `CreateContext(&glist)` | GtkBuilder `.ui` file / Qt `.ui` file | Container for widget tree |
|
||||
| `GT_RefreshWindow()` | Not needed — modern toolkits auto-render | Amiga requires explicit refresh |
|
||||
| `PropInfo` (HorizPot/VertPot) | `gtk_adjustment_set_value()` / Qt `QSlider::setValue()` | Scrollbar/slider state |
|
||||
| `RemoveGadget()` / `AddGadget()` | `gtk_container_remove()` / `gtk_container_add()` | Dynamic widget management |
|
||||
| `PLACETEXT_LEFT/RIGHT` | GTK `GtkLabel` + `GtkBox` / Qt `QFormLayout` | Label positioning |
|
||||
|
||||
---
|
||||
|
||||
## Use Cases
|
||||
|
||||
| Application | Gadget Types Used | Notable Patterns |
|
||||
|-------------|------------------|-----------------|
|
||||
| **Workbench** | System gadgets (close, depth, drag, size) | All windows use the same system gadget set |
|
||||
| **Prefs programs** | Cycle, slider, palette, button | Cycle for screen mode, slider for frequency, palette for colors |
|
||||
| **File requesters (ASL)** | ListView, string, button, scroller | ListView for file list, string for filename input |
|
||||
| **Text editors** | String, button, scroller | String for find/replace dialogs, scroller for document view |
|
||||
| **Image editors (DPaint)** | Cycle, palette, button, custom gadgets | Palette for color selection, custom gadgets for tool options |
|
||||
| **Audio trackers** | Integer, slider, button, listview | Integer for BPM/tempo, slider for volume, listview for patterns |
|
||||
| **Installer scripts** | Button, checkbox, string | Checkbox for options, string for install path |
|
||||
| **Game launchers** | Cycle, button, checkbox, slider | Cycle for resolution, slider for volume, checkbox for fullscreen |
|
||||
|
||||
---
|
||||
|
||||
## FAQ
|
||||
|
||||
**Q: What's the difference between GadTools and BOOPSI gadgets?**
|
||||
A: GadTools is a convenience wrapper that creates raw `struct Gadget` objects with pre-built rendering and behavior. BOOPSI gadgets (`GTYP_CUSTOMGADGET`) use `DoMethod()` dispatch and support inheritance and ICA interconnection. GadTools gadgets are simpler but limited to fixed types; BOOPSI gadgets are extensible but require more boilerplate.
|
||||
|
||||
**Q: Can I mix GadTools and BOOPSI gadgets in the same window?**
|
||||
A: Yes — both ultimately become `struct Gadget` nodes in the same linked list. However, you must use the correct API for each type: `GT_SetGadgetAttrs()` for GadTools, `SetAttrs()` for BOOPSI. Event handling (`IDCMP_GADGETUP`) works the same for both.
|
||||
|
||||
**Q: Why does my slider only send `IDCMP_GADGETUP` on release?**
|
||||
A: By default, sliders only report the final value. To get continuous updates while dragging, set `GA_FollowMouse` in `CreateGadget()`. This causes `IDCMP_MOUSEMOVE` events with the slider gadget as `IAddress` while the user drags.
|
||||
|
||||
**Q: How do I create a scrollable list that updates dynamically?**
|
||||
A: Use `LISTVIEW_KIND` with `GT_SetGadgetAttrs()` and `GTLV_Labels` to update the string array. The listview redraws automatically. Remember the label array must remain valid (static or heap-allocated) for the lifetime of the gadget.
|
||||
|
||||
**Q: Can gadgets span multiple windows?**
|
||||
A: No — a gadget can only be attached to one window at a time. To create the same gadget in multiple windows, create separate gadget instances for each.
|
||||
|
||||
**Q: What happens to gadget input during menu mode?**
|
||||
A: Intuition freezes all gadget input while the menu strip is active (right mouse button held). No `IDCMP_GADGETDOWN`/`IDCMP_GADGETUP` events are delivered until the menu closes.
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- NDK 3.9: `intuition/intuition.h`, `intuition/gadgetclass.h`, `libraries/gadtools.h`
|
||||
- ADCD 2.1: `CreateGadget()`, `GT_SetGadgetAttrs()`, `GT_GetGadgetAttrs()`
|
||||
- AmigaOS Reference Manual (RKRM): Libraries, Chapter 7 — Gadgets
|
||||
- See also: [BOOPSI](boopsi.md), [IDCMP](idcmp.md), [Windows](windows.md)
|
||||
### NDK Headers
|
||||
|
||||
- `intuition/intuition.h` — `struct Gadget`, `struct PropInfo`, `struct StringInfo`, `GFLG_*`/`GACT_*`/`GTYP_*` flags
|
||||
- `intuition/gadgetclass.h` — BOOPSI gadget class attributes (`GA_*`)
|
||||
- `libraries/gadtools.h` — `struct NewGadget`, gadget kinds (`*_KIND`), `GTST_*`/`GTSL_*`/`GTCY_*` tags
|
||||
|
||||
### Autodocs
|
||||
|
||||
- ADCD 2.1: `CreateGadget()`, `CreateContext()`, `GT_SetGadgetAttrs()`, `GT_GetGadgetAttrs()`, `FreeGadgets()`
|
||||
- ADCD 2.1: `GT_GetIMsg()`, `GT_ReplyIMsg()`, `GT_RefreshWindow()`, `GT_BeginRefresh()`, `GT_EndRefresh()`
|
||||
- ADCD 2.1: `AddGadget()`, `RemoveGadget()`, `RefreshGList()`
|
||||
|
||||
### Related Knowledge Base Articles
|
||||
|
||||
- [BOOPSI](boopsi.md) — object-oriented gadget system, ICA interconnection
|
||||
- [IDCMP](idcmp.md) — `IDCMP_GADGETUP`/`IDCMP_GADGETDOWN` event handling
|
||||
- [Windows](windows.md) — windows host gadget lists
|
||||
- [Screens](screens.md) — VisualInfo ties gadgets to screen appearance
|
||||
- [Intuition Base](intuition_base.md) — Intuition's global state and rendering
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ The Amiga's documentation was scattered across out-of-print manuals, Usenet post
|
|||
| [unpacking_and_decrunching.md](05_reversing/unpacking_and_decrunching.md) | Executable unpacking, decruncher architecture, and manual extraction |
|
||||
| [custom_loaders_and_drm.md](05_reversing/custom_loaders_and_drm.md) | Bypassing DOS, Trackloaders, and physical DRM tricks |
|
||||
| [anti_debugging.md](05_reversing/anti_debugging.md) | The Cracker vs. Developer arms race: Trace vector abuse, NMI defeat |
|
||||
| [whdload_architecture.md](05_reversing/whdload_architecture.md) | WHDLoad internals, slaves, resload_DiskLoad, memory patching |
|
||||
| [games/whdload_architecture.md](05_reversing/games/whdload_architecture.md) | WHDLoad internals, slaves, resload_DiskLoad, memory patching |
|
||||
| [case_studies/ramdrive_device.md](05_reversing/case_studies/ramdrive_device.md) | Case Study: ramdrive.device RE walkthrough |
|
||||
|
||||
| Per-Compiler RE Field Manuals | Topic |
|
||||
|
|
@ -213,6 +213,8 @@ The Amiga's documentation was scattered across out-of-print manuals, Usenet post
|
|||
| [blitter.md](08_graphics/blitter.md) | Blitter DMA, minterms, BltBitMap |
|
||||
| [blitter_programming.md](08_graphics/blitter_programming.md) | Blitter deep dive: cookie-cut, fill, line draw |
|
||||
| [sprites.md](08_graphics/sprites.md) | Hardware sprites, SimpleSprite |
|
||||
| [display_modes.md](08_graphics/display_modes.md) | ModeID selection flowchart, CRT vs flat-panel, interlace/progressive tradeoffs, named antipatterns, FPGA/MiSTer impact, historical context, modern analogies, FAQ |
|
||||
| [ham_ehb_modes.md](08_graphics/ham_ehb_modes.md) | HAM6/HAM8 encoding pipeline, EHB half-brite, fringing, palette programming, FPGA decoder logic |
|
||||
| [rastport.md](08_graphics/rastport.md) | RastPort, drawing primitives, layers |
|
||||
| [views.md](08_graphics/views.md) | View/ViewPort, MakeVPort, display pipeline |
|
||||
| [text_fonts.md](08_graphics/text_fonts.md) | TextFont bitmap layout, baseline rendering, algorithmic styles, AvailFonts enumeration |
|
||||
|
|
@ -233,6 +235,7 @@ The Amiga's documentation was scattered across out-of-print manuals, Usenet post
|
|||
| [boopsi.md](09_intuition/boopsi.md) | BOOPSI object system, custom classes |
|
||||
| [input_events.md](09_intuition/input_events.md) | InputEvent, Commodities Exchange |
|
||||
| [commodities.md](09_intuition/commodities.md) | Commodities Exchange: hotkeys, screen blankers, CxObject API |
|
||||
| **[frameworks/mui/](09_intuition/frameworks/mui/)** | **MUI (Magic User Interface): architecture, layout system, widgets, custom classes, events, reference snippets** |
|
||||
|
||||
### 10 — Devices
|
||||
| File | Topic |
|
||||
|
|
|
|||
4
TODO.md
4
TODO.md
|
|
@ -57,7 +57,7 @@ Articles were scored against [AGENTS.md](../amiga/AGENTS.md) "Deep" criteria:
|
|||
| 17 | `09_intuition/screens.md` | 582 | 582 | ❌ **Pending** — Antipatterns, cookbook (screen flipping, borderless, PAL→NTSC handling) |
|
||||
| 18 | `09_intuition/windows.md` | 370 | 778 | ✅ **Complete** — Added 5 named antipatterns (Border Collision, Unresponsive Close, Leaked Message, Refresh Loop, Phantom Window), window type decision guide with Mermaid, 3 cookbooks (resizable, borderless overlay, multi-window shared port), historical comparison, modern analogies, use cases, 7 FAQ |
|
||||
| 19 | `09_intuition/menus.md` | 378 | 695 | ✅ **Complete** — Added render chain sequence diagram, 5 named antipatterns (Multi-Select Ghost, Stale Menu, Cleanup Reversal, Shortcut Collision, Phantom VisualInfo), complete lifecycle cookbook, historical comparison, modern analogies, use cases, 6 FAQ |
|
||||
| 20 | `09_intuition/gadgets.md` | 403 | 403 | ❌ **Pending** — Named antipatterns, BOOPSI command flow, GadTools→BOOPSI migration guide |
|
||||
| 20 | `09_intuition/gadgets.md` | 403 | 804 | ✅ **Complete** — Added 5 named antipatterns (Invisible Gadget, Message Mangler, Orphaned Chain, Hot-Swap Hazard, Silent Button), GadTools→BOOPSI migration guide with comparison table, form cookbook, historical timeline, modern analogies, use cases, 6 FAQ |
|
||||
| 21 | `11_libraries/iffparse.md` | 271 | 1031 | ✅ **DONE** — Nesting & chunk hierarchy diagrams, ILBM/EHB pitfalls, PBM read patterns, cross-reference to Datatypes |
|
||||
| 22 | `13_toolchain/gcc_amiga.md` | 82 | 82 | ❌ **Pending** — Extremely thin stub. Needs full build pipeline, Docker cross-compilation guide, linker scripts, amiga-gcc specifics |
|
||||
| 23 | `11_libraries/layers.md` | 224 | 739 | ✅ **Complete** — Expanded with ClipRect engine deep-dive, API reference with LVOs, backfill hook cookbook, refresh type decision guide, 4 named antipatterns, 4 pitfalls, ClipBlit vs ScrollRaster optimization, historical comparison table, modern analogies, 7 FAQ |
|
||||
|
|
@ -269,7 +269,7 @@ Articles were scored against [AGENTS.md](../amiga/AGENTS.md) "Deep" criteria:
|
|||
| `commodities.md` | 769 | ✅ Deep | Tier 1 creation: Exchange, hotkeys, CxObjects, brokers |
|
||||
| `screens.md` | 582 | ❌ Pending | Tier 3 #17: needs antipatterns, cookbook (screen flipping, borderless, PAL→NTSC) |
|
||||
| `boopsi.md` | 505 | ✅ Adequate | OOP dispatcher, ICA interconnection, custom class tutorial |
|
||||
| `gadgets.md` | 403 | ❌ Pending | Tier 3 #20: needs antipatterns, BOOPSI command flow, GadTools→BOOPSI guide |
|
||||
| `gadgets.md` | 804 | ✅ Deep | 5 antipatterns, GadTools→BOOPSI migration, form cookbook, timeline, modern analogies, use cases, 6 FAQ |
|
||||
| `menus.md` | 695 | ✅ Deep | Render chain diagram, 5 antipatterns, lifecycle cookbook, historical + modern analogies, use cases, 6 FAQ |
|
||||
| `windows.md` | 778 | ✅ Deep | 5 named antipatterns, window type decision guide, 3 cookbooks (resizable, borderless, shared port), historical + modern analogies, use cases, 7 FAQ |
|
||||
| `requesters.md` | 370 | ✅ Adequate | EasyRequest, ASL file/font/screenmode dialogs |
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue