Less sloppy handling of IoErr().
[AROS.git] / rom / intuition / shutdownscreen.c
blobeb8d6263ece544e0b9e41312e7f00215abadbe80
1 /*
2 Copyright © 1995-2013, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <exec/libraries.h>
7 #include <graphics/gfxbase.h>
8 #include <graphics/modeid.h>
10 #include <proto/exec.h>
11 #include <proto/graphics.h>
12 #include <proto/intuition.h>
14 #include "intuition_intern.h"
15 #include "monitorclass_private.h"
16 #include "shutdown_image.h"
18 static VOID ShowShutdownScreen();
19 static struct Screen *OpenFinalScreen(BYTE MinDepth, BOOL squarePixels,
20 struct IntuitionBase *IntuitionBase);
21 static VOID ShowPic(struct Screen *scr, struct IntuitionBase *IntuitionBase);
22 static const UBYTE *UnpackByterun(const UBYTE * source, UBYTE * dest,
23 LONG unpackedsize);
25 static const UWORD empty_pointer[1] = { 0 };
27 /* This reset handler is called if software power-off or reboot has not
28 * occurred */
29 AROS_INTH1(ShutdownScreenHandler, struct Interrupt *, handler)
31 AROS_INTFUNC_INIT
33 ShowShutdownScreen();
35 return FALSE;
37 AROS_INTFUNC_EXIT
40 static VOID ShowShutdownScreen()
42 struct IntuitionBase *IntuitionBase =
43 (void *)TaggedOpenLibrary(TAGGEDOPEN_INTUITION);
45 struct Screen *scr = OpenFinalScreen(4, TRUE, IntuitionBase);
47 if (scr != NULL)
48 ShowPic(scr, IntuitionBase);
50 return;
53 static struct Screen *OpenFinalScreen(BYTE MinDepth, BOOL squarePixels,
54 struct IntuitionBase *IntuitionBase)
56 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
57 UWORD height;
58 ULONG mode;
59 struct Screen *scr = NULL;
60 Object *pointer;
61 struct SharedPointer *shared_pointer;
63 height = 480;
64 mode = BestModeID(BIDTAG_DesiredWidth, 640, BIDTAG_DesiredHeight, height,
65 BIDTAG_Depth, MinDepth, TAG_DONE);
66 if (mode == INVALID_ID)
67 Alert(AN_SysScrnType);
69 /* Set PAL or NTSC default height if we are running on Amiga(tm) hardware.
70 * We also need to check if this is really PAL or NTSC mode because we
71 * have to use PC 640x480 mode if user has Amiga hardware + RTG board.
72 * Check DisplayFlags first because non-Amiga mode IDs use different format.
74 if (GfxBase->DisplayFlags & (NTSC | PAL))
76 if ((mode & MONITOR_ID_MASK) == NTSC_MONITOR_ID)
77 height = squarePixels ? 400 : 200;
78 else if ((mode & MONITOR_ID_MASK) == PAL_MONITOR_ID)
79 height = squarePixels ? 512 : 256;
82 /* We want the screen to occupy the whole display, so we find the best
83 matching mode ID and then open a screen with that mode */
84 mode = BestModeID(BIDTAG_DesiredWidth, 640, BIDTAG_DesiredHeight, height,
85 BIDTAG_Depth, MinDepth, TAG_DONE);
87 if (mode != INVALID_ID)
89 scr = OpenScreenTags(NULL, SA_DisplayID, mode, SA_Draggable, FALSE,
90 SA_Quiet, TRUE, SA_Depth, MinDepth, TAG_DONE);
92 /* Hide mouse pointer */
93 if (scr)
95 pointer = MakePointerFromData(IntuitionBase, empty_pointer,
96 0, 0, 1, 1);
97 GetAttr(POINTERA_SharedPointer, pointer,
98 (IPTR *) & shared_pointer);
99 DoMethod(GetPrivScreen(scr)->IMonitorNode, MM_SetPointerShape,
100 shared_pointer);
104 return scr;
107 static VOID ShowPic(struct Screen *scr, struct IntuitionBase *IntuitionBase)
109 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
110 UBYTE *picture;
111 UWORD x, y;
113 if ((scr->Width >= SHUTDOWN_WIDTH) && (scr->Height >= SHUTDOWN_HEIGHT)
114 && (scr->RastPort.BitMap->Depth >= SHUTDOWN_PLANES))
116 ULONG size = SHUTDOWN_WIDTH * SHUTDOWN_HEIGHT;
118 picture = AllocVec(size, MEMF_ANY);
120 if (picture != NULL)
122 ULONG i;
124 UnpackByterun(shutdown_data, picture, size);
126 for (i = 0; i < SHUTDOWN_COLORS; i++)
127 SetRGB32(&scr->ViewPort, i,
128 (shutdown_pal[i] << 8) & 0xFF000000,
129 (shutdown_pal[i] << 16) & 0xFF000000,
130 (shutdown_pal[i] << 24) & 0xFF000000);
132 SetAPen(&scr->RastPort, 0);
133 RectFill(&scr->RastPort, 0, 0, scr->Width, scr->Height);
135 x = (scr->Width - SHUTDOWN_WIDTH) >> 1;
136 y = (scr->Height - SHUTDOWN_HEIGHT) >> 1;
137 WriteChunkyPixels(&scr->RastPort, x, y,
138 x + SHUTDOWN_WIDTH - 1, y + SHUTDOWN_HEIGHT - 1,
139 picture, SHUTDOWN_WIDTH);
141 return;
144 return;
147 static const UBYTE *UnpackByterun(const UBYTE * source, UBYTE * dest,
148 LONG unpackedsize)
150 UBYTE r;
151 BYTE c;
153 for (;;)
155 c = (BYTE) (*source++);
156 if (c >= 0)
158 while (c-- >= 0)
160 *dest++ = *source++;
161 if (--unpackedsize <= 0)
162 return source;
165 else if (c != -128)
167 c = -c;
168 r = *source++;
170 while (c-- >= 0)
172 *dest++ = r;
173 if (--unpackedsize <= 0)
174 return source;