build, add windows (very experimental)
authorkub <derkub@gmail.com>
Thu, 5 Sep 2024 19:35:36 +0000 (21:35 +0200)
committerkub <derkub@gmail.com>
Tue, 10 Sep 2024 21:11:58 +0000 (23:11 +0200)
.github/workflows/ci.yml
Makefile
configure
platform/common/menu_pico.c
platform/libpicofe
platform/linux/emu.c
platform/win32/plat.c

index 40b77da..0472262 100644 (file)
@@ -25,6 +25,26 @@ jobs:
     - name: make
       run: LDFLAGS=-Wl,--no-undefined make -j$(getconf _NPROCESSORS_ONLN) -f Makefile.libretro
 
+  build-win32:
+    runs-on: ubuntu-latest
+    container: ghcr.io/irixxxx/toolchain-win32
+    steps:
+    - uses: actions/checkout@v4
+      with:
+        submodules: true
+    - name: build
+      run: |
+        git config --global --add safe.directory $PWD
+        ver=$(cut -d'"' -f2 platform/common/version.h)-$(git rev-parse --short HEAD)
+        ./configure --platform=win32
+        make -j$(getconf _NPROCESSORS_ONLN)
+        mv PicoDrive.zip PicoDrive-win32-$ver.zip
+    - name: artifacts
+      uses: actions/upload-artifact@v4
+      with:
+        name: Win32
+        path: PicoDrive-win32*.zip
+
 
   build-gp2x:
     runs-on: ubuntu-latest
index 48fa6a4..a3aea26 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -123,6 +123,17 @@ PicoDrive.zip: $(TARGET)
 all: PicoDrive.zip
 endif
 
+ifeq "$(PLATFORM)" "win32"
+PicoDrive.zip: $(TARGET)
+       $(RM) -rf .od_data
+       mkdir .od_data
+       cp -r platform/linux/skin .od_data
+       cp platform/game_def.cfg .od_data
+       $(STRIP) $< -o .od_data/PicoDrive.exe
+       cd .od_data && zip -9 -r ../$@ *
+all: PicoDrive.zip
+endif
+
 ifeq "$(PLATFORM)" "opendingux"
 .od_data: $(TARGET)
        $(RM) -rf .od_data
@@ -247,6 +258,14 @@ OBJS += platform/ps2/emu.o
 OBJS += platform/ps2/in_ps2.o
 USE_FRONTEND = 1
 endif
+ifeq "$(PLATFORM)" "win32"
+CFLAGS += -DSDL_OVERLAY_2X -DSDL_BUFFER_3X -DSDL_REDRAW_EVT
+OBJS += platform/win32/plat.o
+OBJS += platform/linux/emu.o platform/linux/blit.o # FIXME
+OBJS += platform/common/plat_sdl.o platform/common/inputmap_kbd.o
+OBJS += platform/libpicofe/plat_sdl.o platform/libpicofe/in_sdl.o
+USE_FRONTEND = 1
+endif
 ifeq "$(PLATFORM)" "libretro"
 OBJS += platform/libretro/libretro.o
 ifneq ($(STATIC_LINKING), 1)
index deb9b75..d267c26 100755 (executable)
--- a/configure
+++ b/configure
@@ -39,7 +39,7 @@ check_define()
 # "" means "autodetect".
 
 # TODO this is annoyingly messy. should have platform and device
-platform_list="generic pandora gph dingux retrofw opendingux[-gcw0] odbeta[-gcw0] miyoo rpi1 rpi2 ps2 psp"
+platform_list="generic pandora gph dingux retrofw opendingux[-gcw0] odbeta[-gcw0] miyoo rpi1 rpi2 ps2 psp win32"
 platform="generic"
 sound_driver_list="oss alsa sdl"
 sound_drivers=""
@@ -160,6 +160,9 @@ set_platform()
     CFLAGS="$CFLAGS -D_EE -G0 -I${PS2SDK}/ee/include -I${PS2SDK}/common/include -I${PS2DEV}/gsKit/include -I${PS2SDK}/ports/include"
     LDFLAGS="$LDFLAGS -Wl,-zmax-page-size=128 -T${PS2SDK}/ee/startup/linkfile -L${PS2SDK}/ee/lib -L${PS2DEV}/gsKit/lib -L${PS2SDK}/ports/lib"
     ;;
