Unverified Commit d61f8f95 authored by Libretro-Admin's avatar Libretro-Admin Committed by GitHub
Browse files

Merge pull request #88 from libretro/newui

newui for caprice32
parents 23a0e594 5fd14689
Pipeline #52165 passed with stages
in 1 minute and 52 seconds
......@@ -3,3 +3,9 @@
*.dll
*.a
*.gch
*.orig
*.rej
*.log
# editors
.vscode
.venv
\ No newline at end of file
......@@ -384,7 +384,8 @@ INCDIRS := $(EXTRA_INCLUDES) $(INCFLAGS)
$(CXX) -c -o $@ $< $(CXXFLAGS) $(INCDIRS)
%.o: %.c
$(CC) -c -o $@ $< $(CFLAGS) $(INCDIRS)
@echo $@
@$(CC) -c -o $@ $< $(CFLAGS) $(INCDIRS)
%.o: %.S
$(CC_AS) -c -o $@ $< $(CFLAGS) $(INCDIRS)
......@@ -409,7 +410,7 @@ $(TARGET): $(HEADERS) $(OBJS)
ifeq ($(STATIC_LINKING), 1)
$(AR) rcs $@ $(OBJS)
else
$(CC) -o $@ $(SHARED) $(OBJS) $(LDFLAGS) $(LIBS)
@$(CC) -o $@ $(SHARED) $(OBJS) $(LDFLAGS) $(LIBS)
endif
clean-objs:
......
GUI = $(CORE_DIR)/libretro/nukleargui
DEPS = $(CORE_DIR)/utils
LIBRETRO_COMM_DIR := $(CORE_DIR)/libretro-common
......@@ -7,47 +6,50 @@ INCFLAGS := \
-I$(CORE_DIR)/cap32 \
-I$(CORE_DIR)/cap32/libcpccat \
-I$(CORE_DIR)/libretro \
-I$(LIBRETRO_COMM_DIR)/include \
-I$(GUI) \
-I$(GUI)/nuklear \
-I$(GUI)/retro \
-I$(DEPS)/zlib
-I$(CORE_DIR)/libretro/microui \
-I$(LIBRETRO_COMM_DIR)/include \
-I$(DEPS)/zlib
SOURCES_C := \
$(CORE_DIR)/libretro/libretro-core.c \
$(GUI)/retro/SDL_gfxPrimitives.c \
$(GUI)/retro/retro_surface.c \
$(GUI)/app.c \
$(CORE_DIR)/cap32/cap32.c \
$(CORE_DIR)/cap32/slots.c \
$(CORE_DIR)/cap32/crtc.c \
$(CORE_DIR)/cap32/fdc.c \
$(CORE_DIR)/cap32/psg.c \
$(CORE_DIR)/cap32/tape.c \
$(CORE_DIR)/cap32/cart.c \
$(CORE_DIR)/cap32/asic.c \
$(CORE_DIR)/cap32/z80.c \
$(CORE_DIR)/cap32/libcpccat/fs.c \
$(CORE_DIR)/cap32/kbdauto.c \
$(CORE_DIR)/libretro/retro_strings.c \
$(CORE_DIR)/libretro/retro_utils.c \
$(CORE_DIR)/libretro/retro_disk_control.c \
$(CORE_DIR)/libretro/retro_events.c \
$(CORE_DIR)/libretro/retro_snd.c
$(CORE_DIR)/libretro/libretro-core.c \
$(CORE_DIR)/cap32/cap32.c \
$(CORE_DIR)/cap32/slots.c \
$(CORE_DIR)/cap32/crtc.c \
$(CORE_DIR)/cap32/fdc.c \
$(CORE_DIR)/cap32/psg.c \
$(CORE_DIR)/cap32/tape.c \
$(CORE_DIR)/cap32/cart.c \
$(CORE_DIR)/cap32/asic.c \
$(CORE_DIR)/cap32/z80.c \
$(CORE_DIR)/cap32/libcpccat/fs.c \
$(CORE_DIR)/cap32/kbdauto.c \
$(CORE_DIR)/libretro/microui/microui.c \
$(CORE_DIR)/libretro/gfx/software.c \
$(CORE_DIR)/libretro/assets/ui_keyboard_bg.c \
$(CORE_DIR)/libretro/assets/ui_keyboard_en.c \
$(CORE_DIR)/libretro/assets/font.c \
$(CORE_DIR)/libretro/retro_strings.c \
$(CORE_DIR)/libretro/retro_utils.c \
$(CORE_DIR)/libretro/retro_disk_control.c \
$(CORE_DIR)/libretro/retro_events.c \
$(CORE_DIR)/libretro/retro_snd.c \
$(CORE_DIR)/libretro/retro_render.c \
$(CORE_DIR)/libretro/retro_ui.c \
$(CORE_DIR)/libretro/retro_keyboard.c
SOURCES_C += \
$(DEPS)/zlib/adler32.c \
$(DEPS)/zlib/inflate.c \
$(DEPS)/zlib/inffast.c \
$(DEPS)/zlib/inftrees.c \
$(DEPS)/zlib/zutil.c \
$(DEPS)/zlib/gzread.c \
$(DEPS)/zlib/gzwrite.c \
$(DEPS)/zlib/gzclose.c \
$(DEPS)/zlib/gzlib.c \
$(DEPS)/zlib/trees.c \
$(DEPS)/zlib/crc32.c \
$(DEPS)/zlib/deflate.c
$(DEPS)/zlib/adler32.c \
$(DEPS)/zlib/inflate.c \
$(DEPS)/zlib/inffast.c \
$(DEPS)/zlib/inftrees.c \
$(DEPS)/zlib/zutil.c \
$(DEPS)/zlib/gzread.c \
$(DEPS)/zlib/gzwrite.c \
$(DEPS)/zlib/gzclose.c \
$(DEPS)/zlib/gzlib.c \
$(DEPS)/zlib/trees.c \
$(DEPS)/zlib/crc32.c \
$(DEPS)/zlib/deflate.c
ifneq ($(STATIC_LINKING), 1)
SOURCES_C += \
......
......@@ -162,10 +162,6 @@
May 29, 2004 - 18:09 reintroduced tape_eject, tape_insert and tape_insert_voc; added sound support via the native SDL audio routines
*/
#include <zlib.h>
#define AUTODELAY 50
/* forward declarations - some libretro port callbacks */
void retro_loop(void);
void doCleanUp (void);
......@@ -177,17 +173,17 @@ int HandleExtension(char *path,char *ext);
#include "libretro-core.h"
#include "retro_snd.h"
#include "retro_ui.h"
#include "retro_utils.h"
extern unsigned int bmp[WINDOW_MAX_SIZE];
extern char RPATH[512];
extern char retro_content_filepath[512];
extern int autorun;
extern int SND;
extern bool kbd_runcmd;
int autoboot_delay=0;
extern void kbd_buf_feed(char *s);
extern void kbd_buf_update();
extern void kbd_update_table(int lang);
extern char DISKA_NAME[512];
......@@ -947,10 +943,12 @@ void z80_OUT_handler (reg_pair port, uint8_t val)
if ((port.b.h == 0xfa) && (!(port.b.l & 0x80))) { // floppy motor control?
//printf("FDC motor control access: %u - %u\n", (int) port.b.l, (int) val);
FDC.motor = val & 0x01;
if(FDC.motor)
if(FDC.motor) {
retro_snd_cmd(SND_FDCMOTOR, ST_LOOP);
else
retro_show_statusbar();
} else {
retro_snd_cmd(SND_FDCMOTOR, ST_OFF);
}
#ifdef DEBUG_FDC
fputs(FDC.motor ? "\r\n--- motor on" : "\r\n--- motor off", pfoDebug);
#endif
......@@ -1055,65 +1053,6 @@ int zip_dir (t_zip_info *zi)
return 0; // operation completed successfully
}
int zip_extract (char *pchZipFile, char *pchFileName, uint32_t dwOffset)
{
int iStatus, iCount;
uint32_t dwSize;
uint8_t *pbInputBuffer, *pbOutputBuffer;
FILE *pfileOut, *pfileIn;
z_stream z;
tmpnam(pchFileName); // generate a unique (temporary) file name for the decompression process
if (!(pfileOut = fopen(pchFileName, "wb")))
return ERR_FILE_UNZIP_FAILED; // couldn't create output file
pfileIn = fopen(pchZipFile, "rb"); // open ZIP file for reading
fseek(pfileIn, dwOffset, SEEK_SET); // move file pointer to beginning of data block
if(!fread(pbGPBuffer, 30, 1, pfileIn)) { // read local header
fclose(pfileIn);
fclose(pfileOut);
return ERR_FILE_UNZIP_FAILED;
}
dwSize = *(uint32_t *)(pbGPBuffer + 18); // length of compressed data
dwOffset += 30 + *(uint16_t *)(pbGPBuffer + 26) + *(uint16_t *)(pbGPBuffer + 28);
fseek(pfileIn, dwOffset, SEEK_SET); // move file pointer to start of compressed data
pbInputBuffer = pbGPBuffer; // space for compressed data chunck
pbOutputBuffer = pbInputBuffer + 16384; // space for uncompressed data chunck
z.zalloc = (alloc_func)0;
z.zfree = (free_func)0;
z.opaque = (voidpf)0;
iStatus = inflateInit2(&z, -MAX_WBITS); // init zlib stream (no header)
do {
z.next_in = pbInputBuffer;
if (dwSize > 16384) { // limit input size to max 16K or remaining bytes
z.avail_in = 16384;
} else {
z.avail_in = dwSize;
}
z.avail_in = fread(pbInputBuffer, 1, z.avail_in, pfileIn); // load compressed data chunck from ZIP file
while ((z.avail_in) && (iStatus == Z_OK)) { // loop until all data has been processed
z.next_out = pbOutputBuffer;
z.avail_out = 16384;
iStatus = inflate(&z, Z_NO_FLUSH); // decompress data
iCount = 16384 - z.avail_out;
if (iCount) { // save data to file if output buffer is full
fwrite(pbOutputBuffer, 1, iCount, pfileOut);
}
}
dwSize -= 16384; // advance to next chunck
} while ((dwSize > 0) && (iStatus == Z_OK)) ; // loop until done
if (iStatus != Z_STREAM_END) {
return ERR_FILE_UNZIP_FAILED; // abort on error
}
iStatus = inflateEnd(&z); // clean up
fclose(pfileIn);
fclose(pfileOut);
return 0; // data was successfully decompressed
}
int emulator_select_ROM (void)
{
uint8_t *pbPtr;
......@@ -1684,13 +1623,13 @@ void getConfigValueString (char* pchFileName, char* pchSection,
void loadConfiguration (void)
{
unsigned i, n, iSide, iSector, iRomNum;
char chFileName[_MAX_PATH + 1];
char chPath[_MAX_PATH + 1];
char chFileName[_MAX_PATH + 11];
char chPath[_MAX_PATH + 16];
(void)n;
strncpy(chFileName, chAppPath, sizeof(chFileName)-10);
strcat(chFileName, "/cap32.cfg");
strncat(chFileName, "/cap32.cfg", sizeof(chFileName) - 1);
memset(&CPC, 0, sizeof(CPC));
......@@ -2129,7 +2068,7 @@ int retro_disk_auto()
strcpy(Buffer, "|CPM");
} else {
strcpy(Buffer, "CAT");
printf("autoload not found\n");
printf("autoload: file to load not found\n");
}
} else {
......@@ -2139,14 +2078,15 @@ int retro_disk_auto()
else
if (first_bin != -1) cur_name_id = first_bin;
sprintf(Buffer, "RUN\"%s", cpc_dsk_dirent[cur_name_id]);
// check added to avoid warning on gcc >= 8
if(snprintf(Buffer, sizeof(Buffer), "RUN\"%s", (const char*) &cpc_dsk_dirent[cur_name_id][0]) < 0)
{
printf("autoload: snprintf failed");
}
}
}
//if (CPC.psp_explore_disk == CPC_EXPLORE_FULL_AUTO)
{
strcat(Buffer, "\n");
}
strcat(Buffer, "\n");
//printf("(%s)\n",Buffer);
kbd_buf_feed(Buffer);
......@@ -2196,97 +2136,65 @@ int loadadsk (char *arv,int drive)
{
if( HandleExtension(arv,"DSK") || HandleExtension(arv,"dsk") )
{
if(attach_disk(arv, drive) == 0)
{
retro_disk_auto();
sprintf(RPATH,"%s%d.SNA",arv,drive);
}
if(attach_disk(arv, drive) == 0)
{
retro_disk_auto();
snprintf(
retro_content_filepath,
sizeof(retro_computer_cfg),
"%s%d.SNA",
arv,
drive
);
}
}
else if( HandleExtension(arv,"sna") || HandleExtension(arv,"SNA") )
{
snapshot_load (arv);
sprintf(RPATH,"%s",arv);
snapshot_load(arv);
strncpy(
retro_content_filepath,
arv,
sizeof(retro_content_filepath) - 1
);
}
return 0;
}
void check_kbd_command()
{
if (autoboot_delay<AUTODELAY)
autoboot_delay++;
else if (autoboot_delay==AUTODELAY)
{
if (!autorun)
kbd_runcmd=false;
autoboot_delay++;
}
if(kbd_runcmd==true && autoboot_delay>AUTODELAY){
static int pair=-1;
pair=-pair;
if(pair==1)
return;
kbd_buf_update();
}
return 0;
}
void retro_loop(void)
{
while(theloop());
check_kbd_command();
//printf("auto:%d run:%d cmd:%d\n",autoboot_delay,autorun,kbd_runcmd);
}
int theloop(void)
{
if ((CPC.limit_speed) && (iExitCondition == EC_CYCLE_COUNT))
while(1)
{
//int iTicksAdj = 0; // no adjustment necessary by default
if (CPC.snd_enabled)
if ((CPC.limit_speed) && (iExitCondition == EC_CYCLE_COUNT))
{
if (pbSndStream < CPC.snd_bufferptr)
dwSndDist = CPC.snd_bufferptr - pbSndStream; // determine distance between play and write cursors
else
dwSndDist = (pbSndBufferEnd - pbSndStream) + (CPC.snd_bufferptr - pbSndBuffer);
#if 0
if (dwSndDist < dwSndMinSafeDist)
iTicksAdj = -5; // speed emulation up to compensate
else if (dwSndDist > dwSndMaxSafeDist)
iTicksAdj = 5; // slow emulation down to compensate
#endif
if (CPC.snd_enabled)
{
if (pbSndStream < CPC.snd_bufferptr)
dwSndDist = CPC.snd_bufferptr - pbSndStream; // determine distance between play and write cursors
else
dwSndDist = (pbSndBufferEnd - pbSndStream) + (CPC.snd_bufferptr - pbSndBuffer);
}
}
}
uint32_t dwOffset = CPC.scr_pos - CPC.scr_base; // offset in current surface row
if (VDU.scrln > 0)
CPC.scr_base = retro_getScreenPtr() + (VDU.scrln * CPC.scr_line_offs); // determine current position
else
CPC.scr_base = retro_getScreenPtr(); // reset to surface start
CPC.scr_pos = CPC.scr_base + dwOffset; // update current rendering position
uint32_t dwOffset = CPC.scr_pos - CPC.scr_base; // offset in current surface row
if (VDU.scrln > 0)
CPC.scr_base = retro_getScreenPtr() + (VDU.scrln * CPC.scr_line_offs); // determine current position
else
CPC.scr_base = retro_getScreenPtr(); // reset to surface start
iExitCondition = z80_execute(); // run the emulation until an exit condition is met
CPC.scr_pos = CPC.scr_base + dwOffset; // update current rendering position
if (iExitCondition == EC_FRAME_COMPLETE)
{
/* emulation finished rendering a complete frame? */
return 0; /* exit retro_loop for retro_run */
iExitCondition = z80_execute(); // run the emulation until an exit condition is met
if (iExitCondition == EC_FRAME_COMPLETE)
{
/* emulation finished rendering a complete frame? */
break; /* exit retro_loop for retro_run */
}
else if (iExitCondition == EC_SOUND_BUFFER)
{
mixsnd();
}
}
else if (iExitCondition == EC_SOUND_BUFFER)
mixsnd();
return 1;
}
int capmain (int argc, char **argv)
......@@ -2335,4 +2243,4 @@ int capmain (int argc, char **argv)
emu_status = COMPUTER_READY; // set computer init as completed
return 0;
}
}
\ No newline at end of file
......@@ -61,7 +61,7 @@ extern FILE *pfoDebug;
#define MAX_SYNC_DEC 80
#define MAX_SYNC_INC 80
#define MAX_DRAWN 270 // Max displayed scan line (+1)
#define MAX_DRAWN 272
#define MIN_VHOLD 250
#define MAX_VHOLD 380
......
......@@ -54,6 +54,7 @@
#include "z80.h"
#include "retro_snd.h"
#include "retro_ui.h"
extern t_CPC CPC;
extern t_FDC FDC;
......@@ -723,6 +724,7 @@ uint8_t fdc_read_data(void)
FDC.byte_count = 0; // clear byte counter
FDC.phase = CMD_PHASE; // switch to command phase
FDC.led = 0; // turn the drive LED off
retro_ui_set_led(false);
}
break;
}
......@@ -865,6 +867,8 @@ void fdc_readtrk(void)
void fdc_write(void)
{
retro_ui_set_led(true);
FDC.led = 1; // turn the drive LED on
check_unit(); // switch to target drive
if (init_status_regs() == 0) { // drive Ready?
......@@ -906,6 +910,8 @@ void fdc_write(void)
void fdc_read(void)
{
retro_snd_cmd(SND_FDCREAD, ST_ON);
retro_ui_set_led(true);
FDC.led = 1; // turn the drive LED on
check_unit(); // switch to target drive
if (init_status_regs() == 0) { // drive Ready?
......@@ -1010,6 +1016,8 @@ void fdc_writeID(void)
void fdc_scan(void)
{
retro_ui_set_led(true);
FDC.led = 1; // turn the drive LED on
check_unit(); // switch to target drive
if (init_status_regs() == 0)
......
......@@ -499,7 +499,6 @@ int cpc_get_key_from_ascii(char ascii)
char kbd_feedbuf[255];
int kbd_feedbuf_pos;
bool kbd_runcmd=false;
int kbd_mode = 0;
extern void play_tape();
......@@ -513,16 +512,14 @@ extern uint8_t keyboard_matrix[16];
void kbd_buf_feed(char *s) {
strcpy(kbd_feedbuf, s);
kbd_feedbuf_pos=0;
kbd_runcmd=true;
//printf("cmd:%s\n",s);
}
void kbd_buf_clean(){
kbd_runcmd=false;
memset(keyboard_matrix, 0xff, sizeof(keyboard_matrix));
}
void kbd_buf_update() {
bool kbd_buf_update() {
static int old=0;
......@@ -530,7 +527,7 @@ void kbd_buf_update() {
if( kbd_feedbuf[kbd_feedbuf_pos]=='^' ) {
kbd_feedbuf_pos++;
play_tape();
return;
return false;
}
if( (kbd_feedbuf[kbd_feedbuf_pos]!=0) && old==0) {
......@@ -561,8 +558,10 @@ void kbd_buf_update() {
else if(kbd_feedbuf[kbd_feedbuf_pos]=='\0')
{
kbd_buf_clean();
return true;
}
return false;
}
//FIXME VIRTULAL KBD HANDLE
......
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Simple PNG to bit-font converter
Copyright (C) 2020 David Colmenero - D_Skywalk
http://david.dantoine.org
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
higher any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
"""
import sys
from PIL import Image
import numpy as np
BLACK = [0, 0, 0]
def is_black(data, mode):
if mode == "RGBA":
(r, g, b, a) = data
return [r, g, b] == BLACK
else:
(r, g, b) = data
return [r, g, b] == BLACK
def open(filename):
img = Image.open(filename)
im_array = np.array(img)
(width, height) = img.size
mode = img.mode
# print("pix", is_black(im_array[0][0], mode))
print ("static unsigned char bFont[] = {")
for y in range(0, height):
data = 0
for x in range(0, width):
if not is_black(im_array[y][x], mode):
data |= 1
data <<= 1
data >>= 1
print("0x%02X, " % data, end='')
if y % 16 == 0:
print("")
if __name__ == '__main__':
if len(sys.argv) != 2:
print("error $> convert.py image.png")
open(sys.argv[1])
......@@ -275,6 +275,8 @@ libretro_vfs_implementation_file *retro_vfs_file_open_impl(
libretro_vfs_implementation_file *stream = (libretro_vfs_implementation_file*)
calloc(1, sizeof(*stream));
(void) path_len;
#ifdef VFS_FRONTEND
const char *dumb_prefix = "vfsonly://";
size_t dumb_prefix_siz = strlen(dumb_prefix);
......
/****************************************************************************
* Caprice32 libretro port
*
* Copyright David Colmenero - D_Skywalk (2019-2021)
* Copyright Daniel De Matteis (2012-2021)
*
* Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met:
*
* - Redistributions may not be sold, nor may they be used in a commercial
* product or activity.
*
* - Redistributions that are modified from the original source must include the
* complete source code, including the source code for all components used by a
* binary built from the modified sources. However, as a special exception, the
* source code distributed need not include anything that is normally distributed
* (in either source or binary form) with the major components (compiler, kernel,
* and so on) of the operating system on which the executable runs, unless that
* component itself accompanies the executable.
*
* - Redistributions must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE