1 | ␊ |
2 | /* Graphic utility functions and data types␊ |
3 | * Prashant Vaibhav (C) 12/12/2008␊ |
4 | * Chameleon␊ |
5 | */␊ |
6 | ␊ |
7 | #include "graphic_utils.h"␊ |
8 | #include "graphics.h"␊ |
9 | #include "IOHibernatePrivate.h"␊ |
10 | #include "bmdecompress.h"␊ |
11 | ␊ |
12 | #define VIDEO(x) (bootArgs->Video.v_ ## x)␊ |
13 | ␊ |
14 | //#define MIN(x, y) ((x) < (y) ? (x) : (y))␊ |
15 | ␊ |
16 | int previewTotalSectors = 0;␊ |
17 | uint8_t *previewSaveunder = 0;␊ |
18 | int previewLoadedSectors = 0;␊ |
19 | ␊ |
20 | void␊ |
21 | loadImageScale (void *input, int iw, int ih, int ip, void *output, int ow, int oh, int op, int or)␊ |
22 | {␊ |
23 | ␉int x,y, off;␊ |
24 | ␉int red=0x7f, green=0x7f, blue=0x7f;␊ |
25 | ␉for (x=0;x<ow;x++)␊ |
26 | ␉␉for (y=0;y<oh;y++)␊ |
27 | ␉␉{␊ |
28 | ␉␉␉off=(x*iw)/ow+((y*ih)/oh)*iw;␊ |
29 | ␉␉␉switch (ip)␊ |
30 | ␉␉␉{␊ |
31 | ␉␉␉␉case 16:␊ |
32 | ␉␉␉␉{␊ |
33 | ␉␉␉␉␉uint16_t val;␊ |
34 | ␉␉␉␉␉val=((uint16_t *)input)[off];␊ |
35 | ␉␉␉␉␉red=(val>>7)&0xf8;␊ |
36 | ␉␉␉␉␉green=(val>>2)&0xf8;␊ |
37 | ␉␉␉␉␉blue=(val<<3)&0xf8;␊ |
38 | ␉␉␉␉␉break;␉␉␊ |
39 | ␉␉␉␉}␊ |
40 | ␉␉␉␉case 32:␊ |
41 | ␉␉␉␉{␊ |
42 | ␉␉␉␉␉uint32_t val;␊ |
43 | ␉␉␉␉␉val=((uint32_t *)input)[off];␊ |
44 | ␉␉␉␉␉red=(val>>16)&0xff;␊ |
45 | ␉␉␉␉␉green=(val>>8)&0xff;␊ |
46 | ␉␉␉␉␉blue=(val)&0xff;␊ |
47 | ␉␉␉␉␉break;␊ |
48 | ␉␉␉␉}␊ |
49 | ␉␉␉␉default:␊ |
50 | ␉␉␉␉␉break;␊ |
51 | ␉␉␉}␊ |
52 | ␉␉␉char *ptr=(char *)output+x*(op/8)+y*or;␊ |
53 | ␉␉␉switch (op)␊ |
54 | ␉␉␉{␊ |
55 | ␉␉␉␉case 16:␊ |
56 | ␉␉␉␉␉*((uint16_t *)ptr) = ((red & 0xF8) << 7) | ␊ |
57 | ␉␉␉␉␉((green & 0xF8) << 2) |␊ |
58 | ␉␉␉␉␉((blue & 0xF8) >> 3);␊ |
59 | ␉␉␉␉␉break;␊ |
60 | ␉␉␉␉case 32 :␊ |
61 | ␉␉␉␉␉*((uint32_t *)ptr) = (red << 16) | (green << 8) | blue;␊ |
62 | ␉␉␉␉␉break;␊ |
63 | ␉␉␉␉default:␊ |
64 | ␉␉␉␉␉break;␊ |
65 | ␉␉␉}␊ |
66 | ␉␉}␊ |
67 | }␊ |
68 | ␊ |
69 | DECLARE_IOHIBERNATEPROGRESSALPHA␊ |
70 | ␊ |
71 | void drawPreview(void *src, uint8_t * saveunder)␊ |
72 | {␊ |
73 | ␉uint8_t * screen;␊ |
74 | ␉uint32_t rowBytes, pixelShift;␊ |
75 | ␉uint32_t x, y;␊ |
76 | ␉int32_t blob;␊ |
77 | ␉uint32_t alpha, in, color, result;␊ |
78 | ␉uint8_t * out;␊ |
79 | ␉void *uncomp;␊ |
80 | ␉int origwidth, origheight, origbpx;␊ |
81 | ␉uint32_t saveindex[kIOHibernateProgressCount] = { 0 };␊ |
82 | ␉␊ |
83 | ␉if (src && (uncomp=DecompressData(src, &origwidth, &origheight, &origbpx)))␊ |
84 | ␉{␊ |
85 | #if UNUSED␊ |
86 | ␉␉if (!setVESAGraphicsMode(origwidth, origheight, origbpx, 0))␊ |
87 | #else␊ |
88 | ␉␉if (!setVESAGraphicsMode(origwidth, origheight, origbpx))␊ |
89 | #endif␊ |
90 | ␉␉␉if (initGraphicsMode () != errSuccess)␊ |
91 | ␉␉␉␉return;␊ |
92 | ␉␉screen = (uint8_t *) VIDEO (baseAddr);␊ |
93 | ␉␉rowBytes = VIDEO (rowBytes);␊ |
94 | ␉␉loadImageScale (uncomp, origwidth, origheight, origbpx, screen, VIDEO(width), VIDEO(height), VIDEO(depth), VIDEO (rowBytes));␊ |
95 | ␉}␊ |
96 | ␉else␊ |
97 | ␉{␊ |
98 | ␉␉if (initGraphicsMode () != errSuccess)␊ |
99 | ␉␉␉return;␊ |
100 | ␉␉screen = (uint8_t *) VIDEO (baseAddr);␊ |
101 | ␉␉rowBytes = VIDEO (rowBytes);␊ |
102 | ␉␉// Set the screen to 75% grey.␊ |
103 | drawColorRectangle(0, 0, VIDEO(width), VIDEO(height), 0x01 /* color index */);␊ |
104 | ␉}␊ |
105 | ␉␊ |
106 | ␉␊ |
107 | ␉pixelShift = VIDEO (depth) >> 4;␊ |
108 | ␉if (pixelShift < 1) return;␊ |
109 | ␉␊ |
110 | ␉screen += ((VIDEO (width) ␊ |
111 | ␉␉␉␉- kIOHibernateProgressCount * (kIOHibernateProgressWidth + kIOHibernateProgressSpacing)) << (pixelShift - 1))␊ |
112 | ␉+ (VIDEO (height) - kIOHibernateProgressOriginY - kIOHibernateProgressHeight) * rowBytes;␊ |
113 | ␉␊ |
114 | ␉for (y = 0; y < kIOHibernateProgressHeight; y++)␊ |
115 | ␉{␊ |
116 | ␉␉out = screen + y * rowBytes;␊ |
117 | ␉␉for (blob = 0; blob < kIOHibernateProgressCount; blob++)␊ |
118 | ␉␉{␊ |
119 | ␉␉␉color = blob ? kIOHibernateProgressDarkGray : kIOHibernateProgressMidGray;␊ |
120 | ␉␉␉for (x = 0; x < kIOHibernateProgressWidth; x++)␊ |
121 | ␉␉␉{␊ |
122 | ␉␉␉␉alpha = gIOHibernateProgressAlpha[y][x];␊ |
123 | ␉␉␉␉result = color;␊ |
124 | ␉␉␉␉if (alpha)␊ |
125 | ␉␉␉␉{␊ |
126 | ␉␉␉␉␉if (0xff != alpha)␊ |
127 | ␉␉␉␉␉{␊ |
128 | ␉␉␉␉␉␉if (1 == pixelShift)␊ |
129 | ␉␉␉␉␉␉{␊ |
130 | ␉␉␉␉␉␉␉in = *((uint16_t *)out) & 0x1f;␉// 16␊ |
131 | ␉␉␉␉␉␉␉in = (in << 3) | (in >> 2);␊ |
132 | ␉␉␉␉␉␉}␊ |
133 | ␉␉␉␉␉␉else␊ |
134 | ␉␉␉␉␉␉␉in = *((uint32_t *)out) & 0xff;␉// 32␊ |
135 | ␉␉␉␉␉␉saveunder[blob * kIOHibernateProgressSaveUnderSize + saveindex[blob]++] = in;␊ |
136 | ␉␉␉␉␉␉result = ((255 - alpha) * in + alpha * result + 0xff) >> 8;␊ |
137 | ␉␉␉␉␉}␊ |
138 | ␉␉␉␉␉if (1 == pixelShift)␊ |
139 | ␉␉␉␉␉{␊ |
140 | ␉␉␉␉␉␉result >>= 3;␊ |
141 | ␉␉␉␉␉␉*((uint16_t *)out) = (result << 10) | (result << 5) | result;␉// 16␊ |
142 | ␉␉␉␉␉}␊ |
143 | ␉␉␉␉␉else␊ |
144 | ␉␉␉␉␉␉*((uint32_t *)out) = (result << 16) | (result << 8) | result;␉// 32␊ |
145 | ␉␉␉␉}␊ |
146 | ␉␉␉␉out += (1 << pixelShift);␊ |
147 | ␉␉␉}␊ |
148 | ␉␉␉out += (kIOHibernateProgressSpacing << pixelShift);␊ |
149 | ␉␉}␊ |
150 | ␉}␊ |
151 | }␊ |
152 | ␊ |
153 | void updateProgressBar(uint8_t * saveunder, int32_t firstBlob, int32_t select)␊ |
154 | {␊ |
155 | ␉uint8_t * screen;␊ |
156 | ␉uint32_t rowBytes, pixelShift;␊ |
157 | ␉uint32_t x, y;␊ |
158 | ␉int32_t blob, lastBlob;␊ |
159 | ␉uint32_t alpha, in, color, result;␊ |
160 | ␉uint8_t * out;␊ |
161 | ␉uint32_t saveindex[kIOHibernateProgressCount] = { 0 };␊ |
162 | ␉␊ |
163 | ␉pixelShift = VIDEO(depth) >> 4;␊ |
164 | ␉if (pixelShift < 1) return;␊ |
165 | ␉screen = (uint8_t *) VIDEO (baseAddr);␊ |
166 | ␉rowBytes = VIDEO (rowBytes);␊ |
167 | ␉␊ |
168 | ␉screen += ((VIDEO (width) ␊ |
169 | ␉␉␉␉- kIOHibernateProgressCount * (kIOHibernateProgressWidth + kIOHibernateProgressSpacing)) << (pixelShift - 1))␊ |
170 | ␉+ (VIDEO (height) - kIOHibernateProgressOriginY - kIOHibernateProgressHeight) * rowBytes;␊ |
171 | ␉␊ |
172 | ␉lastBlob = (select < kIOHibernateProgressCount) ? select : (kIOHibernateProgressCount - 1);␊ |
173 | ␉␊ |
174 | ␉screen += (firstBlob * (kIOHibernateProgressWidth + kIOHibernateProgressSpacing)) << pixelShift;␊ |
175 | ␉␊ |
176 | ␉for (y = 0; y < kIOHibernateProgressHeight; y++)␊ |
177 | ␉{␊ |
178 | ␉␉out = screen + y * rowBytes;␊ |
179 | ␉␉for (blob = firstBlob; blob <= lastBlob; blob++)␊ |
180 | ␉␉{␊ |
181 | ␉␉␉color = (blob < select) ? kIOHibernateProgressLightGray : kIOHibernateProgressMidGray;␊ |
182 | ␉␉␉for (x = 0; x < kIOHibernateProgressWidth; x++)␊ |
183 | ␉␉␉{␊ |
184 | ␉␉␉␉alpha = gIOHibernateProgressAlpha[y][x];␊ |
185 | ␉␉␉␉result = color;␊ |
186 | ␉␉␉␉if (alpha)␊ |
187 | ␉␉␉␉{␊ |
188 | ␉␉␉␉␉if (0xff != alpha)␊ |
189 | ␉␉␉␉␉{␊ |
190 | ␉␉␉␉␉␉in = saveunder[blob * kIOHibernateProgressSaveUnderSize + saveindex[blob]++];␊ |
191 | ␉␉␉␉␉␉result = ((255 - alpha) * in + alpha * result + 0xff) / 255;␊ |
192 | ␉␉␉␉␉}␊ |
193 | ␉␉␉␉␉if (1 == pixelShift)␊ |
194 | ␉␉␉␉␉{␊ |
195 | ␉␉␉␉␉␉result >>= 3;␊ |
196 | ␉␉␉␉␉␉*((uint16_t *)out) = (result << 10) | (result << 5) | result;␉// 16␊ |
197 | ␉␉␉␉␉}␊ |
198 | ␉␉␉␉␉else␊ |
199 | ␉␉␉␉␉␉*((uint32_t *)out) = (result << 16) | (result << 8) | result;␉// 32␊ |
200 | ␉␉␉␉}␊ |
201 | ␉␉␉␉out += (1 << pixelShift);␊ |
202 | ␉␉␉}␊ |
203 | ␉␉␉out += (kIOHibernateProgressSpacing << pixelShift);␊ |
204 | ␉␉}␊ |
205 | ␉}␊ |
206 | }␊ |
207 | ␊ |
208 | void␊ |
209 | spinActivityIndicator_hook(void *arg1, void *arg2, void *arg3, void *arg4, void* arg5, void* arg6)␊ |
210 | {␊ |
211 | ␉int sectors = *(int*)arg1;␊ |
212 | ␉bool *doreturn = (bool*)arg2;␊ |
213 | ␉␊ |
214 | ␉if (previewTotalSectors && previewSaveunder)␊ |
215 | ␉{␊ |
216 | ␉␉int blob, lastBlob;␊ |
217 | ␉␉␊ |
218 | ␉␉lastBlob = (previewLoadedSectors * kIOHibernateProgressCount) / previewTotalSectors;␊ |
219 | ␉␉previewLoadedSectors+=sectors;␊ |
220 | ␉␉blob = (previewLoadedSectors * kIOHibernateProgressCount) / previewTotalSectors;␊ |
221 | ␉␉␊ |
222 | ␉␉if (blob!=lastBlob)␊ |
223 | ␉␉␉updateProgressBar (previewSaveunder, lastBlob, blob);␊ |
224 | ␉␉*doreturn = true;␊ |
225 | ␉}␊ |
226 | } |