Browse Source

[sdl] fix Windows 10 HiDPI, seed timer properly for RNG

master
asie 3 months ago
parent
commit
14e9ecc11e
11 changed files with 82 additions and 36 deletions
  1. 8
    0
      mingw/app.manifest
  2. 3
    0
      mingw/resources.rc
  3. 1
    0
      src/config.h
  4. 4
    4
      src/frontend_curses.c
  5. 1
    0
      src/frontend_posix.c
  6. 32
    16
      src/frontend_sdl.c
  7. 3
    4
      src/render_software.c
  8. 17
    5
      src/zzt.c
  9. 7
    3
      src/zzt.h
  10. 2
    2
      zeta_sdl.sh
  11. 4
    2
      zeta_sdl_mingw.sh

+ 8
- 0
mingw/app.manifest View File

@@ -0,0 +1,8 @@
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<asmv3:application>
<asmv3:windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/pm</dpiAware>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">permonitorv2,permonitor</dpiAwareness>
</asmv3:windowsSettings>
</asmv3:application>
</assembly>

+ 3
- 0
mingw/resources.rc View File

@@ -0,0 +1,3 @@
#include "winuser.h"

CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "app.manifest"

+ 1
- 0
src/config.h View File

@@ -27,6 +27,7 @@

// SDL port configuration

#define BLINK_TOGGLE_DURATION_MS 233
#define ENABLE_SCREENSHOTS
#define USE_GETOPT
#define USE_OPENGL

+ 4
- 4
src/frontend_curses.c View File

@@ -34,7 +34,7 @@

static int video_blink;

