From 42c8119010bfc48776e8c82e42cceb06d07c0247 Mon Sep 17 00:00:00 2001 From: notaz Date: Sat, 13 Jun 2009 22:19:53 +0300 Subject: [PATCH] u5 release --- gp2x/gp2x.c | 88 ++++++++++++++++++++++++++++++++--- gp2x/gp2x.h | 5 ++ gp2x/readme_gp2x.txt | 8 +++- gui.c | 81 ++++++++++++++++++++++++++------ input.c | 6 +++ input.h | 2 + main.c | 34 +++++--------- memory.c | 6 ++- video.c | 107 +++++++++++++++++++++++++++++++++++-------- video.h | 7 ++- zip.h | 4 +- 11 files changed, 281 insertions(+), 67 deletions(-) diff --git a/gp2x/gp2x.c b/gp2x/gp2x.c index 482eb17..6d9f82e 100644 --- a/gp2x/gp2x.c +++ b/gp2x/gp2x.c @@ -46,12 +46,12 @@ static u32 fb_paddr[fb_buf_count]; 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) { @@ -68,7 +68,6 @@ static void fb_video_init() 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]); @@ -95,7 +94,6 @@ static void fb_video_init() 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++; @@ -114,12 +112,90 @@ void fb_use_buffers(int count) 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) @@ -188,6 +264,7 @@ void gp2x_quit() #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); @@ -195,8 +272,7 @@ void gp2x_quit() fcloseall(); sync(); - chdir("/usr/gp2x"); - execl("gp2xmenu", "gp2xmenu", NULL); + exit(0); } void gp2x_sound_volume(u32 volume_up) diff --git a/gp2x/gp2x.h b/gp2x/gp2x.h index a801485..85cdac8 100644 --- a/gp2x/gp2x.h +++ b/gp2x/gp2x.h @@ -43,5 +43,10 @@ void upscale_aspect(u16 *dst, u16 *src); 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 diff --git a/gp2x/readme_gp2x.txt b/gp2x/readme_gp2x.txt index 04901a0..9a39fa5 100644 --- a/gp2x/readme_gp2x.txt +++ b/gp2x/readme_gp2x.txt @@ -12,6 +12,12 @@ not apply however). Changelog: +0.9-2xb u5 +- Added portrait drawing modes. They eliminate tearing but are slightly + slower. +- Added page scrolling in ROM browser with L/R. +- 32MB ROM support fixed. + 0.9-2xb u4 (unofficial notaz release, done on Exophase's request) - Wiz port. No emulation related changes. - Wiz: dropped SDL for video and hitting hardware directly (GPH SDL can't @@ -22,7 +28,7 @@ Changelog: - gpSP now comes with wARM, new kernel module+lib for ARM cache control (replaces mmuhack). - gpSP no longer invalidates whole icache after recompilation, might - case minor speedup. + cause minor speedup. 0.9-2xb u3 (unofficial notaz release, released with permission): - Removed built-in CPU/LCD/RAM-Tweaker. diff --git a/gui.c b/gui.c index ccaf764..f03aa49 100644 --- a/gui.c +++ b/gui.c @@ -140,11 +140,11 @@ s32 load_file(u8 **wildcards, u8 *result) 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; @@ -364,6 +364,13 @@ s32 load_file(u8 **wildcards, u8 *result) current_file_in_scroll++; } } + else + { + clear_screen(COLOR_BG); + current_file_selection = 0; + current_file_scroll_value = 0; + current_file_in_scroll = 0; + } } else { @@ -384,6 +391,25 @@ s32 load_file(u8 **wildcards, u8 *result) 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) { @@ -400,6 +426,17 @@ s32 load_file(u8 **wildcards, u8 *result) 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 { @@ -419,7 +456,26 @@ s32 load_file(u8 **wildcards, u8 *result) } 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) @@ -951,7 +1007,7 @@ void get_savestate_snapshot(u8 *savestate_filename) { 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); } @@ -1179,7 +1235,8 @@ u32 menu(u16 *original_screen) 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 @@ -1263,11 +1320,7 @@ u32 menu(u16 *original_screen) { 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" @@ -1581,7 +1634,7 @@ u32 menu(u16 *original_screen) 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); @@ -1627,12 +1680,12 @@ 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, 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); } } diff --git a/input.c b/input.c index 153e6ac..94c561d 100644 --- a/input.c +++ b/input.c @@ -412,6 +412,12 @@ gui_action_type get_gui_input() 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) { diff --git a/input.h b/input.h index e4bc519..1d0bd74 100644 --- a/input.h +++ b/input.h @@ -70,6 +70,8 @@ typedef enum CURSOR_SELECT, CURSOR_BACK, CURSOR_EXIT, + CURSOR_L, + CURSOR_R, CURSOR_NONE } gui_action_type; diff --git a/main.c b/main.c index 3bdc850..6e30605 100644 --- a/main.c +++ b/main.c @@ -494,6 +494,9 @@ void trigger_ext_event() event_number++; } +static u32 fps = 60; +static u32 frames_drawn = 60; + u32 update_gba() { irq_type irq_raised = IRQ_NONE; @@ -608,10 +611,18 @@ u32 update_gba() 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(); @@ -758,28 +769,16 @@ u32 num_skipped_frames = 0; 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++; @@ -802,14 +801,6 @@ void synchronize() num_skipped_frames = 0; } } - else - { - if((synchronize_flag) && - ((time_delta < frame_speed) && synchronize_flag)) - { - delay_us(frame_speed - time_delta); - } - } frames++; @@ -829,7 +820,6 @@ void synchronize() last_frame_interval_timestamp = new_ticks; interval_skipped_frames = 0; - ticks_needed_total = 0; frames = 0; } diff --git a/memory.c b/memory.c index e902af3..9a08df0 100644 --- a/memory.c +++ b/memory.c @@ -19,8 +19,6 @@ #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] = @@ -2158,10 +2156,14 @@ u32 load_gamepak(char *name) 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 diff --git a/video.c b/video.c index ada3fea..b857bf1 100644 --- a/video.c +++ b/video.c @@ -87,6 +87,11 @@ static void Ge_Finish_Callback(int id, void *arg) #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; @@ -3271,6 +3276,28 @@ void update_scanline() 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) { @@ -3338,12 +3365,26 @@ void flip_screen() 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; } @@ -3691,20 +3732,40 @@ void video_resolution_large() 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) @@ -3840,19 +3901,17 @@ void blit_to_screen(u16 *src, u32 w, u32 h, u32 dest_x, u32 dest_y) } 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) @@ -3867,7 +3926,8 @@ void print_string_ext(const char *str, u16 fg_color, u16 bg_color, { 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++) @@ -3880,7 +3940,7 @@ void print_string_ext(const char *str, u16 fg_color, u16 bg_color, } dest_ptr += (pitch - FONT_WIDTH); } - dest_ptr = dest_ptr - (pitch * FONT_HEIGHT) + FONT_WIDTH; + dest_ptr = dest_ptr - (pitch * h) + FONT_WIDTH; } i++; @@ -3909,15 +3969,24 @@ void print_string_ext(const char *str, u16 fg_color, u16 bg_color, 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; diff --git a/video.h b/video.h index 6be6b9c..cb717f2 100644 --- a/video.h +++ b/video.h @@ -30,7 +30,8 @@ void print_string(const char *str, u16 fg_color, u16 bg_color, 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(); @@ -76,7 +77,11 @@ typedef enum { unscaled, scaled_aspect, +#ifndef WIZ_BUILD fullscreen, +#endif + unscaled_rot, + scaled_aspect_rot, } video_scale_type; typedef enum diff --git a/zip.h b/zip.h index a63be6b..c562ece 100644 --- a/zip.h +++ b/zip.h @@ -17,8 +17,8 @@ * 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); -- 2.39.5