Compare commits

...
Sign in to create a new pull request.

1013 commits
tcp ... master

Author SHA1 Message Date
b261c59379 dumb git error 2022-04-26 00:32:54 +02:00
ffd2e82749 ref_name 2022-04-26 00:28:44 +02:00
d6f6d1273e Can't do refs across repos 2022-04-26 00:26:37 +02:00
43a573f71b init and fetch 2022-04-26 00:22:42 +02:00
25d2b5519f sha 2022-04-26 00:05:46 +02:00
2620d3e928 fix ref 2022-04-26 00:03:23 +02:00
81b0396f49 Remove kitware gpg key 2022-04-25 23:58:59 +02:00
894f5e91b6 Fix repo url 2022-04-25 23:55:24 +02:00
34eccfe547 Remove wrong packages 2022-04-25 23:46:56 +02:00
b71f454076 First dnf command 2022-04-25 23:42:20 +02:00
bd3a1c03e0 RPM build 2022-04-25 23:29:51 +02:00
2b7601d9b9 GHA package build script 2022-04-25 22:43:19 +02:00
Andrea Odetti
d4aa32a34c Fix wrong disk number from command line.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2022-03-27 13:18:54 +01:00
Andrea Odetti
48d30b6b19 Merge remote-tracking branch 'upstream/master' 2022-03-26 14:48:43 +00:00
Kelvin Lee
eac88a340d
Fix spelling: "seperator" -> "separator" (PR #1071) 2022-03-25 20:11:33 +00:00
Andrea Odetti
044640cad0 Update ImGui.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2022-03-25 18:17:37 +00:00
Andrea Odetti
2ea14ee2de Merge remote-tracking branch 'upstream/master' 2022-03-25 15:24:55 +00:00
TomCh
a3774705e9
Update README.md 2022-03-23 21:43:24 +00:00
tomcw
37445c4e35 1.30.9.0: Update History.txt 2022-03-23 20:11:50 +00:00
Andrea Odetti
661de9972d Update AW.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2022-03-23 11:44:53 +00:00
Andrea Odetti
49885bbecb Merge remote-tracking branch 'upstream/master' 2022-03-23 09:50:40 +00:00
tomcw
7640ce8383 AppleWin.chm: credit @audetto for his work done on Uthernet II support (+other tweaks) 2022-03-22 19:51:25 +00:00
Andrea
500c2e50b6
Uthernet II: handle TCP connection failure. (PR #1070) 2022-03-22 19:39:49 +00:00
Andrea
cdd360bdfe
Uthernet II: implement IPRAW sockets. (PR #1069) 2022-03-22 19:30:42 +00:00
Kelvin Lee
2d4f60452f
Add ByteToHexStr() and WordToHexStr() (PR #1064)
- Simplify common StrFormat(), especially in Debugger (changes upcoming)
- Add helpers StrAppendByteAsHex() and StrAppendWordAsHex()
- Add helpers StrBufferAppendByteAsHex() and StrBufferAppendWordAsHex() for plain string buffer
2022-03-22 19:19:50 +00:00
Andrea Odetti
5a63f25b89 Update ImGui.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2022-03-19 20:25:53 +00:00
Andrea Odetti
545d6f9f4f Update from AW's master.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2022-03-19 08:50:30 +00:00
Andrea Odetti
592a26332f Merge remote-tracking branch 'upstream/master' 2022-03-19 08:26:58 +00:00
Andrea Odetti
10a5bc1da7 Merge remote-tracking branch 'upstream/master' 2022-03-18 14:51:46 +00:00
Andrea Odetti
bda732cce4 Update AW.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2022-03-15 19:45:49 +00:00
Andrea Odetti
29bc469bc1 Merge remote-tracking branch 'upstream/master' 2022-03-15 19:43:17 +00:00
Andrea Odetti
0357249317 Merge remote-tracking branch 'upstream/master' 2022-03-13 20:12:58 +00:00
Andrea Odetti
afc1477332 Merge remote-tracking branch 'upstream/master' 2022-03-13 16:43:57 +00:00
Andrea Odetti
27904182c4 Update from AW's master.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2022-03-12 14:22:03 +00:00
Andrea Odetti
de2071476e Merge remote-tracking branch 'upstream/master' 2022-03-12 14:15:48 +00:00
Andrea Odetti
01cbc4c43e Merge remote-tracking branch 'upstream/master' 2022-03-08 07:58:18 +00:00
Andrea Odetti
a6b5590744 Merge remote-tracking branch 'upstream/master' 2022-03-07 20:59:33 +00:00
Andrea Odetti
00382da4a2 Merge remote-tracking branch 'upstream/master' 2022-03-03 07:53:37 +00:00
Andrea Odetti
bb1d5ac792 Fix code after updating to AW's master.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2022-03-01 20:44:30 +00:00
Andrea Odetti
f4986708d8 Merge remote-tracking branch 'upstream/master' 2022-03-01 20:40:23 +00:00
Andrea Odetti
bbb5783fa6 Merge native support for Uthernet II from AppleWin.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2022-02-27 20:42:40 +00:00
Andrea Odetti
9006e39eaa Merge remote-tracking branch 'upstream/master' 2022-02-27 18:54:16 +00:00
Andrea Odetti
165c4532fc Exclude .vscode from git.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2022-02-27 18:53:52 +00:00
Andrea Odetti
3d247e6ee9 libwindows: implement strncpy_s from Wine.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2022-02-27 14:15:38 +00:00
Andrea Odetti
124de54aa9 Merge remote-tracking branch 'upstream/master' 2022-02-27 13:24:11 +00:00
Andrea Odetti
ccc0285930 Merge remote-tracking branch 'upstream/master' 2022-02-26 17:23:04 +00:00
Andrea Odetti
fa876ccdd9 Update ImGui.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2022-02-20 13:58:19 +00:00
Andrea Odetti
c3a8259302 Uthernet II: fix printf format specifier. 2022-02-19 16:39:46 +00:00
Andrea Odetti
d101a6c200 Fix format for UINT64.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2022-02-19 15:35:56 +00:00
Andrea Odetti
a87e709503 Merge remote-tracking branch 'origin/format_fix' 2022-02-19 15:35:22 +00:00
Andrea Odetti
375029a2c3 Fix parentheses-equality clang warning.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2022-02-18 20:11:06 +00:00
Andrea Odetti
6e630d038b Fix some format errors.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2022-02-18 13:34:50 +00:00
Andrea Odetti
6e67d1247d Merge remote-tracking branch 'upstream/master' 2022-02-18 09:50:14 +00:00
Andrea Odetti
4bd23597a7 Update AW's.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2022-02-17 09:36:26 +00:00
Andrea Odetti
048391981d Merge remote-tracking branch 'upstream/master' 2022-02-17 09:30:11 +00:00
Andrea Odetti
2464b9dc67 Merge remote-tracking branch 'upstream/master' 2022-02-15 20:44:52 +00:00
Andrea Odetti
c3fb1a7713 Update to AW's master.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2022-02-15 18:56:11 +00:00
Andrea Odetti
cfb38aa08f Merge remote-tracking branch 'upstream/master' 2022-02-15 18:53:18 +00:00
Andrea Odetti
25d0d8a05c Update to latest AW's code.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2022-02-14 08:29:08 +00:00
Andrea Odetti
db34cd326f Merge remote-tracking branch 'upstream/master'
# Conflicts:
#	source/StdAfx.h
2022-02-14 08:08:32 +00:00
Andrea Odetti
c32105ff63 Merge remote-tracking branch 'upstream/master' 2022-02-13 18:41:54 +00:00
Andrea Odetti
4f723d900b Merge remote-tracking branch 'upstream/master' 2022-02-12 18:26:41 +00:00
Andrea Odetti
058726746f Merge remote-tracking branch 'upstream/master' 2022-02-12 17:01:48 +00:00
Andrea Odetti
0419c2ca80 Update AW and ImGui.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2022-02-06 11:44:56 +00:00
Andrea Odetti
4a6315014e Merge remote-tracking branch 'upstream/master' 2022-02-06 11:37:54 +00:00
Andrea Odetti
65f9843ad8 Merge remote-tracking branch 'upstream/master' 2022-01-31 09:20:58 +00:00
Andrea Odetti
71285eebb6 sa2:: update ImGui.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2022-01-30 20:12:17 +00:00
Andrea Odetti
2a908c1889 Expose some printer settings.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2022-01-30 20:10:33 +00:00
Andrea Odetti
4f3c92bee4 sa2: realpath fails if the path does not exist.
Assume the path is absolute (for now).

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2022-01-30 18:56:21 +00:00
Andrea Odetti
ab358975ad Merge remote-tracking branch 'upstream/master' 2022-01-30 15:57:17 +00:00
Andrea Odetti
364cfcbade Debugger: add some more flags & switches.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2022-01-16 20:38:49 +00:00
Andrea Odetti
586f094393 Update ImGui.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2022-01-16 19:17:57 +00:00
Andrea Odetti
6c6409b625 Merge remote-tracking branch 'upstream/master' 2022-01-16 11:16:39 +00:00
Andrea
26a729309f
Merge pull request #62 from audetto/fullspeed
sa2: do not call VideoPresentScreen every Apple ][ frame when in full…
2022-01-14 17:36:28 +00:00
Andrea Odetti
d88ab1199d sa2: do not call VideoPresentScreen every Apple ][ frame when in full speed.
But only call it after 16ms wall clock.

Fixes https://github.com/audetto/AppleWin/issues/61

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2022-01-11 18:08:27 +00:00
Andrea Odetti
c70377fcaf ImGui: avoid non-reentrant call to VideoPresentScreen().
The debugger (which calls VideoPresentScreen) is execute in immediate mode from VideoPresentScreen.

Is this a design problem?

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2022-01-11 17:50:08 +00:00
Andrea Odetti
2abca0c0b2 Update ImGui.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2022-01-10 15:38:25 +00:00
Andrea Odetti
3348d4420e SaveState: fix some issues in the order of things.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2022-01-10 15:38:13 +00:00
Andrea Odetti
726b05cdbe cpack: extract version number from resources.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2022-01-10 12:00:18 +00:00
Andrea Odetti
0264538f4b Merge remote-tracking branch 'upstream/master' 2022-01-08 08:57:04 +00:00
Andrea Odetti
f557566824 Merge remote-tracking branch 'upstream/master' 2022-01-06 18:55:38 +00:00
Andrea Odetti
e8fe81c7cc Merge remote-tracking branch 'upstream/master' 2022-01-06 14:25:28 +00:00
Andrea Odetti
d0601d156d Merge remote-tracking branch 'upstream/master' 2022-01-05 18:45:35 +00:00
Andrea Odetti
c2a255303d Update ImGui.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2022-01-04 17:34:16 +00:00
Andrea
4a51835525
Merge pull request #56 from audetto/paths
Separate Frame from Resource folder to support native MacOS port.
2022-01-04 17:33:27 +00:00
Andrea Odetti
f03c09db76 Separate Frame from Resource folder to support native MacOS port.
Fixes https://github.com/audetto/AppleWin/issues/55

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2022-01-03 17:01:22 +00:00
Andrea Odetti
1f1a0f0c3f /proc/self/exe does not exist on MacOS.
Fixes https://github.com/audetto/AppleWin/issues/54

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2022-01-03 16:32:46 +00:00
Andrea Odetti
fa60480875 Add support for screenshot in sa2 via Alt-Ins.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2022-01-03 16:02:36 +00:00
Andrea Odetti
8de697f3f6 Clean NFrame::FrameRefreshStatus.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2022-01-03 16:01:36 +00:00
Andrea Odetti
dadba55b73 Merge remote-tracking branch 'upstream/master' 2022-01-03 15:50:27 +00:00
Andrea
89d9031752
Merge pull request #52 from audetto/cmake
Use cmake native find_package for OpenGL.
2021-12-31 16:30:21 +00:00
Andrea Odetti
d6e9a58a15 applen: add some help with the most important F keys.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-12-31 15:38:27 +00:00
Andrea Odetti
b48893fab9 Merge remote-tracking branch 'upstream/master' 2021-12-31 14:18:17 +00:00
Andrea Odetti
89842321b8 Update ImGui.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-12-31 14:18:02 +00:00
Andrea Odetti
9006bcf354 Use cmake native find_package for OpenGL.
Could solve https://github.com/audetto/AppleWin/issues/39.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-12-31 14:06:34 +00:00
Andrea Odetti
d865d5c252 Update package version.
Should really be dynamic.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-12-19 20:26:41 +00:00
Andrea Odetti
9ec45b1dab Merge remote-tracking branch 'upstream/master' 2021-12-19 20:18:37 +00:00
Andrea Odetti
e5456916fb Merge remote-tracking branch 'upstream/master' 2021-12-19 15:06:02 +00:00
Andrea Odetti
d6aa407076 Fix a couple of warnings / Pi issues.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-12-18 18:26:30 +00:00
Andrea Odetti
86122aa5f5 Update ImGui.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-12-18 16:45:49 +00:00
Andrea Odetti
913081649e Unify exceptions.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-12-18 16:43:23 +00:00
Andrea Odetti
9590d7c4f9 Merge remote-tracking branch 'upstream/master' 2021-12-18 16:38:39 +00:00
Andrea Odetti
151ef94382 Merge remote-tracking branch 'upstream/master' 2021-12-12 19:55:51 +00:00
Andrea Odetti
c758e6884c qapple: patch qapple.pro.
Qt Creator is better at debugging qapple.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-12-12 19:40:41 +00:00
Andrea Odetti
b80f7c5f50 QApple: fix VidHD.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-12-12 19:15:40 +00:00
Andrea Odetti
28e5703ab5 Update ImGui.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-12-12 18:31:53 +00:00
Andrea Odetti
6dd4390c0b libretro: update cards.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-12-11 20:26:38 +00:00
Andrea Odetti
abe7d664c5 Update from AW.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-12-11 20:08:47 +00:00
Andrea Odetti
b5b2958be1 Merge remote-tracking branch 'upstream/master'
# Conflicts:
#	source/CardManager.cpp
2021-12-11 20:08:34 +00:00
Andrea
9d8d1110ab
Merge pull request #51 from audetto/vidhd
Vidhd
2021-12-11 20:00:12 +00:00
Andrea Odetti
49d0b7535d Set SHR Alpha to 255 for maximum compatibility.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-12-11 17:14:57 +00:00
Andrea Odetti
aa7f3277d1 SDL: reset hardware in Begin, not Initialize.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-12-11 17:14:09 +00:00
Andrea Odetti
36e1c5a135 Move ExpansionCard utility to separate file.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-12-04 13:36:33 +00:00
Andrea Odetti
b740255979 Fix VidHD card insertion.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-12-04 12:47:09 +00:00
Andrea Odetti
ad6ca9c940 Move Initialise/Destroy Emulator to LinuxFrame.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-12-04 12:42:02 +00:00
Andrea Odetti
6e42274033 Uthernet2 as a Card.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-12-03 19:42:53 +00:00
Andrea Odetti
9439b1b400 Incorporate VidHD fro AW.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-12-03 18:46:23 +00:00
Andrea Odetti
79668e49e1 Merge remote-tracking branch 'upstream/master' into hd
# Conflicts:
#	source/Card.h
2021-12-03 10:15:27 +00:00
Andrea Odetti
0ae58c5815 libretro: include DiscControl in save state.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-11-30 09:23:33 +00:00
Andrea Odetti
a6eea044af Update 3rd party repos.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-11-29 20:46:16 +00:00
Andrea Odetti
36ab6a8b4f cmake changes:
1) always build libappleii as static
2) expose OpenGL as a cmake variable
2021-11-29 09:59:34 +00:00
Andrea Odetti
1f1ef6c8a3 libretro: remove poor function.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-11-28 19:35:19 +00:00
Andrea Odetti
97c3472e6e libretro: support relative paths in m3u playlists.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-11-28 19:18:38 +00:00
Andrea Odetti
e08363f141 libretro: ignore RetroArch request to re-insert the previous image.
The idea is that on a multigame floppy, only the first is bootable.
This seems the most common use case.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-11-28 18:52:40 +00:00
Andrea Odetti
24a135e042 libretro: add m3u as supported extension.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-11-28 18:51:42 +00:00
Andrea Odetti
76317c2df1 libwindows: a very tiny step towards compilation of libretro with VS.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-11-28 18:49:17 +00:00
Andrea Odetti
d46c90a82c libretro: cosmetic changes.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-11-28 14:52:58 +00:00
Andrea Odetti
a16b2b2d35 More elegant serialisation data structure.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-11-28 14:29:16 +00:00
Andrea Odetti
02740cee80 libretro: handle m3u format as gamepath.
Implement retro_set_initial_image.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-11-28 14:15:17 +00:00
Andrea Odetti
30dbfad59c libretro: implement retro_reset().
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-11-28 13:24:25 +00:00
Andrea Odetti
7037e20c0f libretro: implement save/load state.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-11-27 21:27:46 +00:00
Andrea Odetti
741849a026 Implement 2nd version of the Disc Control interface.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-11-27 13:45:34 +00:00
Andrea Odetti
117502b774 Implement base Disc Control interface.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-11-27 11:39:55 +00:00
Andrea Odetti
cca65baf97 Reduce verbosity of key logger.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-11-27 11:38:40 +00:00
Andrea Odetti
eb74e28585 libretro: fix meaning of memory ids.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-11-27 10:33:44 +00:00
Andrea Odetti
34a0baa65e Update 3rd party repos.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-11-26 21:09:16 +00:00
Andrea Odetti
fad9da0ec2 Fix for recent AW.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-11-26 20:54:28 +00:00
Andrea Odetti
f61d2073e5 Merge remote-tracking branch 'upstream/master' 2021-11-26 20:51:34 +00:00
Andrea Odetti
f080599718 libretro: support mouse retropad. 2021-11-24 18:02:27 +00:00
Andrea Odetti
6175dc8a55 Add support for memory / achievements.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-11-24 14:08:14 +00:00
Andrea Odetti
8fd124e3ae Enable printf warnings. on retro_log_cb.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-11-24 14:01:37 +00:00
Andrea Odetti
759cb5ac64 libretro: ensure game is released *before* shutdown.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-11-22 19:04:48 +00:00
Andrea Odetti
ea828795c3 Merge remote-tracking branch 'upstream/master' 2021-11-22 18:58:44 +00:00
Andrea Odetti
7c81aafad3 libretro: controllers are inserted after the Game has loaded.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-11-22 18:53:39 +00:00
Andrea
0493cade10
Merge pull request #48 from audetto/cmake
Cmake: add ability to select frontends
2021-11-22 18:50:08 +00:00
Andrea Odetti
682916415c Add libretro.h to the git repo.
To ease libretro compilation.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-11-21 20:23:16 +00:00
Andrea Odetti
7839aa0330 Add ability to select which frontend to build.
cmake .. -DBUILD_SA2=ON

or use cmake-gui.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-11-21 20:23:06 +00:00
Andrea Odetti
3128fdb449 Ensure the Plug-And-Play works as much as possible.
Reset all the IO handlers every time a card is inserted / removed.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-11-19 12:39:44 +00:00
Andrea Odetti
3c09d75573 Rewrite the Uthernet2 as Card.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-11-19 12:39:44 +00:00
Andrea
8da9f845a8
Merge pull request #46 from audetto/libretro
The retro core had been broken for a while...
2021-11-19 12:15:49 +00:00
Andrea Odetti
8c36ead724 The retro core had been broken for a while...
https://github.com/audetto/AppleWin/issues/44

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-11-19 12:11:17 +00:00
Andrea Odetti
1a302935f0 Update from AW.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-11-13 18:28:42 +00:00
Andrea Odetti
09343371d5 Merge remote-tracking branch 'upstream/master' 2021-11-13 18:20:22 +00:00
Andrea Odetti
d72e91dd2a Update from AW.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-11-13 09:31:43 +00:00
Andrea Odetti
8db8423634 Merge remote-tracking branch 'upstream/master' 2021-11-13 09:29:41 +00:00
Andrea Odetti
052ccac8d0 QApple: support yaml drops.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-11-07 16:42:31 +00:00
Andrea Odetti
ca05f42721 HD as a Card from AW.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-11-07 15:23:10 +00:00
Andrea Odetti
b4aa5fff1e Merge branch 'master' into update 2021-11-07 11:43:54 +00:00
Andrea Odetti
b36c17b198 Fix qapple crash due to error in reading config.
Fixes https://github.com/audetto/AppleWin/issues/42

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-11-03 15:49:51 +00:00
Andrea Odetti
94de9e9e00 Merge remote-tracking branch 'upstream/master' 2021-11-02 12:07:38 +00:00
Andrea Odetti
f9c9832262 Fix build.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-11-01 08:41:43 +00:00
Andrea Odetti
78dd08e329 Merge remote-tracking branch 'upstream/master' 2021-11-01 08:36:34 +00:00
Andrea Odetti
70cee11c79 Try with 2 processes.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-10-30 16:08:35 +01:00
Andrea Odetti
ae9e934193 Merge remote-tracking branch 'upstream/master' 2021-10-30 16:02:23 +01:00
Andrea Odetti
ae36dcbe30 Travis, still build master.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-10-30 16:00:21 +01:00
Andrea
783cf233a5
Merge pull request #40 from audetto/geometry
Save load SDL2 window position.
2021-10-30 15:59:02 +01:00
Andrea Odetti
0daa52f9f8 Fix SDLFrame::Destroy().
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-10-30 15:54:13 +01:00
Andrea Odetti
6e872d4bf1 Fix potential sign issue.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-10-30 15:47:49 +01:00
Andrea Odetti
e8bcb72771 Save / load window SDL2 window position.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-10-30 15:24:54 +01:00
Andrea Odetti
c7bf4f5a39 Split registry from Initialisation to make is usable sooner.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-10-30 15:24:06 +01:00
Andrea Odetti
b349ec405d Allow Uthernet card in Slot 3.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-10-30 14:16:20 +01:00
Andrea Odetti
4eb070c653 Make ImGui the default SDL2 implementation.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-10-30 14:10:14 +01:00
Andrea Odetti
b81c3c78b3 Minor changes to readme files.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-10-30 13:52:02 +01:00
Andrea Odetti
48e2668bbc Cosmetic changes to cpack generated packages.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-10-30 13:41:42 +01:00
Andrea Odetti
35452965c8 Merge remote-tracking branch 'upstream/master' 2021-10-30 11:32:32 +01:00
Andrea Odetti
60878c5a4f Small fixes to build and generate RPMs.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-10-30 11:25:00 +01:00
Andrea Odetti
448de8f6c7 Detect hardware changes and show it in gui.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-10-29 12:09:23 +01:00
Andrea Odetti
232d0e62d3 Fix qmake file.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-10-28 15:16:18 +01:00
Andrea Odetti
496a132211 Disable Windows build as too expensive.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-10-24 20:38:03 +01:00
Andrea Odetti
17131932d4 Fix clang compiler options.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-10-24 20:37:41 +01:00
Andrea Odetti
2f80b15ba4 Warn about wrong printf strings.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-10-23 20:33:30 +01:00
Andrea Odetti
b16084baf3 Merge branch 'static' into update 2021-10-23 20:27:43 +01:00
Andrea Odetti
4063198e34 Merge remote-tracking branch 'upstream/master' into update
# Conflicts:
#	source/Tfe/tfearch.cpp
2021-10-23 20:25:59 +01:00
Andrea Odetti
ed98c6ce01 Support (again) the Uthernet2 card.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-10-23 20:23:55 +01:00
Andrea Odetti
4129a78254 Incorporate AW changes.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-10-19 15:20:24 +01:00
Andrea Odetti
3f6116431f Rename gles -> glselector.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-10-19 10:03:14 +01:00
Andrea Odetti
b4f6d64034 Fix colors in OpenGL.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-10-19 09:54:55 +01:00
Andrea Odetti
030d6d5a62 Allow to use OpenGL (not GLES).
GLES is still the default, except on Mac OS X.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-10-19 09:42:33 +01:00
Andrea Odetti
3904cf58b2 Typo in cmake lib dirs.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-10-17 17:45:17 +01:00
Andrea Odetti
51b6604142 Allow code to compile as static.
To avoid the link-time interface, which does not work with Apple's linker.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-10-17 09:48:58 +01:00
Andrea Odetti
fff8fe91a9 Add some includes required by Apple clang.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-10-17 09:21:08 +01:00
Andrea Odetti
6acc688800 Changes required by latest AW code.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-10-17 09:05:32 +01:00
Andrea Odetti
56779456b5 Merge remote-tracking branch 'upstream/master' into update
# Conflicts:
#	source/Utilities.cpp
2021-10-17 09:02:17 +01:00
Andrea Odetti
28ecb6b512 Update ImGui.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-10-16 19:36:55 +01:00
Andrea Odetti
1d2d0a1a5f Update QHexView.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-10-16 19:26:11 +01:00
Andrea Odetti
0d88767320 Fix cmake list.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-10-16 19:24:03 +01:00
Andrea Odetti
53f1bf52f2 Rename interface.h -> linuxinterface.h to avoid case issues.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-10-16 19:18:53 +01:00
Andrea Odetti
b795c05b4f Add 2 more sets of link_directories.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-10-16 16:42:01 +01:00
Andrea Odetti
580be748dd Add _LIBRARY_DIR for non standard library locations.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-10-16 16:29:21 +01:00
Andrea Odetti
f21b4b8b10 Ensure a minimum C++ standard is enforced.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-10-16 16:01:27 +01:00
Andrea Odetti
8640f82323 Include pcap.h as header file. (required by Apple clang).
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-10-16 14:54:34 +01:00
Andrea Odetti
c6b9cb1ee1 StdAfx.h make include consistent with AW.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-10-16 14:50:13 +01:00
Andrea Odetti
e5b431a908 Better name for the package.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-10-11 18:48:29 +01:00
Andrea Odetti
ad40662985 Add support for creating deb packages.
rpm too, but no dependency information is added.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-10-10 20:56:19 +01:00
Andrea Odetti
1315d8050f Remove const_cast.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-07-26 19:30:40 +01:00
Andrea Odetti
fc92b7006a Merge remote-tracking branch 'upstream/master' 2021-07-26 19:28:56 +01:00
Andrea Odetti
b31d134258 Update ImGui.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-07-18 16:25:43 +01:00
Andrea Odetti
34ad2d9a23 Fix https://github.com/audetto/AppleWin/issues/35
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-07-18 16:23:55 +01:00
Andrea Odetti
75e2abbe6e Merge remote-tracking branch 'upstream/master' 2021-07-18 16:21:10 +01:00
Andrea Odetti
cd0a18de1d Updates from upstream.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-07-15 18:56:06 +01:00
tomcw
7ae208a2e5 Make a few utility funcs static 2021-07-15 18:56:06 +01:00
Andrea Odetti
db8997d652 Update ImGui.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-07-01 18:28:46 +01:00
Andrea Odetti
edf8978f17 Merge remote-tracking branch 'upstream/master' 2021-07-01 18:26:22 +01:00
Andrea Odetti
911741e411 Merge remote-tracking branch 'upstream/master' 2021-06-14 19:07:47 +01:00
Andrea Odetti
2a376f8826 Merge remote-tracking branch 'upstream/master' 2021-06-11 13:51:48 +01:00
Andrea Odetti
6cadd8dc36 Remove useless ".c_str()"
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-06-08 18:24:12 +01:00
Andrea Odetti
3617b0d5c5 Fix issue when speed changes.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-06-07 22:21:41 +01:00
Andrea Odetti
c3e8bb94a2 Expose speed setting.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-06-07 18:54:52 +01:00
Andrea Odetti
0b3e57d934 Rewrite the way full speed works.
This is more and more similar to AppleWin's logic.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-06-07 18:34:17 +01:00
Andrea Odetti
24971328ba Make sure Mockingboard slots are conistent.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-06-05 18:04:46 +01:00
Andrea Odetti
abc4a4e1d3 Safer check that Uthernet is active.
Unfortunately we cannot force a hot-activation as this will cause SegFaults in the TFE code.
It does not check if the pcap handle is good, but relies on the initialisation to have succeeded.

Unfortunately, visual feedback on the settings is lost.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-06-05 16:57:12 +01:00
Andrea Odetti
087f0f7942 More correct visualisation of virtual and physical memory.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-06-05 16:40:06 +01:00
Andrea Odetti
4205bc852f More elegant check for geos/relative mouse movement.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-06-05 16:39:28 +01:00
Andrea Odetti
d68b503d0d Fix mouse relative calculation to ensure pointer goes from minX to maxX (and Y) included.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-06-05 14:35:05 +01:00
Andrea Odetti
db71bb1a4c sa2 & mouse: fix dead y zone used to draw the menu.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-06-05 13:51:07 +01:00
Andrea Odetti
a8057a5850 Add hack to make the mouse (barely) usable with geos.
SDL_CaptureMouse() seems to be the only solution.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-06-04 18:48:02 +01:00
Andrea Odetti
8d07bb1506 Fix for https://github.com/tomcw/mb-audit
Update MB (and disk and speaker) in smaller batches.
1 ms like AppleWin.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-06-03 11:51:12 +01:00
Andrea Odetti
dcae60dede Update ImGui.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-06-01 17:25:49 +01:00
Andrea Odetti
629afb1055 Merge remote-tracking branch 'upstream/master' 2021-06-01 16:35:36 +01:00
Andrea Odetti
46333f06e7 Add filename to the tape info.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-30 20:25:34 +01:00
Andrea Odetti
4adde75a13 Tidy up cassette code.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-30 19:57:27 +01:00
Andrea Odetti
a302227470 Merge remote-tracking branch 'upstream/master' 2021-05-30 18:45:22 +01:00
Andrea Odetti
9a77ed4597 Avoid usage of unqualified "long".
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-30 16:50:05 +01:00
Andrea Odetti
e2634210ca Fix various warnings.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-29 21:50:33 +01:00
Andrea Odetti
01c5c91fbd Update QHexView.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-29 21:26:08 +01:00
Andrea Odetti
8d26fdb2b8 Update ImGui.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-29 21:25:06 +01:00
Andrea Odetti
a8c41b79fb Move FPS to the About window.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-29 18:22:10 +01:00
Andrea Odetti
2d60d802a2 Normalise paths.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-29 18:21:44 +01:00
Andrea Odetti
dfae404334 Fix option parsing.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-29 06:53:57 +01:00
Andrea Odetti
cfab12cd6f Fix compilation with gcc 8.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-29 06:53:42 +01:00
Andrea
39cf60f45a
Update linux.md 2021-05-28 19:28:21 +01:00
Andrea Odetti
9b3a3e7913 Debugger: add ability to reset cycles in the debugger.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-28 19:25:29 +01:00
Andrea Odetti
825cb59e62 Since a DialogBox stops the emulator, we need to reset the speed.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-28 19:23:51 +01:00
Andrea Odetti
83ab755144 Expose setting for Enhanced Speed.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-28 19:14:28 +01:00
Andrea Odetti
db2f9be009 sa2: add some logic to implement Full Speed.
Because we run a frame at a time, this is a bit different than in AppleWin.
Run up to 5 extra frames.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-28 19:07:58 +01:00
Andrea Odetti
96e3f37b76 Add support for Cassette Tapes.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-28 18:10:09 +01:00
Andrea Odetti
a059fad539 Add support for custom ROMs.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-27 13:40:57 +01:00
Andrea Odetti
1c94fd7150 Debugger: add registers & flags.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-27 11:33:07 +01:00
Andrea Odetti
d8ebc8dc9f Add cycle information to the Disassembly output.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-26 17:48:44 +01:00
Andrea Odetti
5c96069a3f Set g_sProgramDir so symbols can be found. 2021-05-26 17:12:19 +01:00
Andrea Odetti
77a293a4bc Merge remote-tracking branch 'origin/filenames' 2021-05-25 17:48:41 +01:00
Andrea Odetti
0f753d0bfb Save full pathname to registry.
This was already happening for Hard Disks (although in a convoluted way).
Extend to Floppy Disks.
2021-05-25 17:39:16 +01:00
Andrea Odetti
c1276a3f12 Merge remote-tracking branch 'origin/master' 2021-05-24 16:36:52 +01:00
Andrea
d5c3e7047e
Merge pull request #32 from audetto/qemu
QEMU - Fedora 34. SDL_GL_SwapInterval always fails.
2021-05-24 16:36:14 +01:00
Andrea Odetti
919fe84cfe QEMU - Fedora 34. SDL_GL_SwapInterval always fails.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-24 16:35:37 +01:00
Andrea Odetti
d4568180c5 Merge remote-tracking branch 'upstream/master' 2021-05-24 15:49:53 +01:00
Andrea
b9c199bce3
Merge pull request #31 from audetto/init
Various initialisation fixes
2021-05-24 12:57:21 +01:00
Andrea Odetti
bde3eb92b0 Improve symmetry of Constructor/Destructor functions.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-24 09:22:01 +01:00
Andrea Odetti
7b09bacb01 Initialisation: some fixes.
Ensure log file is created before it is used the first time.
Only close the log file once at the end.

https://github.com/audetto/AppleWin/issues/30

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-23 20:06:36 +01:00
Andrea Odetti
09da101cbb FileRegistry: fix problem with conf file not created.
https://github.com/audetto/AppleWin/issues/30

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-23 20:04:59 +01:00
Andrea Odetti
535ceaadc6 Ensure LogFileTimeUntilFirstKeyReadReset() gets called after every reboot.
https://github.com/audetto/AppleWin/issues/30

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-23 20:03:48 +01:00
Andrea Odetti
e9bcdb25ff Use ISO format when writing date to log.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-23 20:02:45 +01:00
Andrea Odetti
c0c5c2a7cb Update Fedora rpm list.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-22 20:53:47 +01:00
Andrea Odetti
ce54d08bc2 Support KeybReset(). 2021-05-22 17:57:45 +01:00
Andrea Odetti
9af407a089 Add support to copy text to clipboard.
Fix \n handling in paste from clipboard.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-22 17:55:51 +01:00
Andrea Odetti
16c70e4cde Fix https://github.com/audetto/AppleWin/issues/29
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-22 15:23:25 +01:00
Andrea Odetti
8a14c7e974 Minor tfe interface change.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-20 11:57:44 +01:00
Andrea Odetti
6a3ba0bd72 Merge remote-tracking branch 'upstream/master' 2021-05-20 11:50:21 +01:00
Andrea Odetti
283a74d7e7 Separate dropped file processing.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-19 11:22:08 +01:00
Andrea Odetti
1ac7710b07 Fix bug about debuggerCommand().
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-18 21:05:14 +01:00
Andrea Odetti
b65e67ed67 Ensure adaptive speed is reset before a (potential) restart.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-18 18:56:37 +01:00
Andrea Odetti
54403f74c6 Ensure the speed is reset every time the mode might change.
So we avoid that the next adaptive clock is way off.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-17 20:19:58 +01:00
Andrea Odetti
8b77575fbd Merge remote-tracking branch 'upstream/master' 2021-05-17 20:16:03 +01:00
Andrea
c48cbfb46c
Merge pull request #28 from audetto/pi
Allow compilation to work without libslirp (not available on Pi).
2021-05-17 20:11:00 +01:00
Andrea Odetti
a7e2ca580c Fix for when libslirp is indeed present.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-17 19:48:33 +01:00
Andrea Odetti
6753e62abd Allow compilation to work without libslirp (not available on Pi).
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-17 19:26:11 +01:00
Andrea Odetti
a626fc5b50 Update readme.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-16 19:00:22 +01:00
Andrea Odetti
8d21b68af0 Better support for Debugger.
Add ability to set breakpoints with mouse.


Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-16 18:53:38 +01:00
Andrea Odetti
329c19c8d9 Handle MODE_DEBUG in main loop.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-16 18:44:16 +01:00
Andrea Odetti
9d4f293a3c More Debugger related work.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-15 13:32:34 +01:00
Andrea Odetti
c36cbe5a31 Merge remote-tracking branch 'upstream/master' 2021-05-12 16:09:27 +01:00
Andrea Odetti
8ab76a9235 Update ImGui.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-12 16:00:24 +01:00
Andrea Odetti
8852154a6d Debugger: add ability to type in location of reference address.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-12 15:57:35 +01:00
Andrea Odetti
c01487d0f4 Debugger: minor format improvements.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-12 15:33:14 +01:00
Andrea Odetti
1f14d06790 Keyboard: rationalise logging.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-12 14:00:21 +01:00
Andrea Odetti
9393f04d3d Uthernet II: re-initialise dataAddress after a reset.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-12 11:02:55 +01:00
Andrea Odetti
b78f20d915 Uthernet II: fix a bug when TFE buffer size was reduced for 2+ packets.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-12 11:02:30 +01:00
Andrea Odetti
ffa5a35ba8 U2: handle TCP Disconnect. 2021-05-09 19:49:40 +01:00
Andrea Odetti
10e769735a U2: drop packets from libslirp if the queue is full (we keep at most 10).
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-09 19:49:18 +01:00
Andrea Odetti
87f232d990 Shift-Insert to paste from clipboard.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-09 19:44:28 +01:00
Andrea Odetti
36df9170bc Uthernet II: merge UDP and TCP sockets.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-08 20:51:44 +01:00
Andrea Odetti
94a20126b7 Uthernet II: fix case of using TFE.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-08 18:30:55 +01:00
Andrea Odetti
44ddf798f2 Uthernet II: add support for UDP.
Only client (as it does not bind yet).
2021-05-08 18:30:32 +01:00
Andrea Odetti
50599e9535 Debugger: compile Debug.cpp, Debugger_Help.cpp, Commands, and MemoryTextFile.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-06 15:22:14 +01:00
Andrea Odetti
22a9c64010 Uthernet 2: add settings.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-05 15:56:10 +01:00
Andrea Odetti
2f19a3980f Merge remote-tracking branch 'upstream/master' 2021-05-05 15:03:03 +01:00
Andrea Odetti
d2d241cf9c Uthernet 2: add support for TCP sockets.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-05 15:02:42 +01:00
Andrea Odetti
577a3dfa4b Uthernet 2: minor improvements on MR register.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-01 21:09:42 +01:00
Andrea Odetti
d5f2fbbb78 Uthernet 2: in Windows pcap_sendpacket() wants "u_char *" not "const u_char *".
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-01 20:54:50 +01:00
Andrea Odetti
7f3ecac9b1 Uthernet 2: add some logging to debug TCP mode (used by ii-vision). 2021-05-01 20:39:09 +01:00
Andrea Odetti
80222caa0d Comments about Uthernet II.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-01 19:42:54 +01:00
Andrea Odetti
f5c929d2a2 Merge branch 'uthernet2' 2021-05-01 19:37:55 +01:00
Andrea Odetti
2eec57ad1b Merge remote-tracking branch 'upstream/master' 2021-05-01 19:32:47 +01:00
Andrea Odetti
c50bef8cb2 Uthernet 2: introduce some #defines to ease readability.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-05-01 19:31:23 +01:00
Andrea Odetti
df0d6bdb95 Uthernet 2: new implementation based on libslirp which does not require extra capabilities.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-04-30 20:10:30 +01:00
Andrea Odetti
8fd0b0f5a6 Uthernet 2: use isprint();
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-04-28 20:36:03 +01:00
Andrea Odetti
1c9beb246b Uthernet2: move to separate folder.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-04-28 20:32:01 +01:00
Andrea Odetti
669c7124c2 Uthernet 2: draft UDP processing.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-04-28 20:27:43 +01:00
Andrea Odetti
6243d17e93 U2 logging: reduce spam and use AW's LogFileOutput.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-04-25 18:29:52 +01:00
Andrea Odetti
10fcf305b1 Uthernet 2: print some info about IPRAW.
And fix socket number.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-04-24 08:06:00 +01:00
Andrea Odetti
eeaefee89a Uthernet 2: cleanup RX_RSR logic.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-04-23 20:10:25 +01:00
Andrea Odetti
e3c4fe6ebf Fix segfault when selecting a different iface.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-04-23 20:09:00 +01:00
Andrea Odetti
5dd8e39787 Add support for the Uthernet 2 card.
Just enough to run contiki and A2osX.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-04-23 11:49:19 +01:00
Andrea
982ba0922d
Document Uthernet support. 2021-04-18 19:47:39 +01:00
Andrea Odetti
f1b9232933 Add Uthernet configuration.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-04-18 19:03:44 +01:00
Andrea Odetti
9aefc20d24 Merge remote-tracking branch 'upstream/master' 2021-04-18 18:22:55 +01:00
Andrea Odetti
9aba397034 Merge remote-tracking branch 'origin/uthernet' 2021-04-18 18:22:37 +01:00
Andrea Odetti
d7cf271a41 Merge remote-tracking branch 'origin/log' 2021-04-18 18:22:30 +01:00
Andrea Odetti
5966fa5138 Avoid a crash if the LogFile cannot be opened. 2021-04-18 18:11:53 +01:00
Andrea Odetti
b1e431d17d Uthernet: avoid assertions or memory errors in some corner cases.
1) tfe_deactivate_i: there is no need to check as the code can be called anyway. This happens is the interface could not be opened properly (lack of capabilities)
2) tfe_shutdown: free() can alreayd handle NULL. Correctly mark the pointer as freed.
2021-04-18 17:57:54 +01:00
Andrea Odetti
633e2e62ad Add missing dependencies for pcap.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-04-18 13:50:36 +01:00
Andrea Odetti
cf13ce7eb3 Merge remote-tracking branch 'origin/uthernet' 2021-04-17 20:48:57 +01:00
Andrea Odetti
e4a91e084d TFE: print libpcap version in linux too. 2021-04-17 20:48:21 +01:00
Andrea Odetti
bcd56ad8a3 Merge remote-tracking branch 'origin/uthernet' 2021-04-17 20:41:53 +01:00
Andrea Odetti
512594cca7 TFE: ensure log lines are \n-terminated. 2021-04-17 20:41:20 +01:00
Andrea Odetti
9aa7a9df95 Merge remote-tracking branch 'origin/uthernet' 2021-04-17 20:26:47 +01:00
Andrea Odetti
be8eee37b5 The description is not guaranteed to be present.
Inspired from d1b556c5c5/src/tfe/tfearch.c (L129)

See as well

https://www.tcpdump.org/manpages/pcap_findalldevs.3pcap.html
2021-04-17 20:26:09 +01:00
Andrea Odetti
bbb698ece1 Compile TFE and drop the duplicate.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-04-17 19:07:21 +01:00
Andrea Odetti
4683883c2b Merge remote-tracking branch 'origin/uthernet' 2021-04-17 18:47:50 +01:00
Andrea Odetti
4c51309e3b libpcap in linux: we can justuse the libpacap provided and link to it directly.
Moreover, add a #include <StdAfx.h> to include windows types (only needed in linux).
2021-04-17 18:44:48 +01:00
Andrea Odetti
6b6a238bcf Make tfe easier to compile in linux. 2021-04-17 18:44:40 +01:00
Andrea
99907c9a89
Update linux.md 2021-04-13 08:53:46 +01:00
Andrea
73db44ac73
Update linux.md 2021-04-13 08:53:09 +01:00
Andrea
e6bfe89722
Update linux.md 2021-04-13 08:48:52 +01:00
Andrea Odetti
947ae1b7a4 Merge remote-tracking branch 'upstream/master' 2021-04-13 08:39:39 +01:00
Andrea Odetti
ee48c0d567 Merge remote-tracking branch 'upstream/master' 2021-04-06 08:22:40 +01:00
Andrea Odetti
6a75299826 Add About dialog.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-04-04 19:21:04 +01:00
Andrea Odetti
4c8b74332c Update ImGui.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-04-04 18:59:10 +01:00
Andrea Odetti
7a8a162d78 AutoSave configuration for ease of use.
Add option to load .ini file from different location.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-04-04 18:56:53 +01:00
Andrea Odetti
f144cb037f SDL: Support Mouse.
In ImGui there are a couple of issues:
1) it ignores the menu area when computing relative motion
2) does not work well with windowed video

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-04-04 16:44:04 +01:00
Andrea Odetti
dd683e8e48 ImGui: display all current registry settings.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-04-04 14:33:04 +01:00
Andrea Odetti
e40d16c2d7 Merge remote-tracking branch 'upstream/master' 2021-04-03 10:03:45 +01:00
Andrea Odetti
da1648706d Update info in README.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-04-03 10:03:26 +01:00
Andrea Odetti
783ccb9060 Add 50/60 Hz switch.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-04-03 09:55:05 +01:00
Andrea Odetti
362c9877d4 ImGui settings: add video.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-04-03 09:46:56 +01:00
Andrea Odetti
29821c9e7c Disk Status: make it more readable.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-04-03 08:47:29 +01:00
Andrea Odetti
25dc50d83c Add settings / diagnostics about disks.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-04-01 16:04:50 +01:00
Andrea Odetti
953571a433 Better way to display non editable options.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-03-29 14:14:57 +01:00
Andrea Odetti
bb15de8e99 Merge remote-tracking branch 'upstream/master' 2021-03-29 09:05:16 +01:00
Andrea Odetti
4002193584 Merge remote-tracking branch 'upstream/master' 2021-03-28 20:07:09 +01:00
Andrea Odetti
cdf5ca8419 Update ImGui.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-03-28 20:06:51 +01:00
Andrea Odetti
f44428352c Add few more options to the setting window.
Apple 2 Type and Slots.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-03-28 20:05:30 +01:00
Andrea
90cc5732f9
Update README.md 2021-03-27 20:19:03 +00:00
Andrea Odetti
341f1aaac1 Fix uninitialised value.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-03-27 20:11:54 +00:00
Andrea Odetti
a2f89c78db Fix adaptive speed on snapshot load.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-03-27 20:11:54 +00:00
Andrea Odetti
b56ccf8eb4 Add Reset(s) buttons.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-03-27 20:11:47 +00:00
Andrea Odetti
11c44233b4 Revisit initialisation to drive it all from the FrameBase.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-03-27 18:48:05 +00:00
Andrea Odetti
8dc4c042a2 Drag&Drop State files.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-03-27 14:45:40 +00:00
Andrea Odetti
3e03e3ba57 Add more audio settings / diagnostics.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-03-27 14:45:40 +00:00
Andrea Odetti
fec69e1f72 Untabify.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-03-27 14:45:31 +00:00
Andrea Odetti
64e329c054 Speech supported (with recent latest AW code).
Closes

https://github.com/audetto/AppleWin/issues/8

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-03-24 18:56:50 +00:00
Andrea Odetti
488adf2313 Merge remote-tracking branch 'upstream/master' 2021-03-24 17:52:44 +00:00
Andrea Odetti
177858b055 Run missing untabify.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-03-22 10:37:52 +00:00
Andrea
fd2c690ea5
Update README.md 2021-03-22 08:14:56 +00:00
Andrea
ff82eb4a61
Update README.md 2021-03-22 08:14:11 +00:00
Andrea
165830d488
Update linux.md 2021-03-22 08:08:31 +00:00
Andrea Odetti
5b24df0fc9 More fancy disk drive information in settings.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-03-21 20:07:27 +00:00
Andrea Odetti
3d8ac1bee3 Add support for drag & drop in Drive 1.
And add disk names in the setting window.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-03-21 16:32:48 +00:00
Andrea Odetti
cbf9b078c6 sa2: remove multithreading.
Obsolete with recent Pi4 hardware, and even with Pi3, advantage is little.
2021-03-21 12:08:30 +00:00
Andrea Odetti
a583fd75f3 Add debugger color scheme choice.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-03-20 19:39:25 +00:00
Andrea Odetti
7025bcd457 Use correct memory editor.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-03-20 17:00:45 +00:00
Andrea Odetti
24c105ffd5 Colorise debugger console.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-03-20 17:00:29 +00:00
Andrea Odetti
f795147611 Add syntax highlight to the disassembler.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-03-20 10:29:25 +00:00
Andrea
458bbf4634
Update README.md 2021-03-19 07:49:10 +00:00
Andrea
f7848852c6
Update linux.md 2021-03-19 07:41:14 +00:00
Andrea Odetti
3e768c4d78 Use plain characters for branches.
We do not have unicode support apparently.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-03-18 19:48:26 +00:00
Andrea
199a344e37
Merge pull request #27 from audetto/memory
Memory
2021-03-18 19:41:15 +00:00
Andrea Odetti
ea4891f1f6 Start with more sensible values: 2x video size.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-03-18 19:40:30 +00:00
Andrea Odetti
4fca44ed6f Custom opcode formatter to match AppleWin. 2021-03-18 19:40:02 +00:00
Andrea Odetti
d029befe6a Merge branch 'master' into memory
# Conflicts:
#	source/Debugger/Debugger_Disassembler.cpp
2021-03-18 18:55:27 +00:00
Andrea Odetti
c09827f332 Merge remote-tracking branch 'upstream/master' 2021-03-18 18:52:16 +00:00
Andrea Odetti
5a3618912f Convert only up to 0.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-03-18 18:51:24 +00:00
Andrea Odetti
0f66cd6f85 Add DebuggerConsole and improve disassembler.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-03-14 20:40:37 +00:00
Andrea Odetti
49cae397d6 Update ImGui.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-03-14 15:22:53 +00:00
Andrea Odetti
5cb5108409 Remove (wrong) usage of BeginChild and let ImGui deal with the first frozen header row.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-03-14 15:22:20 +00:00
Andrea Odetti
32c200d65c Factor common code to change AppMode.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-03-14 11:31:00 +00:00
Andrea Odetti
5230a6a558 Add ability to step emulator.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-03-14 11:14:03 +00:00
Andrea Odetti
7152b82a45 untabify main.cpp
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-03-14 10:04:14 +00:00
Andrea Odetti
405ea13ba2 Move Execution to SDLFrame for ease of use in debugger.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-03-14 10:02:19 +00:00
Andrea Odetti
f7c6dfc1b9 Remove dead code.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-03-14 09:59:19 +00:00
Andrea Odetti
db874d37be Formatting.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-03-13 20:57:33 +00:00
Andrea Odetti
665245bf7b Bug fix in AW.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-03-13 20:56:31 +00:00
Andrea Odetti
d99d35013d Add support for symbols.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-03-13 20:56:19 +00:00
Andrea Odetti
dd6455ceb9 Add 6502 disassembler.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-03-07 20:32:24 +00:00
Andrea Odetti
883cbdd404 Merge remote-tracking branch 'origin/debug' into memory 2021-03-06 18:13:22 +00:00
Andrea Odetti
8499ccb692 Add info about g_nAppMode to settings.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-03-06 18:00:31 +00:00
Andrea Odetti
03329bba84 Add memory viewer using imgui_club/imgui_memory_editor.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-03-06 18:00:07 +00:00
Andrea Odetti
ddd1c4f301 Move ImGui Settings window(s) to a separate class.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-03-06 17:41:32 +00:00
Andrea Odetti
ec56d2ee00 Separate disassembler functions from display.
Makes it easier to use them in different environments.
2021-03-01 19:21:30 +00:00
Andrea Odetti
8d8782946b Memory 2021-02-28 17:02:30 +00:00
Andrea
462f02e77f
Merge pull request #26 from audetto/imgui
Make ImGui a module.
2021-02-26 09:04:12 +00:00
Andrea Odetti
0459fd3ba9 Make ImGui a module.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-02-25 16:56:36 +00:00
Andrea Odetti
c416eee9df sa2: add namespace and remove tabs.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-02-25 16:31:24 +00:00
Andrea Odetti
6066a52592 applen: add namespace and remove tabs.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-02-25 16:25:09 +00:00
Andrea Odetti
56511affa2 libretro: add namespace ra2 and remove tabs.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-02-25 16:24:52 +00:00
Andrea Odetti
3b917e93be common2: add namespace and reformat everything with space over tabs.
This makes it "possible" to use other editors (than emacs).

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-02-25 16:04:50 +00:00
Andrea Odetti
9366956c49 Merge remote-tracking branch 'upstream/master' 2021-02-23 19:32:19 +00:00
Andrea Odetti
c81b4ab1bf ImGui: fix event handling.
1) always pass events to ImGui
2) only pass keyboards to AW when ImGui says so
2021-02-23 19:32:00 +00:00
Andrea Odetti
fdfbb795d1 CAPS LOCK: use the same logic as AW.
Force it when the emulator starts, and follow its real state as soon as it is pressed.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-02-21 19:14:50 +00:00
Andrea Odetti
d9c6541f73 Inspired from https://github.com/audetto/AppleWin/pull/25
Add menubar to toggle demo and setting window.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-02-21 18:43:46 +00:00
Andrea Odetti
799ffc7604 Fix https://github.com/audetto/AppleWin/issues/23
Page 2 is not used if 80STORE is set.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-02-20 16:47:41 +00:00
Andrea Odetti
b78a2224d0 Support Enter key on keypad.
Honour the Caps Lock state (inverted).

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-02-20 16:14:03 +00:00
Andrea Odetti
4137238cd7 Merge remote-tracking branch 'upstream/master' 2021-02-20 15:54:28 +00:00
Andrea Odetti
956427bea8 Update QHexView.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-02-20 15:24:08 +00:00
Andrea Odetti
3e5a6aa520 Extend geometry arg to WxH(+X+Y).
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-02-20 15:21:53 +00:00
Andrea Odetti
07900d5c38 Add frame timer.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-02-20 08:38:53 +00:00
Andrea Odetti
20092dccb9 Merge remote-tracking branch 'upstream/master' 2021-02-20 08:29:52 +00:00
Andrea Odetti
cb166dc47f Merge remote-tracking branch 'upstream/master' 2021-02-18 16:34:31 +00:00
Andrea Odetti
282e024c37 Merge remote-tracking branch 'upstream/master' 2021-02-13 14:07:18 +00:00
Andrea Odetti
a75833847e Add cmd line option to switch off vsync.
Useful to profile.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-02-13 13:09:55 +00:00
Andrea Odetti
3051fbe3fe Make ClearBackground a standalone function.
Guidelines suggest to always clear background each frame.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-02-13 12:56:21 +00:00
Andrea Odetti
d912026f3e Add options to specify SDL window size via cmd line arguments.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-02-13 12:56:06 +00:00
Andrea Odetti
b204dc5362 Split glTexImage2D and update via glTexSubImage2D.
From the doc, it might allow for better performance.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-02-13 12:55:32 +00:00
Andrea Odetti
1905590b27 Merge remote-tracking branch 'upstream/master' 2021-02-07 20:01:36 +00:00
Andrea Odetti
c2fab20d0c Make the volume slider work.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-02-07 19:55:11 +00:00
Andrea Odetti
dc9bd91f84 Add some more ImGui example settings.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-02-07 19:23:33 +00:00
Andrea Odetti
7865fc3457 First meaningful usage of ImGui features.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-02-07 16:10:54 +00:00
Andrea Odetti
c8ad71ed07 Merge remote-tracking branch 'upstream/master' 2021-02-07 14:09:44 +00:00
Andrea Odetti
1b3c3f6711 Fix SDL rectangle frame.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-02-07 14:00:45 +00:00
Andrea Odetti
4ae655caab Fix a few issues reported by clang.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-02-07 13:46:50 +00:00
Andrea Odetti
0b692ee7f8 Some CMakeLists improvements.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-02-07 13:46:21 +00:00
Andrea
f3d5cb3f10
Merge pull request #21 from audetto/sdlimgui
Integrate Dear ImGui as a renderer over SDL2
2021-02-06 17:36:39 +00:00
Andrea Odetti
cfc7b719fe Cosmetic change.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-02-06 17:13:47 +00:00
Andrea Odetti
93bebd3eb0 Add travis support for Dear ImGui.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-02-06 17:09:27 +00:00
Andrea Odetti
53a6928991 Display Dear ImGui version.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-02-06 17:09:06 +00:00
Andrea Odetti
a3381bfcb6 Define ImTextureID in main config file.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-02-06 16:55:41 +00:00
Andrea Odetti
989410c17d Integrate Dear ImGui with SDL to reduce code duplication.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-02-06 16:55:08 +00:00
Andrea Odetti
05b2d5b2e7 Split SDLFrame to ease integration of ImGui.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-02-06 10:11:29 +00:00
Andrea Odetti
ad5b6628b5 Merge remote-tracking branch 'upstream/master' 2021-02-04 10:13:57 +00:00
Andrea Odetti
ea0a3cb5ba Fix string comparison in cmake.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-02-04 10:12:51 +00:00
Andrea Odetti
5594c4fbc8 Fix for in-place builds.
Which are not recommended anyway.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-02-03 18:34:53 +00:00
Andrea Odetti
bb2fce9e72 Fix libretro compiler bug.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-01-31 14:31:19 +00:00
Andrea Odetti
cc55d9e681 Modern syntax: virtual -> override.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-01-31 13:55:43 +00:00
Andrea Odetti
3215f2aff3 Merge remote-tracking branch 'upstream/master' 2021-01-31 13:27:47 +00:00
Andrea Odetti
e376b787cd Update QHexView.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-01-31 13:26:47 +00:00
Andrea Odetti
be1772bc37 Use RAII pattern to initialise and clear AppleWin emulator.
Plays better with exceptions.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-01-31 13:26:23 +00:00
Andrea Odetti
f61e73b639 Move resources, bitmaps and messageboxes into Frames.
And remove a few windows.h interface functions used before.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-01-20 19:07:18 +00:00
Andrea Odetti
217e9ab2cc Merge remote-tracking branch 'upstream/master' 2021-01-20 11:02:08 +00:00
Andrea Odetti
d3e25773dc Add configuration for printer filename. 2021-01-19 12:18:12 +00:00
Andrea Odetti
75b64a019d Merge remote-tracking branch 'upstream/master' 2021-01-18 08:01:24 +00:00
Andrea Odetti
a3bb062260 Required from upstream.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-01-17 20:19:12 +00:00
Andrea Odetti
094e09a6d1 Merge remote-tracking branch 'upstream/master' 2021-01-17 20:11:20 +00:00
Andrea Odetti
fee6720fb4 Fix qmake project.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-01-16 19:07:07 +00:00
Andrea Odetti
620fa10454 Remove redundant CPU check and data.h / .cpp. 2021-01-16 16:26:43 +00:00
Andrea Odetti
e80fee86c5 Merge remote-tracking branch 'upstream/master' 2021-01-14 14:44:09 +00:00
Andrea Odetti
ad56874b0f Fix missing call to FrameBase::Destroy().
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-01-14 14:39:37 +00:00
Andrea Odetti
6ca8aedcf2 Add NFrame.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-01-14 14:39:18 +00:00
Andrea Odetti
54a3bbf773 RetroFrame.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-01-13 17:48:25 +00:00
Andrea Odetti
59c581b807 Add Qt Frame.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-01-13 17:45:34 +00:00
Andrea Odetti
8a41ed4d73 Introduce SDL Frame. 2021-01-13 15:28:53 +00:00
Andrea Odetti
4e357b59bd Updates from AW's master.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-01-13 13:09:03 +00:00
Andrea Odetti
d06462beb0 Merge remote-tracking branch 'upstream/master' 2021-01-13 13:05:45 +00:00
Andrea Odetti
4fb1d3b75e Update QHexView for minor changes.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-01-12 18:52:31 +00:00
Andrea Odetti
8e36c2c7b3 Add header files to cmake project.
So they appear in QtCreator.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-01-12 12:52:26 +00:00
Andrea Odetti
133285ba1c Update QHexView to fix build.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-01-12 08:05:50 +00:00
Andrea Odetti
0105e626a3 QHexView: update to HEAD.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-01-11 20:39:17 +00:00
Andrea Odetti
9ff3544535 Support F5 = DriveSwap() in applen.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-01-03 18:50:17 +00:00
Andrea Odetti
0aec7061c3 Incorporate changes from AW's master.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-01-03 18:44:44 +00:00
Andrea Odetti
e387a8aaac Merge remote-tracking branch 'upstream/master' 2021-01-03 18:10:23 +00:00
Andrea Odetti
ae33493da7 Merge from AW's master.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-01-03 18:10:07 +00:00
Andrea Odetti
57b2c670ab Merge remote-tracking branch 'upstream/master' 2021-01-02 21:09:09 +00:00
Andrea Odetti
545c175a76 Add missing include for consistency.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2021-01-02 21:08:55 +00:00
Andrea Odetti
ed27650368 Allow users to specify Paddle device for applen.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-31 14:34:00 +00:00
Andrea
0e574fad7b
Merge pull request #19 from audetto/travis
Attempt at building on Windows.
2020-12-31 12:59:30 +00:00
Andrea Odetti
1edec39462 Attempt at building on Windows.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-31 12:06:47 +00:00
Andrea Odetti
3bf4e5648f Minor cosmetic changes.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-30 18:48:42 +00:00
Andrea Odetti
faca71ace7 Incorporate changes to FrameBase and Video.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-30 18:28:27 +00:00
Andrea Odetti
b3abd6962e Merge remote-tracking branch 'upstream/master'
# Conflicts:
#	source/Log.cpp
#	source/NTSC.h
2020-12-30 18:13:52 +00:00
Andrea Odetti
cdf8573202 Tidy up linux interface.h.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-29 09:22:10 +00:00
Andrea Odetti
a1ba1d2cd1 Rename Video -> QVideo due to name clash.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-28 20:00:16 +00:00
Andrea Odetti
247b51b2ab Integration of GetVideo().
Part 1.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-28 19:42:04 +00:00
Andrea Odetti
577a997003 Merge remote-tracking branch 'upstream/master'
# Conflicts:
#	source/Interface.h
2020-12-28 18:47:23 +00:00
Andrea Odetti
32d4c32524 Use macros to avoid duplication.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-28 18:45:04 +00:00
Andrea Odetti
3a063463ca For consistency with Registry::instance.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-28 18:44:47 +00:00
Andrea Odetti
04fe254521 Fix some access violation (NPE).
Due to usage global variables (instances) and the way deleters works, we need to fully delete the old one, before creating the new one.
Otherwise the old's deleter remove instances after the new one has set them.
2020-12-28 15:46:08 +00:00
Andrea Odetti
3d79b7983d Try to use the image as FD first and HD if this fails.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-28 15:35:19 +00:00
Andrea Odetti
38ecf366d6 Make sure interfaces are removed on unload as otherwise it causes seg fault on unloading.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-28 15:05:14 +00:00
Andrea Odetti
87ddb8033f Expose some variable to retroarch.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-28 15:04:24 +00:00
Andrea Odetti
2c9e4561df Share some more registry-related code.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-28 11:35:58 +00:00
Andrea Odetti
84b6afe758 Hide a couple of internals in an anonymous namespace.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-27 20:26:07 +00:00
Andrea Odetti
7d6439fefd Introduce a LinuxFrame.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-27 20:25:42 +00:00
Andrea Odetti
c4f3296336 Merge remote-tracking branch 'upstream/master' 2020-12-27 19:43:53 +00:00
Andrea Odetti
675d1316a9 Add a Registry interface to for more flexibility on case by case usage.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-27 19:43:35 +00:00
Andrea Odetti
093e4d7146 Print less audio - related messages.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-27 13:34:25 +00:00
Andrea Odetti
e0fd978d05 Fix missing call to ApplyNewConfig.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-27 13:32:59 +00:00
Andrea Odetti
5bdc62eff3 In linux, save log to /tmp.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-27 13:32:42 +00:00
Andrea Odetti
9068d47a44 Rename to applewin_libretro.so
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-26 20:38:30 +00:00
Andrea Odetti
2e654a0fcc libretro: add abiity to load snapshot file.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-26 20:38:07 +00:00
Andrea Odetti
05321679f8 Clarify what path is required.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-26 19:31:07 +00:00
Andrea Odetti
175491f250 libretro core: fix (most?) audio glitches.
It was reading a number of bytes not multiple of "2 * channels".

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-26 19:28:51 +00:00
Andrea Odetti
1a5ec9ec0f libretro: play speaker audio (with some glitches).
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-25 21:59:48 +00:00
Andrea Odetti
9b90335c63 Fix list of packages.
This fixes missing audio in Qt in a Pi3.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-23 22:39:46 +00:00
Andrea Odetti
947b39763f Rename folder retro -> libretro for consistency.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-23 19:36:11 +00:00
Andrea Odetti
bea7bac3ab Rename folder sa2 -> sdl for consistency.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-23 19:25:25 +00:00
Andrea Odetti
2fecd3bd1c Rename folder qapple -> qt for consistency.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-23 19:23:13 +00:00
Andrea Odetti
f4af643500 Merge remote-tracking branch 'upstream/master' 2020-12-23 18:57:10 +00:00
Andrea Odetti
e85eb32a0a Add some controls via the joypad (video mode, 50% scan lines and reset).
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-23 18:55:26 +00:00
Andrea Odetti
cb2f9b6177 Re-enable keyboard.
Print a short message informing the user about game focus mode.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-23 17:44:34 +00:00
Andrea Odetti
ad41cae876 Merge remote-tracking branch 'upstream/master'
# Conflicts:
#	source/StdAfx.h
2020-12-23 16:40:25 +00:00
Andrea Odetti
a1f67585d9 Add support for retropads, with and without analog extension.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-23 16:38:22 +00:00
Andrea Odetti
eae49b3f41 Integrate AW changes about IPropertySheet. 2020-12-20 16:35:44 +00:00
Andrea Odetti
2b46f136fc Merge remote-tracking branch 'upstream/master'
# Conflicts:
#	source/Core.cpp
#	source/Utilities.cpp
2020-12-20 16:32:09 +00:00
tomcw
7a8e5bee57 Proposed updated 2020-12-19 15:40:26 +00:00
Andrea Odetti
ba6aaf6775 applen: make --headless really skip ncurses initialisation.
Stop with Ctrl-C.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-19 15:40:16 +00:00
Andrea Odetti
10eeeda581 Add support for the RetroPad and disable keyboard.
How they can coexist is still not clear to me.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-19 14:26:48 +00:00
Andrea Odetti
e6532deea3 Only draw the borderless video buffer.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-19 14:17:49 +00:00
Andrea Odetti
986cf9b896 Make size of hi-res for applen work on Pi3.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-15 17:37:21 +00:00
Andrea Odetti
5de5af3fe8 Move all initialisation for (sa2, applen, retro2) to common2.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-13 19:47:30 +00:00
Andrea Odetti
5c7eaea49e applen: remove unused left buffer.
Move keys to ALT to resize the window.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-13 18:52:39 +00:00
Andrea Odetti
3d10369044 Merge remote-tracking branch 'upstream/master' 2020-12-13 17:59:52 +00:00
Andrea Odetti
f28a806253 Fix creation of config dir.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-13 17:57:34 +00:00
Andrea Odetti
9dcb33aba5 Remove out of place configuration file.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-12 20:19:50 +00:00
Andrea
db7e0625bd
Merge pull request #15 from audetto/retro2
Implement a libretro core.
2020-12-12 20:17:01 +00:00
Andrea Odetti
758e231565 Remove wrong file.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-12 20:07:17 +00:00
Andrea Odetti
a04425bc67 Merge branch 'master' into retro2 2020-12-12 19:57:17 +00:00
Andrea Odetti
62c8b61a6b Integrate upstream changes.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-12 19:57:04 +00:00
Andrea Odetti
1b40c217f4 Merge branch 'applewin' 2020-12-12 19:53:20 +00:00
Andrea Odetti
449e3d2d68 Fix cmake config.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-12 19:45:59 +00:00
Andrea Odetti
254ea8dbf6 Build libretro on travis.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-12 19:39:22 +00:00
Andrea Odetti
c2f4d8ed34 Bite the bullet and flip the video buffer in software.
Until a better solution is found.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-12 19:27:28 +00:00
Andrea Odetti
e461847a49 libretro: add support for Open / Solid Apple keys.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-12 19:25:43 +00:00
Andrea Odetti
ab655cda40 Move keyboard to a callback system.
The "switch" is the same as the SDL version.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-12 18:47:15 +00:00
Andrea
66b62ecca1 Update linux.md 2020-12-12 18:46:56 +00:00
Andrea Odetti
94b7d66096 Remove hard-coded libretro path.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-12 18:46:56 +00:00
Andrea Odetti
54232b988b Accept a few more disk types.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-12 18:46:56 +00:00
Andrea Odetti
120cb8be50 It is not clear to me how the Input API works.
This is copied (without understanding) from other examples.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-12 18:46:56 +00:00
Andrea Odetti
cec0c10286 libretro: first "working" versions.
draws video upside down
accepts keys (O crashes, and others have overloaded meaning)

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-12 18:46:56 +00:00
Andrea Odetti
b95bcadfe9 Fix bitmap loading.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-12 18:46:56 +00:00
Andrea Odetti
7f441060f2 Some change to better structure the code.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-12 18:46:53 +00:00
Andrea Odetti
40b838aeb9 Temporary step to load resources in libretro.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-12 18:46:06 +00:00
Andrea Odetti
c176b3d2ff Add skeleton of a libretro core for AW.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-12 18:45:58 +00:00
Andrea Odetti
edb93cbaa0 Integrate memory changes from AW.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-11 08:28:16 +00:00
Andrea Odetti
f6224a5a3b Merge remote-tracking branch 'upstream/master' 2020-12-11 08:18:18 +00:00
Andrea Odetti
fb708ca7b8 Add ability to disable main loop.
Useful to validate with valgrind.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-07 13:13:42 +00:00
Andrea Odetti
4fc2ee18f2 Merge remote-tracking branch 'upstream/master' 2020-12-06 21:08:47 +00:00
Andrea Odetti
81664c60aa Add support for Pause / Restart key.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-06 19:53:35 +00:00
Andrea Odetti
092a74f5b3 Add F11 Save State confirmation as it is too easy to confuse with F12.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-06 18:28:17 +00:00
Andrea Odetti
1d07215f78 Add ability to Save/Load Snapshot F11/F12.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-06 18:03:41 +00:00
Andrea Odetti
74cb18a7a1 Remove most false positive valgrind results.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-06 13:28:29 +00:00
Andrea Odetti
6cb2e0bbb0 Fix VideoDestroy.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-06 13:27:43 +00:00
Andrea Odetti
eb55d011ca Mirror AW where TestCPU6502 inlcudes a .cpp from source.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-05 20:52:27 +00:00
Andrea Odetti
887e88f89c Fix uninitialised value.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-05 20:34:21 +00:00
Andrea
3dd23a7034
Update linux.md 2020-12-04 21:03:57 +00:00
Andrea
9a41db13d8
Update README.md 2020-12-04 20:02:14 +00:00
Andrea Odetti
c33ae2b26e Add ability to pass all Registry options via cmd line.
-c Configuration.Printer_Filename=Printer2.txt

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-04 19:58:49 +00:00
Andrea Odetti
5029b91850 Move configuration file to ~/.applewin/applewin.conf
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-12-03 15:57:12 +00:00
Andrea Odetti
f867dc0479 Make the code more similar to AW.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-11-30 18:44:31 +00:00
Andrea
8cd74adc21
Remove travis amd64 as it seems to hang. 2020-11-30 18:20:54 +00:00
Andrea
3f5b2bd396
Update .travis.yml 2020-11-30 16:00:57 +00:00
Andrea
9164611a96
Update .travis.yml 2020-11-30 15:59:11 +00:00
Andrea Odetti
1f6538f0b0 Fix build permission.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-11-30 15:49:48 +00:00
Andrea
131120d6fc
Update .travis.yml 2020-11-30 15:44:15 +00:00
Andrea Odetti
2b6093861c Add travis integration.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-11-30 15:29:57 +00:00
Andrea Odetti
ad1382ec36 Merge remote-tracking branch 'origin/master' 2020-11-30 13:46:42 +00:00
Andrea Odetti
861c87efd4 Remove pointless getScreenData() and shed some nanoseconds from screen repaint.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-11-30 13:38:56 +00:00
Andrea
37298f0d5e
Update README.md 2020-11-30 09:52:25 +00:00
Andrea Odetti
299c907be6 Merge remote-tracking branch 'upstream/master' 2020-11-30 09:28:29 +00:00
Andrea Odetti
56a095f0e2 Merge branch 'reset_linux' 2020-11-30 09:27:02 +00:00
Andrea Odetti
586493e8c6 Small fixes to the readme.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-11-30 09:26:27 +00:00
Andrea Odetti
e43a08c5a1 Merge remote-tracking branch 'origin/reset' 2020-11-30 09:25:19 +00:00
Andrea Odetti
dc030fe607 Change F2 like AW: reset.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-11-30 09:23:22 +00:00
Andrea Odetti
2b3c189b07 Small changes to start - stop.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-11-30 09:22:35 +00:00
Andrea
74e7e1a00f
Create README.md 2020-11-29 19:58:03 +00:00
Andrea Odetti
cf6ddba626 Merge remote-tracking branch 'origin/reset' into reset_linux 2020-11-29 19:31:47 +00:00
Andrea Odetti
f919a3ba6f Fix arguments of fwd declared function. 2020-11-29 19:27:11 +00:00
Andrea Odetti
59772cda6b Move CtrlReset() and ResetMachineState() to Utilities.cpp. 2020-11-29 19:26:47 +00:00
Andrea Odetti
40b37ccccb Fix compilation error after merge.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-11-29 18:02:43 +00:00
Andrea Odetti
ab08dd7de7 Merge remote-tracking branch 'upstream/master'
# Conflicts:
#	source/CommonVICE/types.h
2020-11-29 18:00:16 +00:00
Andrea Odetti
600d6cf00e Print AW version in -h output.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-11-29 16:39:17 +00:00
Andrea Odetti
a5734cac10 Use GetAppleWindowTitle() from AW.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-11-29 16:37:45 +00:00
Andrea Odetti
1b6127dbb6 Merge remote-tracking branch 'upstream/master' 2020-11-29 16:36:05 +00:00
Andrea Odetti
a0c3fcf416 Merge remote-tracking branch 'upstream/master'
# Conflicts:
#	source/RGBMonitor.cpp
2020-11-28 14:17:24 +00:00
Andrea Odetti
312a618196 Merge remote-tracking branch 'upstream/master' 2020-11-28 10:02:11 +00:00
Andrea Odetti
338719d82b Make VideoBenchmark include the video redraw (without vsync).
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-11-28 10:01:49 +00:00
Andrea Odetti
156d1421e0 Make sure alpha = 0xFF in all cases.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-11-27 18:55:35 +00:00
Andrea Odetti
9fabc71464 Use existing function VideoGetAppWindowTitle().
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-11-27 18:55:07 +00:00
Andrea Odetti
8e6fc89384 From AW's master, AppleWin.cpp split.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-11-27 13:48:53 +00:00
Andrea Odetti
90368927e8 Merge remote-tracking branch 'upstream/master' 2020-11-27 08:55:05 +00:00
Andrea Odetti
9cd8b22647 Use Frame.cpp from upstream.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-11-24 07:51:50 +00:00
Andrea Odetti
97e219ac47 Merge remote-tracking branch 'upstream/master' 2020-11-24 07:41:15 +00:00
Andrea Odetti
18dd63e7eb Add suppressions for valgrind.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-11-22 20:48:06 +00:00
Andrea Odetti
cadb72442a Use Video.cpp "as is".
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-11-22 09:36:28 +00:00
Andrea Odetti
78200c7a2c Merge remote-tracking branch 'upstream/master' 2020-11-22 08:44:52 +00:00
Andrea Odetti
e2ea9c5f22 Marginally better benchmark calculation.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-11-21 21:01:34 +00:00
Andrea Odetti
e883e1b38c Add support for video benchmark.
Screen repaint is not included (as it would force vsync), so it stops at the texture update.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-11-21 20:13:56 +00:00
Andrea Odetti
a121981e5a sa2: Add support for --headless and --fixed-speed.
Headless will skip the video refresh (and the vsync).
Fixed-Speed will avoid adaptive speed.

Used together, the emulator will go at maximum speed skipping video refresh (useful for profiling).
2020-11-21 15:07:31 +00:00
Andrea Odetti
7067ad150e sa2: Make window resizable.
Ctrl-F6 will still loop between 1x ans 2x sizes.
2020-11-21 09:42:46 +00:00
Andrea Odetti
b59e7605e9 sa2: add application icon.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-11-21 09:35:15 +00:00
Andrea Odetti
dec8b54a9e Write more accurate audio diagnostics.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-11-21 09:15:46 +00:00
Andrea Odetti
6d4dd11f06 Audio: remove useless workaround 1/3 1/4 and initial silence.
Let AW's adaptive algorithm do it all.
Just be careful not writing too much to SDL as it would unsettle AW.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-11-20 20:23:10 +00:00
Andrea Odetti
48146f4c34 Keep track of actual speed to ensure emulated CPU goes at the right speed (and keeps audio on track).
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-11-20 15:32:35 +00:00
Andrea Odetti
ad335e2a5c Merge remote-tracking branch 'upstream/master' 2020-11-20 11:51:41 +00:00
Andrea Odetti
7a9ed38326 Follow upstream capitalisation of AppleWin.cpp.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-11-15 15:44:06 +00:00
Andrea Odetti
31d87f5a9c Merge remote-tracking branch 'upstream/master' 2020-11-15 15:42:44 +00:00
Andrea Odetti
8c71b946b4 Prefer mean over average.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-11-15 14:47:51 +00:00
Andrea Odetti
e58b547d59 Fix actual vs expected clock. 2020-11-14 20:42:27 +00:00
Andrea
0511128fea
Merge pull request #13 from audetto/threads
Threads
2020-11-14 20:36:14 +00:00
Andrea Odetti
7add40d913 Better logging layout.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-11-14 20:09:12 +00:00
Andrea Odetti
c7f8bf1280 Handle volume in SDL.
Make volume loglinear everywhere.
Reduce default volume to avoid annoying loud reset beep.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-11-14 20:08:37 +00:00
Andrea Odetti
70969a2d03 Add ability to select SDL driver.
On a Pi3 opengles2 performs better.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-11-14 11:01:05 +00:00
Andrea Odetti
e7e848917b Reduce extra verbose logging of keys.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-11-14 09:32:51 +00:00
Andrea Odetti
78a7c98c3e Improve SDL debug info.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-11-14 09:29:21 +00:00
Andrea Odetti
4840b7b0ac Improve logging diagnostics.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-11-14 09:14:37 +00:00
Andrea Odetti
169188b2b4 Improve stat logging.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-11-13 20:12:57 +00:00
Andrea Odetti
67df88d9a2 Fix std calculation.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-11-13 20:12:01 +00:00
Andrea Odetti
cbe10854b9 Add timers (to see what happens).
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-11-13 15:37:10 +00:00
Andrea Odetti
1588f1cb05 Fix -h for --help.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-11-13 12:00:42 +00:00
Andrea Odetti
f13816262d Clean up multithreading code and offer it via command line options.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-11-13 11:51:20 +00:00
Andrea Odetti
ef114f9e64 Make the mutex protect AW rather than SDL.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-11-12 20:48:44 +00:00
Andrea Odetti
6a16d416a4 threads 2 2020-11-12 20:33:04 +00:00
Andrea Odetti
314c647daf more threads 2020-11-12 19:51:45 +00:00
Andrea Odetti
b360d27f22 split 2020-11-12 19:31:35 +00:00
Andrea Odetti
892c6e383f Remove some more diffs wrt AW.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-11-12 19:16:35 +00:00
Andrea Odetti
4ff7741a41 Fix previous sdl ppp commit, too messy to revert.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-11-12 18:52:52 +00:00
Andrea Odetti
c7a8c628e4 Changes required from upstream. 2020-11-12 18:43:04 +00:00
Andrea Odetti
aa473958d0 Merge remote-tracking branch 'upstream/master' into pi
# Conflicts:
#	source/Disk.cpp
#	source/DiskImageHelper.cpp
#	source/DiskImageHelper.h
#	source/Memory.h
#	source/MouseInterface.cpp
2020-11-12 18:30:39 +00:00
Andrea Odetti
0dda605c36 ppp 2020-11-11 11:20:06 +00:00
Andrea Odetti
c2105bfe1f Merge remote-tracking branch 'upstream/master' 2020-11-03 11:50:54 +00:00
Andrea Odetti
66ab6dde9d Merge remote-tracking branch 'upstream/master' 2020-10-25 18:45:36 +00:00
Andrea Odetti
d28ac063db Merge remote-tracking branch 'upstream/master' 2020-10-20 15:33:04 +01:00
Andrea Odetti
3ba2cd6d98 SDL2 add audio.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-10-20 15:32:45 +01:00
Andrea Odetti
da37dfe17c QApple fix name of video types.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-10-18 18:43:45 +01:00
Andrea Odetti
b5630539df Bug fix about to using the correct CardManager.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-10-18 10:55:58 +01:00
Andrea Odetti
7037582907 Allow to turn the circle range of a gamepad to a square (as the Apple ][).
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-10-17 19:19:46 +01:00
Andrea Odetti
daa57cc1a0 Merge remote-tracking branch 'upstream/master' 2020-10-17 14:42:56 +01:00
Andrea Odetti
d314546b11 Paddle: make raw interface to return values in [-1,1] to ease transformations.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-10-15 16:24:20 +01:00
Andrea Odetti
e8972aa824 Add support for gamepads (hardcoded to be the first).
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-10-15 12:55:27 +01:00
Andrea Odetti
4866867d06 Merge remote-tracking branch 'upstream/master' 2020-10-12 21:10:21 +01:00
Andrea Odetti
d4fa3f6a2c Remove Ctrl-Q shortcut as it interferes with emulator.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-10-12 21:01:13 +01:00
Andrea Odetti
a72d19b386 Couple of fixes from upstream AW.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-10-12 20:58:32 +01:00
Andrea Odetti
b100ed1ae0 Merge remote-tracking branch 'upstream/master'
# Conflicts:
#	source/Speaker.cpp
2020-10-12 20:41:59 +01:00
Andrea Odetti
9320db8ab7 Move letters to KeyDown as opposed to text.
It is easier to handle Ctrl.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-10-12 20:30:23 +01:00
mariofutire@gmail.com
bc029dee97 sa2: make the keyboard "work" (no CTRL-ASCII codes for the time being).
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-10-11 20:16:07 +01:00
mariofutire@gmail.com
1400828452 Use keycode as opposed to scancode.
We honour a layout change decided by the user.

Signed-off-by: mariofutire@gmail.com <pi@raspberrypi>
2020-10-11 20:14:02 +01:00
mariofutire@gmail.com
aac2c5139a Split event handling and "video" state to separate class.
Signed-off-by: mariofutire@gmail.com <pi@raspberrypi>
2020-10-11 20:14:02 +01:00
mariofutire@gmail.com
ddea5b139e Add #pragma once.
Signed-off-by: mariofutire@gmail.com <pi@raspberrypi>
2020-10-11 20:14:02 +01:00
mariofutire@gmail.com
080198f88c Rename ClosedApple -> SolidApple.
Signed-off-by: mariofutire@gmail.com <pi@raspberrypi>
2020-10-11 20:14:01 +01:00
mariofutire@gmail.com
4ba10089c3 sa2: add button emulation
LALT = Open Apple
RALT = Closed Apple

Signed-off-by: mariofutire@gmail.com <pi@raspberrypi>
2020-10-11 20:14:01 +01:00
mariofutire@gmail.com
3e355288cb sa2: F2 = quit (line applen).
throw an exception rather than a string.

Signed-off-by: mariofutire@gmail.com <pi@raspberrypi>
2020-10-11 20:14:01 +01:00
mariofutire@gmail.com
e279fc7a5d Reindent properly.
Signed-off-by: mariofutire@gmail.com <pi@raspberrypi>
2020-10-11 20:14:01 +01:00
mariofutire@gmail.com
f4eba20295 We will not be adding Disks... (ignore them)
Signed-off-by: mariofutire@gmail.com <pi@raspberrypi>
2020-10-11 20:14:01 +01:00
mariofutire@gmail.com
dab1735a69 Logging / Config replated changes.
sa2 / applen add flag to load qt init file (--qt-ini) (read only for now)
unify logging (--log)

Signed-off-by: mariofutire@gmail.com <pi@raspberrypi>
2020-10-11 20:14:01 +01:00
mariofutire@gmail.com
bc74b5fbfb Implement save-on-exit configuration flag.
Signed-off-by: mariofutire@gmail.com <pi@raspberrypi>
2020-10-11 20:13:50 +01:00
Andrea Odetti
65effc121d Add Quit on the Qt app.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-10-09 19:37:04 +01:00
Andrea Odetti
bb8269052a SDL2: add F6 (full screen) and F5 (swap disks).
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-10-09 19:31:20 +01:00
Andrea
9982ceb36a
Merge pull request #11 from audetto/sdl2
Sdl2
2020-10-09 19:15:16 +01:00
Andrea Odetti
24621373dd Better way to share data between ncurses and sdl2.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-10-09 19:13:42 +01:00
Andrea Odetti
01c059873f Let SDL2 do the refresh sync.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-10-09 11:50:59 +01:00
Andrea Odetti
274ef6a796 Fix sa2 to work with recent code.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-10-09 10:31:18 +01:00
Andrea Odetti
697a5b5c88 Rechange the order of initialisation.
Need to find a better solution.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-10-09 10:30:53 +01:00
Andrea Odetti
8b081725ce More SDL WIP. 2020-10-09 09:46:15 +01:00
Andrea Odetti
ae0194d5b1 Merge branch 'master' into sdl4
# Conflicts:
#	source/CMakeLists.txt
#	source/frontends/ncurses/main.cpp
#	source/frontends/ncurses/resources.cpp
2020-10-09 09:17:55 +01:00
Andrea Odetti
039bfc04c3 Fix a couple of issues with RGB modes. 2020-10-07 20:45:31 +01:00
Andrea Odetti
13edefa6e0 Add support for older cmake versions.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-10-06 20:58:43 +01:00
Andrea Odetti
ffddc18fe6 Dummy implementation of MultiByteToWideChar & WideCharToMultiByte.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-10-06 20:57:18 +01:00
mariofutire@gmail.com
806a369624 WIP SDL2 2020-10-06 20:05:48 +01:00
Andrea Odetti
14fdc2520b Merge remote-tracking branch 'upstream/master' 2020-10-02 21:07:49 +01:00
Andrea Odetti
d9f29257f9 Merge remote-tracking branch 'upstream/master' 2020-09-09 17:25:48 +01:00
Andrea Odetti
317e048d5a Remove windows includes.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-08-31 19:00:16 +01:00
Andrea Odetti
a6cb08714d Merge remote-tracking branch 'upstream/master' 2020-08-31 18:56:40 +01:00
Andrea Odetti
8446794828 Merge remote-tracking branch 'upstream/master'
# Conflicts:
#	source/Video.h
2020-08-27 18:35:42 +01:00
Andrea Odetti
388e6f5916 Merge remote-tracking branch 'upstream/master' 2020-08-16 18:01:38 +01:00
Andrea Odetti
38163b4abf Merge remote-tracking branch 'upstream/master' 2020-08-09 19:09:44 +01:00
Andrea Odetti
450c2e3622 Merge remote-tracking branch 'upstream/master' 2020-08-03 08:35:47 +01:00
Andrea Odetti
7010d9f6e1 Remove WCHAR not needed and change TCHAR to a define.
This helps QTCreator to show the string in the debugger.
Otherwise it would show just an array of bytes.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-07-13 08:20:21 +01:00
Andrea Odetti
60beb9aa58 Add installation and packaging in cmake.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-07-12 15:53:53 +01:00
Andrea Odetti
2ebcb856a3 dirname cant return null.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-07-12 10:29:45 +01:00
Andrea Odetti
ce0db1f74f Use a dynamic relative path to locate resources.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-07-12 10:26:17 +01:00
Andrea Odetti
a310d50da4 applen: partially better way to locate resources if application is launched from different folder.
When loading snapshot, chdir so relative paths can be found.
Ensure endwin() is called.
Use an "int" to exit the process rather than a exit().

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-07-12 10:24:27 +01:00
Andrea Odetti
9515e7de2d Set window icon.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-07-11 18:46:09 +01:00
Andrea Odetti
5e2025d36c Dummy load options for joystick and serial card to avoid warning on the screen.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-07-11 18:42:11 +01:00
Andrea Odetti
9afb9c631f Save absolute path of the snapshot filename.
Otherwise if one starts qapple with --load-state with a relative path it does not work
(as we have cd'ed to allow loading disks).

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-07-11 18:41:09 +01:00
Andrea Odetti
b7fb13576f Merge remote-tracking branch 'upstream/master' 2020-07-08 16:56:40 +01:00
Andrea Odetti
9c442468f5 Compile AW's Speaker.cpp and remove custom implementation.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-07-08 16:52:00 +01:00
Andrea Odetti
22125c9566 Add support for Base64A.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-07-07 20:13:43 +01:00
Andrea Odetti
40d3e822e9 Make resource interface based on "char *" as it is easier to detect a nullptr.
Can't change the return type to std::string.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-07-07 20:13:26 +01:00
Andrea Odetti
a5eaf8a011 Merge remote-tracking branch 'upstream/master' 2020-07-07 08:50:51 +01:00
Andrea Odetti
ac6bc48f60 Fix wrong list of preferences in Slot5.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-07-06 20:30:37 +01:00
Andrea
7204abce03
Merge pull request #7 from audetto/mockingboard
Mockingboard
2020-07-06 19:39:08 +01:00
Andrea Odetti
c9b4eb9aab Fix the call to SetCurrentImageDir to be a path rather than a filename.
Load the path of the save state first as disks are relative to it.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-07-06 19:32:10 +01:00
Andrea Odetti
86ad2130a9 Make sure configuration is saved when a snapshot is loaded.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-07-06 19:29:18 +01:00
Andrea Odetti
ad1b6774ae Fix Mockingboard in applen.
(not playing, but not crashing)

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-07-05 19:10:24 +01:00
Andrea Odetti
a29e781de0 Reduce calls to chdir() and only do it before loading a snapshot as it helps with relative disk locations.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-07-05 18:07:13 +01:00
Andrea
fb776b3c7f
Update linux.md 2020-07-05 14:54:31 +01:00
Andrea Odetti
16d17a3ab3 Partially revert memory leak fix(ed upstream).
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-07-05 14:51:51 +01:00
Andrea Odetti
df01fafd06 Merge branch 'master' into mockingboard 2020-07-05 14:48:48 +01:00
Andrea Odetti
0c0ed92164 Merge remote-tracking branch 'upstream/master' 2020-07-05 14:47:40 +01:00
Andrea Odetti
36e774ab6e Merge branch 'master' into mockingboard 2020-07-05 14:43:42 +01:00
Andrea Odetti
38908c7d6d Fix memory leak.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-07-05 14:42:56 +01:00
Andrea Odetti
74cab50cee Remove dependency on std::filesystem and fix a compilation error. 2020-07-05 13:20:03 +01:00
Andrea Odetti
0539fd9a69 Simplify initialisation.
Just reinitialise everything on soft reboot.
Make sure audio is stopped when emulator is reinitialised.
Stop timers while reinitialising.
2020-07-04 19:59:20 +01:00
Andrea Odetti
3cfea2da07 Add some safety around IDirectSoundBuffer::Release().
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-07-04 19:57:15 +01:00
Andrea Odetti
5dee29fbf9 Make Mockingboard voice actually play.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-07-02 11:02:57 +01:00
Andrea Odetti
04ef0bf377 Compile SoundCore from AW.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-07-01 18:48:41 +01:00
Andrea Odetti
259428a946 Add support for a (munte) mockingboard.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-06-30 15:43:06 +01:00
Andrea Odetti
fd9b2184bf Merge remote-tracking branch 'origin/minor_fixes' 2020-06-30 14:03:28 +01:00
Andrea Odetti
5536050b71 Use c++ sleep_for rather than usleep.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-06-30 14:02:39 +01:00
Andrea Odetti
ebfa58293d No need to cast, it is already of the right size (void *). 2020-06-30 12:09:01 +01:00
Andrea Odetti
98d1f74fba Cosmetic improvements to Perf breakdown. 2020-06-30 10:39:01 +01:00
Andrea Odetti
ca96fa232f Add missing Riff.h include and fix constness of arguments. 2020-06-30 09:56:29 +01:00
Andrea Odetti
a2e7191604 Merge remote-tracking branch 'upstream/master' 2020-06-27 18:34:58 +01:00
Andrea Odetti
85b1f872f0 Rationalise location of some duplicate code.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-06-24 12:26:47 +01:00
Andrea Odetti
46f056f38e Move duplicate code to their standard location.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-06-24 07:54:04 +01:00
Andrea Odetti
de24c4e90a Necessary to avoid crash.
Must initialise card type at least.
2020-06-23 20:35:21 +01:00
Andrea Odetti
ee2e80aae4 Fix order of initialisation of global variables.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-06-22 16:43:36 +01:00
Andrea Odetti
507e316dfc Merge remote-tracking branch 'origin/cppfixes' 2020-06-22 16:09:17 +01:00
Andrea Odetti
aa60179992 Merge remote-tracking branch 'upstream/master' 2020-06-22 15:59:40 +01:00
Andrea Odetti
1d5710151d Some minor c++ correctness changes.
Add const, static forward declaration.
Remove windows.h (already in StdAfx.h) and crtdbg.h (not needed).
2020-06-22 15:24:32 +01:00
Andrea Odetti
b01bfe8b49 Rework a bit the way keys are processed.
Add Ctrl-'-' = 0x1f.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-06-19 18:23:29 +01:00
Andrea Odetti
8502d4b0d9 Use AltGr and Menu to avoid overloading Ctrl keys.
Unfortunately Alt does not work: not all key events are triggered.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-06-18 20:13:29 +01:00
Andrea Odetti
9282c5ddb9 Remove some duplication.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-06-18 14:06:14 +01:00
Andrea Odetti
7acac5cd22 Add support for Tab.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-06-18 13:56:24 +01:00
Andrea Odetti
a7e75078bb Add support for Open/Closed Apple with Left/Right Ctrl.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-06-18 13:56:14 +01:00
Andrea Odetti
457fc184d9 Save and restore emulator window geometry as well.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-06-16 20:15:58 +01:00
Andrea Odetti
42a3294791 Treat Backspace as Left (same as AW).
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-06-15 10:53:42 +01:00
Andrea Odetti
059820847a Support Ctrl characters.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-06-15 10:13:16 +01:00
Andrea Odetti
12a4180fc7 Small fixes from latest upstream changes.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-06-14 09:18:18 +01:00
Andrea Odetti
66bb1b9905 Merge remote-tracking branch 'upstream/master' 2020-06-14 09:03:55 +01:00
Andrea Odetti
0706697b13 Merge remote-tracking branch 'upstream/master' 2020-05-24 19:18:49 +01:00
Andrea Odetti
fc88f17dc5 Add support for JPlus.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-04-13 16:46:41 +01:00
Andrea Odetti
b7e5bb8656 Merge remote-tracking branch 'upstream/master' 2020-04-13 16:22:22 +01:00
Andrea Odetti
54117536fd Add missing variable definition.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-03-31 19:19:49 +01:00
Andrea Odetti
92d421bc68 Merge remote-tracking branch 'upstream/master' 2020-03-31 19:13:55 +01:00
Andrea Odetti
4f466d95a1 Merge remote-tracking branch 'upstream/master' 2020-03-14 18:17:11 +00:00
Andrea Odetti
9eb21251cb Update compatibility layer.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-02-29 10:29:46 +00:00
Andrea Odetti
c3dedef7c9 Merge remote-tracking branch 'upstream/master' 2020-02-29 10:19:38 +00:00
Andrea Odetti
93990b0055 Small changes to compile with latest version.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-02-22 19:00:42 +00:00
Andrea Odetti
3b0043af6d Merge remote-tracking branch 'upstream/master' 2020-02-22 18:34:23 +00:00
Andrea Odetti
582b29a545 Add 50% scalines keys.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-02-08 10:21:14 +00:00
Andrea Odetti
9c21b12176 Add F9 and Ctrl-F6.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-02-08 10:21:14 +00:00
Andrea Odetti
e315bade5a Fix linker error.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-02-08 10:21:14 +00:00
Andrea Odetti
f3bff96968 First draft of the SDL2 port.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2020-02-08 10:21:13 +00:00
Andrea Odetti
c299920fc1 Merge remote-tracking branch 'upstream/master' 2020-01-25 19:36:36 +00:00
Andrea Odetti
3f39bc8f7b Merge remote-tracking branch 'upstream/master' 2020-01-18 19:32:56 +00:00
Andrea Odetti
51497eebc1 Merge remote-tracking branch 'upstream/master' 2020-01-11 11:26:01 +00:00
Andrea Odetti
efec61caba Merge remote-tracking branch 'upstream/master'
# Conflicts:
#	source/StdAfx.h
2020-01-09 09:30:23 +00:00
Andrea Odetti
2d1021c629 Need some of Debug.cpp to link now.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-12-31 18:34:16 +00:00
Andrea Odetti
0191652565 First part of merge of new CardManager code.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-12-31 18:19:45 +00:00
Andrea Odetti
9ef028fac6 Merge remote-tracking branch 'upstream/master' 2019-12-31 16:54:58 +00:00
Andrea
68b19b332f Add speed statistics to linux.md.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-12-14 21:18:00 +00:00
Andrea Odetti
24e0b17135 Works on Raspbian.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-12-14 21:18:00 +00:00
Andrea Odetti
849482ea65 Add list of packages required on Raspbian.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-12-14 21:18:00 +00:00
Andrea Odetti
2b40967589 Merge remote-tracking branch 'upstream/master' into newmaster 2019-12-14 21:17:01 +00:00
Andrea Odetti
ea044268de Small "const" addition.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-12-12 20:19:25 +00:00
Andrea Odetti
e49275ee9d Ensure keys are visible.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-12-12 20:19:10 +00:00
Andrea Odetti
2462743edd Save and restore geometry.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-12-12 20:18:58 +00:00
Andrea Odetti
20852fcb2a Add a few command line options to run the tests automatically.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-12-08 20:21:35 +00:00
Andrea Odetti
900c9ab40b Merge remote-tracking branch 'upstream/master' 2019-12-08 19:14:51 +00:00
Andrea Odetti
f50d303765 Correct video load/save state.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-12-07 15:26:45 +00:00
Andrea Odetti
20a01a5ea9 Keyboard load/save state from yaml file.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-12-07 15:25:12 +00:00
Andrea Odetti
874f4be666 Single keyboard handler.
Seems to work...

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-12-07 11:20:37 +00:00
Andrea Odetti
84332ada39 Minor change.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-12-06 20:36:28 +00:00
Andrea Odetti
187739f913 Forgotten destructors...
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-12-06 20:00:16 +00:00
Andrea Odetti
45721b3fc5 Allow to change monochrome color.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-12-05 21:37:39 +00:00
Andrea Odetti
35765e23e4 Fix a bug when a file canno tbe opened.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-12-05 20:59:00 +00:00
Andrea Odetti
77490c6d48 Update QHexView
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-12-02 20:54:13 +00:00
Andrea Odetti
eb3c11c672 Add option for 50Hz video.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-12-02 20:50:51 +00:00
Andrea Odetti
7c90b040ef Reduce some boilerplate with global and aw's options.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-12-01 19:49:11 +00:00
Andrea Odetti
177f345861 Cap time in each slice to avoid pathological cases.
E.g. when debugging.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-12-01 18:59:20 +00:00
Andrea Odetti
f2d06cb18d Expose timers in preferences.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-12-01 18:58:32 +00:00
Andrea Odetti
01e55a380f Fix cmake output message.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-12-01 18:40:50 +00:00
Andrea Odetti
bad18cafbf Rename configuration.* options.*
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-12-01 18:40:28 +00:00
Andrea Odetti
e8022bf6a0 Cleanup CMakeLists.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-12-01 15:22:17 +00:00
Andrea Odetti
76a1663282 Update some memory comments.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-12-01 14:39:57 +00:00
Andrea Odetti
c2baf8dc83 Use QHexView rather than qhexedit2.
It seems more supported and offers comments and metadata highlights.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-12-01 14:29:13 +00:00
Andrea Odetti
31340919de Move Qt UI to private member.
This way it is clear which variables comes from the ui component.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-11-30 15:48:48 +00:00
Andrea Odetti
54057134cb Remove warnings.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-11-30 11:20:59 +00:00
Andrea Odetti
2820e811f8 Extremely hard to measure.
But it seems ARGB32_Premul is (very) marginally better.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-11-29 20:31:31 +00:00
Andrea Odetti
ee09f828ee Better benchmark calculation:
1) Pure Video Hi Res and Text are the same thing
2) Realistic FPS was actually wrong as it would only CPU update the video for the first 10 frames

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-11-29 20:19:23 +00:00
Andrea Odetti
19c9193412 Use video mode in window title.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-11-29 20:18:29 +00:00
Andrea Odetti
f66e46ec1d Fix RGB to set alpha=255 or Qt makes the widget transparent.
NTSC does it already.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-11-29 20:17:43 +00:00
Andrea Odetti
00df2f93a5 Merge remote-tracking branch 'upstream/master'
# Conflicts:
#	source/RGBMonitor.cpp
2019-11-29 19:55:41 +00:00
Andrea Odetti
5ad8fb3e1b Factor some functions outside the loop to improve speed.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-11-27 17:41:22 +00:00
Andrea Odetti
9ca7485f52 Update VideoBenchmark code to differentiate screen image generation vs blitting.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-11-25 21:08:01 +00:00
Andrea Odetti
151c6c92f9 Add Video settings.
+ F9 to cycle video modes.
2019-11-24 21:06:55 +00:00
Andrea Odetti
17b43a9ded Avoid unused warning.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-11-24 19:30:58 +00:00
Andrea Odetti
256815eff9 Rationalise QApple options.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-11-24 19:30:34 +00:00
Andrea Odetti
7c61888447 Rename options -> preferenceData
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-11-24 17:43:43 +00:00
Andrea Odetti
43f0b140a6 Rename settings.* -> registry.*
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-11-24 17:34:37 +00:00
Andrea Odetti
35a81f8009 applen: add --log, --ntsc, and log time till first $C000 access. 2019-11-23 20:34:24 +00:00
Andrea Odetti
7529f5c659 Reworked the entire wondows.h replacement.
wincompat.h is a stripped down version coming from linapple-pie with the bare minimum common types.
Each group of functions in its own file.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-11-23 18:17:44 +00:00
Andrea
725510f238
Update linux.md 2019-11-22 20:50:02 +00:00
Andrea Odetti
6f0a71a330 Merge remote-tracking branch 'upstream/master' into ntsc 2019-11-22 20:33:27 +00:00
Andrea Odetti
4792c2eeed Remove custon video processor in favour of AppleWin's.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-11-22 20:32:32 +00:00
Andrea Odetti
d18269fb2d First (succesful) attempt at using NTSC code in Linux.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-11-20 21:23:27 +00:00
Andrea Odetti
9c7abcab91 Compile NTSC * NTSC_CharSet from AppleWin.
Video is still duplicated.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-11-17 13:57:34 +00:00
Andrea Odetti
add4e526a9 Split dummies into duplicates of AppleWin files.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-11-16 17:01:11 +00:00
Andrea Odetti
4d0af5d3ca Added a custom version of QPainter which seems to perform much better 20%->11% CPU.
It only works if all images involved have the same format.
Using some typedefs, one can revert to the old QPixmap behaviour.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-11-16 17:00:35 +00:00
Andrea Odetti
54d418725e Add a few correct card names, so the snapshot loading does not fail.
But, these cards are still ignored.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-11-13 21:01:28 +00:00
Andrea Odetti
1da46e89e1 Small cosmetic improvements.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-11-13 21:00:43 +00:00
Andrea Odetti
342697e983 Merge branch 'audio2' 2019-11-11 20:59:32 +00:00
Andrea Odetti
e638f63f6e Add safety check that ZeroMemory is never called on a c++ complex class.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-11-11 20:57:39 +00:00
Andrea Odetti
7d7e46f7ec Merge remote-tracking branch 'upstream/master' 2019-11-11 20:56:30 +00:00
Andrea
60ef2c5d26
Update linux.md 2019-11-10 19:39:09 +00:00
Andrea
d481b3c534
Update linux.md 2019-11-10 19:38:42 +00:00
Andrea Odetti
ced20877c2 Audio: rename physical -> volume.
Fix issue with settings not being propagated.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-11-10 19:05:46 +00:00
Andrea Odetti
8fc3747229 Move qhexedit files in their folder.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-11-10 18:54:43 +00:00
Andrea Odetti
c4a03e0434 Rename audio -> audiogenerator
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-11-10 18:48:02 +00:00
Andrea Odetti
5166731e5a Audio: add a few settings to the option menu.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-11-10 18:44:28 +00:00
Andrea Odetti
0778812560 First decent implementation of Audio Output.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-11-09 21:43:35 +00:00
Andrea Odetti
54a1bb4991 This is probably a better way to schedule execution.
One step ahead rather than one step behind.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-11-07 21:30:05 +00:00
Andrea Odetti
730e35150a Remove some warnings.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-11-06 22:56:08 +00:00
Andrea Odetti
fe63225065 Simplify fps count and repainting decision.
Just run @ 60 fps and repaint all the times.
Previous algorithm had a startup issue and ended up doing exactly the same.


Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-11-06 22:53:44 +00:00
Andrea Odetti
5572f937f0 Merge remote-tracking branch 'upstream/master' 2019-11-06 22:32:11 +00:00
Andrea Odetti
7c65e0f972 Add option to run without screen update in ncurses.
Useful to profile core.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-11-03 16:22:28 +00:00
Andrea Odetti
92c257d1e5 Improve error handling in applen and ability to build outside the source tree.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-11-03 10:21:02 +00:00
Andrea Odetti
3632a06c4b Merge remote-tracking branch 'upstream/master' 2019-11-03 09:42:36 +00:00
Andrea Odetti
f139a88cdb Untested list of packages required on Raspbian.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-11-03 09:36:16 +00:00
Andrea
98b8e6841f Update linux.md
Mention list of required packages in Fedora.
2019-11-03 09:36:16 +00:00
tomcw
8a90b15a36 SSC: Get initial modem status when COM port is first opened 2019-11-03 09:36:16 +00:00
tomcw
2529309e9e SSC: Support COM ports greater than 9 (#707) 2019-11-03 09:36:16 +00:00
Kelvin Lee
41a0b2f5d5 Debugger: Symbol loading: Fix random crash upon start up. (PR #694) 2019-11-03 09:36:16 +00:00
tomcw
e8a443020a Help: Debugger: Added row-80 - red 'x' for ALTZP 2019-11-03 09:36:16 +00:00
tomcw
720ff1606f 1.29.4.0: Updated version and History.txt 2019-11-03 09:36:16 +00:00
tomcw
250e481104 Fixed out-of-bounds global buffer access
. detected using VS2019 asan support
2019-11-03 09:36:16 +00:00
tomcw
bb645d82e1 Help: Debugger: Added BPMR & BPMW 2019-11-03 09:36:16 +00:00
TomCh
bb573c63ef Debugger: BPMR & BPMW (PR #710)
Extended BPM to also support BPMR and BPMW
Fixed BPM[R|W] 0:FFFF (ie. support a range of 0x10000)
2019-11-03 09:36:16 +00:00
Andrea Odetti
d44bc6c019 Improve cmake detection of required libraries.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-11-03 09:36:16 +00:00
Andrea Odetti
0aad738d0e Tiny cleanup.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-11-03 09:36:16 +00:00
tomcw
74d49aebbc Debugger display: minor refactor 2019-11-03 09:36:16 +00:00
tomcw
dcea8cde98 Debugger display (#666, #702):
. Video-scanner: when invisible use yellow (instead of red) (fixes #666)
. Soft-switches: row "80:" show a red 'x' when AltZP is set (#702)
2019-11-03 09:36:16 +00:00
tomcw
4a64bba6c8 History.txt: tweak date for 1.29.3.0 2019-11-03 09:36:16 +00:00
tomcw
906d28117c Disk: minor refactor 2019-11-03 09:36:16 +00:00
tomcw
715321ad4a Save-state: show an error MsgBox if old HDD v1 save-state and PC is in $Cnss HDD firmware 2019-11-03 09:36:16 +00:00
Andrea Odetti
9ce6592c5e Merge remote-tracking branch 'upstream/master' 2019-10-13 11:31:20 +01:00
Andrea Odetti
6c28c71e7f Merge remote-tracking branch 'upstream/master' 2019-10-12 14:29:08 +01:00
Andrea Odetti
c669c101e2 minizip 2.9.0 fixes the bug.
No need for the workaround.
2019-10-12 14:28:54 +01:00
Andrea Odetti
ba801e4e13 Avoid RAND_MAX overflow. 2019-10-12 14:26:52 +01:00
Andrea Odetti
d8f2976830 Merge remote-tracking branch 'upstream/master' 2019-10-05 11:29:49 +01:00
Andrea Odetti
7c5b3a643b Merge remote-tracking branch 'upstream/master' 2019-10-01 10:36:39 +01:00
Andrea Odetti
0a6de645e0 Incorporate chat * -> std::string conversion.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-09-21 09:58:29 +01:00
Andrea Odetti
52bd4ba3d8 Merge remote-tracking branch 'upstream/master' 2019-09-21 09:39:29 +01:00
Andrea Odetti
197c84d556 Add missing g_Slot2.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-09-12 21:01:42 +01:00
Andrea Odetti
fef75d878a Merge remote-tracking branch 'upstream/master' 2019-09-12 20:58:49 +01:00
Andrea Odetti
0783c4ec1d Merge remote-tracking branch 'upstream/master' 2019-09-07 08:32:37 +01:00
Andrea Odetti
907474c489 Add wrappers for StringCbXXXX functions and default RegLoadXXXX.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-08-26 10:27:38 +01:00
Andrea Odetti
ed82f9d9d6 Merge remote-tracking branch 'upstream/master'
# Conflicts:
#	source/StdAfx.h
2019-08-25 19:25:00 +01:00
Andrea Odetti
39812b3c36 Merge remote-tracking branch 'upstream/master' 2019-08-24 09:04:38 +01:00
Andrea Odetti
4d2febfb42 Linux changes for current version of AppleWin.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-08-10 16:16:44 +01:00
Andrea Odetti
850ceff343 Merge remote-tracking branch 'upstream/master' 2019-08-10 08:52:17 +01:00
Andrea Odetti
1776fc8aec Upstream changes.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-06-18 17:06:11 +01:00
Andrea Odetti
d9f1bfb12a Merge remote-tracking branch 'upstream/master' 2019-06-18 16:58:51 +01:00
Andrea Odetti
78ef2cc23c Merge remote-tracking branch 'upstream/master' 2019-06-07 19:49:37 +01:00
Andrea Odetti
f3ad4093c7 Update readme.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-04-27 14:58:37 +01:00
Andrea Odetti
aada654e60 Avoid uninitialised reads if the settings are not present.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-04-27 11:31:30 +01:00
Andrea Odetti
69ec0e7db0 Add support for RamWorks.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-04-22 16:02:06 +01:00
Andrea Odetti
90f0a6d6c4 Fix problem about removing a language card.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-04-21 20:58:54 +01:00
Andrea Odetti
bf6d4510a6 Merge remote-tracking branch 'upstream/master' 2019-04-20 21:04:02 +01:00
Andrea Odetti
020fb5c0cb Remove a deprecated function.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-04-20 21:01:25 +01:00
Andrea Odetti
224fcbce78 Add (better) support to select card in Slot 0.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-04-20 20:51:19 +01:00
Andrea Odetti
a51118cf35 Fix all disk related function due to Disk class introduction.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-04-20 16:43:52 +01:00
Andrea Odetti
f6719554e6 Merge remote-tracking branch 'upstream/master' 2019-04-19 21:14:05 +01:00
Andrea Odetti
a3061f55d6 Fix new Joystick interface.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-04-19 21:13:00 +01:00
Andrea Odetti
e04d5cac04 Merge tag 'v1.28.5.0' 2019-04-19 21:07:30 +01:00
Andrea Odetti
598cb2e70e Fix compilation.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-04-19 21:07:15 +01:00
Andrea Odetti
cbceb5c79f Merge tag 'v1.28.4.0' 2019-04-19 21:00:32 +01:00
Andrea Odetti
f1aa6d2e25 Merge tag 'v1.28.3.0' 2019-04-19 21:00:22 +01:00
Andrea Odetti
d6abf1a93a Fix compilation.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-04-19 21:00:09 +01:00
Andrea Odetti
4373e1ac61 Merge tag 'v1.28.2.0' 2019-04-19 20:55:57 +01:00
Andrea Odetti
7ce15903bf Compile RGBMonitor too.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-04-19 20:55:23 +01:00
Andrea Odetti
7f2310150b Merge tag 'v1.28.1.0' 2019-04-19 20:46:16 +01:00
Andrea Odetti
2ee0a01959 Merge tag 'v1.28.0.0'
# Conflicts:
#	source/SaveState.cpp

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-04-19 20:45:50 +01:00
Andrea Odetti
e68898daf4 Fix Version macros.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-04-19 20:42:25 +01:00
Andrea Odetti
5a737e988b Merge tag 'v1.27.13' 2019-04-19 20:29:40 +01:00
Andrea Odetti
629bbfb757 Add support for the LanguageCard in Slot0 switch.
(not 100% sure how it is supposed to work).


Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2019-04-19 20:27:17 +01:00
Andrea Odetti
0a087e40ae Merge remote-tracking branch 'upstream/master' 2018-11-18 16:23:26 +00:00
Andrea Odetti
ee2c70c389 Incorporate changes about LC.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2018-11-03 19:20:08 +00:00
Andrea Odetti
4f88325d3a Merge remote-tracking branch 'upstream/master' into LC 2018-11-03 19:04:32 +00:00
Andrea Odetti
b697be894d Merge remote-tracking branch 'upstream/master' 2018-10-14 15:22:10 +01:00
Andrea Odetti
d3abd9f2ac Merge remote-tracking branch 'upstream/master' 2018-09-13 20:49:32 +01:00
Andrea Odetti
16beff078d Merge remote-tracking branch 'upstream/master' 2018-09-09 20:03:26 +01:00
Andrea Odetti
d0bb3f5815 Merge remote-tracking branch 'upstream/master' 2018-08-25 21:18:04 +01:00
Andrea Odetti
14c5c820c1 Adapt to upstream changes.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2018-08-25 21:17:55 +01:00
Andrea Odetti
edc1c366fe Merge remote-tracking branch 'upstream/master' 2018-08-06 09:08:18 +01:00
Andrea Odetti
daadd42b63 Merge remote-tracking branch 'upstream/master' 2018-07-03 07:54:48 +01:00
Andrea Odetti
ae25b518a7 Merge remote-tracking branch 'upstream/master'
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>

# Conflicts:
#	source/StdAfx.h
2018-06-09 09:39:11 +01:00
Andrea Odetti
f20a463c36 Fix missing windows macro.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2018-05-05 19:45:41 +01:00
Andrea Odetti
aacf9528a2 Merge remote-tracking branch 'upstream/master' 2018-05-05 19:41:50 +01:00
Andrea Odetti
6b649bee1a Follow AppleWin and rename nCyclesLeft to uExecutedCycles.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2018-04-14 18:46:00 +01:00
Andrea Odetti
f0b4b8e43d Fix compilation errors.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2018-04-14 18:45:27 +01:00
Andrea Odetti
56fccbe621 Merge remote-tracking branch 'upstream/master' 2018-04-14 18:24:22 +01:00
Andrea Odetti
a8e1db3e58 Remove unused file.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2018-03-03 18:08:47 +00:00
Andrea Odetti
b29b69647d Fix code due to changes in recent merge from upstream.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2018-03-03 18:08:31 +00:00
Andrea Odetti
5efc8ca461 Merge remote-tracking branch 'upstream/master' 2018-03-03 17:59:09 +00:00
Andrea Odetti
cdd59a1e12 Fix indentation.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2018-03-03 17:58:39 +00:00
Andrea Odetti
a4ddef6826 A couple of changes lost during the recent merge.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2018-02-24 19:11:33 +00:00
Andrea Odetti
afa366259e Merge remote-tracking branch 'upstream/master'
# Conflicts:
#	source/Disk.h
#	source/DiskImageHelper.cpp
#	source/Harddisk.cpp
#	source/Harddisk.h
#	source/Memory.cpp


Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2018-02-24 19:03:45 +00:00
Andrea Odetti
5659dde498 Pause the emulator when Disks are swapped.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2018-02-13 20:02:17 +00:00
Andrea Odetti
cde7b12555 Add ability to swap floppy disks.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2018-02-13 08:42:47 +00:00
Andrea Odetti
ba8221d3ee Free resources on exit.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2018-02-13 08:39:17 +00:00
Andrea Odetti
2df7a7c67b Disk_t and HDD cannot free the memory in their destructor as they dont really own it.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2018-02-13 08:38:24 +00:00
Andrea Odetti
91050fc3bd Merge remote-tracking branch 'upstream/master' 2018-02-11 20:43:50 +00:00
Andrea Odetti
7a478fb545 Compile TestCPU6502 as well.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2018-02-11 20:43:26 +00:00
Andrea Odetti
9b58ce1a42 Better compatibility with AppleWin: stick to relative include paths.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2018-02-11 19:57:17 +00:00
Andrea Odetti
04f7492e6b For some reason the ncurses ALT-arrow key codes do not work any longer.
Has anything changed in ncurses?


Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2018-02-10 17:52:35 +00:00
Andrea
eeaaede75e
Create Linux readme file 2018-02-10 17:33:54 +00:00
Andrea Odetti
9218eb671e Try a better time slicing algorithm.
We keep a running timer since the last start, or reboot or pause and ensure we track it.

At the same time, a different full speed mode is necessary.
We run for up to 5 ms as long as the disk is spinning and restart all counters.

This will go in some configuration.


Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2018-02-09 21:16:57 +00:00
Andrea Odetti
30ac85b9c0 In GNOME it happens that the open file dialog is not displayed properly and become impossible to interact with it.
It is displayed elsewhere (different desktop, hidden???), and sometimes it is come back.
More often it forces to terminate the emulator.


Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2018-02-09 21:13:32 +00:00
Andrea Odetti
1b70ca4979 Fix PkgConfig for ncursesw and add libevdev.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2018-02-06 17:08:50 +00:00
Andrea Odetti
6985ef40e2 Use CMake / PkgConfig to find ncurses locations and flags.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2018-02-06 16:58:10 +00:00
Andrea Odetti
da7ac10987 Add AppleWin version number in the About dialog box.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2018-02-06 16:50:50 +00:00
Andrea Odetti
a27585d2a6 Add some tooltips and keyboard shortcut.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2018-02-06 16:24:36 +00:00
Andrea Odetti
7a6ad9f363 Ensure the MouseCard is properly reset when the emulator restarts.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2018-02-06 16:21:35 +00:00
Andrea Odetti
21156bb606 Merge remote-tracking branch 'upstream/master'
# Conflicts:
#	source/Disk.cpp
#	source/DiskImageHelper.h
#	source/Memory.cpp

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2018-02-03 20:35:04 +00:00
Andrea Odetti
c1631a1abf Merge remote-tracking branch 'upstream/master'
# Conflicts:
#	source/Disk.cpp
2018-01-07 20:19:42 +00:00
Andrea Odetti
c0623f9134 Merge remote-tracking branch 'upstream/master' 2017-11-30 19:31:38 +00:00
Andrea Odetti
b4098867bb Merge remote-tracking branch 'upstream/master' 2017-11-21 16:11:42 +00:00
Andrea Odetti
154923a039 Ensure the video is repainted after the title has changed.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-11-21 16:11:21 +00:00
Andrea Odetti
b5e5199eeb Move all configurations to a separate file.
Still not ideal as it is not straightforward to add options to places like the Video class.


Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-11-21 16:10:58 +00:00
Andrea Odetti
ea99fb0584 Merge remote-tracking branch 'upstream/master' 2017-10-29 16:27:20 +00:00
Andrea Odetti
0c9bec8af3 Merge remote-tracking branch 'upstream/master' 2017-10-20 20:10:34 +01:00
Andrea Odetti
59e570d8e2 Merge remote-tracking branch 'upstream/master' 2017-10-18 21:15:19 +01:00
Andrea Odetti
269cb6cfd1 Take screenshot.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-17 21:14:36 +01:00
Andrea Odetti
89618601b1 Fix double low resolution colors.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-16 20:45:08 +01:00
Andrea Odetti
0eaeaf60f8 To get decent benchmark results we need to force video repainting.
But it does not work with OpenGL.


Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-15 21:08:08 +01:00
Andrea Odetti
611c661d00 Add about dialogs.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-15 18:58:40 +01:00
Andrea Odetti
ae4be77382 Move MessageBox() to the interface to display it properly in Qt.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-15 18:58:23 +01:00
Andrea Odetti
d4fad7e8eb actionChange was a bit complicated.
Just use plain start / stop.


Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-15 18:24:00 +01:00
Andrea Odetti
3a620f8b92 Add support to load/save state.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-15 18:20:25 +01:00
Andrea Odetti
7c4f50c4fa Fix some problems reported by valgrind:
1) HDD is not a POD and so ZeroMemory does not replace a constructor
2) mismatch free / delete []
3) no need to a shared_ptr<BYTES>, new, just use a vector


Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-15 18:19:40 +01:00
Andrea Odetti
bcf57a4e19 Add a few buttons to the toolbar.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 20:42:23 +01:00
Andrea Odetti
8dd454af4d Add support for Double Low & Hi Resolution.
For Double Low Res, I am not sure the colors are correct.


Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
3231f86f87 Avoid using uninitialised data.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
3733da1af7 Remove configuration from libappleii and delegate it to the frontends.
In qapple we use QSettings.


Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
03de883889 Modularise CMakeLists.txt
qapple does not run at the moment: can find configuration file.


Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
00360bbe64 Add support for Mouse.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
348ba1ecd9 Use QGamepad in QApple.
This requires an interface as napple uses libevdev.


Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
6ec2408e44 Add viewer for (Windows) Registry.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
1334d461b4 Fix support to select clones.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
0f8f7da2b8 Add Qt ignore rules.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
8f92e63f45 Fix uninitialised data if the result is NULL.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
4873e1f020 Add and activate options for slot cards and computer type.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
8b458e61fb Handle hard disks and disk eject.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
2258d91208 Reuse the same preferences dialog, so the drop down menus keep the previous choices.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
86cc85bf8f Add options dialog to load floppy and hard disks.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
246e66d9be Address area: do not show 1 more row than necessary.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
5d00a41d66 Remove tear in cursor for !readOnly mode.
1) ensure the cursor rectangle is inside the character it belongs to
2) draw the same character again so it shows when the cursor blink is on


Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
520de12f58 Improve cursor in read only mode.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
17d75813a7 A couple of fixes.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
1c7f124977 Fix duplicate names of widgets.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
3eca669004 Add memory viewer based on a (modified) widget from
https://github.com/Simsys/qhexedit2


Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
416b461291 Finally some results in the optimisation of CPU usage:
1) Do not call Video::paint() with a scale != 1:1
2) For this reason we need to draw elsewhere
3) and finally scale the whole thing just once to the widget
4) QPixmap vs QImage: cant see the difference
5) QOpenGLWidget is 2x faster than QWidget but it has some flickering when resizing

On my i5-4460  CPU @ 3.20GHz with x2 zoom
TEXT: 4-5% CPU usage
HGR: 6-7% CPU usage


Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
138ff8f94d Use MouseInterface rather than dummy implementation.
Must be enabled in data.cpp via g_Slot4 and anyway no mouse events are enabled yet.


Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
b9c4789198 Fix MouseInterface to compile in linux.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
140b5bf7d4 Fix inverse lowercase in 80 column mode.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
1a75e9f0de And share the joystick with QApple.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
10339131fd Decouple Input from ncurses frontend to reuse it in QApple (Fedora does not package QGamepad yet).
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
d699dc98b8 And add Low Resolution color graphics as well.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
c1b7d96dd1 Add (slow) support for HiRes graphics.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
3da7d4ed55 Handle ESC key.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
8295c686e9 Clarify where 35:24 comes from.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
18e0d3b6b6 Qt does not seem to fire the timer event very precisely (target 5 ms, got often 16).
So we dynamically adjust the number of CPU cycles based on the actual gap.
Only problem is what to do for enhanced disk speed.
We simply block as long as the disk is spinning.


Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
b1644c01e5 Error message if a disk cannot be inserted.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
c6789ece7b Add benchmark and fix timerID values.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
ede695bcd6 Move VideoBenchmark to libapple to be reused.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
9c21b59827 typedef has been removed upstream.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
ba67de8d9a Add Reboot command.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
57934c1bc9 Add menu item to insert disks.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
1033c98028 Add const-nees to parameters.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
b3dc584fb0 Better handling of keys.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
1192f7b584 Fix window title, close event, scrollbars, fast timer when disk spins.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
fe0730c4d3 Various improvements.
Rudimentary keyboard input.
Resize/Zoom video.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
c9fb116464 Various improvements over the QLabel based approach.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
facf9aec25 Initial draft of a QT frontend.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
0c37816c28 Move FindResource to the interface as in QT it will be handled differently.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
ce124e0aa0 It is too easy to set the wrong CPU and then nothing works.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
91678645a7 Add option to save configuration on exit.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
c9a6d7688e Add option to create missing floppy disks.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
eba2cea5ca Display moving average of speed.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
e68748a158 Allow to control of high resolution graphics.
Horizontal resolution: x1 x2 x3 4 x5 x6 x7.
Vertical: x1 x2 x4.

Use Alt-arrows to change.


Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
a43cf5cf8a More uniform allocation of pixels in the 4th column to each sides with half the weight.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
6996c5fc47 Avoid various uninitialised memory errors while reading Registry.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
df53415d98 Add option to benchmark emulator.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
863a9d3671 Write a little measure about current execution speed.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
b63f232ebe Use evdev to handle a joystick.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
a79a4b4a4c Fix configuration.
If the key is mssing, the output variables should not be touched.


Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
26e377e3a1 Fix LowRes colors (swapping foreground and background).
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
d8d2cc2412 Clean at the end.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
ced5c39401 Reduce leaks.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
1d12b788ea Fix missing returns.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
ca7542f39a Read (part of) the registry.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
f42d7e9fcc Add option to control memory initialization.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
8515b20327 Add support to load the state from a snapshot file.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
0ee3225026 Fix a bug in Disk_t: ZeroMemory() does not work for non POD.
Disk_t is NOT a POD as it contains a std::string.
Simply zeroing the memory is not a replacement for a constructor or for a .clear() method.
This would cause access violation when the string strFilenameInZip is used (e.g. line 365).

It is possible that in VS a std::string full of zeros is valid.
This can be triggered inserting the same floppy in both drives.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
05a55c0735 Add ability to save state (use F12).
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
2aae3592c4 Rationalise a bit the command line arguments.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
ae4c010564 Anonymous namespace and indentation.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
2b60a1e0a7 Pass Ctrl-C to the emulator.
Use F2 to leave.


Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
97e672cf4d Add missing diagonal element to the ASCIIArt table.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
50b84e06fe Add support for a text mode high resolution graphics.
Using Unicode quarter blocks the effective resolution is (40x2)x(24x2).


Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
e7ddcd6b82 Small changes, but in particular wcolor_set to handle > 256 color pairs.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
c198c24a22 Compile & link (only) SaveState.cpp.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
5c4d499e14 Reuse old implementation of the VideoGetScannerAddress (a la 1.25).
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
ab831ed2db Rename to avoid clashes with Frame.h in a case insensitive filesystem.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
64d7994c71 Clean up the Frame and display disk information.
Report as well some measure of the ringing frequency of the speaker.


Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
031fcab519 Add support for Open & Solid Apple.
Page Up = Open
Page Down = Solid

One should probably leave the flag up for X ms rather than a single read.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
f625e36f5c Fix usage of getcwd.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
017dc307b2 Handle 80 columns mode.
ncurses windows handling move to a separate file.


Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
aa57d072bc Correct handling of all 256 text characters in both Standard and Alternate charecter set.
Change flash state every 16 frames.


Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
4ccfa0cc56 Add support for Low Resolution graphics.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
1fccde2892 Add libapple and simple ncurses frontend.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
ce0ced0c44 Use various replacements in StdAfx.h
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
Andrea Odetti
26f4532cb8 Minimal changes to ensure compilation in Linux / gcc.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
2017-10-14 19:18:44 +01:00
251 changed files with 22365 additions and 119 deletions

180
.github/workflows/ppa-release.yml vendored Normal file
View file

@ -0,0 +1,180 @@
name: Release
on:
push:
branches:
- master
schedule:
- cron: '0 0 * * *'
jobs:
build_rpm:
env:
REPO_URL: ${{ github.server_url }}/audetto/AppleWin
runs-on: ubuntu-18.04
strategy:
matrix:
include:
- os_name: fedora
os_codename: '34'
build_type: 'QT'
- os_name: fedora
os_codename: '35'
build_type: 'QT'
container: ${{ matrix.os_name }}:${{ matrix.os_codename }}
steps:
- run: dnf -y update && dnf -y install git ca-certificates curl gpg rsync file && dnf clean all
- name: Import GPG key
id: import_gpg
uses: crazy-max/ghaction-import-gpg@v4
with:
gpg_private_key: ${{ secrets.PACKAGE_SIGNING_KEY }}
passphrase: ''
- run: git config --global --add safe.directory /__w/AppleWin/AppleWin && git init && git remote add origin "$REPO_URL" && git fetch origin ${{ github.ref }} && git checkout ${{ github.ref_name }} && git submodule init && git submodule update
- run: CPACK_TYPE=RPM INSTALL_DEPS=${{ matrix.build_type }} bash ./source/linux/build.sh
- run: cd build/packages && rm -rf ./_CPack_Packages
- run: cd build/packages && dpkg-scanpackages --multiversion . > Packages
- run: cd build/packages && gzip -k -f Packages
- run: cd build/packages && apt-ftparchive release . > Release
- run: cd build/packages && gpg --default-key "${{ secrets.PACKAGE_SIGNING_EMAIL }}" -abs -o - Release > Release.gpg
- run: cd build/packages && gpg --default-key "${{ secrets.PACKAGE_SIGNING_EMAIL }}" --clearsign -o - Release > InRelease
- uses: actions/upload-artifact@v2
with:
name: ${{ matrix.os_name }}-${{ matrix.os_codename }}
path: ./build/packages/**/*
build_deb:
env:
DEBIAN_FRONTEND: noninteractive
REPO_URL: ${{ github.server_url }}/audetto/AppleWin
runs-on: ubuntu-18.04
strategy:
matrix:
include:
- os_name: debian
os_codename: bullseye
build_type: 'QT'
has_backports: backports
- os_name: debian
os_codename: bookworm
build_type: 'QT'
- os_name: ubuntu
os_codename: bionic
is_lts: lts
build_type: 'WITHOUT_QT'
- os_name: ubuntu
os_codename: focal
is_lts: lts
build_type: 'QT'
- os_name: ubuntu
os_codename: hirsute
build_type: 'QT'
- os_name: ubuntu
os_codename: impish
build_type: 'QT'
container: ${{ matrix.os_name }}:${{ matrix.os_codename }}
steps:
- run: apt-get update && apt-get install -y --no-install-recommends git ca-certificates apt-transport-https curl gpg gpg-agent lsb-release dpkg-dev apt-utils rsync file
- name: Import GPG key
id: import_gpg
uses: crazy-max/ghaction-import-gpg@v4
with:
gpg_private_key: ${{ secrets.PACKAGE_SIGNING_KEY }}
passphrase: ''
- if: matrix.has_backports == 'backports'
run: echo 'deb http://deb.debian.org/debian ${{ matrix.os_codename }}-backports main' >> /etc/apt/sources.list
- if: matrix.is_lts == 'lts'
run: curl -L https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | gpg --dearmor - | tee /usr/share/keyrings/kitware-archive-keyring.gpg >/dev/null
- if: matrix.is_lts == 'lts'
run: echo "deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/${{ matrix.os_name }}/ $(lsb_release -cs) main" | tee /etc/apt/sources.list.d/kitware.list >/dev/null
- run: git config --global --add safe.directory /__w/AppleWin/AppleWin && git init && git remote add origin "$REPO_URL" && git fetch origin ${{ github.ref }} && git checkout ${{ github.ref_name }} && git submodule init && git submodule update
- run: INSTALL_DEPS=${{ matrix.build_type }} bash ./source/linux/build.sh
- run: cd build/packages && rm -rf ./_CPack_Packages
- run: cd build/packages && dpkg-scanpackages --multiversion . > Packages
- run: cd build/packages && gzip -k -f Packages
- run: cd build/packages && apt-ftparchive release . > Release
- run: cd build/packages && gpg --default-key "${{ secrets.PACKAGE_SIGNING_EMAIL }}" -abs -o - Release > Release.gpg
- run: cd build/packages && gpg --default-key "${{ secrets.PACKAGE_SIGNING_EMAIL }}" --clearsign -o - Release > InRelease
- uses: actions/upload-artifact@v2
with:
name: ${{ matrix.os_name }}-${{ matrix.os_codename }}
path: ./build/packages/**/*
deploy:
needs:
- build_deb
- build_rpm
runs-on: ubuntu-18.04
strategy:
max-parallel: 1
matrix:
include:
- os_name: fedora
os_codename: '34'
- os_name: fedora
os_codename: '35'
- os_name: debian
os_codename: bullseye
- os_name: debian
os_codename: bookworm
- os_name: ubuntu
os_codename: bionic
- os_name: ubuntu
os_codename: focal
- os_name: ubuntu
os_codename: hirsute
- os_name: ubuntu
os_codename: impish
steps:
- uses: actions/checkout@v3
with:
repository: audetto/AppleWin
fetch-depth: 1
ref: ${{ github.event.inputs.tag }}
- uses: actions/download-artifact@v2
with:
name: ${{ matrix.os_name }}-${{ matrix.os_codename }}
path: packages
- name: Deploy
uses: JamesIves/github-pages-deploy-action@v4.3.0
with:
branch: gh-pages
folder: packages
target-folder: packages/${{ matrix.os_name }}/dists/${{ matrix.os_codename }}

65
.gitignore vendored
View file

@ -183,3 +183,68 @@ UpgradeLog*.htm
# Microsoft Fakes
FakesAssemblies/
# Linux
CMakeCache.txt
CMakeFiles
CMakeScripts
Testing
Makefile
cmake_install.cmake
install_manifest.txt
compile_commands.json
CTestTestfile.cmake
*.so
*.a
Disks/
# Qt
# C++ objects and libs
*.slo
*.lo
*.o
*.a
*.la
*.lai
*.so
*.dll
*.dylib
# Qt-es
object_script.*.Release
object_script.*.Debug
*_plugin_import.cpp
/.qmake.cache
/.qmake.stash
*.pro.user
*.pro.user.*
*.qbs.user
*.qbs.user.*
*.moc
moc_*.cpp
moc_*.h
qrc_*.cpp
ui_*.h
*.qmlc
*.jsc
Makefile*
*build-*
# Qt unit tests
target_wrapper.*
# QtCreator
*.autosave
# QtCtreator Qml
*.qmlproject.user
*.qmlproject.user.*
# QtCtreator CMake
CMakeLists.txt.user*
# VSCode
.vscode

9
.gitmodules vendored Normal file
View file

@ -0,0 +1,9 @@
[submodule "source/frontends/qt/QHexView"]
path = source/frontends/qt/QHexView
url = ../../Dax89/QHexView.git
[submodule "source/frontends/sdl/imgui/imgui"]
path = source/frontends/sdl/imgui/imgui
url = ../../ocornut/imgui
[submodule "source/frontends/sdl/imgui/imgui_club"]
path = source/frontends/sdl/imgui/imgui_club
url = ../../ocornut/imgui_club

38
.travis.yml Normal file
View file

@ -0,0 +1,38 @@
language: cpp
branches:
only:
- master
matrix:
include:
# disabled as too expensive
# - name: "AppleWin on Windows"
# os: windows
# script: ./CIBuild.bat
- name: "AppleWin on Linux"
os: linux
dist: focal
arch: amd64
script: source/linux/build.sh
addons:
apt:
packages:
- cmake
- libyaml-dev
- libminizip-dev
- qtbase5-dev
- qtmultimedia5-dev
- libqt5gamepad5-dev
- libboost-program-options-dev
- libncurses-dev
- libevdev-dev
- libsdl2-dev
- libsdl2-image-dev
- libgles-dev
- libpcap-dev
- libslirp-dev

View file

@ -114,6 +114,7 @@
<ClInclude Include="source\StrFormat.h" />
<ClInclude Include="source\SynchronousEventManager.h" />
<ClInclude Include="source\Tape.h" />
<ClInclude Include="source\Tfe\IPRaw.h" />
<ClInclude Include="source\Tfe\NetworkBackend.h" />
<ClInclude Include="source\Tfe\Bpf.h" />
<ClInclude Include="source\Tfe\Ip6_misc.h" />
@ -222,6 +223,7 @@
<ClCompile Include="source\StrFormat.cpp" />
<ClCompile Include="source\SynchronousEventManager.cpp" />
<ClCompile Include="source\Tape.cpp" />
<ClCompile Include="source\Tfe\IPRaw.cpp" />
<ClCompile Include="source\Tfe\NetworkBackend.cpp" />
<ClCompile Include="source\Tfe\PCapBackend.cpp" />
<ClCompile Include="source\Tfe\tfearch.cpp">
@ -467,7 +469,7 @@
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>htmlhelp.lib;comctl32.lib;winmm.lib;dsound.lib;dxguid.lib;version.lib;strmiids.lib;dinput8.lib;user32.lib;gdi32.lib;advapi32.lib;shell32.lib;comdlg32.lib;ole32.lib;wsock32.lib;shlwapi.lib;ddraw.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>iphlpapi.lib;htmlhelp.lib;comctl32.lib;winmm.lib;dsound.lib;dxguid.lib;version.lib;strmiids.lib;dinput8.lib;user32.lib;gdi32.lib;advapi32.lib;shell32.lib;comdlg32.lib;ole32.lib;wsock32.lib;shlwapi.lib;ddraw.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalManifestDependencies>"type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'"</AdditionalManifestDependencies>
<MinimumRequiredVersion>5.01</MinimumRequiredVersion>
</Link>
@ -495,7 +497,7 @@
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>htmlhelp.lib;comctl32.lib;winmm.lib;dsound.lib;ddraw_lib\x86\dxguid.lib;version.lib;strmiids.lib;dinput8.lib;user32.lib;gdi32.lib;advapi32.lib;shell32.lib;comdlg32.lib;ole32.lib;wsock32.lib;shlwapi.lib;ddraw_lib\x86\ddraw.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>iphlpapi.lib;htmlhelp.lib;comctl32.lib;winmm.lib;dsound.lib;ddraw_lib\x86\dxguid.lib;version.lib;strmiids.lib;dinput8.lib;user32.lib;gdi32.lib;advapi32.lib;shell32.lib;comdlg32.lib;ole32.lib;wsock32.lib;shlwapi.lib;ddraw_lib\x86\ddraw.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalManifestDependencies>"type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'"</AdditionalManifestDependencies>
<MinimumRequiredVersion>5.01</MinimumRequiredVersion>
</Link>
@ -522,7 +524,7 @@
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>htmlhelp.lib;comctl32.lib;winmm.lib;dsound.lib;dxguid.lib;version.lib;strmiids.lib;dinput8.lib;user32.lib;gdi32.lib;advapi32.lib;shell32.lib;comdlg32.lib;ole32.lib;wsock32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>iphlpapi.lib;htmlhelp.lib;comctl32.lib;winmm.lib;dsound.lib;dxguid.lib;version.lib;strmiids.lib;dinput8.lib;user32.lib;gdi32.lib;advapi32.lib;shell32.lib;comdlg32.lib;ole32.lib;wsock32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalManifestDependencies>"type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'"</AdditionalManifestDependencies>
<MinimumRequiredVersion>5.01</MinimumRequiredVersion>
</Link>
@ -553,7 +555,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>htmlhelp.lib;comctl32.lib;winmm.lib;dsound.lib;dxguid.lib;version.lib;strmiids.lib;dinput8.lib;user32.lib;gdi32.lib;advapi32.lib;shell32.lib;comdlg32.lib;ole32.lib;wsock32.lib;shlwapi.lib;ddraw.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>iphlpapi.lib;htmlhelp.lib;comctl32.lib;winmm.lib;dsound.lib;dxguid.lib;version.lib;strmiids.lib;dinput8.lib;user32.lib;gdi32.lib;advapi32.lib;shell32.lib;comdlg32.lib;ole32.lib;wsock32.lib;shlwapi.lib;ddraw.lib;%(AdditionalDependencies)</AdditionalDependencies>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<AdditionalManifestDependencies>"type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'"</AdditionalManifestDependencies>
<MinimumRequiredVersion>5.01</MinimumRequiredVersion>
@ -586,7 +588,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>htmlhelp.lib;comctl32.lib;winmm.lib;dsound.lib;ddraw_lib\x86\dxguid.lib;version.lib;strmiids.lib;dinput8.lib;user32.lib;gdi32.lib;advapi32.lib;shell32.lib;comdlg32.lib;ole32.lib;wsock32.lib;shlwapi.lib;ddraw_lib\x86\ddraw.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>iphlpapi.lib;htmlhelp.lib;comctl32.lib;winmm.lib;dsound.lib;ddraw_lib\x86\dxguid.lib;version.lib;strmiids.lib;dinput8.lib;user32.lib;gdi32.lib;advapi32.lib;shell32.lib;comdlg32.lib;ole32.lib;wsock32.lib;shlwapi.lib;ddraw_lib\x86\ddraw.lib;%(AdditionalDependencies)</AdditionalDependencies>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<AdditionalManifestDependencies>"type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'"</AdditionalManifestDependencies>
<MinimumRequiredVersion>5.01</MinimumRequiredVersion>
@ -619,7 +621,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>htmlhelp.lib;comctl32.lib;winmm.lib;dsound.lib;dxguid.lib;version.lib;strmiids.lib;dinput8.lib;user32.lib;gdi32.lib;advapi32.lib;shell32.lib;comdlg32.lib;ole32.lib;wsock32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>iphlpapi.lib;htmlhelp.lib;comctl32.lib;winmm.lib;dsound.lib;dxguid.lib;version.lib;strmiids.lib;dinput8.lib;user32.lib;gdi32.lib;advapi32.lib;shell32.lib;comdlg32.lib;ole32.lib;wsock32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<AdditionalManifestDependencies>"type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'"</AdditionalManifestDependencies>
<MinimumRequiredVersion>5.01</MinimumRequiredVersion>

View file

@ -259,6 +259,9 @@
<ClCompile Include="source\Uthernet2.cpp">
<Filter>Source Files\Uthernet</Filter>
</ClCompile>
<ClCompile Include="source\Tfe\IPRaw.cpp">
<Filter>Source Files\Uthernet</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="source\CommonVICE\6510core.h">
@ -594,6 +597,9 @@
<ClInclude Include="source\Uthernet2.h">
<Filter>Source Files\Uthernet</Filter>
</ClInclude>
<ClInclude Include="source\Tfe\IPRaw.h">
<Filter>Source Files\Uthernet</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Image Include="resource\Applewin.bmp">

10
CIBuild.bat Normal file
View file

@ -0,0 +1,10 @@
rem Commands to build AppleWin on travis
setlocal
choco install visualstudio2019community
choco install visualstudio2019-workload-nativedesktop
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\Tools\VsMSBuildCmd.bat"
MSBuild.exe /p:Configuration=Release AppleWinExpress2019.sln

94
CMakeLists.txt Normal file
View file

@ -0,0 +1,94 @@
cmake_minimum_required(VERSION 3.13)
project(applewin HOMEPAGE_URL "https://github.com/audetto/AppleWin")
option(BUILD_APPLEN "build ncurses frontend")
option(BUILD_QAPPLE "build Qt5 frontend")
option(BUILD_SA2 "build SDL2 frontend")
option(BUILD_LIBRETRO "build libretro core")
if (NOT (BUILD_APPLEN OR BUILD_QAPPLE OR BUILD_SA2 OR BUILD_LIBRETRO))
message(NOTICE "Building everything by default")
set(BUILD_APPLEN ON)
set(BUILD_QAPPLE ON)
set(BUILD_SA2 ON)
set(BUILD_LIBRETRO ON)
endif()
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_compile_options(-Werror=return-type)
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
add_compile_options(-Werror=format -Wno-error=format-overflow -Wno-error=format-truncation -Wno-psabi)
endif()
MESSAGE("CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}")
MESSAGE("CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}")
MESSAGE("CMAKE_CXX_FLAGS_RELEASE: ${CMAKE_CXX_FLAGS_RELEASE}")
MESSAGE("CMAKE_CXX_FLAGS_DEBUG: ${CMAKE_CXX_FLAGS_DEBUG}")
MESSAGE("CMAKE_CXX_FLAGS_RELWITHDEBINFO: ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
# this only affects common2, the others are already build with fPIC by default
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
execute_process(COMMAND uname -n
OUTPUT_VARIABLE UNAME
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(${UNAME} STREQUAL raspberrypi)
# it is too slow and might cause out of memory issues
# more forensic is required
MESSAGE(NOTICE "Raspberry Pi detected: IPO disabled")
else()
include(CheckIPOSupported)
check_ipo_supported()
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION FALSE)
endif()
include_directories(source)
add_subdirectory(source)
add_subdirectory(source/linux/libwindows)
add_subdirectory(test/TestCPU6502)
if (BUILD_LIBRETRO OR BUILD_APPLEN OR BUILD_SA2)
add_subdirectory(source/frontends/common2)
endif()
if (BUILD_APPLEN)
add_subdirectory(source/frontends/ncurses)
endif()
if (BUILD_QAPPLE)
add_subdirectory(source/frontends/qt)
endif()
if (BUILD_SA2)
add_subdirectory(source/frontends/sdl)
endif()
if (BUILD_LIBRETRO)
add_subdirectory(source/frontends/libretro)
endif()
file(STRINGS resource/version.h VERSION_FILE LIMIT_COUNT 1)
string(REGEX MATCH "#define APPLEWIN_VERSION (.*)" _ ${VERSION_FILE})
string(REPLACE "," "." VERSION ${CMAKE_MATCH_1})
set(CPACK_PACKAGE_VERSION ${VERSION})
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Apple ][ emulator for Linux")
set(CPACK_PACKAGE_CONTACT "audetto <mariofutire@gmail.com>")
set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT)
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS "ON")
set(CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS "ON")
set(CPACK_RPM_PACKAGE_LICENSE "GPLv2")
set(CPACK_RPM_PACKAGE_GROUP "Applications/Emulators")
# RPM dependencies are automatic
include(CPack)

View file

@ -15,7 +15,7 @@ Peripheral cards and add-on hardware supported:
- Apple IIe Extended 80-Column Text Card and RamWorks III (8MB)
- RGB cards: Apple's Extended 80-Column Text/AppleColor Adaptor Card, 'Le Chat Mauve' Féline and Eve.
- CP/M SoftCard
- Uthernet I (ethernet card)
- Uthernet I and II (ethernet cards)
- Language Card and Saturn 64/128K for Apple II/II+
- 4Play and SNES MAX joystick cards
- VidHD card (functionality limited to IIgs' Super Hi-Res video modes)

View file

@ -8,6 +8,19 @@ https://github.com/AppleWin/AppleWin/issues/new
Tom Charlesworth
1.30.9.0 - 23 Mar 2022
----------------------
. [Change #518] Support Uthernet II card in slot 3. [audetto]
- EG. Use with Contiki, A2osX, ii-vision, a2stream etc.
- Support for W5100 modes: TCP, UDP, IPRAW and MACRAW (no support for PPPoE mode, interrupts and SPI).
. [Bug #1066] Fix for save-states where (eg) disk image name contains '#' character.
. [Bug #1017] Fix for printer interface where character got output twice.
. [PR #1031 + others] Internal: refactor string output handling. [kiyolee]
. Change: default install of AppleWin now sets slot 3 as empty (was Uthernet I card)
. Fix 6522 bug: IFR.T2 was always set when counter.b15=1
1.30.8.0 - 8 Feb 2022
---------------------
. [Bug #1023] WOZ support: Tweak to track sync support.

View file

@ -35,7 +35,7 @@
X 2002:2003
Released post 1.30.7.0
2.9.1.0 Added: Bookmarks now have their own indicator (a number with a box around it) and replace the ":" seperator. Updated Debug_Font.bmp
2.9.1.0 Added: Bookmarks now have their own indicator (a number with a box around it) and replace the ":" separator. Updated Debug_Font.bmp
.18 Fixed: Resetting bookmarks wasn't setting the total bookmarks back to zero.
.17 Fixed: If all bookmarks were used then setting a new one wouldn't update an existing one to the new address.

View file

@ -21,7 +21,7 @@
<p style="MARGIN-LEFT: 40px">Bob Sander-Cederlof: Applesoft Symbols (<a href="http://www.txbobsc.com/scsc/scdocumentor/index.html">http://www.txbobsc.com/scsc/scdocumentor/</a> S-C DocuMentor: Applesoft)</p>
<p style="MARGIN-LEFT: 40px">David Schmidt: Updates to this help file</p>
<p style="MARGIN-LEFT: 40px">Mike Harvey, Founder &amp; Editor of Nibble Magazine: For providing us Apple fans the pleasure of eagerly awaiting each next month's issue to learn about the Apple! (<a href="http://www.nibblemagazine.com/">http://www.nibblemagazine.com/</a>)</p>
<p style="MARGIN-LEFT: 40px">Andrea Odetti: working on making the source code more portable</p>
<p style="MARGIN-LEFT: 40px">Andrea Odetti: working on making the source code more portable & Uthernet II card support</p>
<p style="MARGIN-LEFT: 40px">Iván Izaguirre: Taiwanese Copam Base64A Apple II clone</p>
<p style="MARGIN-LEFT: 40px">Arnaud C: debugger suggestions and help with 6502/6522/video timing issues</p>
<p style="MARGIN-LEFT: 40px">Cyril Lambin: RGB card/monitor rendering, debugger improvements</p>

View file

@ -78,7 +78,7 @@
<strong>Ethernet Settings...:</strong><br>
This allows to choose which network interface card (NIC) you want to
use with the Uthernet card.<br>
use with the Uthernet or Uthernet II card.<br>
<br>
<strong>Emulation Speed Control:</strong><br>

View file

@ -32,7 +32,7 @@
<li>Parallel Printer card</li>
<li>Super Serial card</li>
<li>No-Slot clock</li>
<li>Uthernet card</li>
<li>Uthernet & Uthernet II cards</li>
<li>4Play & SNES MAX joystick cards</li>
<li>VidHD card</li>
</ul>

View file

@ -31,7 +31,7 @@
<li><a href="sound.html">Sound</a>
<li><a href="clock.html">Clock</a>
<li><a href="card-ssc.html">Super Serial card</a>
<li><a href="uthernet.html">Uthernet network card</a>
<li><a href="uthernet.html">Uthernet network cards</a>
<li><a href="configuration.html">AppleWin Configuration</a>
<li><a href="dbg-toc-intro.html">Using the Debugger</a>
<li><a href="resources.html">Resources</a></li>

View file

@ -1,22 +1,23 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Uthernet network card</title>
<title>Uthernet network cards</title>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
</head>
<body style="FONT-FAMILY: verdana; BACKGROUND-COLOR: rgb(255,255,255)" alink="#008000"
link="#008000" vlink="#008000">
<h2 style="COLOR: rgb(0,128,0)">Uthernet network card</h2>
<h2 style="COLOR: rgb(0,128,0)">Uthernet network cards</h2>
<hr size="4">
<p style="FONT-WEIGHT: bold">Overview:
</p>
<P>The Uthernet network card coupled with the Contiki OS allows you to browse the
<P>The Uthernet network cards coupled with the Contiki OS allow you to browse the
internet on your Apple.</P>
<P style="FONT-WEIGHT: bold">Acknowledgment:
</P>
<P>Uthernet (TFE) support in Applewin was made possible by implementing the GPL
<P>Uthernet (TFE) support in AppleWin was made possible by implementing the GPL
source written by Spiro Trikaliotis for the Vice emulator - <A href="http://vice-emu.sourceforge.net/index.html#developers">
http://vice-emu.sourceforge.net/index.html#developers</A></P>
<P><A href="https://a2retrosystems.com/">Uthernet II</A> support in AppleWin has been contributed by Andrea (audetto) Odetti.</P>
<P style="FONT-WEIGHT: bold">Details:
</P>
<P>To enable ethernet support in AppleWin you must first download and install
@ -35,15 +36,15 @@
<P>After AppleWin starts, select the settings icon and then select the ethernet
settings button.
</P>
<P>Uthernet will be disabled. Select Uthernet from the list of available ethernet
emulations (currently the only one).
<P>Uthernet will be disabled. Select Uthernet or Uthernet II from the list of available ethernet
emulations.
</P>
<P>Select the ethernet interface you want to work with. This must be a physical
ethernet interface.
</P>
<P>If you have more than one interface you may need to select them in turn in order
to get the text description for each interface vs what Npcap likes to use for
a reference. Select Ok. and then close AppleWin.
a reference.
</P>
<P><span style="font-weight: bold;">Note:</span> Wireless does not work
with WinPcap (but see <A href="uthernet-wifi-workaround.html">WiFi Workaround</A>).
@ -56,7 +57,7 @@
also grab a copy of the Uthernet/Contiki getting started guide <A href="http://www.a2retrosystems.com/a2UtherManual.pdf">
http://www.a2retrosystems.com/a2UtherManual.pdf</A>
</P>
<P>When you run AppleWin again, select the contiki80pri.dsk image. Boot AppleWin.
<P>Select the contiki80pri.dsk image. Boot AppleWin.
</P>
<P>Once Contiki is loaded then press Enter to clear the welcome screen and press
ESC for a menu.
@ -87,5 +88,14 @@
if you are still having difficulty then you should refer to the VICE network
support page for additional information - <A href="http://vicekb.trikaliotis.net/13-005.shtml">
http://vicekb.trikaliotis.net/13-005.shtml</A></P>
</body>
<P style="FONT-WEIGHT: bold">Uthernet II:
</P>
<P>Most features of the Uthernet II are emulated, with the following caveats:
<ul>
<li>PPPoE, interrupts and SPI are not implemented</li>
<li>server side is not well tested</li>
<li>after loading a save-state file, TCP and UDP sockets are closed</li>
</ul>
</P>
</body>
</html>

176
linux.md Normal file
View file

@ -0,0 +1,176 @@
# Linux
## Structure
There are 4 projects
* libapple: the core emulator files
* applen: a frontend based on ncurses
* qapple: Qt frontend
* sa2: SDL2 frontend
* libra2: a libretro core
The main goal is to reuse the AppleWin source files without changes: only where really necessary the AppleWin source files have
been modified.
## What works
Almost everything works, except the serial port, SNES-MAX and FourPlay.
The UI has been rewritten in Qt or ImGui.
The rest works very well.
Uthernet I is supported via `libpcap`, but it requires elevated capabilities:
`sudo setcap cap_net_raw=ep ./sa2`
Unfortunately, this must be reapplied after every build.
Most of the debugger now works (in the ImGui version).
## New features
Uthernet II is supported too and by default uses `libslirp` which does *not* require elevated capabilities. Use the ImGui settings to enable it.
`libslirp` is not packaged on Raspberry Pi OS. `libpcap` will be used instead, unless the user manually compiles and installs [libslirp](https://gitlab.freedesktop.org/slirp/libslirp).
Audio files can be read via the cassette interface (SDL Version). Just drop a `wav` file into the emulator. Tested with all the formats from [asciiexpress](https://asciiexpress.net/).
## Executables
### sa2
This is your best choice, in particular the ImGui version.
TL;DR: just run ``sa2``
See [sa2](source/frontends/sdl/README.md) for more details.
### applen
Frontend based on ncurses, with a ASCII art graphic mode.
Keyboard shortcuts
* ``F2``: reset the machine
* ``F3``: terminate the emulator
* ``F11``, ``F12``: Save, Load Snapshot
* ``ALT-RIGHT``: wider hi res graphis
* ``ALT-LEFT``: narrower hi res graphics
* ``ALT-UP``: vertical hi res (smaller)
* ``ALT-DOWN``: vertical hi res (bigger)
In order to properly appreciate the wider hi res graphics, open a big terminal window and choose a small font size.
Try ``CTRL-`` as well if ``ALT-`` does not work: terminals do not report a consistent keycode for these combinations.
The joystick uses evdev (``--device-name /dev/input/by-id/id_of_device``).
### qapple
This is based on Qt.
* keyboard shortcuts are listed in the menu entries
* joystick: it uses QtGamepad
* emulator runs in the main UI thread
* Qt timers are very coarse: the emulator needs to dynamically adapt the cycles to execute
* the app runs at 60FPS with correction for uneven timer deltas.
* full speed when disk spins execute up to 5 ms real wall clock of emulator code (then returns to Qt)
* audio is supported and there are a few configuration options to tune the latency (default very conservative 200ms)
* Open Apple and Solid Apple can be emulated using AltGr and Menu (unfortunately, Alt does not work well)
* ``yaml`` files can be dropped to restore a saved state
### ra2
There is an initial [libretro](https://docs.libretro.com/development/cores/developing-cores/) core.
A retropad can be plugged in port 1 (with or without analog stick).
Keyboard emulation
* ``JOYPAD_R``: equivalent to ``F9`` to cycle video types
* ``JOYPAD_L``: equivalent to ``CTRL-SHIFT-F6`` to cycle 50% scan lines
* ``START``: equivalent to ``F2`` to reset the machine
In order to have a better experience with the keyboard, one should probably enable *Game Focus Mode* (normally Scroll-Lock) to disable hotkeys.
Video works, but the vertical flip is done in software.
Audio (speaker) works.
Easiest way to run from the ``build`` folder:
``retroarch -L source/frontends/libretro/applewin_libretro.so ../bin/MASTER.DSK``
## Build
The project can be built using cmake from the top level directory.
qapple can be managed from Qt Creator as well and the 2 have coexisted so far, but YMMV.
### Checkout
```
git clone https://github.com/audetto/AppleWin.git --recursive
cd AppleWin
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=RELEASE ..
make
```
### Frontend selection
There are 4 `cmake` variables to selectively enable frontends: `BUILD_APPLEN`, `BUILD_QAPPLE`, `BUILD_SA2` and `BUILD_LIBRETRO`.
Usage:
```
cmake -DBUILD_SA2=ON -DBUILD_LIBRETRO=ON ..
```
or use `cmake-gui` (if none is selected, they are all built).
### Fedora
On Fedora 35, from a fresh installation, install all packages from [fedora.list.txt](source/linux/fedora.list.txt).
### Raspberry Pi OS, Ubuntu and other Debian distributions
Install all packages from [raspbian.list.txt](source/linux/raspbian.list.txt).
You can use `sudo apt-get -y install $(cat raspbian.list.txt)` for an automated installation.
See [Travis](.travis.yml) CI too.
### Packaging
It is possible to create `.deb` and `.rpm` packages using `cpack`. Use `cpack -G DEB` or `cpack -G RPM` from the build folder. It is best to build packages for the running system.
## Speed
### Fedora
Intel(R) Core(TM) i5-4460 CPU @ 3.20GHz
Full update = 582 MHz
| Video Stype | Video update |
| :--- | ---: |
| RGB Monitor | 39 |
| NTSC Monitor | 27 |
| Color TV | 25 |
| B&W TV | 27 |
| Amber Monitor | 31 |
### Raspbian
Pi 3B+
Full update = 54 MHz
| Video Stype | Video update |
| :--- | ---: |
| RGB Monitor | 5.3 |
| NTSC Monitor | 3.6 |
| Color TV | 2.6 |
| B&W TV | 2.9 |
| Amber Monitor | 4.5 |

View file

@ -1,4 +1,4 @@
#define APPLEWIN_VERSION 1,30,8,0
#define APPLEWIN_VERSION 1,30,9,0
#define xstr(a) str(a)
#define str(a) #a

265
source/CMakeLists.txt Normal file
View file

@ -0,0 +1,265 @@
include(FindPkgConfig)
include(FindZLIB)
find_package(ZLIB REQUIRED)
pkg_search_module(YAML REQUIRED yaml-0.1)
pkg_search_module(MINIZIP REQUIRED minizip)
pkg_search_module(SLIRP slirp)
if ("${SLIRP_FOUND}" STREQUAL "")
message(WARNING "'libslirp' not found. Will use 'libpcap' instead")
endif()
pkg_search_module(PCAP libpcap)
if ("${PCAP_FOUND}" STREQUAL "")
# old versions of pcap do not work with pkg-config
# this is necessary on Rapsberri Pi OS
execute_process(COMMAND pcap-config --cflags
OUTPUT_VARIABLE PCAP_INCLUDE_DIRS
OUTPUT_STRIP_TRAILING_WHITESPACE
RESULT_VARIABLE STATUS)
if ("${STATUS}" STREQUAL "0")
message("Found 'libpcap' via pcap-config")
else()
message(FATAL_ERROR "Cannot locate 'libpcap-dev'")
endif()
execute_process(COMMAND pcap-config --libs
OUTPUT_VARIABLE PCAP_LIBRARIES
OUTPUT_STRIP_TRAILING_WHITESPACE)
endif()
find_package(Boost REQUIRED)
set(SOURCE_FILES
Tfe/tfearch.cpp
Tfe/tfesupp.cpp
Tfe/NetworkBackend.cpp
Tfe/PCapBackend.cpp
Tfe/IPRaw.cpp
Debugger/Debug.cpp
Debugger/Debugger_Help.cpp
Debugger/Debugger_Color.cpp
Debugger/Debugger_Disassembler.cpp
Debugger/Debugger_Symbols.cpp
Debugger/Debugger_DisassemblerData.cpp
Debugger/Debugger_Console.cpp
Debugger/Debugger_Assembler.cpp
Debugger/Debugger_Parser.cpp
Debugger/Debugger_Range.cpp
Debugger/Debugger_Commands.cpp
Debugger/Util_MemoryTextFile.cpp
Uthernet1.cpp
Uthernet2.cpp
StrFormat.cpp
6522.cpp
VidHD.cpp
SSI263.cpp
Speaker.cpp
SoundCore.cpp
AY8910.cpp
Mockingboard.cpp
Pravets.cpp
YamlHelper.cpp
Log.cpp
Disk.cpp
DiskFormatTrack.cpp
DiskImage.cpp
DiskImageHelper.cpp
Harddisk.cpp
Memory.cpp
CPU.cpp
6821.cpp
NoSlotClock.cpp
SAM.cpp
z80emu.cpp
ParallelPrinter.cpp
MouseInterface.cpp
LanguageCard.cpp
RGBMonitor.cpp
NTSC.cpp
NTSC_CharSet.cpp
Card.cpp
CardManager.cpp
Disk2CardManager.cpp
Riff.cpp
SaveState.cpp
SynchronousEventManager.cpp
Video.cpp
Core.cpp
Utilities.cpp
FrameBase.cpp
CmdLine.cpp
Configuration/PropertySheetHelper.cpp
linux/resources.cpp
linux/benchmark.cpp
linux/paddle.cpp
linux/version.cpp
linux/registry.cpp
linux/keyboard.cpp
linux/linuxframe.cpp
linux/context.cpp
linux/tape.cpp
linux/network/slirp2.cpp
linux/duplicates/Debugger_Display.cpp
linux/duplicates/Debugger_Win32.cpp
linux/duplicates/Joystick.cpp
linux/duplicates/SerialComms.cpp
linux/duplicates/PropertySheet.cpp
linux/duplicates/Registry.cpp
linux/duplicates/FourPlay.cpp
linux/duplicates/SNESMAX.cpp
linux/duplicates/Keyboard.cpp
Z80VICE/z80.cpp
Z80VICE/z80mem.cpp
Z80VICE/daa.cpp
)
set(HEADER_FILES
Tfe/tfearch.h
Tfe/tfesupp.h
Tfe/NetworkBackend.h
Tfe/PCapBackend.h
Tfe/IPRaw.h
Uthernet1.h
Uthernet2.h
W5100.h
6522.h
VidHD.h
SSI263.h
SSI263Phonemes.h
Speaker.h
SoundCore.h
AY8910.h
Mockingboard.h
Pravets.h
Tape.h
YamlHelper.h
Log.h
Disk.h
DiskFormatTrack.h
DiskImage.h
DiskImageHelper.h
Harddisk.h
Memory.h
CPU.h
6821.h
NoSlotClock.h
SAM.h
z80emu.h
ParallelPrinter.h
MouseInterface.h
LanguageCard.h
RGBMonitor.h
NTSC.h
NTSC_CharSet.h
Card.h
CardManager.h
Disk2CardManager.h
Riff.h
SaveState.h
SynchronousEventManager.h
Video.h
Core.h
Utilities.h
FrameBase.h
FourPlay.h
SNESMAX.h
Common.h
DiskDefs.h
DiskLog.h
Interface.h
SaveState_Structs_common.h
SaveState_Structs_v1.h
Debugger/Debug.h
Debugger/DebugDefs.h
Debugger/Debugger_Color.h
Debugger/Debugger_Console.h
Debugger/Debugger_Disassembler.h
Debugger/Debugger_DisassemblerData.h
Debugger/Debugger_Display.h
Debugger/Debugger_Help.h
Debugger/Debugger_Parser.h
Debugger/Debugger_Range.h
Debugger/Debugger_Symbols.h
Debugger/Debugger_Types.h
Debugger/Debugger_Win32.h
Debugger/Util_MemoryTextFile.h
Debugger/Util_Text.h
Configuration/PropertySheetHelper.h
linux/resources.h
linux/linuxinterface.h
linux/benchmark.h
linux/paddle.h
linux/version.h
linux/registry.h
linux/keyboard.h
linux/linuxframe.h
linux/tape.h
linux/network/slirp2.h
Z80VICE/z80.h
Z80VICE/z80mem.h
Z80VICE/z80regs.h
Z80VICE/daa.h
)
# we used to generate a shared object, but it turns out there are more cons than pros
add_library(appleii STATIC
${SOURCE_FILES}
${HEADER_FILES}
)
target_include_directories(appleii PRIVATE
${CMAKE_CURRENT_BINARY_DIR} # for config.h
${YAML_INCLUDE_DIRS}
${PCAP_INCLUDE_DIRS}
${Boost_INCLUDE_DIRS}
${SLIRP_INCLUDE_DIRS}
Debugger
)
# this one appears in header files
target_include_directories(appleii PUBLIC
${MINIZIP_INCLUDE_DIRS}
)
target_link_libraries(appleii PRIVATE
${YAML_LIBRARIES}
${MINIZIP_LIBRARIES}
${PCAP_LIBRARIES}
${SLIRP_LIBRARIES}
ZLIB::ZLIB
)
target_link_libraries(appleii PUBLIC
windows
)
target_link_directories(appleii PRIVATE
${YAML_LIBRARY_DIRS}
${MINIZIP_LIBRARY_DIRS}
${PCAP_LIBRARY_DIRS}
${SLIRP_LIBRARY_DIRS}
)
target_compile_options(appleii PUBLIC
-Wno-multichar
)
add_custom_command(
TARGET appleii POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/bin/*.SYM ${CMAKE_BINARY_DIR}
)
configure_file(linux/config.h.in linux/config.h)

View file

@ -3798,16 +3798,16 @@ Update_t CmdConfigSetDebugDir (int nArgs)
if ((nSubDirLen == 3) && (sSubDir == UP_DIR)) // Up directory "..\" in the subpath?
{
size_t nCurrentLen = g_sCurrentDir.size();
size_t nLastSeperator = g_sCurrentDir.rfind( '\\', nCurrentLen - 2 );
size_t nLastSeparator = g_sCurrentDir.rfind( '\\', nCurrentLen - 2 );
if (nLastSeperator != std::string::npos)
if (nLastSeparator != std::string::npos)
{
#if _DEBUG
LogOutput( "Last: %" SIZE_T_FMT "\n", nLastSeperator );
LogOutput( "Last: %" SIZE_T_FMT "\n", nLastSeparator );
LogOutput( "%s\n", g_sCurrentDir.c_str() );
LogOutput( "%*s%s\n", int(nLastSeperator), "", "^" );
LogOutput( "%*s%s\n", int(nLastSeparator), "", "^" );
#endif
std::string sCurrentDir = g_sCurrentDir.substr( 0, nLastSeperator + 1 ); // Path always has trailing slash so include it
std::string sCurrentDir = g_sCurrentDir.substr( 0, nLastSeparator + 1 ); // Path always has trailing slash so include it
g_sCurrentDir = sCurrentDir;
}
}
@ -5509,7 +5509,7 @@ Update_t _CmdMemorySearch (int nArgs, bool bTextIsAscii = true )
// if (eRange == RANGE_MISSING_ARG_2)
if (! Range_CalcEndLen( eRange, nAddressStart, nAddress2, nAddressEnd, nAddressLen))
return ConsoleDisplayError( "Error: Missing address seperator (comma or colon)" );
return ConsoleDisplayError( "Error: Missing address separator (comma or colon)" );
int iArgFirstByte = 4;
int iArg;
@ -7812,7 +7812,7 @@ int ParseInput ( LPTSTR pConsoleInput, bool bCook )
{
int nArg = 0;
// TODO: need to check for non-quoted command seperator ';', and buffer input
// TODO: need to check for non-quoted command separator ';', and buffer input
RemoveWhiteSpaceReverse( pConsoleInput );
ArgsClear();
@ -7871,24 +7871,24 @@ void ProfileLineReset()
//===========================================================================
void ProfileFormat( bool bExport, ProfileFormat_e eFormatMode )
{
char sSeperator7[ 32 ] = "\t";
char sSeperator2[ 32 ] = "\t";
char sSeperator1[ 32 ] = "\t";
char sSeparator7[ 32 ] = "\t";
char sSeparator2[ 32 ] = "\t";
char sSeparator1[ 32 ] = "\t";
char sOpcode [ 8 ]; // 2 chars for opcode in hex, plus quotes on either side
char sAddress[MAX_OPMODE_NAME];
if (eFormatMode == PROFILE_FORMAT_COMMA)
{
sSeperator7[0] = ',';
sSeperator2[0] = ',';
sSeperator1[0] = ',';
sSeparator7[0] = ',';
sSeparator2[0] = ',';
sSeparator1[0] = ',';
}
else
if (eFormatMode == PROFILE_FORMAT_SPACE)
{
sprintf( sSeperator7, " " ); // 7
sprintf( sSeperator2, " " ); // 2
sprintf( sSeperator1, " " ); // 1
sprintf( sSeparator7, " " ); // 7
sprintf( sSeparator2, " " ); // 2
sprintf( sSeparator1, " " ); // 1
}
ProfileLineReset();
@ -7946,11 +7946,11 @@ void ProfileFormat( bool bExport, ProfileFormat_e eFormatMode )
if (bExport) // Export = SeperateColumns
sprintf( pText
, "\"Percent\"" DELIM "\"Count\"" DELIM "\"Opcode\"" DELIM "\"Mnemonic\"" DELIM "\"Addressing Mode\"\n"
, sSeperator7, sSeperator2, sSeperator1, sSeperator1 );
, sSeparator7, sSeparator2, sSeparator1, sSeparator1 );
else
sprintf( pText
, "Percent" DELIM "Count" DELIM "Mnemonic" DELIM "Addressing Mode\n"
, sSeperator7, sSeperator2, sSeperator1 );
, sSeparator7, sSeparator2, sSeparator1 );
pText = ProfileLinePush();
@ -7998,13 +7998,13 @@ void ProfileFormat( bool bExport, ProfileFormat_e eFormatMode )
, pColorNumber
, nPercent
, pColorOperator
, sSeperator2
, sSeparator2
, pColorNumber
, static_cast<unsigned int>(nCount), sSeperator2
, static_cast<unsigned int>(nCount), sSeparator2
, pColorOpcode
, sOpcode, sSeperator2
, sOpcode, sSeparator2
, pColorMnemonic
, g_aOpcodes[ nOpcode ].sMnemonic, sSeperator2
, g_aOpcodes[ nOpcode ].sMnemonic, sSeparator2
, pColorOpmode
, sAddress
);
@ -8016,7 +8016,7 @@ void ProfileFormat( bool bExport, ProfileFormat_e eFormatMode )
sprintf( pText
, "Total: " DELIM "%s%9u\n"
, sSeperator2
, sSeparator2
, pColorTotal
, static_cast<unsigned int>(nOpcodeTotal) );
pText = ProfileLinePush();
@ -8030,12 +8030,12 @@ void ProfileFormat( bool bExport, ProfileFormat_e eFormatMode )
// Note: 2 extra dummy columns are inserted to keep Addressing Mode in same column
sprintf( pText
, "\"Percent\"" DELIM "\"Count\"" DELIM DELIM DELIM "\"Addressing Mode\"\n"
, sSeperator7, sSeperator2, sSeperator2, sSeperator2 );
, sSeparator7, sSeparator2, sSeparator2, sSeparator2 );
else
{
sprintf( pText
, "Percent" DELIM "Count" DELIM "Addressing Mode\n"
, sSeperator7, sSeperator2 );
, sSeparator7, sSeparator2 );
}
pText = ProfileLinePush();
@ -8060,7 +8060,7 @@ void ProfileFormat( bool bExport, ProfileFormat_e eFormatMode )
if (bExport)
{
// Note: 2 extra dummy columns are inserted to keep Addressing Mode in same column
sprintf( sAddress, "%s%s\"%s\"", sSeperator1, sSeperator1, g_aOpmodes[ nOpmode ].m_sName );
sprintf( sAddress, "%s%s\"%s\"", sSeparator1, sSeparator1, g_aOpmodes[ nOpmode ].m_sName );
}
else // not qouted if dumping to console
{
@ -8073,9 +8073,9 @@ void ProfileFormat( bool bExport, ProfileFormat_e eFormatMode )
, pColorNumber
, nPercent
, pColorOperator
, sSeperator2
, sSeparator2
, pColorNumber
, static_cast<unsigned int>(nCount), sSeperator2
, static_cast<unsigned int>(nCount), sSeparator2
, pColorOpmode
, sAddress
);
@ -8087,7 +8087,7 @@ void ProfileFormat( bool bExport, ProfileFormat_e eFormatMode )
sprintf( pText
, "Total: " DELIM "%s%9u\n"
, sSeperator2
, sSeparator2
, pColorTotal
, static_cast<unsigned int>(nOpmodeTotal) );
pText = ProfileLinePush();
@ -8098,7 +8098,7 @@ void ProfileFormat( bool bExport, ProfileFormat_e eFormatMode )
unsigned int cycles = static_cast<unsigned int>(g_nCumulativeCycles - g_nProfileBeginCycles);
sprintf( pText
, "Cycles: " DELIM "%s%9u\n"
, sSeperator2
, sSeparator2
, pColorNumber
, cycles );
pText = ProfileLinePush();

View file

@ -617,7 +617,7 @@ void FormatNopcodeBytes(WORD nBaseAddress, DisasmLine_t& line_)
//===========================================================================
void FormatDisassemblyLine(const DisasmLine_t& line, char* sDisassembly, const int nBufferSize)
{
//> Address Seperator Opcodes Label Mnemonic Target [Immediate] [Branch]
//> Address Separator Opcodes Label Mnemonic Target [Immediate] [Branch]
//
// Data Disassembler
// Label Directive [Immediate]

View file

@ -1344,7 +1344,7 @@ WORD DrawDisassemblyLine ( int iLine, const WORD nBaseAddress )
nOpbyte = line.nOpbyte;
// sAddress, sOpcodes, sTarget, sTargetOffset, nTargetOffset, sTargetPointer, sTargetValue, sImmediate, nImmediate, sBranch );
//> Address Seperator Opcodes Label Mnemonic Target [Immediate] [Branch]
//> Address Separator Opcodes Label Mnemonic Target [Immediate] [Branch]
//
//> xxxx: xx xx xx LABEL MNEMONIC 'E' =
//> ^ ^ ^ ^ ^
@ -1515,7 +1515,7 @@ WORD DrawDisassemblyLine ( int iLine, const WORD nBaseAddress )
}
// Address Seperator
// Address Separator
if (! bCursorLine)
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_OPERATOR ) );

View file

@ -249,8 +249,8 @@ void Help_Operators()
ConsolePrintFormat( " %s#%s Designate number in hex" , CHC_USAGE, CHC_DEFAULT );
// ConsoleBufferPush( " Operators: (Range)" );
ConsolePrintFormat( " Operators: (%sRange%s)" , CHC_USAGE, CHC_DEFAULT );
ConsolePrintFormat( " %s,%s range seperator (2nd address is relative)", CHC_USAGE, CHC_DEFAULT );
ConsolePrintFormat( " %s:%s range seperator (2nd address is absolute)", CHC_USAGE, CHC_DEFAULT );
ConsolePrintFormat( " %s,%s range separator (2nd address is relative)", CHC_USAGE, CHC_DEFAULT );
ConsolePrintFormat( " %s:%s range separator (2nd address is absolute)", CHC_USAGE, CHC_DEFAULT );
// ConsolePrintFormat( " Operators: (Misc)" );
ConsolePrintFormat( " Operators: (%sMisc%s)" , CHC_USAGE, CHC_DEFAULT );
ConsolePrintFormat( " %s//%s comment until end of line" , CHC_USAGE, CHC_DEFAULT );

View file

@ -286,7 +286,7 @@ int ArgsGet ( TCHAR * pInput )
if (iTokenSrc == TOKEN_SEMI)
{
// TODO - command seperator, must handle non-quoted though!
// TODO - command separator, must handle non-quoted though!
}
if (iTokenSrc == TOKEN_QUOTE_DOUBLE)

View file

@ -1271,7 +1271,7 @@ const DisasmData_t* pDisasmData; // If != NULL then bytes are marked up as data
, TOKEN_PLUS // + Delta Argument1 += Argument2
, TOKEN_QUOTE_SINGLE // '
, TOKEN_QUOTE_DOUBLE // "
, TOKEN_SEMI // ; Command Seperator
, TOKEN_SEMI // ; Command Separator
, TOKEN_SPACE // Token Delimiter
, TOKEN_STAR // *
// , TOKEN_TAB // '\t'

View file

@ -443,7 +443,7 @@ bool Saturn128K::LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT version)
}
// "Memory Bankxx"
std::string memName = GetSnapshotMemStructName() + StrFormat("%02X", uBank);
std::string memName = GetSnapshotMemStructName() + ByteToHexStr(uBank);
if (!yamlLoadHelper.GetSubMap(memName))
throw std::runtime_error("Memory: Missing map name: " + memName);

View file

@ -2443,7 +2443,7 @@ static void MemLoadSnapshotAuxCommon(YamlLoadHelper& yamlLoadHelper, const std::
}
// "Auxiliary Memory Bankxx"
std::string auxMemName = MemGetSnapshotAuxMemStructName() + StrFormat("%02X", uBank-1);
std::string auxMemName = MemGetSnapshotAuxMemStructName() + ByteToHexStr(uBank-1);
if (!yamlLoadHelper.GetSubMap(auxMemName))
throw std::runtime_error("Memory: Missing map name: " + auxMemName);

View file

@ -86,7 +86,7 @@ void SSI_Output(void)
LogOutput("SSI: ");
for (int i = 0; i <= 4; i++)
{
std::string r = (ssiRegs[i] >= 0) ? StrFormat("%02X", ssiRegs[i]) : "--";
std::string r = (ssiRegs[i] >= 0) ? ByteToHexStr(ssiRegs[i]) : "--";
LogOutput("%s ", r.c_str());
ssiRegs[i] = -1;
}

View file

@ -71,6 +71,7 @@ typedef UINT64 uint64_t;
#include <algorithm>
#include <string>
#include <vector>
#include <cassert>
#include "windows.h"

View file

@ -6,6 +6,7 @@
#if defined(_MSC_VER) && _MSC_VER < 1600
#include <basetsd.h>
typedef UINT8 uint8_t;
typedef UINT16 uint16_t;
#else
#include <cstdint>
#endif
@ -19,10 +20,59 @@ typedef UINT8 uint8_t;
std::string StrFormat(const char* format, ...) ATTRIBUTE_FORMAT_PRINTF(1, 2);
std::string StrFormatV(const char* format, va_list va);
namespace {
const char g_aHexDigits[16] = {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
};
// No buffer overflow check or null termination. Use with caution.
inline char* StrBufferAppendByteAsHex(char* cp, uint8_t n)
{
*cp++ = g_aHexDigits[(n >> 4) & 0x0f];
*cp++ = g_aHexDigits[(n >> 0) & 0x0f];
return cp;
}
// No buffer overflow check or null termination. Use with caution.
inline char* StrBufferAppendWordAsHex(char* cp, uint16_t n)
{
*cp++ = g_aHexDigits[(n >> 12) & 0x0f];
*cp++ = g_aHexDigits[(n >> 8) & 0x0f];
*cp++ = g_aHexDigits[(n >> 4) & 0x0f];
*cp++ = g_aHexDigits[(n >> 0) & 0x0f];
return cp;
}
inline std::string& StrAppendByteAsHex(std::string& s, uint8_t n)
{
const char szHex[] = "0123456789ABCDEF";
s += szHex[(n >> 4) & 0x0f];
s += szHex[n & 0x0f];
const char hex[2] = { g_aHexDigits[(n >> 4) & 0x0f],
g_aHexDigits[(n >> 0) & 0x0f] };
return s.append(hex, 2);
}
inline std::string& StrAppendWordAsHex(std::string& s, uint16_t n)
{
const char hex[4] = { g_aHexDigits[(n >> 12) & 0x0f],
g_aHexDigits[(n >> 8) & 0x0f],
g_aHexDigits[(n >> 4) & 0x0f],
g_aHexDigits[(n >> 0) & 0x0f] };
return s.append(hex, 4);
}
inline std::string ByteToHexStr(uint8_t n)
{
std::string s;
StrAppendByteAsHex(s, n);
return s;
}
inline std::string WordToHexStr(uint16_t n)
{
std::string s;
StrAppendWordAsHex(s, n);
return s;
}
} // namespace

162
source/Tfe/IPRaw.cpp Normal file
View file

@ -0,0 +1,162 @@
/*
AppleWin : An Apple //e emulator for Windows
Copyright (C) 2022, Andrea Odetti
AppleWin is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
AppleWin is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with AppleWin; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "StdAfx.h"
#include "IPRaw.h"
#ifndef _MSC_VER
#include <arpa/inet.h>
#endif
#define IPV4 0x04
namespace
{
#pragma pack(push)
#pragma pack(1) // Ensure struct is packed
struct IP4Header
{
uint8_t ihl : 4;
uint8_t version : 4;
uint8_t tos;
uint16_t len;
uint16_t id;
uint16_t flags : 3;
uint16_t fragmentOffset : 13;
uint8_t ttl;
uint8_t proto;
uint16_t checksum;
uint32_t sourceAddress;
uint32_t destinationAddress;
};
struct ETH2Frame
{
uint8_t destinationMac[6];
uint8_t sourceMac[6];
uint16_t type;
};
#pragma pack(pop)
uint32_t sum_every_16bits(const void *addr, int count)
{
uint32_t sum = 0;
const uint16_t *ptr = reinterpret_cast<const uint16_t *>(addr);
while (count > 1)
{
/* This is the inner loop */
sum += *ptr++;
count -= 2;
}
/* Add left-over byte, if any */
if (count > 0)
sum += *reinterpret_cast<const uint8_t *>(ptr);
return sum;
}
uint16_t checksum(const void *addr, int count)
{
/* Compute Internet Checksum for "count" bytes
* beginning at location "addr".
* Taken from https://tools.ietf.org/html/rfc1071
*/
uint32_t sum = sum_every_16bits(addr, count);
/* Fold 32-bit sum to 16 bits */
while (sum >> 16)
sum = (sum & 0xffff) + (sum >> 16);
return ~sum;
}
// get the minimum size of a ETH Frame that contains a IP payload
// 34 = 14 bytes for ETH2 + 20 bytes IPv4 (minimum)
int getIPMinimumSize()
{
const int minimumSize = sizeof(ETH2Frame) + sizeof(IP4Header) + 0; // 0 len
return minimumSize;
}
}
std::vector<uint8_t> createETH2Frame(const std::vector<uint8_t> &data,
const MACAddress *sourceMac, const MACAddress *destinationMac,
const uint8_t ttl, const uint8_t tos, const uint8_t protocol,
const uint32_t sourceAddress, const uint32_t destinationAddress)
{
const size_t total = sizeof(ETH2Frame) + sizeof(IP4Header) + data.size();
std::vector<uint8_t> frame(total);
ETH2Frame *eth2frame = reinterpret_cast<ETH2Frame *>(frame.data() + 0);
memcpy(eth2frame->destinationMac, destinationMac, sizeof(eth2frame->destinationMac));
memcpy(eth2frame->sourceMac, sourceMac, sizeof(eth2frame->destinationMac));
eth2frame->type = htons(0x0800);
IP4Header *ip4header = reinterpret_cast<IP4Header *>(frame.data() + sizeof(ETH2Frame));
ip4header->version = IPV4;
ip4header->ihl = 0x05; // minimum size = 20 bytes, without any extra option
ip4header->tos = tos;
ip4header->len = htons(static_cast<uint16_t>(sizeof(IP4Header) + data.size()));
ip4header->id = 0;
ip4header->fragmentOffset = 0;
ip4header->ttl = ttl;
ip4header->proto = protocol;
ip4header->sourceAddress = sourceAddress;
ip4header->destinationAddress = destinationAddress;
ip4header->checksum = checksum(ip4header, sizeof(IP4Header));
memcpy(frame.data() + sizeof(ETH2Frame) + sizeof(IP4Header), data.data(), data.size());
return frame;
}
void getIPPayload(const int lengthOfFrame, const uint8_t *frame,
size_t &lengthOfPayload, const uint8_t *&payload, uint32_t &destination, uint8_t &protocol)
{
const int minimumSize = getIPMinimumSize();
if (lengthOfFrame > minimumSize)
{
const ETH2Frame *eth2Frame = reinterpret_cast<const ETH2Frame *>(frame);
const IP4Header *ip4header = reinterpret_cast<const IP4Header *>(frame + sizeof(ETH2Frame));
if (eth2Frame->type == htons(0x0800) && ip4header->version == IPV4)
{
const uint16_t ipv4HeaderSize = ip4header->ihl * 4;
const uint16_t ipPacketSize = ntohs(ip4header->len);
const int expectedSize = sizeof(ETH2Frame) + ipPacketSize;
if (ipPacketSize > ipv4HeaderSize && lengthOfFrame >= expectedSize)
{
protocol = ip4header->proto;
payload = frame + sizeof(ETH2Frame) + ipv4HeaderSize;
lengthOfPayload = ipPacketSize - ipv4HeaderSize;
destination = ip4header->destinationAddress;
return;
}
}
}
// not a good packet
protocol = 0xFF; // reserved protocol
payload = nullptr;
lengthOfPayload = 0;
destination = 0;
}

11
source/Tfe/IPRaw.h Normal file
View file

@ -0,0 +1,11 @@
#pragma once
struct MACAddress;
std::vector<uint8_t> createETH2Frame(const std::vector<uint8_t> &data,
const MACAddress *sourceMac, const MACAddress *destinationMac,
const uint8_t ttl, const uint8_t tos, const uint8_t protocol,
const uint32_t sourceAddress, const uint32_t destinationAddress);
void getIPPayload(const int lengthOfFrame, const uint8_t *frame,
size_t &lengthOfPayload, const uint8_t *&payload, uint32_t &destination, uint8_t &protocol);

View file

@ -6,6 +6,14 @@
#define MAX_RXLENGTH 1518
#define MIN_RXLENGTH 64
#pragma pack(push)
#pragma pack(1) // Ensure struct is packed
struct MACAddress
{
uint8_t address[6];
};
#pragma pack(pop)
class NetworkBackend
{
public:
@ -26,6 +34,9 @@ public:
// process pending packets
virtual void update(const ULONG nExecutedCycles) = 0;
// get MAC for IPRAW (it is only supposed to handle addresses on the local network)
virtual void getMACAddress(const uint32_t address, MACAddress & mac) = 0;
// if the backend is usable
virtual bool isValid() = 0;
};

View file

@ -25,6 +25,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "../Common.h"
#include "../Registry.h"
#ifdef _MSC_VER
#include <iphlpapi.h>
#endif
std::string PCapBackend::tfe_interface;
PCapBackend::PCapBackend(const std::string & pcapInterface)
@ -71,6 +75,16 @@ void PCapBackend::update(const ULONG /* nExecutedCycles */)
// nothing to do
}
void PCapBackend::getMACAddress(const uint32_t address, MACAddress & mac)
{
// this is only expected to be called for IP addresses on the same network
#ifdef _MSC_VER
const DWORD dwSourceAddress = INADDR_ANY;
ULONG len = sizeof(MACAddress::address);
SendARP(address, dwSourceAddress, mac.address, &len);
#endif
}
int PCapBackend::tfe_enumadapter_open(void)
{
return tfe_arch_enumadapter_open();

View file

@ -29,6 +29,9 @@ public:
// process pending packets
virtual bool isValid();
// get MAC for IPRAW (it is only supposed to handle addresses on the local network)
virtual void getMACAddress(const uint32_t address, MACAddress & mac);
static void tfe_SetRegistryInterface(UINT slot, const std::string& name);
static void get_disabled_state(int * param);

View file

@ -433,7 +433,7 @@ void TfePcapPacketHandler(u_char *param, const struct pcap_pkthdr *header, const
/* determine the count of bytes which has been returned,
* but make sure not to overrun the buffer
*/
pinternal->rxlength = min(pinternal->size, header->caplen);
pinternal->rxlength = std::min(pinternal->size, header->caplen);
memcpy(pinternal->buffer, pkt_data, pinternal->rxlength);
}

View file

@ -24,6 +24,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "Interface.h"
#include "Tfe/NetworkBackend.h"
#include "Tfe/PCapBackend.h"
#include "Tfe/IPRaw.h"
#include "W5100.h"
// Linux uses EINPROGRESS while Windows returns WSAEWOULDBLOCK
@ -73,6 +74,9 @@ typedef int socklen_t;
#define SOCK_NONBLOCK O_NONBLOCK
#endif
// Dest MAC + Source MAC + Ether Type
#define ETH_MINIMUM_SIZE (6 + 6 + 2)
// #define U2_LOG_VERBOSE
// #define U2_LOG_TRAFFIC
// #define U2_LOG_STATE
@ -95,6 +99,12 @@ namespace
return host;
}
uint32_t readAddress(const uint8_t *ptr)
{
const uint32_t address = *reinterpret_cast<const uint32_t *>(ptr);
return address;
}
uint8_t getIByte(const uint16_t value, const size_t shift)
{
return (value >> shift) & 0xFF;
@ -141,6 +151,13 @@ namespace
writeData(socket, memory, data, len);
}
void writeDataIPRaw(Socket &socket, std::vector<uint8_t> &memory, const uint8_t *data, const size_t len, const uint32_t destination)
{
writeAny(socket, memory, destination);
write16(socket, memory, static_cast<uint16_t>(len));
writeData(socket, memory, data, len);
}
void writeDataForProtocol(Socket &socket, std::vector<uint8_t> &memory, const uint8_t *data, const size_t len, const sockaddr_in &source)
{
if (socket.sn_sr == W5100_SN_SR_SOCK_UDP)
@ -199,31 +216,46 @@ Socket::~Socket()
clearFD();
}
bool Socket::isOpen() const
{
return (myFD != INVALID_SOCKET) &&
((sn_sr == W5100_SN_SR_ESTABLISHED) || (sn_sr == W5100_SN_SR_SOCK_UDP));
}
void Socket::process()
{
if (myFD != INVALID_SOCKET && sn_sr == W5100_SN_SR_SOCK_INIT && (myErrno == SOCK_EINPROGRESS || myErrno == SOCK_EWOULDBLOCK))
{
#ifdef _MSC_VER
FD_SET writefds;
FD_SET writefds, exceptfds;
FD_ZERO(&writefds);
FD_ZERO(&exceptfds);
FD_SET(myFD, &writefds);
FD_SET(myFD, &exceptfds);
const timeval timeout = {0, 0};
if (select(0, NULL, &writefds, NULL, &timeout) > 0)
if (select(0, NULL, &writefds, &exceptfds, &timeout) > 0)
#else
pollfd pfd = {.fd = myFD, .events = POLLOUT};
if (poll(&pfd, 1, 0) > 0)
#endif
{
int err = 0;
socklen_t elen = sizeof err;
getsockopt(myFD, SOL_SOCKET, SO_ERROR, reinterpret_cast<char *>(&err), &elen);
socklen_t elen = sizeof(err);
const int res = getsockopt(myFD, SOL_SOCKET, SO_ERROR, reinterpret_cast<char *>(&err), &elen);
if (err == 0)
if (res == 0 && err == 0)
{
myErrno = 0;
sn_sr = W5100_SN_SR_ESTABLISHED;
#ifdef U2_LOG_STATE
LogFileOutput("U2: TCP[]: Connected\n");
#endif
}
else
{
clearFD();
#ifdef U2_LOG_STATE
LogFileOutput("U2: TCP[]: Connection error: %d - %" ERROR_FMT "\n", res, STRERROR(err));
#endif
}
}
@ -266,12 +298,18 @@ bool Socket::LoadSnapshot(YamlLoadHelper &yamlLoadHelper)
// transmit and receive sizes are restored from the card common registers
if (sn_sr != W5100_SN_SR_SOCK_MACRAW)
switch (sn_sr)
{
case W5100_SN_SR_SOCK_MACRAW:
case W5100_SN_SR_SOCK_IPRAW:
// we can restore RAW sockets
break;
default:
// no point in restoring a broken UDP or TCP connection
// just reset the socket
sn_sr = W5100_SN_SR_CLOSED;
// for the same reason there is no point in saving myFD and myErrno
break;
}
return true;
@ -434,7 +472,7 @@ void Uthernet2::updateRSR(const size_t i)
socket.sn_rx_rsr = dataPresent;
}
int Uthernet2::receiveForMacAddress(const bool acceptAll, const int size, uint8_t * data)
int Uthernet2::receiveForMacAddress(const bool acceptAll, const int size, uint8_t * data, PacketDestination & packetDestination)
{
const uint8_t * mac = myMemory.data() + W5100_SHAR0;
@ -442,15 +480,9 @@ int Uthernet2::receiveForMacAddress(const bool acceptAll, const int size, uint8_
int len;
while ((len = myNetworkBackend->receive(size, data)) > 0)
{
// minimum valid Ethernet frame is actually 64 bytes
// 12 is the minimum to ensure valid MAC Address logging later
if (len >= 12)
// smaller frames are not good anyway
if (len >= ETH_MINIMUM_SIZE)
{
if (acceptAll)
{
return len;
}
if (data[0] == mac[0] &&
data[1] == mac[1] &&
data[2] == mac[2] &&
@ -458,6 +490,7 @@ int Uthernet2::receiveForMacAddress(const bool acceptAll, const int size, uint8_
data[4] == mac[4] &&
data[5] == mac[5])
{
packetDestination = HOST;
return len;
}
@ -468,8 +501,16 @@ int Uthernet2::receiveForMacAddress(const bool acceptAll, const int size, uint8_
data[4] == 0xFF &&
data[5] == 0xFF)
{
packetDestination = BROADCAST;
return len;
}
if (acceptAll)
{
packetDestination = OTHER;
return len;
}
}
// skip this frame and try with another one
}
@ -477,34 +518,110 @@ int Uthernet2::receiveForMacAddress(const bool acceptAll, const int size, uint8_
return len;
}
void Uthernet2::receiveOnePacketMacRaw(const size_t i)
void Uthernet2::receiveOnePacketRaw()
{
bool acceptAll = false;
int macRawSocket = -1; // to which IPRaw soccket to send to (can only be 0)
Socket & socket0 = mySockets[0];
if (socket0.sn_sr == W5100_SN_SR_SOCK_MACRAW)
{
macRawSocket = 0; // the only MAC Raw socket is open, packet will go there as a fallback
const uint8_t mr = myMemory[socket0.registerAddress + W5100_SN_MR];
// see if MAC RAW filters or not
const bool filterMAC = mr & W5100_SN_MR_MF;
if (!filterMAC)
{
acceptAll = true;
}
}
uint8_t buffer[MAX_RXLENGTH];
PacketDestination packetDestination;
const int len = receiveForMacAddress(acceptAll, sizeof(buffer), buffer, packetDestination);
if (len > 0)
{
const uint8_t * payload;
size_t lengthOfPayload;
uint32_t destination;
uint8_t packetProtocol;
getIPPayload(len, buffer, lengthOfPayload, payload, destination, packetProtocol);
// see if there is a IPRAW socket that should accept thi spacket
int ipRawSocket = -1;
if (packetDestination != OTHER) // IPRaw always filters (HOST or BROADCAST, never OTHER)
{
for (size_t i = 0; i < mySockets.size(); ++i)
{
Socket & socket = mySockets[i];
if (socket.sn_sr == W5100_SN_SR_SOCK_IPRAW)
{
// IP only accepts by protocol & always filters MAC
const uint8_t socketProtocol = myMemory[socket.registerAddress + W5100_SN_PROTO];
if (payload && packetProtocol == socketProtocol)
{
ipRawSocket = i;
break; // a valid IPRAW socket has been found
}
}
// we should probably check for UDP & TCP sockets and filter these packets too
}
}
// priority to IPRAW
if (ipRawSocket >= 0)
{
receiveOnePacketIPRaw(ipRawSocket, lengthOfPayload, payload, destination, packetProtocol, len);
}
// fallback to MACRAW (if open)
else if (macRawSocket >= 0)
{
receiveOnePacketMacRaw(macRawSocket, len, buffer);
}
// else packet is dropped
}
}
void Uthernet2::receiveOnePacketMacRaw(const size_t i, const int size, uint8_t * data)
{
Socket &socket = mySockets[i];
uint8_t buffer[MAX_RXLENGTH];
const uint8_t mr = myMemory[socket.registerAddress + W5100_SN_MR];
const bool filterMAC = mr & W5100_SN_MR_MF;
const int len = receiveForMacAddress(!filterMAC, sizeof(buffer), buffer);
if (len > 0)
if (socket.isThereRoomFor(size, sizeof(uint16_t)))
{
// we know the packet is at least 12 bytes, and logging is ok
if (socket.isThereRoomFor(len, sizeof(uint16_t)))
{
writeDataMacRaw(socket, myMemory, buffer, len);
writeDataMacRaw(socket, myMemory, data, size);
#ifdef U2_LOG_TRAFFIC
LogFileOutput("U2: Read MACRAW[%" SIZE_T_FMT "]: " MAC_FMT " -> " MAC_FMT ": +%d -> %d bytes\n", i, MAC_SOURCE(buffer), MAC_DEST(buffer),
len, socket.sn_rx_rsr);
LogFileOutput("U2: Read MACRAW[%" SIZE_T_FMT "]: " MAC_FMT " -> " MAC_FMT ": +%d -> %d bytes\n", i, MAC_SOURCE(data), MAC_DEST(data),
size, socket.sn_rx_rsr);
#endif
}
else
{
// drop it
}
else
{
// drop it
#ifdef U2_LOG_TRAFFIC
LogFileOutput("U2: Skip MACRAW[%" SIZE_T_FMT "]: %d bytes\n", i, len);
LogFileOutput("U2: Skip MACRAW[%" SIZE_T_FMT "]: %d bytes\n", i, size);
#endif
}
}
void Uthernet2::receiveOnePacketIPRaw(const size_t i, const size_t lengthOfPayload, const uint8_t * payload, const uint32_t destination, const uint8_t protocol, const int len)
{
Socket &socket = mySockets[i];
if (socket.isThereRoomFor(lengthOfPayload, 4 + sizeof(uint16_t)))
{
writeDataIPRaw(socket, myMemory, payload, lengthOfPayload, destination);
#ifdef U2_LOG_TRAFFIC
LogFileOutput("U2: Read IPRAW[%" SIZE_T_FMT "]: +%" SIZE_T_FMT " (%d) -> %d bytes\n", i, lengthOfPayload, len, socket.sn_rx_rsr);
#endif
}
else
{
// drop it
#ifdef U2_LOG_TRAFFIC
LogFileOutput("U2: Skip IPRAW[%" SIZE_T_FMT "]: %" SIZE_T_FMT " (%d) bytes \n", i, lengthOfPayload, len);
#endif
}
}
}
@ -512,7 +629,7 @@ void Uthernet2::receiveOnePacketMacRaw(const size_t i)
void Uthernet2::receiveOnePacketFromSocket(const size_t i)
{
Socket &socket = mySockets[i];
if (socket.myFD != INVALID_SOCKET)
if (socket.isOpen())
{
const uint16_t freeRoom = socket.getFreeRoom();
if (freeRoom > 32) // avoid meaningless reads
@ -557,7 +674,8 @@ void Uthernet2::receiveOnePacket(const size_t i)
switch (socket.sn_sr)
{
case W5100_SN_SR_SOCK_MACRAW:
receiveOnePacketMacRaw(i);
case W5100_SN_SR_SOCK_IPRAW:
receiveOnePacketRaw();
break;
case W5100_SN_SR_ESTABLISHED:
case W5100_SN_SR_SOCK_UDP:
@ -572,6 +690,29 @@ void Uthernet2::receiveOnePacket(const size_t i)
};
}
void Uthernet2::sendDataIPRaw(const size_t i, std::vector<uint8_t> &payload)
{
const Socket &socket = mySockets[i];
const uint8_t ttl = myMemory[socket.registerAddress + W5100_SN_TTL];
const uint8_t tos = myMemory[socket.registerAddress + W5100_SN_TOS];
const uint8_t protocol = myMemory[socket.registerAddress + W5100_SN_PROTO];
const uint32_t source = readAddress(myMemory.data() + W5100_SIPR0);
const uint32_t destination = readAddress(myMemory.data() + socket.registerAddress + W5100_SN_DIPR0);
const MACAddress * sourceMac = reinterpret_cast<const MACAddress *>(myMemory.data() + W5100_SHAR0);
const MACAddress * destinationMac;
getMACAddress(destination, destinationMac);
std::vector<uint8_t> packet = createETH2Frame(payload, sourceMac, destinationMac, ttl, tos, protocol, source, destination);
#ifdef U2_LOG_TRAFFIC
LogFileOutput("U2: Send IPRAW[%" SIZE_T_FMT "]: %" SIZE_T_FMT " (%" SIZE_T_FMT ") bytes\n", i, payload.size(), packet.size());
#endif
myNetworkBackend->transmit(packet.size(), packet.data());
}
void Uthernet2::sendDataMacRaw(const size_t i, std::vector<uint8_t> &packet) const
{
#ifdef U2_LOG_TRAFFIC
@ -592,7 +733,7 @@ void Uthernet2::sendDataMacRaw(const size_t i, std::vector<uint8_t> &packet) con
void Uthernet2::sendDataToSocket(const size_t i, std::vector<uint8_t> &data)
{
Socket &socket = mySockets[i];
if (socket.myFD != INVALID_SOCKET)
if (socket.isOpen())
{
sockaddr_in destination = {};
destination.sin_family = AF_INET;
@ -656,6 +797,9 @@ void Uthernet2::sendData(const size_t i)
case W5100_SN_SR_SOCK_MACRAW:
sendDataMacRaw(i, data);
break;
case W5100_SN_SR_SOCK_IPRAW:
sendDataIPRaw(i, data);
break;
case W5100_SN_SR_ESTABLISHED:
case W5100_SN_SR_SOCK_UDP:
sendDataToSocket(i, data);
@ -680,7 +824,7 @@ void Uthernet2::resetRXTXBuffers(const size_t i)
myMemory[socket.registerAddress + W5100_SN_RX_RD1] = 0x00;
}
void Uthernet2::openSystemSocket(const size_t i, const int type, const int protocol, const int state)
void Uthernet2::openSystemSocket(const size_t i, const int type, const int protocol, const int status)
{
Socket &s = mySockets[i];
#ifdef _MSC_VER
@ -691,7 +835,7 @@ void Uthernet2::openSystemSocket(const size_t i, const int type, const int proto
if (fd == INVALID_SOCKET)
{
#ifdef U2_LOG_STATE
const char *proto = state == W5100_SN_SR_SOCK_UDP ? "UDP" : "TCP";
const char *proto = (status == W5100_SN_SR_SOCK_UDP) ? "UDP" : "TCP";
LogFileOutput("U2: %s[%" SIZE_T_FMT "]: socket error: %" ERROR_FMT "\n", proto, i, STRERROR(sock_error()));
#endif
s.clearFD();
@ -702,7 +846,7 @@ void Uthernet2::openSystemSocket(const size_t i, const int type, const int proto
u_long on = 1;
ioctlsocket(fd, FIONBIO, &on);
#endif
s.setFD(fd, state);
s.setFD(fd, status);
}
}
@ -854,7 +998,7 @@ uint8_t Uthernet2::readSocketRegister(const uint16_t address)
break;
default:
#ifdef U2_LOG_UNKNOWN
LogFileOutput("U2: Get unknown socket register[%" SIZE_T_FMT "]: %04x\n", i, address);
LogFileOutput("U2: Get unknown socket register[%d]: %04x\n", i, address);
#endif
value = myMemory[address];
break;
@ -988,7 +1132,7 @@ void Uthernet2::writeSocketRegister(const uint16_t address, const uint8_t value)
break;
#ifdef U2_LOG_UNKNOWN
default:
LogFileOutput("U2: Set unknown socket register[%" SIZE_T_FMT "]: %04x\n", i, address);
LogFileOutput("U2: Set unknown socket register[%d]: %04x\n", i, address);
break;
#endif
};
@ -1073,6 +1217,7 @@ void Uthernet2::Reset(const bool powerCycle)
// dataAddress is NOT reset, see page 10 of Uthernet II
myDataAddress = 0;
myNetworkBackend = GetFrame().CreateNetworkBackend();
myARPCache.clear();
}
mySockets.clear();
@ -1084,14 +1229,25 @@ void Uthernet2::Reset(const bool powerCycle)
{
resetRXTXBuffers(i);
mySockets[i].clearFD();
mySockets[i].registerAddress = static_cast<uint16_t>(W5100_S0_BASE + (i << 8));
const uint16_t registerAddress = static_cast<uint16_t>(W5100_S0_BASE + (i << 8));
mySockets[i].registerAddress = registerAddress;
myMemory[registerAddress + W5100_SN_DHAR0] = 0xFF;
myMemory[registerAddress + W5100_SN_DHAR1] = 0xFF;
myMemory[registerAddress + W5100_SN_DHAR2] = 0xFF;
myMemory[registerAddress + W5100_SN_DHAR3] = 0xFF;
myMemory[registerAddress + W5100_SN_DHAR4] = 0xFF;
myMemory[registerAddress + W5100_SN_DHAR5] = 0xFF;
myMemory[registerAddress + W5100_SN_TTL] = 0x80;
}
// initial values
myMemory[W5100_RTR0] = 0x07;
myMemory[W5100_RTR1] = 0xD0;
myMemory[W5100_RTR0] = 0x07;
myMemory[W5100_RTR1] = 0xD0;
myMemory[W5100_RCR] = 0x08;
setRXSizes(W5100_RMSR, 0x55);
setTXSizes(W5100_TMSR, 0x55);
myMemory[W5100_PTIMER] = 0x28;
}
BYTE Uthernet2::IO_C0(WORD programcounter, WORD address, BYTE write, BYTE value, ULONG nCycles)
@ -1162,6 +1318,46 @@ void Uthernet2::InitializeIO(LPBYTE pCxRomPeripheral)
RegisterIoHandler(m_slot, u2_C0, u2_C0, nullptr, nullptr, this, nullptr);
}
void Uthernet2::getMACAddress(const uint32_t address, const MACAddress * & mac)
{
const auto it = myARPCache.find(address);
if (it != myARPCache.end())
{
mac = &it->second;
}
else
{
MACAddress & macAddr = myARPCache[address];
const uint32_t source = readAddress(myMemory.data() + W5100_SIPR0);
if (address == source)
{
const uint8_t * sourceMac = myMemory.data() + W5100_SHAR0;
memcpy(macAddr.address, sourceMac, sizeof(macAddr.address));
}
else
{
memset(macAddr.address, 0xFF, sizeof(macAddr.address)); // fallback to broadcast
if (address != INADDR_BROADCAST)
{
const uint32_t subnet = readAddress(myMemory.data() + W5100_SUBR0);
if ((address & subnet) == (source & subnet))
{
// same network: send ARP request
myNetworkBackend->getMACAddress(address, macAddr);
}
else
{
const uint32_t gateway = readAddress(myMemory.data() + W5100_GAR0);
// different network: go via gateway
myNetworkBackend->getMACAddress(gateway, macAddr);
}
}
}
mac = &macAddr;
}
}
void Uthernet2::Update(const ULONG nExecutedCycles)
{
myNetworkBackend->update(nExecutedCycles);

View file

@ -3,8 +3,10 @@
#include "Card.h"
#include <vector>
#include <map>
class NetworkBackend;
struct MACAddress;
struct Socket
{
@ -28,6 +30,7 @@ struct Socket
socket_t myFD;
int myErrno;
bool isOpen() const;
void clearFD();
void setFD(const socket_t fd, const int status);
void process();
@ -47,6 +50,7 @@ struct Socket
* Documentation from
* http://dserver.macgui.com/Uthernet%20II%20manual%2017%20Nov%2018.pdf
* https://www.wiznet.io/wp-content/uploads/wiznethome/Chip/W5100/Document/W5100_DS_V128E.pdf
* https://www.wiznet.io/wp-content/uploads/wiznethome/Chip/W5100/Document/3150Aplus_5100_ES_V260E.pdf
*/
class Uthernet2 : public Card
@ -54,6 +58,8 @@ class Uthernet2 : public Card
public:
static const std::string& GetSnapshotCardName();
enum PacketDestination { HOST, BROADCAST, OTHER };
Uthernet2(UINT slot);
virtual void Destroy(void) {}
@ -72,6 +78,13 @@ private:
uint16_t myDataAddress;
std::shared_ptr<NetworkBackend> myNetworkBackend;
// the real Uthernet II card does not have a ARP Cache
// but in the interest of speeding up the emulator
// we introduce one
std::map<uint32_t, MACAddress> myARPCache;
void getMACAddress(const uint32_t address, const MACAddress * & mac);
void setSocketModeRegister(const size_t i, const uint16_t address, const uint8_t value);
void setTXSizes(const uint16_t address, uint8_t value);
void setRXSizes(const uint16_t address, uint8_t value);
@ -79,11 +92,14 @@ private:
uint8_t getTXFreeSizeRegister(const size_t i, const size_t shift) const;
uint8_t getRXDataSizeRegister(const size_t i, const size_t shift) const;
void receiveOnePacketMacRaw(const size_t i);
void receiveOnePacketRaw();
void receiveOnePacketIPRaw(const size_t i, const size_t lengthOfPayload, const uint8_t * payload, const uint32_t destination, const uint8_t protocol, const int len);
void receiveOnePacketMacRaw(const size_t i, const int size, uint8_t * data);
void receiveOnePacketFromSocket(const size_t i);
void receiveOnePacket(const size_t i);
int receiveForMacAddress(const bool acceptAll, const int size, uint8_t * data);
int receiveForMacAddress(const bool acceptAll, const int size, uint8_t * data, PacketDestination & packetDestination);
void sendDataIPRaw(const size_t i, std::vector<uint8_t> &data);
void sendDataMacRaw(const size_t i, std::vector<uint8_t> &data) const;
void sendDataToSocket(const size_t i, std::vector<uint8_t> &data);
void sendData(const size_t i);
@ -91,7 +107,7 @@ private:
void resetRXTXBuffers(const size_t i);
void updateRSR(const size_t i);
void openSystemSocket(const size_t i, const int type, const int protocol, const int state);
void openSystemSocket(const size_t i, const int type, const int protocol, const int status);
void openSocket(const size_t i);
void closeSocket(const size_t i);
void connectSocket(const size_t i);

View file

@ -196,11 +196,13 @@ void LoadConfiguration(bool loadImages)
if(REGLOAD(TEXT(REGVALUE_THE_FREEZES_F8_ROM), &dwTmp))
GetPropertySheet().SetTheFreezesF8Rom(dwTmp);
if(REGLOAD(TEXT(REGVALUE_SPKR_VOLUME), &dwTmp))
SpkrSetVolume(dwTmp, GetPropertySheet().GetVolumeMax());
dwTmp = 70;
REGLOAD(TEXT(REGVALUE_SPKR_VOLUME), &dwTmp);
SpkrSetVolume(dwTmp, GetPropertySheet().GetVolumeMax());
if(REGLOAD(TEXT(REGVALUE_MB_VOLUME), &dwTmp))
MB_SetVolume(dwTmp, GetPropertySheet().GetVolumeMax());
dwTmp = 70;
REGLOAD(TEXT(REGVALUE_MB_VOLUME), &dwTmp);
MB_SetVolume(dwTmp, GetPropertySheet().GetVolumeMax());
if(REGLOAD(TEXT(REGVALUE_SAVE_STATE_ON_EXIT), &dwTmp))
g_bSaveStateOnExit = dwTmp ? true : false;

View file

@ -20,8 +20,10 @@
#define W5100_SIPR3 0x0012
#define W5100_RTR0 0x0017
#define W5100_RTR1 0x0018
#define W5100_RCR 0x0019
#define W5100_RMSR 0x001A
#define W5100_TMSR 0x001B
#define W5100_PTIMER 0x0028
#define W5100_UPORT1 0x002F
#define W5100_S0_BASE 0x0400
#define W5100_S3_MAX 0x07FF
@ -58,6 +60,12 @@
#define W5100_SN_SR 0x03
#define W5100_SN_PORT0 0x04
#define W5100_SN_PORT1 0x05
#define W5100_SN_DHAR0 0x06
#define W5100_SN_DHAR1 0x07
#define W5100_SN_DHAR2 0x08
#define W5100_SN_DHAR3 0x09
#define W5100_SN_DHAR4 0x0A
#define W5100_SN_DHAR5 0x0B
#define W5100_SN_DIPR0 0x0C
#define W5100_SN_DIPR1 0x0D
#define W5100_SN_DIPR2 0x0E

View file

@ -0,0 +1,55 @@
include(GNUInstallDirs)
set(SOURCE_FILES
commonframe.cpp
gnuframe.cpp
fileregistry.cpp
ptreeregistry.cpp
programoptions.cpp
utils.cpp
timer.cpp
speed.cpp
)
set(HEADER_FILES
commonframe.h
gnuframe.h
fileregistry.h
ptreeregistry.h
programoptions.h
utils.h
timer.h
speed.h
)
add_library(common2 STATIC
${SOURCE_FILES}
${HEADER_FILES}
)
find_package(Boost REQUIRED
COMPONENTS program_options
)
target_include_directories(common2 PRIVATE
${CMAKE_CURRENT_BINARY_DIR}
${Boost_INCLUDE_DIRS}
)
target_link_libraries(common2 PRIVATE
Boost::program_options
appleii
windows
)
file(RELATIVE_PATH ROOT_PATH ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR})
if ("${ROOT_PATH}" STREQUAL "")
# if the 2 paths are the same
set(ROOT_PATH "./")
endif()
file(RELATIVE_PATH SHARE_PATH ${CMAKE_INSTALL_FULL_BINDIR} ${CMAKE_INSTALL_FULL_DATADIR}/applewin)
configure_file(config.h.in config.h)
install(DIRECTORY ${CMAKE_SOURCE_DIR}/resource
DESTINATION ${CMAKE_INSTALL_DATADIR}/applewin)

View file

@ -0,0 +1,64 @@
#include "StdAfx.h"
#include "frontends/common2/commonframe.h"
#include "frontends/common2/utils.h"
#include "linux/resources.h"
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "Log.h"
#include "SaveState.h"
namespace common2
{
void CommonFrame::LoadSnapshot()
{
Snapshot_LoadState();
}
BYTE* CommonFrame::GetResource(WORD id, LPCSTR lpType, DWORD expectedSize)
{
myResource.clear();
const std::string & filename = getResourceName(id);
const std::string path = getResourcePath(filename);
const int fd = open(path.c_str(), O_RDONLY);
if (fd != -1)
{
struct stat stdbuf;
if ((fstat(fd, &stdbuf) == 0) && S_ISREG(stdbuf.st_mode))
{
const off_t size = stdbuf.st_size;
std::vector<BYTE> data(size);
const ssize_t rd = read(fd, data.data(), size);
if (rd == expectedSize)
{
std::swap(myResource, data);
}
}
close(fd);
}
if (myResource.empty())
{
LogFileOutput("FindResource: could not load resource %s\n", filename.c_str());
}
return myResource.data();
}
std::string CommonFrame::getBitmapFilename(const std::string & resource)
{
if (resource == "CHARSET40") return "CHARSET4.BMP";
if (resource == "CHARSET82") return "CHARSET82.bmp";
if (resource == "CHARSET8M") return "CHARSET8M.bmp";
if (resource == "CHARSET8C") return "CHARSET8C.bmp";
return resource;
}
}

View file

@ -0,0 +1,24 @@
#pragma once
#include "linux/linuxframe.h"
#include <vector>
#include <string>
namespace common2
{
class CommonFrame : public LinuxFrame
{
public:
BYTE* GetResource(WORD id, LPCSTR lpType, DWORD expectedSize) override;
virtual void LoadSnapshot();
protected:
virtual std::string getResourcePath(const std::string & filename) = 0;
static std::string getBitmapFilename(const std::string & resource);
std::vector<BYTE> myResource;
};
}

View file

@ -0,0 +1,6 @@
// relative path from executable to resources
#cmakedefine ROOT_PATH "@ROOT_PATH@"
#cmakedefine SHARE_PATH "@SHARE_PATH@"
// this one is a bit of a hack, until resources are embedded in the retro core
#cmakedefine CMAKE_SOURCE_DIR "@CMAKE_SOURCE_DIR@"

View file

@ -0,0 +1,137 @@
#include "StdAfx.h"
#include "frontends/common2/fileregistry.h"
#include "frontends/common2/ptreeregistry.h"
#include "frontends/common2/programoptions.h"
#include "Log.h"
#include "windows.h"
#include "frontends/qt/applicationname.h"
#include <boost/property_tree/ini_parser.hpp>
#include <sys/stat.h>
namespace
{
void parseOption(const std::string & s, std::string & path, std::string & value)
{
const size_t pos = s.find('=');
if (pos == std::string::npos)
{
throw std::runtime_error("Invalid option format: " + s + ", expected: section.key=value");
}
path = s.substr(0, pos);
std::replace(path.begin(), path.end(), '_', ' ');
value = s.substr(pos + 1);
std::replace(value.begin(), value.end(), '_', ' ');
}
class Configuration : public common2::PTreeRegistry
{
public:
Configuration(const std::string & filename, const bool saveOnExit);
~Configuration();
void addExtraOptions(const std::vector<std::string> & options);
private:
const std::string myFilename;
bool mySaveOnExit;
};
Configuration::Configuration(const std::string & filename, const bool saveOnExit) : myFilename(filename), mySaveOnExit(saveOnExit)
{
if (GetFileAttributes(myFilename.c_str()) != INVALID_FILE_ATTRIBUTES)
{
boost::property_tree::ini_parser::read_ini(myFilename, myINI);
}
else
{
LogFileOutput("Registry: configuration file '%s' not found\n", filename.c_str());
}
}
Configuration::~Configuration()
{
if (mySaveOnExit)
{
try
{
boost::property_tree::ini_parser::write_ini(myFilename, myINI);
}
catch(const std::exception& e)
{
LogFileOutput("Registry: cannot save settings to '%s': %s\n", myFilename.c_str(), e.what());
}
}
}
void Configuration::addExtraOptions(const std::vector<std::string> & options)
{
for (const std::string & option : options)
{
std::string path, value;
parseOption(option, path, value);
myINI.put(path, value);
}
}
}
namespace common2
{
std::string GetHomeDir()
{
const char* homeDir = getenv("HOME");
if (!homeDir)
{
throw std::runtime_error("${HOME} not set, cannot locate configuration file");
}
return std::string(homeDir);
}
std::string GetConfigFile(const std::string & filename)
{
const std::string dir = GetHomeDir() + "/.applewin";
const int status = mkdir(dir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
if (!status || (errno == EEXIST))
{
return dir + "/" + filename;
}
else
{
const char * s = strerror(errno);
LogFileOutput("No registry. Cannot create %s in %s: %s\n", filename.c_str(), dir.c_str(), s);
return std::string();
}
}
std::shared_ptr<Registry> CreateFileRegistry(const EmulatorOptions & options)
{
const std::string homeDir = GetHomeDir();
std::string filename;
bool saveOnExit;
if (options.useQtIni)
{
filename = homeDir + "/.config/" + ORGANIZATION_NAME + "/" + APPLICATION_NAME + ".conf";
saveOnExit = false;
}
else
{
filename = options.configurationFile;
saveOnExit = true;
}
std::shared_ptr<Configuration> config(new Configuration(filename, saveOnExit));
config->addExtraOptions(options.registryOptions);
return config;
}
}

View file

@ -0,0 +1,17 @@
#pragma once
#include <string>
#include <memory>
class Registry;
namespace common2
{
struct EmulatorOptions;
std::string GetConfigFile(const std::string & filename);
std::shared_ptr<Registry> CreateFileRegistry(const EmulatorOptions & options);
std::string GetHomeDir();
}

View file

@ -0,0 +1,99 @@
#include "StdAfx.h"
#include "frontends/common2/gnuframe.h"
#include "frontends/common2/fileregistry.h"
#include <sys/stat.h>
#include <unistd.h>
#include <libgen.h>
#ifdef __APPLE__
#include "mach-o/dyld.h"
#endif
#include "Core.h"
#include "config.h"
namespace
{
bool dirExists(const std::string & folder)
{
struct stat stdbuf;
if (stat(folder.c_str(), &stdbuf) == 0 && S_ISDIR(stdbuf.st_mode))
{
return true;
}
else
{
return false;
}
}
std::string getResourceFolder(const std::string & target)
{
std::vector<std::string> paths;
char self[1024] = {0};
#ifdef __APPLE__
uint32_t size = sizeof(self);
const int ch = _NSGetExecutablePath(self, &size);
#else
const int ch = readlink("/proc/self/exe", self, sizeof(self));
#endif
if (ch != -1)
{
const char * path = dirname(self);
// case 1: run from the build folder
paths.emplace_back(std::string(path) + '/'+ ROOT_PATH);
// case 2: run from the installation folder
paths.emplace_back(std::string(path) + '/'+ SHARE_PATH);
}
// case 3: use the source folder
paths.emplace_back(CMAKE_SOURCE_DIR);
for (const std::string & path : paths)
{
char * real = realpath(path.c_str(), nullptr);
if (real)
{
const std::string resourcePath = std::string(real) + target;
free(real);
if (dirExists(resourcePath))
{
return resourcePath;
}
}
}
throw std::runtime_error("Cannot found the resource path: " + target);
}
}
namespace common2
{
GNUFrame::GNUFrame()
: myHomeDir(GetHomeDir())
, myResourceFolder(getResourceFolder("/resource/"))
{
// should this go down to LinuxFrame (maybe Initialisation?)
g_sProgramDir = getResourceFolder("/bin/");
}
std::string GNUFrame::getResourcePath(const std::string & filename)
{
return myResourceFolder + filename;
}
std::string GNUFrame::Video_GetScreenShotFolder() const
{
return myHomeDir + "/Pictures/";
}
}

View file

@ -0,0 +1,22 @@
#pragma once
#include "frontends/common2/commonframe.h"
#include <string>
namespace common2
{
class GNUFrame : public virtual CommonFrame
{
public:
GNUFrame();
std::string Video_GetScreenShotFolder() const override;
std::string getResourcePath(const std::string & filename) override;
private:
const std::string myHomeDir;
const std::string myResourceFolder;
};
}

View file

@ -0,0 +1,252 @@
#include "frontends/common2/programoptions.h"
#include "frontends/common2/fileregistry.h"
#include "linux/version.h"
#include "linux/paddle.h"
#include <boost/program_options.hpp>
#include "StdAfx.h"
#include "Memory.h"
#include "Log.h"
#include "Disk.h"
#include "Utilities.h"
#include "Core.h"
#include <iostream>
#include <regex>
namespace po = boost::program_options;
namespace
{
void parseGeometry(const std::string & s, common2::Geometry & geometry)
{
std::smatch m;
if (std::regex_match(s, m, std::regex("^(\\d+)x(\\d+)(\\+(\\d+)\\+(\\d+))?$")))
{
const size_t groups = m.size();
if (groups == 6)
{
geometry.width = std::stoi(m.str(1));
geometry.height = std::stoi(m.str(2));
if (!m.str(3).empty())
{
geometry.x = std::stoi(m.str(4));
geometry.y = std::stoi(m.str(5));
}
return;
}
}
throw std::runtime_error("Invalid sizes: " + s);
}
}
namespace common2
{
EmulatorOptions::EmulatorOptions()
{
memclear = g_nMemoryClearType;
configurationFile = GetConfigFile("applewin.conf");
}
bool getEmulatorOptions(int argc, const char * argv [], const std::string & edition, EmulatorOptions & options)
{
const std::string name = "Apple Emulator for " + edition + " (based on AppleWin " + getVersion() + ")";
po::options_description desc(name);
desc.add_options()
("help,h", "Print this help message")
;
po::options_description configDesc("configuration");
configDesc.add_options()
("conf", po::value<std::string>()->default_value(options.configurationFile), "Select configuration file")
("registry,r", po::value<std::vector<std::string>>(), "Registry options section.path=value")
("qt-ini,q", "Use Qt ini file (read only)")
;
desc.add(configDesc);
po::options_description diskDesc("Disk");
diskDesc.add_options()
("d1,1", po::value<std::string>(), "Disk in 1st drive")
("d2,2", po::value<std::string>(), "Disk in 2nd drive")
;
desc.add(diskDesc);
po::options_description snapshotDesc("Snapshot");
snapshotDesc.add_options()
("state-filename,f", po::value<std::string>(), "Set snapshot filename")
("load-state,s", po::value<std::string>(), "Load snapshot from file")
;
desc.add(snapshotDesc);
po::options_description memoryDesc("Memory");
memoryDesc.add_options()
("memclear", po::value<int>()->default_value(options.memclear), "Memory initialization pattern [0..7]")
;
desc.add(memoryDesc);
po::options_description emulatorDesc("Emulator");
emulatorDesc.add_options()
("log", "Log to AppleWin.log")
("headless", "Headless: disable video (freewheel)")
("fixed-speed", "Fixed (non-adaptive) speed")
("ntsc,nt", "NTSC: execute NTSC code")
("benchmark,b", "Benchmark emulator")
("rom", po::value<std::string>(), "Custom 12k/16k ROM")
("f8rom", po::value<std::string>(), "Custom 2k ROM")
;
desc.add(emulatorDesc);
po::options_description sdlDesc("SDL");
sdlDesc.add_options()
("sdl-driver", po::value<int>()->default_value(options.sdlDriver), "SDL driver")
("gl-swap", po::value<int>()->default_value(options.glSwapInterval), "SDL_GL_SwapInterval")
("no-imgui", "Plain SDL2 renderer")
("geometry", po::value<std::string>(), "WxH[+X+Y]")
;
desc.add(sdlDesc);
po::options_description paddleDesc("Paddle");
paddleDesc.add_options()
("no-squaring", "Gamepad range is (already) a square")
("device-name", po::value<std::string>(), "Gamepad device name")
;
desc.add(paddleDesc);
po::variables_map vm;
try
{
po::store(po::parse_command_line(argc, argv, desc), vm);
if (vm.count("help"))
{
std::cout << desc << std::endl;
return false;
}
options.configurationFile = vm["conf"].as<std::string>();
options.useQtIni = vm.count("qt-ini");
options.sdlDriver = vm["sdl-driver"].as<int>();
options.glSwapInterval = vm["gl-swap"].as<int>();
options.imgui = vm.count("no-imgui") == 0;
if (vm.count("registry"))
{
options.registryOptions = vm["registry"].as<std::vector<std::string> >();
}
if (vm.count("d1"))
{
options.disk1 = vm["d1"].as<std::string>();
}
if (vm.count("d2"))
{
options.disk2 = vm["d2"].as<std::string>();
}
if (vm.count("load-state"))
{
options.snapshotFilename = vm["load-state"].as<std::string>();
options.loadSnapshot = true;
}
if (vm.count("state-filename"))
{
options.snapshotFilename = vm["state-filename"].as<std::string>();
options.loadSnapshot = false;
}
if (vm.count("rom"))
{
options.customRom = vm["rom"].as<std::string>();
}
if (vm.count("f8rom"))
{
options.customRomF8 = vm["f8rom"].as<std::string>();
}
const int memclear = vm["memclear"].as<int>();
if (memclear >=0 && memclear < NUM_MIP)
options.memclear = memclear;
options.benchmark = vm.count("benchmark") > 0;
options.headless = vm.count("headless") > 0;
options.log = vm.count("log") > 0;
options.ntsc = vm.count("ntsc") > 0;
options.fixedSpeed = vm.count("fixed-speed") > 0;
options.paddleSquaring = vm.count("no-squaring") == 0;
if (vm.count("device-name"))
{
options.paddleDeviceName = vm["device-name"].as<std::string>();
}
if (vm.count("geometry"))
{
options.geometry.empty = false;
parseGeometry(vm["geometry"].as<std::string>(), options.geometry);
}
return true;
}
catch (const po::error& e)
{
std::cerr << "ERROR: " << e.what() << std::endl << desc << std::endl;
return false;
}
catch (const std::exception & e)
{
std::cerr << "ERROR: " << e.what() << std::endl;
return false;
}
}
void applyOptions(const EmulatorOptions & options)
{
g_nMemoryClearType = options.memclear;
LPCSTR szImageName_drive[NUM_DRIVES] = {nullptr, nullptr};
bool driveConnected[NUM_DRIVES] = {true, true};
if (!options.disk1.empty())
{
szImageName_drive[DRIVE_1] = options.disk1.c_str();
}
if (!options.disk2.empty())
{
szImageName_drive[DRIVE_2] = options.disk2.c_str();
}
bool bBoot;
InsertFloppyDisks(SLOT6, szImageName_drive, driveConnected, bBoot);
if (!options.customRom.empty())
{
CloseHandle(g_hCustomRom);
g_hCustomRom = CreateFile(options.customRom.c_str(), GENERIC_READ, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, nullptr);
if (g_hCustomRom == INVALID_HANDLE_VALUE)
{
LogFileOutput("Init: Failed to load Custom ROM: %s\n", options.customRom.c_str());
}
}
if (!options.customRomF8.empty())
{
CloseHandle(g_hCustomRomF8);
g_hCustomRomF8 = CreateFile(options.customRomF8.c_str(), GENERIC_READ, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, nullptr);
if (g_hCustomRomF8 == INVALID_HANDLE_VALUE)
{
LogFileOutput("Init: Failed to load custom F8 ROM: %s\n", options.customRomF8.c_str());
}
}
Paddle::setSquaring(options.paddleSquaring);
}
}

View file

@ -0,0 +1,64 @@
#pragma once
#include <string>
#include <vector>
namespace common2
{
struct Geometry
{
bool empty = true;
int width;
int height;
int x;
int y;
};
struct EmulatorOptions
{
EmulatorOptions();
std::string disk1;
std::string disk2;
std::string snapshotFilename;
bool loadSnapshot = false;
int memclear;
bool log = false;
bool benchmark = false;
bool headless = false;
bool ntsc = false; // only for applen
bool paddleSquaring = true; // turn the x/y range to a square
// on my PC it is something like
// "/dev/input/by-id/usb-©Microsoft_Corporation_Controller_1BBE3DB-event-joystick"
std::string paddleDeviceName;
std::string configurationFile;
bool useQtIni = false; // use Qt .ini file (read only)
bool run = true; // false if options include "-h"
bool fixedSpeed = false; // default adaptive
int sdlDriver = -1; // default = -1 to let SDL choose
bool imgui = true; // use imgui renderer
Geometry geometry; // must be initialised with defaults
int glSwapInterval = 1; // SDL_GL_SetSwapInterval
std::string customRomF8;
std::string customRom;
std::vector<std::string> registryOptions;
};
bool getEmulatorOptions(int argc, const char * argv [], const std::string & edition, EmulatorOptions & options);
void applyOptions(const EmulatorOptions & options);
}

View file

@ -0,0 +1,82 @@
#include "frontends/common2/ptreeregistry.h"
#include <boost/algorithm/string/replace.hpp>
namespace
{
std::string decodeKey(const std::string & key)
{
std::string result = key;
// quick implementation, just to make it work.
// is there a library function available somewhere?
boost::algorithm::replace_all(result, "%20", " ");
return result;
}
}
namespace common2
{
bool PTreeRegistry::KeyQtEncodedLess::operator()(const std::string & lhs, const std::string & rhs) const
{
const std::string key1 = decodeKey(lhs);
const std::string key2 = decodeKey(rhs);
return key1 < key2;
}
std::string PTreeRegistry::getString(const std::string & section, const std::string & key) const
{
return getValue<std::string>(section, key);
}
DWORD PTreeRegistry::getDWord(const std::string & section, const std::string & key) const
{
return getValue<DWORD>(section, key);
}
bool PTreeRegistry::getBool(const std::string & section, const std::string & key) const
{
return getValue<bool>(section, key);
}
void PTreeRegistry::putString(const std::string & section, const std::string & key, const std::string & value)
{
putValue(section, key, value);
}
void PTreeRegistry::putDWord(const std::string & section, const std::string & key, const DWORD value)
{
putValue(section, key, value);
}
template <typename T>
T PTreeRegistry::getValue(const std::string & section, const std::string & key) const
{
const std::string path = section + "." + key;
const T value = myINI.get<T>(path);
return value;
}
template <typename T>
void PTreeRegistry::putValue(const std::string & section, const std::string & key, const T & value)
{
const std::string path = section + "." + key;
myINI.put(path, value);
}
std::map<std::string, std::map<std::string, std::string>> PTreeRegistry::getAllValues() const
{
std::map<std::string, std::map<std::string, std::string>> values;
for (const auto & it1 : myINI)
{
for (const auto & it2 : it1.second)
{
values[it1.first][it2.first] = it2.second.get_value<std::string>();
}
}
return values;
}
}

View file

@ -0,0 +1,42 @@
#pragma once
#include "linux/registry.h"
#include <boost/property_tree/ptree.hpp>
#include <string>
namespace common2
{
class PTreeRegistry : public Registry
{
public:
struct KeyQtEncodedLess
{
// this function is used to make the Qt registry compatible with sa2 and napple
// it is here, in the base class PTreeRegistry simply because it makes things easier
// KeyQtEncodedLess goes in the typedef init_t below
bool operator()(const std::string & lhs, const std::string & rhs) const;
};
typedef boost::property_tree::basic_ptree<std::string, std::string, KeyQtEncodedLess> ini_t;
std::string getString(const std::string & section, const std::string & key) const override;
DWORD getDWord(const std::string & section, const std::string & key) const override;
bool getBool(const std::string & section, const std::string & key) const override;
void putString(const std::string & section, const std::string & key, const std::string & value) override;
void putDWord(const std::string & section, const std::string & key, const DWORD value) override;
template<typename T>
T getValue(const std::string & section, const std::string & key) const;
template<typename T>
void putValue(const std::string & section, const std::string & key, const T & value);
std::map<std::string, std::map<std::string, std::string>> getAllValues() const override;
protected:
ini_t myINI;
};
}

View file

@ -0,0 +1,59 @@
#include "frontends/common2/speed.h"
#include "StdAfx.h"
#include "CPU.h"
#include "Core.h"
namespace common2
{
Speed::Speed(const bool fixedSpeed)
: myFixedSpeed(fixedSpeed)
{
reset();
}
void Speed::reset()
{
myStartTime = std::chrono::steady_clock::now();
myStartCycles = g_nCumulativeCycles;
}
uint64_t Speed::getCyclesAtFixedSpeed(const size_t microseconds) const
{
const uint64_t cycles = static_cast<uint64_t>(microseconds * g_fCurrentCLK6502 * 1.0e-6);
return cycles;
}
uint64_t Speed::getCyclesTillNext(const size_t microseconds) const
{
if (myFixedSpeed || g_bFullSpeed)
{
return getCyclesAtFixedSpeed(microseconds);
}
else
{
const uint64_t currentCycles = g_nCumulativeCycles;
const auto currentTime = std::chrono::steady_clock::now();
const auto currentDelta = std::chrono::duration_cast<std::chrono::microseconds>(currentTime - myStartTime).count();
// target the next time we will be called
const auto targetDeltaInMicros = currentDelta + microseconds;
const uint64_t targetCycles = static_cast<uint64_t>(targetDeltaInMicros * g_fCurrentCLK6502 * 1.0e-6) + myStartCycles;
if (targetCycles > currentCycles)
{
// number of cycles to fill this period
const uint64_t cyclesToExecute = targetCycles - currentCycles;
return cyclesToExecute;
}
else
{
// we got ahead, nothing to do this time
// CpuExecute will still execute 1 instruction, which does not cause any issues
return 0;
}
}
}
}

View file

@ -0,0 +1,27 @@
#pragma once
#include <chrono>
namespace common2
{
class Speed
{
public:
Speed(const bool fixedSpeed);
void reset();
// calculate the number of cycles to execute in the current period
// assuming the next call will happen in x microseconds
uint64_t getCyclesTillNext(const size_t microseconds) const;
uint64_t getCyclesAtFixedSpeed(const size_t microseconds) const;
private:
const bool myFixedSpeed;
std::chrono::time_point<std::chrono::steady_clock> myStartTime;
uint64_t myStartCycles;
};
}

View file

@ -0,0 +1,53 @@
#include "frontends/common2/timer.h"
#include <ostream>
#include <cmath>
#include <iomanip>
namespace common2
{
Timer::Timer()
: mySum(0)
, mySum2(0)
, myN(0)
{
tic();
}
void Timer::tic()
{
myT0 = std::chrono::steady_clock::now();
}
void Timer::toc()
{
const auto now = std::chrono::steady_clock::now();
const auto micros = std::chrono::duration_cast<std::chrono::microseconds>(now - myT0).count();
const double s = micros * 0.000001;
mySum += s;
mySum2 += s * s;
++myN;
myT0 = now;
}
double Timer::getTimeInSeconds() const
{
return mySum;
}
std::ostream& operator<<(std::ostream& os, const Timer & timer)
{
const int width = 10;
const double m1 = timer.mySum / timer.myN;
const double m2 = timer.mySum2 / timer.myN;
const double std = std::sqrt(std::max(0.0, m2 - m1 * m1));
const double scale = 1000;
os << "total = " << std::setw(width) << timer.mySum * scale << " ms";
os << ", mean = " << std::setw(width) << m1 * scale << " ms";
os << ", std = " << std::setw(width) << std * scale << " ms";
os << ", n = " << std::setw(6) << timer.myN;
return os;
}
}

View file

@ -0,0 +1,29 @@
#include <chrono>
#include <iosfwd>
namespace common2
{
class Timer
{
public:
Timer();
void tic();
void toc();
double getTimeInSeconds() const;
friend std::ostream& operator<<(std::ostream& os, const Timer & timer);
private:
std::chrono::time_point<std::chrono::steady_clock> myT0;
double mySum;
double mySum2;
int myN;
};
std::ostream& operator<<(std::ostream& os, const Timer & timer);
}

View file

@ -0,0 +1,68 @@
#include "StdAfx.h"
#include "frontends/common2/utils.h"
#include "frontends/common2/programoptions.h"
#include "SaveState.h"
#include "Registry.h"
#include <libgen.h>
#include <unistd.h>
namespace common2
{
void setSnapshotFilename(const std::string & filename)
{
if (!filename.empty())
{
// it is unbelievably hard to convert a path to absolute
// unless the file exists
char * temp = strdup(filename.c_str());
const char * dir = dirname(temp);
// dir points inside temp!
chdir(dir);
Snapshot_SetFilename(filename);
free(temp);
}
}
void loadGeometryFromRegistry(const std::string &section, Geometry & geometry)
{
if (geometry.empty) // otherwise it was user provided
{
const std::string path = section + "\\geometry";
const auto loadValue = [&path](const char * name, int & dest)
{
DWORD value;
if (RegLoadValue(path.c_str(), name, TRUE, &value))
{
// DWORD and int have the same size
// but if they did not, this would be necessary
typedef std::make_signed<DWORD>::type signed_t;
dest = static_cast<signed_t>(value);
}
};
loadValue("width", geometry.width);
loadValue("height", geometry.height);
loadValue("x", geometry.x);
loadValue("y", geometry.y);
}
}
void saveGeometryToRegistry(const std::string &section, const Geometry & geometry)
{
const std::string path = section + "\\geometry";
const auto saveValue = [&path](const char * name, const int source)
{
// this seems to already do the right thing for negative numbers
RegSaveValue(path.c_str(), name, TRUE, source);
};
saveValue("width", geometry.width);
saveValue("height", geometry.height);
saveValue("x", geometry.x);
saveValue("y", geometry.y);
}
}

View file

@ -0,0 +1,13 @@
#pragma once
#include <string>
namespace common2
{
struct Geometry;
void setSnapshotFilename(const std::string & filename);
void loadGeometryFromRegistry(const std::string &section, Geometry & geometry);
void saveGeometryToRegistry(const std::string &section, const Geometry & geometry);
}

View file

@ -0,0 +1,51 @@
set(SOURCE_FILES
environment.cpp
libretro.cpp
rdirectsound.cpp
game.cpp
joypadbase.cpp
joypad.cpp
mouse.cpp
analog.cpp
rdirectsound.cpp
retroregistry.cpp
retroframe.cpp
diskcontrol.cpp
serialisation.cpp
)
set(HEADER_FILES
libretro-common/include/libretro.h
environment.h
rdirectsound.h
game.h
joypadbase.h
joypad.h
mouse.h
analog.h
rdirectsound.h
retroregistry.h
retroframe.h
diskcontrol.h
serialisation.h
)
add_library(applewin_libretro SHARED
${SOURCE_FILES}
${HEADER_FILES}
)
target_compile_features(applewin_libretro PUBLIC cxx_std_17)
target_include_directories(applewin_libretro PRIVATE
libretro-common/include
)
target_link_libraries(applewin_libretro PRIVATE
appleii
common2
windows
)
# just call it "applewin_libretro.so" as per libretro standard
set_target_properties(applewin_libretro PROPERTIES PREFIX "")

View file

@ -0,0 +1,28 @@
#include "frontends/libretro/analog.h"
#include "frontends/libretro/environment.h"
#include "libretro.h"
#define AXIS_MIN -32768
#define AXIS_MAX 32767
namespace ra2
{
Analog::Analog(unsigned device)
: JoypadBase(device)
, myAxisCodes(2)
{
myAxisCodes[0] = std::make_pair(RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X);
myAxisCodes[1] = std::make_pair(RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y);
}
double Analog::getAxis(int i) const
{
const auto & code = myAxisCodes[i];
const int value = input_state_cb(0, myDevice, code.first, code.second);
const double axis = 2.0 * double(value - AXIS_MIN) / double(AXIS_MAX - AXIS_MIN) - 1.0;
return axis;
}
}

View file

@ -0,0 +1,21 @@
#pragma once
#include "frontends/libretro/joypadbase.h"
#include <vector>
namespace ra2
{
class Analog : public JoypadBase
{
public:
Analog(unsigned device);
double getAxis(int i) const override;
private:
std::vector<std::pair<unsigned, unsigned> > myAxisCodes;
};
}

View file

@ -0,0 +1,45 @@
#include <cstddef>
#include <stdexcept>
namespace ra2
{
template<typename C> // so it works with both char * and const char *
class Buffer
{
public:
Buffer(C * const begin, size_t const size) : myPtr(begin), myEnd(begin + size)
{
}
template <typename T>
T & get()
{
C * c = myPtr;
advance(sizeof(T));
return *reinterpret_cast<T *>(c);
}
void get(size_t const size, C * & begin, C * & end)
{
begin = myPtr;
advance(size);
end = myPtr;
}
private:
C * myPtr;
C * const myEnd;
void advance(size_t const size)
{
if (myPtr + size > myEnd)
{
throw std::runtime_error("Buffer: out of bounds");
}
myPtr += size;
}
};
}

View file

@ -0,0 +1,289 @@
#include "StdAfx.h"
#include "frontends/libretro/diskcontrol.h"
#include "frontends/libretro/environment.h"
#include "Core.h"
#include "CardManager.h"
#include "Disk.h"
#include "Harddisk.h"
#include <fstream>
namespace ra2
{
DiskControl::DiskControl() : myEjected(false), myIndex(0)
{
}
bool DiskControl::insertDisk(const std::string & filename)
{
if (insertFloppyDisk(filename))
{
myIndex = 0;
myImages.clear();
myImages.push_back(filename);
myEjected = false;
return true;
}
return insertHardDisk(filename);
}
bool DiskControl::insertPlaylist(const std::string & filename)
{
const std::filesystem::path path(filename);
std::ifstream playlist(path);
if (!playlist)
{
return false;
}
myImages.clear();
const std::filesystem::path parent = path.parent_path();
std::string line;
while (std::getline(playlist, line))
{
// should we trim initial spaces?
if (!line.empty() && line[0] != '#')
{
std::filesystem::path image(line);
if (image.is_relative())
{
image = parent / image;
}
myImages.push_back(image);
}
}
// if we have an initial disk image, let's try to honour it
if (!ourInitialPath.empty() && ourInitialIndex < myImages.size() && myImages[ourInitialIndex] == ourInitialPath)
{
myIndex = ourInitialIndex;
// do we need to reset for next time?
ourInitialPath.clear();
ourInitialIndex = 0;
}
else
{
// insert the first image
myIndex = 0;
}
// this is safe even if myImages is empty
myEjected = true;
return setEjectedState(false);
}
bool DiskControl::insertFloppyDisk(const std::string & filename) const
{
CardManager & cardManager = GetCardMgr();
Disk2InterfaceCard * disk2Card = dynamic_cast<Disk2InterfaceCard*>(cardManager.GetObj(SLOT6));
if (disk2Card)
{
const ImageError_e error = disk2Card->InsertDisk(DRIVE_1, filename.c_str(), IMAGE_FORCE_WRITE_PROTECTED, IMAGE_DONT_CREATE);
if (error == eIMAGE_ERROR_NONE)
{
return true;
}
}
return false;
}
bool DiskControl::insertHardDisk(const std::string & filename) const
{
CardManager & cardManager = GetCardMgr();
if (cardManager.QuerySlot(SLOT7) != CT_GenericHDD)
{
cardManager.Insert(SLOT7, CT_GenericHDD);
}
HarddiskInterfaceCard * harddiskCard = dynamic_cast<HarddiskInterfaceCard*>(cardManager.GetObj(SLOT7));
if (harddiskCard)
{
BOOL bRes = harddiskCard->Insert(HARDDISK_1, filename);
return bRes == TRUE;
}
return false;
}
bool DiskControl::getEjectedState() const
{
return myEjected;
}
bool DiskControl::setEjectedState(bool ejected)
{
if (myEjected == ejected)
{
return true; // or false?
}
CardManager & cardManager = GetCardMgr();
Disk2InterfaceCard * disk2Card = dynamic_cast<Disk2InterfaceCard*>(cardManager.GetObj(SLOT6));
bool result = false;
if (disk2Card && myIndex < myImages.size())
{
if (ejected)
{
disk2Card->EjectDisk(DRIVE_1);
result = true;
myEjected = ejected;
}
else
{
// inserted
result = insertFloppyDisk(myImages[myIndex]);
myEjected = !result;
ra2::log_cb(RETRO_LOG_INFO, "Insert new disk: %s -> %d\n", myImages[myIndex].c_str(), result);
}
}
return result;
}
size_t DiskControl::getImageIndex() const
{
return myIndex;
}
bool DiskControl::setImageIndex(size_t index)
{
if (myEjected)
{
myIndex = index;
return true;
}
else
{
return false;
}
}
size_t DiskControl::getNumImages() const
{
return myImages.size();
}
bool DiskControl::replaceImageIndex(size_t index, const std::string & path)
{
if (myEjected && myIndex < myImages.size())
{
myImages[index] = path;
return true;
}
else
{
return false;
}
}
bool DiskControl::removeImageIndex(size_t index)
{
if (myEjected && myIndex < myImages.size())
{
myImages.erase(myImages.begin() + index);
if (myImages.empty() || myIndex == index)
{
myIndex = myImages.size();
}
else if (myIndex > index)
{
--myIndex;
}
return true;
}
else
{
return false;
}
}
bool DiskControl::addImageIndex()
{
myImages.push_back(std::string());
return true;
}
bool DiskControl::getImagePath(unsigned index, char *path, size_t len) const
{
if (index < myImages.size())
{
strncpy(path, myImages[index].c_str(), len);
path[len - 1] = 0;
return true;
}
else
{
return false;
}
}
bool DiskControl::getImageLabel(unsigned index, char *label, size_t len) const
{
if (index < myImages.size())
{
const std::string filename = myImages[index].filename();
strncpy(label, filename.c_str(), len);
label[len - 1] = 0;
return true;
}
else
{
return false;
}
}
void DiskControl::serialise(Buffer<char> & buffer) const
{
buffer.get<bool>() = myEjected;
buffer.get<size_t>() = myIndex;
buffer.get<size_t>() = myImages.size();
for (std::string const & image : myImages)
{
size_t const size = image.size();
buffer.get<size_t>() = size;
char * begin, * end;
buffer.get(size, begin, end);
memcpy(begin, image.data(), end - begin);
}
}
void DiskControl::deserialise(Buffer<char const> & buffer)
{
myEjected = buffer.get<bool const>();
myIndex = buffer.get<size_t const>();
size_t const numberOfImages = buffer.get<size_t const>();
myImages.clear();
myImages.resize(numberOfImages);
for (size_t i = 0; i < numberOfImages; ++i)
{
size_t const size = buffer.get<size_t const>();
char const * begin, * end;
buffer.get(size, begin, end);
myImages[i].assign(begin, end);
}
}
unsigned DiskControl::ourInitialIndex = 0;
std::string DiskControl::ourInitialPath;
void DiskControl::setInitialPath(unsigned index, const char *path)
{
if (path && *path)
{
ourInitialIndex = index;
ourInitialPath = path;
}
}
}

View file

@ -0,0 +1,51 @@
#include "frontends/libretro/buffer.h"
#include <vector>
#include <string>
#include <filesystem>
namespace ra2
{
class DiskControl
{
public:
DiskControl();
bool getEjectedState() const;
bool setEjectedState(bool state);
size_t getImageIndex() const;
bool setImageIndex(size_t index);
size_t getNumImages() const;
bool replaceImageIndex(size_t index, const std::string & path);
bool removeImageIndex(size_t index);
bool addImageIndex();
// these 2 functions update the images for the Disc Control Interface
bool insertDisk(const std::string & filename);
bool insertPlaylist(const std::string & filename);
bool getImagePath(unsigned index, char *path, size_t len) const;
bool getImageLabel(unsigned index, char *label, size_t len) const;
static void setInitialPath(unsigned index, const char *path);
void serialise(Buffer<char> & buffer) const;
void deserialise(Buffer<char const> & buffer);
private:
std::vector<std::filesystem::path> myImages;
bool myEjected;
size_t myIndex;
bool insertFloppyDisk(const std::string & filename) const;
bool insertHardDisk(const std::string & filename) const;
static unsigned ourInitialIndex;
static std::string ourInitialPath;
};
}

View file

@ -0,0 +1,36 @@
#include "frontends/libretro/environment.h"
#include <cstdarg>
#include <iostream>
namespace ra2
{
void fallback_log(enum retro_log_level level, const char *fmt, ...)
{
(void)level;
va_list va;
va_start(va, fmt);
vfprintf(stderr, fmt, va);
va_end(va);
}
retro_log_callback logging;
retro_log_printf_t log_cb = fallback_log;
retro_input_poll_t input_poll_cb;
retro_input_state_t input_state_cb;
retro_environment_t environ_cb;
retro_video_refresh_t video_cb;
retro_audio_sample_t audio_cb;
retro_audio_sample_batch_t audio_batch_cb;
void display_message(const std::string & message)
{
retro_message rmsg;
rmsg.frames = 180;
rmsg.msg = message.c_str();
environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE, &rmsg);
}
}

View file

@ -0,0 +1,22 @@
#include "libretro.h"
#include <string>
namespace ra2
{
void fallback_log(enum retro_log_level level, const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
extern retro_log_callback logging;
extern retro_log_printf_t log_cb __attribute__((format(printf, 2, 3)));
extern retro_input_poll_t input_poll_cb;
extern retro_input_state_t input_state_cb;
extern retro_environment_t environ_cb;
extern retro_video_refresh_t video_cb;
extern retro_audio_sample_t audio_cb;
extern retro_audio_sample_batch_t audio_batch_cb;
#define MAX_PADS 1
void display_message(const std::string & message);
}

View file

@ -0,0 +1,273 @@
#include "StdAfx.h"
#include "frontends/libretro/game.h"
#include "frontends/libretro/retroregistry.h"
#include "frontends/libretro/retroframe.h"
#include "Common.h"
#include "CardManager.h"
#include "Core.h"
#include "Mockingboard.h"
#include "Speaker.h"
#include "Log.h"
#include "CPU.h"
#include "NTSC.h"
#include "Utilities.h"
#include "Interface.h"
#include "linux/keyboard.h"
#include "linux/registry.h"
#include "linux/paddle.h"
#include "linux/context.h"
#include "frontends/common2/utils.h"
#include "libretro.h"
namespace ra2
{
unsigned Game::ourInputDevices[MAX_PADS] = {RETRO_DEVICE_NONE};
Game::Game()
: mySpeed(true) // fixed speed
, myButtonStates(RETRO_DEVICE_ID_JOYPAD_R3 + 1)
{
myLoggerContext.reset(new LoggerContext(true));
myRegistryContext.reset(new RegistryContext(CreateRetroRegistry()));
myFrame.reset(new ra2::RetroFrame());
SetFrame(myFrame);
myFrame->Begin();
Video & video = GetVideo();
// should the user be allowed to tweak 0.75
myMouse[0] = {0.0, 0.75 / video.GetFrameBufferBorderlessWidth(), RETRO_DEVICE_ID_MOUSE_X};
myMouse[1] = {0.0, 0.75 / video.GetFrameBufferBorderlessHeight(), RETRO_DEVICE_ID_MOUSE_Y};
}
Game::~Game()
{
myFrame->End();
myFrame.reset();
SetFrame(myFrame);
}
retro_usec_t Game::ourFrameTime = 0;
void Game::executeOneFrame()
{
if (g_nAppMode == MODE_RUNNING)
{
const bool bVideoUpdate = true;
const UINT dwClksPerFrame = NTSC_GetCyclesPerFrame();
const uint64_t cyclesToExecute = mySpeed.getCyclesTillNext(ourFrameTime);
const DWORD executedCycles = CpuExecute(cyclesToExecute, bVideoUpdate);
g_dwCyclesThisFrame = (g_dwCyclesThisFrame + executedCycles) % dwClksPerFrame;
GetCardMgr().Update(executedCycles);
SpkrUpdate(executedCycles);
}
}
void Game::processInputEvents()
{
input_poll_cb();
keyboardEmulation();
mouseEmulation();
}
void Game::keyboardCallback(bool down, unsigned keycode, uint32_t character, uint16_t key_modifiers)
{
if (down)
{
processKeyDown(keycode, character, key_modifiers);
}
else
{
processKeyUp(keycode, character, key_modifiers);
}
}
void Game::frameTimeCallback(retro_usec_t usec)
{
ourFrameTime = usec;
}
void Game::processKeyDown(unsigned keycode, uint32_t character, uint16_t key_modifiers)
{
BYTE ch = 0;
switch (keycode)
{
case RETROK_RETURN:
{
ch = 0x0d;
break;
}
case RETROK_BACKSPACE: // same as AppleWin
case RETROK_LEFT:
{
ch = 0x08;
break;
}
case RETROK_RIGHT:
{
ch = 0x15;
break;
}
case RETROK_UP:
{
ch = 0x0b;
break;
}
case RETROK_DOWN:
{
ch = 0x0a;
break;
}
case RETROK_DELETE:
{
ch = 0x7f;
break;
}
case RETROK_ESCAPE:
{
ch = 0x1b;
break;
}
case RETROK_TAB:
{
ch = 0x09;
break;
}
case RETROK_LALT:
{
Paddle::setButtonPressed(Paddle::ourOpenApple);
break;
}
case RETROK_RALT:
{
Paddle::setButtonPressed(Paddle::ourSolidApple);
break;
}
case RETROK_a ... RETROK_z:
{
ch = (keycode - RETROK_a) + 0x01;
if (key_modifiers & RETROKMOD_CTRL)
{
// ok
}
else if (key_modifiers & RETROKMOD_SHIFT)
{
ch += 0x60;
}
else
{
ch += 0x40;
}
break;
}
}
if (!ch)
{
switch (character) {
case 0x20 ... 0x40:
case 0x5b ... 0x60:
case 0x7b ... 0x7e:
{
// not the letters
// this is very simple, but one cannot handle CRTL-key combination.
ch = character;
break;
}
}
}
if (ch)
{
addKeyToBuffer(ch);
// log_cb(RETRO_LOG_INFO, "RA2: %s - %02x\n", __FUNCTION__, ch);
}
}
void Game::processKeyUp(unsigned keycode, uint32_t character, uint16_t key_modifiers)
{
switch (keycode)
{
case RETROK_LALT:
{
Paddle::setButtonReleased(Paddle::ourOpenApple);
break;
}
case RETROK_RALT:
{
Paddle::setButtonReleased(Paddle::ourSolidApple);
break;
}
}
}
bool Game::checkButtonPressed(unsigned id)
{
// pressed if it is down now, but was up before
const int value = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, id);
const bool pressed = (value != 0) && myButtonStates[id] == 0;
// update to avoid multiple fires
myButtonStates[id] = value;
return pressed;
}
void Game::keyboardEmulation()
{
if (ourInputDevices[0] != RETRO_DEVICE_NONE)
{
if (checkButtonPressed(RETRO_DEVICE_ID_JOYPAD_R))
{
myFrame->CycleVideoType();
}
if (checkButtonPressed(RETRO_DEVICE_ID_JOYPAD_L))
{
myFrame->Cycle50ScanLines();
}
if (checkButtonPressed(RETRO_DEVICE_ID_JOYPAD_START))
{
ResetMachineState();
}
}
else
{
std::fill(myButtonStates.begin(), myButtonStates.end(), 0);
}
}
void Game::mouseEmulation()
{
for (auto & mouse : myMouse)
{
const int16_t x = input_state_cb(0, RETRO_DEVICE_MOUSE, 0, mouse.id);
mouse.position += x * mouse.multiplier;
mouse.position = std::min(1.0, std::max(mouse.position, -1.0));
}
}
double Game::getMousePosition(int i) const
{
return myMouse[i].position;
}
bool Game::loadSnapshot(const std::string & path)
{
common2::setSnapshotFilename(path);
myFrame->LoadSnapshot();
return true;
}
DiskControl & Game::getDiskControl()
{
return myDiskControl;
}
}

View file

@ -0,0 +1,70 @@
#pragma once
#include "frontends/common2/speed.h"
#include "frontends/libretro/environment.h"
#include "frontends/libretro/diskcontrol.h"
#include "linux/context.h"
#include <string>
#include <vector>
namespace ra2
{
class RetroFrame;
class Game
{
public:
Game();
~Game();
bool loadSnapshot(const std::string & path);
void executeOneFrame();
void processInputEvents();
void drawVideoBuffer();
double getMousePosition(int i) const;
DiskControl & getDiskControl();
static void keyboardCallback(bool down, unsigned keycode, uint32_t character, uint16_t key_modifiers);
static void frameTimeCallback(retro_usec_t usec);
static constexpr size_t FPS = 60;
static unsigned ourInputDevices[MAX_PADS];
static retro_usec_t ourFrameTime;
private:
// keep them in this order!
std::shared_ptr<LoggerContext> myLoggerContext;
std::shared_ptr<RegistryContext> myRegistryContext;
std::shared_ptr<RetroFrame> myFrame;
common2::Speed mySpeed; // fixed speed
std::vector<int> myButtonStates;
struct MousePosition_t
{
double position; // -1 to 1
double multiplier;
unsigned id;
};
MousePosition_t myMouse[2];
DiskControl myDiskControl;
bool checkButtonPressed(unsigned id);
void keyboardEmulation();
void mouseEmulation();
static void processKeyDown(unsigned keycode, uint32_t character, uint16_t key_modifiers);
static void processKeyUp(unsigned keycode, uint32_t character, uint16_t key_modifiers);
};
}

View file

@ -0,0 +1,33 @@
#include "frontends/libretro/joypad.h"
#include "frontends/libretro/environment.h"
#include "libretro.h"
namespace ra2
{
Joypad::Joypad(unsigned device)
: JoypadBase(device)
, myAxisCodes(2)
{
myAxisCodes[0][RETRO_DEVICE_ID_JOYPAD_LEFT] = -1.0;
myAxisCodes[0][RETRO_DEVICE_ID_JOYPAD_RIGHT] = 1.0;
myAxisCodes[1][RETRO_DEVICE_ID_JOYPAD_UP] = -1.0;
myAxisCodes[1][RETRO_DEVICE_ID_JOYPAD_DOWN] = 1.0;
}
double Joypad::getAxis(int i) const
{
for (const auto & axis : myAxisCodes[i])
{
const int value = input_state_cb(0, myDevice, 0, axis.first);
if (value)
{
return axis.second;
}
}
return 0.0;
}
}

View file

@ -0,0 +1,22 @@
#pragma once
#include "frontends/libretro/joypadbase.h"
#include <vector>
#include <map>
namespace ra2
{
class Joypad : public JoypadBase
{
public:
Joypad(unsigned device);
double getAxis(int i) const override;
private:
std::vector<std::map<unsigned, double> > myAxisCodes;
};
}

View file

@ -0,0 +1,25 @@
#include "frontends/libretro/joypadbase.h"
#include "frontends/libretro/environment.h"
#include "libretro.h"
namespace ra2
{
ControllerBase::ControllerBase(unsigned device, const std::vector<unsigned> & buttonCodes)
: myDevice(device), myButtonCodes(buttonCodes)
{
}
bool ControllerBase::getButton(int i) const
{
const int value = input_state_cb(0, myDevice, 0, myButtonCodes[i]);
return value != 0;
}
JoypadBase::JoypadBase(unsigned device) : ControllerBase(device, {RETRO_DEVICE_ID_JOYPAD_A, RETRO_DEVICE_ID_JOYPAD_B})
{
}
}

View file

@ -0,0 +1,32 @@
#pragma once
#include "linux/paddle.h"
#include <vector>
#include <map>
namespace ra2
{
class ControllerBase : public Paddle
{
public:
ControllerBase(unsigned device, const std::vector<unsigned> & buttonCodes);
bool getButton(int i) const override;
protected:
const unsigned myDevice;
private:
const std::vector<unsigned> myButtonCodes;
};
class JoypadBase : public ControllerBase
{
public:
JoypadBase(unsigned device);
};
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,438 @@
#include "libretro.h"
#include <memory>
#include <cstring>
#include "StdAfx.h"
#include "Common.h"
#include "Video.h"
#include "Interface.h"
#include "Memory.h"
#include "Utilities.h"
#include "Debugger/DebugDefs.h"
#include "linux/version.h"
#include "linux/paddle.h"
#include "frontends/libretro/game.h"
#include "frontends/libretro/environment.h"
#include "frontends/libretro/rdirectsound.h"
#include "frontends/libretro/retroregistry.h"
#include "frontends/libretro/joypad.h"
#include "frontends/libretro/analog.h"
#include "frontends/libretro/mouse.h"
#include "frontends/libretro/serialisation.h"
namespace
{
std::unique_ptr<ra2::Game> ourGame;
bool endsWith(const std::string & value, const std::string & ending)
{
if (ending.size() > value.size())
{
return false;
}
return std::equal(ending.rbegin(), ending.rend(), value.rbegin());
}
bool retro_set_eject_state(bool ejected)
{
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s (%d)\n", __FUNCTION__, ejected);
return ourGame->getDiskControl().setEjectedState(ejected);
}
bool retro_get_eject_state()
{
return ourGame->getDiskControl().getEjectedState();
}
unsigned retro_get_image_index()
{
return ourGame->getDiskControl().getImageIndex();
}
bool retro_set_image_index(unsigned index)
{
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s (%d)\n", __FUNCTION__, index);
return ourGame->getDiskControl().setImageIndex(index);
}
unsigned retro_get_num_images()
{
return ourGame->getDiskControl().getNumImages();
}
bool retro_replace_image_index(unsigned index, const struct retro_game_info *info)
{
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s (%s)\n", __FUNCTION__, info->path);
if (info->path)
{
return ourGame->getDiskControl().replaceImageIndex(index, info->path);
}
else
{
return ourGame->getDiskControl().removeImageIndex(index);
}
}
bool retro_add_image_index()
{
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
return ourGame->getDiskControl().addImageIndex();
}
bool retro_set_initial_image(unsigned index, const char *path)
{
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s (%d) = %s\n", __FUNCTION__, index, path);
ra2::DiskControl::setInitialPath(index, path);
return true;
}
bool retro_get_image_path(unsigned index, char *path, size_t len)
{
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s (%d)\n", __FUNCTION__, index);
return ourGame->getDiskControl().getImagePath(index, path, len);
}
bool retro_get_image_label(unsigned index, char *label, size_t len)
{
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s (%d)\n", __FUNCTION__, index);
return ourGame->getDiskControl().getImageLabel(index, label, len);
}
}
void retro_init(void)
{
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
}
void retro_deinit(void)
{
ourGame.reset();
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
}
unsigned retro_api_version(void)
{
return RETRO_API_VERSION;
}
void retro_set_controller_port_device(unsigned port, unsigned device)
{
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s, Plugging device %u into port %u.\n", __FUNCTION__, device, port);
if (port == 0)
{
ra2::Game::ourInputDevices[port] = device;
switch (device)
{
case RETRO_DEVICE_NONE:
Paddle::instance.reset();
break;
case RETRO_DEVICE_JOYPAD:
Paddle::instance.reset(new ra2::Joypad(device));
Paddle::setSquaring(false);
break;
case RETRO_DEVICE_ANALOG:
Paddle::instance.reset(new ra2::Analog(device));
Paddle::setSquaring(true);
break;
case RETRO_DEVICE_MOUSE:
Paddle::instance.reset(new ra2::Mouse(device, &ourGame));
Paddle::setSquaring(false);
break;
default:
break;
}
}
}
void retro_get_system_info(retro_system_info *info)
{
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
static std::string version = getVersion();
memset(info, 0, sizeof(*info));
info->library_name = "AppleWin";
info->library_version = version.c_str();
info->need_fullpath = true;
info->valid_extensions = "bin|do|dsk|nib|po|gz|woz|zip|2mg|2img|iie|apl|hdv|yaml|m3u";
}
void retro_get_system_av_info(retro_system_av_info *info)
{
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
Video & video = GetVideo();
info->geometry.base_width = video.GetFrameBufferBorderlessWidth();
info->geometry.base_height = video.GetFrameBufferBorderlessHeight();
info->geometry.max_width = video.GetFrameBufferBorderlessWidth();
info->geometry.max_height = video.GetFrameBufferBorderlessHeight();
info->geometry.aspect_ratio = 0;
info->timing.fps = ra2::Game::FPS;
info->timing.sample_rate = SPKR_SAMPLE_RATE;
}
void retro_set_environment(retro_environment_t cb)
{
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
ra2::environ_cb = cb;
if (cb(RETRO_ENVIRONMENT_GET_LOG_INTERFACE, &ra2::logging))
ra2::log_cb = ra2::logging.log;
else
ra2::log_cb = ra2::fallback_log;
static const struct retro_controller_description controllers[] =
{
{ "Standard Joypad", RETRO_DEVICE_JOYPAD },
{ "Analog Joypad", RETRO_DEVICE_ANALOG },
{ "Mouse", RETRO_DEVICE_MOUSE },
};
static const struct retro_controller_info ports[] =
{
{ controllers, sizeof(controllers) / sizeof(controllers[0]) },
{ nullptr, 0 }
};
cb(RETRO_ENVIRONMENT_SET_CONTROLLER_INFO, (void*)ports);
retro_keyboard_callback keyboardCallback = {&ra2::Game::keyboardCallback};
cb(RETRO_ENVIRONMENT_SET_KEYBOARD_CALLBACK, &keyboardCallback);
retro_audio_buffer_status_callback audioCallback = {&ra2::bufferStatusCallback};
cb(RETRO_ENVIRONMENT_SET_AUDIO_BUFFER_STATUS_CALLBACK, &audioCallback);
retro_frame_time_callback timeCallback = {&ra2::Game::frameTimeCallback, 1000000 / ra2::Game::FPS};
cb(RETRO_ENVIRONMENT_SET_FRAME_TIME_CALLBACK, &timeCallback);
// see retro_get_memory_data() below
bool achievements = true;
cb(RETRO_ENVIRONMENT_SET_SUPPORT_ACHIEVEMENTS, &achievements);
unsigned dciVersion = 0;
if (cb(RETRO_ENVIRONMENT_GET_DISK_CONTROL_INTERFACE_VERSION, &dciVersion) && (dciVersion >= 1))
{
retro_disk_control_ext_callback diskControlExtCallback = {
&retro_set_eject_state, &retro_get_eject_state,
&retro_get_image_index, &retro_set_image_index,
&retro_get_num_images, &retro_replace_image_index,
&retro_add_image_index, nullptr,
&retro_get_image_path, &retro_get_image_label
};
// intentionally skip retro_set_initial_image
// as we do always want to restart with the first disk of a playlist
// which (normally) is the only bootable floppy of a game
cb(RETRO_ENVIRONMENT_SET_DISK_CONTROL_EXT_INTERFACE, &diskControlExtCallback);
}
else
{
retro_disk_control_callback diskControlCallback = {
&retro_set_eject_state, &retro_get_eject_state,
&retro_get_image_index, &retro_set_image_index,
&retro_get_num_images, &retro_replace_image_index,
&retro_add_image_index
};
cb(RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE, &diskControlCallback);
}
ra2::SetupRetroVariables();
}
void retro_set_audio_sample(retro_audio_sample_t cb)
{
ra2::audio_cb = cb;
}
void retro_set_audio_sample_batch(retro_audio_sample_batch_t cb)
{
ra2::audio_batch_cb = cb;
}
void retro_set_input_poll(retro_input_poll_t cb)
{
ra2::input_poll_cb = cb;
}
void retro_set_input_state(retro_input_state_t cb)
{
ra2::input_state_cb = cb;
}
void retro_set_video_refresh(retro_video_refresh_t cb)
{
ra2::video_cb = cb;
}
void retro_run(void)
{
ourGame->processInputEvents();
ourGame->executeOneFrame();
GetFrame().VideoPresentScreen();
const size_t ms = (1000 + 60 - 1) / 60; // round up
ra2::writeAudio(ms);
}
bool retro_load_game(const retro_game_info *info)
{
ourGame.reset();
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
enum retro_pixel_format fmt = RETRO_PIXEL_FORMAT_XRGB8888;
if (!ra2::environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &fmt))
{
ra2::log_cb(RETRO_LOG_INFO, "XRGB8888 is not supported.\n");
return false;
}
try
{
std::unique_ptr<ra2::Game> game(new ra2::Game());
const std::string snapshotEnding = ".aws.yaml";
const std::string playlistEnding = ".m3u";
bool ok;
if (info->path && *info->path)
{
const std::string gamePath = info->path;
if (endsWith(gamePath, snapshotEnding))
{
ok = game->loadSnapshot(gamePath);
}
else if (endsWith(gamePath, playlistEnding))
{
ok = game->getDiskControl().insertPlaylist(gamePath);
}
else
{
ok = game->getDiskControl().insertDisk(gamePath);
}
}
else
{
ok = false;
}
ra2::log_cb(RETRO_LOG_INFO, "Game path: %s -> %d\n", info->path, ok);
if (ok)
{
ra2::display_message("Enable Game Focus Mode for better keyboard handling");
std::swap(ourGame, game);
}
return ok;
}
catch (const std::exception & e)
{
ra2::log_cb(RETRO_LOG_INFO, "Exception: %s\n", e.what());
}
return false;
}
void retro_unload_game(void)
{
ourGame.reset();
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
}
unsigned retro_get_region(void)
{
return RETRO_REGION_NTSC;
}
void retro_reset(void)
{
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
ResetMachineState();
}
bool retro_load_game_special(unsigned type, const struct retro_game_info *info, size_t num)
{
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
return false;
}
size_t retro_serialize_size(void)
{
try
{
const size_t size = ra2::RetroSerialisation::getSize();
return size;
}
catch(const std::exception& e)
{
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s - %s\n", __FUNCTION__, e.what());
return 0;
}
}
bool retro_serialize(void *data, size_t size)
{
try
{
ra2::RetroSerialisation::serialise(data, size, ourGame->getDiskControl());
return true;
}
catch(const std::exception& e)
{
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s - %s\n", __FUNCTION__, e.what());
return false;
}
}
bool retro_unserialize(const void *data, size_t size)
{
try
{
ra2::RetroSerialisation::deserialise(data, size, ourGame->getDiskControl());
return true;
}
catch(const std::exception& e)
{
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s - %s\n", __FUNCTION__, e.what());
return false;
}
}
void retro_cheat_reset(void)
{
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
}
void retro_cheat_set(unsigned index, bool enabled, const char *code)
{
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__);
}
void *retro_get_memory_data(unsigned id)
{
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s (%d)\n", __FUNCTION__, id);
switch (id & RETRO_MEMORY_MASK)
{
case RETRO_MEMORY_SYSTEM_RAM:
return MemGetBankPtr(0);
default:
return nullptr;
};
}
size_t retro_get_memory_size(unsigned id)
{
ra2::log_cb(RETRO_LOG_INFO, "RA2: %s (%d)\n", __FUNCTION__, id);
switch (id & RETRO_MEMORY_MASK)
{
case RETRO_MEMORY_SYSTEM_RAM:
return _6502_MEM_LEN;
default:
return 0;
};
}

View file

@ -0,0 +1,21 @@
#include "frontends/libretro/mouse.h"
#include "frontends/libretro/environment.h"
#include "frontends/libretro/game.h"
#include "libretro.h"
namespace ra2
{
Mouse::Mouse(unsigned device, const std::unique_ptr<Game> * game)
: ControllerBase(device, {RETRO_DEVICE_ID_MOUSE_LEFT, RETRO_DEVICE_ID_MOUSE_RIGHT})
, myGame(game)
{
}
double Mouse::getAxis(int i) const
{
return *myGame ? (*myGame)->getMousePosition(i) : 0.0;
}
}

View file

@ -0,0 +1,23 @@
#pragma once
#include "frontends/libretro/joypadbase.h"
#include <memory>
namespace ra2
{
class Game;
class Mouse : public ControllerBase
{
public:
Mouse(unsigned device, const std::unique_ptr<Game> * game);
double getAxis(int i) const override;
private:
const std::unique_ptr<Game> * myGame;
};
}

View file

@ -0,0 +1,206 @@
#include "frontends/libretro/rdirectsound.h"
#include "frontends/libretro/environment.h"
#include "windows.h"
#include "linux/linuxinterface.h"
#include <unordered_map>
#include <memory>
#include <iostream>
#include <iomanip>
#include <cmath>
namespace
{
// we can only run 1 generator at a time
// 1 is for speaker (2 would be Mockingboard)
const size_t ourChannels = 1;
class DirectSoundGenerator
{
public:
DirectSoundGenerator(IDirectSoundBuffer * buffer);
void writeAudio(const size_t ms);
void playSilence(const size_t ms);
bool isRunning() const;
size_t getNumberOfChannels() const;
private:
IDirectSoundBuffer * myBuffer;
std::vector<int16_t> myMixerBuffer;
size_t myBytesPerSecond;
void mixBuffer(const void * ptr, const size_t size);
};
std::unordered_map<IDirectSoundBuffer *, std::shared_ptr<DirectSoundGenerator>> activeSoundGenerators;
std::shared_ptr<DirectSoundGenerator> findRunningGenerator(const size_t channels)
{
for (auto & it : activeSoundGenerators)
{
const std::shared_ptr<DirectSoundGenerator> & generator = it.second;
if (generator->isRunning() && generator->getNumberOfChannels() == channels)
{
return generator;
}
}
return std::shared_ptr<DirectSoundGenerator>();
}
DirectSoundGenerator::DirectSoundGenerator(IDirectSoundBuffer * buffer)
: myBuffer(buffer)
{
myBytesPerSecond = myBuffer->channels * myBuffer->sampleRate * sizeof(int16_t);
}
bool DirectSoundGenerator::isRunning() const
{
DWORD dwStatus;
myBuffer->GetStatus(&dwStatus);
if (dwStatus & DSBSTATUS_PLAYING)
{
return true;
}
else
{
return false;
}
}
size_t DirectSoundGenerator::getNumberOfChannels() const
{
return myBuffer->channels;
}
void DirectSoundGenerator::mixBuffer(const void * ptr, const size_t size)
{
const int16_t frames = size / (sizeof(int16_t) * myBuffer->channels);
const int16_t * data = static_cast<const int16_t *>(ptr);
if (myBuffer->channels == 2)
{
myMixerBuffer.assign(data, data + frames * myBuffer->channels);
}
else
{
myMixerBuffer.resize(2 * frames);
for (int16_t i = 0; i < frames; ++i)
{
myMixerBuffer[i * 2] = data[i];
myMixerBuffer[i * 2 + 1] = data[i];
}
}
const double logVolume = myBuffer->GetLogarithmicVolume();
// same formula as QAudio::convertVolume()
const double linVolume = logVolume > 0.99 ? 1.0 : -std::log(1.0 - logVolume) / std::log(100.0);
const int16_t rvolume = int16_t(linVolume * 128);
for (int16_t & sample : myMixerBuffer)
{
sample = (sample * rvolume) / 128;
}
ra2::audio_batch_cb(myMixerBuffer.data(), frames);
}
void DirectSoundGenerator::playSilence(const size_t ms)
{
if (!isRunning())
{
return;
}
const size_t frames = ms * myBuffer->sampleRate / 1000;
myMixerBuffer.resize(2 * frames);
std::fill(myMixerBuffer.begin(), myMixerBuffer.end(), 0);
ra2::audio_batch_cb(myMixerBuffer.data(), frames);
}
void DirectSoundGenerator::writeAudio(const size_t ms)
{
// this is autostart as we only do for the palying buffers
// and AW might activate one later
if (!isRunning())
{
return;
}
const size_t frames = ms * myBuffer->sampleRate / 1000;
const size_t bytesToRead = frames * myBuffer->channels * sizeof(int16_t);
LPVOID lpvAudioPtr1, lpvAudioPtr2;
DWORD dwAudioBytes1, dwAudioBytes2;
myBuffer->Read(bytesToRead, &lpvAudioPtr1, &dwAudioBytes1, &lpvAudioPtr2, &dwAudioBytes2);
if (lpvAudioPtr1 && dwAudioBytes1)
{
mixBuffer(lpvAudioPtr1, dwAudioBytes1);
}
if (lpvAudioPtr2 && dwAudioBytes2)
{
mixBuffer(lpvAudioPtr2, dwAudioBytes2);
}
}
}
void registerSoundBuffer(IDirectSoundBuffer * buffer)
{
const std::shared_ptr<DirectSoundGenerator> generator = std::make_shared<DirectSoundGenerator>(buffer);
activeSoundGenerators[buffer] = generator;
}
void unregisterSoundBuffer(IDirectSoundBuffer * buffer)
{
const auto it = activeSoundGenerators.find(buffer);
if (it != activeSoundGenerators.end())
{
activeSoundGenerators.erase(it);
}
}
namespace ra2
{
void writeAudio(const size_t ms)
{
const auto generator = findRunningGenerator(ourChannels);
if (generator)
{
generator->writeAudio(ms);
}
}
void playSilence(const size_t ms)
{
const auto generator = findRunningGenerator(ourChannels);
if (generator)
{
generator->playSilence(ms);
}
}
void bufferStatusCallback(bool active, unsigned occupancy, bool underrun_likely)
{
if (active)
{
// I am not sure this is any useful
static unsigned lastOccupancy = 0;
const int diff = std::abs(int(lastOccupancy) - int(occupancy));
if (diff >= 5)
{
// this is very verbose
// log_cb(RETRO_LOG_INFO, "RA2: %s occupancy = %d, underrun_likely = %d\n", __FUNCTION__, occupancy, underrun_likely);
lastOccupancy = occupancy;
}
}
}
}

View file

@ -0,0 +1,9 @@
#pragma once
#include <cstdlib>
namespace ra2
{
void writeAudio(const size_t ms);
void bufferStatusCallback(bool active, unsigned occupancy, bool underrun_likely);
}

View file

@ -0,0 +1,182 @@
#include "StdAfx.h"
#include "frontends/libretro/retroframe.h"
#include "frontends/libretro/environment.h"
#include "Interface.h"
#include "Core.h"
#include "Utilities.h"
#include <fstream>
namespace
{
void readFileToBuffer(const std::string & filename, std::vector<char> & buffer)
{
std::ifstream file(filename.c_str(), std::ios::binary | std::ios::ate);
const std::streamsize size = file.tellg();
file.seekg(0, std::ios::beg);
buffer.resize(size);
file.read(buffer.data(), size);
}
template<typename T>
T getAs(const std::vector<char> & buffer, const size_t offset)
{
if (offset + sizeof(T) > buffer.size())
{
throw std::runtime_error("Invalid bitmap");
}
const T * ptr = reinterpret_cast<const T *>(buffer.data() + offset);
return * ptr;
}
// libretro cannot parse BMP with 1 bpp
// simple version implemented here
bool getBitmapData(const std::vector<char> & buffer, int32_t & width, int32_t & height, uint16_t & bpp, const char * & data, uint32_t & size)
{
if (buffer.size() < 2)
{
return false;
}
if (buffer[0] != 0x42 || buffer[1] != 0x4D)
{
return false;
}
const uint32_t fileSize = getAs<uint32_t>(buffer, 2);
if (fileSize != buffer.size())
{
return false;
}
const uint32_t offset = getAs<uint32_t>(buffer, 10);
const uint32_t header = getAs<uint32_t>(buffer, 14);
if (header != 40)
{
return false;
}
width = getAs<int32_t>(buffer, 18);
height = getAs<int32_t>(buffer, 22);
bpp = getAs<uint16_t>(buffer, 28);
const uint32_t imageSize = getAs<uint32_t>(buffer, 34);
if (offset + imageSize > fileSize)
{
return false;
}
data = buffer.data() + offset;
size = imageSize;
return true;
}
}
namespace ra2
{
RetroFrame::RetroFrame()
{
}
void RetroFrame::FrameRefreshStatus(int drawflags)
{
if (drawflags & DRAW_TITLE)
{
GetAppleWindowTitle();
display_message(g_pAppTitle.c_str());
}
}
void RetroFrame::VideoPresentScreen()
{
// this should not be necessary
// either libretro handles it
// or we should change AW
// but for now, there is no alternative
for (size_t row = 0; row < myHeight; ++row)
{
const uint8_t * src = myFrameBuffer + row * myPitch;
uint8_t * dst = myVideoBuffer.data() + (myHeight - row - 1) * myPitch;
memcpy(dst, src, myPitch);
}
video_cb(myVideoBuffer.data() + myOffset, myBorderlessWidth, myBorderlessHeight, myPitch);
}
void RetroFrame::Initialize(bool resetVideoState)
{
CommonFrame::Initialize(resetVideoState);
FrameRefreshStatus(DRAW_TITLE);
Video & video = GetVideo();
myBorderlessWidth = video.GetFrameBufferBorderlessWidth();
myBorderlessHeight = video.GetFrameBufferBorderlessHeight();
const size_t borderWidth = video.GetFrameBufferBorderWidth();
const size_t borderHeight = video.GetFrameBufferBorderHeight();
const size_t width = video.GetFrameBufferWidth();
myHeight = video.GetFrameBufferHeight();
myFrameBuffer = video.GetFrameBuffer();
myPitch = width * sizeof(bgra_t);
myOffset = (width * borderHeight + borderWidth) * sizeof(bgra_t);
const size_t size = myHeight * myPitch;
myVideoBuffer.resize(size);
}
void RetroFrame::Destroy()
{
CommonFrame::Destroy();
myFrameBuffer = nullptr;
myVideoBuffer.clear();
}
void RetroFrame::GetBitmap(LPCSTR lpBitmapName, LONG cb, LPVOID lpvBits)
{
const std::string filename = getBitmapFilename(lpBitmapName);
const std::string path = getResourcePath(filename);
std::vector<char> buffer;
readFileToBuffer(path, buffer);
if (!buffer.empty())
{
int32_t width, height;
uint16_t bpp;
const char * data;
uint32_t size;
const bool res = getBitmapData(buffer, width, height, bpp, data, size);
log_cb(RETRO_LOG_INFO, "RA2: %s. %s = %dx%d, %dbpp\n", __FUNCTION__, path.c_str(),
width, height, bpp);
if (res && height > 0 && size <= cb)
{
const size_t length = size / height;
// rows are stored upside down
char * out = static_cast<char *>(lpvBits);
for (size_t row = 0; row < height; ++row)
{
const char * src = data + row * length;
char * dst = out + (height - row - 1) * length;
memcpy(dst, src, length);
}
return;
}
}
CommonFrame::GetBitmap(lpBitmapName, cb, lpvBits);
}
int RetroFrame::FrameMessageBox(LPCSTR lpText, LPCSTR lpCaption, UINT uType)
{
log_cb(RETRO_LOG_INFO, "RA2: %s: %s - %s\n", __FUNCTION__, lpCaption, lpText);
return IDOK;
}
}

View file

@ -0,0 +1,35 @@
#pragma once
#include "frontends/common2/commonframe.h"
#include "frontends/common2/gnuframe.h"
#include <memory>
#include <vector>
namespace ra2
{
class RetroFrame : public virtual common2::CommonFrame, public common2::GNUFrame
{
public:
RetroFrame();
void VideoPresentScreen() override;
void FrameRefreshStatus(int drawflags) override;
void Initialize(bool resetVideoState) override;
void Destroy() override;
int FrameMessageBox(LPCSTR lpText, LPCSTR lpCaption, UINT uType) override;
void GetBitmap(LPCSTR lpBitmapName, LONG cb, LPVOID lpvBits) override;
private:
std::vector<uint8_t> myVideoBuffer;
size_t myPitch;
size_t myOffset;
size_t myHeight;
size_t myBorderlessWidth;
size_t myBorderlessHeight;
uint8_t* myFrameBuffer;
};
}

View file

@ -0,0 +1,174 @@
#include "StdAfx.h"
#include "frontends/common2/ptreeregistry.h"
#include "frontends/libretro/environment.h"
#include "Common.h"
#include "Card.h"
#include "Video.h"
#include "libretro.h"
#include <list>
#include <vector>
#include <sstream>
namespace
{
const std::string ourScope = "applewin_";
struct Variable
{
std::string name;
std::string description;
std::string section;
std::string key;
std::vector<std::pair<std::string, DWORD> > values;
};
const std::vector<Variable> ourVariables =
{
{
"machine",
"Apple ][ type",
REG_CONFIG,
REGVALUE_APPLE2_TYPE,
{
{"Enhanced Apple //e", A2TYPE_APPLE2EENHANCED},
{"Apple ][ (Original)", A2TYPE_APPLE2},
{"Apple ][+", A2TYPE_APPLE2PLUS},
{"Apple ][ J-Plus", A2TYPE_APPLE2JPLUS},
{"Apple //e", A2TYPE_APPLE2E},
{"Pravets 82", A2TYPE_PRAVETS82},
{"Pravets 8M", A2TYPE_PRAVETS8M},
{"Pravets 8A", A2TYPE_PRAVETS8A},
{"Base64A", A2TYPE_BASE64A},
{"TK3000 //e", A2TYPE_TK30002E},
}
},
{
"slot3",
"Card in slot 3",
"Configuration\\Slot 3",
REGVALUE_CARD_TYPE,
{
{"Empty", CT_Empty},
{"Video HD", CT_VidHD},
}
},
{
"slot4",
"Card in slot 4",
"Configuration\\Slot 4",
REGVALUE_CARD_TYPE,
{
{"Empty", CT_Empty},
{"Mouse", CT_MouseInterface},
{"Mockingboard", CT_MockingboardC},
{"Phasor", CT_Phasor},
}
},
{
"slot5",
"Card in slot 5",
"Configuration\\Slot 5",
REGVALUE_CARD_TYPE,
{
{"Empty", CT_Empty},
{"CP/M", CT_Z80},
{"Mockingboard", CT_MockingboardC},
{"SAM/DAC", CT_SAM},
}
},
{
"video",
"Video mode",
REG_CONFIG,
REGVALUE_VIDEO_MODE,
{
{"Color (Composite Idealized)", VT_COLOR_IDEALIZED},
{"Color (RGB Card/Monitor)", VT_COLOR_VIDEOCARD_RGB},
{"Color (Composite Monitor)", VT_COLOR_MONITOR_NTSC},
{"Color TV", VT_COLOR_TV},
{"B&W TV", VT_MONO_TV},
{"Monochrome (Amber)", VT_MONO_AMBER},
{"Monochrome (Green)", VT_MONO_GREEN},
{"Monochrome (White)", VT_MONO_WHITE},
}
},
};
std::string getKey(const Variable & var)
{
std::ostringstream ss;
ss << var.description << "; ";
for (size_t i = 0; i < var.values.size(); ++i)
{
if (i > 0)
{
ss << "|";
}
ss << var.values[i].first;
}
return ss.str();
}
}
namespace ra2
{
void SetupRetroVariables()
{
const size_t numberOfVariables = ourVariables.size();
std::vector<retro_variable> retroVariables(numberOfVariables + 1);
std::list<std::string> workspace; // so objects do not move when it resized
// we need to keep the char * alive till after the call to RETRO_ENVIRONMENT_SET_VARIABLES
const auto c_str = [&workspace] (const auto & s)
{
workspace.push_back(s);
return workspace.back().c_str();
};
for (size_t i = 0; i < numberOfVariables; ++i)
{
const Variable & variable = ourVariables[i];
retro_variable & retroVariable = retroVariables[i];
retroVariable.key = c_str(ourScope + variable.name);
retroVariable.value = c_str(getKey(variable));
}
environ_cb(RETRO_ENVIRONMENT_SET_VARIABLES, retroVariables.data());
}
std::shared_ptr<Registry> CreateRetroRegistry()
{
const auto registry = std::make_shared<common2::PTreeRegistry>();
for (const Variable & variable : ourVariables)
{
const std::string retroKey = ourScope + variable.name;
retro_variable retroVariable;
retroVariable.key = retroKey.c_str();
retroVariable.value = nullptr;
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &retroVariable) && retroVariable.value)
{
const std::string value(retroVariable.value);
const auto check = [&value] (const auto & x)
{
return x.first == value;
};
const auto it = std::find_if(variable.values.begin(), variable.values.end(), check);
if (it != variable.values.end())
{
registry->putDWord(variable.section, variable.key, it->second);
}
}
}
return registry;
}
}

View file

@ -0,0 +1,13 @@
#pragma once
#include <memory>
class Registry;
namespace ra2
{
void SetupRetroVariables();
std::shared_ptr<Registry> CreateRetroRegistry();
}

View file

@ -0,0 +1 @@
retroarch -L source/frontends/retro/libra2.so ../Disks/NoSlotClockTest.dsk

View file

@ -0,0 +1,114 @@
#include "StdAfx.h"
#include "SaveState.h"
#include "frontends/libretro/serialisation.h"
#include "frontends/libretro/environment.h"
#include "frontends/libretro/diskcontrol.h"
#include <cstdio>
#include <fstream>
namespace
{
class AutoFile
{
public:
AutoFile();
~AutoFile();
const std::string & getFilename() const; // only if true
protected:
std::string myFilename;
};
AutoFile::AutoFile()
{
// massive race condition, but without changes to AW, little can we do here
const char * tmp = std::tmpnam(nullptr);
if (!tmp)
{
throw std::runtime_error("Cannot create temporary file");
}
myFilename = tmp;
}
AutoFile::~AutoFile()
{
std::remove(myFilename.c_str());
}
const std::string & AutoFile::getFilename() const
{
return myFilename;
}
void saveToFile(const std::string & filename) // cannot be null!
{
Snapshot_SetFilename(filename);
Snapshot_SaveState();
}
}
namespace ra2
{
size_t RetroSerialisation::getSize()
{
AutoFile autoFile;
std::string const & filename = autoFile.getFilename();
saveToFile(filename);
std::ifstream ifs(filename, std::ios::binary | std::ios::ate);
const size_t fileSize = ifs.tellg();
// we add a buffer to include a few things
// DiscControl images
// various sizes
// small variations in AW yaml format
const size_t buffer = 4096;
return fileSize + buffer;
}
void RetroSerialisation::serialise(void * data, size_t size, const DiskControl & diskControl)
{
Buffer buffer(reinterpret_cast<char *>(data), size);
diskControl.serialise(buffer);
AutoFile autoFile;
std::string const & filename = autoFile.getFilename();
saveToFile(filename);
std::ifstream ifs(filename, std::ios::binary | std::ios::ate);
size_t const fileSize = ifs.tellg();
buffer.get<size_t>() = fileSize;
char * begin, * end;
buffer.get(fileSize, begin, end);
ifs.seekg(0, std::ios::beg);
ifs.read(begin, end - begin);
}
void RetroSerialisation::deserialise(const void * data, size_t size, DiskControl & diskControl)
{
Buffer buffer(reinterpret_cast<const char *>(data), size);
diskControl.deserialise(buffer);
const size_t fileSize = buffer.get<size_t const>();
AutoFile autoFile;
std::string const & filename = autoFile.getFilename();
// do not remove the {} scope below! it ensures the file is flushed
{
char const * begin, * end;
buffer.get(fileSize, begin, end);
std::ofstream ofs(filename, std::ios::binary);
ofs.write(begin, end - begin);
}
Snapshot_SetFilename(filename);
Snapshot_LoadState();
}
}

View file

@ -0,0 +1,16 @@
#include <cstddef>
namespace ra2
{
class DiskControl;
class RetroSerialisation
{
public:
static size_t getSize();
static void serialise(void * data, size_t size, const DiskControl & diskControl);
static void deserialise(const void * data, size_t size, DiskControl & diskControl);
};
}

View file

@ -0,0 +1,54 @@
include(FindPkgConfig)
include(FindCurses)
set(SOURCE_FILES
main.cpp
world.cpp
colors.cpp
evdevpaddle.cpp
nframe.cpp
asciiart.cpp
)
set(HEADER_FILES
world.h
colors.h
evdevpaddle.h
nframe.h
asciiart.h
)
add_executable(applen
${SOURCE_FILES}
${HEADER_FILES}
)
find_package(Curses REQUIRED)
# pkg_search_module(NCURSESW REQUIRED ncursesw)
pkg_search_module(LIBEVDEV REQUIRED libevdev)
target_include_directories(applen PRIVATE
${CURSES_INCLUDE_DIRS}
${LIBEVDEV_INCLUDE_DIRS}
${Boost_INCLUDE_DIRS}
)
target_compile_options(applen PRIVATE
${CURSES_CFLAGS}
${LIBEVDEV_CFLAGS_OTHER}
)
target_link_libraries(applen PRIVATE
${CURSES_LIBRARIES}
${LIBEVDEV_LIBRARIES}
appleii
common2
)
target_link_directories(applen PRIVATE
${NCURSESW_LIBRARY_DIRS}
${LIBEVDEV_LIBRARY_DIRS}
)
install(TARGETS applen
DESTINATION bin)

View file

@ -0,0 +1,231 @@
#include "frontends/ncurses/asciiart.h"
#include <cfloat>
#include <memory>
namespace na2
{
ASCIIArt::Unicode::Unicode(const char * aC, Blocks aValues)
: c(aC), values(aValues)
{
}
const int ASCIIArt::PPQ = 8 * (2 * 7) / 4;
ASCIIArt::ASCIIArt() : myRows(0), myColumns(0)
{
myGlyphs.push_back(Unicode("\u2580", {PPQ, PPQ, 0, 0})); // top half
myGlyphs.push_back(Unicode("\u258C", {PPQ, 0, PPQ, 0})); // left half
myGlyphs.push_back(Unicode("\u2596", { 0, 0, PPQ, 0})); // lower left
myGlyphs.push_back(Unicode("\u2597", { 0, 0, 0, PPQ})); // lower right
myGlyphs.push_back(Unicode("\u2598", {PPQ, 0, 0, 0})); // top left
myGlyphs.push_back(Unicode("\u259A", {PPQ, 0, 0, PPQ})); // diagonal
myGlyphs.push_back(Unicode("\u259D", { 0, PPQ, 0, 0})); // top right
myBlocks.resize(128);
init(1, 1); // normal size
}
void ASCIIArt::init(const int rows, const int columns)
{
if (myRows != rows || myColumns != columns)
{
if (myColumns != columns)
{
myColumns = columns;
for (size_t i = 0; i < myBlocks.size(); ++i)
{
myBlocks[i] = decodeByte(i);
}
}
myRows = rows;
myValues.resize(boost::extents[myRows][myColumns]);
myChars.resize(boost::extents[rows][columns]);
}
}
void ASCIIArt::changeColumns(const int x)
{
int newColumns = myColumns + x;
newColumns = std::max(1, std::min(7, newColumns));
init(myRows, newColumns);
}
void ASCIIArt::changeRows(const int x)
{
int newRows = x > 0 ? myRows * 2 : myRows / 2;
newRows = std::max(1, std::min(4, newRows));
init(newRows, myColumns);
}
const ASCIIArt::array_char_t & ASCIIArt::getCharacters(const unsigned char * address)
{
const array_val_t & values = getQuadrantValues(address);
return getCharacters(values);
}
const ASCIIArt::array_val_t & ASCIIArt::getQuadrantValues(const unsigned char * address) const
{
std::fill(myValues.origin(), myValues.origin() + myValues.num_elements(), 0);
const int linesPerRow = 8 / myRows;
const int linesPerQuadrant = linesPerRow / 2;
// 8 lines per text character
for (size_t i = 0; i < 8; ++i)
{
const int offset = 0x0400 * i;
// group color bit is ignored
const unsigned char value = (*(address + offset)) & 0x7f;
const int row = i / linesPerRow;
const int lineInRow = i % linesPerRow;
const int quadrant = lineInRow / linesPerQuadrant;
const int base = quadrant * 2;
const std::vector<Blocks> & decoded = myBlocks[value];
for (size_t col = 0; col < myColumns; ++col)
{
Blocks & blocks = myValues[row][col];
blocks.add(base + 0, decoded[col][0] * myRows);
blocks.add(base + 1, decoded[col][1] * myRows);
}
}
return myValues;
}
std::vector<Blocks> ASCIIArt::decodeByte(const unsigned char value) const
{
const int each = myColumns * 4 * PPQ / (8 * 7);
int available = 7;
int col = 0;
int pos = 0; // left right
std::vector<Blocks> decoded(myColumns);
for (size_t j = 0; j < 7; ++j)
{
int to_allocate = each;
do
{
const int here = std::min(available, to_allocate);
if (value & (1 << j))
{
decoded[col].add(pos, here);
}
to_allocate -= here;
available -= here;
if (available == 0)
{
// new quadrant
available = 7;
++pos;
if (pos == 2)
{
pos = 0;
++col;
}
}
}
while (to_allocate > 0);
}
return decoded;
}
const ASCIIArt::array_char_t & ASCIIArt::getCharacters(const array_val_t & values)
{
const int rows = values.shape()[0];
const int columns = values.shape()[1];
for (size_t i = 0; i < rows; ++i)
{
for (size_t j = 0; j < columns; ++j)
{
myChars[i][j] = getCharacter(values[i][j]);
}
}
return myChars;
}
const ASCIIArt::Character & ASCIIArt::getCharacter(const Blocks & values)
{
const int zip = values.value;
const std::unordered_map<int, Character>::const_iterator it = myAsciiPixels.find(zip);
if (it == myAsciiPixels.end())
{
Character & best = myAsciiPixels[zip];
best.error = DBL_MAX;
for (const Unicode & glyph: myGlyphs)
{
double foreground;
double background;
double error;
fit(values, glyph, foreground, background, error);
if (error < best.error)
{
best.error = error;
best.foreground = foreground;
best.background = background;
best.c = glyph.c;
}
}
return best;
}
else
{
return it->second;
}
}
void ASCIIArt::fit(const Blocks & art, const Unicode & glyph,
double & foreground, double & background, double & error)
{
int num_fg = 0;
int num_bg = 0;
int den_fg = 0;
int den_bg = 0;
for (size_t i = 0; i < art.size(); ++i)
{
const double f = glyph.values[i];
const double b = PPQ - f;
num_fg += art[i] * f;
den_fg += f * f;
num_bg += art[i] * b;
den_bg += b * b;
}
// close formula to minimise the L2 norm of the difference
// of grey intensity
foreground = double(num_fg) / double(den_fg);
background = double(num_bg) / double(den_bg);
error = 0.0;
for (size_t i = 0; i < art.size(); ++i)
{
const double f = glyph.values[i];
const double b = PPQ - f;
const double g = foreground * f + background * b;
const double e = art[i] - g;
error += e * e;
}
}
}

View file

@ -0,0 +1,106 @@
#pragma once
#include <unordered_map>
#include <vector>
#include <initializer_list>
#include <boost/multi_array.hpp>
namespace na2
{
struct Blocks
{
Blocks() : value(0) { }
Blocks(std::initializer_list<int> q)
{
value = 0;
for (auto it = rbegin(q); it != rend(q); ++it)
{
value <<= 5;
value += *it;
}
}
void add(int i, int val)
{
value += val << (i * 5);
}
int operator[](int i) const
{
const int val = (value >> (i * 5)) & 0b11111;
return val;
}
Blocks & operator=(const int val)
{
value = val;
return *this;
}
size_t size() const
{
return 4;
}
int value;
};
class ASCIIArt
{
public:
ASCIIArt();
struct Character
{
const char * c;
double foreground;
double background;
double error;
};
typedef boost::multi_array<Character, 2> array_char_t;
typedef boost::multi_array<Blocks, 2> array_val_t;
void init(const int rows, const int columns);
void changeColumns(const int x);
void changeRows(const int x);
const array_char_t & getCharacters(const unsigned char * address);
const array_char_t & getCharacters(const array_val_t & values);
const array_val_t & getQuadrantValues(const unsigned char * address) const;
std::vector<Blocks> decodeByte(const unsigned char value) const;
private:
static const int PPQ; // Pixels per Quadrant
std::unordered_map<int, Character> myAsciiPixels;
struct Unicode
{
Unicode(const char * aC, Blocks aValues);
const char * c;
Blocks values; // foreground: top left - top right - bottom left - bottom right
};
int myRows;
int myColumns;
std::vector<Unicode> myGlyphs;
std::vector<std::vector<Blocks>> myBlocks;
mutable array_val_t myValues; // workspace
array_char_t myChars; // workspace
const Character & getCharacter(const Blocks & values);
static void fit(const Blocks & art, const Unicode & glyph,
double & foreground, double & background, double & error);
};
}

View file

@ -0,0 +1,129 @@
#include "frontends/ncurses/colors.h"
#include <ncurses.h>
#include <cmath>
namespace
{
enum Color {
BLACK,
DEEP_RED,
DARK_BLUE,
MAGENTA,
DARK_GREEN,
DARK_GRAY,
BLUE,
LIGHT_BLUE,
BROWN,
ORANGE,
LIGHT_GRAY,
PINK,
GREEN,
YELLOW,
AQUA,
WHITE
};
// input 0..255
// output 0..1000
int scaleRGB(int rgb)
{
return rgb * 1000 / 255;
}
}
#define SETFRAMECOLOR(c, r, g, b) init_color(firstColor + Color::c, scaleRGB(r), scaleRGB(g), scaleRGB(b));
namespace na2
{
GraphicsColors::GraphicsColors(const int firstColor, const int firstPair, const int numberOfGreys)
: myNumberOfGRColors(16), myNumberOfGreys(numberOfGreys)
{
has_colors();
start_color();
can_change_color();
SETFRAMECOLOR(BLACK, 0x00,0x00,0x00); // 0
SETFRAMECOLOR(DEEP_RED, 0x9D,0x09,0x66); // 0xD0,0x00,0x30 -> Linards Tweaked 0x9D,0x09,0x66
SETFRAMECOLOR(DARK_BLUE, 0x00,0x00,0x80); // 4 // not used
SETFRAMECOLOR(MAGENTA, 0xC7,0x34,0xFF); // FD Linards Tweaked 0xFF,0x00,0xFF -> 0xC7,0x34,0xFF
SETFRAMECOLOR(DARK_GREEN, 0x00,0x80,0x00); // 2 // not used
SETFRAMECOLOR(DARK_GRAY, 0x80,0x80,0x80); // F8
SETFRAMECOLOR(BLUE, 0x0D,0xA1,0xFF); // FC Linards Tweaked 0x00,0x00,0xFF -> 0x0D,0xA1,0xFF
SETFRAMECOLOR(LIGHT_BLUE,0xAA,0xAA,0xFF); // 0x60,0xA0,0xFF -> Linards Tweaked 0xAA,0xAA,0xFF
SETFRAMECOLOR(BROWN, 0x55,0x55,0x00); // 0x80,0x50,0x00 -> Linards Tweaked 0x55,0x55,0x00
SETFRAMECOLOR(ORANGE, 0xF2,0x5E,0x00); // 0xFF,0x80,0x00 -> Linards Tweaked 0xF2,0x5E,0x00
SETFRAMECOLOR(LIGHT_GRAY, 0xC0,0xC0,0xC0); // 7 // GR: COLOR=10
SETFRAMECOLOR(PINK, 0xFF,0x89,0xE5); // 0xFF,0x90,0x80 -> Linards Tweaked 0xFF,0x89,0xE5
SETFRAMECOLOR(GREEN, 0x38,0xCB,0x00); // FA Linards Tweaked 0x00,0xFF,0x00 -> 0x38,0xCB,0x00
SETFRAMECOLOR(YELLOW, 0xD5,0xD5,0x1A); // FB Linards Tweaked 0xFF,0xFF,0x00 -> 0xD5,0xD5,0x1A
SETFRAMECOLOR(AQUA, 0x62,0xF6,0x99); // 0x40,0xFF,0x90 -> Linards Tweaked 0x62,0xF6,0x99
SETFRAMECOLOR(WHITE, 0xFF,0xFF,0xFF); // FF
int baseColor = firstColor;
int basePair = firstPair;
myFirstGRPair = basePair;
for (size_t i = 0; i < myNumberOfGRColors; ++i)
{
const int fg = firstColor + i;
for (size_t j = 0; j < myNumberOfGRColors; ++j)
{
const int bg = firstColor + j;
const int pair = myFirstGRPair + i * myNumberOfGRColors + j;
init_pair(pair, fg, bg);
}
}
baseColor += myNumberOfGRColors;
basePair += myNumberOfGRColors * myNumberOfGRColors;
myFirstHGRPair = basePair;
for (size_t i = 0; i < myNumberOfGreys; ++i)
{
const int color = baseColor + i;
const int grey = 1000 * i / (myNumberOfGreys - 1);
init_color(color, grey, grey, grey);
}
for (size_t i = 0; i < myNumberOfGreys; ++i)
{
const int fg = baseColor + i;
for (size_t j = 0; j < myNumberOfGreys; ++j)
{
const int bg = baseColor + j;
const int pair = basePair + i * myNumberOfGreys + j;
init_pair(pair, fg, bg);
}
}
}
int GraphicsColors::getPair(int color) const
{
const int fg = color & 0x0f;
const int bg = color >> 4;
const int pair = myFirstGRPair + fg * myNumberOfGRColors + bg;
return pair;
}
int GraphicsColors::getGrey(double foreground, double background) const
{
const int fg = std::nearbyint((myNumberOfGreys - 1) * foreground);
const int bg = std::nearbyint((myNumberOfGreys - 1) * background);
const int basePair = myFirstHGRPair;
const int pair = basePair + fg * myNumberOfGreys + bg;
return pair;
}
}

View file

@ -0,0 +1,23 @@
#pragma once
namespace na2
{
class GraphicsColors
{
public:
GraphicsColors(const int firstColor, const int firstPair, const int numberOfGreys);
int getPair(int color) const;
int getGrey(double foreground, double background) const;
private:
int myFirstGRPair;
int myFirstHGRPair;
const int myNumberOfGRColors;
const int myNumberOfGreys;
};
}

View file

@ -0,0 +1,112 @@
#include "StdAfx.h"
#include "frontends/ncurses/evdevpaddle.h"
#include <cstring>
#include <fcntl.h>
#include <unistd.h>
#include <libevdev/libevdev.h>
#include "Log.h"
namespace na2
{
EvDevPaddle::EvDevPaddle(const std::string & device)
: myButtonCodes(2), myAxisCodes(2), myAxisMins(2), myAxisMaxs(2)
{
myFD = open(device.c_str(), O_RDONLY | O_NONBLOCK);
if (myFD > 0)
{
libevdev * dev;
int rc = libevdev_new_from_fd(myFD, &dev);
if (rc < 0)
{
LogFileOutput("Input: failed to init libevdev (%s): %s\n", strerror(-rc), device.c_str());
}
else
{
myDev.reset(dev, libevdev_free);
myName = libevdev_get_name(dev);
myButtonCodes[0] = BTN_SOUTH;
myButtonCodes[1] = BTN_EAST;
myAxisCodes[0] = ABS_X;
myAxisCodes[1] = ABS_Y;
for (size_t i = 0; i < myAxisCodes.size(); ++i)
{
myAxisMins[i] = libevdev_get_abs_minimum(dev, myAxisCodes[i]);
myAxisMaxs[i] = libevdev_get_abs_maximum(dev, myAxisCodes[i]);
}
}
}
else
{
LogFileOutput("Input: failed to open device (%s): %s\n", strerror(errno), device.c_str());
}
}
EvDevPaddle::~EvDevPaddle()
{
if (myFD > 0)
{
close(myFD);
}
}
int EvDevPaddle::poll()
{
int counter = 0;
if (!myDev)
{
return counter;
}
input_event ev;
int rc = LIBEVDEV_READ_STATUS_SUCCESS;
do
{
if (rc == LIBEVDEV_READ_STATUS_SYNC)
rc = libevdev_next_event(myDev.get(), LIBEVDEV_READ_FLAG_SYNC, &ev);
else
rc = libevdev_next_event(myDev.get(), LIBEVDEV_READ_FLAG_NORMAL, &ev);
++counter;
} while (rc >= 0);
return counter;
}
const std::string & EvDevPaddle::getName() const
{
return myName;
}
bool EvDevPaddle::getButton(int i) const
{
int value = 0;
if (myDev)
{
int rc = libevdev_fetch_event_value(myDev.get(), EV_KEY, myButtonCodes[i], &value);
}
return value != 0;
}
double EvDevPaddle::getAxis(int i) const
{
if (myDev)
{
int value = 0;
int rc = libevdev_fetch_event_value(myDev.get(), EV_ABS, myAxisCodes[i], &value);
const double axis = 2.0 * (value - myAxisMins[i]) / (myAxisMaxs[i] - myAxisMins[i]) - 1.0;
return axis;
}
else
{
return 0;
}
}
}

View file

@ -0,0 +1,40 @@
#pragma once
#include "linux/paddle.h"
#include <string>
#include <vector>
struct libevdev;
struct input_event;
namespace na2
{
class EvDevPaddle : public Paddle
{
public:
EvDevPaddle(const std::string & device);
~EvDevPaddle();
int poll();
const std::string & getName() const;
bool getButton(int i) const override;
double getAxis(int i) const override;
private:
int myFD;
std::shared_ptr<libevdev> myDev;
void process(const input_event & ev);
std::string myName;
std::vector<unsigned int> myButtonCodes;
std::vector<unsigned int> myAxisCodes;
std::vector<int> myAxisMins;
std::vector<int> myAxisMaxs;
};
}

View file

@ -0,0 +1,192 @@
#include "StdAfx.h"
#include <chrono>
#include <thread>
#include <iostream>
#include <ncurses.h>
#include "Common.h"
#include "CardManager.h"
#include "Core.h"
#include "Log.h"
#include "CPU.h"
#include "NTSC.h"
#include "SaveState.h"
#include "Utilities.h"
#include "Interface.h"
#include "linux/benchmark.h"
#include "linux/paddle.h"
#include "linux/context.h"
#include "frontends/common2/fileregistry.h"
#include "frontends/common2/programoptions.h"
#include "frontends/common2/utils.h"
#include "frontends/ncurses/world.h"
#include "frontends/ncurses/nframe.h"
#include "frontends/ncurses/evdevpaddle.h"
namespace
{
bool ContinueExecution(const common2::EmulatorOptions & options, const std::shared_ptr<na2::NFrame> & frame)
{
const auto start = std::chrono::steady_clock::now();
const double fUsecPerSec = 1.e6;
#if 1
const UINT nExecutionPeriodUsec = 1000000 / 60; // 60 FPS
// const UINT nExecutionPeriodUsec = 100; // 0.1ms
const double fExecutionPeriodClks = g_fCurrentCLK6502 * ((double)nExecutionPeriodUsec / fUsecPerSec);
#else
const double fExecutionPeriodClks = 1800.0;
const UINT nExecutionPeriodUsec = (UINT) (fUsecPerSec * (fExecutionPeriodClks / g_fCurrentCLK6502));
#endif
const DWORD uCyclesToExecute = fExecutionPeriodClks;
const bool bVideoUpdate = options.ntsc;
g_bFullSpeed = !bVideoUpdate;
const DWORD uActualCyclesExecuted = CpuExecute(uCyclesToExecute, bVideoUpdate);
g_dwCyclesThisFrame += uActualCyclesExecuted;
CardManager & cardManager = GetCardMgr();
cardManager.Update(uActualCyclesExecuted);
const int key = ProcessKeyboard(frame);
switch (key)
{
case KEY_F(2):
{
ResetMachineState();
break;
}
case 278: // Shift-F2
{
CtrlReset();
break;
}
case KEY_F(3):
{
return false;
}
case KEY_F(5):
{
CardManager & cardManager = GetCardMgr();
if (cardManager.QuerySlot(SLOT6) == CT_Disk2)
{
dynamic_cast<Disk2InterfaceCard*>(cardManager.GetObj(SLOT6))->DriveSwap();
}
break;
}
case KEY_F(11):
{
Snapshot_SaveState();
break;
}
case KEY_F(12):
{
Snapshot_LoadState();
break;
}
}
frame->ProcessEvDev();
const UINT dwClksPerFrame = NTSC_GetCyclesPerFrame();
if (g_dwCyclesThisFrame >= dwClksPerFrame)
{
g_dwCyclesThisFrame = g_dwCyclesThisFrame % dwClksPerFrame;
if (!options.headless)
{
frame->VideoPresentScreen();
}
}
if (!options.headless)
{
const auto end = std::chrono::steady_clock::now();
const auto diff = end - start;
const long us = std::chrono::duration_cast<std::chrono::microseconds>(diff).count();
const double coeff = exp(-0.000001 * nExecutionPeriodUsec); // 0.36 after 1 second
na2::g_relativeSpeed = na2::g_relativeSpeed * coeff + double(us) / double(nExecutionPeriodUsec) * (1.0 - coeff);
if (!cardManager.GetDisk2CardMgr().IsConditionForFullSpeed())
{
if (us < nExecutionPeriodUsec)
{
const auto duration = std::chrono::microseconds(nExecutionPeriodUsec - us);
std::this_thread::sleep_for(duration);
}
}
return true;
}
else
{
return !na2::g_stop;
}
}
void EnterMessageLoop(const common2::EmulatorOptions & options, const std::shared_ptr<na2::NFrame> & frame)
{
while (ContinueExecution(options, frame))
{
}
}
int run_ncurses(int argc, const char * argv [])
{
common2::EmulatorOptions options;
const bool run = getEmulatorOptions(argc, argv, "ncurses", options);
if (!run)
return 1;
const LoggerContext loggerContext(options.log);
const RegistryContext registryContet(CreateFileRegistry(options));
const std::shared_ptr<na2::EvDevPaddle> paddle(new na2::EvDevPaddle(options.paddleDeviceName));
const std::shared_ptr<na2::NFrame> frame(new na2::NFrame(paddle));
const Initialisation init(frame, paddle);
common2::applyOptions(options);
frame->Begin();
common2::setSnapshotFilename(options.snapshotFilename);
if (options.loadSnapshot)
{
frame->LoadSnapshot();
}
na2::SetCtrlCHandler(options.headless);
if (options.benchmark)
{
const auto redraw = [&frame]() { frame->VideoRedrawScreen(); };
VideoBenchmark(redraw, redraw);
}
else
{
EnterMessageLoop(options, frame);
}
frame->End();
return 0;
}
}
int main(int argc, const char * argv [])
{
try
{
return run_ncurses(argc, argv);
}
catch (const std::exception & e)
{
std::cerr << e.what() << std::endl;
return 1;
}
}

View file

@ -0,0 +1,399 @@
#include "StdAfx.h"
#include "frontends/ncurses/nframe.h"
#include "frontends/ncurses/colors.h"
#include "frontends/ncurses/asciiart.h"
#include "frontends/ncurses/evdevpaddle.h"
#include "Interface.h"
#include "Memory.h"
#include "Log.h"
#include "Core.h"
#include "CardManager.h"
#include "Disk.h"
#include <signal.h>
#include <locale.h>
#include <stdlib.h>
namespace na2
{
struct NCurses
{
NCurses()
{
setlocale(LC_ALL, "");
initscr();
curs_set(0);
noecho();
cbreak();
set_escdelay(0);
// make sure this happens when ncurses is indeed initialised
colors.reset(new GraphicsColors(20, 20, 32));
}
~NCurses()
{
endwin();
colors.reset();
}
std::shared_ptr<GraphicsColors> colors;
};
NFrame::NFrame(const std::shared_ptr<EvDevPaddle> & paddle)
: myPaddle(paddle)
, myRows(-1)
, myColumns(-1)
{
// only initialise if actually used
// so we can run headless
}
void NFrame::Initialize(bool resetVideoState)
{
CommonFrame::Initialize(resetVideoState);
myTextFlashCounter = 0;
myTextFlashState = 0;
myAsciiArt.reset(new ASCIIArt());
}
void NFrame::Destroy()
{
CommonFrame::Destroy();
myTextFlashCounter = 0;
myTextFlashState = 0;
myFrame.reset();
myStatus.reset();
myAsciiArt.reset();
myNCurses.reset();
}
void NFrame::ProcessEvDev()
{
myPaddle->poll();
}
void NFrame::ChangeColumns(const int x)
{
myAsciiArt->changeColumns(x);
}
void NFrame::ChangeRows(const int x)
{
myAsciiArt->changeRows(x);
}
void NFrame::Init(int rows, int columns)
{
if (myRows != rows || myColumns != columns)
{
InitialiseNCurses();
if (columns < myColumns || rows < myRows)
{
werase(myStatus.get());
wrefresh(myStatus.get());
werase(myFrame.get());
wrefresh(myFrame.get());
}
myRows = rows;
myColumns = columns;
const int width = 1 + myColumns + 1;
const int left = (COLS - width) / 2;
myFrame.reset(newwin(1 + myRows + 1, width, 0, left), delwin);
box(myFrame.get(), 0 , 0);
wtimeout(myFrame.get(), 0);
keypad(myFrame.get(), true);
wrefresh(myFrame.get());
myStatus.reset(newwin(8, width, 1 + myRows + 1, left), delwin);
FrameRefreshStatus(DRAW_LEDS | DRAW_BUTTON_DRIVES | DRAW_DISK_STATUS);
}
}
WINDOW * NFrame::GetWindow()
{
return myFrame.get();
}
WINDOW * NFrame::GetStatus()
{
return myStatus.get();
}
void NFrame::InitialiseNCurses()
{
if (!myNCurses)
{
myNCurses.reset(new NCurses());
}
}
void NFrame::VideoPresentScreen()
{
VideoUpdateFlash();
Video & video = GetVideo();
// see NTSC_SetVideoMode in NTSC.cpp
// we shoudl really use g_nTextPage and g_nHiresPage
const int displaypage2 = (video.VideoGetSWPAGE2() && !video.VideoGetSW80STORE()) ? 1 : 0;
myHiresBank1 = MemGetAuxPtr (0x2000 << displaypage2);
myHiresBank0 = MemGetMainPtr(0x2000 << displaypage2);
myTextBank1 = MemGetAuxPtr (0x400 << displaypage2);
myTextBank0 = MemGetMainPtr(0x400 << displaypage2);
typedef bool (NFrame::* VideoUpdateFuncPtr_t)(Video &, int, int, int, int, int);
VideoUpdateFuncPtr_t update = video.VideoGetSWTEXT()
? video.VideoGetSW80COL()
? &NFrame::Update80ColCell
: &NFrame::Update40ColCell
: video.VideoGetSWHIRES()
? (video.VideoGetSWDHIRES() && video.VideoGetSW80COL())
? &NFrame::UpdateDHiResCell
: &NFrame::UpdateHiResCell
: (video.VideoGetSWDHIRES() && video.VideoGetSW80COL())
? &NFrame::UpdateDLoResCell
: &NFrame::UpdateLoResCell;
int y = 0;
int ypixel = 0;
while (y < 20) {
int offset = ((y & 7) << 7) + ((y >> 3) * 40);
int x = 0;
int xpixel = 0;
while (x < 40) {
(this->*update)(video, x, y, xpixel, ypixel, offset + x);
++x;
xpixel += 14;
}
++y;
ypixel += 16;
}
if (video.VideoGetSWMIXED())
update = video.VideoGetSW80COL() ? &NFrame::Update80ColCell
: &NFrame::Update40ColCell;
while (y < 24) {
int offset = ((y & 7) << 7) + ((y >> 3) * 40);
int x = 0;
int xpixel = 0;
while (x < 40) {
(this->*update)(video, x, y, xpixel, ypixel, offset + x);
++x;
xpixel += 14;
}
++y;
ypixel += 16;
}
wrefresh(myFrame.get());
}
void NFrame::FrameRefreshStatus(int /* drawflags */)
{
werase(myStatus.get());
box(myStatus.get(), 0 , 0);
int row = 0;
CardManager& cardManager = GetCardMgr();
if (cardManager.QuerySlot(SLOT6) == CT_Disk2)
{
Disk2InterfaceCard& disk2 = dynamic_cast<Disk2InterfaceCard&>(cardManager.GetRef(SLOT6));
const size_t maximumWidth = myColumns - 6; // 6 is the width of "S6D1: "
for (UINT i = DRIVE_1; i <= DRIVE_2; ++i)
{
const std::string name = disk2.GetBaseName(i).substr(0, maximumWidth);
mvwprintw(myStatus.get(), ++row, 1, "S6D%d: %s", 1 + i, name.c_str());
}
}
else
{
row += DRIVE_2 - DRIVE_1 + 1;
}
++row;
mvwprintw(myStatus.get(), ++row, 1, "F2: ResetMachine / Shift-F2: CtrlReset");
mvwprintw(myStatus.get(), ++row, 1, "F3: Exit / F5: Swap");
mvwprintw(myStatus.get(), ++row, 1, "F11: Load State / F12: Save State");
wrefresh(myStatus.get());
}
void NFrame::VideoUpdateFlash()
{
++myTextFlashCounter;
if (myTextFlashCounter == 16) // Flash rate = 0.5 * 60 / 16 Hz (as we need 2 changes for a period)
{
myTextFlashCounter = 0;
myTextFlashState = !myTextFlashState;
}
}
chtype NFrame::MapCharacter(Video & video, BYTE ch)
{
const char low = ch & 0x7f;
const char high = ch & 0x80;
chtype result = low;
const int code = low >> 5;
switch (code)
{
case 0: // 00 - 1F
result += 0x40; // UPPERCASE
break;
case 1: // 20 - 3F
// SPECIAL CHARACTER
break;
case 2: // 40 - 5F
// UPPERCASE
break;
case 3: // 60 - 7F
// LOWERCASE
if (high == 0 && !video.VideoGetSWAltCharSet())
{
result -= 0x40;
}
break;
}
if (result == 0x7f)
{
result = ACS_CKBOARD;
}
if (!high)
{
if (!video.VideoGetSWAltCharSet() && (low >= 0x40))
{
// result |= A_BLINK; // does not work on my terminal
if (myTextFlashState)
{
result |= A_REVERSE;
}
}
else
{
result |= A_REVERSE;
}
}
return result;
}
bool NFrame::Update40ColCell(Video & video, int x, int y, int xpixel, int ypixel, int offset)
{
Init(24, 40);
myAsciiArt->init(1, 1);
BYTE ch = *(myTextBank0+offset);
const chtype ch2 = MapCharacter(video, ch);
mvwaddch(myFrame.get(), 1 + y, 1 + x, ch2);
return true;
}
bool NFrame::Update80ColCell(Video & video, int x, int y, int xpixel, int ypixel, int offset)
{
Init(24, 80);
myAsciiArt->init(1, 2);
BYTE ch1 = *(myTextBank1+offset);
BYTE ch2 = *(myTextBank0+offset);
WINDOW * win = myFrame.get();
const chtype ch12 = MapCharacter(video, ch1);
mvwaddch(win, 1 + y, 1 + 2 * x, ch12);
const chtype ch22 = MapCharacter(video, ch2);
mvwaddch(win, 1 + y, 1 + 2 * x + 1, ch22);
return true;
}
bool NFrame::UpdateLoResCell(Video &, int x, int y, int xpixel, int ypixel, int offset)
{
BYTE val = *(myTextBank0+offset);
const int pair = myNCurses->colors->getPair(val);
WINDOW * win = myFrame.get();
wcolor_set(win, pair, NULL);
if (myColumns == 40)
{
mvwaddstr(win, 1 + y, 1 + x, "\u2580");
}
else
{
mvwaddstr(win, 1 + y, 1 + 2 * x, "\u2580\u2580");
}
wcolor_set(win, 0, NULL);
return true;
}
bool NFrame::UpdateDLoResCell(Video &, int x, int y, int xpixel, int ypixel, int offset)
{
return true;
}
bool NFrame::UpdateHiResCell(Video &, int x, int y, int xpixel, int ypixel, int offset)
{
const BYTE * base = myHiresBank0 + offset;
const ASCIIArt::array_char_t & chs = myAsciiArt->getCharacters(base);
const auto shape = chs.shape();
const size_t rows = shape[0];
const size_t cols = shape[1];
Init(24 * rows, 40 * cols);
WINDOW * win = myFrame.get();
const GraphicsColors & colors = *myNCurses->colors;
for (size_t i = 0; i < rows; ++i)
{
for (size_t j = 0; j < cols; ++j)
{
const int pair = colors.getGrey(chs[i][j].foreground, chs[i][j].background);
wcolor_set(win, pair, NULL);
mvwaddstr(win, 1 + rows * y + i, 1 + cols * x + j, chs[i][j].c);
}
}
wcolor_set(win, 0, NULL);
return true;
}
bool NFrame::UpdateDHiResCell(Video &, int x, int y, int xpixel, int ypixel, int offset)
{
return true;
}
int NFrame::FrameMessageBox(LPCSTR lpText, LPCSTR lpCaption, UINT uType)
{
LogFileOutput("MessageBox:\n%s\n%s\n\n", lpCaption, lpText);
return IDOK;
}
}
void SingleStep(bool /* bReinit */)
{
}

View file

@ -0,0 +1,71 @@
#pragma once
#include "frontends/common2/commonframe.h"
#include "frontends/common2/gnuframe.h"
#include <memory>
#include <string>
#include <ncurses.h>
namespace na2
{
class ASCIIArt;
class EvDevPaddle;
struct NCurses;
class NFrame : public virtual common2::CommonFrame, public common2::GNUFrame
{
public:
NFrame(const std::shared_ptr<EvDevPaddle> & paddle);
WINDOW * GetWindow();
WINDOW * GetStatus();
void Initialize(bool resetVideoState) override;
void Destroy() override;
void VideoPresentScreen() override;
int FrameMessageBox(LPCSTR lpText, LPCSTR lpCaption, UINT uType) override;
void FrameRefreshStatus(int drawflags) override;
void ProcessEvDev();
void ChangeColumns(const int x);
void ChangeRows(const int x);
void Init(int rows, int columns);
private:
const std::shared_ptr<EvDevPaddle> myPaddle;
int myRows;
int myColumns;
int myTextFlashCounter;
bool myTextFlashState;
std::shared_ptr<WINDOW> myFrame;
std::shared_ptr<WINDOW> myStatus;
std::shared_ptr<ASCIIArt> myAsciiArt;
std::shared_ptr<NCurses> myNCurses;
LPBYTE myTextBank1; // Aux
LPBYTE myTextBank0; // Main
LPBYTE myHiresBank1;
LPBYTE myHiresBank0;
void VideoUpdateFlash();
chtype MapCharacter(Video & video, BYTE ch);
bool Update40ColCell(Video & video, int x, int y, int xpixel, int ypixel, int offset);
bool Update80ColCell(Video & video, int x, int y, int xpixel, int ypixel, int offset);
bool UpdateLoResCell(Video &, int x, int y, int xpixel, int ypixel, int offset);
bool UpdateDLoResCell(Video &, int x, int y, int xpixel, int ypixel, int offset);
bool UpdateHiResCell(Video &, int x, int y, int xpixel, int ypixel, int offset);
bool UpdateDHiResCell(Video &, int x, int y, int xpixel, int ypixel, int offset);
void InitialiseNCurses();
};
}

View file

@ -0,0 +1,137 @@
#include "frontends/ncurses/world.h"
#include "StdAfx.h"
#include <ncurses.h>
#include <signal.h>
#include "Log.h"
#include "linux/linuxinterface.h"
#include "linux/keyboard.h"
#include "frontends/ncurses/nframe.h"
namespace
{
void sig_handler_pass(int signo)
{
// Ctrl-C
// is there a race condition here?
// is it a problem?
addKeyToBuffer(0x03);
}
void sig_handler_exit(int signo)
{
na2::g_stop = true;
}
}
namespace na2
{
double g_relativeSpeed = 1.0;
bool g_stop = false;
void SetCtrlCHandler(const bool headless)
{
if (headless)
{
signal(SIGINT, sig_handler_exit);
}
else
{
signal(SIGINT, sig_handler_pass);
// pass Ctrl-C to the emulator
}
}
int ProcessKeyboard(const std::shared_ptr<NFrame> & frame)
{
WINDOW * window = frame->GetWindow();
if (!window)
{
return ERR;
}
const int inch = wgetch(window);
int ch = ERR;
switch (inch)
{
case ERR:
break;
case '\n':
ch = 0x0d; // ENTER
break;
case KEY_BACKSPACE:
case KEY_LEFT:
ch = 0x08;
break;
case KEY_RIGHT:
ch = 0x15;
break;
case KEY_UP:
ch = 0x0b;
break;
case KEY_DOWN:
ch = 0x0a;
break;
case 0x14a: // DEL
ch = 0x7f;
break;
case 543 ... 546: // Various values for Ctrl/Alt - Left on Ubuntu and Pi OS
frame->ChangeColumns(-1);
break;
case 558 ... 561: // Ctrl/Alt - Right
frame->ChangeColumns(+1);
break;
case 564 ... 567: // Ctrl/Alt - Up
frame->ChangeRows(-1);
break;
case 523 ... 526: // Ctrl/Alt - Down
frame->ChangeRows(+1);
break;
default:
if (inch < 0x80)
{
ch = inch;
// Standard for Apple II is Upper case
if (ch >= 'A' && ch <= 'Z')
{
ch += 'a' - 'A';
}
else if (ch >= 'a' && ch <= 'z')
{
ch -= 'a' - 'A';
}
}
}
if (ch != ERR)
{
addKeyToBuffer(ch);
return ERR;
}
else
{
// pass it back
return inch;
}
}
}
// Mockingboard
void registerSoundBuffer(IDirectSoundBuffer * buffer)
{
}
void unregisterSoundBuffer(IDirectSoundBuffer * buffer)
{
}

View file

@ -0,0 +1,17 @@
#pragma once
#include <memory>
namespace na2
{
class NFrame;
int ProcessKeyboard(const std::shared_ptr<NFrame> & frame);
void SetCtrlCHandler(const bool headless);
extern double g_relativeSpeed;
extern bool g_stop;
}

View file

@ -0,0 +1,61 @@
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)
find_package(Qt5 REQUIRED
COMPONENTS Widgets Gamepad Multimedia
)
add_subdirectory(QHexView)
set(SOURCE_FILES
main.cpp
qapple.cpp
preferences.cpp
emulator.cpp
memorycontainer.cpp
gamepadpaddle.cpp
qvideo.cpp
configuration.cpp
options.cpp
loggingcategory.cpp
viewbuffer.cpp
qdirectsound.cpp
qtframe.cpp
)
set(HEADER_FILES
applicationname.h
qapple.h
preferences.h
emulator.h
memorycontainer.h
gamepadpaddle.h
qvideo.h
configuration.h
options.h
loggingcategory.h
viewbuffer.h
qdirectsound.h
qtframe.h
)
add_executable(qapple
${SOURCE_FILES}
${HEADER_FILES}
qapple.qrc
)
target_link_libraries(qapple PRIVATE
Qt5::Widgets
Qt5::Gamepad
Qt5::Multimedia
appleii
qhexview-lib
windows
)
install(TARGETS qapple
DESTINATION bin)

@ -0,0 +1 @@
Subproject commit b3c0e4a8b7318f3c6ed8a29a75694b376ba16cf1

View file

@ -0,0 +1,4 @@
#pragma once
#define ORGANIZATION_NAME "AndSoft"
#define APPLICATION_NAME "QAppleEmulator"

Some files were not shown because too many files have changed in this diff Show more