/*(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 #include 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; }