kobodl/graphics/vidmodes.c
Ville Lindholm dbc223eb84
Initial commit
Import existing source tree; original VCS history is no longer available.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-05-28 16:35:31 +03:00

194 lines
5.1 KiB
C

/*(LGPL)
---------------------------------------------------------------------------
vidmodes.c - Video Mode Manager for Kobo Deluxe
---------------------------------------------------------------------------
* Copyright (C) 2007 David Olofson
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "vidmodes.h"
#include <stdlib.h>
#include <string.h>
typedef struct VMM_IMode
{
int flags, width, height, id;
const char *name;
} VMM_IMode;
static VMM_IMode modetab[] =
{
// 4:3 modes
{VMM_4_3 | VMM_PC, 320, 200, 0x04300, "CGA"},
{VMM_4_3 | VMM_PC, 320, 240, 0x04301, "QVGA"},
{VMM_4_3, 320, 256, 0x04302, "Amiga LoRes"},
{VMM_4_3 | VMM_LORES, 400, 300, 0x04310, NULL},
{VMM_4_3 | VMM_LORES, 512, 384, 0x04320, NULL},
{VMM_4_3 | VMM_PC, 640, 480, 0x04330, "VGA"},
{VMM_4_3, 640, 512, 0x04331, "Amiga HiRes"},
{VMM_4_3 | VMM_TV, 768, 576, 0x04340, "PAL"},
{VMM_4_3 | VMM_PC, 800, 600, 0x04350, NULL},
{VMM_4_3 | VMM_LORES, 960, 720, 0x04360, NULL},
{VMM_4_3 | VMM_PC, 1024, 768, 0x04370, "XGA"},
{VMM_4_3 | VMM_PC, 1152, 864, 0x04380, NULL},
{VMM_4_3 | VMM_PC, 1280, 960, 0x04390, NULL},
{VMM_4_3 | VMM_PC, 1400, 1050, 0x043a0, "SXGA+"},
{VMM_4_3 | VMM_PC, 1600, 1200, 0x043b0, "UXGA"},
{VMM_4_3 | VMM_PC, 1920, 1440, 0x043c0, NULL},
{VMM_4_3 | VMM_PC, 2048, 1536, 0x043d0, "QXGA"},
// 3:2 modes
{VMM_3_2 | VMM_LORES, 360, 240, 0x03200, NULL},
{VMM_3_2 | VMM_LORES, 720, 480, 0x03240, "NTSC"},
{VMM_3_2, 1152, 768, 0x03280, NULL},
{VMM_3_2, 1280, 854, 0x03290, NULL},
{VMM_3_2, 1440, 960, 0x032a0, NULL},
// 5:4 modes
{VMM_5_4 | VMM_LORES, 320, 256, 0x05400, "Amiga LoRes"},
{VMM_5_4 | VMM_LORES, 640, 512, 0x05430, "Amiga HiRes"},
{VMM_5_4 | VMM_PC, 1280, 1024, 0x05490, "SXGA"},
{VMM_5_4, 2560, 2048, 0x054e0, "QSXGA"},
// 16:10 modes
{VMM_16_10 | VMM_LORES, 320, 200, 0x10a00, NULL},
{VMM_16_10 | VMM_PC, 640, 400, 0x10a30, NULL},
{VMM_16_10 | VMM_LORES, 840, 525, 0x10a50, NULL},
{VMM_16_10 | VMM_PC, 1280, 800, 0x10a90, NULL},
{VMM_16_10 | VMM_PC, 1680, 1050, 0x10ab0, "WSXGA+"},
{VMM_16_10 | VMM_PC, 1920, 1200, 0x10ac0, "WUXGA"},
{VMM_16_10 | VMM_PC, 2560, 1600, 0x10ae0, "WQXGA"},
// 16:9 modes
{VMM_16_9 | VMM_LORES, 480, 270, 0x10910, NULL},
{VMM_16_9 | VMM_LORES, 678, 384, 0x10930, NULL},
{VMM_16_9 | VMM_TV, 854, 480, 0x10950, "WVGA"},
{VMM_16_9 | VMM_LORES, 960, 540, 0x10960, NULL},
{VMM_16_9, 1280, 720, 0x10990, "HD 720"},
{VMM_16_9 | VMM_TV, 1356, 768, 0x109a0, "Flat TV"},
{VMM_16_9 | VMM_TV, 1920, 1080, 0x109c0, "HD 1080"},
{VMM_16_9, 2560, 1440, 0x109e0, NULL},
// End of table
{0, 0, 0}
};
/*-------------------------------------------------------------------------
Gathering and constructing modes
-------------------------------------------------------------------------*/
static VMM_Mode *vmm_modes = NULL;
int vmm_Init(int show, int hide)
{
int i;
VMM_Mode *lastm = NULL;
vmm_Close();
/*
TODO: Include detected SDL modes, if requested.
*/
for(i = 0; modetab[i].width; ++i)
{
VMM_Mode *m;
double nominal_aspect;
VMM_IMode *im = &modetab[i];
if(im->flags & hide)
continue;
if(!(im->flags & show))
continue;
m = calloc(1, sizeof(VMM_Mode));
if(!m)
return -1; /* Out of memory! */
m->id = im->id;
m->width = im->width;
m->height = im->height;
m->flags = im->flags;
if(im->flags & VMM_3_2)
nominal_aspect = 3.0f / 2.0f;
else if(im->flags & VMM_5_4)
nominal_aspect = 5.0f / 4.0f;
else if(im->flags & VMM_16_10)
nominal_aspect = 16.0f / 10.0f;
else if(im->flags & VMM_16_9)
nominal_aspect = 16.0f / 9.0f;
else
nominal_aspect = 4.0f / 3.0f;
if(im->width)
m->aspect = nominal_aspect / im->width * im->height;
else
m->aspect = 1.0f;
if(im->name)
m->name = strdup(im->name);
if(lastm)
lastm->next = m;
else
vmm_modes = m;
lastm = m;
}
return 0;
}
void vmm_Close(void)
{
VMM_Mode *m = vmm_First();
while(m)
{
VMM_Mode *dm = m;
m = vmm_Next(m);
free(dm->name);
free(dm);
}
vmm_modes = NULL;
}
/*-------------------------------------------------------------------------
Scanning
-------------------------------------------------------------------------*/
VMM_Mode *vmm_First(void)
{
return vmm_modes;
}
VMM_Mode *vmm_Next(VMM_Mode *current)
{
return current->next;
}
/*-------------------------------------------------------------------------
Indexing
-------------------------------------------------------------------------*/
VMM_Mode *vmm_FindMode(int id)
{
VMM_Mode *m = vmm_First();
while(m)
{
if(m->id == id)
return m;
m = vmm_Next(m);
}
return NULL;
}