xref: /haiku/src/system/boot/platform/generic/video_splash.cpp (revision 477d2636d8cca2b859d6a17d6621909d5c87b911)
17db9fbfeSFrançois Revol /*
27db9fbfeSFrançois Revol  * Copyright 2004-2009, Axel Dörfler, axeld@pinc-software.de.
37db9fbfeSFrançois Revol  * Copyright 2008, Stephan Aßmus <superstippi@gmx.de>
47db9fbfeSFrançois Revol  * Copyright 2008, Philippe Saint-Pierre <stpere@gmail.com>
57db9fbfeSFrançois Revol  * Distributed under the terms of the MIT License.
67db9fbfeSFrançois Revol  */
77db9fbfeSFrançois Revol 
87db9fbfeSFrançois Revol 
97db9fbfeSFrançois Revol #include "video.h"
107db9fbfeSFrançois Revol #include "mmu.h"
117db9fbfeSFrançois Revol 
127db9fbfeSFrançois Revol #include <arch/cpu.h>
137db9fbfeSFrançois Revol #include <boot/stage2.h>
147db9fbfeSFrançois Revol #include <boot/platform.h>
157db9fbfeSFrançois Revol #include <boot/menu.h>
167db9fbfeSFrançois Revol #include <boot/kernel_args.h>
177db9fbfeSFrançois Revol #include <boot/images.h>
187db9fbfeSFrançois Revol #include <boot/platform/generic/video.h>
197db9fbfeSFrançois Revol 
207db9fbfeSFrançois Revol #include <stdio.h>
217db9fbfeSFrançois Revol #include <stdlib.h>
227db9fbfeSFrançois Revol #include <string.h>
237db9fbfeSFrançois Revol 
247db9fbfeSFrançois Revol 
257db9fbfeSFrançois Revol //#define TRACE_VIDEO
267db9fbfeSFrançois Revol #ifdef TRACE_VIDEO
277db9fbfeSFrançois Revol #	define TRACE(x) dprintf x
287db9fbfeSFrançois Revol #else
297db9fbfeSFrançois Revol #	define TRACE(x) ;
307db9fbfeSFrançois Revol #endif
317db9fbfeSFrançois Revol 
327db9fbfeSFrançois Revol 
337db9fbfeSFrançois Revol extern "C" status_t
347db9fbfeSFrançois Revol video_display_splash(addr_t frameBuffer)
357db9fbfeSFrançois Revol {
367db9fbfeSFrançois Revol 	if (!gKernelArgs.frame_buffer.enabled)
377db9fbfeSFrançois Revol 		return B_NO_INIT;
387db9fbfeSFrançois Revol 
397db9fbfeSFrançois Revol 	// clear the video memory
407db9fbfeSFrançois Revol 	memset((void *)frameBuffer, 0,
417db9fbfeSFrançois Revol 		gKernelArgs.frame_buffer.physical_buffer.size);
427db9fbfeSFrançois Revol 
437db9fbfeSFrançois Revol 	uint8 *uncompressedLogo = NULL;
447db9fbfeSFrançois Revol 	switch (gKernelArgs.frame_buffer.depth) {
457db9fbfeSFrançois Revol 		case 8:
467db9fbfeSFrançois Revol 			platform_set_palette(k8BitPalette);
477db9fbfeSFrançois Revol 			uncompressedLogo = (uint8 *)kernel_args_malloc(kSplashLogoWidth
487db9fbfeSFrançois Revol 				* kSplashLogoHeight);
497db9fbfeSFrançois Revol 			if (uncompressedLogo == NULL)
507db9fbfeSFrançois Revol 				return B_NO_MEMORY;
517db9fbfeSFrançois Revol 			uncompress_8bit_RLE(kSplashLogo8BitCompressedImage,
527db9fbfeSFrançois Revol 				uncompressedLogo);
537db9fbfeSFrançois Revol 		break;
547db9fbfeSFrançois Revol 		default:
557db9fbfeSFrançois Revol 			uncompressedLogo = (uint8 *)kernel_args_malloc(kSplashLogoWidth
567db9fbfeSFrançois Revol 				* kSplashLogoHeight * 3);
577db9fbfeSFrançois Revol 			if (uncompressedLogo == NULL)
587db9fbfeSFrançois Revol 				return B_NO_MEMORY;
597db9fbfeSFrançois Revol 			uncompress_24bit_RLE(kSplashLogo24BitCompressedImage,
607db9fbfeSFrançois Revol 				uncompressedLogo);
617db9fbfeSFrançois Revol 		break;
627db9fbfeSFrançois Revol 	}
637db9fbfeSFrançois Revol 
647db9fbfeSFrançois Revol 	// TODO: support 4-bit indexed version of the images!
657db9fbfeSFrançois Revol 
667db9fbfeSFrançois Revol 	// render splash logo
677db9fbfeSFrançois Revol 	uint16 iconsHalfHeight = kSplashIconsHeight / 2;
687db9fbfeSFrançois Revol 
697db9fbfeSFrançois Revol 	int width = min_c(kSplashLogoWidth, gKernelArgs.frame_buffer.width);
707db9fbfeSFrançois Revol 	int height = min_c(kSplashLogoHeight + iconsHalfHeight,
717db9fbfeSFrançois Revol 		gKernelArgs.frame_buffer.height);
727db9fbfeSFrançois Revol 	int placementX = max_c(0, min_c(100, kSplashLogoPlacementX));
737db9fbfeSFrançois Revol 	int placementY = max_c(0, min_c(100, kSplashLogoPlacementY));
747db9fbfeSFrançois Revol 
757db9fbfeSFrançois Revol 	int x = (gKernelArgs.frame_buffer.width - width) * placementX / 100;
767db9fbfeSFrançois Revol 	int y = (gKernelArgs.frame_buffer.height - height) * placementY / 100;
777db9fbfeSFrançois Revol 
787db9fbfeSFrançois Revol 	height = min_c(kSplashLogoHeight, gKernelArgs.frame_buffer.height);
797db9fbfeSFrançois Revol 	switch (gKernelArgs.frame_buffer.depth) {
807db9fbfeSFrançois Revol 		case 8:
817db9fbfeSFrançois Revol 			break;
827db9fbfeSFrançois Revol 	}
837db9fbfeSFrançois Revol 	video_blit_image(frameBuffer, uncompressedLogo, width, height,
847db9fbfeSFrançois Revol 		kSplashLogoWidth, x, y);
857db9fbfeSFrançois Revol 
867db9fbfeSFrançois Revol 	kernel_args_free(uncompressedLogo);
877db9fbfeSFrançois Revol 
887db9fbfeSFrançois Revol 	const uint8* lowerHalfIconImage;
897db9fbfeSFrançois Revol 
907db9fbfeSFrançois Revol 	switch (gKernelArgs.frame_buffer.depth) {
917db9fbfeSFrançois Revol 		case 8:
927db9fbfeSFrançois Revol 			// pointer into the lower half of the icons image data
937db9fbfeSFrançois Revol 			gKernelArgs.boot_splash
947db9fbfeSFrançois Revol 				= (uint8 *)kernel_args_malloc(kSplashIconsWidth
957db9fbfeSFrançois Revol 					* kSplashIconsHeight);
967db9fbfeSFrançois Revol 			if (gKernelArgs.boot_splash == NULL)
977db9fbfeSFrançois Revol 				return B_NO_MEMORY;
987db9fbfeSFrançois Revol 			uncompress_8bit_RLE(kSplashIcons8BitCompressedImage,
997db9fbfeSFrançois Revol 				gKernelArgs.boot_splash );
1007db9fbfeSFrançois Revol 			lowerHalfIconImage = gKernelArgs.boot_splash
1017db9fbfeSFrançois Revol 				+ (kSplashIconsWidth * iconsHalfHeight);
1027db9fbfeSFrançois Revol 		break;
1037db9fbfeSFrançois Revol 		default:
1047db9fbfeSFrançois Revol 			// pointer into the lower half of the icons image data
1057db9fbfeSFrançois Revol 			gKernelArgs.boot_splash
1067db9fbfeSFrançois Revol 				= (uint8 *)kernel_args_malloc(kSplashIconsWidth
1077db9fbfeSFrançois Revol 					* kSplashIconsHeight * 3);
1087db9fbfeSFrançois Revol 			if (gKernelArgs.boot_splash == NULL)
1097db9fbfeSFrançois Revol 				return B_NO_MEMORY;
1107db9fbfeSFrançois Revol 			uncompress_24bit_RLE(kSplashIcons24BitCompressedImage,
1117db9fbfeSFrançois Revol 				gKernelArgs.boot_splash );
1127db9fbfeSFrançois Revol 			lowerHalfIconImage = gKernelArgs.boot_splash
1137db9fbfeSFrançois Revol 				+ (kSplashIconsWidth * iconsHalfHeight) * 3;
1147db9fbfeSFrançois Revol 		break;
1157db9fbfeSFrançois Revol 	}
1167db9fbfeSFrançois Revol 
1177db9fbfeSFrançois Revol 	// render initial (grayed out) icons
1187db9fbfeSFrançois Revol 	// the grayed out version is the lower half of the icons image
1197db9fbfeSFrançois Revol 
1207db9fbfeSFrançois Revol 	width = min_c(kSplashIconsWidth, gKernelArgs.frame_buffer.width);
1217db9fbfeSFrançois Revol 	height = min_c(kSplashLogoHeight + iconsHalfHeight,
1227db9fbfeSFrançois Revol 		gKernelArgs.frame_buffer.height);
1237db9fbfeSFrançois Revol 	placementX = max_c(0, min_c(100, kSplashIconsPlacementX));
1247db9fbfeSFrançois Revol 	placementY = max_c(0, min_c(100, kSplashIconsPlacementY));
1257db9fbfeSFrançois Revol 
1267db9fbfeSFrançois Revol 	x = (gKernelArgs.frame_buffer.width - width) * placementX / 100;
1277db9fbfeSFrançois Revol 	y = kSplashLogoHeight + (gKernelArgs.frame_buffer.height - height)
1287db9fbfeSFrançois Revol 		* placementY / 100;
1297db9fbfeSFrançois Revol 
1307db9fbfeSFrançois Revol 	height = min_c(iconsHalfHeight, gKernelArgs.frame_buffer.height);
1317db9fbfeSFrançois Revol 	video_blit_image(frameBuffer, lowerHalfIconImage, width, height,
1327db9fbfeSFrançois Revol 		kSplashIconsWidth, x, y);
133*477d2636SFrançois Revol 	return B_OK;
1347db9fbfeSFrançois Revol }
1357db9fbfeSFrançois Revol 
136