mirror of
https://github.com/alfishe/amiga-bootcamp.git
synced 2026-06-13 00:26:28 +00:00
Expand documentation suite: 30+ articles enriched with diagrams, code examples, and hardware details
Graphics: text_fonts (bitmap layout, styles), sprites (DMA, multiplexing), gfx_base (chipset detection), rastport (draw modes, clipping), ham_ehb (mermaid fixes), display_modes (HAM palettes) Devices: scsi (per-model interfaces, Gayle limits, CD-ROM, native vs vendor drivers), console (ANSI sequences, CON:/RAW:), parallel (CIA registers, pinout), timer (resource exhaustion), gameport (quadrature, XOR state) Libraries: workbench (WBStartup, AppWindow/Icon/MenuItem), rexxsyslib (ARexx port hosting, command parsing), diskfont (font directory, colour fonts), keymap (rawkey codes, dead keys), locale (catalogue system, date formatting), layers (ClipRect, refresh types), utility (TagItem chains), icon (DiskObject, ToolTypes), iffparse (IFF structure, ByteRun1), expansion (Zorro AutoConfig) Networking: tcp_ip_stacks (major rewrite - Amiga vs Unix architecture, SANA-II pipeline, PPP/SLIP dial-up, Ethernet cards, MiSTer), bsdsocket (pure API ref), sana2 (buffer hooks, driver requirements), protocols (all code examples). Deduplicated overlap between the three files. Toolchain: debugging (Enforcer patterns, SnoopDOS, GDB remote, kprintf checklist), sasc (pragma encoding, __saveds idioms), stormc (NEW - StormC IDE, C++, PowerPC) References: error_codes (DOS, Exec, trackdisk, Intuition error tables) Driver development: rtg_driver (Native driver analysis, P96 tuning) All 22 README indexes updated. Root README synced with stormc.md entry.
This commit is contained in:
parent
0ded078134
commit
f61c26b542
38 changed files with 6402 additions and 1065 deletions
|
|
@ -4,7 +4,31 @@
|
|||
|
||||
## Overview
|
||||
|
||||
`RastPort` is the primary drawing context in AmigaOS. All graphics primitives (pixel, line, rectangle, polygon, text) operate through a `RastPort`, which links a `BitMap`, drawing pen colours, pattern, font, and optional `Layer` for clipping.
|
||||
`RastPort` is the primary drawing context in AmigaOS — the equivalent of a "device context" (Windows) or "graphics context" (X11). All graphics primitives (pixel, line, rectangle, polygon, text) operate through a RastPort, which bundles together a target `BitMap`, drawing pen colours, patterns, font, draw mode, and an optional `Layer` for clipping.
|
||||
|
||||
Every Intuition window and screen has its own RastPort. When you draw into a window, you're drawing through its RastPort.
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
subgraph "RastPort — Drawing Context"
|
||||
RP["struct RastPort"]
|
||||
RP --> BM["BitMap<br/>(pixel storage)"]
|
||||
RP --> PEN["Pens<br/>FgPen, BgPen, AOlPen"]
|
||||
RP --> DM["DrawMode<br/>JAM1/JAM2/COMPLEMENT"]
|
||||
RP --> FONT["TextFont<br/>(current font)"]
|
||||
RP --> PAT["AreaPtrn<br/>(fill pattern)"]
|
||||
RP --> LAYER["Layer<br/>(clipping region)"]
|
||||
RP --> CP["cp_x, cp_y<br/>(cursor position)"]
|
||||
end
|
||||
|
||||
APP["Application Code"] -->|"SetAPen, Move,<br/>Draw, RectFill,<br/>Text, ClipBlit"| RP
|
||||
RP -->|"Drawing operations"| BM
|
||||
LAYER -->|"Clips to visible region"| BM
|
||||
|
||||
style RP fill:#e8f4fd,stroke:#2196f3,color:#333
|
||||
style BM fill:#c8e6c9,stroke:#2e7d32,color:#333
|
||||
style LAYER fill:#fff9c4,stroke:#f9a825,color:#333
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -49,64 +73,331 @@ struct RastPort {
|
|||
|
||||
## Draw Modes
|
||||
|
||||
```c
|
||||
#define JAM1 0 /* draw FgPen only; background transparent */
|
||||
#define JAM2 1 /* draw FgPen and BgPen (opaque) */
|
||||
#define COMPLEMENT 2 /* XOR with existing pixels */
|
||||
#define INVERSVID 4 /* invert video (swap fg/bg for text) */
|
||||
The draw mode controls how new pixels combine with existing content:
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph "JAM1 — Transparent"
|
||||
J1BG["Background<br/>unchanged"] --- J1FG["Foreground<br/>drawn with FgPen"]
|
||||
end
|
||||
|
||||
subgraph "JAM2 — Opaque"
|
||||
J2BG["Background<br/>drawn with BgPen"] --- J2FG["Foreground<br/>drawn with FgPen"]
|
||||
end
|
||||
|
||||
subgraph "COMPLEMENT — XOR"
|
||||
XBG["All pixels<br/>XOR with existing"]
|
||||
end
|
||||
```
|
||||
|
||||
```c
|
||||
#define JAM1 0 /* draw FgPen only; background pixels are NOT touched */
|
||||
#define JAM2 1 /* draw FgPen AND BgPen — fully opaque */
|
||||
#define COMPLEMENT 2 /* XOR all drawn pixels with existing content */
|
||||
#define INVERSVID 4 /* swap foreground/background (for text inverse) */
|
||||
```
|
||||
|
||||
| Mode | Text Example | Fill Example | Use Case |
|
||||
|---|---|---|---|
|
||||
| `JAM1` | Characters drawn, background shows through | Solid fill with FgPen | Transparent overlays, labels on images |
|
||||
| `JAM2` | Characters + background box drawn | Same as JAM1 for fills | Opaque text on busy backgrounds |
|
||||
| `COMPLEMENT` | XOR of text pixels with screen | XOR fill | Rubber-band selection, dragging cursors |
|
||||
| `JAM1 | INVERSVID` | Background drawn with FgPen, chars transparent | — | Highlighted/selected text |
|
||||
|
||||
---
|
||||
|
||||
## Drawing Primitives
|
||||
|
||||
```c
|
||||
/* Set pen colour: */
|
||||
SetAPen(rp, 1); /* foreground = colour 1 */
|
||||
SetBPen(rp, 0); /* background = colour 0 */
|
||||
SetDrMd(rp, JAM1); /* transparent background */
|
||||
### Pen and Position Setup
|
||||
|
||||
/* Move to position: */
|
||||
```c
|
||||
/* Set pen colours: */
|
||||
SetAPen(rp, 1); /* foreground = colour register 1 */
|
||||
SetBPen(rp, 0); /* background = colour register 0 */
|
||||
SetDrMd(rp, JAM1); /* transparent background mode */
|
||||
|
||||
/* OS 3.0+ — use named pen for correct Workbench colours: */
|
||||
SetAPen(rp, screen->RastPort.BitMap->Depth > 1 ?
|
||||
ObtainBestPen(screen->ViewPort.ColorMap,
|
||||
0xFF000000, 0x00000000, 0x00000000, /* red */
|
||||
OBP_Precision, PRECISION_GUI,
|
||||
TAG_DONE) : 1);
|
||||
```
|
||||
|
||||
### Lines and Pixels
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
M["Move(rp, 10, 20)"] -->|"sets cp_x, cp_y"| D1["Draw(rp, 100, 20)"]
|
||||
D1 -->|"draws line,<br/>updates cp"| D2["Draw(rp, 100, 80)"]
|
||||
D2 -->|"draws line,<br/>updates cp"| D3["Draw(rp, 10, 80)"]
|
||||
D3 -->|"draws line,<br/>updates cp"| D4["Draw(rp, 10, 20)"]
|
||||
|
||||
style M fill:#e8f4fd,stroke:#2196f3,color:#333
|
||||
```
|
||||
|
||||
```c
|
||||
/* Move cursor (no drawing): */
|
||||
Move(rp, 100, 50);
|
||||
|
||||
/* Draw line from current position to (x,y): */
|
||||
/* Draw line from current position to (x,y), update cp: */
|
||||
Draw(rp, 200, 100);
|
||||
/* cp is now (200, 100) — next Draw continues from here */
|
||||
|
||||
/* Write pixel: */
|
||||
/* Draw a connected polygon: */
|
||||
Move(rp, 10, 10);
|
||||
Draw(rp, 100, 10); /* top edge */
|
||||
Draw(rp, 100, 80); /* right edge */
|
||||
Draw(rp, 10, 80); /* bottom edge */
|
||||
Draw(rp, 10, 10); /* close: left edge */
|
||||
|
||||
/* Single pixel: */
|
||||
WritePixel(rp, 160, 120);
|
||||
|
||||
/* Read pixel: */
|
||||
LONG colour = ReadPixel(rp, 160, 120);
|
||||
|
||||
/* Filled rectangle: */
|
||||
RectFill(rp, 10, 10, 100, 50);
|
||||
/* Dashed lines: */
|
||||
SetDrPt(rp, 0xF0F0); /* 16-bit pattern: 1111000011110000 */
|
||||
Draw(rp, 200, 100); /* draws dashed line */
|
||||
SetDrPt(rp, 0xFFFF); /* restore solid */
|
||||
```
|
||||
|
||||
/* Draw text at current position: */
|
||||
Move(rp, 20, 30);
|
||||
Text(rp, "Hello", 5);
|
||||
### Rectangles and Fills
|
||||
|
||||
/* Blitter copy between RastPorts: */
|
||||
ClipBlit(srcRP, sx, sy, dstRP, dx, dy, w, h, minterm);
|
||||
```c
|
||||
/* Solid filled rectangle (uses FgPen + DrawMode): */
|
||||
SetAPen(rp, 3);
|
||||
RectFill(rp, 10, 10, 100, 50); /* x1,y1 to x2,y2 inclusive */
|
||||
|
||||
/* Erase to background (clear a region): */
|
||||
SetAPen(rp, 0);
|
||||
SetDrMd(rp, JAM1);
|
||||
RectFill(rp, 0, 0, 319, 255);
|
||||
|
||||
/* Scroll a region (with clear): */
|
||||
ScrollRaster(rp, dx, dy, x1, y1, x2, y2);
|
||||
/* Shifts content by (dx,dy); exposed area cleared to BgPen */
|
||||
```
|
||||
|
||||
### Text Rendering
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
ATTR["TextAttr<br/>(name, size)"] -->|"OpenFont /<br/>OpenDiskFont"| TF["TextFont"]
|
||||
TF -->|"SetFont(rp, font)"| RP["RastPort"]
|
||||
RP -->|"Move + Text"| OUT["Rendered text<br/>on bitmap"]
|
||||
```
|
||||
|
||||
```c
|
||||
/* Set font: */
|
||||
struct TextAttr ta = {"topaz.font", 8, 0, FPF_ROMFONT};
|
||||
struct TextFont *font = OpenFont(&ta);
|
||||
SetFont(rp, font);
|
||||
|
||||
/* Render text at position: */
|
||||
Move(rp, 20, 30); /* baseline position */
|
||||
Text(rp, "Hello Amiga", 11);
|
||||
|
||||
/* Measure text width before rendering (for alignment): */
|
||||
UWORD width = TextLength(rp, "Hello Amiga", 11);
|
||||
/* Right-align: */
|
||||
Move(rp, screenWidth - width - 10, 30);
|
||||
Text(rp, "Hello Amiga", 11);
|
||||
|
||||
/* Bold/italic (algorithmic): */
|
||||
UWORD supported = AskSoftStyle(rp);
|
||||
SetSoftStyle(rp, FSF_BOLD | FSF_ITALIC, supported);
|
||||
Text(rp, "Bold Italic", 11);
|
||||
SetSoftStyle(rp, 0, supported); /* restore */
|
||||
```
|
||||
|
||||
### Area Fills (Polygons)
|
||||
|
||||
```c
|
||||
/* Area fills require setup: TmpRas + AreaInfo */
|
||||
UBYTE areaBuffer[5 * 5]; /* 5 vertices × 5 bytes each */
|
||||
struct AreaInfo areaInfo;
|
||||
InitArea(&areaInfo, areaBuffer, 5);
|
||||
rp->AreaInfo = &areaInfo;
|
||||
|
||||
PLANEPTR tmpRasData = AllocRaster(320, 256);
|
||||
struct TmpRas tmpRas;
|
||||
InitTmpRas(&tmpRas, tmpRasData, RASSIZE(320, 256));
|
||||
rp->TmpRas = &tmpRas;
|
||||
|
||||
/* Draw a filled triangle: */
|
||||
AreaMove(rp, 100, 10); /* first vertex */
|
||||
AreaDraw(rp, 200, 180); /* second vertex */
|
||||
AreaDraw(rp, 20, 180); /* third vertex */
|
||||
AreaEnd(rp); /* fill and close */
|
||||
|
||||
/* Cleanup: */
|
||||
FreeRaster(tmpRasData, 320, 256);
|
||||
```
|
||||
|
||||
### Flood Fill
|
||||
|
||||
```c
|
||||
/* Flood fill from a seed point: */
|
||||
/* Requires TmpRas (same setup as area fills) */
|
||||
Flood(rp, 1, 50, 50);
|
||||
/* mode 1 = fill until FgPen colour boundary */
|
||||
/* mode 0 = fill all connected pixels of same colour as seed */
|
||||
```
|
||||
|
||||
### Blitting (Block Transfer)
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
SRC["Source RastPort<br/>(or BitMap)"] -->|"ClipBlit /<br/>BltBitMapRastPort"| DST["Destination RastPort"]
|
||||
|
||||
subgraph "Minterm Controls"
|
||||
MT["0xC0 = copy<br/>0x30 = invert copy<br/>0x50 = XOR<br/>0x00 = clear"]
|
||||
end
|
||||
MT --> DST
|
||||
```
|
||||
|
||||
```c
|
||||
/* Copy region between RastPorts (respects clipping): */
|
||||
ClipBlit(srcRP, sx, sy, /* source position */
|
||||
dstRP, dx, dy, /* destination position */
|
||||
width, height,
|
||||
0xC0); /* minterm: straight copy */
|
||||
|
||||
/* Copy from BitMap to RastPort: */
|
||||
BltBitMapRastPort(srcBM, sx, sy,
|
||||
dstRP, dx, dy,
|
||||
width, height,
|
||||
0xC0);
|
||||
|
||||
/* Common minterms: */
|
||||
/* 0xC0 = A (copy source) */
|
||||
/* 0x30 = NOT A (invert source) */
|
||||
/* 0x50 = A XOR B (toggle) */
|
||||
/* 0x00 = clear destination */
|
||||
/* 0xFF = set all bits */
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Layers
|
||||
## Layers — Window Clipping
|
||||
|
||||
When `rp->Layer != NULL`, all drawing is clipped to the layer's bounds and damage regions. Layers are managed by `layers.library`:
|
||||
When `rp->Layer != NULL`, all drawing is automatically clipped to the layer's visible region. Intuition creates layers for every window — this is how overlapping windows work without drawing over each other.
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
subgraph "Screen"
|
||||
subgraph "Window A (front)"
|
||||
LA["Layer A<br/>(fully visible)"]
|
||||
end
|
||||
subgraph "Window B (behind)"
|
||||
LB["Layer B<br/>(partially obscured)"]
|
||||
end
|
||||
subgraph "Window C (behind both)"
|
||||
LC["Layer C<br/>(mostly obscured)"]
|
||||
end
|
||||
end
|
||||
|
||||
DRAW["Draw(windowB->RPort, ...)"] --> LB
|
||||
LB -->|"ClipRects exclude<br/>obscured regions"| BM["BitMap<br/>(only visible<br/>portions drawn)"]
|
||||
|
||||
style LA fill:#c8e6c9,stroke:#2e7d32,color:#333
|
||||
style LB fill:#fff9c4,stroke:#f9a825,color:#333
|
||||
style LC fill:#ffcdd2,stroke:#c62828,color:#333
|
||||
```
|
||||
|
||||
Each layer maintains a list of **ClipRects** — rectangles defining which parts of the layer are visible. When you draw to a partially obscured window, `layers.library` breaks your drawing operation into multiple clipped sub-draws, one per visible ClipRect.
|
||||
|
||||
```c
|
||||
/* Direct layer creation (Intuition does this for windows): */
|
||||
struct Layer_Info *li = NewLayerInfo();
|
||||
struct Layer *layer = CreateUpfrontLayer(li, bm, x1, y1, x2, y2, flags, NULL);
|
||||
rp = layer->rp; /* use this RastPort for drawing */
|
||||
/* ... draw ... */
|
||||
struct Layer *layer = CreateUpfrontLayer(li, bm,
|
||||
x1, y1, x2, y2,
|
||||
LAYERSIMPLE, /* or LAYERSMART, LAYERSUPER */
|
||||
NULL);
|
||||
struct RastPort *rp = layer->rp; /* use this for drawing */
|
||||
|
||||
/* LAYERSIMPLE — no backing store; app must redraw damaged areas */
|
||||
/* LAYERSMART — automatic backing store; OS handles redraw */
|
||||
/* LAYERSUPER — super bitmap; full offscreen buffer */
|
||||
|
||||
/* Layer clipping is automatic — Draw, RectFill, Text all respect it */
|
||||
Draw(rp, 200, 100); /* clipped to visible portion of layer */
|
||||
|
||||
/* Cleanup: */
|
||||
DeleteLayer(0, layer);
|
||||
DisposeLayerInfo(li);
|
||||
```
|
||||
|
||||
### Layer Types
|
||||
|
||||
| Type | Flag | Backing Store | Damage Handling | Memory |
|
||||
|---|---|---|---|---|
|
||||
| Simple | `LAYERSIMPLE` | None | App receives `IDCMP_REFRESHWINDOW` and must redraw | Minimal |
|
||||
| Smart | `LAYERSMART` | Auto-saved obscured regions | OS restores automatically | Moderate |
|
||||
| Super | `LAYERSUPER` | Full off-screen bitmap | Full bitmap always valid | High |
|
||||
|
||||
> [!TIP]
|
||||
> **`WFLG_SIMPLE_REFRESH`** windows use the least memory but require the most application code (you must handle `IDCMP_REFRESHWINDOW`). **`WFLG_SMART_REFRESH`** is the default for most applications — Intuition saves/restores obscured regions automatically.
|
||||
|
||||
---
|
||||
|
||||
## Patterns
|
||||
|
||||
### Line Patterns
|
||||
|
||||
```c
|
||||
/* 16-bit repeating pattern for dashed lines: */
|
||||
SetDrPt(rp, 0xFF00); /* ████████░░░░░░░░ — long dash */
|
||||
SetDrPt(rp, 0xF0F0); /* ████░░░░████░░░░ — medium dash */
|
||||
SetDrPt(rp, 0xAAAA); /* █░█░█░█░█░█░█░█░ — dotted */
|
||||
SetDrPt(rp, 0xFCFC); /* ██████░░██████░░ — dash-dot */
|
||||
```
|
||||
|
||||
### Area Fill Patterns
|
||||
|
||||
```c
|
||||
/* Area patterns are powers-of-2 height, 16 bits wide: */
|
||||
UWORD checkerPattern[] = { 0x5555, 0xAAAA }; /* 2-line checkerboard */
|
||||
rp->AreaPtrn = checkerPattern;
|
||||
rp->AreaPtSz = 1; /* log2(2) = 1 */
|
||||
|
||||
/* Now RectFill uses the pattern instead of solid fill: */
|
||||
RectFill(rp, 10, 10, 100, 80);
|
||||
|
||||
/* Multiplane patterns (one set per bitplane): */
|
||||
UWORD brickPattern[] = {
|
||||
/* plane 0: */ 0xFFFF, 0x8080, 0xFFFF, 0x0808,
|
||||
/* plane 1: */ 0xFFFF, 0x8080, 0xFFFF, 0x0808
|
||||
};
|
||||
rp->AreaPtrn = brickPattern;
|
||||
rp->AreaPtSz = 2; /* log2(4 lines) = 2 */
|
||||
rp->Mask |= 0x02; /* enable plane 1 pattern */
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Plane Mask — Selective Bitplane Drawing
|
||||
|
||||
```c
|
||||
/* Mask controls which bitplanes are affected by drawing: */
|
||||
rp->Mask = 0xFF; /* all planes — default */
|
||||
rp->Mask = 0x01; /* only plane 0 — fast for single-plane effects */
|
||||
rp->Mask = 0x03; /* planes 0 and 1 only */
|
||||
|
||||
/* Use case: draw a 2-colour overlay without disturbing other planes: */
|
||||
rp->Mask = 0x04; /* only plane 2 */
|
||||
SetAPen(rp, 4); /* colour index with bit 2 set */
|
||||
RectFill(rp, 0, 0, 319, 255);
|
||||
rp->Mask = 0xFF; /* restore */
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- NDK39: `graphics/rastport.h`, `graphics/gfxmacros.h`
|
||||
- ADCD 2.1: `SetAPen`, `Move`, `Draw`, `Text`, `RectFill`, `ClipBlit`
|
||||
- See also: [bitmap.md](bitmap.md) — BitMap structure and allocation
|
||||
- See also: [layers.md](../../11_libraries/layers.md) — layers.library detailed reference
|
||||
- See also: [text_fonts.md](text_fonts.md) — font loading and rendering
|
||||
- See also: [blitter.md](blitter.md) — hardware Blitter used by BltBitMap
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue