initial pandora port, with hardware scaling and stuff

This commit is contained in:
notaz 2011-09-04 20:02:19 +03:00
parent 43c24b301d
commit eb3668fc5d
16 changed files with 1472 additions and 34 deletions

3
.gitignore vendored
View File

@ -2,3 +2,6 @@
*.u
*.z
gpsp.gpe
tags
cscope.out
pandora/linux

View File

@ -251,4 +251,8 @@ typedef u32 fixed16_16;
// #define STDIO_DEBUG
#endif
#ifdef PND_BUILD
#include "pandora/pnd.h"
#endif
#endif

View File

@ -39,7 +39,7 @@ static u32 gp2x_audio_volume = 74/2;
static volatile u16 *gpsp_gp2x_memregs;
static volatile u32 *gpsp_gp2x_memregl;
u32 button_plat_mask_to_config[] =
u32 button_plat_mask_to_config[PLAT_BUTTON_COUNT] =
{
GP2X_UP,
GP2X_LEFT,
@ -59,7 +59,7 @@ u32 button_plat_mask_to_config[] =
GP2X_VOL_MIDDLE
};
u32 gamepad_config_map[16] =
u32 gamepad_config_map[PLAT_BUTTON_COUNT] =
{
BUTTON_ID_UP, // Up
BUTTON_ID_LEFT, // Left

View File

@ -33,7 +33,8 @@ void gpsp_plat_quit(void);
u32 gpsp_plat_joystick_read(void);
u32 gpsp_plat_buttons_to_cursor(u32 buttons);
extern u32 button_plat_mask_to_config[];
#define PLAT_BUTTON_COUNT 16
extern u32 button_plat_mask_to_config[PLAT_BUTTON_COUNT];
void gp2x_sound_volume(u32 volume_up);
void gp2x_quit();

77
gui.c
View File

@ -569,11 +569,11 @@ struct _menu_option_type
void (* action_function)();
void (* passive_function)();
struct _menu_type *sub_menu;
char *display_string;
const char *display_string;
void *options;
u32 *current_option;
u32 num_options;
char *help_string;
const char *help_string;
u32 line_number;
menu_option_type_enum option_type;
};
@ -740,16 +740,26 @@ u32 gamepad_config_line_to_button[] =
#endif
#ifdef PND_BUILD
u32 gamepad_config_line_to_button[] =
{ 0, 2, 1, 3, 8, 9, 10, 11, 6, 7, 4, 5, 12, 13, 14, 15 };
#endif
u8 *scale_options[] =
{
#ifdef WIZ_BUILD
#ifdef PSP_BUILD
"unscaled 3:2", "scaled 3:2", "fullscreen 16:9"
#elif defined(WIZ_BUILD)
"unscaled 3:2", "scaled 3:2 (slower)",
"unscaled 3:2 (anti-tear)", "scaled 3:2 (anti-tear)"
#else
#elif defined(PND_BUILD)
"unscaled", "2x", "3x", "fullscreen"
#elif defined(GP2X_BUILD)
"unscaled 3:2", "scaled 3:2", "fullscreen", "scaled 3:2 (software)"
#ifdef PSP_BUILD
" 16:9"
#endif
#else
"unscaled 3:2"
#endif
};
@ -1024,7 +1034,7 @@ void get_savestate_snapshot(u8 *savestate_filename)
else
{
memset(snapshot_buffer, 0, 240 * 160 * 2);
print_string_ext("No savestate exists for this slot.",
print_string_ext("No savestate in this slot.",
0xFFFF, 0x0000, 15, 75, snapshot_buffer, 240, 0, 0, FONT_HEIGHT);
print_string("---------- --/--/---- --:--:-- ", COLOR_HELP_TEXT,
COLOR_BG, 10, 40);
@ -1084,7 +1094,7 @@ u32 menu(u16 *original_screen)
auto void choose_menu();
auto void clear_help();
u8 *gamepad_help[] =
static const u8 * const gamepad_help[] =
{
"Up button on GBA d-pad.",
"Down button on GBA d-pad.",
@ -1315,16 +1325,19 @@ u32 menu(u16 *original_screen)
(u32 *)(&screen_scale),
sizeof(scale_options) / sizeof(scale_options[0]),
#ifndef GP2X_BUILD
"Determines how the GBA screen is resized in relation to the entire\n"
"screen. Select unscaled 3:2 for GBA resolution, scaled 3:2 for GBA\n"
"Determines how the GBA screen is resized in relation to the\n"
"entire screen."
#ifdef PSP_BUILD
" Select unscaled 3:2 for GBA resolution, scaled 3:2 for GBA\n"
"aspect ratio scaled to fill the height of the PSP screen, and\n"
"fullscreen to fill the entire PSP screen."
#endif
#endif
"", 2),
#ifndef GP2X_BUILD
string_selection_option(NULL, "Screen filtering", yes_no_options,
(u32 *)(&screen_filter), 2,
"Determines whether or not bilinear filtering should be used when\n"
"Determines whether or not filtering should be used when\n"
"scaling the screen. Selecting this will produce a more even and\n"
"smooth image, at the cost of being blurry and having less vibrant\n"
"colors.", 3),
@ -1352,8 +1365,8 @@ u32 menu(u16 *original_screen)
#ifndef GP2X_BUILD
"If objects in the game flicker at a regular rate certain manual\n"
"frameskip values may cause them to normally disappear. Change this\n"
"value to 'random' to avoid this. Do not use otherwise, as it tends to\n"
"make the image quality worse, especially in high motion games."
"value to 'random' to avoid this. Do not use otherwise, as it tends\n"
"to make the image quality worse, especially in high motion games."
#endif
"", 7),
string_selection_option(NULL, "Audio output", yes_no_options,
@ -1395,25 +1408,29 @@ u32 menu(u16 *original_screen)
cheat_option(7),
cheat_option(8),
cheat_option(9),
#if defined(PSP_BUILD) || defined(GP2X_BUILD)
string_selection_option(NULL, "Clock speed",
clock_speed_options, &clock_speed_number,
sizeof(clock_speed_options) / sizeof(clock_speed_options[0]),
"Change the clock speed of the device. Higher clock\n"
"speed will yield better performance, but will drain\n"
"battery life further.", 11),
#endif
string_selection_option(NULL, "Update backup",
update_backup_options, &update_backup_flag, 2,
#ifdef GP2X_BUILD
"Determines when in-game save files should be\n"
"written back to SD card.",
"written back to SD card."
#else
"Determines when in-game save files should be written back to\n"
"memstick. If set to 'automatic' writebacks will occur shortly after\n"
"the game's backup is altered. On 'exit only' it will only be written\n"
"back when you exit from this menu (NOT from using the home button).\n"
"Use the latter with extreme care.",
"card. If set to 'automatic' writebacks will occur shortly after\n"
"the game's backup is altered. On 'exit only' it will only be\n"
"written back when you exit from this menu.\n"
#ifdef PSP
"(NOT from using the home button), use the latter with extreme care."
#endif
12),
#endif
"", 12),
submenu_option(NULL, "Back", "Return to the main menu.", 14)
};
@ -1483,7 +1500,7 @@ u32 menu(u16 *original_screen)
#endif
#ifdef GP2X_BUILD
#if defined(GP2X_BUILD) || defined(PND_BUILD)
menu_option_type gamepad_config_options[] =
{
@ -1503,10 +1520,18 @@ u32 menu(u16 *original_screen)
gamepad_config_option("Start ", 10),
#endif
gamepad_config_option("Select ", 11),
#ifndef WIZ_BUILD
#if !defined(WIZ_BUILD) && !defined(PND_BUILD)
gamepad_config_option("Stick Push ", 12),
#endif
#ifdef PND_BUILD
gamepad_config_option("1 ", 12),
gamepad_config_option("2 ", 13),
gamepad_config_option("3 ", 14),
gamepad_config_option("4 ", 15),
submenu_option(NULL, "Back", "Return to the main menu.", 16)
#else
submenu_option(NULL, "Back", "Return to the main menu.", 14)
#endif
};
@ -1665,13 +1690,13 @@ u32 menu(u16 *original_screen)
if(display_option == current_option)
{
print_string_pad(line_buffer, COLOR_ACTIVE_ITEM, COLOR_BG, 10,
(display_option->line_number * 10) + 40, 41);
print_string_pad(line_buffer, COLOR_ACTIVE_ITEM, COLOR_BG, 6,
(display_option->line_number * 10) + 40, 36);
}
else
{
print_string_pad(line_buffer, COLOR_INACTIVE_ITEM, COLOR_BG, 10,
(display_option->line_number * 10) + 40, 41);
print_string_pad(line_buffer, COLOR_INACTIVE_ITEM, COLOR_BG, 6,
(display_option->line_number * 10) + 40, 36);
}
}

