Enable VFP unit as early as possible. This has to be so since e.g. gcc9 uses vfp...
[AROS.git] / rom / intuition / shutdownscreen.c
blobbf5abf880cbfe45c766189b2f05e192d6841c08b
1 /*
2 Copyright © 1995-2018, 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 /* Reset to default decorator. The one installed by C:Decoration may try
88 * to load images from disk while opening the screen, which isn't a good
89 * idea when the system is partly shut down */
90 GetPrivIBase(IntuitionBase)->Decorator = NULL;
91 GetPrivIBase(IntuitionBase)->ScrDecorClass = FindClass(SCRDECORCLASS);
92 GetPrivIBase(IntuitionBase)->ScrDecorTags = NULL;
93 GetPrivIBase(IntuitionBase)->MenuDecorClass = FindClass(MENUDECORCLASS);
94 GetPrivIBase(IntuitionBase)->MenuDecorTags = NULL;
95 GetPrivIBase(IntuitionBase)->WinDecorClass = FindClass(WINDECORCLASS);
96 GetPrivIBase(IntuitionBase)->WinDecorTags = NULL;
98 if (mode != INVALID_ID)
100 scr = OpenScreenTags(NULL, SA_DisplayID, mode, SA_Draggable, FALSE,
101 SA_Quiet, TRUE, SA_Depth, MinDepth, TAG_DONE);
103 /* Hide mouse pointer */
104 if (scr)
106 pointer = MakePointerFromData(IntuitionBase, empty_pointer,
107 0, 0, 1, 1);
108 GetAttr(POINTERA_SharedPointer, pointer,
109 (IPTR *) & shared_pointer);
110 DoMethod(GetPrivScreen(scr)->IMonitorNode, MM_SetPointerShape,
111 shared_pointer);
115 return scr;
118 static VOID ShowPic(struct Screen *scr, struct IntuitionBase *IntuitionBase)
120 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
121 UBYTE *picture;
122 UWORD x, y;
124 if ((scr->Width >= SHUTDOWN_WIDTH) && (scr->Height >= SHUTDOWN_HEIGHT)
125 && (scr->RastPort.BitMap->Depth >= SHUTDOWN_PLANES))
127 ULONG size = SHUTDOWN_WIDTH * SHUTDOWN_HEIGHT;
129 picture = AllocVec(size, MEMF_ANY);
131 if (picture != NULL)
133 ULONG i;
135 UnpackByterun(shutdown_data, picture, size);
137 for (i = 0; i < SHUTDOWN_COLORS; i++)
138 SetRGB32(&scr->ViewPort, i,
139 (shutdown_pal[i] << 8) & 0xFF000000,
140 (shutdown_pal[i] << 16) & 0xFF000000,
141 (shutdown_pal[i] << 24) & 0xFF000000);
143 SetAPen(&scr->RastPort, 0);
144 RectFill(&scr->RastPort, 0, 0, scr->Width, scr->Height);
146 x = (scr->Width - SHUTDOWN_WIDTH) >> 1;
147 y = (scr->Height - SHUTDOWN_HEIGHT) >> 1;
148 WriteChunkyPixels(&scr->RastPort, x, y,
149 x + SHUTDOWN_WIDTH - 1, y + SHUTDOWN_HEIGHT - 1,
150 picture, SHUTDOWN_WIDTH);
152 return;
155 return;
158 static const UBYTE *UnpackByterun(const UBYTE * source, UBYTE * dest,
159 LONG unpackedsize)
161 UBYTE r;
162 BYTE c;
164 for (;;)
166 c = (BYTE) (*source++);
167 if (c >= 0)
169 while (c-- >= 0)
171 *dest++ = *source++;
172 if (--unpackedsize <= 0)
173 return source;
176 else if (c != -128)
178 c = -c;
179 r = *source++;
181 while (c-- >= 0)
183 *dest++ = r;
184 if (--unpackedsize <= 0)
185 return source;