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