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