View File

@ -454,7 +454,7 @@ u32 update_input()
handled_buttons = (last_buttons ^ buttons) & buttons;
last_buttons = buttons;
for(i = 0; i < 16; i++)
for(i = 0; i < PLAT_BUTTON_COUNT; i++)
{
if(handled_buttons & button_plat_mask_to_config[i])
button_id = gamepad_config_map[i];

10
main.c
View File

@ -203,9 +203,6 @@ int main(int argc, char *argv[])
#endif
getcwd(main_path, 512);
load_config_file();
gamepak_filename[0] = 0;
#ifdef PSP_BUILD
delay_us(2500000);
@ -214,6 +211,9 @@ int main(int argc, char *argv[])
#ifndef PC_BUILD
gpsp_plat_init();
#endif
load_config_file();
gamepak_filename[0] = 0;
init_video();
@ -235,7 +235,11 @@ int main(int argc, char *argv[])
debug_screen_printl("a860e8c0b6d573d191e4ec7db1b1e4f6 ");
debug_screen_printl(" ");
debug_screen_printl("When you do get it name it gba_bios.bin and put it");
#ifdef PND_BUILD
debug_screen_printl("in <CD card>/pandora/appdata/gpsp/ . ");
#else
debug_screen_printl("in the same directory as gpSP. ");
#endif
debug_screen_printl(" ");
debug_screen_printl("Press any button to exit. ");

41
pandora/Makefile Normal file
View File

@ -0,0 +1,41 @@
# gpSP makefile
# Gilead Kutnick - Exophase
# pandora port - notaz
# Global definitions
CC = $(CROSS_COMPILE)gcc
OBJS = pnd.o main.o cpu.o memory.o video.o input.o sound.o gui.o \
cheats.o zip.o cpu_threaded.o arm_stub.o video_blend.o warm.o \
linux/fbdev.o linux/xenv.o
BIN = gpsp
# Platform specific definitions
VPATH += .. ../arm
CFLAGS += -DARM_ARCH -DPND_BUILD
CFLAGS += -funsigned-char
CFLAGS += -mcpu=cortex-a8 -mtune=cortex-a8 -mfloat-abi=softfp -ffast-math
CFLAGS += -fno-common -fno-builtin
CFLAGS += -ggdb
CFLAGS += -O2
# expecting to have PATH set up to get correct sdl-config first
CFLAGS += `sdl-config --cflags`
LIBS += `sdl-config --libs`
LIBS += -ldl -lpthread -lz
# Compilation:
%.o: %.S
$(CC) $(CFLAGS) -c -o $@ $<
all: $(BIN)
$(BIN): $(OBJS)
$(CC) $(OBJS) $(LIBS) -o $(BIN)
clean:
rm -f *.o $(BIN)

255
pandora/linux/fbdev.c Normal file
View File

@ -0,0 +1,255 @@
/*
* (C) Gražvydas "notaz" Ignotas, 2009-2010
*
* This work is licensed under the terms of any of these licenses
* (at your option):
* - GNU GPL, version 2 or later.
* - GNU LGPL, version 2.1 or later.
* See the COPYING file in the top-level directory.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <linux/fb.h>
#include <linux/matroxfb.h>
#include "fbdev.h"
struct vout_fbdev {
int fd;
void *mem;
size_t mem_size;
struct fb_var_screeninfo fbvar_old;
struct fb_var_screeninfo fbvar_new;
int buffer_write;
int fb_size;
int buffer_count;
int top_border, bottom_border;
};
void *vout_fbdev_flip(struct vout_fbdev *fbdev)
{
int draw_buf;
if (fbdev->buffer_count < 2)
return fbdev->mem;
draw_buf = fbdev->buffer_write;
fbdev->buffer_write++;
if (fbdev->buffer_write >= fbdev->buffer_count)
fbdev->buffer_write = 0;
fbdev->fbvar_new.yoffset =
(fbdev->top_border + fbdev->fbvar_new.yres + fbdev->bottom_border) * draw_buf +
fbdev->top_border;
ioctl(fbdev->fd, FBIOPAN_DISPLAY, &fbdev->fbvar_new);
return (char *)fbdev->mem + fbdev->fb_size * fbdev->buffer_write;
}
void vout_fbdev_wait_vsync(struct vout_fbdev *fbdev)
{
int arg = 0;
ioctl(fbdev->fd, FBIO_WAITFORVSYNC, &arg);
}
/* it is recommended to call vout_fbdev_clear() before this */
void *vout_fbdev_resize(struct vout_fbdev *fbdev, int w, int h, int bpp,
int left_border, int right_border, int top_border, int bottom_border, int buffer_cnt)
{
int w_total = left_border + w + right_border;
int h_total = top_border + h + bottom_border;
size_t mem_size;
int ret;
// unblank to be sure the mode is really accepted
ioctl(fbdev->fd, FBIOBLANK, FB_BLANK_UNBLANK);
if (fbdev->fbvar_new.bits_per_pixel != bpp ||
fbdev->fbvar_new.xres != w ||
fbdev->fbvar_new.yres != h ||
fbdev->fbvar_new.xres_virtual != w_total||
fbdev->fbvar_new.yres_virtual < h_total ||
fbdev->fbvar_new.xoffset != left_border ||
fbdev->buffer_count != buffer_cnt)
{
if (fbdev->fbvar_new.bits_per_pixel != bpp ||
w != fbdev->fbvar_new.xres || h != fbdev->fbvar_new.yres)
printf(" switching to %dx%d@%d\n", w, h, bpp);
fbdev->fbvar_new.xres = w;
fbdev->fbvar_new.yres = h;
fbdev->fbvar_new.xres_virtual = w_total;
fbdev->fbvar_new.yres_virtual = h_total * buffer_cnt;
fbdev->fbvar_new.xoffset = left_border;
fbdev->fbvar_new.yoffset = top_border;
fbdev->fbvar_new.bits_per_pixel = bpp;
fbdev->fbvar_new.nonstd = 0; // can set YUV here on omapfb
fbdev->buffer_count = buffer_cnt;
fbdev->buffer_write = 1;
// seems to help a bit to avoid glitches
vout_fbdev_wait_vsync(fbdev);
ret = ioctl(fbdev->fd, FBIOPUT_VSCREENINFO, &fbdev->fbvar_new);
if (ret == -1) {
// retry with no multibuffering
fbdev->fbvar_new.yres_virtual = h_total;
ret = ioctl(fbdev->fd, FBIOPUT_VSCREENINFO, &fbdev->fbvar_new);
if (ret == -1) {
perror("FBIOPUT_VSCREENINFO ioctl");
return NULL;
}
fbdev->buffer_count = 1;
fbdev->buffer_write = 0;
fprintf(stderr, "Warning: failed to increase virtual resolution, "
"multibuffering disabled\n");
}
}
fbdev->fb_size = w_total * h_total * bpp / 8;
fbdev->top_border = top_border;
fbdev->bottom_border = bottom_border;
mem_size = fbdev->fb_size * fbdev->buffer_count;
if (fbdev->mem_size >= mem_size)
goto out;
if (fbdev->mem != NULL)
munmap(fbdev->mem, fbdev->mem_size);
fbdev->mem = mmap(0, mem_size, PROT_WRITE|PROT_READ, MAP_SHARED, fbdev->fd, 0);
if (fbdev->mem == MAP_FAILED && fbdev->buffer_count > 1) {
fprintf(stderr, "Warning: can't map %zd bytes, doublebuffering disabled\n", mem_size);
fbdev->buffer_count = 1;
fbdev->buffer_write = 0;
mem_size = fbdev->fb_size;
fbdev->mem = mmap(0, mem_size, PROT_WRITE|PROT_READ, MAP_SHARED, fbdev->fd, 0);
}
if (fbdev->mem == MAP_FAILED) {
fbdev->mem = NULL;
fbdev->mem_size = 0;
perror("mmap framebuffer");
return NULL;
}
fbdev->mem_size = mem_size;
out:
return (char *)fbdev->mem + fbdev->fb_size * fbdev->buffer_write;
}
void vout_fbdev_clear(struct vout_fbdev *fbdev)
{
memset(fbdev->mem, 0, fbdev->mem_size);
}
void vout_fbdev_clear_lines(struct vout_fbdev *fbdev, int y, int count)
{
int stride = fbdev->fbvar_new.xres_virtual * fbdev->fbvar_new.bits_per_pixel / 8;
int i;
if (y + count > fbdev->top_border + fbdev->fbvar_new.yres)
count = fbdev->top_border + fbdev->fbvar_new.yres - y;
if (y >= 0 && count > 0)
for (i = 0; i < fbdev->buffer_count; i++)
memset((char *)fbdev->mem + fbdev->fb_size * i + y * stride, 0, stride * count);
}
int vout_fbdev_get_fd(struct vout_fbdev *fbdev)
{
return fbdev->fd;
}
struct vout_fbdev *vout_fbdev_init(const char *fbdev_name, int *w, int *h, int bpp, int buffer_cnt)
{
struct vout_fbdev *fbdev;
int req_w, req_h;
void *pret;
int ret;
fbdev = calloc(1, sizeof(*fbdev));
if (fbdev == NULL)
return NULL;
fbdev->fd = open(fbdev_name, O_RDWR);
if (fbdev->fd == -1) {
fprintf(stderr, "%s: ", fbdev_name);
perror("open");
goto fail_open;
}
ret = ioctl(fbdev->fd, FBIOGET_VSCREENINFO, &fbdev->fbvar_old);
if (ret == -1) {
perror("FBIOGET_VSCREENINFO ioctl");
goto fail;
}
fbdev->fbvar_new = fbdev->fbvar_old;
req_w = fbdev->fbvar_new.xres;
if (*w != 0)
req_w = *w;
req_h = fbdev->fbvar_new.yres;
if (*h != 0)
req_h = *h;
pret = vout_fbdev_resize(fbdev, req_w, req_h, bpp, 0, 0, 0, 0, buffer_cnt);
if (pret == NULL)
goto fail;
printf("%s: %ix%i@%d\n", fbdev_name, fbdev->fbvar_new.xres, fbdev->fbvar_new.yres,
fbdev->fbvar_new.bits_per_pixel);
*w = fbdev->fbvar_new.xres;
*h = fbdev->fbvar_new.yres;
memset(fbdev->mem, 0, fbdev->mem_size);
// some checks
ret = 0;
ret = ioctl(fbdev->fd, FBIO_WAITFORVSYNC, &ret);
if (ret != 0)
fprintf(stderr, "Warning: vsync doesn't seem to be supported\n");
if (fbdev->buffer_count > 1) {
fbdev->buffer_write = 0;
fbdev->fbvar_new.yoffset = fbdev->fbvar_new.yres * (fbdev->buffer_count - 1);
ret = ioctl(fbdev->fd, FBIOPAN_DISPLAY, &fbdev->fbvar_new);
if (ret != 0) {
fbdev->buffer_count = 1;
fprintf(stderr, "Warning: can't pan display, doublebuffering disabled\n");
}
}
printf("fbdev initialized.\n");
return fbdev;
fail:
close(fbdev->fd);
fail_open:
free(fbdev);
return NULL;
}
void vout_fbdev_finish(struct vout_fbdev *fbdev)
{
ioctl(fbdev->fd, FBIOPUT_VSCREENINFO, &fbdev->fbvar_old);
if (fbdev->mem != MAP_FAILED)
munmap(fbdev->mem, fbdev->mem_size);
if (fbdev->fd >= 0)
close(fbdev->fd);
fbdev->mem = NULL;
fbdev->fd = -1;
free(fbdev);
}

12
pandora/linux/fbdev.h Normal file
View File

@ -0,0 +1,12 @@
struct vout_fbdev;
struct vout_fbdev *vout_fbdev_init(const char *fbdev_name, int *w, int *h, int bpp, int buffer_count);
void *vout_fbdev_flip(struct vout_fbdev *fbdev);
void vout_fbdev_wait_vsync(struct vout_fbdev *fbdev);
void *vout_fbdev_resize(struct vout_fbdev *fbdev, int w, int h, int bpp,
int left_border, int right_border, int top_border, int bottom_border,
int buffer_count);
void vout_fbdev_clear(struct vout_fbdev *fbdev);
void vout_fbdev_clear_lines(struct vout_fbdev *fbdev, int y, int count);
int vout_fbdev_get_fd(struct vout_fbdev *fbdev);
void vout_fbdev_finish(struct vout_fbdev *fbdev);

427
pandora/linux/omapfb.h Normal file
View File

@ -0,0 +1,427 @@
/*
* File: arch/arm/plat-omap/include/mach/omapfb.h
*
* Framebuffer driver for TI OMAP boards
*
* Copyright (C) 2004 Nokia Corporation
* Author: Imre Deak <imre.deak@nokia.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __OMAPFB_H
#define __OMAPFB_H
#include <asm/ioctl.h>
#include <asm/types.h>
/* IOCTL commands. */
#define OMAP_IOW(num, dtype) _IOW('O', num, dtype)
#define OMAP_IOR(num, dtype) _IOR('O', num, dtype)
#define OMAP_IOWR(num, dtype) _IOWR('O', num, dtype)
#define OMAP_IO(num) _IO('O', num)
#define OMAPFB_MIRROR OMAP_IOW(31, int)
#define OMAPFB_SYNC_GFX OMAP_IO(37)
#define OMAPFB_VSYNC OMAP_IO(38)
#define OMAPFB_SET_UPDATE_MODE OMAP_IOW(40, int)
#define OMAPFB_GET_CAPS OMAP_IOR(42, struct omapfb_caps)
#define OMAPFB_GET_UPDATE_MODE OMAP_IOW(43, int)
#define OMAPFB_LCD_TEST OMAP_IOW(45, int)
#define OMAPFB_CTRL_TEST OMAP_IOW(46, int)
#define OMAPFB_UPDATE_WINDOW_OLD OMAP_IOW(47, struct omapfb_update_window_old)
#define OMAPFB_SET_COLOR_KEY OMAP_IOW(50, struct omapfb_color_key)
#define OMAPFB_GET_COLOR_KEY OMAP_IOW(51, struct omapfb_color_key)
#define OMAPFB_SETUP_PLANE OMAP_IOW(52, struct omapfb_plane_info)
#define OMAPFB_QUERY_PLANE OMAP_IOW(53, struct omapfb_plane_info)
#define OMAPFB_UPDATE_WINDOW OMAP_IOW(54, struct omapfb_update_window)
#define OMAPFB_SETUP_MEM OMAP_IOW(55, struct omapfb_mem_info)
#define OMAPFB_QUERY_MEM OMAP_IOW(56, struct omapfb_mem_info)
#define OMAPFB_WAITFORVSYNC OMAP_IO(57)
#define OMAPFB_MEMORY_READ OMAP_IOR(58, struct omapfb_memory_read)
#ifndef FBIO_WAITFORVSYNC
#define FBIO_WAITFORVSYNC _IOW('F', 0x20, u_int32_t)
#endif
#define OMAPFB_CAPS_GENERIC_MASK 0x00000fff
#define OMAPFB_CAPS_LCDC_MASK 0x00fff000
#define OMAPFB_CAPS_PANEL_MASK 0xff000000
#define OMAPFB_CAPS_MANUAL_UPDATE 0x00001000
#define OMAPFB_CAPS_TEARSYNC 0x00002000
#define OMAPFB_CAPS_PLANE_RELOCATE_MEM 0x00004000
#define OMAPFB_CAPS_PLANE_SCALE 0x00008000
#define OMAPFB_CAPS_WINDOW_PIXEL_DOUBLE 0x00010000
#define OMAPFB_CAPS_WINDOW_SCALE 0x00020000
#define OMAPFB_CAPS_WINDOW_OVERLAY 0x00040000
#define OMAPFB_CAPS_WINDOW_ROTATE 0x00080000
#define OMAPFB_CAPS_SET_BACKLIGHT 0x01000000
/* Values from DSP must map to lower 16-bits */
#define OMAPFB_FORMAT_MASK 0x00ff
#define OMAPFB_FORMAT_FLAG_DOUBLE 0x0100
#define OMAPFB_FORMAT_FLAG_TEARSYNC 0x0200
#define OMAPFB_FORMAT_FLAG_FORCE_VSYNC 0x0400
#define OMAPFB_FORMAT_FLAG_ENABLE_OVERLAY 0x0800
#define OMAPFB_FORMAT_FLAG_DISABLE_OVERLAY 0x1000
#define OMAPFB_EVENT_READY 1
#define OMAPFB_EVENT_DISABLED 2
#define OMAPFB_MEMTYPE_SDRAM 0
#define OMAPFB_MEMTYPE_SRAM 1
#define OMAPFB_MEMTYPE_MAX 1
enum omapfb_color_format {
OMAPFB_COLOR_RGB565 = 0,
OMAPFB_COLOR_YUV422,
OMAPFB_COLOR_YUV420,
OMAPFB_COLOR_CLUT_8BPP,
OMAPFB_COLOR_CLUT_4BPP,
OMAPFB_COLOR_CLUT_2BPP,
OMAPFB_COLOR_CLUT_1BPP,
OMAPFB_COLOR_RGB444,
OMAPFB_COLOR_YUY422,
OMAPFB_COLOR_ARGB16,
OMAPFB_COLOR_RGB24U, /* RGB24, 32-bit container */
OMAPFB_COLOR_RGB24P, /* RGB24, 24-bit container */
OMAPFB_COLOR_ARGB32,
OMAPFB_COLOR_RGBA32,
OMAPFB_COLOR_RGBX32,
};
struct omapfb_update_window {
__u32 x, y;
__u32 width, height;
__u32 format;
__u32 out_x, out_y;
__u32 out_width, out_height;
__u32 reserved[8];
};
struct omapfb_update_window_old {
__u32 x, y;
__u32 width, height;
__u32 format;
};
enum omapfb_plane {
OMAPFB_PLANE_GFX = 0,
OMAPFB_PLANE_VID1,
OMAPFB_PLANE_VID2,
};
enum omapfb_channel_out {
OMAPFB_CHANNEL_OUT_LCD = 0,
OMAPFB_CHANNEL_OUT_DIGIT,
};
struct omapfb_plane_info {
__u32 pos_x;
__u32 pos_y;
__u8 enabled;
__u8 channel_out;
__u8 mirror;
__u8 reserved1;
__u32 out_width;
__u32 out_height;
__u32 reserved2[12];
};
struct omapfb_mem_info {
__u32 size;
__u8 type;
__u8 reserved[3];
};
struct omapfb_caps {
__u32 ctrl;
__u32 plane_color;
__u32 wnd_color;
};
enum omapfb_color_key_type {
OMAPFB_COLOR_KEY_DISABLED = 0,
OMAPFB_COLOR_KEY_GFX_DST,
OMAPFB_COLOR_KEY_VID_SRC,
};
struct omapfb_color_key {
__u8 channel_out;
__u32 background;
__u32 trans_key;
__u8 key_type;
};
enum omapfb_update_mode {
OMAPFB_UPDATE_DISABLED = 0,
OMAPFB_AUTO_UPDATE,
OMAPFB_MANUAL_UPDATE
};
struct omapfb_memory_read {
__u16 x;
__u16 y;
__u16 w;
__u16 h;
size_t buffer_size;
void *buffer;
};
#ifdef __KERNEL__
#include <linux/completion.h>
#include <linux/interrupt.h>
#include <linux/fb.h>
#include <linux/mutex.h>
#include <mach/board.h>
#define OMAP_LCDC_INV_VSYNC 0x0001
#define OMAP_LCDC_INV_HSYNC 0x0002
#define OMAP_LCDC_INV_PIX_CLOCK 0x0004
#define OMAP_LCDC_INV_OUTPUT_EN 0x0008
#define OMAP_LCDC_HSVS_RISING_EDGE 0x0010
#define OMAP_LCDC_HSVS_OPPOSITE 0x0020
#define OMAP_LCDC_SIGNAL_MASK 0x003f
#define OMAP_LCDC_PANEL_TFT 0x0100
#define OMAPFB_PLANE_XRES_MIN 8
#define OMAPFB_PLANE_YRES_MIN 8
#ifdef CONFIG_ARCH_OMAP1
#define OMAPFB_PLANE_NUM 1
#else
#define OMAPFB_PLANE_NUM 3
#endif
struct omapfb_device;
struct lcd_panel {
const char *name;
int config; /* TFT/STN, signal inversion */
int bpp; /* Pixel format in fb mem */
int data_lines; /* Lines on LCD HW interface */
int x_res, y_res;
int pixel_clock; /* In kHz */
int hsw; /* Horizontal synchronization
pulse width */
int hfp; /* Horizontal front porch */
int hbp; /* Horizontal back porch */
int vsw; /* Vertical synchronization
pulse width */
int vfp; /* Vertical front porch */
int vbp; /* Vertical back porch */
int acb; /* ac-bias pin frequency */
int pcd; /* pixel clock divider.
Obsolete use pixel_clock instead */
int (*init) (struct lcd_panel *panel,
struct omapfb_device *fbdev);
void (*cleanup) (struct lcd_panel *panel);
int (*enable) (struct lcd_panel *panel);
void (*disable) (struct lcd_panel *panel);
unsigned long (*get_caps) (struct lcd_panel *panel);
int (*set_bklight_level)(struct lcd_panel *panel,
unsigned int level);
unsigned int (*get_bklight_level)(struct lcd_panel *panel);
unsigned int (*get_bklight_max) (struct lcd_panel *panel);
int (*run_test) (struct lcd_panel *panel, int test_num);
};
struct extif_timings {
int cs_on_time;
int cs_off_time;
int we_on_time;
int we_off_time;
int re_on_time;
int re_off_time;
int we_cycle_time;
int re_cycle_time;
int cs_pulse_width;
int access_time;
int clk_div;
u32 tim[5]; /* set by extif->convert_timings */
int converted;
};
struct lcd_ctrl_extif {
int (*init) (struct omapfb_device *fbdev);
void (*cleanup) (void);
void (*get_clk_info) (u32 *clk_period, u32 *max_clk_div);
unsigned long (*get_max_tx_rate)(void);
int (*convert_timings) (struct extif_timings *timings);
void (*set_timings) (const struct extif_timings *timings);
void (*set_bits_per_cycle)(int bpc);
void (*write_command) (const void *buf, unsigned int len);
void (*read_data) (void *buf, unsigned int len);
void (*write_data) (const void *buf, unsigned int len);
void (*transfer_area) (int width, int height,
void (callback)(void * data), void *data);
int (*setup_tearsync) (unsigned pin_cnt,
unsigned hs_pulse_time, unsigned vs_pulse_time,
int hs_pol_inv, int vs_pol_inv, int div);
int (*enable_tearsync) (int enable, unsigned line);
unsigned long max_transmit_size;
};
struct omapfb_notifier_block {
struct notifier_block nb;
void *data;
int plane_idx;
};
typedef int (*omapfb_notifier_callback_t)(struct notifier_block *,
unsigned long event,
void *fbi);
struct omapfb_mem_region {
u32 paddr;
void __iomem *vaddr;
unsigned long size;
u8 type; /* OMAPFB_PLANE_MEM_* */
enum omapfb_color_format format;/* OMAPFB_COLOR_* */
unsigned format_used:1; /* Must be set when format is set.
* Needed b/c of the badly chosen 0
* base for OMAPFB_COLOR_* values
*/
unsigned alloc:1; /* allocated by the driver */
unsigned map:1; /* kernel mapped by the driver */
};
struct omapfb_mem_desc {
int region_cnt;
struct omapfb_mem_region region[OMAPFB_PLANE_NUM];
};
struct lcd_ctrl {
const char *name;
void *data;
int (*init) (struct omapfb_device *fbdev,
int ext_mode,
struct omapfb_mem_desc *req_md);
void (*cleanup) (void);
void (*bind_client) (struct omapfb_notifier_block *nb);
void (*get_caps) (int plane, struct omapfb_caps *caps);
int (*set_update_mode)(enum omapfb_update_mode mode);
enum omapfb_update_mode (*get_update_mode)(void);
int (*setup_plane) (int plane, int channel_out,
unsigned long offset,
int screen_width,
int pos_x, int pos_y, int width,
int height, int color_mode);
int (*set_rotate) (int angle);
int (*setup_mem) (int plane, size_t size,
int mem_type, unsigned long *paddr);
int (*mmap) (struct fb_info *info,
struct vm_area_struct *vma);
int (*set_scale) (int plane,
int orig_width, int orig_height,
int out_width, int out_height);
int (*enable_plane) (int plane, int enable);
int (*update_window) (struct fb_info *fbi,
struct omapfb_update_window *win,
void (*callback)(void *),
void *callback_data);
void (*sync) (void);
void (*suspend) (void);
void (*resume) (void);
int (*run_test) (int test_num);
int (*setcolreg) (u_int regno, u16 red, u16 green,
u16 blue, u16 transp,
int update_hw_mem);
int (*set_color_key) (struct omapfb_color_key *ck);
int (*get_color_key) (struct omapfb_color_key *ck);
};
enum omapfb_state {
OMAPFB_DISABLED = 0,
OMAPFB_SUSPENDED= 99,
OMAPFB_ACTIVE = 100
};
struct omapfb_plane_struct {
int idx;
struct omapfb_plane_info info;
enum omapfb_color_format color_mode;
struct omapfb_device *fbdev;
};
struct omapfb_device {
int state;
int ext_lcdc; /* Using external
LCD controller */
struct mutex rqueue_mutex;
int palette_size;
u32 pseudo_palette[17];
struct lcd_panel *panel; /* LCD panel */
const struct lcd_ctrl *ctrl; /* LCD controller */
const struct lcd_ctrl *int_ctrl; /* internal LCD ctrl */
struct lcd_ctrl_extif *ext_if; /* LCD ctrl external
interface */
struct device *dev;
struct fb_var_screeninfo new_var; /* for mode changes */
struct omapfb_mem_desc mem_desc;
struct fb_info *fb_info[OMAPFB_PLANE_NUM];
};
struct omapfb_platform_data {
struct omap_lcd_config lcd;
struct omapfb_mem_desc mem_desc;
void *ctrl_platform_data;
};
#ifdef CONFIG_ARCH_OMAP1
extern struct lcd_ctrl omap1_lcd_ctrl;
#else
extern struct lcd_ctrl omap2_disp_ctrl;
#endif
extern void omapfb_set_platform_data(struct omapfb_platform_data *data);
extern void omapfb_reserve_sdram(void);
extern void omapfb_register_panel(struct lcd_panel *panel);
extern void omapfb_write_first_pixel(struct omapfb_device *fbdev, u16 pixval);
extern void omapfb_notify_clients(struct omapfb_device *fbdev,
unsigned long event);
extern int omapfb_register_client(struct omapfb_notifier_block *nb,
omapfb_notifier_callback_t callback,
void *callback_data);
extern int omapfb_unregister_client(struct omapfb_notifier_block *nb);
extern int omapfb_update_window_async(struct fb_info *fbi,
struct omapfb_update_window *win,
void (*callback)(void *),
void *callback_data);
/* in arch/arm/plat-omap/fb.c */
extern void omapfb_set_ctrl_platform_data(void *pdata);
#endif /* __KERNEL__ */
#endif /* __OMAPFB_H */

281
pandora/linux/xenv.c Normal file
View File

@ -0,0 +1,281 @@
/*
* (C) Gražvydas "notaz" Ignotas, 2009-2011
*
* This work is licensed under the terms of any of these licenses
* (at your option):
* - GNU GPL, version 2 or later.
* - GNU LGPL, version 2.1 or later.
* See the COPYING file in the top-level directory.
*/
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <dlfcn.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/XKBlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <termios.h>
#include <linux/kd.h>
#define PFX "xenv: "
#define FPTR(f) typeof(f) * p##f
#define FPTR_LINK(xf, dl, f) { \
xf.p##f = dlsym(dl, #f); \
if (xf.p##f == NULL) { \
fprintf(stderr, "missing symbol: %s\n", #f); \
goto fail; \
} \
}
struct xstuff {
Display *display;
FPTR(XCreateBitmapFromData);
FPTR(XCreatePixmapCursor);
FPTR(XFreePixmap);
FPTR(XOpenDisplay);
FPTR(XDisplayName);
FPTR(XCloseDisplay);
FPTR(XCreateSimpleWindow);
FPTR(XChangeWindowAttributes);
FPTR(XSelectInput);
FPTR(XMapWindow);
FPTR(XNextEvent);
FPTR(XCheckTypedEvent);
FPTR(XUnmapWindow);
FPTR(XGrabKeyboard);
FPTR(XPending);
FPTR(XLookupKeysym);
FPTR(XkbSetDetectableAutoRepeat);
};
static struct xstuff g_xstuff;
static Cursor transparent_cursor(struct xstuff *xf, Display *display, Window win)
{
Cursor cursor;
Pixmap pix;
XColor dummy;
char d = 0;
memset(&dummy, 0, sizeof(dummy));
pix = xf->pXCreateBitmapFromData(display, win, &d, 1, 1);
cursor = xf->pXCreatePixmapCursor(display, pix, pix,
&dummy, &dummy, 0, 0);
xf->pXFreePixmap(display, pix);
return cursor;
}
static int x11h_init(void)
{
unsigned int display_width, display_height;
Display *display;
XSetWindowAttributes attributes;
Window win;
Visual *visual;
void *x11lib;
int screen;
memset(&g_xstuff, 0, sizeof(g_xstuff));
x11lib = dlopen("libX11.so.6", RTLD_LAZY);
if (x11lib == NULL) {
fprintf(stderr, "libX11.so load failed:\n%s\n", dlerror());
goto fail;
}
FPTR_LINK(g_xstuff, x11lib, XCreateBitmapFromData);
FPTR_LINK(g_xstuff, x11lib, XCreatePixmapCursor);
FPTR_LINK(g_xstuff, x11lib, XFreePixmap);
FPTR_LINK(g_xstuff, x11lib, XOpenDisplay);
FPTR_LINK(g_xstuff, x11lib, XDisplayName);
FPTR_LINK(g_xstuff, x11lib, XCloseDisplay);
FPTR_LINK(g_xstuff, x11lib, XCreateSimpleWindow);
FPTR_LINK(g_xstuff, x11lib, XChangeWindowAttributes);
FPTR_LINK(g_xstuff, x11lib, XSelectInput);
FPTR_LINK(g_xstuff, x11lib, XMapWindow);
FPTR_LINK(g_xstuff, x11lib, XNextEvent);
FPTR_LINK(g_xstuff, x11lib, XCheckTypedEvent);
FPTR_LINK(g_xstuff, x11lib, XUnmapWindow);
FPTR_LINK(g_xstuff, x11lib, XGrabKeyboard);
FPTR_LINK(g_xstuff, x11lib, XPending);
FPTR_LINK(g_xstuff, x11lib, XLookupKeysym);
FPTR_LINK(g_xstuff, x11lib, XkbSetDetectableAutoRepeat);
//XInitThreads();
g_xstuff.display = display = g_xstuff.pXOpenDisplay(NULL);
if (display == NULL)
{
fprintf(stderr, "cannot connect to X server %s, X handling disabled.\n",
g_xstuff.pXDisplayName(NULL));
goto fail2;
}
visual = DefaultVisual(display, 0);
if (visual->class != TrueColor)
fprintf(stderr, PFX "warning: non true color visual\n");
printf(PFX "X vendor: %s, rel: %d, display: %s, protocol ver: %d.%d\n", ServerVendor(display),
VendorRelease(display), DisplayString(display), ProtocolVersion(display),
ProtocolRevision(display));
screen = DefaultScreen(display);
display_width = DisplayWidth(display, screen);
display_height = DisplayHeight(display, screen);
printf(PFX "display is %dx%d\n", display_width, display_height);
win = g_xstuff.pXCreateSimpleWindow(display,
RootWindow(display, screen),
0, 0, display_width, display_height, 0,
BlackPixel(display, screen),
BlackPixel(display, screen));
attributes.override_redirect = True;
attributes.cursor = transparent_cursor(&g_xstuff, display, win);
g_xstuff.pXChangeWindowAttributes(display, win, CWOverrideRedirect | CWCursor, &attributes);
g_xstuff.pXSelectInput(display, win, ExposureMask | FocusChangeMask | KeyPressMask | KeyReleaseMask);
g_xstuff.pXMapWindow(display, win);
g_xstuff.pXGrabKeyboard(display, win, False, GrabModeAsync, GrabModeAsync, CurrentTime);
g_xstuff.pXkbSetDetectableAutoRepeat(display, 1, NULL);
// XSetIOErrorHandler
return 0;
fail2:
dlclose(x11lib);
fail:
g_xstuff.display = NULL;
fprintf(stderr, "x11 handling disabled.\n");
return -1;
}
static int x11h_update(int *is_down)
{
XEvent evt;
while (g_xstuff.pXPending(g_xstuff.display))
{
g_xstuff.pXNextEvent(g_xstuff.display, &evt);
switch (evt.type)
{
case Expose:
while (g_xstuff.pXCheckTypedEvent(g_xstuff.display, Expose, &evt))
;
break;
case KeyPress:
*is_down = 1;
return g_xstuff.pXLookupKeysym(&evt.xkey, 0);
case KeyRelease:
*is_down = 0;
return g_xstuff.pXLookupKeysym(&evt.xkey, 0);
// printf("press %d\n", evt.xkey.keycode);
}
}
return NoSymbol;
}
static struct termios g_kbd_termios_saved;
static int g_kbdfd;
static int tty_init(void)
{
struct termios kbd_termios;
int mode;
g_kbdfd = open("/dev/tty", O_RDWR);
if (g_kbdfd == -1) {
perror(PFX "open /dev/tty");
return -1;
}
if (ioctl(g_kbdfd, KDGETMODE, &mode) == -1) {
perror(PFX "(not hiding FB): KDGETMODE");
goto fail;
}
if (tcgetattr(g_kbdfd, &kbd_termios) == -1) {
perror(PFX "tcgetattr");
goto fail;
}
g_kbd_termios_saved = kbd_termios;
kbd_termios.c_lflag &= ~(ICANON | ECHO); // | ISIG);
kbd_termios.c_iflag &= ~(ISTRIP | IGNCR | ICRNL | INLCR | IXOFF | IXON);
kbd_termios.c_cc[VMIN] = 0;
kbd_termios.c_cc[VTIME] = 0;
if (tcsetattr(g_kbdfd, TCSAFLUSH, &kbd_termios) == -1) {
perror(PFX "tcsetattr");
goto fail;
}
if (ioctl(g_kbdfd, KDSETMODE, KD_GRAPHICS) == -1) {
perror(PFX "KDSETMODE KD_GRAPHICS");
tcsetattr(g_kbdfd, TCSAFLUSH, &g_kbd_termios_saved);
goto fail;
}
return 0;
fail:
close(g_kbdfd);
g_kbdfd = -1;
return -1;
}
static void tty_end(void)
{
if (g_kbdfd <= 0)
return;
if (ioctl(g_kbdfd, KDSETMODE, KD_TEXT) == -1)
perror(PFX "KDSETMODE KD_TEXT");
if (tcsetattr(g_kbdfd, TCSAFLUSH, &g_kbd_termios_saved) == -1)
perror(PFX "tcsetattr");
close(g_kbdfd);
g_kbdfd = -1;
}
int xenv_init(void)
{
int ret;
ret = x11h_init();
if (ret == 0)
return 0;
ret = tty_init();
if (ret == 0)
return 0;
fprintf(stderr, PFX "error: both x11h_init and tty_init failed\n");
return -1;
}
int xenv_update(int *is_down)
{
if (g_xstuff.display)
return x11h_update(is_down);
// TODO: read tty?
return -1;
}
void xenv_finish(void)
{
// TODO: cleanup X?
tty_end();
}

5
pandora/linux/xenv.h Normal file
View File

@ -0,0 +1,5 @@
int xenv_init(void);
int xenv_update(int *is_down);
void xenv_finish(void);

315
pandora/pnd.c Normal file
View File

@ -0,0 +1,315 @@
/* gameplaySP - pandora backend
*
* Copyright (C) 2011 notaz <notasas@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "../common.h"
#include <X11/keysym.h>
#include "linux/omapfb.h" //
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include "linux/fbdev.h"
#include "linux/xenv.h"
enum gpsp_key {
GKEY_UP = 1 << 0,
GKEY_LEFT = 1 << 1,
GKEY_DOWN = 1 << 2,
GKEY_RIGHT = 1 << 3,
GKEY_START = 1 << 4,
GKEY_SELECT = 1 << 5,
GKEY_L = 1 << 6,
GKEY_R = 1 << 7,
GKEY_A = 1 << 8,
GKEY_B = 1 << 9,
GKEY_X = 1 << 10,
GKEY_Y = 1 << 11,
GKEY_1 = 1 << 12,
GKEY_2 = 1 << 13,
GKEY_3 = 1 << 14,
GKEY_4 = 1 << 15,
GKEY_MENU = 1 << 16,
};
u32 button_plat_mask_to_config[PLAT_BUTTON_COUNT] =
{
GKEY_UP,
GKEY_LEFT,
GKEY_DOWN,
GKEY_RIGHT,
GKEY_START,
GKEY_SELECT,
GKEY_L,
GKEY_R,
GKEY_A,
GKEY_B,
GKEY_X,
GKEY_Y,
GKEY_1,
GKEY_2,
GKEY_3,
GKEY_4,
GKEY_MENU,
};
u32 gamepad_config_map[PLAT_BUTTON_COUNT] =
{
BUTTON_ID_UP, // Up
BUTTON_ID_LEFT, // Left
BUTTON_ID_DOWN, // Down
BUTTON_ID_RIGHT, // Right
BUTTON_ID_START, // Start
BUTTON_ID_SELECT, // Select
BUTTON_ID_L, // Ltrigger
BUTTON_ID_R, // Rtrigger
BUTTON_ID_FPS, // A
BUTTON_ID_A, // B
BUTTON_ID_B, // X
BUTTON_ID_MENU, // Y
BUTTON_ID_SAVESTATE, // 1
BUTTON_ID_LOADSTATE, // 2
BUTTON_ID_FASTFORWARD, // 3
BUTTON_ID_NONE, // 4
BUTTON_ID_MENU // Space
};
static const u32 xk_to_gkey[] = {
XK_Up, XK_Left, XK_Down, XK_Right, XK_Alt_L, XK_Control_L,
XK_Shift_L, XK_Control_R, XK_Home, XK_End, XK_Page_Down, XK_Page_Up,
XK_1, XK_2, XK_3, XK_4, XK_space,
};
static const u8 gkey_to_cursor[32] = {
[0 ... 31] = CURSOR_NONE,
[0] = CURSOR_UP, CURSOR_LEFT, CURSOR_DOWN, CURSOR_RIGHT, CURSOR_NONE, CURSOR_NONE,
CURSOR_L, CURSOR_R, CURSOR_SELECT, CURSOR_SELECT, CURSOR_EXIT, CURSOR_BACK,
};
struct vout_fbdev *fb;
static int omap_setup_layer(int fd, int enabled, int x, int y, int w, int h, int first_call)
{
struct omapfb_plane_info pi = { 0, };
struct omapfb_mem_info mi = { 0, };
int ret;
ret = ioctl(fd, OMAPFB_QUERY_PLANE, &pi);
if (ret != 0) {
perror("QUERY_PLANE");
return -1;
}
ret = ioctl(fd, OMAPFB_QUERY_MEM, &mi);
if (ret != 0) {
perror("QUERY_MEM");
return -1;
}
/* must disable when changing stuff */
if (pi.enabled) {
pi.enabled = 0;
ret = ioctl(fd, OMAPFB_SETUP_PLANE, &pi);
if (ret != 0)
perror("SETUP_PLANE");
}
if (first_call) {
mi.size = 640*512*3*3;
ret = ioctl(fd, OMAPFB_SETUP_MEM, &mi);
if (ret != 0) {
perror("SETUP_MEM");
return -1;
}
}
pi.pos_x = x;
pi.pos_y = y;
pi.out_width = w;
pi.out_height = h;
pi.enabled = enabled;
ret = ioctl(fd, OMAPFB_SETUP_PLANE, &pi);
if (ret != 0) {
perror("SETUP_PLANE");
return -1;
}
return 0;
}
void gpsp_plat_init(void)
{
int ret, w, h, fd;
const char *layer_fb_name;
ret = SDL_Init(SDL_INIT_AUDIO | SDL_INIT_NOPARACHUTE);
if (ret != 0) {
fprintf(stderr, "SDL_Init failed: %s\n", SDL_GetError());
exit(1);
}
layer_fb_name = getenv("FBDEV_LAYER");
if (layer_fb_name == NULL)
layer_fb_name = "/dev/fb1";
ret = xenv_init();
if (ret != 0) {
fprintf(stderr, "xenv_init failed with %d\n", ret);
exit(1);
}
// must set the layer up first to be able to use it
fd = open(layer_fb_name, O_RDWR);
if (fd == -1) {
fprintf(stderr, "%s: ", layer_fb_name);
perror("open");
exit(1);
}
ret = omap_setup_layer(fd, 0, 0, 0, 400, 272, 1);
close(fd);
if (ret != 0) {
fprintf(stderr, "failed to set up layer, exiting.\n");
exit(1);
}
w = 240;
h = 160;
fb = vout_fbdev_init("/dev/fb1", &w, &h, 16, 4);
if (fb == NULL) {
fprintf(stderr, "vout_fbdev_init failed\n");
exit(1);
}
// default to 3x scale
screen_scale = 2;
}
void gpsp_plat_quit(void)
{
xenv_finish();
omap_setup_layer(vout_fbdev_get_fd(fb), 0, 0, 0, 0, 0, 0);
vout_fbdev_finish(fb);
SDL_Quit();
}
u32 gpsp_plat_joystick_read(void)
{
static int gkeystate;
int key, is_down, i;
int gkey = -1;
key = xenv_update(&is_down);
for (i = 0; i < sizeof(xk_to_gkey) / sizeof(xk_to_gkey[0]); i++) {
if (key == xk_to_gkey[i]) {
gkey = i;
break;
}
}
if (gkey >= 0) {
if (is_down)
gkeystate |= 1 << gkey;
else
gkeystate &= ~(1 << gkey);
}
return gkeystate;
}
u32 gpsp_plat_buttons_to_cursor(u32 buttons)
{
int i;
if (buttons == 0)
return CURSOR_NONE;
for (i = 0; (buttons & 1) == 0; i++, buttons >>= 1)
;
return gkey_to_cursor[i];
}
static void set_filter(int is_filtered)
{
static int was_filtered = -1;
char buf[128];
if (is_filtered == was_filtered)
return;
snprintf(buf, sizeof(buf), "sudo -n /usr/pandora/scripts/op_videofir.sh %s",
is_filtered ? "default" : "none");
system(buf);
was_filtered = is_filtered;
}
void *fb_flip_screen(void)
{
return vout_fbdev_flip(fb);
}
void fb_wait_vsync(void)
{
vout_fbdev_wait_vsync(fb);
}
void fb_set_mode(int w, int h, int buffers, int scale, int filter)
{
int lx, ly, lw = w, lh = h;
switch (scale) {
case 0:
lw = w;
lh = h;
break;
case 1:
lw = w * 2;
lh = h * 2;
break;
case 2:
lw = w * 3;
lh = h * 3;
break;
case 3:
lw = 800;
lh = 480;
break;
case 15:
lw = w * 2;
lh = h + h /2;
break;
default:
fprintf(stderr, "unknown scale: %d\n", scale);
break;
}
if (lw > 800)
lw = 800;
if (lh > 480)
lh = 480;
lx = 800 / 2 - lw / 2;
ly = 480 / 2 - lh / 2;
omap_setup_layer(vout_fbdev_get_fd(fb), 1, lx, ly, lw, lh, 0);
set_filter(filter);
vout_fbdev_resize(fb, w, h, 16, 0, 0, 0, 0, buffers);
}
// vim:shiftwidth=2:expandtab

