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