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 35static struct frame_buffer_boot_info *sInfo; 36static uint8 *sUncompressedIcons; 37 38 39static void 40blit8_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 63static void 64blit15_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 91static void 92blit16_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 118static void 119blit24_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 144static void 145blit32_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 168static void 169blit_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 201void 202boot_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 216void 217boot_splash_uninit(void) 218{ 219 sInfo = NULL; 220} 221 222 223void 224boot_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