#include "std.h"
#include "resource.h"
#include "emul.h"
#include "vars.h"
#include "snapshot.h"
#include "tape.h"
#include "memory.h"
#include "opendlg.h"
#include "draw.h"
#include "config.h"
#include "z80.h"
#include "sshot_png.h"
#include "funcs.h"
#include "util.h"
#include <io.h> // фы access [NS]
int readSP();
int readSNA48();
int readSNA128();
int readZ80();
int writeSNA(FILE*);
int load_arc(char *fname);
//=============================================================================
SNAP what_is(char *filename)
{
FILE *ff = fopen(filename, "rb");
if (!ff) return snNOFILE;
snapsize = unsigned(fread(snbuf, 1, sizeof snbuf, ff));
fclose(ff);
if (snapsize == sizeof snbuf) return snTOOLARGE;
SNAP type = snUNKNOWN;
char *ptr = strrchr(filename, '.');
unsigned ext = ptr? (*(unsigned*)(ptr+1) | 0x20202020U) : 0;
if (snapsize < 32) return type;
if (snapsize == 131103 || snapsize == 147487) type = snSNA_128;
if (snapsize == 49179) type = snSNA_48;
if (ext == WORD4('t','a','p',' ')) type = snTAP;
if (ext == WORD4('z','8','0',' ')) type = snZ80;
if(ext == WORD4('p', 'a', 'l', ' ') && (snapsize == sizeof(comp.comp_pal)))
{
type = snPAL;
return type;
}
if (conf.trdos_present)
{
if (!snbuf[13] && snbuf[14] && (int)snapsize == snbuf[14]*256+17) type = snHOB;
if (snapsize >= 8192 && !(snapsize & 0xFF) && ext == WORD4('t','r','d',' ')) type = snTRD;
if (snapsize >= 8192 && ext == WORD4('i','s','d',' '))
type = snISD;
if (snapsize >= 8192 && ext == WORD4('p','r','o',' '))
type = snPRO;
if(snapsize >= 8192 && ext == WORD4('d', 's', 'k', ' '))
type = snDSK;
if(snapsize >= 8192 && ext == WORD4('i', 'p', 'f', ' '))
type = snIPF;
if (!memcmp(snbuf, "SINCLAIR", 8))
{
unsigned nfiles = snbuf[8];
unsigned nsec = 0;
for(unsigned i = 0; i < nfiles; i++)
{
nsec += snbuf[9+14*i+13];
}
if(snapsize >= 9 + nfiles * 14 + nsec * 0x100)
type = snSCL;
}
if (!memcmp(snbuf, "FDI", 3) && *(unsigned short*)(snbuf+4) <= MAX_CYLS && *(unsigned short*)(snbuf+6) <= 2) type = snFDI;
if (((*(short*)snbuf|0x2020) == WORD2('t','d')) && snbuf[4] >= 10 && snbuf[4] <= 21 && snbuf[9] <= 2) type = snTD0;
if (*(unsigned*)snbuf == WORD4('U','D','I','!') && *(unsigned*)(snbuf+4)==snapsize-4 && snbuf[9] < MAX_CYLS && snbuf[10]<2 && !snbuf[8]) type = snUDI;
}
if (snapsize > 10 && !memcmp(snbuf, "ZXTape!\x1A", 8))
{
type = snTZX;
}
if (snapsize > 0x22 && !memcmp(snbuf, "Compressed Square Wave\x1A", 23)) type = snCSW;
if (*(unsigned short*)snbuf == WORD2('S','P') && *(unsigned short*)(snbuf+2)+0x26 == (int)snapsize) type = snSP;
return type;
}
//=============================================================================
static int readPAL();
//=============================================================================
int loadsnap(char *filename)
{
//-------------------------------------------------------------------------
if (load_arc(filename))
return 1;
//-------------------------------------------------------------------------
SNAP type = what_is(filename);
//-------------------------------------------------------------------------
if (type >= snHOB)
{
if (trd_toload == -1U)
{
unsigned last = -1U;
for (unsigned i = 0; i < 4; i++)
if (trd_loaded[i]) last = i;
trd_toload = (last == -1U) ? 0 :
(
(type == snHOB) ? last :
(last+1) & 3
);
}
//---------------------------------------------------------------------
for (unsigned k = 0; k < 4; k++)
{
if ((k != trd_toload) && (!stricmp(comp.fdd[k].name, filename)))
{
// ьхЁчёър ьхЁчюёЄ№ !!!
static char err[] = "This disk image is already loaded to drive X:\n"
"Do you still want to load it to drive Y:?";
err[43] = char(k+'A');
err[84] = char(trd_toload+'A');
if (MessageBox(GetForegroundWindow(), err, "Warning", MB_YESNO | MB_ICONWARNING) == IDNO)
return 1;
}
}
//---------------------------------------------------------------------
FDD *drive = comp.fdd + trd_toload;
//---------------------------------------------------------------------
if (!drive->test())
return 0;
//---------------------------------------------------------------------
comp.wd.Eject(trd_toload);
int ok = drive->read(type);
//---------------------------------------------------------------------
if (ok)
{
//-----------------------------------------------------------------
if (*conf.appendboot)
drive->addboot();
//-----------------------------------------------------------------
strcpy(drive->name, filename);
//-----------------------------------------------------------------
if (GetFileAttributes(filename) & FILE_ATTRIBUTE_READONLY)
conf.trdos_wp[trd_toload] = 1;
//-----------------------------------------------------------------
drive->snaptype = (type == snHOB || type == snSCL) ? snTRD :
type;
trd_loaded[trd_toload] = 1;
//---------Alone Coder
char *name = filename;
for (char *x = name; *x; x++)
if (*x == '\\')
name = x + 1;
strcpy(temp.LastSnapName, name);
char *p = strrchr(temp.LastSnapName, '.');
if (p)
{
*p = 0;
}
//printf("loaded file name printing\n");
char wintitle[0x200];
strcpy(wintitle,name);
//strcat(wintitle," - UnrealSpeccy");
strcat(wintitle," - Unreal_NS"); //фы чруЁєцрхьюую фшёъют
SetWindowText(wnd, wintitle);
//~---------Alone Coder
}
//---------------------------------------------------------------------
return ok;
}
//-------------------------------------------------------------------------
if (type == snSP) return readSP();
if (type == snSNA_48) return readSNA48();
if (type == snSNA_128) return readSNA128();
if (type == snZ80) return readZ80();
if (type == snTAP) return readTAP();
if (type == snTZX) return readTZX();
if (type == snCSW) return readCSW();
if (type == snPAL) return readPAL();
//-------------------------------------------------------------------------
return 0;
}
//=============================================================================
//=============================================================================
int readSNA128()
{
//-------------------------------------------------------------------------
if ((conf.mem_model == MM_PENTAGON) && (conf.Sna128Lock))
{
conf.ramsize = 128;
temp.ram_mask = u8((conf.ramsize-1) >> 4);
}
//-------------------------------------------------------------------------
hdrSNA128 *hdr = (hdrSNA128*)snbuf;
reset(hdr->trdos ? RM_DOS :
RM_SOS);
cpu.alt.af = hdr->altaf;
cpu.alt.bc = hdr->altbc;
cpu.alt.de = hdr->altde;
cpu.alt.hl = hdr->althl;
cpu.af = hdr->af;
cpu.bc = hdr->bc;
cpu.de = hdr->de;
cpu.hl = hdr->hl;
cpu.ix = hdr->ix;
cpu.iy = hdr->iy;
cpu.sp = hdr->sp;
cpu.pc = hdr->pc;
cpu.i = hdr->i;
cpu.r_low = hdr->r;
cpu.r_hi = hdr->r & 0x80;
cpu.im = hdr->im;
cpu.iff1 = cpu.iff2 = (hdr->iff >> 2) & 1;
comp.p7FFD = hdr->p7FFD;
comp.pFE = hdr->pFE;
comp.border_attr = comp.pFE & 7;
memcpy(memory + PAGE * 5, hdr->page5, PAGE);
memcpy(memory + PAGE * 2, hdr->page2, PAGE);
memcpy(memory + PAGE * (hdr->p7FFD & 7), hdr->active_page, PAGE);
unsigned char *newpage = snbuf + 0xC01F;
unsigned char mapped = u8(0x24U | (1 << (hdr->p7FFD & 7)));
//-------------------------------------------------------------------------
for (unsigned char i = 0; i < 8; i++)
{
if (!(mapped & (1 << i)))
{
memcpy(memory + PAGE*i, newpage, PAGE);
newpage += PAGE;
}
}
//-------------------------------------------------------------------------
set_banks();
return 1;
}
//=============================================================================
//=============================================================================
int readSNA48()
{
//conf.mem_model = MM_PENTAGON; conf.ramsize = 128; // molodcov_alex
reset(RM_SOS);
hdrSNA128 *hdr = (hdrSNA128*)snbuf;
cpu.alt.af = hdr->altaf;
cpu.alt.bc = hdr->altbc;
cpu.alt.de = hdr->altde;
cpu.alt.hl = hdr->althl;
cpu.af = hdr->af;
cpu.bc = hdr->bc;
cpu.de = hdr->de;
cpu.hl = hdr->hl;
cpu.ix = hdr->ix;
cpu.iy = hdr->iy;
cpu.sp = hdr->sp;
cpu.i = hdr->i;
cpu.r_low = hdr->r;
cpu.r_hi = hdr->r & 0x80;
cpu.im = hdr->im;
cpu.iff1 = cpu.iff2 = (hdr->iff >> 2) & 1;
comp.p7FFD = 0x30;
comp.pEFF7 |= EFF7_LOCKMEM; //Alone Coder
comp.pFE = hdr->pFE;
comp.border_attr = comp.pFE & 7;
memcpy(memory + PAGE * 5, hdr->page5, PAGE);
memcpy(memory + PAGE * 2, hdr->page2, PAGE);
memcpy(memory + PAGE * 0, hdr->active_page, PAGE);
cpu.pc = cpu.DirectRm(cpu.sp) + 0x100 * cpu.DirectRm(cpu.sp + 1);
cpu.sp += 2;
set_banks();
return 1;
}
//=============================================================================
//=============================================================================
int readSP()
{
//conf.mem_model = MM_PENTAGON; conf.ramsize = 128; // molodcov_alex
reset(RM_SOS);
hdrSP *hdr = (hdrSP*)snbuf;
cpu.alt.af = hdr->altaf;
cpu.alt.bc = hdr->altbc;
cpu.alt.de = hdr->altde;
cpu.alt.hl = hdr->althl;
cpu.af = hdr->af;
cpu.bc = hdr->bc;
cpu.de = hdr->de;
cpu.hl = hdr->hl;
cpu.ix = hdr->ix;
cpu.iy = hdr->iy;
cpu.sp = hdr->sp;
cpu.pc = hdr->pc;
cpu.i = hdr->i;
cpu.r_low = hdr->r;
cpu.r_hi = hdr->r & 0x80;
cpu.iff1 = (hdr->flags & 1);
cpu.im = 1 + ((hdr->flags >> 1) & 1);
cpu.iff2 = (hdr->flags >> 2) & 1;
comp.p7FFD = 0x30;
comp.pEFF7 |= EFF7_LOCKMEM; //Alone Coder
comp.pFE = hdr->pFE;
comp.border_attr = comp.pFE & 7;
for (unsigned i = 0; i < hdr->len; i++)
cpu.DirectWm(hdr->start + i, snbuf[i + 0x26]);
set_banks();
return 1;
}
//=============================================================================
//=============================================================================
int writeSNA(FILE *ff)
{
/* if (conf.ramsize != 128)
{
MessageBox(GetForegroundWindow(), "SNA format can hold only\r\n128kb memory models", "Save", MB_ICONERROR);
return 0;
}*/ //Alone Coder
hdrSNA128 *hdr = (hdrSNA128*)snbuf;
hdr->trdos = (comp.flags & CF_TRDOS) ? 1 :
0;
hdr->altaf = u16(cpu.alt.af);
hdr->altbc = u16(cpu.alt.bc);
hdr->altde = u16(cpu.alt.de);
hdr->althl = u16(cpu.alt.hl);
hdr->af = u16(cpu.af);
hdr->bc = u16(cpu.bc);
hdr->de = u16(cpu.de);
hdr->hl = u16(cpu.hl);
hdr->ix = u16(cpu.ix);
hdr->iy = u16(cpu.iy);
hdr->sp = u16(cpu.sp);
hdr->pc = u16(cpu.pc);
hdr->i = cpu.i;
hdr->r = (cpu.r_low & 0x7F)+cpu.r_hi;
hdr->im = cpu.im;
hdr->iff = cpu.iff2 ? 4 :
0;
hdr->p7FFD = comp.p7FFD;
hdr->pFE = comp.pFE;
comp.border_attr = comp.pFE & 7;
unsigned savesize = sizeof(hdrSNA128);
unsigned char mapped = u8(0x24U | (1 << (comp.p7FFD & 7)));
//-------------------------------------------------------------------------
if (comp.p7FFD == 0x30) //эю фы яхэЄруюэр ¤Єю эх чэрўхЄ 48 lock !!!
{ // save 48k
mapped = 0xFF;
savesize = 0xC01B;
hdr->sp -= 2;
cpu.DirectWm(hdr->sp, cpu.pcl);
cpu.DirectWm(hdr->sp+1, cpu.pch);
}
//-------------------------------------------------------------------------
memcpy(hdr->page5, memory+PAGE*5, PAGE);
memcpy(hdr->page2, memory+PAGE*2, PAGE);
memcpy(hdr->active_page, memory+PAGE*(comp.p7FFD & 7), PAGE);
//-------------------------------------------------------------------------
if (fwrite(hdr, 1, savesize, ff) != savesize)
return 0;
//-------------------------------------------------------------------------
for (unsigned char i = 0; i < 8; i++)
{
if (!(mapped & (1 << i)))
{
if (fwrite(memory + PAGE*i, 1, PAGE, ff) != PAGE)
return 0;
}
}
//-------------------------------------------------------------------------
return 1;
}
//=============================================================================
//=============================================================================
static void unpack_page(unsigned char *dst, unsigned dstlen, unsigned char *src, unsigned srclen)
{
memset(dst, 0, dstlen);
while (srclen > 0 && dstlen > 0)
{
if (srclen >= 4 && src[0] == 0xED && src[1] == 0xED)
{
size_t len = src[2];
memset(dst, src[3], len);
dstlen -= len;
srclen -= 4;
src += 4;
dst += len;
}
else
{
*dst++ = *src++;
dstlen--;
srclen--;
}
}
}
//=============================================================================
//=============================================================================
int readZ80()
{
//conf.mem_model = MM_PENTAGON; conf.ramsize = 128; // molodcov_alex
hdrZ80 *hdr = (hdrZ80*)snbuf;
unsigned char *ptr = snbuf + 30;
unsigned char model48k = (hdr->model < 3);
//-------------------------------------------------------------------------
reset((model48k|(hdr->p7FFD & 0x10)) ? RM_SOS :
RM_128);
//-------------------------------------------------------------------------
if (hdr->flags == 0xFF)
hdr->flags = 1;
//-------------------------------------------------------------------------
if (hdr->pc == 0)
{ // 2.01
ptr += 2 + hdr->len;
hdr->pc = hdr->newpc;
memset(RAM_BASE_M, 0, PAGE*8); // clear 128k - first 8 pages
unsigned char * const p48[] =
{
base_sos_rom, nullptr, nullptr, nullptr,
RAM_BASE_M + 2 * PAGE, RAM_BASE_M + 0 * PAGE, nullptr, nullptr,
RAM_BASE_M + 5 * PAGE, nullptr, nullptr, nullptr
};
unsigned char * const p128[] =
{
base_sos_rom, base_dos_rom, base_128_rom, RAM_BASE_M + 0 * PAGE,
RAM_BASE_M + 1 * PAGE, RAM_BASE_M + 2 * PAGE, RAM_BASE_M + 3 * PAGE, RAM_BASE_M + 4 * PAGE,
RAM_BASE_M + 5 * PAGE, RAM_BASE_M + 6 * PAGE, RAM_BASE_M + 7 * PAGE, nullptr
};
//---------------------------------------------------------------------
while (ptr < snbuf+snapsize)
{
unsigned len = *(unsigned short*)ptr;
//-----------------------------------------------------------------
if (ptr[2] > 11)
return 0;
//-----------------------------------------------------------------
unsigned char *dstpage = model48k ? p48[ptr[2]] :
p128[ptr[2]];
//-----------------------------------------------------------------
if (!dstpage)
return 0;
//-----------------------------------------------------------------
ptr += 3;
//-----------------------------------------------------------------
if (len == 0xFFFF)
{
len = PAGE;
memcpy(dstpage, ptr, len);
}
else
{
unpack_page(dstpage, PAGE, ptr, len);
}
//-----------------------------------------------------------------
ptr += len;
//-----------------------------------------------------------------
}
//---------------------------------------------------------------------
}
else
{
unsigned len = snapsize - 30;
unsigned char *mem48 = ptr;
//---------------------------------------------------------------------
if (hdr->flags & 0x20)
unpack_page(mem48 = snbuf + 4*PAGE, 3*PAGE, ptr, len);
//---------------------------------------------------------------------
memcpy(memory + (PAGE * 5), mem48, PAGE);
memcpy(memory + (PAGE * 2), mem48 + PAGE, PAGE);
memcpy(memory + (PAGE * 0), mem48 + (2 * PAGE), PAGE);
model48k = 1;
}
//-------------------------------------------------------------------------
cpu.a = hdr->a;
cpu.f = hdr->f;
cpu.bc = hdr->bc;
cpu.de = hdr->de; cpu.hl = hdr->hl;
cpu.alt.bc = hdr->bc1;
cpu.alt.de = hdr->de1;
cpu.alt.hl = hdr->hl1;
cpu.alt.a = hdr->a1;
cpu.alt.f = hdr->f1;
cpu.pc = hdr->pc;
cpu.sp = hdr->sp;
cpu.ix = hdr->ix;
cpu.iy = hdr->iy;
cpu.i = hdr->i;
cpu.r_low = hdr->r & 0x7F;
cpu.r_hi = u8((hdr->flags & 1U) << 7U);
comp.pFE = (hdr->flags >> 1) & 7;
comp.border_attr = comp.pFE;
cpu.iff1 = hdr->iff1;
cpu.iff2 = hdr->iff2;
cpu.im = (hdr->im & 3);
comp.p7FFD = (model48k) ? 0x30 :
hdr->p7FFD;
//-------------------------------------------------------------------------
if (hdr->len == 55) // version 3.0 (with 1ffd)
comp.p1FFD = hdr->p1FFD;
//-------------------------------------------------------------------------
if (model48k)
comp.pEFF7 |= EFF7_LOCKMEM; //Alone Coder
//-------------------------------------------------------------------------
set_banks();
//-------------------------------------------------------------------------
return 1;
}
//=============================================================================
//=============================================================================
static int readPAL()
{
memcpy(comp.comp_pal, snbuf, snapsize);
temp.comp_pal_changed = 1;
if (conf.ula_plus)
{
// ┼ёыш яЁшёєЄёЄтєхЄ ULA+, Єю ёЁрчє ш ръЄштшЁєхь хх (ўЄюс√ шчьхэхэш ярышЄЁ√ с√ыш тшфэ√)
comp.ula_plus_en = true;
}
return 1;
}
//=============================================================================
//=============================================================================
static int writePAL(FILE *ff)
{
if ( fwrite( comp.comp_pal,
1,
sizeof(comp.comp_pal),
ff
)
!= sizeof(comp.comp_pal)
)
{
return 0;
}
return 1;
}
//=============================================================================
#define arctmp ((char*)rbuf)
static char *arc_fname;
//=============================================================================
static INT_PTR CALLBACK ArcDlg(HWND dlg, UINT msg, WPARAM wp, LPARAM lp)
{
(void)lp;
//-------------------------------------------------------------------------
if (msg == WM_INITDIALOG)
{
for (char *dst = arctmp; *dst; dst += strlen(dst)+1)
SendDlgItemMessage(dlg, IDC_ARCLIST, LB_ADDSTRING, 0, (LPARAM)dst);
SendDlgItemMessage(dlg, IDC_ARCLIST, LB_SETCURSEL, 0, 0);
return 1;
}
//-------------------------------------------------------------------------
if ( ((msg == WM_COMMAND) && (wp == IDCANCEL))
||
((msg == WM_SYSCOMMAND) && ((wp & 0xFFF0) == SC_CLOSE))
)
{
EndDialog(dlg, 0);
}
//-------------------------------------------------------------------------
if ( (msg == WM_COMMAND)
&&
( (LOWORD(wp) == IDOK)
||
((HIWORD(wp) == LBN_DBLCLK) && (LOWORD(wp) == IDC_ARCLIST))
)
)
{
int n = int(SendDlgItemMessage(dlg, IDC_ARCLIST, LB_GETCURSEL, 0, 0));
char *dst = arctmp;
for (int q = 0; q < n; q++)
dst += strlen(dst) + 1;
arc_fname = dst;
EndDialog(dlg, 0);
}
return 0;
}
//=============================================================================
//=============================================================================
static bool filename_ok(char *fname)
{
for (char *wc = skiparc; *wc; wc += strlen(wc) + 1)
if (wcmatch(fname, wc))
return 0;
return 1;
}
//=============================================================================
//=============================================================================
int load_arc(char *fname)
{
char *ext = strrchr(fname, '.');
//-------------------------------------------------------------------------
if (!ext)
return 0;
//-------------------------------------------------------------------------
ext++;
char *cmdtmp;
char done = 0;
//-------------------------------------------------------------------------
for (char *x = arcbuffer; *x; x = cmdtmp + strlen(cmdtmp)+1)
{
cmdtmp = x + strlen(x) + 1;
//---------------------------------------------------------------------
if (stricmp(ext, x))
continue;
//---------------------------------------------------------------------
char dir[0x200];
GetCurrentDirectory(sizeof dir, dir);
char tmp[0x200];
GetTempPath(sizeof tmp, tmp);
char d1[0x20];
sprintf(d1, "us%08lX", GetTickCount());
SetCurrentDirectory(tmp);
CreateDirectory(d1, nullptr);
SetCurrentDirectory(d1);
//---------------------------------------------------------------------
color();
char cmdln[0x200]; sprintf(cmdln, cmdtmp, fname);
STARTUPINFO si = { sizeof si };
si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = SW_HIDE;
PROCESS_INFORMATION pi;
unsigned flags = CREATE_NEW_CONSOLE;
HANDLE hc = CreateFile("CONOUT$", GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr);
//---------------------------------------------------------------------
if (hc != INVALID_HANDLE_VALUE)
{
CloseHandle(hc);
flags = 0;
}
//---------------------------------------------------------------------
if (CreateProcess(nullptr, cmdln, nullptr, nullptr, 0, flags, nullptr, nullptr, &si, &pi)) {
WaitForSingleObject(pi.hProcess, INFINITE);
DWORD code; GetExitCodeProcess(pi.hProcess, &code);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
//-----------------------------------------------------------------
if (!code || MessageBox(GetForegroundWindow(), "Broken archive", nullptr, MB_ICONERROR | MB_OKCANCEL) == IDOK)
{
WIN32_FIND_DATA fd;
HANDLE h;
char *dst = arctmp;
unsigned nfiles = 0;
//-------------------------------------------------------------
if ((h = FindFirstFile("*.*", &fd)) != INVALID_HANDLE_VALUE)
{
//---------------------------------------------------------
do
{
if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && filename_ok(fd.cFileName))
{
strcpy(dst, fd.cFileName);
dst += strlen(dst) + 1;
nfiles++;
}
}
while (FindNextFile(h, &fd));
//---------------------------------------------------------
FindClose(h);
}
//-------------------------------------------------------------
*dst = 0;
arc_fname = nullptr;
//-------------------------------------------------------------
if (nfiles == 1)
arc_fname = arctmp;
//-------------------------------------------------------------
if (nfiles > 1)
DialogBox(hIn, MAKEINTRESOURCE(IDD_ARC), GetForegroundWindow(), ArcDlg);
//-------------------------------------------------------------
if (!nfiles)
MessageBox(GetForegroundWindow(), "Empty archive!", nullptr, MB_ICONERROR | MB_OK);
//-------------------------------------------------------------
char buf[0x200]; strcpy(buf, tmp); strcat(buf, "\\");
strcat(buf, d1);
strcat(buf, "\\");
//-------------------------------------------------------------
if (arc_fname)
{
strcat(buf, arc_fname);
arc_fname = buf;
}
//-------------------------------------------------------------
if (arc_fname && !(done = (char)loadsnap(arc_fname)))
MessageBox(GetForegroundWindow(), "loading error", arc_fname, MB_ICONERROR);
//-------------------------------------------------------------
if (!done)
done = -1;
//-------------------------------------------------------------
}
//-----------------------------------------------------------------
// delete junk
SetCurrentDirectory(tmp);
SetCurrentDirectory(d1);
WIN32_FIND_DATA fd;
HANDLE h;
//-----------------------------------------------------------------
if ((h = FindFirstFile("*.*", &fd)) != INVALID_HANDLE_VALUE)
{
//-------------------------------------------------------------
do
{
DeleteFile(fd.cFileName);
}
while (FindNextFile(h, &fd));
//-------------------------------------------------------------
FindClose(h);
}
}
SetCurrentDirectory(tmp);
RemoveDirectory(d1);
SetCurrentDirectory(dir);
eat();
//---------------------------------------------------------------------
if (done)
return done > 0 ? 1 :
0;
//---------------------------------------------------------------------
}
eat();
return 0;
}
//=============================================================================
//=============================================================================
void opensnap(unsigned index)
{
char mask[0x200];
*mask = 0;
//-------------------------------------------------------------------------
for (char *x = arcbuffer; *x; )
{
strcat(mask, ";*.");
strcat(mask, x);
x += strlen(x) + 1;
x += strlen(x) + 1;
}
//-------------------------------------------------------------------------
char fline[0x400];
const char *src = "all (sna,z80,sp,tap,tzx,csw,trd,scl,fdi,td0,udi,isd,pro,dsk,ipf,hobeta,pal)\0"
"*.sna;*.z80;*.sp;*.tap;*.tzx;*.csw;*.trd;*.scl;*.td0;*.udi;*.fdi;*.isd;*.pro;*.dsk;*.ipf;*.$?;*.!?;*.pal<\0"
"Disk B (trd,scl,fdi,td0,udi,isd,pro,dsk,ipf,hobeta)\0*.trd;*.scl;*.fdi;*.udi;*.td0;*.isd;*.pro;*.dsk;*.ipf;*.$?<\0"
"Disk C (trd,scl,fdi,td0,udi,isd,pro,dsk,ipf,hobeta)\0*.trd;*.scl;*.fdi;*.udi;*.td0;*.isd;*.pro;*.dsk;*.ipf;*.$?<\0"
"Disk D (trd,scl,fdi,td0,udi,isd,pro,dsk,ipf,hobeta)\0*.trd;*.scl;*.fdi;*.udi;*.td0;*.isd;*.pro;*.dsk;*.ipf;*.$?<\0\0>";
//-------------------------------------------------------------------------
if (!conf.trdos_present)
src = "ZX files (sna,z80,tap,tzx,csw,pal)\0*.sna;*.z80;*.tap;*.tzx;*.csw;*.pal<\0\0>";
//-------------------------------------------------------------------------
for (char *dst = fline; *src != '>'; src++)
{
//---------------------------------------------------------------------
if (*src == '<')
{
strcpy(dst, mask);
dst += strlen(dst);
}
//---------------------------------------------------------------------
else
{
*dst++ = *src;
}
//---------------------------------------------------------------------
}
//-------------------------------------------------------------------------
OPENFILENAME ofn = { };
char fname[0x200];
*fname = 0;
char dir[0x200];
GetCurrentDirectory(sizeof dir, dir);
ofn.lStructSize = (WinVerMajor < 5) ? OPENFILENAME_SIZE_VERSION_400 :
sizeof(OPENFILENAME);
ofn.hwndOwner = GetForegroundWindow();
ofn.lpstrFilter = fline;
ofn.lpstrFile = fname;
ofn.nMaxFile = sizeof fname;
ofn.lpstrTitle = "Load Snapshot / Disk / Tape";
ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
ofn.nFilterIndex = DWORD(index);
ofn.lpstrInitialDir = dir;
// __debugbreak();
//-------------------------------------------------------------------------
if (GetSnapshotFileName(&ofn, 0))
{
trd_toload = ofn.nFilterIndex - 1;
if (!loadsnap(fname))
MessageBox(GetForegroundWindow(), fname, "loading error", MB_ICONERROR);
}
//-------------------------------------------------------------------------
eat();
}
//=============================================================================
//=============================================================================
static const int mx_typs = (1 + 4 * 6);
static unsigned char snaps[mx_typs];
static unsigned exts[mx_typs];
static unsigned drvs[mx_typs];
static unsigned snp;
//=============================================================================
//=============================================================================
static void addref(LPSTR &ptr, unsigned char sntype, const char *ref, unsigned drv, unsigned ext)
{
strcpy(ptr, ref);
ptr += strlen(ptr) + 1;
strcpy(ptr, ref + strlen(ref) + 1);
ptr += strlen(ptr) + 1;
drvs[snp] = drv;
exts[snp] = ext;
snaps[snp++] = sntype;
}
//=============================================================================
//=============================================================================
void savesnap(int diskindex)
{
again:
OPENFILENAME ofn = { };
char fname[0x200];
*fname = 0;
//-------------------------------------------------------------------------
if (diskindex >= 0)
{
strcpy(fname, comp.fdd[diskindex].name);
size_t ln = strlen(fname);
if (ln > 4 && (*(unsigned*)(fname+ln-4) | WORD4(0,0x20,0x20,0x20)) == WORD4('.','s','c','l'))
*(unsigned*)(fname+ln-4) = WORD4('.','t','r','d');
}
//-------------------------------------------------------------------------
snp = 1;
char types[600], *ptr = types;
//-------------------------------------------------------------------------
if (diskindex < 0)
{
exts[snp] = WORD4('s','n','a',0);
snaps[snp] = snSNA_128; // default
addref(ptr, snSNA_128, "ZX-Spectrum 128K snapshot (SNA)\0*.sna", -1U, WORD4('s','n','a',0));
exts[snp] = WORD4('p', 'a', 'l', 0);
snaps[snp] = snPAL;
addref(ptr, snPAL, "Palette (ULA+)\0*.pal", -1U, WORD4('p', 'a', 'l', 0));
}
//-------------------------------------------------------------------------
ofn.lStructSize = (WinVerMajor < 5) ? OPENFILENAME_SIZE_VERSION_400 :
sizeof(OPENFILENAME);
ofn.nFilterIndex = 1;
//-------------------------------------------------------------------------
if (conf.trdos_present)
{
static char mask[] = "Disk A (TRD)\0*.trd";
//---------------------------------------------------------------------
static const char ex[][3] =
{
{'T','R','D'},
{'F','D','I'},
{'T','D','0'},
{'U','D','I'},
{'I','S','D'},
{'P','R','O'}
};
//---------------------------------------------------------------------
static const unsigned ex2[] =
{
snTRD,
snFDI,
snTD0,
snUDI,
snISD,
snPRO
};
//---------------------------------------------------------------------
for (unsigned n = 0; n < 4; n++)
{
//-----------------------------------------------------------------
if (!comp.fdd[n].rawdata)
continue;
//-----------------------------------------------------------------
if (diskindex >= 0 && unsigned(diskindex) != n)
continue;
//-----------------------------------------------------------------
mask[5] = char('A'+n);
//-----------------------------------------------------------------
for (size_t i = 0; i < sizeof ex/sizeof(ex[0]); i++)
{
//-------------------------------------------------------------
if ((unsigned(diskindex) == n) && (ex2[i] == comp.fdd[n].snaptype))
ofn.nFilterIndex = snp;
//-------------------------------------------------------------
memcpy(mask+8, ex[i], 3);
memcpy(mask+15, ex[i], 3);
addref( ptr,
u8(ex2[i]),
mask,
n,
(*(const unsigned*)ex[i] & 0xFFFFFF) | 0x202020
);
}
//-----------------------------------------------------------------
}
//---------------------------------------------------------------------
} //conf.trdos_present
//-------------------------------------------------------------------------
ofn.lpstrFilter = types;
*ptr = 0;
ofn.lpstrFile = fname;
ofn.nMaxFile = sizeof fname;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY;
ofn.hwndOwner = GetForegroundWindow();
char *path = strrchr(fname, '\\');
//-------------------------------------------------------------------------
if (path)
{ // check if directory exists (for files opened from archive)
char x = *path;
*path = 0;
unsigned atr = GetFileAttributes(fname);
*path = x;
//---------------------------------------------------------------------
if (atr == -1U || !(atr & FILE_ATTRIBUTE_DIRECTORY))
*fname = 0;
//---------------------------------------------------------------------
}
else
{
path = fname;
}
//-------------------------------------------------------------------------
path = strrchr(path, '.');
if (path)
*path = 0; // delete extension
//-------------------------------------------------------------------------
if (GetSnapshotFileName(&ofn, 1))
{
//printf("get snapshot filename\n"); //Єюы№ъю яЁш чряшёш
//яЁш юЄъЁ√Єшш эх ёЁрсрЄ√трхЄ
char *fn = strrchr(ofn.lpstrFile, '\\');
fn = fn ? fn + 1 :
ofn.lpstrFile;
char *extpos = strrchr(fn, '.');
//---------------------------------------------------------------------
if (!extpos || stricmp(extpos+1, (char*)&exts[ofn.nFilterIndex]))
{
char *dst = fn + strlen(fn);
*dst++ = '.';
*(unsigned*)dst = exts[ofn.nFilterIndex];
}
//---------------------------------------------------------------------
if ( (GetFileAttributes(ofn.lpstrFile) != INVALID_FILE_ATTRIBUTES) &&
(IDNO == MessageBox(GetForegroundWindow(), "File exists. Overwrite ?", "Save", MB_ICONQUESTION | MB_YESNO))
)
{
goto again;
}
//---------------------------------------------------------------------
FILE *ff = fopen(ofn.lpstrFile, "wb");
//---------------------------------------------------------------------
if (ff)
{
int res = 0;
FDD *saveto = comp.fdd + drvs[ofn.nFilterIndex];
//-----------------------------------------------------------------
switch (snaps[ofn.nFilterIndex])
{
case snSNA_128: res = writeSNA(ff); break;
case snPAL: res = writePAL(ff); break;
case snTRD: res = saveto->write_trd(ff); break;
case snUDI: res = saveto->write_udi(ff); break;
case snFDI: res = saveto->write_fdi(ff); break;
case snTD0: res = saveto->write_td0(ff); break;
case snISD: res = saveto->write_isd(ff); break;
case snPRO: res = saveto->write_pro(ff); break;
}
//-----------------------------------------------------------------
fclose(ff);
//-----------------------------------------------------------------
if (!res)
MessageBox(GetForegroundWindow(), "write error", "Save", MB_ICONERROR);
//-----------------------------------------------------------------
else if (drvs[ofn.nFilterIndex]!=-1U)
{
comp.fdd[drvs[ofn.nFilterIndex]].optype=0;
strcpy(comp.fdd[drvs[ofn.nFilterIndex]].name, ofn.lpstrFile);
//---------Alone Coder
char *name = ofn.lpstrFile;
//printf("snaphot filename printing\n");
//-------------------------------------------------------------
for (char *x = name; *x; x++)
{
if (*x == '\\')
name = x+1;
}
//-------------------------------------------------------------
char wintitle[0x200];
strcpy(wintitle,name);
// strcat(wintitle," - UnrealSpeccy");
strcat(wintitle," - Unreal_NS"); // фы ёюїЁрэхээюую фшёър
SetWindowText(wnd, wintitle);
//~---------Alone Coder
}
//-----------------------------------------------------------------
}
//---------------------------------------------------------------------
else
{
MessageBox(GetForegroundWindow(), "Can't open file for writing", "Save", MB_ICONERROR);
}
//---------------------------------------------------------------------
}
//-------------------------------------------------------------------------
eat();
}
//=============================================================================
//=============================================================================
void ConvPal8ToBgr24(u8 *dst, u8 *scrbuf, int dx)
{
u8 *ds = dst;
//-------------------------------------------------------------------------
for(unsigned i = 0; i < temp.oy; i++) // convert to BGR24 format
{
unsigned char *src = scrbuf + int(i) * dx;
//---------------------------------------------------------------------
for (unsigned y = 0; y < temp.ox; y++)
{
ds[0] = pal0[src[y]].peBlue;
ds[1] = pal0[src[y]].peGreen;
ds[2] = pal0[src[y]].peRed;
ds += 3;
}
//---------------------------------------------------------------------
ds = (PBYTE)(ULONG_PTR(ds + 3) & ~ULONG_PTR(3)); // ърцфр ёЄЁюър т√Ёртэхэр эр 4
}
//-------------------------------------------------------------------------
}
//=============================================================================
//=============================================================================
void ConvRgb15ToBgr24(u8 *dst, u8 *scrbuf, int dx)
{
u8 *ds = dst;
//-------------------------------------------------------------------------
for(unsigned i = 0; i < temp.oy; i++) // convert to BGR24 format
{
unsigned char *src = scrbuf + int(i) * dx;
//---------------------------------------------------------------------
for (unsigned y = 0; y < temp.ox; y++)
{
unsigned xx;
xx = *(unsigned*)(src + y*2);
ds[0] = u8((xx & 0x1F) << 3);
ds[1] = u8((xx & 0x03E0) >> 2);
ds[2] = u8((xx & 0x7C00) >> 7);
ds += 3;
}
//---------------------------------------------------------------------
ds = (PBYTE)(ULONG_PTR(ds + 3) & ~ULONG_PTR(3)); // ърцфр ёЄЁюър т√Ёртэхэр эр 4
}
//-------------------------------------------------------------------------
}
//=============================================================================
//=============================================================================
void ConvRgb16ToBgr24(u8 *dst, u8 *scrbuf, int dx)
{
u8 *ds = dst;
//-------------------------------------------------------------------------
for(unsigned i = 0; i < temp.oy; i++) // convert to BGR24 format
{
unsigned char *src = scrbuf + int(i) * dx;
//---------------------------------------------------------------------
for (unsigned y = 0; y < temp.ox; y++)
{
unsigned xx;
xx = *(unsigned*)(src + y*2);
ds[0] = u8((xx&0x1F) << 3);
ds[1] = u8((xx&0x07E0) >> 3);
ds[2] = u8((xx&0xF800) >> 8);
ds += 3;
}
//---------------------------------------------------------------------
ds = (PBYTE)(ULONG_PTR(ds + 3) & ~ULONG_PTR(3)); // ърцфр ёЄЁюър т√Ёртэхэр эр 4
}
//-------------------------------------------------------------------------
}
//=============================================================================
//=============================================================================
void ConvYuy2ToBgr24(u8 *dst, u8 *scrbuf, int dx)
{
u8 *ds = dst;
//-------------------------------------------------------------------------
for(unsigned i = 0; i < temp.oy; i++) // convert to BGR24 format
{
unsigned char *src = scrbuf + int(i) * dx;
//---------------------------------------------------------------------
for (unsigned y = 0; y < temp.ox; y++)
{
unsigned xx;
xx = *(unsigned*)(src + y*2);
int u = src[y / 2 * 4 + 1];
int v = src[y / 2 * 4 + 3];
int Y = src[y * 2];
int r = (int)(.4732927654e-2 * u - 255.3076403 + 1.989858012 * v + .9803921569 * Y);
int g = (int)(-.9756592292 * v + 186.0716700 - .4780256930 * u + .9803921569 * Y);
int b = (int)(.9803921569 * Y + 2.004732928 * u - 255.3076403 - .1014198783e-1 * v); // mapple rulez!
if (r < 0) r = 0; if (r > 255) r = 255;
if (g < 0) g = 0; if (g > 255) g = 255;
if (b < 0) b = 0; if (b > 255) b = 255;
ds[0] = u8(b);
ds[1] = u8(g);
ds[2] = u8(r);
ds += 3;
}
//---------------------------------------------------------------------
ds = (PBYTE)(ULONG_PTR(ds + 3) & ~ULONG_PTR(3)); // ърцфр ёЄЁюър т√Ёртэхэр эр 4
}
//-------------------------------------------------------------------------
}
//=============================================================================
//=============================================================================
void ConvBgr32ToBgr24(u8 *dst, u8 *scrbuf, int dx)
{
u8 *ds = dst;
//-------------------------------------------------------------------------
for(unsigned i = 0; i < temp.oy; i++) // convert to BGR24 format
{
unsigned char *src = scrbuf + int(i) * dx;
//---------------------------------------------------------------------
for (unsigned x = 0; x < temp.ox; x++)
{
ds[0] = src[0];
ds[1] = src[1];
ds[2] = src[2];
src += 4;
ds += 3;
}
//---------------------------------------------------------------------
ds = (PBYTE)(ULONG_PTR(ds + 3) & ~ULONG_PTR(3)); // ърцфр ёЄЁюър т√Ёртэхэр эр 4
}
//-------------------------------------------------------------------------
}
//=============================================================================
TColorConverter ConvBgr24 = nullptr;
//=============================================================================
static void SaveBmp(FILE *File, u8 *ds)
{
//-------------------------------------------------------------------------
static u8 bmpheader32[]=
{
// BITMAPFILEHEADER
0x42, 0x4d, // Type
0x36, 0x10, 0x0e, 0x00, // Size
0x00, 0x00, // Reserved1
0x00, 0x00, // Reserved2
0x36, 0x00, 0x00, 0x00, // OffBits
// BITMAPINFOHEADER
0x28, 0x00, 0x00, 0x00, // Size
0x80, 0x02, 0x00, 0x00, // Width
0xe0, 0x01, 0x00, 0x00, // Height
0x01, 0x00, // Planes
0x18, 0x00, // BitCount
0x00, 0x00, 0x00, 0x00, // Compression
0x00, 0x10, 0x0e, 0x00, // SizeImage
0x00, 0x00, 0x00, 0x00, // XPixelsPerMeter
0x00, 0x00, 0x00, 0x00, // YPixelsPerMeter
0x00, 0x00, 0x00, 0x00, // ClrUsed
0x00, 0x00, 0x00, 0x00 // ClrImportant
};
//-------------------------------------------------------------------------
*(unsigned*)(bmpheader32 + 2) = temp.ox * temp.oy * 3 + sizeof(bmpheader32); // filesize
*(unsigned*)(bmpheader32 + 0x12) = temp.ox;
*(unsigned*)(bmpheader32 + 0x16) = temp.oy;
//-------------------------------------------------------------------------
fwrite(bmpheader32, 1, sizeof(bmpheader32), File);
//-------------------------------------------------------------------------
for (int y = int(temp.oy - 1); y >= 0 ; y--)
{
fwrite(ds + ((unsigned(y) * temp.ox * 3 + 3) & ~3U), 1, temp.ox * 3, File);
}
//-------------------------------------------------------------------------
}
//=============================================================================
//=============================================================================
static void SavePng(FILE *File, u8 *ds)
{
static png_color bkgColor = {127, 127, 127};
if (!temp.PngSupport)
return;
PngSaveImage(File, ds, int(temp.ox), int(temp.oy), bkgColor);
}
//=============================================================================
#define MAKE_RGBQUAD(r,g,b) (ULONG) (u32(b) | (u32(g)<<8) | (u32(r)<<16))
//=============================================================================
static void SaveBmp16c(FILE *File, const u8 *ds)
{
static u8 bmpheader32[]=
{
// BITMAPFILEHEADER
0x42, 0x4d, // Type
0x36, 0x10, 0x0e, 0x00, // Size = 320*200/2 + sizeof(bmpheader32)
0x00, 0x00, // Reserved1
0x00, 0x00, // Reserved2
0x76, 0x00, 0x00, 0x00, // OffBits
// BITMAPINFOHEADER
0x28, 0x00, 0x00, 0x00, // Size
0x40, 0x01, 0x00, 0x00, // Width = 320
0xc8, 0x00, 0x00, 0x00, // Height = 200
0x01, 0x00, // Planes
0x04, 0x00, // BitCount = 4
0x00, 0x00, 0x00, 0x00, // Compression = BI_RGB
0x00, 0x10, 0x0e, 0x00, // SizeImage
0x00, 0x00, 0x00, 0x00, // XPixelsPerMeter
0x00, 0x00, 0x00, 0x00, // YPixelsPerMeter
0x00, 0x00, 0x00, 0x00, // ClrUsed
0x00, 0x00, 0x00, 0x00, // ClrImportant
// PALETTE
0, 0, 0, 0, // 0 bgra
0, 0, 0, 0, // 1 bgra
0, 0, 0, 0, // 2 bgra
0, 0, 0, 0, // 3 bgra
0, 0, 0, 0, // 4 bgra
0, 0, 0, 0, // 5 bgra
0, 0, 0, 0, // 6 bgra
0, 0, 0, 0, // 7 bgra
0, 0, 0, 0, // 8 bgra
0, 0, 0, 0, // 9 bgra
0, 0, 0, 0, // 10 bgra
0, 0, 0, 0, // 11 bgra
0, 0, 0, 0, // 12 bgra
0, 0, 0, 0, // 13 bgra
0, 0, 0, 0, // 14 bgra
0, 0, 0, 0 // 15 bgra
};
*(unsigned*)(bmpheader32 + 2) = 320 * 200 / 2 + sizeof(bmpheader32); // filesize
//-------------------------------------------------------------------------
for(unsigned i = 0; i < 16; i++)
{
// ╘юЁьрЄ фрээ√ї ярышЄЁ√ Gg0Rr0Bb
// ╨рёъырфър ярышЄЁ√ ¤ьєы ЄюЁр - ULA+
unsigned PalIdx = ((i & 8) << 1) | (i & 7);
u8 r = u8(u32((comp.comp_pal[PalIdx] >> 3) & 3) * 255 / 3);
u8 g = u8(u32((comp.comp_pal[PalIdx] >> 6) & 3) * 255 / 3);
u8 b = u8(u32( comp.comp_pal[PalIdx] & 3) * 255 / 3);
*(PULONG)(bmpheader32 + 54 + 4 * i) = MAKE_RGBQUAD(r, g, b);
}
//-------------------------------------------------------------------------
fwrite(bmpheader32, 1, sizeof(bmpheader32), File);
fwrite(ds, 1, 320 * 200 / 2, File);
}
//=============================================================================
//=============================================================================
static void ConvPal16cAtm1(u8 *Buf)
{
static const int ega0_ofs = -4 * PAGE;
static const int ega1_ofs = 0;
static const int ega2_ofs = -4 * PAGE + 0x2000;
static const int ega3_ofs = 0x2000;
//-------------------------------------------------------------------------
for (int y = 200 - 1; y >= 0; y--)
{
const u8 *src = temp.base + y * 40;
//---------------------------------------------------------------------
for(unsigned x = 0; x < 320; x += 8)
{
u8 v0 = src[ega0_ofs];
u8 v1 = src[ega1_ofs];
u8 v2 = src[ega2_ofs];
u8 v3 = src[ega3_ofs];
Buf[0] = u8(((((v0 >> 3) & 8) | (v0 & 0x7)) << 4) | (((v0 & 0x80) | ((v0 << 1) & 0x70)) >> 4));
Buf[1] = u8(((((v1 >> 3) & 8) | (v1 & 0x7)) << 4) | (((v1 & 0x80) | ((v1 << 1) & 0x70)) >> 4));
Buf[2] = u8(((((v2 >> 3) & 8) | (v2 & 0x7)) << 4) | (((v2 & 0x80) | ((v2 << 1) & 0x70)) >> 4));
Buf[3] = u8(((((v3 >> 3) & 8) | (v3 & 0x7)) << 4) | (((v3 & 0x80) | ((v3 << 1) & 0x70)) >> 4));
src++;
Buf += 4;
}
//---------------------------------------------------------------------
}
//-------------------------------------------------------------------------
}
//=============================================================================
#define ConvPal16cAtm2 ConvPal16cAtm1
typedef void (*TSaver)(FILE *File, u8 *ds);
//=============================================================================
void main_scrshot()
{
char fname[FILENAME_MAX];
// static unsigned sshot = 999990;//0; // ёЄрЁЄют√щ эюьхЁ ёъЁшэ°юЄр
static unsigned int sshot = 0; // [NS]
//-------------------------------------------------------------------------
static const char *Format[] =
{
"scr",
"bmp",
"png"
};
//-------------------------------------------------------------------------
static const TSaver Saver[] =
{
SaveBmp,
SavePng
};
//-------------------------------------------------------------------------
const char *Ext = Format[conf.scrshot];
//-------------------------------------------------------------------------
if ( (conf.scrshot == 0)
&&
(
(
((conf.mem_model == MM_ATM710) || (conf.mem_model == MM_ATM3))
&&
((comp.pFF77 & 7) == 0)
)
||
((conf.mem_model == MM_ATM450) && (((comp.aFE >> 5) & 3) == 0))
)
)
{
Ext = Format[1];
}
//-------------------------------------------------------------------------
// ╧хЁтр яЁютхЁър шьхэш Їрщыр (ъюуфр яєёЄр яряър шыш эюьхЁ яюёыхфэхую Їрщыр єцх шчтхёЄхэ) [NS] r0110
// printf("%X\n",sshot);
snprintf( fname,
_countof(fname),
//"%s\\%s_%06u.%s", conf.scrshot_dir,
"%s\\%s_%08u.%s", conf.scrshot_dir,
temp.LastSnapName[0] ? temp.LastSnapName :
"sshot",
sshot,
Ext
);
fname[FILENAME_MAX-1] = 0;
//-------------------------------------------------------------------------
// хёыш Єръш Єръюую Їрщыр Єръш эхЄ Єю ьюыўр Єръш ёюїЁрэ хь [NS] r0110
if (access (fname, 0) != 0)
{
goto screenshot_name_valid;
}
//-------------------------------------------------------------------------
// letz brute new name Єюуфр [NS] r0110
// эю Єъ сЁєЄшЄ№ 9 ёхэ ьрэют Їрщыют ¤Єю эх ърьшы№Їю
// р ъръ яЁртшы№эю яюыєўшЄ№ эюьхЁ яюёыхфэхую Їрщыр ▀╒╟
// Єю
//
{ // яЁюёЄю юуЁрэшўхэшх ьхЁёъющ тшфшьюёЄш фы эюЁьры№эюую фцрьярэ№ эр screenshot_name_valid
sshot = 0xFFFFFFFF;
unsigned int roll_bit = 0x80000000; //INT_MIN; //8000 0000
int temp_cnt = 0;
bool valid_name_found = FALSE;
unsigned int valid_name_cnt = 0;
//---------------------------------------------------------------------
// ёсЁрё√трхь ърцф√щ сшЄ эюьхЁр ўшёыр юЄ d31 фю d0
// ш ётхЁ хь хёЄ№ ыш Єръющ Їрщы
while (temp_cnt < 32)
{
sshot ^= roll_bit;
//printf("%X - ",sshot);
snprintf( fname,
_countof(fname),
//"%s\\%s_%06u.%s", conf.scrshot_dir,
"%s\\%s_%08u.%s", conf.scrshot_dir,
temp.LastSnapName[0] ? temp.LastSnapName :
"sshot",
sshot,
Ext
);
fname[FILENAME_MAX-1] = 0;
//-----------------------------------------------------------------
// Єръющ Їрщы хёЄ№
if (access (fname, 0) == 0)
{
// printf("invalid\n");
sshot ^= roll_bit; //
}
//-----------------------------------------------------------------
// Єръюую Їрщыр эхЄє
else
{
// printf("valid\n");
valid_name_found = TRUE;
valid_name_cnt = sshot;
}
//-----------------------------------------------------------------
roll_bit = (roll_bit >> 1);
//-----------------------------------------------------------------
temp_cnt++;
//system ("pause");
}
//---------------------------------------------------------------------
if (valid_name_found)
{
sshot = valid_name_cnt;
goto screenshot_name_valid;
}
//sshot++;
} // яЁюёЄю юуЁрэшўхэшх ьхЁёъющ тшфшьюёЄш фы эюЁьры№эюую фцрьярэ№ эр screenshot_name_valid
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
printf("screenshot save error: to big sshot counter\n");
return;
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
screenshot_name_valid:
//printf("valid %X\n",sshot);
snprintf( fname,
_countof(fname),
//"%s\\%s_%06u.%s", conf.scrshot_dir,
"%s\\%s_%08u.%s", conf.scrshot_dir,
temp.LastSnapName[0] ? temp.LastSnapName :
"sshot",
sshot,
Ext
);
fname[FILENAME_MAX-1] = 0;
//-------------------------------------------------------------------------
FILE *fileShot = fopen(fname, "wb");
if (!fileShot)
{
printf("screenshot save error\n");
return;
}
//-------------------------------------------------------------------------
if (conf.scrshot == 0)
{
//---------------------------------------------------------------------
switch (conf.mem_model)
{
//-----------------------------------------------------------------
case MM_ATM710:
case MM_ATM3:
{
switch(comp.pFF77 & 7)
{
//---------------------------------------------------------
case 0: // EGA 320x200 16c
{
u8 *Buf = (u8 *)malloc(320*200/2);
ConvPal16cAtm2(Buf);
SaveBmp16c(fileShot, Buf);
free(Buf);
}
break;
//---------------------------------------------------------
case 3:
goto standard_zx_mode;
//---------------------------------------------------------
}
}
break;
//-----------------------------------------------------------------
case MM_ATM450:
switch((comp.aFE >> 5) & 3)
{
//---------------------------------------------------------
case 0: // EGA 320x200 16c
{
u8 *Buf = (u8 *)malloc(320*200/2);
ConvPal16cAtm1(Buf);
SaveBmp16c(fileShot, Buf);
free(Buf);
}
break;
//---------------------------------------------------------
case 3:
goto standard_zx_mode;
//---------------------------------------------------------
}
break;
//-----------------------------------------------------------------
default:
standard_zx_mode:;
fwrite(temp.base, 1, 6912, fileShot);
}
//---------------------------------------------------------------------
}
//-------------------------------------------------------------------------
else
{
unsigned dx = temp.ox * temp.obpp / 8;
unsigned char *scrbuf_unaligned = (unsigned char*)malloc(dx * temp.oy + CACHE_LINE);
unsigned char *scrbuf = (unsigned char*)align_by(scrbuf_unaligned, CACHE_LINE);
memset(scrbuf, 0, dx * temp.oy);
renders[conf.render].func(scrbuf, dx); // render to memory buffer (PAL8, YUY2, RGB15, RGB16, RGB32)
u8 *ds = (u8 *)malloc(((temp.ox * 3 + 3) & ~3U) * temp.oy);
ConvBgr24(ds, scrbuf, int(dx));
Saver[conf.scrshot - 1](fileShot, ds);
free(ds);
free(scrbuf_unaligned);
}
//-------------------------------------------------------------------------
fclose(fileShot);
sprintf(statusline, "saving %s", strrchr(fname, '\\') + 1);
statcnt = 30;
sshot++;
}
//=============================================================================
/*
static void VideoFrameSaver()
{
char fname[FILENAME_MAX];
static unsigned FrameNum = 0;
static const char *Format[] = { "scr", "bmp", "png" };
static const TSaver Saver[] = { SaveBmp, SavePng };
sprintf(fname, "video%06u.%s", FrameNum, Format[conf.scrshot]);
addpath(fname);
FILE *fileShot = fopen(fname, "wb");
if (!fileShot)
return;
if (conf.scrshot == 0)
{
fwrite(temp.base, 1, 6912, fileShot);
}
else
{
unsigned dx = temp.ox * temp.obpp / 8;
unsigned char *scrbuf_unaligned = (unsigned char*)malloc(dx * temp.oy + CACHE_LINE);
unsigned char *scrbuf = (unsigned char*)align_by(scrbuf_unaligned, CACHE_LINE);
memset(scrbuf, 0, dx * temp.oy);
renders[conf.render].func(scrbuf, dx); // render to memory buffer (PAL8, YUY2, RGB15, RGB16, RGB32)
u8 *ds = (u8 *)malloc(((temp.ox * 3 + 3) & ~3) * temp.oy);
ConvBgr24(ds, scrbuf, dx);
Saver[conf.scrshot - 1](fileShot, ds);
free(ds);
free(scrbuf_unaligned);
}
fclose(fileShot);
FrameNum++;
}
//=============================================================================
static void VideoNullSaver()
{
}
//=============================================================================
TVideoSaver VideoSaver = VideoNullSaver;
//=============================================================================
void main_savevideo()
{
static bool StartSave = false;
if(!StartSave)
{
sprintf(statusline, "start saving video");
StartSave = true;
VideoSaver = VideoFrameSaver;
}
else
{
sprintf(statusline, "stop saving video");
StartSave = false;
VideoSaver = VideoNullSaver;
}
statcnt = 30;
}
*/
//=============================================================================