1 /* 2 * Copyright 2008-2010, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Artur Wyszynski <harakash@gmail.com> 7 */ 8 9 10 #include <stdio.h> 11 #include <stdlib.h> 12 #include <string.h> 13 #include <unistd.h> 14 15 #include <KernelExport.h> 16 17 #define __BOOTSPLASH_KERNEL__ 18 #ifdef HAIKU_DISTRO_COMPATIBILITY_OFFICIAL 19 #include <boot/images.h> 20 #else 21 #include <boot/images-sans-tm.h> 22 #endif 23 24 25 #include <boot_item.h> 26 #include <debug.h> 27 #include <frame_buffer_console.h> 28 29 #include <boot_splash.h> 30 31 32 //#define TRACE_BOOT_SPLASH 1 33 #ifdef TRACE_BOOT_SPLASH 34 # define TRACE(x...) dprintf(x); 35 #else 36 # define TRACE(x...) ; 37 #endif 38 39 40 static struct frame_buffer_boot_info *sInfo; 41 static uint8 *sUncompressedIcons; 42 43 44 static void 45 blit8_cropped(const uint8 *data, uint16 imageLeft, uint16 imageTop, 46 uint16 imageRight, uint16 imageBottom, uint16 imageWidth, 47 uint16 left, uint16 top) 48 { 49 data += (imageWidth * imageTop + imageLeft); 50 uint8* start = (uint8*)(sInfo->frame_buffer 51 + sInfo->bytes_per_row * (top + imageTop) + 1 * (left + imageLeft)); 52 53 for (int32 y = imageTop; y < imageBottom; y++) { 54 const uint8* src = data; 55 uint8* dst = start; 56 for (int32 x = imageLeft; x < imageRight; x++) { 57 dst[0] = src[0]; 58 dst++; 59 src++; 60 } 61 62 data += imageWidth; 63 start = (uint8*)((addr_t)start + sInfo->bytes_per_row); 64 } 65 } 66 67 68 static void 69 blit15_cropped(const uint8 *data, uint16 imageLeft, uint16 imageTop, 70 uint16 imageRight, uint16 imageBottom, uint16 imageWidth, 71 uint16 left, uint16 top) 72 { 73 data += (imageWidth * imageTop + imageLeft) * 3; 74 uint16* start = (uint16*)(sInfo->frame_buffer 75 + sInfo->bytes_per_row * (top + imageTop) 76 + 2 * (left + imageLeft)); 77 78 for (int32 y = imageTop; y < imageBottom; y++) { 79 const uint8* src = data; 80 uint16* dst = start; 81 for (int32 x = imageLeft; x < imageRight; x++) { 82 dst[0] = ((src[2] >> 3) << 10) 83 | ((src[1] >> 3) << 5) 84 | ((src[0] >> 3)); 85 86 dst++; 87 src += 3; 88 } 89 90 data += imageWidth * 3; 91 start = (uint16*)((addr_t)start + sInfo->bytes_per_row); 92 } 93 } 94 95 96 static void 97 blit16_cropped(const uint8 *data, uint16 imageLeft, uint16 imageTop, 98 uint16 imageRight, uint16 imageBottom, uint16 imageWidth, 99 uint16 left, uint16 top) 100 { 101 data += (imageWidth * imageTop + imageLeft) * 3; 102 uint16* start = (uint16*)(sInfo->frame_buffer 103 + sInfo->bytes_per_row * (top + imageTop) + 2 * (left + imageLeft)); 104 105 for (int32 y = imageTop; y < imageBottom; y++) { 106 const uint8* src = data; 107 uint16* dst = start; 108 for (int32 x = imageLeft; x < imageRight; x++) { 109 dst[0] = ((src[2] >> 3) << 11) 110 | ((src[1] >> 2) << 5) 111 | ((src[0] >> 3)); 112 113 dst++; 114 src += 3; 115 } 116 117 data += imageWidth * 3; 118 start = (uint16*)((addr_t)start + sInfo->bytes_per_row); 119 } 120 } 121 122 123 static void 124 blit24_cropped(const uint8 *data, uint16 imageLeft, uint16 imageTop, 125 uint16 imageRight, uint16 imageBottom, uint16 imageWidth, 126 uint16 left, uint16 top) 127 { 128 data += (imageWidth * imageTop + imageLeft) * 3; 129 uint8* start = (uint8*)(sInfo->frame_buffer 130 + sInfo->bytes_per_row * (top + imageTop) + 3 * (left + imageLeft)); 131 132 for (int32 y = imageTop; y < imageBottom; y++) { 133 const uint8* src = data; 134 uint8* dst = start; 135 for (int32 x = imageLeft; x < imageRight; x++) { 136 dst[0] = src[0]; 137 dst[1] = src[1]; 138 dst[2] = src[2]; 139 dst += 3; 140 src += 3; 141 } 142 143 data += imageWidth * 3; 144 start = (uint8*)((addr_t)start + sInfo->bytes_per_row); 145 } 146 } 147 148 149 static void 150 blit32_cropped(const uint8 *data, uint16 imageLeft, uint16 imageTop, 151 uint16 imageRight, uint16 imageBottom, uint16 imageWidth, 152 uint16 left, uint16 top) 153 { 154 data += (imageWidth * imageTop + imageLeft) * 3; 155 uint32* start = (uint32*)(sInfo->frame_buffer 156 + sInfo->bytes_per_row * (top + imageTop) + 4 * (left + imageLeft)); 157 158 for (int32 y = imageTop; y < imageBottom; y++) { 159 const uint8* src = data; 160 uint32* dst = start; 161 for (int32 x = imageLeft; x < imageRight; x++) { 162 dst[0] = (src[2] << 16) | (src[1] << 8) | (src[0]); 163 dst++; 164 src += 3; 165 } 166 167 data += imageWidth * 3; 168 start = (uint32*)((addr_t)start + sInfo->bytes_per_row); 169 } 170 } 171 172 173 static void 174 blit_cropped(const uint8* data, uint16 imageLeft, uint16 imageTop, 175 uint16 imageRight, uint16 imageBottom, uint16 imageWidth, 176 uint16 left, uint16 top) 177 { 178 switch (sInfo->depth) { 179 case 8: 180 blit8_cropped(data, imageLeft, imageTop, imageRight, imageBottom, 181 imageWidth, left, top); 182 return; 183 case 15: 184 blit15_cropped(data, imageLeft, imageTop, imageRight, imageBottom, 185 imageWidth, left, top); 186 return; 187 case 16: 188 blit16_cropped(data, imageLeft, imageTop, imageRight, imageBottom, 189 imageWidth, left, top); 190 return; 191 case 24: 192 blit24_cropped(data, imageLeft, imageTop, imageRight, imageBottom, 193 imageWidth, left, top); 194 return; 195 case 32: 196 blit32_cropped(data, imageLeft, imageTop, imageRight, imageBottom, 197 imageWidth, left, top); 198 return; 199 } 200 } 201 202 203 // #pragma mark - exported functions 204 205 206 void 207 boot_splash_init(uint8 *bootSplash) 208 { 209 TRACE("boot_splash_init: enter\n"); 210 211 if (debug_screen_output_enabled()) 212 return; 213 214 sInfo = (frame_buffer_boot_info *)get_boot_item(FRAME_BUFFER_BOOT_INFO, 215 NULL); 216 217 sUncompressedIcons = bootSplash; 218 } 219 220 221 void 222 boot_splash_uninit(void) 223 { 224 sInfo = NULL; 225 } 226 227 228 void 229 boot_splash_set_stage(int stage) 230 { 231 TRACE("boot_splash_set_stage: stage=%d\n", stage); 232 233 if (sInfo == NULL || stage < 0 || stage >= BOOT_SPLASH_STAGE_MAX) 234 return; 235 236 int iconsHalfHeight = kSplashIconsHeight / 2; 237 int width = min_c(kSplashIconsWidth, sInfo->width); 238 int height = min_c(kSplashLogoHeight + iconsHalfHeight, sInfo->height); 239 int placementX = max_c(0, min_c(100, kSplashIconsPlacementX)); 240 int placementY = max_c(0, min_c(100, kSplashIconsPlacementY)); 241 242 int x = (sInfo->width - width) * placementX / 100; 243 int y = kSplashLogoHeight + (sInfo->height - height) * placementY / 100; 244 245 int stageLeftEdge = width * stage / BOOT_SPLASH_STAGE_MAX; 246 int stageRightEdge = width * (stage + 1) / BOOT_SPLASH_STAGE_MAX; 247 248 height = min_c(iconsHalfHeight, sInfo->height); 249 blit_cropped(sUncompressedIcons, stageLeftEdge, 0, stageRightEdge, 250 height, kSplashIconsWidth, x, y); 251 } 252 253