Mercurial > repos > blastem
comparison render_fbdev.c @ 1782:b2bffd98063d
Scale H32 horizontally in fbdev backend so it has the correct aspect ratio
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 10 Mar 2019 23:10:43 -0700 |
parents | 2b4d5cfec6d9 |
children | 8f2e78db0872 |
comparison
equal
deleted
inserted
replaced
1781:2b4d5cfec6d9 | 1782:b2bffd98063d |
---|---|
1082 #endif | 1082 #endif |
1083 static pthread_mutex_t buffer_lock = PTHREAD_MUTEX_INITIALIZER; | 1083 static pthread_mutex_t buffer_lock = PTHREAD_MUTEX_INITIALIZER; |
1084 static pthread_cond_t buffer_cond = PTHREAD_COND_INITIALIZER; | 1084 static pthread_cond_t buffer_cond = PTHREAD_COND_INITIALIZER; |
1085 static uint8_t buffer_ready; | 1085 static uint8_t buffer_ready; |
1086 static uint32_t *copy_buffer; | 1086 static uint32_t *copy_buffer; |
1087 static uint32_t last_width, last_height; | 1087 static uint32_t last_width, last_width_scale, last_height; |
1088 static uint32_t max_multiple; | 1088 static uint32_t max_multiple; |
1089 static void do_buffer_copy(void) | 1089 static void do_buffer_copy(void) |
1090 { | 1090 { |
1091 uint32_t width_multiple = main_width / last_width; | 1091 uint32_t width_multiple = main_width / last_width_scale; |
1092 uint32_t height_multiple = main_height / last_height; | 1092 uint32_t height_multiple = main_height / last_height; |
1093 uint32_t multiple = width_multiple < height_multiple ? width_multiple : height_multiple; | 1093 uint32_t multiple = width_multiple < height_multiple ? width_multiple : height_multiple; |
1094 if (max_multiple && multiple > max_multiple) { | 1094 if (max_multiple && multiple > max_multiple) { |
1095 multiple = max_multiple; | 1095 multiple = max_multiple; |
1096 } | 1096 } |
1097 uint32_t *cur_line = framebuffer + (main_width - last_width * multiple)/2; | 1097 uint32_t *cur_line = framebuffer + (main_width - last_width_scale * multiple)/2; |
1098 cur_line += fb_stride * (main_height - last_height * multiple) / (2 * sizeof(uint32_t)); | 1098 cur_line += fb_stride * (main_height - last_height * multiple) / (2 * sizeof(uint32_t)); |
1099 uint32_t *src_line = copy_buffer; | 1099 uint32_t *src_line = copy_buffer; |
1100 for (uint32_t y = 0; y < last_height; y++) | 1100 if (last_width == last_width_scale) { |
1101 { | 1101 for (uint32_t y = 0; y < last_height; y++) |
1102 for (uint32_t i = 0; i < multiple; i++) | |
1103 { | 1102 { |
1104 uint32_t *cur = cur_line; | 1103 for (uint32_t i = 0; i < multiple; i++) |
1105 uint32_t *src = src_line; | |
1106 for (uint32_t x = 0; x < last_width ; x++) | |
1107 { | 1104 { |
1108 uint32_t pixel = *(src++); | 1105 uint32_t *cur = cur_line; |
1109 for (uint32_t j = 0; j < multiple; j++) | 1106 uint32_t *src = src_line; |
1107 for (uint32_t x = 0; x < last_width ; x++) | |
1110 { | 1108 { |
1111 *(cur++) = pixel; | 1109 uint32_t pixel = *(src++); |
1110 for (uint32_t j = 0; j < multiple; j++) | |
1111 { | |
1112 *(cur++) = pixel; | |
1113 } | |
1112 } | 1114 } |
1113 } | 1115 |
1114 | 1116 cur_line += fb_stride / sizeof(uint32_t); |
1115 cur_line += fb_stride / sizeof(uint32_t); | 1117 } |
1116 } | 1118 src_line += LINEBUF_SIZE; |
1117 src_line += LINEBUF_SIZE; | 1119 } |
1120 } else { | |
1121 float scale_multiple = ((float)(last_width_scale * multiple)) / (float)last_width; | |
1122 float remaining = 0.0f; | |
1123 uint32_t last_pixel = 0; | |
1124 for (uint32_t y = 0; y < last_height; y++) | |
1125 { | |
1126 for (uint32_t i = 0; i < multiple; i++) | |
1127 { | |
1128 uint32_t *cur = cur_line; | |
1129 uint32_t *src = src_line; | |
1130 for (uint32_t x = 0; x < last_width ; x++) | |
1131 { | |
1132 uint32_t pixel = *(src++); | |
1133 float count = scale_multiple; | |
1134 if (remaining > 0.0f) { | |
1135 float a,b,c,d; | |
1136 a = (last_pixel & 255) * remaining; | |
1137 b = (last_pixel >> 8 & 255) * remaining; | |
1138 c = (last_pixel >> 16 & 255) * remaining; | |
1139 d = (last_pixel >> 24 & 255) * remaining; | |
1140 remaining = 1.0f - remaining; | |
1141 a += (pixel & 255) * remaining; | |
1142 b += (pixel >> 8 & 255) * remaining; | |
1143 c += (pixel >> 16 & 255) * remaining; | |
1144 d += (pixel >> 24 & 255) * remaining; | |
1145 count -= remaining; | |
1146 uint32_t mixed = ((int)d) << 24 | ((int)c) << 16 | ((int)b) << 8 | ((int)a); | |
1147 *(cur++) = mixed; | |
1148 } | |
1149 for (; count >= 1; count -= 1.0f) | |
1150 { | |
1151 *(cur++) = pixel; | |
1152 } | |
1153 remaining = count; | |
1154 last_pixel = pixel; | |
1155 } | |
1156 | |
1157 cur_line += fb_stride / sizeof(uint32_t); | |
1158 } | |
1159 src_line += LINEBUF_SIZE; | |
1160 } | |
1118 } | 1161 } |
1119 } | 1162 } |
1120 static void *buffer_copy(void *data) | 1163 static void *buffer_copy(void *data) |
1121 { | 1164 { |
1122 pthread_mutex_lock(&buffer_lock); | 1165 pthread_mutex_lock(&buffer_lock); |
1576 if (max_multiple != 1) { | 1619 if (max_multiple != 1) { |
1577 if (copy_use_thread) { | 1620 if (copy_use_thread) { |
1578 pthread_mutex_lock(&buffer_lock); | 1621 pthread_mutex_lock(&buffer_lock); |
1579 buffer_ready = 1; | 1622 buffer_ready = 1; |
1580 last_width = width; | 1623 last_width = width; |
1624 last_width_scale = LINEBUF_SIZE - (overscan_left[video_standard] + overscan_right[video_standard]); | |
1581 last_height = height; | 1625 last_height = height; |
1582 copy_buffer = texture_buf + texture_off + overscan_left[video_standard] + LINEBUF_SIZE * overscan_top[video_standard]; | 1626 copy_buffer = texture_buf + texture_off + overscan_left[video_standard] + LINEBUF_SIZE * overscan_top[video_standard]; |
1583 texture_off = texture_off ? 0 : LINEBUF_SIZE * 512; | 1627 texture_off = texture_off ? 0 : LINEBUF_SIZE * 512; |
1584 pthread_cond_signal(&buffer_cond); | 1628 pthread_cond_signal(&buffer_cond); |
1585 pthread_mutex_unlock(&buffer_lock); | 1629 pthread_mutex_unlock(&buffer_lock); |
1586 } else { | 1630 } else { |
1587 last_width = width; | 1631 last_width = width; |
1632 last_width_scale = LINEBUF_SIZE - (overscan_left[video_standard] + overscan_right[video_standard]); | |
1588 last_height = height; | 1633 last_height = height; |
1589 copy_buffer = texture_buf + texture_off + overscan_left[video_standard] + LINEBUF_SIZE * overscan_top[video_standard]; | 1634 copy_buffer = texture_buf + texture_off + overscan_left[video_standard] + LINEBUF_SIZE * overscan_top[video_standard]; |
1590 do_buffer_copy(); | 1635 do_buffer_copy(); |
1591 } | 1636 } |
1592 } | 1637 } |