// Pass in ratio... (for purchases) void t_dialog_marketplace::init_dialog( t_window* parent, t_adventure_frame* frame, std::string const& name_text, std::string const& intro_text, int market_efficiency_ratio ) { t_bitmap_layer const* layer; //t_window * window; t_window * background_window; t_screen_point origin(0,0); t_screen_point point(0,0); t_screen_rect rect; t_bitmap_group_ptr material_bitmaps_ptr = k_large_material_bitmaps.get(); int i; t_help_block const& material_help = get_help_block( "material_display" ); t_help_block const& help = get_help_block( "marketplace" ); m_player_ptr = &frame->get_map()->get_player(); m_player_funds = m_player_ptr->get_funds()[k_gold]; m_bitmaps_ptr = k_marketplace_bitmaps.get(); m_market_efficiency_ratio = market_efficiency_ratio; layer = m_bitmaps_ptr->find( "background" ); background_window = new t_bitmap_layer_window( layer, origin, this ); layer = m_bitmaps_ptr->find( "frame" ); rect = layer->get_rect(); m_player_frame = new t_bitmap_layer_window( layer, -rect.top_left(), this ); m_player_frame->set_visible( false ); m_player_frame->update_size(); layer = m_bitmaps_ptr->find( "frame" ); rect = layer->get_rect(); m_market_frame = new t_bitmap_layer_window( layer, -rect.top_left(), this ); m_market_frame->set_visible( false ); m_market_frame->update_size(); // Find wood frame (first item) - get diff for frame. t_screen_point frame_diff(0,0); point = m_bitmaps_ptr->find( "wood_icon" )->get_rect().top_left(); frame_diff = (point - rect.top_left()); /* ** Materials: */ std::string material_icon_text; for (i=0; i<k_material_count; i++) { // Player's material. material_icon_text = format_string ( "%s_icon", k_material_keyword[i] ); rect = m_bitmaps_ptr->find( material_icon_text )->get_rect(); m_player_button[i] = create_marketplace_player_button ( rect.top_left(), background_window, i, k_material_keyword[i], help ); m_player_button[i]->set_click_handler( add_2nd_argument( bound_handler( *this, &t_dialog_marketplace::player_material_clicked ), i)); m_player_frame_locations.push_back ( rect.top_left() - frame_diff ); // Market material. material_icon_text = format_string ( "%s_icon_2", k_material_keyword[i] ); rect = m_bitmaps_ptr->find( material_icon_text )->get_rect(); m_market_button[i] = create_marketplace_player_button ( rect.top_left(), background_window, i, format_string( "%s_%s", "available", k_material_keyword[i] ), help ); m_market_button[i]->set_click_handler( add_2nd_argument( bound_handler( *this, &t_dialog_marketplace::market_material_clicked ), i)); m_market_frame_locations.push_back ( rect.top_left() - frame_diff ); } /* ** Create buttons. */ t_button *button_ptr; t_button_handler button_handler; rect = m_bitmaps_ptr->find( "close_button" )->get_rect(); button_ptr = new t_button( g_ok_button.get(), rect.top_left(), this ); button_ptr->set_click_handler( bound_handler( *this, &t_dialog_marketplace::close_click )); set_help( button_ptr, help, "ok" ); /* ** Add buy button. */ point = m_bitmaps_ptr->find( "sell_button" )->get_rect().top_left() + origin; m_buy_button = new t_button( k_buy_button.get(), point, this ); button_handler = bound_handler( *this, &t_dialog_marketplace::buy_clicked ); m_buy_button->set_click_handler( button_handler ); set_help( m_buy_button, help, "purchase" ); m_buy_button->enable( false ); // Add max button. point = m_bitmaps_ptr->find( "max_button" )->get_rect().top_left() + origin; m_max_button = new t_button( g_max_button.get(), point, this ); button_handler = bound_handler( *this, &t_dialog_marketplace::max_clicked ); m_max_button->set_click_handler( button_handler ); set_help( m_max_button, help, "maximum" ); m_max_button->enable( false ); /* ** Add scrollbar. */ layer = m_bitmaps_ptr->find( "scrollbar" ); rect = layer->get_rect(); m_scrollbar = new t_scrollbar( rect.top_left(), rect.width(), this, 0, 0, false ); m_scrollbar->set_handler( bound_handler( *this, &t_dialog_marketplace::scrollbar_move)); m_scrollbar->set_position( 0 ); m_scrollbar->set_limits( 0, 0 ); /* ** Text windows. */ t_text_window* text_window_ptr; // Title. rect = m_bitmaps_ptr->find( "title" )->get_rect() + origin; text_window_ptr = new t_text_window( get_font( 20 ), rect, this, name_text, t_pixel_24(0,0,0)); text_window_ptr->set_center_horizontal(); text_window_ptr->set_drop_shadow( false ); // Intro text. rect = m_bitmaps_ptr->find( "text" )->get_rect() + origin; text_window_ptr = new t_text_window( get_font( 20 ), rect, this, intro_text, t_pixel_24(0,0,0)); text_window_ptr->set_center_horizontal(); text_window_ptr->set_drop_shadow( false ); std::string material_text_box; for (i=0; i<k_material_count; i++) { // Player's side. Kindgom amount. material_text_box = format_string ( "kingdom_%s", k_material_keyword[i] ); rect = m_bitmaps_ptr->find( material_text_box )->get_rect(); m_player_amount_text[i] = new t_text_window( get_font( 16 ), rect, this, "", t_pixel_24(0,0,0)); m_player_amount_text[i]->set_center_horizontal(); // Market exchange text. material_text_box = format_string ( "%s_exchange", k_material_keyword[i] ); rect = m_bitmaps_ptr->find( material_text_box )->get_rect(); m_market_exchange_text[i] = new t_text_window( get_font( 16 ), rect, this, "", t_pixel_24(0,0,0)); m_market_exchange_text[i]->set_center_horizontal(); } show_player_material_amount(); // Player quantity text. rect = m_bitmaps_ptr->find( "qty_selling" )->get_rect() + origin; m_player_quantity_text = new t_text_window( get_font( rect.height() ), rect, this, "", t_pixel_24(0,0,0)); m_player_quantity_text->set_center_horizontal(); m_player_quantity_text->set_drop_shadow( false ); // Market quantity text. rect = m_bitmaps_ptr->find( "exchange_rate" )->get_rect() + origin; m_market_quantity_text = new t_text_window( get_font( rect.height() ), rect, this, "", t_pixel_24(0,0,0)); m_market_quantity_text->set_center_horizontal(); m_market_quantity_text->set_drop_shadow( false ); show_exchange_rates(); /* ** Center the position and display the window. */ t_screen_rect parent_rect = get_parent()->get_client_rect(); rect = m_bitmaps_ptr->get_rect(); rect += (parent_rect.size() - rect.size()) / 2; init( rect ); }
bool GSRenderer::Merge(int field) { bool en[2]; GSVector4i fr[2]; GSVector4i dr[2]; GSVector2i display_baseline = { INT_MAX, INT_MAX }; GSVector2i frame_baseline = { INT_MAX, INT_MAX }; for(int i = 0; i < 2; i++) { en[i] = IsEnabled(i); if(en[i]) { fr[i] = GetFrameRect(i); dr[i] = GetDisplayRect(i); display_baseline.x = min(dr[i].left, display_baseline.x); display_baseline.y = min(dr[i].top, display_baseline.y); frame_baseline.x = min(fr[i].left, frame_baseline.x); frame_baseline.y = min(fr[i].top, frame_baseline.y); //printf("[%d]: %d %d %d %d, %d %d %d %d\n", i, fr[i].x,fr[i].y,fr[i].z,fr[i].w , dr[i].x,dr[i].y,dr[i].z,dr[i].w); } } if(!en[0] && !en[1]) { return false; } GL_PUSH("Renderer Merge %d (0: enabled %d 0x%x, 1: enabled %d 0x%x)", s_n, en[0], m_regs->DISP[0].DISPFB.Block(), en[1], m_regs->DISP[1].DISPFB.Block()); // try to avoid fullscreen blur, could be nice on tv but on a monitor it's like double vision, hurts my eyes (persona 4, guitar hero) // // NOTE: probably the technique explained in graphtip.pdf (Antialiasing by Supersampling / 4. Reading Odd/Even Scan Lines Separately with the PCRTC then Blending) bool samesrc = en[0] && en[1] && m_regs->DISP[0].DISPFB.FBP == m_regs->DISP[1].DISPFB.FBP && m_regs->DISP[0].DISPFB.FBW == m_regs->DISP[1].DISPFB.FBW && m_regs->DISP[0].DISPFB.PSM == m_regs->DISP[1].DISPFB.PSM; if(samesrc /*&& m_regs->PMODE.SLBG == 0 && m_regs->PMODE.MMOD == 1 && m_regs->PMODE.ALP == 0x80*/) { // persona 4: // // fr[0] = 0 0 640 448 // fr[1] = 0 1 640 448 // dr[0] = 159 50 779 498 // dr[1] = 159 50 779 497 // // second image shifted up by 1 pixel and blended over itself // // god of war: // // fr[0] = 0 1 512 448 // fr[1] = 0 0 512 448 // dr[0] = 127 50 639 497 // dr[1] = 127 50 639 498 // // same just the first image shifted // // These kinds of cases are now fixed by the more generic frame_diff code below, as the code here was too specific and has become obsolete. // NOTE: Persona 4 and God Of War are not rare exceptions, many games have the same(or very similar) offsets. int topDiff = fr[0].top - fr[1].top; if (dr[0].eq(dr[1]) && (fr[0].eq(fr[1] + GSVector4i(0, topDiff, 0, topDiff)) || fr[1].eq(fr[0] + GSVector4i(0, topDiff, 0, topDiff)))) { // dq5: // // fr[0] = 0 1 512 445 // fr[1] = 0 0 512 444 // dr[0] = 127 50 639 494 // dr[1] = 127 50 639 494 int top = min(fr[0].top, fr[1].top); int bottom = min(fr[0].bottom, fr[1].bottom); fr[0].top = fr[1].top = top; fr[0].bottom = fr[1].bottom = bottom; } } GSVector2i fs(0, 0); GSVector2i ds(0, 0); GSTexture* tex[3] = {NULL, NULL, NULL}; int y_offset[3] = {0, 0, 0}; s_n++; bool feedback_merge = m_regs->EXTWRITE.WRITE == 1; if(samesrc && fr[0].bottom == fr[1].bottom && !feedback_merge) { tex[0] = GetOutput(0, y_offset[0]); tex[1] = tex[0]; // saves one texture fetch y_offset[1] = y_offset[0]; } else { if(en[0]) tex[0] = GetOutput(0, y_offset[0]); if(en[1]) tex[1] = GetOutput(1, y_offset[1]); if(feedback_merge) tex[2] = GetFeedbackOutput(); } GSVector4 src[2]; GSVector4 src_hw[2]; GSVector4 dst[2]; for(int i = 0; i < 2; i++) { if(!en[i] || !tex[i]) continue; GSVector4i r = fr[i]; GSVector4 scale = GSVector4(tex[i]->GetScale()).xyxy(); src[i] = GSVector4(r) * scale / GSVector4(tex[i]->GetSize()).xyxy(); src_hw[i] = (GSVector4(r) + GSVector4 (0, y_offset[i], 0, y_offset[i])) * scale / GSVector4(tex[i]->GetSize()).xyxy(); GSVector2 off(0); GSVector2i display_diff(dr[i].left - display_baseline.x, dr[i].top - display_baseline.y); GSVector2i frame_diff(fr[i].left - frame_baseline.x, fr[i].top - frame_baseline.y); // Time Crisis 2/3 uses two side by side images when in split screen mode. // Though ignore cases where baseline and display rectangle offsets only differ by 1 pixel, causes blurring and wrong resolution output on FFXII if(display_diff.x > 2) { off.x = tex[i]->GetScale().x * display_diff.x; } // If the DX offset is too small then consider the status of frame memory offsets, prevents blurring on Tenchu: Fatal Shadows, Worms 3D else if(display_diff.x != frame_diff.x) { off.x = tex[i]->GetScale().x * frame_diff.x; } if(display_diff.y >= 4) // Shouldn't this be >= 2? { off.y = tex[i]->GetScale().y * display_diff.y; if(m_regs->SMODE2.INT && m_regs->SMODE2.FFMD) { off.y /= 2; } } else if(display_diff.y != frame_diff.y) { off.y = tex[i]->GetScale().y * frame_diff.y; } dst[i] = GSVector4(off).xyxy() + scale * GSVector4(r.rsize()); fs.x = max(fs.x, (int)(dst[i].z + 0.5f)); fs.y = max(fs.y, (int)(dst[i].w + 0.5f)); } ds = fs; if(m_regs->SMODE2.INT && m_regs->SMODE2.FFMD) { ds.y *= 2; } m_real_size = ds; bool slbg = m_regs->PMODE.SLBG; if(tex[0] || tex[1]) { if(tex[0] == tex[1] && !slbg && (src[0] == src[1] & dst[0] == dst[1]).alltrue()) { // the two outputs are identical, skip drawing one of them (the one that is alpha blended) tex[0] = NULL; } GSVector4 c = GSVector4((int)m_regs->BGCOLOR.R, (int)m_regs->BGCOLOR.G, (int)m_regs->BGCOLOR.B, (int)m_regs->PMODE.ALP) / 255; m_dev->Merge(tex, src_hw, dst, fs, m_regs->PMODE, m_regs->EXTBUF, c); if(m_regs->SMODE2.INT && m_interlace > 0) { if(m_interlace == 7 && m_regs->SMODE2.FFMD) // Auto interlace enabled / Odd frame interlace setting { int field2 = 0; int mode = 2; m_dev->Interlace(ds, field ^ field2, mode, tex[1] ? tex[1]->GetScale().y : tex[0]->GetScale().y); } else { int field2 = 1 - ((m_interlace - 1) & 1); int mode = (m_interlace - 1) >> 1; m_dev->Interlace(ds, field ^ field2, mode, tex[1] ? tex[1]->GetScale().y : tex[0]->GetScale().y); } } if(m_shadeboost) { m_dev->ShadeBoost(); } if(m_shaderfx) { m_dev->ExternalFX(); } if(m_fxaa) { m_dev->FXAA(); } } return true; }
int main (void) { cc3_histogram_pkt_t my_hist; cc3_color_info_pkt_t s_pkt; cc3_frame_diff_pkt_t fd_pkt; cc3_timer_wait_ms (500); cc3_gpio_set_mode (0, CC3_GPIO_MODE_SERVO); cc3_gpio_set_mode (1, CC3_GPIO_MODE_SERVO); cc3_gpio_set_mode (2, CC3_GPIO_MODE_SERVO); cc3_gpio_set_mode (3, CC3_GPIO_MODE_SERVO); // configure uarts cc3_uart_init (0, CC3_UART_RATE_115200, CC3_UART_MODE_8N1, CC3_UART_BINMODE_TEXT); cc3_uart_init (1, CC3_UART_RATE_38400,//CC3_UART_RATE_115200, CC3_UART_MODE_8N1, CC3_UART_BINMODE_BINARY); // Make it so that stdout and stdin are not buffered setvbuf (stdout, NULL, _IONBF, 0); setvbuf (stdin, NULL, _IONBF, 0); printf( "Opening UART1 file pointer\n" ); FILE *fp = cc3_uart_fopen(1, "r"); if (fp) { printf("Success"); int i = 0; while (1) { fprintf(fp, "i = %08d\n", i++); } } printf( "Calling camera init\n" ); cc3_camera_init (); cc3_camera_set_colorspace (CAM_COLOURS); cc3_camera_set_resolution (CAM_FORMAT); cc3_pixbuf_frame_set_coi (CC3_CHANNEL_ALL);//for full 'colour_info' //cc3_camera_set_colorspace (CC3_COLORSPACE_YCRCB);?All switches handled? //cc3_camera_set_resolution (CC3_CAMERA_RESOLUTION_HIGH);// 352, 288 //cc3_pixbuf_frame_set_subsample(CC3_SUBSAMPLE_RANDOM, 2, 2); printf( "Camera init done\n%d x %d\n", cc3_g_pixbuf_frame.raw_width, cc3_g_pixbuf_frame.raw_height ); // frame difference fd_pkt.coi = CC3_CHANNEL_ALL; fd_pkt.template_width = 16;//8; fd_pkt.template_height = 16;//8; fd_pkt.total_x = cc3_g_pixbuf_frame.width; fd_pkt.total_y = cc3_g_pixbuf_frame.height; fd_pkt.load_frame = 1; // load a new frame fd_pkt.previous_template = malloc (fd_pkt.template_width * fd_pkt.template_height * sizeof (uint32_t)); if (fd_pkt.previous_template == NULL) printf ("Malloc FD startup error!\r"); cc3_camera_set_auto_white_balance (true); cc3_camera_set_auto_exposure (true); // The LED test masks the stabilization delays (~2000ms) printf ("Waiting for image to stabilize\n"); led_test (); cc3_camera_set_auto_white_balance (false); cc3_camera_set_auto_exposure (false); // printf ("\nPush button on camera back to continue\n"); // while (!cc3_button_get_state ()) // ; cc3_led_set_state (0, true); cc3_pixbuf_load (); my_hist.channel = CC3_CHANNEL_ALL; my_hist.bins = 24; my_hist.hist = malloc (my_hist.bins * sizeof (uint32_t)); while (true) { printf ("<3 EE\n 0x%02X\n ", (unsigned int)cc3_timer_get_current_ms()); // Grab an image and take a frame difference of it cc3_pixbuf_load (); frame_diff (&fd_pkt); // Rewind and take a histogram of it cc3_pixbuf_rewind (); //get_histogram (&my_hist); // Rewind and get some stats cc3_pixbuf_rewind (); get_mean(&s_pkt); printf( "min = [%d,%d,%d] mean = [%d,%d,%d] max = [%d,%d,%d] deviation = [%d,%d,%d] ", s_pkt.min.channel[0],s_pkt.min.channel[1],s_pkt.min.channel[2], s_pkt.mean.channel[0],s_pkt.mean.channel[1],s_pkt.mean.channel[2], s_pkt.max.channel[0],s_pkt.max.channel[1],s_pkt.max.channel[2], s_pkt.deviation.channel[0],s_pkt.deviation.channel[1],s_pkt.deviation.channel[2] ); /* printf ("hist[%d] = ", my_hist.bins); for (uint32_t i = 0; i < my_hist.bins; i++) { printf ("%08X ", my_hist.hist[i]); // sample non-blocking serial routine if (!cc3_uart_has_data (1)) { cc3_gpio_set_servo_position (0, SERVO_MID); cc3_gpio_set_servo_position (1, SERVO_MID); } } */ printf ("\n"); cc3_timer_wait_ms(400); // if (cc3_button_get_state()) // break; } printf("\n\nAll done!\n"); return 0; }