patch by Artur Wyszynski (aljen):

* Added the feature of an animated boot screen (icons lighting up at
  different boot stages).
* Added first version of new boot splash images, generated by the new
  hsbg tool. (Also finally contains the "new" Haiku logo.)

changes by myself:
* Added Artur to the contributors list in About System.
* Fixed some left overs in the patch, kept tracing turned off.

TODO:
* Remove the need for hard coding the icon positions. (Maybe generate
  those from hsbg and put them into images.h? Have user provide icon
  spacing/offsets at the command line for hsbg?)
* Rename the stages to something meaningful.
* Use hsbg as a build system tool and generate images.h during build
  from PNGs provided in the artwork folder.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24434 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2008-03-18 10:25:53 +00:00
parent ff2f1edf62
commit aa727f6643
7 changed files with 8324 additions and 12 deletions
File diff suppressed because it is too large Load Diff
+58
View File
@@ -0,0 +1,58 @@
//------------------------------------------------------------------------------
// Copyright (c) 2008, Haiku, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// File Name: bootsplashstructs.h
// Author: Artur Wyszynski <[email protected]>
// Description: Boot splash header
//
//------------------------------------------------------------------------------
#ifndef KERNEL_BOOT_SPLASH_H
#define KERNEL_BOOT_SPLASH_H
struct kernel_args;
#ifdef __cplusplus
extern "C" {
#endif
enum {
BOOT_SPLASH_STAGE_1 = 0,
BOOT_SPLASH_STAGE_2,
BOOT_SPLASH_STAGE_3,
BOOT_SPLASH_STAGE_4,
BOOT_SPLASH_STAGE_5,
BOOT_SPLASH_STAGE_6,
BOOT_SPLASH_STAGE_7
};
status_t boot_splash_fb_init(struct kernel_args *args);
bool boot_splash_fb_available(void);
void boot_splash_set_stage(int stage);
#ifdef __cplusplus
}
#endif
#endif /* KERNEL_BOOT_SPLASH_H */
+1
View File
@@ -465,6 +465,7 @@ AboutView::AboutView(const BRect &rect)
"Nathan Whitehorn\n"
"Michael Wilber\n"
"Ulrich Wimboeck\n"
"Artur Wyszynski\n"
"Gabe Yoder\n"
"Gerald Zajac\n"
"Łukasz Zemczak\n"
+34 -9
View File
@@ -9,7 +9,6 @@
#include "vesa.h"
#include "vga.h"
#include "mmu.h"
#include "images.h"
#include <edid.h>
@@ -18,6 +17,7 @@
#include <boot/platform.h>
#include <boot/menu.h>
#include <boot/kernel_args.h>
#include <boot/images.h>
#include <util/list.h>
#include <drivers/driver_settings.h>
@@ -637,7 +637,7 @@ static void
blit8(const uint8 *data, uint16 width, uint16 height,
const uint8 *palette, uint16 left, uint16 top)
{
if (vesa_set_palette((const uint8 *)kPalette, 0, 256) != B_OK)
if (vesa_set_palette((const uint8 *)palette, 0, 256) != B_OK)
dprintf("set palette failed!\n");
addr_t start = sFrameBuffer + gKernelArgs.frame_buffer.bytes_per_row * top
@@ -719,10 +719,30 @@ blit_8bit_image(const uint8 *data, uint16 width, uint16 height,
}
}
static void
blit16_cropped(const uint8 *data, uint16 imageLeft, uint16 imageTop, uint16 imageRight,
uint16 imageBottom, uint16 imageWidth, uint16 imageHeight, const uint8 *palette,
uint16 left, uint16 top)
{
int32 dataOffset = (imageWidth * imageTop) + imageLeft;
uint16 *start = (uint16 *)(sFrameBuffer
+ gKernelArgs.frame_buffer.bytes_per_row * top + 2 * left);
for (int32 y = imageTop; y < imageBottom; y++) {
for (int32 x = imageLeft; x < imageRight; x++) {
uint16 color = data[(y * (imageWidth)) + x] * 3;
start[x] = ((palette[color + 0] >> 3) << 11)
| ((palette[color + 1] >> 2) << 5)
| ((palette[color + 2] >> 3));
dataOffset += imageWidth;
}
start = (uint16 *)((addr_t)start
+ gKernelArgs.frame_buffer.bytes_per_row);
}
}
// #pragma mark -
extern "C" void
platform_switch_to_logo(void)
{
@@ -788,15 +808,20 @@ fallback:
}
// clear the video memory
memset((void *)sFrameBuffer, 0,
memset((void *)sFrameBuffer, 255,
gKernelArgs.frame_buffer.physical_buffer.size);
// TODO: The image should be compressed, and eventually added by
// the build process.
int x = gKernelArgs.frame_buffer.width / 2 - splashWidth / 2;
int y = gKernelArgs.frame_buffer.height / 2 - splashHeight / 2;
blit_8bit_image(splashImage, splashWidth, splashHeight, splashPalette, x, y);
blit_8bit_image(kImageData, kWidth, kHeight, kPalette,
gKernelArgs.frame_buffer.width - kWidth - 40,
gKernelArgs.frame_buffer.height - kHeight - 60);
x = gKernelArgs.frame_buffer.width / 2 - iconsWidth / 2;
y = y + splashHeight;
blit16_cropped(iconsImage, 0, 32, iconsWidth, 64, iconsWidth, iconsHeight, iconsPalette, x, y);
x = gKernelArgs.frame_buffer.width / 2 - copyrightWidth / 2;
y = gKernelArgs.frame_buffer.height - copyrightHeight - 5;
blit_8bit_image(copyrightImage, copyrightWidth, copyrightHeight, copyrightPalette, x, y);
}
+1
View File
@@ -39,6 +39,7 @@ KernelMergeObject kernel_core.o :
system_info.cpp
smp.c
syscalls.cpp
splash.cpp
team.cpp
thread.cpp
timer.c
+13 -3
View File
@@ -40,11 +40,12 @@
#include <vfs.h>
#include <vm.h>
#include <boot/kernel_args.h>
#include <boot/splash.h>
#include <string.h>
#define TRACE_BOOT
//#define TRACE_BOOT 1
#ifdef TRACE_BOOT
# define TRACE(x...) dprintf("INIT: " x)
#else
@@ -214,15 +215,18 @@ _start(kernel_args *bootKernelArgs, int currentCPU)
return 0;
}
static int32
main2(void *unused)
{
(void)(unused);
TRACE("start of main2: initializing devices\n");
TRACE("Init boot splash frame buffer\n");
boot_splash_fb_init(&sKernelArgs);
TRACE("Init modules\n");
boot_splash_set_stage(BOOT_SPLASH_STAGE_1);
module_init(&sKernelArgs);
// ToDo: the preloaded image debug data is placed in the kernel args, and
@@ -246,9 +250,11 @@ main2(void *unused)
/* bootstrap all the filesystems */
TRACE("Bootstrap file systems\n");
boot_splash_set_stage(BOOT_SPLASH_STAGE_2);
vfs_bootstrap_file_systems();
TRACE("Init Device Manager\n");
boot_splash_set_stage(BOOT_SPLASH_STAGE_3);
device_manager_init(&sKernelArgs);
TRACE("Add preloaded old-style drivers\n");
@@ -260,12 +266,15 @@ main2(void *unused)
int_init_post_device_manager(&sKernelArgs);
TRACE("Mount boot file system\n");
boot_splash_set_stage(BOOT_SPLASH_STAGE_4);
vfs_mount_boot_file_system(&sKernelArgs);
// CPU specific modules may now be available
boot_splash_set_stage(BOOT_SPLASH_STAGE_5);
cpu_init_post_modules(&sKernelArgs);
TRACE("vm_init_post_modules\n");
boot_splash_set_stage(BOOT_SPLASH_STAGE_6);
vm_init_post_modules(&sKernelArgs);
TRACE("debug_init_post_modules\n");
@@ -274,6 +283,7 @@ main2(void *unused)
TRACE("device_manager_init_post_modules\n");
device_manager_init_post_modules(&sKernelArgs);
boot_splash_set_stage(BOOT_SPLASH_STAGE_7);
// start the init process
{
const char *shellArgs[] = {"/bin/sh", "/boot/beos/system/boot/Bootscript", NULL};
+315
View File
@@ -0,0 +1,315 @@
#include <KernelExport.h>
#include <kernel/elf32.h>
#include <kernel.h>
#include <lock.h>
#include <vm.h>
#include <fs/devfs.h>
#include <boot/images.h>
#include <boot/kernel_args.h>
#include <boot/splash.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <graphics/vesa/vga.h>
//#define TRACE_BOOT_SPLASH 1
#ifdef TRACE_BOOT_SPLASH
# define TRACE(x...) dprintf(x);
#else
# define TRACE(x...) ;
#endif
struct boot_splash_info {
mutex lock;
area_id area;
addr_t frame_buffer;
bool enabled;
int32 width;
int32 height;
int32 depth;
int32 bytes_per_pixel;
int32 bytes_per_row;
};
static struct boot_splash_info sBootSplash;
static void
boot_splash_fb_vga_set_palette(const uint8 *palette, int32 firstIndex, int32 numEntries)
{
out8(firstIndex, VGA_COLOR_WRITE_MODE);
// write VGA palette
for (int32 i = firstIndex; i < numEntries; i++) {
// VGA (usually) has only 6 bits per gun
out8(palette[i * 3 + 0] >> 2, VGA_COLOR_DATA);
out8(palette[i * 3 + 1] >> 2, VGA_COLOR_DATA);
out8(palette[i * 3 + 2] >> 2, VGA_COLOR_DATA);
}
}
static void
boot_splash_fb_blit4(const uint8 *data, uint16 width,
uint16 height, const uint8 *palette, uint16 left, uint16 top)
{
// ToDo: no blit yet in VGA mode
}
static void
boot_splash_fb_blit8(const uint8 *data, uint16 width,
uint16 height, const uint8 *palette, uint16 left, uint16 top)
{
boot_splash_fb_vga_set_palette(palette, 0, 256);
addr_t start = sBootSplash.frame_buffer + sBootSplash.bytes_per_row * top
+ left;
for (int32 i = 0; i < height; i++) {
memcpy((void *)(start + sBootSplash.bytes_per_row * i),
&data[i * width], width);
}
}
static void
boot_splash_fb_blit15(const uint8 *data, uint16 width,
uint16 height, const uint8 *palette, uint16 left, uint16 top)
{
uint16 *start = (uint16 *)(sBootSplash.frame_buffer
+ sBootSplash.bytes_per_row * top + 2 * left);
for (int32 y = 0; y < height; y++) {
for (int32 x = 0; x < width; x++) {
uint16 color = data[y * width + x] * 3;
start[x] = ((palette[color + 0] >> 3) << 10)
| ((palette[color + 1] >> 3) << 5)
| ((palette[color + 2] >> 3));
}
start = (uint16 *)((addr_t)start
+ sBootSplash.bytes_per_row);
}
}
static void
boot_splash_fb_blit16(const uint8 *data, uint16 width,
uint16 height, const uint8 *palette, uint16 left, uint16 top)
{
uint16 *start = (uint16 *)(sBootSplash.frame_buffer
+ sBootSplash.bytes_per_row * top + 2 * left);
for (int32 y = 0; y < height; y++) {
for (int32 x = 0; x < width; x++) {
uint16 color = data[y * width + x] * 3;
start[x] = ((palette[color + 0] >> 3) << 11)
| ((palette[color + 1] >> 2) << 5)
| ((palette[color + 2] >> 3));
}
start = (uint16 *)((addr_t)start
+ sBootSplash.bytes_per_row);
}
}
static void
boot_splash_fb_blit24(const uint8 *data, uint16 width,
uint16 height, const uint8 *palette, uint16 left, uint16 top)
{
uint8 *start = (uint8 *)sBootSplash.frame_buffer
+ sBootSplash.bytes_per_row * top + 3 * left;
for (int32 y = 0; y < height; y++) {
for (int32 x = 0; x < width; x++) {
uint16 color = data[y * width + x] * 3;
uint32 index = x * 3;
start[index + 0] = palette[color + 2];
start[index + 1] = palette[color + 1];
start[index + 2] = palette[color + 0];
}
start = start + sBootSplash.bytes_per_row;
}
}
static void
boot_splash_fb_blit32(const uint8 *data, uint16 width,
uint16 height, const uint8 *palette, uint16 left, uint16 top)
{
uint32 *start = (uint32 *)(sBootSplash.frame_buffer
+ sBootSplash.bytes_per_row * top + 4 * left);
for (int32 y = 0; y < height; y++) {
for (int32 x = 0; x < width; x++) {
uint16 color = data[y * width + x] * 3;
start[x] = (palette[color + 0] << 16) | (palette[color + 1] << 8)
| (palette[color + 2]);
}
start = (uint32 *)((addr_t)start
+ sBootSplash.bytes_per_row);
}
}
static void
boot_splash_fb_blit(const uint8 *data, uint16 width,
uint16 height, const uint8 *palette, uint16 left, uint16 top)
{
switch (sBootSplash.depth) {
case 4:
return boot_splash_fb_blit4(data, width, height, palette, left, top);
case 8:
return boot_splash_fb_blit8(data, width, height, palette, left, top);
case 15:
return boot_splash_fb_blit15(data, width, height, palette, left, top);
case 16:
return boot_splash_fb_blit16(data, width, height, palette, left, top);
case 24:
return boot_splash_fb_blit24(data, width, height, palette, left, top);
case 32:
return boot_splash_fb_blit32(data, width, height, palette, left, top);
}
}
static void
boot_splash_fb_blit16_cropped(const uint8 *data, uint16 imageLeft, uint16 imageTop, uint16 imageRight, uint16 imageBottom,
uint16 imageWidth, uint16 imageHeight, const uint8 *palette, uint16 left, uint16 top)
{
int32 dataOffset = (imageWidth * imageTop) + imageLeft;
uint16 *start = (uint16 *)(sBootSplash.frame_buffer
+ sBootSplash.bytes_per_row * top + 2 * left);
for (int32 y = imageTop; y < imageBottom; y++) {
for (int32 x = imageLeft; x < imageRight; x++) {
uint16 color = data[(y * (imageWidth)) + x] * 3;
start[x] = ((palette[color + 0] >> 3) << 11)
| ((palette[color + 1] >> 2) << 5)
| ((palette[color + 2] >> 3));
dataOffset += imageWidth;
}
start = (uint16 *)((addr_t)start + sBootSplash.bytes_per_row);
}
}
static void
boot_splash_fb_blit_cropped(const uint8 *data, uint16 imageLeft, uint16 imageTop,
uint16 imageRight, uint16 imageBottom, uint16 imageWidth, uint16 imageHeight,
const uint8 *palette, uint16 left, uint16 top)
{
switch (sBootSplash.depth) {
case 4:
case 8:
case 15:
return;
case 16:
return boot_splash_fb_blit16_cropped(data, imageLeft, imageTop, imageRight,
imageBottom, imageWidth, imageHeight, palette, left, top);
case 24:
case 32:
return;
}
}
static status_t
boot_splash_fb_update(addr_t baseAddress, int32 width, int32 height, int32 depth, int32 bytesPerRow)
{
TRACE("boot_splash_fb_update: buffer=%p, width=%ld, height=%ld, depth=%ld, bytesPerRow=%ld\n",
(void *)baseAddress, width, height, depth, bytesPerRow);
mutex_lock(&sBootSplash.lock);
sBootSplash.frame_buffer = baseAddress;
sBootSplash.width = width;
sBootSplash.height = height;
sBootSplash.depth = depth;
sBootSplash.bytes_per_pixel = (depth + 7) / 8;
sBootSplash.bytes_per_row = bytesPerRow;
TRACE("boot_splash_fb_update: frame buffer mapped at %p\n", (void *)sBootSplash.frame_buffer);
mutex_unlock(&sBootSplash.lock);
return B_OK;
}
bool
boot_splash_fb_available(void)
{
TRACE("boot_splash_fb_available: enter\n");
return sBootSplash.frame_buffer != (addr_t)NULL;
}
status_t
boot_splash_fb_init(struct kernel_args *args)
{
TRACE("boot_splash_fb_init: enter\n");
if (!args->frame_buffer.enabled) {
sBootSplash.enabled = false;
return B_OK;
}
sBootSplash.enabled = true;
void *frameBuffer;
sBootSplash.area = map_physical_memory("vesa_fb",
(void *)args->frame_buffer.physical_buffer.start,
args->frame_buffer.physical_buffer.size, B_ANY_KERNEL_ADDRESS,
B_READ_AREA | B_WRITE_AREA | B_USER_CLONEABLE_AREA, &frameBuffer);
if (sBootSplash.area < B_OK)
return sBootSplash.area;
boot_splash_fb_update((addr_t)frameBuffer, args->frame_buffer.width,
args->frame_buffer.height, args->frame_buffer.depth,
args->frame_buffer.bytes_per_row);
return B_OK;
}
void
boot_splash_set_stage(int stage)
{
TRACE("boot_splash_set_stage: stage=%d\n", stage);
if (!sBootSplash.enabled)
return;
int x = sBootSplash.width / 2 - iconsWidth / 2;
int y = sBootSplash.height / 2 - splashHeight / 2;
y = y + splashHeight;
int stageOffset = 0;
switch (stage) {
case BOOT_SPLASH_STAGE_1:
stageOffset = 32;
break;
case BOOT_SPLASH_STAGE_2:
stageOffset = 74;
break;
case BOOT_SPLASH_STAGE_3:
stageOffset = 116;
break;
case BOOT_SPLASH_STAGE_4:
stageOffset = 158;
break;
case BOOT_SPLASH_STAGE_5:
stageOffset = 200;
break;
case BOOT_SPLASH_STAGE_6:
stageOffset = 242;
break;
case BOOT_SPLASH_STAGE_7:
stageOffset = iconsWidth;
break;
}
if (stage == BOOT_SPLASH_STAGE_7)
stageOffset = iconsWidth;
boot_splash_fb_blit_cropped(iconsImage, 0, 0, stageOffset, 32,
iconsWidth, iconsHeight, iconsPalette, x, y );
}