+  win32)
+    MFLAGS=""
+    ;;
   *)
     fail "unsupported platform: $platform"
     ;;
@@ -286,7 +289,7 @@ arm*)
 esac
 
 case "$platform" in
-rpi1 | rpi2 | generic | opendingux)
+rpi1 | rpi2 | generic | opendingux | win32)
   need_sdl="yes"
   ;;
 esac
index 53e52b8..415e1b5 100644 (file)
@@ -103,16 +103,25 @@ static void make_bg(int no_scale, int from_screen)
 
        if (!no_scale && g_menuscreen_w / w >= 2 && g_menuscreen_h / h >= 2)
        {
-               u32 t, *d = g_menubg_ptr;
-               d += (g_menuscreen_h / 2 - h * 2 / 2)
-                       * g_menuscreen_w / 2;
-               d += (g_menuscreen_w / 2 - w * 2 / 2) / 2;
-               for (y = 0; y < h; y++, src += pp, d += g_menuscreen_w*2/2) {
-                       for (x = 0; x < w; x++) {
-                               t = src[x];
-                               t = (PXMASKH(t,1)>>1) - (PXMASKH(t,3)>>3);
-                               t |= t << 16;
-                               d[x] = d[x + g_menuscreen_w / 2] = t;
+               int xf = g_menuscreen_w / w, yf = g_menuscreen_h / h;
+               int f = no_scale ? 1 : xf < yf ? xf : yf;
+               int xs = f * w, ys = f * h;
+               unsigned short t;
+               int i, j, k, l;
+
+               x = (g_menuscreen_w - xs)/2, y = (g_menuscreen_h - ys)/2;
+               dst = (short *)g_menubg_ptr + y * g_menuscreen_w + x;
+               for (i = 0; i < h; i++) {
+                       for (j = 0; j < w; j++, src++) {
+                               t = (PXMASKH(*src,1)>>1) - (PXMASKH(*src,3)>>3);
+                               for (l = 0; l < f; l++)
+                                       *dst++ = t;
+                       }
+                       src += pp - w;
+                       dst += g_menuscreen_w - xs;
+                       for (k = 1; k < f; k++) {
+                               memcpy(dst, dst-g_menuscreen_w, g_menuscreen_w*2);
+                               dst += g_menuscreen_w;
                        }
                }
                return;
index 697806c..9fba90a 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 697806c41dccf0adb0a3a35171f6eff9a9191240
+Subproject commit 9fba90ac323df5d2ad87735f6033ae720e5cb892
index 7417ca0..736fbb1 100644 (file)
@@ -9,7 +9,9 @@
 \r
 #include <stdio.h>\r
 #include <unistd.h>\r
-#include <sys/mman.h>\r
+#ifndef __MINGW32__\r
+#include <sys/mman.h> // MAP_JIT\r
+#endif\r
 \r
 #include "../libpicofe/menu.h"\r
 #include "../libpicofe/plat.h"\r
index f275010..a4020af 100644 (file)
@@ -7,28 +7,12 @@
  */
 #include <windows.h>
 #include <stdio.h>
+#include <dirent.h>
 
-#include "../common/plat.h"
+#include "../libpicofe/plat.h"
+#include "../libpicofe/posix.h"
 #include "../common/emu.h"
-#include "../common/version.h"
-#include <pico/pico.h>
-#include "direct.h"
-#include "dsnd.h"
-#include "main.h"
-
-static unsigned short screen_buff[320 * 240];
-const char *renderer_names[] = { NULL };
-const char *renderer_names32x[] = { NULL };
-
-int plat_parse_arg(int argc, char *argv[], int *x)
-{
-       return 1;
-}
-
-void plat_init(void)
-{
-       g_screen_ptr = (void *)screen_buff;
-}
+#include <pico/pico_int.h>
 
 int plat_is_dir(const char *path)
 {
@@ -46,15 +30,6 @@ unsigned int plat_get_ticks_us(void)
        return GetTickCount() * 1000;
 }
 
-void plat_wait_till_us(unsigned int us)
-{
-       int msdiff = (int)(us - plat_get_ticks_us()) / 1000;
-       if (msdiff > 6)
-               Sleep(msdiff - 6);
-       while (plat_get_ticks_us() < us)
-               ;
-}
-
 void plat_sleep_ms(int ms)
 {
        Sleep(ms);
@@ -65,105 +40,6 @@ int plat_wait_event(int *fds_hnds, int count, int timeout_ms)
        return -1;
 }
 
-void pemu_prep_defconfig(void)
-{
-       memset(&defaultConfig, 0, sizeof(defaultConfig));
-       defaultConfig.s_PicoCDBuffers = 0;
-       defaultConfig.Frameskip = 0;
-}
-
-void pemu_validate_config(void)
-{
-}
-
-void pemu_loop_prep(void)
-{
-       PicoDrawSetOutFormat(PDF_RGB555, 1);
-       PicoDrawSetOutBuf(g_screen_ptr, g_screen_ppitch * 2);
-       pemu_sound_start();
-}
-
-void pemu_loop_end(void)
-{
-       pemu_sound_stop();
-}
-
-void pemu_forced_frame(int no_scale, int do_emu)
-{
-}
-
-void pemu_finalize_frame(const char *fps, const char *notice_msg)
-{
-}
-
-void plat_video_flip(void)
-{
-       DirectScreen(g_screen_ptr);
-       DirectPresent();
-}
-
-void plat_video_wait_vsync(void)
-{
-}
-
-void plat_video_toggle_renderer(int change, int is_menu)
-{
-       // this will auto-select SMS/32X renderers
-       PicoDrawSetOutFormat(PDF_RGB555, 1);
-}
-
-void emu_video_mode_change(int start_line, int line_count, int start_col, int col_count)
-{
-       EmuScreenRect.left = start_col;
-       EmuScreenRect.right = start_col + col_count;
-       EmuScreenRect.top = start_line;
-       EmuScreenRect.bottom = start_line + line_count;
-
-       PostMessage(FrameWnd, WM_COMMAND, 0x20000 | 2000, 0);
-}
-
-static int sndbuff[2*44100/50/2 + 4];
-
-static void update_sound(int len)
-{
-       /* avoid writing audio when lagging behind to prevent audio lag */
-       if (PicoIn.skipFrame != 2)
-               DSoundUpdate(sndbuff, (currentConfig.EmuOpt & EOPT_NO_FRMLIMIT) ? 0 : 1);
-}
-
-void pemu_sound_start(void)
-{
-       int ret;
-
-       PicoIn.sndOut = NULL;
-       currentConfig.EmuOpt &= ~EOPT_EXT_FRMLIMIT;
-
-       // prepare sound stuff
-       if (currentConfig.EmuOpt & EOPT_EN_SOUND)
-       {
-               PsndRerate(0);
-
-               ret = DSoundInit(FrameWnd, PicoIn.sndRate, (PicoIn.opt & POPT_EN_STEREO) ? 1 : 0, Pico.snd.len);
-               if (ret != 0) {
-                       lprintf("dsound init failed\n");
-                       return;
-               }
-
-               PicoIn.sndOut = (void *)sndbuff;
-               PicoIn.writeSound = update_sound;
-               currentConfig.EmuOpt |= EOPT_EXT_FRMLIMIT;
-       }
-}
-
-void pemu_sound_stop(void)
-{
-       DSoundExit();
-}
-
-void pemu_sound_wait(void)
-{
-}
-
 int plat_get_root_dir(char *dst, int len)
 {
        int ml;
@@ -178,64 +54,56 @@ int plat_get_root_dir(char *dst, int len)
        return ml;
 }
 
-void plat_status_msg_busy_first(const char *msg)
-{
-}
-
-void plat_status_msg_busy_next(const char *msg)
-{
-}
-
-void plat_status_msg_clear(void)
-{
-}
-
-void plat_video_menu_enter(int is_rom_loaded)
+int plat_get_skin_dir(char *dst, int len)
 {
-}
+       int ml;
 
-void plat_video_menu_begin(void)
-{
+       ml = GetModuleFileName(NULL, dst, len);
+       while (ml > 0 && dst[ml] != '\\')
+               ml--;
+       if (ml != 0)
+               dst[ml++] = '\\';
+       memcpy(dst + ml, "skin\\", sizeof("skin\\"));
+       dst[ml + sizeof("skin\\")] = 0;
+       return ml + sizeof("skin\\") - 1;
 }
 
-void plat_video_menu_end(void)
+int plat_get_data_dir(char *dst, int len)
 {
+       return plat_get_root_dir(dst, len);
 }
 
-void plat_update_volume(int has_changed, int is_up)
+void *plat_mmap(unsigned long addr, size_t size, int need_exec, int is_fixed)
 {
-}
+       void *ptr;
+       unsigned long old;
 
-const char *plat_get_credits(void)
-{
-       return "PicoDrive v" VERSION " minibeta (c) notaz, 2006-2009\n\n"
-               "Credits:\n"
-               "fDave: base code of PicoDrive\n"
-               "Chui: Fame/C\n"
-               "NJ: CZ80\n"
-               "MAME devs: YM2612, SN76496 and SH2 cores\n"
-               "Stéphane Dallongeville: base of Fame/C (C68K), CZ80\n\n"
-               "Special thanks (ideas, valuable information and stuff):\n"
-               "Charles MacDonald, Eke, Exophase, Haze, Lordus, Nemesis,\n"
-               "Pierpaolo Prazzoli, Rokas, Steve Snake, Tasco Deluxe.\n";
+       ptr = VirtualAlloc(NULL, size, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
+       if (ptr && need_exec)
+               VirtualProtect(ptr, size, PAGE_EXECUTE_READWRITE, &old);
+       return ptr;
 }
 
-void plat_debug_cat(char *str)
+void plat_munmap(void *ptr, size_t size)
 {
+       VirtualFree(ptr, 0, MEM_RELEASE);
 }
 
-// required by pico
-int mp3_get_bitrate(void *f, int size)
+void *plat_mremap(void *ptr, size_t oldsize, size_t newsize)
 {
-       return 128;
+       void *ret = plat_mmap(0, newsize, 0, 0);
+       if (ret != NULL) {
+               memcpy(ret, ptr, oldsize);
+               plat_munmap(ptr, oldsize);
+       }
+       return ret;
 }
 
-void mp3_start_play(void *f, int pos)
+int   plat_mem_set_exec(void *ptr, size_t size)
 {
-}
+       unsigned long old;
 
-void mp3_update(int *buffer, int length, int stereo)
-{
+       return -(VirtualProtect(ptr, size, PAGE_EXECUTE_READWRITE, &old) == 0);
 }
 
 // other
@@ -251,7 +119,48 @@ void lprintf(const char *fmt, ...)
   printf("%s", buf);
 }
 
-// fake
-int alphasort() { return 0; }
-int scandir() { return 0; }
+// missing from mingw32
+int scandir(const char *dir, struct dirent ***namelist, int (*select)(const struct dirent *), int (*compar)(const struct dirent **, const struct dirent **)) {
+    HANDLE handle;
+    WIN32_FIND_DATA info;
+    char path[MAX_PATH];
+    struct dirent **entries = NULL;
+    size_t count = 0;
+
+    snprintf(path, sizeof(path), "%s\\*", dir);
+    handle = FindFirstFile(path, &info);
+    if (handle == INVALID_HANDLE_VALUE)
+        return -1;
+
+    do {
+        struct dirent *entry = (struct dirent *)malloc(sizeof(struct dirent));
+        if (!entry) {
+            free(entries);
+            FindClose(handle);
+            return -1;
+        }
+
+        strcpy(entry->d_name, info.cFileName);
+        entry->d_type = (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? DT_DIR : DT_REG;
+
+        if (!select || select(entry)) {
+            entries = realloc(entries, (count + 1) * sizeof(struct dirent *));
+            entries[count++] = entry;
+        } else
+            free(entry);
+    } while (FindNextFile(handle, &info));
 
+    FindClose(handle);
+
+    // Sort entries if a comparison function is provided
+    if (compar) {
+        qsort(entries, count, sizeof(struct dirent *), (int (*)(const void *, const void *))compar);
+    }
+
+    *namelist = entries;
+    return count;
+}
+
+int alphasort(const struct dirent **a, const struct dirent **b) {
+    return strcmp((*a)->d_name, (*b)->d_name);
+}