#include "rom_calls.h"
#include "console.h"
#include "video.h"
#include <arch/cpu.h>
#include <boot/stage2.h>
#include <boot/platform.h>
#include <boot/menu.h>
#include <boot/kernel_args.h>
#include <boot/platform/generic/video.h>
#include <util/list.h>
#include <drivers/driver_settings.h>
#include <GraphicsDefs.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef TRACE_VIDEO
# define TRACE(x) dprintf x
#else
# define TRACE(x) ;
#endif
static addr_t sFrameBuffer;
static void
probe_video_mode()
{
if (gScreen == NULL) {
gKernelArgs.frame_buffer.enabled = false;
return;
}
gKernelArgs.frame_buffer.width = gScreen->RastPort.BitMap->BytesPerRow * 8;
gKernelArgs.frame_buffer.height = gScreen->RastPort.BitMap->Rows;
gKernelArgs.frame_buffer.bytes_per_row = gScreen->RastPort.BitMap->BytesPerRow;
gKernelArgs.frame_buffer.depth = gScreen->RastPort.BitMap->Depth;
gKernelArgs.frame_buffer.physical_buffer.size
= gKernelArgs.frame_buffer.width
* gKernelArgs.frame_buffer.height
* gScreen->RastPort.BitMap->Depth / 8;
gKernelArgs.frame_buffer.physical_buffer.start
= (phys_addr_t)(gScreen->RastPort.BitMap->Planes[0]);
dprintf("video mode: %ux%ux%u\n", gKernelArgs.frame_buffer.width,
gKernelArgs.frame_buffer.height, gKernelArgs.frame_buffer.depth);
gKernelArgs.frame_buffer.enabled = true;
}
bool
video_mode_hook(Menu *menu, MenuItem *item)
{
return true;
}
Menu *
video_mode_menu()
{
Menu *menu = new(nothrow) Menu(CHOICE_MENU, "Select Video Mode");
MenuItem *item;
menu->AddItem(item = new(nothrow) MenuItem("Default"));
item->SetMarked(true);
item->Select(true);
item->SetHelpText("The Default video mode is the one currently configured "
"in the system. If there is no mode configured yet, a viable mode will "
"be chosen automatically.");
#if 1
uint32 modeID = INVALID_ID;
while ((modeID = NextDisplayInfo(modeID)) != INVALID_ID) {
struct DisplayInfo info;
struct DimensionInfo dimension;
struct NameInfo name;
if (GetDisplayInfoData(NULL, (uint8 *)&info, sizeof(info),
DTAG_DISP, modeID) < 48)
continue;
if (GetDisplayInfoData(NULL, (uint8 *)&dimension, sizeof(dimension),
DTAG_DIMS, modeID) < 66)
continue;
if (info.NotAvailable)
continue;
if (info.PropertyFlags & DIPF_IS_HAM)
continue;
if (info.PropertyFlags & DIPF_IS_DUALPF)
continue;
if (dimension.MaxDepth < 4)
continue;
if (dimension.MaxDepth < 8 && dimension.MaxDepth != 4)
continue;
dprintf("mode: %dx%d %dbpp flags: 0x%08lx\n",
dimension.Nominal.MaxX - dimension.Nominal.MinX + 1,
dimension.Nominal.MaxY - dimension.Nominal.MinY + 1,
dimension.MaxDepth, info.PropertyFlags);
char label[128];
sprintf(label, "%ux%u %u bit %08lx%s%s",
dimension.Nominal.MaxX - dimension.Nominal.MinX + 1,
dimension.Nominal.MaxY - dimension.Nominal.MinY + 1,
dimension.MaxDepth, info.PropertyFlags,
(info.PropertyFlags & DIPF_IS_LACE) ? " i" : "",
(info.PropertyFlags & DIPF_IS_PAL) ? " pal" : "");
menu->AddItem(item = new(nothrow) MenuItem(label));
item->SetData((void *)modeID);
}
#endif
dprintf("done\n");
menu->AddSeparatorItem();
menu->AddItem(item = new(nothrow) MenuItem("Return to main menu"));
item->SetType(MENU_ITEM_NO_CHOICE);
return menu;
}
extern "C" void
platform_blit4(addr_t frameBuffer, const uint8 *data,
uint16 width, uint16 height, uint16 imageWidth, uint16 left, uint16 top)
{
if (!data)
return;
}
extern "C" void
platform_set_palette(const uint8 *palette)
{
switch (gKernelArgs.frame_buffer.depth) {
case 4:
break;
case 8:
break;
default:
break;
}
}
extern "C" void
platform_switch_to_logo(void)
{
return;
if ((platform_boot_options() & BOOT_OPTION_DEBUG_OUTPUT) != 0)
return;
addr_t lastBase = gKernelArgs.frame_buffer.physical_buffer.start;
size_t lastSize = gKernelArgs.frame_buffer.physical_buffer.size;
probe_video_mode();
sFrameBuffer = gKernelArgs.frame_buffer.physical_buffer.start;
}
extern "C" void
platform_switch_to_text_mode(void)
{
RemakeDisplay();
}
extern "C" status_t
platform_init_video(void)
{
probe_video_mode();
return B_OK;
}