Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,19 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_compile_definitions("$<$<CONFIG:DEBUG>:_DEBUG>")
add_compile_options(-Werror=return-type -Wno-switch)

if (EMSCRIPTEN)
add_compile_options(
-fexceptions
-Oz
)

add_link_options(
-fexceptions
-sALLOW_MEMORY_GROWTH=1
-Oz
)
endif()

if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
add_compile_options(-Werror=format -Wno-error=format-overflow -Wno-error=format-truncation -Wno-psabi)
endif()
Expand Down
10 changes: 6 additions & 4 deletions minizip/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@ target_include_directories(minizip INTERFACE
${CMAKE_CURRENT_SOURCE_DIR}/..
)

# use 32‑bit file API to fix Android compilation issue
target_compile_definitions(minizip PUBLIC
-DUSE_FILE32API
)
if (NOT EMSCRIPTEN)
# use 32‑bit file API to fix Android compilation issue
target_compile_definitions(minizip PUBLIC
-DUSE_FILE32API
)
endif()

target_link_libraries(minizip PUBLIC
zlib2
Expand Down
2 changes: 1 addition & 1 deletion source/AY8910.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -804,7 +804,7 @@ void AY8913::sound_ay_write( int reg, int val, libspectrum_dword now )
}
else
{
LogOutput("AY reg write discarded: %02X = %02X\n", reg, val);
// LogOutput("AY reg write discarded: %02X = %02X\n", reg, val);
}
}

Expand Down
2 changes: 1 addition & 1 deletion source/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ option(ENABLE_NETWORKING "Enable networking support (SLIRP/PCAP)" ON)
set(SLIRP_FOUND "0")
set(PCAP_FOUND "0")

if (ENABLE_NETWORKING AND NOT WIN32 AND NOT IOS)
if (ENABLE_NETWORKING AND NOT WIN32 AND NOT IOS AND NOT EMSCRIPTEN)
pkg_search_module(SLIRP slirp)

# if slirp is not found, we will try pcap
Expand Down
4 changes: 2 additions & 2 deletions source/NTSC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2716,9 +2716,9 @@ static void GenerateBaseColors(baseColors_t pBaseNtscColors)
int r = (((colors[0]>>16)&0xff) + ((colors[1]>>16)&0xff) + ((colors[2]>>16)&0xff) + ((colors[3]>>16)&0xff)) / 4;
int g = (((colors[0]>> 8)&0xff) + ((colors[1]>> 8)&0xff) + ((colors[2]>> 8)&0xff) + ((colors[3]>> 8)&0xff)) / 4;
int b = (((colors[0] )&0xff) + ((colors[1] )&0xff) + ((colors[2] )&0xff) + ((colors[3] )&0xff)) / 4;
uint32_t color = ((r<<16) | (g<<8) | b) | ALPHA32_MASK;
bgra_t color = makeBGRA(b, g, r, ALPHA);

(*pBaseNtscColors)[i] = * (bgra_t*) &color;
(*pBaseNtscColors)[i] = color;
}
}

Expand Down
58 changes: 29 additions & 29 deletions source/RGBMonitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,9 @@ const BYTE DoubleHiresPalIndex[16] = {
ORANGE, PINK, YELLOW, WHITE
};

static RGBQUAD* g_pPaletteRGB;
static bgra_t* g_pPaletteRGB;

