INLINE void render_quad(sdl_info *sdl, texture_info *texture, render_primitive *prim, int x, int y) { SDL_Texture *texture_id; SDL_Rect target_rect; target_rect.x = x; target_rect.y = y; target_rect.w = round_nearest(prim->bounds.x1 - prim->bounds.x0); target_rect.h = round_nearest(prim->bounds.y1 - prim->bounds.y0); if (texture) { texture_id = texture->texture_id; texture->copyinfo->time -= osd_ticks(); #if 0 if ((PRIMFLAG_GET_SCREENTEX(prim->flags)) && video_config.filter) { SDL_SetTextureScaleMode(texture->texture_id, DRAW2_SCALEMODE_BEST); } else { SDL_SetTextureScaleMode(texture->texture_id, DRAW2_SCALEMODE_NEAREST); } #endif SDL_SetTextureBlendMode(texture_id, texture->sdl_blendmode); set_coloralphamode(texture_id, &prim->color); SDL_RenderCopy(sdl->sdl_renderer, texture_id, NULL, &target_rect); texture->copyinfo->time += osd_ticks(); texture->copyinfo->pixel_count += MAX(STAT_PIXEL_THRESHOLD , (texture->rawwidth * texture->rawheight)); if (sdl->last_blit_pixels) { texture->copyinfo->time += (sdl->last_blit_time * (INT64) (texture->rawwidth * texture->rawheight)) / (INT64) sdl->last_blit_pixels; } texture->copyinfo->samples++; texture->copyinfo->perf = ( texture->copyinfo->pixel_count * (osd_ticks_per_second()/1000)) / texture->copyinfo->time; } else { UINT32 sr = (UINT32)(255.0f * prim->color.r); UINT32 sg = (UINT32)(255.0f * prim->color.g); UINT32 sb = (UINT32)(255.0f * prim->color.b); UINT32 sa = (UINT32)(255.0f * prim->color.a); SDL_SetRenderDrawBlendMode(sdl->sdl_renderer, map_blendmode(PRIMFLAG_GET_BLENDMODE(prim->flags))); SDL_SetRenderDrawColor(sdl->sdl_renderer, sr, sg, sb, sa); SDL_RenderFillRect(sdl->sdl_renderer, &target_rect); } }
void texture_info::render_quad(const render_primitive &prim, const int x, const int y) { SDL_Rect target_rect; target_rect.x = x; target_rect.y = y; target_rect.w = round_nearest(prim.bounds.x1) - round_nearest(prim.bounds.x0); target_rect.h = round_nearest(prim.bounds.y1) - round_nearest(prim.bounds.y0); SDL_SetTextureBlendMode(m_texture_id, m_sdl_blendmode); set_coloralphamode(m_texture_id, &prim.color); //printf("%d %d %d %d\n", target_rect.x, target_rect.y, target_rect.w, target_rect.h); // Arghhh .. Just another bug. SDL_RenderCopy has severe issues with scaling ... SDL_RenderCopy(m_renderer->m_sdl_renderer, m_texture_id, nullptr, &target_rect); //SDL_RenderCopyEx(m_renderer->m_sdl_renderer, m_texture_id, nullptr, &target_rect, 0, nullptr, SDL_FLIP_NONE); //SDL_RenderCopyEx(m_renderer->m_sdl_renderer, m_texture_id, nullptr, nullptr, 0, nullptr, SDL_FLIP_NONE); }
void quad_setup_data::compute(const render_primitive &prim, const int prescale) { const render_quad_texuv *texcoords = &prim.texcoords; int texwidth = prim.texture.width; int texheight = prim.texture.height; float fdudx, fdvdx, fdudy, fdvdy; float width, height; float fscale; /* determine U/V deltas */ if ((PRIMFLAG_GET_SCREENTEX(prim.flags))) fscale = (float) prescale; else fscale = 1.0f; fdudx = (texcoords->tr.u - texcoords->tl.u); // a a11 fdvdx = (texcoords->tr.v - texcoords->tl.v); // c a21 fdudy = (texcoords->bl.u - texcoords->tl.u); // b a12 fdvdy = (texcoords->bl.v - texcoords->tl.v); // d a22 width = fabsf(( fdudx * (float) (texwidth) + fdvdx * (float) (texheight)) ) * fscale; height = fabsf((fdudy * (float) (texwidth) + fdvdy * (float) (texheight)) ) * fscale; fdudx = signf(fdudx) / fscale; fdvdy = signf(fdvdy) / fscale; fdvdx = signf(fdvdx) / fscale; fdudy = signf(fdudy) / fscale; #if 0 printf("tl.u %f tl.v %f\n", texcoords->tl.u, texcoords->tl.v); printf("tr.u %f tr.v %f\n", texcoords->tr.u, texcoords->tr.v); printf("bl.u %f bl.v %f\n", texcoords->bl.u, texcoords->bl.v); printf("br.u %f br.v %f\n", texcoords->br.u, texcoords->br.v); /* compute start and delta U,V coordinates now */ #endif dudx = round_nearest(65536.0f * fdudx); dvdx = round_nearest(65536.0f * fdvdx); dudy = round_nearest(65536.0f * fdudy); dvdy = round_nearest(65536.0f * fdvdy); startu = round_nearest(65536.0f * (float) texwidth * texcoords->tl.u); startv = round_nearest(65536.0f * (float) texheight * texcoords->tl.v); /* clamp to integers */ rotwidth = round_nearest(width); rotheight = round_nearest(height); //printf("%d %d rot %d %d\n", texwidth, texheight, rotwidth, rotheight); startu += (dudx + dudy) / 2; startv += (dvdx + dvdy) / 2; }
void renderer_sdl2::render_quad(texture_info *texture, const render_primitive &prim, const int x, const int y) { SDL_Rect target_rect; target_rect.x = x; target_rect.y = y; target_rect.w = round_nearest(prim.bounds.x1 - prim.bounds.x0); target_rect.h = round_nearest(prim.bounds.y1 - prim.bounds.y0); if (texture) { copy_info_t *copyinfo = texture->m_copyinfo; copyinfo->time -= osd_ticks(); texture->render_quad(prim, x, y); copyinfo->time += osd_ticks(); copyinfo->pixel_count += std::max(STAT_PIXEL_THRESHOLD , (texture->raw_width() * texture->raw_height())); if (m_last_blit_pixels) { copyinfo->time += (m_last_blit_time * (INT64) (texture->raw_width() * texture->raw_height())) / (INT64) m_last_blit_pixels; } copyinfo->samples++; copyinfo->perf = ( texture->m_copyinfo->pixel_count * (osd_ticks_per_second()/1000)) / texture->m_copyinfo->time; } else { UINT32 sr = (UINT32)(255.0f * prim.color.r); UINT32 sg = (UINT32)(255.0f * prim.color.g); UINT32 sb = (UINT32)(255.0f * prim.color.b); UINT32 sa = (UINT32)(255.0f * prim.color.a); SDL_SetRenderDrawBlendMode(m_sdl_renderer, map_blendmode(PRIMFLAG_GET_BLENDMODE(prim.flags))); SDL_SetRenderDrawColor(m_sdl_renderer, sr, sg, sb, sa); SDL_RenderFillRect(m_sdl_renderer, &target_rect); } }
int GetArcToSegmentCount( int aRadius, int aErrorMax, double aArcAngleDegree ) { // calculate the number of segments to approximate a circle by segments // given the max distance between the middle of a segment and the circle // error relative to the radius value: double rel_error = (double)aErrorMax / aRadius; // minimal arc increment in degrees: double arc_increment = 180 / M_PI * acos( 1.0 - rel_error ) * 2; // Ensure a minimal arc increment reasonable value for a circle // (360.0 degrees). For very small radius values, this is mandatory. arc_increment = std::min( 360.0/MIN_SEGCOUNT_FOR_CIRCLE, arc_increment ); int segCount = round_nearest( fabs( aArcAngleDegree ) / arc_increment ); // Ensure at least one segment is used (can happen for small arcs) return std::max( segCount, 1 ); }
static void compute_setup(sdl_info *sdl, const render_primitive *prim, quad_setup_data *setup, int flags) { const render_quad_texuv *texcoords = &prim->texcoords; int texwidth = prim->texture.width; int texheight = prim->texture.height; float fdudx, fdvdx, fdudy, fdvdy; float width, height; float fscale; /* determine U/V deltas */ if ((PRIMFLAG_GET_SCREENTEX(flags))) fscale = (float) video_config.prescale; else fscale = 1.0f; fdudx = (texcoords->tr.u - texcoords->tl.u) / fscale; // a a11 fdvdx = (texcoords->tr.v - texcoords->tl.v) / fscale; // c a21 fdudy = (texcoords->bl.u - texcoords->tl.u) / fscale; // b a12 fdvdy = (texcoords->bl.v - texcoords->tl.v) / fscale; // d a22 /* compute start and delta U,V coordinates now */ setup->dudx = round_nearest(65536.0f * fdudx); setup->dvdx = round_nearest(65536.0f * fdvdx); setup->dudy = round_nearest(65536.0f * fdudy); setup->dvdy = round_nearest(65536.0f * fdvdy); setup->startu = round_nearest(65536.0f * (float) texwidth * texcoords->tl.u); setup->startv = round_nearest(65536.0f * (float) texheight * texcoords->tl.v); /* clamp to integers */ width = fabs((fdudx * (float) (texwidth) + fdvdx * (float) (texheight)) * fscale * fscale); height = fabs((fdudy * (float)(texwidth) + fdvdy * (float) (texheight)) * fscale * fscale); setup->rotwidth = width; setup->rotheight = height; setup->startu += (setup->dudx + setup->dudy) / 2; setup->startv += (setup->dvdx + setup->dvdy) / 2; }
int renderer_sdl2::draw(int update) { texture_info *texture=nullptr; float vofs, hofs; int blit_pixels = 0; if (video_config.novideo) { return 0; } auto win = assert_window(); osd_dim wdim = win->get_size(); if (has_flags(FI_CHANGED) || (wdim.width() != m_width) || (wdim.height() != m_height)) { destroy_all_textures(); m_width = wdim.width(); m_height = wdim.height(); SDL_RenderSetViewport(m_sdl_renderer, nullptr); m_blittimer = 3; clear_flags(FI_CHANGED); } //SDL_SelectRenderer(window().sdl_window); if (m_blittimer > 0) { /* SDL Underlays need alpha = 0 ! */ SDL_SetRenderDrawBlendMode(m_sdl_renderer, SDL_BLENDMODE_NONE); //SDL_SetRenderDrawColor(0,0,0,255); SDL_SetRenderDrawColor(m_sdl_renderer, 0,0,0,0); SDL_RenderFillRect(m_sdl_renderer, nullptr); m_blittimer--; } // compute centering parameters vofs = hofs = 0.0f; if (video_config.centerv || video_config.centerh) { int ch, cw; ch = wdim.height(); cw = wdim.width(); if (video_config.centerv) { vofs = (ch - m_blit_dim.height()) / 2.0f; } if (video_config.centerh) { hofs = (cw - m_blit_dim.width()) / 2.0f; } } m_last_hofs = hofs; m_last_vofs = vofs; win->m_primlist->acquire_lock(); // now draw for (render_primitive &prim : *win->m_primlist) { Uint8 sr, sg, sb, sa; switch (prim.type) { case render_primitive::LINE: sr = (int)(255.0f * prim.color.r); sg = (int)(255.0f * prim.color.g); sb = (int)(255.0f * prim.color.b); sa = (int)(255.0f * prim.color.a); SDL_SetRenderDrawBlendMode(m_sdl_renderer, map_blendmode(PRIMFLAG_GET_BLENDMODE(prim.flags))); SDL_SetRenderDrawColor(m_sdl_renderer, sr, sg, sb, sa); SDL_RenderDrawLine(m_sdl_renderer, prim.bounds.x0 + hofs, prim.bounds.y0 + vofs, prim.bounds.x1 + hofs, prim.bounds.y1 + vofs); break; case render_primitive::QUAD: texture = texture_update(prim); if (texture) blit_pixels += (texture->raw_height() * texture->raw_width()); render_quad(texture, prim, round_nearest(hofs + prim.bounds.x0), round_nearest(vofs + prim.bounds.y0)); break; default: throw emu_fatalerror("Unexpected render_primitive type\n"); } } win->m_primlist->release_lock(); m_last_blit_pixels = blit_pixels; m_last_blit_time = -osd_ticks(); SDL_RenderPresent(m_sdl_renderer); m_last_blit_time += osd_ticks(); return 0; }
static int draw13_window_draw(sdl_window_info *window, UINT32 dc, int update) { sdl_info *sdl = (sdl_info *) window->dxdata; render_primitive *prim; texture_info *texture=NULL; float vofs, hofs; int blit_pixels = 0; if (video_config.novideo) { return 0; } if (sdl->resize_pending) { SDL_SetWindowSize(window->sdl_window, sdl->resize_width, sdl->resize_height); SDL_GetWindowSize(window->sdl_window, &window->width, &window->height); sdl->resize_pending = 0; SDL_RenderSetViewport(sdl->sdl_renderer, NULL); } //SDL_SelectRenderer(window->sdl_window); if (sdl->blittimer > 0) { /* SDL Underlays need alpha = 0 ! */ SDL_SetRenderDrawBlendMode(sdl->sdl_renderer, SDL_BLENDMODE_NONE); //SDL_SetRenderDrawColor(0,0,0,255); SDL_SetRenderDrawColor(sdl->sdl_renderer, 0,0,0,0); SDL_RenderFillRect(sdl->sdl_renderer, NULL); sdl->blittimer--; } // compute centering parameters vofs = hofs = 0.0f; if (video_config.centerv || video_config.centerh) { int ch, cw; if ((window->fullscreen) && (!video_config.switchres)) { ch = window->monitor->center_height; cw = window->monitor->center_width; } else { ch = window->height; cw = window->width; } if (video_config.centerv) { vofs = (ch - window->blitheight) / 2.0f; } if (video_config.centerh) { hofs = (cw - window->blitwidth) / 2.0f; } } sdl->last_hofs = hofs; sdl->last_vofs = vofs; window->primlist->acquire_lock(); // now draw for (prim = window->primlist->first(); prim != NULL; prim = prim->next()) { Uint8 sr, sg, sb, sa; switch (prim->type) { case render_primitive::LINE: sr = (int)(255.0f * prim->color.r); sg = (int)(255.0f * prim->color.g); sb = (int)(255.0f * prim->color.b); sa = (int)(255.0f * prim->color.a); SDL_SetRenderDrawBlendMode(sdl->sdl_renderer, map_blendmode(PRIMFLAG_GET_BLENDMODE(prim->flags))); SDL_SetRenderDrawColor(sdl->sdl_renderer, sr, sg, sb, sa); SDL_RenderDrawLine(sdl->sdl_renderer, prim->bounds.x0 + hofs, prim->bounds.y0 + vofs, prim->bounds.x1 + hofs, prim->bounds.y1 + vofs); break; case render_primitive::QUAD: texture = texture_update(window, prim); if (texture) blit_pixels += (texture->rawheight * texture->rawwidth); render_quad(sdl, texture, prim, round_nearest(hofs + prim->bounds.x0), round_nearest(vofs + prim->bounds.y0)); break; default: throw emu_fatalerror("Unexpected render_primitive type\n"); } } window->primlist->release_lock(); sdl->last_blit_pixels = blit_pixels; sdl->last_blit_time = -osd_ticks(); SDL_RenderPresent(sdl->sdl_renderer); sdl->last_blit_time += osd_ticks(); return 0; }
int Data::travel_time (int dist) { double const hours = ((double)dist) / ((double)(speed)); return round_nearest (hours * 60.0); }