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 | ␉␉␉}␊ |
50 | ␉␉␉char *ptr=(char *)output+x*(op/8)+y*or;␊ |
51 | ␉␉␉switch (op)␊ |
52 | ␉␉␉{␊ |
53 | ␉␉␉␉case 16:␊ |
54 | ␉␉␉␉␉*((uint16_t *)ptr) = ((red & 0xF8) << 7) | ␊ |
55 | ␉␉␉␉␉((green & 0xF8) << 2) |␊ |
56 | ␉␉␉␉␉((blue & 0xF8) >> 3);␊ |
57 | ␉␉␉␉␉break;␊ |
58 | ␉␉␉␉case 32 :␊ |
59 | ␉␉␉␉␉*((uint32_t *)ptr) = (red << 16) | (green << 8) | blue;␊ |
60 | ␉␉␉␉␉break;␊ |
61 | ␉␉␉}␊ |
62 | ␉␉}␊ |
63 | }␊ |
64 | ␊ |
65 | DECLARE_IOHIBERNATEPROGRESSALPHA␊ |
66 | ␊ |
67 | void drawPreview(void *src, uint8_t * saveunder)␊ |
68 | {␊ |
69 | ␉uint8_t * screen;␊ |
70 | ␉uint32_t rowBytes, pixelShift;␊ |
71 | ␉uint32_t x, y;␊ |
72 | ␉int32_t blob;␊ |
73 | ␉uint32_t alpha, in, color, result;␊ |
74 | ␉uint8_t * out;␊ |
75 | ␉void *uncomp;␊ |
76 | ␉int origwidth, origheight, origbpx;␊ |
77 | ␉uint32_t saveindex[kIOHibernateProgressCount] = { 0 };␊ |
78 | ␉␊ |
79 | ␉if (src && (uncomp=DecompressData(src, &origwidth, &origheight, &origbpx)))␊ |
80 | ␉{␊ |
81 | ␉␉if (!setVESAGraphicsMode(origwidth, origheight, origbpx, 0))␊ |
82 | ␉␉␉if (initGraphicsMode () != errSuccess)␊ |
83 | ␉␉␉␉return;␊ |
84 | ␉␉screen = (uint8_t *) VIDEO (baseAddr);␊ |
85 | ␉␉rowBytes = VIDEO (rowBytes);␊ |
86 | ␉␉loadImageScale (uncomp, origwidth, origheight, origbpx, screen, VIDEO(width), VIDEO(height), VIDEO(depth), VIDEO (rowBytes));␊ |
87 | ␉}␊ |
88 | ␉else␊ |
89 | ␉{␊ |
90 | ␉␉if (initGraphicsMode () != errSuccess)␊ |
91 | ␉␉␉return;␊ |
92 | ␉␉screen = (uint8_t *) VIDEO (baseAddr);␊ |
93 | ␉␉rowBytes = VIDEO (rowBytes);␊ |
94 | ␉␉// Set the screen to 75% grey.␊ |
95 | drawColorRectangle(0, 0, VIDEO(width), VIDEO(height), 0x01 /* color index */);␊ |
96 | ␉}␊ |
97 | ␉␊ |
98 | ␉␊ |
99 | ␉pixelShift = VIDEO (depth) >> 4;␊ |
100 | ␉if (pixelShift < 1) return;␊ |
101 | ␉␊ |
102 | ␉screen += ((VIDEO (width) ␊ |
103 | ␉␉␉␉- kIOHibernateProgressCount * (kIOHibernateProgressWidth + kIOHibernateProgressSpacing)) << (pixelShift - 1))␊ |
104 | ␉+ (VIDEO (height) - kIOHibernateProgressOriginY - kIOHibernateProgressHeight) * rowBytes;␊ |
105 | ␉␊ |
106 | ␉for (y = 0; y < kIOHibernateProgressHeight; y++)␊ |
107 | ␉{␊ |
108 | ␉␉out = screen + y * rowBytes;␊ |
109 | ␉␉for (blob = 0; blob < kIOHibernateProgressCount; blob++)␊ |
110 | ␉␉{␊ |
111 | ␉␉␉color = blob ? kIOHibernateProgressDarkGray : kIOHibernateProgressMidGray;␊ |
112 | ␉␉␉for (x = 0; x < kIOHibernateProgressWidth; x++)␊ |
113 | ␉␉␉{␊ |
114 | ␉␉␉␉alpha = gIOHibernateProgressAlpha[y][x];␊ |
115 | ␉␉␉␉result = color;␊ |
116 | ␉␉␉␉if (alpha)␊ |
117 | ␉␉␉␉{␊ |
118 | ␉␉␉␉␉if (0xff != alpha)␊ |
119 | ␉␉␉␉␉{␊ |
120 | ␉␉␉␉␉␉if (1 == pixelShift)␊ |
121 | ␉␉␉␉␉␉{␊ |
122 | ␉␉␉␉␉␉␉in = *((uint16_t *)out) & 0x1f;␉// 16␊ |
123 | ␉␉␉␉␉␉␉in = (in << 3) | (in >> 2);␊ |
124 | ␉␉␉␉␉␉}␊ |
125 | ␉␉␉␉␉␉else␊ |
126 | ␉␉␉␉␉␉␉in = *((uint32_t *)out) & 0xff;␉// 32␊ |
127 | ␉␉␉␉␉␉saveunder[blob * kIOHibernateProgressSaveUnderSize + saveindex[blob]++] = in;␊ |
128 | ␉␉␉␉␉␉result = ((255 - alpha) * in + alpha * result + 0xff) >> 8;␊ |
129 | ␉␉␉␉␉}␊ |
130 | ␉␉␉␉␉if (1 == pixelShift)␊ |
131 | ␉␉␉␉␉{␊ |
132 | ␉␉␉␉␉␉result >>= 3;␊ |
133 | ␉␉␉␉␉␉*((uint16_t *)out) = (result << 10) | (result << 5) | result;␉// 16␊ |
134 | ␉␉␉␉␉}␊ |
135 | ␉␉␉␉␉else␊ |
136 | ␉␉␉␉␉␉*((uint32_t *)out) = (result << 16) | (result << 8) | result;␉// 32␊ |
137 | ␉␉␉␉}␊ |
138 | ␉␉␉␉out += (1 << pixelShift);␊ |
139 | ␉␉␉}␊ |
140 | ␉␉␉out += (kIOHibernateProgressSpacing << pixelShift);␊ |
141 | ␉␉}␊ |
142 | ␉}␊ |
143 | }␊ |
144 | ␊ |
145 | void updateProgressBar(uint8_t * saveunder, int32_t firstBlob, int32_t select)␊ |
146 | {␊ |
147 | ␉uint8_t * screen;␊ |
148 | ␉uint32_t rowBytes, pixelShift;␊ |
149 | ␉uint32_t x, y;␊ |
150 | ␉int32_t blob, lastBlob;␊ |
151 | ␉uint32_t alpha, in, color, result;␊ |
152 | ␉uint8_t * out;␊ |
153 | ␉uint32_t saveindex[kIOHibernateProgressCount] = { 0 };␊ |
154 | ␉␊ |
155 | ␉pixelShift = VIDEO(depth) >> 4;␊ |
156 | ␉if (pixelShift < 1) return;␊ |
157 | ␉screen = (uint8_t *) VIDEO (baseAddr);␊ |
158 | ␉rowBytes = VIDEO (rowBytes);␊ |
159 | ␉␊ |
160 | ␉screen += ((VIDEO (width) ␊ |
161 | ␉␉␉␉- kIOHibernateProgressCount * (kIOHibernateProgressWidth + kIOHibernateProgressSpacing)) << (pixelShift - 1))␊ |
162 | ␉+ (VIDEO (height) - kIOHibernateProgressOriginY - kIOHibernateProgressHeight) * rowBytes;␊ |
163 | ␉␊ |
164 | ␉lastBlob = (select < kIOHibernateProgressCount) ? select : (kIOHibernateProgressCount - 1);␊ |
165 | ␉␊ |
166 | ␉screen += (firstBlob * (kIOHibernateProgressWidth + kIOHibernateProgressSpacing)) << pixelShift;␊ |
167 | ␉␊ |
168 | ␉for (y = 0; y < kIOHibernateProgressHeight; y++)␊ |
169 | ␉{␊ |
170 | ␉␉out = screen + y * rowBytes;␊ |
171 | ␉␉for (blob = firstBlob; blob <= lastBlob; blob++)␊ |
172 | ␉␉{␊ |
173 | ␉␉␉color = (blob < select) ? kIOHibernateProgressLightGray : kIOHibernateProgressMidGray;␊ |
174 | ␉␉␉for (x = 0; x < kIOHibernateProgressWidth; x++)␊ |
175 | ␉␉␉{␊ |
176 | ␉␉␉␉alpha = gIOHibernateProgressAlpha[y][x];␊ |
177 | ␉␉␉␉result = color;␊ |
178 | ␉␉␉␉if (alpha)␊ |
179 | ␉␉␉␉{␊ |
180 | ␉␉␉␉␉if (0xff != alpha)␊ |
181 | ␉␉␉␉␉{␊ |
182 | ␉␉␉␉␉␉in = saveunder[blob * kIOHibernateProgressSaveUnderSize + saveindex[blob]++];␊ |
183 | ␉␉␉␉␉␉result = ((255 - alpha) * in + alpha * result + 0xff) / 255;␊ |
184 | ␉␉␉␉␉}␊ |
185 | ␉␉␉␉␉if (1 == pixelShift)␊ |
186 | ␉␉␉␉␉{␊ |
187 | ␉␉␉␉␉␉result >>= 3;␊ |
188 | ␉␉␉␉␉␉*((uint16_t *)out) = (result << 10) | (result << 5) | result;␉// 16␊ |
189 | ␉␉␉␉␉}␊ |
190 | ␉␉␉␉␉else␊ |
191 | ␉␉␉␉␉␉*((uint32_t *)out) = (result << 16) | (result << 8) | result;␉// 32␊ |
192 | ␉␉␉␉}␊ |
193 | ␉␉␉␉out += (1 << pixelShift);␊ |
194 | ␉␉␉}␊ |
195 | ␉␉␉out += (kIOHibernateProgressSpacing << pixelShift);␊ |
196 | ␉␉}␊ |
197 | ␉}␊ |
198 | }␊ |
199 | ␊ |
200 | void␊ |
201 | spinActivityIndicator_hook(void *arg1, void *arg2, void *arg3, void *arg4, void* arg5, void* arg6)␊ |
202 | {␊ |
203 | ␉int sectors = *(int*)arg1;␊ |
204 | ␉bool *doreturn = (bool*)arg2;␊ |
205 | ␉␊ |
206 | ␉if (previewTotalSectors && previewSaveunder)␊ |
207 | ␉{␊ |
208 | ␉␉int blob, lastBlob;␊ |
209 | ␉␉␊ |
210 | ␉␉lastBlob = (previewLoadedSectors * kIOHibernateProgressCount) / previewTotalSectors;␊ |
211 | ␉␉previewLoadedSectors+=sectors;␊ |
212 | ␉␉blob = (previewLoadedSectors * kIOHibernateProgressCount) / previewTotalSectors;␊ |
213 | ␉␉␊ |
214 | ␉␉if (blob!=lastBlob)␊ |
215 | ␉␉␉updateProgressBar (previewSaveunder, lastBlob, blob);␊ |
216 | ␉␉*doreturn = true;␊ |
217 | ␉}␊ |
218 | } |