long zeta_time_ms() {
long zeta_time_ms(void) {
struct timespec spec;

clock_gettime(CLOCK_REALTIME, &spec);
@@ -46,7 +46,7 @@ void cpu_ext_log(const char* s) {
}

void speaker_on(double freq) {}
void speaker_off() {}
void speaker_off(void) {}

static WINDOW* window;

@@ -62,7 +62,7 @@ void zeta_update_charset(int width, int height, u8* data) {
void zeta_update_palette(u32* data) {
}

static void platform_kbd_tick() {
static void platform_kbd_tick(void) {
int c = getch();
if (c == ERR) return;
if (c == 263) c = 8;
@@ -80,7 +80,7 @@ static int nc_color_map[] = {
COLOR_RED, COLOR_MAGENTA, COLOR_YELLOW, COLOR_WHITE
};

static void init_ncurses_colors() {
static void init_ncurses_colors(void) {
for (int i = 0; i < 64; i++) {
init_pair(i+1, nc_color_map[i&7], nc_color_map[i>>3]);
}

+ 1
- 0
src/frontend_posix.c View File

@@ -70,6 +70,7 @@ static int posix_zzt_init(int argc, char **argv) {
#endif

zzt_init();
zzt_set_timer_ticks(time(NULL));

#ifdef USE_GETOPT
if (argc > optind && posix_vfs_exists(argv[optind])) {

+ 32
- 16
src/frontend_sdl.c View File

@@ -29,7 +29,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_main.h>
#ifdef USE_OPENGL
#ifdef USE_OPENGL_ES
#include <SDL2/SDL_opengles.h>
@@ -63,6 +65,7 @@ static const u8 sdl_to_pc_scancode[] = {

static const int sdl_to_pc_scancode_max = sizeof(sdl_to_pc_scancode) - 1;

#ifdef USE_OPENGL
static SDL_Texture *create_texture_from_array(SDL_Renderer *renderer, int access, unsigned char *data, int height) {
SDL_Texture *texture;
SDL_Rect rect;
@@ -92,8 +95,9 @@ static SDL_Texture *create_texture_from_array(SDL_Renderer *renderer, int access

return texture;
}
#endif

long zeta_time_ms() {
long zeta_time_ms(void) {
return SDL_GetTicks();
}

@@ -121,7 +125,7 @@ void speaker_on(double freq) {
SDL_UnlockMutex(audio_mutex);
}

void speaker_off() {
void speaker_off(void) {
SDL_LockMutex(audio_mutex);
audio_stream_append_off(zeta_time_ms());
SDL_UnlockMutex(audio_mutex);
@@ -129,7 +133,9 @@ void speaker_off() {

static SDL_mutex *zzt_thread_lock;
static SDL_cond *zzt_thread_cond;
#ifdef USE_OPENGL
static u8 zzt_vram_copy[80*25*2];
#endif
static u8 zzt_thread_running;
static atomic_int zzt_renderer_waiting = 0;
static u8 video_blink = 1;
@@ -161,12 +167,16 @@ static Uint32 sdl_timer_thread(Uint32 interval, void *param) {
return tick_time;
}

static void sdl_timer_init() {
static void sdl_timer_init(void) {
first_timer_tick = zeta_time_ms();
timer_time = 0;
SDL_AddTimer((int) SYS_TIMER_TIME, sdl_timer_thread, (void*)NULL);
}

static int sdl_is_blink_phase(long curr_time) {
return ((curr_time % (BLINK_TOGGLE_DURATION_MS*2)) >= BLINK_TOGGLE_DURATION_MS);
}

// try to keep a budget of ~5ms per call

static int zzt_thread_func(void *ptr) {
@@ -284,7 +294,7 @@ static void calc_render_area(SDL_Rect *rect, int w, int h, int *scale_out, int f
}

#ifdef USE_OPENGL
/* static void oglguard() {
/* static void oglguard(void) {
GLenum err;

while ((err = glGetError()) != GL_NO_ERROR) {
@@ -292,7 +302,7 @@ static void calc_render_area(SDL_Rect *rect, int w, int h, int *scale_out, int f
}
} */

static void prepare_render_opengl() {
static void prepare_render_opengl(void) {
SDL_Rect rect;
int w, h, scale;
SDL_GL_GetDrawableSize(window, &w, &h);
@@ -340,7 +350,7 @@ static void update_opengl_colcache(u32* pal) {
}
}

static void init_opengl() {
static void init_opengl(void) {
ogl_buf_pos = malloc((80 * 25) * GL_COMPONENT_POINTS * 2 * sizeof(short));
ogl_buf_pos40 = malloc((40 * 25) * GL_COMPONENT_POINTS * 2 * sizeof(short));
ogl_buf_col = malloc(2 * (80 * 25) * GL_COMPONENT_POINTS * 4 * sizeof(char));
@@ -441,7 +451,7 @@ static void init_opengl() {
#endif
}

static void deinit_opengl() {
static void deinit_opengl(void) {
free(ogl_buf_texcache);
free(ogl_buf_colcache);
free(ogl_buf_tex);
@@ -451,7 +461,7 @@ static void deinit_opengl() {
}

static void render_opengl(long curr_time, int regen_visuals) {
u8 blink_local = video_blink && ((curr_time % 466) >= 233);
u8 blink_local = video_blink && sdl_is_blink_phase(curr_time);
float texw, texh;
int width = (zzt_video_mode() & 2) ? 80 : 40;

@@ -542,9 +552,9 @@ static void render_software_copy(long curr_time) {
}

if (!video_blink) sflags |= RENDER_BLINK_OFF;
else if ((zeta_time_ms() % 466) >= 233) sflags |= RENDER_BLINK_PHASE;
else if (sdl_is_blink_phase(zeta_time_ms())) sflags |= RENDER_BLINK_PHASE;

SDL_GetWindowSize(window, &w, &h);
SDL_GetRendererOutputSize(renderer, &w, &h);
calc_render_area(&dest, w, h, NULL, 0);

SDL_LockTexture(playfieldtex, NULL, &buffer, &pitch);
@@ -661,7 +671,7 @@ int main(int argc, char **argv) {
fprintf(stderr, "Could not initialize OpenGL (%s), using software renderer...", SDL_GetError());
#endif
window = SDL_CreateWindow("Zeta", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
80*charw, 25*charh, 0);
80*charw, 25*charh, SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
SDL_SetHint(SDL_HINT_RENDER_VSYNC, "1");
} else {
SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengl");
@@ -699,7 +709,9 @@ int main(int argc, char **argv) {

sdl_timer_init();

int should_render;
#ifdef USE_OPENGL
int should_render = 1;
#endif

while (cont_loop) {
if (!zzt_thread_running) { cont_loop = 0; break; }
@@ -707,9 +719,13 @@ int main(int argc, char **argv) {
atomic_fetch_add(&zzt_renderer_waiting, 1);
SDL_LockMutex(zzt_thread_lock);
atomic_fetch_sub(&zzt_renderer_waiting, 1);
u8* ram = zzt_get_ram();
should_render = memcmp(ram + 0xB8000, zzt_vram_copy, 80*25*2);
if (should_render) memcpy(zzt_vram_copy, ram + 0xB8000, 80*25*2);
#ifdef USE_OPENGL
if (use_opengl) {
u8* ram = zzt_get_ram();
should_render = memcmp(ram + 0xB8000, zzt_vram_copy, 80*25*2);
if (should_render) memcpy(zzt_vram_copy, ram + 0xB8000, 80*25*2);
}
#endif
zzt_mark_frame();

// do KEYUPs before KEYDOWNS - fixes key loss issues w/ Windows
@@ -740,7 +756,7 @@ int main(int argc, char **argv) {
}

if (!video_blink) sflags |= RENDER_BLINK_OFF;
else if ((zeta_time_ms() % 466) >= 233) sflags |= RENDER_BLINK_PHASE;
else if (sdl_is_blink_phase(zeta_time_ms())) sflags |= RENDER_BLINK_PHASE;

while ((++i) <= 9999) {
snprintf(filename, 23, "screen%d.bmp", i);

+ 3
- 4
src/render_software.c View File

@@ -51,10 +51,9 @@ void render_software_rgb(u32 *buffer, int scr_width, int row_length, int flags,
int line = *co;
for (int cx = 0; cx < char_width; cx++, line <<= 1) {
int bpos = ((y * char_height + cy) * row_length) + ((x * char_width + cx) * pos_mul);
buffer[bpos] = palette[(line & 0x80) ? fg : bg];
if (pos_mul == 2) {
buffer[bpos+1] = palette[(line & 0x80) ? fg : bg];
}
int col = palette[(line & 0x80) ? fg : bg];
buffer[bpos] = col;
if (pos_mul == 2) buffer[bpos+1] = col;
}
}
}

+ 17
- 5
src/zzt.c View File

@@ -110,7 +110,7 @@ void zzt_kmod_clear(int mod) {
zzt.kmod &= ~mod;
}

static long zzt_internal_time() {
static long zzt_internal_time(void) {
return zzt.timer_time;
// return (long) (zzt.timer_time + (zeta_time_ms() - zzt.real_time));
}
@@ -130,11 +130,11 @@ static int zzt_key_append(int qch, int qke) {
return 0;
}

int zzt_key_get_delay() {
int zzt_key_get_delay(void) {
return zzt.key_delay;
}

int zzt_key_get_repeat_delay() {
int zzt_key_get_repeat_delay(void) {
return zzt.key_repeat_delay;
}

@@ -358,6 +358,18 @@ static void cpu_func_intr_0x33(cpu_state* cpu) {
}
}

u32 zzt_get_timer_ticks(void) {
return zzt.cpu.ram[0x46c] | (zzt.cpu.ram[0x46d] << 8)
| (zzt.cpu.ram[0x46e] << 16) | (zzt.cpu.ram[0x46f] << 24);
}

void zzt_set_timer_ticks(u32 time) {
zzt.cpu.ram[0x46c] = time & 0xFF;
zzt.cpu.ram[0x46d] = (time>>8) & 0xFF;
zzt.cpu.ram[0x46e] = (time>>16) & 0xFF;
zzt.cpu.ram[0x46f] = (time>>24) & 0xFF;
}

static int cpu_func_interrupt_main(cpu_state* cpu, u8 intr) {
#ifdef DEBUG_INTERRUPTS
fprintf(stderr, "dbg: interrupt %02X %04X\n", intr, cpu->ax);
@@ -946,7 +958,7 @@ void zzt_load_binary(int handle, const char *arg) {
fprintf(stderr, "wrote %d bytes to %d\n", bytes_read, (offset_pars * 16 + 256));
}

void zzt_init() {
void zzt_init(void) {
/* for (int i = 0; i < MAX_ALLOC; i++)
seg_allocs[i] = (i < 256) ? (256-i) : 0; */

@@ -1006,7 +1018,7 @@ int zzt_execute(int opcodes) {
return cpu_execute(&(zzt.cpu), opcodes);
}

static void zzt_update_keys() {
static void zzt_update_keys(void) {
long ctime = zeta_time_ms();
zzt_key_entry* key = &(zzt.key);


+ 7
- 3
src/zzt.h View File

@@ -49,7 +49,7 @@ void zzt_mouse_axis(int axis, int value /* delta, in pixels */);
USER_FUNCTION
void zzt_mouse_clear(int button);
USER_FUNCTION
void zzt_init();
void zzt_init(void);
USER_FUNCTION
void zzt_load_binary(int handle, const char *arg);
USER_FUNCTION
@@ -61,11 +61,15 @@ void zzt_mark_frame(void);
USER_FUNCTION
void zzt_mark_timer(void);
USER_FUNCTION
int zzt_key_get_delay();
int zzt_key_get_delay(void);
USER_FUNCTION
int zzt_key_get_repeat_delay();
int zzt_key_get_repeat_delay(void);
USER_FUNCTION
void zzt_key_set_delay(int ms, int repeat_ms);
USER_FUNCTION
u32 zzt_get_timer_ticks(void);
USER_FUNCTION
void zzt_set_timer_ticks(u32 ticks);

IMPLEMENT_FUNCTION
long zeta_time_ms(void);

+ 2
- 2
zeta_sdl.sh View File

@@ -1,7 +1,7 @@
#!/bin/sh
xxd -i res/8x14.bin > res/8x14.c
gcc -o build/zeta86 -g -O2 -std=c11 -Wall \
gcc -o build/zeta86 -g -O2 -std=c18 -Wall \
res/8x14.c src/posix_vfs.c src/audio_stream.c \
src/frontend_sdl.c src/zzt.c src/cpu.c \
src/screenshot_writer.c src/render_software.c \
-lGL -lSDL2
-lGL -lSDL2 -lSDL2main

+ 4
- 2
zeta_sdl_mingw.sh View File

@@ -1,6 +1,8 @@
#!/bin/sh
xxd -i res/8x14.bin > res/8x14.c
i686-w64-mingw32-gcc -o build/zeta86.exe -g -O2 -std=c11 -Wall \
if [ -f build/mingw_resources.o ]; then rm build/mingw_resources.o; fi
i686-w64-mingw32-windres mingw/resources.rc build/mingw_resources.o
i686-w64-mingw32-gcc -o build/zeta86.exe -g -O2 -std=c18 -Wall -mwindows \
res/8x14.c src/posix_vfs.c src/audio_stream.c src/frontend_sdl.c src/zzt.c src/cpu.c \
src/screenshot_writer.c src/render_software.c \
src/screenshot_writer.c src/render_software.c build/mingw_resources.o \
-lmingw32 -lSDL2main -lSDL2 -lopengl32

Loading…
Cancel
Save