@@ -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> |
@@ -0,0 +1,3 @@ | |||
#include "winuser.h" | |||
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "app.manifest" |
@@ -27,6 +27,7 @@ | |||
// SDL port configuration | |||
#define BLINK_TOGGLE_DURATION_MS 233 | |||
#define ENABLE_SCREENSHOTS | |||
#define USE_GETOPT | |||
#define USE_OPENGL |
@@ -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]); | |||
} |
@@ -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])) { |
@@ -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); |
@@ -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; | |||
} | |||
} | |||
} |
@@ -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); | |||
@@ -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); |
@@ -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 |
@@ -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 |