summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Pavone <pavone@retrodev.com>2016-08-22 09:46:18 -0700
committerMichael Pavone <pavone@retrodev.com>2016-08-22 09:46:18 -0700
commit4a56a7e2dfe615e03e81e29952003291090470fe (patch)
treee2a7fc9bc4d4188f934d8dcd80afba0ec278c8a7
parent00c00b816bac8f05e49f4733ecbedd363b0b8da2 (diff)
Cleanup the separation of render backend and VDP code in preparation for having extra debug windows. Make determination of H40/H32 based on number of lines in each mode.
-rw-r--r--blastem.c4
-rw-r--r--gst.c3
-rw-r--r--io.c11
-rw-r--r--render.h13
-rwxr-xr-xrender_sdl.c241
-rw-r--r--vdp.c65
-rw-r--r--vdp.h13
7 files changed, 175 insertions, 175 deletions
diff --git a/blastem.c b/blastem.c
index 56f567f..085dd8c 100644
--- a/blastem.c
+++ b/blastem.c
@@ -272,9 +272,7 @@ m68k_context * sync_components(m68k_context * context, uint32_t address)
//printf("reached frame end %d | MCLK Cycles: %d, Target: %d, VDP cycles: %d, vcounter: %d, hslot: %d\n", last_frame_num, mclks, gen->frame_end, v_context->cycles, v_context->vcounter, v_context->hslot);
last_frame_num = v_context->frame;
- if (!headless) {
- break_on_sync |= wait_render_frame(v_context, frame_limit);
- } else if(exit_after){
+ if(exit_after){
--exit_after;
if (!exit_after) {
exit(0);
diff --git a/gst.c b/gst.c
index 7fadc18..2a56a4c 100644
--- a/gst.c
+++ b/gst.c
@@ -224,9 +224,6 @@ uint8_t vdp_load_gst(vdp_context * context, FILE * state_file)
return 0;
}
context->double_res = (context->regs[REG_MODE_4] & (BIT_INTERLACE | BIT_DOUBLE_RES)) == (BIT_INTERLACE | BIT_DOUBLE_RES);
- if (!context->double_res) {
- context->framebuf = context->oddbuf;
- }
latch_mode(context);
if (fread(tmp_buf, 1, CRAM_SIZE*2, state_file) != CRAM_SIZE*2) {
fputs("Failed to read CRAM from savestate\n", stderr);
diff --git a/io.c b/io.c
index 30783a9..acab08f 100644
--- a/io.c
+++ b/io.c
@@ -21,6 +21,7 @@
#include "util.h"
#define CYCLE_NEVER 0xFFFFFFFF
+#define MIN_POLL_INTERVAL 6840
const char * device_type_names[] = {
"3-button gamepad",
@@ -1146,6 +1147,7 @@ void mouse_check_ready(io_port *port, uint32_t current_cycle)
}
}
+uint32_t last_poll_cycle;
void io_adjust_cycles(io_port * port, uint32_t current_cycle, uint32_t deduction)
{
/*uint8_t control = pad->control | 0x80;
@@ -1167,6 +1169,11 @@ void io_adjust_cycles(io_port * port, uint32_t current_cycle, uint32_t deduction
port->device.mouse.ready_cycle -= deduction;
}
}
+ if (last_poll_cycle >= deduction) {
+ last_poll_cycle -= deduction;
+ } else {
+ last_poll_cycle = 0;
+ }
}
#ifndef _WIN32
@@ -1345,6 +1352,10 @@ uint8_t io_data_read(io_port * port, uint32_t current_cycle)
uint8_t output = (control & port->output) | (~control & 0xFF);
uint8_t th = output & 0x40;
uint8_t input;
+ if (current_cycle - last_poll_cycle > MIN_POLL_INTERVAL) {
+ process_events();
+ last_poll_cycle = current_cycle;
+ }
switch (port->device_type)
{
case IO_GAMEPAD3:
diff --git a/render.h b/render.h
index 7671c44..6b5eedb 100644
--- a/render.h
+++ b/render.h
@@ -50,19 +50,16 @@
#define MAX_MICE 8
#define MAX_MOUSE_BUTTONS 8
+#define FRAMEBUFFER_ODD 0
+#define FRAMEBUFFER_EVEN 1
+
#include "vdp.h"
#include "psg.h"
#include "ym2612.h"
-typedef struct {
- void *oddbuf;
- void *evenbuf;
- int stride;
-} surface_info;
-
uint32_t render_map_color(uint8_t r, uint8_t g, uint8_t b);
-void render_alloc_surfaces(vdp_context * context);
-void render_free_surfaces(vdp_context *context);
+uint32_t *render_get_framebuffer(uint8_t which, int *pitch);
+void render_framebuffer_updated(uint8_t which, int width);
void render_init(int width, int height, char * title, uint32_t fps, uint8_t fullscreen);
void render_update_caption(char *title);
void render_context(vdp_context * context);
diff --git a/render_sdl.c b/render_sdl.c
index a07d8cf..c2729aa 100755
--- a/render_sdl.c
+++ b/render_sdl.c
@@ -16,9 +16,12 @@
#include <GL/glew.h>
#endif
+#define MAX_EVENT_POLL_PER_FRAME 2
+
SDL_Window *main_window;
SDL_Renderer *main_renderer;
-SDL_Texture *main_texture;
+SDL_Texture **sdl_textures;
+uint8_t num_textures;
SDL_Rect main_clip;
SDL_GLContext *main_context;
@@ -168,19 +171,20 @@ GLuint load_shader(char * fname, GLenum shader_type)
}
#endif
-void render_alloc_surfaces(vdp_context * context)
+uint32_t texture_buf[512 * 256];
+void render_alloc_surfaces()
{
static uint8_t texture_init;
- context->oddbuf = context->framebuf = malloc(512 * 256 * 4 * 2);
- memset(context->oddbuf, 0, 512 * 256 * 4 * 2);
- context->evenbuf = ((char *)context->oddbuf) + 512 * 256 * 4;
if (texture_init) {
return;
}
+ sdl_textures= malloc(sizeof(SDL_Texture *) * 2);
+ num_textures = 2;
texture_init = 1;
#ifndef DISABLE_OPENGL
if (render_gl) {
+ sdl_textures[0] = sdl_textures[1] = NULL;
glGenTextures(3, textures);
for (int i = 0; i < 3; i++)
{
@@ -190,7 +194,7 @@ void render_alloc_surfaces(vdp_context * context)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
if (i < 2) {
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 512, 256, 0, GL_BGRA, GL_UNSIGNED_BYTE, i ? context->evenbuf : context->oddbuf);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 512, 256, 0, GL_BGRA, GL_UNSIGNED_BYTE, texture_buf);
} else {
uint32_t blank = 255 << 24;
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_BGRA, GL_UNSIGNED_BYTE, &blank);
@@ -221,27 +225,26 @@ void render_alloc_surfaces(vdp_context * context)
at_pos = glGetAttribLocation(program, "pos");
} else {
#endif
- /* height=480 to fit interlaced output */
- main_texture = SDL_CreateTexture(main_renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 320, 480);
+
+ //height=480 to fit interlaced output
+ sdl_textures[0] = sdl_textures[1] = SDL_CreateTexture(main_renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 320, 480);
#ifndef DISABLE_OPENGL
}
#endif
}
-void render_free_surfaces(vdp_context *context)
-{
- free(context->framebuf);
-}
-
char * caption = NULL;
char * fps_caption = NULL;
static void render_quit()
{
render_close_audio();
-#ifdef DISABLE_OPENGL
- SDL_DestroyTexture(main_texture);
-#endif
+ for (int i = 0; i < num_textures; i++)
+ {
+ if (sdl_textures[i]) {
+ SDL_DestroyTexture(sdl_textures[i]);
+ }
+ }
}
void render_init(int width, int height, char * title, uint32_t fps, uint8_t fullscreen)
@@ -356,6 +359,7 @@ void render_init(int width, int height, char * title, uint32_t fps, uint8_t full
}
#endif
}
+ render_alloc_surfaces();
def.ptrval = "off";
scanlines = !strcmp(tern_find_path_default(config, "video\0scanlines\0", def).ptrval, "on");
@@ -419,16 +423,57 @@ void render_update_caption(char *title)
fps_caption = NULL;
}
-void render_context(vdp_context * context)
+uint32_t *locked_pixels;
+uint32_t locked_pitch;
+uint32_t *render_get_framebuffer(uint8_t which, int *pitch)
{
- int width = context->regs[REG_MODE_4] & BIT_H40 ? 320.0f : 256.0f;
- int height = 240;
+#ifndef DISABLE_OPENGL
+ if (render_gl && which <= FRAMEBUFFER_EVEN) {
+ *pitch = 320 * sizeof(uint32_t); //TODO: change this to LINEBUF_SIZE once border rendering is added
+ return texture_buf;
+ } else {
+#endif
+ if (which >= num_textures) {
+ warning("Request for invalid framebuffer number %d\n", which);
+ return NULL;
+ }
+ void *pixels;
+ if (SDL_LockTexture(sdl_textures[which], NULL, &pixels, pitch) < 0) {
+ warning("Failed to lock texture: %s\n", SDL_GetError());
+ return NULL;
+ }
+ static uint8_t last;
+ if (which <= FRAMEBUFFER_EVEN) {
+ locked_pixels = pixels;
+ if (which == FRAMEBUFFER_EVEN) {
+ pixels += *pitch;
+ }
+ locked_pitch = *pitch;
+ if (which != last) {
+ *pitch *= 2;
+ }
+ last = which;
+ }
+ return pixels;
+#ifndef DISABLE_OPENGL
+ }
+#endif
+}
- last_frame = SDL_GetTicks();
+uint8_t events_processed;
+#ifdef __ANDROID__
+#define FPS_INTERVAL 10000
+#else
+#define FPS_INTERVAL 1000
+#endif
+
+void render_framebuffer_updated(uint8_t which, int width)
+{
+ static uint8_t last;
#ifndef DISABLE_OPENGL
- if (render_gl) {
- glBindTexture(GL_TEXTURE_2D, textures[context->framebuf == context->oddbuf ? 0 : 1]);
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 320, 240, GL_BGRA, GL_UNSIGNED_BYTE, context->framebuf);;
+ if (render_gl && which <= FRAMEBUFFER_EVEN) {
+ glBindTexture(GL_TEXTURE_2D, textures[which]);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 320, 240, GL_BGRA, GL_UNSIGNED_BYTE, texture_buf);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
@@ -439,7 +484,7 @@ void render_context(vdp_context * context)
glUniform1i(un_textures[0], 0);
glActiveTexture(GL_TEXTURE1);
- glBindTexture(GL_TEXTURE_2D, textures[(context->regs[REG_MODE_4] & BIT_INTERLACE) ? 1 : scanlines ? 2 : 0]);
+ glBindTexture(GL_TEXTURE_2D, textures[last != which ? 1 : scanlines ? 2 : 0]);
glUniform1i(un_textures[1], 1);
glUniform1f(un_width, width);
@@ -456,48 +501,60 @@ void render_context(vdp_context * context)
SDL_GL_SwapWindow(main_window);
} else {
#endif
- SDL_Rect area;
-
- area.x = area.y = 0;
- area.w = width;
- area.h = height;
-
- if (context->regs[REG_MODE_4] & BIT_INTERLACE) {
- unsigned skip;
- uint32_t *src = (uint32_t*)context->framebuf;
- uint8_t *dst;
- int i;
-
- area.h *= 2;
-
- SDL_LockTexture(main_texture, &area, (void**)&dst, &skip);
-
- if (context->framebuf == context->evenbuf)
- dst += skip;
-
- skip *= 2;
-
- for (i = 0; i < 240; ++i) {
- memcpy(dst, src, width*sizeof(uint32_t));
- src += 320;
- dst += skip;
+ uint32_t height = 240;
+ if (which <= FRAMEBUFFER_EVEN && last != which) {
+ uint8_t *cur_dst = (uint8_t *)locked_pixels;
+ uint8_t *cur_saved = (uint8_t *)texture_buf;
+ uint32_t dst_off = which == FRAMEBUFFER_EVEN ? 0 : locked_pitch;
+ uint32_t src_off = which == FRAMEBUFFER_EVEN ? locked_pitch : 0;
+ for (int i = 0; i < 240; ++i)
+ {
+ //copy saved line from other field
+ memcpy(cur_dst + dst_off, cur_saved, locked_pitch);
+ //save line from this field to buffer for next frame
+ memcpy(cur_saved, cur_dst + src_off, locked_pitch);
+ cur_dst += locked_pitch * 2;
+ cur_saved += locked_pitch;
}
-
- SDL_UnlockTexture(main_texture);
+ height = 480;
}
- else /* possibly faster path for non-interlaced output */
- SDL_UpdateTexture(main_texture, &area, context->framebuf, 320*sizeof(uint32_t));
-
- SDL_RenderClear(main_renderer);
- SDL_RenderCopy(main_renderer, main_texture, &area, &main_clip);
+ SDL_UnlockTexture(sdl_textures[which]);
+ SDL_Rect src_clip = {
+ .x = 0,
+ .y = 0,
+ .w = width,
+ .h = height
+ };
+ SDL_RenderCopy(main_renderer, sdl_textures[which], &src_clip, &main_clip);
SDL_RenderPresent(main_renderer);
#ifndef DISABLE_OPENGL
}
#endif
-
- if (context->regs[REG_MODE_4] & BIT_INTERLACE) {
- context->framebuf = context->framebuf == context->oddbuf ? context->evenbuf : context->oddbuf;
+ if (which <= FRAMEBUFFER_EVEN) {
+ last = which;
+ static uint32_t frame_counter, start;
+ frame_counter++;
+ last_frame= SDL_GetTicks();
+ if ((last_frame - start) > FPS_INTERVAL) {
+ if (start && (last_frame-start)) {
+ #ifdef __ANDROID__
+ info_message("%s - %.1f fps", caption, ((float)frame_counter) / (((float)(last_frame-start)) / 1000.0));
+ #else
+ if (!fps_caption) {
+ fps_caption = malloc(strlen(caption) + strlen(" - 100000000.1 fps") + 1);
+ }
+ sprintf(fps_caption, "%s - %.1f fps", caption, ((float)frame_counter) / (((float)(last_frame-start)) / 1000.0));
+ SDL_SetWindowTitle(main_window, fps_caption);
+ #endif
+ }
+ start = last_frame;
+ frame_counter = 0;
+ }
+ }
+ if (!events_processed) {
+ process_events();
}
+ events_processed = 0;
}
void render_wait_quit(vdp_context * context)
@@ -505,20 +562,6 @@ void render_wait_quit(vdp_context * context)
SDL_Event event;
while(SDL_WaitEvent(&event)) {
switch (event.type) {
- case SDL_KEYDOWN:
- if (event.key.keysym.sym == SDLK_LEFTBRACKET) {
- render_dbg++;
- if (render_dbg == 4) {
- render_dbg = 0;
- }
- render_context(context);
- } else if(event.key.keysym.sym == SDLK_RIGHTBRACKET) {
- debug_pal++;
- if (debug_pal == 4) {
- debug_pal = 0;
- }
- }
- break;
case SDL_QUIT:
return;
}
@@ -720,60 +763,16 @@ int32_t handle_event(SDL_Event *event)
return 0;
}
-uint32_t frame_counter = 0;
-uint32_t start = 0;
-#ifdef __ANDROID__
-#define FPS_INTERVAL 10000
-#else
-#define FPS_INTERVAL 1000
-#endif
-int wait_render_frame(vdp_context * context, int frame_limit)
-{
- SDL_Event event;
- int ret = 0;
- while(SDL_PollEvent(&event)) {
- ret = handle_event(&event);
- }
- if (frame_limit) {
- //TODO: Adjust frame delay so we actually get 60 FPS rather than 62.5 FPS
- uint32_t current = SDL_GetTicks();
- uint32_t desired = last_frame + frame_delay;
- if (current < desired) {
- uint32_t delay = last_frame + frame_delay - current;
- if (delay > min_delay) {
- SDL_Delay((delay/min_delay)*min_delay);
- }
- while ((desired) >= SDL_GetTicks()) {
- }
- }
- }
- render_context(context);
-
- frame_counter++;
- if ((last_frame - start) > FPS_INTERVAL) {
- if (start && (last_frame-start)) {
-#ifdef __ANDROID__
- info_message("%s - %.1f fps", caption, ((float)frame_counter) / (((float)(last_frame-start)) / 1000.0));
-#else
- if (!fps_caption) {
- fps_caption = malloc(strlen(caption) + strlen(" - 100000000.1 fps") + 1);
- }
- sprintf(fps_caption, "%s - %.1f fps", caption, ((float)frame_counter) / (((float)(last_frame-start)) / 1000.0));
- SDL_SetWindowTitle(main_window, fps_caption);
-#endif
- }
- start = last_frame;
- frame_counter = 0;
- }
- return ret;
-}
-
void process_events()
{
+ if (events_processed > MAX_EVENT_POLL_PER_FRAME) {
+ return;
+ }
SDL_Event event;
while(SDL_PollEvent(&event)) {
handle_event(&event);
}
+ events_processed++;
}
void render_wait_psg(psg_context * context)
diff --git a/vdp.c b/vdp.c
index f7f5a3e..bc8ac0f 100644
--- a/vdp.c
+++ b/vdp.c
@@ -59,14 +59,11 @@ void init_vdp_context(vdp_context * context, uint8_t region_pal)
/*
*/
if (headless) {
- context->oddbuf = context->framebuf = malloc(FRAMEBUF_ENTRIES * (32 / 8));
- memset(context->framebuf, 0, FRAMEBUF_ENTRIES * (32 / 8));
- context->evenbuf = malloc(FRAMEBUF_ENTRIES * (32 / 8));
- memset(context->evenbuf, 0, FRAMEBUF_ENTRIES * (32 / 8));
+ context->output = malloc(LINEBUF_SIZE);
+ context->output_pitch = 0;
} else {
- render_alloc_surfaces(context);
+ context->output = render_get_framebuffer(FRAMEBUFFER_ODD, &context->output_pitch);
}
- context->framebuf = context->oddbuf;
context->linebuf = malloc(LINEBUF_SIZE + SCROLL_BUFFER_SIZE*2);
memset(context->linebuf, 0, LINEBUF_SIZE + SCROLL_BUFFER_SIZE*2);
context->tmp_buf_a = context->linebuf + LINEBUF_SIZE;
@@ -146,12 +143,6 @@ void vdp_free(vdp_context *context)
{
free(context->vdpmem);
free(context->linebuf);
- if (headless) {
- free(context->oddbuf);
- free(context->evenbuf);
- } else {
- render_free_surfaces(context);
- }
free(context);
}
@@ -356,7 +347,7 @@ void scan_sprite_table(uint32_t line, vdp_context * context)
uint8_t height_mult;
if (context->double_res) {
line *= 2;
- if (context->framebuf != context->oddbuf) {
+ if (context->flags2 & FLAG2_EVEN_FIELD) {
line++;
}
ymask = 0x3FF;
@@ -427,7 +418,7 @@ void read_sprite_x(uint32_t line, vdp_context * context)
uint8_t height = ((context->sprite_info_list[context->cur_slot].size & 0x3) + 1) * 8;
if (context->double_res) {
line *= 2;
- if (context->framebuf != context->oddbuf) {
+ if (context->flags2 & FLAG2_EVEN_FIELD) {
line++;
}
height *= 2;
@@ -673,7 +664,7 @@ void read_map_scroll(uint16_t column, uint16_t vsram_off, uint32_t line, uint16_
uint16_t window_line_shift, v_offset_mask, vscroll_shift;
if (context->double_res) {
line *= 2;
- if (context->framebuf != context->oddbuf) {
+ if (context->flags2 & FLAG2_EVEN_FIELD) {
line++;
}
window_line_shift = 4;
@@ -886,8 +877,7 @@ void render_map_output(uint32_t line, int32_t col, vdp_context * context)
if (col)
{
col-=2;
- dst = context->framebuf;
- dst += line * 320 + col * 8;
+ dst = context->output + col * 8;
if (context->debug < 2) {
sprite_buf = context->linebuf + col * 8;
uint8_t a_src, src;
@@ -1042,8 +1032,26 @@ void vdp_advance_line(vdp_context *context)
} else if (!(context->latched_mode & BIT_PAL) && context->vcounter == 0xEB) {
context->vcounter = 0x1E5;
}
+ uint32_t inactive_start = (context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START);
+ if (!headless) {
+ if (!context->vcounter && !context->output) {
+ context->output = render_get_framebuffer(context->flags2 & FLAG2_EVEN_FIELD ? FRAMEBUFFER_EVEN : FRAMEBUFFER_ODD, &context->output_pitch);
+ context->h40_lines = 0;
+ } else if (context->vcounter == inactive_start) { //TODO: Change this once border emulation is added
+ context->output = NULL;
+ render_framebuffer_updated(context->flags2 & FLAG2_EVEN_FIELD ? FRAMEBUFFER_EVEN: FRAMEBUFFER_ODD, context->h40_lines > inactive_start / 2 ? 320 : 256);
+ if (context->double_res) {
+ context->flags2 ^= FLAG2_EVEN_FIELD;
+ }
+ } else if (context->output) {
+ context->output = (uint32_t *)(((char *)context->output) + context->output_pitch);
+ if (context->regs[REG_MODE_4] & BIT_H40) {
+ context->h40_lines++;
+ }
+ }
+ }
- if (context->vcounter > (context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START)) {
+ if (context->vcounter > inactive_start) {
context->hint_counter = context->regs[REG_HINT];
} else if (context->hint_counter) {
context->hint_counter--;
@@ -1459,19 +1467,16 @@ void check_render_bg(vdp_context * context, int32_t line, uint32_t slot)
int starti = -1;
if (context->regs[REG_MODE_4] & BIT_H40) {
if (slot >= 12 && slot < 172) {
- uint32_t x = (slot-12)*2;
- starti = line * 320 + x;
+ starti = (slot-12)*2;
}
} else {
if (slot >= 11 && slot < 139) {
- uint32_t x = (slot-11)*2;
- starti = line * 320 + x;
+ starti = (slot-11)*2;
}
}
if (starti >= 0) {
uint32_t color = context->colors[context->regs[REG_BG_COLOR]];
- uint32_t * start = context->framebuf;
- start += starti;
+ uint32_t * start = context->output + starti;
for (int i = 0; i < 2; i++) {
*(start++) = color;
}
@@ -1650,7 +1655,7 @@ int vdp_control_port_write(vdp_context * context, uint16_t value)
if (reg == REG_MODE_4) {
context->double_res = (value & (BIT_INTERLACE | BIT_DOUBLE_RES)) == (BIT_INTERLACE | BIT_DOUBLE_RES);
if (!context->double_res) {
- context->framebuf = context->oddbuf;
+ context->flags &= FLAG2_EVEN_FIELD;
}
}
context->cd &= 0x3C;
@@ -1728,7 +1733,7 @@ uint16_t vdp_control_port_read(vdp_context * context)
value |= 0x20;
context->flags2 &= ~FLAG2_SPRITE_COLLIDE;
}
- if ((context->regs[REG_MODE_4] & BIT_INTERLACE) && context->framebuf == context->oddbuf) {
+ if ((context->regs[REG_MODE_4] & BIT_INTERLACE) && !(context->flags2 & FLAG2_EVEN_FIELD)) {
value |= 0x10;
}
uint32_t line= context->vcounter;
@@ -1767,16 +1772,8 @@ uint16_t vdp_data_port_read(vdp_context * context)
if (context->cd & 1) {
warning("Read from VDP data port while writes are configured, CPU is now frozen. VDP Address: %X, CD: %X\n", context->address, context->cd);
}
- uint32_t old_frame = context->frame;
while (!(context->flags & FLAG_READ_FETCHED)) {
vdp_run_context(context, context->cycles + ((context->regs[REG_MODE_4] & BIT_H40) ? 16 : 20));
- if (context->frame != old_frame) {
- if (!headless) {
- //TODO: make pushing frames to renderer automatic so this doesn't need to be here
- wait_render_frame(context, 0);
- }
- old_frame = context->frame;
- }
}
context->flags &= ~FLAG_READ_FETCHED;
//Should this happen after the prefetch or after the read?
diff --git a/vdp.h b/vdp.h
index 7812ee1..feca77d 100644
--- a/vdp.h
+++ b/vdp.h
@@ -13,8 +13,8 @@
#define CRAM_SIZE 64
#define VSRAM_SIZE 40
#define VRAM_SIZE (64*1024)
-#define LINEBUF_SIZE 320
-#define FRAMEBUF_ENTRIES (320+27)*(240+27) //PAL active display + full border
+#define LINEBUF_SIZE (320+27) //H40 + full border
+#define BORDER_BOTTOM 13 //TODO: Replace with actual value
#define MAX_DRAWS 40
#define MAX_DRAWS_H32 32
#define MAX_SPRITES_LINE 20
@@ -51,6 +51,7 @@
#define FLAG2_READ_PENDING 0x04
#define FLAG2_SPRITE_COLLIDE 0x08
#define FLAG2_REGION_PAL 0x10
+#define FLAG2_EVEN_FIELD 0x20
#define DISPLAY_ENABLE 0x40
@@ -138,15 +139,14 @@ typedef struct {
uint8_t *vdpmem;
//stores 2-bit palette + 4-bit palette index + priority for current sprite line
uint8_t *linebuf;
- //stores 12-bit color + shadow/highlight bits
- void *framebuf;
- void *oddbuf;
- void *evenbuf;
+ //pointer to current line in framebuffer
+ uint32_t *output;
uint16_t cram[CRAM_SIZE];
uint32_t colors[CRAM_SIZE*3];
uint32_t debugcolors[1 << (3 + 1 + 1 + 1)];//3 bits for source, 1 bit for priority, 1 bit for shadow, 1 bit for hilight
uint16_t vsram[VSRAM_SIZE];
uint16_t vscroll_latch[2];
+ uint32_t output_pitch;
uint32_t frame;
uint16_t vcounter;
uint16_t hscroll_a;
@@ -155,6 +155,7 @@ typedef struct {
uint8_t latched_mode;
uint8_t sprite_index;
uint8_t sprite_draws;
+ uint8_t h40_lines;
int8_t slot_counter;
int8_t cur_slot;
sprite_draw sprite_draw_list[MAX_DRAWS];