static RGBQUAD PaletteRGB_NTSC[] =
static bgra_t PaletteRGB_NTSC[] =
{
// hires
#if DO_OPT_PALETTE
Expand Down Expand Up @@ -166,7 +166,7 @@ static RGBQUAD PaletteRGB_NTSC[] =

// Le Chat Mauve Feline's palette
// extracted from a white-balanced RGB video capture
static RGBQUAD PaletteRGB_Feline[] =
static bgra_t PaletteRGB_Feline[] =
{
SETRGBCOLOR(/*HGR_BLACK, */ 0x00,0x00,0x00),
SETRGBCOLOR(/*HGR_WHITE, */ 0xFF,0xFF,0xFF),
Expand Down Expand Up @@ -529,7 +529,7 @@ static void CopyMixedSource(int x, int y, int sx, int sy, bgra_t *pVideoAddress)
// color mixing between adjacent scanlines at current x position
MixColorsVertical(matx+nBytes, maty, isSWMIXED); //Post: colormixbuffer[]

UINT32* pDst = (UINT32*) pVideoAddress;
bgra_t* pDst = pVideoAddress;

for (int h=HGR_MATRIX_YOFFSET; h<=HGR_MATRIX_YOFFSET+1; h++)
{
Expand All @@ -541,8 +541,8 @@ static void CopyMixedSource(int x, int y, int sx, int sy, bgra_t *pVideoAddress)
else
{
_ASSERT( colormixbuffer[h] < (sizeof(PaletteRGB_NTSC)/sizeof(PaletteRGB_NTSC[0])) );
const RGBQUAD& rRGB = g_pPaletteRGB[ colormixbuffer[h] ];
*(pDst+nBytes) = *reinterpret_cast<const UINT32 *>(&rRGB);
const bgra_t& rRGB = g_pPaletteRGB[ colormixbuffer[h] ];
*(pDst+nBytes) = rRGB;
}

pDst -= frameBufferWidth;
Expand All @@ -555,7 +555,7 @@ static void CopyMixedSource(int x, int y, int sx, int sy, bgra_t *pVideoAddress)
// Pre: nSrcAdjustment: for 160-color images, src is +1 compared to dst
static void CopySource(int w, int h, int sx, int sy, bgra_t *pVideoAddress, const int nSrcAdjustment = 0)
{
UINT32* pDst = (UINT32*) pVideoAddress;
bgra_t* pDst = pVideoAddress;
const BYTE* const pSrc = g_aSourceStartofLine[ sy ] + sx;

const bool bIsHalfScanLines = GetVideo().IsVideoStyle(VS_HALF_SCANLINES);
Expand All @@ -573,8 +573,8 @@ static void CopySource(int w, int h, int sx, int sy, bgra_t *pVideoAddress, cons
for (int nBytes=0; nBytes<w; ++nBytes)
{
_ASSERT( *(pSrc+nBytes+nSrcAdjustment) < (sizeof(PaletteRGB_NTSC)/sizeof(PaletteRGB_NTSC[0])) );
const RGBQUAD& rRGB = g_pPaletteRGB[ *(pSrc+nBytes+nSrcAdjustment) ];
*(pDst+nBytes) = *reinterpret_cast<const UINT32 *>(&rRGB);
const bgra_t& rRGB = g_pPaletteRGB[ *(pSrc+nBytes+nSrcAdjustment) ];
*(pDst+nBytes) = rRGB;
}
}

Expand Down Expand Up @@ -667,7 +667,7 @@ void UpdateHiResRGBCell(int x, int y, uint16_t addr, bgra_t* pVideoAddress)
uint32_t dwordval = (byteval1 & 0x7F) | ((byteval2 & 0x7F) << 7) | ((byteval3 & 0x7F) << 14) | ((byteval4 & 0x7F) << 21);

// Extraction of 14 color pixels
UINT32 colors[14];
bgra_t colors[14];
int color = 0;
uint32_t dwordval_tmp = dwordval;
dwordval_tmp = dwordval_tmp >> 7;
Expand All @@ -678,15 +678,15 @@ void UpdateHiResRGBCell(int x, int y, uint16_t addr, bgra_t* pVideoAddress)
color = dwordval_tmp & 0x3;
// Two cases because AppleWin's palette is in a strange order
if (offset)
colors[i] = *reinterpret_cast<const UINT32*>(&g_pPaletteRGB[1 + color]);
colors[i] = g_pPaletteRGB[1 + color];
else
colors[i] = *reinterpret_cast<const UINT32*>(&g_pPaletteRGB[6 - color]);
colors[i] = g_pPaletteRGB[6 - color];
if (i%2) dwordval_tmp >>= 2;
}
// Black and White
UINT32 bw[2];
bw[0] = *reinterpret_cast<const UINT32*>(&g_pPaletteRGB[0]);
bw[1] = *reinterpret_cast<const UINT32*>(&g_pPaletteRGB[1]);
bgra_t bw[2];
bw[0] = g_pPaletteRGB[0];
bw[1] = g_pPaletteRGB[1];

uint32_t mask = 0x01C0; // 00|000001 1|1000000
uint32_t chck1 = 0x0140; // 00|000001 0|1000000
Expand All @@ -697,7 +697,7 @@ void UpdateHiResRGBCell(int x, int y, uint16_t addr, bgra_t* pVideoAddress)
// In all other cases, it's black if 0 and white if 1
// The value of 'color' is defined on a 2-bits basis

UINT32* pDst = (UINT32*)pVideoAddress;
bgra_t* pDst = pVideoAddress;

if (xoffset)
{
Expand Down Expand Up @@ -729,7 +729,7 @@ void UpdateHiResRGBCell(int x, int y, uint16_t addr, bgra_t* pVideoAddress)
const bool bIsHalfScanLines = GetVideo().IsVideoStyle(VS_HALF_SCANLINES);

// Second line
UINT32* pSrc = (UINT32*)pVideoAddress;
bgra_t* pSrc = pVideoAddress;
pDst = pSrc - GetVideo().GetFrameBufferWidth();
if (bIsHalfScanLines)
{
Expand Down Expand Up @@ -766,19 +766,19 @@ void UpdateDHiResCellRGB(int x, int y, uint16_t addr, bgra_t* pVideoAddress, boo

// Extraction of 7 color pixels and 7x4 bits
int bits[7];
UINT32 colors[7];
bgra_t colors[7];
int color = 0;
uint32_t dwordval_tmp = dwordval;
for (int i = 0; i < 7; i++)
{
bits[i] = dwordval_tmp & 0xF;
color = ((bits[i] & 7) << 1) | ((bits[i] & 8) >> 3); // DHGR colors are rotated 1 bit to the right
colors[i] = *reinterpret_cast<const UINT32*>(&g_pPaletteRGB[12 + color]);
colors[i] = g_pPaletteRGB[12 + color];
dwordval_tmp >>= 4;
}
UINT32 bw[2];
bw[0] = *reinterpret_cast<const UINT32*>(&g_pPaletteRGB[12 + 0]);
bw[1] = *reinterpret_cast<const UINT32*>(&g_pPaletteRGB[12 + 15]);
bgra_t bw[2];
bw[0] = g_pPaletteRGB[12 + 0];
bw[1] = g_pPaletteRGB[12 + 15];

if (isBit7Inversed)
{
Expand All @@ -800,7 +800,7 @@ void UpdateDHiResCellRGB(int x, int y, uint16_t addr, bgra_t* pVideoAddress, boo
//
// (Tested on Le Chat Mauve IIc adapter, which was made under patent of Video-7)

UINT32* pDst = (UINT32*)pVideoAddress;
bgra_t* pDst = pVideoAddress;

if (xoffset == 0) // First cell
{
Expand Down Expand Up @@ -944,7 +944,7 @@ void UpdateDHiResCellRGB(int x, int y, uint16_t addr, bgra_t* pVideoAddress, boo
const bool bIsHalfScanLines = GetVideo().IsVideoStyle(VS_HALF_SCANLINES);

// Second line
UINT32* pSrc = (UINT32*)pVideoAddress ;
bgra_t* pSrc = pVideoAddress ;
pDst = pSrc - GetVideo().GetFrameBufferWidth();
if (bIsHalfScanLines)
{
Expand Down Expand Up @@ -1119,11 +1119,11 @@ void UpdateHiResDuochromeCell(int x, int y, uint16_t addr, bgra_t* pVideoAddress
// Can be used in TEXT or HGR mode. The foreground & background colors could be fixed by hardware switches or data lying in AUX.
void UpdateDuochromeCell(int h, int w, bgra_t* pVideoAddress, uint8_t bits, uint8_t foreground, uint8_t background)
{
UINT32* pDst = (UINT32*)pVideoAddress;
bgra_t* pDst = pVideoAddress;

const bool bIsHalfScanLines = GetVideo().IsVideoStyle(VS_HALF_SCANLINES);
const UINT frameBufferWidth = GetVideo().GetFrameBufferWidth();
RGBQUAD colors[2];
bgra_t colors[2];
// use LoRes palette
background += 12;
foreground += 12;
Expand All @@ -1147,11 +1147,11 @@ void UpdateDuochromeCell(int h, int w, bgra_t* pVideoAddress, uint8_t bits, uint
{
int bit = (bits & 1);
bits >>= 1;
const RGBQUAD& rRGB = colors[bit];
*(pDst + nBytes) = *reinterpret_cast<const UINT32*>(&rRGB);
const bgra_t& rRGB = colors[bit];
*(pDst + nBytes) = rRGB;
if (doublepixels)
{
*(pDst + nBytes + 1) = *reinterpret_cast<const UINT32*>(&rRGB);
*(pDst + nBytes + 1) = rRGB;
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion source/Video.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -872,7 +872,7 @@ void Video::VideoRefreshBuffer(uint32_t uRedrawWholeScreenVideoMode, bool bRedra

void Video::ClearFrameBuffer()
{
UINT32* frameBuffer = (UINT32*)GetFrameBuffer();
bgra_t* frameBuffer = (bgra_t*)GetFrameBuffer();
std::fill(frameBuffer, frameBuffer + GetFrameBufferWidth() * GetFrameBufferHeight(), OPAQUE_BLACK);
}

Expand Down
40 changes: 29 additions & 11 deletions source/Video.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,37 @@
// Windows
// SDL (SDL_PIXELFORMAT_ARGB8888)
// Qt (QImage::Format_ARGB32_Premultiplied)
// TODO: Replace with WinGDI.h / RGBQUAD

struct bgra_t
{
#ifdef __EMSCRIPTEN__
uint8_t r;
uint8_t g;
uint8_t b;
uint8_t a; // reserved on Win32
#else
uint8_t b;
uint8_t g;
uint8_t r;
uint8_t a; // reserved on Win32
#endif
};

constexpr bgra_t makeBGRA(uint8_t b, uint8_t g, uint8_t r, uint8_t a)
{
bgra_t bgra{};
bgra.b = b;
bgra.g = g;
bgra.r = r;
bgra.a = a;
return bgra;
}

#define ALPHA 0xFF // fully opaque
#define ALPHA32_MASK (ALPHA << 24)
#define SETRGBCOLOR(r, g, b) {b, g, r, ALPHA} // to create a RGBQUAD
#define OPAQUE_BLACK (0 | ALPHA32_MASK) // Black is RGB 0 0 0
#define SETRGBCOLOR(r, g, b) makeBGRA(b, g, r, ALPHA)
#define OPAQUE_BLACK SETRGBCOLOR(0, 0, 0) // Black is RGB 0 0 0


// Types ____________________________________________________________
Expand Down Expand Up @@ -97,15 +124,6 @@ enum AppleFont_e
// turn on struct member padding
#pragma pack(push,1)

// TODO: Replace with WinGDI.h / RGBQUAD
struct bgra_t
{
uint8_t b;
uint8_t g;
uint8_t r;
uint8_t a; // reserved on Win32
};

struct WinBmpHeader_t
{
// BITMAPFILEHEADER // Addr Size
Expand Down
1 change: 1 addition & 0 deletions source/frontends/common2/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ set(HEADER_FILES
commonframe.h
commoncontext.h
controllerdoublepress.h
emscriptenpaths.h
gnuframe.h
fileregistry.h
ptreeregistry.h
Expand Down
15 changes: 15 additions & 0 deletions source/frontends/common2/emscriptenpaths.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#pragma once

#ifdef __EMSCRIPTEN__

namespace common2
{
namespace emscripten
{
constexpr const char *STORAGE = "/storage"; // IDBFS persistent mount (SDL3)
constexpr const char *DEFAULTS = "/defaults"; // read-only preloaded bundle
constexpr const char *DISKS = "/disks"; // disk images & symbols
} // namespace emscripten
} // namespace common2

#endif
14 changes: 14 additions & 0 deletions source/frontends/common2/fileregistry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ namespace

std::string getLocation() const override;

protected:
void synchronise() override;

private:
const std::filesystem::path myFilename;
};
Expand All @@ -53,6 +56,17 @@ namespace
}
}

void Configuration::synchronise()
{
try
{
saveToYamlFile(myFilename.string());
}
catch (const std::exception &)
{
}
}

Configuration::~Configuration()
{
try
Expand Down
5 changes: 5 additions & 0 deletions source/frontends/common2/gnuframe.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "StdAfx.h"
#include "frontends/common2/gnuframe.h"
#include "frontends/common2/utils.h"
#include "frontends/common2/emscriptenpaths.h"
#include "apple2roms_data.h"

#ifdef __APPLE__
Expand Down Expand Up @@ -76,7 +77,11 @@ namespace common2
: CommonFrame(options)
{
// should this go down to LinuxFrame (maybe Initialisation?)
#ifndef __EMSCRIPTEN__
g_sProgramDir = getResourceFolder("bin").string() + PATH_SEPARATOR;
#else
g_sProgramDir = std::string(emscripten::DISKS) + PATH_SEPARATOR;
#endif
LogFileOutput("Program Dir: '%s'\n", g_sProgramDir.c_str());
}

Expand Down
2 changes: 2 additions & 0 deletions source/frontends/common2/ptreeregistry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,13 @@ namespace common2
void PTreeRegistry::putString(const std::string &section, const std::string &key, const std::string &value)
{
myData[section][key] = value;
synchronise();
}

void PTreeRegistry::putDWord(const std::string &section, const std::string &key, const uint32_t value)
{
myData[section][key] = std::to_string(value);
synchronise();
}

const std::map<std::string, std::map<std::string, std::string>> &PTreeRegistry::getAllValues() const
Expand Down
Loading
Loading