static void *fb_vaddr[fb_buf_count];
static u32 fb_work_buf;
static int fb_buf_use;
+static int fbdev;
static void fb_video_init()
{
struct fb_fix_screeninfo fbfix;
int i, ret;
- int fbdev;
fbdev = open("/dev/fb0", O_RDWR);
if (fbdev < 0) {
printf("framebuffer: \"%s\" @ %08lx\n", fbfix.id, fbfix.smem_start);
fb_paddr[0] = fbfix.smem_start;
- close(fbdev);
fb_vaddr[0] = mmap(0, 320*240*2*fb_buf_count, PROT_READ|PROT_WRITE,
MAP_SHARED, gpsp_gp2x_dev, fb_paddr[0]);
void pollux_video_flip()
{
- warm_cache_op_all(WOP_D_CLEAN);
gpsp_gp2x_memregl[0x406C>>2] = fb_paddr[fb_work_buf];
gpsp_gp2x_memregl[0x4058>>2] |= 0x10;
fb_work_buf++;
memset(fb_vaddr[0], 0, 320*240*2*count);
}
+void wiz_lcd_set_portrait(int y)
+{
+ static int old_y = -1;
+ int cmd[2] = { 0, 0 };
+
+ if (old_y == y)
+ return;
+ cmd[0] = y ? 6 : 5;
+ ioctl(fbdev, _IOW('D', 90, int[2]), cmd);
+ gpsp_gp2x_memregl[0x4004>>2] = y ? 0x013f00ef : 0x00ef013f;
+ gpsp_gp2x_memregl[0x4000>>2] |= 1 << 3;
+ old_y = y;
+}
+
static void fb_video_exit()
{
- /* switch to default fb mem */
+ /* switch to default fb mem, turn portrait off */
gpsp_gp2x_memregl[0x406C>>2] = fb_paddr[0];
gpsp_gp2x_memregl[0x4058>>2] |= 0x10;
+ wiz_lcd_set_portrait(0);
+ close(fbdev);
+}
+
+static int wiz_gamepak_fd = -1;
+static u32 wiz_gamepak_size;
+
+static void wiz_gamepak_cleanup()
+{
+ if (wiz_gamepak_size)
+ munmap(gamepak_rom, wiz_gamepak_size);
+ if (wiz_gamepak_fd >= 0)
+ close(wiz_gamepak_fd);
+ gamepak_rom = NULL;
+ wiz_gamepak_size = 0;
+ wiz_gamepak_fd = -1;
}
+
+u32 wiz_load_gamepak(char *name)
+{
+ char *dot_position = strrchr(name, '.');
+ u32 ret;
+
+ if (!strcasecmp(dot_position, ".zip"))
+ {
+ if (wiz_gamepak_fd >= 0)
+ {
+ wiz_gamepak_cleanup();
+ printf("switching to ROM malloc\n");
+ init_gamepak_buffer();
+ }
+ return load_file_zip(name);
+ }
+
+ if (wiz_gamepak_fd < 0)
+ {
+ extern void *gamepak_memory_map;
+ free(gamepak_rom);
+ free(gamepak_memory_map);
+ gamepak_memory_map = NULL;
+ printf("switching to ROM mmap\n");
+ }
+ else
+ wiz_gamepak_cleanup();
+
+ wiz_gamepak_fd = open(name, O_RDONLY|O_NOATIME, S_IRUSR);
+ if (wiz_gamepak_fd < 0)
+ {
+ perror("wiz_load_gamepak: open failed");
+ return -1;
+ }
+
+ ret = lseek(wiz_gamepak_fd, 0, SEEK_END);
+ wiz_gamepak_size = gamepak_ram_buffer_size = ret;
+
+ gamepak_rom = mmap(0, ret, PROT_READ, MAP_SHARED, wiz_gamepak_fd, 0);
+ if (gamepak_rom == MAP_FAILED)
+ {
+ perror("wiz_load_gamepak: mmap failed");
+ return -1;
+ }
+
+ return ret;
+}
+
#endif
static int get_romdir(char *buff, size_t size)
#ifdef WIZ_BUILD
close(gpsp_gp2x_gpiodev);
fb_video_exit();
+ wiz_gamepak_cleanup();
#endif
munmap((void *)gpsp_gp2x_memregl, 0x10000);
close(gpsp_gp2x_dev_audio);
fcloseall();
sync();
- chdir("/usr/gp2x");
- execl("gp2xmenu", "gp2xmenu", NULL);
+ exit(0);
}
void gp2x_sound_volume(u32 volume_up)
extern void *gpsp_gp2x_screen;
void fb_use_buffers(int count);
void pollux_video_flip();
+void wiz_lcd_set_portrait(int y);
+u32 wiz_load_gamepak(char *name);
+
+void do_rotated_blit(void *dst, void *linesx4, u32 y);
+void upscale_aspect_row(void *dst, void *linesx3, u32 row);
#endif
\r
Changelog:\r
\r
+0.9-2xb u5\r
+- Added portrait drawing modes. They eliminate tearing but are slightly\r
+ slower.\r
+- Added page scrolling in ROM browser with L/R.\r
+- 32MB ROM support fixed.\r
+\r
0.9-2xb u4 (unofficial notaz release, done on Exophase's request)\r
- Wiz port. No emulation related changes.\r
- Wiz: dropped SDL for video and hitting hardware directly (GPH SDL can't\r
- gpSP now comes with wARM, new kernel module+lib for ARM cache control\r
(replaces mmuhack).\r
- gpSP no longer invalidates whole icache after recompilation, might\r
- case minor speedup.\r
+ cause minor speedup.\r
\r
0.9-2xb u3 (unofficial notaz release, released with permission):\r
- Removed built-in CPU/LCD/RAM-Tweaker.\r
u32 chosen_file, chosen_dir;
u32 dialog_result = 1;
s32 return_value = 1;
- u32 current_file_selection;
- u32 current_file_scroll_value;
+ s32 current_file_selection;
+ s32 current_file_scroll_value;
u32 current_dir_selection;
u32 current_dir_scroll_value;
- u32 current_file_in_scroll;
+ s32 current_file_in_scroll;
u32 current_dir_in_scroll;
u32 current_file_number, current_dir_number;
u32 current_column = 0;
current_file_in_scroll++;
}
}
+ else
+ {
+ clear_screen(COLOR_BG);
+ current_file_selection = 0;
+ current_file_scroll_value = 0;
+ current_file_in_scroll = 0;
+ }
}
else
{
break;
+ case CURSOR_R:
+ if (current_column != 0)
+ break;
+ clear_screen(COLOR_BG);
+ current_file_selection += FILE_LIST_ROWS;
+ if (current_file_selection > num_files - 1)
+ current_file_selection = num_files - 1;
+ current_file_scroll_value = current_file_selection - FILE_LIST_ROWS / 2;
+ if (current_file_scroll_value < 0)
+ {
+ current_file_scroll_value = 0;
+ current_file_in_scroll = current_file_selection;
+ }
+ else
+ {
+ current_file_in_scroll = FILE_LIST_ROWS / 2;
+ }
+ break;
+
case CURSOR_UP:
if(current_column == 0)
{
current_file_in_scroll--;
}
}
+ else
+ {
+ clear_screen(COLOR_BG);
+ current_file_selection = num_files - 1;
+ current_file_in_scroll = FILE_LIST_ROWS - 1;
+ if (current_file_in_scroll > num_files - 1)
+ current_file_in_scroll = num_files - 1;
+ current_file_scroll_value = num_files - FILE_LIST_ROWS;
+ if (current_file_scroll_value < 0)
+ current_file_scroll_value = 0;
+ }
}
else
{
}
break;
- case CURSOR_RIGHT:
+ case CURSOR_L:
+ if (current_column != 0)
+ break;
+ clear_screen(COLOR_BG);
+ current_file_selection -= FILE_LIST_ROWS;
+ if (current_file_selection < 0)
+ current_file_selection = 0;
+ current_file_scroll_value = current_file_selection - FILE_LIST_ROWS / 2;
+ if (current_file_scroll_value < 0)
+ {
+ current_file_scroll_value = 0;
+ current_file_in_scroll = current_file_selection;
+ }
+ else
+ {
+ current_file_in_scroll = FILE_LIST_ROWS / 2;
+ }
+ break;
+
+ case CURSOR_RIGHT:
if(current_column == 0)
{
if(num_dirs != 0)
{
memset(snapshot_buffer, 0, 240 * 160 * 2);
print_string_ext("No savestate exists for this slot.",
- 0xFFFF, 0x0000, 15, 75, snapshot_buffer, 240, 0);
+ 0xFFFF, 0x0000, 15, 75, snapshot_buffer, 240, 0, 0, FONT_HEIGHT);
print_string("---------- --/--/---- --:--:-- ", COLOR_HELP_TEXT,
COLOR_BG, 10, 40);
}
u8 *scale_options[] =
{
#ifdef WIZ_BUILD
- "unscaled 3:2", "scaled 3:2 (slower)"
+ "unscaled 3:2", "scaled 3:2 (slower)",
+ "unscaled 3:2 (anti-tear)", "scaled 3:2 (anti-tear)"
#else
"unscaled 3:2", "scaled 3:2", "fullscreen"
#ifdef PSP_BUILD
{
string_selection_option(NULL, "Display scaling", scale_options,
(u32 *)(&screen_scale),
-#ifdef WIZ_BUILD
- 2,
-#else
- 3,
-#endif
+ 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"
first_load = 1;
memset(original_screen, 0x00, 240 * 160 * 2);
print_string_ext("No game loaded yet.", 0xFFFF, 0x0000,
- 60, 75,original_screen, 240, 0);
+ 60, 75,original_screen, 240, 0, 0, FONT_HEIGHT);
}
choose_menu(&main_menu);
if(display_option == current_option)
{
print_string_pad(line_buffer, COLOR_ACTIVE_ITEM, COLOR_BG, 10,
- (display_option->line_number * 10) + 40, 36);
+ (display_option->line_number * 10) + 40, 41);
}
else
{
print_string_pad(line_buffer, COLOR_INACTIVE_ITEM, COLOR_BG, 10,
- (display_option->line_number * 10) + 40, 36);
+ (display_option->line_number * 10) + 40, 41);
}
}
if(new_buttons & GP2X_RIGHT)
new_button = CURSOR_RIGHT;
+ if(new_buttons & GP2X_L)
+ new_button = CURSOR_L;
+
+ if(new_buttons & GP2X_R)
+ new_button = CURSOR_R;
+
if(new_button != CURSOR_NONE)
{
CURSOR_SELECT,
CURSOR_BACK,
CURSOR_EXIT,
+ CURSOR_L,
+ CURSOR_R,
CURSOR_NONE
} gui_action_type;
event_number++;
}
+static u32 fps = 60;
+static u32 frames_drawn = 60;
+
u32 update_gba()
{
irq_type irq_raised = IRQ_NONE;
continue;
update_gbc_sound(cpu_ticks);
- synchronize();
+
+ if(gp2x_fps_debug)
+ {
+ char print_buffer[32];
+ sprintf(print_buffer, "%d (%d)", fps, frames_drawn);
+ print_string(print_buffer, 0xFFFF, 0x000, 0, 0);
+ }
update_screen();
+ synchronize();
+
if(update_backup_flag)
update_backup();
u32 interval_skipped_frames;
u32 frames;
-u32 skipped_frames = 0;
-u32 ticks_needed_total = 0;
const u32 frame_interval = 60;
void synchronize()
{
u64 new_ticks;
u64 time_delta;
- static u32 fps = 60;
- static u32 frames_drawn = 60;
-
- if(gp2x_fps_debug)
- {
- char print_buffer[128];
- sprintf(print_buffer, "%d (%d)", fps, frames_drawn);
- print_string(print_buffer, 0xFFFF, 0x000, 0, 0);
- }
get_ticks_us(&new_ticks);
time_delta = new_ticks - last_screen_timestamp;
last_screen_timestamp = new_ticks;
- ticks_needed_total += time_delta;
skip_next_frame = 0;
virtual_frame_count++;
num_skipped_frames = 0;
}
}
- else
- {
- if((synchronize_flag) &&
- ((time_delta < frame_speed) && synchronize_flag))
- {
- delay_us(frame_speed - time_delta);
- }
- }
frames++;
last_frame_interval_timestamp = new_ticks;
interval_skipped_frames = 0;
- ticks_needed_total = 0;
frames = 0;
}
#include "common.h"
-u32 load_file_zip(u8 *filename);
-
// This table is configured for sequential access on system defaults
u32 waitstate_cycles_sequential[16][3] =
s32 file_size;
u8 cheats_filename[256];
+#ifdef WIZ_BUILD
+ file_size = wiz_load_gamepak(name);
+#else
if(!strcmp(dot_position, ".zip"))
file_size = load_file_zip(name);
else
file_size = load_gamepak_raw(name);
+#endif
// A dumb April fool's joke was here once :o
#elif defined(WIZ_BUILD)
+static u16 rot_buffer[240*4];
+static u32 rot_lines_total = 4;
+static u32 rot_line_count = 0;
+static char rot_msg_buff[64];
+
static u32 screen_offset = 0;
static u16 *screen_pixels = NULL;
const u32 screen_pitch = 320;
if(skip_next_frame)
return;
+#ifdef WIZ_BUILD
+ if (screen_scale == unscaled_rot || screen_scale == scaled_aspect_rot)
+ {
+ if (rot_line_count == rot_lines_total)
+ {
+ rot_line_count = 0;
+ if (vcount - rot_lines_total < FONT_HEIGHT && rot_msg_buff[0])
+ {
+ print_string_ext(rot_msg_buff, 0xFFFF, 0x0000, 0, 0,
+ rot_buffer, 240, 0, vcount - rot_lines_total, rot_lines_total);
+ if (vcount >= FONT_HEIGHT)
+ rot_msg_buff[0] = 0;
+ }
+ if (screen_scale == unscaled_rot)
+ do_rotated_blit(gpsp_gp2x_screen, rot_buffer, vcount);
+ else
+ upscale_aspect_row(gpsp_gp2x_screen, rot_buffer, vcount/3);
+ }
+ screen_offset = &rot_buffer[rot_line_count++ * 240];
+ }
+#endif
+
// If the screen is in in forced blank draw pure white.
if(dispcnt & 0x80)
{
void flip_screen()
{
- if((screen_scale == scaled_aspect) &&
- (resolution_width == small_resolution_width) &&
+ if((resolution_width == small_resolution_width) &&
(resolution_height == small_resolution_height))
{
- upscale_aspect(gpsp_gp2x_screen, screen_pixels);
+ switch(screen_scale)
+ {
+ case scaled_aspect:
+ upscale_aspect(gpsp_gp2x_screen, screen_pixels);
+ break;
+ case unscaled_rot:
+ do_rotated_blit(gpsp_gp2x_screen, rot_buffer, 160);
+ rot_line_count = 0;
+ goto no_clean;
+ case scaled_aspect_rot:
+ rot_line_count = 0;
+ goto no_clean;
+ }
}
+ warm_cache_op_all(WOP_D_CLEAN);
+
+no_clean:
pollux_video_flip();
screen_pixels = (u16 *)gpsp_gp2x_screen + screen_offset;
}
fb_use_buffers(1);
flip_screen();
clear_screen(0);
+ wiz_lcd_set_portrait(0);
}
void video_resolution_small()
{
- if(screen_scale == scaled_aspect)
- screen_offset = 320*(80 - 14) + 80;
- else
- screen_offset = 320*40 + 40;
- resolution_width = 240;
- resolution_height = 160;
-
fb_use_buffers(4);
+
+ switch (screen_scale)
+ {
+ case unscaled:
+ screen_offset = 320*40 + 40;
+ wiz_lcd_set_portrait(0);
+ break;
+ case scaled_aspect:
+ screen_offset = 320*(80 - 14) + 80;
+ wiz_lcd_set_portrait(0);
+ break;
+ case unscaled_rot:
+ wiz_lcd_set_portrait(1);
+ rot_lines_total = 4;
+ rot_line_count = 0;
+ break;
+ case scaled_aspect_rot:
+ wiz_lcd_set_portrait(1);
+ rot_lines_total = 3;
+ rot_line_count = 0;
+ break;
+ }
+
flip_screen();
clear_screen(0);
+
+ resolution_width = 240;
+ resolution_height = 160;
}
void set_gba_resolution(video_scale_type scale)
}
void print_string_ext(const char *str, u16 fg_color, u16 bg_color,
- u32 x, u32 y, void *_dest_ptr, u32 pitch, u32 pad)
+ u32 x, u32 y, void *_dest_ptr, u32 pitch, u32 pad, u32 h_offset, u32 height)
{
u16 *dest_ptr = (u16 *)_dest_ptr + (y * pitch) + x;
u8 current_char = str[0];
u32 current_row;
u32 glyph_offset;
- u32 i = 0, i2, i3;
+ u32 i = 0, i2, i3, h;
u32 str_index = 1;
u32 current_x = x;
-
- /* EDIT */
- if(y + FONT_HEIGHT > resolution_height)
+ if(y + height > resolution_height)
return;
while(current_char)
{
glyph_offset = _font_offset[current_char];
current_x += FONT_WIDTH;
- for(i2 = 0; i2 < FONT_HEIGHT; i2++, glyph_offset++)
+ glyph_offset += h_offset;
+ for(i2 = h_offset, h = 0; i2 < FONT_HEIGHT && h < height; i2++, h++, glyph_offset++)
{
current_row = _font_bits[glyph_offset];
for(i3 = 0; i3 < FONT_WIDTH; i3++)
}
dest_ptr += (pitch - FONT_WIDTH);
}
- dest_ptr = dest_ptr - (pitch * FONT_HEIGHT) + FONT_WIDTH;
+ dest_ptr = dest_ptr - (pitch * h) + FONT_WIDTH;
}
i++;
void print_string(const char *str, u16 fg_color, u16 bg_color,
u32 x, u32 y)
{
+#ifdef WIZ_BUILD
+ if ((screen_scale == unscaled_rot || screen_scale == scaled_aspect_rot) &&
+ (resolution_width == small_resolution_width) &&
+ (resolution_height == small_resolution_height))
+ {
+ snprintf(rot_msg_buff, sizeof(rot_msg_buff), "%s", str);
+ return;
+ }
+#endif
print_string_ext(str, fg_color, bg_color, x, y, get_screen_pixels(),
- get_screen_pitch(), 0);
+ get_screen_pitch(), 0, 0, FONT_HEIGHT);
}
void print_string_pad(const char *str, u16 fg_color, u16 bg_color,
u32 x, u32 y, u32 pad)
{
print_string_ext(str, fg_color, bg_color, x, y, get_screen_pixels(),
- get_screen_pitch(), pad);
+ get_screen_pitch(), pad, 0, FONT_HEIGHT);
}
u32 debug_cursor_x = 0;
void print_string_pad(const char *str, u16 fg_color, u16 bg_color,
u32 x, u32 y, u32 pad);
void print_string_ext(const char *str, u16 fg_color, u16 bg_color,
- u32 x, u32 y, void *_dest_ptr, u32 pitch, u32 pad);
+ u32 x, u32 y, void *_dest_ptr, u32 pitch, u32 pad,
+ u32 h_offset, u32 height);
void clear_screen(u16 color);
void blit_to_screen(u16 *src, u32 w, u32 h, u32 x, u32 y);
u16 *copy_screen();
{
unscaled,
scaled_aspect,
+#ifndef WIZ_BUILD
fullscreen,
+#endif
+ unscaled_rot,
+ scaled_aspect_rot,
} video_scale_type;
typedef enum
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef COMMON_H
-#define COMMON_H
+#ifndef ZIP_H
+#define ZIP_H
u32 load_file_zip(char *filename);