mirror of
https://github.com/fadden/ciderpress.git
synced 2024-06-27 01:29:32 +00:00
Compare commits
66 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
fc2fc1429d | ||
|
53c4050b09 | ||
|
e4cf9d8ba5 | ||
|
118b306e11 | ||
|
1d53e4bcae | ||
|
508475a094 | ||
|
a1218a8dcb | ||
|
0790c97ee2 | ||
|
5f5c089506 | ||
|
f63738444c | ||
|
2cb5bf0dcc | ||
|
b42cc8efe9 | ||
|
5950cb7c74 | ||
|
b87037b75e | ||
|
d39c61255c | ||
|
e098069b10 | ||
|
6de7cfefc0 | ||
|
e782a9df6e | ||
|
4235b47748 | ||
|
eff69cce86 | ||
|
adaeb2c6eb | ||
|
8a6a4ada5c | ||
|
295d9c269c | ||
|
9698f46eae | ||
|
17689a7b23 | ||
|
1f17f9747d | ||
|
0a317cb0e7 | ||
|
27cefa61d3 | ||
|
8813a5efd9 | ||
|
dcefd2d2b6 | ||
|
db3ca0a8ca | ||
|
fd4ac77bcf | ||
|
95c0ec7348 | ||
|
7c637c4e6d | ||
|
9de0b42147 | ||
|
008d13a4b1 | ||
|
5e9d8f0102 | ||
|
a85ceca75f | ||
|
fb25998be5 | ||
|
21151cd76a | ||
|
e5ac0ac631 | ||
|
e625ab5f3a | ||
|
8d5e07e683 | ||
|
8ecb8e35eb | ||
|
31197837fe | ||
|
da182e1c61 | ||
|
1c2b187a32 | ||
|
2adbe9591f | ||
|
3d88397024 | ||
|
35a897b248 | ||
|
640959dad5 | ||
|
c2e3fb8353 | ||
|
d35a9670b5 | ||
|
549342b3d9 | ||
|
9f0640142d | ||
|
1797536793 | ||
|
8e326f2f62 | ||
|
a8c2e4cfd6 | ||
|
c1694deb7e | ||
|
98f098d421 | ||
|
9e2fded3b9 | ||
|
c7869c38a5 | ||
|
6153b0f9a1 | ||
|
ebef6a27c2 | ||
|
6bcf388c3e | ||
|
7596c950fa |
415
.gitignore
vendored
415
.gitignore
vendored
|
@ -1,27 +1,402 @@
|
||||||
# build product output directories (top-level and component)
|
## Ignore Visual Studio temporary files, build results, and
|
||||||
Debug
|
## files generated by popular Visual Studio add-ons.
|
||||||
Release
|
##
|
||||||
|
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
|
||||||
|
|
||||||
# precompiled headers
|
# CiderPress-specific
|
||||||
ipch
|
DIST/Setup*.exe
|
||||||
|
DIST/CiderPress*.zip
|
||||||
|
|
||||||
# binaries generated by Visual Studio
|
# User-specific files
|
||||||
CP.sdf
|
*.rsuser
|
||||||
CP.opensdf
|
*.suo
|
||||||
CP.v12.suo
|
*.user
|
||||||
|
*.userosscache
|
||||||
|
*.sln.docstates
|
||||||
|
|
||||||
|
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||||
|
*.userprefs
|
||||||
|
|
||||||
|
# Mono auto generated files
|
||||||
|
mono_crash.*
|
||||||
|
|
||||||
|
# Build results
|
||||||
|
[Dd]ebug/
|
||||||
|
[Dd]ebugPublic/
|
||||||
|
[Rr]elease/
|
||||||
|
[Rr]eleases/
|
||||||
|
x64/
|
||||||
|
x86/
|
||||||
|
[Ww][Ii][Nn]32/
|
||||||
|
[Aa][Rr][Mm]/
|
||||||
|
[Aa][Rr][Mm]64/
|
||||||
|
bld/
|
||||||
|
[Bb]in/
|
||||||
|
[Oo]bj/
|
||||||
|
[Ll]og/
|
||||||
|
[Ll]ogs/
|
||||||
|
|
||||||
|
# Visual Studio 2015/2017 cache/options directory
|
||||||
|
.vs/
|
||||||
|
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||||
|
#wwwroot/
|
||||||
|
|
||||||
|
# Visual Studio 2017 auto generated files
|
||||||
|
Generated\ Files/
|
||||||
|
|
||||||
|
# MSTest test Results
|
||||||
|
[Tt]est[Rr]esult*/
|
||||||
|
[Bb]uild[Ll]og.*
|
||||||
|
|
||||||
|
# NUnit
|
||||||
|
*.VisualState.xml
|
||||||
|
TestResult.xml
|
||||||
|
nunit-*.xml
|
||||||
|
|
||||||
|
# Build Results of an ATL Project
|
||||||
|
[Dd]ebugPS/
|
||||||
|
[Rr]eleasePS/
|
||||||
|
dlldata.c
|
||||||
|
|
||||||
|
# Benchmark Results
|
||||||
|
BenchmarkDotNet.Artifacts/
|
||||||
|
|
||||||
|
# .NET Core
|
||||||
|
project.lock.json
|
||||||
|
project.fragment.lock.json
|
||||||
|
artifacts/
|
||||||
|
|
||||||
|
# ASP.NET Scaffolding
|
||||||
|
ScaffoldingReadMe.txt
|
||||||
|
|
||||||
|
# StyleCop
|
||||||
|
StyleCopReport.xml
|
||||||
|
|
||||||
|
# Files built by Visual Studio
|
||||||
|
*_i.c
|
||||||
|
*_p.c
|
||||||
|
*_h.h
|
||||||
|
*.ilk
|
||||||
|
*.meta
|
||||||
|
*.obj
|
||||||
|
*.iobj
|
||||||
|
*.pch
|
||||||
|
*.pdb
|
||||||
|
*.ipdb
|
||||||
|
*.pgc
|
||||||
|
*.pgd
|
||||||
|
*.rsp
|
||||||
|
*.sbr
|
||||||
|
*.tlb
|
||||||
|
*.tli
|
||||||
|
*.tlh
|
||||||
|
*.tmp
|
||||||
|
*.tmp_proj
|
||||||
|
*_wpftmp.csproj
|
||||||
|
*.log
|
||||||
|
*.tlog
|
||||||
|
*.vspscc
|
||||||
|
*.vssscc
|
||||||
|
.builds
|
||||||
|
*.pidb
|
||||||
|
*.svclog
|
||||||
|
*.scc
|
||||||
|
|
||||||
|
# Chutzpah Test files
|
||||||
|
_Chutzpah*
|
||||||
|
|
||||||
|
# Visual C++ cache files
|
||||||
|
ipch/
|
||||||
|
*.aps
|
||||||
|
*.ncb
|
||||||
|
*.opendb
|
||||||
|
*.opensdf
|
||||||
|
*.sdf
|
||||||
|
*.cachefile
|
||||||
|
*.VC.db
|
||||||
|
*.VC.VC.opendb
|
||||||
|
|
||||||
|
# Visual Studio profiler
|
||||||
|
*.psess
|
||||||
|
*.vsp
|
||||||
|
*.vspx
|
||||||
|
*.sap
|
||||||
|
|
||||||
|
# Visual Studio Trace Files
|
||||||
|
*.e2e
|
||||||
|
|
||||||
|
# TFS 2012 Local Workspace
|
||||||
|
$tf/
|
||||||
|
|
||||||
|
# Guidance Automation Toolkit
|
||||||
|
*.gpState
|
||||||
|
|
||||||
|
# ReSharper is a .NET coding add-in
|
||||||
|
_ReSharper*/
|
||||||
|
*.[Rr]e[Ss]harper
|
||||||
|
*.DotSettings.user
|
||||||
|
|
||||||
|
# TeamCity is a build add-in
|
||||||
|
_TeamCity*
|
||||||
|
|
||||||
|
# DotCover is a Code Coverage Tool
|
||||||
|
*.dotCover
|
||||||
|
|
||||||
|
# AxoCover is a Code Coverage Tool
|
||||||
|
.axoCover/*
|
||||||
|
!.axoCover/settings.json
|
||||||
|
|
||||||
|
# Coverlet is a free, cross platform Code Coverage Tool
|
||||||
|
coverage*.json
|
||||||
|
coverage*.xml
|
||||||
|
coverage*.info
|
||||||
|
|
||||||
|
# Visual Studio code coverage results
|
||||||
|
*.coverage
|
||||||
|
*.coveragexml
|
||||||
|
|
||||||
|
# NCrunch
|
||||||
|
_NCrunch_*
|
||||||
|
.*crunch*.local.xml
|
||||||
|
nCrunchTemp_*
|
||||||
|
|
||||||
|
# MightyMoose
|
||||||
|
*.mm.*
|
||||||
|
AutoTest.Net/
|
||||||
|
|
||||||
|
# Web workbench (sass)
|
||||||
|
.sass-cache/
|
||||||
|
|
||||||
|
# Installshield output folder
|
||||||
|
[Ee]xpress/
|
||||||
|
|
||||||
|
# DocProject is a documentation generator add-in
|
||||||
|
DocProject/buildhelp/
|
||||||
|
DocProject/Help/*.HxT
|
||||||
|
DocProject/Help/*.HxC
|
||||||
|
DocProject/Help/*.hhc
|
||||||
|
DocProject/Help/*.hhk
|
||||||
|
DocProject/Help/*.hhp
|
||||||
|
DocProject/Help/Html2
|
||||||
|
DocProject/Help/html
|
||||||
|
|
||||||
|
# Click-Once directory
|
||||||
|
publish/
|
||||||
|
|
||||||
|
# Publish Web Output
|
||||||
|
*.[Pp]ublish.xml
|
||||||
|
*.azurePubxml
|
||||||
|
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||||
|
# but database connection strings (with potential passwords) will be unencrypted
|
||||||
|
*.pubxml
|
||||||
|
*.publishproj
|
||||||
|
|
||||||
|
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||||
|
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||||
|
# in these scripts will be unencrypted
|
||||||
|
PublishScripts/
|
||||||
|
|
||||||
|
# NuGet Packages
|
||||||
|
*.nupkg
|
||||||
|
# NuGet Symbol Packages
|
||||||
|
*.snupkg
|
||||||
|
# The packages folder can be ignored because of Package Restore
|
||||||
|
**/[Pp]ackages/*
|
||||||
|
# except build/, which is used as an MSBuild target.
|
||||||
|
!**/[Pp]ackages/build/
|
||||||
|
# Uncomment if necessary however generally it will be regenerated when needed
|
||||||
|
#!**/[Pp]ackages/repositories.config
|
||||||
|
# NuGet v3's project.json files produces more ignorable files
|
||||||
|
*.nuget.props
|
||||||
|
*.nuget.targets
|
||||||
|
|
||||||
|
# Microsoft Azure Build Output
|
||||||
|
csx/
|
||||||
|
*.build.csdef
|
||||||
|
|
||||||
|
# Microsoft Azure Emulator
|
||||||
|
ecf/
|
||||||
|
rcf/
|
||||||
|
|
||||||
|
# Windows Store app package directories and files
|
||||||
|
AppPackages/
|
||||||
|
BundleArtifacts/
|
||||||
|
Package.StoreAssociation.xml
|
||||||
|
_pkginfo.txt
|
||||||
|
*.appx
|
||||||
|
*.appxbundle
|
||||||
|
*.appxupload
|
||||||
|
|
||||||
|
# Visual Studio cache files
|
||||||
|
# files ending in .cache can be ignored
|
||||||
|
*.[Cc]ache
|
||||||
|
# but keep track of directories ending in .cache
|
||||||
|
!?*.[Cc]ache/
|
||||||
|
|
||||||
|
# Others
|
||||||
|
ClientBin/
|
||||||
|
~$*
|
||||||
|
*~
|
||||||
|
*.dbmdl
|
||||||
|
*.dbproj.schemaview
|
||||||
|
*.jfm
|
||||||
|
*.pfx
|
||||||
|
*.publishsettings
|
||||||
|
orleans.codegen.cs
|
||||||
|
|
||||||
|
# Including strong name files can present a security risk
|
||||||
|
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||||
|
#*.snk
|
||||||
|
|
||||||
|
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||||
|
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||||
|
#bower_components/
|
||||||
|
|
||||||
|
# RIA/Silverlight projects
|
||||||
|
Generated_Code/
|
||||||
|
|
||||||
|
# Backup & report files from converting an old project file
|
||||||
|
# to a newer Visual Studio version. Backup files are not needed,
|
||||||
|
# because we have git ;-)
|
||||||
|
_UpgradeReport_Files/
|
||||||
|
Backup*/
|
||||||
|
UpgradeLog*.XML
|
||||||
|
UpgradeLog*.htm
|
||||||
|
ServiceFabricBackup/
|
||||||
|
*.rptproj.bak
|
||||||
|
|
||||||
|
# SQL Server files
|
||||||
|
*.mdf
|
||||||
|
*.ldf
|
||||||
|
*.ndf
|
||||||
|
|
||||||
|
# Business Intelligence projects
|
||||||
|
*.rdl.data
|
||||||
|
*.bim.layout
|
||||||
|
*.bim_*.settings
|
||||||
|
*.rptproj.rsuser
|
||||||
|
*- [Bb]ackup.rdl
|
||||||
|
*- [Bb]ackup ([0-9]).rdl
|
||||||
|
*- [Bb]ackup ([0-9][0-9]).rdl
|
||||||
|
|
||||||
|
# Microsoft Fakes
|
||||||
|
FakesAssemblies/
|
||||||
|
|
||||||
|
# GhostDoc plugin setting file
|
||||||
|
*.GhostDoc.xml
|
||||||
|
|
||||||
|
# Node.js Tools for Visual Studio
|
||||||
|
.ntvs_analysis.dat
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# Visual Studio 6 build log
|
||||||
|
*.plg
|
||||||
|
|
||||||
|
# Visual Studio 6 workspace options file
|
||||||
|
*.opt
|
||||||
|
|
||||||
|
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||||
|
*.vbw
|
||||||
|
|
||||||
|
# Visual Studio 6 auto-generated project file (contains which files were open etc.)
|
||||||
|
*.vbp
|
||||||
|
|
||||||
|
# Visual Studio 6 workspace and project file (working project files containing files to include in project)
|
||||||
|
*.dsw
|
||||||
|
*.dsp
|
||||||
|
|
||||||
|
# Visual Studio 6 technical files
|
||||||
|
*.ncb
|
||||||
*.aps
|
*.aps
|
||||||
|
|
||||||
# installer binary
|
# Visual Studio LightSwitch build output
|
||||||
DIST/Setup*.exe
|
**/*.HTMLClient/GeneratedArtifacts
|
||||||
|
**/*.DesktopClient/GeneratedArtifacts
|
||||||
|
**/*.DesktopClient/ModelManifest.xml
|
||||||
|
**/*.Server/GeneratedArtifacts
|
||||||
|
**/*.Server/ModelManifest.xml
|
||||||
|
_Pvt_Extensions
|
||||||
|
|
||||||
# linux binaries
|
# Paket dependency manager
|
||||||
*.o
|
.paket/paket.exe
|
||||||
diskimg/libdiskimg.a
|
paket-files/
|
||||||
diskimg/libhfs/libhfs.a
|
|
||||||
|
|
||||||
# ctags
|
# FAKE - F# Make
|
||||||
tags
|
.fake/
|
||||||
|
|
||||||
# VIM
|
# CodeRush personal settings
|
||||||
*~
|
.cr/personal
|
||||||
*.swp
|
|
||||||
|
# Python Tools for Visual Studio (PTVS)
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
|
||||||
|
# Cake - Uncomment if you are using it
|
||||||
|
# tools/**
|
||||||
|
# !tools/packages.config
|
||||||
|
|
||||||
|
# Tabs Studio
|
||||||
|
*.tss
|
||||||
|
|
||||||
|
# Telerik's JustMock configuration file
|
||||||
|
*.jmconfig
|
||||||
|
|
||||||
|
# BizTalk build output
|
||||||
|
*.btp.cs
|
||||||
|
*.btm.cs
|
||||||
|
*.odx.cs
|
||||||
|
*.xsd.cs
|
||||||
|
|
||||||
|
# OpenCover UI analysis results
|
||||||
|
OpenCover/
|
||||||
|
|
||||||
|
# Azure Stream Analytics local run output
|
||||||
|
ASALocalRun/
|
||||||
|
|
||||||
|
# MSBuild Binary and Structured Log
|
||||||
|
*.binlog
|
||||||
|
|
||||||
|
# NVidia Nsight GPU debugger configuration file
|
||||||
|
*.nvuser
|
||||||
|
|
||||||
|
# MFractors (Xamarin productivity tool) working folder
|
||||||
|
.mfractor/
|
||||||
|
|
||||||
|
# Local History for Visual Studio
|
||||||
|
.localhistory/
|
||||||
|
|
||||||
|
# Visual Studio History (VSHistory) files
|
||||||
|
.vshistory/
|
||||||
|
|
||||||
|
# BeatPulse healthcheck temp database
|
||||||
|
healthchecksdb
|
||||||
|
|
||||||
|
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
||||||
|
MigrationBackup/
|
||||||
|
|
||||||
|
# Ionide (cross platform F# VS Code tools) working folder
|
||||||
|
.ionide/
|
||||||
|
|
||||||
|
# Fody - auto-generated XML schema
|
||||||
|
FodyWeavers.xsd
|
||||||
|
|
||||||
|
# VS Code files for those working on multiple tools
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/settings.json
|
||||||
|
!.vscode/tasks.json
|
||||||
|
!.vscode/launch.json
|
||||||
|
!.vscode/extensions.json
|
||||||
|
*.code-workspace
|
||||||
|
|
||||||
|
# Local History for Visual Studio Code
|
||||||
|
.history/
|
||||||
|
|
||||||
|
# Windows Installer files from build outputs
|
||||||
|
*.cab
|
||||||
|
*.msi
|
||||||
|
*.msix
|
||||||
|
*.msm
|
||||||
|
*.msp
|
||||||
|
|
||||||
|
# JetBrains Rider
|
||||||
|
*.sln.iml
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
End-User License Agreement for CiderPress
|
End-User License Agreement for CiderPress
|
||||||
Copyright (c) 2014, CiderPress project authors
|
Copyright (C) 2017, CiderPress project authors
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
AGREEMENT. After reading this agreement carefully, if you ("Customer") do
|
AGREEMENT. After reading this agreement carefully, if you ("Customer") do
|
||||||
|
|
BIN
DIST/mfc120u.dll
BIN
DIST/mfc120u.dll
Binary file not shown.
BIN
DIST/mfc140u.dll
Normal file
BIN
DIST/mfc140u.dll
Normal file
Binary file not shown.
Binary file not shown.
BIN
DIST/vcruntime140.dll
Normal file
BIN
DIST/vcruntime140.dll
Normal file
Binary file not shown.
|
@ -1,17 +1,26 @@
|
||||||
DeployMaster Installation Script
|
DeployMaster Installation Script
|
||||||
16
|
720
|
||||||
faddenSoft
|
faddenSoft
|
||||||
http://www.faddensoft.com/
|
http://www.faddensoft.com/
|
||||||
CiderPress
|
CiderPress
|
||||||
http://a2ciderpress.com/
|
http://a2ciderpress.com/
|
||||||
4.0.1
|
4.1.1
|
||||||
42240
|
TRUE
|
||||||
|
45058
|
||||||
C:\DATA\faddenSoft\fs.ico
|
C:\DATA\faddenSoft\fs.ico
|
||||||
Copyright © 2015 CiderPress project authors. All rights reserved.
|
Copyright © 2023 CiderPress project authors. All rights reserved.
|
||||||
C:\Src\CiderPress\DIST\ReadMe.txt
|
C:\Src\CiderPress\DIST\ReadMe.txt
|
||||||
C:\Src\CiderPress\DIST\License.txt
|
C:\Src\CiderPress\DIST\License.txt
|
||||||
|
FALSE
|
||||||
|
|
||||||
|
|
||||||
|
FALSE
|
||||||
|
%PROGRAMFILES%\faddenSoft\CiderPress
|
||||||
|
%COMMONFILES%\faddenSoft\
|
||||||
|
%PROGRAMSMENU%\CiderPress
|
||||||
|
|
||||||
|
TRUE
|
||||||
|
TRUE
|
||||||
%PROGRAMFILES%\faddenSoft\CiderPress
|
%PROGRAMFILES%\faddenSoft\CiderPress
|
||||||
%COMMONFILES%\faddenSoft\
|
%COMMONFILES%\faddenSoft\
|
||||||
%PROGRAMSMENU%\CiderPress
|
%PROGRAMSMENU%\CiderPress
|
||||||
|
@ -24,14 +33,28 @@ FALSE
|
||||||
FALSE
|
FALSE
|
||||||
FALSE
|
FALSE
|
||||||
FALSE
|
FALSE
|
||||||
|
FALSE
|
||||||
|
FALSE
|
||||||
TRUE
|
TRUE
|
||||||
TRUE
|
TRUE
|
||||||
TRUE
|
TRUE
|
||||||
TRUE
|
TRUE
|
||||||
|
1507
|
||||||
|
9999
|
||||||
TRUE
|
TRUE
|
||||||
|
21H2
|
||||||
|
9999
|
||||||
TRUE
|
TRUE
|
||||||
1
|
1
|
||||||
You are attempting to run the installer for %APP% %VERSION%. This installer supports the following versions of Windows: %INSTALLER%. You are running %USER%. Please check the developer's website to see whether there is a separate installer for %APP% that you can use on %USER%.
|
You are attempting to run the installer for %APP% %VERSION%. This installer supports the following versions of Windows: %INSTALLER%. You are running %USER%. Please check the developer's website to see whether there is a separate installer for %APP% that you can use on %USER%.
|
||||||
|
FALSE
|
||||||
|
FALSE
|
||||||
|
FALSE
|
||||||
|
FALSE
|
||||||
|
3
|
||||||
|
The installer for %APP% %VERSION% needs to be able to write to folders that look like they are being protected by Controlled Folder Access in Windows Defender.
|
||||||
|
|
||||||
|
You will need to add %FILE% to the list of apps allowed through Controlled Folder Access in Windows Defender. Do this before you click Yes to continue with the installation. Otherwise the installer will not be able to properly install %APP% %VERSION%.
|
||||||
TRUE
|
TRUE
|
||||||
TRUE
|
TRUE
|
||||||
1
|
1
|
||||||
|
@ -165,16 +188,16 @@ FALSE
|
||||||
1
|
1
|
||||||
FALSE
|
FALSE
|
||||||
+
|
+
|
||||||
C:\Src\ciderpress\DIST\mfc120u.dll
|
C:\Src\ciderpress\DIST\mfc140u.dll
|
||||||
3
|
3
|
||||||
0
|
1
|
||||||
TRUE
|
TRUE
|
||||||
TRUE
|
TRUE
|
||||||
FALSE
|
FALSE
|
||||||
FALSE
|
FALSE
|
||||||
C:\Src\ciderpress\DIST\msvcr120.dll
|
C:\Src\ciderpress\DIST\vcruntime140.dll
|
||||||
3
|
3
|
||||||
0
|
1
|
||||||
TRUE
|
TRUE
|
||||||
TRUE
|
TRUE
|
||||||
FALSE
|
FALSE
|
||||||
|
@ -281,6 +304,14 @@ FALSE
|
||||||
TRUE
|
TRUE
|
||||||
CiderPress
|
CiderPress
|
||||||
+
|
+
|
||||||
|
HKEY_AUTO
|
||||||
|
0
|
||||||
|
FALSE
|
||||||
|
+
|
||||||
|
Software
|
||||||
|
0
|
||||||
|
FALSE
|
||||||
|
-
|
||||||
HKEY_CLASSES_ROOT
|
HKEY_CLASSES_ROOT
|
||||||
0
|
0
|
||||||
FALSE
|
FALSE
|
||||||
|
@ -320,6 +351,14 @@ TRUE
|
||||||
-
|
-
|
||||||
-
|
-
|
||||||
-
|
-
|
||||||
|
HKEY_USERS
|
||||||
|
0
|
||||||
|
FALSE
|
||||||
|
+
|
||||||
|
Software
|
||||||
|
0
|
||||||
|
FALSE
|
||||||
|
-
|
||||||
-
|
-
|
||||||
0
|
0
|
||||||
FALSE
|
FALSE
|
||||||
|
@ -351,13 +390,21 @@ FALSE
|
||||||
0
|
0
|
||||||
FALSE
|
FALSE
|
||||||
36725
|
36725
|
||||||
|
FALSE
|
||||||
|
43446
|
||||||
|
FALSE
|
||||||
|
365
|
||||||
|
0
|
||||||
0
|
0
|
||||||
4095
|
4095
|
||||||
|
|
||||||
|
|
||||||
Setup401.exe
|
Setup411.exe
|
||||||
|
|
||||||
FALSE
|
FALSE
|
||||||
|
|
||||||
|
|
||||||
TRUE
|
TRUE
|
||||||
|
FALSE
|
||||||
|
FALSE
|
||||||
|
|
||||||
|
|
39
README.md
39
README.md
|
@ -2,7 +2,10 @@ CiderPress
|
||||||
==========
|
==========
|
||||||
|
|
||||||
A Windows utility for managing Apple II file archives and disk images.
|
A Windows utility for managing Apple II file archives and disk images.
|
||||||
Visit the web site at http://a2ciderpress.com/.
|
Visit the web site at https://a2ciderpress.com/
|
||||||
|
(or https://fadden.github.io/ciderpress).
|
||||||
|
|
||||||
|
**NEW!** CiderPress II is now available from [github](https://github.com/fadden/CiderPress2).
|
||||||
|
|
||||||
CiderPress was initially sold by faddenSoft, LLC as a shareware product,
|
CiderPress was initially sold by faddenSoft, LLC as a shareware product,
|
||||||
starting in March 2003. In March 2007, the program was released as
|
starting in March 2003. In March 2007, the program was released as
|
||||||
|
@ -71,13 +74,9 @@ is not acceptable, you can remove HFS disk image support from CiderPress
|
||||||
Building the Sources
|
Building the Sources
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
The current version of CiderPress is targeted for Visual Studio 2013,
|
The current version of CiderPress is targeted for Visual Studio 2019
|
||||||
using the WinXP compatibility Platform Toolset to allow installation on
|
Community Edition (i.e. the free version). You should be able to select
|
||||||
Windows XP systems. You should be able to select Debug or Release and
|
Debug or Release and just build the entire thing.
|
||||||
just build the entire thing.
|
|
||||||
|
|
||||||
If you want to use the static analyzer, you will need to change the
|
|
||||||
Platform Toolset to straight Visual Studio 2013.
|
|
||||||
|
|
||||||
A pre-compiled .CHM file, with the help text and pop-up messages,
|
A pre-compiled .CHM file, with the help text and pop-up messages,
|
||||||
is provided. The source files are all included, but generation of the
|
is provided. The source files are all included, but generation of the
|
||||||
|
@ -85,7 +84,7 @@ is provided. The source files are all included, but generation of the
|
||||||
you will need to download the HTML Help Workshop from Microsoft, and use
|
you will need to download the HTML Help Workshop from Microsoft, and use
|
||||||
that to compile the help project in the app/Help directory.
|
that to compile the help project in the app/Help directory.
|
||||||
|
|
||||||
The installer binary is created with [DeployMaster](http://deploymaster.com/).
|
The installer binary is created with [DeployMaster](https://deploymaster.com/).
|
||||||
|
|
||||||
|
|
||||||
Building for Linux
|
Building for Linux
|
||||||
|
@ -167,8 +166,8 @@ Miscellaneous utility functions.
|
||||||
|
|
||||||
#### NufxLib and zlib ####
|
#### NufxLib and zlib ####
|
||||||
|
|
||||||
These are source snapshots from [NufxLib](http://github.com/fadden/nulib2)
|
These are source snapshots from [NufxLib](https://github.com/fadden/nulib2)
|
||||||
and [zlib](http://www.zlib.org).
|
and [zlib](https://zlib.net).
|
||||||
|
|
||||||
#### DIST ####
|
#### DIST ####
|
||||||
|
|
||||||
|
@ -176,7 +175,7 @@ Files used when making a distribution, notably:
|
||||||
|
|
||||||
- the DeployMaster configuration file
|
- the DeployMaster configuration file
|
||||||
- the license and README files that are included in the installer
|
- the license and README files that are included in the installer
|
||||||
- redistributable Windows runtime libraries (only needed on WinXP?)
|
- redistributable Windows runtime libraries
|
||||||
- NiftyList data file
|
- NiftyList data file
|
||||||
|
|
||||||
|
|
||||||
|
@ -218,18 +217,16 @@ are expected to build on Linux, so converting them is a bit of a pain. At
|
||||||
some point it may be necessary to support Unicode fully. v4.0 did a lot of
|
some point it may be necessary to support Unicode fully. v4.0 did a lot of
|
||||||
code reorganization to make this easier, as did NufxLib v3.0.
|
code reorganization to make this easier, as did NufxLib v3.0.
|
||||||
|
|
||||||
4. Windows XP support. The default Visual Studio 2013 configuration creates
|
4. Installer magic. Security improvements and changes like the Win8 "Metro"
|
||||||
executables that do not work in Windows XP. CiderPress uses a compatibility
|
|
||||||
toolset and packs about 5MB of additional DLLs (mfc120u.dll, msvcr120.dll) in
|
|
||||||
the install package to keep things working. At some point it may not be
|
|
||||||
possible to support WinXP, or building for WinXP will prevent something from
|
|
||||||
working. The good news is that, for the current round of tools, it's
|
|
||||||
possible to build a single binary that works fully on WinXP and later systems.
|
|
||||||
|
|
||||||
5. Installer magic. Security improvements and changes like the Win8 "Metro"
|
|
||||||
launcher affect the way apps are installed and launched. So far the only
|
launcher affect the way apps are installed and launched. So far the only
|
||||||
impact on CiderPress was to the file association handling (the stuff that
|
impact on CiderPress was to the file association handling (the stuff that
|
||||||
allows you to double-click a file and have CiderPress open it), but it's
|
allows you to double-click a file and have CiderPress open it), but it's
|
||||||
likely that future OS changes will require matching app changes. The use
|
likely that future OS changes will require matching app changes. The use
|
||||||
of DeployMaster is helpful here, as it has been kept up-to-date with changes
|
of DeployMaster is helpful here, as it has been kept up-to-date with changes
|
||||||
in Windows.
|
in Windows.
|
||||||
|
|
||||||
|
[ENDED] Windows XP support. Starting with the Visual Studio 2013 tools,
|
||||||
|
building an app that would work under WinXP required jumping through some
|
||||||
|
hoops. Microsoft's support for WinXP officially ended in April 2014.
|
||||||
|
CiderPress continued to support WinXP for several years, but support has been
|
||||||
|
dropped due to the added testing and maintenance burdens.
|
||||||
|
|
|
@ -28,14 +28,8 @@ public:
|
||||||
kActionConvFile,
|
kActionConvFile,
|
||||||
} Action;
|
} Action;
|
||||||
|
|
||||||
ActionProgressDialog(void) {
|
ActionProgressDialog(void) : fAction(kActionUnknown), fCancel(false) { }
|
||||||
fAction = kActionUnknown;
|
virtual ~ActionProgressDialog(void) { }
|
||||||
//fpSelSet = NULL;
|
|
||||||
//fpOptionsDlg = NULL;
|
|
||||||
fCancel = false;
|
|
||||||
//fResult = 0;
|
|
||||||
}
|
|
||||||
virtual ~ActionProgressDialog(void) {}
|
|
||||||
|
|
||||||
BOOL Create(Action action, CWnd* pParentWnd = NULL) {
|
BOOL Create(Action action, CWnd* pParentWnd = NULL) {
|
||||||
fAction = action;
|
fAction = action;
|
||||||
|
|
|
@ -912,6 +912,16 @@ bool MainWindow::ExtractEntry(GenericEntry* pEntry, int thread,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Issue #26: if "add type extension" is not checked, don't add
|
||||||
|
* the format converter extension. This is useful for Merlin
|
||||||
|
* source files where you want to do the text conversion but still
|
||||||
|
* want the file to end with ".S".
|
||||||
|
*/
|
||||||
|
if (!pExtOpts->fAddExtension) {
|
||||||
|
noChangePath = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (goodReformat) {
|
if (goodReformat) {
|
||||||
if (!noChangePath)
|
if (!noChangePath)
|
||||||
outputPath = tmpPath;
|
outputPath = tmpPath;
|
||||||
|
|
|
@ -58,11 +58,16 @@ END
|
||||||
// Icon with lowest ID value placed first to ensure application icon
|
// Icon with lowest ID value placed first to ensure application icon
|
||||||
// remains consistent on all systems.
|
// remains consistent on all systems.
|
||||||
IDR_MAINFRAME ICON "Graphics\\CiderPress.ico"
|
IDR_MAINFRAME ICON "Graphics\\CiderPress.ico"
|
||||||
|
|
||||||
IDI_FILE_BINARY2 ICON "Graphics\\binary2.ico"
|
IDI_FILE_BINARY2 ICON "Graphics\\binary2.ico"
|
||||||
|
|
||||||
IDI_FILE_NUFX ICON "Graphics\\nufx.ico"
|
IDI_FILE_NUFX ICON "Graphics\\nufx.ico"
|
||||||
|
|
||||||
IDI_FILE_DISKIMAGE ICON "Graphics\\diskimage.ico"
|
IDI_FILE_DISKIMAGE ICON "Graphics\\diskimage.ico"
|
||||||
|
|
||||||
IDI_FILE_VIEWER ICON "Graphics\\FileViewer.ico"
|
IDI_FILE_VIEWER ICON "Graphics\\FileViewer.ico"
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Menu
|
// Menu
|
||||||
|
@ -222,11 +227,11 @@ BEGIN
|
||||||
PUSHBUTTON "Enter registration code",IDC_ABOUT_ENTER_REG,157,132,86,14
|
PUSHBUTTON "Enter registration code",IDC_ABOUT_ENTER_REG,157,132,86,14
|
||||||
CONTROL IDB_FSLOGO,IDC_STATIC,"Static",SS_BITMAP,7,6,64,59
|
CONTROL IDB_FSLOGO,IDC_STATIC,"Static",SS_BITMAP,7,6,64,59
|
||||||
LTEXT "CiderPress v%d.%d.%d%ls%ls",IDC_CIDERPRESS_VERS_TEXT,77,7,167,9
|
LTEXT "CiderPress v%d.%d.%d%ls%ls",IDC_CIDERPRESS_VERS_TEXT,77,7,167,9
|
||||||
LTEXT "Copyright © 2015 by CiderPress project authors\rAll Rights Reserved.",IDC_STATIC,77,20,167,19
|
LTEXT "Copyright © 2021 by CiderPress project authors.\rAll Rights Reserved.",IDC_STATIC,77,20,167,19
|
||||||
ICON IDR_MAINFRAME,IDC_STATIC,77,45,21,20
|
ICON IDR_MAINFRAME,IDC_STATIC,77,45,20,20
|
||||||
ICON IDI_FILE_NUFX,IDC_STATIC,106,45,21,20
|
ICON IDI_FILE_NUFX,IDC_STATIC,106,45,20,20
|
||||||
ICON IDI_FILE_BINARY2,IDC_STATIC,136,45,21,20
|
ICON IDI_FILE_BINARY2,IDC_STATIC,136,45,20,20
|
||||||
ICON IDI_FILE_DISKIMAGE,IDC_STATIC,166,45,21,20
|
ICON IDI_FILE_DISKIMAGE,IDC_STATIC,166,45,20,20
|
||||||
GROUPBOX "Libraries",IDC_STATIC,7,71,237,56
|
GROUPBOX "Libraries",IDC_STATIC,7,71,237,56
|
||||||
LTEXT "Using NufxLib DLL v%d.%d.%d",IDC_NUFXLIB_VERS_TEXT,16,82,170,10
|
LTEXT "Using NufxLib DLL v%d.%d.%d",IDC_NUFXLIB_VERS_TEXT,16,82,170,10
|
||||||
LTEXT "Using DiskImg DLL v%d.%d.%d",IDC_DISKIMG_VERS_TEXT,16,92,172,8
|
LTEXT "Using DiskImg DLL v%d.%d.%d",IDC_DISKIMG_VERS_TEXT,16,92,172,8
|
||||||
|
@ -315,12 +320,12 @@ BEGIN
|
||||||
PUSHBUTTON "Help",IDHELP,376,242,50,14
|
PUSHBUTTON "Help",IDHELP,376,242,50,14
|
||||||
END
|
END
|
||||||
|
|
||||||
IDD_PREF_FVIEW DIALOGEX 0, 0, 216, 263
|
IDD_PREF_FVIEW DIALOGEX 0, 0, 217, 274
|
||||||
STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTEXTHELP | WS_CHILD | WS_CAPTION
|
STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTEXTHELP | WS_CHILD | WS_CAPTION
|
||||||
CAPTION "File Viewer"
|
CAPTION "File Viewer"
|
||||||
FONT 8, "MS Shell Dlg", 0, 0, 0x0
|
FONT 8, "MS Shell Dlg", 0, 0, 0x0
|
||||||
BEGIN
|
BEGIN
|
||||||
GROUPBOX "Converters",IDC_STATIC,4,7,208,139
|
GROUPBOX "Converters",IDC_STATIC,4,7,209,139
|
||||||
CONTROL "High-ASCII &text",IDC_PVIEW_HITEXT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,19,88,10
|
CONTROL "High-ASCII &text",IDC_PVIEW_HITEXT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,19,88,10
|
||||||
CONTROL "&CP/M text",IDC_PVIEW_CPMTEXT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,30,92,10
|
CONTROL "&CP/M text",IDC_PVIEW_CPMTEXT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,30,92,10
|
||||||
CONTROL "&Pascal text",IDC_PVIEW_PASCALTEXT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,41,87,10
|
CONTROL "&Pascal text",IDC_PVIEW_PASCALTEXT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,41,87,10
|
||||||
|
@ -343,7 +348,7 @@ BEGIN
|
||||||
CONTROL "MacPaint images",IDC_PVIEW_MACPAINT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,112,118,93,10
|
CONTROL "MacPaint images",IDC_PVIEW_MACPAINT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,112,118,93,10
|
||||||
CONTROL "&Relax type-checking on graphics",IDC_PVIEW_RELAX_GFX,
|
CONTROL "&Relax type-checking on graphics",IDC_PVIEW_RELAX_GFX,
|
||||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,50,131,116,10
|
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,50,131,116,10
|
||||||
GROUPBOX "Conversion options",IDC_STATIC,4,150,208,90
|
GROUPBOX "Conversion options",IDC_STATIC,4,150,209,101
|
||||||
CONTROL "&Scroll horizontally instead of wrapping words",IDC_PVIEW_NOWRAP_TEXT,
|
CONTROL "&Scroll horizontally instead of wrapping words",IDC_PVIEW_NOWRAP_TEXT,
|
||||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,162,192,10
|
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,162,192,10
|
||||||
CONTROL "Highlight &hex dump columns (small files)",IDC_PVIEW_BOLD_HEXDUMP,
|
CONTROL "Highlight &hex dump columns (small files)",IDC_PVIEW_BOLD_HEXDUMP,
|
||||||
|
@ -354,12 +359,14 @@ BEGIN
|
||||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,195,189,10
|
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,195,189,10
|
||||||
CONTROL "Prefer &B&&W for hi-res images",IDC_PVIEW_HIRES_BW,
|
CONTROL "Prefer &B&&W for hi-res images",IDC_PVIEW_HIRES_BW,
|
||||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,206,148,10
|
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,206,148,10
|
||||||
LTEXT "Preferred DHR mode:",IDC_STATIC,12,223,69,8
|
CONTROL "Convert MouseText to ASCII",IDC_PVIEW_MOUSETEXT_TO_ASCII,
|
||||||
COMBOBOX IDC_PVIEW_DHR_CONV_COMBO,84,220,118,48,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
|
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,217,194,10
|
||||||
LTEXT "Viewer file size &limit:",IDC_STATIC,4,247,62,8
|
LTEXT "Preferred DHR mode:",IDC_STATIC,12,234,69,8
|
||||||
EDITTEXT IDC_PVIEW_SIZE_EDIT,69,245,40,14,ES_AUTOHSCROLL | ES_NUMBER
|
COMBOBOX IDC_PVIEW_DHR_CONV_COMBO,84,231,118,48,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
|
||||||
CONTROL "Spin2",IDC_PVIEW_SIZE_SPIN,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,112,247,11,14
|
LTEXT "Viewer file size &limit:",IDC_STATIC,4,258,62,8
|
||||||
LTEXT "KBytes",IDC_STATIC,110,247,36,8
|
EDITTEXT IDC_PVIEW_SIZE_EDIT,69,256,40,14,ES_AUTOHSCROLL | ES_NUMBER
|
||||||
|
CONTROL "Spin2",IDC_PVIEW_SIZE_SPIN,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,112,258,11,14
|
||||||
|
LTEXT "KBytes",IDC_STATIC,110,258,36,8
|
||||||
END
|
END
|
||||||
|
|
||||||
IDD_DISKEDIT DIALOGEX 0, 0, 458, 197
|
IDD_DISKEDIT DIALOGEX 0, 0, 458, 197
|
||||||
|
@ -465,47 +472,47 @@ BEGIN
|
||||||
EDITTEXT IDC_PREF_EXTVIEWER_EXTS,7,68,197,14,ES_AUTOHSCROLL
|
EDITTEXT IDC_PREF_EXTVIEWER_EXTS,7,68,197,14,ES_AUTOHSCROLL
|
||||||
END
|
END
|
||||||
|
|
||||||
IDD_EXTRACT_FILES DIALOGEX 0, 0, 299, 242
|
IDD_EXTRACT_FILES DIALOGEX 0, 0, 319, 242
|
||||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CONTEXTHELP | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
|
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CONTEXTHELP | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
|
||||||
CAPTION "Extract Files"
|
CAPTION "Extract Files"
|
||||||
FONT 8, "MS Shell Dlg", 400, 0, 0x0
|
FONT 8, "MS Shell Dlg", 400, 0, 0x0
|
||||||
BEGIN
|
BEGIN
|
||||||
DEFPUSHBUTTON "Extract",IDOK,68,220,50,14
|
DEFPUSHBUTTON "Extract",IDOK,78,220,50,14
|
||||||
PUSHBUTTON "Cancel",IDCANCEL,124,220,50,14
|
PUSHBUTTON "Cancel",IDCANCEL,134,220,50,14
|
||||||
PUSHBUTTON "Help",IDHELP,180,220,50,14
|
PUSHBUTTON "Help",IDHELP,190,220,50,14
|
||||||
LTEXT "Folder where files will be extracted:",IDC_STATIC,8,8,143,8
|
LTEXT "Folder where files will be extracted:",IDC_STATIC,8,8,143,8
|
||||||
EDITTEXT IDC_EXT_PATH,8,18,263,14,ES_AUTOHSCROLL | WS_GROUP
|
EDITTEXT IDC_EXT_PATH,8,18,263,14,ES_AUTOHSCROLL | WS_GROUP
|
||||||
PUSHBUTTON "",IDC_EXT_CHOOSE_FOLDER,276,18,16,14,BS_BITMAP | BS_CENTER | BS_VCENTER | WS_GROUP
|
PUSHBUTTON "",IDC_EXT_CHOOSE_FOLDER,296,18,16,14,BS_BITMAP | BS_CENTER | BS_VCENTER | WS_GROUP
|
||||||
GROUPBOX "Files to extract",IDC_STATIC,8,40,140,35
|
GROUPBOX "Files to extract",IDC_STATIC,8,40,150,35
|
||||||
CONTROL ">Extract 65536 selected files<",IDC_EXT_SELECTED,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,16,50,124,10
|
CONTROL ">Extract 65536 selected files<",IDC_EXT_SELECTED,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,16,50,135,10
|
||||||
CONTROL "Extract &all files",IDC_EXT_ALL,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,16,61,124,10
|
CONTROL "Extract &all files",IDC_EXT_ALL,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,16,61,124,10
|
||||||
GROUPBOX "Parts to extract",IDC_STATIC,152,40,140,47,WS_GROUP
|
GROUPBOX "Parts to extract",IDC_STATIC,162,40,150,47,WS_GROUP
|
||||||
CONTROL "&Data forks",IDC_EXT_DATAFORK,"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,160,50,128,10
|
CONTROL "&Data forks",IDC_EXT_DATAFORK,"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,170,50,128,10
|
||||||
CONTROL "&Resource forks",IDC_EXT_RSRCFORK,"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,160,61,128,10
|
CONTROL "&Resource forks",IDC_EXT_RSRCFORK,"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,170,61,128,10
|
||||||
CONTROL "Disk &images",IDC_EXT_DISKIMAGE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,160,72,128,10
|
CONTROL "Disk &images",IDC_EXT_DISKIMAGE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,170,72,128,10
|
||||||
GROUPBOX "Format conversion",IDC_STATIC,8,77,140,37
|
GROUPBOX "Format conversion",IDC_STATIC,8,77,150,37
|
||||||
CONTROL "&Convert to non-Apple II formats",IDC_EXT_REFORMAT,
|
CONTROL "&Convert to non-Apple II formats",IDC_EXT_REFORMAT,
|
||||||
"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,16,88,124,10
|
"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,16,88,124,10
|
||||||
CONTROL "Extract disks as .&2MG",IDC_EXT_DISK_2MG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,99,124,10
|
CONTROL "Extract disks as .&2MG",IDC_EXT_DISK_2MG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,99,124,10
|
||||||
GROUPBOX "Filenames",IDC_STATIC,152,98,140,40
|
GROUPBOX "Filenames",IDC_STATIC,162,98,150,40
|
||||||
CONTROL "Add file attribute &preservation",IDC_EXT_ADD_PRESERVE,
|
CONTROL "Add file attribute &preservation",IDC_EXT_ADD_PRESERVE,
|
||||||
"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,160,110,128,10
|
"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,170,110,128,10
|
||||||
CONTROL "Add type &extension",IDC_EXT_ADD_EXTEN,"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,160,122,128,10
|
CONTROL "Add type &extension",IDC_EXT_ADD_EXTEN,"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,170,122,128,10
|
||||||
GROUPBOX "Text conversion",IDC_STATIC,8,117,140,70,WS_GROUP
|
GROUPBOX "Text conversion",IDC_STATIC,8,117,150,70,WS_GROUP
|
||||||
CONTROL "&Don't convert text files",IDC_EXT_CONVEOLNONE,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,16,127,124,10
|
CONTROL "&Don't convert text files",IDC_EXT_CONVEOLNONE,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,16,127,124,10
|
||||||
CONTROL "Convert text files by file type",IDC_EXT_CONVEOLTYPE,
|
CONTROL "Convert text files by file type",IDC_EXT_CONVEOLTYPE,
|
||||||
"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,16,138,126,10
|
"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,16,138,126,10
|
||||||
CONTROL "Auto-detect && &convert files with text",IDC_EXT_CONVEOLTEXT,
|
CONTROL "Auto-detect && &convert files with text",IDC_EXT_CONVEOLTEXT,
|
||||||
"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,16,149,126,10
|
"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,16,149,135,10
|
||||||
CONTROL "Convert &ALL files",IDC_EXT_CONVEOLALL,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,16,160,124,10
|
CONTROL "Convert &ALL files",IDC_EXT_CONVEOLALL,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,16,160,124,10
|
||||||
CONTROL "Strip ""&high ASCII"" files",IDC_EXT_CONVHIGHASCII,
|
CONTROL "Strip ""&high ASCII"" files",IDC_EXT_CONVHIGHASCII,
|
||||||
"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,16,171,124,10
|
"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,16,171,124,10
|
||||||
GROUPBOX "Miscellaneous",IDC_STATIC,152,151,140,36,WS_GROUP
|
GROUPBOX "Miscellaneous",IDC_STATIC,162,151,150,36,WS_GROUP
|
||||||
CONTROL "&Strip folder names",IDC_EXT_STRIP_FOLDER,"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,160,161,128,10
|
CONTROL "&Strip folder names",IDC_EXT_STRIP_FOLDER,"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,170,161,128,10
|
||||||
CONTROL "&Overwrite existing files",IDC_EXT_OVERWRITE_EXIST,
|
CONTROL "&Overwrite existing files",IDC_EXT_OVERWRITE_EXIST,
|
||||||
"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,160,172,128,10
|
"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,170,172,128,10
|
||||||
PUSHBUTTON "Configure to preserve Apple II formats",IDC_EXT_CONFIG_PRESERVE,8,196,140,16
|
PUSHBUTTON "Configure to preserve Apple II formats",IDC_EXT_CONFIG_PRESERVE,8,196,150,16
|
||||||
PUSHBUTTON "Configure for easy access in Windows",IDC_EXT_CONFIG_CONVERT,152,196,140,16
|
PUSHBUTTON "Configure for easy access in Windows",IDC_EXT_CONFIG_CONVERT,162,196,150,16
|
||||||
END
|
END
|
||||||
|
|
||||||
IDD_ACTION_PROGRESS DIALOGEX 0, 0, 276, 111
|
IDD_ACTION_PROGRESS DIALOGEX 0, 0, 276, 111
|
||||||
|
@ -1216,14 +1223,22 @@ END
|
||||||
//
|
//
|
||||||
|
|
||||||
IDB_FSLOGO BITMAP "Graphics\\fslogo.bmp"
|
IDB_FSLOGO BITMAP "Graphics\\fslogo.bmp"
|
||||||
|
|
||||||
IDR_TOOLBAR1 BITMAP "Graphics\\toolbar1.bmp"
|
IDR_TOOLBAR1 BITMAP "Graphics\\toolbar1.bmp"
|
||||||
|
|
||||||
IDB_LIST_PICS BITMAP "Graphics\\list-pics.bmp"
|
IDB_LIST_PICS BITMAP "Graphics\\list-pics.bmp"
|
||||||
|
|
||||||
IDB_HDRBAR BITMAP "Graphics\\hdrbar.bmp"
|
IDB_HDRBAR BITMAP "Graphics\\hdrbar.bmp"
|
||||||
|
|
||||||
IDB_NEW_FOLDER BITMAP "graphics\\NewFolder.bmp"
|
IDB_NEW_FOLDER BITMAP "graphics\\NewFolder.bmp"
|
||||||
|
|
||||||
IDB_CHOOSE_FOLDER BITMAP "Graphics\\ChooseFolder.bmp"
|
IDB_CHOOSE_FOLDER BITMAP "Graphics\\ChooseFolder.bmp"
|
||||||
|
|
||||||
IDB_VOL_PICS BITMAP "graphics\\vol_pics.bmp"
|
IDB_VOL_PICS BITMAP "graphics\\vol_pics.bmp"
|
||||||
|
|
||||||
IDB_TREE_PICS BITMAP "graphics\\tree_pics.bmp"
|
IDB_TREE_PICS BITMAP "graphics\\tree_pics.bmp"
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Toolbar
|
// Toolbar
|
||||||
|
@ -1349,12 +1364,12 @@ BEGIN
|
||||||
IDD_PREF_FVIEW, DIALOG
|
IDD_PREF_FVIEW, DIALOG
|
||||||
BEGIN
|
BEGIN
|
||||||
LEFTMARGIN, 4
|
LEFTMARGIN, 4
|
||||||
RIGHTMARGIN, 212
|
RIGHTMARGIN, 213
|
||||||
VERTGUIDE, 12
|
VERTGUIDE, 12
|
||||||
VERTGUIDE, 50
|
VERTGUIDE, 50
|
||||||
VERTGUIDE, 112
|
VERTGUIDE, 112
|
||||||
TOPMARGIN, 7
|
TOPMARGIN, 7
|
||||||
BOTTOMMARGIN, 261
|
BOTTOMMARGIN, 272
|
||||||
END
|
END
|
||||||
|
|
||||||
IDD_DISKEDIT, DIALOG
|
IDD_DISKEDIT, DIALOG
|
||||||
|
@ -1403,8 +1418,10 @@ BEGIN
|
||||||
IDD_EXTRACT_FILES, DIALOG
|
IDD_EXTRACT_FILES, DIALOG
|
||||||
BEGIN
|
BEGIN
|
||||||
LEFTMARGIN, 7
|
LEFTMARGIN, 7
|
||||||
RIGHTMARGIN, 292
|
RIGHTMARGIN, 312
|
||||||
VERTGUIDE, 16
|
VERTGUIDE, 16
|
||||||
|
VERTGUIDE, 158
|
||||||
|
VERTGUIDE, 170
|
||||||
TOPMARGIN, 7
|
TOPMARGIN, 7
|
||||||
BOTTOMMARGIN, 235
|
BOTTOMMARGIN, 235
|
||||||
END
|
END
|
||||||
|
@ -1833,6 +1850,27 @@ BEGIN
|
||||||
END
|
END
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// AFX_DIALOG_LAYOUT
|
||||||
|
//
|
||||||
|
|
||||||
|
IDD_ABOUTDLG AFX_DIALOG_LAYOUT
|
||||||
|
BEGIN
|
||||||
|
0
|
||||||
|
END
|
||||||
|
|
||||||
|
IDD_EXTRACT_FILES AFX_DIALOG_LAYOUT
|
||||||
|
BEGIN
|
||||||
|
0
|
||||||
|
END
|
||||||
|
|
||||||
|
IDD_PREF_FVIEW AFX_DIALOG_LAYOUT
|
||||||
|
BEGIN
|
||||||
|
0
|
||||||
|
END
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// String Table
|
// String Table
|
||||||
|
|
|
@ -459,7 +459,7 @@ CString MainWindow::CopyToCollection(GenericEntry* pEntry, void** pBuf,
|
||||||
memset(&collEnt, 0x99, sizeof(collEnt));
|
memset(&collEnt, 0x99, sizeof(collEnt));
|
||||||
collEnt.signature = kEntrySignature;
|
collEnt.signature = kEntrySignature;
|
||||||
collEnt.dataOffset = sizeof(collEnt);
|
collEnt.dataOffset = sizeof(collEnt);
|
||||||
collEnt.fileNameLen = (wcslen(pEntry->GetPathNameUNI()) +1) * sizeof(WCHAR);
|
collEnt.fileNameLen = (uint16_t)((wcslen(pEntry->GetPathNameUNI()) +1) * sizeof(WCHAR));
|
||||||
if (pEntry->GetRecordKind() == GenericEntry::kRecordKindDirectory) {
|
if (pEntry->GetRecordKind() == GenericEntry::kRecordKindDirectory) {
|
||||||
collEnt.dataLen = collEnt.rsrcLen = collEnt.cmmtLen = 0;
|
collEnt.dataLen = collEnt.rsrcLen = collEnt.cmmtLen = 0;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1581,14 +1581,15 @@ CString DiskArchive::ProcessFileAddData(DiskFS* pDiskFS, int addOptsConvEOL)
|
||||||
else
|
else
|
||||||
convHA = GenericEntry::kConvertHAOff;
|
convHA = GenericEntry::kConvertHAOff;
|
||||||
|
|
||||||
errMsg = LoadFile(pDataDetails->GetLocalPathName(), &dataBuf, &dataLen,
|
errMsg = LoadFile(pDataDetails->GetLocalPathName(), pDiskFS,
|
||||||
convEOL, convHA);
|
&dataBuf, &dataLen, convEOL, convHA);
|
||||||
if (!errMsg.IsEmpty())
|
if (!errMsg.IsEmpty())
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
if (pRsrcDetails != NULL) {
|
if (pRsrcDetails != NULL) {
|
||||||
/* no text conversion on resource forks */
|
/* no text conversion on resource forks */
|
||||||
errMsg = LoadFile(pRsrcDetails->GetLocalPathName(), &rsrcBuf, &rsrcLen,
|
errMsg = LoadFile(pRsrcDetails->GetLocalPathName(), pDiskFS,
|
||||||
|
&rsrcBuf, &rsrcLen,
|
||||||
GenericEntry::kConvertEOLOff, GenericEntry::kConvertHAOff);
|
GenericEntry::kConvertEOLOff, GenericEntry::kConvertHAOff);
|
||||||
if (!errMsg.IsEmpty())
|
if (!errMsg.IsEmpty())
|
||||||
goto bail;
|
goto bail;
|
||||||
|
@ -1624,8 +1625,11 @@ bail:
|
||||||
|
|
||||||
// TODO: really ought to update the progress counter, especially when reading
|
// TODO: really ought to update the progress counter, especially when reading
|
||||||
// really large files.
|
// really large files.
|
||||||
CString DiskArchive::LoadFile(const WCHAR* pathName, uint8_t** pBuf, long* pLen,
|
// TODO: shouldn't be loading really large files into memory. ProDOS is fine
|
||||||
GenericEntry::ConvertEOL conv, GenericEntry::ConvertHighASCII convHA) const
|
// (16MB limit), HFS could be problematic in a 32-bit app.
|
||||||
|
CString DiskArchive::LoadFile(const WCHAR* pathName, DiskFS* pDiskFS,
|
||||||
|
uint8_t** pBuf, long* pLen,
|
||||||
|
GenericEntry::ConvertEOL conv, GenericEntry::ConvertHighASCII convHA) const
|
||||||
{
|
{
|
||||||
const char kCharLF = '\n';
|
const char kCharLF = '\n';
|
||||||
const char kCharCR = '\r';
|
const char kCharCR = '\r';
|
||||||
|
@ -1666,8 +1670,15 @@ CString DiskArchive::LoadFile(const WCHAR* pathName, uint8_t** pBuf, long* pLen,
|
||||||
*pBuf = NULL;
|
*pBuf = NULL;
|
||||||
*pLen = 0;
|
*pLen = 0;
|
||||||
goto bail;
|
goto bail;
|
||||||
} else if (fileLen > 0x00ffffff) {
|
}
|
||||||
errMsg = L"Cannot add files larger than 16MB to a disk image.";
|
// TODO: we want to limit the file length based on the filesystem type,
|
||||||
|
// so we don't initiate an operation that can't possibly succeed. We
|
||||||
|
// should be able to query the DiskImg for its max file size, but that
|
||||||
|
// API doesn't currently exist. For now, limit anything other than HFS
|
||||||
|
// to 16MB.
|
||||||
|
if (pDiskFS->GetDiskImg()->GetFSFormat() != DiskImg::kFormatMacHFS &&
|
||||||
|
fileLen > 0x00ffffff) {
|
||||||
|
errMsg = L"Cannot add files larger than 16MB to a non-HFS disk image.";
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1787,8 +1798,8 @@ bail:
|
||||||
|
|
||||||
DIError DiskArchive::AddForksToDisk(DiskFS* pDiskFS,
|
DIError DiskArchive::AddForksToDisk(DiskFS* pDiskFS,
|
||||||
const DiskFS::CreateParms* pParms,
|
const DiskFS::CreateParms* pParms,
|
||||||
const unsigned char* dataBuf, long dataLen,
|
const uint8_t* dataBuf, long dataLen,
|
||||||
const unsigned char* rsrcBuf, long rsrcLen) const
|
const uint8_t* rsrcBuf, long rsrcLen) const
|
||||||
{
|
{
|
||||||
DIError dierr = kDIErrNone;
|
DIError dierr = kDIErrNone;
|
||||||
const int kFileTypeBIN = 0x06;
|
const int kFileTypeBIN = 0x06;
|
||||||
|
|
|
@ -64,8 +64,14 @@ private:
|
||||||
*/
|
*/
|
||||||
class DiskArchive : public GenericArchive {
|
class DiskArchive : public GenericArchive {
|
||||||
public:
|
public:
|
||||||
DiskArchive(void) : fpPrimaryDiskFS(NULL), fIsReadOnly(false),
|
DiskArchive(void) :
|
||||||
fpAddDataHead(NULL), fpAddDataTail(NULL)
|
fpPrimaryDiskFS(NULL),
|
||||||
|
fIsReadOnly(false),
|
||||||
|
fpAddDataHead(NULL),
|
||||||
|
fpAddDataTail(NULL),
|
||||||
|
fOverwriteExisting(false),
|
||||||
|
fOverwriteNoAsk(false),
|
||||||
|
fpXferTargetFS(NULL)
|
||||||
{}
|
{}
|
||||||
virtual ~DiskArchive(void) { (void) Close(); }
|
virtual ~DiskArchive(void) { (void) Close(); }
|
||||||
|
|
||||||
|
@ -358,7 +364,7 @@ private:
|
||||||
*
|
*
|
||||||
* Returns an empty string on success, or an error message on failure.
|
* Returns an empty string on success, or an error message on failure.
|
||||||
*/
|
*/
|
||||||
CString LoadFile(const WCHAR* pathName, uint8_t** pBuf, long* pLen,
|
CString LoadFile(const WCHAR* pathName, DiskFS* pDiskFS, uint8_t** pBuf, long* pLen,
|
||||||
GenericEntry::ConvertEOL conv, GenericEntry::ConvertHighASCII convHA) const;
|
GenericEntry::ConvertEOL conv, GenericEntry::ConvertHighASCII convHA) const;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -186,11 +186,11 @@ private:
|
||||||
class SectorEditDialog : public DiskEditDialog {
|
class SectorEditDialog : public DiskEditDialog {
|
||||||
public:
|
public:
|
||||||
SectorEditDialog(CWnd* pParentWnd = NULL) :
|
SectorEditDialog(CWnd* pParentWnd = NULL) :
|
||||||
DiskEditDialog(IDD_DISKEDIT, pParentWnd)
|
DiskEditDialog(IDD_DISKEDIT, pParentWnd),
|
||||||
{
|
fTrack(0),
|
||||||
fTrack = 0;
|
fSector(0),
|
||||||
fSector = 0;
|
fSectorData()
|
||||||
}
|
{ }
|
||||||
virtual ~SectorEditDialog() {}
|
virtual ~SectorEditDialog() {}
|
||||||
|
|
||||||
virtual int LoadData(void) override; // load the current track/sector
|
virtual int LoadData(void) override; // load the current track/sector
|
||||||
|
@ -234,11 +234,15 @@ protected:
|
||||||
class SectorFileEditDialog : public SectorEditDialog {
|
class SectorFileEditDialog : public SectorEditDialog {
|
||||||
public:
|
public:
|
||||||
SectorFileEditDialog(SectorEditDialog* pSectEdit, CWnd* pParentWnd = NULL):
|
SectorFileEditDialog(SectorEditDialog* pSectEdit, CWnd* pParentWnd = NULL):
|
||||||
SectorEditDialog(pParentWnd)
|
SectorEditDialog(pParentWnd),
|
||||||
|
fOpenRsrcFork(false),
|
||||||
|
fpFile(NULL),
|
||||||
|
fpOpenFile(NULL),
|
||||||
|
fSectorIdx(0),
|
||||||
|
fLength(0)
|
||||||
{
|
{
|
||||||
DiskEditDialog::Setup(pSectEdit->GetDiskFS(),
|
DiskEditDialog::Setup(pSectEdit->GetDiskFS(),
|
||||||
pSectEdit->GetFileName());
|
pSectEdit->GetFileName());
|
||||||
fSectorIdx = 0;
|
|
||||||
}
|
}
|
||||||
virtual ~SectorFileEditDialog() {}
|
virtual ~SectorFileEditDialog() {}
|
||||||
|
|
||||||
|
@ -326,7 +330,12 @@ protected:
|
||||||
class BlockFileEditDialog : public BlockEditDialog {
|
class BlockFileEditDialog : public BlockEditDialog {
|
||||||
public:
|
public:
|
||||||
BlockFileEditDialog(BlockEditDialog* pBlockEdit, CWnd* pParentWnd = NULL) :
|
BlockFileEditDialog(BlockEditDialog* pBlockEdit, CWnd* pParentWnd = NULL) :
|
||||||
BlockEditDialog(pParentWnd)
|
BlockEditDialog(pParentWnd),
|
||||||
|
fOpenRsrcFork(false),
|
||||||
|
fpFile(NULL),
|
||||||
|
fpOpenFile(NULL),
|
||||||
|
fBlockIdx(0),
|
||||||
|
fLength(0)
|
||||||
{
|
{
|
||||||
DiskEditDialog::Setup(pBlockEdit->GetDiskFS(),
|
DiskEditDialog::Setup(pBlockEdit->GetDiskFS(),
|
||||||
pBlockEdit->GetFileName());
|
pBlockEdit->GetFileName());
|
||||||
|
@ -379,10 +388,11 @@ private:
|
||||||
class NibbleEditDialog : public DiskEditDialog {
|
class NibbleEditDialog : public DiskEditDialog {
|
||||||
public:
|
public:
|
||||||
NibbleEditDialog(CWnd* pParentWnd = NULL) :
|
NibbleEditDialog(CWnd* pParentWnd = NULL) :
|
||||||
DiskEditDialog(IDD_DISKEDIT, pParentWnd)
|
DiskEditDialog(IDD_DISKEDIT, pParentWnd),
|
||||||
{
|
fTrack(0),
|
||||||
fTrack = 0;
|
fNibbleData(),
|
||||||
}
|
fNibbleDataLen(0)
|
||||||
|
{ }
|
||||||
virtual ~NibbleEditDialog() {}
|
virtual ~NibbleEditDialog() {}
|
||||||
|
|
||||||
virtual int LoadData(void) override; // load the current track/sector
|
virtual int LoadData(void) override; // load the current track/sector
|
||||||
|
|
|
@ -17,7 +17,12 @@
|
||||||
class EOLScanDialog : public CDialog {
|
class EOLScanDialog : public CDialog {
|
||||||
public:
|
public:
|
||||||
EOLScanDialog(CWnd* pParentWnd = NULL) :
|
EOLScanDialog(CWnd* pParentWnd = NULL) :
|
||||||
CDialog(IDD_EOLSCAN, pParentWnd)
|
CDialog(IDD_EOLSCAN, pParentWnd),
|
||||||
|
fCountChars(0),
|
||||||
|
fCountCR(0),
|
||||||
|
fCountLF(0),
|
||||||
|
fCountCRLF(0),
|
||||||
|
fCountHighASCII(0)
|
||||||
{}
|
{}
|
||||||
virtual ~EOLScanDialog(void) {}
|
virtual ~EOLScanDialog(void) {}
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -82,6 +82,9 @@ If enabled, hi-res graphics are converted to black & white images by default.
|
||||||
.topic IDH_PVIEW_DHR_CONV_COMBO
|
.topic IDH_PVIEW_DHR_CONV_COMBO
|
||||||
Selects the preferred conversion algorithm for double-hi-res graphics.
|
Selects the preferred conversion algorithm for double-hi-res graphics.
|
||||||
|
|
||||||
|
.topic IDH_PVIEW_MOUSETEXT_TO_ASCII
|
||||||
|
Converts MouseText to ASCII instead of Unicode symbols.
|
||||||
|
|
||||||
.topic IDH_PVIEW_HITEXT
|
.topic IDH_PVIEW_HITEXT
|
||||||
Enables the text converter, which strips "high ASCII" text and converts end-of-line characters.
|
Enables the text converter, which strips "high ASCII" text and converts end-of-line characters.
|
||||||
|
|
||||||
|
@ -505,7 +508,7 @@ The file type, displayed as its hexadecimal code and the common three-letter mne
|
||||||
Tip: clicking in the file type box and then typing a letter takes you to the next entry whose mnemonic begins with that letter. This can make it easier to find an entry by "name".
|
Tip: clicking in the file type box and then typing a letter takes you to the next entry whose mnemonic begins with that letter. This can make it easier to find an entry by "name".
|
||||||
|
|
||||||
.topic IDH_PROPS_AUXTYPE
|
.topic IDH_PROPS_AUXTYPE
|
||||||
The file's auxilliary type. Sometimes used to indicate information about the file (such as a 'BIN' load address), sometimes used to distinguish between files with the same file type (such as the various application-specific 'CFG' config file formats).
|
The file's auxiliary type. Sometimes used to indicate information about the file (such as a 'BIN' load address), sometimes used to distinguish between files with the same file type (such as the various application-specific 'CFG' config file formats).
|
||||||
|
|
||||||
Enter a four-digit hexadecimal number.
|
Enter a four-digit hexadecimal number.
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#define IDH_PVIEW_DISASM_ONEBYTEBRKCOP 1028
|
#define IDH_PVIEW_DISASM_ONEBYTEBRKCOP 1028
|
||||||
#define IDH_PVIEW_HIRES_BW 1029
|
#define IDH_PVIEW_HIRES_BW 1029
|
||||||
#define IDH_PVIEW_DHR_CONV_COMBO 1030
|
#define IDH_PVIEW_DHR_CONV_COMBO 1030
|
||||||
|
#define IDH_PVIEW_MOUSETEXT_TO_ASCII 1031
|
||||||
#define IDH_PVIEW_HITEXT 1036
|
#define IDH_PVIEW_HITEXT 1036
|
||||||
#define IDH_PVIEW_PASCALTEXT 1037
|
#define IDH_PVIEW_PASCALTEXT 1037
|
||||||
#define IDH_PVIEW_APPLESOFT 1038
|
#define IDH_PVIEW_APPLESOFT 1038
|
||||||
|
|
|
@ -11,3 +11,5 @@ This should update the CiderPress.chm in the app/Help directory. You can
|
||||||
copy it into the CiderPress directory, or just rebuild CiderPress to have
|
copy it into the CiderPress directory, or just rebuild CiderPress to have
|
||||||
it copied automatically.
|
it copied automatically.
|
||||||
|
|
||||||
|
NOTE: pop-up text must be added to PopUp.txt, PopUpIds.h, and the
|
||||||
|
PopUpHelpIds table in MyApp.cpp.
|
||||||
|
|
|
@ -91,7 +91,7 @@
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="Courier New" SIZE="2"> GetPort():@Port</FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="Courier New" SIZE="2"> GetPort():@Port</FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="Courier New" SIZE="2"> FreeMem():FreeBytes/4</FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="Courier New" SIZE="2"> FreeMem():FreeBytes/4</FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="Courier New" SIZE="2"> </FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="Courier New" SIZE="2"> </FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="Courier New" SIZE="2">A "/" and a digit after a parmeter means it takes the specified number</FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="Courier New" SIZE="2">A "/" and a digit after a parameter means it takes the specified number</FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="Courier New" SIZE="2">of bytes. (When making a tool call, you must push space on the stack</FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="Courier New" SIZE="2">of bytes. (When making a tool call, you must push space on the stack</FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="Courier New" SIZE="2">for any result values *before* pushing the input values.)</FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="Courier New" SIZE="2">for any result values *before* pushing the input values.)</FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="Courier New" SIZE="2"> </FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="Courier New" SIZE="2"> </FONT></P>
|
||||||
|
|
|
@ -73,7 +73,7 @@
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2">When CiderPress encounters data that it can't interpret, it stops trying to read from that section of the WAV file. For this reason, damaged entries will usually be shorter than undamaged ones. If a file appears to have the correct length but the checksum still doesn't match, it means the signal was sufficiently distorted to make a '0' bit look like a '1' bit, which is actually pretty hard to do. In most cases the decoder will either make an accurate determination or will conclude that the signal is too distorted to process. So far only one case has been found where the checksum was deliberately altered, as part of a copy protection scheme (Sargon II).</FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2">When CiderPress encounters data that it can't interpret, it stops trying to read from that section of the WAV file. For this reason, damaged entries will usually be shorter than undamaged ones. If a file appears to have the correct length but the checksum still doesn't match, it means the signal was sufficiently distorted to make a '0' bit look like a '1' bit, which is actually pretty hard to do. In most cases the decoder will either make an accurate determination or will conclude that the signal is too distorted to process. So far only one case has been found where the checksum was deliberately altered, as part of a copy protection scheme (Sargon II).</FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2">If the tape has more than one program on it, you can usually tell if it's multiple copies of the same thing by comparing lengths and checksums. If the checkums say "good" but have different values, you probably have two different programs, or two slightly different versions of the same program.</FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2">If the tape has more than one program on it, you can usually tell if it's multiple copies of the same thing by comparing lengths and checksums. If the checksums say "good" but have different values, you probably have two different programs, or two slightly different versions of the same program.</FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="3"> </FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="3"> </FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="3"><B>Saving the Data</B></FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="3"><B>Saving the Data</B></FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2">The pathname and modification date will be displayed but may not be changed. (To change the pathname, use the <A HREF="t42.htm">rename</A> feature.) The file type will be shown in the drop-down box, and may be changed by selecting a new entry. Tip: if you click in the drop box and type a letter, you will move to the next entry that begins with that letter. This can make it easier to find a file type by its three-letter abbreviation.</FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2">The pathname and modification date will be displayed but may not be changed. (To change the pathname, use the <A HREF="t42.htm">rename</A> feature.) The file type will be shown in the drop-down box, and may be changed by selecting a new entry. Tip: if you click in the drop box and type a letter, you will move to the next entry that begins with that letter. This can make it easier to find a file type by its three-letter abbreviation.</FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2">The auxilliary type (usually called "aux type") is shown as a 4-digit hexadecimal number, and may be edited freely.</FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2">The auxiliary type (usually called "aux type") is shown as a 4-digit hexadecimal number, and may be edited freely.</FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2">The type description is based on both the file type and the aux type. For example, type "LBR $E0" with aux type "8002" is listed as a "ShrinkIt (NuFX) document" in the Apple File Type Notes.</FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2">The type description is based on both the file type and the aux type. For example, type "LBR $E0" with aux type "8002" is listed as a "ShrinkIt (NuFX) document" in the Apple File Type Notes.</FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
||||||
|
|
|
@ -83,7 +83,7 @@
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2">There are actually three formats here. All of them convert common symbols and accented characters from the IIgs fonts to Windows fonts. Not all of the symbols have equivalents, but many of them do. Text written in languages other than English should convert correctly.</FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2">There are actually three formats here. All of them convert common symbols and accented characters from the IIgs fonts to Windows fonts. Not all of the symbols have equivalents, but many of them do. Text written in languages other than English should convert correctly.</FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2">The supported formats are:</FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2">The supported formats are:</FONT></P>
|
||||||
<UL STYLE="margin-top:0;margin-bottom:0;margin-left:10pt;"><LI><FONT FACE="MS Sans Serif" SIZE="2">Teach document (GWP $5445). The "Teach" application on the Apple IIgs created these, which have text in the data fork and formatting information in the resource fork. Font size and style changes are supported, accented characters are converted, and an attempt is made to convert the typeface to something similar to the original. The results are ususally pretty good.</FONT>
|
<UL STYLE="margin-top:0;margin-bottom:0;margin-left:10pt;"><LI><FONT FACE="MS Sans Serif" SIZE="2">Teach document (GWP $5445). The "Teach" application on the Apple IIgs created these, which have text in the data fork and formatting information in the resource fork. Font size and style changes are supported, accented characters are converted, and an attempt is made to convert the typeface to something similar to the original. The results are usually pretty good.</FONT>
|
||||||
<LI><FONT FACE="MS Sans Serif" SIZE="2">AppleWorks GS Word Processor (GWP $8010). Same basic features as "Teach", plus some basic formatting features like centered and justified paragraphs. The "header" and "footer" sections are displayed at the top of the converted document.</FONT>
|
<LI><FONT FACE="MS Sans Serif" SIZE="2">AppleWorks GS Word Processor (GWP $8010). Same basic features as "Teach", plus some basic formatting features like centered and justified paragraphs. The "header" and "footer" sections are displayed at the top of the converted document.</FONT>
|
||||||
<LI><FONT FACE="MS Sans Serif" SIZE="2">Generic (GWP, any aux type except the two above). Does a IIgs text conversion without any other reformatting. If you have a text file that uses symbols or accented characters from the IIgs font values, you can change its file type to GWP to enable this converter.</FONT></UL>
|
<LI><FONT FACE="MS Sans Serif" SIZE="2">Generic (GWP, any aux type except the two above). Does a IIgs text conversion without any other reformatting. If you have a text file that uses symbols or accented characters from the IIgs font values, you can change its file type to GWP to enable this converter.</FONT></UL>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
||||||
|
@ -118,7 +118,7 @@
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="3"> </FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="3"> </FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="3"><B>Super Hi-Res Graphics (PIC/PNT or 32K BIN, 320/640x200)</B></FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="3"><B>Super Hi-Res Graphics (PIC/PNT or 32K BIN, 320/640x200)</B></FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2">First introduced on the Apple IIgs, Super-Res was the first mode largely devoid of video idiosyncracies. When you set pixels to certain colors, the output on an RGB monitor was exactly what you expected. The resolution, which could be changed on every line, was 200 lines of either 320 pixels across with 4 bits of color per pixel, or 640 pixels across with 2 bits of color per pixel. The way colors in the file were translated to colors on screen involves some minor color palette gymnastics. The output of the converter is a 256-color 640x400 BMP.</FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2">First introduced on the Apple IIgs, Super-Res was the first mode largely devoid of video idiosyncrasies. When you set pixels to certain colors, the output on an RGB monitor was exactly what you expected. The resolution, which could be changed on every line, was 200 lines of either 320 pixels across with 4 bits of color per pixel, or 640 pixels across with 2 bits of color per pixel. The way colors in the file were translated to colors on screen involves some minor color palette gymnastics. The output of the converter is a 256-color 640x400 BMP.</FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2">Super-Res images were also the first to be regularly compressed, which isn't surprising since they're 4x as large as standard hi-res. CiderPress can convert images in the following formats:</FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2">Super-Res images were also the first to be regularly compressed, which isn't surprising since they're 4x as large as standard hi-res. CiderPress can convert images in the following formats:</FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2">One caution: if you format a disk for ProDOS, and then format it with your camera, you may find that it still appears to have some ProDOS files on it. (CiderPress should identify it as an MS-DOS "FAT" filesystem, but if the camera uses a non-standard boot block it may not be detected correctly.) Some files may appear to be damaged. This is because the camera's format routine didn't zero out all of the blocks, so some of the ProDOS directory structure is still present. Attempting to read or write files to the volume as if it were a ProDOS disk is not recommended. The safe way to switch between Apple II and Windows formatting is to use the image-copy tool to overwrite the entire CF card. Be aware that formatting with a camera can reduce the number of blocks available on the drive, which will make copying images onto it impossible: the image copier only works if the destination volume is at least as large as the source volume.</FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2">One caution: if you format a disk for ProDOS, and then format it with your camera, you may find that it still appears to have some ProDOS files on it. (CiderPress should identify it as an MS-DOS "FAT" filesystem, but if the camera uses a non-standard boot block it may not be detected correctly.) Some files may appear to be damaged. This is because the camera's format routine didn't zero out all of the blocks, so some of the ProDOS directory structure is still present. Attempting to read or write files to the volume as if it were a ProDOS disk is not recommended. The safe way to switch between Apple II and Windows formatting is to use the image-copy tool to overwrite the entire CF card. Be aware that formatting with a camera can reduce the number of blocks available on the drive, which will make copying images onto it impossible: the image copier only works if the destination volume is at least as large as the source volume.</FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2">The speed at which CF cards are read or written depends primarly on your card reader. USB2.0 readers will be faster than USB1.x, and Firewire, PCMCIA, or IDE interfaces will usually be faster than USB2.0. Also, some cards have a higher speed rating than others. Speeds of 200-400KB/sec are typical when copying from a USB1.x device, while writing to it may reach 700KB/sec. Writing tends to be faster than reading because of block caching.</FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2">The speed at which CF cards are read or written depends primarily on your card reader. USB2.0 readers will be faster than USB1.x, and Firewire, PCMCIA, or IDE interfaces will usually be faster than USB2.0. Also, some cards have a higher speed rating than others. Speeds of 200-400KB/sec are typical when copying from a USB1.x device, while writing to it may reach 700KB/sec. Writing tends to be faster than reading because of block caching.</FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2">CiderPress assumes that the first partition on a CFFA card will be ProDOS or HFS. If it's not, the image will not be detected as CFFA.</FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2">CiderPress assumes that the first partition on a CFFA card will be ProDOS or HFS. If it's not, the image will not be detected as CFFA.</FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="3"> </FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="3"> </FONT></P>
|
||||||
|
@ -56,7 +56,7 @@
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="3"> </FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="3"> </FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="3"><B>Hard Drives</B></FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="3"><B>Hard Drives</B></FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2">Apple II or Macintosh hard drives can be connected, assuming you have the necessary hardware (e.g. SCSI interface). Non-SCSI drives, such as the Applied Ingenuity InnerDrive or Vulcan drives, may not be formatted with the Macintosh partioning scheme and hence may be inaccessible.</FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2">Apple II or Macintosh hard drives can be connected, assuming you have the necessary hardware (e.g. SCSI interface). Non-SCSI drives, such as the Applied Ingenuity InnerDrive or Vulcan drives, may not be formatted with the Macintosh partitioning scheme and hence may be inaccessible.</FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2">Figuring out the size of a hard drive is a bit tricky under Windows, which uses different interfaces in different versions of the OS. Some interfaces return different answers depending on what version you're running. CiderPress currently scans the drive to determine its size.</FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2">Figuring out the size of a hard drive is a bit tricky under Windows, which uses different interfaces in different versions of the OS. Some interfaces return different answers depending on what version you're running. CiderPress currently scans the drive to determine its size.</FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;">
|
<P STYLE="margin-top:0;margin-bottom:0;">
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2">The sizes used are for the entire partition. If you formatted a 32MB ProDOS volume in a 1GB partition on a CFFA card, CiderPress will treat it as a 1GB volume, even though ProDOS is only on the first part of it. Extracting that ProDOS volume may be awkward.</FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2">The sizes used are for the entire partition. If you formatted a 32MB ProDOS volume in a 1GB partition on a CFFA card, CiderPress will treat it as a 1GB volume, even though ProDOS is only on the first part of it. Extracting that ProDOS volume may be awkward.</FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2">Hard drives with Macintosh-style partioning have explicit filesystem identification for each partition. That is, each partition will be labeled as ProDOS, HFS, a device driver, or whatever is appropriate. CiderPress does not currently have the ability to change these labels. Copying the wrong thing onto a partition, such as putting a ProDOS volume into a partition meant for HFS, could have unexpected results.</FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2">Hard drives with Macintosh-style partitioning have explicit filesystem identification for each partition. That is, each partition will be labeled as ProDOS, HFS, a device driver, or whatever is appropriate. CiderPress does not currently have the ability to change these labels. Copying the wrong thing onto a partition, such as putting a ProDOS volume into a partition meant for HFS, could have unexpected results.</FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2">Bear in mind that old hard drives are pretty slow by today's standards. A 2GB drive purchased in the mid-1990s will deliver 4-5MB/sec on bulk reads, which means it'll take about 8 minutes to back up the entire drive. These drives tended to have small caches and slow seeks though, so it can take 30 seconds to a minute for the contents of the disk to be loaded, because scanning the list of files requires lots of single-block reads.</FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2">Bear in mind that old hard drives are pretty slow by today's standards. A 2GB drive purchased in the mid-1990s will deliver 4-5MB/sec on bulk reads, which means it'll take about 8 minutes to back up the entire drive. These drives tended to have small caches and slow seeks though, so it can take 30 seconds to a minute for the contents of the disk to be loaded, because scanning the list of files requires lots of single-block reads.</FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2">You can also copy documents to other programs. To select the entire document, click on the document to set the input focus, then hit Ctrl-A to select all and Ctrl-C to copy it to the clipboard. Switch to another application (Windows WordPad and Microsoft Word are the most appropriate) and hit Ctrl-V to paste.</FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2">You can also copy documents to other programs. To select the entire document, click on the document to set the input focus, then hit Ctrl-A to select all and Ctrl-C to copy it to the clipboard. Switch to another application (Windows WordPad and Microsoft Word are the most appropriate) and hit Ctrl-V to paste.</FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2">Bear in mind that not all applications support all formats. Pasting text into Windows notepad, which doesn't support Rich Text Format, will cause highlighed BASIC listings and formatted AppleWorks documents to be converted to plain text. Pasting graphics into Notepad doesn't work at all.</FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2">Bear in mind that not all applications support all formats. Pasting text into Windows notepad, which doesn't support Rich Text Format, will cause highlighted BASIC listings and formatted AppleWorks documents to be converted to plain text. Pasting graphics into Notepad doesn't work at all.</FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2">Click "Done" to close the window.</FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2">Click "Done" to close the window.</FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;text-indent:-17pt;margin-left:17pt;"><SPAN STYLE="margin-left:-17pt;text-indent:0pt;width: 17pt"><FONT FACE="Symbol" SIZE="2"><B> </FONT></span><FONT FACE="MS Sans Serif" SIZE="2">Free Space:</B> how much free space is on the disk. For formats like CFFA, which just hold other disk images, this is meaningless.</FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;text-indent:-17pt;margin-left:17pt;"><SPAN STYLE="margin-left:-17pt;text-indent:0pt;width: 17pt"><FONT FACE="Symbol" SIZE="2"><B> </FONT></span><FONT FACE="MS Sans Serif" SIZE="2">Free Space:</B> how much free space is on the disk. For formats like CFFA, which just hold other disk images, this is meaningless.</FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;text-indent:-17pt;margin-left:17pt;"><SPAN STYLE="margin-left:-17pt;text-indent:0pt;width: 17pt"><FONT FACE="Symbol" SIZE="2"><B> </FONT></span><FONT FACE="MS Sans Serif" SIZE="2">Writable Format:</B> says whether or not CiderPress is capable of adding and deleting files on disks with this format. Currently this is "yes" for DOS 3.3, ProDOS, and UCSD Pascal.</FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;text-indent:-17pt;margin-left:17pt;"><SPAN STYLE="margin-left:-17pt;text-indent:0pt;width: 17pt"><FONT FACE="Symbol" SIZE="2"><B> </FONT></span><FONT FACE="MS Sans Serif" SIZE="2">Writable Format:</B> says whether or not CiderPress is capable of adding and deleting files on disks with this format. Currently this is "yes" for DOS 3.3, ProDOS, and UCSD Pascal.</FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;text-indent:-17pt;margin-left:17pt;"><SPAN STYLE="margin-left:-17pt;text-indent:0pt;width: 17pt"><FONT FACE="Symbol" SIZE="2"><B> </FONT></span><FONT FACE="MS Sans Serif" SIZE="2">Damaged: </B>this indicates whether or not CiderPress believes the disk is damaged. If it does, the disk will be marked read-only, and attempts to add or delete files will be blocked.</FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;text-indent:-17pt;margin-left:17pt;"><SPAN STYLE="margin-left:-17pt;text-indent:0pt;width: 17pt"><FONT FACE="Symbol" SIZE="2"><B> </FONT></span><FONT FACE="MS Sans Serif" SIZE="2">Damaged: </B>this indicates whether or not CiderPress believes the disk is damaged. If it does, the disk will be marked read-only, and attempts to add or delete files will be blocked.</FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;text-indent:-17pt;margin-left:17pt;"><SPAN STYLE="margin-left:-17pt;text-indent:0pt;width: 17pt"><FONT FACE="Symbol" SIZE="2"><B> </FONT></span><FONT FACE="MS Sans Serif" SIZE="2">Notes:</B> if CiderPress detects damage or other anomalies when scanning the disk, they wll be noted here.</FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;text-indent:-17pt;margin-left:17pt;"><SPAN STYLE="margin-left:-17pt;text-indent:0pt;width: 17pt"><FONT FACE="Symbol" SIZE="2"><B> </FONT></span><FONT FACE="MS Sans Serif" SIZE="2">Notes:</B> if CiderPress detects damage or other anomalies when scanning the disk, they will be noted here.</FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2">More information about the different disk formats can be found <A HREF="t18.htm">here</A>.</FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2">More information about the different disk formats can be found <A HREF="t18.htm">here</A>.</FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="3"> </FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="3"> </FONT></P>
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2">Windows XP:</FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2">Windows XP:</FONT></P>
|
||||||
<UL STYLE="margin-top:0;margin-bottom:0;margin-left:17pt;"><LI><FONT FACE="MS Sans Serif" SIZE="2">From the "Start" menu, select "Control Panel".</FONT>
|
<UL STYLE="margin-top:0;margin-bottom:0;margin-left:17pt;"><LI><FONT FACE="MS Sans Serif" SIZE="2">From the "Start" menu, select "Control Panel".</FONT>
|
||||||
<LI><FONT FACE="MS Sans Serif" SIZE="2">Click on "User Accounts". If you only see the current account, and it says "limited user", you're not an administator and cannot proceed further.</FONT>
|
<LI><FONT FACE="MS Sans Serif" SIZE="2">Click on "User Accounts". If you only see the current account, and it says "limited user", you're not an administrator and cannot proceed further.</FONT>
|
||||||
<LI><FONT FACE="MS Sans Serif" SIZE="2">Click on the account you want to change.</FONT>
|
<LI><FONT FACE="MS Sans Serif" SIZE="2">Click on the account you want to change.</FONT>
|
||||||
<LI><FONT FACE="MS Sans Serif" SIZE="2">Click on "Change my account type".</FONT>
|
<LI><FONT FACE="MS Sans Serif" SIZE="2">Click on "Change my account type".</FONT>
|
||||||
<LI><FONT FACE="MS Sans Serif" SIZE="2">Click the "Computer Administrator" radio button. Click "change account type".</FONT>
|
<LI><FONT FACE="MS Sans Serif" SIZE="2">Click the "Computer Administrator" radio button. Click "change account type".</FONT>
|
||||||
|
|
|
@ -88,7 +88,7 @@
|
||||||
<LI><FONT FACE="MS Sans Serif" SIZE="2">UNIDOS / AmDOS / OzDOS (two DOS volumes on an 800k disk)</FONT>
|
<LI><FONT FACE="MS Sans Serif" SIZE="2">UNIDOS / AmDOS / OzDOS (two DOS volumes on an 800k disk)</FONT>
|
||||||
<LI><FONT FACE="MS Sans Serif" SIZE="2">ProSel Uni-DOS / DOS Master (DOS volumes embedded in an 800K ProDOS disk)</FONT>
|
<LI><FONT FACE="MS Sans Serif" SIZE="2">ProSel Uni-DOS / DOS Master (DOS volumes embedded in an 800K ProDOS disk)</FONT>
|
||||||
<LI><FONT FACE="MS Sans Serif" SIZE="2">CFFA fixed-size partitions (4-part and 8-part formats)</FONT>
|
<LI><FONT FACE="MS Sans Serif" SIZE="2">CFFA fixed-size partitions (4-part and 8-part formats)</FONT>
|
||||||
<LI><FONT FACE="MS Sans Serif" SIZE="2">Macintosh-style partitoning (for CD-ROMs and SCSI hard drives)</FONT>
|
<LI><FONT FACE="MS Sans Serif" SIZE="2">Macintosh-style partitioning (for CD-ROMs and SCSI hard drives)</FONT>
|
||||||
<LI><FONT FACE="MS Sans Serif" SIZE="2">///SHH Systeme MicroDrive partitioning</FONT>
|
<LI><FONT FACE="MS Sans Serif" SIZE="2">///SHH Systeme MicroDrive partitioning</FONT>
|
||||||
<LI><FONT FACE="MS Sans Serif" SIZE="2">FocusDrive partitioning</FONT></UL>
|
<LI><FONT FACE="MS Sans Serif" SIZE="2">FocusDrive partitioning</FONT></UL>
|
||||||
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
<P STYLE="margin-top:0;margin-bottom:0;"><FONT FACE="MS Sans Serif" SIZE="2"> </FONT></P>
|
||||||
|
|
91
app/Main.cpp
91
app/Main.cpp
|
@ -133,6 +133,7 @@ static const UINT gFindReplaceID = RegisterWindowMessage(FINDMSGSTRING);
|
||||||
|
|
||||||
BEGIN_MESSAGE_MAP(MainWindow, CFrameWnd)
|
BEGIN_MESSAGE_MAP(MainWindow, CFrameWnd)
|
||||||
ON_WM_CREATE()
|
ON_WM_CREATE()
|
||||||
|
ON_WM_CLOSE()
|
||||||
ON_MESSAGE(WMU_LATE_INIT, OnLateInit)
|
ON_MESSAGE(WMU_LATE_INIT, OnLateInit)
|
||||||
//ON_MESSAGE(WMU_CLOSE_MAIN_DIALOG, OnCloseMainDialog)
|
//ON_MESSAGE(WMU_CLOSE_MAIN_DIALOG, OnCloseMainDialog)
|
||||||
ON_WM_SIZE()
|
ON_WM_SIZE()
|
||||||
|
@ -306,6 +307,12 @@ MainWindow::~MainWindow()
|
||||||
LOGI("MainWindow destructor complete");
|
LOGI("MainWindow destructor complete");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::OnClose()
|
||||||
|
{
|
||||||
|
SaveWinPlacement();
|
||||||
|
CFrameWnd::OnClose();
|
||||||
|
}
|
||||||
|
|
||||||
BOOL MainWindow::PreCreateWindow(CREATESTRUCT& cs)
|
BOOL MainWindow::PreCreateWindow(CREATESTRUCT& cs)
|
||||||
{
|
{
|
||||||
BOOL res = CFrameWnd::PreCreateWindow(cs);
|
BOOL res = CFrameWnd::PreCreateWindow(cs);
|
||||||
|
@ -563,6 +570,8 @@ int MainWindow::OnCreate(LPCREATESTRUCT lpcs)
|
||||||
|
|
||||||
fStatusBar.SetPaneText(kProgressPane, L"");
|
fStatusBar.SetPaneText(kProgressPane, L"");
|
||||||
|
|
||||||
|
RestoreWinPlacement();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -827,6 +836,7 @@ void MainWindow::OnEditPreferences(void)
|
||||||
ps.fFviewPage.fHighlightHexDump = fPreferences.GetPrefBool(kPrHighlightHexDump);
|
ps.fFviewPage.fHighlightHexDump = fPreferences.GetPrefBool(kPrHighlightHexDump);
|
||||||
ps.fFviewPage.fHighlightBASIC = fPreferences.GetPrefBool(kPrHighlightBASIC);
|
ps.fFviewPage.fHighlightBASIC = fPreferences.GetPrefBool(kPrHighlightBASIC);
|
||||||
ps.fFviewPage.fConvDisasmOneByteBrkCop = fPreferences.GetPrefBool(kPrDisasmOneByteBrkCop);
|
ps.fFviewPage.fConvDisasmOneByteBrkCop = fPreferences.GetPrefBool(kPrDisasmOneByteBrkCop);
|
||||||
|
ps.fFviewPage.fConvMouseTextToASCII = fPreferences.GetPrefBool(kPrConvMouseTextToASCII);
|
||||||
ps.fFviewPage.fConvHiResBlackWhite = fPreferences.GetPrefBool(kPrConvHiResBlackWhite);
|
ps.fFviewPage.fConvHiResBlackWhite = fPreferences.GetPrefBool(kPrConvHiResBlackWhite);
|
||||||
ps.fFviewPage.fConvDHRAlgorithm = fPreferences.GetPrefLong(kPrConvDHRAlgorithm);
|
ps.fFviewPage.fConvDHRAlgorithm = fPreferences.GetPrefLong(kPrConvDHRAlgorithm);
|
||||||
ps.fFviewPage.fRelaxGfxTypeCheck = fPreferences.GetPrefBool(kPrRelaxGfxTypeCheck);
|
ps.fFviewPage.fRelaxGfxTypeCheck = fPreferences.GetPrefBool(kPrRelaxGfxTypeCheck);
|
||||||
|
@ -955,6 +965,7 @@ void MainWindow::ApplyNow(PrefsSheet* pPS)
|
||||||
fPreferences.SetPrefBool(kPrHighlightHexDump, pPS->fFviewPage.fHighlightHexDump != 0);
|
fPreferences.SetPrefBool(kPrHighlightHexDump, pPS->fFviewPage.fHighlightHexDump != 0);
|
||||||
fPreferences.SetPrefBool(kPrHighlightBASIC, pPS->fFviewPage.fHighlightBASIC != 0);
|
fPreferences.SetPrefBool(kPrHighlightBASIC, pPS->fFviewPage.fHighlightBASIC != 0);
|
||||||
fPreferences.SetPrefBool(kPrDisasmOneByteBrkCop, pPS->fFviewPage.fConvDisasmOneByteBrkCop != 0);
|
fPreferences.SetPrefBool(kPrDisasmOneByteBrkCop, pPS->fFviewPage.fConvDisasmOneByteBrkCop != 0);
|
||||||
|
fPreferences.SetPrefBool(kPrConvMouseTextToASCII, pPS->fFviewPage.fConvMouseTextToASCII != 0);
|
||||||
fPreferences.SetPrefBool(kPrConvHiResBlackWhite, pPS->fFviewPage.fConvHiResBlackWhite != 0);
|
fPreferences.SetPrefBool(kPrConvHiResBlackWhite, pPS->fFviewPage.fConvHiResBlackWhite != 0);
|
||||||
fPreferences.SetPrefLong(kPrConvDHRAlgorithm, pPS->fFviewPage.fConvDHRAlgorithm);
|
fPreferences.SetPrefLong(kPrConvDHRAlgorithm, pPS->fFviewPage.fConvDHRAlgorithm);
|
||||||
fPreferences.SetPrefBool(kPrRelaxGfxTypeCheck, pPS->fFviewPage.fRelaxGfxTypeCheck != 0);
|
fPreferences.SetPrefBool(kPrRelaxGfxTypeCheck, pPS->fFviewPage.fRelaxGfxTypeCheck != 0);
|
||||||
|
@ -1887,6 +1898,84 @@ void MainWindow::EventPause(int duration)
|
||||||
* ===================================
|
* ===================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static const WCHAR kMainWinSection[] = L"mainwin";
|
||||||
|
static const WCHAR kMainWin_Left[] = L"left";
|
||||||
|
static const WCHAR kMainWin_Top[] = L"top";
|
||||||
|
static const WCHAR kMainWin_Right[] = L"right";
|
||||||
|
static const WCHAR kMainWin_Bottom[] = L"bottom";
|
||||||
|
static const WCHAR kMainWin_Cmd[] = L"cmd";
|
||||||
|
|
||||||
|
void MainWindow::SaveWinPlacement()
|
||||||
|
{
|
||||||
|
// Capture the current window position. At the point where the destructor
|
||||||
|
// fires, too much has been shut down, so we need to do it here.
|
||||||
|
WINDOWPLACEMENT wndpl;
|
||||||
|
wndpl.length = sizeof(wndpl);
|
||||||
|
if (!GetWindowPlacement(&wndpl)) {
|
||||||
|
LOGW("Unable to get window placement");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGD("Window is at ltrb=%ld,%ld %ldx%ld showCmd=%d",
|
||||||
|
wndpl.rcNormalPosition.left,
|
||||||
|
wndpl.rcNormalPosition.top,
|
||||||
|
wndpl.rcNormalPosition.right - wndpl.rcNormalPosition.left,
|
||||||
|
wndpl.rcNormalPosition.bottom - wndpl.rcNormalPosition.top,
|
||||||
|
wndpl.showCmd);
|
||||||
|
gMyApp.WriteProfileInt(kMainWinSection,
|
||||||
|
kMainWin_Left, wndpl.rcNormalPosition.left);
|
||||||
|
gMyApp.WriteProfileInt(kMainWinSection,
|
||||||
|
kMainWin_Top, wndpl.rcNormalPosition.top);
|
||||||
|
gMyApp.WriteProfileInt(kMainWinSection,
|
||||||
|
kMainWin_Right, wndpl.rcNormalPosition.right);
|
||||||
|
gMyApp.WriteProfileInt(kMainWinSection,
|
||||||
|
kMainWin_Bottom, wndpl.rcNormalPosition.bottom);
|
||||||
|
gMyApp.WriteProfileInt(kMainWinSection,
|
||||||
|
kMainWin_Cmd, wndpl.showCmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::RestoreWinPlacement()
|
||||||
|
{
|
||||||
|
const int kNoVal = -32000;
|
||||||
|
|
||||||
|
RECT normPos;
|
||||||
|
normPos.left = gMyApp.GetProfileInt(kMainWinSection, kMainWin_Left, kNoVal);
|
||||||
|
normPos.top = gMyApp.GetProfileInt(kMainWinSection, kMainWin_Top, kNoVal);
|
||||||
|
normPos.right = gMyApp.GetProfileInt(kMainWinSection, kMainWin_Right, kNoVal);
|
||||||
|
normPos.bottom = gMyApp.GetProfileInt(kMainWinSection, kMainWin_Bottom, kNoVal);
|
||||||
|
int cmd = gMyApp.GetProfileInt(kMainWinSection, kMainWin_Cmd, kNoVal);
|
||||||
|
|
||||||
|
if (normPos.left == kNoVal || normPos.top == kNoVal ||
|
||||||
|
normPos.right == kNoVal || normPos.bottom == kNoVal || cmd == kNoVal) {
|
||||||
|
LOGI("Previous window placement not found.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
POINT nopt;
|
||||||
|
nopt.x = nopt.y = -1;
|
||||||
|
|
||||||
|
// We need to set the placement for "normal", and then deal with
|
||||||
|
// maximized windows by having the MyApp ShowWindow() call pass the
|
||||||
|
// appropriate command. If we pass the correct normal rect here with
|
||||||
|
// the "maximized" command, we end up with a non-maximized window of
|
||||||
|
// maximum size. (If done correctly, you can maximize, quit, restart,
|
||||||
|
// and un-maximize back to the original size.)
|
||||||
|
WINDOWPLACEMENT wndpl;
|
||||||
|
wndpl.length = sizeof(wndpl);
|
||||||
|
wndpl.flags = 0;
|
||||||
|
wndpl.showCmd = SW_SHOWNORMAL;
|
||||||
|
wndpl.ptMinPosition = nopt;
|
||||||
|
wndpl.ptMaxPosition = nopt;
|
||||||
|
wndpl.rcNormalPosition = normPos;
|
||||||
|
|
||||||
|
LOGD("Restoring previous placement, cmd=%d", wndpl.showCmd);
|
||||||
|
SetWindowPlacement(&wndpl);
|
||||||
|
|
||||||
|
// Stomp on MyApp's show command. We don't want to start minimized,
|
||||||
|
// so switch to "normal" if that's set.
|
||||||
|
gMyApp.m_nCmdShow = (cmd == SW_SHOWMINIMIZED ? SW_SHOWNORMAL : cmd);
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::DrawEmptyClientArea(CDC* pDC, const CRect& clientRect)
|
void MainWindow::DrawEmptyClientArea(CDC* pDC, const CRect& clientRect)
|
||||||
{
|
{
|
||||||
CBrush brush;
|
CBrush brush;
|
||||||
|
@ -2465,6 +2554,8 @@ CString MainWindow::RemoveFile(const WCHAR* fileName)
|
||||||
pPreferences->GetPrefBool(kPrRelaxGfxTypeCheck));
|
pPreferences->GetPrefBool(kPrRelaxGfxTypeCheck));
|
||||||
pReformat->SetOption(ReformatHolder::kOptOneByteBrkCop,
|
pReformat->SetOption(ReformatHolder::kOptOneByteBrkCop,
|
||||||
pPreferences->GetPrefBool(kPrDisasmOneByteBrkCop));
|
pPreferences->GetPrefBool(kPrDisasmOneByteBrkCop));
|
||||||
|
pReformat->SetOption(ReformatHolder::kOptMouseTextToASCII,
|
||||||
|
pPreferences->GetPrefBool(kPrConvMouseTextToASCII));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*static*/ ReformatHolder::SourceFormat MainWindow::ReformatterSourceFormat(
|
/*static*/ ReformatHolder::SourceFormat MainWindow::ReformatterSourceFormat(
|
||||||
|
|
17
app/Main.h
17
app/Main.h
|
@ -54,7 +54,7 @@ public:
|
||||||
/*
|
/*
|
||||||
* Override the pre-create function to tweak the window style.
|
* Override the pre-create function to tweak the window style.
|
||||||
*/
|
*/
|
||||||
BOOL PreCreateWindow(CREATESTRUCT& cs) override;
|
virtual BOOL PreCreateWindow(CREATESTRUCT& cs) override;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Override GetClientRect so we can factor in the status and tool bars.
|
* Override GetClientRect so we can factor in the status and tool bars.
|
||||||
|
@ -71,8 +71,8 @@ public:
|
||||||
void ApplyNow(PrefsSheet*);
|
void ApplyNow(PrefsSheet*);
|
||||||
|
|
||||||
// get the text of the next file in the selection list
|
// get the text of the next file in the selection list
|
||||||
int GetPrevFileText(ReformatHolder* pHolder, CString* pTitle);
|
//int GetPrevFileText(ReformatHolder* pHolder, CString* pTitle);
|
||||||
int GetNextFileText(ReformatHolder* pHolder, CString* pTitle);
|
//int GetNextFileText(ReformatHolder* pHolder, CString* pTitle);
|
||||||
|
|
||||||
// update the progress meter
|
// update the progress meter
|
||||||
void SetProgressBegin(void);
|
void SetProgressBegin(void);
|
||||||
|
@ -268,6 +268,7 @@ private:
|
||||||
|
|
||||||
// Command handlers
|
// Command handlers
|
||||||
afx_msg int OnCreate(LPCREATESTRUCT lpcs);
|
afx_msg int OnCreate(LPCREATESTRUCT lpcs);
|
||||||
|
afx_msg void OnClose();
|
||||||
afx_msg LONG OnLateInit(UINT, LONG);
|
afx_msg LONG OnLateInit(UINT, LONG);
|
||||||
afx_msg void OnSize(UINT nType, int cx, int cy);
|
afx_msg void OnSize(UINT nType, int cx, int cy);
|
||||||
afx_msg void OnGetMinMaxInfo(MINMAXINFO* pMMI);
|
afx_msg void OnGetMinMaxInfo(MINMAXINFO* pMMI);
|
||||||
|
@ -489,6 +490,14 @@ private:
|
||||||
*/
|
*/
|
||||||
void DrawEmptyClientArea(CDC* pDC, const CRect& clientRect);
|
void DrawEmptyClientArea(CDC* pDC, const CRect& clientRect);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Save/restore main window placement. The restore function will move
|
||||||
|
* the window if the previous placement is no longer visible (e.g. a
|
||||||
|
* secondary monitor was removed).
|
||||||
|
*/
|
||||||
|
void SaveWinPlacement();
|
||||||
|
void RestoreWinPlacement();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Extract a record to the temp folder and open it with a new instance of
|
* Extract a record to the temp folder and open it with a new instance of
|
||||||
* CiderPress. We might want to extract disk images as 2MG files to take
|
* CiderPress. We might want to extract disk images as 2MG files to take
|
||||||
|
@ -607,7 +616,7 @@ private:
|
||||||
*/
|
*/
|
||||||
void HandleView(void);
|
void HandleView(void);
|
||||||
|
|
||||||
void DeleteFileOnExit(const WCHAR* name);
|
//void DeleteFileOnExit(const WCHAR* name);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Close and re-open the current archive.
|
* Close and re-open the current archive.
|
||||||
|
|
|
@ -64,6 +64,16 @@ MyApp::~MyApp(void)
|
||||||
|
|
||||||
BOOL MyApp::InitInstance(void)
|
BOOL MyApp::InitInstance(void)
|
||||||
{
|
{
|
||||||
|
// This causes functions like SetProfileInt to use the registry rather
|
||||||
|
// than a .INI file. The registry key is "usually the name of a company".
|
||||||
|
// (Must do this before creating main window so we can restore the
|
||||||
|
// previous window position.)
|
||||||
|
#ifdef CAN_UPDATE_FILE_ASSOC
|
||||||
|
SetRegistryKey(fRegistry.GetAppRegistryKey());
|
||||||
|
#else
|
||||||
|
SetRegistryKey(L"faddenSoft");
|
||||||
|
#endif
|
||||||
|
|
||||||
// Create the main window.
|
// Create the main window.
|
||||||
m_pMainWnd = new MainWindow;
|
m_pMainWnd = new MainWindow;
|
||||||
m_pMainWnd->ShowWindow(m_nCmdShow);
|
m_pMainWnd->ShowWindow(m_nCmdShow);
|
||||||
|
@ -92,14 +102,6 @@ BOOL MyApp::InitInstance(void)
|
||||||
LogModuleLocation(L"riched32.dll");
|
LogModuleLocation(L"riched32.dll");
|
||||||
LogModuleLocation(L"msftedit.dll");
|
LogModuleLocation(L"msftedit.dll");
|
||||||
|
|
||||||
// This causes functions like SetProfileInt to use the registry rather
|
|
||||||
// than a .INI file. The registry key is "usually the name of a company".
|
|
||||||
#ifdef CAN_UPDATE_FILE_ASSOC
|
|
||||||
SetRegistryKey(fRegistry.GetAppRegistryKey());
|
|
||||||
#else
|
|
||||||
SetRegistryKey(L"faddenSoft");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//LOGI("Registry key is '%ls'", m_pszRegistryKey);
|
//LOGI("Registry key is '%ls'", m_pszRegistryKey);
|
||||||
//LOGI("Profile name is '%ls'", m_pszProfileName);
|
//LOGI("Profile name is '%ls'", m_pszProfileName);
|
||||||
LOGI("Short command line is '%ls'", m_lpCmdLine);
|
LOGI("Short command line is '%ls'", m_lpCmdLine);
|
||||||
|
@ -201,6 +203,7 @@ BOOL MyApp::OnIdle(LONG lCount)
|
||||||
IDC_PVIEW_DISASM_ONEBYTEBRKCOP, IDH_PVIEW_DISASM_ONEBYTEBRKCOP,
|
IDC_PVIEW_DISASM_ONEBYTEBRKCOP, IDH_PVIEW_DISASM_ONEBYTEBRKCOP,
|
||||||
IDC_PVIEW_HIRES_BW, IDH_PVIEW_HIRES_BW,
|
IDC_PVIEW_HIRES_BW, IDH_PVIEW_HIRES_BW,
|
||||||
IDC_PVIEW_DHR_CONV_COMBO, IDH_PVIEW_DHR_CONV_COMBO,
|
IDC_PVIEW_DHR_CONV_COMBO, IDH_PVIEW_DHR_CONV_COMBO,
|
||||||
|
IDC_PVIEW_MOUSETEXT_TO_ASCII, IDH_PVIEW_MOUSETEXT_TO_ASCII,
|
||||||
IDC_PVIEW_HITEXT, IDH_PVIEW_HITEXT,
|
IDC_PVIEW_HITEXT, IDH_PVIEW_HITEXT,
|
||||||
IDC_PVIEW_PASCALTEXT, IDH_PVIEW_PASCALTEXT,
|
IDC_PVIEW_PASCALTEXT, IDH_PVIEW_PASCALTEXT,
|
||||||
IDC_PVIEW_APPLESOFT, IDH_PVIEW_APPLESOFT,
|
IDC_PVIEW_APPLESOFT, IDH_PVIEW_APPLESOFT,
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
/* CiderPress version numbers */
|
/* CiderPress version numbers */
|
||||||
#define kAppMajorVersion 4
|
#define kAppMajorVersion 4
|
||||||
#define kAppMinorVersion 0
|
#define kAppMinorVersion 1
|
||||||
#define kAppBugVersion 1
|
#define kAppBugVersion 1
|
||||||
#define kAppDevString L""
|
#define kAppDevString L""
|
||||||
|
|
||||||
|
|
|
@ -835,6 +835,7 @@ NuResult NufxArchive::ContentFunc(NuArchive* pArchive, void* vpRecord)
|
||||||
pDateTime->extra == 0 &&
|
pDateTime->extra == 0 &&
|
||||||
pDateTime->weekDay == 0)
|
pDateTime->weekDay == 0)
|
||||||
{
|
{
|
||||||
|
// not invalid; just no date set
|
||||||
return kDateNone;
|
return kDateNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -858,8 +859,17 @@ NuResult NufxArchive::ContentFunc(NuArchive* pArchive, void* vpRecord)
|
||||||
//LOGI(" Ignoring funky year %ld", year);
|
//LOGI(" Ignoring funky year %ld", year);
|
||||||
return kDateInvalid;
|
return kDateInvalid;
|
||||||
}
|
}
|
||||||
if (pDateTime->month > 11)
|
|
||||||
|
// Must range-check values before passing them to CTime constructor, which
|
||||||
|
// now throws a remarkably fatal exception.
|
||||||
|
if (pDateTime->month > 11 || // [0,11]
|
||||||
|
pDateTime->day > 30 || // [0,30]
|
||||||
|
pDateTime->hour > 59 || // [0,59]
|
||||||
|
pDateTime->minute > 59 || // [0,59]
|
||||||
|
pDateTime->second > 59) { // [0,59]
|
||||||
|
|
||||||
return kDateInvalid;
|
return kDateInvalid;
|
||||||
|
}
|
||||||
|
|
||||||
CTime modTime(year,
|
CTime modTime(year,
|
||||||
pDateTime->month+1,
|
pDateTime->month+1,
|
||||||
|
@ -867,7 +877,8 @@ NuResult NufxArchive::ContentFunc(NuArchive* pArchive, void* vpRecord)
|
||||||
pDateTime->hour,
|
pDateTime->hour,
|
||||||
pDateTime->minute,
|
pDateTime->minute,
|
||||||
pDateTime->second);
|
pDateTime->second);
|
||||||
return (time_t) modTime.GetTime();
|
time_t result = (time_t)modTime.GetTime();
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*static*/ NuResult NufxArchive::ArrayDeleteHandler(NuArchive* pArchive, void* ptr)
|
/*static*/ NuResult NufxArchive::ArrayDeleteHandler(NuArchive* pArchive, void* ptr)
|
||||||
|
|
|
@ -108,6 +108,7 @@ const Preferences::PrefMap Preferences::fPrefMaps[kPrefNumLastEntry] = {
|
||||||
{ kPrConvDHRAlgorithm, kLong, kPrefsSect, L"dhr-algorithm" },
|
{ kPrConvDHRAlgorithm, kLong, kPrefsSect, L"dhr-algorithm" },
|
||||||
{ kPrRelaxGfxTypeCheck, kBool, kPrefsSect, L"relax-gfx-type-check" },
|
{ kPrRelaxGfxTypeCheck, kBool, kPrefsSect, L"relax-gfx-type-check" },
|
||||||
{ kPrDisasmOneByteBrkCop, kBool, kPrefsSect, L"disasm-onebytebrkcop" },
|
{ kPrDisasmOneByteBrkCop, kBool, kPrefsSect, L"disasm-onebytebrkcop" },
|
||||||
|
{ kPrConvMouseTextToASCII, kBool, kPrefsSect, L"conv-mouse-text-to-ascii" },
|
||||||
//{ kPrEOLConvRaw, kBool, kPrefsSect, L"eol-conv-raw" },
|
//{ kPrEOLConvRaw, kBool, kPrefsSect, L"eol-conv-raw" },
|
||||||
{ kPrConvTextEOL_HA, kBool, kPrefsSect, L"conv-eol-ha" },
|
{ kPrConvTextEOL_HA, kBool, kPrefsSect, L"conv-eol-ha" },
|
||||||
{ kPrConvPascalText, kBool, kPrefsSect, L"conv-pascal-text" },
|
{ kPrConvPascalText, kBool, kPrefsSect, L"conv-pascal-text" },
|
||||||
|
@ -214,6 +215,7 @@ Preferences::Preferences(void)
|
||||||
SetPrefLong(kPrConvDHRAlgorithm, 1); // latched
|
SetPrefLong(kPrConvDHRAlgorithm, 1); // latched
|
||||||
SetPrefBool(kPrRelaxGfxTypeCheck, true);
|
SetPrefBool(kPrRelaxGfxTypeCheck, true);
|
||||||
SetPrefBool(kPrDisasmOneByteBrkCop, false);
|
SetPrefBool(kPrDisasmOneByteBrkCop, false);
|
||||||
|
SetPrefBool(kPrConvMouseTextToASCII, false);
|
||||||
//SetPrefBool(kPrEOLConvRaw, true);
|
//SetPrefBool(kPrEOLConvRaw, true);
|
||||||
SetPrefBool(kPrConvTextEOL_HA, true);
|
SetPrefBool(kPrConvTextEOL_HA, true);
|
||||||
SetPrefBool(kPrConvPascalText, true);
|
SetPrefBool(kPrConvPascalText, true);
|
||||||
|
@ -245,16 +247,20 @@ Preferences::Preferences(void)
|
||||||
|
|
||||||
SetPrefString(kPrViewTextTypeFace, L"Courier New");
|
SetPrefString(kPrViewTextTypeFace, L"Courier New");
|
||||||
SetPrefLong(kPrViewTextPointSize, 10);
|
SetPrefLong(kPrViewTextPointSize, 10);
|
||||||
long width = 680 + /* exact width for 80-column text */
|
|
||||||
::GetSystemMetrics(SM_CXVSCROLL);
|
float scaleFactor = GetDesktopScaleFactor();
|
||||||
long height = 516; /* exact height for file viewer to show IIgs graphic */
|
/* exact width for 80-column text; note text is scaled up */
|
||||||
|
long width = (int)(680 * scaleFactor) + ::GetSystemMetrics(SM_CXVSCROLL);
|
||||||
|
/* exact height for file viewer to show IIgs graphic at 1.0x */
|
||||||
|
long height = (int)(516 * scaleFactor);
|
||||||
|
|
||||||
if (GetSystemMetrics(SM_CXSCREEN) < width)
|
if (GetSystemMetrics(SM_CXSCREEN) < width)
|
||||||
width = GetSystemMetrics(SM_CXSCREEN);
|
width = GetSystemMetrics(SM_CXSCREEN);
|
||||||
if (GetSystemMetrics(SM_CYSCREEN) < height)
|
if (GetSystemMetrics(SM_CYSCREEN) < height)
|
||||||
height = GetSystemMetrics(SM_CYSCREEN); // may overlap system bar
|
height = GetSystemMetrics(SM_CYSCREEN); // may overlap system bar
|
||||||
//width = 640; height = 480;
|
|
||||||
SetPrefLong(kPrFileViewerWidth, width);
|
SetPrefLong(kPrFileViewerWidth, width);
|
||||||
SetPrefLong(kPrFileViewerHeight, height);
|
SetPrefLong(kPrFileViewerHeight, height);
|
||||||
|
|
||||||
SetPrefLong(kPrDiskImageCreateFormat, -1);
|
SetPrefLong(kPrDiskImageCreateFormat, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,13 @@
|
||||||
* section to the registry if appropriate.
|
* section to the registry if appropriate.
|
||||||
* - Add a default value to Preferences::Preferences. If not specified,
|
* - Add a default value to Preferences::Preferences. If not specified,
|
||||||
* strings will be NULL and numeric values will be zero.
|
* strings will be NULL and numeric values will be zero.
|
||||||
|
*
|
||||||
|
* For user-settable preferencers, you must also:
|
||||||
|
* - Add a UI element to the appropriate preference page.
|
||||||
|
* - Add the appropriate code for that item. Note in particular the data
|
||||||
|
* exchange and ON_CONTROL_RANGE values.
|
||||||
|
* - In Main.cpp, update OnEditPreferences() to init the page.
|
||||||
|
* - Add a tooltip to the help file.
|
||||||
*/
|
*/
|
||||||
#ifndef APP_PREFERENCES_H
|
#ifndef APP_PREFERENCES_H
|
||||||
#define APP_PREFERENCES_H
|
#define APP_PREFERENCES_H
|
||||||
|
@ -168,6 +175,7 @@ typedef enum {
|
||||||
kPrConvDHRAlgorithm, // long
|
kPrConvDHRAlgorithm, // long
|
||||||
kPrRelaxGfxTypeCheck, // bool
|
kPrRelaxGfxTypeCheck, // bool
|
||||||
kPrDisasmOneByteBrkCop, // bool
|
kPrDisasmOneByteBrkCop, // bool
|
||||||
|
kPrConvMouseTextToASCII, // bool
|
||||||
//kPrEOLConvRaw, // bool
|
//kPrEOLConvRaw, // bool
|
||||||
kPrConvTextEOL_HA, // bool
|
kPrConvTextEOL_HA, // bool
|
||||||
kPrConvPascalText, // bool
|
kPrConvPascalText, // bool
|
||||||
|
|
|
@ -316,6 +316,7 @@ void PrefsFviewPage::DoDataExchange(CDataExchange* pDX)
|
||||||
DDX_Check(pDX, IDC_PVIEW_BOLD_HEXDUMP, fHighlightHexDump);
|
DDX_Check(pDX, IDC_PVIEW_BOLD_HEXDUMP, fHighlightHexDump);
|
||||||
DDX_Check(pDX, IDC_PVIEW_BOLD_BASIC, fHighlightBASIC);
|
DDX_Check(pDX, IDC_PVIEW_BOLD_BASIC, fHighlightBASIC);
|
||||||
DDX_Check(pDX, IDC_PVIEW_DISASM_ONEBYTEBRKCOP, fConvDisasmOneByteBrkCop);
|
DDX_Check(pDX, IDC_PVIEW_DISASM_ONEBYTEBRKCOP, fConvDisasmOneByteBrkCop);
|
||||||
|
DDX_Check(pDX, IDC_PVIEW_MOUSETEXT_TO_ASCII, fConvMouseTextToASCII);
|
||||||
DDX_Check(pDX, IDC_PVIEW_HIRES_BW, fConvHiResBlackWhite);
|
DDX_Check(pDX, IDC_PVIEW_HIRES_BW, fConvHiResBlackWhite);
|
||||||
DDX_CBIndex(pDX, IDC_PVIEW_DHR_CONV_COMBO, fConvDHRAlgorithm);
|
DDX_CBIndex(pDX, IDC_PVIEW_DHR_CONV_COMBO, fConvDHRAlgorithm);
|
||||||
|
|
||||||
|
|
|
@ -23,11 +23,14 @@ public:
|
||||||
PrefsGeneralPage(void) :
|
PrefsGeneralPage(void) :
|
||||||
CPropertyPage(IDD_PREF_GENERAL),
|
CPropertyPage(IDD_PREF_GENERAL),
|
||||||
fReady(false),
|
fReady(false),
|
||||||
|
fColumn(),
|
||||||
fMimicShrinkIt(FALSE),
|
fMimicShrinkIt(FALSE),
|
||||||
fBadMacSHK(FALSE),
|
fBadMacSHK(FALSE),
|
||||||
fReduceSHKErrorChecks(FALSE),
|
fReduceSHKErrorChecks(FALSE),
|
||||||
fCoerceDOSFilenames(FALSE),
|
fCoerceDOSFilenames(FALSE),
|
||||||
fSpacesToUnder(FALSE),
|
fSpacesToUnder(FALSE),
|
||||||
|
fPasteJunkPaths(FALSE),
|
||||||
|
fBeepOnSuccess(FALSE),
|
||||||
fDefaultsPushed(FALSE),
|
fDefaultsPushed(FALSE),
|
||||||
fOurAssociations(NULL)
|
fOurAssociations(NULL)
|
||||||
{}
|
{}
|
||||||
|
@ -82,6 +85,7 @@ public:
|
||||||
fReady(false),
|
fReady(false),
|
||||||
fQueryImageFormat(FALSE),
|
fQueryImageFormat(FALSE),
|
||||||
fOpenVolumeRO(FALSE),
|
fOpenVolumeRO(FALSE),
|
||||||
|
fOpenVolumePhys0(FALSE),
|
||||||
fProDOSAllowLower(FALSE),
|
fProDOSAllowLower(FALSE),
|
||||||
fProDOSUseSparse(FALSE)
|
fProDOSUseSparse(FALSE)
|
||||||
{}
|
{}
|
||||||
|
@ -119,7 +123,9 @@ class PrefsCompressionPage : public CPropertyPage
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PrefsCompressionPage(void) :
|
PrefsCompressionPage(void) :
|
||||||
CPropertyPage(IDD_PREF_COMPRESSION), fReady(false)
|
CPropertyPage(IDD_PREF_COMPRESSION),
|
||||||
|
fReady(false),
|
||||||
|
fCompressType(-1)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool fReady;
|
bool fReady;
|
||||||
|
@ -159,7 +165,39 @@ class PrefsFviewPage : public CPropertyPage
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PrefsFviewPage(void) :
|
PrefsFviewPage(void) :
|
||||||
CPropertyPage(IDD_PREF_FVIEW), fReady(false)
|
CPropertyPage(IDD_PREF_FVIEW),
|
||||||
|
fReady(false),
|
||||||
|
fEOLConvRaw(FALSE),
|
||||||
|
fNoWrapText(FALSE),
|
||||||
|
fHighlightHexDump(FALSE),
|
||||||
|
fHighlightBASIC(FALSE),
|
||||||
|
fConvDisasmOneByteBrkCop(FALSE),
|
||||||
|
fConvMouseTextToASCII(FALSE),
|
||||||
|
fConvHiResBlackWhite(FALSE),
|
||||||
|
fConvDHRAlgorithm(-1),
|
||||||
|
fConvTextEOL_HA(FALSE),
|
||||||
|
fConvCPMText(FALSE),
|
||||||
|
fConvPascalText(FALSE),
|
||||||
|
fConvPascalCode(FALSE),
|
||||||
|
fConvApplesoft(FALSE),
|
||||||
|
fConvInteger(FALSE),
|
||||||
|
fConvBusiness(FALSE),
|
||||||
|
fConvGWP(FALSE),
|
||||||
|
fConvText8(FALSE),
|
||||||
|
fConvAWP(FALSE),
|
||||||
|
fConvADB(FALSE),
|
||||||
|
fConvASP(FALSE),
|
||||||
|
fConvSCAssem(FALSE),
|
||||||
|
fConvDisasm(FALSE),
|
||||||
|
fConvHiRes(FALSE),
|
||||||
|
fConvDHR(FALSE),
|
||||||
|
fConvSHR(FALSE),
|
||||||
|
fConvPrintShop(FALSE),
|
||||||
|
fConvMacPaint(FALSE),
|
||||||
|
fConvProDOSFolder(FALSE),
|
||||||
|
fConvResources(FALSE),
|
||||||
|
fRelaxGfxTypeCheck(FALSE),
|
||||||
|
fMaxViewFileSizeKB(0)
|
||||||
{}
|
{}
|
||||||
bool fReady;
|
bool fReady;
|
||||||
|
|
||||||
|
@ -168,6 +206,7 @@ public:
|
||||||
BOOL fHighlightHexDump;
|
BOOL fHighlightHexDump;
|
||||||
BOOL fHighlightBASIC;
|
BOOL fHighlightBASIC;
|
||||||
BOOL fConvDisasmOneByteBrkCop;
|
BOOL fConvDisasmOneByteBrkCop;
|
||||||
|
BOOL fConvMouseTextToASCII;
|
||||||
BOOL fConvHiResBlackWhite;
|
BOOL fConvHiResBlackWhite;
|
||||||
int fConvDHRAlgorithm; // drop list
|
int fConvDHRAlgorithm; // drop list
|
||||||
|
|
||||||
|
|
|
@ -1787,7 +1787,7 @@ long MainWindow::SSTGetBufOffset(int track)
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
long MainWindow::SSTCountBadBytes(const unsigned char* sctBuf, int count)
|
long MainWindow::SSTCountBadBytes(const uint8_t* sctBuf, int count)
|
||||||
{
|
{
|
||||||
long badCount = 0;
|
long badCount = 0;
|
||||||
unsigned char uch;
|
unsigned char uch;
|
||||||
|
@ -1802,7 +1802,7 @@ long MainWindow::SSTCountBadBytes(const unsigned char* sctBuf, int count)
|
||||||
return badCount;
|
return badCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::SSTProcessTrackData(unsigned char* trackBuf)
|
void MainWindow::SSTProcessTrackData(uint8_t* trackBuf)
|
||||||
{
|
{
|
||||||
unsigned char* trackPtr;
|
unsigned char* trackPtr;
|
||||||
int track;
|
int track;
|
||||||
|
@ -1812,7 +1812,7 @@ void MainWindow::SSTProcessTrackData(unsigned char* trackBuf)
|
||||||
{
|
{
|
||||||
bool inRun;
|
bool inRun;
|
||||||
int start, longestStart;
|
int start, longestStart;
|
||||||
int count7f, longest = -1;
|
int count7f = 0, longest = -1;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
inRun = false;
|
inRun = false;
|
||||||
|
|
|
@ -99,7 +99,7 @@ void TwoImgPropsDialog::DoDataExchange(CDataExchange* pDX)
|
||||||
fpHeader->fFlags |= (dosVolNum & TwoImgHeader::kDOSVolumeMask);
|
fpHeader->fFlags |= (dosVolNum & TwoImgHeader::kDOSVolumeMask);
|
||||||
|
|
||||||
CString appStr, errMsg;
|
CString appStr, errMsg;
|
||||||
if (dosVolNum < 1 || dosVolNum > 254) {
|
if (dosVolNum < 0 || dosVolNum > 254) {
|
||||||
CheckedLoadString(&appStr, IDS_MB_APP_NAME);
|
CheckedLoadString(&appStr, IDS_MB_APP_NAME);
|
||||||
CheckedLoadString(&errMsg, IDS_VALID_VOLNAME_DOS);
|
CheckedLoadString(&errMsg, IDS_VALID_VOLNAME_DOS);
|
||||||
MessageBox(errMsg, appStr, MB_OK);
|
MessageBox(errMsg, appStr, MB_OK);
|
||||||
|
|
|
@ -17,7 +17,13 @@
|
||||||
class UseSelectionDialog : public CDialog {
|
class UseSelectionDialog : public CDialog {
|
||||||
public:
|
public:
|
||||||
UseSelectionDialog(int selCount, CWnd* pParentWnd = NULL, int rsrcID = IDD_USE_SELECTION) :
|
UseSelectionDialog(int selCount, CWnd* pParentWnd = NULL, int rsrcID = IDD_USE_SELECTION) :
|
||||||
CDialog(rsrcID, pParentWnd), fSelectedCount(selCount)
|
CDialog(rsrcID, pParentWnd),
|
||||||
|
fSelectedCount(selCount),
|
||||||
|
fTitleID(-1),
|
||||||
|
fOkLabelID(-1),
|
||||||
|
fSelCountID(-1),
|
||||||
|
fSelCountsID(-1),
|
||||||
|
fAllID(-1)
|
||||||
{
|
{
|
||||||
// init values; these should be overridden before DoModal
|
// init values; these should be overridden before DoModal
|
||||||
fFilesToAction = 0;
|
fFilesToAction = 0;
|
||||||
|
|
|
@ -154,8 +154,12 @@ void ViewFilesDialog::OnCancel(void)
|
||||||
|
|
||||||
void ViewFilesDialog::OnGetMinMaxInfo(MINMAXINFO* pMMI)
|
void ViewFilesDialog::OnGetMinMaxInfo(MINMAXINFO* pMMI)
|
||||||
{
|
{
|
||||||
pMMI->ptMinTrackSize.x = 664;
|
float scaleFactor = GetDesktopScaleFactor();
|
||||||
pMMI->ptMinTrackSize.y = 200;
|
|
||||||
|
// 664x200 was determined empirically to fit all controls. The initial
|
||||||
|
// window size is set over in the Preferences constructor.
|
||||||
|
pMMI->ptMinTrackSize.x = (int)(664 * scaleFactor);
|
||||||
|
pMMI->ptMinTrackSize.y = (int)(200 * scaleFactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViewFilesDialog::OnSize(UINT nType, int cx, int cy)
|
void ViewFilesDialog::OnSize(UINT nType, int cx, int cy)
|
||||||
|
@ -266,7 +270,22 @@ static void DumpBitmapInfo(HBITMAP hBitmap)
|
||||||
LOGD(" bmPits = 0x%p", info.bmBits);
|
LOGD(" bmPits = 0x%p", info.bmBits);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViewFilesDialog::DisplayText(const WCHAR* fileName)
|
bool ViewFilesDialog::IsSourceEmpty(const GenericEntry* pEntry,
|
||||||
|
ReformatHolder::ReformatPart part)
|
||||||
|
{
|
||||||
|
switch (part) {
|
||||||
|
case ReformatHolder::ReformatPart::kPartData:
|
||||||
|
return pEntry->GetDataForkLen() == 0;
|
||||||
|
case ReformatHolder::ReformatPart::kPartRsrc:
|
||||||
|
return pEntry->GetRsrcForkLen() == 0;
|
||||||
|
case ReformatHolder::ReformatPart::kPartCmmt:
|
||||||
|
return !pEntry->GetHasNonEmptyComment();
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewFilesDialog::DisplayText(const WCHAR* fileName, bool zeroSourceLen)
|
||||||
{
|
{
|
||||||
CWaitCursor wait; // streaming of big files can take a little while
|
CWaitCursor wait; // streaming of big files can take a little while
|
||||||
bool errFlg;
|
bool errFlg;
|
||||||
|
@ -404,10 +423,14 @@ void ViewFilesDialog::DisplayText(const WCHAR* fileName)
|
||||||
if (fpOutput->GetOutputKind() == ReformatOutput::kOutputRTF)
|
if (fpOutput->GetOutputKind() == ReformatOutput::kOutputRTF)
|
||||||
streamFormat = SF_RTF;
|
streamFormat = SF_RTF;
|
||||||
if (fpOutput->GetTextLen() == 0) {
|
if (fpOutput->GetTextLen() == 0) {
|
||||||
textBuf = "(file is empty)";
|
if (zeroSourceLen) {
|
||||||
|
textBuf = "(file is empty)";
|
||||||
|
EnableFormatSelection(FALSE);
|
||||||
|
} else {
|
||||||
|
textBuf = "(converted output is empty)";
|
||||||
|
}
|
||||||
textLen = strlen(textBuf);
|
textLen = strlen(textBuf);
|
||||||
emptyFlg = true;
|
emptyFlg = true;
|
||||||
EnableFormatSelection(FALSE);
|
|
||||||
}
|
}
|
||||||
if (fpOutput->GetOutputKind() == ReformatOutput::kOutputErrorMsg)
|
if (fpOutput->GetOutputKind() == ReformatOutput::kOutputErrorMsg)
|
||||||
EnableFormatSelection(FALSE);
|
EnableFormatSelection(FALSE);
|
||||||
|
@ -638,7 +661,8 @@ void ViewFilesDialog::OnFviewNext(void)
|
||||||
id = ConfigureFormatSel(part);
|
id = ConfigureFormatSel(part);
|
||||||
Reformat(pSelEntry->GetEntry(), part, id);
|
Reformat(pSelEntry->GetEntry(), part, id);
|
||||||
|
|
||||||
DisplayText(pSelEntry->GetEntry()->GetDisplayName());
|
DisplayText(pSelEntry->GetEntry()->GetDisplayName(),
|
||||||
|
IsSourceEmpty(pSelEntry->GetEntry(), part));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViewFilesDialog::OnFviewPrev(void)
|
void ViewFilesDialog::OnFviewPrev(void)
|
||||||
|
@ -681,7 +705,7 @@ void ViewFilesDialog::OnFviewPrev(void)
|
||||||
id = ConfigureFormatSel(part);
|
id = ConfigureFormatSel(part);
|
||||||
Reformat(pEntry, part, id);
|
Reformat(pEntry, part, id);
|
||||||
|
|
||||||
DisplayText(pEntry->GetDisplayName());
|
DisplayText(pEntry->GetDisplayName(), IsSourceEmpty(pEntry, part));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViewFilesDialog::ConfigurePartButtons(const GenericEntry* pEntry)
|
void ViewFilesDialog::ConfigurePartButtons(const GenericEntry* pEntry)
|
||||||
|
@ -936,7 +960,7 @@ void ViewFilesDialog::OnFormatSelChange(void)
|
||||||
id = (ReformatHolder::ReformatID) pCombo->GetItemData(pCombo->GetCurSel());
|
id = (ReformatHolder::ReformatID) pCombo->GetItemData(pCombo->GetCurSel());
|
||||||
Reformat(pEntry, part, id);
|
Reformat(pEntry, part, id);
|
||||||
|
|
||||||
DisplayText(pEntry->GetDisplayName());
|
DisplayText(pEntry->GetDisplayName(), IsSourceEmpty(pEntry, part));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViewFilesDialog::OnFviewData(void)
|
void ViewFilesDialog::OnFviewData(void)
|
||||||
|
@ -969,7 +993,7 @@ void ViewFilesDialog::ForkSelectCommon(ReformatHolder::ReformatPart part)
|
||||||
id = ConfigureFormatSel(part);
|
id = ConfigureFormatSel(part);
|
||||||
|
|
||||||
Reformat(pEntry, part, id);
|
Reformat(pEntry, part, id);
|
||||||
DisplayText(pEntry->GetDisplayName());
|
DisplayText(pEntry->GetDisplayName(), IsSourceEmpty(pEntry, part));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViewFilesDialog::OnFviewFmtBest(void)
|
void ViewFilesDialog::OnFviewFmtBest(void)
|
||||||
|
|
|
@ -120,15 +120,23 @@ private:
|
||||||
//void StretchControl(int id, int deltaX, int deltaY);
|
//void StretchControl(int id, int deltaX, int deltaY);
|
||||||
void NewFontSelected(bool resetBold);
|
void NewFontSelected(bool resetBold);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Determines whether the specified part is an empty fork/comment.
|
||||||
|
*/
|
||||||
|
bool IsSourceEmpty(const GenericEntry* pEntry,
|
||||||
|
ReformatHolder::ReformatPart part);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Display a buffer of text in the RichEdit control.
|
* Display a buffer of text in the RichEdit control.
|
||||||
*
|
*
|
||||||
* The RichEdit dialog will hold its own copy of the data, so "pHolder" can
|
* The RichEdit dialog will hold its own copy of the data, so "pHolder" can
|
||||||
* be safely destroyed after this returns.
|
* be safely destroyed after this returns.
|
||||||
*
|
*
|
||||||
* "fileName" is for display only.
|
* "fileName" is for display only. "zeroSourceLen" allows the function to
|
||||||
|
* tell the difference between an empty file and a non-empty file that
|
||||||
|
* generated empty output.
|
||||||
*/
|
*/
|
||||||
void DisplayText(const WCHAR* fileName);
|
void DisplayText(const WCHAR* fileName, bool zeroSourceLen);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set up the fpHolder. Does not reformat the data, just loads the source
|
* Set up the fpHolder. Does not reformat the data, just loads the source
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
<Configuration>Debug</Configuration>
|
<Configuration>Debug</Configuration>
|
||||||
|
@ -19,13 +19,13 @@
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<PlatformToolset>v120_xp</PlatformToolset>
|
|
||||||
<UseOfMfc>Dynamic</UseOfMfc>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<UseOfMfc>Dynamic</UseOfMfc>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<PlatformToolset>v120_xp</PlatformToolset>
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
<UseOfMfc>Dynamic</UseOfMfc>
|
<UseOfMfc>Dynamic</UseOfMfc>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
|
@ -93,6 +93,7 @@
|
||||||
#define IDC_PVIEW_DISASM_ONEBYTEBRKCOP 1028
|
#define IDC_PVIEW_DISASM_ONEBYTEBRKCOP 1028
|
||||||
#define IDC_PVIEW_HIRES_BW 1029
|
#define IDC_PVIEW_HIRES_BW 1029
|
||||||
#define IDC_PVIEW_DHR_CONV_COMBO 1030
|
#define IDC_PVIEW_DHR_CONV_COMBO 1030
|
||||||
|
#define IDC_PVIEW_MOUSETEXT_TO_ASCII 1031
|
||||||
#define IDC_PVIEW_HITEXT 1036
|
#define IDC_PVIEW_HITEXT 1036
|
||||||
#define IDC_PVIEW_PASCALTEXT 1037
|
#define IDC_PVIEW_PASCALTEXT 1037
|
||||||
#define IDC_PVIEW_APPLESOFT 1038
|
#define IDC_PVIEW_APPLESOFT 1038
|
||||||
|
@ -559,9 +560,9 @@
|
||||||
//
|
//
|
||||||
#ifdef APSTUDIO_INVOKED
|
#ifdef APSTUDIO_INVOKED
|
||||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||||
#define _APS_NEXT_RESOURCE_VALUE 193
|
#define _APS_NEXT_RESOURCE_VALUE 196
|
||||||
#define _APS_NEXT_COMMAND_VALUE 40102
|
#define _APS_NEXT_COMMAND_VALUE 40102
|
||||||
#define _APS_NEXT_CONTROL_VALUE 1454
|
#define _APS_NEXT_CONTROL_VALUE 1455
|
||||||
#define _APS_NEXT_SYMED_VALUE 102
|
#define _APS_NEXT_SYMED_VALUE 102
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -835,6 +835,9 @@ DIError DiskFSDOS33::ProcessCatalogSector(int catTrack, int catSect,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memcpy(pFile->fRawFileName, &pEntry[0x03], A2FileDOS::kMaxFileName);
|
||||||
|
pFile->fRawFileName[A2FileDOS::kMaxFileName] = '\0';
|
||||||
|
|
||||||
memcpy(pFile->fFileName, &pEntry[0x03], A2FileDOS::kMaxFileName);
|
memcpy(pFile->fFileName, &pEntry[0x03], A2FileDOS::kMaxFileName);
|
||||||
pFile->fFileName[A2FileDOS::kMaxFileName] = '\0';
|
pFile->fFileName[A2FileDOS::kMaxFileName] = '\0';
|
||||||
pFile->FixFilename();
|
pFile->FixFilename();
|
||||||
|
@ -860,7 +863,6 @@ DIError DiskFSDOS33::ProcessCatalogSector(int catTrack, int catSect,
|
||||||
return kDIErrNone;
|
return kDIErrNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Perform consistency checks on the filesystem.
|
* Perform consistency checks on the filesystem.
|
||||||
*
|
*
|
||||||
|
@ -2768,7 +2770,7 @@ DIError A2FileDOS::LoadTSList(TrackSector** pTSList, int* pTSCount,
|
||||||
if (dierr != kDIErrNone)
|
if (dierr != kDIErrNone)
|
||||||
goto bail;
|
goto bail;
|
||||||
|
|
||||||
if (track != 0 && sector != 0) {
|
if (track != 0) {
|
||||||
/* more T/S lists to come, so we keep all entries */
|
/* more T/S lists to come, so we keep all entries */
|
||||||
tsCount += kMaxTSPairs;
|
tsCount += kMaxTSPairs;
|
||||||
} else {
|
} else {
|
||||||
|
@ -2869,6 +2871,19 @@ bail:
|
||||||
return dierr;
|
return dierr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the raw filename.
|
||||||
|
*
|
||||||
|
* If a pointer to a size_t is passed in, it will be filled with the
|
||||||
|
* raw filename length.
|
||||||
|
*/
|
||||||
|
const char* A2FileDOS::GetRawFileName(size_t* size) const {
|
||||||
|
if (size) {
|
||||||
|
*size = strlen(fRawFileName);
|
||||||
|
}
|
||||||
|
return fRawFileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ===========================================================================
|
* ===========================================================================
|
||||||
|
|
|
@ -211,6 +211,10 @@ DiskImg::DiskImg(void)
|
||||||
fNumBlocks = -1;
|
fNumBlocks = -1;
|
||||||
|
|
||||||
fpScanProgressCallback = NULL;
|
fpScanProgressCallback = NULL;
|
||||||
|
fScanProgressCookie = NULL;
|
||||||
|
fScanCount = 0;
|
||||||
|
fScanMsg[0] = '\0';
|
||||||
|
fScanLastMsgWhen = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a working copy of the nibble descr table. We want to leave
|
* Create a working copy of the nibble descr table. We want to leave
|
||||||
|
@ -292,6 +296,12 @@ void DiskImg::SetCustomNibbleDescr(const NibbleDescr* pDescr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* A2File::GetRawFileName(size_t* size) const { // get unmodified file name
|
||||||
|
if (size) {
|
||||||
|
*size = strlen(GetFileName());
|
||||||
|
}
|
||||||
|
return GetFileName();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Open a volume or a file on disk.
|
* Open a volume or a file on disk.
|
||||||
|
@ -472,7 +482,7 @@ DIError DiskImg::OpenImage(DiskImg* pParent, long firstBlock, long numBlocks)
|
||||||
* already have an open file with specific characteristics.
|
* already have an open file with specific characteristics.
|
||||||
*/
|
*/
|
||||||
//fOffset = pParent->fOffset + kBlockSize * firstBlock;
|
//fOffset = pParent->fOffset + kBlockSize * firstBlock;
|
||||||
fLength = numBlocks * kBlockSize;
|
fLength = (di_off_t)numBlocks * kBlockSize;
|
||||||
fOuterLength = fWrappedLength = fLength;
|
fOuterLength = fWrappedLength = fLength;
|
||||||
fFileFormat = kFileFormatUnadorned;
|
fFileFormat = kFileFormatUnadorned;
|
||||||
fPhysical = pParent->fPhysical;
|
fPhysical = pParent->fPhysical;
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <sys/types.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
//#define EXCISE_GPL_CODE
|
//#define EXCISE_GPL_CODE
|
||||||
|
@ -45,7 +46,7 @@ namespace DiskImgLib {
|
||||||
/* compiled-against versions; call DiskImg::GetVersion for linked-against */
|
/* compiled-against versions; call DiskImg::GetVersion for linked-against */
|
||||||
#define kDiskImgVersionMajor 5
|
#define kDiskImgVersionMajor 5
|
||||||
#define kDiskImgVersionMinor 0
|
#define kDiskImgVersionMinor 0
|
||||||
#define kDiskImgVersionBug 0
|
#define kDiskImgVersionBug 1
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1471,8 +1472,11 @@ public:
|
||||||
* The filename returned is defined to be null-terminated Mac OS Roman.
|
* The filename returned is defined to be null-terminated Mac OS Roman.
|
||||||
* For most filesystems this is automatic, as filenames are restricted
|
* For most filesystems this is automatic, as filenames are restricted
|
||||||
* to ASCII, but for DOS 3.3 it requires stripping high bits. It also
|
* to ASCII, but for DOS 3.3 it requires stripping high bits. It also
|
||||||
* means that embedded nulls in HFS filenames (which are discouraged but
|
* means that embedded nulls will be lost.
|
||||||
* allowed) will be lost.
|
*
|
||||||
|
* The original unmodified filename is available through GetRawFileName,
|
||||||
|
* which can be optionally passed a size_t pointer to get the size
|
||||||
|
* of the raw file name, in case it has embedded nulls.
|
||||||
*
|
*
|
||||||
* We do guarantee that the contents of subdirectories are grouped
|
* We do guarantee that the contents of subdirectories are grouped
|
||||||
* together. This makes it much easier to construct a hierarchy out of
|
* together. This makes it much easier to construct a hierarchy out of
|
||||||
|
@ -1481,6 +1485,7 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual const char* GetFileName(void) const = 0; // name of this file
|
virtual const char* GetFileName(void) const = 0; // name of this file
|
||||||
virtual const char* GetPathName(void) const = 0; // full path
|
virtual const char* GetPathName(void) const = 0; // full path
|
||||||
|
virtual const char* GetRawFileName(size_t* size = NULL) const; // get unmodified file name
|
||||||
virtual char GetFssep(void) const = 0; // '\0' if none
|
virtual char GetFssep(void) const = 0; // '\0' if none
|
||||||
virtual uint32_t GetFileType(void) const = 0;
|
virtual uint32_t GetFileType(void) const = 0;
|
||||||
virtual uint32_t GetAuxType(void) const = 0;
|
virtual uint32_t GetAuxType(void) const = 0;
|
||||||
|
@ -1576,7 +1581,12 @@ private:
|
||||||
*/
|
*/
|
||||||
class DISKIMG_API A2FileDescr {
|
class DISKIMG_API A2FileDescr {
|
||||||
public:
|
public:
|
||||||
A2FileDescr(A2File* pFile) : fpFile(pFile), fProgressUpdateFunc(NULL) {}
|
A2FileDescr(A2File* pFile) :
|
||||||
|
fpFile(pFile),
|
||||||
|
fProgressUpdateFunc(NULL),
|
||||||
|
fProgressUpdateMax(0),
|
||||||
|
fProgressUpdateState(NULL)
|
||||||
|
{}
|
||||||
virtual ~A2FileDescr(void) { fpFile = NULL; /*paranoia*/ }
|
virtual ~A2FileDescr(void) { fpFile = NULL; /*paranoia*/ }
|
||||||
|
|
||||||
virtual DIError Read(void* buf, size_t len, size_t* pActual = NULL) = 0;
|
virtual DIError Read(void* buf, size_t len, size_t* pActual = NULL) = 0;
|
||||||
|
|
|
@ -630,7 +630,7 @@ private:
|
||||||
|
|
||||||
class WrapperFDI : public ImageWrapper {
|
class WrapperFDI : public ImageWrapper {
|
||||||
public:
|
public:
|
||||||
WrapperFDI(void) {}
|
WrapperFDI(void) : fHeaderBuf(), fImageTracks(0), fStorageName(NULL) {}
|
||||||
virtual ~WrapperFDI(void) {}
|
virtual ~WrapperFDI(void) {}
|
||||||
|
|
||||||
static DIError Test(GenericFD* pGFD, di_off_t wrappedLength);
|
static DIError Test(GenericFD* pGFD, di_off_t wrappedLength);
|
||||||
|
@ -1213,10 +1213,21 @@ class A2FileDOS;
|
||||||
*/
|
*/
|
||||||
class DISKIMG_API DiskFSDOS33 : public DiskFS {
|
class DISKIMG_API DiskFSDOS33 : public DiskFS {
|
||||||
public:
|
public:
|
||||||
DiskFSDOS33(void) : DiskFS() {
|
DiskFSDOS33(void) :
|
||||||
fVTOCLoaded = false;
|
DiskFS(),
|
||||||
fDiskIsGood = false;
|
fFirstCatTrack(0),
|
||||||
}
|
fFirstCatSector(0),
|
||||||
|
fVTOCVolumeNumber(0),
|
||||||
|
fVTOCNumTracks(0),
|
||||||
|
fVTOCNumSectors(0),
|
||||||
|
fDiskVolumeNum(0),
|
||||||
|
fDiskVolumeName(),
|
||||||
|
fDiskVolumeID(),
|
||||||
|
fVTOC(),
|
||||||
|
fVTOCLoaded(false),
|
||||||
|
fCatalogSectors(),
|
||||||
|
fDiskIsGood(false)
|
||||||
|
{}
|
||||||
virtual ~DiskFSDOS33(void) {}
|
virtual ~DiskFSDOS33(void) {}
|
||||||
|
|
||||||
static DIError TestFS(DiskImg* pImg, DiskImg::SectorOrder* pOrder,
|
static DIError TestFS(DiskImg* pImg, DiskImg::SectorOrder* pOrder,
|
||||||
|
@ -1259,7 +1270,7 @@ public:
|
||||||
|
|
||||||
// utility function
|
// utility function
|
||||||
static void LowerASCII(uint8_t* buf, long len);
|
static void LowerASCII(uint8_t* buf, long len);
|
||||||
static void ReplaceFssep(char* str, char replacement);
|
//static void ReplaceFssep(char* str, char replacement);
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
kMinTracks = 17, // need to put the catalog track here
|
kMinTracks = 17, // need to put the catalog track here
|
||||||
|
@ -1360,12 +1371,17 @@ private:
|
||||||
*/
|
*/
|
||||||
class DISKIMG_API A2FDDOS : public A2FileDescr {
|
class DISKIMG_API A2FDDOS : public A2FileDescr {
|
||||||
public:
|
public:
|
||||||
A2FDDOS(A2File* pFile) : A2FileDescr(pFile) {
|
A2FDDOS(A2File* pFile) :
|
||||||
fTSList = NULL;
|
A2FileDescr(pFile),
|
||||||
fIndexList = NULL;
|
fTSList(NULL),
|
||||||
fOffset = 0;
|
fTSCount(0),
|
||||||
fModified = false;
|
fIndexList(NULL),
|
||||||
}
|
fIndexCount(0),
|
||||||
|
fOffset(0),
|
||||||
|
fOpenEOF(0),
|
||||||
|
fOpenSectorsUsed(0),
|
||||||
|
fModified(false)
|
||||||
|
{}
|
||||||
virtual ~A2FDDOS(void) {
|
virtual ~A2FDDOS(void) {
|
||||||
delete[] fTSList;
|
delete[] fTSList;
|
||||||
delete[] fIndexList;
|
delete[] fIndexList;
|
||||||
|
@ -1444,6 +1460,7 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual const char* GetFileName(void) const override { return fFileName; }
|
virtual const char* GetFileName(void) const override { return fFileName; }
|
||||||
virtual const char* GetPathName(void) const override { return fFileName; }
|
virtual const char* GetPathName(void) const override { return fFileName; }
|
||||||
|
virtual const char* GetRawFileName(size_t* size = NULL) const override;
|
||||||
virtual char GetFssep(void) const override { return '\0'; }
|
virtual char GetFssep(void) const override { return '\0'; }
|
||||||
virtual uint32_t GetFileType(void) const override;
|
virtual uint32_t GetFileType(void) const override;
|
||||||
virtual uint32_t GetAuxType(void) const override { return fAuxType; }
|
virtual uint32_t GetAuxType(void) const override { return fAuxType; }
|
||||||
|
@ -1482,6 +1499,7 @@ private:
|
||||||
short fTSListSector;
|
short fTSListSector;
|
||||||
uint16_t fLengthInSectors;
|
uint16_t fLengthInSectors;
|
||||||
bool fLocked;
|
bool fLocked;
|
||||||
|
char fRawFileName[kMaxFileName + 1]; // "raw" version
|
||||||
char fFileName[kMaxFileName+1]; // "fixed" version
|
char fFileName[kMaxFileName+1]; // "fixed" version
|
||||||
FileType fFileType;
|
FileType fFileType;
|
||||||
|
|
||||||
|
@ -1536,8 +1554,19 @@ class A2FileProDOS;
|
||||||
*/
|
*/
|
||||||
class DISKIMG_API DiskFSProDOS : public DiskFS {
|
class DISKIMG_API DiskFSProDOS : public DiskFS {
|
||||||
public:
|
public:
|
||||||
DiskFSProDOS(void) : fBitMapPointer(0), fTotalBlocks(0), fBlockUseMap(NULL)
|
DiskFSProDOS(void) :
|
||||||
{}
|
fVolumeName(),
|
||||||
|
fVolumeID(),
|
||||||
|
fAccess(0),
|
||||||
|
fCreateWhen(0),
|
||||||
|
fModWhen(0),
|
||||||
|
fBitMapPointer(0),
|
||||||
|
fTotalBlocks(0),
|
||||||
|
fVolDirFileCount(0),
|
||||||
|
fBlockUseMap(NULL),
|
||||||
|
fDiskIsGood(false),
|
||||||
|
fEarlyDamage(false)
|
||||||
|
{}
|
||||||
virtual ~DiskFSProDOS(void) {
|
virtual ~DiskFSProDOS(void) {
|
||||||
if (fBlockUseMap != NULL) {
|
if (fBlockUseMap != NULL) {
|
||||||
assert(false); // unexpected
|
assert(false); // unexpected
|
||||||
|
@ -1596,6 +1625,7 @@ private:
|
||||||
|
|
||||||
DIError Initialize(InitMode initMode);
|
DIError Initialize(InitMode initMode);
|
||||||
DIError LoadVolHeader(void);
|
DIError LoadVolHeader(void);
|
||||||
|
DIError DetermineVolDirLen(uint16_t nextBlock, uint16_t* pBlocksUsed);
|
||||||
void SetVolumeID(void);
|
void SetVolumeID(void);
|
||||||
void DumpVolHeader(void);
|
void DumpVolHeader(void);
|
||||||
DIError ScanVolBitmap(void);
|
DIError ScanVolBitmap(void);
|
||||||
|
@ -1697,8 +1727,16 @@ private:
|
||||||
*/
|
*/
|
||||||
class DISKIMG_API A2FDProDOS : public A2FileDescr {
|
class DISKIMG_API A2FDProDOS : public A2FileDescr {
|
||||||
public:
|
public:
|
||||||
A2FDProDOS(A2File* pFile) : A2FileDescr(pFile), fModified(false),
|
A2FDProDOS(A2File* pFile) :
|
||||||
fBlockList(NULL), fOffset(0)
|
A2FileDescr(pFile),
|
||||||
|
fModified(false),
|
||||||
|
fBlockCount(0),
|
||||||
|
fBlockList(NULL),
|
||||||
|
fOpenEOF(0),
|
||||||
|
fOpenBlocksUsed(0),
|
||||||
|
fOpenStorageType(0),
|
||||||
|
fOpenRsrcFork(false),
|
||||||
|
fOffset(0)
|
||||||
{}
|
{}
|
||||||
virtual ~A2FDProDOS(void) {
|
virtual ~A2FDProDOS(void) {
|
||||||
delete[] fBlockList;
|
delete[] fBlockList;
|
||||||
|
@ -1742,14 +1780,16 @@ private:
|
||||||
*/
|
*/
|
||||||
class DISKIMG_API A2FileProDOS : public A2File {
|
class DISKIMG_API A2FileProDOS : public A2File {
|
||||||
public:
|
public:
|
||||||
A2FileProDOS(DiskFS* pDiskFS) : A2File(pDiskFS) {
|
A2FileProDOS(DiskFS* pDiskFS) :
|
||||||
fPathName = NULL;
|
A2File(pDiskFS),
|
||||||
fSparseDataEof = fSparseRsrcEof = -1;
|
fParentDirBlock(0),
|
||||||
fpOpenFile = NULL;
|
fParentDirIdx(0),
|
||||||
fParentDirBlock = 0;
|
fSparseDataEof(0),
|
||||||
fParentDirIdx = -1;
|
fSparseRsrcEof(0),
|
||||||
fpParent = NULL;
|
fPathName(NULL),
|
||||||
}
|
fpOpenFile(NULL),
|
||||||
|
fpParent(NULL)
|
||||||
|
{}
|
||||||
virtual ~A2FileProDOS(void) {
|
virtual ~A2FileProDOS(void) {
|
||||||
delete fpOpenFile;
|
delete fpOpenFile;
|
||||||
delete[] fPathName;
|
delete[] fPathName;
|
||||||
|
@ -1949,7 +1989,21 @@ class A2FilePascal;
|
||||||
|
|
||||||
class DISKIMG_API DiskFSPascal : public DiskFS {
|
class DISKIMG_API DiskFSPascal : public DiskFS {
|
||||||
public:
|
public:
|
||||||
DiskFSPascal(void) : fDirectory(NULL) {}
|
DiskFSPascal(void) :
|
||||||
|
fStartBlock(0),
|
||||||
|
fNextBlock(0),
|
||||||
|
fVolumeName(),
|
||||||
|
fVolumeID(),
|
||||||
|
fTotalBlocks(0),
|
||||||
|
fNumFiles(0),
|
||||||
|
fAccessWhen(0),
|
||||||
|
fDateSetWhen(0),
|
||||||
|
fStuff1(0),
|
||||||
|
fStuff2(0),
|
||||||
|
fDiskIsGood(false),
|
||||||
|
fEarlyDamage(false),
|
||||||
|
fDirectory(NULL)
|
||||||
|
{}
|
||||||
virtual ~DiskFSPascal(void) {
|
virtual ~DiskFSPascal(void) {
|
||||||
if (fDirectory != NULL) {
|
if (fDirectory != NULL) {
|
||||||
assert(false); // unexpected
|
assert(false); // unexpected
|
||||||
|
@ -2051,9 +2105,13 @@ private:
|
||||||
*/
|
*/
|
||||||
class DISKIMG_API A2FDPascal : public A2FileDescr {
|
class DISKIMG_API A2FDPascal : public A2FileDescr {
|
||||||
public:
|
public:
|
||||||
A2FDPascal(A2File* pFile) : A2FileDescr(pFile) {
|
A2FDPascal(A2File* pFile) :
|
||||||
fOffset = 0;
|
A2FileDescr(pFile),
|
||||||
}
|
fOffset(0),
|
||||||
|
fOpenEOF(0),
|
||||||
|
fOpenBlocksUsed(0),
|
||||||
|
fModified(0)
|
||||||
|
{}
|
||||||
virtual ~A2FDPascal(void) {
|
virtual ~A2FDPascal(void) {
|
||||||
/* nothing to clean up */
|
/* nothing to clean up */
|
||||||
}
|
}
|
||||||
|
@ -2085,9 +2143,17 @@ private:
|
||||||
*/
|
*/
|
||||||
class DISKIMG_API A2FilePascal : public A2File {
|
class DISKIMG_API A2FilePascal : public A2File {
|
||||||
public:
|
public:
|
||||||
A2FilePascal(DiskFS* pDiskFS) : A2File(pDiskFS) {
|
A2FilePascal(DiskFS* pDiskFS) :
|
||||||
fpOpenFile = NULL;
|
A2File(pDiskFS),
|
||||||
}
|
fStartBlock(0),
|
||||||
|
fNextBlock(0),
|
||||||
|
fFileType(A2FilePascal::FileType::kTypeUntyped),
|
||||||
|
fFileName(),
|
||||||
|
fBytesRemaining(0),
|
||||||
|
fModWhen(0),
|
||||||
|
fLength(0),
|
||||||
|
fpOpenFile(NULL)
|
||||||
|
{}
|
||||||
virtual ~A2FilePascal(void) {
|
virtual ~A2FilePascal(void) {
|
||||||
/* this comes back and calls CloseDescr */
|
/* this comes back and calls CloseDescr */
|
||||||
if (fpOpenFile != NULL)
|
if (fpOpenFile != NULL)
|
||||||
|
@ -2185,7 +2251,7 @@ private:
|
||||||
class A2FileCPM;
|
class A2FileCPM;
|
||||||
class DISKIMG_API DiskFSCPM : public DiskFS {
|
class DISKIMG_API DiskFSCPM : public DiskFS {
|
||||||
public:
|
public:
|
||||||
DiskFSCPM(void) : fDiskIsGood(false) {}
|
DiskFSCPM(void) : fDirEntry(), fDiskIsGood(false) {}
|
||||||
virtual ~DiskFSCPM(void) {}
|
virtual ~DiskFSCPM(void) {}
|
||||||
|
|
||||||
static DIError TestFS(DiskImg* pImg, DiskImg::SectorOrder* pOrder,
|
static DIError TestFS(DiskImg* pImg, DiskImg::SectorOrder* pOrder,
|
||||||
|
@ -2269,10 +2335,12 @@ private:
|
||||||
*/
|
*/
|
||||||
class DISKIMG_API A2FDCPM : public A2FileDescr {
|
class DISKIMG_API A2FDCPM : public A2FileDescr {
|
||||||
public:
|
public:
|
||||||
A2FDCPM(A2File* pFile) : A2FileDescr(pFile) {
|
A2FDCPM(A2File* pFile) :
|
||||||
//fOpen = false;
|
A2FileDescr(pFile),
|
||||||
fBlockList = NULL;
|
fOffset(0),
|
||||||
}
|
fBlockCount(0),
|
||||||
|
fBlockList(NULL)
|
||||||
|
{}
|
||||||
virtual ~A2FDCPM(void) {
|
virtual ~A2FDCPM(void) {
|
||||||
delete fBlockList;
|
delete fBlockList;
|
||||||
fBlockList = NULL;
|
fBlockList = NULL;
|
||||||
|
@ -2308,7 +2376,13 @@ public:
|
||||||
typedef DiskFSCPM::DirEntry DirEntry;
|
typedef DiskFSCPM::DirEntry DirEntry;
|
||||||
|
|
||||||
A2FileCPM(DiskFS* pDiskFS, DirEntry* pDirEntry) :
|
A2FileCPM(DiskFS* pDiskFS, DirEntry* pDirEntry) :
|
||||||
A2File(pDiskFS), fpDirEntry(pDirEntry)
|
A2File(pDiskFS),
|
||||||
|
fFileName(),
|
||||||
|
fReadOnly(false),
|
||||||
|
fLength(0),
|
||||||
|
fDirIdx(0),
|
||||||
|
fpDirEntry(pDirEntry),
|
||||||
|
fpOpenFile(NULL)
|
||||||
{
|
{
|
||||||
fDirIdx = -1;
|
fDirIdx = -1;
|
||||||
fpOpenFile = NULL;
|
fpOpenFile = NULL;
|
||||||
|
@ -2389,7 +2463,7 @@ private:
|
||||||
class A2FileRDOS;
|
class A2FileRDOS;
|
||||||
class DISKIMG_API DiskFSRDOS : public DiskFS {
|
class DISKIMG_API DiskFSRDOS : public DiskFS {
|
||||||
public:
|
public:
|
||||||
DiskFSRDOS(void) {}
|
DiskFSRDOS(void) : fVolumeName(), fOurSectPerTrack(0) {}
|
||||||
virtual ~DiskFSRDOS(void) {}
|
virtual ~DiskFSRDOS(void) {}
|
||||||
|
|
||||||
static DIError TestFS(DiskImg* pImg, DiskImg::SectorOrder* pOrder,
|
static DIError TestFS(DiskImg* pImg, DiskImg::SectorOrder* pOrder,
|
||||||
|
@ -2468,10 +2542,17 @@ private:
|
||||||
*/
|
*/
|
||||||
class DISKIMG_API A2FileRDOS : public A2File {
|
class DISKIMG_API A2FileRDOS : public A2File {
|
||||||
public:
|
public:
|
||||||
A2FileRDOS(DiskFS* pDiskFS) : A2File(pDiskFS) {
|
A2FileRDOS(DiskFS* pDiskFS) :
|
||||||
//fOpen = false;
|
A2File(pDiskFS),
|
||||||
fpOpenFile = NULL;
|
fFileName(),
|
||||||
}
|
fRawFileName(),
|
||||||
|
fFileType(A2FileRDOS::FileType::kTypeUnknown),
|
||||||
|
fNumSectors(0),
|
||||||
|
fLoadAddr(0),
|
||||||
|
fLength(0),
|
||||||
|
fStartSector(0),
|
||||||
|
fpOpenFile(NULL)
|
||||||
|
{}
|
||||||
virtual ~A2FileRDOS(void) {
|
virtual ~A2FileRDOS(void) {
|
||||||
delete fpOpenFile;
|
delete fpOpenFile;
|
||||||
}
|
}
|
||||||
|
@ -2492,6 +2573,7 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual const char* GetFileName(void) const override { return fFileName; }
|
virtual const char* GetFileName(void) const override { return fFileName; }
|
||||||
virtual const char* GetPathName(void) const override { return fFileName; }
|
virtual const char* GetPathName(void) const override { return fFileName; }
|
||||||
|
virtual const char* GetRawFileName(size_t* size = NULL) const override;
|
||||||
virtual char GetFssep(void) const override { return '\0'; }
|
virtual char GetFssep(void) const override { return '\0'; }
|
||||||
virtual uint32_t GetFileType(void) const override;
|
virtual uint32_t GetFileType(void) const override;
|
||||||
virtual uint32_t GetAuxType(void) const override { return fLoadAddr; }
|
virtual uint32_t GetAuxType(void) const override { return fLoadAddr; }
|
||||||
|
@ -2517,6 +2599,7 @@ public:
|
||||||
|
|
||||||
/* fields pulled out of directory block */
|
/* fields pulled out of directory block */
|
||||||
char fFileName[kMaxFileName+1];
|
char fFileName[kMaxFileName+1];
|
||||||
|
char fRawFileName[kMaxFileName + 1];
|
||||||
FileType fFileType;
|
FileType fFileType;
|
||||||
uint16_t fNumSectors;
|
uint16_t fNumSectors;
|
||||||
uint16_t fLoadAddr;
|
uint16_t fLoadAddr;
|
||||||
|
@ -2542,9 +2625,19 @@ private:
|
||||||
class A2FileHFS;
|
class A2FileHFS;
|
||||||
class DISKIMG_API DiskFSHFS : public DiskFS {
|
class DISKIMG_API DiskFSHFS : public DiskFS {
|
||||||
public:
|
public:
|
||||||
DiskFSHFS(void) {
|
DiskFSHFS(void) :
|
||||||
fLocalTimeOffset = -1;
|
fVolumeName(),
|
||||||
fDiskIsGood = true;
|
fVolumeID(),
|
||||||
|
fTotalBlocks(0),
|
||||||
|
fAllocationBlockSize(0),
|
||||||
|
fNumAllocationBlocks(0),
|
||||||
|
fCreatedDateTime(0),
|
||||||
|
fModifiedDateTime(0),
|
||||||
|
fNumFiles(0),
|
||||||
|
fNumDirectories(0),
|
||||||
|
fLocalTimeOffset(-1),
|
||||||
|
fDiskIsGood(true)
|
||||||
|
{
|
||||||
#ifndef EXCISE_GPL_CODE
|
#ifndef EXCISE_GPL_CODE
|
||||||
fHfsVol = NULL;
|
fHfsVol = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
@ -2717,12 +2810,25 @@ private:
|
||||||
*/
|
*/
|
||||||
class DISKIMG_API A2FileHFS : public A2File {
|
class DISKIMG_API A2FileHFS : public A2File {
|
||||||
public:
|
public:
|
||||||
A2FileHFS(DiskFS* pDiskFS) : A2File(pDiskFS) {
|
A2FileHFS(DiskFS* pDiskFS) :
|
||||||
fPathName = NULL;
|
A2File(pDiskFS),
|
||||||
fpOpenFile = NULL;
|
fIsDir(false),
|
||||||
|
fIsVolumeDir(false),
|
||||||
|
fType(0),
|
||||||
|
fCreator(0),
|
||||||
|
fFileName(),
|
||||||
|
fPathName(NULL),
|
||||||
|
fDataLength(0),
|
||||||
|
fRsrcLength(0),
|
||||||
|
fCreateWhen(0),
|
||||||
|
fModWhen(0),
|
||||||
|
fAccess(0),
|
||||||
|
fpOpenFile(NULL)
|
||||||
|
{
|
||||||
#ifdef EXCISE_GPL_CODE
|
#ifdef EXCISE_GPL_CODE
|
||||||
fFakeFileBuf = NULL;
|
fFakeFileBuf = NULL;
|
||||||
#else
|
#else
|
||||||
|
fpParent = NULL;
|
||||||
//fOrigPathName = NULL;
|
//fOrigPathName = NULL;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -2828,10 +2934,19 @@ class A2FileGutenberg;
|
||||||
*/
|
*/
|
||||||
class DISKIMG_API DiskFSGutenberg : public DiskFS {
|
class DISKIMG_API DiskFSGutenberg : public DiskFS {
|
||||||
public:
|
public:
|
||||||
DiskFSGutenberg(void) : DiskFS() {
|
DiskFSGutenberg(void) : DiskFS(),
|
||||||
fVTOCLoaded = false;
|
fFirstCatTrack(0),
|
||||||
fDiskIsGood = false;
|
fFirstCatSector(0),
|
||||||
}
|
fVTOCVolumeNumber(0),
|
||||||
|
fVTOCNumTracks(0),
|
||||||
|
fVTOCNumSectors(0),
|
||||||
|
fDiskVolumeName(),
|
||||||
|
fDiskVolumeID(),
|
||||||
|
fVTOC(),
|
||||||
|
fVTOCLoaded(false),
|
||||||
|
fCatalogSectors(),
|
||||||
|
fDiskIsGood(false)
|
||||||
|
{}
|
||||||
virtual ~DiskFSGutenberg(void) {}
|
virtual ~DiskFSGutenberg(void) {}
|
||||||
|
|
||||||
static DIError TestFS(DiskImg* pImg, DiskImg::SectorOrder* pOrder,
|
static DIError TestFS(DiskImg* pImg, DiskImg::SectorOrder* pOrder,
|
||||||
|
@ -2852,12 +2967,12 @@ public:
|
||||||
virtual DIError GetFreeSpaceCount(long* pTotalUnits, long* pFreeUnits,
|
virtual DIError GetFreeSpaceCount(long* pTotalUnits, long* pFreeUnits,
|
||||||
int* pUnitSize) const override;
|
int* pUnitSize) const override;
|
||||||
|
|
||||||
static bool IsValidFileName(const char* name);
|
//static bool IsValidFileName(const char* name);
|
||||||
static bool IsValidVolumeName(const char* name);
|
//static bool IsValidVolumeName(const char* name);
|
||||||
|
|
||||||
// utility function
|
// utility function
|
||||||
static void LowerASCII(uint8_t* buf, long len);
|
static void LowerASCII(uint8_t* buf, long len);
|
||||||
static void ReplaceFssep(char* str, char replacement);
|
//static void ReplaceFssep(char* str, char replacement);
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
kMinTracks = 17, // need to put the catalog track here
|
kMinTracks = 17, // need to put the catalog track here
|
||||||
|
@ -2875,43 +2990,13 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DIError Initialize(InitMode initMode);
|
DIError Initialize(InitMode initMode);
|
||||||
DIError ReadVTOC(void);
|
|
||||||
void UpdateVolumeNum(void);
|
|
||||||
void DumpVTOC(void);
|
|
||||||
void SetSectorUsage(long track, long sector,
|
|
||||||
VolumeUsage::ChunkPurpose purpose);
|
|
||||||
void FixVolumeUsageMap(void);
|
|
||||||
DIError ReadCatalog(void);
|
DIError ReadCatalog(void);
|
||||||
DIError ProcessCatalogSector(int catTrack, int catSect,
|
DIError ProcessCatalogSector(int catTrack, int catSect,
|
||||||
const uint8_t* sctBuf);
|
const uint8_t* sctBuf);
|
||||||
DIError GetFileLengths(void);
|
DIError GetFileLengths(void);
|
||||||
DIError ComputeLength(A2FileGutenberg* pFile, const TrackSector* tsList,
|
|
||||||
int tsCount);
|
|
||||||
DIError TrimLastSectorUp(A2FileGutenberg* pFile, TrackSector lastTS);
|
|
||||||
void MarkFileUsage(A2FileGutenberg* pFile, TrackSector* tsList, int tsCount,
|
|
||||||
TrackSector* indexList, int indexCount);
|
|
||||||
DIError MakeFileNameUnique(char* fileName);
|
|
||||||
DIError GetFreeCatalogEntry(TrackSector* pCatSect, int* pCatEntry,
|
|
||||||
uint8_t* sctBuf, A2FileGutenberg** ppPrevEntry);
|
|
||||||
void CreateDirEntry(uint8_t* sctBuf, int catEntry,
|
|
||||||
const char* fileName, TrackSector* pTSSect, uint8_t fileType,
|
|
||||||
int access);
|
|
||||||
void FreeTrackSectors(TrackSector* pList, int count);
|
|
||||||
|
|
||||||
bool CheckDiskIsGood(void);
|
bool CheckDiskIsGood(void);
|
||||||
|
|
||||||
DIError WriteDOSTracks(int sectPerTrack);
|
|
||||||
|
|
||||||
DIError ScanVolBitmap(void);
|
|
||||||
DIError LoadVolBitmap(void);
|
|
||||||
DIError SaveVolBitmap(void);
|
|
||||||
void FreeVolBitmap(void);
|
|
||||||
DIError AllocSector(TrackSector* pTS);
|
|
||||||
DIError CreateEmptyBlockMap(bool withDOS);
|
|
||||||
bool GetSectorUseEntry(long track, int sector) const;
|
|
||||||
void SetSectorUseEntry(long track, int sector, bool inUse);
|
|
||||||
inline uint32_t GetVTOCEntry(const uint8_t* pVTOC, long track) const;
|
|
||||||
|
|
||||||
// Largest interesting volume is 400K (50 tracks, 32 sectors), but
|
// Largest interesting volume is 400K (50 tracks, 32 sectors), but
|
||||||
// we may be looking at it in 16-sector mode, so max tracks is 100.
|
// we may be looking at it in 16-sector mode, so max tracks is 100.
|
||||||
enum {
|
enum {
|
||||||
|
@ -2931,7 +3016,7 @@ private:
|
||||||
/* private data */
|
/* private data */
|
||||||
char fDiskVolumeName[10]; //
|
char fDiskVolumeName[10]; //
|
||||||
char fDiskVolumeID[11+12+1]; // sizeof "Gutenberg: " + 12 + null
|
char fDiskVolumeID[11+12+1]; // sizeof "Gutenberg: " + 12 + null
|
||||||
uint8_t fVTOC[kSectorSize];
|
uint8_t fVTOC[kSectorSize];
|
||||||
bool fVTOCLoaded;
|
bool fVTOCLoaded;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2950,12 +3035,15 @@ private:
|
||||||
*/
|
*/
|
||||||
class DISKIMG_API A2FDGutenberg : public A2FileDescr {
|
class DISKIMG_API A2FDGutenberg : public A2FileDescr {
|
||||||
public:
|
public:
|
||||||
A2FDGutenberg(A2File* pFile) : A2FileDescr(pFile) {
|
A2FDGutenberg(A2File* pFile) :
|
||||||
fOffset = 0;
|
A2FileDescr(pFile),
|
||||||
fModified = false;
|
fTSCount(0),
|
||||||
}
|
fOffset(0),
|
||||||
virtual ~A2FDGutenberg(void) {
|
fOpenEOF(0),
|
||||||
}
|
fOpenSectorsUsed(0),
|
||||||
|
fModified(false)
|
||||||
|
{}
|
||||||
|
virtual ~A2FDGutenberg(void) {}
|
||||||
|
|
||||||
friend class A2FileGutenberg;
|
friend class A2FileGutenberg;
|
||||||
|
|
||||||
|
@ -3055,16 +3143,11 @@ public:
|
||||||
|
|
||||||
void FixFilename(void);
|
void FixFilename(void);
|
||||||
|
|
||||||
static FileType ConvertFileType(long prodosType, di_off_t fileLen);
|
|
||||||
static bool IsValidType(long prodosType);
|
|
||||||
static void MakeDOSName(char* buf, const char* name);
|
static void MakeDOSName(char* buf, const char* name);
|
||||||
static void TrimTrailingSpaces(char* filename);
|
static void TrimTrailingSpaces(char* filename);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DIError ExtractTSPairs(const uint8_t* sctBuf, TrackSector* tsList,
|
A2FDGutenberg* fpOpenFile;
|
||||||
int* pLastNonZero);
|
|
||||||
|
|
||||||
A2FDGutenberg* fpOpenFile;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -3083,7 +3166,11 @@ private:
|
||||||
class A2FileFAT;
|
class A2FileFAT;
|
||||||
class DISKIMG_API DiskFSFAT : public DiskFS {
|
class DISKIMG_API DiskFSFAT : public DiskFS {
|
||||||
public:
|
public:
|
||||||
DiskFSFAT(void) {}
|
DiskFSFAT(void) :
|
||||||
|
fVolumeName(),
|
||||||
|
fVolumeID(),
|
||||||
|
fTotalBlocks(0)
|
||||||
|
{}
|
||||||
virtual ~DiskFSFAT(void) {}
|
virtual ~DiskFSFAT(void) {}
|
||||||
|
|
||||||
static DIError TestFS(DiskImg* pImg, DiskImg::SectorOrder* pOrder,
|
static DIError TestFS(DiskImg* pImg, DiskImg::SectorOrder* pOrder,
|
||||||
|
@ -3168,11 +3255,13 @@ private:
|
||||||
*/
|
*/
|
||||||
class DISKIMG_API A2FileFAT : public A2File {
|
class DISKIMG_API A2FileFAT : public A2File {
|
||||||
public:
|
public:
|
||||||
A2FileFAT(DiskFS* pDiskFS) : A2File(pDiskFS) {
|
A2FileFAT(DiskFS* pDiskFS) :
|
||||||
fFakeFileBuf = NULL;
|
A2File(pDiskFS),
|
||||||
//fFakeFileLen = -1;
|
fFileName(),
|
||||||
fpOpenFile = NULL;
|
fLength(0),
|
||||||
}
|
fFakeFileBuf(NULL),
|
||||||
|
fpOpenFile(NULL)
|
||||||
|
{}
|
||||||
virtual ~A2FileFAT(void) {
|
virtual ~A2FileFAT(void) {
|
||||||
delete fpOpenFile;
|
delete fpOpenFile;
|
||||||
delete[] fFakeFileBuf;
|
delete[] fFakeFileBuf;
|
||||||
|
|
|
@ -337,6 +337,7 @@ void DiskFSFAT::CreateFakeFile(void)
|
||||||
fVolumeName,
|
fVolumeName,
|
||||||
capacity,
|
capacity,
|
||||||
(double) capacity / 2048.0);
|
(double) capacity / 2048.0);
|
||||||
|
buf[sizeof(buf) - 1] = '\0';
|
||||||
|
|
||||||
pFile = new A2FileFAT(this);
|
pFile = new A2FileFAT(this);
|
||||||
pFile->SetFakeFile(buf, strlen(buf));
|
pFile->SetFakeFile(buf, strlen(buf));
|
||||||
|
|
|
@ -175,8 +175,12 @@ private:
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
class GFDWinVolume : public GenericFD {
|
class GFDWinVolume : public GenericFD {
|
||||||
public:
|
public:
|
||||||
GFDWinVolume(void) : fPathName(NULL), fCurrentOffset(0), fVolumeEOF(-1)
|
GFDWinVolume(void) :
|
||||||
{}
|
fPathName(NULL),
|
||||||
|
fCurrentOffset(0),
|
||||||
|
fVolumeEOF(-1),
|
||||||
|
fBlockSize(0)
|
||||||
|
{}
|
||||||
virtual ~GFDWinVolume(void) { delete[] fPathName; }
|
virtual ~GFDWinVolume(void) { delete[] fPathName; }
|
||||||
|
|
||||||
virtual DIError Open(const char* deviceName, bool readOnly);
|
virtual DIError Open(const char* deviceName, bool readOnly);
|
||||||
|
@ -203,7 +207,14 @@ private:
|
||||||
|
|
||||||
class GFDBuffer : public GenericFD {
|
class GFDBuffer : public GenericFD {
|
||||||
public:
|
public:
|
||||||
GFDBuffer(void) : fBuffer(NULL) {}
|
GFDBuffer(void) :
|
||||||
|
fBuffer(NULL),
|
||||||
|
fLength(0),
|
||||||
|
fAllocLength(0),
|
||||||
|
fDoDelete(false),
|
||||||
|
fDoExpand(false),
|
||||||
|
fCurrentOffset(0)
|
||||||
|
{}
|
||||||
virtual ~GFDBuffer(void) { Close(); }
|
virtual ~GFDBuffer(void) { Close(); }
|
||||||
|
|
||||||
// If "doDelete" is set, the buffer will be freed with delete[] when
|
// If "doDelete" is set, the buffer will be freed with delete[] when
|
||||||
|
|
|
@ -1145,7 +1145,7 @@ DIError WrapperDiskCopy42::WriteHeader(GenericFD* pGFD, const DC42Header* pHeade
|
||||||
* magic string. To be safe, we only increment it if it starts with '-'.
|
* magic string. To be safe, we only increment it if it starts with '-'.
|
||||||
* (Need access to a Macintosh to test this.)
|
* (Need access to a Macintosh to test this.)
|
||||||
*/
|
*/
|
||||||
hdrBuf[0] = strlen(pHeader->diskName);
|
hdrBuf[0] = (uint8_t) (strlen(pHeader->diskName) & 0xff);
|
||||||
if (pHeader->diskName[0] == '-' && hdrBuf[0] < (kDC42NameLen-1))
|
if (pHeader->diskName[0] == '-' && hdrBuf[0] < (kDC42NameLen-1))
|
||||||
hdrBuf[0]++;
|
hdrBuf[0]++;
|
||||||
memcpy(&hdrBuf[1], pHeader->diskName, hdrBuf[0]);
|
memcpy(&hdrBuf[1], pHeader->diskName, hdrBuf[0]);
|
||||||
|
|
|
@ -1220,7 +1220,7 @@ void OuterZip::LocalFileHeader::SetFileName(const char* name)
|
||||||
fFileNameLength = 0;
|
fFileNameLength = 0;
|
||||||
|
|
||||||
if (name != NULL) {
|
if (name != NULL) {
|
||||||
fFileNameLength = strlen(name);
|
fFileNameLength = (uint16_t)strlen(name);
|
||||||
fFileName = new uint8_t[fFileNameLength+1];
|
fFileName = new uint8_t[fFileNameLength+1];
|
||||||
if (fFileName == NULL) {
|
if (fFileName == NULL) {
|
||||||
LOGW("Malloc failure in SetFileName %u", fFileNameLength);
|
LOGW("Malloc failure in SetFileName %u", fFileNameLength);
|
||||||
|
@ -1388,7 +1388,7 @@ void OuterZip::CentralDirEntry::SetFileName(const char* name)
|
||||||
fFileNameLength = 0;
|
fFileNameLength = 0;
|
||||||
|
|
||||||
if (name != NULL) {
|
if (name != NULL) {
|
||||||
fFileNameLength = strlen(name);
|
fFileNameLength = (uint16_t)strlen(name);
|
||||||
fFileName = new uint8_t[fFileNameLength+1];
|
fFileName = new uint8_t[fFileNameLength+1];
|
||||||
if (fFileName == NULL) {
|
if (fFileName == NULL) {
|
||||||
LOGI("Malloc failure in SetFileName %u", fFileNameLength);
|
LOGI("Malloc failure in SetFileName %u", fFileNameLength);
|
||||||
|
|
|
@ -535,7 +535,7 @@ DIError DiskFSPascal::Format(DiskImg* pDiskImg, const char* volName)
|
||||||
PutShortLE(&blkBuf[0x00], 0); // start block
|
PutShortLE(&blkBuf[0x00], 0); // start block
|
||||||
PutShortLE(&blkBuf[0x02], 6); // next block
|
PutShortLE(&blkBuf[0x02], 6); // next block
|
||||||
PutShortLE(&blkBuf[0x04], 0); // "file" type
|
PutShortLE(&blkBuf[0x04], 0); // "file" type
|
||||||
blkBuf[0x06] = strlen(volName);
|
blkBuf[0x06] = (uint8_t)strlen(volName);
|
||||||
memcpy(&blkBuf[0x07], volName, strlen(volName));
|
memcpy(&blkBuf[0x07], volName, strlen(volName));
|
||||||
PutShortLE(&blkBuf[0x0e], (uint16_t) pDiskImg->GetNumBlocks());
|
PutShortLE(&blkBuf[0x0e], (uint16_t) pDiskImg->GetNumBlocks());
|
||||||
PutShortLE(&blkBuf[0x10], 0); // num files
|
PutShortLE(&blkBuf[0x10], 0); // num files
|
||||||
|
@ -1255,7 +1255,7 @@ DIError DiskFSPascal::RenameFile(A2File* pGenericFile, const char* newName)
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
|
||||||
pEntry[0x06] = strlen(normalName);
|
pEntry[0x06] = (uint8_t)strlen(normalName);
|
||||||
memcpy(&pEntry[0x07], normalName, A2FilePascal::kMaxFileName);
|
memcpy(&pEntry[0x07], normalName, A2FilePascal::kMaxFileName);
|
||||||
strcpy(pFile->fFileName, normalName);
|
strcpy(pFile->fFileName, normalName);
|
||||||
|
|
||||||
|
@ -1339,7 +1339,7 @@ DIError DiskFSPascal::RenameVolume(const char* newName)
|
||||||
if (dierr != kDIErrNone)
|
if (dierr != kDIErrNone)
|
||||||
goto bail;
|
goto bail;
|
||||||
|
|
||||||
fDirectory[0x06] = strlen(normalName);
|
fDirectory[0x06] = (uint8_t)strlen(normalName);
|
||||||
memcpy(&fDirectory[0x07], normalName, fDirectory[0x06]);
|
memcpy(&fDirectory[0x07], normalName, fDirectory[0x06]);
|
||||||
strcpy(fVolumeName, normalName);
|
strcpy(fVolumeName, normalName);
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
|
|
||||||
const int kBlkSize = 512;
|
const int kBlkSize = 512;
|
||||||
const int kVolHeaderBlock = 2; // block where Volume Header resides
|
const int kVolHeaderBlock = 2; // block where Volume Header resides
|
||||||
const int kVolDirExpectedNumBlocks = 4; // customary #of volume header blocks
|
const int kFormatVolDirNumBlocks = 4; // #of volume header blocks for new volumes
|
||||||
const int kMinReasonableBlocks = 16; // min size for ProDOS volume
|
const int kMinReasonableBlocks = 16; // min size for ProDOS volume
|
||||||
const int kExpectedBitmapStart = 6; // block# where vol bitmap should start
|
const int kExpectedBitmapStart = 6; // block# where vol bitmap should start
|
||||||
const int kMaxCatalogIterations = 1024; // theoretical max is 32768?
|
const int kMaxCatalogIterations = 1024; // theoretical max is 32768?
|
||||||
|
@ -360,8 +360,11 @@ DIError DiskFSProDOS::LoadVolHeader(void)
|
||||||
pEntry->fileName[nameLen] = '\0';
|
pEntry->fileName[nameLen] = '\0';
|
||||||
pEntry->fileType = kTypeDIR;
|
pEntry->fileType = kTypeDIR;
|
||||||
pEntry->keyPointer = kVolHeaderBlock;
|
pEntry->keyPointer = kVolHeaderBlock;
|
||||||
pEntry->blocksUsed = kVolDirExpectedNumBlocks;
|
dierr = DetermineVolDirLen(GetShortLE(&blkBuf[0x02]), &pEntry->blocksUsed);
|
||||||
pEntry->eof = kVolDirExpectedNumBlocks * 512;
|
if (dierr != kDIErrNone) {
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
pEntry->eof = pEntry->blocksUsed * 512;
|
||||||
pEntry->createWhen = GetLongLE(&blkBuf[0x1c]);
|
pEntry->createWhen = GetLongLE(&blkBuf[0x1c]);
|
||||||
pEntry->version = blkBuf[0x20];
|
pEntry->version = blkBuf[0x20];
|
||||||
pEntry->minVersion = blkBuf[0x21];
|
pEntry->minVersion = blkBuf[0x21];
|
||||||
|
@ -375,8 +378,47 @@ DIError DiskFSProDOS::LoadVolHeader(void)
|
||||||
pFile->fSparseRsrcEof = -1;
|
pFile->fSparseRsrcEof = -1;
|
||||||
|
|
||||||
AddFileToList(pFile);
|
AddFileToList(pFile);
|
||||||
|
pFile = NULL;
|
||||||
|
|
||||||
bail:
|
bail:
|
||||||
|
delete pFile;
|
||||||
|
return dierr;
|
||||||
|
}
|
||||||
|
|
||||||
|
DIError DiskFSProDOS::DetermineVolDirLen(uint16_t nextBlock, uint16_t* pBlocksUsed) {
|
||||||
|
DIError dierr = kDIErrNone;
|
||||||
|
uint8_t blkBuf[kBlkSize];
|
||||||
|
uint16_t blocksUsed = 1;
|
||||||
|
int iterCount = 0;
|
||||||
|
|
||||||
|
// Traverse the volume directory chain, counting blocks. Normally this will have 4, but
|
||||||
|
// variations are possible.
|
||||||
|
while (nextBlock != 0) {
|
||||||
|
blocksUsed++;
|
||||||
|
|
||||||
|
if (nextBlock < 2 || nextBlock >= fpImg->GetNumBlocks()) {
|
||||||
|
LOGI(" ProDOS ERROR: invalid volume dir link block %u", nextBlock);
|
||||||
|
dierr = kDIErrInvalidBlock;
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
dierr = fpImg->ReadBlock(nextBlock, blkBuf);
|
||||||
|
if (dierr != kDIErrNone) {
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
|
||||||
|
nextBlock = GetShortLE(&blkBuf[0x02]);
|
||||||
|
|
||||||
|
// Watch for infinite loop.
|
||||||
|
iterCount++;
|
||||||
|
if (iterCount > fpImg->GetNumBlocks()) {
|
||||||
|
LOGI(" ProDOS ERROR: infinite vol directory loop found");
|
||||||
|
dierr = kDIErrDirectoryLoop;
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bail:
|
||||||
|
*pBlocksUsed = blocksUsed;
|
||||||
return dierr;
|
return dierr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -552,7 +594,7 @@ DIError DiskFSProDOS::ScanVolBitmap(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generate an empty block use map.
|
* Generate an empty block use map. Used by disk formatter.
|
||||||
*/
|
*/
|
||||||
DIError DiskFSProDOS::CreateEmptyBlockMap(void)
|
DIError DiskFSProDOS::CreateEmptyBlockMap(void)
|
||||||
{
|
{
|
||||||
|
@ -569,7 +611,7 @@ DIError DiskFSProDOS::CreateEmptyBlockMap(void)
|
||||||
*/
|
*/
|
||||||
long block;
|
long block;
|
||||||
long firstEmpty =
|
long firstEmpty =
|
||||||
kVolHeaderBlock + kVolDirExpectedNumBlocks + GetNumBitmapBlocks();
|
kVolHeaderBlock + kFormatVolDirNumBlocks + GetNumBitmapBlocks();
|
||||||
for (block = 0; block < firstEmpty; block++)
|
for (block = 0; block < firstEmpty; block++)
|
||||||
SetBlockUseEntry(block, true);
|
SetBlockUseEntry(block, true);
|
||||||
for ( ; block < fTotalBlocks; block++)
|
for ( ; block < fTotalBlocks; block++)
|
||||||
|
@ -1091,8 +1133,9 @@ DIError DiskFSProDOS::ScanFileUsage(void)
|
||||||
&sparseCount);
|
&sparseCount);
|
||||||
pFile->fSparseDataEof =
|
pFile->fSparseDataEof =
|
||||||
(di_off_t) pFile->fExtData.eof - sparseCount * kBlkSize;
|
(di_off_t) pFile->fExtData.eof - sparseCount * kBlkSize;
|
||||||
//LOGI(" SparseCount %d dataEof %d '%s'",
|
//LOGI(" SparseCount %ld dataEof %ld -> %lld '%s'",
|
||||||
// sparseCount, pFile->fSparseDataEof, pFile->fDirEntry.fileName);
|
// sparseCount, pFile->fExtData.eof, pFile->fSparseDataEof,
|
||||||
|
// pFile->fDirEntry.fileName);
|
||||||
delete[] blockList;
|
delete[] blockList;
|
||||||
blockList = NULL;
|
blockList = NULL;
|
||||||
delete[] indexList;
|
delete[] indexList;
|
||||||
|
@ -1126,9 +1169,9 @@ DIError DiskFSProDOS::ScanFileUsage(void)
|
||||||
&sparseCount);
|
&sparseCount);
|
||||||
pFile->fSparseDataEof =
|
pFile->fSparseDataEof =
|
||||||
(di_off_t) pFile->fDirEntry.eof - sparseCount * kBlkSize;
|
(di_off_t) pFile->fDirEntry.eof - sparseCount * kBlkSize;
|
||||||
//LOGI(" +++ sparseCount=%ld blockCount=%ld sparseDataEof=%ld '%s'",
|
//LOGI(" +++ sparseCount=%ld blockCount=%ld sparseDataEof=%lld '%s'",
|
||||||
// sparseCount, blockCount, (long) pFile->fSparseDataEof,
|
// sparseCount, blockCount, pFile->fSparseDataEof,
|
||||||
// pFile->fDirEntry.fileName);
|
// pFile->fDirEntry.fileName);
|
||||||
|
|
||||||
delete[] blockList;
|
delete[] blockList;
|
||||||
blockList = NULL;
|
blockList = NULL;
|
||||||
|
@ -1494,10 +1537,10 @@ DIError DiskFSProDOS::Format(DiskImg* pDiskImg, const char* volName)
|
||||||
*/
|
*/
|
||||||
int i;
|
int i;
|
||||||
memset(blkBuf, 0, sizeof(blkBuf));
|
memset(blkBuf, 0, sizeof(blkBuf));
|
||||||
for (i = kVolHeaderBlock+1; i < kVolHeaderBlock+kVolDirExpectedNumBlocks; i++)
|
for (i = kVolHeaderBlock+1; i < kVolHeaderBlock+kFormatVolDirNumBlocks; i++)
|
||||||
{
|
{
|
||||||
PutShortLE(&blkBuf[0x00], i-1);
|
PutShortLE(&blkBuf[0x00], i-1);
|
||||||
if (i == kVolHeaderBlock+kVolDirExpectedNumBlocks-1)
|
if (i == kVolHeaderBlock+kFormatVolDirNumBlocks-1)
|
||||||
PutShortLE(&blkBuf[0x02], 0);
|
PutShortLE(&blkBuf[0x02], 0);
|
||||||
else
|
else
|
||||||
PutShortLE(&blkBuf[0x02], i+1);
|
PutShortLE(&blkBuf[0x02], i+1);
|
||||||
|
@ -1529,7 +1572,7 @@ DIError DiskFSProDOS::Format(DiskImg* pDiskImg, const char* volName)
|
||||||
|
|
||||||
PutShortLE(&blkBuf[0x00], 0);
|
PutShortLE(&blkBuf[0x00], 0);
|
||||||
PutShortLE(&blkBuf[0x02], kVolHeaderBlock+1);
|
PutShortLE(&blkBuf[0x02], kVolHeaderBlock+1);
|
||||||
blkBuf[0x04] = strlen(upperName) | (A2FileProDOS::kStorageVolumeDirHeader << 4);
|
blkBuf[0x04] = (uint8_t)(strlen(upperName) | (A2FileProDOS::kStorageVolumeDirHeader << 4));
|
||||||
strncpy((char*) &blkBuf[0x05], upperName, A2FileProDOS::kMaxFileName);
|
strncpy((char*) &blkBuf[0x05], upperName, A2FileProDOS::kMaxFileName);
|
||||||
PutLongLE(&blkBuf[0x16], A2FileProDOS::ConvertProDate(now));
|
PutLongLE(&blkBuf[0x16], A2FileProDOS::ConvertProDate(now));
|
||||||
PutShortLE(&blkBuf[0x1a], lcFlags);
|
PutShortLE(&blkBuf[0x1a], lcFlags);
|
||||||
|
@ -1540,7 +1583,7 @@ DIError DiskFSProDOS::Format(DiskImg* pDiskImg, const char* volName)
|
||||||
blkBuf[0x23] = 0x27; // entry_length: always $27
|
blkBuf[0x23] = 0x27; // entry_length: always $27
|
||||||
blkBuf[0x24] = 0x0d; // entries_per_block: always $0d
|
blkBuf[0x24] = 0x0d; // entries_per_block: always $0d
|
||||||
/* file_count is zero - does not include volume dir */
|
/* file_count is zero - does not include volume dir */
|
||||||
PutShortLE(&blkBuf[0x27], kVolHeaderBlock + kVolDirExpectedNumBlocks); // bit_map_pointer
|
PutShortLE(&blkBuf[0x27], kVolHeaderBlock + kFormatVolDirNumBlocks); // bit_map_pointer
|
||||||
PutShortLE(&blkBuf[0x29], (uint16_t) formatBlocks); // total_blocks
|
PutShortLE(&blkBuf[0x29], (uint16_t) formatBlocks); // total_blocks
|
||||||
dierr = fpImg->WriteBlock(kVolHeaderBlock, blkBuf);
|
dierr = fpImg->WriteBlock(kVolHeaderBlock, blkBuf);
|
||||||
if (dierr != kDIErrNone) {
|
if (dierr != kDIErrNone) {
|
||||||
|
@ -1558,8 +1601,7 @@ DIError DiskFSProDOS::Format(DiskImg* pDiskImg, const char* volName)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generate the initial block usage map. The only entries in use are
|
* Generate the initial block usage map. The only entries in use are
|
||||||
* right at the start of the disk. When we finish, scan what we just
|
* right at the start of the disk.
|
||||||
* created into
|
|
||||||
*/
|
*/
|
||||||
CreateEmptyBlockMap();
|
CreateEmptyBlockMap();
|
||||||
|
|
||||||
|
@ -1973,7 +2015,7 @@ DIError DiskFSProDOS::CreateFile(const CreateParms* pParms, A2File** ppNewFile)
|
||||||
* are lower case. (Some parts of the original may have been stomped
|
* are lower case. (Some parts of the original may have been stomped
|
||||||
* when the name was made unique, so we need to watch for that.)
|
* when the name was made unique, so we need to watch for that.)
|
||||||
*/
|
*/
|
||||||
dirEntryPtr[0x00] = (pParms->storageType << 4) | strlen(upperName);
|
dirEntryPtr[0x00] = (uint8_t)((pParms->storageType << 4) | strlen(upperName));
|
||||||
strncpy((char*) &dirEntryPtr[0x01], upperName, A2FileProDOS::kMaxFileName);
|
strncpy((char*) &dirEntryPtr[0x01], upperName, A2FileProDOS::kMaxFileName);
|
||||||
if (pParms->fileType >= 0 && pParms->fileType <= 0xff)
|
if (pParms->fileType >= 0 && pParms->fileType <= 0xff)
|
||||||
dirEntryPtr[0x10] = (uint8_t) pParms->fileType;
|
dirEntryPtr[0x10] = (uint8_t) pParms->fileType;
|
||||||
|
@ -2229,7 +2271,7 @@ DIError DiskFSProDOS::AllocInitialFileStorage(const CreateParms* pParms,
|
||||||
/* fill in directory header fields */
|
/* fill in directory header fields */
|
||||||
// 0x00: prev, set to zero
|
// 0x00: prev, set to zero
|
||||||
// 0x02: next, set to zero
|
// 0x02: next, set to zero
|
||||||
blkBuf[0x04] = (A2FileProDOS::kStorageSubdirHeader << 4) | strlen(upperName);
|
blkBuf[0x04] = (uint8_t)((A2FileProDOS::kStorageSubdirHeader << 4) | strlen(upperName));
|
||||||
strncpy((char*) &blkBuf[0x05], upperName, A2FileProDOS::kMaxFileName);
|
strncpy((char*) &blkBuf[0x05], upperName, A2FileProDOS::kMaxFileName);
|
||||||
blkBuf[0x14] = 0x76; // 0x75 under old P8, 0x76 under GS/OS
|
blkBuf[0x14] = 0x76; // 0x75 under old P8, 0x76 under GS/OS
|
||||||
PutLongLE(&blkBuf[0x1c], A2FileProDOS::ConvertProDate(pParms->createWhen));
|
PutLongLE(&blkBuf[0x1c], A2FileProDOS::ConvertProDate(pParms->createWhen));
|
||||||
|
@ -3470,7 +3512,7 @@ DIError DiskFSProDOS::RenameFile(A2File* pGenericFile, const char* newName)
|
||||||
dierr = kDIErrBadDirectory;
|
dierr = kDIErrBadDirectory;
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
ptr[0x00] = (ptr[0x00] & 0xf0) | strlen(upperName);
|
ptr[0x00] = (uint8_t)((ptr[0x00] & 0xf0) | strlen(upperName));
|
||||||
memcpy(&ptr[0x01], upperName, A2FileProDOS::kMaxFileName);
|
memcpy(&ptr[0x01], upperName, A2FileProDOS::kMaxFileName);
|
||||||
PutShortLE(&ptr[0x1c], lcFlags); // version/min_version
|
PutShortLE(&ptr[0x1c], lcFlags); // version/min_version
|
||||||
if (isAW)
|
if (isAW)
|
||||||
|
@ -3485,7 +3527,7 @@ DIError DiskFSProDOS::RenameFile(A2File* pGenericFile, const char* newName)
|
||||||
dierr = kDIErrBadDirectory;
|
dierr = kDIErrBadDirectory;
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
ptr[0x00] = (ptr[0x00] & 0xf0) | strlen(upperName);
|
ptr[0x00] = (uint8_t)((ptr[0x00] & 0xf0) | strlen(upperName));
|
||||||
memcpy(&ptr[0x01], upperName, A2FileProDOS::kMaxFileName);
|
memcpy(&ptr[0x01], upperName, A2FileProDOS::kMaxFileName);
|
||||||
PutShortLE(&ptr[0x1c], lcFlags); // version/min_version
|
PutShortLE(&ptr[0x1c], lcFlags); // version/min_version
|
||||||
}
|
}
|
||||||
|
@ -3736,7 +3778,7 @@ DIError DiskFSProDOS::RenameVolume(const char* newName)
|
||||||
dierr = kDIErrBadDirectory;
|
dierr = kDIErrBadDirectory;
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
ptr[0x00] = (ptr[0x00] & 0xf0) | strlen(upperName);
|
ptr[0x00] = (uint8_t)((ptr[0x00] & 0xf0) | strlen(upperName));
|
||||||
memcpy(&ptr[0x01], upperName, A2FileProDOS::kMaxFileName);
|
memcpy(&ptr[0x01], upperName, A2FileProDOS::kMaxFileName);
|
||||||
PutShortLE(&ptr[0x16], lcFlags); // reserved fields
|
PutShortLE(&ptr[0x16], lcFlags); // reserved fields
|
||||||
|
|
||||||
|
@ -4496,6 +4538,8 @@ DIError A2FDProDOS::Write(const void* buf, size_t len, size_t* pActual)
|
||||||
bool allocSparse = (pDiskFS->GetParameter(DiskFS::kParmProDOS_AllocSparse) != 0);
|
bool allocSparse = (pDiskFS->GetParameter(DiskFS::kParmProDOS_AllocSparse) != 0);
|
||||||
uint8_t blkBuf[kBlkSize];
|
uint8_t blkBuf[kBlkSize];
|
||||||
uint16_t keyBlock;
|
uint16_t keyBlock;
|
||||||
|
bool allZero = true;
|
||||||
|
const uint8_t* scanPtr = (const uint8_t*)buf;
|
||||||
|
|
||||||
if (len >= 0x01000000) { // 16MB
|
if (len >= 0x01000000) { // 16MB
|
||||||
assert(false);
|
assert(false);
|
||||||
|
@ -4531,13 +4575,32 @@ DIError A2FDProDOS::Write(const void* buf, size_t len, size_t* pActual)
|
||||||
keyBlock = pFile->fExtData.keyBlock;
|
keyBlock = pFile->fExtData.keyBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See if the file is completely empty. This lets us do an optimization
|
||||||
|
* where we store it as a seedling. (GS/OS seems to do this, ProDOS 8
|
||||||
|
* v2.0.3 tends to allocate the first block.)
|
||||||
|
*/
|
||||||
|
for (unsigned int i = 0; i < len; ++i, ++scanPtr) {
|
||||||
|
if (*scanPtr != 0x00) {
|
||||||
|
allZero = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (allZero) {
|
||||||
|
LOGI("+++ found file filled with %zd zeroes", len);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Special-case seedling files. Just write the data into the key block
|
* Special-case seedling files. Just write the data into the key block
|
||||||
* and we're done.
|
* and we're done.
|
||||||
*/
|
*/
|
||||||
if (len <= (size_t)kBlkSize) {
|
if (allZero || len <= (size_t)kBlkSize) {
|
||||||
memset(blkBuf, 0, sizeof(blkBuf));
|
memset(blkBuf, 0, sizeof(blkBuf));
|
||||||
memcpy(blkBuf, buf, len);
|
if (!allZero) {
|
||||||
|
memcpy(blkBuf, buf, len);
|
||||||
|
} else {
|
||||||
|
LOGI("+++ ProDOS storing large but empty file as seedling");
|
||||||
|
}
|
||||||
dierr = pDiskFS->GetDiskImg()->WriteBlock(keyBlock, blkBuf);
|
dierr = pDiskFS->GetDiskImg()->WriteBlock(keyBlock, blkBuf);
|
||||||
if (dierr != kDIErrNone)
|
if (dierr != kDIErrNone)
|
||||||
goto bail;
|
goto bail;
|
||||||
|
@ -4572,11 +4635,9 @@ DIError A2FDProDOS::Write(const void* buf, size_t len, size_t* pActual)
|
||||||
*/
|
*/
|
||||||
const uint8_t* blkPtr;
|
const uint8_t* blkPtr;
|
||||||
long blockIdx;
|
long blockIdx;
|
||||||
bool allZero;
|
|
||||||
long progressCounter;
|
long progressCounter;
|
||||||
|
|
||||||
progressCounter = 0;
|
progressCounter = 0;
|
||||||
allZero = true;
|
|
||||||
blkPtr = (const uint8_t*) buf;
|
blkPtr = (const uint8_t*) buf;
|
||||||
for (blockIdx = 0; blockIdx < fBlockCount; blockIdx++) {
|
for (blockIdx = 0; blockIdx < fBlockCount; blockIdx++) {
|
||||||
long newBlock;
|
long newBlock;
|
||||||
|
@ -4590,12 +4651,24 @@ DIError A2FDProDOS::Write(const void* buf, size_t len, size_t* pActual)
|
||||||
blkPtr = blkBuf;
|
blkPtr = blkBuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (allocSparse && IsEmptyBlock(blkPtr))
|
if (allocSparse && IsEmptyBlock(blkPtr)) {
|
||||||
newBlock = 0;
|
if (blockIdx == 0) {
|
||||||
else {
|
// Fix for issues #18 and #49. GS/OS appears to get confused
|
||||||
|
// if the first entry in the master index block for a "tree"
|
||||||
|
// file is zero. We can avoid the problem by always allocating
|
||||||
|
// the first data block, which causes allocation of the first
|
||||||
|
// index block. (The "all zeroes" case was handled earlier,
|
||||||
|
// so if we got here we know this won't be an empty seedling.)
|
||||||
|
LOGI("+++ allocating storage for empty first block");
|
||||||
|
newBlock = pDiskFS->AllocBlock();
|
||||||
|
fOpenBlocksUsed++;
|
||||||
|
} else {
|
||||||
|
// Sparse.
|
||||||
|
newBlock = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
newBlock = pDiskFS->AllocBlock();
|
newBlock = pDiskFS->AllocBlock();
|
||||||
fOpenBlocksUsed++;
|
fOpenBlocksUsed++;
|
||||||
allZero = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newBlock < 0) {
|
if (newBlock < 0) {
|
||||||
|
@ -4651,7 +4724,9 @@ DIError A2FDProDOS::Write(const void* buf, size_t len, size_t* pActual)
|
||||||
/*
|
/*
|
||||||
* Now we have a full block map. Allocate any needed index blocks and
|
* Now we have a full block map. Allocate any needed index blocks and
|
||||||
* write them.
|
* write them.
|
||||||
*
|
*/
|
||||||
|
#if 0 // now done earlier
|
||||||
|
/*
|
||||||
* If our block map is empty, i.e. the entire file is sparse, then
|
* If our block map is empty, i.e. the entire file is sparse, then
|
||||||
* there's no need to create a sapling. We just leave the file in
|
* there's no need to create a sapling. We just leave the file in
|
||||||
* seedling form. This can only happen for a completely empty file.
|
* seedling form. This can only happen for a completely empty file.
|
||||||
|
@ -4665,7 +4740,9 @@ DIError A2FDProDOS::Write(const void* buf, size_t len, size_t* pActual)
|
||||||
goto bail;
|
goto bail;
|
||||||
fOpenStorageType = A2FileProDOS::kStorageSeedling;
|
fOpenStorageType = A2FileProDOS::kStorageSeedling;
|
||||||
fBlockList[0] = keyBlock;
|
fBlockList[0] = keyBlock;
|
||||||
} else if (fBlockCount <= 256) {
|
} else
|
||||||
|
#endif
|
||||||
|
if (fBlockCount <= 256) {
|
||||||
/* sapling file, write an index block into the key block */
|
/* sapling file, write an index block into the key block */
|
||||||
//bool allzero = true; <-- should this be getting used?
|
//bool allzero = true; <-- should this be getting used?
|
||||||
assert(fBlockCount > 1);
|
assert(fBlockCount > 1);
|
||||||
|
@ -4972,12 +5049,27 @@ DIError A2FDProDOS::Close(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find the #of sparse blocks.
|
* Find the #of sparse blocks. We do this to update the "sparse EOF",
|
||||||
|
* which determines the "compressed" size shown in the file list. We
|
||||||
|
* have two cases: normal file with sparse contents, and seedling file
|
||||||
|
* that is entirely sparse except for the first block.
|
||||||
|
*
|
||||||
|
* In the normal case, we walk through the list of data blocks,
|
||||||
|
* looking for gaps. In the seedling case, we just use the EOF.
|
||||||
|
*
|
||||||
|
* This is just for display. The value seen after adding a file should
|
||||||
|
* not change if you reload the disk image.
|
||||||
*/
|
*/
|
||||||
int sparseCount = 0;
|
int sparseBlocks = 0;
|
||||||
for (int i = 0; i < fBlockCount; i++) {
|
if (fBlockCount == 1 && fOpenEOF > kBlkSize) {
|
||||||
if (fBlockList[i] == 0)
|
// 1023/1024 = 2 blocks = 1 sparse
|
||||||
sparseCount++;
|
// 1025 = 3 blocks = 2 sparse
|
||||||
|
sparseBlocks = (int)((fOpenEOF-1) / kBlkSize);
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < fBlockCount; i++) {
|
||||||
|
if (fBlockList[i] == 0)
|
||||||
|
sparseBlocks++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -4995,19 +5087,19 @@ DIError A2FDProDOS::Close(void)
|
||||||
pFile->fExtData.storageType = fOpenStorageType;
|
pFile->fExtData.storageType = fOpenStorageType;
|
||||||
pFile->fExtData.blocksUsed = newBlocksUsed;
|
pFile->fExtData.blocksUsed = newBlocksUsed;
|
||||||
pFile->fExtData.eof = newEOF;
|
pFile->fExtData.eof = newEOF;
|
||||||
pFile->fSparseDataEof = (di_off_t) newEOF - (sparseCount * kBlkSize);
|
pFile->fSparseDataEof = (di_off_t) newEOF - (sparseBlocks * kBlkSize);
|
||||||
if (pFile->fSparseDataEof < 0)
|
if (pFile->fSparseDataEof < 0)
|
||||||
pFile->fSparseDataEof = 0;
|
pFile->fSparseDataEof = 0;
|
||||||
} else {
|
} else {
|
||||||
pFile->fExtRsrc.storageType = fOpenStorageType;
|
pFile->fExtRsrc.storageType = fOpenStorageType;
|
||||||
pFile->fExtRsrc.blocksUsed = newBlocksUsed;
|
pFile->fExtRsrc.blocksUsed = newBlocksUsed;
|
||||||
pFile->fExtRsrc.eof = newEOF;
|
pFile->fExtRsrc.eof = newEOF;
|
||||||
pFile->fSparseRsrcEof = (di_off_t) newEOF - (sparseCount * kBlkSize);
|
pFile->fSparseRsrcEof = (di_off_t) newEOF - (sparseBlocks * kBlkSize);
|
||||||
if (pFile->fSparseRsrcEof < 0)
|
if (pFile->fSparseRsrcEof < 0)
|
||||||
pFile->fSparseRsrcEof = 0;
|
pFile->fSparseRsrcEof = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pFile->fSparseDataEof = (di_off_t) newEOF - (sparseCount * kBlkSize);
|
pFile->fSparseDataEof = (di_off_t) newEOF - (sparseBlocks * kBlkSize);
|
||||||
if (pFile->fSparseDataEof < 0)
|
if (pFile->fSparseDataEof < 0)
|
||||||
pFile->fSparseDataEof = 0;
|
pFile->fSparseDataEof = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -344,6 +344,9 @@ DIError DiskFSRDOS::ReadCatalog(void)
|
||||||
|
|
||||||
pFile = new A2FileRDOS(this);
|
pFile = new A2FileRDOS(this);
|
||||||
|
|
||||||
|
memcpy(pFile->fRawFileName, dirPtr, A2FileRDOS::kMaxFileName);
|
||||||
|
pFile->fRawFileName[A2FileRDOS::kMaxFileName] = '\0';
|
||||||
|
|
||||||
memcpy(pFile->fFileName, dirPtr, A2FileRDOS::kMaxFileName);
|
memcpy(pFile->fFileName, dirPtr, A2FileRDOS::kMaxFileName);
|
||||||
pFile->fFileName[A2FileRDOS::kMaxFileName] = '\0';
|
pFile->fFileName[A2FileRDOS::kMaxFileName] = '\0';
|
||||||
pFile->FixFilename();
|
pFile->FixFilename();
|
||||||
|
@ -521,6 +524,19 @@ DIError A2FileRDOS::Open(A2FileDescr** ppOpenFile, bool readOnly,
|
||||||
return kDIErrNone;
|
return kDIErrNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the raw filename.
|
||||||
|
*
|
||||||
|
* If a pointer to a size_t is passed in, it will be filled with the
|
||||||
|
* raw filename length.
|
||||||
|
*/
|
||||||
|
const char* A2FileRDOS::GetRawFileName(size_t* size) const {
|
||||||
|
if (size) {
|
||||||
|
*size = strlen(fRawFileName);
|
||||||
|
}
|
||||||
|
return fRawFileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ===========================================================================
|
* ===========================================================================
|
||||||
|
|
|
@ -30,7 +30,7 @@ int TwoImgHeader::InitHeader(int imageFormat, uint32_t imageSize,
|
||||||
{
|
{
|
||||||
if (imageSize == 0)
|
if (imageSize == 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (imageFormat < kImageFormatDOS || imageFormat > (int) kImageFormatNibble)
|
if (imageFormat < (int) kImageFormatDOS || imageFormat > (int) kImageFormatNibble)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (imageFormat != kImageFormatNibble &&
|
if (imageFormat != kImageFormatNibble &&
|
||||||
|
|
|
@ -30,7 +30,27 @@ namespace DiskImgLib {
|
||||||
*/
|
*/
|
||||||
class DISKIMG_API TwoImgHeader {
|
class DISKIMG_API TwoImgHeader {
|
||||||
public:
|
public:
|
||||||
TwoImgHeader(void) : fDOSVolumeNum(-1), fComment(NULL), fCreatorChunk(NULL)
|
TwoImgHeader(void) :
|
||||||
|
fMagic(0),
|
||||||
|
fCreator(0),
|
||||||
|
fHeaderLen(0),
|
||||||
|
fVersion(0),
|
||||||
|
fImageFormat(0),
|
||||||
|
fFlags(0),
|
||||||
|
fNumBlocks(0),
|
||||||
|
fDataOffset(0),
|
||||||
|
fDataLen(0),
|
||||||
|
fCmtOffset(0),
|
||||||
|
fCmtLen(0),
|
||||||
|
fCreatorOffset(0),
|
||||||
|
fCreatorLen(0),
|
||||||
|
fSpare(),
|
||||||
|
|
||||||
|
fDOSVolumeNum(-1),
|
||||||
|
fMagicStr(),
|
||||||
|
fCreatorStr(),
|
||||||
|
fComment(NULL),
|
||||||
|
fCreatorChunk(NULL)
|
||||||
{}
|
{}
|
||||||
virtual ~TwoImgHeader(void) {
|
virtual ~TwoImgHeader(void) {
|
||||||
delete[] fComment;
|
delete[] fComment;
|
||||||
|
|
|
@ -119,7 +119,9 @@ private:
|
||||||
*/
|
*/
|
||||||
class Win32VolumeAccess {
|
class Win32VolumeAccess {
|
||||||
public:
|
public:
|
||||||
Win32VolumeAccess(void) : fpBlockAccess(NULL)
|
Win32VolumeAccess(void) :
|
||||||
|
fTotalBlocks(-1),
|
||||||
|
fpBlockAccess(NULL)
|
||||||
{}
|
{}
|
||||||
virtual ~Win32VolumeAccess(void) {
|
virtual ~Win32VolumeAccess(void) {
|
||||||
if (fpBlockAccess != NULL) {
|
if (fpBlockAccess != NULL) {
|
||||||
|
@ -305,7 +307,11 @@ private:
|
||||||
*/
|
*/
|
||||||
class PhysicalBlockAccess : public BlockAccess {
|
class PhysicalBlockAccess : public BlockAccess {
|
||||||
public:
|
public:
|
||||||
PhysicalBlockAccess(void) : fHandle(NULL), fInt13Unit(-1) {}
|
PhysicalBlockAccess(void) :
|
||||||
|
fHandle(NULL),
|
||||||
|
fInt13Unit(-1),
|
||||||
|
fFloppyKind(kFloppyUnknown)
|
||||||
|
{}
|
||||||
virtual ~PhysicalBlockAccess(void) {}
|
virtual ~PhysicalBlockAccess(void) {}
|
||||||
|
|
||||||
virtual DIError Open(const WCHAR* deviceName, bool readOnly);
|
virtual DIError Open(const WCHAR* deviceName, bool readOnly);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
<Configuration>Debug</Configuration>
|
<Configuration>Debug</Configuration>
|
||||||
|
@ -18,13 +18,13 @@
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
<PlatformToolset>v120_xp</PlatformToolset>
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
<UseOfMfc>false</UseOfMfc>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<UseOfMfc>Dynamic</UseOfMfc>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
<PlatformToolset>v120_xp</PlatformToolset>
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
<UseOfMfc>false</UseOfMfc>
|
<UseOfMfc>false</UseOfMfc>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
<Configuration>Debug</Configuration>
|
<Configuration>Debug</Configuration>
|
||||||
|
@ -18,15 +18,15 @@
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
<PlatformToolset>v120_xp</PlatformToolset>
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
<UseOfMfc>false</UseOfMfc>
|
<UseOfMfc>false</UseOfMfc>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
<PlatformToolset>v120_xp</PlatformToolset>
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
<UseOfMfc>false</UseOfMfc>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<UseOfMfc>Dynamic</UseOfMfc>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
<ImportGroup Label="ExtensionSettings">
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#include "../diskimg/DiskImg.h"
|
#include "../diskimg/DiskImg.h"
|
||||||
|
|
||||||
using namespace DiskImgLib;
|
using namespace DiskImgLib;
|
||||||
|
@ -97,7 +99,21 @@ CopyFiles(DiskFS* pDiskFS, int argc, char** argv)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
argv--;
|
||||||
while (argc--) {
|
while (argc--) {
|
||||||
|
argv++;
|
||||||
|
|
||||||
|
// Confirm this is a regular file, and not a directory.
|
||||||
|
struct stat sb;
|
||||||
|
if (stat(*argv, &sb) != 0) {
|
||||||
|
fprintf(stderr, "Warning: unable to stat '%s'\n", *argv);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ((sb.st_mode & S_IFREG) == 0) {
|
||||||
|
printf("--- Skipping '%s'\n", *argv);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
printf("+++ Adding '%s'\n", *argv);
|
printf("+++ Adding '%s'\n", *argv);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -148,6 +164,11 @@ CopyFiles(DiskFS* pDiskFS, int argc, char** argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
len = ftell(fp);
|
len = ftell(fp);
|
||||||
|
if (len >= 1L<<31) { // 2GB
|
||||||
|
fprintf(stderr, "Warning: file '%s' too large, skipping\n", *argv);
|
||||||
|
fclose(fp);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
rewind(fp);
|
rewind(fp);
|
||||||
|
|
||||||
buf = new char[len];
|
buf = new char[len];
|
||||||
|
@ -199,11 +220,6 @@ CopyFiles(DiskFS* pDiskFS, int argc, char** argv)
|
||||||
pNewFile->GetPathName(), DIStrError(dierr));
|
pNewFile->GetPathName(), DIStrError(dierr));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* On to the next file.
|
|
||||||
*/
|
|
||||||
argv++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
<Configuration>Debug</Configuration>
|
<Configuration>Debug</Configuration>
|
||||||
|
@ -19,13 +19,13 @@
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<PlatformToolset>v120_xp</PlatformToolset>
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
<UseOfMfc>Dynamic</UseOfMfc>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<UseOfMfc>Dynamic</UseOfMfc>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<PlatformToolset>v120_xp</PlatformToolset>
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
<UseOfMfc>Dynamic</UseOfMfc>
|
<UseOfMfc>Dynamic</UseOfMfc>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
|
@ -1,4 +1,13 @@
|
||||||
2005/01/09 ***** v3.0.0 shipped *****
|
2017/09/21 ***** v3.1.0 shipped *****
|
||||||
|
|
||||||
|
2016/01/11 fadden
|
||||||
|
- Fix handling of disk images (broken by previous change).
|
||||||
|
|
||||||
|
2015/12/26 fadden
|
||||||
|
- Fix handling of entries with missing threads.
|
||||||
|
- Improve handling of Mac OS X file type attributes.
|
||||||
|
|
||||||
|
2015/01/09 ***** v3.0.0 shipped *****
|
||||||
|
|
||||||
2015/01/03 fadden
|
2015/01/03 fadden
|
||||||
- Mac OS X: replace Carbon FinderInfo calls with BSD xattr.
|
- Mac OS X: replace Carbon FinderInfo calls with BSD xattr.
|
||||||
|
|
|
@ -228,6 +228,13 @@ typedef struct NuFileInfo {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Determine whether the record has both data and resource forks.
|
* Determine whether the record has both data and resource forks.
|
||||||
|
*
|
||||||
|
* TODO: if we're not using "mask dataless", scanning threads may not
|
||||||
|
* get the right answer, because GSHK omits theads for zero-length forks.
|
||||||
|
* We could check pRecord->recStorageType, though we have to be careful
|
||||||
|
* because that's overloaded for disk images. In any event, the result
|
||||||
|
* from this method isn't relevant unless we're trying to use forked
|
||||||
|
* files on the native filesystem.
|
||||||
*/
|
*/
|
||||||
static Boolean Nu_IsForkedFile(NuArchive* pArchive, const NuRecord* pRecord)
|
static Boolean Nu_IsForkedFile(NuArchive* pArchive, const NuRecord* pRecord)
|
||||||
{
|
{
|
||||||
|
@ -320,20 +327,44 @@ static NuError Nu_SetFinderInfo(NuArchive* pArchive, const NuRecord* pRecord,
|
||||||
return kNuErrFile;
|
return kNuErrFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* build type and creator from 8-bit type and 16-bit aux type */
|
uint8_t proType = (uint8_t) pRecord->recFileType;
|
||||||
uint32_t fileType, creator;
|
uint16_t proAux = (uint16_t) pRecord->recExtraType;
|
||||||
fileType = ('p' << 24) | ((pRecord->recFileType & 0xff) << 16) |
|
|
||||||
(pRecord->recExtraType & 0xffff);
|
|
||||||
creator = 'pdos';
|
|
||||||
|
|
||||||
fiBuf[0] = fileType >> 24;
|
/*
|
||||||
fiBuf[1] = fileType >> 16;
|
* Attempt to use one of the convenience types. If nothing matches,
|
||||||
fiBuf[2] = fileType >> 8;
|
* use the generic pdos/pXYZ approach. Note that PSYS/PS16 will
|
||||||
fiBuf[3] = fileType;
|
* lose the file's aux type.
|
||||||
fiBuf[4] = creator >> 24;
|
*
|
||||||
fiBuf[5] = creator >> 16;
|
* I'm told this is from page 336 of _Programmer's Reference for
|
||||||
fiBuf[6] = creator >> 8;
|
* System 6.0_.
|
||||||
fiBuf[7] = creator;
|
*/
|
||||||
|
uint8_t* fileTypeBuf = fiBuf;
|
||||||
|
uint8_t* creatorBuf = fiBuf + 4;
|
||||||
|
|
||||||
|
memcpy(creatorBuf, "pdos", 4);
|
||||||
|
if (proType == 0x00 && proAux == 0x0000) {
|
||||||
|
memcpy(fileTypeBuf, "BINA", 4);
|
||||||
|
} else if (proType == 0x04 && proAux == 0x0000) {
|
||||||
|
memcpy(fileTypeBuf, "TEXT", 4);
|
||||||
|
} else if (proType == 0xff) {
|
||||||
|
memcpy(fileTypeBuf, "PSYS", 4);
|
||||||
|
} else if (proType == 0xb3 && (proAux & 0xff00) != 0xdb00) {
|
||||||
|
memcpy(fileTypeBuf, "PS16", 4);
|
||||||
|
} else if (proType == 0xd7 && proAux == 0x0000) {
|
||||||
|
memcpy(fileTypeBuf, "MIDI", 4);
|
||||||
|
} else if (proType == 0xd8 && proAux == 0x0000) {
|
||||||
|
memcpy(fileTypeBuf, "AIFF", 4);
|
||||||
|
} else if (proType == 0xd8 && proAux == 0x0001) {
|
||||||
|
memcpy(fileTypeBuf, "AIFC", 4);
|
||||||
|
} else if (proType == 0xe0 && proAux == 0x0005) {
|
||||||
|
memcpy(creatorBuf, "dCpy", 4);
|
||||||
|
memcpy(fileTypeBuf, "dImg", 4);
|
||||||
|
} else {
|
||||||
|
fileTypeBuf[0] = 'p';
|
||||||
|
fileTypeBuf[1] = proType;
|
||||||
|
fileTypeBuf[2] = (uint8_t) (proAux >> 8);
|
||||||
|
fileTypeBuf[3] = (uint8_t) proAux;
|
||||||
|
}
|
||||||
|
|
||||||
if (setxattr(pathnameUNI, XATTR_FINDERINFO_NAME, fiBuf, sizeof(fiBuf),
|
if (setxattr(pathnameUNI, XATTR_FINDERINFO_NAME, fiBuf, sizeof(fiBuf),
|
||||||
0, 0) != 0)
|
0, 0) != 0)
|
||||||
|
|
|
@ -33,7 +33,7 @@ extern "C" {
|
||||||
* fixes. Unless, of course, your code depends upon that fix.
|
* fixes. Unless, of course, your code depends upon that fix.
|
||||||
*/
|
*/
|
||||||
#define kNuVersionMajor 3
|
#define kNuVersionMajor 3
|
||||||
#define kNuVersionMinor 0
|
#define kNuVersionMinor 1
|
||||||
#define kNuVersionBug 0
|
#define kNuVersionBug 0
|
||||||
|
|
||||||
|
|
||||||
|
@ -201,13 +201,16 @@ typedef uint32_t NuThreadID;
|
||||||
#define kNuThreadClassControl 0x0001
|
#define kNuThreadClassControl 0x0001
|
||||||
#define kNuThreadClassData 0x0002
|
#define kNuThreadClassData 0x0002
|
||||||
#define kNuThreadClassFilename 0x0003
|
#define kNuThreadClassFilename 0x0003
|
||||||
|
#define kNuThreadKindDataFork 0x0000 /* when class=data */
|
||||||
|
#define kNuThreadKindDiskImage 0x0001 /* when class=data */
|
||||||
|
#define kNuThreadKindRsrcFork 0x0002 /* when class=data */
|
||||||
#define kNuThreadIDOldComment NuMakeThreadID(kNuThreadClassMessage, 0x0000)
|
#define kNuThreadIDOldComment NuMakeThreadID(kNuThreadClassMessage, 0x0000)
|
||||||
#define kNuThreadIDComment NuMakeThreadID(kNuThreadClassMessage, 0x0001)
|
#define kNuThreadIDComment NuMakeThreadID(kNuThreadClassMessage, 0x0001)
|
||||||
#define kNuThreadIDIcon NuMakeThreadID(kNuThreadClassMessage, 0x0002)
|
#define kNuThreadIDIcon NuMakeThreadID(kNuThreadClassMessage, 0x0002)
|
||||||
#define kNuThreadIDMkdir NuMakeThreadID(kNuThreadClassControl, 0x0000)
|
#define kNuThreadIDMkdir NuMakeThreadID(kNuThreadClassControl, 0x0000)
|
||||||
#define kNuThreadIDDataFork NuMakeThreadID(kNuThreadClassData, 0x0000)
|
#define kNuThreadIDDataFork NuMakeThreadID(kNuThreadClassData, kNuThreadKindDataFork)
|
||||||
#define kNuThreadIDDiskImage NuMakeThreadID(kNuThreadClassData, 0x0001)
|
#define kNuThreadIDDiskImage NuMakeThreadID(kNuThreadClassData, kNuThreadKindDiskImage)
|
||||||
#define kNuThreadIDRsrcFork NuMakeThreadID(kNuThreadClassData, 0x0002)
|
#define kNuThreadIDRsrcFork NuMakeThreadID(kNuThreadClassData, kNuThreadKindRsrcFork)
|
||||||
#define kNuThreadIDFilename NuMakeThreadID(kNuThreadClassFilename, 0x0000)
|
#define kNuThreadIDFilename NuMakeThreadID(kNuThreadClassFilename, 0x0000)
|
||||||
#define kNuThreadIDWildcard NuMakeThreadID(0xffff, 0xffff)
|
#define kNuThreadIDWildcard NuMakeThreadID(0xffff, 0xffff)
|
||||||
|
|
||||||
|
|
|
@ -1524,7 +1524,7 @@ NuError Nu_StreamExtract(NuArchive* pArchive)
|
||||||
{
|
{
|
||||||
NuError err = kNuErrNone;
|
NuError err = kNuErrNone;
|
||||||
NuRecord tmpRecord;
|
NuRecord tmpRecord;
|
||||||
Boolean hasInterestingThread;
|
Boolean needFakeData, needFakeRsrc;
|
||||||
uint32_t count;
|
uint32_t count;
|
||||||
long idx;
|
long idx;
|
||||||
|
|
||||||
|
@ -1573,7 +1573,8 @@ NuError Nu_StreamExtract(NuArchive* pArchive)
|
||||||
/*Nu_DebugDumpRecord(&tmpRecord);
|
/*Nu_DebugDumpRecord(&tmpRecord);
|
||||||
printf("\n");*/
|
printf("\n");*/
|
||||||
|
|
||||||
hasInterestingThread = false;
|
needFakeData = true;
|
||||||
|
needFakeRsrc = (tmpRecord.recStorageType == kNuStorageExtended);
|
||||||
|
|
||||||
/* extract all relevant (remaining) threads */
|
/* extract all relevant (remaining) threads */
|
||||||
pArchive->lastFileCreatedUNI = NULL;
|
pArchive->lastFileCreatedUNI = NULL;
|
||||||
|
@ -1581,7 +1582,14 @@ NuError Nu_StreamExtract(NuArchive* pArchive)
|
||||||
const NuThread* pThread = Nu_GetThread(&tmpRecord, idx);
|
const NuThread* pThread = Nu_GetThread(&tmpRecord, idx);
|
||||||
|
|
||||||
if (pThread->thThreadClass == kNuThreadClassData) {
|
if (pThread->thThreadClass == kNuThreadClassData) {
|
||||||
hasInterestingThread = true;
|
if (pThread->thThreadKind == kNuThreadKindDataFork) {
|
||||||
|
needFakeData = false;
|
||||||
|
} else if (pThread->thThreadKind == kNuThreadKindRsrcFork) {
|
||||||
|
needFakeRsrc = false;
|
||||||
|
} else if (pThread->thThreadKind == kNuThreadKindDiskImage) {
|
||||||
|
/* needFakeRsrc shouldn't be set, but clear anyway */
|
||||||
|
needFakeData = needFakeRsrc = false;
|
||||||
|
}
|
||||||
err = Nu_ExtractThreadBulk(pArchive, &tmpRecord, pThread);
|
err = Nu_ExtractThreadBulk(pArchive, &tmpRecord, pThread);
|
||||||
if (err == kNuErrSkipped) {
|
if (err == kNuErrSkipped) {
|
||||||
err = Nu_SkipThread(pArchive, &tmpRecord, pThread);
|
err = Nu_SkipThread(pArchive, &tmpRecord, pThread);
|
||||||
|
@ -1595,7 +1603,8 @@ NuError Nu_StreamExtract(NuArchive* pArchive)
|
||||||
if (NuGetThreadID(pThread) != kNuThreadIDComment &&
|
if (NuGetThreadID(pThread) != kNuThreadIDComment &&
|
||||||
NuGetThreadID(pThread) != kNuThreadIDFilename)
|
NuGetThreadID(pThread) != kNuThreadIDFilename)
|
||||||
{
|
{
|
||||||
hasInterestingThread = true;
|
/* unknown stuff in record, skip thread fakery */
|
||||||
|
needFakeData = needFakeRsrc = false;
|
||||||
}
|
}
|
||||||
err = Nu_SkipThread(pArchive, &tmpRecord, pThread);
|
err = Nu_SkipThread(pArchive, &tmpRecord, pThread);
|
||||||
BailError(err);
|
BailError(err);
|
||||||
|
@ -1603,19 +1612,19 @@ NuError Nu_StreamExtract(NuArchive* pArchive)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we're trying to be compatible with ShrinkIt, and the record
|
* As in Nu_ExtractRecordByPtr, we need to synthesize empty forks for
|
||||||
* had nothing in it but comments and filenames, then we need to
|
* cases where GSHK omitted the data thread entirely.
|
||||||
* create a zero-byte data file (and possibly a resource fork).
|
|
||||||
*
|
|
||||||
* See notes in previous instance, above.
|
|
||||||
*/
|
*/
|
||||||
if (/*pArchive->valMaskDataless &&*/ !hasInterestingThread) {
|
Assert(!pArchive->valMaskDataless || (!needFakeData && !needFakeRsrc));
|
||||||
err = Nu_FakeZeroExtract(pArchive, &tmpRecord, 0x0000);
|
if (needFakeData) {
|
||||||
|
err = Nu_FakeZeroExtract(pArchive, &tmpRecord,
|
||||||
|
kNuThreadKindDataFork);
|
||||||
|
BailError(err);
|
||||||
|
}
|
||||||
|
if (needFakeRsrc) {
|
||||||
|
err = Nu_FakeZeroExtract(pArchive, &tmpRecord,
|
||||||
|
kNuThreadKindRsrcFork);
|
||||||
BailError(err);
|
BailError(err);
|
||||||
if (tmpRecord.recStorageType == kNuStorageExtended) {
|
|
||||||
err = Nu_FakeZeroExtract(pArchive, &tmpRecord, 0x0002);
|
|
||||||
BailError(err);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* dispose of the entry */
|
/* dispose of the entry */
|
||||||
|
@ -1698,20 +1707,29 @@ bail:
|
||||||
static NuError Nu_ExtractRecordByPtr(NuArchive* pArchive, NuRecord* pRecord)
|
static NuError Nu_ExtractRecordByPtr(NuArchive* pArchive, NuRecord* pRecord)
|
||||||
{
|
{
|
||||||
NuError err = kNuErrNone;
|
NuError err = kNuErrNone;
|
||||||
Boolean hasInterestingThread;
|
Boolean needFakeData, needFakeRsrc;
|
||||||
uint32_t idx;
|
uint32_t idx;
|
||||||
|
|
||||||
|
needFakeData = true;
|
||||||
|
needFakeRsrc = (pRecord->recStorageType == kNuStorageExtended);
|
||||||
|
|
||||||
Assert(!Nu_IsStreaming(pArchive)); /* we don't skip things we don't read */
|
Assert(!Nu_IsStreaming(pArchive)); /* we don't skip things we don't read */
|
||||||
Assert(pRecord != NULL);
|
Assert(pRecord != NULL);
|
||||||
|
|
||||||
/* extract all relevant threads */
|
/* extract all relevant threads */
|
||||||
hasInterestingThread = false;
|
|
||||||
pArchive->lastFileCreatedUNI = NULL;
|
pArchive->lastFileCreatedUNI = NULL;
|
||||||
for (idx = 0; idx < pRecord->recTotalThreads; idx++) {
|
for (idx = 0; idx < pRecord->recTotalThreads; idx++) {
|
||||||
const NuThread* pThread = Nu_GetThread(pRecord, idx);
|
const NuThread* pThread = Nu_GetThread(pRecord, idx);
|
||||||
|
|
||||||
if (pThread->thThreadClass == kNuThreadClassData) {
|
if (pThread->thThreadClass == kNuThreadClassData) {
|
||||||
hasInterestingThread = true;
|
if (pThread->thThreadKind == kNuThreadKindDataFork) {
|
||||||
|
needFakeData = false;
|
||||||
|
} else if (pThread->thThreadKind == kNuThreadKindRsrcFork) {
|
||||||
|
needFakeRsrc = false;
|
||||||
|
} else if (pThread->thThreadKind == kNuThreadKindDiskImage) {
|
||||||
|
/* needFakeRsrc shouldn't be set, but clear anyway */
|
||||||
|
needFakeData = needFakeRsrc = false;
|
||||||
|
}
|
||||||
err = Nu_ExtractThreadBulk(pArchive, pRecord, pThread);
|
err = Nu_ExtractThreadBulk(pArchive, pRecord, pThread);
|
||||||
if (err == kNuErrSkipped) {
|
if (err == kNuErrSkipped) {
|
||||||
err = Nu_SkipThread(pArchive, pRecord, pThread);
|
err = Nu_SkipThread(pArchive, pRecord, pThread);
|
||||||
|
@ -1722,7 +1740,13 @@ static NuError Nu_ExtractRecordByPtr(NuArchive* pArchive, NuRecord* pRecord)
|
||||||
if (NuGetThreadID(pThread) != kNuThreadIDComment &&
|
if (NuGetThreadID(pThread) != kNuThreadIDComment &&
|
||||||
NuGetThreadID(pThread) != kNuThreadIDFilename)
|
NuGetThreadID(pThread) != kNuThreadIDFilename)
|
||||||
{
|
{
|
||||||
hasInterestingThread = true;
|
/*
|
||||||
|
* This record has a thread we don't recognize. Disable
|
||||||
|
* the thread fakery to avoid doing anything weird -- we
|
||||||
|
* should only need to create zero-length files for
|
||||||
|
* simple file records.
|
||||||
|
*/
|
||||||
|
needFakeData = needFakeRsrc = false;
|
||||||
}
|
}
|
||||||
DBUG(("IGNORING 0x%08lx from '%s'\n",
|
DBUG(("IGNORING 0x%08lx from '%s'\n",
|
||||||
NuMakeThreadID(pThread->thThreadClass, pThread->thThreadKind),
|
NuMakeThreadID(pThread->thThreadClass, pThread->thThreadKind),
|
||||||
|
@ -1731,28 +1755,27 @@ static NuError Nu_ExtractRecordByPtr(NuArchive* pArchive, NuRecord* pRecord)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we're trying to be compatible with ShrinkIt, and the record
|
* GSHK creates empty threads for zero-length forks. It doesn't always
|
||||||
* had nothing in it but comments and filenames, then we need to
|
* handle them correctly when extracting, so it appears this behavior
|
||||||
* create a zero-byte file.
|
* may not be intentional.
|
||||||
*
|
*
|
||||||
* (GSHK handles empty data and resource forks by not storing a
|
* We need to create an empty file for whichever forks are missing.
|
||||||
* thread at all. It doesn't correctly deal with them when extracting
|
* Could be the data fork, resource fork, or both. The only way to
|
||||||
* though, so it appears this behavior wasn't entirely expected.)
|
* know what's expected is to examine the file's storage type.
|
||||||
*
|
*
|
||||||
* If it's a forked file, we also need to create an empty rsrc file.
|
* If valMaskDataless is enabled, this won't fire, because we will have
|
||||||
*
|
* "forged" the appropriate threads.
|
||||||
* If valMaskDataless is enabled, this won't fire, because we "forge"
|
|
||||||
* appropriate threads.
|
|
||||||
*
|
*
|
||||||
* Note there's another one of these below, in Nu_StreamExtract.
|
* Note there's another one of these below, in Nu_StreamExtract.
|
||||||
*/
|
*/
|
||||||
if (/*pArchive->valMaskDataless &&*/ !hasInterestingThread) {
|
Assert(!pArchive->valMaskDataless || (!needFakeData && !needFakeRsrc));
|
||||||
err = Nu_FakeZeroExtract(pArchive, pRecord, 0x0000 /*data*/);
|
if (needFakeData) {
|
||||||
|
err = Nu_FakeZeroExtract(pArchive, pRecord, kNuThreadKindDataFork);
|
||||||
|
BailError(err);
|
||||||
|
}
|
||||||
|
if (needFakeRsrc) {
|
||||||
|
err = Nu_FakeZeroExtract(pArchive, pRecord, kNuThreadKindRsrcFork);
|
||||||
BailError(err);
|
BailError(err);
|
||||||
if (pRecord->recStorageType == kNuStorageExtended) {
|
|
||||||
err = Nu_FakeZeroExtract(pArchive, pRecord, 0x0002 /*rsrc*/);
|
|
||||||
BailError(err);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bail:
|
bail:
|
||||||
|
|
|
@ -67,8 +67,10 @@
|
||||||
# include <direct.h>
|
# include <direct.h>
|
||||||
# define FOPEN_WANTS_B
|
# define FOPEN_WANTS_B
|
||||||
# define HAVE_CHSIZE
|
# define HAVE_CHSIZE
|
||||||
# define snprintf _snprintf
|
# if _MSC_VER < 1900 /* no snprintf until Visual Studio 2015 */
|
||||||
# define vsnprintf _vsnprintf
|
# define snprintf _snprintf
|
||||||
|
# define vsnprintf _vsnprintf
|
||||||
|
# endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -193,7 +193,10 @@ NuError Nu_ReadThreadHeaders(NuArchive* pArchive, NuRecord* pRecord,
|
||||||
NuError err = kNuErrNone;
|
NuError err = kNuErrNone;
|
||||||
NuThread* pThread;
|
NuThread* pThread;
|
||||||
long count;
|
long count;
|
||||||
Boolean hasData = false;
|
Boolean needFakeData, needFakeRsrc;
|
||||||
|
|
||||||
|
needFakeData = true;
|
||||||
|
needFakeRsrc = (pRecord->recStorageType == kNuStorageExtended);
|
||||||
|
|
||||||
Assert(pArchive != NULL);
|
Assert(pArchive != NULL);
|
||||||
Assert(pRecord != NULL);
|
Assert(pRecord != NULL);
|
||||||
|
@ -215,8 +218,16 @@ NuError Nu_ReadThreadHeaders(NuArchive* pArchive, NuRecord* pRecord,
|
||||||
err = Nu_ReadThreadHeader(pArchive, pThread, pCrc);
|
err = Nu_ReadThreadHeader(pArchive, pThread, pCrc);
|
||||||
BailError(err);
|
BailError(err);
|
||||||
|
|
||||||
if (pThread->thThreadClass == kNuThreadClassData)
|
if (pThread->thThreadClass == kNuThreadClassData) {
|
||||||
hasData = true;
|
if (pThread->thThreadKind == kNuThreadKindDataFork) {
|
||||||
|
needFakeData = false;
|
||||||
|
} else if (pThread->thThreadKind == kNuThreadKindRsrcFork) {
|
||||||
|
needFakeRsrc = false;
|
||||||
|
} else if (pThread->thThreadKind == kNuThreadKindDiskImage) {
|
||||||
|
/* needFakeRsrc shouldn't be set, but clear anyway */
|
||||||
|
needFakeData = needFakeRsrc = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Some versions of ShrinkIt write an invalid thThreadEOF for disks,
|
* Some versions of ShrinkIt write an invalid thThreadEOF for disks,
|
||||||
|
@ -258,13 +269,14 @@ NuError Nu_ReadThreadHeaders(NuArchive* pArchive, NuRecord* pRecord,
|
||||||
* If "mask threadless" is set, create "fake" threads with empty
|
* If "mask threadless" is set, create "fake" threads with empty
|
||||||
* data and resource forks as needed.
|
* data and resource forks as needed.
|
||||||
*/
|
*/
|
||||||
if (!hasData && pArchive->valMaskDataless) {
|
if ((needFakeData || needFakeRsrc) && pArchive->valMaskDataless) {
|
||||||
Boolean needRsrc = (pRecord->recStorageType == kNuStorageExtended);
|
|
||||||
int firstNewThread = pRecord->recTotalThreads;
|
int firstNewThread = pRecord->recTotalThreads;
|
||||||
|
|
||||||
pRecord->recTotalThreads++;
|
if (needFakeData) {
|
||||||
pRecord->fakeThreads++;
|
pRecord->recTotalThreads++;
|
||||||
if (needRsrc) {
|
pRecord->fakeThreads++;
|
||||||
|
}
|
||||||
|
if (needFakeRsrc) {
|
||||||
pRecord->recTotalThreads++;
|
pRecord->recTotalThreads++;
|
||||||
pRecord->fakeThreads++;
|
pRecord->fakeThreads++;
|
||||||
}
|
}
|
||||||
|
@ -275,22 +287,23 @@ NuError Nu_ReadThreadHeaders(NuArchive* pArchive, NuRecord* pRecord,
|
||||||
|
|
||||||
pThread = pRecord->pThreads + firstNewThread;
|
pThread = pRecord->pThreads + firstNewThread;
|
||||||
|
|
||||||
pThread->thThreadClass = kNuThreadClassData;
|
if (needFakeData) {
|
||||||
pThread->thThreadFormat = kNuThreadFormatUncompressed;
|
|
||||||
pThread->thThreadKind = 0x0000; /* data fork */
|
|
||||||
pThread->thThreadCRC = kNuInitialThreadCRC;
|
|
||||||
pThread->thThreadEOF = 0;
|
|
||||||
pThread->thCompThreadEOF = 0;
|
|
||||||
pThread->threadIdx = Nu_GetNextThreadIdx(pArchive);
|
|
||||||
pThread->actualThreadEOF = 0;
|
|
||||||
pThread->fileOffset = -99999999;
|
|
||||||
pThread->used = false;
|
|
||||||
|
|
||||||
if (needRsrc) {
|
|
||||||
pThread++;
|
|
||||||
pThread->thThreadClass = kNuThreadClassData;
|
pThread->thThreadClass = kNuThreadClassData;
|
||||||
pThread->thThreadFormat = kNuThreadFormatUncompressed;
|
pThread->thThreadFormat = kNuThreadFormatUncompressed;
|
||||||
pThread->thThreadKind = 0x0002; /* rsrc fork */
|
pThread->thThreadKind = kNuThreadKindDataFork;
|
||||||
|
pThread->thThreadCRC = kNuInitialThreadCRC;
|
||||||
|
pThread->thThreadEOF = 0;
|
||||||
|
pThread->thCompThreadEOF = 0;
|
||||||
|
pThread->threadIdx = Nu_GetNextThreadIdx(pArchive);
|
||||||
|
pThread->actualThreadEOF = 0;
|
||||||
|
pThread->fileOffset = -99999999;
|
||||||
|
pThread->used = false;
|
||||||
|
pThread++;
|
||||||
|
}
|
||||||
|
if (needFakeRsrc) {
|
||||||
|
pThread->thThreadClass = kNuThreadClassData;
|
||||||
|
pThread->thThreadFormat = kNuThreadFormatUncompressed;
|
||||||
|
pThread->thThreadKind = kNuThreadKindRsrcFork;
|
||||||
pThread->thThreadCRC = kNuInitialThreadCRC;
|
pThread->thThreadCRC = kNuInitialThreadCRC;
|
||||||
pThread->thThreadEOF = 0;
|
pThread->thThreadEOF = 0;
|
||||||
pThread->thCompThreadEOF = 0;
|
pThread->thCompThreadEOF = 0;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
<Configuration>Debug</Configuration>
|
<Configuration>Debug</Configuration>
|
||||||
|
@ -19,13 +19,14 @@
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<PlatformToolset>v120_xp</PlatformToolset>
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<UseOfMfc>Dynamic</UseOfMfc>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<PlatformToolset>v120_xp</PlatformToolset>
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
|
@ -24,6 +24,15 @@ static const char kFssep = PATH_SEP;
|
||||||
|
|
||||||
#define kTempFile "exer-temp"
|
#define kTempFile "exer-temp"
|
||||||
|
|
||||||
|
#ifndef HAVE_STRCASECMP
|
||||||
|
static int strcasecmp(const char *str1, const char *str2)
|
||||||
|
{
|
||||||
|
while (*str1 && *str2 && toupper(*str1) == toupper(*str2))
|
||||||
|
str1++, str2++;
|
||||||
|
return (toupper(*str1) - toupper(*str2));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ===========================================================================
|
* ===========================================================================
|
||||||
|
@ -364,13 +373,25 @@ static NuError AbortFunc(ExerciserState* pState, int argc, char** argv)
|
||||||
static NuError AddFileFunc(ExerciserState* pState, int argc, char** argv)
|
static NuError AddFileFunc(ExerciserState* pState, int argc, char** argv)
|
||||||
{
|
{
|
||||||
NuFileDetails nuFileDetails;
|
NuFileDetails nuFileDetails;
|
||||||
|
int fromRsrc = false;
|
||||||
|
|
||||||
(void) pState, (void) argc, (void) argv; /* shut up, gcc */
|
(void) pState, (void) argc, (void) argv; /* shut up, gcc */
|
||||||
assert(ExerciserState_GetNuArchive(pState) != NULL);
|
assert(ExerciserState_GetNuArchive(pState) != NULL);
|
||||||
assert(argc == 2);
|
assert(argc == 3);
|
||||||
|
|
||||||
|
if (strcasecmp(argv[2], "true") == 0) {
|
||||||
|
fromRsrc = true;
|
||||||
|
} else if (strcasecmp(argv[2], "false") != 0) {
|
||||||
|
fprintf(stderr, "WARNING: fromRsrc should be 'true' or 'false'\n");
|
||||||
|
/* ignore */
|
||||||
|
}
|
||||||
|
|
||||||
memset(&nuFileDetails, 0, sizeof(nuFileDetails));
|
memset(&nuFileDetails, 0, sizeof(nuFileDetails));
|
||||||
nuFileDetails.threadID = kNuThreadIDDataFork;
|
if (fromRsrc) {
|
||||||
|
nuFileDetails.threadID = kNuThreadIDRsrcFork;
|
||||||
|
} else {
|
||||||
|
nuFileDetails.threadID = kNuThreadIDDataFork;
|
||||||
|
}
|
||||||
nuFileDetails.storageNameMOR = argv[1];
|
nuFileDetails.storageNameMOR = argv[1];
|
||||||
nuFileDetails.fileSysID = kNuFileSysUnknown;
|
nuFileDetails.fileSysID = kNuFileSysUnknown;
|
||||||
nuFileDetails.fileSysInfo = (short) kFssep;
|
nuFileDetails.fileSysInfo = (short) kFssep;
|
||||||
|
@ -378,7 +399,7 @@ static NuError AddFileFunc(ExerciserState* pState, int argc, char** argv)
|
||||||
/* fileType, extraType, storageType, dates */
|
/* fileType, extraType, storageType, dates */
|
||||||
|
|
||||||
return NuAddFile(ExerciserState_GetNuArchive(pState), argv[1],
|
return NuAddFile(ExerciserState_GetNuArchive(pState), argv[1],
|
||||||
&nuFileDetails, false, NULL);
|
&nuFileDetails, fromRsrc, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1039,7 +1060,7 @@ static const struct {
|
||||||
|
|
||||||
{ "ab", AbortFunc, 0, "", kFlagArchiveReq,
|
{ "ab", AbortFunc, 0, "", kFlagArchiveReq,
|
||||||
"Abort current changes" },
|
"Abort current changes" },
|
||||||
{ "af", AddFileFunc, 1, "filename", kFlagArchiveReq,
|
{ "af", AddFileFunc, 2, "filename fromRsrc", kFlagArchiveReq,
|
||||||
"Add file" },
|
"Add file" },
|
||||||
{ "ar", AddRecordFunc, 1, "storageName", kFlagArchiveReq,
|
{ "ar", AddRecordFunc, 1, "storageName", kFlagArchiveReq,
|
||||||
"Add record" },
|
"Add record" },
|
||||||
|
|
|
@ -16,8 +16,7 @@
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
|
||||||
#ifndef HAVE_STRCASECMP
|
#ifndef HAVE_STRCASECMP
|
||||||
static int
|
static int strcasecmp(const char *str1, const char *str2)
|
||||||
strcasecmp(const char *str1, const char *str2)
|
|
||||||
{
|
{
|
||||||
while (*str1 && *str2 && toupper(*str1) == toupper(*str2))
|
while (*str1 && *str2 && toupper(*str1) == toupper(*str2))
|
||||||
str1++, str2++;
|
str1++, str2++;
|
||||||
|
|
|
@ -298,7 +298,8 @@ int Test_AddStuff(NuArchive* pArchive)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create an empty file with a rather non-empty name.
|
* Create an empty file with a rather non-empty name. Add it as
|
||||||
|
* a resource fork.
|
||||||
*/
|
*/
|
||||||
printf("... add 'long' record\n");
|
printf("... add 'long' record\n");
|
||||||
err = NuCreateDataSourceForBuffer(kNuThreadFormatUncompressed,
|
err = NuCreateDataSourceForBuffer(kNuThreadFormatUncompressed,
|
||||||
|
@ -454,7 +455,8 @@ failed:
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Selection callback filter for "test". This gets called once per record.
|
* Selection callback filter for "test". This gets called once per record,
|
||||||
|
* twice per record for forked files.
|
||||||
*/
|
*/
|
||||||
NuResult VerifySelectionCallback(NuArchive* pArchive, void* vpProposal)
|
NuResult VerifySelectionCallback(NuArchive* pArchive, void* vpProposal)
|
||||||
{
|
{
|
||||||
|
@ -523,7 +525,9 @@ int Test_Verify(NuArchive* pArchive)
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count != kNumEntries) {
|
/* the count will be one higher than the number of records because
|
||||||
|
the last entry is forked, and each fork is tested separately */
|
||||||
|
if (count != kNumEntries + 1) {
|
||||||
fprintf(stderr, "ERROR: verified %ld when expecting %d\n", count,
|
fprintf(stderr, "ERROR: verified %ld when expecting %d\n", count,
|
||||||
kNumEntries);
|
kNumEntries);
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
|
@ -184,6 +184,7 @@ CRCList* GatherCRCs(NuArchive* pArchive)
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int rsrcCrcIdx = -1;
|
||||||
for (i = 0; i < (int)NuRecordGetNumThreads(pRecord); i++) {
|
for (i = 0; i < (int)NuRecordGetNumThreads(pRecord); i++) {
|
||||||
pThread = NuGetThread(pRecord, i);
|
pThread = NuGetThread(pRecord, i);
|
||||||
if (pThread->thThreadClass == kNuThreadClassData) {
|
if (pThread->thThreadClass == kNuThreadClassData) {
|
||||||
|
@ -194,7 +195,30 @@ CRCList* GatherCRCs(NuArchive* pArchive)
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
|
||||||
pEntries[crcIdx++] = pThread->thThreadCRC;
|
/*
|
||||||
|
* Ensure that the data fork CRC comes first. Otherwise
|
||||||
|
* we can fail if it gets rearranged. This is only a
|
||||||
|
* problem for GSHK-created archives that don't have
|
||||||
|
* threads for every fork, so "mask dataless" is create
|
||||||
|
* fake entries.
|
||||||
|
*
|
||||||
|
* The correct way to do this is to store a tuple
|
||||||
|
* { thread-kind, crc }, but that's more work.
|
||||||
|
*/
|
||||||
|
if (pThread->thThreadKind == kNuThreadKindRsrcFork) {
|
||||||
|
rsrcCrcIdx = crcIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pThread->thThreadKind == kNuThreadKindDataFork &&
|
||||||
|
rsrcCrcIdx != -1)
|
||||||
|
{
|
||||||
|
/* this is the data fork, we've already seen the
|
||||||
|
resource fork; swap entries */
|
||||||
|
pEntries[crcIdx++] = pEntries[rsrcCrcIdx];
|
||||||
|
pEntries[rsrcCrcIdx] = pThread->thThreadCRC;
|
||||||
|
} else {
|
||||||
|
pEntries[crcIdx++] = pThread->thThreadCRC;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,20 @@
|
||||||
* array of line records
|
* array of line records
|
||||||
* $ff $ff
|
* $ff $ff
|
||||||
* optional tags
|
* optional tags
|
||||||
|
*
|
||||||
|
* AppleWorks 5.0 introduced inverse and MouseText characters.
|
||||||
|
* These just use previously-unused byte ranges. The full set
|
||||||
|
* of values is thus:
|
||||||
|
* 00-1f special
|
||||||
|
* 20-7f plain ASCII
|
||||||
|
* 80-9f inverse upper (map to 40-5f)
|
||||||
|
* a0-bf inverse symbols/numbers (map to 20-3f)
|
||||||
|
* c0-df MouseText
|
||||||
|
* e0-ff inverse lower (map to 60-7f)
|
||||||
|
*
|
||||||
|
* We can output MouseText as Unicode symbols. Inverse text can use the Rich
|
||||||
|
* Text "highlight" feature; the "background color" feature doesn't seem to
|
||||||
|
* have any effect.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -55,6 +69,8 @@ int ReformatAWP::Process(const ReformatHolder* pHolder,
|
||||||
bool skipRecord;
|
bool skipRecord;
|
||||||
uint8_t lineRecCode, lineRecData;
|
uint8_t lineRecCode, lineRecData;
|
||||||
|
|
||||||
|
fMouseTextToASCII = pHolder->GetOption(ReformatHolder::kOptMouseTextToASCII) != 0;
|
||||||
|
|
||||||
if (srcLen > 65536)
|
if (srcLen > 65536)
|
||||||
fUseRTF = false;
|
fUseRTF = false;
|
||||||
|
|
||||||
|
@ -308,6 +324,7 @@ int ReformatAWP::HandleTextRecord(uint8_t lineRecData,
|
||||||
uint8_t byteCountPlusCR;
|
uint8_t byteCountPlusCR;
|
||||||
int byteCount = lineRecData;
|
int byteCount = lineRecData;
|
||||||
bool noOutput = false;
|
bool noOutput = false;
|
||||||
|
bool inverse = false;
|
||||||
int ic;
|
int ic;
|
||||||
|
|
||||||
tabFlags = Read8(pSrcPtr, pLength);
|
tabFlags = Read8(pSrcPtr, pLength);
|
||||||
|
@ -372,40 +389,40 @@ int ReformatAWP::HandleTextRecord(uint8_t lineRecData,
|
||||||
break;
|
break;
|
||||||
case kSpecialCharEnterKeyboard:
|
case kSpecialCharEnterKeyboard:
|
||||||
if (fShowEmbeds) {
|
if (fShowEmbeds) {
|
||||||
RTFSetColor(kColorBlue);
|
TextColor oldColor = RTFSetColor(kColorBlue);
|
||||||
BufPrintf("<kdb-entry>");
|
BufPrintf("<kdb-entry>");
|
||||||
RTFSetColor(kColorNone);
|
RTFSetColor(oldColor);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case kSpecialCharPrintPageNumber:
|
case kSpecialCharPrintPageNumber:
|
||||||
if (fShowEmbeds) {
|
if (fShowEmbeds) {
|
||||||
RTFSetColor(kColorBlue);
|
TextColor oldColor = RTFSetColor(kColorBlue);
|
||||||
BufPrintf("<page#>");
|
BufPrintf("<page#>");
|
||||||
RTFSetColor(kColorNone);
|
RTFSetColor(oldColor);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case kSpecialCharStickySpace:
|
case kSpecialCharStickySpace:
|
||||||
/* MSWord uses "\~", but RichEdit ignores that */
|
/* MSWord uses "\~", but RichEdit ignores that */
|
||||||
BufPrintf(" ");
|
BufPrintf("\u00a0"); // Unicode NO-BREAK SPACE
|
||||||
break;
|
break;
|
||||||
case kSpecialCharMailMerge:
|
case kSpecialCharMailMerge:
|
||||||
if (fShowEmbeds) {
|
if (fShowEmbeds) {
|
||||||
RTFSetColor(kColorBlue);
|
TextColor oldColor = RTFSetColor(kColorBlue);
|
||||||
BufPrintf("<mail-merge>");
|
BufPrintf("<mail-merge>");
|
||||||
RTFSetColor(kColorNone);
|
RTFSetColor(oldColor);
|
||||||
}
|
}
|
||||||
case kSpecialCharPrintDate:
|
case kSpecialCharPrintDate:
|
||||||
if (fShowEmbeds) {
|
if (fShowEmbeds) {
|
||||||
RTFSetColor(kColorBlue);
|
TextColor oldColor = RTFSetColor(kColorBlue);
|
||||||
BufPrintf("<date>");
|
BufPrintf("<date>");
|
||||||
RTFSetColor(kColorNone);
|
RTFSetColor(oldColor);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case kSpecialCharPrintTime:
|
case kSpecialCharPrintTime:
|
||||||
if (fShowEmbeds) {
|
if (fShowEmbeds) {
|
||||||
RTFSetColor(kColorBlue);
|
TextColor oldColor = RTFSetColor(kColorBlue);
|
||||||
BufPrintf("<time>");
|
BufPrintf("<time>");
|
||||||
RTFSetColor(kColorNone);
|
RTFSetColor(oldColor);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case kSpecialCharTab:
|
case kSpecialCharTab:
|
||||||
|
@ -421,19 +438,65 @@ int ReformatAWP::HandleTextRecord(uint8_t lineRecData,
|
||||||
default:
|
default:
|
||||||
LOGI(" AWP unhandled special char 0x%02x", ic);
|
LOGI(" AWP unhandled special char 0x%02x", ic);
|
||||||
if (fShowEmbeds) {
|
if (fShowEmbeds) {
|
||||||
RTFSetColor(kColorBlue);
|
TextColor oldColor = RTFSetColor(kColorBlue);
|
||||||
BufPrintf("^");
|
BufPrintf("^");
|
||||||
RTFSetColor(kColorNone);
|
RTFSetColor(oldColor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (fUseRTF)
|
// Character.
|
||||||
RTFPrintChar(ic);
|
bool wantInverse = false;
|
||||||
else
|
uint16_t mtLow = 0, mtHigh = 0;
|
||||||
|
|
||||||
|
if (ic >= 0x80 && ic <= 0x9f) {
|
||||||
|
// inverse upper; map 100x xxxx --> 010x xxxx
|
||||||
|
ic ^= 0xc0;
|
||||||
|
wantInverse = true;
|
||||||
|
} else if (ic >= 0xa0 && ic <= 0xbf || ic >= 0xe0 && ic <= 0xff) {
|
||||||
|
// inverse symbols; map 101x xxxx --> 001x xxxx
|
||||||
|
// inverse lower; map 111x xxxx --> 011x xxxx
|
||||||
|
ic ^= 0x80;
|
||||||
|
wantInverse = true;
|
||||||
|
} else if (ic >= 0xc0 && ic <= 0xdf) {
|
||||||
|
// MouseText characters
|
||||||
|
if (fMouseTextToASCII) {
|
||||||
|
ic = MouseTextToASCII(ic & 0x1f);
|
||||||
|
} else {
|
||||||
|
MouseTextToUTF16(ic & 0x1f, &mtLow, &mtHigh);
|
||||||
|
ic = '?';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// plain ASCII
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wantInverse && !inverse) {
|
||||||
|
inverse = true;
|
||||||
|
RTFInverseOn();
|
||||||
|
} else if (!wantInverse && inverse) {
|
||||||
|
inverse = false;
|
||||||
|
RTFInverseOff();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fUseRTF) {
|
||||||
|
if (mtLow != 0) {
|
||||||
|
if (mtHigh != 0) {
|
||||||
|
RTFPrintUTF16Char(mtHigh);
|
||||||
|
}
|
||||||
|
RTFPrintUTF16Char(mtLow);
|
||||||
|
} else {
|
||||||
|
RTFPrintChar(ic);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Plain text output.
|
||||||
BufPrintf("%c", PrintableChar(ic));
|
BufPrintf("%c", PrintableChar(ic));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (inverse) {
|
||||||
|
RTFInverseOff();
|
||||||
|
}
|
||||||
|
|
||||||
/* if there's a carriage return at the end of the line, output it now */
|
/* if there's a carriage return at the end of the line, output it now */
|
||||||
if (byteCountPlusCR & kCRatEOL) {
|
if (byteCountPlusCR & kCRatEOL) {
|
||||||
RTFNewPara();
|
RTFNewPara();
|
||||||
|
|
|
@ -16,7 +16,10 @@
|
||||||
*/
|
*/
|
||||||
class ReformatAWP : public ReformatText {
|
class ReformatAWP : public ReformatText {
|
||||||
public:
|
public:
|
||||||
ReformatAWP(void) { fShowEmbeds = true; }
|
ReformatAWP(void)
|
||||||
|
: fShowEmbeds(true),
|
||||||
|
fMouseTextToASCII(false)
|
||||||
|
{}
|
||||||
virtual ~ReformatAWP(void) {}
|
virtual ~ReformatAWP(void) {}
|
||||||
|
|
||||||
virtual void Examine(ReformatHolder* pHolder) override;
|
virtual void Examine(ReformatHolder* pHolder) override;
|
||||||
|
@ -146,6 +149,7 @@ private:
|
||||||
FileHeader fFileHeader;
|
FileHeader fFileHeader;
|
||||||
DocState fDocState;
|
DocState fDocState;
|
||||||
bool fShowEmbeds;
|
bool fShowEmbeds;
|
||||||
|
bool fMouseTextToASCII;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -81,7 +81,11 @@ void ReformatSCAssem::Examine(ReformatHolder* pHolder)
|
||||||
long srcLen = pHolder->GetSourceLen(ReformatHolder::kPartData);
|
long srcLen = pHolder->GetSourceLen(ReformatHolder::kPartData);
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
len = *ptr;
|
if (srcLen < 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = *ptr; // get length byte
|
||||||
if (len == 0 || len > srcLen)
|
if (len == 0 || len > srcLen)
|
||||||
return false; // should return an error, really
|
return false; // should return an error, really
|
||||||
if (ptr[len-1] == 0x00) {
|
if (ptr[len-1] == 0x00) {
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
*/
|
*/
|
||||||
class ReformatAsm : public ReformatText {
|
class ReformatAsm : public ReformatText {
|
||||||
public:
|
public:
|
||||||
ReformatAsm(void) {}
|
ReformatAsm(void) : fOutBuf(), fOutBufIndex(0) {}
|
||||||
virtual ~ReformatAsm(void) {}
|
virtual ~ReformatAsm(void) {}
|
||||||
|
|
||||||
void OutputStart(void) {
|
void OutputStart(void) {
|
||||||
|
@ -129,7 +129,7 @@ private:
|
||||||
*/
|
*/
|
||||||
class ReformatLISA3 : public ReformatAsm {
|
class ReformatLISA3 : public ReformatAsm {
|
||||||
public:
|
public:
|
||||||
ReformatLISA3(void) : fSymTab(NULL) {}
|
ReformatLISA3(void) : fSymTab(NULL), fSymCount(0) {}
|
||||||
virtual ~ReformatLISA3(void) {}
|
virtual ~ReformatLISA3(void) {}
|
||||||
|
|
||||||
virtual void Examine(ReformatHolder* pHolder) override;
|
virtual void Examine(ReformatHolder* pHolder) override;
|
||||||
|
@ -197,7 +197,14 @@ private:
|
||||||
*/
|
*/
|
||||||
class ReformatLISA4 : public ReformatAsm {
|
class ReformatLISA4 : public ReformatAsm {
|
||||||
public:
|
public:
|
||||||
ReformatLISA4(void) : fSymTab(NULL) {}
|
ReformatLISA4(void) :
|
||||||
|
fSymTab(NULL),
|
||||||
|
fSymCount(0),
|
||||||
|
fOpTab(0),
|
||||||
|
fAdTab(0),
|
||||||
|
fComTab(0),
|
||||||
|
fCpuType(0)
|
||||||
|
{}
|
||||||
virtual ~ReformatLISA4(void) { delete[] fSymTab; }
|
virtual ~ReformatLISA4(void) { delete[] fSymTab; }
|
||||||
|
|
||||||
virtual void Examine(ReformatHolder* pHolder) override;
|
virtual void Examine(ReformatHolder* pHolder) override;
|
||||||
|
|
|
@ -607,7 +607,7 @@ static const char gExtendedBusinessTokens[128*10] = {
|
||||||
/* 0xb8 */ "*error*\0 *error*\0 *error*\0 *error*\0 *error*\0 *error*\0 *error*\0 *error*\0 "
|
/* 0xb8 */ "*error*\0 *error*\0 *error*\0 *error*\0 *error*\0 *error*\0 *error*\0 *error*\0 "
|
||||||
/* 0xc0 */ "*error*\0 *error*\0 *error*\0 STR$(\0 HEX$(\0 CHR$(\0 LEN(\0 VAL(\0 "
|
/* 0xc0 */ "*error*\0 *error*\0 *error*\0 STR$(\0 HEX$(\0 CHR$(\0 LEN(\0 VAL(\0 "
|
||||||
/* 0xc8 */ "ASC(\0 TEN(\0 *error*\0 *error*\0 CONV(\0 CONV&(\0 CONV$(\0 CONV%(\0 "
|
/* 0xc8 */ "ASC(\0 TEN(\0 *error*\0 *error*\0 CONV(\0 CONV&(\0 CONV$(\0 CONV%(\0 "
|
||||||
/* 0xd0 */ "LEFT$(\0 RIGHT$(\0 MID$(\0 INSTR$(\0 *error*\0 *error*\0 *error*\0 *error*\0 "
|
/* 0xd0 */ "LEFT$(\0 RIGHT$(\0 MID$(\0 INSTR(\0 *error*\0 *error*\0 *error*\0 *error*\0 "
|
||||||
/* 0xd8 */ "*error*\0 *error*\0 *error*\0 *error*\0 *error*\0 *error*\0 *error*\0 *error*\0 "
|
/* 0xd8 */ "*error*\0 *error*\0 *error*\0 *error*\0 *error*\0 *error*\0 *error*\0 *error*\0 "
|
||||||
/* 0xe0 */ "*error*\0 *error*\0 *error*\0 *error*\0 *error*\0 *error*\0 *error*\0 *error*\0 "
|
/* 0xe0 */ "*error*\0 *error*\0 *error*\0 *error*\0 *error*\0 *error*\0 *error*\0 *error*\0 "
|
||||||
/* 0xe8 */ "*error*\0 *error*\0 *error*\0 *error*\0 *error*\0 *error*\0 *error*\0 *error*\0 "
|
/* 0xe8 */ "*error*\0 *error*\0 *error*\0 *error*\0 *error*\0 *error*\0 *error*\0 *error*\0 "
|
||||||
|
@ -738,7 +738,7 @@ int ReformatBusiness::Process(const ReformatHolder* pHolder,
|
||||||
(*srcPtr == 0xd0) || // LEFT$(
|
(*srcPtr == 0xd0) || // LEFT$(
|
||||||
(*srcPtr == 0xd1) || // RIGHT$(
|
(*srcPtr == 0xd1) || // RIGHT$(
|
||||||
(*srcPtr == 0xd2) || // MID$(
|
(*srcPtr == 0xd2) || // MID$(
|
||||||
(*srcPtr == 0xd3)) // INSTR$(
|
(*srcPtr == 0xd3)) // INSTR(
|
||||||
firstData = true;
|
firstData = true;
|
||||||
else
|
else
|
||||||
firstData = false;
|
firstData = false;
|
||||||
|
|
|
@ -937,9 +937,10 @@ void ReformatDisasm16::PrintHeader(const OMFSegmentHeader* pSegHdr,
|
||||||
|
|
||||||
const char* versStr;
|
const char* versStr;
|
||||||
switch (pSegHdr->GetVersion()) {
|
switch (pSegHdr->GetVersion()) {
|
||||||
case 0: versStr = "1.0"; break;
|
case 0: versStr = "0.0"; break;
|
||||||
case 1: versStr = "2.0"; break;
|
case 1: versStr = "1.0"; break;
|
||||||
case 2: versStr = "2.1"; break;
|
case 2: versStr = "2.0"; break;
|
||||||
|
case 0x82: versStr = "2.1"; break;
|
||||||
default: versStr = "(unknown)"; break;
|
default: versStr = "(unknown)"; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1058,8 +1059,9 @@ bool OMFSegmentHeader::Unpack(const uint8_t* srcBuf, long srcLen, int fileType)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fRevision = 0;
|
||||||
if (fVersion == 0) {
|
if (fVersion == 0) {
|
||||||
/* unpack OMF v1.0 */
|
/* unpack OMF v0.0 (not actually used for 16-bit code?) */
|
||||||
if (srcLen < kV0HdrMinSize)
|
if (srcLen < kV0HdrMinSize)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -1086,7 +1088,7 @@ bool OMFSegmentHeader::Unpack(const uint8_t* srcBuf, long srcLen, int fileType)
|
||||||
else
|
else
|
||||||
fDispData = fDispName + fLabLen;
|
fDispData = fDispName + fLabLen;
|
||||||
} else if (fVersion == 1) {
|
} else if (fVersion == 1) {
|
||||||
/* unpack OMF v2.0 */
|
/* unpack OMF v1.0 */
|
||||||
if (srcLen < kV1HdrMinSize)
|
if (srcLen < kV1HdrMinSize)
|
||||||
return false;
|
return false;
|
||||||
fBlockCnt = Get32LE(srcBuf + 0x00);
|
fBlockCnt = Get32LE(srcBuf + 0x00);
|
||||||
|
@ -1124,7 +1126,7 @@ bool OMFSegmentHeader::Unpack(const uint8_t* srcBuf, long srcLen, int fileType)
|
||||||
fKind = 0;
|
fKind = 0;
|
||||||
fTempOrg = 0;
|
fTempOrg = 0;
|
||||||
} else {
|
} else {
|
||||||
/* unpack OMF v2.1 */
|
/* unpack OMF v2.x */
|
||||||
if (srcLen < kV2HdrMinSize)
|
if (srcLen < kV2HdrMinSize)
|
||||||
return false;
|
return false;
|
||||||
fByteCnt = Get32LE(srcBuf + 0x00);
|
fByteCnt = Get32LE(srcBuf + 0x00);
|
||||||
|
@ -1144,7 +1146,13 @@ bool OMFSegmentHeader::Unpack(const uint8_t* srcBuf, long srcLen, int fileType)
|
||||||
fEntry = Get32LE(srcBuf + 0x24);
|
fEntry = Get32LE(srcBuf + 0x24);
|
||||||
fDispName = Get16LE(srcBuf + 0x28);
|
fDispName = Get16LE(srcBuf + 0x28);
|
||||||
fDispData = Get16LE(srcBuf + 0x2a);
|
fDispData = Get16LE(srcBuf + 0x2a);
|
||||||
fTempOrg = Get32LE(srcBuf + 0x2c);
|
if (fDispName > 0x2c) {
|
||||||
|
// v2.1 adds a 4-byte "tempOrg" field
|
||||||
|
fTempOrg = Get32LE(srcBuf + 0x2c);
|
||||||
|
fRevision = 1;
|
||||||
|
} else {
|
||||||
|
fTempOrg = 0;
|
||||||
|
}
|
||||||
|
|
||||||
fBlockCnt = 0;
|
fBlockCnt = 0;
|
||||||
fType = 0;
|
fType = 0;
|
||||||
|
@ -1192,6 +1200,8 @@ bool OMFSegmentHeader::Unpack(const uint8_t* srcBuf, long srcLen, int fileType)
|
||||||
fLoadName[kLoadNameLen] = '\0';
|
fLoadName[kLoadNameLen] = '\0';
|
||||||
|
|
||||||
segName += kLoadNameLen;
|
segName += kLoadNameLen;
|
||||||
|
} else {
|
||||||
|
fLoadName[0] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fLabLen == 0) {
|
if (fLabLen == 0) {
|
||||||
|
|
|
@ -227,7 +227,7 @@ public:
|
||||||
kTypePathName = 0x04,
|
kTypePathName = 0x04,
|
||||||
kTypeLibraryDict = 0x08,
|
kTypeLibraryDict = 0x08,
|
||||||
kTypeInit = 0x10,
|
kTypeInit = 0x10,
|
||||||
kTypeAbsoluteBank = 0x11,
|
kTypeAbsoluteBank = 0x11, // v1.0 only
|
||||||
kTypeDPStack = 0x12,
|
kTypeDPStack = 0x12,
|
||||||
} SegmentType;
|
} SegmentType;
|
||||||
typedef enum SegmentFlag {
|
typedef enum SegmentFlag {
|
||||||
|
@ -241,7 +241,7 @@ public:
|
||||||
kFlagDynamic,
|
kFlagDynamic,
|
||||||
} SegmentFlag;
|
} SegmentFlag;
|
||||||
|
|
||||||
uint8_t GetVersion(void) const { return fVersion; }
|
uint8_t GetVersion(void) const { return fVersion + (fRevision << 7); }
|
||||||
uint32_t GetSegmentLen(void) const { return fByteCnt; }
|
uint32_t GetSegmentLen(void) const { return fByteCnt; }
|
||||||
SegmentType GetSegmentType(void) const;
|
SegmentType GetSegmentType(void) const;
|
||||||
bool GetSegmentFlag(SegmentFlag flag) const;
|
bool GetSegmentFlag(SegmentFlag flag) const;
|
||||||
|
@ -254,11 +254,11 @@ public:
|
||||||
|
|
||||||
// some of these must be public in VC++6.0
|
// some of these must be public in VC++6.0
|
||||||
enum {
|
enum {
|
||||||
kMaxVersion = 2, // v0/1/2 == OMF 1.0 / 2.0 / 2.1
|
kMaxVersion = 2, // v0/1/2 == OMF 0.0 / 1.0 / 2.x
|
||||||
kLoadNameLen = 10,
|
kLoadNameLen = 10,
|
||||||
kV0HdrMinSize = 0x25,
|
kV0HdrMinSize = 0x25,
|
||||||
kV1HdrMinSize = 0x2c + kLoadNameLen,
|
kV1HdrMinSize = 0x2c + kLoadNameLen,
|
||||||
kV2HdrMinSize = 0x30 + kLoadNameLen,
|
kV2HdrMinSize = kV1HdrMinSize, // 2.1 is slightly larger; handle that elsewhere
|
||||||
kHdrMinSize = kV0HdrMinSize, // smallest of the three
|
kHdrMinSize = kV0HdrMinSize, // smallest of the three
|
||||||
kExpectedNumLen = 4,
|
kExpectedNumLen = 4,
|
||||||
kExpectedBankSize = 65536,
|
kExpectedBankSize = 65536,
|
||||||
|
@ -277,13 +277,14 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t fBlockCnt; // v0/v1
|
uint32_t fBlockCnt; // v0/v1
|
||||||
uint32_t fByteCnt; // v2
|
uint32_t fByteCnt; // [v1]/v2
|
||||||
uint32_t fResSpc;
|
uint32_t fResSpc;
|
||||||
uint32_t fLength;
|
uint32_t fLength;
|
||||||
uint8_t fType; // v0/v1
|
uint8_t fType; // v0/v1
|
||||||
uint8_t fLabLen;
|
uint8_t fLabLen;
|
||||||
uint8_t fNumLen; // (always 4)
|
uint8_t fNumLen; // (always 4)
|
||||||
uint8_t fVersion; // (0, 1, or 2)
|
uint8_t fVersion; // (0, 1, or 2)
|
||||||
|
uint8_t fRevision; // fictitious field; holds 0 or 1
|
||||||
uint32_t fBankSize; // (always 65536)
|
uint32_t fBankSize; // (always 65536)
|
||||||
uint16_t fKind; // v2
|
uint16_t fKind; // v2
|
||||||
uint32_t fOrg;
|
uint32_t fOrg;
|
||||||
|
|
|
@ -143,6 +143,7 @@ public:
|
||||||
kOptDHRAlgorithm,
|
kOptDHRAlgorithm,
|
||||||
kOptRelaxGfxTypeCheck,
|
kOptRelaxGfxTypeCheck,
|
||||||
kOptOneByteBrkCop,
|
kOptOneByteBrkCop,
|
||||||
|
kOptMouseTextToASCII,
|
||||||
|
|
||||||
kOptMAX // must be last
|
kOptMAX // must be last
|
||||||
} OptionID;
|
} OptionID;
|
||||||
|
@ -186,7 +187,7 @@ public:
|
||||||
* We want to know if it's DOS so we can relax some file-type checking,
|
* We want to know if it's DOS so we can relax some file-type checking,
|
||||||
* and we want to know if it's CP/M so we can adjust the way we think
|
* and we want to know if it's CP/M so we can adjust the way we think
|
||||||
* about text files. We want to know if it's Gutenberg because they only
|
* about text files. We want to know if it's Gutenberg because they only
|
||||||
* have one type of file, and it's indistingusihable from any other text file!
|
* have one type of file, and it's indistinguishable from any other text file!
|
||||||
*/
|
*/
|
||||||
typedef enum SourceFormat {
|
typedef enum SourceFormat {
|
||||||
kSourceFormatGeneric = 0,
|
kSourceFormatGeneric = 0,
|
||||||
|
@ -199,7 +200,16 @@ public:
|
||||||
/*
|
/*
|
||||||
* Construct/destruct our object.
|
* Construct/destruct our object.
|
||||||
*/
|
*/
|
||||||
ReformatHolder(void) {
|
ReformatHolder(void) :
|
||||||
|
fApplies(),
|
||||||
|
fFileType(0),
|
||||||
|
fAuxType(0),
|
||||||
|
fSourceFormat(kSourceFormatGeneric),
|
||||||
|
fNameExt(NULL),
|
||||||
|
fSourceBuf(),
|
||||||
|
fSourceLen(),
|
||||||
|
fErrorBuf()
|
||||||
|
{
|
||||||
int i;
|
int i;
|
||||||
for (int part = 0; part < kPartMAX; part++) {
|
for (int part = 0; part < kPartMAX; part++) {
|
||||||
if (part == kPartUnknown)
|
if (part == kPartUnknown)
|
||||||
|
@ -207,7 +217,7 @@ public:
|
||||||
for (i = 0; i < kReformatMAX; i++)
|
for (i = 0; i < kReformatMAX; i++)
|
||||||
fApplies[part][i] = kApplicUnknown;
|
fApplies[part][i] = kApplicUnknown;
|
||||||
fSourceBuf[part] = NULL;
|
fSourceBuf[part] = NULL;
|
||||||
fSourceLen[part] = NULL;
|
fSourceLen[part] = 0;
|
||||||
fErrorBuf[part] = NULL;
|
fErrorBuf[part] = NULL;
|
||||||
}
|
}
|
||||||
for (i = 0; i < kReformatMAX; i++) {
|
for (i = 0; i < kReformatMAX; i++) {
|
||||||
|
@ -215,10 +225,6 @@ public:
|
||||||
}
|
}
|
||||||
for (i = 0; i < kOptMAX; i++)
|
for (i = 0; i < kOptMAX; i++)
|
||||||
fOption[i] = 0;
|
fOption[i] = 0;
|
||||||
|
|
||||||
fFileType = fAuxType = 0;
|
|
||||||
fSourceFormat = kSourceFormatGeneric;
|
|
||||||
fNameExt = NULL;
|
|
||||||
}
|
}
|
||||||
~ReformatHolder(void) {
|
~ReformatHolder(void) {
|
||||||
LOGI("In ~ReformatHolder");
|
LOGI("In ~ReformatHolder");
|
||||||
|
@ -355,7 +361,7 @@ private:
|
||||||
char* fNameExt; // guaranteed non-NULL
|
char* fNameExt; // guaranteed non-NULL
|
||||||
|
|
||||||
/* input goes here */
|
/* input goes here */
|
||||||
uint8_t* fSourceBuf[kPartMAX];
|
uint8_t* fSourceBuf[kPartMAX];
|
||||||
long fSourceLen[kPartMAX];
|
long fSourceLen[kPartMAX];
|
||||||
|
|
||||||
char* fErrorBuf[kPartMAX];
|
char* fErrorBuf[kPartMAX];
|
||||||
|
|
|
@ -241,6 +241,28 @@ void ReformatText::RTFUnderlineOff(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ReformatText::RTFInverseOn(void)
|
||||||
|
{
|
||||||
|
if (fInverseEnabled)
|
||||||
|
return;
|
||||||
|
if (fUseRTF) {
|
||||||
|
RTFSetColor(TextColor::kColorWhite);
|
||||||
|
BufPrintf("\\highlight1 "); // black
|
||||||
|
fInverseEnabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReformatText::RTFInverseOff(void)
|
||||||
|
{
|
||||||
|
if (!fInverseEnabled)
|
||||||
|
return;
|
||||||
|
if (fUseRTF) {
|
||||||
|
RTFSetColor(TextColor::kColorNone);
|
||||||
|
BufPrintf("\\highlight0 ");
|
||||||
|
fInverseEnabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ReformatText::RTFOutlineOn(void)
|
void ReformatText::RTFOutlineOn(void)
|
||||||
{
|
{
|
||||||
if (fOutlineEnabled)
|
if (fOutlineEnabled)
|
||||||
|
@ -321,14 +343,14 @@ void ReformatText::RTFSuperscriptOff(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReformatText::RTFSetColor(TextColor color)
|
ReformatText::TextColor ReformatText::RTFSetColor(TextColor color)
|
||||||
{
|
{
|
||||||
if (color == fTextColor)
|
TextColor oldColor = fTextColor;
|
||||||
return;
|
if (color != fTextColor && fUseRTF) {
|
||||||
if (fUseRTF) {
|
|
||||||
BufPrintf("\\cf%d ", color);
|
BufPrintf("\\cf%d ", color);
|
||||||
fTextColor = color;
|
fTextColor = color;
|
||||||
}
|
}
|
||||||
|
return oldColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -586,7 +608,7 @@ void ReformatText::ConvertEOL(const uint8_t* srcBuf, long srcLen,
|
||||||
*
|
*
|
||||||
* If "stripHiBits" is set, the high bit of each character is cleared before
|
* If "stripHiBits" is set, the high bit of each character is cleared before
|
||||||
* the value is considered.
|
* the value is considered.
|
||||||
*2
|
*
|
||||||
* If "stripNulls" is true, no null values will make it through.
|
* If "stripNulls" is true, no null values will make it through.
|
||||||
*/
|
*/
|
||||||
void ReformatText::ConvertEOL(const uint8_t* srcBuf, long srcLen,
|
void ReformatText::ConvertEOL(const uint8_t* srcBuf, long srcLen,
|
||||||
|
@ -721,6 +743,61 @@ void ReformatText::BufHexDump(const uint8_t* srcBuf, long srcLen)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Thanks to http://hoop-la.ca/apple2/docs/mousetext/unicode.html for Unicode.
|
||||||
|
// Thanks to Hugh Hood for extracting the ASCII conversions from SEG.WP.
|
||||||
|
static const struct {
|
||||||
|
uint32_t unicode; // UTF-16 single code point or surrogate pair
|
||||||
|
int8_t ascii; // 7-bit ASCII
|
||||||
|
} gMouseTextConv[32] = {
|
||||||
|
{ 0xd83cdf4e, '@' }, // 00 U+1f34e RED APPLE
|
||||||
|
{ 0xd83cdf4f, '@' }, // 01 U+1f34f GREEN APPLE
|
||||||
|
//{ 0x00002316, '^' }, // 02 U+2316 POSITION INDICATOR
|
||||||
|
{ 0x000025c4, '^' }, // 02 U+25c4 BLACK LEFT-POINTING POINTER
|
||||||
|
{ 0x000023f3, '&' }, // 03 U+23f3 HOURGLASS WITH FLOWING SAND
|
||||||
|
{ 0x00002713, '\'' }, // 04 U+2713 CHECK MARK
|
||||||
|
{ 0x00002705, '\'' }, // 05 U+2705 WHITE HEAVY CHECK MARK
|
||||||
|
{ 0x000023ce, '/' }, // 06 U+23ce RETURN SYMBOL
|
||||||
|
//{ 0xd83cdf54, ':' }, // 07 U+1f354 HAMBURGER
|
||||||
|
{ 0x00002630, ':' }, // 07 U+2630 TRIGRAM FOR HEAVEN (actually want 4 lines, not 3)
|
||||||
|
{ 0x00002190, '<' }, // 08 U+2190 LEFTWARDS ARROW
|
||||||
|
{ 0x00002026, '_' }, // 09 U+2026 HORIZONTAL ELLIPSIS
|
||||||
|
{ 0x00002193, 'v' }, // 0a U+2193 DOWNWARDS ARROW
|
||||||
|
{ 0x00002191, '^' }, // 0b U+2191 UPWARDS ARROW
|
||||||
|
{ 0x00002594, '-' }, // 0c U+2594 UPPER ONE EIGHTH BLOCK
|
||||||
|
{ 0x000021b5, '/' }, // 0d U+21b5 DOWNWARDS ARROW WITH CORNER LEFTWARDS
|
||||||
|
{ 0x00002589, '$' }, // 0e U+2589 LEFT SEVEN EIGHTHS BLOCK
|
||||||
|
{ 0x000021e4, '{' }, // 0f U+21e4 LEFTWARDS ARROW TO BAR
|
||||||
|
{ 0x000021e5, '}' }, // 10 U+21e5 RIGHTWARDS ARROW TO BAR
|
||||||
|
{ 0x00002913, 'v' }, // 11 U+2913 DOWNWARDS ARROW TO BAR
|
||||||
|
{ 0x00002912, '^' }, // 12 U+2912 UPWARDS ARROW TO BAR
|
||||||
|
{ 0x00002500, '-' }, // 13 U+2500 BOX DRAWINGS LIGHT HORIZONTAL
|
||||||
|
{ 0x0000231e, 'L' }, // 14 U+231e BOTTOM LEFT CORNER
|
||||||
|
{ 0x00002192, '>' }, // 15 U+2192 UPWARDS ARROW TO BAR
|
||||||
|
//{ 0xd83dde7e, '*' }, // 16 U+1f67e CHECKER BOARD
|
||||||
|
{ 0x00002591, '*' }, // 16 U+2591 LIGHT SHADE
|
||||||
|
//{ 0xd83dde7f, '*' }, // 17 U+1f67f REVERSE CHECKER BOARD
|
||||||
|
{ 0x00002592, '*' }, // 17 U+2592 MEDIUM SHADE
|
||||||
|
{ 0xd83ddcc1, '[' }, // 18 U+1f4c1 FILE FOLDER
|
||||||
|
{ 0xd83ddcc2, ']' }, // 19 U+1f4c2 OPEN FILE FOLDER
|
||||||
|
{ 0x00002595, '|' }, // 1a U+2595 RIGHT ONE EIGHTH BLOCK
|
||||||
|
{ 0x00002666, '#' }, // 1b U+2666 BLACK DIAMOND SUIT
|
||||||
|
{ 0x0000203e, '=' }, // 1c U+203e OVERLINE -- wrong, want top/bottom
|
||||||
|
{ 0x0000256c, '#' }, // 1d U+256c BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
|
||||||
|
//{ 0xd83ddcbe, 'O' }, // 1e U+1f4be FLOPPY DISK
|
||||||
|
{ 0x000022a1, 'O' }, // 1e U+22a1 SQUARED DOT OPERATOR (seems better than 25a3)
|
||||||
|
{ 0x0000258f, '|' }, // 1f U+258f LEFT ONE EIGHTH BLOCK
|
||||||
|
};
|
||||||
|
void ReformatText::MouseTextToUTF16(uint8_t mtVal, uint16_t* pLow, uint16_t* pHigh) {
|
||||||
|
ASSERT(mtVal < 32);
|
||||||
|
|
||||||
|
*pLow = gMouseTextConv[mtVal].unicode & 0xffff;
|
||||||
|
*pHigh = gMouseTextConv[mtVal].unicode >> 16;
|
||||||
|
}
|
||||||
|
int8_t ReformatText::MouseTextToASCII(uint8_t mtVal) {
|
||||||
|
ASSERT(mtVal < 32);
|
||||||
|
return gMouseTextConv[mtVal].ascii;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ==========================================================================
|
* ==========================================================================
|
||||||
|
@ -786,11 +863,14 @@ void ReformatGraphics::SetResultBuffer(ReformatOutput* pOutput, MyDIBitmap* pDib
|
||||||
* Pass the destination buffer in "dst", source buffer in "src", source
|
* Pass the destination buffer in "dst", source buffer in "src", source
|
||||||
* length in "srcLen", and expected sizes of output in "dstRem".
|
* length in "srcLen", and expected sizes of output in "dstRem".
|
||||||
*
|
*
|
||||||
* Returns 0 on success, nonzero if the buffer is overfilled or underfilled.
|
* Returns the number of bytes unpacked on success, negative if the buffer is
|
||||||
|
* overfilled.
|
||||||
*/
|
*/
|
||||||
int ReformatGraphics::UnpackBytes(uint8_t* dst, const uint8_t* src,
|
int ReformatGraphics::UnpackBytes(uint8_t* dst, const uint8_t* src,
|
||||||
long dstRem, long srcLen)
|
long dstRem, long srcLen)
|
||||||
{
|
{
|
||||||
|
const uint8_t* origDst = dst;
|
||||||
|
|
||||||
while (srcLen > 0) {
|
while (srcLen > 0) {
|
||||||
uint8_t flag = *src++;
|
uint8_t flag = *src++;
|
||||||
int count = (flag & 0x3f) +1;
|
int count = (flag & 0x3f) +1;
|
||||||
|
@ -884,13 +964,15 @@ int ReformatGraphics::UnpackBytes(uint8_t* dst, const uint8_t* src,
|
||||||
|
|
||||||
ASSERT(srcLen == 0);
|
ASSERT(srcLen == 0);
|
||||||
|
|
||||||
/* require that we completely fill the buffer */
|
if (false) {
|
||||||
if (dstRem != 0) {
|
/* require that we completely fill the buffer */
|
||||||
LOGI(" SHR unpack dstRem at %d", dstRem);
|
if (dstRem != 0) {
|
||||||
return -1;
|
LOGI(" SHR unpack dstRem at %d", dstRem);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return dst - origDst;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -139,7 +139,7 @@ private:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Abstract base class for reformatting a graphics file into a
|
* Abstract base class for reformatting a graphics file into a
|
||||||
* device-independent bitmap..
|
* device-independent bitmap.
|
||||||
*/
|
*/
|
||||||
class ReformatGraphics: public Reformat {
|
class ReformatGraphics: public Reformat {
|
||||||
public:
|
public:
|
||||||
|
@ -189,7 +189,8 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
ReformatText()
|
ReformatText()
|
||||||
: fLeftMargin(0),
|
: fUseRTF(true),
|
||||||
|
fLeftMargin(0),
|
||||||
fRightMargin(0),
|
fRightMargin(0),
|
||||||
fPointSize(8),
|
fPointSize(8),
|
||||||
fPreMultPointSize(8),
|
fPreMultPointSize(8),
|
||||||
|
@ -197,6 +198,7 @@ public:
|
||||||
fBoldEnabled(false),
|
fBoldEnabled(false),
|
||||||
fItalicEnabled(false),
|
fItalicEnabled(false),
|
||||||
fUnderlineEnabled(false),
|
fUnderlineEnabled(false),
|
||||||
|
fInverseEnabled(false),
|
||||||
fOutlineEnabled(false),
|
fOutlineEnabled(false),
|
||||||
fShadowEnabled(false),
|
fShadowEnabled(false),
|
||||||
fSuperscriptEnabled(false),
|
fSuperscriptEnabled(false),
|
||||||
|
@ -304,6 +306,8 @@ protected:
|
||||||
void RTFItalicOff(void);
|
void RTFItalicOff(void);
|
||||||
void RTFUnderlineOn(void);
|
void RTFUnderlineOn(void);
|
||||||
void RTFUnderlineOff(void);
|
void RTFUnderlineOff(void);
|
||||||
|
void RTFInverseOn(void);
|
||||||
|
void RTFInverseOff(void);
|
||||||
void RTFParaLeft(void);
|
void RTFParaLeft(void);
|
||||||
void RTFParaRight(void);
|
void RTFParaRight(void);
|
||||||
void RTFParaCenter(void);
|
void RTFParaCenter(void);
|
||||||
|
@ -316,7 +320,7 @@ protected:
|
||||||
void RTFOutlineOff(void);
|
void RTFOutlineOff(void);
|
||||||
void RTFShadowOn(void);
|
void RTFShadowOn(void);
|
||||||
void RTFShadowOff(void);
|
void RTFShadowOff(void);
|
||||||
void RTFSetColor(TextColor color);
|
TextColor RTFSetColor(TextColor color);
|
||||||
void RTFSetFont(RTFFont font);
|
void RTFSetFont(RTFFont font);
|
||||||
void RTFSetFontSize(int points);
|
void RTFSetFontSize(int points);
|
||||||
void RTFLeftMargin(int margin);
|
void RTFLeftMargin(int margin);
|
||||||
|
@ -381,9 +385,19 @@ protected:
|
||||||
fExpBuf.Printf("%c", ch);
|
fExpBuf.Printf("%c", ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Converts a MouseText value (0-31) to a 16-bit UTF-16 value. If
|
||||||
|
// the character is in the BMP then only low is used. If it requires
|
||||||
|
// encoding as a surrogate pair, high will be nonzero.
|
||||||
|
void MouseTextToUTF16(uint8_t mtVal, uint16_t* pLow, uint16_t* pHigh);
|
||||||
|
|
||||||
|
// Converts a MouseText value (0-31) to an ASCII equivalent. This is not
|
||||||
|
// a 1:1 conversion, so it's not reversible.
|
||||||
|
int8_t MouseTextToASCII(uint8_t mtVal);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DECLARE_COPY_AND_OPEQ(ReformatText)
|
DECLARE_COPY_AND_OPEQ(ReformatText)
|
||||||
int CreateWorkBuf(void);
|
int CreateWorkBuf(void);
|
||||||
|
|
||||||
enum { kRTFUnitsPerInch = 1440 }; // TWIPS
|
enum { kRTFUnitsPerInch = 1440 }; // TWIPS
|
||||||
|
|
||||||
int fLeftMargin, fRightMargin; // for documents, in 1/10th inch
|
int fLeftMargin, fRightMargin; // for documents, in 1/10th inch
|
||||||
|
@ -393,6 +407,7 @@ private:
|
||||||
bool fBoldEnabled;
|
bool fBoldEnabled;
|
||||||
bool fItalicEnabled;
|
bool fItalicEnabled;
|
||||||
bool fUnderlineEnabled;
|
bool fUnderlineEnabled;
|
||||||
|
bool fInverseEnabled;
|
||||||
bool fOutlineEnabled;
|
bool fOutlineEnabled;
|
||||||
bool fShadowEnabled;
|
bool fShadowEnabled;
|
||||||
bool fSuperscriptEnabled;
|
bool fSuperscriptEnabled;
|
||||||
|
|
|
@ -79,6 +79,10 @@ int ReformatResourceFork::Process(const ReformatHolder* pHolder,
|
||||||
|
|
||||||
result = ReadHeader(srcBuf, srcLen, &rFileVersion, &rFileToMap,
|
result = ReadHeader(srcBuf, srcLen, &rFileVersion, &rFileToMap,
|
||||||
&rFileMapSize, &littleEndian);
|
&rFileMapSize, &littleEndian);
|
||||||
|
if (!result) {
|
||||||
|
BufPrintf("Does not appear to be a valid resource fork.\r\n");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
BufPrintf("Resource fork header (%s):\r\n",
|
BufPrintf("Resource fork header (%s):\r\n",
|
||||||
littleEndian ? "Apple IIgs little-endian" : "Macintosh big-endian");
|
littleEndian ? "Apple IIgs little-endian" : "Macintosh big-endian");
|
||||||
|
@ -93,10 +97,6 @@ int ReformatResourceFork::Process(const ReformatHolder* pHolder,
|
||||||
BufPrintf("Not an Apple IIgs resource fork (probably Macintosh).\r\n");
|
BufPrintf("Not an Apple IIgs resource fork (probably Macintosh).\r\n");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (!result) {
|
|
||||||
BufPrintf("Does not appear to be a valid resource fork.\r\n");
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* move to start of resource map */
|
/* move to start of resource map */
|
||||||
const uint8_t* mapPtr;
|
const uint8_t* mapPtr;
|
||||||
|
@ -169,7 +169,7 @@ done:
|
||||||
bool* pLittleEndian)
|
bool* pLittleEndian)
|
||||||
{
|
{
|
||||||
if (srcLen < 128) {
|
if (srcLen < 128) {
|
||||||
LOGI("ReformatResource: invalid len %d", srcLen);
|
LOGD("ReformatResource: invalid len %d", srcLen);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,11 +41,6 @@
|
||||||
* color table is reversed, with color #15 appearing first in each table.
|
* color table is reversed, with color #15 appearing first in each table.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* Convert a SHRScreen struct to a 256-color DIB.
|
|
||||||
*
|
|
||||||
* This is a reasonably generic routine shared by SHR functions.
|
|
||||||
*/
|
|
||||||
MyDIBitmap* ReformatSHR::SHRScreenToBitmap8(const SHRScreen* pScreen)
|
MyDIBitmap* ReformatSHR::SHRScreenToBitmap8(const SHRScreen* pScreen)
|
||||||
{
|
{
|
||||||
return SHRDataToBitmap8(pScreen->pixels, pScreen->scb,
|
return SHRDataToBitmap8(pScreen->pixels, pScreen->scb,
|
||||||
|
@ -55,61 +50,70 @@ MyDIBitmap* ReformatSHR::SHRScreenToBitmap8(const SHRScreen* pScreen)
|
||||||
|
|
||||||
MyDIBitmap* ReformatSHR::SHRDataToBitmap8(const uint8_t* pPixels,
|
MyDIBitmap* ReformatSHR::SHRDataToBitmap8(const uint8_t* pPixels,
|
||||||
const uint8_t* pSCB, const uint8_t* pColorTable,
|
const uint8_t* pSCB, const uint8_t* pColorTable,
|
||||||
int pixelBytesPerLine, int numScanLines,
|
unsigned int bytesPerLine, unsigned int numScanLines,
|
||||||
int outputWidth, int outputHeight)
|
unsigned int outputWidthPix, unsigned int outputHeightPix)
|
||||||
{
|
{
|
||||||
MyDIBitmap* pDib = new MyDIBitmap;
|
MyDIBitmap* pDib = new MyDIBitmap;
|
||||||
const uint8_t* pSCBStart = pSCB; // sanity check only
|
|
||||||
uint8_t* outBuf;
|
|
||||||
int line;
|
|
||||||
|
|
||||||
if (pDib == NULL)
|
if (pDib == NULL)
|
||||||
goto bail;
|
goto bail;
|
||||||
|
|
||||||
|
// We can have an odd number of pixels, which results in 1-3 empty
|
||||||
|
// spaces in the last byte. We double the 4bpp pixels, so we're
|
||||||
|
// always outputting 4 pixels per byte.
|
||||||
|
if (outputWidthPix > bytesPerLine * 4 ||
|
||||||
|
outputWidthPix < bytesPerLine * 4 - 3) {
|
||||||
|
LOGW(" Invalid params: outputWidthPix=%u bytesPerLine=%u",
|
||||||
|
outputWidthPix, bytesPerLine);
|
||||||
|
ASSERT(false);
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t* pSCBStart = pSCB; // sanity check only
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set up a DIB to hold the data. "Create" returns a pointer to the
|
* Set up a DIB to hold the data. "Create" returns a pointer to the
|
||||||
* pixel storage.
|
* pixel storage.
|
||||||
*/
|
*/
|
||||||
outBuf = (uint8_t*) pDib->Create(outputWidth, outputHeight, 8,
|
uint8_t* outBuf = (uint8_t*) pDib->Create(outputWidthPix, outputHeightPix,
|
||||||
kNumColorTables * kNumEntriesPerColorTable);
|
8, kNumColorTables * kNumEntriesPerColorTable);
|
||||||
if (outBuf == NULL) {
|
if (outBuf == NULL) {
|
||||||
delete pDib;
|
delete pDib;
|
||||||
pDib = NULL;
|
pDib = NULL;
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
int outputStride = pDib->GetPitch();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convert color palette.
|
* Convert color palette.
|
||||||
*/
|
*/
|
||||||
const uint16_t* pClrTable;
|
const uint16_t* pClrTable;
|
||||||
pClrTable = (const uint16_t*) pColorTable;
|
pClrTable = (const uint16_t*) pColorTable;
|
||||||
int table;
|
for (int table = 0; table < kNumColorTables; table++) {
|
||||||
for (table = 0; table < kNumColorTables; table++) {
|
|
||||||
for (int entry = 0; entry < kNumEntriesPerColorTable; entry++) {
|
for (int entry = 0; entry < kNumEntriesPerColorTable; entry++) {
|
||||||
GSColor(*pClrTable++, &fColorTables[table][entry]);
|
GSColor(*pClrTable++, &fColorTables[table][entry]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pDib->SetColorTable((RGBQUAD*)fColorTables);
|
pDib->SetColorTable((RGBQUAD*)fColorTables);
|
||||||
|
|
||||||
/*
|
if (false) {
|
||||||
LOGI(" SHR color table 0");
|
LOGI(" SHR color table 0");
|
||||||
int ii;
|
for (int ii = 0; ii < kNumEntriesPerColorTable; ii++) {
|
||||||
for (ii = 0; ii < kNumEntriesPerColorTable; ii++) {
|
LOGI(" %2d: 0x%02x %02x %02x",
|
||||||
LOGI(" %2d: 0x%02x %02x %02x",
|
ii,
|
||||||
ii,
|
fColorTables[0][ii].rgbRed,
|
||||||
fColorTables[0][ii].rgbRed,
|
fColorTables[0][ii].rgbGreen,
|
||||||
fColorTables[0][ii].rgbGreen,
|
fColorTables[0][ii].rgbBlue);
|
||||||
fColorTables[0][ii].rgbBlue);
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the pixels to palette indices.
|
* Set the pixels to palette indices.
|
||||||
*/
|
*/
|
||||||
|
unsigned int line;
|
||||||
for (line = 0; line < numScanLines; line++) {
|
for (line = 0; line < numScanLines; line++) {
|
||||||
bool mode640, fillMode;
|
bool mode640, fillMode;
|
||||||
int colorTableOffset;
|
int colorTableOffset;
|
||||||
int byteCount, pixelByte;
|
unsigned int byteCount;
|
||||||
uint8_t pixelVal;
|
uint8_t pixelVal;
|
||||||
uint8_t colorIndex;
|
uint8_t colorIndex;
|
||||||
int x = 0;
|
int x = 0;
|
||||||
|
@ -128,30 +132,27 @@ MyDIBitmap* ReformatSHR::SHRDataToBitmap8(const uint8_t* pPixels,
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SetPix(x, y, colridx) \
|
#define SetPix(x, y, colridx) \
|
||||||
outBuf[((outputHeight-1) - (y)) * outputWidth + (x)] = colridx
|
outBuf[((outputHeightPix-1) - (y)) * outputStride + (x)] = colridx
|
||||||
|
|
||||||
if (mode640) {
|
if (mode640) {
|
||||||
/* 320 mode, one byte becomes four non-doubled pixels (1:4) */
|
/* 640 mode, one byte becomes four non-doubled pixels (1:4) */
|
||||||
int actualBytesPerLine = outputWidth / 4;
|
unsigned int fullBytesPerLine = outputWidthPix / 4;
|
||||||
ASSERT(actualBytesPerLine <= pixelBytesPerLine);
|
ASSERT(fullBytesPerLine <= bytesPerLine);
|
||||||
|
|
||||||
for (byteCount = 0; byteCount < actualBytesPerLine; byteCount++) {
|
for (byteCount = 0; byteCount < fullBytesPerLine; byteCount++) {
|
||||||
pixelByte = *pPixels++;
|
uint8_t pixelByte = *pPixels++;
|
||||||
|
|
||||||
pixelVal = (pixelByte >> 6) & 0x03;
|
pixelVal = (pixelByte >> 6) & 0x03;
|
||||||
//rgbval = fColorLookup[colorTable][pixelVal + 12];
|
|
||||||
colorIndex = colorTableOffset + pixelVal + 8;
|
colorIndex = colorTableOffset + pixelVal + 8;
|
||||||
SetPix(x, line*2, colorIndex);
|
SetPix(x, line*2, colorIndex);
|
||||||
SetPix(x++, line*2+1, colorIndex);
|
SetPix(x++, line*2+1, colorIndex);
|
||||||
|
|
||||||
pixelVal = (pixelByte >> 4) & 0x03;
|
pixelVal = (pixelByte >> 4) & 0x03;
|
||||||
//rgbval = fColorLookup[colorTable][pixelVal + 8];
|
|
||||||
colorIndex = colorTableOffset + pixelVal + 12;
|
colorIndex = colorTableOffset + pixelVal + 12;
|
||||||
SetPix(x, line*2, colorIndex);
|
SetPix(x, line*2, colorIndex);
|
||||||
SetPix(x++, line*2+1, colorIndex);
|
SetPix(x++, line*2+1, colorIndex);
|
||||||
|
|
||||||
pixelVal = (pixelByte >> 2) & 0x03;
|
pixelVal = (pixelByte >> 2) & 0x03;
|
||||||
//rgbval = fColorLookup[colorTable][pixelVal + 4];
|
|
||||||
colorIndex = colorTableOffset + pixelVal + 0;
|
colorIndex = colorTableOffset + pixelVal + 0;
|
||||||
SetPix(x, line*2, colorIndex);
|
SetPix(x, line*2, colorIndex);
|
||||||
SetPix(x++, line*2+1, colorIndex);
|
SetPix(x++, line*2+1, colorIndex);
|
||||||
|
@ -162,18 +163,38 @@ MyDIBitmap* ReformatSHR::SHRDataToBitmap8(const uint8_t* pPixels,
|
||||||
SetPix(x, line*2, colorIndex);
|
SetPix(x, line*2, colorIndex);
|
||||||
SetPix(x++, line*2+1, colorIndex);
|
SetPix(x++, line*2+1, colorIndex);
|
||||||
}
|
}
|
||||||
for ( ; byteCount < pixelBytesPerLine; byteCount++)
|
if (byteCount != bytesPerLine) {
|
||||||
pPixels++;
|
// 1-3 pixels in last byte
|
||||||
|
uint8_t pixelByte = *pPixels++;
|
||||||
|
int rem = outputWidthPix - fullBytesPerLine * 4;
|
||||||
|
if (rem >= 3) {
|
||||||
|
pixelVal = (pixelByte >> 6) & 0x03;
|
||||||
|
colorIndex = colorTableOffset + pixelVal + 8;
|
||||||
|
SetPix(x, line * 2, colorIndex);
|
||||||
|
SetPix(x++, line * 2 + 1, colorIndex);
|
||||||
|
}
|
||||||
|
if (rem >= 2) {
|
||||||
|
pixelVal = (pixelByte >> 4) & 0x03;
|
||||||
|
colorIndex = colorTableOffset + pixelVal + 12;
|
||||||
|
SetPix(x, line * 2, colorIndex);
|
||||||
|
SetPix(x++, line * 2 + 1, colorIndex);
|
||||||
|
}
|
||||||
|
if (rem >= 1) {
|
||||||
|
pixelVal = (pixelByte >> 2) & 0x03;
|
||||||
|
colorIndex = colorTableOffset + pixelVal + 0;
|
||||||
|
SetPix(x, line * 2, colorIndex);
|
||||||
|
SetPix(x++, line * 2 + 1, colorIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* 320 mode, one byte becomes two doubled pixels (1:4) */
|
/* 320 mode, one byte becomes two doubled pixels (1:4) */
|
||||||
int actualBytesPerLine = outputWidth / 4;
|
unsigned int fullBytesPerLine = outputWidthPix / 4;
|
||||||
ASSERT(actualBytesPerLine <= pixelBytesPerLine);
|
ASSERT(fullBytesPerLine <= bytesPerLine);
|
||||||
|
|
||||||
for (byteCount = 0; byteCount < actualBytesPerLine; byteCount++) {
|
for (byteCount = 0; byteCount < fullBytesPerLine; byteCount++) {
|
||||||
pixelByte = *pPixels++;
|
uint8_t pixelByte = *pPixels++;
|
||||||
|
|
||||||
pixelVal = (pixelByte >> 4) & 0x0f;
|
pixelVal = (pixelByte >> 4) & 0x0f;
|
||||||
//rgbval = fColorLookup[colorTable][pixelVal];
|
|
||||||
colorIndex = colorTableOffset + pixelVal;
|
colorIndex = colorTableOffset + pixelVal;
|
||||||
SetPix(x, line*2, colorIndex);
|
SetPix(x, line*2, colorIndex);
|
||||||
SetPix(x++, line*2+1, colorIndex);
|
SetPix(x++, line*2+1, colorIndex);
|
||||||
|
@ -181,27 +202,31 @@ MyDIBitmap* ReformatSHR::SHRDataToBitmap8(const uint8_t* pPixels,
|
||||||
SetPix(x++, line*2+1, colorIndex);
|
SetPix(x++, line*2+1, colorIndex);
|
||||||
|
|
||||||
pixelVal = pixelByte & 0x0f;
|
pixelVal = pixelByte & 0x0f;
|
||||||
//rgbval = fColorLookup[colorTable][pixelVal];
|
|
||||||
colorIndex = colorTableOffset + pixelVal;
|
colorIndex = colorTableOffset + pixelVal;
|
||||||
SetPix(x, line*2, colorIndex);
|
SetPix(x, line*2, colorIndex);
|
||||||
SetPix(x++, line*2+1, colorIndex);
|
SetPix(x++, line*2+1, colorIndex);
|
||||||
SetPix(x, line*2, colorIndex);
|
SetPix(x, line*2, colorIndex);
|
||||||
SetPix(x++, line*2+1, colorIndex);
|
SetPix(x++, line*2+1, colorIndex);
|
||||||
}
|
}
|
||||||
for ( ; byteCount < pixelBytesPerLine; byteCount++)
|
if (byteCount != bytesPerLine) {
|
||||||
pPixels++;
|
// 1 pixel in last byte
|
||||||
|
uint8_t pixelByte = *pPixels++;
|
||||||
|
pixelVal = (pixelByte >> 4) & 0x0f;
|
||||||
|
colorIndex = colorTableOffset + pixelVal;
|
||||||
|
SetPix(x, line * 2, colorIndex);
|
||||||
|
SetPix(x++, line * 2 + 1, colorIndex);
|
||||||
|
SetPix(x, line * 2, colorIndex);
|
||||||
|
SetPix(x++, line * 2 + 1, colorIndex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#undef SetPix
|
#undef SetPix
|
||||||
|
|
||||||
/* pixel bytes can be 0-7 larger because of 8-byte boundary req */
|
ASSERT(x == outputWidthPix);
|
||||||
/* pixel count is 1x or 2x the pixel bytes */
|
|
||||||
/* output width is 1x or 2x the pixel count */
|
|
||||||
ASSERT(x >= outputWidth && x < outputWidth + (8*4));
|
|
||||||
|
|
||||||
pSCB++;
|
pSCB++;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(line == outputHeight/2);
|
ASSERT(line == outputHeightPix/2);
|
||||||
ASSERT(pSCB == pSCBStart + numScanLines);
|
ASSERT(pSCB == pSCBStart + numScanLines);
|
||||||
|
|
||||||
bail:
|
bail:
|
||||||
|
@ -441,7 +466,7 @@ int ReformatPaintworksSHR::Process(const ReformatHolder* pHolder,
|
||||||
pHolder->GetSourceBuf(part) + kPWDataOffset,
|
pHolder->GetSourceBuf(part) + kPWDataOffset,
|
||||||
kPWOutputSize,
|
kPWOutputSize,
|
||||||
pHolder->GetSourceLen(part) - kPWDataOffset);
|
pHolder->GetSourceLen(part) - kPWDataOffset);
|
||||||
if (result != 0) {
|
if (result != kPWOutputSize) {
|
||||||
LOGI("WARNING: UnpackBytes wasn't happy");
|
LOGI("WARNING: UnpackBytes wasn't happy");
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -523,7 +548,7 @@ int ReformatPackedSHR::Process(const ReformatHolder* pHolder,
|
||||||
|
|
||||||
if (UnpackBytes((uint8_t*) &fScreen,
|
if (UnpackBytes((uint8_t*) &fScreen,
|
||||||
pHolder->GetSourceBuf(part), kTotalSize,
|
pHolder->GetSourceBuf(part), kTotalSize,
|
||||||
pHolder->GetSourceLen(part)) != 0)
|
pHolder->GetSourceLen(part)) != kTotalSize)
|
||||||
{
|
{
|
||||||
LOGW(" SHR UnpackBytes failed");
|
LOGW(" SHR UnpackBytes failed");
|
||||||
goto bail;
|
goto bail;
|
||||||
|
@ -649,7 +674,9 @@ int ReformatAPFSHR::Process(const ReformatHolder* pHolder,
|
||||||
if (!haveGraphics)
|
if (!haveGraphics)
|
||||||
goto bail;
|
goto bail;
|
||||||
|
|
||||||
if (is3200) {
|
// TODO: we don't currently handle MULTIPAL with anything other than
|
||||||
|
// a 320x200 image. Fortunately this is rare.
|
||||||
|
if (is3200 && !fNonStandard) {
|
||||||
Reformat3200SHR ref3200(&fScreen, multiPal);
|
Reformat3200SHR ref3200(&fScreen, multiPal);
|
||||||
|
|
||||||
pDib = ref3200.SHR3200ToBitmap24();
|
pDib = ref3200.SHR3200ToBitmap24();
|
||||||
|
@ -699,11 +726,11 @@ int ReformatAPFSHR::UnpackMain(const uint8_t* srcPtr, long srcLen)
|
||||||
{
|
{
|
||||||
const int kColorTableSize = kNumEntriesPerColorTable * kColorTableEntrySize;
|
const int kColorTableSize = kNumEntriesPerColorTable * kColorTableEntrySize;
|
||||||
uint16_t masterMode;
|
uint16_t masterMode;
|
||||||
int numColorTables;
|
unsigned int numColorTables;
|
||||||
int* packedDataLen = NULL;
|
uint16_t* packedDataLen = NULL;
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
|
|
||||||
if (srcLen < 256) {
|
if (srcLen < 64) {
|
||||||
/* can't possibly be this small */
|
/* can't possibly be this small */
|
||||||
LOGI(" APFSHR unlikely srcLen %d", srcLen);
|
LOGI(" APFSHR unlikely srcLen %d", srcLen);
|
||||||
goto bail;
|
goto bail;
|
||||||
|
@ -712,9 +739,7 @@ int ReformatAPFSHR::UnpackMain(const uint8_t* srcPtr, long srcLen)
|
||||||
masterMode = Read16(&srcPtr, &srcLen);
|
masterMode = Read16(&srcPtr, &srcLen);
|
||||||
fPixelsPerScanLine = Read16(&srcPtr, &srcLen);
|
fPixelsPerScanLine = Read16(&srcPtr, &srcLen);
|
||||||
numColorTables = Read16(&srcPtr, &srcLen);
|
numColorTables = Read16(&srcPtr, &srcLen);
|
||||||
if (fPixelsPerScanLine < 8 || fPixelsPerScanLine > kMaxPixelsPerScan ||
|
if (fPixelsPerScanLine == 0 || fPixelsPerScanLine > kMaxPixelsPerScan) {
|
||||||
(fPixelsPerScanLine & 0x01) != 0)
|
|
||||||
{
|
|
||||||
LOGI(" APFSHR unsupported pixelsPerScanLine %d",
|
LOGI(" APFSHR unsupported pixelsPerScanLine %d",
|
||||||
fPixelsPerScanLine);
|
fPixelsPerScanLine);
|
||||||
goto bail;
|
goto bail;
|
||||||
|
@ -722,8 +747,10 @@ int ReformatAPFSHR::UnpackMain(const uint8_t* srcPtr, long srcLen)
|
||||||
|
|
||||||
LOGD(" APFSHR masterMode=0x%04x, ppsl=%d, nct=%d",
|
LOGD(" APFSHR masterMode=0x%04x, ppsl=%d, nct=%d",
|
||||||
masterMode, fPixelsPerScanLine, numColorTables);
|
masterMode, fPixelsPerScanLine, numColorTables);
|
||||||
if (numColorTables <= 0 || numColorTables > kNumColorTables) {
|
if (numColorTables == 0 || numColorTables > kNumColorTables) {
|
||||||
LOGI(" APFSHR unexpected numColorTables %d", numColorTables);
|
// Zero is valid per the spec, but we don't know how to render that.
|
||||||
|
// Rather than showing an all-black bitmap, just fail.
|
||||||
|
LOGI(" APFSHR unsupported numColorTables %d", numColorTables);
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -731,10 +758,9 @@ int ReformatAPFSHR::UnpackMain(const uint8_t* srcPtr, long srcLen)
|
||||||
* Load the color tables.
|
* Load the color tables.
|
||||||
*/
|
*/
|
||||||
memset(fScreen.colorTable, 0, sizeof(fScreen.colorTable));
|
memset(fScreen.colorTable, 0, sizeof(fScreen.colorTable));
|
||||||
int i;
|
for (unsigned int i = 0; i < numColorTables; i++) {
|
||||||
for (i = 0; i < numColorTables; i++) {
|
|
||||||
if (srcLen < kColorTableSize) {
|
if (srcLen < kColorTableSize) {
|
||||||
LOGI(" APFSHR ran out while copying color tables");
|
LOGI(" APFSHR underrun while copying color tables");
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -751,7 +777,7 @@ int ReformatAPFSHR::UnpackMain(const uint8_t* srcPtr, long srcLen)
|
||||||
* doubling so we can handle both 320 mode and 640 mode.
|
* doubling so we can handle both 320 mode and 640 mode.
|
||||||
*/
|
*/
|
||||||
fNumScanLines = Read16(&srcPtr, &srcLen);
|
fNumScanLines = Read16(&srcPtr, &srcLen);
|
||||||
if (fNumScanLines < 8 || fNumScanLines > kMaxScanLines) {
|
if (fNumScanLines == 0 || fNumScanLines > kMaxScanLines) {
|
||||||
LOGI(" APFSHR unsupported numScanLines %d", fNumScanLines);
|
LOGI(" APFSHR unsupported numScanLines %d", fNumScanLines);
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
@ -783,17 +809,6 @@ int ReformatAPFSHR::UnpackMain(const uint8_t* srcPtr, long srcLen)
|
||||||
fOutputWidth = fPixelsPerScanLine;
|
fOutputWidth = fPixelsPerScanLine;
|
||||||
fPixelBytesPerLine = (fPixelsPerScanLine + 3) / 4; // "640 mode"
|
fPixelBytesPerLine = (fPixelsPerScanLine + 3) / 4; // "640 mode"
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
* We want to create our storage such that the bytes per line is evenly
|
|
||||||
* divisible by 8. I have no idea why I'm doing this, but at this
|
|
||||||
* point I'm afraid to change it. Something with PackBytes? The APF
|
|
||||||
* filetype note doesn't say anything. It doesn't matter to the
|
|
||||||
* bitmap code, because we're feeding it in a pixel at a time, and any
|
|
||||||
* pitch requirememts are concealed within MyDIBitmap.
|
|
||||||
*
|
|
||||||
* Figure this out someday.
|
|
||||||
*/
|
|
||||||
fPixelBytesPerLine = ((fPixelBytesPerLine + 7) / 8) * 8;
|
|
||||||
fPixelStore = new uint8_t[fPixelBytesPerLine * fNumScanLines];
|
fPixelStore = new uint8_t[fPixelBytesPerLine * fNumScanLines];
|
||||||
if (fPixelStore == NULL) {
|
if (fPixelStore == NULL) {
|
||||||
LOGI(" APFSHR ERROR: alloc of %d bytes fPixelStore failed",
|
LOGI(" APFSHR ERROR: alloc of %d bytes fPixelStore failed",
|
||||||
|
@ -813,12 +828,10 @@ int ReformatAPFSHR::UnpackMain(const uint8_t* srcPtr, long srcLen)
|
||||||
/*
|
/*
|
||||||
* Get the per-scanline data.
|
* Get the per-scanline data.
|
||||||
*/
|
*/
|
||||||
packedDataLen = new int[fNumScanLines];
|
packedDataLen = new uint16_t[fNumScanLines];
|
||||||
if (packedDataLen == NULL)
|
if (packedDataLen == NULL)
|
||||||
goto bail;
|
goto bail;
|
||||||
for (i = 0; i < fNumScanLines; i++) {
|
for (unsigned int i = 0; i < fNumScanLines; i++) {
|
||||||
uint16_t mode;
|
|
||||||
|
|
||||||
packedDataLen[i] = Read16(&srcPtr, &srcLen);
|
packedDataLen[i] = Read16(&srcPtr, &srcLen);
|
||||||
if (packedDataLen[i] > fPixelsPerScanLine) {
|
if (packedDataLen[i] > fPixelsPerScanLine) {
|
||||||
/* each pixel is 2 or 4 bits, so this is a 2-4x expansion */
|
/* each pixel is 2 or 4 bits, so this is a 2-4x expansion */
|
||||||
|
@ -827,28 +840,42 @@ int ReformatAPFSHR::UnpackMain(const uint8_t* srcPtr, long srcLen)
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
|
||||||
mode = Read16(&srcPtr, &srcLen);
|
uint16_t mode = Read16(&srcPtr, &srcLen);
|
||||||
if (mode >> 8 == 0)
|
if (mode >> 8 == 0)
|
||||||
fSCBStore[i] = (uint8_t) mode;
|
fSCBStore[i] = (uint8_t) mode;
|
||||||
else {
|
else {
|
||||||
LOGI(" APFSHR odd mode 0x%04x on line %d", mode, i);
|
LOGI(" APFSHR odd mode 0x%04x on line %d", mode, i);
|
||||||
|
fSCBStore[i] = 0; // ?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Unpack the scan lines.
|
* Unpack the scan lines into the pixel storage. Some APF files
|
||||||
|
* use PackBytes in a not-quite-safe way, e.g. a 28x30 image with
|
||||||
|
* 14 bytes per line uses the 32-bit pattern repeat mode (0x3fff),
|
||||||
|
* yielding 16 bytes. We need to unpack to a temp buffer.
|
||||||
|
*
|
||||||
|
* I've found a few from 816/Paint that appear to have the wrong width
|
||||||
|
* value; they claim 320 but look like they're actually 640 (the image
|
||||||
|
* seems to be cut in half, and we unpack 2x as much data as we expect).
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < fNumScanLines; i++) {
|
for (unsigned int i = 0; i < fNumScanLines; i++) {
|
||||||
|
// PackBytes can generate 256 bytes from a single pair of bytes.
|
||||||
|
uint8_t tmpBuf[ReformatSHR::kMaxPixelsPerScan];
|
||||||
|
|
||||||
if (srcLen <= 0) {
|
if (srcLen <= 0) {
|
||||||
LOGI(" APFSHR ran out of data while unpacking pixels");
|
LOGI(" APFSHR ran out of data while unpacking pixels");
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
if (UnpackBytes(&fPixelStore[i * fPixelBytesPerLine],
|
int actual = UnpackBytes(tmpBuf, srcPtr, sizeof(tmpBuf), packedDataLen[i]);
|
||||||
srcPtr, fPixelBytesPerLine, packedDataLen[i]) != 0)
|
if (actual < (int) fPixelBytesPerLine) { // includes actual < 0
|
||||||
{
|
LOGI(" APFSHR UnpackBytes failed on line %d (pbpl=%d actual=%d)",
|
||||||
LOGI(" APFSHR UnpackBytes failed on line %d", i);
|
i, fPixelBytesPerLine, actual);
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
//LOGD("+++ unpackbytes %d pbpl=%d pdl=%d --> %d",
|
||||||
|
// i, fPixelBytesPerLine, packedDataLen[i], actual);
|
||||||
|
memcpy(&fPixelStore[i * fPixelBytesPerLine], tmpBuf, fPixelBytesPerLine);
|
||||||
|
|
||||||
srcPtr += packedDataLen[i];
|
srcPtr += packedDataLen[i];
|
||||||
srcLen -= packedDataLen[i];
|
srcLen -= packedDataLen[i];
|
||||||
|
@ -1006,8 +1033,7 @@ int Reformat3200SHR::Process(const ReformatHolder* pHolder,
|
||||||
const uint16_t* pSrcTable = (const uint16_t*)
|
const uint16_t* pSrcTable = (const uint16_t*)
|
||||||
(pHolder->GetSourceBuf(part) + sizeof(fScreen.pixels));
|
(pHolder->GetSourceBuf(part) + sizeof(fScreen.pixels));
|
||||||
uint16_t* pDstTable = (uint16_t*) fExtColorTable;
|
uint16_t* pDstTable = (uint16_t*) fExtColorTable;
|
||||||
int table;
|
for (int table = 0; table < kExtNumColorTables; table++) {
|
||||||
for (table = 0; table < kExtNumColorTables; table++) {
|
|
||||||
int entry;
|
int entry;
|
||||||
for (entry = 0; entry < kNumEntriesPerColorTable; entry++) {
|
for (entry = 0; entry < kNumEntriesPerColorTable; entry++) {
|
||||||
pDstTable[(kNumEntriesPerColorTable-1) - entry] = *pSrcTable++;
|
pDstTable[(kNumEntriesPerColorTable-1) - entry] = *pSrcTable++;
|
||||||
|
@ -1057,8 +1083,7 @@ MyDIBitmap* Reformat3200SHR::SHR3200ToBitmap24(void)
|
||||||
*/
|
*/
|
||||||
const uint16_t* pClrTable;
|
const uint16_t* pClrTable;
|
||||||
pClrTable = (const uint16_t*) fExtColorTable;
|
pClrTable = (const uint16_t*) fExtColorTable;
|
||||||
int table;
|
for (int table = 0; table < kExtNumColorTables; table++) {
|
||||||
for (table = 0; table < kExtNumColorTables; table++) {
|
|
||||||
for (int entry = 0; entry < kNumEntriesPerColorTable; entry++) {
|
for (int entry = 0; entry < kNumEntriesPerColorTable; entry++) {
|
||||||
GSColor(*pClrTable++, &colorLookup[table][entry]);
|
GSColor(*pClrTable++, &colorLookup[table][entry]);
|
||||||
//if (!table) {
|
//if (!table) {
|
||||||
|
@ -1188,8 +1213,10 @@ int Reformat3201SHR::Process(const ReformatHolder* pHolder,
|
||||||
length -= srcBuf - (pHolder->GetSourceBuf(part) +4);
|
length -= srcBuf - (pHolder->GetSourceBuf(part) +4);
|
||||||
|
|
||||||
/* now unpack the PackBytes-format pixels */
|
/* now unpack the PackBytes-format pixels */
|
||||||
if (UnpackBytes(fScreen.pixels, srcBuf, sizeof(fScreen.pixels), length) != 0)
|
if (UnpackBytes(fScreen.pixels, srcBuf, sizeof(fScreen.pixels), length)
|
||||||
|
!= sizeof(fScreen.pixels)) {
|
||||||
goto bail;
|
goto bail;
|
||||||
|
}
|
||||||
|
|
||||||
pDib = SHR3200ToBitmap24();
|
pDib = SHR3200ToBitmap24();
|
||||||
if (pDib == NULL)
|
if (pDib == NULL)
|
||||||
|
|
|
@ -69,11 +69,33 @@ public:
|
||||||
/* 16 palettes of 16 colors */
|
/* 16 palettes of 16 colors */
|
||||||
RGBQUAD fColorTables[kNumColorTables][kNumEntriesPerColorTable];
|
RGBQUAD fColorTables[kNumColorTables][kNumEntriesPerColorTable];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert a SHRScreen struct to a 256-color DIB.
|
||||||
|
*
|
||||||
|
* This is a reasonably generic routine shared by SHR functions.
|
||||||
|
*/
|
||||||
MyDIBitmap* SHRScreenToBitmap8(const SHRScreen* pScreen);
|
MyDIBitmap* SHRScreenToBitmap8(const SHRScreen* pScreen);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert tables of SHR data to an 8bpp bitmap. The expectation is
|
||||||
|
* that we double-up 320-mode pixels and double the height, so the
|
||||||
|
* output for a standard SHR image will be a 640x400 bitmap.
|
||||||
|
*
|
||||||
|
* "pPixels" is the 2-bit or 4-bit pixel data.
|
||||||
|
* "pSCB" points to an array of SCB values, one per scan line.
|
||||||
|
* "pColorTable" points to an array of 16 color tables (16 entries each).
|
||||||
|
* "bytesPerLine" is the number of whole bytes per line.
|
||||||
|
* "numScanLines" is the number of scan lines.
|
||||||
|
* "outputWidthPix" is the width, in pixels (640 for full screen).
|
||||||
|
* "outputHeightPix" is the height, in pixels (400 for full screen).
|
||||||
|
*
|
||||||
|
* If the source material has an odd width, part of the last byte will
|
||||||
|
* be empty.
|
||||||
|
*/
|
||||||
MyDIBitmap* SHRDataToBitmap8(const uint8_t* pPixels,
|
MyDIBitmap* SHRDataToBitmap8(const uint8_t* pPixels,
|
||||||
const uint8_t* pSCB, const uint8_t* pColorTable,
|
const uint8_t* pSCB, const uint8_t* pColorTable,
|
||||||
int pixelBytesPerLine, int numScanLines,
|
unsigned int bytesPerLine, unsigned int numScanLines,
|
||||||
int outputWidth, int outputHeight);
|
unsigned int outputWidthPix, unsigned int outputHeightPix);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -185,11 +207,11 @@ private:
|
||||||
/* use this for non-standard-sized images */
|
/* use this for non-standard-sized images */
|
||||||
uint8_t* fPixelStore;
|
uint8_t* fPixelStore;
|
||||||
uint8_t* fSCBStore;
|
uint8_t* fSCBStore;
|
||||||
int fNumScanLines; // #of scan lines in image
|
unsigned int fNumScanLines; // #of scan lines in image
|
||||||
int fPixelsPerScanLine;
|
unsigned int fPixelsPerScanLine;
|
||||||
int fPixelBytesPerLine;
|
unsigned int fPixelBytesPerLine;
|
||||||
int fOutputWidth;
|
unsigned int fOutputWidth;
|
||||||
int fOutputHeight; // scan lines * 2
|
unsigned int fOutputHeight; // scan lines * 2
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
<Configuration>Debug</Configuration>
|
<Configuration>Debug</Configuration>
|
||||||
|
@ -19,13 +19,13 @@
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
<PlatformToolset>v120_xp</PlatformToolset>
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
<UseOfMfc>Dynamic</UseOfMfc>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<UseOfMfc>Dynamic</UseOfMfc>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
<PlatformToolset>v120_xp</PlatformToolset>
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
<UseOfMfc>Dynamic</UseOfMfc>
|
<UseOfMfc>Dynamic</UseOfMfc>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
*/
|
*/
|
||||||
class CancelDialog : public ModelessDialog {
|
class CancelDialog : public ModelessDialog {
|
||||||
public:
|
public:
|
||||||
CancelDialog(void) {}
|
CancelDialog(void) : fpCancelFlag(NULL) {}
|
||||||
virtual ~CancelDialog(void) {}
|
virtual ~CancelDialog(void) {}
|
||||||
|
|
||||||
BOOL Create(bool* pCancelFlag, int dialogID, CWnd* pParentWnd = NULL) {
|
BOOL Create(bool* pCancelFlag, int dialogID, CWnd* pParentWnd = NULL) {
|
||||||
|
|
|
@ -62,6 +62,9 @@ void* MyDIBitmap::Create(int width, int height, int bitsPerPixel, int colorsUsed
|
||||||
assert(bitsPerPixel == 24 || bitsPerPixel == 32 || colorsUsed > 0);
|
assert(bitsPerPixel == 24 || bitsPerPixel == 32 || colorsUsed > 0);
|
||||||
|
|
||||||
// should include a warning if line stride is not a multiple of 4 bytes
|
// should include a warning if line stride is not a multiple of 4 bytes
|
||||||
|
if ((width & 0x03) != 0) {
|
||||||
|
LOGW(" DIB stride must be multiple of 4 bytes (got %d)", width);
|
||||||
|
}
|
||||||
|
|
||||||
mBitmapInfoHdr.biSize = sizeof(mBitmapInfoHdr); // BITMAPINFOHEADER
|
mBitmapInfoHdr.biSize = sizeof(mBitmapInfoHdr); // BITMAPINFOHEADER
|
||||||
mBitmapInfoHdr.biWidth = width;
|
mBitmapInfoHdr.biWidth = width;
|
||||||
|
|
|
@ -67,6 +67,11 @@ public:
|
||||||
/*
|
/*
|
||||||
* Creates a blank DIB with the requested dimensions.
|
* Creates a blank DIB with the requested dimensions.
|
||||||
*
|
*
|
||||||
|
* The DIB requires that the array of bytes defining the pixels of the
|
||||||
|
* bitmap be padded with zeroes to end on a "LONG data-type boundary",
|
||||||
|
* i.e. the start of each line must be 32-bit aligned. This is done
|
||||||
|
* automatically behind the scenes.
|
||||||
|
*
|
||||||
* Returns a pointer to the pixel storage on success, or NULL on failure.
|
* Returns a pointer to the pixel storage on success, or NULL on failure.
|
||||||
*/
|
*/
|
||||||
void* Create(int width, int height, int bitsPerPixel, int colorsUsed,
|
void* Create(int width, int height, int bitsPerPixel, int colorsUsed,
|
||||||
|
|
|
@ -46,7 +46,8 @@ class SelectFilesDialog : public CFileDialog {
|
||||||
public:
|
public:
|
||||||
SelectFilesDialog(const WCHAR* rctmpl, bool showHelp, CWnd* pParentWnd = NULL) :
|
SelectFilesDialog(const WCHAR* rctmpl, bool showHelp, CWnd* pParentWnd = NULL) :
|
||||||
CFileDialog(true, NULL, NULL, OFN_HIDEREADONLY, NULL, pParentWnd,
|
CFileDialog(true, NULL, NULL, OFN_HIDEREADONLY, NULL, pParentWnd,
|
||||||
0, FALSE /*disable Vista style*/)
|
0, FALSE /*disable Vista style*/),
|
||||||
|
fPrevWndProc(NULL)
|
||||||
{
|
{
|
||||||
// Set flags. We specify ALLOWMULTISELECT but no filename buffer;
|
// Set flags. We specify ALLOWMULTISELECT but no filename buffer;
|
||||||
// we want the multi-select behavior but we don't want to return
|
// we want the multi-select behavior but we don't want to return
|
||||||
|
|
|
@ -362,7 +362,7 @@ void CreateSimpleFont(CFont* pFont, CWnd* pWnd, const WCHAR* typeFace,
|
||||||
void GetWin32ErrorString(DWORD err, CString* pStr)
|
void GetWin32ErrorString(DWORD err, CString* pStr)
|
||||||
{
|
{
|
||||||
DWORD count;
|
DWORD count;
|
||||||
LPVOID lpMsgBuf;
|
LPVOID lpMsgBuf = NULL;
|
||||||
|
|
||||||
count = FormatMessage(
|
count = FormatMessage(
|
||||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||||
|
@ -417,6 +417,27 @@ void CheckedLoadString(CString* pString, UINT nID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float GetDesktopScaleFactor()
|
||||||
|
{
|
||||||
|
// The current scale factor for controls is determined by the settings
|
||||||
|
// for the main display at the time the application was launched. If we
|
||||||
|
// don't do this, the controls will get all scrunched together if the
|
||||||
|
// scale is over 100% (issue #53). The settings API doesn't seem to
|
||||||
|
// allow scaling things down, so we're only worried about expansion here.
|
||||||
|
//
|
||||||
|
// https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/dpi-related-apis-and-registry-settings?view=windows-11#primary-display-dpi-scale-factor
|
||||||
|
// Get desktop dc
|
||||||
|
HDC desktopDc = ::GetDC(NULL);
|
||||||
|
// Get native resolution
|
||||||
|
int horizontalDPI = GetDeviceCaps(desktopDc, LOGPIXELSX);
|
||||||
|
int verticalDPI = GetDeviceCaps(desktopDc, LOGPIXELSY);
|
||||||
|
|
||||||
|
float scaleFactor = horizontalDPI / 96.0f;
|
||||||
|
LOGD("Native DPI: %dx%d, scaleFactor=%.3f",
|
||||||
|
horizontalDPI, verticalDPI, scaleFactor);
|
||||||
|
return scaleFactor;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ===========================================================================
|
* ===========================================================================
|
||||||
|
@ -486,6 +507,7 @@ void LogHexDump(const void* vbuf, long len)
|
||||||
cp = outBuf + strlen(outBuf);
|
cp = outBuf + strlen(outBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ASSERT(cp != NULL);
|
||||||
sprintf(cp, "%02x ", *buf++);
|
sprintf(cp, "%02x ", *buf++);
|
||||||
cp += 3;
|
cp += 3;
|
||||||
}
|
}
|
||||||
|
@ -757,7 +779,7 @@ bool MatchSemicolonList(const CString set, const CString match)
|
||||||
cp++;
|
cp++;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOGI("--- No match for '%ls' in '%ls'", (LPCWSTR) match, (LPCWSTR) set);
|
LOGD("--- No match for '%ls' in '%ls'", (LPCWSTR) match, (LPCWSTR) set);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -199,6 +199,13 @@ bool IsWin9x(void);
|
||||||
*/
|
*/
|
||||||
void CheckedLoadString(CString* pString, UINT nID);
|
void CheckedLoadString(CString* pString, UINT nID);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the desktop scaling factor (usually 1.0). Assumes vertical and
|
||||||
|
* horizontal scaling is identical.
|
||||||
|
*/
|
||||||
|
float GetDesktopScaleFactor();
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ====================================
|
* ====================================
|
||||||
* Miscellaneous functions
|
* Miscellaneous functions
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
<Configuration>Debug</Configuration>
|
<Configuration>Debug</Configuration>
|
||||||
|
@ -19,13 +19,13 @@
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
<PlatformToolset>v120_xp</PlatformToolset>
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
<UseOfMfc>Dynamic</UseOfMfc>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<UseOfMfc>Dynamic</UseOfMfc>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
<PlatformToolset>v120_xp</PlatformToolset>
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
<UseOfMfc>Dynamic</UseOfMfc>
|
<UseOfMfc>Dynamic</UseOfMfc>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
<Configuration>Debug</Configuration>
|
<Configuration>Debug</Configuration>
|
||||||
|
@ -19,13 +19,14 @@
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<PlatformToolset>v120_xp</PlatformToolset>
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<UseOfMfc>Dynamic</UseOfMfc>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<PlatformToolset>v120_xp</PlatformToolset>
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user