12
pandora/pnd.h Normal file
View File

@ -0,0 +1,12 @@
void gpsp_plat_init(void);
void gpsp_plat_quit(void);
u32 gpsp_plat_joystick_read(void);
u32 gpsp_plat_buttons_to_cursor(u32 buttons);
#define PLAT_BUTTON_COUNT 17
extern u32 button_plat_mask_to_config[PLAT_BUTTON_COUNT];
void *fb_flip_screen(void);
void fb_set_mode(int w, int h, int buffers, int scale, int filter);
void fb_wait_vsync(void);

55
video.c
View File

@ -102,6 +102,16 @@ const u32 screen_pitch = 320;
#define get_screen_pitch() \
screen_pitch \
#elif defined(PND_BUILD)
static u16 *screen_pixels = NULL;
#define get_screen_pixels() \
screen_pixels \
#define get_screen_pitch() \
resolution_width \
#else
#ifdef GP2X_BUILD
@ -3392,6 +3402,13 @@ no_clean:
screen_pixels = (u16 *)gpsp_gp2x_screen + screen_offset;
}
#elif defined(PND_BUILD)
void flip_screen()
{
screen_pixels = fb_flip_screen();
}
#else
#define integer_scale_copy_2() \
@ -3601,7 +3618,7 @@ void init_video()
GE_CMD(NOP, 0);
}
#elif defined(WIZ_BUILD)
#elif defined(WIZ_BUILD) || defined(PND_BUILD)
void init_video()
{
@ -3796,6 +3813,42 @@ void clear_screen(u16 color)
*p++ = col;
}
#elif defined(PND_BUILD)
void video_resolution_large()
{
resolution_width = 400;
resolution_height = 272;
fb_set_mode(400, 272, 1, 15, screen_filter);
flip_screen();
clear_screen(0);
}
void video_resolution_small()
{
resolution_width = 240;
resolution_height = 160;
fb_set_mode(240, 160, 4, screen_scale, screen_filter);
flip_screen();
clear_screen(0);
}
void set_gba_resolution(video_scale_type scale)
{
screen_scale = scale;
}
void clear_screen(u16 color)
{
u32 col = ((u32)color << 16) | color;
u32 *p = (u32 *)get_screen_pixels();
int c = resolution_width * resolution_height / 2;
while (c-- > 0)
*p++ = col;
}
#else
void video_resolution_large()